summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig150
-rw-r--r--drivers/acpi/Makefile52
-rw-r--r--drivers/acpi/ac.c1
-rw-r--r--drivers/acpi/acpica/Makefile4
-rw-r--r--drivers/acpi/acpica/acglobal.h11
-rw-r--r--drivers/acpi/acpica/achware.h12
-rw-r--r--drivers/acpi/acpica/aclocal.h60
-rw-r--r--drivers/acpi/acpica/acmacros.h4
-rw-r--r--drivers/acpi/acpica/acobject.h1
-rw-r--r--drivers/acpi/acpica/acpredef.h41
-rw-r--r--drivers/acpi/acpica/actables.h9
-rw-r--r--drivers/acpi/acpica/acutils.h15
-rw-r--r--drivers/acpi/acpica/dsinit.c16
-rw-r--r--drivers/acpi/acpica/dsmthdat.c2
-rw-r--r--drivers/acpi/acpica/dsobject.c6
-rw-r--r--drivers/acpi/acpica/dsopcode.c32
-rw-r--r--drivers/acpi/acpica/dsutils.c2
-rw-r--r--drivers/acpi/acpica/dswexec.c5
-rw-r--r--drivers/acpi/acpica/evevent.c18
-rw-r--r--drivers/acpi/acpica/evgpe.c7
-rw-r--r--drivers/acpi/acpica/evgpeblk.c70
-rw-r--r--drivers/acpi/acpica/evmisc.c16
-rw-r--r--drivers/acpi/acpica/evregion.c5
-rw-r--r--drivers/acpi/acpica/evrgnini.c22
-rw-r--r--drivers/acpi/acpica/evxface.c3
-rw-r--r--drivers/acpi/acpica/evxfevnt.c24
-rw-r--r--drivers/acpi/acpica/evxfregn.c3
-rw-r--r--drivers/acpi/acpica/exconfig.c17
-rw-r--r--drivers/acpi/acpica/exconvrt.c11
-rw-r--r--drivers/acpi/acpica/exdump.c59
-rw-r--r--drivers/acpi/acpica/exfield.c29
-rw-r--r--drivers/acpi/acpica/exfldio.c14
-rw-r--r--drivers/acpi/acpica/exmisc.c14
-rw-r--r--drivers/acpi/acpica/exoparg1.c13
-rw-r--r--drivers/acpi/acpica/exoparg2.c2
-rw-r--r--drivers/acpi/acpica/exoparg3.c7
-rw-r--r--drivers/acpi/acpica/exprep.c2
-rw-r--r--drivers/acpi/acpica/exregion.c4
-rw-r--r--drivers/acpi/acpica/exresnte.c8
-rw-r--r--drivers/acpi/acpica/exresolv.c9
-rw-r--r--drivers/acpi/acpica/exresop.c23
-rw-r--r--drivers/acpi/acpica/exstore.c18
-rw-r--r--drivers/acpi/acpica/exstoren.c29
-rw-r--r--drivers/acpi/acpica/exutils.c2
-rw-r--r--drivers/acpi/acpica/hwacpi.c9
-rw-r--r--drivers/acpi/acpica/hwgpe.c21
-rw-r--r--drivers/acpi/acpica/hwregs.c322
-rw-r--r--drivers/acpi/acpica/hwsleep.c130
-rw-r--r--drivers/acpi/acpica/hwvalid.c258
-rw-r--r--drivers/acpi/acpica/hwxface.c279
-rw-r--r--drivers/acpi/acpica/nsaccess.c54
-rw-r--r--drivers/acpi/acpica/nsalloc.c24
-rw-r--r--drivers/acpi/acpica/nsdump.c24
-rw-r--r--drivers/acpi/acpica/nseval.c2
-rw-r--r--drivers/acpi/acpica/nsinit.c19
-rw-r--r--drivers/acpi/acpica/nsload.c4
-rw-r--r--drivers/acpi/acpica/nsobject.c18
-rw-r--r--drivers/acpi/acpica/nsparse.c10
-rw-r--r--drivers/acpi/acpica/nspredef.c38
-rw-r--r--drivers/acpi/acpica/nssearch.c14
-rw-r--r--drivers/acpi/acpica/nsutils.c27
-rw-r--r--drivers/acpi/acpica/nswalk.c12
-rw-r--r--drivers/acpi/acpica/nsxfeval.c36
-rw-r--r--drivers/acpi/acpica/rscalc.c7
-rw-r--r--drivers/acpi/acpica/rscreate.c15
-rw-r--r--drivers/acpi/acpica/tbfadt.c363
-rw-r--r--drivers/acpi/acpica/tbinstal.c82
-rw-r--r--drivers/acpi/acpica/tbutils.c106
-rw-r--r--drivers/acpi/acpica/tbxface.c71
-rw-r--r--drivers/acpi/acpica/tbxfroot.c4
-rw-r--r--drivers/acpi/acpica/utcopy.c30
-rw-r--r--drivers/acpi/acpica/utdelete.c6
-rw-r--r--drivers/acpi/acpica/uteval.c98
-rw-r--r--drivers/acpi/acpica/utglobal.c17
-rw-r--r--drivers/acpi/acpica/utlock.c175
-rw-r--r--drivers/acpi/acpica/utmisc.c3
-rw-r--r--drivers/acpi/acpica/utmutex.c23
-rw-r--r--drivers/acpi/acpica/utobject.c11
-rw-r--r--drivers/acpi/battery.c30
-rw-r--r--drivers/acpi/bus.c15
-rw-r--r--drivers/acpi/button.c80
-rw-r--r--drivers/acpi/debug.c19
-rw-r--r--drivers/acpi/dock.c3
-rw-r--r--drivers/acpi/ec.c39
-rw-r--r--drivers/acpi/fan.c22
-rw-r--r--drivers/acpi/glue.c6
-rw-r--r--drivers/acpi/internal.h43
-rw-r--r--drivers/acpi/numa.c46
-rw-r--r--drivers/acpi/osl.c6
-rw-r--r--drivers/acpi/pci_irq.c18
-rw-r--r--drivers/acpi/pci_link.c147
-rw-r--r--drivers/acpi/pci_root.c180
-rw-r--r--drivers/acpi/power.c12
-rw-r--r--drivers/acpi/proc.c7
-rw-r--r--drivers/acpi/processor_core.c47
-rw-r--r--drivers/acpi/processor_idle.c124
-rw-r--r--drivers/acpi/processor_perflib.c46
-rw-r--r--drivers/acpi/processor_thermal.c22
-rw-r--r--drivers/acpi/processor_throttling.c8
-rw-r--r--drivers/acpi/sbs.c42
-rw-r--r--drivers/acpi/scan.c94
-rw-r--r--drivers/acpi/sleep.c13
-rw-r--r--drivers/acpi/system.c64
-rw-r--r--drivers/acpi/tables.c30
-rw-r--r--drivers/acpi/thermal.c543
-rw-r--r--drivers/acpi/video.c341
-rw-r--r--drivers/acpi/video_detect.c3
-rw-r--r--drivers/acpi/wakeup.c9
-rw-r--r--drivers/ata/Kconfig2
-rw-r--r--drivers/auxdisplay/Kconfig3
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/iommu.c9
-rw-r--r--drivers/base/node.c2
-rw-r--r--drivers/base/power/main.c20
-rw-r--r--drivers/base/sys.c10
-rw-r--r--drivers/block/aoe/aoecmd.c23
-rw-r--r--drivers/block/floppy.c8
-rw-r--r--drivers/block/hd.c2
-rw-r--r--drivers/block/loop.c30
-rw-r--r--drivers/block/nbd.c112
-rw-r--r--drivers/block/ps3vram.c2
-rw-r--r--drivers/block/xsysace.c30
-rw-r--r--drivers/char/amiserial.c62
-rw-r--r--drivers/char/applicom.c1
-rw-r--r--drivers/char/bsr.c2
-rw-r--r--drivers/char/cyclades.c56
-rw-r--r--drivers/char/hpet.c22
-rw-r--r--drivers/char/hw_random/timeriomem-rng.c39
-rw-r--r--drivers/char/ip2/ip2main.c74
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c12
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c6
-rw-r--r--drivers/char/isicom.c1
-rw-r--r--drivers/char/istallion.c121
-rw-r--r--drivers/char/moxa.c9
-rw-r--r--drivers/char/mxser.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c73
-rw-r--r--drivers/char/random.c3
-rw-r--r--drivers/char/raw.c1
-rw-r--r--drivers/char/rio/rio_linux.c2
-rw-r--r--drivers/char/riscom8.c2
-rw-r--r--drivers/char/specialix.c1
-rw-r--r--drivers/char/stallion.c126
-rw-r--r--drivers/char/synclink.c98
-rw-r--r--drivers/char/synclink_gt.c132
-rw-r--r--drivers/char/synclinkmp.c74
-rw-r--r--drivers/char/sysrq.c23
-rw-r--r--drivers/char/tty_audit.c2
-rw-r--r--drivers/char/tty_io.c26
-rw-r--r--drivers/char/tty_ldisc.c1
-rw-r--r--drivers/clocksource/sh_cmt.c3
-rw-r--r--drivers/crypto/hifn_795x.c2
-rw-r--r--drivers/crypto/ixp4xx_crypto.c182
-rw-r--r--drivers/dma/Kconfig11
-rw-r--r--drivers/dma/dmaengine.c60
-rw-r--r--drivers/dma/dmatest.c307
-rw-r--r--drivers/dma/dw_dmac.c333
-rw-r--r--drivers/dma/dw_dmac_regs.h7
-rw-r--r--drivers/dma/fsldma.c1
-rw-r--r--drivers/dma/ioat_dma.c1
-rw-r--r--drivers/dma/iop-adma.c1
-rw-r--r--drivers/dma/ipu/ipu_idmac.c371
-rw-r--r--drivers/dma/ipu/ipu_irq.c2
-rw-r--r--drivers/dma/mv_xor.c1
-rw-r--r--drivers/edac/Kconfig36
-rw-r--r--drivers/edac/Makefile2
-rw-r--r--drivers/edac/amd8111_edac.c595
-rw-r--r--drivers/edac/amd8111_edac.h130
-rw-r--r--drivers/edac/amd8131_edac.c379
-rw-r--r--drivers/edac/amd8131_edac.h119
-rw-r--r--drivers/edac/edac_core.h16
-rw-r--r--drivers/edac/edac_pci.c14
-rw-r--r--drivers/edac/ppc4xx_edac.c1448
-rw-r--r--drivers/edac/ppc4xx_edac.h172
-rw-r--r--drivers/firmware/dmi_scan.c18
-rw-r--r--drivers/gpio/Kconfig6
-rw-r--r--drivers/gpio/gpiolib.c19
-rw-r--r--drivers/gpu/drm/ati_pcigart.c40
-rw-r--r--drivers/gpu/drm/drm_bufs.c122
-rw-r--r--drivers/gpu/drm/drm_context.c4
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c31
-rw-r--r--drivers/gpu/drm/drm_drv.c88
-rw-r--r--drivers/gpu/drm/drm_edid.c191
-rw-r--r--drivers/gpu/drm/drm_fops.c1
-rw-r--r--drivers/gpu/drm/drm_gem.c9
-rw-r--r--drivers/gpu/drm/drm_info.c6
-rw-r--r--drivers/gpu/drm/drm_ioc32.c4
-rw-r--r--drivers/gpu/drm/drm_memory.c6
-rw-r--r--drivers/gpu/drm/drm_proc.c1
-rw-r--r--drivers/gpu/drm/drm_stub.c93
-rw-r--r--drivers/gpu/drm/drm_sysfs.c38
-rw-r--r--drivers/gpu/drm/drm_vm.c32
-rw-r--r--drivers/gpu/drm/i810/i810_drv.h4
-rw-r--r--drivers/gpu/drm/i830/i830_drv.h4
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c18
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c40
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h9
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c45
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debug.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_debugfs.c6
-rw-r--r--drivers/gpu/drm/i915/i915_gem_tiling.c16
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c67
-rw-r--r--drivers/gpu/drm/i915/i915_opregion.c65
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h11
-rw-r--r--drivers/gpu/drm/i915/intel_crt.c4
-rw-r--r--drivers/gpu/drm/i915/intel_display.c22
-rw-r--r--drivers/gpu/drm/i915/intel_modes.c1
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c193
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo_regs.h3
-rw-r--r--drivers/gpu/drm/i915/intel_tv.c30
-rw-r--r--drivers/gpu/drm/mga/mga_dma.c17
-rw-r--r--drivers/gpu/drm/mga/mga_drv.h8
-rw-r--r--drivers/gpu/drm/r128/r128_cce.c7
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/r300_cmdbuf.c11
-rw-r--r--drivers/gpu/drm/radeon/r300_reg.h5
-rw-r--r--drivers/gpu/drm/radeon/r600_cp.c2253
-rw-r--r--drivers/gpu/drm/radeon/r600_microcode.h23297
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c522
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c22
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.h635
-rw-r--r--drivers/gpu/drm/radeon/radeon_irq.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon_state.c51
-rw-r--r--drivers/gpu/drm/savage/savage_bci.c8
-rw-r--r--drivers/gpu/drm/via/via_drv.c6
-rw-r--r--drivers/hid/Kconfig42
-rw-r--r--drivers/hid/Makefile7
-rw-r--r--drivers/hid/hid-a4tech.c2
-rw-r--r--drivers/hid/hid-apple.c26
-rw-r--r--drivers/hid/hid-belkin.c2
-rw-r--r--drivers/hid/hid-cherry.c2
-rw-r--r--drivers/hid/hid-chicony.c2
-rw-r--r--drivers/hid/hid-core.c37
-rw-r--r--drivers/hid/hid-cypress.c2
-rw-r--r--drivers/hid/hid-drff.c188
-rw-r--r--drivers/hid/hid-dummy.c78
-rw-r--r--drivers/hid/hid-ezkey.c2
-rw-r--r--drivers/hid/hid-gaff.c2
-rw-r--r--drivers/hid/hid-gyration.c2
-rw-r--r--drivers/hid/hid-ids.h10
-rw-r--r--drivers/hid/hid-kensington.c63
-rw-r--r--drivers/hid/hid-kye.c69
-rw-r--r--drivers/hid/hid-lg.c2
-rw-r--r--drivers/hid/hid-microsoft.c2
-rw-r--r--drivers/hid/hid-monterey.c2
-rw-r--r--drivers/hid/hid-ntrig.c2
-rw-r--r--drivers/hid/hid-petalynx.c2
-rw-r--r--drivers/hid/hid-pl.c52
-rw-r--r--drivers/hid/hid-samsung.c2
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hid/hid-sunplus.c2
-rw-r--r--drivers/hid/hid-tmff.c2
-rw-r--r--drivers/hid/hid-topseed.c2
-rw-r--r--drivers/hid/hid-zpff.c2
-rw-r--r--drivers/hid/hidraw.c17
-rw-r--r--drivers/hid/usbhid/hid-core.c475
-rw-r--r--drivers/hid/usbhid/hiddev.c22
-rw-r--r--drivers/hid/usbhid/usbhid.h14
-rw-r--r--drivers/hwmon/Kconfig63
-rw-r--r--drivers/hwmon/Makefile4
-rw-r--r--drivers/hwmon/ds1621.c172
-rw-r--r--drivers/hwmon/f75375s.c4
-rw-r--r--drivers/hwmon/fschmd.c229
-rw-r--r--drivers/hwmon/hdaps.c66
-rw-r--r--drivers/hwmon/hp_accel.c124
-rw-r--r--drivers/hwmon/lis3lv02d.c288
-rw-r--r--drivers/hwmon/lis3lv02d.h20
-rw-r--r--drivers/hwmon/lis3lv02d_spi.c114
-rw-r--r--drivers/hwmon/lm95241.c527
-rw-r--r--drivers/hwmon/ltc4215.c364
-rw-r--r--drivers/hwmon/pcf8591.c (renamed from drivers/i2c/chips/pcf8591.c)24
-rw-r--r--drivers/hwmon/w83627ehf.c170
-rw-r--r--drivers/i2c/algos/Kconfig4
-rw-r--r--drivers/i2c/algos/Makefile1
-rw-r--r--drivers/i2c/algos/i2c-algo-sgi.c179
-rw-r--r--drivers/i2c/busses/i2c-i801.c77
-rw-r--r--drivers/i2c/busses/i2c-mpc.c9
-rw-r--r--drivers/i2c/chips/Kconfig13
-rw-r--r--drivers/i2c/chips/Makefile1
-rw-r--r--drivers/ide/Kconfig33
-rw-r--r--drivers/ide/Makefile2
-rw-r--r--drivers/ide/alim15x3.c15
-rw-r--r--drivers/ide/at91_ide.c101
-rw-r--r--drivers/ide/au1xxx-ide.c59
-rw-r--r--drivers/ide/buddha.c11
-rw-r--r--drivers/ide/cmd64x.c12
-rw-r--r--drivers/ide/cs5530.c3
-rw-r--r--drivers/ide/cs5536.c3
-rw-r--r--drivers/ide/delkin_cb.c1
-rw-r--r--drivers/ide/dtc2278.c3
-rw-r--r--drivers/ide/falconide.c49
-rw-r--r--drivers/ide/gayle.c19
-rw-r--r--drivers/ide/hpt366.c16
-rw-r--r--drivers/ide/ht6560b.c20
-rw-r--r--drivers/ide/icside.c32
-rw-r--r--drivers/ide/ide-4drives.c3
-rw-r--r--drivers/ide/ide-acpi.c10
-rw-r--r--drivers/ide/ide-atapi.c249
-rw-r--r--drivers/ide/ide-cd.c644
-rw-r--r--drivers/ide/ide-cd.h4
-rw-r--r--drivers/ide/ide-cs.c1
-rw-r--r--drivers/ide/ide-devsets.c4
-rw-r--r--drivers/ide/ide-disk.c175
-rw-r--r--drivers/ide/ide-disk_proc.c28
-rw-r--r--drivers/ide/ide-dma-sff.c52
-rw-r--r--drivers/ide/ide-dma.c139
-rw-r--r--drivers/ide/ide-eh.c44
-rw-r--r--drivers/ide/ide-floppy.c177
-rw-r--r--drivers/ide/ide-floppy_ioctl.c5
-rw-r--r--drivers/ide/ide-gd.c10
-rw-r--r--drivers/ide/ide-gd.h4
-rw-r--r--drivers/ide/ide-generic.c88
-rw-r--r--drivers/ide/ide-h8300.c94
-rw-r--r--drivers/ide/ide-io-std.c197
-rw-r--r--drivers/ide/ide-io.c306
-rw-r--r--drivers/ide/ide-ioctls.c44
-rw-r--r--drivers/ide/ide-iops.c97
-rw-r--r--drivers/ide/ide-lib.c20
-rw-r--r--drivers/ide/ide-park.c19
-rw-r--r--drivers/ide/ide-pm.c47
-rw-r--r--drivers/ide/ide-pnp.c6
-rw-r--r--drivers/ide/ide-probe.c126
-rw-r--r--drivers/ide/ide-proc.c16
-rw-r--r--drivers/ide/ide-tape.c159
-rw-r--r--drivers/ide/ide-taskfile.c508
-rw-r--r--drivers/ide/ide-timings.c12
-rw-r--r--drivers/ide/ide-xfer-mode.c15
-rw-r--r--drivers/ide/ide_arm.c49
-rw-r--r--drivers/ide/it821x.c3
-rw-r--r--drivers/ide/macide.c7
-rw-r--r--drivers/ide/ns87415.c113
-rw-r--r--drivers/ide/palm_bk3710.c13
-rw-r--r--drivers/ide/pdc202xx_old.c14
-rw-r--r--drivers/ide/pmac.c129
-rw-r--r--drivers/ide/q40ide.c19
-rw-r--r--drivers/ide/qd65xx.c21
-rw-r--r--drivers/ide/sc1200.c9
-rw-r--r--drivers/ide/scc_pata.c161
-rw-r--r--drivers/ide/setup-pci.c4
-rw-r--r--drivers/ide/sgiioc4.c50
-rw-r--r--drivers/ide/siimage.c3
-rw-r--r--drivers/ide/sl82c105.c12
-rw-r--r--drivers/ide/tc86c001.c3
-rw-r--r--drivers/ide/trm290.c64
-rw-r--r--drivers/ide/tx4938ide.c103
-rw-r--r--drivers/ide/tx4939ide.c161
-rw-r--r--drivers/input/Kconfig2
-rw-r--r--drivers/input/input.c2
-rw-r--r--drivers/input/keyboard/sh_keysc.c17
-rw-r--r--drivers/input/mouse/gpio_mouse.c2
-rw-r--r--drivers/input/mouse/hgpk.c2
-rw-r--r--drivers/input/touchscreen/ads7846.c2
-rw-r--r--drivers/input/touchscreen/migor_ts.c23
-rw-r--r--drivers/isdn/capi/capi.c7
-rw-r--r--drivers/isdn/hardware/eicon/divasi.c1
-rw-r--r--drivers/isdn/mISDN/Kconfig10
-rw-r--r--drivers/isdn/mISDN/l1oip_codec.c2
-rw-r--r--drivers/leds/Kconfig81
-rw-r--r--drivers/leds/Makefile7
-rw-r--r--drivers/leds/led-class.c21
-rw-r--r--drivers/leds/led-triggers.c10
-rw-r--r--drivers/leds/leds-bd2802.c765
-rw-r--r--drivers/leds/leds-dac124s085.c150
-rw-r--r--drivers/leds/leds-gpio.c225
-rw-r--r--drivers/leds/leds-h1940.c2
-rw-r--r--drivers/leds/leds-pca9532.c6
-rw-r--r--drivers/leds/leds-pwm.c153
-rw-r--r--drivers/leds/leds-rb532.c77
-rw-r--r--drivers/leds/leds-s3c24xx.c7
-rw-r--r--drivers/leds/leds.h4
-rw-r--r--drivers/leds/ledtrig-default-on.c2
-rw-r--r--drivers/leds/ledtrig-gpio.c239
-rw-r--r--drivers/leds/ledtrig-heartbeat.c4
-rw-r--r--drivers/leds/ledtrig-ide-disk.c3
-rw-r--r--drivers/leds/ledtrig-timer.c2
-rw-r--r--drivers/lguest/core.c4
-rw-r--r--drivers/lguest/interrupts_and_traps.c28
-rw-r--r--drivers/lguest/lg.h8
-rw-r--r--drivers/lguest/lguest_device.c4
-rw-r--r--drivers/lguest/page_tables.c22
-rw-r--r--drivers/lguest/segments.c2
-rw-r--r--drivers/lguest/x86/core.c62
-rw-r--r--drivers/macintosh/therm_adt746x.c4
-rw-r--r--drivers/md/Kconfig31
-rw-r--r--drivers/md/Makefile16
-rw-r--r--drivers/md/bitmap.c49
-rw-r--r--drivers/md/bitmap.h288
-rw-r--r--drivers/md/dm-bio-list.h10
-rw-r--r--drivers/md/dm-bio-record.h26
-rw-r--r--drivers/md/dm-crypt.c6
-rw-r--r--drivers/md/dm-exception-store.c252
-rw-r--r--drivers/md/dm-exception-store.h58
-rw-r--r--drivers/md/dm-io.c5
-rw-r--r--drivers/md/dm-log.c75
-rw-r--r--drivers/md/dm-path-selector.c21
-rw-r--r--drivers/md/dm-raid1.c50
-rw-r--r--drivers/md/dm-snap-persistent.c153
-rw-r--r--drivers/md/dm-snap-transient.c86
-rw-r--r--drivers/md/dm-snap.c384
-rw-r--r--drivers/md/dm-snap.h105
-rw-r--r--drivers/md/dm-table.c26
-rw-r--r--drivers/md/dm-target.c104
-rw-r--r--drivers/md/dm.c134
-rw-r--r--drivers/md/dm.h2
-rw-r--r--drivers/md/faulty.c19
-rw-r--r--drivers/md/linear.c25
-rw-r--r--drivers/md/linear.h29
-rw-r--r--drivers/md/md.c615
-rw-r--r--drivers/md/md.h436
-rw-r--r--drivers/md/mktables.c14
-rw-r--r--drivers/md/multipath.c17
-rw-r--r--drivers/md/multipath.h40
-rw-r--r--drivers/md/raid0.c66
-rw-r--r--drivers/md/raid0.h28
-rw-r--r--drivers/md/raid1.c44
-rw-r--r--drivers/md/raid1.h132
-rw-r--r--drivers/md/raid10.c42
-rw-r--r--drivers/md/raid10.h121
-rw-r--r--drivers/md/raid5.c1494
-rw-r--r--drivers/md/raid5.h474
-rw-r--r--drivers/md/raid6.h130
-rw-r--r--drivers/md/raid6algos.c21
-rw-r--r--drivers/md/raid6altivec.uc4
-rw-r--r--drivers/md/raid6int.uc4
-rw-r--r--drivers/md/raid6mmx.c4
-rw-r--r--drivers/md/raid6recov.c13
-rw-r--r--drivers/md/raid6sse1.c4
-rw-r--r--drivers/md/raid6sse2.c4
-rw-r--r--drivers/md/raid6test/Makefile2
-rw-r--r--drivers/md/raid6test/test.c2
-rw-r--r--drivers/md/raid6x86.h2
-rw-r--r--drivers/media/Kconfig2
-rw-r--r--drivers/media/common/ir-keymaps.c146
-rw-r--r--drivers/media/common/saa7146_core.c15
-rw-r--r--drivers/media/common/saa7146_fops.c48
-rw-r--r--drivers/media/common/saa7146_i2c.c29
-rw-r--r--drivers/media/common/saa7146_video.c1268
-rw-r--r--drivers/media/common/tuners/Kconfig66
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/mc44s803.c371
-rw-r--r--drivers/media/common/tuners/mc44s803.h46
-rw-r--r--drivers/media/common/tuners/mc44s803_priv.h208
-rw-r--r--drivers/media/common/tuners/mt2060.c2
-rw-r--r--drivers/media/common/tuners/mt20xx.c2
-rw-r--r--drivers/media/common/tuners/mxl5005s.c7
-rw-r--r--drivers/media/common/tuners/mxl5007t.c428
-rw-r--r--drivers/media/common/tuners/tda18271-common.c6
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c37
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h6
-rw-r--r--drivers/media/common/tuners/tda18271.h10
-rw-r--r--drivers/media/common/tuners/tda827x.c237
-rw-r--r--drivers/media/common/tuners/tda8290.c9
-rw-r--r--drivers/media/common/tuners/tea5761.c2
-rw-r--r--drivers/media/common/tuners/tea5767.c2
-rw-r--r--drivers/media/common/tuners/xc5000.c14
-rw-r--r--drivers/media/dvb/b2c2/Kconfig2
-rw-r--r--drivers/media/dvb/b2c2/Makefile1
-rw-r--r--drivers/media/dvb/b2c2/flexcop-common.h64
-rw-r--r--drivers/media/dvb/b2c2/flexcop-dma.c27
-rw-r--r--drivers/media/dvb/b2c2/flexcop-eeprom.c47
-rw-r--r--drivers/media/dvb/b2c2/flexcop-fe-tuner.c6
-rw-r--r--drivers/media/dvb/b2c2/flexcop-hw-filter.c171
-rw-r--r--drivers/media/dvb/b2c2/flexcop-i2c.c61
-rw-r--r--drivers/media/dvb/b2c2/flexcop-misc.c68
-rw-r--r--drivers/media/dvb/b2c2/flexcop-pci.c165
-rw-r--r--drivers/media/dvb/b2c2/flexcop-reg.h21
-rw-r--r--drivers/media/dvb/b2c2/flexcop-sram.c112
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c368
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.h62
-rw-r--r--drivers/media/dvb/b2c2/flexcop.c86
-rw-r--r--drivers/media/dvb/b2c2/flexcop.h20
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_be.h7
-rw-r--r--drivers/media/dvb/b2c2/flexcop_ibi_value_le.h7
-rw-r--r--drivers/media/dvb/bt8xx/Kconfig2
-rw-r--r--drivers/media/dvb/bt8xx/dst_ca.c14
-rw-r--r--drivers/media/dvb/bt8xx/dvb-bt8xx.c2
-rw-r--r--drivers/media/dvb/dm1105/Kconfig1
-rw-r--r--drivers/media/dvb/dm1105/dm1105.c204
-rw-r--r--drivers/media/dvb/dvb-core/dmxdev.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_ca_en50221.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_net.c2
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c4
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.h2
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig67
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile2
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c60
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h31
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c328
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.h69
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c10
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c164
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h11
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig71
-rw-r--r--drivers/media/dvb/frontends/Makefile6
-rw-r--r--drivers/media/dvb/frontends/au8522.h16
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c835
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c (renamed from drivers/media/dvb/frontends/au8522.c)96
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h412
-rw-r--r--drivers/media/dvb/frontends/cx24113.c2
-rw-r--r--drivers/media/dvb/frontends/cx24116.c63
-rw-r--r--drivers/media/dvb/frontends/cx24123.c4
-rw-r--r--drivers/media/dvb/frontends/dib0070.h2
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.h36
-rw-r--r--drivers/media/dvb/frontends/dib7000m.h28
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h35
-rw-r--r--drivers/media/dvb/frontends/drx397xD.c2
-rw-r--r--drivers/media/dvb/frontends/dvb_dummy_fe.h19
-rw-r--r--drivers/media/dvb/frontends/itd1000_priv.h2
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c1
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.c1087
-rw-r--r--drivers/media/dvb/frontends/lgdt3305.h85
-rw-r--r--drivers/media/dvb/frontends/lnbh24.h55
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c41
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h34
-rw-r--r--drivers/media/dvb/frontends/s921_module.c1
-rw-r--r--drivers/media/dvb/frontends/stb6100_cfg.h4
-rw-r--r--drivers/media/dvb/frontends/stv0900.h62
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c1949
-rw-r--r--drivers/media/dvb/frontends/stv0900_init.h441
-rw-r--r--drivers/media/dvb/frontends/stv0900_priv.h430
-rw-r--r--drivers/media/dvb/frontends/stv0900_reg.h3787
-rw-r--r--drivers/media/dvb/frontends/stv0900_sw.c2847
-rw-r--r--drivers/media/dvb/frontends/stv6110.c456
-rw-r--r--drivers/media/dvb/frontends/stv6110.h62
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c30
-rw-r--r--drivers/media/dvb/frontends/zl10036.c519
-rw-r--r--drivers/media/dvb/frontends/zl10036.h53
-rw-r--r--drivers/media/dvb/frontends/zl10353.c8
-rw-r--r--drivers/media/dvb/frontends/zl10353.h4
-rw-r--r--drivers/media/dvb/frontends/zl10353_priv.h8
-rw-r--r--drivers/media/dvb/pluto2/pluto2.c7
-rw-r--r--drivers/media/dvb/siano/Makefile4
-rw-r--r--drivers/media/dvb/siano/sms-cards.c92
-rw-r--r--drivers/media/dvb/siano/sms-cards.h5
-rw-r--r--drivers/media/dvb/siano/smscoreapi.c45
-rw-r--r--drivers/media/dvb/siano/smscoreapi.h41
-rw-r--r--drivers/media/dvb/siano/smsdvb.c60
-rw-r--r--drivers/media/dvb/siano/smsusb.c73
-rw-r--r--drivers/media/dvb/ttpci/Kconfig2
-rw-r--r--drivers/media/dvb/ttpci/av7110.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_av.c4
-rw-r--r--drivers/media/dvb/ttpci/av7110_ca.c2
-rw-r--r--drivers/media/dvb/ttpci/av7110_v4l.c480
-rw-r--r--drivers/media/dvb/ttpci/budget-av.c88
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c6
-rw-r--r--drivers/media/radio/dsbr100.c10
-rw-r--r--drivers/media/radio/radio-aimslab.c347
-rw-r--r--drivers/media/radio/radio-aztech.c378
-rw-r--r--drivers/media/radio/radio-cadet.c595
-rw-r--r--drivers/media/radio/radio-gemtek-pci.c329
-rw-r--r--drivers/media/radio/radio-gemtek.c396
-rw-r--r--drivers/media/radio/radio-maestro.c337
-rw-r--r--drivers/media/radio/radio-maxiradio.c374
-rw-r--r--drivers/media/radio/radio-mr800.c221
-rw-r--r--drivers/media/radio/radio-rtrack2.c276
-rw-r--r--drivers/media/radio/radio-sf16fmi.c283
-rw-r--r--drivers/media/radio/radio-sf16fmr2.c371
-rw-r--r--drivers/media/radio/radio-si470x.c200
-rw-r--r--drivers/media/radio/radio-terratec.c310
-rw-r--r--drivers/media/radio/radio-trust.c343
-rw-r--r--drivers/media/radio/radio-typhoon.c349
-rw-r--r--drivers/media/radio/radio-zoltrix.c378
-rw-r--r--drivers/media/video/Kconfig94
-rw-r--r--drivers/media/video/Makefile10
-rw-r--r--drivers/media/video/adv7170.c354
-rw-r--r--drivers/media/video/adv7175.c329
-rw-r--r--drivers/media/video/au0828/Kconfig10
-rw-r--r--drivers/media/video/au0828/Makefile2
-rw-r--r--drivers/media/video/au0828/au0828-cards.c127
-rw-r--r--drivers/media/video/au0828/au0828-core.c34
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c2
-rw-r--r--drivers/media/video/au0828/au0828-i2c.c72
-rw-r--r--drivers/media/video/au0828/au0828-reg.h6
-rw-r--r--drivers/media/video/au0828/au0828-video.c1712
-rw-r--r--drivers/media/video/au0828/au0828.h181
-rw-r--r--drivers/media/video/bt819.c493
-rw-r--r--drivers/media/video/bt856.c291
-rw-r--r--drivers/media/video/bt866.c282
-rw-r--r--drivers/media/video/bt8xx/Kconfig2
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c1672
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c197
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c61
-rw-r--r--drivers/media/video/bt8xx/bttv-if.c18
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c2
-rw-r--r--drivers/media/video/bt8xx/bttv.h96
-rw-r--r--drivers/media/video/bt8xx/bttvp.h30
-rw-r--r--drivers/media/video/cafe_ccic.c432
-rw-r--r--drivers/media/video/cpia.c4
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c1
-rw-r--r--drivers/media/video/cs5345.c7
-rw-r--r--drivers/media/video/cs53l32a.c12
-rw-r--r--drivers/media/video/cx18/Kconfig2
-rw-r--r--drivers/media/video/cx18/cx18-audio.c52
-rw-r--r--drivers/media/video/cx18/cx18-audio.h2
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c120
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c796
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h49
-rw-r--r--drivers/media/video/cx18/cx18-av-firmware.c16
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c367
-rw-r--r--drivers/media/video/cx18/cx18-cards.c50
-rw-r--r--drivers/media/video/cx18/cx18-cards.h18
-rw-r--r--drivers/media/video/cx18/cx18-controls.c70
-rw-r--r--drivers/media/video/cx18/cx18-driver.c416
-rw-r--r--drivers/media/video/cx18/cx18-driver.h258
-rw-r--r--drivers/media/video/cx18/cx18-dvb.c2
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c107
-rw-r--r--drivers/media/video/cx18/cx18-firmware.c22
-rw-r--r--drivers/media/video/cx18/cx18-gpio.c319
-rw-r--r--drivers/media/video/cx18/cx18-gpio.h10
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c296
-rw-r--r--drivers/media/video/cx18/cx18-i2c.h5
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c273
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c44
-rw-r--r--drivers/media/video/cx18/cx18-queue.c4
-rw-r--r--drivers/media/video/cx18/cx18-queue.h4
-rw-r--r--drivers/media/video/cx18/cx18-streams.c210
-rw-r--r--drivers/media/video/cx18/cx18-vbi.c155
-rw-r--r--drivers/media/video/cx18/cx18-vbi.h2
-rw-r--r--drivers/media/video/cx18/cx18-version.h4
-rw-r--r--drivers/media/video/cx18/cx18-video.c3
-rw-r--r--drivers/media/video/cx18/cx23418.h16
-rw-r--r--drivers/media/video/cx2341x.c196
-rw-r--r--drivers/media/video/cx23885/Kconfig15
-rw-r--r--drivers/media/video/cx23885/Makefile4
-rw-r--r--drivers/media/video/cx23885/cimax2.c472
-rw-r--r--drivers/media/video/cx23885/cimax2.h47
-rw-r--r--drivers/media/video/cx23885/cx23885-417.c49
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c94
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c43
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c166
-rw-r--r--drivers/media/video/cx23885/cx23885-i2c.c68
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h2
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c51
-rw-r--r--drivers/media/video/cx23885/cx23885.h20
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.c107
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.h42
-rw-r--r--drivers/media/video/cx23885/netup-init.c125
-rw-r--r--drivers/media/video/cx23885/netup-init.h25
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c121
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c65
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h8
-rw-r--r--drivers/media/video/cx25840/cx25840-vbi.c314
-rw-r--r--drivers/media/video/cx88/Kconfig2
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c8
-rw-r--r--drivers/media/video/cx88/cx88-cards.c99
-rw-r--r--drivers/media/video/cx88/cx88-core.c11
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c18
-rw-r--r--drivers/media/video/cx88/cx88-i2c.c41
-rw-r--r--drivers/media/video/cx88/cx88-input.c29
-rw-r--r--drivers/media/video/cx88/cx88-video.c52
-rw-r--r--drivers/media/video/cx88/cx88.h24
-rw-r--r--drivers/media/video/dabusb.c83
-rw-r--r--drivers/media/video/em28xx/em28xx-audio.c77
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c195
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c41
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c3
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c12
-rw-r--r--drivers/media/video/em28xx/em28xx-input.c22
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c61
-rw-r--r--drivers/media/video/em28xx/em28xx.h24
-rw-r--r--drivers/media/video/gspca/Kconfig27
-rw-r--r--drivers/media/video/gspca/Makefile102
-rw-r--r--drivers/media/video/gspca/conex.c63
-rw-r--r--drivers/media/video/gspca/etoms.c36
-rw-r--r--drivers/media/video/gspca/finepix.c433
-rw-r--r--drivers/media/video/gspca/gspca.c166
-rw-r--r--drivers/media/video/gspca/gspca.h14
-rw-r--r--drivers/media/video/gspca/jpeg.h263
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c7
-rw-r--r--drivers/media/video/gspca/mars.c506
-rw-r--r--drivers/media/video/gspca/mr97310a.c362
-rw-r--r--drivers/media/video/gspca/ov519.c7
-rw-r--r--drivers/media/video/gspca/ov534.c820
-rw-r--r--drivers/media/video/gspca/pac207.c8
-rw-r--r--drivers/media/video/gspca/pac7311.c7
-rw-r--r--drivers/media/video/gspca/sonixb.c7
-rw-r--r--drivers/media/video/gspca/sonixj.c951
-rw-r--r--drivers/media/video/gspca/spca500.c99
-rw-r--r--drivers/media/video/gspca/spca501.c22
-rw-r--r--drivers/media/video/gspca/spca505.c525
-rw-r--r--drivers/media/video/gspca/spca506.c57
-rw-r--r--drivers/media/video/gspca/spca508.c128
-rw-r--r--drivers/media/video/gspca/spca561.c192
-rw-r--r--drivers/media/video/gspca/sq905.c456
-rw-r--r--drivers/media/video/gspca/sq905c.c328
-rw-r--r--drivers/media/video/gspca/stk014.c72
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c7
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c76
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h65
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c147
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h130
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_sensor.h8
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c123
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h58
-rw-r--r--drivers/media/video/gspca/sunplus.c124
-rw-r--r--drivers/media/video/gspca/t613.c564
-rw-r--r--drivers/media/video/gspca/tv8532.c483
-rw-r--r--drivers/media/video/gspca/vc032x.c1591
-rw-r--r--drivers/media/video/gspca/zc3xx.c884
-rw-r--r--drivers/media/video/hdpvr/Kconfig10
-rw-r--r--drivers/media/video/hdpvr/Makefile9
-rw-r--r--drivers/media/video/hdpvr/hdpvr-control.c201
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c466
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c145
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c1248
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h303
-rw-r--r--drivers/media/video/hexium_gemini.c292
-rw-r--r--drivers/media/video/hexium_orion.c103
-rw-r--r--drivers/media/video/indycam.c314
-rw-r--r--drivers/media/video/indycam.h19
-rw-r--r--drivers/media/video/ir-kbd-i2c.c84
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c93
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h26
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-firmware.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-gpio.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c14
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c20
-rw-r--r--drivers/media/video/ivtv/ivtv-irq.c4
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.c8
-rw-r--r--drivers/media/video/ivtv/ivtv-queue.h8
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c68
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.h4
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-version.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c6
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c6
-rw-r--r--drivers/media/video/ks0127.c677
-rw-r--r--drivers/media/video/ks0127.h2
-rw-r--r--drivers/media/video/m52790.c7
-rw-r--r--drivers/media/video/meye.c45
-rw-r--r--drivers/media/video/msp3400-driver.c142
-rw-r--r--drivers/media/video/mt9m001.c164
-rw-r--r--drivers/media/video/mt9m111.c64
-rw-r--r--drivers/media/video/mt9t031.c179
-rw-r--r--drivers/media/video/mt9v022.c205
-rw-r--r--drivers/media/video/mx3_camera.c1220
-rw-r--r--drivers/media/video/mxb.c828
-rw-r--r--drivers/media/video/omap24xxcam.c7
-rw-r--r--drivers/media/video/ov7670.c552
-rw-r--r--drivers/media/video/ov772x.c320
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_core.c197
-rw-r--r--drivers/media/video/ovcamchip/ovcamchip_priv.h7
-rw-r--r--drivers/media/video/pvrusb2/Kconfig8
-rw-r--r--drivers/media/video/pvrusb2/Makefile7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.c142
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-audio.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c95
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h (renamed from drivers/media/video/pvrusb2/pvrusb2-tuner.h)21
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c245
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.c5
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-debugifc.h12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c102
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h34
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-dvb.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-encoder.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h50
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c648
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.h6
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c113
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c322
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h50
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c417
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.h57
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-main.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c12
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-tuner.c120
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.c214
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-video-v4l.h7
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.c134
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-wm8775.h4
-rw-r--r--drivers/media/video/pwc/Kconfig10
-rw-r--r--drivers/media/video/pwc/pwc-if.c79
-rw-r--r--drivers/media/video/pwc/pwc.h6
-rw-r--r--drivers/media/video/pxa_camera.c68
-rw-r--r--drivers/media/video/s2255drv.c41
-rw-r--r--drivers/media/video/saa5246a.c70
-rw-r--r--drivers/media/video/saa5249.c71
-rw-r--r--drivers/media/video/saa6588.c207
-rw-r--r--drivers/media/video/saa7110.c472
-rw-r--r--drivers/media/video/saa7111.c492
-rw-r--r--drivers/media/video/saa7114.c1068
-rw-r--r--drivers/media/video/saa7115.c64
-rw-r--r--drivers/media/video/saa7127.c1
-rw-r--r--drivers/media/video/saa7134/Kconfig13
-rw-r--r--drivers/media/video/saa7134/saa6752hs.c581
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c333
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c108
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c75
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c27
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c23
-rw-r--r--drivers/media/video/saa7134/saa7134-ts.c15
-rw-r--r--drivers/media/video/saa7134/saa7134-video.c75
-rw-r--r--drivers/media/video/saa7134/saa7134.h40
-rw-r--r--drivers/media/video/saa7146.h2
-rw-r--r--drivers/media/video/saa717x.c10
-rw-r--r--drivers/media/video/saa7185.c239
-rw-r--r--drivers/media/video/saa7191.c500
-rw-r--r--drivers/media/video/saa7191.h26
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c82
-rw-r--r--drivers/media/video/sn9c102/sn9c102_devtable.h4
-rw-r--r--drivers/media/video/soc_camera.c135
-rw-r--r--drivers/media/video/soc_camera_platform.c9
-rw-r--r--drivers/media/video/stk-webcam.c24
-rw-r--r--drivers/media/video/tcm825x.c22
-rw-r--r--drivers/media/video/tcm825x.h2
-rw-r--r--drivers/media/video/tda7432.c22
-rw-r--r--drivers/media/video/tda9840.c82
-rw-r--r--drivers/media/video/tda9840.h14
-rw-r--r--drivers/media/video/tda9875.c19
-rw-r--r--drivers/media/video/tea6415c.c53
-rw-r--r--drivers/media/video/tea6415c.h12
-rw-r--r--drivers/media/video/tea6420.c69
-rw-r--r--drivers/media/video/tea6420.h27
-rw-r--r--drivers/media/video/tlv320aic23b.c12
-rw-r--r--drivers/media/video/tuner-core.c152
-rw-r--r--drivers/media/video/tvaudio.c173
-rw-r--r--drivers/media/video/tveeprom.c7
-rw-r--r--drivers/media/video/tvp514x.c113
-rw-r--r--drivers/media/video/tvp5150.c10
-rw-r--r--drivers/media/video/tw9910.c36
-rw-r--r--drivers/media/video/upd64031a.c7
-rw-r--r--drivers/media/video/upd64083.c7
-rw-r--r--drivers/media/video/usbvideo/vicam.c2
-rw-r--r--drivers/media/video/usbvision/usbvision-core.c49
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c153
-rw-r--r--drivers/media/video/usbvision/usbvision-video.c125
-rw-r--r--drivers/media/video/usbvision/usbvision.h10
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c2
-rw-r--r--drivers/media/video/uvc/uvc_driver.c45
-rw-r--r--drivers/media/video/uvc/uvc_status.c16
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c20
-rw-r--r--drivers/media/video/uvc/uvc_video.c133
-rw-r--r--drivers/media/video/uvc/uvcvideo.h8
-rw-r--r--drivers/media/video/v4l2-common.c265
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c1
-rw-r--r--drivers/media/video/v4l2-dev.c54
-rw-r--r--drivers/media/video/v4l2-device.c58
-rw-r--r--drivers/media/video/v4l2-ioctl.c192
-rw-r--r--drivers/media/video/v4l2-subdev.c18
-rw-r--r--drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--drivers/media/video/videobuf-vmalloc.c2
-rw-r--r--drivers/media/video/vino.c1655
-rw-r--r--drivers/media/video/vivi.c495
-rw-r--r--drivers/media/video/vp27smpx.c7
-rw-r--r--drivers/media/video/vpx3220.c491
-rw-r--r--drivers/media/video/w9966.c2
-rw-r--r--drivers/media/video/w9968cf.c133
-rw-r--r--drivers/media/video/w9968cf.h24
-rw-r--r--drivers/media/video/wm8739.c7
-rw-r--r--drivers/media/video/wm8775.c12
-rw-r--r--drivers/media/video/zc0301/zc0301_sensor.h8
-rw-r--r--drivers/media/video/zoran/Kconfig8
-rw-r--r--drivers/media/video/zoran/videocodec.h9
-rw-r--r--drivers/media/video/zoran/zoran.h97
-rw-r--r--drivers/media/video/zoran/zoran_card.c555
-rw-r--r--drivers/media/video/zoran/zoran_card.h3
-rw-r--r--drivers/media/video/zoran/zoran_device.c529
-rw-r--r--drivers/media/video/zoran/zoran_device.h14
-rw-r--r--drivers/media/video/zoran/zoran_driver.c4385
-rw-r--r--drivers/media/video/zoran/zoran_procfs.c2
-rw-r--r--drivers/media/video/zoran/zr36016.c5
-rw-r--r--drivers/media/video/zoran/zr36050.c4
-rw-r--r--drivers/media/video/zoran/zr36060.c4
-rw-r--r--drivers/media/video/zr364xx.c17
-rw-r--r--drivers/message/fusion/mptsas.c5
-rw-r--r--drivers/message/i2o/i2o_proc.c2
-rw-r--r--drivers/mfd/Kconfig3
-rw-r--r--drivers/mfd/da903x.c2
-rw-r--r--drivers/mfd/htc-pasic3.c169
-rw-r--r--drivers/mfd/pcf50633-core.c1
-rw-r--r--drivers/mfd/t7l66xb.c4
-rw-r--r--drivers/mfd/tc6393xb.c2
-rw-r--r--drivers/mfd/twl4030-core.c2
-rw-r--r--drivers/mfd/twl4030-irq.c2
-rw-r--r--drivers/mfd/wm8350-core.c39
-rw-r--r--drivers/misc/Kconfig20
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/eeprom/at24.c67
-rw-r--r--drivers/misc/eeprom/at25.c58
-rw-r--r--drivers/misc/hpilo.c6
-rw-r--r--drivers/misc/hpilo.h6
-rw-r--r--drivers/misc/isl29003.c470
-rw-r--r--drivers/misc/sgi-gru/Makefile2
-rw-r--r--drivers/misc/sgi-gru/gru_instructions.h22
-rw-r--r--drivers/misc/sgi-gru/grufault.c130
-rw-r--r--drivers/misc/sgi-gru/grufile.c36
-rw-r--r--drivers/misc/sgi-gru/gruhandles.c183
-rw-r--r--drivers/misc/sgi-gru/gruhandles.h178
-rw-r--r--drivers/misc/sgi-gru/grukservices.c131
-rw-r--r--drivers/misc/sgi-gru/grukservices.h33
-rw-r--r--drivers/misc/sgi-gru/grumain.c84
-rw-r--r--drivers/misc/sgi-gru/gruprocfs.c45
-rw-r--r--drivers/misc/sgi-gru/grutables.h41
-rw-r--r--drivers/misc/sgi-gru/grutlbpurge.c7
-rw-r--r--drivers/misc/sgi-xp/xpc.h33
-rw-r--r--drivers/misc/sgi-xp/xpc_channel.c8
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c6
-rw-r--r--drivers/misc/sgi-xp/xpc_sn2.c20
-rw-r--r--drivers/misc/sgi-xp/xpc_uv.c229
-rw-r--r--drivers/mmc/card/block.c2
-rw-r--r--drivers/mmc/card/sdio_uart.c62
-rw-r--r--drivers/mmc/core/bus.c8
-rw-r--r--drivers/mmc/core/core.c118
-rw-r--r--drivers/mmc/core/debugfs.c67
-rw-r--r--drivers/mmc/core/sdio_cis.c8
-rw-r--r--drivers/mmc/core/sdio_ops.c8
-rw-r--r--drivers/mmc/host/Kconfig31
-rw-r--r--drivers/mmc/host/Makefile2
-rw-r--r--drivers/mmc/host/atmel-mci.c2
-rw-r--r--drivers/mmc/host/mmc_spi.c40
-rw-r--r--drivers/mmc/host/mvsdio.c885
-rw-r--r--drivers/mmc/host/mvsdio.h190
-rw-r--r--drivers/mmc/host/omap_hsmmc.c355
-rw-r--r--drivers/mmc/host/sdhci-of.c309
-rw-r--r--drivers/mmc/host/sdhci.c317
-rw-r--r--drivers/mmc/host/sdhci.h112
-rw-r--r--drivers/mmc/host/tmio_mmc.c6
-rw-r--r--drivers/mmc/host/tmio_mmc.h3
-rw-r--r--drivers/mtd/Makefile2
-rw-r--r--drivers/mtd/ar7part.c6
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0001.c8
-rw-r--r--drivers/mtd/chips/cfi_cmdset_0002.c11
-rw-r--r--drivers/mtd/chips/jedec_probe.c16
-rw-r--r--drivers/mtd/chips/map_ram.c17
-rw-r--r--drivers/mtd/chips/map_rom.c17
-rw-r--r--drivers/mtd/cmdlinepart.c6
-rw-r--r--drivers/mtd/devices/doc2000.c1
-rw-r--r--drivers/mtd/devices/doc2001.c1
-rw-r--r--drivers/mtd/devices/doc2001plus.c1
-rw-r--r--drivers/mtd/devices/docecc.c1
-rw-r--r--drivers/mtd/devices/m25p80.c19
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c18
-rw-r--r--drivers/mtd/devices/mtdram.c14
-rw-r--r--drivers/mtd/inftlmount.c1
-rw-r--r--drivers/mtd/internal.h17
-rw-r--r--drivers/mtd/maps/Kconfig12
-rw-r--r--drivers/mtd/maps/Makefile2
-rw-r--r--drivers/mtd/maps/omap_nor.c2
-rw-r--r--drivers/mtd/maps/physmap.c1
-rw-r--r--drivers/mtd/maps/physmap_of.c1
-rw-r--r--drivers/mtd/maps/plat-ram.c1
-rw-r--r--drivers/mtd/maps/pxa2xx-flash.c2
-rw-r--r--drivers/mtd/maps/rbtx4939-flash.c208
-rw-r--r--drivers/mtd/maps/sa1100-flash.c2
-rw-r--r--drivers/mtd/maps/sharpsl-flash.c116
-rw-r--r--drivers/mtd/mtd_blkdevs.c4
-rw-r--r--drivers/mtd/mtdbdi.c43
-rw-r--r--drivers/mtd/mtdchar.c111
-rw-r--r--drivers/mtd/mtdconcat.c47
-rw-r--r--drivers/mtd/mtdcore.c208
-rw-r--r--drivers/mtd/mtdoops.c16
-rw-r--r--drivers/mtd/mtdpart.c31
-rw-r--r--drivers/mtd/nand/Kconfig21
-rw-r--r--drivers/mtd/nand/Makefile3
-rw-r--r--drivers/mtd/nand/bf5xx_nand.c18
-rw-r--r--drivers/mtd/nand/cafe_nand.c1
-rw-r--r--drivers/mtd/nand/davinci_nand.c570
-rw-r--r--drivers/mtd/nand/diskonchip.c2
-rw-r--r--drivers/mtd/nand/fsl_upm.c119
-rw-r--r--drivers/mtd/nand/mxc_nand.c1
-rw-r--r--drivers/mtd/nand/nand_base.c129
-rw-r--r--drivers/mtd/nand/plat_nand.c2
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c119
-rw-r--r--drivers/mtd/nand/sh_flctl.c18
-rw-r--r--drivers/mtd/nand/socrates_nand.c325
-rw-r--r--drivers/mtd/nand/txx9ndfmc.c428
-rw-r--r--drivers/mtd/nftlcore.c3
-rw-r--r--drivers/mtd/ofpart.c7
-rw-r--r--drivers/mtd/onenand/omap2.c6
-rw-r--r--drivers/mtd/onenand/onenand_base.c145
-rw-r--r--drivers/mtd/tests/mtd_oobtest.c24
-rw-r--r--drivers/mtd/tests/mtd_readtest.c2
-rw-r--r--drivers/mtd/ubi/cdev.c11
-rw-r--r--drivers/net/bonding/bond_main.c35
-rw-r--r--drivers/net/dm9000.c2
-rw-r--r--drivers/net/fec_mpc52xx.c6
-rw-r--r--drivers/net/irda/vlsi_ir.c7
-rw-r--r--drivers/net/meth.c2
-rw-r--r--drivers/net/mlx4/en_netdev.c2
-rw-r--r--drivers/net/mlx4/en_rx.c2
-rw-r--r--drivers/net/mlx4/sense.c2
-rw-r--r--drivers/net/phy/phy.c3
-rw-r--r--drivers/net/sb1250-mac.c2
-rw-r--r--drivers/net/skfp/h/hwmtm.h2
-rw-r--r--drivers/net/smc91x.h32
-rw-r--r--drivers/net/tg3.c2
-rw-r--r--drivers/net/wan/farsync.c2
-rw-r--r--drivers/net/wireless/airo.c1
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c2
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c2
-rw-r--r--drivers/net/wireless/libertas/cmd.c2
-rw-r--r--drivers/of/base.c1
-rw-r--r--drivers/oprofile/buffer_sync.c20
-rw-r--r--drivers/oprofile/buffer_sync.h4
-rw-r--r--drivers/oprofile/cpu_buffer.c5
-rw-r--r--drivers/oprofile/oprof.c9
-rw-r--r--drivers/parisc/asp.c2
-rw-r--r--drivers/parisc/ccio-dma.c16
-rw-r--r--drivers/parisc/dino.c7
-rw-r--r--drivers/parisc/eisa.c2
-rw-r--r--drivers/parisc/eisa_enumerator.c4
-rw-r--r--drivers/parisc/iosapic.c2
-rw-r--r--drivers/parisc/led.c26
-rw-r--r--drivers/parport/parport_serial.c30
-rw-r--r--drivers/pci/Kconfig10
-rw-r--r--drivers/pci/Makefile2
-rw-r--r--drivers/pci/bus.c8
-rw-r--r--drivers/pci/dmar.c361
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c58
-rw-r--r--drivers/pci/hotplug/fakephp.c444
-rw-r--r--drivers/pci/hotplug/pciehp.h13
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c21
-rw-r--r--drivers/pci/hotplug/pciehp_core.c18
-rw-r--r--drivers/pci/hotplug/pciehp_hpc.c34
-rw-r--r--drivers/pci/hotplug/shpchp.h10
-rw-r--r--drivers/pci/hotplug/shpchp_pci.c2
-rw-r--r--drivers/pci/intel-iommu.c620
-rw-r--r--drivers/pci/intr_remapping.c190
-rw-r--r--drivers/pci/iov.c680
-rw-r--r--drivers/pci/msi.c426
-rw-r--r--drivers/pci/msi.h6
-rw-r--r--drivers/pci/pci-acpi.c219
-rw-r--r--drivers/pci/pci-driver.c261
-rw-r--r--drivers/pci/pci-sysfs.c124
-rw-r--r--drivers/pci/pci.c337
-rw-r--r--drivers/pci/pci.h66
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c28
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c10
-rw-r--r--drivers/pci/pcie/portdrv.h14
-rw-r--r--drivers/pci/pcie/portdrv_bus.c18
-rw-r--r--drivers/pci/pcie/portdrv_core.c379
-rw-r--r--drivers/pci/pcie/portdrv_pci.c50
-rw-r--r--drivers/pci/probe.c210
-rw-r--r--drivers/pci/quirks.c221
-rw-r--r--drivers/pci/remove.c4
-rw-r--r--drivers/pci/search.c2
-rw-r--r--drivers/pci/setup-bus.c7
-rw-r--r--drivers/pci/setup-res.c15
-rw-r--r--drivers/pci/slot.c18
-rw-r--r--drivers/pcmcia/pxa2xx_cm_x255.c2
-rw-r--r--drivers/platform/x86/Kconfig35
-rw-r--r--drivers/platform/x86/Makefile1
-rw-r--r--drivers/platform/x86/acer-wmi.c35
-rw-r--r--drivers/platform/x86/asus_acpi.c3
-rw-r--r--drivers/platform/x86/dell-laptop.c4
-rw-r--r--drivers/platform/x86/dell-wmi.c210
-rw-r--r--drivers/platform/x86/hp-wmi.c25
-rw-r--r--drivers/platform/x86/intel_menlow.c29
-rw-r--r--drivers/platform/x86/panasonic-laptop.c9
-rw-r--r--drivers/platform/x86/sony-laptop.c531
-rw-r--r--drivers/platform/x86/tc1100-wmi.c7
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c739
-rw-r--r--drivers/platform/x86/toshiba_acpi.c3
-rw-r--r--drivers/pnp/pnpacpi/core.c23
-rw-r--r--drivers/pnp/pnpbios/core.c16
-rw-r--r--drivers/power/bq27x00_battery.c2
-rw-r--r--drivers/power/power_supply_sysfs.c2
-rw-r--r--drivers/ps3/ps3av.c16
-rw-r--r--drivers/regulator/Kconfig13
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/bq24022.c3
-rw-r--r--drivers/regulator/core.c386
-rw-r--r--drivers/regulator/da903x.c3
-rw-r--r--drivers/regulator/fixed.c3
-rw-r--r--drivers/regulator/pcf50633-regulator.c3
-rw-r--r--drivers/regulator/twl4030-regulator.c500
-rw-r--r--drivers/regulator/virtual.c14
-rw-r--r--drivers/regulator/wm8350-regulator.c57
-rw-r--r--drivers/regulator/wm8400-regulator.c36
-rw-r--r--drivers/rtc/Kconfig50
-rw-r--r--drivers/rtc/Makefile5
-rw-r--r--drivers/rtc/rtc-ds1307.c189
-rw-r--r--drivers/rtc/rtc-ds1374.c6
-rw-r--r--drivers/rtc/rtc-efi.c235
-rw-r--r--drivers/rtc/rtc-generic.c84
-rw-r--r--drivers/rtc/rtc-lib.c7
-rw-r--r--drivers/rtc/rtc-m41t80.c18
-rw-r--r--drivers/rtc/rtc-parisc.c112
-rw-r--r--drivers/rtc/rtc-ppc.c69
-rw-r--r--drivers/rtc/rtc-proc.c10
-rw-r--r--drivers/rtc/rtc-ps3.c104
-rw-r--r--drivers/rtc/rtc-sh.c36
-rw-r--r--drivers/rtc/rtc-v3020.c230
-rw-r--r--drivers/rtc/rtc-wm8350.c43
-rw-r--r--drivers/s390/block/dasd.c1
-rw-r--r--drivers/s390/block/dasd_proc.c2
-rw-r--r--drivers/s390/cio/device.c43
-rw-r--r--drivers/s390/cio/device.h1
-rw-r--r--drivers/s390/cio/device_fsm.c31
-rw-r--r--drivers/s390/net/qeth_core_offl.c0
-rw-r--r--drivers/s390/net/qeth_core_offl.h0
-rw-r--r--drivers/s390/scsi/zfcp_ccw.c5
-rw-r--r--drivers/s390/scsi/zfcp_fc.c2
-rw-r--r--drivers/scsi/Kconfig21
-rw-r--r--drivers/scsi/Makefile1
-rw-r--r--drivers/scsi/a2091.c6
-rw-r--r--drivers/scsi/a2091.h3
-rw-r--r--drivers/scsi/a3000.c6
-rw-r--r--drivers/scsi/a3000.h3
-rw-r--r--drivers/scsi/aacraid/aachba.c40
-rw-r--r--drivers/scsi/aacraid/aacraid.h9
-rw-r--r--drivers/scsi/aacraid/comminit.c14
-rw-r--r--drivers/scsi/aacraid/linit.c8
-rw-r--r--drivers/scsi/advansys.c1731
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_core.c12
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_inline.h32
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.h102
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_pci.c8
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_inline.h5
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.h104
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_pci.c10
-rw-r--r--drivers/scsi/aic7xxx/aiclib.h4
-rw-r--r--drivers/scsi/cxgb3i/Kbuild4
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i.h10
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.c275
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_ddp.h6
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_init.c31
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_iscsi.c129
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.c101
-rw-r--r--drivers/scsi/cxgb3i/cxgb3i_offload.h13
-rw-r--r--drivers/scsi/fcoe/Makefile8
-rw-r--r--drivers/scsi/fcoe/fc_transport_fcoe.c443
-rw-r--r--drivers/scsi/fcoe/fcoe.c1878
-rw-r--r--drivers/scsi/fcoe/fcoe.h75
-rw-r--r--drivers/scsi/fcoe/fcoe_sw.c561
-rw-r--r--drivers/scsi/fcoe/libfcoe.c2216
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.c126
-rw-r--r--drivers/scsi/ibmvscsi/ibmvfc.h16
-rw-r--r--drivers/scsi/libfc/fc_fcp.c10
-rw-r--r--drivers/scsi/libfc/fc_lport.c11
-rw-r--r--drivers/scsi/libiscsi.c4
-rw-r--r--drivers/scsi/osd/osd_initiator.c42
-rw-r--r--drivers/scsi/osd/osd_uld.c6
-rw-r--r--drivers/scsi/ql1040_fw.h2130
-rw-r--r--drivers/scsi/ql12160_fw.h1811
-rw-r--r--drivers/scsi/ql1280_fw.h2048
-rw-r--r--drivers/scsi/qla1280.c114
-rw-r--r--drivers/scsi/qla1280.h6
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c295
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h136
-rw-r--r--drivers/scsi/qla2xxx/qla_dfs.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_fw.h42
-rw-r--r--drivers/scsi/qla2xxx/qla_gbl.h25
-rw-r--r--drivers/scsi/qla2xxx/qla_init.c136
-rw-r--r--drivers/scsi/qla2xxx/qla_iocb.c37
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c32
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c238
-rw-r--r--drivers/scsi/qla2xxx/qla_mid.c12
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c258
-rw-r--r--drivers/scsi/qla2xxx/qla_sup.c103
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h4
-rw-r--r--drivers/scsi/qlogicpti.c63
-rw-r--r--drivers/scsi/qlogicpti_asm.c1160
-rw-r--r--drivers/scsi/scsi.c4
-rw-r--r--drivers/scsi/scsi_devinfo.c2
-rw-r--r--drivers/scsi/scsi_lib.c17
-rw-r--r--drivers/scsi/scsi_proc.c3
-rw-r--r--drivers/scsi/sd.c6
-rw-r--r--drivers/scsi/ses.c2
-rw-r--r--drivers/scsi/sg.c37
-rw-r--r--drivers/scsi/sr.c9
-rw-r--r--drivers/scsi/stex.c742
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.h6
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_hipd.h6
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_malloc.c2
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_misc.h18
-rw-r--r--drivers/serial/8250_pci.c412
-rw-r--r--drivers/serial/8250_pnp.c7
-rw-r--r--drivers/serial/Kconfig4
-rw-r--r--drivers/serial/atmel_serial.c9
-rw-r--r--drivers/serial/bfin_5xx.c15
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_core.c14
-rw-r--r--drivers/serial/icom.c14
-rw-r--r--drivers/serial/jsm/jsm_driver.c9
-rw-r--r--drivers/serial/jsm/jsm_tty.c4
-rw-r--r--drivers/serial/mcf.c2
-rw-r--r--drivers/serial/mpc52xx_uart.c40
-rw-r--r--drivers/serial/serial_core.c76
-rw-r--r--drivers/serial/ucc_uart.c1
-rw-r--r--drivers/sh/intc.c68
-rw-r--r--drivers/sh/maple/maple.c2
-rw-r--r--drivers/spi/spi_gpio.c21
-rw-r--r--drivers/spi/spi_mpc83xx.c366
-rw-r--r--drivers/spi/xilinx_spi.c9
-rw-r--r--drivers/staging/Kconfig26
-rw-r--r--drivers/staging/Makefile11
-rw-r--r--drivers/staging/agnx/agnx.h14
-rw-r--r--drivers/staging/agnx/debug.h21
-rw-r--r--drivers/staging/agnx/pci.c75
-rw-r--r--drivers/staging/agnx/phy.c32
-rw-r--r--drivers/staging/agnx/rf.c23
-rw-r--r--drivers/staging/agnx/sta.c21
-rw-r--r--drivers/staging/agnx/sta.h2
-rw-r--r--drivers/staging/agnx/table.c12
-rw-r--r--drivers/staging/agnx/xmit.c216
-rw-r--r--drivers/staging/altpciechdma/altpciechdma.c80
-rw-r--r--drivers/staging/android/binder.c18
-rw-r--r--drivers/staging/android/ram_console.c8
-rw-r--r--drivers/staging/asus_oled/asus_oled.c149
-rw-r--r--drivers/staging/at76_usb/TODO9
-rw-r--r--drivers/staging/at76_usb/at76_usb.c21
-rw-r--r--drivers/staging/at76_usb/at76_usb.h87
-rw-r--r--drivers/staging/b3dfg/Kconfig9
-rw-r--r--drivers/staging/b3dfg/Makefile1
-rw-r--r--drivers/staging/b3dfg/TODO4
-rw-r--r--drivers/staging/b3dfg/b3dfg.c1119
-rw-r--r--drivers/staging/comedi/Kconfig18
-rw-r--r--drivers/staging/comedi/comedi.h83
-rw-r--r--drivers/staging/comedi/comedi_compat32.c128
-rw-r--r--drivers/staging/comedi/comedi_fops.c293
-rw-r--r--drivers/staging/comedi/comedi_fops.h1
-rw-r--r--drivers/staging/comedi/comedi_ksyms.c12
-rw-r--r--drivers/staging/comedi/comedi_rt.h9
-rw-r--r--drivers/staging/comedi/comedidev.h202
-rw-r--r--drivers/staging/comedi/comedilib.h114
-rw-r--r--drivers/staging/comedi/drivers.c187
-rw-r--r--drivers/staging/comedi/drivers/8253.h420
-rw-r--r--drivers/staging/comedi/drivers/8255.c442
-rw-r--r--drivers/staging/comedi/drivers/8255.h57
-rw-r--r--drivers/staging/comedi/drivers/Makefile113
-rw-r--r--drivers/staging/comedi/drivers/acl7225b.c149
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c1047
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h73
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c2032
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h74
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c1020
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h46
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c5363
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h271
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c861
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h47
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c3588
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h76
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c848
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h43
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c2049
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h57
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c1038
-rw-r--r--drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h44
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c203
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h27
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h476
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.c3062
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_common.h462
-rw-r--r--drivers/staging/comedi/drivers/addi-data/addi_eeprom.c1158
-rw-r--r--drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h457
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c1265
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h71
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c600
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h123
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c285
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h63
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c3045
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h165
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c542
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h64
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c1105
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h119
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c780
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h94
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c460
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h70
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c579
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h81
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c549
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h61
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c2697
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h241
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c3642
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h187
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c742
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h94
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c1691
-rw-r--r--drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h62
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_035.c5
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1032.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1500.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1516.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1564.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_16xx.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_1710.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2016.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2032.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_2200.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3001.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3120.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3200.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3300.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3501.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_3xxx.c3
-rw-r--r--drivers/staging/comedi/drivers/addi_apci_all.c18
-rw-r--r--drivers/staging/comedi/drivers/adl_pci6208.c391
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7296.c174
-rw-r--r--drivers/staging/comedi/drivers/adl_pci7432.c202
-rw-r--r--drivers/staging/comedi/drivers/adl_pci8164.c512
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9111.c1391
-rw-r--r--drivers/staging/comedi/drivers/adl_pci9118.c2100
-rw-r--r--drivers/staging/comedi/drivers/adq12b.c394
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1710.c1568
-rw-r--r--drivers/staging/comedi/drivers/adv_pci1723.c465
-rw-r--r--drivers/staging/comedi/drivers/adv_pci_dio.c1077
-rw-r--r--drivers/staging/comedi/drivers/aio_aio12_8.c226
-rw-r--r--drivers/staging/comedi/drivers/aio_iiro_16.c177
-rw-r--r--drivers/staging/comedi/drivers/am9513.h79
-rw-r--r--drivers/staging/comedi/drivers/amcc_s5933.h172
-rw-r--r--drivers/staging/comedi/drivers/amplc_dio200.c1483
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc236.c654
-rw-r--r--drivers/staging/comedi/drivers/amplc_pc263.c431
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci224.c1545
-rw-r--r--drivers/staging/comedi/drivers/amplc_pci230.c2977
-rw-r--r--drivers/staging/comedi/drivers/c6xdigio.c517
-rw-r--r--drivers/staging/comedi/drivers/cb_das16_cs.c976
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas.c1831
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidas64.c4222
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidda.c841
-rw-r--r--drivers/staging/comedi/drivers/cb_pcidio.c294
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdas.c484
-rw-r--r--drivers/staging/comedi/drivers/cb_pcimdda.c474
-rw-r--r--drivers/staging/comedi/drivers/comedi_bond.c56
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.c14
-rw-r--r--drivers/staging/comedi/drivers/comedi_fc.h18
-rw-r--r--drivers/staging/comedi/drivers/comedi_parport.c44
-rw-r--r--drivers/staging/comedi/drivers/comedi_rt_timer.c728
-rw-r--r--drivers/staging/comedi/drivers/comedi_test.c80
-rw-r--r--drivers/staging/comedi/drivers/contec_pci_dio.c230
-rw-r--r--drivers/staging/comedi/drivers/daqboard2000.c877
-rw-r--r--drivers/staging/comedi/drivers/das08.c1068
-rw-r--r--drivers/staging/comedi/drivers/das08.h78
-rw-r--r--drivers/staging/comedi/drivers/das08_cs.c488
-rw-r--r--drivers/staging/comedi/drivers/das16.c1730
-rw-r--r--drivers/staging/comedi/drivers/das16m1.c765
-rw-r--r--drivers/staging/comedi/drivers/das1800.c1758
-rw-r--r--drivers/staging/comedi/drivers/das6402.c354
-rw-r--r--drivers/staging/comedi/drivers/das800.c894
-rw-r--r--drivers/staging/comedi/drivers/dmm32at.c1081
-rw-r--r--drivers/staging/comedi/drivers/dt2801.c697
-rw-r--r--drivers/staging/comedi/drivers/dt2811.c604
-rw-r--r--drivers/staging/comedi/drivers/dt2814.c383
-rw-r--r--drivers/staging/comedi/drivers/dt2815.c264
-rw-r--r--drivers/staging/comedi/drivers/dt2817.c178
-rw-r--r--drivers/staging/comedi/drivers/dt282x.c1471
-rw-r--r--drivers/staging/comedi/drivers/dt3000.c983
-rw-r--r--drivers/staging/comedi/drivers/dt9812.c40
-rw-r--r--drivers/staging/comedi/drivers/fl512.c186
-rw-r--r--drivers/staging/comedi/drivers/gsc_hpdi.c1060
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.c392
-rw-r--r--drivers/staging/comedi/drivers/icp_multi.h19
-rw-r--r--drivers/staging/comedi/drivers/ii_pci20kc.c612
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.c976
-rw-r--r--drivers/staging/comedi/drivers/jr3_pci.h681
-rw-r--r--drivers/staging/comedi/drivers/ke_counter.c254
-rw-r--r--drivers/staging/comedi/drivers/me4000.c296
-rw-r--r--drivers/staging/comedi/drivers/me4000.h268
-rw-r--r--drivers/staging/comedi/drivers/me_daq.c55
-rw-r--r--drivers/staging/comedi/drivers/mite.c63
-rw-r--r--drivers/staging/comedi/drivers/mite.h68
-rw-r--r--drivers/staging/comedi/drivers/mpc624.c386
-rw-r--r--drivers/staging/comedi/drivers/mpc8260cpm.c169
-rw-r--r--drivers/staging/comedi/drivers/multiq3.c333
-rw-r--r--drivers/staging/comedi/drivers/ni_6527.c489
-rw-r--r--drivers/staging/comedi/drivers/ni_65xx.c809
-rw-r--r--drivers/staging/comedi/drivers/ni_660x.c1324
-rw-r--r--drivers/staging/comedi/drivers/ni_670x.c337
-rw-r--r--drivers/staging/comedi/drivers/ni_at_a2150.c909
-rw-r--r--drivers/staging/comedi/drivers/ni_at_ao.c454
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio.c513
-rw-r--r--drivers/staging/comedi/drivers/ni_atmio16d.c860
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_700.c841
-rw-r--r--drivers/staging/comedi/drivers/ni_daq_dio24.c598
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.c2005
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc.h85
-rw-r--r--drivers/staging/comedi/drivers/ni_labpc_cs.c573
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_common.c5862
-rw-r--r--drivers/staging/comedi/drivers/ni_mio_cs.c551
-rw-r--r--drivers/staging/comedi/drivers/ni_pcidio.c1302
-rw-r--r--drivers/staging/comedi/drivers/ni_pcimio.c1788
-rw-r--r--drivers/staging/comedi/drivers/ni_stc.h1498
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.c1691
-rw-r--r--drivers/staging/comedi/drivers/ni_tio.h163
-rw-r--r--drivers/staging/comedi/drivers/ni_tio_internal.h774
-rw-r--r--drivers/staging/comedi/drivers/ni_tiocmd.c523
-rw-r--r--drivers/staging/comedi/drivers/pcl711.c623
-rw-r--r--drivers/staging/comedi/drivers/pcl724.c222
-rw-r--r--drivers/staging/comedi/drivers/pcl725.c111
-rw-r--r--drivers/staging/comedi/drivers/pcl726.c377
-rw-r--r--drivers/staging/comedi/drivers/pcl730.c168
-rw-r--r--drivers/staging/comedi/drivers/pcl812.c1605
-rw-r--r--drivers/staging/comedi/drivers/pcl816.c1251
-rw-r--r--drivers/staging/comedi/drivers/pcl818.c1988
-rw-r--r--drivers/staging/comedi/drivers/pcm3724.c307
-rw-r--r--drivers/staging/comedi/drivers/pcm3730.c152
-rw-r--r--drivers/staging/comedi/drivers/pcmad.c173
-rw-r--r--drivers/staging/comedi/drivers/pcmda12.c306
-rw-r--r--drivers/staging/comedi/drivers/pcmmio.c1333
-rw-r--r--drivers/staging/comedi/drivers/pcmuio.c1101
-rw-r--r--drivers/staging/comedi/drivers/plx9052.h86
-rw-r--r--drivers/staging/comedi/drivers/plx9080.h80
-rw-r--r--drivers/staging/comedi/drivers/poc.c247
-rw-r--r--drivers/staging/comedi/drivers/quatech_daqp_cs.c1363
-rw-r--r--drivers/staging/comedi/drivers/rtd520.c277
-rw-r--r--drivers/staging/comedi/drivers/rtd520.h676
-rw-r--r--drivers/staging/comedi/drivers/rti800.c458
-rw-r--r--drivers/staging/comedi/drivers/rti802.c151
-rw-r--r--drivers/staging/comedi/drivers/s526.c977
-rw-r--r--drivers/staging/comedi/drivers/s626.c2538
-rw-r--r--drivers/staging/comedi/drivers/s626.h1226
-rw-r--r--drivers/staging/comedi/drivers/serial2002.c870
-rw-r--r--drivers/staging/comedi/drivers/skel.c624
-rw-r--r--drivers/staging/comedi/drivers/ssv_dnp.c311
-rw-r--r--drivers/staging/comedi/drivers/unioxx5.c515
-rw-r--r--drivers/staging/comedi/drivers/usbdux.c304
-rw-r--r--drivers/staging/comedi/drivers/usbduxfast.c2028
-rw-r--r--drivers/staging/comedi/interrupt.h9
-rw-r--r--drivers/staging/comedi/kcomedilib/data.c22
-rw-r--r--drivers/staging/comedi/kcomedilib/dio.c18
-rw-r--r--drivers/staging/comedi/kcomedilib/get.c132
-rw-r--r--drivers/staging/comedi/kcomedilib/kcomedilib_main.c138
-rw-r--r--drivers/staging/comedi/kcomedilib/ksyms.c4
-rw-r--r--drivers/staging/comedi/pci_ids.h2
-rw-r--r--drivers/staging/comedi/proc.c17
-rw-r--r--drivers/staging/comedi/range.c35
-rw-r--r--drivers/staging/comedi/rt.c29
-rw-r--r--drivers/staging/comedi/rt_pend_tq.c8
-rw-r--r--drivers/staging/dst/Kconfig67
-rw-r--r--drivers/staging/dst/Makefile3
-rw-r--r--drivers/staging/dst/crypto.c731
-rw-r--r--drivers/staging/dst/dcore.c995
-rw-r--r--drivers/staging/dst/export.c657
-rw-r--r--drivers/staging/dst/state.c839
-rw-r--r--drivers/staging/dst/thread_pool.c345
-rw-r--r--drivers/staging/dst/trans.c335
-rw-r--r--drivers/staging/echo/bit_operations.h30
-rw-r--r--drivers/staging/echo/echo.c42
-rw-r--r--drivers/staging/echo/echo.h2
-rw-r--r--drivers/staging/echo/fir.h28
-rw-r--r--drivers/staging/echo/mmx.h408
-rw-r--r--drivers/staging/epl/Benchmark.h12
-rw-r--r--drivers/staging/epl/Debug.h48
-rw-r--r--drivers/staging/epl/Edrv8139.c108
-rw-r--r--drivers/staging/epl/EdrvFec.h6
-rw-r--r--drivers/staging/epl/EdrvFec5282.h340
-rw-r--r--drivers/staging/epl/EdrvSim.h4
-rw-r--r--drivers/staging/epl/Epl.h139
-rw-r--r--drivers/staging/epl/EplAmi.h121
-rw-r--r--drivers/staging/epl/EplApiGeneric.c188
-rw-r--r--drivers/staging/epl/EplApiLinuxKernel.c105
-rw-r--r--drivers/staging/epl/EplApiProcessImage.c31
-rw-r--r--drivers/staging/epl/EplDll.h50
-rw-r--r--drivers/staging/epl/EplDllCal.h2
-rw-r--r--drivers/staging/epl/EplDllk.c134
-rw-r--r--drivers/staging/epl/EplDllkCal.c14
-rw-r--r--drivers/staging/epl/EplDlluCal.c6
-rw-r--r--drivers/staging/epl/EplErrorHandlerk.c36
-rw-r--r--drivers/staging/epl/EplEvent.h8
-rw-r--r--drivers/staging/epl/EplEventk.c24
-rw-r--r--drivers/staging/epl/EplEventu.c25
-rw-r--r--drivers/staging/epl/EplFrame.h166
-rw-r--r--drivers/staging/epl/EplIdentu.c26
-rw-r--r--drivers/staging/epl/EplInc.h23
-rw-r--r--drivers/staging/epl/EplInstDef.h60
-rw-r--r--drivers/staging/epl/EplNmt.h2
-rw-r--r--drivers/staging/epl/EplNmtCnu.c39
-rw-r--r--drivers/staging/epl/EplNmtMnu.c121
-rw-r--r--drivers/staging/epl/EplNmtk.c30
-rw-r--r--drivers/staging/epl/EplNmtkCal.c2
-rw-r--r--drivers/staging/epl/EplNmtu.c22
-rw-r--r--drivers/staging/epl/EplNmtuCal.c2
-rw-r--r--drivers/staging/epl/EplObd.c444
-rw-r--r--drivers/staging/epl/EplObd.h58
-rw-r--r--drivers/staging/epl/EplObdMacro.h40
-rw-r--r--drivers/staging/epl/EplObdkCal.c1
-rw-r--r--drivers/staging/epl/EplObdu.c69
-rw-r--r--drivers/staging/epl/EplObduCal.c75
-rw-r--r--drivers/staging/epl/EplObjDef.h208
-rw-r--r--drivers/staging/epl/EplPdo.h6
-rw-r--r--drivers/staging/epl/EplPdok.c73
-rw-r--r--drivers/staging/epl/EplPdou.c34
-rw-r--r--drivers/staging/epl/EplSdo.h24
-rw-r--r--drivers/staging/epl/EplSdoAsndu.c26
-rw-r--r--drivers/staging/epl/EplSdoAsySequ.c72
-rw-r--r--drivers/staging/epl/EplSdoComu.c153
-rw-r--r--drivers/staging/epl/EplSdoUdpu.c163
-rw-r--r--drivers/staging/epl/EplStatusu.c19
-rw-r--r--drivers/staging/epl/EplTarget.h109
-rw-r--r--drivers/staging/epl/EplTimer.h3
-rw-r--r--drivers/staging/epl/EplTimeruLinuxKernel.c26
-rw-r--r--drivers/staging/epl/EplTimeruNull.c312
-rw-r--r--drivers/staging/epl/EplTimeruWin32.c513
-rw-r--r--drivers/staging/epl/SharedBuff.c111
-rw-r--r--drivers/staging/epl/SharedBuff.h17
-rw-r--r--drivers/staging/epl/ShbIpc-LinuxKernel.c48
-rw-r--r--drivers/staging/epl/ShbIpc-Win32.c1202
-rw-r--r--drivers/staging/epl/ShbIpc.h26
-rw-r--r--drivers/staging/epl/TimerHighReskX86.c34
-rw-r--r--drivers/staging/epl/VirtualEthernetLinux.c5
-rw-r--r--drivers/staging/epl/amix86.c316
-rw-r--r--drivers/staging/epl/demo_main.c84
-rw-r--r--drivers/staging/epl/edrv.h22
-rw-r--r--drivers/staging/epl/global.h1253
-rw-r--r--drivers/staging/epl/kernel/EplDllk.h24
-rw-r--r--drivers/staging/epl/kernel/EplDllkCal.h14
-rw-r--r--drivers/staging/epl/kernel/EplErrorHandlerk.h20
-rw-r--r--drivers/staging/epl/kernel/EplEventk.h28
-rw-r--r--drivers/staging/epl/kernel/EplNmtk.h25
-rw-r--r--drivers/staging/epl/kernel/EplNmtkCal.h89
-rw-r--r--drivers/staging/epl/kernel/EplObdk.h122
-rw-r--r--drivers/staging/epl/kernel/EplObdkCal.h89
-rw-r--r--drivers/staging/epl/kernel/EplPdok.h12
-rw-r--r--drivers/staging/epl/kernel/EplPdokCal.h13
-rw-r--r--drivers/staging/epl/kernel/EplTimerHighResk.h43
-rw-r--r--drivers/staging/epl/kernel/EplTimerk.h36
-rw-r--r--drivers/staging/epl/kernel/VirtualEthernet.h16
-rw-r--r--drivers/staging/epl/proc_fs.c23
-rw-r--r--drivers/staging/epl/user/EplCfgMau.h80
-rw-r--r--drivers/staging/epl/user/EplDllu.h14
-rw-r--r--drivers/staging/epl/user/EplDlluCal.h15
-rw-r--r--drivers/staging/epl/user/EplEventu.h28
-rw-r--r--drivers/staging/epl/user/EplIdentu.h34
-rw-r--r--drivers/staging/epl/user/EplLedu.h32
-rw-r--r--drivers/staging/epl/user/EplNmtCnu.h32
-rw-r--r--drivers/staging/epl/user/EplNmtMnu.h42
-rw-r--r--drivers/staging/epl/user/EplNmtu.h38
-rw-r--r--drivers/staging/epl/user/EplNmtuCal.h17
-rw-r--r--drivers/staging/epl/user/EplObdu.h83
-rw-r--r--drivers/staging/epl/user/EplObduCal.h94
-rw-r--r--drivers/staging/epl/user/EplPdou.h22
-rw-r--r--drivers/staging/epl/user/EplSdoAsndu.h33
-rw-r--r--drivers/staging/epl/user/EplSdoAsySequ.h41
-rw-r--r--drivers/staging/epl/user/EplSdoComu.h48
-rw-r--r--drivers/staging/epl/user/EplSdoUdpu.h34
-rw-r--r--drivers/staging/epl/user/EplStatusu.h32
-rw-r--r--drivers/staging/epl/user/EplTimeru.h38
-rw-r--r--drivers/staging/et131x/et1310_rx.c3
-rw-r--r--drivers/staging/frontier/README53
-rw-r--r--drivers/staging/frontier/alphatrack.c383
-rw-r--r--drivers/staging/frontier/alphatrack.h80
-rw-r--r--drivers/staging/frontier/frontier_compat.h63
-rw-r--r--drivers/staging/frontier/surface_sysfs.h100
-rw-r--r--drivers/staging/frontier/tranzport.c685
-rw-r--r--drivers/staging/go7007/Kconfig4
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c1
-rw-r--r--drivers/staging/go7007/s2250-board.c7
-rw-r--r--drivers/staging/heci/Kconfig6
-rw-r--r--drivers/staging/heci/Makefile9
-rw-r--r--drivers/staging/heci/TODO6
-rw-r--r--drivers/staging/heci/heci.h176
-rw-r--r--drivers/staging/heci/heci_data_structures.h530
-rw-r--r--drivers/staging/heci/heci_init.c1077
-rw-r--r--drivers/staging/heci/heci_interface.c485
-rw-r--r--drivers/staging/heci/heci_interface.h170
-rw-r--r--drivers/staging/heci/heci_main.c1564
-rw-r--r--drivers/staging/heci/heci_version.h54
-rw-r--r--drivers/staging/heci/interrupt.c1553
-rw-r--r--drivers/staging/heci/io_heci.c847
-rw-r--r--drivers/staging/line6/Kconfig21
-rw-r--r--drivers/staging/line6/Makefile15
-rw-r--r--drivers/staging/line6/audio.c72
-rw-r--r--drivers/staging/line6/audio.h24
-rw-r--r--drivers/staging/line6/capture.c372
-rw-r--r--drivers/staging/line6/capture.h32
-rw-r--r--drivers/staging/line6/config.h48
-rw-r--r--drivers/staging/line6/control.c840
-rw-r--r--drivers/staging/line6/control.h187
-rw-r--r--drivers/staging/line6/driver.c1102
-rw-r--r--drivers/staging/line6/driver.h204
-rw-r--r--drivers/staging/line6/dumprequest.c151
-rw-r--r--drivers/staging/line6/dumprequest.h90
-rw-r--r--drivers/staging/line6/midi.c422
-rw-r--r--drivers/staging/line6/midi.h87
-rw-r--r--drivers/staging/line6/midibuf.c262
-rw-r--r--drivers/staging/line6/midibuf.h39
-rw-r--r--drivers/staging/line6/pcm.c301
-rw-r--r--drivers/staging/line6/pcm.h222
-rw-r--r--drivers/staging/line6/playback.c427
-rw-r--r--drivers/staging/line6/playback.h30
-rw-r--r--drivers/staging/line6/pod.c1151
-rw-r--r--drivers/staging/line6/pod.h204
-rw-r--r--drivers/staging/line6/revision.h4
-rw-r--r--drivers/staging/line6/toneport.c241
-rw-r--r--drivers/staging/line6/toneport.h45
-rw-r--r--drivers/staging/line6/usbdefs.h74
-rw-r--r--drivers/staging/line6/variax.c546
-rw-r--r--drivers/staging/line6/variax.h108
-rw-r--r--drivers/staging/me4000/me4000.c193
-rw-r--r--drivers/staging/meilhaus/me0600_device.c4
-rw-r--r--drivers/staging/meilhaus/me0600_dio.c18
-rw-r--r--drivers/staging/meilhaus/me0600_ext_irq.c8
-rw-r--r--drivers/staging/meilhaus/me0600_optoi.c14
-rw-r--r--drivers/staging/meilhaus/me0600_relay.c14
-rw-r--r--drivers/staging/meilhaus/me0600_ttli.c12
-rw-r--r--drivers/staging/meilhaus/me0900_device.c4
-rw-r--r--drivers/staging/meilhaus/me0900_di.c12
-rw-r--r--drivers/staging/meilhaus/me0900_do.c14
-rw-r--r--drivers/staging/meilhaus/me1000_device.c8
-rw-r--r--drivers/staging/meilhaus/me1000_dio.c4
-rw-r--r--drivers/staging/meilhaus/me1400_device.c4
-rw-r--r--drivers/staging/meilhaus/me1400_ext_irq.c7
-rw-r--r--drivers/staging/meilhaus/me1600_ao.c70
-rw-r--r--drivers/staging/meilhaus/me1600_ao.h4
-rw-r--r--drivers/staging/meilhaus/me1600_device.c8
-rw-r--r--drivers/staging/meilhaus/me4600_ai.c157
-rw-r--r--drivers/staging/meilhaus/me4600_ai.h4
-rw-r--r--drivers/staging/meilhaus/me4600_ao.c191
-rw-r--r--drivers/staging/meilhaus/me4600_ao.h4
-rw-r--r--drivers/staging/meilhaus/me4600_device.c4
-rw-r--r--drivers/staging/meilhaus/me4600_di.c14
-rw-r--r--drivers/staging/meilhaus/me4600_dio.c16
-rw-r--r--drivers/staging/meilhaus/me4600_do.c16
-rw-r--r--drivers/staging/meilhaus/me4600_ext_irq.c21
-rw-r--r--drivers/staging/meilhaus/me6000_ao.c146
-rw-r--r--drivers/staging/meilhaus/me6000_ao.h4
-rw-r--r--drivers/staging/meilhaus/me6000_device.c4
-rw-r--r--drivers/staging/meilhaus/me6000_dio.c16
-rw-r--r--drivers/staging/meilhaus/me8100_device.c4
-rw-r--r--drivers/staging/meilhaus/me8100_di.c24
-rw-r--r--drivers/staging/meilhaus/me8100_do.c16
-rw-r--r--drivers/staging/meilhaus/me8200_device.c4
-rw-r--r--drivers/staging/meilhaus/me8200_di.c58
-rw-r--r--drivers/staging/meilhaus/me8200_dio.c16
-rw-r--r--drivers/staging/meilhaus/me8200_do.c26
-rw-r--r--drivers/staging/meilhaus/me8254.c14
-rw-r--r--drivers/staging/meilhaus/me8255.c4
-rw-r--r--drivers/staging/meilhaus/mecirc_buf.h16
-rw-r--r--drivers/staging/meilhaus/medevice.c14
-rw-r--r--drivers/staging/meilhaus/medlist.c6
-rw-r--r--drivers/staging/meilhaus/medlock.c4
-rw-r--r--drivers/staging/meilhaus/medummy.c84
-rw-r--r--drivers/staging/meilhaus/memain.c34
-rw-r--r--drivers/staging/meilhaus/meslist.c6
-rw-r--r--drivers/staging/meilhaus/meslock.c2
-rw-r--r--drivers/staging/meilhaus/mesubdevice.c12
-rw-r--r--drivers/staging/meilhaus/metempl_device.c4
-rw-r--r--drivers/staging/meilhaus/metempl_sub.c10
-rw-r--r--drivers/staging/mimio/Kconfig2
-rw-r--r--drivers/staging/otus/80211core/amsdu.c145
-rw-r--r--drivers/staging/otus/80211core/cmmsta.c5
-rw-r--r--drivers/staging/otus/80211core/coid.c8
-rw-r--r--drivers/staging/otus/80211core/cwm.c6
-rw-r--r--drivers/staging/otus/TODO9
-rw-r--r--drivers/staging/otus/hal/hpani.c46
-rw-r--r--drivers/staging/otus/hal/hpmain.c101
-rw-r--r--drivers/staging/otus/hal/hpreg.c9
-rw-r--r--drivers/staging/otus/hal/hprw.c30
-rw-r--r--drivers/staging/otus/hal/hpusb.c11
-rw-r--r--drivers/staging/otus/ioctl.c4789
-rw-r--r--drivers/staging/otus/usbdrv.c12
-rw-r--r--drivers/staging/otus/wwrap.c6
-rw-r--r--drivers/staging/otus/zdcompat.h7
-rw-r--r--drivers/staging/p9auth/Kconfig9
-rw-r--r--drivers/staging/p9auth/Makefile1
-rw-r--r--drivers/staging/p9auth/p9auth.c383
-rw-r--r--drivers/staging/panel/Kconfig2
-rw-r--r--drivers/staging/phison/Kconfig5
-rw-r--r--drivers/staging/phison/Makefile1
-rw-r--r--drivers/staging/phison/phison.c106
-rw-r--r--drivers/staging/pohmelfs/Kconfig28
-rw-r--r--drivers/staging/pohmelfs/Makefile3
-rw-r--r--drivers/staging/pohmelfs/config.c478
-rw-r--r--drivers/staging/pohmelfs/crypto.c880
-rw-r--r--drivers/staging/pohmelfs/dir.c1093
-rw-r--r--drivers/staging/pohmelfs/inode.c1976
-rw-r--r--drivers/staging/pohmelfs/lock.c182
-rw-r--r--drivers/staging/pohmelfs/mcache.c171
-rw-r--r--drivers/staging/pohmelfs/net.c1247
-rw-r--r--drivers/staging/pohmelfs/netfs.h932
-rw-r--r--drivers/staging/pohmelfs/path_entry.c114
-rw-r--r--drivers/staging/pohmelfs/trans.c715
-rw-r--r--drivers/staging/rspiusb/rspiusb.c5
-rw-r--r--drivers/staging/rt2860/2860_main_dev.c50
-rw-r--r--drivers/staging/rt2860/Makefile1
-rw-r--r--drivers/staging/rt2860/TODO4
-rw-r--r--drivers/staging/rt2860/common/cmm_data.c27
-rw-r--r--drivers/staging/rt2860/common/cmm_data_2860.c144
-rw-r--r--drivers/staging/rt2860/common/cmm_info.c6
-rw-r--r--drivers/staging/rt2860/common/cmm_sync.c2
-rw-r--r--drivers/staging/rt2860/common/cmm_wpa.c40
-rw-r--r--drivers/staging/rt2860/common/mlme.c289
-rw-r--r--drivers/staging/rt2860/common/rtmp_init.c157
-rw-r--r--drivers/staging/rt2860/common/spectrum.c2
-rw-r--r--drivers/staging/rt2860/config.mk4
-rw-r--r--drivers/staging/rt2860/oid.h2
-rw-r--r--drivers/staging/rt2860/rt2860.h22
-rw-r--r--drivers/staging/rt2860/rt28xx.h4
-rw-r--r--drivers/staging/rt2860/rt_ate.c18
-rw-r--r--drivers/staging/rt2860/rt_ate.h6
-rw-r--r--drivers/staging/rt2860/rt_config.h2
-rw-r--r--drivers/staging/rt2860/rt_linux.c29
-rw-r--r--drivers/staging/rt2860/rt_linux.h49
-rw-r--r--drivers/staging/rt2860/rt_main_dev.c149
-rw-r--r--drivers/staging/rt2860/rt_profile.c2
-rw-r--r--drivers/staging/rt2860/rtmp.h61
-rw-r--r--drivers/staging/rt2860/rtmp_def.h29
-rw-r--r--drivers/staging/rt2860/sta/assoc.c23
-rw-r--r--drivers/staging/rt2860/sta/connect.c45
-rw-r--r--drivers/staging/rt2860/sta/dls.c4
-rw-r--r--drivers/staging/rt2860/sta/rtmp_data.c29
-rw-r--r--drivers/staging/rt2860/sta/sync.c16
-rw-r--r--drivers/staging/rt2860/sta/wpa.c10
-rw-r--r--drivers/staging/rt2860/sta_ioctl.c96
-rw-r--r--drivers/staging/rt2860/wpa.h1
-rw-r--r--drivers/staging/rt2870/2870_main_dev.c67
-rw-r--r--drivers/staging/rt2870/TODO9
-rw-r--r--drivers/staging/rt2870/common/2870_rtmp_init.c35
-rw-r--r--drivers/staging/rt2870/common/cmm_data.c3
-rw-r--r--drivers/staging/rt2870/common/rtmp_init.c2
-rw-r--r--drivers/staging/rt2870/common/rtusb_io.c3
-rw-r--r--drivers/staging/rt2870/common/spectrum.c2
-rw-r--r--drivers/staging/rt2870/rt2870.h7
-rw-r--r--drivers/staging/rt2870/rt_linux.c2
-rw-r--r--drivers/staging/rt2870/rt_linux.h12
-rw-r--r--drivers/staging/rt2870/sta_ioctl.c2
-rw-r--r--drivers/staging/rt3070/2870_main_dev.c1627
-rw-r--r--drivers/staging/rt3070/Kconfig6
-rw-r--r--drivers/staging/rt3070/Makefile47
-rw-r--r--drivers/staging/rt3070/action.h68
-rw-r--r--drivers/staging/rt3070/aironet.h210
-rw-r--r--drivers/staging/rt3070/ap.h557
-rw-r--r--drivers/staging/rt3070/chlist.h1253
-rw-r--r--drivers/staging/rt3070/common/2870_rtmp_init.c1762
-rw-r--r--drivers/staging/rt3070/common/action.c1038
-rw-r--r--drivers/staging/rt3070/common/ba_action.c1810
-rw-r--r--drivers/staging/rt3070/common/cmm_data.c2827
-rw-r--r--drivers/staging/rt3070/common/cmm_data_2870.c980
-rw-r--r--drivers/staging/rt3070/common/cmm_info.c3395
-rw-r--r--drivers/staging/rt3070/common/cmm_sanity.c1669
-rw-r--r--drivers/staging/rt3070/common/cmm_sync.c711
-rw-r--r--drivers/staging/rt3070/common/cmm_wpa.c1606
-rw-r--r--drivers/staging/rt3070/common/dfs.c441
-rw-r--r--drivers/staging/rt3070/common/eeprom.c1498
-rw-r--r--drivers/staging/rt3070/common/md5.c1427
-rw-r--r--drivers/staging/rt3070/common/mlme.c9136
-rw-r--r--drivers/staging/rt3070/common/netif_block.c136
-rw-r--r--drivers/staging/rt3070/common/rtmp_init.c4197
-rw-r--r--drivers/staging/rt3070/common/rtmp_tkip.c1613
-rw-r--r--drivers/staging/rt3070/common/rtmp_wep.c508
-rw-r--r--drivers/staging/rt3070/common/rtusb_bulk.c1382
-rw-r--r--drivers/staging/rt3070/common/rtusb_data.c218
-rw-r--r--drivers/staging/rt3070/common/rtusb_io.c1908
-rw-r--r--drivers/staging/rt3070/common/spectrum.c1876
-rw-r--r--drivers/staging/rt3070/dfs.h100
-rw-r--r--drivers/staging/rt3070/firmware.h558
-rw-r--r--drivers/staging/rt3070/leap.h215
-rw-r--r--drivers/staging/rt3070/link_list.h134
-rw-r--r--drivers/staging/rt3070/md4.h42
-rw-r--r--drivers/staging/rt3070/md5.h107
-rw-r--r--drivers/staging/rt3070/mlme.h1468
-rw-r--r--drivers/staging/rt3070/netif_block.h58
-rw-r--r--drivers/staging/rt3070/oid.h1142
-rw-r--r--drivers/staging/rt3070/rt2870.h756
-rw-r--r--drivers/staging/rt3070/rt28xx.h2725
-rw-r--r--drivers/staging/rt3070/rt_ate.c6506
-rw-r--r--drivers/staging/rt3070/rt_ate.h294
-rw-r--r--drivers/staging/rt3070/rt_config.h121
-rw-r--r--drivers/staging/rt3070/rt_linux.c1063
-rw-r--r--drivers/staging/rt3070/rt_linux.h887
-rw-r--r--drivers/staging/rt3070/rt_main_dev.c1800
-rw-r--r--drivers/staging/rt3070/rt_profile.c2041
-rw-r--r--drivers/staging/rt3070/rtmp.h7728
-rw-r--r--drivers/staging/rt3070/rtmp_ckipmic.h113
-rw-r--r--drivers/staging/rt3070/rtmp_def.h1559
-rw-r--r--drivers/staging/rt3070/rtmp_type.h95
-rw-r--r--drivers/staging/rt3070/spectrum.h322
-rw-r--r--drivers/staging/rt3070/spectrum_def.h95
-rw-r--r--drivers/staging/rt3070/sta/aironet.c1312
-rw-r--r--drivers/staging/rt3070/sta/assoc.c2060
-rw-r--r--drivers/staging/rt3070/sta/auth.c475
-rw-r--r--drivers/staging/rt3070/sta/auth_rsp.c167
-rw-r--r--drivers/staging/rt3070/sta/connect.c2857
-rw-r--r--drivers/staging/rt3070/sta/dls.c2170
-rw-r--r--drivers/staging/rt3070/sta/rtmp_data.c2637
-rw-r--r--drivers/staging/rt3070/sta/sanity.c420
-rw-r--r--drivers/staging/rt3070/sta/sync.c1755
-rw-r--r--drivers/staging/rt3070/sta/wpa.c2099
-rw-r--r--drivers/staging/rt3070/sta_ioctl.c7203
-rw-r--r--drivers/staging/rt3070/wpa.h356
-rw-r--r--drivers/staging/rtl8187se/dot11d.h202
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.c492
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.h204
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c8
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c4
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c10
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.c3450
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.h82
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.c12
-rw-r--r--drivers/staging/serqt_usb/Kconfig9
-rw-r--r--drivers/staging/serqt_usb/Makefile1
-rw-r--r--drivers/staging/serqt_usb/TODO8
-rw-r--r--drivers/staging/serqt_usb/serqt_usb.c2779
-rw-r--r--drivers/staging/slicoss/gbdownload.h8215
-rw-r--r--drivers/staging/slicoss/gbrcvucode.h238
-rw-r--r--drivers/staging/slicoss/oasisdbgdownload.h6850
-rw-r--r--drivers/staging/slicoss/oasisdownload.h6848
-rw-r--r--drivers/staging/slicoss/oasisrcvucode.h205
-rw-r--r--drivers/staging/slicoss/slic.h86
-rw-r--r--drivers/staging/slicoss/slic_os.h84
-rw-r--r--drivers/staging/slicoss/slicbuild.h96
-rw-r--r--drivers/staging/slicoss/slicdbg.h100
-rw-r--r--drivers/staging/slicoss/slicdump.h278
-rw-r--r--drivers/staging/slicoss/slichw.h1038
-rw-r--r--drivers/staging/slicoss/slicinc.h185
-rw-r--r--drivers/staging/slicoss/slicoss.c2913
-rw-r--r--drivers/staging/stlc45xx/Kconfig8
-rw-r--r--drivers/staging/stlc45xx/Makefile1
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.c2606
-rw-r--r--drivers/staging/stlc45xx/stlc45xx.h283
-rw-r--r--drivers/staging/stlc45xx/stlc45xx_lmac.h434
-rw-r--r--drivers/staging/sxg/Kconfig2
-rw-r--r--drivers/staging/sxg/Makefile4
-rw-r--r--drivers/staging/sxg/saharadbgdownload.h4854
-rw-r--r--drivers/staging/sxg/sxg.c2885
-rw-r--r--drivers/staging/sxg/sxg.h919
-rw-r--r--drivers/staging/sxg/sxg_ethtool.c328
-rw-r--r--drivers/staging/sxg/sxg_os.h100
-rw-r--r--drivers/staging/sxg/sxgdbg.h129
-rw-r--r--drivers/staging/sxg/sxghif.h1110
-rw-r--r--drivers/staging/sxg/sxghw.h1564
-rw-r--r--drivers/staging/sxg/sxgphycode-1.2.h130
-rw-r--r--drivers/staging/sxg/sxgphycode.h349
-rw-r--r--drivers/staging/uc2322/Kconfig10
-rw-r--r--drivers/staging/uc2322/Makefile1
-rw-r--r--drivers/staging/uc2322/TODO7
-rw-r--r--drivers/staging/uc2322/aten2011.c2452
-rw-r--r--drivers/staging/usbip/stub_rx.c4
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c3
-rw-r--r--drivers/staging/winbond/bss_f.h63
-rw-r--r--drivers/staging/winbond/bssdscpt.h164
-rw-r--r--drivers/staging/winbond/common.h27
-rw-r--r--drivers/staging/winbond/core.h7
-rw-r--r--drivers/staging/winbond/ds_tkip.h37
-rw-r--r--drivers/staging/winbond/gl_80211.h126
-rw-r--r--drivers/staging/winbond/ioctls.h678
-rw-r--r--drivers/staging/winbond/mds.c26
-rw-r--r--drivers/staging/winbond/mds_s.h24
-rw-r--r--drivers/staging/winbond/mlme_mib.h84
-rw-r--r--drivers/staging/winbond/mlmetxrx.c2
-rw-r--r--drivers/staging/winbond/mto.c24
-rw-r--r--drivers/staging/winbond/mto.h12
-rw-r--r--drivers/staging/winbond/mto_f.h13
-rw-r--r--drivers/staging/winbond/os_common.h2
-rw-r--r--drivers/staging/winbond/phy_calibration.c28
-rw-r--r--drivers/staging/winbond/phy_calibration.h2
-rw-r--r--drivers/staging/winbond/reg.c81
-rw-r--r--drivers/staging/winbond/sme_api.h3
-rw-r--r--drivers/staging/winbond/sme_s.h236
-rw-r--r--drivers/staging/winbond/wb35_ver.h30
-rw-r--r--drivers/staging/winbond/wb35reg.c41
-rw-r--r--drivers/staging/winbond/wb35reg_f.h70
-rw-r--r--drivers/staging/winbond/wb35rx.c43
-rw-r--r--drivers/staging/winbond/wb35rx_f.h6
-rw-r--r--drivers/staging/winbond/wb35rx_s.h8
-rw-r--r--drivers/staging/winbond/wb35tx.c54
-rw-r--r--drivers/staging/winbond/wb35tx_f.h8
-rw-r--r--drivers/staging/winbond/wb35tx_s.h6
-rw-r--r--drivers/staging/winbond/wbhal.c50
-rw-r--r--drivers/staging/winbond/wbhal_f.h94
-rw-r--r--drivers/staging/winbond/wbhal_s.h87
-rw-r--r--drivers/staging/winbond/wbusb.c20
-rw-r--r--drivers/staging/winbond/wbusb_s.h16
-rw-r--r--drivers/staging/wlan-ng/README4
-rw-r--r--drivers/staging/wlan-ng/hfa384x.h2638
-rw-r--r--drivers/staging/wlan-ng/hfa384x_usb.c2295
-rw-r--r--drivers/staging/wlan-ng/p80211conv.c377
-rw-r--r--drivers/staging/wlan-ng/p80211conv.h131
-rw-r--r--drivers/staging/wlan-ng/p80211hdr.h146
-rw-r--r--drivers/staging/wlan-ng/p80211ioctl.h46
-rw-r--r--drivers/staging/wlan-ng/p80211meta.h110
-rw-r--r--drivers/staging/wlan-ng/p80211metadef.h544
-rw-r--r--drivers/staging/wlan-ng/p80211metamib.h105
-rw-r--r--drivers/staging/wlan-ng/p80211metamsg.h105
-rw-r--r--drivers/staging/wlan-ng/p80211metastruct.h424
-rw-r--r--drivers/staging/wlan-ng/p80211mgmt.h441
-rw-r--r--drivers/staging/wlan-ng/p80211msg.h48
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.c411
-rw-r--r--drivers/staging/wlan-ng/p80211netdev.h218
-rw-r--r--drivers/staging/wlan-ng/p80211req.c235
-rw-r--r--drivers/staging/wlan-ng/p80211req.h17
-rw-r--r--drivers/staging/wlan-ng/p80211types.h505
-rw-r--r--drivers/staging/wlan-ng/p80211wep.c24
-rw-r--r--drivers/staging/wlan-ng/p80211wext.c1214
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.c899
-rw-r--r--drivers/staging/wlan-ng/prism2mgmt.h69
-rw-r--r--drivers/staging/wlan-ng/prism2mib.c905
-rw-r--r--drivers/staging/wlan-ng/prism2sta.c1561
-rw-r--r--drivers/staging/wlan-ng/prism2usb.c158
-rw-r--r--drivers/staging/wlan-ng/wlan_compat.h193
-rw-r--r--drivers/thermal/thermal_sys.c356
-rw-r--r--drivers/usb/atm/ueagle-atm.c2
-rw-r--r--drivers/usb/class/cdc-acm.c5
-rw-r--r--drivers/usb/gadget/Kconfig2
-rw-r--r--drivers/usb/gadget/atmel_usba_udc.c14
-rw-r--r--drivers/usb/serial/ChangeLog.history2
-rw-r--r--drivers/usb/serial/Kconfig4
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h4
-rw-r--r--drivers/usb/serial/symbolserial.c67
-rw-r--r--drivers/usb/serial/usb-serial.c58
-rw-r--r--drivers/usb/storage/isd200.c239
-rw-r--r--drivers/usb/wusbcore/devconnect.c2
-rw-r--r--drivers/usb/wusbcore/security.c2
-rw-r--r--drivers/uwb/Kconfig4
-rw-r--r--drivers/video/68328fb.c5
-rw-r--r--drivers/video/Kconfig61
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amba-clcd.c8
-rw-r--r--drivers/video/amifb.c7
-rw-r--r--drivers/video/arkfb.c4
-rw-r--r--drivers/video/asiliantfb.c26
-rw-r--r--drivers/video/aty/mach64_accel.c3
-rw-r--r--drivers/video/aty/mach64_cursor.c15
-rw-r--r--drivers/video/aty/radeon_pm.c5
-rw-r--r--drivers/video/backlight/Kconfig18
-rw-r--r--drivers/video/backlight/Makefile2
-rw-r--r--drivers/video/backlight/backlight.c3
-rw-r--r--drivers/video/backlight/jornada720_bl.c161
-rw-r--r--drivers/video/backlight/jornada720_lcd.c153
-rw-r--r--drivers/video/backlight/lcd.c3
-rw-r--r--drivers/video/backlight/mbp_nvidia_bl.c191
-rw-r--r--drivers/video/backlight/pwm_bl.c4
-rw-r--r--drivers/video/cirrusfb.c1529
-rw-r--r--drivers/video/console/fbcon.c73
-rw-r--r--drivers/video/cyblafb.c1683
-rw-r--r--drivers/video/efifb.c5
-rw-r--r--drivers/video/fb_defio.c3
-rw-r--r--drivers/video/fbmem.c22
-rw-r--r--drivers/video/nvidia/nv_setup.c1
-rw-r--r--drivers/video/nvidia/nv_type.h2
-rw-r--r--drivers/video/nvidia/nvidia.c7
-rw-r--r--drivers/video/omap/hwa742.c4
-rw-r--r--drivers/video/omap/omapfb_main.c8
-rw-r--r--drivers/video/s1d13xxxfb.c48
-rw-r--r--drivers/video/s3c-fb.c1036
-rw-r--r--drivers/video/sgivwfb.c2
-rw-r--r--drivers/video/skeletonfb.c9
-rw-r--r--drivers/video/sm501fb.c5
-rw-r--r--drivers/video/sstfb.c10
-rw-r--r--drivers/video/stifb.c18
-rw-r--r--drivers/video/sunxvr500.c6
-rw-r--r--drivers/video/tdfxfb.c1
-rw-r--r--drivers/video/tgafb.c4
-rw-r--r--drivers/video/tridentfb.c19
-rw-r--r--drivers/video/uvesafb.c17
-rw-r--r--drivers/video/valkyriefb.c15
-rw-r--r--drivers/video/vesafb.c2
-rw-r--r--drivers/video/vfb.c1
-rw-r--r--drivers/video/via/accel.c8
-rw-r--r--drivers/video/via/viafbdev.c5
-rw-r--r--drivers/virtio/virtio_ring.c22
-rw-r--r--drivers/w1/masters/ds1wm.c58
-rw-r--r--drivers/w1/w1_io.c16
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/hpwdt.c4
-rw-r--r--drivers/xen/Kconfig2
-rw-r--r--drivers/xen/cpu_hotplug.c4
-rw-r--r--drivers/xen/manage.c16
1966 files changed, 402758 insertions, 119811 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8a851d0f438..431f8b43955 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -11,9 +11,9 @@ menuconfig ACPI
select PNP
select CPU_IDLE
default y
- ---help---
+ help
Advanced Configuration and Power Interface (ACPI) support for
- Linux requires an ACPI compliant platform (hardware/firmware),
+ Linux requires an ACPI-compliant platform (hardware/firmware),
and assumes the presence of OS-directed configuration and power
management (OSPM) software. This option will enlarge your
kernel by about 70K.
@@ -23,20 +23,19 @@ menuconfig ACPI
the Plug-and-Play BIOS specification (PnP BIOS), the
MultiProcessor Specification (MPS), and the Advanced Power
Management (APM) specification. If both ACPI and APM support
- are configured, whichever is loaded first shall be used.
+ are configured, ACPI is used.
- The ACPI SourceForge project contains the latest source code,
- documentation, tools, mailing list subscription, and other
- information. This project is available at:
- <http://sourceforge.net/projects/acpi>
+ The project home page for the Linux ACPI subsystem is here:
+ <http://www.lesswatts.org/projects/acpi/>
Linux support for ACPI is based on Intel Corporation's ACPI
- Component Architecture (ACPI CA). For more information see:
- <http://developer.intel.com/technology/iapc/acpi>
+ Component Architecture (ACPI CA). For more information on the
+ ACPI CA, see:
+ <http://acpica.org/>
- ACPI is an open industry specification co-developed by Compaq,
- Intel, Microsoft, Phoenix, and Toshiba. The specification is
- available at:
+ ACPI is an open industry specification co-developed by
+ Hewlett-Packard, Intel, Microsoft, Phoenix, and Toshiba.
+ The specification is available at:
<http://www.acpi.info>
if ACPI
@@ -49,14 +48,14 @@ config ACPI_SLEEP
config ACPI_PROCFS
bool "Deprecated /proc/acpi files"
depends on PROC_FS
- ---help---
+ help
For backwards compatibility, this option allows
deprecated /proc/acpi/ files to exist, even when
they have been replaced by functions in /sys.
The deprecated files (and their replacements) include:
/proc/acpi/sleep (/sys/power/state)
- /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version)
+ /proc/acpi/info (/sys/module/acpi/parameters/acpica_version)
/proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT)
/proc/acpi/fadt (/sys/firmware/acpi/tables/FACP)
/proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer)
@@ -66,11 +65,12 @@ config ACPI_PROCFS
and functions which do not yet exist in /sys.
Say N to delete /proc/acpi/ files that have moved to /sys/
+
config ACPI_PROCFS_POWER
bool "Deprecated power /proc/acpi directories"
depends on PROC_FS
default y
- ---help---
+ help
For backwards compatibility, this option allows
deprecated power /proc/acpi/ directories to exist, even when
they have been replaced by functions in /sys.
@@ -86,19 +86,19 @@ config ACPI_SYSFS_POWER
bool "Future power /sys interface"
select POWER_SUPPLY
default y
- ---help---
+ help
Say N to disable power /sys interface
config ACPI_PROC_EVENT
bool "Deprecated /proc/acpi/event support"
depends on PROC_FS
default y
- ---help---
- A user-space daemon, acpi, typically read /proc/acpi/event
- and handled all ACPI sub-system generated events.
+ help
+ A user-space daemon, acpid, typically reads /proc/acpi/event
+ and handles all ACPI-generated events.
- These events are now delivered to user-space via
- either the input layer, or as netlink events.
+ These events are now delivered to user-space either
+ via the input layer or as netlink events.
This build option enables the old code for legacy
user-space implementation. After some time, this will
@@ -112,10 +112,13 @@ config ACPI_AC
depends on X86
default y
help
- This driver adds support for the AC Adapter object, which indicates
- whether a system is on AC, or not. If you have a system that can
+ This driver supports the AC Adapter object, which indicates
+ whether a system is on AC or not. If you have a system that can
switch between A/C and battery, say Y.
+ To compile this driver as a module, choose M here:
+ the module will be called ac.
+
config ACPI_BATTERY
tristate "Battery"
depends on X86
@@ -125,15 +128,21 @@ config ACPI_BATTERY
/proc/acpi/battery. If you have a mobile system with a battery,
say Y.
+ To compile this driver as a module, choose M here:
+ the module will be called battery.
+
config ACPI_BUTTON
tristate "Button"
depends on INPUT
default y
help
- This driver handles events on the power, sleep and lid buttons.
+ This driver handles events on the power, sleep, and lid buttons.
A daemon reads /proc/acpi/event and perform user-defined actions
such as shutting down the system. This is necessary for
- software controlled poweroff.
+ software-controlled poweroff.
+
+ To compile this driver as a module, choose M here:
+ the module will be called button.
config ACPI_VIDEO
tristate "Video"
@@ -141,38 +150,45 @@ config ACPI_VIDEO
depends on INPUT
select THERMAL
help
- This driver implement the ACPI Extensions For Display Adapters
+ This driver implements the ACPI Extensions For Display Adapters
for integrated graphics devices on motherboard, as specified in
- ACPI 2.0 Specification, Appendix B, allowing to perform some basic
- control like defining the video POST device, retrieving EDID information
- or to setup a video output, etc.
- Note that this is an ref. implementation only. It may or may not work
- for your integrated video device.
+ ACPI 2.0 Specification, Appendix B. This supports basic operations
+ such as defining the video POST device, retrieving EDID information,
+ and setting up a video output.
+
+ To compile this driver as a module, choose M here:
+ the module will be called video.
config ACPI_FAN
tristate "Fan"
select THERMAL
default y
help
- This driver adds support for ACPI fan devices, allowing user-mode
+ This driver supports ACPI fan devices, allowing user-mode
applications to perform basic fan control (on, off, status).
+ To compile this driver as a module, choose M here:
+ the module will be called fan.
+
config ACPI_DOCK
bool "Dock"
depends on EXPERIMENTAL
help
- This driver adds support for ACPI controlled docking stations and removable
- drive bays such as the IBM ultrabay or the Dell Module Bay.
+ This driver supports ACPI-controlled docking stations and removable
+ drive bays such as the IBM Ultrabay and the Dell Module Bay.
config ACPI_PROCESSOR
tristate "Processor"
select THERMAL
default y
help
- This driver installs ACPI as the idle handler for Linux, and uses
- ACPI C2 and C3 processor states to save power, on systems that
+ This driver installs ACPI as the idle handler for Linux and uses
+ ACPI C2 and C3 processor states to save power on systems that
support it. It is required by several flavors of cpufreq
- Performance-state drivers.
+ performance-state drivers.
+
+ To compile this driver as a module, choose M here:
+ the module will be called processor.
config ACPI_HOTPLUG_CPU
bool
@@ -186,11 +202,14 @@ config ACPI_THERMAL
select THERMAL
default y
help
- This driver adds support for ACPI thermal zones. Most mobile and
+ This driver supports ACPI thermal zones. Most mobile and
some desktop systems support ACPI thermal zones. It is HIGHLY
recommended that this option be enabled, as your processor(s)
may be damaged without it.
+ To compile this driver as a module, choose M here:
+ the module will be called thermal.
+
config ACPI_NUMA
bool "NUMA support"
depends on NUMA
@@ -218,7 +237,7 @@ config ACPI_BLACKLIST_YEAR
int "Disable ACPI for systems before Jan 1st this year" if X86_32
default 0
help
- enter a 4-digit year, eg. 2001 to disable ACPI by default
+ Enter a 4-digit year, e.g., 2001, to disable ACPI by default
on platforms with DMI BIOS date before January 1st that year.
"acpi=force" can be used to override this mechanism.
@@ -249,10 +268,13 @@ config ACPI_PCI_SLOT
tristate "PCI slot detection driver"
default n
help
- This driver will attempt to discover all PCI slots in your system,
- and creates entries in /sys/bus/pci/slots/. This feature can
- help you correlate PCI bus addresses with the physical geography
- of your slots. If you are unsure, say N.
+ This driver creates entries in /sys/bus/pci/slots/ for all PCI
+ slots in the system. This can help correlate PCI bus addresses,
+ i.e., segment/bus/device/function tuples, with physical slots in
+ the system. If you are unsure, say N.
+
+ To compile this driver as a module, choose M here:
+ the module will be called pci_slot.
config X86_PM_TIMER
bool "Power Management Timer Support" if EMBEDDED
@@ -271,43 +293,43 @@ config X86_PM_TIMER
systems require this timer.
config ACPI_CONTAINER
- tristate "ACPI0004,PNP0A05 and PNP0A06 Container Driver (EXPERIMENTAL)"
+ tristate "Container and Module Devices (EXPERIMENTAL)"
depends on EXPERIMENTAL
default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO)
- ---help---
- This allows _physical_ insertion and removal of CPUs and memory.
- This can be useful, for example, on NUMA machines that support
- ACPI based physical hotplug of nodes, or non-NUMA machines that
- support physical cpu/memory hot-plug.
+ help
+ This driver supports ACPI Container and Module devices (IDs
+ ACPI0004, PNP0A05, and PNP0A06).
- If one selects "m", this driver can be loaded with
- "modprobe container".
+ This helps support hotplug of nodes, CPUs, and memory.
+
+ To compile this driver as a module, choose M here:
+ the module will be called container.
config ACPI_HOTPLUG_MEMORY
tristate "Memory Hotplug"
depends on MEMORY_HOTPLUG
default n
help
- This driver adds supports for ACPI Memory Hotplug. This driver
- provides support for fielding notifications on ACPI memory
- devices (PNP0C80) which represent memory ranges that may be
- onlined or offlined during runtime.
+ This driver supports ACPI memory hotplug. The driver
+ fields notifications on ACPI memory devices (PNP0C80),
+ which represent memory ranges that may be onlined or
+ offlined during runtime.
- Enabling this driver assumes that your platform hardware
- and firmware have support for hot-plugging physical memory. If
- your system does not support physically adding or ripping out
- memory DIMMs at some platform defined granularity (individually
- or as a bank) at runtime, then you need not enable this driver.
+ If your hardware and firmware do not support adding or
+ removing memory devices at runtime, you need not enable
+ this driver.
- If one selects "m," this driver can be loaded using the following
- command:
- $>modprobe acpi_memhotplug
+ To compile this driver as a module, choose M here:
+ the module will be called acpi_memhotplug.
config ACPI_SBS
tristate "Smart Battery System"
depends on X86
help
- This driver adds support for the Smart Battery System, another
+ This driver supports the Smart Battery System, another
type of access to battery information, found on some laptops.
+ To compile this driver as a module, choose M here:
+ the modules will be called sbs and sbshc.
+
endif # ACPI
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index b130ea0d075..03a985be3fe 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -14,48 +14,50 @@ obj-$(CONFIG_X86) += blacklist.o
#
# ACPI Core Subsystem (Interpreter)
#
-obj-y += osl.o utils.o reboot.o\
+obj-y += acpi.o \
acpica/
+# All the builtin files are in the "acpi." module_param namespace.
+acpi-y += osl.o utils.o reboot.o
+
# sleep related files
-obj-y += wakeup.o
-obj-y += sleep.o
-obj-$(CONFIG_ACPI_SLEEP) += proc.o
+acpi-y += wakeup.o
+acpi-y += sleep.o
+acpi-$(CONFIG_ACPI_SLEEP) += proc.o
#
# ACPI Bus and Device Drivers
#
-processor-objs += processor_core.o processor_throttling.o \
- processor_idle.o processor_thermal.o
-ifdef CONFIG_CPU_FREQ
-processor-objs += processor_perflib.o
+acpi-y += bus.o glue.o
+acpi-y += scan.o
+acpi-y += ec.o
+acpi-$(CONFIG_ACPI_DOCK) += dock.o
+acpi-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
+acpi-y += power.o
+acpi-y += system.o event.o
+acpi-$(CONFIG_ACPI_DEBUG) += debug.o
+acpi-$(CONFIG_ACPI_NUMA) += numa.o
+acpi-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+ifdef CONFIG_ACPI_VIDEO
+acpi-y += video_detect.o
endif
-obj-y += bus.o glue.o
-obj-y += scan.o
-# Keep EC driver first. Initialization of others depend on it.
-obj-y += ec.o
+# These are (potentially) separate modules
obj-$(CONFIG_ACPI_AC) += ac.o
-obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_FAN) += fan.o
-obj-$(CONFIG_ACPI_DOCK) += dock.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
-ifdef CONFIG_ACPI_VIDEO
-obj-y += video_detect.o
-endif
-
-obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI_CONTAINER) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
-obj-y += power.o
-obj-y += system.o event.o
-obj-$(CONFIG_ACPI_DEBUG) += debug.o
-obj-$(CONFIG_ACPI_NUMA) += numa.o
-obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
-obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o
+obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o
+obj-$(CONFIG_ACPI_BATTERY) += battery.o
obj-$(CONFIG_ACPI_SBS) += sbshc.o
obj-$(CONFIG_ACPI_SBS) += sbs.o
+
+# processor has its own "processor." module_param namespace
+processor-y := processor_core.o processor_throttling.o
+processor-y += processor_idle.o processor_thermal.o
+processor-$(CONFIG_CPU_FREQ) += processor_perflib.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 9b917dac773..88e42abf5d8 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -191,7 +191,6 @@ static int acpi_ac_add_fs(struct acpi_device *device)
acpi_ac_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
/* 'state' [R] */
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile
index 3f23298ee3f..17e50824a6f 100644
--- a/drivers/acpi/acpica/Makefile
+++ b/drivers/acpi/acpica/Makefile
@@ -18,7 +18,7 @@ obj-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\
excreate.o exmisc.o exoparg2.o exregion.o exstore.o exutils.o \
exdump.o exmutex.o exoparg3.o exresnte.o exstoren.o
-obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o
+obj-y += hwacpi.o hwgpe.o hwregs.o hwsleep.o hwxface.o hwvalid.o
obj-$(ACPI_FUTURE_USAGE) += hwtimer.o
@@ -41,4 +41,4 @@ obj-y += tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
obj-y += utalloc.o utdebug.o uteval.o utinit.o utmisc.o utxface.o \
utcopy.o utdelete.o utglobal.o utmath.o utobject.o \
- utstate.o utmutex.o utobject.o utresrc.o
+ utstate.o utmutex.o utobject.o utresrc.o utlock.o
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index ddb40f5c68f..16e5210ae93 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -148,9 +148,12 @@ ACPI_EXTERN struct acpi_internal_rsdt acpi_gbl_root_table_list;
ACPI_EXTERN struct acpi_table_fadt acpi_gbl_FADT;
ACPI_EXTERN struct acpi_table_facs *acpi_gbl_FACS;
-/* These addresses are calculated from FADT address values */
+/* These addresses are calculated from the FADT Event Block addresses */
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_status;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1a_enable;
+
+ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_status;
ACPI_EXTERN struct acpi_generic_address acpi_gbl_xpm1b_enable;
/*
@@ -162,6 +165,10 @@ ACPI_EXTERN u8 acpi_gbl_integer_bit_width;
ACPI_EXTERN u8 acpi_gbl_integer_byte_width;
ACPI_EXTERN u8 acpi_gbl_integer_nybble_width;
+/* Reader/Writer lock is used for namespace walk and dynamic table unload */
+
+ACPI_EXTERN struct acpi_rw_lock acpi_gbl_namespace_rw_lock;
+
/*****************************************************************************
*
* Mutual exlusion within ACPICA subsystem
@@ -245,6 +252,7 @@ ACPI_EXTERN u8 acpi_gbl_step_to_next_call;
ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present;
ACPI_EXTERN u8 acpi_gbl_events_initialized;
ACPI_EXTERN u8 acpi_gbl_system_awake_and_running;
+ACPI_EXTERN u8 acpi_gbl_osi_data;
#ifndef DEFINE_ACPI_GLOBALS
@@ -371,7 +379,6 @@ ACPI_EXTERN char *acpi_gbl_db_buffer;
ACPI_EXTERN char *acpi_gbl_db_filename;
ACPI_EXTERN u32 acpi_gbl_db_debug_level;
ACPI_EXTERN u32 acpi_gbl_db_console_debug_level;
-ACPI_EXTERN struct acpi_table_header *acpi_gbl_db_table_ptr;
ACPI_EXTERN struct acpi_namespace_node *acpi_gbl_db_scope_node;
/*
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 58c69dc49ab..4afa3d8e0ef 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -64,14 +64,22 @@ u32 acpi_hw_get_mode(void);
*/
struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id);
-acpi_status
-acpi_hw_register_read(u32 register_id, u32 * return_value);
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control);
+
+acpi_status acpi_hw_register_read(u32 register_id, u32 *return_value);
acpi_status acpi_hw_register_write(u32 register_id, u32 value);
acpi_status acpi_hw_clear_acpi_status(void);
/*
+ * hwvalid - Port I/O with validation
+ */
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width);
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
+
+/*
* hwgpe - GPE support
*/
acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info);
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index 492d02761bb..772ee5c4ccc 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -108,6 +108,14 @@ static char *acpi_gbl_mutex_names[ACPI_NUM_MUTEX] = {
#endif
#endif
+/* Lock structure for reader/writer interfaces */
+
+struct acpi_rw_lock {
+ acpi_mutex writer_mutex;
+ acpi_mutex reader_mutex;
+ u32 num_readers;
+};
+
/*
* Predefined handles for spinlocks used within the subsystem.
* These spinlocks are created by acpi_ut_mutex_initialize
@@ -772,7 +780,19 @@ struct acpi_bit_register_info {
* must be preserved.
*/
#define ACPI_PM1_STATUS_PRESERVED_BITS 0x0800 /* Bit 11 */
-#define ACPI_PM1_CONTROL_PRESERVED_BITS 0x0200 /* Bit 9 (whatever) */
+
+/* Write-only bits must be zeroed by software */
+
+#define ACPI_PM1_CONTROL_WRITEONLY_BITS 0x2004 /* Bits 13, 2 */
+
+/* For control registers, both ignored and reserved bits must be preserved */
+
+#define ACPI_PM1_CONTROL_IGNORED_BITS 0x0201 /* Bits 9, 0(SCI_EN) */
+#define ACPI_PM1_CONTROL_RESERVED_BITS 0xC1F8 /* Bits 14-15, 3-8 */
+#define ACPI_PM1_CONTROL_PRESERVED_BITS \
+ (ACPI_PM1_CONTROL_IGNORED_BITS | ACPI_PM1_CONTROL_RESERVED_BITS)
+
+#define ACPI_PM2_CONTROL_PRESERVED_BITS 0xFFFFFFFE /* All except bit 0 */
/*
* Register IDs
@@ -781,12 +801,10 @@ struct acpi_bit_register_info {
#define ACPI_REGISTER_PM1_STATUS 0x01
#define ACPI_REGISTER_PM1_ENABLE 0x02
#define ACPI_REGISTER_PM1_CONTROL 0x03
-#define ACPI_REGISTER_PM1A_CONTROL 0x04
-#define ACPI_REGISTER_PM1B_CONTROL 0x05
-#define ACPI_REGISTER_PM2_CONTROL 0x06
-#define ACPI_REGISTER_PM_TIMER 0x07
-#define ACPI_REGISTER_PROCESSOR_BLOCK 0x08
-#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x09
+#define ACPI_REGISTER_PM2_CONTROL 0x04
+#define ACPI_REGISTER_PM_TIMER 0x05
+#define ACPI_REGISTER_PROCESSOR_BLOCK 0x06
+#define ACPI_REGISTER_SMI_COMMAND_BLOCK 0x07
/* Masks used to access the bit_registers */
@@ -818,7 +836,7 @@ struct acpi_bit_register_info {
#define ACPI_BITMASK_SCI_ENABLE 0x0001
#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002
#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004
-#define ACPI_BITMASK_SLEEP_TYPE_X 0x1C00
+#define ACPI_BITMASK_SLEEP_TYPE 0x1C00
#define ACPI_BITMASK_SLEEP_ENABLE 0x2000
#define ACPI_BITMASK_ARB_DISABLE 0x0001
@@ -844,11 +862,35 @@ struct acpi_bit_register_info {
#define ACPI_BITPOSITION_SCI_ENABLE 0x00
#define ACPI_BITPOSITION_BUS_MASTER_RLD 0x01
#define ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE 0x02
-#define ACPI_BITPOSITION_SLEEP_TYPE_X 0x0A
+#define ACPI_BITPOSITION_SLEEP_TYPE 0x0A
#define ACPI_BITPOSITION_SLEEP_ENABLE 0x0D
#define ACPI_BITPOSITION_ARB_DISABLE 0x00
+/* Structs and definitions for _OSI support and I/O port validation */
+
+#define ACPI_OSI_WIN_2000 0x01
+#define ACPI_OSI_WIN_XP 0x02
+#define ACPI_OSI_WIN_XP_SP1 0x03
+#define ACPI_OSI_WINSRV_2003 0x04
+#define ACPI_OSI_WIN_XP_SP2 0x05
+#define ACPI_OSI_WINSRV_2003_SP1 0x06
+#define ACPI_OSI_WIN_VISTA 0x07
+
+#define ACPI_ALWAYS_ILLEGAL 0x00
+
+struct acpi_interface_info {
+ char *name;
+ u8 value;
+};
+
+struct acpi_port_info {
+ char *name;
+ u16 start;
+ u16 end;
+ u8 osi_dependency;
+};
+
/*****************************************************************************
*
* Resource descriptors
diff --git a/drivers/acpi/acpica/acmacros.h b/drivers/acpi/acpica/acmacros.h
index 9c127e8e2d6..91ac7d7b440 100644
--- a/drivers/acpi/acpica/acmacros.h
+++ b/drivers/acpi/acpica/acmacros.h
@@ -292,10 +292,6 @@
#define ACPI_GET_DESCRIPTOR_TYPE(d) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type)
#define ACPI_SET_DESCRIPTOR_TYPE(d, t) (((union acpi_descriptor *)(void *)(d))->common.descriptor_type = t)
-/* Macro to test the object type */
-
-#define ACPI_GET_OBJECT_TYPE(d) (((union acpi_operand_object *)(void *)(d))->common.type)
-
/*
* Macros for the master AML opcode table
*/
diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h
index eb6f038b03d..544dcf83492 100644
--- a/drivers/acpi/acpica/acobject.h
+++ b/drivers/acpi/acpica/acobject.h
@@ -97,7 +97,6 @@
#define AOPOBJ_OBJECT_INITIALIZED 0x08
#define AOPOBJ_SETUP_COMPLETE 0x10
#define AOPOBJ_SINGLE_DATUM 0x20
-#define AOPOBJ_INVALID 0x40 /* Used if host OS won't allow an op_region address */
/******************************************************************************
*
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h
index 16a9ca9a66e..63f656ae360 100644
--- a/drivers/acpi/acpica/acpredef.h
+++ b/drivers/acpi/acpica/acpredef.h
@@ -52,41 +52,44 @@
* 1) PTYPE1 packages do not contain sub-packages.
*
* ACPI_PTYPE1_FIXED: Fixed length, 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
*
* ACPI_PTYPE1_VAR: Variable length:
- * object type (Int/Buf/Ref)
+ * object type (Int/Buf/Ref)
*
- * ACPI_PTYPE1_OPTION: Package has some required and some optional elements:
- * Used for _PRW
+ * ACPI_PTYPE1_OPTION: Package has some required and some optional elements
+ * (Used for _PRW)
*
*
* 2) PTYPE2 packages contain a variable number of sub-packages. Each of the
* different types describe the contents of each of the sub-packages.
*
* ACPI_PTYPE2: Each subpackage contains 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _ALR,_MLS,_PSS,_TRT,_TSS)
*
* ACPI_PTYPE2_COUNT: Each subpackage has a count as first element:
- * object type
+ * object type
+ * (Used for _CSD,_PSD,_TSD)
*
* ACPI_PTYPE2_PKG_COUNT: Count of subpackages at start, 1 or 2 object types:
- * object type
- * count
- * object type
- * count
+ * object type
+ * count
+ * object type
+ * count
+ * (Used for _CST)
*
- * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length:
- * Used for _PRT
+ * ACPI_PTYPE2_FIXED: Each subpackage is of fixed length
+ * (Used for _PRT)
*
* ACPI_PTYPE2_MIN: Each subpackage has a variable but minimum length
- * Used for _HPX
+ * (Used for _HPX)
*
*****************************************************************************/
diff --git a/drivers/acpi/acpica/actables.h b/drivers/acpi/acpica/actables.h
index 7ce6e33c7f7..01c76b8ea7b 100644
--- a/drivers/acpi/acpica/actables.h
+++ b/drivers/acpi/acpica/actables.h
@@ -49,7 +49,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count);
/*
* tbfadt - FADT parse/convert/validate
*/
-void acpi_tb_parse_fadt(u32 table_index, u8 flags);
+void acpi_tb_parse_fadt(u32 table_index);
void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length);
@@ -79,7 +79,7 @@ void acpi_tb_delete_table(struct acpi_table_desc *table_desc);
void acpi_tb_terminate(void);
-void acpi_tb_delete_namespace_by_owner(u32 table_index);
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
acpi_status acpi_tb_allocate_owner_id(u32 table_index);
@@ -109,9 +109,8 @@ acpi_tb_verify_checksum(struct acpi_table_header *table, u32 length);
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, u32 table_index);
+ char *signature, u32 table_index);
-acpi_status
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags);
+acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
#endif /* __ACTABLES_H__ */
diff --git a/drivers/acpi/acpica/acutils.h b/drivers/acpi/acpica/acutils.h
index 80d8813484f..897810ba0cc 100644
--- a/drivers/acpi/acpica/acutils.h
+++ b/drivers/acpi/acpica/acutils.h
@@ -346,6 +346,21 @@ acpi_status
acpi_ut_execute_sxds(struct acpi_namespace_node *device_node, u8 * highest);
/*
+ * utlock - reader/writer locks
+ */
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock);
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock);
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock);
+
+/*
* utobject - internal object create/delete/cache routines
*/
union acpi_operand_object *acpi_ut_create_internal_object_dbg(const char
diff --git a/drivers/acpi/acpica/dsinit.c b/drivers/acpi/acpica/dsinit.c
index eb144b13d8f..3aae13f30c5 100644
--- a/drivers/acpi/acpica/dsinit.c
+++ b/drivers/acpi/acpica/dsinit.c
@@ -180,11 +180,23 @@ acpi_ds_initialize_objects(u32 table_index,
/* Walk entire namespace from the supplied root */
- status = acpi_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
- acpi_ds_init_one_object, &info, NULL);
+ status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ /*
+ * We don't use acpi_walk_namespace since we do not want to acquire
+ * the namespace reader lock.
+ */
+ status =
+ acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
+ ACPI_NS_WALK_UNLOCK, acpi_ds_init_one_object,
+ &info, NULL);
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
}
+ (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
status = acpi_get_table_by_index(table_index, &table);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dsmthdat.c b/drivers/acpi/acpica/dsmthdat.c
index da0f5468184..22b1a3ce2c9 100644
--- a/drivers/acpi/acpica/dsmthdat.c
+++ b/drivers/acpi/acpica/dsmthdat.c
@@ -713,6 +713,6 @@ acpi_ds_method_data_get_type(u16 opcode,
/* Get the object type */
- return_VALUE(ACPI_GET_OBJECT_TYPE(object));
+ return_VALUE(object->type);
}
#endif
diff --git a/drivers/acpi/acpica/dsobject.c b/drivers/acpi/acpica/dsobject.c
index 15c628e6aa0..dab3f48f0b4 100644
--- a/drivers/acpi/acpica/dsobject.c
+++ b/drivers/acpi/acpica/dsobject.c
@@ -565,7 +565,7 @@ acpi_ds_create_node(struct acpi_walk_state *walk_state,
/* Re-type the object according to its argument */
- node->type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ node->type = obj_desc->common.type;
/* Attach obj to node */
@@ -619,7 +619,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
/* Perform per-object initialization */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
/*
@@ -803,7 +803,7 @@ acpi_ds_init_object_from_op(struct acpi_walk_state *walk_state,
default:
ACPI_ERROR((AE_INFO, "Unimplemented data type: %X",
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc->common.type));
status = AE_AML_OPERAND_TYPE;
break;
diff --git a/drivers/acpi/acpica/dsopcode.c b/drivers/acpi/acpica/dsopcode.c
index 0c3b4dd60e8..b4c87b5053e 100644
--- a/drivers/acpi/acpica/dsopcode.c
+++ b/drivers/acpi/acpica/dsopcode.c
@@ -397,30 +397,6 @@ acpi_status acpi_ds_get_region_arguments(union acpi_operand_object *obj_desc)
status = acpi_ds_execute_arguments(node, acpi_ns_get_parent_node(node),
extra_desc->extra.aml_length,
extra_desc->extra.aml_start);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
-
- /* Validate the region address/length via the host OS */
-
- status = acpi_os_validate_address(obj_desc->region.space_id,
- obj_desc->region.address,
- (acpi_size) obj_desc->region.length,
- acpi_ut_get_node_name(node));
-
- if (ACPI_FAILURE(status)) {
- /*
- * Invalid address/length. We will emit an error message and mark
- * the region as invalid, so that it will cause an additional error if
- * it is ever used. Then return AE_OK.
- */
- ACPI_EXCEPTION((AE_INFO, status,
- "During address validation of OpRegion [%4.4s]",
- node->name.ascii));
- obj_desc->common.flags |= AOPOBJ_INVALID;
- status = AE_OK;
- }
-
return_ACPI_STATUS(status);
}
@@ -484,7 +460,7 @@ acpi_ds_init_buffer_field(u16 aml_opcode,
/* Host object must be a Buffer */
- if (ACPI_GET_OBJECT_TYPE(buffer_desc) != ACPI_TYPE_BUFFER) {
+ if (buffer_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO,
"Target of Create Field is not a Buffer object - %s",
acpi_ut_get_object_type_name(buffer_desc)));
@@ -1365,10 +1341,8 @@ acpi_ds_exec_end_control_op(struct acpi_walk_state * walk_state,
if ((ACPI_GET_DESCRIPTOR_TYPE
(walk_state->results->results.obj_desc[0]) ==
ACPI_DESC_TYPE_OPERAND)
- &&
- (ACPI_GET_OBJECT_TYPE
- (walk_state->results->results.obj_desc[0]) ==
- ACPI_TYPE_LOCAL_REFERENCE)
+ && ((walk_state->results->results.obj_desc[0])->
+ common.type == ACPI_TYPE_LOCAL_REFERENCE)
&& ((walk_state->results->results.obj_desc[0])->
reference.class != ACPI_REFCLASS_INDEX)) {
status =
diff --git a/drivers/acpi/acpica/dsutils.c b/drivers/acpi/acpica/dsutils.c
index dabc23a4617..dfa10410292 100644
--- a/drivers/acpi/acpica/dsutils.c
+++ b/drivers/acpi/acpica/dsutils.c
@@ -816,7 +816,7 @@ acpi_status acpi_ds_evaluate_name_path(struct acpi_walk_state *walk_state)
goto push_result;
}
- type = ACPI_GET_OBJECT_TYPE(*operand);
+ type = (*operand)->common.type;
status = acpi_ex_resolve_to_value(operand, walk_state);
if (ACPI_FAILURE(status)) {
diff --git a/drivers/acpi/acpica/dswexec.c b/drivers/acpi/acpica/dswexec.c
index 350e6656bc8..f0280856dc0 100644
--- a/drivers/acpi/acpica/dswexec.c
+++ b/drivers/acpi/acpica/dswexec.c
@@ -138,11 +138,10 @@ acpi_ds_get_predicate_value(struct acpi_walk_state *walk_state,
goto cleanup;
}
- if (ACPI_GET_OBJECT_TYPE(local_obj_desc) != ACPI_TYPE_INTEGER) {
+ if (local_obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"Bad predicate (not an integer) ObjDesc=%p State=%p Type=%X",
- obj_desc, walk_state,
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc, walk_state, obj_desc->common.type));
status = AE_AML_OPERAND_TYPE;
goto cleanup;
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c
index 803edd9e3f6..cd55c774e88 100644
--- a/drivers/acpi/acpica/evevent.c
+++ b/drivers/acpi/acpica/evevent.c
@@ -183,7 +183,7 @@ acpi_status acpi_ev_install_xrupt_handlers(void)
*
* RETURN: Status
*
- * DESCRIPTION: Install the fixed event handlers and enable the fixed events.
+ * DESCRIPTION: Install the fixed event handlers and disable all fixed events.
*
******************************************************************************/
@@ -200,12 +200,13 @@ static acpi_status acpi_ev_fixed_event_initialize(void)
acpi_gbl_fixed_event_handlers[i].handler = NULL;
acpi_gbl_fixed_event_handlers[i].context = NULL;
- /* Enable the fixed event */
+ /* Disable the fixed event */
if (acpi_gbl_fixed_event_info[i].enable_register_id != 0xFF) {
status =
- acpi_set_register(acpi_gbl_fixed_event_info[i].
- enable_register_id, 0);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [i].enable_register_id,
+ ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -288,16 +289,17 @@ static u32 acpi_ev_fixed_event_dispatch(u32 event)
/* Clear the status bit */
- (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
- status_register_id, 1);
+ (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, ACPI_CLEAR_STATUS);
/*
* Make sure we've got a handler. If not, report an error. The event is
* disabled to prevent further interrupts.
*/
if (NULL == acpi_gbl_fixed_event_handlers[event].handler) {
- (void)acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 0);
+ (void)acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id,
+ ACPI_DISABLE_EVENT);
ACPI_ERROR((AE_INFO,
"No installed handler for fixed event [%08X]",
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index f345ced3647..b9d8ee69ca6 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -88,10 +88,10 @@ acpi_ev_set_gpe_type(struct acpi_gpe_event_info *gpe_event_info, u8 type)
status = acpi_ev_disable_gpe(gpe_event_info);
- /* Type was validated above */
+ /* Clear the type bits and insert the new Type */
- gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK; /* Clear type bits */
- gpe_event_info->flags |= type; /* Insert type */
+ gpe_event_info->flags &= ~ACPI_GPE_TYPE_MASK;
+ gpe_event_info->flags |= type;
return_ACPI_STATUS(status);
}
@@ -122,6 +122,7 @@ acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info,
if (!gpe_register_info) {
return_ACPI_STATUS(AE_NOT_EXIST);
}
+
register_bit = (u8)
(1 <<
(gpe_event_info->gpe_number - gpe_register_info->base_gpe_number));
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 484cc0565d5..7b346363942 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -104,9 +104,9 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info)
while (gpe_block) {
if ((&gpe_block->event_info[0] <= gpe_event_info) &&
- (&gpe_block->
- event_info[((acpi_size) gpe_block->
- register_count) * 8] >
+ (&gpe_block->event_info[((acpi_size)
+ gpe_block->
+ register_count) * 8] >
gpe_event_info)) {
return (TRUE);
}
@@ -210,10 +210,9 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
/* Now look at the individual GPEs in this byte register */
for (j = 0; j < ACPI_GPE_REGISTER_WIDTH; j++) {
- gpe_event_info =
- &gpe_block->
- event_info[((acpi_size) i *
- ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH)
+ + j];
if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
ACPI_GPE_DISPATCH_HANDLER) {
@@ -293,8 +292,8 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
/* Unknown method type, just ignore it! */
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
- "Ignoring unknown GPE method type: %s (name not of form _Lxx or _Exx)",
- name));
+ "Ignoring unknown GPE method type: %s "
+ "(name not of form _Lxx or _Exx)", name));
return_ACPI_STATUS(AE_OK);
}
@@ -306,17 +305,16 @@ acpi_ev_save_method_info(acpi_handle obj_handle,
/* Conversion failed; invalid method, just ignore it */
ACPI_DEBUG_PRINT((ACPI_DB_LOAD,
- "Could not extract GPE number from name: %s (name is not of form _Lxx or _Exx)",
- name));
+ "Could not extract GPE number from name: %s "
+ "(name is not of form _Lxx or _Exx)", name));
return_ACPI_STATUS(AE_OK);
}
/* Ensure that we have a valid GPE number for this GPE block */
if ((gpe_number < gpe_block->block_base_number) ||
- (gpe_number >=
- (gpe_block->block_base_number +
- (gpe_block->register_count * 8)))) {
+ (gpe_number >= (gpe_block->block_base_number +
+ (gpe_block->register_count * 8)))) {
/*
* Not valid for this GPE block, just ignore it. However, it may be
* valid for a different GPE block, since GPE0 and GPE1 methods both
@@ -408,7 +406,7 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
*/
obj_desc = pkg_desc->package.elements[0];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Use FADT-defined GPE device (from definition of _PRW) */
@@ -417,15 +415,15 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
/* Integer is the GPE number in the FADT described GPE blocks */
gpe_number = (u32) obj_desc->integer.value;
- } else if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ } else if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
/* Package contains a GPE reference and GPE number within a GPE block */
if ((obj_desc->package.count < 2) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[0]) !=
- ACPI_TYPE_LOCAL_REFERENCE)
- || (ACPI_GET_OBJECT_TYPE(obj_desc->package.elements[1]) !=
- ACPI_TYPE_INTEGER)) {
+ ((obj_desc->package.elements[0])->common.type !=
+ ACPI_TYPE_LOCAL_REFERENCE) ||
+ ((obj_desc->package.elements[1])->common.type !=
+ ACPI_TYPE_INTEGER)) {
goto cleanup;
}
@@ -450,11 +448,11 @@ acpi_ev_match_prw_and_gpe(acpi_handle obj_handle,
*/
if ((gpe_device == target_gpe_device) &&
(gpe_number >= gpe_block->block_base_number) &&
- (gpe_number <
- gpe_block->block_base_number + (gpe_block->register_count * 8))) {
- gpe_event_info =
- &gpe_block->event_info[gpe_number -
- gpe_block->block_base_number];
+ (gpe_number < gpe_block->block_base_number +
+ (gpe_block->register_count * 8))) {
+ gpe_event_info = &gpe_block->event_info[gpe_number -
+ gpe_block->
+ block_base_number];
/* Mark GPE for WAKE-ONLY but WAKE_DISABLED */
@@ -1033,8 +1031,8 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
* 1) are "runtime" or "run/wake" GPEs, and
* 2) have a corresponding _Lxx or _Exx method
*
- * Any other GPEs within this block must be enabled via the acpi_enable_gpe()
- * external interface.
+ * Any other GPEs within this block must be enabled via the
+ * acpi_enable_gpe() external interface.
*/
wake_gpe_count = 0;
gpe_enabled_count = 0;
@@ -1044,14 +1042,13 @@ acpi_ev_initialize_gpe_block(struct acpi_namespace_node *gpe_device,
/* Get the info block for this particular GPE */
- gpe_event_info =
- &gpe_block->
- event_info[((acpi_size) i *
- ACPI_GPE_REGISTER_WIDTH) + j];
+ gpe_event_info = &gpe_block->event_info[((acpi_size) i *
+ ACPI_GPE_REGISTER_WIDTH)
+ + j];
if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
- ACPI_GPE_DISPATCH_METHOD)
- && (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
+ ACPI_GPE_DISPATCH_METHOD) &&
+ (gpe_event_info->flags & ACPI_GPE_TYPE_RUNTIME)) {
gpe_enabled_count++;
}
@@ -1105,8 +1102,8 @@ acpi_status acpi_ev_gpe_initialize(void)
/*
* Initialize the GPE Block(s) defined in the FADT
*
- * Why the GPE register block lengths are divided by 2: From the ACPI Spec,
- * section "General-Purpose Event Registers", we have:
+ * Why the GPE register block lengths are divided by 2: From the ACPI
+ * Spec, section "General-Purpose Event Registers", we have:
*
* "Each register block contains two registers of equal length
* GPEx_STS and GPEx_EN (where x is 0 or 1). The length of the
@@ -1163,7 +1160,8 @@ acpi_status acpi_ev_gpe_initialize(void)
if ((register_count0) &&
(gpe_number_max >= acpi_gbl_FADT.gpe1_base)) {
ACPI_ERROR((AE_INFO,
- "GPE0 block (GPE 0 to %d) overlaps the GPE1 block (GPE %d to %d) - Ignoring GPE1",
+ "GPE0 block (GPE 0 to %d) overlaps the GPE1 block "
+ "(GPE %d to %d) - Ignoring GPE1",
gpe_number_max, acpi_gbl_FADT.gpe1_base,
acpi_gbl_FADT.gpe1_base +
((register_count1 *
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c
index 5f893057bcc..ce224e1eaa8 100644
--- a/drivers/acpi/acpica/evmisc.c
+++ b/drivers/acpi/acpica/evmisc.c
@@ -163,10 +163,10 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
* 2) Global device notify handler
* 3) Per-device notify handler
*/
- if ((acpi_gbl_system_notify.handler
- && (notify_value <= ACPI_MAX_SYS_NOTIFY))
- || (acpi_gbl_device_notify.handler
- && (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
+ if ((acpi_gbl_system_notify.handler &&
+ (notify_value <= ACPI_MAX_SYS_NOTIFY)) ||
+ (acpi_gbl_device_notify.handler &&
+ (notify_value > ACPI_MAX_SYS_NOTIFY)) || handler_obj) {
notify_info = acpi_ut_create_generic_state();
if (!notify_info) {
return (AE_NO_MEMORY);
@@ -174,7 +174,8 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
if (!handler_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Executing system notify handler for Notify (%4.4s, %X) node %p\n",
+ "Executing system notify handler for Notify (%4.4s, %X) "
+ "node %p\n",
acpi_ut_get_node_name(node),
notify_value, node));
}
@@ -534,8 +535,9 @@ acpi_status acpi_ev_release_global_lock(void)
*/
if (pending) {
status =
- acpi_set_register(ACPI_BITREG_GLOBAL_LOCK_RELEASE,
- 1);
+ acpi_write_bit_register
+ (ACPI_BITREG_GLOBAL_LOCK_RELEASE,
+ ACPI_ENABLE_EVENT);
}
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/evregion.c b/drivers/acpi/acpica/evregion.c
index 665c0887ab4..538d6326455 100644
--- a/drivers/acpi/acpica/evregion.c
+++ b/drivers/acpi/acpica/evregion.c
@@ -691,7 +691,7 @@ acpi_ev_install_handler(acpi_handle obj_handle,
/* Devices are handled different than regions */
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_DEVICE) {
+ if (obj_desc->common.type == ACPI_TYPE_DEVICE) {
/* Check if this Device already has a handler for this address space */
@@ -703,7 +703,8 @@ acpi_ev_install_handler(acpi_handle obj_handle,
if (next_handler_obj->address_space.space_id ==
handler_obj->address_space.space_id) {
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
- "Found handler for region [%s] in device %p(%p) handler %p\n",
+ "Found handler for region [%s] in device %p(%p) "
+ "handler %p\n",
acpi_ut_get_region_name
(handler_obj->address_space.
space_id), obj_desc,
diff --git a/drivers/acpi/acpica/evrgnini.c b/drivers/acpi/acpica/evrgnini.c
index f3f1fb45c3d..284a7becbe9 100644
--- a/drivers/acpi/acpica/evrgnini.c
+++ b/drivers/acpi/acpica/evrgnini.c
@@ -241,7 +241,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
status = AE_OK;
} else {
ACPI_EXCEPTION((AE_INFO, status,
- "Could not install PciConfig handler for Root Bridge %4.4s",
+ "Could not install PciConfig handler "
+ "for Root Bridge %4.4s",
acpi_ut_get_node_name
(pci_root_node)));
}
@@ -293,9 +294,8 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
* Get the PCI device and function numbers from the _ADR object contained
* in the parent's scope.
*/
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR, pci_device_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__ADR,
+ pci_device_node, &pci_value);
/*
* The default is zero, and since the allocation above zeroed the data,
@@ -308,18 +308,16 @@ acpi_ev_pci_config_region_setup(acpi_handle handle,
/* The PCI segment number comes from the _SEG method */
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG, pci_root_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__SEG,
+ pci_root_node, &pci_value);
if (ACPI_SUCCESS(status)) {
pci_id->segment = ACPI_LOWORD(pci_value);
}
/* The PCI bus number comes from the _BBN method */
- status =
- acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN, pci_root_node,
- &pci_value);
+ status = acpi_ut_evaluate_numeric_object(METHOD_NAME__BBN,
+ pci_root_node, &pci_value);
if (ACPI_SUCCESS(status)) {
pci_id->bus = ACPI_LOWORD(pci_value);
}
@@ -632,8 +630,8 @@ acpi_ev_initialize_region(union acpi_operand_object *region_obj,
acpi_ns_locked);
/*
- * Tell all users that this region is usable by running the _REG
- * method
+ * Tell all users that this region is usable by
+ * running the _REG method
*/
if (acpi_ns_locked) {
status =
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c
index 3aca9010a11..10b8543dd46 100644
--- a/drivers/acpi/acpica/evxface.c
+++ b/drivers/acpi/acpica/evxface.c
@@ -631,7 +631,8 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
/* Setup up dispatch flags to indicate handler (vs. method) */
- gpe_event_info->flags &= ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); /* Clear bits */
+ gpe_event_info->flags &=
+ ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK);
gpe_event_info->flags |= (u8) (type | ACPI_GPE_DISPATCH_HANDLER);
acpi_os_release_lock(acpi_gbl_gpe_lock, flags);
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c
index 35485e4b60a..d0a080747ec 100644
--- a/drivers/acpi/acpica/evxfevnt.c
+++ b/drivers/acpi/acpica/evxfevnt.c
@@ -172,8 +172,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, ACPI_ENABLE_EVENT);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -181,8 +181,8 @@ acpi_status acpi_enable_event(u32 event, u32 flags)
/* Make sure that the hardware responded */
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, &value);
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -354,15 +354,15 @@ acpi_status acpi_disable_event(u32 event, u32 flags)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, 0);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, ACPI_DISABLE_EVENT);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
- enable_register_id, &value);
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
+ enable_register_id, &value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -407,8 +407,8 @@ acpi_status acpi_clear_event(u32 event)
* register bit)
*/
status =
- acpi_set_register(acpi_gbl_fixed_event_info[event].
- status_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info[event].
+ status_register_id, ACPI_CLEAR_STATUS);
return_ACPI_STATUS(status);
}
@@ -495,7 +495,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
/* Get the status of the requested fixed event */
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
enable_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
@@ -503,7 +503,7 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status)
*event_status = value;
status =
- acpi_get_register(acpi_gbl_fixed_event_info[event].
+ acpi_read_bit_register(acpi_gbl_fixed_event_info[event].
status_register_id, &value);
if (ACPI_FAILURE(status))
return_ACPI_STATUS(status);
diff --git a/drivers/acpi/acpica/evxfregn.c b/drivers/acpi/acpica/evxfregn.c
index 479e7a3721b..7c3d2d356ff 100644
--- a/drivers/acpi/acpica/evxfregn.c
+++ b/drivers/acpi/acpica/evxfregn.c
@@ -193,7 +193,8 @@ acpi_remove_address_space_handler(acpi_handle device,
/* Matched space_id, first dereference this in the Regions */
ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
- "Removing address handler %p(%p) for region %s on Device %p(%p)\n",
+ "Removing address handler %p(%p) for region %s "
+ "on Device %p(%p)\n",
handler_obj, handler,
acpi_ut_get_region_name(space_id),
node, obj_desc));
diff --git a/drivers/acpi/acpica/exconfig.c b/drivers/acpi/acpica/exconfig.c
index 932bbc26aa0..3deb20a126b 100644
--- a/drivers/acpi/acpica/exconfig.c
+++ b/drivers/acpi/acpica/exconfig.c
@@ -291,7 +291,7 @@ acpi_ex_load_op(union acpi_operand_object *obj_desc,
/* Source Object can be either an op_region or a Buffer/Field */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_REGION:
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
@@ -501,7 +501,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
*/
if ((!ddb_handle) ||
(ACPI_GET_DESCRIPTOR_TYPE(ddb_handle) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE(ddb_handle) != ACPI_TYPE_LOCAL_REFERENCE)) {
+ (ddb_handle->common.type != ACPI_TYPE_LOCAL_REFERENCE)) {
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
@@ -520,13 +520,14 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
}
}
- /*
- * Delete the entire namespace under this table Node
- * (Offset contains the table_id)
- */
- acpi_tb_delete_namespace_by_owner(table_index);
- (void)acpi_tb_release_owner_id(table_index);
+ /* Delete the portion of the namespace owned by this table */
+
+ status = acpi_tb_delete_namespace_by_owner(table_index);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+ (void)acpi_tb_release_owner_id(table_index);
acpi_tb_set_table_loaded_flag(table_index, FALSE);
/* Table unloaded, remove a reference to the ddb_handle object */
diff --git a/drivers/acpi/acpica/exconvrt.c b/drivers/acpi/acpica/exconvrt.c
index 0be10188316..37d0d39e60a 100644
--- a/drivers/acpi/acpica/exconvrt.c
+++ b/drivers/acpi/acpica/exconvrt.c
@@ -82,7 +82,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_integer, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* No conversion necessary */
@@ -116,7 +116,7 @@ acpi_ex_convert_to_integer(union acpi_operand_object *obj_desc,
/* String conversion is different than Buffer conversion */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
/*
@@ -206,7 +206,7 @@ acpi_ex_convert_to_buffer(union acpi_operand_object *obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_buffer, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
/* No conversion necessary */
@@ -409,7 +409,7 @@ acpi_ex_convert_to_string(union acpi_operand_object * obj_desc,
ACPI_FUNCTION_TRACE_PTR(ex_convert_to_string, obj_desc);
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
/* No conversion necessary */
@@ -605,8 +605,7 @@ acpi_ex_convert_to_target_type(acpi_object_type destination_type,
default:
/* No conversion allowed for these types */
- if (destination_type !=
- ACPI_GET_OBJECT_TYPE(source_desc)) {
+ if (destination_type != source_desc->common.type) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Explicit operator, will store (%s) over existing type (%s)\n",
acpi_ut_get_object_type_name
diff --git a/drivers/acpi/acpica/exdump.c b/drivers/acpi/acpica/exdump.c
index aa313574b0d..89d141fdae0 100644
--- a/drivers/acpi/acpica/exdump.c
+++ b/drivers/acpi/acpica/exdump.c
@@ -350,6 +350,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
break;
case ACPI_EXD_TYPE:
+
acpi_ex_out_string("Type",
acpi_ut_get_object_type_name
(obj_desc));
@@ -422,6 +423,7 @@ acpi_ex_dump_object(union acpi_operand_object *obj_desc,
break;
default:
+
acpi_os_printf("**** Invalid table opcode [%X] ****\n",
info->opcode);
return;
@@ -492,7 +494,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
/* Decode object type */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
acpi_os_printf("Reference: [%s] ",
@@ -527,44 +529,16 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
type));
break;
- case ACPI_REFCLASS_ARG:
-
- acpi_os_printf("%X", obj_desc->reference.value);
-
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
- /* Value is an Integer */
-
- acpi_os_printf(" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64(obj_desc->
- integer.
- value));
- }
+ case ACPI_REFCLASS_NAME:
- acpi_os_printf("\n");
+ acpi_os_printf("- [%4.4s]\n",
+ obj_desc->reference.node->name.ascii);
break;
+ case ACPI_REFCLASS_ARG:
case ACPI_REFCLASS_LOCAL:
- acpi_os_printf("%X", obj_desc->reference.value);
-
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
-
- /* Value is an Integer */
-
- acpi_os_printf(" value is [%8.8X%8.8x]",
- ACPI_FORMAT_UINT64(obj_desc->
- integer.
- value));
- }
-
- acpi_os_printf("\n");
- break;
-
- case ACPI_REFCLASS_NAME:
-
- acpi_os_printf("- [%4.4s]\n",
- obj_desc->reference.node->name.ascii);
+ acpi_os_printf("%X\n", obj_desc->reference.value);
break;
default: /* Unknown reference class */
@@ -661,8 +635,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
case ACPI_TYPE_LOCAL_REGION_FIELD:
acpi_os_printf
- ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at byte=%X bit=%X of below:\n",
- obj_desc->field.bit_length,
+ ("RegionField: Bits=%X AccWidth=%X Lock=%X Update=%X at "
+ "byte=%X bit=%X of below:\n", obj_desc->field.bit_length,
obj_desc->field.access_byte_width,
obj_desc->field.field_flags & AML_FIELD_LOCK_RULE_MASK,
obj_desc->field.field_flags & AML_FIELD_UPDATE_RULE_MASK,
@@ -686,9 +660,8 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
if (!obj_desc->buffer_field.buffer_obj) {
ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "*NULL*\n"));
- } else
- if (ACPI_GET_OBJECT_TYPE(obj_desc->buffer_field.buffer_obj)
- != ACPI_TYPE_BUFFER) {
+ } else if ((obj_desc->buffer_field.buffer_obj)->common.type !=
+ ACPI_TYPE_BUFFER) {
acpi_os_printf("*not a Buffer*\n");
} else {
acpi_ex_dump_operand(obj_desc->buffer_field.buffer_obj,
@@ -737,8 +710,7 @@ void acpi_ex_dump_operand(union acpi_operand_object *obj_desc, u32 depth)
default:
/* Unknown Type */
- acpi_os_printf("Unknown Type %X\n",
- ACPI_GET_OBJECT_TYPE(obj_desc));
+ acpi_os_printf("Unknown Type %X\n", obj_desc->common.type);
break;
}
@@ -939,7 +911,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
/* Packages may only contain a few object types */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
acpi_os_printf("[Integer] = %8.8X%8.8X\n",
@@ -990,8 +962,7 @@ acpi_ex_dump_package_obj(union acpi_operand_object *obj_desc,
default:
- acpi_os_printf("[Unknown Type] %X\n",
- ACPI_GET_OBJECT_TYPE(obj_desc));
+ acpi_os_printf("[Unknown Type] %X\n", obj_desc->common.type);
break;
}
}
diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c
index a352d023385..546dcdd8678 100644
--- a/drivers/acpi/acpica/exfield.c
+++ b/drivers/acpi/acpica/exfield.c
@@ -84,7 +84,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
@@ -95,9 +95,8 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
return_ACPI_STATUS(status);
}
}
- } else
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
- && (obj_desc->field.region_obj->region.space_id ==
+ } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus read. We must create a buffer to hold the data
@@ -163,7 +162,7 @@ acpi_ex_read_data_from_field(struct acpi_walk_state *walk_state,
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldRead [TO]: Obj %p, Type %X, Buf %p, ByteLen %X\n",
- obj_desc, ACPI_GET_OBJECT_TYPE(obj_desc), buffer,
+ obj_desc, obj_desc->common.type, buffer,
(u32) length));
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldRead [FROM]: BitLen %X, BitOff %X, ByteOff %X\n",
@@ -222,7 +221,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
return_ACPI_STATUS(AE_AML_NO_OPERAND);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* If the buffer_field arguments have not been previously evaluated,
* evaluate them now and save the results.
@@ -233,9 +232,8 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
return_ACPI_STATUS(status);
}
}
- } else
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REGION_FIELD)
- && (obj_desc->field.region_obj->region.space_id ==
+ } else if ((obj_desc->common.type == ACPI_TYPE_LOCAL_REGION_FIELD) &&
+ (obj_desc->field.region_obj->region.space_id ==
ACPI_ADR_SPACE_SMBUS)) {
/*
* This is an SMBus write. We will bypass the entire field mechanism
@@ -243,7 +241,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
*
* Source must be a buffer of sufficient size (ACPI_SMBUS_BUFFER_SIZE).
*/
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ if (source_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO,
"SMBus write requires Buffer, found type %s",
acpi_ut_get_object_type_name(source_desc)));
@@ -291,7 +289,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
/* Get a pointer to the data to be written */
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
buffer = &source_desc->integer.value;
length = sizeof(source_desc->integer.value);
@@ -314,15 +312,14 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc,
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldWrite [FROM]: Obj %p (%s:%X), Buf %p, ByteLen %X\n",
source_desc,
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
- (source_desc)),
- ACPI_GET_OBJECT_TYPE(source_desc), buffer, length));
+ acpi_ut_get_type_name(source_desc->common.type),
+ source_desc->common.type, buffer, length));
ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
"FieldWrite [TO]: Obj %p (%s:%X), BitLen %X, BitOff %X, ByteOff %X\n",
obj_desc,
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)),
- ACPI_GET_OBJECT_TYPE(obj_desc),
+ acpi_ut_get_type_name(obj_desc->common.type),
+ obj_desc->common.type,
obj_desc->common_field.bit_length,
obj_desc->common_field.start_field_bit_offset,
obj_desc->common_field.base_byte_offset));
diff --git a/drivers/acpi/acpica/exfldio.c b/drivers/acpi/acpica/exfldio.c
index ef58ac4e687..99cee61e655 100644
--- a/drivers/acpi/acpica/exfldio.c
+++ b/drivers/acpi/acpica/exfldio.c
@@ -94,9 +94,9 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
/* We must have a valid region */
- if (ACPI_GET_OBJECT_TYPE(rgn_desc) != ACPI_TYPE_REGION) {
+ if (rgn_desc->common.type != ACPI_TYPE_REGION) {
ACPI_ERROR((AE_INFO, "Needed Region, found type %X (%s)",
- ACPI_GET_OBJECT_TYPE(rgn_desc),
+ rgn_desc->common.type,
acpi_ut_get_object_type_name(rgn_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -113,12 +113,6 @@ acpi_ex_setup_region(union acpi_operand_object *obj_desc,
}
}
- /* Exit if Address/Length have been disallowed by the host OS */
-
- if (rgn_desc->common.flags & AOPOBJ_INVALID) {
- return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
- }
-
/*
* Exit now for SMBus address space, it has a non-linear address space
* and the request cannot be directly validated
@@ -390,7 +384,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
* index_field - Write to an Index Register, then read/write from/to a
* Data Register
*/
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER_FIELD:
/*
* If the buffer_field arguments have not been previously evaluated,
@@ -527,7 +521,7 @@ acpi_ex_field_datum_io(union acpi_operand_object *obj_desc,
default:
ACPI_ERROR((AE_INFO, "Wrong object type in field I/O %X",
- ACPI_GET_OBJECT_TYPE(obj_desc)));
+ obj_desc->common.type));
status = AE_AML_INTERNAL;
break;
}
diff --git a/drivers/acpi/acpica/exmisc.c b/drivers/acpi/acpica/exmisc.c
index 6b0747ac683..998eac32993 100644
--- a/drivers/acpi/acpica/exmisc.c
+++ b/drivers/acpi/acpica/exmisc.c
@@ -80,7 +80,7 @@ acpi_ex_get_object_reference(union acpi_operand_object *obj_desc,
switch (ACPI_GET_DESCRIPTOR_TYPE(obj_desc)) {
case ACPI_DESC_TYPE_OPERAND:
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_LOCAL_REFERENCE) {
+ if (obj_desc->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
@@ -260,7 +260,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
status =
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -277,7 +277,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
default:
ACPI_ERROR((AE_INFO, "Invalid object type: %X",
- ACPI_GET_OBJECT_TYPE(operand0)));
+ operand0->common.type));
status = AE_AML_INTERNAL;
}
@@ -298,7 +298,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
* 2) Two Strings concatenated to produce a new String
* 3) Two Buffers concatenated to produce a new Buffer
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
/* Result of two Integers is a Buffer */
@@ -379,7 +379,7 @@ acpi_ex_do_concatenate(union acpi_operand_object *operand0,
/* Invalid object type, should not happen here */
ACPI_ERROR((AE_INFO, "Invalid object type: %X",
- ACPI_GET_OBJECT_TYPE(operand0)));
+ operand0->common.type));
status = AE_AML_INTERNAL;
goto cleanup;
}
@@ -581,7 +581,7 @@ acpi_ex_do_logical_op(u16 opcode,
* guaranteed to be either Integer/String/Buffer by the operand
* resolution mechanism.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand0)) {
+ switch (operand0->common.type) {
case ACPI_TYPE_INTEGER:
status =
acpi_ex_convert_to_integer(operand1, &local_operand1, 16);
@@ -608,7 +608,7 @@ acpi_ex_do_logical_op(u16 opcode,
/*
* Two cases: 1) Both Integers, 2) Both Strings or Buffers
*/
- if (ACPI_GET_OBJECT_TYPE(operand0) == ACPI_TYPE_INTEGER) {
+ if (operand0->common.type == ACPI_TYPE_INTEGER) {
/*
* 1) Both operands are of type integer
* Note: local_operand1 may have changed above
diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c
index b530480cc7d..9635d21e568 100644
--- a/drivers/acpi/acpica/exoparg1.c
+++ b/drivers/acpi/acpica/exoparg1.c
@@ -807,11 +807,9 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
acpi_namespace_node *)
operand[0]);
if (temp_desc
- &&
- ((ACPI_GET_OBJECT_TYPE(temp_desc) ==
- ACPI_TYPE_STRING)
- || (ACPI_GET_OBJECT_TYPE(temp_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE))) {
+ && ((temp_desc->common.type == ACPI_TYPE_STRING)
+ || (temp_desc->common.type ==
+ ACPI_TYPE_LOCAL_REFERENCE))) {
operand[0] = temp_desc;
acpi_ut_add_reference(temp_desc);
} else {
@@ -819,7 +817,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
goto cleanup;
}
} else {
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
/*
* This is a deref_of (local_x | arg_x)
@@ -877,8 +875,7 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state)
if (ACPI_GET_DESCRIPTOR_TYPE(operand[0]) !=
ACPI_DESC_TYPE_NAMED) {
- if (ACPI_GET_OBJECT_TYPE(operand[0]) ==
- ACPI_TYPE_STRING) {
+ if ((operand[0])->common.type == ACPI_TYPE_STRING) {
/*
* This is a deref_of (String). The string is a reference
* to a named ACPI object.
diff --git a/drivers/acpi/acpica/exoparg2.c b/drivers/acpi/acpica/exoparg2.c
index 0b4f513ca88..85d95c92dfd 100644
--- a/drivers/acpi/acpica/exoparg2.c
+++ b/drivers/acpi/acpica/exoparg2.c
@@ -399,7 +399,7 @@ acpi_status acpi_ex_opcode_2A_1T_1R(struct acpi_walk_state *walk_state)
* At this point, the Source operand is a String, Buffer, or Package.
* Verify that the index is within range.
*/
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_STRING:
if (index >= operand[0]->string.length) {
diff --git a/drivers/acpi/acpica/exoparg3.c b/drivers/acpi/acpica/exoparg3.c
index c6520bbf882..253f9e12258 100644
--- a/drivers/acpi/acpica/exoparg3.c
+++ b/drivers/acpi/acpica/exoparg3.c
@@ -161,9 +161,8 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
* Create the return object. The Source operand is guaranteed to be
* either a String or a Buffer, so just use its type.
*/
- return_desc =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
- (operand[0]));
+ return_desc = acpi_ut_create_internal_object((operand[0])->
+ common.type);
if (!return_desc) {
status = AE_NO_MEMORY;
goto cleanup;
@@ -191,7 +190,7 @@ acpi_status acpi_ex_opcode_3A_1T_1R(struct acpi_walk_state *walk_state)
/* Strings always have a sub-pointer, not so for buffers */
- switch (ACPI_GET_OBJECT_TYPE(operand[0])) {
+ switch ((operand[0])->common.type) {
case ACPI_TYPE_STRING:
/* Always allocate a new buffer for the String */
diff --git a/drivers/acpi/acpica/exprep.c b/drivers/acpi/acpica/exprep.c
index a226f74d4a5..52fec07064f 100644
--- a/drivers/acpi/acpica/exprep.c
+++ b/drivers/acpi/acpica/exprep.c
@@ -279,7 +279,7 @@ acpi_ex_decode_field_access(union acpi_operand_object *obj_desc,
return_UINT32(0);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_BUFFER_FIELD) {
+ if (obj_desc->common.type == ACPI_TYPE_BUFFER_FIELD) {
/*
* buffer_field access can be on any byte boundary, so the
* byte_alignment is always 1 byte -- regardless of any byte_alignment
diff --git a/drivers/acpi/acpica/exregion.c b/drivers/acpi/acpica/exregion.c
index 76ec8ff903b..3a54b737d2d 100644
--- a/drivers/acpi/acpica/exregion.c
+++ b/drivers/acpi/acpica/exregion.c
@@ -294,14 +294,14 @@ acpi_ex_system_io_space_handler(u32 function,
switch (function) {
case ACPI_READ:
- status = acpi_os_read_port((acpi_io_address) address,
+ status = acpi_hw_read_port((acpi_io_address) address,
&value32, bit_width);
*value = value32;
break;
case ACPI_WRITE:
- status = acpi_os_write_port((acpi_io_address) address,
+ status = acpi_hw_write_port((acpi_io_address) address,
(u32) * value, bit_width);
break;
diff --git a/drivers/acpi/acpica/exresnte.c b/drivers/acpi/acpica/exresnte.c
index a063a74006f..607958ff467 100644
--- a/drivers/acpi/acpica/exresnte.c
+++ b/drivers/acpi/acpica/exresnte.c
@@ -136,7 +136,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
switch (entry_type) {
case ACPI_TYPE_PACKAGE:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_PACKAGE) {
+ if (source_desc->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO, "Object not a Package, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -154,7 +154,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_BUFFER:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) {
+ if (source_desc->common.type != ACPI_TYPE_BUFFER) {
ACPI_ERROR((AE_INFO, "Object not a Buffer, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -172,7 +172,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_STRING:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) {
+ if (source_desc->common.type != ACPI_TYPE_STRING) {
ACPI_ERROR((AE_INFO, "Object not a String, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
@@ -186,7 +186,7 @@ acpi_ex_resolve_node_to_value(struct acpi_namespace_node **object_ptr,
case ACPI_TYPE_INTEGER:
- if (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) {
+ if (source_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO, "Object not a Integer, type %s",
acpi_ut_get_object_type_name(source_desc)));
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
diff --git a/drivers/acpi/acpica/exresolv.c b/drivers/acpi/acpica/exresolv.c
index f6105a6d612..c93b54ce7f7 100644
--- a/drivers/acpi/acpica/exresolv.c
+++ b/drivers/acpi/acpica/exresolv.c
@@ -149,7 +149,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
/* This is a union acpi_operand_object */
- switch (ACPI_GET_OBJECT_TYPE(stack_desc)) {
+ switch (stack_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
ref_type = stack_desc->reference.class;
@@ -297,8 +297,7 @@ acpi_ex_resolve_object_to_value(union acpi_operand_object **stack_ptr,
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"FieldRead SourceDesc=%p Type=%X\n",
- stack_desc,
- ACPI_GET_OBJECT_TYPE(stack_desc)));
+ stack_desc, stack_desc->common.type));
status =
acpi_ex_read_data_from_field(walk_state, stack_desc,
@@ -386,7 +385,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
* specification of the object_type and size_of operators). This means
* traversing the list of possibly many nested references.
*/
- while (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_REFERENCE) {
+ while (obj_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
switch (obj_desc->reference.class) {
case ACPI_REFCLASS_REFOF:
case ACPI_REFCLASS_NAME:
@@ -518,7 +517,7 @@ acpi_ex_resolve_multiple(struct acpi_walk_state *walk_state,
* Now we are guaranteed to have an object that has not been created
* via the ref_of or Index operators.
*/
- type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ type = obj_desc->common.type;
exit:
/* Convert internal types to external types */
diff --git a/drivers/acpi/acpica/exresop.c b/drivers/acpi/acpica/exresop.c
index 3c3802764bf..5c729a9e913 100644
--- a/drivers/acpi/acpica/exresop.c
+++ b/drivers/acpi/acpica/exresop.c
@@ -212,7 +212,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* ACPI internal object */
- object_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ object_type = obj_desc->common.type;
/* Check for bad acpi_object_type */
@@ -287,8 +287,7 @@ acpi_ex_resolve_operands(u16 opcode,
if ((ACPI_GET_DESCRIPTOR_TYPE(obj_desc) ==
ACPI_DESC_TYPE_OPERAND)
- && (ACPI_GET_OBJECT_TYPE(obj_desc) ==
- ACPI_TYPE_STRING)) {
+ && (obj_desc->common.type == ACPI_TYPE_STRING)) {
/*
* String found - the string references a named object and
* must be resolved to a node
@@ -336,7 +335,7 @@ acpi_ex_resolve_operands(u16 opcode,
* -- All others must be resolved below.
*/
if ((opcode == AML_STORE_OP) &&
- (ACPI_GET_OBJECT_TYPE(*stack_ptr) ==
+ ((*stack_ptr)->common.type ==
ACPI_TYPE_LOCAL_REFERENCE)
&& ((*stack_ptr)->reference.class == ACPI_REFCLASS_INDEX)) {
goto next_operand;
@@ -490,7 +489,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type INTEGER, STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -512,7 +511,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type STRING or BUFFER */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -553,7 +552,7 @@ acpi_ex_resolve_operands(u16 opcode,
* The only reference allowed here is a direct reference to
* a namespace node.
*/
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -576,7 +575,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need a buffer or package or (ACPI 2.0) String */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
case ACPI_TYPE_BUFFER:
@@ -598,7 +597,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Need an operand of type REGION or a BUFFER (which could be a resolved region field) */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_REGION:
@@ -619,7 +618,7 @@ acpi_ex_resolve_operands(u16 opcode,
/* Used by the Store() operator only */
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
case ACPI_TYPE_PACKAGE:
case ACPI_TYPE_STRING:
@@ -677,8 +676,8 @@ acpi_ex_resolve_operands(u16 opcode,
* required object type (Simple cases only).
*/
status = acpi_ex_check_object_type(type_needed,
- ACPI_GET_OBJECT_TYPE
- (*stack_ptr), *stack_ptr);
+ (*stack_ptr)->common.type,
+ *stack_ptr);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/exstore.c b/drivers/acpi/acpica/exstore.c
index e35e9b4f6a4..90d606196c9 100644
--- a/drivers/acpi/acpica/exstore.c
+++ b/drivers/acpi/acpica/exstore.c
@@ -129,7 +129,7 @@ acpi_ex_do_debug_object(union acpi_operand_object *source_desc,
/* source_desc is of type ACPI_DESC_TYPE_OPERAND */
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Output correct integer width */
@@ -324,7 +324,7 @@ acpi_ex_store(union acpi_operand_object *source_desc,
/* Destination object must be a Reference or a Constant object */
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
break;
@@ -460,9 +460,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
*/
obj_desc = *(index_desc->reference.where);
- if (ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE
- && source_desc->reference.class == ACPI_REFCLASS_TABLE) {
+ if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE &&
+ source_desc->reference.class == ACPI_REFCLASS_TABLE) {
/* This is a DDBHandle, just add a reference to it */
@@ -520,8 +519,8 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
* by the INDEX_OP code.
*/
obj_desc = index_desc->reference.object;
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_STRING)) {
+ if ((obj_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (obj_desc->common.type != ACPI_TYPE_STRING)) {
return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
}
@@ -529,7 +528,7 @@ acpi_ex_store_object_to_index(union acpi_operand_object *source_desc,
* The assignment of the individual elements will be slightly
* different for each source type.
*/
- switch (ACPI_GET_OBJECT_TYPE(source_desc)) {
+ switch (source_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Use the least-significant byte of the integer */
@@ -707,8 +706,7 @@ acpi_ex_store_object_to_node(union acpi_operand_object *source_desc,
/* No conversions for all other types. Just attach the source object */
status = acpi_ns_attach_object(node, source_desc,
- ACPI_GET_OBJECT_TYPE
- (source_desc));
+ source_desc->common.type);
break;
}
diff --git a/drivers/acpi/acpica/exstoren.c b/drivers/acpi/acpica/exstoren.c
index 145d15305f7..608e838d537 100644
--- a/drivers/acpi/acpica/exstoren.c
+++ b/drivers/acpi/acpica/exstoren.c
@@ -96,8 +96,7 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
* are all essentially the same. This case handles the
* "interchangeable" types Integer, String, and Buffer.
*/
- if (ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE) {
+ if (source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
/* Resolve a reference object first */
@@ -117,13 +116,11 @@ acpi_ex_resolve_object(union acpi_operand_object **source_desc_ptr,
/* Must have a Integer, Buffer, or String */
- if ((ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_INTEGER) &&
- (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_BUFFER) &&
- (ACPI_GET_OBJECT_TYPE(source_desc) != ACPI_TYPE_STRING) &&
- !((ACPI_GET_OBJECT_TYPE(source_desc) ==
- ACPI_TYPE_LOCAL_REFERENCE)
- && (source_desc->reference.class ==
- ACPI_REFCLASS_TABLE))) {
+ if ((source_desc->common.type != ACPI_TYPE_INTEGER) &&
+ (source_desc->common.type != ACPI_TYPE_BUFFER) &&
+ (source_desc->common.type != ACPI_TYPE_STRING) &&
+ !((source_desc->common.type == ACPI_TYPE_LOCAL_REFERENCE) &&
+ (source_desc->reference.class == ACPI_REFCLASS_TABLE))) {
/* Conversion successful but still not a valid type */
@@ -218,8 +215,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(source_desc) !=
- ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ if (source_desc->common.type != dest_desc->common.type) {
/*
* The source type does not match the type of the destination.
* Perform the "implicit conversion" of the source to the current type
@@ -229,11 +225,10 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
* Otherwise, actual_src_desc is a temporary object to hold the
* converted object.
*/
- status =
- acpi_ex_convert_to_target_type(ACPI_GET_OBJECT_TYPE
- (dest_desc), source_desc,
- &actual_src_desc,
- walk_state);
+ status = acpi_ex_convert_to_target_type(dest_desc->common.type,
+ source_desc,
+ &actual_src_desc,
+ walk_state);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -252,7 +247,7 @@ acpi_ex_store_object_to_object(union acpi_operand_object *source_desc,
* We now have two objects of identical types, and we can perform a
* copy of the *value* of the source object.
*/
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_INTEGER:
dest_desc->integer.value = actual_src_desc->integer.value;
diff --git a/drivers/acpi/acpica/exutils.c b/drivers/acpi/acpica/exutils.c
index 32b85d68e75..87730e94413 100644
--- a/drivers/acpi/acpica/exutils.c
+++ b/drivers/acpi/acpica/exutils.c
@@ -221,7 +221,7 @@ void acpi_ex_truncate_for32bit_table(union acpi_operand_object *obj_desc)
*/
if ((!obj_desc) ||
(ACPI_GET_DESCRIPTOR_TYPE(obj_desc) != ACPI_DESC_TYPE_OPERAND) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+ (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
return;
}
diff --git a/drivers/acpi/acpica/hwacpi.c b/drivers/acpi/acpica/hwacpi.c
index a9d4fea4167..9af361a191e 100644
--- a/drivers/acpi/acpica/hwacpi.c
+++ b/drivers/acpi/acpica/hwacpi.c
@@ -86,7 +86,8 @@ acpi_status acpi_hw_set_mode(u32 mode)
*/
if (!acpi_gbl_FADT.acpi_enable && !acpi_gbl_FADT.acpi_disable) {
ACPI_ERROR((AE_INFO,
- "No ACPI mode transition supported in this system (enable/disable both zero)"));
+ "No ACPI mode transition supported in this system "
+ "(enable/disable both zero)"));
return_ACPI_STATUS(AE_OK);
}
@@ -95,7 +96,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
/* BIOS should have disabled ALL fixed and GP events */
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_enable, 8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Attempting to enable ACPI mode\n"));
@@ -107,7 +108,7 @@ acpi_status acpi_hw_set_mode(u32 mode)
* BIOS should clear all fixed status bits and restore fixed event
* enable bits to default
*/
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.acpi_disable,
8);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -172,7 +173,7 @@ u32 acpi_hw_get_mode(void)
return_UINT32(ACPI_SYS_MODE_ACPI);
}
- status = acpi_get_register(ACPI_BITREG_SCI_ENABLE, &value);
+ status = acpi_read_bit_register(ACPI_BITREG_SCI_ENABLE, &value);
if (ACPI_FAILURE(status)) {
return_UINT32(ACPI_SYS_MODE_LEGACY);
}
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 2013b66745d..d3b7e37c9ee 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -89,10 +89,9 @@ acpi_status acpi_hw_low_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
/* Clear just the bit that corresponds to this GPE */
- ACPI_CLEAR_BIT(enable_mask,
- ((u32) 1 <<
- (gpe_event_info->gpe_number -
- gpe_register_info->base_gpe_number)));
+ ACPI_CLEAR_BIT(enable_mask, ((u32)1 <<
+ (gpe_event_info->gpe_number -
+ gpe_register_info->base_gpe_number)));
/* Write the updated enable mask */
@@ -156,10 +155,9 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info)
ACPI_FUNCTION_ENTRY();
- register_bit = (u8)
- (1 <<
- (gpe_event_info->gpe_number -
- gpe_event_info->register_info->base_gpe_number));
+ register_bit = (u8)(1 <<
+ (gpe_event_info->gpe_number -
+ gpe_event_info->register_info->base_gpe_number));
/*
* Write a one to the appropriate bit in the status register to
@@ -206,10 +204,9 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info,
/* Get the register bitmask for this GPE */
- register_bit = (u8)
- (1 <<
- (gpe_event_info->gpe_number -
- gpe_event_info->register_info->base_gpe_number));
+ register_bit = (u8)(1 <<
+ (gpe_event_info->gpe_number -
+ gpe_event_info->register_info->base_gpe_number));
/* GPE currently enabled? (enabled for runtime?) */
diff --git a/drivers/acpi/acpica/hwregs.c b/drivers/acpi/acpica/hwregs.c
index 4dc43b01851..7b2fb602b5c 100644
--- a/drivers/acpi/acpica/hwregs.c
+++ b/drivers/acpi/acpica/hwregs.c
@@ -51,6 +51,17 @@
#define _COMPONENT ACPI_HARDWARE
ACPI_MODULE_NAME("hwregs")
+/* Local Prototypes */
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b);
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b);
+
/*******************************************************************************
*
* FUNCTION: acpi_hw_clear_acpi_status
@@ -60,9 +71,9 @@ ACPI_MODULE_NAME("hwregs")
* RETURN: Status
*
* DESCRIPTION: Clears all fixed and general purpose status bits
- * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED
*
******************************************************************************/
+
acpi_status acpi_hw_clear_acpi_status(void)
{
acpi_status status;
@@ -70,28 +81,20 @@ acpi_status acpi_hw_clear_acpi_status(void)
ACPI_FUNCTION_TRACE(hw_clear_acpi_status);
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %04X\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "About to write %04X to %0llX\n",
ACPI_BITMASK_ALL_FIXED_STATUS,
- (u16) acpi_gbl_FADT.xpm1a_event_block.address));
+ acpi_gbl_xpm1a_status.address));
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
+ /* Clear the fixed events in PM1 A/B */
+
status = acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
ACPI_BITMASK_ALL_FIXED_STATUS);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- /* Clear the fixed events */
-
- if (acpi_gbl_FADT.xpm1b_event_block.address) {
- status = acpi_write(ACPI_BITMASK_ALL_FIXED_STATUS,
- &acpi_gbl_FADT.xpm1b_event_block);
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
- }
-
/* Clear the GPE Bits in all GPE registers in all GPE blocks */
status = acpi_ev_walk_gpe_list(acpi_hw_clear_gpe_block, NULL);
@@ -128,6 +131,42 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
/******************************************************************************
*
+ * FUNCTION: acpi_hw_write_pm1_control
+ *
+ * PARAMETERS: pm1a_control - Value to be written to PM1A control
+ * pm1b_control - Value to be written to PM1B control
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write the PM1 A/B control registers. These registers are
+ * different than than the PM1 A/B status and enable registers
+ * in that different values can be written to the A/B registers.
+ * Most notably, the SLP_TYP bits can be different, as per the
+ * values returned from the _Sx predefined methods.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_write_pm1_control(u32 pm1a_control, u32 pm1b_control)
+{
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(hw_write_pm1_control);
+
+ status = acpi_write(pm1a_control, &acpi_gbl_FADT.xpm1a_control_block);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (acpi_gbl_FADT.xpm1b_control_block.address) {
+ status =
+ acpi_write(pm1b_control,
+ &acpi_gbl_FADT.xpm1b_control_block);
+ }
+ return_ACPI_STATUS(status);
+}
+
+/******************************************************************************
+ *
* FUNCTION: acpi_hw_register_read
*
* PARAMETERS: register_id - ACPI Register ID
@@ -141,64 +180,56 @@ struct acpi_bit_register_info *acpi_hw_get_bit_register_info(u32 register_id)
acpi_status
acpi_hw_register_read(u32 register_id, u32 * return_value)
{
- u32 value1 = 0;
- u32 value2 = 0;
+ u32 value = 0;
acpi_status status;
ACPI_FUNCTION_TRACE(hw_register_read);
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
-
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_event_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_event_block);
- value1 |= value2;
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_xpm1a_status,
+ &acpi_gbl_xpm1b_status);
break;
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value1, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
-
- status = acpi_read(&value2, &acpi_gbl_xpm1b_enable);
- value1 |= value2;
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_xpm1a_enable,
+ &acpi_gbl_xpm1b_enable);
break;
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm1a_control_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
+ status = acpi_hw_read_multiple(&value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
- status = acpi_read(&value2, &acpi_gbl_FADT.xpm1b_control_block);
- value1 |= value2;
+ /*
+ * Zero the write-only bits. From the ACPI specification, "Hardware
+ * Write-Only Bits": "Upon reads to registers with write-only bits,
+ * software masks out all write-only bits."
+ */
+ value &= ~ACPI_PM1_CONTROL_WRITEONLY_BITS;
break;
case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm2_control_block);
+ status = acpi_read(&value, &acpi_gbl_FADT.xpm2_control_block);
break;
case ACPI_REGISTER_PM_TIMER: /* 32-bit access */
- status = acpi_read(&value1, &acpi_gbl_FADT.xpm_timer_block);
+ status = acpi_read(&value, &acpi_gbl_FADT.xpm_timer_block);
break;
case ACPI_REGISTER_SMI_COMMAND_BLOCK: /* 8-bit access */
status =
- acpi_os_read_port(acpi_gbl_FADT.smi_command, &value1, 8);
+ acpi_hw_read_port(acpi_gbl_FADT.smi_command, &value, 8);
break;
default:
@@ -207,10 +238,8 @@ acpi_hw_register_read(u32 register_id, u32 * return_value)
break;
}
- exit:
-
if (ACPI_SUCCESS(status)) {
- *return_value = value1;
+ *return_value = value;
}
return_ACPI_STATUS(status);
@@ -250,52 +279,42 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
ACPI_FUNCTION_TRACE(hw_register_write);
switch (register_id) {
- case ACPI_REGISTER_PM1_STATUS: /* 16-bit access */
-
- /* Perform a read first to preserve certain bits (per ACPI spec) */
-
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_STATUS,
- &read_value);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* Insert the bits to be preserved */
-
- ACPI_INSERT_BITS(value, ACPI_PM1_STATUS_PRESERVED_BITS,
- read_value);
-
- /* Now we can write the data */
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_event_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
+ case ACPI_REGISTER_PM1_STATUS: /* PM1 A/B: 16-bit access each */
+ /*
+ * Handle the "ignored" bit in PM1 Status. According to the ACPI
+ * specification, ignored bits are to be preserved when writing.
+ * Normally, this would mean a read/modify/write sequence. However,
+ * preserving a bit in the status register is different. Writing a
+ * one clears the status, and writing a zero preserves the status.
+ * Therefore, we must always write zero to the ignored bit.
+ *
+ * This behavior is clarified in the ACPI 4.0 specification.
+ */
+ value &= ~ACPI_PM1_STATUS_PRESERVED_BITS;
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_event_block);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_xpm1a_status,
+ &acpi_gbl_xpm1b_status);
break;
- case ACPI_REGISTER_PM1_ENABLE: /* 16-bit access */
+ case ACPI_REGISTER_PM1_ENABLE: /* PM1 A/B: 16-bit access */
- status = acpi_write(value, &acpi_gbl_xpm1a_enable);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- /* PM1B is optional */
-
- status = acpi_write(value, &acpi_gbl_xpm1b_enable);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_xpm1a_enable,
+ &acpi_gbl_xpm1b_enable);
break;
- case ACPI_REGISTER_PM1_CONTROL: /* 16-bit access */
+ case ACPI_REGISTER_PM1_CONTROL: /* PM1 A/B: 16-bit access each */
/*
* Perform a read first to preserve certain bits (per ACPI spec)
+ * Note: This includes SCI_EN, we never want to change this bit
*/
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
- &read_value);
+ status = acpi_hw_read_multiple(&read_value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
if (ACPI_FAILURE(status)) {
goto exit;
}
@@ -307,25 +326,29 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
/* Now we can write the data */
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
- if (ACPI_FAILURE(status)) {
- goto exit;
- }
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
+ status = acpi_hw_write_multiple(value,
+ &acpi_gbl_FADT.
+ xpm1a_control_block,
+ &acpi_gbl_FADT.
+ xpm1b_control_block);
break;
- case ACPI_REGISTER_PM1A_CONTROL: /* 16-bit access */
-
- status = acpi_write(value, &acpi_gbl_FADT.xpm1a_control_block);
- break;
+ case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
- case ACPI_REGISTER_PM1B_CONTROL: /* 16-bit access */
+ /*
+ * For control registers, all reserved bits must be preserved,
+ * as per the ACPI spec.
+ */
+ status =
+ acpi_read(&read_value, &acpi_gbl_FADT.xpm2_control_block);
+ if (ACPI_FAILURE(status)) {
+ goto exit;
+ }
- status = acpi_write(value, &acpi_gbl_FADT.xpm1b_control_block);
- break;
+ /* Insert the bits to be preserved */
- case ACPI_REGISTER_PM2_CONTROL: /* 8-bit access */
+ ACPI_INSERT_BITS(value, ACPI_PM2_CONTROL_PRESERVED_BITS,
+ read_value);
status = acpi_write(value, &acpi_gbl_FADT.xpm2_control_block);
break;
@@ -340,10 +363,11 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
/* SMI_CMD is currently always in IO space */
status =
- acpi_os_write_port(acpi_gbl_FADT.smi_command, value, 8);
+ acpi_hw_write_port(acpi_gbl_FADT.smi_command, value, 8);
break;
default:
+ ACPI_ERROR((AE_INFO, "Unknown Register ID: %X", register_id));
status = AE_BAD_PARAMETER;
break;
}
@@ -351,3 +375,103 @@ acpi_status acpi_hw_register_write(u32 register_id, u32 value)
exit:
return_ACPI_STATUS(status);
}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_read_multiple
+ *
+ * PARAMETERS: Value - Where the register value is returned
+ * register_a - First ACPI register (required)
+ * register_b - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Read from the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_read_multiple(u32 *value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b)
+{
+ u32 value_a = 0;
+ u32 value_b = 0;
+ acpi_status status;
+
+ /* The first register is always required */
+
+ status = acpi_read(&value_a, register_a);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /* Second register is optional */
+
+ if (register_b->address) {
+ status = acpi_read(&value_b, register_b);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+ }
+
+ /*
+ * OR the two return values together. No shifting or masking is necessary,
+ * because of how the PM1 registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ *value = (value_a | value_b);
+ return (AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_write_multiple
+ *
+ * PARAMETERS: Value - The value to write
+ * register_a - First ACPI register (required)
+ * register_b - Second ACPI register (optional)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Write to the specified two-part ACPI register (such as PM1 A/B)
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_write_multiple(u32 value,
+ struct acpi_generic_address *register_a,
+ struct acpi_generic_address *register_b)
+{
+ acpi_status status;
+
+ /* The first register is always required */
+
+ status = acpi_write(value, register_a);
+ if (ACPI_FAILURE(status)) {
+ return (status);
+ }
+
+ /*
+ * Second register is optional
+ *
+ * No bit shifting or clearing is necessary, because of how the PM1
+ * registers are defined in the ACPI specification:
+ *
+ * "Although the bits can be split between the two register blocks (each
+ * register block has a unique pointer within the FADT), the bit positions
+ * are maintained. The register block with unimplemented bits (that is,
+ * those implemented in the other register block) always returns zeros,
+ * and writes have no side effects"
+ */
+ if (register_b->address) {
+ status = acpi_write(value, register_b);
+ }
+
+ return (status);
+}
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c
index a2af2a4f2f2..baa5fc05e12 100644
--- a/drivers/acpi/acpica/hwsleep.c
+++ b/drivers/acpi/acpica/hwsleep.c
@@ -90,6 +90,7 @@ acpi_set_firmware_waking_vector(u32 physical_address)
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
+#if ACPI_MACHINE_WIDTH == 64
/*******************************************************************************
*
* FUNCTION: acpi_set_firmware_waking_vector64
@@ -100,7 +101,8 @@ ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector)
* RETURN: Status
*
* DESCRIPTION: Sets the 64-bit X_firmware_waking_vector field of the FACS, if
- * it exists in the table.
+ * it exists in the table. This function is intended for use with
+ * 64-bit host operating systems.
*
******************************************************************************/
acpi_status
@@ -124,6 +126,7 @@ acpi_set_firmware_waking_vector64(u64 physical_address)
}
ACPI_EXPORT_SYMBOL(acpi_set_firmware_waking_vector64)
+#endif
/*******************************************************************************
*
@@ -147,9 +150,8 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_prep);
- /*
- * _PSW methods could be run here to enable wake-on keyboard, LAN, etc.
- */
+ /* _PSW methods could be run here to enable wake-on keyboard, LAN, etc. */
+
status = acpi_get_sleep_type_data(sleep_state,
&acpi_gbl_sleep_type_a,
&acpi_gbl_sleep_type_b);
@@ -223,8 +225,8 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep)
******************************************************************************/
acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
{
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
+ u32 pm1a_control;
+ u32 pm1b_control;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
u32 in_value;
@@ -242,13 +244,14 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
}
sleep_type_reg_info =
- acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Clear wake status */
- status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ status =
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -289,24 +292,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Get current value of PM1A control */
- status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
+ status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
+ &pm1a_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
ACPI_DEBUG_PRINT((ACPI_DB_INIT,
"Entering sleep state [S%d]\n", sleep_state));
- /* Clear SLP_EN and SLP_TYP fields */
+ /* Clear the SLP_EN and SLP_TYP fields */
- PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->access_bit_mask);
- PM1Bcontrol = PM1Acontrol;
+ pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+ sleep_enable_reg_info->access_bit_mask);
+ pm1b_control = pm1a_control;
- /* Insert SLP_TYP bits */
+ /* Insert the SLP_TYP bits */
- PM1Acontrol |=
+ pm1a_control |=
(acpi_gbl_sleep_type_a << sleep_type_reg_info->bit_position);
- PM1Bcontrol |=
+ pm1b_control |=
(acpi_gbl_sleep_type_b << sleep_type_reg_info->bit_position);
/*
@@ -314,37 +318,25 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
* poorly implemented hardware.
*/
- /* Write #1: fill in SLP_TYP data */
+ /* Write #1: write the SLP_TYP data to the PM1 Control registers */
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
+ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ /* Insert the sleep enable (SLP_EN) bit */
- /* Insert SLP_ENABLE bit */
+ pm1a_control |= sleep_enable_reg_info->access_bit_mask;
+ pm1b_control |= sleep_enable_reg_info->access_bit_mask;
- PM1Acontrol |= sleep_enable_reg_info->access_bit_mask;
- PM1Bcontrol |= sleep_enable_reg_info->access_bit_mask;
-
- /* Write #2: SLP_TYP + SLP_EN */
+ /* Flush caches, as per ACPI specification */
ACPI_FLUSH_CPU_CACHE();
- status = acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
- if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
- }
+ /* Write #2: Write both SLP_TYP + SLP_EN */
- status = acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
+ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -357,8 +349,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
* Wait ten seconds, then try again. This is to get S4/S5 to work on
* all machines.
*
- * We wait so long to allow chipsets that poll this reg very slowly to
- * still read the right value. Ideally, this block would go
+ * We wait so long to allow chipsets that poll this reg very slowly
+ * to still read the right value. Ideally, this block would go
* away entirely.
*/
acpi_os_stall(10000000);
@@ -374,7 +366,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
/* Wait until we enter sleep state */
do {
- status = acpi_get_register_unlocked(ACPI_BITREG_WAKE_STATUS,
+ status = acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS,
&in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
@@ -408,7 +400,10 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
ACPI_FUNCTION_TRACE(acpi_enter_sleep_state_s4bios);
- status = acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ /* Clear the wake status bit (PM1) */
+
+ status =
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, ACPI_CLEAR_STATUS);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -435,12 +430,13 @@ acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)
ACPI_FLUSH_CPU_CACHE();
- status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command,
(u32) acpi_gbl_FADT.S4bios_request, 8);
do {
acpi_os_stall(1000);
- status = acpi_get_register(ACPI_BITREG_WAKE_STATUS, &in_value);
+ status =
+ acpi_read_bit_register(ACPI_BITREG_WAKE_STATUS, &in_value);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -471,8 +467,8 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
acpi_status status;
struct acpi_bit_register_info *sleep_type_reg_info;
struct acpi_bit_register_info *sleep_enable_reg_info;
- u32 PM1Acontrol;
- u32 PM1Bcontrol;
+ u32 pm1a_control;
+ u32 pm1b_control;
ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
@@ -486,38 +482,34 @@ acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
&acpi_gbl_sleep_type_b);
if (ACPI_SUCCESS(status)) {
sleep_type_reg_info =
- acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE_A);
+ acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_TYPE);
sleep_enable_reg_info =
acpi_hw_get_bit_register_info(ACPI_BITREG_SLEEP_ENABLE);
/* Get current value of PM1A control */
status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL,
- &PM1Acontrol);
+ &pm1a_control);
if (ACPI_SUCCESS(status)) {
- /* Clear SLP_EN and SLP_TYP fields */
+ /* Clear the SLP_EN and SLP_TYP fields */
- PM1Acontrol &= ~(sleep_type_reg_info->access_bit_mask |
- sleep_enable_reg_info->
- access_bit_mask);
- PM1Bcontrol = PM1Acontrol;
+ pm1a_control &= ~(sleep_type_reg_info->access_bit_mask |
+ sleep_enable_reg_info->
+ access_bit_mask);
+ pm1b_control = pm1a_control;
- /* Insert SLP_TYP bits */
+ /* Insert the SLP_TYP bits */
- PM1Acontrol |=
- (acpi_gbl_sleep_type_a << sleep_type_reg_info->
- bit_position);
- PM1Bcontrol |=
- (acpi_gbl_sleep_type_b << sleep_type_reg_info->
- bit_position);
+ pm1a_control |= (acpi_gbl_sleep_type_a <<
+ sleep_type_reg_info->bit_position);
+ pm1b_control |= (acpi_gbl_sleep_type_b <<
+ sleep_type_reg_info->bit_position);
- /* Just ignore any errors */
+ /* Write the control registers and ignore any errors */
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1A_CONTROL,
- PM1Acontrol);
- (void)acpi_hw_register_write(ACPI_REGISTER_PM1B_CONTROL,
- PM1Bcontrol);
+ (void)acpi_hw_write_pm1_control(pm1a_control,
+ pm1b_control);
}
}
@@ -603,19 +595,21 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
* it to determine whether the system is rebooting or resuming. Clear
* it for compatibility.
*/
- acpi_set_register(ACPI_BITREG_WAKE_STATUS, 1);
+ acpi_write_bit_register(ACPI_BITREG_WAKE_STATUS, 1);
acpi_gbl_system_awake_and_running = TRUE;
/* Enable power button */
(void)
- acpi_set_register(acpi_gbl_fixed_event_info
- [ACPI_EVENT_POWER_BUTTON].enable_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].
+ enable_register_id, ACPI_ENABLE_EVENT);
(void)
- acpi_set_register(acpi_gbl_fixed_event_info
- [ACPI_EVENT_POWER_BUTTON].status_register_id, 1);
+ acpi_write_bit_register(acpi_gbl_fixed_event_info
+ [ACPI_EVENT_POWER_BUTTON].
+ status_register_id, ACPI_CLEAR_STATUS);
arg.integer.value = ACPI_SST_WORKING;
status = acpi_evaluate_object(NULL, METHOD_NAME__SST, &arg_list, NULL);
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
new file mode 100644
index 00000000000..bd3c937b0ac
--- /dev/null
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -0,0 +1,258 @@
+
+/******************************************************************************
+ *
+ * Module Name: hwvalid - I/O request validation
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_HARDWARE
+ACPI_MODULE_NAME("hwvalid")
+
+/* Local prototypes */
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width);
+
+/*
+ * Protected I/O ports. Some ports are always illegal, and some are
+ * conditionally illegal. This table must remain ordered by port address.
+ *
+ * The table is used to implement the Microsoft port access rules that
+ * first appeared in Windows XP. Some ports are always illegal, and some
+ * ports are only illegal if the BIOS calls _OSI with a win_xP string or
+ * later (meaning that the BIOS itelf is post-XP.)
+ *
+ * This provides ACPICA with the desired port protections and
+ * Microsoft compatibility.
+ *
+ * Description of port entries:
+ * DMA: DMA controller
+ * PIC0: Programmable Interrupt Controller (8259_a)
+ * PIT1: System Timer 1
+ * PIT2: System Timer 2 failsafe
+ * RTC: Real-time clock
+ * CMOS: Extended CMOS
+ * DMA1: DMA 1 page registers
+ * DMA1L: DMA 1 Ch 0 low page
+ * DMA2: DMA 2 page registers
+ * DMA2L: DMA 2 low page refresh
+ * ARBC: Arbitration control
+ * SETUP: Reserved system board setup
+ * POS: POS channel select
+ * PIC1: Cascaded PIC
+ * IDMA: ISA DMA
+ * ELCR: PIC edge/level registers
+ * PCI: PCI configuration space
+ */
+static const struct acpi_port_info acpi_protected_ports[] = {
+ {"DMA", 0x0000, 0x000F, ACPI_OSI_WIN_XP},
+ {"PIC0", 0x0020, 0x0021, ACPI_ALWAYS_ILLEGAL},
+ {"PIT1", 0x0040, 0x0043, ACPI_OSI_WIN_XP},
+ {"PIT2", 0x0048, 0x004B, ACPI_OSI_WIN_XP},
+ {"RTC", 0x0070, 0x0071, ACPI_OSI_WIN_XP},
+ {"CMOS", 0x0074, 0x0076, ACPI_OSI_WIN_XP},
+ {"DMA1", 0x0081, 0x0083, ACPI_OSI_WIN_XP},
+ {"DMA1L", 0x0087, 0x0087, ACPI_OSI_WIN_XP},
+ {"DMA2", 0x0089, 0x008B, ACPI_OSI_WIN_XP},
+ {"DMA2L", 0x008F, 0x008F, ACPI_OSI_WIN_XP},
+ {"ARBC", 0x0090, 0x0091, ACPI_OSI_WIN_XP},
+ {"SETUP", 0x0093, 0x0094, ACPI_OSI_WIN_XP},
+ {"POS", 0x0096, 0x0097, ACPI_OSI_WIN_XP},
+ {"PIC1", 0x00A0, 0x00A1, ACPI_ALWAYS_ILLEGAL},
+ {"IDMA", 0x00C0, 0x00DF, ACPI_OSI_WIN_XP},
+ {"ELCR", 0x04D0, 0x04D1, ACPI_ALWAYS_ILLEGAL},
+ {"PCI", 0x0CF8, 0x0CFF, ACPI_OSI_WIN_XP}
+};
+
+#define ACPI_PORT_INFO_ENTRIES ACPI_ARRAY_LENGTH (acpi_protected_ports)
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_validate_io_request
+ *
+ * PARAMETERS: Address Address of I/O port/register
+ * bit_width Number of bits (8,16,32)
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Validates an I/O request (address/length). Certain ports are
+ * always illegal and some ports are only illegal depending on
+ * the requests the BIOS AML code makes to the predefined
+ * _OSI method.
+ *
+ ******************************************************************************/
+
+static acpi_status
+acpi_hw_validate_io_request(acpi_io_address address, u32 bit_width)
+{
+ u32 i;
+ u32 byte_width;
+ acpi_io_address last_address;
+ const struct acpi_port_info *port_info;
+
+ ACPI_FUNCTION_TRACE(hw_validate_io_request);
+
+ /* Supported widths are 8/16/32 */
+
+ if ((bit_width != 8) && (bit_width != 16) && (bit_width != 32)) {
+ return AE_BAD_PARAMETER;
+ }
+
+ port_info = acpi_protected_ports;
+ byte_width = ACPI_DIV_8(bit_width);
+ last_address = address + byte_width - 1;
+
+ ACPI_DEBUG_PRINT((ACPI_DB_IO, "Address %p LastAddress %p Length %X",
+ ACPI_CAST_PTR(void, address), ACPI_CAST_PTR(void,
+ last_address),
+ byte_width));
+
+ /* Maximum 16-bit address in I/O space */
+
+ if (last_address > ACPI_UINT16_MAX) {
+ ACPI_ERROR((AE_INFO,
+ "Illegal I/O port address/length above 64K: 0x%p/%X",
+ ACPI_CAST_PTR(void, address), byte_width));
+ return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+ }
+
+ /* Exit if requested address is not within the protected port table */
+
+ if (address > acpi_protected_ports[ACPI_PORT_INFO_ENTRIES - 1].end) {
+ return_ACPI_STATUS(AE_OK);
+ }
+
+ /* Check request against the list of protected I/O ports */
+
+ for (i = 0; i < ACPI_PORT_INFO_ENTRIES; i++, port_info++) {
+ /*
+ * Check if the requested address range will write to a reserved
+ * port. Four cases to consider:
+ *
+ * 1) Address range is contained completely in the port address range
+ * 2) Address range overlaps port range at the port range start
+ * 3) Address range overlaps port range at the port range end
+ * 4) Address range completely encompasses the port range
+ */
+ if ((address <= port_info->end)
+ && (last_address >= port_info->start)) {
+
+ /* Port illegality may depend on the _OSI calls made by the BIOS */
+
+ if (acpi_gbl_osi_data >= port_info->osi_dependency) {
+ ACPI_ERROR((AE_INFO,
+ "Denied AML access to port 0x%p/%X (%s 0x%.4X-0x%.4X)",
+ ACPI_CAST_PTR(void, address),
+ byte_width, port_info->name,
+ port_info->start, port_info->end));
+
+ return_ACPI_STATUS(AE_AML_ILLEGAL_ADDRESS);
+ }
+ }
+
+ /* Finished if address range ends before the end of this port */
+
+ if (last_address <= port_info->end) {
+ break;
+ }
+ }
+
+ return_ACPI_STATUS(AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_read_port
+ *
+ * PARAMETERS: Address Address of I/O port/register to read
+ * Value Where value is placed
+ * Width Number of bits
+ *
+ * RETURN: Value read from port
+ *
+ * DESCRIPTION: Read data from an I/O port or register. This is a front-end
+ * to acpi_os_read_port that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width)
+{
+ acpi_status status;
+
+ status = acpi_hw_validate_io_request(address, width);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_read_port(address, value, width);
+ return status;
+}
+
+/******************************************************************************
+ *
+ * FUNCTION: acpi_hw_write_port
+ *
+ * PARAMETERS: Address Address of I/O port/register to write
+ * Value Value to write
+ * Width Number of bits
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Write data to an I/O port or register. This is a front-end
+ * to acpi_os_write_port that performs validation on both the port
+ * address and the length.
+ *
+ *****************************************************************************/
+
+acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
+{
+ acpi_status status;
+
+ status = acpi_hw_validate_io_request(address, width);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_write_port(address, value, width);
+ return status;
+}
diff --git a/drivers/acpi/acpica/hwxface.c b/drivers/acpi/acpica/hwxface.c
index ae597c0ab53..9829979f2bd 100644
--- a/drivers/acpi/acpica/hwxface.c
+++ b/drivers/acpi/acpica/hwxface.c
@@ -107,19 +107,18 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
ACPI_FUNCTION_NAME(acpi_read);
/*
- * Must have a valid pointer to a GAS structure, and
- * a non-zero address within. However, don't return an error
- * because the PM1A/B code must not fail if B isn't present.
+ * Must have a valid pointer to a GAS structure, and a non-zero address
+ * within.
*/
if (!reg) {
- return (AE_OK);
+ return (AE_BAD_PARAMETER);
}
/* Get a local copy of the address. Handles possible alignment issues */
ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
- return (AE_OK);
+ return (AE_BAD_ADDRESS);
}
/* Supported widths are 8/16/32 */
@@ -134,8 +133,8 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
*value = 0;
/*
- * Two address spaces supported: Memory or IO.
- * PCI_Config is not supported here because the GAS struct is insufficient
+ * Two address spaces supported: Memory or IO. PCI_Config is
+ * not supported here because the GAS structure is insufficient
*/
switch (reg->space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
@@ -147,7 +146,7 @@ acpi_status acpi_read(u32 *value, struct acpi_generic_address *reg)
case ACPI_ADR_SPACE_SYSTEM_IO:
status =
- acpi_os_read_port((acpi_io_address) address, value, width);
+ acpi_hw_read_port((acpi_io_address) address, value, width);
break;
default:
@@ -187,19 +186,18 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg)
ACPI_FUNCTION_NAME(acpi_write);
/*
- * Must have a valid pointer to a GAS structure, and
- * a non-zero address within. However, don't return an error
- * because the PM1A/B code must not fail if B isn't present.
+ * Must have a valid pointer to a GAS structure, and a non-zero address
+ * within.
*/
if (!reg) {
- return (AE_OK);
+ return (AE_BAD_PARAMETER);
}
/* Get a local copy of the address. Handles possible alignment issues */
ACPI_MOVE_64_TO_64(&address, &reg->address);
if (!address) {
- return (AE_OK);
+ return (AE_BAD_ADDRESS);
}
/* Supported widths are 8/16/32 */
@@ -222,7 +220,7 @@ acpi_status acpi_write(u32 value, struct acpi_generic_address *reg)
case ACPI_ADR_SPACE_SYSTEM_IO:
- status = acpi_os_write_port((acpi_io_address) address, value,
+ status = acpi_hw_write_port((acpi_io_address) address, value,
width);
break;
@@ -244,24 +242,36 @@ ACPI_EXPORT_SYMBOL(acpi_write)
/*******************************************************************************
*
- * FUNCTION: acpi_get_register_unlocked
+ * FUNCTION: acpi_read_bit_register
*
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * return_value - Value that was read from the register
+ * PARAMETERS: register_id - ID of ACPI Bit Register to access
+ * return_value - Value that was read from the register,
+ * normalized to bit position zero.
*
- * RETURN: Status and the value read from specified Register. Value
+ * RETURN: Status and the value read from the specified Register. Value
* returned is normalized to bit0 (is shifted all the way right)
*
* DESCRIPTION: ACPI bit_register read function. Does not acquire the HW lock.
*
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note: The hardware lock is not required when reading the ACPI bit registers
+ * since almost all of them are single bit and it does not matter that
+ * the parent hardware register can be split across two physical
+ * registers. The only multi-bit field is SLP_TYP in the PM1 control
+ * register, but this field does not cross an 8-bit boundary (nor does
+ * it make much sense to actually read this field.)
+ *
******************************************************************************/
-acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
+acpi_status acpi_read_bit_register(u32 register_id, u32 *return_value)
{
- u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
+ u32 register_value;
+ u32 value;
acpi_status status;
- ACPI_FUNCTION_TRACE(acpi_get_register_unlocked);
+ ACPI_FUNCTION_TRACE_U32(acpi_read_bit_register, register_id);
/* Get the info structure corresponding to the requested ACPI Register */
@@ -270,209 +280,133 @@ acpi_status acpi_get_register_unlocked(u32 register_id, u32 *return_value)
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /* Read from the register */
+ /* Read the entire parent register */
status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
-
- if (ACPI_SUCCESS(status)) {
-
- /* Normalize the value that was read */
-
- register_value =
- ((register_value & bit_reg_info->access_bit_mask)
- >> bit_reg_info->bit_position);
-
- *return_value = register_value;
-
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "Read value %8.8X register %X\n",
- register_value,
- bit_reg_info->parent_register));
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
}
- return_ACPI_STATUS(status);
-}
+ /* Normalize the value that was read, mask off other bits */
-ACPI_EXPORT_SYMBOL(acpi_get_register_unlocked)
+ value = ((register_value & bit_reg_info->access_bit_mask)
+ >> bit_reg_info->bit_position);
-/*******************************************************************************
- *
- * FUNCTION: acpi_get_register
- *
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * return_value - Value that was read from the register
- *
- * RETURN: Status and the value read from specified Register. Value
- * returned is normalized to bit0 (is shifted all the way right)
- *
- * DESCRIPTION: ACPI bit_register read function.
- *
- ******************************************************************************/
-acpi_status acpi_get_register(u32 register_id, u32 *return_value)
-{
- acpi_status status;
- acpi_cpu_flags flags;
-
- flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- status = acpi_get_register_unlocked(register_id, return_value);
- acpi_os_release_lock(acpi_gbl_hardware_lock, flags);
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Actual %8.8X, ReturnValue %8.8X\n",
+ register_id, bit_reg_info->parent_register,
+ register_value, value));
- return (status);
+ *return_value = value;
+ return_ACPI_STATUS(AE_OK);
}
-ACPI_EXPORT_SYMBOL(acpi_get_register)
+ACPI_EXPORT_SYMBOL(acpi_read_bit_register)
/*******************************************************************************
*
- * FUNCTION: acpi_set_register
+ * FUNCTION: acpi_write_bit_register
*
- * PARAMETERS: register_id - ID of ACPI bit_register to access
- * Value - (only used on write) value to write to the
- * Register, NOT pre-normalized to the bit pos
+ * PARAMETERS: register_id - ID of ACPI Bit Register to access
+ * Value - Value to write to the register, in bit
+ * position zero. The bit is automaticallly
+ * shifted to the correct position.
*
* RETURN: Status
*
- * DESCRIPTION: ACPI Bit Register write function.
+ * DESCRIPTION: ACPI Bit Register write function. Acquires the hardware lock
+ * since most operations require a read/modify/write sequence.
+ *
+ * SUPPORTS: Bit fields in PM1 Status, PM1 Enable, PM1 Control, and
+ * PM2 Control.
+ *
+ * Note that at this level, the fact that there may be actually two
+ * hardware registers (A and B - and B may not exist) is abstracted.
*
******************************************************************************/
-acpi_status acpi_set_register(u32 register_id, u32 value)
+acpi_status acpi_write_bit_register(u32 register_id, u32 value)
{
- u32 register_value = 0;
struct acpi_bit_register_info *bit_reg_info;
- acpi_status status;
acpi_cpu_flags lock_flags;
+ u32 register_value;
+ acpi_status status = AE_OK;
- ACPI_FUNCTION_TRACE_U32(acpi_set_register, register_id);
+ ACPI_FUNCTION_TRACE_U32(acpi_write_bit_register, register_id);
/* Get the info structure corresponding to the requested ACPI Register */
bit_reg_info = acpi_hw_get_bit_register_info(register_id);
if (!bit_reg_info) {
- ACPI_ERROR((AE_INFO, "Bad ACPI HW RegisterId: %X",
- register_id));
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
lock_flags = acpi_os_acquire_lock(acpi_gbl_hardware_lock);
- /* Always do a register read first so we can insert the new bits */
-
- status = acpi_hw_register_read(bit_reg_info->parent_register,
- &register_value);
- if (ACPI_FAILURE(status)) {
- goto unlock_and_exit;
- }
-
/*
- * Decode the Register ID
- * Register ID = [Register block ID] | [bit ID]
- *
- * Check bit ID to fine locate Register offset.
- * Check Mask to determine Register offset, and then read-write.
+ * At this point, we know that the parent register is one of the
+ * following: PM1 Status, PM1 Enable, PM1 Control, or PM2 Control
*/
- switch (bit_reg_info->parent_register) {
- case ACPI_REGISTER_PM1_STATUS:
-
+ if (bit_reg_info->parent_register != ACPI_REGISTER_PM1_STATUS) {
/*
- * Status Registers are different from the rest. Clear by
- * writing 1, and writing 0 has no effect. So, the only relevant
- * information is the single bit we're interested in, all others should
- * be written as 0 so they will be left unchanged.
+ * 1) Case for PM1 Enable, PM1 Control, and PM2 Control
+ *
+ * Perform a register read to preserve the bits that we are not
+ * interested in
*/
- value = ACPI_REGISTER_PREPARE_BITS(value,
- bit_reg_info->bit_position,
- bit_reg_info->
- access_bit_mask);
- if (value) {
- status =
- acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
- (u16) value);
- register_value = 0;
- }
- break;
-
- case ACPI_REGISTER_PM1_ENABLE:
-
- ACPI_REGISTER_INSERT_VALUE(register_value,
- bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask,
- value);
-
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_ENABLE,
- (u16) register_value);
- break;
-
- case ACPI_REGISTER_PM1_CONTROL:
-
- /*
- * Write the PM1 Control register.
- * Note that at this level, the fact that there are actually TWO
- * registers (A and B - and B may not exist) is abstracted.
- */
- ACPI_DEBUG_PRINT((ACPI_DB_IO, "PM1 control: Read %X\n",
- register_value));
-
- ACPI_REGISTER_INSERT_VALUE(register_value,
- bit_reg_info->bit_position,
- bit_reg_info->access_bit_mask,
- value);
-
- status = acpi_hw_register_write(ACPI_REGISTER_PM1_CONTROL,
- (u16) register_value);
- break;
-
- case ACPI_REGISTER_PM2_CONTROL:
-
- status = acpi_hw_register_read(ACPI_REGISTER_PM2_CONTROL,
+ status = acpi_hw_register_read(bit_reg_info->parent_register,
&register_value);
if (ACPI_FAILURE(status)) {
goto unlock_and_exit;
}
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "PM2 control: Read %X from %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64(acpi_gbl_FADT.
- xpm2_control_block.
- address)));
-
+ /*
+ * Insert the input bit into the value that was just read
+ * and write the register
+ */
ACPI_REGISTER_INSERT_VALUE(register_value,
bit_reg_info->bit_position,
bit_reg_info->access_bit_mask,
value);
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "About to write %4.4X to %8.8X%8.8X\n",
- register_value,
- ACPI_FORMAT_UINT64(acpi_gbl_FADT.
- xpm2_control_block.
- address)));
+ status = acpi_hw_register_write(bit_reg_info->parent_register,
+ register_value);
+ } else {
+ /*
+ * 2) Case for PM1 Status
+ *
+ * The Status register is different from the rest. Clear an event
+ * by writing 1, writing 0 has no effect. So, the only relevant
+ * information is the single bit we're interested in, all others
+ * should be written as 0 so they will be left unchanged.
+ */
+ register_value = ACPI_REGISTER_PREPARE_BITS(value,
+ bit_reg_info->
+ bit_position,
+ bit_reg_info->
+ access_bit_mask);
- status = acpi_hw_register_write(ACPI_REGISTER_PM2_CONTROL,
- (u8) (register_value));
- break;
+ /* No need to write the register if value is all zeros */
- default:
- break;
+ if (register_value) {
+ status =
+ acpi_hw_register_write(ACPI_REGISTER_PM1_STATUS,
+ register_value);
+ }
}
- unlock_and_exit:
-
- acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
-
- /* Normalize the value that was read */
+ ACPI_DEBUG_PRINT((ACPI_DB_IO,
+ "BitReg %X, ParentReg %X, Value %8.8X, Actual %8.8X\n",
+ register_id, bit_reg_info->parent_register, value,
+ register_value));
- ACPI_DEBUG_EXEC(register_value =
- ((register_value & bit_reg_info->access_bit_mask) >>
- bit_reg_info->bit_position));
+unlock_and_exit:
- ACPI_DEBUG_PRINT((ACPI_DB_IO,
- "Set bits: %8.8X actual %8.8X register %X\n", value,
- register_value, bit_reg_info->parent_register));
+ acpi_os_release_lock(acpi_gbl_hardware_lock, lock_flags);
return_ACPI_STATUS(status);
}
-ACPI_EXPORT_SYMBOL(acpi_set_register)
+ACPI_EXPORT_SYMBOL(acpi_write_bit_register)
/*******************************************************************************
*
@@ -534,7 +468,7 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
/* It must be of type Package */
- else if (ACPI_GET_OBJECT_TYPE(info->return_object) != ACPI_TYPE_PACKAGE) {
+ else if (info->return_object->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO,
"Sleep State return object is not a Package"));
status = AE_AML_OPERAND_TYPE;
@@ -555,12 +489,13 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 *sleep_type_a, u8 *sleep_type_b)
/* The first two elements must both be of type Integer */
- else if ((ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[0])
+ else if (((info->return_object->package.elements[0])->common.type
!= ACPI_TYPE_INTEGER) ||
- (ACPI_GET_OBJECT_TYPE(info->return_object->package.elements[1])
+ ((info->return_object->package.elements[1])->common.type
!= ACPI_TYPE_INTEGER)) {
ACPI_ERROR((AE_INFO,
- "Sleep State return package elements are not both Integers (%s, %s)",
+ "Sleep State return package elements are not both Integers "
+ "(%s, %s)",
acpi_ut_get_object_type_name(info->return_object->
package.elements[0]),
acpi_ut_get_object_type_name(info->return_object->
diff --git a/drivers/acpi/acpica/nsaccess.c b/drivers/acpi/acpica/nsaccess.c
index 88303ebe924..9c3cdbe2d82 100644
--- a/drivers/acpi/acpica/nsaccess.c
+++ b/drivers/acpi/acpica/nsaccess.c
@@ -118,9 +118,8 @@ acpi_status acpi_ns_root_initialize(void)
}
/*
- * Name entered successfully.
- * If entry in pre_defined_names[] specifies an
- * initial value, create the initial value.
+ * Name entered successfully. If entry in pre_defined_names[] specifies
+ * an initial value, create the initial value.
*/
if (init_val->val) {
status = acpi_os_predefined_override(init_val, &val);
@@ -178,9 +177,8 @@ acpi_status acpi_ns_root_initialize(void)
case ACPI_TYPE_STRING:
- /*
- * Build an object around the static string
- */
+ /* Build an object around the static string */
+
obj_desc->string.length =
(u32) ACPI_STRLEN(val);
obj_desc->string.pointer = val;
@@ -234,8 +232,7 @@ acpi_status acpi_ns_root_initialize(void)
/* Store pointer to value descriptor in the Node */
status = acpi_ns_attach_object(new_node, obj_desc,
- ACPI_GET_OBJECT_TYPE
- (obj_desc));
+ obj_desc->common.type);
/* Remove local reference to the object */
@@ -315,10 +312,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
return_ACPI_STATUS(AE_NO_NAMESPACE);
}
- /*
- * Get the prefix scope.
- * A null scope means use the root scope
- */
+ /* Get the prefix scope. A null scope means use the root scope */
+
if ((!scope_info) || (!scope_info->scope.node)) {
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
"Null scope prefix, using root node (%p)\n",
@@ -338,8 +333,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
if (!(flags & ACPI_NS_PREFIX_IS_SCOPE)) {
/*
* This node might not be a actual "scope" node (such as a
- * Device/Method, etc.) It could be a Package or other object node.
- * Backup up the tree to find the containing scope node.
+ * Device/Method, etc.) It could be a Package or other object
+ * node. Backup up the tree to find the containing scope node.
*/
while (!acpi_ns_opens_scope(prefix_node->type) &&
prefix_node->type != ACPI_TYPE_ANY) {
@@ -349,7 +344,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
}
}
- /* Save type TBD: may be no longer necessary */
+ /* Save type. TBD: may be no longer necessary */
type_to_check_for = type;
@@ -414,6 +409,7 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Name is fully qualified, no search rules apply */
search_parent_flag = ACPI_NS_NO_UPSEARCH;
+
/*
* Point past this prefix to the name segment
* part or the next Parent Prefix
@@ -429,7 +425,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/* Current scope has no parent scope */
ACPI_ERROR((AE_INFO,
- "ACPI path has too many parent prefixes (^) - reached beyond root node"));
+ "ACPI path has too many parent prefixes (^) "
+ "- reached beyond root node"));
return_ACPI_STATUS(AE_NOT_FOUND);
}
}
@@ -531,9 +528,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
while (num_segments && current_node) {
num_segments--;
if (!num_segments) {
- /*
- * This is the last segment, enable typechecking
- */
+
+ /* This is the last segment, enable typechecking */
+
this_search_type = type;
/*
@@ -584,9 +581,9 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
if (num_segments > 0) {
/*
* If we have an alias to an object that opens a scope (such as a
- * device or processor), we need to dereference the alias here so that
- * we can access any children of the original node (via the remaining
- * segments).
+ * device or processor), we need to dereference the alias here so
+ * that we can access any children of the original node (via the
+ * remaining segments).
*/
if (this_node->type == ACPI_TYPE_LOCAL_ALIAS) {
if (!this_node->object) {
@@ -594,8 +591,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
}
if (acpi_ns_opens_scope
- (((struct acpi_namespace_node *)this_node->
- object)->type)) {
+ (((struct acpi_namespace_node *)
+ this_node->object)->type)) {
this_node =
(struct acpi_namespace_node *)
this_node->object;
@@ -639,8 +636,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
/*
* If this is the last name segment and we are not looking for a
- * specific type, but the type of found object is known, use that type
- * to (later) see if it opens a scope.
+ * specific type, but the type of found object is known, use that
+ * type to (later) see if it opens a scope.
*/
if (type == ACPI_TYPE_ANY) {
type = this_node->type;
@@ -653,9 +650,8 @@ acpi_ns_lookup(union acpi_generic_state *scope_info,
current_node = this_node;
}
- /*
- * Always check if we need to open a new scope
- */
+ /* Always check if we need to open a new scope */
+
if (!(flags & ACPI_NS_DONT_OPEN_SCOPE) && (walk_state)) {
/*
* If entry is a type which opens a scope, push the new scope on the
diff --git a/drivers/acpi/acpica/nsalloc.c b/drivers/acpi/acpica/nsalloc.c
index f976d848fe8..aceb9311196 100644
--- a/drivers/acpi/acpica/nsalloc.c
+++ b/drivers/acpi/acpica/nsalloc.c
@@ -76,8 +76,7 @@ struct acpi_namespace_node *acpi_ns_create_node(u32 name)
ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_allocated++);
#ifdef ACPI_DBG_TRACK_ALLOCATIONS
- temp =
- acpi_gbl_ns_node_list->total_allocated -
+ temp = acpi_gbl_ns_node_list->total_allocated -
acpi_gbl_ns_node_list->total_freed;
if (temp > acpi_gbl_ns_node_list->max_occupied) {
acpi_gbl_ns_node_list->max_occupied = temp;
@@ -145,9 +144,8 @@ void acpi_ns_delete_node(struct acpi_namespace_node *node)
ACPI_MEM_TRACKING(acpi_gbl_ns_node_list->total_freed++);
- /*
- * Detach an object if there is one, then delete the node
- */
+ /* Detach an object if there is one, then delete the node */
+
acpi_ns_detach_object(node);
(void)acpi_os_release_object(acpi_gbl_namespace_cache, node);
return_VOID;
@@ -183,9 +181,8 @@ void acpi_ns_install_node(struct acpi_walk_state *walk_state, struct acpi_namesp
ACPI_FUNCTION_TRACE(ns_install_node);
/*
- * Get the owner ID from the Walk state
- * The owner ID is used to track table deletion and
- * deletion of objects created by methods
+ * Get the owner ID from the Walk state. The owner ID is used to track
+ * table deletion and deletion of objects created by methods.
*/
if (walk_state) {
owner_id = walk_state->owner_id;
@@ -260,9 +257,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
return_VOID;
}
- /*
- * Deallocate all children at this level
- */
+ /* Deallocate all children at this level */
+
do {
/* Get the things we need */
@@ -285,9 +281,8 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
"Object %p, Remaining %X\n", child_node,
acpi_gbl_current_node_count));
- /*
- * Detach an object if there is one, then free the child node
- */
+ /* Detach an object if there is one, then free the child node */
+
acpi_ns_detach_object(child_node);
/* Now we can delete the node */
@@ -304,7 +299,6 @@ void acpi_ns_delete_children(struct acpi_namespace_node *parent_node)
/* Clear the parent's child pointer */
parent_node->child = NULL;
-
return_VOID;
}
diff --git a/drivers/acpi/acpica/nsdump.c b/drivers/acpi/acpica/nsdump.c
index 0da33c8e9ba..2bad613db73 100644
--- a/drivers/acpi/acpica/nsdump.c
+++ b/drivers/acpi/acpica/nsdump.c
@@ -181,6 +181,12 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
}
this_node = acpi_ns_map_handle_to_node(obj_handle);
+ if (!this_node) {
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Invalid object handle %p\n",
+ obj_handle));
+ return (AE_OK);
+ }
+
type = this_node->type;
/* Check if the owner matches */
@@ -214,9 +220,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
acpi_os_printf("%4.4s", acpi_ut_get_node_name(this_node));
}
- /*
- * Now we can print out the pertinent information
- */
+ /* Now we can print out the pertinent information */
+
acpi_os_printf(" %-12s %p %2.2X ",
acpi_ut_get_type_name(type), this_node,
this_node->owner_id);
@@ -509,7 +514,7 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
case ACPI_DESC_TYPE_OPERAND:
- obj_type = ACPI_GET_OBJECT_TYPE(obj_desc);
+ obj_type = obj_desc->common.type;
if (obj_type > ACPI_TYPE_LOCAL_MAX) {
acpi_os_printf
@@ -539,9 +544,8 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
goto cleanup;
}
- /*
- * Valid object, get the pointer to next level, if any
- */
+ /* Valid object, get the pointer to next level, if any */
+
switch (obj_type) {
case ACPI_TYPE_BUFFER:
case ACPI_TYPE_STRING:
@@ -602,14 +606,14 @@ acpi_ns_dump_one_object(acpi_handle obj_handle,
* display_type - 0 or ACPI_DISPLAY_SUMMARY
* max_depth - Maximum depth of dump. Use ACPI_UINT32_MAX
* for an effectively unlimited depth.
- * owner_id - Dump only objects owned by this ID. Use
+ * owner_id - Dump only objects owned by this ID. Use
* ACPI_UINT32_MAX to match all owners.
* start_handle - Where in namespace to start/end search
*
* RETURN: None
*
- * DESCRIPTION: Dump typed objects within the loaded namespace.
- * Uses acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
+ * DESCRIPTION: Dump typed objects within the loaded namespace. Uses
+ * acpi_ns_walk_namespace in conjunction with acpi_ns_dump_one_object.
*
******************************************************************************/
diff --git a/drivers/acpi/acpica/nseval.c b/drivers/acpi/acpica/nseval.c
index 0f3d5f9b596..8e7dec1176c 100644
--- a/drivers/acpi/acpica/nseval.c
+++ b/drivers/acpi/acpica/nseval.c
@@ -155,7 +155,7 @@ acpi_status acpi_ns_evaluate(struct acpi_evaluate_info * info)
}
- ACPI_DUMP_PATHNAME(info->resolved_node, "Execute Method:",
+ ACPI_DUMP_PATHNAME(info->resolved_node, "ACPI: Execute Method",
ACPI_LV_INFO, _COMPONENT);
ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
diff --git a/drivers/acpi/acpica/nsinit.c b/drivers/acpi/acpica/nsinit.c
index 13501cb8186..2adfcf329e1 100644
--- a/drivers/acpi/acpica/nsinit.c
+++ b/drivers/acpi/acpica/nsinit.c
@@ -103,7 +103,8 @@ acpi_status acpi_ns_initialize_objects(void)
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd Buffers %hd/%hd Packages (%hd nodes)\n",
+ "\nInitialized %hd/%hd Regions %hd/%hd Fields %hd/%hd "
+ "Buffers %hd/%hd Packages (%hd nodes)\n",
info.op_region_init, info.op_region_count,
info.field_init, info.field_count,
info.buffer_init, info.buffer_count,
@@ -148,7 +149,8 @@ acpi_status acpi_ns_initialize_devices(void)
info.num_INI = 0;
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "Initializing Device/Processor/Thermal objects by executing _INI methods:"));
+ "Initializing Device/Processor/Thermal objects "
+ "by executing _INI methods:"));
/* Tree analysis: find all subtrees that contain _INI methods */
@@ -180,7 +182,8 @@ acpi_status acpi_ns_initialize_devices(void)
}
ACPI_DEBUG_PRINT_RAW((ACPI_DB_INIT,
- "\nExecuted %hd _INI methods requiring %hd _STA executions (examined %hd objects)\n",
+ "\nExecuted %hd _INI methods requiring %hd _STA executions "
+ "(examined %hd objects)\n",
info.num_INI, info.num_STA, info.device_count));
return_ACPI_STATUS(status);
@@ -263,16 +266,14 @@ acpi_ns_init_one_object(acpi_handle obj_handle,
return (AE_OK);
}
- /*
- * If the object is already initialized, nothing else to do
- */
+ /* If the object is already initialized, nothing else to do */
+
if (obj_desc->common.flags & AOPOBJ_DATA_VALID) {
return (AE_OK);
}
- /*
- * Must lock the interpreter before executing AML code
- */
+ /* Must lock the interpreter before executing AML code */
+
acpi_ex_enter_interpreter();
/*
diff --git a/drivers/acpi/acpica/nsload.c b/drivers/acpi/acpica/nsload.c
index a0ba9e12379..dcd7a6adbbb 100644
--- a/drivers/acpi/acpica/nsload.c
+++ b/drivers/acpi/acpica/nsload.c
@@ -128,12 +128,12 @@ acpi_ns_load_table(u32 table_index, struct acpi_namespace_node *node)
* parse trees.
*/
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "**** Begin Table Method Parsing and Object Initialization ****\n"));
+ "**** Begin Table Method Parsing and Object Initialization\n"));
status = acpi_ds_initialize_objects(table_index, node);
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "**** Completed Table Method Parsing and Object Initialization ****\n"));
+ "**** Completed Table Method Parsing and Object Initialization\n"));
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/nsobject.c b/drivers/acpi/acpica/nsobject.c
index 08a97a57f8f..3eb20bfda9d 100644
--- a/drivers/acpi/acpica/nsobject.c
+++ b/drivers/acpi/acpica/nsobject.c
@@ -209,8 +209,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
obj_desc = node->object;
- if (!obj_desc ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA)) {
+ if (!obj_desc || (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA)) {
return_VOID;
}
@@ -220,8 +219,7 @@ void acpi_ns_detach_object(struct acpi_namespace_node *node)
if (ACPI_GET_DESCRIPTOR_TYPE(obj_desc) == ACPI_DESC_TYPE_OPERAND) {
node->object = obj_desc->common.next_object;
if (node->object &&
- (ACPI_GET_OBJECT_TYPE(node->object) !=
- ACPI_TYPE_LOCAL_DATA)) {
+ ((node->object)->common.type != ACPI_TYPE_LOCAL_DATA)) {
node->object = node->object->common.next_object;
}
}
@@ -267,7 +265,7 @@ union acpi_operand_object *acpi_ns_get_attached_object(struct
((ACPI_GET_DESCRIPTOR_TYPE(node->object) != ACPI_DESC_TYPE_OPERAND)
&& (ACPI_GET_DESCRIPTOR_TYPE(node->object) !=
ACPI_DESC_TYPE_NAMED))
- || (ACPI_GET_OBJECT_TYPE(node->object) == ACPI_TYPE_LOCAL_DATA)) {
+ || ((node->object)->common.type == ACPI_TYPE_LOCAL_DATA)) {
return_PTR(NULL);
}
@@ -294,9 +292,9 @@ union acpi_operand_object *acpi_ns_get_secondary_object(union
ACPI_FUNCTION_TRACE_PTR(ns_get_secondary_object, obj_desc);
if ((!obj_desc) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) ||
+ (obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) ||
(!obj_desc->common.next_object) ||
- (ACPI_GET_OBJECT_TYPE(obj_desc->common.next_object) ==
+ ((obj_desc->common.next_object)->common.type ==
ACPI_TYPE_LOCAL_DATA)) {
return_PTR(NULL);
}
@@ -331,7 +329,7 @@ acpi_ns_attach_data(struct acpi_namespace_node *node,
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
return (AE_ALREADY_EXISTS);
}
@@ -385,7 +383,7 @@ acpi_ns_detach_data(struct acpi_namespace_node * node,
prev_obj_desc = NULL;
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
if (prev_obj_desc) {
prev_obj_desc->common.next_object =
@@ -428,7 +426,7 @@ acpi_ns_get_attached_data(struct acpi_namespace_node * node,
obj_desc = node->object;
while (obj_desc) {
- if ((ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_LOCAL_DATA) &&
+ if ((obj_desc->common.type == ACPI_TYPE_LOCAL_DATA) &&
(obj_desc->data.handler == handler)) {
*data = obj_desc->data.pointer;
return (AE_OK);
diff --git a/drivers/acpi/acpica/nsparse.c b/drivers/acpi/acpica/nsparse.c
index b9e8d0070b6..662a4bd5b62 100644
--- a/drivers/acpi/acpica/nsparse.c
+++ b/drivers/acpi/acpica/nsparse.c
@@ -176,9 +176,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
* performs another complete parse of the AML.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 1\n"));
- status =
- acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1, table_index,
- start_node);
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS1,
+ table_index, start_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
@@ -193,9 +192,8 @@ acpi_ns_parse_table(u32 table_index, struct acpi_namespace_node *start_node)
* parse objects are all cached.
*/
ACPI_DEBUG_PRINT((ACPI_DB_PARSE, "**** Start pass 2\n"));
- status =
- acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2, table_index,
- start_node);
+ status = acpi_ns_one_complete_parse(ACPI_IMODE_LOAD_PASS2,
+ table_index, start_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c
index 452703290d3..d9e8cbc6e67 100644
--- a/drivers/acpi/acpica/nspredef.c
+++ b/drivers/acpi/acpica/nspredef.c
@@ -79,7 +79,9 @@ acpi_ns_check_package(char *pathname,
static acpi_status
acpi_ns_check_package_elements(char *pathname,
union acpi_operand_object **elements,
- u8 type1, u32 count1, u8 type2, u32 count2);
+ u8 type1,
+ u32 count1,
+ u8 type2, u32 count2, u32 start_index);
static acpi_status
acpi_ns_check_object_type(char *pathname,
@@ -221,7 +223,7 @@ acpi_ns_check_predefined_names(struct acpi_namespace_node *node,
/* For returned Package objects, check the type of all sub-objects */
- if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_PACKAGE) {
+ if (return_object->common.type == ACPI_TYPE_PACKAGE) {
status =
acpi_ns_check_package(pathname, return_object_ptr,
predefined);
@@ -302,7 +304,8 @@ acpi_ns_check_parameter_count(char *pathname,
if ((user_param_count != required_params_current) &&
(user_param_count != required_params_old)) {
ACPI_WARNING((AE_INFO,
- "%s: Parameter count mismatch - caller passed %d, ACPI requires %d",
+ "%s: Parameter count mismatch - "
+ "caller passed %d, ACPI requires %d",
pathname, user_param_count,
required_params_current));
}
@@ -472,7 +475,7 @@ acpi_ns_check_package(char *pathname,
package->ret_info.
object_type2,
package->ret_info.
- count2);
+ count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -623,7 +626,7 @@ acpi_ns_check_package(char *pathname,
object_type2,
package->
ret_info.
- count2);
+ count2, 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -672,7 +675,8 @@ acpi_ns_check_package(char *pathname,
object_type1,
sub_package->
package.
- count, 0, 0);
+ count, 0, 0,
+ 0);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -710,7 +714,8 @@ acpi_ns_check_package(char *pathname,
ret_info.
object_type1,
(expected_count
- - 1), 0, 0);
+ - 1), 0, 0,
+ 1);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -758,6 +763,7 @@ acpi_ns_check_package(char *pathname,
* Count1 - Count for first group
* Type2 - Object type for second group
* Count2 - Count for second group
+ * start_index - Start of the first group of elements
*
* RETURN: Status
*
@@ -769,7 +775,9 @@ acpi_ns_check_package(char *pathname,
static acpi_status
acpi_ns_check_package_elements(char *pathname,
union acpi_operand_object **elements,
- u8 type1, u32 count1, u8 type2, u32 count2)
+ u8 type1,
+ u32 count1,
+ u8 type2, u32 count2, u32 start_index)
{
union acpi_operand_object **this_element = elements;
acpi_status status;
@@ -782,7 +790,7 @@ acpi_ns_check_package_elements(char *pathname,
*/
for (i = 0; i < count1; i++) {
status = acpi_ns_check_object_type(pathname, this_element,
- type1, i);
+ type1, i + start_index);
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -791,7 +799,8 @@ acpi_ns_check_package_elements(char *pathname,
for (i = 0; i < count2; i++) {
status = acpi_ns_check_object_type(pathname, this_element,
- type2, (i + count1));
+ type2,
+ (i + count1 + start_index));
if (ACPI_FAILURE(status)) {
return (status);
}
@@ -858,7 +867,7 @@ acpi_ns_check_object_type(char *pathname,
* from all of the predefined names (including elements of returned
* packages)
*/
- switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+ switch (return_object->common.type) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_RTYPE_INTEGER;
break;
@@ -901,7 +910,7 @@ acpi_ns_check_object_type(char *pathname,
/* For reference objects, check that the reference type is correct */
- if (ACPI_GET_OBJECT_TYPE(return_object) == ACPI_TYPE_LOCAL_REFERENCE) {
+ if (return_object->common.type == ACPI_TYPE_LOCAL_REFERENCE) {
status = acpi_ns_check_reference(pathname, return_object);
}
@@ -974,7 +983,8 @@ acpi_ns_check_reference(char *pathname,
}
ACPI_WARNING((AE_INFO,
- "%s: Return type mismatch - unexpected reference object type [%s] %2.2X",
+ "%s: Return type mismatch - "
+ "unexpected reference object type [%s] %2.2X",
pathname, acpi_ut_get_reference_name(return_object),
return_object->reference.class));
@@ -1006,7 +1016,7 @@ acpi_ns_repair_object(u32 expected_btypes,
union acpi_operand_object *new_object;
acpi_size length;
- switch (ACPI_GET_OBJECT_TYPE(return_object)) {
+ switch (return_object->common.type) {
case ACPI_TYPE_BUFFER:
if (!(expected_btypes & ACPI_RTYPE_STRING)) {
diff --git a/drivers/acpi/acpica/nssearch.c b/drivers/acpi/acpica/nssearch.c
index 6fea13f3f52..f9b4f51bf8f 100644
--- a/drivers/acpi/acpica/nssearch.c
+++ b/drivers/acpi/acpica/nssearch.c
@@ -167,7 +167,8 @@ acpi_ns_search_one_scope(u32 target_name,
/* Searched entire namespace level, not found */
ACPI_DEBUG_PRINT((ACPI_DB_NAMES,
- "Name [%4.4s] (%s) not found in search in scope [%4.4s] %p first child %p\n",
+ "Name [%4.4s] (%s) not found in search in scope [%4.4s] "
+ "%p first child %p\n",
ACPI_CAST_PTR(char, &target_name),
acpi_ut_get_type_name(type),
acpi_ut_get_node_name(parent_node), parent_node,
@@ -239,9 +240,8 @@ acpi_ns_search_parent_tree(u32 target_name,
acpi_ut_get_node_name(parent_node),
ACPI_CAST_PTR(char, &target_name)));
- /*
- * Search parents until target is found or we have backed up to the root
- */
+ /* Search parents until target is found or we have backed up to the root */
+
while (parent_node) {
/*
* Search parent scope. Use TYPE_ANY because we don't care about the
@@ -395,9 +395,9 @@ acpi_ns_search_and_enter(u32 target_name,
return_ACPI_STATUS(AE_NO_MEMORY);
}
#ifdef ACPI_ASL_COMPILER
- /*
- * Node is an object defined by an External() statement
- */
+
+ /* Node is an object defined by an External() statement */
+
if (flags & ACPI_NS_EXTERNAL) {
new_node->flags |= ANOBJ_IS_EXTERNAL;
}
diff --git a/drivers/acpi/acpica/nsutils.c b/drivers/acpi/acpica/nsutils.c
index 3e1149bf4aa..78277ed0833 100644
--- a/drivers/acpi/acpica/nsutils.c
+++ b/drivers/acpi/acpica/nsutils.c
@@ -325,9 +325,8 @@ void acpi_ns_get_internal_name_length(struct acpi_namestring_info *info)
next_external_char++;
}
} else {
- /*
- * Handle Carat prefixes
- */
+ /* Handle Carat prefixes */
+
while (*next_external_char == '^') {
info->num_carats++;
next_external_char++;
@@ -552,9 +551,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
return_ACPI_STATUS(AE_BAD_PARAMETER);
}
- /*
- * Check for a prefix (one '\' | one or more '^').
- */
+ /* Check for a prefix (one '\' | one or more '^') */
+
switch (internal_name[0]) {
case '\\':
prefix_length = 1;
@@ -580,7 +578,7 @@ acpi_ns_externalize_name(u32 internal_name_length,
}
/*
- * Check for object names. Note that there could be 0-255 of these
+ * Check for object names. Note that there could be 0-255 of these
* 4-byte elements.
*/
if (prefix_length < internal_name_length) {
@@ -637,9 +635,8 @@ acpi_ns_externalize_name(u32 internal_name_length,
return_ACPI_STATUS(AE_BAD_PATHNAME);
}
- /*
- * Build converted_name
- */
+ /* Build the converted_name */
+
*converted_name = ACPI_ALLOCATE_ZEROED(required_length);
if (!(*converted_name)) {
return_ACPI_STATUS(AE_NO_MEMORY);
@@ -685,6 +682,9 @@ acpi_ns_externalize_name(u32 internal_name_length,
* and keep all pointers within this subsystem - however this introduces
* more (and perhaps unnecessary) overhead.
*
+ * The current implemenation is basically a placeholder until such time comes
+ * that it is needed.
+ *
******************************************************************************/
struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
@@ -692,9 +692,8 @@ struct acpi_namespace_node *acpi_ns_map_handle_to_node(acpi_handle handle)
ACPI_FUNCTION_ENTRY();
- /*
- * Simple implementation
- */
+ /* Parameter validation */
+
if ((!handle) || (handle == ACPI_ROOT_OBJECT)) {
return (acpi_gbl_root_node);
}
@@ -872,7 +871,7 @@ acpi_ns_get_node(struct acpi_namespace_node *prefix_node,
(flags | ACPI_NS_DONT_OPEN_SCOPE), NULL,
return_node);
if (ACPI_FAILURE(status)) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s, %s\n",
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "%s, %s\n",
pathname, acpi_format_exception(status)));
}
diff --git a/drivers/acpi/acpica/nswalk.c b/drivers/acpi/acpica/nswalk.c
index 200895fa272..83e3aa6d4b9 100644
--- a/drivers/acpi/acpica/nswalk.c
+++ b/drivers/acpi/acpica/nswalk.c
@@ -135,8 +135,8 @@ struct acpi_namespace_node *acpi_ns_get_next_node(acpi_object_type type, struct
* starting (and ending) at the node specified by start_handle.
* The user_function is called whenever a node that matches
* the type parameter is found. If the user function returns
- * a non-zero value, the search is terminated immediately and this
- * value is returned to the caller.
+ * a non-zero value, the search is terminated immediately and
+ * this value is returned to the caller.
*
* The point of this procedure is to provide a generic namespace
* walk routine that can be called from multiple places to
@@ -200,10 +200,10 @@ acpi_ns_walk_namespace(acpi_object_type type,
/*
* Ignore all temporary namespace nodes (created during control
* method execution) unless told otherwise. These temporary nodes
- * can cause a race condition because they can be deleted during the
- * execution of the user function (if the namespace is unlocked before
- * invocation of the user function.) Only the debugger namespace dump
- * will examine the temporary nodes.
+ * can cause a race condition because they can be deleted during
+ * the execution of the user function (if the namespace is
+ * unlocked before invocation of the user function.) Only the
+ * debugger namespace dump will examine the temporary nodes.
*/
if ((child_node->flags & ANOBJ_TEMPORARY) &&
!(flags & ACPI_NS_WALK_TEMP_NODES)) {
diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c
index 22a7171ac1e..045054037c2 100644
--- a/drivers/acpi/acpica/nsxfeval.c
+++ b/drivers/acpi/acpica/nsxfeval.c
@@ -387,8 +387,7 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info)
/* We are interested in reference objects only */
- if (ACPI_GET_OBJECT_TYPE(info->return_object) !=
- ACPI_TYPE_LOCAL_REFERENCE) {
+ if ((info->return_object)->common.type != ACPI_TYPE_LOCAL_REFERENCE) {
return;
}
@@ -476,21 +475,40 @@ acpi_walk_namespace(acpi_object_type type,
}
/*
- * Lock the namespace around the walk.
- * The namespace will be unlocked/locked around each call
- * to the user function - since this function
- * must be allowed to make Acpi calls itself.
+ * Need to acquire the namespace reader lock to prevent interference
+ * with any concurrent table unloads (which causes the deletion of
+ * namespace objects). We cannot allow the deletion of a namespace node
+ * while the user function is using it. The exception to this are the
+ * nodes created and deleted during control method execution -- these
+ * nodes are marked as temporary nodes and are ignored by the namespace
+ * walk. Thus, control methods can be executed while holding the
+ * namespace deletion lock (and the user function can execute control
+ * methods.)
+ */
+ status = acpi_ut_acquire_read_lock(&acpi_gbl_namespace_rw_lock);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /*
+ * Lock the namespace around the walk. The namespace will be
+ * unlocked/locked around each call to the user function - since the user
+ * function must be allowed to make ACPICA calls itself (for example, it
+ * will typically execute control methods during device enumeration.)
*/
status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE);
if (ACPI_FAILURE(status)) {
- return_ACPI_STATUS(status);
+ goto unlock_and_exit;
}
status = acpi_ns_walk_namespace(type, start_object, max_depth,
- ACPI_NS_WALK_UNLOCK,
- user_function, context, return_value);
+ ACPI_NS_WALK_UNLOCK, user_function,
+ context, return_value);
(void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE);
+
+ unlock_and_exit:
+ (void)acpi_ut_release_read_lock(&acpi_gbl_namespace_rw_lock);
return_ACPI_STATUS(status);
}
diff --git a/drivers/acpi/acpica/rscalc.c b/drivers/acpi/acpica/rscalc.c
index 52865ee6bc7..b6667ff059e 100644
--- a/drivers/acpi/acpica/rscalc.c
+++ b/drivers/acpi/acpica/rscalc.c
@@ -557,9 +557,9 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
table_index++) {
if (*sub_object_list && /* Null object allowed */
((ACPI_TYPE_STRING ==
- ACPI_GET_OBJECT_TYPE(*sub_object_list)) ||
+ (*sub_object_list)->common.type) ||
((ACPI_TYPE_LOCAL_REFERENCE ==
- ACPI_GET_OBJECT_TYPE(*sub_object_list)) &&
+ (*sub_object_list)->common.type) &&
((*sub_object_list)->reference.class ==
ACPI_REFCLASS_NAME)))) {
name_found = TRUE;
@@ -575,8 +575,7 @@ acpi_rs_get_pci_routing_table_length(union acpi_operand_object *package_object,
/* Was a String type found? */
if (name_found) {
- if (ACPI_GET_OBJECT_TYPE(*sub_object_list) ==
- ACPI_TYPE_STRING) {
+ if ((*sub_object_list)->common.type == ACPI_TYPE_STRING) {
/*
* The length String.Length field does not include the
* terminating NULL, add 1
diff --git a/drivers/acpi/acpica/rscreate.c b/drivers/acpi/acpica/rscreate.c
index 61566b1a061..663f692fffc 100644
--- a/drivers/acpi/acpica/rscreate.c
+++ b/drivers/acpi/acpica/rscreate.c
@@ -212,7 +212,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* Each element of the top-level package must also be a package */
- if (ACPI_GET_OBJECT_TYPE(*top_object_list) != ACPI_TYPE_PACKAGE) {
+ if ((*top_object_list)->common.type != ACPI_TYPE_PACKAGE) {
ACPI_ERROR((AE_INFO,
"(PRT[%X]) Need sub-package, found %s",
index,
@@ -240,7 +240,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 1) First subobject: Dereference the PRT.Address */
obj_desc = sub_object_list[0];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Address) Need Integer, found %s",
index,
@@ -253,7 +253,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 2) Second subobject: Dereference the PRT.Pin */
obj_desc = sub_object_list[1];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].Pin) Need Integer, found %s",
index,
@@ -265,7 +265,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* If BIOS erroneously reversed the _PRT source_name and source_index,
* then reverse them back.
*/
- if (ACPI_GET_OBJECT_TYPE(sub_object_list[3]) !=
+ if ((sub_object_list[3])->common.type !=
ACPI_TYPE_INTEGER) {
if (acpi_gbl_enable_interpreter_slack) {
source_name_index = 3;
@@ -291,8 +291,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
* other ACPI implementations.
*/
obj_desc = sub_object_list[3];
- if (!obj_desc
- || (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER)) {
+ if (!obj_desc || (obj_desc->common.type != ACPI_TYPE_INTEGER)) {
sub_object_list[3] = sub_object_list[2];
sub_object_list[2] = obj_desc;
@@ -307,7 +306,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
*/
obj_desc = sub_object_list[source_name_index];
if (obj_desc) {
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_LOCAL_REFERENCE:
if (obj_desc->reference.class !=
@@ -380,7 +379,7 @@ acpi_rs_create_pci_routing_table(union acpi_operand_object *package_object,
/* 4) Fourth subobject: Dereference the PRT.source_index */
obj_desc = sub_object_list[source_index_index];
- if (ACPI_GET_OBJECT_TYPE(obj_desc) != ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type != ACPI_TYPE_INTEGER) {
ACPI_ERROR((AE_INFO,
"(PRT[%X].SourceIndex) Need Integer, found %s",
index,
diff --git a/drivers/acpi/acpica/tbfadt.c b/drivers/acpi/acpica/tbfadt.c
index 3636e4f8fb7..71e655d14cb 100644
--- a/drivers/acpi/acpica/tbfadt.c
+++ b/drivers/acpi/acpica/tbfadt.c
@@ -57,6 +57,8 @@ static void acpi_tb_convert_fadt(void);
static void acpi_tb_validate_fadt(void);
+static void acpi_tb_setup_fadt_registers(void);
+
/* Table for conversion of FADT to common internal format and FADT validation */
typedef struct acpi_fadt_info {
@@ -130,7 +132,38 @@ static struct acpi_fadt_info fadt_info_table[] = {
ACPI_FADT_SEPARATE_LENGTH}
};
-#define ACPI_FADT_INFO_ENTRIES (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+#define ACPI_FADT_INFO_ENTRIES \
+ (sizeof (fadt_info_table) / sizeof (struct acpi_fadt_info))
+
+/* Table used to split Event Blocks into separate status/enable registers */
+
+typedef struct acpi_fadt_pm_info {
+ struct acpi_generic_address *target;
+ u8 source;
+ u8 register_num;
+
+} acpi_fadt_pm_info;
+
+static struct acpi_fadt_pm_info fadt_pm_info_table[] = {
+ {&acpi_gbl_xpm1a_status,
+ ACPI_FADT_OFFSET(xpm1a_event_block),
+ 0},
+
+ {&acpi_gbl_xpm1a_enable,
+ ACPI_FADT_OFFSET(xpm1a_event_block),
+ 1},
+
+ {&acpi_gbl_xpm1b_status,
+ ACPI_FADT_OFFSET(xpm1b_event_block),
+ 0},
+
+ {&acpi_gbl_xpm1b_enable,
+ ACPI_FADT_OFFSET(xpm1b_event_block),
+ 1}
+};
+
+#define ACPI_FADT_PM_INFO_ENTRIES \
+ (sizeof (fadt_pm_info_table) / sizeof (struct acpi_fadt_pm_info))
/*******************************************************************************
*
@@ -172,7 +205,6 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
* FUNCTION: acpi_tb_parse_fadt
*
* PARAMETERS: table_index - Index for the FADT
- * Flags - Flags
*
* RETURN: None
*
@@ -181,7 +213,7 @@ acpi_tb_init_generic_address(struct acpi_generic_address *generic_address,
*
******************************************************************************/
-void acpi_tb_parse_fadt(u32 table_index, u8 flags)
+void acpi_tb_parse_fadt(u32 table_index)
{
u32 length;
struct acpi_table_header *table;
@@ -208,7 +240,7 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
*/
(void)acpi_tb_verify_checksum(table, length);
- /* Obtain a local copy of the FADT in common ACPI 2.0+ format */
+ /* Create a local copy of the FADT in common ACPI 2.0+ format */
acpi_tb_create_local_fadt(table, length);
@@ -219,10 +251,10 @@ void acpi_tb_parse_fadt(u32 table_index, u8 flags)
/* Obtain the DSDT and FACS tables via their addresses within the FADT */
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xdsdt,
- flags, ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
+ ACPI_SIG_DSDT, ACPI_TABLE_INDEX_DSDT);
acpi_tb_install_table((acpi_physical_address) acpi_gbl_FADT.Xfacs,
- flags, ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
+ ACPI_SIG_FACS, ACPI_TABLE_INDEX_FACS);
}
/*******************************************************************************
@@ -266,11 +298,17 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
ACPI_MEMCPY(&acpi_gbl_FADT, table,
ACPI_MIN(length, sizeof(struct acpi_table_fadt)));
- /*
- * 1) Convert the local copy of the FADT to the common internal format
- * 2) Validate some of the important values within the FADT
- */
+ /* Convert the local copy of the FADT to the common internal format */
+
acpi_tb_convert_fadt();
+
+ /* Validate FADT values now, before we make any changes */
+
+ acpi_tb_validate_fadt();
+
+ /* Initialize the global ACPI register structures */
+
+ acpi_tb_setup_fadt_registers();
}
/*******************************************************************************
@@ -282,31 +320,35 @@ void acpi_tb_create_local_fadt(struct acpi_table_header *table, u32 length)
* RETURN: None
*
* DESCRIPTION: Converts all versions of the FADT to a common internal format.
- * Expand all 32-bit addresses to 64-bit.
+ * Expand 32-bit addresses to 64-bit as necessary.
*
* NOTE: acpi_gbl_FADT must be of size (struct acpi_table_fadt),
* and must contain a copy of the actual FADT.
*
- * ACPICA will use the "X" fields of the FADT for all addresses.
+ * Notes on 64-bit register addresses:
+ *
+ * After this FADT conversion, later ACPICA code will only use the 64-bit "X"
+ * fields of the FADT for all ACPI register addresses.
*
- * "X" fields are optional extensions to the original V1.0 fields. Even if
- * they are present in the structure, they can be optionally not used by
- * setting them to zero. Therefore, we must selectively expand V1.0 fields
- * if the corresponding X field is zero.
+ * The 64-bit "X" fields are optional extensions to the original 32-bit FADT
+ * V1.0 fields. Even if they are present in the FADT, they are optional and
+ * are unused if the BIOS sets them to zero. Therefore, we must copy/expand
+ * 32-bit V1.0 fields if the corresponding X field is zero.
*
- * For ACPI 1.0 FADTs, all address fields are expanded to the corresponding
- * "X" fields.
+ * For ACPI 1.0 FADTs, all 32-bit address fields are expanded to the
+ * corresponding "X" fields in the internal FADT.
*
- * For ACPI 2.0 FADTs, any "X" fields that are NULL are filled in by
- * expanding the corresponding ACPI 1.0 field.
+ * For ACPI 2.0+ FADTs, all valid (non-zero) 32-bit address fields are expanded
+ * to the corresponding 64-bit X fields. For compatibility with other ACPI
+ * implementations, we ignore the 64-bit field if the 32-bit field is valid,
+ * regardless of whether the host OS is 32-bit or 64-bit.
*
******************************************************************************/
static void acpi_tb_convert_fadt(void)
{
- u8 pm1_register_bit_width;
- u8 pm1_register_byte_width;
- struct acpi_generic_address *target64;
+ struct acpi_generic_address *address64;
+ u32 address32;
u32 i;
/* Update the local FADT table header length */
@@ -355,140 +397,56 @@ static void acpi_tb_convert_fadt(void)
* Expand the ACPI 1.0 32-bit addresses to the ACPI 2.0 64-bit "X"
* generic address structures as necessary. Later code will always use
* the 64-bit address structures.
+ *
+ * March 2009:
+ * We now always use the 32-bit address if it is valid (non-null). This
+ * is not in accordance with the ACPI specification which states that
+ * the 64-bit address supersedes the 32-bit version, but we do this for
+ * compatibility with other ACPI implementations. Most notably, in the
+ * case where both the 32 and 64 versions are non-null, we use the 32-bit
+ * version. This is the only address that is guaranteed to have been
+ * tested by the BIOS manufacturer.
*/
for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
- target64 =
- ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
- fadt_info_table[i].address64);
+ address32 = *ACPI_ADD_PTR(u32,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address32);
- /* Expand only if the 64-bit X target is null */
+ address64 = ACPI_ADD_PTR(struct acpi_generic_address,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address64);
- if (!target64->address) {
+ /*
+ * If both 32- and 64-bit addresses are valid (non-zero),
+ * they must match.
+ */
+ if (address64->address && address32 &&
+ (address64->address != (u64) address32)) {
+ ACPI_ERROR((AE_INFO,
+ "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 32",
+ fadt_info_table[i].name, address32,
+ ACPI_FORMAT_UINT64(address64->address)));
+ }
- /* The space_id is always I/O for the 32-bit legacy address fields */
+ /* Always use 32-bit address if it is valid (non-null) */
- acpi_tb_init_generic_address(target64,
+ if (address32) {
+ /*
+ * Copy the 32-bit address to the 64-bit GAS structure. The
+ * Space ID is always I/O for 32-bit legacy address fields
+ */
+ acpi_tb_init_generic_address(address64,
ACPI_ADR_SPACE_SYSTEM_IO,
*ACPI_ADD_PTR(u8,
&acpi_gbl_FADT,
fadt_info_table
[i].length),
- (u64) * ACPI_ADD_PTR(u32,
- &acpi_gbl_FADT,
- fadt_info_table
- [i].
- address32));
- }
- }
-
- /* Validate FADT values now, before we make any changes */
-
- acpi_tb_validate_fadt();
-
- /*
- * Optionally check all register lengths against the default values and
- * update them if they are incorrect.
- */
- if (acpi_gbl_use_default_register_widths) {
- for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
- target64 =
- ACPI_ADD_PTR(struct acpi_generic_address,
- &acpi_gbl_FADT,
- fadt_info_table[i].address64);
-
- /*
- * If a valid register (Address != 0) and the (default_length > 0)
- * (Not a GPE register), then check the width against the default.
- */
- if ((target64->address) &&
- (fadt_info_table[i].default_length > 0) &&
- (fadt_info_table[i].default_length !=
- target64->bit_width)) {
- ACPI_WARNING((AE_INFO,
- "Invalid length for %s: %d, using default %d",
- fadt_info_table[i].name,
- target64->bit_width,
- fadt_info_table[i].
- default_length));
-
- /* Incorrect size, set width to the default */
-
- target64->bit_width =
- fadt_info_table[i].default_length;
- }
+ address32);
}
}
-
- /*
- * Get the length of the individual PM1 registers (enable and status).
- * Each register is defined to be (event block length / 2).
- */
- pm1_register_bit_width =
- (u8)ACPI_DIV_2(acpi_gbl_FADT.xpm1a_event_block.bit_width);
- pm1_register_byte_width = (u8)ACPI_DIV_8(pm1_register_bit_width);
-
- /*
- * Adjust the lengths of the PM1 Event Blocks so that they can be used to
- * access the PM1 status register(s). Use (width / 2)
- */
- acpi_gbl_FADT.xpm1a_event_block.bit_width = pm1_register_bit_width;
- acpi_gbl_FADT.xpm1b_event_block.bit_width = pm1_register_bit_width;
-
- /*
- * Calculate separate GAS structs for the PM1 Enable registers.
- * These addresses do not appear (directly) in the FADT, so it is
- * useful to calculate them once, here.
- *
- * The PM event blocks are split into two register blocks, first is the
- * PM Status Register block, followed immediately by the PM Enable
- * Register block. Each is of length (xpm1x_event_block.bit_width/2).
- *
- * On various systems the v2 fields (and particularly the bit widths)
- * cannot be relied upon, though. Hence resort to using the v1 length
- * here (and warn about the inconsistency).
- */
- if (acpi_gbl_FADT.xpm1a_event_block.bit_width
- != acpi_gbl_FADT.pm1_event_length * 8)
- printk(KERN_WARNING "FADT: "
- "X_PM1a_EVT_BLK.bit_width (%u) does not match"
- " PM1_EVT_LEN (%u)\n",
- acpi_gbl_FADT.xpm1a_event_block.bit_width,
- acpi_gbl_FADT.pm1_event_length);
-
- /* The PM1A register block is required */
-
- acpi_tb_init_generic_address(&acpi_gbl_xpm1a_enable,
- acpi_gbl_FADT.xpm1a_event_block.space_id,
- pm1_register_byte_width,
- (acpi_gbl_FADT.xpm1a_event_block.address +
- pm1_register_byte_width));
- /* Don't forget to copy space_id of the GAS */
- acpi_gbl_xpm1a_enable.space_id =
- acpi_gbl_FADT.xpm1a_event_block.space_id;
-
- /* The PM1B register block is optional, ignore if not present */
-
- if (acpi_gbl_FADT.xpm1b_event_block.address) {
- if (acpi_gbl_FADT.xpm1b_event_block.bit_width
- != acpi_gbl_FADT.pm1_event_length * 8)
- printk(KERN_WARNING "FADT: "
- "X_PM1b_EVT_BLK.bit_width (%u) does not match"
- " PM1_EVT_LEN (%u)\n",
- acpi_gbl_FADT.xpm1b_event_block.bit_width,
- acpi_gbl_FADT.pm1_event_length);
- acpi_tb_init_generic_address(&acpi_gbl_xpm1b_enable,
- acpi_gbl_FADT.xpm1b_event_block.space_id,
- pm1_register_byte_width,
- (acpi_gbl_FADT.xpm1b_event_block.
- address + pm1_register_byte_width));
- /* Don't forget to copy space_id of the GAS */
- acpi_gbl_xpm1b_enable.space_id =
- acpi_gbl_FADT.xpm1b_event_block.space_id;
-
- }
}
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_tb_validate_fadt
*
@@ -525,18 +483,22 @@ static void acpi_tb_validate_fadt(void)
(acpi_gbl_FADT.Xfacs != (u64) acpi_gbl_FADT.facs)) {
ACPI_WARNING((AE_INFO,
"32/64X FACS address mismatch in FADT - "
- "two FACS tables! %8.8X/%8.8X%8.8X",
+ "%8.8X/%8.8X%8.8X, using 32",
acpi_gbl_FADT.facs,
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xfacs)));
+
+ acpi_gbl_FADT.Xfacs = (u64) acpi_gbl_FADT.facs;
}
if (acpi_gbl_FADT.dsdt &&
(acpi_gbl_FADT.Xdsdt != (u64) acpi_gbl_FADT.dsdt)) {
ACPI_WARNING((AE_INFO,
"32/64X DSDT address mismatch in FADT - "
- "two DSDT tables! %8.8X/%8.8X%8.8X",
+ "%8.8X/%8.8X%8.8X, using 32",
acpi_gbl_FADT.dsdt,
ACPI_FORMAT_UINT64(acpi_gbl_FADT.Xdsdt)));
+
+ acpi_gbl_FADT.Xdsdt = (u64) acpi_gbl_FADT.dsdt;
}
/* Examine all of the 64-bit extended address fields (X fields) */
@@ -561,7 +523,8 @@ static void acpi_tb_validate_fadt(void)
* For each extended field, check for length mismatch between the
* legacy length field and the corresponding 64-bit X length field.
*/
- if (address64 && (address64->bit_width != ACPI_MUL_8(length))) {
+ if (address64->address &&
+ (address64->bit_width != ACPI_MUL_8(length))) {
ACPI_WARNING((AE_INFO,
"32/64X length mismatch in %s: %d/%d",
name, ACPI_MUL_8(length),
@@ -575,7 +538,8 @@ static void acpi_tb_validate_fadt(void)
*/
if (!address64->address || !length) {
ACPI_ERROR((AE_INFO,
- "Required field %s has zero address and/or length: %8.8X%8.8X/%X",
+ "Required field %s has zero address and/or length:"
+ " %8.8X%8.8X/%X",
name,
ACPI_FORMAT_UINT64(address64->
address),
@@ -584,27 +548,112 @@ static void acpi_tb_validate_fadt(void)
} else if (fadt_info_table[i].type & ACPI_FADT_SEPARATE_LENGTH) {
/*
* Field is optional (PM2Control, GPE0, GPE1) AND has its own
- * length field. If present, both the address and length must be valid.
+ * length field. If present, both the address and length must
+ * be valid.
*/
- if ((address64->address && !length)
- || (!address64->address && length)) {
+ if ((address64->address && !length) ||
+ (!address64->address && length)) {
ACPI_WARNING((AE_INFO,
- "Optional field %s has zero address or length: %8.8X%8.8X/%X",
+ "Optional field %s has zero address or length: "
+ "%8.8X%8.8X/%X",
name,
ACPI_FORMAT_UINT64(address64->
address),
length));
}
}
+ }
+}
- /* If both 32- and 64-bit addresses are valid (non-zero), they must match */
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_tb_setup_fadt_registers
+ *
+ * PARAMETERS: None, uses acpi_gbl_FADT.
+ *
+ * RETURN: None
+ *
+ * DESCRIPTION: Initialize global ACPI PM1 register definitions. Optionally,
+ * force FADT register definitions to their default lengths.
+ *
+ ******************************************************************************/
- if (address64->address && *address32 &&
- (address64->address != (u64) * address32)) {
- ACPI_ERROR((AE_INFO,
- "32/64X address mismatch in %s: %8.8X/%8.8X%8.8X, using 64X",
- name, *address32,
- ACPI_FORMAT_UINT64(address64->address)));
+static void acpi_tb_setup_fadt_registers(void)
+{
+ struct acpi_generic_address *target64;
+ struct acpi_generic_address *source64;
+ u8 pm1_register_byte_width;
+ u32 i;
+
+ /*
+ * Optionally check all register lengths against the default values and
+ * update them if they are incorrect.
+ */
+ if (acpi_gbl_use_default_register_widths) {
+ for (i = 0; i < ACPI_FADT_INFO_ENTRIES; i++) {
+ target64 =
+ ACPI_ADD_PTR(struct acpi_generic_address,
+ &acpi_gbl_FADT,
+ fadt_info_table[i].address64);
+
+ /*
+ * If a valid register (Address != 0) and the (default_length > 0)
+ * (Not a GPE register), then check the width against the default.
+ */
+ if ((target64->address) &&
+ (fadt_info_table[i].default_length > 0) &&
+ (fadt_info_table[i].default_length !=
+ target64->bit_width)) {
+ ACPI_WARNING((AE_INFO,
+ "Invalid length for %s: %d, using default %d",
+ fadt_info_table[i].name,
+ target64->bit_width,
+ fadt_info_table[i].
+ default_length));
+
+ /* Incorrect size, set width to the default */
+
+ target64->bit_width =
+ fadt_info_table[i].default_length;
+ }
+ }
+ }
+
+ /*
+ * Get the length of the individual PM1 registers (enable and status).
+ * Each register is defined to be (event block length / 2). Extra divide
+ * by 8 converts bits to bytes.
+ */
+ pm1_register_byte_width = (u8)
+ ACPI_DIV_16(acpi_gbl_FADT.xpm1a_event_block.bit_width);
+
+ /*
+ * Calculate separate GAS structs for the PM1x (A/B) Status and Enable
+ * registers. These addresses do not appear (directly) in the FADT, so it
+ * is useful to pre-calculate them from the PM1 Event Block definitions.
+ *
+ * The PM event blocks are split into two register blocks, first is the
+ * PM Status Register block, followed immediately by the PM Enable
+ * Register block. Each is of length (pm1_event_length/2)
+ *
+ * Note: The PM1A event block is required by the ACPI specification.
+ * However, the PM1B event block is optional and is rarely, if ever,
+ * used.
+ */
+
+ for (i = 0; i < ACPI_FADT_PM_INFO_ENTRIES; i++) {
+ source64 =
+ ACPI_ADD_PTR(struct acpi_generic_address, &acpi_gbl_FADT,
+ fadt_pm_info_table[i].source);
+
+ if (source64->address) {
+ acpi_tb_init_generic_address(fadt_pm_info_table[i].
+ target, source64->space_id,
+ pm1_register_byte_width,
+ source64->address +
+ (fadt_pm_info_table[i].
+ register_num *
+ pm1_register_byte_width));
}
}
}
diff --git a/drivers/acpi/acpica/tbinstal.c b/drivers/acpi/acpica/tbinstal.c
index 37374b21969..f865d5a096d 100644
--- a/drivers/acpi/acpica/tbinstal.c
+++ b/drivers/acpi/acpica/tbinstal.c
@@ -103,7 +103,9 @@ acpi_status acpi_tb_verify_table(struct acpi_table_desc *table_desc)
*
* RETURN: Status
*
- * DESCRIPTION: This function is called to add the ACPI table
+ * DESCRIPTION: This function is called to add an ACPI table. It is used to
+ * dynamically load tables via the Load and load_table AML
+ * operators.
*
******************************************************************************/
@@ -112,6 +114,7 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
{
u32 i;
acpi_status status = AE_OK;
+ struct acpi_table_header *override_table = NULL;
ACPI_FUNCTION_TRACE(tb_add_table);
@@ -201,6 +204,29 @@ acpi_tb_add_table(struct acpi_table_desc *table_desc, u32 *table_index)
}
}
+ /*
+ * ACPI Table Override:
+ * Allow the host to override dynamically loaded tables.
+ */
+ status = acpi_os_table_override(table_desc->pointer, &override_table);
+ if (ACPI_SUCCESS(status) && override_table) {
+ ACPI_INFO((AE_INFO,
+ "%4.4s @ 0x%p Table override, replaced with:",
+ table_desc->pointer->signature,
+ ACPI_CAST_PTR(void, table_desc->address)));
+
+ /* We can delete the table that was passed as a parameter */
+
+ acpi_tb_delete_table(table_desc);
+
+ /* Setup descriptor for the new table */
+
+ table_desc->address = ACPI_PTR_TO_PHYSADDR(override_table);
+ table_desc->pointer = override_table;
+ table_desc->length = override_table->length;
+ table_desc->flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ }
+
/* Add the table to the global root table list */
status = acpi_tb_store_table(table_desc->address, table_desc->pointer,
@@ -247,8 +273,9 @@ acpi_status acpi_tb_resize_root_table_list(void)
/* Increase the Table Array size */
tables = ACPI_ALLOCATE_ZEROED(((acpi_size) acpi_gbl_root_table_list.
- size + ACPI_ROOT_TABLE_SIZE_INCREMENT)
- * sizeof(struct acpi_table_desc));
+ size +
+ ACPI_ROOT_TABLE_SIZE_INCREMENT) *
+ sizeof(struct acpi_table_desc));
if (!tables) {
ACPI_ERROR((AE_INFO,
"Could not allocate new root table array"));
@@ -407,27 +434,56 @@ void acpi_tb_terminate(void)
*
* PARAMETERS: table_index - Table index
*
- * RETURN: None
+ * RETURN: Status
*
* DESCRIPTION: Delete all namespace objects created when this table was loaded.
*
******************************************************************************/
-void acpi_tb_delete_namespace_by_owner(u32 table_index)
+acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index)
{
acpi_owner_id owner_id;
+ acpi_status status;
+
+ ACPI_FUNCTION_TRACE(tb_delete_namespace_by_owner);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ if (table_index >= acpi_gbl_root_table_list.count) {
+
+ /* The table index does not exist */
- (void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
- if (table_index < acpi_gbl_root_table_list.count) {
- owner_id =
- acpi_gbl_root_table_list.tables[table_index].owner_id;
- } else {
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
- return;
+ return_ACPI_STATUS(AE_NOT_EXIST);
}
+ /* Get the owner ID for this table, used to delete namespace nodes */
+
+ owner_id = acpi_gbl_root_table_list.tables[table_index].owner_id;
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
+
+ /*
+ * Need to acquire the namespace writer lock to prevent interference
+ * with any concurrent namespace walks. The interpreter must be
+ * released during the deletion since the acquisition of the deletion
+ * lock may block, and also since the execution of a namespace walk
+ * must be allowed to use the interpreter.
+ */
+ acpi_ut_release_mutex(ACPI_MTX_INTERPRETER);
+ status = acpi_ut_acquire_write_lock(&acpi_gbl_namespace_rw_lock);
+
acpi_ns_delete_namespace_by_owner(owner_id);
+ if (ACPI_FAILURE(status)) {
+ return_ACPI_STATUS(status);
+ }
+
+ acpi_ut_release_write_lock(&acpi_gbl_namespace_rw_lock);
+
+ status = acpi_ut_acquire_mutex(ACPI_MTX_INTERPRETER);
+ return_ACPI_STATUS(status);
}
/*******************************************************************************
@@ -535,8 +591,8 @@ u8 acpi_tb_is_table_loaded(u32 table_index)
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
if (table_index < acpi_gbl_root_table_list.count) {
is_loaded = (u8)
- (acpi_gbl_root_table_list.tables[table_index].
- flags & ACPI_TABLE_IS_LOADED);
+ (acpi_gbl_root_table_list.tables[table_index].flags &
+ ACPI_TABLE_IS_LOADED);
}
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
diff --git a/drivers/acpi/acpica/tbutils.c b/drivers/acpi/acpica/tbutils.c
index 22ce4898572..ef7d2c2d8f0 100644
--- a/drivers/acpi/acpica/tbutils.c
+++ b/drivers/acpi/acpica/tbutils.c
@@ -177,19 +177,23 @@ acpi_tb_print_table_header(acpi_physical_address address,
struct acpi_table_header *header)
{
+ /*
+ * The reason that the Address is cast to a void pointer is so that we
+ * can use %p which will work properly on both 32-bit and 64-bit hosts.
+ */
if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_FACS)) {
- /* FACS only has signature and length fields of common table header */
+ /* FACS only has signature and length fields */
- ACPI_INFO((AE_INFO, "%4.4s %08lX, %04X",
- header->signature, (unsigned long)address,
+ ACPI_INFO((AE_INFO, "%4.4s %p %05X",
+ header->signature, ACPI_CAST_PTR(void, address),
header->length));
} else if (ACPI_COMPARE_NAME(header->signature, ACPI_SIG_RSDP)) {
/* RSDP has no common fields */
- ACPI_INFO((AE_INFO, "RSDP %08lX, %04X (r%d %6.6s)",
- (unsigned long)address,
+ ACPI_INFO((AE_INFO, "RSDP %p %05X (v%.2d %6.6s)",
+ ACPI_CAST_PTR (void, address),
(ACPI_CAST_PTR(struct acpi_table_rsdp, header)->
revision >
0) ? ACPI_CAST_PTR(struct acpi_table_rsdp,
@@ -202,8 +206,8 @@ acpi_tb_print_table_header(acpi_physical_address address,
/* Standard ACPI table with full common header */
ACPI_INFO((AE_INFO,
- "%4.4s %08lX, %04X (r%d %6.6s %8.8s %8X %4.4s %8X)",
- header->signature, (unsigned long)address,
+ "%4.4s %p %05X (v%.2d %6.6s %8.8s %08X %4.4s %08X)",
+ header->signature, ACPI_CAST_PTR (void, address),
header->length, header->revision, header->oem_id,
header->oem_table_id, header->oem_revision,
header->asl_compiler_id,
@@ -280,22 +284,28 @@ u8 acpi_tb_checksum(u8 *buffer, u32 length)
* FUNCTION: acpi_tb_install_table
*
* PARAMETERS: Address - Physical address of DSDT or FACS
- * Flags - Flags
* Signature - Table signature, NULL if no need to
* match
* table_index - Index into root table array
*
* RETURN: None
*
- * DESCRIPTION: Install an ACPI table into the global data structure.
+ * DESCRIPTION: Install an ACPI table into the global data structure. The
+ * table override mechanism is implemented here to allow the host
+ * OS to replace any table before it is installed in the root
+ * table array.
*
******************************************************************************/
void
acpi_tb_install_table(acpi_physical_address address,
- u8 flags, char *signature, u32 table_index)
+ char *signature, u32 table_index)
{
- struct acpi_table_header *table;
+ u8 flags;
+ acpi_status status;
+ struct acpi_table_header *table_to_install;
+ struct acpi_table_header *mapped_table;
+ struct acpi_table_header *override_table = NULL;
if (!address) {
ACPI_ERROR((AE_INFO,
@@ -306,41 +316,69 @@ acpi_tb_install_table(acpi_physical_address address,
/* Map just the table header */
- table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
- if (!table) {
+ mapped_table =
+ acpi_os_map_memory(address, sizeof(struct acpi_table_header));
+ if (!mapped_table) {
return;
}
- /* If a particular signature is expected, signature must match */
+ /* If a particular signature is expected (DSDT/FACS), it must match */
- if (signature && !ACPI_COMPARE_NAME(table->signature, signature)) {
+ if (signature && !ACPI_COMPARE_NAME(mapped_table->signature, signature)) {
ACPI_ERROR((AE_INFO,
- "Invalid signature 0x%X for ACPI table [%s]",
- *ACPI_CAST_PTR(u32, table->signature), signature));
+ "Invalid signature 0x%X for ACPI table, expected [%s]",
+ *ACPI_CAST_PTR(u32, mapped_table->signature),
+ signature));
goto unmap_and_exit;
}
+ /*
+ * ACPI Table Override:
+ *
+ * Before we install the table, let the host OS override it with a new
+ * one if desired. Any table within the RSDT/XSDT can be replaced,
+ * including the DSDT which is pointed to by the FADT.
+ */
+ status = acpi_os_table_override(mapped_table, &override_table);
+ if (ACPI_SUCCESS(status) && override_table) {
+ ACPI_INFO((AE_INFO,
+ "%4.4s @ 0x%p Table override, replaced with:",
+ mapped_table->signature, ACPI_CAST_PTR(void,
+ address)));
+
+ acpi_gbl_root_table_list.tables[table_index].pointer =
+ override_table;
+ address = ACPI_PTR_TO_PHYSADDR(override_table);
+
+ table_to_install = override_table;
+ flags = ACPI_TABLE_ORIGIN_OVERRIDE;
+ } else {
+ table_to_install = mapped_table;
+ flags = ACPI_TABLE_ORIGIN_MAPPED;
+ }
+
/* Initialize the table entry */
acpi_gbl_root_table_list.tables[table_index].address = address;
- acpi_gbl_root_table_list.tables[table_index].length = table->length;
+ acpi_gbl_root_table_list.tables[table_index].length =
+ table_to_install->length;
acpi_gbl_root_table_list.tables[table_index].flags = flags;
ACPI_MOVE_32_TO_32(&
(acpi_gbl_root_table_list.tables[table_index].
- signature), table->signature);
+ signature), table_to_install->signature);
- acpi_tb_print_table_header(address, table);
+ acpi_tb_print_table_header(address, table_to_install);
if (table_index == ACPI_TABLE_INDEX_DSDT) {
/* Global integer width is based upon revision of the DSDT */
- acpi_ut_set_integer_width(table->revision);
+ acpi_ut_set_integer_width(table_to_install->revision);
}
unmap_and_exit:
- acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
+ acpi_os_unmap_memory(mapped_table, sizeof(struct acpi_table_header));
}
/*******************************************************************************
@@ -379,7 +417,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
} else {
/*
* 32-bit platform, XSDT: Truncate 64-bit to 32-bit and return
- * 64-bit platform, XSDT: Move (unaligned) 64-bit to local, return 64-bit
+ * 64-bit platform, XSDT: Move (unaligned) 64-bit to local,
+ * return 64-bit
*/
ACPI_MOVE_64_TO_64(&address64, table_entry);
@@ -389,7 +428,8 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
/* Will truncate 64-bit address to 32 bits, issue warning */
ACPI_WARNING((AE_INFO,
- "64-bit Physical Address in XSDT is too large (%8.8X%8.8X), truncating",
+ "64-bit Physical Address in XSDT is too large (%8.8X%8.8X),"
+ " truncating",
ACPI_FORMAT_UINT64(address64)));
}
#endif
@@ -402,7 +442,6 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
* FUNCTION: acpi_tb_parse_root_table
*
* PARAMETERS: Rsdp - Pointer to the RSDP
- * Flags - Flags
*
* RETURN: Status
*
@@ -416,7 +455,7 @@ acpi_tb_get_root_table_entry(u8 *table_entry, u32 table_entry_size)
******************************************************************************/
acpi_status __init
-acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
+acpi_tb_parse_root_table(acpi_physical_address rsdp_address)
{
struct acpi_table_rsdp *rsdp;
u32 table_entry_size;
@@ -513,13 +552,12 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
/* Calculate the number of tables described in the root table */
- table_count =
- (u32) ((table->length -
- sizeof(struct acpi_table_header)) / table_entry_size);
-
+ table_count = (u32)((table->length - sizeof(struct acpi_table_header)) /
+ table_entry_size);
/*
- * First two entries in the table array are reserved for the DSDT and FACS,
- * which are not actually present in the RSDT/XSDT - they come from the FADT
+ * First two entries in the table array are reserved for the DSDT
+ * and FACS, which are not actually present in the RSDT/XSDT - they
+ * come from the FADT
*/
table_entry =
ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
@@ -567,14 +605,14 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
*/
for (i = 2; i < acpi_gbl_root_table_list.count; i++) {
acpi_tb_install_table(acpi_gbl_root_table_list.tables[i].
- address, flags, NULL, i);
+ address, NULL, i);
/* Special case for FADT - get the DSDT and FACS */
if (ACPI_COMPARE_NAME
(&acpi_gbl_root_table_list.tables[i].signature,
ACPI_SIG_FADT)) {
- acpi_tb_parse_fadt(i, flags);
+ acpi_tb_parse_fadt(i);
}
}
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index ab0aff3c7d6..a88f02bd6c9 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -150,8 +150,7 @@ acpi_initialize_tables(struct acpi_table_desc * initial_table_array,
* Root Table Array. This array contains the information of the RSDT/XSDT
* in a common, more useable format.
*/
- status =
- acpi_tb_parse_root_table(rsdp_address, ACPI_TABLE_ORIGIN_MAPPED);
+ status = acpi_tb_parse_root_table(rsdp_address);
return_ACPI_STATUS(status);
}
@@ -247,7 +246,7 @@ acpi_status acpi_load_table(struct acpi_table_header *table_ptr)
ACPI_EXPORT_SYMBOL(acpi_load_table)
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_get_table_header
*
@@ -262,7 +261,7 @@ ACPI_EXPORT_SYMBOL(acpi_load_table)
* NOTE: Caller is responsible in unmapping the header with
* acpi_os_unmap_memory
*
- *****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_get_table_header(char *signature,
u32 instance, struct acpi_table_header *out_table_header)
@@ -277,9 +276,8 @@ acpi_get_table_header(char *signature,
return (AE_BAD_PARAMETER);
}
- /*
- * Walk the root table list
- */
+ /* Walk the root table list */
+
for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
if (!ACPI_COMPARE_NAME
(&(acpi_gbl_root_table_list.tables[i].signature),
@@ -292,8 +290,8 @@ acpi_get_table_header(char *signature,
}
if (!acpi_gbl_root_table_list.tables[i].pointer) {
- if ((acpi_gbl_root_table_list.tables[i].
- flags & ACPI_TABLE_ORIGIN_MASK) ==
+ if ((acpi_gbl_root_table_list.tables[i].flags &
+ ACPI_TABLE_ORIGIN_MASK) ==
ACPI_TABLE_ORIGIN_MAPPED) {
header =
acpi_os_map_memory(acpi_gbl_root_table_list.
@@ -324,7 +322,7 @@ acpi_get_table_header(char *signature,
ACPI_EXPORT_SYMBOL(acpi_get_table_header)
-/******************************************************************************
+/*******************************************************************************
*
* FUNCTION: acpi_unload_table_id
*
@@ -375,7 +373,7 @@ ACPI_EXPORT_SYMBOL(acpi_unload_table_id)
*
* DESCRIPTION: Finds and verifies an ACPI table.
*
- *****************************************************************************/
+ ******************************************************************************/
acpi_status
acpi_get_table_with_size(char *signature,
u32 instance, struct acpi_table_header **out_table,
@@ -391,9 +389,8 @@ acpi_get_table_with_size(char *signature,
return (AE_BAD_PARAMETER);
}
- /*
- * Walk the root table list
- */
+ /* Walk the root table list */
+
for (i = 0, j = 0; i < acpi_gbl_root_table_list.count; i++) {
if (!ACPI_COMPARE_NAME
(&(acpi_gbl_root_table_list.tables[i].signature),
@@ -502,7 +499,6 @@ ACPI_EXPORT_SYMBOL(acpi_get_table_by_index)
static acpi_status acpi_tb_load_namespace(void)
{
acpi_status status;
- struct acpi_table_header *table;
u32 i;
ACPI_FUNCTION_TRACE(tb_load_namespace);
@@ -526,58 +522,28 @@ static acpi_status acpi_tb_load_namespace(void)
goto unlock_and_exit;
}
- /*
- * Find DSDT table
- */
- status =
- acpi_os_table_override(acpi_gbl_root_table_list.
- tables[ACPI_TABLE_INDEX_DSDT].pointer,
- &table);
- if (ACPI_SUCCESS(status) && table) {
- /*
- * DSDT table has been found
- */
- acpi_tb_delete_table(&acpi_gbl_root_table_list.
- tables[ACPI_TABLE_INDEX_DSDT]);
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].pointer =
- table;
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].length =
- table->length;
- acpi_gbl_root_table_list.tables[ACPI_TABLE_INDEX_DSDT].flags =
- ACPI_TABLE_ORIGIN_UNKNOWN;
-
- ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
- acpi_tb_print_table_header(0, table);
-
- if (no_auto_ssdt == 0) {
- printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"\n");
- }
- }
+ /* A valid DSDT is required */
status =
acpi_tb_verify_table(&acpi_gbl_root_table_list.
tables[ACPI_TABLE_INDEX_DSDT]);
if (ACPI_FAILURE(status)) {
- /* A valid DSDT is required */
-
status = AE_NO_ACPI_TABLES;
goto unlock_and_exit;
}
(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
- /*
- * Load and parse tables.
- */
+ /* Load and parse tables */
+
status = acpi_ns_load_table(ACPI_TABLE_INDEX_DSDT, acpi_gbl_root_node);
if (ACPI_FAILURE(status)) {
return_ACPI_STATUS(status);
}
- /*
- * Load any SSDT or PSDT tables. Note: Loop leaves tables locked
- */
+ /* Load any SSDT or PSDT tables. Note: Loop leaves tables locked */
+
(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
if ((!ACPI_COMPARE_NAME
@@ -630,9 +596,8 @@ acpi_status acpi_load_tables(void)
ACPI_FUNCTION_TRACE(acpi_load_tables);
- /*
- * Load the namespace from the tables
- */
+ /* Load the namespace from the tables */
+
status = acpi_tb_load_namespace();
if (ACPI_FAILURE(status)) {
ACPI_EXCEPTION((AE_INFO, status,
diff --git a/drivers/acpi/acpica/tbxfroot.c b/drivers/acpi/acpica/tbxfroot.c
index b7fc8dd4334..85ea834199e 100644
--- a/drivers/acpi/acpica/tbxfroot.c
+++ b/drivers/acpi/acpica/tbxfroot.c
@@ -75,8 +75,8 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
* Note: Sometimes there exists more than one RSDP in memory; the valid
* RSDP has a valid checksum, all others have an invalid checksum.
*/
- if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP, sizeof(ACPI_SIG_RSDP) - 1)
- != 0) {
+ if (ACPI_STRNCMP((char *)rsdp, ACPI_SIG_RSDP,
+ sizeof(ACPI_SIG_RSDP) - 1) != 0) {
/* Nope, BAD Signature */
diff --git a/drivers/acpi/acpica/utcopy.c b/drivers/acpi/acpica/utcopy.c
index b0dcfd3c872..919624f123d 100644
--- a/drivers/acpi/acpica/utcopy.c
+++ b/drivers/acpi/acpica/utcopy.c
@@ -135,11 +135,11 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
* In general, the external object will be the same type as
* the internal object
*/
- external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->type = internal_object->common.type;
/* However, only a limited number of external types are supported */
- switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+ switch (internal_object->common.type) {
case ACPI_TYPE_STRING:
external_object->string.pointer = (char *)data_space;
@@ -222,8 +222,8 @@ acpi_ut_copy_isimple_to_esimple(union acpi_operand_object *internal_object,
*/
ACPI_ERROR((AE_INFO,
"Unsupported object type, cannot convert to external object: %s",
- acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE
- (internal_object))));
+ acpi_ut_get_type_name(internal_object->common.
+ type)));
return_ACPI_STATUS(AE_SUPPORT);
}
@@ -355,7 +355,7 @@ acpi_ut_copy_ipackage_to_epackage(union acpi_operand_object *internal_object,
info.object_space = 0;
info.num_packages = 1;
- external_object->type = ACPI_GET_OBJECT_TYPE(internal_object);
+ external_object->type = internal_object->common.type;
external_object->package.count = internal_object->package.count;
external_object->package.elements = ACPI_CAST_PTR(union acpi_object,
info.free_space);
@@ -399,7 +399,7 @@ acpi_ut_copy_iobject_to_eobject(union acpi_operand_object *internal_object,
ACPI_FUNCTION_TRACE(ut_copy_iobject_to_eobject);
- if (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE) {
+ if (internal_object->common.type == ACPI_TYPE_PACKAGE) {
/*
* Package object: Copy all subobjects (including
* nested packages)
@@ -496,8 +496,9 @@ acpi_ut_copy_esimple_to_isimple(union acpi_object *external_object,
case ACPI_TYPE_STRING:
internal_object->string.pointer =
- ACPI_ALLOCATE_ZEROED((acpi_size) external_object->string.
- length + 1);
+ ACPI_ALLOCATE_ZEROED((acpi_size)
+ external_object->string.length + 1);
+
if (!internal_object->string.pointer) {
goto error_exit;
}
@@ -697,7 +698,7 @@ acpi_ut_copy_simple_object(union acpi_operand_object *source_desc,
/* Handle the objects with extra data */
- switch (ACPI_GET_OBJECT_TYPE(dest_desc)) {
+ switch (dest_desc->common.type) {
case ACPI_TYPE_BUFFER:
/*
* Allocate and copy the actual buffer if and only if:
@@ -814,8 +815,8 @@ acpi_ut_copy_ielement_to_ielement(u8 object_type,
* This is a simple object, just copy it
*/
target_object =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE
- (source_object));
+ acpi_ut_create_internal_object(source_object->
+ common.type);
if (!target_object) {
return (AE_NO_MEMORY);
}
@@ -892,7 +893,7 @@ acpi_ut_copy_ipackage_to_ipackage(union acpi_operand_object *source_obj,
ACPI_FUNCTION_TRACE(ut_copy_ipackage_to_ipackage);
- dest_obj->common.type = ACPI_GET_OBJECT_TYPE(source_obj);
+ dest_obj->common.type = source_obj->common.type;
dest_obj->common.flags = source_obj->common.flags;
dest_obj->package.count = source_obj->package.count;
@@ -950,15 +951,14 @@ acpi_ut_copy_iobject_to_iobject(union acpi_operand_object *source_desc,
/* Create the top level object */
- *dest_desc =
- acpi_ut_create_internal_object(ACPI_GET_OBJECT_TYPE(source_desc));
+ *dest_desc = acpi_ut_create_internal_object(source_desc->common.type);
if (!*dest_desc) {
return_ACPI_STATUS(AE_NO_MEMORY);
}
/* Copy the object and possible subobjects */
- if (ACPI_GET_OBJECT_TYPE(source_desc) == ACPI_TYPE_PACKAGE) {
+ if (source_desc->common.type == ACPI_TYPE_PACKAGE) {
status =
acpi_ut_copy_ipackage_to_ipackage(source_desc, *dest_desc,
walk_state);
diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c
index a0be9e39531..a5ee23bc4f5 100644
--- a/drivers/acpi/acpica/utdelete.c
+++ b/drivers/acpi/acpica/utdelete.c
@@ -86,7 +86,7 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
* Must delete or free any pointers within the object that are not
* actual ACPI objects (for example, a raw buffer pointer).
*/
- switch (ACPI_GET_OBJECT_TYPE(object)) {
+ switch (object->common.type) {
case ACPI_TYPE_STRING:
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
@@ -382,7 +382,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action)
object, new_count));
}
- if (ACPI_GET_OBJECT_TYPE(object) == ACPI_TYPE_METHOD) {
+ if (object->common.type == ACPI_TYPE_METHOD) {
ACPI_DEBUG_PRINT((ACPI_DB_ALLOCATIONS,
"Method Obj %p Refs=%X, [Decremented]\n",
object, new_count));
@@ -469,7 +469,7 @@ acpi_ut_update_object_reference(union acpi_operand_object *object, u16 action)
* All sub-objects must have their reference count incremented also.
* Different object types have different subobjects.
*/
- switch (ACPI_GET_OBJECT_TYPE(object)) {
+ switch (object->common.type) {
case ACPI_TYPE_DEVICE:
case ACPI_TYPE_PROCESSOR:
case ACPI_TYPE_POWER:
diff --git a/drivers/acpi/acpica/uteval.c b/drivers/acpi/acpica/uteval.c
index 9c9897dbe90..006b16c2601 100644
--- a/drivers/acpi/acpica/uteval.c
+++ b/drivers/acpi/acpica/uteval.c
@@ -59,26 +59,35 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
/*
* Strings supported by the _OSI predefined (internal) method.
+ *
+ * March 2009: Removed "Linux" as this host no longer wants to respond true
+ * for this string. Basically, the only safe OS strings are windows-related
+ * and in many or most cases represent the only test path within the
+ * BIOS-provided ASL code.
+ *
+ * The second element of each entry is used to track the newest version of
+ * Windows that the BIOS has requested.
*/
-static char *acpi_interfaces_supported[] = {
+static struct acpi_interface_info acpi_interfaces_supported[] = {
/* Operating System Vendor Strings */
- "Windows 2000", /* Windows 2000 */
- "Windows 2001", /* Windows XP */
- "Windows 2001 SP1", /* Windows XP SP1 */
- "Windows 2001 SP2", /* Windows XP SP2 */
- "Windows 2001.1", /* Windows Server 2003 */
- "Windows 2001.1 SP1", /* Windows Server 2003 SP1 - Added 03/2006 */
- "Windows 2006", /* Windows Vista - Added 03/2006 */
+ {"Windows 2000", ACPI_OSI_WIN_2000}, /* Windows 2000 */
+ {"Windows 2001", ACPI_OSI_WIN_XP}, /* Windows XP */
+ {"Windows 2001 SP1", ACPI_OSI_WIN_XP_SP1}, /* Windows XP SP1 */
+ {"Windows 2001.1", ACPI_OSI_WINSRV_2003}, /* Windows Server 2003 */
+ {"Windows 2001 SP2", ACPI_OSI_WIN_XP_SP2}, /* Windows XP SP2 */
+ {"Windows 2001.1 SP1", ACPI_OSI_WINSRV_2003_SP1}, /* Windows Server 2003 SP1 - Added 03/2006 */
+ {"Windows 2006", ACPI_OSI_WIN_VISTA}, /* Windows Vista - Added 03/2006 */
/* Feature Group Strings */
- "Extended Address Space Descriptor"
- /*
- * All "optional" feature group strings (features that are implemented
- * by the host) should be implemented in the host version of
- * acpi_os_validate_interface and should not be added here.
- */
+ {"Extended Address Space Descriptor", 0}
+
+ /*
+ * All "optional" feature group strings (features that are implemented
+ * by the host) should be implemented in the host version of
+ * acpi_os_validate_interface and should not be added here.
+ */
};
/*******************************************************************************
@@ -98,6 +107,7 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
acpi_status status;
union acpi_operand_object *string_desc;
union acpi_operand_object *return_desc;
+ u32 return_value;
u32 i;
ACPI_FUNCTION_TRACE(ut_osi_implementation);
@@ -116,19 +126,28 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
return_ACPI_STATUS(AE_NO_MEMORY);
}
- /* Default return value is 0, NOT-SUPPORTED */
+ /* Default return value is 0, NOT SUPPORTED */
- return_desc->integer.value = 0;
- walk_state->return_desc = return_desc;
+ return_value = 0;
/* Compare input string to static table of supported interfaces */
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
- if (!ACPI_STRCMP
- (string_desc->string.pointer,
- acpi_interfaces_supported[i])) {
- return_desc->integer.value = ACPI_UINT32_MAX;
- goto done;
+ if (!ACPI_STRCMP(string_desc->string.pointer,
+ acpi_interfaces_supported[i].name)) {
+ /*
+ * The interface is supported.
+ * Update the osi_data if necessary. We keep track of the latest
+ * version of Windows that has been requested by the BIOS.
+ */
+ if (acpi_interfaces_supported[i].value >
+ acpi_gbl_osi_data) {
+ acpi_gbl_osi_data =
+ acpi_interfaces_supported[i].value;
+ }
+
+ return_value = ACPI_UINT32_MAX;
+ goto exit;
}
}
@@ -139,15 +158,22 @@ acpi_status acpi_ut_osi_implementation(struct acpi_walk_state *walk_state)
*/
status = acpi_os_validate_interface(string_desc->string.pointer);
if (ACPI_SUCCESS(status)) {
- return_desc->integer.value = ACPI_UINT32_MAX;
+
+ /* The interface is supported */
+
+ return_value = ACPI_UINT32_MAX;
}
-done:
- ACPI_DEBUG_PRINT_RAW((ACPI_DB_INFO, "ACPI: BIOS _OSI(%s) %ssupported\n",
- string_desc->string.pointer,
- return_desc->integer.value == 0 ? "not-" : ""));
+exit:
+ ACPI_DEBUG_PRINT_RAW ((ACPI_DB_INFO,
+ "ACPI: BIOS _OSI(%s) is %ssupported\n",
+ string_desc->string.pointer, return_value == 0 ? "not " : ""));
- return_ACPI_STATUS(AE_OK);
+ /* Complete the return value */
+
+ return_desc->integer.value = return_value;
+ walk_state->return_desc = return_desc;
+ return_ACPI_STATUS (AE_OK);
}
/*******************************************************************************
@@ -167,8 +193,8 @@ acpi_status acpi_osi_invalidate(char *interface)
int i;
for (i = 0; i < ACPI_ARRAY_LENGTH(acpi_interfaces_supported); i++) {
- if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i])) {
- *acpi_interfaces_supported[i] = '\0';
+ if (!ACPI_STRCMP(interface, acpi_interfaces_supported[i].name)) {
+ *acpi_interfaces_supported[i].name = '\0';
return AE_OK;
}
}
@@ -248,7 +274,7 @@ acpi_ut_evaluate_object(struct acpi_namespace_node *prefix_node,
/* Map the return object type to the bitmapped type */
- switch (ACPI_GET_OBJECT_TYPE(info->return_object)) {
+ switch ((info->return_object)->common.type) {
case ACPI_TYPE_INTEGER:
return_btype = ACPI_BTYPE_INTEGER;
break;
@@ -418,7 +444,7 @@ acpi_ut_execute_HID(struct acpi_namespace_node *device_node,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Convert the Numeric HID to string */
@@ -459,7 +485,7 @@ acpi_ut_translate_one_cid(union acpi_operand_object *obj_desc,
struct acpi_compatible_id *one_cid)
{
- switch (ACPI_GET_OBJECT_TYPE(obj_desc)) {
+ switch (obj_desc->common.type) {
case ACPI_TYPE_INTEGER:
/* Convert the Numeric CID to string */
@@ -527,7 +553,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
/* Get the number of _CIDs returned */
count = 1;
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
count = obj_desc->package.count;
}
@@ -555,7 +581,7 @@ acpi_ut_execute_CID(struct acpi_namespace_node * device_node,
/* The _CID object can be either a single CID or a package (list) of CIDs */
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_PACKAGE) {
+ if (obj_desc->common.type == ACPI_TYPE_PACKAGE) {
/* Translate each package element */
@@ -620,7 +646,7 @@ acpi_ut_execute_UID(struct acpi_namespace_node *device_node,
return_ACPI_STATUS(status);
}
- if (ACPI_GET_OBJECT_TYPE(obj_desc) == ACPI_TYPE_INTEGER) {
+ if (obj_desc->common.type == ACPI_TYPE_INTEGER) {
/* Convert the Numeric UID to string */
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c
index a3ab9d9da29..59e46f257c0 100644
--- a/drivers/acpi/acpica/utglobal.c
+++ b/drivers/acpi/acpica/utglobal.c
@@ -294,12 +294,9 @@ struct acpi_bit_register_info acpi_gbl_bit_register_info[ACPI_NUM_BITREG] = {
/* ACPI_BITREG_GLOBAL_LOCK_RELEASE */ {ACPI_REGISTER_PM1_CONTROL,
ACPI_BITPOSITION_GLOBAL_LOCK_RELEASE,
ACPI_BITMASK_GLOBAL_LOCK_RELEASE},
- /* ACPI_BITREG_SLEEP_TYPE_A */ {ACPI_REGISTER_PM1_CONTROL,
- ACPI_BITPOSITION_SLEEP_TYPE_X,
- ACPI_BITMASK_SLEEP_TYPE_X},
- /* ACPI_BITREG_SLEEP_TYPE_B */ {ACPI_REGISTER_PM1_CONTROL,
- ACPI_BITPOSITION_SLEEP_TYPE_X,
- ACPI_BITMASK_SLEEP_TYPE_X},
+ /* ACPI_BITREG_SLEEP_TYPE */ {ACPI_REGISTER_PM1_CONTROL,
+ ACPI_BITPOSITION_SLEEP_TYPE,
+ ACPI_BITMASK_SLEEP_TYPE},
/* ACPI_BITREG_SLEEP_ENABLE */ {ACPI_REGISTER_PM1_CONTROL,
ACPI_BITPOSITION_SLEEP_ENABLE,
ACPI_BITMASK_SLEEP_ENABLE},
@@ -476,7 +473,7 @@ char *acpi_ut_get_object_type_name(union acpi_operand_object *obj_desc)
return ("[NULL Object Descriptor]");
}
- return (acpi_ut_get_type_name(ACPI_GET_OBJECT_TYPE(obj_desc)));
+ return (acpi_ut_get_type_name(obj_desc->common.type));
}
/*******************************************************************************
@@ -749,7 +746,10 @@ acpi_status acpi_ut_init_globals(void)
for (i = 0; i < ACPI_NUM_OWNERID_MASKS; i++) {
acpi_gbl_owner_id_mask[i] = 0;
}
- acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000; /* Last ID is never valid */
+
+ /* Last owner_iD is never valid */
+
+ acpi_gbl_owner_id_mask[ACPI_NUM_OWNERID_MASKS - 1] = 0x80000000;
/* GPE support */
@@ -789,6 +789,7 @@ acpi_status acpi_ut_init_globals(void)
acpi_gbl_trace_dbg_layer = 0;
acpi_gbl_debugger_configuration = DEBUGGER_THREADING;
acpi_gbl_db_output_flags = ACPI_DB_CONSOLE_OUTPUT;
+ acpi_gbl_osi_data = 0;
/* Hardware oriented */
diff --git a/drivers/acpi/acpica/utlock.c b/drivers/acpi/acpica/utlock.c
new file mode 100644
index 00000000000..25e03120686
--- /dev/null
+++ b/drivers/acpi/acpica/utlock.c
@@ -0,0 +1,175 @@
+/******************************************************************************
+ *
+ * Module Name: utlock - Reader/Writer lock interfaces
+ *
+ *****************************************************************************/
+
+/*
+ * Copyright (C) 2000 - 2009, Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ */
+
+#include <acpi/acpi.h>
+#include "accommon.h"
+
+#define _COMPONENT ACPI_UTILITIES
+ACPI_MODULE_NAME("utlock")
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_create_rw_lock
+ * acpi_ut_delete_rw_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
+ *
+ ******************************************************************************/
+acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ lock->num_readers = 0;
+ status = acpi_os_create_mutex(&lock->reader_mutex);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ status = acpi_os_create_mutex(&lock->writer_mutex);
+ return status;
+}
+
+void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
+{
+
+ acpi_os_delete_mutex(lock->reader_mutex);
+ acpi_os_delete_mutex(lock->writer_mutex);
+
+ lock->num_readers = 0;
+ lock->reader_mutex = NULL;
+ lock->writer_mutex = NULL;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_read_lock
+ * acpi_ut_release_read_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
+ * only the first reader acquires the write mutex. On release,
+ * only the last reader releases the write mutex. Although this
+ * algorithm can in theory starve writers, this should not be a
+ * problem with ACPICA since the subsystem is infrequently used
+ * in comparison to (for example) an I/O system.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /* Acquire the write lock only for the first reader */
+
+ lock->num_readers++;
+ if (lock->num_readers == 1) {
+ status =
+ acpi_os_acquire_mutex(lock->writer_mutex,
+ ACPI_WAIT_FOREVER);
+ }
+
+ acpi_os_release_mutex(lock->reader_mutex);
+ return status;
+}
+
+acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
+ if (ACPI_FAILURE(status)) {
+ return status;
+ }
+
+ /* Release the write lock only for the very last reader */
+
+ lock->num_readers--;
+ if (lock->num_readers == 0) {
+ acpi_os_release_mutex(lock->writer_mutex);
+ }
+
+ acpi_os_release_mutex(lock->reader_mutex);
+ return status;
+}
+
+/*******************************************************************************
+ *
+ * FUNCTION: acpi_ut_acquire_write_lock
+ * acpi_ut_release_write_lock
+ *
+ * PARAMETERS: Lock - Pointer to a valid RW lock
+ *
+ * RETURN: Status
+ *
+ * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
+ * release the writer mutex associated with the lock. Acquisition
+ * of the lock is fully exclusive and will block all readers and
+ * writers until it is released.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
+{
+ acpi_status status;
+
+ status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
+ return status;
+}
+
+void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
+{
+
+ acpi_os_release_mutex(lock->writer_mutex);
+}
diff --git a/drivers/acpi/acpica/utmisc.c b/drivers/acpi/acpica/utmisc.c
index c1f7f4e1a72..1c9e250caef 100644
--- a/drivers/acpi/acpica/utmisc.c
+++ b/drivers/acpi/acpica/utmisc.c
@@ -938,8 +938,7 @@ acpi_ut_walk_package_tree(union acpi_operand_object * source_object,
if ((!this_source_obj) ||
(ACPI_GET_DESCRIPTOR_TYPE(this_source_obj) !=
ACPI_DESC_TYPE_OPERAND)
- || (ACPI_GET_OBJECT_TYPE(this_source_obj) !=
- ACPI_TYPE_PACKAGE)) {
+ || (this_source_obj->common.type != ACPI_TYPE_PACKAGE)) {
status =
walk_callback(ACPI_COPY_TYPE_SIMPLE,
this_source_obj, state, context);
diff --git a/drivers/acpi/acpica/utmutex.c b/drivers/acpi/acpica/utmutex.c
index 14eb52c4d64..26c93a748e6 100644
--- a/drivers/acpi/acpica/utmutex.c
+++ b/drivers/acpi/acpica/utmutex.c
@@ -60,7 +60,8 @@ static acpi_status acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
*
* RETURN: Status
*
- * DESCRIPTION: Create the system mutex objects.
+ * DESCRIPTION: Create the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
*
******************************************************************************/
@@ -71,9 +72,8 @@ acpi_status acpi_ut_mutex_initialize(void)
ACPI_FUNCTION_TRACE(ut_mutex_initialize);
- /*
- * Create each of the predefined mutex objects
- */
+ /* Create each of the predefined mutex objects */
+
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
status = acpi_ut_create_mutex(i);
if (ACPI_FAILURE(status)) {
@@ -86,6 +86,9 @@ acpi_status acpi_ut_mutex_initialize(void)
spin_lock_init(acpi_gbl_gpe_lock);
spin_lock_init(acpi_gbl_hardware_lock);
+ /* Create the reader/writer lock for namespace access */
+
+ status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
return_ACPI_STATUS(status);
}
@@ -97,7 +100,8 @@ acpi_status acpi_ut_mutex_initialize(void)
*
* RETURN: None.
*
- * DESCRIPTION: Delete all of the system mutex objects.
+ * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
+ * spin locks, and reader/writer locks.
*
******************************************************************************/
@@ -107,9 +111,8 @@ void acpi_ut_mutex_terminate(void)
ACPI_FUNCTION_TRACE(ut_mutex_terminate);
- /*
- * Delete each predefined mutex object
- */
+ /* Delete each predefined mutex object */
+
for (i = 0; i < ACPI_NUM_MUTEX; i++) {
(void)acpi_ut_delete_mutex(i);
}
@@ -118,6 +121,10 @@ void acpi_ut_mutex_terminate(void)
acpi_os_delete_lock(acpi_gbl_gpe_lock);
acpi_os_delete_lock(acpi_gbl_hardware_lock);
+
+ /* Delete the reader/writer lock */
+
+ acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
return_VOID;
}
diff --git a/drivers/acpi/acpica/utobject.c b/drivers/acpi/acpica/utobject.c
index fd5ea7543e5..0207b625274 100644
--- a/drivers/acpi/acpica/utobject.c
+++ b/drivers/acpi/acpica/utobject.c
@@ -310,7 +310,7 @@ u8 acpi_ut_valid_internal_object(void *object)
/* Check for a null pointer */
if (!object) {
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "**** Null Object Ptr\n"));
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "**** Null Object Ptr\n"));
return (FALSE);
}
@@ -324,7 +324,7 @@ u8 acpi_ut_valid_internal_object(void *object)
return (TRUE);
default:
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
"%p is not not an ACPI operand obj [%s]\n",
object, acpi_ut_get_descriptor_name(object)));
break;
@@ -457,7 +457,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
* must be accessed bytewise or there may be alignment problems on
* certain processors
*/
- switch (ACPI_GET_OBJECT_TYPE(internal_object)) {
+ switch (internal_object->common.type) {
case ACPI_TYPE_STRING:
length += (acpi_size) internal_object->string.length + 1;
@@ -518,8 +518,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
ACPI_ERROR((AE_INFO, "Cannot convert to external object - "
"unsupported type [%s] %X in object %p",
acpi_ut_get_object_type_name(internal_object),
- ACPI_GET_OBJECT_TYPE(internal_object),
- internal_object));
+ internal_object->common.type, internal_object));
status = AE_TYPE;
break;
}
@@ -664,7 +663,7 @@ acpi_ut_get_object_size(union acpi_operand_object *internal_object,
if ((ACPI_GET_DESCRIPTOR_TYPE(internal_object) ==
ACPI_DESC_TYPE_OPERAND)
- && (ACPI_GET_OBJECT_TYPE(internal_object) == ACPI_TYPE_PACKAGE)) {
+ && (internal_object->common.type == ACPI_TYPE_PACKAGE)) {
status =
acpi_ut_get_package_object_size(internal_object,
obj_length);
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 69cbc57c2d1..b0de6312919 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/jiffies.h>
+#include <linux/async.h>
#ifdef CONFIG_ACPI_PROCFS_POWER
#include <linux/proc_fs.h>
@@ -92,7 +93,7 @@ struct acpi_battery {
#endif
struct acpi_device *device;
unsigned long update_time;
- int current_now;
+ int rate_now;
int capacity_now;
int voltage_now;
int design_capacity;
@@ -196,7 +197,8 @@ static int acpi_battery_get_property(struct power_supply *psy,
val->intval = battery->voltage_now * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = battery->current_now * 1000;
+ case POWER_SUPPLY_PROP_POWER_NOW:
+ val->intval = battery->rate_now * 1000;
break;
case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
@@ -247,6 +249,7 @@ static enum power_supply_property energy_battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
+ POWER_SUPPLY_PROP_POWER_NOW,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
POWER_SUPPLY_PROP_ENERGY_NOW,
@@ -273,7 +276,7 @@ struct acpi_offsets {
static struct acpi_offsets state_offsets[] = {
{offsetof(struct acpi_battery, state), 0},
- {offsetof(struct acpi_battery, current_now), 0},
+ {offsetof(struct acpi_battery, rate_now), 0},
{offsetof(struct acpi_battery, capacity_now), 0},
{offsetof(struct acpi_battery, voltage_now), 0},
};
@@ -605,11 +608,11 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)
else
seq_printf(seq, "charging state: charged\n");
- if (battery->current_now == ACPI_BATTERY_VALUE_UNKNOWN)
+ if (battery->rate_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "present rate: unknown\n");
else
seq_printf(seq, "present rate: %d %s\n",
- battery->current_now, acpi_battery_units(battery));
+ battery->rate_now, acpi_battery_units(battery));
if (battery->capacity_now == ACPI_BATTERY_VALUE_UNKNOWN)
seq_printf(seq, "remaining capacity: unknown\n");
@@ -740,7 +743,7 @@ DECLARE_FILE_FUNCTIONS(alarm);
static struct battery_file {
struct file_operations ops;
mode_t mode;
- char *name;
+ const char *name;
} acpi_battery_file[] = {
FILE_DESCRIPTION_RO(info),
FILE_DESCRIPTION_RO(state),
@@ -760,7 +763,6 @@ static int acpi_battery_add_fs(struct acpi_device *device)
acpi_battery_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
for (i = 0; i < ACPI_BATTERY_NUMFILES; ++i) {
@@ -901,21 +903,27 @@ static struct acpi_driver acpi_battery_driver = {
},
};
-static int __init acpi_battery_init(void)
+static void __init acpi_battery_init_async(void *unused, async_cookie_t cookie)
{
if (acpi_disabled)
- return -ENODEV;
+ return;
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_battery_dir = acpi_lock_battery_dir();
if (!acpi_battery_dir)
- return -ENODEV;
+ return;
#endif
if (acpi_bus_register_driver(&acpi_battery_driver) < 0) {
#ifdef CONFIG_ACPI_PROCFS_POWER
acpi_unlock_battery_dir(acpi_battery_dir);
#endif
- return -ENODEV;
+ return;
}
+ return;
+}
+
+static int __init acpi_battery_init(void)
+{
+ async_schedule(acpi_battery_init_async, NULL);
return 0;
}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index bee64b73c91..e8f7b64e92d 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,6 +39,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+#include "internal.h"
+
#define _COMPONENT ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("bus");
@@ -846,6 +848,7 @@ static int __init acpi_init(void)
acpi_kobj = NULL;
}
+ init_acpi_device_notify();
result = acpi_bus_init();
if (!result) {
@@ -860,11 +863,23 @@ static int __init acpi_init(void)
}
} else
disable_acpi();
+
+ if (acpi_disabled)
+ return result;
+
/*
* If the laptop falls into the DMI check table, the power state check
* will be disabled in the course of device power transistion.
*/
dmi_check_system(power_nocheck_dmi_table);
+
+ acpi_scan_init();
+ acpi_ec_init();
+ acpi_power_init();
+ acpi_system_init();
+ acpi_debug_init();
+ acpi_sleep_proc_init();
+ acpi_wakeup_device_init();
return result;
}
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 171fd914f43..d73c94b8441 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
static int acpi_button_add(struct acpi_device *device);
static int acpi_button_remove(struct acpi_device *device, int type);
static int acpi_button_resume(struct acpi_device *device);
+static void acpi_button_notify(struct acpi_device *device, u32 event);
static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
@@ -89,6 +90,7 @@ static struct acpi_driver acpi_button_driver = {
.add = acpi_button_add,
.resume = acpi_button_resume,
.remove = acpi_button_remove,
+ .notify = acpi_button_notify,
},
};
@@ -200,12 +202,10 @@ static int acpi_button_add_fs(struct acpi_device *device)
if (!entry)
return -ENODEV;
- entry->owner = THIS_MODULE;
acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), entry);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
/* 'info' [R] */
entry = proc_create_data(ACPI_BUTTON_FILE_INFO,
@@ -265,15 +265,18 @@ static int acpi_lid_send_state(struct acpi_button *button)
return 0;
}
-static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_button_notify(struct acpi_device *device, u32 event)
{
- struct acpi_button *button = data;
+ struct acpi_button *button = acpi_driver_data(device);
struct input_dev *input;
if (!button || !button->device)
return;
switch (event) {
+ case ACPI_FIXED_HARDWARE_EVENT:
+ event = ACPI_BUTTON_NOTIFY_STATUS;
+ /* fall through */
case ACPI_BUTTON_NOTIFY_STATUS:
input = button->input;
if (button->type == ACPI_BUTTON_TYPE_LID) {
@@ -300,46 +303,6 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
return;
}
-static acpi_status acpi_button_notify_fixed(void *data)
-{
- struct acpi_button *button = data;
-
- if (!button)
- return AE_BAD_PARAMETER;
-
- acpi_button_notify(button->device->handle, ACPI_BUTTON_NOTIFY_STATUS, button);
-
- return AE_OK;
-}
-
-static int acpi_button_install_notify_handlers(struct acpi_button *button)
-{
- acpi_status status;
-
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWERF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed,
- button);
- break;
- case ACPI_BUTTON_TYPE_SLEEPF:
- status =
- acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed,
- button);
- break;
- default:
- status = acpi_install_notify_handler(button->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify,
- button);
- break;
- }
-
- return ACPI_FAILURE(status) ? -ENODEV : 0;
-}
-
static int acpi_button_resume(struct acpi_device *device)
{
struct acpi_button *button;
@@ -351,25 +314,6 @@ static int acpi_button_resume(struct acpi_device *device)
return 0;
}
-static void acpi_button_remove_notify_handlers(struct acpi_button *button)
-{
- switch (button->type) {
- case ACPI_BUTTON_TYPE_POWERF:
- acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
- acpi_button_notify_fixed);
- break;
- case ACPI_BUTTON_TYPE_SLEEPF:
- acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
- acpi_button_notify_fixed);
- break;
- default:
- acpi_remove_notify_handler(button->device->handle,
- ACPI_DEVICE_NOTIFY,
- acpi_button_notify);
- break;
- }
-}
-
static int acpi_button_add(struct acpi_device *device)
{
int error;
@@ -434,10 +378,6 @@ static int acpi_button_add(struct acpi_device *device)
if (error)
goto err_free_input;
- error = acpi_button_install_notify_handlers(button);
- if (error)
- goto err_remove_fs;
-
snprintf(button->phys, sizeof(button->phys),
"%s/button/input0", acpi_device_hid(device));
@@ -468,7 +408,7 @@ static int acpi_button_add(struct acpi_device *device)
error = input_register_device(input);
if (error)
- goto err_remove_handlers;
+ goto err_remove_fs;
if (button->type == ACPI_BUTTON_TYPE_LID)
acpi_lid_send_state(button);
@@ -487,8 +427,6 @@ static int acpi_button_add(struct acpi_device *device)
return 0;
- err_remove_handlers:
- acpi_button_remove_notify_handlers(button);
err_remove_fs:
acpi_button_remove_fs(device);
err_free_input:
@@ -507,7 +445,6 @@ static int acpi_button_remove(struct acpi_device *device, int type)
button = acpi_driver_data(device);
- acpi_button_remove_notify_handlers(button);
acpi_button_remove_fs(device);
input_unregister_device(button->input);
kfree(button);
@@ -522,7 +459,6 @@ static int __init acpi_button_init(void)
acpi_button_dir = proc_mkdir(ACPI_BUTTON_CLASS, acpi_root_dir);
if (!acpi_button_dir)
return -ENODEV;
- acpi_button_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&acpi_button_driver);
if (result < 0) {
remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index 20223cbd0d1..a8287be0870 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -13,11 +13,6 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("debug");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
-
struct acpi_dlayer {
const char *name;
unsigned long value;
@@ -297,17 +292,15 @@ acpi_system_write_debug(struct file *file,
return count;
}
+#endif
-static int __init acpi_debug_init(void)
+int __init acpi_debug_init(void)
{
+#ifdef CONFIG_ACPI_PROCFS
struct proc_dir_entry *entry;
int error = 0;
char *name;
-
- if (acpi_disabled)
- return 0;
-
/* 'debug_layer' [R/W] */
name = ACPI_SYSTEM_FILE_DEBUG_LAYER;
entry =
@@ -338,7 +331,7 @@ static int __init acpi_debug_init(void)
remove_proc_entry(ACPI_SYSTEM_FILE_DEBUG_LAYER, acpi_root_dir);
error = -ENODEV;
goto Done;
-}
-
-subsys_initcall(acpi_debug_init);
+#else
+ return 0;
#endif
+}
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 7af7db1ba8c..efb959d6c8a 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -1146,9 +1146,10 @@ static int __init dock_init(void)
static void __exit dock_exit(void)
{
struct dock_station *dock_station;
+ struct dock_station *tmp;
unregister_acpi_bus_notifier(&dock_acpi_notifier);
- list_for_each_entry(dock_station, &dock_stations, sibiling)
+ list_for_each_entry_safe(dock_station, tmp, &dock_stations, sibiling)
dock_remove(dock_station);
}
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 2fe15060dcd..04e90443eff 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -67,7 +67,7 @@ enum ec_command {
#define ACPI_EC_DELAY 500 /* Wait 500ms max. during EC ops */
#define ACPI_EC_UDELAY_GLK 1000 /* Wait 1ms max. to get global lock */
-#define ACPI_EC_UDELAY 100 /* Wait 100us before polling EC again */
+#define ACPI_EC_CDELAY 10 /* Wait 10us before polling EC */
#define ACPI_EC_STORM_THRESHOLD 8 /* number of false interrupts
per one transaction */
@@ -236,13 +236,23 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
return 0;
}
+static void ec_delay(void)
+{
+ /* EC in MSI notebooks don't tolerate delays other than 550 usec */
+ if (EC_FLAGS_MSI)
+ udelay(ACPI_EC_DELAY);
+ else
+ /* Use shortest sleep available */
+ msleep(1);
+}
+
static int ec_poll(struct acpi_ec *ec)
{
unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
- udelay(ACPI_EC_UDELAY);
+ udelay(ACPI_EC_CDELAY);
while (time_before(jiffies, delay)) {
gpe_transaction(ec, acpi_ec_read_status(ec));
- udelay(ACPI_EC_UDELAY);
+ ec_delay();
if (ec_transaction_done(ec))
return 0;
}
@@ -672,7 +682,7 @@ static int acpi_ec_info_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_ec_read_info, PDE(inode)->data);
}
-static struct file_operations acpi_ec_info_ops = {
+static const struct file_operations acpi_ec_info_ops = {
.open = acpi_ec_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -755,6 +765,10 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
unsigned long long tmp = 0;
struct acpi_ec *ec = context;
+
+ /* clear addr values, ec_parse_io_ports depend on it */
+ ec->command_addr = ec->data_addr = 0;
+
status = acpi_walk_resources(handle, METHOD_NAME__CRS,
ec_parse_io_ports, ec);
if (ACPI_FAILURE(status))
@@ -804,11 +818,11 @@ static int acpi_ec_add(struct acpi_device *device)
ec = make_acpi_ec();
if (!ec)
return -ENOMEM;
- if (ec_parse_device(device->handle, 0, ec, NULL) !=
- AE_CTRL_TERMINATE) {
+ }
+ if (ec_parse_device(device->handle, 0, ec, NULL) !=
+ AE_CTRL_TERMINATE) {
kfree(ec);
return -EINVAL;
- }
}
ec->handle = device->handle;
@@ -986,12 +1000,12 @@ int __init acpi_ec_ecdt_probe(void)
boot_ec->handle = ACPI_ROOT_OBJECT;
acpi_get_handle(ACPI_ROOT_OBJECT, ecdt_ptr->id, &boot_ec->handle);
/* Don't trust ECDT, which comes from ASUSTek */
- if (!dmi_name_in_vendors("ASUS"))
+ if (!dmi_name_in_vendors("ASUS") && EC_FLAGS_MSI == 0)
goto install;
saved_ec = kmalloc(sizeof(struct acpi_ec), GFP_KERNEL);
if (!saved_ec)
return -ENOMEM;
- memcpy(saved_ec, boot_ec, sizeof(*saved_ec));
+ memcpy(saved_ec, boot_ec, sizeof(struct acpi_ec));
/* fall through */
}
/* This workaround is needed only on some broken machines,
@@ -1069,13 +1083,10 @@ static struct acpi_driver acpi_ec_driver = {
},
};
-static int __init acpi_ec_init(void)
+int __init acpi_ec_init(void)
{
int result = 0;
- if (acpi_disabled)
- return 0;
-
acpi_ec_dir = proc_mkdir(ACPI_EC_CLASS, acpi_root_dir);
if (!acpi_ec_dir)
return -ENODEV;
@@ -1090,8 +1101,6 @@ static int __init acpi_ec_init(void)
return result;
}
-subsys_initcall(acpi_ec_init);
-
/* EC driver currently not unloadable */
#if 0
static void __exit acpi_ec_exit(void)
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index eaaee1660bd..53698ea0837 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -68,31 +68,35 @@ static struct acpi_driver acpi_fan_driver = {
};
/* thermal cooling device callbacks */
-static int fan_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_max_state(struct thermal_cooling_device *cdev, unsigned long
+ *state)
{
/* ACPI fan device only support two states: ON/OFF */
- return sprintf(buf, "1\n");
+ *state = 1;
+ return 0;
}
-static int fan_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long
+ *state)
{
struct acpi_device *device = cdev->devdata;
- int state;
int result;
+ int acpi_state;
if (!device)
return -EINVAL;
- result = acpi_bus_get_power(device->handle, &state);
+ result = acpi_bus_get_power(device->handle, &acpi_state);
if (result)
return result;
- return sprintf(buf, "%s\n", state == ACPI_STATE_D3 ? "0" :
- (state == ACPI_STATE_D0 ? "1" : "unknown"));
+ *state = (acpi_state == ACPI_STATE_D3 ? 0 :
+ (acpi_state == ACPI_STATE_D0 ? 1 : -1));
+ return 0;
}
static int
-fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+fan_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct acpi_device *device = cdev->devdata;
int result;
@@ -193,7 +197,6 @@ static int acpi_fan_add_fs(struct acpi_device *device)
acpi_fan_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
/* 'status' [R/W] */
@@ -347,7 +350,6 @@ static int __init acpi_fan_init(void)
acpi_fan_dir = proc_mkdir(ACPI_FAN_CLASS, acpi_root_dir);
if (!acpi_fan_dir)
return -ENODEV;
- acpi_fan_dir->owner = THIS_MODULE;
#endif
result = acpi_bus_register_driver(&acpi_fan_driver);
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 5479b9f4251..8bd2c2a6884 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -286,10 +286,8 @@ static int acpi_platform_notify_remove(struct device *dev)
return 0;
}
-static int __init init_acpi_device_notify(void)
+int __init init_acpi_device_notify(void)
{
- if (acpi_disabled)
- return 0;
if (platform_notify || platform_notify_remove) {
printk(KERN_ERR PREFIX "Can't use platform_notify\n");
return 0;
@@ -298,5 +296,3 @@ static int __init init_acpi_device_notify(void)
platform_notify_remove = acpi_platform_notify_remove;
return 0;
}
-
-arch_initcall(init_acpi_device_notify);
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h
new file mode 100644
index 00000000000..11a69b53004
--- /dev/null
+++ b/drivers/acpi/internal.h
@@ -0,0 +1,43 @@
+/* For use by Linux/ACPI infrastructure, not drivers */
+
+int init_acpi_device_notify(void);
+int acpi_scan_init(void);
+int acpi_system_init(void);
+
+#ifdef CONFIG_ACPI_DEBUG
+int acpi_debug_init(void);
+#else
+static inline int acpi_debug_init(void) { return 0; }
+#endif
+
+/* --------------------------------------------------------------------------
+ Power Resource
+ -------------------------------------------------------------------------- */
+int acpi_power_init(void);
+int acpi_device_sleep_wake(struct acpi_device *dev,
+ int enable, int sleep_state, int dev_state);
+int acpi_enable_wakeup_device_power(struct acpi_device *dev, int sleep_state);
+int acpi_disable_wakeup_device_power(struct acpi_device *dev);
+int acpi_power_get_inferred_state(struct acpi_device *device);
+int acpi_power_transition(struct acpi_device *device, int state);
+extern int acpi_power_nocheck;
+
+int acpi_wakeup_device_init(void);
+
+/* --------------------------------------------------------------------------
+ Embedded Controller
+ -------------------------------------------------------------------------- */
+int acpi_ec_init(void);
+int acpi_ec_ecdt_probe(void);
+int acpi_boot_ec_enable(void);
+
+/*--------------------------------------------------------------------------
+ Suspend/Resume
+ -------------------------------------------------------------------------- */
+extern int acpi_sleep_init(void);
+
+#ifdef CONFIG_ACPI_SLEEP
+int acpi_sleep_proc_init(void);
+#else
+static inline int acpi_sleep_proc_init(void) { return 0; }
+#endif
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 3a0d8ef25c7..d440ccd27d9 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -131,6 +131,21 @@ acpi_table_print_srat_entry(struct acpi_subtable_header *header)
#endif /* ACPI_DEBUG_OUTPUT */
break;
+ case ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+ {
+ struct acpi_srat_x2apic_cpu_affinity *p =
+ (struct acpi_srat_x2apic_cpu_affinity *)header;
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "SRAT Processor (x2apicid[0x%08x]) in"
+ " proximity domain %d %s\n",
+ p->apic_id,
+ p->proximity_domain,
+ (p->flags & ACPI_SRAT_CPU_ENABLED) ?
+ "enabled" : "disabled"));
+ }
+#endif /* ACPI_DEBUG_OUTPUT */
+ break;
default:
printk(KERN_WARNING PREFIX
"Found unsupported SRAT entry (type = 0x%x)\n",
@@ -180,8 +195,35 @@ static int __init acpi_parse_slit(struct acpi_table_header *table)
return 0;
}
+void __init __attribute__ ((weak))
+acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
+{
+ printk(KERN_WARNING PREFIX
+ "Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
+ return;
+}
+
+
+static int __init
+acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
+ const unsigned long end)
+{
+ struct acpi_srat_x2apic_cpu_affinity *processor_affinity;
+
+ processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header;
+ if (!processor_affinity)
+ return -EINVAL;
+
+ acpi_table_print_srat_entry(header);
+
+ /* let architecture-dependent part to do it */
+ acpi_numa_x2apic_affinity_init(processor_affinity);
+
+ return 0;
+}
+
static int __init
-acpi_parse_processor_affinity(struct acpi_subtable_header * header,
+acpi_parse_processor_affinity(struct acpi_subtable_header *header,
const unsigned long end)
{
struct acpi_srat_cpu_affinity *processor_affinity;
@@ -241,6 +283,8 @@ int __init acpi_numa_init(void)
{
/* SRAT: Static Resource Affinity Table */
if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
+ acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
+ acpi_parse_x2apic_affinity, NR_CPUS);
acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
acpi_parse_processor_affinity, NR_CPUS);
acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index eb8980d6736..d59f08ecaf1 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1070,9 +1070,9 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
* in arbitrary AML code and can interfere with legacy drivers.
* acpi_enforce_resources= can be set to:
*
- * - strict (2)
+ * - strict (default) (2)
* -> further driver trying to access the resources will not load
- * - lax (default) (1)
+ * - lax (1)
* -> further driver trying to access the resources will load, but you
* get a system message that something might go wrong...
*
@@ -1084,7 +1084,7 @@ __setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
#define ENFORCE_RESOURCES_LAX 1
#define ENFORCE_RESOURCES_NO 0
-static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_LAX;
+static unsigned int acpi_enforce_resources = ENFORCE_RESOURCES_STRICT;
static int __init acpi_enforce_resources_setup(char *str)
{
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 891bdf6679f..51b9f8280f8 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -86,7 +86,7 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(struct pci_dev *dev,
}
/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
-static struct dmi_system_id medion_md9580[] = {
+static const struct dmi_system_id medion_md9580[] = {
{
.ident = "Medion MD9580-F laptop",
.matches = {
@@ -98,7 +98,7 @@ static struct dmi_system_id medion_md9580[] = {
};
/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
-static struct dmi_system_id dell_optiplex[] = {
+static const struct dmi_system_id dell_optiplex[] = {
{
.ident = "Dell Optiplex GX1",
.matches = {
@@ -110,7 +110,7 @@ static struct dmi_system_id dell_optiplex[] = {
};
/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
-static struct dmi_system_id hp_t5710[] = {
+static const struct dmi_system_id hp_t5710[] = {
{
.ident = "HP t5710",
.matches = {
@@ -123,13 +123,13 @@ static struct dmi_system_id hp_t5710[] = {
};
struct prt_quirk {
- struct dmi_system_id *system;
+ const struct dmi_system_id *system;
unsigned int segment;
unsigned int bus;
unsigned int device;
unsigned char pin;
- char *source; /* according to BIOS */
- char *actual_source;
+ const char *source; /* according to BIOS */
+ const char *actual_source;
};
#define PCI_INTX_PIN(c) (c - 'A' + 1)
@@ -139,7 +139,7 @@ struct prt_quirk {
* interrupt at the listed segment/bus/device/pin is connected to the first
* link device, but it is actually connected to the second.
*/
-static struct prt_quirk prt_quirks[] = {
+static const struct prt_quirk prt_quirks[] = {
{ medion_md9580, 0, 0, 9, PCI_INTX_PIN('A'),
"\\_SB_.PCI0.ISA_.LNKA",
"\\_SB_.PCI0.ISA_.LNKB"},
@@ -155,7 +155,7 @@ static void do_prt_fixups(struct acpi_prt_entry *entry,
struct acpi_pci_routing_table *prt)
{
int i;
- struct prt_quirk *quirk;
+ const struct prt_quirk *quirk;
for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
quirk = &prt_quirks[i];
@@ -319,7 +319,7 @@ static struct acpi_prt_entry *acpi_pci_irq_lookup(struct pci_dev *dev, int pin)
*/
bridge = dev->bus->self;
while (bridge) {
- pin = (((pin - 1) + PCI_SLOT(dev->devfn)) % 4) + 1;
+ pin = pci_swizzle_interrupt_pin(dev, pin);
if ((bridge->class >> 8) == PCI_CLASS_BRIDGE_CARDBUS) {
/* PC card has the same IRQ as its cardbridge */
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 6c772ca76bd..16e0f9d3d17 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -43,13 +43,14 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
-#define _COMPONENT ACPI_PCI_COMPONENT
+#define _COMPONENT ACPI_PCI_COMPONENT
ACPI_MODULE_NAME("pci_link");
#define ACPI_PCI_LINK_CLASS "pci_irq_routing"
#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
#define ACPI_PCI_LINK_FILE_INFO "info"
#define ACPI_PCI_LINK_FILE_STATUS "state"
-#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+#define ACPI_PCI_LINK_MAX_POSSIBLE 16
+
static int acpi_pci_link_add(struct acpi_device *device);
static int acpi_pci_link_remove(struct acpi_device *device, int type);
@@ -66,7 +67,7 @@ static struct acpi_driver acpi_pci_link_driver = {
.ops = {
.add = acpi_pci_link_add,
.remove = acpi_pci_link_remove,
- },
+ },
};
/*
@@ -76,7 +77,7 @@ static struct acpi_driver acpi_pci_link_driver = {
struct acpi_pci_link_irq {
u8 active; /* Current IRQ */
u8 triggering; /* All IRQs */
- u8 polarity; /* All IRQs */
+ u8 polarity; /* All IRQs */
u8 resource_type;
u8 possible_count;
u8 possible[ACPI_PCI_LINK_MAX_POSSIBLE];
@@ -85,16 +86,13 @@ struct acpi_pci_link_irq {
};
struct acpi_pci_link {
- struct list_head node;
- struct acpi_device *device;
- struct acpi_pci_link_irq irq;
- int refcnt;
+ struct list_head list;
+ struct acpi_device *device;
+ struct acpi_pci_link_irq irq;
+ int refcnt;
};
-static struct {
- int count;
- struct list_head entries;
-} acpi_link;
+static LIST_HEAD(acpi_link_list);
static DEFINE_MUTEX(acpi_link_lock);
/* --------------------------------------------------------------------------
@@ -104,12 +102,11 @@ static DEFINE_MUTEX(acpi_link_lock);
/*
* set context (link) possible list from resource list
*/
-static acpi_status
-acpi_pci_link_check_possible(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_possible(struct acpi_resource *resource,
+ void *context)
{
struct acpi_pci_link *link = context;
- u32 i = 0;
-
+ u32 i;
switch (resource->type) {
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -179,10 +176,6 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
{
acpi_status status;
-
- if (!link)
- return -EINVAL;
-
status = acpi_walk_resources(link->device->handle, METHOD_NAME__PRS,
acpi_pci_link_check_possible, link);
if (ACPI_FAILURE(status)) {
@@ -197,11 +190,10 @@ static int acpi_pci_link_get_possible(struct acpi_pci_link *link)
return 0;
}
-static acpi_status
-acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
+static acpi_status acpi_pci_link_check_current(struct acpi_resource *resource,
+ void *context)
{
- int *irq = (int *)context;
-
+ int *irq = context;
switch (resource->type) {
case ACPI_RESOURCE_TYPE_START_DEPENDENT:
@@ -258,12 +250,9 @@ acpi_pci_link_check_current(struct acpi_resource *resource, void *context)
static int acpi_pci_link_get_current(struct acpi_pci_link *link)
{
int result = 0;
- acpi_status status = AE_OK;
+ acpi_status status;
int irq = 0;
- if (!link)
- return -EINVAL;
-
link->irq.active = 0;
/* in practice, status disabled is meaningless, ignore it */
@@ -308,16 +297,15 @@ static int acpi_pci_link_get_current(struct acpi_pci_link *link)
static int acpi_pci_link_set(struct acpi_pci_link *link, int irq)
{
- int result = 0;
- acpi_status status = AE_OK;
+ int result;
+ acpi_status status;
struct {
struct acpi_resource res;
struct acpi_resource end;
} *resource;
struct acpi_buffer buffer = { 0, NULL };
-
- if (!link || !irq)
+ if (!irq)
return -EINVAL;
resource = kzalloc(sizeof(*resource) + 1, irqs_disabled() ? GFP_ATOMIC: GFP_KERNEL);
@@ -479,30 +467,22 @@ static int acpi_irq_penalty[ACPI_MAX_IRQS] = {
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ9 PCI, often acpi */
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ10 PCI */
PIRQ_PENALTY_PCI_AVAILABLE, /* IRQ11 PCI */
- PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
- PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
- PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
- PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
+ PIRQ_PENALTY_ISA_USED, /* IRQ12 mouse */
+ PIRQ_PENALTY_ISA_USED, /* IRQ13 fpe, sometimes */
+ PIRQ_PENALTY_ISA_USED, /* IRQ14 ide0 */
+ PIRQ_PENALTY_ISA_USED, /* IRQ15 ide1 */
/* >IRQ15 */
};
int __init acpi_irq_penalty_init(void)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
- int i = 0;
-
+ struct acpi_pci_link *link;
+ int i;
/*
* Update penalties to facilitate IRQ balancing.
*/
- list_for_each(node, &acpi_link.entries) {
-
- link = list_entry(node, struct acpi_pci_link, node);
- if (!link) {
- printk(KERN_ERR PREFIX "Invalid link context\n");
- continue;
- }
+ list_for_each_entry(link, &acpi_link_list, list) {
/*
* reflect the possible and active irqs in the penalty table --
@@ -527,7 +507,6 @@ int __init acpi_irq_penalty_init(void)
}
/* Add a penalty for the SCI */
acpi_irq_penalty[acpi_gbl_FADT.sci_interrupt] += PIRQ_PENALTY_PCI_USING;
-
return 0;
}
@@ -538,7 +517,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
int irq;
int i;
-
if (link->irq.initialized) {
if (link->refcnt == 0)
/* This means the link is disabled but initialized */
@@ -566,11 +544,10 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
/*
* if active found, use it; else pick entry from end of possible list.
*/
- if (link->irq.active) {
+ if (link->irq.active)
irq = link->irq.active;
- } else {
+ else
irq = link->irq.possible[link->irq.possible_count - 1];
- }
if (acpi_irq_balance || !link->irq.active) {
/*
@@ -599,7 +576,6 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
}
link->irq.initialized = 1;
-
return 0;
}
@@ -608,16 +584,12 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
* success: return IRQ >= 0
* failure: return -1
*/
-
-int
-acpi_pci_link_allocate_irq(acpi_handle handle,
- int index,
- int *triggering, int *polarity, char **name)
+int acpi_pci_link_allocate_irq(acpi_handle handle, int index, int *triggering,
+ int *polarity, char **name)
{
- int result = 0;
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
-
+ int result;
+ struct acpi_device *device;
+ struct acpi_pci_link *link;
result = acpi_bus_get_device(handle, &device);
if (result) {
@@ -669,11 +641,10 @@ acpi_pci_link_allocate_irq(acpi_handle handle,
*/
int acpi_pci_link_free_irq(acpi_handle handle)
{
- struct acpi_device *device = NULL;
- struct acpi_pci_link *link = NULL;
+ struct acpi_device *device;
+ struct acpi_pci_link *link;
acpi_status result;
-
result = acpi_bus_get_device(handle, &device);
if (result) {
printk(KERN_ERR PREFIX "Invalid link device\n");
@@ -708,9 +679,9 @@ int acpi_pci_link_free_irq(acpi_handle handle)
"Link %s is dereferenced\n",
acpi_device_bid(link->device)));
- if (link->refcnt == 0) {
+ if (link->refcnt == 0)
acpi_evaluate_object(link->device->handle, "_DIS", NULL, NULL);
- }
+
mutex_unlock(&acpi_link_lock);
return (link->irq.active);
}
@@ -721,15 +692,11 @@ int acpi_pci_link_free_irq(acpi_handle handle)
static int acpi_pci_link_add(struct acpi_device *device)
{
- int result = 0;
- struct acpi_pci_link *link = NULL;
- int i = 0;
+ int result;
+ struct acpi_pci_link *link;
+ int i;
int found = 0;
-
- if (!device)
- return -EINVAL;
-
link = kzalloc(sizeof(struct acpi_pci_link), GFP_KERNEL);
if (!link)
return -ENOMEM;
@@ -767,9 +734,7 @@ static int acpi_pci_link_add(struct acpi_device *device)
printk("\n");
- /* TBD: Acquire/release lock */
- list_add_tail(&link->node, &acpi_link.entries);
- acpi_link.count++;
+ list_add_tail(&link->list, &acpi_link_list);
end:
/* disable all links -- to be activated on use */
@@ -784,24 +749,17 @@ static int acpi_pci_link_add(struct acpi_device *device)
static int acpi_pci_link_resume(struct acpi_pci_link *link)
{
-
if (link->refcnt && link->irq.active && link->irq.initialized)
return (acpi_pci_link_set(link, link->irq.active));
- else
- return 0;
+
+ return 0;
}
static int irqrouter_resume(struct sys_device *dev)
{
- struct list_head *node = NULL;
- struct acpi_pci_link *link = NULL;
+ struct acpi_pci_link *link;
- list_for_each(node, &acpi_link.entries) {
- link = list_entry(node, struct acpi_pci_link, node);
- if (!link) {
- printk(KERN_ERR PREFIX "Invalid link context\n");
- continue;
- }
+ list_for_each_entry(link, &acpi_link_list, list) {
acpi_pci_link_resume(link);
}
return 0;
@@ -809,20 +767,15 @@ static int irqrouter_resume(struct sys_device *dev)
static int acpi_pci_link_remove(struct acpi_device *device, int type)
{
- struct acpi_pci_link *link = NULL;
-
-
- if (!device || !acpi_driver_data(device))
- return -EINVAL;
+ struct acpi_pci_link *link;
link = acpi_driver_data(device);
mutex_lock(&acpi_link_lock);
- list_del(&link->node);
+ list_del(&link->list);
mutex_unlock(&acpi_link_lock);
kfree(link);
-
return 0;
}
@@ -931,7 +884,6 @@ static int __init irqrouter_init_sysfs(void)
{
int error;
-
if (acpi_disabled || acpi_noirq)
return 0;
@@ -957,9 +909,6 @@ static int __init acpi_pci_link_init(void)
acpi_irq_balance = 0;
}
- acpi_link.count = 0;
- INIT_LIST_HEAD(&acpi_link.entries);
-
if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0)
return -ENODEV;
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 5b38a026d12..196f97d0095 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -66,11 +66,18 @@ struct acpi_pci_root {
struct acpi_device * device;
struct acpi_pci_id id;
struct pci_bus *bus;
+
+ u32 osc_support_set; /* _OSC state of support bits */
+ u32 osc_control_set; /* _OSC state of control bits */
+ u32 osc_control_qry; /* the latest _OSC query result */
+
+ u32 osc_queried:1; /* has _OSC control been queried? */
};
static LIST_HEAD(acpi_pci_roots);
static struct acpi_pci_driver *sub_driver;
+static DEFINE_MUTEX(osc_lock);
int acpi_pci_register_driver(struct acpi_pci_driver *driver)
{
@@ -185,6 +192,175 @@ static void acpi_pci_bridge_scan(struct acpi_device *device)
}
}
+static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
+ 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
+
+static acpi_status acpi_pci_run_osc(acpi_handle handle,
+ const u32 *capbuf, u32 *retval)
+{
+ acpi_status status;
+ struct acpi_object_list input;
+ union acpi_object in_params[4];
+ struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
+ union acpi_object *out_obj;
+ u32 errors;
+
+ /* Setting up input parameters */
+ input.count = 4;
+ input.pointer = in_params;
+ in_params[0].type = ACPI_TYPE_BUFFER;
+ in_params[0].buffer.length = 16;
+ in_params[0].buffer.pointer = OSC_UUID;
+ in_params[1].type = ACPI_TYPE_INTEGER;
+ in_params[1].integer.value = 1;
+ in_params[2].type = ACPI_TYPE_INTEGER;
+ in_params[2].integer.value = 3;
+ in_params[3].type = ACPI_TYPE_BUFFER;
+ in_params[3].buffer.length = 12;
+ in_params[3].buffer.pointer = (u8 *)capbuf;
+
+ status = acpi_evaluate_object(handle, "_OSC", &input, &output);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ if (!output.length)
+ return AE_NULL_OBJECT;
+
+ out_obj = output.pointer;
+ if (out_obj->type != ACPI_TYPE_BUFFER) {
+ printk(KERN_DEBUG "_OSC evaluation returned wrong type\n");
+ status = AE_TYPE;
+ goto out_kfree;
+ }
+ /* Need to ignore the bit0 in result code */
+ errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
+ if (errors) {
+ if (errors & OSC_REQUEST_ERROR)
+ printk(KERN_DEBUG "_OSC request failed\n");
+ if (errors & OSC_INVALID_UUID_ERROR)
+ printk(KERN_DEBUG "_OSC invalid UUID\n");
+ if (errors & OSC_INVALID_REVISION_ERROR)
+ printk(KERN_DEBUG "_OSC invalid revision\n");
+ if (errors & OSC_CAPABILITIES_MASK_ERROR) {
+ if (capbuf[OSC_QUERY_TYPE] & OSC_QUERY_ENABLE)
+ goto out_success;
+ printk(KERN_DEBUG
+ "Firmware did not grant requested _OSC control\n");
+ status = AE_SUPPORT;
+ goto out_kfree;
+ }
+ status = AE_ERROR;
+ goto out_kfree;
+ }
+out_success:
+ *retval = *((u32 *)(out_obj->buffer.pointer + 8));
+ status = AE_OK;
+
+out_kfree:
+ kfree(output.pointer);
+ return status;
+}
+
+static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags)
+{
+ acpi_status status;
+ u32 support_set, result, capbuf[3];
+
+ /* do _OSC query for all possible controls */
+ support_set = root->osc_support_set | (flags & OSC_SUPPORT_MASKS);
+ capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
+ capbuf[OSC_SUPPORT_TYPE] = support_set;
+ capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
+
+ status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
+ if (ACPI_SUCCESS(status)) {
+ root->osc_support_set = support_set;
+ root->osc_control_qry = result;
+ root->osc_queried = 1;
+ }
+ return status;
+}
+
+static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
+{
+ acpi_status status;
+ acpi_handle tmp;
+
+ status = acpi_get_handle(root->device->handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+ mutex_lock(&osc_lock);
+ status = acpi_pci_query_osc(root, flags);
+ mutex_unlock(&osc_lock);
+ return status;
+}
+
+static struct acpi_pci_root *acpi_pci_find_root(acpi_handle handle)
+{
+ struct acpi_pci_root *root;
+ list_for_each_entry(root, &acpi_pci_roots, node) {
+ if (root->device->handle == handle)
+ return root;
+ }
+ return NULL;
+}
+
+/**
+ * acpi_pci_osc_control_set - commit requested control to Firmware
+ * @handle: acpi_handle for the target ACPI object
+ * @flags: driver's requested control bits
+ *
+ * Attempt to take control from Firmware on requested control bits.
+ **/
+acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags)
+{
+ acpi_status status;
+ u32 control_req, result, capbuf[3];
+ acpi_handle tmp;
+ struct acpi_pci_root *root;
+
+ status = acpi_get_handle(handle, "_OSC", &tmp);
+ if (ACPI_FAILURE(status))
+ return status;
+
+ control_req = (flags & OSC_CONTROL_MASKS);
+ if (!control_req)
+ return AE_TYPE;
+
+ root = acpi_pci_find_root(handle);
+ if (!root)
+ return AE_NOT_EXIST;
+
+ mutex_lock(&osc_lock);
+ /* No need to evaluate _OSC if the control was already granted. */
+ if ((root->osc_control_set & control_req) == control_req)
+ goto out;
+
+ /* Need to query controls first before requesting them */
+ if (!root->osc_queried) {
+ status = acpi_pci_query_osc(root, root->osc_support_set);
+ if (ACPI_FAILURE(status))
+ goto out;
+ }
+ if ((root->osc_control_qry & control_req) != control_req) {
+ printk(KERN_DEBUG
+ "Firmware did not grant requested _OSC control\n");
+ status = AE_SUPPORT;
+ goto out;
+ }
+
+ capbuf[OSC_QUERY_TYPE] = 0;
+ capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
+ capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req;
+ status = acpi_pci_run_osc(handle, capbuf, &result);
+ if (ACPI_SUCCESS(status))
+ root->osc_control_set = result;
+out:
+ mutex_unlock(&osc_lock);
+ return status;
+}
+EXPORT_SYMBOL(acpi_pci_osc_control_set);
+
static int __devinit acpi_pci_root_add(struct acpi_device *device)
{
int result = 0;
@@ -217,7 +393,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
* PCI domains, so we indicate this in _OSC support capabilities.
*/
flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
- pci_acpi_osc_support(device->handle, flags);
+ acpi_pci_osc_support(root, flags);
/*
* Segment
@@ -353,7 +529,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
if (pci_msi_enabled())
flags |= OSC_MSI_SUPPORT;
if (flags != base_flags)
- pci_acpi_osc_support(device->handle, flags);
+ acpi_pci_osc_support(root, flags);
end:
if (result) {
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index c926e7d4a0d..56665a63bf1 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -54,10 +54,6 @@ ACPI_MODULE_NAME("power");
#define ACPI_POWER_RESOURCE_STATE_ON 0x01
#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
int acpi_power_nocheck;
module_param_named(power_nocheck, acpi_power_nocheck, bool, 000);
@@ -773,14 +769,10 @@ static int acpi_power_resume(struct acpi_device *device)
return 0;
}
-static int __init acpi_power_init(void)
+int __init acpi_power_init(void)
{
int result = 0;
-
- if (acpi_disabled)
- return 0;
-
INIT_LIST_HEAD(&acpi_power_resource_list);
acpi_power_dir = proc_mkdir(ACPI_POWER_CLASS, acpi_root_dir);
@@ -795,5 +787,3 @@ static int __init acpi_power_init(void)
return 0;
}
-
-subsys_initcall(acpi_power_init);
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c
index 428c911dba0..05dfdc96802 100644
--- a/drivers/acpi/proc.c
+++ b/drivers/acpi/proc.c
@@ -496,11 +496,8 @@ static u32 rtc_handler(void *context)
}
#endif /* HAVE_ACPI_LEGACY_ALARM */
-static int __init acpi_sleep_proc_init(void)
+int __init acpi_sleep_proc_init(void)
{
- if (acpi_disabled)
- return 0;
-
#ifdef CONFIG_ACPI_PROCFS
/* 'sleep' [R/W] */
proc_create("sleep", S_IFREG | S_IRUGO | S_IWUSR,
@@ -527,5 +524,3 @@ static int __init acpi_sleep_proc_init(void)
return 0;
}
-
-late_initcall(acpi_sleep_proc_init);
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 0cc2fd31e37..45ad3288c5f 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -82,7 +82,7 @@ static int acpi_processor_add(struct acpi_device *device);
static int acpi_processor_start(struct acpi_device *device);
static int acpi_processor_remove(struct acpi_device *device, int type);
static int acpi_processor_info_open_fs(struct inode *inode, struct file *file);
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data);
+static void acpi_processor_notify(struct acpi_device *device, u32 event);
static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
static int acpi_processor_handle_eject(struct acpi_processor *pr);
@@ -104,6 +104,7 @@ static struct acpi_driver acpi_processor_driver = {
.start = acpi_processor_start,
.suspend = acpi_processor_suspend,
.resume = acpi_processor_resume,
+ .notify = acpi_processor_notify,
},
};
@@ -359,7 +360,6 @@ static int acpi_processor_add_fs(struct acpi_device *device)
if (!acpi_device_dir(device))
return -ENODEV;
}
- acpi_device_dir(device)->owner = THIS_MODULE;
/* 'info' [R] */
entry = proc_create_data(ACPI_PROCESSOR_FILE_INFO,
@@ -427,6 +427,29 @@ static int map_lapic_id(struct acpi_subtable_header *entry,
return 0;
}
+static int map_x2apic_id(struct acpi_subtable_header *entry,
+ int device_declaration, u32 acpi_id, int *apic_id)
+{
+ struct acpi_madt_local_x2apic *apic =
+ (struct acpi_madt_local_x2apic *)entry;
+ u32 tmp = apic->local_apic_id;
+
+ /* Only check enabled APICs*/
+ if (!(apic->lapic_flags & ACPI_MADT_ENABLED))
+ return 0;
+
+ /* Device statement declaration type */
+ if (device_declaration) {
+ if (apic->uid == acpi_id)
+ goto found;
+ }
+
+ return 0;
+found:
+ *apic_id = tmp;
+ return 1;
+}
+
static int map_lsapic_id(struct acpi_subtable_header *entry,
int device_declaration, u32 acpi_id, int *apic_id)
{
@@ -476,6 +499,9 @@ static int map_madt_entry(int type, u32 acpi_id)
if (header->type == ACPI_MADT_TYPE_LOCAL_APIC) {
if (map_lapic_id(header, acpi_id, &apic_id))
break;
+ } else if (header->type == ACPI_MADT_TYPE_LOCAL_X2APIC) {
+ if (map_x2apic_id(header, type, acpi_id, &apic_id))
+ break;
} else if (header->type == ACPI_MADT_TYPE_LOCAL_SAPIC) {
if (map_lsapic_id(header, type, acpi_id, &apic_id))
break;
@@ -666,7 +692,6 @@ static DEFINE_PER_CPU(void *, processor_device_array);
static int __cpuinit acpi_processor_start(struct acpi_device *device)
{
int result = 0;
- acpi_status status = AE_OK;
struct acpi_processor *pr;
struct sys_device *sysdev;
@@ -703,9 +728,6 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev"))
return -EFAULT;
- status = acpi_install_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify, pr);
-
/* _PDC call should be done before doing anything else (if reqd.). */
arch_acpi_processor_init_pdc(pr);
acpi_processor_set_pdc(pr);
@@ -751,18 +773,14 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
return result;
}
-static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
+static void acpi_processor_notify(struct acpi_device *device, u32 event)
{
- struct acpi_processor *pr = data;
- struct acpi_device *device = NULL;
+ struct acpi_processor *pr = acpi_driver_data(device);
int saved;
if (!pr)
return;
- if (acpi_bus_get_device(pr->handle, &device))
- return;
-
switch (event) {
case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
saved = pr->performance_platform_limit;
@@ -841,7 +859,6 @@ static int acpi_processor_add(struct acpi_device *device)
static int acpi_processor_remove(struct acpi_device *device, int type)
{
- acpi_status status = AE_OK;
struct acpi_processor *pr = NULL;
@@ -860,9 +877,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
acpi_processor_power_exit(pr, device);
- status = acpi_remove_notify_handler(pr->handle, ACPI_DEVICE_NOTIFY,
- acpi_processor_notify);
-
sysfs_remove_link(&device->dev.kobj, "sysdev");
acpi_processor_remove_fs(device);
@@ -1137,7 +1151,6 @@ static int __init acpi_processor_init(void)
acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
if (!acpi_processor_dir)
return -ENOMEM;
- acpi_processor_dir->owner = THIS_MODULE;
/*
* Check whether the system is DMI table. If yes, OSPM
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 7bc22a471fe..4e6e758bd39 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -64,7 +64,6 @@
#define _COMPONENT ACPI_PROCESSOR_COMPONENT
ACPI_MODULE_NAME("processor_idle");
#define ACPI_PROCESSOR_FILE_POWER "power"
-#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
#define C2_OVERHEAD 1 /* 1us */
#define C3_OVERHEAD 1 /* 1us */
@@ -78,6 +77,10 @@ module_param(nocst, uint, 0000);
static unsigned int latency_factor __read_mostly = 2;
module_param(latency_factor, uint, 0644);
+static s64 us_to_pm_timer_ticks(s64 t)
+{
+ return div64_u64(t * PM_TIMER_FREQUENCY, 1000000);
+}
/*
* IBM ThinkPad R40e crashes mysteriously when going into C2 or C3.
* For now disable this. Probably a bug somewhere else.
@@ -101,57 +104,6 @@ static int set_max_cstate(const struct dmi_system_id *id)
/* Actually this shouldn't be __cpuinitdata, would be better to fix the
callers to only run once -AK */
static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET70WW")}, (void *)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW")}, (void *)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET43WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET45WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET47WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET50WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET52WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET55WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET56WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET59WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET60WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET61WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET62WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET64WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET65WW") }, (void*)1},
- { set_max_cstate, "IBM ThinkPad R40e", {
- DMI_MATCH(DMI_BIOS_VENDOR,"IBM"),
- DMI_MATCH(DMI_BIOS_VERSION,"1SET68WW") }, (void*)1},
- { set_max_cstate, "Medion 41700", {
- DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
- DMI_MATCH(DMI_BIOS_VERSION,"R01-A1J")}, (void *)1},
{ set_max_cstate, "Clevo 5600D", {
DMI_MATCH(DMI_BIOS_VENDOR,"Phoenix Technologies LTD"),
DMI_MATCH(DMI_BIOS_VERSION,"SHE845M0.86C.0013.D.0302131307")},
@@ -159,25 +111,6 @@ static struct dmi_system_id __cpuinitdata processor_power_dmi_table[] = {
{},
};
-static inline u32 ticks_elapsed(u32 t1, u32 t2)
-{
- if (t2 >= t1)
- return (t2 - t1);
- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
- return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
- else
- return ((0xFFFFFFFF - t1) + t2);
-}
-
-static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2)
-{
- if (t2 >= t1)
- return PM_TIMER_TICKS_TO_US(t2 - t1);
- else if (!(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER))
- return PM_TIMER_TICKS_TO_US(((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
- else
- return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2);
-}
/*
* Callers should disable interrupts before the call and enable
@@ -630,7 +563,7 @@ static void acpi_processor_power_verify_c3(struct acpi_processor *pr,
* In either case, the proper way to
* handle BM_RLD is to set it and leave it set.
*/
- acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_RLD, 1);
return;
}
@@ -800,9 +733,9 @@ static int acpi_idle_bm_check(void)
{
u32 bm_status = 0;
- acpi_get_register_unlocked(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
+ acpi_read_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, &bm_status);
if (bm_status)
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
+ acpi_write_bit_register(ACPI_BITREG_BUS_MASTER_STATUS, 1);
/*
* PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
* the true state of bus mastering activity; forcing us to
@@ -853,7 +786,8 @@ static inline void acpi_idle_do_entry(struct acpi_processor_cx *cx)
static int acpi_idle_enter_c1(struct cpuidle_device *dev,
struct cpuidle_state *state)
{
- u32 t1, t2;
+ ktime_t kt1, kt2;
+ s64 idle_time;
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
@@ -871,14 +805,15 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev,
return 0;
}
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
local_irq_enable();
cx->usage++;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
/**
@@ -891,8 +826,9 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
{
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- int sleep_ticks = 0;
+ ktime_t kt1, kt2;
+ s64 idle_time;
+ s64 sleep_ticks = 0;
pr = __get_cpu_var(processors);
@@ -925,18 +861,19 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
if (cx->type == ACPI_STATE_C3)
ACPI_FLUSH_CPU_CACHE();
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
/* Tell the scheduler that we are going deep-idle: */
sched_clock_idle_sleep_event();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86)
/* TSC could halt in idle, so notify users */
if (tsc_halts_in_c(cx->type))
mark_tsc_unstable("TSC halts in idle");;
#endif
- sleep_ticks = ticks_elapsed(t1, t2);
+ sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -948,7 +885,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
acpi_state_timer_broadcast(pr, cx, 0);
cx->time += sleep_ticks;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
static int c3_cpu_count;
@@ -966,8 +903,10 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
{
struct acpi_processor *pr;
struct acpi_processor_cx *cx = cpuidle_get_statedata(state);
- u32 t1, t2;
- int sleep_ticks = 0;
+ ktime_t kt1, kt2;
+ s64 idle_time;
+ s64 sleep_ticks = 0;
+
pr = __get_cpu_var(processors);
@@ -1028,20 +967,21 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
c3_cpu_count++;
/* Disable bus master arbitration when all CPUs are in C3 */
if (c3_cpu_count == num_online_cpus())
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 1);
spin_unlock(&c3_lock);
} else if (!pr->flags.bm_check) {
ACPI_FLUSH_CPU_CACHE();
}
- t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt1 = ktime_get_real();
acpi_idle_do_entry(cx);
- t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
+ kt2 = ktime_get_real();
+ idle_time = ktime_to_us(ktime_sub(kt2, kt1));
/* Re-enable bus master arbitration */
if (pr->flags.bm_check && pr->flags.bm_control) {
spin_lock(&c3_lock);
- acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+ acpi_write_bit_register(ACPI_BITREG_ARB_DISABLE, 0);
c3_cpu_count--;
spin_unlock(&c3_lock);
}
@@ -1051,7 +991,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
if (tsc_halts_in_c(ACPI_STATE_C3))
mark_tsc_unstable("TSC halts in idle");
#endif
- sleep_ticks = ticks_elapsed(t1, t2);
+ sleep_ticks = us_to_pm_timer_ticks(idle_time);
/* Tell the scheduler how much we idled: */
sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
@@ -1062,7 +1002,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
acpi_state_timer_broadcast(pr, cx, 0);
cx->time += sleep_ticks;
- return ticks_elapsed_in_us(t1, t2);
+ return idle_time;
}
struct cpuidle_driver acpi_idle_driver = {
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 68fd3d29279..cafb41000f6 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -479,6 +479,13 @@ static int acpi_processor_get_psd(struct acpi_processor *pr)
goto end;
}
+ if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
+ pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
+ pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
+ printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
+ result = -EFAULT;
+ goto end;
+ }
end:
kfree(buffer.pointer);
return result;
@@ -501,9 +508,10 @@ int acpi_processor_preregister_performance(
mutex_lock(&performance_mutex);
- retval = 0;
-
- /* Call _PSD for all CPUs */
+ /*
+ * Check if another driver has already registered, and abort before
+ * changing pr->performance if it has. Check input data as well.
+ */
for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
if (!pr) {
@@ -513,13 +521,20 @@ int acpi_processor_preregister_performance(
if (pr->performance) {
retval = -EBUSY;
- continue;
+ goto err_out;
}
if (!performance || !per_cpu_ptr(performance, i)) {
retval = -EINVAL;
- continue;
+ goto err_out;
}
+ }
+
+ /* Call _PSD for all CPUs */
+ for_each_possible_cpu(i) {
+ pr = per_cpu(processors, i);
+ if (!pr)
+ continue;
pr->performance = per_cpu_ptr(performance, i);
cpumask_set_cpu(i, pr->performance->shared_cpu_map);
@@ -535,26 +550,6 @@ int acpi_processor_preregister_performance(
* Now that we have _PSD data from all CPUs, lets setup P-state
* domain info.
*/
- for_each_possible_cpu(i) {
- pr = per_cpu(processors, i);
- if (!pr)
- continue;
-
- /* Basic validity check for domain info */
- pdomain = &(pr->performance->domain_info);
- if ((pdomain->revision != ACPI_PSD_REV0_REVISION) ||
- (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES)) {
- retval = -EINVAL;
- goto err_ret;
- }
- if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
- pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
- retval = -EINVAL;
- goto err_ret;
- }
- }
-
cpumask_clear(covered_cpus);
for_each_possible_cpu(i) {
pr = per_cpu(processors, i);
@@ -643,6 +638,7 @@ err_ret:
pr->performance = NULL; /* Will be set for real in register */
}
+err_out:
mutex_unlock(&performance_mutex);
free_cpumask_var(covered_cpus);
return retval;
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index b1eb376fae4..39838c66603 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -373,7 +373,8 @@ static int acpi_processor_max_state(struct acpi_processor *pr)
return max_state;
}
static int
-processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_max_state(struct thermal_cooling_device *cdev,
+ unsigned long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
@@ -381,28 +382,29 @@ processor_get_max_state(struct thermal_cooling_device *cdev, char *buf)
if (!device || !pr)
return -EINVAL;
- return sprintf(buf, "%d\n", acpi_processor_max_state(pr));
+ *state = acpi_processor_max_state(pr);
+ return 0;
}
static int
-processor_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+processor_get_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long *cur_state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
- int cur_state;
if (!device || !pr)
return -EINVAL;
- cur_state = cpufreq_get_cur_state(pr->id);
+ *cur_state = cpufreq_get_cur_state(pr->id);
if (pr->flags.throttling)
- cur_state += pr->throttling.state;
-
- return sprintf(buf, "%d\n", cur_state);
+ *cur_state += pr->throttling.state;
+ return 0;
}
static int
-processor_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+processor_set_cur_state(struct thermal_cooling_device *cdev,
+ unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_processor *pr = acpi_driver_data(device);
@@ -507,7 +509,7 @@ static ssize_t acpi_processor_write_limit(struct file * file,
return count;
}
-struct file_operations acpi_processor_limit_fops = {
+const struct file_operations acpi_processor_limit_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_limit_open_fs,
.read = seq_read,
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index d27838171f4..d0d1f4d5043 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -783,11 +783,9 @@ static int acpi_get_throttling_state(struct acpi_processor *pr,
(struct acpi_processor_tx_tss *)&(pr->throttling.
states_tss[i]);
if (tx->control == value)
- break;
+ return i;
}
- if (i > pr->throttling.state_count)
- i = -1;
- return i;
+ return -1;
}
static int acpi_get_throttling_value(struct acpi_processor *pr,
@@ -1291,7 +1289,7 @@ static ssize_t acpi_processor_write_throttling(struct file *file,
return count;
}
-struct file_operations acpi_processor_throttling_fops = {
+const struct file_operations acpi_processor_throttling_fops = {
.owner = THIS_MODULE,
.open = acpi_processor_throttling_open_fs,
.read = seq_read,
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 6050ce48187..4b214b74eba 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -102,8 +102,8 @@ struct acpi_battery {
u16 cycle_count;
u16 temp_now;
u16 voltage_now;
- s16 current_now;
- s16 current_avg;
+ s16 rate_now;
+ s16 rate_avg;
u16 capacity_now;
u16 state_of_charge;
u16 state;
@@ -202,9 +202,9 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
return -ENODEV;
switch (psp) {
case POWER_SUPPLY_PROP_STATUS:
- if (battery->current_now < 0)
+ if (battery->rate_now < 0)
val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
- else if (battery->current_now > 0)
+ else if (battery->rate_now > 0)
val->intval = POWER_SUPPLY_STATUS_CHARGING;
else
val->intval = POWER_SUPPLY_STATUS_FULL;
@@ -224,11 +224,13 @@ static int acpi_sbs_battery_get_property(struct power_supply *psy,
acpi_battery_vscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_NOW:
- val->intval = abs(battery->current_now) *
+ case POWER_SUPPLY_PROP_POWER_NOW:
+ val->intval = abs(battery->rate_now) *
acpi_battery_ipscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CURRENT_AVG:
- val->intval = abs(battery->current_avg) *
+ case POWER_SUPPLY_PROP_POWER_AVG:
+ val->intval = abs(battery->rate_avg) *
acpi_battery_ipscale(battery) * 1000;
break;
case POWER_SUPPLY_PROP_CAPACITY:
@@ -293,6 +295,8 @@ static enum power_supply_property sbs_energy_battery_props[] = {
POWER_SUPPLY_PROP_VOLTAGE_NOW,
POWER_SUPPLY_PROP_CURRENT_NOW,
POWER_SUPPLY_PROP_CURRENT_AVG,
+ POWER_SUPPLY_PROP_POWER_NOW,
+ POWER_SUPPLY_PROP_POWER_AVG,
POWER_SUPPLY_PROP_CAPACITY,
POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
POWER_SUPPLY_PROP_ENERGY_FULL,
@@ -301,6 +305,7 @@ static enum power_supply_property sbs_energy_battery_props[] = {
POWER_SUPPLY_PROP_MODEL_NAME,
POWER_SUPPLY_PROP_MANUFACTURER,
};
+
#endif
/* --------------------------------------------------------------------------
@@ -330,8 +335,8 @@ static struct acpi_battery_reader info_readers[] = {
static struct acpi_battery_reader state_readers[] = {
{0x08, SMBUS_READ_WORD, offsetof(struct acpi_battery, temp_now)},
{0x09, SMBUS_READ_WORD, offsetof(struct acpi_battery, voltage_now)},
- {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_now)},
- {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, current_avg)},
+ {0x0a, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_now)},
+ {0x0b, SMBUS_READ_WORD, offsetof(struct acpi_battery, rate_avg)},
{0x0f, SMBUS_READ_WORD, offsetof(struct acpi_battery, capacity_now)},
{0x0e, SMBUS_READ_WORD, offsetof(struct acpi_battery, state_of_charge)},
{0x16, SMBUS_READ_WORD, offsetof(struct acpi_battery, state)},
@@ -479,16 +484,15 @@ static int
acpi_sbs_add_fs(struct proc_dir_entry **dir,
struct proc_dir_entry *parent_dir,
char *dir_name,
- struct file_operations *info_fops,
- struct file_operations *state_fops,
- struct file_operations *alarm_fops, void *data)
+ const struct file_operations *info_fops,
+ const struct file_operations *state_fops,
+ const struct file_operations *alarm_fops, void *data)
{
if (!*dir) {
*dir = proc_mkdir(dir_name, parent_dir);
if (!*dir) {
return -ENODEV;
}
- (*dir)->owner = THIS_MODULE;
}
/* 'info' [R] */
@@ -589,9 +593,9 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
seq_printf(seq, "capacity state: %s\n",
(battery->state & 0x0010) ? "critical" : "ok");
seq_printf(seq, "charging state: %s\n",
- (battery->current_now < 0) ? "discharging" :
- ((battery->current_now > 0) ? "charging" : "charged"));
- rate = abs(battery->current_now) * acpi_battery_ipscale(battery);
+ (battery->rate_now < 0) ? "discharging" :
+ ((battery->rate_now > 0) ? "charging" : "charged"));
+ rate = abs(battery->rate_now) * acpi_battery_ipscale(battery);
rate *= (acpi_battery_mode(battery))?(battery->voltage_now *
acpi_battery_vscale(battery)/1000):1;
seq_printf(seq, "present rate: %d%s\n", rate,
@@ -677,7 +681,7 @@ static int acpi_battery_alarm_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_battery_read_alarm, PDE(inode)->data);
}
-static struct file_operations acpi_battery_info_fops = {
+static const struct file_operations acpi_battery_info_fops = {
.open = acpi_battery_info_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -685,7 +689,7 @@ static struct file_operations acpi_battery_info_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_state_fops = {
+static const struct file_operations acpi_battery_state_fops = {
.open = acpi_battery_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
@@ -693,7 +697,7 @@ static struct file_operations acpi_battery_state_fops = {
.owner = THIS_MODULE,
};
-static struct file_operations acpi_battery_alarm_fops = {
+static const struct file_operations acpi_battery_alarm_fops = {
.open = acpi_battery_alarm_open_fs,
.read = seq_read,
.write = acpi_battery_write_alarm,
@@ -725,7 +729,7 @@ static int acpi_ac_state_open_fs(struct inode *inode, struct file *file)
return single_open(file, acpi_ac_read_state, PDE(inode)->data);
}
-static struct file_operations acpi_ac_state_fops = {
+static const struct file_operations acpi_ac_state_fops = {
.open = acpi_ac_state_open_fs,
.read = seq_read,
.llseek = seq_lseek,
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c54d7b6c406..20c23c04920 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,6 +11,8 @@
#include <acpi/acpi_drivers.h>
+#include "internal.h"
+
#define _COMPONENT ACPI_BUS_COMPONENT
ACPI_MODULE_NAME("scan");
#define STRUCT_TO_INT(s) (*((int*)&s))
@@ -357,6 +359,61 @@ static int acpi_device_uevent(struct device *dev, struct kobj_uevent_env *env)
return 0;
}
+static void acpi_device_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct acpi_device *device = data;
+
+ device->driver->ops.notify(device, event);
+}
+
+static acpi_status acpi_device_notify_fixed(void *data)
+{
+ struct acpi_device *device = data;
+
+ acpi_device_notify(device->handle, ACPI_FIXED_HARDWARE_EVENT, device);
+ return AE_OK;
+}
+
+static int acpi_device_install_notify_handler(struct acpi_device *device)
+{
+ acpi_status status;
+ char *hid;
+
+ hid = acpi_device_hid(device);
+ if (!strcmp(hid, ACPI_BUTTON_HID_POWERF))
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_device_notify_fixed,
+ device);
+ else if (!strcmp(hid, ACPI_BUTTON_HID_SLEEPF))
+ status =
+ acpi_install_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_device_notify_fixed,
+ device);
+ else
+ status = acpi_install_notify_handler(device->handle,
+ ACPI_DEVICE_NOTIFY,
+ acpi_device_notify,
+ device);
+
+ if (ACPI_FAILURE(status))
+ return -EINVAL;
+ return 0;
+}
+
+static void acpi_device_remove_notify_handler(struct acpi_device *device)
+{
+ if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_POWERF))
+ acpi_remove_fixed_event_handler(ACPI_EVENT_POWER_BUTTON,
+ acpi_device_notify_fixed);
+ else if (!strcmp(acpi_device_hid(device), ACPI_BUTTON_HID_SLEEPF))
+ acpi_remove_fixed_event_handler(ACPI_EVENT_SLEEP_BUTTON,
+ acpi_device_notify_fixed);
+ else
+ acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
+ acpi_device_notify);
+}
+
static int acpi_bus_driver_init(struct acpi_device *, struct acpi_driver *);
static int acpi_start_single_object(struct acpi_device *);
static int acpi_device_probe(struct device * dev)
@@ -369,6 +426,20 @@ static int acpi_device_probe(struct device * dev)
if (!ret) {
if (acpi_dev->bus_ops.acpi_op_start)
acpi_start_single_object(acpi_dev);
+
+ if (acpi_drv->ops.notify) {
+ ret = acpi_device_install_notify_handler(acpi_dev);
+ if (ret) {
+ if (acpi_drv->ops.stop)
+ acpi_drv->ops.stop(acpi_dev,
+ acpi_dev->removal_type);
+ if (acpi_drv->ops.remove)
+ acpi_drv->ops.remove(acpi_dev,
+ acpi_dev->removal_type);
+ return ret;
+ }
+ }
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Found driver [%s] for device [%s]\n",
acpi_drv->name, acpi_dev->pnp.bus_id));
@@ -383,6 +454,8 @@ static int acpi_device_remove(struct device * dev)
struct acpi_driver *acpi_drv = acpi_dev->driver;
if (acpi_drv) {
+ if (acpi_drv->ops.notify)
+ acpi_device_remove_notify_handler(acpi_dev);
if (acpi_drv->ops.stop)
acpi_drv->ops.stop(acpi_dev, acpi_dev->removal_type);
if (acpi_drv->ops.remove)
@@ -395,22 +468,10 @@ static int acpi_device_remove(struct device * dev)
return 0;
}
-static void acpi_device_shutdown(struct device *dev)
-{
- struct acpi_device *acpi_dev = to_acpi_device(dev);
- struct acpi_driver *acpi_drv = acpi_dev->driver;
-
- if (acpi_drv && acpi_drv->ops.shutdown)
- acpi_drv->ops.shutdown(acpi_dev);
-
- return ;
-}
-
struct bus_type acpi_bus_type = {
.name = "acpi",
.suspend = acpi_device_suspend,
.resume = acpi_device_resume,
- .shutdown = acpi_device_shutdown,
.match = acpi_bus_match,
.probe = acpi_device_probe,
.remove = acpi_device_remove,
@@ -1524,16 +1585,11 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
return result;
}
-
-static int __init acpi_scan_init(void)
+int __init acpi_scan_init(void)
{
int result;
struct acpi_bus_ops ops;
-
- if (acpi_disabled)
- return 0;
-
memset(&ops, 0, sizeof(ops));
ops.acpi_op_add = 1;
ops.acpi_op_start = 1;
@@ -1566,5 +1622,3 @@ static int __init acpi_scan_init(void)
Done:
return result;
}
-
-subsys_initcall(acpi_scan_init);
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
index 00456fccfa3..779e4e500df 100644
--- a/drivers/acpi/sleep.c
+++ b/drivers/acpi/sleep.c
@@ -21,6 +21,8 @@
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
+
+#include "internal.h"
#include "sleep.h"
u8 sleep_states[ACPI_S_STATE_COUNT];
@@ -248,7 +250,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state)
/* If ACPI is not enabled by the BIOS, we need to enable it here. */
if (set_sci_en_on_resume)
- acpi_set_register(ACPI_BITREG_SCI_ENABLE, 1);
+ acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1);
else
acpi_enable();
@@ -394,6 +396,15 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Satellite L300"),
},
},
+ {
+ .callback = init_old_suspend_ordering,
+ .ident = "Panasonic CF51-2L",
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR,
+ "Matsushita Electric Industrial Co.,Ltd."),
+ DMI_MATCH(DMI_BOARD_NAME, "CF51-2L"),
+ },
+ },
{},
};
#endif /* CONFIG_SUSPEND */
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 391d0358a59..da51f05ef8d 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -33,10 +33,6 @@
#define _COMPONENT ACPI_SYSTEM_COMPONENT
ACPI_MODULE_NAME("system");
-#ifdef MODULE_PARAM_PREFIX
-#undef MODULE_PARAM_PREFIX
-#endif
-#define MODULE_PARAM_PREFIX "acpi."
#define ACPI_SYSTEM_CLASS "system"
#define ACPI_SYSTEM_DEVICE_NAME "System"
@@ -62,6 +58,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
-------------------------------------------------------------------------- */
static LIST_HEAD(acpi_table_attr_list);
static struct kobject *tables_kobj;
+static struct kobject *dynamic_tables_kobj;
struct acpi_table_attr {
struct bin_attribute attr;
@@ -128,6 +125,40 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
return;
}
+static acpi_status
+acpi_sysfs_table_handler(u32 event, void *table, void *context)
+{
+ struct acpi_table_attr *table_attr;
+
+ switch (event) {
+ case ACPI_TABLE_EVENT_LOAD:
+ table_attr =
+ kzalloc(sizeof(struct acpi_table_attr), GFP_KERNEL);
+ if (!table_attr)
+ return AE_NO_MEMORY;
+
+ acpi_table_attr_init(table_attr, table);
+ if (sysfs_create_bin_file(dynamic_tables_kobj,
+ &table_attr->attr)) {
+ kfree(table_attr);
+ return AE_ERROR;
+ } else
+ list_add_tail(&table_attr->node,
+ &acpi_table_attr_list);
+ break;
+ case ACPI_TABLE_EVENT_UNLOAD:
+ /*
+ * we do not need to do anything right now
+ * because the table is not deleted from the
+ * global table list when unloading it.
+ */
+ break;
+ default:
+ return AE_BAD_PARAMETER;
+ }
+ return AE_OK;
+}
+
static int acpi_system_sysfs_init(void)
{
struct acpi_table_attr *table_attr;
@@ -137,7 +168,11 @@ static int acpi_system_sysfs_init(void)
tables_kobj = kobject_create_and_add("tables", acpi_kobj);
if (!tables_kobj)
- return -ENOMEM;
+ goto err;
+
+ dynamic_tables_kobj = kobject_create_and_add("dynamic", tables_kobj);
+ if (!dynamic_tables_kobj)
+ goto err_dynamic_tables;
do {
result = acpi_get_table_by_index(table_index, &table_header);
@@ -162,8 +197,14 @@ static int acpi_system_sysfs_init(void)
}
} while (!result);
kobject_uevent(tables_kobj, KOBJ_ADD);
-
- return 0;
+ kobject_uevent(dynamic_tables_kobj, KOBJ_ADD);
+ result = acpi_install_table_handler(acpi_sysfs_table_handler, NULL);
+
+ return result == AE_OK ? 0 : -EINVAL;
+err_dynamic_tables:
+ kobject_put(tables_kobj);
+err:
+ return -ENOMEM;
}
/*
@@ -571,12 +612,9 @@ static int acpi_system_procfs_init(void)
}
#endif
-static int __init acpi_system_init(void)
+int __init acpi_system_init(void)
{
- int result = 0;
-
- if (acpi_disabled)
- return 0;
+ int result;
result = acpi_system_procfs_init();
if (result)
@@ -586,5 +624,3 @@ static int __init acpi_system_init(void)
return result;
}
-
-subsys_initcall(acpi_system_init);
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index fec1ae36d43..646d39c031c 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -62,6 +62,18 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
}
break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC:
+ {
+ struct acpi_madt_local_x2apic *p =
+ (struct acpi_madt_local_x2apic *)header;
+ printk(KERN_INFO PREFIX
+ "X2APIC (apic_id[0x%02x] uid[0x%02x] %s)\n",
+ p->local_apic_id, p->uid,
+ (p->lapic_flags & ACPI_MADT_ENABLED) ?
+ "enabled" : "disabled");
+ }
+ break;
+
case ACPI_MADT_TYPE_IO_APIC:
{
struct acpi_madt_io_apic *p =
@@ -116,6 +128,24 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
}
break;
+ case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+ {
+ u16 polarity, trigger;
+ struct acpi_madt_local_x2apic_nmi *p =
+ (struct acpi_madt_local_x2apic_nmi *)header;
+
+ polarity = p->inti_flags & ACPI_MADT_POLARITY_MASK;
+ trigger = (p->inti_flags & ACPI_MADT_TRIGGER_MASK) >> 2;
+
+ printk(KERN_INFO PREFIX
+ "X2APIC_NMI (uid[0x%02x] %s %s lint[0x%x])\n",
+ p->uid,
+ mps_inti_flags_polarity[polarity],
+ mps_inti_flags_trigger[trigger],
+ p->lint);
+ }
+ break;
+
case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
{
struct acpi_madt_local_apic_override *p =
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 99e6f1f8ea4..e8c143caf0f 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -37,11 +37,11 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/proc_fs.h>
-#include <linux/timer.h>
#include <linux/jiffies.h>
#include <linux/kmod.h>
#include <linux/seq_file.h>
#include <linux/reboot.h>
+#include <linux/device.h>
#include <asm/uaccess.h>
#include <linux/thermal.h>
#include <acpi/acpi_bus.h>
@@ -190,7 +190,6 @@ struct acpi_thermal {
struct acpi_thermal_state state;
struct acpi_thermal_trips trips;
struct acpi_handle_list devices;
- struct timer_list timer;
struct thermal_zone_device *thermal_zone;
int tz_enabled;
struct mutex lock;
@@ -290,6 +289,11 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
tz->polling_frequency = seconds * 10; /* Convert value to deci-seconds */
+ tz->thermal_zone->polling_delay = seconds * 1000;
+
+ if (tz->tz_enabled)
+ thermal_zone_device_update(tz->thermal_zone);
+
ACPI_DEBUG_PRINT((ACPI_DB_INFO,
"Polling frequency set to %lu seconds\n",
tz->polling_frequency/10));
@@ -367,7 +371,7 @@ static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
/*
* Treat freezing temperatures as invalid as well; some
* BIOSes return really low values and cause reboots at startup.
- * Below zero (Celcius) values clearly aren't right for sure..
+ * Below zero (Celsius) values clearly aren't right for sure..
* ... so lets discard those as invalid.
*/
if (ACPI_FAILURE(status) ||
@@ -569,392 +573,18 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
}
-static int acpi_thermal_critical(struct acpi_thermal *tz)
-{
- if (!tz || !tz->trips.critical.flags.valid)
- return -EINVAL;
-
- if (tz->temperature >= tz->trips.critical.temperature) {
- printk(KERN_WARNING PREFIX "Critical trip point\n");
- tz->trips.critical.flags.enabled = 1;
- } else if (tz->trips.critical.flags.enabled)
- tz->trips.critical.flags.enabled = 0;
-
- acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
- tz->trips.critical.flags.enabled);
- acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- dev_name(&tz->device->dev),
- ACPI_THERMAL_NOTIFY_CRITICAL,
- tz->trips.critical.flags.enabled);
-
- /* take no action if nocrt is set */
- if(!nocrt) {
- printk(KERN_EMERG
- "Critical temperature reached (%ld C), shutting down.\n",
- KELVIN_TO_CELSIUS(tz->temperature));
- orderly_poweroff(true);
- }
-
- return 0;
-}
-
-static int acpi_thermal_hot(struct acpi_thermal *tz)
-{
- if (!tz || !tz->trips.hot.flags.valid)
- return -EINVAL;
-
- if (tz->temperature >= tz->trips.hot.temperature) {
- printk(KERN_WARNING PREFIX "Hot trip point\n");
- tz->trips.hot.flags.enabled = 1;
- } else if (tz->trips.hot.flags.enabled)
- tz->trips.hot.flags.enabled = 0;
-
- acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
- tz->trips.hot.flags.enabled);
- acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
- dev_name(&tz->device->dev),
- ACPI_THERMAL_NOTIFY_HOT,
- tz->trips.hot.flags.enabled);
-
- /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
-
- return 0;
-}
-
-static void acpi_thermal_passive(struct acpi_thermal *tz)
-{
- int result = 1;
- struct acpi_thermal_passive *passive = NULL;
- int trend = 0;
- int i = 0;
-
-
- if (!tz || !tz->trips.passive.flags.valid)
- return;
-
- passive = &(tz->trips.passive);
-
- /*
- * Above Trip?
- * -----------
- * Calculate the thermal trend (using the passive cooling equation)
- * and modify the performance limit for all passive cooling devices
- * accordingly. Note that we assume symmetry.
- */
- if (tz->temperature >= passive->temperature) {
- trend =
- (passive->tc1 * (tz->temperature - tz->last_temperature)) +
- (passive->tc2 * (tz->temperature - passive->temperature));
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
- trend, passive->tc1, tz->temperature,
- tz->last_temperature, passive->tc2,
- tz->temperature, passive->temperature));
- passive->flags.enabled = 1;
- /* Heating up? */
- if (trend > 0)
- for (i = 0; i < passive->devices.count; i++)
- acpi_processor_set_thermal_limit(passive->
- devices.
- handles[i],
- ACPI_PROCESSOR_LIMIT_INCREMENT);
- /* Cooling off? */
- else if (trend < 0) {
- for (i = 0; i < passive->devices.count; i++)
- /*
- * assume that we are on highest
- * freq/lowest thrott and can leave
- * passive mode, even in error case
- */
- if (!acpi_processor_set_thermal_limit
- (passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT))
- result = 0;
- /*
- * Leave cooling mode, even if the temp might
- * higher than trip point This is because some
- * machines might have long thermal polling
- * frequencies (tsp) defined. We will fall back
- * into passive mode in next cycle (probably quicker)
- */
- if (result) {
- passive->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling, still above threshold,"
- " but we are cooling down\n"));
- }
- }
- return;
- }
-
- /*
- * Below Trip?
- * -----------
- * Implement passive cooling hysteresis to slowly increase performance
- * and avoid thrashing around the passive trip point. Note that we
- * assume symmetry.
- */
- if (!passive->flags.enabled)
- return;
- for (i = 0; i < passive->devices.count; i++)
- if (!acpi_processor_set_thermal_limit
- (passive->devices.handles[i],
- ACPI_PROCESSOR_LIMIT_DECREMENT))
- result = 0;
- if (result) {
- passive->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Disabling passive cooling (zone is cool)\n"));
- }
-}
-
-static void acpi_thermal_active(struct acpi_thermal *tz)
-{
- int result = 0;
- struct acpi_thermal_active *active = NULL;
- int i = 0;
- int j = 0;
- unsigned long maxtemp = 0;
-
-
- if (!tz)
- return;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- active = &(tz->trips.active[i]);
- if (!active || !active->flags.valid)
- break;
- if (tz->temperature >= active->temperature) {
- /*
- * Above Threshold?
- * ----------------
- * If not already enabled, turn ON all cooling devices
- * associated with this active threshold.
- */
- if (active->temperature > maxtemp)
- tz->state.active_index = i;
- maxtemp = active->temperature;
- if (active->flags.enabled)
- continue;
- for (j = 0; j < active->devices.count; j++) {
- result =
- acpi_bus_set_power(active->devices.
- handles[j],
- ACPI_STATE_D0);
- if (result) {
- printk(KERN_WARNING PREFIX
- "Unable to turn cooling device [%p] 'on'\n",
- active->devices.
- handles[j]);
- continue;
- }
- active->flags.enabled = 1;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'on'\n",
- active->devices.handles[j]));
- }
- continue;
- }
- if (!active->flags.enabled)
- continue;
- /*
- * Below Threshold?
- * ----------------
- * Turn OFF all cooling devices associated with this
- * threshold.
- */
- for (j = 0; j < active->devices.count; j++) {
- result = acpi_bus_set_power(active->devices.handles[j],
- ACPI_STATE_D3);
- if (result) {
- printk(KERN_WARNING PREFIX
- "Unable to turn cooling device [%p] 'off'\n",
- active->devices.handles[j]);
- continue;
- }
- active->flags.enabled = 0;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO,
- "Cooling device [%p] now 'off'\n",
- active->devices.handles[j]));
- }
- }
-}
-
-static void acpi_thermal_check(void *context);
-
-static void acpi_thermal_run(unsigned long data)
-{
- struct acpi_thermal *tz = (struct acpi_thermal *)data;
- if (!tz->zombie)
- acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
-}
-
-static void acpi_thermal_active_off(void *data)
-{
- int result = 0;
- struct acpi_thermal *tz = data;
- int i = 0;
- int j = 0;
- struct acpi_thermal_active *active = NULL;
-
- if (!tz) {
- printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
- return;
- }
-
- result = acpi_thermal_get_temperature(tz);
- if (result)
- return;
-
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
- active = &(tz->trips.active[i]);
- if (!active || !active->flags.valid)
- break;
- if (tz->temperature >= active->temperature) {
- /*
- * If the thermal temperature is greater than the
- * active threshod, unnecessary to turn off the
- * the active cooling device.
- */
- continue;
- }
- /*
- * Below Threshold?
- * ----------------
- * Turn OFF all cooling devices associated with this
- * threshold.
- */
- for (j = 0; j < active->devices.count; j++)
- result = acpi_bus_set_power(active->devices.handles[j],
- ACPI_STATE_D3);
- }
-}
-
static void acpi_thermal_check(void *data)
{
- int result = 0;
struct acpi_thermal *tz = data;
- unsigned long sleep_time = 0;
- unsigned long timeout_jiffies = 0;
- int i = 0;
- struct acpi_thermal_state state;
-
-
- if (!tz) {
- printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
- return;
- }
-
- /* Check if someone else is already running */
- if (!mutex_trylock(&tz->lock))
- return;
-
- state = tz->state;
-
- result = acpi_thermal_get_temperature(tz);
- if (result)
- goto unlock;
-
- if (!tz->tz_enabled)
- goto unlock;
-
- memset(&tz->state, 0, sizeof(tz->state));
-
- /*
- * Check Trip Points
- * -----------------
- * Compare the current temperature to the trip point values to see
- * if we've entered one of the thermal policy states. Note that
- * this function determines when a state is entered, but the
- * individual policy decides when it is exited (e.g. hysteresis).
- */
- if (tz->trips.critical.flags.valid)
- state.critical |=
- (tz->temperature >= tz->trips.critical.temperature);
- if (tz->trips.hot.flags.valid)
- state.hot |= (tz->temperature >= tz->trips.hot.temperature);
- if (tz->trips.passive.flags.valid)
- state.passive |=
- (tz->temperature >= tz->trips.passive.temperature);
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
- if (tz->trips.active[i].flags.valid)
- state.active |=
- (tz->temperature >=
- tz->trips.active[i].temperature);
-
- /*
- * Invoke Policy
- * -------------
- * Separated from the above check to allow individual policy to
- * determine when to exit a given state.
- */
- if (state.critical)
- acpi_thermal_critical(tz);
- if (state.hot)
- acpi_thermal_hot(tz);
- if (state.passive)
- acpi_thermal_passive(tz);
- if (state.active)
- acpi_thermal_active(tz);
-
- /*
- * Calculate State
- * ---------------
- * Again, separated from the above two to allow independent policy
- * decisions.
- */
- tz->state.critical = tz->trips.critical.flags.enabled;
- tz->state.hot = tz->trips.hot.flags.enabled;
- tz->state.passive = tz->trips.passive.flags.enabled;
- tz->state.active = 0;
- for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
- tz->state.active |= tz->trips.active[i].flags.enabled;
-
- /*
- * Calculate Sleep Time
- * --------------------
- * If we're in the passive state, use _TSP's value. Otherwise
- * use the default polling frequency (e.g. _TZP). If no polling
- * frequency is specified then we'll wait forever (at least until
- * a thermal event occurs). Note that _TSP and _TZD values are
- * given in 1/10th seconds (we must covert to milliseconds).
- */
- if (tz->state.passive) {
- sleep_time = tz->trips.passive.tsp * 100;
- timeout_jiffies = jiffies + (HZ * sleep_time) / 1000;
- } else if (tz->polling_frequency > 0) {
- sleep_time = tz->polling_frequency * 100;
- timeout_jiffies = round_jiffies(jiffies + (HZ * sleep_time) / 1000);
- }
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
- tz->name, tz->temperature, sleep_time));
-
- /*
- * Schedule Next Poll
- * ------------------
- */
- if (!sleep_time) {
- if (timer_pending(&(tz->timer)))
- del_timer(&(tz->timer));
- } else {
- if (timer_pending(&(tz->timer)))
- mod_timer(&(tz->timer), timeout_jiffies);
- else {
- tz->timer.data = (unsigned long)tz;
- tz->timer.function = acpi_thermal_run;
- tz->timer.expires = timeout_jiffies;
- add_timer(&(tz->timer));
- }
- }
- unlock:
- mutex_unlock(&tz->lock);
+ thermal_zone_device_update(tz->thermal_zone);
}
/* sys I/F for generic thermal sysfs support */
#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
-static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
+static int thermal_get_temp(struct thermal_zone_device *thermal,
+ unsigned long *temp)
{
struct acpi_thermal *tz = thermal->devdata;
int result;
@@ -966,25 +596,28 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
if (result)
return result;
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
+ *temp = KELVIN_TO_MILLICELSIUS(tz->temperature);
+ return 0;
}
static const char enabled[] = "kernel";
static const char disabled[] = "user";
static int thermal_get_mode(struct thermal_zone_device *thermal,
- char *buf)
+ enum thermal_device_mode *mode)
{
struct acpi_thermal *tz = thermal->devdata;
if (!tz)
return -EINVAL;
- return sprintf(buf, "%s\n", tz->tz_enabled ?
- enabled : disabled);
+ *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
+ THERMAL_DEVICE_DISABLED;
+
+ return 0;
}
static int thermal_set_mode(struct thermal_zone_device *thermal,
- const char *buf)
+ enum thermal_device_mode mode)
{
struct acpi_thermal *tz = thermal->devdata;
int enable;
@@ -995,9 +628,9 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
/*
* enable/disable thermal management from ACPI thermal driver
*/
- if (!strncmp(buf, enabled, sizeof enabled - 1))
+ if (mode == THERMAL_DEVICE_ENABLED)
enable = 1;
- else if (!strncmp(buf, disabled, sizeof disabled - 1))
+ else if (mode == THERMAL_DEVICE_DISABLED)
enable = 0;
else
return -EINVAL;
@@ -1013,7 +646,7 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
}
static int thermal_get_trip_type(struct thermal_zone_device *thermal,
- int trip, char *buf)
+ int trip, enum thermal_trip_type *type)
{
struct acpi_thermal *tz = thermal->devdata;
int i;
@@ -1022,27 +655,35 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
return -EINVAL;
if (tz->trips.critical.flags.valid) {
- if (!trip)
- return sprintf(buf, "critical\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_CRITICAL;
+ return 0;
+ }
trip--;
}
if (tz->trips.hot.flags.valid) {
- if (!trip)
- return sprintf(buf, "hot\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_HOT;
+ return 0;
+ }
trip--;
}
if (tz->trips.passive.flags.valid) {
- if (!trip)
- return sprintf(buf, "passive\n");
+ if (!trip) {
+ *type = THERMAL_TRIP_PASSIVE;
+ return 0;
+ }
trip--;
}
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++) {
- if (!trip)
- return sprintf(buf, "active%d\n", i);
+ if (!trip) {
+ *type = THERMAL_TRIP_ACTIVE;
+ return 0;
+ }
trip--;
}
@@ -1050,7 +691,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal,
}
static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
- int trip, char *buf)
+ int trip, unsigned long *temp)
{
struct acpi_thermal *tz = thermal->devdata;
int i;
@@ -1059,31 +700,39 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
return -EINVAL;
if (tz->trips.critical.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.critical.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.critical.temperature);
+ return 0;
+ }
trip--;
}
if (tz->trips.hot.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.hot.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.hot.temperature);
+ return 0;
+ }
trip--;
}
if (tz->trips.passive.flags.valid) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.passive.temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.passive.temperature);
+ return 0;
+ }
trip--;
}
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++) {
- if (!trip)
- return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
- tz->trips.active[i].temperature));
+ if (!trip) {
+ *temp = KELVIN_TO_MILLICELSIUS(
+ tz->trips.active[i].temperature);
+ return 0;
+ }
trip--;
}
@@ -1102,6 +751,29 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
return -EINVAL;
}
+static int thermal_notify(struct thermal_zone_device *thermal, int trip,
+ enum thermal_trip_type trip_type)
+{
+ u8 type = 0;
+ struct acpi_thermal *tz = thermal->devdata;
+
+ if (trip_type == THERMAL_TRIP_CRITICAL)
+ type = ACPI_THERMAL_NOTIFY_CRITICAL;
+ else if (trip_type == THERMAL_TRIP_HOT)
+ type = ACPI_THERMAL_NOTIFY_HOT;
+ else
+ return 0;
+
+ acpi_bus_generate_proc_event(tz->device, type, 1);
+ acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
+ dev_name(&tz->device->dev), type, 1);
+
+ if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
+ return 1;
+
+ return 0;
+}
+
typedef int (*cb)(struct thermal_zone_device *, int,
struct thermal_cooling_device *);
static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
@@ -1194,6 +866,7 @@ static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
.get_trip_type = thermal_get_trip_type,
.get_trip_temp = thermal_get_trip_temp,
.get_crit_temp = thermal_get_crit_temp,
+ .notify = thermal_notify,
};
static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
@@ -1214,8 +887,21 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
tz->trips.active[i].flags.valid; i++, trips++);
- tz->thermal_zone = thermal_zone_device_register("acpitz",
- trips, tz, &acpi_thermal_zone_ops);
+
+ if (tz->trips.passive.flags.valid)
+ tz->thermal_zone =
+ thermal_zone_device_register("acpitz", trips, tz,
+ &acpi_thermal_zone_ops,
+ tz->trips.passive.tc1,
+ tz->trips.passive.tc2,
+ tz->trips.passive.tsp*100,
+ tz->polling_frequency*100);
+ else
+ tz->thermal_zone =
+ thermal_zone_device_register("acpitz", trips, tz,
+ &acpi_thermal_zone_ops,
+ 0, 0, 0,
+ tz->polling_frequency);
if (IS_ERR(tz->thermal_zone))
return -ENODEV;
@@ -1447,13 +1133,13 @@ static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
if (!tz)
goto end;
- if (!tz->polling_frequency) {
+ if (!tz->thermal_zone->polling_delay) {
seq_puts(seq, "<polling disabled>\n");
goto end;
}
- seq_printf(seq, "polling frequency: %lu seconds\n",
- (tz->polling_frequency / 10));
+ seq_printf(seq, "polling frequency: %d seconds\n",
+ (tz->thermal_zone->polling_delay / 1000));
end:
return 0;
@@ -1506,7 +1192,6 @@ static int acpi_thermal_add_fs(struct acpi_device *device)
acpi_thermal_dir);
if (!acpi_device_dir(device))
return -ENODEV;
- acpi_device_dir(device)->owner = THIS_MODULE;
}
/* 'state' [R] */
@@ -1683,12 +1368,6 @@ static int acpi_thermal_add(struct acpi_device *device)
if (result)
goto unregister_thermal_zone;
- init_timer(&tz->timer);
-
- acpi_thermal_active_off(tz);
-
- acpi_thermal_check(tz);
-
status = acpi_install_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
acpi_thermal_notify, tz);
@@ -1717,36 +1396,15 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
acpi_status status = AE_OK;
struct acpi_thermal *tz = NULL;
-
if (!device || !acpi_driver_data(device))
return -EINVAL;
tz = acpi_driver_data(device);
- /* avoid timer adding new defer task */
- tz->zombie = 1;
- /* wait for running timer (on other CPUs) finish */
- del_timer_sync(&(tz->timer));
- /* synchronize deferred task */
- acpi_os_wait_events_complete(NULL);
- /* deferred task may reinsert timer */
- del_timer_sync(&(tz->timer));
-
status = acpi_remove_notify_handler(device->handle,
ACPI_DEVICE_NOTIFY,
acpi_thermal_notify);
- /* Terminate policy */
- if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
- tz->trips.passive.flags.enabled = 0;
- acpi_thermal_passive(tz);
- }
- if (tz->trips.active[0].flags.valid
- && tz->trips.active[0].flags.enabled) {
- tz->trips.active[0].flags.enabled = 0;
- acpi_thermal_active(tz);
- }
-
acpi_thermal_remove_fs(device);
acpi_thermal_unregister_thermal_zone(tz);
mutex_destroy(&tz->lock);
@@ -1875,7 +1533,6 @@ static int __init acpi_thermal_init(void)
acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
if (!acpi_thermal_dir)
return -ENODEV;
- acpi_thermal_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&acpi_thermal_driver);
if (result < 0) {
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bb5ed059114..ab06143672b 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -37,6 +37,8 @@
#include <linux/thermal.h>
#include <linux/video_output.h>
#include <linux/sort.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
#include <asm/uaccess.h>
#include <acpi/acpi_bus.h>
@@ -162,16 +164,26 @@ struct acpi_video_device_cap {
u8 _BCL:1; /*Query list of brightness control levels supported */
u8 _BCM:1; /*Set the brightness level */
u8 _BQC:1; /* Get current brightness level */
+ u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */
u8 _DDC:1; /*Return the EDID for this device */
u8 _DCS:1; /*Return status of output device */
u8 _DGS:1; /*Query graphics state */
u8 _DSS:1; /*Device state set */
};
+struct acpi_video_brightness_flags {
+ u8 _BCL_no_ac_battery_levels:1; /* no AC/Battery levels in _BCL */
+ u8 _BCL_reversed:1; /* _BCL package is in a reversed order*/
+ u8 _BCL_use_index:1; /* levels in _BCL are index values */
+ u8 _BCM_use_index:1; /* input of _BCM is an index value */
+ u8 _BQC_use_index:1; /* _BQC returns an index value */
+};
+
struct acpi_video_device_brightness {
int curr;
int count;
int *levels;
+ struct acpi_video_brightness_flags flags;
};
struct acpi_video_device {
@@ -189,7 +201,7 @@ struct acpi_video_device {
/* bus */
static int acpi_video_bus_info_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_info_fops = {
+static const struct file_operations acpi_video_bus_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_info_open_fs,
.read = seq_read,
@@ -198,7 +210,7 @@ static struct file_operations acpi_video_bus_info_fops = {
};
static int acpi_video_bus_ROM_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_ROM_fops = {
+static const struct file_operations acpi_video_bus_ROM_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_ROM_open_fs,
.read = seq_read,
@@ -208,7 +220,7 @@ static struct file_operations acpi_video_bus_ROM_fops = {
static int acpi_video_bus_POST_info_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_bus_POST_info_fops = {
+static const struct file_operations acpi_video_bus_POST_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_POST_info_open_fs,
.read = seq_read,
@@ -217,19 +229,25 @@ static struct file_operations acpi_video_bus_POST_info_fops = {
};
static int acpi_video_bus_POST_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_POST_fops = {
+static ssize_t acpi_video_bus_write_POST(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_POST_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_POST_open_fs,
.read = seq_read,
+ .write = acpi_video_bus_write_POST,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_bus_DOS_open_fs(struct inode *inode, struct file *file);
-static struct file_operations acpi_video_bus_DOS_fops = {
+static ssize_t acpi_video_bus_write_DOS(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_bus_DOS_fops = {
.owner = THIS_MODULE,
.open = acpi_video_bus_DOS_open_fs,
.read = seq_read,
+ .write = acpi_video_bus_write_DOS,
.llseek = seq_lseek,
.release = single_release,
};
@@ -237,7 +255,7 @@ static struct file_operations acpi_video_bus_DOS_fops = {
/* device */
static int acpi_video_device_info_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_info_fops = {
+static const struct file_operations acpi_video_device_info_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_info_open_fs,
.read = seq_read,
@@ -247,27 +265,33 @@ static struct file_operations acpi_video_device_info_fops = {
static int acpi_video_device_state_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_state_fops = {
+static ssize_t acpi_video_device_write_state(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
+static const struct file_operations acpi_video_device_state_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_state_open_fs,
.read = seq_read,
+ .write = acpi_video_device_write_state,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_device_brightness_open_fs(struct inode *inode,
struct file *file);
+static ssize_t acpi_video_device_write_brightness(struct file *file,
+ const char __user *buffer, size_t count, loff_t *data);
static struct file_operations acpi_video_device_brightness_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_brightness_open_fs,
.read = seq_read,
+ .write = acpi_video_device_write_brightness,
.llseek = seq_lseek,
.release = single_release,
};
static int acpi_video_device_EDID_open_fs(struct inode *inode,
struct file *file);
-static struct file_operations acpi_video_device_EDID_fops = {
+static const struct file_operations acpi_video_device_EDID_fops = {
.owner = THIS_MODULE,
.open = acpi_video_device_EDID_open_fs,
.read = seq_read,
@@ -275,7 +299,7 @@ static struct file_operations acpi_video_device_EDID_fops = {
.release = single_release,
};
-static char device_decode[][30] = {
+static const char device_decode[][30] = {
"motherboard VGA device",
"PCI VGA device",
"AGP VGA device",
@@ -294,7 +318,7 @@ static int acpi_video_device_lcd_get_level_current(
unsigned long long *level);
static int acpi_video_get_next_level(struct acpi_video_device *device,
u32 level_current, u32 event);
-static void acpi_video_switch_brightness(struct acpi_video_device *device,
+static int acpi_video_switch_brightness(struct acpi_video_device *device,
int event);
static int acpi_video_device_get_state(struct acpi_video_device *device,
unsigned long long *state);
@@ -308,7 +332,9 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
int i;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
- acpi_video_device_lcd_get_level_current(vd, &cur_level);
+
+ if (acpi_video_device_lcd_get_level_current(vd, &cur_level))
+ return -EINVAL;
for (i = 2; i < vd->brightness->count; i++) {
if (vd->brightness->levels[i] == cur_level)
/* The first two entries are special - see page 575
@@ -320,12 +346,12 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
static int acpi_video_set_brightness(struct backlight_device *bd)
{
- int request_level = bd->props.brightness+2;
+ int request_level = bd->props.brightness + 2;
struct acpi_video_device *vd =
(struct acpi_video_device *)bl_get_data(bd);
- acpi_video_device_lcd_set_level(vd,
- vd->brightness->levels[request_level]);
- return 0;
+
+ return acpi_video_device_lcd_set_level(vd,
+ vd->brightness->levels[request_level]);
}
static struct backlight_ops acpi_backlight_ops = {
@@ -358,32 +384,37 @@ static struct output_properties acpi_output_properties = {
/* thermal cooling device callbacks */
-static int video_get_max_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_max_state(struct thermal_cooling_device *cdev, unsigned
+ long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
- return sprintf(buf, "%d\n", video->brightness->count - 3);
+ *state = video->brightness->count - 3;
+ return 0;
}
-static int video_get_cur_state(struct thermal_cooling_device *cdev, char *buf)
+static int video_get_cur_state(struct thermal_cooling_device *cdev, unsigned
+ long *state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
unsigned long long level;
- int state;
+ int offset;
- acpi_video_device_lcd_get_level_current(video, &level);
- for (state = 2; state < video->brightness->count; state++)
- if (level == video->brightness->levels[state])
- return sprintf(buf, "%d\n",
- video->brightness->count - state - 1);
+ if (acpi_video_device_lcd_get_level_current(video, &level))
+ return -EINVAL;
+ for (offset = 2; offset < video->brightness->count; offset++)
+ if (level == video->brightness->levels[offset]) {
+ *state = video->brightness->count - offset - 1;
+ return 0;
+ }
return -EINVAL;
}
static int
-video_set_cur_state(struct thermal_cooling_device *cdev, unsigned int state)
+video_set_cur_state(struct thermal_cooling_device *cdev, unsigned long state)
{
struct acpi_device *device = cdev->devdata;
struct acpi_video_device *video = acpi_driver_data(device);
@@ -479,34 +510,68 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,
static int
acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
{
- int status = AE_OK;
+ int status;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
int state;
-
arg0.integer.value = level;
- if (device->cap._BCM)
- status = acpi_evaluate_object(device->dev->handle, "_BCM",
- &args, NULL);
+ status = acpi_evaluate_object(device->dev->handle, "_BCM",
+ &args, NULL);
+ if (ACPI_FAILURE(status)) {
+ ACPI_ERROR((AE_INFO, "Evaluating _BCM failed"));
+ return -EIO;
+ }
+
device->brightness->curr = level;
for (state = 2; state < device->brightness->count; state++)
- if (level == device->brightness->levels[state])
- device->backlight->props.brightness = state - 2;
+ if (level == device->brightness->levels[state]) {
+ if (device->backlight)
+ device->backlight->props.brightness = state - 2;
+ return 0;
+ }
- return status;
+ ACPI_ERROR((AE_INFO, "Current brightness invalid"));
+ return -EINVAL;
}
static int
acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
unsigned long long *level)
{
- if (device->cap._BQC)
- return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL,
- level);
+ acpi_status status = AE_OK;
+
+ if (device->cap._BQC || device->cap._BCQ) {
+ char *buf = device->cap._BQC ? "_BQC" : "_BCQ";
+
+ status = acpi_evaluate_integer(device->dev->handle, buf,
+ NULL, level);
+ if (ACPI_SUCCESS(status)) {
+ if (device->brightness->flags._BQC_use_index) {
+ if (device->brightness->flags._BCL_reversed)
+ *level = device->brightness->count
+ - 3 - (*level);
+ *level = device->brightness->levels[*level + 2];
+
+ }
+ device->brightness->curr = *level;
+ return 0;
+ } else {
+ /* Fixme:
+ * should we return an error or ignore this failure?
+ * dev->brightness->curr is a cached value which stores
+ * the correct current backlight level in most cases.
+ * ACPI video backlight still works w/ buggy _BQC.
+ * http://bugzilla.kernel.org/show_bug.cgi?id=12233
+ */
+ ACPI_WARNING((AE_INFO, "Evaluating %s failed", buf));
+ device->cap._BQC = device->cap._BCQ = 0;
+ }
+ }
+
*level = device->brightness->curr;
- return AE_OK;
+ return 0;
}
static int
@@ -655,9 +720,11 @@ static int
acpi_video_init_brightness(struct acpi_video_device *device)
{
union acpi_object *obj = NULL;
- int i, max_level = 0, count = 0;
+ int i, max_level = 0, count = 0, level_ac_battery = 0;
+ unsigned long long level, level_old;
union acpi_object *o;
struct acpi_video_device_brightness *br = NULL;
+ int result = -EINVAL;
if (!ACPI_SUCCESS(acpi_video_device_lcd_query_levels(device, &obj))) {
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Could not query available "
@@ -671,13 +738,16 @@ acpi_video_init_brightness(struct acpi_video_device *device)
br = kzalloc(sizeof(*br), GFP_KERNEL);
if (!br) {
printk(KERN_ERR "can't allocate memory\n");
+ result = -ENOMEM;
goto out;
}
- br->levels = kmalloc(obj->package.count * sizeof *(br->levels),
+ br->levels = kmalloc((obj->package.count + 2) * sizeof *(br->levels),
GFP_KERNEL);
- if (!br->levels)
+ if (!br->levels) {
+ result = -ENOMEM;
goto out_free;
+ }
for (i = 0; i < obj->package.count; i++) {
o = (union acpi_object *)&obj->package.elements[i];
@@ -692,18 +762,86 @@ acpi_video_init_brightness(struct acpi_video_device *device)
count++;
}
- /* don't sort the first two brightness levels */
- sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
- acpi_video_cmp_level, NULL);
-
- if (count < 2)
- goto out_free_levels;
+ /*
+ * some buggy BIOS don't export the levels
+ * when machine is on AC/Battery in _BCL package.
+ * In this case, the first two elements in _BCL packages
+ * are also supported brightness levels that OS should take care of.
+ */
+ for (i = 2; i < count; i++)
+ if (br->levels[i] == br->levels[0] ||
+ br->levels[i] == br->levels[1])
+ level_ac_battery++;
+
+ if (level_ac_battery < 2) {
+ level_ac_battery = 2 - level_ac_battery;
+ br->flags._BCL_no_ac_battery_levels = 1;
+ for (i = (count - 1 + level_ac_battery); i >= 2; i--)
+ br->levels[i] = br->levels[i - level_ac_battery];
+ count += level_ac_battery;
+ } else if (level_ac_battery > 2)
+ ACPI_ERROR((AE_INFO, "Too many duplicates in _BCL package\n"));
+
+ /* Check if the _BCL package is in a reversed order */
+ if (max_level == br->levels[2]) {
+ br->flags._BCL_reversed = 1;
+ sort(&br->levels[2], count - 2, sizeof(br->levels[2]),
+ acpi_video_cmp_level, NULL);
+ } else if (max_level != br->levels[count - 1])
+ ACPI_ERROR((AE_INFO,
+ "Found unordered _BCL package\n"));
br->count = count;
device->brightness = br;
- ACPI_DEBUG_PRINT((ACPI_DB_INFO, "found %d brightness levels\n", count));
+
+ /* Check the input/output of _BQC/_BCL/_BCM */
+ if ((max_level < 100) && (max_level <= (count - 2)))
+ br->flags._BCL_use_index = 1;
+
+ /*
+ * _BCM is always consistent with _BCL,
+ * at least for all the laptops we have ever seen.
+ */
+ br->flags._BCM_use_index = br->flags._BCL_use_index;
+
+ /* _BQC uses INDEX while _BCL uses VALUE in some laptops */
+ br->curr = max_level;
+ result = acpi_video_device_lcd_get_level_current(device, &level_old);
+ if (result)
+ goto out_free_levels;
+
+ result = acpi_video_device_lcd_set_level(device, br->curr);
+ if (result)
+ goto out_free_levels;
+
+ result = acpi_video_device_lcd_get_level_current(device, &level);
+ if (result)
+ goto out_free_levels;
+
+ if ((level != level_old) && !br->flags._BCM_use_index) {
+ /* Note:
+ * This piece of code does not work correctly if the current
+ * brightness levels is 0.
+ * But I guess boxes that boot with such a dark screen are rare
+ * and no more code is needed to cover this specifial case.
+ */
+
+ if (level_ac_battery != 2) {
+ /*
+ * For now, we don't support the _BCL like this:
+ * 16, 15, 0, 1, 2, 3, ..., 14, 15, 16
+ * because we may mess up the index returned by _BQC.
+ * Plus: we have not got a box like this.
+ */
+ ACPI_ERROR((AE_INFO, "_BCL not supported\n"));
+ }
+ br->flags._BQC_use_index = 1;
+ }
+
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "found %d brightness levels\n", count - 2));
kfree(obj);
- return max_level;
+ return result;
out_free_levels:
kfree(br->levels);
@@ -712,7 +850,7 @@ out_free:
out:
device->brightness = NULL;
kfree(obj);
- return 0;
+ return result;
}
/*
@@ -729,7 +867,6 @@ out:
static void acpi_video_device_find_cap(struct acpi_video_device *device)
{
acpi_handle h_dummy1;
- u32 max_level = 0;
memset(&device->cap, 0, sizeof(device->cap));
@@ -745,6 +882,12 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
}
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle,"_BQC",&h_dummy1)))
device->cap._BQC = 1;
+ else if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_BCQ",
+ &h_dummy1))) {
+ printk(KERN_WARNING FW_BUG "_BCQ is used instead of _BQC\n");
+ device->cap._BCQ = 1;
+ }
+
if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) {
device->cap._DDC = 1;
}
@@ -758,13 +901,14 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->cap._DSS = 1;
}
- if (acpi_video_backlight_support())
- max_level = acpi_video_init_brightness(device);
-
- if (device->cap._BCL && device->cap._BCM && max_level > 0) {
+ if (acpi_video_backlight_support()) {
int result;
static int count = 0;
char *name;
+
+ result = acpi_video_init_brightness(device);
+ if (result)
+ return;
name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
if (!name)
return;
@@ -773,18 +917,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->backlight = backlight_device_register(name,
NULL, device, &acpi_backlight_ops);
device->backlight->props.max_brightness = device->brightness->count-3;
- /*
- * If there exists the _BQC object, the _BQC object will be
- * called to get the current backlight brightness. Otherwise
- * the brightness will be set to the maximum.
- */
- if (device->cap._BQC)
- device->backlight->props.brightness =
- acpi_video_get_brightness(device->backlight);
- else
- device->backlight->props.brightness =
- device->backlight->props.max_brightness;
- backlight_update_status(device->backlight);
kfree(name);
device->cdev = thermal_cooling_device_register("LCD",
@@ -1061,13 +1193,12 @@ acpi_video_device_write_brightness(struct file *file,
/* validate through the list of available levels */
for (i = 2; i < dev->brightness->count; i++)
if (level == dev->brightness->levels[i]) {
- if (ACPI_SUCCESS
- (acpi_video_device_lcd_set_level(dev, level)))
- dev->brightness->curr = level;
+ if (!acpi_video_device_lcd_set_level(dev, level))
+ return count;
break;
}
- return count;
+ return -EINVAL;
}
static int acpi_video_device_EDID_seq_show(struct seq_file *seq, void *offset)
@@ -1125,8 +1256,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
if (!device_dir)
return -ENOMEM;
- device_dir->owner = THIS_MODULE;
-
/* 'info' [R] */
entry = proc_create_data("info", S_IRUGO, device_dir,
&acpi_video_device_info_fops, acpi_driver_data(device));
@@ -1134,7 +1263,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
goto err_remove_dir;
/* 'state' [R/W] */
- acpi_video_device_state_fops.write = acpi_video_device_write_state;
entry = proc_create_data("state", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_device_state_fops,
@@ -1143,8 +1271,6 @@ static int acpi_video_device_add_fs(struct acpi_device *device)
goto err_remove_info;
/* 'brightness' [R/W] */
- acpi_video_device_brightness_fops.write =
- acpi_video_device_write_brightness;
entry = proc_create_data("brightness", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_device_brightness_fops,
@@ -1403,8 +1529,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
if (!device_dir)
return -ENOMEM;
- device_dir->owner = THIS_MODULE;
-
/* 'info' [R] */
entry = proc_create_data("info", S_IRUGO, device_dir,
&acpi_video_bus_info_fops,
@@ -1427,7 +1551,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
goto err_remove_rom;
/* 'POST' [R/W] */
- acpi_video_bus_POST_fops.write = acpi_video_bus_write_POST;
entry = proc_create_data("POST", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_bus_POST_fops,
@@ -1436,7 +1559,6 @@ static int acpi_video_bus_add_fs(struct acpi_device *device)
goto err_remove_post_info;
/* 'DOS' [R/W] */
- acpi_video_bus_DOS_fops.write = acpi_video_bus_write_DOS;
entry = proc_create_data("DOS", S_IFREG | S_IRUGO | S_IWUSR,
device_dir,
&acpi_video_bus_DOS_fops,
@@ -1749,15 +1871,29 @@ acpi_video_get_next_level(struct acpi_video_device *device,
}
}
-static void
+static int
acpi_video_switch_brightness(struct acpi_video_device *device, int event)
{
unsigned long long level_current, level_next;
+ int result = -EINVAL;
+
if (!device->brightness)
- return;
- acpi_video_device_lcd_get_level_current(device, &level_current);
+ goto out;
+
+ result = acpi_video_device_lcd_get_level_current(device,
+ &level_current);
+ if (result)
+ goto out;
+
level_next = acpi_video_get_next_level(device, level_current, event);
- acpi_video_device_lcd_set_level(device, level_next);
+
+ result = acpi_video_device_lcd_set_level(device, level_next);
+
+out:
+ if (result)
+ printk(KERN_ERR PREFIX "Failed to switch the brightness\n");
+
+ return result;
}
static int
@@ -2124,14 +2260,33 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
return 0;
}
-static int __init acpi_video_init(void)
+static int __init intel_opregion_present(void)
+{
+#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
+ struct pci_dev *dev = NULL;
+ u32 address;
+
+ for_each_pci_dev(dev) {
+ if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
+ continue;
+ if (dev->vendor != PCI_VENDOR_ID_INTEL)
+ continue;
+ pci_read_config_dword(dev, 0xfc, &address);
+ if (!address)
+ continue;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+int acpi_video_register(void)
{
int result = 0;
acpi_video_dir = proc_mkdir(ACPI_VIDEO_CLASS, acpi_root_dir);
if (!acpi_video_dir)
return -ENODEV;
- acpi_video_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&acpi_video_bus);
if (result < 0) {
@@ -2141,6 +2296,22 @@ static int __init acpi_video_init(void)
return 0;
}
+EXPORT_SYMBOL(acpi_video_register);
+
+/*
+ * This is kind of nasty. Hardware using Intel chipsets may require
+ * the video opregion code to be run first in order to initialise
+ * state before any ACPI video calls are made. To handle this we defer
+ * registration of the video class until the opregion code has run.
+ */
+
+static int __init acpi_video_init(void)
+{
+ if (intel_opregion_present())
+ return 0;
+
+ return acpi_video_register();
+}
static void __exit acpi_video_exit(void)
{
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
index 50e3d2dbf3a..09737275e25 100644
--- a/drivers/acpi/video_detect.c
+++ b/drivers/acpi/video_detect.c
@@ -55,6 +55,9 @@ acpi_backlight_cap_match(acpi_handle handle, u32 level, void *context,
ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found generic backlight "
"support\n"));
*cap |= ACPI_VIDEO_BACKLIGHT;
+ if (ACPI_FAILURE(acpi_get_handle(handle, "_BQC", &h_dummy)))
+ printk(KERN_WARNING FW_BUG PREFIX "ACPI brightness "
+ "control misses _BQC function\n");
/* We have backlight support, no need to scan further */
return AE_CTRL_TERMINATE;
}
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c
index 2d34806d45d..5aee8c26cc9 100644
--- a/drivers/acpi/wakeup.c
+++ b/drivers/acpi/wakeup.c
@@ -8,6 +8,8 @@
#include <acpi/acpi_drivers.h>
#include <linux/kernel.h>
#include <linux/types.h>
+
+#include "internal.h"
#include "sleep.h"
#define _COMPONENT ACPI_SYSTEM_COMPONENT
@@ -136,13 +138,10 @@ void acpi_disable_wakeup_device(u8 sleep_state)
spin_unlock(&acpi_device_lock);
}
-static int __init acpi_wakeup_device_init(void)
+int __init acpi_wakeup_device_init(void)
{
struct list_head *node, *next;
- if (acpi_disabled)
- return 0;
-
spin_lock(&acpi_device_lock);
list_for_each_safe(node, next, &acpi_wakeup_device_list) {
struct acpi_device *dev = container_of(node,
@@ -163,5 +162,3 @@ static int __init acpi_wakeup_device_init(void)
spin_unlock(&acpi_device_lock);
return 0;
}
-
-late_initcall(acpi_wakeup_device_init);
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 0bcf2646467..9120717c070 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -86,7 +86,7 @@ config ATA_SFF
For users with exclusively modern controllers like AHCI,
Silicon Image 3124, or Marvell 6440, you may choose to
- disable this uneeded SFF support.
+ disable this unneeded SFF support.
If unsure, say Y.
diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig
index 14b9d5f4c20..c07e725ea93 100644
--- a/drivers/auxdisplay/Kconfig
+++ b/drivers/auxdisplay/Kconfig
@@ -6,7 +6,6 @@
#
menuconfig AUXDISPLAY
- depends on PARPORT
bool "Auxiliary Display support"
---help---
Say Y here to get to see options for auxiliary display drivers.
@@ -14,7 +13,7 @@ menuconfig AUXDISPLAY
If you say N, all options in this submenu will be skipped and disabled.
-if AUXDISPLAY && PARPORT
+if AUXDISPLAY
config KS0108
tristate "KS0108 LCD Controller"
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 5b257a57bc5..e62a4ccea54 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -119,7 +119,7 @@ static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
#define print_cpus_func(type) \
static ssize_t print_cpus_##type(struct sysdev_class *class, char *buf) \
{ \
- return print_cpus_map(buf, &cpu_##type##_map); \
+ return print_cpus_map(buf, cpu_##type##_mask); \
} \
static struct sysdev_class_attribute attr_##type##_map = \
_SYSDEV_CLASS_ATTR(type, 0444, print_cpus_##type, NULL)
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c
index 5e039d4f877..9f0e672f4be 100644
--- a/drivers/base/iommu.c
+++ b/drivers/base/iommu.c
@@ -31,7 +31,7 @@ void register_iommu(struct iommu_ops *ops)
iommu_ops = ops;
}
-bool iommu_found()
+bool iommu_found(void)
{
return iommu_ops != NULL;
}
@@ -98,3 +98,10 @@ phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
return iommu_ops->iova_to_phys(domain, iova);
}
EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
+
+int iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return iommu_ops->domain_has_cap(domain, cap);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
diff --git a/drivers/base/node.c b/drivers/base/node.c
index f8f578a71b2..40b809742a1 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -24,7 +24,7 @@ static struct sysdev_class node_class = {
static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
{
struct node *node_dev = to_node(dev);
- node_to_cpumask_ptr(mask, node_dev->sysdev.id);
+ const struct cpumask *mask = cpumask_of_node(node_dev->sysdev.id);
int len;
/* 2008/04/07: buf currently PAGE_SIZE, need 9 chars per 32 bits. */
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index e255341682c..69b4ddb7de3 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -23,6 +23,7 @@
#include <linux/pm.h>
#include <linux/resume-trace.h>
#include <linux/rwsem.h>
+#include <linux/interrupt.h>
#include "../base.h"
#include "power.h"
@@ -349,7 +350,8 @@ static int resume_device_noirq(struct device *dev, pm_message_t state)
* Execute the appropriate "noirq resume" callback for all devices marked
* as DPM_OFF_IRQ.
*
- * Must be called with interrupts disabled and only one CPU running.
+ * Must be called under dpm_list_mtx. Device drivers should not receive
+ * interrupts while it's being executed.
*/
static void dpm_power_up(pm_message_t state)
{
@@ -370,14 +372,13 @@ static void dpm_power_up(pm_message_t state)
* device_power_up - Turn on all devices that need special attention.
* @state: PM transition of the system being carried out.
*
- * Power on system devices, then devices that required we shut them down
- * with interrupts disabled.
- *
- * Must be called with interrupts disabled.
+ * Call the "early" resume handlers and enable device drivers to receive
+ * interrupts.
*/
void device_power_up(pm_message_t state)
{
dpm_power_up(state);
+ resume_device_irqs();
}
EXPORT_SYMBOL_GPL(device_power_up);
@@ -602,16 +603,17 @@ static int suspend_device_noirq(struct device *dev, pm_message_t state)
* device_power_down - Shut down special devices.
* @state: PM transition of the system being carried out.
*
- * Power down devices that require interrupts to be disabled.
- * Then power down system devices.
+ * Prevent device drivers from receiving interrupts and call the "late"
+ * suspend handlers.
*
- * Must be called with interrupts disabled and only one CPU running.
+ * Must be called under dpm_list_mtx.
*/
int device_power_down(pm_message_t state)
{
struct device *dev;
int error = 0;
+ suspend_device_irqs();
list_for_each_entry_reverse(dev, &dpm_list, power.entry) {
error = suspend_device_noirq(dev, state);
if (error) {
@@ -621,7 +623,7 @@ int device_power_down(pm_message_t state)
dev->power.status = DPM_OFF_IRQ;
}
if (error)
- dpm_power_up(resume_event(state));
+ device_power_up(resume_event(state));
return error;
}
EXPORT_SYMBOL_GPL(device_power_down);
diff --git a/drivers/base/sys.c b/drivers/base/sys.c
index cbd36cf59a0..3236b434b96 100644
--- a/drivers/base/sys.c
+++ b/drivers/base/sys.c
@@ -22,6 +22,7 @@
#include <linux/pm.h>
#include <linux/device.h>
#include <linux/mutex.h>
+#include <linux/interrupt.h>
#include "base.h"
@@ -299,7 +300,7 @@ void sysdev_unregister(struct sys_device *sysdev)
* and the class driver.
*
* Note: The list is iterated in reverse order, so that we shut down
- * child devices before we shut down thier parents. The list ordering
+ * child devices before we shut down their parents. The list ordering
* is guaranteed by virtue of the fact that child devices are registered
* after their parents.
*/
@@ -369,6 +370,13 @@ int sysdev_suspend(pm_message_t state)
struct sysdev_driver *drv, *err_drv;
int ret;
+ pr_debug("Checking wake-up interrupts\n");
+
+ /* Return error code if there are any wake-up interrupts pending */
+ ret = check_wakeup_irqs();
+ if (ret)
+ return ret;
+
pr_debug("Suspending System Devices\n");
list_for_each_entry_reverse(cls, &system_kset->list, kset.kobj.entry) {
diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
index 45c5a33daf4..31693bc2444 100644
--- a/drivers/block/aoe/aoecmd.c
+++ b/drivers/block/aoe/aoecmd.c
@@ -4,6 +4,7 @@
* Filesystem request handling methods
*/
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/blkdev.h>
#include <linux/skbuff.h>
@@ -267,7 +268,7 @@ aoecmd_ata_rw(struct aoedev *d)
writebit = 0;
}
- ah->cmdstat = WIN_READ | writebit | extbit;
+ ah->cmdstat = ATA_CMD_PIO_READ | writebit | extbit;
/* mark all tracking fields and load out */
buf->nframesout += 1;
@@ -362,10 +363,10 @@ resend(struct aoedev *d, struct aoetgt *t, struct frame *f)
switch (ah->cmdstat) {
default:
break;
- case WIN_READ:
- case WIN_READ_EXT:
- case WIN_WRITE:
- case WIN_WRITE_EXT:
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
put_lba(ah, f->lba);
n = f->bcnt;
@@ -812,8 +813,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
d->htgt = NULL;
n = ahout->scnt << 9;
switch (ahout->cmdstat) {
- case WIN_READ:
- case WIN_READ_EXT:
+ case ATA_CMD_PIO_READ:
+ case ATA_CMD_PIO_READ_EXT:
if (skb->len - sizeof *hin - sizeof *ahin < n) {
printk(KERN_ERR
"aoe: %s. skb->len=%d need=%ld\n",
@@ -823,8 +824,8 @@ aoecmd_ata_rsp(struct sk_buff *skb)
return;
}
memcpy(f->bufaddr, ahin+1, n);
- case WIN_WRITE:
- case WIN_WRITE_EXT:
+ case ATA_CMD_PIO_WRITE:
+ case ATA_CMD_PIO_WRITE_EXT:
ifp = getif(t, skb->dev);
if (ifp) {
ifp->lost = 0;
@@ -838,7 +839,7 @@ aoecmd_ata_rsp(struct sk_buff *skb)
goto xmit;
}
break;
- case WIN_IDENTIFY:
+ case ATA_CMD_ID_ATA:
if (skb->len - sizeof *hin - sizeof *ahin < 512) {
printk(KERN_INFO
"aoe: runt data size in ataid. skb->len=%d\n",
@@ -914,7 +915,7 @@ aoecmd_ata_id(struct aoedev *d)
/* set up ata header */
ah->scnt = 1;
- ah->cmdstat = WIN_IDENTIFY;
+ ah->cmdstat = ATA_CMD_ID_ATA;
ah->lba3 = 0xa0;
skb->dev = t->ifp->nd;
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index c2c95e61450..1300df6f164 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -177,6 +177,7 @@ static int print_unex = 1;
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/mod_devicetable.h>
#include <linux/buffer_head.h> /* for invalidate_buffers() */
#include <linux/mutex.h>
@@ -4597,6 +4598,13 @@ MODULE_AUTHOR("Alain L. Knaff");
MODULE_SUPPORTED_DEVICE("fd");
MODULE_LICENSE("GPL");
+/* This doesn't actually get used other than for module information */
+static const struct pnp_device_id floppy_pnpids[] = {
+ { "PNP0700", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(pnp, floppy_pnpids);
+
#else
__setup("floppy=", floppy_setup);
diff --git a/drivers/block/hd.c b/drivers/block/hd.c
index 482c0c4b964..3c11f062a18 100644
--- a/drivers/block/hd.c
+++ b/drivers/block/hd.c
@@ -42,6 +42,8 @@
#include <linux/ata.h>
#include <linux/hdreg.h>
+#define HD_IRQ 14
+
#define REALLY_SLOW_IO
#include <asm/system.h>
#include <asm/io.h>
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 2621ed2ce6d..40b17d3b55a 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -1192,6 +1192,30 @@ loop_get_status64(struct loop_device *lo, struct loop_info64 __user *arg) {
return err;
}
+static int loop_set_capacity(struct loop_device *lo, struct block_device *bdev)
+{
+ int err;
+ sector_t sec;
+ loff_t sz;
+
+ err = -ENXIO;
+ if (unlikely(lo->lo_state != Lo_bound))
+ goto out;
+ err = figure_loop_size(lo);
+ if (unlikely(err))
+ goto out;
+ sec = get_capacity(lo->lo_disk);
+ /* the width of sector_t may be narrow for bit-shift */
+ sz = sec;
+ sz <<= 9;
+ mutex_lock(&bdev->bd_mutex);
+ bd_set_size(bdev, sz);
+ mutex_unlock(&bdev->bd_mutex);
+
+ out:
+ return err;
+}
+
static int lo_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
@@ -1224,6 +1248,11 @@ static int lo_ioctl(struct block_device *bdev, fmode_t mode,
case LOOP_GET_STATUS64:
err = loop_get_status64(lo, (struct loop_info64 __user *) arg);
break;
+ case LOOP_SET_CAPACITY:
+ err = -EPERM;
+ if ((mode & FMODE_WRITE) || capable(CAP_SYS_ADMIN))
+ err = loop_set_capacity(lo, bdev);
+ break;
default:
err = lo->ioctl ? lo->ioctl(lo, cmd, arg) : -EINVAL;
}
@@ -1371,6 +1400,7 @@ static int lo_compat_ioctl(struct block_device *bdev, fmode_t mode,
lo, (struct compat_loop_info __user *) arg);
mutex_unlock(&lo->lo_ctl_mutex);
break;
+ case LOOP_SET_CAPACITY:
case LOOP_CLR_FD:
case LOOP_GET_STATUS64:
case LOOP_SET_STATUS64:
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 8299e2d3b61..4d6de4f15cc 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -4,7 +4,7 @@
* Note that you can not swap over this thing, yet. Seems to work but
* deadlocks sometimes - you can not swap over TCP in general.
*
- * Copyright 1997-2000 Pavel Machek <pavel@ucw.cz>
+ * Copyright 1997-2000, 2008 Pavel Machek <pavel@suse.cz>
* Parts copyright 2001 Steven Whitehouse <steve@chygwyn.com>
*
* This file is released under GPLv2 or later.
@@ -276,7 +276,7 @@ static int nbd_send_req(struct nbd_device *lo, struct request *req)
return 0;
error_out:
- return 1;
+ return -EIO;
}
static struct request *nbd_find_request(struct nbd_device *lo,
@@ -467,9 +467,7 @@ static void nbd_handle_req(struct nbd_device *lo, struct request *req)
mutex_unlock(&lo->tx_lock);
printk(KERN_ERR "%s: Attempted send on closed socket\n",
lo->disk->disk_name);
- req->errors++;
- nbd_end_request(req);
- return;
+ goto error_out;
}
lo->active_req = req;
@@ -531,7 +529,7 @@ static int nbd_thread(void *data)
* { printk( "Warning: Ignoring result!\n"); nbd_end_request( req ); }
*/
-static void do_nbd_request(struct request_queue * q)
+static void do_nbd_request(struct request_queue *q)
{
struct request *req;
@@ -568,27 +566,17 @@ static void do_nbd_request(struct request_queue * q)
}
}
-static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
- unsigned int cmd, unsigned long arg)
-{
- struct nbd_device *lo = bdev->bd_disk->private_data;
- struct file *file;
- int error;
- struct request sreq ;
- struct task_struct *thread;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
-
- BUG_ON(lo->magic != LO_MAGIC);
-
- /* Anyone capable of this syscall can do *real bad* things */
- dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
- lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
+/* Must be called with tx_lock held */
+static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *lo,
+ unsigned int cmd, unsigned long arg)
+{
switch (cmd) {
- case NBD_DISCONNECT:
+ case NBD_DISCONNECT: {
+ struct request sreq;
+
printk(KERN_INFO "%s: NBD_DISCONNECT\n", lo->disk->disk_name);
+
blk_rq_init(NULL, &sreq);
sreq.cmd_type = REQ_TYPE_SPECIAL;
nbd_cmd(&sreq) = NBD_CMD_DISC;
@@ -599,29 +587,29 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
*/
sreq.sector = 0;
sreq.nr_sectors = 0;
- if (!lo->sock)
+ if (!lo->sock)
return -EINVAL;
- mutex_lock(&lo->tx_lock);
- nbd_send_req(lo, &sreq);
- mutex_unlock(&lo->tx_lock);
+ nbd_send_req(lo, &sreq);
return 0;
+ }
- case NBD_CLEAR_SOCK:
- error = 0;
- mutex_lock(&lo->tx_lock);
+ case NBD_CLEAR_SOCK: {
+ struct file *file;
+
lo->sock = NULL;
- mutex_unlock(&lo->tx_lock);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
BUG_ON(!list_empty(&lo->queue_head));
if (file)
fput(file);
- return error;
- case NBD_SET_SOCK:
+ return 0;
+ }
+
+ case NBD_SET_SOCK: {
+ struct file *file;
if (lo->file)
return -EBUSY;
- error = -EINVAL;
file = fget(arg);
if (file) {
struct inode *inode = file->f_path.dentry->d_inode;
@@ -630,12 +618,14 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
lo->sock = SOCKET_I(inode);
if (max_part > 0)
bdev->bd_invalidated = 1;
- error = 0;
+ return 0;
} else {
fput(file);
}
}
- return error;
+ return -EINVAL;
+ }
+
case NBD_SET_BLKSIZE:
lo->blksize = arg;
lo->bytesize &= ~(lo->blksize-1);
@@ -643,35 +633,50 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
set_blocksize(bdev, lo->blksize);
set_capacity(lo->disk, lo->bytesize >> 9);
return 0;
+
case NBD_SET_SIZE:
lo->bytesize = arg & ~(lo->blksize-1);
bdev->bd_inode->i_size = lo->bytesize;
set_blocksize(bdev, lo->blksize);
set_capacity(lo->disk, lo->bytesize >> 9);
return 0;
+
case NBD_SET_TIMEOUT:
lo->xmit_timeout = arg * HZ;
return 0;
+
case NBD_SET_SIZE_BLOCKS:
lo->bytesize = ((u64) arg) * lo->blksize;
bdev->bd_inode->i_size = lo->bytesize;
set_blocksize(bdev, lo->blksize);
set_capacity(lo->disk, lo->bytesize >> 9);
return 0;
- case NBD_DO_IT:
+
+ case NBD_DO_IT: {
+ struct task_struct *thread;
+ struct file *file;
+ int error;
+
if (lo->pid)
return -EBUSY;
if (!lo->file)
return -EINVAL;
+
+ mutex_unlock(&lo->tx_lock);
+
thread = kthread_create(nbd_thread, lo, lo->disk->disk_name);
- if (IS_ERR(thread))
+ if (IS_ERR(thread)) {
+ mutex_lock(&lo->tx_lock);
return PTR_ERR(thread);
+ }
wake_up_process(thread);
error = nbd_do_it(lo);
kthread_stop(thread);
+
+ mutex_lock(&lo->tx_lock);
if (error)
return error;
- sock_shutdown(lo, 1);
+ sock_shutdown(lo, 0);
file = lo->file;
lo->file = NULL;
nbd_clear_que(lo);
@@ -684,6 +689,8 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
if (max_part > 0)
ioctl_by_bdev(bdev, BLKRRPART, 0);
return lo->harderror;
+ }
+
case NBD_CLEAR_QUE:
/*
* This is for compatibility only. The queue is always cleared
@@ -691,6 +698,7 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
*/
BUG_ON(!lo->sock && !list_empty(&lo->queue_head));
return 0;
+
case NBD_PRINT_DEBUG:
printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n",
bdev->bd_disk->disk_name,
@@ -698,7 +706,29 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
&lo->queue_head);
return 0;
}
- return -EINVAL;
+ return -ENOTTY;
+}
+
+static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
+ unsigned int cmd, unsigned long arg)
+{
+ struct nbd_device *lo = bdev->bd_disk->private_data;
+ int error;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ BUG_ON(lo->magic != LO_MAGIC);
+
+ /* Anyone capable of this syscall can do *real bad* things */
+ dprintk(DBG_IOCTL, "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n",
+ lo->disk->disk_name, ioctl_cmd_to_ascii(cmd), cmd, arg);
+
+ mutex_lock(&lo->tx_lock);
+ error = __nbd_ioctl(bdev, lo, cmd, arg);
+ mutex_unlock(&lo->tx_lock);
+
+ return error;
}
static struct block_device_operations nbd_fops =
diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c
index 393ed6760d7..8eddef373a9 100644
--- a/drivers/block/ps3vram.c
+++ b/drivers/block/ps3vram.c
@@ -551,8 +551,6 @@ static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev)
dev_warn(&dev->core, "failed to create /proc entry\n");
return;
}
-
- pde->owner = THIS_MODULE;
pde->data = priv;
}
diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c
index 119be3442f2..6cccdc3f522 100644
--- a/drivers/block/xsysace.c
+++ b/drivers/block/xsysace.c
@@ -89,6 +89,7 @@
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/platform_device.h>
#if defined(CONFIG_OF)
@@ -208,7 +209,7 @@ struct ace_device {
struct gendisk *gd;
/* Inserted CF card parameters */
- struct hd_driveid cf_id;
+ u16 cf_id[ATA_ID_WORDS];
};
static int ace_major;
@@ -402,21 +403,14 @@ static void ace_dump_regs(struct ace_device *ace)
ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));
}
-void ace_fix_driveid(struct hd_driveid *id)
+void ace_fix_driveid(u16 *id)
{
#if defined(__BIG_ENDIAN)
- u16 *buf = (void *)id;
int i;
/* All half words have wrong byte order; swap the bytes */
- for (i = 0; i < sizeof(struct hd_driveid); i += 2, buf++)
- *buf = le16_to_cpu(*buf);
-
- /* Some of the data values are 32bit; swap the half words */
- id->lba_capacity = ((id->lba_capacity >> 16) & 0x0000FFFF) |
- ((id->lba_capacity << 16) & 0xFFFF0000);
- id->spg = ((id->spg >> 16) & 0x0000FFFF) |
- ((id->spg << 16) & 0xFFFF0000);
+ for (i = 0; i < ATA_ID_WORDS; i++, id++)
+ *id = le16_to_cpu(*id);
#endif
}
@@ -614,7 +608,7 @@ static void ace_fsm_dostate(struct ace_device *ace)
break;
case ACE_FSM_STATE_IDENTIFY_COMPLETE:
- ace_fix_driveid(&ace->cf_id);
+ ace_fix_driveid(&ace->cf_id[0]);
ace_dump_mem(&ace->cf_id, 512); /* Debug: Dump out disk ID */
if (ace->data_result) {
@@ -627,9 +621,10 @@ static void ace_fsm_dostate(struct ace_device *ace)
ace->media_change = 0;
/* Record disk parameters */
- set_capacity(ace->gd, ace->cf_id.lba_capacity);
+ set_capacity(ace->gd,
+ ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
dev_info(ace->dev, "capacity: %i sectors\n",
- ace->cf_id.lba_capacity);
+ ata_id_u32(&ace->cf_id, ATA_ID_LBA_CAPACITY));
}
/* We're done, drop to IDLE state and notify waiters */
@@ -928,12 +923,13 @@ static int ace_release(struct gendisk *disk, fmode_t mode)
static int ace_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
struct ace_device *ace = bdev->bd_disk->private_data;
+ u16 *cf_id = &ace->cf_id[0];
dev_dbg(ace->dev, "ace_getgeo()\n");
- geo->heads = ace->cf_id.heads;
- geo->sectors = ace->cf_id.sectors;
- geo->cylinders = ace->cf_id.cyls;
+ geo->heads = cf_id[ATA_ID_HEADS];
+ geo->sectors = cf_id[ATA_ID_SECTORS];
+ geo->cylinders = cf_id[ATA_ID_CYLS];
return 0;
}
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index a58869ea851..fd3ebd1be57 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -79,6 +79,7 @@ static char *serial_version = "4.30";
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/bitops.h>
@@ -1825,14 +1826,13 @@ static int rs_open(struct tty_struct *tty, struct file * filp)
* /proc fs routines....
*/
-static inline int line_info(char *buf, struct serial_state *state)
+static inline void line_info(struct seq_file *m, struct serial_state *state)
{
struct async_struct *info = state->info, scr_info;
char stat_buf[30], control, status;
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%d: uart:amiga_builtin",state->line);
+ seq_printf(m, "%d: uart:amiga_builtin",state->line);
/*
* Figure out the current RS-232 lines
@@ -1864,55 +1864,49 @@ static inline int line_info(char *buf, struct serial_state *state)
strcat(stat_buf, "|CD");
if (info->quot) {
- ret += sprintf(buf+ret, " baud:%d",
- state->baud_base / info->quot);
+ seq_printf(m, " baud:%d", state->baud_base / info->quot);
}
- ret += sprintf(buf+ret, " tx:%d rx:%d",
- state->icount.tx, state->icount.rx);
+ seq_printf(m, " tx:%d rx:%d", state->icount.tx, state->icount.rx);
if (state->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", state->icount.frame);
+ seq_printf(m, " fe:%d", state->icount.frame);
if (state->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", state->icount.parity);
+ seq_printf(m, " pe:%d", state->icount.parity);
if (state->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", state->icount.brk);
+ seq_printf(m, " brk:%d", state->icount.brk);
if (state->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", state->icount.overrun);
+ seq_printf(m, " oe:%d", state->icount.overrun);
/*
* Last thing is the RS-232 status lines
*/
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
- return ret;
+ seq_printf(m, " %s\n", stat_buf+1);
}
-static int rs_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int rs_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
-
- len += sprintf(page, "serinfo:1.0 driver:%s\n", serial_version);
- l = line_info(page + len, &rs_table[0]);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+ seq_printf(m, "serinfo:1.0 driver:%s\n", serial_version);
+ line_info(m, &rs_table[0]);
+ return 0;
}
+static int rs_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, rs_proc_show, NULL);
+}
+
+static const struct file_operations rs_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = rs_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* ---------------------------------------------------------------------
* rs_init() and friends
@@ -1951,9 +1945,9 @@ static const struct tty_operations serial_ops = {
.break_ctl = rs_break,
.send_xchar = rs_send_xchar,
.wait_until_sent = rs_wait_until_sent,
- .read_proc = rs_read_proc,
.tiocmget = rs_tiocmget,
.tiocmset = rs_tiocmset,
+ .proc_fops = &rs_proc_fops,
};
/*
diff --git a/drivers/char/applicom.c b/drivers/char/applicom.c
index 05674febb0c..73a0765344b 100644
--- a/drivers/char/applicom.c
+++ b/drivers/char/applicom.c
@@ -75,6 +75,7 @@ MODULE_DEVICE_TABLE(pci, applicom_pci_tbl);
MODULE_AUTHOR("David Woodhouse & Applicom International");
MODULE_DESCRIPTION("Driver for Applicom Profibus card");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(AC_MINOR);
MODULE_SUPPORTED_DEVICE("ac");
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index f6094ae0ef3..140ea10ecb8 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -140,7 +140,7 @@ static int bsr_open(struct inode * inode, struct file * filp)
return 0;
}
-const static struct file_operations bsr_fops = {
+static const struct file_operations bsr_fops = {
.owner = THIS_MODULE,
.mmap = bsr_mmap,
.open = bsr_open,
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index 6a59f72a9c2..1fdb9f657d8 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -646,6 +646,7 @@
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/firmware.h>
+#include <linux/device.h>
#include <asm/system.h>
#include <linux/io.h>
@@ -657,6 +658,7 @@
#include <linux/stat.h>
#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
static void cy_throttle(struct tty_struct *tty);
static void cy_send_xchar(struct tty_struct *tty, char ch);
@@ -868,8 +870,6 @@ static int cyz_issue_cmd(struct cyclades_card *, __u32, __u8, __u32);
static unsigned detect_isa_irq(void __iomem *);
#endif /* CONFIG_ISA */
-static int cyclades_get_proc_info(char *, char **, off_t, int, int *, void *);
-
#ifndef CONFIG_CYZ_INTR
static void cyz_poll(unsigned long);
@@ -5216,31 +5216,22 @@ static struct pci_driver cy_pci_driver = {
};
#endif
-static int
-cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
- int *eof, void *data)
+static int cyclades_proc_show(struct seq_file *m, void *v)
{
struct cyclades_port *info;
unsigned int i, j;
- int len = 0;
- off_t begin = 0;
- off_t pos = 0;
- int size;
__u32 cur_jifs = jiffies;
- size = sprintf(buf, "Dev TimeOpen BytesOut IdleOut BytesIn "
+ seq_puts(m, "Dev TimeOpen BytesOut IdleOut BytesIn "
"IdleIn Overruns Ldisc\n");
- pos += size;
- len += size;
-
/* Output one line for each known port */
for (i = 0; i < NR_CARDS; i++)
for (j = 0; j < cy_card[i].nports; j++) {
info = &cy_card[i].ports[j];
if (info->port.count)
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ seq_printf(m, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n", info->line,
(cur_jifs - info->idle_stats.in_use) /
HZ, info->idle_stats.xmit_bytes,
@@ -5251,30 +5242,26 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
/* FIXME: double check locking */
(long)info->port.tty->ldisc.ops->num);
else
- size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
+ seq_printf(m, "%3d %8lu %10lu %8lu "
"%10lu %8lu %9lu %6ld\n",
info->line, 0L, 0L, 0L, 0L, 0L, 0L, 0L);
- len += size;
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- goto done;
}
- *eof = 1;
-done:
- *start = buf + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Start slop */
- if (len > length)
- len = length; /* Ending slop */
- if (len < 0)
- len = 0;
- return len;
+ return 0;
+}
+
+static int cyclades_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, cyclades_proc_show, NULL);
}
+static const struct file_operations cyclades_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = cyclades_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* The serial driver boot-time initialization code!
Hardware I/O ports are mapped to character special devices on a
first found, first allocated manner. That is, this code searches
@@ -5311,9 +5298,9 @@ static const struct tty_operations cy_ops = {
.hangup = cy_hangup,
.break_ctl = cy_break,
.wait_until_sent = cy_wait_until_sent,
- .read_proc = cyclades_get_proc_info,
.tiocmget = cy_tiocmget,
.tiocmset = cy_tiocmset,
+ .proc_fops = &cyclades_proc_fops,
};
static int __init cy_init(void)
@@ -5422,3 +5409,4 @@ module_exit(cy_cleanup_module);
MODULE_LICENSE("GPL");
MODULE_VERSION(CY_VERSION);
+MODULE_ALIAS_CHARDEV_MAJOR(CYCLADES_MAJOR);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 32b8bbf5003..50dfa3bc71c 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -713,7 +713,7 @@ static struct ctl_table_header *sysctl_header;
*/
#define TICK_CALIBRATE (1000UL)
-static unsigned long hpet_calibrate(struct hpets *hpetp)
+static unsigned long __hpet_calibrate(struct hpets *hpetp)
{
struct hpet_timer __iomem *timer = NULL;
unsigned long t, m, count, i, flags, start;
@@ -750,6 +750,26 @@ static unsigned long hpet_calibrate(struct hpets *hpetp)
return (m - start) / i;
}
+static unsigned long hpet_calibrate(struct hpets *hpetp)
+{
+ unsigned long ret = -1;
+ unsigned long tmp;
+
+ /*
+ * Try to calibrate until return value becomes stable small value.
+ * If SMI interruption occurs in calibration loop, the return value
+ * will be big. This avoids its impact.
+ */
+ for ( ; ; ) {
+ tmp = __hpet_calibrate(hpetp);
+ if (ret <= tmp)
+ break;
+ ret = tmp;
+ }
+
+ return ret;
+}
+
int hpet_alloc(struct hpet_data *hdp)
{
u64 cap, mcfg;
diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c
index 10ad41be589..dcd352ad0e7 100644
--- a/drivers/char/hw_random/timeriomem-rng.c
+++ b/drivers/char/hw_random/timeriomem-rng.c
@@ -90,10 +90,30 @@ static struct hwrng timeriomem_rng_ops = {
static int __init timeriomem_rng_probe(struct platform_device *pdev)
{
+ struct resource *res, *mem;
int ret;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ if (!res)
+ return -ENOENT;
+
+ mem = request_mem_region(res->start, res->end - res->start + 1,
+ pdev->name);
+ if (mem == NULL)
+ return -EBUSY;
+
+ dev_set_drvdata(&pdev->dev, mem);
+
timeriomem_rng_data = pdev->dev.platform_data;
+ timeriomem_rng_data->address = ioremap(res->start,
+ res->end - res->start + 1);
+ if (!timeriomem_rng_data->address) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
if (timeriomem_rng_data->period != 0
&& usecs_to_jiffies(timeriomem_rng_data->period) > 0) {
timeriomem_rng_timer.expires = jiffies;
@@ -104,23 +124,34 @@ static int __init timeriomem_rng_probe(struct platform_device *pdev)
timeriomem_rng_data->present = 1;
ret = hwrng_register(&timeriomem_rng_ops);
- if (ret) {
- dev_err(&pdev->dev, "problem registering\n");
- return ret;
- }
+ if (ret)
+ goto err_register;
dev_info(&pdev->dev, "32bits from 0x%p @ %dus\n",
timeriomem_rng_data->address,
timeriomem_rng_data->period);
return 0;
+
+err_register:
+ dev_err(&pdev->dev, "problem registering\n");
+ iounmap(timeriomem_rng_data->address);
+err_ioremap:
+ release_resource(mem);
+
+ return ret;
}
static int __devexit timeriomem_rng_remove(struct platform_device *pdev)
{
+ struct resource *mem = dev_get_drvdata(&pdev->dev);
+
del_timer_sync(&timeriomem_rng_timer);
hwrng_unregister(&timeriomem_rng_ops);
+ iounmap(timeriomem_rng_data->address);
+ release_resource(mem);
+
return 0;
}
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 70e0ebc30bd..afd9247cf08 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -139,7 +139,7 @@
#include <linux/seq_file.h>
static const struct file_operations ip2mem_proc_fops;
-static int ip2_read_proc(char *, char **, off_t, int, int *, void * );
+static const struct file_operations ip2_proc_fops;
/********************/
/* Type Definitions */
@@ -446,9 +446,9 @@ static const struct tty_operations ip2_ops = {
.stop = ip2_stop,
.start = ip2_start,
.hangup = ip2_hangup,
- .read_proc = ip2_read_proc,
.tiocmget = ip2_tiocmget,
.tiocmset = ip2_tiocmset,
+ .proc_fops = &ip2_proc_fops,
};
/******************************************************************************/
@@ -3029,19 +3029,17 @@ static const struct file_operations ip2mem_proc_fops = {
* different sources including ip2mkdev.c and a couple of other drivers.
* The bugs are all mine. :-) =mhw=
*/
-static int ip2_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int ip2_proc_show(struct seq_file *m, void *v)
{
int i, j, box;
- int len = 0;
int boxes = 0;
int ports = 0;
int tports = 0;
- off_t begin = 0;
i2eBordStrPtr pB;
+ char *sep;
- len += sprintf(page, "ip2info: 1.0 driver: %s\n", pcVersion );
- len += sprintf(page+len, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
+ seq_printf(m, "ip2info: 1.0 driver: %s\n", pcVersion);
+ seq_printf(m, "Driver: SMajor=%d CMajor=%d IMajor=%d MaxBoards=%d MaxBoxes=%d MaxPorts=%d\n",
IP2_TTY_MAJOR, IP2_CALLOUT_MAJOR, IP2_IPL_MAJOR,
IP2_MAX_BOARDS, ABS_MAX_BOXES, ABS_BIGGEST_BOX);
@@ -3053,7 +3051,8 @@ static int ip2_read_proc(char *page, char **start, off_t off,
switch( pB->i2ePom.e.porID & ~POR_ID_RESERVED )
{
case POR_ID_FIIEX:
- len += sprintf( page+len, "Board %d: EX ports=", i );
+ seq_printf(m, "Board %d: EX ports=", i);
+ sep = "";
for( box = 0; box < ABS_MAX_BOXES; ++box )
{
ports = 0;
@@ -3065,79 +3064,74 @@ static int ip2_read_proc(char *page, char **start, off_t off,
++ports;
}
}
- len += sprintf( page+len, "%d,", ports );
+ seq_printf(m, "%s%d", sep, ports);
+ sep = ",";
tports += ports;
}
-
- --len; /* Backup over that last comma */
-
- len += sprintf( page+len, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8 );
+ seq_printf(m, " boxes=%d width=%d", boxes, pB->i2eDataWidth16 ? 16 : 8);
break;
case POR_ID_II_4:
- len += sprintf(page+len, "Board %d: ISA-4 ports=4 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-4 ports=4 boxes=1", i);
tports = ports = 4;
break;
case POR_ID_II_8:
- len += sprintf(page+len, "Board %d: ISA-8-std ports=8 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-8-std ports=8 boxes=1", i);
tports = ports = 8;
break;
case POR_ID_II_8R:
- len += sprintf(page+len, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i );
+ seq_printf(m, "Board %d: ISA-8-RJ11 ports=8 boxes=1", i);
tports = ports = 8;
break;
default:
- len += sprintf(page+len, "Board %d: unknown", i );
+ seq_printf(m, "Board %d: unknown", i);
/* Don't try and probe for minor numbers */
tports = ports = 0;
}
} else {
/* Don't try and probe for minor numbers */
- len += sprintf(page+len, "Board %d: vacant", i );
+ seq_printf(m, "Board %d: vacant", i);
tports = ports = 0;
}
if( tports ) {
- len += sprintf(page+len, " minors=" );
-
+ seq_puts(m, " minors=");
+ sep = "";
for ( box = 0; box < ABS_MAX_BOXES; ++box )
{
for ( j = 0; j < ABS_BIGGEST_BOX; ++j )
{
if ( pB->i2eChannelMap[box] & (1 << j) )
{
- len += sprintf (page+len,"%d,",
+ seq_printf(m, "%s%d", sep,
j + ABS_BIGGEST_BOX *
(box+i*ABS_MAX_BOXES));
+ sep = ",";
}
}
}
-
- page[ len - 1 ] = '\n'; /* Overwrite that last comma */
- } else {
- len += sprintf (page+len,"\n" );
- }
-
- if (len+begin > off+count)
- break;
- if (len+begin < off) {
- begin += len;
- len = 0;
}
+ seq_putc(m, '\n');
}
+ return 0;
+ }
- if (i >= IP2_MAX_BOARDS)
- *eof = 1;
- if (off >= len+begin)
- return 0;
+static int ip2_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, ip2_proc_show, NULL);
+}
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
- }
+static const struct file_operations ip2_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = ip2_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
/******************************************************************************/
/* Function: ip2trace() */
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index 7a88dfd4427..e93fc8d22fb 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -1944,7 +1944,7 @@ static int stat_file_read_proc(char *page, char **start, off_t off,
int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
read_proc_t *read_proc,
- void *data, struct module *owner)
+ void *data)
{
int rv = 0;
#ifdef CONFIG_PROC_FS
@@ -1970,7 +1970,6 @@ int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
} else {
file->data = data;
file->read_proc = read_proc;
- file->owner = owner;
mutex_lock(&smi->proc_entry_lock);
/* Stick it on the list. */
@@ -1993,23 +1992,21 @@ static int add_proc_entries(ipmi_smi_t smi, int num)
smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
if (!smi->proc_dir)
rv = -ENOMEM;
- else
- smi->proc_dir->owner = THIS_MODULE;
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "stats",
stat_file_read_proc,
- smi, THIS_MODULE);
+ smi);
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "ipmb",
ipmb_file_read_proc,
- smi, THIS_MODULE);
+ smi);
if (rv == 0)
rv = ipmi_smi_add_proc_entry(smi, "version",
version_file_read_proc,
- smi, THIS_MODULE);
+ smi);
#endif /* CONFIG_PROC_FS */
return rv;
@@ -4265,7 +4262,6 @@ static int ipmi_init_msghandler(void)
return -ENOMEM;
}
- proc_ipmi_root->owner = THIS_MODULE;
#endif /* CONFIG_PROC_FS */
setup_timer(&ipmi_timer, ipmi_timeout, 0);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 3000135f2ea..e58ea4cd55c 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -2899,7 +2899,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
type_file_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
@@ -2909,7 +2909,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
stat_file_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
@@ -2919,7 +2919,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv = ipmi_smi_add_proc_entry(new_smi->intf, "params",
param_read_proc,
- new_smi, THIS_MODULE);
+ new_smi);
if (rv) {
printk(KERN_ERR
"ipmi_si: Unable to create proc entry: %d\n",
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 24aa6e88e22..a59eac584d1 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -925,6 +925,7 @@ static void isicom_shutdown_port(struct isi_port *port)
if (!card->count)
isicom_shutdown_board(card);
}
+ tty_kref_put(tty);
}
static void isicom_flush_buffer(struct tty_struct *tty)
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 5c3dc6b8411..fff19f7e29d 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -24,6 +24,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
+#include <linux/seq_file.h>
#include <linux/cdk.h>
#include <linux/comstats.h>
#include <linux/istallion.h>
@@ -613,7 +614,6 @@ static int stli_breakctl(struct tty_struct *tty, int state);
static void stli_waituntilsent(struct tty_struct *tty, int timeout);
static void stli_sendxchar(struct tty_struct *tty, char ch);
static void stli_hangup(struct tty_struct *tty);
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos);
static int stli_brdinit(struct stlibrd *brdp);
static int stli_startbrd(struct stlibrd *brdp);
@@ -1893,20 +1893,10 @@ static void stli_sendxchar(struct tty_struct *tty, char ch)
stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0);
}
-/*****************************************************************************/
-
-#define MAXLINE 80
-
-/*
- * Format info for a specified port. The line is deliberately limited
- * to 80 characters. (If it is too long it will be truncated, if too
- * short then padded with spaces).
- */
-
-static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portnr, char *pos)
+static void stli_portinfo(struct seq_file *m, struct stlibrd *brdp, struct stliport *portp, int portnr)
{
- char *sp, *uart;
- int rc, cnt;
+ char *uart;
+ int rc;
rc = stli_portcmdstats(NULL, portp);
@@ -1918,44 +1908,50 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn
default:uart = "CD1400"; break;
}
}
-
- sp = pos;
- sp += sprintf(sp, "%d: uart:%s ", portnr, uart);
+ seq_printf(m, "%d: uart:%s ", portnr, uart);
if ((brdp->state & BST_STARTED) && (rc >= 0)) {
- sp += sprintf(sp, "tx:%d rx:%d", (int) stli_comstats.txtotal,
+ char sep;
+
+ seq_printf(m, "tx:%d rx:%d", (int) stli_comstats.txtotal,
(int) stli_comstats.rxtotal);
if (stli_comstats.rxframing)
- sp += sprintf(sp, " fe:%d",
+ seq_printf(m, " fe:%d",
(int) stli_comstats.rxframing);
if (stli_comstats.rxparity)
- sp += sprintf(sp, " pe:%d",
+ seq_printf(m, " pe:%d",
(int) stli_comstats.rxparity);
if (stli_comstats.rxbreaks)
- sp += sprintf(sp, " brk:%d",
+ seq_printf(m, " brk:%d",
(int) stli_comstats.rxbreaks);
if (stli_comstats.rxoverrun)
- sp += sprintf(sp, " oe:%d",
+ seq_printf(m, " oe:%d",
(int) stli_comstats.rxoverrun);
- cnt = sprintf(sp, "%s%s%s%s%s ",
- (stli_comstats.signals & TIOCM_RTS) ? "|RTS" : "",
- (stli_comstats.signals & TIOCM_CTS) ? "|CTS" : "",
- (stli_comstats.signals & TIOCM_DTR) ? "|DTR" : "",
- (stli_comstats.signals & TIOCM_CD) ? "|DCD" : "",
- (stli_comstats.signals & TIOCM_DSR) ? "|DSR" : "");
- *sp = ' ';
- sp += cnt;
+ sep = ' ';
+ if (stli_comstats.signals & TIOCM_RTS) {
+ seq_printf(m, "%c%s", sep, "RTS");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_CTS) {
+ seq_printf(m, "%c%s", sep, "CTS");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_DTR) {
+ seq_printf(m, "%c%s", sep, "DTR");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_CD) {
+ seq_printf(m, "%c%s", sep, "DCD");
+ sep = '|';
+ }
+ if (stli_comstats.signals & TIOCM_DSR) {
+ seq_printf(m, "%c%s", sep, "DSR");
+ sep = '|';
+ }
}
-
- for (cnt = (sp - pos); (cnt < (MAXLINE - 1)); cnt++)
- *sp++ = ' ';
- if (cnt >= MAXLINE)
- pos[(MAXLINE - 2)] = '+';
- pos[(MAXLINE - 1)] = '\n';
-
- return(MAXLINE);
+ seq_putc(m, '\n');
}
/*****************************************************************************/
@@ -1964,26 +1960,15 @@ static int stli_portinfo(struct stlibrd *brdp, struct stliport *portp, int portn
* Port info, read from the /proc file system.
*/
-static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stli_proc_show(struct seq_file *m, void *v)
{
struct stlibrd *brdp;
struct stliport *portp;
unsigned int brdnr, portnr, totalport;
- int curoff, maxoff;
- char *pos;
- pos = page;
totalport = 0;
- curoff = 0;
-
- if (off == 0) {
- pos += sprintf(pos, "%s: version %s", stli_drvtitle,
- stli_drvversion);
- while (pos < (page + MAXLINE - 1))
- *pos++ = ' ';
- *pos++ = '\n';
- }
- curoff = MAXLINE;
+
+ seq_printf(m, "%s: version %s\n", stli_drvtitle, stli_drvversion);
/*
* We scan through for each board, panel and port. The offset is
@@ -1996,33 +1981,31 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo
if (brdp->state == 0)
continue;
- maxoff = curoff + (brdp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- continue;
- }
-
totalport = brdnr * STL_MAXPORTS;
for (portnr = 0; (portnr < brdp->nrports); portnr++,
totalport++) {
portp = brdp->ports[portnr];
if (portp == NULL)
continue;
- if (off >= (curoff += MAXLINE))
- continue;
- if ((pos - page + MAXLINE) > count)
- goto stli_readdone;
- pos += stli_portinfo(brdp, portp, totalport, pos);
+ stli_portinfo(m, brdp, portp, totalport);
}
}
+ return 0;
+}
- *eof = 1;
-
-stli_readdone:
- *start = page;
- return(pos - page);
+static int stli_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stli_proc_show, NULL);
}
+static const struct file_operations stli_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = stli_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*****************************************************************************/
/*
@@ -4427,9 +4410,9 @@ static const struct tty_operations stli_ops = {
.break_ctl = stli_breakctl,
.wait_until_sent = stli_waituntilsent,
.send_xchar = stli_sendxchar,
- .read_proc = stli_readproc,
.tiocmget = stli_tiocmget,
.tiocmset = stli_tiocmset,
+ .proc_fops = &stli_proc_fops,
};
static const struct tty_port_operations stli_port_ops = {
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index 8b0da97d529..4a4cab73d0b 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -1486,11 +1486,11 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
}
if (!handle) /* nothing else to do */
- return 0;
+ goto put;
intr = readw(ip); /* port irq status */
if (intr == 0)
- return 0;
+ goto put;
writew(0, ip); /* ACK port */
ofsAddr = p->tableAddr;
@@ -1499,16 +1499,17 @@ static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
ofsAddr + HostStat);
if (!inited)
- return 0;
+ goto put;
if (tty && (intr & IntrBreak) && !I_IGNBRK(tty)) { /* BREAK */
tty_insert_flip_char(tty, 0, TTY_BREAK);
tty_schedule_flip(tty);
}
- tty_kref_put(tty);
if (intr & IntrLine)
moxa_new_dcdstate(p, readb(ofsAddr + FlagStat) & DCD_state);
+put:
+ tty_kref_put(tty);
return 0;
}
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 402c9f217f8..a420e8d437d 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -820,7 +820,6 @@ static void mxser_check_modem_status(struct tty_struct *tty,
wake_up_interruptible(&port->port.open_wait);
}
- tty = tty_port_tty_get(&port->port);
if (port->port.flags & ASYNC_CTS_FLOW) {
if (tty->hw_stopped) {
if (status & UART_MSR_CTS) {
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 5608a1e5a3b..19d79fc5446 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -51,6 +51,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -2619,13 +2620,12 @@ cleanup:
* /proc fs routines....
*/
-static inline int line_info(char *buf, MGSLPC_INFO *info)
+static inline void line_info(struct seq_file *m, MGSLPC_INFO *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s:io:%04X irq:%d",
+ seq_printf(m, "%s:io:%04X irq:%d",
info->device_name, info->io_base, info->irq_level);
/* output current serial signal states */
@@ -2649,75 +2649,70 @@ static inline int line_info(char *buf, MGSLPC_INFO *info)
strcat(stat_buf, "|RI");
if (info->params.mode == MGSL_MODE_HDLC) {
- ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+ seq_printf(m, " HDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+ seq_printf(m, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int mgslpc_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int mgslpc_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
MGSLPC_INFO *info;
- len += sprintf(page, "synclink driver:%s\n", driver_version);
+ seq_printf(m, "synclink driver:%s\n", driver_version);
info = mgslpc_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int mgslpc_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mgslpc_proc_show, NULL);
}
+static const struct file_operations mgslpc_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = mgslpc_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int rx_alloc_buffers(MGSLPC_INFO *info)
{
/* each buffer has header and data */
@@ -2861,13 +2856,13 @@ static const struct tty_operations mgslpc_ops = {
.send_xchar = mgslpc_send_xchar,
.break_ctl = mgslpc_break,
.wait_until_sent = mgslpc_wait_until_sent,
- .read_proc = mgslpc_read_proc,
.set_termios = mgslpc_set_termios,
.stop = tx_pause,
.start = tx_release,
.hangup = mgslpc_hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &mgslpc_proc_fops,
};
static void synclink_cs_cleanup(void)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 7c43ae782b2..f824ef8a927 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1488,7 +1488,8 @@ static void rekey_seq_generator(struct work_struct *work)
keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
smp_wmb();
ip_cnt++;
- schedule_delayed_work(&rekey_work, REKEY_INTERVAL);
+ schedule_delayed_work(&rekey_work,
+ round_jiffies_relative(REKEY_INTERVAL));
}
static inline struct keydata *get_keyptr(void)
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 96adf28a17e..20d90e6a6e5 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -90,6 +90,7 @@ out1:
blkdev_put(bdev, filp->f_mode);
out:
mutex_unlock(&raw_mutex);
+ unlock_kernel();
return err;
}
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 2e8a6eed34b..ce81da5b2da 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -333,7 +333,7 @@ void rio_copy_to_card(void *from, void __iomem *to, int len)
int rio_minor(struct tty_struct *tty)
{
- return tty->index + (tty->driver == rio_driver) ? 0 : 256;
+ return tty->index + ((tty->driver == rio_driver) ? 0 : 256);
}
static int rio_set_real_termios(void *ptr)
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index 9af8d74875b..21766045123 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -48,6 +48,7 @@
#include <linux/delay.h>
#include <linux/tty_flip.h>
#include <linux/spinlock.h>
+#include <linux/device.h>
#include <linux/uaccess.h>
@@ -1524,6 +1525,7 @@ module_param(iobase2, int, 0);
module_param(iobase3, int, 0);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(RISCOM8_NORMAL_MAJOR);
#endif /* MODULE */
/*
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 3c67c3d83de..e72be4190a4 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -2365,3 +2365,4 @@ module_init(specialix_init_module);
module_exit(specialix_exit_module);
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(SPECIALIX_NORMAL_MAJOR);
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index e1e0dd89ac9..2ad813a801d 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -32,6 +32,7 @@
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/serial.h>
+#include <linux/seq_file.h>
#include <linux/cd1400.h>
#include <linux/sc26198.h>
#include <linux/comstats.h>
@@ -1379,52 +1380,47 @@ static void stl_sendxchar(struct tty_struct *tty, char ch)
stl_putchar(tty, ch);
}
-/*****************************************************************************/
-
-#define MAXLINE 80
-
-/*
- * Format info for a specified port. The line is deliberately limited
- * to 80 characters. (If it is too long it will be truncated, if too
- * short then padded with spaces).
- */
-
-static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
+static void stl_portinfo(struct seq_file *m, struct stlport *portp, int portnr)
{
- char *sp;
- int sigs, cnt;
+ int sigs;
+ char sep;
- sp = pos;
- sp += sprintf(sp, "%d: uart:%s tx:%d rx:%d",
+ seq_printf(m, "%d: uart:%s tx:%d rx:%d",
portnr, (portp->hwid == 1) ? "SC26198" : "CD1400",
(int) portp->stats.txtotal, (int) portp->stats.rxtotal);
if (portp->stats.rxframing)
- sp += sprintf(sp, " fe:%d", (int) portp->stats.rxframing);
+ seq_printf(m, " fe:%d", (int) portp->stats.rxframing);
if (portp->stats.rxparity)
- sp += sprintf(sp, " pe:%d", (int) portp->stats.rxparity);
+ seq_printf(m, " pe:%d", (int) portp->stats.rxparity);
if (portp->stats.rxbreaks)
- sp += sprintf(sp, " brk:%d", (int) portp->stats.rxbreaks);
+ seq_printf(m, " brk:%d", (int) portp->stats.rxbreaks);
if (portp->stats.rxoverrun)
- sp += sprintf(sp, " oe:%d", (int) portp->stats.rxoverrun);
+ seq_printf(m, " oe:%d", (int) portp->stats.rxoverrun);
sigs = stl_getsignals(portp);
- cnt = sprintf(sp, "%s%s%s%s%s ",
- (sigs & TIOCM_RTS) ? "|RTS" : "",
- (sigs & TIOCM_CTS) ? "|CTS" : "",
- (sigs & TIOCM_DTR) ? "|DTR" : "",
- (sigs & TIOCM_CD) ? "|DCD" : "",
- (sigs & TIOCM_DSR) ? "|DSR" : "");
- *sp = ' ';
- sp += cnt;
-
- for (cnt = sp - pos; cnt < (MAXLINE - 1); cnt++)
- *sp++ = ' ';
- if (cnt >= MAXLINE)
- pos[(MAXLINE - 2)] = '+';
- pos[(MAXLINE - 1)] = '\n';
-
- return MAXLINE;
+ sep = ' ';
+ if (sigs & TIOCM_RTS) {
+ seq_printf(m, "%c%s", sep, "RTS");
+ sep = '|';
+ }
+ if (sigs & TIOCM_CTS) {
+ seq_printf(m, "%c%s", sep, "CTS");
+ sep = '|';
+ }
+ if (sigs & TIOCM_DTR) {
+ seq_printf(m, "%c%s", sep, "DTR");
+ sep = '|';
+ }
+ if (sigs & TIOCM_CD) {
+ seq_printf(m, "%c%s", sep, "DCD");
+ sep = '|';
+ }
+ if (sigs & TIOCM_DSR) {
+ seq_printf(m, "%c%s", sep, "DSR");
+ sep = '|';
+ }
+ seq_putc(m, '\n');
}
/*****************************************************************************/
@@ -1433,30 +1429,17 @@ static int stl_portinfo(struct stlport *portp, int portnr, char *pos)
* Port info, read from the /proc file system.
*/
-static int stl_readproc(char *page, char **start, off_t off, int count, int *eof, void *data)
+static int stl_proc_show(struct seq_file *m, void *v)
{
struct stlbrd *brdp;
struct stlpanel *panelp;
struct stlport *portp;
unsigned int brdnr, panelnr, portnr;
- int totalport, curoff, maxoff;
- char *pos;
+ int totalport;
- pr_debug("stl_readproc(page=%p,start=%p,off=%lx,count=%d,eof=%p,"
- "data=%p\n", page, start, off, count, eof, data);
-
- pos = page;
totalport = 0;
- curoff = 0;
-
- if (off == 0) {
- pos += sprintf(pos, "%s: version %s", stl_drvtitle,
- stl_drvversion);
- while (pos < (page + MAXLINE - 1))
- *pos++ = ' ';
- *pos++ = '\n';
- }
- curoff = MAXLINE;
+
+ seq_printf(m, "%s: version %s\n", stl_drvtitle, stl_drvversion);
/*
* We scan through for each board, panel and port. The offset is
@@ -1469,46 +1452,37 @@ static int stl_readproc(char *page, char **start, off_t off, int count, int *eof
if (brdp->state == 0)
continue;
- maxoff = curoff + (brdp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- continue;
- }
-
totalport = brdnr * STL_MAXPORTS;
for (panelnr = 0; panelnr < brdp->nrpanels; panelnr++) {
panelp = brdp->panels[panelnr];
if (panelp == NULL)
continue;
- maxoff = curoff + (panelp->nrports * MAXLINE);
- if (off >= maxoff) {
- curoff = maxoff;
- totalport += panelp->nrports;
- continue;
- }
-
for (portnr = 0; portnr < panelp->nrports; portnr++,
totalport++) {
portp = panelp->ports[portnr];
if (portp == NULL)
continue;
- if (off >= (curoff += MAXLINE))
- continue;
- if ((pos - page + MAXLINE) > count)
- goto stl_readdone;
- pos += stl_portinfo(portp, totalport, pos);
+ stl_portinfo(m, portp, totalport);
}
}
}
+ return 0;
+}
- *eof = 1;
-
-stl_readdone:
- *start = page;
- return pos - page;
+static int stl_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, stl_proc_show, NULL);
}
+static const struct file_operations stl_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = stl_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*****************************************************************************/
/*
@@ -2566,9 +2540,9 @@ static const struct tty_operations stl_ops = {
.break_ctl = stl_breakctl,
.wait_until_sent = stl_waituntilsent,
.send_xchar = stl_sendxchar,
- .read_proc = stl_readproc,
.tiocmget = stl_tiocmget,
.tiocmset = stl_tiocmset,
+ .proc_fops = &stl_proc_fops,
};
static const struct tty_port_operations stl_port_ops = {
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index 0057a8f58cb..afd0b26ca05 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -79,6 +79,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
@@ -3459,18 +3460,17 @@ cleanup:
* /proc fs routines....
*/
-static inline int line_info(char *buf, struct mgsl_struct *info)
+static inline void line_info(struct seq_file *m, struct mgsl_struct *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
if (info->bus_type == MGSL_BUS_TYPE_PCI) {
- ret = sprintf(buf, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
+ seq_printf(m, "%s:PCI io:%04X irq:%d mem:%08X lcr:%08X",
info->device_name, info->io_base, info->irq_level,
info->phys_memory_base, info->phys_lcr_base);
} else {
- ret = sprintf(buf, "%s:(E)ISA io:%04X irq:%d dma:%d",
+ seq_printf(m, "%s:(E)ISA io:%04X irq:%d dma:%d",
info->device_name, info->io_base,
info->irq_level, info->dma_level);
}
@@ -3497,37 +3497,37 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
if (info->params.mode == MGSL_MODE_HDLC ||
info->params.mode == MGSL_MODE_RAW ) {
- ret += sprintf(buf+ret, " HDLC txok:%d rxok:%d",
+ seq_printf(m, " HDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, " ASYNC tx:%d rx:%d",
+ seq_printf(m, " ASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "txactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
@@ -3544,60 +3544,40 @@ static inline int line_info(char *buf, struct mgsl_struct *info)
u16 Tmr = usc_InReg( info, TMR );
u16 Tccr = usc_InReg( info, TCCR );
u16 Ccar = inw( info->io_base + CCAR );
- ret += sprintf(buf+ret, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
+ seq_printf(m, "tcsr=%04X tdmr=%04X ticr=%04X rcsr=%04X rdmr=%04X\n"
"ricr=%04X icr =%04X dccr=%04X tmr=%04X tccr=%04X ccar=%04X\n",
Tcsr,Tdmr,Ticr,Rscr,Rdmr,Ricr,Icr,Dccr,Tmr,Tccr,Ccar );
}
spin_unlock_irqrestore(&info->irq_spinlock,flags);
-
- return ret;
-
-} /* end of line_info() */
+}
-/* mgsl_read_proc()
- *
- * Called to print information about devices
- *
- * Arguments:
- * page page of memory to hold returned info
- * start
- * off
- * count
- * eof
- * data
- *
- * Return Value:
- */
-static int mgsl_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+/* Called to print information about devices */
+static int mgsl_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
struct mgsl_struct *info;
- len += sprintf(page, "synclink driver:%s\n", driver_version);
+ seq_printf(m, "synclink driver:%s\n", driver_version);
info = mgsl_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
-
-} /* end of mgsl_read_proc() */
+static int mgsl_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mgsl_proc_show, NULL);
+}
+
+static const struct file_operations mgsl_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = mgsl_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
/* mgsl_allocate_dma_buffers()
*
@@ -4335,13 +4315,13 @@ static const struct tty_operations mgsl_ops = {
.send_xchar = mgsl_send_xchar,
.break_ctl = mgsl_break,
.wait_until_sent = mgsl_wait_until_sent,
- .read_proc = mgsl_read_proc,
.set_termios = mgsl_set_termios,
.stop = mgsl_stop,
.start = mgsl_start,
.hangup = mgsl_hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &mgsl_proc_fops,
};
/*
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index efb3dc928a4..5e256494686 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -60,6 +60,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -154,7 +155,6 @@ static void tx_hold(struct tty_struct *tty);
static void tx_release(struct tty_struct *tty);
static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
@@ -298,6 +298,7 @@ struct slgt_info {
unsigned int rbuf_fill_level;
unsigned int if_mode;
+ unsigned int base_clock;
/* device status */
@@ -1156,22 +1157,26 @@ static long set_params32(struct slgt_info *info, struct MGSL_PARAMS32 __user *ne
return -EFAULT;
spin_lock(&info->lock);
- info->params.mode = tmp_params.mode;
- info->params.loopback = tmp_params.loopback;
- info->params.flags = tmp_params.flags;
- info->params.encoding = tmp_params.encoding;
- info->params.clock_speed = tmp_params.clock_speed;
- info->params.addr_filter = tmp_params.addr_filter;
- info->params.crc_type = tmp_params.crc_type;
- info->params.preamble_length = tmp_params.preamble_length;
- info->params.preamble = tmp_params.preamble;
- info->params.data_rate = tmp_params.data_rate;
- info->params.data_bits = tmp_params.data_bits;
- info->params.stop_bits = tmp_params.stop_bits;
- info->params.parity = tmp_params.parity;
+ if (tmp_params.mode == MGSL_MODE_BASE_CLOCK) {
+ info->base_clock = tmp_params.clock_speed;
+ } else {
+ info->params.mode = tmp_params.mode;
+ info->params.loopback = tmp_params.loopback;
+ info->params.flags = tmp_params.flags;
+ info->params.encoding = tmp_params.encoding;
+ info->params.clock_speed = tmp_params.clock_speed;
+ info->params.addr_filter = tmp_params.addr_filter;
+ info->params.crc_type = tmp_params.crc_type;
+ info->params.preamble_length = tmp_params.preamble_length;
+ info->params.preamble = tmp_params.preamble;
+ info->params.data_rate = tmp_params.data_rate;
+ info->params.data_bits = tmp_params.data_bits;
+ info->params.stop_bits = tmp_params.stop_bits;
+ info->params.parity = tmp_params.parity;
+ }
spin_unlock(&info->lock);
- change_params(info);
+ program_hw(info);
return 0;
}
@@ -1229,13 +1234,12 @@ static long slgt_compat_ioctl(struct tty_struct *tty, struct file *file,
/*
* proc fs support
*/
-static inline int line_info(char *buf, struct slgt_info *info)
+static inline void line_info(struct seq_file *m, struct slgt_info *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
+ seq_printf(m, "%s: IO=%08X IRQ=%d MaxFrameSize=%u\n",
info->device_name, info->phys_reg_addr,
info->irq_level, info->max_frame_size);
@@ -1260,75 +1264,70 @@ static inline int line_info(char *buf, struct slgt_info *info)
strcat(stat_buf, "|RI");
if (info->params.mode != MGSL_MODE_ASYNC) {
- ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+ seq_printf(m, "\tHDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxcrc:%d", info->icount.rxcrc);
+ seq_printf(m, " rxcrc:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+ seq_printf(m, "\tASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int synclink_gt_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
struct slgt_info *info;
- len += sprintf(page, "synclink_gt driver\n");
+ seq_puts(m, "synclink_gt driver\n");
info = slgt_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int synclink_gt_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, synclink_gt_proc_show, NULL);
}
+static const struct file_operations synclink_gt_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = synclink_gt_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/*
* return count of bytes in transmit buffer
*/
@@ -2565,10 +2564,13 @@ static int set_params(struct slgt_info *info, MGSL_PARAMS __user *new_params)
return -EFAULT;
spin_lock_irqsave(&info->lock, flags);
- memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
+ if (tmp_params.mode == MGSL_MODE_BASE_CLOCK)
+ info->base_clock = tmp_params.clock_speed;
+ else
+ memcpy(&info->params, &tmp_params, sizeof(MGSL_PARAMS));
spin_unlock_irqrestore(&info->lock, flags);
- change_params(info);
+ program_hw(info);
return 0;
}
@@ -3438,6 +3440,7 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
info->magic = MGSL_MAGIC;
INIT_WORK(&info->task, bh_handler);
info->max_frame_size = 4096;
+ info->base_clock = 14745600;
info->rbuf_fill_level = DMABUFSIZE;
info->port.close_delay = 5*HZ/10;
info->port.closing_wait = 30*HZ;
@@ -3562,13 +3565,13 @@ static const struct tty_operations ops = {
.send_xchar = send_xchar,
.break_ctl = set_break,
.wait_until_sent = wait_until_sent,
- .read_proc = read_proc,
.set_termios = set_termios,
.stop = tx_hold,
.start = tx_release,
.hangup = hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &synclink_gt_proc_fops,
};
static void slgt_cleanup(void)
@@ -3785,7 +3788,7 @@ static void enable_loopback(struct slgt_info *info)
static void set_rate(struct slgt_info *info, u32 rate)
{
unsigned int div;
- static unsigned int osc = 14745600;
+ unsigned int osc = info->base_clock;
/* div = osc/rate - 1
*
@@ -4089,18 +4092,27 @@ static void async_mode(struct slgt_info *info)
* 06 CTS IRQ enable
* 05 DCD IRQ enable
* 04 RI IRQ enable
- * 03 reserved, must be zero
+ * 03 0=16x sampling, 1=8x sampling
* 02 1=txd->rxd internal loopback enable
* 01 reserved, must be zero
* 00 1=master IRQ enable
*/
val = BIT15 + BIT14 + BIT0;
+ /* JCR[8] : 1 = x8 async mode feature available */
+ if ((rd_reg32(info, JCR) & BIT8) && info->params.data_rate &&
+ ((info->base_clock < (info->params.data_rate * 16)) ||
+ (info->base_clock % (info->params.data_rate * 16)))) {
+ /* use 8x sampling */
+ val |= BIT3;
+ set_rate(info, info->params.data_rate * 8);
+ } else {
+ /* use 16x sampling */
+ set_rate(info, info->params.data_rate * 16);
+ }
wr_reg16(info, SCR, val);
slgt_irq_on(info, IRQ_RXBREAK | IRQ_RXOVER);
- set_rate(info, info->params.data_rate * 16);
-
if (info->params.loopback)
enable_loopback(info);
}
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index 8eb6c89a980..26de60efe4b 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -50,6 +50,7 @@
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/mm.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/vmalloc.h>
@@ -520,7 +521,6 @@ static void tx_hold(struct tty_struct *tty);
static void tx_release(struct tty_struct *tty);
static int ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg);
-static int read_proc(char *page, char **start, off_t off, int count,int *eof, void *data);
static int chars_in_buffer(struct tty_struct *tty);
static void throttle(struct tty_struct * tty);
static void unthrottle(struct tty_struct * tty);
@@ -1354,13 +1354,12 @@ static int ioctl(struct tty_struct *tty, struct file *file,
* /proc fs routines....
*/
-static inline int line_info(char *buf, SLMP_INFO *info)
+static inline void line_info(struct seq_file *m, SLMP_INFO *info)
{
char stat_buf[30];
- int ret;
unsigned long flags;
- ret = sprintf(buf, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
+ seq_printf(m, "%s: SCABase=%08x Mem=%08X StatusControl=%08x LCR=%08X\n"
"\tIRQ=%d MaxFrameSize=%u\n",
info->device_name,
info->phys_sca_base,
@@ -1391,75 +1390,70 @@ static inline int line_info(char *buf, SLMP_INFO *info)
strcat(stat_buf, "|RI");
if (info->params.mode == MGSL_MODE_HDLC) {
- ret += sprintf(buf+ret, "\tHDLC txok:%d rxok:%d",
+ seq_printf(m, "\tHDLC txok:%d rxok:%d",
info->icount.txok, info->icount.rxok);
if (info->icount.txunder)
- ret += sprintf(buf+ret, " txunder:%d", info->icount.txunder);
+ seq_printf(m, " txunder:%d", info->icount.txunder);
if (info->icount.txabort)
- ret += sprintf(buf+ret, " txabort:%d", info->icount.txabort);
+ seq_printf(m, " txabort:%d", info->icount.txabort);
if (info->icount.rxshort)
- ret += sprintf(buf+ret, " rxshort:%d", info->icount.rxshort);
+ seq_printf(m, " rxshort:%d", info->icount.rxshort);
if (info->icount.rxlong)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxlong);
+ seq_printf(m, " rxlong:%d", info->icount.rxlong);
if (info->icount.rxover)
- ret += sprintf(buf+ret, " rxover:%d", info->icount.rxover);
+ seq_printf(m, " rxover:%d", info->icount.rxover);
if (info->icount.rxcrc)
- ret += sprintf(buf+ret, " rxlong:%d", info->icount.rxcrc);
+ seq_printf(m, " rxlong:%d", info->icount.rxcrc);
} else {
- ret += sprintf(buf+ret, "\tASYNC tx:%d rx:%d",
+ seq_printf(m, "\tASYNC tx:%d rx:%d",
info->icount.tx, info->icount.rx);
if (info->icount.frame)
- ret += sprintf(buf+ret, " fe:%d", info->icount.frame);
+ seq_printf(m, " fe:%d", info->icount.frame);
if (info->icount.parity)
- ret += sprintf(buf+ret, " pe:%d", info->icount.parity);
+ seq_printf(m, " pe:%d", info->icount.parity);
if (info->icount.brk)
- ret += sprintf(buf+ret, " brk:%d", info->icount.brk);
+ seq_printf(m, " brk:%d", info->icount.brk);
if (info->icount.overrun)
- ret += sprintf(buf+ret, " oe:%d", info->icount.overrun);
+ seq_printf(m, " oe:%d", info->icount.overrun);
}
/* Append serial signal status to end */
- ret += sprintf(buf+ret, " %s\n", stat_buf+1);
+ seq_printf(m, " %s\n", stat_buf+1);
- ret += sprintf(buf+ret, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
+ seq_printf(m, "\ttxactive=%d bh_req=%d bh_run=%d pending_bh=%x\n",
info->tx_active,info->bh_requested,info->bh_running,
info->pending_bh);
-
- return ret;
}
/* Called to print information about devices
*/
-static int read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int synclinkmp_proc_show(struct seq_file *m, void *v)
{
- int len = 0, l;
- off_t begin = 0;
SLMP_INFO *info;
- len += sprintf(page, "synclinkmp driver:%s\n", driver_version);
+ seq_printf(m, "synclinkmp driver:%s\n", driver_version);
info = synclinkmp_device_list;
while( info ) {
- l = line_info(page + len, info);
- len += l;
- if (len+begin > off+count)
- goto done;
- if (len+begin < off) {
- begin += len;
- len = 0;
- }
+ line_info(m, info);
info = info->next_device;
}
+ return 0;
+}
- *eof = 1;
-done:
- if (off >= len+begin)
- return 0;
- *start = page + (off-begin);
- return ((count < begin+len-off) ? count : begin+len-off);
+static int synclinkmp_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, synclinkmp_proc_show, NULL);
}
+static const struct file_operations synclinkmp_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = synclinkmp_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
/* Return the count of bytes in transmit buffer
*/
static int chars_in_buffer(struct tty_struct *tty)
@@ -3905,13 +3899,13 @@ static const struct tty_operations ops = {
.send_xchar = send_xchar,
.break_ctl = set_break,
.wait_until_sent = wait_until_sent,
- .read_proc = read_proc,
.set_termios = set_termios,
.stop = tx_hold,
.start = tx_release,
.hangup = hangup,
.tiocmget = tiocmget,
.tiocmset = tiocmset,
+ .proc_fops = &synclinkmp_proc_fops,
};
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 33a9351c896..6de020d078e 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -35,7 +35,7 @@
#include <linux/vt_kern.h>
#include <linux/workqueue.h>
#include <linux/kexec.h>
-#include <linux/irq.h>
+#include <linux/interrupt.h>
#include <linux/hrtimer.h>
#include <linux/oom.h>
@@ -283,7 +283,7 @@ static void sysrq_ftrace_dump(int key, struct tty_struct *tty)
}
static struct sysrq_key_op sysrq_ftrace_dump_op = {
.handler = sysrq_ftrace_dump,
- .help_msg = "dumpZ-ftrace-buffer",
+ .help_msg = "dump-ftrace-buffer(Z)",
.action_msg = "Dump ftrace buffer",
.enable_mask = SYSRQ_ENABLE_DUMP,
};
@@ -346,6 +346,19 @@ static struct sysrq_key_op sysrq_moom_op = {
.enable_mask = SYSRQ_ENABLE_SIGNAL,
};
+#ifdef CONFIG_BLOCK
+static void sysrq_handle_thaw(int key, struct tty_struct *tty)
+{
+ emergency_thaw_all();
+}
+static struct sysrq_key_op sysrq_thaw_op = {
+ .handler = sysrq_handle_thaw,
+ .help_msg = "thaw-filesystems(J)",
+ .action_msg = "Emergency Thaw of all frozen filesystems",
+ .enable_mask = SYSRQ_ENABLE_SIGNAL,
+};
+#endif
+
static void sysrq_handle_kill(int key, struct tty_struct *tty)
{
send_sig_all(SIGKILL);
@@ -396,9 +409,13 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
&sysrq_moom_op, /* f */
/* g: May be registered by ppc for kgdb */
NULL, /* g */
- NULL, /* h */
+ NULL, /* h - reserved for help */
&sysrq_kill_op, /* i */
+#ifdef CONFIG_BLOCK
+ &sysrq_thaw_op, /* j */
+#else
NULL, /* j */
+#endif
&sysrq_SAK_op, /* k */
#ifdef CONFIG_SMP
&sysrq_showallcpus_op, /* l */
diff --git a/drivers/char/tty_audit.c b/drivers/char/tty_audit.c
index 34ab6d798f8..55ba6f14288 100644
--- a/drivers/char/tty_audit.c
+++ b/drivers/char/tty_audit.c
@@ -10,8 +10,6 @@
*/
#include <linux/audit.h>
-#include <linux/file.h>
-#include <linux/fdtable.h>
#include <linux/tty.h>
struct tty_audit_buf {
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 224f271d8cb..66b99a2049e 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -464,7 +464,7 @@ void tty_wakeup(struct tty_struct *tty)
tty_ldisc_deref(ld);
}
}
- wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
}
EXPORT_SYMBOL_GPL(tty_wakeup);
@@ -587,8 +587,8 @@ static void do_tty_hangup(struct work_struct *work)
* FIXME: Once we trust the LDISC code better we can wait here for
* ldisc completion and fix the driver call race
*/
- wake_up_interruptible(&tty->write_wait);
- wake_up_interruptible(&tty->read_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
+ wake_up_interruptible_poll(&tty->read_wait, POLLIN);
/*
* Shutdown the current line discipline, and reset it to
* N_TTY.
@@ -879,7 +879,7 @@ void stop_tty(struct tty_struct *tty)
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_START;
tty->ctrl_status |= TIOCPKT_STOP;
- wake_up_interruptible(&tty->link->read_wait);
+ wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
}
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->ops->stop)
@@ -913,7 +913,7 @@ void start_tty(struct tty_struct *tty)
if (tty->link && tty->link->packet) {
tty->ctrl_status &= ~TIOCPKT_STOP;
tty->ctrl_status |= TIOCPKT_START;
- wake_up_interruptible(&tty->link->read_wait);
+ wake_up_interruptible_poll(&tty->link->read_wait, POLLIN);
}
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (tty->ops->start)
@@ -970,7 +970,7 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
void tty_write_unlock(struct tty_struct *tty)
{
mutex_unlock(&tty->atomic_write_lock);
- wake_up_interruptible(&tty->write_wait);
+ wake_up_interruptible_poll(&tty->write_wait, POLLOUT);
}
int tty_write_lock(struct tty_struct *tty, int ndelay)
@@ -1623,21 +1623,21 @@ void tty_release_dev(struct file *filp)
if (tty_closing) {
if (waitqueue_active(&tty->read_wait)) {
- wake_up(&tty->read_wait);
+ wake_up_poll(&tty->read_wait, POLLIN);
do_sleep++;
}
if (waitqueue_active(&tty->write_wait)) {
- wake_up(&tty->write_wait);
+ wake_up_poll(&tty->write_wait, POLLOUT);
do_sleep++;
}
}
if (o_tty_closing) {
if (waitqueue_active(&o_tty->read_wait)) {
- wake_up(&o_tty->read_wait);
+ wake_up_poll(&o_tty->read_wait, POLLIN);
do_sleep++;
}
if (waitqueue_active(&o_tty->write_wait)) {
- wake_up(&o_tty->write_wait);
+ wake_up_poll(&o_tty->write_wait, POLLOUT);
do_sleep++;
}
}
@@ -1758,7 +1758,7 @@ static int __tty_open(struct inode *inode, struct file *filp)
struct tty_driver *driver;
int index;
dev_t device = inode->i_rdev;
- unsigned short saved_flags = filp->f_flags;
+ unsigned saved_flags = filp->f_flags;
nonseekable_open(inode, filp);
@@ -2681,7 +2681,7 @@ void __do_SAK(struct tty_struct *tty)
/* Kill the entire session */
do_each_pid_task(session, PIDTYPE_SID, p) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): task_session_nr(p)==tty->session\n",
+ " (%s): task_session(p)==tty->session\n",
task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
} while_each_pid_task(session, PIDTYPE_SID, p);
@@ -2691,7 +2691,7 @@ void __do_SAK(struct tty_struct *tty)
do_each_thread(g, p) {
if (p->signal->tty == tty) {
printk(KERN_NOTICE "SAK: killed process %d"
- " (%s): task_session_nr(p)==tty->session\n",
+ " (%s): task_session(p)==tty->session\n",
task_pid_nr(p), p->comm);
send_sig(SIGKILL, p, 1);
continue;
diff --git a/drivers/char/tty_ldisc.c b/drivers/char/tty_ldisc.c
index 7a84b406a95..f78f5b0127a 100644
--- a/drivers/char/tty_ldisc.c
+++ b/drivers/char/tty_ldisc.c
@@ -10,7 +10,6 @@
#include <linux/tty_flip.h>
#include <linux/devpts_fs.h>
#include <linux/file.h>
-#include <linux/fdtable.h>
#include <linux/console.h>
#include <linux/timer.h>
#include <linux/ctype.h>
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c
index 7783b42f691..1c92c39a53a 100644
--- a/drivers/clocksource/sh_cmt.c
+++ b/drivers/clocksource/sh_cmt.c
@@ -465,7 +465,6 @@ static void sh_cmt_register_clockevent(struct sh_cmt_priv *p,
ced->set_mode = sh_cmt_clock_event_mode;
pr_info("sh_cmt: %s used for clock events\n", ced->name);
- ced->mult = 1; /* work around misplaced WARN_ON() in clockevents.c */
clockevents_register_device(ced);
}
@@ -557,7 +556,7 @@ static int sh_cmt_setup(struct sh_cmt_priv *p, struct platform_device *pdev)
cfg->clockevent_rating,
cfg->clocksource_rating);
err2:
- free_irq(irq, p);
+ remove_irq(irq, &p->irqaction);
err1:
iounmap(p->mapbase);
err0:
diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c
index 0c79fe7f156..4d85402a9e4 100644
--- a/drivers/crypto/hifn_795x.c
+++ b/drivers/crypto/hifn_795x.c
@@ -1882,7 +1882,7 @@ static void hifn_clear_rings(struct hifn_device *dev, int error)
static void hifn_work(struct work_struct *work)
{
- struct delayed_work *dw = container_of(work, struct delayed_work, work);
+ struct delayed_work *dw = to_delayed_work(work);
struct hifn_device *dev = container_of(dw, struct hifn_device, work);
unsigned long flags;
int reset = 0;
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c
index d9e751be8c5..af9761ccf9f 100644
--- a/drivers/crypto/ixp4xx_crypto.c
+++ b/drivers/crypto/ixp4xx_crypto.c
@@ -101,6 +101,7 @@ struct buffer_desc {
u32 phys_addr;
u32 __reserved[4];
struct buffer_desc *next;
+ enum dma_data_direction dir;
};
struct crypt_ctl {
@@ -132,14 +133,10 @@ struct crypt_ctl {
struct ablk_ctx {
struct buffer_desc *src;
struct buffer_desc *dst;
- unsigned src_nents;
- unsigned dst_nents;
};
struct aead_ctx {
struct buffer_desc *buffer;
- unsigned short assoc_nents;
- unsigned short src_nents;
struct scatterlist ivlist;
/* used when the hmac is not on one sg entry */
u8 *hmac_virt;
@@ -312,7 +309,7 @@ static struct crypt_ctl *get_crypt_desc_emerg(void)
}
}
-static void free_buf_chain(struct buffer_desc *buf, u32 phys)
+static void free_buf_chain(struct device *dev, struct buffer_desc *buf,u32 phys)
{
while (buf) {
struct buffer_desc *buf1;
@@ -320,6 +317,7 @@ static void free_buf_chain(struct buffer_desc *buf, u32 phys)
buf1 = buf->next;
phys1 = buf->phys_next;
+ dma_unmap_single(dev, buf->phys_next, buf->buf_len, buf->dir);
dma_pool_free(buffer_pool, buf, phys);
buf = buf1;
phys = phys1;
@@ -348,7 +346,6 @@ static void one_packet(dma_addr_t phys)
struct crypt_ctl *crypt;
struct ixp_ctx *ctx;
int failed;
- enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
failed = phys & 0x1 ? -EBADMSG : 0;
phys &= ~0x3;
@@ -358,13 +355,8 @@ static void one_packet(dma_addr_t phys)
case CTL_FLAG_PERFORM_AEAD: {
struct aead_request *req = crypt->data.aead_req;
struct aead_ctx *req_ctx = aead_request_ctx(req);
- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents,
- DMA_TO_DEVICE);
- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
- dma_unmap_sg(dev, req->src, req_ctx->src_nents,
- DMA_BIDIRECTIONAL);
- free_buf_chain(req_ctx->buffer, crypt->src_buf);
+ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
if (req_ctx->hmac_virt) {
finish_scattered_hmac(crypt);
}
@@ -374,16 +366,11 @@ static void one_packet(dma_addr_t phys)
case CTL_FLAG_PERFORM_ABLK: {
struct ablkcipher_request *req = crypt->data.ablk_req;
struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
- int nents;
+
if (req_ctx->dst) {
- nents = req_ctx->dst_nents;
- dma_unmap_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
- free_buf_chain(req_ctx->dst, crypt->dst_buf);
- src_direction = DMA_TO_DEVICE;
+ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
}
- nents = req_ctx->src_nents;
- dma_unmap_sg(dev, req->src, nents, src_direction);
- free_buf_chain(req_ctx->src, crypt->src_buf);
+ free_buf_chain(dev, req_ctx->src, crypt->src_buf);
req->base.complete(&req->base, failed);
break;
}
@@ -750,56 +737,35 @@ static int setup_cipher(struct crypto_tfm *tfm, int encrypt,
return 0;
}
-static int count_sg(struct scatterlist *sg, int nbytes)
+static struct buffer_desc *chainup_buffers(struct device *dev,
+ struct scatterlist *sg, unsigned nbytes,
+ struct buffer_desc *buf, gfp_t flags,
+ enum dma_data_direction dir)
{
- int i;
- for (i = 0; nbytes > 0; i++, sg = sg_next(sg))
- nbytes -= sg->length;
- return i;
-}
-
-static struct buffer_desc *chainup_buffers(struct scatterlist *sg,
- unsigned nbytes, struct buffer_desc *buf, gfp_t flags)
-{
- int nents = 0;
-
- while (nbytes > 0) {
+ for (;nbytes > 0; sg = scatterwalk_sg_next(sg)) {
+ unsigned len = min(nbytes, sg->length);
struct buffer_desc *next_buf;
u32 next_buf_phys;
- unsigned len = min(nbytes, sg_dma_len(sg));
+ void *ptr;
- nents++;
nbytes -= len;
- if (!buf->phys_addr) {
- buf->phys_addr = sg_dma_address(sg);
- buf->buf_len = len;
- buf->next = NULL;
- buf->phys_next = 0;
- goto next;
- }
- /* Two consecutive chunks on one page may be handled by the old
- * buffer descriptor, increased by the length of the new one
- */
- if (sg_dma_address(sg) == buf->phys_addr + buf->buf_len) {
- buf->buf_len += len;
- goto next;
- }
+ ptr = page_address(sg_page(sg)) + sg->offset;
next_buf = dma_pool_alloc(buffer_pool, flags, &next_buf_phys);
- if (!next_buf)
- return NULL;
+ if (!next_buf) {
+ buf = NULL;
+ break;
+ }
+ sg_dma_address(sg) = dma_map_single(dev, ptr, len, dir);
buf->next = next_buf;
buf->phys_next = next_buf_phys;
-
buf = next_buf;
- buf->next = NULL;
- buf->phys_next = 0;
+
buf->phys_addr = sg_dma_address(sg);
buf->buf_len = len;
-next:
- if (nbytes > 0) {
- sg = sg_next(sg);
- }
+ buf->dir = dir;
}
+ buf->next = NULL;
+ buf->phys_next = 0;
return buf;
}
@@ -860,12 +826,12 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req);
struct ixp_ctx *ctx = crypto_ablkcipher_ctx(tfm);
unsigned ivsize = crypto_ablkcipher_ivsize(tfm);
- int ret = -ENOMEM;
struct ix_sa_dir *dir;
struct crypt_ctl *crypt;
- unsigned int nbytes = req->nbytes, nents;
+ unsigned int nbytes = req->nbytes;
enum dma_data_direction src_direction = DMA_BIDIRECTIONAL;
struct ablk_ctx *req_ctx = ablkcipher_request_ctx(req);
+ struct buffer_desc src_hook;
gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
GFP_KERNEL : GFP_ATOMIC;
@@ -878,7 +844,7 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
crypt = get_crypt_desc();
if (!crypt)
- return ret;
+ return -ENOMEM;
crypt->data.ablk_req = req;
crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -891,53 +857,41 @@ static int ablk_perform(struct ablkcipher_request *req, int encrypt)
BUG_ON(ivsize && !req->info);
memcpy(crypt->iv, req->info, ivsize);
if (req->src != req->dst) {
+ struct buffer_desc dst_hook;
crypt->mode |= NPE_OP_NOT_IN_PLACE;
- nents = count_sg(req->dst, nbytes);
/* This was never tested by Intel
* for more than one dst buffer, I think. */
- BUG_ON(nents != 1);
- req_ctx->dst_nents = nents;
- dma_map_sg(dev, req->dst, nents, DMA_FROM_DEVICE);
- req_ctx->dst = dma_pool_alloc(buffer_pool, flags,&crypt->dst_buf);
- if (!req_ctx->dst)
- goto unmap_sg_dest;
- req_ctx->dst->phys_addr = 0;
- if (!chainup_buffers(req->dst, nbytes, req_ctx->dst, flags))
+ BUG_ON(req->dst->length < nbytes);
+ req_ctx->dst = NULL;
+ if (!chainup_buffers(dev, req->dst, nbytes, &dst_hook,
+ flags, DMA_FROM_DEVICE))
goto free_buf_dest;
src_direction = DMA_TO_DEVICE;
+ req_ctx->dst = dst_hook.next;
+ crypt->dst_buf = dst_hook.phys_next;
} else {
req_ctx->dst = NULL;
- req_ctx->dst_nents = 0;
}
- nents = count_sg(req->src, nbytes);
- req_ctx->src_nents = nents;
- dma_map_sg(dev, req->src, nents, src_direction);
-
- req_ctx->src = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
- if (!req_ctx->src)
- goto unmap_sg_src;
- req_ctx->src->phys_addr = 0;
- if (!chainup_buffers(req->src, nbytes, req_ctx->src, flags))
+ req_ctx->src = NULL;
+ if (!chainup_buffers(dev, req->src, nbytes, &src_hook,
+ flags, src_direction))
goto free_buf_src;
+ req_ctx->src = src_hook.next;
+ crypt->src_buf = src_hook.phys_next;
crypt->ctl_flags |= CTL_FLAG_PERFORM_ABLK;
qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
BUG_ON(qmgr_stat_overflow(SEND_QID));
return -EINPROGRESS;
free_buf_src:
- free_buf_chain(req_ctx->src, crypt->src_buf);
-unmap_sg_src:
- dma_unmap_sg(dev, req->src, req_ctx->src_nents, src_direction);
+ free_buf_chain(dev, req_ctx->src, crypt->src_buf);
free_buf_dest:
if (req->src != req->dst) {
- free_buf_chain(req_ctx->dst, crypt->dst_buf);
-unmap_sg_dest:
- dma_unmap_sg(dev, req->src, req_ctx->dst_nents,
- DMA_FROM_DEVICE);
+ free_buf_chain(dev, req_ctx->dst, crypt->dst_buf);
}
crypt->ctl_flags = CTL_FLAG_UNUSED;
- return ret;
+ return -ENOMEM;
}
static int ablk_encrypt(struct ablkcipher_request *req)
@@ -985,7 +939,7 @@ static int hmac_inconsistent(struct scatterlist *sg, unsigned start,
break;
offset += sg->length;
- sg = sg_next(sg);
+ sg = scatterwalk_sg_next(sg);
}
return (start + nbytes > offset + sg->length);
}
@@ -997,11 +951,10 @@ static int aead_perform(struct aead_request *req, int encrypt,
struct ixp_ctx *ctx = crypto_aead_ctx(tfm);
unsigned ivsize = crypto_aead_ivsize(tfm);
unsigned authsize = crypto_aead_authsize(tfm);
- int ret = -ENOMEM;
struct ix_sa_dir *dir;
struct crypt_ctl *crypt;
- unsigned int cryptlen, nents;
- struct buffer_desc *buf;
+ unsigned int cryptlen;
+ struct buffer_desc *buf, src_hook;
struct aead_ctx *req_ctx = aead_request_ctx(req);
gfp_t flags = req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ?
GFP_KERNEL : GFP_ATOMIC;
@@ -1022,7 +975,7 @@ static int aead_perform(struct aead_request *req, int encrypt,
}
crypt = get_crypt_desc();
if (!crypt)
- return ret;
+ return -ENOMEM;
crypt->data.aead_req = req;
crypt->crypto_ctx = dir->npe_ctx_phys;
@@ -1041,31 +994,27 @@ static int aead_perform(struct aead_request *req, int encrypt,
BUG(); /* -ENOTSUP because of my lazyness */
}
- req_ctx->buffer = dma_pool_alloc(buffer_pool, flags, &crypt->src_buf);
- if (!req_ctx->buffer)
- goto out;
- req_ctx->buffer->phys_addr = 0;
/* ASSOC data */
- nents = count_sg(req->assoc, req->assoclen);
- req_ctx->assoc_nents = nents;
- dma_map_sg(dev, req->assoc, nents, DMA_TO_DEVICE);
- buf = chainup_buffers(req->assoc, req->assoclen, req_ctx->buffer,flags);
+ buf = chainup_buffers(dev, req->assoc, req->assoclen, &src_hook,
+ flags, DMA_TO_DEVICE);
+ req_ctx->buffer = src_hook.next;
+ crypt->src_buf = src_hook.phys_next;
if (!buf)
- goto unmap_sg_assoc;
+ goto out;
/* IV */
sg_init_table(&req_ctx->ivlist, 1);
sg_set_buf(&req_ctx->ivlist, iv, ivsize);
- dma_map_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
- buf = chainup_buffers(&req_ctx->ivlist, ivsize, buf, flags);
+ buf = chainup_buffers(dev, &req_ctx->ivlist, ivsize, buf, flags,
+ DMA_BIDIRECTIONAL);
if (!buf)
- goto unmap_sg_iv;
+ goto free_chain;
if (unlikely(hmac_inconsistent(req->src, cryptlen, authsize))) {
/* The 12 hmac bytes are scattered,
* we need to copy them into a safe buffer */
req_ctx->hmac_virt = dma_pool_alloc(buffer_pool, flags,
&crypt->icv_rev_aes);
if (unlikely(!req_ctx->hmac_virt))
- goto unmap_sg_iv;
+ goto free_chain;
if (!encrypt) {
scatterwalk_map_and_copy(req_ctx->hmac_virt,
req->src, cryptlen, authsize, 0);
@@ -1075,33 +1024,28 @@ static int aead_perform(struct aead_request *req, int encrypt,
req_ctx->hmac_virt = NULL;
}
/* Crypt */
- nents = count_sg(req->src, cryptlen + authsize);
- req_ctx->src_nents = nents;
- dma_map_sg(dev, req->src, nents, DMA_BIDIRECTIONAL);
- buf = chainup_buffers(req->src, cryptlen + authsize, buf, flags);
+ buf = chainup_buffers(dev, req->src, cryptlen + authsize, buf, flags,
+ DMA_BIDIRECTIONAL);
if (!buf)
- goto unmap_sg_src;
+ goto free_hmac_virt;
if (!req_ctx->hmac_virt) {
crypt->icv_rev_aes = buf->phys_addr + buf->buf_len - authsize;
}
+
crypt->ctl_flags |= CTL_FLAG_PERFORM_AEAD;
qmgr_put_entry(SEND_QID, crypt_virt2phys(crypt));
BUG_ON(qmgr_stat_overflow(SEND_QID));
return -EINPROGRESS;
-unmap_sg_src:
- dma_unmap_sg(dev, req->src, req_ctx->src_nents, DMA_BIDIRECTIONAL);
+free_hmac_virt:
if (req_ctx->hmac_virt) {
dma_pool_free(buffer_pool, req_ctx->hmac_virt,
crypt->icv_rev_aes);
}
-unmap_sg_iv:
- dma_unmap_sg(dev, &req_ctx->ivlist, 1, DMA_BIDIRECTIONAL);
-unmap_sg_assoc:
- dma_unmap_sg(dev, req->assoc, req_ctx->assoc_nents, DMA_TO_DEVICE);
- free_buf_chain(req_ctx->buffer, crypt->src_buf);
+free_chain:
+ free_buf_chain(dev, req_ctx->buffer, crypt->src_buf);
out:
crypt->ctl_flags = CTL_FLAG_UNUSED;
- return ret;
+ return -ENOMEM;
}
static int aead_setup(struct crypto_aead *tfm, unsigned int authsize)
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 48ea59e7967..3b3c01b6f1e 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -98,6 +98,17 @@ config NET_DMA
Say Y here if you enabled INTEL_IOATDMA or FSL_DMA, otherwise
say N.
+config ASYNC_TX_DMA
+ bool "Async_tx: Offload support for the async_tx api"
+ depends on DMA_ENGINE
+ help
+ This allows the async_tx api to take advantage of offload engines for
+ memcpy, memset, xor, and raid6 p+q operations. If your platform has
+ a dma engine that can perform raid operations and you have enabled
+ MD_RAID456 say Y.
+
+ If unsure, say N.
+
config DMATEST
tristate "DMA Test client"
depends on DMA_ENGINE
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 280a9d263eb..92438e9dacc 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -507,6 +507,7 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
* published in the general-purpose allocator
*/
dma_cap_set(DMA_PRIVATE, device->cap_mask);
+ device->privatecnt++;
err = dma_chan_get(chan);
if (err == -ENODEV) {
@@ -518,6 +519,8 @@ struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, v
dma_chan_name(chan), err);
else
break;
+ if (--device->privatecnt == 0)
+ dma_cap_clear(DMA_PRIVATE, device->cap_mask);
chan->private = NULL;
chan = NULL;
}
@@ -537,6 +540,9 @@ void dma_release_channel(struct dma_chan *chan)
WARN_ONCE(chan->client_count != 1,
"chan reference count %d != 1\n", chan->client_count);
dma_chan_put(chan);
+ /* drop PRIVATE cap enabled by __dma_request_channel() */
+ if (--chan->device->privatecnt == 0)
+ dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask);
chan->private = NULL;
mutex_unlock(&dma_list_mutex);
}
@@ -602,6 +608,24 @@ void dmaengine_put(void)
}
EXPORT_SYMBOL(dmaengine_put);
+static int get_dma_id(struct dma_device *device)
+{
+ int rc;
+
+ idr_retry:
+ if (!idr_pre_get(&dma_idr, GFP_KERNEL))
+ return -ENOMEM;
+ mutex_lock(&dma_list_mutex);
+ rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
+ mutex_unlock(&dma_list_mutex);
+ if (rc == -EAGAIN)
+ goto idr_retry;
+ else if (rc != 0)
+ return rc;
+
+ return 0;
+}
+
/**
* dma_async_device_register - registers DMA devices found
* @device: &dma_device
@@ -640,27 +664,25 @@ int dma_async_device_register(struct dma_device *device)
idr_ref = kmalloc(sizeof(*idr_ref), GFP_KERNEL);
if (!idr_ref)
return -ENOMEM;
- atomic_set(idr_ref, 0);
- idr_retry:
- if (!idr_pre_get(&dma_idr, GFP_KERNEL))
- return -ENOMEM;
- mutex_lock(&dma_list_mutex);
- rc = idr_get_new(&dma_idr, NULL, &device->dev_id);
- mutex_unlock(&dma_list_mutex);
- if (rc == -EAGAIN)
- goto idr_retry;
- else if (rc != 0)
+ rc = get_dma_id(device);
+ if (rc != 0) {
+ kfree(idr_ref);
return rc;
+ }
+
+ atomic_set(idr_ref, 0);
/* represent channels in sysfs. Probably want devs too */
list_for_each_entry(chan, &device->channels, device_node) {
+ rc = -ENOMEM;
chan->local = alloc_percpu(typeof(*chan->local));
if (chan->local == NULL)
- continue;
+ goto err_out;
chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL);
if (chan->dev == NULL) {
free_percpu(chan->local);
- continue;
+ chan->local = NULL;
+ goto err_out;
}
chan->chan_id = chancnt++;
@@ -677,6 +699,8 @@ int dma_async_device_register(struct dma_device *device)
if (rc) {
free_percpu(chan->local);
chan->local = NULL;
+ kfree(chan->dev);
+ atomic_dec(idr_ref);
goto err_out;
}
chan->client_count = 0;
@@ -701,12 +725,23 @@ int dma_async_device_register(struct dma_device *device)
}
}
list_add_tail_rcu(&device->global_node, &dma_device_list);
+ if (dma_has_cap(DMA_PRIVATE, device->cap_mask))
+ device->privatecnt++; /* Always private */
dma_channel_rebalance();
mutex_unlock(&dma_list_mutex);
return 0;
err_out:
+ /* if we never registered a channel just release the idr */
+ if (atomic_read(idr_ref) == 0) {
+ mutex_lock(&dma_list_mutex);
+ idr_remove(&dma_idr, device->dev_id);
+ mutex_unlock(&dma_list_mutex);
+ kfree(idr_ref);
+ return rc;
+ }
+
list_for_each_entry(chan, &device->channels, device_node) {
if (chan->local == NULL)
continue;
@@ -893,6 +928,7 @@ void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx,
{
tx->chan = chan;
spin_lock_init(&tx->lock);
+ INIT_LIST_HEAD(&tx->tx_list);
}
EXPORT_SYMBOL(dma_async_tx_descriptor_init);
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c
index e190d8b3070..a27c0fb1bc1 100644
--- a/drivers/dma/dmatest.c
+++ b/drivers/dma/dmatest.c
@@ -38,6 +38,11 @@ module_param(max_channels, uint, S_IRUGO);
MODULE_PARM_DESC(max_channels,
"Maximum number of channels to use (default: all)");
+static unsigned int xor_sources = 3;
+module_param(xor_sources, uint, S_IRUGO);
+MODULE_PARM_DESC(xor_sources,
+ "Number of xor source buffers (default: 3)");
+
/*
* Initialization patterns. All bytes in the source buffer has bit 7
* set, all bytes in the destination buffer has bit 7 cleared.
@@ -59,8 +64,9 @@ struct dmatest_thread {
struct list_head node;
struct task_struct *task;
struct dma_chan *chan;
- u8 *srcbuf;
- u8 *dstbuf;
+ u8 **srcs;
+ u8 **dsts;
+ enum dma_transaction_type type;
};
struct dmatest_chan {
@@ -98,30 +104,37 @@ static unsigned long dmatest_random(void)
return buf;
}
-static void dmatest_init_srcbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_srcs(u8 **bufs, unsigned int start, unsigned int len)
{
unsigned int i;
-
- for (i = 0; i < start; i++)
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
- for ( ; i < start + len; i++)
- buf[i] = PATTERN_SRC | PATTERN_COPY
- | (~i & PATTERN_COUNT_MASK);;
- for ( ; i < test_buf_size; i++)
- buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ u8 *buf;
+
+ for (; (buf = *bufs); bufs++) {
+ for (i = 0; i < start; i++)
+ buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < start + len; i++)
+ buf[i] = PATTERN_SRC | PATTERN_COPY
+ | (~i & PATTERN_COUNT_MASK);;
+ for ( ; i < test_buf_size; i++)
+ buf[i] = PATTERN_SRC | (~i & PATTERN_COUNT_MASK);
+ buf++;
+ }
}
-static void dmatest_init_dstbuf(u8 *buf, unsigned int start, unsigned int len)
+static void dmatest_init_dsts(u8 **bufs, unsigned int start, unsigned int len)
{
unsigned int i;
-
- for (i = 0; i < start; i++)
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
- for ( ; i < start + len; i++)
- buf[i] = PATTERN_DST | PATTERN_OVERWRITE
- | (~i & PATTERN_COUNT_MASK);
- for ( ; i < test_buf_size; i++)
- buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ u8 *buf;
+
+ for (; (buf = *bufs); bufs++) {
+ for (i = 0; i < start; i++)
+ buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < start + len; i++)
+ buf[i] = PATTERN_DST | PATTERN_OVERWRITE
+ | (~i & PATTERN_COUNT_MASK);
+ for ( ; i < test_buf_size; i++)
+ buf[i] = PATTERN_DST | (~i & PATTERN_COUNT_MASK);
+ }
}
static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
@@ -150,23 +163,30 @@ static void dmatest_mismatch(u8 actual, u8 pattern, unsigned int index,
thread_name, index, expected, actual);
}
-static unsigned int dmatest_verify(u8 *buf, unsigned int start,
+static unsigned int dmatest_verify(u8 **bufs, unsigned int start,
unsigned int end, unsigned int counter, u8 pattern,
bool is_srcbuf)
{
unsigned int i;
unsigned int error_count = 0;
u8 actual;
-
- for (i = start; i < end; i++) {
- actual = buf[i];
- if (actual != (pattern | (~counter & PATTERN_COUNT_MASK))) {
- if (error_count < 32)
- dmatest_mismatch(actual, pattern, i, counter,
- is_srcbuf);
- error_count++;
+ u8 expected;
+ u8 *buf;
+ unsigned int counter_orig = counter;
+
+ for (; (buf = *bufs); bufs++) {
+ counter = counter_orig;
+ for (i = start; i < end; i++) {
+ actual = buf[i];
+ expected = pattern | (~counter & PATTERN_COUNT_MASK);
+ if (actual != expected) {
+ if (error_count < 32)
+ dmatest_mismatch(actual, pattern, i,
+ counter, is_srcbuf);
+ error_count++;
+ }
+ counter++;
}
- counter++;
}
if (error_count > 32)
@@ -176,12 +196,17 @@ static unsigned int dmatest_verify(u8 *buf, unsigned int start,
return error_count;
}
+static void dmatest_callback(void *completion)
+{
+ complete(completion);
+}
+
/*
* This function repeatedly tests DMA transfers of various lengths and
- * offsets until it is told to exit by kthread_stop(). There may be
- * multiple threads running this function in parallel for a single
- * channel, and there may be multiple channels being tested in
- * parallel.
+ * offsets for a given operation type until it is told to exit by
+ * kthread_stop(). There may be multiple threads running this function
+ * in parallel for a single channel, and there may be multiple channels
+ * being tested in parallel.
*
* Before each test, the source and destination buffer is initialized
* with a known pattern. This pattern is different depending on
@@ -201,25 +226,57 @@ static int dmatest_func(void *data)
unsigned int total_tests = 0;
dma_cookie_t cookie;
enum dma_status status;
+ enum dma_ctrl_flags flags;
int ret;
+ int src_cnt;
+ int dst_cnt;
+ int i;
thread_name = current->comm;
ret = -ENOMEM;
- thread->srcbuf = kmalloc(test_buf_size, GFP_KERNEL);
- if (!thread->srcbuf)
- goto err_srcbuf;
- thread->dstbuf = kmalloc(test_buf_size, GFP_KERNEL);
- if (!thread->dstbuf)
- goto err_dstbuf;
smp_rmb();
chan = thread->chan;
+ if (thread->type == DMA_MEMCPY)
+ src_cnt = dst_cnt = 1;
+ else if (thread->type == DMA_XOR) {
+ src_cnt = xor_sources | 1; /* force odd to ensure dst = src */
+ dst_cnt = 1;
+ } else
+ goto err_srcs;
+
+ thread->srcs = kcalloc(src_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->srcs)
+ goto err_srcs;
+ for (i = 0; i < src_cnt; i++) {
+ thread->srcs[i] = kmalloc(test_buf_size, GFP_KERNEL);
+ if (!thread->srcs[i])
+ goto err_srcbuf;
+ }
+ thread->srcs[i] = NULL;
+
+ thread->dsts = kcalloc(dst_cnt+1, sizeof(u8 *), GFP_KERNEL);
+ if (!thread->dsts)
+ goto err_dsts;
+ for (i = 0; i < dst_cnt; i++) {
+ thread->dsts[i] = kmalloc(test_buf_size, GFP_KERNEL);
+ if (!thread->dsts[i])
+ goto err_dstbuf;
+ }
+ thread->dsts[i] = NULL;
+
+ set_user_nice(current, 10);
+
+ flags = DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP | DMA_PREP_INTERRUPT;
while (!kthread_should_stop()) {
struct dma_device *dev = chan->device;
- struct dma_async_tx_descriptor *tx;
- dma_addr_t dma_src, dma_dest;
+ struct dma_async_tx_descriptor *tx = NULL;
+ dma_addr_t dma_srcs[src_cnt];
+ dma_addr_t dma_dsts[dst_cnt];
+ struct completion cmp;
+ unsigned long tmo = msecs_to_jiffies(3000);
total_tests++;
@@ -227,22 +284,41 @@ static int dmatest_func(void *data)
src_off = dmatest_random() % (test_buf_size - len + 1);
dst_off = dmatest_random() % (test_buf_size - len + 1);
- dmatest_init_srcbuf(thread->srcbuf, src_off, len);
- dmatest_init_dstbuf(thread->dstbuf, dst_off, len);
+ dmatest_init_srcs(thread->srcs, src_off, len);
+ dmatest_init_dsts(thread->dsts, dst_off, len);
- dma_src = dma_map_single(dev->dev, thread->srcbuf + src_off,
- len, DMA_TO_DEVICE);
+ for (i = 0; i < src_cnt; i++) {
+ u8 *buf = thread->srcs[i] + src_off;
+
+ dma_srcs[i] = dma_map_single(dev->dev, buf, len,
+ DMA_TO_DEVICE);
+ }
/* map with DMA_BIDIRECTIONAL to force writeback/invalidate */
- dma_dest = dma_map_single(dev->dev, thread->dstbuf,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < dst_cnt; i++) {
+ dma_dsts[i] = dma_map_single(dev->dev, thread->dsts[i],
+ test_buf_size,
+ DMA_BIDIRECTIONAL);
+ }
+
+ if (thread->type == DMA_MEMCPY)
+ tx = dev->device_prep_dma_memcpy(chan,
+ dma_dsts[0] + dst_off,
+ dma_srcs[0], len,
+ flags);
+ else if (thread->type == DMA_XOR)
+ tx = dev->device_prep_dma_xor(chan,
+ dma_dsts[0] + dst_off,
+ dma_srcs, xor_sources,
+ len, flags);
- tx = dev->device_prep_dma_memcpy(chan, dma_dest + dst_off,
- dma_src, len,
- DMA_CTRL_ACK | DMA_COMPL_SKIP_DEST_UNMAP);
if (!tx) {
- dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE);
- dma_unmap_single(dev->dev, dma_dest,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < src_cnt; i++)
+ dma_unmap_single(dev->dev, dma_srcs[i], len,
+ DMA_TO_DEVICE);
+ for (i = 0; i < dst_cnt; i++)
+ dma_unmap_single(dev->dev, dma_dsts[i],
+ test_buf_size,
+ DMA_BIDIRECTIONAL);
pr_warning("%s: #%u: prep error with src_off=0x%x "
"dst_off=0x%x len=0x%x\n",
thread_name, total_tests - 1,
@@ -251,7 +327,10 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
- tx->callback = NULL;
+
+ init_completion(&cmp);
+ tx->callback = dmatest_callback;
+ tx->callback_param = &cmp;
cookie = tx->tx_submit(tx);
if (dma_submit_error(cookie)) {
@@ -263,44 +342,50 @@ static int dmatest_func(void *data)
failed_tests++;
continue;
}
- dma_async_memcpy_issue_pending(chan);
+ dma_async_issue_pending(chan);
- do {
- msleep(1);
- status = dma_async_memcpy_complete(
- chan, cookie, NULL, NULL);
- } while (status == DMA_IN_PROGRESS);
+ tmo = wait_for_completion_timeout(&cmp, tmo);
+ status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
- if (status == DMA_ERROR) {
- pr_warning("%s: #%u: error during copy\n",
- thread_name, total_tests - 1);
+ if (tmo == 0) {
+ pr_warning("%s: #%u: test timed out\n",
+ thread_name, total_tests - 1);
+ failed_tests++;
+ continue;
+ } else if (status != DMA_SUCCESS) {
+ pr_warning("%s: #%u: got completion callback,"
+ " but status is \'%s\'\n",
+ thread_name, total_tests - 1,
+ status == DMA_ERROR ? "error" : "in progress");
failed_tests++;
continue;
}
+
/* Unmap by myself (see DMA_COMPL_SKIP_DEST_UNMAP above) */
- dma_unmap_single(dev->dev, dma_dest,
- test_buf_size, DMA_BIDIRECTIONAL);
+ for (i = 0; i < dst_cnt; i++)
+ dma_unmap_single(dev->dev, dma_dsts[i], test_buf_size,
+ DMA_BIDIRECTIONAL);
error_count = 0;
pr_debug("%s: verifying source buffer...\n", thread_name);
- error_count += dmatest_verify(thread->srcbuf, 0, src_off,
+ error_count += dmatest_verify(thread->srcs, 0, src_off,
0, PATTERN_SRC, true);
- error_count += dmatest_verify(thread->srcbuf, src_off,
+ error_count += dmatest_verify(thread->srcs, src_off,
src_off + len, src_off,
PATTERN_SRC | PATTERN_COPY, true);
- error_count += dmatest_verify(thread->srcbuf, src_off + len,
+ error_count += dmatest_verify(thread->srcs, src_off + len,
test_buf_size, src_off + len,
PATTERN_SRC, true);
pr_debug("%s: verifying dest buffer...\n",
thread->task->comm);
- error_count += dmatest_verify(thread->dstbuf, 0, dst_off,
+ error_count += dmatest_verify(thread->dsts, 0, dst_off,
0, PATTERN_DST, false);
- error_count += dmatest_verify(thread->dstbuf, dst_off,
+ error_count += dmatest_verify(thread->dsts, dst_off,
dst_off + len, src_off,
PATTERN_SRC | PATTERN_COPY, false);
- error_count += dmatest_verify(thread->dstbuf, dst_off + len,
+ error_count += dmatest_verify(thread->dsts, dst_off + len,
test_buf_size, dst_off + len,
PATTERN_DST, false);
@@ -319,10 +404,16 @@ static int dmatest_func(void *data)
}
ret = 0;
- kfree(thread->dstbuf);
+ for (i = 0; thread->dsts[i]; i++)
+ kfree(thread->dsts[i]);
err_dstbuf:
- kfree(thread->srcbuf);
+ kfree(thread->dsts);
+err_dsts:
+ for (i = 0; thread->srcs[i]; i++)
+ kfree(thread->srcs[i]);
err_srcbuf:
+ kfree(thread->srcs);
+err_srcs:
pr_notice("%s: terminating after %u tests, %u failures (status %d)\n",
thread_name, total_tests, failed_tests, ret);
return ret;
@@ -344,35 +435,36 @@ static void dmatest_cleanup_channel(struct dmatest_chan *dtc)
kfree(dtc);
}
-static int dmatest_add_channel(struct dma_chan *chan)
+static int dmatest_add_threads(struct dmatest_chan *dtc, enum dma_transaction_type type)
{
- struct dmatest_chan *dtc;
- struct dmatest_thread *thread;
- unsigned int i;
-
- dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
- if (!dtc) {
- pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
- return -ENOMEM;
- }
+ struct dmatest_thread *thread;
+ struct dma_chan *chan = dtc->chan;
+ char *op;
+ unsigned int i;
- dtc->chan = chan;
- INIT_LIST_HEAD(&dtc->threads);
+ if (type == DMA_MEMCPY)
+ op = "copy";
+ else if (type == DMA_XOR)
+ op = "xor";
+ else
+ return -EINVAL;
for (i = 0; i < threads_per_chan; i++) {
thread = kzalloc(sizeof(struct dmatest_thread), GFP_KERNEL);
if (!thread) {
- pr_warning("dmatest: No memory for %s-test%u\n",
- dma_chan_name(chan), i);
+ pr_warning("dmatest: No memory for %s-%s%u\n",
+ dma_chan_name(chan), op, i);
+
break;
}
thread->chan = dtc->chan;
+ thread->type = type;
smp_wmb();
- thread->task = kthread_run(dmatest_func, thread, "%s-test%u",
- dma_chan_name(chan), i);
+ thread->task = kthread_run(dmatest_func, thread, "%s-%s%u",
+ dma_chan_name(chan), op, i);
if (IS_ERR(thread->task)) {
- pr_warning("dmatest: Failed to run thread %s-test%u\n",
- dma_chan_name(chan), i);
+ pr_warning("dmatest: Failed to run thread %s-%s%u\n",
+ dma_chan_name(chan), op, i);
kfree(thread);
break;
}
@@ -382,7 +474,36 @@ static int dmatest_add_channel(struct dma_chan *chan)
list_add_tail(&thread->node, &dtc->threads);
}
- pr_info("dmatest: Started %u threads using %s\n", i, dma_chan_name(chan));
+ return i;
+}
+
+static int dmatest_add_channel(struct dma_chan *chan)
+{
+ struct dmatest_chan *dtc;
+ struct dma_device *dma_dev = chan->device;
+ unsigned int thread_count = 0;
+ unsigned int cnt;
+
+ dtc = kmalloc(sizeof(struct dmatest_chan), GFP_KERNEL);
+ if (!dtc) {
+ pr_warning("dmatest: No memory for %s\n", dma_chan_name(chan));
+ return -ENOMEM;
+ }
+
+ dtc->chan = chan;
+ INIT_LIST_HEAD(&dtc->threads);
+
+ if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
+ cnt = dmatest_add_threads(dtc, DMA_MEMCPY);
+ thread_count += cnt > 0 ?: 0;
+ }
+ if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
+ cnt = dmatest_add_threads(dtc, DMA_XOR);
+ thread_count += cnt > 0 ?: 0;
+ }
+
+ pr_info("dmatest: Started %u threads using %s\n",
+ thread_count, dma_chan_name(chan));
list_add_tail(&dtc->node, &dmatest_channels);
nr_channels++;
diff --git a/drivers/dma/dw_dmac.c b/drivers/dma/dw_dmac.c
index 20ad3d26bec..98c9a847bf5 100644
--- a/drivers/dma/dw_dmac.c
+++ b/drivers/dma/dw_dmac.c
@@ -363,6 +363,82 @@ static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
dwc_descriptor_complete(dwc, bad_desc);
}
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+inline dma_addr_t dw_dma_get_src_addr(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ return channel_readl(dwc, SAR);
+}
+EXPORT_SYMBOL(dw_dma_get_src_addr);
+
+inline dma_addr_t dw_dma_get_dst_addr(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ return channel_readl(dwc, DAR);
+}
+EXPORT_SYMBOL(dw_dma_get_dst_addr);
+
+/* called with dwc->lock held and all DMAC interrupts disabled */
+static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
+ u32 status_block, u32 status_err, u32 status_xfer)
+{
+ if (status_block & dwc->mask) {
+ void (*callback)(void *param);
+ void *callback_param;
+
+ dev_vdbg(chan2dev(&dwc->chan), "new cyclic period llp 0x%08x\n",
+ channel_readl(dwc, LLP));
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+
+ callback = dwc->cdesc->period_callback;
+ callback_param = dwc->cdesc->period_callback_param;
+ if (callback) {
+ spin_unlock(&dwc->lock);
+ callback(callback_param);
+ spin_lock(&dwc->lock);
+ }
+ }
+
+ /*
+ * Error and transfer complete are highly unlikely, and will most
+ * likely be due to a configuration error by the user.
+ */
+ if (unlikely(status_err & dwc->mask) ||
+ unlikely(status_xfer & dwc->mask)) {
+ int i;
+
+ dev_err(chan2dev(&dwc->chan), "cyclic DMA unexpected %s "
+ "interrupt, stopping DMA transfer\n",
+ status_xfer ? "xfer" : "error");
+ dev_err(chan2dev(&dwc->chan),
+ " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+ channel_readl(dwc, SAR),
+ channel_readl(dwc, DAR),
+ channel_readl(dwc, LLP),
+ channel_readl(dwc, CTL_HI),
+ channel_readl(dwc, CTL_LO));
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ /* make sure DMA does not restart by loading a new list */
+ channel_writel(dwc, LLP, 0);
+ channel_writel(dwc, CTL_LO, 0);
+ channel_writel(dwc, CTL_HI, 0);
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ for (i = 0; i < dwc->cdesc->periods; i++)
+ dwc_dump_lli(dwc, &dwc->cdesc->desc[i]->lli);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+
static void dw_dma_tasklet(unsigned long data)
{
struct dw_dma *dw = (struct dw_dma *)data;
@@ -382,7 +458,10 @@ static void dw_dma_tasklet(unsigned long data)
for (i = 0; i < dw->dma.chancnt; i++) {
dwc = &dw->chan[i];
spin_lock(&dwc->lock);
- if (status_err & (1 << i))
+ if (test_bit(DW_DMA_IS_CYCLIC, &dwc->flags))
+ dwc_handle_cyclic(dw, dwc, status_block, status_err,
+ status_xfer);
+ else if (status_err & (1 << i))
dwc_handle_error(dw, dwc);
else if ((status_block | status_xfer) & (1 << i))
dwc_scan_descriptors(dw, dwc);
@@ -826,7 +905,6 @@ static int dwc_alloc_chan_resources(struct dma_chan *chan)
dma_async_tx_descriptor_init(&desc->txd, chan);
desc->txd.tx_submit = dwc_tx_submit;
desc->txd.flags = DMA_CTRL_ACK;
- INIT_LIST_HEAD(&desc->txd.tx_list);
desc->txd.phys = dma_map_single(chan2parent(chan), &desc->lli,
sizeof(desc->lli), DMA_TO_DEVICE);
dwc_desc_put(dwc, desc);
@@ -884,6 +962,257 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
dev_vdbg(chan2dev(chan), "free_chan_resources done\n");
}
+/* --------------------- Cyclic DMA API extensions -------------------- */
+
+/**
+ * dw_dma_cyclic_start - start the cyclic DMA transfer
+ * @chan: the DMA channel to start
+ *
+ * Must be called with soft interrupts disabled. Returns zero on success or
+ * -errno on failure.
+ */
+int dw_dma_cyclic_start(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+
+ if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+ dev_err(chan2dev(&dwc->chan), "missing prep for cyclic DMA\n");
+ return -ENODEV;
+ }
+
+ spin_lock(&dwc->lock);
+
+ /* assert channel is idle */
+ if (dma_readl(dw, CH_EN) & dwc->mask) {
+ dev_err(chan2dev(&dwc->chan),
+ "BUG: Attempted to start non-idle channel\n");
+ dev_err(chan2dev(&dwc->chan),
+ " SAR: 0x%x DAR: 0x%x LLP: 0x%x CTL: 0x%x:%08x\n",
+ channel_readl(dwc, SAR),
+ channel_readl(dwc, DAR),
+ channel_readl(dwc, LLP),
+ channel_readl(dwc, CTL_HI),
+ channel_readl(dwc, CTL_LO));
+ spin_unlock(&dwc->lock);
+ return -EBUSY;
+ }
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ /* setup DMAC channel registers */
+ channel_writel(dwc, LLP, dwc->cdesc->desc[0]->txd.phys);
+ channel_writel(dwc, CTL_LO, DWC_CTLL_LLP_D_EN | DWC_CTLL_LLP_S_EN);
+ channel_writel(dwc, CTL_HI, 0);
+
+ channel_set_bit(dw, CH_EN, dwc->mask);
+
+ spin_unlock(&dwc->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_start);
+
+/**
+ * dw_dma_cyclic_stop - stop the cyclic DMA transfer
+ * @chan: the DMA channel to stop
+ *
+ * Must be called with soft interrupts disabled.
+ */
+void dw_dma_cyclic_stop(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+
+ spin_lock(&dwc->lock);
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ spin_unlock(&dwc->lock);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_stop);
+
+/**
+ * dw_dma_cyclic_prep - prepare the cyclic DMA transfer
+ * @chan: the DMA channel to prepare
+ * @buf_addr: physical DMA address where the buffer starts
+ * @buf_len: total number of bytes for the entire buffer
+ * @period_len: number of bytes for each period
+ * @direction: transfer direction, to or from device
+ *
+ * Must be called before trying to start the transfer. Returns a valid struct
+ * dw_cyclic_desc if successful or an ERR_PTR(-errno) if not successful.
+ */
+struct dw_cyclic_desc *dw_dma_cyclic_prep(struct dma_chan *chan,
+ dma_addr_t buf_addr, size_t buf_len, size_t period_len,
+ enum dma_data_direction direction)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_cyclic_desc *cdesc;
+ struct dw_cyclic_desc *retval = NULL;
+ struct dw_desc *desc;
+ struct dw_desc *last = NULL;
+ struct dw_dma_slave *dws = chan->private;
+ unsigned long was_cyclic;
+ unsigned int reg_width;
+ unsigned int periods;
+ unsigned int i;
+
+ spin_lock_bh(&dwc->lock);
+ if (!list_empty(&dwc->queue) || !list_empty(&dwc->active_list)) {
+ spin_unlock_bh(&dwc->lock);
+ dev_dbg(chan2dev(&dwc->chan),
+ "queue and/or active list are not empty\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ was_cyclic = test_and_set_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+ spin_unlock_bh(&dwc->lock);
+ if (was_cyclic) {
+ dev_dbg(chan2dev(&dwc->chan),
+ "channel already prepared for cyclic DMA\n");
+ return ERR_PTR(-EBUSY);
+ }
+
+ retval = ERR_PTR(-EINVAL);
+ reg_width = dws->reg_width;
+ periods = buf_len / period_len;
+
+ /* Check for too big/unaligned periods and unaligned DMA buffer. */
+ if (period_len > (DWC_MAX_COUNT << reg_width))
+ goto out_err;
+ if (unlikely(period_len & ((1 << reg_width) - 1)))
+ goto out_err;
+ if (unlikely(buf_addr & ((1 << reg_width) - 1)))
+ goto out_err;
+ if (unlikely(!(direction & (DMA_TO_DEVICE | DMA_FROM_DEVICE))))
+ goto out_err;
+
+ retval = ERR_PTR(-ENOMEM);
+
+ if (periods > NR_DESCS_PER_CHANNEL)
+ goto out_err;
+
+ cdesc = kzalloc(sizeof(struct dw_cyclic_desc), GFP_KERNEL);
+ if (!cdesc)
+ goto out_err;
+
+ cdesc->desc = kzalloc(sizeof(struct dw_desc *) * periods, GFP_KERNEL);
+ if (!cdesc->desc)
+ goto out_err_alloc;
+
+ for (i = 0; i < periods; i++) {
+ desc = dwc_desc_get(dwc);
+ if (!desc)
+ goto out_err_desc_get;
+
+ switch (direction) {
+ case DMA_TO_DEVICE:
+ desc->lli.dar = dws->tx_reg;
+ desc->lli.sar = buf_addr + (period_len * i);
+ desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+ | DWC_CTLL_DST_WIDTH(reg_width)
+ | DWC_CTLL_SRC_WIDTH(reg_width)
+ | DWC_CTLL_DST_FIX
+ | DWC_CTLL_SRC_INC
+ | DWC_CTLL_FC_M2P
+ | DWC_CTLL_INT_EN);
+ break;
+ case DMA_FROM_DEVICE:
+ desc->lli.dar = buf_addr + (period_len * i);
+ desc->lli.sar = dws->rx_reg;
+ desc->lli.ctllo = (DWC_DEFAULT_CTLLO
+ | DWC_CTLL_SRC_WIDTH(reg_width)
+ | DWC_CTLL_DST_WIDTH(reg_width)
+ | DWC_CTLL_DST_INC
+ | DWC_CTLL_SRC_FIX
+ | DWC_CTLL_FC_P2M
+ | DWC_CTLL_INT_EN);
+ break;
+ default:
+ break;
+ }
+
+ desc->lli.ctlhi = (period_len >> reg_width);
+ cdesc->desc[i] = desc;
+
+ if (last) {
+ last->lli.llp = desc->txd.phys;
+ dma_sync_single_for_device(chan2parent(chan),
+ last->txd.phys, sizeof(last->lli),
+ DMA_TO_DEVICE);
+ }
+
+ last = desc;
+ }
+
+ /* lets make a cyclic list */
+ last->lli.llp = cdesc->desc[0]->txd.phys;
+ dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
+ sizeof(last->lli), DMA_TO_DEVICE);
+
+ dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%08x len %zu "
+ "period %zu periods %d\n", buf_addr, buf_len,
+ period_len, periods);
+
+ cdesc->periods = periods;
+ dwc->cdesc = cdesc;
+
+ return cdesc;
+
+out_err_desc_get:
+ while (i--)
+ dwc_desc_put(dwc, cdesc->desc[i]);
+out_err_alloc:
+ kfree(cdesc);
+out_err:
+ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+ return (struct dw_cyclic_desc *)retval;
+}
+EXPORT_SYMBOL(dw_dma_cyclic_prep);
+
+/**
+ * dw_dma_cyclic_free - free a prepared cyclic DMA transfer
+ * @chan: the DMA channel to free
+ */
+void dw_dma_cyclic_free(struct dma_chan *chan)
+{
+ struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
+ struct dw_dma *dw = to_dw_dma(dwc->chan.device);
+ struct dw_cyclic_desc *cdesc = dwc->cdesc;
+ int i;
+
+ dev_dbg(chan2dev(&dwc->chan), "cyclic free\n");
+
+ if (!cdesc)
+ return;
+
+ spin_lock_bh(&dwc->lock);
+
+ channel_clear_bit(dw, CH_EN, dwc->mask);
+ while (dma_readl(dw, CH_EN) & dwc->mask)
+ cpu_relax();
+
+ dma_writel(dw, CLEAR.BLOCK, dwc->mask);
+ dma_writel(dw, CLEAR.ERROR, dwc->mask);
+ dma_writel(dw, CLEAR.XFER, dwc->mask);
+
+ spin_unlock_bh(&dwc->lock);
+
+ for (i = 0; i < cdesc->periods; i++)
+ dwc_desc_put(dwc, cdesc->desc[i]);
+
+ kfree(cdesc->desc);
+ kfree(cdesc);
+
+ clear_bit(DW_DMA_IS_CYCLIC, &dwc->flags);
+}
+EXPORT_SYMBOL(dw_dma_cyclic_free);
+
/*----------------------------------------------------------------------*/
static void dw_dma_off(struct dw_dma *dw)
diff --git a/drivers/dma/dw_dmac_regs.h b/drivers/dma/dw_dmac_regs.h
index b252b202c5c..13a58076703 100644
--- a/drivers/dma/dw_dmac_regs.h
+++ b/drivers/dma/dw_dmac_regs.h
@@ -126,6 +126,10 @@ struct dw_dma_regs {
#define DW_REGLEN 0x400
+enum dw_dmac_flags {
+ DW_DMA_IS_CYCLIC = 0,
+};
+
struct dw_dma_chan {
struct dma_chan chan;
void __iomem *ch_regs;
@@ -134,10 +138,12 @@ struct dw_dma_chan {
spinlock_t lock;
/* these other elements are all protected by lock */
+ unsigned long flags;
dma_cookie_t completed;
struct list_head active_list;
struct list_head queue;
struct list_head free_list;
+ struct dw_cyclic_desc *cdesc;
unsigned int descs_allocated;
};
@@ -158,7 +164,6 @@ static inline struct dw_dma_chan *to_dw_dma_chan(struct dma_chan *chan)
return container_of(chan, struct dw_dma_chan, chan);
}
-
struct dw_dma {
struct dma_device dma;
void __iomem *regs;
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c
index 86d6da47f55..da8a8ed9e41 100644
--- a/drivers/dma/fsldma.c
+++ b/drivers/dma/fsldma.c
@@ -354,7 +354,6 @@ static struct fsl_desc_sw *fsl_dma_alloc_descriptor(
dma_async_tx_descriptor_init(&desc_sw->async_tx,
&fsl_chan->common);
desc_sw->async_tx.tx_submit = fsl_dma_tx_submit;
- INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
desc_sw->async_tx.phys = pdesc;
}
diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c
index 5905cd36bcd..e4fc33c1c32 100644
--- a/drivers/dma/ioat_dma.c
+++ b/drivers/dma/ioat_dma.c
@@ -693,7 +693,6 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
desc_sw->async_tx.tx_submit = ioat2_tx_submit;
break;
}
- INIT_LIST_HEAD(&desc_sw->async_tx.tx_list);
desc_sw->hw = desc;
desc_sw->async_tx.phys = phys;
diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
index 16adbe61cfb..2f052265122 100644
--- a/drivers/dma/iop-adma.c
+++ b/drivers/dma/iop-adma.c
@@ -498,7 +498,6 @@ static int iop_adma_alloc_chan_resources(struct dma_chan *chan)
slot->async_tx.tx_submit = iop_adma_tx_submit;
INIT_LIST_HEAD(&slot->chain_node);
INIT_LIST_HEAD(&slot->slot_node);
- INIT_LIST_HEAD(&slot->async_tx.tx_list);
hw_desc = (char *) iop_chan->device->dma_desc_pool;
slot->async_tx.phys =
(dma_addr_t) &hw_desc[idx * IOP_ADMA_SLOT_SIZE];
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index da781d10789..e202a6ce557 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -28,6 +28,9 @@
#define FS_VF_IN_VALID 0x00000002
#define FS_ENC_IN_VALID 0x00000001
+static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
+ bool wait_for_stop);
+
/*
* There can be only one, we could allocate it dynamically, but then we'd have
* to add an extra parameter to some functions, and use something as ugly as
@@ -107,7 +110,7 @@ static uint32_t bytes_per_pixel(enum pixel_fmt fmt)
}
}
-/* Enable / disable direct write to memory by the Camera Sensor Interface */
+/* Enable direct write to memory by the Camera Sensor Interface */
static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
{
uint32_t ic_conf, mask;
@@ -126,6 +129,7 @@ static void ipu_ic_enable_task(struct ipu *ipu, enum ipu_channel channel)
idmac_write_icreg(ipu, ic_conf, IC_CONF);
}
+/* Called under spin_lock_irqsave(&ipu_data.lock) */
static void ipu_ic_disable_task(struct ipu *ipu, enum ipu_channel channel)
{
uint32_t ic_conf, mask;
@@ -422,7 +426,7 @@ static void ipu_ch_param_set_size(union chan_param_mem *params,
break;
default:
dev_err(ipu_data.dev,
- "mxc ipu: unimplemented pixel format %d\n", pixel_fmt);
+ "mx3 ipu: unimplemented pixel format %d\n", pixel_fmt);
break;
}
@@ -433,20 +437,20 @@ static void ipu_ch_param_set_burst_size(union chan_param_mem *params,
uint16_t burst_pixels)
{
params->pp.npb = burst_pixels - 1;
-};
+}
static void ipu_ch_param_set_buffer(union chan_param_mem *params,
dma_addr_t buf0, dma_addr_t buf1)
{
params->pp.eba0 = buf0;
params->pp.eba1 = buf1;
-};
+}
static void ipu_ch_param_set_rotation(union chan_param_mem *params,
enum ipu_rotate_mode rotate)
{
params->pp.bam = rotate;
-};
+}
static void ipu_write_param_mem(uint32_t addr, uint32_t *data,
uint32_t num_words)
@@ -571,7 +575,7 @@ static uint32_t dma_param_addr(uint32_t dma_ch)
{
/* Channel Parameter Memory */
return 0x10000 | (dma_ch << 4);
-};
+}
static void ipu_channel_set_priority(struct ipu *ipu, enum ipu_channel channel,
bool prio)
@@ -611,7 +615,8 @@ static uint32_t ipu_channel_conf_mask(enum ipu_channel channel)
/**
* ipu_enable_channel() - enable an IPU channel.
- * @channel: channel ID.
+ * @idmac: IPU DMAC context.
+ * @ichan: IDMAC channel.
* @return: 0 on success or negative error code on failure.
*/
static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
@@ -649,7 +654,7 @@ static int ipu_enable_channel(struct idmac *idmac, struct idmac_channel *ichan)
/**
* ipu_init_channel_buffer() - initialize a buffer for logical IPU channel.
- * @channel: channel ID.
+ * @ichan: IDMAC channel.
* @pixel_fmt: pixel format of buffer. Pixel format is a FOURCC ASCII code.
* @width: width of buffer in pixels.
* @height: height of buffer in pixels.
@@ -687,7 +692,7 @@ static int ipu_init_channel_buffer(struct idmac_channel *ichan,
}
/* IC channel's stride must be a multiple of 8 pixels */
- if ((channel <= 13) && (stride % 8)) {
+ if ((channel <= IDMAC_IC_13) && (stride % 8)) {
dev_err(ipu->dev, "Stride must be 8 pixel multiple\n");
return -EINVAL;
}
@@ -752,7 +757,7 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
/**
* ipu_update_channel_buffer() - update physical address of a channel buffer.
- * @channel: channel ID.
+ * @ichan: IDMAC channel.
* @buffer_n: buffer number to update.
* 0 or 1 are the only valid values.
* @phyaddr: buffer physical address.
@@ -760,9 +765,10 @@ static void ipu_select_buffer(enum ipu_channel channel, int buffer_n)
* function will fail if the buffer is set to ready.
*/
/* Called under spin_lock(_irqsave)(&ichan->lock) */
-static int ipu_update_channel_buffer(enum ipu_channel channel,
+static int ipu_update_channel_buffer(struct idmac_channel *ichan,
int buffer_n, dma_addr_t phyaddr)
{
+ enum ipu_channel channel = ichan->dma_chan.chan_id;
uint32_t reg;
unsigned long flags;
@@ -771,8 +777,8 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
if (buffer_n == 0) {
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
if (reg & (1UL << channel)) {
- spin_unlock_irqrestore(&ipu_data.lock, flags);
- return -EACCES;
+ ipu_ic_disable_task(&ipu_data, channel);
+ ichan->status = IPU_CHANNEL_READY;
}
/* 44.3.3.1.9 - Row Number 1 (WORD1, offset 0) */
@@ -782,8 +788,8 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
} else {
reg = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
if (reg & (1UL << channel)) {
- spin_unlock_irqrestore(&ipu_data.lock, flags);
- return -EACCES;
+ ipu_ic_disable_task(&ipu_data, channel);
+ ichan->status = IPU_CHANNEL_READY;
}
/* Check if double-buffering is already enabled */
@@ -805,6 +811,39 @@ static int ipu_update_channel_buffer(enum ipu_channel channel,
}
/* Called under spin_lock_irqsave(&ichan->lock) */
+static int ipu_submit_buffer(struct idmac_channel *ichan,
+ struct idmac_tx_desc *desc, struct scatterlist *sg, int buf_idx)
+{
+ unsigned int chan_id = ichan->dma_chan.chan_id;
+ struct device *dev = &ichan->dma_chan.dev->device;
+ int ret;
+
+ if (async_tx_test_ack(&desc->txd))
+ return -EINTR;
+
+ /*
+ * On first invocation this shouldn't be necessary, the call to
+ * ipu_init_channel_buffer() above will set addresses for us, so we
+ * could make it conditional on status >= IPU_CHANNEL_ENABLED, but
+ * doing it again shouldn't hurt either.
+ */
+ ret = ipu_update_channel_buffer(ichan, buf_idx,
+ sg_dma_address(sg));
+
+ if (ret < 0) {
+ dev_err(dev, "Updating sg %p on channel 0x%x buffer %d failed!\n",
+ sg, chan_id, buf_idx);
+ return ret;
+ }
+
+ ipu_select_buffer(chan_id, buf_idx);
+ dev_dbg(dev, "Updated sg %p on channel 0x%x buffer %d\n",
+ sg, chan_id, buf_idx);
+
+ return 0;
+}
+
+/* Called under spin_lock_irqsave(&ichan->lock) */
static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
struct idmac_tx_desc *desc)
{
@@ -815,20 +854,10 @@ static int ipu_submit_channel_buffers(struct idmac_channel *ichan,
if (!ichan->sg[i]) {
ichan->sg[i] = sg;
- /*
- * On first invocation this shouldn't be necessary, the
- * call to ipu_init_channel_buffer() above will set
- * addresses for us, so we could make it conditional
- * on status >= IPU_CHANNEL_ENABLED, but doing it again
- * shouldn't hurt either.
- */
- ret = ipu_update_channel_buffer(ichan->dma_chan.chan_id, i,
- sg_dma_address(sg));
+ ret = ipu_submit_buffer(ichan, desc, sg, i);
if (ret < 0)
return ret;
- ipu_select_buffer(ichan->dma_chan.chan_id, i);
-
sg = sg_next(sg);
}
}
@@ -842,19 +871,22 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
struct idmac_channel *ichan = to_idmac_chan(tx->chan);
struct idmac *idmac = to_idmac(tx->chan->device);
struct ipu *ipu = to_ipu(idmac);
+ struct device *dev = &ichan->dma_chan.dev->device;
dma_cookie_t cookie;
unsigned long flags;
+ int ret;
/* Sanity check */
if (!list_empty(&desc->list)) {
/* The descriptor doesn't belong to client */
- dev_err(&ichan->dma_chan.dev->device,
- "Descriptor %p not prepared!\n", tx);
+ dev_err(dev, "Descriptor %p not prepared!\n", tx);
return -EBUSY;
}
mutex_lock(&ichan->chan_mutex);
+ async_tx_clear_ack(tx);
+
if (ichan->status < IPU_CHANNEL_READY) {
struct idmac_video_param *video = &ichan->params.video;
/*
@@ -878,16 +910,7 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
goto out;
}
- /* ipu->lock can be taken under ichan->lock, but not v.v. */
- spin_lock_irqsave(&ichan->lock, flags);
-
- /* submit_buffers() atomically verifies and fills empty sg slots */
- cookie = ipu_submit_channel_buffers(ichan, desc);
-
- spin_unlock_irqrestore(&ichan->lock, flags);
-
- if (cookie < 0)
- goto out;
+ dev_dbg(dev, "Submitting sg %p\n", &desc->sg[0]);
cookie = ichan->dma_chan.cookie;
@@ -897,24 +920,40 @@ static dma_cookie_t idmac_tx_submit(struct dma_async_tx_descriptor *tx)
/* from dmaengine.h: "last cookie value returned to client" */
ichan->dma_chan.cookie = cookie;
tx->cookie = cookie;
+
+ /* ipu->lock can be taken under ichan->lock, but not v.v. */
spin_lock_irqsave(&ichan->lock, flags);
+
list_add_tail(&desc->list, &ichan->queue);
+ /* submit_buffers() atomically verifies and fills empty sg slots */
+ ret = ipu_submit_channel_buffers(ichan, desc);
+
spin_unlock_irqrestore(&ichan->lock, flags);
+ if (ret < 0) {
+ cookie = ret;
+ goto dequeue;
+ }
+
if (ichan->status < IPU_CHANNEL_ENABLED) {
- int ret = ipu_enable_channel(idmac, ichan);
+ ret = ipu_enable_channel(idmac, ichan);
if (ret < 0) {
cookie = ret;
- spin_lock_irqsave(&ichan->lock, flags);
- list_del_init(&desc->list);
- spin_unlock_irqrestore(&ichan->lock, flags);
- tx->cookie = cookie;
- ichan->dma_chan.cookie = cookie;
+ goto dequeue;
}
}
dump_idmac_reg(ipu);
+dequeue:
+ if (cookie < 0) {
+ spin_lock_irqsave(&ichan->lock, flags);
+ list_del_init(&desc->list);
+ spin_unlock_irqrestore(&ichan->lock, flags);
+ tx->cookie = cookie;
+ ichan->dma_chan.cookie = cookie;
+ }
+
out:
mutex_unlock(&ichan->chan_mutex);
@@ -944,8 +983,6 @@ static int idmac_desc_alloc(struct idmac_channel *ichan, int n)
memset(txd, 0, sizeof(*txd));
dma_async_tx_descriptor_init(txd, &ichan->dma_chan);
txd->tx_submit = idmac_tx_submit;
- txd->chan = &ichan->dma_chan;
- INIT_LIST_HEAD(&txd->tx_list);
list_add(&desc->list, &ichan->free_list);
@@ -1161,6 +1198,24 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
return 0;
}
+static struct scatterlist *idmac_sg_next(struct idmac_channel *ichan,
+ struct idmac_tx_desc **desc, struct scatterlist *sg)
+{
+ struct scatterlist *sgnew = sg ? sg_next(sg) : NULL;
+
+ if (sgnew)
+ /* next sg-element in this list */
+ return sgnew;
+
+ if ((*desc)->list.next == &ichan->queue)
+ /* No more descriptors on the queue */
+ return NULL;
+
+ /* Fetch next descriptor */
+ *desc = list_entry((*desc)->list.next, struct idmac_tx_desc, list);
+ return (*desc)->sg;
+}
+
/*
* We have several possibilities here:
* current BUF next BUF
@@ -1176,23 +1231,46 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
static irqreturn_t idmac_interrupt(int irq, void *dev_id)
{
struct idmac_channel *ichan = dev_id;
+ struct device *dev = &ichan->dma_chan.dev->device;
unsigned int chan_id = ichan->dma_chan.chan_id;
struct scatterlist **sg, *sgnext, *sgnew = NULL;
/* Next transfer descriptor */
- struct idmac_tx_desc *desc = NULL, *descnew;
+ struct idmac_tx_desc *desc, *descnew;
dma_async_tx_callback callback;
void *callback_param;
bool done = false;
- u32 ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY),
- ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY),
- curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ u32 ready0, ready1, curbuf, err;
+ unsigned long flags;
/* IDMAC has cleared the respective BUFx_RDY bit, we manage the buffer */
- pr_debug("IDMAC irq %d\n", irq);
+ dev_dbg(dev, "IDMAC irq %d, buf %d\n", irq, ichan->active_buffer);
+
+ spin_lock_irqsave(&ipu_data.lock, flags);
+
+ ready0 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
+ ready1 = idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
+ curbuf = idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
+ err = idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
+
+ if (err & (1 << chan_id)) {
+ idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+ /*
+ * Doing this
+ * ichan->sg[0] = ichan->sg[1] = NULL;
+ * you can force channel re-enable on the next tx_submit(), but
+ * this is dirty - think about descriptors with multiple
+ * sg elements.
+ */
+ dev_warn(dev, "NFB4EOF on channel %d, ready %x, %x, cur %x\n",
+ chan_id, ready0, ready1, curbuf);
+ return IRQ_HANDLED;
+ }
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
+
/* Other interrupts do not interfere with this channel */
spin_lock(&ichan->lock);
-
if (unlikely(chan_id != IDMAC_SDC_0 && chan_id != IDMAC_SDC_1 &&
((curbuf >> chan_id) & 1) == ichan->active_buffer)) {
int i = 100;
@@ -1207,19 +1285,23 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
if (!i) {
spin_unlock(&ichan->lock);
- dev_dbg(ichan->dma_chan.device->dev,
+ dev_dbg(dev,
"IRQ on active buffer on channel %x, active "
"%d, ready %x, %x, current %x!\n", chan_id,
ichan->active_buffer, ready0, ready1, curbuf);
return IRQ_NONE;
- }
+ } else
+ dev_dbg(dev,
+ "Buffer deactivated on channel %x, active "
+ "%d, ready %x, %x, current %x, rest %d!\n", chan_id,
+ ichan->active_buffer, ready0, ready1, curbuf, i);
}
if (unlikely((ichan->active_buffer && (ready1 >> chan_id) & 1) ||
(!ichan->active_buffer && (ready0 >> chan_id) & 1)
)) {
spin_unlock(&ichan->lock);
- dev_dbg(ichan->dma_chan.device->dev,
+ dev_dbg(dev,
"IRQ with active buffer still ready on channel %x, "
"active %d, ready %x, %x!\n", chan_id,
ichan->active_buffer, ready0, ready1);
@@ -1227,8 +1309,9 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
}
if (unlikely(list_empty(&ichan->queue))) {
+ ichan->sg[ichan->active_buffer] = NULL;
spin_unlock(&ichan->lock);
- dev_err(ichan->dma_chan.device->dev,
+ dev_err(dev,
"IRQ without queued buffers on channel %x, active %d, "
"ready %x, %x!\n", chan_id,
ichan->active_buffer, ready0, ready1);
@@ -1243,40 +1326,44 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
sg = &ichan->sg[ichan->active_buffer];
sgnext = ichan->sg[!ichan->active_buffer];
+ if (!*sg) {
+ spin_unlock(&ichan->lock);
+ return IRQ_HANDLED;
+ }
+
+ desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
+ descnew = desc;
+
+ dev_dbg(dev, "IDMAC irq %d, dma 0x%08x, next dma 0x%08x, current %d, curbuf 0x%08x\n",
+ irq, sg_dma_address(*sg), sgnext ? sg_dma_address(sgnext) : 0, ichan->active_buffer, curbuf);
+
+ /* Find the descriptor of sgnext */
+ sgnew = idmac_sg_next(ichan, &descnew, *sg);
+ if (sgnext != sgnew)
+ dev_err(dev, "Submitted buffer %p, next buffer %p\n", sgnext, sgnew);
+
/*
* if sgnext == NULL sg must be the last element in a scatterlist and
* queue must be empty
*/
if (unlikely(!sgnext)) {
- if (unlikely(sg_next(*sg))) {
- dev_err(ichan->dma_chan.device->dev,
- "Broken buffer-update locking on channel %x!\n",
- chan_id);
- /* We'll let the user catch up */
+ if (!WARN_ON(sg_next(*sg)))
+ dev_dbg(dev, "Underrun on channel %x\n", chan_id);
+ ichan->sg[!ichan->active_buffer] = sgnew;
+
+ if (unlikely(sgnew)) {
+ ipu_submit_buffer(ichan, descnew, sgnew, !ichan->active_buffer);
} else {
- /* Underrun */
+ spin_lock_irqsave(&ipu_data.lock, flags);
ipu_ic_disable_task(&ipu_data, chan_id);
- dev_dbg(ichan->dma_chan.device->dev,
- "Underrun on channel %x\n", chan_id);
+ spin_unlock_irqrestore(&ipu_data.lock, flags);
ichan->status = IPU_CHANNEL_READY;
/* Continue to check for complete descriptor */
}
}
- desc = list_entry(ichan->queue.next, struct idmac_tx_desc, list);
-
- /* First calculate and submit the next sg element */
- if (likely(sgnext))
- sgnew = sg_next(sgnext);
-
- if (unlikely(!sgnew)) {
- /* Start a new scatterlist, if any queued */
- if (likely(desc->list.next != &ichan->queue)) {
- descnew = list_entry(desc->list.next,
- struct idmac_tx_desc, list);
- sgnew = &descnew->sg[0];
- }
- }
+ /* Calculate and submit the next sg element */
+ sgnew = idmac_sg_next(ichan, &descnew, sgnew);
if (unlikely(!sg_next(*sg)) || !sgnext) {
/*
@@ -1289,17 +1376,13 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
*sg = sgnew;
- if (likely(sgnew)) {
- int ret;
-
- ret = ipu_update_channel_buffer(chan_id, ichan->active_buffer,
- sg_dma_address(*sg));
- if (ret < 0)
- dev_err(ichan->dma_chan.device->dev,
- "Failed to update buffer on channel %x buffer %d!\n",
- chan_id, ichan->active_buffer);
- else
- ipu_select_buffer(chan_id, ichan->active_buffer);
+ if (likely(sgnew) &&
+ ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+ spin_unlock(&ichan->lock);
+ callback(callback_param);
+ spin_lock(&ichan->lock);
}
/* Flip the active buffer - even if update above failed */
@@ -1327,13 +1410,20 @@ static void ipu_gc_tasklet(unsigned long arg)
struct idmac_channel *ichan = ipu->channel + i;
struct idmac_tx_desc *desc;
unsigned long flags;
- int j;
+ struct scatterlist *sg;
+ int j, k;
for (j = 0; j < ichan->n_tx_desc; j++) {
desc = ichan->desc + j;
spin_lock_irqsave(&ichan->lock, flags);
if (async_tx_test_ack(&desc->txd)) {
list_move(&desc->list, &ichan->free_list);
+ for_each_sg(desc->sg, sg, desc->sg_len, k) {
+ if (ichan->sg[0] == sg)
+ ichan->sg[0] = NULL;
+ else if (ichan->sg[1] == sg)
+ ichan->sg[1] = NULL;
+ }
async_tx_clear_ack(&desc->txd);
}
spin_unlock_irqrestore(&ichan->lock, flags);
@@ -1341,13 +1431,7 @@ static void ipu_gc_tasklet(unsigned long arg)
}
}
-/*
- * At the time .device_alloc_chan_resources() method is called, we cannot know,
- * whether the client will accept the channel. Thus we must only check, if we
- * can satisfy client's request but the only real criterion to verify, whether
- * the client has accepted our offer is the client_count. That's why we have to
- * perform the rest of our allocation tasks on the first call to this function.
- */
+/* Allocate and initialise a transfer descriptor. */
static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan,
struct scatterlist *sgl, unsigned int sg_len,
enum dma_data_direction direction, unsigned long tx_flags)
@@ -1358,8 +1442,8 @@ static struct dma_async_tx_descriptor *idmac_prep_slave_sg(struct dma_chan *chan
unsigned long flags;
/* We only can handle these three channels so far */
- if (ichan->dma_chan.chan_id != IDMAC_SDC_0 && ichan->dma_chan.chan_id != IDMAC_SDC_1 &&
- ichan->dma_chan.chan_id != IDMAC_IC_7)
+ if (chan->chan_id != IDMAC_SDC_0 && chan->chan_id != IDMAC_SDC_1 &&
+ chan->chan_id != IDMAC_IC_7)
return NULL;
if (direction != DMA_FROM_DEVICE && direction != DMA_TO_DEVICE) {
@@ -1400,7 +1484,7 @@ static void idmac_issue_pending(struct dma_chan *chan)
/* This is not always needed, but doesn't hurt either */
spin_lock_irqsave(&ipu->lock, flags);
- ipu_select_buffer(ichan->dma_chan.chan_id, ichan->active_buffer);
+ ipu_select_buffer(chan->chan_id, ichan->active_buffer);
spin_unlock_irqrestore(&ipu->lock, flags);
/*
@@ -1432,8 +1516,7 @@ static void __idmac_terminate_all(struct dma_chan *chan)
struct idmac_tx_desc *desc = ichan->desc + i;
if (list_empty(&desc->list))
/* Descriptor was prepared, but not submitted */
- list_add(&desc->list,
- &ichan->free_list);
+ list_add(&desc->list, &ichan->free_list);
async_tx_clear_ack(&desc->txd);
}
@@ -1458,6 +1541,28 @@ static void idmac_terminate_all(struct dma_chan *chan)
mutex_unlock(&ichan->chan_mutex);
}
+#ifdef DEBUG
+static irqreturn_t ic_sof_irq(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ printk(KERN_DEBUG "Got SOF IRQ %d on Channel %d\n",
+ irq, ichan->dma_chan.chan_id);
+ disable_irq(irq);
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t ic_eof_irq(int irq, void *dev_id)
+{
+ struct idmac_channel *ichan = dev_id;
+ printk(KERN_DEBUG "Got EOF IRQ %d on Channel %d\n",
+ irq, ichan->dma_chan.chan_id);
+ disable_irq(irq);
+ return IRQ_HANDLED;
+}
+
+static int ic_sof = -EINVAL, ic_eof = -EINVAL;
+#endif
+
static int idmac_alloc_chan_resources(struct dma_chan *chan)
{
struct idmac_channel *ichan = to_idmac_chan(chan);
@@ -1471,31 +1576,49 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
chan->cookie = 1;
ichan->completed = -ENXIO;
- ret = ipu_irq_map(ichan->dma_chan.chan_id);
+ ret = ipu_irq_map(chan->chan_id);
if (ret < 0)
goto eimap;
ichan->eof_irq = ret;
+
+ /*
+ * Important to first disable the channel, because maybe someone
+ * used it before us, e.g., the bootloader
+ */
+ ipu_disable_channel(idmac, ichan, true);
+
+ ret = ipu_init_channel(idmac, ichan);
+ if (ret < 0)
+ goto eichan;
+
ret = request_irq(ichan->eof_irq, idmac_interrupt, 0,
ichan->eof_name, ichan);
if (ret < 0)
goto erirq;
- ret = ipu_init_channel(idmac, ichan);
- if (ret < 0)
- goto eichan;
+#ifdef DEBUG
+ if (chan->chan_id == IDMAC_IC_7) {
+ ic_sof = ipu_irq_map(69);
+ if (ic_sof > 0)
+ request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
+ ic_eof = ipu_irq_map(70);
+ if (ic_eof > 0)
+ request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
+ }
+#endif
ichan->status = IPU_CHANNEL_INITIALIZED;
- dev_dbg(&ichan->dma_chan.dev->device, "Found channel 0x%x, irq %d\n",
- ichan->dma_chan.chan_id, ichan->eof_irq);
+ dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+ chan->chan_id, ichan->eof_irq);
return ret;
-eichan:
- free_irq(ichan->eof_irq, ichan);
erirq:
- ipu_irq_unmap(ichan->dma_chan.chan_id);
+ ipu_uninit_channel(idmac, ichan);
+eichan:
+ ipu_irq_unmap(chan->chan_id);
eimap:
return ret;
}
@@ -1510,8 +1633,22 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
__idmac_terminate_all(chan);
if (ichan->status > IPU_CHANNEL_FREE) {
+#ifdef DEBUG
+ if (chan->chan_id == IDMAC_IC_7) {
+ if (ic_sof > 0) {
+ free_irq(ic_sof, ichan);
+ ipu_irq_unmap(69);
+ ic_sof = -EINVAL;
+ }
+ if (ic_eof > 0) {
+ free_irq(ic_eof, ichan);
+ ipu_irq_unmap(70);
+ ic_eof = -EINVAL;
+ }
+ }
+#endif
free_irq(ichan->eof_irq, ichan);
- ipu_irq_unmap(ichan->dma_chan.chan_id);
+ ipu_irq_unmap(chan->chan_id);
}
ichan->status = IPU_CHANNEL_FREE;
@@ -1573,7 +1710,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
dma_chan->device = &idmac->dma;
dma_chan->cookie = 1;
dma_chan->chan_id = i;
- list_add_tail(&ichan->dma_chan.device_node, &dma->channels);
+ list_add_tail(&dma_chan->device_node, &dma->channels);
}
idmac_write_icreg(ipu, 0x00000070, IDMAC_CONF);
@@ -1581,7 +1718,7 @@ static int __init ipu_idmac_init(struct ipu *ipu)
return dma_async_device_register(&idmac->dma);
}
-static void ipu_idmac_exit(struct ipu *ipu)
+static void __exit ipu_idmac_exit(struct ipu *ipu)
{
int i;
struct idmac *idmac = &ipu->idmac;
@@ -1600,7 +1737,7 @@ static void ipu_idmac_exit(struct ipu *ipu)
* IPU common probe / remove
*/
-static int ipu_probe(struct platform_device *pdev)
+static int __init ipu_probe(struct platform_device *pdev)
{
struct ipu_platform_data *pdata = pdev->dev.platform_data;
struct resource *mem_ipu, *mem_ic;
@@ -1700,7 +1837,7 @@ err_noirq:
return ret;
}
-static int ipu_remove(struct platform_device *pdev)
+static int __exit ipu_remove(struct platform_device *pdev)
{
struct ipu *ipu = platform_get_drvdata(pdev);
@@ -1725,7 +1862,7 @@ static struct platform_driver ipu_platform_driver = {
.name = "ipu-core",
.owner = THIS_MODULE,
},
- .remove = ipu_remove,
+ .remove = __exit_p(ipu_remove),
};
static int __init ipu_init(void)
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index 83f532cc767..dd8ebc75b66 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -352,7 +352,7 @@ static struct irq_chip ipu_irq_chip = {
};
/* Install the IRQ handler */
-int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
+int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
{
struct ipu_platform_data *pdata = dev->dev.platform_data;
unsigned int irq, irq_base, i;
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index cb7f26fb9f1..ddab94f5122 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -632,7 +632,6 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
slot->async_tx.tx_submit = mv_xor_tx_submit;
INIT_LIST_HEAD(&slot->chain_node);
INIT_LIST_HEAD(&slot->slot_node);
- INIT_LIST_HEAD(&slot->async_tx.tx_list);
hw_desc = (char *) mv_chan->device->dma_desc_pool;
slot->async_tx.phys =
(dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index eee47fd16d7..e5f5c5a8ba6 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -1,13 +1,12 @@
#
# EDAC Kconfig
-# Copyright (c) 2003 Linux Networx
+# Copyright (c) 2008 Doug Thompson www.softwarebitmaker.com
# Licensed and distributed under the GPL
#
menuconfig EDAC
- bool "EDAC - error detection and reporting (EXPERIMENTAL)"
+ bool "EDAC - error detection and reporting"
depends on HAS_IOMEM
- depends on EXPERIMENTAL
depends on X86 || PPC
help
EDAC is designed to report errors in the core system.
@@ -40,6 +39,14 @@ config EDAC_DEBUG
there're four debug levels (x=0,1,2,3 from low to high).
Usually you should select 'N'.
+config EDAC_DEBUG_VERBOSE
+ bool "More verbose debugging"
+ depends on EDAC_DEBUG
+ help
+ This option makes debugging information more verbose.
+ Source file name and line number where debugging message
+ printed will be added to debugging message.
+
config EDAC_MM_EDAC
tristate "Main Memory EDAC (Error Detection And Correction) reporting"
default y
@@ -174,4 +181,27 @@ config EDAC_CELL
Cell Broadband Engine internal memory controller
on platform without a hypervisor
+config EDAC_PPC4XX
+ tristate "PPC4xx IBM DDR2 Memory Controller"
+ depends on EDAC_MM_EDAC && 4xx
+ help
+ This enables support for EDAC on the ECC memory used
+ with the IBM DDR2 memory controller found in various
+ PowerPC 4xx embedded processors such as the 405EX[r],
+ 440SP, 440SPe, 460EX, 460GT and 460SX.
+
+config EDAC_AMD8131
+ tristate "AMD8131 HyperTransport PCI-X Tunnel"
+ depends on EDAC_MM_EDAC && PCI
+ help
+ Support for error detection and correction on the
+ AMD8131 HyperTransport PCI-X Tunnel chip.
+
+config EDAC_AMD8111
+ tristate "AMD8111 HyperTransport I/O Hub"
+ depends on EDAC_MM_EDAC && PCI
+ help
+ Support for error detection and correction on the
+ AMD8111 HyperTransport I/O Hub chip.
+
endif # EDAC
diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile
index b75196927de..a5fdcf02f59 100644
--- a/drivers/edac/Makefile
+++ b/drivers/edac/Makefile
@@ -34,4 +34,4 @@ obj-$(CONFIG_EDAC_PASEMI) += pasemi_edac.o
obj-$(CONFIG_EDAC_MPC85XX) += mpc85xx_edac.o
obj-$(CONFIG_EDAC_MV64X60) += mv64x60_edac.o
obj-$(CONFIG_EDAC_CELL) += cell_edac.o
-
+obj-$(CONFIG_EDAC_PPC4XX) += ppc4xx_edac.o
diff --git a/drivers/edac/amd8111_edac.c b/drivers/edac/amd8111_edac.c
new file mode 100644
index 00000000000..61469218112
--- /dev/null
+++ b/drivers/edac/amd8111_edac.c
@@ -0,0 +1,595 @@
+/*
+ * amd8111_edac.c, AMD8111 Hyper Transport chip EDAC kernel module
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/edac.h>
+#include <linux/pci_ids.h>
+#include <asm/io.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+#include "amd8111_edac.h"
+
+#define AMD8111_EDAC_REVISION " Ver: 1.0.0 " __DATE__
+#define AMD8111_EDAC_MOD_STR "amd8111_edac"
+
+#define PCI_DEVICE_ID_AMD_8111_PCI 0x7460
+static int edac_dev_idx;
+
+enum amd8111_edac_devs {
+ LPC_BRIDGE = 0,
+};
+
+enum amd8111_edac_pcis {
+ PCI_BRIDGE = 0,
+};
+
+/* Wrapper functions for accessing PCI configuration space */
+static int edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
+{
+ int ret;
+
+ ret = pci_read_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Read Error at 0x%x\n", reg);
+
+ return ret;
+}
+
+static void edac_pci_read_byte(struct pci_dev *dev, int reg, u8 *val8)
+{
+ int ret;
+
+ ret = pci_read_config_byte(dev, reg, val8);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Read Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
+{
+ int ret;
+
+ ret = pci_write_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Write Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_byte(struct pci_dev *dev, int reg, u8 val8)
+{
+ int ret;
+
+ ret = pci_write_config_byte(dev, reg, val8);
+ if (ret != 0)
+ printk(KERN_ERR AMD8111_EDAC_MOD_STR
+ " PCI Access Write Error at 0x%x\n", reg);
+}
+
+/*
+ * device-specific methods for amd8111 PCI Bridge Controller
+ *
+ * Error Reporting and Handling for amd8111 chipset could be found
+ * in its datasheet 3.1.2 section, P37
+ */
+static void amd8111_pci_bridge_init(struct amd8111_pci_info *pci_info)
+{
+ u32 val32;
+ struct pci_dev *dev = pci_info->dev;
+
+ /* First clear error detection flags on the host interface */
+
+ /* Clear SSE/SMA/STA flags in the global status register*/
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ if (val32 & PCI_STSCMD_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ /* Clear CRC and Link Fail flags in HT Link Control reg */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ if (val32 & HT_LINK_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ /* Second clear all fault on the secondary interface */
+
+ /* Clear error flags in the memory-base limit reg. */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ /* Clear Discard Timer Expired flag in Interrupt/Bridge Control reg */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ if (val32 & PCI_INTBRG_CTRL_CLEAR_MASK)
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+
+ /* Last enable error detections */
+ if (edac_op_state == EDAC_OPSTATE_POLL) {
+ /* Enable System Error reporting in global status register */
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ val32 |= PCI_STSCMD_SERREN;
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ /* Enable CRC Sync flood packets to HyperTransport Link */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ val32 |= HT_LINK_CRCFEN;
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ /* Enable SSE reporting etc in Interrupt control reg */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ val32 |= PCI_INTBRG_CTRL_POLL_MASK;
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+ }
+}
+
+static void amd8111_pci_bridge_exit(struct amd8111_pci_info *pci_info)
+{
+ u32 val32;
+ struct pci_dev *dev = pci_info->dev;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL) {
+ /* Disable System Error reporting */
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ val32 &= ~PCI_STSCMD_SERREN;
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ /* Disable CRC flood packets */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ val32 &= ~HT_LINK_CRCFEN;
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ /* Disable DTSERREN/MARSP/SERREN in Interrupt Control reg */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ val32 &= ~PCI_INTBRG_CTRL_POLL_MASK;
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+ }
+}
+
+static void amd8111_pci_bridge_check(struct edac_pci_ctl_info *edac_dev)
+{
+ struct amd8111_pci_info *pci_info = edac_dev->pvt_info;
+ struct pci_dev *dev = pci_info->dev;
+ u32 val32;
+
+ /* Check out PCI Bridge Status and Command Register */
+ edac_pci_read_dword(dev, REG_PCI_STSCMD, &val32);
+ if (val32 & PCI_STSCMD_CLEAR_MASK) {
+ printk(KERN_INFO "Error(s) in PCI bridge status and command"
+ "register on device %s\n", pci_info->ctl_name);
+ printk(KERN_INFO "SSE: %d, RMA: %d, RTA: %d\n",
+ (val32 & PCI_STSCMD_SSE) != 0,
+ (val32 & PCI_STSCMD_RMA) != 0,
+ (val32 & PCI_STSCMD_RTA) != 0);
+
+ val32 |= PCI_STSCMD_CLEAR_MASK;
+ edac_pci_write_dword(dev, REG_PCI_STSCMD, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check out HyperTransport Link Control Register */
+ edac_pci_read_dword(dev, REG_HT_LINK, &val32);
+ if (val32 & HT_LINK_LKFAIL) {
+ printk(KERN_INFO "Error(s) in hypertransport link control"
+ "register on device %s\n", pci_info->ctl_name);
+ printk(KERN_INFO "LKFAIL: %d\n",
+ (val32 & HT_LINK_LKFAIL) != 0);
+
+ val32 |= HT_LINK_LKFAIL;
+ edac_pci_write_dword(dev, REG_HT_LINK, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check out PCI Interrupt and Bridge Control Register */
+ edac_pci_read_dword(dev, REG_PCI_INTBRG_CTRL, &val32);
+ if (val32 & PCI_INTBRG_CTRL_DTSTAT) {
+ printk(KERN_INFO "Error(s) in PCI interrupt and bridge control"
+ "register on device %s\n", pci_info->ctl_name);
+ printk(KERN_INFO "DTSTAT: %d\n",
+ (val32 & PCI_INTBRG_CTRL_DTSTAT) != 0);
+
+ val32 |= PCI_INTBRG_CTRL_DTSTAT;
+ edac_pci_write_dword(dev, REG_PCI_INTBRG_CTRL, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check out PCI Bridge Memory Base-Limit Register */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_CLEAR_MASK) {
+ printk(KERN_INFO
+ "Error(s) in mem limit register on %s device\n",
+ pci_info->ctl_name);
+ printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
+ "RTA: %d, STA: %d, MDPE: %d\n",
+ (val32 & MEM_LIMIT_DPE) != 0,
+ (val32 & MEM_LIMIT_RSE) != 0,
+ (val32 & MEM_LIMIT_RMA) != 0,
+ (val32 & MEM_LIMIT_RTA) != 0,
+ (val32 & MEM_LIMIT_STA) != 0,
+ (val32 & MEM_LIMIT_MDPE) != 0);
+
+ val32 |= MEM_LIMIT_CLEAR_MASK;
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+}
+
+static struct resource *legacy_io_res;
+static int at_compat_reg_broken;
+#define LEGACY_NR_PORTS 1
+
+/* device-specific methods for amd8111 LPC Bridge device */
+static void amd8111_lpc_bridge_init(struct amd8111_dev_info *dev_info)
+{
+ u8 val8;
+ struct pci_dev *dev = dev_info->dev;
+
+ /* First clear REG_AT_COMPAT[SERR, IOCHK] if necessary */
+ legacy_io_res = request_region(REG_AT_COMPAT, LEGACY_NR_PORTS,
+ AMD8111_EDAC_MOD_STR);
+ if (!legacy_io_res)
+ printk(KERN_INFO "%s: failed to request legacy I/O region "
+ "start %d, len %d\n", __func__,
+ REG_AT_COMPAT, LEGACY_NR_PORTS);
+ else {
+ val8 = __do_inb(REG_AT_COMPAT);
+ if (val8 == 0xff) { /* buggy port */
+ printk(KERN_INFO "%s: port %d is buggy, not supported"
+ " by hardware?\n", __func__, REG_AT_COMPAT);
+ at_compat_reg_broken = 1;
+ release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
+ legacy_io_res = NULL;
+ } else {
+ u8 out8 = 0;
+ if (val8 & AT_COMPAT_SERR)
+ out8 = AT_COMPAT_CLRSERR;
+ if (val8 & AT_COMPAT_IOCHK)
+ out8 |= AT_COMPAT_CLRIOCHK;
+ if (out8 > 0)
+ __do_outb(out8, REG_AT_COMPAT);
+ }
+ }
+
+ /* Second clear error flags on LPC bridge */
+ edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
+ if (val8 & IO_CTRL_1_CLEAR_MASK)
+ edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
+}
+
+static void amd8111_lpc_bridge_exit(struct amd8111_dev_info *dev_info)
+{
+ if (legacy_io_res)
+ release_region(REG_AT_COMPAT, LEGACY_NR_PORTS);
+}
+
+static void amd8111_lpc_bridge_check(struct edac_device_ctl_info *edac_dev)
+{
+ struct amd8111_dev_info *dev_info = edac_dev->pvt_info;
+ struct pci_dev *dev = dev_info->dev;
+ u8 val8;
+
+ edac_pci_read_byte(dev, REG_IO_CTRL_1, &val8);
+ if (val8 & IO_CTRL_1_CLEAR_MASK) {
+ printk(KERN_INFO
+ "Error(s) in IO control register on %s device\n",
+ dev_info->ctl_name);
+ printk(KERN_INFO "LPC ERR: %d, PW2LPC: %d\n",
+ (val8 & IO_CTRL_1_LPC_ERR) != 0,
+ (val8 & IO_CTRL_1_PW2LPC) != 0);
+
+ val8 |= IO_CTRL_1_CLEAR_MASK;
+ edac_pci_write_byte(dev, REG_IO_CTRL_1, val8);
+
+ edac_device_handle_ue(edac_dev, 0, 0, edac_dev->ctl_name);
+ }
+
+ if (at_compat_reg_broken == 0) {
+ u8 out8 = 0;
+ val8 = __do_inb(REG_AT_COMPAT);
+ if (val8 & AT_COMPAT_SERR)
+ out8 = AT_COMPAT_CLRSERR;
+ if (val8 & AT_COMPAT_IOCHK)
+ out8 |= AT_COMPAT_CLRIOCHK;
+ if (out8 > 0) {
+ __do_outb(out8, REG_AT_COMPAT);
+ edac_device_handle_ue(edac_dev, 0, 0,
+ edac_dev->ctl_name);
+ }
+ }
+}
+
+/* General devices represented by edac_device_ctl_info */
+static struct amd8111_dev_info amd8111_devices[] = {
+ [LPC_BRIDGE] = {
+ .err_dev = PCI_DEVICE_ID_AMD_8111_LPC,
+ .ctl_name = "lpc",
+ .init = amd8111_lpc_bridge_init,
+ .exit = amd8111_lpc_bridge_exit,
+ .check = amd8111_lpc_bridge_check,
+ },
+ {0},
+};
+
+/* PCI controllers represented by edac_pci_ctl_info */
+static struct amd8111_pci_info amd8111_pcis[] = {
+ [PCI_BRIDGE] = {
+ .err_dev = PCI_DEVICE_ID_AMD_8111_PCI,
+ .ctl_name = "AMD8111_PCI_Controller",
+ .init = amd8111_pci_bridge_init,
+ .exit = amd8111_pci_bridge_exit,
+ .check = amd8111_pci_bridge_check,
+ },
+ {0},
+};
+
+static int amd8111_dev_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct amd8111_dev_info *dev_info = &amd8111_devices[id->driver_data];
+
+ dev_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ dev_info->err_dev, NULL);
+
+ if (!dev_info->dev) {
+ printk(KERN_ERR "EDAC device not found:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, dev_info->err_dev,
+ dev_info->ctl_name);
+ return -ENODEV;
+ }
+
+ if (pci_enable_device(dev_info->dev)) {
+ pci_dev_put(dev_info->dev);
+ printk(KERN_ERR "failed to enable:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, dev_info->err_dev,
+ dev_info->ctl_name);
+ return -ENODEV;
+ }
+
+ /*
+ * we do not allocate extra private structure for
+ * edac_device_ctl_info, but make use of existing
+ * one instead.
+ */
+ dev_info->edac_idx = edac_dev_idx++;
+ dev_info->edac_dev =
+ edac_device_alloc_ctl_info(0, dev_info->ctl_name, 1,
+ NULL, 0, 0,
+ NULL, 0, dev_info->edac_idx);
+ if (!dev_info->edac_dev)
+ return -ENOMEM;
+
+ dev_info->edac_dev->pvt_info = dev_info;
+ dev_info->edac_dev->dev = &dev_info->dev->dev;
+ dev_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
+ dev_info->edac_dev->ctl_name = dev_info->ctl_name;
+ dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ dev_info->edac_dev->edac_check = dev_info->check;
+
+ if (dev_info->init)
+ dev_info->init(dev_info);
+
+ if (edac_device_add_device(dev_info->edac_dev) > 0) {
+ printk(KERN_ERR "failed to add edac_dev for %s\n",
+ dev_info->ctl_name);
+ edac_device_free_ctl_info(dev_info->edac_dev);
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "added one edac_dev on AMD8111 "
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, dev_info->err_dev,
+ dev_info->ctl_name);
+
+ return 0;
+}
+
+static void amd8111_dev_remove(struct pci_dev *dev)
+{
+ struct amd8111_dev_info *dev_info;
+
+ for (dev_info = amd8111_devices; dev_info->err_dev; dev_info++)
+ if (dev_info->dev->device == dev->device)
+ break;
+
+ if (!dev_info->err_dev) /* should never happen */
+ return;
+
+ if (dev_info->edac_dev) {
+ edac_device_del_device(dev_info->edac_dev->dev);
+ edac_device_free_ctl_info(dev_info->edac_dev);
+ }
+
+ if (dev_info->exit)
+ dev_info->exit(dev_info);
+
+ pci_dev_put(dev_info->dev);
+}
+
+static int amd8111_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct amd8111_pci_info *pci_info = &amd8111_pcis[id->driver_data];
+
+ pci_info->dev = pci_get_device(PCI_VENDOR_ID_AMD,
+ pci_info->err_dev, NULL);
+
+ if (!pci_info->dev) {
+ printk(KERN_ERR "EDAC device not found:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, pci_info->err_dev,
+ pci_info->ctl_name);
+ return -ENODEV;
+ }
+
+ if (pci_enable_device(pci_info->dev)) {
+ pci_dev_put(pci_info->dev);
+ printk(KERN_ERR "failed to enable:"
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, pci_info->err_dev,
+ pci_info->ctl_name);
+ return -ENODEV;
+ }
+
+ /*
+ * we do not allocate extra private structure for
+ * edac_pci_ctl_info, but make use of existing
+ * one instead.
+ */
+ pci_info->edac_idx = edac_pci_alloc_index();
+ pci_info->edac_dev = edac_pci_alloc_ctl_info(0, pci_info->ctl_name);
+ if (!pci_info->edac_dev)
+ return -ENOMEM;
+
+ pci_info->edac_dev->pvt_info = pci_info;
+ pci_info->edac_dev->dev = &pci_info->dev->dev;
+ pci_info->edac_dev->mod_name = AMD8111_EDAC_MOD_STR;
+ pci_info->edac_dev->ctl_name = pci_info->ctl_name;
+ pci_info->edac_dev->dev_name = pci_info->dev->dev.bus_id;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ pci_info->edac_dev->edac_check = pci_info->check;
+
+ if (pci_info->init)
+ pci_info->init(pci_info);
+
+ if (edac_pci_add_device(pci_info->edac_dev, pci_info->edac_idx) > 0) {
+ printk(KERN_ERR "failed to add edac_pci for %s\n",
+ pci_info->ctl_name);
+ edac_pci_free_ctl_info(pci_info->edac_dev);
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "added one edac_pci on AMD8111 "
+ "vendor %x, device %x, name %s\n",
+ PCI_VENDOR_ID_AMD, pci_info->err_dev,
+ pci_info->ctl_name);
+
+ return 0;
+}
+
+static void amd8111_pci_remove(struct pci_dev *dev)
+{
+ struct amd8111_pci_info *pci_info;
+
+ for (pci_info = amd8111_pcis; pci_info->err_dev; pci_info++)
+ if (pci_info->dev->device == dev->device)
+ break;
+
+ if (!pci_info->err_dev) /* should never happen */
+ return;
+
+ if (pci_info->edac_dev) {
+ edac_pci_del_device(pci_info->edac_dev->dev);
+ edac_pci_free_ctl_info(pci_info->edac_dev);
+ }
+
+ if (pci_info->exit)
+ pci_info->exit(pci_info);
+
+ pci_dev_put(pci_info->dev);
+}
+
+/* PCI Device ID talbe for general EDAC device */
+static const struct pci_device_id amd8111_edac_dev_tbl[] = {
+ {
+ PCI_VEND_DEV(AMD, 8111_LPC),
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = 0,
+ .class_mask = 0,
+ .driver_data = LPC_BRIDGE,
+ },
+ {
+ 0,
+ } /* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8111_edac_dev_tbl);
+
+static struct pci_driver amd8111_edac_dev_driver = {
+ .name = "AMD8111_EDAC_DEV",
+ .probe = amd8111_dev_probe,
+ .remove = amd8111_dev_remove,
+ .id_table = amd8111_edac_dev_tbl,
+};
+
+/* PCI Device ID table for EDAC PCI controller */
+static const struct pci_device_id amd8111_edac_pci_tbl[] = {
+ {
+ PCI_VEND_DEV(AMD, 8111_PCI),
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = 0,
+ .class_mask = 0,
+ .driver_data = PCI_BRIDGE,
+ },
+ {
+ 0,
+ } /* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8111_edac_pci_tbl);
+
+static struct pci_driver amd8111_edac_pci_driver = {
+ .name = "AMD8111_EDAC_PCI",
+ .probe = amd8111_pci_probe,
+ .remove = amd8111_pci_remove,
+ .id_table = amd8111_edac_pci_tbl,
+};
+
+static int __init amd8111_edac_init(void)
+{
+ int val;
+
+ printk(KERN_INFO "AMD8111 EDAC driver " AMD8111_EDAC_REVISION "\n");
+ printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
+
+ /* Only POLL mode supported so far */
+ edac_op_state = EDAC_OPSTATE_POLL;
+
+ val = pci_register_driver(&amd8111_edac_dev_driver);
+ val |= pci_register_driver(&amd8111_edac_pci_driver);
+
+ return val;
+}
+
+static void __exit amd8111_edac_exit(void)
+{
+ pci_unregister_driver(&amd8111_edac_pci_driver);
+ pci_unregister_driver(&amd8111_edac_dev_driver);
+}
+
+
+module_init(amd8111_edac_init);
+module_exit(amd8111_edac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
+MODULE_DESCRIPTION("AMD8111 HyperTransport I/O Hub EDAC kernel module");
diff --git a/drivers/edac/amd8111_edac.h b/drivers/edac/amd8111_edac.h
new file mode 100644
index 00000000000..35794331deb
--- /dev/null
+++ b/drivers/edac/amd8111_edac.h
@@ -0,0 +1,130 @@
+/*
+ * amd8111_edac.h, EDAC defs for AMD8111 hypertransport chip
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _AMD8111_EDAC_H_
+#define _AMD8111_EDAC_H_
+
+/************************************************************
+ * PCI Bridge Status and Command Register, DevA:0x04
+ ************************************************************/
+#define REG_PCI_STSCMD 0x04
+enum pci_stscmd_bits {
+ PCI_STSCMD_SSE = BIT(30),
+ PCI_STSCMD_RMA = BIT(29),
+ PCI_STSCMD_RTA = BIT(28),
+ PCI_STSCMD_SERREN = BIT(8),
+ PCI_STSCMD_CLEAR_MASK = (PCI_STSCMD_SSE |
+ PCI_STSCMD_RMA |
+ PCI_STSCMD_RTA)
+};
+
+/************************************************************
+ * PCI Bridge Memory Base-Limit Register, DevA:0x1c
+ ************************************************************/
+#define REG_MEM_LIM 0x1c
+enum mem_limit_bits {
+ MEM_LIMIT_DPE = BIT(31),
+ MEM_LIMIT_RSE = BIT(30),
+ MEM_LIMIT_RMA = BIT(29),
+ MEM_LIMIT_RTA = BIT(28),
+ MEM_LIMIT_STA = BIT(27),
+ MEM_LIMIT_MDPE = BIT(24),
+ MEM_LIMIT_CLEAR_MASK = (MEM_LIMIT_DPE |
+ MEM_LIMIT_RSE |
+ MEM_LIMIT_RMA |
+ MEM_LIMIT_RTA |
+ MEM_LIMIT_STA |
+ MEM_LIMIT_MDPE)
+};
+
+/************************************************************
+ * HyperTransport Link Control Register, DevA:0xc4
+ ************************************************************/
+#define REG_HT_LINK 0xc4
+enum ht_link_bits {
+ HT_LINK_LKFAIL = BIT(4),
+ HT_LINK_CRCFEN = BIT(1),
+ HT_LINK_CLEAR_MASK = (HT_LINK_LKFAIL)
+};
+
+/************************************************************
+ * PCI Bridge Interrupt and Bridge Control, DevA:0x3c
+ ************************************************************/
+#define REG_PCI_INTBRG_CTRL 0x3c
+enum pci_intbrg_ctrl_bits {
+ PCI_INTBRG_CTRL_DTSERREN = BIT(27),
+ PCI_INTBRG_CTRL_DTSTAT = BIT(26),
+ PCI_INTBRG_CTRL_MARSP = BIT(21),
+ PCI_INTBRG_CTRL_SERREN = BIT(17),
+ PCI_INTBRG_CTRL_PEREN = BIT(16),
+ PCI_INTBRG_CTRL_CLEAR_MASK = (PCI_INTBRG_CTRL_DTSTAT),
+ PCI_INTBRG_CTRL_POLL_MASK = (PCI_INTBRG_CTRL_DTSERREN |
+ PCI_INTBRG_CTRL_MARSP |
+ PCI_INTBRG_CTRL_SERREN)
+};
+
+/************************************************************
+ * I/O Control 1 Register, DevB:0x40
+ ************************************************************/
+#define REG_IO_CTRL_1 0x40
+enum io_ctrl_1_bits {
+ IO_CTRL_1_NMIONERR = BIT(7),
+ IO_CTRL_1_LPC_ERR = BIT(6),
+ IO_CTRL_1_PW2LPC = BIT(1),
+ IO_CTRL_1_CLEAR_MASK = (IO_CTRL_1_LPC_ERR | IO_CTRL_1_PW2LPC)
+};
+
+/************************************************************
+ * Legacy I/O Space Registers
+ ************************************************************/
+#define REG_AT_COMPAT 0x61
+enum at_compat_bits {
+ AT_COMPAT_SERR = BIT(7),
+ AT_COMPAT_IOCHK = BIT(6),
+ AT_COMPAT_CLRIOCHK = BIT(3),
+ AT_COMPAT_CLRSERR = BIT(2),
+};
+
+struct amd8111_dev_info {
+ u16 err_dev; /* PCI Device ID */
+ struct pci_dev *dev;
+ int edac_idx; /* device index */
+ char *ctl_name;
+ struct edac_device_ctl_info *edac_dev;
+ void (*init)(struct amd8111_dev_info *dev_info);
+ void (*exit)(struct amd8111_dev_info *dev_info);
+ void (*check)(struct edac_device_ctl_info *edac_dev);
+};
+
+struct amd8111_pci_info {
+ u16 err_dev; /* PCI Device ID */
+ struct pci_dev *dev;
+ int edac_idx; /* pci index */
+ const char *ctl_name;
+ struct edac_pci_ctl_info *edac_dev;
+ void (*init)(struct amd8111_pci_info *dev_info);
+ void (*exit)(struct amd8111_pci_info *dev_info);
+ void (*check)(struct edac_pci_ctl_info *edac_dev);
+};
+
+#endif /* _AMD8111_EDAC_H_ */
diff --git a/drivers/edac/amd8131_edac.c b/drivers/edac/amd8131_edac.c
new file mode 100644
index 00000000000..c083b31cac5
--- /dev/null
+++ b/drivers/edac/amd8131_edac.c
@@ -0,0 +1,379 @@
+/*
+ * amd8131_edac.c, AMD8131 hypertransport chip EDAC kernel module
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+#include <linux/edac.h>
+#include <linux/pci_ids.h>
+
+#include "edac_core.h"
+#include "edac_module.h"
+#include "amd8131_edac.h"
+
+#define AMD8131_EDAC_REVISION " Ver: 1.0.0 " __DATE__
+#define AMD8131_EDAC_MOD_STR "amd8131_edac"
+
+/* Wrapper functions for accessing PCI configuration space */
+static void edac_pci_read_dword(struct pci_dev *dev, int reg, u32 *val32)
+{
+ int ret;
+
+ ret = pci_read_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8131_EDAC_MOD_STR
+ " PCI Access Read Error at 0x%x\n", reg);
+}
+
+static void edac_pci_write_dword(struct pci_dev *dev, int reg, u32 val32)
+{
+ int ret;
+
+ ret = pci_write_config_dword(dev, reg, val32);
+ if (ret != 0)
+ printk(KERN_ERR AMD8131_EDAC_MOD_STR
+ " PCI Access Write Error at 0x%x\n", reg);
+}
+
+static char * const bridge_str[] = {
+ [NORTH_A] = "NORTH A",
+ [NORTH_B] = "NORTH B",
+ [SOUTH_A] = "SOUTH A",
+ [SOUTH_B] = "SOUTH B",
+ [NO_BRIDGE] = "NO BRIDGE",
+};
+
+/* Support up to two AMD8131 chipsets on a platform */
+static struct amd8131_dev_info amd8131_devices[] = {
+ {
+ .inst = NORTH_A,
+ .devfn = DEVFN_PCIX_BRIDGE_NORTH_A,
+ .ctl_name = "AMD8131_PCIX_NORTH_A",
+ },
+ {
+ .inst = NORTH_B,
+ .devfn = DEVFN_PCIX_BRIDGE_NORTH_B,
+ .ctl_name = "AMD8131_PCIX_NORTH_B",
+ },
+ {
+ .inst = SOUTH_A,
+ .devfn = DEVFN_PCIX_BRIDGE_SOUTH_A,
+ .ctl_name = "AMD8131_PCIX_SOUTH_A",
+ },
+ {
+ .inst = SOUTH_B,
+ .devfn = DEVFN_PCIX_BRIDGE_SOUTH_B,
+ .ctl_name = "AMD8131_PCIX_SOUTH_B",
+ },
+ {.inst = NO_BRIDGE,},
+};
+
+static void amd8131_pcix_init(struct amd8131_dev_info *dev_info)
+{
+ u32 val32;
+ struct pci_dev *dev = dev_info->dev;
+
+ /* First clear error detection flags */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_MASK)
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ /* Clear Discard Timer Timedout flag */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ if (val32 & INT_CTLR_DTS)
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ /* Clear CRC Error flag on link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ if (val32 & LNK_CTRL_CRCERR_A)
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ /* Clear CRC Error flag on link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ if (val32 & LNK_CTRL_CRCERR_B)
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+
+ /*
+ * Then enable all error detections.
+ *
+ * Setup Discard Timer Sync Flood Enable,
+ * System Error Enable and Parity Error Enable.
+ */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ val32 |= INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE;
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ /* Enable overall SERR Error detection */
+ edac_pci_read_dword(dev, REG_STS_CMD, &val32);
+ val32 |= STS_CMD_SERREN;
+ edac_pci_write_dword(dev, REG_STS_CMD, val32);
+
+ /* Setup CRC Flood Enable for link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ val32 |= LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ /* Setup CRC Flood Enable for link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ val32 |= LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+}
+
+static void amd8131_pcix_exit(struct amd8131_dev_info *dev_info)
+{
+ u32 val32;
+ struct pci_dev *dev = dev_info->dev;
+
+ /* Disable SERR, PERR and DTSE Error detection */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ val32 &= ~(INT_CTLR_PERR | INT_CTLR_SERR | INT_CTLR_DTSE);
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ /* Disable overall System Error detection */
+ edac_pci_read_dword(dev, REG_STS_CMD, &val32);
+ val32 &= ~STS_CMD_SERREN;
+ edac_pci_write_dword(dev, REG_STS_CMD, val32);
+
+ /* Disable CRC Sync Flood on link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ val32 &= ~LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ /* Disable CRC Sync Flood on link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ val32 &= ~LNK_CTRL_CRCFEN;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+}
+
+static void amd8131_pcix_check(struct edac_pci_ctl_info *edac_dev)
+{
+ struct amd8131_dev_info *dev_info = edac_dev->pvt_info;
+ struct pci_dev *dev = dev_info->dev;
+ u32 val32;
+
+ /* Check PCI-X Bridge Memory Base-Limit Register for errors */
+ edac_pci_read_dword(dev, REG_MEM_LIM, &val32);
+ if (val32 & MEM_LIMIT_MASK) {
+ printk(KERN_INFO "Error(s) in mem limit register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "DPE: %d, RSE: %d, RMA: %d\n"
+ "RTA: %d, STA: %d, MDPE: %d\n",
+ val32 & MEM_LIMIT_DPE,
+ val32 & MEM_LIMIT_RSE,
+ val32 & MEM_LIMIT_RMA,
+ val32 & MEM_LIMIT_RTA,
+ val32 & MEM_LIMIT_STA,
+ val32 & MEM_LIMIT_MDPE);
+
+ val32 |= MEM_LIMIT_MASK;
+ edac_pci_write_dword(dev, REG_MEM_LIM, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check if Discard Timer timed out */
+ edac_pci_read_dword(dev, REG_INT_CTLR, &val32);
+ if (val32 & INT_CTLR_DTS) {
+ printk(KERN_INFO "Error(s) in interrupt and control register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "DTS: %d\n", val32 & INT_CTLR_DTS);
+
+ val32 |= INT_CTLR_DTS;
+ edac_pci_write_dword(dev, REG_INT_CTLR, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check if CRC error happens on link side A */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_A, &val32);
+ if (val32 & LNK_CTRL_CRCERR_A) {
+ printk(KERN_INFO "Error(s) in link conf and control register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_A);
+
+ val32 |= LNK_CTRL_CRCERR_A;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_A, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+
+ /* Check if CRC error happens on link side B */
+ edac_pci_read_dword(dev, REG_LNK_CTRL_B, &val32);
+ if (val32 & LNK_CTRL_CRCERR_B) {
+ printk(KERN_INFO "Error(s) in link conf and control register "
+ "on %s bridge\n", dev_info->ctl_name);
+ printk(KERN_INFO "CRCERR: %d\n", val32 & LNK_CTRL_CRCERR_B);
+
+ val32 |= LNK_CTRL_CRCERR_B;
+ edac_pci_write_dword(dev, REG_LNK_CTRL_B, val32);
+
+ edac_pci_handle_npe(edac_dev, edac_dev->ctl_name);
+ }
+}
+
+static struct amd8131_info amd8131_chipset = {
+ .err_dev = PCI_DEVICE_ID_AMD_8131_APIC,
+ .devices = amd8131_devices,
+ .init = amd8131_pcix_init,
+ .exit = amd8131_pcix_exit,
+ .check = amd8131_pcix_check,
+};
+
+/*
+ * There are 4 PCIX Bridges on ATCA-6101 that share the same PCI Device ID,
+ * so amd8131_probe() would be called by kernel 4 times, with different
+ * address of pci_dev for each of them each time.
+ */
+static int amd8131_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ struct amd8131_dev_info *dev_info;
+
+ for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
+ dev_info++)
+ if (dev_info->devfn == dev->devfn)
+ break;
+
+ if (dev_info->inst == NO_BRIDGE) /* should never happen */
+ return -ENODEV;
+
+ /*
+ * We can't call pci_get_device() as we are used to do because
+ * there are 4 of them but pci_dev_get() instead.
+ */
+ dev_info->dev = pci_dev_get(dev);
+
+ if (pci_enable_device(dev_info->dev)) {
+ pci_dev_put(dev_info->dev);
+ printk(KERN_ERR "failed to enable:"
+ "vendor %x, device %x, devfn %x, name %s\n",
+ PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
+ dev_info->devfn, dev_info->ctl_name);
+ return -ENODEV;
+ }
+
+ /*
+ * we do not allocate extra private structure for
+ * edac_pci_ctl_info, but make use of existing
+ * one instead.
+ */
+ dev_info->edac_idx = edac_pci_alloc_index();
+ dev_info->edac_dev = edac_pci_alloc_ctl_info(0, dev_info->ctl_name);
+ if (!dev_info->edac_dev)
+ return -ENOMEM;
+
+ dev_info->edac_dev->pvt_info = dev_info;
+ dev_info->edac_dev->dev = &dev_info->dev->dev;
+ dev_info->edac_dev->mod_name = AMD8131_EDAC_MOD_STR;
+ dev_info->edac_dev->ctl_name = dev_info->ctl_name;
+ dev_info->edac_dev->dev_name = dev_info->dev->dev.bus_id;
+
+ if (edac_op_state == EDAC_OPSTATE_POLL)
+ dev_info->edac_dev->edac_check = amd8131_chipset.check;
+
+ if (amd8131_chipset.init)
+ amd8131_chipset.init(dev_info);
+
+ if (edac_pci_add_device(dev_info->edac_dev, dev_info->edac_idx) > 0) {
+ printk(KERN_ERR "failed edac_pci_add_device() for %s\n",
+ dev_info->ctl_name);
+ edac_pci_free_ctl_info(dev_info->edac_dev);
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "added one device on AMD8131 "
+ "vendor %x, device %x, devfn %x, name %s\n",
+ PCI_VENDOR_ID_AMD, amd8131_chipset.err_dev,
+ dev_info->devfn, dev_info->ctl_name);
+
+ return 0;
+}
+
+static void amd8131_remove(struct pci_dev *dev)
+{
+ struct amd8131_dev_info *dev_info;
+
+ for (dev_info = amd8131_chipset.devices; dev_info->inst != NO_BRIDGE;
+ dev_info++)
+ if (dev_info->devfn == dev->devfn)
+ break;
+
+ if (dev_info->inst == NO_BRIDGE) /* should never happen */
+ return;
+
+ if (dev_info->edac_dev) {
+ edac_pci_del_device(dev_info->edac_dev->dev);
+ edac_pci_free_ctl_info(dev_info->edac_dev);
+ }
+
+ if (amd8131_chipset.exit)
+ amd8131_chipset.exit(dev_info);
+
+ pci_dev_put(dev_info->dev);
+}
+
+static const struct pci_device_id amd8131_edac_pci_tbl[] = {
+ {
+ PCI_VEND_DEV(AMD, 8131_BRIDGE),
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .class = 0,
+ .class_mask = 0,
+ .driver_data = 0,
+ },
+ {
+ 0,
+ } /* table is NULL-terminated */
+};
+MODULE_DEVICE_TABLE(pci, amd8131_edac_pci_tbl);
+
+static struct pci_driver amd8131_edac_driver = {
+ .name = AMD8131_EDAC_MOD_STR,
+ .probe = amd8131_probe,
+ .remove = amd8131_remove,
+ .id_table = amd8131_edac_pci_tbl,
+};
+
+static int __init amd8131_edac_init(void)
+{
+ printk(KERN_INFO "AMD8131 EDAC driver " AMD8131_EDAC_REVISION "\n");
+ printk(KERN_INFO "\t(c) 2008 Wind River Systems, Inc.\n");
+
+ /* Only POLL mode supported so far */
+ edac_op_state = EDAC_OPSTATE_POLL;
+
+ return pci_register_driver(&amd8131_edac_driver);
+}
+
+static void __exit amd8131_edac_exit(void)
+{
+ pci_unregister_driver(&amd8131_edac_driver);
+}
+
+module_init(amd8131_edac_init);
+module_exit(amd8131_edac_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Cao Qingtao <qingtao.cao@windriver.com>\n");
+MODULE_DESCRIPTION("AMD8131 HyperTransport PCI-X Tunnel EDAC kernel module");
diff --git a/drivers/edac/amd8131_edac.h b/drivers/edac/amd8131_edac.h
new file mode 100644
index 00000000000..60e0d1c72de
--- /dev/null
+++ b/drivers/edac/amd8131_edac.h
@@ -0,0 +1,119 @@
+/*
+ * amd8131_edac.h, EDAC defs for AMD8131 hypertransport chip
+ *
+ * Copyright (c) 2008 Wind River Systems, Inc.
+ *
+ * Authors: Cao Qingtao <qingtao.cao@windriver.com>
+ * Benjamin Walsh <benjamin.walsh@windriver.com>
+ * Hu Yongqi <yongqi.hu@windriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _AMD8131_EDAC_H_
+#define _AMD8131_EDAC_H_
+
+#define DEVFN_PCIX_BRIDGE_NORTH_A 8
+#define DEVFN_PCIX_BRIDGE_NORTH_B 16
+#define DEVFN_PCIX_BRIDGE_SOUTH_A 24
+#define DEVFN_PCIX_BRIDGE_SOUTH_B 32
+
+/************************************************************
+ * PCI-X Bridge Status and Command Register, DevA:0x04
+ ************************************************************/
+#define REG_STS_CMD 0x04
+enum sts_cmd_bits {
+ STS_CMD_SSE = BIT(30),
+ STS_CMD_SERREN = BIT(8)
+};
+
+/************************************************************
+ * PCI-X Bridge Interrupt and Bridge Control Register,
+ ************************************************************/
+#define REG_INT_CTLR 0x3c
+enum int_ctlr_bits {
+ INT_CTLR_DTSE = BIT(27),
+ INT_CTLR_DTS = BIT(26),
+ INT_CTLR_SERR = BIT(17),
+ INT_CTLR_PERR = BIT(16)
+};
+
+/************************************************************
+ * PCI-X Bridge Memory Base-Limit Register, DevA:0x1C
+ ************************************************************/
+#define REG_MEM_LIM 0x1c
+enum mem_limit_bits {
+ MEM_LIMIT_DPE = BIT(31),
+ MEM_LIMIT_RSE = BIT(30),
+ MEM_LIMIT_RMA = BIT(29),
+ MEM_LIMIT_RTA = BIT(28),
+ MEM_LIMIT_STA = BIT(27),
+ MEM_LIMIT_MDPE = BIT(24),
+ MEM_LIMIT_MASK = MEM_LIMIT_DPE|MEM_LIMIT_RSE|MEM_LIMIT_RMA|
+ MEM_LIMIT_RTA|MEM_LIMIT_STA|MEM_LIMIT_MDPE
+};
+
+/************************************************************
+ * Link Configuration And Control Register, side A
+ ************************************************************/
+#define REG_LNK_CTRL_A 0xc4
+
+/************************************************************
+ * Link Configuration And Control Register, side B
+ ************************************************************/
+#define REG_LNK_CTRL_B 0xc8
+
+enum lnk_ctrl_bits {
+ LNK_CTRL_CRCERR_A = BIT(9),
+ LNK_CTRL_CRCERR_B = BIT(8),
+ LNK_CTRL_CRCFEN = BIT(1)
+};
+
+enum pcix_bridge_inst {
+ NORTH_A = 0,
+ NORTH_B = 1,
+ SOUTH_A = 2,
+ SOUTH_B = 3,
+ NO_BRIDGE = 4
+};
+
+struct amd8131_dev_info {
+ int devfn;
+ enum pcix_bridge_inst inst;
+ struct pci_dev *dev;
+ int edac_idx; /* pci device index */
+ char *ctl_name;
+ struct edac_pci_ctl_info *edac_dev;
+};
+
+/*
+ * AMD8131 chipset has two pairs of PCIX Bridge and related IOAPIC
+ * Controler, and ATCA-6101 has two AMD8131 chipsets, so there are
+ * four PCIX Bridges on ATCA-6101 altogether.
+ *
+ * These PCIX Bridges share the same PCI Device ID and are all of
+ * Function Zero, they could be discrimated by their pci_dev->devfn.
+ * They share the same set of init/check/exit methods, and their
+ * private structures are collected in the devices[] array.
+ */
+struct amd8131_info {
+ u16 err_dev; /* PCI Device ID for AMD8131 APIC*/
+ struct amd8131_dev_info *devices;
+ void (*init)(struct amd8131_dev_info *dev_info);
+ void (*exit)(struct amd8131_dev_info *dev_info);
+ void (*check)(struct edac_pci_ctl_info *edac_dev);
+};
+
+#endif /* _AMD8131_EDAC_H_ */
+
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h
index 4b55ec607a8..28f2c3f959b 100644
--- a/drivers/edac/edac_core.h
+++ b/drivers/edac/edac_core.h
@@ -49,6 +49,10 @@
#define edac_printk(level, prefix, fmt, arg...) \
printk(level "EDAC " prefix ": " fmt, ##arg)
+#define edac_printk_verbose(level, prefix, fmt, arg...) \
+ printk(level "EDAC " prefix ": " "in %s, line at %d: " fmt, \
+ __FILE__, __LINE__, ##arg)
+
#define edac_mc_printk(mci, level, fmt, arg...) \
printk(level "EDAC MC%d: " fmt, mci->mc_idx, ##arg)
@@ -71,11 +75,20 @@
#ifdef CONFIG_EDAC_DEBUG
extern int edac_debug_level;
+#ifndef CONFIG_EDAC_DEBUG_VERBOSE
#define edac_debug_printk(level, fmt, arg...) \
do { \
if (level <= edac_debug_level) \
edac_printk(KERN_DEBUG, EDAC_DEBUG, fmt, ##arg); \
- } while(0)
+ } while (0)
+#else /* CONFIG_EDAC_DEBUG_VERBOSE */
+#define edac_debug_printk(level, fmt, arg...) \
+ do { \
+ if (level <= edac_debug_level) \
+ edac_printk_verbose(KERN_DEBUG, EDAC_DEBUG, fmt, \
+ ##arg); \
+ } while (0)
+#endif
#define debugf0( ... ) edac_debug_printk(0, __VA_ARGS__ )
#define debugf1( ... ) edac_debug_printk(1, __VA_ARGS__ )
@@ -831,6 +844,7 @@ extern void edac_pci_free_ctl_info(struct edac_pci_ctl_info *pci);
extern void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci,
unsigned long value);
+extern int edac_pci_alloc_index(void);
extern int edac_pci_add_device(struct edac_pci_ctl_info *pci, int edac_idx);
extern struct edac_pci_ctl_info *edac_pci_del_device(struct device *dev);
diff --git a/drivers/edac/edac_pci.c b/drivers/edac/edac_pci.c
index 5d3c8083a40..5b150aea703 100644
--- a/drivers/edac/edac_pci.c
+++ b/drivers/edac/edac_pci.c
@@ -30,6 +30,7 @@
static DEFINE_MUTEX(edac_pci_ctls_mutex);
static LIST_HEAD(edac_pci_list);
+static atomic_t pci_indexes = ATOMIC_INIT(0);
/*
* edac_pci_alloc_ctl_info
@@ -318,6 +319,19 @@ void edac_pci_reset_delay_period(struct edac_pci_ctl_info *pci,
EXPORT_SYMBOL_GPL(edac_pci_reset_delay_period);
/*
+ * edac_pci_alloc_index: Allocate a unique PCI index number
+ *
+ * Return:
+ * allocated index number
+ *
+ */
+int edac_pci_alloc_index(void)
+{
+ return atomic_inc_return(&pci_indexes) - 1;
+}
+EXPORT_SYMBOL_GPL(edac_pci_alloc_index);
+
+/*
* edac_pci_add_device: Insert the 'edac_dev' structure into the
* edac_pci global list and create sysfs entries associated with
* edac_pci structure.
diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c
new file mode 100644
index 00000000000..11f2172aa1e
--- /dev/null
+++ b/drivers/edac/ppc4xx_edac.c
@@ -0,0 +1,1448 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of the
+ * License.
+ *
+ */
+
+#include <linux/edac.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+#include <linux/types.h>
+
+#include <asm/dcr.h>
+
+#include "edac_core.h"
+#include "ppc4xx_edac.h"
+
+/*
+ * This file implements a driver for monitoring and handling events
+ * associated with the IMB DDR2 ECC controller found in the AMCC/IBM
+ * 405EX[r], 440SP, 440SPe, 460EX, 460GT and 460SX.
+ *
+ * As realized in the 405EX[r], this controller features:
+ *
+ * - Support for registered- and non-registered DDR1 and DDR2 memory.
+ * - 32-bit or 16-bit memory interface with optional ECC.
+ *
+ * o ECC support includes:
+ *
+ * - 4-bit SEC/DED
+ * - Aligned-nibble error detect
+ * - Bypass mode
+ *
+ * - Two (2) memory banks/ranks.
+ * - Up to 1 GiB per bank/rank in 32-bit mode and up to 512 MiB per
+ * bank/rank in 16-bit mode.
+ *
+ * As realized in the 440SP and 440SPe, this controller changes/adds:
+ *
+ * - 64-bit or 32-bit memory interface with optional ECC.
+ *
+ * o ECC support includes:
+ *
+ * - 8-bit SEC/DED
+ * - Aligned-nibble error detect
+ * - Bypass mode
+ *
+ * - Up to 4 GiB per bank/rank in 64-bit mode and up to 2 GiB
+ * per bank/rank in 32-bit mode.
+ *
+ * As realized in the 460EX and 460GT, this controller changes/adds:
+ *
+ * - 64-bit or 32-bit memory interface with optional ECC.
+ *
+ * o ECC support includes:
+ *
+ * - 8-bit SEC/DED
+ * - Aligned-nibble error detect
+ * - Bypass mode
+ *
+ * - Four (4) memory banks/ranks.
+ * - Up to 16 GiB per bank/rank in 64-bit mode and up to 8 GiB
+ * per bank/rank in 32-bit mode.
+ *
+ * At present, this driver has ONLY been tested against the controller
+ * realization in the 405EX[r] on the AMCC Kilauea and Haleakala
+ * boards (256 MiB w/o ECC memory soldered onto the board) and a
+ * proprietary board based on those designs (128 MiB ECC memory, also
+ * soldered onto the board).
+ *
+ * Dynamic feature detection and handling needs to be added for the
+ * other realizations of this controller listed above.
+ *
+ * Eventually, this driver will likely be adapted to the above variant
+ * realizations of this controller as well as broken apart to handle
+ * the other known ECC-capable controllers prevalent in other 4xx
+ * processors:
+ *
+ * - IBM SDRAM (405GP, 405CR and 405EP) "ibm,sdram-4xx"
+ * - IBM DDR1 (440GP, 440GX, 440EP and 440GR) "ibm,sdram-4xx-ddr"
+ * - Denali DDR1/DDR2 (440EPX and 440GRX) "denali,sdram-4xx-ddr2"
+ *
+ * For this controller, unfortunately, correctable errors report
+ * nothing more than the beat/cycle and byte/lane the correction
+ * occurred on and the check bit group that covered the error.
+ *
+ * In contrast, uncorrectable errors also report the failing address,
+ * the bus master and the transaction direction (i.e. read or write)
+ *
+ * Regardless of whether the error is a CE or a UE, we report the
+ * following pieces of information in the driver-unique message to the
+ * EDAC subsystem:
+ *
+ * - Device tree path
+ * - Bank(s)
+ * - Check bit error group
+ * - Beat(s)/lane(s)
+ */
+
+/* Preprocessor Definitions */
+
+#define EDAC_OPSTATE_INT_STR "interrupt"
+#define EDAC_OPSTATE_POLL_STR "polled"
+#define EDAC_OPSTATE_UNKNOWN_STR "unknown"
+
+#define PPC4XX_EDAC_MODULE_NAME "ppc4xx_edac"
+#define PPC4XX_EDAC_MODULE_REVISION "v1.0.0 " __DATE__
+
+#define PPC4XX_EDAC_MESSAGE_SIZE 256
+
+/*
+ * Kernel logging without an EDAC instance
+ */
+#define ppc4xx_edac_printk(level, fmt, arg...) \
+ edac_printk(level, "PPC4xx MC", fmt, ##arg)
+
+/*
+ * Kernel logging with an EDAC instance
+ */
+#define ppc4xx_edac_mc_printk(level, mci, fmt, arg...) \
+ edac_mc_chipset_printk(mci, level, "PPC4xx", fmt, ##arg)
+
+/*
+ * Macros to convert bank configuration size enumerations into MiB and
+ * page values.
+ */
+#define SDRAM_MBCF_SZ_MiB_MIN 4
+#define SDRAM_MBCF_SZ_TO_MiB(n) (SDRAM_MBCF_SZ_MiB_MIN \
+ << (SDRAM_MBCF_SZ_DECODE(n)))
+#define SDRAM_MBCF_SZ_TO_PAGES(n) (SDRAM_MBCF_SZ_MiB_MIN \
+ << (20 - PAGE_SHIFT + \
+ SDRAM_MBCF_SZ_DECODE(n)))
+
+/*
+ * The ibm,sdram-4xx-ddr2 Device Control Registers (DCRs) are
+ * indirectly acccessed and have a base and length defined by the
+ * device tree. The base can be anything; however, we expect the
+ * length to be precisely two registers, the first for the address
+ * window and the second for the data window.
+ */
+#define SDRAM_DCR_RESOURCE_LEN 2
+#define SDRAM_DCR_ADDR_OFFSET 0
+#define SDRAM_DCR_DATA_OFFSET 1
+
+/*
+ * Device tree interrupt indices
+ */
+#define INTMAP_ECCDED_INDEX 0 /* Double-bit Error Detect */
+#define INTMAP_ECCSEC_INDEX 1 /* Single-bit Error Correct */
+
+/* Type Definitions */
+
+/*
+ * PPC4xx SDRAM memory controller private instance data
+ */
+struct ppc4xx_edac_pdata {
+ dcr_host_t dcr_host; /* Indirect DCR address/data window mapping */
+ struct {
+ int sec; /* Single-bit correctable error IRQ assigned */
+ int ded; /* Double-bit detectable error IRQ assigned */
+ } irqs;
+};
+
+/*
+ * Various status data gathered and manipulated when checking and
+ * reporting ECC status.
+ */
+struct ppc4xx_ecc_status {
+ u32 ecces;
+ u32 besr;
+ u32 bearh;
+ u32 bearl;
+ u32 wmirq;
+};
+
+/* Function Prototypes */
+
+static int ppc4xx_edac_probe(struct of_device *device,
+ const struct of_device_id *device_id);
+static int ppc4xx_edac_remove(struct of_device *device);
+
+/* Global Variables */
+
+/*
+ * Device tree node type and compatible tuples this driver can match
+ * on.
+ */
+static struct of_device_id ppc4xx_edac_match[] = {
+ {
+ .compatible = "ibm,sdram-4xx-ddr2"
+ },
+ { }
+};
+
+static struct of_platform_driver ppc4xx_edac_driver = {
+ .match_table = ppc4xx_edac_match,
+ .probe = ppc4xx_edac_probe,
+ .remove = ppc4xx_edac_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = PPC4XX_EDAC_MODULE_NAME
+ }
+};
+
+/*
+ * TODO: The row and channel parameters likely need to be dynamically
+ * set based on the aforementioned variant controller realizations.
+ */
+static const unsigned ppc4xx_edac_nr_csrows = 2;
+static const unsigned ppc4xx_edac_nr_chans = 1;
+
+/*
+ * Strings associated with PLB master IDs capable of being posted in
+ * SDRAM_BESR or SDRAM_WMIRQ on uncorrectable ECC errors.
+ */
+static const char * const ppc4xx_plb_masters[9] = {
+ [SDRAM_PLB_M0ID_ICU] = "ICU",
+ [SDRAM_PLB_M0ID_PCIE0] = "PCI-E 0",
+ [SDRAM_PLB_M0ID_PCIE1] = "PCI-E 1",
+ [SDRAM_PLB_M0ID_DMA] = "DMA",
+ [SDRAM_PLB_M0ID_DCU] = "DCU",
+ [SDRAM_PLB_M0ID_OPB] = "OPB",
+ [SDRAM_PLB_M0ID_MAL] = "MAL",
+ [SDRAM_PLB_M0ID_SEC] = "SEC",
+ [SDRAM_PLB_M0ID_AHB] = "AHB"
+};
+
+/**
+ * mfsdram - read and return controller register data
+ * @dcr_host: A pointer to the DCR mapping.
+ * @idcr_n: The indirect DCR register to read.
+ *
+ * This routine reads and returns the data associated with the
+ * controller's specified indirect DCR register.
+ *
+ * Returns the read data.
+ */
+static inline u32
+mfsdram(const dcr_host_t *dcr_host, unsigned int idcr_n)
+{
+ return __mfdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET,
+ dcr_host->base + SDRAM_DCR_DATA_OFFSET,
+ idcr_n);
+}
+
+/**
+ * mtsdram - write controller register data
+ * @dcr_host: A pointer to the DCR mapping.
+ * @idcr_n: The indirect DCR register to write.
+ * @value: The data to write.
+ *
+ * This routine writes the provided data to the controller's specified
+ * indirect DCR register.
+ */
+static inline void
+mtsdram(const dcr_host_t *dcr_host, unsigned int idcr_n, u32 value)
+{
+ return __mtdcri(dcr_host->base + SDRAM_DCR_ADDR_OFFSET,
+ dcr_host->base + SDRAM_DCR_DATA_OFFSET,
+ idcr_n,
+ value);
+}
+
+/**
+ * ppc4xx_edac_check_bank_error - check a bank for an ECC bank error
+ * @status: A pointer to the ECC status structure to check for an
+ * ECC bank error.
+ * @bank: The bank to check for an ECC error.
+ *
+ * This routine determines whether the specified bank has an ECC
+ * error.
+ *
+ * Returns true if the specified bank has an ECC error; otherwise,
+ * false.
+ */
+static bool
+ppc4xx_edac_check_bank_error(const struct ppc4xx_ecc_status *status,
+ unsigned int bank)
+{
+ switch (bank) {
+ case 0:
+ return status->ecces & SDRAM_ECCES_BK0ER;
+ case 1:
+ return status->ecces & SDRAM_ECCES_BK1ER;
+ default:
+ return false;
+ }
+}
+
+/**
+ * ppc4xx_edac_generate_bank_message - generate interpretted bank status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the bank message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[BKNER]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_bank_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n, total = 0;
+ unsigned int row, rows;
+
+ n = snprintf(buffer, size, "%s: Banks: ", mci->dev_name);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ for (rows = 0, row = 0; row < mci->nr_csrows; row++) {
+ if (ppc4xx_edac_check_bank_error(status, row)) {
+ n = snprintf(buffer, size, "%s%u",
+ (rows++ ? ", " : ""), row);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+ }
+ }
+
+ n = snprintf(buffer, size, "%s; ", rows ? "" : "None");
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ fail:
+ return total;
+}
+
+/**
+ * ppc4xx_edac_generate_checkbit_message - generate interpretted checkbit message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the checkbit message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[CKBER]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_checkbit_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ const char *ckber = NULL;
+
+ switch (status->ecces & SDRAM_ECCES_CKBER_MASK) {
+ case SDRAM_ECCES_CKBER_NONE:
+ ckber = "None";
+ break;
+ case SDRAM_ECCES_CKBER_32_ECC_0_3:
+ ckber = "ECC0:3";
+ break;
+ case SDRAM_ECCES_CKBER_32_ECC_4_8:
+ switch (mfsdram(&pdata->dcr_host, SDRAM_MCOPT1) &
+ SDRAM_MCOPT1_WDTH_MASK) {
+ case SDRAM_MCOPT1_WDTH_16:
+ ckber = "ECC0:3";
+ break;
+ case SDRAM_MCOPT1_WDTH_32:
+ ckber = "ECC4:8";
+ break;
+ default:
+ ckber = "Unknown";
+ break;
+ }
+ break;
+ case SDRAM_ECCES_CKBER_32_ECC_0_8:
+ ckber = "ECC0:8";
+ break;
+ default:
+ ckber = "Unknown";
+ break;
+ }
+
+ return snprintf(buffer, size, "Checkbit Error: %s", ckber);
+}
+
+/**
+ * ppc4xx_edac_generate_lane_message - generate interpretted byte lane message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the byte lane message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS[BNCE]
+ * field of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_lane_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n, total = 0;
+ unsigned int lane, lanes;
+ const unsigned int first_lane = 0;
+ const unsigned int lane_count = 16;
+
+ n = snprintf(buffer, size, "; Byte Lane Errors: ");
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ for (lanes = 0, lane = first_lane; lane < lane_count; lane++) {
+ if ((status->ecces & SDRAM_ECCES_BNCE_ENCODE(lane)) != 0) {
+ n = snprintf(buffer, size,
+ "%s%u",
+ (lanes++ ? ", " : ""), lane);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+ }
+ }
+
+ n = snprintf(buffer, size, "%s; ", lanes ? "" : "None");
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ fail:
+ return total;
+}
+
+/**
+ * ppc4xx_edac_generate_ecc_message - generate interpretted ECC status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the ECCES message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the ECCESS register of
+ * the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_ecc_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n, total = 0;
+
+ n = ppc4xx_edac_generate_bank_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ n = ppc4xx_edac_generate_checkbit_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ n = ppc4xx_edac_generate_lane_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ goto fail;
+
+ buffer += n;
+ size -= n;
+ total += n;
+
+ fail:
+ return total;
+}
+
+/**
+ * ppc4xx_edac_generate_plb_message - generate interpretted PLB status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the PLB message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the portion of the
+ * driver-unique report message associated with the PLB-related BESR
+ * and/or WMIRQ registers of the specified ECC status.
+ *
+ * Returns the number of characters generated on success; otherwise, <
+ * 0 on error.
+ */
+static int
+ppc4xx_edac_generate_plb_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ unsigned int master;
+ bool read;
+
+ if ((status->besr & SDRAM_BESR_MASK) == 0)
+ return 0;
+
+ if ((status->besr & SDRAM_BESR_M0ET_MASK) == SDRAM_BESR_M0ET_NONE)
+ return 0;
+
+ read = ((status->besr & SDRAM_BESR_M0RW_MASK) == SDRAM_BESR_M0RW_READ);
+
+ master = SDRAM_BESR_M0ID_DECODE(status->besr);
+
+ return snprintf(buffer, size,
+ "%s error w/ PLB master %u \"%s\"; ",
+ (read ? "Read" : "Write"),
+ master,
+ (((master >= SDRAM_PLB_M0ID_FIRST) &&
+ (master <= SDRAM_PLB_M0ID_LAST)) ?
+ ppc4xx_plb_masters[master] : "UNKNOWN"));
+}
+
+/**
+ * ppc4xx_edac_generate_message - generate interpretted status message
+ * @mci: A pointer to the EDAC memory controller instance associated
+ * with the driver-unique message being generated.
+ * @status: A pointer to the ECC status structure to generate the
+ * message from.
+ * @buffer: A pointer to the buffer in which to generate the
+ * message.
+ * @size: The size, in bytes, of space available in buffer.
+ *
+ * This routine generates to the provided buffer the driver-unique
+ * EDAC report message from the specified ECC status.
+ */
+static void
+ppc4xx_edac_generate_message(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status,
+ char *buffer,
+ size_t size)
+{
+ int n;
+
+ if (buffer == NULL || size == 0)
+ return;
+
+ n = ppc4xx_edac_generate_ecc_message(mci, status, buffer, size);
+
+ if (n < 0 || n >= size)
+ return;
+
+ buffer += n;
+ size -= n;
+
+ ppc4xx_edac_generate_plb_message(mci, status, buffer, size);
+}
+
+#ifdef DEBUG
+/**
+ * ppc4xx_ecc_dump_status - dump controller ECC status registers
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the status being dumped.
+ * @status: A pointer to the ECC status structure to generate the
+ * dump from.
+ *
+ * This routine dumps to the kernel log buffer the raw and
+ * interpretted specified ECC status.
+ */
+static void
+ppc4xx_ecc_dump_status(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+ ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+ ppc4xx_edac_mc_printk(KERN_INFO, mci,
+ "\n"
+ "\tECCES: 0x%08x\n"
+ "\tWMIRQ: 0x%08x\n"
+ "\tBESR: 0x%08x\n"
+ "\tBEAR: 0x%08x%08x\n"
+ "\t%s\n",
+ status->ecces,
+ status->wmirq,
+ status->besr,
+ status->bearh,
+ status->bearl,
+ message);
+}
+#endif /* DEBUG */
+
+/**
+ * ppc4xx_ecc_get_status - get controller ECC status
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the status being retrieved.
+ * @status: A pointer to the ECC status structure to populate the
+ * ECC status with.
+ *
+ * This routine reads and masks, as appropriate, all the relevant
+ * status registers that deal with ibm,sdram-4xx-ddr2 ECC errors.
+ * While we read all of them, for correctable errors, we only expect
+ * to deal with ECCES. For uncorrectable errors, we expect to deal
+ * with all of them.
+ */
+static void
+ppc4xx_ecc_get_status(const struct mem_ctl_info *mci,
+ struct ppc4xx_ecc_status *status)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ const dcr_host_t *dcr_host = &pdata->dcr_host;
+
+ status->ecces = mfsdram(dcr_host, SDRAM_ECCES) & SDRAM_ECCES_MASK;
+ status->wmirq = mfsdram(dcr_host, SDRAM_WMIRQ) & SDRAM_WMIRQ_MASK;
+ status->besr = mfsdram(dcr_host, SDRAM_BESR) & SDRAM_BESR_MASK;
+ status->bearl = mfsdram(dcr_host, SDRAM_BEARL);
+ status->bearh = mfsdram(dcr_host, SDRAM_BEARH);
+}
+
+/**
+ * ppc4xx_ecc_clear_status - clear controller ECC status
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the status being cleared.
+ * @status: A pointer to the ECC status structure containing the
+ * values to write to clear the ECC status.
+ *
+ * This routine clears--by writing the masked (as appropriate) status
+ * values back to--the status registers that deal with
+ * ibm,sdram-4xx-ddr2 ECC errors.
+ */
+static void
+ppc4xx_ecc_clear_status(const struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ const dcr_host_t *dcr_host = &pdata->dcr_host;
+
+ mtsdram(dcr_host, SDRAM_ECCES, status->ecces & SDRAM_ECCES_MASK);
+ mtsdram(dcr_host, SDRAM_WMIRQ, status->wmirq & SDRAM_WMIRQ_MASK);
+ mtsdram(dcr_host, SDRAM_BESR, status->besr & SDRAM_BESR_MASK);
+ mtsdram(dcr_host, SDRAM_BEARL, 0);
+ mtsdram(dcr_host, SDRAM_BEARH, 0);
+}
+
+/**
+ * ppc4xx_edac_handle_ce - handle controller correctable ECC error (CE)
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the correctable error being handled and reported.
+ * @status: A pointer to the ECC status structure associated with
+ * the correctable error being handled and reported.
+ *
+ * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
+ * correctable error. Per the aforementioned discussion, there's not
+ * enough status available to use the full EDAC correctable error
+ * interface, so we just pass driver-unique message to the "no info"
+ * interface.
+ */
+static void
+ppc4xx_edac_handle_ce(struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ int row;
+ char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+ ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+ for (row = 0; row < mci->nr_csrows; row++)
+ if (ppc4xx_edac_check_bank_error(status, row))
+ edac_mc_handle_ce_no_info(mci, message);
+}
+
+/**
+ * ppc4xx_edac_handle_ue - handle controller uncorrectable ECC error (UE)
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the uncorrectable error being handled and
+ * reported.
+ * @status: A pointer to the ECC status structure associated with
+ * the uncorrectable error being handled and reported.
+ *
+ * This routine handles an ibm,sdram-4xx-ddr2 controller ECC
+ * uncorrectable error.
+ */
+static void
+ppc4xx_edac_handle_ue(struct mem_ctl_info *mci,
+ const struct ppc4xx_ecc_status *status)
+{
+ const u64 bear = ((u64)status->bearh << 32 | status->bearl);
+ const unsigned long page = bear >> PAGE_SHIFT;
+ const unsigned long offset = bear & ~PAGE_MASK;
+ int row;
+ char message[PPC4XX_EDAC_MESSAGE_SIZE];
+
+ ppc4xx_edac_generate_message(mci, status, message, sizeof(message));
+
+ for (row = 0; row < mci->nr_csrows; row++)
+ if (ppc4xx_edac_check_bank_error(status, row))
+ edac_mc_handle_ue(mci, page, offset, row, message);
+}
+
+/**
+ * ppc4xx_edac_check - check controller for ECC errors
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the ibm,sdram-4xx-ddr2 controller being
+ * checked.
+ *
+ * This routine is used to check and post ECC errors and is called by
+ * both the EDAC polling thread and this driver's CE and UE interrupt
+ * handler.
+ */
+static void
+ppc4xx_edac_check(struct mem_ctl_info *mci)
+{
+#ifdef DEBUG
+ static unsigned int count;
+#endif
+ struct ppc4xx_ecc_status status;
+
+ ppc4xx_ecc_get_status(mci, &status);
+
+#ifdef DEBUG
+ if (count++ % 30 == 0)
+ ppc4xx_ecc_dump_status(mci, &status);
+#endif
+
+ if (status.ecces & SDRAM_ECCES_UE)
+ ppc4xx_edac_handle_ue(mci, &status);
+
+ if (status.ecces & SDRAM_ECCES_CE)
+ ppc4xx_edac_handle_ce(mci, &status);
+
+ ppc4xx_ecc_clear_status(mci, &status);
+}
+
+/**
+ * ppc4xx_edac_isr - SEC (CE) and DED (UE) interrupt service routine
+ * @irq: The virtual interrupt number being serviced.
+ * @dev_id: A pointer to the EDAC memory controller instance
+ * associated with the interrupt being handled.
+ *
+ * This routine implements the interrupt handler for both correctable
+ * (CE) and uncorrectable (UE) ECC errors for the ibm,sdram-4xx-ddr2
+ * controller. It simply calls through to the same routine used during
+ * polling to check, report and clear the ECC status.
+ *
+ * Unconditionally returns IRQ_HANDLED.
+ */
+static irqreturn_t
+ppc4xx_edac_isr(int irq, void *dev_id)
+{
+ struct mem_ctl_info *mci = dev_id;
+
+ ppc4xx_edac_check(mci);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * ppc4xx_edac_get_dtype - return the controller memory width
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which the width
+ * is derived.
+ *
+ * This routine returns the EDAC device type width appropriate for the
+ * current controller configuration.
+ *
+ * TODO: This needs to be conditioned dynamically through feature
+ * flags or some such when other controller variants are supported as
+ * the 405EX[r] is 16-/32-bit and the others are 32-/64-bit with the
+ * 16- and 64-bit field definition/value/enumeration (b1) overloaded
+ * among them.
+ *
+ * Returns a device type width enumeration.
+ */
+static enum dev_type __devinit
+ppc4xx_edac_get_dtype(u32 mcopt1)
+{
+ switch (mcopt1 & SDRAM_MCOPT1_WDTH_MASK) {
+ case SDRAM_MCOPT1_WDTH_16:
+ return DEV_X2;
+ case SDRAM_MCOPT1_WDTH_32:
+ return DEV_X4;
+ default:
+ return DEV_UNKNOWN;
+ }
+}
+
+/**
+ * ppc4xx_edac_get_mtype - return controller memory type
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which the memory type
+ * is derived.
+ *
+ * This routine returns the EDAC memory type appropriate for the
+ * current controller configuration.
+ *
+ * Returns a memory type enumeration.
+ */
+static enum mem_type __devinit
+ppc4xx_edac_get_mtype(u32 mcopt1)
+{
+ bool rden = ((mcopt1 & SDRAM_MCOPT1_RDEN_MASK) == SDRAM_MCOPT1_RDEN);
+
+ switch (mcopt1 & SDRAM_MCOPT1_DDR_TYPE_MASK) {
+ case SDRAM_MCOPT1_DDR2_TYPE:
+ return rden ? MEM_RDDR2 : MEM_DDR2;
+ case SDRAM_MCOPT1_DDR1_TYPE:
+ return rden ? MEM_RDDR : MEM_DDR;
+ default:
+ return MEM_UNKNOWN;
+ }
+}
+
+/**
+ * ppc4xx_edac_init_csrows - intialize driver instance rows
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the ibm,sdram-4xx-ddr2 controller for which
+ * the csrows (i.e. banks/ranks) are being initialized.
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which bank width
+ * and memory typ information is derived.
+ *
+ * This routine intializes the virtual "chip select rows" associated
+ * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2
+ * controller bank/rank is mapped to a row.
+ *
+ * Returns 0 if OK; otherwise, -EINVAL if the memory bank size
+ * configuration cannot be determined.
+ */
+static int __devinit
+ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1)
+{
+ const struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ int status = 0;
+ enum mem_type mtype;
+ enum dev_type dtype;
+ enum edac_type edac_mode;
+ int row;
+ u32 mbxcf, size;
+ static u32 ppc4xx_last_page;
+
+ /* Establish the memory type and width */
+
+ mtype = ppc4xx_edac_get_mtype(mcopt1);
+ dtype = ppc4xx_edac_get_dtype(mcopt1);
+
+ /* Establish EDAC mode */
+
+ if (mci->edac_cap & EDAC_FLAG_SECDED)
+ edac_mode = EDAC_SECDED;
+ else if (mci->edac_cap & EDAC_FLAG_EC)
+ edac_mode = EDAC_EC;
+ else
+ edac_mode = EDAC_NONE;
+
+ /*
+ * Initialize each chip select row structure which correspond
+ * 1:1 with a controller bank/rank.
+ */
+
+ for (row = 0; row < mci->nr_csrows; row++) {
+ struct csrow_info *csi = &mci->csrows[row];
+
+ /*
+ * Get the configuration settings for this
+ * row/bank/rank and skip disabled banks.
+ */
+
+ mbxcf = mfsdram(&pdata->dcr_host, SDRAM_MBXCF(row));
+
+ if ((mbxcf & SDRAM_MBCF_BE_MASK) != SDRAM_MBCF_BE_ENABLE)
+ continue;
+
+ /* Map the bank configuration size setting to pages. */
+
+ size = mbxcf & SDRAM_MBCF_SZ_MASK;
+
+ switch (size) {
+ case SDRAM_MBCF_SZ_4MB:
+ case SDRAM_MBCF_SZ_8MB:
+ case SDRAM_MBCF_SZ_16MB:
+ case SDRAM_MBCF_SZ_32MB:
+ case SDRAM_MBCF_SZ_64MB:
+ case SDRAM_MBCF_SZ_128MB:
+ case SDRAM_MBCF_SZ_256MB:
+ case SDRAM_MBCF_SZ_512MB:
+ case SDRAM_MBCF_SZ_1GB:
+ case SDRAM_MBCF_SZ_2GB:
+ case SDRAM_MBCF_SZ_4GB:
+ case SDRAM_MBCF_SZ_8GB:
+ csi->nr_pages = SDRAM_MBCF_SZ_TO_PAGES(size);
+ break;
+ default:
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unrecognized memory bank %d "
+ "size 0x%08x\n",
+ row, SDRAM_MBCF_SZ_DECODE(size));
+ status = -EINVAL;
+ goto done;
+ }
+
+ csi->first_page = ppc4xx_last_page;
+ csi->last_page = csi->first_page + csi->nr_pages - 1;
+ csi->page_mask = 0;
+
+ /*
+ * It's unclear exactly what grain should be set to
+ * here. The SDRAM_ECCES register allows resolution of
+ * an error down to a nibble which would potentially
+ * argue for a grain of '1' byte, even though we only
+ * know the associated address for uncorrectable
+ * errors. This value is not used at present for
+ * anything other than error reporting so getting it
+ * wrong should be of little consequence. Other
+ * possible values would be the PLB width (16), the
+ * page size (PAGE_SIZE) or the memory width (2 or 4).
+ */
+
+ csi->grain = 1;
+
+ csi->mtype = mtype;
+ csi->dtype = dtype;
+
+ csi->edac_mode = edac_mode;
+
+ ppc4xx_last_page += csi->nr_pages;
+ }
+
+ done:
+ return status;
+}
+
+/**
+ * ppc4xx_edac_mc_init - intialize driver instance
+ * @mci: A pointer to the EDAC memory controller instance being
+ * initialized.
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller this EDAC instance is bound to.
+ * @match: A pointer to the OpenFirmware device tree match
+ * information associated with the controller this EDAC instance
+ * is bound to.
+ * @dcr_host: A pointer to the DCR data containing the DCR mapping
+ * for this controller instance.
+ * @mcopt1: The 32-bit Memory Controller Option 1 register value
+ * currently set for the controller, from which ECC capabilities
+ * and scrub mode are derived.
+ *
+ * This routine performs initialization of the EDAC memory controller
+ * instance and related driver-private data associated with the
+ * ibm,sdram-4xx-ddr2 memory controller the instance is bound to.
+ *
+ * Returns 0 if OK; otherwise, < 0 on error.
+ */
+static int __devinit
+ppc4xx_edac_mc_init(struct mem_ctl_info *mci,
+ struct of_device *op,
+ const struct of_device_id *match,
+ const dcr_host_t *dcr_host,
+ u32 mcopt1)
+{
+ int status = 0;
+ const u32 memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
+ struct ppc4xx_edac_pdata *pdata = NULL;
+ const struct device_node *np = op->node;
+
+ if (match == NULL)
+ return -EINVAL;
+
+ /* Initial driver pointers and private data */
+
+ mci->dev = &op->dev;
+
+ dev_set_drvdata(mci->dev, mci);
+
+ pdata = mci->pvt_info;
+
+ pdata->dcr_host = *dcr_host;
+ pdata->irqs.sec = NO_IRQ;
+ pdata->irqs.ded = NO_IRQ;
+
+ /* Initialize controller capabilities and configuration */
+
+ mci->mtype_cap = (MEM_FLAG_DDR | MEM_FLAG_RDDR |
+ MEM_FLAG_DDR2 | MEM_FLAG_RDDR2);
+
+ mci->edac_ctl_cap = (EDAC_FLAG_NONE |
+ EDAC_FLAG_EC |
+ EDAC_FLAG_SECDED);
+
+ mci->scrub_cap = SCRUB_NONE;
+ mci->scrub_mode = SCRUB_NONE;
+
+ /*
+ * Update the actual capabilites based on the MCOPT1[MCHK]
+ * settings. Scrubbing is only useful if reporting is enabled.
+ */
+
+ switch (memcheck) {
+ case SDRAM_MCOPT1_MCHK_CHK:
+ mci->edac_cap = EDAC_FLAG_EC;
+ break;
+ case SDRAM_MCOPT1_MCHK_CHK_REP:
+ mci->edac_cap = (EDAC_FLAG_EC | EDAC_FLAG_SECDED);
+ mci->scrub_mode = SCRUB_SW_SRC;
+ break;
+ default:
+ mci->edac_cap = EDAC_FLAG_NONE;
+ break;
+ }
+
+ /* Initialize strings */
+
+ mci->mod_name = PPC4XX_EDAC_MODULE_NAME;
+ mci->mod_ver = PPC4XX_EDAC_MODULE_REVISION;
+ mci->ctl_name = match->compatible,
+ mci->dev_name = np->full_name;
+
+ /* Initialize callbacks */
+
+ mci->edac_check = ppc4xx_edac_check;
+ mci->ctl_page_to_phys = NULL;
+
+ /* Initialize chip select rows */
+
+ status = ppc4xx_edac_init_csrows(mci, mcopt1);
+
+ if (status)
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Failed to initialize rows!\n");
+
+ return status;
+}
+
+/**
+ * ppc4xx_edac_register_irq - setup and register controller interrupts
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller this EDAC instance is bound to.
+ * @mci: A pointer to the EDAC memory controller instance
+ * associated with the ibm,sdram-4xx-ddr2 controller for which
+ * interrupts are being registered.
+ *
+ * This routine parses the correctable (CE) and uncorrectable error (UE)
+ * interrupts from the device tree node and maps and assigns them to
+ * the associated EDAC memory controller instance.
+ *
+ * Returns 0 if OK; otherwise, -ENODEV if the interrupts could not be
+ * mapped and assigned.
+ */
+static int __devinit
+ppc4xx_edac_register_irq(struct of_device *op, struct mem_ctl_info *mci)
+{
+ int status = 0;
+ int ded_irq, sec_irq;
+ struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+ struct device_node *np = op->node;
+
+ ded_irq = irq_of_parse_and_map(np, INTMAP_ECCDED_INDEX);
+ sec_irq = irq_of_parse_and_map(np, INTMAP_ECCSEC_INDEX);
+
+ if (ded_irq == NO_IRQ || sec_irq == NO_IRQ) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unable to map interrupts.\n");
+ status = -ENODEV;
+ goto fail;
+ }
+
+ status = request_irq(ded_irq,
+ ppc4xx_edac_isr,
+ IRQF_DISABLED,
+ "[EDAC] MC ECCDED",
+ mci);
+
+ if (status < 0) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unable to request irq %d for ECC DED",
+ ded_irq);
+ status = -ENODEV;
+ goto fail1;
+ }
+
+ status = request_irq(sec_irq,
+ ppc4xx_edac_isr,
+ IRQF_DISABLED,
+ "[EDAC] MC ECCSEC",
+ mci);
+
+ if (status < 0) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Unable to request irq %d for ECC SEC",
+ sec_irq);
+ status = -ENODEV;
+ goto fail2;
+ }
+
+ ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCDED irq is %d\n", ded_irq);
+ ppc4xx_edac_mc_printk(KERN_INFO, mci, "ECCSEC irq is %d\n", sec_irq);
+
+ pdata->irqs.ded = ded_irq;
+ pdata->irqs.sec = sec_irq;
+
+ return 0;
+
+ fail2:
+ free_irq(sec_irq, mci);
+
+ fail1:
+ free_irq(ded_irq, mci);
+
+ fail:
+ return status;
+}
+
+/**
+ * ppc4xx_edac_map_dcrs - locate and map controller registers
+ * @np: A pointer to the device tree node containing the DCR
+ * resources to map.
+ * @dcr_host: A pointer to the DCR data to populate with the
+ * DCR mapping.
+ *
+ * This routine attempts to locate in the device tree and map the DCR
+ * register resources associated with the controller's indirect DCR
+ * address and data windows.
+ *
+ * Returns 0 if the DCRs were successfully mapped; otherwise, < 0 on
+ * error.
+ */
+static int __devinit
+ppc4xx_edac_map_dcrs(const struct device_node *np, dcr_host_t *dcr_host)
+{
+ unsigned int dcr_base, dcr_len;
+
+ if (np == NULL || dcr_host == NULL)
+ return -EINVAL;
+
+ /* Get the DCR resource extent and sanity check the values. */
+
+ dcr_base = dcr_resource_start(np, 0);
+ dcr_len = dcr_resource_len(np, 0);
+
+ if (dcr_base == 0 || dcr_len == 0) {
+ ppc4xx_edac_printk(KERN_ERR,
+ "Failed to obtain DCR property.\n");
+ return -ENODEV;
+ }
+
+ if (dcr_len != SDRAM_DCR_RESOURCE_LEN) {
+ ppc4xx_edac_printk(KERN_ERR,
+ "Unexpected DCR length %d, expected %d.\n",
+ dcr_len, SDRAM_DCR_RESOURCE_LEN);
+ return -ENODEV;
+ }
+
+ /* Attempt to map the DCR extent. */
+
+ *dcr_host = dcr_map(np, dcr_base, dcr_len);
+
+ if (!DCR_MAP_OK(*dcr_host)) {
+ ppc4xx_edac_printk(KERN_INFO, "Failed to map DCRs.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * ppc4xx_edac_probe - check controller and bind driver
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller being probed for driver binding.
+ * @match: A pointer to the OpenFirmware device tree match
+ * information associated with the controller being probed
+ * for driver binding.
+ *
+ * This routine probes a specific ibm,sdram-4xx-ddr2 controller
+ * instance for binding with the driver.
+ *
+ * Returns 0 if the controller instance was successfully bound to the
+ * driver; otherwise, < 0 on error.
+ */
+static int __devinit
+ppc4xx_edac_probe(struct of_device *op, const struct of_device_id *match)
+{
+ int status = 0;
+ u32 mcopt1, memcheck;
+ dcr_host_t dcr_host;
+ const struct device_node *np = op->node;
+ struct mem_ctl_info *mci = NULL;
+ static int ppc4xx_edac_instance;
+
+ /*
+ * At this point, we only support the controller realized on
+ * the AMCC PPC 405EX[r]. Reject anything else.
+ */
+
+ if (!of_device_is_compatible(np, "ibm,sdram-405ex") &&
+ !of_device_is_compatible(np, "ibm,sdram-405exr")) {
+ ppc4xx_edac_printk(KERN_NOTICE,
+ "Only the PPC405EX[r] is supported.\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Next, get the DCR property and attempt to map it so that we
+ * can probe the controller.
+ */
+
+ status = ppc4xx_edac_map_dcrs(np, &dcr_host);
+
+ if (status)
+ return status;
+
+ /*
+ * First determine whether ECC is enabled at all. If not,
+ * there is no useful checking or monitoring that can be done
+ * for this controller.
+ */
+
+ mcopt1 = mfsdram(&dcr_host, SDRAM_MCOPT1);
+ memcheck = (mcopt1 & SDRAM_MCOPT1_MCHK_MASK);
+
+ if (memcheck == SDRAM_MCOPT1_MCHK_NON) {
+ ppc4xx_edac_printk(KERN_INFO, "%s: No ECC memory detected or "
+ "ECC is disabled.\n", np->full_name);
+ status = -ENODEV;
+ goto done;
+ }
+
+ /*
+ * At this point, we know ECC is enabled, allocate an EDAC
+ * controller instance and perform the appropriate
+ * initialization.
+ */
+
+ mci = edac_mc_alloc(sizeof(struct ppc4xx_edac_pdata),
+ ppc4xx_edac_nr_csrows,
+ ppc4xx_edac_nr_chans,
+ ppc4xx_edac_instance);
+
+ if (mci == NULL) {
+ ppc4xx_edac_printk(KERN_ERR, "%s: "
+ "Failed to allocate EDAC MC instance!\n",
+ np->full_name);
+ status = -ENOMEM;
+ goto done;
+ }
+
+ status = ppc4xx_edac_mc_init(mci, op, match, &dcr_host, mcopt1);
+
+ if (status) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Failed to initialize instance!\n");
+ goto fail;
+ }
+
+ /*
+ * We have a valid, initialized EDAC instance bound to the
+ * controller. Attempt to register it with the EDAC subsystem
+ * and, if necessary, register interrupts.
+ */
+
+ if (edac_mc_add_mc(mci)) {
+ ppc4xx_edac_mc_printk(KERN_ERR, mci,
+ "Failed to add instance!\n");
+ status = -ENODEV;
+ goto fail;
+ }
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ status = ppc4xx_edac_register_irq(op, mci);
+
+ if (status)
+ goto fail1;
+ }
+
+ ppc4xx_edac_instance++;
+
+ return 0;
+
+ fail1:
+ edac_mc_del_mc(mci->dev);
+
+ fail:
+ edac_mc_free(mci);
+
+ done:
+ return status;
+}
+
+/**
+ * ppc4xx_edac_remove - unbind driver from controller
+ * @op: A pointer to the OpenFirmware device tree node associated
+ * with the controller this EDAC instance is to be unbound/removed
+ * from.
+ *
+ * This routine unbinds the EDAC memory controller instance associated
+ * with the specified ibm,sdram-4xx-ddr2 controller described by the
+ * OpenFirmware device tree node passed as a parameter.
+ *
+ * Unconditionally returns 0.
+ */
+static int
+ppc4xx_edac_remove(struct of_device *op)
+{
+ struct mem_ctl_info *mci = dev_get_drvdata(&op->dev);
+ struct ppc4xx_edac_pdata *pdata = mci->pvt_info;
+
+ if (edac_op_state == EDAC_OPSTATE_INT) {
+ free_irq(pdata->irqs.sec, mci);
+ free_irq(pdata->irqs.ded, mci);
+ }
+
+ dcr_unmap(pdata->dcr_host, SDRAM_DCR_RESOURCE_LEN);
+
+ edac_mc_del_mc(mci->dev);
+ edac_mc_free(mci);
+
+ return 0;
+}
+
+/**
+ * ppc4xx_edac_opstate_init - initialize EDAC reporting method
+ *
+ * This routine ensures that the EDAC memory controller reporting
+ * method is mapped to a sane value as the EDAC core defines the value
+ * to EDAC_OPSTATE_INVAL by default. We don't call the global
+ * opstate_init as that defaults to polling and we want interrupt as
+ * the default.
+ */
+static inline void __init
+ppc4xx_edac_opstate_init(void)
+{
+ switch (edac_op_state) {
+ case EDAC_OPSTATE_POLL:
+ case EDAC_OPSTATE_INT:
+ break;
+ default:
+ edac_op_state = EDAC_OPSTATE_INT;
+ break;
+ }
+
+ ppc4xx_edac_printk(KERN_INFO, "Reporting type: %s\n",
+ ((edac_op_state == EDAC_OPSTATE_POLL) ?
+ EDAC_OPSTATE_POLL_STR :
+ ((edac_op_state == EDAC_OPSTATE_INT) ?
+ EDAC_OPSTATE_INT_STR :
+ EDAC_OPSTATE_UNKNOWN_STR)));
+}
+
+/**
+ * ppc4xx_edac_init - driver/module insertion entry point
+ *
+ * This routine is the driver/module insertion entry point. It
+ * initializes the EDAC memory controller reporting state and
+ * registers the driver as an OpenFirmware device tree platform
+ * driver.
+ */
+static int __init
+ppc4xx_edac_init(void)
+{
+ ppc4xx_edac_printk(KERN_INFO, PPC4XX_EDAC_MODULE_REVISION "\n");
+
+ ppc4xx_edac_opstate_init();
+
+ return of_register_platform_driver(&ppc4xx_edac_driver);
+}
+
+/**
+ * ppc4xx_edac_exit - driver/module removal entry point
+ *
+ * This routine is the driver/module removal entry point. It
+ * unregisters the driver as an OpenFirmware device tree platform
+ * driver.
+ */
+static void __exit
+ppc4xx_edac_exit(void)
+{
+ of_unregister_platform_driver(&ppc4xx_edac_driver);
+}
+
+module_init(ppc4xx_edac_init);
+module_exit(ppc4xx_edac_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Grant Erickson <gerickson@nuovations.com>");
+MODULE_DESCRIPTION("EDAC MC Driver for the PPC4xx IBM DDR2 Memory Controller");
+module_param(edac_op_state, int, 0444);
+MODULE_PARM_DESC(edac_op_state, "EDAC Error Reporting State: "
+ "0=" EDAC_OPSTATE_POLL_STR ", 2=" EDAC_OPSTATE_INT_STR);
diff --git a/drivers/edac/ppc4xx_edac.h b/drivers/edac/ppc4xx_edac.h
new file mode 100644
index 00000000000..d3154764c44
--- /dev/null
+++ b/drivers/edac/ppc4xx_edac.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2008 Nuovation System Designs, LLC
+ * Grant Erickson <gerickson@nuovations.com>
+ *
+ * This file defines processor mnemonics for accessing and managing
+ * the IBM DDR1/DDR2 ECC controller found in the 405EX[r], 440SP,
+ * 440SPe, 460EX, 460GT and 460SX.
+ *
+ * This program is free software; 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.
+ *
+ */
+
+#ifndef __PPC4XX_EDAC_H
+#define __PPC4XX_EDAC_H
+
+#include <linux/types.h>
+
+/*
+ * Macro for generating register field mnemonics
+ */
+#define PPC_REG_BITS 32
+#define PPC_REG_VAL(bit, val) ((val) << ((PPC_REG_BITS - 1) - (bit)))
+#define PPC_REG_DECODE(bit, val) ((val) >> ((PPC_REG_BITS - 1) - (bit)))
+
+/*
+ * IBM 4xx DDR1/DDR2 SDRAM memory controller registers (at least those
+ * relevant to ECC)
+ */
+#define SDRAM_BESR 0x00 /* Error status (read/clear) */
+#define SDRAM_BESRT 0x01 /* Error statuss (test/set) */
+#define SDRAM_BEARL 0x02 /* Error address low */
+#define SDRAM_BEARH 0x03 /* Error address high */
+#define SDRAM_WMIRQ 0x06 /* Write master (read/clear) */
+#define SDRAM_WMIRQT 0x07 /* Write master (test/set) */
+#define SDRAM_MCOPT1 0x20 /* Controller options 1 */
+#define SDRAM_MBXCF_BASE 0x40 /* Bank n configuration base */
+#define SDRAM_MBXCF(n) (SDRAM_MBXCF_BASE + (4 * (n)))
+#define SDRAM_MB0CF SDRAM_MBXCF(0)
+#define SDRAM_MB1CF SDRAM_MBXCF(1)
+#define SDRAM_MB2CF SDRAM_MBXCF(2)
+#define SDRAM_MB3CF SDRAM_MBXCF(3)
+#define SDRAM_ECCCR 0x98 /* ECC error status */
+#define SDRAM_ECCES SDRAM_ECCCR
+
+/*
+ * PLB Master IDs
+ */
+#define SDRAM_PLB_M0ID_FIRST 0
+#define SDRAM_PLB_M0ID_ICU SDRAM_PLB_M0ID_FIRST
+#define SDRAM_PLB_M0ID_PCIE0 1
+#define SDRAM_PLB_M0ID_PCIE1 2
+#define SDRAM_PLB_M0ID_DMA 3
+#define SDRAM_PLB_M0ID_DCU 4
+#define SDRAM_PLB_M0ID_OPB 5
+#define SDRAM_PLB_M0ID_MAL 6
+#define SDRAM_PLB_M0ID_SEC 7
+#define SDRAM_PLB_M0ID_AHB 8
+#define SDRAM_PLB_M0ID_LAST SDRAM_PLB_M0ID_AHB
+#define SDRAM_PLB_M0ID_COUNT (SDRAM_PLB_M0ID_LAST - \
+ SDRAM_PLB_M0ID_FIRST + 1)
+
+/*
+ * Memory Controller Bus Error Status Register
+ */
+#define SDRAM_BESR_MASK PPC_REG_VAL(7, 0xFF)
+#define SDRAM_BESR_M0ID_MASK PPC_REG_VAL(3, 0xF)
+#define SDRAM_BESR_M0ID_DECODE(n) PPC_REG_DECODE(3, n)
+#define SDRAM_BESR_M0ID_ICU PPC_REG_VAL(3, SDRAM_PLB_M0ID_ICU)
+#define SDRAM_BESR_M0ID_PCIE0 PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE0)
+#define SDRAM_BESR_M0ID_PCIE1 PPC_REG_VAL(3, SDRAM_PLB_M0ID_PCIE1)
+#define SDRAM_BESR_M0ID_DMA PPC_REG_VAL(3, SDRAM_PLB_M0ID_DMA)
+#define SDRAM_BESR_M0ID_DCU PPC_REG_VAL(3, SDRAM_PLB_M0ID_DCU)
+#define SDRAM_BESR_M0ID_OPB PPC_REG_VAL(3, SDRAM_PLB_M0ID_OPB)
+#define SDRAM_BESR_M0ID_MAL PPC_REG_VAL(3, SDRAM_PLB_M0ID_MAL)
+#define SDRAM_BESR_M0ID_SEC PPC_REG_VAL(3, SDRAM_PLB_M0ID_SEC)
+#define SDRAM_BESR_M0ID_AHB PPC_REG_VAL(3, SDRAM_PLB_M0ID_AHB)
+#define SDRAM_BESR_M0ET_MASK PPC_REG_VAL(6, 0x7)
+#define SDRAM_BESR_M0ET_NONE PPC_REG_VAL(6, 0)
+#define SDRAM_BESR_M0ET_ECC PPC_REG_VAL(6, 1)
+#define SDRAM_BESR_M0RW_MASK PPC_REG_VAL(7, 1)
+#define SDRAM_BESR_M0RW_WRITE PPC_REG_VAL(7, 0)
+#define SDRAM_BESR_M0RW_READ PPC_REG_VAL(7, 1)
+
+/*
+ * Memory Controller PLB Write Master Interrupt Register
+ */
+#define SDRAM_WMIRQ_MASK PPC_REG_VAL(8, 0x1FF)
+#define SDRAM_WMIRQ_ENCODE(id) PPC_REG_VAL((id % \
+ SDRAM_PLB_M0ID_COUNT), 1)
+#define SDRAM_WMIRQ_ICU PPC_REG_VAL(SDRAM_PLB_M0ID_ICU, 1)
+#define SDRAM_WMIRQ_PCIE0 PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE0, 1)
+#define SDRAM_WMIRQ_PCIE1 PPC_REG_VAL(SDRAM_PLB_M0ID_PCIE1, 1)
+#define SDRAM_WMIRQ_DMA PPC_REG_VAL(SDRAM_PLB_M0ID_DMA, 1)
+#define SDRAM_WMIRQ_DCU PPC_REG_VAL(SDRAM_PLB_M0ID_DCU, 1)
+#define SDRAM_WMIRQ_OPB PPC_REG_VAL(SDRAM_PLB_M0ID_OPB, 1)
+#define SDRAM_WMIRQ_MAL PPC_REG_VAL(SDRAM_PLB_M0ID_MAL, 1)
+#define SDRAM_WMIRQ_SEC PPC_REG_VAL(SDRAM_PLB_M0ID_SEC, 1)
+#define SDRAM_WMIRQ_AHB PPC_REG_VAL(SDRAM_PLB_M0ID_AHB, 1)
+
+/*
+ * Memory Controller Options 1 Register
+ */
+#define SDRAM_MCOPT1_MCHK_MASK PPC_REG_VAL(3, 0x3) /* ECC mask */
+#define SDRAM_MCOPT1_MCHK_NON PPC_REG_VAL(3, 0x0) /* No ECC gen */
+#define SDRAM_MCOPT1_MCHK_GEN PPC_REG_VAL(3, 0x2) /* ECC gen */
+#define SDRAM_MCOPT1_MCHK_CHK PPC_REG_VAL(3, 0x1) /* ECC gen and chk */
+#define SDRAM_MCOPT1_MCHK_CHK_REP PPC_REG_VAL(3, 0x3) /* ECC gen/chk/rpt */
+#define SDRAM_MCOPT1_MCHK_DECODE(n) ((((u32)(n)) >> 28) & 0x3)
+#define SDRAM_MCOPT1_RDEN_MASK PPC_REG_VAL(4, 0x1) /* Rgstrd DIMM mask */
+#define SDRAM_MCOPT1_RDEN PPC_REG_VAL(4, 0x1) /* Rgstrd DIMM enbl */
+#define SDRAM_MCOPT1_WDTH_MASK PPC_REG_VAL(7, 0x1) /* Width mask */
+#define SDRAM_MCOPT1_WDTH_32 PPC_REG_VAL(7, 0x0) /* 32 bits */
+#define SDRAM_MCOPT1_WDTH_16 PPC_REG_VAL(7, 0x1) /* 16 bits */
+#define SDRAM_MCOPT1_DDR_TYPE_MASK PPC_REG_VAL(11, 0x1) /* DDR type mask */
+#define SDRAM_MCOPT1_DDR1_TYPE PPC_REG_VAL(11, 0x0) /* DDR1 type */
+#define SDRAM_MCOPT1_DDR2_TYPE PPC_REG_VAL(11, 0x1) /* DDR2 type */
+
+/*
+ * Memory Bank 0 - n Configuration Register
+ */
+#define SDRAM_MBCF_BA_MASK PPC_REG_VAL(12, 0x1FFF)
+#define SDRAM_MBCF_SZ_MASK PPC_REG_VAL(19, 0xF)
+#define SDRAM_MBCF_SZ_DECODE(mbxcf) PPC_REG_DECODE(19, mbxcf)
+#define SDRAM_MBCF_SZ_4MB PPC_REG_VAL(19, 0x0)
+#define SDRAM_MBCF_SZ_8MB PPC_REG_VAL(19, 0x1)
+#define SDRAM_MBCF_SZ_16MB PPC_REG_VAL(19, 0x2)
+#define SDRAM_MBCF_SZ_32MB PPC_REG_VAL(19, 0x3)
+#define SDRAM_MBCF_SZ_64MB PPC_REG_VAL(19, 0x4)
+#define SDRAM_MBCF_SZ_128MB PPC_REG_VAL(19, 0x5)
+#define SDRAM_MBCF_SZ_256MB PPC_REG_VAL(19, 0x6)
+#define SDRAM_MBCF_SZ_512MB PPC_REG_VAL(19, 0x7)
+#define SDRAM_MBCF_SZ_1GB PPC_REG_VAL(19, 0x8)
+#define SDRAM_MBCF_SZ_2GB PPC_REG_VAL(19, 0x9)
+#define SDRAM_MBCF_SZ_4GB PPC_REG_VAL(19, 0xA)
+#define SDRAM_MBCF_SZ_8GB PPC_REG_VAL(19, 0xB)
+#define SDRAM_MBCF_AM_MASK PPC_REG_VAL(23, 0xF)
+#define SDRAM_MBCF_AM_MODE0 PPC_REG_VAL(23, 0x0)
+#define SDRAM_MBCF_AM_MODE1 PPC_REG_VAL(23, 0x1)
+#define SDRAM_MBCF_AM_MODE2 PPC_REG_VAL(23, 0x2)
+#define SDRAM_MBCF_AM_MODE3 PPC_REG_VAL(23, 0x3)
+#define SDRAM_MBCF_AM_MODE4 PPC_REG_VAL(23, 0x4)
+#define SDRAM_MBCF_AM_MODE5 PPC_REG_VAL(23, 0x5)
+#define SDRAM_MBCF_AM_MODE6 PPC_REG_VAL(23, 0x6)
+#define SDRAM_MBCF_AM_MODE7 PPC_REG_VAL(23, 0x7)
+#define SDRAM_MBCF_AM_MODE8 PPC_REG_VAL(23, 0x8)
+#define SDRAM_MBCF_AM_MODE9 PPC_REG_VAL(23, 0x9)
+#define SDRAM_MBCF_BE_MASK PPC_REG_VAL(31, 0x1)
+#define SDRAM_MBCF_BE_DISABLE PPC_REG_VAL(31, 0x0)
+#define SDRAM_MBCF_BE_ENABLE PPC_REG_VAL(31, 0x1)
+
+/*
+ * ECC Error Status
+ */
+#define SDRAM_ECCES_MASK PPC_REG_VAL(21, 0x3FFFFF)
+#define SDRAM_ECCES_BNCE_MASK PPC_REG_VAL(15, 0xFFFF)
+#define SDRAM_ECCES_BNCE_ENCODE(lane) PPC_REG_VAL(((lane) & 0xF), 1)
+#define SDRAM_ECCES_CKBER_MASK PPC_REG_VAL(17, 0x3)
+#define SDRAM_ECCES_CKBER_NONE PPC_REG_VAL(17, 0)
+#define SDRAM_ECCES_CKBER_16_ECC_0_3 PPC_REG_VAL(17, 2)
+#define SDRAM_ECCES_CKBER_32_ECC_0_3 PPC_REG_VAL(17, 1)
+#define SDRAM_ECCES_CKBER_32_ECC_4_8 PPC_REG_VAL(17, 2)
+#define SDRAM_ECCES_CKBER_32_ECC_0_8 PPC_REG_VAL(17, 3)
+#define SDRAM_ECCES_CE PPC_REG_VAL(18, 1)
+#define SDRAM_ECCES_UE PPC_REG_VAL(19, 1)
+#define SDRAM_ECCES_BKNER_MASK PPC_REG_VAL(21, 0x3)
+#define SDRAM_ECCES_BK0ER PPC_REG_VAL(20, 1)
+#define SDRAM_ECCES_BK1ER PPC_REG_VAL(21, 1)
+
+#endif /* __PPC4XX_EDAC_H */
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 8f0f7c44930..5f1b5400d96 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -68,7 +68,8 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s)
* pointing to completely the wrong place for example
*/
static void dmi_table(u8 *buf, int len, int num,
- void (*decode)(const struct dmi_header *))
+ void (*decode)(const struct dmi_header *, void *),
+ void *private_data)
{
u8 *data = buf;
int i = 0;
@@ -89,7 +90,7 @@ static void dmi_table(u8 *buf, int len, int num,
while ((data - buf < len - 1) && (data[0] || data[1]))
data++;
if (data - buf < len - 1)
- decode(dm);
+ decode(dm, private_data);
data += 2;
i++;
}
@@ -99,7 +100,8 @@ static u32 dmi_base;
static u16 dmi_len;
static u16 dmi_num;
-static int __init dmi_walk_early(void (*decode)(const struct dmi_header *))
+static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
+ void *))
{
u8 *buf;
@@ -107,7 +109,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *))
if (buf == NULL)
return -1;
- dmi_table(buf, dmi_len, dmi_num, decode);
+ dmi_table(buf, dmi_len, dmi_num, decode, NULL);
dmi_iounmap(buf, dmi_len);
return 0;
@@ -295,7 +297,7 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
* and machine entries. For 2.5 we should pull the smbus controller info
* out of here.
*/
-static void __init dmi_decode(const struct dmi_header *dm)
+static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
{
switch(dm->type) {
case 0: /* BIOS Information */
@@ -598,10 +600,12 @@ int dmi_get_year(int field)
/**
* dmi_walk - Walk the DMI table and get called back for every record
* @decode: Callback function
+ * @private_data: Private data to be passed to the callback function
*
* Returns -1 when the DMI table can't be reached, 0 on success.
*/
-int dmi_walk(void (*decode)(const struct dmi_header *))
+int dmi_walk(void (*decode)(const struct dmi_header *, void *),
+ void *private_data)
{
u8 *buf;
@@ -612,7 +616,7 @@ int dmi_walk(void (*decode)(const struct dmi_header *))
if (buf == NULL)
return -1;
- dmi_table(buf, dmi_len, dmi_num, decode);
+ dmi_table(buf, dmi_len, dmi_num, decode, private_data);
iounmap(buf);
return 0;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 3d2565441b3..edb02530e46 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -42,9 +42,9 @@ config DEBUG_GPIO
depends on DEBUG_KERNEL
help
Say Y here to add some extra checks and diagnostics to GPIO calls.
- The checks help ensure that GPIOs have been properly initialized
- before they are used and that sleeping calls aren not made from
- nonsleeping contexts. They can make bitbanged serial protocols
+ These checks help ensure that GPIOs have been properly initialized
+ before they are used, and that sleeping calls are not made from
+ non-sleeping contexts. They can make bitbanged serial protocols
slower. The diagnostics help catch the type of setup errors
that are most common when setting up new platforms or boards.
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 42fb2fd24c0..51a8d4103be 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -69,20 +69,24 @@ static inline void desc_set_label(struct gpio_desc *d, const char *label)
* those calls have no teeth) we can't avoid autorequesting. This nag
* message should motivate switching to explicit requests... so should
* the weaker cleanup after faults, compared to gpio_request().
+ *
+ * NOTE: the autorequest mechanism is going away; at this point it's
+ * only "legal" in the sense that (old) code using it won't break yet,
+ * but instead only triggers a WARN() stack dump.
*/
static int gpio_ensure_requested(struct gpio_desc *desc, unsigned offset)
{
- if (test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0) {
- struct gpio_chip *chip = desc->chip;
- int gpio = chip->base + offset;
+ const struct gpio_chip *chip = desc->chip;
+ const int gpio = chip->base + offset;
+ if (WARN(test_and_set_bit(FLAG_REQUESTED, &desc->flags) == 0,
+ "autorequest GPIO-%d\n", gpio)) {
if (!try_module_get(chip->owner)) {
pr_err("GPIO-%d: module can't be gotten \n", gpio);
clear_bit(FLAG_REQUESTED, &desc->flags);
/* lose */
return -EIO;
}
- pr_warning("GPIO-%d autorequested\n", gpio);
desc_set_label(desc, "[auto]");
/* caller must chip->request() w/o spinlock */
if (chip->request)
@@ -438,6 +442,7 @@ int gpio_export(unsigned gpio, bool direction_may_change)
unsigned long flags;
struct gpio_desc *desc;
int status = -EINVAL;
+ char *ioname = NULL;
/* can't export until sysfs is available ... */
if (!gpio_class.p) {
@@ -461,11 +466,14 @@ int gpio_export(unsigned gpio, bool direction_may_change)
}
spin_unlock_irqrestore(&gpio_lock, flags);
+ if (desc->chip->names && desc->chip->names[gpio - desc->chip->base])
+ ioname = desc->chip->names[gpio - desc->chip->base];
+
if (status == 0) {
struct device *dev;
dev = device_create(&gpio_class, desc->chip->dev, MKDEV(0, 0),
- desc, "gpio%d", gpio);
+ desc, ioname ? ioname : "gpio%d", gpio);
if (dev) {
if (direction_may_change)
status = sysfs_create_group(&dev->kobj,
@@ -513,6 +521,7 @@ void gpio_unexport(unsigned gpio)
mutex_lock(&sysfs_lock);
desc = &gpio_desc[gpio];
+
if (test_bit(FLAG_EXPORT, &desc->flags)) {
struct device *dev = NULL;
diff --git a/drivers/gpu/drm/ati_pcigart.c b/drivers/gpu/drm/ati_pcigart.c
index c533d0c9ec6..628eae3e9b8 100644
--- a/drivers/gpu/drm/ati_pcigart.c
+++ b/drivers/gpu/drm/ati_pcigart.c
@@ -77,7 +77,7 @@ int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info
if (!entry->busaddr[i])
break;
pci_unmap_page(dev->pdev, entry->busaddr[i],
- PAGE_SIZE, PCI_DMA_TODEVICE);
+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
}
if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
@@ -95,13 +95,14 @@ EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
{
+ struct drm_local_map *map = &gart_info->mapping;
struct drm_sg_mem *entry = dev->sg;
void *address = NULL;
unsigned long pages;
- u32 *pci_gart, page_base;
+ u32 *pci_gart = NULL, page_base, gart_idx;
dma_addr_t bus_address = 0;
int i, j, ret = 0;
- int max_pages;
+ int max_ati_pages, max_real_pages;
if (!entry) {
DRM_ERROR("no scatter/gather memory!\n");
@@ -117,6 +118,7 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
goto done;
}
+ pci_gart = gart_info->table_handle->vaddr;
address = gart_info->table_handle->vaddr;
bus_address = gart_info->table_handle->busaddr;
} else {
@@ -127,18 +129,23 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
(unsigned long)address);
}
- pci_gart = (u32 *) address;
- max_pages = (gart_info->table_size / sizeof(u32));
- pages = (entry->pages <= max_pages)
- ? entry->pages : max_pages;
+ max_ati_pages = (gart_info->table_size / sizeof(u32));
+ max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
+ pages = (entry->pages <= max_real_pages)
+ ? entry->pages : max_real_pages;
- memset(pci_gart, 0, max_pages * sizeof(u32));
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
+ memset(pci_gart, 0, max_ati_pages * sizeof(u32));
+ } else {
+ memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u32));
+ }
+ gart_idx = 0;
for (i = 0; i < pages; i++) {
/* we need to support large memory configurations */
entry->busaddr[i] = pci_map_page(dev->pdev, entry->pagelist[i],
- 0, PAGE_SIZE, PCI_DMA_TODEVICE);
+ 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
if (entry->busaddr[i] == 0) {
DRM_ERROR("unable to map PCIGART pages!\n");
drm_ati_pcigart_cleanup(dev, gart_info);
@@ -149,19 +156,26 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
page_base = (u32) entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+ u32 val;
+
switch(gart_info->gart_reg_if) {
case DRM_ATI_GART_IGP:
- *pci_gart = cpu_to_le32((page_base) | 0xc);
+ val = page_base | 0xc;
break;
case DRM_ATI_GART_PCIE:
- *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
+ val = (page_base >> 8) | 0xc;
break;
default:
case DRM_ATI_GART_PCI:
- *pci_gart = cpu_to_le32(page_base);
+ val = page_base;
break;
}
- pci_gart++;
+ if (gart_info->gart_table_location ==
+ DRM_ATI_GART_MAIN)
+ pci_gart[gart_idx] = cpu_to_le32(val);
+ else
+ DRM_WRITE32(map, gart_idx * sizeof(u32), val);
+ gart_idx++;
page_base += ATI_PCIGART_PAGE_SIZE;
}
}
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index 12715d3c078..6d80d17f1e9 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -34,15 +34,17 @@
*/
#include <linux/vmalloc.h>
+#include <linux/log2.h>
+#include <asm/shmparam.h>
#include "drmP.h"
-unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource)
+resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource)
{
return pci_resource_start(dev->pdev, resource);
}
EXPORT_SYMBOL(drm_get_resource_start);
-unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource)
+resource_size_t drm_get_resource_len(struct drm_device *dev, unsigned int resource)
{
return pci_resource_len(dev->pdev, resource);
}
@@ -50,24 +52,44 @@ unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource
EXPORT_SYMBOL(drm_get_resource_len);
static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
- drm_local_map_t *map)
+ struct drm_local_map *map)
{
struct drm_map_list *entry;
list_for_each_entry(entry, &dev->maplist, head) {
- if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) &&
- ((entry->map->offset == map->offset) ||
- ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) {
+ /*
+ * Because the kernel-userspace ABI is fixed at a 32-bit offset
+ * while PCI resources may live above that, we ignore the map
+ * offset for maps of type _DRM_FRAMEBUFFER or _DRM_REGISTERS.
+ * It is assumed that each driver will have only one resource of
+ * each type.
+ */
+ if (!entry->map ||
+ map->type != entry->map->type ||
+ entry->master != dev->primary->master)
+ continue;
+ switch (map->type) {
+ case _DRM_SHM:
+ if (map->flags != _DRM_CONTAINS_LOCK)
+ break;
+ case _DRM_REGISTERS:
+ case _DRM_FRAME_BUFFER:
return entry;
+ default: /* Make gcc happy */
+ ;
}
+ if (entry->map->offset == map->offset)
+ return entry;
}
return NULL;
}
static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
- unsigned long user_token, int hashed_handle)
+ unsigned long user_token, int hashed_handle, int shm)
{
- int use_hashed_handle;
+ int use_hashed_handle, shift;
+ unsigned long add;
+
#if (BITS_PER_LONG == 64)
use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
#elif (BITS_PER_LONG == 32)
@@ -83,30 +105,47 @@ static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
if (ret != -EINVAL)
return ret;
}
+
+ shift = 0;
+ add = DRM_MAP_HASH_OFFSET >> PAGE_SHIFT;
+ if (shm && (SHMLBA > PAGE_SIZE)) {
+ int bits = ilog2(SHMLBA >> PAGE_SHIFT) + 1;
+
+ /* For shared memory, we have to preserve the SHMLBA
+ * bits of the eventual vma->vm_pgoff value during
+ * mmap(). Otherwise we run into cache aliasing problems
+ * on some platforms. On these platforms, the pgoff of
+ * a mmap() request is used to pick a suitable virtual
+ * address for the mmap() region such that it will not
+ * cause cache aliasing problems.
+ *
+ * Therefore, make sure the SHMLBA relevant bits of the
+ * hash value we use are equal to those in the original
+ * kernel virtual address.
+ */
+ shift = bits;
+ add |= ((user_token >> PAGE_SHIFT) & ((1UL << bits) - 1UL));
+ }
+
return drm_ht_just_insert_please(&dev->map_hash, hash,
user_token, 32 - PAGE_SHIFT - 3,
- 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT);
+ shift, add);
}
/**
- * Ioctl to specify a range of memory that is available for mapping by a non-root process.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg pointer to a drm_map structure.
- * \return zero on success or a negative value on error.
+ * Core function to create a range of memory available for mapping by a
+ * non-root process.
*
* Adjusts the memory offset to its absolute value according to the mapping
* type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
* applicable and if supported by the kernel.
*/
-static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
+static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
unsigned int size, enum drm_map_type type,
enum drm_map_flags flags,
struct drm_map_list ** maplist)
{
- struct drm_map *map;
+ struct drm_local_map *map;
struct drm_map_list *list;
drm_dma_handle_t *dmah;
unsigned long user_token;
@@ -129,9 +168,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
- DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
- map->offset, map->size, map->type);
- if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
+ DRM_DEBUG("offset = 0x%08llx, size = 0x%08lx, type = %d\n",
+ (unsigned long long)map->offset, map->size, map->type);
+ if ((map->offset & (~(resource_size_t)PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EINVAL;
}
@@ -259,7 +298,8 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
drm_free(map, sizeof(*map), DRM_MEM_MAPS);
return -EPERM;
}
- DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
+ DRM_DEBUG("AGP offset = 0x%08llx, size = 0x%08lx\n",
+ (unsigned long long)map->offset, map->size);
break;
case _DRM_GEM:
@@ -309,7 +349,8 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
/* We do it here so that dev->struct_mutex protects the increment */
user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
map->offset;
- ret = drm_map_handle(dev, &list->hash, user_token, 0);
+ ret = drm_map_handle(dev, &list->hash, user_token, 0,
+ (map->type == _DRM_SHM));
if (ret) {
if (map->type == _DRM_REGISTERS)
iounmap(map->handle);
@@ -327,9 +368,9 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
return 0;
}
-int drm_addmap(struct drm_device * dev, unsigned int offset,
+int drm_addmap(struct drm_device * dev, resource_size_t offset,
unsigned int size, enum drm_map_type type,
- enum drm_map_flags flags, drm_local_map_t ** map_ptr)
+ enum drm_map_flags flags, struct drm_local_map ** map_ptr)
{
struct drm_map_list *list;
int rc;
@@ -342,6 +383,17 @@ int drm_addmap(struct drm_device * dev, unsigned int offset,
EXPORT_SYMBOL(drm_addmap);
+/**
+ * Ioctl to specify a range of memory that is available for mapping by a
+ * non-root process.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg pointer to a drm_map structure.
+ * \return zero on success or a negative value on error.
+ *
+ */
int drm_addmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -367,19 +419,13 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data,
* Remove a map private from list and deallocate resources if the mapping
* isn't in use.
*
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg pointer to a struct drm_map structure.
- * \return zero on success or a negative value on error.
- *
* Searches the map on drm_device::maplist, removes it from the list, see if
* its being used, and free any associate resource (such as MTRR's) if it's not
* being on use.
*
* \sa drm_addmap
*/
-int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
+int drm_rmmap_locked(struct drm_device *dev, struct drm_local_map *map)
{
struct drm_map_list *r_list = NULL, *list_t;
drm_dma_handle_t dmah;
@@ -442,7 +488,7 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
}
EXPORT_SYMBOL(drm_rmmap_locked);
-int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
+int drm_rmmap(struct drm_device *dev, struct drm_local_map *map)
{
int ret;
@@ -462,12 +508,18 @@ EXPORT_SYMBOL(drm_rmmap);
* One use case might be after addmap is allowed for normal users for SHM and
* gets used by drivers that the server doesn't need to care about. This seems
* unlikely.
+ *
+ * \param inode device inode.
+ * \param file_priv DRM file private.
+ * \param cmd command.
+ * \param arg pointer to a struct drm_map structure.
+ * \return zero on success or a negative value on error.
*/
int drm_rmmap_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_map *request = data;
- drm_local_map_t *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_map_list *r_list;
int ret;
@@ -1534,7 +1586,7 @@ int drm_mapbufs(struct drm_device *dev, void *data,
&& (dma->flags & _DRM_DMA_USE_SG))
|| (drm_core_check_feature(dev, DRIVER_FB_DMA)
&& (dma->flags & _DRM_DMA_USE_FB))) {
- struct drm_map *map = dev->agp_buffer_map;
+ struct drm_local_map *map = dev->agp_buffer_map;
unsigned long token = dev->agp_buffer_token;
if (!map) {
diff --git a/drivers/gpu/drm/drm_context.c b/drivers/gpu/drm/drm_context.c
index 809ec0f0345..7d1e53c10d4 100644
--- a/drivers/gpu/drm/drm_context.c
+++ b/drivers/gpu/drm/drm_context.c
@@ -143,7 +143,7 @@ int drm_getsareactx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
- struct drm_map *map;
+ struct drm_local_map *map;
struct drm_map_list *_entry;
mutex_lock(&dev->struct_mutex);
@@ -186,7 +186,7 @@ int drm_setsareactx(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
struct drm_ctx_priv_map *request = data;
- struct drm_map *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_map_list *r_list = NULL;
mutex_lock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index 1c3a8c55714..a04639dc633 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -42,6 +42,26 @@ static struct drm_display_mode std_modes[] = {
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
};
+static void drm_mode_validate_flag(struct drm_connector *connector,
+ int flags)
+{
+ struct drm_display_mode *mode, *t;
+
+ if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
+ return;
+
+ list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+ !(flags & DRM_MODE_FLAG_INTERLACE))
+ mode->status = MODE_NO_INTERLACE;
+ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+ !(flags & DRM_MODE_FLAG_DBLSCAN))
+ mode->status = MODE_NO_DBLESCAN;
+ }
+
+ return;
+}
+
/**
* drm_helper_probe_connector_modes - get complete set of display modes
* @dev: DRM device
@@ -72,6 +92,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
struct drm_connector_helper_funcs *connector_funcs =
connector->helper_private;
int count = 0;
+ int mode_flags = 0;
DRM_DEBUG("%s\n", drm_get_connector_name(connector));
/* set all modes to the unverified state */
@@ -96,6 +117,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
if (maxX && maxY)
drm_mode_validate_size(dev, &connector->modes, maxX,
maxY, 0);
+
+ if (connector->interlace_allowed)
+ mode_flags |= DRM_MODE_FLAG_INTERLACE;
+ if (connector->doublescan_allowed)
+ mode_flags |= DRM_MODE_FLAG_DBLSCAN;
+ drm_mode_validate_flag(connector, mode_flags);
+
list_for_each_entry_safe(mode, t, &connector->modes, head) {
if (mode->status == MODE_OK)
mode->status = connector_funcs->mode_valid(connector,
@@ -885,7 +913,6 @@ bool drm_helper_plugged_event(struct drm_device *dev)
/**
* drm_initial_config - setup a sane initial connector configuration
* @dev: DRM device
- * @can_grow: this configuration is growable
*
* LOCKING:
* Called at init time, must take mode config lock.
@@ -897,7 +924,7 @@ bool drm_helper_plugged_event(struct drm_device *dev)
* RETURNS:
* Zero if everything went ok, nonzero otherwise.
*/
-bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
+bool drm_helper_initial_config(struct drm_device *dev)
{
struct drm_connector *connector;
int count = 0;
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index ed32edb1716..c4ada8b6295 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -254,15 +254,19 @@ int drm_lastclose(struct drm_device * dev)
int drm_init(struct drm_driver *driver)
{
struct pci_dev *pdev = NULL;
- struct pci_device_id *pid;
+ const struct pci_device_id *pid;
int i;
DRM_DEBUG("\n");
INIT_LIST_HEAD(&driver->device_list);
+ if (driver->driver_features & DRIVER_MODESET)
+ return pci_register_driver(&driver->pci_driver);
+
+ /* If not using KMS, fall back to stealth mode manual scanning. */
for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
- pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
+ pid = &driver->pci_driver.id_table[i];
/* Loop around setting up a DRM device for each PCI device
* matching our ID and device class. If we had the internal
@@ -287,68 +291,17 @@ int drm_init(struct drm_driver *driver)
EXPORT_SYMBOL(drm_init);
-/**
- * Called via cleanup_module() at module unload time.
- *
- * Cleans up all DRM device, calling drm_lastclose().
- *
- * \sa drm_init
- */
-static void drm_cleanup(struct drm_device * dev)
-{
- struct drm_map_list *r_list, *list_temp;
- DRM_DEBUG("\n");
-
- if (!dev) {
- DRM_ERROR("cleanup called no dev\n");
- return;
- }
-
- drm_vblank_cleanup(dev);
-
- drm_lastclose(dev);
-
- if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
- dev->agp && dev->agp->agp_mtrr >= 0) {
- int retval;
- retval = mtrr_del(dev->agp->agp_mtrr,
- dev->agp->agp_info.aper_base,
- dev->agp->agp_info.aper_size * 1024 * 1024);
- DRM_DEBUG("mtrr_del=%d\n", retval);
- }
-
- if (dev->driver->unload)
- dev->driver->unload(dev);
-
- if (drm_core_has_AGP(dev) && dev->agp) {
- drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
- dev->agp = NULL;
- }
-
- drm_ht_remove(&dev->map_hash);
- drm_ctxbitmap_cleanup(dev);
-
- list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
- drm_rmmap(dev, r_list->map);
-
- if (drm_core_check_feature(dev, DRIVER_MODESET))
- drm_put_minor(&dev->control);
-
- if (dev->driver->driver_features & DRIVER_GEM)
- drm_gem_destroy(dev);
-
- drm_put_minor(&dev->primary);
- if (drm_put_dev(dev))
- DRM_ERROR("Cannot unload module\n");
-}
-
void drm_exit(struct drm_driver *driver)
{
struct drm_device *dev, *tmp;
DRM_DEBUG("\n");
- list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
- drm_cleanup(dev);
+ if (driver->driver_features & DRIVER_MODESET) {
+ pci_unregister_driver(&driver->pci_driver);
+ } else {
+ list_for_each_entry_safe(dev, tmp, &driver->device_list, driver_item)
+ drm_put_dev(dev);
+ }
DRM_INFO("Module unloaded\n");
}
@@ -468,6 +421,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
drm_ioctl_t *func;
unsigned int nr = DRM_IOCTL_NR(cmd);
int retcode = -EINVAL;
+ char stack_kdata[128];
char *kdata = NULL;
atomic_inc(&dev->ioctl_count);
@@ -506,10 +460,14 @@ int drm_ioctl(struct inode *inode, struct file *filp,
retcode = -EACCES;
} else {
if (cmd & (IOC_IN | IOC_OUT)) {
- kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
- if (!kdata) {
- retcode = -ENOMEM;
- goto err_i1;
+ if (_IOC_SIZE(cmd) <= sizeof(stack_kdata)) {
+ kdata = stack_kdata;
+ } else {
+ kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
+ if (!kdata) {
+ retcode = -ENOMEM;
+ goto err_i1;
+ }
}
}
@@ -530,7 +488,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
}
err_i1:
- if (kdata)
+ if (kdata != stack_kdata)
kfree(kdata);
atomic_dec(&dev->ioctl_count);
if (retcode)
@@ -540,7 +498,7 @@ int drm_ioctl(struct inode *inode, struct file *filp,
EXPORT_SYMBOL(drm_ioctl);
-drm_local_map_t *drm_getsarea(struct drm_device *dev)
+struct drm_local_map *drm_getsarea(struct drm_device *dev)
{
struct drm_map_list *entry;
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index a839a28d8ee..ca9c6165671 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -125,10 +125,8 @@ static bool edid_is_valid(struct edid *edid)
DRM_ERROR("EDID has major version %d, instead of 1\n", edid->version);
goto bad;
}
- if (edid->revision > 3) {
- DRM_ERROR("EDID has minor version %d, which is not between 0-3\n", edid->revision);
- goto bad;
- }
+ if (edid->revision > 4)
+ DRM_DEBUG("EDID minor > 4, assuming backward compatibility\n");
for (i = 0; i < EDID_LENGTH; i++)
csum += raw_edid[i];
@@ -162,7 +160,7 @@ static bool edid_vendor(struct edid *edid, char *vendor)
edid_vendor[0] = ((edid->mfg_id[0] & 0x7c) >> 2) + '@';
edid_vendor[1] = (((edid->mfg_id[0] & 0x3) << 3) |
((edid->mfg_id[1] & 0xe0) >> 5)) + '@';
- edid_vendor[2] = (edid->mfg_id[2] & 0x1f) + '@';
+ edid_vendor[2] = (edid->mfg_id[1] & 0x1f) + '@';
return !strncmp(edid_vendor, vendor, 3);
}
@@ -550,11 +548,20 @@ static int add_detailed_info(struct drm_connector *connector,
}
#define DDC_ADDR 0x50
-
-unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter)
+/**
+ * Get EDID information via I2C.
+ *
+ * \param adapter : i2c device adaptor
+ * \param buf : EDID data buffer to be filled
+ * \param len : EDID data buffer length
+ * \return 0 on success or -1 on failure.
+ *
+ * Try to fetch EDID information by calling i2c driver function.
+ */
+int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
+ unsigned char *buf, int len)
{
unsigned char start = 0x0;
- unsigned char *buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
struct i2c_msg msgs[] = {
{
.addr = DDC_ADDR,
@@ -564,31 +571,36 @@ unsigned char *drm_do_probe_ddc_edid(struct i2c_adapter *adapter)
}, {
.addr = DDC_ADDR,
.flags = I2C_M_RD,
- .len = EDID_LENGTH,
+ .len = len,
.buf = buf,
}
};
- if (!buf) {
- dev_warn(&adapter->dev, "unable to allocate memory for EDID "
- "block.\n");
- return NULL;
- }
-
if (i2c_transfer(adapter, msgs, 2) == 2)
- return buf;
+ return 0;
dev_info(&adapter->dev, "unable to read EDID block.\n");
- kfree(buf);
- return NULL;
+ return -1;
}
EXPORT_SYMBOL(drm_do_probe_ddc_edid);
-static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
+/**
+ * Get EDID information.
+ *
+ * \param adapter : i2c device adaptor.
+ * \param buf : EDID data buffer to be filled
+ * \param len : EDID data buffer length
+ * \return 0 on success or -1 on failure.
+ *
+ * Initialize DDC, then fetch EDID information
+ * by calling drm_do_probe_ddc_edid function.
+ */
+static int drm_ddc_read(struct i2c_adapter *adapter,
+ unsigned char *buf, int len)
{
struct i2c_algo_bit_data *algo_data = adapter->algo_data;
- unsigned char *edid = NULL;
int i, j;
+ int ret = -1;
algo_data->setscl(algo_data->data, 1);
@@ -616,7 +628,7 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
msleep(15);
/* Do the real work */
- edid = drm_do_probe_ddc_edid(adapter);
+ ret = drm_do_probe_ddc_edid(adapter, buf, len);
algo_data->setsda(algo_data->data, 0);
algo_data->setscl(algo_data->data, 0);
msleep(15);
@@ -632,7 +644,7 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
msleep(15);
algo_data->setscl(algo_data->data, 0);
algo_data->setsda(algo_data->data, 0);
- if (edid)
+ if (ret == 0)
break;
}
/* Release the DDC lines when done or the Apple Cinema HD display
@@ -641,9 +653,31 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
algo_data->setsda(algo_data->data, 1);
algo_data->setscl(algo_data->data, 1);
- return edid;
+ return ret;
}
+static int drm_ddc_read_edid(struct drm_connector *connector,
+ struct i2c_adapter *adapter,
+ char *buf, int len)
+{
+ int ret;
+
+ ret = drm_ddc_read(adapter, buf, len);
+ if (ret != 0) {
+ dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
+ drm_get_connector_name(connector));
+ goto end;
+ }
+ if (!edid_is_valid((struct edid *)buf)) {
+ dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+ drm_get_connector_name(connector));
+ ret = -1;
+ }
+end:
+ return ret;
+}
+
+#define MAX_EDID_EXT_NUM 4
/**
* drm_get_edid - get EDID data, if available
* @connector: connector we're probing
@@ -656,27 +690,118 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter)
{
+ int ret;
struct edid *edid;
- edid = (struct edid *)drm_ddc_read(adapter);
- if (!edid) {
- dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
- drm_get_connector_name(connector));
- return NULL;
+ edid = kmalloc(EDID_LENGTH * (MAX_EDID_EXT_NUM + 1),
+ GFP_KERNEL);
+ if (edid == NULL) {
+ dev_warn(&connector->dev->pdev->dev,
+ "Failed to allocate EDID\n");
+ goto end;
}
- if (!edid_is_valid(edid)) {
- dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
- drm_get_connector_name(connector));
- kfree(edid);
- return NULL;
+
+ /* Read first EDID block */
+ ret = drm_ddc_read_edid(connector, adapter,
+ (unsigned char *)edid, EDID_LENGTH);
+ if (ret != 0)
+ goto clean_up;
+
+ /* There are EDID extensions to be read */
+ if (edid->extensions != 0) {
+ int edid_ext_num = edid->extensions;
+
+ if (edid_ext_num > MAX_EDID_EXT_NUM) {
+ dev_warn(&connector->dev->pdev->dev,
+ "The number of extension(%d) is "
+ "over max (%d), actually read number (%d)\n",
+ edid_ext_num, MAX_EDID_EXT_NUM,
+ MAX_EDID_EXT_NUM);
+ /* Reset EDID extension number to be read */
+ edid_ext_num = MAX_EDID_EXT_NUM;
+ }
+ /* Read EDID including extensions too */
+ ret = drm_ddc_read_edid(connector, adapter, (char *)edid,
+ EDID_LENGTH * (edid_ext_num + 1));
+ if (ret != 0)
+ goto clean_up;
+
}
connector->display_info.raw_edid = (char *)edid;
+ goto end;
+clean_up:
+ kfree(edid);
+ edid = NULL;
+end:
return edid;
+
}
EXPORT_SYMBOL(drm_get_edid);
+#define HDMI_IDENTIFIER 0x000C03
+#define VENDOR_BLOCK 0x03
+/**
+ * drm_detect_hdmi_monitor - detect whether monitor is hdmi.
+ * @edid: monitor EDID information
+ *
+ * Parse the CEA extension according to CEA-861-B.
+ * Return true if HDMI, false if not or unknown.
+ */
+bool drm_detect_hdmi_monitor(struct edid *edid)
+{
+ char *edid_ext = NULL;
+ int i, hdmi_id, edid_ext_num;
+ int start_offset, end_offset;
+ bool is_hdmi = false;
+
+ /* No EDID or EDID extensions */
+ if (edid == NULL || edid->extensions == 0)
+ goto end;
+
+ /* Chose real EDID extension number */
+ edid_ext_num = edid->extensions > MAX_EDID_EXT_NUM ?
+ MAX_EDID_EXT_NUM : edid->extensions;
+
+ /* Find CEA extension */
+ for (i = 0; i < edid_ext_num; i++) {
+ edid_ext = (char *)edid + EDID_LENGTH * (i + 1);
+ /* This block is CEA extension */
+ if (edid_ext[0] == 0x02)
+ break;
+ }
+
+ if (i == edid_ext_num)
+ goto end;
+
+ /* Data block offset in CEA extension block */
+ start_offset = 4;
+ end_offset = edid_ext[2];
+
+ /*
+ * Because HDMI identifier is in Vendor Specific Block,
+ * search it from all data blocks of CEA extension.
+ */
+ for (i = start_offset; i < end_offset;
+ /* Increased by data block len */
+ i += ((edid_ext[i] & 0x1f) + 1)) {
+ /* Find vendor specific block */
+ if ((edid_ext[i] >> 5) == VENDOR_BLOCK) {
+ hdmi_id = edid_ext[i + 1] | (edid_ext[i + 2] << 8) |
+ edid_ext[i + 3] << 16;
+ /* Find HDMI identifier */
+ if (hdmi_id == HDMI_IDENTIFIER)
+ is_hdmi = true;
+ break;
+ }
+ }
+
+end:
+ return is_hdmi;
+}
+EXPORT_SYMBOL(drm_detect_hdmi_monitor);
+
/**
* drm_add_edid_modes - add modes from EDID data, if available
* @connector: connector we're probing
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index e13cb62bbae..09a3571c990 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -274,6 +274,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
/* create a new master */
priv->minor->master = drm_master_create(priv->minor);
if (!priv->minor->master) {
+ mutex_unlock(&dev->struct_mutex);
ret = -ENOMEM;
goto out_free;
}
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 88d3368ffdd..4984aa89cf3 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -502,10 +502,9 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_gem_object *obj;
struct drm_hash_item *hash;
- unsigned long prot;
int ret = 0;
mutex_lock(&dev->struct_mutex);
@@ -538,11 +537,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_ops = obj->dev->driver->gem_vm_ops;
vma->vm_private_data = map->handle;
/* FIXME: use pgprot_writecombine when available */
- prot = pgprot_val(vma->vm_page_prot);
-#ifdef CONFIG_X86
- prot |= _PAGE_CACHE_WC;
-#endif
- vma->vm_page_prot = __pgprot(prot);
+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
/* Take a ref for this mapping of the object, so that the fault
* handler can dereference the mmap offset's pointer to the object.
diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
index 1b699768ccf..f0f6c6b93f3 100644
--- a/drivers/gpu/drm/drm_info.c
+++ b/drivers/gpu/drm/drm_info.c
@@ -72,7 +72,7 @@ int drm_vm_info(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct drm_device *dev = node->minor->dev;
- struct drm_map *map;
+ struct drm_local_map *map;
struct drm_map_list *r_list;
/* Hardcoded from _DRM_FRAME_BUFFER,
@@ -94,9 +94,9 @@ int drm_vm_info(struct seq_file *m, void *data)
else
type = types[map->type];
- seq_printf(m, "%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
+ seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i,
- map->offset,
+ (unsigned long long)map->offset,
map->size, type, map->flags,
(unsigned long) r_list->user_token);
if (map->mtrr < 0)
diff --git a/drivers/gpu/drm/drm_ioc32.c b/drivers/gpu/drm/drm_ioc32.c
index 920b72fbc95..282d9fdf9f4 100644
--- a/drivers/gpu/drm/drm_ioc32.c
+++ b/drivers/gpu/drm/drm_ioc32.c
@@ -954,6 +954,7 @@ static int compat_drm_sg_free(struct file *file, unsigned int cmd,
DRM_IOCTL_SG_FREE, (unsigned long)request);
}
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
typedef struct drm_update_draw32 {
drm_drawable_t handle;
unsigned int type;
@@ -984,6 +985,7 @@ static int compat_drm_update_draw(struct file *file, unsigned int cmd,
DRM_IOCTL_UPDATE_DRAW, (unsigned long)request);
return err;
}
+#endif
struct drm_wait_vblank_request32 {
enum drm_vblank_seq_type type;
@@ -1066,7 +1068,9 @@ drm_ioctl_compat_t *drm_compat_ioctls[] = {
#endif
[DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
[DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
+#if defined(CONFIG_X86) || defined(CONFIG_IA64)
[DRM_IOCTL_NR(DRM_IOCTL_UPDATE_DRAW32)] = compat_drm_update_draw,
+#endif
[DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
};
diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
index bcc869bc409..0c707f533ea 100644
--- a/drivers/gpu/drm/drm_memory.c
+++ b/drivers/gpu/drm/drm_memory.c
@@ -159,7 +159,7 @@ static inline void *agp_remap(unsigned long offset, unsigned long size,
#endif /* debug_memory */
-void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremap(struct drm_local_map *map, struct drm_device *dev)
{
if (drm_core_has_AGP(dev) &&
dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
@@ -169,7 +169,7 @@ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
}
EXPORT_SYMBOL(drm_core_ioremap);
-void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremap_wc(struct drm_local_map *map, struct drm_device *dev)
{
if (drm_core_has_AGP(dev) &&
dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
@@ -179,7 +179,7 @@ void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev)
}
EXPORT_SYMBOL(drm_core_ioremap_wc);
-void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
+void drm_core_ioremapfree(struct drm_local_map *map, struct drm_device *dev)
{
if (!map->handle || !map->size)
return;
diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
index 9b3c5af61e9..bae5391165a 100644
--- a/drivers/gpu/drm/drm_proc.c
+++ b/drivers/gpu/drm/drm_proc.c
@@ -40,7 +40,6 @@
#include <linux/seq_file.h>
#include "drmP.h"
-
/***************************************************
* Initialization, etc.
**************************************************/
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index 48f33be8fd0..d009661781b 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -381,6 +381,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
}
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ pci_set_drvdata(pdev, dev);
ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
if (ret)
goto err_g2;
@@ -404,9 +405,9 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
list_add_tail(&dev->driver_item, &driver->device_list);
- DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
+ DRM_INFO("Initialized %s %d.%d.%d %s for %s on minor %d\n",
driver->name, driver->major, driver->minor, driver->patchlevel,
- driver->date, dev->primary->index);
+ driver->date, pci_name(pdev), dev->primary->index);
return 0;
@@ -418,29 +419,7 @@ err_g1:
drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
return ret;
}
-
-/**
- * Put a device minor number.
- *
- * \param dev device data structure
- * \return always zero
- *
- * Cleans up the proc resources. If it is the last minor then release the foreign
- * "drm" data, otherwise unregisters the "drm" data, frees the dev list and
- * unregisters the character device.
- */
-int drm_put_dev(struct drm_device * dev)
-{
- DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name);
-
- if (dev->devname) {
- drm_free(dev->devname, strlen(dev->devname) + 1,
- DRM_MEM_DRIVER);
- dev->devname = NULL;
- }
- drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
- return 0;
-}
+EXPORT_SYMBOL(drm_get_dev);
/**
* Put a secondary minor number.
@@ -472,3 +451,67 @@ int drm_put_minor(struct drm_minor **minor_p)
*minor_p = NULL;
return 0;
}
+
+/**
+ * Called via drm_exit() at module unload time or when pci device is
+ * unplugged.
+ *
+ * Cleans up all DRM device, calling drm_lastclose().
+ *
+ * \sa drm_init
+ */
+void drm_put_dev(struct drm_device *dev)
+{
+ struct drm_driver *driver = dev->driver;
+ struct drm_map_list *r_list, *list_temp;
+
+ DRM_DEBUG("\n");
+
+ if (!dev) {
+ DRM_ERROR("cleanup called no dev\n");
+ return;
+ }
+
+ drm_vblank_cleanup(dev);
+
+ drm_lastclose(dev);
+
+ if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
+ dev->agp && dev->agp->agp_mtrr >= 0) {
+ int retval;
+ retval = mtrr_del(dev->agp->agp_mtrr,
+ dev->agp->agp_info.aper_base,
+ dev->agp->agp_info.aper_size * 1024 * 1024);
+ DRM_DEBUG("mtrr_del=%d\n", retval);
+ }
+
+ if (dev->driver->unload)
+ dev->driver->unload(dev);
+
+ if (drm_core_has_AGP(dev) && dev->agp) {
+ drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
+ dev->agp = NULL;
+ }
+
+ drm_ht_remove(&dev->map_hash);
+ drm_ctxbitmap_cleanup(dev);
+
+ list_for_each_entry_safe(r_list, list_temp, &dev->maplist, head)
+ drm_rmmap(dev, r_list->map);
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_put_minor(&dev->control);
+
+ if (driver->driver_features & DRIVER_GEM)
+ drm_gem_destroy(dev);
+
+ drm_put_minor(&dev->primary);
+
+ if (dev->devname) {
+ drm_free(dev->devname, strlen(dev->devname) + 1,
+ DRM_MEM_DRIVER);
+ dev->devname = NULL;
+ }
+ drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
+}
+EXPORT_SYMBOL(drm_put_dev);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 186d08159d4..bc0c6849360 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -35,7 +35,9 @@ static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
struct drm_minor *drm_minor = to_drm_minor(dev);
struct drm_device *drm_dev = drm_minor->dev;
- if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->suspend)
+ if (drm_minor->type == DRM_MINOR_LEGACY &&
+ !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+ drm_dev->driver->suspend)
return drm_dev->driver->suspend(drm_dev, state);
return 0;
@@ -53,7 +55,9 @@ static int drm_sysfs_resume(struct device *dev)
struct drm_minor *drm_minor = to_drm_minor(dev);
struct drm_device *drm_dev = drm_minor->dev;
- if (drm_minor->type == DRM_MINOR_LEGACY && drm_dev->driver->resume)
+ if (drm_minor->type == DRM_MINOR_LEGACY &&
+ !drm_core_check_feature(drm_dev, DRIVER_MODESET) &&
+ drm_dev->driver->resume)
return drm_dev->driver->resume(drm_dev);
return 0;
@@ -118,20 +122,6 @@ void drm_sysfs_destroy(void)
class_destroy(drm_class);
}
-static ssize_t show_dri(struct device *device, struct device_attribute *attr,
- char *buf)
-{
- struct drm_minor *drm_minor = to_drm_minor(device);
- struct drm_device *drm_dev = drm_minor->dev;
- if (drm_dev->driver->dri_library_name)
- return drm_dev->driver->dri_library_name(drm_dev, buf);
- return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name);
-}
-
-static struct device_attribute device_attrs[] = {
- __ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
-};
-
/**
* drm_sysfs_device_release - do nothing
* @dev: Linux device
@@ -461,6 +451,7 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
kobject_uevent_env(&dev->primary->kdev.kobj, KOBJ_CHANGE, envp);
}
+EXPORT_SYMBOL(drm_sysfs_hotplug_event);
/**
* drm_sysfs_device_add - adds a class device to sysfs for a character driver
@@ -474,7 +465,6 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
int drm_sysfs_device_add(struct drm_minor *minor)
{
int err;
- int i, j;
char *minor_str;
minor->kdev.parent = &minor->dev->pdev->dev;
@@ -496,18 +486,8 @@ int drm_sysfs_device_add(struct drm_minor *minor)
goto err_out;
}
- for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
- err = device_create_file(&minor->kdev, &device_attrs[i]);
- if (err)
- goto err_out_files;
- }
-
return 0;
-err_out_files:
- if (i > 0)
- for (j = 0; j < i; j++)
- device_remove_file(&minor->kdev, &device_attrs[j]);
device_unregister(&minor->kdev);
err_out:
@@ -523,9 +503,5 @@ err_out:
*/
void drm_sysfs_device_remove(struct drm_minor *minor)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
- device_remove_file(&minor->kdev, &device_attrs[i]);
device_unregister(&minor->kdev);
}
diff --git a/drivers/gpu/drm/drm_vm.c b/drivers/gpu/drm/drm_vm.c
index 3ffae021d28..22f76567ac7 100644
--- a/drivers/gpu/drm/drm_vm.c
+++ b/drivers/gpu/drm/drm_vm.c
@@ -91,7 +91,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->minor->dev;
- struct drm_map *map = NULL;
+ struct drm_local_map *map = NULL;
struct drm_map_list *r_list;
struct drm_hash_item *hash;
@@ -115,9 +115,9 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
* Using vm_pgoff as a selector forces us to use this unusual
* addressing scheme.
*/
- unsigned long offset = (unsigned long)vmf->virtual_address -
- vma->vm_start;
- unsigned long baddr = map->offset + offset;
+ resource_size_t offset = (unsigned long)vmf->virtual_address -
+ vma->vm_start;
+ resource_size_t baddr = map->offset + offset;
struct drm_agp_mem *agpmem;
struct page *page;
@@ -149,8 +149,10 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
vmf->page = page;
DRM_DEBUG
- ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
- baddr, __va(agpmem->memory->memory[offset]), offset,
+ ("baddr = 0x%llx page = 0x%p, offset = 0x%llx, count=%d\n",
+ (unsigned long long)baddr,
+ __va(agpmem->memory->memory[offset]),
+ (unsigned long long)offset,
page_count(page));
return 0;
}
@@ -176,7 +178,7 @@ static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
*/
static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+ struct drm_local_map *map = vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;
@@ -209,7 +211,7 @@ static void drm_vm_shm_close(struct vm_area_struct *vma)
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_vma_entry *pt, *temp;
- struct drm_map *map;
+ struct drm_local_map *map;
struct drm_map_list *r_list;
int found_maps = 0;
@@ -322,7 +324,7 @@ static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
*/
static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- struct drm_map *map = (struct drm_map *) vma->vm_private_data;
+ struct drm_local_map *map = vma->vm_private_data;
struct drm_file *priv = vma->vm_file->private_data;
struct drm_device *dev = priv->minor->dev;
struct drm_sg_mem *entry = dev->sg;
@@ -512,14 +514,14 @@ static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
return 0;
}
-unsigned long drm_core_get_map_ofs(struct drm_map * map)
+resource_size_t drm_core_get_map_ofs(struct drm_local_map * map)
{
return map->offset;
}
EXPORT_SYMBOL(drm_core_get_map_ofs);
-unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
+resource_size_t drm_core_get_reg_ofs(struct drm_device *dev)
{
#ifdef __alpha__
return dev->hose->dense_mem_base - dev->hose->mem_space->start;
@@ -547,8 +549,8 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
{
struct drm_file *priv = filp->private_data;
struct drm_device *dev = priv->minor->dev;
- struct drm_map *map = NULL;
- unsigned long offset = 0;
+ struct drm_local_map *map = NULL;
+ resource_size_t offset = 0;
struct drm_hash_item *hash;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
@@ -623,9 +625,9 @@ int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
vma->vm_page_prot))
return -EAGAIN;
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
- " offset = 0x%lx\n",
+ " offset = 0x%llx\n",
map->type,
- vma->vm_start, vma->vm_end, map->offset + offset);
+ vma->vm_start, vma->vm_end, (unsigned long long)(map->offset + offset));
vma->vm_ops = &drm_vm_ops;
break;
case _DRM_CONSISTENT:
diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h
index 0118849a567..21e2691f28f 100644
--- a/drivers/gpu/drm/i810/i810_drv.h
+++ b/drivers/gpu/drm/i810/i810_drv.h
@@ -77,8 +77,8 @@ typedef struct _drm_i810_ring_buffer {
} drm_i810_ring_buffer_t;
typedef struct drm_i810_private {
- struct drm_map *sarea_map;
- struct drm_map *mmio_map;
+ struct drm_local_map *sarea_map;
+ struct drm_local_map *mmio_map;
drm_i810_sarea_t *sarea_priv;
drm_i810_ring_buffer_t ring;
diff --git a/drivers/gpu/drm/i830/i830_drv.h b/drivers/gpu/drm/i830/i830_drv.h
index b5bf8cc0fda..da82afe4ded 100644
--- a/drivers/gpu/drm/i830/i830_drv.h
+++ b/drivers/gpu/drm/i830/i830_drv.h
@@ -84,8 +84,8 @@ typedef struct _drm_i830_ring_buffer {
} drm_i830_ring_buffer_t;
typedef struct drm_i830_private {
- struct drm_map *sarea_map;
- struct drm_map *mmio_map;
+ struct drm_local_map *sarea_map;
+ struct drm_local_map *mmio_map;
drm_i830_sarea_t *sarea_priv;
drm_i830_ring_buffer_t ring;
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index a818b377e1f..a000cf02882 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -922,7 +922,7 @@ static int i915_probe_agp(struct drm_device *dev, unsigned long *aperture_size,
* Some of the preallocated space is taken by the GTT
* and popup. GTT is 1K per MB of aperture size, and popup is 4K.
*/
- if (IS_G4X(dev))
+ if (IS_G4X(dev) || IS_IGD(dev))
overhead = 4096;
else
overhead = (*aperture_size / 1024) + 4096;
@@ -1030,13 +1030,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
if (ret)
goto destroy_ringbuffer;
- /* FIXME: re-add hotplug support */
-#if 0
- ret = drm_hotplug_init(dev);
- if (ret)
- goto destroy_ringbuffer;
-#endif
-
/* Always safe in the mode setting case. */
/* FIXME: do pre/post-mode set stuff in core KMS code */
dev->vblank_disable_allowed = 1;
@@ -1049,7 +1042,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
intel_modeset_init(dev);
- drm_helper_initial_config(dev, false);
+ drm_helper_initial_config(dev);
return 0;
@@ -1099,7 +1092,7 @@ void i915_master_destroy(struct drm_device *dev, struct drm_master *master)
int i915_driver_load(struct drm_device *dev, unsigned long flags)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned long base, size;
+ resource_size_t base, size;
int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
/* i915 has 4 more counters */
@@ -1186,8 +1179,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);
- intel_opregion_init(dev);
-
spin_lock_init(&dev_priv->user_irq_lock);
dev_priv->user_irq_refcount = 0;
@@ -1206,6 +1197,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
}
}
+ /* Must be done after probing outputs */
+ intel_opregion_init(dev, 0);
+
return 0;
out_iomapfree:
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index dcb91f5df6e..6503e2210f6 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -42,6 +42,8 @@ module_param_named(modeset, i915_modeset, int, 0400);
unsigned int i915_fbpercrtc = 0;
module_param_named(fbpercrtc, i915_fbpercrtc, int, 0400);
+static struct drm_driver driver;
+
static struct pci_device_id pciidlist[] = {
i915_PCI_IDS
};
@@ -99,7 +101,7 @@ static int i915_resume(struct drm_device *dev)
i915_restore_state(dev);
- intel_opregion_init(dev);
+ intel_opregion_init(dev, 1);
/* KMS EnterVT equivalent */
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
@@ -117,6 +119,36 @@ static int i915_resume(struct drm_device *dev)
return ret;
}
+static int __devinit
+i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return drm_get_dev(pdev, ent, &driver);
+}
+
+static void
+i915_pci_remove(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ drm_put_dev(dev);
+}
+
+static int
+i915_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ return i915_suspend(dev, state);
+}
+
+static int
+i915_pci_resume(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ return i915_resume(dev);
+}
+
static struct vm_operations_struct i915_gem_vm_ops = {
.fault = i915_gem_fault,
.open = drm_gem_vm_open,
@@ -174,6 +206,12 @@ static struct drm_driver driver = {
.pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
+ .probe = i915_pci_probe,
+ .remove = i915_pci_remove,
+#ifdef CONFIG_PM
+ .resume = i915_pci_resume,
+ .suspend = i915_pci_suspend,
+#endif
},
.name = DRIVER_NAME,
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c1685d0c704..3750d800304 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -159,6 +159,9 @@ typedef struct drm_i915_private {
u32 irq_mask_reg;
u32 pipestat[2];
+ u32 hotplug_supported_mask;
+ struct work_struct hotplug_work;
+
int tex_lru_log_granularity;
int allow_batchbuffer;
struct mem_block *agp_heap;
@@ -297,6 +300,7 @@ typedef struct drm_i915_private {
*
* A reference is held on the buffer while on this list.
*/
+ spinlock_t active_list_lock;
struct list_head active_list;
/**
@@ -662,12 +666,12 @@ extern int i915_restore_state(struct drm_device *dev);
#ifdef CONFIG_ACPI
/* i915_opregion.c */
-extern int intel_opregion_init(struct drm_device *dev);
+extern int intel_opregion_init(struct drm_device *dev, int resume);
extern void intel_opregion_free(struct drm_device *dev);
extern void opregion_asle_intr(struct drm_device *dev);
extern void opregion_enable_asle(struct drm_device *dev);
#else
-static inline int intel_opregion_init(struct drm_device *dev) { return 0; }
+static inline int intel_opregion_init(struct drm_device *dev, int resume) { return 0; }
static inline void intel_opregion_free(struct drm_device *dev) { return; }
static inline void opregion_asle_intr(struct drm_device *dev) { return; }
static inline void opregion_enable_asle(struct drm_device *dev) { return; }
@@ -810,6 +814,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define HAS_128_BYTE_Y_TILING(dev) (IS_I9XX(dev) && !(IS_I915G(dev) || \
IS_I915GM(dev)))
#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev))
+#define I915_HAS_HOTPLUG(dev) (IS_I945G(dev) || IS_I945GM(dev) || IS_I965G(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index b52cba0f16d..1449b452cc6 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -446,13 +446,16 @@ fast_shmem_write(struct page **pages,
int length)
{
char __iomem *vaddr;
+ unsigned long unwritten;
vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT], KM_USER0);
if (vaddr == NULL)
return -ENOMEM;
- __copy_from_user_inatomic(vaddr + page_offset, data, length);
+ unwritten = __copy_from_user_inatomic(vaddr + page_offset, data, length);
kunmap_atomic(vaddr, KM_USER0);
+ if (unwritten)
+ return -EFAULT;
return 0;
}
@@ -1069,6 +1072,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
case -EAGAIN:
return VM_FAULT_OOM;
case -EFAULT:
+ case -EINVAL:
return VM_FAULT_SIGBUS;
default:
return VM_FAULT_NOPAGE;
@@ -1093,7 +1097,7 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj)
struct drm_gem_mm *mm = dev->mm_private;
struct drm_i915_gem_object *obj_priv = obj->driver_private;
struct drm_map_list *list;
- struct drm_map *map;
+ struct drm_local_map *map;
int ret = 0;
/* Set the object up for mmap'ing */
@@ -1321,8 +1325,10 @@ i915_gem_object_move_to_active(struct drm_gem_object *obj, uint32_t seqno)
obj_priv->active = 1;
}
/* Move from whatever list we were on to the tail of execution. */
+ spin_lock(&dev_priv->mm.active_list_lock);
list_move_tail(&obj_priv->list,
&dev_priv->mm.active_list);
+ spin_unlock(&dev_priv->mm.active_list_lock);
obj_priv->last_rendering_seqno = seqno;
}
@@ -1464,6 +1470,7 @@ i915_gem_retire_request(struct drm_device *dev,
/* Move any buffers on the active list that are no longer referenced
* by the ringbuffer to the flushing/inactive lists as appropriate.
*/
+ spin_lock(&dev_priv->mm.active_list_lock);
while (!list_empty(&dev_priv->mm.active_list)) {
struct drm_gem_object *obj;
struct drm_i915_gem_object *obj_priv;
@@ -1478,7 +1485,7 @@ i915_gem_retire_request(struct drm_device *dev,
* this seqno.
*/
if (obj_priv->last_rendering_seqno != request->seqno)
- return;
+ goto out;
#if WATCH_LRU
DRM_INFO("%s: retire %d moves to inactive list %p\n",
@@ -1490,6 +1497,8 @@ i915_gem_retire_request(struct drm_device *dev,
else
i915_gem_object_move_to_inactive(obj);
}
+out:
+ spin_unlock(&dev_priv->mm.active_list_lock);
}
/**
@@ -1987,20 +1996,23 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg)
int regnum = obj_priv->fence_reg;
uint32_t val;
uint32_t pitch_val;
+ uint32_t fence_size_bits;
- if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) ||
+ if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) ||
(obj_priv->gtt_offset & (obj->size - 1))) {
- WARN(1, "%s: object 0x%08x not 1M or size aligned\n",
+ WARN(1, "%s: object 0x%08x not 512K or size aligned\n",
__func__, obj_priv->gtt_offset);
return;
}
pitch_val = (obj_priv->stride / 128) - 1;
-
+ WARN_ON(pitch_val & ~0x0000000f);
val = obj_priv->gtt_offset;
if (obj_priv->tiling_mode == I915_TILING_Y)
val |= 1 << I830_FENCE_TILING_Y_SHIFT;
- val |= I830_FENCE_SIZE_BITS(obj->size);
+ fence_size_bits = I830_FENCE_SIZE_BITS(obj->size);
+ WARN_ON(fence_size_bits & ~0x00000f00);
+ val |= fence_size_bits;
val |= pitch_val << I830_FENCE_PITCH_SHIFT;
val |= I830_FENCE_REG_VALID;
@@ -2191,7 +2203,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
return -EBUSY;
if (alignment == 0)
alignment = i915_gem_get_gtt_alignment(obj);
- if (alignment & (PAGE_SIZE - 1)) {
+ if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) {
DRM_ERROR("Invalid object alignment requested %u\n", alignment);
return -EINVAL;
}
@@ -2208,15 +2220,20 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
}
}
if (obj_priv->gtt_space == NULL) {
+ bool lists_empty;
+
/* If the gtt is empty and we're still having trouble
* fitting our object in, we're out of memory.
*/
#if WATCH_LRU
DRM_INFO("%s: GTT full, evicting something\n", __func__);
#endif
- if (list_empty(&dev_priv->mm.inactive_list) &&
- list_empty(&dev_priv->mm.flushing_list) &&
- list_empty(&dev_priv->mm.active_list)) {
+ spin_lock(&dev_priv->mm.active_list_lock);
+ lists_empty = (list_empty(&dev_priv->mm.inactive_list) &&
+ list_empty(&dev_priv->mm.flushing_list) &&
+ list_empty(&dev_priv->mm.active_list));
+ spin_unlock(&dev_priv->mm.active_list_lock);
+ if (lists_empty) {
DRM_ERROR("GTT full, but LRU list empty\n");
return -ENOMEM;
}
@@ -3672,6 +3689,7 @@ i915_gem_idle(struct drm_device *dev)
i915_gem_retire_requests(dev);
+ spin_lock(&dev_priv->mm.active_list_lock);
if (!dev_priv->mm.wedged) {
/* Active and flushing should now be empty as we've
* waited for a sequence higher than any pending execbuffer
@@ -3698,6 +3716,7 @@ i915_gem_idle(struct drm_device *dev)
obj_priv->obj->write_domain &= ~I915_GEM_GPU_DOMAINS;
i915_gem_object_move_to_inactive(obj_priv->obj);
}
+ spin_unlock(&dev_priv->mm.active_list_lock);
while (!list_empty(&dev_priv->mm.flushing_list)) {
struct drm_i915_gem_object *obj_priv;
@@ -3946,7 +3965,10 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
if (ret != 0)
return ret;
+ spin_lock(&dev_priv->mm.active_list_lock);
BUG_ON(!list_empty(&dev_priv->mm.active_list));
+ spin_unlock(&dev_priv->mm.active_list_lock);
+
BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
BUG_ON(!list_empty(&dev_priv->mm.request_list));
@@ -3990,6 +4012,7 @@ i915_gem_load(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
+ spin_lock_init(&dev_priv->mm.active_list_lock);
INIT_LIST_HEAD(&dev_priv->mm.active_list);
INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
index 131c088f8c8..8d0b943e2c5 100644
--- a/drivers/gpu/drm/i915/i915_gem_debug.c
+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
@@ -105,12 +105,14 @@ i915_dump_lru(struct drm_device *dev, const char *where)
struct drm_i915_gem_object *obj_priv;
DRM_INFO("active list %s {\n", where);
+ spin_lock(&dev_priv->mm.active_list_lock);
list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
list)
{
DRM_INFO(" %p: %08x\n", obj_priv,
obj_priv->last_rendering_seqno);
}
+ spin_unlock(&dev_priv->mm.active_list_lock);
DRM_INFO("}\n");
DRM_INFO("flushing list %s {\n", where);
list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
diff --git a/drivers/gpu/drm/i915/i915_gem_debugfs.c b/drivers/gpu/drm/i915/i915_gem_debugfs.c
index 455ec970b38..a1ac0c5e730 100644
--- a/drivers/gpu/drm/i915/i915_gem_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_gem_debugfs.c
@@ -69,10 +69,13 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
struct drm_device *dev = node->minor->dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj_priv;
+ spinlock_t *lock = NULL;
switch (list) {
case ACTIVE_LIST:
seq_printf(m, "Active:\n");
+ lock = &dev_priv->mm.active_list_lock;
+ spin_lock(lock);
head = &dev_priv->mm.active_list;
break;
case INACTIVE_LIST:
@@ -104,6 +107,9 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data)
seq_printf(m, " (fence: %d\n", obj_priv->fence_reg);
seq_printf(m, "\n");
}
+
+ if (lock)
+ spin_unlock(lock);
return 0;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
index 4cce1aef438..6be3f927c86 100644
--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
@@ -216,6 +216,22 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode)
else
tile_width = 512;
+ /* check maximum stride & object size */
+ if (IS_I965G(dev)) {
+ /* i965 stores the end address of the gtt mapping in the fence
+ * reg, so dont bother to check the size */
+ if (stride / 128 > I965_FENCE_MAX_PITCH_VAL)
+ return false;
+ } else if (IS_I9XX(dev)) {
+ if (stride / tile_width > I830_FENCE_MAX_PITCH_VAL ||
+ size > (I830_FENCE_MAX_SIZE_VAL << 20))
+ return false;
+ } else {
+ if (stride / 128 > I830_FENCE_MAX_PITCH_VAL ||
+ size > (I830_FENCE_MAX_SIZE_VAL << 19))
+ return false;
+ }
+
/* 965+ just needs multiples of tile width */
if (IS_I965G(dev)) {
if (stride & (tile_width - 1))
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 87b6b603469..ee7ce7b78cf 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -48,10 +48,6 @@
/** Interrupts that we mask and unmask at runtime. */
#define I915_INTERRUPT_ENABLE_VAR (I915_USER_INTERRUPT)
-/** These are all of the interrupts used by the driver */
-#define I915_INTERRUPT_ENABLE_MASK (I915_INTERRUPT_ENABLE_FIX | \
- I915_INTERRUPT_ENABLE_VAR)
-
#define I915_PIPE_VBLANK_STATUS (PIPE_START_VBLANK_INTERRUPT_STATUS |\
PIPE_VBLANK_INTERRUPT_STATUS)
@@ -187,6 +183,19 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
return I915_READ(reg);
}
+/*
+ * Handle hotplug events outside the interrupt handler proper.
+ */
+static void i915_hotplug_work_func(struct work_struct *work)
+{
+ drm_i915_private_t *dev_priv = container_of(work, drm_i915_private_t,
+ hotplug_work);
+ struct drm_device *dev = dev_priv->dev;
+
+ /* Just fire off a uevent and let userspace tell us what to do */
+ drm_sysfs_hotplug_event(dev);
+}
+
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -244,6 +253,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
ret = IRQ_HANDLED;
+ /* Consume port. Then clear IIR or we'll miss events */
+ if ((I915_HAS_HOTPLUG(dev)) &&
+ (iir & I915_DISPLAY_PORT_INTERRUPT)) {
+ u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
+
+ DRM_DEBUG("hotplug event received, stat 0x%08x\n",
+ hotplug_status);
+ if (hotplug_status & dev_priv->hotplug_supported_mask)
+ schedule_work(&dev_priv->hotplug_work);
+
+ I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
+ I915_READ(PORT_HOTPLUG_STAT);
+ }
+
I915_WRITE(IIR, iir);
new_iir = I915_READ(IIR); /* Flush posted writes */
@@ -528,17 +551,24 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
atomic_set(&dev_priv->irq_received, 0);
+ if (I915_HAS_HOTPLUG(dev)) {
+ I915_WRITE(PORT_HOTPLUG_EN, 0);
+ I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+ }
+
I915_WRITE(HWSTAM, 0xeffe);
I915_WRITE(PIPEASTAT, 0);
I915_WRITE(PIPEBSTAT, 0);
I915_WRITE(IMR, 0xffffffff);
I915_WRITE(IER, 0x0);
(void) I915_READ(IER);
+ INIT_WORK(&dev_priv->hotplug_work, i915_hotplug_work_func);
}
int i915_driver_irq_postinstall(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
+ u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR;
dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
@@ -550,13 +580,35 @@ int i915_driver_irq_postinstall(struct drm_device *dev)
dev_priv->pipestat[0] = 0;
dev_priv->pipestat[1] = 0;
+ if (I915_HAS_HOTPLUG(dev)) {
+ u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN);
+
+ /* Leave other bits alone */
+ hotplug_en |= HOTPLUG_EN_MASK;
+ I915_WRITE(PORT_HOTPLUG_EN, hotplug_en);
+
+ dev_priv->hotplug_supported_mask = CRT_HOTPLUG_INT_STATUS |
+ TV_HOTPLUG_INT_STATUS | SDVOC_HOTPLUG_INT_STATUS |
+ SDVOB_HOTPLUG_INT_STATUS;
+ if (IS_G4X(dev)) {
+ dev_priv->hotplug_supported_mask |=
+ HDMIB_HOTPLUG_INT_STATUS |
+ HDMIC_HOTPLUG_INT_STATUS |
+ HDMID_HOTPLUG_INT_STATUS;
+ }
+ /* Enable in IER... */
+ enable_mask |= I915_DISPLAY_PORT_INTERRUPT;
+ /* and unmask in IMR */
+ i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT);
+ }
+
/* Disable pipe interrupt enables, clear pending pipe status */
I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
/* Clear pending interrupt status */
I915_WRITE(IIR, I915_READ(IIR));
- I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
+ I915_WRITE(IER, enable_mask);
I915_WRITE(IMR, dev_priv->irq_mask_reg);
(void) I915_READ(IER);
@@ -575,6 +627,11 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
dev_priv->vblank_pipe = 0;
+ if (I915_HAS_HOTPLUG(dev)) {
+ I915_WRITE(PORT_HOTPLUG_EN, 0);
+ I915_WRITE(PORT_HOTPLUG_STAT, I915_READ(PORT_HOTPLUG_STAT));
+ }
+
I915_WRITE(HWSTAM, 0xffffffff);
I915_WRITE(PIPEASTAT, 0);
I915_WRITE(PIPEBSTAT, 0);
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
index ff012835a38..69427722d20 100644
--- a/drivers/gpu/drm/i915/i915_opregion.c
+++ b/drivers/gpu/drm/i915/i915_opregion.c
@@ -26,6 +26,7 @@
*/
#include <linux/acpi.h>
+#include <acpi/video.h>
#include "drmP.h"
#include "i915_drm.h"
@@ -136,6 +137,12 @@ struct opregion_asle {
#define ASLE_CBLV_VALID (1<<31)
+#define ACPI_OTHER_OUTPUT (0<<8)
+#define ACPI_VGA_OUTPUT (1<<8)
+#define ACPI_TV_OUTPUT (2<<8)
+#define ACPI_DIGITAL_OUTPUT (3<<8)
+#define ACPI_LVDS_OUTPUT (4<<8)
+
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
@@ -282,7 +289,58 @@ static struct notifier_block intel_opregion_notifier = {
.notifier_call = intel_opregion_video_event,
};
-int intel_opregion_init(struct drm_device *dev)
+/*
+ * Initialise the DIDL field in opregion. This passes a list of devices to
+ * the firmware. Values are defined by section B.4.2 of the ACPI specification
+ * (version 3)
+ */
+
+static void intel_didl_outputs(struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = dev->dev_private;
+ struct intel_opregion *opregion = &dev_priv->opregion;
+ struct drm_connector *connector;
+ int i = 0;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ int output_type = ACPI_OTHER_OUTPUT;
+ if (i >= 8) {
+ dev_printk (KERN_ERR, &dev->pdev->dev,
+ "More than 8 outputs detected\n");
+ return;
+ }
+ switch (connector->connector_type) {
+ case DRM_MODE_CONNECTOR_VGA:
+ case DRM_MODE_CONNECTOR_DVIA:
+ output_type = ACPI_VGA_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_Composite:
+ case DRM_MODE_CONNECTOR_SVIDEO:
+ case DRM_MODE_CONNECTOR_Component:
+ case DRM_MODE_CONNECTOR_9PinDIN:
+ output_type = ACPI_TV_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_DVII:
+ case DRM_MODE_CONNECTOR_DVID:
+ case DRM_MODE_CONNECTOR_DisplayPort:
+ case DRM_MODE_CONNECTOR_HDMIA:
+ case DRM_MODE_CONNECTOR_HDMIB:
+ output_type = ACPI_DIGITAL_OUTPUT;
+ break;
+ case DRM_MODE_CONNECTOR_LVDS:
+ output_type = ACPI_LVDS_OUTPUT;
+ break;
+ }
+ opregion->acpi->didl[i] |= (1<<31) | output_type | i;
+ i++;
+ }
+
+ /* If fewer than 8 outputs, the list must be null terminated */
+ if (i < 8)
+ opregion->acpi->didl[i] = 0;
+}
+
+int intel_opregion_init(struct drm_device *dev, int resume)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_opregion *opregion = &dev_priv->opregion;
@@ -312,6 +370,11 @@ int intel_opregion_init(struct drm_device *dev)
if (mboxes & MBOX_ACPI) {
DRM_DEBUG("Public ACPI methods supported\n");
opregion->acpi = base + OPREGION_ACPI_OFFSET;
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ intel_didl_outputs(dev);
+ if (!resume)
+ acpi_video_register();
+ }
} else {
DRM_DEBUG("Public ACPI methods not supported\n");
err = -ENOTSUPP;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 377cc588f5e..e805b590ae7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -190,6 +190,8 @@
#define I830_FENCE_SIZE_BITS(size) ((ffs((size) >> 19) - 1) << 8)
#define I830_FENCE_PITCH_SHIFT 4
#define I830_FENCE_REG_VALID (1<<0)
+#define I830_FENCE_MAX_PITCH_VAL 0x10
+#define I830_FENCE_MAX_SIZE_VAL (1<<8)
#define I915_FENCE_START_MASK 0x0ff00000
#define I915_FENCE_SIZE_BITS(size) ((ffs((size) >> 20) - 1) << 8)
@@ -198,6 +200,7 @@
#define I965_FENCE_PITCH_SHIFT 2
#define I965_FENCE_TILING_Y_SHIFT 1
#define I965_FENCE_REG_VALID (1<<0)
+#define I965_FENCE_MAX_PITCH_VAL 0x0400
/*
* Instruction and interrupt control regs
@@ -648,6 +651,14 @@
#define CRT_HOTPLUG_DETECT_VOLTAGE_325MV (0 << 2)
#define CRT_HOTPLUG_DETECT_VOLTAGE_475MV (1 << 2)
#define CRT_HOTPLUG_MASK (0x3fc) /* Bits 9-2 */
+#define CRT_FORCE_HOTPLUG_MASK 0xfffffe1f
+#define HOTPLUG_EN_MASK (HDMIB_HOTPLUG_INT_EN | \
+ HDMIC_HOTPLUG_INT_EN | \
+ HDMID_HOTPLUG_INT_EN | \
+ SDVOB_HOTPLUG_INT_EN | \
+ SDVOC_HOTPLUG_INT_EN | \
+ TV_HOTPLUG_INT_EN | \
+ CRT_HOTPLUG_INT_EN)
#define PORT_HOTPLUG_STAT 0x61114
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c
index 2b6d44381c3..9bdd959260a 100644
--- a/drivers/gpu/drm/i915/intel_crt.c
+++ b/drivers/gpu/drm/i915/intel_crt.c
@@ -41,7 +41,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
temp = I915_READ(ADPA);
temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);
- temp &= ~ADPA_DAC_ENABLE;
+ temp |= ADPA_DAC_ENABLE;
switch(mode) {
case DRM_MODE_DPMS_ON:
@@ -158,7 +158,7 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector)
else
tries = 1;
hotplug_en = I915_READ(PORT_HOTPLUG_EN);
- hotplug_en &= ~(CRT_HOTPLUG_MASK);
+ hotplug_en &= CRT_FORCE_HOTPLUG_MASK;
hotplug_en |= CRT_HOTPLUG_FORCE_DETECT;
if (IS_GM45(dev))
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index d9c50ff94d7..64773ce5296 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -636,7 +636,7 @@ void
intel_wait_for_vblank(struct drm_device *dev)
{
/* Wait for 20ms, i.e. one cycle at 50hz. */
- udelay(20000);
+ mdelay(20);
}
static int
@@ -1106,6 +1106,26 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc,
return -EINVAL;
}
+ /* SDVO TV has fixed PLL values depend on its clock range,
+ this mirrors vbios setting. */
+ if (is_sdvo && is_tv) {
+ if (adjusted_mode->clock >= 100000
+ && adjusted_mode->clock < 140500) {
+ clock.p1 = 2;
+ clock.p2 = 10;
+ clock.n = 3;
+ clock.m1 = 16;
+ clock.m2 = 8;
+ } else if (adjusted_mode->clock >= 140500
+ && adjusted_mode->clock <= 200000) {
+ clock.p1 = 1;
+ clock.p2 = 10;
+ clock.n = 6;
+ clock.m1 = 12;
+ clock.m2 = 8;
+ }
+ }
+
if (IS_IGD(dev))
fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2;
else
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c
index e42019e5d66..07d7ec97616 100644
--- a/drivers/gpu/drm/i915/intel_modes.c
+++ b/drivers/gpu/drm/i915/intel_modes.c
@@ -76,6 +76,7 @@ int intel_ddc_get_modes(struct intel_output *intel_output)
drm_mode_connector_update_edid_property(&intel_output->base,
edid);
ret = drm_add_edid_modes(&intel_output->base, edid);
+ intel_output->base.display_info.raw_edid = NULL;
kfree(edid);
}
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c
index fbe6f3931b1..7b31f55f55c 100644
--- a/drivers/gpu/drm/i915/intel_sdvo.c
+++ b/drivers/gpu/drm/i915/intel_sdvo.c
@@ -273,20 +273,20 @@ static void intel_sdvo_debug_write(struct intel_output *intel_output, u8 cmd,
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int i;
- DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
+ printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
for (i = 0; i < args_len; i++)
- printk("%02X ", ((u8 *)args)[i]);
+ printk(KERN_DEBUG "%02X ", ((u8 *)args)[i]);
for (; i < 8; i++)
- printk(" ");
+ printk(KERN_DEBUG " ");
for (i = 0; i < sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); i++) {
if (cmd == sdvo_cmd_names[i].cmd) {
- printk("(%s)", sdvo_cmd_names[i].name);
+ printk(KERN_DEBUG "(%s)", sdvo_cmd_names[i].name);
break;
}
}
if (i == sizeof(sdvo_cmd_names)/ sizeof(sdvo_cmd_names[0]))
- printk("(%02X)",cmd);
- printk("\n");
+ printk(KERN_DEBUG "(%02X)", cmd);
+ printk(KERN_DEBUG "\n");
}
#else
#define intel_sdvo_debug_write(o, c, a, l)
@@ -323,17 +323,18 @@ static void intel_sdvo_debug_response(struct intel_output *intel_output,
u8 status)
{
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
+ int i;
- DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
+ printk(KERN_DEBUG "%s: R: ", SDVO_NAME(sdvo_priv));
for (i = 0; i < response_len; i++)
- printk("%02X ", ((u8 *)response)[i]);
+ printk(KERN_DEBUG "%02X ", ((u8 *)response)[i]);
for (; i < 8; i++)
- printk(" ");
+ printk(KERN_DEBUG " ");
if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
- printk("(%s)", cmd_status_names[status]);
+ printk(KERN_DEBUG "(%s)", cmd_status_names[status]);
else
- printk("(??? %d)", status);
- printk("\n");
+ printk(KERN_DEBUG "(??? %d)", status);
+ printk(KERN_DEBUG "\n");
}
#else
#define intel_sdvo_debug_response(o, r, l, s)
@@ -588,9 +589,12 @@ intel_sdvo_create_preferred_input_timing(struct intel_output *output,
struct intel_sdvo_preferred_input_timing_args args;
uint8_t status;
+ memset(&args, 0, sizeof(args));
args.clock = clock;
args.width = width;
args.height = height;
+ args.interlace = 0;
+ args.scaled = 0;
intel_sdvo_write_cmd(output, SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING,
&args, sizeof(args));
status = intel_sdvo_read_response(output, NULL, 0);
@@ -683,7 +687,7 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
dtd->part1.v_high = (((height >> 8) & 0xf) << 4) |
((v_blank_len >> 8) & 0xf);
- dtd->part2.h_sync_off = h_sync_offset;
+ dtd->part2.h_sync_off = h_sync_offset & 0xff;
dtd->part2.h_sync_width = h_sync_len & 0xff;
dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 |
(v_sync_len & 0xf);
@@ -705,27 +709,10 @@ static void intel_sdvo_get_dtd_from_mode(struct intel_sdvo_dtd *dtd,
static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
struct intel_sdvo_dtd *dtd)
{
- uint16_t width, height;
- uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len;
- uint16_t h_sync_offset, v_sync_offset;
-
- width = mode->crtc_hdisplay;
- height = mode->crtc_vdisplay;
-
- /* do some mode translations */
- h_blank_len = mode->crtc_hblank_end - mode->crtc_hblank_start;
- h_sync_len = mode->crtc_hsync_end - mode->crtc_hsync_start;
-
- v_blank_len = mode->crtc_vblank_end - mode->crtc_vblank_start;
- v_sync_len = mode->crtc_vsync_end - mode->crtc_vsync_start;
-
- h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start;
- v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start;
-
mode->hdisplay = dtd->part1.h_active;
mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8;
mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off;
- mode->hsync_start += (dtd->part2.sync_off_width_high & 0xa0) << 2;
+ mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2;
mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width;
mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4;
mode->htotal = mode->hdisplay + dtd->part1.h_blank;
@@ -735,7 +722,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8;
mode->vsync_start = mode->vdisplay;
mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf;
- mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0a) << 2;
+ mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2;
mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0;
mode->vsync_end = mode->vsync_start +
(dtd->part2.v_sync_off_width & 0xf);
@@ -745,7 +732,7 @@ static void intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode,
mode->clock = dtd->part1.clock * 10;
- mode->flags &= (DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
+ mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC);
if (dtd->part2.dtd_flags & 0x2)
mode->flags |= DRM_MODE_FLAG_PHSYNC;
if (dtd->part2.dtd_flags & 0x4)
@@ -924,6 +911,27 @@ static void intel_sdvo_set_avi_infoframe(struct intel_output *output,
SDVO_HBUF_TX_VSYNC);
}
+static void intel_sdvo_set_tv_format(struct intel_output *output)
+{
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ struct intel_sdvo_tv_format *format, unset;
+ u8 status;
+
+ format = &sdvo_priv->tv_format;
+ memset(&unset, 0, sizeof(unset));
+ if (memcmp(format, &unset, sizeof(*format))) {
+ DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
+ SDVO_NAME(sdvo_priv));
+ format->ntsc_m = 1;
+ intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, format,
+ sizeof(*format));
+ status = intel_sdvo_read_response(output, NULL, 0);
+ if (status != SDVO_CMD_STATUS_SUCCESS)
+ DRM_DEBUG("%s: Failed to set TV format\n",
+ SDVO_NAME(sdvo_priv));
+ }
+}
+
static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
@@ -968,6 +976,12 @@ static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
&input_dtd);
intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
+ drm_mode_set_crtcinfo(adjusted_mode, 0);
+
+ mode->clock = adjusted_mode->clock;
+
+ adjusted_mode->clock *=
+ intel_sdvo_get_pixel_multiplier(mode);
} else {
return false;
}
@@ -1012,7 +1026,12 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
sdvox |= SDVO_AUDIO_ENABLE;
}
- intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
+ /* We have tried to get input timing in mode_fixup, and filled into
+ adjusted_mode */
+ if (sdvo_priv->is_tv)
+ intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
+ else
+ intel_sdvo_get_dtd_from_mode(&input_dtd, mode);
/* If it's a TV, we already set the output timing in mode_fixup.
* Otherwise, the output timing is equal to the input timing.
@@ -1027,6 +1046,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
/* Set the input timing to the screen. Assume always input 0. */
intel_sdvo_set_target_input(output, true, false);
+ if (sdvo_priv->is_tv)
+ intel_sdvo_set_tv_format(output);
+
/* We would like to use intel_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
* feature. However, presumably we would need to adjust the CRTC to
@@ -1395,7 +1417,7 @@ static void
intel_sdvo_check_tv_format(struct intel_output *output)
{
struct intel_sdvo_priv *dev_priv = output->dev_priv;
- struct intel_sdvo_tv_format format, unset;
+ struct intel_sdvo_tv_format format;
uint8_t status;
intel_sdvo_write_cmd(output, SDVO_CMD_GET_TV_FORMAT, NULL, 0);
@@ -1403,15 +1425,7 @@ intel_sdvo_check_tv_format(struct intel_output *output)
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
- memset(&unset, 0, sizeof(unset));
- if (memcmp(&format, &unset, sizeof(format))) {
- DRM_DEBUG("%s: Choosing default TV format of NTSC-M\n",
- SDVO_NAME(dev_priv));
-
- format.ntsc_m = true;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TV_FORMAT, NULL, 0);
- status = intel_sdvo_read_response(output, NULL, 0);
- }
+ memcpy(&dev_priv->tv_format, &format, sizeof(format));
}
/*
@@ -1420,68 +1434,70 @@ intel_sdvo_check_tv_format(struct intel_output *output)
* XXX: all 60Hz refresh?
*/
struct drm_display_mode sdvo_tv_modes[] = {
- { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815680, 321, 384, 416,
- 200, 0, 232, 201, 233, 4196112, 0,
+ { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384,
+ 416, 0, 200, 201, 232, 233, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814080, 321, 384, 416,
- 240, 0, 272, 241, 273, 4196112, 0,
+ { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384,
+ 416, 0, 240, 241, 272, 273, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910080, 401, 464, 496,
- 300, 0, 332, 301, 333, 4196112, 0,
+ { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464,
+ 496, 0, 300, 301, 332, 333, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913280, 641, 704, 736,
- 350, 0, 382, 351, 383, 4196112, 0,
+ { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704,
+ 736, 0, 350, 351, 382, 383, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
- 400, 0, 432, 401, 433, 4196112, 0,
+ { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704,
+ 736, 0, 400, 401, 432, 433, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121280, 641, 704, 736,
- 400, 0, 432, 401, 433, 4196112, 0,
+ { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704,
+ 736, 0, 480, 481, 512, 513, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624000, 705, 768, 800,
- 480, 0, 512, 481, 513, 4196112, 0,
+ { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768,
+ 800, 0, 480, 481, 512, 513, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232000, 705, 768, 800,
- 576, 0, 608, 577, 609, 4196112, 0,
+ { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768,
+ 800, 0, 576, 577, 608, 609, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751680, 721, 784, 816,
- 350, 0, 382, 351, 383, 4196112, 0,
+ { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784,
+ 816, 0, 350, 351, 382, 383, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199680, 721, 784, 816,
- 400, 0, 432, 401, 433, 4196112, 0,
+ { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784,
+ 816, 0, 400, 401, 432, 433, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116480, 721, 784, 816,
- 480, 0, 512, 481, 513, 4196112, 0,
+ { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784,
+ 816, 0, 480, 481, 512, 513, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054080, 721, 784, 816,
- 540, 0, 572, 541, 573, 4196112, 0,
+ { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784,
+ 816, 0, 540, 541, 572, 573, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816640, 721, 784, 816,
- 576, 0, 608, 577, 609, 4196112, 0,
+ { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784,
+ 816, 0, 576, 577, 608, 609, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570560, 769, 832, 864,
- 576, 0, 608, 577, 609, 4196112, 0,
+ { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832,
+ 864, 0, 576, 577, 608, 609, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030080, 801, 864, 896,
- 600, 0, 632, 601, 633, 4196112, 0,
+ { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864,
+ 896, 0, 600, 601, 632, 633, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581760, 833, 896, 928,
- 624, 0, 656, 625, 657, 4196112, 0,
+ { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896,
+ 928, 0, 624, 625, 656, 657, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707040, 921, 984, 1016,
- 766, 0, 798, 767, 799, 4196112, 0,
+ { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984,
+ 1016, 0, 766, 767, 798, 799, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827200, 1025, 1088, 1120,
- 768, 0, 800, 769, 801, 4196112, 0,
+ { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088,
+ 1120, 0, 768, 769, 800, 801, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
- { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265920, 1281, 1344, 1376,
- 1024, 0, 1056, 1025, 1057, 4196112, 0,
+ { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344,
+ 1376, 0, 1024, 1025, 1056, 1057, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
};
static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
{
struct intel_output *output = to_intel_output(connector);
+ struct intel_sdvo_priv *sdvo_priv = output->dev_priv;
+ struct intel_sdvo_sdtv_resolution_request tv_res;
uint32_t reply = 0;
uint8_t status;
int i = 0;
@@ -1491,15 +1507,22 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector)
/* Read the list of supported input resolutions for the selected TV
* format.
*/
+ memset(&tv_res, 0, sizeof(tv_res));
+ memcpy(&tv_res, &sdvo_priv->tv_format, sizeof(tv_res));
intel_sdvo_write_cmd(output, SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT,
- NULL, 0);
+ &tv_res, sizeof(tv_res));
status = intel_sdvo_read_response(output, &reply, 3);
if (status != SDVO_CMD_STATUS_SUCCESS)
return;
for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++)
- if (reply & (1 << i))
- drm_mode_probed_add(connector, &sdvo_tv_modes[i]);
+ if (reply & (1 << i)) {
+ struct drm_display_mode *nmode;
+ nmode = drm_mode_duplicate(connector->dev,
+ &sdvo_tv_modes[i]);
+ if (nmode)
+ drm_mode_probed_add(connector, nmode);
+ }
}
static int intel_sdvo_get_modes(struct drm_connector *connector)
diff --git a/drivers/gpu/drm/i915/intel_sdvo_regs.h b/drivers/gpu/drm/i915/intel_sdvo_regs.h
index 1117b9c151a..193938b7d7f 100644
--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h
+++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h
@@ -100,6 +100,9 @@ struct intel_sdvo_preferred_input_timing_args {
u16 clock;
u16 width;
u16 height;
+ u8 interlace:1;
+ u8 scaled:1;
+ u8 pad:6;
} __attribute__((packed));
/* I2C registers for SDVO */
diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c
index ceca9471a75..d2c32983242 100644
--- a/drivers/gpu/drm/i915/intel_tv.c
+++ b/drivers/gpu/drm/i915/intel_tv.c
@@ -1570,33 +1570,49 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
struct drm_device *dev = connector->dev;
struct intel_output *intel_output = to_intel_output(connector);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+ struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_crtc *crtc = encoder->crtc;
int ret = 0;
+ bool changed = false;
ret = drm_connector_property_set_value(connector, property, val);
if (ret < 0)
goto out;
- if (property == dev->mode_config.tv_left_margin_property)
+ if (property == dev->mode_config.tv_left_margin_property &&
+ tv_priv->margin[TV_MARGIN_LEFT] != val) {
tv_priv->margin[TV_MARGIN_LEFT] = val;
- else if (property == dev->mode_config.tv_right_margin_property)
+ changed = true;
+ } else if (property == dev->mode_config.tv_right_margin_property &&
+ tv_priv->margin[TV_MARGIN_RIGHT] != val) {
tv_priv->margin[TV_MARGIN_RIGHT] = val;
- else if (property == dev->mode_config.tv_top_margin_property)
+ changed = true;
+ } else if (property == dev->mode_config.tv_top_margin_property &&
+ tv_priv->margin[TV_MARGIN_TOP] != val) {
tv_priv->margin[TV_MARGIN_TOP] = val;
- else if (property == dev->mode_config.tv_bottom_margin_property)
+ changed = true;
+ } else if (property == dev->mode_config.tv_bottom_margin_property &&
+ tv_priv->margin[TV_MARGIN_BOTTOM] != val) {
tv_priv->margin[TV_MARGIN_BOTTOM] = val;
- else if (property == dev->mode_config.tv_mode_property) {
+ changed = true;
+ } else if (property == dev->mode_config.tv_mode_property) {
if (val >= NUM_TV_MODES) {
ret = -EINVAL;
goto out;
}
+ if (!strcmp(tv_priv->tv_format, tv_modes[val].name))
+ goto out;
+
tv_priv->tv_format = tv_modes[val].name;
- intel_tv_mode_set(&intel_output->enc, NULL, NULL);
+ changed = true;
} else {
ret = -EINVAL;
goto out;
}
- intel_tv_mode_set(&intel_output->enc, NULL, NULL);
+ if (changed && crtc)
+ drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x,
+ crtc->y, crtc->fb);
out:
return ret;
}
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c
index b49c5ff2958..7a6bf9ffc5a 100644
--- a/drivers/gpu/drm/mga/mga_dma.c
+++ b/drivers/gpu/drm/mga/mga_dma.c
@@ -148,8 +148,8 @@ void mga_do_dma_flush(drm_mga_private_t * dev_priv)
primary->space = head - tail;
}
- DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
- DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset);
+ DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
+ DRM_DEBUG(" tail = 0x%06lx\n", (unsigned long)(tail - dev_priv->primary->offset));
DRM_DEBUG(" space = 0x%06x\n", primary->space);
mga_flush_write_combine();
@@ -187,7 +187,7 @@ void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
primary->space = head - dev_priv->primary->offset;
}
- DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
+ DRM_DEBUG(" head = 0x%06lx\n", (unsigned long)(head - dev_priv->primary->offset));
DRM_DEBUG(" tail = 0x%06x\n", primary->tail);
DRM_DEBUG(" wrap = %d\n", primary->last_wrap);
DRM_DEBUG(" space = 0x%06x\n", primary->space);
@@ -239,7 +239,7 @@ static void mga_freelist_print(struct drm_device * dev)
for (entry = dev_priv->head->next; entry; entry = entry->next) {
DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n",
entry, entry->buf->idx, entry->age.head,
- entry->age.head - dev_priv->primary->offset);
+ (unsigned long)(entry->age.head - dev_priv->primary->offset));
}
DRM_INFO("\n");
}
@@ -340,10 +340,10 @@ static struct drm_buf *mga_freelist_get(struct drm_device * dev)
DRM_DEBUG(" tail=0x%06lx %d\n",
tail->age.head ?
- tail->age.head - dev_priv->primary->offset : 0,
+ (unsigned long)(tail->age.head - dev_priv->primary->offset) : 0,
tail->age.wrap);
DRM_DEBUG(" head=0x%06lx %d\n",
- head - dev_priv->primary->offset, wrap);
+ (unsigned long)(head - dev_priv->primary->offset), wrap);
if (TEST_AGE(&tail->age, head, wrap)) {
prev = dev_priv->tail->prev;
@@ -366,8 +366,9 @@ int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
drm_mga_freelist_t *head, *entry, *prev;
DRM_DEBUG("age=0x%06lx wrap=%d\n",
- buf_priv->list_entry->age.head -
- dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
+ (unsigned long)(buf_priv->list_entry->age.head -
+ dev_priv->primary->offset),
+ buf_priv->list_entry->age.wrap);
entry = buf_priv->list_entry;
head = dev_priv->head;
diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h
index 88257c276eb..3d264f28823 100644
--- a/drivers/gpu/drm/mga/mga_drv.h
+++ b/drivers/gpu/drm/mga/mga_drv.h
@@ -113,8 +113,8 @@ typedef struct drm_mga_private {
* \sa drm_mga_private_t::mmio
*/
/*@{ */
- u32 mmio_base; /**< Bus address of base of MMIO. */
- u32 mmio_size; /**< Size of the MMIO region. */
+ resource_size_t mmio_base; /**< Bus address of base of MMIO. */
+ resource_size_t mmio_size; /**< Size of the MMIO region. */
/*@} */
u32 clear_cmd;
@@ -317,8 +317,8 @@ do { \
DRM_INFO( "\n" ); \
DRM_INFO( " tail=0x%06x head=0x%06lx\n", \
dev_priv->prim.tail, \
- MGA_READ( MGA_PRIMADDRESS ) - \
- dev_priv->primary->offset ); \
+ (unsigned long)(MGA_READ(MGA_PRIMADDRESS) - \
+ dev_priv->primary->offset)); \
} \
if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \
if ( dev_priv->prim.space < \
diff --git a/drivers/gpu/drm/r128/r128_cce.c b/drivers/gpu/drm/r128/r128_cce.c
index c31afbde62e..32de4cedc36 100644
--- a/drivers/gpu/drm/r128/r128_cce.c
+++ b/drivers/gpu/drm/r128/r128_cce.c
@@ -525,11 +525,12 @@ static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
} else
#endif
{
- dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset;
+ dev_priv->cce_ring->handle =
+ (void *)(unsigned long)dev_priv->cce_ring->offset;
dev_priv->ring_rptr->handle =
- (void *)dev_priv->ring_rptr->offset;
+ (void *)(unsigned long)dev_priv->ring_rptr->offset;
dev->agp_buffer_map->handle =
- (void *)dev->agp_buffer_map->offset;
+ (void *)(unsigned long)dev->agp_buffer_map->offset;
}
#if __OS_HAS_AGP
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile
index feb521ebc39..52ce439a0f2 100644
--- a/drivers/gpu/drm/radeon/Makefile
+++ b/drivers/gpu/drm/radeon/Makefile
@@ -3,7 +3,7 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
-radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
+radeon-y := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o r600_cp.o
radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
diff --git a/drivers/gpu/drm/radeon/r300_cmdbuf.c b/drivers/gpu/drm/radeon/r300_cmdbuf.c
index cace3964fee..cb2e470f97d 100644
--- a/drivers/gpu/drm/radeon/r300_cmdbuf.c
+++ b/drivers/gpu/drm/radeon/r300_cmdbuf.c
@@ -37,6 +37,8 @@
#include "radeon_drv.h"
#include "r300_reg.h"
+#include <asm/unaligned.h>
+
#define R300_SIMULTANEOUS_CLIPRECTS 4
/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
@@ -205,6 +207,10 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(0x42C0, 2);
ADD_RANGE(R300_RS_CNTL_0, 2);
+ ADD_RANGE(R300_SU_REG_DEST, 1);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530)
+ ADD_RANGE(RV530_FG_ZBREG_DEST, 1);
+
ADD_RANGE(R300_SC_HYPERZ, 2);
ADD_RANGE(0x43E8, 1);
@@ -230,6 +236,7 @@ void r300_init_reg_flags(struct drm_device *dev)
ADD_RANGE(R300_ZB_DEPTHPITCH, 1);
ADD_RANGE(R300_ZB_DEPTHCLEARVALUE, 1);
ADD_RANGE(R300_ZB_ZMASK_OFFSET, 13);
+ ADD_RANGE(R300_ZB_ZPASS_DATA, 2); /* ZB_ZPASS_DATA, ZB_ZPASS_ADDR */
ADD_RANGE(R300_TX_FILTER_0, 16);
ADD_RANGE(R300_TX_FILTER1_0, 16);
@@ -917,6 +924,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
{
u32 *ref_age_base;
u32 i, buf_idx, h_pending;
+ u64 ptr_addr;
RING_LOCALS;
if (cmdbuf->bufsz <
@@ -930,7 +938,8 @@ static int r300_scratch(drm_radeon_private_t *dev_priv,
dev_priv->scratch_ages[header.scratch.reg]++;
- ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf);
+ ptr_addr = get_unaligned((u64 *)cmdbuf->buf);
+ ref_age_base = (u32 *)(unsigned long)ptr_addr;
cmdbuf->buf += sizeof(u64);
cmdbuf->bufsz -= sizeof(u64);
diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h
index ee6f811599a..bdbc95fa672 100644
--- a/drivers/gpu/drm/radeon/r300_reg.h
+++ b/drivers/gpu/drm/radeon/r300_reg.h
@@ -1770,4 +1770,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R500_RB3D_COLOR_CLEAR_VALUE_AR 0x46c0
#define R500_RB3D_CONSTANT_COLOR_AR 0x4ef8
+#define R300_SU_REG_DEST 0x42c8
+#define RV530_FG_ZBREG_DEST 0x4be8
+#define R300_ZB_ZPASS_DATA 0x4f58
+#define R300_ZB_ZPASS_ADDR 0x4f5c
+
#endif /* _R300_REG_H */
diff --git a/drivers/gpu/drm/radeon/r600_cp.c b/drivers/gpu/drm/radeon/r600_cp.c
new file mode 100644
index 00000000000..bc9d09dfa8e
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_cp.c
@@ -0,0 +1,2253 @@
+/*
+ * Copyright 2008-2009 Advanced Micro Devices, Inc.
+ * Copyright 2008 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Dave Airlie <airlied@redhat.com>
+ * Alex Deucher <alexander.deucher@amd.com>
+ */
+
+#include "drmP.h"
+#include "drm.h"
+#include "radeon_drm.h"
+#include "radeon_drv.h"
+
+#include "r600_microcode.h"
+
+# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
+# define ATI_PCIGART_PAGE_MASK (~(ATI_PCIGART_PAGE_SIZE-1))
+
+#define R600_PTE_VALID (1 << 0)
+#define R600_PTE_SYSTEM (1 << 1)
+#define R600_PTE_SNOOPED (1 << 2)
+#define R600_PTE_READABLE (1 << 5)
+#define R600_PTE_WRITEABLE (1 << 6)
+
+/* MAX values used for gfx init */
+#define R6XX_MAX_SH_GPRS 256
+#define R6XX_MAX_TEMP_GPRS 16
+#define R6XX_MAX_SH_THREADS 256
+#define R6XX_MAX_SH_STACK_ENTRIES 4096
+#define R6XX_MAX_BACKENDS 8
+#define R6XX_MAX_BACKENDS_MASK 0xff
+#define R6XX_MAX_SIMDS 8
+#define R6XX_MAX_SIMDS_MASK 0xff
+#define R6XX_MAX_PIPES 8
+#define R6XX_MAX_PIPES_MASK 0xff
+
+#define R7XX_MAX_SH_GPRS 256
+#define R7XX_MAX_TEMP_GPRS 16
+#define R7XX_MAX_SH_THREADS 256
+#define R7XX_MAX_SH_STACK_ENTRIES 4096
+#define R7XX_MAX_BACKENDS 8
+#define R7XX_MAX_BACKENDS_MASK 0xff
+#define R7XX_MAX_SIMDS 16
+#define R7XX_MAX_SIMDS_MASK 0xffff
+#define R7XX_MAX_PIPES 8
+#define R7XX_MAX_PIPES_MASK 0xff
+
+static int r600_do_wait_for_fifo(drm_radeon_private_t *dev_priv, int entries)
+{
+ int i;
+
+ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ int slots;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ slots = (RADEON_READ(R600_GRBM_STATUS)
+ & R700_CMDFIFO_AVAIL_MASK);
+ else
+ slots = (RADEON_READ(R600_GRBM_STATUS)
+ & R600_CMDFIFO_AVAIL_MASK);
+ if (slots >= entries)
+ return 0;
+ DRM_UDELAY(1);
+ }
+ DRM_INFO("wait for fifo failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(R600_GRBM_STATUS),
+ RADEON_READ(R600_GRBM_STATUS2));
+
+ return -EBUSY;
+}
+
+static int r600_do_wait_for_idle(drm_radeon_private_t *dev_priv)
+{
+ int i, ret;
+
+ dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ ret = r600_do_wait_for_fifo(dev_priv, 8);
+ else
+ ret = r600_do_wait_for_fifo(dev_priv, 16);
+ if (ret)
+ return ret;
+ for (i = 0; i < dev_priv->usec_timeout; i++) {
+ if (!(RADEON_READ(R600_GRBM_STATUS) & R600_GUI_ACTIVE))
+ return 0;
+ DRM_UDELAY(1);
+ }
+ DRM_INFO("wait idle failed status : 0x%08X 0x%08X\n",
+ RADEON_READ(R600_GRBM_STATUS),
+ RADEON_READ(R600_GRBM_STATUS2));
+
+ return -EBUSY;
+}
+
+void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
+{
+ struct drm_sg_mem *entry = dev->sg;
+ int max_pages;
+ int pages;
+ int i;
+
+ if (!entry)
+ return;
+
+ if (gart_info->bus_addr) {
+ max_pages = (gart_info->table_size / sizeof(u64));
+ pages = (entry->pages <= max_pages)
+ ? entry->pages : max_pages;
+
+ for (i = 0; i < pages; i++) {
+ if (!entry->busaddr[i])
+ break;
+ pci_unmap_page(dev->pdev, entry->busaddr[i],
+ PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+ }
+ if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+ gart_info->bus_addr = 0;
+ }
+}
+
+/* R600 has page table setup */
+int r600_page_table_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
+ struct drm_local_map *map = &gart_info->mapping;
+ struct drm_sg_mem *entry = dev->sg;
+ int ret = 0;
+ int i, j;
+ int pages;
+ u64 page_base;
+ dma_addr_t entry_addr;
+ int max_ati_pages, max_real_pages, gart_idx;
+
+ /* okay page table is available - lets rock */
+ max_ati_pages = (gart_info->table_size / sizeof(u64));
+ max_real_pages = max_ati_pages / (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE);
+
+ pages = (entry->pages <= max_real_pages) ?
+ entry->pages : max_real_pages;
+
+ memset_io((void __iomem *)map->handle, 0, max_ati_pages * sizeof(u64));
+
+ gart_idx = 0;
+ for (i = 0; i < pages; i++) {
+ entry->busaddr[i] = pci_map_page(dev->pdev,
+ entry->pagelist[i], 0,
+ PAGE_SIZE,
+ PCI_DMA_BIDIRECTIONAL);
+ if (entry->busaddr[i] == 0) {
+ DRM_ERROR("unable to map PCIGART pages!\n");
+ r600_page_table_cleanup(dev, gart_info);
+ goto done;
+ }
+ entry_addr = entry->busaddr[i];
+ for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
+ page_base = (u64) entry_addr & ATI_PCIGART_PAGE_MASK;
+ page_base |= R600_PTE_VALID | R600_PTE_SYSTEM | R600_PTE_SNOOPED;
+ page_base |= R600_PTE_READABLE | R600_PTE_WRITEABLE;
+
+ DRM_WRITE64(map, gart_idx * sizeof(u64), page_base);
+
+ gart_idx++;
+
+ if ((i % 128) == 0)
+ DRM_DEBUG("page entry %d: 0x%016llx\n",
+ i, (unsigned long long)page_base);
+ entry_addr += ATI_PCIGART_PAGE_SIZE;
+ }
+ }
+ ret = 1;
+done:
+ return ret;
+}
+
+static void r600_vm_flush_gart_range(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 resp, countdown = 1000;
+ RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_REQUEST_RESPONSE, 2);
+
+ do {
+ resp = RADEON_READ(R600_VM_CONTEXT0_REQUEST_RESPONSE);
+ countdown--;
+ DRM_UDELAY(1);
+ } while (((resp & 0xf0) == 0) && countdown);
+}
+
+static void r600_vm_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ /* initialise the VM to use the page table we constructed up there */
+ u32 vm_c0, i;
+ u32 mc_rd_a;
+ u32 vm_l2_cntl, vm_l2_cntl3;
+ /* okay set up the PCIE aperture type thingo */
+ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+ RADEON_WRITE(R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+ /* setup MC RD a */
+ mc_rd_a = R600_MCD_L1_TLB | R600_MCD_L1_FRAG_PROC | R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS |
+ R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | R600_MCD_EFFECTIVE_L1_TLB_SIZE(5) |
+ R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(5) | R600_MCD_WAIT_L2_QUERY;
+
+ RADEON_WRITE(R600_MCD_RD_A_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_RD_B_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_WR_A_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_B_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_GFX_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_GFX_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_SYS_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_SYS_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_HDP_CNTL, mc_rd_a | R600_MCD_L1_STRICT_ORDERING);
+ RADEON_WRITE(R600_MCD_WR_HDP_CNTL, mc_rd_a /*| R600_MCD_L1_STRICT_ORDERING*/);
+
+ RADEON_WRITE(R600_MCD_RD_PDMA_CNTL, mc_rd_a);
+ RADEON_WRITE(R600_MCD_WR_PDMA_CNTL, mc_rd_a);
+
+ RADEON_WRITE(R600_MCD_RD_SEM_CNTL, mc_rd_a | R600_MCD_SEMAPHORE_MODE);
+ RADEON_WRITE(R600_MCD_WR_SEM_CNTL, mc_rd_a);
+
+ vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+ vm_l2_cntl |= R600_VM_L2_CNTL_QUEUE_SIZE(7);
+ RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+ RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+ vm_l2_cntl3 = (R600_VM_L2_CNTL3_BANK_SELECT_0(0) |
+ R600_VM_L2_CNTL3_BANK_SELECT_1(1) |
+ R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(2));
+ RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+ vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+ vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+ /* disable all other contexts */
+ for (i = 1; i < 8; i++)
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+ r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+static void r600_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+ int i;
+
+ r600_do_cp_stop(dev_priv);
+
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ R600_RB_NO_UPDATE |
+ R600_RB_BLKSZ(15) |
+ R600_RB_BUFSZ(3));
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(15000);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600)) {
+ DRM_INFO("Loading R600 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ R600_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ R600_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ R600_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading R600 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, R600_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610)) {
+ DRM_INFO("Loading RV610 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV610_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV610_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV610_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV610 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV610_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
+ DRM_INFO("Loading RV630 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV630_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV630_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV630_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV630 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV630_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620)) {
+ DRM_INFO("Loading RV620 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV620_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV620_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV620_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV620 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV620_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
+ DRM_INFO("Loading RV635 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV635_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV635_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV635_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV635 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV635_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)) {
+ DRM_INFO("Loading RV670 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV670_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV670_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RV670_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV670 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV670_pfp_microcode[i]);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+ DRM_INFO("Loading RS780 CP Microcode\n");
+ for (i = 0; i < PM4_UCODE_SIZE; i++) {
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RS780_cp_microcode[i][0]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RS780_cp_microcode[i][1]);
+ RADEON_WRITE(R600_CP_ME_RAM_DATA,
+ RS780_cp_microcode[i][2]);
+ }
+
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RS780 PFP Microcode\n");
+ for (i = 0; i < PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RS780_pfp_microcode[i]);
+ }
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
+
+}
+
+static void r700_vm_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ /* initialise the VM to use the page table we constructed up there */
+ u32 vm_c0, i;
+ u32 mc_vm_md_l1;
+ u32 vm_l2_cntl, vm_l2_cntl3;
+ /* okay set up the PCIE aperture type thingo */
+ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+ RADEON_WRITE(R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0);
+
+ mc_vm_md_l1 = R700_ENABLE_L1_TLB |
+ R700_ENABLE_L1_FRAGMENT_PROCESSING |
+ R700_SYSTEM_ACCESS_MODE_IN_SYS |
+ R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
+ R700_EFFECTIVE_L1_TLB_SIZE(5) |
+ R700_EFFECTIVE_L1_QUEUE_SIZE(5);
+
+ RADEON_WRITE(R700_MC_VM_MD_L1_TLB0_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MD_L1_TLB1_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MD_L1_TLB2_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB0_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB1_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB2_CNTL, mc_vm_md_l1);
+ RADEON_WRITE(R700_MC_VM_MB_L1_TLB3_CNTL, mc_vm_md_l1);
+
+ vm_l2_cntl = R600_VM_L2_CACHE_EN | R600_VM_L2_FRAG_PROC | R600_VM_ENABLE_PTE_CACHE_LRU_W;
+ vm_l2_cntl |= R700_VM_L2_CNTL_QUEUE_SIZE(7);
+ RADEON_WRITE(R600_VM_L2_CNTL, vm_l2_cntl);
+
+ RADEON_WRITE(R600_VM_L2_CNTL2, 0);
+ vm_l2_cntl3 = R700_VM_L2_CNTL3_BANK_SELECT(0) | R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(2);
+ RADEON_WRITE(R600_VM_L2_CNTL3, vm_l2_cntl3);
+
+ vm_c0 = R600_VM_ENABLE_CONTEXT | R600_VM_PAGE_TABLE_DEPTH_FLAT;
+
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL, vm_c0);
+
+ vm_c0 &= ~R600_VM_ENABLE_CONTEXT;
+
+ /* disable all other contexts */
+ for (i = 1; i < 8; i++)
+ RADEON_WRITE(R600_VM_CONTEXT0_CNTL + (i * 4), vm_c0);
+
+ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, dev_priv->gart_info.bus_addr >> 12);
+ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR, dev_priv->gart_vm_start >> 12);
+ RADEON_WRITE(R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR, (dev_priv->gart_vm_start + dev_priv->gart_size - 1) >> 12);
+
+ r600_vm_flush_gart_range(dev);
+}
+
+/* load r600 microcode */
+static void r700_cp_load_microcode(drm_radeon_private_t *dev_priv)
+{
+ int i;
+
+ r600_do_cp_stop(dev_priv);
+
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ R600_RB_NO_UPDATE |
+ (15 << 8) |
+ (3 << 0));
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(15000);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)) {
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV770 PFP Microcode\n");
+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV770_pfp_microcode[i]);
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ DRM_INFO("Loading RV770 CP Microcode\n");
+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV770_cp_microcode[i]);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV730)) {
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV730 PFP Microcode\n");
+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV730_pfp_microcode[i]);
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ DRM_INFO("Loading RV730 CP Microcode\n");
+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV730_cp_microcode[i]);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)) {
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ DRM_INFO("Loading RV710 PFP Microcode\n");
+ for (i = 0; i < R700_PFP_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_PFP_UCODE_DATA, RV710_pfp_microcode[i]);
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ DRM_INFO("Loading RV710 CP Microcode\n");
+ for (i = 0; i < R700_PM4_UCODE_SIZE; i++)
+ RADEON_WRITE(R600_CP_ME_RAM_DATA, RV710_cp_microcode[i]);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+
+ }
+ RADEON_WRITE(R600_CP_PFP_UCODE_ADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_WADDR, 0);
+ RADEON_WRITE(R600_CP_ME_RAM_RADDR, 0);
+
+}
+
+static void r600_test_writeback(drm_radeon_private_t *dev_priv)
+{
+ u32 tmp;
+
+ /* Start with assuming that writeback doesn't work */
+ dev_priv->writeback_works = 0;
+
+ /* Writeback doesn't seem to work everywhere, test it here and possibly
+ * enable it if it appears to work
+ */
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
+
+ RADEON_WRITE(R600_SCRATCH_REG1, 0xdeadbeef);
+
+ for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
+ u32 val;
+
+ val = radeon_read_ring_rptr(dev_priv, R600_SCRATCHOFF(1));
+ if (val == 0xdeadbeef)
+ break;
+ DRM_UDELAY(1);
+ }
+
+ if (tmp < dev_priv->usec_timeout) {
+ dev_priv->writeback_works = 1;
+ DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
+ } else {
+ dev_priv->writeback_works = 0;
+ DRM_INFO("writeback test failed\n");
+ }
+ if (radeon_no_wb == 1) {
+ dev_priv->writeback_works = 0;
+ DRM_INFO("writeback forced off\n");
+ }
+
+ if (!dev_priv->writeback_works) {
+ /* Disable writeback to avoid unnecessary bus master transfer */
+ RADEON_WRITE(R600_CP_RB_CNTL, RADEON_READ(R600_CP_RB_CNTL) |
+ RADEON_RB_NO_UPDATE);
+ RADEON_WRITE(R600_SCRATCH_UMSK, 0);
+ }
+}
+
+int r600_do_engine_reset(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 cp_ptr, cp_me_cntl, cp_rb_cntl;
+
+ DRM_INFO("Resetting GPU\n");
+
+ cp_ptr = RADEON_READ(R600_CP_RB_WPTR);
+ cp_me_cntl = RADEON_READ(R600_CP_ME_CNTL);
+ RADEON_WRITE(R600_CP_ME_CNTL, R600_CP_ME_HALT);
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0x7fff);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(50);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+
+ RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
+ cp_rb_cntl = RADEON_READ(R600_CP_RB_CNTL);
+ RADEON_WRITE(R600_CP_RB_CNTL, R600_RB_RPTR_WR_ENA);
+
+ RADEON_WRITE(R600_CP_RB_RPTR_WR, cp_ptr);
+ RADEON_WRITE(R600_CP_RB_WPTR, cp_ptr);
+ RADEON_WRITE(R600_CP_RB_CNTL, cp_rb_cntl);
+ RADEON_WRITE(R600_CP_ME_CNTL, cp_me_cntl);
+
+ /* Reset the CP ring */
+ r600_do_cp_reset(dev_priv);
+
+ /* The CP is no longer running after an engine reset */
+ dev_priv->cp_running = 0;
+
+ /* Reset any pending vertex, indirect buffers */
+ radeon_freelist_reset(dev);
+
+ return 0;
+
+}
+
+static u32 r600_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+ u32 num_backends,
+ u32 backend_disable_mask)
+{
+ u32 backend_map = 0;
+ u32 enabled_backends_mask;
+ u32 enabled_backends_count;
+ u32 cur_pipe;
+ u32 swizzle_pipe[R6XX_MAX_PIPES];
+ u32 cur_backend;
+ u32 i;
+
+ if (num_tile_pipes > R6XX_MAX_PIPES)
+ num_tile_pipes = R6XX_MAX_PIPES;
+ if (num_tile_pipes < 1)
+ num_tile_pipes = 1;
+ if (num_backends > R6XX_MAX_BACKENDS)
+ num_backends = R6XX_MAX_BACKENDS;
+ if (num_backends < 1)
+ num_backends = 1;
+
+ enabled_backends_mask = 0;
+ enabled_backends_count = 0;
+ for (i = 0; i < R6XX_MAX_BACKENDS; ++i) {
+ if (((backend_disable_mask >> i) & 1) == 0) {
+ enabled_backends_mask |= (1 << i);
+ ++enabled_backends_count;
+ }
+ if (enabled_backends_count == num_backends)
+ break;
+ }
+
+ if (enabled_backends_count == 0) {
+ enabled_backends_mask = 1;
+ enabled_backends_count = 1;
+ }
+
+ if (enabled_backends_count != num_backends)
+ num_backends = enabled_backends_count;
+
+ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R6XX_MAX_PIPES);
+ switch (num_tile_pipes) {
+ case 1:
+ swizzle_pipe[0] = 0;
+ break;
+ case 2:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ break;
+ case 3:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ swizzle_pipe[2] = 2;
+ break;
+ case 4:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ swizzle_pipe[2] = 2;
+ swizzle_pipe[3] = 3;
+ break;
+ case 5:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ swizzle_pipe[2] = 2;
+ swizzle_pipe[3] = 3;
+ swizzle_pipe[4] = 4;
+ break;
+ case 6:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 5;
+ swizzle_pipe[4] = 1;
+ swizzle_pipe[5] = 3;
+ break;
+ case 7:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 1;
+ swizzle_pipe[5] = 3;
+ swizzle_pipe[6] = 5;
+ break;
+ case 8:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 1;
+ swizzle_pipe[5] = 3;
+ swizzle_pipe[6] = 5;
+ swizzle_pipe[7] = 7;
+ break;
+ }
+
+ cur_backend = 0;
+ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+ while (((1 << cur_backend) & enabled_backends_mask) == 0)
+ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+
+ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+ cur_backend = (cur_backend + 1) % R6XX_MAX_BACKENDS;
+ }
+
+ return backend_map;
+}
+
+static int r600_count_pipe_bits(uint32_t val)
+{
+ int i, ret = 0;
+ for (i = 0; i < 32; i++) {
+ ret += val & 1;
+ val >>= 1;
+ }
+ return ret;
+}
+
+static void r600_gfx_init(struct drm_device *dev,
+ drm_radeon_private_t *dev_priv)
+{
+ int i, j, num_qd_pipes;
+ u32 sx_debug_1;
+ u32 tc_cntl;
+ u32 arb_pop;
+ u32 num_gs_verts_per_thread;
+ u32 vgt_gs_per_es;
+ u32 gs_prim_buffer_depth = 0;
+ u32 sq_ms_fifo_sizes;
+ u32 sq_config;
+ u32 sq_gpr_resource_mgmt_1 = 0;
+ u32 sq_gpr_resource_mgmt_2 = 0;
+ u32 sq_thread_resource_mgmt = 0;
+ u32 sq_stack_resource_mgmt_1 = 0;
+ u32 sq_stack_resource_mgmt_2 = 0;
+ u32 hdp_host_path_cntl;
+ u32 backend_map;
+ u32 gb_tiling_config = 0;
+ u32 cc_rb_backend_disable = 0;
+ u32 cc_gc_shader_pipe_config = 0;
+ u32 ramcfg;
+
+ /* setup chip specs */
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_R600:
+ dev_priv->r600_max_pipes = 4;
+ dev_priv->r600_max_tile_pipes = 8;
+ dev_priv->r600_max_simds = 4;
+ dev_priv->r600_max_backends = 4;
+ dev_priv->r600_max_gprs = 256;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 2;
+ break;
+ case CHIP_RV630:
+ case CHIP_RV635:
+ dev_priv->r600_max_pipes = 2;
+ dev_priv->r600_max_tile_pipes = 2;
+ dev_priv->r600_max_simds = 3;
+ dev_priv->r600_max_backends = 1;
+ dev_priv->r600_max_gprs = 128;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 128;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 4;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 2;
+ break;
+ case CHIP_RV610:
+ case CHIP_RS780:
+ case CHIP_RV620:
+ dev_priv->r600_max_pipes = 1;
+ dev_priv->r600_max_tile_pipes = 1;
+ dev_priv->r600_max_simds = 2;
+ dev_priv->r600_max_backends = 1;
+ dev_priv->r600_max_gprs = 128;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 128;
+ dev_priv->r600_max_hw_contexts = 4;
+ dev_priv->r600_max_gs_threads = 4;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 1;
+ break;
+ case CHIP_RV670:
+ dev_priv->r600_max_pipes = 4;
+ dev_priv->r600_max_tile_pipes = 4;
+ dev_priv->r600_max_simds = 4;
+ dev_priv->r600_max_backends = 4;
+ dev_priv->r600_max_gprs = 192;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 128;
+ dev_priv->r600_sq_num_cf_insts = 2;
+ break;
+ default:
+ break;
+ }
+
+ /* Initialize HDP */
+ j = 0;
+ for (i = 0; i < 32; i++) {
+ RADEON_WRITE((0x2c14 + j), 0x00000000);
+ RADEON_WRITE((0x2c18 + j), 0x00000000);
+ RADEON_WRITE((0x2c1c + j), 0x00000000);
+ RADEON_WRITE((0x2c20 + j), 0x00000000);
+ RADEON_WRITE((0x2c24 + j), 0x00000000);
+ j += 0x18;
+ }
+
+ RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff));
+
+ /* setup tiling, simd, pipe config */
+ ramcfg = RADEON_READ(R600_RAMCFG);
+
+ switch (dev_priv->r600_max_tile_pipes) {
+ case 1:
+ gb_tiling_config |= R600_PIPE_TILING(0);
+ break;
+ case 2:
+ gb_tiling_config |= R600_PIPE_TILING(1);
+ break;
+ case 4:
+ gb_tiling_config |= R600_PIPE_TILING(2);
+ break;
+ case 8:
+ gb_tiling_config |= R600_PIPE_TILING(3);
+ break;
+ default:
+ break;
+ }
+
+ gb_tiling_config |= R600_BANK_TILING((ramcfg >> R600_NOOFBANK_SHIFT) & R600_NOOFBANK_MASK);
+
+ gb_tiling_config |= R600_GROUP_SIZE(0);
+
+ if (((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK) > 3) {
+ gb_tiling_config |= R600_ROW_TILING(3);
+ gb_tiling_config |= R600_SAMPLE_SPLIT(3);
+ } else {
+ gb_tiling_config |=
+ R600_ROW_TILING(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK));
+ gb_tiling_config |=
+ R600_SAMPLE_SPLIT(((ramcfg >> R600_NOOFROWS_SHIFT) & R600_NOOFROWS_MASK));
+ }
+
+ gb_tiling_config |= R600_BANK_SWAPS(1);
+
+ backend_map = r600_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
+ dev_priv->r600_max_backends,
+ (0xff << dev_priv->r600_max_backends) & 0xff);
+ gb_tiling_config |= R600_BACKEND_MAP(backend_map);
+
+ cc_gc_shader_pipe_config =
+ R600_INACTIVE_QD_PIPES((R6XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R6XX_MAX_PIPES_MASK);
+ cc_gc_shader_pipe_config |=
+ R600_INACTIVE_SIMDS((R6XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R6XX_MAX_SIMDS_MASK);
+
+ cc_rb_backend_disable =
+ R600_BACKEND_DISABLE((R6XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R6XX_MAX_BACKENDS_MASK);
+
+ RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config);
+ RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+ RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+
+ RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+ RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+ RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+
+ num_qd_pipes =
+ R6XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK);
+ RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK);
+ RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK);
+
+ /* set HW defaults for 3D engine */
+ RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) |
+ R600_ROQ_IB2_START(0x2b)));
+
+ RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, (R600_MEQ_END(0x40) |
+ R600_ROQ_END(0x40)));
+
+ RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO |
+ R600_SYNC_GRADIENT |
+ R600_SYNC_WALKER |
+ R600_SYNC_ALIGNER));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670)
+ RADEON_WRITE(R600_ARB_GDEC_RD_CNTL, 0x00000021);
+
+ sx_debug_1 = RADEON_READ(R600_SX_DEBUG_1);
+ sx_debug_1 |= R600_SMX_EVENT_RELEASE;
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_R600))
+ sx_debug_1 |= R600_ENABLE_NEW_SMX_ADDRESS;
+ RADEON_WRITE(R600_SX_DEBUG_1, sx_debug_1);
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780))
+ RADEON_WRITE(R600_DB_DEBUG, R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE);
+ else
+ RADEON_WRITE(R600_DB_DEBUG, 0);
+
+ RADEON_WRITE(R600_DB_WATERMARKS, (R600_DEPTH_FREE(4) |
+ R600_DEPTH_FLUSH(16) |
+ R600_DEPTH_PENDING_FREE(4) |
+ R600_DEPTH_CACHELINE_FREE(16)));
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+ RADEON_WRITE(R600_VGT_NUM_INSTANCES, 0);
+
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0));
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(0));
+
+ sq_ms_fifo_sizes = RADEON_READ(R600_SQ_MS_FIFO_SIZES);
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+ sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(0xa) |
+ R600_FETCH_FIFO_HIWATER(0xa) |
+ R600_DONE_FIFO_HIWATER(0xe0) |
+ R600_ALU_UPDATE_FIFO_HIWATER(0x8));
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630)) {
+ sq_ms_fifo_sizes &= ~R600_DONE_FIFO_HIWATER(0xff);
+ sq_ms_fifo_sizes |= R600_DONE_FIFO_HIWATER(0x4);
+ }
+ RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
+
+ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+ * should be adjusted as needed by the 2D/3D drivers. This just sets default values
+ */
+ sq_config = RADEON_READ(R600_SQ_CONFIG);
+ sq_config &= ~(R600_PS_PRIO(3) |
+ R600_VS_PRIO(3) |
+ R600_GS_PRIO(3) |
+ R600_ES_PRIO(3));
+ sq_config |= (R600_DX9_CONSTS |
+ R600_VC_ENABLE |
+ R600_PS_PRIO(0) |
+ R600_VS_PRIO(1) |
+ R600_GS_PRIO(2) |
+ R600_ES_PRIO(3));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R600) {
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(124) |
+ R600_NUM_VS_GPRS(124) |
+ R600_NUM_CLAUSE_TEMP_GPRS(4));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(0) |
+ R600_NUM_ES_GPRS(0));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(136) |
+ R600_NUM_VS_THREADS(48) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(4));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(128) |
+ R600_NUM_VS_STACK_ENTRIES(128));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(0) |
+ R600_NUM_ES_STACK_ENTRIES(0));
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780)) {
+ /* no vertex cache */
+ sq_config &= ~R600_VC_ENABLE;
+
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+ R600_NUM_VS_GPRS(44) |
+ R600_NUM_CLAUSE_TEMP_GPRS(2));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) |
+ R600_NUM_ES_GPRS(17));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+ R600_NUM_VS_THREADS(78) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(31));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) |
+ R600_NUM_VS_STACK_ENTRIES(40));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) |
+ R600_NUM_ES_STACK_ENTRIES(16));
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV630) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV635)) {
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+ R600_NUM_VS_GPRS(44) |
+ R600_NUM_CLAUSE_TEMP_GPRS(2));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(18) |
+ R600_NUM_ES_GPRS(18));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+ R600_NUM_VS_THREADS(78) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(31));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(40) |
+ R600_NUM_VS_STACK_ENTRIES(40));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(32) |
+ R600_NUM_ES_STACK_ENTRIES(16));
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV670) {
+ sq_gpr_resource_mgmt_1 = (R600_NUM_PS_GPRS(44) |
+ R600_NUM_VS_GPRS(44) |
+ R600_NUM_CLAUSE_TEMP_GPRS(2));
+ sq_gpr_resource_mgmt_2 = (R600_NUM_GS_GPRS(17) |
+ R600_NUM_ES_GPRS(17));
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS(79) |
+ R600_NUM_VS_THREADS(78) |
+ R600_NUM_GS_THREADS(4) |
+ R600_NUM_ES_THREADS(31));
+ sq_stack_resource_mgmt_1 = (R600_NUM_PS_STACK_ENTRIES(64) |
+ R600_NUM_VS_STACK_ENTRIES(64));
+ sq_stack_resource_mgmt_2 = (R600_NUM_GS_STACK_ENTRIES(64) |
+ R600_NUM_ES_STACK_ENTRIES(64));
+ }
+
+ RADEON_WRITE(R600_SQ_CONFIG, sq_config);
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1);
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2);
+ RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV610) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV620) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS780))
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_TC_ONLY));
+ else
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, R600_CACHE_INVALIDATION(R600_VC_AND_TC));
+
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_2S, (R600_S0_X(0xc) |
+ R600_S0_Y(0x4) |
+ R600_S1_X(0x4) |
+ R600_S1_Y(0xc)));
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_4S, (R600_S0_X(0xe) |
+ R600_S0_Y(0xe) |
+ R600_S1_X(0x2) |
+ R600_S1_Y(0x2) |
+ R600_S2_X(0xa) |
+ R600_S2_Y(0x6) |
+ R600_S3_X(0x6) |
+ R600_S3_Y(0xa)));
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0, (R600_S0_X(0xe) |
+ R600_S0_Y(0xb) |
+ R600_S1_X(0x4) |
+ R600_S1_Y(0xc) |
+ R600_S2_X(0x1) |
+ R600_S2_Y(0x6) |
+ R600_S3_X(0xa) |
+ R600_S3_Y(0xe)));
+ RADEON_WRITE(R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1, (R600_S4_X(0x6) |
+ R600_S4_Y(0x1) |
+ R600_S5_X(0x0) |
+ R600_S5_Y(0x0) |
+ R600_S6_X(0xb) |
+ R600_S6_Y(0x4) |
+ R600_S7_X(0x7) |
+ R600_S7_Y(0x8)));
+
+
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_R600:
+ case CHIP_RV630:
+ case CHIP_RV635:
+ gs_prim_buffer_depth = 0;
+ break;
+ case CHIP_RV610:
+ case CHIP_RS780:
+ case CHIP_RV620:
+ gs_prim_buffer_depth = 32;
+ break;
+ case CHIP_RV670:
+ gs_prim_buffer_depth = 128;
+ break;
+ default:
+ break;
+ }
+
+ num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16;
+ vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
+ /* Max value for this is 256 */
+ if (vgt_gs_per_es > 256)
+ vgt_gs_per_es = 256;
+
+ RADEON_WRITE(R600_VGT_ES_PER_GS, 128);
+ RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es);
+ RADEON_WRITE(R600_VGT_GS_PER_VS, 2);
+ RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16);
+
+ /* more default values. 2D/3D driver should adjust as needed */
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0);
+ RADEON_WRITE(R600_VGT_STRMOUT_EN, 0);
+ RADEON_WRITE(R600_SX_MISC, 0);
+ RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0);
+ RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0);
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0);
+ RADEON_WRITE(R600_SPI_INPUT_Z, 0);
+ RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2));
+ RADEON_WRITE(R600_CB_COLOR7_FRAG, 0);
+
+ /* clear render buffer base addresses */
+ RADEON_WRITE(R600_CB_COLOR0_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR1_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR2_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR3_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR4_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR5_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR6_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR7_BASE, 0);
+
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV610:
+ case CHIP_RS780:
+ case CHIP_RV620:
+ tc_cntl = R600_TC_L2_SIZE(8);
+ break;
+ case CHIP_RV630:
+ case CHIP_RV635:
+ tc_cntl = R600_TC_L2_SIZE(4);
+ break;
+ case CHIP_R600:
+ tc_cntl = R600_TC_L2_SIZE(0) | R600_L2_DISABLE_LATE_HIT;
+ break;
+ default:
+ tc_cntl = R600_TC_L2_SIZE(0);
+ break;
+ }
+
+ RADEON_WRITE(R600_TC_CNTL, tc_cntl);
+
+ hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL);
+ RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+ arb_pop = RADEON_READ(R600_ARB_POP);
+ arb_pop |= R600_ENABLE_TC128;
+ RADEON_WRITE(R600_ARB_POP, arb_pop);
+
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+ RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA |
+ R600_NUM_CLIP_SEQ(3)));
+ RADEON_WRITE(R600_PA_SC_ENHANCE, R600_FORCE_EOV_MAX_CLK_CNT(4095));
+
+}
+
+static u32 r700_get_tile_pipe_to_backend_map(u32 num_tile_pipes,
+ u32 num_backends,
+ u32 backend_disable_mask)
+{
+ u32 backend_map = 0;
+ u32 enabled_backends_mask;
+ u32 enabled_backends_count;
+ u32 cur_pipe;
+ u32 swizzle_pipe[R7XX_MAX_PIPES];
+ u32 cur_backend;
+ u32 i;
+
+ if (num_tile_pipes > R7XX_MAX_PIPES)
+ num_tile_pipes = R7XX_MAX_PIPES;
+ if (num_tile_pipes < 1)
+ num_tile_pipes = 1;
+ if (num_backends > R7XX_MAX_BACKENDS)
+ num_backends = R7XX_MAX_BACKENDS;
+ if (num_backends < 1)
+ num_backends = 1;
+
+ enabled_backends_mask = 0;
+ enabled_backends_count = 0;
+ for (i = 0; i < R7XX_MAX_BACKENDS; ++i) {
+ if (((backend_disable_mask >> i) & 1) == 0) {
+ enabled_backends_mask |= (1 << i);
+ ++enabled_backends_count;
+ }
+ if (enabled_backends_count == num_backends)
+ break;
+ }
+
+ if (enabled_backends_count == 0) {
+ enabled_backends_mask = 1;
+ enabled_backends_count = 1;
+ }
+
+ if (enabled_backends_count != num_backends)
+ num_backends = enabled_backends_count;
+
+ memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * R7XX_MAX_PIPES);
+ switch (num_tile_pipes) {
+ case 1:
+ swizzle_pipe[0] = 0;
+ break;
+ case 2:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 1;
+ break;
+ case 3:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 1;
+ break;
+ case 4:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 3;
+ swizzle_pipe[3] = 1;
+ break;
+ case 5:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 1;
+ swizzle_pipe[4] = 3;
+ break;
+ case 6:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 5;
+ swizzle_pipe[4] = 3;
+ swizzle_pipe[5] = 1;
+ break;
+ case 7:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 3;
+ swizzle_pipe[5] = 1;
+ swizzle_pipe[6] = 5;
+ break;
+ case 8:
+ swizzle_pipe[0] = 0;
+ swizzle_pipe[1] = 2;
+ swizzle_pipe[2] = 4;
+ swizzle_pipe[3] = 6;
+ swizzle_pipe[4] = 3;
+ swizzle_pipe[5] = 1;
+ swizzle_pipe[6] = 7;
+ swizzle_pipe[7] = 5;
+ break;
+ }
+
+ cur_backend = 0;
+ for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
+ while (((1 << cur_backend) & enabled_backends_mask) == 0)
+ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+
+ backend_map |= (u32)(((cur_backend & 3) << (swizzle_pipe[cur_pipe] * 2)));
+
+ cur_backend = (cur_backend + 1) % R7XX_MAX_BACKENDS;
+ }
+
+ return backend_map;
+}
+
+static void r700_gfx_init(struct drm_device *dev,
+ drm_radeon_private_t *dev_priv)
+{
+ int i, j, num_qd_pipes;
+ u32 sx_debug_1;
+ u32 smx_dc_ctl0;
+ u32 num_gs_verts_per_thread;
+ u32 vgt_gs_per_es;
+ u32 gs_prim_buffer_depth = 0;
+ u32 sq_ms_fifo_sizes;
+ u32 sq_config;
+ u32 sq_thread_resource_mgmt;
+ u32 hdp_host_path_cntl;
+ u32 sq_dyn_gpr_size_simd_ab_0;
+ u32 backend_map;
+ u32 gb_tiling_config = 0;
+ u32 cc_rb_backend_disable = 0;
+ u32 cc_gc_shader_pipe_config = 0;
+ u32 mc_arb_ramcfg;
+ u32 db_debug4;
+
+ /* setup chip specs */
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV770:
+ dev_priv->r600_max_pipes = 4;
+ dev_priv->r600_max_tile_pipes = 8;
+ dev_priv->r600_max_simds = 10;
+ dev_priv->r600_max_backends = 4;
+ dev_priv->r600_max_gprs = 256;
+ dev_priv->r600_max_threads = 248;
+ dev_priv->r600_max_stack_entries = 512;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16 * 2;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 112;
+ dev_priv->r600_sq_num_cf_insts = 2;
+
+ dev_priv->r700_sx_num_of_sets = 7;
+ dev_priv->r700_sc_prim_fifo_size = 0xF9;
+ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+ break;
+ case CHIP_RV730:
+ dev_priv->r600_max_pipes = 2;
+ dev_priv->r600_max_tile_pipes = 4;
+ dev_priv->r600_max_simds = 8;
+ dev_priv->r600_max_backends = 2;
+ dev_priv->r600_max_gprs = 128;
+ dev_priv->r600_max_threads = 248;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 8;
+ dev_priv->r600_max_gs_threads = 16 * 2;
+ dev_priv->r600_sx_max_export_size = 256;
+ dev_priv->r600_sx_max_export_pos_size = 32;
+ dev_priv->r600_sx_max_export_smx_size = 224;
+ dev_priv->r600_sq_num_cf_insts = 2;
+
+ dev_priv->r700_sx_num_of_sets = 7;
+ dev_priv->r700_sc_prim_fifo_size = 0xf9;
+ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+ break;
+ case CHIP_RV710:
+ dev_priv->r600_max_pipes = 2;
+ dev_priv->r600_max_tile_pipes = 2;
+ dev_priv->r600_max_simds = 2;
+ dev_priv->r600_max_backends = 1;
+ dev_priv->r600_max_gprs = 256;
+ dev_priv->r600_max_threads = 192;
+ dev_priv->r600_max_stack_entries = 256;
+ dev_priv->r600_max_hw_contexts = 4;
+ dev_priv->r600_max_gs_threads = 8 * 2;
+ dev_priv->r600_sx_max_export_size = 128;
+ dev_priv->r600_sx_max_export_pos_size = 16;
+ dev_priv->r600_sx_max_export_smx_size = 112;
+ dev_priv->r600_sq_num_cf_insts = 1;
+
+ dev_priv->r700_sx_num_of_sets = 7;
+ dev_priv->r700_sc_prim_fifo_size = 0x40;
+ dev_priv->r700_sc_hiz_tile_fifo_size = 0x30;
+ dev_priv->r700_sc_earlyz_tile_fifo_fize = 0x130;
+ break;
+ default:
+ break;
+ }
+
+ /* Initialize HDP */
+ j = 0;
+ for (i = 0; i < 32; i++) {
+ RADEON_WRITE((0x2c14 + j), 0x00000000);
+ RADEON_WRITE((0x2c18 + j), 0x00000000);
+ RADEON_WRITE((0x2c1c + j), 0x00000000);
+ RADEON_WRITE((0x2c20 + j), 0x00000000);
+ RADEON_WRITE((0x2c24 + j), 0x00000000);
+ j += 0x18;
+ }
+
+ RADEON_WRITE(R600_GRBM_CNTL, R600_GRBM_READ_TIMEOUT(0xff));
+
+ /* setup tiling, simd, pipe config */
+ mc_arb_ramcfg = RADEON_READ(R700_MC_ARB_RAMCFG);
+
+ switch (dev_priv->r600_max_tile_pipes) {
+ case 1:
+ gb_tiling_config |= R600_PIPE_TILING(0);
+ break;
+ case 2:
+ gb_tiling_config |= R600_PIPE_TILING(1);
+ break;
+ case 4:
+ gb_tiling_config |= R600_PIPE_TILING(2);
+ break;
+ case 8:
+ gb_tiling_config |= R600_PIPE_TILING(3);
+ break;
+ default:
+ break;
+ }
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)
+ gb_tiling_config |= R600_BANK_TILING(1);
+ else
+ gb_tiling_config |= R600_BANK_TILING((mc_arb_ramcfg >> R700_NOOFBANK_SHIFT) & R700_NOOFBANK_MASK);
+
+ gb_tiling_config |= R600_GROUP_SIZE(0);
+
+ if (((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK) > 3) {
+ gb_tiling_config |= R600_ROW_TILING(3);
+ gb_tiling_config |= R600_SAMPLE_SPLIT(3);
+ } else {
+ gb_tiling_config |=
+ R600_ROW_TILING(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK));
+ gb_tiling_config |=
+ R600_SAMPLE_SPLIT(((mc_arb_ramcfg >> R700_NOOFROWS_SHIFT) & R700_NOOFROWS_MASK));
+ }
+
+ gb_tiling_config |= R600_BANK_SWAPS(1);
+
+ backend_map = r700_get_tile_pipe_to_backend_map(dev_priv->r600_max_tile_pipes,
+ dev_priv->r600_max_backends,
+ (0xff << dev_priv->r600_max_backends) & 0xff);
+ gb_tiling_config |= R600_BACKEND_MAP(backend_map);
+
+ cc_gc_shader_pipe_config =
+ R600_INACTIVE_QD_PIPES((R7XX_MAX_PIPES_MASK << dev_priv->r600_max_pipes) & R7XX_MAX_PIPES_MASK);
+ cc_gc_shader_pipe_config |=
+ R600_INACTIVE_SIMDS((R7XX_MAX_SIMDS_MASK << dev_priv->r600_max_simds) & R7XX_MAX_SIMDS_MASK);
+
+ cc_rb_backend_disable =
+ R600_BACKEND_DISABLE((R7XX_MAX_BACKENDS_MASK << dev_priv->r600_max_backends) & R7XX_MAX_BACKENDS_MASK);
+
+ RADEON_WRITE(R600_GB_TILING_CONFIG, gb_tiling_config);
+ RADEON_WRITE(R600_DCP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+ RADEON_WRITE(R600_HDP_TILING_CONFIG, (gb_tiling_config & 0xffff));
+
+ RADEON_WRITE(R600_CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+ RADEON_WRITE(R600_CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+ RADEON_WRITE(R600_GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config);
+
+ RADEON_WRITE(R700_CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
+ RADEON_WRITE(R700_CGTS_SYS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_USER_SYS_TCC_DISABLE, 0);
+ RADEON_WRITE(R700_CGTS_USER_TCC_DISABLE, 0);
+
+ num_qd_pipes =
+ R7XX_MAX_BACKENDS - r600_count_pipe_bits(cc_gc_shader_pipe_config & R600_INACTIVE_QD_PIPES_MASK);
+ RADEON_WRITE(R600_VGT_OUT_DEALLOC_CNTL, (num_qd_pipes * 4) & R600_DEALLOC_DIST_MASK);
+ RADEON_WRITE(R600_VGT_VERTEX_REUSE_BLOCK_CNTL, ((num_qd_pipes * 4) - 2) & R600_VTX_REUSE_DEPTH_MASK);
+
+ /* set HW defaults for 3D engine */
+ RADEON_WRITE(R600_CP_QUEUE_THRESHOLDS, (R600_ROQ_IB1_START(0x16) |
+ R600_ROQ_IB2_START(0x2b)));
+
+ RADEON_WRITE(R600_CP_MEQ_THRESHOLDS, R700_STQ_SPLIT(0x30));
+
+ RADEON_WRITE(R600_TA_CNTL_AUX, (R600_DISABLE_CUBE_ANISO |
+ R600_SYNC_GRADIENT |
+ R600_SYNC_WALKER |
+ R600_SYNC_ALIGNER));
+
+ sx_debug_1 = RADEON_READ(R700_SX_DEBUG_1);
+ sx_debug_1 |= R700_ENABLE_NEW_SMX_ADDRESS;
+ RADEON_WRITE(R700_SX_DEBUG_1, sx_debug_1);
+
+ smx_dc_ctl0 = RADEON_READ(R600_SMX_DC_CTL0);
+ smx_dc_ctl0 &= ~R700_CACHE_DEPTH(0x1ff);
+ smx_dc_ctl0 |= R700_CACHE_DEPTH((dev_priv->r700_sx_num_of_sets * 64) - 1);
+ RADEON_WRITE(R600_SMX_DC_CTL0, smx_dc_ctl0);
+
+ RADEON_WRITE(R700_SMX_EVENT_CTL, (R700_ES_FLUSH_CTL(4) |
+ R700_GS_FLUSH_CTL(4) |
+ R700_ACK_FLUSH_CTL(3) |
+ R700_SYNC_FLUSH_CTL));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV770)
+ RADEON_WRITE(R700_DB_DEBUG3, R700_DB_CLK_OFF_DELAY(0x1f));
+ else {
+ db_debug4 = RADEON_READ(RV700_DB_DEBUG4);
+ db_debug4 |= RV700_DISABLE_TILE_COVERED_FOR_PS_ITER;
+ RADEON_WRITE(RV700_DB_DEBUG4, db_debug4);
+ }
+
+ RADEON_WRITE(R600_SX_EXPORT_BUFFER_SIZES, (R600_COLOR_BUFFER_SIZE((dev_priv->r600_sx_max_export_size / 4) - 1) |
+ R600_POSITION_BUFFER_SIZE((dev_priv->r600_sx_max_export_pos_size / 4) - 1) |
+ R600_SMX_BUFFER_SIZE((dev_priv->r600_sx_max_export_smx_size / 4) - 1)));
+
+ RADEON_WRITE(R700_PA_SC_FIFO_SIZE_R7XX, (R700_SC_PRIM_FIFO_SIZE(dev_priv->r700_sc_prim_fifo_size) |
+ R700_SC_HIZ_TILE_FIFO_SIZE(dev_priv->r700_sc_hiz_tile_fifo_size) |
+ R700_SC_EARLYZ_TILE_FIFO_SIZE(dev_priv->r700_sc_earlyz_tile_fifo_fize)));
+
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+
+ RADEON_WRITE(R600_VGT_NUM_INSTANCES, 1);
+
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL, R600_GPR_WRITE_PRIORITY(0));
+
+ RADEON_WRITE(R600_SPI_CONFIG_CNTL_1, R600_VTX_DONE_DELAY(4));
+
+ RADEON_WRITE(R600_CP_PERFMON_CNTL, 0);
+
+ sq_ms_fifo_sizes = (R600_CACHE_FIFO_SIZE(16 * dev_priv->r600_sq_num_cf_insts) |
+ R600_DONE_FIFO_HIWATER(0xe0) |
+ R600_ALU_UPDATE_FIFO_HIWATER(0x8));
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV770:
+ sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x1);
+ break;
+ case CHIP_RV730:
+ case CHIP_RV710:
+ default:
+ sq_ms_fifo_sizes |= R600_FETCH_FIFO_HIWATER(0x4);
+ break;
+ }
+ RADEON_WRITE(R600_SQ_MS_FIFO_SIZES, sq_ms_fifo_sizes);
+
+ /* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
+ * should be adjusted as needed by the 2D/3D drivers. This just sets default values
+ */
+ sq_config = RADEON_READ(R600_SQ_CONFIG);
+ sq_config &= ~(R600_PS_PRIO(3) |
+ R600_VS_PRIO(3) |
+ R600_GS_PRIO(3) |
+ R600_ES_PRIO(3));
+ sq_config |= (R600_DX9_CONSTS |
+ R600_VC_ENABLE |
+ R600_EXPORT_SRC_C |
+ R600_PS_PRIO(0) |
+ R600_VS_PRIO(1) |
+ R600_GS_PRIO(2) |
+ R600_ES_PRIO(3));
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)
+ /* no vertex cache */
+ sq_config &= ~R600_VC_ENABLE;
+
+ RADEON_WRITE(R600_SQ_CONFIG, sq_config);
+
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_1, (R600_NUM_PS_GPRS((dev_priv->r600_max_gprs * 24)/64) |
+ R600_NUM_VS_GPRS((dev_priv->r600_max_gprs * 24)/64) |
+ R600_NUM_CLAUSE_TEMP_GPRS(((dev_priv->r600_max_gprs * 24)/64)/2)));
+
+ RADEON_WRITE(R600_SQ_GPR_RESOURCE_MGMT_2, (R600_NUM_GS_GPRS((dev_priv->r600_max_gprs * 7)/64) |
+ R600_NUM_ES_GPRS((dev_priv->r600_max_gprs * 7)/64)));
+
+ sq_thread_resource_mgmt = (R600_NUM_PS_THREADS((dev_priv->r600_max_threads * 4)/8) |
+ R600_NUM_VS_THREADS((dev_priv->r600_max_threads * 2)/8) |
+ R600_NUM_ES_THREADS((dev_priv->r600_max_threads * 1)/8));
+ if (((dev_priv->r600_max_threads * 1) / 8) > dev_priv->r600_max_gs_threads)
+ sq_thread_resource_mgmt |= R600_NUM_GS_THREADS(dev_priv->r600_max_gs_threads);
+ else
+ sq_thread_resource_mgmt |= R600_NUM_GS_THREADS((dev_priv->r600_max_gs_threads * 1)/8);
+ RADEON_WRITE(R600_SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
+
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_1, (R600_NUM_PS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) |
+ R600_NUM_VS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4)));
+
+ RADEON_WRITE(R600_SQ_STACK_RESOURCE_MGMT_2, (R600_NUM_GS_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4) |
+ R600_NUM_ES_STACK_ENTRIES((dev_priv->r600_max_stack_entries * 1)/4)));
+
+ sq_dyn_gpr_size_simd_ab_0 = (R700_SIMDA_RING0((dev_priv->r600_max_gprs * 38)/64) |
+ R700_SIMDA_RING1((dev_priv->r600_max_gprs * 38)/64) |
+ R700_SIMDB_RING0((dev_priv->r600_max_gprs * 38)/64) |
+ R700_SIMDB_RING1((dev_priv->r600_max_gprs * 38)/64));
+
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_0, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_1, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_2, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_3, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_4, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_5, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_6, sq_dyn_gpr_size_simd_ab_0);
+ RADEON_WRITE(R700_SQ_DYN_GPR_SIZE_SIMD_AB_7, sq_dyn_gpr_size_simd_ab_0);
+
+ RADEON_WRITE(R700_PA_SC_FORCE_EOV_MAX_CNTS, (R700_FORCE_EOV_MAX_CLK_CNT(4095) |
+ R700_FORCE_EOV_MAX_REZ_CNT(255)));
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV710)
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_TC_ONLY) |
+ R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO)));
+ else
+ RADEON_WRITE(R600_VGT_CACHE_INVALIDATION, (R600_CACHE_INVALIDATION(R600_VC_AND_TC) |
+ R700_AUTO_INVLD_EN(R700_ES_AND_GS_AUTO)));
+
+ switch (dev_priv->flags & RADEON_FAMILY_MASK) {
+ case CHIP_RV770:
+ case CHIP_RV730:
+ gs_prim_buffer_depth = 384;
+ break;
+ case CHIP_RV710:
+ gs_prim_buffer_depth = 128;
+ break;
+ default:
+ break;
+ }
+
+ num_gs_verts_per_thread = dev_priv->r600_max_pipes * 16;
+ vgt_gs_per_es = gs_prim_buffer_depth + num_gs_verts_per_thread;
+ /* Max value for this is 256 */
+ if (vgt_gs_per_es > 256)
+ vgt_gs_per_es = 256;
+
+ RADEON_WRITE(R600_VGT_ES_PER_GS, 128);
+ RADEON_WRITE(R600_VGT_GS_PER_ES, vgt_gs_per_es);
+ RADEON_WRITE(R600_VGT_GS_PER_VS, 2);
+
+ /* more default values. 2D/3D driver should adjust as needed */
+ RADEON_WRITE(R600_VGT_GS_VERTEX_REUSE, 16);
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE_STATE, 0);
+ RADEON_WRITE(R600_VGT_STRMOUT_EN, 0);
+ RADEON_WRITE(R600_SX_MISC, 0);
+ RADEON_WRITE(R600_PA_SC_MODE_CNTL, 0);
+ RADEON_WRITE(R700_PA_SC_EDGERULE, 0xaaaaaaaa);
+ RADEON_WRITE(R600_PA_SC_AA_CONFIG, 0);
+ RADEON_WRITE(R600_PA_SC_CLIPRECT_RULE, 0xffff);
+ RADEON_WRITE(R600_PA_SC_LINE_STIPPLE, 0);
+ RADEON_WRITE(R600_SPI_INPUT_Z, 0);
+ RADEON_WRITE(R600_SPI_PS_IN_CONTROL_0, R600_NUM_INTERP(2));
+ RADEON_WRITE(R600_CB_COLOR7_FRAG, 0);
+
+ /* clear render buffer base addresses */
+ RADEON_WRITE(R600_CB_COLOR0_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR1_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR2_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR3_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR4_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR5_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR6_BASE, 0);
+ RADEON_WRITE(R600_CB_COLOR7_BASE, 0);
+
+ RADEON_WRITE(R700_TCP_CNTL, 0);
+
+ hdp_host_path_cntl = RADEON_READ(R600_HDP_HOST_PATH_CNTL);
+ RADEON_WRITE(R600_HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
+
+ RADEON_WRITE(R600_PA_SC_MULTI_CHIP_CNTL, 0);
+
+ RADEON_WRITE(R600_PA_CL_ENHANCE, (R600_CLIP_VTX_REORDER_ENA |
+ R600_NUM_CLIP_SEQ(3)));
+
+}
+
+static void r600_cp_init_ring_buffer(struct drm_device *dev,
+ drm_radeon_private_t *dev_priv,
+ struct drm_file *file_priv)
+{
+ struct drm_radeon_master_private *master_priv;
+ u32 ring_start;
+ u64 rptr_addr;
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+ r700_gfx_init(dev, dev_priv);
+ else
+ r600_gfx_init(dev, dev_priv);
+
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, R600_SOFT_RESET_CP);
+ RADEON_READ(R600_GRBM_SOFT_RESET);
+ DRM_UDELAY(15000);
+ RADEON_WRITE(R600_GRBM_SOFT_RESET, 0);
+
+
+ /* Set ring buffer size */
+#ifdef __BIG_ENDIAN
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_BUF_SWAP_32BIT |
+ RADEON_RB_NO_UPDATE |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#else
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_RB_NO_UPDATE |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#endif
+
+ RADEON_WRITE(R600_CP_SEM_WAIT_TIMER, 0x4);
+
+ /* Set the write pointer delay */
+ RADEON_WRITE(R600_CP_RB_WPTR_DELAY, 0);
+
+#ifdef __BIG_ENDIAN
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_BUF_SWAP_32BIT |
+ RADEON_RB_NO_UPDATE |
+ RADEON_RB_RPTR_WR_ENA |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#else
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_RB_NO_UPDATE |
+ RADEON_RB_RPTR_WR_ENA |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#endif
+
+ /* Initialize the ring buffer's read and write pointers */
+ RADEON_WRITE(R600_CP_RB_RPTR_WR, 0);
+ RADEON_WRITE(R600_CP_RB_WPTR, 0);
+ SET_RING_HEAD(dev_priv, 0);
+ dev_priv->ring.tail = 0;
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ rptr_addr = dev_priv->ring_rptr->offset
+ - dev->agp->base +
+ dev_priv->gart_vm_start;
+ } else
+#endif
+ {
+ rptr_addr = dev_priv->ring_rptr->offset
+ - ((unsigned long) dev->sg->virtual)
+ + dev_priv->gart_vm_start;
+ }
+ RADEON_WRITE(R600_CP_RB_RPTR_ADDR,
+ rptr_addr & 0xffffffff);
+ RADEON_WRITE(R600_CP_RB_RPTR_ADDR_HI,
+ upper_32_bits(rptr_addr));
+
+#ifdef __BIG_ENDIAN
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ RADEON_BUF_SWAP_32BIT |
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#else
+ RADEON_WRITE(R600_CP_RB_CNTL,
+ (dev_priv->ring.rptr_update_l2qw << 8) |
+ dev_priv->ring.size_l2qw);
+#endif
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ /* XXX */
+ radeon_write_agp_base(dev_priv, dev->agp->base);
+
+ /* XXX */
+ radeon_write_agp_location(dev_priv,
+ (((dev_priv->gart_vm_start - 1 +
+ dev_priv->gart_size) & 0xffff0000) |
+ (dev_priv->gart_vm_start >> 16)));
+
+ ring_start = (dev_priv->cp_ring->offset
+ - dev->agp->base
+ + dev_priv->gart_vm_start);
+ } else
+#endif
+ ring_start = (dev_priv->cp_ring->offset
+ - (unsigned long)dev->sg->virtual
+ + dev_priv->gart_vm_start);
+
+ RADEON_WRITE(R600_CP_RB_BASE, ring_start >> 8);
+
+ RADEON_WRITE(R600_CP_ME_CNTL, 0xff);
+
+ RADEON_WRITE(R600_CP_DEBUG, (1 << 27) | (1 << 28));
+
+ /* Initialize the scratch register pointer. This will cause
+ * the scratch register values to be written out to memory
+ * whenever they are updated.
+ *
+ * We simply put this behind the ring read pointer, this works
+ * with PCI GART as well as (whatever kind of) AGP GART
+ */
+ {
+ u64 scratch_addr;
+
+ scratch_addr = RADEON_READ(R600_CP_RB_RPTR_ADDR);
+ scratch_addr |= ((u64)RADEON_READ(R600_CP_RB_RPTR_ADDR_HI)) << 32;
+ scratch_addr += R600_SCRATCH_REG_OFFSET;
+ scratch_addr >>= 8;
+ scratch_addr &= 0xffffffff;
+
+ RADEON_WRITE(R600_SCRATCH_ADDR, (uint32_t)scratch_addr);
+ }
+
+ RADEON_WRITE(R600_SCRATCH_UMSK, 0x7);
+
+ /* Turn on bus mastering */
+ radeon_enable_bm(dev_priv);
+
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(0), 0);
+ RADEON_WRITE(R600_LAST_FRAME_REG, 0);
+
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(1), 0);
+ RADEON_WRITE(R600_LAST_DISPATCH_REG, 0);
+
+ radeon_write_ring_rptr(dev_priv, R600_SCRATCHOFF(2), 0);
+ RADEON_WRITE(R600_LAST_CLEAR_REG, 0);
+
+ /* reset sarea copies of these */
+ master_priv = file_priv->master->driver_priv;
+ if (master_priv->sarea_priv) {
+ master_priv->sarea_priv->last_frame = 0;
+ master_priv->sarea_priv->last_dispatch = 0;
+ master_priv->sarea_priv->last_clear = 0;
+ }
+
+ r600_do_wait_for_idle(dev_priv);
+
+}
+
+int r600_do_cleanup_cp(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG("\n");
+
+ /* Make sure interrupts are disabled here because the uninstall ioctl
+ * may not have been called from userspace and after dev_private
+ * is freed, it's too late.
+ */
+ if (dev->irq_enabled)
+ drm_irq_uninstall(dev);
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ if (dev_priv->cp_ring != NULL) {
+ drm_core_ioremapfree(dev_priv->cp_ring, dev);
+ dev_priv->cp_ring = NULL;
+ }
+ if (dev_priv->ring_rptr != NULL) {
+ drm_core_ioremapfree(dev_priv->ring_rptr, dev);
+ dev_priv->ring_rptr = NULL;
+ }
+ if (dev->agp_buffer_map != NULL) {
+ drm_core_ioremapfree(dev->agp_buffer_map, dev);
+ dev->agp_buffer_map = NULL;
+ }
+ } else
+#endif
+ {
+
+ if (dev_priv->gart_info.bus_addr)
+ r600_page_table_cleanup(dev, &dev_priv->gart_info);
+
+ if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) {
+ drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
+ dev_priv->gart_info.addr = NULL;
+ }
+ }
+ /* only clear to the start of flags */
+ memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
+
+ return 0;
+}
+
+int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+ struct drm_file *file_priv)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv;
+
+ DRM_DEBUG("\n");
+
+ /* if we require new memory map but we don't have it fail */
+ if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
+ DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) {
+ DRM_DEBUG("Forcing AGP card to PCI mode\n");
+ dev_priv->flags &= ~RADEON_IS_AGP;
+ /* The writeback test succeeds, but when writeback is enabled,
+ * the ring buffer read ptr update fails after first 128 bytes.
+ */
+ radeon_no_wb = 1;
+ } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE))
+ && !init->is_pci) {
+ DRM_DEBUG("Restoring AGP flag\n");
+ dev_priv->flags |= RADEON_IS_AGP;
+ }
+
+ dev_priv->usec_timeout = init->usec_timeout;
+ if (dev_priv->usec_timeout < 1 ||
+ dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
+ DRM_DEBUG("TIMEOUT problem!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ /* Enable vblank on CRTC1 for older X servers
+ */
+ dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
+
+ dev_priv->cp_mode = init->cp_mode;
+
+ /* We don't support anything other than bus-mastering ring mode,
+ * but the ring can be in either AGP or PCI space for the ring
+ * read pointer.
+ */
+ if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
+ (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
+ DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ switch (init->fb_bpp) {
+ case 16:
+ dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
+ break;
+ case 32:
+ default:
+ dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
+ break;
+ }
+ dev_priv->front_offset = init->front_offset;
+ dev_priv->front_pitch = init->front_pitch;
+ dev_priv->back_offset = init->back_offset;
+ dev_priv->back_pitch = init->back_pitch;
+
+ dev_priv->ring_offset = init->ring_offset;
+ dev_priv->ring_rptr_offset = init->ring_rptr_offset;
+ dev_priv->buffers_offset = init->buffers_offset;
+ dev_priv->gart_textures_offset = init->gart_textures_offset;
+
+ master_priv->sarea = drm_getsarea(dev);
+ if (!master_priv->sarea) {
+ DRM_ERROR("could not find sarea!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
+ if (!dev_priv->cp_ring) {
+ DRM_ERROR("could not find cp ring region!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
+ if (!dev_priv->ring_rptr) {
+ DRM_ERROR("could not find ring read pointer!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ dev->agp_buffer_token = init->buffers_offset;
+ dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
+ if (!dev->agp_buffer_map) {
+ DRM_ERROR("could not find dma buffer region!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ if (init->gart_textures_offset) {
+ dev_priv->gart_textures =
+ drm_core_findmap(dev, init->gart_textures_offset);
+ if (!dev_priv->gart_textures) {
+ DRM_ERROR("could not find GART texture region!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ }
+
+#if __OS_HAS_AGP
+ /* XXX */
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ drm_core_ioremap_wc(dev_priv->cp_ring, dev);
+ drm_core_ioremap_wc(dev_priv->ring_rptr, dev);
+ drm_core_ioremap_wc(dev->agp_buffer_map, dev);
+ if (!dev_priv->cp_ring->handle ||
+ !dev_priv->ring_rptr->handle ||
+ !dev->agp_buffer_map->handle) {
+ DRM_ERROR("could not find ioremap agp regions!\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+ } else
+#endif
+ {
+ dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+ dev_priv->ring_rptr->handle =
+ (void *)dev_priv->ring_rptr->offset;
+ dev->agp_buffer_map->handle =
+ (void *)dev->agp_buffer_map->offset;
+
+ DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
+ dev_priv->cp_ring->handle);
+ DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
+ dev_priv->ring_rptr->handle);
+ DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
+ dev->agp_buffer_map->handle);
+ }
+
+ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 24;
+ dev_priv->fb_size =
+ (((radeon_read_fb_location(dev_priv) & 0xffff0000u) << 8) + 0x1000000)
+ - dev_priv->fb_location;
+
+ dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
+ ((dev_priv->front_offset
+ + dev_priv->fb_location) >> 10));
+
+ dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
+ ((dev_priv->back_offset
+ + dev_priv->fb_location) >> 10));
+
+ dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
+ ((dev_priv->depth_offset
+ + dev_priv->fb_location) >> 10));
+
+ dev_priv->gart_size = init->gart_size;
+
+ /* New let's set the memory map ... */
+ if (dev_priv->new_memmap) {
+ u32 base = 0;
+
+ DRM_INFO("Setting GART location based on new memory map\n");
+
+ /* If using AGP, try to locate the AGP aperture at the same
+ * location in the card and on the bus, though we have to
+ * align it down.
+ */
+#if __OS_HAS_AGP
+ /* XXX */
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ base = dev->agp->base;
+ /* Check if valid */
+ if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
+ base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
+ DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
+ dev->agp->base);
+ base = 0;
+ }
+ }
+#endif
+ /* If not or if AGP is at 0 (Macs), try to put it elsewhere */
+ if (base == 0) {
+ base = dev_priv->fb_location + dev_priv->fb_size;
+ if (base < dev_priv->fb_location ||
+ ((base + dev_priv->gart_size) & 0xfffffffful) < base)
+ base = dev_priv->fb_location
+ - dev_priv->gart_size;
+ }
+ dev_priv->gart_vm_start = base & 0xffc00000u;
+ if (dev_priv->gart_vm_start != base)
+ DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
+ base, dev_priv->gart_vm_start);
+ }
+
+#if __OS_HAS_AGP
+ /* XXX */
+ if (dev_priv->flags & RADEON_IS_AGP)
+ dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+ - dev->agp->base
+ + dev_priv->gart_vm_start);
+ else
+#endif
+ dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
+ - (unsigned long)dev->sg->virtual
+ + dev_priv->gart_vm_start);
+
+ DRM_DEBUG("fb 0x%08x size %d\n",
+ (unsigned int) dev_priv->fb_location,
+ (unsigned int) dev_priv->fb_size);
+ DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
+ DRM_DEBUG("dev_priv->gart_vm_start 0x%08x\n",
+ (unsigned int) dev_priv->gart_vm_start);
+ DRM_DEBUG("dev_priv->gart_buffers_offset 0x%08lx\n",
+ dev_priv->gart_buffers_offset);
+
+ dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
+ dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
+ + init->ring_size / sizeof(u32));
+ dev_priv->ring.size = init->ring_size;
+ dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
+
+ dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
+ dev_priv->ring.rptr_update_l2qw = drm_order(/* init->rptr_update */ 4096 / 8);
+
+ dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
+ dev_priv->ring.fetch_size_l2ow = drm_order(/* init->fetch_size */ 32 / 16);
+
+ dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
+
+ dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
+
+#if __OS_HAS_AGP
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ /* XXX turn off pcie gart */
+ } else
+#endif
+ {
+ dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
+ /* if we have an offset set from userspace */
+ if (!dev_priv->pcigart_offset_set) {
+ DRM_ERROR("Need gart offset from userspace\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ DRM_DEBUG("Using gart offset 0x%08lx\n", dev_priv->pcigart_offset);
+
+ dev_priv->gart_info.bus_addr =
+ dev_priv->pcigart_offset + dev_priv->fb_location;
+ dev_priv->gart_info.mapping.offset =
+ dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
+ dev_priv->gart_info.mapping.size =
+ dev_priv->gart_info.table_size;
+
+ drm_core_ioremap_wc(&dev_priv->gart_info.mapping, dev);
+ if (!dev_priv->gart_info.mapping.handle) {
+ DRM_ERROR("ioremap failed.\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ dev_priv->gart_info.addr =
+ dev_priv->gart_info.mapping.handle;
+
+ DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
+ dev_priv->gart_info.addr,
+ dev_priv->pcigart_offset);
+
+ if (!r600_page_table_init(dev)) {
+ DRM_ERROR("Failed to init GART table\n");
+ r600_do_cleanup_cp(dev);
+ return -EINVAL;
+ }
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+ r700_vm_init(dev);
+ else
+ r600_vm_init(dev);
+ }
+
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770))
+ r700_cp_load_microcode(dev_priv);
+ else
+ r600_cp_load_microcode(dev_priv);
+
+ r600_cp_init_ring_buffer(dev, dev_priv, file_priv);
+
+ dev_priv->last_buf = 0;
+
+ r600_do_engine_reset(dev);
+ r600_test_writeback(dev_priv);
+
+ return 0;
+}
+
+int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ DRM_DEBUG("\n");
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)) {
+ r700_vm_init(dev);
+ r700_cp_load_microcode(dev_priv);
+ } else {
+ r600_vm_init(dev);
+ r600_cp_load_microcode(dev_priv);
+ }
+ r600_cp_init_ring_buffer(dev, dev_priv, file_priv);
+ r600_do_engine_reset(dev);
+
+ return 0;
+}
+
+/* Wait for the CP to go idle.
+ */
+int r600_do_cp_idle(drm_radeon_private_t *dev_priv)
+{
+ RING_LOCALS;
+ DRM_DEBUG("\n");
+
+ BEGIN_RING(5);
+ OUT_RING(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
+ OUT_RING(R600_CACHE_FLUSH_AND_INV_EVENT);
+ /* wait for 3D idle clean */
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+ OUT_RING((R600_WAIT_UNTIL - R600_SET_CONFIG_REG_OFFSET) >> 2);
+ OUT_RING(RADEON_WAIT_3D_IDLE | RADEON_WAIT_3D_IDLECLEAN);
+
+ ADVANCE_RING();
+ COMMIT_RING();
+
+ return r600_do_wait_for_idle(dev_priv);
+}
+
+/* Start the Command Processor.
+ */
+void r600_do_cp_start(drm_radeon_private_t *dev_priv)
+{
+ u32 cp_me;
+ RING_LOCALS;
+ DRM_DEBUG("\n");
+
+ BEGIN_RING(7);
+ OUT_RING(CP_PACKET3(R600_IT_ME_INITIALIZE, 5));
+ OUT_RING(0x00000001);
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV770))
+ OUT_RING(0x00000003);
+ else
+ OUT_RING(0x00000000);
+ OUT_RING((dev_priv->r600_max_hw_contexts - 1));
+ OUT_RING(R600_ME_INITIALIZE_DEVICE_ID(1));
+ OUT_RING(0x00000000);
+ OUT_RING(0x00000000);
+ ADVANCE_RING();
+ COMMIT_RING();
+
+ /* set the mux and reset the halt bit */
+ cp_me = 0xff;
+ RADEON_WRITE(R600_CP_ME_CNTL, cp_me);
+
+ dev_priv->cp_running = 1;
+
+}
+
+void r600_do_cp_reset(drm_radeon_private_t *dev_priv)
+{
+ u32 cur_read_ptr;
+ DRM_DEBUG("\n");
+
+ cur_read_ptr = RADEON_READ(R600_CP_RB_RPTR);
+ RADEON_WRITE(R600_CP_RB_WPTR, cur_read_ptr);
+ SET_RING_HEAD(dev_priv, cur_read_ptr);
+ dev_priv->ring.tail = cur_read_ptr;
+}
+
+void r600_do_cp_stop(drm_radeon_private_t *dev_priv)
+{
+ uint32_t cp_me;
+
+ DRM_DEBUG("\n");
+
+ cp_me = 0xff | R600_CP_ME_HALT;
+
+ RADEON_WRITE(R600_CP_ME_CNTL, cp_me);
+
+ dev_priv->cp_running = 0;
+}
+
+int r600_cp_dispatch_indirect(struct drm_device *dev,
+ struct drm_buf *buf, int start, int end)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ RING_LOCALS;
+
+ if (start != end) {
+ unsigned long offset = (dev_priv->gart_buffers_offset
+ + buf->offset + start);
+ int dwords = (end - start + 3) / sizeof(u32);
+
+ DRM_DEBUG("dwords:%d\n", dwords);
+ DRM_DEBUG("offset 0x%lx\n", offset);
+
+
+ /* Indirect buffer data must be a multiple of 16 dwords.
+ * pad the data with a Type-2 CP packet.
+ */
+ while (dwords & 0xf) {
+ u32 *data = (u32 *)
+ ((char *)dev->agp_buffer_map->handle
+ + buf->offset + start);
+ data[dwords++] = RADEON_CP_PACKET2;
+ }
+
+ /* Fire off the indirect buffer */
+ BEGIN_RING(4);
+ OUT_RING(CP_PACKET3(R600_IT_INDIRECT_BUFFER, 2));
+ OUT_RING((offset & 0xfffffffc));
+ OUT_RING((upper_32_bits(offset) & 0xff));
+ OUT_RING(dwords);
+ ADVANCE_RING();
+ }
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/radeon/r600_microcode.h b/drivers/gpu/drm/radeon/r600_microcode.h
new file mode 100644
index 00000000000..778c8b4b2fd
--- /dev/null
+++ b/drivers/gpu/drm/radeon/r600_microcode.h
@@ -0,0 +1,23297 @@
+/*
+ * Copyright 2008-2009 Advanced Micro Devices, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef R600_MICROCODE_H
+#define R600_MICROCODE_H
+
+static const int ME_JUMP_TABLE_START = 1764;
+static const int ME_JUMP_TABLE_END = 1792;
+
+#define PFP_UCODE_SIZE 576
+#define PM4_UCODE_SIZE 1792
+#define R700_PFP_UCODE_SIZE 848
+#define R700_PM4_UCODE_SIZE 1360
+
+static const u32 R600_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x614 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000020, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000021, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x0000001d, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x0000001d, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000030, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x00000010, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000030, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000032, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x0000002d, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x080 },
+ { 0x0000002e, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x081 },
+ { 0x00000000, 0x00400000, 0x087 },
+ { 0x0000002d, 0x00203623, 0x000 },
+ { 0x0000002e, 0x00203624, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x087 },
+ { 0x00000000, 0x00600000, 0x5ed },
+ { 0x00000000, 0x00600000, 0x5e1 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08a },
+ { 0x00000018, 0xc0403620, 0x090 },
+ { 0x00000000, 0x2ee00000, 0x08e },
+ { 0x00000000, 0x2ce00000, 0x08d },
+ { 0x00000002, 0x00400e2d, 0x08f },
+ { 0x00000003, 0x00400e2d, 0x08f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000018, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x095 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x09d },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09b },
+ { 0x00000000, 0x2ce00000, 0x09a },
+ { 0x00000002, 0x00400e2d, 0x09c },
+ { 0x00000003, 0x00400e2d, 0x09c },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a4 },
+ { 0x0000001c, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x0000001b, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0db },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x28c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x128 },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0c5 },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0d6 },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0d4 },
+ { 0x00000013, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0cf },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ce },
+ { 0x00003f00, 0x00400c11, 0x0d0 },
+ { 0x00001f00, 0x00400c11, 0x0d0 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0d6 },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00284a22, 0x000 },
+ { 0x00000030, 0x00200e2d, 0x000 },
+ { 0x0000002e, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e3 },
+ { 0x00000000, 0x00600000, 0x5e7 },
+ { 0x00000000, 0x00400000, 0x0e4 },
+ { 0x00000000, 0x00600000, 0x5ea },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x0000001d, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f1 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f1 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x0000001a, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f6 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x104 },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000013, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0fd },
+ { 0xffffffff, 0x00404811, 0x104 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x100 },
+ { 0x0000ffff, 0x00404811, 0x104 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x103 },
+ { 0x000000ff, 0x00404811, 0x104 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000019, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x10d },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000019, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x114 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x110 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x127 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x00000004, 0x00404c11, 0x12e },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00000000, 0x00600000, 0x151 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2a4 },
+ { 0x0001a1fd, 0x00604411, 0x2c9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x138 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x151 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2a4 },
+ { 0x0001a1fd, 0x00604411, 0x2c9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x149 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x17c },
+ { 0x00000000, 0x00600000, 0x18d },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x189 },
+ { 0x00000000, 0x00600000, 0x2a4 },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x28c },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x173 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x16f },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x184 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000013, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2e4 },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x165 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x2fe },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x181 },
+ { 0x0000001b, 0xc0203620, 0x000 },
+ { 0x0000001c, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x19f },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x188 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000032, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x00000011, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x128 },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00600e2d, 0x1aa },
+ { 0x0000001c, 0x00600e2d, 0x1aa },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x0000001d, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1a6 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000020, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000019, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1cd },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1c9 },
+ { 0x00000000, 0x00600000, 0x1d6 },
+ { 0x00000001, 0x00531e27, 0x1c5 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1be },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1d6 },
+ { 0x00000001, 0x00531e27, 0x1d2 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2a4 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e5 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x1f2 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x1f2 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2a4 },
+ { 0x0001a1fd, 0x00604411, 0x2c9 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x206 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x1ff },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000000, 0x0040040f, 0x200 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000210, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00600000, 0x18d },
+ { 0x00000000, 0x00600000, 0x189 },
+ { 0x00000000, 0x00600000, 0x2a4 },
+ { 0x00000000, 0x00600000, 0x28c },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x21f },
+ { 0x00000000, 0xc0404800, 0x21c },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2e4 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x235 },
+ { 0x0000001a, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x0000001a, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x23a },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x2fe },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x265 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x253 },
+ { 0x00000018, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x248 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x24b },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000018, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x250 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x253 },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2aa },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25b },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25a },
+ { 0x00000016, 0x00404811, 0x25f },
+ { 0x00000018, 0x00404811, 0x25f },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25e },
+ { 0x00000017, 0x00404811, 0x25f },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2d2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x23f },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x614 },
+ { 0x00000000, 0x00600000, 0x5b2 },
+ { 0x00000000, 0xc0600000, 0x28c },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x00000034, 0x00201a2d, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x00000033, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x27b },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000034, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x128 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x286 },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000024, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000032, 0x00203622, 0x000 },
+ { 0x00000031, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000029, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000029, 0x00203627, 0x000 },
+ { 0x0000002a, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x0000002a, 0x00203627, 0x000 },
+ { 0x0000002b, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x0000002b, 0x00203627, 0x000 },
+ { 0x0000002c, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x0000002c, 0x00803627, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x0000002a, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x0000002b, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x0000002c, 0x00803627, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00203628, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2c5 },
+ { 0x00000000, 0x00400000, 0x2c2 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00203628, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2c2 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2c5 },
+ { 0x0000002b, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2c5 },
+ { 0x00000029, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2c5 },
+ { 0x0000002c, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2c5 },
+ { 0x0000002a, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2c5 },
+ { 0x00000000, 0x00600000, 0x5ed },
+ { 0x00000000, 0x00600000, 0x29e },
+ { 0x00000000, 0x00400000, 0x2c7 },
+ { 0x00000000, 0x00600000, 0x29e },
+ { 0x00000000, 0x00600000, 0x5e4 },
+ { 0x00000000, 0x00400000, 0x2c7 },
+ { 0x00000000, 0x00600000, 0x290 },
+ { 0x00000000, 0x00400000, 0x2c7 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000023, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x0000001d, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x301 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x0000001a, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x5c5 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x334 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x33d },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x351 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x355 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00404811, 0x349 },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x349 },
+ { 0x00002104, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x00000035, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x360 },
+ { 0x00000035, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x376 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x380 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x38c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x398 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x398 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39a },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39f },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000015, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x382 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x38e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00000016, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3b9 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ab },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3be },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x614 },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3cc },
+ { 0x00000000, 0xc0401800, 0x3cf },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x614 },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3d2 },
+ { 0x00000000, 0xc0401c00, 0x3d5 },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x614 },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x3fd },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3e2 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ea },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x3fd },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x3fd },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3e5 },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3e5 },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3e5 },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3e5 },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3e5 },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3e5 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0018f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x42e },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x43c },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x444 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x614 },
+ { 0x00000000, 0x00400000, 0x44d },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x449 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x44c },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x454 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x459 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x45e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x463 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x468 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x46d },
+ { 0x00000000, 0x00400000, 0x47a },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x477 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x480 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x43c },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x48a },
+ { 0x00040000, 0xc0494a20, 0x48b },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x497 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x493 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x491 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ae },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x4a9 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x4ac },
+ { 0x00000000, 0x00400000, 0x4b2 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x614 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4b9 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x614 },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4bb },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4eb },
+ { 0x00000035, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4da },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4ce },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000036, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x491 },
+ { 0x00000035, 0xc0203620, 0x000 },
+ { 0x00000036, 0xc0403620, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0xe0000000, 0xc0484a20, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4f2 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x4f6 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x50b },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0x00000034, 0x00203623, 0x000 },
+ { 0x00000032, 0x00203623, 0x000 },
+ { 0x00000031, 0x00203623, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x0000002d, 0x00203623, 0x000 },
+ { 0x0000002e, 0x00203623, 0x000 },
+ { 0x0000001b, 0x00203623, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x0000002a, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x0000002c, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000033, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000027, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000028, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x00000026, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x602 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x541 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x614 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x549 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x55b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x549 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x614 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x55b },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x54d },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x55b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x559 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x554 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x557 },
+ { 0x00000000, 0x00401c10, 0x55b },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x55d },
+ { 0x00000000, 0x00600000, 0x5a4 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56d },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x56b },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x57d },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x57b },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58d },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58b },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x614 },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x599 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x59f },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5a4 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x5b7 },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x00000034, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x5bb },
+ { 0x00000000, 0x00600000, 0x5a4 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5bb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x0000217a, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x5e1 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x5dc },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x0000001d, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x0000001d, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000016, 0x00604811, 0x35e },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0x00ffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x614 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x00000010, 0x00404c11, 0x5f9 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x00000025, 0x00200a2d, 0x000 },
+ { 0x00000026, 0x00200e2d, 0x000 },
+ { 0x00000027, 0x0020122d, 0x000 },
+ { 0x00000028, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x612 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x00000027, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x614 },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x617 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x2fe },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x19f },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000029, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x0000002c, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000002a, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000002b, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x013304ef, 0x059b0239, 0x000 },
+ { 0x01b00159, 0x0425059b, 0x000 },
+ { 0x021201f6, 0x02390142, 0x000 },
+ { 0x0210022e, 0x0289022a, 0x000 },
+ { 0x03c2059b, 0x059b059b, 0x000 },
+ { 0x05cd05ce, 0x0308059b, 0x000 },
+ { 0x059b05a0, 0x03090329, 0x000 },
+ { 0x0313026b, 0x032b031d, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b052c, 0x059b059b, 0x000 },
+ { 0x03a5059b, 0x04a2032d, 0x000 },
+ { 0x04810433, 0x0423059b, 0x000 },
+ { 0x04bb04ed, 0x042704c8, 0x000 },
+ { 0x043304f4, 0x033a0365, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x05b905a2, 0x000 },
+ { 0x059b059b, 0x0007059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x03e303d8, 0x03f303f1, 0x000 },
+ { 0x03f903f5, 0x03f703fb, 0x000 },
+ { 0x04070403, 0x040f040b, 0x000 },
+ { 0x04170413, 0x041f041b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x059b059b, 0x059b059b, 0x000 },
+ { 0x00020600, 0x06190006, 0x000 },
+};
+
+static const u32 R600_pfp_microcode[] = {
+0xd40071,
+0xd40072,
+0xca0400,
+0xa00000,
+0x7e828b,
+0x800003,
+0xca0400,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d4,
+0xd5c01e,
+0xca0800,
+0x80001b,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000d,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000d,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800054,
+0xd40073,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800002,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800002,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b9,
+0xd4c01e,
+0xc6083e,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800002,
+0x062001,
+0xc6083e,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x80007a,
+0xd42013,
+0xc6083e,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008e,
+0x000000,
+0xc41432,
+0xc6183e,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800002,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xd40073,
+0xe4015e,
+0xd4001e,
+0x8001b9,
+0x062001,
+0x0a2001,
+0xd60074,
+0xc40836,
+0xc61040,
+0x988007,
+0xcc3835,
+0x95010f,
+0xd4001f,
+0xd46062,
+0x800002,
+0xd42062,
+0xcc1433,
+0x8401bc,
+0xd40070,
+0xd5401e,
+0x800002,
+0xee001e,
+0xca0c00,
+0xca1000,
+0xd4c01a,
+0x8401bc,
+0xd5001a,
+0xcc0443,
+0x35101f,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b9,
+0xd4006d,
+0x344401,
+0xcc0c44,
+0x98403a,
+0xcc2c46,
+0x958004,
+0xcc0445,
+0x8001b9,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f3,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f3,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f3,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f3,
+0xcc1003,
+0x988014,
+0xcc1047,
+0x9a8009,
+0xcc1448,
+0x9840da,
+0xd4006d,
+0xcc1844,
+0xd5001a,
+0xd5401a,
+0x8000cc,
+0xd5801a,
+0x96c0d3,
+0xd4006d,
+0x8001b9,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800002,
+0xec007f,
+0x9ac0ca,
+0xd4006d,
+0x8001b9,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b9,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809c,
+0xd4006d,
+0x98409a,
+0xd4006e,
+0xcc0847,
+0xcc0c48,
+0xcc1044,
+0xd4801a,
+0xd4c01a,
+0x800104,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d8,
+0xca0c00,
+0xd4401e,
+0x800002,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800002,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bc,
+0x000000,
+0x8401bc,
+0xd7806f,
+0x800002,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902af,
+0x7c738b,
+0x8401bc,
+0xd7806f,
+0x800002,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984296,
+0x000000,
+0x800164,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800002,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc1049,
+0x990004,
+0xd40071,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800002,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x95001f,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x7d8380,
+0xd5806f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0x8001b9,
+0xd60074,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800002,
+0xee001e,
+0x800002,
+0xee001f,
+0xd4001f,
+0x800002,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010174,
+0x02017b,
+0x030090,
+0x040080,
+0x050005,
+0x060040,
+0x070033,
+0x08012f,
+0x090047,
+0x0a0037,
+0x1001b7,
+0x1700a4,
+0x22013d,
+0x23014c,
+0x2000b5,
+0x240128,
+0x27004e,
+0x28006b,
+0x2a0061,
+0x2b0053,
+0x2f0066,
+0x320088,
+0x340182,
+0x3c0159,
+0x3f0073,
+0x41018f,
+0x440131,
+0x550176,
+0x56017d,
+0x60000c,
+0x610035,
+0x620039,
+0x630039,
+0x640039,
+0x650039,
+0x660039,
+0x670039,
+0x68003b,
+0x690042,
+0x6a0049,
+0x6b0049,
+0x6c0049,
+0x6d0049,
+0x6e0049,
+0x6f0049,
+0x7301b7,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+0x000007,
+};
+
+static const u32 RV610_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5c0 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68d },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68d },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000018, 0x40210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x445 },
+ { 0x00800000, 0xc0494a20, 0x446 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x44b },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x459 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x461 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68d },
+ { 0x00000000, 0x00400000, 0x466 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x692 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x472 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x477 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47c },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x481 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x490 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x499 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x459 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a3 },
+ { 0x00040000, 0xc0494a20, 0x4a4 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4b0 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ac },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00400000, 0x4c7 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68d },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ce },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d0 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x500 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ef },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e3 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x505 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x519 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52e },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x67b },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x566 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x572 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x57a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00401c10, 0x57c },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57e },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58f },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58d },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a0 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59e },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5b1 },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5af },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5be },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c4 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c9 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5d0 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e3 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68d },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68d },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x605 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60e },
+ { 0x0004a003, 0x00604411, 0x68d },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x0004a010, 0x00604411, 0x68d },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x0004a011, 0x00604411, 0x68d },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68d },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68d },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68d },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68d },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68d },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68d },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63d },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x63b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x641 },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x641 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62d },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62d },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x656 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000010, 0x00404c11, 0x672 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x68b },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68d },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x690 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x692 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x695 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x01420502, 0x05c00250, 0x000 },
+ { 0x01c30168, 0x043f05c0, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705c0, 0x05c005c0, 0x000 },
+ { 0x0649064a, 0x031f05c0, 0x000 },
+ { 0x05c005c5, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c00551, 0x05c005c0, 0x000 },
+ { 0x03ba05c0, 0x04bb0344, 0x000 },
+ { 0x049a0450, 0x043d05c0, 0x000 },
+ { 0x04d005c0, 0x044104dd, 0x000 },
+ { 0x04500507, 0x03510375, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x063f05c7, 0x000 },
+ { 0x05c005c0, 0x000705c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05c005c0, 0x043805c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x00020679, 0x06970006, 0x000 },
+};
+
+static const u32 RV610_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV620_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00000000, 0x00600000, 0x631 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x668 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x645 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5c0 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68d },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68d },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000018, 0x40210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x445 },
+ { 0x00800000, 0xc0494a20, 0x446 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x44b },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x459 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x461 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68d },
+ { 0x00000000, 0x00400000, 0x466 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x692 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46d },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x472 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x477 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47c },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x481 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x486 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x486 },
+ { 0x00000000, 0x00400000, 0x493 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x490 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x499 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x459 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a3 },
+ { 0x00040000, 0xc0494a20, 0x4a4 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4b0 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ac },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00400000, 0x4c7 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68d },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4ce },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68d },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d0 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x500 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ef },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e3 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4aa },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x505 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x519 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52e },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x67b },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x566 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68d },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x572 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x57c },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x57a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x692 },
+ { 0x00000000, 0x00401c10, 0x57c },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57e },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58f },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58d },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a0 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59e },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5b1 },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5af },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5be },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c4 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c9 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5d0 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e3 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e3 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68d },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68d },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68d },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68d },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68d },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68d },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x605 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60e },
+ { 0x0004a003, 0x00604411, 0x68d },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x613 },
+ { 0x0004a010, 0x00604411, 0x68d },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62b },
+ { 0x0004a011, 0x00604411, 0x68d },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68d },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68d },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68d },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68d },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68d },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68d },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63d },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x63b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68d },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x641 },
+ { 0x00000000, 0x00600000, 0x5c9 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x641 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62d },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62d },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x656 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68d },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x68c },
+ { 0x00000010, 0x00404c11, 0x672 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x68b },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68d },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x690 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x692 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x695 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x01420502, 0x05c00250, 0x000 },
+ { 0x01c30168, 0x043f05c0, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705c0, 0x05c005c0, 0x000 },
+ { 0x0649064a, 0x031f05c0, 0x000 },
+ { 0x05c005c5, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c00551, 0x05c005c0, 0x000 },
+ { 0x03ba05c0, 0x04bb0344, 0x000 },
+ { 0x049a0450, 0x043d05c0, 0x000 },
+ { 0x04d005c0, 0x044104dd, 0x000 },
+ { 0x04500507, 0x03510375, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x063f05c7, 0x000 },
+ { 0x05c005c0, 0x000705c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05c005c0, 0x043805c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x05c005c0, 0x05c005c0, 0x000 },
+ { 0x00020679, 0x06970006, 0x000 },
+};
+
+static const u32 RV620_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV630_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5bd },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68a },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68a },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x448 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x456 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x45e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68a },
+ { 0x00000000, 0x00400000, 0x463 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x68f },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x474 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x48d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x496 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x456 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a0 },
+ { 0x00040000, 0xc0494a20, 0x4a1 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4ad },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4a9 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00400000, 0x4c4 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68a },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cb },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cd },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4fd },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ec },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e0 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x502 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x516 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52b },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x678 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x563 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56f },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x577 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00401c10, 0x579 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57b },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58c },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58a },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x59d },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59b },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ae },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5ac },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5bb },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c1 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c6 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5cd },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e0 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68a },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68a },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x602 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60b },
+ { 0x0004a003, 0x00604411, 0x68a },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x610 },
+ { 0x0004a010, 0x00604411, 0x68a },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x0004a011, 0x00604411, 0x68a },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68a },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68a },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68a },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68a },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68a },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68a },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63a },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x638 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x63e },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x63e },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62a },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62a },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x653 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000010, 0x00404c11, 0x66f },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x688 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68a },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x68d },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68f },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x692 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x014204ff, 0x05bd0250, 0x000 },
+ { 0x01c30168, 0x043f05bd, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705bd, 0x05bd05bd, 0x000 },
+ { 0x06460647, 0x031f05bd, 0x000 },
+ { 0x05bd05c2, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd054e, 0x05bd05bd, 0x000 },
+ { 0x03ba05bd, 0x04b80344, 0x000 },
+ { 0x0497044d, 0x043d05bd, 0x000 },
+ { 0x04cd05bd, 0x044104da, 0x000 },
+ { 0x044d0504, 0x03510375, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x063c05c4, 0x000 },
+ { 0x05bd05bd, 0x000705bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05bd05bd, 0x043805bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x00020676, 0x06940006, 0x000 },
+};
+
+static const u32 RV630_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV635_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x65f },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x662 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00000000, 0x00600000, 0x62e },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x665 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x65c },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x642 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x364 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36e },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5bd },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35f },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x386 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b1 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b5 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x39c },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a8 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x390 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x392 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39e },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ae },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c0 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x68a },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x68a },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x448 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x456 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x45e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x68a },
+ { 0x00000000, 0x00400000, 0x463 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x68f },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x474 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x483 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x483 },
+ { 0x00000000, 0x00400000, 0x490 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x48d },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x496 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x456 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a0 },
+ { 0x00040000, 0xc0494a20, 0x4a1 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4ad },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4a9 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00400000, 0x4c4 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x68a },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cb },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x68a },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cd },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4fd },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4ec },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4e0 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4a7 },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x502 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x516 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x52b },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x678 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x563 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56b },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x68a },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56f },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x579 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x577 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x68f },
+ { 0x00000000, 0x00401c10, 0x579 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x57b },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x58c },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x58a },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x59d },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59b },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ae },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5ac },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5bb },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5c1 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c6 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5cd },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5e0 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5e0 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x68a },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x68a },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x68a },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x68a },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x68a },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x68a },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x629 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x602 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x60b },
+ { 0x0004a003, 0x00604411, 0x68a },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x610 },
+ { 0x0004a010, 0x00604411, 0x68a },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x628 },
+ { 0x0004a011, 0x00604411, 0x68a },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x68a },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x68a },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x68a },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x68a },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x68a },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x68a },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x63a },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x638 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x68a },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x63e },
+ { 0x00000000, 0x00600000, 0x5c6 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x63e },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x62a },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x62a },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x653 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36e },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x68a },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x689 },
+ { 0x00000010, 0x00404c11, 0x66f },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x688 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68a },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x68d },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x68f },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x692 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x014204ff, 0x05bd0250, 0x000 },
+ { 0x01c30168, 0x043f05bd, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705bd, 0x05bd05bd, 0x000 },
+ { 0x06460647, 0x031f05bd, 0x000 },
+ { 0x05bd05c2, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd054e, 0x05bd05bd, 0x000 },
+ { 0x03ba05bd, 0x04b80344, 0x000 },
+ { 0x0497044d, 0x043d05bd, 0x000 },
+ { 0x04cd05bd, 0x044104da, 0x000 },
+ { 0x044d0504, 0x03510375, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x063c05c4, 0x000 },
+ { 0x05bd05bd, 0x000705bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05bd05bd, 0x043805bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x05bd05bd, 0x05bd05bd, 0x000 },
+ { 0x00020676, 0x06940006, 0x000 },
+};
+
+static const u32 RV635_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV670_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000000, 0x00600000, 0x64d },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x653 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x656 },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x67b },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x67b },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x00000000, 0x00600000, 0x624 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x659 },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x650 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x638 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x34b },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x354 },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x362 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x36a },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x366 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35d },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5b3 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x35d },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36c },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x382 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3ad },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3af },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x398 },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a4 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a4 },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x38c },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x38e },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x39a },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3aa },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36a },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c4 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3b8 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3c9 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x67c },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3d7 },
+ { 0x00000000, 0xc0401800, 0x3da },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x67c },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3dd },
+ { 0x00000000, 0xc0401c00, 0x3e0 },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x67c },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x408 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3ed },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3f5 },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x408 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x408 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3f0 },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3f0 },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3f0 },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3f0 },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3f0 },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3f0 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x43e },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x44c },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x454 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x67c },
+ { 0x00000000, 0x00400000, 0x459 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x681 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x460 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x465 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x46f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x474 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x479 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x479 },
+ { 0x00000000, 0x00400000, 0x486 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x483 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x48c },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x44c },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x496 },
+ { 0x00040000, 0xc0494a20, 0x497 },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4a3 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x49f },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x49d },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4b6 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x681 },
+ { 0x00000000, 0x00400000, 0x4ba },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x67c },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c1 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x67c },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4c3 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4f3 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4e2 },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4d6 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x49d },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4f8 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x50c },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x521 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x66a },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x559 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x67c },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x561 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x56f },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x561 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x67c },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x56f },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x565 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x56f },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x56d },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x681 },
+ { 0x00000000, 0x00401c10, 0x56f },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x571 },
+ { 0x00000000, 0x00600000, 0x5bc },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x582 },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x580 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x593 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x591 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a4 },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5a2 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x67c },
+ { 0x0000001a, 0x00212230, 0x000 },
+ { 0x00000006, 0x00222630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5b1 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5b7 },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5bc },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000002c, 0x00203621, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5c3 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000030, 0x00403621, 0x5d6 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5d6 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004a092, 0x00604411, 0x67c },
+ { 0x00000031, 0x00203630, 0x000 },
+ { 0x0004a093, 0x00604411, 0x67c },
+ { 0x00000032, 0x00203630, 0x000 },
+ { 0x0004a2b6, 0x00604411, 0x67c },
+ { 0x00000033, 0x00203630, 0x000 },
+ { 0x0004a2ba, 0x00604411, 0x67c },
+ { 0x00000034, 0x00203630, 0x000 },
+ { 0x0004a2be, 0x00604411, 0x67c },
+ { 0x00000035, 0x00203630, 0x000 },
+ { 0x0004a2c2, 0x00604411, 0x67c },
+ { 0x00000036, 0x00203630, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000001, 0x002f0230, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61f },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61f },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00007e00, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x5f8 },
+ { 0x0000a092, 0x00204411, 0x000 },
+ { 0x00000031, 0x00204a2d, 0x000 },
+ { 0x0000a093, 0x00204411, 0x000 },
+ { 0x00000032, 0x00204a2d, 0x000 },
+ { 0x0000a2b6, 0x00204411, 0x000 },
+ { 0x00000033, 0x00204a2d, 0x000 },
+ { 0x0000a2ba, 0x00204411, 0x000 },
+ { 0x00000034, 0x00204a2d, 0x000 },
+ { 0x0000a2be, 0x00204411, 0x000 },
+ { 0x00000035, 0x00204a2d, 0x000 },
+ { 0x0000a2c2, 0x00204411, 0x000 },
+ { 0x00000036, 0x00204a2d, 0x000 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x000001ff, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61e },
+ { 0x00000000, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x601 },
+ { 0x0004a003, 0x00604411, 0x67c },
+ { 0x0000a003, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x14c00000, 0x606 },
+ { 0x0004a010, 0x00604411, 0x67c },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00000001, 0x00210621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x61e },
+ { 0x0004a011, 0x00604411, 0x67c },
+ { 0x0000a011, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a012, 0x00604411, 0x67c },
+ { 0x0000a012, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a013, 0x00604411, 0x67c },
+ { 0x0000a013, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a014, 0x00604411, 0x67c },
+ { 0x0000a014, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a015, 0x00604411, 0x67c },
+ { 0x0000a015, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a016, 0x00604411, 0x67c },
+ { 0x0000a016, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x0004a017, 0x00604411, 0x67c },
+ { 0x0000a017, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x0000002c, 0x0080062d, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x630 },
+ { 0x00000030, 0x0020062d, 0x000 },
+ { 0x00000002, 0x00280621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x62e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x67c },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x634 },
+ { 0x00000000, 0x00600000, 0x5bc },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x634 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x620 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x620 },
+ { 0x00000000, 0x00600000, 0x64d },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x647 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x36a },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x67c },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x67b },
+ { 0x00000010, 0x00404c11, 0x661 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x67a },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x67c },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x67f },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x681 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x684 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x014204f5, 0x05b30250, 0x000 },
+ { 0x01c30168, 0x043505b3, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03cd05b3, 0x05b305b3, 0x000 },
+ { 0x063c063d, 0x031f05b3, 0x000 },
+ { 0x05b305b8, 0x03200340, 0x000 },
+ { 0x032a0282, 0x03420334, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b30544, 0x05b305b3, 0x000 },
+ { 0x03b205b3, 0x04ae0344, 0x000 },
+ { 0x048d0443, 0x043305b3, 0x000 },
+ { 0x04c305b3, 0x043704d0, 0x000 },
+ { 0x044304fa, 0x03510371, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x063205ba, 0x000 },
+ { 0x05b305b3, 0x000705b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x03ee03e3, 0x03fe03fc, 0x000 },
+ { 0x04040400, 0x04020406, 0x000 },
+ { 0x0412040e, 0x041a0416, 0x000 },
+ { 0x0422041e, 0x042a0426, 0x000 },
+ { 0x05b305b3, 0x042e05b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x05b305b3, 0x05b305b3, 0x000 },
+ { 0x00020668, 0x06860006, 0x000 },
+};
+
+static const u32 RV670_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001b8,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581a8,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0fff0,
+0x042c04,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255403,
+0x7cd580,
+0x259c03,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800053,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xd48060,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001b8,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x800079,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x80008d,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401bb,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401bb,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001b8,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x8400f0,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x8400f0,
+0xcc1003,
+0x988017,
+0x043808,
+0x8400f0,
+0xcc1003,
+0x988013,
+0x043804,
+0x8400f0,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000c9,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001b8,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001b8,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800101,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482d9,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x9882bd,
+0x000000,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x9902b0,
+0x7c738b,
+0x8401bb,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984297,
+0x000000,
+0x800161,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001b8,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010171,
+0x020178,
+0x03008f,
+0x04007f,
+0x050003,
+0x06003f,
+0x070032,
+0x08012c,
+0x090046,
+0x0a0036,
+0x1001b6,
+0x1700a2,
+0x22013a,
+0x230149,
+0x2000b4,
+0x240125,
+0x27004d,
+0x28006a,
+0x2a0060,
+0x2b0052,
+0x2f0065,
+0x320087,
+0x34017f,
+0x3c0156,
+0x3f0072,
+0x41018c,
+0x44012e,
+0x550173,
+0x56017a,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RS780_cp_microcode[][3] = {
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0000ffff, 0x00284621, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000000, 0x00e00000, 0x000 },
+ { 0x00010000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x622 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000f00, 0x00281622, 0x000 },
+ { 0x00000008, 0x00211625, 0x000 },
+ { 0x00000018, 0x00203625, 0x000 },
+ { 0x8d000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x002f0225, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x018 },
+ { 0x00412000, 0x00404811, 0x019 },
+ { 0x00422000, 0x00204811, 0x000 },
+ { 0x8e000000, 0x00204411, 0x000 },
+ { 0x00000028, 0x00204a2d, 0x000 },
+ { 0x90000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x0000000c, 0x00211622, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000019, 0x00211a22, 0x000 },
+ { 0x00000004, 0x00281a26, 0x000 },
+ { 0x00000000, 0x002914c5, 0x000 },
+ { 0x00000019, 0x00203625, 0x000 },
+ { 0x00000000, 0x003a1402, 0x000 },
+ { 0x00000016, 0x00211625, 0x000 },
+ { 0x00000003, 0x00281625, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0xfffffffc, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002914a3, 0x000 },
+ { 0x00000017, 0x00203625, 0x000 },
+ { 0x00008000, 0x00280e22, 0x000 },
+ { 0x00000007, 0x00220e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x20000000, 0x00280e22, 0x000 },
+ { 0x00000006, 0x00210e23, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x00000000, 0x00220222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x038 },
+ { 0x00000000, 0x2ee00000, 0x035 },
+ { 0x00000000, 0x2ce00000, 0x037 },
+ { 0x00000000, 0x00400e2d, 0x039 },
+ { 0x00000008, 0x00200e2d, 0x000 },
+ { 0x00000009, 0x0040122d, 0x046 },
+ { 0x00000001, 0x00400e2d, 0x039 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x03e },
+ { 0x00000008, 0x00401c11, 0x041 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x0000000f, 0x00281e27, 0x000 },
+ { 0x00000003, 0x00221e27, 0x000 },
+ { 0x7fc00000, 0x00281a23, 0x000 },
+ { 0x00000014, 0x00211a26, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000008, 0x00221a26, 0x000 },
+ { 0x00000000, 0x00290cc7, 0x000 },
+ { 0x00000027, 0x00203624, 0x000 },
+ { 0x00007f00, 0x00281221, 0x000 },
+ { 0x00001400, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x04b },
+ { 0x00000001, 0x00290e23, 0x000 },
+ { 0x0000000e, 0x00203623, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfff80000, 0x00294a23, 0x000 },
+ { 0x00000000, 0x003a2c02, 0x000 },
+ { 0x00000002, 0x00220e2b, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x0000000f, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00204a2d, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000029, 0x00200e2d, 0x000 },
+ { 0x060a0200, 0x00294a23, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14e00000, 0x061 },
+ { 0x00000000, 0x2ee00000, 0x05f },
+ { 0x00000000, 0x2ce00000, 0x05e },
+ { 0x00000000, 0x00400e2d, 0x062 },
+ { 0x00000001, 0x00400e2d, 0x062 },
+ { 0x0000000a, 0x00200e2d, 0x000 },
+ { 0x0000000b, 0x0040122d, 0x06a },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x003ffffc, 0x00281223, 0x000 },
+ { 0x00000002, 0x00221224, 0x000 },
+ { 0x7fc00000, 0x00281623, 0x000 },
+ { 0x00000014, 0x00211625, 0x000 },
+ { 0x00000001, 0x00331625, 0x000 },
+ { 0x80000000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00290ca3, 0x000 },
+ { 0x3ffffc00, 0x00290e23, 0x000 },
+ { 0x0000001f, 0x00211e23, 0x000 },
+ { 0x00000000, 0x14e00000, 0x06d },
+ { 0x00000100, 0x00401c11, 0x070 },
+ { 0x0000000d, 0x00201e2d, 0x000 },
+ { 0x000000f0, 0x00281e27, 0x000 },
+ { 0x00000004, 0x00221e27, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0xfffff0ff, 0x00281a30, 0x000 },
+ { 0x0000a028, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948e6, 0x000 },
+ { 0x0000a018, 0x00204411, 0x000 },
+ { 0x3fffffff, 0x00284a23, 0x000 },
+ { 0x0000a010, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000030, 0x0020162d, 0x000 },
+ { 0x00000002, 0x00291625, 0x000 },
+ { 0x00000030, 0x00203625, 0x000 },
+ { 0x00000025, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a3, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x083 },
+ { 0x00000026, 0x0020162d, 0x000 },
+ { 0x00000000, 0x002f00a4, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x084 },
+ { 0x00000000, 0x00400000, 0x08a },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203624, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x08a },
+ { 0x00000000, 0x00600000, 0x5ff },
+ { 0x00000000, 0x00600000, 0x5f3 },
+ { 0x00000002, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x08d },
+ { 0x00000012, 0xc0403620, 0x093 },
+ { 0x00000000, 0x2ee00000, 0x091 },
+ { 0x00000000, 0x2ce00000, 0x090 },
+ { 0x00000002, 0x00400e2d, 0x092 },
+ { 0x00000003, 0x00400e2d, 0x092 },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000012, 0x00203623, 0x000 },
+ { 0x00000003, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x098 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x0a0 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x2ee00000, 0x09e },
+ { 0x00000000, 0x2ce00000, 0x09d },
+ { 0x00000002, 0x00400e2d, 0x09f },
+ { 0x00000003, 0x00400e2d, 0x09f },
+ { 0x0000000c, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x003f0000, 0x00280e23, 0x000 },
+ { 0x00000010, 0x00210e23, 0x000 },
+ { 0x00000011, 0x00203623, 0x000 },
+ { 0x0000001e, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0a7 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x0000001f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0aa },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000008, 0x00210e2b, 0x000 },
+ { 0x0000007f, 0x00280e23, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0e1 },
+ { 0x00000000, 0x27000000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x0b3 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000000c, 0x00221e30, 0x000 },
+ { 0x99800000, 0x00204411, 0x000 },
+ { 0x00000004, 0x0020122d, 0x000 },
+ { 0x00000008, 0x00221224, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00291ce4, 0x000 },
+ { 0x00000000, 0x00604807, 0x12f },
+ { 0x9b000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x9c000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x0033146f, 0x000 },
+ { 0x00000001, 0x00333e23, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0x00203c05, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e007, 0x00204411, 0x000 },
+ { 0x0000000f, 0x0021022b, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0cb },
+ { 0x00f8ff08, 0x00204811, 0x000 },
+ { 0x98000000, 0x00404811, 0x0dc },
+ { 0x000000f0, 0x00280e22, 0x000 },
+ { 0x000000a0, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x0da },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d5 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0d4 },
+ { 0x00003f00, 0x00400c11, 0x0d6 },
+ { 0x00001f00, 0x00400c11, 0x0d6 },
+ { 0x00000f00, 0x00200c11, 0x000 },
+ { 0x00380009, 0x00294a23, 0x000 },
+ { 0x3f000000, 0x00280e2b, 0x000 },
+ { 0x00000002, 0x00220e23, 0x000 },
+ { 0x00000007, 0x00494a23, 0x0dc },
+ { 0x00380f09, 0x00204811, 0x000 },
+ { 0x68000007, 0x00204811, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000a202, 0x00204411, 0x000 },
+ { 0x00ff0000, 0x00280e22, 0x000 },
+ { 0x00000080, 0x00294a23, 0x000 },
+ { 0x00000027, 0x00200e2d, 0x000 },
+ { 0x00000026, 0x0020122d, 0x000 },
+ { 0x00000000, 0x002f0083, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x0ea },
+ { 0x00000000, 0x00600000, 0x5f9 },
+ { 0x00000000, 0x00400000, 0x0eb },
+ { 0x00000000, 0x00600000, 0x5fc },
+ { 0x00000007, 0x0020222d, 0x000 },
+ { 0x00000005, 0x00220e22, 0x000 },
+ { 0x00100000, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000000, 0x003a0c02, 0x000 },
+ { 0x000000ef, 0x00280e23, 0x000 },
+ { 0x00000000, 0x00292068, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000003, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x0f8 },
+ { 0x0000000b, 0x00210228, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0f8 },
+ { 0x00000400, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000001c, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x0fd },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000001e, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x10b },
+ { 0x0000a30f, 0x00204411, 0x000 },
+ { 0x00000011, 0x00200e2d, 0x000 },
+ { 0x00000001, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x104 },
+ { 0xffffffff, 0x00404811, 0x10b },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x107 },
+ { 0x0000ffff, 0x00404811, 0x10b },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x10a },
+ { 0x000000ff, 0x00404811, 0x10b },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0002c400, 0x00204411, 0x000 },
+ { 0x0000001f, 0x00210e22, 0x000 },
+ { 0x00000000, 0x14c00000, 0x112 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000018, 0x40224a20, 0x000 },
+ { 0x00000010, 0xc0424a20, 0x114 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x00000013, 0x00203623, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000000a, 0x00201011, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x11b },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00531224, 0x117 },
+ { 0xffbfffff, 0x00283a2e, 0x000 },
+ { 0x0000001b, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x12e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000d, 0x00204811, 0x000 },
+ { 0x00000018, 0x00220e30, 0x000 },
+ { 0xfc000000, 0x00280e23, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x00000000, 0x00201010, 0x000 },
+ { 0x0000e00e, 0x00204411, 0x000 },
+ { 0x07f8ff08, 0x00204811, 0x000 },
+ { 0x00000000, 0x00294a23, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a24, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00800000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204806, 0x000 },
+ { 0x00000008, 0x00214a27, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x621 },
+ { 0x00000004, 0x00404c11, 0x135 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000001c, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x13c },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40280620, 0x000 },
+ { 0x00000010, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x00341461, 0x000 },
+ { 0x00000000, 0x00741882, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x147 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x160 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0681a20, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x158 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000001, 0x00300a2f, 0x000 },
+ { 0x00000001, 0x00210a22, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600000, 0x18f },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00202c08, 0x000 },
+ { 0x00000000, 0x00202411, 0x000 },
+ { 0x00000000, 0x00202811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00221e29, 0x000 },
+ { 0x00000000, 0x007048eb, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000001, 0x40330620, 0x000 },
+ { 0x00000000, 0xc0302409, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x181 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x186 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x186 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000001, 0x00530621, 0x182 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0604800, 0x197 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000011, 0x0020062d, 0x000 },
+ { 0x00000000, 0x0078042a, 0x2fb },
+ { 0x00000000, 0x00202809, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x174 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x194 },
+ { 0x00000015, 0xc0203620, 0x000 },
+ { 0x00000016, 0xc0203620, 0x000 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x46000000, 0x00600811, 0x1b2 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x19b },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00804811, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000ffff, 0x40281620, 0x000 },
+ { 0x00000010, 0xc0811a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x00000008, 0x00221e30, 0x000 },
+ { 0x00000029, 0x00201a2d, 0x000 },
+ { 0x0000e000, 0x00204411, 0x000 },
+ { 0xfffbff09, 0x00204811, 0x000 },
+ { 0x0000000f, 0x0020222d, 0x000 },
+ { 0x00001fff, 0x00294a28, 0x000 },
+ { 0x00000006, 0x0020222d, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000100, 0x00201811, 0x000 },
+ { 0x00000008, 0x00621e28, 0x12f },
+ { 0x00000008, 0x00822228, 0x000 },
+ { 0x0002c000, 0x00204411, 0x000 },
+ { 0x00000015, 0x00600e2d, 0x1bd },
+ { 0x00000016, 0x00600e2d, 0x1bd },
+ { 0x0000c008, 0x00204411, 0x000 },
+ { 0x00000017, 0x00200e2d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x1b9 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x39000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00804802, 0x000 },
+ { 0x00000018, 0x00202e2d, 0x000 },
+ { 0x00000000, 0x003b0d63, 0x000 },
+ { 0x00000008, 0x00224a23, 0x000 },
+ { 0x00000010, 0x00224a23, 0x000 },
+ { 0x00000018, 0x00224a23, 0x000 },
+ { 0x00000000, 0x00804803, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00000007, 0x0021062f, 0x000 },
+ { 0x00000013, 0x00200a2d, 0x000 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000ffff, 0x40282220, 0x000 },
+ { 0x0000000f, 0x00262228, 0x000 },
+ { 0x00000010, 0x40212620, 0x000 },
+ { 0x0000000f, 0x00262629, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1e0 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000081, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000080, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1dc },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1d8 },
+ { 0x00000001, 0x00202c11, 0x000 },
+ { 0x0000001f, 0x00280a22, 0x000 },
+ { 0x0000001f, 0x00282a2a, 0x000 },
+ { 0x00000001, 0x00530621, 0x1d1 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000002, 0x00304a2f, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000001, 0x00301e2f, 0x000 },
+ { 0x00000000, 0x002f0227, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00600000, 0x1e9 },
+ { 0x00000001, 0x00531e27, 0x1e5 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x0000000f, 0x00260e23, 0x000 },
+ { 0x00000010, 0xc0211220, 0x000 },
+ { 0x0000000f, 0x00261224, 0x000 },
+ { 0x00000000, 0x00201411, 0x000 },
+ { 0x00000000, 0x00601811, 0x2bb },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022b, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x1f8 },
+ { 0x00000010, 0x00221628, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a29, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x0020480a, 0x000 },
+ { 0x00000000, 0x00202c11, 0x000 },
+ { 0x00000010, 0x00221623, 0x000 },
+ { 0xffff0000, 0x00281625, 0x000 },
+ { 0x0000ffff, 0x00281a24, 0x000 },
+ { 0x00000000, 0x002948c5, 0x000 },
+ { 0x00000000, 0x00731503, 0x205 },
+ { 0x00000000, 0x00201805, 0x000 },
+ { 0x00000000, 0x00731524, 0x205 },
+ { 0x00000000, 0x002d14c5, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00202802, 0x000 },
+ { 0x00000000, 0x00202003, 0x000 },
+ { 0x00000000, 0x00802404, 0x000 },
+ { 0x0000000f, 0x00210225, 0x000 },
+ { 0x00000000, 0x14c00000, 0x621 },
+ { 0x00000000, 0x002b1405, 0x000 },
+ { 0x00000001, 0x00901625, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001a, 0x00294a22, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a21, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000ffff, 0x40281220, 0x000 },
+ { 0x00000010, 0xc0211a20, 0x000 },
+ { 0x0000ffff, 0x40280e20, 0x000 },
+ { 0x00000010, 0xc0211620, 0x000 },
+ { 0x00000000, 0x00741465, 0x2bb },
+ { 0x0001a1fd, 0x00604411, 0x2e0 },
+ { 0x00000001, 0x00330621, 0x000 },
+ { 0x00000000, 0x002f0221, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x219 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x212 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000000, 0x0040040f, 0x213 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000210, 0x00600411, 0x315 },
+ { 0x00000000, 0x00600000, 0x1a0 },
+ { 0x00000000, 0x00600000, 0x19c },
+ { 0x00000000, 0x00600000, 0x2bb },
+ { 0x00000000, 0x00600000, 0x2a3 },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204808, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x232 },
+ { 0x00000000, 0x00600000, 0x13a },
+ { 0x00000000, 0x00400000, 0x236 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x236 },
+ { 0x00000000, 0xc0404800, 0x233 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x00600411, 0x2fb },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x0000a00c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000018, 0x40210a20, 0x000 },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x24c },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x00080101, 0x00292228, 0x000 },
+ { 0x00000014, 0x00203628, 0x000 },
+ { 0x0000a30c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x251 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000010, 0x00600411, 0x315 },
+ { 0x3f800000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00000000, 0x00600000, 0x27c },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000001, 0x00211e27, 0x000 },
+ { 0x00000000, 0x14e00000, 0x26a },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x0000ffff, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00341c27, 0x000 },
+ { 0x00000000, 0x12c00000, 0x25f },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e5, 0x000 },
+ { 0x00000000, 0x08c00000, 0x262 },
+ { 0x00000000, 0x00201407, 0x000 },
+ { 0x00000012, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00211e27, 0x000 },
+ { 0x00000000, 0x00341c47, 0x000 },
+ { 0x00000000, 0x12c00000, 0x267 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x08c00000, 0x26a },
+ { 0x00000000, 0x00201807, 0x000 },
+ { 0x00000000, 0x00600000, 0x2c1 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x00000000, 0x00342023, 0x000 },
+ { 0x00000000, 0x12c00000, 0x272 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x271 },
+ { 0x00000016, 0x00404811, 0x276 },
+ { 0x00000018, 0x00404811, 0x276 },
+ { 0x00000000, 0x00342044, 0x000 },
+ { 0x00000000, 0x12c00000, 0x275 },
+ { 0x00000017, 0x00404811, 0x276 },
+ { 0x00000019, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0x00604411, 0x2e9 },
+ { 0x00003fff, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x256 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x00000010, 0x40210620, 0x000 },
+ { 0x0000ffff, 0xc0280a20, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x00000010, 0x40211620, 0x000 },
+ { 0x0000ffff, 0xc0881a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00042004, 0x00604411, 0x622 },
+ { 0x00000000, 0x00600000, 0x5d1 },
+ { 0x00000000, 0xc0600000, 0x2a3 },
+ { 0x00000005, 0x00200a2d, 0x000 },
+ { 0x00000008, 0x00220a22, 0x000 },
+ { 0x0000002b, 0x00201a2d, 0x000 },
+ { 0x0000001c, 0x00201e2d, 0x000 },
+ { 0x00007000, 0x00281e27, 0x000 },
+ { 0x00000000, 0x00311ce6, 0x000 },
+ { 0x0000002a, 0x00201a2d, 0x000 },
+ { 0x0000000c, 0x00221a26, 0x000 },
+ { 0x00000000, 0x002f00e6, 0x000 },
+ { 0x00000000, 0x06e00000, 0x292 },
+ { 0x00000000, 0x00201c11, 0x000 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000010, 0x00201811, 0x000 },
+ { 0x00000000, 0x00691ce2, 0x12f },
+ { 0x93800000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x95000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f022f, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x29d },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x92000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000001c, 0x00403627, 0x000 },
+ { 0x0000000c, 0xc0220a20, 0x000 },
+ { 0x00000029, 0x00203622, 0x000 },
+ { 0x00000028, 0xc0403620, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000009, 0x00204811, 0x000 },
+ { 0xa1000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00804811, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce3, 0x000 },
+ { 0x00000021, 0x00203627, 0x000 },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002c1ce4, 0x000 },
+ { 0x00000022, 0x00203627, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a3, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x00000000, 0x002d1d07, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203624, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000023, 0x00203627, 0x000 },
+ { 0x00000000, 0x00311cc4, 0x000 },
+ { 0x00000024, 0x00803627, 0x000 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14c00000, 0x2dc },
+ { 0x00000000, 0x00400000, 0x2d9 },
+ { 0x0000001a, 0x00203627, 0x000 },
+ { 0x0000001b, 0x00203628, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000002, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2d9 },
+ { 0x00000003, 0x00210227, 0x000 },
+ { 0x00000000, 0x14e00000, 0x2dc },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e1, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120a1, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000024, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x002e00e2, 0x000 },
+ { 0x00000000, 0x02c00000, 0x2dc },
+ { 0x00000022, 0x00201e2d, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x00000000, 0x002e00e8, 0x000 },
+ { 0x00000000, 0x06c00000, 0x2dc },
+ { 0x00000000, 0x00600000, 0x5ff },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2b5 },
+ { 0x00000000, 0x00600000, 0x5f6 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x00000000, 0x00600000, 0x2a7 },
+ { 0x00000000, 0x00400000, 0x2de },
+ { 0x0000001a, 0x00201e2d, 0x000 },
+ { 0x0000001b, 0x0080222d, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000000, 0x00311ca1, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294847, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e21, 0x000 },
+ { 0x00000000, 0x003120c2, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00311ca3, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294887, 0x000 },
+ { 0x00000001, 0x00220a21, 0x000 },
+ { 0x00000000, 0x003008a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000010, 0x00221e23, 0x000 },
+ { 0x00000000, 0x003120c4, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x003808c5, 0x000 },
+ { 0x00000000, 0x00300841, 0x000 },
+ { 0x00000001, 0x00220a22, 0x000 },
+ { 0x00000000, 0x003308a2, 0x000 },
+ { 0x00000010, 0x00221e22, 0x000 },
+ { 0x00000010, 0x00212222, 0x000 },
+ { 0x00000000, 0x00894907, 0x000 },
+ { 0x00000017, 0x0020222d, 0x000 },
+ { 0x00000000, 0x14c00000, 0x318 },
+ { 0xffffffef, 0x00280621, 0x000 },
+ { 0x00000014, 0x0020222d, 0x000 },
+ { 0x0000f8e0, 0x00204411, 0x000 },
+ { 0x00000000, 0x00294901, 0x000 },
+ { 0x00000000, 0x00894901, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x060a0200, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0204811, 0x000 },
+ { 0x8a000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00002257, 0x00204411, 0x000 },
+ { 0x00000003, 0xc0484a20, 0x000 },
+ { 0x0000225d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0x00600000, 0x5de },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00384a22, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0001a1fd, 0x00204411, 0x000 },
+ { 0x00000000, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x00000001, 0x40304a20, 0x000 },
+ { 0x00000002, 0xc0304a20, 0x000 },
+ { 0x00000001, 0x00530a22, 0x355 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x35e },
+ { 0x00000014, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x36c },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00604802, 0x374 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x370 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x367 },
+ { 0x00000028, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ba },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x367 },
+ { 0x0000002c, 0x00203626, 0x000 },
+ { 0x00000049, 0x00201811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000001, 0x00331a26, 0x000 },
+ { 0x00000000, 0x002f0226, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x376 },
+ { 0x0000002c, 0x00801a2d, 0x000 },
+ { 0x0000003f, 0xc0280a20, 0x000 },
+ { 0x00000015, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x38c },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b7 },
+ { 0x00000016, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3b9 },
+ { 0x00000020, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3a2 },
+ { 0x0000000f, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3ae },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x3ae },
+ { 0x0000001e, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x396 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x08000000, 0x00290a22, 0x000 },
+ { 0x00000003, 0x40210e20, 0x000 },
+ { 0x0000000c, 0xc0211220, 0x000 },
+ { 0x00080000, 0x00281224, 0x000 },
+ { 0x00000014, 0xc0221620, 0x000 },
+ { 0x00000000, 0x002914a4, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x002948a2, 0x000 },
+ { 0x0000a1fe, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000016, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000015, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x398 },
+ { 0x0000210e, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000017, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000003, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3a4 },
+ { 0x00002108, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404802, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x80000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000010, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3b4 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000006, 0x00404811, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x374 },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x0000001d, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3ce },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x00000018, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000011, 0x00210230, 0x000 },
+ { 0x00000000, 0x14e00000, 0x3c2 },
+ { 0x00002100, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0xbabecafe, 0x00204811, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000004, 0x00404811, 0x000 },
+ { 0x00002170, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000a, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3d3 },
+ { 0x8c000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00003fff, 0x40280a20, 0x000 },
+ { 0x80000000, 0x40280e20, 0x000 },
+ { 0x40000000, 0xc0281220, 0x000 },
+ { 0x00040000, 0x00694622, 0x622 },
+ { 0x00000000, 0x00201410, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e1 },
+ { 0x00000000, 0xc0401800, 0x3e4 },
+ { 0x00003fff, 0xc0281a20, 0x000 },
+ { 0x00040000, 0x00694626, 0x622 },
+ { 0x00000000, 0x00201810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x3e7 },
+ { 0x00000000, 0xc0401c00, 0x3ea },
+ { 0x00003fff, 0xc0281e20, 0x000 },
+ { 0x00040000, 0x00694627, 0x622 },
+ { 0x00000000, 0x00201c10, 0x000 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0x002820c5, 0x000 },
+ { 0x00000000, 0x004948e8, 0x000 },
+ { 0xa5800000, 0x00200811, 0x000 },
+ { 0x00002000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x40204800, 0x000 },
+ { 0x0000001f, 0xc0210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x3f7 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00008000, 0x00204811, 0x000 },
+ { 0x0000ffff, 0xc0481220, 0x3ff },
+ { 0xa7800000, 0x00200811, 0x000 },
+ { 0x0000a000, 0x00200c11, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0x00204402, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000ffff, 0xc0281220, 0x000 },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00304883, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x83000000, 0x00604411, 0x412 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xa9800000, 0x00200811, 0x000 },
+ { 0x0000c000, 0x00400c11, 0x3fa },
+ { 0xab800000, 0x00200811, 0x000 },
+ { 0x0000f8e0, 0x00400c11, 0x3fa },
+ { 0xad800000, 0x00200811, 0x000 },
+ { 0x0000f880, 0x00400c11, 0x3fa },
+ { 0xb3800000, 0x00200811, 0x000 },
+ { 0x0000f3fc, 0x00400c11, 0x3fa },
+ { 0xaf800000, 0x00200811, 0x000 },
+ { 0x0000e000, 0x00400c11, 0x3fa },
+ { 0xb1800000, 0x00200811, 0x000 },
+ { 0x0000f000, 0x00400c11, 0x3fa },
+ { 0x83000000, 0x00204411, 0x000 },
+ { 0x00002148, 0x00204811, 0x000 },
+ { 0x84000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x1d000000, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x01182000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0218a000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0318c000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0418f8e0, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0518f880, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0618e000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0718f000, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x0818f3fc, 0xc0304620, 0x000 },
+ { 0x00000000, 0xd9004800, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x00000033, 0xc0300a20, 0x000 },
+ { 0x00000000, 0xc0403440, 0x000 },
+ { 0x00000030, 0x00200a2d, 0x000 },
+ { 0x00000000, 0xc0290c40, 0x000 },
+ { 0x00000030, 0x00203623, 0x000 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x00a0000a, 0x000 },
+ { 0x86000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x85000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0x00404801, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x00000018, 0x40210220, 0x000 },
+ { 0x00000000, 0x14c00000, 0x447 },
+ { 0x00800000, 0xc0494a20, 0x448 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x06e00000, 0x450 },
+ { 0x00000004, 0x00200811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00404c02, 0x450 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x00000000, 0xc0201400, 0x000 },
+ { 0x00000000, 0xc0201800, 0x000 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x461 },
+ { 0x00000000, 0xc0202000, 0x000 },
+ { 0x00000004, 0x002f0228, 0x000 },
+ { 0x00000000, 0x06e00000, 0x461 },
+ { 0x00000004, 0x00202011, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x00000010, 0x00280a23, 0x000 },
+ { 0x00000010, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x469 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0x00694624, 0x622 },
+ { 0x00000000, 0x00400000, 0x46e },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00604805, 0x627 },
+ { 0x00000000, 0x002824f0, 0x000 },
+ { 0x00000007, 0x00280a23, 0x000 },
+ { 0x00000001, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x475 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x04e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000002, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47a },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x02e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000003, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x47f },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000004, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x484 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000005, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x489 },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x06e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00000006, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x48e },
+ { 0x00000000, 0x002f00c9, 0x000 },
+ { 0x00000000, 0x08e00000, 0x48e },
+ { 0x00000000, 0x00400000, 0x49b },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x000 },
+ { 0x00000008, 0x00210a23, 0x000 },
+ { 0x00000000, 0x14c00000, 0x498 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00007f00, 0x00280a21, 0x000 },
+ { 0x00004500, 0x002f0222, 0x000 },
+ { 0x00000000, 0x0ae00000, 0x4a1 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x00404c08, 0x461 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000010, 0x40210e20, 0x000 },
+ { 0x00000011, 0x40211220, 0x000 },
+ { 0x00000012, 0x40211620, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00210225, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4ab },
+ { 0x00040000, 0xc0494a20, 0x4ac },
+ { 0xfffbffff, 0xc0284a20, 0x000 },
+ { 0x00000000, 0x00210223, 0x000 },
+ { 0x00000000, 0x14e00000, 0x4b8 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x0000000c, 0x00204811, 0x000 },
+ { 0x00000000, 0x00200010, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4b4 },
+ { 0xa0000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000004, 0x00204811, 0x000 },
+ { 0x0000216b, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000216c, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204810, 0x000 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0ce00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4b2 },
+ { 0x00000000, 0xc0210a20, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4cb },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x627 },
+ { 0x00000000, 0x00400000, 0x4cf },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00040000, 0xc0294620, 0x000 },
+ { 0x00000000, 0xc0600000, 0x622 },
+ { 0x00000001, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d6 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00404811, 0x000 },
+ { 0x00000000, 0xc0204400, 0x000 },
+ { 0x00000000, 0xc0404810, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x000021f8, 0x00204411, 0x000 },
+ { 0x0000000e, 0x00204811, 0x000 },
+ { 0x000421f9, 0x00604411, 0x622 },
+ { 0x00000000, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x4d8 },
+ { 0x00002180, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000003, 0x00333e2f, 0x000 },
+ { 0x00000001, 0x00210221, 0x000 },
+ { 0x00000000, 0x14e00000, 0x508 },
+ { 0x0000002c, 0x00200a2d, 0x000 },
+ { 0x00040000, 0x18e00c11, 0x4f7 },
+ { 0x00000001, 0x00333e2f, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xd8c04800, 0x4eb },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000002d, 0x0020122d, 0x000 },
+ { 0x00000000, 0x00290c83, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204802, 0x000 },
+ { 0x00000000, 0x00204803, 0x000 },
+ { 0x00000008, 0x00300a22, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000011, 0x00210224, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000000, 0x00400000, 0x4b2 },
+ { 0x0000002c, 0xc0203620, 0x000 },
+ { 0x0000002d, 0xc0403620, 0x000 },
+ { 0x0000000f, 0x00210221, 0x000 },
+ { 0x00000000, 0x14c00000, 0x50d },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00000000, 0xd9000000, 0x000 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0xb5000000, 0x00204411, 0x000 },
+ { 0x00002000, 0x00204811, 0x000 },
+ { 0xb6000000, 0x00204411, 0x000 },
+ { 0x0000a000, 0x00204811, 0x000 },
+ { 0xb7000000, 0x00204411, 0x000 },
+ { 0x0000c000, 0x00204811, 0x000 },
+ { 0xb8000000, 0x00204411, 0x000 },
+ { 0x0000f8e0, 0x00204811, 0x000 },
+ { 0xb9000000, 0x00204411, 0x000 },
+ { 0x0000f880, 0x00204811, 0x000 },
+ { 0xba000000, 0x00204411, 0x000 },
+ { 0x0000e000, 0x00204811, 0x000 },
+ { 0xbb000000, 0x00204411, 0x000 },
+ { 0x0000f000, 0x00204811, 0x000 },
+ { 0xbc000000, 0x00204411, 0x000 },
+ { 0x0000f3fc, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000002, 0x00204811, 0x000 },
+ { 0x000000ff, 0x00280e30, 0x000 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x521 },
+ { 0x00000000, 0xc0200800, 0x000 },
+ { 0x00000000, 0x14c00000, 0x536 },
+ { 0x00000000, 0x00200c11, 0x000 },
+ { 0x0000001c, 0x00203623, 0x000 },
+ { 0x0000002b, 0x00203623, 0x000 },
+ { 0x00000029, 0x00203623, 0x000 },
+ { 0x00000028, 0x00203623, 0x000 },
+ { 0x00000017, 0x00203623, 0x000 },
+ { 0x00000025, 0x00203623, 0x000 },
+ { 0x00000026, 0x00203623, 0x000 },
+ { 0x00000015, 0x00203623, 0x000 },
+ { 0x00000016, 0x00203623, 0x000 },
+ { 0xffffe000, 0x00200c11, 0x000 },
+ { 0x00000021, 0x00203623, 0x000 },
+ { 0x00000022, 0x00203623, 0x000 },
+ { 0x00001fff, 0x00200c11, 0x000 },
+ { 0x00000023, 0x00203623, 0x000 },
+ { 0x00000024, 0x00203623, 0x000 },
+ { 0xf1ffffff, 0x00283a2e, 0x000 },
+ { 0x0000001a, 0xc0220e20, 0x000 },
+ { 0x00000000, 0x0029386e, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000006, 0x00204811, 0x000 },
+ { 0x0000002a, 0x40203620, 0x000 },
+ { 0x87000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0x9d000000, 0x00204411, 0x000 },
+ { 0x0000001f, 0x40214a20, 0x000 },
+ { 0x96000000, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0200c00, 0x000 },
+ { 0x00000000, 0xc0201000, 0x000 },
+ { 0x0000001f, 0x00211624, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x0000001d, 0x00203623, 0x000 },
+ { 0x00000003, 0x00281e23, 0x000 },
+ { 0x00000008, 0x00222223, 0x000 },
+ { 0xfffff000, 0x00282228, 0x000 },
+ { 0x00000000, 0x002920e8, 0x000 },
+ { 0x0000001f, 0x00203628, 0x000 },
+ { 0x00000018, 0x00211e23, 0x000 },
+ { 0x00000020, 0x00203627, 0x000 },
+ { 0x00000002, 0x00221624, 0x000 },
+ { 0x00000000, 0x003014a8, 0x000 },
+ { 0x0000001e, 0x00203625, 0x000 },
+ { 0x00000003, 0x00211a24, 0x000 },
+ { 0x10000000, 0x00281a26, 0x000 },
+ { 0xefffffff, 0x00283a2e, 0x000 },
+ { 0x00000000, 0x004938ce, 0x610 },
+ { 0x00000001, 0x40280a20, 0x000 },
+ { 0x00000006, 0x40280e20, 0x000 },
+ { 0x00000300, 0xc0281220, 0x000 },
+ { 0x00000008, 0x00211224, 0x000 },
+ { 0x00000000, 0xc0201620, 0x000 },
+ { 0x00000000, 0xc0201a20, 0x000 },
+ { 0x00000000, 0x00210222, 0x000 },
+ { 0x00000000, 0x14c00000, 0x56c },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x622 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00020000, 0x00294a26, 0x000 },
+ { 0x00000000, 0x00204810, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x574 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x582 },
+ { 0x00000002, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x574 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00002258, 0x00300a24, 0x000 },
+ { 0x00040000, 0x00694622, 0x622 },
+ { 0x00000000, 0xc0201c10, 0x000 },
+ { 0x00000000, 0xc0400000, 0x582 },
+ { 0x00000000, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x578 },
+ { 0x00000000, 0xc0201c00, 0x000 },
+ { 0x00000000, 0xc0400000, 0x582 },
+ { 0x00000004, 0x002f0223, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x580 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x0000216d, 0x00204411, 0x000 },
+ { 0x00000000, 0xc0204800, 0x000 },
+ { 0x00000000, 0xc0604800, 0x627 },
+ { 0x00000000, 0x00401c10, 0x582 },
+ { 0x00000000, 0xc0200000, 0x000 },
+ { 0x00000000, 0xc0400000, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x584 },
+ { 0x00000000, 0x00600000, 0x5c3 },
+ { 0x00000000, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x592 },
+ { 0x0000a2b7, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000033, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c4, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x590 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d1, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000001, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5a0 },
+ { 0x0000a2bb, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000034, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c5, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x59e },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d2, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x00000002, 0x002f0224, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x5ae },
+ { 0x0000a2bf, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000035, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c6, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5ac },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d3, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x0000a2c3, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204807, 0x000 },
+ { 0x00000036, 0x0020262d, 0x000 },
+ { 0x0000001a, 0x00212229, 0x000 },
+ { 0x00000006, 0x00222629, 0x000 },
+ { 0x0000a2c7, 0x00204411, 0x000 },
+ { 0x00000000, 0x003048e9, 0x000 },
+ { 0x00000000, 0x00e00000, 0x5b8 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404808, 0x000 },
+ { 0x0000a2d4, 0x00204411, 0x000 },
+ { 0x00000001, 0x00504a28, 0x000 },
+ { 0x85000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0x0000304a, 0x00204411, 0x000 },
+ { 0x01000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x00400000, 0x5be },
+ { 0xa4000000, 0xc0204411, 0x000 },
+ { 0x00000000, 0xc0404800, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5c3 },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x0000003f, 0x00204811, 0x000 },
+ { 0x00000005, 0x00204811, 0x000 },
+ { 0x0000a1f4, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x88000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0xff000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x00000002, 0x00804811, 0x000 },
+ { 0x00000000, 0x0ee00000, 0x5d6 },
+ { 0x00001000, 0x00200811, 0x000 },
+ { 0x0000002b, 0x00203622, 0x000 },
+ { 0x00000000, 0x00600000, 0x5da },
+ { 0x00000000, 0x00600000, 0x5c3 },
+ { 0x98000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00804811, 0x000 },
+ { 0x00000000, 0xc0600000, 0x5da },
+ { 0x00000000, 0xc0400400, 0x001 },
+ { 0x0000a2a4, 0x00204411, 0x000 },
+ { 0x00000022, 0x00204811, 0x000 },
+ { 0x89000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00404811, 0x5cd },
+ { 0x97000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x8a000000, 0x00204411, 0x000 },
+ { 0x00000000, 0x00404811, 0x5cd },
+ { 0x00000000, 0x00600000, 0x5f3 },
+ { 0x0001a2a4, 0xc0204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x374 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x09800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x000 },
+ { 0x00000004, 0x00404c11, 0x5ed },
+ { 0x00000000, 0x00400000, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000004, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffffb, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0x00000008, 0x00291e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x00000017, 0x00201e2d, 0x000 },
+ { 0xfffffff7, 0x00281e27, 0x000 },
+ { 0x00000017, 0x00803627, 0x000 },
+ { 0x0001a2a4, 0x00204411, 0x000 },
+ { 0x00000016, 0x00604811, 0x374 },
+ { 0x00002010, 0x00204411, 0x000 },
+ { 0x00010000, 0x00204811, 0x000 },
+ { 0x0000217c, 0x00204411, 0x000 },
+ { 0x01800000, 0x00204811, 0x000 },
+ { 0xffffffff, 0x00204811, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000000, 0x17000000, 0x000 },
+ { 0x81000000, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0004217f, 0x00604411, 0x622 },
+ { 0x0000001f, 0x00210230, 0x000 },
+ { 0x00000000, 0x14c00000, 0x621 },
+ { 0x00000010, 0x00404c11, 0x607 },
+ { 0x00000000, 0xc0200400, 0x000 },
+ { 0x00000000, 0x38c00000, 0x000 },
+ { 0x0000001d, 0x00200a2d, 0x000 },
+ { 0x0000001e, 0x00200e2d, 0x000 },
+ { 0x0000001f, 0x0020122d, 0x000 },
+ { 0x00000020, 0x0020162d, 0x000 },
+ { 0x00002169, 0x00204411, 0x000 },
+ { 0x00000000, 0x00204804, 0x000 },
+ { 0x00000000, 0x00204805, 0x000 },
+ { 0x00000000, 0x00204801, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000004, 0x00301224, 0x000 },
+ { 0x00000000, 0x002f0064, 0x000 },
+ { 0x00000000, 0x0cc00000, 0x620 },
+ { 0x00000003, 0x00281a22, 0x000 },
+ { 0x00000008, 0x00221222, 0x000 },
+ { 0xfffff000, 0x00281224, 0x000 },
+ { 0x00000000, 0x002910c4, 0x000 },
+ { 0x0000001f, 0x00403624, 0x000 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x622 },
+ { 0x9f000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x625 },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x1ac00000, 0x627 },
+ { 0x9e000000, 0x00204411, 0x000 },
+ { 0xcafebabe, 0x00204811, 0x000 },
+ { 0x00000000, 0x1ae00000, 0x62a },
+ { 0x00000000, 0x00800000, 0x000 },
+ { 0x00000000, 0x00600000, 0x00b },
+ { 0x00001000, 0x00600411, 0x315 },
+ { 0x00000000, 0x00200411, 0x000 },
+ { 0x00000000, 0x00600811, 0x1b2 },
+ { 0x0000225c, 0x00204411, 0x000 },
+ { 0x00000003, 0x00204811, 0x000 },
+ { 0x00002256, 0x00204411, 0x000 },
+ { 0x0000001b, 0x00204811, 0x000 },
+ { 0x0000a1fc, 0x00204411, 0x000 },
+ { 0x00000001, 0x00204811, 0x000 },
+ { 0x0001a1fd, 0xc0204411, 0x000 },
+ { 0x00000021, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000024, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000022, 0x0020222d, 0x000 },
+ { 0x0000ffff, 0x00282228, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00204811, 0x000 },
+ { 0x00000023, 0x00201e2d, 0x000 },
+ { 0x00000010, 0x00221e27, 0x000 },
+ { 0x00000000, 0x00294907, 0x000 },
+ { 0x00000000, 0x00404811, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x00000000, 0x00000000, 0x000 },
+ { 0x0142050a, 0x05ba0250, 0x000 },
+ { 0x01c30168, 0x044105ba, 0x000 },
+ { 0x02250209, 0x02500151, 0x000 },
+ { 0x02230245, 0x02a00241, 0x000 },
+ { 0x03d705ba, 0x05ba05ba, 0x000 },
+ { 0x05e205e3, 0x031f05ba, 0x000 },
+ { 0x032005bf, 0x0320034a, 0x000 },
+ { 0x03340282, 0x034c033e, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba0557, 0x05ba032a, 0x000 },
+ { 0x03bc05ba, 0x04c3034e, 0x000 },
+ { 0x04a20455, 0x043f05ba, 0x000 },
+ { 0x04d805ba, 0x044304e5, 0x000 },
+ { 0x0455050f, 0x035b037b, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05d805c1, 0x000 },
+ { 0x05ba05ba, 0x000705ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x03f803ed, 0x04080406, 0x000 },
+ { 0x040e040a, 0x040c0410, 0x000 },
+ { 0x041c0418, 0x04240420, 0x000 },
+ { 0x042c0428, 0x04340430, 0x000 },
+ { 0x05ba05ba, 0x043a0438, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x05ba05ba, 0x05ba05ba, 0x000 },
+ { 0x0002060e, 0x062c0006, 0x000 },
+};
+
+static const u32 RS780_pfp_microcode[] = {
+0xca0400,
+0xa00000,
+0x7e828b,
+0x7c038b,
+0x8001db,
+0x7c038b,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xc41838,
+0xca2400,
+0xca2800,
+0x9581cb,
+0xc41c3a,
+0xc3c000,
+0xca0800,
+0xca0c00,
+0x7c744b,
+0xc20005,
+0x99c000,
+0xc41c3a,
+0x7c744c,
+0xc0ffe0,
+0x042c08,
+0x309002,
+0x7d2500,
+0x351402,
+0x7d350b,
+0x255407,
+0x7cd580,
+0x259c07,
+0x95c004,
+0xd5001b,
+0x7eddc1,
+0x7d9d80,
+0xd6801b,
+0xd5801b,
+0xd4401e,
+0xd5401e,
+0xd6401e,
+0xd6801e,
+0xd4801e,
+0xd4c01e,
+0x9783d3,
+0xd5c01e,
+0xca0800,
+0x80001a,
+0xca0c00,
+0xe4011e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xe4013e,
+0xd4001e,
+0x80000c,
+0xc41838,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0xca0c00,
+0x8001db,
+0xd48024,
+0xca0800,
+0x7c00c0,
+0xc81425,
+0xc81824,
+0x7c9488,
+0x7c9880,
+0xc20003,
+0xd40075,
+0x7c744c,
+0x800064,
+0xd4401e,
+0xca1800,
+0xd4401e,
+0xd5801e,
+0x800062,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xe2001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xd40075,
+0xd4401e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd48019,
+0xd4c018,
+0xd50017,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c01,
+0xd48060,
+0x94c003,
+0x041001,
+0x041002,
+0xd50025,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xd48061,
+0xd4401e,
+0x800000,
+0xd4801e,
+0xca0800,
+0xca0c00,
+0xd4401e,
+0xd48016,
+0xd4c016,
+0xd4801e,
+0x8001db,
+0xd4c01e,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x948004,
+0xca1400,
+0xe420f3,
+0xd42013,
+0xd56065,
+0xd4e01c,
+0xd5201c,
+0xd5601c,
+0x800000,
+0x062001,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9483f7,
+0xca1400,
+0xe420f3,
+0x80009c,
+0xd42013,
+0xc60843,
+0xca0c00,
+0xca1000,
+0x9883ef,
+0xca1400,
+0xd40064,
+0x8000b0,
+0x000000,
+0xc41432,
+0xc61843,
+0xc4082f,
+0x954005,
+0xc40c30,
+0xd4401e,
+0x800000,
+0xee001e,
+0x9583f5,
+0xc41031,
+0xd44033,
+0xd52065,
+0xd4a01c,
+0xd4e01c,
+0xd5201c,
+0xe4015e,
+0xd4001e,
+0x800000,
+0x062001,
+0xca1800,
+0x0a2001,
+0xd60076,
+0xc40836,
+0x988007,
+0xc61045,
+0x950110,
+0xd4001f,
+0xd46062,
+0x800000,
+0xd42062,
+0xcc3835,
+0xcc1433,
+0x8401de,
+0xd40072,
+0xd5401e,
+0x800000,
+0xee001e,
+0xe2001a,
+0x8401de,
+0xe2001a,
+0xcc104b,
+0xcc0447,
+0x2c9401,
+0x7d098b,
+0x984005,
+0x7d15cb,
+0xd4001a,
+0x8001db,
+0xd4006d,
+0x344401,
+0xcc0c48,
+0x98403a,
+0xcc2c4a,
+0x958004,
+0xcc0449,
+0x8001db,
+0xd4001a,
+0xd4c01a,
+0x282801,
+0x840113,
+0xcc1003,
+0x98801b,
+0x04380c,
+0x840113,
+0xcc1003,
+0x988017,
+0x043808,
+0x840113,
+0xcc1003,
+0x988013,
+0x043804,
+0x840113,
+0xcc1003,
+0x988014,
+0xcc104c,
+0x9a8009,
+0xcc144d,
+0x9840dc,
+0xd4006d,
+0xcc1848,
+0xd5001a,
+0xd5401a,
+0x8000ec,
+0xd5801a,
+0x96c0d5,
+0xd4006d,
+0x8001db,
+0xd4006e,
+0x9ac003,
+0xd4006d,
+0xd4006e,
+0x800000,
+0xec007f,
+0x9ac0cc,
+0xd4006d,
+0x8001db,
+0xd4006e,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0x7d9103,
+0x7dd583,
+0x7d190c,
+0x35cc1f,
+0x35701f,
+0x7cf0cb,
+0x7cd08b,
+0x880000,
+0x7e8e8b,
+0x95c004,
+0xd4006e,
+0x8001db,
+0xd4001a,
+0xd4c01a,
+0xcc0803,
+0xcc0c03,
+0xcc1003,
+0xcc1403,
+0xcc1803,
+0xcc1c03,
+0xcc2403,
+0xcc2803,
+0x35c41f,
+0x36b01f,
+0x7c704b,
+0x34f01f,
+0x7c704b,
+0x35701f,
+0x7c704b,
+0x7d8881,
+0x7dccc1,
+0x7e5101,
+0x7e9541,
+0x7c9082,
+0x7cd4c2,
+0x7c848b,
+0x9ac003,
+0x7c8c8b,
+0x2c8801,
+0x98809e,
+0xd4006d,
+0x98409c,
+0xd4006e,
+0xcc084c,
+0xcc0c4d,
+0xcc1048,
+0xd4801a,
+0xd4c01a,
+0x800124,
+0xd5001a,
+0xcc0832,
+0xd40032,
+0x9482b6,
+0xca0c00,
+0xd4401e,
+0x800000,
+0xd4001e,
+0xe4011e,
+0xd4001e,
+0xca0800,
+0xca0c00,
+0xca1000,
+0xd4401e,
+0xca1400,
+0xd4801e,
+0xd4c01e,
+0xd5001e,
+0xd5401e,
+0xd54034,
+0x800000,
+0xee001e,
+0x280404,
+0xe2001a,
+0xe2001a,
+0xd4401a,
+0xca3800,
+0xcc0803,
+0xcc0c03,
+0xcc0c03,
+0xcc0c03,
+0x98829a,
+0x000000,
+0x8401de,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0400,
+0xc2ff00,
+0xcc0834,
+0xc13fff,
+0x7c74cb,
+0x7cc90b,
+0x7d010f,
+0x99028d,
+0x7c738b,
+0x8401de,
+0xd7a06f,
+0x800000,
+0xee001f,
+0xca0800,
+0x281900,
+0x7d898b,
+0x958014,
+0x281404,
+0xca0c00,
+0xca1000,
+0xca1c00,
+0xca2400,
+0xe2001f,
+0xd4c01a,
+0xd5001a,
+0xd5401a,
+0xcc1803,
+0xcc2c03,
+0xcc2c03,
+0xcc2c03,
+0x7da58b,
+0x7d9c47,
+0x984274,
+0x000000,
+0x800184,
+0xd4c01a,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xe4013e,
+0xd4001e,
+0xd4401e,
+0xee001e,
+0xca0400,
+0xa00000,
+0x7e828b,
+0xca0800,
+0x248c06,
+0x0ccc06,
+0x98c006,
+0xcc104e,
+0x990004,
+0xd40073,
+0xe4011e,
+0xd4001e,
+0xd4401e,
+0xd4801e,
+0x800000,
+0xee001e,
+0xca0800,
+0xca0c00,
+0x34d018,
+0x251001,
+0x950021,
+0xc17fff,
+0xca1000,
+0xca1400,
+0xca1800,
+0xd4801d,
+0xd4c01d,
+0x7db18b,
+0xc14202,
+0xc2c001,
+0xd5801d,
+0x34dc0e,
+0x7d5d4c,
+0x7f734c,
+0xd7401e,
+0xd5001e,
+0xd5401e,
+0xc14200,
+0xc2c000,
+0x099c01,
+0x31dc10,
+0x7f5f4c,
+0x7f734c,
+0x042802,
+0x7d8380,
+0xd5a86f,
+0xd58066,
+0xd7401e,
+0xec005e,
+0xc82402,
+0xc82402,
+0x8001db,
+0xd60076,
+0xd4401e,
+0xd4801e,
+0xd4c01e,
+0x800000,
+0xee001e,
+0x800000,
+0xee001f,
+0xd4001f,
+0x800000,
+0xd4001f,
+0xd4001f,
+0x880000,
+0xd4001f,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x000000,
+0x010194,
+0x02019b,
+0x0300b2,
+0x0400a2,
+0x050003,
+0x06003f,
+0x070032,
+0x08014f,
+0x090046,
+0x0a0036,
+0x1001d9,
+0x1700c5,
+0x22015d,
+0x23016c,
+0x2000d7,
+0x240148,
+0x26004d,
+0x27005c,
+0x28008d,
+0x290051,
+0x2a007e,
+0x2b0061,
+0x2f0088,
+0x3200aa,
+0x3401a2,
+0x36006f,
+0x3c0179,
+0x3f0095,
+0x4101af,
+0x440151,
+0x550196,
+0x56019d,
+0x60000b,
+0x610034,
+0x620038,
+0x630038,
+0x640038,
+0x650038,
+0x660038,
+0x670038,
+0x68003a,
+0x690041,
+0x6a0048,
+0x6b0048,
+0x6c0048,
+0x6d0048,
+0x6e0048,
+0x6f0048,
+0x7301d9,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+0x000006,
+};
+
+static const u32 RV770_cp_microcode[] = {
+0xcc0003ea,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xd040007f,
+0x80000001,
+0xcc400041,
+0x7c40c000,
+0xc0160004,
+0x30d03fff,
+0x7d15000c,
+0xcc110000,
+0x28d8001e,
+0x31980001,
+0x28dc001f,
+0xc8200004,
+0x95c00006,
+0x7c424000,
+0xcc000062,
+0x7e56800c,
+0xcc290000,
+0xc8240004,
+0x7e26000b,
+0x95800006,
+0x7c42c000,
+0xcc000062,
+0x7ed7000c,
+0xcc310000,
+0xc82c0004,
+0x7e2e000c,
+0xcc000062,
+0x31103fff,
+0x80000001,
+0xce110000,
+0x7c40c000,
+0x80000001,
+0xcc400040,
+0x80000001,
+0xcc412257,
+0x7c418000,
+0xcc400045,
+0xcc400048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc400045,
+0xcc400048,
+0x7c40c000,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc000045,
+0xcc000048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x040ca1fd,
+0xc0120001,
+0xcc000045,
+0xcc000048,
+0x7cd0c00c,
+0xcc41225c,
+0xcc41a1fc,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xcc41225d,
+0x7c408000,
+0x7c40c000,
+0xc02a0002,
+0x7c410000,
+0x7d29000c,
+0x30940001,
+0x30980006,
+0x309c0300,
+0x29dc0008,
+0x7c420000,
+0x7c424000,
+0x9540000f,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0xccc12169,
+0xcd01216a,
+0xce81216b,
+0x0db40002,
+0xcc01216c,
+0x9740000e,
+0x0db40000,
+0x8000007b,
+0xc834000a,
+0x0db40002,
+0x97400009,
+0x0db40000,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0x8000007b,
+0xc834000a,
+0x97400004,
+0x7e028000,
+0x8000007b,
+0xc834000a,
+0x0db40004,
+0x9740ff8c,
+0x00000000,
+0xce01216d,
+0xce41216e,
+0xc8280003,
+0xc834000a,
+0x9b400004,
+0x043c0005,
+0x8400026d,
+0xcc000062,
+0x0df40000,
+0x9740000b,
+0xc82c03e6,
+0xce81a2b7,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c4,
+0x80000001,
+0xcfc1a2d1,
+0x0df40001,
+0x9740000b,
+0xc82c03e7,
+0xce81a2bb,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c5,
+0x80000001,
+0xcfc1a2d2,
+0x0df40002,
+0x9740000b,
+0xc82c03e8,
+0xce81a2bf,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c6,
+0x80000001,
+0xcfc1a2d3,
+0xc82c03e9,
+0xce81a2c3,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c7,
+0x80000001,
+0xcfc1a2d4,
+0x80000001,
+0xcc400042,
+0x7c40c000,
+0x7c410000,
+0x2914001d,
+0x31540001,
+0x9940000d,
+0x31181000,
+0xc81c0011,
+0x09dc0001,
+0x95c0ffff,
+0xc81c0011,
+0xccc12100,
+0xcd012101,
+0xccc12102,
+0xcd012103,
+0x04180004,
+0x8000039f,
+0xcd81a2a4,
+0xc02a0004,
+0x95800008,
+0x36a821a3,
+0xcc290000,
+0xc8280004,
+0xc81c0011,
+0x0de40040,
+0x9640ffff,
+0xc81c0011,
+0xccc12170,
+0xcd012171,
+0xc8200012,
+0x96000000,
+0xc8200012,
+0x8000039f,
+0xcc000064,
+0x7c40c000,
+0x7c410000,
+0xcc000045,
+0xcc000048,
+0x40d40003,
+0xcd41225c,
+0xcd01a1fc,
+0xc01a0001,
+0x041ca1fd,
+0x7dd9c00c,
+0x7c420000,
+0x08cc0001,
+0x06240001,
+0x06280002,
+0xce1d0000,
+0xce5d0000,
+0x98c0fffa,
+0xce9d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x30d00001,
+0x28cc0001,
+0x7c414000,
+0x95000006,
+0x7c418000,
+0xcd41216d,
+0xcd81216e,
+0x800000f3,
+0xc81c0003,
+0xc0220004,
+0x7e16000c,
+0xcc210000,
+0xc81c0004,
+0x7c424000,
+0x98c00004,
+0x7c428000,
+0x80000001,
+0xcde50000,
+0xce412169,
+0xce81216a,
+0xcdc1216b,
+0x80000001,
+0xcc01216c,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9680000a,
+0x7c020000,
+0x7c420000,
+0x1e300003,
+0xcc00006a,
+0x9b000003,
+0x42200005,
+0x04200040,
+0x80000110,
+0x7c024000,
+0x7e024000,
+0x9a400000,
+0x0a640001,
+0x30ec0010,
+0x9ac0000a,
+0xcc000062,
+0xc02a0004,
+0xc82c0021,
+0x7e92800c,
+0xcc000041,
+0xcc290000,
+0xcec00021,
+0x80000120,
+0xc8300004,
+0xcd01216d,
+0xcd41216e,
+0xc8300003,
+0x7f1f000b,
+0x30f40007,
+0x27780001,
+0x9740002a,
+0x07b80125,
+0x9f800000,
+0x00000000,
+0x80000135,
+0x7f1b8004,
+0x80000139,
+0x7f1b8005,
+0x8000013d,
+0x7f1b8002,
+0x80000141,
+0x7f1b8003,
+0x80000145,
+0x7f1b8007,
+0x80000149,
+0x7f1b8006,
+0x8000014e,
+0x28a40008,
+0x9b800019,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800015,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800011,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b80000d,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800009,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x9b800005,
+0x28a40008,
+0x8000015e,
+0x326400ff,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9a80feb1,
+0x28ec0008,
+0x7c434000,
+0x7c438000,
+0x7c43c000,
+0x96c00007,
+0xcc000062,
+0xcf412169,
+0xcf81216a,
+0xcfc1216b,
+0x80000001,
+0xcc01216c,
+0x80000001,
+0xcff50000,
+0xcc00006b,
+0x840003a2,
+0x0e68003c,
+0x9a800004,
+0xc8280015,
+0x80000001,
+0xd040007f,
+0x9680ffab,
+0x7e024000,
+0x8400023b,
+0xc00e0002,
+0xcc000041,
+0x80000239,
+0xccc1304a,
+0x7c40c000,
+0x7c410000,
+0xc01e0001,
+0x29240012,
+0xc0220002,
+0x96400005,
+0xc0260004,
+0xc027fffb,
+0x7d25000b,
+0xc0260000,
+0x7dd2800b,
+0x7e12c00b,
+0x7d25000c,
+0x7c414000,
+0x7c418000,
+0xccc12169,
+0x9a80000a,
+0xcd01216a,
+0xcd41216b,
+0x96c0fe82,
+0xcd81216c,
+0xc8300018,
+0x97000000,
+0xc8300018,
+0x80000001,
+0xcc000018,
+0x840003a2,
+0xcc00007f,
+0xc8140013,
+0xc8180014,
+0xcd41216b,
+0x96c0fe76,
+0xcd81216c,
+0x80000182,
+0xc8300018,
+0xc80c0008,
+0x98c00000,
+0xc80c0008,
+0x7c410000,
+0x95000002,
+0x00000000,
+0x7c414000,
+0xc8200009,
+0xcc400043,
+0xce01a1f4,
+0xcc400044,
+0xc00e8000,
+0x7c424000,
+0x7c428000,
+0x2aac001f,
+0x96c0fe63,
+0xc035f000,
+0xce4003e2,
+0x32780003,
+0x267c0008,
+0x7ff7c00b,
+0x7ffbc00c,
+0x2a780018,
+0xcfc003e3,
+0xcf8003e4,
+0x26b00002,
+0x7f3f0000,
+0xcf0003e5,
+0x8000031f,
+0x7c80c000,
+0x7c40c000,
+0x28d00008,
+0x3110000f,
+0x9500000f,
+0x25280001,
+0x06a801b3,
+0x9e800000,
+0x00000000,
+0x800001d4,
+0xc0120800,
+0x800001e2,
+0xc814000f,
+0x800001e9,
+0xc8140010,
+0x800001f0,
+0xccc1a2a4,
+0x800001f9,
+0xc8140011,
+0x30d0003f,
+0x0d280015,
+0x9a800012,
+0x0d28001e,
+0x9a80001e,
+0x0d280020,
+0x9a800023,
+0x0d24000f,
+0x0d280010,
+0x7e6a800c,
+0x9a800026,
+0x0d200004,
+0x0d240014,
+0x0d280028,
+0x7e62400c,
+0x7ea6800c,
+0x9a80002a,
+0xc8140011,
+0x80000001,
+0xccc1a2a4,
+0xc0120800,
+0x7c414000,
+0x7d0cc00c,
+0xc0120008,
+0x29580003,
+0x295c000c,
+0x7c420000,
+0x7dd1c00b,
+0x26200014,
+0x7e1e400c,
+0x7e4e800c,
+0xce81a2a4,
+0x80000001,
+0xcd81a1fe,
+0xc814000f,
+0x0410210e,
+0x95400000,
+0xc814000f,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xc8140010,
+0x04102108,
+0x95400000,
+0xc8140010,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xccc1a2a4,
+0x04100001,
+0xcd000019,
+0x840003a2,
+0xcc00007f,
+0xc8100019,
+0x99000000,
+0xc8100019,
+0x80000002,
+0x7c408000,
+0x04102100,
+0x09540001,
+0x9540ffff,
+0xc8140011,
+0xd0510000,
+0x8000039f,
+0xccc1a2a4,
+0x7c40c000,
+0xcc40000d,
+0x94c0fdff,
+0xcc40000e,
+0x7c410000,
+0x95000005,
+0x08cc0001,
+0xc8140005,
+0x99400014,
+0x00000000,
+0x98c0fffb,
+0x7c410000,
+0x80000002,
+0x7d008000,
+0xc8140005,
+0x7c40c000,
+0x9940000c,
+0xc818000c,
+0x7c410000,
+0x9580fdee,
+0xc820000e,
+0xc81c000d,
+0x66200020,
+0x7e1e002c,
+0x25240002,
+0x7e624020,
+0x80000001,
+0xcce60000,
+0x7c410000,
+0xcc00006c,
+0xcc00006d,
+0xc818001f,
+0xc81c001e,
+0x65980020,
+0x7dd9c02c,
+0x7cd4c00c,
+0xccde0000,
+0x45dc0004,
+0xc8280017,
+0x9680000f,
+0xc00e0001,
+0x28680008,
+0x2aac0016,
+0x32a800ff,
+0x0eb00049,
+0x7f2f000b,
+0x97000006,
+0x00000000,
+0xc8140005,
+0x7c40c000,
+0x80000223,
+0x7c410000,
+0x80000226,
+0xd040007f,
+0x8400023b,
+0xcc000041,
+0xccc1304a,
+0x94000000,
+0xc83c001a,
+0x043c0005,
+0xcfc1a2a4,
+0xc0361f90,
+0xc0387fff,
+0x7c03c010,
+0x7f7b400c,
+0xcf41217c,
+0xcfc1217d,
+0xcc01217e,
+0xc03a0004,
+0x0434217f,
+0x7f7b400c,
+0xcc350000,
+0xc83c0004,
+0x2bfc001f,
+0x04380020,
+0x97c00005,
+0xcc000062,
+0x9b800000,
+0x0bb80001,
+0x80000247,
+0xcc000071,
+0xcc01a1f4,
+0x04380016,
+0xc0360002,
+0xcf81a2a4,
+0x88000000,
+0xcf412010,
+0x7c40c000,
+0x28d0001c,
+0x95000005,
+0x04d40001,
+0xcd400065,
+0x80000001,
+0xcd400068,
+0x09540002,
+0x80000001,
+0xcd400066,
+0x8400026c,
+0xc81803ea,
+0x7c40c000,
+0x9980fd9d,
+0xc8140016,
+0x08d00001,
+0x9940002b,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0005,
+0xcfc1a2a4,
+0xcc01a1f4,
+0x840003a2,
+0xcc000046,
+0x88000000,
+0xcc00007f,
+0x8400027e,
+0xc81803ea,
+0x7c40c000,
+0x9980fd8b,
+0xc8140016,
+0x08d00001,
+0x99400019,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0022,
+0xcfc1a2a4,
+0x840003a2,
+0xcc000047,
+0x88000000,
+0xcc00007f,
+0xc8100016,
+0x9900000d,
+0xcc400067,
+0x80000002,
+0x7c408000,
+0xc81803ea,
+0x9980fd77,
+0x7c40c000,
+0x94c00003,
+0xc8100016,
+0x99000004,
+0xccc00068,
+0x80000002,
+0x7c408000,
+0x8400023b,
+0xc0148000,
+0xcc000041,
+0xcd41304a,
+0xc0148000,
+0x99000000,
+0xc8100016,
+0x80000002,
+0x7c408000,
+0xc0120001,
+0x7c51400c,
+0x80000001,
+0xd0550000,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x291c001f,
+0xccc0004a,
+0xcd00004b,
+0x95c00003,
+0xc01c8000,
+0xcdc12010,
+0xdd830000,
+0x055c2000,
+0xcc000062,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004c,
+0xcd00004d,
+0xdd830000,
+0x055ca000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004e,
+0xcd00004f,
+0xdd830000,
+0x055cc000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00050,
+0xcd000051,
+0xdd830000,
+0x055cf8e0,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00052,
+0xcd000053,
+0xdd830000,
+0x055cf880,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00054,
+0xcd000055,
+0xdd830000,
+0x055ce000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00056,
+0xcd000057,
+0xdd830000,
+0x055cf000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00058,
+0xcd000059,
+0xdd830000,
+0x055cf3fc,
+0x80000001,
+0xd81f4100,
+0xd0432000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043a000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043c000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f8e0,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f880,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043e000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f3fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc81403e0,
+0xcc430000,
+0xcc430000,
+0xcc430000,
+0x7d45c000,
+0xcdc30000,
+0xd0430000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0xc81003e2,
+0xc81403e5,
+0xc81803e3,
+0xc81c03e4,
+0xcd812169,
+0xcdc1216a,
+0xccc1216b,
+0xcc01216c,
+0x04200004,
+0x7da18000,
+0x7d964002,
+0x9640fcd7,
+0xcd8003e3,
+0x31280003,
+0xc02df000,
+0x25180008,
+0x7dad800b,
+0x7da9800c,
+0x80000001,
+0xcd8003e3,
+0x308cffff,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x7c410000,
+0x29240018,
+0x32640001,
+0x9a400013,
+0xc8140020,
+0x15580002,
+0x9580ffff,
+0xc8140020,
+0xcc00006e,
+0xccc12180,
+0xcd01218d,
+0xcc412181,
+0x2914001f,
+0x34588000,
+0xcd81218c,
+0x9540fcb9,
+0xcc412182,
+0xc8140020,
+0x9940ffff,
+0xc8140020,
+0x80000002,
+0x7c408000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x65b40020,
+0x7f57402c,
+0xd4378100,
+0x47740004,
+0xd4378100,
+0x47740004,
+0xd4378100,
+0x47740004,
+0x09dc0004,
+0xd4378100,
+0x99c0fff8,
+0x47740004,
+0x2924001f,
+0xc0380019,
+0x9640fca1,
+0xc03e0004,
+0xcf8121f8,
+0x37e021f9,
+0xcc210000,
+0xc8200004,
+0x2a200018,
+0x32200001,
+0x9a00fffb,
+0xcf8121f8,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x28d00018,
+0x31100001,
+0xc0160080,
+0x95000003,
+0xc02a0004,
+0x7cd4c00c,
+0xccc1217c,
+0xcc41217d,
+0xcc41217e,
+0x7c418000,
+0x1db00003,
+0x36a0217f,
+0x9b000003,
+0x419c0005,
+0x041c0040,
+0x99c00000,
+0x09dc0001,
+0xcc210000,
+0xc8240004,
+0x2a6c001f,
+0x419c0005,
+0x9ac0fffa,
+0xcc800062,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x04d403e6,
+0x80000001,
+0xcc540000,
+0x8000039f,
+0xcc4003ea,
+0xc01c8000,
+0x044ca000,
+0xcdc12010,
+0x7c410000,
+0xc8140009,
+0x04180000,
+0x041c0008,
+0xcd800071,
+0x09dc0001,
+0x05980001,
+0xcd0d0000,
+0x99c0fffc,
+0xcc800062,
+0x8000039f,
+0xcd400071,
+0xc00e0100,
+0xcc000041,
+0xccc1304a,
+0xc83c007f,
+0xcc00007f,
+0x80000001,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00010333,
+0x00100004,
+0x00170006,
+0x00210008,
+0x00270028,
+0x00280023,
+0x00290029,
+0x002a0026,
+0x002b0029,
+0x002d0038,
+0x002e003f,
+0x002f004a,
+0x0034004c,
+0x00360030,
+0x003900af,
+0x003a00d0,
+0x003b00e5,
+0x003c00fd,
+0x003d016c,
+0x003f00ad,
+0x00410338,
+0x0043036c,
+0x0044018f,
+0x004500fd,
+0x004601ad,
+0x004701ad,
+0x00480200,
+0x0049020e,
+0x004a0257,
+0x004b0284,
+0x00520261,
+0x00530273,
+0x00540289,
+0x0057029b,
+0x0060029f,
+0x006102ae,
+0x006202b8,
+0x006302c2,
+0x006402cc,
+0x006502d6,
+0x006602e0,
+0x006702ea,
+0x006802f4,
+0x006902f8,
+0x006a02fc,
+0x006b0300,
+0x006c0304,
+0x006d0308,
+0x006e030c,
+0x006f0310,
+0x00700314,
+0x00720386,
+0x0074038c,
+0x0079038a,
+0x007c031e,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+0x000f039b,
+};
+
+static const u32 RV770_pfp_microcode[] = {
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x80000000,
+0xdc030000,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xc818000e,
+0x31980001,
+0x7c424000,
+0x95800252,
+0x7c428000,
+0xc81c001c,
+0xc037c000,
+0x7c40c000,
+0x7c410000,
+0x7cb4800b,
+0xc0360003,
+0x99c00000,
+0xc81c001c,
+0x7cb4800c,
+0x24d40002,
+0x7d654000,
+0xcd400043,
+0xce800043,
+0xcd000043,
+0xcc800040,
+0xce400040,
+0xce800040,
+0xccc00040,
+0xdc3a0000,
+0x9780ffde,
+0xcd000040,
+0x7c40c000,
+0x80000018,
+0x7c410000,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x8000000c,
+0x31980002,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x288c0008,
+0x30cc000f,
+0x34100001,
+0x7d0d0008,
+0x8000000c,
+0x7d91800b,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc4003f9,
+0x80000261,
+0xcc4003f8,
+0xc82003f8,
+0xc81c03f9,
+0xc81803fb,
+0xc037ffff,
+0x7c414000,
+0xcf41a29e,
+0x66200020,
+0x7de1c02c,
+0x7d58c008,
+0x7cdcc020,
+0x68d00020,
+0xc0360003,
+0xcc000054,
+0x7cb4800c,
+0x8000006a,
+0xcc800040,
+0x7c418000,
+0xcd81a29e,
+0xcc800040,
+0xcd800040,
+0x80000068,
+0xcc000054,
+0xc019ffff,
+0xcc800040,
+0xcd81a29e,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcc400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc000054,
+0xcc800040,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00001,
+0xccc1a29f,
+0x95000003,
+0x04140001,
+0x04140002,
+0xcd4003fb,
+0xcc800040,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0xcc800040,
+0xccc1a2a2,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0x28d4001f,
+0xcc800040,
+0x95400003,
+0x7c410000,
+0xccc00057,
+0x2918001f,
+0xccc00040,
+0x95800003,
+0xcd000040,
+0xcd000058,
+0x80000261,
+0xcc00007f,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0xca0c0010,
+0x7c410000,
+0x94c00004,
+0x7c414000,
+0xd42002c4,
+0xcde00044,
+0x9b00000b,
+0x7c418000,
+0xcc00004b,
+0xcda00049,
+0xcd200041,
+0xcd600041,
+0xcda00041,
+0x06200001,
+0xce000056,
+0x80000261,
+0xcc00007f,
+0xc8280020,
+0xc82c0021,
+0xcc000063,
+0x7eea4001,
+0x65740020,
+0x7f53402c,
+0x269c0002,
+0x7df5c020,
+0x69f80020,
+0xce80004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0xce600041,
+0x271c0002,
+0x7df5c020,
+0x69f80020,
+0x7db24001,
+0xcf00004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0x800000bd,
+0xce600041,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xca0c0010,
+0x7c410000,
+0x94c0000b,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0x800000b6,
+0x7c414000,
+0xcc000048,
+0x800000ef,
+0x00000000,
+0xc8200017,
+0xc81c0023,
+0x0e240002,
+0x99c00015,
+0x7c418000,
+0x0a200001,
+0xce000056,
+0xd4000440,
+0xcc000040,
+0xc036c000,
+0xca140013,
+0x96400007,
+0x37747900,
+0xcf400040,
+0xcc000040,
+0xc83003fa,
+0x80000104,
+0xcf000022,
+0xcc000022,
+0x9540015d,
+0xcc00007f,
+0xcca00046,
+0x80000000,
+0xcc200046,
+0x80000261,
+0xcc000064,
+0xc8200017,
+0xc810001f,
+0x96000005,
+0x09100001,
+0xd4000440,
+0xcd000040,
+0xcd000022,
+0xcc800040,
+0xd0400040,
+0xc80c0025,
+0x94c0feeb,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0x7c40c000,
+0x7c410000,
+0xccc003fd,
+0xcd0003fc,
+0xccc00042,
+0xcd000042,
+0x2914001f,
+0x29180010,
+0x31980007,
+0x3b5c0001,
+0x7d76000b,
+0x99800005,
+0x7d5e400b,
+0xcc000042,
+0x80000261,
+0xcc00004d,
+0x29980001,
+0x292c0008,
+0x9980003d,
+0x32ec0001,
+0x96000004,
+0x2930000c,
+0x80000261,
+0xcc000042,
+0x04140010,
+0xcd400042,
+0x33300001,
+0x34280001,
+0x8400015e,
+0xc8140003,
+0x9b40001b,
+0x0438000c,
+0x8400015e,
+0xc8140003,
+0x9b400017,
+0x04380008,
+0x8400015e,
+0xc8140003,
+0x9b400013,
+0x04380004,
+0x8400015e,
+0xc8140003,
+0x9b400015,
+0xc80c03fd,
+0x9a800009,
+0xc81003fc,
+0x9b000118,
+0xcc00004d,
+0x04140010,
+0xccc00042,
+0xcd000042,
+0x80000136,
+0xcd400042,
+0x96c00111,
+0xcc00004d,
+0x80000261,
+0xcc00004e,
+0x9ac00003,
+0xcc00004d,
+0xcc00004e,
+0xdf830000,
+0x80000000,
+0xd80301ff,
+0x9ac00107,
+0xcc00004d,
+0x80000261,
+0xcc00004e,
+0xc8180003,
+0xc81c0003,
+0xc8200003,
+0x7d5d4003,
+0x7da1c003,
+0x7d5d400c,
+0x2a10001f,
+0x299c001f,
+0x7d1d000b,
+0x7d17400b,
+0x88000000,
+0x7e92800b,
+0x96400004,
+0xcc00004e,
+0x80000261,
+0xcc000042,
+0x04380008,
+0xcf800042,
+0xc8080003,
+0xc80c0003,
+0xc8100003,
+0xc8140003,
+0xc8180003,
+0xc81c0003,
+0xc8240003,
+0xc8280003,
+0x29fc001f,
+0x2ab0001f,
+0x7ff3c00b,
+0x28f0001f,
+0x7ff3c00b,
+0x2970001f,
+0x7ff3c00b,
+0x7d888001,
+0x7dccc001,
+0x7e510001,
+0x7e954001,
+0x7c908002,
+0x7cd4c002,
+0x7cbc800b,
+0x9ac00003,
+0x7c8f400b,
+0x38b40001,
+0x9b4000d8,
+0xcc00004d,
+0x9bc000d6,
+0xcc00004e,
+0xc80c03fd,
+0xc81003fc,
+0xccc00042,
+0x8000016f,
+0xcd000042,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xcc400040,
+0xcc400040,
+0xcc400040,
+0x7c40c000,
+0xccc00040,
+0xccc0000d,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0x7c410000,
+0x65140020,
+0x7d4d402c,
+0x24580002,
+0x7d598020,
+0x7c41c000,
+0xcd800042,
+0x69980020,
+0xcd800042,
+0xcdc00042,
+0xc023c000,
+0x05e40002,
+0x7ca0800b,
+0x26640010,
+0x7ca4800c,
+0xcc800040,
+0xcdc00040,
+0xccc00040,
+0x95c0000e,
+0xcd000040,
+0x09dc0001,
+0xc8280003,
+0x96800008,
+0xce800040,
+0xc834001d,
+0x97400000,
+0xc834001d,
+0x26a80008,
+0x84000264,
+0xcc2b0000,
+0x99c0fff7,
+0x09dc0001,
+0xdc3a0000,
+0x97800004,
+0x7c418000,
+0x800001a3,
+0x25980002,
+0xa0000000,
+0x7d808000,
+0xc818001d,
+0x7c40c000,
+0x64d00008,
+0x95800000,
+0xc818001d,
+0xcc130000,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xcc400040,
+0xc810001f,
+0x7c40c000,
+0xcc800040,
+0x7cd1400c,
+0xcd400040,
+0x05180001,
+0x80000000,
+0xcd800022,
+0x7c40c000,
+0x64500020,
+0x84000264,
+0xcc000061,
+0x7cd0c02c,
+0xc8200017,
+0xc8d60000,
+0x99400008,
+0x7c438000,
+0xdf830000,
+0xcfa0004f,
+0x84000264,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000261,
+0xcc000062,
+0x84000264,
+0xcc000061,
+0xc8200017,
+0x7c40c000,
+0xc036ff00,
+0xc810000d,
+0xc0303fff,
+0x7cf5400b,
+0x7d51800b,
+0x7d81800f,
+0x99800008,
+0x7cf3800b,
+0xdf830000,
+0xcfa0004f,
+0x84000264,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000261,
+0xcc000062,
+0x84000264,
+0x7c40c000,
+0x28dc0008,
+0x95c00019,
+0x30dc0010,
+0x7c410000,
+0x99c00004,
+0x64540020,
+0x80000209,
+0xc91d0000,
+0x7d15002c,
+0xc91e0000,
+0x7c420000,
+0x7c424000,
+0x7c418000,
+0x7de5c00b,
+0x7de28007,
+0x9a80000e,
+0x41ac0005,
+0x9ac00000,
+0x0aec0001,
+0x30dc0010,
+0x99c00004,
+0x00000000,
+0x8000020c,
+0xc91d0000,
+0x8000020c,
+0xc91e0000,
+0xcc800040,
+0xccc00040,
+0xd0400040,
+0xc80c0025,
+0x94c0fde3,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00006,
+0x0d100006,
+0x99000007,
+0xc8140015,
+0x99400005,
+0xcc000052,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0xcc4d0000,
+0xdc3a0000,
+0x9780fdbc,
+0x04cc0001,
+0x80000243,
+0xcc4d0000,
+0x7c40c000,
+0x7c410000,
+0x29240018,
+0x32640001,
+0x9640000f,
+0xcc800040,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0xccc00043,
+0xcd000043,
+0x31dc7fff,
+0xcdc00043,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcd800040,
+0x80000000,
+0xcdc00040,
+0xccc00040,
+0xcd000040,
+0x80000000,
+0xd0400040,
+0x80000000,
+0xd040007f,
+0xcc00007f,
+0x80000000,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00030223,
+0x0004022b,
+0x000500a0,
+0x00020003,
+0x0006003c,
+0x00070027,
+0x00080192,
+0x00090044,
+0x000a002d,
+0x0010025f,
+0x001700f1,
+0x002201d8,
+0x002301e9,
+0x0026004c,
+0x0027005f,
+0x0020011b,
+0x00280093,
+0x0029004f,
+0x002a0084,
+0x002b0065,
+0x002f008e,
+0x003200d9,
+0x00340233,
+0x00360075,
+0x0039010b,
+0x003c01fd,
+0x003f00a0,
+0x00410248,
+0x00440195,
+0x0048019e,
+0x004901c6,
+0x004a01d0,
+0x00550226,
+0x0056022e,
+0x0060000a,
+0x0061002a,
+0x00620030,
+0x00630030,
+0x00640030,
+0x00650030,
+0x00660030,
+0x00670030,
+0x00680037,
+0x0069003f,
+0x006a0047,
+0x006b0047,
+0x006c0047,
+0x006d0047,
+0x006e0047,
+0x006f0047,
+0x00700047,
+0x0073025f,
+0x007b0241,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+};
+
+static const u32 RV730_pfp_microcode[] = {
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x80000000,
+0xdc030000,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xc818000e,
+0x31980001,
+0x7c424000,
+0x9580023a,
+0x7c428000,
+0xc81c001c,
+0xc037c000,
+0x7c40c000,
+0x7c410000,
+0x7cb4800b,
+0xc0360003,
+0x99c00000,
+0xc81c001c,
+0x7cb4800c,
+0x24d40002,
+0x7d654000,
+0xcd400043,
+0xce800043,
+0xcd000043,
+0xcc800040,
+0xce400040,
+0xce800040,
+0xccc00040,
+0xdc3a0000,
+0x9780ffde,
+0xcd000040,
+0x7c40c000,
+0x80000018,
+0x7c410000,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x8000000c,
+0x31980002,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x288c0008,
+0x30cc000f,
+0x34100001,
+0x7d0d0008,
+0x8000000c,
+0x7d91800b,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc4003f9,
+0x80000249,
+0xcc4003f8,
+0xc037ffff,
+0x7c414000,
+0xcf41a29e,
+0xc82003f8,
+0xc81c03f9,
+0x66200020,
+0xc81803fb,
+0x7de1c02c,
+0x7d58c008,
+0x7cdcc020,
+0x69100020,
+0xc0360003,
+0xcc000054,
+0x7cb4800c,
+0x80000069,
+0xcc800040,
+0x7c418000,
+0xcd81a29e,
+0xcc800040,
+0x80000067,
+0xcd800040,
+0xc019ffff,
+0xcc800040,
+0xcd81a29e,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcc400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc000054,
+0xcc800040,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00001,
+0xccc1a29f,
+0x95000003,
+0x04140001,
+0x04140002,
+0xcd4003fb,
+0xcc800040,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0xcc800040,
+0xccc1a2a2,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0x28d4001f,
+0xcc800040,
+0x95400003,
+0x7c410000,
+0xccc00057,
+0x2918001f,
+0xccc00040,
+0x95800003,
+0xcd000040,
+0xcd000058,
+0x80000249,
+0xcc00007f,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0xca0c0010,
+0x7c410000,
+0x94c00004,
+0x7c414000,
+0xd42002c4,
+0xcde00044,
+0x9b00000b,
+0x7c418000,
+0xcc00004b,
+0xcda00049,
+0xcd200041,
+0xcd600041,
+0xcda00041,
+0x06200001,
+0xce000056,
+0x80000249,
+0xcc00007f,
+0xc8280020,
+0xc82c0021,
+0xcc000063,
+0x7eea4001,
+0x65740020,
+0x7f53402c,
+0x269c0002,
+0x7df5c020,
+0x69f80020,
+0xce80004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0xce600041,
+0x271c0002,
+0x7df5c020,
+0x69f80020,
+0x7db24001,
+0xcf00004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0x800000bc,
+0xce600041,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xca0c0010,
+0x7c410000,
+0x94c0000b,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0x800000b5,
+0x7c414000,
+0xcc000048,
+0x800000ee,
+0x00000000,
+0xc8200017,
+0xc81c0023,
+0x0e240002,
+0x99c00015,
+0x7c418000,
+0x0a200001,
+0xce000056,
+0xd4000440,
+0xcc000040,
+0xc036c000,
+0xca140013,
+0x96400007,
+0x37747900,
+0xcf400040,
+0xcc000040,
+0xc83003fa,
+0x80000103,
+0xcf000022,
+0xcc000022,
+0x95400146,
+0xcc00007f,
+0xcca00046,
+0x80000000,
+0xcc200046,
+0x80000249,
+0xcc000064,
+0xc8200017,
+0xc810001f,
+0x96000005,
+0x09100001,
+0xd4000440,
+0xcd000040,
+0xcd000022,
+0xcc800040,
+0xd0400040,
+0xc80c0025,
+0x94c0feec,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0x7c40c000,
+0x7c410000,
+0xccc003fd,
+0xcd0003fc,
+0xccc00042,
+0xcd000042,
+0x2914001f,
+0x29180010,
+0x31980007,
+0x3b5c0001,
+0x7d76000b,
+0x99800005,
+0x7d5e400b,
+0xcc000042,
+0x80000249,
+0xcc00004d,
+0x29980001,
+0x292c0008,
+0x9980003d,
+0x32ec0001,
+0x96000004,
+0x2930000c,
+0x80000249,
+0xcc000042,
+0x04140010,
+0xcd400042,
+0x33300001,
+0x34280001,
+0x8400015d,
+0xc8140003,
+0x9b40001b,
+0x0438000c,
+0x8400015d,
+0xc8140003,
+0x9b400017,
+0x04380008,
+0x8400015d,
+0xc8140003,
+0x9b400013,
+0x04380004,
+0x8400015d,
+0xc8140003,
+0x9b400015,
+0xc80c03fd,
+0x9a800009,
+0xc81003fc,
+0x9b000101,
+0xcc00004d,
+0x04140010,
+0xccc00042,
+0xcd000042,
+0x80000135,
+0xcd400042,
+0x96c000fa,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0x9ac00003,
+0xcc00004d,
+0xcc00004e,
+0xdf830000,
+0x80000000,
+0xd80301ff,
+0x9ac000f0,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0xc8180003,
+0xc81c0003,
+0xc8200003,
+0x7d5d4003,
+0x7da1c003,
+0x7d5d400c,
+0x2a10001f,
+0x299c001f,
+0x7d1d000b,
+0x7d17400b,
+0x88000000,
+0x7e92800b,
+0x96400004,
+0xcc00004e,
+0x80000249,
+0xcc000042,
+0x04380008,
+0xcf800042,
+0xc8080003,
+0xc80c0003,
+0xc8100003,
+0xc8140003,
+0xc8180003,
+0xc81c0003,
+0xc8240003,
+0xc8280003,
+0x29fc001f,
+0x2ab0001f,
+0x7ff3c00b,
+0x28f0001f,
+0x7ff3c00b,
+0x2970001f,
+0x7ff3c00b,
+0x7d888001,
+0x7dccc001,
+0x7e510001,
+0x7e954001,
+0x7c908002,
+0x7cd4c002,
+0x7cbc800b,
+0x9ac00003,
+0x7c8f400b,
+0x38b40001,
+0x9b4000c1,
+0xcc00004d,
+0x9bc000bf,
+0xcc00004e,
+0xc80c03fd,
+0xc81003fc,
+0xccc00042,
+0x8000016e,
+0xcd000042,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xcc400040,
+0xcc400040,
+0xcc400040,
+0x7c40c000,
+0xccc00040,
+0xccc0000d,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0x7c410000,
+0x65140020,
+0x7d4d402c,
+0x24580002,
+0x7d598020,
+0x7c41c000,
+0xcd800042,
+0x69980020,
+0xcd800042,
+0xcdc00042,
+0xc023c000,
+0x05e40002,
+0x7ca0800b,
+0x26640010,
+0x7ca4800c,
+0xcc800040,
+0xcdc00040,
+0xccc00040,
+0x95c0000e,
+0xcd000040,
+0x09dc0001,
+0xc8280003,
+0x96800008,
+0xce800040,
+0xc834001d,
+0x97400000,
+0xc834001d,
+0x26a80008,
+0x8400024c,
+0xcc2b0000,
+0x99c0fff7,
+0x09dc0001,
+0xdc3a0000,
+0x97800004,
+0x7c418000,
+0x800001a2,
+0x25980002,
+0xa0000000,
+0x7d808000,
+0xc818001d,
+0x7c40c000,
+0x64d00008,
+0x95800000,
+0xc818001d,
+0xcc130000,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xcc400040,
+0xc810001f,
+0x7c40c000,
+0xcc800040,
+0x7cd1400c,
+0xcd400040,
+0x05180001,
+0x80000000,
+0xcd800022,
+0x7c40c000,
+0x64500020,
+0x8400024c,
+0xcc000061,
+0x7cd0c02c,
+0xc8200017,
+0xc8d60000,
+0x99400008,
+0x7c438000,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0xcc000061,
+0xc8200017,
+0x7c40c000,
+0xc036ff00,
+0xc810000d,
+0xc0303fff,
+0x7cf5400b,
+0x7d51800b,
+0x7d81800f,
+0x99800008,
+0x7cf3800b,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0x7c40c000,
+0x28dc0008,
+0x95c00019,
+0x30dc0010,
+0x7c410000,
+0x99c00004,
+0x64540020,
+0x80000208,
+0xc91d0000,
+0x7d15002c,
+0xc91e0000,
+0x7c420000,
+0x7c424000,
+0x7c418000,
+0x7de5c00b,
+0x7de28007,
+0x9a80000e,
+0x41ac0005,
+0x9ac00000,
+0x0aec0001,
+0x30dc0010,
+0x99c00004,
+0x00000000,
+0x8000020b,
+0xc91d0000,
+0x8000020b,
+0xc91e0000,
+0xcc800040,
+0xccc00040,
+0xd0400040,
+0xc80c0025,
+0x94c0fde4,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00006,
+0x0d100006,
+0x99000007,
+0xc8140015,
+0x99400005,
+0xcc000052,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0xcc4d0000,
+0xdc3a0000,
+0x9780fdbd,
+0x04cc0001,
+0x80000242,
+0xcc4d0000,
+0x80000000,
+0xd040007f,
+0xcc00007f,
+0x80000000,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00030222,
+0x0004022a,
+0x0005009f,
+0x00020003,
+0x0006003c,
+0x00070027,
+0x00080191,
+0x00090044,
+0x000a002d,
+0x00100247,
+0x001700f0,
+0x002201d7,
+0x002301e8,
+0x0026004c,
+0x0027005f,
+0x0020011a,
+0x00280092,
+0x0029004f,
+0x002a0083,
+0x002b0064,
+0x002f008d,
+0x003200d8,
+0x00340232,
+0x00360074,
+0x0039010a,
+0x003c01fc,
+0x003f009f,
+0x00410005,
+0x00440194,
+0x0048019d,
+0x004901c5,
+0x004a01cf,
+0x00550225,
+0x0056022d,
+0x0060000a,
+0x0061002a,
+0x00620030,
+0x00630030,
+0x00640030,
+0x00650030,
+0x00660030,
+0x00670030,
+0x00680037,
+0x0069003f,
+0x006a0047,
+0x006b0047,
+0x006c0047,
+0x006d0047,
+0x006e0047,
+0x006f0047,
+0x00700047,
+0x00730247,
+0x007b0240,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+};
+
+static const u32 RV730_cp_microcode[] = {
+0xcc0003ea,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xd040007f,
+0x80000001,
+0xcc400041,
+0x7c40c000,
+0xc0160004,
+0x30d03fff,
+0x7d15000c,
+0xcc110000,
+0x28d8001e,
+0x31980001,
+0x28dc001f,
+0xc8200004,
+0x95c00006,
+0x7c424000,
+0xcc000062,
+0x7e56800c,
+0xcc290000,
+0xc8240004,
+0x7e26000b,
+0x95800006,
+0x7c42c000,
+0xcc000062,
+0x7ed7000c,
+0xcc310000,
+0xc82c0004,
+0x7e2e000c,
+0xcc000062,
+0x31103fff,
+0x80000001,
+0xce110000,
+0x7c40c000,
+0x80000001,
+0xcc400040,
+0x80000001,
+0xcc412257,
+0x7c418000,
+0xcc400045,
+0xcc400048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc400045,
+0xcc400048,
+0x7c40c000,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc000045,
+0xcc000048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x040ca1fd,
+0xc0120001,
+0xcc000045,
+0xcc000048,
+0x7cd0c00c,
+0xcc41225c,
+0xcc41a1fc,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000001,
+0xcc41225d,
+0x7c408000,
+0x7c40c000,
+0xc02a0002,
+0x7c410000,
+0x7d29000c,
+0x30940001,
+0x30980006,
+0x309c0300,
+0x29dc0008,
+0x7c420000,
+0x7c424000,
+0x9540000f,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0xccc12169,
+0xcd01216a,
+0xce81216b,
+0x0db40002,
+0xcc01216c,
+0x9740000e,
+0x0db40000,
+0x8000007b,
+0xc834000a,
+0x0db40002,
+0x97400009,
+0x0db40000,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0x8000007b,
+0xc834000a,
+0x97400004,
+0x7e028000,
+0x8000007b,
+0xc834000a,
+0x0db40004,
+0x9740ff8c,
+0x00000000,
+0xce01216d,
+0xce41216e,
+0xc8280003,
+0xc834000a,
+0x9b400004,
+0x043c0005,
+0x8400026b,
+0xcc000062,
+0x0df40000,
+0x9740000b,
+0xc82c03e6,
+0xce81a2b7,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c4,
+0x80000001,
+0xcfc1a2d1,
+0x0df40001,
+0x9740000b,
+0xc82c03e7,
+0xce81a2bb,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c5,
+0x80000001,
+0xcfc1a2d2,
+0x0df40002,
+0x9740000b,
+0xc82c03e8,
+0xce81a2bf,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c6,
+0x80000001,
+0xcfc1a2d3,
+0xc82c03e9,
+0xce81a2c3,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c7,
+0x80000001,
+0xcfc1a2d4,
+0x80000001,
+0xcc400042,
+0x7c40c000,
+0x7c410000,
+0x2914001d,
+0x31540001,
+0x9940000c,
+0x31181000,
+0xc81c0011,
+0x95c00000,
+0xc81c0011,
+0xccc12100,
+0xcd012101,
+0xccc12102,
+0xcd012103,
+0x04180004,
+0x8000037c,
+0xcd81a2a4,
+0xc02a0004,
+0x95800008,
+0x36a821a3,
+0xcc290000,
+0xc8280004,
+0xc81c0011,
+0x0de40040,
+0x9640ffff,
+0xc81c0011,
+0xccc12170,
+0xcd012171,
+0xc8200012,
+0x96000000,
+0xc8200012,
+0x8000037c,
+0xcc000064,
+0x7c40c000,
+0x7c410000,
+0xcc000045,
+0xcc000048,
+0x40d40003,
+0xcd41225c,
+0xcd01a1fc,
+0xc01a0001,
+0x041ca1fd,
+0x7dd9c00c,
+0x7c420000,
+0x08cc0001,
+0x06240001,
+0x06280002,
+0xce1d0000,
+0xce5d0000,
+0x98c0fffa,
+0xce9d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x30d00001,
+0x28cc0001,
+0x7c414000,
+0x95000006,
+0x7c418000,
+0xcd41216d,
+0xcd81216e,
+0x800000f2,
+0xc81c0003,
+0xc0220004,
+0x7e16000c,
+0xcc210000,
+0xc81c0004,
+0x7c424000,
+0x98c00004,
+0x7c428000,
+0x80000001,
+0xcde50000,
+0xce412169,
+0xce81216a,
+0xcdc1216b,
+0x80000001,
+0xcc01216c,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9680000a,
+0x7c020000,
+0x7c420000,
+0x1e300003,
+0xcc00006a,
+0x9b000003,
+0x42200005,
+0x04200040,
+0x8000010f,
+0x7c024000,
+0x7e024000,
+0x9a400000,
+0x0a640001,
+0x30ec0010,
+0x9ac0000a,
+0xcc000062,
+0xc02a0004,
+0xc82c0021,
+0x7e92800c,
+0xcc000041,
+0xcc290000,
+0xcec00021,
+0x8000011f,
+0xc8300004,
+0xcd01216d,
+0xcd41216e,
+0xc8300003,
+0x7f1f000b,
+0x30f40007,
+0x27780001,
+0x9740002a,
+0x07b80124,
+0x9f800000,
+0x00000000,
+0x80000134,
+0x7f1b8004,
+0x80000138,
+0x7f1b8005,
+0x8000013c,
+0x7f1b8002,
+0x80000140,
+0x7f1b8003,
+0x80000144,
+0x7f1b8007,
+0x80000148,
+0x7f1b8006,
+0x8000014d,
+0x28a40008,
+0x9b800019,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800015,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800011,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b80000d,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800009,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x9b800005,
+0x28a40008,
+0x8000015d,
+0x326400ff,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9a80feb2,
+0x28ec0008,
+0x7c434000,
+0x7c438000,
+0x7c43c000,
+0x96c00007,
+0xcc000062,
+0xcf412169,
+0xcf81216a,
+0xcfc1216b,
+0x80000001,
+0xcc01216c,
+0x80000001,
+0xcff50000,
+0xcc00006b,
+0x8400037f,
+0x0e68003c,
+0x9a800004,
+0xc8280015,
+0x80000001,
+0xd040007f,
+0x9680ffab,
+0x7e024000,
+0x84000239,
+0xc00e0002,
+0xcc000041,
+0x80000237,
+0xccc1304a,
+0x7c40c000,
+0x7c410000,
+0xc01e0001,
+0x29240012,
+0xc0220002,
+0x96400005,
+0xc0260004,
+0xc027fffb,
+0x7d25000b,
+0xc0260000,
+0x7dd2800b,
+0x7e12c00b,
+0x7d25000c,
+0x7c414000,
+0x7c418000,
+0xccc12169,
+0x9a80000a,
+0xcd01216a,
+0xcd41216b,
+0x96c0fe83,
+0xcd81216c,
+0xc8300018,
+0x97000000,
+0xc8300018,
+0x80000001,
+0xcc000018,
+0x8400037f,
+0xcc00007f,
+0xc8140013,
+0xc8180014,
+0xcd41216b,
+0x96c0fe77,
+0xcd81216c,
+0x80000181,
+0xc8300018,
+0xc80c0008,
+0x98c00000,
+0xc80c0008,
+0x7c410000,
+0x95000002,
+0x00000000,
+0x7c414000,
+0xc8200009,
+0xcc400043,
+0xce01a1f4,
+0xcc400044,
+0xc00e8000,
+0x7c424000,
+0x7c428000,
+0x2aac001f,
+0x96c0fe64,
+0xc035f000,
+0xce4003e2,
+0x32780003,
+0x267c0008,
+0x7ff7c00b,
+0x7ffbc00c,
+0x2a780018,
+0xcfc003e3,
+0xcf8003e4,
+0x26b00002,
+0x7f3f0000,
+0xcf0003e5,
+0x8000031d,
+0x7c80c000,
+0x7c40c000,
+0x28d00008,
+0x3110000f,
+0x9500000f,
+0x25280001,
+0x06a801b2,
+0x9e800000,
+0x00000000,
+0x800001d3,
+0xc0120800,
+0x800001e1,
+0xc814000f,
+0x800001e8,
+0xc8140010,
+0x800001ef,
+0xccc1a2a4,
+0x800001f8,
+0xc8140011,
+0x30d0003f,
+0x0d280015,
+0x9a800012,
+0x0d28001e,
+0x9a80001e,
+0x0d280020,
+0x9a800023,
+0x0d24000f,
+0x0d280010,
+0x7e6a800c,
+0x9a800026,
+0x0d200004,
+0x0d240014,
+0x0d280028,
+0x7e62400c,
+0x7ea6800c,
+0x9a80002a,
+0xc8140011,
+0x80000001,
+0xccc1a2a4,
+0xc0120800,
+0x7c414000,
+0x7d0cc00c,
+0xc0120008,
+0x29580003,
+0x295c000c,
+0x7c420000,
+0x7dd1c00b,
+0x26200014,
+0x7e1e400c,
+0x7e4e800c,
+0xce81a2a4,
+0x80000001,
+0xcd81a1fe,
+0xc814000f,
+0x0410210e,
+0x95400000,
+0xc814000f,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xc8140010,
+0x04102108,
+0x95400000,
+0xc8140010,
+0xd0510000,
+0x80000001,
+0xccc1a2a4,
+0xccc1a2a4,
+0x04100001,
+0xcd000019,
+0x8400037f,
+0xcc00007f,
+0xc8100019,
+0x99000000,
+0xc8100019,
+0x80000002,
+0x7c408000,
+0x04102100,
+0x95400000,
+0xc8140011,
+0xd0510000,
+0x8000037c,
+0xccc1a2a4,
+0x7c40c000,
+0xcc40000d,
+0x94c0fe01,
+0xcc40000e,
+0x7c410000,
+0x95000005,
+0x08cc0001,
+0xc8140005,
+0x99400014,
+0x00000000,
+0x98c0fffb,
+0x7c410000,
+0x80000002,
+0x7d008000,
+0xc8140005,
+0x7c40c000,
+0x9940000c,
+0xc818000c,
+0x7c410000,
+0x9580fdf0,
+0xc820000e,
+0xc81c000d,
+0x66200020,
+0x7e1e002c,
+0x25240002,
+0x7e624020,
+0x80000001,
+0xcce60000,
+0x7c410000,
+0xcc00006c,
+0xcc00006d,
+0xc818001f,
+0xc81c001e,
+0x65980020,
+0x7dd9c02c,
+0x7cd4c00c,
+0xccde0000,
+0x45dc0004,
+0xc8280017,
+0x9680000f,
+0xc00e0001,
+0x28680008,
+0x2aac0016,
+0x32a800ff,
+0x0eb00049,
+0x7f2f000b,
+0x97000006,
+0x00000000,
+0xc8140005,
+0x7c40c000,
+0x80000221,
+0x7c410000,
+0x80000224,
+0xd040007f,
+0x84000239,
+0xcc000041,
+0xccc1304a,
+0x94000000,
+0xc83c001a,
+0x043c0005,
+0xcfc1a2a4,
+0xc0361f90,
+0xc0387fff,
+0x7c03c010,
+0x7f7b400c,
+0xcf41217c,
+0xcfc1217d,
+0xcc01217e,
+0xc03a0004,
+0x0434217f,
+0x7f7b400c,
+0xcc350000,
+0xc83c0004,
+0x2bfc001f,
+0x04380020,
+0x97c00005,
+0xcc000062,
+0x9b800000,
+0x0bb80001,
+0x80000245,
+0xcc000071,
+0xcc01a1f4,
+0x04380016,
+0xc0360002,
+0xcf81a2a4,
+0x88000000,
+0xcf412010,
+0x7c40c000,
+0x28d0001c,
+0x95000005,
+0x04d40001,
+0xcd400065,
+0x80000001,
+0xcd400068,
+0x09540002,
+0x80000001,
+0xcd400066,
+0x8400026a,
+0xc81803ea,
+0x7c40c000,
+0x9980fd9f,
+0xc8140016,
+0x08d00001,
+0x9940002b,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0005,
+0xcfc1a2a4,
+0xcc01a1f4,
+0x8400037f,
+0xcc000046,
+0x88000000,
+0xcc00007f,
+0x8400027c,
+0xc81803ea,
+0x7c40c000,
+0x9980fd8d,
+0xc8140016,
+0x08d00001,
+0x99400019,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0022,
+0xcfc1a2a4,
+0x8400037f,
+0xcc000047,
+0x88000000,
+0xcc00007f,
+0xc8100016,
+0x9900000d,
+0xcc400067,
+0x80000002,
+0x7c408000,
+0xc81803ea,
+0x9980fd79,
+0x7c40c000,
+0x94c00003,
+0xc8100016,
+0x99000004,
+0xccc00068,
+0x80000002,
+0x7c408000,
+0x84000239,
+0xc0148000,
+0xcc000041,
+0xcd41304a,
+0xc0148000,
+0x99000000,
+0xc8100016,
+0x80000002,
+0x7c408000,
+0xc0120001,
+0x7c51400c,
+0x80000001,
+0xd0550000,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x291c001f,
+0xccc0004a,
+0xcd00004b,
+0x95c00003,
+0xc01c8000,
+0xcdc12010,
+0xdd830000,
+0x055c2000,
+0xcc000062,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004c,
+0xcd00004d,
+0xdd830000,
+0x055ca000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004e,
+0xcd00004f,
+0xdd830000,
+0x055cc000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00050,
+0xcd000051,
+0xdd830000,
+0x055cf8e0,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00052,
+0xcd000053,
+0xdd830000,
+0x055cf880,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00054,
+0xcd000055,
+0xdd830000,
+0x055ce000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00056,
+0xcd000057,
+0xdd830000,
+0x055cf000,
+0x80000001,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00058,
+0xcd000059,
+0xdd830000,
+0x055cf3fc,
+0x80000001,
+0xd81f4100,
+0xd0432000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043a000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043c000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f8e0,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f880,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043e000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f3fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc81403e0,
+0xcc430000,
+0xcc430000,
+0xcc430000,
+0x7d45c000,
+0xcdc30000,
+0xd0430000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0xc81003e2,
+0xc81403e5,
+0xc81803e3,
+0xc81c03e4,
+0xcd812169,
+0xcdc1216a,
+0xccc1216b,
+0xcc01216c,
+0x04200004,
+0x7da18000,
+0x7d964002,
+0x9640fcd9,
+0xcd8003e3,
+0x31280003,
+0xc02df000,
+0x25180008,
+0x7dad800b,
+0x7da9800c,
+0x80000001,
+0xcd8003e3,
+0x308cffff,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc8140020,
+0x15580002,
+0x9580ffff,
+0xc8140020,
+0xcc00006e,
+0xcc412180,
+0x7c40c000,
+0xccc1218d,
+0xcc412181,
+0x28d0001f,
+0x34588000,
+0xcd81218c,
+0x9500fcbf,
+0xcc412182,
+0xc8140020,
+0x9940ffff,
+0xc8140020,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x28d00018,
+0x31100001,
+0xc0160080,
+0x95000003,
+0xc02a0004,
+0x7cd4c00c,
+0xccc1217c,
+0xcc41217d,
+0xcc41217e,
+0x7c418000,
+0x1db00003,
+0x36a0217f,
+0x9b000003,
+0x419c0005,
+0x041c0040,
+0x99c00000,
+0x09dc0001,
+0xcc210000,
+0xc8240004,
+0x2a6c001f,
+0x419c0005,
+0x9ac0fffa,
+0xcc800062,
+0x80000002,
+0x7c408000,
+0x7c40c000,
+0x04d403e6,
+0x80000001,
+0xcc540000,
+0x8000037c,
+0xcc4003ea,
+0xc01c8000,
+0x044ca000,
+0xcdc12010,
+0x7c410000,
+0xc8140009,
+0x04180000,
+0x041c0008,
+0xcd800071,
+0x09dc0001,
+0x05980001,
+0xcd0d0000,
+0x99c0fffc,
+0xcc800062,
+0x8000037c,
+0xcd400071,
+0xc00e0100,
+0xcc000041,
+0xccc1304a,
+0xc83c007f,
+0xcc00007f,
+0x80000001,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00010331,
+0x00100004,
+0x00170006,
+0x00210008,
+0x00270028,
+0x00280023,
+0x00290029,
+0x002a0026,
+0x002b0029,
+0x002d0038,
+0x002e003f,
+0x002f004a,
+0x0034004c,
+0x00360030,
+0x003900af,
+0x003a00cf,
+0x003b00e4,
+0x003c00fc,
+0x003d016b,
+0x003f00ad,
+0x00410336,
+0x00430349,
+0x0044018e,
+0x004500fc,
+0x004601ac,
+0x004701ac,
+0x004801fe,
+0x0049020c,
+0x004a0255,
+0x004b0282,
+0x0052025f,
+0x00530271,
+0x00540287,
+0x00570299,
+0x0060029d,
+0x006102ac,
+0x006202b6,
+0x006302c0,
+0x006402ca,
+0x006502d4,
+0x006602de,
+0x006702e8,
+0x006802f2,
+0x006902f6,
+0x006a02fa,
+0x006b02fe,
+0x006c0302,
+0x006d0306,
+0x006e030a,
+0x006f030e,
+0x00700312,
+0x00720363,
+0x00740369,
+0x00790367,
+0x007c031c,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+0x000f0378,
+};
+
+static const u32 RV710_pfp_microcode[] = {
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x80000000,
+0xdc030000,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xc818000e,
+0x31980001,
+0x7c424000,
+0x9580023a,
+0x7c428000,
+0xc81c001c,
+0xc037c000,
+0x7c40c000,
+0x7c410000,
+0x7cb4800b,
+0xc0360003,
+0x99c00000,
+0xc81c001c,
+0x7cb4800c,
+0x24d40002,
+0x7d654000,
+0xcd400043,
+0xce800043,
+0xcd000043,
+0xcc800040,
+0xce400040,
+0xce800040,
+0xccc00040,
+0xdc3a0000,
+0x9780ffde,
+0xcd000040,
+0x7c40c000,
+0x80000018,
+0x7c410000,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x8000000c,
+0x31980002,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xc818000e,
+0x288c0008,
+0x30cc000f,
+0x34100001,
+0x7d0d0008,
+0x8000000c,
+0x7d91800b,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc4003f9,
+0x80000249,
+0xcc4003f8,
+0xc037ffff,
+0x7c414000,
+0xcf41a29e,
+0xc82003f8,
+0xc81c03f9,
+0x66200020,
+0xc81803fb,
+0x7de1c02c,
+0x7d58c008,
+0x7cdcc020,
+0x69100020,
+0xc0360003,
+0xcc000054,
+0x7cb4800c,
+0x80000069,
+0xcc800040,
+0x7c418000,
+0xcd81a29e,
+0xcc800040,
+0x80000067,
+0xcd800040,
+0xc019ffff,
+0xcc800040,
+0xcd81a29e,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xcc400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xcc000054,
+0xcc800040,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0xccc1a1fa,
+0xcd01a1f9,
+0xcd41a29d,
+0xccc00040,
+0xcd000040,
+0xcd400040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00001,
+0xccc1a29f,
+0x95000003,
+0x04140001,
+0x04140002,
+0xcd4003fb,
+0xcc800040,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0xcc800040,
+0xccc1a2a2,
+0x80000000,
+0xccc00040,
+0x7c40c000,
+0x28d4001f,
+0xcc800040,
+0x95400003,
+0x7c410000,
+0xccc00057,
+0x2918001f,
+0xccc00040,
+0x95800003,
+0xcd000040,
+0xcd000058,
+0x80000249,
+0xcc00007f,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0xca0c0010,
+0x7c410000,
+0x94c00004,
+0x7c414000,
+0xd42002c4,
+0xcde00044,
+0x9b00000b,
+0x7c418000,
+0xcc00004b,
+0xcda00049,
+0xcd200041,
+0xcd600041,
+0xcda00041,
+0x06200001,
+0xce000056,
+0x80000249,
+0xcc00007f,
+0xc8280020,
+0xc82c0021,
+0xcc000063,
+0x7eea4001,
+0x65740020,
+0x7f53402c,
+0x269c0002,
+0x7df5c020,
+0x69f80020,
+0xce80004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0xce600041,
+0x271c0002,
+0x7df5c020,
+0x69f80020,
+0x7db24001,
+0xcf00004b,
+0xce600049,
+0xcde00041,
+0xcfa00041,
+0x800000bc,
+0xce600041,
+0xc8200017,
+0xc8300022,
+0x9a000006,
+0x0e280001,
+0xc824001e,
+0x0a640001,
+0xd4001240,
+0xce400040,
+0xca0c0010,
+0x7c410000,
+0x94c0000b,
+0xc036c000,
+0x96800007,
+0x37747900,
+0x041c0001,
+0xcf400040,
+0xcdc00040,
+0xcf0003fa,
+0x7c030000,
+0x800000b5,
+0x7c414000,
+0xcc000048,
+0x800000ee,
+0x00000000,
+0xc8200017,
+0xc81c0023,
+0x0e240002,
+0x99c00015,
+0x7c418000,
+0x0a200001,
+0xce000056,
+0xd4000440,
+0xcc000040,
+0xc036c000,
+0xca140013,
+0x96400007,
+0x37747900,
+0xcf400040,
+0xcc000040,
+0xc83003fa,
+0x80000103,
+0xcf000022,
+0xcc000022,
+0x95400146,
+0xcc00007f,
+0xcca00046,
+0x80000000,
+0xcc200046,
+0x80000249,
+0xcc000064,
+0xc8200017,
+0xc810001f,
+0x96000005,
+0x09100001,
+0xd4000440,
+0xcd000040,
+0xcd000022,
+0xcc800040,
+0xd0400040,
+0xc80c0025,
+0x94c0feec,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0x7c40c000,
+0x7c410000,
+0xccc003fd,
+0xcd0003fc,
+0xccc00042,
+0xcd000042,
+0x2914001f,
+0x29180010,
+0x31980007,
+0x3b5c0001,
+0x7d76000b,
+0x99800005,
+0x7d5e400b,
+0xcc000042,
+0x80000249,
+0xcc00004d,
+0x29980001,
+0x292c0008,
+0x9980003d,
+0x32ec0001,
+0x96000004,
+0x2930000c,
+0x80000249,
+0xcc000042,
+0x04140010,
+0xcd400042,
+0x33300001,
+0x34280001,
+0x8400015d,
+0xc8140003,
+0x9b40001b,
+0x0438000c,
+0x8400015d,
+0xc8140003,
+0x9b400017,
+0x04380008,
+0x8400015d,
+0xc8140003,
+0x9b400013,
+0x04380004,
+0x8400015d,
+0xc8140003,
+0x9b400015,
+0xc80c03fd,
+0x9a800009,
+0xc81003fc,
+0x9b000101,
+0xcc00004d,
+0x04140010,
+0xccc00042,
+0xcd000042,
+0x80000135,
+0xcd400042,
+0x96c000fa,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0x9ac00003,
+0xcc00004d,
+0xcc00004e,
+0xdf830000,
+0x80000000,
+0xd80301ff,
+0x9ac000f0,
+0xcc00004d,
+0x80000249,
+0xcc00004e,
+0xc8180003,
+0xc81c0003,
+0xc8200003,
+0x7d5d4003,
+0x7da1c003,
+0x7d5d400c,
+0x2a10001f,
+0x299c001f,
+0x7d1d000b,
+0x7d17400b,
+0x88000000,
+0x7e92800b,
+0x96400004,
+0xcc00004e,
+0x80000249,
+0xcc000042,
+0x04380008,
+0xcf800042,
+0xc8080003,
+0xc80c0003,
+0xc8100003,
+0xc8140003,
+0xc8180003,
+0xc81c0003,
+0xc8240003,
+0xc8280003,
+0x29fc001f,
+0x2ab0001f,
+0x7ff3c00b,
+0x28f0001f,
+0x7ff3c00b,
+0x2970001f,
+0x7ff3c00b,
+0x7d888001,
+0x7dccc001,
+0x7e510001,
+0x7e954001,
+0x7c908002,
+0x7cd4c002,
+0x7cbc800b,
+0x9ac00003,
+0x7c8f400b,
+0x38b40001,
+0x9b4000c1,
+0xcc00004d,
+0x9bc000bf,
+0xcc00004e,
+0xc80c03fd,
+0xc81003fc,
+0xccc00042,
+0x8000016e,
+0xcd000042,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xcc400040,
+0xcc400040,
+0xcc400040,
+0x7c40c000,
+0xccc00040,
+0xccc0000d,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0x7c410000,
+0x65140020,
+0x7d4d402c,
+0x24580002,
+0x7d598020,
+0x7c41c000,
+0xcd800042,
+0x69980020,
+0xcd800042,
+0xcdc00042,
+0xc023c000,
+0x05e40002,
+0x7ca0800b,
+0x26640010,
+0x7ca4800c,
+0xcc800040,
+0xcdc00040,
+0xccc00040,
+0x95c0000e,
+0xcd000040,
+0x09dc0001,
+0xc8280003,
+0x96800008,
+0xce800040,
+0xc834001d,
+0x97400000,
+0xc834001d,
+0x26a80008,
+0x8400024c,
+0xcc2b0000,
+0x99c0fff7,
+0x09dc0001,
+0xdc3a0000,
+0x97800004,
+0x7c418000,
+0x800001a2,
+0x25980002,
+0xa0000000,
+0x7d808000,
+0xc818001d,
+0x7c40c000,
+0x64d00008,
+0x95800000,
+0xc818001d,
+0xcc130000,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xcc400040,
+0xc810001f,
+0x7c40c000,
+0xcc800040,
+0x7cd1400c,
+0xcd400040,
+0x05180001,
+0x80000000,
+0xcd800022,
+0x7c40c000,
+0x64500020,
+0x8400024c,
+0xcc000061,
+0x7cd0c02c,
+0xc8200017,
+0xc8d60000,
+0x99400008,
+0x7c438000,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0xcc000061,
+0xc8200017,
+0x7c40c000,
+0xc036ff00,
+0xc810000d,
+0xc0303fff,
+0x7cf5400b,
+0x7d51800b,
+0x7d81800f,
+0x99800008,
+0x7cf3800b,
+0xdf830000,
+0xcfa0004f,
+0x8400024c,
+0xcc000062,
+0x80000000,
+0xd040007f,
+0x80000249,
+0xcc000062,
+0x8400024c,
+0x7c40c000,
+0x28dc0008,
+0x95c00019,
+0x30dc0010,
+0x7c410000,
+0x99c00004,
+0x64540020,
+0x80000208,
+0xc91d0000,
+0x7d15002c,
+0xc91e0000,
+0x7c420000,
+0x7c424000,
+0x7c418000,
+0x7de5c00b,
+0x7de28007,
+0x9a80000e,
+0x41ac0005,
+0x9ac00000,
+0x0aec0001,
+0x30dc0010,
+0x99c00004,
+0x00000000,
+0x8000020b,
+0xc91d0000,
+0x8000020b,
+0xc91e0000,
+0xcc800040,
+0xccc00040,
+0xd0400040,
+0xc80c0025,
+0x94c0fde4,
+0xc8100008,
+0xcd000040,
+0xd4000fc0,
+0x80000000,
+0xd4000fa2,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0xd40003c0,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xd0400040,
+0x7c408000,
+0xa0000000,
+0x7e82800b,
+0x7c40c000,
+0x30d00006,
+0x0d100006,
+0x99000007,
+0xc8140015,
+0x99400005,
+0xcc000052,
+0xd4000340,
+0xd4000fc0,
+0xd4000fa2,
+0xcc800040,
+0xccc00040,
+0x80000000,
+0xd0400040,
+0x7c40c000,
+0xcc4d0000,
+0xdc3a0000,
+0x9780fdbd,
+0x04cc0001,
+0x80000242,
+0xcc4d0000,
+0x80000000,
+0xd040007f,
+0xcc00007f,
+0x80000000,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00030222,
+0x0004022a,
+0x0005009f,
+0x00020003,
+0x0006003c,
+0x00070027,
+0x00080191,
+0x00090044,
+0x000a002d,
+0x00100247,
+0x001700f0,
+0x002201d7,
+0x002301e8,
+0x0026004c,
+0x0027005f,
+0x0020011a,
+0x00280092,
+0x0029004f,
+0x002a0083,
+0x002b0064,
+0x002f008d,
+0x003200d8,
+0x00340232,
+0x00360074,
+0x0039010a,
+0x003c01fc,
+0x003f009f,
+0x00410005,
+0x00440194,
+0x0048019d,
+0x004901c5,
+0x004a01cf,
+0x00550225,
+0x0056022d,
+0x0060000a,
+0x0061002a,
+0x00620030,
+0x00630030,
+0x00640030,
+0x00650030,
+0x00660030,
+0x00670030,
+0x00680037,
+0x0069003f,
+0x006a0047,
+0x006b0047,
+0x006c0047,
+0x006d0047,
+0x006e0047,
+0x006f0047,
+0x00700047,
+0x00730247,
+0x007b0240,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+0x00000005,
+};
+
+static const u32 RV710_cp_microcode[] = {
+0xcc0003ea,
+0x04080003,
+0xcc800043,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000003,
+0xd040007f,
+0x80000003,
+0xcc400041,
+0x7c40c000,
+0xc0160004,
+0x30d03fff,
+0x7d15000c,
+0xcc110000,
+0x28d8001e,
+0x31980001,
+0x28dc001f,
+0xc8200004,
+0x95c00006,
+0x7c424000,
+0xcc000062,
+0x7e56800c,
+0xcc290000,
+0xc8240004,
+0x7e26000b,
+0x95800006,
+0x7c42c000,
+0xcc000062,
+0x7ed7000c,
+0xcc310000,
+0xc82c0004,
+0x7e2e000c,
+0xcc000062,
+0x31103fff,
+0x80000003,
+0xce110000,
+0x7c40c000,
+0x80000003,
+0xcc400040,
+0x80000003,
+0xcc412257,
+0x7c418000,
+0xcc400045,
+0xcc400048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc400045,
+0xcc400048,
+0x7c40c000,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xcc000045,
+0xcc000048,
+0xcc41225c,
+0xcc41a1fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x040ca1fd,
+0xc0120001,
+0xcc000045,
+0xcc000048,
+0x7cd0c00c,
+0xcc41225c,
+0xcc41a1fc,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x80000003,
+0xcc41225d,
+0x7c408000,
+0x7c40c000,
+0xc02a0002,
+0x7c410000,
+0x7d29000c,
+0x30940001,
+0x30980006,
+0x309c0300,
+0x29dc0008,
+0x7c420000,
+0x7c424000,
+0x9540000f,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0xccc12169,
+0xcd01216a,
+0xce81216b,
+0x0db40002,
+0xcc01216c,
+0x9740000e,
+0x0db40000,
+0x8000007d,
+0xc834000a,
+0x0db40002,
+0x97400009,
+0x0db40000,
+0xc02e0004,
+0x05f02258,
+0x7f2f000c,
+0xcc310000,
+0xc8280004,
+0x8000007d,
+0xc834000a,
+0x97400004,
+0x7e028000,
+0x8000007d,
+0xc834000a,
+0x0db40004,
+0x9740ff8c,
+0x00000000,
+0xce01216d,
+0xce41216e,
+0xc8280003,
+0xc834000a,
+0x9b400004,
+0x043c0005,
+0x8400026d,
+0xcc000062,
+0x0df40000,
+0x9740000b,
+0xc82c03e6,
+0xce81a2b7,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c4,
+0x80000003,
+0xcfc1a2d1,
+0x0df40001,
+0x9740000b,
+0xc82c03e7,
+0xce81a2bb,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c5,
+0x80000003,
+0xcfc1a2d2,
+0x0df40002,
+0x9740000b,
+0xc82c03e8,
+0xce81a2bf,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c6,
+0x80000003,
+0xcfc1a2d3,
+0xc82c03e9,
+0xce81a2c3,
+0xc0300006,
+0x7ef34028,
+0xc0300020,
+0x7f6b8020,
+0x7fb3c029,
+0xcf81a2c7,
+0x80000003,
+0xcfc1a2d4,
+0x80000003,
+0xcc400042,
+0x7c40c000,
+0x7c410000,
+0x2914001d,
+0x31540001,
+0x9940000c,
+0x31181000,
+0xc81c0011,
+0x95c00000,
+0xc81c0011,
+0xccc12100,
+0xcd012101,
+0xccc12102,
+0xcd012103,
+0x04180004,
+0x8000037e,
+0xcd81a2a4,
+0xc02a0004,
+0x95800008,
+0x36a821a3,
+0xcc290000,
+0xc8280004,
+0xc81c0011,
+0x0de40040,
+0x9640ffff,
+0xc81c0011,
+0xccc12170,
+0xcd012171,
+0xc8200012,
+0x96000000,
+0xc8200012,
+0x8000037e,
+0xcc000064,
+0x7c40c000,
+0x7c410000,
+0xcc000045,
+0xcc000048,
+0x40d40003,
+0xcd41225c,
+0xcd01a1fc,
+0xc01a0001,
+0x041ca1fd,
+0x7dd9c00c,
+0x7c420000,
+0x08cc0001,
+0x06240001,
+0x06280002,
+0xce1d0000,
+0xce5d0000,
+0x98c0fffa,
+0xce9d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0x30d00001,
+0x28cc0001,
+0x7c414000,
+0x95000006,
+0x7c418000,
+0xcd41216d,
+0xcd81216e,
+0x800000f4,
+0xc81c0003,
+0xc0220004,
+0x7e16000c,
+0xcc210000,
+0xc81c0004,
+0x7c424000,
+0x98c00004,
+0x7c428000,
+0x80000003,
+0xcde50000,
+0xce412169,
+0xce81216a,
+0xcdc1216b,
+0x80000003,
+0xcc01216c,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x7c41c000,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9680000a,
+0x7c020000,
+0x7c420000,
+0x1e300003,
+0xcc00006a,
+0x9b000003,
+0x42200005,
+0x04200040,
+0x80000111,
+0x7c024000,
+0x7e024000,
+0x9a400000,
+0x0a640001,
+0x30ec0010,
+0x9ac0000a,
+0xcc000062,
+0xc02a0004,
+0xc82c0021,
+0x7e92800c,
+0xcc000041,
+0xcc290000,
+0xcec00021,
+0x80000121,
+0xc8300004,
+0xcd01216d,
+0xcd41216e,
+0xc8300003,
+0x7f1f000b,
+0x30f40007,
+0x27780001,
+0x9740002a,
+0x07b80126,
+0x9f800000,
+0x00000000,
+0x80000136,
+0x7f1b8004,
+0x8000013a,
+0x7f1b8005,
+0x8000013e,
+0x7f1b8002,
+0x80000142,
+0x7f1b8003,
+0x80000146,
+0x7f1b8007,
+0x8000014a,
+0x7f1b8006,
+0x8000014f,
+0x28a40008,
+0x9b800019,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800015,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800011,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b80000d,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800009,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x9b800005,
+0x28a40008,
+0x8000015f,
+0x326400ff,
+0x28a40008,
+0x326400ff,
+0x0e68003c,
+0x9a80feb2,
+0x28ec0008,
+0x7c434000,
+0x7c438000,
+0x7c43c000,
+0x96c00007,
+0xcc000062,
+0xcf412169,
+0xcf81216a,
+0xcfc1216b,
+0x80000003,
+0xcc01216c,
+0x80000003,
+0xcff50000,
+0xcc00006b,
+0x84000381,
+0x0e68003c,
+0x9a800004,
+0xc8280015,
+0x80000003,
+0xd040007f,
+0x9680ffab,
+0x7e024000,
+0x8400023b,
+0xc00e0002,
+0xcc000041,
+0x80000239,
+0xccc1304a,
+0x7c40c000,
+0x7c410000,
+0xc01e0001,
+0x29240012,
+0xc0220002,
+0x96400005,
+0xc0260004,
+0xc027fffb,
+0x7d25000b,
+0xc0260000,
+0x7dd2800b,
+0x7e12c00b,
+0x7d25000c,
+0x7c414000,
+0x7c418000,
+0xccc12169,
+0x9a80000a,
+0xcd01216a,
+0xcd41216b,
+0x96c0fe83,
+0xcd81216c,
+0xc8300018,
+0x97000000,
+0xc8300018,
+0x80000003,
+0xcc000018,
+0x84000381,
+0xcc00007f,
+0xc8140013,
+0xc8180014,
+0xcd41216b,
+0x96c0fe77,
+0xcd81216c,
+0x80000183,
+0xc8300018,
+0xc80c0008,
+0x98c00000,
+0xc80c0008,
+0x7c410000,
+0x95000002,
+0x00000000,
+0x7c414000,
+0xc8200009,
+0xcc400043,
+0xce01a1f4,
+0xcc400044,
+0xc00e8000,
+0x7c424000,
+0x7c428000,
+0x2aac001f,
+0x96c0fe64,
+0xc035f000,
+0xce4003e2,
+0x32780003,
+0x267c0008,
+0x7ff7c00b,
+0x7ffbc00c,
+0x2a780018,
+0xcfc003e3,
+0xcf8003e4,
+0x26b00002,
+0x7f3f0000,
+0xcf0003e5,
+0x8000031f,
+0x7c80c000,
+0x7c40c000,
+0x28d00008,
+0x3110000f,
+0x9500000f,
+0x25280001,
+0x06a801b4,
+0x9e800000,
+0x00000000,
+0x800001d5,
+0xc0120800,
+0x800001e3,
+0xc814000f,
+0x800001ea,
+0xc8140010,
+0x800001f1,
+0xccc1a2a4,
+0x800001fa,
+0xc8140011,
+0x30d0003f,
+0x0d280015,
+0x9a800012,
+0x0d28001e,
+0x9a80001e,
+0x0d280020,
+0x9a800023,
+0x0d24000f,
+0x0d280010,
+0x7e6a800c,
+0x9a800026,
+0x0d200004,
+0x0d240014,
+0x0d280028,
+0x7e62400c,
+0x7ea6800c,
+0x9a80002a,
+0xc8140011,
+0x80000003,
+0xccc1a2a4,
+0xc0120800,
+0x7c414000,
+0x7d0cc00c,
+0xc0120008,
+0x29580003,
+0x295c000c,
+0x7c420000,
+0x7dd1c00b,
+0x26200014,
+0x7e1e400c,
+0x7e4e800c,
+0xce81a2a4,
+0x80000003,
+0xcd81a1fe,
+0xc814000f,
+0x0410210e,
+0x95400000,
+0xc814000f,
+0xd0510000,
+0x80000003,
+0xccc1a2a4,
+0xc8140010,
+0x04102108,
+0x95400000,
+0xc8140010,
+0xd0510000,
+0x80000003,
+0xccc1a2a4,
+0xccc1a2a4,
+0x04100001,
+0xcd000019,
+0x84000381,
+0xcc00007f,
+0xc8100019,
+0x99000000,
+0xc8100019,
+0x80000004,
+0x7c408000,
+0x04102100,
+0x95400000,
+0xc8140011,
+0xd0510000,
+0x8000037e,
+0xccc1a2a4,
+0x7c40c000,
+0xcc40000d,
+0x94c0fe01,
+0xcc40000e,
+0x7c410000,
+0x95000005,
+0x08cc0001,
+0xc8140005,
+0x99400014,
+0x00000000,
+0x98c0fffb,
+0x7c410000,
+0x80000004,
+0x7d008000,
+0xc8140005,
+0x7c40c000,
+0x9940000c,
+0xc818000c,
+0x7c410000,
+0x9580fdf0,
+0xc820000e,
+0xc81c000d,
+0x66200020,
+0x7e1e002c,
+0x25240002,
+0x7e624020,
+0x80000003,
+0xcce60000,
+0x7c410000,
+0xcc00006c,
+0xcc00006d,
+0xc818001f,
+0xc81c001e,
+0x65980020,
+0x7dd9c02c,
+0x7cd4c00c,
+0xccde0000,
+0x45dc0004,
+0xc8280017,
+0x9680000f,
+0xc00e0001,
+0x28680008,
+0x2aac0016,
+0x32a800ff,
+0x0eb00049,
+0x7f2f000b,
+0x97000006,
+0x00000000,
+0xc8140005,
+0x7c40c000,
+0x80000223,
+0x7c410000,
+0x80000226,
+0xd040007f,
+0x8400023b,
+0xcc000041,
+0xccc1304a,
+0x94000000,
+0xc83c001a,
+0x043c0005,
+0xcfc1a2a4,
+0xc0361f90,
+0xc0387fff,
+0x7c03c010,
+0x7f7b400c,
+0xcf41217c,
+0xcfc1217d,
+0xcc01217e,
+0xc03a0004,
+0x0434217f,
+0x7f7b400c,
+0xcc350000,
+0xc83c0004,
+0x2bfc001f,
+0x04380020,
+0x97c00005,
+0xcc000062,
+0x9b800000,
+0x0bb80001,
+0x80000247,
+0xcc000071,
+0xcc01a1f4,
+0x04380016,
+0xc0360002,
+0xcf81a2a4,
+0x88000000,
+0xcf412010,
+0x7c40c000,
+0x28d0001c,
+0x95000005,
+0x04d40001,
+0xcd400065,
+0x80000003,
+0xcd400068,
+0x09540002,
+0x80000003,
+0xcd400066,
+0x8400026c,
+0xc81803ea,
+0x7c40c000,
+0x9980fd9f,
+0xc8140016,
+0x08d00001,
+0x9940002b,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0005,
+0xcfc1a2a4,
+0xcc01a1f4,
+0x84000381,
+0xcc000046,
+0x88000000,
+0xcc00007f,
+0x8400027e,
+0xc81803ea,
+0x7c40c000,
+0x9980fd8d,
+0xc8140016,
+0x08d00001,
+0x99400019,
+0xcd000068,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x043c0022,
+0xcfc1a2a4,
+0x84000381,
+0xcc000047,
+0x88000000,
+0xcc00007f,
+0xc8100016,
+0x9900000d,
+0xcc400067,
+0x80000004,
+0x7c408000,
+0xc81803ea,
+0x9980fd79,
+0x7c40c000,
+0x94c00003,
+0xc8100016,
+0x99000004,
+0xccc00068,
+0x80000004,
+0x7c408000,
+0x8400023b,
+0xc0148000,
+0xcc000041,
+0xcd41304a,
+0xc0148000,
+0x99000000,
+0xc8100016,
+0x80000004,
+0x7c408000,
+0xc0120001,
+0x7c51400c,
+0x80000003,
+0xd0550000,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0x291c001f,
+0xccc0004a,
+0xcd00004b,
+0x95c00003,
+0xc01c8000,
+0xcdc12010,
+0xdd830000,
+0x055c2000,
+0xcc000062,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004c,
+0xcd00004d,
+0xdd830000,
+0x055ca000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc0004e,
+0xcd00004f,
+0xdd830000,
+0x055cc000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00050,
+0xcd000051,
+0xdd830000,
+0x055cf8e0,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00052,
+0xcd000053,
+0xdd830000,
+0x055cf880,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00054,
+0xcd000055,
+0xdd830000,
+0x055ce000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00056,
+0xcd000057,
+0xdd830000,
+0x055cf000,
+0x80000003,
+0xd81f4100,
+0x7c40c000,
+0x7c410000,
+0x7c414000,
+0x7c418000,
+0xccc00058,
+0xcd000059,
+0xdd830000,
+0x055cf3fc,
+0x80000003,
+0xd81f4100,
+0xd0432000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043a000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043c000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f8e0,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f880,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043e000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xd043f3fc,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc81403e0,
+0xcc430000,
+0xcc430000,
+0xcc430000,
+0x7d45c000,
+0xcdc30000,
+0xd0430000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0x7c40c000,
+0xc81003e2,
+0xc81403e5,
+0xc81803e3,
+0xc81c03e4,
+0xcd812169,
+0xcdc1216a,
+0xccc1216b,
+0xcc01216c,
+0x04200004,
+0x7da18000,
+0x7d964002,
+0x9640fcd9,
+0xcd8003e3,
+0x31280003,
+0xc02df000,
+0x25180008,
+0x7dad800b,
+0x7da9800c,
+0x80000003,
+0xcd8003e3,
+0x308cffff,
+0xd04d0000,
+0x7c408000,
+0xa0000000,
+0xcc800062,
+0xc8140020,
+0x15580002,
+0x9580ffff,
+0xc8140020,
+0xcc00006e,
+0xcc412180,
+0x7c40c000,
+0xccc1218d,
+0xcc412181,
+0x28d0001f,
+0x34588000,
+0xcd81218c,
+0x9500fcbf,
+0xcc412182,
+0xc8140020,
+0x9940ffff,
+0xc8140020,
+0x80000004,
+0x7c408000,
+0x7c40c000,
+0x28d00018,
+0x31100001,
+0xc0160080,
+0x95000003,
+0xc02a0004,
+0x7cd4c00c,
+0xccc1217c,
+0xcc41217d,
+0xcc41217e,
+0x7c418000,
+0x1db00003,
+0x36a0217f,
+0x9b000003,
+0x419c0005,
+0x041c0040,
+0x99c00000,
+0x09dc0001,
+0xcc210000,
+0xc8240004,
+0x2a6c001f,
+0x419c0005,
+0x9ac0fffa,
+0xcc800062,
+0x80000004,
+0x7c408000,
+0x7c40c000,
+0x04d403e6,
+0x80000003,
+0xcc540000,
+0x8000037e,
+0xcc4003ea,
+0xc01c8000,
+0x044ca000,
+0xcdc12010,
+0x7c410000,
+0xc8140009,
+0x04180000,
+0x041c0008,
+0xcd800071,
+0x09dc0001,
+0x05980001,
+0xcd0d0000,
+0x99c0fffc,
+0xcc800062,
+0x8000037e,
+0xcd400071,
+0xc00e0100,
+0xcc000041,
+0xccc1304a,
+0xc83c007f,
+0xcc00007f,
+0x80000003,
+0xcc00007f,
+0xcc00007f,
+0x88000000,
+0xcc00007f,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00000000,
+0x00010333,
+0x00100006,
+0x00170008,
+0x0021000a,
+0x0027002a,
+0x00280025,
+0x0029002b,
+0x002a0028,
+0x002b002b,
+0x002d003a,
+0x002e0041,
+0x002f004c,
+0x0034004e,
+0x00360032,
+0x003900b1,
+0x003a00d1,
+0x003b00e6,
+0x003c00fe,
+0x003d016d,
+0x003f00af,
+0x00410338,
+0x0043034b,
+0x00440190,
+0x004500fe,
+0x004601ae,
+0x004701ae,
+0x00480200,
+0x0049020e,
+0x004a0257,
+0x004b0284,
+0x00520261,
+0x00530273,
+0x00540289,
+0x0057029b,
+0x0060029f,
+0x006102ae,
+0x006202b8,
+0x006302c2,
+0x006402cc,
+0x006502d6,
+0x006602e0,
+0x006702ea,
+0x006802f4,
+0x006902f8,
+0x006a02fc,
+0x006b0300,
+0x006c0304,
+0x006d0308,
+0x006e030c,
+0x006f0310,
+0x00700314,
+0x00720365,
+0x0074036b,
+0x00790369,
+0x007c031e,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+0x000f037a,
+};
+
+#endif
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c
index 92965dbb3c1..77a7a4d8465 100644
--- a/drivers/gpu/drm/radeon/radeon_cp.c
+++ b/drivers/gpu/drm/radeon/radeon_cp.c
@@ -43,6 +43,78 @@
static int radeon_do_cleanup_cp(struct drm_device * dev);
static void radeon_do_cp_start(drm_radeon_private_t * dev_priv);
+u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off)
+{
+ u32 val;
+
+ if (dev_priv->flags & RADEON_IS_AGP) {
+ val = DRM_READ32(dev_priv->ring_rptr, off);
+ } else {
+ val = *(((volatile u32 *)
+ dev_priv->ring_rptr->handle) +
+ (off / sizeof(u32)));
+ val = le32_to_cpu(val);
+ }
+ return val;
+}
+
+u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv)
+{
+ if (dev_priv->writeback_works)
+ return radeon_read_ring_rptr(dev_priv, 0);
+ else {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return RADEON_READ(R600_CP_RB_RPTR);
+ else
+ return RADEON_READ(RADEON_CP_RB_RPTR);
+ }
+}
+
+void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val)
+{
+ if (dev_priv->flags & RADEON_IS_AGP)
+ DRM_WRITE32(dev_priv->ring_rptr, off, val);
+ else
+ *(((volatile u32 *) dev_priv->ring_rptr->handle) +
+ (off / sizeof(u32))) = cpu_to_le32(val);
+}
+
+void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val)
+{
+ radeon_write_ring_rptr(dev_priv, 0, val);
+}
+
+u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index)
+{
+ if (dev_priv->writeback_works) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return radeon_read_ring_rptr(dev_priv,
+ R600_SCRATCHOFF(index));
+ else
+ return radeon_read_ring_rptr(dev_priv,
+ RADEON_SCRATCHOFF(index));
+ } else {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return RADEON_READ(R600_SCRATCH_REG0 + 4*index);
+ else
+ return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index);
+ }
+}
+
+u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+
+ if (addr < 0x10000)
+ ret = DRM_READ32(dev_priv->mmio, addr);
+ else {
+ DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr);
+ ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA);
+ }
+
+ return ret;
+}
+
static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
u32 ret;
@@ -70,11 +142,22 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
return ret;
}
+static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) |
+ RS600_MC_IND_CITF_ARB0));
+ ret = RADEON_READ(RS600_MC_DATA);
+ return ret;
+}
+
static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
return RS690_READ_MCIND(dev_priv, addr);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ return RS600_READ_MCIND(dev_priv, addr);
else
return RS480_READ_MCIND(dev_priv, addr);
}
@@ -82,11 +165,17 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
{
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ return RADEON_READ(R700_MC_VM_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return RADEON_READ(R600_MC_VM_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
else
@@ -95,42 +184,66 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
else
RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
}
-static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
+void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
{
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) {
+ RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
+ RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */
+ RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff);
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740))
RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc);
else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
else
RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
}
-static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
+void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
{
u32 agp_base_hi = upper_32_bits(agp_base);
u32 agp_base_lo = agp_base & 0xffffffff;
-
- if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
+ u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff;
+
+ /* R6xx/R7xx must be aligned to a 4MB boundry */
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770)
+ RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+ RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo);
+ RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi);
} else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
@@ -145,6 +258,25 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
}
}
+void radeon_enable_bm(struct drm_radeon_private *dev_priv)
+{
+ u32 tmp;
+ /* Turn on bus mastering */
+ if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
+ /* rs600/rs690/rs740 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
+ ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
+ /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
+ tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
+ RADEON_WRITE(RADEON_BUS_CNTL, tmp);
+ } /* PCIE cards appears to not need this */
+}
+
static int RADEON_READ_PLL(struct drm_device * dev, int addr)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -302,7 +434,7 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv)
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4));
- RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
+ RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1));
}
RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config);
radeon_do_wait_for_idle(dev_priv);
@@ -382,6 +514,14 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
RS690_cp_microcode[i][0]);
}
+ } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+ DRM_INFO("Loading RS600 Microcode\n");
+ for (i = 0; i < 256; i++) {
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
+ RS600_cp_microcode[i][1]);
+ RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
+ RS600_cp_microcode[i][0]);
+ }
} else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) ||
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) ||
@@ -562,7 +702,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
{
struct drm_radeon_master_private *master_priv;
u32 ring_start, cur_read_ptr;
- u32 tmp;
/* Initialize the memory controller. With new memory map, the fb location
* is not changed, it should have been properly initialized already. Part
@@ -611,17 +750,10 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
} else
#endif
{
- struct drm_sg_mem *entry = dev->sg;
- unsigned long tmp_ofs, page_ofs;
-
- tmp_ofs = dev_priv->ring_rptr->offset -
- (unsigned long)dev->sg->virtual;
- page_ofs = tmp_ofs >> PAGE_SHIFT;
-
- RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
- DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
- (unsigned long)entry->busaddr[page_ofs],
- entry->handle + tmp_ofs);
+ RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
+ dev_priv->ring_rptr->offset
+ - ((unsigned long) dev->sg->virtual)
+ + dev_priv->gart_vm_start);
}
/* Set ring buffer size */
@@ -649,34 +781,17 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev,
RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
+ RADEON_SCRATCH_REG_OFFSET);
- dev_priv->scratch = ((__volatile__ u32 *)
- dev_priv->ring_rptr->handle +
- (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
-
RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
- /* Turn on bus mastering */
- if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) {
- /* rs600/rs690/rs740 */
- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS;
- RADEON_WRITE(RADEON_BUS_CNTL, tmp);
- } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) ||
- ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) {
- /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */
- tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
- RADEON_WRITE(RADEON_BUS_CNTL, tmp);
- } /* PCIE cards appears to not need this */
+ radeon_enable_bm(dev_priv);
- dev_priv->scratch[0] = 0;
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0);
RADEON_WRITE(RADEON_LAST_FRAME_REG, 0);
- dev_priv->scratch[1] = 0;
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0);
RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0);
- dev_priv->scratch[2] = 0;
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0);
RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0);
/* reset sarea copies of these */
@@ -708,12 +823,15 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
/* Writeback doesn't seem to work everywhere, test it here and possibly
* enable it if it appears to work
*/
- DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
+ radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0);
+
RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
- if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
- 0xdeadbeef)
+ u32 val;
+
+ val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
+ if (val == 0xdeadbeef)
break;
DRM_UDELAY(1);
}
@@ -809,6 +927,82 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
}
}
+/* Enable or disable IGP GART on the chip */
+static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on)
+{
+ u32 temp;
+ int i;
+
+ if (on) {
+ DRM_DEBUG("programming igp gart %08X %08lX %08X\n",
+ dev_priv->gart_vm_start,
+ (long)dev_priv->gart_info.bus_addr,
+ dev_priv->gart_size);
+
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) |
+ RS600_EFFECTIVE_L2_QUEUE_SIZE(6)));
+
+ for (i = 0; i < 19; i++)
+ IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i,
+ (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE |
+ RS600_SYSTEM_ACCESS_MODE_IN_SYS |
+ RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH |
+ RS600_EFFECTIVE_L1_CACHE_SIZE(3) |
+ RS600_ENABLE_FRAGMENT_PROCESSING |
+ RS600_EFFECTIVE_L1_QUEUE_SIZE(3)));
+
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE |
+ RS600_PAGE_TABLE_TYPE_FLAT));
+
+ /* disable all other contexts */
+ for (i = 1; i < 8; i++)
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0);
+
+ /* setup the page table aperture */
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR,
+ dev_priv->gart_info.bus_addr);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR,
+ dev_priv->gart_vm_start);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR,
+ (dev_priv->gart_vm_start + dev_priv->gart_size - 1));
+ IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0);
+
+ /* setup the system aperture */
+ IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR,
+ dev_priv->gart_vm_start);
+ IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR,
+ (dev_priv->gart_vm_start + dev_priv->gart_size - 1));
+
+ /* enable page tables */
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT));
+
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
+ IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES));
+
+ /* invalidate the cache */
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE;
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE);
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL);
+
+ } else {
+ IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0);
+ temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1);
+ temp &= ~RS600_ENABLE_PAGE_TABLES;
+ IGP_WRITE_MCIND(RS600_MC_CNTL1, temp);
+ }
+}
+
static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
{
u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
@@ -850,6 +1044,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
return;
}
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) {
+ rs600_set_igpgart(dev_priv, on);
+ return;
+ }
+
if (dev_priv->flags & RADEON_IS_PCIE) {
radeon_set_pciegart(dev_priv, on);
return;
@@ -881,6 +1080,46 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
}
}
+static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv)
+{
+ struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info;
+ struct radeon_virt_surface *vp;
+ int i;
+
+ for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) {
+ if (!dev_priv->virt_surfaces[i].file_priv ||
+ dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV)
+ break;
+ }
+ if (i >= 2 * RADEON_MAX_SURFACES)
+ return -ENOMEM;
+ vp = &dev_priv->virt_surfaces[i];
+
+ for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+ struct radeon_surface *sp = &dev_priv->surfaces[i];
+ if (sp->refcount)
+ continue;
+
+ vp->surface_index = i;
+ vp->lower = gart_info->bus_addr;
+ vp->upper = vp->lower + gart_info->table_size;
+ vp->flags = 0;
+ vp->file_priv = PCIGART_FILE_PRIV;
+
+ sp->refcount = 1;
+ sp->lower = vp->lower;
+ sp->upper = vp->upper;
+ sp->flags = 0;
+
+ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags);
+ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower);
+ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper);
+ return 0;
+ }
+
+ return -ENOMEM;
+}
+
static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
struct drm_file *file_priv)
{
@@ -1062,11 +1301,12 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
} else
#endif
{
- dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
+ dev_priv->cp_ring->handle =
+ (void *)(unsigned long)dev_priv->cp_ring->offset;
dev_priv->ring_rptr->handle =
- (void *)dev_priv->ring_rptr->offset;
+ (void *)(unsigned long)dev_priv->ring_rptr->offset;
dev->agp_buffer_map->handle =
- (void *)dev->agp_buffer_map->offset;
+ (void *)(unsigned long)dev->agp_buffer_map->offset;
DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
dev_priv->cp_ring->handle);
@@ -1173,11 +1413,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
} else
#endif
{
+ u32 sctrl;
+ int ret;
+
dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
/* if we have an offset set from userspace */
if (dev_priv->pcigart_offset_set) {
dev_priv->gart_info.bus_addr =
- dev_priv->pcigart_offset + dev_priv->fb_location;
+ (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location;
dev_priv->gart_info.mapping.offset =
dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
dev_priv->gart_info.mapping.size =
@@ -1214,12 +1457,31 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
}
}
- if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
+ sctrl = RADEON_READ(RADEON_SURFACE_CNTL);
+ RADEON_WRITE(RADEON_SURFACE_CNTL, 0);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ ret = r600_page_table_init(dev);
+ else
+ ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info);
+ RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl);
+
+ if (!ret) {
DRM_ERROR("failed to init PCI GART!\n");
radeon_do_cleanup_cp(dev);
return -ENOMEM;
}
+ ret = radeon_setup_pcigart_surface(dev_priv);
+ if (ret) {
+ DRM_ERROR("failed to setup GART surface!\n");
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ r600_page_table_cleanup(dev, &dev_priv->gart_info);
+ else
+ drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info);
+ radeon_do_cleanup_cp(dev);
+ return ret;
+ }
+
/* Turn on PCI GART */
radeon_set_pcigart(dev_priv, 1);
}
@@ -1268,14 +1530,18 @@ static int radeon_do_cleanup_cp(struct drm_device * dev)
if (dev_priv->gart_info.bus_addr) {
/* Turn off PCI GART */
radeon_set_pcigart(dev_priv, 0);
- if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
- DRM_ERROR("failed to cleanup PCI GART!\n");
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600)
+ r600_page_table_cleanup(dev, &dev_priv->gart_info);
+ else {
+ if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
+ DRM_ERROR("failed to cleanup PCI GART!\n");
+ }
}
if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
{
drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
- dev_priv->gart_info.addr = 0;
+ dev_priv->gart_info.addr = NULL;
}
}
/* only clear to the start of flags */
@@ -1326,6 +1592,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri
int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
drm_radeon_init_t *init = data;
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1338,8 +1605,13 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri
case RADEON_INIT_R200_CP:
case RADEON_INIT_R300_CP:
return radeon_do_init_cp(dev, init, file_priv);
+ case RADEON_INIT_R600_CP:
+ return r600_do_init_cp(dev, init, file_priv);
case RADEON_CLEANUP_CP:
- return radeon_do_cleanup_cp(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_cleanup_cp(dev);
+ else
+ return radeon_do_cleanup_cp(dev);
}
return -EINVAL;
@@ -1362,7 +1634,10 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr
return 0;
}
- radeon_do_cp_start(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cp_start(dev_priv);
+ else
+ radeon_do_cp_start(dev_priv);
return 0;
}
@@ -1393,7 +1668,10 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri
* code so that the DRM ioctl wrapper can try again.
*/
if (stop->idle) {
- ret = radeon_do_cp_idle(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ ret = r600_do_cp_idle(dev_priv);
+ else
+ ret = radeon_do_cp_idle(dev_priv);
if (ret)
return ret;
}
@@ -1402,10 +1680,16 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri
* we will get some dropped triangles as they won't be fully
* rendered before the CP is shut down.
*/
- radeon_do_cp_stop(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cp_stop(dev_priv);
+ else
+ radeon_do_cp_stop(dev_priv);
/* Reset the engine */
- radeon_do_engine_reset(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_engine_reset(dev);
+ else
+ radeon_do_engine_reset(dev);
return 0;
}
@@ -1418,29 +1702,47 @@ void radeon_do_release(struct drm_device * dev)
if (dev_priv) {
if (dev_priv->cp_running) {
/* Stop the cp */
- while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
- DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ while ((ret = r600_do_cp_idle(dev_priv)) != 0) {
+ DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
+#ifdef __linux__
+ schedule();
+#else
+ tsleep(&ret, PZERO, "rdnrel", 1);
+#endif
+ }
+ } else {
+ while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
+ DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
#ifdef __linux__
- schedule();
+ schedule();
#else
- tsleep(&ret, PZERO, "rdnrel", 1);
+ tsleep(&ret, PZERO, "rdnrel", 1);
#endif
+ }
+ }
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ r600_do_cp_stop(dev_priv);
+ r600_do_engine_reset(dev);
+ } else {
+ radeon_do_cp_stop(dev_priv);
+ radeon_do_engine_reset(dev);
}
- radeon_do_cp_stop(dev_priv);
- radeon_do_engine_reset(dev);
}
- /* Disable *all* interrupts */
- if (dev_priv->mmio) /* remove this after permanent addmaps */
- RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
-
- if (dev_priv->mmio) { /* remove all surfaces */
- for (i = 0; i < RADEON_MAX_SURFACES; i++) {
- RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
- RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
- 16 * i, 0);
- RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
- 16 * i, 0);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) {
+ /* Disable *all* interrupts */
+ if (dev_priv->mmio) /* remove this after permanent addmaps */
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
+
+ if (dev_priv->mmio) { /* remove all surfaces */
+ for (i = 0; i < RADEON_MAX_SURFACES; i++) {
+ RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
+ RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
+ 16 * i, 0);
+ RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
+ 16 * i, 0);
+ }
}
}
@@ -1449,7 +1751,10 @@ void radeon_do_release(struct drm_device * dev)
radeon_mem_takedown(&(dev_priv->fb_heap));
/* deallocate kernel resources */
- radeon_do_cleanup_cp(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cleanup_cp(dev);
+ else
+ radeon_do_cleanup_cp(dev);
}
}
@@ -1467,7 +1772,10 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr
return -EINVAL;
}
- radeon_do_cp_reset(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_do_cp_reset(dev_priv);
+ else
+ radeon_do_cp_reset(dev_priv);
/* The CP is no longer running after an engine reset */
dev_priv->cp_running = 0;
@@ -1482,23 +1790,36 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
- return radeon_do_cp_idle(dev_priv);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_cp_idle(dev_priv);
+ else
+ return radeon_do_cp_idle(dev_priv);
}
/* Added by Charl P. Botha to call radeon_do_resume_cp().
*/
int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
- return radeon_do_resume_cp(dev, file_priv);
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ DRM_DEBUG("\n");
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_resume_cp(dev, file_priv);
+ else
+ return radeon_do_resume_cp(dev, file_priv);
}
int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
- return radeon_do_engine_reset(dev);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return r600_do_engine_reset(dev);
+ else
+ return radeon_do_engine_reset(dev);
}
/* ================================================================
@@ -1548,7 +1869,7 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
start = dev_priv->last_buf;
for (t = 0; t < dev_priv->usec_timeout; t++) {
- u32 done_age = GET_SCRATCH(1);
+ u32 done_age = GET_SCRATCH(dev_priv, 1);
DRM_DEBUG("done_age = %d\n", done_age);
for (i = start; i < dma->buf_count; i++) {
buf = dma->buflist[i];
@@ -1582,8 +1903,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev)
struct drm_buf *buf;
int i, t;
int start;
- u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
+ u32 done_age;
+ done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1));
if (++dev_priv->last_buf >= dma->buf_count)
dev_priv->last_buf = 0;
@@ -1854,3 +2176,41 @@ int radeon_driver_unload(struct drm_device *dev)
dev->dev_private = NULL;
return 0;
}
+
+void radeon_commit_ring(drm_radeon_private_t *dev_priv)
+{
+ int i;
+ u32 *ring;
+ int tail_aligned;
+
+ /* check if the ring is padded out to 16-dword alignment */
+
+ tail_aligned = dev_priv->ring.tail & 0xf;
+ if (tail_aligned) {
+ int num_p2 = 16 - tail_aligned;
+
+ ring = dev_priv->ring.start;
+ /* pad with some CP_PACKET2 */
+ for (i = 0; i < num_p2; i++)
+ ring[dev_priv->ring.tail + i] = CP_PACKET2();
+
+ dev_priv->ring.tail += i;
+
+ dev_priv->ring.space -= num_p2 * sizeof(u32);
+ }
+
+ dev_priv->ring.tail &= dev_priv->ring.tail_mask;
+
+ DRM_MEMORYBARRIER();
+ GET_RING_HEAD( dev_priv );
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail);
+ /* read from PCI bus to ensure correct posting */
+ RADEON_READ(R600_CP_RB_RPTR);
+ } else {
+ RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail);
+ /* read from PCI bus to ensure correct posting */
+ RADEON_READ(RADEON_CP_RB_RPTR);
+ }
+}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index fef207881f4..13a60f4d422 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -41,23 +41,15 @@ int radeon_no_wb;
MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers");
module_param_named(no_wb, radeon_no_wb, int, 0444);
-static int dri_library_name(struct drm_device *dev, char *buf)
-{
- drm_radeon_private_t *dev_priv = dev->dev_private;
- int family = dev_priv->flags & RADEON_FAMILY_MASK;
-
- return snprintf(buf, PAGE_SIZE, "%s\n",
- (family < CHIP_R200) ? "radeon" :
- ((family < CHIP_R300) ? "r200" :
- "r300"));
-}
-
static int radeon_suspend(struct drm_device *dev, pm_message_t state)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return 0;
+
/* Disable *all* interrupts */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
return 0;
@@ -67,8 +59,11 @@ static int radeon_resume(struct drm_device *dev)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ return 0;
+
/* Restore interrupt registers */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
return 0;
@@ -95,7 +90,6 @@ static struct drm_driver driver = {
.get_vblank_counter = radeon_get_vblank_counter,
.enable_vblank = radeon_enable_vblank,
.disable_vblank = radeon_disable_vblank,
- .dri_library_name = dri_library_name,
.master_create = radeon_master_create,
.master_destroy = radeon_master_destroy,
.irq_preinstall = radeon_driver_irq_preinstall,
diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h
index 490bc7ceef6..ed4d27e6ee6 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.h
+++ b/drivers/gpu/drm/radeon/radeon_drv.h
@@ -126,6 +126,7 @@ enum radeon_family {
CHIP_RV410,
CHIP_RS400,
CHIP_RS480,
+ CHIP_RS600,
CHIP_RS690,
CHIP_RS740,
CHIP_RV515,
@@ -134,6 +135,16 @@ enum radeon_family {
CHIP_RV560,
CHIP_RV570,
CHIP_R580,
+ CHIP_R600,
+ CHIP_RV610,
+ CHIP_RV630,
+ CHIP_RV620,
+ CHIP_RV635,
+ CHIP_RV670,
+ CHIP_RS780,
+ CHIP_RV770,
+ CHIP_RV730,
+ CHIP_RV710,
CHIP_LAST,
};
@@ -160,10 +171,6 @@ enum radeon_chip_flags {
RADEON_IS_IGPGART = 0x01000000UL,
};
-#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
- DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
-#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
-
typedef struct drm_radeon_freelist {
unsigned int age;
struct drm_buf *buf;
@@ -221,10 +228,11 @@ struct radeon_virt_surface {
u32 upper;
u32 flags;
struct drm_file *file_priv;
+#define PCIGART_FILE_PRIV ((void *) -1L)
};
-#define RADEON_FLUSH_EMITED (1 < 0)
-#define RADEON_PURGE_EMITED (1 < 1)
+#define RADEON_FLUSH_EMITED (1 << 0)
+#define RADEON_PURGE_EMITED (1 << 1)
struct drm_radeon_master_private {
drm_local_map_t *sarea;
@@ -248,7 +256,6 @@ typedef struct drm_radeon_private {
drm_radeon_freelist_t *head;
drm_radeon_freelist_t *tail;
int last_buf;
- volatile u32 *scratch;
int writeback_works;
int usec_timeout;
@@ -316,11 +323,31 @@ typedef struct drm_radeon_private {
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
- unsigned long fb_aper_offset;
+ resource_size_t fb_aper_offset;
int num_gb_pipes;
int track_flush;
drm_local_map_t *mmio;
+
+ /* r6xx/r7xx pipe/shader config */
+ int r600_max_pipes;
+ int r600_max_tile_pipes;
+ int r600_max_simds;
+ int r600_max_backends;
+ int r600_max_gprs;
+ int r600_max_threads;
+ int r600_max_stack_entries;
+ int r600_max_hw_contexts;
+ int r600_max_gs_threads;
+ int r600_sx_max_export_size;
+ int r600_sx_max_export_pos_size;
+ int r600_sx_max_export_smx_size;
+ int r600_sq_num_cf_insts;
+ int r700_sx_num_of_sets;
+ int r700_sc_prim_fifo_size;
+ int r700_sc_hiz_tile_fifo_size;
+ int r700_sc_earlyz_tile_fifo_fize;
+
} drm_radeon_private_t;
typedef struct drm_radeon_buf_priv {
@@ -338,6 +365,12 @@ extern int radeon_no_wb;
extern struct drm_ioctl_desc radeon_ioctls[];
extern int radeon_max_ioctl;
+extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv);
+extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val);
+
+#define GET_RING_HEAD(dev_priv) radeon_get_ring_head(dev_priv)
+#define SET_RING_HEAD(dev_priv, val) radeon_set_ring_head(dev_priv, val)
+
/* Check whether the given hardware address is inside the framebuffer or the
* GART area.
*/
@@ -364,6 +397,9 @@ extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_fi
extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
+extern void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc);
+extern void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base);
+extern u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr);
extern void radeon_freelist_reset(struct drm_device * dev);
extern struct drm_buf *radeon_freelist_get(struct drm_device * dev);
@@ -383,6 +419,10 @@ extern void radeon_mem_takedown(struct mem_block **heap);
extern void radeon_mem_release(struct drm_file *file_priv,
struct mem_block *heap);
+extern void radeon_enable_bm(struct drm_radeon_private *dev_priv);
+extern u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off);
+extern void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val);
+
/* radeon_irq.c */
extern void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state);
extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
@@ -423,6 +463,21 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
struct drm_file *file_priv,
drm_radeon_kcmd_buffer_t *cmdbuf);
+/* r600_cp.c */
+extern int r600_do_engine_reset(struct drm_device *dev);
+extern int r600_do_cleanup_cp(struct drm_device *dev);
+extern int r600_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init,
+ struct drm_file *file_priv);
+extern int r600_do_resume_cp(struct drm_device *dev, struct drm_file *file_priv);
+extern int r600_do_cp_idle(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_start(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_reset(drm_radeon_private_t *dev_priv);
+extern void r600_do_cp_stop(drm_radeon_private_t *dev_priv);
+extern int r600_cp_dispatch_indirect(struct drm_device *dev,
+ struct drm_buf *buf, int start, int end);
+extern int r600_page_table_init(struct drm_device *dev);
+extern void r600_page_table_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info);
+
/* Flags for stats.boxes
*/
#define RADEON_BOX_DMA_IDLE 0x1
@@ -434,6 +489,8 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
/* Register definitions, register access macros and drmAddMap constants
* for Radeon kernel driver.
*/
+#define RADEON_MM_INDEX 0x0000
+#define RADEON_MM_DATA 0x0004
#define RADEON_AGP_COMMAND 0x0f60
#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
@@ -556,6 +613,56 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RS690_MC_AGP_BASE 0x102
#define RS690_MC_AGP_BASE_2 0x103
+#define RS600_MC_INDEX 0x70
+# define RS600_MC_ADDR_MASK 0xffff
+# define RS600_MC_IND_SEQ_RBS_0 (1 << 16)
+# define RS600_MC_IND_SEQ_RBS_1 (1 << 17)
+# define RS600_MC_IND_SEQ_RBS_2 (1 << 18)
+# define RS600_MC_IND_SEQ_RBS_3 (1 << 19)
+# define RS600_MC_IND_AIC_RBS (1 << 20)
+# define RS600_MC_IND_CITF_ARB0 (1 << 21)
+# define RS600_MC_IND_CITF_ARB1 (1 << 22)
+# define RS600_MC_IND_WR_EN (1 << 23)
+#define RS600_MC_DATA 0x74
+
+#define RS600_MC_STATUS 0x0
+# define RS600_MC_IDLE (1 << 1)
+#define RS600_MC_FB_LOCATION 0x4
+#define RS600_MC_AGP_LOCATION 0x5
+#define RS600_AGP_BASE 0x6
+#define RS600_AGP_BASE_2 0x7
+#define RS600_MC_CNTL1 0x9
+# define RS600_ENABLE_PAGE_TABLES (1 << 26)
+#define RS600_MC_PT0_CNTL 0x100
+# define RS600_ENABLE_PT (1 << 0)
+# define RS600_EFFECTIVE_L2_CACHE_SIZE(x) ((x) << 15)
+# define RS600_EFFECTIVE_L2_QUEUE_SIZE(x) ((x) << 21)
+# define RS600_INVALIDATE_ALL_L1_TLBS (1 << 28)
+# define RS600_INVALIDATE_L2_CACHE (1 << 29)
+#define RS600_MC_PT0_CONTEXT0_CNTL 0x102
+# define RS600_ENABLE_PAGE_TABLE (1 << 0)
+# define RS600_PAGE_TABLE_TYPE_FLAT (0 << 1)
+#define RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR 0x112
+#define RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR 0x114
+#define RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR 0x11c
+#define RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR 0x12c
+#define RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR 0x13c
+#define RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR 0x14c
+#define RS600_MC_PT0_CLIENT0_CNTL 0x16c
+# define RS600_ENABLE_TRANSLATION_MODE_OVERRIDE (1 << 0)
+# define RS600_TRANSLATION_MODE_OVERRIDE (1 << 1)
+# define RS600_SYSTEM_ACCESS_MODE_MASK (3 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_IN_SYS (2 << 8)
+# define RS600_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 8)
+# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH (0 << 10)
+# define RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 10)
+# define RS600_EFFECTIVE_L1_CACHE_SIZE(x) ((x) << 11)
+# define RS600_ENABLE_FRAGMENT_PROCESSING (1 << 14)
+# define RS600_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15)
+# define RS600_INVALIDATE_L1_TLB (1 << 20)
+
#define R520_MC_IND_INDEX 0x70
#define R520_MC_IND_WR_EN (1 << 24)
#define R520_MC_IND_DATA 0x74
@@ -580,7 +687,6 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
/* pipe config regs */
#define R400_GB_PIPE_SELECT 0x402c
#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */
-#define R500_SU_REG_DEST 0x42c8
#define R300_GB_TILE_CONFIG 0x4018
# define R300_ENABLE_TILING (1 << 0)
# define R300_PIPE_COUNT_RV350 (0 << 1)
@@ -639,9 +745,22 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
-#define GET_SCRATCH( x ) (dev_priv->writeback_works \
- ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
- : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
+extern u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index);
+
+#define GET_SCRATCH(dev_priv, x) radeon_get_scratch(dev_priv, x)
+
+#define R600_SCRATCH_REG0 0x8500
+#define R600_SCRATCH_REG1 0x8504
+#define R600_SCRATCH_REG2 0x8508
+#define R600_SCRATCH_REG3 0x850c
+#define R600_SCRATCH_REG4 0x8510
+#define R600_SCRATCH_REG5 0x8514
+#define R600_SCRATCH_REG6 0x8518
+#define R600_SCRATCH_REG7 0x851c
+#define R600_SCRATCH_UMSK 0x8540
+#define R600_SCRATCH_ADDR 0x8544
+
+#define R600_SCRATCHOFF(x) (R600_SCRATCH_REG_OFFSET + 4*(x))
#define RADEON_GEN_INT_CNTL 0x0040
# define RADEON_CRTC_VBLANK_MASK (1 << 0)
@@ -922,6 +1041,7 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_CP_RB_CNTL 0x0704
# define RADEON_BUF_SWAP_32BIT (2 << 16)
# define RADEON_RB_NO_UPDATE (1 << 27)
+# define RADEON_RB_RPTR_WR_ENA (1 << 31)
#define RADEON_CP_RB_RPTR_ADDR 0x070c
#define RADEON_CP_RB_RPTR 0x0710
#define RADEON_CP_RB_WPTR 0x0714
@@ -983,6 +1103,14 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
# define RADEON_CNTL_SET_SCISSORS 0xC0001E00
+# define R600_IT_INDIRECT_BUFFER 0x00003200
+# define R600_IT_ME_INITIALIZE 0x00004400
+# define R600_ME_INITIALIZE_DEVICE_ID(x) ((x) << 16)
+# define R600_IT_EVENT_WRITE 0x00004600
+# define R600_IT_SET_CONFIG_REG 0x00006800
+# define R600_SET_CONFIG_REG_OFFSET 0x00008000
+# define R600_SET_CONFIG_REG_END 0x0000ac00
+
#define RADEON_CP_PACKET_MASK 0xC0000000
#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
#define RADEON_CP_PACKET0_REG_MASK 0x000007ff
@@ -1181,6 +1309,422 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define R500_D1_VBLANK_INTERRUPT (1 << 4)
#define R500_D2_VBLANK_INTERRUPT (1 << 5)
+/* R6xx/R7xx registers */
+#define R600_MC_VM_FB_LOCATION 0x2180
+#define R600_MC_VM_AGP_TOP 0x2184
+#define R600_MC_VM_AGP_BOT 0x2188
+#define R600_MC_VM_AGP_BASE 0x218c
+#define R600_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2190
+#define R600_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2194
+#define R600_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x2198
+
+#define R700_MC_VM_FB_LOCATION 0x2024
+#define R700_MC_VM_AGP_TOP 0x2028
+#define R700_MC_VM_AGP_BOT 0x202c
+#define R700_MC_VM_AGP_BASE 0x2030
+#define R700_MC_VM_SYSTEM_APERTURE_LOW_ADDR 0x2034
+#define R700_MC_VM_SYSTEM_APERTURE_HIGH_ADDR 0x2038
+#define R700_MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR 0x203c
+
+#define R600_MCD_RD_A_CNTL 0x219c
+#define R600_MCD_RD_B_CNTL 0x21a0
+
+#define R600_MCD_WR_A_CNTL 0x21a4
+#define R600_MCD_WR_B_CNTL 0x21a8
+
+#define R600_MCD_RD_SYS_CNTL 0x2200
+#define R600_MCD_WR_SYS_CNTL 0x2214
+
+#define R600_MCD_RD_GFX_CNTL 0x21fc
+#define R600_MCD_RD_HDP_CNTL 0x2204
+#define R600_MCD_RD_PDMA_CNTL 0x2208
+#define R600_MCD_RD_SEM_CNTL 0x220c
+#define R600_MCD_WR_GFX_CNTL 0x2210
+#define R600_MCD_WR_HDP_CNTL 0x2218
+#define R600_MCD_WR_PDMA_CNTL 0x221c
+#define R600_MCD_WR_SEM_CNTL 0x2220
+
+# define R600_MCD_L1_TLB (1 << 0)
+# define R600_MCD_L1_FRAG_PROC (1 << 1)
+# define R600_MCD_L1_STRICT_ORDERING (1 << 2)
+
+# define R600_MCD_SYSTEM_ACCESS_MODE_MASK (3 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_PA_ONLY (0 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_USE_SYS_MAP (1 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_IN_SYS (2 << 6)
+# define R600_MCD_SYSTEM_ACCESS_MODE_NOT_IN_SYS (3 << 6)
+
+# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 8)
+# define R600_MCD_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE (1 << 8)
+
+# define R600_MCD_SEMAPHORE_MODE (1 << 10)
+# define R600_MCD_WAIT_L2_QUERY (1 << 11)
+# define R600_MCD_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 12)
+# define R600_MCD_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 15)
+
+#define R700_MC_VM_MD_L1_TLB0_CNTL 0x2654
+#define R700_MC_VM_MD_L1_TLB1_CNTL 0x2658
+#define R700_MC_VM_MD_L1_TLB2_CNTL 0x265c
+
+#define R700_MC_VM_MB_L1_TLB0_CNTL 0x2234
+#define R700_MC_VM_MB_L1_TLB1_CNTL 0x2238
+#define R700_MC_VM_MB_L1_TLB2_CNTL 0x223c
+#define R700_MC_VM_MB_L1_TLB3_CNTL 0x2240
+
+# define R700_ENABLE_L1_TLB (1 << 0)
+# define R700_ENABLE_L1_FRAGMENT_PROCESSING (1 << 1)
+# define R700_SYSTEM_ACCESS_MODE_IN_SYS (2 << 3)
+# define R700_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU (0 << 5)
+# define R700_EFFECTIVE_L1_TLB_SIZE(x) ((x) << 15)
+# define R700_EFFECTIVE_L1_QUEUE_SIZE(x) ((x) << 18)
+
+#define R700_MC_ARB_RAMCFG 0x2760
+# define R700_NOOFBANK_SHIFT 0
+# define R700_NOOFBANK_MASK 0x3
+# define R700_NOOFRANK_SHIFT 2
+# define R700_NOOFRANK_MASK 0x1
+# define R700_NOOFROWS_SHIFT 3
+# define R700_NOOFROWS_MASK 0x7
+# define R700_NOOFCOLS_SHIFT 6
+# define R700_NOOFCOLS_MASK 0x3
+# define R700_CHANSIZE_SHIFT 8
+# define R700_CHANSIZE_MASK 0x1
+# define R700_BURSTLENGTH_SHIFT 9
+# define R700_BURSTLENGTH_MASK 0x1
+#define R600_RAMCFG 0x2408
+# define R600_NOOFBANK_SHIFT 0
+# define R600_NOOFBANK_MASK 0x1
+# define R600_NOOFRANK_SHIFT 1
+# define R600_NOOFRANK_MASK 0x1
+# define R600_NOOFROWS_SHIFT 2
+# define R600_NOOFROWS_MASK 0x7
+# define R600_NOOFCOLS_SHIFT 5
+# define R600_NOOFCOLS_MASK 0x3
+# define R600_CHANSIZE_SHIFT 7
+# define R600_CHANSIZE_MASK 0x1
+# define R600_BURSTLENGTH_SHIFT 8
+# define R600_BURSTLENGTH_MASK 0x1
+
+#define R600_VM_L2_CNTL 0x1400
+# define R600_VM_L2_CACHE_EN (1 << 0)
+# define R600_VM_L2_FRAG_PROC (1 << 1)
+# define R600_VM_ENABLE_PTE_CACHE_LRU_W (1 << 9)
+# define R600_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 13)
+# define R700_VM_L2_CNTL_QUEUE_SIZE(x) ((x) << 14)
+
+#define R600_VM_L2_CNTL2 0x1404
+# define R600_VM_L2_CNTL2_INVALIDATE_ALL_L1_TLBS (1 << 0)
+# define R600_VM_L2_CNTL2_INVALIDATE_L2_CACHE (1 << 1)
+#define R600_VM_L2_CNTL3 0x1408
+# define R600_VM_L2_CNTL3_BANK_SELECT_0(x) ((x) << 0)
+# define R600_VM_L2_CNTL3_BANK_SELECT_1(x) ((x) << 5)
+# define R600_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 10)
+# define R700_VM_L2_CNTL3_BANK_SELECT(x) ((x) << 0)
+# define R700_VM_L2_CNTL3_CACHE_UPDATE_MODE(x) ((x) << 6)
+
+#define R600_VM_L2_STATUS 0x140c
+
+#define R600_VM_CONTEXT0_CNTL 0x1410
+# define R600_VM_ENABLE_CONTEXT (1 << 0)
+# define R600_VM_PAGE_TABLE_DEPTH_FLAT (0 << 1)
+
+#define R600_VM_CONTEXT0_CNTL2 0x1430
+#define R600_VM_CONTEXT0_REQUEST_RESPONSE 0x1470
+#define R600_VM_CONTEXT0_INVALIDATION_LOW_ADDR 0x1490
+#define R600_VM_CONTEXT0_INVALIDATION_HIGH_ADDR 0x14b0
+#define R600_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x1574
+#define R600_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x1594
+#define R600_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x15b4
+
+#define R700_VM_CONTEXT0_PAGE_TABLE_BASE_ADDR 0x153c
+#define R700_VM_CONTEXT0_PAGE_TABLE_START_ADDR 0x155c
+#define R700_VM_CONTEXT0_PAGE_TABLE_END_ADDR 0x157c
+
+#define R600_HDP_HOST_PATH_CNTL 0x2c00
+
+#define R600_GRBM_CNTL 0x8000
+# define R600_GRBM_READ_TIMEOUT(x) ((x) << 0)
+
+#define R600_GRBM_STATUS 0x8010
+# define R600_CMDFIFO_AVAIL_MASK 0x1f
+# define R700_CMDFIFO_AVAIL_MASK 0xf
+# define R600_GUI_ACTIVE (1 << 31)
+#define R600_GRBM_STATUS2 0x8014
+#define R600_GRBM_SOFT_RESET 0x8020
+# define R600_SOFT_RESET_CP (1 << 0)
+#define R600_WAIT_UNTIL 0x8040
+
+#define R600_CP_SEM_WAIT_TIMER 0x85bc
+#define R600_CP_ME_CNTL 0x86d8
+# define R600_CP_ME_HALT (1 << 28)
+#define R600_CP_QUEUE_THRESHOLDS 0x8760
+# define R600_ROQ_IB1_START(x) ((x) << 0)
+# define R600_ROQ_IB2_START(x) ((x) << 8)
+#define R600_CP_MEQ_THRESHOLDS 0x8764
+# define R700_STQ_SPLIT(x) ((x) << 0)
+# define R600_MEQ_END(x) ((x) << 16)
+# define R600_ROQ_END(x) ((x) << 24)
+#define R600_CP_PERFMON_CNTL 0x87fc
+#define R600_CP_RB_BASE 0xc100
+#define R600_CP_RB_CNTL 0xc104
+# define R600_RB_BUFSZ(x) ((x) << 0)
+# define R600_RB_BLKSZ(x) ((x) << 8)
+# define R600_RB_NO_UPDATE (1 << 27)
+# define R600_RB_RPTR_WR_ENA (1 << 31)
+#define R600_CP_RB_RPTR_WR 0xc108
+#define R600_CP_RB_RPTR_ADDR 0xc10c
+#define R600_CP_RB_RPTR_ADDR_HI 0xc110
+#define R600_CP_RB_WPTR 0xc114
+#define R600_CP_RB_WPTR_ADDR 0xc118
+#define R600_CP_RB_WPTR_ADDR_HI 0xc11c
+#define R600_CP_RB_RPTR 0x8700
+#define R600_CP_RB_WPTR_DELAY 0x8704
+#define R600_CP_PFP_UCODE_ADDR 0xc150
+#define R600_CP_PFP_UCODE_DATA 0xc154
+#define R600_CP_ME_RAM_RADDR 0xc158
+#define R600_CP_ME_RAM_WADDR 0xc15c
+#define R600_CP_ME_RAM_DATA 0xc160
+#define R600_CP_DEBUG 0xc1fc
+
+#define R600_PA_CL_ENHANCE 0x8a14
+# define R600_CLIP_VTX_REORDER_ENA (1 << 0)
+# define R600_NUM_CLIP_SEQ(x) ((x) << 1)
+#define R600_PA_SC_LINE_STIPPLE_STATE 0x8b10
+#define R600_PA_SC_MULTI_CHIP_CNTL 0x8b20
+#define R700_PA_SC_FORCE_EOV_MAX_CNTS 0x8b24
+# define R700_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0)
+# define R700_FORCE_EOV_MAX_REZ_CNT(x) ((x) << 16)
+#define R600_PA_SC_AA_SAMPLE_LOCS_2S 0x8b40
+#define R600_PA_SC_AA_SAMPLE_LOCS_4S 0x8b44
+#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD0 0x8b48
+#define R600_PA_SC_AA_SAMPLE_LOCS_8S_WD1 0x8b4c
+# define R600_S0_X(x) ((x) << 0)
+# define R600_S0_Y(x) ((x) << 4)
+# define R600_S1_X(x) ((x) << 8)
+# define R600_S1_Y(x) ((x) << 12)
+# define R600_S2_X(x) ((x) << 16)
+# define R600_S2_Y(x) ((x) << 20)
+# define R600_S3_X(x) ((x) << 24)
+# define R600_S3_Y(x) ((x) << 28)
+# define R600_S4_X(x) ((x) << 0)
+# define R600_S4_Y(x) ((x) << 4)
+# define R600_S5_X(x) ((x) << 8)
+# define R600_S5_Y(x) ((x) << 12)
+# define R600_S6_X(x) ((x) << 16)
+# define R600_S6_Y(x) ((x) << 20)
+# define R600_S7_X(x) ((x) << 24)
+# define R600_S7_Y(x) ((x) << 28)
+#define R600_PA_SC_FIFO_SIZE 0x8bd0
+# define R600_SC_PRIM_FIFO_SIZE(x) ((x) << 0)
+# define R600_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 8)
+# define R600_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 16)
+#define R700_PA_SC_FIFO_SIZE_R7XX 0x8bcc
+# define R700_SC_PRIM_FIFO_SIZE(x) ((x) << 0)
+# define R700_SC_HIZ_TILE_FIFO_SIZE(x) ((x) << 12)
+# define R700_SC_EARLYZ_TILE_FIFO_SIZE(x) ((x) << 20)
+#define R600_PA_SC_ENHANCE 0x8bf0
+# define R600_FORCE_EOV_MAX_CLK_CNT(x) ((x) << 0)
+# define R600_FORCE_EOV_MAX_TILE_CNT(x) ((x) << 12)
+#define R600_PA_SC_CLIPRECT_RULE 0x2820c
+#define R700_PA_SC_EDGERULE 0x28230
+#define R600_PA_SC_LINE_STIPPLE 0x28a0c
+#define R600_PA_SC_MODE_CNTL 0x28a4c
+#define R600_PA_SC_AA_CONFIG 0x28c04
+
+#define R600_SX_EXPORT_BUFFER_SIZES 0x900c
+# define R600_COLOR_BUFFER_SIZE(x) ((x) << 0)
+# define R600_POSITION_BUFFER_SIZE(x) ((x) << 8)
+# define R600_SMX_BUFFER_SIZE(x) ((x) << 16)
+#define R600_SX_DEBUG_1 0x9054
+# define R600_SMX_EVENT_RELEASE (1 << 0)
+# define R600_ENABLE_NEW_SMX_ADDRESS (1 << 16)
+#define R700_SX_DEBUG_1 0x9058
+# define R700_ENABLE_NEW_SMX_ADDRESS (1 << 16)
+#define R600_SX_MISC 0x28350
+
+#define R600_DB_DEBUG 0x9830
+# define R600_PREZ_MUST_WAIT_FOR_POSTZ_DONE (1 << 31)
+#define R600_DB_WATERMARKS 0x9838
+# define R600_DEPTH_FREE(x) ((x) << 0)
+# define R600_DEPTH_FLUSH(x) ((x) << 5)
+# define R600_DEPTH_PENDING_FREE(x) ((x) << 15)
+# define R600_DEPTH_CACHELINE_FREE(x) ((x) << 20)
+#define R700_DB_DEBUG3 0x98b0
+# define R700_DB_CLK_OFF_DELAY(x) ((x) << 11)
+#define RV700_DB_DEBUG4 0x9b8c
+# define RV700_DISABLE_TILE_COVERED_FOR_PS_ITER (1 << 6)
+
+#define R600_VGT_CACHE_INVALIDATION 0x88c4
+# define R600_CACHE_INVALIDATION(x) ((x) << 0)
+# define R600_VC_ONLY 0
+# define R600_TC_ONLY 1
+# define R600_VC_AND_TC 2
+# define R700_AUTO_INVLD_EN(x) ((x) << 6)
+# define R700_NO_AUTO 0
+# define R700_ES_AUTO 1
+# define R700_GS_AUTO 2
+# define R700_ES_AND_GS_AUTO 3
+#define R600_VGT_GS_PER_ES 0x88c8
+#define R600_VGT_ES_PER_GS 0x88cc
+#define R600_VGT_GS_PER_VS 0x88e8
+#define R600_VGT_GS_VERTEX_REUSE 0x88d4
+#define R600_VGT_NUM_INSTANCES 0x8974
+#define R600_VGT_STRMOUT_EN 0x28ab0
+#define R600_VGT_EVENT_INITIATOR 0x28a90
+# define R600_CACHE_FLUSH_AND_INV_EVENT (0x16 << 0)
+#define R600_VGT_VERTEX_REUSE_BLOCK_CNTL 0x28c58
+# define R600_VTX_REUSE_DEPTH_MASK 0xff
+#define R600_VGT_OUT_DEALLOC_CNTL 0x28c5c
+# define R600_DEALLOC_DIST_MASK 0x7f
+
+#define R600_CB_COLOR0_BASE 0x28040
+#define R600_CB_COLOR1_BASE 0x28044
+#define R600_CB_COLOR2_BASE 0x28048
+#define R600_CB_COLOR3_BASE 0x2804c
+#define R600_CB_COLOR4_BASE 0x28050
+#define R600_CB_COLOR5_BASE 0x28054
+#define R600_CB_COLOR6_BASE 0x28058
+#define R600_CB_COLOR7_BASE 0x2805c
+#define R600_CB_COLOR7_FRAG 0x280fc
+
+#define R600_TC_CNTL 0x9608
+# define R600_TC_L2_SIZE(x) ((x) << 5)
+# define R600_L2_DISABLE_LATE_HIT (1 << 9)
+
+#define R600_ARB_POP 0x2418
+# define R600_ENABLE_TC128 (1 << 30)
+#define R600_ARB_GDEC_RD_CNTL 0x246c
+
+#define R600_TA_CNTL_AUX 0x9508
+# define R600_DISABLE_CUBE_WRAP (1 << 0)
+# define R600_DISABLE_CUBE_ANISO (1 << 1)
+# define R700_GETLOD_SELECT(x) ((x) << 2)
+# define R600_SYNC_GRADIENT (1 << 24)
+# define R600_SYNC_WALKER (1 << 25)
+# define R600_SYNC_ALIGNER (1 << 26)
+# define R600_BILINEAR_PRECISION_6_BIT (0 << 31)
+# define R600_BILINEAR_PRECISION_8_BIT (1 << 31)
+
+#define R700_TCP_CNTL 0x9610
+
+#define R600_SMX_DC_CTL0 0xa020
+# define R700_USE_HASH_FUNCTION (1 << 0)
+# define R700_CACHE_DEPTH(x) ((x) << 1)
+# define R700_FLUSH_ALL_ON_EVENT (1 << 10)
+# define R700_STALL_ON_EVENT (1 << 11)
+#define R700_SMX_EVENT_CTL 0xa02c
+# define R700_ES_FLUSH_CTL(x) ((x) << 0)
+# define R700_GS_FLUSH_CTL(x) ((x) << 3)
+# define R700_ACK_FLUSH_CTL(x) ((x) << 6)
+# define R700_SYNC_FLUSH_CTL (1 << 8)
+
+#define R600_SQ_CONFIG 0x8c00
+# define R600_VC_ENABLE (1 << 0)
+# define R600_EXPORT_SRC_C (1 << 1)
+# define R600_DX9_CONSTS (1 << 2)
+# define R600_ALU_INST_PREFER_VECTOR (1 << 3)
+# define R600_DX10_CLAMP (1 << 4)
+# define R600_CLAUSE_SEQ_PRIO(x) ((x) << 8)
+# define R600_PS_PRIO(x) ((x) << 24)
+# define R600_VS_PRIO(x) ((x) << 26)
+# define R600_GS_PRIO(x) ((x) << 28)
+# define R600_ES_PRIO(x) ((x) << 30)
+#define R600_SQ_GPR_RESOURCE_MGMT_1 0x8c04
+# define R600_NUM_PS_GPRS(x) ((x) << 0)
+# define R600_NUM_VS_GPRS(x) ((x) << 16)
+# define R700_DYN_GPR_ENABLE (1 << 27)
+# define R600_NUM_CLAUSE_TEMP_GPRS(x) ((x) << 28)
+#define R600_SQ_GPR_RESOURCE_MGMT_2 0x8c08
+# define R600_NUM_GS_GPRS(x) ((x) << 0)
+# define R600_NUM_ES_GPRS(x) ((x) << 16)
+#define R600_SQ_THREAD_RESOURCE_MGMT 0x8c0c
+# define R600_NUM_PS_THREADS(x) ((x) << 0)
+# define R600_NUM_VS_THREADS(x) ((x) << 8)
+# define R600_NUM_GS_THREADS(x) ((x) << 16)
+# define R600_NUM_ES_THREADS(x) ((x) << 24)
+#define R600_SQ_STACK_RESOURCE_MGMT_1 0x8c10
+# define R600_NUM_PS_STACK_ENTRIES(x) ((x) << 0)
+# define R600_NUM_VS_STACK_ENTRIES(x) ((x) << 16)
+#define R600_SQ_STACK_RESOURCE_MGMT_2 0x8c14
+# define R600_NUM_GS_STACK_ENTRIES(x) ((x) << 0)
+# define R600_NUM_ES_STACK_ENTRIES(x) ((x) << 16)
+#define R600_SQ_MS_FIFO_SIZES 0x8cf0
+# define R600_CACHE_FIFO_SIZE(x) ((x) << 0)
+# define R600_FETCH_FIFO_HIWATER(x) ((x) << 8)
+# define R600_DONE_FIFO_HIWATER(x) ((x) << 16)
+# define R600_ALU_UPDATE_FIFO_HIWATER(x) ((x) << 24)
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_0 0x8db0
+# define R700_SIMDA_RING0(x) ((x) << 0)
+# define R700_SIMDA_RING1(x) ((x) << 8)
+# define R700_SIMDB_RING0(x) ((x) << 16)
+# define R700_SIMDB_RING1(x) ((x) << 24)
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_1 0x8db4
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_2 0x8db8
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_3 0x8dbc
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_4 0x8dc0
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_5 0x8dc4
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_6 0x8dc8
+#define R700_SQ_DYN_GPR_SIZE_SIMD_AB_7 0x8dcc
+
+#define R600_SPI_PS_IN_CONTROL_0 0x286cc
+# define R600_NUM_INTERP(x) ((x) << 0)
+# define R600_POSITION_ENA (1 << 8)
+# define R600_POSITION_CENTROID (1 << 9)
+# define R600_POSITION_ADDR(x) ((x) << 10)
+# define R600_PARAM_GEN(x) ((x) << 15)
+# define R600_PARAM_GEN_ADDR(x) ((x) << 19)
+# define R600_BARYC_SAMPLE_CNTL(x) ((x) << 26)
+# define R600_PERSP_GRADIENT_ENA (1 << 28)
+# define R600_LINEAR_GRADIENT_ENA (1 << 29)
+# define R600_POSITION_SAMPLE (1 << 30)
+# define R600_BARYC_AT_SAMPLE_ENA (1 << 31)
+#define R600_SPI_PS_IN_CONTROL_1 0x286d0
+# define R600_GEN_INDEX_PIX (1 << 0)
+# define R600_GEN_INDEX_PIX_ADDR(x) ((x) << 1)
+# define R600_FRONT_FACE_ENA (1 << 8)
+# define R600_FRONT_FACE_CHAN(x) ((x) << 9)
+# define R600_FRONT_FACE_ALL_BITS (1 << 11)
+# define R600_FRONT_FACE_ADDR(x) ((x) << 12)
+# define R600_FOG_ADDR(x) ((x) << 17)
+# define R600_FIXED_PT_POSITION_ENA (1 << 24)
+# define R600_FIXED_PT_POSITION_ADDR(x) ((x) << 25)
+# define R700_POSITION_ULC (1 << 30)
+#define R600_SPI_INPUT_Z 0x286d8
+
+#define R600_SPI_CONFIG_CNTL 0x9100
+# define R600_GPR_WRITE_PRIORITY(x) ((x) << 0)
+# define R600_DISABLE_INTERP_1 (1 << 5)
+#define R600_SPI_CONFIG_CNTL_1 0x913c
+# define R600_VTX_DONE_DELAY(x) ((x) << 0)
+# define R600_INTERP_ONE_PRIM_PER_ROW (1 << 4)
+
+#define R600_GB_TILING_CONFIG 0x98f0
+# define R600_PIPE_TILING(x) ((x) << 1)
+# define R600_BANK_TILING(x) ((x) << 4)
+# define R600_GROUP_SIZE(x) ((x) << 6)
+# define R600_ROW_TILING(x) ((x) << 8)
+# define R600_BANK_SWAPS(x) ((x) << 11)
+# define R600_SAMPLE_SPLIT(x) ((x) << 14)
+# define R600_BACKEND_MAP(x) ((x) << 16)
+#define R600_DCP_TILING_CONFIG 0x6ca0
+#define R600_HDP_TILING_CONFIG 0x2f3c
+
+#define R600_CC_RB_BACKEND_DISABLE 0x98f4
+#define R700_CC_SYS_RB_BACKEND_DISABLE 0x3f88
+# define R600_BACKEND_DISABLE(x) ((x) << 16)
+
+#define R600_CC_GC_SHADER_PIPE_CONFIG 0x8950
+#define R600_GC_USER_SHADER_PIPE_CONFIG 0x8954
+# define R600_INACTIVE_QD_PIPES(x) ((x) << 8)
+# define R600_INACTIVE_QD_PIPES_MASK (0xff << 8)
+# define R600_INACTIVE_SIMDS(x) ((x) << 16)
+# define R600_INACTIVE_SIMDS_MASK (0xff << 16)
+
+#define R700_CGTS_SYS_TCC_DISABLE 0x3f90
+#define R700_CGTS_USER_SYS_TCC_DISABLE 0x3f94
+#define R700_CGTS_TCC_DISABLE 0x9148
+#define R700_CGTS_USER_TCC_DISABLE 0x914c
+
/* Constants */
#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
@@ -1190,6 +1734,11 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3
#define RADEON_LAST_DISPATCH 1
+#define R600_LAST_FRAME_REG R600_SCRATCH_REG0
+#define R600_LAST_DISPATCH_REG R600_SCRATCH_REG1
+#define R600_LAST_CLEAR_REG R600_SCRATCH_REG2
+#define R600_LAST_SWI_REG R600_SCRATCH_REG3
+
#define RADEON_MAX_VB_AGE 0x7fffffff
#define RADEON_MAX_VB_VERTS (0xffff)
@@ -1198,7 +1747,15 @@ extern int r300_do_cp_cmdbuf(struct drm_device *dev,
#define RADEON_PCIGART_TABLE_SIZE (32*1024)
#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
-#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
+#define RADEON_WRITE(reg, val) \
+do { \
+ if (reg < 0x10000) { \
+ DRM_WRITE32(dev_priv->mmio, (reg), (val)); \
+ } else { \
+ DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, (reg)); \
+ DRM_WRITE32(dev_priv->mmio, RADEON_MM_DATA, (val)); \
+ } \
+} while (0)
#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
@@ -1238,11 +1795,19 @@ do { \
RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
} while (0)
+#define RS600_WRITE_MCIND(addr, val) \
+do { \
+ RADEON_WRITE(RS600_MC_INDEX, RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | ((addr) & RS600_MC_ADDR_MASK)); \
+ RADEON_WRITE(RS600_MC_DATA, val); \
+} while (0)
+
#define IGP_WRITE_MCIND(addr, val) \
do { \
if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || \
((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) \
RS690_WRITE_MCIND(addr, val); \
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) \
+ RS600_WRITE_MCIND(addr, val); \
else \
RS480_WRITE_MCIND(addr, val); \
} while (0)
@@ -1346,7 +1911,11 @@ do { \
struct drm_radeon_master_private *master_priv = file_priv->master->driver_priv; \
drm_radeon_sarea_t *sarea_priv = master_priv->sarea_priv; \
if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
- int __ret = radeon_do_cp_idle( dev_priv ); \
+ int __ret; \
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) \
+ __ret = r600_do_cp_idle(dev_priv); \
+ else \
+ __ret = radeon_do_cp_idle(dev_priv); \
if ( __ret ) return __ret; \
sarea_priv->last_dispatch = 0; \
radeon_freelist_reset( dev ); \
@@ -1368,21 +1937,40 @@ do { \
OUT_RING( age ); \
} while (0)
+#define R600_DISPATCH_AGE(age) do { \
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \
+ OUT_RING((R600_LAST_DISPATCH_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \
+ OUT_RING(age); \
+} while (0)
+
+#define R600_FRAME_AGE(age) do { \
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \
+ OUT_RING((R600_LAST_FRAME_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \
+ OUT_RING(age); \
+} while (0)
+
+#define R600_CLEAR_AGE(age) do { \
+ OUT_RING(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1)); \
+ OUT_RING((R600_LAST_CLEAR_REG - R600_SET_CONFIG_REG_OFFSET) >> 2); \
+ OUT_RING(age); \
+} while (0)
+
/* ================================================================
* Ring control
*/
#define RADEON_VERBOSE 0
-#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring;
+#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring;
#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
- if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
+ _align_nr = (n + 0xf) & ~0xf; \
+ if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \
COMMIT_RING(); \
- radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
+ radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \
} \
_nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
ring = dev_priv->ring.start; \
@@ -1399,19 +1987,16 @@ do { \
DRM_ERROR( \
"ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
((dev_priv->ring.tail + _nr) & mask), \
- write, __LINE__); \
+ write, __LINE__); \
} else \
dev_priv->ring.tail = write; \
} while (0)
+extern void radeon_commit_ring(drm_radeon_private_t *dev_priv);
+
#define COMMIT_RING() do { \
- /* Flush writes to ring */ \
- DRM_MEMORYBARRIER(); \
- GET_RING_HEAD( dev_priv ); \
- RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
- /* read from PCI bus to ensure correct posting */ \
- RADEON_READ( RADEON_CP_RB_RPTR ); \
-} while (0)
+ radeon_commit_ring(dev_priv); \
+ } while(0)
#define OUT_RING( x ) do { \
if ( RADEON_VERBOSE ) { \
diff --git a/drivers/gpu/drm/radeon/radeon_irq.c b/drivers/gpu/drm/radeon/radeon_irq.c
index 8289e16419a..9836c705a95 100644
--- a/drivers/gpu/drm/radeon/radeon_irq.c
+++ b/drivers/gpu/drm/radeon/radeon_irq.c
@@ -65,7 +65,7 @@ int radeon_enable_vblank(struct drm_device *dev, int crtc)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
switch (crtc) {
case 0:
r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 1);
@@ -100,7 +100,7 @@ void radeon_disable_vblank(struct drm_device *dev, int crtc)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
switch (crtc) {
case 0:
r500_vbl_irq_set_state(dev, R500_D1MODE_INT_MASK, 0);
@@ -135,7 +135,7 @@ static inline u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r
u32 irq_mask = RADEON_SW_INT_TEST;
*r500_disp_int = 0;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
/* vbl interrupts in a different place */
if (irqs & R500_DISPLAY_INT_STATUS) {
@@ -202,7 +202,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
DRM_WAKEUP(&dev_priv->swi_queue);
/* VBLANK interrupt */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
drm_handle_vblank(dev, 0);
if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
@@ -265,7 +265,7 @@ u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
return -EINVAL;
}
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
if (crtc == 0)
return RADEON_READ(R500_D1CRTC_FRAME_COUNT);
else
@@ -327,7 +327,7 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
u32 dummy;
/* Disable *all* interrupts */
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
@@ -357,7 +357,7 @@ void radeon_driver_irq_uninstall(struct drm_device * dev)
if (!dev_priv)
return;
- if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
/* Disable *all* interrupts */
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c
index ef940a079dc..fa728ec6ed3 100644
--- a/drivers/gpu/drm/radeon/radeon_state.c
+++ b/drivers/gpu/drm/radeon/radeon_state.c
@@ -1556,9 +1556,15 @@ static void radeon_cp_discard_buffer(struct drm_device *dev, struct drm_master *
buf_priv->age = ++master_priv->sarea_priv->last_dispatch;
/* Emit the vertex buffer age */
- BEGIN_RING(2);
- RADEON_DISPATCH_AGE(buf_priv->age);
- ADVANCE_RING();
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
+ BEGIN_RING(3);
+ R600_DISPATCH_AGE(buf_priv->age);
+ ADVANCE_RING();
+ } else {
+ BEGIN_RING(2);
+ RADEON_DISPATCH_AGE(buf_priv->age);
+ ADVANCE_RING();
+ }
buf->pending = 1;
buf->used = 0;
@@ -1980,7 +1986,7 @@ static int alloc_surface(drm_radeon_surface_alloc_t *new,
/* find a virtual surface */
for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
- if (dev_priv->virt_surfaces[i].file_priv == 0)
+ if (dev_priv->virt_surfaces[i].file_priv == NULL)
break;
if (i == 2 * RADEON_MAX_SURFACES) {
return -1;
@@ -2473,24 +2479,25 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
buf->used = indirect->end;
- /* Wait for the 3D stream to idle before the indirect buffer
- * containing 2D acceleration commands is processed.
- */
- BEGIN_RING(2);
-
- RADEON_WAIT_UNTIL_3D_IDLE();
-
- ADVANCE_RING();
-
/* Dispatch the indirect buffer full of commands from the
* X server. This is insecure and is thus only available to
* privileged clients.
*/
- radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
- if (indirect->discard) {
- radeon_cp_discard_buffer(dev, file_priv->master, buf);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ r600_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
+ else {
+ /* Wait for the 3D stream to idle before the indirect buffer
+ * containing 2D acceleration commands is processed.
+ */
+ BEGIN_RING(2);
+ RADEON_WAIT_UNTIL_3D_IDLE();
+ ADVANCE_RING();
+ radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
}
+ if (indirect->discard)
+ radeon_cp_discard_buffer(dev, file_priv->master, buf);
+
COMMIT_RING();
return 0;
}
@@ -3010,14 +3017,14 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
break;
case RADEON_PARAM_LAST_FRAME:
dev_priv->stats.last_frame_reads++;
- value = GET_SCRATCH(0);
+ value = GET_SCRATCH(dev_priv, 0);
break;
case RADEON_PARAM_LAST_DISPATCH:
- value = GET_SCRATCH(1);
+ value = GET_SCRATCH(dev_priv, 1);
break;
case RADEON_PARAM_LAST_CLEAR:
dev_priv->stats.last_clear_reads++;
- value = GET_SCRATCH(2);
+ value = GET_SCRATCH(dev_priv, 2);
break;
case RADEON_PARAM_IRQ_NR:
value = drm_dev_to_irq(dev);
@@ -3052,7 +3059,10 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
case RADEON_PARAM_SCRATCH_OFFSET:
if (!dev_priv->writeback_works)
return -EINVAL;
- value = RADEON_SCRATCH_REG_OFFSET;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
+ value = R600_SCRATCH_REG_OFFSET;
+ else
+ value = RADEON_SCRATCH_REG_OFFSET;
break;
case RADEON_PARAM_CARD_TYPE:
if (dev_priv->flags & RADEON_IS_PCIE)
@@ -3155,6 +3165,7 @@ void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
void radeon_driver_lastclose(struct drm_device *dev)
{
+ radeon_surfaces_release(PCIGART_FILE_PRIV, dev->dev_private);
radeon_do_release(dev);
}
diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c
index d465b2f9c1c..456cd040f31 100644
--- a/drivers/gpu/drm/savage/savage_bci.c
+++ b/drivers/gpu/drm/savage/savage_bci.c
@@ -599,8 +599,8 @@ int savage_driver_firstopen(struct drm_device *dev)
drm_mtrr_add(dev_priv->mtrr[2].base,
dev_priv->mtrr[2].size, DRM_MTRR_WC);
} else {
- DRM_ERROR("strange pci_resource_len %08lx\n",
- drm_get_resource_len(dev, 0));
+ DRM_ERROR("strange pci_resource_len %08llx\n",
+ (unsigned long long)drm_get_resource_len(dev, 0));
}
} else if (dev_priv->chipset != S3_SUPERSAVAGE &&
dev_priv->chipset != S3_SAVAGE2000) {
@@ -620,8 +620,8 @@ int savage_driver_firstopen(struct drm_device *dev)
drm_mtrr_add(dev_priv->mtrr[0].base,
dev_priv->mtrr[0].size, DRM_MTRR_WC);
} else {
- DRM_ERROR("strange pci_resource_len %08lx\n",
- drm_get_resource_len(dev, 1));
+ DRM_ERROR("strange pci_resource_len %08llx\n",
+ (unsigned long long)drm_get_resource_len(dev, 1));
}
} else {
mmio_base = drm_get_resource_start(dev, 0);
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index 0993b441fc4..bc2f5184300 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -28,11 +28,6 @@
#include "drm_pciids.h"
-static int dri_library_name(struct drm_device *dev, char *buf)
-{
- return snprintf(buf, PAGE_SIZE, "unichrome");
-}
-
static struct pci_device_id pciidlist[] = {
viadrv_PCI_IDS
};
@@ -52,7 +47,6 @@ static struct drm_driver driver = {
.irq_uninstall = via_driver_irq_uninstall,
.irq_handler = via_driver_irq_handler,
.dma_quiescent = via_driver_dma_quiescent,
- .dri_library_name = dri_library_name,
.reclaim_buffers = drm_core_reclaim_buffers,
.reclaim_buffers_locked = NULL,
.reclaim_buffers_idlelocked = via_reclaim_buffers_locked,
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
index e85c8fe9ffc..7e67dcb3d4f 100644
--- a/drivers/hid/Kconfig
+++ b/drivers/hid/Kconfig
@@ -29,11 +29,11 @@ config HID
For docs and specs, see http://www.usb.org/developers/hidpage/
- If unsure, say Y
+ If unsure, say Y.
config HID_DEBUG
bool "HID debugging support"
- default y if !EMBEDDED
+ default y
depends on HID
---help---
This option lets the HID layer output diagnostics about its internal
@@ -44,7 +44,7 @@ config HID_DEBUG
This feature is useful for those who are either debugging the HID parser
or any HID hardware device.
- If unsure, say N
+ If unsure, say Y.
config HIDRAW
bool "/dev/hidraw raw HID device support"
@@ -70,18 +70,6 @@ source "drivers/hid/usbhid/Kconfig"
menu "Special HID drivers"
depends on HID
-config HID_COMPAT
- bool "Load all HID drivers on hid core load"
- default y
- ---help---
- Compatible option for older userspace. If you have system without udev
- support of module loading through aliases and also old
- module-init-tools which can't handle hid bus, choose Y here. Otherwise
- say N. If you say N and your userspace is old enough, the only
- functionality you lose is modules autoloading.
-
- If unsure, say Y.
-
config HID_A4TECH
tristate "A4 tech" if EMBEDDED
depends on USB_HID
@@ -128,6 +116,14 @@ config HID_CYPRESS
---help---
Support for cypress mouse and barcode readers.
+config DRAGONRISE_FF
+ tristate "DragonRise Inc. force feedback support"
+ depends on USB_HID
+ select INPUT_FF_MEMLESS
+ ---help---
+ Say Y here if you want to enable force feedback support for DragonRise Inc.
+ game controllers.
+
config HID_EZKEY
tristate "Ezkey" if EMBEDDED
depends on USB_HID
@@ -135,6 +131,13 @@ config HID_EZKEY
---help---
Support for Ezkey BTC 8193 keyboard.
+config HID_KYE
+ tristate "Kye" if EMBEDDED
+ depends on USB_HID
+ default !EMBEDDED
+ ---help---
+ Support for Kye/Genius Ergo Mouse.
+
config HID_GYRATION
tristate "Gyration" if EMBEDDED
depends on USB_HID
@@ -142,6 +145,13 @@ config HID_GYRATION
---help---
Support for Gyration remote control.
+config HID_KENSINGTON
+ tristate "Kensington" if EMBEDDED
+ depends on USB_HID
+ default !EMBEDDED
+ ---help---
+ Support for Kensington Slimblade Trackball.
+
config HID_LOGITECH
tristate "Logitech" if EMBEDDED
depends on USB_HID
@@ -243,7 +253,7 @@ config GREENASIA_FF
select INPUT_FF_MEMLESS
---help---
Say Y here if you have a GreenAsia (Product ID 0x12) based game controller
- (like MANTA Warior MM816 and SpeedLink Strike2 SL-6635) or adapter
+ (like MANTA Warrior MM816 and SpeedLink Strike2 SL-6635) or adapter
and want to enable force feedback support for it.
config HID_TOPSEED
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
index fbd021f153f..1f7cb0fd450 100644
--- a/drivers/hid/Makefile
+++ b/drivers/hid/Makefile
@@ -8,10 +8,6 @@ obj-$(CONFIG_HID) += hid.o
hid-$(CONFIG_HID_DEBUG) += hid-debug.o
hid-$(CONFIG_HIDRAW) += hidraw.o
-ifdef CONFIG_HID_COMPAT
-obj-m += hid-dummy.o
-endif
-
hid-logitech-objs := hid-lg.o
ifdef CONFIG_LOGITECH_FF
hid-logitech-objs += hid-lgff.o
@@ -26,8 +22,11 @@ obj-$(CONFIG_HID_BELKIN) += hid-belkin.o
obj-$(CONFIG_HID_CHERRY) += hid-cherry.o
obj-$(CONFIG_HID_CHICONY) += hid-chicony.o
obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o
+obj-$(CONFIG_DRAGONRISE_FF) += hid-drff.o
obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o
obj-$(CONFIG_HID_GYRATION) += hid-gyration.o
+obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o
+obj-$(CONFIG_HID_KYE) += hid-kye.o
obj-$(CONFIG_HID_LOGITECH) += hid-logitech.o
obj-$(CONFIG_HID_MICROSOFT) += hid-microsoft.o
obj-$(CONFIG_HID_MONTEREY) += hid-monterey.o
diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c
index ebca00e6c10..42ea359e94c 100644
--- a/drivers/hid/hid-a4tech.c
+++ b/drivers/hid/hid-a4tech.c
@@ -158,5 +158,3 @@ static void a4_exit(void)
module_init(a4_init);
module_exit(a4_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(a4tech);
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c
index aa28aed0e46..7359d9d88e4 100644
--- a/drivers/hid/hid-apple.c
+++ b/drivers/hid/hid-apple.c
@@ -53,7 +53,7 @@ struct apple_key_translation {
u8 flags;
};
-static struct apple_key_translation apple_fn_keys[] = {
+static const struct apple_key_translation apple_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_ENTER, KEY_INSERT },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
@@ -75,7 +75,7 @@ static struct apple_key_translation apple_fn_keys[] = {
{ }
};
-static struct apple_key_translation powerbook_fn_keys[] = {
+static const struct apple_key_translation powerbook_fn_keys[] = {
{ KEY_BACKSPACE, KEY_DELETE },
{ KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY },
{ KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY },
@@ -94,7 +94,7 @@ static struct apple_key_translation powerbook_fn_keys[] = {
{ }
};
-static struct apple_key_translation powerbook_numlock_keys[] = {
+static const struct apple_key_translation powerbook_numlock_keys[] = {
{ KEY_J, KEY_KP1 },
{ KEY_K, KEY_KP2 },
{ KEY_L, KEY_KP3 },
@@ -117,16 +117,16 @@ static struct apple_key_translation powerbook_numlock_keys[] = {
{ }
};
-static struct apple_key_translation apple_iso_keyboard[] = {
+static const struct apple_key_translation apple_iso_keyboard[] = {
{ KEY_GRAVE, KEY_102ND },
{ KEY_102ND, KEY_GRAVE },
{ }
};
-static struct apple_key_translation *apple_find_translation(
- struct apple_key_translation *table, u16 from)
+static const struct apple_key_translation *apple_find_translation(
+ const struct apple_key_translation *table, u16 from)
{
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
/* Look for the translation */
for (trans = table; trans->from; trans++)
@@ -140,7 +140,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input,
struct hid_usage *usage, __s32 value)
{
struct apple_sc *asc = hid_get_drvdata(hid);
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
if (usage->code == KEY_FN) {
asc->fn_on = !!value;
@@ -253,7 +253,7 @@ static void apple_report_fixup(struct hid_device *hdev, __u8 *rdesc,
static void apple_setup_input(struct input_dev *input)
{
- struct apple_key_translation *trans;
+ const struct apple_key_translation *trans;
set_bit(KEY_NUMLOCK, input->keybit);
@@ -387,6 +387,12 @@ static const struct hid_device_id apple_devices[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS),
.driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN |
APPLE_RDESC_JIS },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI),
+ .driver_data = APPLE_HAS_FN },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO),
+ .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS),
+ .driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI),
.driver_data = APPLE_HAS_FN },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO),
@@ -468,5 +474,3 @@ static void apple_exit(void)
module_init(apple_init);
module_exit(apple_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(apple);
diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c
index 12c8a9ba6ed..2f6723133a4 100644
--- a/drivers/hid/hid-belkin.c
+++ b/drivers/hid/hid-belkin.c
@@ -101,5 +101,3 @@ static void belkin_exit(void)
module_init(belkin_init);
module_exit(belkin_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(belkin);
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c
index b833b9769ab..ab8209e7e45 100644
--- a/drivers/hid/hid-cherry.c
+++ b/drivers/hid/hid-cherry.c
@@ -83,5 +83,3 @@ static void ch_exit(void)
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cherry);
diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c
index a54d4096e0f..7f91076d849 100644
--- a/drivers/hid/hid-chicony.c
+++ b/drivers/hid/hid-chicony.c
@@ -76,5 +76,3 @@ static void ch_exit(void)
module_init(ch_init);
module_exit(ch_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(chicony);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 1cc967448f4..5746a5903bc 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -1236,6 +1236,9 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ANSI) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_ISO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_MINI_JIS) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ANSI) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_ISO) },
{ HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_JIS) },
@@ -1262,6 +1265,7 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) },
{ HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_MOUSE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006) },
{ HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) },
@@ -1269,6 +1273,8 @@ static const struct hid_device_id hid_blacklist[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0012) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE) },
{ HID_USB_DEVICE(USB_VENDOR_ID_GYRATION, USB_DEVICE_ID_GYRATION_REMOTE_2) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LABTEC, USB_DEVICE_ID_LABTEC_WIRELESS_KEYBOARD) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_MX3000_RECEIVER) },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
@@ -1813,14 +1819,21 @@ void hid_unregister_driver(struct hid_driver *hdrv)
}
EXPORT_SYMBOL_GPL(hid_unregister_driver);
-#ifdef CONFIG_HID_COMPAT
-static void hid_compat_load(struct work_struct *ws)
+int hid_check_keys_pressed(struct hid_device *hid)
{
- request_module("hid-dummy");
+ struct hid_input *hidinput;
+ int i;
+
+ list_for_each_entry(hidinput, &hid->inputs, list) {
+ for (i = 0; i < BITS_TO_LONGS(KEY_MAX); i++)
+ if (hidinput->input->key[i])
+ return 1;
+ }
+
+ return 0;
}
-static DECLARE_WORK(hid_compat_work, hid_compat_load);
-static struct workqueue_struct *hid_compat_wq;
-#endif
+
+EXPORT_SYMBOL_GPL(hid_check_keys_pressed);
static int __init hid_init(void)
{
@@ -1836,15 +1849,6 @@ static int __init hid_init(void)
if (ret)
goto err_bus;
-#ifdef CONFIG_HID_COMPAT
- hid_compat_wq = create_singlethread_workqueue("hid_compat");
- if (!hid_compat_wq) {
- hidraw_exit();
- goto err;
- }
- queue_work(hid_compat_wq, &hid_compat_work);
-#endif
-
return 0;
err_bus:
bus_unregister(&hid_bus_type);
@@ -1854,9 +1858,6 @@ err:
static void __exit hid_exit(void)
{
-#ifdef CONFIG_HID_COMPAT
- destroy_workqueue(hid_compat_wq);
-#endif
hidraw_exit();
bus_unregister(&hid_bus_type);
}
diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c
index 5d69d27b935..9d6d3b91773 100644
--- a/drivers/hid/hid-cypress.c
+++ b/drivers/hid/hid-cypress.c
@@ -154,5 +154,3 @@ static void cp_exit(void)
module_init(cp_init);
module_exit(cp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(cypress);
diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c
new file mode 100644
index 00000000000..34f3eb65100
--- /dev/null
+++ b/drivers/hid/hid-drff.c
@@ -0,0 +1,188 @@
+/*
+ * Force feedback support for DragonRise Inc. game controllers
+ *
+ * From what I have gathered, these devices are mass produced in China and are
+ * distributed under several vendors. They often share the same design as
+ * the original PlayStation DualShock controller.
+ *
+ * 0079:0006 "DragonRise Inc. Generic USB Joystick "
+ * - tested with a Tesun USB-703 game controller.
+ *
+ * Copyright (c) 2009 Richard Walmsley <richwalm@gmail.com>
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/input.h>
+#include <linux/usb.h>
+#include <linux/hid.h>
+
+#include "hid-ids.h"
+#include "usbhid/usbhid.h"
+
+struct drff_device {
+ struct hid_report *report;
+};
+
+static int drff_play(struct input_dev *dev, void *data,
+ struct ff_effect *effect)
+{
+ struct hid_device *hid = input_get_drvdata(dev);
+ struct drff_device *drff = data;
+ int strong, weak;
+
+ strong = effect->u.rumble.strong_magnitude;
+ weak = effect->u.rumble.weak_magnitude;
+
+ dbg_hid("called with 0x%04x 0x%04x", strong, weak);
+
+ if (strong || weak) {
+ strong = strong * 0xff / 0xffff;
+ weak = weak * 0xff / 0xffff;
+
+ /* While reverse engineering this device, I found that when
+ this value is set, it causes the strong rumble to function
+ at a near maximum speed, so we'll bypass it. */
+ if (weak == 0x0a)
+ weak = 0x0b;
+
+ drff->report->field[0]->value[0] = 0x51;
+ drff->report->field[0]->value[1] = 0x00;
+ drff->report->field[0]->value[2] = weak;
+ drff->report->field[0]->value[4] = strong;
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ drff->report->field[0]->value[0] = 0xfa;
+ drff->report->field[0]->value[1] = 0xfe;
+ } else {
+ drff->report->field[0]->value[0] = 0xf3;
+ drff->report->field[0]->value[1] = 0x00;
+ }
+
+ drff->report->field[0]->value[2] = 0x00;
+ drff->report->field[0]->value[4] = 0x00;
+ dbg_hid("running with 0x%02x 0x%02x", strong, weak);
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ return 0;
+}
+
+static int drff_init(struct hid_device *hid)
+{
+ struct drff_device *drff;
+ struct hid_report *report;
+ struct hid_input *hidinput = list_first_entry(&hid->inputs,
+ struct hid_input, list);
+ struct list_head *report_list =
+ &hid->report_enum[HID_OUTPUT_REPORT].report_list;
+ struct input_dev *dev = hidinput->input;
+ int error;
+
+ if (list_empty(report_list)) {
+ dev_err(&hid->dev, "no output reports found\n");
+ return -ENODEV;
+ }
+
+ report = list_first_entry(report_list, struct hid_report, list);
+ if (report->maxfield < 1) {
+ dev_err(&hid->dev, "no fields in the report\n");
+ return -ENODEV;
+ }
+
+ if (report->field[0]->report_count < 7) {
+ dev_err(&hid->dev, "not enough values in the field\n");
+ return -ENODEV;
+ }
+
+ drff = kzalloc(sizeof(struct drff_device), GFP_KERNEL);
+ if (!drff)
+ return -ENOMEM;
+
+ set_bit(FF_RUMBLE, dev->ffbit);
+
+ error = input_ff_create_memless(dev, drff, drff_play);
+ if (error) {
+ kfree(drff);
+ return error;
+ }
+
+ drff->report = report;
+ drff->report->field[0]->value[0] = 0xf3;
+ drff->report->field[0]->value[1] = 0x00;
+ drff->report->field[0]->value[2] = 0x00;
+ drff->report->field[0]->value[3] = 0x00;
+ drff->report->field[0]->value[4] = 0x00;
+ drff->report->field[0]->value[5] = 0x00;
+ drff->report->field[0]->value[6] = 0x00;
+ usbhid_submit_report(hid, drff->report, USB_DIR_OUT);
+
+ dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game "
+ "controllers by Richard Walmsley <richwalm@gmail.com>\n");
+
+ return 0;
+}
+
+static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id)
+{
+ int ret;
+
+ dev_dbg(&hdev->dev, "DragonRise Inc. HID hardware probe...");
+
+ ret = hid_parse(hdev);
+ if (ret) {
+ dev_err(&hdev->dev, "parse failed\n");
+ goto err;
+ }
+
+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF);
+ if (ret) {
+ dev_err(&hdev->dev, "hw start failed\n");
+ goto err;
+ }
+
+ drff_init(hdev);
+
+ return 0;
+err:
+ return ret;
+}
+
+static const struct hid_device_id dr_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_DRAGONRISE, 0x0006), },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, dr_devices);
+
+static struct hid_driver dr_driver = {
+ .name = "dragonrise",
+ .id_table = dr_devices,
+ .probe = dr_probe,
+};
+
+static int __init dr_init(void)
+{
+ return hid_register_driver(&dr_driver);
+}
+
+static void __exit dr_exit(void)
+{
+ hid_unregister_driver(&dr_driver);
+}
+
+module_init(dr_init);
+module_exit(dr_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-dummy.c b/drivers/hid/hid-dummy.c
deleted file mode 100644
index b4cc0f743d6..00000000000
--- a/drivers/hid/hid-dummy.c
+++ /dev/null
@@ -1,78 +0,0 @@
-#include <linux/autoconf.h>
-#include <linux/module.h>
-#include <linux/hid.h>
-
-static int __init hid_dummy_init(void)
-{
-#ifdef CONFIG_HID_A4TECH_MODULE
- HID_COMPAT_CALL_DRIVER(a4tech);
-#endif
-#ifdef CONFIG_HID_APPLE_MODULE
- HID_COMPAT_CALL_DRIVER(apple);
-#endif
-#ifdef CONFIG_HID_BELKIN_MODULE
- HID_COMPAT_CALL_DRIVER(belkin);
-#endif
-#ifdef CONFIG_HID_BRIGHT_MODULE
- HID_COMPAT_CALL_DRIVER(bright);
-#endif
-#ifdef CONFIG_HID_CHERRY_MODULE
- HID_COMPAT_CALL_DRIVER(cherry);
-#endif
-#ifdef CONFIG_HID_CHICONY_MODULE
- HID_COMPAT_CALL_DRIVER(chicony);
-#endif
-#ifdef CONFIG_HID_CYPRESS_MODULE
- HID_COMPAT_CALL_DRIVER(cypress);
-#endif
-#ifdef CONFIG_HID_DELL_MODULE
- HID_COMPAT_CALL_DRIVER(dell);
-#endif
-#ifdef CONFIG_HID_EZKEY_MODULE
- HID_COMPAT_CALL_DRIVER(ezkey);
-#endif
-#ifdef CONFIG_HID_GYRATION_MODULE
- HID_COMPAT_CALL_DRIVER(gyration);
-#endif
-#ifdef CONFIG_HID_LOGITECH_MODULE
- HID_COMPAT_CALL_DRIVER(logitech);
-#endif
-#ifdef CONFIG_HID_MICROSOFT_MODULE
- HID_COMPAT_CALL_DRIVER(microsoft);
-#endif
-#ifdef CONFIG_HID_MONTEREY_MODULE
- HID_COMPAT_CALL_DRIVER(monterey);
-#endif
-#ifdef CONFIG_HID_NTRIG_MODULE
- HID_COMPAT_CALL_DRIVER(ntrig);
-#endif
-#ifdef CONFIG_HID_PANTHERLORD_MODULE
- HID_COMPAT_CALL_DRIVER(pantherlord);
-#endif
-#ifdef CONFIG_HID_PETALYNX_MODULE
- HID_COMPAT_CALL_DRIVER(petalynx);
-#endif
-#ifdef CONFIG_HID_SAMSUNG_MODULE
- HID_COMPAT_CALL_DRIVER(samsung);
-#endif
-#ifdef CONFIG_HID_SONY_MODULE
- HID_COMPAT_CALL_DRIVER(sony);
-#endif
-#ifdef CONFIG_HID_SUNPLUS_MODULE
- HID_COMPAT_CALL_DRIVER(sunplus);
-#endif
-#ifdef CONFIG_GREENASIA_FF_MODULE
- HID_COMPAT_CALL_DRIVER(greenasia);
-#endif
-#ifdef CONFIG_THRUSTMASTER_FF_MODULE
- HID_COMPAT_CALL_DRIVER(thrustmaster);
-#endif
-#ifdef CONFIG_ZEROPLUS_FF_MODULE
- HID_COMPAT_CALL_DRIVER(zeroplus);
-#endif
-
- return -EIO;
-}
-module_init(hid_dummy_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-ezkey.c b/drivers/hid/hid-ezkey.c
index deb42f931b7..0a1fe054799 100644
--- a/drivers/hid/hid-ezkey.c
+++ b/drivers/hid/hid-ezkey.c
@@ -91,5 +91,3 @@ static void ez_exit(void)
module_init(ez_init);
module_exit(ez_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ezkey);
diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c
index 71211f6a4f0..510ad3ab8d3 100644
--- a/drivers/hid/hid-gaff.c
+++ b/drivers/hid/hid-gaff.c
@@ -181,5 +181,3 @@ static void __exit ga_exit(void)
module_init(ga_init);
module_exit(ga_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(greenasia);
diff --git a/drivers/hid/hid-gyration.c b/drivers/hid/hid-gyration.c
index 04a0afec52a..d42d222097a 100644
--- a/drivers/hid/hid-gyration.c
+++ b/drivers/hid/hid-gyration.c
@@ -94,5 +94,3 @@ static void gyration_exit(void)
module_init(gyration_init);
module_exit(gyration_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(gyration);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 88511970508..bdeda4c7cc1 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -67,6 +67,9 @@
#define USB_DEVICE_ID_APPLE_GEYSER4_ANSI 0x021a
#define USB_DEVICE_ID_APPLE_GEYSER4_ISO 0x021b
#define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ANSI 0x021d
+#define USB_DEVICE_ID_APPLE_ALU_MINI_ISO 0x021e
+#define USB_DEVICE_ID_APPLE_ALU_MINI_JIS 0x021f
#define USB_DEVICE_ID_APPLE_ALU_ANSI 0x0220
#define USB_DEVICE_ID_APPLE_ALU_ISO 0x0221
#define USB_DEVICE_ID_APPLE_ALU_JIS 0x0222
@@ -148,6 +151,8 @@
#define USB_VENDOR_ID_DMI 0x0c0b
#define USB_DEVICE_ID_DMI_ENC 0x5fab
+#define USB_VENDOR_ID_DRAGONRISE 0x0079
+
#define USB_VENDOR_ID_ELO 0x04E7
#define USB_DEVICE_ID_ELO_TS2700 0x0020
@@ -272,6 +277,9 @@
#define USB_DEVICE_ID_LD_POWERCONTROL 0x2030
#define USB_DEVICE_ID_LD_MACHINETEST 0x2040
+#define USB_VENDOR_ID_KENSINGTON 0x047d
+#define USB_DEVICE_ID_KS_SLIMBLADE 0x2041
+
#define USB_VENDOR_ID_LOGITECH 0x046d
#define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
#define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
@@ -418,6 +426,8 @@
#define USB_VENDOR_ID_ZEROPLUS 0x0c12
#define USB_VENDOR_ID_KYE 0x0458
+#define USB_DEVICE_ID_KYE_ERGO_525V 0x0087
#define USB_DEVICE_ID_KYE_GPEN_560 0x5003
+
#endif
diff --git a/drivers/hid/hid-kensington.c b/drivers/hid/hid-kensington.c
new file mode 100644
index 00000000000..7353bd79cbe
--- /dev/null
+++ b/drivers/hid/hid-kensington.c
@@ -0,0 +1,63 @@
+/*
+ * HID driver for Kensigton Slimblade Trackball
+ *
+ * Copyright (c) 2009 Jiri Kosina
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+#define ks_map_key(c) hid_map_usage(hi, usage, bit, max, EV_KEY, (c))
+
+static int ks_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+ struct hid_field *field, struct hid_usage *usage,
+ unsigned long **bit, int *max)
+{
+ if ((usage->hid & HID_USAGE_PAGE) != HID_UP_MSVENDOR)
+ return 0;
+
+ switch (usage->hid & HID_USAGE) {
+ case 0x01: ks_map_key(BTN_MIDDLE); break;
+ case 0x02: ks_map_key(BTN_SIDE); break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+static const struct hid_device_id ks_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_KENSINGTON, USB_DEVICE_ID_KS_SLIMBLADE) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, ks_devices);
+
+static struct hid_driver ks_driver = {
+ .name = "kensington",
+ .id_table = ks_devices,
+ .input_mapping = ks_input_mapping,
+};
+
+static int ks_init(void)
+{
+ return hid_register_driver(&ks_driver);
+}
+
+static void ks_exit(void)
+{
+ hid_unregister_driver(&ks_driver);
+}
+
+module_init(ks_init);
+module_exit(ks_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c
new file mode 100644
index 00000000000..72ee3fec56d
--- /dev/null
+++ b/drivers/hid/hid-kye.c
@@ -0,0 +1,69 @@
+/*
+ * HID driver for Kye/Genius devices not fully compliant with HID standard
+ *
+ * Copyright (c) 2009 Jiri Kosina
+ * Copyright (c) 2009 Tomas Hanak
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/device.h>
+#include <linux/hid.h>
+#include <linux/module.h>
+
+#include "hid-ids.h"
+
+/* the fixups that need to be done:
+ * - change led usage page to button for extra buttons
+ * - report size 8 count 1 must be size 1 count 8 for button bitfield
+ * - change the button usage range to 4-7 for the extra buttons
+ */
+static void kye_report_fixup(struct hid_device *hdev, __u8 *rdesc,
+ unsigned int rsize)
+{
+ if (rsize >= 74 &&
+ rdesc[61] == 0x05 && rdesc[62] == 0x08 &&
+ rdesc[63] == 0x19 && rdesc[64] == 0x08 &&
+ rdesc[65] == 0x29 && rdesc[66] == 0x0f &&
+ rdesc[71] == 0x75 && rdesc[72] == 0x08 &&
+ rdesc[73] == 0x95 && rdesc[74] == 0x01) {
+ dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report "
+ "descriptor\n");
+ rdesc[62] = 0x09;
+ rdesc[64] = 0x04;
+ rdesc[66] = 0x07;
+ rdesc[72] = 0x01;
+ rdesc[74] = 0x08;
+ }
+}
+
+static const struct hid_device_id kye_devices[] = {
+ { HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_ERGO_525V) },
+ { }
+};
+MODULE_DEVICE_TABLE(hid, kye_devices);
+
+static struct hid_driver kye_driver = {
+ .name = "kye",
+ .id_table = kye_devices,
+ .report_fixup = kye_report_fixup,
+};
+
+static int kye_init(void)
+{
+ return hid_register_driver(&kye_driver);
+}
+
+static void kye_exit(void)
+{
+ hid_unregister_driver(&kye_driver);
+}
+
+module_init(kye_init);
+module_exit(kye_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c
index 83e07c9f414..7b80cb69498 100644
--- a/drivers/hid/hid-lg.c
+++ b/drivers/hid/hid-lg.c
@@ -326,5 +326,3 @@ static void lg_exit(void)
module_init(lg_init);
module_exit(lg_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(logitech);
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 25b10dcad90..5e9e37a0506 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -210,5 +210,3 @@ static void ms_exit(void)
module_init(ms_init);
module_exit(ms_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(microsoft);
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c
index f3a85a065f1..240f87618be 100644
--- a/drivers/hid/hid-monterey.c
+++ b/drivers/hid/hid-monterey.c
@@ -78,5 +78,3 @@ static void mr_exit(void)
module_init(mr_init);
module_exit(mr_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(monterey);
diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c
index db44fbd7bdf..c5b252be9c2 100644
--- a/drivers/hid/hid-ntrig.c
+++ b/drivers/hid/hid-ntrig.c
@@ -78,5 +78,3 @@ static void ntrig_exit(void)
module_init(ntrig_init);
module_exit(ntrig_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(ntrig);
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c
index 10945fe12d5..2e83e8ff891 100644
--- a/drivers/hid/hid-petalynx.c
+++ b/drivers/hid/hid-petalynx.c
@@ -118,5 +118,3 @@ static void pl_exit(void)
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(petalynx);
diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c
index 46941f979b9..4db9a348376 100644
--- a/drivers/hid/hid-pl.c
+++ b/drivers/hid/hid-pl.c
@@ -9,9 +9,12 @@
* - contains two reports, one for each port (HID_QUIRK_MULTI_INPUT)
*
* 0e8f:0003 "GreenAsia Inc. USB Joystick "
- * - tested with K??ng Gaming gamepad
+ * - tested with König Gaming gamepad
*
- * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com>
+ * 0e8f:0003 "GASIA USB Gamepad"
+ * - another version of the König gamepad
+ *
+ * Copyright (c) 2007, 2009 Anssi Hannula <anssi.hannula@gmail.com>
*/
/*
@@ -46,6 +49,8 @@
struct plff_device {
struct hid_report *report;
+ s32 *strong;
+ s32 *weak;
};
static int hid_plff_play(struct input_dev *dev, void *data,
@@ -62,8 +67,8 @@ static int hid_plff_play(struct input_dev *dev, void *data,
left = left * 0x7f / 0xffff;
right = right * 0x7f / 0xffff;
- plff->report->field[0]->value[2] = left;
- plff->report->field[0]->value[3] = right;
+ *plff->strong = left;
+ *plff->weak = right;
debug("running with 0x%02x 0x%02x", left, right);
usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
@@ -80,6 +85,8 @@ static int plff_init(struct hid_device *hid)
struct list_head *report_ptr = report_list;
struct input_dev *dev;
int error;
+ s32 *strong;
+ s32 *weak;
/* The device contains one output report per physical device, all
containing 1 field, which contains 4 ff00.0002 usages and 4 16bit
@@ -87,7 +94,12 @@ static int plff_init(struct hid_device *hid)
The input reports also contain a field which contains
8 ff00.0001 usages and 8 boolean values. Their meaning is
- currently unknown. */
+ currently unknown.
+
+ A version of the 0e8f:0003 exists that has all the values in
+ separate fields and misses the extra input field, thus resembling
+ Zeroplus (hid-zpff) devices.
+ */
if (list_empty(report_list)) {
dev_err(&hid->dev, "no output reports found\n");
@@ -110,8 +122,21 @@ static int plff_init(struct hid_device *hid)
return -ENODEV;
}
- if (report->field[0]->report_count < 4) {
- dev_err(&hid->dev, "not enough values in the field\n");
+ if (report->field[0]->report_count >= 4) {
+ report->field[0]->value[0] = 0x00;
+ report->field[0]->value[1] = 0x00;
+ strong = &report->field[0]->value[2];
+ weak = &report->field[0]->value[3];
+ debug("detected single-field device");
+ } else if (report->maxfield >= 4 && report->field[0]->maxusage == 1 &&
+ report->field[0]->usage[0].hid == (HID_UP_LED | 0x43)) {
+ report->field[0]->value[0] = 0x00;
+ report->field[1]->value[0] = 0x00;
+ strong = &report->field[2]->value[0];
+ weak = &report->field[3]->value[0];
+ debug("detected 4-field device");
+ } else {
+ dev_err(&hid->dev, "not enough fields or values\n");
return -ENODEV;
}
@@ -130,10 +155,11 @@ static int plff_init(struct hid_device *hid)
}
plff->report = report;
- plff->report->field[0]->value[0] = 0x00;
- plff->report->field[0]->value[1] = 0x00;
- plff->report->field[0]->value[2] = 0x00;
- plff->report->field[0]->value[3] = 0x00;
+ plff->strong = strong;
+ plff->weak = weak;
+
+ *strong = 0x00;
+ *weak = 0x00;
usbhid_submit_report(hid, plff->report, USB_DIR_OUT);
}
@@ -180,7 +206,7 @@ static const struct hid_device_id pl_devices[] = {
.driver_data = 1 }, /* Twin USB Joystick */
{ HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR),
.driver_data = 1 }, /* Twin USB Joystick */
- { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), }, /* GreenAsia Inc. USB Joystick */
+ { HID_USB_DEVICE(USB_VENDOR_ID_GREENASIA, 0x0003), },
{ }
};
MODULE_DEVICE_TABLE(hid, pl_devices);
@@ -204,5 +230,3 @@ static void pl_exit(void)
module_init(pl_init);
module_exit(pl_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(pantherlord);
diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c
index 15f3c049245..07083aa6c19 100644
--- a/drivers/hid/hid-samsung.c
+++ b/drivers/hid/hid-samsung.c
@@ -96,5 +96,3 @@ static void samsung_exit(void)
module_init(samsung_init);
module_exit(samsung_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(samsung);
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index dd5a3979a4d..c2599388a35 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -148,5 +148,3 @@ static void sony_exit(void)
module_init(sony_init);
module_exit(sony_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sony);
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c
index 5ba68f7dbb7..e0a8fd36a85 100644
--- a/drivers/hid/hid-sunplus.c
+++ b/drivers/hid/hid-sunplus.c
@@ -78,5 +78,3 @@ static void sp_exit(void)
module_init(sp_init);
module_exit(sp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(sunplus);
diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c
index 1b7cba0f7e1..7c1f7b50330 100644
--- a/drivers/hid/hid-tmff.c
+++ b/drivers/hid/hid-tmff.c
@@ -265,5 +265,3 @@ static void tm_exit(void)
module_init(tm_init);
module_exit(tm_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(thrustmaster);
diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c
index cca64a0564a..152ccfabeba 100644
--- a/drivers/hid/hid-topseed.c
+++ b/drivers/hid/hid-topseed.c
@@ -73,5 +73,3 @@ static void ts_exit(void)
module_init(ts_init);
module_exit(ts_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(topseed);
diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c
index ea82f3718b2..85a198a1853 100644
--- a/drivers/hid/hid-zpff.c
+++ b/drivers/hid/hid-zpff.c
@@ -158,5 +158,3 @@ static void zp_exit(void)
module_init(zp_init);
module_exit(zp_exit);
MODULE_LICENSE("GPL");
-
-HID_COMPAT_LOAD_DRIVER(zeroplus);
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 02b19db5442..e263d473117 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -181,9 +181,17 @@ static int hidraw_open(struct inode *inode, struct file *file)
dev = hidraw_table[minor];
if (!dev->open++) {
+ if (dev->hid->ll_driver->power) {
+ err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON);
+ if (err < 0)
+ goto out_unlock;
+ }
err = dev->hid->ll_driver->open(dev->hid);
- if (err < 0)
+ if (err < 0) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->open--;
+ }
}
out_unlock:
@@ -209,10 +217,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
list_del(&list->node);
dev = hidraw_table[minor];
if (!--dev->open) {
- if (list->hidraw->exist)
+ if (list->hidraw->exist) {
+ if (dev->hid->ll_driver->power)
+ dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL);
dev->hid->ll_driver->close(dev->hid);
- else
+ } else {
kfree(list->hidraw);
+ }
}
kfree(list);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c
index f0a0f72238a..4306cb1b8ce 100644
--- a/drivers/hid/usbhid/hid-core.c
+++ b/drivers/hid/usbhid/hid-core.c
@@ -5,6 +5,7 @@
* Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz>
* Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc
* Copyright (c) 2006-2008 Jiri Kosina
+ * Copyright (c) 2007-2008 Oliver Neukum
*/
/*
@@ -27,6 +28,7 @@
#include <asm/byteorder.h>
#include <linux/input.h>
#include <linux/wait.h>
+#include <linux/workqueue.h>
#include <linux/usb.h>
@@ -53,6 +55,10 @@ static unsigned int hid_mousepoll_interval;
module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644);
MODULE_PARM_DESC(mousepoll, "Polling interval of mice");
+static unsigned int ignoreled;
+module_param_named(ignoreled, ignoreled, uint, 0644);
+MODULE_PARM_DESC(ignoreled, "Autosuspend with active leds");
+
/* Quirks specified at module load time */
static char *quirks_param[MAX_USBHID_BOOT_QUIRKS] = { [ 0 ... (MAX_USBHID_BOOT_QUIRKS - 1) ] = NULL };
module_param_array_named(quirks, quirks_param, charp, NULL, 0444);
@@ -63,8 +69,13 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
/*
* Input submission and I/O error handler.
*/
+static DEFINE_MUTEX(hid_open_mut);
+static struct workqueue_struct *resumption_waker;
static void hid_io_error(struct hid_device *hid);
+static int hid_submit_out(struct hid_device *hid);
+static int hid_submit_ctrl(struct hid_device *hid);
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid);
/* Start up the input URB */
static int hid_start_in(struct hid_device *hid)
@@ -73,15 +84,16 @@ static int hid_start_in(struct hid_device *hid)
int rc = 0;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
- if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) &&
+ spin_lock_irqsave(&usbhid->lock, flags);
+ if (hid->open > 0 &&
!test_bit(HID_DISCONNECTED, &usbhid->iofl) &&
+ !test_bit(HID_REPORTED_IDLE, &usbhid->iofl) &&
!test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) {
rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC);
if (rc != 0)
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
}
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return rc;
}
@@ -145,7 +157,7 @@ static void hid_io_error(struct hid_device *hid)
unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
- spin_lock_irqsave(&usbhid->inlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
/* Stop when disconnected */
if (test_bit(HID_DISCONNECTED, &usbhid->iofl))
@@ -175,7 +187,51 @@ static void hid_io_error(struct hid_device *hid)
mod_timer(&usbhid->io_retry,
jiffies + msecs_to_jiffies(usbhid->retry_delay));
done:
- spin_unlock_irqrestore(&usbhid->inlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+}
+
+static void usbhid_mark_busy(struct usbhid_device *usbhid)
+{
+ struct usb_interface *intf = usbhid->intf;
+
+ usb_mark_last_busy(interface_to_usbdev(intf));
+}
+
+static int usbhid_restart_out_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->outhead != usbhid->outtail))) {
+ dbg("Kicking head %d tail %d", usbhid->outhead, usbhid->outtail);
+ if (hid_submit_out(hid)) {
+ clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
+}
+
+static int usbhid_restart_ctrl_queue(struct usbhid_device *usbhid)
+{
+ struct hid_device *hid = usb_get_intfdata(usbhid->intf);
+ int kicked;
+
+ WARN_ON(hid == NULL);
+ if (!hid)
+ return 0;
+
+ if ((kicked = (usbhid->ctrlhead != usbhid->ctrltail))) {
+ dbg("Kicking head %d tail %d", usbhid->ctrlhead, usbhid->ctrltail);
+ if (hid_submit_ctrl(hid)) {
+ clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+ wake_up(&usbhid->wait);
+ }
+ }
+ return kicked;
}
/*
@@ -190,12 +246,23 @@ static void hid_irq_in(struct urb *urb)
switch (urb->status) {
case 0: /* success */
+ usbhid_mark_busy(usbhid);
usbhid->retry_delay = 0;
hid_input_report(urb->context, HID_INPUT_REPORT,
urb->transfer_buffer,
urb->actual_length, 1);
+ /*
+ * autosuspend refused while keys are pressed
+ * because most keyboards don't wake up when
+ * a key is released
+ */
+ if (hid_check_keys_pressed(hid))
+ set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
+ else
+ clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
break;
case -EPIPE: /* stall */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
set_bit(HID_CLEAR_HALT, &usbhid->iofl);
schedule_work(&usbhid->reset_work);
@@ -209,6 +276,7 @@ static void hid_irq_in(struct urb *urb)
case -EPROTO: /* protocol error or unplug */
case -ETIME: /* protocol error or unplug */
case -ETIMEDOUT: /* Should never happen, but... */
+ usbhid_mark_busy(usbhid);
clear_bit(HID_IN_RUNNING, &usbhid->iofl);
hid_io_error(hid);
return;
@@ -239,16 +307,25 @@ static int hid_submit_out(struct hid_device *hid)
report = usbhid->out[usbhid->outtail].report;
raw_report = usbhid->out[usbhid->outtail].raw_report;
- usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- usbhid->urbout->dev = hid_to_usb_dev(hid);
- memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
- kfree(raw_report);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ usbhid->urbout->dev = hid_to_usb_dev(hid);
+ memcpy(usbhid->outbuf, raw_report, usbhid->urbout->transfer_buffer_length);
+ kfree(raw_report);
- dbg_hid("submitting out urb\n");
+ dbg_hid("submitting out urb\n");
- if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(out) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(out) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -266,41 +343,50 @@ static int hid_submit_ctrl(struct hid_device *hid)
raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
dir = usbhid->ctrl[usbhid->ctrltail].dir;
- len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
- if (dir == USB_DIR_OUT) {
- usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
- usbhid->urbctrl->transfer_buffer_length = len;
- memcpy(usbhid->ctrlbuf, raw_report, len);
- kfree(raw_report);
- } else {
- int maxpacket, padlen;
-
- usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
- maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
- if (maxpacket > 0) {
- padlen = DIV_ROUND_UP(len, maxpacket);
- padlen *= maxpacket;
- if (padlen > usbhid->bufsize)
- padlen = usbhid->bufsize;
- } else
- padlen = 0;
- usbhid->urbctrl->transfer_buffer_length = padlen;
- }
- usbhid->urbctrl->dev = hid_to_usb_dev(hid);
+ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
+ len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
+ if (dir == USB_DIR_OUT) {
+ usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0);
+ usbhid->urbctrl->transfer_buffer_length = len;
+ memcpy(usbhid->ctrlbuf, raw_report, len);
+ kfree(raw_report);
+ } else {
+ int maxpacket, padlen;
+
+ usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0);
+ maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0);
+ if (maxpacket > 0) {
+ padlen = DIV_ROUND_UP(len, maxpacket);
+ padlen *= maxpacket;
+ if (padlen > usbhid->bufsize)
+ padlen = usbhid->bufsize;
+ } else
+ padlen = 0;
+ usbhid->urbctrl->transfer_buffer_length = padlen;
+ }
+ usbhid->urbctrl->dev = hid_to_usb_dev(hid);
- usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
- usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
- usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
- usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
- usbhid->cr->wLength = cpu_to_le16(len);
+ usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir;
+ usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT;
+ usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id);
+ usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum);
+ usbhid->cr->wLength = cpu_to_le16(len);
- dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
- usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
- usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
+ dbg_hid("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u\n",
+ usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report",
+ usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
- if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
- err_hid("usb_submit_urb(ctrl) failed");
- return -1;
+ if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
+ err_hid("usb_submit_urb(ctrl) failed");
+ return -1;
+ }
+ } else {
+ /*
+ * queue work to wake up the device.
+ * as the work queue is freezeable, this is safe
+ * with respect to STD and STR
+ */
+ queue_work(resumption_waker, &usbhid->restart_work);
}
return 0;
@@ -332,7 +418,7 @@ static void hid_irq_out(struct urb *urb)
"received\n", urb->status);
}
- spin_lock_irqsave(&usbhid->outlock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
if (unplug)
usbhid->outtail = usbhid->outhead;
@@ -344,12 +430,12 @@ static void hid_irq_out(struct urb *urb)
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
return;
}
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->outlock, flags);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
wake_up(&usbhid->wait);
}
@@ -361,12 +447,11 @@ static void hid_ctrl(struct urb *urb)
{
struct hid_device *hid = urb->context;
struct usbhid_device *usbhid = hid->driver_data;
- unsigned long flags;
- int unplug = 0;
+ int unplug = 0, status = urb->status;
- spin_lock_irqsave(&usbhid->ctrllock, flags);
+ spin_lock(&usbhid->lock);
- switch (urb->status) {
+ switch (status) {
case 0: /* success */
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN)
hid_input_report(urb->context,
@@ -383,7 +468,7 @@ static void hid_ctrl(struct urb *urb)
break;
default: /* error */
dev_warn(&urb->dev->dev, "ctrl urb status %d "
- "received\n", urb->status);
+ "received\n", status);
}
if (unplug)
@@ -396,19 +481,18 @@ static void hid_ctrl(struct urb *urb)
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
wake_up(&usbhid->wait);
}
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
return;
}
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_unlock(&usbhid->lock);
wake_up(&usbhid->wait);
}
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+void __usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
{
int head;
- unsigned long flags;
struct usbhid_device *usbhid = hid->driver_data;
int len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
@@ -416,18 +500,13 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
return;
if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
-
- spin_lock_irqsave(&usbhid->outlock, flags);
-
if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queue full\n");
return;
}
usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->out[usbhid->outhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->outlock, flags);
dev_warn(&hid->dev, "output queueing failed\n");
return;
}
@@ -438,15 +517,10 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl))
if (hid_submit_out(hid))
clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
-
- spin_unlock_irqrestore(&usbhid->outlock, flags);
return;
}
- spin_lock_irqsave(&usbhid->ctrllock, flags);
-
if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queue full\n");
return;
}
@@ -454,7 +528,6 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (dir == USB_DIR_OUT) {
usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
dev_warn(&hid->dev, "control queueing failed\n");
return;
}
@@ -467,15 +540,25 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl))
if (hid_submit_ctrl(hid))
clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
+}
+
+void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+ unsigned long flags;
- spin_unlock_irqrestore(&usbhid->ctrllock, flags);
+ spin_lock_irqsave(&usbhid->lock, flags);
+ __usbhid_submit_report(hid, report, dir);
+ spin_unlock_irqrestore(&usbhid->lock, flags);
}
EXPORT_SYMBOL_GPL(usbhid_submit_report);
static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
struct hid_device *hid = input_get_drvdata(dev);
+ struct usbhid_device *usbhid = hid->driver_data;
struct hid_field *field;
+ unsigned long flags;
int offset;
if (type == EV_FF)
@@ -490,6 +573,15 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un
}
hid_set_field(field, offset, value);
+ if (value) {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount++;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ } else {
+ spin_lock_irqsave(&usbhid->lock, flags);
+ usbhid->ledcount--;
+ spin_unlock_irqrestore(&usbhid->lock, flags);
+ }
usbhid_submit_report(hid, field->report, USB_DIR_OUT);
return 0;
@@ -538,15 +630,22 @@ int usbhid_open(struct hid_device *hid)
struct usbhid_device *usbhid = hid->driver_data;
int res;
+ mutex_lock(&hid_open_mut);
if (!hid->open++) {
res = usb_autopm_get_interface(usbhid->intf);
+ /* the device must be awake to reliable request remote wakeup */
if (res < 0) {
hid->open--;
+ mutex_unlock(&hid_open_mut);
return -EIO;
}
+ usbhid->intf->needs_remote_wakeup = 1;
+ if (hid_start_in(hid))
+ hid_io_error(hid);
+
+ usb_autopm_put_interface(usbhid->intf);
}
- if (hid_start_in(hid))
- hid_io_error(hid);
+ mutex_unlock(&hid_open_mut);
return 0;
}
@@ -554,10 +653,22 @@ void usbhid_close(struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
+ mutex_lock(&hid_open_mut);
+
+ /* protecting hid->open to make sure we don't restart
+ * data acquistion due to a resumption we no longer
+ * care about
+ */
+ spin_lock_irq(&usbhid->lock);
if (!--hid->open) {
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
- usb_autopm_put_interface(usbhid->intf);
+ flush_scheduled_work();
+ usbhid->intf->needs_remote_wakeup = 0;
+ } else {
+ spin_unlock_irq(&usbhid->lock);
}
+ mutex_unlock(&hid_open_mut);
}
/*
@@ -687,6 +798,25 @@ static int usbhid_output_raw_report(struct hid_device *hid, __u8 *buf, size_t co
return ret;
}
+static void usbhid_restart_queues(struct usbhid_device *usbhid)
+{
+ if (usbhid->urbout)
+ usbhid_restart_out_queue(usbhid);
+ usbhid_restart_ctrl_queue(usbhid);
+}
+
+static void __usbhid_restart_queues(struct work_struct *work)
+{
+ struct usbhid_device *usbhid =
+ container_of(work, struct usbhid_device, restart_work);
+ int r;
+
+ r = usb_autopm_get_interface(usbhid->intf);
+ if (r < 0)
+ return;
+ usb_autopm_put_interface(usbhid->intf);
+}
+
static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
{
struct usbhid_device *usbhid = hid->driver_data;
@@ -711,6 +841,9 @@ static int usbhid_parse(struct hid_device *hid)
quirks = usbhid_lookup_quirk(le16_to_cpu(dev->descriptor.idVendor),
le16_to_cpu(dev->descriptor.idProduct));
+ if (quirks & HID_QUIRK_IGNORE)
+ return -ENODEV;
+
/* Many keyboards and mice don't like to be polled for reports,
* so we will always set the HID_QUIRK_NOGET flag for them. */
if (interface->desc.bInterfaceSubClass == USB_INTERFACE_SUBCLASS_BOOT) {
@@ -850,11 +983,11 @@ static int usbhid_start(struct hid_device *hid)
init_waitqueue_head(&usbhid->wait);
INIT_WORK(&usbhid->reset_work, hid_reset);
+ INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
- spin_lock_init(&usbhid->inlock);
- spin_lock_init(&usbhid->outlock);
- spin_lock_init(&usbhid->ctrllock);
+ spin_lock_init(&usbhid->lock);
+ spin_lock_init(&usbhid->lock);
usbhid->intf = intf;
usbhid->ifnum = interface->desc.bInterfaceNumber;
@@ -906,15 +1039,14 @@ static void usbhid_stop(struct hid_device *hid)
return;
clear_bit(HID_STARTED, &usbhid->iofl);
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
set_bit(HID_DISCONNECTED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
+ spin_unlock_irq(&usbhid->lock);
usb_kill_urb(usbhid->urbin);
usb_kill_urb(usbhid->urbout);
usb_kill_urb(usbhid->urbctrl);
- del_timer_sync(&usbhid->io_retry);
- cancel_work_sync(&usbhid->reset_work);
+ hid_cancel_delayed_stuff(usbhid);
if (hid->claimed & HID_CLAIMED_INPUT)
hidinput_disconnect(hid);
@@ -935,12 +1067,28 @@ static void usbhid_stop(struct hid_device *hid)
hid_free_buffers(hid_to_usb_dev(hid), hid);
}
+static int usbhid_power(struct hid_device *hid, int lvl)
+{
+ int r = 0;
+
+ switch (lvl) {
+ case PM_HINT_FULLON:
+ r = usbhid_get_power(hid);
+ break;
+ case PM_HINT_NORMAL:
+ usbhid_put_power(hid);
+ break;
+ }
+ return r;
+}
+
static struct hid_ll_driver usb_hid_driver = {
.parse = usbhid_parse,
.start = usbhid_start,
.stop = usbhid_stop,
.open = usbhid_open,
.close = usbhid_close,
+ .power = usbhid_power,
.hidinput_input_event = usb_hidinput_input_event,
};
@@ -1049,19 +1197,126 @@ static void hid_disconnect(struct usb_interface *intf)
kfree(usbhid);
}
+static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
+{
+ del_timer_sync(&usbhid->io_retry);
+ cancel_work_sync(&usbhid->restart_work);
+ cancel_work_sync(&usbhid->reset_work);
+}
+
+static void hid_cease_io(struct usbhid_device *usbhid)
+{
+ del_timer(&usbhid->io_retry);
+ usb_kill_urb(usbhid->urbin);
+ usb_kill_urb(usbhid->urbctrl);
+ usb_kill_urb(usbhid->urbout);
+}
+
+/* Treat USB reset pretty much the same as suspend/resume */
+static int hid_pre_reset(struct usb_interface *intf)
+{
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ cancel_work_sync(&usbhid->restart_work);
+ hid_cease_io(usbhid);
+
+ return 0;
+}
+
+/* Same routine used for post_reset and reset_resume */
+static int hid_post_reset(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
+ int status;
+
+ spin_lock_irq(&usbhid->lock);
+ clear_bit(HID_RESET_PENDING, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
+ /* FIXME: Any more reinitialization needed? */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
+
+ return 0;
+}
+
+int usbhid_get_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ return usb_autopm_get_interface(usbhid->intf);
+}
+
+void usbhid_put_power(struct hid_device *hid)
+{
+ struct usbhid_device *usbhid = hid->driver_data;
+
+ usb_autopm_put_interface(usbhid->intf);
+}
+
+
+#ifdef CONFIG_PM
static int hid_suspend(struct usb_interface *intf, pm_message_t message)
{
- struct hid_device *hid = usb_get_intfdata (intf);
+ struct hid_device *hid = usb_get_intfdata(intf);
struct usbhid_device *usbhid = hid->driver_data;
+ struct usb_device *udev = interface_to_usbdev(intf);
+ int status;
- if (!test_bit(HID_STARTED, &usbhid->iofl))
- return 0;
+ if (udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock); /* Sync with error handler */
+ if (!test_bit(HID_RESET_PENDING, &usbhid->iofl)
+ && !test_bit(HID_CLEAR_HALT, &usbhid->iofl)
+ && !test_bit(HID_OUT_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_CTRL_RUNNING, &usbhid->iofl)
+ && !test_bit(HID_KEYS_PRESSED, &usbhid->iofl)
+ && (!usbhid->ledcount || ignoreled))
+ {
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ } else {
+ usbhid_mark_busy(usbhid);
+ spin_unlock_irq(&usbhid->lock);
+ return -EBUSY;
+ }
- spin_lock_irq(&usbhid->inlock); /* Sync with error handler */
- set_bit(HID_SUSPENDED, &usbhid->iofl);
- spin_unlock_irq(&usbhid->inlock);
- del_timer_sync(&usbhid->io_retry);
- usb_kill_urb(usbhid->urbin);
+ } else {
+ spin_lock_irq(&usbhid->lock);
+ set_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ spin_unlock_irq(&usbhid->lock);
+ if (usbhid_wait_io(hid) < 0)
+ return -EIO;
+ }
+
+ if (!ignoreled && udev->auto_pm) {
+ spin_lock_irq(&usbhid->lock);
+ if (test_bit(HID_LED_ON, &usbhid->iofl)) {
+ spin_unlock_irq(&usbhid->lock);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
+ spin_unlock_irq(&usbhid->lock);
+ }
+
+ hid_cancel_delayed_stuff(usbhid);
+ hid_cease_io(usbhid);
+
+ if (udev->auto_pm && test_bit(HID_KEYS_PRESSED, &usbhid->iofl)) {
+ /* lost race against keypresses */
+ status = hid_start_in(hid);
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_mark_busy(usbhid);
+ return -EBUSY;
+ }
dev_dbg(&intf->dev, "suspend\n");
return 0;
}
@@ -1075,32 +1330,33 @@ static int hid_resume(struct usb_interface *intf)
if (!test_bit(HID_STARTED, &usbhid->iofl))
return 0;
- clear_bit(HID_SUSPENDED, &usbhid->iofl);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ usbhid_mark_busy(usbhid);
+
+ if (test_bit(HID_CLEAR_HALT, &usbhid->iofl) ||
+ test_bit(HID_RESET_PENDING, &usbhid->iofl))
+ schedule_work(&usbhid->reset_work);
usbhid->retry_delay = 0;
status = hid_start_in(hid);
- dev_dbg(&intf->dev, "resume status %d\n", status);
- return status;
-}
+ if (status < 0)
+ hid_io_error(hid);
+ usbhid_restart_queues(usbhid);
-/* Treat USB reset pretty much the same as suspend/resume */
-static int hid_pre_reset(struct usb_interface *intf)
-{
- /* FIXME: What if the interface is already suspended? */
- hid_suspend(intf, PMSG_ON);
+ dev_dbg(&intf->dev, "resume status %d\n", status);
return 0;
}
-/* Same routine used for post_reset and reset_resume */
-static int hid_post_reset(struct usb_interface *intf)
+static int hid_reset_resume(struct usb_interface *intf)
{
- struct usb_device *dev = interface_to_usbdev (intf);
-
- hid_set_idle(dev, intf->cur_altsetting->desc.bInterfaceNumber, 0, 0);
- /* FIXME: Any more reinitialization needed? */
+ struct hid_device *hid = usb_get_intfdata(intf);
+ struct usbhid_device *usbhid = hid->driver_data;
- return hid_resume(intf);
+ clear_bit(HID_REPORTED_IDLE, &usbhid->iofl);
+ return hid_post_reset(intf);
}
+#endif /* CONFIG_PM */
+
static struct usb_device_id hid_usb_ids [] = {
{ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
.bInterfaceClass = USB_INTERFACE_CLASS_HID },
@@ -1113,9 +1369,11 @@ static struct usb_driver hid_driver = {
.name = "usbhid",
.probe = hid_probe,
.disconnect = hid_disconnect,
+#ifdef CONFIG_PM
.suspend = hid_suspend,
.resume = hid_resume,
- .reset_resume = hid_post_reset,
+ .reset_resume = hid_reset_resume,
+#endif
.pre_reset = hid_pre_reset,
.post_reset = hid_post_reset,
.id_table = hid_usb_ids,
@@ -1134,7 +1392,11 @@ static struct hid_driver hid_usb_driver = {
static int __init hid_init(void)
{
- int retval;
+ int retval = -ENOMEM;
+
+ resumption_waker = create_freezeable_workqueue("usbhid_resumer");
+ if (!resumption_waker)
+ goto no_queue;
retval = hid_register_driver(&hid_usb_driver);
if (retval)
goto hid_register_fail;
@@ -1158,6 +1420,8 @@ hiddev_init_fail:
usbhid_quirks_init_fail:
hid_unregister_driver(&hid_usb_driver);
hid_register_fail:
+ destroy_workqueue(resumption_waker);
+no_queue:
return retval;
}
@@ -1167,6 +1431,7 @@ static void __exit hid_exit(void)
hiddev_exit();
usbhid_quirks_exit();
hid_unregister_driver(&hid_usb_driver);
+ destroy_workqueue(resumption_waker);
}
module_init(hid_init);
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index aa214170baf..e9b436d2d94 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -246,10 +246,12 @@ static int hiddev_release(struct inode * inode, struct file * file)
spin_unlock_irqrestore(&list->hiddev->list_lock, flags);
if (!--list->hiddev->open) {
- if (list->hiddev->exist)
+ if (list->hiddev->exist) {
usbhid_close(list->hiddev->hid);
- else
+ usbhid_put_power(list->hiddev->hid);
+ } else {
kfree(list->hiddev);
+ }
}
kfree(list);
@@ -300,6 +302,17 @@ static int hiddev_open(struct inode *inode, struct file *file)
list_add_tail(&list->node, &hiddev_table[i]->list);
spin_unlock_irq(&list->hiddev->list_lock);
+ if (!list->hiddev->open++)
+ if (list->hiddev->exist) {
+ struct hid_device *hid = hiddev_table[i]->hid;
+ res = usbhid_get_power(hid);
+ if (res < 0) {
+ res = -EIO;
+ goto bail;
+ }
+ usbhid_open(hid);
+ }
+
return 0;
bail:
file->private_data = NULL;
@@ -875,16 +888,21 @@ int hiddev_connect(struct hid_device *hid, unsigned int force)
hiddev->hid = hid;
hiddev->exist = 1;
+ /* when lock_kernel() usage is fixed in usb_open(),
+ * we could also fix it here */
+ lock_kernel();
retval = usb_register_dev(usbhid->intf, &hiddev_class);
if (retval) {
err_hid("Not able to get a minor for this device.");
hid->hiddev = NULL;
+ unlock_kernel();
kfree(hiddev);
return -1;
} else {
hid->minor = usbhid->intf->minor;
hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev;
}
+ unlock_kernel();
return 0;
}
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h
index 9eb30564be9..08f505ca2e3 100644
--- a/drivers/hid/usbhid/usbhid.h
+++ b/drivers/hid/usbhid/usbhid.h
@@ -38,7 +38,10 @@ int usbhid_wait_io(struct hid_device* hid);
void usbhid_close(struct hid_device *hid);
int usbhid_open(struct hid_device *hid);
void usbhid_init_reports(struct hid_device *hid);
-void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+void usbhid_submit_report
+(struct hid_device *hid, struct hid_report *report, unsigned char dir);
+int usbhid_get_power(struct hid_device *hid);
+void usbhid_put_power(struct hid_device *hid);
/* iofl flags */
#define HID_CTRL_RUNNING 1
@@ -49,6 +52,9 @@ void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, uns
#define HID_CLEAR_HALT 6
#define HID_DISCONNECTED 7
#define HID_STARTED 8
+#define HID_REPORTED_IDLE 9
+#define HID_KEYS_PRESSED 10
+#define HID_LED_ON 11
/*
* USB-specific HID struct, to be pointed to
@@ -66,7 +72,6 @@ struct usbhid_device {
struct urb *urbin; /* Input URB */
char *inbuf; /* Input buffer */
dma_addr_t inbuf_dma; /* Input buffer dma */
- spinlock_t inlock; /* Input fifo spinlock */
struct urb *urbctrl; /* Control URB */
struct usb_ctrlrequest *cr; /* Control request struct */
@@ -75,21 +80,22 @@ struct usbhid_device {
unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */
char *ctrlbuf; /* Control buffer */
dma_addr_t ctrlbuf_dma; /* Control buffer dma */
- spinlock_t ctrllock; /* Control fifo spinlock */
struct urb *urbout; /* Output URB */
struct hid_output_fifo out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */
unsigned char outhead, outtail; /* Output pipe fifo head & tail */
char *outbuf; /* Output buffer */
dma_addr_t outbuf_dma; /* Output buffer dma */
- spinlock_t outlock; /* Output fifo spinlock */
+ spinlock_t lock; /* fifo spinlock */
unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */
struct timer_list io_retry; /* Retry timer */
unsigned long stop_retry; /* Time to give up, in jiffies */
unsigned int retry_delay; /* Delay length in ms */
struct work_struct reset_work; /* Task context for resets */
+ struct work_struct restart_work; /* waking up for output to be done in a task */
wait_queue_head_t wait; /* For sleeping */
+ int ledcount; /* counting the number of active leds */
};
#define hid_to_usb_dev(hid_dev) \
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index b4eea0292c1..ce52bf2f235 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -343,12 +343,13 @@ config SENSORS_FSCPOS
will be called fscpos.
config SENSORS_FSCHMD
- tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles"
+ tristate "Fujitsu Siemens Computers sensor chips"
depends on X86 && I2C
help
- If you say yes here you get support for various Fujitsu Siemens
- Computers sensor chips, including support for the integrated
- watchdog.
+ If you say yes here you get support for the following Fujitsu
+ Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes,
+ Heimdall, Heracles, Hades and Syleus including support for the
+ integrated watchdog.
This is a merged driver for FSC sensor chips replacing the fscpos,
fscscy and fscher drivers and adding support for several other FSC
@@ -570,6 +571,17 @@ config SENSORS_LM93
This driver can also be built as a module. If so, the module
will be called lm93.
+config SENSORS_LTC4215
+ tristate "Linear Technology LTC4215"
+ depends on I2C && EXPERIMENTAL
+ default n
+ help
+ If you say yes here you get support for Linear Technology LTC4215
+ Hot Swap Controller I2C interface.
+
+ This driver can also be built as a module. If so, the module will
+ be called ltc4215.
+
config SENSORS_LTC4245
tristate "Linear Technology LTC4245"
depends on I2C && EXPERIMENTAL
@@ -581,6 +593,15 @@ config SENSORS_LTC4245
This driver can also be built as a module. If so, the module will
be called ltc4245.
+config SENSORS_LM95241
+ tristate "National Semiconductor LM95241 sensor chip"
+ depends on I2C
+ help
+ If you say yes here you get support for LM95241 sensor chip.
+
+ This driver can also be built as a module. If so, the module
+ will be called lm95241.
+
config SENSORS_MAX1111
tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
depends on SPI_MASTER
@@ -635,6 +656,20 @@ config SENSORS_PC87427
This driver can also be built as a module. If so, the module
will be called pc87427.
+config SENSORS_PCF8591
+ tristate "Philips PCF8591 ADC/DAC"
+ depends on I2C
+ default n
+ help
+ If you say yes here you get support for Philips PCF8591 4-channel
+ ADC, 1-channel DAC chips.
+
+ This driver can also be built as a module. If so, the module
+ will be called pcf8591.
+
+ These devices are hard to detect and rarely found on mainstream
+ hardware. If unsure, say N.
+
config SENSORS_SIS5595
tristate "Silicon Integrated Systems Corp. SiS5595"
depends on PCI
@@ -827,7 +862,7 @@ config SENSORS_W83627HF
will be called w83627hf.
config SENSORS_W83627EHF
- tristate "Winbond W83627EHF/DHG"
+ tristate "Winbond W83627EHF/EHG/DHG, W83667HG"
select HWMON_VID
help
If you say yes here you get support for the hardware
@@ -838,6 +873,8 @@ config SENSORS_W83627EHF
chip suited for specific Intel processors that use PECI such as
the Core 2 Duo.
+ This driver also supports the W83667HG chip.
+
This driver can also be built as a module. If so, the module
will be called w83627ehf.
@@ -895,6 +932,22 @@ config SENSORS_LIS3LV02D
Say Y here if you have an applicable laptop and want to experience
the awesome power of lis3lv02d.
+config SENSORS_LIS3_SPI
+ tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
+ depends on !ACPI && SPI_MASTER && INPUT
+ default n
+ help
+ This driver provides support for the LIS3LV02Dx accelerometer connected
+ via SPI. The accelerometer data is readable via
+ /sys/devices/platform/lis3lv02d.
+
+ This driver also provides an absolute input class device, allowing
+ the laptop to act as a pinball machine-esque joystick.
+
+ This driver can also be built as modules. If so, the core module
+ will be called lis3lv02d and a specific module for the SPI transport
+ is called lis3lv02d_spi.
+
config SENSORS_APPLESMC
tristate "Apple SMC (Motion sensor, light sensor, keyboard backlight)"
depends on INPUT && X86
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 2e80f37f39e..3a6b1f06f8f 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -52,6 +52,7 @@ obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o
obj-$(CONFIG_SENSORS_IT87) += it87.o
obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o
obj-$(CONFIG_SENSORS_LIS3LV02D) += lis3lv02d.o hp_accel.o
+obj-$(CONFIG_SENSORS_LIS3_SPI) += lis3lv02d.o lis3lv02d_spi.o
obj-$(CONFIG_SENSORS_LM63) += lm63.o
obj-$(CONFIG_SENSORS_LM70) += lm70.o
obj-$(CONFIG_SENSORS_LM75) += lm75.o
@@ -64,12 +65,15 @@ obj-$(CONFIG_SENSORS_LM87) += lm87.o
obj-$(CONFIG_SENSORS_LM90) += lm90.o
obj-$(CONFIG_SENSORS_LM92) += lm92.o
obj-$(CONFIG_SENSORS_LM93) += lm93.o
+obj-$(CONFIG_SENSORS_LM95241) += lm95241.o
+obj-$(CONFIG_SENSORS_LTC4215) += ltc4215.o
obj-$(CONFIG_SENSORS_LTC4245) += ltc4245.o
obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
+obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 7415381601c..53f88f51181 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -81,71 +81,84 @@ struct ds1621_data {
u8 conf; /* Register encoding, combined */
};
-static int ds1621_probe(struct i2c_client *client,
- const struct i2c_device_id *id);
-static int ds1621_detect(struct i2c_client *client, int kind,
- struct i2c_board_info *info);
-static void ds1621_init_client(struct i2c_client *client);
-static int ds1621_remove(struct i2c_client *client);
-static struct ds1621_data *ds1621_update_client(struct device *dev);
-
-static const struct i2c_device_id ds1621_id[] = {
- { "ds1621", ds1621 },
- { "ds1625", ds1621 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, ds1621_id);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver ds1621_driver = {
- .class = I2C_CLASS_HWMON,
- .driver = {
- .name = "ds1621",
- },
- .probe = ds1621_probe,
- .remove = ds1621_remove,
- .id_table = ds1621_id,
- .detect = ds1621_detect,
- .address_data = &addr_data,
-};
-
-/* All registers are word-sized, except for the configuration register.
+/* Temperature registers are word-sized.
DS1621 uses a high-byte first convention, which is exactly opposite to
the SMBus standard. */
-static int ds1621_read_value(struct i2c_client *client, u8 reg)
+static int ds1621_read_temp(struct i2c_client *client, u8 reg)
{
- if (reg == DS1621_REG_CONF)
- return i2c_smbus_read_byte_data(client, reg);
- else
- return swab16(i2c_smbus_read_word_data(client, reg));
+ int ret;
+
+ ret = i2c_smbus_read_word_data(client, reg);
+ if (ret < 0)
+ return ret;
+ return swab16(ret);
}
-static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value)
+static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value)
{
- if (reg == DS1621_REG_CONF)
- return i2c_smbus_write_byte_data(client, reg, value);
- else
- return i2c_smbus_write_word_data(client, reg, swab16(value));
+ return i2c_smbus_write_word_data(client, reg, swab16(value));
}
static void ds1621_init_client(struct i2c_client *client)
{
- int reg = ds1621_read_value(client, DS1621_REG_CONF);
+ u8 conf, new_conf;
+
+ new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
/* switch to continuous conversion mode */
- reg &= ~ DS1621_REG_CONFIG_1SHOT;
+ new_conf &= ~DS1621_REG_CONFIG_1SHOT;
/* setup output polarity */
if (polarity == 0)
- reg &= ~DS1621_REG_CONFIG_POLARITY;
+ new_conf &= ~DS1621_REG_CONFIG_POLARITY;
else if (polarity == 1)
- reg |= DS1621_REG_CONFIG_POLARITY;
+ new_conf |= DS1621_REG_CONFIG_POLARITY;
- ds1621_write_value(client, DS1621_REG_CONF, reg);
+ if (conf != new_conf)
+ i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf);
/* start conversion */
i2c_smbus_write_byte(client, DS1621_COM_START);
}
+static struct ds1621_data *ds1621_update_client(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ds1621_data *data = i2c_get_clientdata(client);
+ u8 new_conf;
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+ || !data->valid) {
+ int i;
+
+ dev_dbg(&client->dev, "Starting ds1621 update\n");
+
+ data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+
+ for (i = 0; i < ARRAY_SIZE(data->temp); i++)
+ data->temp[i] = ds1621_read_temp(client,
+ DS1621_REG_TEMP[i]);
+
+ /* reset alarms if necessary */
+ new_conf = data->conf;
+ if (data->temp[0] > data->temp[1]) /* input > min */
+ new_conf &= ~DS1621_ALARM_TEMP_LOW;
+ if (data->temp[0] < data->temp[2]) /* input < max */
+ new_conf &= ~DS1621_ALARM_TEMP_HIGH;
+ if (data->conf != new_conf)
+ i2c_smbus_write_byte_data(client, DS1621_REG_CONF,
+ new_conf);
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
char *buf)
{
@@ -160,13 +173,13 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
{
struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
struct i2c_client *client = to_i2c_client(dev);
- struct ds1621_data *data = ds1621_update_client(dev);
+ struct ds1621_data *data = i2c_get_clientdata(client);
u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10));
mutex_lock(&data->update_lock);
data->temp[attr->index] = val;
- ds1621_write_value(client, DS1621_REG_TEMP[attr->index],
- data->temp[attr->index]);
+ ds1621_write_temp(client, DS1621_REG_TEMP[attr->index],
+ data->temp[attr->index]);
mutex_unlock(&data->update_lock);
return count;
}
@@ -228,13 +241,14 @@ static int ds1621_detect(struct i2c_client *client, int kind,
/* The NVB bit should be low if no EEPROM write has been
requested during the latest 10ms, which is highly
improbable in our case. */
- conf = ds1621_read_value(client, DS1621_REG_CONF);
- if (conf & DS1621_REG_CONFIG_NVB)
+ conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
+ if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
return -ENODEV;
/* The 7 lowest bits of a temperature should always be 0. */
for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
- temp = ds1621_read_value(client, DS1621_REG_TEMP[i]);
- if (temp & 0x007f)
+ temp = i2c_smbus_read_word_data(client,
+ DS1621_REG_TEMP[i]);
+ if (temp < 0 || (temp & 0x7f00))
return -ENODEV;
}
}
@@ -294,45 +308,25 @@ static int ds1621_remove(struct i2c_client *client)
return 0;
}
+static const struct i2c_device_id ds1621_id[] = {
+ { "ds1621", ds1621 },
+ { "ds1625", ds1621 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ds1621_id);
-static struct ds1621_data *ds1621_update_client(struct device *dev)
-{
- struct i2c_client *client = to_i2c_client(dev);
- struct ds1621_data *data = i2c_get_clientdata(client);
- u8 new_conf;
-
- mutex_lock(&data->update_lock);
-
- if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
- || !data->valid) {
- int i;
-
- dev_dbg(&client->dev, "Starting ds1621 update\n");
-
- data->conf = ds1621_read_value(client, DS1621_REG_CONF);
-
- for (i = 0; i < ARRAY_SIZE(data->temp); i++)
- data->temp[i] = ds1621_read_value(client,
- DS1621_REG_TEMP[i]);
-
- /* reset alarms if necessary */
- new_conf = data->conf;
- if (data->temp[0] > data->temp[1]) /* input > min */
- new_conf &= ~DS1621_ALARM_TEMP_LOW;
- if (data->temp[0] < data->temp[2]) /* input < max */
- new_conf &= ~DS1621_ALARM_TEMP_HIGH;
- if (data->conf != new_conf)
- ds1621_write_value(client, DS1621_REG_CONF,
- new_conf);
-
- data->last_updated = jiffies;
- data->valid = 1;
- }
-
- mutex_unlock(&data->update_lock);
-
- return data;
-}
+/* This is the driver that will be inserted */
+static struct i2c_driver ds1621_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ds1621",
+ },
+ .probe = ds1621_probe,
+ .remove = ds1621_remove,
+ .id_table = ds1621_id,
+ .detect = ds1621_detect,
+ .address_data = &addr_data,
+};
static int __init ds1621_init(void)
{
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index 18a1ba88816..e2107e533ed 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -1,7 +1,7 @@
/*
* f75375s.c - driver for the Fintek F75375/SP and F75373
* hardware monitoring features
- * Copyright (C) 2006-2007 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2006-2007 Riku Voipio
*
* Datasheets available at:
*
@@ -721,7 +721,7 @@ static void __exit sensors_f75375_exit(void)
i2c_del_driver(&f75375_driver);
}
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("F75373/F75375 hardware monitoring driver");
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index d07f4ef7509..ea955edde87 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -1,6 +1,6 @@
/* fschmd.c
*
- * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
+ * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
/*
* Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes,
- * Scylla, Heracles and Heimdall chips
+ * Scylla, Heracles, Heimdall, Hades and Syleus chips
*
* Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6
* (candidate) fschmd drivers:
@@ -56,7 +56,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, int, 0);
MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
__MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
-I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
+I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl);
/*
* The FSCHMD registers and other defines
@@ -75,9 +75,12 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
#define FSCHMD_CONTROL_ALERT_LED 0x01
/* watchdog */
-#define FSCHMD_REG_WDOG_PRESET 0x28
-#define FSCHMD_REG_WDOG_STATE 0x23
-#define FSCHMD_REG_WDOG_CONTROL 0x21
+static const u8 FSCHMD_REG_WDOG_CONTROL[7] =
+ { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 };
+static const u8 FSCHMD_REG_WDOG_STATE[7] =
+ { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 };
+static const u8 FSCHMD_REG_WDOG_PRESET[7] =
+ { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a };
#define FSCHMD_WDOG_CONTROL_TRIGGER 0x10
#define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */
@@ -87,70 +90,95 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
#define FSCHMD_WDOG_STATE_CARDRESET 0x02
/* voltages, weird order is to keep the same order as the old drivers */
-static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 };
+static const u8 FSCHMD_REG_VOLT[7][6] = {
+ { 0x45, 0x42, 0x48 }, /* pos */
+ { 0x45, 0x42, 0x48 }, /* her */
+ { 0x45, 0x42, 0x48 }, /* scy */
+ { 0x45, 0x42, 0x48 }, /* hrc */
+ { 0x45, 0x42, 0x48 }, /* hmd */
+ { 0x21, 0x20, 0x22 }, /* hds */
+ { 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 }, /* syl */
+};
+
+static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 };
/* minimum pwm at which the fan is driven (pwm can by increased depending on
the temp. Notice that for the scy some fans share there minimum speed.
Also notice that with the scy the sensor order is different than with the
other chips, this order was in the 2.4 driver and kept for consistency. */
-static const u8 FSCHMD_REG_FAN_MIN[5][6] = {
+static const u8 FSCHMD_REG_FAN_MIN[7][7] = {
{ 0x55, 0x65 }, /* pos */
{ 0x55, 0x65, 0xb5 }, /* her */
{ 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */
{ 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */
{ 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */
+ { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hds */
+ { 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 }, /* syl */
};
/* actual fan speed */
-static const u8 FSCHMD_REG_FAN_ACT[5][6] = {
+static const u8 FSCHMD_REG_FAN_ACT[7][7] = {
{ 0x0e, 0x6b, 0xab }, /* pos */
{ 0x0e, 0x6b, 0xbb }, /* her */
{ 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */
{ 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */
{ 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */
+ { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hds */
+ { 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 }, /* syl */
};
/* fan status registers */
-static const u8 FSCHMD_REG_FAN_STATE[5][6] = {
+static const u8 FSCHMD_REG_FAN_STATE[7][7] = {
{ 0x0d, 0x62, 0xa2 }, /* pos */
{ 0x0d, 0x62, 0xb2 }, /* her */
{ 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */
{ 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */
{ 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */
+ { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hds */
+ { 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 }, /* syl */
};
/* fan ripple / divider registers */
-static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = {
+static const u8 FSCHMD_REG_FAN_RIPPLE[7][7] = {
{ 0x0f, 0x6f, 0xaf }, /* pos */
{ 0x0f, 0x6f, 0xbf }, /* her */
{ 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */
{ 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */
{ 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */
+ { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hds */
+ { 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 }, /* syl */
};
-static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 };
+static const int FSCHMD_NO_FAN_SENSORS[7] = { 3, 3, 6, 4, 5, 5, 7 };
/* Fan status register bitmasks */
#define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */
-#define FSCHMD_FAN_NOT_PRESENT 0x08 /* not documented */
+#define FSCHMD_FAN_NOT_PRESENT 0x08
+#define FSCHMD_FAN_DISABLED 0x80
/* actual temperature registers */
-static const u8 FSCHMD_REG_TEMP_ACT[5][5] = {
+static const u8 FSCHMD_REG_TEMP_ACT[7][11] = {
{ 0x64, 0x32, 0x35 }, /* pos */
{ 0x64, 0x32, 0x35 }, /* her */
{ 0x64, 0xD0, 0x32, 0x35 }, /* scy */
{ 0x64, 0x32, 0x35 }, /* hrc */
{ 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */
+ { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hds */
+ { 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, /* syl */
+ 0xb8, 0xc8, 0xd8, 0xe8, 0xf8 },
};
/* temperature state registers */
-static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
+static const u8 FSCHMD_REG_TEMP_STATE[7][11] = {
{ 0x71, 0x81, 0x91 }, /* pos */
{ 0x71, 0x81, 0x91 }, /* her */
{ 0x71, 0xd1, 0x81, 0x91 }, /* scy */
{ 0x71, 0x81, 0x91 }, /* hrc */
{ 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */
+ { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hds */
+ { 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, /* syl */
+ 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 },
};
/* temperature high limit registers, FSC does not document these. Proven to be
@@ -158,24 +186,31 @@ static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
at these addresses, but doesn't want to confirm they are the same as with
the fscher?? */
-static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = {
+static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = {
{ 0, 0, 0 }, /* pos */
{ 0x76, 0x86, 0x96 }, /* her */
{ 0x76, 0xd6, 0x86, 0x96 }, /* scy */
{ 0x76, 0x86, 0x96 }, /* hrc */
{ 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */
+ { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hds */
+ { 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, /* syl */
+ 0xba, 0xca, 0xda, 0xea, 0xfa },
};
/* These were found through experimenting with an fscher, currently they are
not used, but we keep them around for future reference.
+ On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc),
+ AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence
+ the fan speed.
static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 };
static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */
-static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
+static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 };
/* temp status register bitmasks */
#define FSCHMD_TEMP_WORKING 0x01
#define FSCHMD_TEMP_ALERT 0x02
+#define FSCHMD_TEMP_DISABLED 0x80
/* there only really is an alarm if the sensor is working and alert == 1 */
#define FSCHMD_TEMP_ALARM_MASK \
(FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
@@ -201,6 +236,8 @@ static const struct i2c_device_id fschmd_id[] = {
{ "fscscy", fscscy },
{ "fschrc", fschrc },
{ "fschmd", fschmd },
+ { "fschds", fschds },
+ { "fscsyl", fscsyl },
{ }
};
MODULE_DEVICE_TABLE(i2c, fschmd_id);
@@ -242,14 +279,14 @@ struct fschmd_data {
u8 watchdog_control; /* watchdog control register */
u8 watchdog_state; /* watchdog status register */
u8 watchdog_preset; /* watchdog counter preset on trigger val */
- u8 volt[3]; /* 12, 5, battery voltage */
- u8 temp_act[5]; /* temperature */
- u8 temp_status[5]; /* status of sensor */
- u8 temp_max[5]; /* high temp limit, notice: undocumented! */
- u8 fan_act[6]; /* fans revolutions per second */
- u8 fan_status[6]; /* fan status */
- u8 fan_min[6]; /* fan min value for rps */
- u8 fan_ripple[6]; /* divider for rps */
+ u8 volt[6]; /* voltage */
+ u8 temp_act[11]; /* temperature */
+ u8 temp_status[11]; /* status of sensor */
+ u8 temp_max[11]; /* high temp limit, notice: undocumented! */
+ u8 fan_act[7]; /* fans revolutions per second */
+ u8 fan_status[7]; /* fan status */
+ u8 fan_min[7]; /* fan min value for rps */
+ u8 fan_ripple[7]; /* divider for rps */
};
/* Global variables to hold information read from special DMI tables, which are
@@ -257,8 +294,8 @@ struct fschmd_data {
protect these with a lock as they are only modified from our attach function
which always gets called with the i2c-core lock held and never accessed
before the attach function is done with them. */
-static int dmi_mult[3] = { 490, 200, 100 };
-static int dmi_offset[3] = { 0, 0, 0 };
+static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 };
+static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 };
static int dmi_vref = -1;
/* Somewhat ugly :( global data pointer list with all fschmd devices, so that
@@ -450,10 +487,11 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
struct device_attribute *devattr, char *buf)
{
int index = to_sensor_dev_attr(devattr)->index;
- int val = fschmd_update_device(dev)->fan_min[index];
+ struct fschmd_data *data = fschmd_update_device(dev);
+ int val = data->fan_min[index];
- /* 0 = allow turning off, 1-255 = 50-100% */
- if (val)
+ /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+ if (val || data->kind == fscsyl - 1)
val = val / 2 + 128;
return sprintf(buf, "%d\n", val);
@@ -466,8 +504,8 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
struct fschmd_data *data = dev_get_drvdata(dev);
unsigned long v = simple_strtoul(buf, NULL, 10);
- /* register: 0 = allow turning off, 1-255 = 50-100% */
- if (v) {
+ /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
+ if (v || data->kind == fscsyl - 1) {
v = SENSORS_LIMIT(v, 128, 255);
v = (v - 128) * 2 + 1;
}
@@ -522,11 +560,15 @@ static ssize_t store_alert_led(struct device *dev,
return count;
}
+static DEVICE_ATTR(alert_led, 0644, show_alert_led, store_alert_led);
+
static struct sensor_device_attribute fschmd_attr[] = {
SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
- SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0),
+ SENSOR_ATTR(in3_input, 0444, show_in_value, NULL, 3),
+ SENSOR_ATTR(in4_input, 0444, show_in_value, NULL, 4),
+ SENSOR_ATTR(in5_input, 0444, show_in_value, NULL, 5),
};
static struct sensor_device_attribute fschmd_temp_attr[] = {
@@ -550,6 +592,30 @@ static struct sensor_device_attribute fschmd_temp_attr[] = {
SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4),
SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
+ SENSOR_ATTR(temp6_input, 0444, show_temp_value, NULL, 5),
+ SENSOR_ATTR(temp6_max, 0644, show_temp_max, store_temp_max, 5),
+ SENSOR_ATTR(temp6_fault, 0444, show_temp_fault, NULL, 5),
+ SENSOR_ATTR(temp6_alarm, 0444, show_temp_alarm, NULL, 5),
+ SENSOR_ATTR(temp7_input, 0444, show_temp_value, NULL, 6),
+ SENSOR_ATTR(temp7_max, 0644, show_temp_max, store_temp_max, 6),
+ SENSOR_ATTR(temp7_fault, 0444, show_temp_fault, NULL, 6),
+ SENSOR_ATTR(temp7_alarm, 0444, show_temp_alarm, NULL, 6),
+ SENSOR_ATTR(temp8_input, 0444, show_temp_value, NULL, 7),
+ SENSOR_ATTR(temp8_max, 0644, show_temp_max, store_temp_max, 7),
+ SENSOR_ATTR(temp8_fault, 0444, show_temp_fault, NULL, 7),
+ SENSOR_ATTR(temp8_alarm, 0444, show_temp_alarm, NULL, 7),
+ SENSOR_ATTR(temp9_input, 0444, show_temp_value, NULL, 8),
+ SENSOR_ATTR(temp9_max, 0644, show_temp_max, store_temp_max, 8),
+ SENSOR_ATTR(temp9_fault, 0444, show_temp_fault, NULL, 8),
+ SENSOR_ATTR(temp9_alarm, 0444, show_temp_alarm, NULL, 8),
+ SENSOR_ATTR(temp10_input, 0444, show_temp_value, NULL, 9),
+ SENSOR_ATTR(temp10_max, 0644, show_temp_max, store_temp_max, 9),
+ SENSOR_ATTR(temp10_fault, 0444, show_temp_fault, NULL, 9),
+ SENSOR_ATTR(temp10_alarm, 0444, show_temp_alarm, NULL, 9),
+ SENSOR_ATTR(temp11_input, 0444, show_temp_value, NULL, 10),
+ SENSOR_ATTR(temp11_max, 0644, show_temp_max, store_temp_max, 10),
+ SENSOR_ATTR(temp11_fault, 0444, show_temp_fault, NULL, 10),
+ SENSOR_ATTR(temp11_alarm, 0444, show_temp_alarm, NULL, 10),
};
static struct sensor_device_attribute fschmd_fan_attr[] = {
@@ -589,6 +655,12 @@ static struct sensor_device_attribute fschmd_fan_attr[] = {
SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
store_pwm_auto_point1_pwm, 5),
+ SENSOR_ATTR(fan7_input, 0444, show_fan_value, NULL, 6),
+ SENSOR_ATTR(fan7_div, 0644, show_fan_div, store_fan_div, 6),
+ SENSOR_ATTR(fan7_alarm, 0444, show_fan_alarm, NULL, 6),
+ SENSOR_ATTR(fan7_fault, 0444, show_fan_fault, NULL, 6),
+ SENSOR_ATTR(pwm7_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
+ store_pwm_auto_point1_pwm, 6),
};
@@ -624,10 +696,11 @@ static int watchdog_set_timeout(struct fschmd_data *data, int timeout)
data->watchdog_preset = DIV_ROUND_UP(timeout, resolution);
/* Write new timeout value */
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_PRESET,
- data->watchdog_preset);
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_PRESET[data->kind], data->watchdog_preset);
/* Write new control register, do not trigger! */
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_CONTROL[data->kind],
data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER);
ret = data->watchdog_preset * resolution;
@@ -662,8 +735,9 @@ static int watchdog_trigger(struct fschmd_data *data)
}
data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER;
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
- data->watchdog_control);
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_CONTROL[data->kind],
+ data->watchdog_control);
leave:
mutex_unlock(&data->watchdog_lock);
return ret;
@@ -682,7 +756,8 @@ static int watchdog_stop(struct fschmd_data *data)
data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED;
/* Don't store the stop flag in our watchdog control register copy, as
its a write only bit (read always returns 0) */
- i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
+ i2c_smbus_write_byte_data(data->client,
+ FSCHMD_REG_WDOG_CONTROL[data->kind],
data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP);
leave:
mutex_unlock(&data->watchdog_lock);
@@ -856,7 +931,7 @@ static struct file_operations watchdog_fops = {
/* DMI decode routine to read voltage scaling factors from special DMI tables,
which are available on FSC machines with an fscher or later chip. */
-static void fschmd_dmi_decode(const struct dmi_header *header)
+static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy)
{
int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
@@ -912,6 +987,15 @@ static void fschmd_dmi_decode(const struct dmi_header *header)
dmi_mult[i] = mult[i] * 10;
dmi_offset[i] = offset[i] * 10;
}
+ /* According to the docs there should be separate dmi entries
+ for the mult's and offsets of in3-5 of the syl, but on
+ my test machine these are not present */
+ dmi_mult[3] = dmi_mult[2];
+ dmi_mult[4] = dmi_mult[1];
+ dmi_mult[5] = dmi_mult[2];
+ dmi_offset[3] = dmi_offset[2];
+ dmi_offset[4] = dmi_offset[1];
+ dmi_offset[5] = dmi_offset[2];
dmi_vref = vref;
}
}
@@ -920,8 +1004,6 @@ static int fschmd_detect(struct i2c_client *client, int kind,
struct i2c_board_info *info)
{
struct i2c_adapter *adapter = client->adapter;
- const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
- "fschrc", "fschmd" };
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
@@ -948,11 +1030,15 @@ static int fschmd_detect(struct i2c_client *client, int kind,
kind = fschrc;
else if (!strcmp(id, "HMD"))
kind = fschmd;
+ else if (!strcmp(id, "HDS"))
+ kind = fschds;
+ else if (!strcmp(id, "SYL"))
+ kind = fscsyl;
else
return -ENODEV;
}
- strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
+ strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
return 0;
}
@@ -961,8 +1047,8 @@ static int fschmd_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct fschmd_data *data;
- const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
- "Heracles", "Heimdall" };
+ const char * const names[7] = { "Poseidon", "Hermes", "Scylla",
+ "Heracles", "Heimdall", "Hades", "Syleus" };
const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
int i, err;
enum chips kind = id->driver_data;
@@ -991,7 +1077,7 @@ static int fschmd_probe(struct i2c_client *client,
/* Read the special DMI table for fscher and newer chips */
if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) {
- dmi_walk(fschmd_dmi_decode);
+ dmi_walk(fschmd_dmi_decode, NULL);
if (dmi_vref == -1) {
dev_warn(&client->dev,
"Couldn't get voltage scaling factors from "
@@ -1000,21 +1086,25 @@ static int fschmd_probe(struct i2c_client *client,
}
}
+ /* i2c kind goes from 1-6, we want from 0-5 to address arrays */
+ data->kind = kind - 1;
+
/* Read in some never changing registers */
data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
data->global_control = i2c_smbus_read_byte_data(client,
FSCHMD_REG_CONTROL);
data->watchdog_control = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_WDOG_CONTROL);
+ FSCHMD_REG_WDOG_CONTROL[data->kind]);
data->watchdog_state = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_WDOG_STATE);
+ FSCHMD_REG_WDOG_STATE[data->kind]);
data->watchdog_preset = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_WDOG_PRESET);
+ FSCHMD_REG_WDOG_PRESET[data->kind]);
- /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
- data->kind = kind - 1;
+ err = device_create_file(&client->dev, &dev_attr_alert_led);
+ if (err)
+ goto exit_detach;
- for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
+ for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++) {
err = device_create_file(&client->dev,
&fschmd_attr[i].dev_attr);
if (err)
@@ -1027,6 +1117,16 @@ static int fschmd_probe(struct i2c_client *client,
show_temp_max)
continue;
+ if (kind == fscsyl) {
+ if (i % 4 == 0)
+ data->temp_status[i / 4] =
+ i2c_smbus_read_byte_data(client,
+ FSCHMD_REG_TEMP_STATE
+ [data->kind][i / 4]);
+ if (data->temp_status[i / 4] & FSCHMD_TEMP_DISABLED)
+ continue;
+ }
+
err = device_create_file(&client->dev,
&fschmd_temp_attr[i].dev_attr);
if (err)
@@ -1040,6 +1140,16 @@ static int fschmd_probe(struct i2c_client *client,
"pwm3_auto_point1_pwm"))
continue;
+ if (kind == fscsyl) {
+ if (i % 5 == 0)
+ data->fan_status[i / 5] =
+ i2c_smbus_read_byte_data(client,
+ FSCHMD_REG_FAN_STATE
+ [data->kind][i / 5]);
+ if (data->fan_status[i / 5] & FSCHMD_FAN_DISABLED)
+ continue;
+ }
+
err = device_create_file(&client->dev,
&fschmd_fan_attr[i].dev_attr);
if (err)
@@ -1126,7 +1236,8 @@ static int fschmd_remove(struct i2c_client *client)
if (data->hwmon_dev)
hwmon_device_unregister(data->hwmon_dev);
- for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++)
+ device_remove_file(&client->dev, &dev_attr_alert_led);
+ for (i = 0; i < (FSCHMD_NO_VOLT_SENSORS[data->kind]); i++)
device_remove_file(&client->dev, &fschmd_attr[i].dev_attr);
for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++)
device_remove_file(&client->dev,
@@ -1171,7 +1282,7 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
data->temp_act[i] < data->temp_max[i])
i2c_smbus_write_byte_data(client,
FSCHMD_REG_TEMP_STATE[data->kind][i],
- FSCHMD_TEMP_ALERT);
+ data->temp_status[i]);
}
for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
@@ -1193,12 +1304,12 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
data->fan_act[i])
i2c_smbus_write_byte_data(client,
FSCHMD_REG_FAN_STATE[data->kind][i],
- FSCHMD_FAN_ALARM);
+ data->fan_status[i]);
}
- for (i = 0; i < 3; i++)
+ for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++)
data->volt[i] = i2c_smbus_read_byte_data(client,
- FSCHMD_REG_VOLT[i]);
+ FSCHMD_REG_VOLT[data->kind][i]);
data->last_updated = jiffies;
data->valid = 1;
@@ -1220,8 +1331,8 @@ static void __exit fschmd_exit(void)
}
MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
-MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
- "Heimdall driver");
+MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades "
+ "and Syleus driver");
MODULE_LICENSE("GPL");
module_init(fschmd_init);
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index a4d92d246d5..d3612a1f198 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -65,6 +65,10 @@
#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
#define HDAPS_INPUT_FLAT 4
+#define HDAPS_X_AXIS (1 << 0)
+#define HDAPS_Y_AXIS (1 << 1)
+#define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS)
+
static struct platform_device *pdev;
static struct input_polled_dev *hdaps_idev;
static unsigned int hdaps_invert;
@@ -182,11 +186,11 @@ static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
km_activity = inb(HDAPS_PORT_KMACT);
__device_complete();
- /* if hdaps_invert is set, negate the two values */
- if (hdaps_invert) {
+ /* hdaps_invert is a bitvector to negate the axes */
+ if (hdaps_invert & HDAPS_X_AXIS)
*x = -*x;
+ if (hdaps_invert & HDAPS_Y_AXIS)
*y = -*y;
- }
return 0;
}
@@ -436,7 +440,8 @@ static ssize_t hdaps_invert_store(struct device *dev,
{
int invert;
- if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0))
+ if (sscanf(buf, "%d", &invert) != 1 ||
+ invert < 0 || invert > HDAPS_BOTH_AXES)
return -EINVAL;
hdaps_invert = invert;
@@ -483,56 +488,52 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id)
/* hdaps_dmi_match_invert - found an inverted match. */
static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
{
- hdaps_invert = 1;
- printk(KERN_INFO "hdaps: inverting axis readings.\n");
+ hdaps_invert = (unsigned long)id->driver_data;
+ printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n",
+ hdaps_invert);
return hdaps_dmi_match(id);
}
-#define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \
- .ident = vendor " " model, \
- .callback = hdaps_dmi_match, \
- .matches = { \
- DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
- DMI_MATCH(DMI_PRODUCT_VERSION, model) \
- } \
-}
-
-#define HDAPS_DMI_MATCH_INVERT(vendor, model) { \
+#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) { \
.ident = vendor " " model, \
.callback = hdaps_dmi_match_invert, \
+ .driver_data = (void *)axes, \
.matches = { \
DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
DMI_MATCH(DMI_PRODUCT_VERSION, model) \
} \
}
+#define HDAPS_DMI_MATCH_NORMAL(vendor, model) \
+ HDAPS_DMI_MATCH_INVERT(vendor, model, 0)
+
/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
"ThinkPad T42p", so the order of the entries matters.
If your ThinkPad is not recognized, please update to latest
BIOS. This is especially the case for some R52 ThinkPads. */
static struct dmi_system_id __initdata hdaps_whitelist[] = {
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"),
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
- HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
- HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"),
+ HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X41", HDAPS_Y_AXIS),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES),
HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"),
- HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES),
+ HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES),
{ .ident = NULL }
};
@@ -627,8 +628,9 @@ static void __exit hdaps_exit(void)
module_init(hdaps_init);
module_exit(hdaps_exit);
-module_param_named(invert, hdaps_invert, bool, 0);
-MODULE_PARM_DESC(invert, "invert data along each axis");
+module_param_named(invert, hdaps_invert, int, 0);
+MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, "
+ "2 invert y-axis, 3 invert both axes.");
MODULE_AUTHOR("Robert Love");
MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index 29c83b5b969..55d3dc565be 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -85,25 +85,31 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids);
/**
* lis3lv02d_acpi_init - ACPI _INI method: initialize the device.
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
*
- * Returns AE_OK on success.
+ * Returns 0 on success.
*/
-acpi_status lis3lv02d_acpi_init(acpi_handle handle)
+int lis3lv02d_acpi_init(struct lis3lv02d *lis3)
{
- return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL);
+ struct acpi_device *dev = lis3->bus_priv;
+ if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI,
+ NULL, NULL) != AE_OK)
+ return -EINVAL;
+
+ return 0;
}
/**
* lis3lv02d_acpi_read - ACPI ALRD method: read a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
* @reg: the register to read
* @ret: result of the operation
*
- * Returns AE_OK on success.
+ * Returns 0 on success.
*/
-acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
+int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret)
{
+ struct acpi_device *dev = lis3->bus_priv;
union acpi_object arg0 = { ACPI_TYPE_INTEGER };
struct acpi_object_list args = { 1, &arg0 };
unsigned long long lret;
@@ -111,21 +117,22 @@ acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret)
arg0.integer.value = reg;
- status = acpi_evaluate_integer(handle, "ALRD", &args, &lret);
+ status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret);
*ret = lret;
- return status;
+ return (status != AE_OK) ? -EINVAL : 0;
}
/**
* lis3lv02d_acpi_write - ACPI ALWR method: write to a register
- * @handle: the handle of the device
+ * @lis3: pointer to the device struct
* @reg: the register to write to
* @val: the value to write
*
- * Returns AE_OK on success.
+ * Returns 0 on success.
*/
-acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
+int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
{
+ struct acpi_device *dev = lis3->bus_priv;
unsigned long long ret; /* Not used when writting */
union acpi_object in_obj[2];
struct acpi_object_list args = { 2, in_obj };
@@ -135,12 +142,15 @@ acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val)
in_obj[1].type = ACPI_TYPE_INTEGER;
in_obj[1].integer.value = val;
- return acpi_evaluate_integer(handle, "ALWR", &args, &ret);
+ if (acpi_evaluate_integer(dev->handle, "ALWR", &args, &ret) != AE_OK)
+ return -EINVAL;
+
+ return 0;
}
static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
{
- adev.ac = *((struct axis_conversion *)dmi->driver_data);
+ lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data);
printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
return 1;
@@ -187,6 +197,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
AXIS_DMI_MATCH("NC2510", "HP Compaq 2510", y_inverted),
AXIS_DMI_MATCH("NC8510", "HP Compaq 8510", xy_swap_inverted),
AXIS_DMI_MATCH("HP2133", "HP 2133", xy_rotated_left),
+ AXIS_DMI_MATCH("HP2140", "HP 2140", xy_swap_inverted),
AXIS_DMI_MATCH("NC653x", "HP Compaq 653", xy_rotated_left_usd),
AXIS_DMI_MATCH("NC673x", "HP Compaq 673", xy_rotated_left_usd),
AXIS_DMI_MATCH("NC651xx", "HP Compaq 651", xy_rotated_right),
@@ -201,6 +212,8 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
PRODUCT_NAME, "HP Pavilion dv5",
BOARD_NAME, "3600",
y_inverted),
+ AXIS_DMI_MATCH("DV7", "HP Pavilion dv7", x_inverted),
+ AXIS_DMI_MATCH("HP8710", "HP Compaq 8710", y_inverted),
{ NULL, }
/* Laptop models without axis info (yet):
* "NC6910" "HP Compaq 6910"
@@ -214,7 +227,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = {
static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value)
{
- acpi_handle handle = adev.device->handle;
+ struct acpi_device *dev = lis3_dev.bus_priv;
unsigned long long ret; /* Not used when writing */
union acpi_object in_obj[1];
struct acpi_object_list args = { 1, in_obj };
@@ -222,7 +235,7 @@ static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness
in_obj[0].type = ACPI_TYPE_INTEGER;
in_obj[0].integer.value = !!value;
- acpi_evaluate_integer(handle, "ALED", &args, &ret);
+ acpi_evaluate_integer(dev->handle, "ALED", &args, &ret);
}
static struct delayed_led_classdev hpled_led = {
@@ -254,28 +267,11 @@ static void lis3lv02d_enum_resources(struct acpi_device *device)
acpi_status status;
status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
- lis3lv02d_get_resource, &adev.irq);
+ lis3lv02d_get_resource, &lis3_dev.irq);
if (ACPI_FAILURE(status))
printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n");
}
-static s16 lis3lv02d_read_16(acpi_handle handle, int reg)
-{
- u8 lo, hi;
-
- adev.read(handle, reg - 1, &lo);
- adev.read(handle, reg, &hi);
- /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
- return (s16)((hi << 8) | lo);
-}
-
-static s16 lis3lv02d_read_8(acpi_handle handle, int reg)
-{
- s8 lo;
- adev.read(handle, reg, &lo);
- return lo;
-}
-
static int lis3lv02d_add(struct acpi_device *device)
{
int ret;
@@ -283,51 +279,35 @@ static int lis3lv02d_add(struct acpi_device *device)
if (!device)
return -EINVAL;
- adev.device = device;
- adev.init = lis3lv02d_acpi_init;
- adev.read = lis3lv02d_acpi_read;
- adev.write = lis3lv02d_acpi_write;
+ lis3_dev.bus_priv = device;
+ lis3_dev.init = lis3lv02d_acpi_init;
+ lis3_dev.read = lis3lv02d_acpi_read;
+ lis3_dev.write = lis3lv02d_acpi_write;
strcpy(acpi_device_name(device), DRIVER_NAME);
strcpy(acpi_device_class(device), ACPI_MDPS_CLASS);
- device->driver_data = &adev;
-
- lis3lv02d_acpi_read(device->handle, WHO_AM_I, &adev.whoami);
- switch (adev.whoami) {
- case LIS_DOUBLE_ID:
- printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
- adev.read_data = lis3lv02d_read_16;
- adev.mdps_max_val = 2048;
- break;
- case LIS_SINGLE_ID:
- printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
- adev.read_data = lis3lv02d_read_8;
- adev.mdps_max_val = 128;
- break;
- default:
- printk(KERN_ERR DRIVER_NAME
- ": unknown sensor type 0x%X\n", adev.whoami);
- return -EINVAL;
- }
+ device->driver_data = &lis3_dev;
+
+ /* obtain IRQ number of our device from ACPI */
+ lis3lv02d_enum_resources(device);
/* If possible use a "standard" axes order */
if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
"using default axes configuration\n");
- adev.ac = lis3lv02d_axis_normal;
+ lis3_dev.ac = lis3lv02d_axis_normal;
}
- INIT_WORK(&hpled_led.work, delayed_set_status_worker);
- ret = led_classdev_register(NULL, &hpled_led.led_classdev);
+ /* call the core layer do its init */
+ ret = lis3lv02d_init_device(&lis3_dev);
if (ret)
return ret;
- /* obtain IRQ number of our device from ACPI */
- lis3lv02d_enum_resources(adev.device);
-
- ret = lis3lv02d_init_device(&adev);
+ INIT_WORK(&hpled_led.work, delayed_set_status_worker);
+ ret = led_classdev_register(NULL, &hpled_led.led_classdev);
if (ret) {
+ lis3lv02d_joystick_disable();
+ lis3lv02d_poweroff(&lis3_dev);
flush_work(&hpled_led.work);
- led_classdev_unregister(&hpled_led.led_classdev);
return ret;
}
@@ -340,7 +320,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
return -EINVAL;
lis3lv02d_joystick_disable();
- lis3lv02d_poweroff(device->handle);
+ lis3lv02d_poweroff(&lis3_dev);
flush_work(&hpled_led.work);
led_classdev_unregister(&hpled_led.led_classdev);
@@ -353,19 +333,19 @@ static int lis3lv02d_remove(struct acpi_device *device, int type)
static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state)
{
/* make sure the device is off when we suspend */
- lis3lv02d_poweroff(device->handle);
+ lis3lv02d_poweroff(&lis3_dev);
return 0;
}
static int lis3lv02d_resume(struct acpi_device *device)
{
/* put back the device in the right state (ACPI might turn it on) */
- mutex_lock(&adev.lock);
- if (adev.usage > 0)
- lis3lv02d_poweron(device->handle);
+ mutex_lock(&lis3_dev.lock);
+ if (lis3_dev.usage > 0)
+ lis3lv02d_poweron(&lis3_dev);
else
- lis3lv02d_poweroff(device->handle);
- mutex_unlock(&adev.lock);
+ lis3lv02d_poweroff(&lis3_dev);
+ mutex_unlock(&lis3_dev.lock);
return 0;
}
#else
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index 8bb2158f045..778eb779598 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -36,7 +36,6 @@
#include <linux/freezer.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
-#include <acpi/acpi_drivers.h>
#include <asm/atomic.h>
#include "lis3lv02d.h"
@@ -53,13 +52,30 @@
* joystick.
*/
-struct acpi_lis3lv02d adev = {
- .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait),
+struct lis3lv02d lis3_dev = {
+ .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait),
};
-EXPORT_SYMBOL_GPL(adev);
+EXPORT_SYMBOL_GPL(lis3_dev);
-static int lis3lv02d_add_fs(struct acpi_device *device);
+static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg)
+{
+ s8 lo;
+ if (lis3->read(lis3, reg, &lo) < 0)
+ return 0;
+
+ return lo;
+}
+
+static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg)
+{
+ u8 lo, hi;
+
+ lis3->read(lis3, reg - 1, &lo);
+ lis3->read(lis3, reg, &hi);
+ /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */
+ return (s16)((hi << 8) | lo);
+}
/**
* lis3lv02d_get_axis - For the given axis, give the value converted
@@ -78,36 +94,36 @@ static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3])
/**
* lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer
- * @handle: the handle to the device
- * @x: where to store the X axis value
- * @y: where to store the Y axis value
- * @z: where to store the Z axis value
+ * @lis3: pointer to the device struct
+ * @x: where to store the X axis value
+ * @y: where to store the Y axis value
+ * @z: where to store the Z axis value
*
* Note that 40Hz input device can eat up about 10% CPU at 800MHZ
*/
-static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z)
+static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
{
int position[3];
- position[0] = adev.read_data(handle, OUTX);
- position[1] = adev.read_data(handle, OUTY);
- position[2] = adev.read_data(handle, OUTZ);
+ position[0] = lis3_dev.read_data(lis3, OUTX);
+ position[1] = lis3_dev.read_data(lis3, OUTY);
+ position[2] = lis3_dev.read_data(lis3, OUTZ);
- *x = lis3lv02d_get_axis(adev.ac.x, position);
- *y = lis3lv02d_get_axis(adev.ac.y, position);
- *z = lis3lv02d_get_axis(adev.ac.z, position);
+ *x = lis3lv02d_get_axis(lis3_dev.ac.x, position);
+ *y = lis3lv02d_get_axis(lis3_dev.ac.y, position);
+ *z = lis3lv02d_get_axis(lis3_dev.ac.z, position);
}
-void lis3lv02d_poweroff(acpi_handle handle)
+void lis3lv02d_poweroff(struct lis3lv02d *lis3)
{
- adev.is_on = 0;
+ lis3_dev.is_on = 0;
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweroff);
-void lis3lv02d_poweron(acpi_handle handle)
+void lis3lv02d_poweron(struct lis3lv02d *lis3)
{
- adev.is_on = 1;
- adev.init(handle);
+ lis3_dev.is_on = 1;
+ lis3_dev.init(lis3);
}
EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
@@ -116,13 +132,13 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron);
* device will always be on until a call to lis3lv02d_decrease_use(). Not to be
* used from interrupt context.
*/
-static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_increase_use(struct lis3lv02d *dev)
{
mutex_lock(&dev->lock);
dev->usage++;
if (dev->usage == 1) {
if (!dev->is_on)
- lis3lv02d_poweron(dev->device->handle);
+ lis3lv02d_poweron(dev);
}
mutex_unlock(&dev->lock);
}
@@ -131,12 +147,12 @@ static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev)
* To be called whenever a usage of the device is stopped.
* It will make sure to turn off the device when there is not usage.
*/
-static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev)
+static void lis3lv02d_decrease_use(struct lis3lv02d *dev)
{
mutex_lock(&dev->lock);
dev->usage--;
if (dev->usage == 0)
- lis3lv02d_poweroff(dev->device->handle);
+ lis3lv02d_poweroff(dev);
mutex_unlock(&dev->lock);
}
@@ -147,10 +163,10 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy)
* the lid is closed. This leads to interrupts as soon as a little move
* is done.
*/
- atomic_inc(&adev.count);
+ atomic_inc(&lis3_dev.count);
- wake_up_interruptible(&adev.misc_wait);
- kill_fasync(&adev.async_queue, SIGIO, POLL_IN);
+ wake_up_interruptible(&lis3_dev.misc_wait);
+ kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN);
return IRQ_HANDLED;
}
@@ -158,10 +174,10 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
{
int ret;
- if (test_and_set_bit(0, &adev.misc_opened))
+ if (test_and_set_bit(0, &lis3_dev.misc_opened))
return -EBUSY; /* already open */
- atomic_set(&adev.count, 0);
+ atomic_set(&lis3_dev.count, 0);
/*
* The sensor can generate interrupts for free-fall and direction
@@ -174,25 +190,25 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file)
* io-apic is not configurable (and generates a warning) but I keep it
* in case of support for other hardware.
*/
- ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
- DRIVER_NAME, &adev);
+ ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING,
+ DRIVER_NAME, &lis3_dev);
if (ret) {
- clear_bit(0, &adev.misc_opened);
- printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq);
+ clear_bit(0, &lis3_dev.misc_opened);
+ printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq);
return -EBUSY;
}
- lis3lv02d_increase_use(&adev);
- printk("lis3: registered interrupt %d\n", adev.irq);
+ lis3lv02d_increase_use(&lis3_dev);
+ printk("lis3: registered interrupt %d\n", lis3_dev.irq);
return 0;
}
static int lis3lv02d_misc_release(struct inode *inode, struct file *file)
{
- fasync_helper(-1, file, 0, &adev.async_queue);
- lis3lv02d_decrease_use(&adev);
- free_irq(adev.irq, &adev);
- clear_bit(0, &adev.misc_opened); /* release the device */
+ fasync_helper(-1, file, 0, &lis3_dev.async_queue);
+ lis3lv02d_decrease_use(&lis3_dev);
+ free_irq(lis3_dev.irq, &lis3_dev);
+ clear_bit(0, &lis3_dev.misc_opened); /* release the device */
return 0;
}
@@ -207,10 +223,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
if (count < 1)
return -EINVAL;
- add_wait_queue(&adev.misc_wait, &wait);
+ add_wait_queue(&lis3_dev.misc_wait, &wait);
while (true) {
set_current_state(TASK_INTERRUPTIBLE);
- data = atomic_xchg(&adev.count, 0);
+ data = atomic_xchg(&lis3_dev.count, 0);
if (data)
break;
@@ -240,22 +256,22 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf,
out:
__set_current_state(TASK_RUNNING);
- remove_wait_queue(&adev.misc_wait, &wait);
+ remove_wait_queue(&lis3_dev.misc_wait, &wait);
return retval;
}
static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait)
{
- poll_wait(file, &adev.misc_wait, wait);
- if (atomic_read(&adev.count))
+ poll_wait(file, &lis3_dev.misc_wait, wait);
+ if (atomic_read(&lis3_dev.count))
return POLLIN | POLLRDNORM;
return 0;
}
static int lis3lv02d_misc_fasync(int fd, struct file *file, int on)
{
- return fasync_helper(fd, file, on, &adev.async_queue);
+ return fasync_helper(fd, file, on, &lis3_dev.async_queue);
}
static const struct file_operations lis3lv02d_misc_fops = {
@@ -283,12 +299,12 @@ static int lis3lv02d_joystick_kthread(void *data)
int x, y, z;
while (!kthread_should_stop()) {
- lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
- input_report_abs(adev.idev, ABS_X, x - adev.xcalib);
- input_report_abs(adev.idev, ABS_Y, y - adev.ycalib);
- input_report_abs(adev.idev, ABS_Z, z - adev.zcalib);
+ lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+ input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib);
+ input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib);
+ input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib);
- input_sync(adev.idev);
+ input_sync(lis3_dev.idev);
try_to_freeze();
msleep_interruptible(MDPS_POLL_INTERVAL);
@@ -299,11 +315,11 @@ static int lis3lv02d_joystick_kthread(void *data)
static int lis3lv02d_joystick_open(struct input_dev *input)
{
- lis3lv02d_increase_use(&adev);
- adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
- if (IS_ERR(adev.kthread)) {
- lis3lv02d_decrease_use(&adev);
- return PTR_ERR(adev.kthread);
+ lis3lv02d_increase_use(&lis3_dev);
+ lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d");
+ if (IS_ERR(lis3_dev.kthread)) {
+ lis3lv02d_decrease_use(&lis3_dev);
+ return PTR_ERR(lis3_dev.kthread);
}
return 0;
@@ -311,45 +327,46 @@ static int lis3lv02d_joystick_open(struct input_dev *input)
static void lis3lv02d_joystick_close(struct input_dev *input)
{
- kthread_stop(adev.kthread);
- lis3lv02d_decrease_use(&adev);
+ kthread_stop(lis3_dev.kthread);
+ lis3lv02d_decrease_use(&lis3_dev);
}
static inline void lis3lv02d_calibrate_joystick(void)
{
- lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib);
+ lis3lv02d_get_xyz(&lis3_dev,
+ &lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib);
}
int lis3lv02d_joystick_enable(void)
{
int err;
- if (adev.idev)
+ if (lis3_dev.idev)
return -EINVAL;
- adev.idev = input_allocate_device();
- if (!adev.idev)
+ lis3_dev.idev = input_allocate_device();
+ if (!lis3_dev.idev)
return -ENOMEM;
lis3lv02d_calibrate_joystick();
- adev.idev->name = "ST LIS3LV02DL Accelerometer";
- adev.idev->phys = DRIVER_NAME "/input0";
- adev.idev->id.bustype = BUS_HOST;
- adev.idev->id.vendor = 0;
- adev.idev->dev.parent = &adev.pdev->dev;
- adev.idev->open = lis3lv02d_joystick_open;
- adev.idev->close = lis3lv02d_joystick_close;
+ lis3_dev.idev->name = "ST LIS3LV02DL Accelerometer";
+ lis3_dev.idev->phys = DRIVER_NAME "/input0";
+ lis3_dev.idev->id.bustype = BUS_HOST;
+ lis3_dev.idev->id.vendor = 0;
+ lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev;
+ lis3_dev.idev->open = lis3lv02d_joystick_open;
+ lis3_dev.idev->close = lis3lv02d_joystick_close;
- set_bit(EV_ABS, adev.idev->evbit);
- input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
- input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
- input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3);
+ set_bit(EV_ABS, lis3_dev.idev->evbit);
+ input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+ input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
+ input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3);
- err = input_register_device(adev.idev);
+ err = input_register_device(lis3_dev.idev);
if (err) {
- input_free_device(adev.idev);
- adev.idev = NULL;
+ input_free_device(lis3_dev.idev);
+ lis3_dev.idev = NULL;
}
return err;
@@ -358,71 +375,40 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable);
void lis3lv02d_joystick_disable(void)
{
- if (!adev.idev)
+ if (!lis3_dev.idev)
return;
misc_deregister(&lis3lv02d_misc_device);
- input_unregister_device(adev.idev);
- adev.idev = NULL;
+ input_unregister_device(lis3_dev.idev);
+ lis3_dev.idev = NULL;
}
EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable);
-/*
- * Initialise the accelerometer and the various subsystems.
- * Should be rather independant of the bus system.
- */
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev)
-{
- mutex_init(&dev->lock);
- lis3lv02d_add_fs(dev->device);
- lis3lv02d_increase_use(dev);
-
- if (lis3lv02d_joystick_enable())
- printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
-
- printk("lis3_init_device: irq %d\n", dev->irq);
-
- /* if we did not get an IRQ from ACPI - we have nothing more to do */
- if (!dev->irq) {
- printk(KERN_ERR DRIVER_NAME
- ": No IRQ in ACPI. Disabling /dev/freefall\n");
- goto out;
- }
-
- printk("lis3: registering device\n");
- if (misc_register(&lis3lv02d_misc_device))
- printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
-out:
- lis3lv02d_decrease_use(dev);
- return 0;
-}
-EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
-
/* Sysfs stuff */
static ssize_t lis3lv02d_position_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int x, y, z;
- lis3lv02d_increase_use(&adev);
- lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z);
- lis3lv02d_decrease_use(&adev);
+ lis3lv02d_increase_use(&lis3_dev);
+ lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z);
+ lis3lv02d_decrease_use(&lis3_dev);
return sprintf(buf, "(%d,%d,%d)\n", x, y, z);
}
static ssize_t lis3lv02d_calibrate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib);
+ return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib);
}
static ssize_t lis3lv02d_calibrate_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
- lis3lv02d_increase_use(&adev);
+ lis3lv02d_increase_use(&lis3_dev);
lis3lv02d_calibrate_joystick();
- lis3lv02d_decrease_use(&adev);
+ lis3lv02d_decrease_use(&lis3_dev);
return count;
}
@@ -434,9 +420,9 @@ static ssize_t lis3lv02d_rate_show(struct device *dev,
u8 ctrl;
int val;
- lis3lv02d_increase_use(&adev);
- adev.read(adev.device->handle, CTRL_REG1, &ctrl);
- lis3lv02d_decrease_use(&adev);
+ lis3lv02d_increase_use(&lis3_dev);
+ lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
+ lis3lv02d_decrease_use(&lis3_dev);
val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4;
return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]);
}
@@ -458,23 +444,73 @@ static struct attribute_group lis3lv02d_attribute_group = {
};
-static int lis3lv02d_add_fs(struct acpi_device *device)
+static int lis3lv02d_add_fs(struct lis3lv02d *lis3)
{
- adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
- if (IS_ERR(adev.pdev))
- return PTR_ERR(adev.pdev);
+ lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+ if (IS_ERR(lis3_dev.pdev))
+ return PTR_ERR(lis3_dev.pdev);
- return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+ return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
}
int lis3lv02d_remove_fs(void)
{
- sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group);
- platform_device_unregister(adev.pdev);
+ sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group);
+ platform_device_unregister(lis3_dev.pdev);
return 0;
}
EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs);
+/*
+ * Initialise the accelerometer and the various subsystems.
+ * Should be rather independant of the bus system.
+ */
+int lis3lv02d_init_device(struct lis3lv02d *dev)
+{
+ dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I);
+
+ switch (dev->whoami) {
+ case LIS_DOUBLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n");
+ dev->read_data = lis3lv02d_read_16;
+ dev->mdps_max_val = 2048;
+ break;
+ case LIS_SINGLE_ID:
+ printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n");
+ dev->read_data = lis3lv02d_read_8;
+ dev->mdps_max_val = 128;
+ break;
+ default:
+ printk(KERN_ERR DRIVER_NAME
+ ": unknown sensor type 0x%X\n", lis3_dev.whoami);
+ return -EINVAL;
+ }
+
+ mutex_init(&dev->lock);
+ lis3lv02d_add_fs(dev);
+ lis3lv02d_increase_use(dev);
+
+ if (lis3lv02d_joystick_enable())
+ printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n");
+
+ printk("lis3_init_device: irq %d\n", dev->irq);
+
+ /* bail if we did not get an IRQ from the bus layer */
+ if (!dev->irq) {
+ printk(KERN_ERR DRIVER_NAME
+ ": No IRQ. Disabling /dev/freefall\n");
+ goto out;
+ }
+
+ printk("lis3: registering device\n");
+ if (misc_register(&lis3lv02d_misc_device))
+ printk(KERN_ERR DRIVER_NAME ": misc_register failed\n");
+out:
+ lis3lv02d_decrease_use(dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(lis3lv02d_init_device);
+
MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver");
MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek");
MODULE_LICENSE("GPL");
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 75972bf372f..745ec96806d 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -159,14 +159,14 @@ struct axis_conversion {
s8 z;
};
-struct acpi_lis3lv02d {
- struct acpi_device *device; /* The ACPI device */
- acpi_status (*init) (acpi_handle handle);
- acpi_status (*write) (acpi_handle handle, int reg, u8 val);
- acpi_status (*read) (acpi_handle handle, int reg, u8 *ret);
+struct lis3lv02d {
+ void *bus_priv; /* used by the bus layer only */
+ int (*init) (struct lis3lv02d *lis3);
+ int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
+ int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
u8 whoami; /* 3Ah: 2-byte registries, 3Bh: 1-byte registries */
- s16 (*read_data) (acpi_handle handle, int reg);
+ s16 (*read_data) (struct lis3lv02d *lis3, int reg);
int mdps_max_val;
struct input_dev *idev; /* input device */
@@ -187,11 +187,11 @@ struct acpi_lis3lv02d {
unsigned long misc_opened; /* bit0: whether the device is open */
};
-int lis3lv02d_init_device(struct acpi_lis3lv02d *dev);
+int lis3lv02d_init_device(struct lis3lv02d *lis3);
int lis3lv02d_joystick_enable(void);
void lis3lv02d_joystick_disable(void);
-void lis3lv02d_poweroff(acpi_handle handle);
-void lis3lv02d_poweron(acpi_handle handle);
+void lis3lv02d_poweroff(struct lis3lv02d *lis3);
+void lis3lv02d_poweron(struct lis3lv02d *lis3);
int lis3lv02d_remove_fs(void);
-extern struct acpi_lis3lv02d adev;
+extern struct lis3lv02d lis3_dev;
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
new file mode 100644
index 00000000000..07ae74b0e19
--- /dev/null
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -0,0 +1,114 @@
+/*
+ * lis3lv02d_spi - SPI glue layer for lis3lv02d
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+#include "lis3lv02d.h"
+
+#define DRV_NAME "lis3lv02d_spi"
+#define LIS3_SPI_READ 0x80
+
+static int lis3_spi_read(struct lis3lv02d *lis3, int reg, u8 *v)
+{
+ struct spi_device *spi = lis3->bus_priv;
+ int ret = spi_w8r8(spi, reg | LIS3_SPI_READ);
+ if (ret < 0)
+ return -EINVAL;
+
+ *v = (u8) ret;
+ return 0;
+}
+
+static int lis3_spi_write(struct lis3lv02d *lis3, int reg, u8 val)
+{
+ u8 tmp[2] = { reg, val };
+ struct spi_device *spi = lis3->bus_priv;
+ return spi_write(spi, tmp, sizeof(tmp));
+}
+
+static int lis3_spi_init(struct lis3lv02d *lis3)
+{
+ u8 reg;
+ int ret;
+
+ /* power up the device */
+ ret = lis3->read(lis3, CTRL_REG1, &reg);
+ if (ret < 0)
+ return ret;
+
+ reg |= CTRL1_PD0;
+ return lis3->write(lis3, CTRL_REG1, reg);
+}
+
+static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 };
+
+static int __devinit lis302dl_spi_probe(struct spi_device *spi)
+{
+ int ret;
+
+ spi->bits_per_word = 8;
+ spi->mode = SPI_MODE_0;
+ ret = spi_setup(spi);
+ if (ret < 0)
+ return ret;
+
+ lis3_dev.bus_priv = spi;
+ lis3_dev.init = lis3_spi_init;
+ lis3_dev.read = lis3_spi_read;
+ lis3_dev.write = lis3_spi_write;
+ lis3_dev.irq = spi->irq;
+ lis3_dev.ac = lis3lv02d_axis_normal;
+ spi_set_drvdata(spi, &lis3_dev);
+
+ ret = lis3lv02d_init_device(&lis3_dev);
+ return ret;
+}
+
+static int __devexit lis302dl_spi_remove(struct spi_device *spi)
+{
+ struct lis3lv02d *lis3 = spi_get_drvdata(spi);
+ lis3lv02d_joystick_disable();
+ lis3lv02d_poweroff(lis3);
+ return 0;
+}
+
+static struct spi_driver lis302dl_spi_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = lis302dl_spi_probe,
+ .remove = __devexit_p(lis302dl_spi_remove),
+};
+
+static int __init lis302dl_init(void)
+{
+ return spi_register_driver(&lis302dl_spi_driver);
+}
+
+static void __exit lis302dl_exit(void)
+{
+ spi_unregister_driver(&lis302dl_spi_driver);
+}
+
+module_init(lis302dl_init);
+module_exit(lis302dl_exit);
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("lis3lv02d SPI glue layer");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
new file mode 100644
index 00000000000..091d95f38aa
--- /dev/null
+++ b/drivers/hwmon/lm95241.c
@@ -0,0 +1,527 @@
+/*
+ * lm95241.c - Part of lm_sensors, Linux kernel modules for hardware
+ * monitoring
+ * Copyright (C) 2008 Davide Rizzo <elpa-rizzo@gmail.com>
+ *
+ * Based on the max1619 driver. The LM95241 is a sensor chip made by National
+ * Semiconductors.
+ * It reports up to three temperatures (its own plus up to
+ * two external ones). Complete datasheet can be
+ * obtained from National's website at:
+ * http://www.national.com/ds.cgi/LM/LM95241.pdf
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/sysfs.h>
+
+static const unsigned short normal_i2c[] = {
+ 0x19, 0x2a, 0x2b, I2C_CLIENT_END};
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(lm95241);
+
+/* LM95241 registers */
+#define LM95241_REG_R_MAN_ID 0xFE
+#define LM95241_REG_R_CHIP_ID 0xFF
+#define LM95241_REG_R_STATUS 0x02
+#define LM95241_REG_RW_CONFIG 0x03
+#define LM95241_REG_RW_REM_FILTER 0x06
+#define LM95241_REG_RW_TRUTHERM 0x07
+#define LM95241_REG_W_ONE_SHOT 0x0F
+#define LM95241_REG_R_LOCAL_TEMPH 0x10
+#define LM95241_REG_R_REMOTE1_TEMPH 0x11
+#define LM95241_REG_R_REMOTE2_TEMPH 0x12
+#define LM95241_REG_R_LOCAL_TEMPL 0x20
+#define LM95241_REG_R_REMOTE1_TEMPL 0x21
+#define LM95241_REG_R_REMOTE2_TEMPL 0x22
+#define LM95241_REG_RW_REMOTE_MODEL 0x30
+
+/* LM95241 specific bitfields */
+#define CFG_STOP 0x40
+#define CFG_CR0076 0x00
+#define CFG_CR0182 0x10
+#define CFG_CR1000 0x20
+#define CFG_CR2700 0x30
+#define R1MS_SHIFT 0
+#define R2MS_SHIFT 2
+#define R1MS_MASK (0x01 << (R1MS_SHIFT))
+#define R2MS_MASK (0x01 << (R2MS_SHIFT))
+#define R1DF_SHIFT 1
+#define R2DF_SHIFT 2
+#define R1DF_MASK (0x01 << (R1DF_SHIFT))
+#define R2DF_MASK (0x01 << (R2DF_SHIFT))
+#define R1FE_MASK 0x01
+#define R2FE_MASK 0x05
+#define TT1_SHIFT 0
+#define TT2_SHIFT 4
+#define TT_OFF 0
+#define TT_ON 1
+#define TT_MASK 7
+#define MANUFACTURER_ID 0x01
+#define DEFAULT_REVISION 0xA4
+
+/* Conversions and various macros */
+#define TEMP_FROM_REG(val_h, val_l) (((val_h) & 0x80 ? (val_h) - 0x100 : \
+ (val_h)) * 1000 + (val_l) * 1000 / 256)
+
+/* Functions declaration */
+static int lm95241_attach_adapter(struct i2c_adapter *adapter);
+static int lm95241_detect(struct i2c_adapter *adapter, int address,
+ int kind);
+static void lm95241_init_client(struct i2c_client *client);
+static int lm95241_detach_client(struct i2c_client *client);
+static struct lm95241_data *lm95241_update_device(struct device *dev);
+
+/* Driver data (common to all clients) */
+static struct i2c_driver lm95241_driver = {
+ .driver = {
+ .name = "lm95241",
+ },
+ .attach_adapter = lm95241_attach_adapter,
+ .detach_client = lm95241_detach_client,
+};
+
+/* Client data (each client gets its own) */
+struct lm95241_data {
+ struct i2c_client client;
+ struct device *hwmon_dev;
+ struct mutex update_lock;
+ unsigned long last_updated, rate; /* in jiffies */
+ char valid; /* zero until following fields are valid */
+ /* registers values */
+ u8 local_h, local_l; /* local */
+ u8 remote1_h, remote1_l; /* remote1 */
+ u8 remote2_h, remote2_l; /* remote2 */
+ u8 config, model, trutherm;
+};
+
+/* Sysfs stuff */
+#define show_temp(value) \
+static ssize_t show_##value(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct lm95241_data *data = lm95241_update_device(dev); \
+ snprintf(buf, PAGE_SIZE - 1, "%d\n", \
+ TEMP_FROM_REG(data->value##_h, data->value##_l)); \
+ return strlen(buf); \
+}
+show_temp(local);
+show_temp(remote1);
+show_temp(remote2);
+
+static ssize_t show_rate(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct lm95241_data *data = lm95241_update_device(dev);
+
+ snprintf(buf, PAGE_SIZE - 1, "%lu\n", 1000 * data->rate / HZ);
+ return strlen(buf);
+}
+
+static ssize_t set_rate(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ strict_strtol(buf, 10, &data->rate);
+ data->rate = data->rate * HZ / 1000;
+
+ return count;
+}
+
+#define show_type(flag) \
+static ssize_t show_type##flag(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ snprintf(buf, PAGE_SIZE - 1, \
+ data->model & R##flag##MS_MASK ? "1\n" : "2\n"); \
+ return strlen(buf); \
+}
+show_type(1);
+show_type(2);
+
+#define show_min(flag) \
+static ssize_t show_min##flag(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ snprintf(buf, PAGE_SIZE - 1, \
+ data->config & R##flag##DF_MASK ? \
+ "-127000\n" : "0\n"); \
+ return strlen(buf); \
+}
+show_min(1);
+show_min(2);
+
+#define show_max(flag) \
+static ssize_t show_max##flag(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ snprintf(buf, PAGE_SIZE - 1, \
+ data->config & R##flag##DF_MASK ? \
+ "127000\n" : "255000\n"); \
+ return strlen(buf); \
+}
+show_max(1);
+show_max(2);
+
+#define set_type(flag) \
+static ssize_t set_type##flag(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ long val; \
+ strict_strtol(buf, 10, &val); \
+\
+ if ((val == 1) || (val == 2)) { \
+\
+ mutex_lock(&data->update_lock); \
+\
+ data->trutherm &= ~(TT_MASK << TT##flag##_SHIFT); \
+ if (val == 1) { \
+ data->model |= R##flag##MS_MASK; \
+ data->trutherm |= (TT_ON << TT##flag##_SHIFT); \
+ } \
+ else { \
+ data->model &= ~R##flag##MS_MASK; \
+ data->trutherm |= (TT_OFF << TT##flag##_SHIFT); \
+ } \
+\
+ data->valid = 0; \
+\
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL, \
+ data->model); \
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM, \
+ data->trutherm); \
+\
+ mutex_unlock(&data->update_lock); \
+\
+ } \
+ return count; \
+}
+set_type(1);
+set_type(2);
+
+#define set_min(flag) \
+static ssize_t set_min##flag(struct device *dev, \
+ struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ long val; \
+ strict_strtol(buf, 10, &val); \
+\
+ mutex_lock(&data->update_lock); \
+\
+ if (val < 0) \
+ data->config |= R##flag##DF_MASK; \
+ else \
+ data->config &= ~R##flag##DF_MASK; \
+\
+ data->valid = 0; \
+\
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+ data->config); \
+\
+ mutex_unlock(&data->update_lock); \
+\
+ return count; \
+}
+set_min(1);
+set_min(2);
+
+#define set_max(flag) \
+static ssize_t set_max##flag(struct device *dev, \
+ struct device_attribute *devattr, const char *buf, size_t count) \
+{ \
+ struct i2c_client *client = to_i2c_client(dev); \
+ struct lm95241_data *data = i2c_get_clientdata(client); \
+\
+ long val; \
+ strict_strtol(buf, 10, &val); \
+\
+ mutex_lock(&data->update_lock); \
+\
+ if (val <= 127000) \
+ data->config |= R##flag##DF_MASK; \
+ else \
+ data->config &= ~R##flag##DF_MASK; \
+\
+ data->valid = 0; \
+\
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG, \
+ data->config); \
+\
+ mutex_unlock(&data->update_lock); \
+\
+ return count; \
+}
+set_max(1);
+set_max(2);
+
+static DEVICE_ATTR(temp1_input, S_IRUGO, show_local, NULL);
+static DEVICE_ATTR(temp2_input, S_IRUGO, show_remote1, NULL);
+static DEVICE_ATTR(temp3_input, S_IRUGO, show_remote2, NULL);
+static DEVICE_ATTR(temp2_type, S_IWUSR | S_IRUGO, show_type1, set_type1);
+static DEVICE_ATTR(temp3_type, S_IWUSR | S_IRUGO, show_type2, set_type2);
+static DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_min1, set_min1);
+static DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_min2, set_min2);
+static DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_max1, set_max1);
+static DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_max2, set_max2);
+static DEVICE_ATTR(rate, S_IWUSR | S_IRUGO, show_rate, set_rate);
+
+static struct attribute *lm95241_attributes[] = {
+ &dev_attr_temp1_input.attr,
+ &dev_attr_temp2_input.attr,
+ &dev_attr_temp3_input.attr,
+ &dev_attr_temp2_type.attr,
+ &dev_attr_temp3_type.attr,
+ &dev_attr_temp2_min.attr,
+ &dev_attr_temp3_min.attr,
+ &dev_attr_temp2_max.attr,
+ &dev_attr_temp3_max.attr,
+ &dev_attr_rate.attr,
+ NULL
+};
+
+static const struct attribute_group lm95241_group = {
+ .attrs = lm95241_attributes,
+};
+
+/* Init/exit code */
+static int lm95241_attach_adapter(struct i2c_adapter *adapter)
+{
+ if (!(adapter->class & I2C_CLASS_HWMON))
+ return 0;
+ return i2c_probe(adapter, &addr_data, lm95241_detect);
+}
+
+/*
+ * The following function does more than just detection. If detection
+ * succeeds, it also registers the new chip.
+ */
+static int lm95241_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+ struct i2c_client *new_client;
+ struct lm95241_data *data;
+ int err = 0;
+ const char *name = "";
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ goto exit;
+
+ data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ /* The common I2C client data is placed right before the
+ LM95241-specific data. */
+ new_client = &data->client;
+ i2c_set_clientdata(new_client, data);
+ new_client->addr = address;
+ new_client->adapter = adapter;
+ new_client->driver = &lm95241_driver;
+ new_client->flags = 0;
+
+ /*
+ * Now we do the remaining detection. A negative kind means that
+ * the driver was loaded with no force parameter (default), so we
+ * must both detect and identify the chip. A zero kind means that
+ * the driver was loaded with the force parameter, the detection
+ * step shall be skipped. A positive kind means that the driver
+ * was loaded with the force parameter and a given kind of chip is
+ * requested, so both the detection and the identification steps
+ * are skipped.
+ */
+ if (kind < 0) { /* detection */
+ if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+ != MANUFACTURER_ID)
+ || (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+ < DEFAULT_REVISION)) {
+ dev_dbg(&adapter->dev,
+ "LM95241 detection failed at 0x%02x.\n",
+ address);
+ goto exit_free;
+ }
+ }
+
+ if (kind <= 0) { /* identification */
+ if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
+ == MANUFACTURER_ID)
+ && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
+ >= DEFAULT_REVISION)) {
+
+ kind = lm95241;
+
+ if (kind <= 0) { /* identification failed */
+ dev_info(&adapter->dev, "Unsupported chip\n");
+ goto exit_free;
+ }
+ }
+ }
+
+ if (kind == lm95241)
+ name = "lm95241";
+
+ /* We can fill in the remaining client fields */
+ strlcpy(new_client->name, name, I2C_NAME_SIZE);
+ data->valid = 0;
+ mutex_init(&data->update_lock);
+
+ /* Tell the I2C layer a new client has arrived */
+ err = i2c_attach_client(new_client);
+ if (err)
+ goto exit_free;
+
+ /* Initialize the LM95241 chip */
+ lm95241_init_client(new_client);
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
+ if (err)
+ goto exit_detach;
+
+ data->hwmon_dev = hwmon_device_register(&new_client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ err = PTR_ERR(data->hwmon_dev);
+ goto exit_remove_files;
+ }
+
+ return 0;
+
+exit_remove_files:
+ sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
+exit_detach:
+ i2c_detach_client(new_client);
+exit_free:
+ kfree(data);
+exit:
+ return err;
+}
+
+static void lm95241_init_client(struct i2c_client *client)
+{
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ data->rate = HZ; /* 1 sec default */
+ data->valid = 0;
+ data->config = CFG_CR0076;
+ data->model = 0;
+ data->trutherm = (TT_OFF << TT1_SHIFT) | (TT_OFF << TT2_SHIFT);
+
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_CONFIG,
+ data->config);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REM_FILTER,
+ R1FE_MASK | R2FE_MASK);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_TRUTHERM,
+ data->trutherm);
+ i2c_smbus_write_byte_data(client, LM95241_REG_RW_REMOTE_MODEL,
+ data->model);
+}
+
+static int lm95241_detach_client(struct i2c_client *client)
+{
+ struct lm95241_data *data = i2c_get_clientdata(client);
+ int err;
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &lm95241_group);
+
+ err = i2c_detach_client(client);
+ if (err)
+ return err;
+
+ kfree(data);
+ return 0;
+}
+
+static struct lm95241_data *lm95241_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lm95241_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->update_lock);
+
+ if (time_after(jiffies, data->last_updated + data->rate) ||
+ !data->valid) {
+ dev_dbg(&client->dev, "Updating lm95241 data.\n");
+ data->local_h =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_LOCAL_TEMPH);
+ data->local_l =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_LOCAL_TEMPL);
+ data->remote1_h =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE1_TEMPH);
+ data->remote1_l =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE1_TEMPL);
+ data->remote2_h =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE2_TEMPH);
+ data->remote2_l =
+ i2c_smbus_read_byte_data(client,
+ LM95241_REG_R_REMOTE2_TEMPL);
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+static int __init sensors_lm95241_init(void)
+{
+ return i2c_add_driver(&lm95241_driver);
+}
+
+static void __exit sensors_lm95241_exit(void)
+{
+ i2c_del_driver(&lm95241_driver);
+}
+
+MODULE_AUTHOR("Davide Rizzo <elpa-rizzo@gmail.com>");
+MODULE_DESCRIPTION("LM95241 sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(sensors_lm95241_init);
+module_exit(sensors_lm95241_exit);
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c
new file mode 100644
index 00000000000..9386e2a3921
--- /dev/null
+++ b/drivers/hwmon/ltc4215.c
@@ -0,0 +1,364 @@
+/*
+ * Driver for Linear Technology LTC4215 I2C Hot Swap Controller
+ *
+ * Copyright (C) 2009 Ira W. Snyder <iws@ovro.caltech.edu>
+ *
+ * This program is free software; 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.
+ *
+ * Datasheet:
+ * http://www.linear.com/pc/downloadDocument.do?navId=H0,C1,C1003,C1006,C1163,P17572,D12697
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+
+static const unsigned short normal_i2c[] = { I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_1(ltc4215);
+
+/* Here are names of the chip's registers (a.k.a. commands) */
+enum ltc4215_cmd {
+ LTC4215_CONTROL = 0x00, /* rw */
+ LTC4215_ALERT = 0x01, /* rw */
+ LTC4215_STATUS = 0x02, /* ro */
+ LTC4215_FAULT = 0x03, /* rw */
+ LTC4215_SENSE = 0x04, /* rw */
+ LTC4215_SOURCE = 0x05, /* rw */
+ LTC4215_ADIN = 0x06, /* rw */
+};
+
+struct ltc4215_data {
+ struct device *hwmon_dev;
+
+ struct mutex update_lock;
+ bool valid;
+ unsigned long last_updated; /* in jiffies */
+
+ /* Registers */
+ u8 regs[7];
+};
+
+static struct ltc4215_data *ltc4215_update_device(struct device *dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct ltc4215_data *data = i2c_get_clientdata(client);
+ s32 val;
+ int i;
+
+ mutex_lock(&data->update_lock);
+
+ /* The chip's A/D updates 10 times per second */
+ if (time_after(jiffies, data->last_updated + HZ / 10) || !data->valid) {
+
+ dev_dbg(&client->dev, "Starting ltc4215 update\n");
+
+ /* Read all registers */
+ for (i = 0; i < ARRAY_SIZE(data->regs); i++) {
+ val = i2c_smbus_read_byte_data(client, i);
+ if (unlikely(val < 0))
+ data->regs[i] = 0;
+ else
+ data->regs[i] = val;
+ }
+
+ data->last_updated = jiffies;
+ data->valid = 1;
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return data;
+}
+
+/* Return the voltage from the given register in millivolts */
+static int ltc4215_get_voltage(struct device *dev, u8 reg)
+{
+ struct ltc4215_data *data = ltc4215_update_device(dev);
+ const u8 regval = data->regs[reg];
+ u32 voltage = 0;
+
+ switch (reg) {
+ case LTC4215_SENSE:
+ /* 151 uV per increment */
+ voltage = regval * 151 / 1000;
+ break;
+ case LTC4215_SOURCE:
+ /* 60.5 mV per increment */
+ voltage = regval * 605 / 10;
+ break;
+ case LTC4215_ADIN:
+ /* The ADIN input is divided by 12.5, and has 4.82 mV
+ * per increment, so we have the additional multiply */
+ voltage = regval * 482 * 125 / 1000;
+ break;
+ default:
+ /* If we get here, the developer messed up */
+ WARN_ON_ONCE(1);
+ break;
+ }
+
+ return voltage;
+}
+
+/* Return the current from the sense resistor in mA */
+static unsigned int ltc4215_get_current(struct device *dev)
+{
+ struct ltc4215_data *data = ltc4215_update_device(dev);
+
+ /* The strange looking conversions that follow are fixed-point
+ * math, since we cannot do floating point in the kernel.
+ *
+ * Step 1: convert sense register to microVolts
+ * Step 2: convert voltage to milliAmperes
+ *
+ * If you play around with the V=IR equation, you come up with
+ * the following: X uV / Y mOhm == Z mA
+ *
+ * With the resistors that are fractions of a milliOhm, we multiply
+ * the voltage and resistance by 10, to shift the decimal point.
+ * Now we can use the normal division operator again.
+ */
+
+ /* Calculate voltage in microVolts (151 uV per increment) */
+ const unsigned int voltage = data->regs[LTC4215_SENSE] * 151;
+
+ /* Calculate current in milliAmperes (4 milliOhm sense resistor) */
+ const unsigned int curr = voltage / 4;
+
+ return curr;
+}
+
+static ssize_t ltc4215_show_voltage(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+ const int voltage = ltc4215_get_voltage(dev, attr->index);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", voltage);
+}
+
+static ssize_t ltc4215_show_current(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ const unsigned int curr = ltc4215_get_current(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", curr);
+}
+
+static ssize_t ltc4215_show_power(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ const unsigned int curr = ltc4215_get_current(dev);
+ const int output_voltage = ltc4215_get_voltage(dev, LTC4215_ADIN);
+
+ /* current in mA * voltage in mV == power in uW */
+ const unsigned int power = abs(output_voltage * curr);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", power);
+}
+
+static ssize_t ltc4215_show_alarm(struct device *dev,
+ struct device_attribute *da,
+ char *buf)
+{
+ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(da);
+ struct ltc4215_data *data = ltc4215_update_device(dev);
+ const u8 reg = data->regs[attr->index];
+ const u32 mask = attr->nr;
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", (reg & mask) ? 1 : 0);
+}
+
+/* These macros are used below in constructing device attribute objects
+ * for use with sysfs_create_group() to make a sysfs device file
+ * for each register.
+ */
+
+#define LTC4215_VOLTAGE(name, ltc4215_cmd_idx) \
+ static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+ ltc4215_show_voltage, NULL, ltc4215_cmd_idx)
+
+#define LTC4215_CURRENT(name) \
+ static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+ ltc4215_show_current, NULL, 0);
+
+#define LTC4215_POWER(name) \
+ static SENSOR_DEVICE_ATTR(name, S_IRUGO, \
+ ltc4215_show_power, NULL, 0);
+
+#define LTC4215_ALARM(name, mask, reg) \
+ static SENSOR_DEVICE_ATTR_2(name, S_IRUGO, \
+ ltc4215_show_alarm, NULL, (mask), reg)
+
+/* Construct a sensor_device_attribute structure for each register */
+
+/* Current */
+LTC4215_CURRENT(curr1_input);
+LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS);
+
+/* Power (virtual) */
+LTC4215_POWER(power1_input);
+LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS);
+
+/* Input Voltage */
+LTC4215_VOLTAGE(in1_input, LTC4215_ADIN);
+LTC4215_ALARM(in1_max_alarm, (1 << 0), LTC4215_STATUS);
+LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS);
+
+/* Output Voltage */
+LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE);
+
+/* Finally, construct an array of pointers to members of the above objects,
+ * as required for sysfs_create_group()
+ */
+static struct attribute *ltc4215_attributes[] = {
+ &sensor_dev_attr_curr1_input.dev_attr.attr,
+ &sensor_dev_attr_curr1_max_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_power1_input.dev_attr.attr,
+ &sensor_dev_attr_power1_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_in1_input.dev_attr.attr,
+ &sensor_dev_attr_in1_max_alarm.dev_attr.attr,
+ &sensor_dev_attr_in1_min_alarm.dev_attr.attr,
+
+ &sensor_dev_attr_in2_input.dev_attr.attr,
+
+ NULL,
+};
+
+static const struct attribute_group ltc4215_group = {
+ .attrs = ltc4215_attributes,
+};
+
+static int ltc4215_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct ltc4215_data *data;
+ int ret;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (!data) {
+ ret = -ENOMEM;
+ goto out_kzalloc;
+ }
+
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->update_lock);
+
+ /* Initialize the LTC4215 chip */
+ /* TODO */
+
+ /* Register sysfs hooks */
+ ret = sysfs_create_group(&client->dev.kobj, &ltc4215_group);
+ if (ret)
+ goto out_sysfs_create_group;
+
+ data->hwmon_dev = hwmon_device_register(&client->dev);
+ if (IS_ERR(data->hwmon_dev)) {
+ ret = PTR_ERR(data->hwmon_dev);
+ goto out_hwmon_device_register;
+ }
+
+ return 0;
+
+out_hwmon_device_register:
+ sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+out_sysfs_create_group:
+ kfree(data);
+out_kzalloc:
+ return ret;
+}
+
+static int ltc4215_remove(struct i2c_client *client)
+{
+ struct ltc4215_data *data = i2c_get_clientdata(client);
+
+ hwmon_device_unregister(data->hwmon_dev);
+ sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
+
+ kfree(data);
+
+ return 0;
+}
+
+static int ltc4215_detect(struct i2c_client *client,
+ int kind,
+ struct i2c_board_info *info)
+{
+ struct i2c_adapter *adapter = client->adapter;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ if (kind < 0) { /* probed detection - check the chip type */
+ s32 v; /* 8 bits from the chip, or -ERRNO */
+
+ /*
+ * Register 0x01 bit b7 is reserved, expect 0
+ * Register 0x03 bit b6 and b7 are reserved, expect 0
+ */
+ v = i2c_smbus_read_byte_data(client, LTC4215_ALERT);
+ if (v < 0 || (v & (1 << 7)) != 0)
+ return -ENODEV;
+
+ v = i2c_smbus_read_byte_data(client, LTC4215_FAULT);
+ if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0)
+ return -ENODEV;
+ }
+
+ strlcpy(info->type, "ltc4215", I2C_NAME_SIZE);
+ dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n",
+ kind < 0 ? "probed" : "forced",
+ client->addr);
+
+ return 0;
+}
+
+static const struct i2c_device_id ltc4215_id[] = {
+ { "ltc4215", ltc4215 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ltc4215_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver ltc4215_driver = {
+ .class = I2C_CLASS_HWMON,
+ .driver = {
+ .name = "ltc4215",
+ },
+ .probe = ltc4215_probe,
+ .remove = ltc4215_remove,
+ .id_table = ltc4215_id,
+ .detect = ltc4215_detect,
+ .address_data = &addr_data,
+};
+
+static int __init ltc4215_init(void)
+{
+ return i2c_add_driver(&ltc4215_driver);
+}
+
+static void __exit ltc4215_exit(void)
+{
+ i2c_del_driver(&ltc4215_driver);
+}
+
+MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
+MODULE_DESCRIPTION("LTC4215 driver");
+MODULE_LICENSE("GPL");
+
+module_init(ltc4215_init);
+module_exit(ltc4215_exit);
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/hwmon/pcf8591.c
index 16ce3e19377..1d7ffebd679 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/hwmon/pcf8591.c
@@ -1,6 +1,6 @@
/*
Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
- Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
+ Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
the help of Jean Delvare <khali@linux-fr.org>
This program is free software; you can redistribute it and/or modify
@@ -41,13 +41,13 @@ MODULE_PARM_DESC(input_mode,
" 3 = two differential inputs\n");
/* The PCF8591 control byte
- 7 6 5 4 3 2 1 0
+ 7 6 5 4 3 2 1 0
| 0 |AOEF| AIP | 0 |AINC| AICH | */
/* Analog Output Enable Flag (analog output active if 1) */
#define PCF8591_CONTROL_AOEF 0x40
-
-/* Analog Input Programming
+
+/* Analog Input Programming
0x00 = four single ended inputs
0x10 = three differential inputs
0x20 = single ended and differential mixed
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(input_mode,
#define PCF8591_CONTROL_AINC 0x04
/* Channel selection
- 0x00 = channel 0
+ 0x00 = channel 0
0x01 = channel 1
0x02 = channel 2
0x03 = channel 3 */
@@ -114,7 +114,7 @@ static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr
return -EINVAL;
}
-static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
+static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
show_out0_ouput, set_out0_output);
static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
@@ -139,7 +139,7 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr
return count;
}
-static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
+static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
show_out0_enable, set_out0_enable);
static struct attribute *pcf8591_attributes[] = {
@@ -196,7 +196,7 @@ static int pcf8591_probe(struct i2c_client *client,
err = -ENOMEM;
goto exit;
}
-
+
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
@@ -249,8 +249,8 @@ static void pcf8591_init_client(struct i2c_client *client)
data->aout = PCF8591_INIT_AOUT;
i2c_smbus_write_byte_data(client, data->control, data->aout);
-
- /* The first byte transmitted contains the conversion code of the
+
+ /* The first byte transmitted contains the conversion code of the
previous read cycle. FLUSH IT! */
i2c_smbus_read_byte(client);
}
@@ -267,8 +267,8 @@ static int pcf8591_read_channel(struct device *dev, int channel)
data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
| channel;
i2c_smbus_write_byte(client, data->control);
-
- /* The first byte transmitted contains the conversion code of
+
+ /* The first byte transmitted contains the conversion code of
the previous read cycle. FLUSH IT! */
i2c_smbus_read_byte(client);
}
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index feae743ba99..e64b42058b2 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -36,6 +36,7 @@
w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3
0x8860 0xa1
w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
+ w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
*/
#include <linux/module.h>
@@ -52,12 +53,13 @@
#include <asm/io.h>
#include "lm75.h"
-enum kinds { w83627ehf, w83627dhg };
+enum kinds { w83627ehf, w83627dhg, w83667hg };
/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
static const char * w83627ehf_device_names[] = {
"w83627ehf",
"w83627dhg",
+ "w83667hg",
};
static unsigned short force_id;
@@ -71,6 +73,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
*/
#define W83627EHF_LD_HWM 0x0b
+#define W83667HG_LD_VID 0x0d
#define SIO_REG_LDSEL 0x07 /* Logical device select */
#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
@@ -83,6 +86,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
#define SIO_W83627EHF_ID 0x8850
#define SIO_W83627EHG_ID 0x8860
#define SIO_W83627DHG_ID 0xa020
+#define SIO_W83667HG_ID 0xa510
#define SIO_ID_MASK 0xFFF0
static inline void
@@ -289,6 +293,7 @@ struct w83627ehf_data {
u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
u8 pwm_enable[4]; /* 1->manual
2->thermal cruise (also called SmartFan I) */
+ u8 pwm_num; /* number of pwm */
u8 pwm[4];
u8 target_temp[4];
u8 tolerance[4];
@@ -298,6 +303,9 @@ struct w83627ehf_data {
u8 vid;
u8 vrm;
+
+ u8 temp3_disable;
+ u8 in6_skip;
};
struct w83627ehf_sio_data {
@@ -866,25 +874,37 @@ show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
}
-static struct sensor_device_attribute sda_temp[] = {
+static struct sensor_device_attribute sda_temp_input[] = {
SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0),
SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0),
SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1),
+};
+
+static struct sensor_device_attribute sda_temp_max[] = {
SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max,
store_temp1_max, 0),
SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 0),
SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 1),
+};
+
+static struct sensor_device_attribute sda_temp_max_hyst[] = {
SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst,
store_temp1_max_hyst, 0),
SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 0),
SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 1),
+};
+
+static struct sensor_device_attribute sda_temp_alarm[] = {
SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
+};
+
+static struct sensor_device_attribute sda_temp_type[] = {
SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
@@ -1181,6 +1201,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
for (i = 0; i < data->in_num; i++) {
+ if ((i == 6) && data->in6_skip)
+ continue;
device_remove_file(dev, &sda_in_input[i].dev_attr);
device_remove_file(dev, &sda_in_alarm[i].dev_attr);
device_remove_file(dev, &sda_in_min[i].dev_attr);
@@ -1192,15 +1214,22 @@ static void w83627ehf_device_remove_files(struct device *dev)
device_remove_file(dev, &sda_fan_div[i].dev_attr);
device_remove_file(dev, &sda_fan_min[i].dev_attr);
}
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < data->pwm_num; i++) {
device_remove_file(dev, &sda_pwm[i].dev_attr);
device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
device_remove_file(dev, &sda_target_temp[i].dev_attr);
device_remove_file(dev, &sda_tolerance[i].dev_attr);
}
- for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
- device_remove_file(dev, &sda_temp[i].dev_attr);
+ for (i = 0; i < 3; i++) {
+ if ((i == 2) && data->temp3_disable)
+ continue;
+ device_remove_file(dev, &sda_temp_input[i].dev_attr);
+ device_remove_file(dev, &sda_temp_max[i].dev_attr);
+ device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
+ device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
+ device_remove_file(dev, &sda_temp_type[i].dev_attr);
+ }
device_remove_file(dev, &dev_attr_name);
device_remove_file(dev, &dev_attr_cpu0_vid);
@@ -1222,6 +1251,8 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data)
for (i = 0; i < 2; i++) {
tmp = w83627ehf_read_value(data,
W83627EHF_REG_TEMP_CONFIG[i]);
+ if ((i == 1) && data->temp3_disable)
+ continue;
if (tmp & 0x01)
w83627ehf_write_value(data,
W83627EHF_REG_TEMP_CONFIG[i],
@@ -1272,8 +1303,17 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
data->name = w83627ehf_device_names[sio_data->kind];
platform_set_drvdata(pdev, data);
- /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */
- data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10;
+ /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
+ data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
+ /* 667HG has 3 pwms */
+ data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4;
+
+ /* Check temp3 configuration bit for 667HG */
+ if (sio_data->kind == w83667hg) {
+ data->temp3_disable = w83627ehf_read_value(data,
+ W83627EHF_REG_TEMP_CONFIG[1]) & 0x01;
+ data->in6_skip = !data->temp3_disable;
+ }
/* Initialize the chip */
w83627ehf_init_device(data);
@@ -1281,44 +1321,64 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
data->vrm = vid_which_vrm();
superio_enter(sio_data->sioreg);
/* Read VID value */
- superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
- if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
- /* Set VID input sensibility if needed. In theory the BIOS
- should have set it, but in practice it's not always the
- case. We only do it for the W83627EHF/EHG because the
- W83627DHG is more complex in this respect. */
- if (sio_data->kind == w83627ehf) {
- en_vrm10 = superio_inb(sio_data->sioreg,
- SIO_REG_EN_VRM10);
- if ((en_vrm10 & 0x08) && data->vrm == 90) {
- dev_warn(dev, "Setting VID input voltage to "
- "TTL\n");
- superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
- en_vrm10 & ~0x08);
- } else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
- dev_warn(dev, "Setting VID input voltage to "
- "VRM10\n");
- superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
- en_vrm10 | 0x08);
- }
- }
-
- data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA);
- if (sio_data->kind == w83627ehf) /* 6 VID pins only */
- data->vid &= 0x3f;
-
+ if (sio_data->kind == w83667hg) {
+ /* W83667HG has different pins for VID input and output, so
+ we can get the VID input values directly at logical device D
+ 0xe3. */
+ superio_select(sio_data->sioreg, W83667HG_LD_VID);
+ data->vid = superio_inb(sio_data->sioreg, 0xe3);
err = device_create_file(dev, &dev_attr_cpu0_vid);
if (err)
goto exit_release;
} else {
- dev_info(dev, "VID pins in output mode, CPU VID not "
- "available\n");
+ superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
+ if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
+ /* Set VID input sensibility if needed. In theory the
+ BIOS should have set it, but in practice it's not
+ always the case. We only do it for the W83627EHF/EHG
+ because the W83627DHG is more complex in this
+ respect. */
+ if (sio_data->kind == w83627ehf) {
+ en_vrm10 = superio_inb(sio_data->sioreg,
+ SIO_REG_EN_VRM10);
+ if ((en_vrm10 & 0x08) && data->vrm == 90) {
+ dev_warn(dev, "Setting VID input "
+ "voltage to TTL\n");
+ superio_outb(sio_data->sioreg,
+ SIO_REG_EN_VRM10,
+ en_vrm10 & ~0x08);
+ } else if (!(en_vrm10 & 0x08)
+ && data->vrm == 100) {
+ dev_warn(dev, "Setting VID input "
+ "voltage to VRM10\n");
+ superio_outb(sio_data->sioreg,
+ SIO_REG_EN_VRM10,
+ en_vrm10 | 0x08);
+ }
+ }
+
+ data->vid = superio_inb(sio_data->sioreg,
+ SIO_REG_VID_DATA);
+ if (sio_data->kind == w83627ehf) /* 6 VID pins only */
+ data->vid &= 0x3f;
+
+ err = device_create_file(dev, &dev_attr_cpu0_vid);
+ if (err)
+ goto exit_release;
+ } else {
+ dev_info(dev, "VID pins in output mode, CPU VID not "
+ "available\n");
+ }
}
/* fan4 and fan5 share some pins with the GPIO and serial flash */
-
- fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2;
- fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6;
+ if (sio_data->kind == w83667hg) {
+ fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
+ fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
+ } else {
+ fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02);
+ fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06);
+ }
superio_exit(sio_data->sioreg);
/* It looks like fan4 and fan5 pins can be alternatively used
@@ -1329,9 +1389,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
data->has_fan = 0x07; /* fan1, fan2 and fan3 */
i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
- if ((i & (1 << 2)) && (!fan4pin))
+ if ((i & (1 << 2)) && fan4pin)
data->has_fan |= (1 << 3);
- if (!(i & (1 << 1)) && (!fan5pin))
+ if (!(i & (1 << 1)) && fan5pin)
data->has_fan |= (1 << 4);
/* Read fan clock dividers immediately */
@@ -1344,14 +1404,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
goto exit_remove;
/* if fan4 is enabled create the sf3 files for it */
- if (data->has_fan & (1 << 3))
+ if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
if ((err = device_create_file(dev,
&sda_sf3_arrays_fan4[i].dev_attr)))
goto exit_remove;
}
- for (i = 0; i < data->in_num; i++)
+ for (i = 0; i < data->in_num; i++) {
+ if ((i == 6) && data->in6_skip)
+ continue;
if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
|| (err = device_create_file(dev,
&sda_in_alarm[i].dev_attr))
@@ -1360,6 +1422,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&sda_in_max[i].dev_attr)))
goto exit_remove;
+ }
for (i = 0; i < 5; i++) {
if (data->has_fan & (1 << i)) {
@@ -1372,7 +1435,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
|| (err = device_create_file(dev,
&sda_fan_min[i].dev_attr)))
goto exit_remove;
- if (i < 4 && /* w83627ehf only has 4 pwm */
+ if (i < data->pwm_num &&
((err = device_create_file(dev,
&sda_pwm[i].dev_attr))
|| (err = device_create_file(dev,
@@ -1387,9 +1450,21 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
}
}
- for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
- if ((err = device_create_file(dev, &sda_temp[i].dev_attr)))
+ for (i = 0; i < 3; i++) {
+ if ((i == 2) && data->temp3_disable)
+ continue;
+ if ((err = device_create_file(dev,
+ &sda_temp_input[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_max[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_max_hyst[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_alarm[i].dev_attr))
+ || (err = device_create_file(dev,
+ &sda_temp_type[i].dev_attr)))
goto exit_remove;
+ }
err = device_create_file(dev, &dev_attr_name);
if (err)
@@ -1442,6 +1517,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
+ static const char __initdata sio_name_W83667HG[] = "W83667HG";
u16 val;
const char *sio_name;
@@ -1466,6 +1542,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
sio_data->kind = w83627dhg;
sio_name = sio_name_W83627DHG;
break;
+ case SIO_W83667HG_ID:
+ sio_data->kind = w83667hg;
+ sio_name = sio_name_W83667HG;
+ break;
default:
if (val != 0xffff)
pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",
diff --git a/drivers/i2c/algos/Kconfig b/drivers/i2c/algos/Kconfig
index b788579b822..7b2ce4a0852 100644
--- a/drivers/i2c/algos/Kconfig
+++ b/drivers/i2c/algos/Kconfig
@@ -14,8 +14,4 @@ config I2C_ALGOPCF
config I2C_ALGOPCA
tristate "I2C PCA 9564 interfaces"
-config I2C_ALGO_SGI
- tristate
- depends on SGI_IP22 || SGI_IP32 || X86_VISWS
-
endmenu
diff --git a/drivers/i2c/algos/Makefile b/drivers/i2c/algos/Makefile
index cac1051bd4f..18b3e962ec0 100644
--- a/drivers/i2c/algos/Makefile
+++ b/drivers/i2c/algos/Makefile
@@ -5,7 +5,6 @@
obj-$(CONFIG_I2C_ALGOBIT) += i2c-algo-bit.o
obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o
obj-$(CONFIG_I2C_ALGOPCA) += i2c-algo-pca.o
-obj-$(CONFIG_I2C_ALGO_SGI) += i2c-algo-sgi.o
ifeq ($(CONFIG_I2C_DEBUG_ALGO),y)
EXTRA_CFLAGS += -DDEBUG
diff --git a/drivers/i2c/algos/i2c-algo-sgi.c b/drivers/i2c/algos/i2c-algo-sgi.c
deleted file mode 100644
index 6eaf145e1ad..00000000000
--- a/drivers/i2c/algos/i2c-algo-sgi.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * i2c-algo-sgi.c: i2c driver algorithm used by the VINO (SGI Indy) and
- * MACE (SGI O2) chips.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License version 2 as published by the Free Software Foundation.
- *
- * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-
-#include <linux/i2c.h>
-#include <linux/i2c-algo-sgi.h>
-
-
-#define SGI_I2C_FORCE_IDLE (0 << 0)
-#define SGI_I2C_NOT_IDLE (1 << 0)
-#define SGI_I2C_WRITE (0 << 1)
-#define SGI_I2C_READ (1 << 1)
-#define SGI_I2C_RELEASE_BUS (0 << 2)
-#define SGI_I2C_HOLD_BUS (1 << 2)
-#define SGI_I2C_XFER_DONE (0 << 4)
-#define SGI_I2C_XFER_BUSY (1 << 4)
-#define SGI_I2C_ACK (0 << 5)
-#define SGI_I2C_NACK (1 << 5)
-#define SGI_I2C_BUS_OK (0 << 7)
-#define SGI_I2C_BUS_ERR (1 << 7)
-
-#define get_control() adap->getctrl(adap->data)
-#define set_control(val) adap->setctrl(adap->data, val)
-#define read_data() adap->rdata(adap->data)
-#define write_data(val) adap->wdata(adap->data, val)
-
-
-static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((get_control() & SGI_I2C_XFER_BUSY) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int wait_ack(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- if (wait_xfer_done(adap))
- return -ETIMEDOUT;
- for (i = 0; i < adap->ack_timeout; i++) {
- if ((get_control() & SGI_I2C_NACK) == 0)
- return 0;
- udelay(1);
- }
-
- return -ETIMEDOUT;
-}
-
-static int force_idle(struct i2c_algo_sgi_data *adap)
-{
- int i;
-
- set_control(SGI_I2C_FORCE_IDLE);
- for (i = 0; i < adap->xfer_timeout; i++) {
- if ((get_control() & SGI_I2C_NOT_IDLE) == 0)
- goto out;
- udelay(1);
- }
- return -ETIMEDOUT;
-out:
- if (get_control() & SGI_I2C_BUS_ERR)
- return -EIO;
- return 0;
-}
-
-static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
- int rd)
-{
- if (rd)
- set_control(SGI_I2C_NOT_IDLE);
- /* Check if bus is idle, eventually force it to do so */
- if (get_control() & SGI_I2C_NOT_IDLE)
- if (force_idle(adap))
- return -EIO;
- /* Write out the i2c chip address and specify operation */
- set_control(SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
- if (rd)
- addr |= 1;
- write_data(addr);
- if (wait_ack(adap))
- return -EIO;
- return 0;
-}
-
-static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- set_control(SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
- for (i = 0; i < len; i++) {
- if (wait_xfer_done(adap))
- return -EIO;
- buf[i] = read_data();
- }
- set_control(SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
-
- return 0;
-
-}
-
-static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
- unsigned int len)
-{
- int i;
-
- /* We are already in write state */
- for (i = 0; i < len; i++) {
- write_data(buf[i]);
- if (wait_ack(adap))
- return -EIO;
- }
- return 0;
-}
-
-static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
- int num)
-{
- struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
- struct i2c_msg *p;
- int i, err = 0;
-
- for (i = 0; !err && i < num; i++) {
- p = &msgs[i];
- err = do_address(adap, p->addr, p->flags & I2C_M_RD);
- if (err || !p->len)
- continue;
- if (p->flags & I2C_M_RD)
- err = i2c_read(adap, p->buf, p->len);
- else
- err = i2c_write(adap, p->buf, p->len);
- }
-
- return (err < 0) ? err : i;
-}
-
-static u32 sgi_func(struct i2c_adapter *adap)
-{
- return I2C_FUNC_SMBUS_EMUL;
-}
-
-static const struct i2c_algorithm sgi_algo = {
- .master_xfer = sgi_xfer,
- .functionality = sgi_func,
-};
-
-/*
- * registering functions to load algorithms at runtime
- */
-int i2c_sgi_add_bus(struct i2c_adapter *adap)
-{
- adap->algo = &sgi_algo;
-
- return i2c_add_adapter(adap);
-}
-EXPORT_SYMBOL(i2c_sgi_add_bus);
-
-MODULE_AUTHOR("Ladislav Michl <ladis@linux-mips.org>");
-MODULE_DESCRIPTION("I2C-Bus SGI algorithm");
-MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 230238df56c..10411848fd7 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -65,6 +65,7 @@
#include <linux/i2c.h>
#include <linux/acpi.h>
#include <linux/io.h>
+#include <linux/dmi.h>
/* I801 SMBus address offsets */
#define SMBHSTSTS (0 + i801_smba)
@@ -616,10 +617,81 @@ static void __init input_apanel_init(void)
static void __init input_apanel_init(void) {}
#endif
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+struct dmi_onboard_device_info {
+ const char *name;
+ u8 type;
+ unsigned short i2c_addr;
+ const char *i2c_type;
+};
+
+static struct dmi_onboard_device_info __devinitdata dmi_devices[] = {
+ { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
+ { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
+ { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
+};
+
+static void __devinit dmi_check_onboard_device(u8 type, const char *name,
+ struct i2c_adapter *adap)
+{
+ int i;
+ struct i2c_board_info info;
+
+ for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
+ /* & ~0x80, ignore enabled/disabled bit */
+ if ((type & ~0x80) != dmi_devices[i].type)
+ continue;
+ if (strcmp(name, dmi_devices[i].name))
+ continue;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ info.addr = dmi_devices[i].i2c_addr;
+ strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
+ i2c_new_device(adap, &info);
+ break;
+ }
+}
+
+/* We use our own function to check for onboard devices instead of
+ dmi_find_device() as some buggy BIOS's have the devices we are interested
+ in marked as disabled */
+static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm,
+ void *adap)
+{
+ int i, count;
+
+ if (dm->type != 10)
+ return;
+
+ count = (dm->length - sizeof(struct dmi_header)) / 2;
+ for (i = 0; i < count; i++) {
+ const u8 *d = (char *)(dm + 1) + (i * 2);
+ const char *name = ((char *) dm) + dm->length;
+ u8 type = d[0];
+ u8 s = d[1];
+
+ if (!s)
+ continue;
+ s--;
+ while (s > 0 && name[0]) {
+ name += strlen(name) + 1;
+ s--;
+ }
+ if (name[0] == 0) /* Bogus string reference */
+ continue;
+
+ dmi_check_onboard_device(type, name, adap);
+ }
+}
+#endif
+
static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
unsigned char temp;
int err;
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+ const char *vendor;
+#endif
I801_dev = dev;
i801_features = 0;
@@ -712,6 +784,11 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
i2c_new_device(&i801_adapter, &info);
}
#endif
+#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
+ vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
+ if (vendor && !strcmp(vendor, "FUJITSU SIEMENS"))
+ dmi_walk(dmi_check_onboard_devices, &i801_adapter);
+#endif
return 0;
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 2b847d87594..26bf3701058 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -70,7 +70,7 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
/* Read again to allow register to stabilise */
i2c->interrupt = readb(i2c->base + MPC_I2C_SR);
writeb(0, i2c->base + MPC_I2C_SR);
- wake_up_interruptible(&i2c->queue);
+ wake_up(&i2c->queue);
}
return IRQ_HANDLED;
}
@@ -115,13 +115,10 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
writeb(0, i2c->base + MPC_I2C_SR);
} else {
/* Interrupt mode */
- result = wait_event_interruptible_timeout(i2c->queue,
+ result = wait_event_timeout(i2c->queue,
(i2c->interrupt & CSR_MIF), timeout);
- if (unlikely(result < 0)) {
- pr_debug("I2C: wait interrupted\n");
- writeccr(i2c, 0);
- } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {
+ if (unlikely(!(i2c->interrupt & CSR_MIF))) {
pr_debug("I2C: wait timeout\n");
writeccr(i2c, 0);
result = -ETIMEDOUT;
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index c80312c1f38..8f8c81eb0ae 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -64,19 +64,6 @@ config SENSORS_PCA9539
This driver is deprecated and will be dropped soon. Use
drivers/gpio/pca953x.c instead.
-config SENSORS_PCF8591
- tristate "Philips PCF8591"
- depends on EXPERIMENTAL
- default n
- help
- If you say yes here you get support for Philips PCF8591 chips.
-
- This driver can also be built as a module. If so, the module
- will be called pcf8591.
-
- These devices are hard to detect and rarely found on mainstream
- hardware. If unsure, say N.
-
config SENSORS_MAX6875
tristate "Maxim MAX6875 Power supply supervisor"
depends on EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index d142f238a2d..55a37603718 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
obj-$(CONFIG_PCF8575) += pcf8575.o
-obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index 640c9920724..cf06494bb74 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -222,7 +222,8 @@ comment "IDE chipset support/bugfixes"
config IDE_GENERIC
tristate "generic/default IDE chipset support"
- depends on ALPHA || X86 || IA64 || M32R || MIPS
+ depends on ALPHA || X86 || IA64 || M32R || MIPS || ARCH_RPC || ARCH_SHARK
+ default ARM && (ARCH_RPC || ARCH_SHARK)
help
This is the generic IDE driver. This driver attaches to the
fixed legacy ports (e.g. on PCs 0x1f0/0x170, 0x1e8/0x168 and
@@ -680,7 +681,7 @@ endif
# TODO: BLK_DEV_IDEDMA_PCI -> BLK_DEV_IDEDMA_SFF
config BLK_DEV_IDE_PMAC
tristate "PowerMac on-board IDE support"
- depends on PPC_PMAC && IDE=y
+ depends on PPC_PMAC
select IDE_TIMINGS
select BLK_DEV_IDEDMA_PCI
help
@@ -731,11 +732,6 @@ config BLK_DEV_IDE_AT91
depends on ARM && ARCH_AT91 && !ARCH_AT91RM9200 && !ARCH_AT91X40
select IDE_TIMINGS
-config IDE_ARM
- tristate "ARM IDE support"
- depends on ARM && (ARCH_RPC || ARCH_SHARK)
- default y
-
config BLK_DEV_IDE_ICSIDE
tristate "ICS IDE interface support"
depends on ARM && ARCH_ACORN
@@ -774,27 +770,20 @@ config BLK_DEV_GAYLE
This includes on-board IDE interfaces on some Amiga models (A600,
A1200, A4000, and A4000T), and IDE interfaces on the Zorro expansion
bus (M-Tech E-Matrix 530 expansion card).
- Say Y if you have an Amiga with a Gayle IDE interface and want to use
- IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
- it.
- Note that you also have to enable Zorro bus support if you want to
- use Gayle IDE interfaces on the Zorro expansion bus.
-config BLK_DEV_IDEDOUBLER
- bool "Amiga IDE Doubler support (EXPERIMENTAL)"
- depends on BLK_DEV_GAYLE && EXPERIMENTAL
- ---help---
- This feature provides support for the so-called `IDE doublers' (made
+ It also provides support for the so-called `IDE doublers' (made
by various manufacturers, e.g. Eyetech) that can be connected to
the on-board IDE interface of some Amiga models. Using such an IDE
doubler, you can connect up to four instead of two IDE devices to
- the Amiga's on-board IDE interface.
+ the Amiga's on-board IDE interface. The feature is enabled at kernel
+ runtime using the "gayle.doubler" kernel boot parameter.
- Note that the normal Amiga Gayle IDE driver may not work correctly
- if you have an IDE doubler and don't enable this feature!
+ Say Y if you have an Amiga with a Gayle IDE interface and want to use
+ IDE devices (hard disks, CD-ROM drives, etc.) that are connected to
+ it.
- Say Y if you have an IDE doubler. The feature is enabled at kernel
- runtime using the "gayle.doubler" kernel boot parameter.
+ Note that you also have to enable Zorro bus support if you want to
+ use Gayle IDE interfaces on the Zorro expansion bus.
config BLK_DEV_BUDDHA
tristate "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)"
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index 9b4bbe1cdc1..81df925f0e8 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -21,8 +21,6 @@ ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o
obj-$(CONFIG_IDE) += ide-core.o
-obj-$(CONFIG_IDE_ARM) += ide_arm.o
-
obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
diff --git a/drivers/ide/alim15x3.c b/drivers/ide/alim15x3.c
index d3513b6b853..537da1cde16 100644
--- a/drivers/ide/alim15x3.c
+++ b/drivers/ide/alim15x3.c
@@ -189,19 +189,20 @@ static void ali_set_dma_mode(ide_drive_t *drive, const u8 speed)
}
/**
- * ali15x3_dma_setup - begin a DMA phase
+ * ali_dma_check - DMA check
* @drive: target device
+ * @cmd: command
*
* Returns 1 if the DMA cannot be performed, zero on success.
*/
-static int ali15x3_dma_setup(ide_drive_t *drive)
+static int ali_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
if (m5229_revision < 0xC2 && drive->media != ide_disk) {
- if (rq_data_dir(drive->hwif->rq))
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
return 1; /* try PIO instead of DMA */
}
- return ide_dma_setup(drive);
+ return 0;
}
/**
@@ -502,13 +503,13 @@ static const struct ide_port_ops ali_port_ops = {
static const struct ide_dma_ops ali_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ali15x3_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
+ .dma_setup = ide_dma_setup,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_check = ali_dma_check,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c
index 1bb50f46388..8eda552326e 100644
--- a/drivers/ide/at91_ide.c
+++ b/drivers/ide/at91_ide.c
@@ -143,7 +143,7 @@ static void apply_timings(const u8 chipselect, const u8 pio,
set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy);
}
-static void at91_ide_input_data(ide_drive_t *drive, struct request *rq,
+static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
@@ -156,11 +156,11 @@ static void at91_ide_input_data(ide_drive_t *drive, struct request *rq,
len++;
enter_16bit(chipselect, mode);
- __ide_mm_insw((void __iomem *) io_ports->data_addr, buf, len / 2);
+ readsw((void __iomem *)io_ports->data_addr, buf, len / 2);
leave_16bit(chipselect, mode);
}
-static void at91_ide_output_data(ide_drive_t *drive, struct request *rq,
+static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
@@ -171,7 +171,7 @@ static void at91_ide_output_data(ide_drive_t *drive, struct request *rq,
pdbg("cs %u buf %p len %d\n", chipselect, buf, len);
enter_16bit(chipselect, mode);
- __ide_mm_outsw((void __iomem *) io_ports->data_addr, buf, len / 2);
+ writesw((void __iomem *)io_ports->data_addr, buf, len / 2);
leave_16bit(chipselect, mode);
}
@@ -185,91 +185,77 @@ static void ide_mm_outb(u8 value, unsigned long port)
writeb(value, (void __iomem *) port);
}
-static void at91_ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void at91_ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- at91_ide_output_data(drive, NULL, &data, 2);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
ide_mm_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
ide_mm_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
ide_mm_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
ide_mm_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
ide_mm_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
ide_mm_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
ide_mm_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
ide_mm_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
ide_mm_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
ide_mm_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
ide_mm_outb((tf->device & HIHI) | drive->select, io_ports->device_addr);
}
-static void at91_ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void at91_ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- at91_ide_input_data(drive, NULL, &data, 2);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- ide_mm_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ ide_mm_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = ide_mm_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = ide_mm_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = ide_mm_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = ide_mm_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = ide_mm_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = ide_mm_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = ide_mm_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- ide_mm_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = ide_mm_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ ide_mm_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = ide_mm_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = ide_mm_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = ide_mm_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = ide_mm_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = ide_mm_inb(io_ports->lbah_addr);
}
}
@@ -295,8 +281,9 @@ static const struct ide_tp_ops at91_ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
- .set_irq = ide_set_irq,
+ .write_devctl = ide_write_devctl,
+ .dev_select = ide_dev_select,
.tf_load = at91_ide_tf_load,
.tf_read = at91_ide_tf_read,
diff --git a/drivers/ide/au1xxx-ide.c b/drivers/ide/au1xxx-ide.c
index 154ec2cf734..46013644c96 100644
--- a/drivers/ide/au1xxx-ide.c
+++ b/drivers/ide/au1xxx-ide.c
@@ -50,7 +50,7 @@ static _auide_hwif auide_hwif;
#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
-void auide_insw(unsigned long port, void *addr, u32 count)
+static inline void auide_insw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
@@ -68,7 +68,7 @@ void auide_insw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-void auide_outsw(unsigned long port, void *addr, u32 count)
+static inline void auide_outsw(unsigned long port, void *addr, u32 count)
{
_auide_hwif *ahwif = &auide_hwif;
chan_tab_t *ctp;
@@ -86,13 +86,13 @@ void auide_outsw(unsigned long port, void *addr, u32 count)
ctp->cur_ptr = au1xxx_ddma_get_nextptr_virt(dp);
}
-static void au1xxx_input_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
auide_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
}
-static void au1xxx_output_data(ide_drive_t *drive, struct request *rq,
+static void au1xxx_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
auide_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
@@ -209,23 +209,17 @@ static void auide_set_dma_mode(ide_drive_t *drive, const u8 speed)
*/
#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
-static int auide_build_dmatable(ide_drive_t *drive)
+static int auide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
- int i, iswrite, count = 0;
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
_auide_hwif *ahwif = &auide_hwif;
struct scatterlist *sg;
+ int i = cmd->sg_nents, count = 0;
+ int iswrite = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- iswrite = (rq_data_dir(rq) == WRITE);
/* Save for interrupt context */
ahwif->drive = drive;
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
/* fill the descriptors */
sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
@@ -242,7 +236,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
if (++count >= PRD_ENTRIES) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
}
/* Lets enable intr for the last descriptor only */
@@ -278,21 +272,11 @@ static int auide_build_dmatable(ide_drive_t *drive)
if (count)
return 1;
- use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
static int auide_dma_end(ide_drive_t *drive)
{
- ide_hwif_t *hwif = drive->hwif;
-
- if (hwif->sg_nents) {
- ide_destroy_dmatable(drive);
- hwif->sg_nents = 0;
- }
-
return 0;
}
@@ -301,23 +285,11 @@ static void auide_dma_start(ide_drive_t *drive )
}
-static void auide_dma_exec_cmd(ide_drive_t *drive, u8 command)
+static int auide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr,
- (2*WAIT_CMD), NULL);
-}
-
-static int auide_dma_setup(ide_drive_t *drive)
-{
- struct request *rq = drive->hwif->rq;
-
- if (!auide_build_dmatable(drive)) {
- ide_map_sg(drive, rq);
+ if (auide_build_dmatable(drive, cmd) == 0)
return 1;
- }
- drive->waiting_for_dma = 1;
return 0;
}
@@ -342,16 +314,11 @@ static void auide_dma_host_set(ide_drive_t *drive, int on)
static void auide_ddma_tx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
static void auide_ddma_rx_callback(int irq, void *param)
{
- _auide_hwif *ahwif = (_auide_hwif*)param;
- ahwif->drive->waiting_for_dma = 0;
}
-
#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */
static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags)
@@ -369,12 +336,10 @@ static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 de
static const struct ide_dma_ops au1xxx_dma_ops = {
.dma_host_set = auide_dma_host_set,
.dma_setup = auide_dma_setup,
- .dma_exec_cmd = auide_dma_exec_cmd,
.dma_start = auide_dma_start,
.dma_end = auide_dma_end,
.dma_test_irq = auide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static int auide_ddma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
@@ -502,9 +467,9 @@ static const struct ide_tp_ops au1xxx_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
diff --git a/drivers/ide/buddha.c b/drivers/ide/buddha.c
index c5a3c9ef6a5..d028f8864bc 100644
--- a/drivers/ide/buddha.c
+++ b/drivers/ide/buddha.c
@@ -143,6 +143,11 @@ static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
+static const struct ide_port_info buddha_port_info = {
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
+};
+
/*
* Probe for a Buddha or Catweasel IDE interface
*/
@@ -172,10 +177,6 @@ static int __init buddha_init(void)
board = z->resource.start;
-/*
- * FIXME: we now have selectable mmio v/s iomio transports.
- */
-
if(type != BOARD_XSURF) {
if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
continue;
@@ -224,7 +225,7 @@ fail_base2:
hws[i] = &hw[i];
}
- ide_host_add(NULL, hws, NULL);
+ ide_host_add(&buddha_port_info, hws, NULL);
}
return 0;
diff --git a/drivers/ide/cmd64x.c b/drivers/ide/cmd64x.c
index aeee036b150..80b777e4247 100644
--- a/drivers/ide/cmd64x.c
+++ b/drivers/ide/cmd64x.c
@@ -318,7 +318,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
/* get DMA status */
dma_stat = inb(hwif->dma_base + ATA_DMA_STATUS);
/* read DMA command state */
@@ -327,8 +326,6 @@ static int cmd646_1_dma_end(ide_drive_t *drive)
outb(dma_cmd & ~1, hwif->dma_base + ATA_DMA_CMD);
/* clear the INTR & ERROR bits */
outb(dma_stat | 6, hwif->dma_base + ATA_DMA_STATUS);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
return (dma_stat & 7) != 4;
}
@@ -379,36 +376,33 @@ static const struct ide_port_ops cmd64x_port_ops = {
static const struct ide_dma_ops cmd64x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd64x_dma_end,
.dma_test_irq = cmd64x_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd646_rev1_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd646_1_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops cmd648_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = cmd648_dma_end,
.dma_test_irq = cmd648_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/cs5530.c b/drivers/ide/cs5530.c
index 8e8b35a8990..40bf05eddf6 100644
--- a/drivers/ide/cs5530.c
+++ b/drivers/ide/cs5530.c
@@ -92,8 +92,7 @@ static u8 cs5530_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
- if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
- (mateid[ATA_ID_MWDMA_MODES] & 7))
+ if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
diff --git a/drivers/ide/cs5536.c b/drivers/ide/cs5536.c
index 7a62db719a4..353a35bbba6 100644
--- a/drivers/ide/cs5536.c
+++ b/drivers/ide/cs5536.c
@@ -231,12 +231,11 @@ static const struct ide_port_ops cs5536_port_ops = {
static const struct ide_dma_ops cs5536_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = cs5536_dma_start,
.dma_end = cs5536_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
};
static const struct ide_port_info cs5536_info = {
diff --git a/drivers/ide/delkin_cb.c b/drivers/ide/delkin_cb.c
index bacb1194c9c..f153b95619b 100644
--- a/drivers/ide/delkin_cb.c
+++ b/drivers/ide/delkin_cb.c
@@ -66,6 +66,7 @@ static const struct ide_port_info delkin_cb_port_info = {
.port_ops = &delkin_cb_port_ops,
.host_flags = IDE_HFLAG_IO_32BIT | IDE_HFLAG_UNMASK_IRQS |
IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
.init_chipset = delkin_cb_init_chipset,
};
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c
index 689b2e49341..c6b13812298 100644
--- a/drivers/ide/dtc2278.c
+++ b/drivers/ide/dtc2278.c
@@ -100,7 +100,8 @@ static const struct ide_port_info dtc2278_port_info __initdata = {
IDE_HFLAG_IO_32BIT |
/* disallow ->io_32bit changes */
IDE_HFLAG_NO_IO_32BIT |
- IDE_HFLAG_NO_DMA,
+ IDE_HFLAG_NO_DMA |
+ IDE_HFLAG_DTC2278,
.pio_mask = ATA_PIO4,
};
diff --git a/drivers/ide/falconide.c b/drivers/ide/falconide.c
index a638e952d67..afa2af9a362 100644
--- a/drivers/ide/falconide.c
+++ b/drivers/ide/falconide.c
@@ -40,29 +40,48 @@
* which is shared between several drivers.
*/
-int falconide_intr_lock;
-EXPORT_SYMBOL(falconide_intr_lock);
+static int falconide_intr_lock;
-static void falconide_input_data(ide_drive_t *drive, struct request *rq,
+static void falconide_release_lock(void)
+{
+ if (falconide_intr_lock == 0) {
+ printk(KERN_ERR "%s: bug\n", __func__);
+ return;
+ }
+ falconide_intr_lock = 0;
+ stdma_release();
+}
+
+static void falconide_get_lock(irq_handler_t handler, void *data)
+{
+ if (falconide_intr_lock == 0) {
+ if (in_interrupt() > 0)
+ panic("Falcon IDE hasn't ST-DMA lock in interrupt");
+ stdma_lock(handler, data);
+ falconide_intr_lock = 1;
+ }
+}
+
+static void falconide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return insw(data_addr, buf, (len + 1) / 2);
- insw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
-static void falconide_output_data(ide_drive_t *drive, struct request *rq,
+static void falconide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return outsw(data_addr, buf, (len + 1) / 2);
- outsw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
/* Atari has a byte-swapped IDE interface */
@@ -70,9 +89,9 @@ static const struct ide_tp_ops falconide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -81,8 +100,12 @@ static const struct ide_tp_ops falconide_tp_ops = {
};
static const struct ide_port_info falconide_port_info = {
+ .get_lock = falconide_get_lock,
+ .release_lock = falconide_release_lock,
.tp_ops = &falconide_tp_ops,
- .host_flags = IDE_HFLAG_NO_DMA | IDE_HFLAG_SERIALIZE,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
static void __init falconide_setup_ports(hw_regs_t *hw)
@@ -132,9 +155,9 @@ static int __init falconide_init(void)
goto err;
}
- ide_get_lock(NULL, NULL);
+ falconide_get_lock(NULL, NULL);
rc = ide_host_register(host, &falconide_port_info, hws);
- ide_release_lock();
+ falconide_release_lock();
if (rc)
goto err_free;
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index 59bd0be9dcb..c7119516c5a 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -53,11 +53,6 @@
#define GAYLE_NEXT_PORT 0x1000
-#ifndef CONFIG_BLK_DEV_IDEDOUBLER
-#define GAYLE_NUM_HWIFS 1
-#define GAYLE_NUM_PROBE_HWIFS GAYLE_NUM_HWIFS
-#define GAYLE_HAS_CONTROL_REG 1
-#else /* CONFIG_BLK_DEV_IDEDOUBLER */
#define GAYLE_NUM_HWIFS 2
#define GAYLE_NUM_PROBE_HWIFS (ide_doubler ? GAYLE_NUM_HWIFS : \
GAYLE_NUM_HWIFS-1)
@@ -66,8 +61,6 @@
static int ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
-#endif /* CONFIG_BLK_DEV_IDEDOUBLER */
-
/*
* Check and acknowledge the interrupt status
@@ -118,7 +111,9 @@ static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base,
}
static const struct ide_port_info gayle_port_info = {
- .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_SERIALIZE |
+ IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
/*
@@ -149,10 +144,7 @@ static int __init gayle_init(void)
found:
printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n",
a4000 ? 4000 : 1200,
-#ifdef CONFIG_BLK_DEV_IDEDOUBLER
- ide_doubler ? ", IDE doubler" :
-#endif
- "");
+ ide_doubler ? ", IDE doubler" : "");
if (a4000) {
phys_base = GAYLE_BASE_4000;
@@ -163,9 +155,6 @@ found:
irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200);
ack_intr = gayle_ack_intr_a1200;
}
-/*
- * FIXME: we now have selectable modes between mmio v/s iomio
- */
res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1);
res_n = GAYLE_IDEREG_SIZE;
diff --git a/drivers/ide/hpt366.c b/drivers/ide/hpt366.c
index d3b3e824f44..a0eb87f5913 100644
--- a/drivers/ide/hpt366.c
+++ b/drivers/ide/hpt366.c
@@ -835,12 +835,6 @@ static int hpt370_dma_end(ide_drive_t *drive)
return ide_dma_end(drive);
}
-static void hpt370_dma_timeout(ide_drive_t *drive)
-{
- hpt370_irq_timeout(drive);
- ide_dma_timeout(drive);
-}
-
/* returns 1 if DMA IRQ issued, 0 otherwise */
static int hpt374_dma_test_irq(ide_drive_t *drive)
{
@@ -1418,36 +1412,34 @@ static const struct ide_port_ops hpt3xx_port_ops = {
static const struct ide_dma_ops hpt37x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = hpt374_dma_end,
.dma_test_irq = hpt374_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt370_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = hpt370_dma_start,
.dma_end = hpt370_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = hpt370_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = hpt370_irq_timeout,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops hpt36x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = hpt366_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index c7e5c2246b7..2fb0f296500 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -103,7 +103,7 @@
/*
* This routine is invoked from ide.c to prepare for access to a given drive.
*/
-static void ht6560b_selectproc (ide_drive_t *drive)
+static void ht6560b_dev_select(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
@@ -143,6 +143,8 @@ static void ht6560b_selectproc (ide_drive_t *drive)
#endif
}
local_irq_restore(flags);
+
+ outb(drive->select | ATA_DEVICE_OBS, hwif->io_ports.device_addr);
}
/*
@@ -305,15 +307,29 @@ static int probe_ht6560b;
module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
+static const struct ide_tp_ops ht6560b_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = ht6560b_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
+
static const struct ide_port_ops ht6560b_port_ops = {
.init_dev = ht6560b_init_dev,
.set_pio_mode = ht6560b_set_pio_mode,
- .selectproc = ht6560b_selectproc,
};
static const struct ide_port_info ht6560b_port_info __initdata = {
.name = DRV_NAME,
.chipset = ide_ht6560b,
+ .tp_ops = &ht6560b_tp_ops,
.port_ops = &ht6560b_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | /* is this needed? */
IDE_HFLAG_NO_DMA |
diff --git a/drivers/ide/icside.c b/drivers/ide/icside.c
index 415d7e24f2b..4e16ce68b06 100644
--- a/drivers/ide/icside.c
+++ b/drivers/ide/icside.c
@@ -287,13 +287,8 @@ static int icside_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
- drive->waiting_for_dma = 0;
-
disable_dma(ec->dma);
- /* Teardown mappings after DMA has completed. */
- ide_destroy_dmatable(drive);
-
return get_dma_residue(ec->dma) != 0;
}
@@ -307,15 +302,14 @@ static void icside_dma_start(ide_drive_t *drive)
enable_dma(ec->dma);
}
-static int icside_dma_setup(ide_drive_t *drive)
+static int icside_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct expansion_card *ec = ECARD_DEV(hwif->dev);
struct icside_state *state = ecard_get_drvdata(ec);
- struct request *rq = hwif->rq;
unsigned int dma_mode;
- if (rq_data_dir(rq))
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
dma_mode = DMA_MODE_WRITE;
else
dma_mode = DMA_MODE_READ;
@@ -325,8 +319,6 @@ static int icside_dma_setup(ide_drive_t *drive)
*/
BUG_ON(dma_channel_active(ec->dma));
- hwif->sg_nents = ide_build_sglist(drive, rq);
-
/*
* Ensure that we have the right interrupt routed.
*/
@@ -346,20 +338,12 @@ static int icside_dma_setup(ide_drive_t *drive)
* Tell the DMA engine about the SG table and
* data direction.
*/
- set_dma_sg(ec->dma, hwif->sg_table, hwif->sg_nents);
+ set_dma_sg(ec->dma, hwif->sg_table, cmd->sg_nents);
set_dma_mode(ec->dma, dma_mode);
- drive->waiting_for_dma = 1;
-
return 0;
}
-static void icside_dma_exec_cmd(ide_drive_t *drive, u8 cmd)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD, NULL);
-}
-
static int icside_dma_test_irq(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
@@ -383,11 +367,9 @@ static int icside_dma_init(ide_hwif_t *hwif, const struct ide_port_info *d)
static const struct ide_dma_ops icside_v6_dma_ops = {
.dma_host_set = icside_dma_host_set,
.dma_setup = icside_dma_setup,
- .dma_exec_cmd = icside_dma_exec_cmd,
.dma_start = icside_dma_start,
.dma_end = icside_dma_end,
.dma_test_irq = icside_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
};
#else
@@ -419,6 +401,10 @@ static void icside_setup_ports(hw_regs_t *hw, void __iomem *base,
hw->chipset = ide_acorn;
}
+static const struct ide_port_info icside_v5_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static int __devinit
icside_register_v5(struct icside_state *state, struct expansion_card *ec)
{
@@ -445,7 +431,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
icside_setup_ports(&hw, base, &icside_cardinfo_v5, ec);
- host = ide_host_alloc(NULL, hws);
+ host = ide_host_alloc(&icside_v5_port_info, hws);
if (host == NULL)
return -ENODEV;
@@ -453,7 +439,7 @@ icside_register_v5(struct icside_state *state, struct expansion_card *ec)
ecard_set_drvdata(ec, state);
- ret = ide_host_register(host, NULL, hws);
+ ret = ide_host_register(host, &icside_v5_port_info, hws);
if (ret)
goto err_free;
diff --git a/drivers/ide/ide-4drives.c b/drivers/ide/ide-4drives.c
index 9e85b1ec960..78aca75a2c4 100644
--- a/drivers/ide/ide-4drives.c
+++ b/drivers/ide/ide-4drives.c
@@ -23,7 +23,8 @@ static const struct ide_port_ops ide_4drives_port_ops = {
static const struct ide_port_info ide_4drives_port_info = {
.port_ops = &ide_4drives_port_ops,
- .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA |
+ IDE_HFLAG_4DRIVES,
};
static int __init ide_4drives_init(void)
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index 5b704f1ea90..12f436951bf 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -304,7 +304,7 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
/* send all taskfile registers (0x1f1-0x1f7) *in*that*order* */
for (ix = 0; ix < gtf_count; ix++) {
u8 *gtf = (u8 *)(gtf_address + ix * REGS_PER_GTF);
- ide_task_t task;
+ struct ide_cmd cmd;
DEBPRINT("(0x1f1-1f7): "
"hex: %02x %02x %02x %02x %02x %02x %02x\n",
@@ -317,11 +317,11 @@ static int do_drive_set_taskfiles(ide_drive_t *drive,
}
/* convert GTF to taskfile */
- memset(&task, 0, sizeof(ide_task_t));
- memcpy(&task.tf_array[7], gtf, REGS_PER_GTF);
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&cmd.tf_array[7], gtf, REGS_PER_GTF);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- err = ide_no_data_taskfile(drive, &task);
+ err = ide_no_data_taskfile(drive, &cmd);
if (err) {
printk(KERN_ERR "%s: ide_no_data_taskfile failed: %u\n",
__func__, err);
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index 6adc5b4a440..3e43b889dd6 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -6,6 +6,8 @@
#include <linux/cdrom.h>
#include <linux/delay.h>
#include <linux/ide.h>
+#include <linux/scatterlist.h>
+
#include <scsi/scsi.h>
#ifdef DEBUG
@@ -69,56 +71,6 @@ int ide_check_atapi_device(ide_drive_t *drive, const char *s)
}
EXPORT_SYMBOL_GPL(ide_check_atapi_device);
-/* PIO data transfer routine using the scatter gather table. */
-int ide_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
- unsigned int bcount, int write)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_tp_ops *tp_ops = hwif->tp_ops;
- xfer_func_t *xf = write ? tp_ops->output_data : tp_ops->input_data;
- struct scatterlist *sg = pc->sg;
- char *buf;
- int count, done = 0;
-
- while (bcount) {
- count = min(sg->length - pc->b_count, bcount);
-
- if (PageHighMem(sg_page(sg))) {
- unsigned long flags;
-
- local_irq_save(flags);
- buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
- xf(drive, NULL, buf + pc->b_count, count);
- kunmap_atomic(buf - sg->offset, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = sg_virt(sg);
- xf(drive, NULL, buf + pc->b_count, count);
- }
-
- bcount -= count;
- pc->b_count += count;
- done += count;
-
- if (pc->b_count == sg->length) {
- if (!--pc->sg_cnt)
- break;
- pc->sg = sg = sg_next(sg);
- pc->b_count = 0;
- }
- }
-
- if (bcount) {
- printk(KERN_ERR "%s: %d leftover bytes, %s\n", drive->name,
- bcount, write ? "padding with zeros"
- : "discarding data");
- ide_pad_transfer(drive, write, bcount);
- }
-
- return done;
-}
-EXPORT_SYMBOL_GPL(ide_io_buffers);
-
void ide_init_pc(struct ide_atapi_pc *pc)
{
memset(pc, 0, sizeof(*pc));
@@ -302,16 +254,16 @@ EXPORT_SYMBOL_GPL(ide_cd_get_xferlen);
void ide_read_bcount_and_ireason(ide_drive_t *drive, u16 *bcount, u8 *ireason)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
- IDE_TFLAG_IN_NSECT;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_LBAH | IDE_TFLAG_IN_LBAM |
+ IDE_TFLAG_IN_NSECT;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- *bcount = (task.tf.lbah << 8) | task.tf.lbam;
- *ireason = task.tf.nsect & 3;
+ *bcount = (cmd.tf.lbah << 8) | cmd.tf.lbam;
+ *ireason = cmd.tf.nsect & 3;
}
EXPORT_SYMBOL_GPL(ide_read_bcount_and_ireason);
@@ -324,29 +276,31 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
{
struct ide_atapi_pc *pc = drive->pc;
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
xfer_func_t *xferfunc;
- unsigned int timeout, temp;
+ unsigned int timeout, done;
u16 bcount;
u8 stat, ireason, dsc = 0;
+ u8 write = !!(pc->flags & PC_FLAG_WRITING);
debug_log("Enter %s - interrupt handler\n", __func__);
timeout = (drive->media == ide_floppy) ? WAIT_FLOPPY_CMD
: WAIT_TAPE_CMD;
- if (pc->flags & PC_FLAG_TIMEDOUT) {
- drive->pc_callback(drive, 0);
- return ide_stopped;
- }
-
/* Clear the interrupt */
stat = tp_ops->read_status(hwif);
if (pc->flags & PC_FLAG_DMA_IN_PROGRESS) {
- if (hwif->dma_ops->dma_end(drive) ||
- (drive->media == ide_tape && (stat & ATA_ERR))) {
+ int rc;
+
+ drive->waiting_for_dma = 0;
+ rc = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+
+ if (rc || (drive->media == ide_tape && (stat & ATA_ERR))) {
if (drive->media == ide_floppy)
printk(KERN_ERR "%s: DMA %s error\n",
drive->name, rq_data_dir(pc->rq)
@@ -362,6 +316,9 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
/* No more interrupts */
if ((stat & ATA_DRQ) == 0) {
+ int uptodate, error;
+ unsigned int done;
+
debug_log("Packet command completed, %d bytes transferred\n",
pc->xferred);
@@ -400,8 +357,31 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
dsc = 1;
/* Command finished - Call the callback function */
- drive->pc_callback(drive, dsc);
+ uptodate = drive->pc_callback(drive, dsc);
+
+ if (uptodate == 0)
+ drive->failed_pc = NULL;
+
+ if (blk_special_request(rq)) {
+ rq->errors = 0;
+ done = blk_rq_bytes(rq);
+ error = 0;
+ } else {
+
+ if (blk_fs_request(rq) == 0 && uptodate <= 0) {
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ }
+
+ if (drive->media == ide_tape)
+ done = ide_rq_bytes(rq); /* FIXME */
+ else
+ done = blk_rq_bytes(rq);
+ error = uptodate ? 0 : -EIO;
+ }
+
+ ide_complete_rq(drive, error, done);
return ide_stopped;
}
@@ -421,8 +401,7 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
- if (((ireason & ATAPI_IO) == ATAPI_IO) ==
- !!(pc->flags & PC_FLAG_WRITING)) {
+ if (((ireason & ATAPI_IO) == ATAPI_IO) == write) {
/* Hopefully, we will never get here */
printk(KERN_ERR "%s: We wanted to %s, but the device wants us "
"to %s!\n", drive->name,
@@ -431,78 +410,57 @@ static ide_startstop_t ide_pc_intr(ide_drive_t *drive)
return ide_do_reset(drive);
}
- if (!(pc->flags & PC_FLAG_WRITING)) {
- /* Reading - Check that we have enough space */
- temp = pc->xferred + bcount;
- if (temp > pc->req_xfer) {
- if (temp > pc->buf_size) {
- printk(KERN_ERR "%s: The device wants to send "
- "us more data than expected - "
- "discarding data\n",
- drive->name);
-
- ide_pad_transfer(drive, 0, bcount);
- goto next_irq;
- }
- debug_log("The device wants to send us more data than "
- "expected - allowing transfer\n");
- }
- xferfunc = tp_ops->input_data;
- } else
- xferfunc = tp_ops->output_data;
+ xferfunc = write ? tp_ops->output_data : tp_ops->input_data;
- if ((drive->media == ide_floppy && !pc->buf) ||
- (drive->media == ide_tape && pc->bh)) {
- int done = drive->pc_io_buffers(drive, pc, bcount,
- !!(pc->flags & PC_FLAG_WRITING));
-
- /* FIXME: don't do partial completions */
- if (drive->media == ide_floppy)
- ide_end_request(drive, 1, done >> 9);
- } else
- xferfunc(drive, NULL, pc->cur_pos, bcount);
+ if (drive->media == ide_floppy && pc->buf == NULL) {
+ done = min_t(unsigned int, bcount, cmd->nleft);
+ ide_pio_bytes(drive, cmd, write, done);
+ } else if (drive->media == ide_tape && pc->bh) {
+ done = drive->pc_io_buffers(drive, pc, bcount, write);
+ } else {
+ done = min_t(unsigned int, bcount, pc->req_xfer - pc->xferred);
+ xferfunc(drive, NULL, pc->cur_pos, done);
+ }
/* Update the current position */
- pc->xferred += bcount;
- pc->cur_pos += bcount;
+ pc->xferred += done;
+ pc->cur_pos += done;
+
+ bcount -= done;
+
+ if (bcount)
+ ide_pad_transfer(drive, write, bcount);
+
+ debug_log("[cmd %x] transferred %d bytes, padded %d bytes\n",
+ rq->cmd[0], done, bcount);
- debug_log("[cmd %x] transferred %d bytes on that intr.\n",
- rq->cmd[0], bcount);
-next_irq:
/* And set the interrupt handler again */
- ide_set_handler(drive, ide_pc_intr, timeout, NULL);
+ ide_set_handler(drive, ide_pc_intr, timeout);
return ide_started;
}
-static void ide_pktcmd_tf_load(ide_drive_t *drive, u32 tf_flags, u16 bcount)
+static void ide_init_packet_cmd(struct ide_cmd *cmd, u32 tf_flags,
+ u16 bcount, u8 dma)
{
- ide_hwif_t *hwif = drive->hwif;
- ide_task_t task;
- u8 dma = drive->dma;
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
- IDE_TFLAG_OUT_FEATURE | tf_flags;
- task.tf.feature = dma; /* Use PIO/DMA */
- task.tf.lbam = bcount & 0xff;
- task.tf.lbah = (bcount >> 8) & 0xff;
-
- ide_tf_dump(drive->name, &task.tf);
- hwif->tp_ops->set_irq(hwif, 1);
- SELECT_MASK(drive, 0);
- hwif->tp_ops->tf_load(drive, &task);
+ cmd->protocol = dma ? ATAPI_PROT_DMA : ATAPI_PROT_PIO;
+ cmd->tf_flags |= IDE_TFLAG_OUT_LBAH | IDE_TFLAG_OUT_LBAM |
+ IDE_TFLAG_OUT_FEATURE | tf_flags;
+ cmd->tf.command = ATA_CMD_PACKET;
+ cmd->tf.feature = dma; /* Use PIO/DMA */
+ cmd->tf.lbam = bcount & 0xff;
+ cmd->tf.lbah = (bcount >> 8) & 0xff;
}
static u8 ide_read_ireason(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_NSECT;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_NSECT;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.nsect & 3;
+ return cmd.tf.nsect & 3;
}
static u8 ide_wait_ireason(ide_drive_t *drive, u8 ireason)
@@ -597,11 +555,17 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
}
+ hwif->expiry = expiry;
+
/* Set the interrupt routine */
ide_set_handler(drive,
(dev_is_idecd(drive) ? drive->irq_handler
: ide_pc_intr),
- timeout, expiry);
+ timeout);
+
+ /* Send the actual packet */
+ if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
+ hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
/* Begin DMA, if necessary */
if (dev_is_idecd(drive)) {
@@ -614,30 +578,28 @@ static ide_startstop_t ide_transfer_pc(ide_drive_t *drive)
}
}
- /* Send the actual packet */
- if ((drive->atapi_flags & IDE_AFLAG_ZIP_DRIVE) == 0)
- hwif->tp_ops->output_data(drive, NULL, rq->cmd, cmd_len);
-
return ide_started;
}
-ide_startstop_t ide_issue_pc(ide_drive_t *drive)
+ide_startstop_t ide_issue_pc(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_atapi_pc *pc;
ide_hwif_t *hwif = drive->hwif;
ide_expiry_t *expiry = NULL;
+ struct request *rq = hwif->rq;
unsigned int timeout;
u32 tf_flags;
u16 bcount;
+ u8 drq_int = !!(drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT);
if (dev_is_idecd(drive)) {
tf_flags = IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL;
- bcount = ide_cd_get_xferlen(hwif->rq);
+ bcount = ide_cd_get_xferlen(rq);
expiry = ide_cd_expiry;
timeout = ATAPI_WAIT_PC;
if (drive->dma)
- drive->dma = !hwif->dma_ops->dma_setup(drive);
+ drive->dma = !ide_dma_prepare(drive, cmd);
} else {
pc = drive->pc;
@@ -655,9 +617,8 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
ide_dma_off(drive);
}
- if ((pc->flags & PC_FLAG_DMA_OK) &&
- (drive->dev_flags & IDE_DFLAG_USING_DMA))
- drive->dma = !hwif->dma_ops->dma_setup(drive);
+ if (pc->flags & PC_FLAG_DMA_OK)
+ drive->dma = !ide_dma_prepare(drive, cmd);
if (!drive->dma)
pc->flags &= ~PC_FLAG_DMA_OK;
@@ -666,18 +627,18 @@ ide_startstop_t ide_issue_pc(ide_drive_t *drive)
: WAIT_TAPE_CMD;
}
- ide_pktcmd_tf_load(drive, tf_flags, bcount);
+ ide_init_packet_cmd(cmd, tf_flags, bcount, drive->dma);
- /* Issue the packet command */
- if (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT) {
+ (void)do_rw_taskfile(drive, cmd);
+
+ if (drq_int) {
if (drive->dma)
drive->waiting_for_dma = 0;
- ide_execute_command(drive, ATA_CMD_PACKET, ide_transfer_pc,
- timeout, expiry);
- return ide_started;
- } else {
- ide_execute_pkt_cmd(drive);
- return ide_transfer_pc(drive);
+ hwif->expiry = expiry;
}
+
+ ide_execute_command(drive, cmd, ide_transfer_pc, timeout);
+
+ return drq_int ? ide_started : ide_transfer_pc(drive);
}
EXPORT_SYMBOL_GPL(ide_issue_pc);
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 2177cd11664..35729a47f79 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -4,7 +4,7 @@
* Copyright (C) 1994-1996 Scott Snyder <snyder@fnald0.fnal.gov>
* Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org>
* Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de>
- * Copyright (C) 2005, 2007 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2005, 2007-2009 Bartlomiej Zolnierkiewicz
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
@@ -12,12 +12,9 @@
* See Documentation/cdrom/ide-cd for usage information.
*
* Suggestions are welcome. Patches that work are more welcome though. ;-)
- * For those wishing to work on this driver, please be sure you download
- * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
- * (SFF-8020i rev 2.6) standards. These documents can be obtained by
- * anonymous ftp from:
- * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
- * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
+ *
+ * Documentation:
+ * Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards.
*
* For historical changelog please see:
* Documentation/ide/ChangeLog.ide-cd.1994-2004
@@ -100,8 +97,7 @@ static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
{
int log = 0;
- ide_debug_log(IDE_DBG_SENSE, "Call %s, sense_key: 0x%x\n", __func__,
- sense->sense_key);
+ ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
return 0;
@@ -151,13 +147,12 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive,
unsigned long bio_sectors;
struct cdrom_info *info = drive->driver_data;
- ide_debug_log(IDE_DBG_SENSE, "Call %s, error_code: 0x%x, "
- "sense_key: 0x%x\n", __func__, sense->error_code,
- sense->sense_key);
+ ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
+ sense->error_code, sense->sense_key);
if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "%s: failed cmd: 0x%x\n",
- __func__, failed_command->cmd[0]);
+ ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
+ failed_command->cmd[0]);
if (!cdrom_log_sense(drive, failed_command, sense))
return;
@@ -215,9 +210,9 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command)
{
struct cdrom_info *info = drive->driver_data;
- struct request *rq = &info->request_sense_request;
+ struct request *rq = &drive->request_sense_rq;
- ide_debug_log(IDE_DBG_SENSE, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_SENSE, "enter");
if (sense == NULL)
sense = &info->sense_data;
@@ -239,79 +234,42 @@ static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
rq->buffer = (void *) failed_command;
if (failed_command)
- ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x\n",
- failed_command->cmd[0]);
+ ide_debug_log(IDE_DBG_SENSE, "failed_cmd: 0x%x",
+ failed_command->cmd[0]);
drive->hwif->rq = NULL;
elv_add_request(drive->queue, rq, ELEVATOR_INSERT_FRONT, 0);
}
-static void cdrom_end_request(ide_drive_t *drive, int uptodate)
+static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
- struct request *rq = drive->hwif->rq;
- int nsectors = rq->hard_cur_sectors;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s, cmd: 0x%x, uptodate: 0x%x, "
- "nsectors: %d\n", __func__, rq->cmd[0], uptodate,
- nsectors);
-
- if (blk_sense_request(rq) && uptodate) {
- /*
- * For REQ_TYPE_SENSE, "rq->buffer" points to the original
- * failed request
- */
- struct request *failed = (struct request *) rq->buffer;
- struct cdrom_info *info = drive->driver_data;
- void *sense = &info->sense_data;
-
- if (failed) {
- if (failed->sense) {
- sense = failed->sense;
- failed->sense_len = rq->sense_len;
- }
- cdrom_analyze_sense_data(drive, failed, sense);
- /*
- * now end the failed request
- */
- if (blk_fs_request(failed)) {
- if (ide_end_dequeued_request(drive, failed, 0,
- failed->hard_nr_sectors))
- BUG();
- } else {
- if (blk_end_request(failed, -EIO,
- failed->data_len))
- BUG();
- }
- } else
- cdrom_analyze_sense_data(drive, NULL, sense);
- }
-
- if (!rq->current_nr_sectors && blk_fs_request(rq))
- uptodate = 1;
- /* make sure it's fully ended */
- if (blk_pc_request(rq))
- nsectors = (rq->data_len + 511) >> 9;
- if (!nsectors)
- nsectors = 1;
-
- ide_debug_log(IDE_DBG_FUNC, "Exit %s, uptodate: 0x%x, nsectors: %d\n",
- __func__, uptodate, nsectors);
+ /*
+ * For REQ_TYPE_SENSE, "rq->buffer" points to the original
+ * failed request
+ */
+ struct request *failed = (struct request *)rq->buffer;
+ struct cdrom_info *info = drive->driver_data;
+ void *sense = &info->sense_data;
- ide_end_request(drive, uptodate, nsectors);
-}
+ if (failed) {
+ if (failed->sense) {
+ sense = failed->sense;
+ failed->sense_len = rq->sense_len;
+ }
+ cdrom_analyze_sense_data(drive, failed, sense);
-static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 st)
-{
- if (st & 0x80)
- return;
- ide_dump_status(drive, msg, st);
+ if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
+ BUG();
+ } else
+ cdrom_analyze_sense_data(drive, NULL, sense);
}
/*
* Returns:
* 0: if the request should be continued.
- * 1: if the request was ended.
+ * 1: if the request will be going through error recovery.
+ * 2: if the request should be ended.
*/
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
{
@@ -332,15 +290,10 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
err = ide_read_error(drive);
sense_key = err >> 4;
- if (rq == NULL) {
- printk(KERN_ERR PFX "%s: missing rq in %s\n",
- drive->name, __func__);
- return 1;
- }
-
- ide_debug_log(IDE_DBG_RQ, "%s: stat: 0x%x, good_stat: 0x%x, "
- "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x, err: 0x%x\n",
- __func__, stat, good_stat, rq->cmd[0], rq->cmd_type, err);
+ ide_debug_log(IDE_DBG_RQ, "stat: 0x%x, good_stat: 0x%x, cmd[0]: 0x%x, "
+ "rq->cmd_type: 0x%x, err: 0x%x",
+ stat, good_stat, rq->cmd[0], rq->cmd_type,
+ err);
if (blk_sense_request(rq)) {
/*
@@ -349,10 +302,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* Just give up.
*/
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
- ide_error(drive, "request sense failure", stat);
- return 1;
-
+ return 2;
} else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
/* All other functions, except for READ. */
@@ -455,21 +405,19 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
* No point in retrying after an illegal request or data
* protect error.
*/
- ide_dump_status_no_sense(drive, "command error", stat);
+ ide_dump_status(drive, "command error", stat);
do_end_request = 1;
} else if (sense_key == MEDIUM_ERROR) {
/*
* No point in re-trying a zillion times on a bad
* sector. If we got here the error is not correctable.
*/
- ide_dump_status_no_sense(drive,
- "media error (bad sector)",
- stat);
+ ide_dump_status(drive, "media error (bad sector)",
+ stat);
do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
/* disk appears blank ?? */
- ide_dump_status_no_sense(drive, "media error (blank)",
- stat);
+ ide_dump_status(drive, "media error (blank)", stat);
do_end_request = 1;
} else if ((err & ~ATA_ABORTED) != 0) {
/* go to the default handler for other errors */
@@ -494,14 +442,12 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
*/
if (stat & ATA_ERR)
cdrom_queue_request_sense(drive, NULL, NULL);
+ return 1;
} else {
blk_dump_rq_flags(rq, PFX "bad rq");
- cdrom_end_request(drive, 0);
+ return 2;
}
- /* retry, or handle the next request */
- return 1;
-
end_request:
if (stat & ATA_ERR) {
struct request_queue *q = drive->queue;
@@ -514,10 +460,9 @@ end_request:
hwif->rq = NULL;
cdrom_queue_request_sense(drive, rq->sense, rq);
+ return 1;
} else
- cdrom_end_request(drive, 0);
-
- return 1;
+ return 2;
}
/*
@@ -530,8 +475,7 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
{
ide_hwif_t *hwif = drive->hwif;
- ide_debug_log(IDE_DBG_FUNC, "Call %s, ireason: 0x%x, rw: 0x%x\n",
- __func__, ireason, rw);
+ ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw);
/*
* ireason == 0: the drive wants to receive data from us
@@ -562,115 +506,28 @@ static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
if (rq->cmd_type == REQ_TYPE_ATA_PC)
rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, 0);
return -1;
}
-/*
- * Assume that the drive will always provide data in multiples of at least
- * SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise.
- */
-static int ide_cd_check_transfer_size(ide_drive_t *drive, int len)
-{
- ide_debug_log(IDE_DBG_FUNC, "Call %s, len: %d\n", __func__, len);
-
- if ((len % SECTOR_SIZE) == 0)
- return 0;
-
- printk(KERN_ERR PFX "%s: %s: Bad transfer size %d\n", drive->name,
- __func__, len);
-
- if (drive->atapi_flags & IDE_AFLAG_LIMIT_NFRAMES)
- printk(KERN_ERR PFX "This drive is not supported by this "
- "version of the driver\n");
- else {
- printk(KERN_ERR PFX "Trying to limit transfer sizes\n");
- drive->atapi_flags |= IDE_AFLAG_LIMIT_NFRAMES;
- }
-
- return 1;
-}
-
-static ide_startstop_t ide_cd_prepare_rw_request(ide_drive_t *drive,
- struct request *rq)
+static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_debug_log(IDE_DBG_RQ, "Call %s: rq->cmd_flags: 0x%x\n", __func__,
- rq->cmd_flags);
-
- if (rq_data_dir(rq) == READ) {
- unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
- int nskip = rq->sector & (sectors_per_frame - 1);
+ struct request *rq = cmd->rq;
- /*
- * If the requested sector doesn't start on a frame boundary,
- * we must adjust the start of the transfer so that it does,
- * and remember to skip the first few sectors.
- *
- * If the rq->current_nr_sectors field is larger than the size
- * of the buffer, it will mean that we're to skip a number of
- * sectors equal to the amount by which rq->current_nr_sectors
- * is larger than the buffer size.
- */
- if (nskip > 0) {
- /* sanity check... */
- if (rq->current_nr_sectors !=
- bio_cur_sectors(rq->bio)) {
- printk(KERN_ERR PFX "%s: %s: buffer botch (%u)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- rq->current_nr_sectors += nskip;
- }
- }
-
- /* set up the command */
- rq->timeout = ATAPI_WAIT_PC;
-
- return ide_started;
-}
-
-/*
- * Fix up a possibly partially-processed request so that we can start it over
- * entirely, or even put it back on the request queue.
- */
-static void ide_cd_restore_request(ide_drive_t *drive, struct request *rq)
-{
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- if (rq->buffer != bio_data(rq->bio)) {
- sector_t n =
- (rq->buffer - (char *)bio_data(rq->bio)) / SECTOR_SIZE;
-
- rq->buffer = bio_data(rq->bio);
- rq->nr_sectors += n;
- rq->sector -= n;
- }
- rq->current_nr_sectors = bio_cur_sectors(rq->bio);
- rq->hard_cur_sectors = rq->current_nr_sectors;
- rq->hard_nr_sectors = rq->nr_sectors;
- rq->hard_sector = rq->sector;
- rq->q->prep_rq_fn(rq->q, rq);
-}
-
-static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct request *rq)
-{
- ide_debug_log(IDE_DBG_FUNC, "Call %s, rq->cmd[0]: 0x%x\n",
- __func__, rq->cmd[0]);
+ ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
/*
* Some of the trailing request sense fields are optional,
* and some drives don't send them. Sigh.
*/
if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
- rq->data_len > 0 && rq->data_len <= 5)
- while (rq->data_len > 0) {
- *(u8 *)rq->data++ = 0;
- --rq->data_len;
+ cmd->nleft > 0 && cmd->nleft <= 5) {
+ unsigned int ofs = cmd->nbytes - cmd->nleft;
+
+ while (cmd->nleft > 0) {
+ *((u8 *)rq->data + ofs++) = 0;
+ cmd->nleft--;
}
+ }
}
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
@@ -686,9 +543,9 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
if (!sense)
sense = &local_sense;
- ide_debug_log(IDE_DBG_PC, "Call %s, cmd[0]: 0x%x, write: 0x%x, "
- "timeout: %d, cmd_flags: 0x%x\n", __func__, cmd[0], write,
- timeout, cmd_flags);
+ ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
+ "cmd_flags: 0x%x",
+ cmd[0], write, timeout, cmd_flags);
/* start of retry loop */
do {
@@ -750,36 +607,40 @@ int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
return (flags & REQ_FAILED) ? -EIO : 0;
}
-/*
- * Called from blk_end_request_callback() after the data of the request is
- * completed and before the request itself is completed. By returning value '1',
- * blk_end_request_callback() returns immediately without completing it.
- */
-static int cdrom_newpc_intr_dummy_cb(struct request *rq)
+static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
- return 1;
+ unsigned int nr_bytes = cmd->nbytes - cmd->nleft;
+
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
+ nr_bytes -= cmd->last_xfer_len;
+
+ if (nr_bytes > 0)
+ ide_complete_rq(drive, 0, nr_bytes);
}
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq = hwif->rq;
- xfer_func_t *xferfunc;
ide_expiry_t *expiry = NULL;
int dma_error = 0, dma, stat, thislen, uptodate = 0;
- int write = (rq_data_dir(rq) == WRITE) ? 1 : 0;
+ int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc, nsectors;
+ int sense = blk_sense_request(rq);
unsigned int timeout;
u16 len;
u8 ireason;
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x\n",
- __func__, rq->cmd[0], write);
+ ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x",
+ rq->cmd[0], write);
/* check for errors */
dma = drive->dma;
if (dma) {
drive->dma = 0;
+ drive->waiting_for_dma = 0;
dma_error = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
if (dma_error) {
printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name,
write ? "write" : "read");
@@ -787,31 +648,29 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
}
}
- if (cdrom_decode_status(drive, 0, &stat))
+ rc = cdrom_decode_status(drive, 0, &stat);
+ if (rc) {
+ if (rc == 2)
+ goto out_end;
return ide_stopped;
+ }
/* using dma, transfer is complete now */
if (dma) {
if (dma_error)
return ide_error(drive, "dma error", stat);
- if (blk_fs_request(rq)) {
- ide_end_request(drive, 1, rq->nr_sectors);
- return ide_stopped;
- } else if (rq->cmd_type == REQ_TYPE_ATA_PC && !rq->bio) {
- ide_end_request(drive, 1, 1);
- return ide_stopped;
- }
- goto end_request;
+ uptodate = 1;
+ goto out_end;
}
ide_read_bcount_and_ireason(drive, &len, &ireason);
- thislen = blk_fs_request(rq) ? len : rq->data_len;
+ thislen = blk_fs_request(rq) ? len : cmd->nleft;
if (thislen > len)
thislen = len;
- ide_debug_log(IDE_DBG_PC, "%s: DRQ: stat: 0x%x, thislen: %d\n",
- __func__, stat, thislen);
+ ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d",
+ stat, thislen);
/* If DRQ is clear, the command has completed. */
if ((stat & ATA_DRQ) == 0) {
@@ -821,135 +680,62 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
* Otherwise, complete the command normally.
*/
uptodate = 1;
- if (rq->current_nr_sectors > 0) {
+ if (cmd->nleft > 0) {
printk(KERN_ERR PFX "%s: %s: data underrun "
- "(%d blocks)\n",
- drive->name, __func__,
- rq->current_nr_sectors);
+ "(%u bytes)\n", drive->name, __func__,
+ cmd->nleft);
if (!write)
rq->cmd_flags |= REQ_FAILED;
uptodate = 0;
}
- cdrom_end_request(drive, uptodate);
- return ide_stopped;
} else if (!blk_pc_request(rq)) {
- ide_cd_request_sense_fixup(drive, rq);
+ ide_cd_request_sense_fixup(drive, cmd);
/* complain if we still have data left to transfer */
- uptodate = rq->data_len ? 0 : 1;
+ uptodate = cmd->nleft ? 0 : 1;
+ if (uptodate == 0)
+ rq->cmd_flags |= REQ_FAILED;
}
- goto end_request;
+ goto out_end;
}
/* check which way to transfer data */
- if (ide_cd_check_ireason(drive, rq, len, ireason, write))
- return ide_stopped;
+ rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
+ if (rc)
+ goto out_end;
- if (blk_fs_request(rq)) {
- if (write == 0) {
- int nskip;
-
- if (ide_cd_check_transfer_size(drive, len)) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
+ cmd->last_xfer_len = 0;
- /*
- * First, figure out if we need to bit-bucket
- * any of the leading sectors.
- */
- nskip = min_t(int, rq->current_nr_sectors
- - bio_cur_sectors(rq->bio),
- thislen >> 9);
- if (nskip > 0) {
- ide_pad_transfer(drive, write, nskip << 9);
- rq->current_nr_sectors -= nskip;
- thislen -= (nskip << 9);
- }
- }
- }
-
- if (ireason == 0) {
- write = 1;
- xferfunc = hwif->tp_ops->output_data;
- } else {
- write = 0;
- xferfunc = hwif->tp_ops->input_data;
- }
-
- ide_debug_log(IDE_DBG_PC, "%s: data transfer, rq->cmd_type: 0x%x, "
- "ireason: 0x%x\n", __func__, rq->cmd_type, ireason);
+ ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, "
+ "ireason: 0x%x",
+ rq->cmd_type, ireason);
/* transfer data */
while (thislen > 0) {
- u8 *ptr = blk_fs_request(rq) ? NULL : rq->data;
- int blen = rq->data_len;
-
- /* bio backed? */
- if (rq->bio) {
- if (blk_fs_request(rq)) {
- ptr = rq->buffer;
- blen = rq->current_nr_sectors << 9;
- } else {
- ptr = bio_data(rq->bio);
- blen = bio_iovec(rq->bio)->bv_len;
- }
- }
+ int blen = min_t(int, thislen, cmd->nleft);
- if (!ptr) {
- if (blk_fs_request(rq) && !write)
- /*
- * If the buffers are full, pipe the rest into
- * oblivion.
- */
- ide_pad_transfer(drive, 0, thislen);
- else {
- printk(KERN_ERR PFX "%s: confused, missing data\n",
- drive->name);
- blk_dump_rq_flags(rq, rq_data_dir(rq)
- ? "cdrom_newpc_intr, write"
- : "cdrom_newpc_intr, read");
- }
+ if (cmd->nleft == 0)
break;
- }
-
- if (blen > thislen)
- blen = thislen;
- xferfunc(drive, NULL, ptr, blen);
+ ide_pio_bytes(drive, cmd, write, blen);
+ cmd->last_xfer_len += blen;
thislen -= blen;
len -= blen;
- if (blk_fs_request(rq)) {
- rq->buffer += blen;
- rq->nr_sectors -= (blen >> 9);
- rq->current_nr_sectors -= (blen >> 9);
- rq->sector += (blen >> 9);
-
- if (rq->current_nr_sectors == 0 && rq->nr_sectors)
- cdrom_end_request(drive, 1);
- } else {
- rq->data_len -= blen;
-
- /*
- * The request can't be completed until DRQ is cleared.
- * So complete the data, but don't complete the request
- * using the dummy function for the callback feature
- * of blk_end_request_callback().
- */
- if (rq->bio)
- blk_end_request_callback(rq, 0, blen,
- cdrom_newpc_intr_dummy_cb);
- else
- rq->data += blen;
- }
- if (!write && blk_sense_request(rq))
+ if (sense && write == 0)
rq->sense_len += blen;
}
/* pad, if necessary */
- if (!blk_fs_request(rq) && len > 0)
- ide_pad_transfer(drive, write, len);
+ if (len > 0) {
+ if (blk_fs_request(rq) == 0 || write == 0)
+ ide_pad_transfer(drive, write, len);
+ else {
+ printk(KERN_ERR PFX "%s: confused, missing data\n",
+ drive->name);
+ blk_dump_rq_flags(rq, "cdrom_newpc_intr");
+ }
+ }
if (blk_pc_request(rq)) {
timeout = rq->timeout;
@@ -959,24 +745,54 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
expiry = ide_cd_expiry;
}
- ide_set_handler(drive, cdrom_newpc_intr, timeout, expiry);
+ hwif->expiry = expiry;
+ ide_set_handler(drive, cdrom_newpc_intr, timeout);
return ide_started;
-end_request:
- if (blk_pc_request(rq)) {
+out_end:
+ if (blk_pc_request(rq) && rc == 0) {
unsigned int dlen = rq->data_len;
- if (dma)
- rq->data_len = 0;
+ rq->data_len = 0;
if (blk_end_request(rq, 0, dlen))
BUG();
hwif->rq = NULL;
} else {
- if (!uptodate)
- rq->cmd_flags |= REQ_FAILED;
- cdrom_end_request(drive, uptodate);
+ if (sense && uptodate)
+ ide_cd_complete_failed_rq(drive, rq);
+
+ if (blk_fs_request(rq)) {
+ if (cmd->nleft == 0)
+ uptodate = 1;
+ } else {
+ if (uptodate <= 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ }
+
+ if (uptodate == 0)
+ ide_cd_error_cmd(drive, cmd);
+
+ /* make sure it's fully ended */
+ if (blk_pc_request(rq))
+ nsectors = (rq->data_len + 511) >> 9;
+ else
+ nsectors = rq->hard_nr_sectors;
+
+ if (nsectors == 0)
+ nsectors = 1;
+
+ if (blk_fs_request(rq) == 0) {
+ rq->data_len -= (cmd->nbytes - cmd->nleft);
+ if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
+ rq->data_len += cmd->last_xfer_len;
+ }
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ if (sense && rc == 2)
+ ide_error(drive, "request sense failure", stat);
}
return ide_stopped;
}
@@ -984,51 +800,48 @@ end_request:
static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
+ struct request_queue *q = drive->queue;
int write = rq_data_dir(rq) == WRITE;
unsigned short sectors_per_frame =
- queue_hardsect_size(drive->queue) >> SECTOR_BITS;
+ queue_hardsect_size(q) >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, write: 0x%x, "
- "secs_per_frame: %u\n",
- __func__, rq->cmd[0], write, sectors_per_frame);
+ ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
+ "secs_per_frame: %u",
+ rq->cmd[0], rq->cmd_flags, sectors_per_frame);
if (write) {
/* disk has become write protected */
- if (get_disk_ro(cd->disk)) {
- cdrom_end_request(drive, 0);
+ if (get_disk_ro(cd->disk))
return ide_stopped;
- }
} else {
/*
* We may be retrying this request after an error. Fix up any
* weirdness which might be present in the request packet.
*/
- ide_cd_restore_request(drive, rq);
+ q->prep_rq_fn(q, rq);
}
- /* use DMA, if possible / writes *must* be hardware frame aligned */
+ /* fs requests *must* be hardware frame aligned */
if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
- (rq->sector & (sectors_per_frame - 1))) {
- if (write) {
- cdrom_end_request(drive, 0);
- return ide_stopped;
- }
- drive->dma = 0;
- } else
- drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
+ (rq->sector & (sectors_per_frame - 1)))
+ return ide_stopped;
+
+ /* use DMA, if possible */
+ drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
if (write)
cd->devinfo.media_written = 1;
+ rq->timeout = ATAPI_WAIT_PC;
+
return ide_started;
}
static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
{
- ide_debug_log(IDE_DBG_PC, "Call %s, rq->cmd[0]: 0x%x, "
- "rq->cmd_type: 0x%x\n", __func__, rq->cmd[0],
- rq->cmd_type);
+ ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
+ rq->cmd[0], rq->cmd_type);
if (blk_pc_request(rq))
rq->cmd_flags |= REQ_QUIET;
@@ -1067,17 +880,18 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
sector_t block)
{
- ide_debug_log(IDE_DBG_RQ, "Call %s, rq->cmd[0]: 0x%x, "
- "rq->cmd_type: 0x%x, block: %llu\n",
- __func__, rq->cmd[0], rq->cmd_type,
- (unsigned long long)block);
+ struct ide_cmd cmd;
+ int uptodate = 0, nsectors;
+
+ ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
+ rq->cmd[0], (unsigned long long)block);
+
+ if (drive->debug_mask & IDE_DBG_RQ)
+ blk_dump_rq_flags(rq, "ide_cd_do_request");
if (blk_fs_request(rq)) {
if (cdrom_start_rw(drive, rq) == ide_stopped)
- return ide_stopped;
-
- if (ide_cd_prepare_rw_request(drive, rq) == ide_stopped)
- return ide_stopped;
+ goto out_end;
} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
rq->cmd_type == REQ_TYPE_ATA_PC) {
if (!rq->timeout)
@@ -1086,15 +900,38 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
cdrom_do_block_pc(drive, rq);
} else if (blk_special_request(rq)) {
/* right now this can only be a reset... */
- cdrom_end_request(drive, 1);
- return ide_stopped;
+ uptodate = 1;
+ goto out_end;
} else {
blk_dump_rq_flags(rq, DRV_NAME " bad flags");
- cdrom_end_request(drive, 0);
- return ide_stopped;
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ goto out_end;
+ }
+
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
+ if (blk_fs_request(rq) || rq->data_len) {
+ ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9)
+ : rq->data_len);
+ ide_map_sg(drive, &cmd);
}
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, &cmd);
+out_end:
+ nsectors = rq->hard_nr_sectors;
+
+ if (nsectors == 0)
+ nsectors = 1;
+
+ ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);
+
+ return ide_stopped;
}
/*
@@ -1119,7 +956,7 @@ int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
struct cdrom_device_info *cdi = &info->devinfo;
unsigned char cmd[BLK_MAX_CDB];
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_TEST_UNIT_READY;
@@ -1147,7 +984,7 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
unsigned len = sizeof(capbuf);
u32 blocklen;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
cmd[0] = GPCMD_READ_CDVD_CAPACITY;
@@ -1179,8 +1016,8 @@ static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
*capacity = 1 + be32_to_cpu(capbuf.lba);
*sectors_per_frame = blocklen >> SECTOR_BITS;
- ide_debug_log(IDE_DBG_PROBE, "%s: cap: %lu, sectors_per_frame: %lu\n",
- __func__, *capacity, *sectors_per_frame);
+ ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu",
+ *capacity, *sectors_per_frame);
return 0;
}
@@ -1191,7 +1028,7 @@ static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
{
unsigned char cmd[BLK_MAX_CDB];
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
memset(cmd, 0, BLK_MAX_CDB);
@@ -1221,7 +1058,7 @@ int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
long last_written;
unsigned long sectors_per_frame = SECTORS_PER_FRAME;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (toc == NULL) {
/* try to allocate space */
@@ -1383,7 +1220,7 @@ int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
struct packet_command cgc;
int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0)
size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
@@ -1403,7 +1240,7 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
struct cdrom_info *cd = drive->driver_data;
u16 curspeed, maxspeed;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
@@ -1413,8 +1250,8 @@ void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
}
- ide_debug_log(IDE_DBG_PROBE, "%s: curspeed: %u, maxspeed: %u\n",
- __func__, curspeed, maxspeed);
+ ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
+ curspeed, maxspeed);
cd->current_speed = (curspeed + (176/2)) / 176;
cd->max_speed = (maxspeed + (176/2)) / 176;
@@ -1448,7 +1285,7 @@ static int ide_cdrom_register(ide_drive_t *drive, int nslots)
struct cdrom_info *info = drive->driver_data;
struct cdrom_device_info *devinfo = &info->devinfo;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, nslots: %d\n", __func__, nslots);
+ ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots);
devinfo->ops = &ide_cdrom_dops;
devinfo->speed = info->current_speed;
@@ -1471,9 +1308,8 @@ static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
mechtype_t mechtype;
int nslots = 1;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->media: 0x%x, "
- "drive->atapi_flags: 0x%lx\n", __func__, drive->media,
- drive->atapi_flags);
+ ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx",
+ drive->media, drive->atapi_flags);
cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
@@ -1687,9 +1523,6 @@ static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
#endif
static const struct cd_list_entry ide_cd_quirks_list[] = {
- /* Limit transfer size per interrupt. */
- { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_AFLAG_LIMIT_NFRAMES },
- { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_AFLAG_LIMIT_NFRAMES },
/* SCR-3231 doesn't support the SET_CD_SPEED command. */
{ "SAMSUNG CD-ROM SCR-3231", NULL, IDE_AFLAG_NO_SPEED_SELECT },
/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
@@ -1750,18 +1583,18 @@ static int ide_cdrom_setup(ide_drive_t *drive)
{
struct cdrom_info *cd = drive->driver_data;
struct cdrom_device_info *cdi = &cd->devinfo;
+ struct request_queue *q = drive->queue;
u16 *id = drive->id;
char *fw_rev = (char *)&id[ATA_ID_FW_REV];
int nslots;
- ide_debug_log(IDE_DBG_PROBE, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_PROBE, "enter");
- blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
- blk_queue_dma_alignment(drive->queue, 31);
- blk_queue_update_dma_pad(drive->queue, 15);
- drive->queue->unplug_delay = (1 * HZ) / 1000;
- if (!drive->queue->unplug_delay)
- drive->queue->unplug_delay = 1;
+ blk_queue_prep_rq(q, ide_cdrom_prep_fn);
+ blk_queue_dma_alignment(q, 31);
+ blk_queue_update_dma_pad(q, 15);
+
+ q->unplug_delay = max((1 * HZ) / 1000, 1);
drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
@@ -1779,8 +1612,7 @@ static int ide_cdrom_setup(ide_drive_t *drive)
nslots = ide_cdrom_probe_capabilities(drive);
- /* set correct block size */
- blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
+ blk_queue_hardsect_size(q, CD_FRAMESIZE);
if (ide_cdrom_register(drive, nslots)) {
printk(KERN_ERR PFX "%s: %s failed to register device with the"
@@ -1797,7 +1629,7 @@ static void ide_cd_remove(ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
ide_proc_unregister_driver(drive, info->driver);
device_del(&info->dev);
@@ -1815,7 +1647,7 @@ static void ide_cd_release(struct device *dev)
ide_drive_t *drive = info->drive;
struct gendisk *g = info->disk;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
kfree(info->toc);
if (devinfo->handle == drive)
@@ -1839,7 +1671,6 @@ static struct ide_driver ide_cdrom_driver = {
.remove = ide_cd_remove,
.version = IDECD_VERSION,
.do_request = ide_cd_do_request,
- .end_request = ide_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_cd_proc_entries,
.proc_devsets = ide_cd_proc_devsets,
@@ -1960,9 +1791,6 @@ static struct block_device_operations idecd_ops = {
};
/* module options */
-static char *ignore;
-module_param(ignore, charp, 0400);
-
static unsigned long debug_mask;
module_param(debug_mask, ulong, 0644);
@@ -1974,9 +1802,8 @@ static int ide_cd_probe(ide_drive_t *drive)
struct gendisk *g;
struct request_sense sense;
- ide_debug_log(IDE_DBG_PROBE, "Call %s, drive->driver_req: %s, "
- "drive->media: 0x%x\n", __func__, drive->driver_req,
- drive->media);
+ ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x",
+ drive->driver_req, drive->media);
if (!strstr("ide-cdrom", drive->driver_req))
goto failed;
@@ -1984,15 +1811,6 @@ static int ide_cd_probe(ide_drive_t *drive)
if (drive->media != ide_cdrom && drive->media != ide_optical)
goto failed;
- /* skip drives that we were told to ignore */
- if (ignore != NULL) {
- if (strstr(ignore, drive->name)) {
- printk(KERN_INFO PFX "ignoring drive %s\n",
- drive->name);
- goto failed;
- }
- }
-
drive->debug_mask = debug_mask;
drive->irq_handler = cdrom_newpc_intr;
diff --git a/drivers/ide/ide-cd.h b/drivers/ide/ide-cd.h
index c878bfcf111..1d97101099c 100644
--- a/drivers/ide/ide-cd.h
+++ b/drivers/ide/ide-cd.h
@@ -11,7 +11,7 @@
#define IDECD_DEBUG_LOG 0
#if IDECD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
#else
#define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif
@@ -91,8 +91,6 @@ struct cdrom_info {
on this device. */
struct request_sense sense_data;
- struct request request_sense_request;
-
u8 max_speed; /* Max speed of the drive. */
u8 current_speed; /* Current speed of the drive. */
diff --git a/drivers/ide/ide-cs.c b/drivers/ide/ide-cs.c
index f50210fe558..9e47f3529d5 100644
--- a/drivers/ide/ide-cs.c
+++ b/drivers/ide/ide-cs.c
@@ -154,6 +154,7 @@ static const struct ide_port_ops idecs_port_ops = {
static const struct ide_port_info idecs_port_info = {
.port_ops = &idecs_port_ops,
.host_flags = IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
static struct ide_host *idecs_register(unsigned long io, unsigned long ctl,
diff --git a/drivers/ide/ide-devsets.c b/drivers/ide/ide-devsets.c
index 7c3953414d4..5bf958e5b1d 100644
--- a/drivers/ide/ide-devsets.c
+++ b/drivers/ide/ide-devsets.c
@@ -183,8 +183,6 @@ ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
err = setfunc(drive, *(int *)&rq->cmd[1]);
if (err)
rq->errors = err;
- else
- err = 1;
- ide_end_request(drive, err, 0);
+ ide_complete_rq(drive, err, ide_rq_bytes(rq));
return ide_stopped;
}
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 806760d24ce..c998cf8e971 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -28,7 +28,6 @@
#include <linux/mutex.h>
#include <linux/leds.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include <asm/byteorder.h>
#include <asm/irq.h>
@@ -53,33 +52,26 @@ static const u8 ide_rw_cmds[] = {
ATA_CMD_WRITE_EXT,
};
-static const u8 ide_data_phases[] = {
- TASKFILE_MULTI_IN,
- TASKFILE_MULTI_OUT,
- TASKFILE_IN,
- TASKFILE_OUT,
- TASKFILE_IN_DMA,
- TASKFILE_OUT_DMA,
-};
-
-static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
+static void ide_tf_set_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 dma)
{
u8 index, lba48, write;
- lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
- write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
+ lba48 = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
+ write = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;
- if (dma)
+ if (dma) {
+ cmd->protocol = ATA_PROT_DMA;
index = 8;
- else
- index = drive->mult_count ? 0 : 4;
-
- task->tf.command = ide_rw_cmds[index + lba48 + write];
-
- if (dma)
- index = 8; /* fixup index */
+ } else {
+ cmd->protocol = ATA_PROT_PIO;
+ if (drive->mult_count) {
+ cmd->tf_flags |= IDE_TFLAG_MULTI_PIO;
+ index = 0;
+ } else
+ index = 4;
+ }
- task->data_phase = ide_data_phases[index / 2 + write];
+ cmd->tf.command = ide_rw_cmds[index + lba48 + write];
}
/*
@@ -93,8 +85,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
u16 nsectors = (u16)rq->nr_sectors;
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
u8 dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
ide_startstop_t rc;
if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
@@ -104,13 +96,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
lba48 = 0;
}
- if (!dma) {
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- }
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (drive->dev_flags & IDE_DFLAG_LBA) {
if (lba48) {
@@ -129,7 +116,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->lbam = (u8)(block >> 8);
tf->lbah = (u8)(block >> 16);
- task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
} else {
tf->nsect = nsectors & 0xff;
tf->lbal = block;
@@ -156,23 +143,27 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
tf->device = head;
}
+ cmd.tf_flags |= IDE_TFLAG_FS;
+
if (rq_data_dir(rq))
- task.tf_flags |= IDE_TFLAG_WRITE;
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ ide_tf_set_cmd(drive, &cmd, dma);
+ cmd.rq = rq;
- ide_tf_set_cmd(drive, &task, dma);
- if (!dma)
- hwif->data_phase = task.data_phase;
- task.rq = rq;
+ if (dma == 0) {
+ ide_init_sg_cmd(&cmd, nsectors << 9);
+ ide_map_sg(drive, &cmd);
+ }
- rc = do_rw_taskfile(drive, &task);
+ rc = do_rw_taskfile(drive, &cmd);
if (rc == ide_stopped && dma) {
/* fallback to PIO */
- task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
- ide_tf_set_cmd(drive, &task, 0);
- hwif->data_phase = task.data_phase;
- ide_init_sg_cmd(drive, rq);
- rc = do_rw_taskfile(drive, &task);
+ cmd.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
+ ide_tf_set_cmd(drive, &cmd, 0);
+ ide_init_sg_cmd(&cmd, nsectors << 9);
+ rc = do_rw_taskfile(drive, &cmd);
}
return rc;
@@ -193,7 +184,9 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
if (!blk_fs_request(rq)) {
blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
- ide_end_request(drive, 0, 0);
+ if (rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
return ide_stopped;
}
@@ -216,25 +209,25 @@ static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
*/
static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u64 addr = 0;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
if (lba48)
tf->command = ATA_CMD_READ_NATIVE_MAX_EXT;
else
tf->command = ATA_CMD_READ_NATIVE_MAX;
tf->device = ATA_LBA;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
- /* submit command request */
- ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+
+ ide_no_data_taskfile(drive, &cmd);
/* if OK, compute maximum address value */
- if ((tf->status & 0x01) == 0)
+ if (!(tf->status & ATA_ERR))
addr = ide_get_lba_addr(tf, lba48) + 1;
return addr;
@@ -246,13 +239,13 @@ static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
*/
static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u64 addr_set = 0;
addr_req--;
- /* Create IDE/ATA command request structure */
- memset(&args, 0, sizeof(ide_task_t));
+
+ memset(&cmd, 0, sizeof(cmd));
tf->lbal = (addr_req >> 0) & 0xff;
tf->lbam = (addr_req >>= 8) & 0xff;
tf->lbah = (addr_req >>= 8) & 0xff;
@@ -266,13 +259,15 @@ static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
tf->command = ATA_CMD_SET_MAX;
}
tf->device |= ATA_LBA;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
if (lba48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
- /* submit command request */
- ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
+
+ ide_no_data_taskfile(drive, &cmd);
+
/* if OK, compute maximum address value */
- if ((tf->status & 0x01) == 0)
+ if (!(tf->status & ATA_ERR))
addr_set = ide_get_lba_addr(tf, lba48) + 1;
return addr_set;
@@ -389,24 +384,24 @@ static int ide_disk_get_capacity(ide_drive_t *drive)
static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
{
ide_drive_t *drive = q->queuedata;
- ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC);
+ struct ide_cmd *cmd = kmalloc(sizeof(*cmd), GFP_ATOMIC);
/* FIXME: map struct ide_taskfile on rq->cmd[] */
- BUG_ON(task == NULL);
+ BUG_ON(cmd == NULL);
- memset(task, 0, sizeof(*task));
+ memset(cmd, 0, sizeof(*cmd));
if (ata_id_flush_ext_enabled(drive->id) &&
(drive->capacity64 >= (1UL << 28)))
- task->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd->tf.command = ATA_CMD_FLUSH_EXT;
else
- task->tf.command = ATA_CMD_FLUSH;
- task->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
- IDE_TFLAG_DYN;
- task->data_phase = TASKFILE_NO_DATA;
+ cmd->tf.command = ATA_CMD_FLUSH;
+ cmd->tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
+ IDE_TFLAG_DYN;
+ cmd->protocol = ATA_PROT_NODATA;
rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
rq->cmd_flags |= REQ_SOFTBARRIER;
- rq->special = task;
+ rq->special = cmd;
}
ide_devset_get(multcount, mult_count);
@@ -456,15 +451,15 @@ static int set_nowerr(ide_drive_t *drive, int arg)
static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf.feature = feature;
- task.tf.nsect = nsect;
- task.tf.command = ATA_CMD_SET_FEATURES;
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.feature = feature;
+ cmd.tf.nsect = nsect;
+ cmd.tf.command = ATA_CMD_SET_FEATURES;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &task);
+ return ide_no_data_taskfile(drive, &cmd);
}
static void update_ordered(ide_drive_t *drive)
@@ -531,15 +526,16 @@ static int set_wcache(ide_drive_t *drive, int arg)
static int do_idedisk_flushcache(ide_drive_t *drive)
{
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
if (ata_id_flush_ext_enabled(drive->id))
- args.tf.command = ATA_CMD_FLUSH_EXT;
+ cmd.tf.command = ATA_CMD_FLUSH_EXT;
else
- args.tf.command = ATA_CMD_FLUSH;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &args);
+ cmd.tf.command = ATA_CMD_FLUSH;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ return ide_no_data_taskfile(drive, &cmd);
}
ide_devset_get(acoustic, acoustic);
@@ -711,17 +707,17 @@ static int ide_disk_init_media(ide_drive_t *drive, struct gendisk *disk)
static int ide_disk_set_doorlock(ide_drive_t *drive, struct gendisk *disk,
int on)
{
- ide_task_t task;
+ struct ide_cmd cmd;
int ret;
if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) == 0)
return 0;
- memset(&task, 0, sizeof(task));
- task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- ret = ide_no_data_taskfile(drive, &task);
+ ret = ide_no_data_taskfile(drive, &cmd);
if (ret)
drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
@@ -737,6 +733,5 @@ const struct ide_disk_ops ide_ata_disk_ops = {
.init_media = ide_disk_init_media,
.set_doorlock = ide_disk_set_doorlock,
.do_request = ide_do_rw_disk,
- .end_request = ide_end_request,
.ioctl = ide_disk_ioctl,
};
diff --git a/drivers/ide/ide-disk_proc.c b/drivers/ide/ide-disk_proc.c
index 1f86dcbd2b1..eaea3bef207 100644
--- a/drivers/ide/ide-disk_proc.c
+++ b/drivers/ide/ide-disk_proc.c
@@ -1,38 +1,38 @@
#include <linux/kernel.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include "ide-disk.h"
static int smart_enable(ide_drive_t *drive)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = ATA_SMART_ENABLE;
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- return ide_no_data_taskfile(drive, &args);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+
+ return ide_no_data_taskfile(drive, &cmd);
}
static int get_smart_data(ide_drive_t *drive, u8 *buf, u8 sub_cmd)
{
- ide_task_t args;
- struct ide_taskfile *tf = &args.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = sub_cmd;
tf->nsect = 0x01;
tf->lbam = ATA_SMART_LBAM_PASS;
tf->lbah = ATA_SMART_LBAH_PASS;
tf->command = ATA_CMD_SMART;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args.data_phase = TASKFILE_IN;
- (void) smart_enable(drive);
- return ide_raw_taskfile(drive, &args, buf, 1);
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.protocol = ATA_PROT_PIO;
+
+ return ide_raw_taskfile(drive, &cmd, buf, 1);
}
static int proc_idedisk_read_cache
@@ -67,6 +67,8 @@ static int proc_idedisk_read_smart(char *page, char **start, off_t off,
ide_drive_t *drive = (ide_drive_t *)data;
int len = 0, i = 0;
+ (void)smart_enable(drive);
+
if (get_smart_data(drive, page, sub_cmd) == 0) {
unsigned short *val = (unsigned short *) page;
char *out = (char *)val + SECTOR_SIZE;
diff --git a/drivers/ide/ide-dma-sff.c b/drivers/ide/ide-dma-sff.c
index 123d393658a..16fc46edc32 100644
--- a/drivers/ide/ide-dma-sff.c
+++ b/drivers/ide/ide-dma-sff.c
@@ -38,10 +38,9 @@ int config_drive_for_dma(ide_drive_t *drive)
* Enable DMA on any drive that has mode2 DMA
* (multi or single) enabled
*/
- if (id[ATA_ID_FIELD_VALID] & 2) /* regular DMA */
- if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
- (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
- return 1;
+ if ((id[ATA_ID_MWDMA_MODES] & 0x404) == 0x404 ||
+ (id[ATA_ID_SWDMA_MODES] & 0x404) == 0x404)
+ return 1;
/* Consult the list of known "good" drives */
if (ide_dma_good_drive(drive))
@@ -111,7 +110,7 @@ EXPORT_SYMBOL_GPL(ide_dma_host_set);
* May also be invoked from trm290.c
*/
-int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+int ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
__le32 *table = (__le32 *)hwif->dmatable_cpu;
@@ -120,11 +119,7 @@ int ide_build_dmatable(ide_drive_t *drive, struct request *rq)
struct scatterlist *sg;
u8 is_trm290 = !!(hwif->host_flags & IDE_HFLAG_TRM290);
- hwif->sg_nents = ide_build_sglist(drive, rq);
- if (hwif->sg_nents == 0)
- return 0;
-
- for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+ for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
u32 cur_addr, cur_len, xcount, bcount;
cur_addr = sg_dma_address(sg);
@@ -170,8 +165,6 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
EXPORT_SYMBOL_GPL(ide_build_dmatable);
@@ -179,6 +172,7 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
/**
* ide_dma_setup - begin a DMA phase
* @drive: target device
+ * @cmd: command
*
* Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers for a device
@@ -189,17 +183,16 @@ EXPORT_SYMBOL_GPL(ide_build_dmatable);
* is returned.
*/
-int ide_dma_setup(ide_drive_t *drive)
+int ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int reading = rq_data_dir(rq) ? 0 : ATA_DMA_WR;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
+ u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
u8 dma_stat;
/* fall back to pio! */
- if (!ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (ide_build_dmatable(drive, cmd) == 0) {
+ ide_map_sg(drive, cmd);
return 1;
}
@@ -212,9 +205,9 @@ int ide_dma_setup(ide_drive_t *drive)
/* specify r/w */
if (mmio)
- writeb(reading, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
+ writeb(rw, (void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
else
- outb(reading, hwif->dma_base + ATA_DMA_CMD);
+ outb(rw, hwif->dma_base + ATA_DMA_CMD);
/* read DMA status for INTR & ERROR flags */
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -222,13 +215,12 @@ int ide_dma_setup(ide_drive_t *drive)
/* clear INTR & ERROR flags */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- drive->waiting_for_dma = 1;
return 0;
}
EXPORT_SYMBOL_GPL(ide_dma_setup);
/**
- * dma_timer_expiry - handle a DMA timeout
+ * ide_dma_sff_timer_expiry - handle a DMA timeout
* @drive: Drive that timed out
*
* An IDE DMA transfer timed out. In the event of an error we ask
@@ -241,7 +233,7 @@ EXPORT_SYMBOL_GPL(ide_dma_setup);
* This can occur if an interrupt is lost or due to hang or bugs.
*/
-static int dma_timer_expiry(ide_drive_t *drive)
+int ide_dma_sff_timer_expiry(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
@@ -265,14 +257,7 @@ static int dma_timer_expiry(ide_drive_t *drive)
return 0; /* Status is unknown -- reset the bus */
}
-
-void ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr, 2 * WAIT_CMD,
- dma_timer_expiry);
-}
-EXPORT_SYMBOL_GPL(ide_dma_exec_cmd);
+EXPORT_SYMBOL_GPL(ide_dma_sff_timer_expiry);
void ide_dma_start(ide_drive_t *drive)
{
@@ -303,8 +288,6 @@ int ide_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0, mask;
- drive->waiting_for_dma = 0;
-
/* stop DMA */
if (hwif->host_flags & IDE_HFLAG_MMIO) {
dma_cmd = readb((void __iomem *)(hwif->dma_base + ATA_DMA_CMD));
@@ -321,8 +304,6 @@ int ide_dma_end(ide_drive_t *drive)
/* clear INTR & ERROR bits */
ide_dma_sff_write_status(hwif, dma_stat | ATA_DMA_ERR | ATA_DMA_INTR);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
wmb();
/* verify good DMA status */
@@ -346,12 +327,11 @@ EXPORT_SYMBOL_GPL(ide_dma_test_irq);
const struct ide_dma_ops sff_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
EXPORT_SYMBOL_GPL(sff_dma_ops);
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index a878f4734f8..a0b8cab1d9a 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -89,16 +89,21 @@ static const struct drive_list_entry drive_blacklist[] = {
ide_startstop_t ide_dma_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd *cmd = &hwif->cmd;
u8 stat = 0, dma_stat = 0;
+ drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
stat = hwif->tp_ops->read_status(hwif);
if (OK_STAT(stat, DRIVE_READY, drive->bad_wstat | ATA_DRQ)) {
if (!dma_stat) {
- struct request *rq = hwif->rq;
-
- task_end_request(drive, rq, stat);
+ if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+ ide_finish_cmd(drive, cmd, stat);
+ else
+ ide_complete_rq(drive, 0,
+ cmd->rq->nr_sectors << 9);
return ide_stopped;
}
printk(KERN_ERR "%s: %s: bad DMA status (0x%02x)\n",
@@ -106,7 +111,6 @@ ide_startstop_t ide_dma_intr(ide_drive_t *drive)
}
return ide_error(drive, "dma_intr", stat);
}
-EXPORT_SYMBOL_GPL(ide_dma_intr);
int ide_dma_good_drive(ide_drive_t *drive)
{
@@ -114,9 +118,9 @@ int ide_dma_good_drive(ide_drive_t *drive)
}
/**
- * ide_build_sglist - map IDE scatter gather for DMA I/O
- * @drive: the drive to build the DMA table for
- * @rq: the request holding the sg list
+ * ide_dma_map_sg - map IDE scatter gather for DMA I/O
+ * @drive: the drive to map the DMA table for
+ * @cmd: command
*
* Perform the DMA mapping magic necessary to access the source or
* target buffers of a request via DMA. The lower layers of the
@@ -124,31 +128,28 @@ int ide_dma_good_drive(ide_drive_t *drive)
* operate in a portable fashion.
*/
-int ide_build_sglist(ide_drive_t *drive, struct request *rq)
+static int ide_dma_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
int i;
- ide_map_sg(drive, rq);
-
- if (rq_data_dir(rq) == READ)
- hwif->sg_dma_direction = DMA_FROM_DEVICE;
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
+ cmd->sg_dma_direction = DMA_TO_DEVICE;
else
- hwif->sg_dma_direction = DMA_TO_DEVICE;
+ cmd->sg_dma_direction = DMA_FROM_DEVICE;
- i = dma_map_sg(hwif->dev, sg, hwif->sg_nents, hwif->sg_dma_direction);
+ i = dma_map_sg(hwif->dev, sg, cmd->sg_nents, cmd->sg_dma_direction);
if (i) {
- hwif->orig_sg_nents = hwif->sg_nents;
- hwif->sg_nents = i;
+ cmd->orig_sg_nents = cmd->sg_nents;
+ cmd->sg_nents = i;
}
return i;
}
-EXPORT_SYMBOL_GPL(ide_build_sglist);
/**
- * ide_destroy_dmatable - clean up DMA mapping
+ * ide_dma_unmap_sg - clean up DMA mapping
* @drive: The drive to unmap
*
* Teardown mappings after DMA has completed. This must be called
@@ -158,14 +159,14 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
* time.
*/
-void ide_destroy_dmatable(ide_drive_t *drive)
+void ide_dma_unmap_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- dma_unmap_sg(hwif->dev, hwif->sg_table, hwif->orig_sg_nents,
- hwif->sg_dma_direction);
+ dma_unmap_sg(hwif->dev, hwif->sg_table, cmd->orig_sg_nents,
+ cmd->sg_dma_direction);
}
-EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
+EXPORT_SYMBOL_GPL(ide_dma_unmap_sg);
/**
* ide_dma_off_quietly - Generic DMA kill
@@ -244,12 +245,11 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
case XFER_UDMA_0:
if ((id[ATA_ID_FIELD_VALID] & 4) == 0)
break;
-
+ mask = id[ATA_ID_UDMA_MODES];
if (port_ops && port_ops->udma_filter)
- mask = port_ops->udma_filter(drive);
+ mask &= port_ops->udma_filter(drive);
else
- mask = hwif->ultra_mask;
- mask &= id[ATA_ID_UDMA_MODES];
+ mask &= hwif->ultra_mask;
/*
* avoid false cable warning from eighty_ninty_three()
@@ -260,18 +260,23 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
}
break;
case XFER_MW_DMA_0:
- if ((id[ATA_ID_FIELD_VALID] & 2) == 0)
- break;
+ mask = id[ATA_ID_MWDMA_MODES];
+
+ /* Also look for the CF specific MWDMA modes... */
+ if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 0x38)) {
+ u8 mode = ((id[ATA_ID_CFA_MODES] & 0x38) >> 3) - 1;
+
+ mask |= ((2 << mode) - 1) << 3;
+ }
+
if (port_ops && port_ops->mdma_filter)
- mask = port_ops->mdma_filter(drive);
+ mask &= port_ops->mdma_filter(drive);
else
- mask = hwif->mwdma_mask;
- mask &= id[ATA_ID_MWDMA_MODES];
+ mask &= hwif->mwdma_mask;
break;
case XFER_SW_DMA_0:
- if (id[ATA_ID_FIELD_VALID] & 2) {
- mask = id[ATA_ID_SWDMA_MODES] & hwif->swdma_mask;
- } else if (id[ATA_ID_OLD_DMA_MODES] >> 8) {
+ mask = id[ATA_ID_SWDMA_MODES];
+ if (!(mask & ATA_SWDMA2) && (id[ATA_ID_OLD_DMA_MODES] >> 8)) {
u8 mode = id[ATA_ID_OLD_DMA_MODES] >> 8;
/*
@@ -279,8 +284,9 @@ static unsigned int ide_get_mode_mask(ide_drive_t *drive, u8 base, u8 req_mode)
* (the maximum allowed mode is XFER_SW_DMA_2)
*/
if (mode <= 2)
- mask = ((2 << mode) - 1) & hwif->swdma_mask;
+ mask = (2 << mode) - 1;
}
+ mask &= hwif->swdma_mask;
break;
default:
BUG();
@@ -397,11 +403,10 @@ int ide_id_dma_bug(ide_drive_t *drive)
if ((id[ATA_ID_UDMA_MODES] >> 8) &&
(id[ATA_ID_MWDMA_MODES] >> 8))
goto err_out;
- } else if (id[ATA_ID_FIELD_VALID] & 2) {
- if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
- (id[ATA_ID_SWDMA_MODES] >> 8))
- goto err_out;
- }
+ } else if ((id[ATA_ID_MWDMA_MODES] >> 8) &&
+ (id[ATA_ID_SWDMA_MODES] >> 8))
+ goto err_out;
+
return 0;
err_out:
printk(KERN_ERR "%s: bad DMA info in identify block\n", drive->name);
@@ -455,21 +460,6 @@ void ide_dma_lost_irq(ide_drive_t *drive)
}
EXPORT_SYMBOL_GPL(ide_dma_lost_irq);
-void ide_dma_timeout(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
-
- printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
-
- if (hwif->dma_ops->dma_test_irq(drive))
- return;
-
- ide_dump_status(drive, "DMA timeout", hwif->tp_ops->read_status(hwif));
-
- hwif->dma_ops->dma_end(drive);
-}
-EXPORT_SYMBOL_GPL(ide_dma_timeout);
-
/*
* un-busy the port etc, and clear any pending DMA status. we want to
* retry the current request in pio mode instead of risking tossing it
@@ -478,6 +468,8 @@ EXPORT_SYMBOL_GPL(ide_dma_timeout);
ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_dma_ops *dma_ops = hwif->dma_ops;
+ struct ide_cmd *cmd = &hwif->cmd;
struct request *rq;
ide_startstop_t ret = ide_stopped;
@@ -487,12 +479,23 @@ ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
if (error < 0) {
printk(KERN_WARNING "%s: DMA timeout error\n", drive->name);
- (void)hwif->dma_ops->dma_end(drive);
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
ret = ide_error(drive, "dma timeout error",
hwif->tp_ops->read_status(hwif));
} else {
printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name);
- hwif->dma_ops->dma_timeout(drive);
+ if (dma_ops->dma_clear)
+ dma_ops->dma_clear(drive);
+ printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+ if (dma_ops->dma_test_irq(drive) == 0) {
+ ide_dump_status(drive, "DMA timeout",
+ hwif->tp_ops->read_status(hwif));
+ drive->waiting_for_dma = 0;
+ (void)dma_ops->dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
+ }
}
/*
@@ -562,3 +565,25 @@ int ide_allocate_dma_engine(ide_hwif_t *hwif)
return 0;
}
EXPORT_SYMBOL_GPL(ide_allocate_dma_engine);
+
+int ide_dma_prepare(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ const struct ide_dma_ops *dma_ops = drive->hwif->dma_ops;
+
+ if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
+ (dma_ops->dma_check && dma_ops->dma_check(drive, cmd)))
+ goto out;
+ ide_map_sg(drive, cmd);
+ if (ide_dma_map_sg(drive, cmd) == 0)
+ goto out_map;
+ if (dma_ops->dma_setup(drive, cmd))
+ goto out_dma_unmap;
+ drive->waiting_for_dma = 1;
+ return 0;
+out_dma_unmap:
+ ide_dma_unmap_sg(drive, cmd);
+out_map:
+ ide_map_sg(drive, cmd);
+out:
+ return 1;
+}
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c
index 1231b5e486f..5d5fb961b5c 100644
--- a/drivers/ide/ide-eh.c
+++ b/drivers/ide/ide-eh.c
@@ -123,8 +123,18 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
/* retry only "normal" I/O: */
if (!blk_fs_request(rq)) {
- rq->errors = 1;
- ide_end_drive_cmd(drive, stat, err);
+ if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
+ struct ide_cmd *cmd = rq->special;
+
+ if (cmd)
+ ide_complete_cmd(drive, cmd, stat, err);
+ } else if (blk_pm_request(rq)) {
+ rq->errors = 1;
+ ide_complete_pm_rq(drive, rq);
+ return ide_stopped;
+ }
+ rq->errors = err;
+ ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
return ide_stopped;
}
@@ -136,8 +146,11 @@ static inline void ide_complete_drive_reset(ide_drive_t *drive, int err)
{
struct request *rq = drive->hwif->rq;
- if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET)
- ide_end_request(drive, err ? err : 1, 0);
+ if (rq && blk_special_request(rq) && rq->cmd[0] == REQ_DRIVE_RESET) {
+ if (err <= 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, err ? err : 0, ide_rq_bytes(rq));
+ }
}
/* needed below */
@@ -152,18 +165,18 @@ static ide_startstop_t do_reset1(ide_drive_t *, int);
static ide_startstop_t atapi_reset_pollfunc(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
u8 stat;
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
udelay(10);
- stat = hwif->tp_ops->read_status(hwif);
+ stat = tp_ops->read_status(hwif);
if (OK_STAT(stat, 0, ATA_BUSY))
printk(KERN_INFO "%s: ATAPI reset complete\n", drive->name);
else {
if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20,
- NULL);
+ ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
/* continue polling */
return ide_started;
}
@@ -225,7 +238,7 @@ static ide_startstop_t reset_pollfunc(ide_drive_t *drive)
if (!OK_STAT(tmp, 0, ATA_BUSY)) {
if (time_before(jiffies, hwif->poll_timeout)) {
- ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
+ ide_set_handler(drive, &reset_pollfunc, HZ/20);
/* continue polling */
return ide_started;
}
@@ -336,13 +349,13 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
/* For an ATAPI device, first try an ATAPI SRST. */
if (drive->media != ide_disk && !do_not_try_atapi) {
pre_reset(drive);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
udelay(20);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
ndelay(400);
hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
hwif->polling = 1;
- __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL);
+ __ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20);
spin_unlock_irqrestore(&hwif->lock, flags);
return ide_started;
}
@@ -389,20 +402,19 @@ static ide_startstop_t do_reset1(ide_drive_t *drive, int do_not_try_atapi)
* immediate interrupt due to the edge transition it produces.
* This single interrupt gives us a "fast poll" for drives that
* recover from reset very quickly, saving us the first 50ms wait time.
- *
- * TODO: add ->softreset method and stop abusing ->set_irq
*/
/* set SRST and nIEN */
- tp_ops->set_irq(hwif, 4);
+ tp_ops->write_devctl(hwif, ATA_SRST | ATA_NIEN | ATA_DEVCTL_OBS);
/* more than enough time */
udelay(10);
/* clear SRST, leave nIEN (unless device is on the quirk list) */
- tp_ops->set_irq(hwif, drive->quirk_list == 2);
+ tp_ops->write_devctl(hwif, (drive->quirk_list == 2 ? 0 : ATA_NIEN) |
+ ATA_DEVCTL_OBS);
/* more than enough time */
udelay(10);
hwif->poll_timeout = jiffies + WAIT_WORSTCASE;
hwif->polling = 1;
- __ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL);
+ __ide_set_handler(drive, &reset_pollfunc, HZ/20);
/*
* Some weird controller like resetting themselves to a strange
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index 317ec62c33d..2b4868d95f8 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -61,73 +61,20 @@
*/
#define IDEFLOPPY_PC_DELAY (HZ/20) /* default delay for ZIP 100 (50ms) */
-/* Error code returned in rq->errors to the higher part of the driver. */
-#define IDEFLOPPY_ERROR_GENERAL 101
-
-/*
- * Used to finish servicing a request. For read/write requests, we will call
- * ide_end_request to pass to the next buffer.
- */
-static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
-{
- struct ide_disk_obj *floppy = drive->driver_data;
- struct request *rq = drive->hwif->rq;
- int error;
-
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
-
- switch (uptodate) {
- case 0:
- error = IDEFLOPPY_ERROR_GENERAL;
- break;
-
- case 1:
- error = 0;
- break;
-
- default:
- error = uptodate;
- }
-
- if (error)
- floppy->failed_pc = NULL;
- /* Why does this happen? */
- if (!rq)
- return 0;
- if (!blk_special_request(rq)) {
- /* our real local end request function */
- ide_end_request(drive, uptodate, nsecs);
- return 0;
- }
- rq->errors = error;
- /* fixme: need to move this local also */
- ide_end_drive_cmd(drive, 0, 0);
- return 0;
-}
-
-static void idefloppy_update_buffers(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
-{
- struct request *rq = pc->rq;
- struct bio *bio = rq->bio;
-
- while ((bio = rq->bio) != NULL)
- ide_floppy_end_request(drive, 1, 0);
-}
-
-static void ide_floppy_callback(ide_drive_t *drive, int dsc)
+static int ide_floppy_callback(ide_drive_t *drive, int dsc)
{
struct ide_disk_obj *floppy = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
+ struct request *rq = pc->rq;
int uptodate = pc->error ? 0 : 1;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
- if (floppy->failed_pc == pc)
- floppy->failed_pc = NULL;
+ if (drive->failed_pc == pc)
+ drive->failed_pc = NULL;
if (pc->c[0] == GPCMD_READ_10 || pc->c[0] == GPCMD_WRITE_10 ||
- (pc->rq && blk_pc_request(pc->rq)))
+ (rq && blk_pc_request(rq)))
uptodate = 1; /* FIXME */
else if (pc->c[0] == GPCMD_REQUEST_SENSE) {
u8 *buf = pc->buf;
@@ -139,19 +86,22 @@ static void ide_floppy_callback(ide_drive_t *drive, int dsc)
floppy->progress_indication = buf[15] & 0x80 ?
(u16)get_unaligned((u16 *)&buf[16]) : 0x10000;
- if (floppy->failed_pc)
- ide_debug_log(IDE_DBG_PC, "pc = %x, ",
- floppy->failed_pc->c[0]);
+ if (drive->failed_pc)
+ ide_debug_log(IDE_DBG_PC, "pc = %x",
+ drive->failed_pc->c[0]);
ide_debug_log(IDE_DBG_SENSE, "sense key = %x, asc = %x,"
- "ascq = %x\n", floppy->sense_key,
+ "ascq = %x", floppy->sense_key,
floppy->asc, floppy->ascq);
} else
printk(KERN_ERR PFX "Error in REQUEST SENSE itself - "
"Aborting request!\n");
}
- ide_floppy_end_request(drive, uptodate, 0);
+ if (blk_special_request(rq))
+ rq->errors = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
+
+ return uptodate;
}
static void ide_floppy_report_error(struct ide_disk_obj *floppy,
@@ -170,14 +120,15 @@ static void ide_floppy_report_error(struct ide_disk_obj *floppy,
}
-static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
+static ide_startstop_t ide_floppy_issue_pc(ide_drive_t *drive,
+ struct ide_cmd *cmd,
+ struct ide_atapi_pc *pc)
{
struct ide_disk_obj *floppy = drive->driver_data;
- if (floppy->failed_pc == NULL &&
+ if (drive->failed_pc == NULL &&
pc->c[0] != GPCMD_REQUEST_SENSE)
- floppy->failed_pc = pc;
+ drive->failed_pc = pc;
/* Set the current packet command */
drive->pc = pc;
@@ -186,18 +137,18 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
if (!(pc->flags & PC_FLAG_SUPPRESS_ERROR))
ide_floppy_report_error(floppy, pc);
/* Giving up */
- pc->error = IDEFLOPPY_ERROR_GENERAL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
- floppy->failed_pc = NULL;
+ drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
return ide_stopped;
}
- ide_debug_log(IDE_DBG_FUNC, "%s: Retry #%d\n", __func__, pc->retries);
+ ide_debug_log(IDE_DBG_FUNC, "retry #%d", pc->retries);
pc->retries++;
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, cmd);
}
void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
@@ -242,8 +193,7 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
int blocks = rq->nr_sectors / floppy->bs_factor;
int cmd = rq_data_dir(rq);
- ide_debug_log(IDE_DBG_FUNC, "%s: block: %d, blocks: %d\n", __func__,
- block, blocks);
+ ide_debug_log(IDE_DBG_FUNC, "block: %d, blocks: %d", block, blocks);
ide_init_pc(pc);
pc->c[0] = cmd == READ ? GPCMD_READ_10 : GPCMD_WRITE_10;
@@ -253,7 +203,6 @@ static void idefloppy_create_rw_cmd(ide_drive_t *drive,
memcpy(rq->cmd, pc->c, 12);
pc->rq = rq;
- pc->b_count = 0;
if (rq->cmd_flags & REQ_RW)
pc->flags |= PC_FLAG_WRITING;
pc->buf = NULL;
@@ -267,7 +216,6 @@ static void idefloppy_blockpc_cmd(struct ide_disk_obj *floppy,
ide_init_pc(pc);
memcpy(pc->c, rq->cmd, sizeof(pc->c));
pc->rq = rq;
- pc->b_count = 0;
if (rq->data_len && rq_data_dir(rq) == WRITE)
pc->flags |= PC_FLAG_WRITING;
pc->buf = rq->data;
@@ -284,35 +232,36 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
struct request *rq, sector_t block)
{
struct ide_disk_obj *floppy = drive->driver_data;
- ide_hwif_t *hwif = drive->hwif;
+ struct ide_cmd cmd;
struct ide_atapi_pc *pc;
- ide_debug_log(IDE_DBG_FUNC, "%s: dev: %s, cmd: 0x%x, cmd_type: %x, "
- "errors: %d\n",
- __func__, rq->rq_disk ? rq->rq_disk->disk_name : "?",
- rq->cmd[0], rq->cmd_type, rq->errors);
+ ide_debug_log(IDE_DBG_FUNC, "enter, cmd: 0x%x\n", rq->cmd[0]);
- ide_debug_log(IDE_DBG_FUNC, "%s: sector: %ld, nr_sectors: %ld, "
- "current_nr_sectors: %d\n",
- __func__, (long)rq->sector, rq->nr_sectors,
- rq->current_nr_sectors);
+ if (drive->debug_mask & IDE_DBG_RQ)
+ blk_dump_rq_flags(rq, (rq->rq_disk
+ ? rq->rq_disk->disk_name
+ : "dev?"));
if (rq->errors >= ERROR_MAX) {
- if (floppy->failed_pc)
- ide_floppy_report_error(floppy, floppy->failed_pc);
- else
+ if (drive->failed_pc) {
+ ide_floppy_report_error(floppy, drive->failed_pc);
+ drive->failed_pc = NULL;
+ } else
printk(KERN_ERR PFX "%s: I/O error\n", drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ if (blk_special_request(rq)) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+ return ide_stopped;
+ } else
+ goto out_end;
}
if (blk_fs_request(rq)) {
if (((long)rq->sector % floppy->bs_factor) ||
(rq->nr_sectors % floppy->bs_factor)) {
printk(KERN_ERR PFX "%s: unsupported r/w rq size\n",
drive->name);
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
pc = &floppy->queued_pc;
idefloppy_create_rw_cmd(drive, pc, rq, (unsigned long)block);
@@ -323,21 +272,30 @@ static ide_startstop_t ide_floppy_do_request(ide_drive_t *drive,
idefloppy_blockpc_cmd(floppy, pc, rq);
} else {
blk_dump_rq_flags(rq, PFX "unsupported command in queue");
- ide_floppy_end_request(drive, 0, 0);
- return ide_stopped;
+ goto out_end;
}
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
if (blk_fs_request(rq) || pc->req_xfer) {
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
+ ide_init_sg_cmd(&cmd, pc->req_xfer);
+ ide_map_sg(drive, &cmd);
}
- pc->sg = hwif->sg_table;
- pc->sg_cnt = hwif->sg_nents;
-
pc->rq = rq;
- return idefloppy_issue_pc(drive, pc);
+ return ide_floppy_issue_pc(drive, &cmd, pc);
+out_end:
+ drive->failed_pc = NULL;
+ if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
+ return ide_stopped;
}
/*
@@ -413,9 +371,11 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
struct gendisk *disk = floppy->disk;
struct ide_atapi_pc pc;
u8 *cap_desc;
- u8 header_len, desc_cnt;
+ u8 pc_buf[256], header_len, desc_cnt;
int i, rc = 1, blocks, length;
+ ide_debug_log(IDE_DBG_FUNC, "enter");
+
drive->bios_cyl = 0;
drive->bios_head = drive->bios_sect = 0;
floppy->blocks = 0;
@@ -423,6 +383,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
drive->capacity64 = 0;
ide_floppy_create_read_capacity_cmd(&pc);
+ pc.buf = &pc_buf[0];
+ pc.buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, disk, &pc)) {
printk(KERN_ERR PFX "Can't get floppy parameters\n");
return 1;
@@ -438,8 +401,9 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
length = be16_to_cpup((__be16 *)&pc.buf[desc_start + 6]);
ide_debug_log(IDE_DBG_PROBE, "Descriptor %d: %dkB, %d blocks, "
- "%d sector size\n",
- i, blocks * length / 1024, blocks, length);
+ "%d sector size",
+ i, blocks * length / 1024,
+ blocks, length);
if (i)
continue;
@@ -495,8 +459,8 @@ static int ide_floppy_get_capacity(ide_drive_t *drive)
"in drive\n", drive->name);
break;
}
- ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d\n",
- pc.buf[desc_start + 4] & 0x03);
+ ide_debug_log(IDE_DBG_PROBE, "Descriptor 0 Code: %d",
+ pc.buf[desc_start + 4] & 0x03);
}
/* Clik! disk does not support get_flexible_disk_page */
@@ -512,8 +476,6 @@ static void ide_floppy_setup(ide_drive_t *drive)
u16 *id = drive->id;
drive->pc_callback = ide_floppy_callback;
- drive->pc_update_buffers = idefloppy_update_buffers;
- drive->pc_io_buffers = ide_io_buffers;
/*
* We used to check revisions here. At this point however I'm giving up.
@@ -575,6 +537,5 @@ const struct ide_disk_ops ide_atapi_disk_ops = {
.init_media = ide_floppy_init_media,
.set_doorlock = ide_set_media_lock,
.do_request = ide_floppy_do_request,
- .end_request = ide_floppy_end_request,
.ioctl = ide_floppy_ioctl,
};
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index 8f8be854603..cd8a42027ed 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -36,9 +36,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
int __user *arg)
{
struct ide_disk_obj *floppy = drive->driver_data;
- u8 header_len, desc_cnt;
int i, blocks, length, u_array_size, u_index;
int __user *argp;
+ u8 pc_buf[256], header_len, desc_cnt;
if (get_user(u_array_size, arg))
return -EFAULT;
@@ -47,6 +47,9 @@ static int ide_floppy_get_format_capacities(ide_drive_t *drive,
return -EINVAL;
ide_floppy_create_read_capacity_cmd(pc);
+ pc->buf = &pc_buf[0];
+ pc->buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, floppy->disk, pc)) {
printk(KERN_ERR "ide-floppy: Can't get floppy parameters\n");
return -EIO;
diff --git a/drivers/ide/ide-gd.c b/drivers/ide/ide-gd.c
index 04710941990..1aebdf1a4f5 100644
--- a/drivers/ide/ide-gd.c
+++ b/drivers/ide/ide-gd.c
@@ -145,11 +145,6 @@ static ide_startstop_t ide_gd_do_request(ide_drive_t *drive,
return drive->disk_ops->do_request(drive, rq, sector);
}
-static int ide_gd_end_request(ide_drive_t *drive, int uptodate, int nrsecs)
-{
- return drive->disk_ops->end_request(drive, uptodate, nrsecs);
-}
-
static struct ide_driver ide_gd_driver = {
.gen_driver = {
.owner = THIS_MODULE,
@@ -162,7 +157,6 @@ static struct ide_driver ide_gd_driver = {
.shutdown = ide_gd_shutdown,
.version = IDE_GD_VERSION,
.do_request = ide_gd_do_request,
- .end_request = ide_gd_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_disk_proc_entries,
.proc_devsets = ide_disk_proc_devsets,
@@ -182,7 +176,7 @@ static int ide_gd_open(struct block_device *bdev, fmode_t mode)
drive = idkp->drive;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
idkp->openers++;
@@ -232,7 +226,7 @@ static int ide_gd_release(struct gendisk *disk, fmode_t mode)
struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
ide_drive_t *drive = idkp->drive;
- ide_debug_log(IDE_DBG_FUNC, "Call %s\n", __func__);
+ ide_debug_log(IDE_DBG_FUNC, "enter");
if (idkp->openers == 1)
drive->disk_ops->flush(drive);
diff --git a/drivers/ide/ide-gd.h b/drivers/ide/ide-gd.h
index b604bdd318a..55970772bd0 100644
--- a/drivers/ide/ide-gd.h
+++ b/drivers/ide/ide-gd.h
@@ -8,7 +8,7 @@
#define IDE_GD_DEBUG_LOG 0
#if IDE_GD_DEBUG_LOG
-#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, args)
+#define ide_debug_log(lvl, fmt, args...) __ide_debug_log(lvl, fmt, ## args)
#else
#define ide_debug_log(lvl, fmt, args...) do {} while (0)
#endif
@@ -20,8 +20,6 @@ struct ide_disk_obj {
struct device dev;
unsigned int openers; /* protected by BKL for now */
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
/* used for blk_{fs,pc}_request() requests */
struct ide_atapi_pc queued_pc;
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c
index 81a5282ce1e..7812ca0be13 100644
--- a/drivers/ide/ide-generic.c
+++ b/drivers/ide/ide-generic.c
@@ -1,27 +1,22 @@
/*
* generic/default IDE host driver
*
- * Copyright (C) 2004, 2008 Bartlomiej Zolnierkiewicz
+ * Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz
* This code was split off from ide.c. See it for original copyrights.
*
* May be copied or modified under the terms of the GNU General Public License.
*/
-/*
- * For special cases new interfaces may be added using sysfs, i.e.
- *
- * echo -n "0x168:0x36e:10" > /sys/class/ide_generic/add
- *
- * will add an interface using I/O ports 0x168-0x16f/0x36e and IRQ 10.
- */
-
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#include <linux/pci_ids.h>
-/* FIXME: convert m32r to use ide_platform host driver */
+/* FIXME: convert arm and m32r to use ide_platform host driver */
+#ifdef CONFIG_ARM
+#include <asm/irq.h>
+#endif
#ifdef CONFIG_M32R
#include <asm/m32r.h>
#endif
@@ -32,62 +27,15 @@ static int probe_mask;
module_param(probe_mask, int, 0);
MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
-static ssize_t store_add(struct class *cls, const char *buf, size_t n)
-{
- unsigned int base, ctl;
- int irq, rc;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (sscanf(buf, "%x:%x:%d", &base, &ctl, &irq) != 3)
- return -EINVAL;
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = irq;
- hw.chipset = ide_generic;
-
- rc = ide_host_add(NULL, hws, NULL);
- if (rc)
- return rc;
-
- return n;
-};
-
-static struct class_attribute ide_generic_class_attrs[] = {
- __ATTR(add, S_IWUSR, NULL, store_add),
- __ATTR_NULL
+static const struct ide_port_info ide_generic_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
};
-static void ide_generic_class_release(struct class *cls)
-{
- kfree(cls);
-}
-
-static int __init ide_generic_sysfs_init(void)
-{
- struct class *cls;
- int rc;
-
- cls = kzalloc(sizeof(*cls), GFP_KERNEL);
- if (!cls)
- return -ENOMEM;
-
- cls->name = DRV_NAME;
- cls->owner = THIS_MODULE;
- cls->class_release = ide_generic_class_release;
- cls->class_attrs = ide_generic_class_attrs;
-
- rc = class_register(cls);
- if (rc) {
- kfree(cls);
- return rc;
- }
-
- return 0;
-}
-
-#if defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) \
- || defined(CONFIG_PLAT_OPSPUT)
+#ifdef CONFIG_ARM
+static const u16 legacy_bases[] = { 0x1f0 };
+static const int legacy_irqs[] = { IRQ_HARDDISK };
+#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
+ defined(CONFIG_PLAT_OPSPUT)
static const u16 legacy_bases[] = { 0x1f0 };
static const int legacy_irqs[] = { PLD_IRQ_CFIREQ };
#elif defined(CONFIG_PLAT_MAPPI3)
@@ -103,11 +51,11 @@ static const int legacy_irqs[] = { 14, 15, 11, 10, 8, 12 };
static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
{
+#ifdef CONFIG_PCI
struct pci_dev *p = NULL;
u16 val;
for_each_pci_dev(p) {
-
if (pci_resource_start(p, 0) == 0x1f0)
*primary = 1;
if (pci_resource_start(p, 2) == 0x170)
@@ -122,7 +70,6 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
/* Intel MPIIX - PIO ATA on non PCI side of bridge */
if (p->vendor == PCI_VENDOR_ID_INTEL &&
p->device == PCI_DEVICE_ID_INTEL_82371MX) {
-
pci_read_config_word(p, 0x6C, &val);
if (val & 0x8000) {
/* ATA port enabled */
@@ -133,6 +80,7 @@ static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
}
}
}
+#endif
}
static int __init ide_generic_init(void)
@@ -164,6 +112,7 @@ static int __init ide_generic_init(void)
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
"not free.\n",
DRV_NAME, io_addr, io_addr + 7);
+ rc = -EBUSY;
continue;
}
@@ -172,6 +121,7 @@ static int __init ide_generic_init(void)
"not free.\n",
DRV_NAME, io_addr + 0x206);
release_region(io_addr, 8);
+ rc = -EBUSY;
continue;
}
@@ -184,7 +134,7 @@ static int __init ide_generic_init(void)
#endif
hw.chipset = ide_generic;
- rc = ide_host_add(NULL, hws, NULL);
+ rc = ide_host_add(&ide_generic_port_info, hws, NULL);
if (rc) {
release_region(io_addr + 0x206, 1);
release_region(io_addr, 8);
@@ -192,10 +142,6 @@ static int __init ide_generic_init(void)
}
}
- if (ide_generic_sysfs_init())
- printk(KERN_ERR DRV_NAME ": failed to create ide_generic "
- "class\n");
-
return rc;
}
diff --git a/drivers/ide/ide-h8300.c b/drivers/ide/ide-h8300.c
index 9270d3255ee..dac9a6d4496 100644
--- a/drivers/ide/ide-h8300.c
+++ b/drivers/ide/ide-h8300.c
@@ -44,88 +44,78 @@ static u16 mm_inw(unsigned long a)
return r;
}
-static void h8300_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void h8300_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA)
- mm_outw((tf->hob_data << 8) | tf->data, io_ports->data_addr);
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void h8300_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void h8300_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data = mm_inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
@@ -143,13 +133,13 @@ static void mm_insw(unsigned long addr, void *buf, u32 len)
*bp = bswap(*(volatile u16 *)addr);
}
-static void h8300_input_data(ide_drive_t *drive, struct request *rq,
+static void h8300_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
mm_insw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
}
-static void h8300_output_data(ide_drive_t *drive, struct request *rq,
+static void h8300_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
mm_outsw(drive->hwif->io_ports.data_addr, buf, (len + 1) / 2);
@@ -159,9 +149,9 @@ static const struct ide_tp_ops h8300_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = h8300_tf_load,
.tf_read = h8300_tf_read,
diff --git a/drivers/ide/ide-io-std.c b/drivers/ide/ide-io-std.c
index 45b43dd49cd..9cac281d82c 100644
--- a/drivers/ide/ide-io-std.c
+++ b/drivers/ide/ide-io-std.c
@@ -2,6 +2,13 @@
#include <linux/kernel.h>
#include <linux/ide.h>
+#if defined(CONFIG_ARM) || defined(CONFIG_M68K) || defined(CONFIG_MIPS) || \
+ defined(CONFIG_PARISC) || defined(CONFIG_PPC) || defined(CONFIG_SPARC)
+#include <asm/ide.h>
+#else
+#include <asm-generic/ide_iops.h>
+#endif
+
/*
* Conventional PIO operations for ATA devices
*/
@@ -57,83 +64,77 @@ u8 ide_read_altstatus(ide_hwif_t *hwif)
}
EXPORT_SYMBOL_GPL(ide_read_altstatus);
-void ide_set_irq(ide_hwif_t *hwif, int on)
+void ide_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
if (hwif->host_flags & IDE_HFLAG_MMIO)
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
else
outb(ctl, hwif->io_ports.ctl_addr);
}
-EXPORT_SYMBOL_GPL(ide_set_irq);
+EXPORT_SYMBOL_GPL(ide_write_devctl);
-void ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+void ide_dev_select(ide_drive_t *drive)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ u8 select = drive->select | ATA_DEVICE_OBS;
+
+ if (hwif->host_flags & IDE_HFLAG_MMIO)
+ writeb(select, (void __iomem *)hwif->io_ports.device_addr);
+ else
+ outb(select, hwif->io_ports.device_addr);
+}
+EXPORT_SYMBOL_GPL(ide_dev_select);
+
+void ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_taskfile *tf = &cmd->tf;
void (*tf_outb)(u8 addr, unsigned long port);
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
if (mmio)
tf_outb = ide_mm_outb;
else
tf_outb = ide_outb;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- if (mmio)
- writew(data, (void __iomem *)io_ports->data_addr);
- else
- outw(data, io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tf_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
tf_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
tf_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
tf_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
tf_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
tf_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
tf_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
tf_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
tf_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
tf_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
tf_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
EXPORT_SYMBOL_GPL(ide_tf_load);
-void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+void ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_taskfile *tf = &cmd->tf;
void (*tf_outb)(u8 addr, unsigned long port);
u8 (*tf_inb)(unsigned long port);
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
@@ -146,47 +147,35 @@ void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
tf_inb = ide_inb;
}
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- if (mmio)
- data = readw((void __iomem *)io_ports->data_addr);
- else
- data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
-
/* be sure we're looking at the low order bits */
- tf_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tf_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = tf_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = tf_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tf_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = tf_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tf_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tf_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tf_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tf_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tf_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tf_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tf_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tf_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tf_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tf_inb(io_ports->lbah_addr);
}
}
EXPORT_SYMBOL_GPL(ide_tf_read);
@@ -212,17 +201,16 @@ static void ata_vlb_sync(unsigned long port)
* so if an odd len is specified, be sure that there's at least one
* extra byte allocated for the buffer.
*/
-void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
+void ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long data_addr = io_ports->data_addr;
+ unsigned int words = (len + 1) >> 1;
u8 io_32bit = drive->io_32bit;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- len++;
-
if (io_32bit) {
unsigned long uninitialized_var(flags);
@@ -231,44 +219,42 @@ void ide_input_data(ide_drive_t *drive, struct request *rq, void *buf,
ata_vlb_sync(io_ports->nsect_addr);
}
+ words >>= 1;
if (mmio)
- __ide_mm_insl((void __iomem *)data_addr, buf, len / 4);
+ __ide_mm_insl((void __iomem *)data_addr, buf, words);
else
- insl(data_addr, buf, len / 4);
+ insl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
local_irq_restore(flags);
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- insw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_insw((void __iomem *)data_addr, buf, len / 2);
- else
- insw(data_addr, buf, len / 2);
+ if (((len + 1) & 3) < 2)
+ return;
+
+ buf += len & ~3;
+ words = 1;
}
+
+ if (mmio)
+ __ide_mm_insw((void __iomem *)data_addr, buf, words);
+ else
+ insw(data_addr, buf, words);
}
EXPORT_SYMBOL_GPL(ide_input_data);
/*
* This is used for most PIO data transfers *to* the IDE interface
*/
-void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
+void ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, void *buf,
unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
unsigned long data_addr = io_ports->data_addr;
+ unsigned int words = (len + 1) >> 1;
u8 io_32bit = drive->io_32bit;
u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0;
- len++;
-
if (io_32bit) {
unsigned long uninitialized_var(flags);
@@ -277,27 +263,26 @@ void ide_output_data(ide_drive_t *drive, struct request *rq, void *buf,
ata_vlb_sync(io_ports->nsect_addr);
}
+ words >>= 1;
if (mmio)
- __ide_mm_outsl((void __iomem *)data_addr, buf, len / 4);
+ __ide_mm_outsl((void __iomem *)data_addr, buf, words);
else
- outsl(data_addr, buf, len / 4);
+ outsl(data_addr, buf, words);
if ((io_32bit & 2) && !mmio)
local_irq_restore(flags);
- if ((len & 3) >= 2) {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr,
- (u8 *)buf + (len & ~3), 1);
- else
- outsw(data_addr, (u8 *)buf + (len & ~3), 1);
- }
- } else {
- if (mmio)
- __ide_mm_outsw((void __iomem *)data_addr, buf, len / 2);
- else
- outsw(data_addr, buf, len / 2);
+ if (((len + 1) & 3) < 2)
+ return;
+
+ buf += len & ~3;
+ words = 1;
}
+
+ if (mmio)
+ __ide_mm_outsw((void __iomem *)data_addr, buf, words);
+ else
+ outsw(data_addr, buf, words);
}
EXPORT_SYMBOL_GPL(ide_output_data);
@@ -305,9 +290,9 @@ const struct ide_tp_ops default_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 2e92497b58a..1deb6d29b18 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -40,7 +40,6 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include <linux/completion.h>
#include <linux/reboot.h>
#include <linux/cdrom.h>
@@ -55,25 +54,9 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-static int __ide_end_request(ide_drive_t *drive, struct request *rq,
- int uptodate, unsigned int nr_bytes, int dequeue)
+int ide_end_rq(ide_drive_t *drive, struct request *rq, int error,
+ unsigned int nr_bytes)
{
- int ret = 1;
- int error = 0;
-
- if (uptodate <= 0)
- error = uptodate ? uptodate : -EIO;
-
- /*
- * if failfast is set on a request, override number of sectors and
- * complete the whole request right now
- */
- if (blk_noretry_request(rq) && error)
- nr_bytes = rq->hard_nr_sectors << 9;
-
- if (!blk_fs_request(rq) && error && !rq->errors)
- rq->errors = -EIO;
-
/*
* decide whether to reenable DMA -- 3 is a random magic for now,
* if we DMA timeout more than 3 times, just stay in PIO
@@ -84,127 +67,96 @@ static int __ide_end_request(ide_drive_t *drive, struct request *rq,
ide_dma_on(drive);
}
- if (!blk_end_request(rq, error, nr_bytes))
- ret = 0;
+ return blk_end_request(rq, error, nr_bytes);
+}
+EXPORT_SYMBOL_GPL(ide_end_rq);
- if (ret == 0 && dequeue)
- drive->hwif->rq = NULL;
+void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
+{
+ const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops;
+ struct ide_taskfile *tf = &cmd->tf;
+ struct request *rq = cmd->rq;
+ u8 tf_cmd = tf->command;
- return ret;
-}
+ tf->error = err;
+ tf->status = stat;
-/**
- * ide_end_request - complete an IDE I/O
- * @drive: IDE device for the I/O
- * @uptodate:
- * @nr_sectors: number of sectors completed
- *
- * This is our end_request wrapper function. We complete the I/O
- * update random number input and dequeue the request, which if
- * it was tagged may be out of order.
- */
+ if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
+ u8 data[2];
-int ide_end_request (ide_drive_t *drive, int uptodate, int nr_sectors)
-{
- unsigned int nr_bytes = nr_sectors << 9;
- struct request *rq = drive->hwif->rq;
+ tp_ops->input_data(drive, cmd, data, 2);
- if (!nr_bytes) {
- if (blk_pc_request(rq))
- nr_bytes = rq->data_len;
- else
- nr_bytes = rq->hard_cur_sectors << 9;
+ tf->data = data[0];
+ tf->hob_data = data[1];
}
- return __ide_end_request(drive, rq, uptodate, nr_bytes, 1);
-}
-EXPORT_SYMBOL(ide_end_request);
+ tp_ops->tf_read(drive, cmd);
-/**
- * ide_end_dequeued_request - complete an IDE I/O
- * @drive: IDE device for the I/O
- * @uptodate:
- * @nr_sectors: number of sectors completed
- *
- * Complete an I/O that is no longer on the request queue. This
- * typically occurs when we pull the request and issue a REQUEST_SENSE.
- * We must still finish the old request but we must not tamper with the
- * queue in the meantime.
- *
- * NOTE: This path does not handle barrier, but barrier is not supported
- * on ide-cd anyway.
- */
+ if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
+ tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
+ if (tf->lbal != 0xc4) {
+ printk(KERN_ERR "%s: head unload failed!\n",
+ drive->name);
+ ide_tf_dump(drive->name, tf);
+ } else
+ drive->dev_flags |= IDE_DFLAG_PARKED;
+ }
-int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
- int uptodate, int nr_sectors)
-{
- BUG_ON(!blk_rq_started(rq));
+ if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
+ memcpy(rq->special, cmd, sizeof(*cmd));
- return __ide_end_request(drive, rq, uptodate, nr_sectors << 9, 0);
+ if (cmd->tf_flags & IDE_TFLAG_DYN)
+ kfree(cmd);
}
-EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
-/**
- * ide_end_drive_cmd - end an explicit drive command
- * @drive: command
- * @stat: status bits
- * @err: error bits
- *
- * Clean up after success/failure of an explicit drive command.
- * These get thrown onto the queue so they are synchronized with
- * real I/O operations on the drive.
- *
- * In LBA48 mode we have to read the register set twice to get
- * all the extra information out.
- */
-
-void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
+/* obsolete, blk_rq_bytes() should be used instead */
+unsigned int ide_rq_bytes(struct request *rq)
+{
+ if (blk_pc_request(rq))
+ return rq->data_len;
+ else
+ return rq->hard_cur_sectors << 9;
+}
+EXPORT_SYMBOL_GPL(ide_rq_bytes);
+
+int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
{
ide_hwif_t *hwif = drive->hwif;
struct request *rq = hwif->rq;
+ int rc;
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- ide_task_t *task = (ide_task_t *)rq->special;
-
- if (task) {
- struct ide_taskfile *tf = &task->tf;
-
- tf->error = err;
- tf->status = stat;
-
- drive->hwif->tp_ops->tf_read(drive, task);
-
- if (task->tf_flags & IDE_TFLAG_DYN)
- kfree(task);
- }
- } else if (blk_pm_request(rq)) {
- struct request_pm_state *pm = rq->data;
-
- ide_complete_power_step(drive, rq);
- if (pm->pm_step == IDE_PM_COMPLETED)
- ide_complete_pm_request(drive, rq);
- return;
- }
-
- hwif->rq = NULL;
+ /*
+ * if failfast is set on a request, override number of sectors
+ * and complete the whole request right now
+ */
+ if (blk_noretry_request(rq) && error <= 0)
+ nr_bytes = rq->hard_nr_sectors << 9;
- rq->errors = err;
+ rc = ide_end_rq(drive, rq, error, nr_bytes);
+ if (rc == 0)
+ hwif->rq = NULL;
- if (unlikely(blk_end_request(rq, (rq->errors ? -EIO : 0),
- blk_rq_bytes(rq))))
- BUG();
+ return rc;
}
-EXPORT_SYMBOL(ide_end_drive_cmd);
+EXPORT_SYMBOL(ide_complete_rq);
void ide_kill_rq(ide_drive_t *drive, struct request *rq)
{
- if (rq->rq_disk) {
- struct ide_driver *drv;
+ u8 drv_req = blk_special_request(rq) && rq->rq_disk;
+ u8 media = drive->media;
- drv = *(struct ide_driver **)rq->rq_disk->private_data;
- drv->end_request(drive, 0, 0);
- } else
- ide_end_request(drive, 0, 0);
+ drive->failed_pc = NULL;
+
+ if ((media == ide_floppy || media == ide_tape) && drv_req) {
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
+ } else {
+ if (media == ide_tape)
+ rq->errors = IDE_DRV_ERROR_GENERAL;
+ else if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
+ }
}
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
@@ -232,20 +184,20 @@ static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
static ide_startstop_t ide_disk_special(ide_drive_t *drive)
{
special_t *s = &drive->special;
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
- args.data_phase = TASKFILE_NO_DATA;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.protocol = ATA_PROT_NODATA;
if (s->b.set_geometry) {
s->b.set_geometry = 0;
- ide_tf_set_specify_cmd(drive, &args.tf);
+ ide_tf_set_specify_cmd(drive, &cmd.tf);
} else if (s->b.recalibrate) {
s->b.recalibrate = 0;
- ide_tf_set_restore_cmd(drive, &args.tf);
+ ide_tf_set_restore_cmd(drive, &cmd.tf);
} else if (s->b.set_multmode) {
s->b.set_multmode = 0;
- ide_tf_set_setmult_cmd(drive, &args.tf);
+ ide_tf_set_setmult_cmd(drive, &cmd.tf);
} else if (s->all) {
int special = s->all;
s->all = 0;
@@ -253,10 +205,10 @@ static ide_startstop_t ide_disk_special(ide_drive_t *drive)
return ide_stopped;
}
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
- IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE |
+ IDE_TFLAG_CUSTOM_HANDLER;
- do_rw_taskfile(drive, &args);
+ do_rw_taskfile(drive, &cmd);
return ide_started;
}
@@ -286,33 +238,29 @@ static ide_startstop_t do_special (ide_drive_t *drive)
return ide_stopped;
}
-void ide_map_sg(ide_drive_t *drive, struct request *rq)
+void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
+ struct request *rq = cmd->rq;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
- hwif->sg_nents = 1;
+ cmd->sg_nents = 1;
} else if (!rq->bio) {
sg_init_one(sg, rq->data, rq->data_len);
- hwif->sg_nents = 1;
- } else {
- hwif->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
- }
+ cmd->sg_nents = 1;
+ } else
+ cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
}
-
EXPORT_SYMBOL_GPL(ide_map_sg);
-void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
+void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes)
{
- ide_hwif_t *hwif = drive->hwif;
-
- hwif->nsect = hwif->nleft = rq->nr_sectors;
- hwif->cursg_ofs = 0;
- hwif->cursg = NULL;
+ cmd->nbytes = cmd->nleft = nr_bytes;
+ cmd->cursg_ofs = 0;
+ cmd->cursg = NULL;
}
-
EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
/**
@@ -330,24 +278,15 @@ EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
struct request *rq)
{
- ide_hwif_t *hwif = drive->hwif;
- ide_task_t *task = rq->special;
-
- if (task) {
- hwif->data_phase = task->data_phase;
-
- switch (hwif->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- ide_init_sg_cmd(drive, rq);
- ide_map_sg(drive, rq);
- default:
- break;
+ struct ide_cmd *cmd = rq->special;
+
+ if (cmd) {
+ if (cmd->protocol == ATA_PROT_PIO) {
+ ide_init_sg_cmd(cmd, rq->nr_sectors << 9);
+ ide_map_sg(drive, cmd);
}
- return do_rw_taskfile(drive, task);
+ return do_rw_taskfile(drive, cmd);
}
/*
@@ -357,8 +296,8 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
#ifdef DEBUG
printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
- ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif),
- ide_read_error(drive));
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
}
@@ -376,9 +315,7 @@ static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
case REQ_DRIVE_RESET:
return ide_do_reset(drive);
default:
- blk_dump_rq_flags(rq, "ide_special_rq - bad request");
- ide_end_request(drive, 0, 0);
- return ide_stopped;
+ BUG();
}
}
@@ -411,7 +348,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
if (blk_pm_request(rq))
ide_check_pm_state(drive, rq);
- SELECT_DRIVE(drive);
+ drive->hwif->tp_ops->dev_select(drive);
if (ide_wait_stat(&startstop, drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ, WAIT_READY)) {
printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
@@ -438,7 +375,7 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
startstop = ide_start_power_step(drive, rq);
if (startstop == ide_stopped &&
pm->pm_step == IDE_PM_COMPLETED)
- ide_complete_pm_request(drive, rq);
+ ide_complete_pm_rq(drive, rq);
return startstop;
} else if (!rq->rq_disk && blk_special_request(rq))
/*
@@ -501,8 +438,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
if (rc == 0) {
- /* for atari only */
- ide_get_lock(ide_intr, hwif);
+ if (host->get_lock)
+ host->get_lock(ide_intr, hwif);
}
}
return rc;
@@ -511,8 +448,8 @@ static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
static inline void ide_unlock_host(struct ide_host *host)
{
if (host->host_flags & IDE_HFLAG_SERIALIZE) {
- /* for atari only */
- ide_release_lock();
+ if (host->release_lock)
+ host->release_lock();
clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
}
}
@@ -554,11 +491,10 @@ repeat:
prev_port = hwif->host->cur_port;
hwif->rq = NULL;
- if (drive->dev_flags & IDE_DFLAG_SLEEPING) {
- if (time_before(drive->sleep, jiffies)) {
- ide_unlock_port(hwif);
- goto plug_device;
- }
+ if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
+ time_after(drive->sleep, jiffies)) {
+ ide_unlock_port(hwif);
+ goto plug_device;
}
if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
@@ -568,7 +504,9 @@ repeat:
* quirk_list may not like intr setups/cleanups
*/
if (prev_port && prev_port->cur_dev->quirk_list == 0)
- prev_port->tp_ops->set_irq(prev_port, 0);
+ prev_port->tp_ops->write_devctl(prev_port,
+ ATA_NIEN |
+ ATA_DEVCTL_OBS);
hwif->host->cur_port = hwif;
}
@@ -724,6 +662,7 @@ void ide_timer_expiry (unsigned long data)
}
}
hwif->handler = NULL;
+ hwif->expiry = NULL;
/*
* We need to simulate a real interrupt when invoking
* the handler() function, which means we need to
@@ -739,7 +678,8 @@ void ide_timer_expiry (unsigned long data)
} else if (drive_is_ready(drive)) {
if (drive->waiting_for_dma)
hwif->dma_ops->dma_lost_irq(drive);
- (void)ide_ack_intr(hwif);
+ if (hwif->ack_intr)
+ hwif->ack_intr(hwif);
printk(KERN_WARNING "%s: lost interrupt\n",
drive->name);
startstop = handler(drive);
@@ -840,6 +780,7 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif)
irqreturn_t ide_intr (int irq, void *dev_id)
{
ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
+ struct ide_host *host = hwif->host;
ide_drive_t *uninitialized_var(drive);
ide_handler_t *handler;
unsigned long flags;
@@ -847,14 +788,14 @@ irqreturn_t ide_intr (int irq, void *dev_id)
irqreturn_t irq_ret = IRQ_NONE;
int plug_device = 0;
- if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE) {
- if (hwif != hwif->host->cur_port)
+ if (host->host_flags & IDE_HFLAG_SERIALIZE) {
+ if (hwif != host->cur_port)
goto out_early;
}
spin_lock_irqsave(&hwif->lock, flags);
- if (!ide_ack_intr(hwif))
+ if (hwif->ack_intr && hwif->ack_intr(hwif) == 0)
goto out;
handler = hwif->handler;
@@ -871,27 +812,19 @@ irqreturn_t ide_intr (int irq, void *dev_id)
*
* For PCI, we cannot tell the difference,
* so in that case we just ignore it and hope it goes away.
- *
- * FIXME: unexpected_intr should be hwif-> then we can
- * remove all the ifdef PCI crap
*/
-#ifdef CONFIG_BLK_DEV_IDEPCI
- if (hwif->chipset != ide_pci)
-#endif /* CONFIG_BLK_DEV_IDEPCI */
- {
+ if ((host->irq_flags & IRQF_SHARED) == 0) {
/*
* Probably not a shared PCI interrupt,
* so we can safely try to do something about it:
*/
unexpected_intr(irq, hwif);
-#ifdef CONFIG_BLK_DEV_IDEPCI
} else {
/*
* Whack the status register, just in case
* we have a leftover pending IRQ.
*/
(void)hwif->tp_ops->read_status(hwif);
-#endif /* CONFIG_BLK_DEV_IDEPCI */
}
goto out;
}
@@ -909,6 +842,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
goto out;
hwif->handler = NULL;
+ hwif->expiry = NULL;
hwif->req_gen++;
del_timer(&hwif->timer);
spin_unlock(&hwif->lock);
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c
index 1be263eb9c0..77014276743 100644
--- a/drivers/ide/ide-ioctls.c
+++ b/drivers/ide/ide-ioctls.c
@@ -111,13 +111,13 @@ static int ide_set_nice_ioctl(ide_drive_t *drive, unsigned long arg)
return 0;
}
-static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg)
{
u8 *buf = NULL;
int bufsize = 0, err = 0;
u8 args[4], xfer_rate = 0;
- ide_task_t tfargs;
- struct ide_taskfile *tf = &tfargs.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u16 *id = drive->id;
if (NULL == (void *) arg) {
@@ -134,24 +134,24 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
if (copy_from_user(args, (void __user *)arg, 4))
return -EFAULT;
- memset(&tfargs, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
tf->feature = args[2];
if (args[0] == ATA_CMD_SMART) {
tf->nsect = args[3];
tf->lbal = args[1];
tf->lbam = 0x4f;
tf->lbah = 0xc2;
- tfargs.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
+ cmd.tf_flags = IDE_TFLAG_OUT_TF | IDE_TFLAG_IN_NSECT;
} else {
tf->nsect = args[1];
- tfargs.tf_flags = IDE_TFLAG_OUT_FEATURE |
- IDE_TFLAG_OUT_NSECT | IDE_TFLAG_IN_NSECT;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
+ IDE_TFLAG_IN_NSECT;
}
tf->command = args[0];
- tfargs.data_phase = args[3] ? TASKFILE_IN : TASKFILE_NO_DATA;
+ cmd.protocol = args[3] ? ATA_PROT_PIO : ATA_PROT_NODATA;
if (args[3]) {
- tfargs.tf_flags |= IDE_TFLAG_IO_16BIT;
+ cmd.tf_flags |= IDE_TFLAG_IO_16BIT;
bufsize = SECTOR_SIZE * args[3];
buf = kzalloc(bufsize, GFP_KERNEL);
if (buf == NULL)
@@ -172,7 +172,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
}
}
- err = ide_raw_taskfile(drive, &tfargs, buf, args[3]);
+ err = ide_raw_taskfile(drive, &cmd, buf, args[3]);
args[0] = tf->status;
args[1] = tf->error;
@@ -194,25 +194,25 @@ abort:
return err;
}
-static int ide_task_ioctl(ide_drive_t *drive, unsigned cmd, unsigned long arg)
+static int ide_task_ioctl(ide_drive_t *drive, unsigned long arg)
{
void __user *p = (void __user *)arg;
int err = 0;
u8 args[7];
- ide_task_t task;
+ struct ide_cmd cmd;
if (copy_from_user(args, p, 7))
return -EFAULT;
- memset(&task, 0, sizeof(task));
- memcpy(&task.tf_array[7], &args[1], 6);
- task.tf.command = args[0];
- task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ memcpy(&cmd.tf_array[7], &args[1], 6);
+ cmd.tf.command = args[0];
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- err = ide_no_data_taskfile(drive, &task);
+ err = ide_no_data_taskfile(drive, &cmd);
- args[0] = task.tf.command;
- memcpy(&args[1], &task.tf_array[7], 6);
+ args[0] = cmd.tf.command;
+ memcpy(&args[1], &cmd.tf_array[7], 6);
if (copy_to_user(p, args, 7))
err = -EFAULT;
@@ -262,17 +262,17 @@ int generic_ide_ioctl(ide_drive_t *drive, struct block_device *bdev,
if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
return -EACCES;
if (drive->media == ide_disk)
- return ide_taskfile_ioctl(drive, cmd, arg);
+ return ide_taskfile_ioctl(drive, arg);
return -ENOMSG;
#endif
case HDIO_DRIVE_CMD:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return ide_cmd_ioctl(drive, cmd, arg);
+ return ide_cmd_ioctl(drive, arg);
case HDIO_DRIVE_TASK:
if (!capable(CAP_SYS_RAWIO))
return -EACCES;
- return ide_task_ioctl(drive, cmd, arg);
+ return ide_task_ioctl(drive, arg);
case HDIO_DRIVE_RESET:
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index 317c5dadd7c..27bb70ddd45 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -27,21 +27,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
-void SELECT_DRIVE(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- const struct ide_port_ops *port_ops = hwif->port_ops;
- ide_task_t task;
-
- if (port_ops && port_ops->selectproc)
- port_ops->selectproc(drive);
-
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_DEVICE;
-
- drive->hwif->tp_ops->tf_load(drive, &task);
-}
-
void SELECT_MASK(ide_drive_t *drive, int mask)
{
const struct ide_port_ops *port_ops = drive->hwif->port_ops;
@@ -52,14 +37,14 @@ void SELECT_MASK(ide_drive_t *drive, int mask)
u8 ide_read_error(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_FEATURE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_ERROR;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.error;
+ return cmd.tf.error;
}
EXPORT_SYMBOL_GPL(ide_read_error);
@@ -306,6 +291,7 @@ int ide_driveid_update(ide_drive_t *drive)
drive->id[ATA_ID_UDMA_MODES] = id[ATA_ID_UDMA_MODES];
drive->id[ATA_ID_MWDMA_MODES] = id[ATA_ID_MWDMA_MODES];
drive->id[ATA_ID_SWDMA_MODES] = id[ATA_ID_SWDMA_MODES];
+ drive->id[ATA_ID_CFA_MODES] = id[ATA_ID_CFA_MODES];
/* anything more ? */
kfree(id);
@@ -329,7 +315,7 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
u16 *id = drive->id, i;
int error = 0;
u8 stat;
- ide_task_t task;
+ struct ide_cmd cmd;
#ifdef CONFIG_BLK_DEV_IDEDMA
if (hwif->dma_ops) /* check if host supports DMA */
@@ -356,22 +342,22 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
disable_irq_nosync(hwif->irq);
udelay(1);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
SELECT_MASK(drive, 1);
udelay(1);
- tp_ops->set_irq(hwif, 0);
+ tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
- task.tf.feature = SETFEATURES_XFER;
- task.tf.nsect = speed;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT;
+ cmd.tf.feature = SETFEATURES_XFER;
+ cmd.tf.nsect = speed;
- tp_ops->tf_load(drive, &task);
+ tp_ops->tf_load(drive, &cmd);
tp_ops->exec_command(hwif, ATA_CMD_SET_FEATURES);
if (drive->quirk_list == 2)
- tp_ops->set_irq(hwif, 1);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
error = __ide_wait_stat(drive, drive->ready_stat,
ATA_BUSY | ATA_DRQ | ATA_ERR,
@@ -386,9 +372,14 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
return error;
}
- id[ATA_ID_UDMA_MODES] &= ~0xFF00;
- id[ATA_ID_MWDMA_MODES] &= ~0x0F00;
- id[ATA_ID_SWDMA_MODES] &= ~0x0F00;
+ if (speed >= XFER_SW_DMA_0) {
+ id[ATA_ID_UDMA_MODES] &= ~0xFF00;
+ id[ATA_ID_MWDMA_MODES] &= ~0x0700;
+ id[ATA_ID_SWDMA_MODES] &= ~0x0700;
+ if (ata_id_is_cfa(id))
+ id[ATA_ID_CFA_MODES] &= ~0x0E00;
+ } else if (ata_id_is_cfa(id))
+ id[ATA_ID_CFA_MODES] &= ~0x01C0;
skip:
#ifdef CONFIG_BLK_DEV_IDEDMA
@@ -401,12 +392,18 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
if (speed >= XFER_UDMA_0) {
i = 1 << (speed - XFER_UDMA_0);
id[ATA_ID_UDMA_MODES] |= (i << 8 | i);
+ } else if (ata_id_is_cfa(id) && speed >= XFER_MW_DMA_3) {
+ i = speed - XFER_MW_DMA_2;
+ id[ATA_ID_CFA_MODES] |= i << 9;
} else if (speed >= XFER_MW_DMA_0) {
i = 1 << (speed - XFER_MW_DMA_0);
id[ATA_ID_MWDMA_MODES] |= (i << 8 | i);
} else if (speed >= XFER_SW_DMA_0) {
i = 1 << (speed - XFER_SW_DMA_0);
id[ATA_ID_SWDMA_MODES] |= (i << 8 | i);
+ } else if (ata_id_is_cfa(id) && speed >= XFER_PIO_5) {
+ i = speed - XFER_PIO_4;
+ id[ATA_ID_CFA_MODES] |= i << 6;
}
if (!drive->init_speed)
@@ -425,26 +422,25 @@ int ide_config_drive_speed(ide_drive_t *drive, u8 speed)
* See also ide_execute_command
*/
void __ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+ unsigned int timeout)
{
ide_hwif_t *hwif = drive->hwif;
BUG_ON(hwif->handler);
hwif->handler = handler;
- hwif->expiry = expiry;
hwif->timer.expires = jiffies + timeout;
hwif->req_gen_timer = hwif->req_gen;
add_timer(&hwif->timer);
}
-void ide_set_handler (ide_drive_t *drive, ide_handler_t *handler,
- unsigned int timeout, ide_expiry_t *expiry)
+void ide_set_handler(ide_drive_t *drive, ide_handler_t *handler,
+ unsigned int timeout)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
spin_lock_irqsave(&hwif->lock, flags);
- __ide_set_handler(drive, handler, timeout, expiry);
+ __ide_set_handler(drive, handler, timeout);
spin_unlock_irqrestore(&hwif->lock, flags);
}
EXPORT_SYMBOL(ide_set_handler);
@@ -452,10 +448,9 @@ EXPORT_SYMBOL(ide_set_handler);
/**
* ide_execute_command - execute an IDE command
* @drive: IDE drive to issue the command against
- * @command: command byte to write
+ * @cmd: command
* @handler: handler for next phase
* @timeout: timeout for command
- * @expiry: handler to run on timeout
*
* Helper function to issue an IDE command. This handles the
* atomicity requirements, command timing and ensures that the
@@ -463,15 +458,18 @@ EXPORT_SYMBOL(ide_set_handler);
* should go via this function or do equivalent locking.
*/
-void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
- unsigned timeout, ide_expiry_t *expiry)
+void ide_execute_command(ide_drive_t *drive, struct ide_cmd *cmd,
+ ide_handler_t *handler, unsigned timeout)
{
ide_hwif_t *hwif = drive->hwif;
unsigned long flags;
spin_lock_irqsave(&hwif->lock, flags);
- __ide_set_handler(drive, handler, timeout, expiry);
- hwif->tp_ops->exec_command(hwif, cmd);
+ if ((cmd->protocol != ATAPI_PROT_DMA &&
+ cmd->protocol != ATAPI_PROT_PIO) ||
+ (drive->atapi_flags & IDE_AFLAG_DRQ_INTERRUPT))
+ __ide_set_handler(drive, handler, timeout);
+ hwif->tp_ops->exec_command(hwif, cmd->tf.command);
/*
* Drive takes 400nS to respond, we must avoid the IRQ being
* serviced before that.
@@ -481,19 +479,6 @@ void ide_execute_command(ide_drive_t *drive, u8 cmd, ide_handler_t *handler,
ndelay(400);
spin_unlock_irqrestore(&hwif->lock, flags);
}
-EXPORT_SYMBOL(ide_execute_command);
-
-void ide_execute_pkt_cmd(ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- unsigned long flags;
-
- spin_lock_irqsave(&hwif->lock, flags);
- hwif->tp_ops->exec_command(hwif, ATA_CMD_PACKET);
- ndelay(400);
- spin_unlock_irqrestore(&hwif->lock, flags);
-}
-EXPORT_SYMBOL_GPL(ide_execute_pkt_cmd);
/*
* ide_wait_not_busy() waits for the currently selected device on the hwif
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index f6c683dd298..217b7fdf2b1 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -34,19 +34,19 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
static void ide_dump_opcode(ide_drive_t *drive)
{
struct request *rq = drive->hwif->rq;
- ide_task_t *task = NULL;
+ struct ide_cmd *cmd = NULL;
if (!rq)
return;
if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
- task = rq->special;
+ cmd = rq->special;
printk(KERN_ERR "ide: failed opcode was: ");
- if (task == NULL)
+ if (cmd == NULL)
printk(KERN_CONT "unknown\n");
else
- printk(KERN_CONT "0x%02x\n", task->tf.command);
+ printk(KERN_CONT "0x%02x\n", cmd->tf.command);
}
u64 ide_get_lba_addr(struct ide_taskfile *tf, int lba48)
@@ -66,18 +66,18 @@ EXPORT_SYMBOL_GPL(ide_get_lba_addr);
static void ide_dump_sector(ide_drive_t *drive)
{
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
u8 lba48 = !!(drive->dev_flags & IDE_DFLAG_LBA48);
- memset(&task, 0, sizeof(task));
+ memset(&cmd, 0, sizeof(cmd));
if (lba48)
- task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
+ cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_HOB_LBA |
IDE_TFLAG_LBA48;
else
- task.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
+ cmd.tf_flags = IDE_TFLAG_IN_LBA | IDE_TFLAG_IN_DEVICE;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
if (lba48 || (tf->device & ATA_LBA))
printk(KERN_CONT ", LBAsect=%llu",
diff --git a/drivers/ide/ide-park.c b/drivers/ide/ide-park.c
index f30e52152fc..9490b446519 100644
--- a/drivers/ide/ide-park.c
+++ b/drivers/ide/ide-park.c
@@ -1,6 +1,5 @@
#include <linux/kernel.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
#include <linux/jiffies.h>
#include <linux/blkdev.h>
@@ -63,10 +62,10 @@ out:
ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
{
- ide_task_t task;
- struct ide_taskfile *tf = &task.tf;
+ struct ide_cmd cmd;
+ struct ide_taskfile *tf = &cmd.tf;
- memset(&task, 0, sizeof(task));
+ memset(&cmd, 0, sizeof(cmd));
if (rq->cmd[0] == REQ_PARK_HEADS) {
drive->sleep = *(unsigned long *)rq->special;
drive->dev_flags |= IDE_DFLAG_SLEEPING;
@@ -75,14 +74,16 @@ ide_startstop_t ide_do_park_unpark(ide_drive_t *drive, struct request *rq)
tf->lbal = 0x4c;
tf->lbam = 0x4e;
tf->lbah = 0x55;
- task.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
} else /* cmd == REQ_UNPARK_HEADS */
tf->command = ATA_CMD_CHK_POWER;
- task.tf_flags |= IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- task.rq = rq;
- drive->hwif->data_phase = task.data_phase = TASKFILE_NO_DATA;
- return do_rw_taskfile(drive, &task);
+ cmd.tf_flags |= IDE_TFLAG_CUSTOM_HANDLER;
+ cmd.protocol = ATA_PROT_NODATA;
+
+ cmd.rq = rq;
+
+ return do_rw_taskfile(drive, &cmd);
}
ssize_t ide_park_show(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/ide/ide-pm.c b/drivers/ide/ide-pm.c
index 60538d9c84e..bb7858ebb7d 100644
--- a/drivers/ide/ide-pm.c
+++ b/drivers/ide/ide-pm.c
@@ -1,6 +1,5 @@
#include <linux/kernel.h>
#include <linux/ide.h>
-#include <linux/hdreg.h>
int generic_ide_suspend(struct device *dev, pm_message_t mesg)
{
@@ -8,7 +7,7 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- ide_task_t args;
+ struct ide_cmd cmd;
int ret;
/* call ACPI _GTM only once */
@@ -16,10 +15,10 @@ int generic_ide_suspend(struct device *dev, pm_message_t mesg)
ide_acpi_get_timing(hwif);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
+ memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_SUSPEND;
- rq->special = &args;
+ rq->special = &cmd;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_SUSPEND;
if (mesg.event == PM_EVENT_PRETHAW)
@@ -42,7 +41,7 @@ int generic_ide_resume(struct device *dev)
ide_hwif_t *hwif = drive->hwif;
struct request *rq;
struct request_pm_state rqpm;
- ide_task_t args;
+ struct ide_cmd cmd;
int err;
/* call ACPI _PS0 / _STM only once */
@@ -54,11 +53,11 @@ int generic_ide_resume(struct device *dev)
ide_acpi_exec_tfs(drive);
memset(&rqpm, 0, sizeof(rqpm));
- memset(&args, 0, sizeof(args));
+ memset(&cmd, 0, sizeof(cmd));
rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
rq->cmd_type = REQ_TYPE_PM_RESUME;
rq->cmd_flags |= REQ_PREEMPT;
- rq->special = &args;
+ rq->special = &cmd;
rq->data = &rqpm;
rqpm.pm_step = IDE_PM_START_RESUME;
rqpm.pm_state = PM_EVENT_ON;
@@ -109,9 +108,9 @@ void ide_complete_power_step(ide_drive_t *drive, struct request *rq)
ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
{
struct request_pm_state *pm = rq->data;
- ide_task_t *args = rq->special;
+ struct ide_cmd *cmd = rq->special;
- memset(args, 0, sizeof(*args));
+ memset(cmd, 0, sizeof(*cmd));
switch (pm->pm_step) {
case IDE_PM_FLUSH_CACHE: /* Suspend step 1 (flush cache) */
@@ -124,12 +123,12 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
return ide_stopped;
}
if (ata_id_flush_ext_enabled(drive->id))
- args->tf.command = ATA_CMD_FLUSH_EXT;
+ cmd->tf.command = ATA_CMD_FLUSH_EXT;
else
- args->tf.command = ATA_CMD_FLUSH;
+ cmd->tf.command = ATA_CMD_FLUSH;
goto out_do_tf;
case IDE_PM_STANDBY: /* Suspend step 2 (standby) */
- args->tf.command = ATA_CMD_STANDBYNOW1;
+ cmd->tf.command = ATA_CMD_STANDBYNOW1;
goto out_do_tf;
case IDE_PM_RESTORE_PIO: /* Resume step 1 (restore PIO) */
ide_set_max_pio(drive);
@@ -142,7 +141,7 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
ide_complete_power_step(drive, rq);
return ide_stopped;
case IDE_PM_IDLE: /* Resume step 2 (idle) */
- args->tf.command = ATA_CMD_IDLEIMMEDIATE;
+ cmd->tf.command = ATA_CMD_IDLEIMMEDIATE;
goto out_do_tf;
case IDE_PM_RESTORE_DMA: /* Resume step 3 (restore DMA) */
/*
@@ -160,27 +159,34 @@ ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *rq)
}
pm->pm_step = IDE_PM_COMPLETED;
+
return ide_stopped;
out_do_tf:
- args->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args->data_phase = TASKFILE_NO_DATA;
- return do_rw_taskfile(drive, args);
+ cmd->tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd->protocol = ATA_PROT_NODATA;
+
+ return do_rw_taskfile(drive, cmd);
}
/**
- * ide_complete_pm_request - end the current Power Management request
+ * ide_complete_pm_rq - end the current Power Management request
* @drive: target drive
* @rq: request
*
* This function cleans up the current PM request and stops the queue
* if necessary.
*/
-void ide_complete_pm_request(ide_drive_t *drive, struct request *rq)
+void ide_complete_pm_rq(ide_drive_t *drive, struct request *rq)
{
struct request_queue *q = drive->queue;
+ struct request_pm_state *pm = rq->data;
unsigned long flags;
+ ide_complete_power_step(drive, rq);
+ if (pm->pm_step != IDE_PM_COMPLETED)
+ return;
+
#ifdef DEBUG_PM
printk("%s: completing PM request, %s\n", drive->name,
blk_pm_suspend_request(rq) ? "suspend" : "resume");
@@ -217,6 +223,7 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
* point.
*/
ide_hwif_t *hwif = drive->hwif;
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
struct request_queue *q = drive->queue;
unsigned long flags;
int rc;
@@ -226,8 +233,8 @@ void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
printk(KERN_WARNING "%s: bus not ready on wakeup\n", drive->name);
- SELECT_DRIVE(drive);
- hwif->tp_ops->set_irq(hwif, 1);
+ tp_ops->dev_select(drive);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
rc = ide_wait_not_busy(hwif, 100000);
if (rc)
printk(KERN_WARNING "%s: drive not ready on wakeup\n", drive->name);
diff --git a/drivers/ide/ide-pnp.c b/drivers/ide/ide-pnp.c
index bac9b392b68..6e80b774e88 100644
--- a/drivers/ide/ide-pnp.c
+++ b/drivers/ide/ide-pnp.c
@@ -27,6 +27,10 @@ static struct pnp_device_id idepnp_devices[] = {
{.id = ""}
};
+static const struct ide_port_info ide_pnp_port_info = {
+ .host_flags = IDE_HFLAG_NO_DMA,
+};
+
static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
struct ide_host *host;
@@ -60,7 +64,7 @@ static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
hw.irq = pnp_irq(dev, 0);
hw.chipset = ide_generic;
- rc = ide_host_add(NULL, hws, &host);
+ rc = ide_host_add(&ide_pnp_port_info, hws, &host);
if (rc)
goto out;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 974067043fb..d8c1c3e735b 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -228,15 +228,9 @@ static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
m[ATA_ID_PROD_LEN - 1] = '\0';
if (strstr(m, "E X A B Y T E N E S T"))
- goto err_misc;
-
- drive->dev_flags |= IDE_DFLAG_PRESENT;
- drive->dev_flags &= ~IDE_DFLAG_DEAD;
-
- return;
-err_misc:
- kfree(id);
- drive->dev_flags &= ~IDE_DFLAG_PRESENT;
+ drive->dev_flags &= ~IDE_DFLAG_PRESENT;
+ else
+ drive->dev_flags |= IDE_DFLAG_PRESENT;
}
/**
@@ -266,7 +260,7 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
* during the identify phase that the IRQ handler isn't expecting.
*/
if (io_ports->ctl_addr)
- tp_ops->set_irq(hwif, 0);
+ tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
/* take a deep breath */
msleep(50);
@@ -289,13 +283,13 @@ int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id)
* identify command to be sure of reply
*/
if (cmd == ATA_CMD_ID_ATAPI) {
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
+ memset(&cmd, 0, sizeof(cmd));
/* disable DMA & overlap */
- task.tf_flags = IDE_TFLAG_OUT_FEATURE;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE;
- tp_ops->tf_load(drive, &task);
+ tp_ops->tf_load(drive, &cmd);
}
/* ask drive for ID */
@@ -343,14 +337,14 @@ int ide_busy_sleep(ide_hwif_t *hwif, unsigned long timeout, int altstatus)
static u8 ide_read_device(ide_drive_t *drive)
{
- ide_task_t task;
+ struct ide_cmd cmd;
- memset(&task, 0, sizeof(task));
- task.tf_flags = IDE_TFLAG_IN_DEVICE;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf_flags = IDE_TFLAG_IN_DEVICE;
- drive->hwif->tp_ops->tf_read(drive, &task);
+ drive->hwif->tp_ops->tf_read(drive, &cmd);
- return task.tf.device;
+ return cmd.tf.device;
}
/**
@@ -396,13 +390,13 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
* (e.g. crw9624 as drive0 with disk as slave)
*/
msleep(50);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
msleep(50);
if (ide_read_device(drive) != drive->select && present == 0) {
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
/* allow ATA_BUSY to assert & clear */
msleep(50);
}
@@ -428,7 +422,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
printk(KERN_ERR "%s: no response (status = 0x%02x), "
"resetting drive\n", drive->name, stat);
msleep(50);
- SELECT_DRIVE(drive);
+ tp_ops->dev_select(drive);
msleep(50);
tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
(void)ide_busy_sleep(hwif, WAIT_WORSTCASE, 0);
@@ -447,7 +441,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd)
}
if (drive->dn & 1) {
/* exit with drive0 selected */
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
msleep(50);
/* ensure drive irq is clear */
(void)tp_ops->read_status(hwif);
@@ -505,8 +499,7 @@ static u8 probe_for_drive(ide_drive_t *drive)
}
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- /* drive not found */
- return 0;
+ goto out_free;
/* identification failed? */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -530,7 +523,7 @@ static u8 probe_for_drive(ide_drive_t *drive)
}
if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
- return 0;
+ goto out_free;
/* The drive wasn't being helpful. Add generic info only */
if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
@@ -543,7 +536,10 @@ static u8 probe_for_drive(ide_drive_t *drive)
ide_disk_init_mult_count(drive);
}
- return !!(drive->dev_flags & IDE_DFLAG_PRESENT);
+ return 1;
+out_free:
+ kfree(drive->id);
+ return 0;
}
static void hwif_release_dev(struct device *dev)
@@ -609,6 +605,7 @@ out:
static int ide_port_wait_ready(ide_hwif_t *hwif)
{
+ const struct ide_tp_ops *tp_ops = hwif->tp_ops;
ide_drive_t *drive;
int i, rc;
@@ -631,8 +628,8 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
/* Ignore disks that we will not probe for later. */
if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
(drive->dev_flags & IDE_DFLAG_PRESENT)) {
- SELECT_DRIVE(drive);
- hwif->tp_ops->set_irq(hwif, 1);
+ tp_ops->dev_select(drive);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
mdelay(2);
rc = ide_wait_not_busy(hwif, 35000);
if (rc)
@@ -644,7 +641,7 @@ static int ide_port_wait_ready(ide_hwif_t *hwif)
out:
/* Exit function with master reselected (let's be sane) */
if (i)
- SELECT_DRIVE(hwif->devices[0]);
+ tp_ops->dev_select(hwif->devices[0]);
return rc;
}
@@ -841,34 +838,19 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
static int init_irq (ide_hwif_t *hwif)
{
struct ide_io_ports *io_ports = &hwif->io_ports;
- irq_handler_t irq_handler;
- int sa = 0;
+ struct ide_host *host = hwif->host;
+ irq_handler_t irq_handler = host->irq_handler;
+ int sa = host->irq_flags;
- irq_handler = hwif->host->irq_handler;
if (irq_handler == NULL)
irq_handler = ide_intr;
-#if defined(__mc68000__)
- sa = IRQF_SHARED;
-#endif /* __mc68000__ */
-
- if (hwif->chipset == ide_pci)
- sa = IRQF_SHARED;
-
if (io_ports->ctl_addr)
- hwif->tp_ops->set_irq(hwif, 1);
+ hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
goto out_up;
- if (!hwif->rqsize) {
- if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
- (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
- hwif->rqsize = 256;
- else
- hwif->rqsize = 65536;
- }
-
#if !defined(__mc68000__)
printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
io_ports->data_addr, io_ports->status_addr,
@@ -961,20 +943,16 @@ EXPORT_SYMBOL_GPL(ide_init_disk);
static void drive_release_dev (struct device *dev)
{
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
- ide_hwif_t *hwif = drive->hwif;
ide_proc_unregister_device(drive);
- spin_lock_irq(&hwif->lock);
+ blk_cleanup_queue(drive->queue);
+ drive->queue = NULL;
+
kfree(drive->id);
drive->id = NULL;
+
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
- /* Messed up locking ... */
- spin_unlock_irq(&hwif->lock);
- blk_cleanup_queue(drive->queue);
- spin_lock_irq(&hwif->lock);
- drive->queue = NULL;
- spin_unlock_irq(&hwif->lock);
complete(&drive->gendev_rel_comp);
}
@@ -1080,7 +1058,7 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
hwif->tp_ops = d->tp_ops;
/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
- if (hwif->chipset != ide_dtc2278 || hwif->channel == 0)
+ if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0)
hwif->port_ops = d->port_ops;
hwif->swdma_mask = d->swdma_mask;
@@ -1114,6 +1092,13 @@ static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
if (d->max_sectors)
hwif->rqsize = d->max_sectors;
+ else {
+ if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
+ (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
+ hwif->rqsize = 256;
+ else
+ hwif->rqsize = 65536;
+ }
/* call chipset specific routine for each enabled port */
if (d->init_hwif)
@@ -1326,6 +1311,8 @@ struct ide_host *ide_host_alloc(const struct ide_port_info *d, hw_regs_t **hws)
if (d) {
host->init_chipset = d->init_chipset;
+ host->get_lock = d->get_lock;
+ host->release_lock = d->release_lock;
host->host_flags = d->host_flags;
}
@@ -1372,20 +1359,15 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
ide_init_port_hw(hwif, hws[i]);
ide_port_apply_params(hwif);
- if (d == NULL) {
- mate = NULL;
- } else {
- if ((i & 1) && mate) {
- hwif->mate = mate;
- mate->mate = hwif;
- }
-
- mate = (i & 1) ? NULL : hwif;
-
- ide_init_port(hwif, i & 1, d);
- ide_port_cable_detect(hwif);
+ if ((i & 1) && mate) {
+ hwif->mate = mate;
+ mate->mate = hwif;
}
+ mate = (i & 1) ? NULL : hwif;
+
+ ide_init_port(hwif, i & 1, d);
+ ide_port_cable_detect(hwif);
ide_port_init_devices(hwif);
}
@@ -1396,8 +1378,8 @@ int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
if (ide_probe_port(hwif) == 0)
hwif->present = 1;
- if (hwif->chipset != ide_4drives || !hwif->mate ||
- !hwif->mate->present) {
+ if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
+ hwif->mate == NULL || hwif->mate->present == 0) {
if (ide_register_port(hwif)) {
ide_disable_port(hwif);
continue;
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c
index 417cde56eaf..10a88bf3eef 100644
--- a/drivers/ide/ide-proc.c
+++ b/drivers/ide/ide-proc.c
@@ -194,20 +194,20 @@ ide_devset_get(xfer_rate, current_speed);
static int set_xfer_rate (ide_drive_t *drive, int arg)
{
- ide_task_t task;
+ struct ide_cmd cmd;
int err;
if (arg < XFER_PIO_0 || arg > XFER_UDMA_6)
return -EINVAL;
- memset(&task, 0, sizeof(task));
- task.tf.command = ATA_CMD_SET_FEATURES;
- task.tf.feature = SETFEATURES_XFER;
- task.tf.nsect = (u8)arg;
- task.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
- IDE_TFLAG_IN_NSECT;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.command = ATA_CMD_SET_FEATURES;
+ cmd.tf.feature = SETFEATURES_XFER;
+ cmd.tf.nsect = (u8)arg;
+ cmd.tf_flags = IDE_TFLAG_OUT_FEATURE | IDE_TFLAG_OUT_NSECT |
+ IDE_TFLAG_IN_NSECT;
- err = ide_no_data_taskfile(drive, &task);
+ err = ide_no_data_taskfile(drive, &cmd);
if (!err) {
ide_set_xfer_rate(drive, (u8) arg);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 4e6181c7bbd..cb942a9b580 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -152,11 +152,6 @@ struct idetape_bh {
#define IDETAPE_LU_RETENSION_MASK 2
#define IDETAPE_LU_EOT_MASK 4
-/* Error codes returned in rq->errors to the higher part of the driver. */
-#define IDETAPE_ERROR_GENERAL 101
-#define IDETAPE_ERROR_FILEMARK 102
-#define IDETAPE_ERROR_EOD 103
-
/* Structures related to the SELECT SENSE / MODE SENSE packet commands. */
#define IDETAPE_BLOCK_DESCRIPTOR 0
#define IDETAPE_CAPABILITIES_PAGE 0x2a
@@ -171,14 +166,6 @@ typedef struct ide_tape_obj {
struct gendisk *disk;
struct device dev;
- /*
- * failed_pc points to the last failed packet command, or contains
- * NULL if we do not need to retry any packet command. This is
- * required since an additional packet command is needed before the
- * retry, to get detailed information on what went wrong.
- */
- /* Last failed packet command */
- struct ide_atapi_pc *failed_pc;
/* used by REQ_IDETAPE_{READ,WRITE} requests */
struct ide_atapi_pc queued_pc;
@@ -245,9 +232,6 @@ typedef struct ide_tape_obj {
/* Wasted space in each stage */
int excess_bh_size;
- /* protects the ide-tape queue */
- spinlock_t lock;
-
/* Measures average tape speed */
unsigned long avg_time;
int avg_size;
@@ -313,19 +297,15 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i)
return tape;
}
-static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
int count;
while (bcount) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in "
- "idetape_input_buffers\n");
- ide_pad_transfer(drive, 0, bcount);
- return;
- }
+ if (bh == NULL)
+ break;
count = min(
(unsigned int)(bh->b_size - atomic_read(&bh->b_count)),
bcount);
@@ -339,21 +319,21 @@ static void idetape_input_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
atomic_set(&bh->b_count, 0);
}
}
+
pc->bh = bh;
+
+ return bcount;
}
-static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
+static int idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount)
{
struct idetape_bh *bh = pc->bh;
int count;
while (bcount) {
- if (bh == NULL) {
- printk(KERN_ERR "ide-tape: bh == NULL in %s\n",
- __func__);
- return;
- }
+ if (bh == NULL)
+ break;
count = min((unsigned int)pc->b_count, (unsigned int)bcount);
drive->hwif->tp_ops->output_data(drive, NULL, pc->b_data, count);
bcount -= count;
@@ -368,6 +348,8 @@ static void idetape_output_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
}
}
}
+
+ return bcount;
}
static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
@@ -400,7 +382,7 @@ static void idetape_update_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc)
static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
{
idetape_tape_t *tape = drive->driver_data;
- struct ide_atapi_pc *pc = tape->failed_pc;
+ struct ide_atapi_pc *pc = drive->failed_pc;
tape->sense_key = sense[2] & 0xF;
tape->asc = sense[12];
@@ -433,19 +415,19 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense)
}
}
if (pc->c[0] == READ_6 && (sense[2] & 0x80)) {
- pc->error = IDETAPE_ERROR_FILEMARK;
+ pc->error = IDE_DRV_ERROR_FILEMARK;
pc->flags |= PC_FLAG_ABORT;
}
if (pc->c[0] == WRITE_6) {
if ((sense[2] & 0x40) || (tape->sense_key == 0xd
&& tape->asc == 0x0 && tape->ascq == 0x2)) {
- pc->error = IDETAPE_ERROR_EOD;
+ pc->error = IDE_DRV_ERROR_EOD;
pc->flags |= PC_FLAG_ABORT;
}
}
if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
if (tape->sense_key == 8) {
- pc->error = IDETAPE_ERROR_EOD;
+ pc->error = IDE_DRV_ERROR_EOD;
pc->flags |= PC_FLAG_ABORT;
}
if (!(pc->flags & PC_FLAG_ABORT) &&
@@ -477,52 +459,23 @@ static void ide_tape_kfree_buffer(idetape_tape_t *tape)
}
}
-static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
-{
- struct request *rq = drive->hwif->rq;
- idetape_tape_t *tape = drive->driver_data;
- unsigned long flags;
- int error;
-
- debug_log(DBG_PROCS, "Enter %s\n", __func__);
-
- switch (uptodate) {
- case 0: error = IDETAPE_ERROR_GENERAL; break;
- case 1: error = 0; break;
- default: error = uptodate;
- }
- rq->errors = error;
- if (error)
- tape->failed_pc = NULL;
-
- if (!blk_special_request(rq)) {
- ide_end_request(drive, uptodate, nr_sects);
- return 0;
- }
-
- spin_lock_irqsave(&tape->lock, flags);
-
- ide_end_drive_cmd(drive, 0, 0);
-
- spin_unlock_irqrestore(&tape->lock, flags);
- return 0;
-}
-
static void ide_tape_handle_dsc(ide_drive_t *);
-static void ide_tape_callback(ide_drive_t *drive, int dsc)
+static int ide_tape_callback(ide_drive_t *drive, int dsc)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = drive->pc;
+ struct request *rq = drive->hwif->rq;
int uptodate = pc->error ? 0 : 1;
+ int err = uptodate ? 0 : IDE_DRV_ERROR_GENERAL;
debug_log(DBG_PROCS, "Enter %s\n", __func__);
if (dsc)
ide_tape_handle_dsc(drive);
- if (tape->failed_pc == pc)
- tape->failed_pc = NULL;
+ if (drive->failed_pc == pc)
+ drive->failed_pc = NULL;
if (pc->c[0] == REQUEST_SENSE) {
if (uptodate)
@@ -531,7 +484,6 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
printk(KERN_ERR "ide-tape: Error in REQUEST SENSE "
"itself - Aborting request!\n");
} else if (pc->c[0] == READ_6 || pc->c[0] == WRITE_6) {
- struct request *rq = drive->hwif->rq;
int blocks = pc->xferred / tape->blk_size;
tape->avg_size += blocks * tape->blk_size;
@@ -546,8 +498,10 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
tape->first_frame += blocks;
rq->current_nr_sectors -= blocks;
- if (pc->error)
- uptodate = pc->error;
+ if (pc->error) {
+ uptodate = 0;
+ err = pc->error;
+ }
} else if (pc->c[0] == READ_POSITION && uptodate) {
u8 *readpos = pc->buf;
@@ -561,6 +515,7 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
"to the tape\n");
clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags);
uptodate = 0;
+ err = IDE_DRV_ERROR_GENERAL;
} else {
debug_log(DBG_SENSE, "Block Location - %u\n",
be32_to_cpup((__be32 *)&readpos[4]));
@@ -571,7 +526,9 @@ static void ide_tape_callback(ide_drive_t *drive, int dsc)
}
}
- idetape_end_request(drive, uptodate, 0);
+ rq->errors = err;
+
+ return uptodate;
}
/*
@@ -604,12 +561,14 @@ static void ide_tape_handle_dsc(ide_drive_t *drive)
static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
unsigned int bcount, int write)
{
+ unsigned int bleft;
+
if (write)
- idetape_output_buffers(drive, pc, bcount);
+ bleft = idetape_output_buffers(drive, pc, bcount);
else
- idetape_input_buffers(drive, pc, bcount);
+ bleft = idetape_input_buffers(drive, pc, bcount);
- return bcount;
+ return bcount - bleft;
}
/*
@@ -621,7 +580,7 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
*
* The handling will be done in three stages:
*
- * 1. idetape_issue_pc will send the packet command to the drive, and will set
+ * 1. ide_tape_issue_pc will send the packet command to the drive, and will set
* the interrupt handler to ide_pc_intr.
*
* 2. On each interrupt, ide_pc_intr will be called. This step will be
@@ -649,8 +608,9 @@ static int ide_tape_io_buffers(ide_drive_t *drive, struct ide_atapi_pc *pc,
* request.
*/
-static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
- struct ide_atapi_pc *pc)
+static ide_startstop_t ide_tape_issue_pc(ide_drive_t *drive,
+ struct ide_cmd *cmd,
+ struct ide_atapi_pc *pc)
{
idetape_tape_t *tape = drive->driver_data;
@@ -660,8 +620,8 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
"Two request sense in serial were issued\n");
}
- if (tape->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
- tape->failed_pc = pc;
+ if (drive->failed_pc == NULL && pc->c[0] != REQUEST_SENSE)
+ drive->failed_pc = pc;
/* Set the current packet command */
drive->pc = pc;
@@ -685,9 +645,9 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
tape->ascq);
}
/* Giving up */
- pc->error = IDETAPE_ERROR_GENERAL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
}
- tape->failed_pc = NULL;
+ drive->failed_pc = NULL;
drive->pc_callback(drive, 0);
return ide_stopped;
}
@@ -695,7 +655,7 @@ static ide_startstop_t idetape_issue_pc(ide_drive_t *drive,
pc->retries++;
- return ide_issue_pc(drive);
+ return ide_issue_pc(drive, cmd);
}
/* A mode sense command is used to "sense" tape parameters. */
@@ -746,8 +706,8 @@ static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive)
}
pc->error = 0;
} else {
- pc->error = IDETAPE_ERROR_GENERAL;
- tape->failed_pc = NULL;
+ pc->error = IDE_DRV_ERROR_GENERAL;
+ drive->failed_pc = NULL;
}
drive->pc_callback(drive, 0);
return ide_stopped;
@@ -790,6 +750,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc *pc = NULL;
struct request *postponed_rq = tape->postponed_rq;
+ struct ide_cmd cmd;
u8 stat;
debug_log(DBG_SENSE, "sector: %llu, nr_sectors: %lu,"
@@ -801,13 +762,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
/* We do not support buffer cache originated requests. */
printk(KERN_NOTICE "ide-tape: %s: Unsupported request in "
"request queue (%d)\n", drive->name, rq->cmd_type);
- ide_end_request(drive, 0, 0);
+ if (blk_fs_request(rq) == 0 && rq->errors == 0)
+ rq->errors = -EIO;
+ ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
return ide_stopped;
}
/* Retry a failed packet command */
- if (tape->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
- pc = tape->failed_pc;
+ if (drive->failed_pc && drive->pc->c[0] == REQUEST_SENSE) {
+ pc = drive->failed_pc;
goto out;
}
@@ -815,7 +778,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
if (rq != postponed_rq) {
printk(KERN_ERR "ide-tape: ide-tape.c bug - "
"Two DSC requests were queued\n");
- idetape_end_request(drive, 0, 0);
+ drive->failed_pc = NULL;
+ rq->errors = 0;
+ ide_complete_rq(drive, 0, blk_rq_bytes(rq));
return ide_stopped;
}
@@ -881,7 +846,14 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive,
BUG();
out:
- return idetape_issue_pc(drive, pc);
+ memset(&cmd, 0, sizeof(cmd));
+
+ if (rq_data_dir(rq))
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+
+ cmd.rq = rq;
+
+ return ide_tape_issue_pc(drive, &cmd, pc);
}
/*
@@ -1226,7 +1198,7 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks,
if (tape->merge_bh)
idetape_init_merge_buffer(tape);
- if (errors == IDETAPE_ERROR_GENERAL)
+ if (errors == IDE_DRV_ERROR_GENERAL)
return -EIO;
return ret;
}
@@ -2042,9 +2014,13 @@ static void idetape_get_inquiry_results(ide_drive_t *drive)
{
idetape_tape_t *tape = drive->driver_data;
struct ide_atapi_pc pc;
+ u8 pc_buf[256];
char fw_rev[4], vendor_id[8], product_id[16];
idetape_create_inquiry_cmd(&pc);
+ pc.buf = &pc_buf[0];
+ pc.buf_size = sizeof(pc_buf);
+
if (ide_queue_pc_tail(drive, tape->disk, &pc)) {
printk(KERN_ERR "ide-tape: %s: can't get INQUIRY results\n",
tape->name);
@@ -2192,8 +2168,6 @@ static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor)
drive->pc_update_buffers = idetape_update_buffers;
drive->pc_io_buffers = ide_tape_io_buffers;
- spin_lock_init(&tape->lock);
-
drive->dev_flags |= IDE_DFLAG_DSC_OVERLAP;
if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) {
@@ -2325,7 +2299,6 @@ static struct ide_driver idetape_driver = {
.remove = ide_tape_remove,
.version = IDETAPE_VERSION,
.do_request = idetape_do_request,
- .end_request = idetape_end_request,
#ifdef CONFIG_IDE_PROC_FS
.proc_entries = ide_tape_proc_entries,
.proc_devsets = ide_tape_proc_devsets,
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 16138bce84a..243421ce40d 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -39,88 +39,90 @@ void ide_tf_dump(const char *s, struct ide_taskfile *tf)
int taskfile_lib_get_identify (ide_drive_t *drive, u8 *buf)
{
- ide_task_t args;
+ struct ide_cmd cmd;
- memset(&args, 0, sizeof(ide_task_t));
- args.tf.nsect = 0x01;
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.tf.nsect = 0x01;
if (drive->media == ide_disk)
- args.tf.command = ATA_CMD_ID_ATA;
+ cmd.tf.command = ATA_CMD_ID_ATA;
else
- args.tf.command = ATA_CMD_ID_ATAPI;
- args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
- args.data_phase = TASKFILE_IN;
- return ide_raw_taskfile(drive, &args, buf, 1);
+ cmd.tf.command = ATA_CMD_ID_ATAPI;
+ cmd.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
+ cmd.protocol = ATA_PROT_PIO;
+
+ return ide_raw_taskfile(drive, &cmd, buf, 1);
}
static ide_startstop_t task_no_data_intr(ide_drive_t *);
-static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct request *);
-static ide_startstop_t task_in_intr(ide_drive_t *);
+static ide_startstop_t pre_task_out_intr(ide_drive_t *, struct ide_cmd *);
+static ide_startstop_t task_pio_intr(ide_drive_t *);
-ide_startstop_t do_rw_taskfile (ide_drive_t *drive, ide_task_t *task)
+ide_startstop_t do_rw_taskfile(ide_drive_t *drive, struct ide_cmd *orig_cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct ide_taskfile *tf = &task->tf;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct ide_taskfile *tf = &cmd->tf;
ide_handler_t *handler = NULL;
const struct ide_tp_ops *tp_ops = hwif->tp_ops;
const struct ide_dma_ops *dma_ops = hwif->dma_ops;
- if (task->data_phase == TASKFILE_MULTI_IN ||
- task->data_phase == TASKFILE_MULTI_OUT) {
- if (!drive->mult_count) {
- printk(KERN_ERR "%s: multimode not set!\n",
- drive->name);
- return ide_stopped;
- }
+ if (orig_cmd->protocol == ATA_PROT_PIO &&
+ (orig_cmd->tf_flags & IDE_TFLAG_MULTI_PIO) &&
+ drive->mult_count == 0) {
+ printk(KERN_ERR "%s: multimode not set!\n", drive->name);
+ return ide_stopped;
}
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
- task->tf_flags |= IDE_TFLAG_FLAGGED_SET_IN_FLAGS;
+ if (orig_cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
+ orig_cmd->ftf_flags |= IDE_FTFLAG_SET_IN_FLAGS;
- memcpy(&hwif->task, task, sizeof(*task));
+ memcpy(cmd, orig_cmd, sizeof(*cmd));
- if ((task->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
+ if ((cmd->tf_flags & IDE_TFLAG_DMA_PIO_FALLBACK) == 0) {
ide_tf_dump(drive->name, tf);
- tp_ops->set_irq(hwif, 1);
+ tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
SELECT_MASK(drive, 0);
- tp_ops->tf_load(drive, task);
+
+ if (cmd->ftf_flags & IDE_FTFLAG_OUT_DATA) {
+ u8 data[2] = { tf->data, tf->hob_data };
+
+ tp_ops->output_data(drive, cmd, data, 2);
+ }
+ tp_ops->tf_load(drive, cmd);
}
- switch (task->data_phase) {
- case TASKFILE_MULTI_OUT:
- case TASKFILE_OUT:
- tp_ops->exec_command(hwif, tf->command);
- ndelay(400); /* FIXME */
- return pre_task_out_intr(drive, task->rq);
- case TASKFILE_MULTI_IN:
- case TASKFILE_IN:
- handler = task_in_intr;
+ switch (cmd->protocol) {
+ case ATA_PROT_PIO:
+ if (cmd->tf_flags & IDE_TFLAG_WRITE) {
+ tp_ops->exec_command(hwif, tf->command);
+ ndelay(400); /* FIXME */
+ return pre_task_out_intr(drive, cmd);
+ }
+ handler = task_pio_intr;
/* fall-through */
- case TASKFILE_NO_DATA:
+ case ATA_PROT_NODATA:
if (handler == NULL)
handler = task_no_data_intr;
- ide_execute_command(drive, tf->command, handler,
- WAIT_WORSTCASE, NULL);
+ ide_execute_command(drive, cmd, handler, WAIT_WORSTCASE);
return ide_started;
- default:
- if ((drive->dev_flags & IDE_DFLAG_USING_DMA) == 0 ||
- dma_ops->dma_setup(drive))
+ case ATA_PROT_DMA:
+ if (ide_dma_prepare(drive, cmd))
return ide_stopped;
- dma_ops->dma_exec_cmd(drive, tf->command);
+ hwif->expiry = dma_ops->dma_timer_expiry;
+ ide_execute_command(drive, cmd, ide_dma_intr, 2 * WAIT_CMD);
dma_ops->dma_start(drive);
+ default:
return ide_started;
}
}
EXPORT_SYMBOL_GPL(do_rw_taskfile);
-/*
- * Handler for commands without a data phase
- */
static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- ide_task_t *task = &hwif->task;
- struct ide_taskfile *tf = &task->tf;
- int custom = (task->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
+ struct ide_cmd *cmd = &hwif->cmd;
+ struct ide_taskfile *tf = &cmd->tf;
+ int custom = (cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) ? 1 : 0;
int retries = (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) ? 5 : 1;
u8 stat;
@@ -142,28 +144,26 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
} else if (custom && tf->command == ATA_CMD_INIT_DEV_PARAMS) {
if ((stat & (ATA_ERR | ATA_DRQ)) == 0) {
ide_set_handler(drive, &task_no_data_intr,
- WAIT_WORSTCASE, NULL);
+ WAIT_WORSTCASE);
return ide_started;
}
}
return ide_error(drive, "task_no_data_intr", stat);
- /* calls ide_end_drive_cmd */
}
- if (!custom)
- ide_end_drive_cmd(drive, stat, ide_read_error(drive));
- else if (tf->command == ATA_CMD_IDLEIMMEDIATE) {
- hwif->tp_ops->tf_read(drive, task);
- if (tf->lbal != 0xc4) {
- printk(KERN_ERR "%s: head unload failed!\n",
- drive->name);
- ide_tf_dump(drive->name, tf);
- } else
- drive->dev_flags |= IDE_DFLAG_PARKED;
- ide_end_drive_cmd(drive, stat, ide_read_error(drive));
- } else if (tf->command == ATA_CMD_SET_MULTI)
+ if (custom && tf->command == ATA_CMD_SET_MULTI)
drive->mult_count = drive->mult_req;
+ if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE ||
+ tf->command == ATA_CMD_CHK_POWER) {
+ struct request *rq = hwif->rq;
+
+ if (blk_pm_request(rq))
+ ide_complete_pm_rq(drive, rq);
+ else
+ ide_finish_cmd(drive, cmd, stat);
+ }
+
return ide_stopped;
}
@@ -192,239 +192,188 @@ static u8 wait_drive_not_busy(ide_drive_t *drive)
return stat;
}
-static void ide_pio_sector(ide_drive_t *drive, struct request *rq,
- unsigned int write)
+void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd,
+ unsigned int write, unsigned int len)
{
ide_hwif_t *hwif = drive->hwif;
struct scatterlist *sg = hwif->sg_table;
- struct scatterlist *cursg = hwif->cursg;
+ struct scatterlist *cursg = cmd->cursg;
struct page *page;
-#ifdef CONFIG_HIGHMEM
unsigned long flags;
-#endif
unsigned int offset;
u8 *buf;
- cursg = hwif->cursg;
- if (!cursg) {
- cursg = sg;
- hwif->cursg = sg;
- }
+ cursg = cmd->cursg;
+ if (cursg == NULL)
+ cursg = cmd->cursg = sg;
- page = sg_page(cursg);
- offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
+ while (len) {
+ unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs);
- /* get the current page and offset */
- page = nth_page(page, (offset >> PAGE_SHIFT));
- offset %= PAGE_SIZE;
+ if (nr_bytes > PAGE_SIZE)
+ nr_bytes = PAGE_SIZE;
-#ifdef CONFIG_HIGHMEM
- local_irq_save(flags);
-#endif
- buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
+ page = sg_page(cursg);
+ offset = cursg->offset + cmd->cursg_ofs;
- hwif->nleft--;
- hwif->cursg_ofs++;
+ /* get the current page and offset */
+ page = nth_page(page, (offset >> PAGE_SHIFT));
+ offset %= PAGE_SIZE;
- if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
- hwif->cursg = sg_next(hwif->cursg);
- hwif->cursg_ofs = 0;
- }
+ if (PageHighMem(page))
+ local_irq_save(flags);
- /* do the actual data transfer */
- if (write)
- hwif->tp_ops->output_data(drive, rq, buf, SECTOR_SIZE);
- else
- hwif->tp_ops->input_data(drive, rq, buf, SECTOR_SIZE);
+ buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset;
- kunmap_atomic(buf, KM_BIO_SRC_IRQ);
-#ifdef CONFIG_HIGHMEM
- local_irq_restore(flags);
-#endif
-}
+ cmd->nleft -= nr_bytes;
+ cmd->cursg_ofs += nr_bytes;
-static void ide_pio_multi(ide_drive_t *drive, struct request *rq,
- unsigned int write)
-{
- unsigned int nsect;
+ if (cmd->cursg_ofs == cursg->length) {
+ cursg = cmd->cursg = sg_next(cmd->cursg);
+ cmd->cursg_ofs = 0;
+ }
+
+ /* do the actual data transfer */
+ if (write)
+ hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes);
+ else
+ hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes);
+
+ kunmap_atomic(buf, KM_BIO_SRC_IRQ);
+
+ if (PageHighMem(page))
+ local_irq_restore(flags);
- nsect = min_t(unsigned int, drive->hwif->nleft, drive->mult_count);
- while (nsect--)
- ide_pio_sector(drive, rq, write);
+ len -= nr_bytes;
+ }
}
+EXPORT_SYMBOL_GPL(ide_pio_bytes);
-static void ide_pio_datablock(ide_drive_t *drive, struct request *rq,
- unsigned int write)
+static void ide_pio_datablock(ide_drive_t *drive, struct ide_cmd *cmd,
+ unsigned int write)
{
- u8 saved_io_32bit = drive->io_32bit;
+ unsigned int nr_bytes;
- if (rq->bio) /* fs request */
- rq->errors = 0;
+ u8 saved_io_32bit = drive->io_32bit;
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- ide_task_t *task = rq->special;
+ if (cmd->tf_flags & IDE_TFLAG_FS)
+ cmd->rq->errors = 0;
- if (task->tf_flags & IDE_TFLAG_IO_16BIT)
- drive->io_32bit = 0;
- }
+ if (cmd->tf_flags & IDE_TFLAG_IO_16BIT)
+ drive->io_32bit = 0;
touch_softlockup_watchdog();
- switch (drive->hwif->data_phase) {
- case TASKFILE_MULTI_IN:
- case TASKFILE_MULTI_OUT:
- ide_pio_multi(drive, rq, write);
- break;
- default:
- ide_pio_sector(drive, rq, write);
- break;
- }
+ if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+ nr_bytes = min_t(unsigned, cmd->nleft, drive->mult_count << 9);
+ else
+ nr_bytes = SECTOR_SIZE;
+
+ ide_pio_bytes(drive, cmd, write, nr_bytes);
drive->io_32bit = saved_io_32bit;
}
-static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
- const char *s, u8 stat)
+static void ide_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
- if (rq->bio) {
- ide_hwif_t *hwif = drive->hwif;
- int sectors = hwif->nsect - hwif->nleft;
-
- switch (hwif->data_phase) {
- case TASKFILE_IN:
- if (hwif->nleft)
- break;
- /* fall through */
- case TASKFILE_OUT:
- sectors--;
- break;
- case TASKFILE_MULTI_IN:
- if (hwif->nleft)
- break;
- /* fall through */
- case TASKFILE_MULTI_OUT:
- sectors -= drive->mult_count;
- default:
- break;
+ if (cmd->tf_flags & IDE_TFLAG_FS) {
+ int nr_bytes = cmd->nbytes - cmd->nleft;
+
+ if (cmd->protocol == ATA_PROT_PIO &&
+ ((cmd->tf_flags & IDE_TFLAG_WRITE) || cmd->nleft == 0)) {
+ if (cmd->tf_flags & IDE_TFLAG_MULTI_PIO)
+ nr_bytes -= drive->mult_count << 9;
+ else
+ nr_bytes -= SECTOR_SIZE;
}
- if (sectors > 0) {
- struct ide_driver *drv;
-
- drv = *(struct ide_driver **)rq->rq_disk->private_data;
- drv->end_request(drive, 1, sectors);
- }
+ if (nr_bytes > 0)
+ ide_complete_rq(drive, 0, nr_bytes);
}
- return ide_error(drive, s, stat);
}
-void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
+void ide_finish_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat)
{
- if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
- u8 err = ide_read_error(drive);
-
- ide_end_drive_cmd(drive, stat, err);
- return;
- }
-
- if (rq->rq_disk) {
- struct ide_driver *drv;
+ struct request *rq = drive->hwif->rq;
+ u8 err = ide_read_error(drive);
- drv = *(struct ide_driver **)rq->rq_disk->private_data;;
- drv->end_request(drive, 1, rq->nr_sectors);
- } else
- ide_end_request(drive, 1, rq->nr_sectors);
+ ide_complete_cmd(drive, cmd, stat, err);
+ rq->errors = err;
+ ide_complete_rq(drive, err ? -EIO : 0, blk_rq_bytes(rq));
}
/*
- * We got an interrupt on a task_in case, but no errors and no DRQ.
- *
- * It might be a spurious irq (shared irq), but it might be a
- * command that had no output.
+ * Handler for command with PIO data phase.
*/
-static ide_startstop_t task_in_unexpected(ide_drive_t *drive, struct request *rq, u8 stat)
-{
- /* Command all done? */
- if (OK_STAT(stat, ATA_DRDY, ATA_BUSY)) {
- task_end_request(drive, rq, stat);
- return ide_stopped;
- }
-
- /* Assume it was a spurious irq */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
- return ide_started;
-}
-
-/*
- * Handler for command with PIO data-in phase (Read/Read Multiple).
- */
-static ide_startstop_t task_in_intr(ide_drive_t *drive)
+static ide_startstop_t task_pio_intr(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
+ struct ide_cmd *cmd = &drive->hwif->cmd;
u8 stat = hwif->tp_ops->read_status(hwif);
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- /* Error? */
- if (stat & ATA_ERR)
- return task_error(drive, rq, __func__, stat);
+ if (write == 0) {
+ /* Error? */
+ if (stat & ATA_ERR)
+ goto out_err;
- /* Didn't want any data? Odd. */
- if ((stat & ATA_DRQ) == 0)
- return task_in_unexpected(drive, rq, stat);
+ /* Didn't want any data? Odd. */
+ if ((stat & ATA_DRQ) == 0) {
+ /* Command all done? */
+ if (OK_STAT(stat, ATA_DRDY, ATA_BUSY))
+ goto out_end;
- ide_pio_datablock(drive, rq, 0);
+ /* Assume it was a spurious irq */
+ goto out_wait;
+ }
+ } else {
+ if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
+ goto out_err;
- /* Are we done? Check status and finish transfer. */
- if (!hwif->nleft) {
- stat = wait_drive_not_busy(drive);
- if (!OK_STAT(stat, 0, BAD_STAT))
- return task_error(drive, rq, __func__, stat);
- task_end_request(drive, rq, stat);
- return ide_stopped;
+ /* Deal with unexpected ATA data phase. */
+ if (((stat & ATA_DRQ) == 0) ^ (cmd->nleft == 0))
+ goto out_err;
}
- /* Still data left to transfer. */
- ide_set_handler(drive, &task_in_intr, WAIT_WORSTCASE, NULL);
-
- return ide_started;
-}
-
-/*
- * Handler for command with PIO data-out phase (Write/Write Multiple).
- */
-static ide_startstop_t task_out_intr (ide_drive_t *drive)
-{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- u8 stat = hwif->tp_ops->read_status(hwif);
+ if (write && cmd->nleft == 0)
+ goto out_end;
- if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat))
- return task_error(drive, rq, __func__, stat);
+ /* Still data left to transfer. */
+ ide_pio_datablock(drive, cmd, write);
- /* Deal with unexpected ATA data phase. */
- if (((stat & ATA_DRQ) == 0) ^ !hwif->nleft)
- return task_error(drive, rq, __func__, stat);
+ /* Are we done? Check status and finish transfer. */
+ if (write == 0 && cmd->nleft == 0) {
+ stat = wait_drive_not_busy(drive);
+ if (!OK_STAT(stat, 0, BAD_STAT))
+ goto out_err;
- if (!hwif->nleft) {
- task_end_request(drive, rq, stat);
- return ide_stopped;
+ goto out_end;
}
-
+out_wait:
/* Still data left to transfer. */
- ide_pio_datablock(drive, rq, 1);
- ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
-
+ ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
return ide_started;
+out_end:
+ if ((cmd->tf_flags & IDE_TFLAG_FS) == 0)
+ ide_finish_cmd(drive, cmd, stat);
+ else
+ ide_complete_rq(drive, 0, cmd->rq->nr_sectors << 9);
+ return ide_stopped;
+out_err:
+ ide_error_cmd(drive, cmd);
+ return ide_error(drive, __func__, stat);
}
-static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
+static ide_startstop_t pre_task_out_intr(ide_drive_t *drive,
+ struct ide_cmd *cmd)
{
ide_startstop_t startstop;
if (ide_wait_stat(&startstop, drive, ATA_DRQ,
drive->bad_wstat, WAIT_DRQ)) {
printk(KERN_ERR "%s: no DRQ after issuing %sWRITE%s\n",
- drive->name, drive->hwif->data_phase ? "MULT" : "",
+ drive->name,
+ (cmd->tf_flags & IDE_TFLAG_MULTI_PIO) ? "MULT" : "",
(drive->dev_flags & IDE_DFLAG_LBA48) ? "_EXT" : "");
return startstop;
}
@@ -432,13 +381,15 @@ static ide_startstop_t pre_task_out_intr(ide_drive_t *drive, struct request *rq)
if ((drive->dev_flags & IDE_DFLAG_UNMASK) == 0)
local_irq_disable();
- ide_set_handler(drive, &task_out_intr, WAIT_WORSTCASE, NULL);
- ide_pio_datablock(drive, rq, 1);
+ ide_set_handler(drive, &task_pio_intr, WAIT_WORSTCASE);
+
+ ide_pio_datablock(drive, cmd, 1);
return ide_started;
}
-int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
+int ide_raw_taskfile(ide_drive_t *drive, struct ide_cmd *cmd, u8 *buf,
+ u16 nsect)
{
struct request *rq;
int error;
@@ -456,11 +407,11 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
rq->hard_nr_sectors = rq->nr_sectors = nsect;
rq->hard_cur_sectors = rq->current_nr_sectors = nsect;
- if (task->tf_flags & IDE_TFLAG_WRITE)
+ if (cmd->tf_flags & IDE_TFLAG_WRITE)
rq->cmd_flags |= REQ_RW;
- rq->special = task;
- task->rq = rq;
+ rq->special = cmd;
+ cmd->rq = rq;
error = blk_execute_rq(drive->queue, NULL, rq, 0);
blk_put_request(rq);
@@ -470,19 +421,19 @@ int ide_raw_taskfile(ide_drive_t *drive, ide_task_t *task, u8 *buf, u16 nsect)
EXPORT_SYMBOL(ide_raw_taskfile);
-int ide_no_data_taskfile(ide_drive_t *drive, ide_task_t *task)
+int ide_no_data_taskfile(ide_drive_t *drive, struct ide_cmd *cmd)
{
- task->data_phase = TASKFILE_NO_DATA;
+ cmd->protocol = ATA_PROT_NODATA;
- return ide_raw_taskfile(drive, task, NULL, 0);
+ return ide_raw_taskfile(drive, cmd, NULL, 0);
}
EXPORT_SYMBOL_GPL(ide_no_data_taskfile);
#ifdef CONFIG_IDE_TASK_IOCTL
-int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
+int ide_taskfile_ioctl(ide_drive_t *drive, unsigned long arg)
{
ide_task_request_t *req_task;
- ide_task_t args;
+ struct ide_cmd cmd;
u8 *outbuf = NULL;
u8 *inbuf = NULL;
u8 *data_buf = NULL;
@@ -536,53 +487,63 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
}
}
- memset(&args, 0, sizeof(ide_task_t));
+ memset(&cmd, 0, sizeof(cmd));
- memcpy(&args.tf_array[0], req_task->hob_ports, HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(&args.tf_array[6], req_task->io_ports, HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(&cmd.tf_array[0], req_task->hob_ports,
+ HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(&cmd.tf_array[6], req_task->io_ports,
+ HDIO_DRIVE_TASK_HDR_SIZE);
- args.data_phase = req_task->data_phase;
+ cmd.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
+ IDE_TFLAG_IN_TF;
- args.tf_flags = IDE_TFLAG_IO_16BIT | IDE_TFLAG_DEVICE |
- IDE_TFLAG_IN_TF;
if (drive->dev_flags & IDE_DFLAG_LBA48)
- args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
+ cmd.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_IN_HOB);
if (req_task->out_flags.all) {
- args.tf_flags |= IDE_TFLAG_FLAGGED;
+ cmd.ftf_flags |= IDE_FTFLAG_FLAGGED;
if (req_task->out_flags.b.data)
- args.tf_flags |= IDE_TFLAG_OUT_DATA;
+ cmd.ftf_flags |= IDE_FTFLAG_OUT_DATA;
if (req_task->out_flags.b.nsector_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_NSECT;
if (req_task->out_flags.b.sector_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAL;
if (req_task->out_flags.b.lcyl_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAM;
if (req_task->out_flags.b.hcyl_hob)
- args.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB_LBAH;
if (req_task->out_flags.b.error_feature)
- args.tf_flags |= IDE_TFLAG_OUT_FEATURE;
+ cmd.tf_flags |= IDE_TFLAG_OUT_FEATURE;
if (req_task->out_flags.b.nsector)
- args.tf_flags |= IDE_TFLAG_OUT_NSECT;
+ cmd.tf_flags |= IDE_TFLAG_OUT_NSECT;
if (req_task->out_flags.b.sector)
- args.tf_flags |= IDE_TFLAG_OUT_LBAL;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAL;
if (req_task->out_flags.b.lcyl)
- args.tf_flags |= IDE_TFLAG_OUT_LBAM;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAM;
if (req_task->out_flags.b.hcyl)
- args.tf_flags |= IDE_TFLAG_OUT_LBAH;
+ cmd.tf_flags |= IDE_TFLAG_OUT_LBAH;
} else {
- args.tf_flags |= IDE_TFLAG_OUT_TF;
- if (args.tf_flags & IDE_TFLAG_LBA48)
- args.tf_flags |= IDE_TFLAG_OUT_HOB;
+ cmd.tf_flags |= IDE_TFLAG_OUT_TF;
+ if (cmd.tf_flags & IDE_TFLAG_LBA48)
+ cmd.tf_flags |= IDE_TFLAG_OUT_HOB;
}
if (req_task->in_flags.b.data)
- args.tf_flags |= IDE_TFLAG_IN_DATA;
+ cmd.ftf_flags |= IDE_FTFLAG_IN_DATA;
+
+ if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE) {
+ /* fixup data phase if needed */
+ if (req_task->data_phase == TASKFILE_IN_DMAQ ||
+ req_task->data_phase == TASKFILE_IN_DMA)
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
+ }
- switch(req_task->data_phase) {
+ cmd.protocol = ATA_PROT_DMA;
+
+ switch (req_task->data_phase) {
case TASKFILE_MULTI_OUT:
if (!drive->mult_count) {
/* (hs): give up if multcount is not set */
@@ -592,11 +553,14 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
err = -EPERM;
goto abort;
}
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_OUT:
+ cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_OUT_DMAQ:
case TASKFILE_OUT_DMA:
+ cmd.tf_flags |= IDE_TFLAG_WRITE;
nsect = taskout / SECTOR_SIZE;
data_buf = outbuf;
break;
@@ -609,8 +573,10 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
err = -EPERM;
goto abort;
}
+ cmd.tf_flags |= IDE_TFLAG_MULTI_PIO;
/* fall through */
case TASKFILE_IN:
+ cmd.protocol = ATA_PROT_PIO;
/* fall through */
case TASKFILE_IN_DMAQ:
case TASKFILE_IN_DMA:
@@ -618,6 +584,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
data_buf = inbuf;
break;
case TASKFILE_NO_DATA:
+ cmd.protocol = ATA_PROT_NODATA;
break;
default:
err = -EFAULT;
@@ -627,7 +594,7 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
if (req_task->req_cmd == IDE_DRIVE_TASK_NO_DATA)
nsect = 0;
else if (!nsect) {
- nsect = (args.tf.hob_nsect << 8) | args.tf.nsect;
+ nsect = (cmd.tf.hob_nsect << 8) | cmd.tf.nsect;
if (!nsect) {
printk(KERN_ERR "%s: in/out command without data\n",
@@ -637,15 +604,14 @@ int ide_taskfile_ioctl (ide_drive_t *drive, unsigned int cmd, unsigned long arg)
}
}
- if (req_task->req_cmd == IDE_DRIVE_TASK_RAW_WRITE)
- args.tf_flags |= IDE_TFLAG_WRITE;
-
- err = ide_raw_taskfile(drive, &args, data_buf, nsect);
+ err = ide_raw_taskfile(drive, &cmd, data_buf, nsect);
- memcpy(req_task->hob_ports, &args.tf_array[0], HDIO_DRIVE_HOB_HDR_SIZE - 2);
- memcpy(req_task->io_ports, &args.tf_array[6], HDIO_DRIVE_TASK_HDR_SIZE);
+ memcpy(req_task->hob_ports, &cmd.tf_array[0],
+ HDIO_DRIVE_HOB_HDR_SIZE - 2);
+ memcpy(req_task->io_ports, &cmd.tf_array[6],
+ HDIO_DRIVE_TASK_HDR_SIZE);
- if ((args.tf_flags & IDE_TFLAG_FLAGGED_SET_IN_FLAGS) &&
+ if ((cmd.ftf_flags & IDE_FTFLAG_SET_IN_FLAGS) &&
req_task->in_flags.all == 0) {
req_task->in_flags.all = IDE_TASKFILE_STD_IN_FLAGS;
if (drive->dev_flags & IDE_DFLAG_LBA48)
diff --git a/drivers/ide/ide-timings.c b/drivers/ide/ide-timings.c
index 81f527af8fa..001a56365be 100644
--- a/drivers/ide/ide-timings.c
+++ b/drivers/ide/ide-timings.c
@@ -43,6 +43,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_UDMA_1, 0, 0, 0, 0, 0, 0, 0, 80 },
{ XFER_UDMA_0, 0, 0, 0, 0, 0, 0, 0, 120 },
+ { XFER_MW_DMA_4, 25, 0, 0, 0, 55, 20, 80, 0 },
+ { XFER_MW_DMA_3, 25, 0, 0, 0, 65, 25, 100, 0 },
{ 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 },
@@ -51,7 +53,8 @@ static struct ide_timing ide_timing[] = {
{ XFER_SW_DMA_1, 90, 0, 0, 0, 240, 240, 480, 0 },
{ XFER_SW_DMA_0, 120, 0, 0, 0, 480, 480, 960, 0 },
- { XFER_PIO_5, 20, 50, 30, 100, 50, 30, 100, 0 },
+ { XFER_PIO_6, 10, 55, 20, 80, 55, 20, 80, 0 },
+ { XFER_PIO_5, 15, 65, 25, 100, 65, 25, 100, 0 },
{ XFER_PIO_4, 25, 70, 25, 120, 70, 25, 120, 0 },
{ XFER_PIO_3, 30, 80, 70, 180, 80, 70, 180, 0 },
@@ -90,6 +93,10 @@ u16 ide_pio_cycle_time(ide_drive_t *drive, u8 pio)
/* conservative "downgrade" for all pre-ATA2 drives */
if (pio < 3 && cycle < t->cycle)
cycle = 0; /* use standard timing */
+
+ /* Use the standard timing for the CF specific modes too */
+ if (pio > 4 && ata_id_is_cfa(id))
+ cycle = 0;
}
return cycle ? cycle : t->cycle;
@@ -161,7 +168,8 @@ int ide_timing_compute(ide_drive_t *drive, u8 speed,
if (speed <= XFER_PIO_2)
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO];
- else if (speed <= XFER_PIO_5)
+ else if ((speed <= XFER_PIO_4) ||
+ (speed == XFER_PIO_5 && !ata_id_is_cfa(id)))
p.cycle = p.cyc8b = id[ATA_ID_EIDE_PIO_IORDY];
else if (speed >= XFER_MW_DMA_0 && speed <= XFER_MW_DMA_2)
p.cycle = id[ATA_ID_EIDE_DMA_MIN];
diff --git a/drivers/ide/ide-xfer-mode.c b/drivers/ide/ide-xfer-mode.c
index 6910f6a257e..af44be9d546 100644
--- a/drivers/ide/ide-xfer-mode.c
+++ b/drivers/ide/ide-xfer-mode.c
@@ -9,11 +9,11 @@ static const char *udma_str[] =
{ "UDMA/16", "UDMA/25", "UDMA/33", "UDMA/44",
"UDMA/66", "UDMA/100", "UDMA/133", "UDMA7" };
static const char *mwdma_str[] =
- { "MWDMA0", "MWDMA1", "MWDMA2" };
+ { "MWDMA0", "MWDMA1", "MWDMA2", "MWDMA3", "MWDMA4" };
static const char *swdma_str[] =
{ "SWDMA0", "SWDMA1", "SWDMA2" };
static const char *pio_str[] =
- { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5" };
+ { "PIO0", "PIO1", "PIO2", "PIO3", "PIO4", "PIO5", "PIO6" };
/**
* ide_xfer_verbose - return IDE mode names
@@ -30,11 +30,11 @@ const char *ide_xfer_verbose(u8 mode)
if (mode >= XFER_UDMA_0 && mode <= XFER_UDMA_7)
s = udma_str[i];
- else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_2)
+ else if (mode >= XFER_MW_DMA_0 && mode <= XFER_MW_DMA_4)
s = mwdma_str[i];
else if (mode >= XFER_SW_DMA_0 && mode <= XFER_SW_DMA_2)
s = swdma_str[i];
- else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_5)
+ else if (mode >= XFER_PIO_0 && mode <= XFER_PIO_6)
s = pio_str[i & 0x7];
else if (mode == XFER_PIO_SLOW)
s = "PIO SLOW";
@@ -79,7 +79,10 @@ u8 ide_get_best_pio_mode(ide_drive_t *drive, u8 mode_wanted, u8 max_mode)
}
if (id[ATA_ID_FIELD_VALID] & 2) { /* ATA2? */
- if (ata_id_has_iordy(id)) {
+ if (ata_id_is_cfa(id) && (id[ATA_ID_CFA_MODES] & 7))
+ pio_mode = 4 + min_t(int, 2,
+ id[ATA_ID_CFA_MODES] & 7);
+ else if (ata_id_has_iordy(id)) {
if (id[ATA_ID_PIO_MODES] & 7) {
overridden = 0;
if (id[ATA_ID_PIO_MODES] & 4)
@@ -239,7 +242,7 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
BUG_ON(rate < XFER_PIO_0);
- if (rate >= XFER_PIO_0 && rate <= XFER_PIO_5)
+ if (rate >= XFER_PIO_0 && rate <= XFER_PIO_6)
return ide_set_pio_mode(drive, rate);
return ide_set_dma_mode(drive, rate);
diff --git a/drivers/ide/ide_arm.c b/drivers/ide/ide_arm.c
deleted file mode 100644
index bdcac94d7c1..00000000000
--- a/drivers/ide/ide_arm.c
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * ARM default IDE host driver
- *
- * Copyright (C) 2004 Bartlomiej Zolnierkiewicz
- * Based on code by: Russell King, Ian Molton and Alexander Schulz.
- *
- * May be copied or modified under the terms of the GNU General Public License.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/ide.h>
-
-#include <asm/irq.h>
-
-#define DRV_NAME "ide_arm"
-
-#define IDE_ARM_IO 0x1f0
-#define IDE_ARM_IRQ IRQ_HARDDISK
-
-static int __init ide_arm_init(void)
-{
- unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206;
- hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
-
- if (!request_region(base, 8, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
- DRV_NAME, base, base + 7);
- return -EBUSY;
- }
-
- if (!request_region(ctl, 1, DRV_NAME)) {
- printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
- DRV_NAME, ctl);
- release_region(base, 8);
- return -EBUSY;
- }
-
- memset(&hw, 0, sizeof(hw));
- ide_std_init_ports(&hw, base, ctl);
- hw.irq = IDE_ARM_IRQ;
- hw.chipset = ide_generic;
-
- return ide_host_add(NULL, hws, NULL);
-}
-
-module_init(ide_arm_init);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/ide/it821x.c b/drivers/ide/it821x.c
index 6b9fc950b4a..51aa745246d 100644
--- a/drivers/ide/it821x.c
+++ b/drivers/ide/it821x.c
@@ -508,12 +508,11 @@ static void it821x_quirkproc(ide_drive_t *drive)
static struct ide_dma_ops it821x_pass_through_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = it821x_dma_start,
.dma_end = it821x_dma_end,
.dma_test_irq = ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = ide_dma_lost_irq,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/macide.c b/drivers/ide/macide.c
index 3c60064f1d4..4b1718e8328 100644
--- a/drivers/ide/macide.c
+++ b/drivers/ide/macide.c
@@ -80,6 +80,11 @@ static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
+static const struct ide_port_info macide_port_info = {
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
+};
+
static const char *mac_ide_name[] =
{ "Quadra", "Powerbook", "Powerbook Baboon" };
@@ -122,7 +127,7 @@ static int __init macide_init(void)
macide_setup_ports(&hw, base, irq, ack_intr);
- return ide_host_add(NULL, hws, NULL);
+ return ide_host_add(&macide_port_info, hws, NULL);
}
module_init(macide_init);
diff --git a/drivers/ide/ns87415.c b/drivers/ide/ns87415.c
index ea48a3ee806..71a39fb3856 100644
--- a/drivers/ide/ns87415.c
+++ b/drivers/ide/ns87415.c
@@ -61,57 +61,52 @@ static u8 superio_dma_sff_read_status(ide_hwif_t *hwif)
return superio_ide_inb(hwif->dma_base + ATA_DMA_STATUS);
}
-static void superio_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void superio_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data = inw(io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = superio_ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = inb(io_ports->lbah_addr);
}
}
+static void ns87415_dev_select(ide_drive_t *drive);
+
static const struct ide_tp_ops superio_tp_ops = {
.exec_command = ide_exec_command,
.read_status = superio_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ns87415_dev_select,
.tf_load = ide_tf_load,
.tf_read = superio_tf_read,
@@ -190,10 +185,18 @@ static void ns87415_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
-static void ns87415_selectproc (ide_drive_t *drive)
+static void ns87415_dev_select(ide_drive_t *drive)
{
ns87415_prepare_drive(drive,
!!(drive->dev_flags & IDE_DFLAG_USING_DMA));
+
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
+}
+
+static void ns87415_dma_start(ide_drive_t *drive)
+{
+ ns87415_prepare_drive(drive, 1);
+ ide_dma_start(drive);
}
static int ns87415_dma_end(ide_drive_t *drive)
@@ -201,7 +204,6 @@ static int ns87415_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat = 0, dma_cmd = 0;
- drive->waiting_for_dma = 0;
dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
/* get DMA command mode */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
@@ -210,21 +212,11 @@ static int ns87415_dma_end(ide_drive_t *drive)
/* from ERRATA: clear the INTR & ERROR bits */
dma_cmd = inb(hwif->dma_base + ATA_DMA_CMD);
outb(dma_cmd | 6, hwif->dma_base + ATA_DMA_CMD);
- /* and free any DMA resources */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
- return (dma_stat & 7) != 4;
-}
-static int ns87415_dma_setup(ide_drive_t *drive)
-{
- /* select DMA xfer */
- ns87415_prepare_drive(drive, 1);
- if (!ide_dma_setup(drive))
- return 0;
- /* DMA failed: select PIO xfer */
ns87415_prepare_drive(drive, 0);
- return 1;
+
+ /* verify good DMA status */
+ return (dma_stat & 7) != 4;
}
static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
@@ -242,7 +234,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
* Also, leave IRQ masked during drive probing, to prevent infinite
* interrupts from a potentially floating INTA..
*
- * IRQs get unmasked in selectproc when drive is first used.
+ * IRQs get unmasked in dev_select() when drive is first used.
*/
(void) pci_read_config_dword(dev, 0x40, &ctrl);
(void) pci_read_config_byte(dev, 0x09, &progif);
@@ -270,7 +262,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
#ifdef __sparc_v9__
/*
* XXX: Reset the device, if we don't it will not respond to
- * SELECT_DRIVE() properly during first ide_probe_port().
+ * dev_select() properly during first ide_probe_port().
*/
timeout = 10000;
outb(12, hwif->io_ports.ctl_addr);
@@ -294,26 +286,35 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
outb(0x60, hwif->dma_base + ATA_DMA_STATUS);
}
-static const struct ide_port_ops ns87415_port_ops = {
- .selectproc = ns87415_selectproc,
+static const struct ide_tp_ops ns87415_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = ns87415_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static const struct ide_dma_ops ns87415_dma_ops = {
.dma_host_set = ide_dma_host_set,
- .dma_setup = ns87415_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
- .dma_start = ide_dma_start,
+ .dma_setup = ide_dma_setup,
+ .dma_start = ns87415_dma_start,
.dma_end = ns87415_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = superio_dma_sff_read_status,
};
static const struct ide_port_info ns87415_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_ns87415,
- .port_ops = &ns87415_port_ops,
+ .tp_ops = &ns87415_tp_ops,
.dma_ops = &ns87415_dma_ops,
.host_flags = IDE_HFLAG_TRUST_BIOS_FOR_DMA |
IDE_HFLAG_NO_ATAPI_DMA,
diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c
index f38aac78044..c7acca0b873 100644
--- a/drivers/ide/palm_bk3710.c
+++ b/drivers/ide/palm_bk3710.c
@@ -347,7 +347,7 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
struct clk *clk;
struct resource *mem, *irq;
void __iomem *base;
- unsigned long rate;
+ unsigned long rate, mem_size;
int i, rc;
hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL };
@@ -374,13 +374,18 @@ static int __init palm_bk3710_probe(struct platform_device *pdev)
return -ENODEV;
}
- if (request_mem_region(mem->start, mem->end - mem->start + 1,
- "palm_bk3710") == NULL) {
+ mem_size = mem->end - mem->start + 1;
+ if (request_mem_region(mem->start, mem_size, "palm_bk3710") == NULL) {
printk(KERN_ERR "failed to request memory region\n");
return -EBUSY;
}
- base = IO_ADDRESS(mem->start);
+ base = ioremap(mem->start, mem_size);
+ if (!base) {
+ printk(KERN_ERR "failed to map IO memory\n");
+ release_mem_region(mem->start, mem_size);
+ return -ENOMEM;
+ }
/* Configure the Palm Chip controller */
palm_bk3710_chipinit(base);
diff --git a/drivers/ide/pdc202xx_old.c b/drivers/ide/pdc202xx_old.c
index cba66ebce4e..248a54bd238 100644
--- a/drivers/ide/pdc202xx_old.c
+++ b/drivers/ide/pdc202xx_old.c
@@ -258,12 +258,6 @@ static void pdc202xx_dma_lost_irq(ide_drive_t *drive)
ide_dma_lost_irq(drive);
}
-static void pdc202xx_dma_timeout(ide_drive_t *drive)
-{
- pdc202xx_reset(drive);
- ide_dma_timeout(drive);
-}
-
static int init_chipset_pdc202xx(struct pci_dev *dev)
{
unsigned long dmabase = pci_resource_start(dev, 4);
@@ -331,24 +325,24 @@ static const struct ide_port_ops pdc2026x_port_ops = {
static const struct ide_dma_ops pdc20246_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
static const struct ide_dma_ops pdc2026x_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = pdc202xx_dma_start,
.dma_end = pdc202xx_dma_end,
.dma_test_irq = pdc202xx_dma_test_irq,
.dma_lost_irq = pdc202xx_dma_lost_irq,
- .dma_timeout = pdc202xx_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = pdc202xx_reset,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/pmac.c b/drivers/ide/pmac.c
index 74625e821a4..052b9bf1f8f 100644
--- a/drivers/ide/pmac.c
+++ b/drivers/ide/pmac.c
@@ -404,9 +404,6 @@ kauai_lookup_timing(struct kauai_timing* table, int cycle_time)
#define IDE_WAKEUP_DELAY (1*HZ)
static int pmac_ide_init_dma(ide_hwif_t *, const struct ide_port_info *);
-static int pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq);
-static void pmac_ide_selectproc(ide_drive_t *drive);
-static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
#define PMAC_IDE_REG(x) \
((void __iomem *)((drive)->hwif->io_ports.data_addr + (x)))
@@ -416,8 +413,7 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive);
* timing register when selecting that unit. This version is for
* ASICs with a single timing register
*/
-static void
-pmac_ide_selectproc(ide_drive_t *drive)
+static void pmac_ide_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
@@ -435,8 +431,7 @@ pmac_ide_selectproc(ide_drive_t *drive)
* timing register when selecting that unit. This version is for
* ASICs with a dual timing register (Kauai)
*/
-static void
-pmac_ide_kauai_selectproc(ide_drive_t *drive)
+static void pmac_ide_kauai_apply_timings(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
@@ -465,9 +460,25 @@ pmac_ide_do_update_timings(ide_drive_t *drive)
if (pmif->kind == controller_sh_ata6 ||
pmif->kind == controller_un_ata6 ||
pmif->kind == controller_k2_ata6)
- pmac_ide_kauai_selectproc(drive);
+ pmac_ide_kauai_apply_timings(drive);
else
- pmac_ide_selectproc(drive);
+ pmac_ide_apply_timings(drive);
+}
+
+static void pmac_dev_select(ide_drive_t *drive)
+{
+ pmac_ide_apply_timings(drive);
+
+ writeb(drive->select | ATA_DEVICE_OBS,
+ (void __iomem *)drive->hwif->io_ports.device_addr);
+}
+
+static void pmac_kauai_dev_select(ide_drive_t *drive)
+{
+ pmac_ide_kauai_apply_timings(drive);
+
+ writeb(drive->select | ATA_DEVICE_OBS,
+ (void __iomem *)drive->hwif->io_ports.device_addr);
}
static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
@@ -477,17 +488,8 @@ static void pmac_exec_command(ide_hwif_t *hwif, u8 cmd)
+ IDE_TIMING_CONFIG));
}
-static void pmac_set_irq(ide_hwif_t *hwif, int on)
+static void pmac_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
writeb(ctl, (void __iomem *)hwif->io_ports.ctl_addr);
(void)readl((void __iomem *)(hwif->io_ports.data_addr
+ IDE_TIMING_CONFIG));
@@ -917,10 +919,18 @@ static u8 pmac_ide_cable_detect(ide_hwif_t *hwif)
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct device_node *np = pmif->node;
const char *cable = of_get_property(np, "cable-type", NULL);
+ struct device_node *root = of_find_node_by_path("/");
+ const char *model = of_get_property(root, "model", NULL);
/* Get cable type from device-tree. */
- if (cable && !strncmp(cable, "80-", 3))
- return ATA_CBL_PATA80;
+ if (cable && !strncmp(cable, "80-", 3)) {
+ /* Some drives fail to detect 80c cable in PowerBook */
+ /* These machine use proprietary short IDE cable anyway */
+ if (!strncmp(model, "PowerBook", 9))
+ return ATA_CBL_PATA40_SHORT;
+ else
+ return ATA_CBL_PATA80;
+ }
/*
* G5's seem to have incorrect cable type in device-tree.
@@ -955,9 +965,9 @@ static const struct ide_tp_ops pmac_tp_ops = {
.exec_command = pmac_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = pmac_write_devctl,
- .set_irq = pmac_set_irq,
-
+ .dev_select = pmac_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -965,19 +975,24 @@ static const struct ide_tp_ops pmac_tp_ops = {
.output_data = ide_output_data,
};
-static const struct ide_port_ops pmac_ide_ata6_port_ops = {
- .init_dev = pmac_ide_init_dev,
- .set_pio_mode = pmac_ide_set_pio_mode,
- .set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_kauai_selectproc,
- .cable_detect = pmac_ide_cable_detect,
+static const struct ide_tp_ops pmac_ata6_tp_ops = {
+ .exec_command = pmac_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = pmac_write_devctl,
+
+ .dev_select = pmac_kauai_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static const struct ide_port_ops pmac_ide_ata4_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_selectproc,
.cable_detect = pmac_ide_cable_detect,
};
@@ -985,7 +1000,6 @@ static const struct ide_port_ops pmac_ide_port_ops = {
.init_dev = pmac_ide_init_dev,
.set_pio_mode = pmac_ide_set_pio_mode,
.set_dma_mode = pmac_ide_set_dma_mode,
- .selectproc = pmac_ide_selectproc,
};
static const struct ide_dma_ops pmac_dma_ops;
@@ -1022,15 +1036,18 @@ static int __devinit pmac_ide_setup_device(pmac_ide_hwif_t *pmif, hw_regs_t *hw)
pmif->broken_dma = pmif->broken_dma_warn = 0;
if (of_device_is_compatible(np, "shasta-ata")) {
pmif->kind = controller_sh_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA6;
} else if (of_device_is_compatible(np, "kauai-ata")) {
pmif->kind = controller_un_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "K2-UATA")) {
pmif->kind = controller_k2_ata6;
- d.port_ops = &pmac_ide_ata6_port_ops;
+ d.tp_ops = &pmac_ata6_tp_ops;
+ d.port_ops = &pmac_ide_ata4_port_ops;
d.udma_mask = ATA_UDMA5;
} else if (of_device_is_compatible(np, "keylargo-ata")) {
if (strcmp(np->name, "ata-4") == 0) {
@@ -1422,17 +1439,16 @@ out:
* pmac_ide_build_dmatable builds the DBDMA command list
* for a transfer and sets the DBDMA channel to point to it.
*/
-static int
-pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int pmac_ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
struct dbdma_cmd *table;
- int i, count = 0;
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
struct scatterlist *sg;
- int wr = (rq_data_dir(rq) == WRITE);
+ int wr = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
+ int i = cmd->sg_nents, count = 0;
/* DMA table is already aligned */
table = (struct dbdma_cmd *) pmif->dma_table_cpu;
@@ -1442,11 +1458,6 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
while (readl(&dma->status) & RUN)
udelay(1);
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0;
-
/* Build DBDMA commands list */
sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
@@ -1462,7 +1473,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
"switching to PIO on Ohare chipset\n", drive->name);
pmif->broken_dma_warn = 1;
}
- goto use_pio_instead;
+ return 0;
}
while (cur_len) {
unsigned int tc = (cur_len < 0xfe00)? cur_len: 0xfe00;
@@ -1470,7 +1481,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
if (count++ >= MAX_DCMDS) {
printk(KERN_WARNING "%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
}
st_le16(&table->command, wr? OUTPUT_MORE: INPUT_MORE);
st_le16(&table->req_count, tc);
@@ -1499,9 +1510,6 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
printk(KERN_DEBUG "%s: empty DMA table?\n", drive->name);
-use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
@@ -1509,39 +1517,27 @@ use_pio_instead:
* Prepare a DMA transfer. We build the DMA table, adjust the timings for
* a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
*/
-static int
-pmac_ide_dma_setup(ide_drive_t *drive)
+static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
pmac_ide_hwif_t *pmif =
(pmac_ide_hwif_t *)dev_get_drvdata(hwif->gendev.parent);
- struct request *rq = hwif->rq;
u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (!pmac_ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (pmac_ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* Apple adds 60ns to wrDataSetup on reads */
if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
- writel(pmif->timings[unit] + (!rq_data_dir(rq) ? 0x00800000UL : 0),
+ writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
PMAC_IDE_REG(IDE_TIMING_CONFIG));
(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
}
- drive->waiting_for_dma = 1;
-
return 0;
}
-static void
-pmac_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- /* issue cmd to drive */
- ide_execute_command(drive, command, &ide_dma_intr, 2*WAIT_CMD, NULL);
-}
-
/*
* Kick the DMA controller into life after the DMA command has been issued
* to the drive.
@@ -1573,12 +1569,9 @@ pmac_ide_dma_end (ide_drive_t *drive)
volatile struct dbdma_regs __iomem *dma = pmif->dma_regs;
u32 dstat;
- drive->waiting_for_dma = 0;
dstat = readl(&dma->status);
writel(((RUN|WAKE|DEAD) << 16), &dma->control);
- ide_destroy_dmatable(drive);
-
/* verify good dma status. we don't check for ACTIVE beeing 0. We should...
* in theory, but with ATAPI decices doing buffer underruns, that would
* cause us to disable DMA, which isn't what we want
@@ -1662,11 +1655,9 @@ pmac_ide_dma_lost_irq (ide_drive_t *drive)
static const struct ide_dma_ops pmac_dma_ops = {
.dma_host_set = pmac_ide_dma_host_set,
.dma_setup = pmac_ide_dma_setup,
- .dma_exec_cmd = pmac_ide_dma_exec_cmd,
.dma_start = pmac_ide_dma_start,
.dma_end = pmac_ide_dma_end,
.dma_test_irq = pmac_ide_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
.dma_lost_irq = pmac_ide_dma_lost_irq,
};
diff --git a/drivers/ide/q40ide.c b/drivers/ide/q40ide.c
index 9f9c0b3cc3a..d007e7f6659 100644
--- a/drivers/ide/q40ide.c
+++ b/drivers/ide/q40ide.c
@@ -72,26 +72,26 @@ static void q40_ide_setup_ports(hw_regs_t *hw, unsigned long base,
hw->chipset = ide_generic;
}
-static void q40ide_input_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return insw(data_addr, buf, (len + 1) / 2);
- insw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_insw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
-static void q40ide_output_data(ide_drive_t *drive, struct request *rq,
+static void q40ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
- if (drive->media == ide_disk && rq && rq->cmd_type == REQ_TYPE_FS)
+ if (drive->media == ide_disk && cmd && (cmd->tf_flags & IDE_TFLAG_FS))
return outsw(data_addr, buf, (len + 1) / 2);
- outsw_swapw(data_addr, buf, (len + 1) / 2);
+ raw_outsw_swapw((u16 *)data_addr, buf, (len + 1) / 2);
}
/* Q40 has a byte-swapped IDE interface */
@@ -99,9 +99,9 @@ static const struct ide_tp_ops q40ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -111,7 +111,8 @@ static const struct ide_tp_ops q40ide_tp_ops = {
static const struct ide_port_info q40ide_port_info = {
.tp_ops = &q40ide_tp_ops,
- .host_flags = IDE_HFLAG_NO_DMA,
+ .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
+ .irq_flags = IRQF_SHARED,
};
/*
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index 08c4fa35e9b..c9a13498689 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -90,13 +90,15 @@ static int timings[4]={-1,-1,-1,-1}; /* stores current timing for each timer */
* This routine is invoked to prepare for access to a given drive.
*/
-static void qd65xx_select(ide_drive_t *drive)
+static void qd65xx_dev_select(ide_drive_t *drive)
{
u8 index = (( (QD_TIMREG(drive)) & 0x80 ) >> 7) |
(QD_TIMREG(drive) & 0x02);
if (timings[index] != QD_TIMING(drive))
outb(timings[index] = QD_TIMING(drive), QD_TIMREG(drive));
+
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
/*
@@ -309,20 +311,33 @@ static void __init qd6580_init_dev(ide_drive_t *drive)
drive->drive_data = (drive->dn & 1) ? t2 : t1;
}
+static const struct ide_tp_ops qd65xx_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = qd65xx_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
+};
+
static const struct ide_port_ops qd6500_port_ops = {
.init_dev = qd6500_init_dev,
.set_pio_mode = qd6500_set_pio_mode,
- .selectproc = qd65xx_select,
};
static const struct ide_port_ops qd6580_port_ops = {
.init_dev = qd6580_init_dev,
.set_pio_mode = qd6580_set_pio_mode,
- .selectproc = qd65xx_select,
};
static const struct ide_port_info qd65xx_port_info __initdata = {
.name = DRV_NAME,
+ .tp_ops = &qd65xx_tp_ops,
.chipset = ide_qd65xx,
.host_flags = IDE_HFLAG_IO_32BIT |
IDE_HFLAG_NO_DMA,
diff --git a/drivers/ide/sc1200.c b/drivers/ide/sc1200.c
index dbdd2985a0d..d467478d68d 100644
--- a/drivers/ide/sc1200.c
+++ b/drivers/ide/sc1200.c
@@ -115,8 +115,7 @@ static u8 sc1200_udma_filter(ide_drive_t *drive)
if ((mateid[ATA_ID_FIELD_VALID] & 4) &&
(mateid[ATA_ID_UDMA_MODES] & 7))
goto out;
- if ((mateid[ATA_ID_FIELD_VALID] & 2) &&
- (mateid[ATA_ID_MWDMA_MODES] & 7))
+ if (mateid[ATA_ID_MWDMA_MODES] & 7)
mask = 0;
}
out:
@@ -183,9 +182,6 @@ static int sc1200_dma_end(ide_drive_t *drive)
outb(dma_stat|0x1b, dma_base+2); /* clear the INTR & ERROR bits */
outb(inb(dma_base)&~1, dma_base); /* !! DO THIS HERE !! stop DMA */
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive); /* purge DMA mappings */
-
return (dma_stat & 7) != 4; /* verify good DMA status */
}
@@ -286,12 +282,11 @@ static const struct ide_port_ops sc1200_port_ops = {
static const struct ide_dma_ops sc1200_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = sc1200_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/scc_pata.c b/drivers/ide/scc_pata.c
index 8d2314b6327..6d8dbd9c10b 100644
--- a/drivers/ide/scc_pata.c
+++ b/drivers/ide/scc_pata.c
@@ -148,17 +148,8 @@ static u8 scc_dma_sff_read_status(ide_hwif_t *hwif)
return (u8)in_be32((void *)(hwif->dma_base + 4));
}
-static void scc_set_irq(ide_hwif_t *hwif, int on)
+static void scc_write_devctl(ide_hwif_t *hwif, u8 ctl)
{
- u8 ctl = ATA_DEVCTL_OBS;
-
- if (on == 4) { /* hack for SRST */
- ctl |= 4;
- on &= ~4;
- }
-
- ctl |= on ? 0 : 2;
-
out_be32((void *)hwif->io_ports.ctl_addr, ctl);
eieio();
in_be32((void *)(hwif->dma_base + 0x01c));
@@ -303,8 +294,9 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
}
/**
- * scc_ide_dma_setup - begin a DMA phase
+ * scc_dma_setup - begin a DMA phase
* @drive: target device
+ * @cmd: command
*
* Build an IDE DMA PRD (IDE speak for scatter gather table)
* and then set up the DMA transfer registers.
@@ -313,36 +305,28 @@ static void scc_dma_host_set(ide_drive_t *drive, int on)
* is returned.
*/
-static int scc_dma_setup(ide_drive_t *drive)
+static int scc_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int reading;
+ u32 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
u8 dma_stat;
- if (rq_data_dir(rq))
- reading = 0;
- else
- reading = 1 << 3;
-
/* fall back to pio! */
- if (!ide_build_dmatable(drive, rq)) {
- ide_map_sg(drive, rq);
+ if (ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
out_be32((void __iomem *)(hwif->dma_base + 8), hwif->dmatable_dma);
/* specify r/w */
- out_be32((void __iomem *)hwif->dma_base, reading);
+ out_be32((void __iomem *)hwif->dma_base, rw);
/* read DMA status for INTR & ERROR flags */
dma_stat = scc_dma_sff_read_status(hwif);
/* clear INTR & ERROR flags */
out_be32((void __iomem *)(hwif->dma_base + 4), dma_stat | 6);
- drive->waiting_for_dma = 1;
+
return 0;
}
@@ -361,7 +345,6 @@ static int __scc_dma_end(ide_drive_t *drive)
ide_hwif_t *hwif = drive->hwif;
u8 dma_stat, dma_cmd;
- drive->waiting_for_dma = 0;
/* get DMA command mode */
dma_cmd = scc_ide_inb(hwif->dma_base);
/* stop DMA */
@@ -370,8 +353,6 @@ static int __scc_dma_end(ide_drive_t *drive)
dma_stat = scc_dma_sff_read_status(hwif);
/* clear the INTR & ERROR bits */
scc_ide_outb(dma_stat | 6, hwif->dma_base + 4);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
/* verify good DMA status */
wmb();
return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0;
@@ -666,91 +647,80 @@ static int __devinit init_setup_scc(struct pci_dev *dev,
return rc;
}
-static void scc_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA)
- out_be32((void *)io_ports->data_addr,
- (tf->hob_data << 8) | tf->data);
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
scc_ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
scc_ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
scc_ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
scc_ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
scc_ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
scc_ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
scc_ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void scc_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
struct ide_io_ports *io_ports = &drive->hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data = (u16)in_be32((void *)io_ports->data_addr);
-
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- scc_ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = scc_ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = scc_ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = scc_ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = scc_ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = scc_ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = scc_ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = scc_ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- scc_ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature = scc_ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = scc_ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr);
}
}
-static void scc_input_data(ide_drive_t *drive, struct request *rq,
+static void scc_input_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -766,7 +736,7 @@ static void scc_input_data(ide_drive_t *drive, struct request *rq,
scc_ide_insw(data_addr, buf, len / 2);
}
-static void scc_output_data(ide_drive_t *drive, struct request *rq,
+static void scc_output_data(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long data_addr = drive->hwif->io_ports.data_addr;
@@ -853,9 +823,9 @@ static const struct ide_tp_ops scc_tp_ops = {
.exec_command = scc_exec_command,
.read_status = scc_read_status,
.read_altstatus = scc_read_altstatus,
+ .write_devctl = scc_write_devctl,
- .set_irq = scc_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = scc_tf_load,
.tf_read = scc_tf_read,
@@ -873,30 +843,25 @@ static const struct ide_port_ops scc_port_ops = {
static const struct ide_dma_ops scc_dma_ops = {
.dma_host_set = scc_dma_host_set,
.dma_setup = scc_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = scc_dma_start,
.dma_end = scc_dma_end,
.dma_test_irq = scc_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = scc_dma_sff_read_status,
};
-#define DECLARE_SCC_DEV(name_str) \
- { \
- .name = name_str, \
- .init_iops = init_iops_scc, \
- .init_dma = scc_init_dma, \
- .init_hwif = init_hwif_scc, \
- .tp_ops = &scc_tp_ops, \
- .port_ops = &scc_port_ops, \
- .dma_ops = &scc_dma_ops, \
- .host_flags = IDE_HFLAG_SINGLE, \
- .pio_mask = ATA_PIO4, \
- }
-
-static const struct ide_port_info scc_chipsets[] __devinitdata = {
- /* 0 */ DECLARE_SCC_DEV("sccIDE"),
+static const struct ide_port_info scc_chipset __devinitdata = {
+ .name = "sccIDE",
+ .init_iops = init_iops_scc,
+ .init_dma = scc_init_dma,
+ .init_hwif = init_hwif_scc,
+ .tp_ops = &scc_tp_ops,
+ .port_ops = &scc_port_ops,
+ .dma_ops = &scc_dma_ops,
+ .host_flags = IDE_HFLAG_SINGLE,
+ .irq_flags = IRQF_SHARED,
+ .pio_mask = ATA_PIO4,
};
/**
@@ -910,7 +875,7 @@ static const struct ide_port_info scc_chipsets[] __devinitdata = {
static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
- return init_setup_scc(dev, &scc_chipsets[id->driver_data]);
+ return init_setup_scc(dev, &scc_chipset);
}
/**
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c
index 24bc884826f..a19dbccd761 100644
--- a/drivers/ide/setup-pci.c
+++ b/drivers/ide/setup-pci.c
@@ -558,6 +558,8 @@ int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
host->host_priv = priv;
+ host->irq_flags = IRQF_SHARED;
+
pci_set_drvdata(dev, host);
ret = do_ide_setup_pci_device(dev, d, 1);
@@ -606,6 +608,8 @@ int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
host->host_priv = priv;
+ host->irq_flags = IRQF_SHARED;
+
pci_set_drvdata(pdev[0], host);
pci_set_drvdata(pdev[1], host);
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index fdb9d703769..e5d2a48a84d 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -258,9 +258,6 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
}
}
- drive->waiting_for_dma = 0;
- ide_destroy_dmatable(drive);
-
return dma_stat;
}
@@ -280,10 +277,12 @@ static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
sgiioc4_clearirq(drive);
}
-static void
-sgiioc4_resetproc(ide_drive_t * drive)
+static void sgiioc4_resetproc(ide_drive_t *drive)
{
+ struct ide_cmd *cmd = &drive->hwif->cmd;
+
sgiioc4_dma_end(drive);
+ ide_dma_unmap_sg(drive, cmd);
sgiioc4_clearirq(drive);
}
@@ -412,7 +411,6 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
writel(dma_direction, (void __iomem *)ioc4_dma_addr);
- drive->waiting_for_dma = 1;
}
/* IOC4 Scatter Gather list Format */
@@ -424,20 +422,13 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */
/* --------------------------------------------------------------------- */
/* Creates the scatter gather list, DMA Table */
-static unsigned int
-sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
+static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
unsigned int *table = hwif->dmatable_cpu;
- unsigned int count = 0, i = 1;
- struct scatterlist *sg;
-
- hwif->sg_nents = i = ide_build_sglist(drive, rq);
-
- if (!i)
- return 0; /* sglist of length Zero */
+ unsigned int count = 0, i = cmd->sg_nents;
+ struct scatterlist *sg = hwif->sg_table;
- sg = hwif->sg_table;
while (i && sg_dma_len(sg)) {
dma_addr_t cur_addr;
int cur_len;
@@ -449,7 +440,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
printk(KERN_WARNING
"%s: DMA table too small\n",
drive->name);
- goto use_pio_instead;
+ return 0;
} else {
u32 bcount =
0x10000 - (cur_addr & 0xffff);
@@ -484,30 +475,19 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
return count;
}
-use_pio_instead:
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
-static int sgiioc4_dma_setup(ide_drive_t *drive)
+static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
- struct request *rq = drive->hwif->rq;
- unsigned int count = 0;
int ddir;
+ u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
- if (rq_data_dir(rq))
- ddir = PCI_DMA_TODEVICE;
- else
- ddir = PCI_DMA_FROMDEVICE;
-
- if (!(count = sgiioc4_build_dma_table(drive, rq, ddir))) {
+ if (sgiioc4_build_dmatable(drive, cmd) == 0)
/* try PIO instead of DMA */
- ide_map_sg(drive, rq);
return 1;
- }
- if (rq_data_dir(rq))
+ if (write)
/* Writes TO the IOC4 FROM Main Memory */
ddir = IOC4_DMA_READ;
else
@@ -523,9 +503,9 @@ static const struct ide_tp_ops sgiioc4_tp_ops = {
.exec_command = ide_exec_command,
.read_status = sgiioc4_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = ide_tf_load,
.tf_read = ide_tf_read,
@@ -546,7 +526,6 @@ static const struct ide_dma_ops sgiioc4_dma_ops = {
.dma_end = sgiioc4_dma_end,
.dma_test_irq = sgiioc4_dma_test_irq,
.dma_lost_irq = sgiioc4_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
};
static const struct ide_port_info sgiioc4_port_info __devinitconst = {
@@ -557,6 +536,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = {
.port_ops = &sgiioc4_port_ops,
.dma_ops = &sgiioc4_dma_ops,
.host_flags = IDE_HFLAG_MMIO,
+ .irq_flags = IRQF_SHARED,
.mwdma_mask = ATA_MWDMA2_ONLY,
};
diff --git a/drivers/ide/siimage.c b/drivers/ide/siimage.c
index 1811ae9cd84..e4973cd1fba 100644
--- a/drivers/ide/siimage.c
+++ b/drivers/ide/siimage.c
@@ -711,11 +711,10 @@ static const struct ide_port_ops sil_sata_port_ops = {
static const struct ide_dma_ops sil_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = siimage_dma_test_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_lost_irq = ide_dma_lost_irq,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c
index dba213c51ba..b0a46062533 100644
--- a/drivers/ide/sl82c105.c
+++ b/drivers/ide/sl82c105.c
@@ -61,7 +61,8 @@ static unsigned int get_pio_timings(ide_drive_t *drive, u8 pio)
if (cmd_off == 0)
cmd_off = 1;
- if (pio > 2 || ata_id_has_iordy(drive->id))
+ if ((pio > 2 || ata_id_has_iordy(drive->id)) &&
+ !(pio > 4 && ata_id_is_cfa(drive->id)))
iordy = 0x40;
return (cmd_on - 1) << 8 | (cmd_off - 1) | iordy;
@@ -189,14 +190,13 @@ static void sl82c105_dma_start(ide_drive_t *drive)
ide_dma_start(drive);
}
-static void sl82c105_dma_timeout(ide_drive_t *drive)
+static void sl82c105_dma_clear(ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(drive->hwif->dev);
- DBG(("sl82c105_dma_timeout(drive:%s)\n", drive->name));
+ DBG(("sl82c105_dma_clear(drive:%s)\n", drive->name));
sl82c105_reset_host(dev);
- ide_dma_timeout(drive);
}
static int sl82c105_dma_end(ide_drive_t *drive)
@@ -293,12 +293,12 @@ static const struct ide_port_ops sl82c105_port_ops = {
static const struct ide_dma_ops sl82c105_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = sl82c105_dma_start,
.dma_end = sl82c105_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = sl82c105_dma_lost_irq,
- .dma_timeout = sl82c105_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
+ .dma_clear = sl82c105_dma_clear,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/tc86c001.c b/drivers/ide/tc86c001.c
index 84109f5a163..b4cf42dc8a6 100644
--- a/drivers/ide/tc86c001.c
+++ b/drivers/ide/tc86c001.c
@@ -182,12 +182,11 @@ static const struct ide_port_ops tc86c001_port_ops = {
static const struct ide_dma_ops tc86c001_dma_ops = {
.dma_host_set = ide_dma_host_set,
.dma_setup = ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = tc86c001_dma_start,
.dma_end = ide_dma_end,
.dma_test_irq = ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = ide_dma_sff_read_status,
};
diff --git a/drivers/ide/trm290.c b/drivers/ide/trm290.c
index 1c09e549c42..4b42ca09153 100644
--- a/drivers/ide/trm290.c
+++ b/drivers/ide/trm290.c
@@ -171,58 +171,51 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
local_irq_restore(flags);
}
-static void trm290_selectproc (ide_drive_t *drive)
+static void trm290_dev_select(ide_drive_t *drive)
{
trm290_prepare_drive(drive, !!(drive->dev_flags & IDE_DFLAG_USING_DMA));
-}
-static void trm290_dma_exec_cmd(ide_drive_t *drive, u8 command)
-{
- ide_execute_command(drive, command, &ide_dma_intr, WAIT_CMD, NULL);
+ outb(drive->select | ATA_DEVICE_OBS, drive->hwif->io_ports.device_addr);
}
-static int trm290_dma_setup(ide_drive_t *drive)
+static int trm290_dma_check(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_hwif_t *hwif = drive->hwif;
- struct request *rq = hwif->rq;
- unsigned int count, rw;
-
- if (rq_data_dir(rq)) {
+ if (cmd->tf_flags & IDE_TFLAG_WRITE) {
#ifdef TRM290_NO_DMA_WRITES
/* always use PIO for writes */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
#endif
- rw = 1;
- } else
- rw = 2;
+ }
+ return 0;
+}
+
+static int trm290_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
+{
+ ide_hwif_t *hwif = drive->hwif;
+ unsigned int count, rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 1 : 2;
- if (!(count = ide_build_dmatable(drive, rq))) {
+ count = ide_build_dmatable(drive, cmd);
+ if (count == 0)
/* try PIO instead of DMA */
- trm290_prepare_drive(drive, 0); /* select PIO xfer */
return 1;
- }
- /* select DMA xfer */
- trm290_prepare_drive(drive, 1);
+
outl(hwif->dmatable_dma | rw, hwif->dma_base);
- drive->waiting_for_dma = 1;
/* start DMA */
outw(count * 2 - 1, hwif->dma_base + 2);
+
return 0;
}
static void trm290_dma_start(ide_drive_t *drive)
{
+ trm290_prepare_drive(drive, 1);
}
static int trm290_dma_end(ide_drive_t *drive)
{
- u16 status;
+ u16 status = inw(drive->hwif->dma_base + 2);
- drive->waiting_for_dma = 0;
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- status = inw(drive->hwif->dma_base + 2);
+ trm290_prepare_drive(drive, 0);
return status != 0x00ff;
}
@@ -307,25 +300,34 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
#endif
}
-static const struct ide_port_ops trm290_port_ops = {
- .selectproc = trm290_selectproc,
+static const struct ide_tp_ops trm290_tp_ops = {
+ .exec_command = ide_exec_command,
+ .read_status = ide_read_status,
+ .read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
+
+ .dev_select = trm290_dev_select,
+ .tf_load = ide_tf_load,
+ .tf_read = ide_tf_read,
+
+ .input_data = ide_input_data,
+ .output_data = ide_output_data,
};
static struct ide_dma_ops trm290_dma_ops = {
.dma_host_set = trm290_dma_host_set,
.dma_setup = trm290_dma_setup,
- .dma_exec_cmd = trm290_dma_exec_cmd,
.dma_start = trm290_dma_start,
.dma_end = trm290_dma_end,
.dma_test_irq = trm290_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_check = trm290_dma_check,
};
static const struct ide_port_info trm290_chipset __devinitdata = {
.name = DRV_NAME,
.init_hwif = init_hwif_trm290,
- .port_ops = &trm290_port_ops,
+ .tp_ops = &trm290_tp_ops,
.dma_ops = &trm290_dma_ops,
.host_flags = IDE_HFLAG_TRM290 |
IDE_HFLAG_NO_ATAPI_DMA |
diff --git a/drivers/ide/tx4938ide.c b/drivers/ide/tx4938ide.c
index d9095345f7c..4cb79c4c260 100644
--- a/drivers/ide/tx4938ide.c
+++ b/drivers/ide/tx4938ide.c
@@ -15,6 +15,8 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+
+#include <asm/ide.h>
#include <asm/txx9/tx4938.h>
static void tx4938ide_tune_ebusc(unsigned int ebus_ch,
@@ -80,99 +82,82 @@ static void tx4938ide_outb(u8 value, unsigned long port)
__raw_writeb(value, (void __iomem *)port);
}
-static void tx4938ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4938ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- /* no endian swap */
- __raw_writew(data, (void __iomem *)io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4938ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
tx4938ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
tx4938ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
tx4938ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
tx4938ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
tx4938ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
tx4938ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
tx4938ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
tx4938ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
tx4938ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
tx4938ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
}
-static void tx4938ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void tx4938ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- /* no endian swap */
- data = __raw_readw((void __iomem *)io_ports->data_addr);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- tx4938ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tx4938ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tx4938ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tx4938ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = tx4938ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = tx4938ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tx4938ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature =
- tx4938ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tx4938ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tx4938ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tx4938ide_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tx4938ide_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tx4938ide_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tx4938ide_inb(io_ports->lbah_addr);
}
}
-static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_input_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
@@ -184,7 +169,7 @@ static void tx4938ide_input_data_swap(ide_drive_t *drive, struct request *rq,
__ide_flush_dcache_range((unsigned long)buf, roundup(len, 2));
}
-static void tx4938ide_output_data_swap(ide_drive_t *drive, struct request *rq,
+static void tx4938ide_output_data_swap(ide_drive_t *drive, struct ide_cmd *cmd,
void *buf, unsigned int len)
{
unsigned long port = drive->hwif->io_ports.data_addr;
@@ -202,9 +187,9 @@ static const struct ide_tp_ops tx4938ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4938ide_tf_load,
.tf_read = tx4938ide_tf_read,
diff --git a/drivers/ide/tx4939ide.c b/drivers/ide/tx4939ide.c
index 40b0812a045..0040a9a3e26 100644
--- a/drivers/ide/tx4939ide.c
+++ b/drivers/ide/tx4939ide.c
@@ -18,6 +18,8 @@
#include <linux/io.h>
#include <linux/scatterlist.h>
+#include <asm/ide.h>
+
#define MODNAME "tx4939ide"
/* ATA Shadow Registers (8-bit except for Data which is 16-bit) */
@@ -230,7 +232,7 @@ static u8 tx4939ide_clear_dma_status(void __iomem *base)
#ifdef __BIG_ENDIAN
/* custom ide_build_dmatable to handle swapped layout */
-static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
+static int tx4939ide_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
u32 *table = (u32 *)hwif->dmatable_cpu;
@@ -238,11 +240,7 @@ static int tx4939ide_build_dmatable(ide_drive_t *drive, struct request *rq)
int i;
struct scatterlist *sg;
- hwif->sg_nents = ide_build_sglist(drive, rq);
- if (hwif->sg_nents == 0)
- return 0;
-
- for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
+ for_each_sg(hwif->sg_table, sg, cmd->sg_nents, i) {
u32 cur_addr, cur_len, bcount;
cur_addr = sg_dma_address(sg);
@@ -281,48 +279,36 @@ use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
- ide_destroy_dmatable(drive);
-
return 0; /* revert to PIO for this request */
}
#else
#define tx4939ide_build_dmatable ide_build_dmatable
#endif
-static int tx4939ide_dma_setup(ide_drive_t *drive)
+static int tx4939ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
void __iomem *base = TX4939IDE_BASE(hwif);
- struct request *rq = hwif->rq;
- u8 reading;
- int nent;
-
- if (rq_data_dir(rq))
- reading = 0;
- else
- reading = ATA_DMA_WR;
+ u8 rw = (cmd->tf_flags & IDE_TFLAG_WRITE) ? 0 : ATA_DMA_WR;
/* fall back to PIO! */
- nent = tx4939ide_build_dmatable(drive, rq);
- if (!nent) {
- ide_map_sg(drive, rq);
+ if (tx4939ide_build_dmatable(drive, cmd) == 0)
return 1;
- }
/* PRD table */
tx4939ide_writel(hwif->dmatable_dma, base, TX4939IDE_PRD_Ptr);
/* specify r/w */
- tx4939ide_writeb(reading, base, TX4939IDE_DMA_Cmd);
+ tx4939ide_writeb(rw, base, TX4939IDE_DMA_Cmd);
/* clear INTR & ERROR flags */
tx4939ide_clear_dma_status(base);
- drive->waiting_for_dma = 1;
-
tx4939ide_writew(SECTOR_SIZE / 2, base, drive->dn ?
TX4939IDE_Xfer_Cnt_2 : TX4939IDE_Xfer_Cnt_1);
- tx4939ide_writew(rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
+ tx4939ide_writew(cmd->rq->nr_sectors, base, TX4939IDE_Sec_Cnt);
+
return 0;
}
@@ -333,8 +319,6 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
void __iomem *base = TX4939IDE_BASE(hwif);
u16 ctl = tx4939ide_readw(base, TX4939IDE_Int_Ctl);
- drive->waiting_for_dma = 0;
-
/* get DMA command mode */
dma_cmd = tx4939ide_readb(base, TX4939IDE_DMA_Cmd);
/* stop DMA */
@@ -343,11 +327,9 @@ static int tx4939ide_dma_end(ide_drive_t *drive)
/* read and clear the INTR & ERROR bits */
dma_stat = tx4939ide_clear_dma_status(base);
- /* purge DMA mappings */
- ide_destroy_dmatable(drive);
- /* verify good DMA status */
wmb();
+ /* verify good DMA status */
if ((dma_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == 0 &&
(ctl & (TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST)) ==
(TX4939IDE_INT_XFEREND | TX4939IDE_INT_HOST))
@@ -437,7 +419,7 @@ static int tx4939ide_init_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
return ide_allocate_dma_engine(hwif);
}
-static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load_fixup(ide_drive_t *drive)
{
ide_hwif_t *hwif = drive->hwif;
void __iomem *base = TX4939IDE_BASE(hwif);
@@ -447,7 +429,7 @@ static void tx4939ide_tf_load_fixup(ide_drive_t *drive, ide_task_t *task)
* Fix ATA100 CORE System Control Register. (The write to the
* Device/Head register may write wrong data to the System
* Control Register)
- * While Sys_Ctl is written here, selectproc is not needed.
+ * While Sys_Ctl is written here, dev_select() is not needed.
*/
tx4939ide_writew(sysctl, base, TX4939IDE_Sys_Ctl);
}
@@ -465,97 +447,80 @@ static void tx4939ide_outb(u8 value, unsigned long port)
__raw_writeb(value, (void __iomem *)port);
}
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
- u8 HIHI = task->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
+ struct ide_taskfile *tf = &cmd->tf;
+ u8 HIHI = cmd->tf_flags & IDE_TFLAG_LBA48 ? 0xE0 : 0xEF;
- if (task->tf_flags & IDE_TFLAG_FLAGGED)
+ if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED)
HIHI = 0xFF;
- if (task->tf_flags & IDE_TFLAG_OUT_DATA) {
- u16 data = (tf->hob_data << 8) | tf->data;
-
- /* no endian swap */
- __raw_writew(data, (void __iomem *)io_ports->data_addr);
- }
-
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE)
tx4939ide_outb(tf->hob_feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT)
tx4939ide_outb(tf->hob_nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL)
tx4939ide_outb(tf->hob_lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM)
tx4939ide_outb(tf->hob_lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH)
tx4939ide_outb(tf->hob_lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_FEATURE)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE)
tx4939ide_outb(tf->feature, io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT)
tx4939ide_outb(tf->nsect, io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL)
tx4939ide_outb(tf->lbal, io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM)
tx4939ide_outb(tf->lbam, io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH)
tx4939ide_outb(tf->lbah, io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) {
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) {
tx4939ide_outb((tf->device & HIHI) | drive->select,
io_ports->device_addr);
- tx4939ide_tf_load_fixup(drive, task);
+ tx4939ide_tf_load_fixup(drive);
}
}
-static void tx4939ide_tf_read(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_read(ide_drive_t *drive, struct ide_cmd *cmd)
{
ide_hwif_t *hwif = drive->hwif;
struct ide_io_ports *io_ports = &hwif->io_ports;
- struct ide_taskfile *tf = &task->tf;
-
- if (task->tf_flags & IDE_TFLAG_IN_DATA) {
- u16 data;
-
- /* no endian swap */
- data = __raw_readw((void __iomem *)io_ports->data_addr);
- tf->data = data & 0xff;
- tf->hob_data = (data >> 8) & 0xff;
- }
+ struct ide_taskfile *tf = &cmd->tf;
/* be sure we're looking at the low order bits */
- tx4939ide_outb(ATA_DEVCTL_OBS & ~0x80, io_ports->ctl_addr);
+ tx4939ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr);
- if (task->tf_flags & IDE_TFLAG_IN_FEATURE)
- tf->feature = tx4939ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_NSECT)
+ if (cmd->tf_flags & IDE_TFLAG_IN_ERROR)
+ tf->error = tx4939ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_NSECT)
tf->nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAL)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAL)
tf->lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAM)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAM)
tf->lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_LBAH)
+ if (cmd->tf_flags & IDE_TFLAG_IN_LBAH)
tf->lbah = tx4939ide_inb(io_ports->lbah_addr);
- if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
+ if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE)
tf->device = tx4939ide_inb(io_ports->device_addr);
- if (task->tf_flags & IDE_TFLAG_LBA48) {
- tx4939ide_outb(ATA_DEVCTL_OBS | 0x80, io_ports->ctl_addr);
-
- if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
- tf->hob_feature =
- tx4939ide_inb(io_ports->feature_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
- tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
- tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
- tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
- if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
- tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
+ if (cmd->tf_flags & IDE_TFLAG_LBA48) {
+ tx4939ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr);
+
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR)
+ tf->hob_error = tx4939ide_inb(io_ports->feature_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
+ tf->hob_nsect = tx4939ide_inb(io_ports->nsect_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
+ tf->hob_lbal = tx4939ide_inb(io_ports->lbal_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
+ tf->hob_lbam = tx4939ide_inb(io_ports->lbam_addr);
+ if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
+ tf->hob_lbah = tx4939ide_inb(io_ports->lbah_addr);
}
}
@@ -589,9 +554,9 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = tx4939ide_tf_read,
@@ -601,20 +566,21 @@ static const struct ide_tp_ops tx4939ide_tp_ops = {
#else /* __LITTLE_ENDIAN */
-static void tx4939ide_tf_load(ide_drive_t *drive, ide_task_t *task)
+static void tx4939ide_tf_load(ide_drive_t *drive, struct ide_cmd *cmd)
{
- ide_tf_load(drive, task);
- if (task->tf_flags & IDE_TFLAG_OUT_DEVICE)
- tx4939ide_tf_load_fixup(drive, task);
+ ide_tf_load(drive, cmd);
+
+ if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE)
+ tx4939ide_tf_load_fixup(drive);
}
static const struct ide_tp_ops tx4939ide_tp_ops = {
.exec_command = ide_exec_command,
.read_status = ide_read_status,
.read_altstatus = ide_read_altstatus,
+ .write_devctl = ide_write_devctl,
- .set_irq = ide_set_irq,
-
+ .dev_select = ide_dev_select,
.tf_load = tx4939ide_tf_load,
.tf_read = ide_tf_read,
@@ -634,12 +600,11 @@ static const struct ide_port_ops tx4939ide_port_ops = {
static const struct ide_dma_ops tx4939ide_dma_ops = {
.dma_host_set = tx4939ide_dma_host_set,
.dma_setup = tx4939ide_dma_setup,
- .dma_exec_cmd = ide_dma_exec_cmd,
.dma_start = ide_dma_start,
.dma_end = tx4939ide_dma_end,
.dma_test_irq = tx4939ide_dma_test_irq,
.dma_lost_irq = ide_dma_lost_irq,
- .dma_timeout = ide_dma_timeout,
+ .dma_timer_expiry = ide_dma_sff_timer_expiry,
.dma_sff_read_status = tx4939ide_dma_sff_read_status,
};
diff --git a/drivers/input/Kconfig b/drivers/input/Kconfig
index 5f9d860925a..cd50c00ab20 100644
--- a/drivers/input/Kconfig
+++ b/drivers/input/Kconfig
@@ -143,7 +143,7 @@ config INPUT_APMPOWER
---help---
Say Y here if you want suspend key events to trigger a user
requested suspend through APM. This is useful on embedded
- systems where such behviour is desired without userspace
+ systems where such behaviour is desired without userspace
interaction. If unsure, say N.
To compile this driver as a module, choose M here: the
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 1730d7331a5..ec3db3ade11 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -903,8 +903,6 @@ static int __init input_proc_init(void)
if (!proc_bus_input_dir)
return -ENOMEM;
- proc_bus_input_dir->owner = THIS_MODULE;
-
entry = proc_create("devices", 0, proc_bus_input_dir,
&input_devices_fileops);
if (!entry)
diff --git a/drivers/input/keyboard/sh_keysc.c b/drivers/input/keyboard/sh_keysc.c
index e1480fb11de..cea70e6a103 100644
--- a/drivers/input/keyboard/sh_keysc.c
+++ b/drivers/input/keyboard/sh_keysc.c
@@ -259,12 +259,15 @@ static int sh_keysc_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct sh_keysc_priv *priv = platform_get_drvdata(pdev);
+ int irq = platform_get_irq(pdev, 0);
unsigned short value;
value = ioread16(priv->iomem_base + KYCR1_OFFS);
- if (device_may_wakeup(dev))
+ if (device_may_wakeup(dev)) {
value |= 0x80;
+ enable_irq_wake(irq);
+ }
else
value &= ~0x80;
@@ -272,8 +275,20 @@ static int sh_keysc_suspend(struct device *dev)
return 0;
}
+static int sh_keysc_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int irq = platform_get_irq(pdev, 0);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(irq);
+
+ return 0;
+}
+
static struct dev_pm_ops sh_keysc_dev_pm_ops = {
.suspend = sh_keysc_suspend,
+ .resume = sh_keysc_resume,
};
struct platform_driver sh_keysc_device_driver = {
diff --git a/drivers/input/mouse/gpio_mouse.c b/drivers/input/mouse/gpio_mouse.c
index 0db8d16c5ed..5e5eb88d8d1 100644
--- a/drivers/input/mouse/gpio_mouse.c
+++ b/drivers/input/mouse/gpio_mouse.c
@@ -18,7 +18,7 @@
/*
* Timer function which is run every scan_ms ms when the device is opened.
- * The dev input varaible is set to the the input_dev pointer.
+ * The dev input variable is set to the the input_dev pointer.
*/
static void gpio_mouse_scan(struct input_polled_dev *dev)
{
diff --git a/drivers/input/mouse/hgpk.c b/drivers/input/mouse/hgpk.c
index 81e6ebf323e..55cd0fa6833 100644
--- a/drivers/input/mouse/hgpk.c
+++ b/drivers/input/mouse/hgpk.c
@@ -381,7 +381,7 @@ static void hgpk_disconnect(struct psmouse *psmouse)
static void hgpk_recalib_work(struct work_struct *work)
{
- struct delayed_work *w = container_of(work, struct delayed_work, work);
+ struct delayed_work *w = to_delayed_work(work);
struct hgpk_data *priv = container_of(w, struct hgpk_data, recalib_wq);
struct psmouse *psmouse = priv->psmouse;
diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c
index 7c27c8b9b6d..056ac77e2cf 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -295,7 +295,7 @@ name ## _show(struct device *dev, struct device_attribute *attr, char *buf) \
static DEVICE_ATTR(name, S_IRUGO, name ## _show, NULL);
-/* Sysfs conventions report temperatures in millidegrees Celcius.
+/* Sysfs conventions report temperatures in millidegrees Celsius.
* ADS7846 could use the low-accuracy two-sample scheme, but can't do the high
* accuracy scheme without calibration data. For now we won't try either;
* userspace sees raw sensor values, and must scale/calibrate appropriately.
diff --git a/drivers/input/touchscreen/migor_ts.c b/drivers/input/touchscreen/migor_ts.c
index 504ca11749a..141dd584330 100644
--- a/drivers/input/touchscreen/migor_ts.c
+++ b/drivers/input/touchscreen/migor_ts.c
@@ -198,6 +198,7 @@ static int migor_ts_probe(struct i2c_client *client,
goto err2;
}
+ device_init_wakeup(&client->dev, 1);
return 0;
err2:
@@ -224,6 +225,26 @@ static int migor_ts_remove(struct i2c_client *client)
return 0;
}
+static int migor_ts_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+ if (device_may_wakeup(&client->dev))
+ enable_irq_wake(priv->irq);
+
+ return 0;
+}
+
+static int migor_ts_resume(struct i2c_client *client)
+{
+ struct migor_ts_priv *priv = dev_get_drvdata(&client->dev);
+
+ if (device_may_wakeup(&client->dev))
+ disable_irq_wake(priv->irq);
+
+ return 0;
+}
+
static const struct i2c_device_id migor_ts_id[] = {
{ "migor_ts", 0 },
{ }
@@ -236,6 +257,8 @@ static struct i2c_driver migor_ts_driver = {
},
.probe = migor_ts_probe,
.remove = migor_ts_remove,
+ .suspend = migor_ts_suspend,
+ .resume = migor_ts_resume,
.id_table = migor_ts_id,
};
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 3e468d2cf73..2d8352419c0 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1331,12 +1331,6 @@ static void capinc_tty_send_xchar(struct tty_struct *tty, char ch)
#endif
}
-static int capinc_tty_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
-{
- return 0;
-}
-
static struct tty_driver *capinc_tty_driver;
static const struct tty_operations capinc_ops = {
@@ -1358,7 +1352,6 @@ static const struct tty_operations capinc_ops = {
.flush_buffer = capinc_tty_flush_buffer,
.set_ldisc = capinc_tty_set_ldisc,
.send_xchar = capinc_tty_send_xchar,
- .read_proc = capinc_tty_read_proc,
};
static int capinc_tty_init(void)
diff --git a/drivers/isdn/hardware/eicon/divasi.c b/drivers/isdn/hardware/eicon/divasi.c
index f4969fe0a05..69e71ebe784 100644
--- a/drivers/isdn/hardware/eicon/divasi.c
+++ b/drivers/isdn/hardware/eicon/divasi.c
@@ -118,7 +118,6 @@ static int DIVA_INIT_FUNCTION create_um_idi_proc(void)
return (0);
um_idi_proc_entry->read_proc = um_idi_proc_read;
- um_idi_proc_entry->owner = THIS_MODULE;
return (1);
}
diff --git a/drivers/isdn/mISDN/Kconfig b/drivers/isdn/mISDN/Kconfig
index 4938355c407..1747a02a019 100644
--- a/drivers/isdn/mISDN/Kconfig
+++ b/drivers/isdn/mISDN/Kconfig
@@ -14,13 +14,15 @@ config MISDN_DSP
depends on MISDN
help
Enable support for digital audio processing capability.
+
This module may be used for special applications that require
- cross connecting of bchannels, conferencing, dtmf decoding
+ cross connecting of bchannels, conferencing, dtmf decoding,
echo cancelation, tone generation, and Blowfish encryption and
- decryption.
- It may use hardware features if available.
+ decryption. It may use hardware features if available.
+
E.g. it is required for PBX4Linux. Go to http://isdn.eversberg.eu
- and get more informations about this module and it's usage.
+ and get more information about this module and its usage.
+
If unsure, say 'N'.
config MISDN_L1OIP
diff --git a/drivers/isdn/mISDN/l1oip_codec.c b/drivers/isdn/mISDN/l1oip_codec.c
index 2ec4b28d9ed..e4ecba3d48d 100644
--- a/drivers/isdn/mISDN/l1oip_codec.c
+++ b/drivers/isdn/mISDN/l1oip_codec.c
@@ -331,7 +331,7 @@ l1oip_4bit_alloc(int ulaw)
/* alloc conversion tables */
table_com = vmalloc(65536);
table_dec = vmalloc(512);
- if (!table_com | !table_dec) {
+ if (!table_com || !table_dec) {
l1oip_4bit_free();
return -ENOMEM;
}
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 556aeca0d86..9b60b6b684d 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -31,6 +31,13 @@ config LEDS_LOCOMO
This option enables support for the LEDs on Sharp Locomo.
Zaurus models SL-5500 and SL-5600.
+config LEDS_MIKROTIK_RB532
+ tristate "LED Support for Mikrotik Routerboard 532"
+ depends on LEDS_CLASS && MIKROTIK_RB532
+ help
+ This option enables support for the so called "User LED" of
+ Mikrotik's Routerboard 532.
+
config LEDS_S3C24XX
tristate "LED Support for Samsung S3C24XX GPIO LEDs"
depends on LEDS_CLASS && ARCH_S3C2410
@@ -100,7 +107,7 @@ config LEDS_HP6XX
tristate "LED Support for the HP Jornada 6xx"
depends on LEDS_CLASS && SH_HP6XX
help
- This option enables led support for the handheld
+ This option enables LED support for the handheld
HP Jornada 620/660/680/690.
config LEDS_PCA9532
@@ -108,7 +115,7 @@ config LEDS_PCA9532
depends on LEDS_CLASS && I2C && INPUT && EXPERIMENTAL
help
This option enables support for NXP pca9532
- led controller. It is generally only usefull
+ LED controller. It is generally only useful
as a platform driver
config LEDS_GPIO
@@ -117,11 +124,40 @@ config LEDS_GPIO
help
This option enables support for the LEDs connected to GPIO
outputs. To be useful the particular board must have LEDs
- and they must be connected to the GPIO lines.
+ and they must be connected to the GPIO lines. The LEDs must be
+ defined as platform devices and/or OpenFirmware platform devices.
+ The code to use these bindings can be selected below.
+
+config LEDS_GPIO_PLATFORM
+ bool "Platform device bindings for GPIO LEDs"
+ depends on LEDS_GPIO
+ default y
+ help
+ Let the leds-gpio driver drive LEDs which have been defined as
+ platform devices. If you don't know what this means, say yes.
+
+config LEDS_GPIO_OF
+ bool "OpenFirmware platform device bindings for GPIO LEDs"
+ depends on LEDS_GPIO && OF_DEVICE
+ default y
+ help
+ Let the leds-gpio driver drive LEDs which have been defined as
+ of_platform devices. For instance, LEDs which are listed in a "dts"
+ file.
+
+config LEDS_LP5521
+ tristate "LED Support for the LP5521 LEDs"
+ depends on LEDS_CLASS && I2C
+ help
+ If you say 'Y' here you get support for the National Semiconductor
+ LP5521 LED driver used in n8x0 boards.
+
+ This driver can be built as a module by choosing 'M'. The module
+ will be called leds-lp5521.
config LEDS_CLEVO_MAIL
- tristate "Mail LED on Clevo notebook (EXPERIMENTAL)"
- depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI && EXPERIMENTAL
+ tristate "Mail LED on Clevo notebook"
+ depends on LEDS_CLASS && X86 && SERIO_I8042 && DMI
help
This driver makes the mail LED accessible from userspace
programs through the leds subsystem. This LED have three
@@ -144,7 +180,7 @@ config LEDS_CLEVO_MAIL
Positivo Mobile (Clevo M5x0V)
If your model is not listed here you can try the "nodetect"
- module paramter.
+ module parameter.
To compile this driver as a module, choose M here: the
module will be called leds-clevo-mail.
@@ -171,6 +207,26 @@ config LEDS_DA903X
This option enables support for on-chip LED drivers found
on Dialog Semiconductor DA9030/DA9034 PMICs.
+config LEDS_DAC124S085
+ tristate "LED Support for DAC124S085 SPI DAC"
+ depends on LEDS_CLASS && SPI
+ help
+ This option enables support for DAC124S085 SPI DAC from NatSemi,
+ which can be used to control up to four LEDs.
+
+config LEDS_PWM
+ tristate "PWM driven LED Support"
+ depends on LEDS_CLASS && HAVE_PWM
+ help
+ This option enables support for pwm driven LEDs
+
+config LEDS_BD2802
+ tristate "LED driver for BD2802 RGB LED"
+ depends on LEDS_CLASS && I2C
+ help
+ This option enables support for BD2802GU RGB LED driver chips
+ accessed via the I2C bus.
+
comment "LED Triggers"
config LEDS_TRIGGERS
@@ -216,6 +272,19 @@ config LEDS_TRIGGER_BACKLIGHT
If unsure, say N.
+config LEDS_TRIGGER_GPIO
+ tristate "LED GPIO Trigger"
+ depends on LEDS_TRIGGERS
+ depends on GPIOLIB
+ help
+ This allows LEDs to be controlled by gpio events. It's good
+ when using gpios as switches and triggering the needed LEDs
+ from there. One use case is n810's keypad LEDs that could
+ be triggered by this trigger when user slides up to show
+ keypad.
+
+ If unsure, say N.
+
config LEDS_TRIGGER_DEFAULT_ON
tristate "LED Default ON Trigger"
depends on LEDS_TRIGGERS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 9d76f0f160a..2d41c4dcf92 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -6,7 +6,9 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o
# LED Platform Drivers
obj-$(CONFIG_LEDS_ATMEL_PWM) += leds-atmel-pwm.o
+obj-$(CONFIG_LEDS_BD2802) += leds-bd2802.o
obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o
+obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o
obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o
obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o
obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o
@@ -24,10 +26,15 @@ obj-$(CONFIG_LEDS_FSG) += leds-fsg.o
obj-$(CONFIG_LEDS_PCA955X) += leds-pca955x.o
obj-$(CONFIG_LEDS_DA903X) += leds-da903x.o
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
+obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
+
+# LED SPI Drivers
+obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
# LED Triggers
obj-$(CONFIG_LEDS_TRIGGER_TIMER) += ledtrig-timer.o
obj-$(CONFIG_LEDS_TRIGGER_IDE_DISK) += ledtrig-ide-disk.o
obj-$(CONFIG_LEDS_TRIGGER_HEARTBEAT) += ledtrig-heartbeat.o
obj-$(CONFIG_LEDS_TRIGGER_BACKLIGHT) += ledtrig-backlight.o
+obj-$(CONFIG_LEDS_TRIGGER_GPIO) += ledtrig-gpio.o
obj-$(CONFIG_LEDS_TRIGGER_DEFAULT_ON) += ledtrig-default-on.o
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 52f82e3ea13..f2cc13d7681 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -64,7 +64,16 @@ static ssize_t led_brightness_store(struct device *dev,
return ret;
}
+static ssize_t led_max_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+
+ return sprintf(buf, "%u\n", led_cdev->max_brightness);
+}
+
static DEVICE_ATTR(brightness, 0644, led_brightness_show, led_brightness_store);
+static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL);
#ifdef CONFIG_LEDS_TRIGGERS
static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store);
#endif
@@ -138,6 +147,13 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
list_add_tail(&led_cdev->node, &leds_list);
up_write(&leds_list_lock);
+ if (!led_cdev->max_brightness)
+ led_cdev->max_brightness = LED_FULL;
+
+ rc = device_create_file(led_cdev->dev, &dev_attr_max_brightness);
+ if (rc)
+ goto err_out_attr_max;
+
led_update_brightness(led_cdev);
#ifdef CONFIG_LEDS_TRIGGERS
@@ -155,9 +171,11 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
#ifdef CONFIG_LEDS_TRIGGERS
err_out_led_list:
+ device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
+#endif
+err_out_attr_max:
device_remove_file(led_cdev->dev, &dev_attr_brightness);
list_del(&led_cdev->node);
-#endif
err_out:
device_unregister(led_cdev->dev);
return rc;
@@ -172,6 +190,7 @@ EXPORT_SYMBOL_GPL(led_classdev_register);
*/
void led_classdev_unregister(struct led_classdev *led_cdev)
{
+ device_remove_file(led_cdev->dev, &dev_attr_max_brightness);
device_remove_file(led_cdev->dev, &dev_attr_brightness);
#ifdef CONFIG_LEDS_TRIGGERS
device_remove_file(led_cdev->dev, &dev_attr_trigger);
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c
index f910eaffe3a..d8ddd9ef899 100644
--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -156,12 +156,20 @@ EXPORT_SYMBOL_GPL(led_trigger_set_default);
int led_trigger_register(struct led_trigger *trigger)
{
struct led_classdev *led_cdev;
+ struct led_trigger *trig;
rwlock_init(&trigger->leddev_list_lock);
INIT_LIST_HEAD(&trigger->led_cdevs);
- /* Add to the list of led triggers */
down_write(&triggers_list_lock);
+ /* Make sure the trigger's name isn't already in use */
+ list_for_each_entry(trig, &trigger_list, next_trig) {
+ if (!strcmp(trig->name, trigger->name)) {
+ up_write(&triggers_list_lock);
+ return -EEXIST;
+ }
+ }
+ /* Add to the list of led triggers */
list_add_tail(&trigger->next_trig, &trigger_list);
up_write(&triggers_list_lock);
diff --git a/drivers/leds/leds-bd2802.c b/drivers/leds/leds-bd2802.c
new file mode 100644
index 00000000000..4149ecb3a9b
--- /dev/null
+++ b/drivers/leds/leds-bd2802.c
@@ -0,0 +1,765 @@
+/*
+ * leds-bd2802.c - RGB LED Driver
+ *
+ * Copyright (C) 2009 Samsung Electronics
+ * Kim Kyuwon <q1.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/leds.h>
+#include <linux/leds-bd2802.h>
+
+
+#define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
+
+#define BD2802_LED_OFFSET 0xa
+#define BD2802_COLOR_OFFSET 0x3
+
+#define BD2802_REG_CLKSETUP 0x00
+#define BD2802_REG_CONTROL 0x01
+#define BD2802_REG_HOURSETUP 0x02
+#define BD2802_REG_CURRENT1SETUP 0x03
+#define BD2802_REG_CURRENT2SETUP 0x04
+#define BD2802_REG_WAVEPATTERN 0x05
+
+#define BD2802_CURRENT_032 0x10 /* 3.2mA */
+#define BD2802_CURRENT_000 0x00 /* 0.0mA */
+
+#define BD2802_PATTERN_FULL 0x07
+#define BD2802_PATTERN_HALF 0x03
+
+enum led_ids {
+ LED1,
+ LED2,
+ LED_NUM,
+};
+
+enum led_colors {
+ RED,
+ GREEN,
+ BLUE,
+};
+
+enum led_bits {
+ BD2802_OFF,
+ BD2802_BLINK,
+ BD2802_ON,
+};
+
+/*
+ * State '0' : 'off'
+ * State '1' : 'blink'
+ * State '2' : 'on'.
+ */
+struct led_state {
+ unsigned r:2;
+ unsigned g:2;
+ unsigned b:2;
+};
+
+struct bd2802_led {
+ struct bd2802_led_platform_data *pdata;
+ struct i2c_client *client;
+ struct rw_semaphore rwsem;
+ struct work_struct work;
+
+ struct led_state led[2];
+
+ /*
+ * Making led_classdev as array is not recommended, because array
+ * members prevent using 'container_of' macro. So repetitive works
+ * are needed.
+ */
+ struct led_classdev cdev_led1r;
+ struct led_classdev cdev_led1g;
+ struct led_classdev cdev_led1b;
+ struct led_classdev cdev_led2r;
+ struct led_classdev cdev_led2g;
+ struct led_classdev cdev_led2b;
+
+ /*
+ * Advanced Configuration Function(ADF) mode:
+ * In ADF mode, user can set registers of BD2802GU directly,
+ * therefore BD2802GU doesn't enter reset state.
+ */
+ int adf_on;
+
+ enum led_ids led_id;
+ enum led_colors color;
+ enum led_bits state;
+};
+
+
+/*--------------------------------------------------------------*/
+/* BD2802GU helper functions */
+/*--------------------------------------------------------------*/
+
+static inline int bd2802_is_rgb_off(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ switch (color) {
+ case RED:
+ return !led->led[id].r;
+ case GREEN:
+ return !led->led[id].g;
+ case BLUE:
+ return !led->led[id].b;
+ default:
+ dev_err(&led->client->dev, "%s: Invalid color\n", __func__);
+ return -EINVAL;
+ }
+}
+
+static inline int bd2802_is_led_off(struct bd2802_led *led, enum led_ids id)
+{
+ if (led->led[id].r || led->led[id].g || led->led[id].b)
+ return 0;
+
+ return 1;
+}
+
+static inline int bd2802_is_all_off(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < LED_NUM; i++)
+ if (!bd2802_is_led_off(led, i))
+ return 0;
+
+ return 1;
+}
+
+static inline u8 bd2802_get_base_offset(enum led_ids id, enum led_colors color)
+{
+ return id * BD2802_LED_OFFSET + color * BD2802_COLOR_OFFSET;
+}
+
+static inline u8 bd2802_get_reg_addr(enum led_ids id, enum led_colors color,
+ u8 reg_offset)
+{
+ return reg_offset + bd2802_get_base_offset(id, color);
+}
+
+
+/*--------------------------------------------------------------*/
+/* BD2802GU core functions */
+/*--------------------------------------------------------------*/
+
+static int bd2802_write_byte(struct i2c_client *client, u8 reg, u8 val)
+{
+ int ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret >= 0)
+ return 0;
+
+ dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
+ __func__, reg, val, ret);
+
+ return ret;
+}
+
+static void bd2802_update_state(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color, enum led_bits led_bit)
+{
+ int i;
+ u8 value;
+
+ for (i = 0; i < LED_NUM; i++) {
+ if (i == id) {
+ switch (color) {
+ case RED:
+ led->led[i].r = led_bit;
+ break;
+ case GREEN:
+ led->led[i].g = led_bit;
+ break;
+ case BLUE:
+ led->led[i].b = led_bit;
+ break;
+ default:
+ dev_err(&led->client->dev,
+ "%s: Invalid color\n", __func__);
+ return;
+ }
+ }
+ }
+
+ if (led_bit == BD2802_BLINK || led_bit == BD2802_ON)
+ return;
+
+ if (!bd2802_is_led_off(led, id))
+ return;
+
+ if (bd2802_is_all_off(led) && !led->adf_on) {
+ gpio_set_value(led->pdata->reset_gpio, 0);
+ return;
+ }
+
+ /*
+ * In this case, other led is turned on, and current led is turned
+ * off. So set RGB LED Control register to stop the current RGB LED
+ */
+ value = (id == LED1) ? LED_CTL(1, 0) : LED_CTL(0, 1);
+ bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_configure(struct bd2802_led *led)
+{
+ struct bd2802_led_platform_data *pdata = led->pdata;
+ u8 reg;
+
+ reg = bd2802_get_reg_addr(LED1, RED, BD2802_REG_HOURSETUP);
+ bd2802_write_byte(led->client, reg, pdata->rgb_time);
+
+ reg = bd2802_get_reg_addr(LED2, RED, BD2802_REG_HOURSETUP);
+ bd2802_write_byte(led->client, reg, pdata->rgb_time);
+}
+
+static void bd2802_reset_cancel(struct bd2802_led *led)
+{
+ gpio_set_value(led->pdata->reset_gpio, 1);
+ udelay(100);
+ bd2802_configure(led);
+}
+
+static void bd2802_enable(struct bd2802_led *led, enum led_ids id)
+{
+ enum led_ids other_led = (id == LED1) ? LED2 : LED1;
+ u8 value, other_led_on;
+
+ other_led_on = !bd2802_is_led_off(led, other_led);
+ if (id == LED1)
+ value = LED_CTL(other_led_on, 1);
+ else
+ value = LED_CTL(1 , other_led_on);
+
+ bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
+}
+
+static void bd2802_set_on(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_all_off(led) && !led->adf_on)
+ bd2802_reset_cancel(led);
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+ bd2802_write_byte(led->client, reg, BD2802_PATTERN_FULL);
+
+ bd2802_enable(led, id);
+ bd2802_update_state(led, id, color, BD2802_ON);
+}
+
+static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_all_off(led) && !led->adf_on)
+ bd2802_reset_cancel(led);
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_032);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
+ bd2802_write_byte(led->client, reg, BD2802_PATTERN_HALF);
+
+ bd2802_enable(led, id);
+ bd2802_update_state(led, id, color, BD2802_BLINK);
+}
+
+static void bd2802_turn_on(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color, enum led_bits led_bit)
+{
+ if (led_bit == BD2802_OFF) {
+ dev_err(&led->client->dev,
+ "Only 'blink' and 'on' are allowed\n");
+ return;
+ }
+
+ if (led_bit == BD2802_BLINK)
+ bd2802_set_blink(led, id, color);
+ else
+ bd2802_set_on(led, id, color);
+}
+
+static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id,
+ enum led_colors color)
+{
+ u8 reg;
+
+ if (bd2802_is_rgb_off(led, id, color))
+ return;
+
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+ reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
+ bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
+
+ bd2802_update_state(led, id, color, BD2802_OFF);
+}
+
+static void bd2802_restore_state(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < LED_NUM; i++) {
+ if (led->led[i].r)
+ bd2802_turn_on(led, i, RED, led->led[i].r);
+ if (led->led[i].g)
+ bd2802_turn_on(led, i, GREEN, led->led[i].g);
+ if (led->led[i].b)
+ bd2802_turn_on(led, i, BLUE, led->led[i].b);
+ }
+}
+
+#define BD2802_SET_REGISTER(reg_addr, reg_name) \
+static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
+ struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
+ unsigned long val; \
+ int ret; \
+ if (!count) \
+ return -EINVAL; \
+ ret = strict_strtoul(buf, 16, &val); \
+ if (ret) \
+ return ret; \
+ down_write(&led->rwsem); \
+ bd2802_write_byte(led->client, reg_addr, (u8) val); \
+ up_write(&led->rwsem); \
+ return count; \
+} \
+static struct device_attribute bd2802_reg##reg_addr##_attr = { \
+ .attr = {.name = reg_name, .mode = 0644, .owner = THIS_MODULE}, \
+ .store = bd2802_store_reg##reg_addr, \
+};
+
+BD2802_SET_REGISTER(0x00, "0x00");
+BD2802_SET_REGISTER(0x01, "0x01");
+BD2802_SET_REGISTER(0x02, "0x02");
+BD2802_SET_REGISTER(0x03, "0x03");
+BD2802_SET_REGISTER(0x04, "0x04");
+BD2802_SET_REGISTER(0x05, "0x05");
+BD2802_SET_REGISTER(0x06, "0x06");
+BD2802_SET_REGISTER(0x07, "0x07");
+BD2802_SET_REGISTER(0x08, "0x08");
+BD2802_SET_REGISTER(0x09, "0x09");
+BD2802_SET_REGISTER(0x0a, "0x0a");
+BD2802_SET_REGISTER(0x0b, "0x0b");
+BD2802_SET_REGISTER(0x0c, "0x0c");
+BD2802_SET_REGISTER(0x0d, "0x0d");
+BD2802_SET_REGISTER(0x0e, "0x0e");
+BD2802_SET_REGISTER(0x0f, "0x0f");
+BD2802_SET_REGISTER(0x10, "0x10");
+BD2802_SET_REGISTER(0x11, "0x11");
+BD2802_SET_REGISTER(0x12, "0x12");
+BD2802_SET_REGISTER(0x13, "0x13");
+BD2802_SET_REGISTER(0x14, "0x14");
+BD2802_SET_REGISTER(0x15, "0x15");
+
+static struct device_attribute *bd2802_addr_attributes[] = {
+ &bd2802_reg0x00_attr,
+ &bd2802_reg0x01_attr,
+ &bd2802_reg0x02_attr,
+ &bd2802_reg0x03_attr,
+ &bd2802_reg0x04_attr,
+ &bd2802_reg0x05_attr,
+ &bd2802_reg0x06_attr,
+ &bd2802_reg0x07_attr,
+ &bd2802_reg0x08_attr,
+ &bd2802_reg0x09_attr,
+ &bd2802_reg0x0a_attr,
+ &bd2802_reg0x0b_attr,
+ &bd2802_reg0x0c_attr,
+ &bd2802_reg0x0d_attr,
+ &bd2802_reg0x0e_attr,
+ &bd2802_reg0x0f_attr,
+ &bd2802_reg0x10_attr,
+ &bd2802_reg0x11_attr,
+ &bd2802_reg0x12_attr,
+ &bd2802_reg0x13_attr,
+ &bd2802_reg0x14_attr,
+ &bd2802_reg0x15_attr,
+};
+
+static void bd2802_enable_adv_conf(struct bd2802_led *led)
+{
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) {
+ ret = device_create_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+ if (ret) {
+ dev_err(&led->client->dev, "failed to sysfs file %s\n",
+ bd2802_addr_attributes[i]->attr.name);
+ goto failed_remove_files;
+ }
+ }
+
+ if (bd2802_is_all_off(led))
+ bd2802_reset_cancel(led);
+
+ led->adf_on = 1;
+
+ return;
+
+failed_remove_files:
+ for (i--; i >= 0; i--)
+ device_remove_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+}
+
+static void bd2802_disable_adv_conf(struct bd2802_led *led)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++)
+ device_remove_file(&led->client->dev,
+ bd2802_addr_attributes[i]);
+
+ if (bd2802_is_all_off(led))
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ led->adf_on = 0;
+}
+
+static ssize_t bd2802_show_adv_conf(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+ ssize_t ret;
+
+ down_read(&led->rwsem);
+ if (led->adf_on)
+ ret = sprintf(buf, "on\n");
+ else
+ ret = sprintf(buf, "off\n");
+ up_read(&led->rwsem);
+
+ return ret;
+}
+
+static ssize_t bd2802_store_adv_conf(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
+
+ if (!count)
+ return -EINVAL;
+
+ down_write(&led->rwsem);
+ if (!led->adf_on && !strncmp(buf, "on", 2))
+ bd2802_enable_adv_conf(led);
+ else if (led->adf_on && !strncmp(buf, "off", 3))
+ bd2802_disable_adv_conf(led);
+ up_write(&led->rwsem);
+
+ return count;
+}
+
+static struct device_attribute bd2802_adv_conf_attr = {
+ .attr = {
+ .name = "advanced_configuration",
+ .mode = 0644,
+ .owner = THIS_MODULE
+ },
+ .show = bd2802_show_adv_conf,
+ .store = bd2802_store_adv_conf,
+};
+
+static void bd2802_led_work(struct work_struct *work)
+{
+ struct bd2802_led *led = container_of(work, struct bd2802_led, work);
+
+ if (led->state)
+ bd2802_turn_on(led, led->led_id, led->color, led->state);
+ else
+ bd2802_turn_off(led, led->led_id, led->color);
+}
+
+#define BD2802_CONTROL_RGBS(name, id, clr) \
+static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\
+ enum led_brightness value) \
+{ \
+ struct bd2802_led *led = \
+ container_of(led_cdev, struct bd2802_led, cdev_##name); \
+ led->led_id = id; \
+ led->color = clr; \
+ if (value == LED_OFF) \
+ led->state = BD2802_OFF; \
+ else \
+ led->state = BD2802_ON; \
+ schedule_work(&led->work); \
+} \
+static int bd2802_set_##name##_blink(struct led_classdev *led_cdev, \
+ unsigned long *delay_on, unsigned long *delay_off) \
+{ \
+ struct bd2802_led *led = \
+ container_of(led_cdev, struct bd2802_led, cdev_##name); \
+ if (*delay_on == 0 || *delay_off == 0) \
+ return -EINVAL; \
+ led->led_id = id; \
+ led->color = clr; \
+ led->state = BD2802_BLINK; \
+ schedule_work(&led->work); \
+ return 0; \
+}
+
+BD2802_CONTROL_RGBS(led1r, LED1, RED);
+BD2802_CONTROL_RGBS(led1g, LED1, GREEN);
+BD2802_CONTROL_RGBS(led1b, LED1, BLUE);
+BD2802_CONTROL_RGBS(led2r, LED2, RED);
+BD2802_CONTROL_RGBS(led2g, LED2, GREEN);
+BD2802_CONTROL_RGBS(led2b, LED2, BLUE);
+
+static int bd2802_register_led_classdev(struct bd2802_led *led)
+{
+ int ret;
+
+ INIT_WORK(&led->work, bd2802_led_work);
+
+ led->cdev_led1r.name = "led1_R";
+ led->cdev_led1r.brightness = LED_OFF;
+ led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness;
+ led->cdev_led1r.blink_set = bd2802_set_led1r_blink;
+ led->cdev_led1r.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1r);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1r.name);
+ goto failed_unregister_led1_R;
+ }
+
+ led->cdev_led1g.name = "led1_G";
+ led->cdev_led1g.brightness = LED_OFF;
+ led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness;
+ led->cdev_led1g.blink_set = bd2802_set_led1g_blink;
+ led->cdev_led1g.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1g);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1g.name);
+ goto failed_unregister_led1_G;
+ }
+
+ led->cdev_led1b.name = "led1_B";
+ led->cdev_led1b.brightness = LED_OFF;
+ led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness;
+ led->cdev_led1b.blink_set = bd2802_set_led1b_blink;
+ led->cdev_led1b.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led1b);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led1b.name);
+ goto failed_unregister_led1_B;
+ }
+
+ led->cdev_led2r.name = "led2_R";
+ led->cdev_led2r.brightness = LED_OFF;
+ led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness;
+ led->cdev_led2r.blink_set = bd2802_set_led2r_blink;
+ led->cdev_led2r.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2r);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2r.name);
+ goto failed_unregister_led2_R;
+ }
+
+ led->cdev_led2g.name = "led2_G";
+ led->cdev_led2g.brightness = LED_OFF;
+ led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness;
+ led->cdev_led2g.blink_set = bd2802_set_led2g_blink;
+ led->cdev_led2g.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2g);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2g.name);
+ goto failed_unregister_led2_G;
+ }
+
+ led->cdev_led2b.name = "led2_B";
+ led->cdev_led2b.brightness = LED_OFF;
+ led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness;
+ led->cdev_led2b.blink_set = bd2802_set_led2b_blink;
+ led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&led->client->dev, &led->cdev_led2b);
+ if (ret < 0) {
+ dev_err(&led->client->dev, "couldn't register LED %s\n",
+ led->cdev_led2b.name);
+ goto failed_unregister_led2_B;
+ }
+
+ return 0;
+
+failed_unregister_led2_B:
+ led_classdev_unregister(&led->cdev_led2g);
+failed_unregister_led2_G:
+ led_classdev_unregister(&led->cdev_led2r);
+failed_unregister_led2_R:
+ led_classdev_unregister(&led->cdev_led1b);
+failed_unregister_led1_B:
+ led_classdev_unregister(&led->cdev_led1g);
+failed_unregister_led1_G:
+ led_classdev_unregister(&led->cdev_led1r);
+failed_unregister_led1_R:
+
+ return ret;
+}
+
+static void bd2802_unregister_led_classdev(struct bd2802_led *led)
+{
+ cancel_work_sync(&led->work);
+ led_classdev_unregister(&led->cdev_led1r);
+}
+
+static int __devinit bd2802_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct bd2802_led *led;
+ struct bd2802_led_platform_data *pdata;
+ int ret;
+
+ led = kzalloc(sizeof(struct bd2802_led), GFP_KERNEL);
+ if (!led) {
+ dev_err(&client->dev, "failed to allocate driver data\n");
+ return -ENOMEM;
+ }
+
+ led->client = client;
+ pdata = led->pdata = client->dev.platform_data;
+ i2c_set_clientdata(client, led);
+
+ /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
+ gpio_request(pdata->reset_gpio, "RGB_RESETB");
+ gpio_direction_output(pdata->reset_gpio, 1);
+
+ /* Tacss = min 0.1ms */
+ udelay(100);
+
+ /* Detect BD2802GU */
+ ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to detect device\n");
+ goto failed_free;
+ } else
+ dev_info(&client->dev, "return 0x%02x\n", ret);
+
+ /* To save the power, reset BD2802 after detecting */
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ init_rwsem(&led->rwsem);
+
+ ret = device_create_file(&client->dev, &bd2802_adv_conf_attr);
+ if (ret) {
+ dev_err(&client->dev, "failed to create sysfs file %s\n",
+ bd2802_adv_conf_attr.attr.name);
+ goto failed_free;
+ }
+
+ ret = bd2802_register_led_classdev(led);
+ if (ret < 0)
+ goto failed_unregister_dev_file;
+
+ return 0;
+
+failed_unregister_dev_file:
+ device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+failed_free:
+ i2c_set_clientdata(client, NULL);
+ kfree(led);
+
+ return ret;
+}
+
+static int __exit bd2802_remove(struct i2c_client *client)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ bd2802_unregister_led_classdev(led);
+ gpio_set_value(led->pdata->reset_gpio, 0);
+ if (led->adf_on)
+ bd2802_disable_adv_conf(led);
+ device_remove_file(&client->dev, &bd2802_adv_conf_attr);
+ i2c_set_clientdata(client, NULL);
+ kfree(led);
+
+ return 0;
+}
+
+static int bd2802_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ gpio_set_value(led->pdata->reset_gpio, 0);
+
+ return 0;
+}
+
+static int bd2802_resume(struct i2c_client *client)
+{
+ struct bd2802_led *led = i2c_get_clientdata(client);
+
+ if (!bd2802_is_all_off(led) || led->adf_on) {
+ gpio_set_value(led->pdata->reset_gpio, 1);
+ udelay(100);
+ bd2802_restore_state(led);
+ }
+
+ return 0;
+}
+
+static const struct i2c_device_id bd2802_id[] = {
+ { "BD2802", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, bd2802_id);
+
+static struct i2c_driver bd2802_i2c_driver = {
+ .driver = {
+ .name = "BD2802",
+ },
+ .probe = bd2802_probe,
+ .remove = __exit_p(bd2802_remove),
+ .suspend = bd2802_suspend,
+ .resume = bd2802_resume,
+ .id_table = bd2802_id,
+};
+
+static int __init bd2802_init(void)
+{
+ return i2c_add_driver(&bd2802_i2c_driver);
+}
+module_init(bd2802_init);
+
+static void __exit bd2802_exit(void)
+{
+ i2c_del_driver(&bd2802_i2c_driver);
+}
+module_exit(bd2802_exit);
+
+MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
+MODULE_DESCRIPTION("BD2802 LED driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/leds-dac124s085.c b/drivers/leds/leds-dac124s085.c
new file mode 100644
index 00000000000..098d9aae725
--- /dev/null
+++ b/drivers/leds/leds-dac124s085.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This file is subject to the terms and conditions of version 2 of
+ * the GNU General Public License. See the file COPYING in the main
+ * directory of this archive for more details.
+ *
+ * LED driver for the DAC124S085 SPI DAC
+ */
+
+#include <linux/gfp.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/spi/spi.h>
+
+struct dac124s085_led {
+ struct led_classdev ldev;
+ struct spi_device *spi;
+ int id;
+ int brightness;
+ char name[sizeof("dac124s085-3")];
+
+ struct mutex mutex;
+ struct work_struct work;
+ spinlock_t lock;
+};
+
+struct dac124s085 {
+ struct dac124s085_led leds[4];
+};
+
+#define REG_WRITE (0 << 12)
+#define REG_WRITE_UPDATE (1 << 12)
+#define ALL_WRITE_UPDATE (2 << 12)
+#define POWER_DOWN_OUTPUT (3 << 12)
+
+static void dac124s085_led_work(struct work_struct *work)
+{
+ struct dac124s085_led *led = container_of(work, struct dac124s085_led,
+ work);
+ u16 word;
+
+ mutex_lock(&led->mutex);
+ word = cpu_to_le16(((led->id) << 14) | REG_WRITE_UPDATE |
+ (led->brightness & 0xfff));
+ spi_write(led->spi, (const u8 *)&word, sizeof(word));
+ mutex_unlock(&led->mutex);
+}
+
+static void dac124s085_set_brightness(struct led_classdev *ldev,
+ enum led_brightness brightness)
+{
+ struct dac124s085_led *led = container_of(ldev, struct dac124s085_led,
+ ldev);
+
+ spin_lock(&led->lock);
+ led->brightness = brightness;
+ schedule_work(&led->work);
+ spin_unlock(&led->lock);
+}
+
+static int dac124s085_probe(struct spi_device *spi)
+{
+ struct dac124s085 *dac;
+ struct dac124s085_led *led;
+ int i, ret;
+
+ dac = kzalloc(sizeof(*dac), GFP_KERNEL);
+ if (!dac)
+ return -ENOMEM;
+
+ spi->bits_per_word = 16;
+
+ for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+ led = dac->leds + i;
+ led->id = i;
+ led->brightness = LED_OFF;
+ led->spi = spi;
+ snprintf(led->name, sizeof(led->name), "dac124s085-%d", i);
+ spin_lock_init(&led->lock);
+ INIT_WORK(&led->work, dac124s085_led_work);
+ mutex_init(&led->mutex);
+ led->ldev.name = led->name;
+ led->ldev.brightness = LED_OFF;
+ led->ldev.max_brightness = 0xfff;
+ led->ldev.brightness_set = dac124s085_set_brightness;
+ ret = led_classdev_register(&spi->dev, &led->ldev);
+ if (ret < 0)
+ goto eledcr;
+ }
+
+ spi_set_drvdata(spi, dac);
+
+ return 0;
+
+eledcr:
+ while (i--)
+ led_classdev_unregister(&dac->leds[i].ldev);
+
+ spi_set_drvdata(spi, NULL);
+ kfree(dac);
+ return ret;
+}
+
+static int dac124s085_remove(struct spi_device *spi)
+{
+ struct dac124s085 *dac = spi_get_drvdata(spi);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {
+ led_classdev_unregister(&dac->leds[i].ldev);
+ cancel_work_sync(&dac->leds[i].work);
+ }
+
+ spi_set_drvdata(spi, NULL);
+ kfree(dac);
+
+ return 0;
+}
+
+static struct spi_driver dac124s085_driver = {
+ .probe = dac124s085_probe,
+ .remove = dac124s085_remove,
+ .driver = {
+ .name = "dac124s085",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init dac124s085_leds_init(void)
+{
+ return spi_register_driver(&dac124s085_driver);
+}
+
+static void __exit dac124s085_leds_exit(void)
+{
+ spi_unregister_driver(&dac124s085_driver);
+}
+
+module_init(dac124s085_leds_init);
+module_exit(dac124s085_leds_exit);
+
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_DESCRIPTION("DAC124S085 LED driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/leds/leds-gpio.c b/drivers/leds/leds-gpio.c
index 2e3df08b649..102ef4a14c5 100644
--- a/drivers/leds/leds-gpio.c
+++ b/drivers/leds/leds-gpio.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2007 8D Technologies inc.
* Raphael Assenat <raph@8d.com>
+ * Copyright (C) 2008 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -71,11 +72,67 @@ static int gpio_blink_set(struct led_classdev *led_cdev,
return led_dat->platform_gpio_blink_set(led_dat->gpio, delay_on, delay_off);
}
+static int __devinit create_gpio_led(const struct gpio_led *template,
+ struct gpio_led_data *led_dat, struct device *parent,
+ int (*blink_set)(unsigned, unsigned long *, unsigned long *))
+{
+ int ret;
+
+ /* skip leds that aren't available */
+ if (!gpio_is_valid(template->gpio)) {
+ printk(KERN_INFO "Skipping unavilable LED gpio %d (%s)\n",
+ template->gpio, template->name);
+ return;
+ }
+
+ ret = gpio_request(template->gpio, template->name);
+ if (ret < 0)
+ return ret;
+
+ led_dat->cdev.name = template->name;
+ led_dat->cdev.default_trigger = template->default_trigger;
+ led_dat->gpio = template->gpio;
+ led_dat->can_sleep = gpio_cansleep(template->gpio);
+ led_dat->active_low = template->active_low;
+ if (blink_set) {
+ led_dat->platform_gpio_blink_set = blink_set;
+ led_dat->cdev.blink_set = gpio_blink_set;
+ }
+ led_dat->cdev.brightness_set = gpio_led_set;
+ led_dat->cdev.brightness = LED_OFF;
+ if (!template->retain_state_suspended)
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = gpio_direction_output(led_dat->gpio, led_dat->active_low);
+ if (ret < 0)
+ goto err;
+
+ INIT_WORK(&led_dat->work, gpio_led_work);
+
+ ret = led_classdev_register(parent, &led_dat->cdev);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+err:
+ gpio_free(led_dat->gpio);
+ return ret;
+}
+
+static void delete_gpio_led(struct gpio_led_data *led)
+{
+ if (!gpio_is_valid(led->gpio))
+ return;
+ led_classdev_unregister(&led->cdev);
+ cancel_work_sync(&led->work);
+ gpio_free(led->gpio);
+}
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
static int gpio_led_probe(struct platform_device *pdev)
{
struct gpio_led_platform_data *pdata = pdev->dev.platform_data;
- struct gpio_led *cur_led;
- struct gpio_led_data *leds_data, *led_dat;
+ struct gpio_led_data *leds_data;
int i, ret = 0;
if (!pdata)
@@ -87,35 +144,10 @@ static int gpio_led_probe(struct platform_device *pdev)
return -ENOMEM;
for (i = 0; i < pdata->num_leds; i++) {
- cur_led = &pdata->leds[i];
- led_dat = &leds_data[i];
-
- ret = gpio_request(cur_led->gpio, cur_led->name);
+ ret = create_gpio_led(&pdata->leds[i], &leds_data[i],
+ &pdev->dev, pdata->gpio_blink_set);
if (ret < 0)
goto err;
-
- led_dat->cdev.name = cur_led->name;
- led_dat->cdev.default_trigger = cur_led->default_trigger;
- led_dat->gpio = cur_led->gpio;
- led_dat->can_sleep = gpio_cansleep(cur_led->gpio);
- led_dat->active_low = cur_led->active_low;
- if (pdata->gpio_blink_set) {
- led_dat->platform_gpio_blink_set = pdata->gpio_blink_set;
- led_dat->cdev.blink_set = gpio_blink_set;
- }
- led_dat->cdev.brightness_set = gpio_led_set;
- led_dat->cdev.brightness = LED_OFF;
- led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
-
- gpio_direction_output(led_dat->gpio, led_dat->active_low);
-
- INIT_WORK(&led_dat->work, gpio_led_work);
-
- ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
- if (ret < 0) {
- gpio_free(led_dat->gpio);
- goto err;
- }
}
platform_set_drvdata(pdev, leds_data);
@@ -123,13 +155,8 @@ static int gpio_led_probe(struct platform_device *pdev)
return 0;
err:
- if (i > 0) {
- for (i = i - 1; i >= 0; i--) {
- led_classdev_unregister(&leds_data[i].cdev);
- cancel_work_sync(&leds_data[i].work);
- gpio_free(leds_data[i].gpio);
- }
- }
+ for (i = i - 1; i >= 0; i--)
+ delete_gpio_led(&leds_data[i]);
kfree(leds_data);
@@ -144,11 +171,8 @@ static int __devexit gpio_led_remove(struct platform_device *pdev)
leds_data = platform_get_drvdata(pdev);
- for (i = 0; i < pdata->num_leds; i++) {
- led_classdev_unregister(&leds_data[i].cdev);
- cancel_work_sync(&leds_data[i].work);
- gpio_free(leds_data[i].gpio);
- }
+ for (i = 0; i < pdata->num_leds; i++)
+ delete_gpio_led(&leds_data[i]);
kfree(leds_data);
@@ -164,20 +188,133 @@ static struct platform_driver gpio_led_driver = {
},
};
+MODULE_ALIAS("platform:leds-gpio");
+#endif /* CONFIG_LEDS_GPIO_PLATFORM */
+
+/* Code to create from OpenFirmware platform devices */
+#ifdef CONFIG_LEDS_GPIO_OF
+#include <linux/of_platform.h>
+#include <linux/of_gpio.h>
+
+struct gpio_led_of_platform_data {
+ int num_leds;
+ struct gpio_led_data led_data[];
+};
+
+static int __devinit of_gpio_leds_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node, *child;
+ struct gpio_led led;
+ struct gpio_led_of_platform_data *pdata;
+ int count = 0, ret;
+
+ /* count LEDs defined by this device, so we know how much to allocate */
+ for_each_child_of_node(np, child)
+ count++;
+ if (!count)
+ return 0; /* or ENODEV? */
+
+ pdata = kzalloc(sizeof(*pdata) + sizeof(struct gpio_led_data) * count,
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+
+ memset(&led, 0, sizeof(led));
+ for_each_child_of_node(np, child) {
+ enum of_gpio_flags flags;
+
+ led.gpio = of_get_gpio_flags(child, 0, &flags);
+ led.active_low = flags & OF_GPIO_ACTIVE_LOW;
+ led.name = of_get_property(child, "label", NULL) ? : child->name;
+ led.default_trigger =
+ of_get_property(child, "linux,default-trigger", NULL);
+
+ ret = create_gpio_led(&led, &pdata->led_data[pdata->num_leds++],
+ &ofdev->dev, NULL);
+ if (ret < 0) {
+ of_node_put(child);
+ goto err;
+ }
+ }
+
+ dev_set_drvdata(&ofdev->dev, pdata);
+
+ return 0;
+
+err:
+ for (count = pdata->num_leds - 2; count >= 0; count--)
+ delete_gpio_led(&pdata->led_data[count]);
+
+ kfree(pdata);
+
+ return ret;
+}
+
+static int __devexit of_gpio_leds_remove(struct of_device *ofdev)
+{
+ struct gpio_led_of_platform_data *pdata = dev_get_drvdata(&ofdev->dev);
+ int i;
+
+ for (i = 0; i < pdata->num_leds; i++)
+ delete_gpio_led(&pdata->led_data[i]);
+
+ kfree(pdata);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id of_gpio_leds_match[] = {
+ { .compatible = "gpio-leds", },
+ {},
+};
+
+static struct of_platform_driver of_gpio_leds_driver = {
+ .driver = {
+ .name = "of_gpio_leds",
+ .owner = THIS_MODULE,
+ },
+ .match_table = of_gpio_leds_match,
+ .probe = of_gpio_leds_probe,
+ .remove = __devexit_p(of_gpio_leds_remove),
+};
+#endif
+
static int __init gpio_led_init(void)
{
- return platform_driver_register(&gpio_led_driver);
+ int ret;
+
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
+ ret = platform_driver_register(&gpio_led_driver);
+ if (ret)
+ return ret;
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+ ret = of_register_platform_driver(&of_gpio_leds_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
+ if (ret)
+ platform_driver_unregister(&gpio_led_driver);
+#endif
+
+ return ret;
}
static void __exit gpio_led_exit(void)
{
+#ifdef CONFIG_LEDS_GPIO_PLATFORM
platform_driver_unregister(&gpio_led_driver);
+#endif
+#ifdef CONFIG_LEDS_GPIO_OF
+ of_unregister_platform_driver(&of_gpio_leds_driver);
+#endif
}
module_init(gpio_led_init);
module_exit(gpio_led_exit);
-MODULE_AUTHOR("Raphael Assenat <raph@8d.com>");
+MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
MODULE_DESCRIPTION("GPIO LED driver");
MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:leds-gpio");
diff --git a/drivers/leds/leds-h1940.c b/drivers/leds/leds-h1940.c
index 11b77a70bbc..1aa46a390a0 100644
--- a/drivers/leds/leds-h1940.c
+++ b/drivers/leds/leds-h1940.c
@@ -104,7 +104,7 @@ static struct led_classdev h1940_blueled = {
.default_trigger = "h1940-bluetooth",
};
-static int __init h1940leds_probe(struct platform_device *pdev)
+static int __devinit h1940leds_probe(struct platform_device *pdev)
{
int ret;
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c
index 76ec7498e2d..3937244fdca 100644
--- a/drivers/leds/leds-pca9532.c
+++ b/drivers/leds/leds-pca9532.c
@@ -1,7 +1,7 @@
/*
* pca9532.c - 16-bit Led dimmer
*
- * Copyright (C) 2008 Riku Voipio <riku.voipio@movial.fi>
+ * Copyright (C) 2008 Riku Voipio
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -169,7 +169,7 @@ static int pca9532_event(struct input_dev *dev, unsigned int type,
{
struct pca9532_data *data = input_get_drvdata(dev);
- if (type != EV_SND && (code != SND_BELL || code != SND_TONE))
+ if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE)))
return -1;
/* XXX: allow different kind of beeps with psc/pwm modifications */
@@ -367,7 +367,7 @@ static void __exit pca9532_exit(void)
i2c_del_driver(&pca9532_driver);
}
-MODULE_AUTHOR("Riku Voipio <riku.voipio@movial.fi>");
+MODULE_AUTHOR("Riku Voipio");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PCA 9532 LED dimmer");
diff --git a/drivers/leds/leds-pwm.c b/drivers/leds/leds-pwm.c
new file mode 100644
index 00000000000..cdfdc8714e1
--- /dev/null
+++ b/drivers/leds/leds-pwm.c
@@ -0,0 +1,153 @@
+/*
+ * linux/drivers/leds-pwm.c
+ *
+ * simple PWM based LED control
+ *
+ * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de)
+ *
+ * based on leds-gpio.c by Raphael Assenat <raph@8d.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/fb.h>
+#include <linux/leds.h>
+#include <linux/err.h>
+#include <linux/pwm.h>
+#include <linux/leds_pwm.h>
+
+struct led_pwm_data {
+ struct led_classdev cdev;
+ struct pwm_device *pwm;
+ unsigned int active_low;
+ unsigned int period;
+ unsigned int max_brightness;
+};
+
+static void led_pwm_set(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct led_pwm_data *led_dat =
+ container_of(led_cdev, struct led_pwm_data, cdev);
+ unsigned int max = led_dat->max_brightness;
+ unsigned int period = led_dat->period;
+
+ if (brightness == 0) {
+ pwm_config(led_dat->pwm, 0, period);
+ pwm_disable(led_dat->pwm);
+ } else {
+ pwm_config(led_dat->pwm, brightness * period / max, period);
+ pwm_enable(led_dat->pwm);
+ }
+}
+
+static int led_pwm_probe(struct platform_device *pdev)
+{
+ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+ struct led_pwm *cur_led;
+ struct led_pwm_data *leds_data, *led_dat;
+ int i, ret = 0;
+
+ if (!pdata)
+ return -EBUSY;
+
+ leds_data = kzalloc(sizeof(struct led_pwm_data) * pdata->num_leds,
+ GFP_KERNEL);
+ if (!leds_data)
+ return -ENOMEM;
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ cur_led = &pdata->leds[i];
+ led_dat = &leds_data[i];
+
+ led_dat->pwm = pwm_request(cur_led->pwm_id,
+ cur_led->name);
+ if (IS_ERR(led_dat->pwm)) {
+ dev_err(&pdev->dev, "unable to request PWM %d\n",
+ cur_led->pwm_id);
+ goto err;
+ }
+
+ led_dat->cdev.name = cur_led->name;
+ led_dat->cdev.default_trigger = cur_led->default_trigger;
+ led_dat->active_low = cur_led->active_low;
+ led_dat->max_brightness = cur_led->max_brightness;
+ led_dat->period = cur_led->pwm_period_ns;
+ led_dat->cdev.brightness_set = led_pwm_set;
+ led_dat->cdev.brightness = LED_OFF;
+ led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
+
+ ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
+ if (ret < 0) {
+ pwm_free(led_dat->pwm);
+ goto err;
+ }
+ }
+
+ platform_set_drvdata(pdev, leds_data);
+
+ return 0;
+
+err:
+ if (i > 0) {
+ for (i = i - 1; i >= 0; i--) {
+ led_classdev_unregister(&leds_data[i].cdev);
+ pwm_free(leds_data[i].pwm);
+ }
+ }
+
+ kfree(leds_data);
+
+ return ret;
+}
+
+static int __devexit led_pwm_remove(struct platform_device *pdev)
+{
+ int i;
+ struct led_pwm_platform_data *pdata = pdev->dev.platform_data;
+ struct led_pwm_data *leds_data;
+
+ leds_data = platform_get_drvdata(pdev);
+
+ for (i = 0; i < pdata->num_leds; i++) {
+ led_classdev_unregister(&leds_data[i].cdev);
+ pwm_free(leds_data[i].pwm);
+ }
+
+ kfree(leds_data);
+
+ return 0;
+}
+
+static struct platform_driver led_pwm_driver = {
+ .probe = led_pwm_probe,
+ .remove = __devexit_p(led_pwm_remove),
+ .driver = {
+ .name = "leds_pwm",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init led_pwm_init(void)
+{
+ return platform_driver_register(&led_pwm_driver);
+}
+
+static void __exit led_pwm_exit(void)
+{
+ platform_driver_unregister(&led_pwm_driver);
+}
+
+module_init(led_pwm_init);
+module_exit(led_pwm_exit);
+
+MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
+MODULE_DESCRIPTION("PWM LED driver for PXA");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-pwm");
diff --git a/drivers/leds/leds-rb532.c b/drivers/leds/leds-rb532.c
new file mode 100644
index 00000000000..c3525f37f73
--- /dev/null
+++ b/drivers/leds/leds-rb532.c
@@ -0,0 +1,77 @@
+/*
+ * LEDs driver for the "User LED" on Routerboard532
+ *
+ * Copyright (C) 2009 Phil Sutter <n0-1@freewrt.org>
+ *
+ * Based on leds-cobalt-qube.c by Florian Fainelly and
+ * rb-diag.c (my own standalone driver for both LED and
+ * button of Routerboard532).
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-rc32434/gpio.h>
+#include <asm/mach-rc32434/rb.h>
+
+static void rb532_led_set(struct led_classdev *cdev,
+ enum led_brightness brightness)
+{
+ if (brightness)
+ set_latch_u5(LO_ULED, 0);
+
+ else
+ set_latch_u5(0, LO_ULED);
+}
+
+static enum led_brightness rb532_led_get(struct led_classdev *cdev)
+{
+ return (get_latch_u5() & LO_ULED) ? LED_FULL : LED_OFF;
+}
+
+static struct led_classdev rb532_uled = {
+ .name = "uled",
+ .brightness_set = rb532_led_set,
+ .brightness_get = rb532_led_get,
+ .default_trigger = "nand-disk",
+};
+
+static int __devinit rb532_led_probe(struct platform_device *pdev)
+{
+ return led_classdev_register(&pdev->dev, &rb532_uled);
+}
+
+static int __devexit rb532_led_remove(struct platform_device *pdev)
+{
+ led_classdev_unregister(&rb532_uled);
+ return 0;
+}
+
+static struct platform_driver rb532_led_driver = {
+ .probe = rb532_led_probe,
+ .remove = __devexit_p(rb532_led_remove),
+ .driver = {
+ .name = "rb532-led",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rb532_led_init(void)
+{
+ return platform_driver_register(&rb532_led_driver);
+}
+
+static void __exit rb532_led_exit(void)
+{
+ platform_driver_unregister(&rb532_led_driver);
+}
+
+module_init(rb532_led_init);
+module_exit(rb532_led_exit);
+
+MODULE_ALIAS("platform:rb532-led");
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("User LED support for Routerboard532");
+MODULE_AUTHOR("Phil Sutter <n0-1@freewrt.org>");
diff --git a/drivers/leds/leds-s3c24xx.c b/drivers/leds/leds-s3c24xx.c
index 4d81131542a..aa2e7ae0cda 100644
--- a/drivers/leds/leds-s3c24xx.c
+++ b/drivers/leds/leds-s3c24xx.c
@@ -102,14 +102,11 @@ static int s3c24xx_led_probe(struct platform_device *dev)
ret = led_classdev_register(&dev->dev, &led->cdev);
if (ret < 0) {
dev_err(&dev->dev, "led_classdev_register failed\n");
- goto exit_err1;
+ kfree(led);
+ return ret;
}
return 0;
-
- exit_err1:
- kfree(led);
- return ret;
}
static struct platform_driver s3c24xx_led_driver = {
diff --git a/drivers/leds/leds.h b/drivers/leds/leds.h
index 5edbf52c4fa..2dd8ecbfdc3 100644
--- a/drivers/leds/leds.h
+++ b/drivers/leds/leds.h
@@ -20,8 +20,8 @@
static inline void led_set_brightness(struct led_classdev *led_cdev,
enum led_brightness value)
{
- if (value > LED_FULL)
- value = LED_FULL;
+ if (value > led_cdev->max_brightness)
+ value = led_cdev->max_brightness;
led_cdev->brightness = value;
if (!(led_cdev->flags & LED_SUSPENDED))
led_cdev->brightness_set(led_cdev, value);
diff --git a/drivers/leds/ledtrig-default-on.c b/drivers/leds/ledtrig-default-on.c
index 92995e40cfa..a4ef54b9d50 100644
--- a/drivers/leds/ledtrig-default-on.c
+++ b/drivers/leds/ledtrig-default-on.c
@@ -19,7 +19,7 @@
static void defon_trig_activate(struct led_classdev *led_cdev)
{
- led_set_brightness(led_cdev, LED_FULL);
+ led_set_brightness(led_cdev, led_cdev->max_brightness);
}
static struct led_trigger defon_led_trigger = {
diff --git a/drivers/leds/ledtrig-gpio.c b/drivers/leds/ledtrig-gpio.c
new file mode 100644
index 00000000000..a247ae63374
--- /dev/null
+++ b/drivers/leds/ledtrig-gpio.c
@@ -0,0 +1,239 @@
+/*
+ * ledtrig-gio.c - LED Trigger Based on GPIO events
+ *
+ * Copyright 2009 Felipe Balbi <me@felipebalbi.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+#include "leds.h"
+
+struct gpio_trig_data {
+ struct led_classdev *led;
+ struct work_struct work;
+
+ unsigned desired_brightness; /* desired brightness when led is on */
+ unsigned inverted; /* true when gpio is inverted */
+ unsigned gpio; /* gpio that triggers the leds */
+};
+
+static irqreturn_t gpio_trig_irq(int irq, void *_led)
+{
+ struct led_classdev *led = _led;
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ /* just schedule_work since gpio_get_value can sleep */
+ schedule_work(&gpio_data->work);
+
+ return IRQ_HANDLED;
+};
+
+static void gpio_trig_work(struct work_struct *work)
+{
+ struct gpio_trig_data *gpio_data = container_of(work,
+ struct gpio_trig_data, work);
+ int tmp;
+
+ if (!gpio_data->gpio)
+ return;
+
+ tmp = gpio_get_value(gpio_data->gpio);
+ if (gpio_data->inverted)
+ tmp = !tmp;
+
+ if (tmp) {
+ if (gpio_data->desired_brightness)
+ led_set_brightness(gpio_data->led,
+ gpio_data->desired_brightness);
+ else
+ led_set_brightness(gpio_data->led, LED_FULL);
+ } else {
+ led_set_brightness(gpio_data->led, LED_OFF);
+ }
+}
+
+static ssize_t gpio_trig_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%u\n", gpio_data->desired_brightness);
+}
+
+static ssize_t gpio_trig_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned desired_brightness;
+ int ret;
+
+ ret = sscanf(buf, "%u", &desired_brightness);
+ if (ret < 1 || desired_brightness > 255) {
+ dev_err(dev, "invalid value\n");
+ return -EINVAL;
+ }
+
+ gpio_data->desired_brightness = desired_brightness;
+
+ return n;
+}
+static DEVICE_ATTR(desired_brightness, 0644, gpio_trig_brightness_show,
+ gpio_trig_brightness_store);
+
+static ssize_t gpio_trig_inverted_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%s\n", gpio_data->inverted ? "yes" : "no");
+}
+
+static ssize_t gpio_trig_inverted_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned inverted;
+ int ret;
+
+ ret = sscanf(buf, "%u", &inverted);
+ if (ret < 1) {
+ dev_err(dev, "invalid value\n");
+ return -EINVAL;
+ }
+
+ gpio_data->inverted = !!inverted;
+
+ return n;
+}
+static DEVICE_ATTR(inverted, 0644, gpio_trig_inverted_show,
+ gpio_trig_inverted_store);
+
+static ssize_t gpio_trig_gpio_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ return sprintf(buf, "%u\n", gpio_data->gpio);
+}
+
+static ssize_t gpio_trig_gpio_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t n)
+{
+ struct led_classdev *led = dev_get_drvdata(dev);
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+ unsigned gpio;
+ int ret;
+
+ ret = sscanf(buf, "%u", &gpio);
+ if (ret < 1) {
+ dev_err(dev, "couldn't read gpio number\n");
+ flush_work(&gpio_data->work);
+ return -EINVAL;
+ }
+
+ if (!gpio) {
+ free_irq(gpio_to_irq(gpio_data->gpio), led);
+ return n;
+ }
+
+ if (gpio_data->gpio > 0 && gpio_data->gpio != gpio)
+ free_irq(gpio_to_irq(gpio_data->gpio), led);
+
+ gpio_data->gpio = gpio;
+ ret = request_irq(gpio_to_irq(gpio), gpio_trig_irq,
+ IRQF_SHARED | IRQF_TRIGGER_RISING
+ | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
+ if (ret)
+ dev_err(dev, "request_irq failed with error %d\n", ret);
+
+ return ret ? ret : n;
+}
+static DEVICE_ATTR(gpio, 0644, gpio_trig_gpio_show, gpio_trig_gpio_store);
+
+static void gpio_trig_activate(struct led_classdev *led)
+{
+ struct gpio_trig_data *gpio_data;
+ int ret;
+
+ gpio_data = kzalloc(sizeof(*gpio_data), GFP_KERNEL);
+ if (!gpio_data)
+ return;
+
+ ret = device_create_file(led->dev, &dev_attr_gpio);
+ if (ret)
+ goto err_gpio;
+
+ ret = device_create_file(led->dev, &dev_attr_inverted);
+ if (ret)
+ goto err_inverted;
+
+ ret = device_create_file(led->dev, &dev_attr_desired_brightness);
+ if (ret)
+ goto err_brightness;
+
+ gpio_data->led = led;
+ led->trigger_data = gpio_data;
+ INIT_WORK(&gpio_data->work, gpio_trig_work);
+
+ return;
+
+err_brightness:
+ device_remove_file(led->dev, &dev_attr_inverted);
+
+err_inverted:
+ device_remove_file(led->dev, &dev_attr_gpio);
+
+err_gpio:
+ kfree(gpio_data);
+}
+
+static void gpio_trig_deactivate(struct led_classdev *led)
+{
+ struct gpio_trig_data *gpio_data = led->trigger_data;
+
+ if (gpio_data) {
+ device_remove_file(led->dev, &dev_attr_gpio);
+ device_remove_file(led->dev, &dev_attr_inverted);
+ device_remove_file(led->dev, &dev_attr_desired_brightness);
+ flush_work(&gpio_data->work);
+ free_irq(gpio_to_irq(gpio_data->gpio),led);
+ kfree(gpio_data);
+ }
+}
+
+static struct led_trigger gpio_led_trigger = {
+ .name = "gpio",
+ .activate = gpio_trig_activate,
+ .deactivate = gpio_trig_deactivate,
+};
+
+static int __init gpio_trig_init(void)
+{
+ return led_trigger_register(&gpio_led_trigger);
+}
+module_init(gpio_trig_init);
+
+static void __exit gpio_trig_exit(void)
+{
+ led_trigger_unregister(&gpio_led_trigger);
+}
+module_exit(gpio_trig_exit);
+
+MODULE_AUTHOR("Felipe Balbi <me@felipebalbi.com>");
+MODULE_DESCRIPTION("GPIO LED trigger");
+MODULE_LICENSE("GPL");
diff --git a/drivers/leds/ledtrig-heartbeat.c b/drivers/leds/ledtrig-heartbeat.c
index 4bf8cec8b8c..c1c1ea6f817 100644
--- a/drivers/leds/ledtrig-heartbeat.c
+++ b/drivers/leds/ledtrig-heartbeat.c
@@ -47,7 +47,7 @@ static void led_heartbeat_function(unsigned long data)
msecs_to_jiffies(heartbeat_data->period);
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
- brightness = LED_FULL;
+ brightness = led_cdev->max_brightness;
break;
case 1:
delay = heartbeat_data->period / 4 - msecs_to_jiffies(70);
@@ -56,7 +56,7 @@ static void led_heartbeat_function(unsigned long data)
case 2:
delay = msecs_to_jiffies(70);
heartbeat_data->phase++;
- brightness = LED_FULL;
+ brightness = led_cdev->max_brightness;
break;
default:
delay = heartbeat_data->period - heartbeat_data->period / 4 -
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index 883a577b1b9..ec099fcbcb0 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -37,7 +37,8 @@ static void ledtrig_ide_timerfunc(unsigned long data)
{
if (ide_lastactivity != ide_activity) {
ide_lastactivity = ide_activity;
- led_trigger_event(ledtrig_ide, LED_FULL);
+ /* INT_MAX will set each LED to its maximum brightness */
+ led_trigger_event(ledtrig_ide, INT_MAX);
mod_timer(&ledtrig_ide_timer, jiffies + msecs_to_jiffies(10));
} else {
led_trigger_event(ledtrig_ide, LED_OFF);
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 3d6531396dd..3b83406de75 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -166,7 +166,7 @@ static void timer_trig_activate(struct led_classdev *led_cdev)
timer_data->brightness_on = led_get_brightness(led_cdev);
if (timer_data->brightness_on == LED_OFF)
- timer_data->brightness_on = LED_FULL;
+ timer_data->brightness_on = led_cdev->max_brightness;
led_cdev->trigger_data = timer_data;
init_timer(&timer_data->timer);
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 60156dfdc60..4845fb3cf74 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -152,8 +152,8 @@ static void unmap_switcher(void)
* code. We have to check that the range is below the pfn_limit the Launcher
* gave us. We have to make sure that addr + len doesn't give us a false
* positive by overflowing, too. */
-int lguest_address_ok(const struct lguest *lg,
- unsigned long addr, unsigned long len)
+bool lguest_address_ok(const struct lguest *lg,
+ unsigned long addr, unsigned long len)
{
return (addr+len) / PAGE_SIZE < lg->pfn_limit && (addr+len >= addr);
}
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 415fab0125a..6e99adbe194 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -34,7 +34,7 @@ static int idt_type(u32 lo, u32 hi)
}
/* An IDT entry can't be used unless the "present" bit is set. */
-static int idt_present(u32 lo, u32 hi)
+static bool idt_present(u32 lo, u32 hi)
{
return (hi & 0x8000);
}
@@ -60,7 +60,8 @@ static void push_guest_stack(struct lg_cpu *cpu, unsigned long *gstack, u32 val)
* We set up the stack just like the CPU does for a real interrupt, so it's
* identical for the Guest (and the standard "iret" instruction will undo
* it). */
-static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi, int has_err)
+static void set_guest_interrupt(struct lg_cpu *cpu, u32 lo, u32 hi,
+ bool has_err)
{
unsigned long gstack, origstack;
u32 eflags, ss, irq_enable;
@@ -184,7 +185,7 @@ void maybe_do_interrupt(struct lg_cpu *cpu)
/* set_guest_interrupt() takes the interrupt descriptor and a
* flag to say whether this interrupt pushes an error code onto
* the stack as well: virtual interrupts never do. */
- set_guest_interrupt(cpu, idt->a, idt->b, 0);
+ set_guest_interrupt(cpu, idt->a, idt->b, false);
}
/* Every time we deliver an interrupt, we update the timestamp in the
@@ -244,26 +245,26 @@ void free_interrupts(void)
/*H:220 Now we've got the routines to deliver interrupts, delivering traps like
* page fault is easy. The only trick is that Intel decided that some traps
* should have error codes: */
-static int has_err(unsigned int trap)
+static bool has_err(unsigned int trap)
{
return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17);
}
/* deliver_trap() returns true if it could deliver the trap. */
-int deliver_trap(struct lg_cpu *cpu, unsigned int num)
+bool deliver_trap(struct lg_cpu *cpu, unsigned int num)
{
/* Trap numbers are always 8 bit, but we set an impossible trap number
* for traps inside the Switcher, so check that here. */
if (num >= ARRAY_SIZE(cpu->arch.idt))
- return 0;
+ return false;
/* Early on the Guest hasn't set the IDT entries (or maybe it put a
* bogus one in): if we fail here, the Guest will be killed. */
if (!idt_present(cpu->arch.idt[num].a, cpu->arch.idt[num].b))
- return 0;
+ return false;
set_guest_interrupt(cpu, cpu->arch.idt[num].a,
cpu->arch.idt[num].b, has_err(num));
- return 1;
+ return true;
}
/*H:250 Here's the hard part: returning to the Host every time a trap happens
@@ -279,18 +280,19 @@ int deliver_trap(struct lg_cpu *cpu, unsigned int num)
*
* This routine indicates if a particular trap number could be delivered
* directly. */
-static int direct_trap(unsigned int num)
+static bool direct_trap(unsigned int num)
{
/* Hardware interrupts don't go to the Guest at all (except system
* call). */
if (num >= FIRST_EXTERNAL_VECTOR && !could_be_syscall(num))
- return 0;
+ return false;
/* The Host needs to see page faults (for shadow paging and to save the
* fault address), general protection faults (in/out emulation) and
- * device not available (TS handling), and of course, the hypercall
- * trap. */
- return num != 14 && num != 13 && num != 7 && num != LGUEST_TRAP_ENTRY;
+ * device not available (TS handling), invalid opcode fault (kvm hcall),
+ * and of course, the hypercall trap. */
+ return num != 14 && num != 13 && num != 7 &&
+ num != 6 && num != LGUEST_TRAP_ENTRY;
}
/*:*/
diff --git a/drivers/lguest/lg.h b/drivers/lguest/lg.h
index f2c641e0bdd..ac8a4a3741b 100644
--- a/drivers/lguest/lg.h
+++ b/drivers/lguest/lg.h
@@ -109,8 +109,8 @@ struct lguest
extern struct mutex lguest_lock;
/* core.c: */
-int lguest_address_ok(const struct lguest *lg,
- unsigned long addr, unsigned long len);
+bool lguest_address_ok(const struct lguest *lg,
+ unsigned long addr, unsigned long len);
void __lgread(struct lg_cpu *, void *, unsigned long, unsigned);
void __lgwrite(struct lg_cpu *, unsigned long, const void *, unsigned);
@@ -140,7 +140,7 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user);
/* interrupts_and_traps.c: */
void maybe_do_interrupt(struct lg_cpu *cpu);
-int deliver_trap(struct lg_cpu *cpu, unsigned int num);
+bool deliver_trap(struct lg_cpu *cpu, unsigned int num);
void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int i,
u32 low, u32 hi);
void guest_set_stack(struct lg_cpu *cpu, u32 seg, u32 esp, unsigned int pages);
@@ -173,7 +173,7 @@ void guest_pagetable_flush_user(struct lg_cpu *cpu);
void guest_set_pte(struct lg_cpu *cpu, unsigned long gpgdir,
unsigned long vaddr, pte_t val);
void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages);
-int demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode);
+bool demand_page(struct lg_cpu *cpu, unsigned long cr2, int errcode);
void pin_page(struct lg_cpu *cpu, unsigned long vaddr);
unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr);
void page_table_guest_data_init(struct lg_cpu *cpu);
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 8132533d71f..df44d962626 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -161,7 +161,7 @@ static void set_status(struct virtio_device *vdev, u8 status)
/* We set the status. */
to_lgdev(vdev)->desc->status = status;
- hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0);
+ kvm_hypercall1(LHCALL_NOTIFY, (max_pfn << PAGE_SHIFT) + offset);
}
static void lg_set_status(struct virtio_device *vdev, u8 status)
@@ -209,7 +209,7 @@ static void lg_notify(struct virtqueue *vq)
* virtqueue structure. */
struct lguest_vq_info *lvq = vq->priv;
- hcall(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT, 0, 0);
+ kvm_hypercall1(LHCALL_NOTIFY, lvq->config.pfn << PAGE_SHIFT);
}
/* An extern declaration inside a C file is bad form. Don't do it. */
diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c
index 576a8318221..a059cf9980f 100644
--- a/drivers/lguest/page_tables.c
+++ b/drivers/lguest/page_tables.c
@@ -199,7 +199,7 @@ static void check_gpgd(struct lg_cpu *cpu, pgd_t gpgd)
*
* If we fixed up the fault (ie. we mapped the address), this routine returns
* true. Otherwise, it was a real fault and we need to tell the Guest. */
-int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
+bool demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
{
pgd_t gpgd;
pgd_t *spgd;
@@ -211,7 +211,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
/* Toplevel not present? We can't map it in. */
if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
- return 0;
+ return false;
/* Now look at the matching shadow entry. */
spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr);
@@ -222,7 +222,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
* simple for this corner case. */
if (!ptepage) {
kill_guest(cpu, "out of memory allocating pte page");
- return 0;
+ return false;
}
/* We check that the Guest pgd is OK. */
check_gpgd(cpu, gpgd);
@@ -238,16 +238,16 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
/* If this page isn't in the Guest page tables, we can't page it in. */
if (!(pte_flags(gpte) & _PAGE_PRESENT))
- return 0;
+ return false;
/* Check they're not trying to write to a page the Guest wants
* read-only (bit 2 of errcode == write). */
if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
- return 0;
+ return false;
/* User access to a kernel-only page? (bit 3 == user access) */
if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
- return 0;
+ return false;
/* Check that the Guest PTE flags are OK, and the page number is below
* the pfn_limit (ie. not mapping the Launcher binary). */
@@ -283,7 +283,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
* manipulated, the result returned and the code complete. A small
* delay and a trace of alliteration are the only indications the Guest
* has that a page fault occurred at all. */
- return 1;
+ return true;
}
/*H:360
@@ -296,7 +296,7 @@ int demand_page(struct lg_cpu *cpu, unsigned long vaddr, int errcode)
*
* This is a quick version which answers the question: is this virtual address
* mapped by the shadow page tables, and is it writable? */
-static int page_writable(struct lg_cpu *cpu, unsigned long vaddr)
+static bool page_writable(struct lg_cpu *cpu, unsigned long vaddr)
{
pgd_t *spgd;
unsigned long flags;
@@ -304,7 +304,7 @@ static int page_writable(struct lg_cpu *cpu, unsigned long vaddr)
/* Look at the current top level entry: is it present? */
spgd = spgd_addr(cpu, cpu->cpu_pgd, vaddr);
if (!(pgd_flags(*spgd) & _PAGE_PRESENT))
- return 0;
+ return false;
/* Check the flags on the pte entry itself: it must be present and
* writable. */
@@ -373,8 +373,10 @@ unsigned long guest_pa(struct lg_cpu *cpu, unsigned long vaddr)
/* First step: get the top-level Guest page table entry. */
gpgd = lgread(cpu, gpgd_addr(cpu, vaddr), pgd_t);
/* Toplevel not present? We can't map it in. */
- if (!(pgd_flags(gpgd) & _PAGE_PRESENT))
+ if (!(pgd_flags(gpgd) & _PAGE_PRESENT)) {
kill_guest(cpu, "Bad address %#lx", vaddr);
+ return -1UL;
+ }
gpte = lgread(cpu, gpte_addr(gpgd, vaddr), pte_t);
if (!(pte_flags(gpte) & _PAGE_PRESENT))
diff --git a/drivers/lguest/segments.c b/drivers/lguest/segments.c
index ec6aa3f1c36..4f15439b7f1 100644
--- a/drivers/lguest/segments.c
+++ b/drivers/lguest/segments.c
@@ -45,7 +45,7 @@
* "Task State Segment" which controls all kinds of delicate things. The
* LGUEST_CS and LGUEST_DS entries are reserved for the Switcher, and the
* the Guest can't be trusted to deal with double faults. */
-static int ignored_gdt(unsigned int num)
+static bool ignored_gdt(unsigned int num)
{
return (num == GDT_ENTRY_TSS
|| num == GDT_ENTRY_LGUEST_CS
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index bf7942327bd..a6b717644be 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -290,6 +290,57 @@ static int emulate_insn(struct lg_cpu *cpu)
return 1;
}
+/* Our hypercalls mechanism used to be based on direct software interrupts.
+ * After Anthony's "Refactor hypercall infrastructure" kvm patch, we decided to
+ * change over to using kvm hypercalls.
+ *
+ * KVM_HYPERCALL is actually a "vmcall" instruction, which generates an invalid
+ * opcode fault (fault 6) on non-VT cpus, so the easiest solution seemed to be
+ * an *emulation approach*: if the fault was really produced by an hypercall
+ * (is_hypercall() does exactly this check), we can just call the corresponding
+ * hypercall host implementation function.
+ *
+ * But these invalid opcode faults are notably slower than software interrupts.
+ * So we implemented the *patching (or rewriting) approach*: every time we hit
+ * the KVM_HYPERCALL opcode in Guest code, we patch it to the old "int 0x1f"
+ * opcode, so next time the Guest calls this hypercall it will use the
+ * faster trap mechanism.
+ *
+ * Matias even benchmarked it to convince you: this shows the average cycle
+ * cost of a hypercall. For each alternative solution mentioned above we've
+ * made 5 runs of the benchmark:
+ *
+ * 1) direct software interrupt: 2915, 2789, 2764, 2721, 2898
+ * 2) emulation technique: 3410, 3681, 3466, 3392, 3780
+ * 3) patching (rewrite) technique: 2977, 2975, 2891, 2637, 2884
+ *
+ * One two-line function is worth a 20% hypercall speed boost!
+ */
+static void rewrite_hypercall(struct lg_cpu *cpu)
+{
+ /* This are the opcodes we use to patch the Guest. The opcode for "int
+ * $0x1f" is "0xcd 0x1f" but vmcall instruction is 3 bytes long, so we
+ * complete the sequence with a NOP (0x90). */
+ u8 insn[3] = {0xcd, 0x1f, 0x90};
+
+ __lgwrite(cpu, guest_pa(cpu, cpu->regs->eip), insn, sizeof(insn));
+}
+
+static bool is_hypercall(struct lg_cpu *cpu)
+{
+ u8 insn[3];
+
+ /* This must be the Guest kernel trying to do something.
+ * The bottom two bits of the CS segment register are the privilege
+ * level. */
+ if ((cpu->regs->cs & 3) != GUEST_PL)
+ return false;
+
+ /* Is it a vmcall? */
+ __lgread(cpu, insn, guest_pa(cpu, cpu->regs->eip), sizeof(insn));
+ return insn[0] == 0x0f && insn[1] == 0x01 && insn[2] == 0xc1;
+}
+
/*H:050 Once we've re-enabled interrupts, we look at why the Guest exited. */
void lguest_arch_handle_trap(struct lg_cpu *cpu)
{
@@ -337,7 +388,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
break;
case 32 ... 255:
/* These values mean a real interrupt occurred, in which case
- * the Host handler has already been run. We just do a
+ * the Host handler has already been run. We just do a
* friendly check if another process should now be run, then
* return to run the Guest again */
cond_resched();
@@ -347,6 +398,15 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
* up the pointer now to indicate a hypercall is pending. */
cpu->hcall = (struct hcall_args *)cpu->regs;
return;
+ case 6:
+ /* kvm hypercalls trigger an invalid opcode fault (6).
+ * We need to check if ring == GUEST_PL and
+ * faulting instruction == vmcall. */
+ if (is_hypercall(cpu)) {
+ rewrite_hypercall(cpu);
+ return;
+ }
+ break;
}
/* We didn't handle the trap, so it needs to go to the Guest. */
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 82607add69a..c0621d50c8a 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -498,8 +498,8 @@ static ssize_t store_##name(struct device *dev, struct device_attribute *attr, c
#define BUILD_STORE_FUNC_INT(name, data) \
static ssize_t store_##name(struct device *dev, struct device_attribute *attr, const char *buf, size_t n) \
{ \
- u32 val; \
- val = simple_strtoul(buf, NULL, 10); \
+ int val; \
+ val = simple_strtol(buf, NULL, 10); \
if (val < 0 || val > 255) \
return -EINVAL; \
printk(KERN_INFO "Setting specified fan speed to %d\n", val); \
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig
index 2281b5098e9..36e0675be9f 100644
--- a/drivers/md/Kconfig
+++ b/drivers/md/Kconfig
@@ -121,6 +121,7 @@ config MD_RAID10
config MD_RAID456
tristate "RAID-4/RAID-5/RAID-6 mode"
depends on BLK_DEV_MD
+ select MD_RAID6_PQ
select ASYNC_MEMCPY
select ASYNC_XOR
---help---
@@ -151,34 +152,8 @@ config MD_RAID456
If unsure, say Y.
-config MD_RAID5_RESHAPE
- bool "Support adding drives to a raid-5 array"
- depends on MD_RAID456
- default y
- ---help---
- A RAID-5 set can be expanded by adding extra drives. This
- requires "restriping" the array which means (almost) every
- block must be written to a different place.
-
- This option allows such restriping to be done while the array
- is online.
-
- You will need mdadm version 2.4.1 or later to use this
- feature safely. During the early stage of reshape there is
- a critical section where live data is being over-written. A
- crash during this time needs extra care for recovery. The
- newer mdadm takes a copy of the data in the critical section
- and will restore it, if necessary, after a crash.
-
- The mdadm usage is e.g.
- mdadm --grow /dev/md1 --raid-disks=6
- to grow '/dev/md1' to having 6 disks.
-
- Note: The array can only be expanded, not contracted.
- There should be enough spares already present to make the new
- array workable.
-
- If unsure, say Y.
+config MD_RAID6_PQ
+ tristate
config MD_MULTIPATH
tristate "Multipath I/O support"
diff --git a/drivers/md/Makefile b/drivers/md/Makefile
index 72880b7e28d..45cc5951d92 100644
--- a/drivers/md/Makefile
+++ b/drivers/md/Makefile
@@ -2,20 +2,21 @@
# Makefile for the kernel software RAID and LVM drivers.
#
-dm-mod-objs := dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
+dm-mod-y += dm.o dm-table.o dm-target.o dm-linear.o dm-stripe.o \
dm-ioctl.o dm-io.o dm-kcopyd.o dm-sysfs.o
-dm-multipath-objs := dm-path-selector.o dm-mpath.o
-dm-snapshot-objs := dm-snap.o dm-exception-store.o dm-snap-transient.o \
+dm-multipath-y += dm-path-selector.o dm-mpath.o
+dm-snapshot-y += dm-snap.o dm-exception-store.o dm-snap-transient.o \
dm-snap-persistent.o
-dm-mirror-objs := dm-raid1.o
-md-mod-objs := md.o bitmap.o
-raid456-objs := raid5.o raid6algos.o raid6recov.o raid6tables.o \
+dm-mirror-y += dm-raid1.o
+md-mod-y += md.o bitmap.o
+raid456-y += raid5.o
+raid6_pq-y += raid6algos.o raid6recov.o raid6tables.o \
raid6int1.o raid6int2.o raid6int4.o \
raid6int8.o raid6int16.o raid6int32.o \
raid6altivec1.o raid6altivec2.o raid6altivec4.o \
raid6altivec8.o \
raid6mmx.o raid6sse1.o raid6sse2.o
-hostprogs-y := mktables
+hostprogs-y += mktables
# Note: link order is important. All raid personalities
# and must come before md.o, as they each initialise
@@ -26,6 +27,7 @@ obj-$(CONFIG_MD_LINEAR) += linear.o
obj-$(CONFIG_MD_RAID0) += raid0.o
obj-$(CONFIG_MD_RAID1) += raid1.o
obj-$(CONFIG_MD_RAID10) += raid10.o
+obj-$(CONFIG_MD_RAID6_PQ) += raid6_pq.o
obj-$(CONFIG_MD_RAID456) += raid456.o
obj-$(CONFIG_MD_MULTIPATH) += multipath.o
obj-$(CONFIG_MD_FAULTY) += faulty.o
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 71994376339..f8a9f7ab2cb 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -16,6 +16,7 @@
* wait if count gets too high, wake when it drops to half.
*/
+#include <linux/blkdev.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -26,8 +27,8 @@
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/buffer_head.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include "md.h"
+#include "bitmap.h"
/* debug macros */
@@ -111,9 +112,10 @@ static int bitmap_checkpage(struct bitmap *bitmap, unsigned long page, int creat
unsigned char *mappage;
if (page >= bitmap->pages) {
- printk(KERN_ALERT
- "%s: invalid bitmap page request: %lu (> %lu)\n",
- bmname(bitmap), page, bitmap->pages-1);
+ /* This can happen if bitmap_start_sync goes beyond
+ * End-of-device while looking for a whole page.
+ * It is harmless.
+ */
return -EINVAL;
}
@@ -265,7 +267,6 @@ static mdk_rdev_t *next_active_rdev(mdk_rdev_t *rdev, mddev_t *mddev)
list_for_each_continue_rcu(pos, &mddev->disks) {
rdev = list_entry(pos, mdk_rdev_t, same_set);
if (rdev->raid_disk >= 0 &&
- test_bit(In_sync, &rdev->flags) &&
!test_bit(Faulty, &rdev->flags)) {
/* this is a usable devices */
atomic_inc(&rdev->nr_pending);
@@ -297,7 +298,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait)
+ size/512 > 0)
/* bitmap runs in to metadata */
goto bad_alignment;
- if (rdev->data_offset + mddev->size*2
+ if (rdev->data_offset + mddev->dev_sectors
> rdev->sb_start + bitmap->offset)
/* data runs in to bitmap */
goto bad_alignment;
@@ -570,7 +571,7 @@ static int bitmap_read_sb(struct bitmap *bitmap)
else if (le32_to_cpu(sb->version) < BITMAP_MAJOR_LO ||
le32_to_cpu(sb->version) > BITMAP_MAJOR_HI)
reason = "unrecognized superblock version";
- else if (chunksize < PAGE_SIZE)
+ else if (chunksize < 512)
reason = "bitmap chunksize too small";
else if ((1 << ffz(~chunksize)) != chunksize)
reason = "bitmap chunksize not a power of 2";
@@ -1306,6 +1307,9 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
PRINTK(KERN_DEBUG "dec write-behind count %d/%d\n",
atomic_read(&bitmap->behind_writes), bitmap->max_write_behind);
}
+ if (bitmap->mddev->degraded)
+ /* Never clear bits or update events_cleared when degraded */
+ success = 0;
while (sectors) {
int blocks;
@@ -1345,8 +1349,8 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long secto
}
}
-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
- int degraded)
+static int __bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+ int degraded)
{
bitmap_counter_t *bmc;
int rv;
@@ -1374,6 +1378,29 @@ int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
return rv;
}
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,
+ int degraded)
+{
+ /* bitmap_start_sync must always report on multiples of whole
+ * pages, otherwise resync (which is very PAGE_SIZE based) will
+ * get confused.
+ * So call __bitmap_start_sync repeatedly (if needed) until
+ * At least PAGE_SIZE>>9 blocks are covered.
+ * Return the 'or' of the result.
+ */
+ int rv = 0;
+ int blocks1;
+
+ *blocks = 0;
+ while (*blocks < (PAGE_SIZE>>9)) {
+ rv |= __bitmap_start_sync(bitmap, offset,
+ &blocks1, degraded);
+ offset += blocks1;
+ *blocks += blocks1;
+ }
+ return rv;
+}
+
void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted)
{
bitmap_counter_t *bmc;
@@ -1443,6 +1470,8 @@ void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector)
wait_event(bitmap->mddev->recovery_wait,
atomic_read(&bitmap->mddev->recovery_active) == 0);
+ bitmap->mddev->curr_resync_completed = bitmap->mddev->curr_resync;
+ set_bit(MD_CHANGE_CLEAN, &bitmap->mddev->flags);
sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1);
s = 0;
while (s < sector && s < bitmap->mddev->resync_max_sectors) {
diff --git a/drivers/md/bitmap.h b/drivers/md/bitmap.h
new file mode 100644
index 00000000000..e98900671ca
--- /dev/null
+++ b/drivers/md/bitmap.h
@@ -0,0 +1,288 @@
+/*
+ * bitmap.h: Copyright (C) Peter T. Breuer (ptb@ot.uc3m.es) 2003
+ *
+ * additions: Copyright (C) 2003-2004, Paul Clements, SteelEye Technology, Inc.
+ */
+#ifndef BITMAP_H
+#define BITMAP_H 1
+
+#define BITMAP_MAJOR_LO 3
+/* version 4 insists the bitmap is in little-endian order
+ * with version 3, it is host-endian which is non-portable
+ */
+#define BITMAP_MAJOR_HI 4
+#define BITMAP_MAJOR_HOSTENDIAN 3
+
+#define BITMAP_MINOR 39
+
+/*
+ * in-memory bitmap:
+ *
+ * Use 16 bit block counters to track pending writes to each "chunk".
+ * The 2 high order bits are special-purpose, the first is a flag indicating
+ * whether a resync is needed. The second is a flag indicating whether a
+ * resync is active.
+ * This means that the counter is actually 14 bits:
+ *
+ * +--------+--------+------------------------------------------------+
+ * | resync | resync | counter |
+ * | needed | active | |
+ * | (0-1) | (0-1) | (0-16383) |
+ * +--------+--------+------------------------------------------------+
+ *
+ * The "resync needed" bit is set when:
+ * a '1' bit is read from storage at startup.
+ * a write request fails on some drives
+ * a resync is aborted on a chunk with 'resync active' set
+ * It is cleared (and resync-active set) when a resync starts across all drives
+ * of the chunk.
+ *
+ *
+ * The "resync active" bit is set when:
+ * a resync is started on all drives, and resync_needed is set.
+ * resync_needed will be cleared (as long as resync_active wasn't already set).
+ * It is cleared when a resync completes.
+ *
+ * The counter counts pending write requests, plus the on-disk bit.
+ * When the counter is '1' and the resync bits are clear, the on-disk
+ * bit can be cleared aswell, thus setting the counter to 0.
+ * When we set a bit, or in the counter (to start a write), if the fields is
+ * 0, we first set the disk bit and set the counter to 1.
+ *
+ * If the counter is 0, the on-disk bit is clear and the stipe is clean
+ * Anything that dirties the stipe pushes the counter to 2 (at least)
+ * and sets the on-disk bit (lazily).
+ * If a periodic sweep find the counter at 2, it is decremented to 1.
+ * If the sweep find the counter at 1, the on-disk bit is cleared and the
+ * counter goes to zero.
+ *
+ * Also, we'll hijack the "map" pointer itself and use it as two 16 bit block
+ * counters as a fallback when "page" memory cannot be allocated:
+ *
+ * Normal case (page memory allocated):
+ *
+ * page pointer (32-bit)
+ *
+ * [ ] ------+
+ * |
+ * +-------> [ ][ ]..[ ] (4096 byte page == 2048 counters)
+ * c1 c2 c2048
+ *
+ * Hijacked case (page memory allocation failed):
+ *
+ * hijacked page pointer (32-bit)
+ *
+ * [ ][ ] (no page memory allocated)
+ * counter #1 (16-bit) counter #2 (16-bit)
+ *
+ */
+
+#ifdef __KERNEL__
+
+#define PAGE_BITS (PAGE_SIZE << 3)
+#define PAGE_BIT_SHIFT (PAGE_SHIFT + 3)
+
+typedef __u16 bitmap_counter_t;
+#define COUNTER_BITS 16
+#define COUNTER_BIT_SHIFT 4
+#define COUNTER_BYTE_RATIO (COUNTER_BITS / 8)
+#define COUNTER_BYTE_SHIFT (COUNTER_BIT_SHIFT - 3)
+
+#define NEEDED_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 1)))
+#define RESYNC_MASK ((bitmap_counter_t) (1 << (COUNTER_BITS - 2)))
+#define COUNTER_MAX ((bitmap_counter_t) RESYNC_MASK - 1)
+#define NEEDED(x) (((bitmap_counter_t) x) & NEEDED_MASK)
+#define RESYNC(x) (((bitmap_counter_t) x) & RESYNC_MASK)
+#define COUNTER(x) (((bitmap_counter_t) x) & COUNTER_MAX)
+
+/* how many counters per page? */
+#define PAGE_COUNTER_RATIO (PAGE_BITS / COUNTER_BITS)
+/* same, except a shift value for more efficient bitops */
+#define PAGE_COUNTER_SHIFT (PAGE_BIT_SHIFT - COUNTER_BIT_SHIFT)
+/* same, except a mask value for more efficient bitops */
+#define PAGE_COUNTER_MASK (PAGE_COUNTER_RATIO - 1)
+
+#define BITMAP_BLOCK_SIZE 512
+#define BITMAP_BLOCK_SHIFT 9
+
+/* how many blocks per chunk? (this is variable) */
+#define CHUNK_BLOCK_RATIO(bitmap) ((bitmap)->chunksize >> BITMAP_BLOCK_SHIFT)
+#define CHUNK_BLOCK_SHIFT(bitmap) ((bitmap)->chunkshift - BITMAP_BLOCK_SHIFT)
+#define CHUNK_BLOCK_MASK(bitmap) (CHUNK_BLOCK_RATIO(bitmap) - 1)
+
+/* when hijacked, the counters and bits represent even larger "chunks" */
+/* there will be 1024 chunks represented by each counter in the page pointers */
+#define PAGEPTR_BLOCK_RATIO(bitmap) \
+ (CHUNK_BLOCK_RATIO(bitmap) << PAGE_COUNTER_SHIFT >> 1)
+#define PAGEPTR_BLOCK_SHIFT(bitmap) \
+ (CHUNK_BLOCK_SHIFT(bitmap) + PAGE_COUNTER_SHIFT - 1)
+#define PAGEPTR_BLOCK_MASK(bitmap) (PAGEPTR_BLOCK_RATIO(bitmap) - 1)
+
+/*
+ * on-disk bitmap:
+ *
+ * Use one bit per "chunk" (block set). We do the disk I/O on the bitmap
+ * file a page at a time. There's a superblock at the start of the file.
+ */
+
+/* map chunks (bits) to file pages - offset by the size of the superblock */
+#define CHUNK_BIT_OFFSET(chunk) ((chunk) + (sizeof(bitmap_super_t) << 3))
+
+#endif
+
+/*
+ * bitmap structures:
+ */
+
+#define BITMAP_MAGIC 0x6d746962
+
+/* use these for bitmap->flags and bitmap->sb->state bit-fields */
+enum bitmap_state {
+ BITMAP_STALE = 0x002, /* the bitmap file is out of date or had -EIO */
+ BITMAP_WRITE_ERROR = 0x004, /* A write error has occurred */
+ BITMAP_HOSTENDIAN = 0x8000,
+};
+
+/* the superblock at the front of the bitmap file -- little endian */
+typedef struct bitmap_super_s {
+ __le32 magic; /* 0 BITMAP_MAGIC */
+ __le32 version; /* 4 the bitmap major for now, could change... */
+ __u8 uuid[16]; /* 8 128 bit uuid - must match md device uuid */
+ __le64 events; /* 24 event counter for the bitmap (1)*/
+ __le64 events_cleared;/*32 event counter when last bit cleared (2) */
+ __le64 sync_size; /* 40 the size of the md device's sync range(3) */
+ __le32 state; /* 48 bitmap state information */
+ __le32 chunksize; /* 52 the bitmap chunk size in bytes */
+ __le32 daemon_sleep; /* 56 seconds between disk flushes */
+ __le32 write_behind; /* 60 number of outstanding write-behind writes */
+
+ __u8 pad[256 - 64]; /* set to zero */
+} bitmap_super_t;
+
+/* notes:
+ * (1) This event counter is updated before the eventcounter in the md superblock
+ * When a bitmap is loaded, it is only accepted if this event counter is equal
+ * to, or one greater than, the event counter in the superblock.
+ * (2) This event counter is updated when the other one is *if*and*only*if* the
+ * array is not degraded. As bits are not cleared when the array is degraded,
+ * this represents the last time that any bits were cleared.
+ * If a device is being added that has an event count with this value or
+ * higher, it is accepted as conforming to the bitmap.
+ * (3)This is the number of sectors represented by the bitmap, and is the range that
+ * resync happens across. For raid1 and raid5/6 it is the size of individual
+ * devices. For raid10 it is the size of the array.
+ */
+
+#ifdef __KERNEL__
+
+/* the in-memory bitmap is represented by bitmap_pages */
+struct bitmap_page {
+ /*
+ * map points to the actual memory page
+ */
+ char *map;
+ /*
+ * in emergencies (when map cannot be alloced), hijack the map
+ * pointer and use it as two counters itself
+ */
+ unsigned int hijacked:1;
+ /*
+ * count of dirty bits on the page
+ */
+ unsigned int count:31;
+};
+
+/* keep track of bitmap file pages that have pending writes on them */
+struct page_list {
+ struct list_head list;
+ struct page *page;
+};
+
+/* the main bitmap structure - one per mddev */
+struct bitmap {
+ struct bitmap_page *bp;
+ unsigned long pages; /* total number of pages in the bitmap */
+ unsigned long missing_pages; /* number of pages not yet allocated */
+
+ mddev_t *mddev; /* the md device that the bitmap is for */
+
+ int counter_bits; /* how many bits per block counter */
+
+ /* bitmap chunksize -- how much data does each bit represent? */
+ unsigned long chunksize;
+ unsigned long chunkshift; /* chunksize = 2^chunkshift (for bitops) */
+ unsigned long chunks; /* total number of data chunks for the array */
+
+ /* We hold a count on the chunk currently being synced, and drop
+ * it when the last block is started. If the resync is aborted
+ * midway, we need to be able to drop that count, so we remember
+ * the counted chunk..
+ */
+ unsigned long syncchunk;
+
+ __u64 events_cleared;
+ int need_sync;
+
+ /* bitmap spinlock */
+ spinlock_t lock;
+
+ long offset; /* offset from superblock if file is NULL */
+ struct file *file; /* backing disk file */
+ struct page *sb_page; /* cached copy of the bitmap file superblock */
+ struct page **filemap; /* list of cache pages for the file */
+ unsigned long *filemap_attr; /* attributes associated w/ filemap pages */
+ unsigned long file_pages; /* number of pages in the file */
+ int last_page_size; /* bytes in the last page */
+
+ unsigned long flags;
+
+ int allclean;
+
+ unsigned long max_write_behind; /* write-behind mode */
+ atomic_t behind_writes;
+
+ /*
+ * the bitmap daemon - periodically wakes up and sweeps the bitmap
+ * file, cleaning up bits and flushing out pages to disk as necessary
+ */
+ unsigned long daemon_lastrun; /* jiffies of last run */
+ unsigned long daemon_sleep; /* how many seconds between updates? */
+ unsigned long last_end_sync; /* when we lasted called end_sync to
+ * update bitmap with resync progress */
+
+ atomic_t pending_writes; /* pending writes to the bitmap file */
+ wait_queue_head_t write_wait;
+ wait_queue_head_t overflow_wait;
+
+};
+
+/* the bitmap API */
+
+/* these are used only by md/bitmap */
+int bitmap_create(mddev_t *mddev);
+void bitmap_flush(mddev_t *mddev);
+void bitmap_destroy(mddev_t *mddev);
+
+void bitmap_print_sb(struct bitmap *bitmap);
+void bitmap_update_sb(struct bitmap *bitmap);
+
+int bitmap_setallbits(struct bitmap *bitmap);
+void bitmap_write_all(struct bitmap *bitmap);
+
+void bitmap_dirty_bits(struct bitmap *bitmap, unsigned long s, unsigned long e);
+
+/* these are exported */
+int bitmap_startwrite(struct bitmap *bitmap, sector_t offset,
+ unsigned long sectors, int behind);
+void bitmap_endwrite(struct bitmap *bitmap, sector_t offset,
+ unsigned long sectors, int success, int behind);
+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);
+void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);
+void bitmap_close_sync(struct bitmap *bitmap);
+void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector);
+
+void bitmap_unplug(struct bitmap *bitmap);
+void bitmap_daemon_work(struct bitmap *bitmap);
+#endif
+
+#endif
diff --git a/drivers/md/dm-bio-list.h b/drivers/md/dm-bio-list.h
index d4509be0fe6..345098b4ca7 100644
--- a/drivers/md/dm-bio-list.h
+++ b/drivers/md/dm-bio-list.h
@@ -52,6 +52,16 @@ static inline void bio_list_add(struct bio_list *bl, struct bio *bio)
bl->tail = bio;
}
+static inline void bio_list_add_head(struct bio_list *bl, struct bio *bio)
+{
+ bio->bi_next = bl->head;
+
+ bl->head = bio;
+
+ if (!bl->tail)
+ bl->tail = bio;
+}
+
static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2)
{
if (!bl2->head)
diff --git a/drivers/md/dm-bio-record.h b/drivers/md/dm-bio-record.h
index d3ec217847d..3a8cfa2645c 100644
--- a/drivers/md/dm-bio-record.h
+++ b/drivers/md/dm-bio-record.h
@@ -16,30 +16,56 @@
* functions in this file help the target record and restore the
* original bio state.
*/
+
+struct dm_bio_vec_details {
+#if PAGE_SIZE < 65536
+ __u16 bv_len;
+ __u16 bv_offset;
+#else
+ unsigned bv_len;
+ unsigned bv_offset;
+#endif
+};
+
struct dm_bio_details {
sector_t bi_sector;
struct block_device *bi_bdev;
unsigned int bi_size;
unsigned short bi_idx;
unsigned long bi_flags;
+ struct dm_bio_vec_details bi_io_vec[BIO_MAX_PAGES];
};
static inline void dm_bio_record(struct dm_bio_details *bd, struct bio *bio)
{
+ unsigned i;
+
bd->bi_sector = bio->bi_sector;
bd->bi_bdev = bio->bi_bdev;
bd->bi_size = bio->bi_size;
bd->bi_idx = bio->bi_idx;
bd->bi_flags = bio->bi_flags;
+
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ bd->bi_io_vec[i].bv_len = bio->bi_io_vec[i].bv_len;
+ bd->bi_io_vec[i].bv_offset = bio->bi_io_vec[i].bv_offset;
+ }
}
static inline void dm_bio_restore(struct dm_bio_details *bd, struct bio *bio)
{
+ unsigned i;
+
bio->bi_sector = bd->bi_sector;
bio->bi_bdev = bd->bi_bdev;
bio->bi_size = bd->bi_size;
bio->bi_idx = bd->bi_idx;
bio->bi_flags = bd->bi_flags;
+
+ for (i = 0; i < bio->bi_vcnt; i++) {
+ bio->bi_io_vec[i].bv_len = bd->bi_io_vec[i].bv_len;
+ bio->bi_io_vec[i].bv_offset = bd->bi_io_vec[i].bv_offset;
+ }
}
#endif
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index bfefd079a95..53394e863c7 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1156,8 +1156,7 @@ bad_ivmode:
crypto_free_ablkcipher(tfm);
bad_cipher:
/* Must zero key material before freeing */
- memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
- kfree(cc);
+ kzfree(cc);
return -EINVAL;
}
@@ -1183,8 +1182,7 @@ static void crypt_dtr(struct dm_target *ti)
dm_put_device(ti, cc->dev);
/* Must zero key material before freeing */
- memset(cc, 0, sizeof(*cc) + cc->key_size * sizeof(u8));
- kfree(cc);
+ kzfree(cc);
}
static int crypt_map(struct dm_target *ti, struct bio *bio,
diff --git a/drivers/md/dm-exception-store.c b/drivers/md/dm-exception-store.c
index dccbfb0e010..a2e26c24214 100644
--- a/drivers/md/dm-exception-store.c
+++ b/drivers/md/dm-exception-store.c
@@ -7,6 +7,7 @@
#include "dm-exception-store.h"
+#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
#include <linux/vmalloc.h>
@@ -14,6 +15,257 @@
#define DM_MSG_PREFIX "snapshot exception stores"
+static LIST_HEAD(_exception_store_types);
+static DEFINE_SPINLOCK(_lock);
+
+static struct dm_exception_store_type *__find_exception_store_type(const char *name)
+{
+ struct dm_exception_store_type *type;
+
+ list_for_each_entry(type, &_exception_store_types, list)
+ if (!strcmp(name, type->name))
+ return type;
+
+ return NULL;
+}
+
+static struct dm_exception_store_type *_get_exception_store_type(const char *name)
+{
+ struct dm_exception_store_type *type;
+
+ spin_lock(&_lock);
+
+ type = __find_exception_store_type(name);
+
+ if (type && !try_module_get(type->module))
+ type = NULL;
+
+ spin_unlock(&_lock);
+
+ return type;
+}
+
+/*
+ * get_type
+ * @type_name
+ *
+ * Attempt to retrieve the dm_exception_store_type by name. If not already
+ * available, attempt to load the appropriate module.
+ *
+ * Exstore modules are named "dm-exstore-" followed by the 'type_name'.
+ * Modules may contain multiple types.
+ * This function will first try the module "dm-exstore-<type_name>",
+ * then truncate 'type_name' on the last '-' and try again.
+ *
+ * For example, if type_name was "clustered-shared", it would search
+ * 'dm-exstore-clustered-shared' then 'dm-exstore-clustered'.
+ *
+ * 'dm-exception-store-<type_name>' is too long of a name in my
+ * opinion, which is why I've chosen to have the files
+ * containing exception store implementations be 'dm-exstore-<type_name>'.
+ * If you want your module to be autoloaded, you will follow this
+ * naming convention.
+ *
+ * Returns: dm_exception_store_type* on success, NULL on failure
+ */
+static struct dm_exception_store_type *get_type(const char *type_name)
+{
+ char *p, *type_name_dup;
+ struct dm_exception_store_type *type;
+
+ type = _get_exception_store_type(type_name);
+ if (type)
+ return type;
+
+ type_name_dup = kstrdup(type_name, GFP_KERNEL);
+ if (!type_name_dup) {
+ DMERR("No memory left to attempt load for \"%s\"", type_name);
+ return NULL;
+ }
+
+ while (request_module("dm-exstore-%s", type_name_dup) ||
+ !(type = _get_exception_store_type(type_name))) {
+ p = strrchr(type_name_dup, '-');
+ if (!p)
+ break;
+ p[0] = '\0';
+ }
+
+ if (!type)
+ DMWARN("Module for exstore type \"%s\" not found.", type_name);
+
+ kfree(type_name_dup);
+
+ return type;
+}
+
+static void put_type(struct dm_exception_store_type *type)
+{
+ spin_lock(&_lock);
+ module_put(type->module);
+ spin_unlock(&_lock);
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type)
+{
+ int r = 0;
+
+ spin_lock(&_lock);
+ if (!__find_exception_store_type(type->name))
+ list_add(&type->list, &_exception_store_types);
+ else
+ r = -EEXIST;
+ spin_unlock(&_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(dm_exception_store_type_register);
+
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type)
+{
+ spin_lock(&_lock);
+
+ if (!__find_exception_store_type(type->name)) {
+ spin_unlock(&_lock);
+ return -EINVAL;
+ }
+
+ list_del(&type->list);
+
+ spin_unlock(&_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(dm_exception_store_type_unregister);
+
+/*
+ * Round a number up to the nearest 'size' boundary. size must
+ * be a power of 2.
+ */
+static ulong round_up(ulong n, ulong size)
+{
+ size--;
+ return (n + size) & ~size;
+}
+
+static int set_chunk_size(struct dm_exception_store *store,
+ const char *chunk_size_arg, char **error)
+{
+ unsigned long chunk_size_ulong;
+ char *value;
+
+ chunk_size_ulong = simple_strtoul(chunk_size_arg, &value, 10);
+ if (*chunk_size_arg == '\0' || *value != '\0') {
+ *error = "Invalid chunk size";
+ return -EINVAL;
+ }
+
+ if (!chunk_size_ulong) {
+ store->chunk_size = store->chunk_mask = store->chunk_shift = 0;
+ return 0;
+ }
+
+ /*
+ * Chunk size must be multiple of page size. Silently
+ * round up if it's not.
+ */
+ chunk_size_ulong = round_up(chunk_size_ulong, PAGE_SIZE >> 9);
+
+ /* Check chunk_size is a power of 2 */
+ if (!is_power_of_2(chunk_size_ulong)) {
+ *error = "Chunk size is not a power of 2";
+ return -EINVAL;
+ }
+
+ /* Validate the chunk size against the device block size */
+ if (chunk_size_ulong % (bdev_hardsect_size(store->cow->bdev) >> 9)) {
+ *error = "Chunk size is not a multiple of device blocksize";
+ return -EINVAL;
+ }
+
+ store->chunk_size = chunk_size_ulong;
+ store->chunk_mask = chunk_size_ulong - 1;
+ store->chunk_shift = ffs(chunk_size_ulong) - 1;
+
+ return 0;
+}
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ unsigned *args_used,
+ struct dm_exception_store **store)
+{
+ int r = 0;
+ struct dm_exception_store_type *type;
+ struct dm_exception_store *tmp_store;
+ char persistent;
+
+ if (argc < 3) {
+ ti->error = "Insufficient exception store arguments";
+ return -EINVAL;
+ }
+
+ tmp_store = kmalloc(sizeof(*tmp_store), GFP_KERNEL);
+ if (!tmp_store) {
+ ti->error = "Exception store allocation failed";
+ return -ENOMEM;
+ }
+
+ persistent = toupper(*argv[1]);
+ if (persistent != 'P' && persistent != 'N') {
+ ti->error = "Persistent flag is not P or N";
+ return -EINVAL;
+ }
+
+ type = get_type(argv[1]);
+ if (!type) {
+ ti->error = "Exception store type not recognised";
+ r = -EINVAL;
+ goto bad_type;
+ }
+
+ tmp_store->type = type;
+ tmp_store->ti = ti;
+
+ r = dm_get_device(ti, argv[0], 0, 0,
+ FMODE_READ | FMODE_WRITE, &tmp_store->cow);
+ if (r) {
+ ti->error = "Cannot get COW device";
+ goto bad_cow;
+ }
+
+ r = set_chunk_size(tmp_store, argv[2], &ti->error);
+ if (r)
+ goto bad_cow;
+
+ r = type->ctr(tmp_store, 0, NULL);
+ if (r) {
+ ti->error = "Exception store type constructor failed";
+ goto bad_ctr;
+ }
+
+ *args_used = 3;
+ *store = tmp_store;
+ return 0;
+
+bad_ctr:
+ dm_put_device(ti, tmp_store->cow);
+bad_cow:
+ put_type(type);
+bad_type:
+ kfree(tmp_store);
+ return r;
+}
+EXPORT_SYMBOL(dm_exception_store_create);
+
+void dm_exception_store_destroy(struct dm_exception_store *store)
+{
+ store->type->dtr(store);
+ dm_put_device(store->ti, store->cow);
+ put_type(store->type);
+ kfree(store);
+}
+EXPORT_SYMBOL(dm_exception_store_destroy);
+
int dm_exception_store_init(void)
{
int r;
diff --git a/drivers/md/dm-exception-store.h b/drivers/md/dm-exception-store.h
index bb9f33d5daa..0a2e6e7f67b 100644
--- a/drivers/md/dm-exception-store.h
+++ b/drivers/md/dm-exception-store.h
@@ -37,11 +37,18 @@ struct dm_snap_exception {
* Abstraction to handle the meta/layout of exception stores (the
* COW device).
*/
-struct dm_exception_store {
+struct dm_exception_store;
+struct dm_exception_store_type {
+ const char *name;
+ struct module *module;
+
+ int (*ctr) (struct dm_exception_store *store,
+ unsigned argc, char **argv);
+
/*
* Destroys this object when you've finished with it.
*/
- void (*destroy) (struct dm_exception_store *store);
+ void (*dtr) (struct dm_exception_store *store);
/*
* The target shouldn't read the COW device until this is
@@ -72,8 +79,9 @@ struct dm_exception_store {
*/
void (*drop_snapshot) (struct dm_exception_store *store);
- int (*status) (struct dm_exception_store *store, status_type_t status,
- char *result, unsigned int maxlen);
+ unsigned (*status) (struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen);
/*
* Return how full the snapshot is.
@@ -82,7 +90,21 @@ struct dm_exception_store {
sector_t *numerator,
sector_t *denominator);
- struct dm_snapshot *snap;
+ /* For internal device-mapper use only. */
+ struct list_head list;
+};
+
+struct dm_exception_store {
+ struct dm_exception_store_type *type;
+ struct dm_target *ti;
+
+ struct dm_dev *cow;
+
+ /* Size of data blocks saved - must be a power of 2 */
+ chunk_t chunk_size;
+ chunk_t chunk_mask;
+ chunk_t chunk_shift;
+
void *context;
};
@@ -129,6 +151,28 @@ static inline void dm_consecutive_chunk_count_inc(struct dm_snap_exception *e)
# endif
+/*
+ * Return the number of sectors in the device.
+ */
+static inline sector_t get_dev_size(struct block_device *bdev)
+{
+ return bdev->bd_inode->i_size >> SECTOR_SHIFT;
+}
+
+static inline chunk_t sector_to_chunk(struct dm_exception_store *store,
+ sector_t sector)
+{
+ return (sector & ~store->chunk_mask) >> store->chunk_shift;
+}
+
+int dm_exception_store_type_register(struct dm_exception_store_type *type);
+int dm_exception_store_type_unregister(struct dm_exception_store_type *type);
+
+int dm_exception_store_create(struct dm_target *ti, int argc, char **argv,
+ unsigned *args_used,
+ struct dm_exception_store **store);
+void dm_exception_store_destroy(struct dm_exception_store *store);
+
int dm_exception_store_init(void);
void dm_exception_store_exit(void);
@@ -141,8 +185,4 @@ void dm_persistent_snapshot_exit(void);
int dm_transient_snapshot_init(void);
void dm_transient_snapshot_exit(void);
-int dm_create_persistent(struct dm_exception_store *store);
-
-int dm_create_transient(struct dm_exception_store *store);
-
#endif /* _LINUX_DM_EXCEPTION_STORE */
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 36e2b5e46a6..e73aabd61cd 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -370,16 +370,13 @@ static int sync_io(struct dm_io_client *client, unsigned int num_regions,
while (1) {
set_current_state(TASK_UNINTERRUPTIBLE);
- if (!atomic_read(&io.count) || signal_pending(current))
+ if (!atomic_read(&io.count))
break;
io_schedule();
}
set_current_state(TASK_RUNNING);
- if (atomic_read(&io.count))
- return -EINTR;
-
if (error_bits)
*error_bits = io.error_bits;
diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c
index 737961f275c..be233bc4d91 100644
--- a/drivers/md/dm-log.c
+++ b/drivers/md/dm-log.c
@@ -16,40 +16,29 @@
#define DM_MSG_PREFIX "dirty region log"
-struct dm_dirty_log_internal {
- struct dm_dirty_log_type *type;
-
- struct list_head list;
- long use;
-};
-
static LIST_HEAD(_log_types);
static DEFINE_SPINLOCK(_lock);
-static struct dm_dirty_log_internal *__find_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *__find_dirty_log_type(const char *name)
{
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
list_for_each_entry(log_type, &_log_types, list)
- if (!strcmp(name, log_type->type->name))
+ if (!strcmp(name, log_type->name))
return log_type;
return NULL;
}
-static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
+static struct dm_dirty_log_type *_get_dirty_log_type(const char *name)
{
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
spin_lock(&_lock);
log_type = __find_dirty_log_type(name);
- if (log_type) {
- if (!log_type->use && !try_module_get(log_type->type->module))
- log_type = NULL;
- else
- log_type->use++;
- }
+ if (log_type && !try_module_get(log_type->module))
+ log_type = NULL;
spin_unlock(&_lock);
@@ -76,14 +65,14 @@ static struct dm_dirty_log_internal *_get_dirty_log_type(const char *name)
static struct dm_dirty_log_type *get_type(const char *type_name)
{
char *p, *type_name_dup;
- struct dm_dirty_log_internal *log_type;
+ struct dm_dirty_log_type *log_type;
if (!type_name)
return NULL;
log_type = _get_dirty_log_type(type_name);
if (log_type)
- return log_type->type;
+ return log_type;
type_name_dup = kstrdup(type_name, GFP_KERNEL);
if (!type_name_dup) {
@@ -105,56 +94,33 @@ static struct dm_dirty_log_type *get_type(const char *type_name)
kfree(type_name_dup);
- return log_type ? log_type->type : NULL;
+ return log_type;
}
static void put_type(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type;
-
if (!type)
return;
spin_lock(&_lock);
- log_type = __find_dirty_log_type(type->name);
- if (!log_type)
+ if (!__find_dirty_log_type(type->name))
goto out;
- if (!--log_type->use)
- module_put(type->module);
-
- BUG_ON(log_type->use < 0);
+ module_put(type->module);
out:
spin_unlock(&_lock);
}
-static struct dm_dirty_log_internal *_alloc_dirty_log_type(struct dm_dirty_log_type *type)
-{
- struct dm_dirty_log_internal *log_type = kzalloc(sizeof(*log_type),
- GFP_KERNEL);
-
- if (log_type)
- log_type->type = type;
-
- return log_type;
-}
-
int dm_dirty_log_type_register(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type = _alloc_dirty_log_type(type);
int r = 0;
- if (!log_type)
- return -ENOMEM;
-
spin_lock(&_lock);
if (!__find_dirty_log_type(type->name))
- list_add(&log_type->list, &_log_types);
- else {
- kfree(log_type);
+ list_add(&type->list, &_log_types);
+ else
r = -EEXIST;
- }
spin_unlock(&_lock);
return r;
@@ -163,25 +129,16 @@ EXPORT_SYMBOL(dm_dirty_log_type_register);
int dm_dirty_log_type_unregister(struct dm_dirty_log_type *type)
{
- struct dm_dirty_log_internal *log_type;
-
spin_lock(&_lock);
- log_type = __find_dirty_log_type(type->name);
- if (!log_type) {
+ if (!__find_dirty_log_type(type->name)) {
spin_unlock(&_lock);
return -EINVAL;
}
- if (log_type->use) {
- spin_unlock(&_lock);
- return -ETXTBSY;
- }
-
- list_del(&log_type->list);
+ list_del(&type->list);
spin_unlock(&_lock);
- kfree(log_type);
return 0;
}
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c
index 96ea226155b..42c04f04a0c 100644
--- a/drivers/md/dm-path-selector.c
+++ b/drivers/md/dm-path-selector.c
@@ -17,9 +17,7 @@
struct ps_internal {
struct path_selector_type pst;
-
struct list_head list;
- long use;
};
#define pst_to_psi(__pst) container_of((__pst), struct ps_internal, pst)
@@ -45,12 +43,8 @@ static struct ps_internal *get_path_selector(const char *name)
down_read(&_ps_lock);
psi = __find_path_selector_type(name);
- if (psi) {
- if ((psi->use == 0) && !try_module_get(psi->pst.module))
- psi = NULL;
- else
- psi->use++;
- }
+ if (psi && !try_module_get(psi->pst.module))
+ psi = NULL;
up_read(&_ps_lock);
return psi;
@@ -84,11 +78,7 @@ void dm_put_path_selector(struct path_selector_type *pst)
if (!psi)
goto out;
- if (--psi->use == 0)
- module_put(psi->pst.module);
-
- BUG_ON(psi->use < 0);
-
+ module_put(psi->pst.module);
out:
up_read(&_ps_lock);
}
@@ -136,11 +126,6 @@ int dm_unregister_path_selector(struct path_selector_type *pst)
return -EINVAL;
}
- if (psi->use) {
- up_write(&_ps_lock);
- return -ETXTBSY;
- }
-
list_del(&psi->list);
up_write(&_ps_lock);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 4d6bc101962..536ef0bef15 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -145,6 +145,8 @@ struct dm_raid1_read_record {
struct dm_bio_details details;
};
+static struct kmem_cache *_dm_raid1_read_record_cache;
+
/*
* Every mirror should look like this one.
*/
@@ -586,6 +588,9 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
int state;
struct bio *bio;
struct bio_list sync, nosync, recover, *this_list = NULL;
+ struct bio_list requeue;
+ struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
+ region_t region;
if (!writes->head)
return;
@@ -596,10 +601,18 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
bio_list_init(&sync);
bio_list_init(&nosync);
bio_list_init(&recover);
+ bio_list_init(&requeue);
while ((bio = bio_list_pop(writes))) {
- state = dm_rh_get_state(ms->rh,
- dm_rh_bio_to_region(ms->rh, bio), 1);
+ region = dm_rh_bio_to_region(ms->rh, bio);
+
+ if (log->type->is_remote_recovering &&
+ log->type->is_remote_recovering(log, region)) {
+ bio_list_add(&requeue, bio);
+ continue;
+ }
+
+ state = dm_rh_get_state(ms->rh, region, 1);
switch (state) {
case DM_RH_CLEAN:
case DM_RH_DIRTY:
@@ -619,6 +632,16 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
}
/*
+ * Add bios that are delayed due to remote recovery
+ * back on to the write queue
+ */
+ if (unlikely(requeue.head)) {
+ spin_lock_irq(&ms->lock);
+ bio_list_merge(&ms->writes, &requeue);
+ spin_unlock_irq(&ms->lock);
+ }
+
+ /*
* Increment the pending counts for any regions that will
* be written to (writes to recover regions are going to
* be delayed).
@@ -764,9 +787,9 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
atomic_set(&ms->suspend, 0);
atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
- len = sizeof(struct dm_raid1_read_record);
- ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS,
- len);
+ ms->read_record_pool = mempool_create_slab_pool(MIN_READ_RECORDS,
+ _dm_raid1_read_record_cache);
+
if (!ms->read_record_pool) {
ti->error = "Error creating mirror read_record_pool";
kfree(ms);
@@ -1279,16 +1302,31 @@ static int __init dm_mirror_init(void)
{
int r;
+ _dm_raid1_read_record_cache = KMEM_CACHE(dm_raid1_read_record, 0);
+ if (!_dm_raid1_read_record_cache) {
+ DMERR("Can't allocate dm_raid1_read_record cache");
+ r = -ENOMEM;
+ goto bad_cache;
+ }
+
r = dm_register_target(&mirror_target);
- if (r < 0)
+ if (r < 0) {
DMERR("Failed to register mirror target");
+ goto bad_target;
+ }
+
+ return 0;
+bad_target:
+ kmem_cache_destroy(_dm_raid1_read_record_cache);
+bad_cache:
return r;
}
static void __exit dm_mirror_exit(void)
{
dm_unregister_target(&mirror_target);
+ kmem_cache_destroy(_dm_raid1_read_record_cache);
}
/* Module hooks */
diff --git a/drivers/md/dm-snap-persistent.c b/drivers/md/dm-snap-persistent.c
index 936b34e0959..e75c6dd76a9 100644
--- a/drivers/md/dm-snap-persistent.c
+++ b/drivers/md/dm-snap-persistent.c
@@ -6,7 +6,6 @@
*/
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include <linux/mm.h>
#include <linux/pagemap.h>
@@ -89,7 +88,7 @@ struct commit_callback {
* The top level structure for a persistent exception store.
*/
struct pstore {
- struct dm_snapshot *snap; /* up pointer to my snapshot */
+ struct dm_exception_store *store;
int version;
int valid;
uint32_t exceptions_per_area;
@@ -141,7 +140,7 @@ static int alloc_area(struct pstore *ps)
int r = -ENOMEM;
size_t len;
- len = ps->snap->chunk_size << SECTOR_SHIFT;
+ len = ps->store->chunk_size << SECTOR_SHIFT;
/*
* Allocate the chunk_size block of memory that will hold
@@ -163,9 +162,12 @@ static int alloc_area(struct pstore *ps)
static void free_area(struct pstore *ps)
{
- vfree(ps->area);
+ if (ps->area)
+ vfree(ps->area);
ps->area = NULL;
- vfree(ps->zero_area);
+
+ if (ps->zero_area)
+ vfree(ps->zero_area);
ps->zero_area = NULL;
}
@@ -189,9 +191,9 @@ static void do_metadata(struct work_struct *work)
static int chunk_io(struct pstore *ps, chunk_t chunk, int rw, int metadata)
{
struct dm_io_region where = {
- .bdev = ps->snap->cow->bdev,
- .sector = ps->snap->chunk_size * chunk,
- .count = ps->snap->chunk_size,
+ .bdev = ps->store->cow->bdev,
+ .sector = ps->store->chunk_size * chunk,
+ .count = ps->store->chunk_size,
};
struct dm_io_request io_req = {
.bi_rw = rw,
@@ -247,15 +249,15 @@ static int area_io(struct pstore *ps, int rw)
static void zero_memory_area(struct pstore *ps)
{
- memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
}
static int zero_disk_area(struct pstore *ps, chunk_t area)
{
struct dm_io_region where = {
- .bdev = ps->snap->cow->bdev,
- .sector = ps->snap->chunk_size * area_location(ps, area),
- .count = ps->snap->chunk_size,
+ .bdev = ps->store->cow->bdev,
+ .sector = ps->store->chunk_size * area_location(ps, area),
+ .count = ps->store->chunk_size,
};
struct dm_io_request io_req = {
.bi_rw = WRITE,
@@ -278,15 +280,15 @@ static int read_header(struct pstore *ps, int *new_snapshot)
/*
* Use default chunk size (or hardsect_size, if larger) if none supplied
*/
- if (!ps->snap->chunk_size) {
- ps->snap->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
- bdev_hardsect_size(ps->snap->cow->bdev) >> 9);
- ps->snap->chunk_mask = ps->snap->chunk_size - 1;
- ps->snap->chunk_shift = ffs(ps->snap->chunk_size) - 1;
+ if (!ps->store->chunk_size) {
+ ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS,
+ bdev_hardsect_size(ps->store->cow->bdev) >> 9);
+ ps->store->chunk_mask = ps->store->chunk_size - 1;
+ ps->store->chunk_shift = ffs(ps->store->chunk_size) - 1;
chunk_size_supplied = 0;
}
- ps->io_client = dm_io_client_create(sectors_to_pages(ps->snap->
+ ps->io_client = dm_io_client_create(sectors_to_pages(ps->store->
chunk_size));
if (IS_ERR(ps->io_client))
return PTR_ERR(ps->io_client);
@@ -317,22 +319,22 @@ static int read_header(struct pstore *ps, int *new_snapshot)
ps->version = le32_to_cpu(dh->version);
chunk_size = le32_to_cpu(dh->chunk_size);
- if (!chunk_size_supplied || ps->snap->chunk_size == chunk_size)
+ if (!chunk_size_supplied || ps->store->chunk_size == chunk_size)
return 0;
DMWARN("chunk size %llu in device metadata overrides "
"table chunk size of %llu.",
(unsigned long long)chunk_size,
- (unsigned long long)ps->snap->chunk_size);
+ (unsigned long long)ps->store->chunk_size);
/* We had a bogus chunk_size. Fix stuff up. */
free_area(ps);
- ps->snap->chunk_size = chunk_size;
- ps->snap->chunk_mask = chunk_size - 1;
- ps->snap->chunk_shift = ffs(chunk_size) - 1;
+ ps->store->chunk_size = chunk_size;
+ ps->store->chunk_mask = chunk_size - 1;
+ ps->store->chunk_shift = ffs(chunk_size) - 1;
- r = dm_io_client_resize(sectors_to_pages(ps->snap->chunk_size),
+ r = dm_io_client_resize(sectors_to_pages(ps->store->chunk_size),
ps->io_client);
if (r)
return r;
@@ -349,13 +351,13 @@ static int write_header(struct pstore *ps)
{
struct disk_header *dh;
- memset(ps->area, 0, ps->snap->chunk_size << SECTOR_SHIFT);
+ memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT);
dh = (struct disk_header *) ps->area;
dh->magic = cpu_to_le32(SNAP_MAGIC);
dh->valid = cpu_to_le32(ps->valid);
dh->version = cpu_to_le32(ps->version);
- dh->chunk_size = cpu_to_le32(ps->snap->chunk_size);
+ dh->chunk_size = cpu_to_le32(ps->store->chunk_size);
return chunk_io(ps, 0, WRITE, 1);
}
@@ -474,18 +476,25 @@ static struct pstore *get_info(struct dm_exception_store *store)
static void persistent_fraction_full(struct dm_exception_store *store,
sector_t *numerator, sector_t *denominator)
{
- *numerator = get_info(store)->next_free * store->snap->chunk_size;
- *denominator = get_dev_size(store->snap->cow->bdev);
+ *numerator = get_info(store)->next_free * store->chunk_size;
+ *denominator = get_dev_size(store->cow->bdev);
}
-static void persistent_destroy(struct dm_exception_store *store)
+static void persistent_dtr(struct dm_exception_store *store)
{
struct pstore *ps = get_info(store);
destroy_workqueue(ps->metadata_wq);
- dm_io_client_destroy(ps->io_client);
- vfree(ps->callbacks);
+
+ /* Created in read_header */
+ if (ps->io_client)
+ dm_io_client_destroy(ps->io_client);
free_area(ps);
+
+ /* Allocated in persistent_read_metadata */
+ if (ps->callbacks)
+ vfree(ps->callbacks);
+
kfree(ps);
}
@@ -507,7 +516,7 @@ static int persistent_read_metadata(struct dm_exception_store *store,
/*
* Now we know correct chunk_size, complete the initialisation.
*/
- ps->exceptions_per_area = (ps->snap->chunk_size << SECTOR_SHIFT) /
+ ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) /
sizeof(struct disk_exception);
ps->callbacks = dm_vcalloc(ps->exceptions_per_area,
sizeof(*ps->callbacks));
@@ -564,10 +573,10 @@ static int persistent_prepare_exception(struct dm_exception_store *store,
struct pstore *ps = get_info(store);
uint32_t stride;
chunk_t next_free;
- sector_t size = get_dev_size(store->snap->cow->bdev);
+ sector_t size = get_dev_size(store->cow->bdev);
/* Is there enough room ? */
- if (size < ((ps->next_free + 1) * store->snap->chunk_size))
+ if (size < ((ps->next_free + 1) * store->chunk_size))
return -ENOSPC;
e->new_chunk = ps->next_free;
@@ -656,16 +665,17 @@ static void persistent_drop_snapshot(struct dm_exception_store *store)
DMWARN("write header failed");
}
-int dm_create_persistent(struct dm_exception_store *store)
+static int persistent_ctr(struct dm_exception_store *store,
+ unsigned argc, char **argv)
{
struct pstore *ps;
/* allocate the pstore */
- ps = kmalloc(sizeof(*ps), GFP_KERNEL);
+ ps = kzalloc(sizeof(*ps), GFP_KERNEL);
if (!ps)
return -ENOMEM;
- ps->snap = store->snap;
+ ps->store = store;
ps->valid = 1;
ps->version = SNAPSHOT_DISK_VERSION;
ps->area = NULL;
@@ -683,22 +693,77 @@ int dm_create_persistent(struct dm_exception_store *store)
return -ENOMEM;
}
- store->destroy = persistent_destroy;
- store->read_metadata = persistent_read_metadata;
- store->prepare_exception = persistent_prepare_exception;
- store->commit_exception = persistent_commit_exception;
- store->drop_snapshot = persistent_drop_snapshot;
- store->fraction_full = persistent_fraction_full;
store->context = ps;
return 0;
}
+static unsigned persistent_status(struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen)
+{
+ unsigned sz = 0;
+
+ switch (status) {
+ case STATUSTYPE_INFO:
+ break;
+ case STATUSTYPE_TABLE:
+ DMEMIT(" %s P %llu", store->cow->name,
+ (unsigned long long)store->chunk_size);
+ }
+
+ return sz;
+}
+
+static struct dm_exception_store_type _persistent_type = {
+ .name = "persistent",
+ .module = THIS_MODULE,
+ .ctr = persistent_ctr,
+ .dtr = persistent_dtr,
+ .read_metadata = persistent_read_metadata,
+ .prepare_exception = persistent_prepare_exception,
+ .commit_exception = persistent_commit_exception,
+ .drop_snapshot = persistent_drop_snapshot,
+ .fraction_full = persistent_fraction_full,
+ .status = persistent_status,
+};
+
+static struct dm_exception_store_type _persistent_compat_type = {
+ .name = "P",
+ .module = THIS_MODULE,
+ .ctr = persistent_ctr,
+ .dtr = persistent_dtr,
+ .read_metadata = persistent_read_metadata,
+ .prepare_exception = persistent_prepare_exception,
+ .commit_exception = persistent_commit_exception,
+ .drop_snapshot = persistent_drop_snapshot,
+ .fraction_full = persistent_fraction_full,
+ .status = persistent_status,
+};
+
int dm_persistent_snapshot_init(void)
{
- return 0;
+ int r;
+
+ r = dm_exception_store_type_register(&_persistent_type);
+ if (r) {
+ DMERR("Unable to register persistent exception store type");
+ return r;
+ }
+
+ r = dm_exception_store_type_register(&_persistent_compat_type);
+ if (r) {
+ DMERR("Unable to register old-style persistent exception "
+ "store type");
+ dm_exception_store_type_unregister(&_persistent_type);
+ return r;
+ }
+
+ return r;
}
void dm_persistent_snapshot_exit(void)
{
+ dm_exception_store_type_unregister(&_persistent_type);
+ dm_exception_store_type_unregister(&_persistent_compat_type);
}
diff --git a/drivers/md/dm-snap-transient.c b/drivers/md/dm-snap-transient.c
index 7f6e2e6dcb0..cde5aa558e6 100644
--- a/drivers/md/dm-snap-transient.c
+++ b/drivers/md/dm-snap-transient.c
@@ -6,7 +6,6 @@
*/
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include <linux/mm.h>
#include <linux/pagemap.h>
@@ -23,7 +22,7 @@ struct transient_c {
sector_t next_free;
};
-static void transient_destroy(struct dm_exception_store *store)
+static void transient_dtr(struct dm_exception_store *store)
{
kfree(store->context);
}
@@ -39,14 +38,14 @@ static int transient_read_metadata(struct dm_exception_store *store,
static int transient_prepare_exception(struct dm_exception_store *store,
struct dm_snap_exception *e)
{
- struct transient_c *tc = (struct transient_c *) store->context;
- sector_t size = get_dev_size(store->snap->cow->bdev);
+ struct transient_c *tc = store->context;
+ sector_t size = get_dev_size(store->cow->bdev);
- if (size < (tc->next_free + store->snap->chunk_size))
+ if (size < (tc->next_free + store->chunk_size))
return -1;
- e->new_chunk = sector_to_chunk(store->snap, tc->next_free);
- tc->next_free += store->snap->chunk_size;
+ e->new_chunk = sector_to_chunk(store, tc->next_free);
+ tc->next_free += store->chunk_size;
return 0;
}
@@ -64,20 +63,14 @@ static void transient_fraction_full(struct dm_exception_store *store,
sector_t *numerator, sector_t *denominator)
{
*numerator = ((struct transient_c *) store->context)->next_free;
- *denominator = get_dev_size(store->snap->cow->bdev);
+ *denominator = get_dev_size(store->cow->bdev);
}
-int dm_create_transient(struct dm_exception_store *store)
+static int transient_ctr(struct dm_exception_store *store,
+ unsigned argc, char **argv)
{
struct transient_c *tc;
- store->destroy = transient_destroy;
- store->read_metadata = transient_read_metadata;
- store->prepare_exception = transient_prepare_exception;
- store->commit_exception = transient_commit_exception;
- store->drop_snapshot = NULL;
- store->fraction_full = transient_fraction_full;
-
tc = kmalloc(sizeof(struct transient_c), GFP_KERNEL);
if (!tc)
return -ENOMEM;
@@ -88,11 +81,70 @@ int dm_create_transient(struct dm_exception_store *store)
return 0;
}
+static unsigned transient_status(struct dm_exception_store *store,
+ status_type_t status, char *result,
+ unsigned maxlen)
+{
+ unsigned sz = 0;
+
+ switch (status) {
+ case STATUSTYPE_INFO:
+ break;
+ case STATUSTYPE_TABLE:
+ DMEMIT(" %s N %llu", store->cow->name,
+ (unsigned long long)store->chunk_size);
+ }
+
+ return sz;
+}
+
+static struct dm_exception_store_type _transient_type = {
+ .name = "transient",
+ .module = THIS_MODULE,
+ .ctr = transient_ctr,
+ .dtr = transient_dtr,
+ .read_metadata = transient_read_metadata,
+ .prepare_exception = transient_prepare_exception,
+ .commit_exception = transient_commit_exception,
+ .fraction_full = transient_fraction_full,
+ .status = transient_status,
+};
+
+static struct dm_exception_store_type _transient_compat_type = {
+ .name = "N",
+ .module = THIS_MODULE,
+ .ctr = transient_ctr,
+ .dtr = transient_dtr,
+ .read_metadata = transient_read_metadata,
+ .prepare_exception = transient_prepare_exception,
+ .commit_exception = transient_commit_exception,
+ .fraction_full = transient_fraction_full,
+ .status = transient_status,
+};
+
int dm_transient_snapshot_init(void)
{
- return 0;
+ int r;
+
+ r = dm_exception_store_type_register(&_transient_type);
+ if (r) {
+ DMWARN("Unable to register transient exception store type");
+ return r;
+ }
+
+ r = dm_exception_store_type_register(&_transient_compat_type);
+ if (r) {
+ DMWARN("Unable to register old-style transient "
+ "exception store type");
+ dm_exception_store_type_unregister(&_transient_type);
+ return r;
+ }
+
+ return r;
}
void dm_transient_snapshot_exit(void)
{
+ dm_exception_store_type_unregister(&_transient_type);
+ dm_exception_store_type_unregister(&_transient_compat_type);
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 65ff82ff124..981a0413068 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -7,7 +7,6 @@
*/
#include <linux/blkdev.h>
-#include <linux/ctype.h>
#include <linux/device-mapper.h>
#include <linux/delay.h>
#include <linux/fs.h>
@@ -20,9 +19,9 @@
#include <linux/vmalloc.h>
#include <linux/log2.h>
#include <linux/dm-kcopyd.h>
+#include <linux/workqueue.h>
#include "dm-exception-store.h"
-#include "dm-snap.h"
#include "dm-bio-list.h"
#define DM_MSG_PREFIX "snapshots"
@@ -47,9 +46,76 @@
*/
#define MIN_IOS 256
+#define DM_TRACKED_CHUNK_HASH_SIZE 16
+#define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \
+ (DM_TRACKED_CHUNK_HASH_SIZE - 1))
+
+struct exception_table {
+ uint32_t hash_mask;
+ unsigned hash_shift;
+ struct list_head *table;
+};
+
+struct dm_snapshot {
+ struct rw_semaphore lock;
+
+ struct dm_dev *origin;
+
+ /* List of snapshots per Origin */
+ struct list_head list;
+
+ /* You can't use a snapshot if this is 0 (e.g. if full) */
+ int valid;
+
+ /* Origin writes don't trigger exceptions until this is set */
+ int active;
+
+ mempool_t *pending_pool;
+
+ atomic_t pending_exceptions_count;
+
+ struct exception_table pending;
+ struct exception_table complete;
+
+ /*
+ * pe_lock protects all pending_exception operations and access
+ * as well as the snapshot_bios list.
+ */
+ spinlock_t pe_lock;
+
+ /* The on disk metadata handler */
+ struct dm_exception_store *store;
+
+ struct dm_kcopyd_client *kcopyd_client;
+
+ /* Queue of snapshot writes for ksnapd to flush */
+ struct bio_list queued_bios;
+ struct work_struct queued_bios_work;
+
+ /* Chunks with outstanding reads */
+ mempool_t *tracked_chunk_pool;
+ spinlock_t tracked_chunk_lock;
+ struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
+};
+
static struct workqueue_struct *ksnapd;
static void flush_queued_bios(struct work_struct *work);
+static sector_t chunk_to_sector(struct dm_exception_store *store,
+ chunk_t chunk)
+{
+ return chunk << store->chunk_shift;
+}
+
+static int bdev_equal(struct block_device *lhs, struct block_device *rhs)
+{
+ /*
+ * There is only ever one instance of a particular block
+ * device so we can compare pointers safely.
+ */
+ return lhs == rhs;
+}
+
struct dm_snap_pending_exception {
struct dm_snap_exception e;
@@ -476,11 +542,11 @@ static int init_hash_tables(struct dm_snapshot *s)
* Calculate based on the size of the original volume or
* the COW volume...
*/
- cow_dev_size = get_dev_size(s->cow->bdev);
+ cow_dev_size = get_dev_size(s->store->cow->bdev);
origin_dev_size = get_dev_size(s->origin->bdev);
max_buckets = calc_max_buckets();
- hash_size = min(origin_dev_size, cow_dev_size) >> s->chunk_shift;
+ hash_size = min(origin_dev_size, cow_dev_size) >> s->store->chunk_shift;
hash_size = min(hash_size, max_buckets);
hash_size = rounddown_pow_of_two(hash_size);
@@ -505,58 +571,6 @@ static int init_hash_tables(struct dm_snapshot *s)
}
/*
- * Round a number up to the nearest 'size' boundary. size must
- * be a power of 2.
- */
-static ulong round_up(ulong n, ulong size)
-{
- size--;
- return (n + size) & ~size;
-}
-
-static int set_chunk_size(struct dm_snapshot *s, const char *chunk_size_arg,
- char **error)
-{
- unsigned long chunk_size;
- char *value;
-
- chunk_size = simple_strtoul(chunk_size_arg, &value, 10);
- if (*chunk_size_arg == '\0' || *value != '\0') {
- *error = "Invalid chunk size";
- return -EINVAL;
- }
-
- if (!chunk_size) {
- s->chunk_size = s->chunk_mask = s->chunk_shift = 0;
- return 0;
- }
-
- /*
- * Chunk size must be multiple of page size. Silently
- * round up if it's not.
- */
- chunk_size = round_up(chunk_size, PAGE_SIZE >> 9);
-
- /* Check chunk_size is a power of 2 */
- if (!is_power_of_2(chunk_size)) {
- *error = "Chunk size is not a power of 2";
- return -EINVAL;
- }
-
- /* Validate the chunk size against the device block size */
- if (chunk_size % (bdev_hardsect_size(s->cow->bdev) >> 9)) {
- *error = "Chunk size is not a multiple of device blocksize";
- return -EINVAL;
- }
-
- s->chunk_size = chunk_size;
- s->chunk_mask = chunk_size - 1;
- s->chunk_shift = ffs(chunk_size) - 1;
-
- return 0;
-}
-
-/*
* Construct a snapshot mapping: <origin_dev> <COW-dev> <p/n> <chunk-size>
*/
static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
@@ -564,91 +578,68 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
struct dm_snapshot *s;
int i;
int r = -EINVAL;
- char persistent;
char *origin_path;
- char *cow_path;
+ struct dm_exception_store *store;
+ unsigned args_used;
if (argc != 4) {
ti->error = "requires exactly 4 arguments";
r = -EINVAL;
- goto bad1;
+ goto bad_args;
}
origin_path = argv[0];
- cow_path = argv[1];
- persistent = toupper(*argv[2]);
+ argv++;
+ argc--;
- if (persistent != 'P' && persistent != 'N') {
- ti->error = "Persistent flag is not P or N";
+ r = dm_exception_store_create(ti, argc, argv, &args_used, &store);
+ if (r) {
+ ti->error = "Couldn't create exception store";
r = -EINVAL;
- goto bad1;
+ goto bad_args;
}
+ argv += args_used;
+ argc -= args_used;
+
s = kmalloc(sizeof(*s), GFP_KERNEL);
- if (s == NULL) {
+ if (!s) {
ti->error = "Cannot allocate snapshot context private "
"structure";
r = -ENOMEM;
- goto bad1;
+ goto bad_snap;
}
r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin);
if (r) {
ti->error = "Cannot get origin device";
- goto bad2;
- }
-
- r = dm_get_device(ti, cow_path, 0, 0,
- FMODE_READ | FMODE_WRITE, &s->cow);
- if (r) {
- dm_put_device(ti, s->origin);
- ti->error = "Cannot get COW device";
- goto bad2;
+ goto bad_origin;
}
- r = set_chunk_size(s, argv[3], &ti->error);
- if (r)
- goto bad3;
-
- s->type = persistent;
-
+ s->store = store;
s->valid = 1;
s->active = 0;
atomic_set(&s->pending_exceptions_count, 0);
init_rwsem(&s->lock);
spin_lock_init(&s->pe_lock);
- s->ti = ti;
/* Allocate hash table for COW data */
if (init_hash_tables(s)) {
ti->error = "Unable to allocate hash table space";
r = -ENOMEM;
- goto bad3;
- }
-
- s->store.snap = s;
-
- if (persistent == 'P')
- r = dm_create_persistent(&s->store);
- else
- r = dm_create_transient(&s->store);
-
- if (r) {
- ti->error = "Couldn't create exception store";
- r = -EINVAL;
- goto bad4;
+ goto bad_hash_tables;
}
r = dm_kcopyd_client_create(SNAPSHOT_PAGES, &s->kcopyd_client);
if (r) {
ti->error = "Could not create kcopyd client";
- goto bad5;
+ goto bad_kcopyd;
}
s->pending_pool = mempool_create_slab_pool(MIN_IOS, pending_cache);
if (!s->pending_pool) {
ti->error = "Could not allocate mempool for pending exceptions";
- goto bad6;
+ goto bad_pending_pool;
}
s->tracked_chunk_pool = mempool_create_slab_pool(MIN_IOS,
@@ -665,7 +656,8 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
spin_lock_init(&s->tracked_chunk_lock);
/* Metadata must only be loaded into one table at once */
- r = s->store.read_metadata(&s->store, dm_add_exception, (void *)s);
+ r = s->store->type->read_metadata(s->store, dm_add_exception,
+ (void *)s);
if (r < 0) {
ti->error = "Failed to read snapshot metadata";
goto bad_load_and_register;
@@ -686,34 +678,33 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
}
ti->private = s;
- ti->split_io = s->chunk_size;
+ ti->split_io = s->store->chunk_size;
return 0;
- bad_load_and_register:
+bad_load_and_register:
mempool_destroy(s->tracked_chunk_pool);
- bad_tracked_chunk_pool:
+bad_tracked_chunk_pool:
mempool_destroy(s->pending_pool);
- bad6:
+bad_pending_pool:
dm_kcopyd_client_destroy(s->kcopyd_client);
- bad5:
- s->store.destroy(&s->store);
-
- bad4:
+bad_kcopyd:
exit_exception_table(&s->pending, pending_cache);
exit_exception_table(&s->complete, exception_cache);
- bad3:
- dm_put_device(ti, s->cow);
+bad_hash_tables:
dm_put_device(ti, s->origin);
- bad2:
+bad_origin:
kfree(s);
- bad1:
+bad_snap:
+ dm_exception_store_destroy(store);
+
+bad_args:
return r;
}
@@ -724,8 +715,6 @@ static void __free_exceptions(struct dm_snapshot *s)
exit_exception_table(&s->pending, pending_cache);
exit_exception_table(&s->complete, exception_cache);
-
- s->store.destroy(&s->store);
}
static void snapshot_dtr(struct dm_target *ti)
@@ -761,7 +750,8 @@ static void snapshot_dtr(struct dm_target *ti)
mempool_destroy(s->pending_pool);
dm_put_device(ti, s->origin);
- dm_put_device(ti, s->cow);
+
+ dm_exception_store_destroy(s->store);
kfree(s);
}
@@ -820,12 +810,12 @@ static void __invalidate_snapshot(struct dm_snapshot *s, int err)
else if (err == -ENOMEM)
DMERR("Invalidating snapshot: Unable to allocate exception.");
- if (s->store.drop_snapshot)
- s->store.drop_snapshot(&s->store);
+ if (s->store->type->drop_snapshot)
+ s->store->type->drop_snapshot(s->store);
s->valid = 0;
- dm_table_event(s->ti->table);
+ dm_table_event(s->store->ti->table);
}
static void get_pending_exception(struct dm_snap_pending_exception *pe)
@@ -943,8 +933,8 @@ static void copy_callback(int read_err, unsigned long write_err, void *context)
else
/* Update the metadata if we are persistent */
- s->store.commit_exception(&s->store, &pe->e, commit_callback,
- pe);
+ s->store->type->commit_exception(s->store, &pe->e,
+ commit_callback, pe);
}
/*
@@ -960,11 +950,11 @@ static void start_copy(struct dm_snap_pending_exception *pe)
dev_size = get_dev_size(bdev);
src.bdev = bdev;
- src.sector = chunk_to_sector(s, pe->e.old_chunk);
- src.count = min(s->chunk_size, dev_size - src.sector);
+ src.sector = chunk_to_sector(s->store, pe->e.old_chunk);
+ src.count = min(s->store->chunk_size, dev_size - src.sector);
- dest.bdev = s->cow->bdev;
- dest.sector = chunk_to_sector(s, pe->e.new_chunk);
+ dest.bdev = s->store->cow->bdev;
+ dest.sector = chunk_to_sector(s->store, pe->e.new_chunk);
dest.count = src.count;
/* Hand over to kcopyd */
@@ -972,6 +962,17 @@ static void start_copy(struct dm_snap_pending_exception *pe)
&src, 1, &dest, 0, copy_callback, pe);
}
+static struct dm_snap_pending_exception *
+__lookup_pending_exception(struct dm_snapshot *s, chunk_t chunk)
+{
+ struct dm_snap_exception *e = lookup_exception(&s->pending, chunk);
+
+ if (!e)
+ return NULL;
+
+ return container_of(e, struct dm_snap_pending_exception, e);
+}
+
/*
* Looks to see if this snapshot already has a pending exception
* for this chunk, otherwise it allocates a new one and inserts
@@ -981,40 +982,15 @@ static void start_copy(struct dm_snap_pending_exception *pe)
* this.
*/
static struct dm_snap_pending_exception *
-__find_pending_exception(struct dm_snapshot *s, struct bio *bio)
+__find_pending_exception(struct dm_snapshot *s,
+ struct dm_snap_pending_exception *pe, chunk_t chunk)
{
- struct dm_snap_exception *e;
- struct dm_snap_pending_exception *pe;
- chunk_t chunk = sector_to_chunk(s, bio->bi_sector);
+ struct dm_snap_pending_exception *pe2;
- /*
- * Is there a pending exception for this already ?
- */
- e = lookup_exception(&s->pending, chunk);
- if (e) {
- /* cast the exception to a pending exception */
- pe = container_of(e, struct dm_snap_pending_exception, e);
- goto out;
- }
-
- /*
- * Create a new pending exception, we don't want
- * to hold the lock while we do this.
- */
- up_write(&s->lock);
- pe = alloc_pending_exception(s);
- down_write(&s->lock);
-
- if (!s->valid) {
- free_pending_exception(pe);
- return NULL;
- }
-
- e = lookup_exception(&s->pending, chunk);
- if (e) {
+ pe2 = __lookup_pending_exception(s, chunk);
+ if (pe2) {
free_pending_exception(pe);
- pe = container_of(e, struct dm_snap_pending_exception, e);
- goto out;
+ return pe2;
}
pe->e.old_chunk = chunk;
@@ -1024,7 +1000,7 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
atomic_set(&pe->ref_count, 0);
pe->started = 0;
- if (s->store.prepare_exception(&s->store, &pe->e)) {
+ if (s->store->type->prepare_exception(s->store, &pe->e)) {
free_pending_exception(pe);
return NULL;
}
@@ -1032,17 +1008,18 @@ __find_pending_exception(struct dm_snapshot *s, struct bio *bio)
get_pending_exception(pe);
insert_exception(&s->pending, &pe->e);
- out:
return pe;
}
static void remap_exception(struct dm_snapshot *s, struct dm_snap_exception *e,
struct bio *bio, chunk_t chunk)
{
- bio->bi_bdev = s->cow->bdev;
- bio->bi_sector = chunk_to_sector(s, dm_chunk_number(e->new_chunk) +
- (chunk - e->old_chunk)) +
- (bio->bi_sector & s->chunk_mask);
+ bio->bi_bdev = s->store->cow->bdev;
+ bio->bi_sector = chunk_to_sector(s->store,
+ dm_chunk_number(e->new_chunk) +
+ (chunk - e->old_chunk)) +
+ (bio->bi_sector &
+ s->store->chunk_mask);
}
static int snapshot_map(struct dm_target *ti, struct bio *bio,
@@ -1054,7 +1031,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
chunk_t chunk;
struct dm_snap_pending_exception *pe = NULL;
- chunk = sector_to_chunk(s, bio->bi_sector);
+ chunk = sector_to_chunk(s->store, bio->bi_sector);
/* Full snapshots are not usable */
/* To get here the table must be live so s->active is always set. */
@@ -1083,11 +1060,31 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
* writeable.
*/
if (bio_rw(bio) == WRITE) {
- pe = __find_pending_exception(s, bio);
+ pe = __lookup_pending_exception(s, chunk);
if (!pe) {
- __invalidate_snapshot(s, -ENOMEM);
- r = -EIO;
- goto out_unlock;
+ up_write(&s->lock);
+ pe = alloc_pending_exception(s);
+ down_write(&s->lock);
+
+ if (!s->valid) {
+ free_pending_exception(pe);
+ r = -EIO;
+ goto out_unlock;
+ }
+
+ e = lookup_exception(&s->complete, chunk);
+ if (e) {
+ free_pending_exception(pe);
+ remap_exception(s, e, bio, chunk);
+ goto out_unlock;
+ }
+
+ pe = __find_pending_exception(s, pe, chunk);
+ if (!pe) {
+ __invalidate_snapshot(s, -ENOMEM);
+ r = -EIO;
+ goto out_unlock;
+ }
}
remap_exception(s, &pe->e, bio, chunk);
@@ -1137,24 +1134,25 @@ static void snapshot_resume(struct dm_target *ti)
static int snapshot_status(struct dm_target *ti, status_type_t type,
char *result, unsigned int maxlen)
{
+ unsigned sz = 0;
struct dm_snapshot *snap = ti->private;
switch (type) {
case STATUSTYPE_INFO:
if (!snap->valid)
- snprintf(result, maxlen, "Invalid");
+ DMEMIT("Invalid");
else {
- if (snap->store.fraction_full) {
+ if (snap->store->type->fraction_full) {
sector_t numerator, denominator;
- snap->store.fraction_full(&snap->store,
- &numerator,
- &denominator);
- snprintf(result, maxlen, "%llu/%llu",
- (unsigned long long)numerator,
- (unsigned long long)denominator);
+ snap->store->type->fraction_full(snap->store,
+ &numerator,
+ &denominator);
+ DMEMIT("%llu/%llu",
+ (unsigned long long)numerator,
+ (unsigned long long)denominator);
}
else
- snprintf(result, maxlen, "Unknown");
+ DMEMIT("Unknown");
}
break;
@@ -1164,10 +1162,9 @@ static int snapshot_status(struct dm_target *ti, status_type_t type,
* to make private copies if the output is to
* make sense.
*/
- snprintf(result, maxlen, "%s %s %c %llu",
- snap->origin->name, snap->cow->name,
- snap->type,
- (unsigned long long)snap->chunk_size);
+ DMEMIT("%s", snap->origin->name);
+ snap->store->type->status(snap->store, type, result + sz,
+ maxlen - sz);
break;
}
@@ -1196,14 +1193,14 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
goto next_snapshot;
/* Nothing to do if writing beyond end of snapshot */
- if (bio->bi_sector >= dm_table_get_size(snap->ti->table))
+ if (bio->bi_sector >= dm_table_get_size(snap->store->ti->table))
goto next_snapshot;
/*
* Remember, different snapshots can have
* different chunk sizes.
*/
- chunk = sector_to_chunk(snap, bio->bi_sector);
+ chunk = sector_to_chunk(snap->store, bio->bi_sector);
/*
* Check exception table to see if block
@@ -1217,10 +1214,28 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
if (e)
goto next_snapshot;
- pe = __find_pending_exception(snap, bio);
+ pe = __lookup_pending_exception(snap, chunk);
if (!pe) {
- __invalidate_snapshot(snap, -ENOMEM);
- goto next_snapshot;
+ up_write(&snap->lock);
+ pe = alloc_pending_exception(snap);
+ down_write(&snap->lock);
+
+ if (!snap->valid) {
+ free_pending_exception(pe);
+ goto next_snapshot;
+ }
+
+ e = lookup_exception(&snap->complete, chunk);
+ if (e) {
+ free_pending_exception(pe);
+ goto next_snapshot;
+ }
+
+ pe = __find_pending_exception(snap, pe, chunk);
+ if (!pe) {
+ __invalidate_snapshot(snap, -ENOMEM);
+ goto next_snapshot;
+ }
}
if (!primary_pe) {
@@ -1360,7 +1375,8 @@ static void origin_resume(struct dm_target *ti)
o = __lookup_origin(dev->bdev);
if (o)
list_for_each_entry (snap, &o->snapshots, list)
- chunk_size = min_not_zero(chunk_size, snap->chunk_size);
+ chunk_size = min_not_zero(chunk_size,
+ snap->store->chunk_size);
up_read(&_origins_lock);
ti->split_io = chunk_size;
diff --git a/drivers/md/dm-snap.h b/drivers/md/dm-snap.h
deleted file mode 100644
index d9e62b43cf8..00000000000
--- a/drivers/md/dm-snap.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2001-2002 Sistina Software (UK) Limited.
- *
- * This file is released under the GPL.
- */
-
-#ifndef DM_SNAPSHOT_H
-#define DM_SNAPSHOT_H
-
-#include <linux/device-mapper.h>
-#include "dm-exception-store.h"
-#include "dm-bio-list.h"
-#include <linux/blkdev.h>
-#include <linux/workqueue.h>
-
-struct exception_table {
- uint32_t hash_mask;
- unsigned hash_shift;
- struct list_head *table;
-};
-
-#define DM_TRACKED_CHUNK_HASH_SIZE 16
-#define DM_TRACKED_CHUNK_HASH(x) ((unsigned long)(x) & \
- (DM_TRACKED_CHUNK_HASH_SIZE - 1))
-
-struct dm_snapshot {
- struct rw_semaphore lock;
- struct dm_target *ti;
-
- struct dm_dev *origin;
- struct dm_dev *cow;
-
- /* List of snapshots per Origin */
- struct list_head list;
-
- /* Size of data blocks saved - must be a power of 2 */
- chunk_t chunk_size;
- chunk_t chunk_mask;
- chunk_t chunk_shift;
-
- /* You can't use a snapshot if this is 0 (e.g. if full) */
- int valid;
-
- /* Origin writes don't trigger exceptions until this is set */
- int active;
-
- /* Used for display of table */
- char type;
-
- mempool_t *pending_pool;
-
- atomic_t pending_exceptions_count;
-
- struct exception_table pending;
- struct exception_table complete;
-
- /*
- * pe_lock protects all pending_exception operations and access
- * as well as the snapshot_bios list.
- */
- spinlock_t pe_lock;
-
- /* The on disk metadata handler */
- struct dm_exception_store store;
-
- struct dm_kcopyd_client *kcopyd_client;
-
- /* Queue of snapshot writes for ksnapd to flush */
- struct bio_list queued_bios;
- struct work_struct queued_bios_work;
-
- /* Chunks with outstanding reads */
- mempool_t *tracked_chunk_pool;
- spinlock_t tracked_chunk_lock;
- struct hlist_head tracked_chunk_hash[DM_TRACKED_CHUNK_HASH_SIZE];
-};
-
-/*
- * Return the number of sectors in the device.
- */
-static inline sector_t get_dev_size(struct block_device *bdev)
-{
- return bdev->bd_inode->i_size >> SECTOR_SHIFT;
-}
-
-static inline chunk_t sector_to_chunk(struct dm_snapshot *s, sector_t sector)
-{
- return (sector & ~s->chunk_mask) >> s->chunk_shift;
-}
-
-static inline sector_t chunk_to_sector(struct dm_snapshot *s, chunk_t chunk)
-{
- return chunk << s->chunk_shift;
-}
-
-static inline int bdev_equal(struct block_device *lhs, struct block_device *rhs)
-{
- /*
- * There is only ever one instance of a particular block
- * device so we can compare pointers safely.
- */
- return lhs == rhs;
-}
-
-#endif
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2fd66c30f7f..e8361b191b9 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -399,28 +399,30 @@ static int check_device_area(struct dm_dev_internal *dd, sector_t start,
}
/*
- * This upgrades the mode on an already open dm_dev. Being
+ * This upgrades the mode on an already open dm_dev, being
* careful to leave things as they were if we fail to reopen the
- * device.
+ * device and not to touch the existing bdev field in case
+ * it is accessed concurrently inside dm_table_any_congested().
*/
static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
struct mapped_device *md)
{
int r;
- struct dm_dev_internal dd_copy;
- dev_t dev = dd->dm_dev.bdev->bd_dev;
+ struct dm_dev_internal dd_new, dd_old;
- dd_copy = *dd;
+ dd_new = dd_old = *dd;
+
+ dd_new.dm_dev.mode |= new_mode;
+ dd_new.dm_dev.bdev = NULL;
+
+ r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
+ if (r)
+ return r;
dd->dm_dev.mode |= new_mode;
- dd->dm_dev.bdev = NULL;
- r = open_dev(dd, dev, md);
- if (!r)
- close_dev(&dd_copy, md);
- else
- *dd = dd_copy;
+ close_dev(&dd_old, md);
- return r;
+ return 0;
}
/*
diff --git a/drivers/md/dm-target.c b/drivers/md/dm-target.c
index 7decf10006e..04feccf2a99 100644
--- a/drivers/md/dm-target.c
+++ b/drivers/md/dm-target.c
@@ -14,45 +14,34 @@
#define DM_MSG_PREFIX "target"
-struct tt_internal {
- struct target_type tt;
-
- struct list_head list;
- long use;
-};
-
static LIST_HEAD(_targets);
static DECLARE_RWSEM(_lock);
#define DM_MOD_NAME_SIZE 32
-static inline struct tt_internal *__find_target_type(const char *name)
+static inline struct target_type *__find_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
- list_for_each_entry (ti, &_targets, list)
- if (!strcmp(name, ti->tt.name))
- return ti;
+ list_for_each_entry(tt, &_targets, list)
+ if (!strcmp(name, tt->name))
+ return tt;
return NULL;
}
-static struct tt_internal *get_target_type(const char *name)
+static struct target_type *get_target_type(const char *name)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- ti = __find_target_type(name);
- if (ti) {
- if ((ti->use == 0) && !try_module_get(ti->tt.module))
- ti = NULL;
- else
- ti->use++;
- }
+ tt = __find_target_type(name);
+ if (tt && !try_module_get(tt->module))
+ tt = NULL;
up_read(&_lock);
- return ti;
+ return tt;
}
static void load_module(const char *name)
@@ -62,92 +51,59 @@ static void load_module(const char *name)
struct target_type *dm_get_target_type(const char *name)
{
- struct tt_internal *ti = get_target_type(name);
+ struct target_type *tt = get_target_type(name);
- if (!ti) {
+ if (!tt) {
load_module(name);
- ti = get_target_type(name);
+ tt = get_target_type(name);
}
- return ti ? &ti->tt : NULL;
+ return tt;
}
-void dm_put_target_type(struct target_type *t)
+void dm_put_target_type(struct target_type *tt)
{
- struct tt_internal *ti = (struct tt_internal *) t;
-
down_read(&_lock);
- if (--ti->use == 0)
- module_put(ti->tt.module);
-
- BUG_ON(ti->use < 0);
+ module_put(tt->module);
up_read(&_lock);
-
- return;
-}
-
-static struct tt_internal *alloc_target(struct target_type *t)
-{
- struct tt_internal *ti = kzalloc(sizeof(*ti), GFP_KERNEL);
-
- if (ti)
- ti->tt = *t;
-
- return ti;
}
-
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param)
{
- struct tt_internal *ti;
+ struct target_type *tt;
down_read(&_lock);
- list_for_each_entry (ti, &_targets, list)
- iter_func(&ti->tt, param);
+ list_for_each_entry(tt, &_targets, list)
+ iter_func(tt, param);
up_read(&_lock);
return 0;
}
-int dm_register_target(struct target_type *t)
+int dm_register_target(struct target_type *tt)
{
int rv = 0;
- struct tt_internal *ti = alloc_target(t);
-
- if (!ti)
- return -ENOMEM;
down_write(&_lock);
- if (__find_target_type(t->name))
+ if (__find_target_type(tt->name))
rv = -EEXIST;
else
- list_add(&ti->list, &_targets);
+ list_add(&tt->list, &_targets);
up_write(&_lock);
- if (rv)
- kfree(ti);
return rv;
}
-void dm_unregister_target(struct target_type *t)
+void dm_unregister_target(struct target_type *tt)
{
- struct tt_internal *ti;
-
down_write(&_lock);
- if (!(ti = __find_target_type(t->name))) {
- DMCRIT("Unregistering unrecognised target: %s", t->name);
- BUG();
- }
-
- if (ti->use) {
- DMCRIT("Attempt to unregister target still in use: %s",
- t->name);
+ if (!__find_target_type(tt->name)) {
+ DMCRIT("Unregistering unrecognised target: %s", tt->name);
BUG();
}
- list_del(&ti->list);
- kfree(ti);
+ list_del(&tt->list);
up_write(&_lock);
}
@@ -156,17 +112,17 @@ void dm_unregister_target(struct target_type *t)
* io-err: always fails an io, useful for bringing
* up LVs that have holes in them.
*/
-static int io_err_ctr(struct dm_target *ti, unsigned int argc, char **args)
+static int io_err_ctr(struct dm_target *tt, unsigned int argc, char **args)
{
return 0;
}
-static void io_err_dtr(struct dm_target *ti)
+static void io_err_dtr(struct dm_target *tt)
{
/* empty */
}
-static int io_err_map(struct dm_target *ti, struct bio *bio,
+static int io_err_map(struct dm_target *tt, struct bio *bio,
union map_info *map_context)
{
return -EIO;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 8d40f27cce8..788ba96a625 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -99,19 +99,9 @@ union map_info *dm_get_mapinfo(struct bio *bio)
/*
* Work processed by per-device workqueue.
*/
-struct dm_wq_req {
- enum {
- DM_WQ_FLUSH_DEFERRED,
- } type;
- struct work_struct work;
- struct mapped_device *md;
- void *context;
-};
-
struct mapped_device {
struct rw_semaphore io_lock;
struct mutex suspend_lock;
- spinlock_t pushback_lock;
rwlock_t map_lock;
atomic_t holders;
atomic_t open_count;
@@ -129,8 +119,9 @@ struct mapped_device {
*/
atomic_t pending;
wait_queue_head_t wait;
+ struct work_struct work;
struct bio_list deferred;
- struct bio_list pushback;
+ spinlock_t deferred_lock;
/*
* Processing queue (flush/barriers)
@@ -453,7 +444,9 @@ static int queue_io(struct mapped_device *md, struct bio *bio)
return 1;
}
+ spin_lock_irq(&md->deferred_lock);
bio_list_add(&md->deferred, bio);
+ spin_unlock_irq(&md->deferred_lock);
up_write(&md->io_lock);
return 0; /* deferred successfully */
@@ -537,16 +530,14 @@ static void dec_pending(struct dm_io *io, int error)
if (io->error == DM_ENDIO_REQUEUE) {
/*
* Target requested pushing back the I/O.
- * This must be handled before the sleeper on
- * suspend queue merges the pushback list.
*/
- spin_lock_irqsave(&md->pushback_lock, flags);
+ spin_lock_irqsave(&md->deferred_lock, flags);
if (__noflush_suspending(md))
- bio_list_add(&md->pushback, io->bio);
+ bio_list_add(&md->deferred, io->bio);
else
/* noflush suspend was interrupted. */
io->error = -EIO;
- spin_unlock_irqrestore(&md->pushback_lock, flags);
+ spin_unlock_irqrestore(&md->deferred_lock, flags);
}
end_io_acct(io);
@@ -834,20 +825,22 @@ static int __clone_and_map(struct clone_info *ci)
}
/*
- * Split the bio into several clones.
+ * Split the bio into several clones and submit it to targets.
*/
-static int __split_bio(struct mapped_device *md, struct bio *bio)
+static void __split_and_process_bio(struct mapped_device *md, struct bio *bio)
{
struct clone_info ci;
int error = 0;
ci.map = dm_get_table(md);
- if (unlikely(!ci.map))
- return -EIO;
+ if (unlikely(!ci.map)) {
+ bio_io_error(bio);
+ return;
+ }
if (unlikely(bio_barrier(bio) && !dm_table_barrier_ok(ci.map))) {
dm_table_put(ci.map);
bio_endio(bio, -EOPNOTSUPP);
- return 0;
+ return;
}
ci.md = md;
ci.bio = bio;
@@ -867,8 +860,6 @@ static int __split_bio(struct mapped_device *md, struct bio *bio)
/* drop the extra reference count */
dec_pending(ci.io, error);
dm_table_put(ci.map);
-
- return 0;
}
/*-----------------------------------------------------------------
* CRUD END
@@ -959,8 +950,9 @@ static int dm_request(struct request_queue *q, struct bio *bio)
down_read(&md->io_lock);
}
- r = __split_bio(md, bio);
+ __split_and_process_bio(md, bio);
up_read(&md->io_lock);
+ return 0;
out_req:
if (r < 0)
@@ -1074,6 +1066,8 @@ out:
static struct block_device_operations dm_blk_dops;
+static void dm_wq_work(struct work_struct *work);
+
/*
* Allocate and initialise a blank device with a given minor.
*/
@@ -1101,7 +1095,7 @@ static struct mapped_device *alloc_dev(int minor)
init_rwsem(&md->io_lock);
mutex_init(&md->suspend_lock);
- spin_lock_init(&md->pushback_lock);
+ spin_lock_init(&md->deferred_lock);
rwlock_init(&md->map_lock);
atomic_set(&md->holders, 1);
atomic_set(&md->open_count, 0);
@@ -1118,6 +1112,7 @@ static struct mapped_device *alloc_dev(int minor)
md->queue->backing_dev_info.congested_fn = dm_any_congested;
md->queue->backing_dev_info.congested_data = md;
blk_queue_make_request(md->queue, dm_request);
+ blk_queue_ordered(md->queue, QUEUE_ORDERED_DRAIN, NULL);
blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
md->queue->unplug_fn = dm_unplug_all;
blk_queue_merge_bvec(md->queue, dm_merge_bvec);
@@ -1140,6 +1135,7 @@ static struct mapped_device *alloc_dev(int minor)
atomic_set(&md->pending, 0);
init_waitqueue_head(&md->wait);
+ INIT_WORK(&md->work, dm_wq_work);
init_waitqueue_head(&md->eventq);
md->disk->major = _major;
@@ -1379,18 +1375,24 @@ void dm_put(struct mapped_device *md)
}
EXPORT_SYMBOL_GPL(dm_put);
-static int dm_wait_for_completion(struct mapped_device *md)
+static int dm_wait_for_completion(struct mapped_device *md, int interruptible)
{
int r = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ dm_unplug_all(md->queue);
+
+ add_wait_queue(&md->wait, &wait);
while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
+ set_current_state(interruptible);
smp_mb();
if (!atomic_read(&md->pending))
break;
- if (signal_pending(current)) {
+ if (interruptible == TASK_INTERRUPTIBLE &&
+ signal_pending(current)) {
r = -EINTR;
break;
}
@@ -1399,67 +1401,40 @@ static int dm_wait_for_completion(struct mapped_device *md)
}
set_current_state(TASK_RUNNING);
+ remove_wait_queue(&md->wait, &wait);
+
return r;
}
/*
* Process the deferred bios
*/
-static void __flush_deferred_io(struct mapped_device *md)
+static void dm_wq_work(struct work_struct *work)
{
+ struct mapped_device *md = container_of(work, struct mapped_device,
+ work);
struct bio *c;
- while ((c = bio_list_pop(&md->deferred))) {
- if (__split_bio(md, c))
- bio_io_error(c);
- }
-
- clear_bit(DMF_BLOCK_IO, &md->flags);
-}
+ down_write(&md->io_lock);
-static void __merge_pushback_list(struct mapped_device *md)
-{
- unsigned long flags;
+next_bio:
+ spin_lock_irq(&md->deferred_lock);
+ c = bio_list_pop(&md->deferred);
+ spin_unlock_irq(&md->deferred_lock);
- spin_lock_irqsave(&md->pushback_lock, flags);
- clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
- bio_list_merge_head(&md->deferred, &md->pushback);
- bio_list_init(&md->pushback);
- spin_unlock_irqrestore(&md->pushback_lock, flags);
-}
+ if (c) {
+ __split_and_process_bio(md, c);
+ goto next_bio;
+ }
-static void dm_wq_work(struct work_struct *work)
-{
- struct dm_wq_req *req = container_of(work, struct dm_wq_req, work);
- struct mapped_device *md = req->md;
+ clear_bit(DMF_BLOCK_IO, &md->flags);
- down_write(&md->io_lock);
- switch (req->type) {
- case DM_WQ_FLUSH_DEFERRED:
- __flush_deferred_io(md);
- break;
- default:
- DMERR("dm_wq_work: unrecognised work type %d", req->type);
- BUG();
- }
up_write(&md->io_lock);
}
-static void dm_wq_queue(struct mapped_device *md, int type, void *context,
- struct dm_wq_req *req)
-{
- req->type = type;
- req->md = md;
- req->context = context;
- INIT_WORK(&req->work, dm_wq_work);
- queue_work(md->wq, &req->work);
-}
-
-static void dm_queue_flush(struct mapped_device *md, int type, void *context)
+static void dm_queue_flush(struct mapped_device *md)
{
- struct dm_wq_req req;
-
- dm_wq_queue(md, type, context, &req);
+ queue_work(md->wq, &md->work);
flush_workqueue(md->wq);
}
@@ -1534,7 +1509,6 @@ static void unlock_fs(struct mapped_device *md)
int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
{
struct dm_table *map = NULL;
- DECLARE_WAITQUEUE(wait, current);
int r = 0;
int do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG ? 1 : 0;
int noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG ? 1 : 0;
@@ -1584,28 +1558,22 @@ int dm_suspend(struct mapped_device *md, unsigned suspend_flags)
down_write(&md->io_lock);
set_bit(DMF_BLOCK_IO, &md->flags);
- add_wait_queue(&md->wait, &wait);
up_write(&md->io_lock);
- /* unplug */
- if (map)
- dm_table_unplug_all(map);
-
/*
* Wait for the already-mapped ios to complete.
*/
- r = dm_wait_for_completion(md);
+ r = dm_wait_for_completion(md, TASK_INTERRUPTIBLE);
down_write(&md->io_lock);
- remove_wait_queue(&md->wait, &wait);
if (noflush)
- __merge_pushback_list(md);
+ clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
up_write(&md->io_lock);
/* were we interrupted ? */
if (r < 0) {
- dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
goto out; /* pushback list is already flushed, so skip flush */
@@ -1645,7 +1613,7 @@ int dm_resume(struct mapped_device *md)
if (r)
goto out;
- dm_queue_flush(md, DM_WQ_FLUSH_DEFERRED, NULL);
+ dm_queue_flush(md);
unlock_fs(md);
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 20194e000c5..b48397c0abb 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -60,7 +60,7 @@ int dm_table_barrier_ok(struct dm_table *t);
int dm_target_init(void);
void dm_target_exit(void);
struct target_type *dm_get_target_type(const char *name);
-void dm_put_target_type(struct target_type *t);
+void dm_put_target_type(struct target_type *tt);
int dm_target_iterate(void (*iter_func)(struct target_type *tt,
void *param), void *param);
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c
index 86d9adf90e7..8695809b24b 100644
--- a/drivers/md/faulty.c
+++ b/drivers/md/faulty.c
@@ -62,7 +62,10 @@
#define ModeShift 5
#define MaxFault 50
-#include <linux/raid/md.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include <linux/seq_file.h>
static void faulty_fail(struct bio *bio, int error)
@@ -280,6 +283,17 @@ static int reconfig(mddev_t *mddev, int layout, int chunk_size)
return 0;
}
+static sector_t faulty_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ WARN_ONCE(raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ if (sectors == 0)
+ return mddev->dev_sectors;
+
+ return sectors;
+}
+
static int run(mddev_t *mddev)
{
mdk_rdev_t *rdev;
@@ -298,7 +312,7 @@ static int run(mddev_t *mddev)
list_for_each_entry(rdev, &mddev->disks, same_set)
conf->rdev = rdev;
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, faulty_size(mddev, 0, 0));
mddev->private = conf;
reconfig(mddev, mddev->layout, -1);
@@ -325,6 +339,7 @@ static struct mdk_personality faulty_personality =
.stop = stop,
.status = status,
.reconfig = reconfig,
+ .size = faulty_size,
};
static int __init raid_init(void)
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 09658b21847..7a36e38393a 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -16,7 +16,11 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/linear.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "linear.h"
/*
* find which device holds a particular offset
@@ -97,6 +101,16 @@ static int linear_congested(void *data, int bits)
return ret;
}
+static sector_t linear_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ linear_conf_t *conf = mddev_to_conf(mddev);
+
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ return conf->array_sectors;
+}
+
static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
{
linear_conf_t *conf;
@@ -135,8 +149,8 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks)
mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
- disk->num_sectors = rdev->size * 2;
- conf->array_sectors += rdev->size * 2;
+ disk->num_sectors = rdev->sectors;
+ conf->array_sectors += rdev->sectors;
cnt++;
}
@@ -249,7 +263,7 @@ static int linear_run (mddev_t *mddev)
if (!conf)
return 1;
mddev->private = conf;
- mddev->array_sectors = conf->array_sectors;
+ md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
mddev->queue->unplug_fn = linear_unplug;
@@ -283,7 +297,7 @@ static int linear_add(mddev_t *mddev, mdk_rdev_t *rdev)
newconf->prev = mddev_to_conf(mddev);
mddev->private = newconf;
mddev->raid_disks++;
- mddev->array_sectors = newconf->array_sectors;
+ md_set_array_sectors(mddev, linear_size(mddev, 0, 0));
set_capacity(mddev->gendisk, mddev->array_sectors);
return 0;
}
@@ -381,6 +395,7 @@ static struct mdk_personality linear_personality =
.stop = linear_stop,
.status = linear_status,
.hot_add_disk = linear_add,
+ .size = linear_size,
};
static int __init linear_init (void)
diff --git a/drivers/md/linear.h b/drivers/md/linear.h
new file mode 100644
index 00000000000..bf8179587f9
--- /dev/null
+++ b/drivers/md/linear.h
@@ -0,0 +1,29 @@
+#ifndef _LINEAR_H
+#define _LINEAR_H
+
+struct dev_info {
+ mdk_rdev_t *rdev;
+ sector_t num_sectors;
+ sector_t start_sector;
+};
+
+typedef struct dev_info dev_info_t;
+
+struct linear_private_data
+{
+ struct linear_private_data *prev; /* earlier version */
+ dev_info_t **hash_table;
+ sector_t spacing;
+ sector_t array_sectors;
+ int sector_shift; /* shift before dividing
+ * by spacing
+ */
+ dev_info_t disks[0];
+};
+
+
+typedef struct linear_private_data linear_conf_t;
+
+#define mddev_to_conf(mddev) ((linear_conf_t *) mddev->private)
+
+#endif
diff --git a/drivers/md/md.c b/drivers/md/md.c
index a307f87eb90..ed5727c089a 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -33,9 +33,9 @@
*/
#include <linux/kthread.h>
-#include <linux/raid/md.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
#include <linux/sysctl.h>
+#include <linux/seq_file.h>
#include <linux/buffer_head.h> /* for invalidate_bdev */
#include <linux/poll.h>
#include <linux/ctype.h>
@@ -45,11 +45,10 @@
#include <linux/reboot.h>
#include <linux/file.h>
#include <linux/delay.h>
-
-#define MAJOR_NR MD_MAJOR
-
-/* 63 partitions with the alternate major number (mdp) */
-#define MdpMinorShift 6
+#include <linux/raid/md_p.h>
+#include <linux/raid/md_u.h>
+#include "md.h"
+#include "bitmap.h"
#define DEBUG 0
#define dprintk(x...) ((void)(DEBUG && printk(x)))
@@ -202,12 +201,68 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
)
-static int md_fail_request(struct request_queue *q, struct bio *bio)
+/* Rather than calling directly into the personality make_request function,
+ * IO requests come here first so that we can check if the device is
+ * being suspended pending a reconfiguration.
+ * We hold a refcount over the call to ->make_request. By the time that
+ * call has finished, the bio has been linked into some internal structure
+ * and so is visible to ->quiesce(), so we don't need the refcount any more.
+ */
+static int md_make_request(struct request_queue *q, struct bio *bio)
{
- bio_io_error(bio);
- return 0;
+ mddev_t *mddev = q->queuedata;
+ int rv;
+ if (mddev == NULL || mddev->pers == NULL) {
+ bio_io_error(bio);
+ return 0;
+ }
+ rcu_read_lock();
+ if (mddev->suspended) {
+ DEFINE_WAIT(__wait);
+ for (;;) {
+ prepare_to_wait(&mddev->sb_wait, &__wait,
+ TASK_UNINTERRUPTIBLE);
+ if (!mddev->suspended)
+ break;
+ rcu_read_unlock();
+ schedule();
+ rcu_read_lock();
+ }
+ finish_wait(&mddev->sb_wait, &__wait);
+ }
+ atomic_inc(&mddev->active_io);
+ rcu_read_unlock();
+ rv = mddev->pers->make_request(q, bio);
+ if (atomic_dec_and_test(&mddev->active_io) && mddev->suspended)
+ wake_up(&mddev->sb_wait);
+
+ return rv;
+}
+
+static void mddev_suspend(mddev_t *mddev)
+{
+ BUG_ON(mddev->suspended);
+ mddev->suspended = 1;
+ synchronize_rcu();
+ wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
+ mddev->pers->quiesce(mddev, 1);
+ md_unregister_thread(mddev->thread);
+ mddev->thread = NULL;
+ /* we now know that no code is executing in the personality module,
+ * except possibly the tail end of a ->bi_end_io function, but that
+ * is certain to complete before the module has a chance to get
+ * unloaded
+ */
+}
+
+static void mddev_resume(mddev_t *mddev)
+{
+ mddev->suspended = 0;
+ wake_up(&mddev->sb_wait);
+ mddev->pers->quiesce(mddev, 0);
}
+
static inline mddev_t *mddev_get(mddev_t *mddev)
{
atomic_inc(&mddev->active);
@@ -310,6 +365,7 @@ static mddev_t * mddev_find(dev_t unit)
init_timer(&new->safemode_timer);
atomic_set(&new->active, 1);
atomic_set(&new->openers, 0);
+ atomic_set(&new->active_io, 0);
spin_lock_init(&new->write_lock);
init_waitqueue_head(&new->sb_wait);
init_waitqueue_head(&new->recovery_wait);
@@ -326,6 +382,11 @@ static inline int mddev_lock(mddev_t * mddev)
return mutex_lock_interruptible(&mddev->reconfig_mutex);
}
+static inline int mddev_is_locked(mddev_t *mddev)
+{
+ return mutex_is_locked(&mddev->reconfig_mutex);
+}
+
static inline int mddev_trylock(mddev_t * mddev)
{
return mutex_trylock(&mddev->reconfig_mutex);
@@ -409,7 +470,7 @@ static void free_disk_sb(mdk_rdev_t * rdev)
rdev->sb_loaded = 0;
rdev->sb_page = NULL;
rdev->sb_start = 0;
- rdev->size = 0;
+ rdev->sectors = 0;
}
}
@@ -775,9 +836,9 @@ static int super_90_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version
else
ret = 0;
}
- rdev->size = calc_num_sectors(rdev, sb->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, sb->chunk_size);
- if (rdev->size < sb->size && sb->level > 1)
+ if (rdev->sectors < sb->size * 2 && sb->level > 1)
/* "this cannot possibly happen" ... */
ret = -EINVAL;
@@ -812,7 +873,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->clevel[0] = 0;
mddev->layout = sb->layout;
mddev->raid_disks = sb->raid_disks;
- mddev->size = sb->size;
+ mddev->dev_sectors = sb->size * 2;
mddev->events = ev1;
mddev->bitmap_offset = 0;
mddev->default_bitmap_offset = MD_SB_BYTES >> 9;
@@ -926,7 +987,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->ctime = mddev->ctime;
sb->level = mddev->level;
- sb->size = mddev->size;
+ sb->size = mddev->dev_sectors / 2;
sb->raid_disks = mddev->raid_disks;
sb->md_minor = mddev->md_minor;
sb->not_persistent = 0;
@@ -1024,7 +1085,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev)
static unsigned long long
super_90_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
{
- if (num_sectors && num_sectors < rdev->mddev->size * 2)
+ if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
return 0; /* component must fit device */
if (rdev->mddev->bitmap_offset)
return 0; /* can't move bitmap */
@@ -1180,16 +1241,17 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
ret = 0;
}
if (minor_version)
- rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
+ rdev->sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+ le64_to_cpu(sb->data_offset);
else
- rdev->size = rdev->sb_start / 2;
- if (rdev->size < le64_to_cpu(sb->data_size)/2)
+ rdev->sectors = rdev->sb_start;
+ if (rdev->sectors < le64_to_cpu(sb->data_size))
return -EINVAL;
- rdev->size = le64_to_cpu(sb->data_size)/2;
+ rdev->sectors = le64_to_cpu(sb->data_size);
if (le32_to_cpu(sb->chunksize))
- rdev->size &= ~((sector_t)le32_to_cpu(sb->chunksize)/2 - 1);
+ rdev->sectors &= ~((sector_t)le32_to_cpu(sb->chunksize) - 1);
- if (le64_to_cpu(sb->size) > rdev->size*2)
+ if (le64_to_cpu(sb->size) > rdev->sectors)
return -EINVAL;
return ret;
}
@@ -1216,7 +1278,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev)
mddev->clevel[0] = 0;
mddev->layout = le32_to_cpu(sb->layout);
mddev->raid_disks = le32_to_cpu(sb->raid_disks);
- mddev->size = le64_to_cpu(sb->size)/2;
+ mddev->dev_sectors = le64_to_cpu(sb->size);
mddev->events = ev1;
mddev->bitmap_offset = 0;
mddev->default_bitmap_offset = 1024 >> 9;
@@ -1312,7 +1374,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
sb->cnt_corrected_read = cpu_to_le32(atomic_read(&rdev->corrected_errors));
sb->raid_disks = cpu_to_le32(mddev->raid_disks);
- sb->size = cpu_to_le64(mddev->size<<1);
+ sb->size = cpu_to_le64(mddev->dev_sectors);
if (mddev->bitmap && mddev->bitmap_file == NULL) {
sb->bitmap_offset = cpu_to_le32((__u32)mddev->bitmap_offset);
@@ -1320,10 +1382,15 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev)
}
if (rdev->raid_disk >= 0 &&
- !test_bit(In_sync, &rdev->flags) &&
- rdev->recovery_offset > 0) {
- sb->feature_map |= cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
- sb->recovery_offset = cpu_to_le64(rdev->recovery_offset);
+ !test_bit(In_sync, &rdev->flags)) {
+ if (mddev->curr_resync_completed > rdev->recovery_offset)
+ rdev->recovery_offset = mddev->curr_resync_completed;
+ if (rdev->recovery_offset > 0) {
+ sb->feature_map |=
+ cpu_to_le32(MD_FEATURE_RECOVERY_OFFSET);
+ sb->recovery_offset =
+ cpu_to_le64(rdev->recovery_offset);
+ }
}
if (mddev->reshape_position != MaxSector) {
@@ -1365,7 +1432,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
{
struct mdp_superblock_1 *sb;
sector_t max_sectors;
- if (num_sectors && num_sectors < rdev->mddev->size * 2)
+ if (num_sectors && num_sectors < rdev->mddev->dev_sectors)
return 0; /* component must fit device */
if (rdev->sb_start < rdev->data_offset) {
/* minor versions 1 and 2; superblock before data */
@@ -1381,7 +1448,7 @@ super_1_rdev_size_change(mdk_rdev_t *rdev, sector_t num_sectors)
sector_t sb_start;
sb_start = (rdev->bdev->bd_inode->i_size >> 9) - 8*2;
sb_start &= ~(sector_t)(4*2 - 1);
- max_sectors = rdev->size * 2 + sb_start - rdev->sb_start;
+ max_sectors = rdev->sectors + sb_start - rdev->sb_start;
if (!num_sectors || num_sectors > max_sectors)
num_sectors = max_sectors;
rdev->sb_start = sb_start;
@@ -1433,6 +1500,38 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2)
static LIST_HEAD(pending_raid_disks);
+static void md_integrity_check(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+ struct mdk_personality *pers = mddev->pers;
+ struct gendisk *disk = mddev->gendisk;
+ struct blk_integrity *bi_rdev = bdev_get_integrity(rdev->bdev);
+ struct blk_integrity *bi_mddev = blk_get_integrity(disk);
+
+ /* Data integrity passthrough not supported on RAID 4, 5 and 6 */
+ if (pers && pers->level >= 4 && pers->level <= 6)
+ return;
+
+ /* If rdev is integrity capable, register profile for mddev */
+ if (!bi_mddev && bi_rdev) {
+ if (blk_integrity_register(disk, bi_rdev))
+ printk(KERN_ERR "%s: %s Could not register integrity!\n",
+ __func__, disk->disk_name);
+ else
+ printk(KERN_NOTICE "Enabling data integrity on %s\n",
+ disk->disk_name);
+ return;
+ }
+
+ /* Check that mddev and rdev have matching profiles */
+ if (blk_integrity_compare(disk, rdev->bdev->bd_disk) < 0) {
+ printk(KERN_ERR "%s: %s/%s integrity mismatch!\n", __func__,
+ disk->disk_name, rdev->bdev->bd_disk->disk_name);
+ printk(KERN_NOTICE "Disabling data integrity on %s\n",
+ disk->disk_name);
+ blk_integrity_unregister(disk);
+ }
+}
+
static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
{
char b[BDEVNAME_SIZE];
@@ -1449,8 +1548,9 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (find_rdev(mddev, rdev->bdev->bd_dev))
return -EEXIST;
- /* make sure rdev->size exceeds mddev->size */
- if (rdev->size && (mddev->size == 0 || rdev->size < mddev->size)) {
+ /* make sure rdev->sectors exceeds mddev->dev_sectors */
+ if (rdev->sectors && (mddev->dev_sectors == 0 ||
+ rdev->sectors < mddev->dev_sectors)) {
if (mddev->pers) {
/* Cannot change size, so fail
* If mddev->level <= 0, then we don't care
@@ -1459,7 +1559,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
if (mddev->level > 0)
return -ENOSPC;
} else
- mddev->size = rdev->size;
+ mddev->dev_sectors = rdev->sectors;
}
/* Verify rdev->desc_nr is unique.
@@ -1503,6 +1603,8 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
/* May as well allow recovery to be retried once */
mddev->recovery_disabled = 0;
+
+ md_integrity_check(rdev, mddev);
return 0;
fail:
@@ -1713,8 +1815,8 @@ static void print_sb_1(struct mdp_superblock_1 *sb)
static void print_rdev(mdk_rdev_t *rdev, int major_version)
{
char b[BDEVNAME_SIZE];
- printk(KERN_INFO "md: rdev %s, SZ:%08llu F:%d S:%d DN:%u\n",
- bdevname(rdev->bdev,b), (unsigned long long)rdev->size,
+ printk(KERN_INFO "md: rdev %s, Sect:%08llu F:%d S:%d DN:%u\n",
+ bdevname(rdev->bdev, b), (unsigned long long)rdev->sectors,
test_bit(Faulty, &rdev->flags), test_bit(In_sync, &rdev->flags),
rdev->desc_nr);
if (rdev->sb_loaded) {
@@ -2153,7 +2255,7 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len)
return -EINVAL;
if (rdev->mddev->pers && rdev->raid_disk >= 0)
return -EBUSY;
- if (rdev->size && rdev->mddev->external)
+ if (rdev->sectors && rdev->mddev->external)
/* Must set offset before size, so overlap checks
* can be sane */
return -EBUSY;
@@ -2167,7 +2269,7 @@ __ATTR(offset, S_IRUGO|S_IWUSR, offset_show, offset_store);
static ssize_t
rdev_size_show(mdk_rdev_t *rdev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)rdev->size);
+ return sprintf(page, "%llu\n", (unsigned long long)rdev->sectors / 2);
}
static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
@@ -2180,34 +2282,52 @@ static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2)
return 1;
}
+static int strict_blocks_to_sectors(const char *buf, sector_t *sectors)
+{
+ unsigned long long blocks;
+ sector_t new;
+
+ if (strict_strtoull(buf, 10, &blocks) < 0)
+ return -EINVAL;
+
+ if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
+ return -EINVAL; /* sector conversion overflow */
+
+ new = blocks * 2;
+ if (new != blocks * 2)
+ return -EINVAL; /* unsigned long long to sector_t overflow */
+
+ *sectors = new;
+ return 0;
+}
+
static ssize_t
rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
{
- unsigned long long size;
- unsigned long long oldsize = rdev->size;
mddev_t *my_mddev = rdev->mddev;
+ sector_t oldsectors = rdev->sectors;
+ sector_t sectors;
- if (strict_strtoull(buf, 10, &size) < 0)
+ if (strict_blocks_to_sectors(buf, &sectors) < 0)
return -EINVAL;
if (my_mddev->pers && rdev->raid_disk >= 0) {
if (my_mddev->persistent) {
- size = super_types[my_mddev->major_version].
- rdev_size_change(rdev, size * 2);
- if (!size)
+ sectors = super_types[my_mddev->major_version].
+ rdev_size_change(rdev, sectors);
+ if (!sectors)
return -EBUSY;
- } else if (!size) {
- size = (rdev->bdev->bd_inode->i_size >> 10);
- size -= rdev->data_offset/2;
- }
+ } else if (!sectors)
+ sectors = (rdev->bdev->bd_inode->i_size >> 9) -
+ rdev->data_offset;
}
- if (size < my_mddev->size)
+ if (sectors < my_mddev->dev_sectors)
return -EINVAL; /* component must fit device */
- rdev->size = size;
- if (size > oldsize && my_mddev->external) {
+ rdev->sectors = sectors;
+ if (sectors > oldsectors && my_mddev->external) {
/* need to check that all other rdevs with the same ->bdev
* do not overlap. We need to unlock the mddev to avoid
- * a deadlock. We have already changed rdev->size, and if
+ * a deadlock. We have already changed rdev->sectors, and if
* we have to change it back, we will have the lock again.
*/
mddev_t *mddev;
@@ -2223,9 +2343,9 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (test_bit(AllReserved, &rdev2->flags) ||
(rdev->bdev == rdev2->bdev &&
rdev != rdev2 &&
- overlaps(rdev->data_offset, rdev->size * 2,
+ overlaps(rdev->data_offset, rdev->sectors,
rdev2->data_offset,
- rdev2->size * 2))) {
+ rdev2->sectors))) {
overlap = 1;
break;
}
@@ -2239,11 +2359,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
if (overlap) {
/* Someone else could have slipped in a size
* change here, but doing so is just silly.
- * We put oldsize back because we *know* it is
+ * We put oldsectors back because we *know* it is
* safe, and trust userspace not to race with
* itself
*/
- rdev->size = oldsize;
+ rdev->sectors = oldsectors;
return -EBUSY;
}
}
@@ -2547,18 +2667,101 @@ level_show(mddev_t *mddev, char *page)
static ssize_t
level_store(mddev_t *mddev, const char *buf, size_t len)
{
+ char level[16];
ssize_t rv = len;
- if (mddev->pers)
+ struct mdk_personality *pers;
+ void *priv;
+
+ if (mddev->pers == NULL) {
+ if (len == 0)
+ return 0;
+ if (len >= sizeof(mddev->clevel))
+ return -ENOSPC;
+ strncpy(mddev->clevel, buf, len);
+ if (mddev->clevel[len-1] == '\n')
+ len--;
+ mddev->clevel[len] = 0;
+ mddev->level = LEVEL_NONE;
+ return rv;
+ }
+
+ /* request to change the personality. Need to ensure:
+ * - array is not engaged in resync/recovery/reshape
+ * - old personality can be suspended
+ * - new personality will access other array.
+ */
+
+ if (mddev->sync_thread || mddev->reshape_position != MaxSector)
return -EBUSY;
- if (len == 0)
- return 0;
- if (len >= sizeof(mddev->clevel))
- return -ENOSPC;
- strncpy(mddev->clevel, buf, len);
- if (mddev->clevel[len-1] == '\n')
+
+ if (!mddev->pers->quiesce) {
+ printk(KERN_WARNING "md: %s: %s does not support online personality change\n",
+ mdname(mddev), mddev->pers->name);
+ return -EINVAL;
+ }
+
+ /* Now find the new personality */
+ if (len == 0 || len >= sizeof(level))
+ return -EINVAL;
+ strncpy(level, buf, len);
+ if (level[len-1] == '\n')
len--;
- mddev->clevel[len] = 0;
- mddev->level = LEVEL_NONE;
+ level[len] = 0;
+
+ request_module("md-%s", level);
+ spin_lock(&pers_lock);
+ pers = find_pers(LEVEL_NONE, level);
+ if (!pers || !try_module_get(pers->owner)) {
+ spin_unlock(&pers_lock);
+ printk(KERN_WARNING "md: personality %s not loaded\n", level);
+ return -EINVAL;
+ }
+ spin_unlock(&pers_lock);
+
+ if (pers == mddev->pers) {
+ /* Nothing to do! */
+ module_put(pers->owner);
+ return rv;
+ }
+ if (!pers->takeover) {
+ module_put(pers->owner);
+ printk(KERN_WARNING "md: %s: %s does not support personality takeover\n",
+ mdname(mddev), level);
+ return -EINVAL;
+ }
+
+ /* ->takeover must set new_* and/or delta_disks
+ * if it succeeds, and may set them when it fails.
+ */
+ priv = pers->takeover(mddev);
+ if (IS_ERR(priv)) {
+ mddev->new_level = mddev->level;
+ mddev->new_layout = mddev->layout;
+ mddev->new_chunk = mddev->chunk_size;
+ mddev->raid_disks -= mddev->delta_disks;
+ mddev->delta_disks = 0;
+ module_put(pers->owner);
+ printk(KERN_WARNING "md: %s: %s would not accept array\n",
+ mdname(mddev), level);
+ return PTR_ERR(priv);
+ }
+
+ /* Looks like we have a winner */
+ mddev_suspend(mddev);
+ mddev->pers->stop(mddev);
+ module_put(mddev->pers->owner);
+ mddev->pers = pers;
+ mddev->private = priv;
+ strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+ mddev->level = mddev->new_level;
+ mddev->layout = mddev->new_layout;
+ mddev->chunk_size = mddev->new_chunk;
+ mddev->delta_disks = 0;
+ pers->run(mddev);
+ mddev_resume(mddev);
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+ md_wakeup_thread(mddev->thread);
return rv;
}
@@ -2586,12 +2789,18 @@ layout_store(mddev_t *mddev, const char *buf, size_t len)
if (!*buf || (*e && *e != '\n'))
return -EINVAL;
- if (mddev->pers)
- return -EBUSY;
- if (mddev->reshape_position != MaxSector)
+ if (mddev->pers) {
+ int err;
+ if (mddev->pers->reconfig == NULL)
+ return -EBUSY;
+ err = mddev->pers->reconfig(mddev, n, -1);
+ if (err)
+ return err;
+ } else {
mddev->new_layout = n;
- else
- mddev->layout = n;
+ if (mddev->reshape_position == MaxSector)
+ mddev->layout = n;
+ }
return len;
}
static struct md_sysfs_entry md_layout =
@@ -2648,19 +2857,24 @@ chunk_size_show(mddev_t *mddev, char *page)
static ssize_t
chunk_size_store(mddev_t *mddev, const char *buf, size_t len)
{
- /* can only set chunk_size if array is not yet active */
char *e;
unsigned long n = simple_strtoul(buf, &e, 10);
if (!*buf || (*e && *e != '\n'))
return -EINVAL;
- if (mddev->pers)
- return -EBUSY;
- else if (mddev->reshape_position != MaxSector)
+ if (mddev->pers) {
+ int err;
+ if (mddev->pers->reconfig == NULL)
+ return -EBUSY;
+ err = mddev->pers->reconfig(mddev, -1, n);
+ if (err)
+ return err;
+ } else {
mddev->new_chunk = n;
- else
- mddev->chunk_size = n;
+ if (mddev->reshape_position == MaxSector)
+ mddev->chunk_size = n;
+ }
return len;
}
static struct md_sysfs_entry md_chunk_size =
@@ -2669,6 +2883,8 @@ __ATTR(chunk_size, S_IRUGO|S_IWUSR, chunk_size_show, chunk_size_store);
static ssize_t
resync_start_show(mddev_t *mddev, char *page)
{
+ if (mddev->recovery_cp == MaxSector)
+ return sprintf(page, "none\n");
return sprintf(page, "%llu\n", (unsigned long long)mddev->recovery_cp);
}
@@ -2766,7 +2982,7 @@ array_state_show(mddev_t *mddev, char *page)
else {
if (list_empty(&mddev->disks) &&
mddev->raid_disks == 0 &&
- mddev->size == 0)
+ mddev->dev_sectors == 0)
st = clear;
else
st = inactive;
@@ -2973,7 +3189,8 @@ __ATTR(bitmap_set_bits, S_IWUSR, null_show, bitmap_store);
static ssize_t
size_show(mddev_t *mddev, char *page)
{
- return sprintf(page, "%llu\n", (unsigned long long)mddev->size);
+ return sprintf(page, "%llu\n",
+ (unsigned long long)mddev->dev_sectors / 2);
}
static int update_size(mddev_t *mddev, sector_t num_sectors);
@@ -2985,20 +3202,18 @@ size_store(mddev_t *mddev, const char *buf, size_t len)
* not increase it (except from 0).
* If array is active, we can try an on-line resize
*/
- char *e;
- int err = 0;
- unsigned long long size = simple_strtoull(buf, &e, 10);
- if (!*buf || *buf == '\n' ||
- (*e && *e != '\n'))
- return -EINVAL;
+ sector_t sectors;
+ int err = strict_blocks_to_sectors(buf, &sectors);
+ if (err < 0)
+ return err;
if (mddev->pers) {
- err = update_size(mddev, size * 2);
+ err = update_size(mddev, sectors);
md_update_sb(mddev, 1);
} else {
- if (mddev->size == 0 ||
- mddev->size > size)
- mddev->size = size;
+ if (mddev->dev_sectors == 0 ||
+ mddev->dev_sectors > sectors)
+ mddev->dev_sectors = sectors;
else
err = -ENOSPC;
}
@@ -3251,6 +3466,8 @@ static ssize_t
sync_speed_show(mddev_t *mddev, char *page)
{
unsigned long resync, dt, db;
+ if (mddev->curr_resync == 0)
+ return sprintf(page, "none\n");
resync = mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active);
dt = (jiffies - mddev->resync_mark) / HZ;
if (!dt) dt++;
@@ -3263,15 +3480,15 @@ static struct md_sysfs_entry md_sync_speed = __ATTR_RO(sync_speed);
static ssize_t
sync_completed_show(mddev_t *mddev, char *page)
{
- unsigned long max_blocks, resync;
+ unsigned long max_sectors, resync;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
- max_blocks = mddev->resync_max_sectors;
+ max_sectors = mddev->resync_max_sectors;
else
- max_blocks = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
- return sprintf(page, "%lu / %lu\n", resync, max_blocks);
+ return sprintf(page, "%lu / %lu\n", resync, max_sectors);
}
static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed);
@@ -3431,6 +3648,57 @@ static struct md_sysfs_entry md_reshape_position =
__ATTR(reshape_position, S_IRUGO|S_IWUSR, reshape_position_show,
reshape_position_store);
+static ssize_t
+array_size_show(mddev_t *mddev, char *page)
+{
+ if (mddev->external_size)
+ return sprintf(page, "%llu\n",
+ (unsigned long long)mddev->array_sectors/2);
+ else
+ return sprintf(page, "default\n");
+}
+
+static ssize_t
+array_size_store(mddev_t *mddev, const char *buf, size_t len)
+{
+ sector_t sectors;
+
+ if (strncmp(buf, "default", 7) == 0) {
+ if (mddev->pers)
+ sectors = mddev->pers->size(mddev, 0, 0);
+ else
+ sectors = mddev->array_sectors;
+
+ mddev->external_size = 0;
+ } else {
+ if (strict_blocks_to_sectors(buf, &sectors) < 0)
+ return -EINVAL;
+ if (mddev->pers && mddev->pers->size(mddev, 0, 0) < sectors)
+ return -EINVAL;
+
+ mddev->external_size = 1;
+ }
+
+ mddev->array_sectors = sectors;
+ set_capacity(mddev->gendisk, mddev->array_sectors);
+ if (mddev->pers) {
+ struct block_device *bdev = bdget_disk(mddev->gendisk, 0);
+
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode,
+ (loff_t)mddev->array_sectors << 9);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+ }
+
+ return len;
+}
+
+static struct md_sysfs_entry md_array_size =
+__ATTR(array_size, S_IRUGO|S_IWUSR, array_size_show,
+ array_size_store);
static struct attribute *md_default_attrs[] = {
&md_level.attr,
@@ -3444,6 +3712,7 @@ static struct attribute *md_default_attrs[] = {
&md_safe_delay.attr,
&md_array_state.attr,
&md_reshape_position.attr,
+ &md_array_size.attr,
NULL,
};
@@ -3602,10 +3871,12 @@ static int md_alloc(dev_t dev, char *name)
mddev_put(mddev);
return -ENOMEM;
}
+ mddev->queue->queuedata = mddev;
+
/* Can be unlocked because the queue is new: no concurrency */
queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue);
- blk_queue_make_request(mddev->queue, md_fail_request);
+ blk_queue_make_request(mddev->queue, md_make_request);
disk = alloc_disk(1 << shift);
if (!disk) {
@@ -3731,13 +4002,13 @@ static int do_md_run(mddev_t * mddev)
list_for_each_entry(rdev, &mddev->disks, same_set) {
if (test_bit(Faulty, &rdev->flags))
continue;
- if (rdev->size < chunk_size / 1024) {
+ if (rdev->sectors < chunk_size / 512) {
printk(KERN_WARNING
"md: Dev %s smaller than chunk_size:"
- " %lluk < %dk\n",
+ " %llu < %d\n",
bdevname(rdev->bdev,b),
- (unsigned long long)rdev->size,
- chunk_size / 1024);
+ (unsigned long long)rdev->sectors,
+ chunk_size / 512);
return -EINVAL;
}
}
@@ -3761,11 +4032,11 @@ static int do_md_run(mddev_t * mddev)
/* perform some consistency tests on the device.
* We don't want the data to overlap the metadata,
- * Internal Bitmap issues has handled elsewhere.
+ * Internal Bitmap issues have been handled elsewhere.
*/
if (rdev->data_offset < rdev->sb_start) {
- if (mddev->size &&
- rdev->data_offset + mddev->size*2
+ if (mddev->dev_sectors &&
+ rdev->data_offset + mddev->dev_sectors
> rdev->sb_start) {
printk("md: %s: data overlaps metadata\n",
mdname(mddev));
@@ -3801,9 +4072,16 @@ static int do_md_run(mddev_t * mddev)
}
mddev->pers = pers;
spin_unlock(&pers_lock);
- mddev->level = pers->level;
+ if (mddev->level != pers->level) {
+ mddev->level = pers->level;
+ mddev->new_level = pers->level;
+ }
strlcpy(mddev->clevel, pers->name, sizeof(mddev->clevel));
+ if (pers->level >= 4 && pers->level <= 6)
+ /* Cannot support integrity (yet) */
+ blk_integrity_unregister(mddev->gendisk);
+
if (mddev->reshape_position != MaxSector &&
pers->start_reshape == NULL) {
/* This personality cannot handle reshaping... */
@@ -3843,7 +4121,9 @@ static int do_md_run(mddev_t * mddev)
}
mddev->recovery = 0;
- mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */
+ /* may be over-ridden by personality */
+ mddev->resync_max_sectors = mddev->dev_sectors;
+
mddev->barriers_work = 1;
mddev->ok_start_degraded = start_dirty_degraded;
@@ -3853,7 +4133,17 @@ static int do_md_run(mddev_t * mddev)
err = mddev->pers->run(mddev);
if (err)
printk(KERN_ERR "md: pers->run() failed ...\n");
- else if (mddev->pers->sync_request) {
+ else if (mddev->pers->size(mddev, 0, 0) < mddev->array_sectors) {
+ WARN_ONCE(!mddev->external_size, "%s: default size too small,"
+ " but 'external_size' not in effect?\n", __func__);
+ printk(KERN_ERR
+ "md: invalid array_size %llu > default size %llu\n",
+ (unsigned long long)mddev->array_sectors / 2,
+ (unsigned long long)mddev->pers->size(mddev, 0, 0) / 2);
+ err = -EINVAL;
+ mddev->pers->stop(mddev);
+ }
+ if (err == 0 && mddev->pers->sync_request) {
err = bitmap_create(mddev);
if (err) {
printk(KERN_ERR "%s: failed to create bitmap (%d)\n",
@@ -3899,16 +4189,6 @@ static int do_md_run(mddev_t * mddev)
set_capacity(disk, mddev->array_sectors);
- /* If we call blk_queue_make_request here, it will
- * re-initialise max_sectors etc which may have been
- * refined inside -> run. So just set the bits we need to set.
- * Most initialisation happended when we called
- * blk_queue_make_request(..., md_fail_request)
- * earlier.
- */
- mddev->queue->queuedata = mddev;
- mddev->queue->make_request_fn = mddev->pers->make_request;
-
/* If there is a partially-recovered drive we need to
* start recovery here. If we leave it to md_check_recovery,
* it will remove the drives and not do the right thing
@@ -4038,7 +4318,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
md_super_wait(mddev);
if (mddev->ro)
set_disk_ro(disk, 0);
- blk_queue_make_request(mddev->queue, md_fail_request);
+
mddev->pers->stop(mddev);
mddev->queue->merge_bvec_fn = NULL;
mddev->queue->unplug_fn = NULL;
@@ -4095,7 +4375,8 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
export_array(mddev);
mddev->array_sectors = 0;
- mddev->size = 0;
+ mddev->external_size = 0;
+ mddev->dev_sectors = 0;
mddev->raid_disks = 0;
mddev->recovery_cp = 0;
mddev->resync_min = 0;
@@ -4135,6 +4416,7 @@ static int do_md_stop(mddev_t * mddev, int mode, int is_open)
printk(KERN_INFO "md: %s switched to read-only mode.\n",
mdname(mddev));
err = 0;
+ blk_integrity_unregister(disk);
md_new_event(mddev);
sysfs_notify_dirent(mddev->sysfs_state);
out:
@@ -4300,8 +4582,8 @@ static int get_array_info(mddev_t * mddev, void __user * arg)
info.patch_version = MD_PATCHLEVEL_VERSION;
info.ctime = mddev->ctime;
info.level = mddev->level;
- info.size = mddev->size;
- if (info.size != mddev->size) /* overflow */
+ info.size = mddev->dev_sectors / 2;
+ if (info.size != mddev->dev_sectors / 2) /* overflow */
info.size = -1;
info.nr_disks = nr;
info.raid_disks = mddev->raid_disks;
@@ -4480,6 +4762,8 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
clear_bit(In_sync, &rdev->flags); /* just to be sure */
if (info->state & (1<<MD_DISK_WRITEMOSTLY))
set_bit(WriteMostly, &rdev->flags);
+ else
+ clear_bit(WriteMostly, &rdev->flags);
rdev->raid_disk = -1;
err = bind_rdev_to_array(rdev, mddev);
@@ -4543,7 +4827,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info)
rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
} else
rdev->sb_start = calc_dev_sboffset(rdev->bdev);
- rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
err = bind_rdev_to_array(rdev, mddev);
if (err) {
@@ -4613,7 +4897,7 @@ static int hot_add_disk(mddev_t * mddev, dev_t dev)
else
rdev->sb_start = rdev->bdev->bd_inode->i_size / 512;
- rdev->size = calc_num_sectors(rdev, mddev->chunk_size) / 2;
+ rdev->sectors = calc_num_sectors(rdev, mddev->chunk_size);
if (test_bit(Faulty, &rdev->flags)) {
printk(KERN_WARNING
@@ -4749,7 +5033,7 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
mddev->level = info->level;
mddev->clevel[0] = 0;
- mddev->size = info->size;
+ mddev->dev_sectors = 2 * (sector_t)info->size;
mddev->raid_disks = info->raid_disks;
/* don't set md_minor, it is determined by which /dev/md* was
* openned
@@ -4788,6 +5072,17 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info)
return 0;
}
+void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors)
+{
+ WARN(!mddev_is_locked(mddev), "%s: unlocked mddev!\n", __func__);
+
+ if (mddev->external_size)
+ return;
+
+ mddev->array_sectors = array_sectors;
+}
+EXPORT_SYMBOL(md_set_array_sectors);
+
static int update_size(mddev_t *mddev, sector_t num_sectors)
{
mdk_rdev_t *rdev;
@@ -4814,8 +5109,7 @@ static int update_size(mddev_t *mddev, sector_t num_sectors)
*/
return -EBUSY;
list_for_each_entry(rdev, &mddev->disks, same_set) {
- sector_t avail;
- avail = rdev->size * 2;
+ sector_t avail = rdev->sectors;
if (fit && (num_sectors == 0 || num_sectors > avail))
num_sectors = avail;
@@ -4887,12 +5181,18 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
)
return -EINVAL;
/* Check there is only one change */
- if (info->size >= 0 && mddev->size != info->size) cnt++;
- if (mddev->raid_disks != info->raid_disks) cnt++;
- if (mddev->layout != info->layout) cnt++;
- if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT)) cnt++;
- if (cnt == 0) return 0;
- if (cnt > 1) return -EINVAL;
+ if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
+ cnt++;
+ if (mddev->raid_disks != info->raid_disks)
+ cnt++;
+ if (mddev->layout != info->layout)
+ cnt++;
+ if ((state ^ info->state) & (1<<MD_SB_BITMAP_PRESENT))
+ cnt++;
+ if (cnt == 0)
+ return 0;
+ if (cnt > 1)
+ return -EINVAL;
if (mddev->layout != info->layout) {
/* Change layout
@@ -4904,7 +5204,7 @@ static int update_array_info(mddev_t *mddev, mdu_array_info_t *info)
else
return mddev->pers->reconfig(mddev, info->layout, -1);
}
- if (info->size >= 0 && mddev->size != info->size)
+ if (info->size >= 0 && mddev->dev_sectors / 2 != info->size)
rv = update_size(mddev, (sector_t)info->size * 2);
if (mddev->raid_disks != info->raid_disks)
@@ -5331,6 +5631,8 @@ mdk_thread_t *md_register_thread(void (*run) (mddev_t *), mddev_t *mddev,
void md_unregister_thread(mdk_thread_t *thread)
{
+ if (!thread)
+ return;
dprintk("interrupting MD-thread pid %d\n", task_pid_nr(thread->tsk));
kthread_stop(thread->tsk);
@@ -5404,7 +5706,7 @@ static void status_resync(struct seq_file *seq, mddev_t * mddev)
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_blocks = mddev->resync_max_sectors >> 1;
else
- max_blocks = mddev->size;
+ max_blocks = mddev->dev_sectors / 2;
/*
* Should not happen.
@@ -5537,7 +5839,7 @@ struct mdstat_info {
static int md_seq_show(struct seq_file *seq, void *v)
{
mddev_t *mddev = v;
- sector_t size;
+ sector_t sectors;
mdk_rdev_t *rdev;
struct mdstat_info *mi = seq->private;
struct bitmap *bitmap;
@@ -5573,7 +5875,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
seq_printf(seq, " %s", mddev->pers->name);
}
- size = 0;
+ sectors = 0;
list_for_each_entry(rdev, &mddev->disks, same_set) {
char b[BDEVNAME_SIZE];
seq_printf(seq, " %s[%d]",
@@ -5585,7 +5887,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
continue;
} else if (rdev->raid_disk < 0)
seq_printf(seq, "(S)"); /* spare */
- size += rdev->size;
+ sectors += rdev->sectors;
}
if (!list_empty(&mddev->disks)) {
@@ -5595,7 +5897,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
mddev->array_sectors / 2);
else
seq_printf(seq, "\n %llu blocks",
- (unsigned long long)size);
+ (unsigned long long)sectors / 2);
}
if (mddev->persistent) {
if (mddev->major_version != 0 ||
@@ -5722,19 +6024,19 @@ int unregister_md_personality(struct mdk_personality *p)
return 0;
}
-static int is_mddev_idle(mddev_t *mddev)
+static int is_mddev_idle(mddev_t *mddev, int init)
{
mdk_rdev_t * rdev;
int idle;
- long curr_events;
+ int curr_events;
idle = 1;
rcu_read_lock();
rdev_for_each_rcu(rdev, mddev) {
struct gendisk *disk = rdev->bdev->bd_contains->bd_disk;
- curr_events = part_stat_read(&disk->part0, sectors[0]) +
- part_stat_read(&disk->part0, sectors[1]) -
- atomic_read(&disk->sync_io);
+ curr_events = (int)part_stat_read(&disk->part0, sectors[0]) +
+ (int)part_stat_read(&disk->part0, sectors[1]) -
+ atomic_read(&disk->sync_io);
/* sync IO will cause sync_io to increase before the disk_stats
* as sync_io is counted when a request starts, and
* disk_stats is counted when it completes.
@@ -5757,7 +6059,7 @@ static int is_mddev_idle(mddev_t *mddev)
* always make curr_events less than last_events.
*
*/
- if (curr_events - rdev->last_events > 4096) {
+ if (init || curr_events - rdev->last_events > 64) {
rdev->last_events = curr_events;
idle = 0;
}
@@ -5980,10 +6282,10 @@ void md_do_sync(mddev_t *mddev)
j = mddev->recovery_cp;
} else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
- max_sectors = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
else {
/* recovery follows the physical size of devices */
- max_sectors = mddev->size << 1;
+ max_sectors = mddev->dev_sectors;
j = MaxSector;
list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
@@ -6000,7 +6302,7 @@ void md_do_sync(mddev_t *mddev)
"(but not more than %d KB/sec) for %s.\n",
speed_max(mddev), desc);
- is_mddev_idle(mddev); /* this also initializes IO event counters */
+ is_mddev_idle(mddev, 1); /* this initializes IO event counters */
io_sectors = 0;
for (m = 0; m < SYNC_MARKS; m++) {
@@ -6040,6 +6342,18 @@ void md_do_sync(mddev_t *mddev)
}
if (kthread_should_stop())
goto interrupted;
+
+ if (mddev->curr_resync > mddev->curr_resync_completed &&
+ (mddev->curr_resync - mddev->curr_resync_completed)
+ > (max_sectors >> 4)) {
+ /* time to update curr_resync_completed */
+ blk_unplug(mddev->queue);
+ wait_event(mddev->recovery_wait,
+ atomic_read(&mddev->recovery_active) == 0);
+ mddev->curr_resync_completed =
+ mddev->curr_resync;
+ set_bit(MD_CHANGE_CLEAN, &mddev->flags);
+ }
sectors = mddev->pers->sync_request(mddev, j, &skipped,
currspeed < speed_min(mddev));
if (sectors == 0) {
@@ -6102,7 +6416,7 @@ void md_do_sync(mddev_t *mddev)
if (currspeed > speed_min(mddev)) {
if ((currspeed > speed_max(mddev)) ||
- !is_mddev_idle(mddev)) {
+ !is_mddev_idle(mddev, 0)) {
msleep(500);
goto repeat;
}
@@ -6173,6 +6487,8 @@ static int remove_and_add_spares(mddev_t *mddev)
mdk_rdev_t *rdev;
int spares = 0;
+ mddev->curr_resync_completed = 0;
+
list_for_each_entry(rdev, &mddev->disks, same_set)
if (rdev->raid_disk >= 0 &&
!test_bit(Blocked, &rdev->flags) &&
@@ -6327,6 +6643,9 @@ void md_check_recovery(mddev_t *mddev)
sysfs_notify(&mddev->kobj, NULL,
"degraded");
}
+ if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+ mddev->pers->finish_reshape)
+ mddev->pers->finish_reshape(mddev);
md_update_sb(mddev, 1);
/* if array is no-longer degraded, then any saved_raid_disk
@@ -6470,13 +6789,13 @@ static void md_geninit(void)
static int __init md_init(void)
{
- if (register_blkdev(MAJOR_NR, "md"))
+ if (register_blkdev(MD_MAJOR, "md"))
return -1;
if ((mdp_major=register_blkdev(0, "mdp"))<=0) {
- unregister_blkdev(MAJOR_NR, "md");
+ unregister_blkdev(MD_MAJOR, "md");
return -1;
}
- blk_register_region(MKDEV(MAJOR_NR, 0), 1UL<<MINORBITS, THIS_MODULE,
+ blk_register_region(MKDEV(MD_MAJOR, 0), 1UL<<MINORBITS, THIS_MODULE,
md_probe, NULL, NULL);
blk_register_region(MKDEV(mdp_major, 0), 1UL<<MINORBITS, THIS_MODULE,
md_probe, NULL, NULL);
@@ -6562,10 +6881,10 @@ static __exit void md_exit(void)
mddev_t *mddev;
struct list_head *tmp;
- blk_unregister_region(MKDEV(MAJOR_NR,0), 1U << MINORBITS);
+ blk_unregister_region(MKDEV(MD_MAJOR,0), 1U << MINORBITS);
blk_unregister_region(MKDEV(mdp_major,0), 1U << MINORBITS);
- unregister_blkdev(MAJOR_NR,"md");
+ unregister_blkdev(MD_MAJOR,"md");
unregister_blkdev(mdp_major, "mdp");
unregister_reboot_notifier(&md_notifier);
unregister_sysctl_table(raid_table_header);
diff --git a/drivers/md/md.h b/drivers/md/md.h
new file mode 100644
index 00000000000..e9b7f54c24d
--- /dev/null
+++ b/drivers/md/md.h
@@ -0,0 +1,436 @@
+/*
+ md_k.h : kernel internal structure of the Linux MD driver
+ Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ You should have received a copy of the GNU General Public License
+ (for example /usr/src/linux/COPYING); if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _MD_K_H
+#define _MD_K_H
+
+#ifdef CONFIG_BLOCK
+
+#define MaxSector (~(sector_t)0)
+
+typedef struct mddev_s mddev_t;
+typedef struct mdk_rdev_s mdk_rdev_t;
+
+/*
+ * options passed in raidrun:
+ */
+
+/* Currently this must fit in an 'int' */
+#define MAX_CHUNK_SIZE (1<<30)
+
+/*
+ * MD's 'extended' device
+ */
+struct mdk_rdev_s
+{
+ struct list_head same_set; /* RAID devices within the same set */
+
+ sector_t sectors; /* Device size (in 512bytes sectors) */
+ mddev_t *mddev; /* RAID array if running */
+ int last_events; /* IO event timestamp */
+
+ struct block_device *bdev; /* block device handle */
+
+ struct page *sb_page;
+ int sb_loaded;
+ __u64 sb_events;
+ sector_t data_offset; /* start of data in array */
+ sector_t sb_start; /* offset of the super block (in 512byte sectors) */
+ int sb_size; /* bytes in the superblock */
+ int preferred_minor; /* autorun support */
+
+ struct kobject kobj;
+
+ /* A device can be in one of three states based on two flags:
+ * Not working: faulty==1 in_sync==0
+ * Fully working: faulty==0 in_sync==1
+ * Working, but not
+ * in sync with array
+ * faulty==0 in_sync==0
+ *
+ * It can never have faulty==1, in_sync==1
+ * This reduces the burden of testing multiple flags in many cases
+ */
+
+ unsigned long flags;
+#define Faulty 1 /* device is known to have a fault */
+#define In_sync 2 /* device is in_sync with rest of array */
+#define WriteMostly 4 /* Avoid reading if at all possible */
+#define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */
+#define AllReserved 6 /* If whole device is reserved for
+ * one array */
+#define AutoDetected 7 /* added by auto-detect */
+#define Blocked 8 /* An error occured on an externally
+ * managed array, don't allow writes
+ * until it is cleared */
+#define StateChanged 9 /* Faulty or Blocked has changed during
+ * interrupt, so it needs to be
+ * notified by the thread */
+ wait_queue_head_t blocked_wait;
+
+ int desc_nr; /* descriptor index in the superblock */
+ int raid_disk; /* role of device in array */
+ int saved_raid_disk; /* role that device used to have in the
+ * array and could again if we did a partial
+ * resync from the bitmap
+ */
+ sector_t recovery_offset;/* If this device has been partially
+ * recovered, this is where we were
+ * up to.
+ */
+
+ atomic_t nr_pending; /* number of pending requests.
+ * only maintained for arrays that
+ * support hot removal
+ */
+ atomic_t read_errors; /* number of consecutive read errors that
+ * we have tried to ignore.
+ */
+ atomic_t corrected_errors; /* number of corrected read errors,
+ * for reporting to userspace and storing
+ * in superblock.
+ */
+ struct work_struct del_work; /* used for delayed sysfs removal */
+
+ struct sysfs_dirent *sysfs_state; /* handle for 'state'
+ * sysfs entry */
+};
+
+struct mddev_s
+{
+ void *private;
+ struct mdk_personality *pers;
+ dev_t unit;
+ int md_minor;
+ struct list_head disks;
+ unsigned long flags;
+#define MD_CHANGE_DEVS 0 /* Some device status has changed */
+#define MD_CHANGE_CLEAN 1 /* transition to or from 'clean' */
+#define MD_CHANGE_PENDING 2 /* superblock update in progress */
+
+ int suspended;
+ atomic_t active_io;
+ int ro;
+
+ struct gendisk *gendisk;
+
+ struct kobject kobj;
+ int hold_active;
+#define UNTIL_IOCTL 1
+#define UNTIL_STOP 2
+
+ /* Superblock information */
+ int major_version,
+ minor_version,
+ patch_version;
+ int persistent;
+ int external; /* metadata is
+ * managed externally */
+ char metadata_type[17]; /* externally set*/
+ int chunk_size;
+ time_t ctime, utime;
+ int level, layout;
+ char clevel[16];
+ int raid_disks;
+ int max_disks;
+ sector_t dev_sectors; /* used size of
+ * component devices */
+ sector_t array_sectors; /* exported array size */
+ int external_size; /* size managed
+ * externally */
+ __u64 events;
+
+ char uuid[16];
+
+ /* If the array is being reshaped, we need to record the
+ * new shape and an indication of where we are up to.
+ * This is written to the superblock.
+ * If reshape_position is MaxSector, then no reshape is happening (yet).
+ */
+ sector_t reshape_position;
+ int delta_disks, new_level, new_layout, new_chunk;
+
+ struct mdk_thread_s *thread; /* management thread */
+ struct mdk_thread_s *sync_thread; /* doing resync or reconstruct */
+ sector_t curr_resync; /* last block scheduled */
+ /* As resync requests can complete out of order, we cannot easily track
+ * how much resync has been completed. So we occasionally pause until
+ * everything completes, then set curr_resync_completed to curr_resync.
+ * As such it may be well behind the real resync mark, but it is a value
+ * we are certain of.
+ */
+ sector_t curr_resync_completed;
+ unsigned long resync_mark; /* a recent timestamp */
+ sector_t resync_mark_cnt;/* blocks written at resync_mark */
+ sector_t curr_mark_cnt; /* blocks scheduled now */
+
+ sector_t resync_max_sectors; /* may be set by personality */
+
+ sector_t resync_mismatches; /* count of sectors where
+ * parity/replica mismatch found
+ */
+
+ /* allow user-space to request suspension of IO to regions of the array */
+ sector_t suspend_lo;
+ sector_t suspend_hi;
+ /* if zero, use the system-wide default */
+ int sync_speed_min;
+ int sync_speed_max;
+
+ /* resync even though the same disks are shared among md-devices */
+ int parallel_resync;
+
+ int ok_start_degraded;
+ /* recovery/resync flags
+ * NEEDED: we might need to start a resync/recover
+ * RUNNING: a thread is running, or about to be started
+ * SYNC: actually doing a resync, not a recovery
+ * RECOVER: doing recovery, or need to try it.
+ * INTR: resync needs to be aborted for some reason
+ * DONE: thread is done and is waiting to be reaped
+ * REQUEST: user-space has requested a sync (used with SYNC)
+ * CHECK: user-space request for for check-only, no repair
+ * RESHAPE: A reshape is happening
+ *
+ * If neither SYNC or RESHAPE are set, then it is a recovery.
+ */
+#define MD_RECOVERY_RUNNING 0
+#define MD_RECOVERY_SYNC 1
+#define MD_RECOVERY_RECOVER 2
+#define MD_RECOVERY_INTR 3
+#define MD_RECOVERY_DONE 4
+#define MD_RECOVERY_NEEDED 5
+#define MD_RECOVERY_REQUESTED 6
+#define MD_RECOVERY_CHECK 7
+#define MD_RECOVERY_RESHAPE 8
+#define MD_RECOVERY_FROZEN 9
+
+ unsigned long recovery;
+ int recovery_disabled; /* if we detect that recovery
+ * will always fail, set this
+ * so we don't loop trying */
+
+ int in_sync; /* know to not need resync */
+ struct mutex reconfig_mutex;
+ atomic_t active; /* general refcount */
+ atomic_t openers; /* number of active opens */
+
+ int changed; /* true if we might need to reread partition info */
+ int degraded; /* whether md should consider
+ * adding a spare
+ */
+ int barriers_work; /* initialised to true, cleared as soon
+ * as a barrier request to slave
+ * fails. Only supported
+ */
+ struct bio *biolist; /* bios that need to be retried
+ * because BIO_RW_BARRIER is not supported
+ */
+
+ atomic_t recovery_active; /* blocks scheduled, but not written */
+ wait_queue_head_t recovery_wait;
+ sector_t recovery_cp;
+ sector_t resync_min; /* user requested sync
+ * starts here */
+ sector_t resync_max; /* resync should pause
+ * when it gets here */
+
+ struct sysfs_dirent *sysfs_state; /* handle for 'array_state'
+ * file in sysfs.
+ */
+ struct sysfs_dirent *sysfs_action; /* handle for 'sync_action' */
+
+ struct work_struct del_work; /* used for delayed sysfs removal */
+
+ spinlock_t write_lock;
+ wait_queue_head_t sb_wait; /* for waiting on superblock updates */
+ atomic_t pending_writes; /* number of active superblock writes */
+
+ unsigned int safemode; /* if set, update "clean" superblock
+ * when no writes pending.
+ */
+ unsigned int safemode_delay;
+ struct timer_list safemode_timer;
+ atomic_t writes_pending;
+ struct request_queue *queue; /* for plugging ... */
+
+ atomic_t write_behind; /* outstanding async IO */
+ unsigned int max_write_behind; /* 0 = sync */
+
+ struct bitmap *bitmap; /* the bitmap for the device */
+ struct file *bitmap_file; /* the bitmap file */
+ long bitmap_offset; /* offset from superblock of
+ * start of bitmap. May be
+ * negative, but not '0'
+ */
+ long default_bitmap_offset; /* this is the offset to use when
+ * hot-adding a bitmap. It should
+ * eventually be settable by sysfs.
+ */
+
+ struct list_head all_mddevs;
+};
+
+
+static inline void rdev_dec_pending(mdk_rdev_t *rdev, mddev_t *mddev)
+{
+ int faulty = test_bit(Faulty, &rdev->flags);
+ if (atomic_dec_and_test(&rdev->nr_pending) && faulty)
+ set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
+}
+
+static inline void md_sync_acct(struct block_device *bdev, unsigned long nr_sectors)
+{
+ atomic_add(nr_sectors, &bdev->bd_contains->bd_disk->sync_io);
+}
+
+struct mdk_personality
+{
+ char *name;
+ int level;
+ struct list_head list;
+ struct module *owner;
+ int (*make_request)(struct request_queue *q, struct bio *bio);
+ int (*run)(mddev_t *mddev);
+ int (*stop)(mddev_t *mddev);
+ void (*status)(struct seq_file *seq, mddev_t *mddev);
+ /* error_handler must set ->faulty and clear ->in_sync
+ * if appropriate, and should abort recovery if needed
+ */
+ void (*error_handler)(mddev_t *mddev, mdk_rdev_t *rdev);
+ int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev);
+ int (*hot_remove_disk) (mddev_t *mddev, int number);
+ int (*spare_active) (mddev_t *mddev);
+ sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
+ int (*resize) (mddev_t *mddev, sector_t sectors);
+ sector_t (*size) (mddev_t *mddev, sector_t sectors, int raid_disks);
+ int (*check_reshape) (mddev_t *mddev);
+ int (*start_reshape) (mddev_t *mddev);
+ void (*finish_reshape) (mddev_t *mddev);
+ int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
+ /* quiesce moves between quiescence states
+ * 0 - fully active
+ * 1 - no new requests allowed
+ * others - reserved
+ */
+ void (*quiesce) (mddev_t *mddev, int state);
+ /* takeover is used to transition an array from one
+ * personality to another. The new personality must be able
+ * to handle the data in the current layout.
+ * e.g. 2drive raid1 -> 2drive raid5
+ * ndrive raid5 -> degraded n+1drive raid6 with special layout
+ * If the takeover succeeds, a new 'private' structure is returned.
+ * This needs to be installed and then ->run used to activate the
+ * array.
+ */
+ void *(*takeover) (mddev_t *mddev);
+};
+
+
+struct md_sysfs_entry {
+ struct attribute attr;
+ ssize_t (*show)(mddev_t *, char *);
+ ssize_t (*store)(mddev_t *, const char *, size_t);
+};
+
+
+static inline char * mdname (mddev_t * mddev)
+{
+ return mddev->gendisk ? mddev->gendisk->disk_name : "mdX";
+}
+
+/*
+ * iterates through some rdev ringlist. It's safe to remove the
+ * current 'rdev'. Dont touch 'tmp' though.
+ */
+#define rdev_for_each_list(rdev, tmp, head) \
+ list_for_each_entry_safe(rdev, tmp, head, same_set)
+
+/*
+ * iterates through the 'same array disks' ringlist
+ */
+#define rdev_for_each(rdev, tmp, mddev) \
+ list_for_each_entry_safe(rdev, tmp, &((mddev)->disks), same_set)
+
+#define rdev_for_each_rcu(rdev, mddev) \
+ list_for_each_entry_rcu(rdev, &((mddev)->disks), same_set)
+
+typedef struct mdk_thread_s {
+ void (*run) (mddev_t *mddev);
+ mddev_t *mddev;
+ wait_queue_head_t wqueue;
+ unsigned long flags;
+ struct task_struct *tsk;
+ unsigned long timeout;
+} mdk_thread_t;
+
+#define THREAD_WAKEUP 0
+
+#define __wait_event_lock_irq(wq, condition, lock, cmd) \
+do { \
+ wait_queue_t __wait; \
+ init_waitqueue_entry(&__wait, current); \
+ \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ set_current_state(TASK_UNINTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ spin_unlock_irq(&lock); \
+ cmd; \
+ schedule(); \
+ spin_lock_irq(&lock); \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event_lock_irq(wq, condition, lock, cmd) \
+do { \
+ if (condition) \
+ break; \
+ __wait_event_lock_irq(wq, condition, lock, cmd); \
+} while (0)
+
+static inline void safe_put_page(struct page *p)
+{
+ if (p) put_page(p);
+}
+
+#endif /* CONFIG_BLOCK */
+#endif
+
+
+extern int register_md_personality(struct mdk_personality *p);
+extern int unregister_md_personality(struct mdk_personality *p);
+extern mdk_thread_t * md_register_thread(void (*run) (mddev_t *mddev),
+ mddev_t *mddev, const char *name);
+extern void md_unregister_thread(mdk_thread_t *thread);
+extern void md_wakeup_thread(mdk_thread_t *thread);
+extern void md_check_recovery(mddev_t *mddev);
+extern void md_write_start(mddev_t *mddev, struct bio *bi);
+extern void md_write_end(mddev_t *mddev);
+extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
+extern void md_error(mddev_t *mddev, mdk_rdev_t *rdev);
+
+extern void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
+ sector_t sector, int size, struct page *page);
+extern void md_super_wait(mddev_t *mddev);
+extern int sync_page_io(struct block_device *bdev, sector_t sector, int size,
+ struct page *page, int rw);
+extern void md_do_sync(mddev_t *mddev);
+extern void md_new_event(mddev_t *mddev);
+extern int md_allow_write(mddev_t *mddev);
+extern void md_wait_for_blocked_rdev(mdk_rdev_t *rdev, mddev_t *mddev);
+extern void md_set_array_sectors(mddev_t *mddev, sector_t array_sectors);
diff --git a/drivers/md/mktables.c b/drivers/md/mktables.c
index b61d5767aae..3b1500843bb 100644
--- a/drivers/md/mktables.c
+++ b/drivers/md/mktables.c
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
uint8_t v;
uint8_t exptbl[256], invtbl[256];
- printf("#include \"raid6.h\"\n");
+ printf("#include <linux/raid/pq.h>\n");
/* Compute multiplication table */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -76,6 +76,9 @@ int main(int argc, char *argv[])
printf("\t},\n");
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfmul);\n");
+ printf("#endif\n");
/* Compute power-of-2 table (exponent) */
v = 1;
@@ -92,6 +95,9 @@ int main(int argc, char *argv[])
}
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfexp);\n");
+ printf("#endif\n");
/* Compute inverse table x^-1 == x^254 */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -104,6 +110,9 @@ int main(int argc, char *argv[])
}
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfinv);\n");
+ printf("#endif\n");
/* Compute inv(2^x + 1) (exponent-xor-inverse) table */
printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -115,6 +124,9 @@ int main(int argc, char *argv[])
(j == 7) ? '\n' : ' ');
}
printf("};\n");
+ printf("#ifdef __KERNEL__\n");
+ printf("EXPORT_SYMBOL(raid6_gfexi);\n");
+ printf("#endif\n");
return 0;
}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index f6d08f24167..41ced0cbe82 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -19,7 +19,11 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/multipath.h>
+#include <linux/blkdev.h>
+#include <linux/raid/md_u.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "multipath.h"
#define MAX_WORK_PER_DISK 128
@@ -402,6 +406,14 @@ static void multipathd (mddev_t *mddev)
spin_unlock_irqrestore(&conf->device_lock, flags);
}
+static sector_t multipath_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ return mddev->dev_sectors;
+}
+
static int multipath_run (mddev_t *mddev)
{
multipath_conf_t *conf;
@@ -498,7 +510,7 @@ static int multipath_run (mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, multipath_size(mddev, 0, 0));
mddev->queue->unplug_fn = multipath_unplug;
mddev->queue->backing_dev_info.congested_fn = multipath_congested;
@@ -543,6 +555,7 @@ static struct mdk_personality multipath_personality =
.error_handler = multipath_error,
.hot_add_disk = multipath_add_disk,
.hot_remove_disk= multipath_remove_disk,
+ .size = multipath_size,
};
static int __init multipath_init (void)
diff --git a/drivers/md/multipath.h b/drivers/md/multipath.h
new file mode 100644
index 00000000000..6fa70b400cd
--- /dev/null
+++ b/drivers/md/multipath.h
@@ -0,0 +1,40 @@
+#ifndef _MULTIPATH_H
+#define _MULTIPATH_H
+
+struct multipath_info {
+ mdk_rdev_t *rdev;
+};
+
+struct multipath_private_data {
+ mddev_t *mddev;
+ struct multipath_info *multipaths;
+ int raid_disks;
+ int working_disks;
+ spinlock_t device_lock;
+ struct list_head retry_list;
+
+ mempool_t *pool;
+};
+
+typedef struct multipath_private_data multipath_conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((multipath_conf_t *) mddev->private)
+
+/*
+ * this is our 'private' 'collective' MULTIPATH buffer head.
+ * it contains information about what kind of IO operations were started
+ * for this MULTIPATH operation, and about their status:
+ */
+
+struct multipath_bh {
+ mddev_t *mddev;
+ struct bio *master_bio;
+ struct bio bio;
+ int path;
+ struct list_head retry_list;
+};
+#endif
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index c605ba80558..c08d7559be5 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -18,7 +18,10 @@
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/raid/raid0.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid0.h"
static void raid0_unplug(struct request_queue *q)
{
@@ -73,16 +76,15 @@ static int create_strip_zones (mddev_t *mddev)
list_for_each_entry(rdev2, &mddev->disks, same_set) {
printk(KERN_INFO "raid0: comparing %s(%llu)",
bdevname(rdev1->bdev,b),
- (unsigned long long)rdev1->size);
+ (unsigned long long)rdev1->sectors);
printk(KERN_INFO " with %s(%llu)\n",
bdevname(rdev2->bdev,b),
- (unsigned long long)rdev2->size);
+ (unsigned long long)rdev2->sectors);
if (rdev2 == rdev1) {
printk(KERN_INFO "raid0: END\n");
break;
}
- if (rdev2->size == rdev1->size)
- {
+ if (rdev2->sectors == rdev1->sectors) {
/*
* Not unique, don't count it as a new
* group
@@ -145,7 +147,7 @@ static int create_strip_zones (mddev_t *mddev)
mddev->queue->max_sectors > (PAGE_SIZE>>9))
blk_queue_max_sectors(mddev->queue, PAGE_SIZE>>9);
- if (!smallest || (rdev1->size <smallest->size))
+ if (!smallest || (rdev1->sectors < smallest->sectors))
smallest = rdev1;
cnt++;
}
@@ -155,10 +157,10 @@ static int create_strip_zones (mddev_t *mddev)
goto abort;
}
zone->nb_dev = cnt;
- zone->sectors = smallest->size * cnt * 2;
+ zone->sectors = smallest->sectors * cnt;
zone->zone_start = 0;
- current_start = smallest->size * 2;
+ current_start = smallest->sectors;
curr_zone_start = zone->sectors;
/* now do the other zones */
@@ -177,29 +179,29 @@ static int create_strip_zones (mddev_t *mddev)
rdev = conf->strip_zone[0].dev[j];
printk(KERN_INFO "raid0: checking %s ...",
bdevname(rdev->bdev, b));
- if (rdev->size > current_start / 2) {
- printk(KERN_INFO " contained as device %d\n",
- c);
- zone->dev[c] = rdev;
- c++;
- if (!smallest || (rdev->size <smallest->size)) {
- smallest = rdev;
- printk(KERN_INFO " (%llu) is smallest!.\n",
- (unsigned long long)rdev->size);
- }
- } else
+ if (rdev->sectors <= current_start) {
printk(KERN_INFO " nope.\n");
+ continue;
+ }
+ printk(KERN_INFO " contained as device %d\n", c);
+ zone->dev[c] = rdev;
+ c++;
+ if (!smallest || rdev->sectors < smallest->sectors) {
+ smallest = rdev;
+ printk(KERN_INFO " (%llu) is smallest!.\n",
+ (unsigned long long)rdev->sectors);
+ }
}
zone->nb_dev = c;
- zone->sectors = (smallest->size * 2 - current_start) * c;
+ zone->sectors = (smallest->sectors - current_start) * c;
printk(KERN_INFO "raid0: zone->nb_dev: %d, sectors: %llu\n",
zone->nb_dev, (unsigned long long)zone->sectors);
zone->zone_start = curr_zone_start;
curr_zone_start += zone->sectors;
- current_start = smallest->size * 2;
+ current_start = smallest->sectors;
printk(KERN_INFO "raid0: current zone start: %llu\n",
(unsigned long long)current_start);
}
@@ -261,12 +263,25 @@ static int raid0_mergeable_bvec(struct request_queue *q,
return max;
}
+static sector_t raid0_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ sector_t array_sectors = 0;
+ mdk_rdev_t *rdev;
+
+ WARN_ONCE(sectors || raid_disks,
+ "%s does not support generic reshape\n", __func__);
+
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ array_sectors += rdev->sectors;
+
+ return array_sectors;
+}
+
static int raid0_run (mddev_t *mddev)
{
unsigned cur=0, i=0, nb_zone;
s64 sectors;
raid0_conf_t *conf;
- mdk_rdev_t *rdev;
if (mddev->chunk_size == 0) {
printk(KERN_ERR "md/raid0: non-zero chunk size required.\n");
@@ -291,16 +306,14 @@ static int raid0_run (mddev_t *mddev)
goto out_free_conf;
/* calculate array device size */
- mddev->array_sectors = 0;
- list_for_each_entry(rdev, &mddev->disks, same_set)
- mddev->array_sectors += rdev->size * 2;
+ md_set_array_sectors(mddev, raid0_size(mddev, 0, 0));
printk(KERN_INFO "raid0 : md_size is %llu sectors.\n",
(unsigned long long)mddev->array_sectors);
printk(KERN_INFO "raid0 : conf->spacing is %llu sectors.\n",
(unsigned long long)conf->spacing);
{
- sector_t s = mddev->array_sectors;
+ sector_t s = raid0_size(mddev, 0, 0);
sector_t space = conf->spacing;
int round;
conf->sector_shift = 0;
@@ -509,6 +522,7 @@ static struct mdk_personality raid0_personality=
.run = raid0_run,
.stop = raid0_stop,
.status = raid0_status,
+ .size = raid0_size,
};
static int __init raid0_init (void)
diff --git a/drivers/md/raid0.h b/drivers/md/raid0.h
new file mode 100644
index 00000000000..824b12eb1d4
--- /dev/null
+++ b/drivers/md/raid0.h
@@ -0,0 +1,28 @@
+#ifndef _RAID0_H
+#define _RAID0_H
+
+struct strip_zone
+{
+ sector_t zone_start; /* Zone offset in md_dev (in sectors) */
+ sector_t dev_start; /* Zone offset in real dev (in sectors) */
+ sector_t sectors; /* Zone size in sectors */
+ int nb_dev; /* # of devices attached to the zone */
+ mdk_rdev_t **dev; /* Devices attached to the zone */
+};
+
+struct raid0_private_data
+{
+ struct strip_zone **hash_table; /* Table of indexes into strip_zone */
+ struct strip_zone *strip_zone;
+ mdk_rdev_t **devlist; /* lists of rdevs, pointed to by strip_zone->dev */
+ int nr_strip_zones;
+
+ sector_t spacing;
+ int sector_shift; /* shift this before divide by spacing */
+};
+
+typedef struct raid0_private_data raid0_conf_t;
+
+#define mddev_to_conf(mddev) ((raid0_conf_t *) mddev->private)
+
+#endif
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index e2466425d9c..274b491a11c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -31,10 +31,13 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "dm-bio-list.h"
#include <linux/delay.h>
-#include <linux/raid/raid1.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid1.h"
+#include "bitmap.h"
#define DEBUG 0
#if DEBUG
@@ -120,6 +123,7 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
goto out_free_pages;
bio->bi_io_vec[i].bv_page = page;
+ bio->bi_vcnt = i+1;
}
}
/* If not user-requests, copy the page pointers to all bios */
@@ -135,9 +139,9 @@ static void * r1buf_pool_alloc(gfp_t gfp_flags, void *data)
return r1_bio;
out_free_pages:
- for (i=0; i < RESYNC_PAGES ; i++)
- for (j=0 ; j < pi->raid_disks; j++)
- safe_put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
+ for (j=0 ; j < pi->raid_disks; j++)
+ for (i=0; i < r1_bio->bios[j]->bi_vcnt ; i++)
+ put_page(r1_bio->bios[j]->bi_io_vec[i].bv_page);
j = -1;
out_free_bio:
while ( ++j < pi->raid_disks )
@@ -582,7 +586,7 @@ static int raid1_congested(void *data, int bits)
/* Note the '|| 1' - when read_balance prefers
* non-congested targets, it can be removed
*/
- if ((bits & (1<<BDI_write_congested)) || 1)
+ if ((bits & (1<<BDI_async_congested)) || 1)
ret |= bdi_congested(&q->backing_dev_info, bits);
else
ret &= bdi_congested(&q->backing_dev_info, bits);
@@ -1723,7 +1727,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return 0;
}
- max_sector = mddev->size << 1;
+ max_sector = mddev->dev_sectors;
if (sector_nr >= max_sector) {
/* If we aborted, we need to abort the
* sync on the 'current' bitmap chunk (there will
@@ -1919,6 +1923,14 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return nr_sectors;
}
+static sector_t raid1_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ if (sectors)
+ return sectors;
+
+ return mddev->dev_sectors;
+}
+
static int run(mddev_t *mddev)
{
conf_t *conf;
@@ -2048,7 +2060,7 @@ static int run(mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = mddev->size * 2;
+ md_set_array_sectors(mddev, raid1_size(mddev, 0, 0));
mddev->queue->unplug_fn = raid1_unplug;
mddev->queue->backing_dev_info.congested_fn = raid1_congested;
@@ -2089,6 +2101,9 @@ static int stop(mddev_t *mddev)
/* need to kick something here to make sure I/O goes? */
}
+ raise_barrier(conf);
+ lower_barrier(conf);
+
md_unregister_thread(mddev->thread);
mddev->thread = NULL;
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2110,15 +2125,17 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems
* worth it.
*/
- mddev->array_sectors = sectors;
+ md_set_array_sectors(mddev, raid1_size(mddev, sectors, 0));
+ if (mddev->array_sectors > raid1_size(mddev, sectors, 0))
+ return -EINVAL;
set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1;
- if (mddev->array_sectors / 2 > mddev->size &&
+ if (sectors > mddev->dev_sectors &&
mddev->recovery_cp == MaxSector) {
- mddev->recovery_cp = mddev->size << 1;
+ mddev->recovery_cp = mddev->dev_sectors;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
- mddev->size = mddev->array_sectors / 2;
+ mddev->dev_sectors = sectors;
mddev->resync_max_sectors = sectors;
return 0;
}
@@ -2264,6 +2281,7 @@ static struct mdk_personality raid1_personality =
.spare_active = raid1_spare_active,
.sync_request = sync_request,
.resize = raid1_resize,
+ .size = raid1_size,
.check_reshape = raid1_reshape,
.quiesce = raid1_quiesce,
};
diff --git a/drivers/md/raid1.h b/drivers/md/raid1.h
new file mode 100644
index 00000000000..1620eea3d57
--- /dev/null
+++ b/drivers/md/raid1.h
@@ -0,0 +1,132 @@
+#ifndef _RAID1_H
+#define _RAID1_H
+
+typedef struct mirror_info mirror_info_t;
+
+struct mirror_info {
+ mdk_rdev_t *rdev;
+ sector_t head_position;
+};
+
+/*
+ * memory pools need a pointer to the mddev, so they can force an unplug
+ * when memory is tight, and a count of the number of drives that the
+ * pool was allocated for, so they know how much to allocate and free.
+ * mddev->raid_disks cannot be used, as it can change while a pool is active
+ * These two datums are stored in a kmalloced struct.
+ */
+
+struct pool_info {
+ mddev_t *mddev;
+ int raid_disks;
+};
+
+
+typedef struct r1bio_s r1bio_t;
+
+struct r1_private_data_s {
+ mddev_t *mddev;
+ mirror_info_t *mirrors;
+ int raid_disks;
+ int last_used;
+ sector_t next_seq_sect;
+ spinlock_t device_lock;
+
+ struct list_head retry_list;
+ /* queue pending writes and submit them on unplug */
+ struct bio_list pending_bio_list;
+ /* queue of writes that have been unplugged */
+ struct bio_list flushing_bio_list;
+
+ /* for use when syncing mirrors: */
+
+ spinlock_t resync_lock;
+ int nr_pending;
+ int nr_waiting;
+ int nr_queued;
+ int barrier;
+ sector_t next_resync;
+ int fullsync; /* set to 1 if a full sync is needed,
+ * (fresh device added).
+ * Cleared when a sync completes.
+ */
+
+ wait_queue_head_t wait_barrier;
+
+ struct pool_info *poolinfo;
+
+ struct page *tmppage;
+
+ mempool_t *r1bio_pool;
+ mempool_t *r1buf_pool;
+};
+
+typedef struct r1_private_data_s conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
+
+/*
+ * this is our 'private' RAID1 bio.
+ *
+ * it contains information about what kind of IO operations were started
+ * for this RAID1 operation, and about their status:
+ */
+
+struct r1bio_s {
+ atomic_t remaining; /* 'have we finished' count,
+ * used from IRQ handlers
+ */
+ atomic_t behind_remaining; /* number of write-behind ios remaining
+ * in this BehindIO request
+ */
+ sector_t sector;
+ int sectors;
+ unsigned long state;
+ mddev_t *mddev;
+ /*
+ * original bio going to /dev/mdx
+ */
+ struct bio *master_bio;
+ /*
+ * if the IO is in READ direction, then this is where we read
+ */
+ int read_disk;
+
+ struct list_head retry_list;
+ struct bitmap_update *bitmap_update;
+ /*
+ * if the IO is in WRITE direction, then multiple bios are used.
+ * We choose the number when they are allocated.
+ */
+ struct bio *bios[0];
+ /* DO NOT PUT ANY NEW FIELDS HERE - bios array is contiguously alloced*/
+};
+
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error. To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
+/* bits for r1bio.state */
+#define R1BIO_Uptodate 0
+#define R1BIO_IsSync 1
+#define R1BIO_Degraded 2
+#define R1BIO_BehindIO 3
+#define R1BIO_Barrier 4
+#define R1BIO_BarrierRetry 5
+/* For write-behind requests, we call bi_end_io when
+ * the last non-write-behind device completes, providing
+ * any write was successful. Otherwise we call when
+ * any write-behind write succeeds, otherwise we call
+ * with failure when last write completes (and all failed).
+ * Record that bi_end_io was called with this flag...
+ */
+#define R1BIO_Returned 6
+
+#endif
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 7301631abe0..e293d92641a 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -18,10 +18,13 @@
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include "dm-bio-list.h"
#include <linux/delay.h>
-#include <linux/raid/raid10.h>
-#include <linux/raid/bitmap.h>
+#include <linux/blkdev.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "dm-bio-list.h"
+#include "raid10.h"
+#include "bitmap.h"
/*
* RAID10 provides a combination of RAID0 and RAID1 functionality.
@@ -1695,7 +1698,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
return 0;
skipped:
- max_sector = mddev->size << 1;
+ max_sector = mddev->dev_sectors;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_sector = mddev->resync_max_sectors;
if (sector_nr >= max_sector) {
@@ -2020,6 +2023,25 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
goto skipped;
}
+static sector_t
+raid10_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ sector_t size;
+ conf_t *conf = mddev_to_conf(mddev);
+
+ if (!raid_disks)
+ raid_disks = mddev->raid_disks;
+ if (!sectors)
+ sectors = mddev->dev_sectors;
+
+ size = sectors >> conf->chunk_shift;
+ sector_div(size, conf->far_copies);
+ size = size * raid_disks;
+ sector_div(size, conf->near_copies);
+
+ return size << conf->chunk_shift;
+}
+
static int run(mddev_t *mddev)
{
conf_t *conf;
@@ -2076,7 +2098,7 @@ static int run(mddev_t *mddev)
conf->far_offset = fo;
conf->chunk_mask = (sector_t)(mddev->chunk_size>>9)-1;
conf->chunk_shift = ffz(~mddev->chunk_size) - 9;
- size = mddev->size >> (conf->chunk_shift-1);
+ size = mddev->dev_sectors >> conf->chunk_shift;
sector_div(size, fc);
size = size * conf->raid_disks;
sector_div(size, nc);
@@ -2089,7 +2111,7 @@ static int run(mddev_t *mddev)
*/
stride += conf->raid_disks - 1;
sector_div(stride, conf->raid_disks);
- mddev->size = stride << (conf->chunk_shift-1);
+ mddev->dev_sectors = stride << conf->chunk_shift;
if (fo)
stride = 1;
@@ -2171,8 +2193,8 @@ static int run(mddev_t *mddev)
/*
* Ok, everything is just fine now
*/
- mddev->array_sectors = size << conf->chunk_shift;
- mddev->resync_max_sectors = size << conf->chunk_shift;
+ md_set_array_sectors(mddev, raid10_size(mddev, 0, 0));
+ mddev->resync_max_sectors = raid10_size(mddev, 0, 0);
mddev->queue->unplug_fn = raid10_unplug;
mddev->queue->backing_dev_info.congested_fn = raid10_congested;
@@ -2208,6 +2230,9 @@ static int stop(mddev_t *mddev)
{
conf_t *conf = mddev_to_conf(mddev);
+ raise_barrier(conf, 0);
+ lower_barrier(conf);
+
md_unregister_thread(mddev->thread);
mddev->thread = NULL;
blk_sync_queue(mddev->queue); /* the unplug fn references 'conf'*/
@@ -2255,6 +2280,7 @@ static struct mdk_personality raid10_personality =
.spare_active = raid10_spare_active,
.sync_request = sync_request,
.quiesce = raid10_quiesce,
+ .size = raid10_size,
};
static int __init raid_init(void)
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h
new file mode 100644
index 00000000000..244dbe507a5
--- /dev/null
+++ b/drivers/md/raid10.h
@@ -0,0 +1,121 @@
+#ifndef _RAID10_H
+#define _RAID10_H
+
+typedef struct mirror_info mirror_info_t;
+
+struct mirror_info {
+ mdk_rdev_t *rdev;
+ sector_t head_position;
+};
+
+typedef struct r10bio_s r10bio_t;
+
+struct r10_private_data_s {
+ mddev_t *mddev;
+ mirror_info_t *mirrors;
+ int raid_disks;
+ spinlock_t device_lock;
+
+ /* geometry */
+ int near_copies; /* number of copies layed out raid0 style */
+ int far_copies; /* number of copies layed out
+ * at large strides across drives
+ */
+ int far_offset; /* far_copies are offset by 1 stripe
+ * instead of many
+ */
+ int copies; /* near_copies * far_copies.
+ * must be <= raid_disks
+ */
+ sector_t stride; /* distance between far copies.
+ * This is size / far_copies unless
+ * far_offset, in which case it is
+ * 1 stripe.
+ */
+
+ int chunk_shift; /* shift from chunks to sectors */
+ sector_t chunk_mask;
+
+ struct list_head retry_list;
+ /* queue pending writes and submit them on unplug */
+ struct bio_list pending_bio_list;
+
+
+ spinlock_t resync_lock;
+ int nr_pending;
+ int nr_waiting;
+ int nr_queued;
+ int barrier;
+ sector_t next_resync;
+ int fullsync; /* set to 1 if a full sync is needed,
+ * (fresh device added).
+ * Cleared when a sync completes.
+ */
+
+ wait_queue_head_t wait_barrier;
+
+ mempool_t *r10bio_pool;
+ mempool_t *r10buf_pool;
+ struct page *tmppage;
+};
+
+typedef struct r10_private_data_s conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((conf_t *) mddev->private)
+
+/*
+ * this is our 'private' RAID10 bio.
+ *
+ * it contains information about what kind of IO operations were started
+ * for this RAID10 operation, and about their status:
+ */
+
+struct r10bio_s {
+ atomic_t remaining; /* 'have we finished' count,
+ * used from IRQ handlers
+ */
+ sector_t sector; /* virtual sector number */
+ int sectors;
+ unsigned long state;
+ mddev_t *mddev;
+ /*
+ * original bio going to /dev/mdx
+ */
+ struct bio *master_bio;
+ /*
+ * if the IO is in READ direction, then this is where we read
+ */
+ int read_slot;
+
+ struct list_head retry_list;
+ /*
+ * if the IO is in WRITE direction, then multiple bios are used,
+ * one for each copy.
+ * When resyncing we also use one for each copy.
+ * When reconstructing, we use 2 bios, one for read, one for write.
+ * We choose the number when they are allocated.
+ */
+ struct {
+ struct bio *bio;
+ sector_t addr;
+ int devnum;
+ } devs[0];
+};
+
+/* when we get a read error on a read-only array, we redirect to another
+ * device without failing the first device, or trying to over-write to
+ * correct the read error. To keep track of bad blocks on a per-bio
+ * level, we store IO_BLOCKED in the appropriate 'bios' pointer
+ */
+#define IO_BLOCKED ((struct bio*)1)
+
+/* bits for r10bio.state */
+#define R10BIO_Uptodate 0
+#define R10BIO_IsSync 1
+#define R10BIO_IsRecover 2
+#define R10BIO_Degraded 3
+#endif
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a5ba080d303..3bbc6d64704 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -43,11 +43,14 @@
* miss any bits.
*/
+#include <linux/blkdev.h>
#include <linux/kthread.h>
-#include "raid6.h"
-
-#include <linux/raid/bitmap.h>
+#include <linux/raid/pq.h>
#include <linux/async_tx.h>
+#include <linux/seq_file.h>
+#include "md.h"
+#include "raid5.h"
+#include "bitmap.h"
/*
* Stripe cache
@@ -91,11 +94,6 @@
#define printk_rl(args...) ((void) (printk_ratelimit() && printk(args)))
-#if !RAID6_USE_EMPTY_ZERO_PAGE
-/* In .bss so it's zeroed */
-const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
-#endif
-
/*
* We maintain a biased count of active stripes in the bottom 16 bits of
* bi_phys_segments, and a count of processed stripes in the upper 16 bits
@@ -130,12 +128,42 @@ static inline void raid5_set_bi_hw_segments(struct bio *bio, unsigned int cnt)
bio->bi_phys_segments = raid5_bi_phys_segments(bio) || (cnt << 16);
}
+/* Find first data disk in a raid6 stripe */
+static inline int raid6_d0(struct stripe_head *sh)
+{
+ if (sh->ddf_layout)
+ /* ddf always start from first device */
+ return 0;
+ /* md starts just after Q block */
+ if (sh->qd_idx == sh->disks - 1)
+ return 0;
+ else
+ return sh->qd_idx + 1;
+}
static inline int raid6_next_disk(int disk, int raid_disks)
{
disk++;
return (disk < raid_disks) ? disk : 0;
}
+/* When walking through the disks in a raid5, starting at raid6_d0,
+ * We need to map each disk to a 'slot', where the data disks are slot
+ * 0 .. raid_disks-3, the parity disk is raid_disks-2 and the Q disk
+ * is raid_disks-1. This help does that mapping.
+ */
+static int raid6_idx_to_slot(int idx, struct stripe_head *sh,
+ int *count, int syndrome_disks)
+{
+ int slot;
+
+ if (idx == sh->pd_idx)
+ return syndrome_disks;
+ if (idx == sh->qd_idx)
+ return syndrome_disks + 1;
+ slot = (*count)++;
+ return slot;
+}
+
static void return_io(struct bio *return_bi)
{
struct bio *bi = return_bi;
@@ -193,6 +221,7 @@ static void __release_stripe(raid5_conf_t *conf, struct stripe_head *sh)
}
}
}
+
static void release_stripe(struct stripe_head *sh)
{
raid5_conf_t *conf = sh->raid_conf;
@@ -270,9 +299,11 @@ static int grow_buffers(struct stripe_head *sh, int num)
return 0;
}
-static void raid5_build_block(struct stripe_head *sh, int i);
+static void raid5_build_block(struct stripe_head *sh, int i, int previous);
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+ struct stripe_head *sh);
-static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int disks)
+static void init_stripe(struct stripe_head *sh, sector_t sector, int previous)
{
raid5_conf_t *conf = sh->raid_conf;
int i;
@@ -287,11 +318,12 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
remove_hash(sh);
+ sh->generation = conf->generation - previous;
+ sh->disks = previous ? conf->previous_raid_disks : conf->raid_disks;
sh->sector = sector;
- sh->pd_idx = pd_idx;
+ stripe_set_idx(sector, conf, previous, sh);
sh->state = 0;
- sh->disks = disks;
for (i = sh->disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
@@ -305,12 +337,13 @@ static void init_stripe(struct stripe_head *sh, sector_t sector, int pd_idx, int
BUG();
}
dev->flags = 0;
- raid5_build_block(sh, i);
+ raid5_build_block(sh, i, previous);
}
insert_hash(conf, sh);
}
-static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, int disks)
+static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector,
+ short generation)
{
struct stripe_head *sh;
struct hlist_node *hn;
@@ -318,7 +351,7 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in
CHECK_DEVLOCK();
pr_debug("__find_stripe, sector %llu\n", (unsigned long long)sector);
hlist_for_each_entry(sh, hn, stripe_hash(conf, sector), hash)
- if (sh->sector == sector && sh->disks == disks)
+ if (sh->sector == sector && sh->generation == generation)
return sh;
pr_debug("__stripe %llu not in cache\n", (unsigned long long)sector);
return NULL;
@@ -327,8 +360,9 @@ static struct stripe_head *__find_stripe(raid5_conf_t *conf, sector_t sector, in
static void unplug_slaves(mddev_t *mddev);
static void raid5_unplug_device(struct request_queue *q);
-static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector, int disks,
- int pd_idx, int noblock)
+static struct stripe_head *
+get_active_stripe(raid5_conf_t *conf, sector_t sector,
+ int previous, int noblock)
{
struct stripe_head *sh;
@@ -340,7 +374,7 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
wait_event_lock_irq(conf->wait_for_stripe,
conf->quiesce == 0,
conf->device_lock, /* nothing */);
- sh = __find_stripe(conf, sector, disks);
+ sh = __find_stripe(conf, sector, conf->generation - previous);
if (!sh) {
if (!conf->inactive_blocked)
sh = get_free_stripe(conf);
@@ -358,10 +392,11 @@ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector
);
conf->inactive_blocked = 0;
} else
- init_stripe(sh, sector, pd_idx, disks);
+ init_stripe(sh, sector, previous);
} else {
if (atomic_read(&sh->count)) {
- BUG_ON(!list_empty(&sh->lru));
+ BUG_ON(!list_empty(&sh->lru)
+ && !test_bit(STRIPE_EXPANDING, &sh->state));
} else {
if (!test_bit(STRIPE_HANDLE, &sh->state))
atomic_inc(&conf->active_stripes);
@@ -895,8 +930,10 @@ static int grow_stripes(raid5_conf_t *conf, int num)
struct kmem_cache *sc;
int devs = conf->raid_disks;
- sprintf(conf->cache_name[0], "raid5-%s", mdname(conf->mddev));
- sprintf(conf->cache_name[1], "raid5-%s-alt", mdname(conf->mddev));
+ sprintf(conf->cache_name[0],
+ "raid%d-%s", conf->level, mdname(conf->mddev));
+ sprintf(conf->cache_name[1],
+ "raid%d-%s-alt", conf->level, mdname(conf->mddev));
conf->active_name = 0;
sc = kmem_cache_create(conf->cache_name[conf->active_name],
sizeof(struct stripe_head)+(devs-1)*sizeof(struct r5dev),
@@ -911,7 +948,6 @@ static int grow_stripes(raid5_conf_t *conf, int num)
return 0;
}
-#ifdef CONFIG_MD_RAID5_RESHAPE
static int resize_stripes(raid5_conf_t *conf, int newsize)
{
/* Make all the stripes able to hold 'newsize' devices.
@@ -1036,7 +1072,6 @@ static int resize_stripes(raid5_conf_t *conf, int newsize)
conf->pool_size = newsize;
return err;
}
-#endif
static int drop_one_stripe(raid5_conf_t *conf)
{
@@ -1066,7 +1101,7 @@ static void shrink_stripes(raid5_conf_t *conf)
static void raid5_end_read_request(struct bio * bi, int error)
{
- struct stripe_head *sh = bi->bi_private;
+ struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1148,7 +1183,7 @@ static void raid5_end_read_request(struct bio * bi, int error)
static void raid5_end_write_request(struct bio *bi, int error)
{
- struct stripe_head *sh = bi->bi_private;
+ struct stripe_head *sh = bi->bi_private;
raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks, i;
int uptodate = test_bit(BIO_UPTODATE, &bi->bi_flags);
@@ -1176,9 +1211,9 @@ static void raid5_end_write_request(struct bio *bi, int error)
}
-static sector_t compute_blocknr(struct stripe_head *sh, int i);
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous);
-static void raid5_build_block(struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i, int previous)
{
struct r5dev *dev = &sh->dev[i];
@@ -1194,7 +1229,7 @@ static void raid5_build_block(struct stripe_head *sh, int i)
dev->req.bi_private = sh;
dev->flags = 0;
- dev->sector = compute_blocknr(sh, i);
+ dev->sector = compute_blocknr(sh, i, previous);
}
static void error(mddev_t *mddev, mdk_rdev_t *rdev)
@@ -1227,15 +1262,23 @@ static void error(mddev_t *mddev, mdk_rdev_t *rdev)
* Input: a 'big' sector number,
* Output: index of the data and parity disk, and the sector # in them.
*/
-static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
- unsigned int data_disks, unsigned int * dd_idx,
- unsigned int * pd_idx, raid5_conf_t *conf)
+static sector_t raid5_compute_sector(raid5_conf_t *conf, sector_t r_sector,
+ int previous, int *dd_idx,
+ struct stripe_head *sh)
{
long stripe;
unsigned long chunk_number;
unsigned int chunk_offset;
+ int pd_idx, qd_idx;
+ int ddf_layout = 0;
sector_t new_sector;
- int sectors_per_chunk = conf->chunk_size >> 9;
+ int algorithm = previous ? conf->prev_algo
+ : conf->algorithm;
+ int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int raid_disks = previous ? conf->previous_raid_disks
+ : conf->raid_disks;
+ int data_disks = raid_disks - conf->max_degraded;
/* First compute the information on this sector */
@@ -1259,68 +1302,170 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
/*
* Select the parity disk based on the user selected algorithm.
*/
+ pd_idx = qd_idx = ~0;
switch(conf->level) {
case 4:
- *pd_idx = data_disks;
+ pd_idx = data_disks;
break;
case 5:
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
+ pd_idx = data_disks - stripe % raid_disks;
+ if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- *pd_idx = stripe % raid_disks;
- if (*dd_idx >= *pd_idx)
+ pd_idx = stripe % raid_disks;
+ if (*dd_idx >= pd_idx)
(*dd_idx)++;
break;
case ALGORITHM_LEFT_SYMMETRIC:
- *pd_idx = data_disks - stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ pd_idx = data_disks - stripe % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- *pd_idx = stripe % raid_disks;
- *dd_idx = (*pd_idx + 1 + *dd_idx) % raid_disks;
+ pd_idx = stripe % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+ break;
+ case ALGORITHM_PARITY_0:
+ pd_idx = 0;
+ (*dd_idx)++;
+ break;
+ case ALGORITHM_PARITY_N:
+ pd_idx = data_disks;
break;
default:
printk(KERN_ERR "raid5: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
case 6:
- /**** FIX THIS ****/
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
- *pd_idx = raid_disks - 1 - (stripe % raid_disks);
- if (*pd_idx == raid_disks-1)
- (*dd_idx)++; /* Q D D D P */
- else if (*dd_idx >= *pd_idx)
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_RIGHT_ASYMMETRIC:
- *pd_idx = stripe % raid_disks;
- if (*pd_idx == raid_disks-1)
- (*dd_idx)++; /* Q D D D P */
- else if (*dd_idx >= *pd_idx)
+ pd_idx = stripe % raid_disks;
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
(*dd_idx) += 2; /* D D P Q D */
break;
case ALGORITHM_LEFT_SYMMETRIC:
- *pd_idx = raid_disks - 1 - (stripe % raid_disks);
- *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = (pd_idx + 1) % raid_disks;
+ *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
break;
case ALGORITHM_RIGHT_SYMMETRIC:
- *pd_idx = stripe % raid_disks;
- *dd_idx = (*pd_idx + 2 + *dd_idx) % raid_disks;
+ pd_idx = stripe % raid_disks;
+ qd_idx = (pd_idx + 1) % raid_disks;
+ *dd_idx = (pd_idx + 2 + *dd_idx) % raid_disks;
+ break;
+
+ case ALGORITHM_PARITY_0:
+ pd_idx = 0;
+ qd_idx = 1;
+ (*dd_idx) += 2;
+ break;
+ case ALGORITHM_PARITY_N:
+ pd_idx = data_disks;
+ qd_idx = data_disks + 1;
break;
+
+ case ALGORITHM_ROTATING_ZERO_RESTART:
+ /* Exactly the same as RIGHT_ASYMMETRIC, but or
+ * of blocks for computing Q is different.
+ */
+ pd_idx = stripe % raid_disks;
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
+ (*dd_idx) += 2; /* D D P Q D */
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_ROTATING_N_RESTART:
+ /* Same a left_asymmetric, by first stripe is
+ * D D D P Q rather than
+ * Q D D D P
+ */
+ pd_idx = raid_disks - 1 - ((stripe + 1) % raid_disks);
+ qd_idx = pd_idx + 1;
+ if (pd_idx == raid_disks-1) {
+ (*dd_idx)++; /* Q D D D P */
+ qd_idx = 0;
+ } else if (*dd_idx >= pd_idx)
+ (*dd_idx) += 2; /* D D P Q D */
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_ROTATING_N_CONTINUE:
+ /* Same as left_symmetric but Q is before P */
+ pd_idx = raid_disks - 1 - (stripe % raid_disks);
+ qd_idx = (pd_idx + raid_disks - 1) % raid_disks;
+ *dd_idx = (pd_idx + 1 + *dd_idx) % raid_disks;
+ ddf_layout = 1;
+ break;
+
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ /* RAID5 left_asymmetric, with Q on last device */
+ pd_idx = data_disks - stripe % (raid_disks-1);
+ if (*dd_idx >= pd_idx)
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ pd_idx = stripe % (raid_disks-1);
+ if (*dd_idx >= pd_idx)
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ pd_idx = data_disks - stripe % (raid_disks-1);
+ *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ pd_idx = stripe % (raid_disks-1);
+ *dd_idx = (pd_idx + 1 + *dd_idx) % (raid_disks-1);
+ qd_idx = raid_disks - 1;
+ break;
+
+ case ALGORITHM_PARITY_0_6:
+ pd_idx = 0;
+ (*dd_idx)++;
+ qd_idx = raid_disks - 1;
+ break;
+
+
default:
printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
}
+ if (sh) {
+ sh->pd_idx = pd_idx;
+ sh->qd_idx = qd_idx;
+ sh->ddf_layout = ddf_layout;
+ }
/*
* Finally, compute the new sector number
*/
@@ -1329,17 +1474,21 @@ static sector_t raid5_compute_sector(sector_t r_sector, unsigned int raid_disks,
}
-static sector_t compute_blocknr(struct stripe_head *sh, int i)
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
{
raid5_conf_t *conf = sh->raid_conf;
int raid_disks = sh->disks;
int data_disks = raid_disks - conf->max_degraded;
sector_t new_sector = sh->sector, check;
- int sectors_per_chunk = conf->chunk_size >> 9;
+ int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int algorithm = previous ? conf->prev_algo
+ : conf->algorithm;
sector_t stripe;
int chunk_offset;
- int chunk_number, dummy1, dummy2, dd_idx = i;
+ int chunk_number, dummy1, dd_idx = i;
sector_t r_sector;
+ struct stripe_head sh2;
chunk_offset = sector_div(new_sector, sectors_per_chunk);
@@ -1351,7 +1500,7 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
switch(conf->level) {
case 4: break;
case 5:
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC:
if (i > sh->pd_idx)
@@ -1363,19 +1512,27 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
i += raid_disks;
i -= (sh->pd_idx + 1);
break;
+ case ALGORITHM_PARITY_0:
+ i -= 1;
+ break;
+ case ALGORITHM_PARITY_N:
+ break;
default:
printk(KERN_ERR "raid5: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
case 6:
- if (i == raid6_next_disk(sh->pd_idx, raid_disks))
+ if (i == sh->qd_idx)
return 0; /* It is the Q disk */
- switch (conf->algorithm) {
+ switch (algorithm) {
case ALGORITHM_LEFT_ASYMMETRIC:
case ALGORITHM_RIGHT_ASYMMETRIC:
- if (sh->pd_idx == raid_disks-1)
- i--; /* Q D D D P */
+ case ALGORITHM_ROTATING_ZERO_RESTART:
+ case ALGORITHM_ROTATING_N_RESTART:
+ if (sh->pd_idx == raid_disks-1)
+ i--; /* Q D D D P */
else if (i > sh->pd_idx)
i -= 2; /* D D P Q D */
break;
@@ -1390,9 +1547,35 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
i -= (sh->pd_idx + 2);
}
break;
+ case ALGORITHM_PARITY_0:
+ i -= 2;
+ break;
+ case ALGORITHM_PARITY_N:
+ break;
+ case ALGORITHM_ROTATING_N_CONTINUE:
+ if (sh->pd_idx == 0)
+ i--; /* P D D D Q */
+ else if (i > sh->pd_idx)
+ i -= 2; /* D D Q P D */
+ break;
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ if (i > sh->pd_idx)
+ i--;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ if (i < sh->pd_idx)
+ i += data_disks + 1;
+ i -= (sh->pd_idx + 1);
+ break;
+ case ALGORITHM_PARITY_0_6:
+ i -= 1;
+ break;
default:
printk(KERN_CRIT "raid6: unsupported algorithm %d\n",
- conf->algorithm);
+ algorithm);
+ BUG();
}
break;
}
@@ -1400,8 +1583,10 @@ static sector_t compute_blocknr(struct stripe_head *sh, int i)
chunk_number = stripe * data_disks + i;
r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
- check = raid5_compute_sector(r_sector, raid_disks, data_disks, &dummy1, &dummy2, conf);
- if (check != sh->sector || dummy1 != dd_idx || dummy2 != sh->pd_idx) {
+ check = raid5_compute_sector(conf, r_sector,
+ previous, &dummy1, &sh2);
+ if (check != sh->sector || dummy1 != dd_idx || sh2.pd_idx != sh->pd_idx
+ || sh2.qd_idx != sh->qd_idx) {
printk(KERN_ERR "compute_blocknr: map not correct\n");
return 0;
}
@@ -1468,14 +1653,16 @@ static void copy_data(int frombio, struct bio *bio,
static void compute_parity6(struct stripe_head *sh, int method)
{
- raid6_conf_t *conf = sh->raid_conf;
- int i, pd_idx = sh->pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+ raid5_conf_t *conf = sh->raid_conf;
+ int i, pd_idx, qd_idx, d0_idx, disks = sh->disks, count;
+ int syndrome_disks = sh->ddf_layout ? disks : (disks - 2);
struct bio *chosen;
/**** FIX THIS: This could be very bad if disks is close to 256 ****/
- void *ptrs[disks];
+ void *ptrs[syndrome_disks+2];
- qd_idx = raid6_next_disk(pd_idx, disks);
- d0_idx = raid6_next_disk(qd_idx, disks);
+ pd_idx = sh->pd_idx;
+ qd_idx = sh->qd_idx;
+ d0_idx = raid6_d0(sh);
pr_debug("compute_parity, stripe %llu, method %d\n",
(unsigned long long)sh->sector, method);
@@ -1513,24 +1700,29 @@ static void compute_parity6(struct stripe_head *sh, int method)
set_bit(R5_UPTODATE, &sh->dev[i].flags);
}
-// switch(method) {
-// case RECONSTRUCT_WRITE:
-// case CHECK_PARITY:
-// case UPDATE_PARITY:
- /* Note that unlike RAID-5, the ordering of the disks matters greatly. */
- /* FIX: Is this ordering of drives even remotely optimal? */
- count = 0;
- i = d0_idx;
- do {
- ptrs[count++] = page_address(sh->dev[i].page);
- if (count <= disks-2 && !test_bit(R5_UPTODATE, &sh->dev[i].flags))
- printk("block %d/%d not uptodate on parity calc\n", i,count);
- i = raid6_next_disk(i, disks);
- } while ( i != d0_idx );
-// break;
-// }
-
- raid6_call.gen_syndrome(disks, STRIPE_SIZE, ptrs);
+ /* Note that unlike RAID-5, the ordering of the disks matters greatly.*/
+
+ for (i = 0; i < disks; i++)
+ ptrs[i] = (void *)raid6_empty_zero_page;
+
+ count = 0;
+ i = d0_idx;
+ do {
+ int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+ ptrs[slot] = page_address(sh->dev[i].page);
+ if (slot < syndrome_disks &&
+ !test_bit(R5_UPTODATE, &sh->dev[i].flags)) {
+ printk(KERN_ERR "block %d/%d not uptodate "
+ "on parity calc\n", i, count);
+ BUG();
+ }
+
+ i = raid6_next_disk(i, disks);
+ } while (i != d0_idx);
+ BUG_ON(count != syndrome_disks);
+
+ raid6_call.gen_syndrome(syndrome_disks+2, STRIPE_SIZE, ptrs);
switch(method) {
case RECONSTRUCT_WRITE:
@@ -1552,8 +1744,7 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
{
int i, count, disks = sh->disks;
void *ptr[MAX_XOR_BLOCKS], *dest, *p;
- int pd_idx = sh->pd_idx;
- int qd_idx = raid6_next_disk(pd_idx, disks);
+ int qd_idx = sh->qd_idx;
pr_debug("compute_block_1, stripe %llu, idx %d\n",
(unsigned long long)sh->sector, dd_idx);
@@ -1589,63 +1780,65 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
static void compute_block_2(struct stripe_head *sh, int dd_idx1, int dd_idx2)
{
int i, count, disks = sh->disks;
- int pd_idx = sh->pd_idx;
- int qd_idx = raid6_next_disk(pd_idx, disks);
- int d0_idx = raid6_next_disk(qd_idx, disks);
- int faila, failb;
+ int syndrome_disks = sh->ddf_layout ? disks : disks-2;
+ int d0_idx = raid6_d0(sh);
+ int faila = -1, failb = -1;
+ /**** FIX THIS: This could be very bad if disks is close to 256 ****/
+ void *ptrs[syndrome_disks+2];
- /* faila and failb are disk numbers relative to d0_idx */
- /* pd_idx become disks-2 and qd_idx become disks-1 */
- faila = (dd_idx1 < d0_idx) ? dd_idx1+(disks-d0_idx) : dd_idx1-d0_idx;
- failb = (dd_idx2 < d0_idx) ? dd_idx2+(disks-d0_idx) : dd_idx2-d0_idx;
+ for (i = 0; i < disks ; i++)
+ ptrs[i] = (void *)raid6_empty_zero_page;
+ count = 0;
+ i = d0_idx;
+ do {
+ int slot = raid6_idx_to_slot(i, sh, &count, syndrome_disks);
+
+ ptrs[slot] = page_address(sh->dev[i].page);
+
+ if (i == dd_idx1)
+ faila = slot;
+ if (i == dd_idx2)
+ failb = slot;
+ i = raid6_next_disk(i, disks);
+ } while (i != d0_idx);
+ BUG_ON(count != syndrome_disks);
BUG_ON(faila == failb);
if ( failb < faila ) { int tmp = faila; faila = failb; failb = tmp; }
pr_debug("compute_block_2, stripe %llu, idx %d,%d (%d,%d)\n",
- (unsigned long long)sh->sector, dd_idx1, dd_idx2, faila, failb);
+ (unsigned long long)sh->sector, dd_idx1, dd_idx2,
+ faila, failb);
- if ( failb == disks-1 ) {
+ if (failb == syndrome_disks+1) {
/* Q disk is one of the missing disks */
- if ( faila == disks-2 ) {
+ if (faila == syndrome_disks) {
/* Missing P+Q, just recompute */
compute_parity6(sh, UPDATE_PARITY);
return;
} else {
/* We're missing D+Q; recompute D from P */
- compute_block_1(sh, (dd_idx1 == qd_idx) ? dd_idx2 : dd_idx1, 0);
+ compute_block_1(sh, ((dd_idx1 == sh->qd_idx) ?
+ dd_idx2 : dd_idx1),
+ 0);
compute_parity6(sh, UPDATE_PARITY); /* Is this necessary? */
return;
}
}
- /* We're missing D+P or D+D; build pointer table */
- {
- /**** FIX THIS: This could be very bad if disks is close to 256 ****/
- void *ptrs[disks];
-
- count = 0;
- i = d0_idx;
- do {
- ptrs[count++] = page_address(sh->dev[i].page);
- i = raid6_next_disk(i, disks);
- if (i != dd_idx1 && i != dd_idx2 &&
- !test_bit(R5_UPTODATE, &sh->dev[i].flags))
- printk("compute_2 with missing block %d/%d\n", count, i);
- } while ( i != d0_idx );
-
- if ( failb == disks-2 ) {
- /* We're missing D+P. */
- raid6_datap_recov(disks, STRIPE_SIZE, faila, ptrs);
- } else {
- /* We're missing D+D. */
- raid6_2data_recov(disks, STRIPE_SIZE, faila, failb, ptrs);
- }
-
- /* Both the above update both missing blocks */
- set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
- set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
+ /* We're missing D+P or D+D; */
+ if (failb == syndrome_disks) {
+ /* We're missing D+P. */
+ raid6_datap_recov(syndrome_disks+2, STRIPE_SIZE, faila, ptrs);
+ } else {
+ /* We're missing D+D. */
+ raid6_2data_recov(syndrome_disks+2, STRIPE_SIZE, faila, failb,
+ ptrs);
}
+
+ /* Both the above update both missing blocks */
+ set_bit(R5_UPTODATE, &sh->dev[dd_idx1].flags);
+ set_bit(R5_UPTODATE, &sh->dev[dd_idx2].flags);
}
static void
@@ -1800,17 +1993,21 @@ static int page_is_zero(struct page *p)
memcmp(a, a+4, STRIPE_SIZE-4)==0);
}
-static int stripe_to_pdidx(sector_t stripe, raid5_conf_t *conf, int disks)
+static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
+ struct stripe_head *sh)
{
- int sectors_per_chunk = conf->chunk_size >> 9;
- int pd_idx, dd_idx;
+ int sectors_per_chunk =
+ previous ? (conf->prev_chunk >> 9)
+ : (conf->chunk_size >> 9);
+ int dd_idx;
int chunk_offset = sector_div(stripe, sectors_per_chunk);
+ int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
- raid5_compute_sector(stripe * (disks - conf->max_degraded)
+ raid5_compute_sector(conf,
+ stripe * (disks - conf->max_degraded)
*sectors_per_chunk + chunk_offset,
- disks, disks - conf->max_degraded,
- &dd_idx, &pd_idx, conf);
- return pd_idx;
+ previous,
+ &dd_idx, sh);
}
static void
@@ -2181,7 +2378,7 @@ static void handle_stripe_dirtying6(raid5_conf_t *conf,
struct r6_state *r6s, int disks)
{
int rcw = 0, must_compute = 0, pd_idx = sh->pd_idx, i;
- int qd_idx = r6s->qd_idx;
+ int qd_idx = sh->qd_idx;
for (i = disks; i--; ) {
struct r5dev *dev = &sh->dev[i];
/* Would I have to read this buffer for reconstruct_write */
@@ -2371,7 +2568,7 @@ static void handle_parity_checks6(raid5_conf_t *conf, struct stripe_head *sh,
int update_p = 0, update_q = 0;
struct r5dev *dev;
int pd_idx = sh->pd_idx;
- int qd_idx = r6s->qd_idx;
+ int qd_idx = sh->qd_idx;
set_bit(STRIPE_HANDLE, &sh->state);
@@ -2467,17 +2664,14 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
struct dma_async_tx_descriptor *tx = NULL;
clear_bit(STRIPE_EXPAND_SOURCE, &sh->state);
for (i = 0; i < sh->disks; i++)
- if (i != sh->pd_idx && (!r6s || i != r6s->qd_idx)) {
- int dd_idx, pd_idx, j;
+ if (i != sh->pd_idx && i != sh->qd_idx) {
+ int dd_idx, j;
struct stripe_head *sh2;
- sector_t bn = compute_blocknr(sh, i);
- sector_t s = raid5_compute_sector(bn, conf->raid_disks,
- conf->raid_disks -
- conf->max_degraded, &dd_idx,
- &pd_idx, conf);
- sh2 = get_active_stripe(conf, s, conf->raid_disks,
- pd_idx, 1);
+ sector_t bn = compute_blocknr(sh, i, 1);
+ sector_t s = raid5_compute_sector(conf, bn, 0,
+ &dd_idx, NULL);
+ sh2 = get_active_stripe(conf, s, 0, 1);
if (sh2 == NULL)
/* so far only the early blocks of this stripe
* have been requested. When later blocks
@@ -2500,8 +2694,7 @@ static void handle_stripe_expansion(raid5_conf_t *conf, struct stripe_head *sh,
set_bit(R5_UPTODATE, &sh2->dev[dd_idx].flags);
for (j = 0; j < conf->raid_disks; j++)
if (j != sh2->pd_idx &&
- (!r6s || j != raid6_next_disk(sh2->pd_idx,
- sh2->disks)) &&
+ (!r6s || j != sh2->qd_idx) &&
!test_bit(R5_Expanded, &sh2->dev[j].flags))
break;
if (j == conf->raid_disks) {
@@ -2750,6 +2943,23 @@ static bool handle_stripe5(struct stripe_head *sh)
/* Finish reconstruct operations initiated by the expansion process */
if (sh->reconstruct_state == reconstruct_state_result) {
+ struct stripe_head *sh2
+ = get_active_stripe(conf, sh->sector, 1, 1);
+ if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+ /* sh cannot be written until sh2 has been read.
+ * so arrange for sh to be delayed a little
+ */
+ set_bit(STRIPE_DELAYED, &sh->state);
+ set_bit(STRIPE_HANDLE, &sh->state);
+ if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+ &sh2->state))
+ atomic_inc(&conf->preread_active_stripes);
+ release_stripe(sh2);
+ goto unlock;
+ }
+ if (sh2)
+ release_stripe(sh2);
+
sh->reconstruct_state = reconstruct_state_idle;
clear_bit(STRIPE_EXPANDING, &sh->state);
for (i = conf->raid_disks; i--; ) {
@@ -2763,8 +2973,7 @@ static bool handle_stripe5(struct stripe_head *sh)
!sh->reconstruct_state) {
/* Need to write out all blocks after computing parity */
sh->disks = conf->raid_disks;
- sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
- conf->raid_disks);
+ stripe_set_idx(sh->sector, conf, 0, sh);
schedule_reconstruction5(sh, &s, 1, 1);
} else if (s.expanded && !sh->reconstruct_state && s.locked == 0) {
clear_bit(STRIPE_EXPAND_READY, &sh->state);
@@ -2796,20 +3005,19 @@ static bool handle_stripe5(struct stripe_head *sh)
static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
{
- raid6_conf_t *conf = sh->raid_conf;
+ raid5_conf_t *conf = sh->raid_conf;
int disks = sh->disks;
struct bio *return_bi = NULL;
- int i, pd_idx = sh->pd_idx;
+ int i, pd_idx = sh->pd_idx, qd_idx = sh->qd_idx;
struct stripe_head_state s;
struct r6_state r6s;
struct r5dev *dev, *pdev, *qdev;
mdk_rdev_t *blocked_rdev = NULL;
- r6s.qd_idx = raid6_next_disk(pd_idx, disks);
pr_debug("handling stripe %llu, state=%#lx cnt=%d, "
"pd_idx=%d, qd_idx=%d\n",
(unsigned long long)sh->sector, sh->state,
- atomic_read(&sh->count), pd_idx, r6s.qd_idx);
+ atomic_read(&sh->count), pd_idx, qd_idx);
memset(&s, 0, sizeof(s));
spin_lock(&sh->lock);
@@ -2920,9 +3128,9 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
pdev = &sh->dev[pd_idx];
r6s.p_failed = (s.failed >= 1 && r6s.failed_num[0] == pd_idx)
|| (s.failed >= 2 && r6s.failed_num[1] == pd_idx);
- qdev = &sh->dev[r6s.qd_idx];
- r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == r6s.qd_idx)
- || (s.failed >= 2 && r6s.failed_num[1] == r6s.qd_idx);
+ qdev = &sh->dev[qd_idx];
+ r6s.q_failed = (s.failed >= 1 && r6s.failed_num[0] == qd_idx)
+ || (s.failed >= 2 && r6s.failed_num[1] == qd_idx);
if ( s.written &&
( r6s.p_failed || ((test_bit(R5_Insync, &pdev->flags)
@@ -2980,10 +3188,26 @@ static bool handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
}
if (s.expanded && test_bit(STRIPE_EXPANDING, &sh->state)) {
+ struct stripe_head *sh2
+ = get_active_stripe(conf, sh->sector, 1, 1);
+ if (sh2 && test_bit(STRIPE_EXPAND_SOURCE, &sh2->state)) {
+ /* sh cannot be written until sh2 has been read.
+ * so arrange for sh to be delayed a little
+ */
+ set_bit(STRIPE_DELAYED, &sh->state);
+ set_bit(STRIPE_HANDLE, &sh->state);
+ if (!test_and_set_bit(STRIPE_PREREAD_ACTIVE,
+ &sh2->state))
+ atomic_inc(&conf->preread_active_stripes);
+ release_stripe(sh2);
+ goto unlock;
+ }
+ if (sh2)
+ release_stripe(sh2);
+
/* Need to write out all blocks after computing P&Q */
sh->disks = conf->raid_disks;
- sh->pd_idx = stripe_to_pdidx(sh->sector, conf,
- conf->raid_disks);
+ stripe_set_idx(sh->sector, conf, 0, sh);
compute_parity6(sh, RECONSTRUCT_WRITE);
for (i = conf->raid_disks ; i-- ; ) {
set_bit(R5_LOCKED, &sh->dev[i].flags);
@@ -3134,6 +3358,8 @@ static int raid5_mergeable_bvec(struct request_queue *q,
if ((bvm->bi_rw & 1) == WRITE)
return biovec->bv_len; /* always allow writes to be mergeable */
+ if (mddev->new_chunk < mddev->chunk_size)
+ chunk_sectors = mddev->new_chunk >> 9;
max = (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
if (max < 0) max = 0;
if (max <= biovec->bv_len && bio_sectors == 0)
@@ -3149,6 +3375,8 @@ static int in_chunk_boundary(mddev_t *mddev, struct bio *bio)
unsigned int chunk_sectors = mddev->chunk_size >> 9;
unsigned int bio_sectors = bio->bi_size >> 9;
+ if (mddev->new_chunk < mddev->chunk_size)
+ chunk_sectors = mddev->new_chunk >> 9;
return chunk_sectors >=
((sector & (chunk_sectors - 1)) + bio_sectors);
}
@@ -3255,9 +3483,7 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
{
mddev_t *mddev = q->queuedata;
raid5_conf_t *conf = mddev_to_conf(mddev);
- const unsigned int raid_disks = conf->raid_disks;
- const unsigned int data_disks = raid_disks - conf->max_degraded;
- unsigned int dd_idx, pd_idx;
+ unsigned int dd_idx;
struct bio* align_bi;
mdk_rdev_t *rdev;
@@ -3266,7 +3492,7 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
return 0;
}
/*
- * use bio_clone to make a copy of the bio
+ * use bio_clone to make a copy of the bio
*/
align_bi = bio_clone(raid_bio, GFP_NOIO);
if (!align_bi)
@@ -3280,12 +3506,9 @@ static int chunk_aligned_read(struct request_queue *q, struct bio * raid_bio)
/*
* compute position
*/
- align_bi->bi_sector = raid5_compute_sector(raid_bio->bi_sector,
- raid_disks,
- data_disks,
- &dd_idx,
- &pd_idx,
- conf);
+ align_bi->bi_sector = raid5_compute_sector(conf, raid_bio->bi_sector,
+ 0,
+ &dd_idx, NULL);
rcu_read_lock();
rdev = rcu_dereference(conf->disks[dd_idx].rdev);
@@ -3377,7 +3600,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
{
mddev_t *mddev = q->queuedata;
raid5_conf_t *conf = mddev_to_conf(mddev);
- unsigned int dd_idx, pd_idx;
+ int dd_idx;
sector_t new_sector;
sector_t logical_sector, last_sector;
struct stripe_head *sh;
@@ -3400,7 +3623,7 @@ static int make_request(struct request_queue *q, struct bio * bi)
if (rw == READ &&
mddev->reshape_position == MaxSector &&
chunk_aligned_read(q,bi))
- return 0;
+ return 0;
logical_sector = bi->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
last_sector = bi->bi_sector + (bi->bi_size>>9);
@@ -3410,26 +3633,31 @@ static int make_request(struct request_queue *q, struct bio * bi)
for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
DEFINE_WAIT(w);
int disks, data_disks;
+ int previous;
retry:
+ previous = 0;
+ disks = conf->raid_disks;
prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
- if (likely(conf->expand_progress == MaxSector))
- disks = conf->raid_disks;
- else {
- /* spinlock is needed as expand_progress may be
+ if (unlikely(conf->reshape_progress != MaxSector)) {
+ /* spinlock is needed as reshape_progress may be
* 64bit on a 32bit platform, and so it might be
* possible to see a half-updated value
- * Ofcourse expand_progress could change after
+ * Ofcourse reshape_progress could change after
* the lock is dropped, so once we get a reference
* to the stripe that we think it is, we will have
* to check again.
*/
spin_lock_irq(&conf->device_lock);
- disks = conf->raid_disks;
- if (logical_sector >= conf->expand_progress)
+ if (mddev->delta_disks < 0
+ ? logical_sector < conf->reshape_progress
+ : logical_sector >= conf->reshape_progress) {
disks = conf->previous_raid_disks;
- else {
- if (logical_sector >= conf->expand_lo) {
+ previous = 1;
+ } else {
+ if (mddev->delta_disks < 0
+ ? logical_sector < conf->reshape_safe
+ : logical_sector >= conf->reshape_safe) {
spin_unlock_irq(&conf->device_lock);
schedule();
goto retry;
@@ -3439,15 +3667,17 @@ static int make_request(struct request_queue *q, struct bio * bi)
}
data_disks = disks - conf->max_degraded;
- new_sector = raid5_compute_sector(logical_sector, disks, data_disks,
- &dd_idx, &pd_idx, conf);
+ new_sector = raid5_compute_sector(conf, logical_sector,
+ previous,
+ &dd_idx, NULL);
pr_debug("raid5: make_request, sector %llu logical %llu\n",
(unsigned long long)new_sector,
(unsigned long long)logical_sector);
- sh = get_active_stripe(conf, new_sector, disks, pd_idx, (bi->bi_rw&RWA_MASK));
+ sh = get_active_stripe(conf, new_sector, previous,
+ (bi->bi_rw&RWA_MASK));
if (sh) {
- if (unlikely(conf->expand_progress != MaxSector)) {
+ if (unlikely(previous)) {
/* expansion might have moved on while waiting for a
* stripe, so we must do the range check again.
* Expansion could still move past after this
@@ -3458,8 +3688,9 @@ static int make_request(struct request_queue *q, struct bio * bi)
*/
int must_retry = 0;
spin_lock_irq(&conf->device_lock);
- if (logical_sector < conf->expand_progress &&
- disks == conf->previous_raid_disks)
+ if (mddev->delta_disks < 0
+ ? logical_sector >= conf->reshape_progress
+ : logical_sector < conf->reshape_progress)
/* mismatch, need to try again */
must_retry = 1;
spin_unlock_irq(&conf->device_lock);
@@ -3514,6 +3745,8 @@ static int make_request(struct request_queue *q, struct bio * bi)
return 0;
}
+static sector_t raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks);
+
static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped)
{
/* reshaping is quite different to recovery/resync so it is
@@ -3527,61 +3760,118 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
*/
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
- int pd_idx;
sector_t first_sector, last_sector;
int raid_disks = conf->previous_raid_disks;
int data_disks = raid_disks - conf->max_degraded;
int new_data_disks = conf->raid_disks - conf->max_degraded;
int i;
int dd_idx;
- sector_t writepos, safepos, gap;
-
- if (sector_nr == 0 &&
- conf->expand_progress != 0) {
- /* restarting in the middle, skip the initial sectors */
- sector_nr = conf->expand_progress;
+ sector_t writepos, readpos, safepos;
+ sector_t stripe_addr;
+ int reshape_sectors;
+ struct list_head stripes;
+
+ if (sector_nr == 0) {
+ /* If restarting in the middle, skip the initial sectors */
+ if (mddev->delta_disks < 0 &&
+ conf->reshape_progress < raid5_size(mddev, 0, 0)) {
+ sector_nr = raid5_size(mddev, 0, 0)
+ - conf->reshape_progress;
+ } else if (mddev->delta_disks > 0 &&
+ conf->reshape_progress > 0)
+ sector_nr = conf->reshape_progress;
sector_div(sector_nr, new_data_disks);
- *skipped = 1;
- return sector_nr;
+ if (sector_nr) {
+ *skipped = 1;
+ return sector_nr;
+ }
}
+ /* We need to process a full chunk at a time.
+ * If old and new chunk sizes differ, we need to process the
+ * largest of these
+ */
+ if (mddev->new_chunk > mddev->chunk_size)
+ reshape_sectors = mddev->new_chunk / 512;
+ else
+ reshape_sectors = mddev->chunk_size / 512;
+
/* we update the metadata when there is more than 3Meg
* in the block range (that is rather arbitrary, should
* probably be time based) or when the data about to be
* copied would over-write the source of the data at
* the front of the range.
- * i.e. one new_stripe forward from expand_progress new_maps
- * to after where expand_lo old_maps to
+ * i.e. one new_stripe along from reshape_progress new_maps
+ * to after where reshape_safe old_maps to
*/
- writepos = conf->expand_progress +
- conf->chunk_size/512*(new_data_disks);
+ writepos = conf->reshape_progress;
sector_div(writepos, new_data_disks);
- safepos = conf->expand_lo;
+ readpos = conf->reshape_progress;
+ sector_div(readpos, data_disks);
+ safepos = conf->reshape_safe;
sector_div(safepos, data_disks);
- gap = conf->expand_progress - conf->expand_lo;
+ if (mddev->delta_disks < 0) {
+ writepos -= reshape_sectors;
+ readpos += reshape_sectors;
+ safepos += reshape_sectors;
+ } else {
+ writepos += reshape_sectors;
+ readpos -= reshape_sectors;
+ safepos -= reshape_sectors;
+ }
- if (writepos >= safepos ||
- gap > (new_data_disks)*3000*2 /*3Meg*/) {
+ /* 'writepos' is the most advanced device address we might write.
+ * 'readpos' is the least advanced device address we might read.
+ * 'safepos' is the least address recorded in the metadata as having
+ * been reshaped.
+ * If 'readpos' is behind 'writepos', then there is no way that we can
+ * ensure safety in the face of a crash - that must be done by userspace
+ * making a backup of the data. So in that case there is no particular
+ * rush to update metadata.
+ * Otherwise if 'safepos' is behind 'writepos', then we really need to
+ * update the metadata to advance 'safepos' to match 'readpos' so that
+ * we can be safe in the event of a crash.
+ * So we insist on updating metadata if safepos is behind writepos and
+ * readpos is beyond writepos.
+ * In any case, update the metadata every 10 seconds.
+ * Maybe that number should be configurable, but I'm not sure it is
+ * worth it.... maybe it could be a multiple of safemode_delay???
+ */
+ if ((mddev->delta_disks < 0
+ ? (safepos > writepos && readpos < writepos)
+ : (safepos < writepos && readpos > writepos)) ||
+ time_after(jiffies, conf->reshape_checkpoint + 10*HZ)) {
/* Cannot proceed until we've updated the superblock... */
wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes)==0);
- mddev->reshape_position = conf->expand_progress;
+ mddev->reshape_position = conf->reshape_progress;
+ conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread);
wait_event(mddev->sb_wait, mddev->flags == 0 ||
kthread_should_stop());
spin_lock_irq(&conf->device_lock);
- conf->expand_lo = mddev->reshape_position;
+ conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap);
}
- for (i=0; i < conf->chunk_size/512; i+= STRIPE_SECTORS) {
+ if (mddev->delta_disks < 0) {
+ BUG_ON(conf->reshape_progress == 0);
+ stripe_addr = writepos;
+ BUG_ON((mddev->dev_sectors &
+ ~((sector_t)reshape_sectors - 1))
+ - reshape_sectors - stripe_addr
+ != sector_nr);
+ } else {
+ BUG_ON(writepos != sector_nr + reshape_sectors);
+ stripe_addr = sector_nr;
+ }
+ INIT_LIST_HEAD(&stripes);
+ for (i = 0; i < reshape_sectors; i += STRIPE_SECTORS) {
int j;
int skipped = 0;
- pd_idx = stripe_to_pdidx(sector_nr+i, conf, conf->raid_disks);
- sh = get_active_stripe(conf, sector_nr+i,
- conf->raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, stripe_addr+i, 0, 0);
set_bit(STRIPE_EXPANDING, &sh->state);
atomic_inc(&conf->reshape_stripes);
/* If any of this stripe is beyond the end of the old
@@ -3592,10 +3882,10 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
if (j == sh->pd_idx)
continue;
if (conf->level == 6 &&
- j == raid6_next_disk(sh->pd_idx, sh->disks))
+ j == sh->qd_idx)
continue;
- s = compute_blocknr(sh, j);
- if (s < mddev->array_sectors) {
+ s = compute_blocknr(sh, j, 0);
+ if (s < raid5_size(mddev, 0, 0)) {
skipped = 1;
continue;
}
@@ -3607,10 +3897,13 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
set_bit(STRIPE_EXPAND_READY, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
}
- release_stripe(sh);
+ list_add(&sh->lru, &stripes);
}
spin_lock_irq(&conf->device_lock);
- conf->expand_progress = (sector_nr + i) * new_data_disks;
+ if (mddev->delta_disks < 0)
+ conf->reshape_progress -= reshape_sectors * new_data_disks;
+ else
+ conf->reshape_progress += reshape_sectors * new_data_disks;
spin_unlock_irq(&conf->device_lock);
/* Ok, those stripe are ready. We can start scheduling
* reads on the source stripes.
@@ -3618,46 +3911,50 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped
* block on the destination stripes.
*/
first_sector =
- raid5_compute_sector(sector_nr*(new_data_disks),
- raid_disks, data_disks,
- &dd_idx, &pd_idx, conf);
+ raid5_compute_sector(conf, stripe_addr*(new_data_disks),
+ 1, &dd_idx, NULL);
last_sector =
- raid5_compute_sector((sector_nr+conf->chunk_size/512)
- *(new_data_disks) -1,
- raid_disks, data_disks,
- &dd_idx, &pd_idx, conf);
- if (last_sector >= (mddev->size<<1))
- last_sector = (mddev->size<<1)-1;
+ raid5_compute_sector(conf, ((stripe_addr+conf->chunk_size/512)
+ *(new_data_disks) - 1),
+ 1, &dd_idx, NULL);
+ if (last_sector >= mddev->dev_sectors)
+ last_sector = mddev->dev_sectors - 1;
while (first_sector <= last_sector) {
- pd_idx = stripe_to_pdidx(first_sector, conf,
- conf->previous_raid_disks);
- sh = get_active_stripe(conf, first_sector,
- conf->previous_raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, first_sector, 1, 0);
set_bit(STRIPE_EXPAND_SOURCE, &sh->state);
set_bit(STRIPE_HANDLE, &sh->state);
release_stripe(sh);
first_sector += STRIPE_SECTORS;
}
+ /* Now that the sources are clearly marked, we can release
+ * the destination stripes
+ */
+ while (!list_empty(&stripes)) {
+ sh = list_entry(stripes.next, struct stripe_head, lru);
+ list_del_init(&sh->lru);
+ release_stripe(sh);
+ }
/* If this takes us to the resync_max point where we have to pause,
* then we need to write out the superblock.
*/
- sector_nr += conf->chunk_size>>9;
+ sector_nr += reshape_sectors;
if (sector_nr >= mddev->resync_max) {
/* Cannot proceed until we've updated the superblock... */
wait_event(conf->wait_for_overlap,
atomic_read(&conf->reshape_stripes) == 0);
- mddev->reshape_position = conf->expand_progress;
+ mddev->reshape_position = conf->reshape_progress;
+ conf->reshape_checkpoint = jiffies;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
md_wakeup_thread(mddev->thread);
wait_event(mddev->sb_wait,
!test_bit(MD_CHANGE_DEVS, &mddev->flags)
|| kthread_should_stop());
spin_lock_irq(&conf->device_lock);
- conf->expand_lo = mddev->reshape_position;
+ conf->reshape_safe = mddev->reshape_position;
spin_unlock_irq(&conf->device_lock);
wake_up(&conf->wait_for_overlap);
}
- return conf->chunk_size>>9;
+ return reshape_sectors;
}
/* FIXME go_faster isn't used */
@@ -3665,9 +3962,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
- int pd_idx;
- int raid_disks = conf->raid_disks;
- sector_t max_sector = mddev->size << 1;
+ sector_t max_sector = mddev->dev_sectors;
int sync_blocks;
int still_degraded = 0;
int i;
@@ -3675,6 +3970,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
if (sector_nr >= max_sector) {
/* just being told to finish up .. nothing much to do */
unplug_slaves(mddev);
+
if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
end_reshape(conf);
return 0;
@@ -3705,7 +4001,7 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
*/
if (mddev->degraded >= conf->max_degraded &&
test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
- sector_t rv = (mddev->size << 1) - sector_nr;
+ sector_t rv = mddev->dev_sectors - sector_nr;
*skipped = 1;
return rv;
}
@@ -3721,10 +4017,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski
bitmap_cond_end_sync(mddev->bitmap, sector_nr);
- pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks);
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector_nr, 0, 1);
if (sh == NULL) {
- sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 0);
+ sh = get_active_stripe(conf, sector_nr, 0, 0);
/* make sure we don't swamp the stripe cache if someone else
* is trying to get access
*/
@@ -3766,19 +4061,15 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
* it will be only one 'dd_idx' and only need one call to raid5_compute_sector.
*/
struct stripe_head *sh;
- int dd_idx, pd_idx;
+ int dd_idx;
sector_t sector, logical_sector, last_sector;
int scnt = 0;
int remaining;
int handled = 0;
logical_sector = raid_bio->bi_sector & ~((sector_t)STRIPE_SECTORS-1);
- sector = raid5_compute_sector( logical_sector,
- conf->raid_disks,
- conf->raid_disks - conf->max_degraded,
- &dd_idx,
- &pd_idx,
- conf);
+ sector = raid5_compute_sector(conf, logical_sector,
+ 0, &dd_idx, NULL);
last_sector = raid_bio->bi_sector + (raid_bio->bi_size>>9);
for (; logical_sector < last_sector;
@@ -3790,7 +4081,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio)
/* already done this stripe */
continue;
- sh = get_active_stripe(conf, sector, conf->raid_disks, pd_idx, 1);
+ sh = get_active_stripe(conf, sector, 0, 1);
if (!sh) {
/* failed to get a stripe - must wait */
@@ -3992,89 +4283,69 @@ static struct attribute_group raid5_attrs_group = {
.attrs = raid5_attrs,
};
-static int run(mddev_t *mddev)
+static sector_t
+raid5_size(mddev_t *mddev, sector_t sectors, int raid_disks)
+{
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (!sectors)
+ sectors = mddev->dev_sectors;
+ if (!raid_disks) {
+ /* size is defined by the smallest of previous and new size */
+ if (conf->raid_disks < conf->previous_raid_disks)
+ raid_disks = conf->raid_disks;
+ else
+ raid_disks = conf->previous_raid_disks;
+ }
+
+ sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+ sectors &= ~((sector_t)mddev->new_chunk/512 - 1);
+ return sectors * (raid_disks - conf->max_degraded);
+}
+
+static raid5_conf_t *setup_conf(mddev_t *mddev)
{
raid5_conf_t *conf;
int raid_disk, memory;
mdk_rdev_t *rdev;
struct disk_info *disk;
- int working_disks = 0;
- if (mddev->level != 5 && mddev->level != 4 && mddev->level != 6) {
+ if (mddev->new_level != 5
+ && mddev->new_level != 4
+ && mddev->new_level != 6) {
printk(KERN_ERR "raid5: %s: raid level not set to 4/5/6 (%d)\n",
- mdname(mddev), mddev->level);
- return -EIO;
+ mdname(mddev), mddev->new_level);
+ return ERR_PTR(-EIO);
}
-
- if (mddev->chunk_size < PAGE_SIZE) {
- printk(KERN_ERR "md/raid5: chunk_size must be at least "
- "PAGE_SIZE but %d < %ld\n",
- mddev->chunk_size, PAGE_SIZE);
- return -EINVAL;
+ if ((mddev->new_level == 5
+ && !algorithm_valid_raid5(mddev->new_layout)) ||
+ (mddev->new_level == 6
+ && !algorithm_valid_raid6(mddev->new_layout))) {
+ printk(KERN_ERR "raid5: %s: layout %d not supported\n",
+ mdname(mddev), mddev->new_layout);
+ return ERR_PTR(-EIO);
}
-
- if (mddev->reshape_position != MaxSector) {
- /* Check that we can continue the reshape.
- * Currently only disks can change, it must
- * increase, and we must be past the point where
- * a stripe over-writes itself
- */
- sector_t here_new, here_old;
- int old_disks;
- int max_degraded = (mddev->level == 5 ? 1 : 2);
-
- if (mddev->new_level != mddev->level ||
- mddev->new_layout != mddev->layout ||
- mddev->new_chunk != mddev->chunk_size) {
- printk(KERN_ERR "raid5: %s: unsupported reshape "
- "required - aborting.\n",
- mdname(mddev));
- return -EINVAL;
- }
- if (mddev->delta_disks <= 0) {
- printk(KERN_ERR "raid5: %s: unsupported reshape "
- "(reduce disks) required - aborting.\n",
- mdname(mddev));
- return -EINVAL;
- }
- old_disks = mddev->raid_disks - mddev->delta_disks;
- /* reshape_position must be on a new-stripe boundary, and one
- * further up in new geometry must map after here in old
- * geometry.
- */
- here_new = mddev->reshape_position;
- if (sector_div(here_new, (mddev->chunk_size>>9)*
- (mddev->raid_disks - max_degraded))) {
- printk(KERN_ERR "raid5: reshape_position not "
- "on a stripe boundary\n");
- return -EINVAL;
- }
- /* here_new is the stripe we will write to */
- here_old = mddev->reshape_position;
- sector_div(here_old, (mddev->chunk_size>>9)*
- (old_disks-max_degraded));
- /* here_old is the first stripe that we might need to read
- * from */
- if (here_new >= here_old) {
- /* Reading from the same stripe as writing to - bad */
- printk(KERN_ERR "raid5: reshape_position too early for "
- "auto-recovery - aborting.\n");
- return -EINVAL;
- }
- printk(KERN_INFO "raid5: reshape will continue\n");
- /* OK, we should be able to continue; */
+ if (mddev->new_level == 6 && mddev->raid_disks < 4) {
+ printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
+ mdname(mddev), mddev->raid_disks);
+ return ERR_PTR(-EINVAL);
}
+ if (!mddev->new_chunk || mddev->new_chunk % PAGE_SIZE) {
+ printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
+ mddev->new_chunk, mdname(mddev));
+ return ERR_PTR(-EINVAL);
+ }
- mddev->private = kzalloc(sizeof (raid5_conf_t), GFP_KERNEL);
- if ((conf = mddev->private) == NULL)
+ conf = kzalloc(sizeof(raid5_conf_t), GFP_KERNEL);
+ if (conf == NULL)
goto abort;
- if (mddev->reshape_position == MaxSector) {
- conf->previous_raid_disks = conf->raid_disks = mddev->raid_disks;
- } else {
- conf->raid_disks = mddev->raid_disks;
+
+ conf->raid_disks = mddev->raid_disks;
+ if (mddev->reshape_position == MaxSector)
+ conf->previous_raid_disks = mddev->raid_disks;
+ else
conf->previous_raid_disks = mddev->raid_disks - mddev->delta_disks;
- }
conf->disks = kzalloc(conf->raid_disks * sizeof(struct disk_info),
GFP_KERNEL);
@@ -4086,13 +4357,12 @@ static int run(mddev_t *mddev)
if ((conf->stripe_hashtbl = kzalloc(PAGE_SIZE, GFP_KERNEL)) == NULL)
goto abort;
- if (mddev->level == 6) {
+ if (mddev->new_level == 6) {
conf->spare_page = alloc_page(GFP_KERNEL);
if (!conf->spare_page)
goto abort;
}
spin_lock_init(&conf->device_lock);
- mddev->queue->queue_lock = &conf->device_lock;
init_waitqueue_head(&conf->wait_for_stripe);
init_waitqueue_head(&conf->wait_for_overlap);
INIT_LIST_HEAD(&conf->handle_list);
@@ -4121,47 +4391,134 @@ static int run(mddev_t *mddev)
printk(KERN_INFO "raid5: device %s operational as raid"
" disk %d\n", bdevname(rdev->bdev,b),
raid_disk);
- working_disks++;
} else
/* Cannot rely on bitmap to complete recovery */
conf->fullsync = 1;
}
- /*
- * 0 for a fully functional array, 1 or 2 for a degraded array.
- */
- mddev->degraded = conf->raid_disks - working_disks;
- conf->mddev = mddev;
- conf->chunk_size = mddev->chunk_size;
- conf->level = mddev->level;
+ conf->chunk_size = mddev->new_chunk;
+ conf->level = mddev->new_level;
if (conf->level == 6)
conf->max_degraded = 2;
else
conf->max_degraded = 1;
- conf->algorithm = mddev->layout;
+ conf->algorithm = mddev->new_layout;
conf->max_nr_stripes = NR_STRIPES;
- conf->expand_progress = mddev->reshape_position;
-
- /* device size must be a multiple of chunk size */
- mddev->size &= ~(mddev->chunk_size/1024 -1);
- mddev->resync_max_sectors = mddev->size << 1;
+ conf->reshape_progress = mddev->reshape_position;
+ if (conf->reshape_progress != MaxSector) {
+ conf->prev_chunk = mddev->chunk_size;
+ conf->prev_algo = mddev->layout;
+ }
- if (conf->level == 6 && conf->raid_disks < 4) {
- printk(KERN_ERR "raid6: not enough configured devices for %s (%d, minimum 4)\n",
- mdname(mddev), conf->raid_disks);
+ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
+ conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
+ if (grow_stripes(conf, conf->max_nr_stripes)) {
+ printk(KERN_ERR
+ "raid5: couldn't allocate %dkB for buffers\n", memory);
goto abort;
- }
- if (!conf->chunk_size || conf->chunk_size % 4) {
- printk(KERN_ERR "raid5: invalid chunk size %d for %s\n",
- conf->chunk_size, mdname(mddev));
+ } else
+ printk(KERN_INFO "raid5: allocated %dkB for %s\n",
+ memory, mdname(mddev));
+
+ conf->thread = md_register_thread(raid5d, mddev, "%s_raid5");
+ if (!conf->thread) {
+ printk(KERN_ERR
+ "raid5: couldn't allocate thread for %s\n",
+ mdname(mddev));
goto abort;
}
- if (conf->algorithm > ALGORITHM_RIGHT_SYMMETRIC) {
- printk(KERN_ERR
- "raid5: unsupported parity algorithm %d for %s\n",
- conf->algorithm, mdname(mddev));
- goto abort;
+
+ return conf;
+
+ abort:
+ if (conf) {
+ shrink_stripes(conf);
+ safe_put_page(conf->spare_page);
+ kfree(conf->disks);
+ kfree(conf->stripe_hashtbl);
+ kfree(conf);
+ return ERR_PTR(-EIO);
+ } else
+ return ERR_PTR(-ENOMEM);
+}
+
+static int run(mddev_t *mddev)
+{
+ raid5_conf_t *conf;
+ int working_disks = 0;
+ mdk_rdev_t *rdev;
+
+ if (mddev->reshape_position != MaxSector) {
+ /* Check that we can continue the reshape.
+ * Currently only disks can change, it must
+ * increase, and we must be past the point where
+ * a stripe over-writes itself
+ */
+ sector_t here_new, here_old;
+ int old_disks;
+ int max_degraded = (mddev->level == 6 ? 2 : 1);
+
+ if (mddev->new_level != mddev->level) {
+ printk(KERN_ERR "raid5: %s: unsupported reshape "
+ "required - aborting.\n",
+ mdname(mddev));
+ return -EINVAL;
+ }
+ old_disks = mddev->raid_disks - mddev->delta_disks;
+ /* reshape_position must be on a new-stripe boundary, and one
+ * further up in new geometry must map after here in old
+ * geometry.
+ */
+ here_new = mddev->reshape_position;
+ if (sector_div(here_new, (mddev->new_chunk>>9)*
+ (mddev->raid_disks - max_degraded))) {
+ printk(KERN_ERR "raid5: reshape_position not "
+ "on a stripe boundary\n");
+ return -EINVAL;
+ }
+ /* here_new is the stripe we will write to */
+ here_old = mddev->reshape_position;
+ sector_div(here_old, (mddev->chunk_size>>9)*
+ (old_disks-max_degraded));
+ /* here_old is the first stripe that we might need to read
+ * from */
+ if (here_new >= here_old) {
+ /* Reading from the same stripe as writing to - bad */
+ printk(KERN_ERR "raid5: reshape_position too early for "
+ "auto-recovery - aborting.\n");
+ return -EINVAL;
+ }
+ printk(KERN_INFO "raid5: reshape will continue\n");
+ /* OK, we should be able to continue; */
+ } else {
+ BUG_ON(mddev->level != mddev->new_level);
+ BUG_ON(mddev->layout != mddev->new_layout);
+ BUG_ON(mddev->chunk_size != mddev->new_chunk);
+ BUG_ON(mddev->delta_disks != 0);
}
+
+ if (mddev->private == NULL)
+ conf = setup_conf(mddev);
+ else
+ conf = mddev->private;
+
+ if (IS_ERR(conf))
+ return PTR_ERR(conf);
+
+ mddev->thread = conf->thread;
+ conf->thread = NULL;
+ mddev->private = conf;
+
+ /*
+ * 0 for a fully functional array, 1 or 2 for a degraded array.
+ */
+ list_for_each_entry(rdev, &mddev->disks, same_set)
+ if (rdev->raid_disk >= 0 &&
+ test_bit(In_sync, &rdev->flags))
+ working_disks++;
+
+ mddev->degraded = conf->raid_disks - working_disks;
+
if (mddev->degraded > conf->max_degraded) {
printk(KERN_ERR "raid5: not enough operational devices for %s"
" (%d/%d failed)\n",
@@ -4169,6 +4526,10 @@ static int run(mddev_t *mddev)
goto abort;
}
+ /* device size must be a multiple of chunk size */
+ mddev->dev_sectors &= ~(mddev->chunk_size / 512 - 1);
+ mddev->resync_max_sectors = mddev->dev_sectors;
+
if (mddev->degraded > 0 &&
mddev->recovery_cp != MaxSector) {
if (mddev->ok_start_degraded)
@@ -4184,43 +4545,22 @@ static int run(mddev_t *mddev)
}
}
- {
- mddev->thread = md_register_thread(raid5d, mddev, "%s_raid5");
- if (!mddev->thread) {
- printk(KERN_ERR
- "raid5: couldn't allocate thread for %s\n",
- mdname(mddev));
- goto abort;
- }
- }
- memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
- conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
- if (grow_stripes(conf, conf->max_nr_stripes)) {
- printk(KERN_ERR
- "raid5: couldn't allocate %dkB for buffers\n", memory);
- shrink_stripes(conf);
- md_unregister_thread(mddev->thread);
- goto abort;
- } else
- printk(KERN_INFO "raid5: allocated %dkB for %s\n",
- memory, mdname(mddev));
-
if (mddev->degraded == 0)
printk("raid5: raid level %d set %s active with %d out of %d"
- " devices, algorithm %d\n", conf->level, mdname(mddev),
- mddev->raid_disks-mddev->degraded, mddev->raid_disks,
- conf->algorithm);
+ " devices, algorithm %d\n", conf->level, mdname(mddev),
+ mddev->raid_disks-mddev->degraded, mddev->raid_disks,
+ mddev->new_layout);
else
printk(KERN_ALERT "raid5: raid level %d set %s active with %d"
" out of %d devices, algorithm %d\n", conf->level,
mdname(mddev), mddev->raid_disks - mddev->degraded,
- mddev->raid_disks, conf->algorithm);
+ mddev->raid_disks, mddev->new_layout);
print_raid5_conf(conf);
- if (conf->expand_progress != MaxSector) {
+ if (conf->reshape_progress != MaxSector) {
printk("...ok start reshape thread\n");
- conf->expand_lo = conf->expand_progress;
+ conf->reshape_safe = conf->reshape_progress;
atomic_set(&conf->reshape_stripes, 0);
clear_bit(MD_RECOVERY_SYNC, &mddev->recovery);
clear_bit(MD_RECOVERY_CHECK, &mddev->recovery);
@@ -4247,18 +4587,22 @@ static int run(mddev_t *mddev)
"raid5: failed to create sysfs attributes for %s\n",
mdname(mddev));
+ mddev->queue->queue_lock = &conf->device_lock;
+
mddev->queue->unplug_fn = raid5_unplug_device;
mddev->queue->backing_dev_info.congested_data = mddev;
mddev->queue->backing_dev_info.congested_fn = raid5_congested;
- mddev->array_sectors = 2 * mddev->size * (conf->previous_raid_disks -
- conf->max_degraded);
+ md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
blk_queue_merge_bvec(mddev->queue, raid5_mergeable_bvec);
return 0;
abort:
+ md_unregister_thread(mddev->thread);
+ mddev->thread = NULL;
if (conf) {
+ shrink_stripes(conf);
print_raid5_conf(conf);
safe_put_page(conf->spare_page);
kfree(conf->disks);
@@ -4396,6 +4740,10 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
print_raid5_conf(conf);
rdev = p->rdev;
if (rdev) {
+ if (number >= conf->raid_disks &&
+ conf->reshape_progress == MaxSector)
+ clear_bit(In_sync, &rdev->flags);
+
if (test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) {
err = -EBUSY;
@@ -4405,7 +4753,8 @@ static int raid5_remove_disk(mddev_t *mddev, int number)
* isn't possible.
*/
if (!test_bit(Faulty, &rdev->flags) &&
- mddev->degraded <= conf->max_degraded) {
+ mddev->degraded <= conf->max_degraded &&
+ number < conf->raid_disks) {
err = -EBUSY;
goto abort;
}
@@ -4472,36 +4821,48 @@ static int raid5_resize(mddev_t *mddev, sector_t sectors)
* any io in the removed space completes, but it hardly seems
* worth it.
*/
- raid5_conf_t *conf = mddev_to_conf(mddev);
-
sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
- mddev->array_sectors = sectors * (mddev->raid_disks
- - conf->max_degraded);
+ md_set_array_sectors(mddev, raid5_size(mddev, sectors,
+ mddev->raid_disks));
+ if (mddev->array_sectors >
+ raid5_size(mddev, sectors, mddev->raid_disks))
+ return -EINVAL;
set_capacity(mddev->gendisk, mddev->array_sectors);
mddev->changed = 1;
- if (sectors/2 > mddev->size && mddev->recovery_cp == MaxSector) {
- mddev->recovery_cp = mddev->size << 1;
+ if (sectors > mddev->dev_sectors && mddev->recovery_cp == MaxSector) {
+ mddev->recovery_cp = mddev->dev_sectors;
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
}
- mddev->size = sectors /2;
+ mddev->dev_sectors = sectors;
mddev->resync_max_sectors = sectors;
return 0;
}
-#ifdef CONFIG_MD_RAID5_RESHAPE
static int raid5_check_reshape(mddev_t *mddev)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
- int err;
- if (mddev->delta_disks < 0 ||
- mddev->new_level != mddev->level)
- return -EINVAL; /* Cannot shrink array or change level yet */
- if (mddev->delta_disks == 0)
- return 0; /* nothing to do */
+ if (mddev->delta_disks == 0 &&
+ mddev->new_layout == mddev->layout &&
+ mddev->new_chunk == mddev->chunk_size)
+ return -EINVAL; /* nothing to do */
if (mddev->bitmap)
/* Cannot grow a bitmap yet */
return -EBUSY;
+ if (mddev->degraded > conf->max_degraded)
+ return -EINVAL;
+ if (mddev->delta_disks < 0) {
+ /* We might be able to shrink, but the devices must
+ * be made bigger first.
+ * For raid6, 4 is the minimum size.
+ * Otherwise 2 is the minimum
+ */
+ int min = 2;
+ if (mddev->level == 6)
+ min = 4;
+ if (mddev->raid_disks + mddev->delta_disks < min)
+ return -EINVAL;
+ }
/* Can only proceed if there are plenty of stripe_heads.
* We need a minimum of one full stripe,, and for sensible progress
@@ -4514,18 +4875,12 @@ static int raid5_check_reshape(mddev_t *mddev)
if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
(mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
printk(KERN_WARNING "raid5: reshape: not enough stripes. Needed %lu\n",
- (mddev->chunk_size / STRIPE_SIZE)*4);
+ (max(mddev->chunk_size, mddev->new_chunk)
+ / STRIPE_SIZE)*4);
return -ENOSPC;
}
- err = resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
- if (err)
- return err;
-
- if (mddev->degraded > conf->max_degraded)
- return -EINVAL;
- /* looks like we might be able to manage this */
- return 0;
+ return resize_stripes(conf, conf->raid_disks + mddev->delta_disks);
}
static int raid5_start_reshape(mddev_t *mddev)
@@ -4550,12 +4905,31 @@ static int raid5_start_reshape(mddev_t *mddev)
*/
return -EINVAL;
+ /* Refuse to reduce size of the array. Any reductions in
+ * array size must be through explicit setting of array_size
+ * attribute.
+ */
+ if (raid5_size(mddev, 0, conf->raid_disks + mddev->delta_disks)
+ < mddev->array_sectors) {
+ printk(KERN_ERR "md: %s: array size must be reduced "
+ "before number of disks\n", mdname(mddev));
+ return -EINVAL;
+ }
+
atomic_set(&conf->reshape_stripes, 0);
spin_lock_irq(&conf->device_lock);
conf->previous_raid_disks = conf->raid_disks;
conf->raid_disks += mddev->delta_disks;
- conf->expand_progress = 0;
- conf->expand_lo = 0;
+ conf->prev_chunk = conf->chunk_size;
+ conf->chunk_size = mddev->new_chunk;
+ conf->prev_algo = conf->algorithm;
+ conf->algorithm = mddev->new_layout;
+ if (mddev->delta_disks < 0)
+ conf->reshape_progress = raid5_size(mddev, 0, 0);
+ else
+ conf->reshape_progress = 0;
+ conf->reshape_safe = conf->reshape_progress;
+ conf->generation++;
spin_unlock_irq(&conf->device_lock);
/* Add some new drives, as many as will fit.
@@ -4580,9 +4954,12 @@ static int raid5_start_reshape(mddev_t *mddev)
break;
}
- spin_lock_irqsave(&conf->device_lock, flags);
- mddev->degraded = (conf->raid_disks - conf->previous_raid_disks) - added_devices;
- spin_unlock_irqrestore(&conf->device_lock, flags);
+ if (mddev->delta_disks > 0) {
+ spin_lock_irqsave(&conf->device_lock, flags);
+ mddev->degraded = (conf->raid_disks - conf->previous_raid_disks)
+ - added_devices;
+ spin_unlock_irqrestore(&conf->device_lock, flags);
+ }
mddev->raid_disks = conf->raid_disks;
mddev->reshape_position = 0;
set_bit(MD_CHANGE_DEVS, &mddev->flags);
@@ -4597,52 +4974,86 @@ static int raid5_start_reshape(mddev_t *mddev)
mddev->recovery = 0;
spin_lock_irq(&conf->device_lock);
mddev->raid_disks = conf->raid_disks = conf->previous_raid_disks;
- conf->expand_progress = MaxSector;
+ conf->reshape_progress = MaxSector;
spin_unlock_irq(&conf->device_lock);
return -EAGAIN;
}
+ conf->reshape_checkpoint = jiffies;
md_wakeup_thread(mddev->sync_thread);
md_new_event(mddev);
return 0;
}
-#endif
+/* This is called from the reshape thread and should make any
+ * changes needed in 'conf'
+ */
static void end_reshape(raid5_conf_t *conf)
{
- struct block_device *bdev;
if (!test_bit(MD_RECOVERY_INTR, &conf->mddev->recovery)) {
- conf->mddev->array_sectors = 2 * conf->mddev->size *
- (conf->raid_disks - conf->max_degraded);
- set_capacity(conf->mddev->gendisk, conf->mddev->array_sectors);
- conf->mddev->changed = 1;
-
- bdev = bdget_disk(conf->mddev->gendisk, 0);
- if (bdev) {
- mutex_lock(&bdev->bd_inode->i_mutex);
- i_size_write(bdev->bd_inode,
- (loff_t)conf->mddev->array_sectors << 9);
- mutex_unlock(&bdev->bd_inode->i_mutex);
- bdput(bdev);
- }
+
spin_lock_irq(&conf->device_lock);
- conf->expand_progress = MaxSector;
+ conf->previous_raid_disks = conf->raid_disks;
+ conf->reshape_progress = MaxSector;
spin_unlock_irq(&conf->device_lock);
- conf->mddev->reshape_position = MaxSector;
+ wake_up(&conf->wait_for_overlap);
/* read-ahead size must cover two whole stripes, which is
* 2 * (datadisks) * chunksize where 'n' is the number of raid devices
*/
{
- int data_disks = conf->previous_raid_disks - conf->max_degraded;
- int stripe = data_disks *
- (conf->mddev->chunk_size / PAGE_SIZE);
+ int data_disks = conf->raid_disks - conf->max_degraded;
+ int stripe = data_disks * (conf->chunk_size
+ / PAGE_SIZE);
if (conf->mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
conf->mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
}
}
}
+/* This is called from the raid5d thread with mddev_lock held.
+ * It makes config changes to the device.
+ */
+static void raid5_finish_reshape(mddev_t *mddev)
+{
+ struct block_device *bdev;
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+
+ if (mddev->delta_disks > 0) {
+ md_set_array_sectors(mddev, raid5_size(mddev, 0, 0));
+ set_capacity(mddev->gendisk, mddev->array_sectors);
+ mddev->changed = 1;
+
+ bdev = bdget_disk(mddev->gendisk, 0);
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode,
+ (loff_t)mddev->array_sectors << 9);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+ } else {
+ int d;
+ mddev->degraded = conf->raid_disks;
+ for (d = 0; d < conf->raid_disks ; d++)
+ if (conf->disks[d].rdev &&
+ test_bit(In_sync,
+ &conf->disks[d].rdev->flags))
+ mddev->degraded--;
+ for (d = conf->raid_disks ;
+ d < conf->raid_disks - mddev->delta_disks;
+ d++)
+ raid5_remove_disk(mddev, d);
+ }
+ mddev->layout = conf->algorithm;
+ mddev->chunk_size = conf->chunk_size;
+ mddev->reshape_position = MaxSector;
+ mddev->delta_disks = 0;
+ }
+}
+
static void raid5_quiesce(mddev_t *mddev, int state)
{
raid5_conf_t *conf = mddev_to_conf(mddev);
@@ -4672,6 +5083,212 @@ static void raid5_quiesce(mddev_t *mddev, int state)
}
}
+
+static void *raid5_takeover_raid1(mddev_t *mddev)
+{
+ int chunksect;
+
+ if (mddev->raid_disks != 2 ||
+ mddev->degraded > 1)
+ return ERR_PTR(-EINVAL);
+
+ /* Should check if there are write-behind devices? */
+
+ chunksect = 64*2; /* 64K by default */
+
+ /* The array must be an exact multiple of chunksize */
+ while (chunksect && (mddev->array_sectors & (chunksect-1)))
+ chunksect >>= 1;
+
+ if ((chunksect<<9) < STRIPE_SIZE)
+ /* array size does not allow a suitable chunk size */
+ return ERR_PTR(-EINVAL);
+
+ mddev->new_level = 5;
+ mddev->new_layout = ALGORITHM_LEFT_SYMMETRIC;
+ mddev->new_chunk = chunksect << 9;
+
+ return setup_conf(mddev);
+}
+
+static void *raid5_takeover_raid6(mddev_t *mddev)
+{
+ int new_layout;
+
+ switch (mddev->layout) {
+ case ALGORITHM_LEFT_ASYMMETRIC_6:
+ new_layout = ALGORITHM_LEFT_ASYMMETRIC;
+ break;
+ case ALGORITHM_RIGHT_ASYMMETRIC_6:
+ new_layout = ALGORITHM_RIGHT_ASYMMETRIC;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC_6:
+ new_layout = ALGORITHM_LEFT_SYMMETRIC;
+ break;
+ case ALGORITHM_RIGHT_SYMMETRIC_6:
+ new_layout = ALGORITHM_RIGHT_SYMMETRIC;
+ break;
+ case ALGORITHM_PARITY_0_6:
+ new_layout = ALGORITHM_PARITY_0;
+ break;
+ case ALGORITHM_PARITY_N:
+ new_layout = ALGORITHM_PARITY_N;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+ mddev->new_level = 5;
+ mddev->new_layout = new_layout;
+ mddev->delta_disks = -1;
+ mddev->raid_disks -= 1;
+ return setup_conf(mddev);
+}
+
+
+static int raid5_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+ /* For a 2-drive array, the layout and chunk size can be changed
+ * immediately as not restriping is needed.
+ * For larger arrays we record the new value - after validation
+ * to be used by a reshape pass.
+ */
+ raid5_conf_t *conf = mddev_to_conf(mddev);
+
+ if (new_layout >= 0 && !algorithm_valid_raid5(new_layout))
+ return -EINVAL;
+ if (new_chunk > 0) {
+ if (new_chunk & (new_chunk-1))
+ /* not a power of 2 */
+ return -EINVAL;
+ if (new_chunk < PAGE_SIZE)
+ return -EINVAL;
+ if (mddev->array_sectors & ((new_chunk>>9)-1))
+ /* not factor of array size */
+ return -EINVAL;
+ }
+
+ /* They look valid */
+
+ if (mddev->raid_disks == 2) {
+
+ if (new_layout >= 0) {
+ conf->algorithm = new_layout;
+ mddev->layout = mddev->new_layout = new_layout;
+ }
+ if (new_chunk > 0) {
+ conf->chunk_size = new_chunk;
+ mddev->chunk_size = mddev->new_chunk = new_chunk;
+ }
+ set_bit(MD_CHANGE_DEVS, &mddev->flags);
+ md_wakeup_thread(mddev->thread);
+ } else {
+ if (new_layout >= 0)
+ mddev->new_layout = new_layout;
+ if (new_chunk > 0)
+ mddev->new_chunk = new_chunk;
+ }
+ return 0;
+}
+
+static int raid6_reconfig(mddev_t *mddev, int new_layout, int new_chunk)
+{
+ if (new_layout >= 0 && !algorithm_valid_raid6(new_layout))
+ return -EINVAL;
+ if (new_chunk > 0) {
+ if (new_chunk & (new_chunk-1))
+ /* not a power of 2 */
+ return -EINVAL;
+ if (new_chunk < PAGE_SIZE)
+ return -EINVAL;
+ if (mddev->array_sectors & ((new_chunk>>9)-1))
+ /* not factor of array size */
+ return -EINVAL;
+ }
+
+ /* They look valid */
+
+ if (new_layout >= 0)
+ mddev->new_layout = new_layout;
+ if (new_chunk > 0)
+ mddev->new_chunk = new_chunk;
+
+ return 0;
+}
+
+static void *raid5_takeover(mddev_t *mddev)
+{
+ /* raid5 can take over:
+ * raid0 - if all devices are the same - make it a raid4 layout
+ * raid1 - if there are two drives. We need to know the chunk size
+ * raid4 - trivial - just use a raid4 layout.
+ * raid6 - Providing it is a *_6 layout
+ *
+ * For now, just do raid1
+ */
+
+ if (mddev->level == 1)
+ return raid5_takeover_raid1(mddev);
+ if (mddev->level == 4) {
+ mddev->new_layout = ALGORITHM_PARITY_N;
+ mddev->new_level = 5;
+ return setup_conf(mddev);
+ }
+ if (mddev->level == 6)
+ return raid5_takeover_raid6(mddev);
+
+ return ERR_PTR(-EINVAL);
+}
+
+
+static struct mdk_personality raid5_personality;
+
+static void *raid6_takeover(mddev_t *mddev)
+{
+ /* Currently can only take over a raid5. We map the
+ * personality to an equivalent raid6 personality
+ * with the Q block at the end.
+ */
+ int new_layout;
+
+ if (mddev->pers != &raid5_personality)
+ return ERR_PTR(-EINVAL);
+ if (mddev->degraded > 1)
+ return ERR_PTR(-EINVAL);
+ if (mddev->raid_disks > 253)
+ return ERR_PTR(-EINVAL);
+ if (mddev->raid_disks < 3)
+ return ERR_PTR(-EINVAL);
+
+ switch (mddev->layout) {
+ case ALGORITHM_LEFT_ASYMMETRIC:
+ new_layout = ALGORITHM_LEFT_ASYMMETRIC_6;
+ break;
+ case ALGORITHM_RIGHT_ASYMMETRIC:
+ new_layout = ALGORITHM_RIGHT_ASYMMETRIC_6;
+ break;
+ case ALGORITHM_LEFT_SYMMETRIC:
+ new_layout = ALGORITHM_LEFT_SYMMETRIC_6;
+ break;
+ case ALGORITHM_RIGHT_SYMMETRIC:
+ new_layout = ALGORITHM_RIGHT_SYMMETRIC_6;
+ break;
+ case ALGORITHM_PARITY_0:
+ new_layout = ALGORITHM_PARITY_0_6;
+ break;
+ case ALGORITHM_PARITY_N:
+ new_layout = ALGORITHM_PARITY_N;
+ break;
+ default:
+ return ERR_PTR(-EINVAL);
+ }
+ mddev->new_level = 6;
+ mddev->new_layout = new_layout;
+ mddev->delta_disks = 1;
+ mddev->raid_disks += 1;
+ return setup_conf(mddev);
+}
+
+
static struct mdk_personality raid6_personality =
{
.name = "raid6",
@@ -4687,11 +5304,13 @@ static struct mdk_personality raid6_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
+ .takeover = raid6_takeover,
+ .reconfig = raid6_reconfig,
};
static struct mdk_personality raid5_personality =
{
@@ -4708,11 +5327,13 @@ static struct mdk_personality raid5_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
+ .takeover = raid5_takeover,
+ .reconfig = raid5_reconfig,
};
static struct mdk_personality raid4_personality =
@@ -4730,20 +5351,15 @@ static struct mdk_personality raid4_personality =
.spare_active = raid5_spare_active,
.sync_request = sync_request,
.resize = raid5_resize,
-#ifdef CONFIG_MD_RAID5_RESHAPE
+ .size = raid5_size,
.check_reshape = raid5_check_reshape,
.start_reshape = raid5_start_reshape,
-#endif
+ .finish_reshape = raid5_finish_reshape,
.quiesce = raid5_quiesce,
};
static int __init raid5_init(void)
{
- int e;
-
- e = raid6_select_algo();
- if ( e )
- return e;
register_md_personality(&raid6_personality);
register_md_personality(&raid5_personality);
register_md_personality(&raid4_personality);
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
new file mode 100644
index 00000000000..52ba99954de
--- /dev/null
+++ b/drivers/md/raid5.h
@@ -0,0 +1,474 @@
+#ifndef _RAID5_H
+#define _RAID5_H
+
+#include <linux/raid/xor.h>
+
+/*
+ *
+ * Each stripe contains one buffer per disc. Each buffer can be in
+ * one of a number of states stored in "flags". Changes between
+ * these states happen *almost* exclusively under a per-stripe
+ * spinlock. Some very specific changes can happen in bi_end_io, and
+ * these are not protected by the spin lock.
+ *
+ * The flag bits that are used to represent these states are:
+ * R5_UPTODATE and R5_LOCKED
+ *
+ * State Empty == !UPTODATE, !LOCK
+ * We have no data, and there is no active request
+ * State Want == !UPTODATE, LOCK
+ * A read request is being submitted for this block
+ * State Dirty == UPTODATE, LOCK
+ * Some new data is in this buffer, and it is being written out
+ * State Clean == UPTODATE, !LOCK
+ * We have valid data which is the same as on disc
+ *
+ * The possible state transitions are:
+ *
+ * Empty -> Want - on read or write to get old data for parity calc
+ * Empty -> Dirty - on compute_parity to satisfy write/sync request.(RECONSTRUCT_WRITE)
+ * Empty -> Clean - on compute_block when computing a block for failed drive
+ * Want -> Empty - on failed read
+ * Want -> Clean - on successful completion of read request
+ * Dirty -> Clean - on successful completion of write request
+ * Dirty -> Clean - on failed write
+ * Clean -> Dirty - on compute_parity to satisfy write/sync (RECONSTRUCT or RMW)
+ *
+ * The Want->Empty, Want->Clean, Dirty->Clean, transitions
+ * all happen in b_end_io at interrupt time.
+ * Each sets the Uptodate bit before releasing the Lock bit.
+ * This leaves one multi-stage transition:
+ * Want->Dirty->Clean
+ * This is safe because thinking that a Clean buffer is actually dirty
+ * will at worst delay some action, and the stripe will be scheduled
+ * for attention after the transition is complete.
+ *
+ * There is one possibility that is not covered by these states. That
+ * is if one drive has failed and there is a spare being rebuilt. We
+ * can't distinguish between a clean block that has been generated
+ * from parity calculations, and a clean block that has been
+ * successfully written to the spare ( or to parity when resyncing).
+ * To distingush these states we have a stripe bit STRIPE_INSYNC that
+ * is set whenever a write is scheduled to the spare, or to the parity
+ * disc if there is no spare. A sync request clears this bit, and
+ * when we find it set with no buffers locked, we know the sync is
+ * complete.
+ *
+ * Buffers for the md device that arrive via make_request are attached
+ * to the appropriate stripe in one of two lists linked on b_reqnext.
+ * One list (bh_read) for read requests, one (bh_write) for write.
+ * There should never be more than one buffer on the two lists
+ * together, but we are not guaranteed of that so we allow for more.
+ *
+ * If a buffer is on the read list when the associated cache buffer is
+ * Uptodate, the data is copied into the read buffer and it's b_end_io
+ * routine is called. This may happen in the end_request routine only
+ * if the buffer has just successfully been read. end_request should
+ * remove the buffers from the list and then set the Uptodate bit on
+ * the buffer. Other threads may do this only if they first check
+ * that the Uptodate bit is set. Once they have checked that they may
+ * take buffers off the read queue.
+ *
+ * When a buffer on the write list is committed for write it is copied
+ * into the cache buffer, which is then marked dirty, and moved onto a
+ * third list, the written list (bh_written). Once both the parity
+ * block and the cached buffer are successfully written, any buffer on
+ * a written list can be returned with b_end_io.
+ *
+ * The write list and read list both act as fifos. The read list is
+ * protected by the device_lock. The write and written lists are
+ * protected by the stripe lock. The device_lock, which can be
+ * claimed while the stipe lock is held, is only for list
+ * manipulations and will only be held for a very short time. It can
+ * be claimed from interrupts.
+ *
+ *
+ * Stripes in the stripe cache can be on one of two lists (or on
+ * neither). The "inactive_list" contains stripes which are not
+ * currently being used for any request. They can freely be reused
+ * for another stripe. The "handle_list" contains stripes that need
+ * to be handled in some way. Both of these are fifo queues. Each
+ * stripe is also (potentially) linked to a hash bucket in the hash
+ * table so that it can be found by sector number. Stripes that are
+ * not hashed must be on the inactive_list, and will normally be at
+ * the front. All stripes start life this way.
+ *
+ * The inactive_list, handle_list and hash bucket lists are all protected by the
+ * device_lock.
+ * - stripes on the inactive_list never have their stripe_lock held.
+ * - stripes have a reference counter. If count==0, they are on a list.
+ * - If a stripe might need handling, STRIPE_HANDLE is set.
+ * - When refcount reaches zero, then if STRIPE_HANDLE it is put on
+ * handle_list else inactive_list
+ *
+ * This, combined with the fact that STRIPE_HANDLE is only ever
+ * cleared while a stripe has a non-zero count means that if the
+ * refcount is 0 and STRIPE_HANDLE is set, then it is on the
+ * handle_list and if recount is 0 and STRIPE_HANDLE is not set, then
+ * the stripe is on inactive_list.
+ *
+ * The possible transitions are:
+ * activate an unhashed/inactive stripe (get_active_stripe())
+ * lockdev check-hash unlink-stripe cnt++ clean-stripe hash-stripe unlockdev
+ * activate a hashed, possibly active stripe (get_active_stripe())
+ * lockdev check-hash if(!cnt++)unlink-stripe unlockdev
+ * attach a request to an active stripe (add_stripe_bh())
+ * lockdev attach-buffer unlockdev
+ * handle a stripe (handle_stripe())
+ * lockstripe clrSTRIPE_HANDLE ...
+ * (lockdev check-buffers unlockdev) ..
+ * change-state ..
+ * record io/ops needed unlockstripe schedule io/ops
+ * release an active stripe (release_stripe())
+ * lockdev if (!--cnt) { if STRIPE_HANDLE, add to handle_list else add to inactive-list } unlockdev
+ *
+ * The refcount counts each thread that have activated the stripe,
+ * plus raid5d if it is handling it, plus one for each active request
+ * on a cached buffer, and plus one if the stripe is undergoing stripe
+ * operations.
+ *
+ * Stripe operations are performed outside the stripe lock,
+ * the stripe operations are:
+ * -copying data between the stripe cache and user application buffers
+ * -computing blocks to save a disk access, or to recover a missing block
+ * -updating the parity on a write operation (reconstruct write and
+ * read-modify-write)
+ * -checking parity correctness
+ * -running i/o to disk
+ * These operations are carried out by raid5_run_ops which uses the async_tx
+ * api to (optionally) offload operations to dedicated hardware engines.
+ * When requesting an operation handle_stripe sets the pending bit for the
+ * operation and increments the count. raid5_run_ops is then run whenever
+ * the count is non-zero.
+ * There are some critical dependencies between the operations that prevent some
+ * from being requested while another is in flight.
+ * 1/ Parity check operations destroy the in cache version of the parity block,
+ * so we prevent parity dependent operations like writes and compute_blocks
+ * from starting while a check is in progress. Some dma engines can perform
+ * the check without damaging the parity block, in these cases the parity
+ * block is re-marked up to date (assuming the check was successful) and is
+ * not re-read from disk.
+ * 2/ When a write operation is requested we immediately lock the affected
+ * blocks, and mark them as not up to date. This causes new read requests
+ * to be held off, as well as parity checks and compute block operations.
+ * 3/ Once a compute block operation has been requested handle_stripe treats
+ * that block as if it is up to date. raid5_run_ops guaruntees that any
+ * operation that is dependent on the compute block result is initiated after
+ * the compute block completes.
+ */
+
+/*
+ * Operations state - intermediate states that are visible outside of sh->lock
+ * In general _idle indicates nothing is running, _run indicates a data
+ * processing operation is active, and _result means the data processing result
+ * is stable and can be acted upon. For simple operations like biofill and
+ * compute that only have an _idle and _run state they are indicated with
+ * sh->state flags (STRIPE_BIOFILL_RUN and STRIPE_COMPUTE_RUN)
+ */
+/**
+ * enum check_states - handles syncing / repairing a stripe
+ * @check_state_idle - check operations are quiesced
+ * @check_state_run - check operation is running
+ * @check_state_result - set outside lock when check result is valid
+ * @check_state_compute_run - check failed and we are repairing
+ * @check_state_compute_result - set outside lock when compute result is valid
+ */
+enum check_states {
+ check_state_idle = 0,
+ check_state_run, /* parity check */
+ check_state_check_result,
+ check_state_compute_run, /* parity repair */
+ check_state_compute_result,
+};
+
+/**
+ * enum reconstruct_states - handles writing or expanding a stripe
+ */
+enum reconstruct_states {
+ reconstruct_state_idle = 0,
+ reconstruct_state_prexor_drain_run, /* prexor-write */
+ reconstruct_state_drain_run, /* write */
+ reconstruct_state_run, /* expand */
+ reconstruct_state_prexor_drain_result,
+ reconstruct_state_drain_result,
+ reconstruct_state_result,
+};
+
+struct stripe_head {
+ struct hlist_node hash;
+ struct list_head lru; /* inactive_list or handle_list */
+ struct raid5_private_data *raid_conf;
+ short generation; /* increments with every
+ * reshape */
+ sector_t sector; /* sector of this row */
+ short pd_idx; /* parity disk index */
+ short qd_idx; /* 'Q' disk index for raid6 */
+ short ddf_layout;/* use DDF ordering to calculate Q */
+ unsigned long state; /* state flags */
+ atomic_t count; /* nr of active thread/requests */
+ spinlock_t lock;
+ int bm_seq; /* sequence number for bitmap flushes */
+ int disks; /* disks in stripe */
+ enum check_states check_state;
+ enum reconstruct_states reconstruct_state;
+ /* stripe_operations
+ * @target - STRIPE_OP_COMPUTE_BLK target
+ */
+ struct stripe_operations {
+ int target;
+ u32 zero_sum_result;
+ } ops;
+ struct r5dev {
+ struct bio req;
+ struct bio_vec vec;
+ struct page *page;
+ struct bio *toread, *read, *towrite, *written;
+ sector_t sector; /* sector of this page */
+ unsigned long flags;
+ } dev[1]; /* allocated with extra space depending of RAID geometry */
+};
+
+/* stripe_head_state - collects and tracks the dynamic state of a stripe_head
+ * for handle_stripe. It is only valid under spin_lock(sh->lock);
+ */
+struct stripe_head_state {
+ int syncing, expanding, expanded;
+ int locked, uptodate, to_read, to_write, failed, written;
+ int to_fill, compute, req_compute, non_overwrite;
+ int failed_num;
+ unsigned long ops_request;
+};
+
+/* r6_state - extra state data only relevant to r6 */
+struct r6_state {
+ int p_failed, q_failed, failed_num[2];
+};
+
+/* Flags */
+#define R5_UPTODATE 0 /* page contains current data */
+#define R5_LOCKED 1 /* IO has been submitted on "req" */
+#define R5_OVERWRITE 2 /* towrite covers whole page */
+/* and some that are internal to handle_stripe */
+#define R5_Insync 3 /* rdev && rdev->in_sync at start */
+#define R5_Wantread 4 /* want to schedule a read */
+#define R5_Wantwrite 5
+#define R5_Overlap 7 /* There is a pending overlapping request on this block */
+#define R5_ReadError 8 /* seen a read error here recently */
+#define R5_ReWrite 9 /* have tried to over-write the readerror */
+
+#define R5_Expanded 10 /* This block now has post-expand data */
+#define R5_Wantcompute 11 /* compute_block in progress treat as
+ * uptodate
+ */
+#define R5_Wantfill 12 /* dev->toread contains a bio that needs
+ * filling
+ */
+#define R5_Wantdrain 13 /* dev->towrite needs to be drained */
+/*
+ * Write method
+ */
+#define RECONSTRUCT_WRITE 1
+#define READ_MODIFY_WRITE 2
+/* not a write method, but a compute_parity mode */
+#define CHECK_PARITY 3
+/* Additional compute_parity mode -- updates the parity w/o LOCKING */
+#define UPDATE_PARITY 4
+
+/*
+ * Stripe state
+ */
+#define STRIPE_HANDLE 2
+#define STRIPE_SYNCING 3
+#define STRIPE_INSYNC 4
+#define STRIPE_PREREAD_ACTIVE 5
+#define STRIPE_DELAYED 6
+#define STRIPE_DEGRADED 7
+#define STRIPE_BIT_DELAY 8
+#define STRIPE_EXPANDING 9
+#define STRIPE_EXPAND_SOURCE 10
+#define STRIPE_EXPAND_READY 11
+#define STRIPE_IO_STARTED 12 /* do not count towards 'bypass_count' */
+#define STRIPE_FULL_WRITE 13 /* all blocks are set to be overwritten */
+#define STRIPE_BIOFILL_RUN 14
+#define STRIPE_COMPUTE_RUN 15
+/*
+ * Operation request flags
+ */
+#define STRIPE_OP_BIOFILL 0
+#define STRIPE_OP_COMPUTE_BLK 1
+#define STRIPE_OP_PREXOR 2
+#define STRIPE_OP_BIODRAIN 3
+#define STRIPE_OP_POSTXOR 4
+#define STRIPE_OP_CHECK 5
+
+/*
+ * Plugging:
+ *
+ * To improve write throughput, we need to delay the handling of some
+ * stripes until there has been a chance that several write requests
+ * for the one stripe have all been collected.
+ * In particular, any write request that would require pre-reading
+ * is put on a "delayed" queue until there are no stripes currently
+ * in a pre-read phase. Further, if the "delayed" queue is empty when
+ * a stripe is put on it then we "plug" the queue and do not process it
+ * until an unplug call is made. (the unplug_io_fn() is called).
+ *
+ * When preread is initiated on a stripe, we set PREREAD_ACTIVE and add
+ * it to the count of prereading stripes.
+ * When write is initiated, or the stripe refcnt == 0 (just in case) we
+ * clear the PREREAD_ACTIVE flag and decrement the count
+ * Whenever the 'handle' queue is empty and the device is not plugged, we
+ * move any strips from delayed to handle and clear the DELAYED flag and set
+ * PREREAD_ACTIVE.
+ * In stripe_handle, if we find pre-reading is necessary, we do it if
+ * PREREAD_ACTIVE is set, else we set DELAYED which will send it to the delayed queue.
+ * HANDLE gets cleared if stripe_handle leave nothing locked.
+ */
+
+
+struct disk_info {
+ mdk_rdev_t *rdev;
+};
+
+struct raid5_private_data {
+ struct hlist_head *stripe_hashtbl;
+ mddev_t *mddev;
+ struct disk_info *spare;
+ int chunk_size, level, algorithm;
+ int max_degraded;
+ int raid_disks;
+ int max_nr_stripes;
+
+ /* reshape_progress is the leading edge of a 'reshape'
+ * It has value MaxSector when no reshape is happening
+ * If delta_disks < 0, it is the last sector we started work on,
+ * else is it the next sector to work on.
+ */
+ sector_t reshape_progress;
+ /* reshape_safe is the trailing edge of a reshape. We know that
+ * before (or after) this address, all reshape has completed.
+ */
+ sector_t reshape_safe;
+ int previous_raid_disks;
+ int prev_chunk, prev_algo;
+ short generation; /* increments with every reshape */
+ unsigned long reshape_checkpoint; /* Time we last updated
+ * metadata */
+
+ struct list_head handle_list; /* stripes needing handling */
+ struct list_head hold_list; /* preread ready stripes */
+ struct list_head delayed_list; /* stripes that have plugged requests */
+ struct list_head bitmap_list; /* stripes delaying awaiting bitmap update */
+ struct bio *retry_read_aligned; /* currently retrying aligned bios */
+ struct bio *retry_read_aligned_list; /* aligned bios retry list */
+ atomic_t preread_active_stripes; /* stripes with scheduled io */
+ atomic_t active_aligned_reads;
+ atomic_t pending_full_writes; /* full write backlog */
+ int bypass_count; /* bypassed prereads */
+ int bypass_threshold; /* preread nice */
+ struct list_head *last_hold; /* detect hold_list promotions */
+
+ atomic_t reshape_stripes; /* stripes with pending writes for reshape */
+ /* unfortunately we need two cache names as we temporarily have
+ * two caches.
+ */
+ int active_name;
+ char cache_name[2][20];
+ struct kmem_cache *slab_cache; /* for allocating stripes */
+
+ int seq_flush, seq_write;
+ int quiesce;
+
+ int fullsync; /* set to 1 if a full sync is needed,
+ * (fresh device added).
+ * Cleared when a sync completes.
+ */
+
+ struct page *spare_page; /* Used when checking P/Q in raid6 */
+
+ /*
+ * Free stripes pool
+ */
+ atomic_t active_stripes;
+ struct list_head inactive_list;
+ wait_queue_head_t wait_for_stripe;
+ wait_queue_head_t wait_for_overlap;
+ int inactive_blocked; /* release of inactive stripes blocked,
+ * waiting for 25% to be free
+ */
+ int pool_size; /* number of disks in stripeheads in pool */
+ spinlock_t device_lock;
+ struct disk_info *disks;
+
+ /* When taking over an array from a different personality, we store
+ * the new thread here until we fully activate the array.
+ */
+ struct mdk_thread_s *thread;
+};
+
+typedef struct raid5_private_data raid5_conf_t;
+
+#define mddev_to_conf(mddev) ((raid5_conf_t *) mddev->private)
+
+/*
+ * Our supported algorithms
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC 0 /* Rotating Parity N with Data Restart */
+#define ALGORITHM_RIGHT_ASYMMETRIC 1 /* Rotating Parity 0 with Data Restart */
+#define ALGORITHM_LEFT_SYMMETRIC 2 /* Rotating Parity N with Data Continuation */
+#define ALGORITHM_RIGHT_SYMMETRIC 3 /* Rotating Parity 0 with Data Continuation */
+
+/* Define non-rotating (raid4) algorithms. These allow
+ * conversion of raid4 to raid5.
+ */
+#define ALGORITHM_PARITY_0 4 /* P or P,Q are initial devices */
+#define ALGORITHM_PARITY_N 5 /* P or P,Q are final devices. */
+
+/* DDF RAID6 layouts differ from md/raid6 layouts in two ways.
+ * Firstly, the exact positioning of the parity block is slightly
+ * different between the 'LEFT_*' modes of md and the "_N_*" modes
+ * of DDF.
+ * Secondly, or order of datablocks over which the Q syndrome is computed
+ * is different.
+ * Consequently we have different layouts for DDF/raid6 than md/raid6.
+ * These layouts are from the DDFv1.2 spec.
+ * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but
+ * leaves RLQ=3 as 'Vendor Specific'
+ */
+
+#define ALGORITHM_ROTATING_ZERO_RESTART 8 /* DDF PRL=6 RLQ=1 */
+#define ALGORITHM_ROTATING_N_RESTART 9 /* DDF PRL=6 RLQ=2 */
+#define ALGORITHM_ROTATING_N_CONTINUE 10 /*DDF PRL=6 RLQ=3 */
+
+
+/* For every RAID5 algorithm we define a RAID6 algorithm
+ * with exactly the same layout for data and parity, and
+ * with the Q block always on the last device (N-1).
+ * This allows trivial conversion from RAID5 to RAID6
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC_6 16
+#define ALGORITHM_RIGHT_ASYMMETRIC_6 17
+#define ALGORITHM_LEFT_SYMMETRIC_6 18
+#define ALGORITHM_RIGHT_SYMMETRIC_6 19
+#define ALGORITHM_PARITY_0_6 20
+#define ALGORITHM_PARITY_N_6 ALGORITHM_PARITY_N
+
+static inline int algorithm_valid_raid5(int layout)
+{
+ return (layout >= 0) &&
+ (layout <= 5);
+}
+static inline int algorithm_valid_raid6(int layout)
+{
+ return (layout >= 0 && layout <= 5)
+ ||
+ (layout == 8 || layout == 10)
+ ||
+ (layout >= 16 && layout <= 20);
+}
+
+static inline int algorithm_is_DDF(int layout)
+{
+ return layout >= 8 && layout <= 10;
+}
+#endif
diff --git a/drivers/md/raid6.h b/drivers/md/raid6.h
deleted file mode 100644
index 98dcde88470..00000000000
--- a/drivers/md/raid6.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* -*- linux-c -*- ------------------------------------------------------- *
- *
- * Copyright 2003 H. Peter Anvin - 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, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
- * (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-#ifndef LINUX_RAID_RAID6_H
-#define LINUX_RAID_RAID6_H
-
-#ifdef __KERNEL__
-
-/* Set to 1 to use kernel-wide empty_zero_page */
-#define RAID6_USE_EMPTY_ZERO_PAGE 0
-
-#include <linux/raid/md.h>
-#include <linux/raid/raid5.h>
-
-typedef raid5_conf_t raid6_conf_t; /* Same configuration */
-
-/* Additional compute_parity mode -- updates the parity w/o LOCKING */
-#define UPDATE_PARITY 4
-
-/* We need a pre-zeroed page... if we don't want to use the kernel-provided
- one define it here */
-#if RAID6_USE_EMPTY_ZERO_PAGE
-# define raid6_empty_zero_page empty_zero_page
-#else
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-#endif
-
-#else /* ! __KERNEL__ */
-/* Used for testing in user space */
-
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-/* Not standard, but glibc defines it */
-#define BITS_PER_LONG __WORDSIZE
-
-typedef uint8_t u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE 4096
-#endif
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-
-#define __init
-#define __exit
-#define __attribute_const__ __attribute__((const))
-#define noinline __attribute__((noinline))
-
-#define preempt_enable()
-#define preempt_disable()
-#define cpu_has_feature(x) 1
-#define enable_kernel_altivec()
-#define disable_kernel_altivec()
-
-#endif /* __KERNEL__ */
-
-/* Routine choices */
-struct raid6_calls {
- void (*gen_syndrome)(int, size_t, void **);
- int (*valid)(void); /* Returns 1 if this routine set is usable */
- const char *name; /* Name of this routine set */
- int prefer; /* Has special performance attribute */
-};
-
-/* Selected algorithm */
-extern struct raid6_calls raid6_call;
-
-/* Algorithm list */
-extern const struct raid6_calls * const raid6_algos[];
-int raid6_select_algo(void);
-
-/* Return values from chk_syndrome */
-#define RAID6_OK 0
-#define RAID6_P_BAD 1
-#define RAID6_Q_BAD 2
-#define RAID6_PQ_BAD 3
-
-/* Galois field tables */
-extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256)));
-extern const u8 raid6_gfexp[256] __attribute__((aligned(256)));
-extern const u8 raid6_gfinv[256] __attribute__((aligned(256)));
-extern const u8 raid6_gfexi[256] __attribute__((aligned(256)));
-
-/* Recovery routines */
-void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
-void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-
-/* Some definitions to allow code to be compiled for testing in userspace */
-#ifndef __KERNEL__
-
-# define jiffies raid6_jiffies()
-# define printk printf
-# define GFP_KERNEL 0
-# define __get_free_pages(x,y) ((unsigned long)mmap(NULL, PAGE_SIZE << (y), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0))
-# define free_pages(x,y) munmap((void *)(x), (y)*PAGE_SIZE)
-
-static inline void cpu_relax(void)
-{
- /* Nothing */
-}
-
-#undef HZ
-#define HZ 1000
-static inline uint32_t raid6_jiffies(void)
-{
- struct timeval tv;
- gettimeofday(&tv, NULL);
- return tv.tv_sec*1000 + tv.tv_usec/1000;
-}
-
-#endif /* ! __KERNEL__ */
-
-#endif /* LINUX_RAID_RAID6_H */
diff --git a/drivers/md/raid6algos.c b/drivers/md/raid6algos.c
index 21987e3dbe6..866215ac7f2 100644
--- a/drivers/md/raid6algos.c
+++ b/drivers/md/raid6algos.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -16,13 +16,20 @@
* Algorithm list and algorithm selection for RAID-6
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
#ifndef __KERNEL__
#include <sys/mman.h>
#include <stdio.h>
+#else
+#if !RAID6_USE_EMPTY_ZERO_PAGE
+/* In .bss so it's zeroed */
+const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
+EXPORT_SYMBOL(raid6_empty_zero_page);
+#endif
#endif
struct raid6_calls raid6_call;
+EXPORT_SYMBOL_GPL(raid6_call);
/* Various routine sets */
extern const struct raid6_calls raid6_intx1;
@@ -79,6 +86,7 @@ const struct raid6_calls * const raid6_algos[] = {
#else
/* Need more time to be stable in userspace */
#define RAID6_TIME_JIFFIES_LG2 9
+#define time_before(x, y) ((x) < (y))
#endif
/* Try to pick the best algorithm */
@@ -152,3 +160,12 @@ int __init raid6_select_algo(void)
return best ? 0 : -EINVAL;
}
+
+static void raid6_exit(void)
+{
+ do { } while (0);
+}
+
+subsys_initcall(raid6_select_algo);
+module_exit(raid6_exit);
+MODULE_LICENSE("GPL");
diff --git a/drivers/md/raid6altivec.uc b/drivers/md/raid6altivec.uc
index b9afd35b881..699dfeee494 100644
--- a/drivers/md/raid6altivec.uc
+++ b/drivers/md/raid6altivec.uc
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -22,7 +22,7 @@
* bracked this with preempt_disable/enable or in a lock)
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
#ifdef CONFIG_ALTIVEC
diff --git a/drivers/md/raid6int.uc b/drivers/md/raid6int.uc
index ad004cee0e2..f9bf9cba357 100644
--- a/drivers/md/raid6int.uc
+++ b/drivers/md/raid6int.uc
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
* This file is postprocessed using unroll.pl
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
/*
* This is the C data type to use
diff --git a/drivers/md/raid6mmx.c b/drivers/md/raid6mmx.c
index d4e4a1bd70a..e7f6c13132b 100644
--- a/drivers/md/raid6mmx.c
+++ b/drivers/md/raid6mmx.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
#if defined(__i386__) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
/* Shared with raid6sse1.c */
diff --git a/drivers/md/raid6recov.c b/drivers/md/raid6recov.c
index a8c4d9451bd..2609f00e0d6 100644
--- a/drivers/md/raid6recov.c
+++ b/drivers/md/raid6recov.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -18,7 +18,7 @@
* the syndrome.)
*/
-#include "raid6.h"
+#include <linux/raid/pq.h>
/* Recover two failed data blocks. */
void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
@@ -63,9 +63,7 @@ void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
p++; q++;
}
}
-
-
-
+EXPORT_SYMBOL_GPL(raid6_2data_recov);
/* Recover failure of one data block plus the P block */
void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
@@ -97,9 +95,10 @@ void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
q++; dq++;
}
}
+EXPORT_SYMBOL_GPL(raid6_datap_recov);
-
-#ifndef __KERNEL__ /* Testing only */
+#ifndef __KERNEL__
+/* Testing only */
/* Recover two failed blocks. */
void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
diff --git a/drivers/md/raid6sse1.c b/drivers/md/raid6sse1.c
index 0666237276f..b274dd5eab8 100644
--- a/drivers/md/raid6sse1.c
+++ b/drivers/md/raid6sse1.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -23,7 +23,7 @@
#if defined(__i386__) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
/* Defined in raid6mmx.c */
diff --git a/drivers/md/raid6sse2.c b/drivers/md/raid6sse2.c
index b034ad86803..6ed6c6c0389 100644
--- a/drivers/md/raid6sse2.c
+++ b/drivers/md/raid6sse2.c
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
@@ -19,7 +19,7 @@
#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
-#include "raid6.h"
+#include <linux/raid/pq.h>
#include "raid6x86.h"
static const struct raid6_sse_constants {
diff --git a/drivers/md/raid6test/Makefile b/drivers/md/raid6test/Makefile
index 78e0396adf2..58ffdf4f516 100644
--- a/drivers/md/raid6test/Makefile
+++ b/drivers/md/raid6test/Makefile
@@ -5,7 +5,7 @@
CC = gcc
OPTFLAGS = -O2 # Adjust as desired
-CFLAGS = -I.. -g $(OPTFLAGS)
+CFLAGS = -I.. -I ../../../include -g $(OPTFLAGS)
LD = ld
PERL = perl
AR = ar
diff --git a/drivers/md/raid6test/test.c b/drivers/md/raid6test/test.c
index 559cc41b258..7a930318b17 100644
--- a/drivers/md/raid6test/test.c
+++ b/drivers/md/raid6test/test.c
@@ -17,7 +17,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include "raid6.h"
+#include <linux/raid/pq.h>
#define NDISKS 16 /* Including P and Q */
diff --git a/drivers/md/raid6x86.h b/drivers/md/raid6x86.h
index 99fea7a70ca..4c22c156855 100644
--- a/drivers/md/raid6x86.h
+++ b/drivers/md/raid6x86.h
@@ -5,7 +5,7 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, Inc., 53 Temple Place Ste 330,
- * Bostom MA 02111-1307, USA; either version 2 of the License, or
+ * Boston MA 02111-1307, USA; either version 2 of the License, or
* (at your option) any later version; incorporated herein by reference.
*
* ----------------------------------------------------------------------- */
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 93ea201f426..223c36ede5a 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -117,7 +117,7 @@ source "drivers/media/dvb/Kconfig"
config DAB
boolean "DAB adapters"
---help---
- Allow selecting support for for Digital Audio Broadcasting (DAB)
+ Allow selecting support for Digital Audio Broadcasting (DAB)
Receiver adapters.
if DAB
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index d8229a0e9a9..3fe158ac7bb 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -153,6 +153,65 @@ IR_KEYTAB_TYPE ir_codes_avermedia_m135a[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_avermedia_m135a);
+/* Oldrich Jedlicka <oldium.pro@seznam.cz> */
+IR_KEYTAB_TYPE ir_codes_avermedia_cardbus[IR_KEYTAB_SIZE] = {
+ [0x00] = KEY_POWER,
+ [0x01] = KEY_TUNER, /* TV/FM */
+ [0x03] = KEY_TEXT, /* Teletext */
+ [0x04] = KEY_EPG,
+ [0x05] = KEY_1,
+ [0x06] = KEY_2,
+ [0x07] = KEY_3,
+ [0x08] = KEY_AUDIO,
+ [0x09] = KEY_4,
+ [0x0a] = KEY_5,
+ [0x0b] = KEY_6,
+ [0x0c] = KEY_ZOOM, /* Full screen */
+ [0x0d] = KEY_7,
+ [0x0e] = KEY_8,
+ [0x0f] = KEY_9,
+ [0x10] = KEY_PAGEUP, /* 16-CH PREV */
+ [0x11] = KEY_0,
+ [0x12] = KEY_INFO,
+ [0x13] = KEY_AGAIN, /* CH RTN - channel return */
+ [0x14] = KEY_MUTE,
+ [0x15] = KEY_EDIT, /* Autoscan */
+ [0x17] = KEY_SAVE, /* Screenshot */
+ [0x18] = KEY_PLAYPAUSE,
+ [0x19] = KEY_RECORD,
+ [0x1a] = KEY_PLAY,
+ [0x1b] = KEY_STOP,
+ [0x1c] = KEY_FASTFORWARD,
+ [0x1d] = KEY_REWIND,
+ [0x1e] = KEY_VOLUMEDOWN,
+ [0x1f] = KEY_VOLUMEUP,
+ [0x22] = KEY_SLEEP, /* Sleep */
+ [0x23] = KEY_ZOOM, /* Aspect */
+ [0x26] = KEY_SCREEN, /* Pos */
+ [0x27] = KEY_ANGLE, /* Size */
+ [0x28] = KEY_SELECT, /* Select */
+ [0x29] = KEY_BLUE, /* Blue/Picture */
+ [0x2a] = KEY_BACKSPACE, /* Back */
+ [0x2b] = KEY_MEDIA, /* PIP (Picture-in-picture) */
+ [0x2c] = KEY_DOWN,
+ [0x2e] = KEY_DOT,
+ [0x2f] = KEY_TV, /* Live TV */
+ [0x32] = KEY_LEFT,
+ [0x33] = KEY_CLEAR, /* Clear */
+ [0x35] = KEY_RED, /* Red/TV */
+ [0x36] = KEY_UP,
+ [0x37] = KEY_HOME, /* Home */
+ [0x39] = KEY_GREEN, /* Green/Video */
+ [0x3d] = KEY_YELLOW, /* Yellow/Music */
+ [0x3e] = KEY_OK, /* Ok */
+ [0x3f] = KEY_RIGHT,
+ [0x40] = KEY_NEXT, /* Next */
+ [0x41] = KEY_PREVIOUS, /* Previous */
+ [0x42] = KEY_CHANNELDOWN, /* Channel down */
+ [0x43] = KEY_CHANNELUP /* Channel up */
+};
+EXPORT_SYMBOL_GPL(ir_codes_avermedia_cardbus);
+
/* Attila Kondoros <attila.kondoros@chello.hu> */
IR_KEYTAB_TYPE ir_codes_apac_viewcomp[IR_KEYTAB_SIZE] = {
@@ -2452,6 +2511,55 @@ IR_KEYTAB_TYPE ir_codes_kworld_plus_tv_analog[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_kworld_plus_tv_analog);
+/* Kaiomy TVnPC U2
+ Mauro Carvalho Chehab <mchehab@infradead.org>
+ */
+IR_KEYTAB_TYPE ir_codes_kaiomy[IR_KEYTAB_SIZE] = {
+ [0x43] = KEY_POWER2,
+ [0x01] = KEY_LIST,
+ [0x0b] = KEY_ZOOM,
+ [0x03] = KEY_POWER,
+
+ [0x04] = KEY_1,
+ [0x08] = KEY_2,
+ [0x02] = KEY_3,
+
+ [0x0f] = KEY_4,
+ [0x05] = KEY_5,
+ [0x06] = KEY_6,
+
+ [0x0c] = KEY_7,
+ [0x0d] = KEY_8,
+ [0x0a] = KEY_9,
+
+ [0x11] = KEY_0,
+
+ [0x09] = KEY_CHANNELUP,
+ [0x07] = KEY_CHANNELDOWN,
+
+ [0x0e] = KEY_VOLUMEUP,
+ [0x13] = KEY_VOLUMEDOWN,
+
+ [0x10] = KEY_HOME,
+ [0x12] = KEY_ENTER,
+
+ [0x14] = KEY_RECORD,
+ [0x15] = KEY_STOP,
+ [0x16] = KEY_PLAY,
+ [0x17] = KEY_MUTE,
+
+ [0x18] = KEY_UP,
+ [0x19] = KEY_DOWN,
+ [0x1a] = KEY_LEFT,
+ [0x1b] = KEY_RIGHT,
+
+ [0x1c] = KEY_RED,
+ [0x1d] = KEY_GREEN,
+ [0x1e] = KEY_YELLOW,
+ [0x1f] = KEY_BLUE,
+};
+EXPORT_SYMBOL_GPL(ir_codes_kaiomy);
+
IR_KEYTAB_TYPE ir_codes_avermedia_a16d[IR_KEYTAB_SIZE] = {
[0x20] = KEY_LIST,
[0x00] = KEY_POWER,
@@ -2604,3 +2712,41 @@ IR_KEYTAB_TYPE ir_codes_ati_tv_wonder_hd_600[IR_KEYTAB_SIZE] = {
};
EXPORT_SYMBOL_GPL(ir_codes_ati_tv_wonder_hd_600);
+
+/* DVBWorld remotes
+ Igor M. Liplianin <liplianin@me.by>
+ */
+IR_KEYTAB_TYPE ir_codes_dm1105_nec[IR_KEYTAB_SIZE] = {
+ [0x0a] = KEY_Q, /*power*/
+ [0x0c] = KEY_M, /*mute*/
+ [0x11] = KEY_1,
+ [0x12] = KEY_2,
+ [0x13] = KEY_3,
+ [0x14] = KEY_4,
+ [0x15] = KEY_5,
+ [0x16] = KEY_6,
+ [0x17] = KEY_7,
+ [0x18] = KEY_8,
+ [0x19] = KEY_9,
+ [0x10] = KEY_0,
+ [0x1c] = KEY_PAGEUP, /*ch+*/
+ [0x0f] = KEY_PAGEDOWN, /*ch-*/
+ [0x1a] = KEY_O, /*vol+*/
+ [0x0e] = KEY_Z, /*vol-*/
+ [0x04] = KEY_R, /*rec*/
+ [0x09] = KEY_D, /*fav*/
+ [0x08] = KEY_BACKSPACE, /*rewind*/
+ [0x07] = KEY_A, /*fast*/
+ [0x0b] = KEY_P, /*pause*/
+ [0x02] = KEY_ESC, /*cancel*/
+ [0x03] = KEY_G, /*tab*/
+ [0x00] = KEY_UP, /*up*/
+ [0x1f] = KEY_ENTER, /*ok*/
+ [0x01] = KEY_DOWN, /*down*/
+ [0x05] = KEY_C, /*cap*/
+ [0x06] = KEY_S, /*stop*/
+ [0x40] = KEY_F, /*full*/
+ [0x1e] = KEY_W, /*tvmode*/
+ [0x1b] = KEY_B, /*recall*/
+};
+EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec);
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c
index d599d360da3..982f000a57f 100644
--- a/drivers/media/common/saa7146_core.c
+++ b/drivers/media/common/saa7146_core.c
@@ -452,8 +452,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
INFO(("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x).\n", dev->mem, dev->revision, pci->irq, pci->subsystem_vendor, pci->subsystem_device));
dev->ext = ext;
- pci_set_drvdata(pci, dev);
-
mutex_init(&dev->lock);
spin_lock_init(&dev->int_slock);
spin_lock_init(&dev->slock);
@@ -477,8 +475,12 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
if (ext->attach(dev, pci_ext)) {
DEB_D(("ext->attach() failed for %p. skipping device.\n",dev));
- goto err_unprobe;
+ goto err_free_i2c;
}
+ /* V4L extensions will set the pci drvdata to the v4l2_device in the
+ attach() above. So for those cards that do not use V4L we have to
+ set it explicitly. */
+ pci_set_drvdata(pci, &dev->v4l2_dev);
INIT_LIST_HEAD(&dev->item);
list_add_tail(&dev->item,&saa7146_devices);
@@ -488,8 +490,6 @@ static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent
out:
return err;
-err_unprobe:
- pci_set_drvdata(pci, NULL);
err_free_i2c:
pci_free_consistent(pci, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
dev->d_i2c.dma_handle);
@@ -514,7 +514,8 @@ err_free:
static void saa7146_remove_one(struct pci_dev *pdev)
{
- struct saa7146_dev* dev = pci_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
+ struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
struct {
void *addr;
dma_addr_t dma;
@@ -528,6 +529,8 @@ static void saa7146_remove_one(struct pci_dev *pdev)
DEB_EE(("dev:%p\n",dev));
dev->ext->detach(dev);
+ /* Zero the PCI drvdata after use. */
+ pci_set_drvdata(pdev, NULL);
/* shut down all video dma transfers */
saa7146_write(dev, MC1, 0x00ff0000);
diff --git a/drivers/media/common/saa7146_fops.c b/drivers/media/common/saa7146_fops.c
index cf06f4d10ad..620f655fa9c 100644
--- a/drivers/media/common/saa7146_fops.c
+++ b/drivers/media/common/saa7146_fops.c
@@ -308,14 +308,6 @@ static int fops_release(struct file *file)
return 0;
}
-static long fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-/*
- DEB_EE(("file:%p, cmd:%d, arg:%li\n", file, cmd, arg));
-*/
- return video_usercopy(file, cmd, arg, saa7146_video_do_ioctl);
-}
-
static int fops_mmap(struct file *file, struct vm_area_struct * vma)
{
struct saa7146_fh *fh = file->private_data;
@@ -425,7 +417,7 @@ static const struct v4l2_file_operations video_fops =
.write = fops_write,
.poll = fops_poll,
.mmap = fops_mmap,
- .ioctl = fops_ioctl,
+ .ioctl = video_ioctl2,
};
static void vv_callback(struct saa7146_dev *dev, unsigned long status)
@@ -452,19 +444,22 @@ static void vv_callback(struct saa7146_dev *dev, unsigned long status)
}
}
-static struct video_device device_template =
-{
- .fops = &video_fops,
- .minor = -1,
-};
-
int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
{
- struct saa7146_vv *vv = kzalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
- if( NULL == vv ) {
+ struct saa7146_vv *vv;
+ int err;
+
+ err = v4l2_device_register(&dev->pci->dev, &dev->v4l2_dev);
+ if (err)
+ return err;
+
+ vv = kzalloc(sizeof(struct saa7146_vv), GFP_KERNEL);
+ if (vv == NULL) {
ERR(("out of memory. aborting.\n"));
- return -1;
+ return -ENOMEM;
}
+ ext_vv->ops = saa7146_video_ioctl_ops;
+ ext_vv->core_ops = &saa7146_video_ioctl_ops;
DEB_EE(("dev:%p\n",dev));
@@ -507,6 +502,7 @@ int saa7146_vv_release(struct saa7146_dev* dev)
DEB_EE(("dev:%p\n",dev));
+ v4l2_device_unregister(&dev->v4l2_dev);
pci_free_consistent(dev->pci, SAA7146_CLIPPING_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
kfree(vv);
dev->vv_data = NULL;
@@ -521,6 +517,8 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
{
struct saa7146_vv *vv = dev->vv_data;
struct video_device *vfd;
+ int err;
+ int i;
DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));
@@ -529,16 +527,20 @@ int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
if (vfd == NULL)
return -ENOMEM;
- memcpy(vfd, &device_template, sizeof(struct video_device));
- strlcpy(vfd->name, name, sizeof(vfd->name));
+ vfd->fops = &video_fops;
+ vfd->ioctl_ops = &dev->ext_vv_data->ops;
vfd->release = video_device_release;
+ vfd->tvnorms = 0;
+ for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+ vfd->tvnorms |= dev->ext_vv_data->stds[i].id;
+ strlcpy(vfd->name, name, sizeof(vfd->name));
video_set_drvdata(vfd, dev);
- // fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
- if (video_register_device(vfd, type, -1) < 0) {
+ err = video_register_device(vfd, type, -1);
+ if (err < 0) {
ERR(("cannot register v4l2 device. skipping.\n"));
video_device_release(vfd);
- return -1;
+ return err;
}
if( VFL_TYPE_GRABBER == type ) {
diff --git a/drivers/media/common/saa7146_i2c.c b/drivers/media/common/saa7146_i2c.c
index c11da4d09cd..7e8f5681599 100644
--- a/drivers/media/common/saa7146_i2c.c
+++ b/drivers/media/common/saa7146_i2c.c
@@ -293,7 +293,6 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m
int i = 0, count = 0;
__le32 *buffer = dev->d_i2c.cpu_addr;
int err = 0;
- int address_err = 0;
int short_delay = 0;
if (mutex_lock_interruptible(&dev->i2c_lock))
@@ -333,17 +332,10 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m
i2c address probing, however, and address errors indicate that a
device is really *not* there. retrying in that case
increases the time the device needs to probe greatly, so
- it should be avoided. because of the fact, that only
- analog based cards use irq based i2c transactions (for dvb
- cards, this screwes up other interrupt sources), we bail out
- completely for analog cards after an address error and trust
- the saa7146 address error detection. */
- if ( -EREMOTEIO == err ) {
- if( 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags)) {
- goto out;
- }
- address_err++;
- }
+ it should be avoided. So we bail out in irq mode after an
+ address error and trust the saa7146 address error detection. */
+ if (-EREMOTEIO == err && 0 != (SAA7146_USE_I2C_IRQ & dev->ext->flags))
+ goto out;
DEB_I2C(("error while sending message(s). starting again.\n"));
break;
}
@@ -358,10 +350,9 @@ static int saa7146_i2c_transfer(struct saa7146_dev *dev, const struct i2c_msg *m
} while (err != num && retries--);
- /* if every retry had an address error, exit right away */
- if (address_err == retries) {
+ /* quit if any error occurred */
+ if (err != num)
goto out;
- }
/* if any things had to be read, get the results */
if ( 0 != saa7146_i2c_msg_cleanup(msgs, num, buffer)) {
@@ -390,7 +381,8 @@ out:
/* utility functions */
static int saa7146_i2c_xfer(struct i2c_adapter* adapter, struct i2c_msg *msg, int num)
{
- struct saa7146_dev* dev = i2c_get_adapdata(adapter);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+ struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
/* use helper function to transfer data */
return saa7146_i2c_transfer(dev, msg, num, adapter->retries);
@@ -417,9 +409,8 @@ int saa7146_i2c_adapter_prepare(struct saa7146_dev *dev, struct i2c_adapter *i2c
dev->i2c_bitrate = bitrate;
saa7146_i2c_reset(dev);
- if( NULL != i2c_adapter ) {
- BUG_ON(!i2c_adapter->class);
- i2c_set_adapdata(i2c_adapter,dev);
+ if (i2c_adapter) {
+ i2c_set_adapdata(i2c_adapter, &dev->v4l2_dev);
i2c_adapter->dev.parent = &dev->pci->dev;
i2c_adapter->algo = &saa7146_algo;
i2c_adapter->algo_data = NULL;
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 47fee05eaef..552dab442d7 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1,4 +1,5 @@
#include <media/saa7146_vv.h>
+#include <media/v4l2-chip-ident.h>
static int max_memory = 32;
@@ -97,172 +98,13 @@ struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc)
return NULL;
}
-static int g_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- DEB_EE(("dev:%p, fh:%p\n",dev,fh));
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- f->fmt.pix = fh->video_fmt;
- return 0;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- f->fmt.win = fh->ov.win;
- return 0;
- case V4L2_BUF_TYPE_VBI_CAPTURE:
- {
- f->fmt.vbi = fh->vbi_fmt;
- return 0;
- }
- default:
- DEB_D(("invalid format type '%d'.\n",f->type));
- return -EINVAL;
- }
-}
-
-static int try_win(struct saa7146_dev *dev, struct v4l2_window *win)
-{
- struct saa7146_vv *vv = dev->vv_data;
- enum v4l2_field field;
- int maxw, maxh;
-
- DEB_EE(("dev:%p\n",dev));
-
- if (NULL == vv->ov_fb.base) {
- DEB_D(("no fb base set.\n"));
- return -EINVAL;
- }
- if (NULL == vv->ov_fmt) {
- DEB_D(("no fb fmt set.\n"));
- return -EINVAL;
- }
- if (win->w.width < 48 || win->w.height < 32) {
- DEB_D(("min width/height. (%d,%d)\n",win->w.width,win->w.height));
- return -EINVAL;
- }
- if (win->clipcount > 16) {
- DEB_D(("clipcount too big.\n"));
- return -EINVAL;
- }
-
- field = win->field;
- maxw = vv->standard->h_max_out;
- maxh = vv->standard->v_max_out;
-
- if (V4L2_FIELD_ANY == field) {
- field = (win->w.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_TOP;
- }
- switch (field) {
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- case V4L2_FIELD_ALTERNATE:
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- break;
- default: {
- DEB_D(("no known field mode '%d'.\n",field));
- return -EINVAL;
- }
- }
-
- win->field = field;
- if (win->w.width > maxw)
- win->w.width = maxw;
- if (win->w.height > maxh)
- win->w.height = maxh;
-
- return 0;
-}
-
-static int try_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
- int err;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- {
- struct saa7146_format *fmt;
- enum v4l2_field field;
- int maxw, maxh;
- int calc_bpl;
-
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
-
- fmt = format_by_fourcc(dev,f->fmt.pix.pixelformat);
- if (NULL == fmt) {
- return -EINVAL;
- }
-
- field = f->fmt.pix.field;
- maxw = vv->standard->h_max_out;
- maxh = vv->standard->v_max_out;
-
- if (V4L2_FIELD_ANY == field) {
- field = (f->fmt.pix.height > maxh/2)
- ? V4L2_FIELD_INTERLACED
- : V4L2_FIELD_BOTTOM;
- }
- switch (field) {
- case V4L2_FIELD_ALTERNATE: {
- vv->last_field = V4L2_FIELD_TOP;
- maxh = maxh / 2;
- break;
- }
- case V4L2_FIELD_TOP:
- case V4L2_FIELD_BOTTOM:
- vv->last_field = V4L2_FIELD_INTERLACED;
- maxh = maxh / 2;
- break;
- case V4L2_FIELD_INTERLACED:
- vv->last_field = V4L2_FIELD_INTERLACED;
- break;
- default: {
- DEB_D(("no known field mode '%d'.\n",field));
- return -EINVAL;
- }
- }
-
- f->fmt.pix.field = field;
- if (f->fmt.pix.width > maxw)
- f->fmt.pix.width = maxw;
- if (f->fmt.pix.height > maxh)
- f->fmt.pix.height = maxh;
-
- calc_bpl = (f->fmt.pix.width * fmt->depth)/8;
-
- if (f->fmt.pix.bytesperline < calc_bpl)
- f->fmt.pix.bytesperline = calc_bpl;
-
- if (f->fmt.pix.bytesperline > (2*PAGE_SIZE * fmt->depth)/8) /* arbitrary constraint */
- f->fmt.pix.bytesperline = calc_bpl;
-
- f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
- DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n",f->fmt.pix.width,f->fmt.pix.height,f->fmt.pix.bytesperline,f->fmt.pix.sizeimage));
-
- return 0;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
- err = try_win(dev,&f->fmt.win);
- if (0 != err) {
- return err;
- }
- return 0;
- default:
- DEB_EE(("unknown format type '%d'\n",f->type));
- return -EINVAL;
- }
-}
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f);
int saa7146_start_preview(struct saa7146_fh *fh)
{
struct saa7146_dev *dev = fh->dev;
struct saa7146_vv *vv = dev->vv_data;
+ struct v4l2_format fmt;
int ret = 0, err = 0;
DEB_EE(("dev:%p, fh:%p\n",dev,fh));
@@ -294,12 +136,13 @@ int saa7146_start_preview(struct saa7146_fh *fh)
return -EBUSY;
}
- err = try_win(dev,&fh->ov.win);
+ fmt.fmt.win = fh->ov.win;
+ err = vidioc_try_fmt_vid_overlay(NULL, fh, &fmt);
if (0 != err) {
saa7146_res_free(vv->video_fh, RESOURCE_DMA1_HPS|RESOURCE_DMA2_CLP);
return -EBUSY;
}
-
+ fh->ov.win = fmt.fmt.win;
vv->ov_data = &fh->ov;
DEB_D(("%dx%d+%d+%d %s field=%s\n",
@@ -355,58 +198,6 @@ int saa7146_stop_preview(struct saa7146_fh *fh)
}
EXPORT_SYMBOL_GPL(saa7146_stop_preview);
-static int s_fmt(struct saa7146_fh *fh, struct v4l2_format *f)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- int err;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n",dev,fh));
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_EE(("streaming capture is active\n"));
- return -EBUSY;
- }
- err = try_fmt(fh,f);
- if (0 != err)
- return err;
- fh->video_fmt = f->fmt.pix;
- DEB_EE(("set to pixelformat '%4.4s'\n",(char *)&fh->video_fmt.pixelformat));
- return 0;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n",dev,fh));
- err = try_win(dev,&f->fmt.win);
- if (0 != err)
- return err;
- mutex_lock(&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);
- return -EFAULT;
- }
-
- /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
- fh->ov.fh = fh;
-
- mutex_unlock(&dev->lock);
-
- /* check if our current overlay is active */
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- saa7146_stop_preview(fh);
- saa7146_start_preview(fh);
- }
- return 0;
- default:
- DEB_D(("unknown format type '%d'\n",f->type));
- return -EINVAL;
- }
-}
-
/********************************************************************************/
/* device controls */
@@ -419,6 +210,7 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 128,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_CONTRAST,
.name = "Contrast",
@@ -427,6 +219,7 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 64,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_SATURATION,
.name = "Saturation",
@@ -435,15 +228,16 @@ static struct v4l2_queryctrl controls[] = {
.step = 1,
.default_value = 64,
.type = V4L2_CTRL_TYPE_INTEGER,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
},{
.id = V4L2_CID_VFLIP,
- .name = "Vertical flip",
+ .name = "Vertical Flip",
.minimum = 0,
.maximum = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
},{
.id = V4L2_CID_HFLIP,
- .name = "Horizontal flip",
+ .name = "Horizontal Flip",
.minimum = 0,
.maximum = 1,
.type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -463,132 +257,6 @@ static struct v4l2_queryctrl* ctrl_by_id(int id)
return NULL;
}
-static int get_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- const struct v4l2_queryctrl* ctrl;
- u32 value = 0;
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl)
- return -EINVAL;
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0xff & (value >> 24);
- DEB_D(("V4L2_CID_BRIGHTNESS: %d\n",c->value));
- break;
- case V4L2_CID_CONTRAST:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0x7f & (value >> 16);
- DEB_D(("V4L2_CID_CONTRAST: %d\n",c->value));
- break;
- case V4L2_CID_SATURATION:
- value = saa7146_read(dev, BCS_CTRL);
- c->value = 0x7f & (value >> 0);
- DEB_D(("V4L2_CID_SATURATION: %d\n",c->value));
- break;
- case V4L2_CID_VFLIP:
- c->value = vv->vflip;
- DEB_D(("V4L2_CID_VFLIP: %d\n",c->value));
- break;
- case V4L2_CID_HFLIP:
- c->value = vv->hflip;
- DEB_D(("V4L2_CID_HFLIP: %d\n",c->value));
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int set_control(struct saa7146_fh *fh, struct v4l2_control *c)
-{
- struct saa7146_dev *dev = fh->dev;
- struct saa7146_vv *vv = dev->vv_data;
-
- const struct v4l2_queryctrl* ctrl;
-
- ctrl = ctrl_by_id(c->id);
- if (NULL == ctrl) {
- DEB_D(("unknown control %d\n",c->id));
- return -EINVAL;
- }
-
- mutex_lock(&dev->lock);
-
- switch (ctrl->type) {
- case V4L2_CTRL_TYPE_BOOLEAN:
- case V4L2_CTRL_TYPE_MENU:
- case V4L2_CTRL_TYPE_INTEGER:
- if (c->value < ctrl->minimum)
- c->value = ctrl->minimum;
- if (c->value > ctrl->maximum)
- c->value = ctrl->maximum;
- break;
- default:
- /* nothing */;
- };
-
- switch (c->id) {
- case V4L2_CID_BRIGHTNESS: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0x00ffffff;
- value |= (c->value << 24);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_CONTRAST: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0xff00ffff;
- value |= (c->value << 16);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_SATURATION: {
- u32 value = saa7146_read(dev, BCS_CTRL);
- value &= 0xffffff00;
- value |= (c->value << 0);
- saa7146_write(dev, BCS_CTRL, value);
- saa7146_write(dev, MC2, MASK_22 | MASK_06 );
- break;
- }
- case V4L2_CID_HFLIP:
- /* 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);
- return -EINVAL;
- }
- vv->hflip = c->value;
- break;
- case V4L2_CID_VFLIP:
- if (IS_CAPTURE_ACTIVE(fh) != 0) {
- DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
- vv->vflip = c->value;
- break;
- default: {
- mutex_unlock(&dev->lock);
- return -EINVAL;
- }
- }
- mutex_unlock(&dev->lock);
-
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- saa7146_stop_preview(fh);
- saa7146_start_preview(fh);
- }
- return 0;
-}
-
/********************************************************************************/
/* common pagetable functions */
@@ -829,231 +497,446 @@ static int video_end(struct saa7146_fh *fh, struct file *file)
return 0;
}
-/*
- * This function is _not_ called directly, but from
- * video_generic_ioctl (and maybe others). userspace
- * copying is done already, arg is a kernel pointer.
- */
+static int vidioc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+
+ strcpy((char *)cap->driver, "saa7146 v4l2");
+ strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
+ sprintf((char *)cap->bus_info, "PCI:%s", pci_name(dev->pci));
+ cap->version = SAA7146_VERSION_CODE;
+ cap->capabilities =
+ V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OVERLAY |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING;
+ cap->capabilities |= dev->ext_vv_data->capabilities;
+ return 0;
+}
-long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
{
- struct saa7146_fh *fh = file->private_data;
- struct saa7146_dev *dev = fh->dev;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ *fb = vv->ov_fb;
+ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+ return 0;
+}
+
+static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct saa7146_vv *vv = dev->vv_data;
+ struct saa7146_format *fmt;
- long err = 0;
- int result = 0, ee = 0;
+ DEB_EE(("VIDIOC_S_FBUF\n"));
- struct saa7146_use_ops *ops;
- struct videobuf_queue *q;
+ if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO))
+ return -EPERM;
- /* check if extension handles the command */
- for(ee = 0; dev->ext_vv_data->ioctls[ee].flags != 0; ee++) {
- if( cmd == dev->ext_vv_data->ioctls[ee].cmd )
- break;
+ /* check args */
+ fmt = format_by_fourcc(dev, fb->fmt.pixelformat);
+ if (NULL == fmt)
+ return -EINVAL;
+
+ /* planar formats are not allowed for overlay video, clipping and video dma would clash */
+ if (fmt->flags & FORMAT_IS_PLANAR)
+ DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",
+ (char *)&fmt->pixelformat));
+
+ /* check if overlay is running */
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ if (vv->video_fh != fh) {
+ DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
+ return -EBUSY;
+ }
}
- if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_EXCLUSIVE) ) {
- DEB_D(("extension handles ioctl exclusive.\n"));
- result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- return result;
+ mutex_lock(&dev->lock);
+
+ /* ok, accept it */
+ vv->ov_fb = *fb;
+ vv->ov_fmt = fmt;
+ if (0 == vv->ov_fb.fmt.bytesperline)
+ vv->ov_fb.fmt.bytesperline =
+ vv->ov_fb.fmt.width * fmt->depth / 8;
+
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
+{
+ if (f->index >= NUM_FORMATS)
+ return -EINVAL;
+ strlcpy((char *)f->description, formats[f->index].name,
+ sizeof(f->description));
+ f->pixelformat = formats[f->index].pixelformat;
+ return 0;
+}
+
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
+{
+ const struct v4l2_queryctrl *ctrl;
+
+ if ((c->id < V4L2_CID_BASE ||
+ c->id >= V4L2_CID_LASTP1) &&
+ (c->id < V4L2_CID_PRIVATE_BASE ||
+ c->id >= V4L2_CID_PRIVATE_LASTP1))
+ return -EINVAL;
+
+ ctrl = ctrl_by_id(c->id);
+ if (ctrl == NULL)
+ return -EINVAL;
+
+ DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n", c->id));
+ *c = *ctrl;
+ return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ const struct v4l2_queryctrl *ctrl;
+ u32 value = 0;
+
+ ctrl = ctrl_by_id(c->id);
+ if (NULL == ctrl)
+ return -EINVAL;
+ switch (c->id) {
+ case V4L2_CID_BRIGHTNESS:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0xff & (value >> 24);
+ DEB_D(("V4L2_CID_BRIGHTNESS: %d\n", c->value));
+ break;
+ case V4L2_CID_CONTRAST:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0x7f & (value >> 16);
+ DEB_D(("V4L2_CID_CONTRAST: %d\n", c->value));
+ break;
+ case V4L2_CID_SATURATION:
+ value = saa7146_read(dev, BCS_CTRL);
+ c->value = 0x7f & (value >> 0);
+ DEB_D(("V4L2_CID_SATURATION: %d\n", c->value));
+ break;
+ case V4L2_CID_VFLIP:
+ c->value = vv->vflip;
+ DEB_D(("V4L2_CID_VFLIP: %d\n", c->value));
+ break;
+ case V4L2_CID_HFLIP:
+ c->value = vv->hflip;
+ DEB_D(("V4L2_CID_HFLIP: %d\n", c->value));
+ break;
+ default:
+ return -EINVAL;
}
- if( 0 != (dev->ext_vv_data->ioctls[ee].flags & SAA7146_BEFORE) ) {
- DEB_D(("extension handles ioctl before.\n"));
- result = dev->ext_vv_data->ioctl(fh, cmd, arg);
- if( -EAGAIN != result ) {
- return result;
- }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ const struct v4l2_queryctrl *ctrl;
+
+ ctrl = ctrl_by_id(c->id);
+ if (NULL == ctrl) {
+ DEB_D(("unknown control %d\n", c->id));
+ return -EINVAL;
}
- /* fixme: add handle "after" case (is it still needed?) */
+ mutex_lock(&dev->lock);
- switch (fh->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- ops = &saa7146_video_uops;
- q = &fh->video_q;
+ switch (ctrl->type) {
+ case V4L2_CTRL_TYPE_BOOLEAN:
+ case V4L2_CTRL_TYPE_MENU:
+ case V4L2_CTRL_TYPE_INTEGER:
+ if (c->value < ctrl->minimum)
+ c->value = ctrl->minimum;
+ if (c->value > ctrl->maximum)
+ c->value = ctrl->maximum;
break;
+ default:
+ /* nothing */;
+ }
+
+ switch (c->id) {
+ case V4L2_CID_BRIGHTNESS: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0x00ffffff;
+ value |= (c->value << 24);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_CONTRAST: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0xff00ffff;
+ value |= (c->value << 16);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_SATURATION: {
+ u32 value = saa7146_read(dev, BCS_CTRL);
+ value &= 0xffffff00;
+ value |= (c->value << 0);
+ saa7146_write(dev, BCS_CTRL, value);
+ saa7146_write(dev, MC2, MASK_22 | MASK_06);
+ break;
+ }
+ case V4L2_CID_HFLIP:
+ /* 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);
+ return -EBUSY;
}
- case V4L2_BUF_TYPE_VBI_CAPTURE: {
- ops = &saa7146_vbi_uops;
- q = &fh->vbi_q;
+ vv->hflip = c->value;
break;
+ case V4L2_CID_VFLIP:
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_D(("V4L2_CID_VFLIP while active capture.\n"));
+ mutex_unlock(&dev->lock);
+ return -EBUSY;
}
+ vv->vflip = c->value;
+ break;
default:
- BUG();
- return 0;
+ mutex_unlock(&dev->lock);
+ return -EINVAL;
}
+ mutex_unlock(&dev->lock);
- switch (cmd) {
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
- memset(cap,0,sizeof(*cap));
-
- DEB_EE(("VIDIOC_QUERYCAP\n"));
-
- strcpy((char *)cap->driver, "saa7146 v4l2");
- strlcpy((char *)cap->card, dev->ext->name, sizeof(cap->card));
- sprintf((char *)cap->bus_info,"PCI:%s", pci_name(dev->pci));
- cap->version = SAA7146_VERSION_CODE;
- cap->capabilities =
- V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_VIDEO_OVERLAY |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING;
- cap->capabilities |= dev->ext_vv_data->capabilities;
- return 0;
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ saa7146_stop_preview(fh);
+ saa7146_start_preview(fh);
}
- case VIDIOC_G_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
-
- DEB_EE(("VIDIOC_G_FBUF\n"));
+ return 0;
+}
- *fb = vv->ov_fb;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
- return 0;
- }
- case VIDIOC_S_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
- struct saa7146_format *fmt;
+static int vidioc_g_parm(struct file *file, void *fh,
+ struct v4l2_streamparm *parm)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
- DEB_EE(("VIDIOC_S_FBUF\n"));
+ parm->parm.capture.readbuffers = 1;
+ v4l2_video_std_frame_period(vv->standard->id,
+ &parm->parm.capture.timeperframe);
+ return 0;
+}
- if(!capable(CAP_SYS_ADMIN) &&
- !capable(CAP_SYS_RAWIO))
- return -EPERM;
+static int vidioc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.pix = ((struct saa7146_fh *)fh)->video_fmt;
+ return 0;
+}
- /* check args */
- fmt = format_by_fourcc(dev,fb->fmt.pixelformat);
- if (NULL == fmt) {
- return -EINVAL;
- }
+static int vidioc_g_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.win = ((struct saa7146_fh *)fh)->ov.win;
+ return 0;
+}
- /* planar formats are not allowed for overlay video, clipping and video dma would clash */
- if (0 != (fmt->flags & FORMAT_IS_PLANAR)) {
- DEB_S(("planar pixelformat '%4.4s' not allowed for overlay\n",(char *)&fmt->pixelformat));
- }
+static int vidioc_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ f->fmt.vbi = ((struct saa7146_fh *)fh)->vbi_fmt;
+ return 0;
+}
- /* check if overlay is running */
- if (IS_OVERLAY_ACTIVE(fh) != 0) {
- if (vv->video_fh != fh) {
- DEB_D(("refusing to change framebuffer informations while overlay is active in another open.\n"));
- return -EBUSY;
- }
- }
+static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ struct saa7146_format *fmt;
+ enum v4l2_field field;
+ int maxw, maxh;
+ int calc_bpl;
- mutex_lock(&dev->lock);
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
- /* ok, accept it */
- vv->ov_fb = *fb;
- vv->ov_fmt = fmt;
- if (0 == vv->ov_fb.fmt.bytesperline)
- vv->ov_fb.fmt.bytesperline =
- vv->ov_fb.fmt.width*fmt->depth/8;
+ fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat);
+ if (NULL == fmt)
+ return -EINVAL;
- mutex_unlock(&dev->lock);
+ field = f->fmt.pix.field;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
- return 0;
+ if (V4L2_FIELD_ANY == field) {
+ field = (f->fmt.pix.height > maxh / 2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_BOTTOM;
}
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *f = arg;
-
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- if (f->index >= NUM_FORMATS)
- return -EINVAL;
- strlcpy((char *)f->description, formats[f->index].name,
- sizeof(f->description));
- f->pixelformat = formats[f->index].pixelformat;
- f->flags = 0;
- memset(f->reserved, 0, sizeof(f->reserved));
- break;
- default:
- return -EINVAL;
- }
-
- DEB_EE(("VIDIOC_ENUM_FMT: type:%d, index:%d\n",f->type,f->index));
- return 0;
+ switch (field) {
+ case V4L2_FIELD_ALTERNATE:
+ vv->last_field = V4L2_FIELD_TOP;
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ vv->last_field = V4L2_FIELD_INTERLACED;
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ vv->last_field = V4L2_FIELD_INTERLACED;
+ break;
+ default:
+ DEB_D(("no known field mode '%d'.\n", field));
+ return -EINVAL;
}
- case VIDIOC_QUERYCTRL:
- {
- const struct v4l2_queryctrl *ctrl;
- struct v4l2_queryctrl *c = arg;
- if ((c->id < V4L2_CID_BASE ||
- c->id >= V4L2_CID_LASTP1) &&
- (c->id < V4L2_CID_PRIVATE_BASE ||
- c->id >= V4L2_CID_PRIVATE_LASTP1))
- return -EINVAL;
+ f->fmt.pix.field = field;
+ if (f->fmt.pix.width > maxw)
+ f->fmt.pix.width = maxw;
+ if (f->fmt.pix.height > maxh)
+ f->fmt.pix.height = maxh;
- ctrl = ctrl_by_id(c->id);
- if( NULL == ctrl ) {
- return -EINVAL;
-/*
- c->flags = V4L2_CTRL_FLAG_DISABLED;
- return 0;
-*/
- }
+ calc_bpl = (f->fmt.pix.width * fmt->depth) / 8;
- DEB_EE(("VIDIOC_QUERYCTRL: id:%d\n",c->id));
- *c = *ctrl;
- return 0;
+ if (f->fmt.pix.bytesperline < calc_bpl)
+ f->fmt.pix.bytesperline = calc_bpl;
+
+ if (f->fmt.pix.bytesperline > (2 * PAGE_SIZE * fmt->depth) / 8) /* arbitrary constraint */
+ f->fmt.pix.bytesperline = calc_bpl;
+
+ f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * f->fmt.pix.height;
+ DEB_D(("w:%d, h:%d, bytesperline:%d, sizeimage:%d\n", f->fmt.pix.width,
+ f->fmt.pix.height, f->fmt.pix.bytesperline, f->fmt.pix.sizeimage));
+
+ return 0;
+}
+
+
+static int vidioc_try_fmt_vid_overlay(struct file *file, void *fh, struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ struct v4l2_window *win = &f->fmt.win;
+ enum v4l2_field field;
+ int maxw, maxh;
+
+ DEB_EE(("dev:%p\n", dev));
+
+ if (NULL == vv->ov_fb.base) {
+ DEB_D(("no fb base set.\n"));
+ return -EINVAL;
}
- case VIDIOC_G_CTRL: {
- DEB_EE(("VIDIOC_G_CTRL\n"));
- return get_control(fh,arg);
+ if (NULL == vv->ov_fmt) {
+ DEB_D(("no fb fmt set.\n"));
+ return -EINVAL;
}
- case VIDIOC_S_CTRL:
- {
- DEB_EE(("VIDIOC_S_CTRL\n"));
- err = set_control(fh,arg);
- return err;
+ if (win->w.width < 48 || win->w.height < 32) {
+ DEB_D(("min width/height. (%d,%d)\n", win->w.width, win->w.height));
+ return -EINVAL;
}
- case VIDIOC_G_PARM:
- {
- struct v4l2_streamparm *parm = arg;
- if( parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ) {
- return -EINVAL;
- }
- memset(&parm->parm.capture,0,sizeof(struct v4l2_captureparm));
- parm->parm.capture.readbuffers = 1;
- // fixme: only for PAL!
- parm->parm.capture.timeperframe.numerator = 1;
- parm->parm.capture.timeperframe.denominator = 25;
- return 0;
+ if (win->clipcount > 16) {
+ DEB_D(("clipcount too big.\n"));
+ return -EINVAL;
}
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_G_FMT\n"));
- return g_fmt(fh,f);
+
+ field = win->field;
+ maxw = vv->standard->h_max_out;
+ maxh = vv->standard->v_max_out;
+
+ if (V4L2_FIELD_ANY == field) {
+ field = (win->w.height > maxh / 2)
+ ? V4L2_FIELD_INTERLACED
+ : V4L2_FIELD_TOP;
+ }
+ switch (field) {
+ case V4L2_FIELD_TOP:
+ case V4L2_FIELD_BOTTOM:
+ case V4L2_FIELD_ALTERNATE:
+ maxh = maxh / 2;
+ break;
+ case V4L2_FIELD_INTERLACED:
+ break;
+ default:
+ DEB_D(("no known field mode '%d'.\n", field));
+ return -EINVAL;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_S_FMT\n"));
- return s_fmt(fh,f);
+
+ win->field = field;
+ if (win->w.width > maxw)
+ win->w.width = maxw;
+ if (win->w.height > maxh)
+ win->w.height = maxh;
+
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *__fh, struct v4l2_format *f)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh));
+ if (IS_CAPTURE_ACTIVE(fh) != 0) {
+ DEB_EE(("streaming capture is active\n"));
+ return -EBUSY;
}
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *f = arg;
- DEB_EE(("VIDIOC_TRY_FMT\n"));
- return try_fmt(fh,f);
+ err = vidioc_try_fmt_vid_cap(file, fh, f);
+ if (0 != err)
+ return err;
+ fh->video_fmt = f->fmt.pix;
+ DEB_EE(("set to pixelformat '%4.4s'\n", (char *)&fh->video_fmt.pixelformat));
+ return 0;
+}
+
+static int vidioc_s_fmt_vid_overlay(struct file *file, void *__fh, struct v4l2_format *f)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_EE(("V4L2_BUF_TYPE_VIDEO_OVERLAY: dev:%p, fh:%p\n", dev, fh));
+ err = vidioc_try_fmt_vid_overlay(file, fh, f);
+ if (0 != err)
+ return err;
+ mutex_lock(&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);
+ return -EFAULT;
}
- case VIDIOC_G_STD:
- {
- v4l2_std_id *id = arg;
- DEB_EE(("VIDIOC_G_STD\n"));
- *id = vv->standard->id;
- return 0;
+
+ /* fh->ov.fh is used to indicate that we have valid overlay informations, too */
+ fh->ov.fh = fh;
+
+ mutex_unlock(&dev->lock);
+
+ /* check if our current overlay is active */
+ if (IS_OVERLAY_ACTIVE(fh) != 0) {
+ saa7146_stop_preview(fh);
+ saa7146_start_preview(fh);
}
+ return 0;
+}
+
+static int vidioc_g_std(struct file *file, void *fh, v4l2_std_id *norm)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+
+ *norm = vv->standard->id;
+ return 0;
+}
+
/* the saa7146 supfhrts (used in conjunction with the saa7111a for example)
PAL / NTSC / SECAM. if your hardware does not (or does more)
-- override this function in your extension */
+/*
case VIDIOC_ENUMSTD:
{
struct v4l2_standard *e = arg;
@@ -1066,162 +949,245 @@ long saa7146_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
}
return -EINVAL;
}
- case VIDIOC_S_STD:
- {
- v4l2_std_id *id = arg;
- int found = 0;
- int i;
-
- DEB_EE(("VIDIOC_S_STD\n"));
+ */
- if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
- DEB_D(("cannot change video standard while streaming capture is active\n"));
- return -EBUSY;
- }
+static int vidioc_s_std(struct file *file, void *fh, v4l2_std_id *id)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int found = 0;
+ int err, i;
- if ((vv->video_status & STATUS_OVERLAY) != 0) {
- vv->ov_suspend = vv->video_fh;
- err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
- if (0 != err) {
- DEB_D(("suspending video failed. aborting\n"));
- return err;
- }
- }
+ DEB_EE(("VIDIOC_S_STD\n"));
- mutex_lock(&dev->lock);
+ if ((vv->video_status & STATUS_CAPTURE) == STATUS_CAPTURE) {
+ DEB_D(("cannot change video standard while streaming capture is active\n"));
+ return -EBUSY;
+ }
- for(i = 0; i < dev->ext_vv_data->num_stds; i++)
- if (*id & dev->ext_vv_data->stds[i].id)
- break;
- if (i != dev->ext_vv_data->num_stds) {
- vv->standard = &dev->ext_vv_data->stds[i];
- if( NULL != dev->ext_vv_data->std_callback )
- dev->ext_vv_data->std_callback(dev, vv->standard);
- found = 1;
+ if ((vv->video_status & STATUS_OVERLAY) != 0) {
+ vv->ov_suspend = vv->video_fh;
+ err = saa7146_stop_preview(vv->video_fh); /* side effect: video_status is now 0, video_fh is NULL */
+ if (0 != err) {
+ DEB_D(("suspending video failed. aborting\n"));
+ return err;
}
+ }
- mutex_unlock(&dev->lock);
+ mutex_lock(&dev->lock);
- if (vv->ov_suspend != NULL) {
- saa7146_start_preview(vv->ov_suspend);
- vv->ov_suspend = NULL;
- }
+ for (i = 0; i < dev->ext_vv_data->num_stds; i++)
+ if (*id & dev->ext_vv_data->stds[i].id)
+ break;
+ if (i != dev->ext_vv_data->num_stds) {
+ vv->standard = &dev->ext_vv_data->stds[i];
+ if (NULL != dev->ext_vv_data->std_callback)
+ dev->ext_vv_data->std_callback(dev, vv->standard);
+ found = 1;
+ }
- if( 0 == found ) {
- DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
- return -EINVAL;
- }
+ mutex_unlock(&dev->lock);
- DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n",vv->standard->name));
- return 0;
+ if (vv->ov_suspend != NULL) {
+ saa7146_start_preview(vv->ov_suspend);
+ vv->ov_suspend = NULL;
}
- case VIDIOC_OVERLAY:
- {
- int on = *(int *)arg;
- DEB_D(("VIDIOC_OVERLAY on:%d\n",on));
- if (on != 0) {
- err = saa7146_start_preview(fh);
- } else {
- err = saa7146_stop_preview(fh);
- }
- return err;
- }
- case VIDIOC_REQBUFS: {
- struct v4l2_requestbuffers *req = arg;
- DEB_D(("VIDIOC_REQBUFS, type:%d\n",req->type));
- return videobuf_reqbufs(q,req);
- }
- case VIDIOC_QUERYBUF: {
- struct v4l2_buffer *buf = arg;
- DEB_D(("VIDIOC_QUERYBUF, type:%d, offset:%d\n",buf->type,buf->m.offset));
- return videobuf_querybuf(q,buf);
- }
- case VIDIOC_QBUF: {
- struct v4l2_buffer *buf = arg;
- int ret = 0;
- ret = videobuf_qbuf(q,buf);
- DEB_D(("VIDIOC_QBUF: ret:%d, index:%d\n",ret,buf->index));
- return ret;
- }
- case VIDIOC_DQBUF: {
- struct v4l2_buffer *buf = arg;
- int ret = 0;
- ret = videobuf_dqbuf(q,buf,file->f_flags & O_NONBLOCK);
- DEB_D(("VIDIOC_DQBUF: ret:%d, index:%d\n",ret,buf->index));
- return ret;
+ if (!found) {
+ DEB_EE(("VIDIOC_S_STD: standard not found.\n"));
+ return -EINVAL;
}
- case VIDIOC_STREAMON: {
- int *type = arg;
- DEB_D(("VIDIOC_STREAMON, type:%d\n",*type));
- err = video_begin(fh);
- if( 0 != err) {
- return err;
- }
- err = videobuf_streamon(q);
- return err;
- }
- case VIDIOC_STREAMOFF: {
- int *type = arg;
+ DEB_EE(("VIDIOC_S_STD: set to standard to '%s'\n", vv->standard->name));
+ return 0;
+}
- DEB_D(("VIDIOC_STREAMOFF, type:%d\n",*type));
+static int vidioc_overlay(struct file *file, void *fh, unsigned int on)
+{
+ int err;
- /* ugly: we need to copy some checks from video_end(),
- because videobuf_streamoff() relies on the capture running.
- check and fix this */
- if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
- DEB_S(("not capturing.\n"));
- return 0;
- }
+ DEB_D(("VIDIOC_OVERLAY on:%d\n", on));
+ if (on)
+ err = saa7146_start_preview(fh);
+ else
+ err = saa7146_stop_preview(fh);
+ return err;
+}
- if (vv->video_fh != fh) {
- DEB_S(("capturing, but in another open.\n"));
- return -EBUSY;
- }
+static int vidioc_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *b)
+{
+ struct saa7146_fh *fh = __fh;
- err = videobuf_streamoff(q);
- if (0 != err) {
- DEB_D(("warning: videobuf_streamoff() failed.\n"));
- video_end(fh, file);
- } else {
- err = video_end(fh, file);
- }
+ if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_reqbufs(&fh->video_q, b);
+ if (b->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_reqbufs(&fh->vbi_q, b);
+ return -EINVAL;
+}
+
+static int vidioc_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_querybuf(&fh->video_q, buf);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_querybuf(&fh->vbi_q, buf);
+ return -EINVAL;
+}
+
+static int vidioc_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_qbuf(&fh->video_q, buf);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_qbuf(&fh->vbi_q, buf);
+ return -EINVAL;
+}
+
+static int vidioc_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct saa7146_fh *fh = __fh;
+
+ if (buf->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_dqbuf(&fh->video_q, buf, file->f_flags & O_NONBLOCK);
+ if (buf->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_dqbuf(&fh->vbi_q, buf, file->f_flags & O_NONBLOCK);
+ return -EINVAL;
+}
+
+static int vidioc_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct saa7146_fh *fh = __fh;
+ int err;
+
+ DEB_D(("VIDIOC_STREAMON, type:%d\n", type));
+
+ err = video_begin(fh);
+ if (err)
return err;
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return videobuf_streamon(&fh->video_q);
+ if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return videobuf_streamon(&fh->vbi_q);
+ return -EINVAL;
+}
+
+static int vidioc_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
+ struct saa7146_vv *vv = dev->vv_data;
+ int err;
+
+ DEB_D(("VIDIOC_STREAMOFF, type:%d\n", type));
+
+ /* ugly: we need to copy some checks from video_end(),
+ because videobuf_streamoff() relies on the capture running.
+ check and fix this */
+ if ((vv->video_status & STATUS_CAPTURE) != STATUS_CAPTURE) {
+ DEB_S(("not capturing.\n"));
+ return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- case VIDIOCGMBUF:
- {
- struct video_mbuf *mbuf = arg;
- int i;
- /* fixme: number of capture buffers and sizes for v4l apps */
- int gbuffers = 2;
- int gbufsize = 768*576*4;
+ if (vv->video_fh != fh) {
+ DEB_S(("capturing, but in another open.\n"));
+ return -EBUSY;
+ }
- DEB_D(("VIDIOCGMBUF \n"));
+ err = -EINVAL;
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ err = videobuf_streamoff(&fh->video_q);
+ else if (type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ err = videobuf_streamoff(&fh->vbi_q);
+ if (0 != err) {
+ DEB_D(("warning: videobuf_streamoff() failed.\n"));
+ video_end(fh, file);
+ } else {
+ err = video_end(fh, file);
+ }
+ return err;
+}
- q = &fh->video_q;
- err = videobuf_mmap_setup(q,gbuffers,gbufsize,
- V4L2_MEMORY_MMAP);
- if (err < 0)
- return err;
+static int vidioc_g_chip_ident(struct file *file, void *__fh,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct saa7146_fh *fh = __fh;
+ struct saa7146_dev *dev = fh->dev;
- gbuffers = err;
- memset(mbuf,0,sizeof(*mbuf));
- mbuf->frames = gbuffers;
- mbuf->size = gbuffers * gbufsize;
- for (i = 0; i < gbuffers; i++)
- mbuf->offsets[i] = i * gbufsize;
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ if (chip->match.type == V4L2_CHIP_MATCH_HOST && !chip->match.addr) {
+ chip->ident = V4L2_IDENT_SAA7146;
return 0;
}
-#endif
- default:
- return v4l_compat_translate_ioctl(file, cmd, arg,
- saa7146_video_do_ioctl);
- }
+ return v4l2_device_call_until_err(&dev->v4l2_dev, 0,
+ core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *mbuf)
+{
+ struct saa7146_fh *fh = __fh;
+ struct videobuf_queue *q = &fh->video_q;
+ int err, i;
+
+ /* fixme: number of capture buffers and sizes for v4l apps */
+ int gbuffers = 2;
+ int gbufsize = 768 * 576 * 4;
+
+ DEB_D(("VIDIOCGMBUF \n"));
+
+ q = &fh->video_q;
+ err = videobuf_mmap_setup(q, gbuffers, gbufsize,
+ V4L2_MEMORY_MMAP);
+ if (err < 0)
+ return err;
+
+ gbuffers = err;
+ memset(mbuf, 0, sizeof(*mbuf));
+ mbuf->frames = gbuffers;
+ mbuf->size = gbuffers * gbufsize;
+ for (i = 0; i < gbuffers; i++)
+ mbuf->offsets[i] = i * gbufsize;
return 0;
}
+#endif
+
+const struct v4l2_ioctl_ops saa7146_video_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+ .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
+ .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
+ .vidioc_g_chip_ident = vidioc_g_chip_ident,
+
+ .vidioc_overlay = vidioc_overlay,
+ .vidioc_g_fbuf = vidioc_g_fbuf,
+ .vidioc_s_fbuf = vidioc_s_fbuf,
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_g_std = vidioc_g_std,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_parm = vidioc_g_parm,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidiocgmbuf,
+#endif
+};
/*********************************************************************************/
/* buffer handling functions */
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 6f92beaa5ac..607d319ce8e 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -21,16 +21,17 @@ config MEDIA_TUNER
tristate
default VIDEO_MEDIA && I2C
depends on VIDEO_MEDIA && I2C
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE
-
-menuconfig MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
+
+menuconfig MEDIA_TUNER_CUSTOMISE
bool "Customize analog and hybrid tuner modules to build"
depends on MEDIA_TUNER
default n
@@ -43,13 +44,13 @@ menuconfig MEDIA_TUNER_CUSTOMIZE
If unsure say N.
-if MEDIA_TUNER_CUSTOMIZE
+if MEDIA_TUNER_CUSTOMISE
config MEDIA_TUNER_SIMPLE
tristate "Simple tuner support"
depends on VIDEO_MEDIA && I2C
select MEDIA_TUNER_TDA9887
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for various simple tuners.
@@ -58,28 +59,28 @@ config MEDIA_TUNER_TDA8290
depends on VIDEO_MEDIA && I2C
select MEDIA_TUNER_TDA827X
select MEDIA_TUNER_TDA18271
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for Philips TDA8290+8275(a) tuner.
config MEDIA_TUNER_TDA827X
tristate "Philips TDA827X silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A DVB-T silicon tuner module. Say Y when you want to support this tuner.
config MEDIA_TUNER_TDA18271
tristate "NXP TDA18271 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A silicon tuner module. Say Y when you want to support this tuner.
config MEDIA_TUNER_TDA9887
tristate "TDA 9885/6/7 analog IF demodulator"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for Philips TDA9885/6/7
analog IF demodulator.
@@ -88,80 +89,87 @@ config MEDIA_TUNER_TEA5761
tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
depends on VIDEO_MEDIA && I2C
depends on EXPERIMENTAL
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the Philips TEA5761 radio tuner.
config MEDIA_TUNER_TEA5767
tristate "TEA 5767 radio tuner"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the Philips TEA5767 radio tuner.
config MEDIA_TUNER_MT20XX
tristate "Microtune 2032 / 2050 tuners"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the MT2032 / MT2050 tuner.
config MEDIA_TUNER_MT2060
tristate "Microtune MT2060 silicon IF tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon IF tuner MT2060 from Microtune.
config MEDIA_TUNER_MT2266
tristate "Microtune MT2266 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon baseband tuner MT2266 from Microtune.
config MEDIA_TUNER_MT2131
tristate "Microtune MT2131 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon baseband tuner MT2131 from Microtune.
config MEDIA_TUNER_QT1010
tristate "Quantek QT1010 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner QT1010 from Quantek.
config MEDIA_TUNER_XC2028
tristate "XCeive xc2028/xc3028 tuners"
depends on VIDEO_MEDIA && I2C
- default m if MEDIA_TUNER_CUSTOMIZE
+ default m if MEDIA_TUNER_CUSTOMISE
help
Say Y here to include support for the xc2028/xc3028 tuners.
config MEDIA_TUNER_XC5000
tristate "Xceive XC5000 silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner XC5000 from Xceive.
- This device is only used inside a SiP called togther with a
+ This device is only used inside a SiP called together with a
demodulator for now.
config MEDIA_TUNER_MXL5005S
tristate "MaxLinear MSL5005S silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner MXL5005S from MaxLinear.
config MEDIA_TUNER_MXL5007T
tristate "MaxLinear MxL5007T silicon tuner"
depends on VIDEO_MEDIA && I2C
- default m if DVB_FE_CUSTOMISE
+ default m if MEDIA_TUNER_CUSTOMISE
help
A driver for the silicon tuner MxL5007T from MaxLinear.
-endif # MEDIA_TUNER_CUSTOMIZE
+config MEDIA_TUNER_MC44S803
+ tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
+ depends on VIDEO_MEDIA && I2C
+ default m if MEDIA_TUNER_CUSTOMISE
+ help
+ Say Y here to support the Freescale MC44S803 based tuners
+
+endif # MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 4dfbe5b8264..4132b2be79e 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
+obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/mc44s803.c b/drivers/media/common/tuners/mc44s803.c
new file mode 100644
index 00000000000..20c4485ce16
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803.c
@@ -0,0 +1,371 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mc44s803.h"
+#include "mc44s803_priv.h"
+
+#define mc_printk(level, format, arg...) \
+ printk(level "mc44s803: " format , ## arg)
+
+/* Writes a single register */
+static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
+{
+ u8 buf[3];
+ struct i2c_msg msg = {
+ .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
+ };
+
+ buf[0] = (val & 0xff0000) >> 16;
+ buf[1] = (val & 0xff00) >> 8;
+ buf[2] = (val & 0xff);
+
+ if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+ mc_printk(KERN_WARNING, "I2C write failed\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+/* Reads a single register */
+static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
+{
+ u32 wval;
+ u8 buf[3];
+ int ret;
+ struct i2c_msg msg[] = {
+ { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+ .buf = buf, .len = 3 },
+ };
+
+ wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
+ MC44S803_REG_SM(reg, MC44S803_D);
+
+ ret = mc44s803_writereg(priv, wval);
+ if (ret)
+ return ret;
+
+ if (i2c_transfer(priv->i2c, msg, 1) != 1) {
+ mc_printk(KERN_WARNING, "I2C read failed\n");
+ return -EREMOTEIO;
+ }
+
+ *val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
+
+ return 0;
+}
+
+static int mc44s803_release(struct dvb_frontend *fe)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(priv);
+
+ return 0;
+}
+
+static int mc44s803_init(struct dvb_frontend *fe)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ u32 val;
+ int err;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+/* Reset chip */
+ val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_RS);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Power Up and Start Osc */
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+ MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
+ MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
+ MC44S803_REG_SM(0x200, MC44S803_POWER);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ msleep(10);
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+ MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
+ MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ msleep(20);
+
+/* Setup Mixer */
+
+ val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
+ MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup Cirquit Adjust */
+
+ val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_G1) |
+ MC44S803_REG_SM(1, MC44S803_G3) |
+ MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+ MC44S803_REG_SM(1, MC44S803_G6) |
+ MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+ MC44S803_REG_SM(0x3, MC44S803_LP) |
+ MC44S803_REG_SM(1, MC44S803_CLRF) |
+ MC44S803_REG_SM(1, MC44S803_CLIF);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_G1) |
+ MC44S803_REG_SM(1, MC44S803_G3) |
+ MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+ MC44S803_REG_SM(1, MC44S803_G6) |
+ MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+ MC44S803_REG_SM(0x3, MC44S803_LP);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup Digtune */
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(3, MC44S803_XOD);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+/* Setup AGC */
+
+ val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_AT1) |
+ MC44S803_REG_SM(1, MC44S803_AT2) |
+ MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
+ MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
+ MC44S803_REG_SM(1, MC44S803_LNA0);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ return 0;
+
+exit:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ mc_printk(KERN_WARNING, "I/O Error\n");
+ return err;
+}
+
+static int mc44s803_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ u32 r1, r2, n1, n2, lo1, lo2, freq, val;
+ int err;
+
+ priv->frequency = params->frequency;
+
+ r1 = MC44S803_OSC / 1000000;
+ r2 = MC44S803_OSC / 100000;
+
+ n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000;
+ freq = MC44S803_OSC / r1 * n1;
+ lo1 = ((60 * n1) + (r1 / 2)) / r1;
+ freq = freq - params->frequency;
+
+ n2 = (freq - MC44S803_IF2 + 50000) / 100000;
+ lo2 = ((60 * n2) + (r2 / 2)) / r2;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
+ MC44S803_REG_SM(r1-1, MC44S803_R1) |
+ MC44S803_REG_SM(r2-1, MC44S803_R2) |
+ MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
+ MC44S803_REG_SM(n1-2, MC44S803_LO1);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
+ MC44S803_REG_SM(n2-2, MC44S803_LO2);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(1, MC44S803_DA) |
+ MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
+ MC44S803_REG_SM(1, MC44S803_AT);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+ MC44S803_REG_SM(2, MC44S803_DA) |
+ MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
+ MC44S803_REG_SM(1, MC44S803_AT);
+
+ err = mc44s803_writereg(priv, val);
+ if (err)
+ goto exit;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+
+exit:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ mc_printk(KERN_WARNING, "I/O Error\n");
+ return err;
+}
+
+static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct mc44s803_priv *priv = fe->tuner_priv;
+ *frequency = priv->frequency;
+ return 0;
+}
+
+static const struct dvb_tuner_ops mc44s803_tuner_ops = {
+ .info = {
+ .name = "Freescale MC44S803",
+ .frequency_min = 48000000,
+ .frequency_max = 1000000000,
+ .frequency_step = 100000,
+ },
+
+ .release = mc44s803_release,
+ .init = mc44s803_init,
+ .set_params = mc44s803_set_params,
+ .get_frequency = mc44s803_get_frequency
+};
+
+/* This functions tries to identify a MC44S803 tuner by reading the ID
+ register. This is hasty. */
+struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+ struct mc44s803_priv *priv;
+ u32 reg;
+ u8 id;
+ int ret;
+
+ reg = 0;
+
+ priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->cfg = cfg;
+ priv->i2c = i2c;
+ priv->fe = fe;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
+ if (ret)
+ goto error;
+
+ id = MC44S803_REG_MS(reg, MC44S803_ID);
+
+ if (id != 0x14) {
+ mc_printk(KERN_ERR, "unsupported ID "
+ "(%x should be 0x14)\n", id);
+ goto error;
+ }
+
+ mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
+ memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+
+ fe->tuner_priv = priv;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return fe;
+
+error:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ kfree(priv);
+ return NULL;
+}
+EXPORT_SYMBOL(mc44s803_attach);
+
+MODULE_AUTHOR("Jochen Friedrich");
+MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/mc44s803.h b/drivers/media/common/tuners/mc44s803.h
new file mode 100644
index 00000000000..34f3892d3f6
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803.h
@@ -0,0 +1,46 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MC44S803_H
+#define MC44S803_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mc44s803_config {
+ u8 i2c_address;
+ u8 dig_out;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
+ (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg);
+#else
+static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
+
+#endif
diff --git a/drivers/media/common/tuners/mc44s803_priv.h b/drivers/media/common/tuners/mc44s803_priv.h
new file mode 100644
index 00000000000..14a92780906
--- /dev/null
+++ b/drivers/media/common/tuners/mc44s803_priv.h
@@ -0,0 +1,208 @@
+/*
+ * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
+ */
+
+#ifndef MC44S803_PRIV_H
+#define MC44S803_PRIV_H
+
+/* This driver is based on the information available in the datasheet
+ http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
+
+ SPI or I2C Address : 0xc0-0xc6
+
+ Reg.No | Function
+ -------------------------------------------
+ 00 | Power Down
+ 01 | Reference Oszillator
+ 02 | Reference Dividers
+ 03 | Mixer and Reference Buffer
+ 04 | Reset/Serial Out
+ 05 | LO 1
+ 06 | LO 2
+ 07 | Circuit Adjust
+ 08 | Test
+ 09 | Digital Tune
+ 0A | LNA AGC
+ 0B | Data Register Address
+ 0C | Regulator Test
+ 0D | VCO Test
+ 0E | LNA Gain/Input Power
+ 0F | ID Bits
+
+*/
+
+#define MC44S803_OSC 26000000 /* 26 MHz */
+#define MC44S803_IF1 1086000000 /* 1086 MHz */
+#define MC44S803_IF2 36125000 /* 36.125 MHz */
+
+#define MC44S803_REG_POWER 0
+#define MC44S803_REG_REFOSC 1
+#define MC44S803_REG_REFDIV 2
+#define MC44S803_REG_MIXER 3
+#define MC44S803_REG_RESET 4
+#define MC44S803_REG_LO1 5
+#define MC44S803_REG_LO2 6
+#define MC44S803_REG_CIRCADJ 7
+#define MC44S803_REG_TEST 8
+#define MC44S803_REG_DIGTUNE 9
+#define MC44S803_REG_LNAAGC 0x0A
+#define MC44S803_REG_DATAREG 0x0B
+#define MC44S803_REG_REGTEST 0x0C
+#define MC44S803_REG_VCOTEST 0x0D
+#define MC44S803_REG_LNAGAIN 0x0E
+#define MC44S803_REG_ID 0x0F
+
+/* Register definitions */
+#define MC44S803_ADDR 0x0F
+#define MC44S803_ADDR_S 0
+/* REG_POWER */
+#define MC44S803_POWER 0xFFFFF0
+#define MC44S803_POWER_S 4
+/* REG_REFOSC */
+#define MC44S803_REFOSC 0x1FF0
+#define MC44S803_REFOSC_S 4
+#define MC44S803_OSCSEL 0x2000
+#define MC44S803_OSCSEL_S 13
+/* REG_REFDIV */
+#define MC44S803_R2 0x1FF0
+#define MC44S803_R2_S 4
+#define MC44S803_REFBUF_EN 0x2000
+#define MC44S803_REFBUF_EN_S 13
+#define MC44S803_R1 0x7C000
+#define MC44S803_R1_S 14
+/* REG_MIXER */
+#define MC44S803_R3 0x70
+#define MC44S803_R3_S 4
+#define MC44S803_MUX3 0x80
+#define MC44S803_MUX3_S 7
+#define MC44S803_MUX4 0x100
+#define MC44S803_MUX4_S 8
+#define MC44S803_OSC_SCR 0x200
+#define MC44S803_OSC_SCR_S 9
+#define MC44S803_TRI_STATE 0x400
+#define MC44S803_TRI_STATE_S 10
+#define MC44S803_BUF_GAIN 0x800
+#define MC44S803_BUF_GAIN_S 11
+#define MC44S803_BUF_IO 0x1000
+#define MC44S803_BUF_IO_S 12
+#define MC44S803_MIXER_RES 0xFE000
+#define MC44S803_MIXER_RES_S 13
+/* REG_RESET */
+#define MC44S803_RS 0x10
+#define MC44S803_RS_S 4
+#define MC44S803_SO 0x20
+#define MC44S803_SO_S 5
+/* REG_LO1 */
+#define MC44S803_LO1 0xFFF0
+#define MC44S803_LO1_S 4
+/* REG_LO2 */
+#define MC44S803_LO2 0x7FFF0
+#define MC44S803_LO2_S 4
+/* REG_CIRCADJ */
+#define MC44S803_G1 0x20
+#define MC44S803_G1_S 5
+#define MC44S803_G3 0x80
+#define MC44S803_G3_S 7
+#define MC44S803_CIRCADJ_RES 0x300
+#define MC44S803_CIRCADJ_RES_S 8
+#define MC44S803_G6 0x400
+#define MC44S803_G6_S 10
+#define MC44S803_G7 0x800
+#define MC44S803_G7_S 11
+#define MC44S803_S1 0x1000
+#define MC44S803_S1_S 12
+#define MC44S803_LP 0x7E000
+#define MC44S803_LP_S 13
+#define MC44S803_CLRF 0x80000
+#define MC44S803_CLRF_S 19
+#define MC44S803_CLIF 0x100000
+#define MC44S803_CLIF_S 20
+/* REG_TEST */
+/* REG_DIGTUNE */
+#define MC44S803_DA 0xF0
+#define MC44S803_DA_S 4
+#define MC44S803_XOD 0x300
+#define MC44S803_XOD_S 8
+#define MC44S803_RST 0x10000
+#define MC44S803_RST_S 16
+#define MC44S803_LO_REF 0x1FFF00
+#define MC44S803_LO_REF_S 8
+#define MC44S803_AT 0x200000
+#define MC44S803_AT_S 21
+#define MC44S803_MT 0x400000
+#define MC44S803_MT_S 22
+/* REG_LNAAGC */
+#define MC44S803_G 0x3F0
+#define MC44S803_G_S 4
+#define MC44S803_AT1 0x400
+#define MC44S803_AT1_S 10
+#define MC44S803_AT2 0x800
+#define MC44S803_AT2_S 11
+#define MC44S803_HL_GR_EN 0x8000
+#define MC44S803_HL_GR_EN_S 15
+#define MC44S803_AGC_AN_DIG 0x10000
+#define MC44S803_AGC_AN_DIG_S 16
+#define MC44S803_ATTEN_EN 0x20000
+#define MC44S803_ATTEN_EN_S 17
+#define MC44S803_AGC_READ_EN 0x40000
+#define MC44S803_AGC_READ_EN_S 18
+#define MC44S803_LNA0 0x80000
+#define MC44S803_LNA0_S 19
+#define MC44S803_AGC_SEL 0x100000
+#define MC44S803_AGC_SEL_S 20
+#define MC44S803_AT0 0x200000
+#define MC44S803_AT0_S 21
+#define MC44S803_B 0xC00000
+#define MC44S803_B_S 22
+/* REG_DATAREG */
+#define MC44S803_D 0xF0
+#define MC44S803_D_S 4
+/* REG_REGTEST */
+/* REG_VCOTEST */
+/* REG_LNAGAIN */
+#define MC44S803_IF_PWR 0x700
+#define MC44S803_IF_PWR_S 8
+#define MC44S803_RF_PWR 0x3800
+#define MC44S803_RF_PWR_S 11
+#define MC44S803_LNA_GAIN 0xFC000
+#define MC44S803_LNA_GAIN_S 14
+/* REG_ID */
+#define MC44S803_ID 0x3E00
+#define MC44S803_ID_S 9
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define MC44S803_REG_SM(_val, _reg) \
+ (((_val) << _reg##_S) & (_reg))
+
+/* First mask, then shift */
+#define MC44S803_REG_MS(_val, _reg) \
+ (((_val) & (_reg)) >> _reg##_S)
+
+struct mc44s803_priv {
+ struct mc44s803_config *cfg;
+ struct i2c_adapter *i2c;
+ struct dvb_frontend *fe;
+
+ u32 frequency;
+};
+
+#endif
diff --git a/drivers/media/common/tuners/mt2060.c b/drivers/media/common/tuners/mt2060.c
index 12206d75dd4..c7abe3d8f90 100644
--- a/drivers/media/common/tuners/mt2060.c
+++ b/drivers/media/common/tuners/mt2060.c
@@ -278,7 +278,7 @@ static void mt2060_calibrate(struct mt2060_priv *priv)
while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
msleep(20);
- if (i < 10) {
+ if (i <= 10) {
mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
dprintk("calibration was successful: %d", (int)priv->fmfreq);
} else
diff --git a/drivers/media/common/tuners/mt20xx.c b/drivers/media/common/tuners/mt20xx.c
index 35b763a16d5..44608ad4e2d 100644
--- a/drivers/media/common/tuners/mt20xx.c
+++ b/drivers/media/common/tuners/mt20xx.c
@@ -6,7 +6,7 @@
*/
#include <linux/delay.h>
#include <linux/i2c.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include "tuner-i2c.h"
#include "mt20xx.h"
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 31522d2e318..0803dab58ff 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -4003,12 +4003,11 @@ static int mxl5005s_set_params(struct dvb_frontend *fe,
/* Change tuner for new modulation type if reqd */
if (req_mode != state->current_mode) {
switch (req_mode) {
- case VSB_8:
- case QAM_64:
- case QAM_256:
- case QAM_AUTO:
+ case MXL_ATSC:
+ case MXL_QAM:
req_bw = MXL5005S_BANDWIDTH_6MHZ;
break;
+ case MXL_DVBT:
default:
/* Assume DVB-T */
switch (params->u.ofdm.bandwidth) {
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 3ec28945c26..2d02698d4f4 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -1,7 +1,7 @@
/*
* mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
*
- * Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
+ * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.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
@@ -66,22 +66,17 @@ MODULE_PARM_DESC(debug, "set debug level");
#define MHz 1000000
enum mxl5007t_mode {
- MxL_MODE_OTA_DVBT_ATSC = 0,
- MxL_MODE_OTA_NTSC_PAL_GH = 1,
- MxL_MODE_OTA_PAL_IB = 2,
- MxL_MODE_OTA_PAL_D_SECAM_KL = 3,
- MxL_MODE_OTA_ISDBT = 4,
- MxL_MODE_CABLE_DIGITAL = 0x10,
- MxL_MODE_CABLE_NTSC_PAL_GH = 0x11,
- MxL_MODE_CABLE_PAL_IB = 0x12,
- MxL_MODE_CABLE_PAL_D_SECAM_KL = 0x13,
- MxL_MODE_CABLE_SCTE40 = 0x14,
+ MxL_MODE_ISDBT = 0,
+ MxL_MODE_DVBT = 1,
+ MxL_MODE_ATSC = 2,
+ MxL_MODE_CABLE = 0x10,
};
enum mxl5007t_chip_version {
MxL_UNKNOWN_ID = 0x00,
MxL_5007_V1_F1 = 0x11,
MxL_5007_V1_F2 = 0x12,
+ MxL_5007_V4 = 0x14,
MxL_5007_V2_100_F1 = 0x21,
MxL_5007_V2_100_F2 = 0x22,
MxL_5007_V2_200_F1 = 0x23,
@@ -96,67 +91,61 @@ struct reg_pair_t {
/* ------------------------------------------------------------------------- */
static struct reg_pair_t init_tab[] = {
- { 0x0b, 0x44 }, /* XTAL */
- { 0x0c, 0x60 }, /* IF */
- { 0x10, 0x00 }, /* MISC */
- { 0x12, 0xca }, /* IDAC */
- { 0x16, 0x90 }, /* MODE */
- { 0x32, 0x38 }, /* MODE Analog/Digital */
- { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
- { 0x2c, 0x34 }, /* OVERRIDE */
- { 0x4d, 0x40 }, /* OVERRIDE */
- { 0x7f, 0x02 }, /* OVERRIDE */
- { 0x9a, 0x52 }, /* OVERRIDE */
- { 0x48, 0x5a }, /* OVERRIDE */
- { 0x76, 0x1a }, /* OVERRIDE */
- { 0x6a, 0x48 }, /* OVERRIDE */
- { 0x64, 0x28 }, /* OVERRIDE */
- { 0x66, 0xe6 }, /* OVERRIDE */
- { 0x35, 0x0e }, /* OVERRIDE */
- { 0x7e, 0x01 }, /* OVERRIDE */
- { 0x83, 0x00 }, /* OVERRIDE */
- { 0x04, 0x0b }, /* OVERRIDE */
- { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0x02, 0x06 },
+ { 0x03, 0x48 },
+ { 0x05, 0x04 },
+ { 0x06, 0x10 },
+ { 0x2e, 0x15 }, /* OVERRIDE */
+ { 0x30, 0x10 }, /* OVERRIDE */
+ { 0x45, 0x58 }, /* OVERRIDE */
+ { 0x48, 0x19 }, /* OVERRIDE */
+ { 0x52, 0x03 }, /* OVERRIDE */
+ { 0x53, 0x44 }, /* OVERRIDE */
+ { 0x6a, 0x4b }, /* OVERRIDE */
+ { 0x76, 0x00 }, /* OVERRIDE */
+ { 0x78, 0x18 }, /* OVERRIDE */
+ { 0x7a, 0x17 }, /* OVERRIDE */
+ { 0x85, 0x06 }, /* OVERRIDE */
+ { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
{ 0, 0 }
};
static struct reg_pair_t init_tab_cable[] = {
- { 0x0b, 0x44 }, /* XTAL */
- { 0x0c, 0x60 }, /* IF */
- { 0x10, 0x00 }, /* MISC */
- { 0x12, 0xca }, /* IDAC */
- { 0x16, 0x90 }, /* MODE */
- { 0x32, 0x38 }, /* MODE A/D */
- { 0x71, 0x3f }, /* TOP1 */
- { 0x72, 0x3f }, /* TOP2 */
- { 0x74, 0x3f }, /* TOP3 */
- { 0xd8, 0x18 }, /* CLK_OUT_ENABLE */
- { 0x2c, 0x34 }, /* OVERRIDE */
- { 0x4d, 0x40 }, /* OVERRIDE */
- { 0x7f, 0x02 }, /* OVERRIDE */
- { 0x9a, 0x52 }, /* OVERRIDE */
- { 0x48, 0x5a }, /* OVERRIDE */
- { 0x76, 0x1a }, /* OVERRIDE */
- { 0x6a, 0x48 }, /* OVERRIDE */
- { 0x64, 0x28 }, /* OVERRIDE */
- { 0x66, 0xe6 }, /* OVERRIDE */
- { 0x35, 0x0e }, /* OVERRIDE */
- { 0x7e, 0x01 }, /* OVERRIDE */
- { 0x04, 0x0b }, /* OVERRIDE */
- { 0x68, 0xb4 }, /* OVERRIDE */
- { 0x36, 0x00 }, /* OVERRIDE */
- { 0x05, 0x01 }, /* TOP_MASTER_ENABLE */
+ { 0x02, 0x06 },
+ { 0x03, 0x48 },
+ { 0x05, 0x04 },
+ { 0x06, 0x10 },
+ { 0x09, 0x3f },
+ { 0x0a, 0x3f },
+ { 0x0b, 0x3f },
+ { 0x2e, 0x15 }, /* OVERRIDE */
+ { 0x30, 0x10 }, /* OVERRIDE */
+ { 0x45, 0x58 }, /* OVERRIDE */
+ { 0x48, 0x19 }, /* OVERRIDE */
+ { 0x52, 0x03 }, /* OVERRIDE */
+ { 0x53, 0x44 }, /* OVERRIDE */
+ { 0x6a, 0x4b }, /* OVERRIDE */
+ { 0x76, 0x00 }, /* OVERRIDE */
+ { 0x78, 0x18 }, /* OVERRIDE */
+ { 0x7a, 0x17 }, /* OVERRIDE */
+ { 0x85, 0x06 }, /* OVERRIDE */
+ { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
{ 0, 0 }
};
/* ------------------------------------------------------------------------- */
static struct reg_pair_t reg_pair_rftune[] = {
- { 0x11, 0x00 }, /* abort tune */
- { 0x13, 0x15 },
- { 0x14, 0x40 },
- { 0x15, 0x0e },
- { 0x11, 0x02 }, /* start tune */
+ { 0x0f, 0x00 }, /* abort tune */
+ { 0x0c, 0x15 },
+ { 0x0d, 0x40 },
+ { 0x0e, 0x0e },
+ { 0x1f, 0x87 }, /* OVERRIDE */
+ { 0x20, 0x1f }, /* OVERRIDE */
+ { 0x21, 0x87 }, /* OVERRIDE */
+ { 0x22, 0x1f }, /* OVERRIDE */
+ { 0x80, 0x01 }, /* freq dependent */
+ { 0x0f, 0x01 }, /* start tune */
{ 0, 0 }
};
@@ -227,63 +216,20 @@ static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
s32 if_diff_out_level)
{
switch (mode) {
- case MxL_MODE_OTA_DVBT_ATSC:
- set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
- set_reg_bits(state->tab_init, 0x35, 0xff, 0x0e);
+ case MxL_MODE_ATSC:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
break;
- case MxL_MODE_OTA_ISDBT:
- set_reg_bits(state->tab_init, 0x32, 0x0f, 0x06);
- set_reg_bits(state->tab_init, 0x35, 0xff, 0x12);
+ case MxL_MODE_DVBT:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
break;
- case MxL_MODE_OTA_NTSC_PAL_GH:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
+ case MxL_MODE_ISDBT:
+ set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
break;
- case MxL_MODE_OTA_PAL_IB:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- break;
- case MxL_MODE_OTA_PAL_D_SECAM_KL:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- break;
- case MxL_MODE_CABLE_DIGITAL:
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_NTSC_PAL_GH:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x00);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_PAL_IB:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x10);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
+ case MxL_MODE_CABLE:
+ set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
+ set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_PAL_D_SECAM_KL:
- set_reg_bits(state->tab_init, 0x16, 0x70, 0x20);
- set_reg_bits(state->tab_init, 0x32, 0xff, 0x85);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
- break;
- case MxL_MODE_CABLE_SCTE40:
- set_reg_bits(state->tab_init_cable, 0x36, 0xff, 0x08);
- set_reg_bits(state->tab_init_cable, 0x68, 0xff, 0xbc);
- set_reg_bits(state->tab_init_cable, 0x71, 0xff, 0x01);
- set_reg_bits(state->tab_init_cable, 0x72, 0xff,
- 8 - if_diff_out_level);
- set_reg_bits(state->tab_init_cable, 0x74, 0xff, 0x17);
+ set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
break;
default:
mxl_fail(-EINVAL);
@@ -302,43 +248,43 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
val = 0x00;
break;
case MxL_IF_4_5_MHZ:
- val = 0x20;
+ val = 0x02;
break;
case MxL_IF_4_57_MHZ:
- val = 0x30;
+ val = 0x03;
break;
case MxL_IF_5_MHZ:
- val = 0x40;
+ val = 0x04;
break;
case MxL_IF_5_38_MHZ:
- val = 0x50;
+ val = 0x05;
break;
case MxL_IF_6_MHZ:
- val = 0x60;
+ val = 0x06;
break;
case MxL_IF_6_28_MHZ:
- val = 0x70;
+ val = 0x07;
break;
case MxL_IF_9_1915_MHZ:
- val = 0x80;
+ val = 0x08;
break;
case MxL_IF_35_25_MHZ:
- val = 0x90;
+ val = 0x09;
break;
case MxL_IF_36_15_MHZ:
- val = 0xa0;
+ val = 0x0a;
break;
case MxL_IF_44_MHZ:
- val = 0xb0;
+ val = 0x0b;
break;
default:
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_init, 0x0c, 0xf0, val);
+ set_reg_bits(state->tab_init, 0x02, 0x0f, val);
/* set inverted IF or normal IF */
- set_reg_bits(state->tab_init, 0x0c, 0x08, invert_if ? 0x08 : 0x00);
+ set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
return;
}
@@ -346,56 +292,68 @@ static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
enum mxl5007t_xtal_freq xtal_freq)
{
- u8 val;
-
switch (xtal_freq) {
case MxL_XTAL_16_MHZ:
- val = 0x00; /* select xtal freq & Ref Freq */
+ /* select xtal freq & ref freq */
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
break;
case MxL_XTAL_20_MHZ:
- val = 0x11;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
break;
case MxL_XTAL_20_25_MHZ:
- val = 0x22;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
break;
case MxL_XTAL_20_48_MHZ:
- val = 0x33;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
break;
case MxL_XTAL_24_MHZ:
- val = 0x44;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
break;
case MxL_XTAL_25_MHZ:
- val = 0x55;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
break;
case MxL_XTAL_25_14_MHZ:
- val = 0x66;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
break;
case MxL_XTAL_27_MHZ:
- val = 0x77;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
break;
case MxL_XTAL_28_8_MHZ:
- val = 0x88;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
break;
case MxL_XTAL_32_MHZ:
- val = 0x99;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
break;
case MxL_XTAL_40_MHZ:
- val = 0xaa;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
break;
case MxL_XTAL_44_MHZ:
- val = 0xbb;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
break;
case MxL_XTAL_48_MHZ:
- val = 0xcc;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
break;
case MxL_XTAL_49_3811_MHZ:
- val = 0xdd;
+ set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
+ set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
break;
default:
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_init, 0x0b, 0xff, val);
return;
}
@@ -412,16 +370,11 @@ static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
- set_reg_bits(state->tab_init, 0x10, 0x40, cfg->loop_thru_enable << 6);
-
- set_reg_bits(state->tab_init, 0xd8, 0x08, cfg->clk_out_enable << 3);
-
- set_reg_bits(state->tab_init, 0x10, 0x07, cfg->clk_out_amp);
+ set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
+ set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
+ set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
- /* set IDAC to automatic mode control by AGC */
- set_reg_bits(state->tab_init, 0x12, 0x80, 0x00);
-
- if (mode >= MxL_MODE_CABLE_DIGITAL) {
+ if (mode >= MxL_MODE_CABLE) {
copy_reg_bits(state->tab_init, state->tab_init_cable);
return state->tab_init_cable;
} else
@@ -447,7 +400,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
* and DIG_MODEINDEX_CSF */
break;
case MxL_BW_7MHz:
- val = 0x21;
+ val = 0x2a;
break;
case MxL_BW_8MHz:
val = 0x3f;
@@ -456,7 +409,7 @@ static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
mxl_fail(-EINVAL);
return;
}
- set_reg_bits(state->tab_rftune, 0x13, 0x3f, val);
+ set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
return;
}
@@ -493,8 +446,11 @@ reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
if (temp > 7812)
dig_rf_freq++;
- set_reg_bits(state->tab_rftune, 0x14, 0xff, (u8)dig_rf_freq);
- set_reg_bits(state->tab_rftune, 0x15, 0xff, (u8)(dig_rf_freq >> 8));
+ set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
+ set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
+
+ if (rf_freq >= 333000000)
+ set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
return state->tab_rftune;
}
@@ -551,9 +507,10 @@ static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
static int mxl5007t_soft_reset(struct mxl5007t_state *state)
{
u8 d = 0xff;
- struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
- .buf = &d, .len = 1 };
-
+ struct i2c_msg msg = {
+ .addr = state->i2c_props.addr, .flags = 0,
+ .buf = &d, .len = 1
+ };
int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
if (ret != 1) {
@@ -580,9 +537,6 @@ static int mxl5007t_tuner_init(struct mxl5007t_state *state,
if (mxl_fail(ret))
goto fail;
mdelay(1);
-
- ret = mxl5007t_write_reg(state, 0x2c, 0x35);
- mxl_fail(ret);
fail:
return ret;
}
@@ -615,7 +569,7 @@ static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
*rf_locked = 0;
*ref_locked = 0;
- ret = mxl5007t_read_reg(state, 0xcf, &d);
+ ret = mxl5007t_read_reg(state, 0xd8, &d);
if (mxl_fail(ret))
goto fail;
@@ -628,37 +582,14 @@ fail:
return ret;
}
-static int mxl5007t_check_rf_input_power(struct mxl5007t_state *state,
- s32 *rf_input_level)
-{
- u8 d1, d2;
- int ret;
-
- ret = mxl5007t_read_reg(state, 0xb7, &d1);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_read_reg(state, 0xbf, &d2);
- if (mxl_fail(ret))
- goto fail;
-
- d2 = d2 >> 4;
- if (d2 > 7)
- d2 += 0xf0;
-
- *rf_input_level = (s32)(d1 + d2 - 113);
-fail:
- return ret;
-}
-
/* ------------------------------------------------------------------------- */
static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
{
struct mxl5007t_state *state = fe->tuner_priv;
- int rf_locked, ref_locked;
- s32 rf_input_level = 0;
- int ret;
+ int rf_locked, ref_locked, ret;
+
+ *status = 0;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -669,10 +600,8 @@ static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
mxl_debug("%s%s", rf_locked ? "rf locked " : "",
ref_locked ? "ref locked" : "");
- ret = mxl5007t_check_rf_input_power(state, &rf_input_level);
- if (mxl_fail(ret))
- goto fail;
- mxl_debug("rf input power: %d", rf_input_level);
+ if ((rf_locked) || (ref_locked))
+ *status |= TUNER_STATUS_LOCKED;
fail:
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -695,11 +624,11 @@ static int mxl5007t_set_params(struct dvb_frontend *fe,
switch (params->u.vsb.modulation) {
case VSB_8:
case VSB_16:
- mode = MxL_MODE_OTA_DVBT_ATSC;
+ mode = MxL_MODE_ATSC;
break;
case QAM_64:
case QAM_256:
- mode = MxL_MODE_CABLE_DIGITAL;
+ mode = MxL_MODE_CABLE;
break;
default:
mxl_err("modulation not set!");
@@ -721,7 +650,7 @@ static int mxl5007t_set_params(struct dvb_frontend *fe,
mxl_err("bandwidth not set!");
return -EINVAL;
}
- mode = MxL_MODE_OTA_DVBT_ATSC;
+ mode = MxL_MODE_DVBT;
} else {
mxl_err("modulation type not supported!");
return -EINVAL;
@@ -752,96 +681,20 @@ fail:
return ret;
}
-static int mxl5007t_set_analog_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- struct mxl5007t_state *state = fe->tuner_priv;
- enum mxl5007t_bw_mhz bw = 0; /* FIXME */
- enum mxl5007t_mode cbl_mode;
- enum mxl5007t_mode ota_mode;
- char *mode_name;
- int ret;
- u32 freq = params->frequency * 62500;
-
-#define cable 1
- if (params->std & V4L2_STD_MN) {
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- mode_name = "MN";
- } else if (params->std & V4L2_STD_B) {
- cbl_mode = MxL_MODE_CABLE_PAL_IB;
- ota_mode = MxL_MODE_OTA_PAL_IB;
- mode_name = "B";
- } else if (params->std & V4L2_STD_GH) {
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- mode_name = "GH";
- } else if (params->std & V4L2_STD_PAL_I) {
- cbl_mode = MxL_MODE_CABLE_PAL_IB;
- ota_mode = MxL_MODE_OTA_PAL_IB;
- mode_name = "I";
- } else if (params->std & V4L2_STD_DK) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "DK";
- } else if (params->std & V4L2_STD_SECAM_L) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "L";
- } else if (params->std & V4L2_STD_SECAM_LC) {
- cbl_mode = MxL_MODE_CABLE_PAL_D_SECAM_KL;
- ota_mode = MxL_MODE_OTA_PAL_D_SECAM_KL;
- mode_name = "L'";
- } else {
- mode_name = "xx";
- /* FIXME */
- cbl_mode = MxL_MODE_CABLE_NTSC_PAL_GH;
- ota_mode = MxL_MODE_OTA_NTSC_PAL_GH;
- }
- mxl_debug("setting mxl5007 to system %s", mode_name);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
-
- mutex_lock(&state->lock);
-
- ret = mxl5007t_tuner_init(state, cable ? cbl_mode : ota_mode);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_tuner_rf_tune(state, freq, bw);
- if (mxl_fail(ret))
- goto fail;
-
- state->frequency = freq;
- state->bandwidth = 0;
-fail:
- mutex_unlock(&state->lock);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
-
- return ret;
-}
-
/* ------------------------------------------------------------------------- */
static int mxl5007t_init(struct dvb_frontend *fe)
{
struct mxl5007t_state *state = fe->tuner_priv;
int ret;
- u8 d;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- ret = mxl5007t_read_reg(state, 0x05, &d);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_write_reg(state, 0x05, d | 0x01);
+ /* wake from standby */
+ ret = mxl5007t_write_reg(state, 0x01, 0x01);
mxl_fail(ret);
-fail:
+
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -852,18 +705,16 @@ static int mxl5007t_sleep(struct dvb_frontend *fe)
{
struct mxl5007t_state *state = fe->tuner_priv;
int ret;
- u8 d;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
- ret = mxl5007t_read_reg(state, 0x05, &d);
- if (mxl_fail(ret))
- goto fail;
-
- ret = mxl5007t_write_reg(state, 0x05, d & ~0x01);
+ /* enter standby mode */
+ ret = mxl5007t_write_reg(state, 0x01, 0x00);
mxl_fail(ret);
-fail:
+ ret = mxl5007t_write_reg(state, 0x0f, 0x00);
+ mxl_fail(ret);
+
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -911,7 +762,6 @@ static struct dvb_tuner_ops mxl5007t_tuner_ops = {
.init = mxl5007t_init,
.sleep = mxl5007t_sleep,
.set_params = mxl5007t_set_params,
- .set_analog_params = mxl5007t_set_analog_params,
.get_status = mxl5007t_get_status,
.get_frequency = mxl5007t_get_frequency,
.get_bandwidth = mxl5007t_get_bandwidth,
@@ -924,7 +774,7 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
int ret;
u8 id;
- ret = mxl5007t_read_reg(state, 0xd3, &id);
+ ret = mxl5007t_read_reg(state, 0xd9, &id);
if (mxl_fail(ret))
goto fail;
@@ -947,8 +797,12 @@ static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
case MxL_5007_V2_200_F2:
name = "MxL5007.v2.200.f2";
break;
+ case MxL_5007_V4:
+ name = "MxL5007T.v4";
+ break;
default:
name = "MxL5007T";
+ printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
id = MxL_UNKNOWN_ID;
}
state->chip_id = id;
@@ -975,7 +829,7 @@ struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
mutex_lock(&mxl5007t_list_mutex);
instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
hybrid_tuner_instance_list,
- i2c, addr, "mxl5007");
+ i2c, addr, "mxl5007t");
switch (instance) {
case 0:
goto fail;
@@ -1018,7 +872,7 @@ EXPORT_SYMBOL_GPL(mxl5007t_attach);
MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
MODULE_LICENSE("GPL");
-MODULE_VERSION("0.1");
+MODULE_VERSION("0.2");
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index 6fb5b458656..fc76c30e24f 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -490,9 +490,9 @@ int tda18271_set_standby_mode(struct dvb_frontend *fe,
tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */
- regs[R_EP3] |= sm ? (1 << 7) : 0 |
- sm_lt ? (1 << 6) : 0 |
- sm_xt ? (1 << 5) : 0;
+ regs[R_EP3] |= (sm ? (1 << 7) : 0) |
+ (sm_lt ? (1 << 6) : 0) |
+ (sm_xt ? (1 << 5) : 0);
return tda18271_write_regs(fe, R_EP3, 1);
}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 1b48b5d0bf1..b1093563015 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -818,6 +818,38 @@ fail:
return ret;
}
+/* ------------------------------------------------------------------ */
+
+static int tda18271_agc(struct dvb_frontend *fe)
+{
+ struct tda18271_priv *priv = fe->tuner_priv;
+ int ret = 0;
+
+ switch (priv->config) {
+ case 0:
+ /* no LNA */
+ tda_dbg("no agc configuration provided\n");
+ break;
+ case 3:
+ /* switch with GPIO of saa713x */
+ tda_dbg("invoking callback\n");
+ if (fe->callback)
+ ret = fe->callback(priv->i2c_props.adap->algo_data,
+ DVB_FRONTEND_COMPONENT_TUNER,
+ TDA18271_CALLBACK_CMD_AGC_ENABLE,
+ priv->mode);
+ break;
+ case 1:
+ case 2:
+ default:
+ /* n/a - currently not supported */
+ tda_err("unsupported configuration: %d\n", priv->config);
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
static int tda18271_tune(struct dvb_frontend *fe,
struct tda18271_std_map_item *map, u32 freq, u32 bw)
{
@@ -827,6 +859,10 @@ static int tda18271_tune(struct dvb_frontend *fe,
tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
freq, map->if_freq, bw, map->agc_mode, map->std);
+ ret = tda18271_agc(fe);
+ if (tda_fail(ret))
+ tda_warn("failed to configure agc\n");
+
ret = tda18271_init(fe);
if (tda_fail(ret))
goto fail;
@@ -1159,6 +1195,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
/* new tuner instance */
priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
+ priv->config = (cfg) ? cfg->config : 0;
priv->cal_initialized = false;
mutex_init(&priv->lock);
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 81a739365f8..74beb28806f 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -91,11 +91,6 @@ enum tda18271_pll {
TDA18271_CAL_PLL,
};
-enum tda18271_mode {
- TDA18271_ANALOG,
- TDA18271_DIGITAL,
-};
-
struct tda18271_map_layout;
enum tda18271_ver {
@@ -114,6 +109,7 @@ struct tda18271_priv {
enum tda18271_i2c_gate gate;
enum tda18271_ver id;
+ unsigned int config; /* interface to saa713x / tda829x */
unsigned int tm_rfcal;
unsigned int cal_initialized:1;
unsigned int small_i2c:1;
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 7db9831c0cb..53a9892a18d 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -79,6 +79,16 @@ struct tda18271_config {
/* some i2c providers cant write all 39 registers at once */
unsigned int small_i2c:1;
+
+ /* interface to saa713x / tda829x */
+ unsigned int config;
+};
+
+#define TDA18271_CALLBACK_CMD_AGC_ENABLE 0
+
+enum tda18271_mode {
+ TDA18271_ANALOG = 0,
+ TDA18271_DIGITAL,
};
#if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
diff --git a/drivers/media/common/tuners/tda827x.c b/drivers/media/common/tuners/tda827x.c
index f4d931f14fa..36a7bc7585a 100644
--- a/drivers/media/common/tuners/tda827x.c
+++ b/drivers/media/common/tuners/tda827x.c
@@ -132,11 +132,31 @@ static const struct tda827x_data tda827x_table[] = {
{ .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
};
+static int tuner_transfer(struct dvb_frontend *fe,
+ struct i2c_msg *msg,
+ const int size)
+{
+ int rc;
+ struct tda827x_priv *priv = fe->tuner_priv;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ rc = i2c_transfer(priv->i2c_adap, msg, size);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (rc >= 0 && rc != size)
+ return -EIO;
+
+ return rc;
+}
+
static int tda827xo_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct tda827x_priv *priv = fe->tuner_priv;
u8 buf[14];
+ int rc;
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
@@ -183,27 +203,29 @@ static int tda827xo_set_params(struct dvb_frontend *fe,
buf[13] = 0x40;
msg.len = 14;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
+
msleep(500);
/* correct CP value */
buf[0] = 0x30;
buf[1] = 0x50 + tda827x_table[i].cp;
msg.len = 2;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
priv->frequency = params->frequency;
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
return 0;
+
+err:
+ printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+ __func__, priv->i2c_addr << 1);
+ return rc;
}
static int tda827xo_sleep(struct dvb_frontend *fe)
@@ -214,9 +236,7 @@ static int tda827xo_sleep(struct dvb_frontend *fe)
.buf = buf, .len = sizeof(buf) };
dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
if (priv->cfg && priv->cfg->sleep)
priv->cfg->sleep(fe);
@@ -266,44 +286,44 @@ static int tda827xo_set_analog_params(struct dvb_frontend *fe,
msg.buf = tuner_reg;
msg.len = 8;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.buf = reg2;
msg.len = 2;
reg2[0] = 0x80;
reg2[1] = 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x60;
reg2[1] = 0xbf;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4] + 0x80;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4] + 4;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(1);
reg2[0] = 0x30;
reg2[1] = tuner_reg[4];
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(550);
reg2[0] = 0x30;
reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x60;
reg2[1] = 0x3f;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
reg2[0] = 0x80;
reg2[1] = 0x08; /* Vsync en */
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
priv->frequency = params->frequency;
@@ -317,7 +337,7 @@ static void tda827xo_agcf(struct dvb_frontend *fe)
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = data, .len = 2};
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
}
/* ------------------------------------------------------------------ */
@@ -331,7 +351,7 @@ struct tda827xa_data {
u8 gc3;
};
-static const struct tda827xa_data tda827xa_dvbt[] = {
+static struct tda827xa_data tda827xa_dvbt[] = {
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
{ .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
@@ -361,6 +381,36 @@ static const struct tda827xa_data tda827xa_dvbt[] = {
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
};
+static struct tda827xa_data tda827xa_dvbc[] = {
+ { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
+ { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
+ { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
+ { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
+ { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+ { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+ { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
+ { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+ { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
+ { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
+};
+
static struct tda827xa_data tda827xa_analog[] = {
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
@@ -398,13 +448,8 @@ static int tda827xa_sleep(struct dvb_frontend *fe)
.buf = buf, .len = sizeof(buf) };
dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
+ tuner_transfer(fe, &msg, 1);
if (priv->cfg && priv->cfg->sleep)
priv->cfg->sleep(fe);
@@ -455,7 +500,7 @@ static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
buf[1] = high ? 0 : 1;
if (priv->cfg->config == 2)
buf[1] = high ? 1 : 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
break;
case 3: /* switch with GPIO of saa713x */
if (fe->callback)
@@ -469,12 +514,13 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct tda827x_priv *priv = fe->tuner_priv;
+ struct tda827xa_data *frequency_map = tda827xa_dvbt;
u8 buf[11];
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
- int i, tuner_freq, if_freq;
+ int i, tuner_freq, if_freq, rc;
u32 N;
dprintk("%s:\n", __func__);
@@ -495,56 +541,58 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
}
tuner_freq = params->frequency + if_freq;
+ if (fe->ops.info.type == FE_QAM) {
+ dprintk("%s select tda827xa_dvbc\n", __func__);
+ frequency_map = tda827xa_dvbc;
+ }
+
i = 0;
- while (tda827xa_dvbt[i].lomax < tuner_freq) {
- if(tda827xa_dvbt[i + 1].lomax == 0)
+ while (frequency_map[i].lomax < tuner_freq) {
+ if (frequency_map[i + 1].lomax == 0)
break;
i++;
}
- N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
+ N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
buf[0] = 0; // subaddress
buf[1] = N >> 8;
buf[2] = N & 0xff;
buf[3] = 0;
buf[4] = 0x16;
- buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
- tda827xa_dvbt[i].sbs;
- buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
+ buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
+ frequency_map[i].sbs;
+ buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
buf[7] = 0x1c;
buf[8] = 0x06;
buf[9] = 0x24;
buf[10] = 0x00;
msg.len = 11;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
+
buf[0] = 0x90;
buf[1] = 0xff;
buf[2] = 0x60;
buf[3] = 0x00;
buf[4] = 0x59; // lpsel, for 6MHz + 2
msg.len = 5;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
buf[0] = 0xa0;
buf[1] = 0x40;
msg.len = 2;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(11);
msg.flags = I2C_M_RD;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msg.flags = 0;
buf[1] >>= 4;
@@ -553,49 +601,55 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
tda827xa_lna_gain(fe, 0, NULL);
buf[0] = 0x60;
buf[1] = 0x0c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
}
buf[0] = 0xc0;
buf[1] = 0x99; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
buf[0] = 0x60;
buf[1] = 0x3c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
/* correct CP value */
buf[0] = 0x30;
- buf[1] = 0x10 + tda827xa_dvbt[i].scr;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ buf[1] = 0x10 + frequency_map[i].scr;
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(163);
buf[0] = 0xc0;
buf[1] = 0x39; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
msleep(3);
/* freeze AGC1 */
buf[0] = 0x50;
- buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
+ rc = tuner_transfer(fe, &msg, 1);
+ if (rc < 0)
+ goto err;
priv->frequency = params->frequency;
priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
+
return 0;
+
+err:
+ printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
+ __func__, priv->i2c_addr << 1);
+ return rc;
}
@@ -643,7 +697,7 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
tuner_reg[9] = 0x20;
tuner_reg[10] = 0x00;
msg.len = 11;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x90;
tuner_reg[1] = 0xff;
@@ -651,19 +705,19 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
tuner_reg[3] = 0;
tuner_reg[4] = 0x99 + (priv->lpsel << 1);
msg.len = 5;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xa0;
tuner_reg[1] = 0xc0;
msg.len = 2;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x30;
tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.flags = I2C_M_RD;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msg.flags = 0;
tuner_reg[1] >>= 4;
dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
@@ -673,24 +727,24 @@ static int tda827xa_set_analog_params(struct dvb_frontend *fe,
msleep(100);
tuner_reg[0] = 0x60;
tuner_reg[1] = 0x3c;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
msleep(163);
tuner_reg[0] = 0x50;
tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0x80;
tuner_reg[1] = 0x28;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xb0;
tuner_reg[1] = 0x01;
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
tuner_reg[0] = 0xc0;
tuner_reg[1] = 0x19 + (priv->lpsel << 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
priv->frequency = params->frequency;
@@ -703,7 +757,7 @@ static void tda827xa_agcf(struct dvb_frontend *fe)
unsigned char data[] = {0x80, 0x2c};
struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
.buf = data, .len = 2};
- i2c_transfer(priv->i2c_adap, &msg, 1);
+ tuner_transfer(fe, &msg, 1);
}
/* ------------------------------------------------------------------ */
@@ -792,16 +846,19 @@ static struct dvb_tuner_ops tda827xa_tuner_ops = {
};
static int tda827x_probe_version(struct dvb_frontend *fe)
-{ u8 data;
+{
+ u8 data;
+ int rc;
struct tda827x_priv *priv = fe->tuner_priv;
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
.buf = &data, .len = 1 };
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
+
+ rc = tuner_transfer(fe, &msg, 1);
+
+ if (rc < 0) {
printk("%s: could not read from tuner at addr: 0x%02x\n",
__func__, msg.addr << 1);
- return -EIO;
+ return rc;
}
if ((data & 0x3c) == 0) {
dprintk("tda827x tuner found\n");
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 4b8662edb7c..064d14c8d7b 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -22,7 +22,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include "tuner-i2c.h"
#include "tda8290.h"
#include "tda827x.h"
@@ -566,8 +566,11 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
u8 data;
struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
- if (NULL == analog_ops->i2c_gate_ctrl)
+ if (!analog_ops->i2c_gate_ctrl) {
+ printk(KERN_ERR "tda8290: no gate control were provided!\n");
+
return -EINVAL;
+ }
analog_ops->i2c_gate_ctrl(fe, 1);
@@ -615,11 +618,13 @@ static int tda829x_find_tuner(struct dvb_frontend *fe)
if (ret != 1) {
tuner_warn("tuner access failed!\n");
+ analog_ops->i2c_gate_ctrl(fe, 0);
return -EREMOTEIO;
}
if ((data == 0x83) || (data == 0x84)) {
priv->ver |= TDA18271;
+ tda829x_tda18271_config.config = priv->cfg.config;
dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
priv->i2c_props.adap, &tda829x_tda18271_config);
} else {
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c
index b23dadeecd0..60ed872f3d4 100644
--- a/drivers/media/common/tuners/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
@@ -9,7 +9,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/tuner.h>
#include "tuner-i2c.h"
#include "tea5761.h"
diff --git a/drivers/media/common/tuners/tea5767.c b/drivers/media/common/tuners/tea5767.c
index 1f5646334a8..223a226d20a 100644
--- a/drivers/media/common/tuners/tea5767.c
+++ b/drivers/media/common/tuners/tea5767.c
@@ -12,7 +12,7 @@
#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include "tuner-i2c.h"
#include "tea5767.h"
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 493ce93caf4..b54598550dc 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -739,7 +739,10 @@ static int xc5000_set_analog_params(struct dvb_frontend *fe,
dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
__func__, params->frequency);
- priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */
+ /* Fix me: it could be air. */
+ priv->rf_mode = params->mode;
+ if (params->mode > XC_RF_MODE_CABLE)
+ priv->rf_mode = XC_RF_MODE_CABLE;
/* params->frequency is in units of 62.5khz */
priv->freq_hz = params->frequency * 62500;
@@ -970,8 +973,6 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
case 1:
/* new tuner instance */
priv->bandwidth = BANDWIDTH_6_MHZ;
- priv->if_khz = cfg->if_khz;
-
fe->tuner_priv = priv;
break;
default:
@@ -980,6 +981,13 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
break;
}
+ if (priv->if_khz == 0) {
+ /* If the IF hasn't been set yet, use the value provided by
+ the caller (occurs in hybrid devices where the analog
+ call to xc5000_attach occurs before the digital side) */
+ priv->if_khz = cfg->if_khz;
+ }
+
/* Check if firmware has been loaded. It is possible that another
instance of the driver has loaded the firmware.
*/
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig
index a8c6249c409..9e578140074 100644
--- a/drivers/media/dvb/b2c2/Kconfig
+++ b/drivers/media/dvb/b2c2/Kconfig
@@ -13,7 +13,7 @@ config DVB_B2C2_FLEXCOP
select DVB_TUNER_ITD1000 if !DVB_FE_CUSTOMISE
select DVB_ISL6421 if !DVB_FE_CUSTOMISE
select DVB_CX24123 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
select DVB_TUNER_CX24113 if !DVB_FE_CUSTOMISE
help
Support for the digital TV receiver chip made by B2C2 Inc. included in
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile
index d9db066f985..b97cf7208a1 100644
--- a/drivers/media/dvb/b2c2/Makefile
+++ b/drivers/media/dvb/b2c2/Makefile
@@ -2,7 +2,6 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
-
ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
b2c2-flexcop-objs += flexcop-dma.o
endif
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h
index 8ce06336e76..3e1c472092a 100644
--- a/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/drivers/media/dvb/b2c2/flexcop-common.h
@@ -28,11 +28,14 @@
/* Steal from usb.h */
#undef err
-#define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define err(format, arg...) \
+ printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
#undef info
-#define info(format, arg...) printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
#undef warn
-#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+ printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
struct flexcop_dma {
struct pci_dev *pdev;
@@ -91,16 +94,14 @@ struct flexcop_device {
int fullts_streaming_state;
/* bus specific callbacks */
- flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register);
- int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value);
-
-
- int (*i2c_request) (struct flexcop_i2c_adapter*,
+ flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
+ flexcop_ibi_register);
+ int (*write_ibi_reg) (struct flexcop_device *,
+ flexcop_ibi_register, flexcop_ibi_value);
+ int (*i2c_request) (struct flexcop_i2c_adapter *,
flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
- int (*stream_control) (struct flexcop_device*, int);
-
+ int (*stream_control) (struct flexcop_device *, int);
int (*get_mac_addr) (struct flexcop_device *fc, int extended);
-
void *bus_specific;
};
@@ -111,22 +112,28 @@ void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
-void flexcop_device_kfree(struct flexcop_device*);
+void flexcop_device_kfree(struct flexcop_device *);
-int flexcop_device_initialize(struct flexcop_device*);
+int flexcop_device_initialize(struct flexcop_device *);
void flexcop_device_exit(struct flexcop_device *fc);
-
void flexcop_reset_block_300(struct flexcop_device *fc);
/* from flexcop-dma.c */
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
+int flexcop_dma_allocate(struct pci_dev *pdev,
+ struct flexcop_dma *dma, u32 size);
void flexcop_dma_free(struct flexcop_dma *dma);
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
-int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
-int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no, int onoff);
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no, int onoff);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
+ flexcop_dma_index_t dma_idx);
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
+ int onoff);
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx, u8 cycles);
/* from flexcop-eeprom.c */
/* the PCI part uses this call to get the MAC address, the USB part has its own */
@@ -141,13 +148,15 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
u8 chipaddr, u8 addr, u8 *buf, u16 len);
/* from flexcop-sram.c */
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target);
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+ flexcop_sram_dest_target_t target);
void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
-void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill);
+void flexcop_sram_ctrl(struct flexcop_device *fc,
+ int usb_wan, int sramdma, int maximumfill);
/* global prototypes for the flexcop-chip */
/* from flexcop-fe-tuner.c */
-int flexcop_frontend_init(struct flexcop_device *card);
+int flexcop_frontend_init(struct flexcop_device *fc);
void flexcop_frontend_exit(struct flexcop_device *fc);
/* from flexcop-i2c.c */
@@ -159,11 +168,14 @@ int flexcop_sram_init(struct flexcop_device *fc);
/* from flexcop-misc.c */
void flexcop_determine_revision(struct flexcop_device *fc);
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
+void flexcop_device_name(struct flexcop_device *fc,
+ const char *prefix, const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, int num);
/* from flexcop-hw-filter.c */
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+ struct dvb_demux_feed *dvbdmxfeed, int onoff);
void flexcop_hw_filter_init(struct flexcop_device *fc);
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c
index 26f0011a507..2881e0d956a 100644
--- a/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -1,13 +1,12 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size)
+int flexcop_dma_allocate(struct pci_dev *pdev,
+ struct flexcop_dma *dma, u32 size)
{
u8 *tcpu;
dma_addr_t tdma = 0;
@@ -32,7 +31,8 @@ EXPORT_SYMBOL(flexcop_dma_allocate);
void flexcop_dma_free(struct flexcop_dma *dma)
{
- pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0);
+ pci_free_consistent(dma->pdev, dma->size*2,
+ dma->cpu_addr0, dma->dma_addr0);
memset(dma,0,sizeof(struct flexcop_dma));
}
EXPORT_SYMBOL(flexcop_dma_free);
@@ -44,8 +44,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
flexcop_ibi_value v0x0,v0x4,v0xc;
v0x0.raw = v0x4.raw = v0xc.raw = 0;
- v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
- v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
+ v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
+ v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
if ((dma_idx & FC_DMA_1) == dma_idx) {
@@ -57,7 +57,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
fc->write_ibi_reg(fc,dma2_014,v0x4);
fc->write_ibi_reg(fc,dma2_01c,v0xc);
} else {
- err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
+ err("either DMA1 or DMA2 can be configured within one "
+ "flexcop_dma_config call.");
return -EINVAL;
}
@@ -81,7 +82,8 @@ int flexcop_dma_xfer_control(struct flexcop_device *fc,
r0x0 = dma2_010;
r0xc = dma2_01c;
} else {
- err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+ err("either transfer DMA1 or DMA2 can be started within one "
+ "flexcop_dma_xfer_control call.");
return -EINVAL;
}
@@ -154,8 +156,7 @@ EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
/* 1 cycles = 1.97 msec */
int flexcop_dma_config_timer(struct flexcop_device *fc,
- flexcop_dma_index_t dma_idx,
- u8 cycles)
+ flexcop_dma_index_t dma_idx, u8 cycles)
{
flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c
index 8a8ae8a3e6b..a25373a9bd8 100644
--- a/drivers/media/dvb/b2c2/flexcop-eeprom.c
+++ b/drivers/media/dvb/b2c2/flexcop-eeprom.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used)
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -14,17 +12,17 @@ static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
}
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
+static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
+ u32 len, u8 *wbuf, u8 *rbuf, int retries)
{
- int i;
+int i;
- for (i = 0; i < retries; i++) {
- if (eeprom_write(adapter, addr, wbuf, len) == len) {
- if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
- return 1;
+for (i = 0; i < retries; i++) {
+ if (eeprom_write(adapter, addr, wbuf, len) == len) {
+ if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
+ return 1;
}
}
-
return 0;
}
@@ -39,12 +37,10 @@ static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
return 0;
memcpy(wbuf, key, len);
-
wbuf[16] = 0;
wbuf[17] = 0;
wbuf[18] = 0;
wbuf[19] = calc_lrc(wbuf, 19);
-
return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
}
@@ -59,7 +55,6 @@ static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
return 0;
memcpy(key, buf, len);
-
return 1;
}
@@ -74,9 +69,7 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
tmp[3] = mac[5];
tmp[4] = mac[6];
tmp[5] = mac[7];
-
} else {
-
tmp[0] = mac[0];
tmp[1] = mac[1];
tmp[2] = mac[2];
@@ -90,11 +83,11 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
return 1;
-
return 0;
}
-static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len)
+static int flexcop_eeprom_read(struct flexcop_device *fc,
+ u16 addr, u8 *buf, u16 len)
{
return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
}
@@ -110,7 +103,8 @@ static u8 calc_lrc(u8 *buf, int len)
return sum;
}
-static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_request(struct flexcop_device *fc,
+ flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
{
int i,ret = 0;
u8 chipaddr = 0x50 | ((addr >> 8) & 3);
@@ -123,7 +117,8 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t
return ret;
}
-static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
+ u8 *buf, u16 len, int retries)
{
int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
if (ret == 0)
@@ -133,8 +128,7 @@ static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf,
}
/* JJ's comment about extended == 1: it is not presently used anywhere but was
- * added to the low-level functions for possible support of EUI64
- */
+ * added to the low-level functions for possible support of EUI64 */
int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
{
u8 buf[8];
@@ -142,12 +136,9 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
if (extended != 0) {
- err("TODO: extended (EUI64) MAC addresses aren't completely supported yet");
+ err("TODO: extended (EUI64) MAC addresses aren't "
+ "completely supported yet");
ret = -EINVAL;
-/* memcpy(fc->dvb_adapter.proposed_mac,buf,3);
- mac[3] = 0xfe;
- mac[4] = 0xff;
- memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */
} else
memcpy(fc->dvb_adapter.proposed_mac,buf,6);
}
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 5cded370854..f7afab5944c 100644
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -592,14 +592,14 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY;
+ fc->dev_type = FC_SKY_REV26;
goto fe_found;
}
/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
if (fc->fe != NULL) {
- fc->dev_type = FC_AIR_DVB;
+ fc->dev_type = FC_AIR_DVBT;
fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
goto fe_found;
}
@@ -653,7 +653,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY_OLD;
+ fc->dev_type = FC_SKY_REV23;
goto fe_found;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 451974ba32f..77e45475f4c 100644
--- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -1,33 +1,30 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-hw-filter.c - pid and mac address filtering and control functions
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
-
- deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
+ flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
+ deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
}
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
}
static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
}
void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
{
- flexcop_ibi_value v418,v41c;
- v41c = fc->read_ibi_reg(fc,mac_address_41c);
+ flexcop_ibi_value v418, v41c;
+ v41c = fc->read_ibi_reg(fc, mac_address_41c);
v418.mac_address_418.MAC1 = mac[0];
v418.mac_address_418.MAC2 = mac[1];
@@ -36,27 +33,28 @@ void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
v41c.mac_address_41c.MAC7 = mac[4];
v41c.mac_address_41c.MAC8 = mac[5];
- fc->write_ibi_reg(fc,mac_address_418,v418);
- fc->write_ibi_reg(fc,mac_address_41c,v41c);
+ fc->write_ibi_reg(fc, mac_address_418, v418);
+ fc->write_ibi_reg(fc, mac_address_41c, v41c);
}
void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
}
-static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask)
+static void flexcop_pid_group_filter(struct flexcop_device *fc,
+ u16 pid, u16 mask)
{
/* index_reg_310.extra_index_reg need to 0 or 7 to work */
flexcop_ibi_value v30c;
v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
- fc->write_ibi_reg(fc,pid_filter_30c,v30c);
+ fc->write_ibi_reg(fc, pid_filter_30c, v30c);
}
static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
}
/* this fancy define reduces the code size of the quite similar PID controlling of
@@ -65,91 +63,112 @@ static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
- v208 = fc->read_ibi_reg(fc, ctrl_208); \
-\
- vpid.vregname.field = onoff ? pid : 0x1fff; \
- vpid.vregname.trans_field = transval; \
- v208.ctrl_208.enablefield = onoff; \
-\
- fc->write_ibi_reg(fc,vregname,vpid); \
- fc->write_ibi_reg(fc,ctrl_208,v208);
+v208 = fc->read_ibi_reg(fc, ctrl_208); \
+vpid.vregname.field = onoff ? pid : 0x1fff; \
+vpid.vregname.trans_field = transval; \
+v208.ctrl_208.enablefield = onoff; \
+fc->write_ibi_reg(fc, vregname, vpid); \
+fc->write_ibi_reg(fc, ctrl_208, v208);
-static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0);
+ pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
+ Stream1_trans, 0);
}
-static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0);
+ pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
+ Stream2_trans, 0);
}
-static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0);
+ pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
}
-static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0);
+ pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
}
-static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0);
+ pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
}
-static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0);
+ pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
}
-static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff)
+static void flexcop_pid_control(struct flexcop_device *fc,
+ int index, u16 pid, int onoff)
{
if (pid == 0x2000)
return;
- deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off");
+ deb_ts("setting pid: %5d %04x at index %d '%s'\n",
+ pid, pid, index, onoff ? "on" : "off");
/* We could use bit magic here to reduce source code size.
* I decided against it, but to use the real register names */
switch (index) {
- case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break;
- case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break;
- case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break;
- case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break;
- case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break;
- case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break;
- default:
- if (fc->has_32_hw_pid_filter && index < 38) {
- flexcop_ibi_value vpid,vid;
-
- /* set the index */
- vid = fc->read_ibi_reg(fc,index_reg_310);
- vid.index_reg_310.index_reg = index - 6;
- fc->write_ibi_reg(fc,index_reg_310, vid);
-
- vpid = fc->read_ibi_reg(fc,pid_n_reg_314);
- vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
- vpid.pid_n_reg_314.PID_enable_bit = onoff;
- fc->write_ibi_reg(fc,pid_n_reg_314, vpid);
- }
- break;
+ case 0:
+ flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
+ break;
+ case 1:
+ flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
+ break;
+ case 2:
+ flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
+ break;
+ case 3:
+ flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
+ break;
+ case 4:
+ flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
+ break;
+ case 5:
+ flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
+ break;
+ default:
+ if (fc->has_32_hw_pid_filter && index < 38) {
+ flexcop_ibi_value vpid, vid;
+
+ /* set the index */
+ vid = fc->read_ibi_reg(fc, index_reg_310);
+ vid.index_reg_310.index_reg = index - 6;
+ fc->write_ibi_reg(fc, index_reg_310, vid);
+
+ vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
+ vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
+ vpid.pid_n_reg_314.PID_enable_bit = onoff;
+ fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
+ }
+ break;
}
}
-static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff)
+static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
{
if (fc->fullts_streaming_state != onoff) {
deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
- flexcop_pid_group_filter_ctrl(fc,onoff);
+ flexcop_pid_group_filter_ctrl(fc, onoff);
fc->fullts_streaming_state = onoff;
}
return 0;
}
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff)
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+ struct dvb_demux_feed *dvbdmxfeed, int onoff)
{
int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
@@ -164,24 +183,25 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
* - or the requested pid is 0x2000 */
if (!fc->pid_filtering && fc->feedcount == onoff)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
if (fc->pid_filtering) {
- flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+ flexcop_pid_control \
+ (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
if (fc->extra_feedcount > 0)
- flexcop_toggle_fullts_streaming(fc,1);
+ flexcop_toggle_fullts_streaming(fc, 1);
else if (dvbdmxfeed->pid == 0x2000)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
else
- flexcop_toggle_fullts_streaming(fc,0);
+ flexcop_toggle_fullts_streaming(fc, 0);
}
/* if it was the first or last feed request change the stream-status */
if (fc->feedcount == onoff) {
- flexcop_rcv_data_ctrl(fc,onoff);
+ flexcop_rcv_data_ctrl(fc, onoff);
if (fc->stream_control) /* device specific stream control */
- fc->stream_control(fc,onoff);
+ fc->stream_control(fc, onoff);
/* feeding stopped -> reset the flexcop filter*/
if (onoff == 0) {
@@ -189,7 +209,6 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
flexcop_hw_filter_init(fc);
}
}
-
return 0;
}
EXPORT_SYMBOL(flexcop_pid_feed_control);
@@ -199,15 +218,15 @@ void flexcop_hw_filter_init(struct flexcop_device *fc)
int i;
flexcop_ibi_value v;
for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
- flexcop_pid_control(fc,i,0x1fff,0);
+ flexcop_pid_control(fc, i, 0x1fff, 0);
flexcop_pid_group_filter(fc, 0, 0x1fe0);
- flexcop_pid_group_filter_ctrl(fc,0);
+ flexcop_pid_group_filter_ctrl(fc, 0);
- v = fc->read_ibi_reg(fc,pid_filter_308);
+ v = fc->read_ibi_reg(fc, pid_filter_308);
v.pid_filter_308.EMM_filter_4 = 1;
v.pid_filter_308.EMM_filter_6 = 0;
- fc->write_ibi_reg(fc,pid_filter_308,v);
+ fc->write_ibi_reg(fc, pid_filter_308, v);
flexcop_null_filter_ctrl(fc, 1);
}
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c
index f13783f08f0..e2bed507648 100644
--- a/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -1,17 +1,14 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
#define FC_MAX_I2C_RETRIES 100000
-/* #define DUMP_I2C_MESSAGES */
-
-static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100)
+static int flexcop_i2c_operation(struct flexcop_device *fc,
+ flexcop_ibi_value *r100)
{
int i;
flexcop_ibi_value r;
@@ -26,7 +23,7 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
r = fc->read_ibi_reg(fc, tw_sm_c_100);
if (!r.tw_sm_c_100.no_base_addr_ack_error) {
- if (r.tw_sm_c_100.st_done) { /* && !r.tw_sm_c_100.working_start */
+ if (r.tw_sm_c_100.st_done) {
*r100 = r;
deb_i2c("i2c success\n");
return 0;
@@ -36,17 +33,31 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
return -EREMOTEIO;
}
}
- deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i);
+ deb_i2c("tried %d times i2c operation, "
+ "never finished or too many ack errors.\n", i);
return -EREMOTEIO;
}
static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
- flexcop_ibi_value r100, u8 *buf)
+ flexcop_ibi_value r100, u8 *buf)
{
flexcop_ibi_value r104;
- int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */
+ int len = r100.tw_sm_c_100.total_bytes,
+ /* remember total_bytes is buflen-1 */
ret;
+ /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
+ * correctly:
+ *
+ * the ITD1000 is behind an i2c-gate which closes automatically
+ * after an i2c-transaction the STV0297 needs 2 consecutive reads
+ * one with no_base_addr = 0 and one with 1
+ *
+ * those two work-arounds are conflictin: we check for the card
+ * type, it is set when probing the ITD1000 */
+ if (i2c->fc->dev_type == FC_SKY_REV27)
+ r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
+
ret = flexcop_i2c_operation(i2c->fc, &r100);
if (ret != 0) {
deb_i2c("Retrying operation\n");
@@ -69,11 +80,11 @@ static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
}
-
return 0;
}
-static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf)
+static int flexcop_i2c_write4(struct flexcop_device *fc,
+ flexcop_ibi_value r100, u8 *buf)
{
flexcop_ibi_value r104;
int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
@@ -81,7 +92,6 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
/* there is at least one byte, otherwise we wouldn't be here */
r100.tw_sm_c_100.data1_reg = buf[0];
-
r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
@@ -94,7 +104,7 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
}
int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
- flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+ flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
{
int ret;
@@ -117,7 +127,6 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
printk("rd(");
else
printk("wr(");
-
printk("%02x): %02x ", chipaddr, addr);
#endif
@@ -163,7 +172,8 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
EXPORT_SYMBOL(flexcop_i2c_request);
/* master xfer callback for demodulator */
-static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msgs[], int num)
{
struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
int i, ret = 0;
@@ -182,12 +192,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
/* reading */
if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
- msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len);
+ msgs[i].buf[0], msgs[i+1].buf,
+ msgs[i+1].len);
i++; /* skip the following message */
} else /* writing */
ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
- msgs[i].buf[0], &msgs[i].buf[1],
- msgs[i].len - 1);
+ msgs[i].buf[0], &msgs[i].buf[1],
+ msgs[i].len - 1);
if (ret < 0) {
err("i2c master_xfer failed");
break;
@@ -214,23 +225,21 @@ static struct i2c_algorithm flexcop_algo = {
int flexcop_i2c_init(struct flexcop_device *fc)
{
int ret;
-
mutex_init(&fc->i2c_mutex);
fc->fc_i2c_adap[0].fc = fc;
fc->fc_i2c_adap[1].fc = fc;
fc->fc_i2c_adap[2].fc = fc;
-
fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
- sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
- sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
- sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
@@ -268,7 +277,6 @@ adap_2_failed:
i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
adap_1_failed:
i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
-
return ret;
}
@@ -279,6 +287,5 @@ void flexcop_i2c_exit(struct flexcop_device *fc)
i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
}
-
fc->init_state &= ~FC_STATE_I2C_INIT;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c
index 93d20e56f90..e56627d2f0f 100644
--- a/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-misc.c - miscellaneous functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-misc.c - miscellaneous functions
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -12,39 +10,43 @@ void flexcop_determine_revision(struct flexcop_device *fc)
flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
switch (v.misc_204.Rev_N_sig_revision_hi) {
- case 0x2:
- deb_info("found a FlexCopII.\n");
- fc->rev = FLEXCOP_II;
- break;
- case 0x3:
- deb_info("found a FlexCopIIb.\n");
- fc->rev = FLEXCOP_IIB;
- break;
- case 0x0:
- deb_info("found a FlexCopIII.\n");
- fc->rev = FLEXCOP_III;
- break;
- default:
- err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi);
- break;
+ case 0x2:
+ deb_info("found a FlexCopII.\n");
+ fc->rev = FLEXCOP_II;
+ break;
+ case 0x3:
+ deb_info("found a FlexCopIIb.\n");
+ fc->rev = FLEXCOP_IIB;
+ break;
+ case 0x0:
+ deb_info("found a FlexCopIII.\n");
+ fc->rev = FLEXCOP_III;
+ break;
+ default:
+ err("unknown FlexCop Revision: %x. Please report this to "
+ "linux-dvb@linuxtv.org.",
+ v.misc_204.Rev_N_sig_revision_hi);
+ break;
}
if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
- deb_info("this FlexCop has the additional 32 hardware pid filter.\n");
+ deb_info("this FlexCop has "
+ "the additional 32 hardware pid filter.\n");
else
- deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n");
+ deb_info("this FlexCop has "
+ "the 6 basic main hardware pid filter.\n");
/* bus parts have to decide if hw pid filtering is used or not. */
}
static const char *flexcop_revision_names[] = {
- "Unkown chip",
+ "Unknown chip",
"FlexCopII",
"FlexCopIIb",
"FlexCopIII",
};
static const char *flexcop_device_names[] = {
- "Unkown device",
+ "Unknown device",
"Air2PC/AirStar 2 DVB-T",
"Air2PC/AirStar 2 ATSC 1st generation",
"Air2PC/AirStar 2 ATSC 2nd generation",
@@ -61,21 +63,23 @@ static const char *flexcop_bus_names[] = {
"PCI",
};
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
- char *suffix)
+void flexcop_device_name(struct flexcop_device *fc,
+ const char *prefix, const char *suffix)
{
- info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix,
- flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
- flexcop_revision_names[fc->rev],suffix);
+ info("%s '%s' at the '%s' bus controlled by a '%s' %s",
+ prefix, flexcop_device_names[fc->dev_type],
+ flexcop_bus_names[fc->bus_type],
+ flexcop_revision_names[fc->rev], suffix);
}
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
+void flexcop_dump_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, int num)
{
flexcop_ibi_value v;
int i;
for (i = 0; i < num; i++) {
- v = fc->read_ibi_reg(fc,reg+4*i);
- deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
+ v = fc->read_ibi_reg(fc, reg+4*i);
+ deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
}
deb_rdump("\n");
}
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c
index 76e37fd96bb..227c0200b70 100644
--- a/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-pci.c - covers the PCI part including DMA transfers.
- *
- * see flexcop.c for copyright information.
+ * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-pci.c - covers the PCI part including DMA transfers
+ * see flexcop.c for copyright information
*/
#define FC_LOG_PREFIX "flexcop-pci"
@@ -11,7 +9,8 @@
static int enable_pid_filtering = 1;
module_param(enable_pid_filtering, int, 0444);
-MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
+MODULE_PARM_DESC(enable_pid_filtering,
+ "enable hardware pid filtering: supported values: 0 (fullts), 1");
static int irq_chk_intv = 100;
module_param(irq_chk_intv, int, 0644);
@@ -26,17 +25,17 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
#define DEBSTATUS " (debugging is not enabled)"
#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_reg(args...) dprintk(0x02,args)
-#define deb_ts(args...) dprintk(0x04,args)
-#define deb_irq(args...) dprintk(0x08,args)
-#define deb_chk(args...) dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_reg(args...) dprintk(0x02, args)
+#define deb_ts(args...) dprintk(0x04, args)
+#define deb_irq(args...) dprintk(0x08, args)
+#define deb_chk(args...) dprintk(0x10, args)
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,
"set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
- DEBSTATUS);
+ DEBSTATUS);
#define DRIVER_VERSION "0.1"
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
@@ -51,30 +50,30 @@ struct flexcop_pci {
void __iomem *io_mem;
u32 irq;
-/* buffersize (at least for DMA1, need to be % 188 == 0,
- * this logic is required */
+ /* buffersize (at least for DMA1, need to be % 188 == 0,
+ * this logic is required */
#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
struct flexcop_dma dma[2];
int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
- u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
+ u32 last_dma1_cur_pos;
+ /* position of the pointer last time the timer/packet irq occured */
int count;
int count_prev;
int stream_problem;
spinlock_t irq_lock;
-
unsigned long last_irq;
struct delayed_work irq_check_work;
-
struct flexcop_device *fc_dev;
};
-static int lastwreg,lastwval,lastrreg,lastrval;
+static int lastwreg, lastwval, lastrreg, lastrval;
-static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r)
+static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register r)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
flexcop_ibi_value v;
@@ -82,19 +81,20 @@ static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, fl
if (lastrreg != r || lastrval != v.raw) {
lastrreg = r; lastrval = v.raw;
- deb_reg("new rd: %3x: %08x\n",r,v.raw);
+ deb_reg("new rd: %3x: %08x\n", r, v.raw);
}
return v;
}
-static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v)
+static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register r, flexcop_ibi_value v)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
if (lastwreg != r || lastwval != v.raw) {
lastwreg = r; lastwval = v.raw;
- deb_reg("new wr: %3x: %08x\n",r,v.raw);
+ deb_reg("new wr: %3x: %08x\n", r, v.raw);
}
writel(v.raw, fc_pci->io_mem + r);
@@ -113,15 +113,16 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
deb_chk("no IRQ since the last check\n");
if (fc_pci->stream_problem++ == 3) {
struct dvb_demux_feed *feed;
+ deb_info("flexcop-pci: stream problem, resetting pid filter\n");
spin_lock_irq(&fc->demux.lock);
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 0);
}
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 1);
}
spin_unlock_irq(&fc->demux.lock);
@@ -149,11 +150,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED;
- spin_lock_irqsave(&fc_pci->irq_lock,flags);
-
- v = fc->read_ibi_reg(fc,irq_20c);
+ spin_lock_irqsave(&fc_pci->irq_lock, flags);
+ v = fc->read_ibi_reg(fc, irq_20c);
- /* errors */
+ /* errors */
if (v.irq_20c.Data_receiver_error)
deb_chk("data receiver error\n");
if (v.irq_20c.Continuity_error_flag)
@@ -164,24 +164,29 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
deb_chk("Transport error\n");
if ((fc_pci->count % 1000) == 0)
- deb_chk("%d valid irq took place so far\n",fc_pci->count);
+ deb_chk("%d valid irq took place so far\n", fc_pci->count);
if (v.irq_20c.DMA1_IRQ_Status == 1) {
if (fc_pci->active_dma1_addr == 0)
- flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
+ flexcop_pass_dmx_packets(fc_pci->fc_dev,
+ fc_pci->dma[0].cpu_addr0,
+ fc_pci->dma[0].size / 188);
else
- flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188);
+ flexcop_pass_dmx_packets(fc_pci->fc_dev,
+ fc_pci->dma[0].cpu_addr1,
+ fc_pci->dma[0].size / 188);
deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
- } else if (v.irq_20c.DMA1_Timer_Status == 1) {
/* for the timer IRQ we only can use buffer dmx feeding, because we don't have
* complete TS packets when reading from the DMA memory */
+ } else if (v.irq_20c.DMA1_Timer_Status == 1) {
dma_addr_t cur_addr =
fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
- deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
+ deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, "
+ "last_cur_pos: %08x ",
jiffies_to_usecs(jiffies - fc_pci->last_irq),
v.raw, (unsigned long long)cur_addr, cur_pos,
fc_pci->last_dma1_cur_pos);
@@ -191,30 +196,36 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
* pass the data from last_cur_pos to the buffer end to the demux
*/
if (cur_pos < fc_pci->last_dma1_cur_pos) {
- deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos);
+ deb_irq(" end was reached: passing %d bytes ",
+ (fc_pci->dma[0].size*2 - 1) -
+ fc_pci->last_dma1_cur_pos);
flexcop_pass_dmx_data(fc_pci->fc_dev,
- fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
- (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
+ fc_pci->dma[0].cpu_addr0 +
+ fc_pci->last_dma1_cur_pos,
+ (fc_pci->dma[0].size*2) -
+ fc_pci->last_dma1_cur_pos);
fc_pci->last_dma1_cur_pos = 0;
}
if (cur_pos > fc_pci->last_dma1_cur_pos) {
- deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos);
+ deb_irq(" passing %d bytes ",
+ cur_pos - fc_pci->last_dma1_cur_pos);
flexcop_pass_dmx_data(fc_pci->fc_dev,
- fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
- cur_pos - fc_pci->last_dma1_cur_pos);
+ fc_pci->dma[0].cpu_addr0 +
+ fc_pci->last_dma1_cur_pos,
+ cur_pos - fc_pci->last_dma1_cur_pos);
}
deb_irq("\n");
fc_pci->last_dma1_cur_pos = cur_pos;
fc_pci->count++;
} else {
- deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
+ deb_irq("isr for flexcop called, "
+ "apparently without reason (%08x)\n", v.raw);
ret = IRQ_NONE;
}
- spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
-
+ spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
return ret;
}
@@ -222,52 +233,48 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
if (onoff) {
- flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
- flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
-
- flexcop_dma_config_timer(fc,FC_DMA_1,0);
-
- flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
+ flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1);
+ flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2);
+ flexcop_dma_config_timer(fc, FC_DMA_1, 0);
+ flexcop_dma_xfer_control(fc, FC_DMA_1,
+ FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1);
deb_irq("DMA xfer enabled\n");
fc_pci->last_dma1_cur_pos = 0;
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+ flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
deb_irq("IRQ enabled\n");
-
fc_pci->count_prev = fc_pci->count;
-
-// fc_pci->active_dma1_addr = 0;
-// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
-
} else {
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+ flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0);
deb_irq("IRQ disabled\n");
-// flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
-
- flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
+ flexcop_dma_xfer_control(fc, FC_DMA_1,
+ FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0);
deb_irq("DMA xfer disabled\n");
}
-
return 0;
}
static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
{
int ret;
- if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0)
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
+ FC_DEFAULT_DMA1_BUFSIZE);
+ if (ret != 0)
return ret;
- if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) {
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
+ FC_DEFAULT_DMA2_BUFSIZE);
+ if (ret != 0) {
flexcop_dma_free(&fc_pci->dma[0]);
return ret;
}
- flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
- flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
-
+ flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA |
+ FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
+ flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO |
+ FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
fc_pci->init_state |= FC_PCI_DMA_INIT;
-
return ret;
}
@@ -290,12 +297,8 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
return ret;
-
pci_set_master(fc_pci->pdev);
- /* enable interrupts */
- // pci_write_config_dword(pdev, 0x6c, 0x8000);
-
if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
goto err_pci_disable_device;
@@ -338,8 +341,8 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
fc_pci->init_state &= ~FC_PCI_INIT;
}
-
-static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int flexcop_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct flexcop_device *fc;
struct flexcop_pci *fc_pci;
@@ -350,7 +353,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_pci = fc->bus_specific;
fc_pci->fc_dev = fc;
@@ -358,7 +361,6 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
fc->i2c_request = flexcop_i2c_request;
fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
-
fc->stream_control = flexcop_pci_stream_control;
if (enable_pid_filtering)
@@ -368,29 +370,29 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
fc->pid_filtering = enable_pid_filtering;
fc->bus_type = FC_PCI;
-
fc->dev = &pdev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_pci->pdev = pdev;
if ((ret = flexcop_pci_init(fc_pci)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_pci_exit;
-/* init dma */
+ /* init dma */
if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
goto err_fc_exit;
INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
- if (irq_chk_intv > 0)
- schedule_delayed_work(&fc_pci->irq_check_work,
- msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
-
+ if (irq_chk_intv > 0)
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ?
+ 100 :
+ irq_chk_intv));
return ret;
err_fc_exit:
@@ -420,7 +422,6 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
static struct pci_device_id flexcop_pci_tbl[] = {
{ PCI_DEVICE(0x13d0, 0x2103) },
-/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */
{ },
};
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h
index 7599fccc1a5..dc4528dcbb9 100644
--- a/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -1,14 +1,11 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_REG_H__
#define __FLEXCOP_REG_H__
-
typedef enum {
FLEXCOP_UNK = 0,
FLEXCOP_II,
@@ -18,13 +15,13 @@ typedef enum {
typedef enum {
FC_UNK = 0,
- FC_AIR_DVB,
+ FC_CABLE,
+ FC_AIR_DVBT,
FC_AIR_ATSC1,
FC_AIR_ATSC2,
- FC_SKY,
- FC_SKY_OLD,
- FC_CABLE,
FC_AIR_ATSC3,
+ FC_SKY_REV23,
+ FC_SKY_REV26,
FC_SKY_REV27,
FC_SKY_REV28,
} flexcop_device_type_t;
@@ -36,12 +33,12 @@ typedef enum {
/* FlexCop IBI Registers */
#if defined(__LITTLE_ENDIAN)
- #include "flexcop_ibi_value_le.h"
+#include "flexcop_ibi_value_le.h"
#else
#if defined(__BIG_ENDIAN)
- #include "flexcop_ibi_value_be.h"
+#include "flexcop_ibi_value_be.h"
#else
- #error no endian defined
+#error no endian defined
#endif
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c
index cda69528548..f2199e43e80 100644
--- a/drivers/media/dvb/b2c2/flexcop-sram.c
+++ b/drivers/media/dvb/b2c2/flexcop-sram.c
@@ -1,45 +1,43 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-sram.c - functions for controlling the SRAM.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-sram.c - functions for controlling the SRAM
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
-static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type)
+static void flexcop_sram_set_chip(struct flexcop_device *fc,
+ flexcop_sram_type_t type)
{
- flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type);
+ flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
}
int flexcop_sram_init(struct flexcop_device *fc)
{
switch (fc->rev) {
- case FLEXCOP_II:
- case FLEXCOP_IIB:
- flexcop_sram_set_chip(fc,FC_SRAM_1_32KB);
- break;
- case FLEXCOP_III:
- flexcop_sram_set_chip(fc,FC_SRAM_1_48KB);
- break;
- default:
- return -EINVAL;
+ case FLEXCOP_II:
+ case FLEXCOP_IIB:
+ flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
+ break;
+ case FLEXCOP_III:
+ flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
+ break;
+ default:
+ return -EINVAL;
}
return 0;
}
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target)
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+ flexcop_sram_dest_target_t target)
{
flexcop_ibi_value v;
-
- v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+ v = fc->read_ibi_reg(fc, sram_dest_reg_714);
if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
err("SRAM destination target to available on FlexCopII(b)\n");
return -EINVAL;
}
-
- deb_sram("sram dest: %x target: %x\n",dest, target);
+ deb_sram("sram dest: %x target: %x\n", dest, target);
if (dest & FC_SRAM_DEST_NET)
v.sram_dest_reg_714.NET_Dest = target;
@@ -154,14 +152,12 @@ static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len
else
bank = 0x10000000;
}
-
flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
}
static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
{
u32 bank;
-
bank = 0;
if (adapter->dw_sram_type == 0x20000) {
@@ -174,26 +170,22 @@ static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
else
bank = 0x10000000;
}
-
flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
}
static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
{
u32 length;
-
while (len != 0) {
length = len;
-
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is read from
- // one chip at a time.
+ /* check if the address range belongs to the same
+ * 32K memory chip. If not, the data is read
+ * from one chip at a time */
if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
}
sram_read_chunk(adapter, addr, buf, length);
-
addr = addr + length;
buf = buf + length;
len = len - length;
@@ -203,19 +195,17 @@ static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
{
u32 length;
-
while (len != 0) {
length = len;
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is written to
- // one chip at a time.
+ /* check if the address range belongs to the same
+ * 32K memory chip. If not, the data is
+ * written to one chip at a time */
if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
}
sram_write_chunk(adapter, addr, buf, length);
-
addr = addr + length;
buf = buf + length;
len = len - length;
@@ -224,39 +214,29 @@ static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
static void sram_set_size(struct adapter *adapter, u32 mask)
{
- write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+ write_reg_dw(adapter, 0x71c,
+ (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
}
static void sram_init(struct adapter *adapter)
{
u32 tmp;
-
tmp = read_reg_dw(adapter, 0x71c);
-
write_reg_dw(adapter, 0x71c, 1);
if (read_reg_dw(adapter, 0x71c) != 0) {
write_reg_dw(adapter, 0x71c, tmp);
-
adapter->dw_sram_type = tmp & 0x30000;
-
ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
-
} else {
-
adapter->dw_sram_type = 0x10000;
-
ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
}
-
- /* return value is never used? */
-/* return adapter->dw_sram_type; */
}
static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
{
u8 tmp1, tmp2;
-
dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
sram_set_size(adapter, mask);
@@ -269,7 +249,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -287,7 +266,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -297,26 +275,24 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
if (tmp2 != 0x5a)
return 0;
-
return 1;
}
static u32 sram_length(struct adapter *adapter)
{
if (adapter->dw_sram_type == 0x10000)
- return 32768; // 32K
+ return 32768; /* 32K */
if (adapter->dw_sram_type == 0x00000)
- return 65536; // 64K
+ return 65536; /* 64K */
if (adapter->dw_sram_type == 0x20000)
- return 131072; // 128K
-
- return 32768; // 32K
+ return 131072; /* 128K */
+ return 32768; /* 32K */
}
/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
- - for 128K there are 4x32K chips at bank 0,1,2,3.
- - for 64K there are 2x32K chips at bank 1,2.
- - for 32K there is one 32K chip at bank 0.
+ - for 128K there are 4x32K chips at bank 0,1,2,3.
+ - for 64K there are 2x32K chips at bank 1,2.
+ - for 32K there is one 32K chip at bank 0.
FlexCop works only with one bank at a time. The bank is selected
by bits 28-29 of the 0x700 register.
@@ -324,24 +300,18 @@ static u32 sram_length(struct adapter *adapter)
bank 0 covers addresses 0x00000-0x07fff
bank 1 covers addresses 0x08000-0x0ffff
bank 2 covers addresses 0x10000-0x17fff
- bank 3 covers addresses 0x18000-0x1ffff
-*/
+ bank 3 covers addresses 0x18000-0x1ffff */
static int flexcop_sram_detect(struct flexcop_device *fc)
{
- flexcop_ibi_value r208,r71c_0,vr71c_1;
-
+ flexcop_ibi_value r208, r71c_0, vr71c_1;
r208 = fc->read_ibi_reg(fc, ctrl_208);
fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
-
write_reg_dw(adapter, 0x71c, 1);
-
tmp3 = read_reg_dw(adapter, 0x71c);
-
dprintk("%s: tmp3 = %x\n", __func__, tmp3);
-
write_reg_dw(adapter, 0x71c, tmp2);
// check for internal SRAM ???
@@ -350,9 +320,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 32K\n", __func__);
-
return 32;
}
@@ -360,9 +328,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x20000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 128K\n", __func__);
-
return 128;
}
@@ -370,9 +336,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x00000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 64K\n", __func__);
-
return 64;
}
@@ -380,18 +344,14 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 32K\n", __func__);
-
return 32;
}
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
-
return 0;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c
index ae0d76a5d51..bedcfb67162 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -1,11 +1,8 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-usb.c - covers the USB part.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.c - covers the USB part
+ * see flexcop.c for copyright information
*/
-
#define FC_LOG_PREFIX "flexcop_usb"
#include "flexcop-usb.h"
#include "flexcop-common.h"
@@ -18,42 +15,47 @@
/* debug */
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) \
- do { if ((debug & level)) { printk(args); } } while (0)
-#define debug_dump(b,l,method) {\
+ do { if ((debug & level)) printk(args); } while (0)
+
+#define debug_dump(b, l, method) do {\
int i; \
- for (i = 0; i < l; i++) method("%02x ", b[i]); \
- method("\n");\
-}
+ for (i = 0; i < l; i++) \
+ method("%02x ", b[i]); \
+ method("\n"); \
+} while (0)
#define DEBSTATUS ""
#else
-#define dprintk(level,args...)
-#define debug_dump(b,l,method)
+#define dprintk(level, args...)
+#define debug_dump(b, l, method)
#define DEBSTATUS " (debugging is not enabled)"
#endif
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,"
+ "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
#undef DEBSTATUS
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_ts(args...) dprintk(0x02,args)
-#define deb_ctrl(args...) dprintk(0x04,args)
-#define deb_i2c(args...) dprintk(0x08,args)
-#define deb_v8(args...) dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_ts(args...) dprintk(0x02, args)
+#define deb_ctrl(args...) dprintk(0x04, args)
+#define deb_i2c(args...) dprintk(0x08, args)
+#define deb_v8(args...) dprintk(0x10, args)
/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
* in the IBI address, to make the V8 code simpler.
- * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
+ * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used)
* in general: 0000 0HHH 000L LL00
* IBI ADDRESS FORMAT: RHHH BLLL
*
* where R is the read(1)/write(0) bit, B is the busy bit
* and HHH and LLL are the two sets of three bits from the PCI address.
*/
-#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
-#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
+#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \
+ (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
+#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \
+ (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
/*
* DKT 020228
@@ -69,12 +71,13 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
struct flexcop_usb *fc_usb = fc->bus_specific;
u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
- u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0);
+ u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
+ (read ? 0x80 : 0);
int len = usb_control_msg(fc_usb->udev,
read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
request,
- request_type, /* 0xc0 read or 0x40 write*/
+ request_type, /* 0xc0 read or 0x40 write */
wAddress,
0,
val,
@@ -82,55 +85,49 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
B2C2_WAIT_FOR_OPERATION_RDW * HZ);
if (len != sizeof(u32)) {
- err("error while %s dword from %d (%d).",read ? "reading" : "writing",
- wAddress,wRegOffsPCI);
+ err("error while %s dword from %d (%d).", read ? "reading" :
+ "writing", wAddress, wRegOffsPCI);
return -EIO;
}
return 0;
}
-
/*
* DKT 010817 - add support for V8 memory read/write and flash update
*/
static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
flexcop_usb_request_t req, u8 page, u16 wAddress,
- u8 *pbBuffer,u32 buflen)
+ u8 *pbBuffer, u32 buflen)
{
-// u8 dwRequestType;
u8 request_type = USB_TYPE_VENDOR;
u16 wIndex;
- int nWaitTime,pipe,len;
-
+ int nWaitTime, pipe, len;
wIndex = page << 8;
switch (req) {
- case B2C2_USB_READ_V8_MEM:
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
- request_type |= USB_DIR_IN;
-// dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
- pipe = B2C2_USB_CTRL_PIPE_IN;
+ case B2C2_USB_READ_V8_MEM:
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
+ request_type |= USB_DIR_IN;
+ pipe = B2C2_USB_CTRL_PIPE_IN;
break;
- case B2C2_USB_WRITE_V8_MEM:
- wIndex |= pbBuffer[0];
- request_type |= USB_DIR_OUT;
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
-// dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
- pipe = B2C2_USB_CTRL_PIPE_OUT;
+ case B2C2_USB_WRITE_V8_MEM:
+ wIndex |= pbBuffer[0];
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
break;
- case B2C2_USB_FLASH_BLOCK:
- request_type |= USB_DIR_OUT;
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
-// dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
- pipe = B2C2_USB_CTRL_PIPE_OUT;
+ case B2C2_USB_FLASH_BLOCK:
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
break;
- default:
- deb_info("unsupported request for v8_mem_req %x.\n",req);
+ default:
+ deb_info("unsupported request for v8_mem_req %x.\n", req);
return -EINVAL;
}
- deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req,
- wAddress,wIndex,buflen);
+ deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
+ wAddress, wIndex, buflen);
- len = usb_control_msg(fc_usb->udev,pipe,
+ len = usb_control_msg(fc_usb->udev, pipe,
req,
request_type,
wAddress,
@@ -139,39 +136,53 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
buflen,
nWaitTime * HZ);
- debug_dump(pbBuffer,len,deb_v8);
-
+ debug_dump(pbBuffer, len, deb_v8);
return len == buflen ? 0 : -EIO;
}
#define bytes_left_to_read_on_page(paddr,buflen) \
- ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
- ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
+ ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
+ ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
-static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req,
- flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len)
+static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
+ flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
+ u32 addr, int extended, u8 *buf, u32 len)
{
int i,ret = 0;
u16 wMax;
u32 pagechunk = 0;
switch(req) {
- case B2C2_USB_READ_V8_MEM: wMax = USB_MEM_READ_MAX; break;
- case B2C2_USB_WRITE_V8_MEM: wMax = USB_MEM_WRITE_MAX; break;
- case B2C2_USB_FLASH_BLOCK: wMax = USB_FLASH_MAX; break;
- default:
- return -EINVAL;
+ case B2C2_USB_READ_V8_MEM:
+ wMax = USB_MEM_READ_MAX;
+ break;
+ case B2C2_USB_WRITE_V8_MEM:
+ wMax = USB_MEM_WRITE_MAX;
+ break;
+ case B2C2_USB_FLASH_BLOCK:
+ wMax = USB_FLASH_MAX;
+ break;
+ default:
+ return -EINVAL;
break;
}
for (i = 0; i < len;) {
- pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len);
- deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended));
- if ((ret = flexcop_usb_v8_memory_req(fc_usb,req,
- page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */
- (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended),
- &buf[i],pagechunk)) < 0)
+ pagechunk =
+ wMax < bytes_left_to_read_on_page(addr, len) ?
+ wMax :
+ bytes_left_to_read_on_page(addr, len);
+ deb_info("%x\n",
+ (addr & V8_MEMORY_PAGE_MASK) |
+ (V8_MEMORY_EXTENDED*extended));
+
+ ret = flexcop_usb_v8_memory_req(fc_usb, req,
+ page_start + (addr / V8_MEMORY_PAGE_SIZE),
+ (addr & V8_MEMORY_PAGE_MASK) |
+ (V8_MEMORY_EXTENDED*extended),
+ &buf[i], pagechunk);
+
+ if (ret < 0)
return ret;
-
addr += pagechunk;
len -= pagechunk;
}
@@ -180,8 +191,9 @@ static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request
static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
{
- return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM,
- V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6);
+ return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
+ V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
+ fc->dvb_adapter.proposed_mac, 6);
}
#if 0
@@ -191,11 +203,8 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
{
u16 wValue;
u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
-// u8 dwRequestType = (u8) RTYPE_GENERIC,
int nWaitTime = 2,
- pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
- len;
-
+ pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
wValue = (func << 8) | extra;
len = usb_control_msg(fc_usb->udev,pipe,
@@ -218,36 +227,35 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
u16 wValue, wIndex;
int nWaitTime,pipe,len;
-// u8 dwRequestType;
u8 request_type = USB_TYPE_VENDOR;
switch (func) {
- case USB_FUNC_I2C_WRITE:
- case USB_FUNC_I2C_MULTIWRITE:
- case USB_FUNC_I2C_REPEATWRITE:
+ case USB_FUNC_I2C_WRITE:
+ case USB_FUNC_I2C_MULTIWRITE:
+ case USB_FUNC_I2C_REPEATWRITE:
/* DKT 020208 - add this to support special case of DiSEqC */
- case USB_FUNC_I2C_CHECKWRITE:
- pipe = B2C2_USB_CTRL_PIPE_OUT;
- nWaitTime = 2;
-// dwRequestType = (u8) RTYPE_GENERIC;
- request_type |= USB_DIR_OUT;
+ case USB_FUNC_I2C_CHECKWRITE:
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
+ nWaitTime = 2;
+ request_type |= USB_DIR_OUT;
break;
- case USB_FUNC_I2C_READ:
- case USB_FUNC_I2C_REPEATREAD:
- pipe = B2C2_USB_CTRL_PIPE_IN;
- nWaitTime = 2;
-// dwRequestType = (u8) RTYPE_GENERIC;
- request_type |= USB_DIR_IN;
+ case USB_FUNC_I2C_READ:
+ case USB_FUNC_I2C_REPEATREAD:
+ pipe = B2C2_USB_CTRL_PIPE_IN;
+ nWaitTime = 2;
+ request_type |= USB_DIR_IN;
break;
- default:
- deb_info("unsupported function for i2c_req %x\n",func);
- return -EINVAL;
+ default:
+ deb_info("unsupported function for i2c_req %x\n", func);
+ return -EINVAL;
}
wValue = (func << 8) | (i2c->port << 4);
wIndex = (chipaddr << 8 ) | addr;
- deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
- wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8);
+ deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
+ func, request_type, req,
+ wValue & 0xff, wValue >> 8,
+ wIndex & 0xff, wIndex >> 8);
len = usb_control_msg(fc_usb->udev,pipe,
req,
@@ -257,44 +265,49 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
buf,
buflen,
nWaitTime * HZ);
-
return len == buflen ? 0 : -EREMOTEIO;
}
-/* actual bus specific access functions, make sure prototype are/will be equal to pci */
-static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg)
+/* actual bus specific access functions,
+ make sure prototype are/will be equal to pci */
+static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg)
{
flexcop_ibi_value val;
val.raw = 0;
- flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1);
+ flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1);
return val;
}
-static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val)
+static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, flexcop_ibi_value val)
{
- return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0);
+ return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0);
}
static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c,
- flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+ flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
{
if (op == FC_READ)
return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
- USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
+ USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
else
return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
- USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
+ USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
}
-static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)
+static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
+ u8 *buffer, int buffer_length)
{
u8 *b;
int l;
- deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length);
+ deb_ts("tmp_buffer_length=%d, buffer_length=%d\n",
+ fc_usb->tmp_buffer_length, buffer_length);
if (fc_usb->tmp_buffer_length > 0) {
- memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length);
+ memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer,
+ buffer_length);
fc_usb->tmp_buffer_length += buffer_length;
b = fc_usb->tmp_buffer;
l = fc_usb->tmp_buffer_length;
@@ -304,23 +317,26 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in
}
while (l >= 190) {
- if (*b == 0xff)
+ if (*b == 0xff) {
switch (*(b+1) & 0x03) {
- case 0x01: /* media packet */
- if ( *(b+2) == 0x47 )
- flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1);
- else
- deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) );
-
- b += 190;
- l -= 190;
+ case 0x01: /* media packet */
+ if (*(b+2) == 0x47)
+ flexcop_pass_dmx_packets(
+ fc_usb->fc_dev, b+2, 1);
+ else
+ deb_ts(
+ "not ts packet %02x %02x %02x %02x \n",
+ *(b+2), *(b+3),
+ *(b+4), *(b+5));
+ b += 190;
+ l -= 190;
break;
- default:
- deb_ts("wrong packet type\n");
- l = 0;
+ default:
+ deb_ts("wrong packet type\n");
+ l = 0;
break;
}
- else {
+ } else {
deb_ts("wrong header\n");
l = 0;
}
@@ -337,23 +353,26 @@ static void flexcop_usb_urb_complete(struct urb *urb)
int i;
if (urb->actual_length > 0)
- deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length);
+ deb_ts("urb completed, bufsize: %d actlen; %d\n",
+ urb->transfer_buffer_length, urb->actual_length);
for (i = 0; i < urb->number_of_packets; i++) {
if (urb->iso_frame_desc[i].status < 0) {
- err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status);
+ err("iso frame descriptor %d has an error: %d\n", i,
+ urb->iso_frame_desc[i].status);
} else
if (urb->iso_frame_desc[i].actual_length > 0) {
- deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length);
+ deb_ts("passed %d bytes to the demux\n",
+ urb->iso_frame_desc[i].actual_length);
flexcop_usb_process_frame(fc_usb,
- urb->transfer_buffer + urb->iso_frame_desc[i].offset,
+ urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset,
urb->iso_frame_desc[i].actual_length);
- }
+ }
urb->iso_frame_desc[i].status = 0;
urb->iso_frame_desc[i].actual_length = 0;
}
-
usb_submit_urb(urb,GFP_ATOMIC);
}
@@ -374,35 +393,47 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
}
if (fc_usb->iso_buffer != NULL)
- pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr);
+ pci_free_consistent(NULL,
+ fc_usb->buffer_size, fc_usb->iso_buffer,
+ fc_usb->dma_addr);
}
static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
{
- u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
- int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
+ u16 frame_size = le16_to_cpu(
+ fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
+ int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO *
+ frame_size, i, j, ret;
int buffer_offset = 0;
- deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
- B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
+ deb_ts("creating %d iso-urbs with %d frames "
+ "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB,
+ B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize);
- fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr);
+ fc_usb->iso_buffer = pci_alloc_consistent(NULL,
+ bufsize, &fc_usb->dma_addr);
if (fc_usb->iso_buffer == NULL)
return -ENOMEM;
+
memset(fc_usb->iso_buffer, 0, bufsize);
fc_usb->buffer_size = bufsize;
/* creating iso urbs */
- for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
- if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
+ for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+ fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,
+ GFP_ATOMIC);
+ if (fc_usb->iso_urb[i] == NULL) {
ret = -ENOMEM;
goto urb_error;
}
+ }
+
/* initialising and submitting iso urbs */
for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
int frame_offset = 0;
struct urb *urb = fc_usb->iso_urb[i];
- deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
+ deb_ts("initializing and submitting urb no. %d "
+ "(buf_offset: %d).\n", i, buffer_offset);
urb->dev = fc_usb->udev;
urb->context = fc_usb;
@@ -416,26 +447,26 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
- deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
+ deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",
+ i, j, frame_offset);
urb->iso_frame_desc[j].offset = frame_offset;
urb->iso_frame_desc[j].length = frame_size;
frame_offset += frame_size;
}
if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {
- err("submitting urb %d failed with %d.",i,ret);
+ err("submitting urb %d failed with %d.", i, ret);
goto urb_error;
}
deb_ts("submitted urb no. %d.\n",i);
}
-/* SRAM */
-
- flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET |
- FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB);
- flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS);
- flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1);
-
+ /* SRAM */
+ flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA |
+ FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI,
+ FC_SRAM_DEST_TARGET_WAN_USB);
+ flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS);
+ flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1);
return 0;
urb_error:
@@ -448,20 +479,20 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb)
/* use the alternate setting with the larges buffer */
usb_set_interface(fc_usb->udev,0,1);
switch (fc_usb->udev->speed) {
- case USB_SPEED_LOW:
- err("cannot handle USB speed because it is to sLOW.");
- return -ENODEV;
- break;
- case USB_SPEED_FULL:
- info("running at FULL speed.");
- break;
- case USB_SPEED_HIGH:
- info("running at HIGH speed.");
- break;
- case USB_SPEED_UNKNOWN: /* fall through */
- default:
- err("cannot handle USB speed because it is unkown.");
- return -ENODEV;
+ case USB_SPEED_LOW:
+ err("cannot handle USB speed because it is too slow.");
+ return -ENODEV;
+ break;
+ case USB_SPEED_FULL:
+ info("running at FULL speed.");
+ break;
+ case USB_SPEED_HIGH:
+ info("running at HIGH speed.");
+ break;
+ case USB_SPEED_UNKNOWN: /* fall through */
+ default:
+ err("cannot handle USB speed because it is unknown.");
+ return -ENODEV;
}
usb_set_intfdata(fc_usb->uintf, fc_usb);
return 0;
@@ -485,7 +516,7 @@ static int flexcop_usb_probe(struct usb_interface *intf,
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_usb = fc->bus_specific;
fc_usb->fc_dev = fc;
@@ -502,21 +533,21 @@ static int flexcop_usb_probe(struct usb_interface *intf,
fc->dev = &udev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_usb->udev = udev;
fc_usb->uintf = intf;
if ((ret = flexcop_usb_init(fc_usb)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_usb_exit;
-/* xfer init */
+ /* xfer init */
if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
goto err_fc_exit;
- info("%s successfully initialized and connected.",DRIVER_NAME);
+ info("%s successfully initialized and connected.", DRIVER_NAME);
return 0;
err_fc_exit:
@@ -535,12 +566,12 @@ static void flexcop_usb_disconnect(struct usb_interface *intf)
flexcop_device_exit(fc_usb->fc_dev);
flexcop_usb_exit(fc_usb);
flexcop_device_kfree(fc_usb->fc_dev);
- info("%s successfully deinitialized and disconnected.",DRIVER_NAME);
+ info("%s successfully deinitialized and disconnected.", DRIVER_NAME);
}
static struct usb_device_id flexcop_usb_table [] = {
- { USB_DEVICE(0x0af7, 0x0101) },
- { }
+ { USB_DEVICE(0x0af7, 0x0101) },
+ { }
};
MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
@@ -557,10 +588,9 @@ static int __init flexcop_usb_module_init(void)
{
int result;
if ((result = usb_register(&flexcop_usb_driver))) {
- err("usb_register failed. (%d)",result);
+ err("usb_register failed. (%d)", result);
return result;
}
-
return 0;
}
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h
index 630e647a2ca..92529a9c447 100644
--- a/drivers/media/dvb/b2c2/flexcop-usb.h
+++ b/drivers/media/dvb/b2c2/flexcop-usb.h
@@ -1,15 +1,20 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.h - header file for the USB part
+ * see flexcop.c for copyright information
+ */
#ifndef __FLEXCOP_USB_H_INCLUDED__
#define __FLEXCOP_USB_H_INCLUDED__
#include <linux/usb.h>
/* transfer parameters */
-#define B2C2_USB_FRAMES_PER_ISO 4
-#define B2C2_USB_NUM_ISO_URB 4
+#define B2C2_USB_FRAMES_PER_ISO 4
+#define B2C2_USB_NUM_ISO_URB 4
-#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev,0x81)
+#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81)
struct flexcop_usb {
struct usb_device *udev;
@@ -18,8 +23,8 @@ struct flexcop_usb {
u8 *iso_buffer;
int buffer_size;
dma_addr_t dma_addr;
- struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
+ struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
struct flexcop_device *fc_dev;
u8 tmp_buffer[1023+190];
@@ -30,14 +35,6 @@ struct flexcop_usb {
/* request types TODO What is its use?*/
typedef enum {
-/* something is wrong with this part
- RTYPE_READ_DW = (1 << 6),
- RTYPE_WRITE_DW_1 = (3 << 6),
- RTYPE_READ_V8_MEMORY = (6 << 6),
- RTYPE_WRITE_V8_MEMORY = (7 << 6),
- RTYPE_WRITE_V8_FLASH = (8 << 6),
- RTYPE_GENERIC = (9 << 6),
-*/
} flexcop_usb_request_type_t;
#endif
@@ -47,7 +44,6 @@ typedef enum {
B2C2_USB_READ_V8_MEM = 0x05,
B2C2_USB_READ_REG = 0x08,
B2C2_USB_WRITE_REG = 0x0A,
-/* B2C2_USB_WRITEREGLO = 0x0A, */
B2C2_USB_WRITEREGHI = 0x0B,
B2C2_USB_FLASH_BLOCK = 0x10,
B2C2_USB_I2C_REQUEST = 0x11,
@@ -62,15 +58,13 @@ typedef enum {
USB_FUNC_I2C_REPEATWRITE = 0x04,
USB_FUNC_GET_DESCRIPTOR = 0x05,
USB_FUNC_I2C_REPEATREAD = 0x06,
-/* DKT 020208 - add this to support special case of DiSEqC */
+ /* DKT 020208 - add this to support special case of DiSEqC */
USB_FUNC_I2C_CHECKWRITE = 0x07,
USB_FUNC_I2C_CHECKRESULT = 0x08,
} flexcop_usb_i2c_function_t;
-/*
- * function definition for UTILITY request 0x12
- * DKT 020304 - new utility function
- */
+/* function definition for UTILITY request 0x12
+ * DKT 020304 - new utility function */
typedef enum {
UTILITY_SET_FILTER = 0x01,
UTILITY_DATA_ENABLE = 0x02,
@@ -84,7 +78,7 @@ typedef enum {
UTILITY_DATA_RESET = 0x0A,
UTILITY_GET_DATA_STATUS = 0x10,
UTILITY_GET_V8_REG = 0x11,
-/* DKT 020326 - add function for v1.14 */
+ /* DKT 020326 - add function for v1.14 */
UTILITY_SRAM_WRITE = 0x12,
UTILITY_SRAM_READ = 0x13,
UTILITY_SRAM_TESTFILL = 0x14,
@@ -92,13 +86,13 @@ typedef enum {
UTILITY_SRAM_TESTVERIFY = 0x16,
} flexcop_usb_utility_function_t;
-#define B2C2_WAIT_FOR_OPERATION_RW 1*HZ /* 1 s */
-#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ /* 1 s */
+#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
+#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
-#define B2C2_WAIT_FOR_OPERATION_V8READ 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3*HZ /* 3 s */
+#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
typedef enum {
V8_MEMORY_PAGE_DVB_CI = 0x20,
@@ -107,13 +101,11 @@ typedef enum {
V8_MEMORY_PAGE_FLASH = 0x80
} flexcop_usb_mem_page_t;
-#define V8_MEMORY_EXTENDED (1 << 15)
-
-#define USB_MEM_READ_MAX 32
-#define USB_MEM_WRITE_MAX 1
-#define USB_FLASH_MAX 8
-
-#define V8_MEMORY_PAGE_SIZE 0x8000 // 32K
-#define V8_MEMORY_PAGE_MASK 0x7FFF
+#define V8_MEMORY_EXTENDED (1 << 15)
+#define USB_MEM_READ_MAX 32
+#define USB_MEM_WRITE_MAX 1
+#define USB_FLASH_MAX 8
+#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */
+#define V8_MEMORY_PAGE_MASK 0x7FFF
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c
index 91068952b50..2df1b0214dc 100644
--- a/drivers/media/dvb/b2c2/flexcop.c
+++ b/drivers/media/dvb/b2c2/flexcop.c
@@ -1,22 +1,20 @@
/*
- * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * Copyright (C) 2004-5 Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * based on the skystar2-driver
- * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.c - main module part
+ * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
+ * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
*
* Acknowledgements:
- * John Jurrius from BBTI, Inc. for extensive support with
- * code examples and data books
- *
- * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
+ * John Jurrius from BBTI, Inc. for extensive support
+ * with code examples and data books
+ * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
*
* Contributions to the skystar2-driver have been done by
- * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
- * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
- * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering)
- *
+ * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
+ * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
+ * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
+ * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
+ * filtering)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -46,7 +44,10 @@
int b2c2_flexcop_debug;
module_param_named(debug, b2c2_flexcop_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug,
+ "set debug level (1=info,2=tuner,4=i2c,8=ts,"
+ "16=sram,32=reg (|-able))."
+ DEBSTATUS);
#undef DEBSTATUS
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -57,37 +58,36 @@ flexcop_ibi_value ibi_zero;
static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct flexcop_device *fc = dvbdmxfeed->demux->priv;
- return flexcop_pid_feed_control(fc,dvbdmxfeed,1);
+ return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
}
static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct flexcop_device *fc = dvbdmxfeed->demux->priv;
- return flexcop_pid_feed_control(fc,dvbdmxfeed,0);
+ return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
}
static int flexcop_dvb_init(struct flexcop_device *fc)
{
int ret = dvb_register_adapter(&fc->dvb_adapter,
- "FlexCop Digital TV device", fc->owner,
- fc->dev, adapter_nr);
+ "FlexCop Digital TV device", fc->owner,
+ fc->dev, adapter_nr);
if (ret < 0) {
err("error registering DVB adapter");
return ret;
}
fc->dvb_adapter.priv = fc;
- fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+ fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
+ | DMX_MEMORY_BASED_FILTERING);
fc->demux.priv = fc;
-
fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
-
fc->demux.start_feed = flexcop_dvb_start_feed;
fc->demux.stop_feed = flexcop_dvb_stop_feed;
fc->demux.write_to_decoder = NULL;
if ((ret = dvb_dmx_init(&fc->demux)) < 0) {
- err("dvb_dmx failed: error %d",ret);
+ err("dvb_dmx failed: error %d", ret);
goto err_dmx;
}
@@ -97,23 +97,23 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
fc->dmxdev.demux = &fc->demux.dmx;
fc->dmxdev.capabilities = 0;
if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) {
- err("dvb_dmxdev_init failed: error %d",ret);
+ err("dvb_dmxdev_init failed: error %d", ret);
goto err_dmx_dev;
}
if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
- err("adding hw_frontend to dmx failed: error %d",ret);
+ err("adding hw_frontend to dmx failed: error %d", ret);
goto err_dmx_add_hw_frontend;
}
fc->mem_frontend.source = DMX_MEMORY_FE;
if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) {
- err("adding mem_frontend to dmx failed: error %d",ret);
+ err("adding mem_frontend to dmx failed: error %d", ret);
goto err_dmx_add_mem_frontend;
}
if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
- err("connect frontend failed: error %d",ret);
+ err("connect frontend failed: error %d", ret);
goto err_connect_frontend;
}
@@ -123,9 +123,9 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
return 0;
err_connect_frontend:
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
err_dmx_add_mem_frontend:
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
err_dmx_add_hw_frontend:
dvb_dmxdev_release(&fc->dmxdev);
err_dmx_dev:
@@ -141,12 +141,13 @@ static void flexcop_dvb_exit(struct flexcop_device *fc)
dvb_net_release(&fc->dvbnet);
fc->demux.dmx.close(&fc->demux.dmx);
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+ &fc->mem_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+ &fc->hw_frontend);
dvb_dmxdev_release(&fc->dmxdev);
dvb_dmx_release(&fc->demux);
dvb_unregister_adapter(&fc->dvb_adapter);
-
deb_info("deinitialized dvb stuff\n");
}
fc->init_state &= ~FC_STATE_DVB_INIT;
@@ -168,9 +169,9 @@ EXPORT_SYMBOL(flexcop_pass_dmx_packets);
static void flexcop_reset(struct flexcop_device *fc)
{
- flexcop_ibi_value v210,v204;
+ flexcop_ibi_value v210, v204;
-/* reset the flexcop itself */
+ /* reset the flexcop itself */
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.raw = 0;
@@ -183,13 +184,11 @@ static void flexcop_reset(struct flexcop_device *fc)
v210.sw_reset_210.reset_block_600 = 1;
v210.sw_reset_210.reset_block_700 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
-
v210.sw_reset_210.Special_controls = 0xc259;
-
fc->write_ibi_reg(fc,sw_reset_210,v210);
msleep(1);
-/* reset the periphical devices */
+ /* reset the periphical devices */
v204 = fc->read_ibi_reg(fc,misc_204);
v204.misc_204.Per_reset_sig = 0;
@@ -201,25 +200,24 @@ static void flexcop_reset(struct flexcop_device *fc)
void flexcop_reset_block_300(struct flexcop_device *fc)
{
- flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
- v210 = fc->read_ibi_reg(fc,sw_reset_210);
-
- deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+ flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
+ v210 = fc->read_ibi_reg(fc, sw_reset_210);
+ deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.sw_reset_210.reset_block_300 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
fc->write_ibi_reg(fc,sw_reset_210,v210);
- udelay(1000);
fc->write_ibi_reg(fc,ctrl_208,v208_save);
}
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
{
void *bus;
- struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), GFP_KERNEL);
+ struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
+ GFP_KERNEL);
if (!fc) {
err("no memory");
return NULL;
@@ -254,7 +252,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
flexcop_determine_revision(fc);
flexcop_sram_init(fc);
flexcop_hw_filter_init(fc);
-
flexcop_smc_ctrl(fc, 0);
if ((ret = flexcop_dvb_init(fc)))
@@ -279,7 +276,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
goto error;
flexcop_device_name(fc,"initialization of","complete");
-
return 0;
error:
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h
index 0cebe1d92e0..897b10c85ad 100644
--- a/drivers/media/dvb/b2c2/flexcop.h
+++ b/drivers/media/dvb/b2c2/flexcop.h
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop.h - private header file for all flexcop-chip-source files.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.h - private header file for all flexcop-chip-source files
+ * see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_H__
#define __FLEXCOP_H___
@@ -21,11 +19,11 @@ extern int b2c2_flexcop_debug;
#define dprintk(level,args...)
#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_tuner(args...) dprintk(0x02,args)
-#define deb_i2c(args...) dprintk(0x04,args)
-#define deb_ts(args...) dprintk(0x08,args)
-#define deb_sram(args...) dprintk(0x10,args)
-#define deb_rdump(args...) dprintk(0x20,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_tuner(args...) dprintk(0x02, args)
+#define deb_i2c(args...) dprintk(0x04, args)
+#define deb_ts(args...) dprintk(0x08, args)
+#define deb_sram(args...) dprintk(0x10, args)
+#define deb_rdump(args...) dprintk(0x20, args)
#endif
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
index ed9a6756b19..8f64bdbd72b 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
-
/* This file is automatically generated, do not edit things here. */
#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
#define __FLEXCOP_IBI_VALUE_INCLUDED__
diff --git a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
index 49f2315b6e5..c75830d7d94 100644
--- a/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
+++ b/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
-
/* This file is automatically generated, do not edit things here. */
#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
#define __FLEXCOP_IBI_VALUE_INCLUDED__
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig
index 27edb0ece58..8668e634c7e 100644
--- a/drivers/media/dvb/bt8xx/Kconfig
+++ b/drivers/media/dvb/bt8xx/Kconfig
@@ -8,7 +8,7 @@ config DVB_BT8XX
select DVB_OR51211 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
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/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c
index 0258451423a..4601b059b2b 100644
--- a/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/drivers/media/dvb/bt8xx/dst_ca.c
@@ -552,16 +552,19 @@ free_mem_and_exit:
return result;
}
-static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
+static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
{
- struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
- struct dst_state* state = (struct dst_state*) dvbdev->priv;
+ struct dvb_device *dvbdev;
+ struct dst_state *state;
struct ca_slot_info *p_ca_slot_info;
struct ca_caps *p_ca_caps;
struct ca_msg *p_ca_message;
void __user *arg = (void __user *)ioctl_arg;
int result = 0;
+ lock_kernel();
+ dvbdev = (struct dvb_device *)file->private_data;
+ state = (struct dst_state *)dvbdev->priv;
p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
@@ -647,6 +650,7 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
kfree (p_ca_slot_info);
kfree (p_ca_caps);
+ unlock_kernel();
return result;
}
@@ -682,9 +686,9 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t
return 0;
}
-static struct file_operations dst_ca_fops = {
+static const struct file_operations dst_ca_fops = {
.owner = THIS_MODULE,
- .ioctl = dst_ca_ioctl,
+ .unlocked_ioctl = dst_ca_ioctl,
.open = dst_ca_open,
.release = dst_ca_release,
.read = dst_ca_read,
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
index 48762a2b9e4..b1857c19bbd 100644
--- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c
+++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c
@@ -814,7 +814,7 @@ static int __devinit dvb_bt8xx_probe(struct bttv_sub_device *sub)
mutex_init(&card->lock);
card->bttv_nr = sub->core->nr;
- strncpy(card->card_name, sub->core->name, sizeof(sub->core->name));
+ strlcpy(card->card_name, sub->core->v4l2_dev.name, sizeof(card->card_name));
card->i2c_adapter = &sub->core->i2c_adap;
switch(sub->core->type) {
diff --git a/drivers/media/dvb/dm1105/Kconfig b/drivers/media/dvb/dm1105/Kconfig
index 43f4d44edca..de3eeb0a8d6 100644
--- a/drivers/media/dvb/dm1105/Kconfig
+++ b/drivers/media/dvb/dm1105/Kconfig
@@ -8,6 +8,7 @@ config DVB_DM1105
select DVB_STB6000 if !DVB_FE_CUSTOMISE
select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_SI21XX if !DVB_FE_CUSTOMISE
+ select VIDEO_IR
help
Support for cards based on the SDMC DM1105 PCI chip like
DvbWorld 2002
diff --git a/drivers/media/dvb/dm1105/dm1105.c b/drivers/media/dvb/dm1105/dm1105.c
index f48f73aff19..5b20cf5a29f 100644
--- a/drivers/media/dvb/dm1105/dm1105.c
+++ b/drivers/media/dvb/dm1105/dm1105.c
@@ -156,46 +156,12 @@ MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-static u16 ir_codes_dm1105_nec[128] = {
- [0x0a] = KEY_Q, /*power*/
- [0x0c] = KEY_M, /*mute*/
- [0x11] = KEY_1,
- [0x12] = KEY_2,
- [0x13] = KEY_3,
- [0x14] = KEY_4,
- [0x15] = KEY_5,
- [0x16] = KEY_6,
- [0x17] = KEY_7,
- [0x18] = KEY_8,
- [0x19] = KEY_9,
- [0x10] = KEY_0,
- [0x1c] = KEY_PAGEUP, /*ch+*/
- [0x0f] = KEY_PAGEDOWN, /*ch-*/
- [0x1a] = KEY_O, /*vol+*/
- [0x0e] = KEY_Z, /*vol-*/
- [0x04] = KEY_R, /*rec*/
- [0x09] = KEY_D, /*fav*/
- [0x08] = KEY_BACKSPACE, /*rewind*/
- [0x07] = KEY_A, /*fast*/
- [0x0b] = KEY_P, /*pause*/
- [0x02] = KEY_ESC, /*cancel*/
- [0x03] = KEY_G, /*tab*/
- [0x00] = KEY_UP, /*up*/
- [0x1f] = KEY_ENTER, /*ok*/
- [0x01] = KEY_DOWN, /*down*/
- [0x05] = KEY_C, /*cap*/
- [0x06] = KEY_S, /*stop*/
- [0x40] = KEY_F, /*full*/
- [0x1e] = KEY_W, /*tvmode*/
- [0x1b] = KEY_B, /*recall*/
-};
-
/* infrared remote control */
struct infrared {
- u16 key_map[128];
struct input_dev *input_dev;
+ struct ir_input_state ir;
char input_phys[32];
- struct tasklet_struct ir_tasklet;
+ struct work_struct work;
u32 ir_command;
};
@@ -220,10 +186,14 @@ struct dm1105dvb {
/* i2c */
struct i2c_adapter i2c_adap;
+ /* irq */
+ struct work_struct work;
+
/* dma */
dma_addr_t dma_addr;
unsigned char *ts_buf;
u32 wrp;
+ u32 nextwrp;
u32 buffer_size;
unsigned int PacketErrorCount;
unsigned int dmarst;
@@ -233,8 +203,6 @@ struct dm1105dvb {
#define dm_io_mem(reg) ((unsigned long)(&dm1105dvb->io_mem[reg]))
-static struct dm1105dvb *dm1105dvb_local;
-
static int dm1105_i2c_xfer(struct i2c_adapter *i2c_adap,
struct i2c_msg *msgs, int num)
{
@@ -407,38 +375,61 @@ static int dm1105dvb_stop_feed(struct dvb_demux_feed *f)
return 0;
}
-/* ir tasklet */
-static void dm1105_emit_key(unsigned long parm)
+/* ir work handler */
+static void dm1105_emit_key(struct work_struct *work)
{
- struct infrared *ir = (struct infrared *) parm;
+ struct infrared *ir = container_of(work, struct infrared, work);
u32 ircom = ir->ir_command;
u8 data;
- u16 keycode;
+
+ if (ir_debug)
+ printk(KERN_INFO "%s: received byte 0x%04x\n", __func__, ircom);
data = (ircom >> 8) & 0x7f;
- input_event(ir->input_dev, EV_MSC, MSC_RAW, (0x0000f8 << 16) | data);
- input_event(ir->input_dev, EV_MSC, MSC_SCAN, data);
- keycode = ir->key_map[data];
+ ir_input_keydown(ir->input_dev, &ir->ir, data, data);
+ ir_input_nokey(ir->input_dev, &ir->ir);
+}
- if (!keycode)
- return;
+/* work handler */
+static void dm1105_dmx_buffer(struct work_struct *work)
+{
+ struct dm1105dvb *dm1105dvb =
+ container_of(work, struct dm1105dvb, work);
+ unsigned int nbpackets;
+ u32 oldwrp = dm1105dvb->wrp;
+ u32 nextwrp = dm1105dvb->nextwrp;
+
+ if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
+ (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
+ (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
+ dm1105dvb->PacketErrorCount++;
+ /* bad packet found */
+ if ((dm1105dvb->PacketErrorCount >= 2) &&
+ (dm1105dvb->dmarst == 0)) {
+ outb(1, dm_io_mem(DM1105_RST));
+ dm1105dvb->wrp = 0;
+ dm1105dvb->PacketErrorCount = 0;
+ dm1105dvb->dmarst = 0;
+ return;
+ }
+ }
- input_event(ir->input_dev, EV_KEY, keycode, 1);
- input_sync(ir->input_dev);
- input_event(ir->input_dev, EV_KEY, keycode, 0);
- input_sync(ir->input_dev);
+ if (nextwrp < oldwrp) {
+ memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size,
+ dm1105dvb->ts_buf, nextwrp);
+ nbpackets = ((dm1105dvb->buffer_size - oldwrp) + nextwrp) / 188;
+ } else
+ nbpackets = (nextwrp - oldwrp) / 188;
+ dm1105dvb->wrp = nextwrp;
+ dvb_dmx_swfilter_packets(&dm1105dvb->demux,
+ &dm1105dvb->ts_buf[oldwrp], nbpackets);
}
static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
{
struct dm1105dvb *dm1105dvb = dev_id;
- unsigned int piece;
- unsigned int nbpackets;
- u32 command;
- u32 nextwrp;
- u32 oldwrp;
/* Read-Write INSTS Ack's Interrupt for DM1105 chip 16.03.2008 */
unsigned int intsts = inb(dm_io_mem(DM1105_INTSTS));
@@ -447,71 +438,25 @@ static irqreturn_t dm1105dvb_irq(int irq, void *dev_id)
switch (intsts) {
case INTSTS_TSIRQ:
case (INTSTS_TSIRQ | INTSTS_IR):
- nextwrp = inl(dm_io_mem(DM1105_WRP)) -
- inl(dm_io_mem(DM1105_STADR)) ;
- oldwrp = dm1105dvb->wrp;
- spin_lock(&dm1105dvb->lock);
- if (!((dm1105dvb->ts_buf[oldwrp] == 0x47) &&
- (dm1105dvb->ts_buf[oldwrp + 188] == 0x47) &&
- (dm1105dvb->ts_buf[oldwrp + 188 * 2] == 0x47))) {
- dm1105dvb->PacketErrorCount++;
- /* bad packet found */
- if ((dm1105dvb->PacketErrorCount >= 2) &&
- (dm1105dvb->dmarst == 0)) {
- outb(1, dm_io_mem(DM1105_RST));
- dm1105dvb->wrp = 0;
- dm1105dvb->PacketErrorCount = 0;
- dm1105dvb->dmarst = 0;
- spin_unlock(&dm1105dvb->lock);
- return IRQ_HANDLED;
- }
- }
- if (nextwrp < oldwrp) {
- piece = dm1105dvb->buffer_size - oldwrp;
- memcpy(dm1105dvb->ts_buf + dm1105dvb->buffer_size, dm1105dvb->ts_buf, nextwrp);
- nbpackets = (piece + nextwrp)/188;
- } else {
- nbpackets = (nextwrp - oldwrp)/188;
- }
- dvb_dmx_swfilter_packets(&dm1105dvb->demux, &dm1105dvb->ts_buf[oldwrp], nbpackets);
- dm1105dvb->wrp = nextwrp;
- spin_unlock(&dm1105dvb->lock);
+ dm1105dvb->nextwrp = inl(dm_io_mem(DM1105_WRP)) -
+ inl(dm_io_mem(DM1105_STADR));
+ schedule_work(&dm1105dvb->work);
break;
case INTSTS_IR:
- command = inl(dm_io_mem(DM1105_IRCODE));
- if (ir_debug)
- printk("dm1105: received byte 0x%04x\n", command);
-
- dm1105dvb->ir.ir_command = command;
- tasklet_schedule(&dm1105dvb->ir.ir_tasklet);
+ dm1105dvb->ir.ir_command = inl(dm_io_mem(DM1105_IRCODE));
+ schedule_work(&dm1105dvb->ir.work);
break;
}
- return IRQ_HANDLED;
-
-
-}
-
-/* register with input layer */
-static void input_register_keys(struct infrared *ir)
-{
- int i;
- memset(ir->input_dev->keybit, 0, sizeof(ir->input_dev->keybit));
-
- for (i = 0; i < ARRAY_SIZE(ir->key_map); i++)
- set_bit(ir->key_map[i], ir->input_dev->keybit);
-
- ir->input_dev->keycode = ir->key_map;
- ir->input_dev->keycodesize = sizeof(ir->key_map[0]);
- ir->input_dev->keycodemax = ARRAY_SIZE(ir->key_map);
+ return IRQ_HANDLED;
}
int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
{
struct input_dev *input_dev;
- int err;
-
- dm1105dvb_local = dm1105;
+ IR_KEYTAB_TYPE *ir_codes = ir_codes_dm1105_nec;
+ int ir_type = IR_TYPE_OTHER;
+ int err = -ENOMEM;
input_dev = input_allocate_device();
if (!input_dev)
@@ -521,12 +466,11 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
snprintf(dm1105->ir.input_phys, sizeof(dm1105->ir.input_phys),
"pci-%s/ir0", pci_name(dm1105->pdev));
- input_dev->evbit[0] = BIT(EV_KEY);
+ ir_input_init(input_dev, &dm1105->ir.ir, ir_type, ir_codes);
input_dev->name = "DVB on-card IR receiver";
-
input_dev->phys = dm1105->ir.input_phys;
input_dev->id.bustype = BUS_PCI;
- input_dev->id.version = 2;
+ input_dev->id.version = 1;
if (dm1105->pdev->subsystem_vendor) {
input_dev->id.vendor = dm1105->pdev->subsystem_vendor;
input_dev->id.product = dm1105->pdev->subsystem_device;
@@ -534,25 +478,22 @@ int __devinit dm1105_ir_init(struct dm1105dvb *dm1105)
input_dev->id.vendor = dm1105->pdev->vendor;
input_dev->id.product = dm1105->pdev->device;
}
+
input_dev->dev.parent = &dm1105->pdev->dev;
- /* initial keymap */
- memcpy(dm1105->ir.key_map, ir_codes_dm1105_nec, sizeof dm1105->ir.key_map);
- input_register_keys(&dm1105->ir);
+
+ INIT_WORK(&dm1105->ir.work, dm1105_emit_key);
+
err = input_register_device(input_dev);
if (err) {
input_free_device(input_dev);
return err;
}
- tasklet_init(&dm1105->ir.ir_tasklet, dm1105_emit_key, (unsigned long) &dm1105->ir);
-
return 0;
}
-
void __devexit dm1105_ir_exit(struct dm1105dvb *dm1105)
{
- tasklet_kill(&dm1105->ir.ir_tasklet);
input_unregister_device(dm1105->ir.input_dev);
}
@@ -710,7 +651,7 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
dm1105dvb = kzalloc(sizeof(struct dm1105dvb), GFP_KERNEL);
if (!dm1105dvb)
- goto out;
+ return -ENOMEM;
dm1105dvb->pdev = pdev;
dm1105dvb->buffer_size = 5 * DM1105_DMA_BYTES;
@@ -740,13 +681,9 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
spin_lock_init(&dm1105dvb->lock);
pci_set_drvdata(pdev, dm1105dvb);
- ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED, DRIVER_NAME, dm1105dvb);
- if (ret < 0)
- goto err_pci_iounmap;
-
ret = dm1105dvb_hw_init(dm1105dvb);
if (ret < 0)
- goto err_free_irq;
+ goto err_pci_iounmap;
/* i2c */
i2c_set_adapdata(&dm1105dvb->i2c_adap, dm1105dvb);
@@ -813,8 +750,15 @@ static int __devinit dm1105_probe(struct pci_dev *pdev,
dvb_net_init(dvb_adapter, &dm1105dvb->dvbnet, dmx);
dm1105_ir_init(dm1105dvb);
-out:
- return ret;
+
+ INIT_WORK(&dm1105dvb->work, dm1105_dmx_buffer);
+
+ ret = request_irq(pdev->irq, dm1105dvb_irq, IRQF_SHARED,
+ DRIVER_NAME, dm1105dvb);
+ if (ret < 0)
+ goto err_free_irq;
+
+ return 0;
err_disconnect_frontend:
dmx->disconnect_frontend(dmx);
@@ -843,7 +787,7 @@ err_pci_disable_device:
err_kfree:
pci_set_drvdata(pdev, NULL);
kfree(dm1105dvb);
- goto out;
+ return ret;
}
static void __devexit dm1105_remove(struct pci_dev *pdev)
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c
index 069d847ba88..c35fbb8d8f4 100644
--- a/drivers/media/dvb/dvb-core/dmxdev.c
+++ b/drivers/media/dvb/dvb-core/dmxdev.c
@@ -1024,7 +1024,7 @@ static int dvb_demux_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_demux_fops = {
+static const struct file_operations dvb_demux_fops = {
.owner = THIS_MODULE,
.read = dvb_demux_read,
.ioctl = dvb_demux_ioctl,
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
index 7e3aeaa7370..cb22da53bfb 100644
--- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
+++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c
@@ -1607,7 +1607,7 @@ static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait)
EXPORT_SYMBOL(dvb_ca_en50221_init);
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_en50221_io_read,
.write = dvb_ca_en50221_io_write,
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index 8dcb3fbf7ac..ebc78157b9b 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -1875,7 +1875,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file)
return ret;
}
-static struct file_operations dvb_frontend_fops = {
+static const struct file_operations dvb_frontend_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.poll = dvb_frontend_poll,
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c
index f6ba8468858..8280f8d66a3 100644
--- a/drivers/media/dvb/dvb-core/dvb_net.c
+++ b/drivers/media/dvb/dvb-core/dvb_net.c
@@ -1459,7 +1459,7 @@ static int dvb_net_close(struct inode *inode, struct file *file)
}
-static struct file_operations dvb_net_fops = {
+static const struct file_operations dvb_net_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_net_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index 6a32680dbb1..a454ee8f1e4 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -228,8 +228,8 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
dvbdev->fops = dvbdevfops;
init_waitqueue_head (&dvbdev->wait_queue);
- memcpy(dvbdev->fops, template->fops, sizeof(struct file_operations));
- dvbdev->fops->owner = adap->module;
+ memcpy(dvbdevfops, template->fops, sizeof(struct file_operations));
+ dvbdevfops->owner = adap->module;
list_add_tail (&dvbdev->list_head, &adap->device_list);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h
index dca49cf962e..79927305e84 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.h
+++ b/drivers/media/dvb/dvb-core/dvbdev.h
@@ -71,7 +71,7 @@ struct dvb_adapter {
struct dvb_device {
struct list_head list_head;
- struct file_operations *fops;
+ const struct file_operations *fops;
struct dvb_adapter *adapter;
int type;
int minor;
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 49f7b20c25d..6103caad164 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -25,7 +25,7 @@ config DVB_USB_A800
depends on DVB_USB
select DVB_DIB3000MC
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the AVerMedia AverTV DVB-T USB 2.0 (A800) receiver.
@@ -34,7 +34,7 @@ config DVB_USB_DIBUSB_MB
depends on DVB_USB
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_DIB3000MB
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Support for USB 1.1 and 2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-B demodulator.
@@ -55,7 +55,7 @@ config DVB_USB_DIBUSB_MC
tristate "DiBcom USB DVB-T devices (based on the DiB3000M-C/P) (see help for device list)"
depends on DVB_USB
select DVB_DIB3000MC
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Support for USB2.0 DVB-T receivers based on reference designs made by
DiBcom (<http://www.dibcom.fr>) equipped with a DiB3000M-C/P demodulator.
@@ -69,15 +69,17 @@ config DVB_USB_DIBUSB_MC
config DVB_USB_DIB0700
tristate "DiBcom DiB0700 USB DVB devices (see help for supported devices)"
depends on DVB_USB
- select DVB_DIB7000P
- select DVB_DIB7000M
- select DVB_DIB3000MC
+ select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+ select DVB_DIB7000M if !DVB_FE_CUSTOMISE
+ select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_TUNER_DIB0070
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMIZE
+ select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+ select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MT2266 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
help
Support for USB2.0/1.1 DVB receivers based on the DiB0700 USB bridge. The
USB bridge is also present in devices having the DiB7700 DVB-T-USB
@@ -95,7 +97,8 @@ config DVB_USB_UMT_010
depends on DVB_USB
select DVB_PLL if !DVB_FE_CUSTOMISE
select DVB_DIB3000MC
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select DVB_MT352 if !DVB_FE_CUSTOMISE
help
Say Y here to support the HanfTek UMT-010 USB2.0 stick-sized DVB-T receiver.
@@ -108,10 +111,11 @@ config DVB_USB_CXUSB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_DIB7000P if !DVB_FE_CUSTOMISE
+ select DVB_LGS8GL5 if !DVB_FE_CUSTOMISE
select DVB_TUNER_DIB0070 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
@@ -125,8 +129,8 @@ config DVB_USB_M920X
depends on DVB_USB
select DVB_MT352 if !DVB_FE_CUSTOMISE
select DVB_TDA1004X if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the MSI Mega Sky 580 USB2.0 DVB-T receiver.
Currently, only devices with a product id of
@@ -137,7 +141,7 @@ config DVB_USB_GL861
tristate "Genesys Logic GL861 USB2.0 support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the MSI Megasky 580 (55801) DVB-T USB2.0
receiver with USB ID 0db0:5581.
@@ -146,7 +150,7 @@ config DVB_USB_AU6610
tristate "Alcor Micro AU6610 USB2.0 support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Sigmatek DVB-110 DVB-T USB2.0 receiver.
@@ -199,7 +203,7 @@ config DVB_USB_NOVA_T_USB2
depends on DVB_USB
select DVB_DIB3000MC
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 receiver.
@@ -235,8 +239,8 @@ config DVB_USB_OPERA1
config DVB_USB_AF9005
tristate "Afatech AF9005 DVB-T USB1.1 support"
depends on DVB_USB && EXPERIMENTAL
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver
and the TerraTec Cinergy T USB XE (Rev.1)
@@ -284,7 +288,7 @@ config DVB_USB_DTV5100
tristate "AME DTV-5100 USB2.0 DVB-T support"
depends on DVB_USB
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the AME DTV-5100 USB2.0 DVB-T receiver.
@@ -293,9 +297,18 @@ config DVB_USB_AF9015
depends on DVB_USB && EXPERIMENTAL
select DVB_AF9013
select DVB_PLL if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MT2060 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_QT1010 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
+
+config DVB_USB_CE6230
+ tristate "Intel CE6230 DVB-T USB2.0 support"
+ depends on DVB_USB && EXPERIMENTAL
+ select DVB_ZL10353
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ help
+ Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 3122b7cc2c2..f92734ed777 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -76,6 +76,8 @@ obj-$(CONFIG_DVB_USB_AF9015) += dvb-usb-af9015.o
dvb-usb-cinergyT2-objs = cinergyT2-core.o cinergyT2-fe.o
obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
+dvb-usb-ce6230-objs = ce6230.o
+obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
# due to tuner-xc3028
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 6a97a40d3df..f0ba8b07b84 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -27,9 +27,7 @@
#include "qt1010.h"
#include "tda18271.h"
#include "mxl5005s.h"
-#if 0
-#include "mc44s80x.h"
-#endif
+#include "mc44s803.h"
static int dvb_usb_af9015_debug;
module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -37,9 +35,6 @@ MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
static int dvb_usb_af9015_remote;
module_param_named(remote, dvb_usb_af9015_remote, int, 0644);
MODULE_PARM_DESC(remote, "select remote");
-static int dvb_usb_af9015_dual_mode;
-module_param_named(dual_mode, dvb_usb_af9015_dual_mode, int, 0644);
-MODULE_PARM_DESC(dual_mode, "enable dual mode");
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
static DEFINE_MUTEX(af9015_usb_mutex);
@@ -283,6 +278,21 @@ Due to that the only way to select correct tuner is use demodulator I2C-gate.
req.data = &msg[i+1].buf[0];
ret = af9015_ctrl_msg(d, &req);
i += 2;
+ } else if (msg[i].flags & I2C_M_RD) {
+ ret = -EINVAL;
+ if (msg[i].addr ==
+ af9015_af9013_config[0].demod_address)
+ goto error;
+ else
+ req.cmd = READ_I2C;
+ req.i2c_addr = msg[i].addr;
+ req.addr = addr;
+ req.mbox = mbox;
+ req.addr_len = addr_len;
+ req.data_len = msg[i].len;
+ req.data = &msg[i].buf[0];
+ ret = af9015_ctrl_msg(d, &req);
+ i += 1;
} else {
if (msg[i].addr ==
af9015_af9013_config[0].demod_address)
@@ -748,6 +758,16 @@ static int af9015_read_config(struct usb_device *udev)
af9015_config.ir_table_size =
ARRAY_SIZE(af9015_ir_table_digittrade);
break;
+ case AF9015_REMOTE_AVERMEDIA_KS:
+ af9015_properties[i].rc_key_map =
+ af9015_rc_keys_avermedia;
+ af9015_properties[i].rc_key_map_size =
+ ARRAY_SIZE(af9015_rc_keys_avermedia);
+ af9015_config.ir_table =
+ af9015_ir_table_avermedia_ks;
+ af9015_config.ir_table_size =
+ ARRAY_SIZE(af9015_ir_table_avermedia_ks);
+ break;
}
} else {
switch (le16_to_cpu(udev->descriptor.idVendor)) {
@@ -836,9 +856,6 @@ static int af9015_read_config(struct usb_device *udev)
goto error;
af9015_config.dual_mode = val;
deb_info("%s: TS mode:%d\n", __func__, af9015_config.dual_mode);
- /* disable dual mode by default because it is buggy */
- if (!dvb_usb_af9015_dual_mode)
- af9015_config.dual_mode = 0;
/* Set adapter0 buffer size according to USB port speed, adapter1 buffer
size can be static because it is enabled only USB2.0 */
@@ -935,7 +952,6 @@ static int af9015_read_config(struct usb_device *udev)
switch (val) {
case AF9013_TUNER_ENV77H11D5:
case AF9013_TUNER_MT2060:
- case AF9013_TUNER_MC44S803:
case AF9013_TUNER_QT1010:
case AF9013_TUNER_UNKNOWN:
case AF9013_TUNER_MT2060_2:
@@ -948,6 +964,10 @@ static int af9015_read_config(struct usb_device *udev)
case AF9013_TUNER_MXL5005R:
af9015_af9013_config[i].rf_spec_inv = 0;
break;
+ case AF9013_TUNER_MC44S803:
+ af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+ af9015_af9013_config[i].rf_spec_inv = 1;
+ break;
default:
warn("tuner id:%d not supported, please report!", val);
return -ENODEV;
@@ -1135,6 +1155,11 @@ static struct mxl5005s_config af9015_mxl5005_config = {
.AgcMasterByte = 0x00,
};
+static struct mc44s803_config af9015_mc44s803_config = {
+ .i2c_address = 0xc0,
+ .dig_out = 1,
+};
+
static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
{
struct af9015_state *state = adap->dev->priv;
@@ -1179,15 +1204,8 @@ static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_MC44S803:
-#if 0
- ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap)
- == NULL ? -ENODEV : 0;
-#else
- ret = -ENODEV;
- info("Freescale MC44S803 tuner found but no driver for that" \
- "tuner. Look at the Linuxtv.org for tuner driver" \
- "status.");
-#endif
+ ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
+ &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
break;
case AF9013_TUNER_UNKNOWN:
default:
@@ -1218,6 +1236,7 @@ static struct usb_device_id af9015_usb_table[] = {
{USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A309)},
/* 15 */{USB_DEVICE(USB_VID_MSI_2, USB_PID_MSI_DIGI_VOX_MINI_III)},
{USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U)},
+ {USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_395U_2)},
{0},
};
MODULE_DEVICE_TABLE(usb, af9015_usb_table);
@@ -1417,7 +1436,8 @@ static struct dvb_usb_device_properties af9015_properties[] = {
{
.name = "KWorld USB DVB-T TV Stick II " \
"(VS-DVB-T 395U)",
- .cold_ids = {&af9015_usb_table[16], NULL},
+ .cold_ids = {&af9015_usb_table[16],
+ &af9015_usb_table[17], NULL},
.warm_ids = {NULL},
},
}
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index 21c7782f488..00e25714662 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -124,6 +124,7 @@ enum af9015_remote {
AF9015_REMOTE_MSI_DIGIVOX_MINI_II_V3,
AF9015_REMOTE_MYGICTV_U718,
AF9015_REMOTE_DIGITTRADE_DVB_T,
+ AF9015_REMOTE_AVERMEDIA_KS,
};
/* Leadtek WinFast DTV Dongle Gold */
@@ -597,6 +598,36 @@ static u8 af9015_ir_table_avermedia[] = {
0x03, 0xfc, 0x03, 0xfc, 0x0e, 0x05, 0x00,
};
+static u8 af9015_ir_table_avermedia_ks[] = {
+ 0x05, 0xfa, 0x01, 0xfe, 0x12, 0x05, 0x00,
+ 0x05, 0xfa, 0x02, 0xfd, 0x0e, 0x05, 0x00,
+ 0x05, 0xfa, 0x03, 0xfc, 0x0d, 0x05, 0x00,
+ 0x05, 0xfa, 0x04, 0xfb, 0x2e, 0x05, 0x00,
+ 0x05, 0xfa, 0x05, 0xfa, 0x2d, 0x05, 0x00,
+ 0x05, 0xfa, 0x06, 0xf9, 0x10, 0x05, 0x00,
+ 0x05, 0xfa, 0x07, 0xf8, 0x0f, 0x05, 0x00,
+ 0x05, 0xfa, 0x08, 0xf7, 0x3d, 0x05, 0x00,
+ 0x05, 0xfa, 0x09, 0xf6, 0x1e, 0x05, 0x00,
+ 0x05, 0xfa, 0x0a, 0xf5, 0x1f, 0x05, 0x00,
+ 0x05, 0xfa, 0x0b, 0xf4, 0x20, 0x05, 0x00,
+ 0x05, 0xfa, 0x0c, 0xf3, 0x21, 0x05, 0x00,
+ 0x05, 0xfa, 0x0d, 0xf2, 0x22, 0x05, 0x00,
+ 0x05, 0xfa, 0x0e, 0xf1, 0x23, 0x05, 0x00,
+ 0x05, 0xfa, 0x0f, 0xf0, 0x24, 0x05, 0x00,
+ 0x05, 0xfa, 0x10, 0xef, 0x25, 0x05, 0x00,
+ 0x05, 0xfa, 0x11, 0xee, 0x26, 0x05, 0x00,
+ 0x05, 0xfa, 0x12, 0xed, 0x27, 0x05, 0x00,
+ 0x05, 0xfa, 0x13, 0xec, 0x04, 0x05, 0x00,
+ 0x05, 0xfa, 0x15, 0xea, 0x0a, 0x05, 0x00,
+ 0x05, 0xfa, 0x16, 0xe9, 0x11, 0x05, 0x00,
+ 0x05, 0xfa, 0x17, 0xe8, 0x15, 0x05, 0x00,
+ 0x05, 0xfa, 0x18, 0xe7, 0x16, 0x05, 0x00,
+ 0x05, 0xfa, 0x1c, 0xe3, 0x05, 0x05, 0x00,
+ 0x05, 0xfa, 0x1d, 0xe2, 0x09, 0x05, 0x00,
+ 0x05, 0xfa, 0x4d, 0xb2, 0x3f, 0x05, 0x00,
+ 0x05, 0xfa, 0x56, 0xa9, 0x3e, 0x05, 0x00
+};
+
/* Digittrade DVB-T USB Stick */
static struct dvb_usb_rc_key af9015_rc_keys_digittrade[] = {
{ 0x01, 0x0f, KEY_LAST }, /* RETURN */
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
new file mode 100644
index 00000000000..5862820f109
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -0,0 +1,328 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include "ce6230.h"
+#include "zl10353.h"
+#include "mxl5005s.h"
+
+/* debug */
+static int dvb_usb_ce6230_debug;
+module_param_named(debug, dvb_usb_ce6230_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level" DVB_USB_DEBUG_STATUS);
+DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+
+static struct zl10353_config ce6230_zl10353_config;
+
+static int ce6230_rw_udev(struct usb_device *udev, struct req_t *req)
+{
+ int ret;
+ unsigned int pipe;
+ u8 request;
+ u8 requesttype;
+ u16 value;
+ u16 index;
+ u8 buf[req->data_len];
+
+ request = req->cmd;
+ value = req->value;
+ index = req->index;
+
+ switch (req->cmd) {
+ case I2C_READ:
+ case DEMOD_READ:
+ case REG_READ:
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_IN);
+ break;
+ case I2C_WRITE:
+ case DEMOD_WRITE:
+ case REG_WRITE:
+ requesttype = (USB_TYPE_VENDOR | USB_DIR_OUT);
+ break;
+ default:
+ err("unknown command:%02x", req->cmd);
+ ret = -EPERM;
+ goto error;
+ }
+
+ if (requesttype == (USB_TYPE_VENDOR | USB_DIR_OUT)) {
+ /* write */
+ memcpy(buf, req->data, req->data_len);
+ pipe = usb_sndctrlpipe(udev, 0);
+ } else {
+ /* read */
+ pipe = usb_rcvctrlpipe(udev, 0);
+ }
+
+ msleep(1); /* avoid I2C errors */
+
+ ret = usb_control_msg(udev, pipe, request, requesttype, value, index,
+ buf, sizeof(buf), CE6230_USB_TIMEOUT);
+
+ ce6230_debug_dump(request, requesttype, value, index, buf,
+ req->data_len, deb_xfer);
+
+ if (ret < 0)
+ deb_info("%s: usb_control_msg failed:%d\n", __func__, ret);
+ else
+ ret = 0;
+
+ /* read request, copy returned data to return buf */
+ if (!ret && requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
+ memcpy(req->data, buf, req->data_len);
+
+error:
+ return ret;
+}
+
+static int ce6230_ctrl_msg(struct dvb_usb_device *d, struct req_t *req)
+{
+ return ce6230_rw_udev(d->udev, req);
+}
+
+/* I2C */
+static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
+ int num)
+{
+ struct dvb_usb_device *d = i2c_get_adapdata(adap);
+ int i = 0;
+ struct req_t req;
+ int ret = 0;
+ memset(&req, 0, sizeof(&req));
+
+ if (num > 2)
+ return -EINVAL;
+
+ if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
+ return -EAGAIN;
+
+ while (i < num) {
+ if (num > i + 1 && (msg[i+1].flags & I2C_M_RD)) {
+ if (msg[i].addr ==
+ ce6230_zl10353_config.demod_address) {
+ req.cmd = DEMOD_READ;
+ req.value = msg[i].addr >> 1;
+ req.index = msg[i].buf[0];
+ req.data_len = msg[i+1].len;
+ req.data = &msg[i+1].buf[0];
+ ret = ce6230_ctrl_msg(d, &req);
+ } else {
+ err("i2c read not implemented");
+ ret = -EPERM;
+ }
+ i += 2;
+ } else {
+ if (msg[i].addr ==
+ ce6230_zl10353_config.demod_address) {
+ req.cmd = DEMOD_WRITE;
+ req.value = msg[i].addr >> 1;
+ req.index = msg[i].buf[0];
+ req.data_len = msg[i].len-1;
+ req.data = &msg[i].buf[1];
+ ret = ce6230_ctrl_msg(d, &req);
+ } else {
+ req.cmd = I2C_WRITE;
+ req.value = 0x2000 + (msg[i].addr >> 1);
+ req.index = 0x0000;
+ req.data_len = msg[i].len;
+ req.data = &msg[i].buf[0];
+ ret = ce6230_ctrl_msg(d, &req);
+ }
+ i += 1;
+ }
+ if (ret)
+ break;
+ }
+
+ mutex_unlock(&d->i2c_mutex);
+ return ret ? ret : i;
+}
+
+static u32 ce6230_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static struct i2c_algorithm ce6230_i2c_algo = {
+ .master_xfer = ce6230_i2c_xfer,
+ .functionality = ce6230_i2c_func,
+};
+
+/* Callbacks for DVB USB */
+static struct zl10353_config ce6230_zl10353_config = {
+ .demod_address = 0x1e,
+ .adc_clock = 450000,
+ .if2 = 45700,
+ .no_tuner = 1,
+ .parallel_ts = 1,
+ .clock_ctl_1 = 0x34,
+ .pll_0 = 0x0e,
+};
+
+static int ce6230_zl10353_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ deb_info("%s:\n", __func__);
+ adap->fe = dvb_attach(zl10353_attach, &ce6230_zl10353_config,
+ &adap->dev->i2c_adap);
+ if (adap->fe == NULL)
+ return -ENODEV;
+ return 0;
+}
+
+static struct mxl5005s_config ce6230_mxl5003s_config = {
+ .i2c_address = 0xc6,
+ .if_freq = IF_FREQ_4570000HZ,
+ .xtal_freq = CRYSTAL_FREQ_16000000HZ,
+ .agc_mode = MXL_SINGLE_AGC,
+ .tracking_filter = MXL_TF_DEFAULT,
+ .rssi_enable = MXL_RSSI_ENABLE,
+ .cap_select = MXL_CAP_SEL_ENABLE,
+ .div_out = MXL_DIV_OUT_4,
+ .clock_out = MXL_CLOCK_OUT_DISABLE,
+ .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM,
+ .top = MXL5005S_TOP_25P2,
+ .mod_mode = MXL_DIGITAL_MODE,
+ .if_mode = MXL_ZERO_IF,
+ .AgcMasterByte = 0x00,
+};
+
+static int ce6230_mxl5003s_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ int ret;
+ deb_info("%s:\n", __func__);
+ ret = dvb_attach(mxl5005s_attach, adap->fe, &adap->dev->i2c_adap,
+ &ce6230_mxl5003s_config) == NULL ? -ENODEV : 0;
+ return ret;
+}
+
+static int ce6230_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ int ret;
+ deb_info("%s: onoff:%d\n", __func__, onoff);
+
+ /* InterfaceNumber 1 / AlternateSetting 0 idle
+ InterfaceNumber 1 / AlternateSetting 1 streaming */
+ ret = usb_set_interface(d->udev, 1, onoff);
+ if (ret)
+ err("usb_set_interface failed with error:%d", ret);
+
+ return ret;
+}
+
+/* DVB USB Driver stuff */
+static struct dvb_usb_device_properties ce6230_properties;
+
+static int ce6230_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ int ret = 0;
+ struct dvb_usb_device *d = NULL;
+
+ deb_info("%s: interface:%d\n", __func__,
+ intf->cur_altsetting->desc.bInterfaceNumber);
+
+ if (intf->cur_altsetting->desc.bInterfaceNumber == 1) {
+ ret = dvb_usb_device_init(intf, &ce6230_properties, THIS_MODULE,
+ &d, adapter_nr);
+ if (ret)
+ err("init failed with error:%d\n", ret);
+ }
+
+ return ret;
+}
+
+static struct usb_device_id ce6230_table[] = {
+ { USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, ce6230_table);
+
+static struct dvb_usb_device_properties ce6230_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .no_reconnect = 1,
+
+ .size_of_priv = 0,
+
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = ce6230_zl10353_frontend_attach,
+ .tuner_attach = ce6230_mxl5003s_tuner_attach,
+ .stream = {
+ .type = USB_BULK,
+ .count = 6,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 512,
+ }
+ }
+ },
+ }
+ },
+
+ .power_ctrl = ce6230_power_ctrl,
+
+ .i2c_algo = &ce6230_i2c_algo,
+
+ .num_device_descs = 1,
+ .devices = {
+ {
+ .name = "Intel CE9500 reference design",
+ .cold_ids = {NULL},
+ .warm_ids = {&ce6230_table[0], NULL},
+ },
+ }
+};
+
+static struct usb_driver ce6230_driver = {
+ .name = "dvb_usb_ce6230",
+ .probe = ce6230_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = ce6230_table,
+};
+
+/* module stuff */
+static int __init ce6230_module_init(void)
+{
+ int ret;
+ deb_info("%s:\n", __func__);
+ ret = usb_register(&ce6230_driver);
+ if (ret)
+ err("usb_register failed with error:%d", ret);
+
+ return ret;
+}
+
+static void __exit ce6230_module_exit(void)
+{
+ deb_info("%s:\n", __func__);
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&ce6230_driver);
+}
+
+module_init(ce6230_module_init);
+module_exit(ce6230_module_exit);
+
+MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
+MODULE_DESCRIPTION("Driver for Intel CE6230 DVB-T USB2.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/ce6230.h b/drivers/media/dvb/dvb-usb/ce6230.h
new file mode 100644
index 00000000000..97c42482ccb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/ce6230.h
@@ -0,0 +1,69 @@
+/*
+ * DVB USB Linux driver for Intel CE6230 DVB-T USB2.0 receiver
+ *
+ * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _DVB_USB_CE6230_H_
+#define _DVB_USB_CE6230_H_
+
+#define DVB_USB_LOG_PREFIX "ce6230"
+#include "dvb-usb.h"
+
+#define deb_info(args...) dprintk(dvb_usb_ce6230_debug, 0x01, args)
+#define deb_rc(args...) dprintk(dvb_usb_ce6230_debug, 0x02, args)
+#define deb_xfer(args...) dprintk(dvb_usb_ce6230_debug, 0x04, args)
+#define deb_reg(args...) dprintk(dvb_usb_ce6230_debug, 0x08, args)
+#define deb_i2c(args...) dprintk(dvb_usb_ce6230_debug, 0x10, args)
+#define deb_fw(args...) dprintk(dvb_usb_ce6230_debug, 0x20, args)
+
+#define ce6230_debug_dump(r, t, v, i, b, l, func) { \
+ int loop_; \
+ func("%02x %02x %02x %02x %02x %02x %02x %02x", \
+ t, r, v & 0xff, v >> 8, i & 0xff, i >> 8, l & 0xff, l >> 8); \
+ if (t == (USB_TYPE_VENDOR | USB_DIR_OUT)) \
+ func(" >>> "); \
+ else \
+ func(" <<< "); \
+ for (loop_ = 0; loop_ < l; loop_++) \
+ func("%02x ", b[loop_]); \
+ func("\n");\
+}
+
+#define CE6230_USB_TIMEOUT 1000
+
+struct req_t {
+ u8 cmd; /* [1] */
+ u16 value; /* [2|3] */
+ u16 index; /* [4|5] */
+ u16 data_len; /* [6|7] */
+ u8 *data;
+};
+
+enum ce6230_cmd {
+ CONFIG_READ = 0xd0, /* rd 0 (unclear) */
+ UNKNOWN_WRITE = 0xc7, /* wr 7 (unclear) */
+ I2C_READ = 0xd9, /* rd 9 (unclear) */
+ I2C_WRITE = 0xca, /* wr a */
+ DEMOD_READ = 0xdb, /* rd b */
+ DEMOD_WRITE = 0xcc, /* wr c */
+ REG_READ = 0xde, /* rd e */
+ REG_WRITE = 0xcf, /* wr f */
+};
+
+#endif
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 200b215f4d8..db7f7f79a66 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -158,6 +158,10 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
err("i2c read error (status = %d)\n", result);
break;
}
+
+ deb_data("<<< ");
+ debug_dump(msg[i].buf, msg[i].len, deb_data);
+
} else {
/* Write request */
buf[0] = REQUEST_NEW_I2C_WRITE;
@@ -169,6 +173,9 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
/* The Actual i2c payload */
memcpy(&buf[4], msg[i].buf, msg[i].len);
+ deb_data(">>> ");
+ debug_dump(buf, msg[i].len + 4, deb_data);
+
result = usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev, 0),
REQUEST_NEW_I2C_WRITE,
@@ -211,7 +218,8 @@ static int dib0700_i2c_xfer_legacy(struct i2c_adapter *adap,
/* special thing in the current firmware: when length is zero the read-failed */
if ((len = dib0700_ctrl_rd(d, buf, msg[i].len + 2, msg[i+1].buf, msg[i+1].len)) <= 0) {
- deb_info("I2C read failed on address %x\n", msg[i].addr);
+ deb_info("I2C read failed on address 0x%02x\n",
+ msg[i].addr);
break;
}
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 635d30a5507..8ddbadf6219 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -17,6 +17,8 @@
#include "xc5000.h"
#include "s5h1411.h"
#include "dib0070.h"
+#include "lgdt3305.h"
+#include "mxl5007t.h"
static int force_lna_activation;
module_param(force_lna_activation, int, 0644);
@@ -262,7 +264,12 @@ static int stk7700P2_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap,1,18,stk7700d_dib7000p_mt2266_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -284,7 +291,12 @@ static int stk7700d_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap,2,18,stk7700d_dib7000p_mt2266_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7700d_dib7000p_mt2266_config)
+ != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
+ return -ENODEV;
+ }
}
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap,0x80+(adap->id << 1),
@@ -421,8 +433,12 @@ static int stk7700ph_frontend_attach(struct dvb_usb_adapter *adap)
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
msleep(10);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &stk7700ph_dib7700_xc3028_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &stk7700ph_dib7700_xc3028_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&stk7700ph_dib7700_xc3028_config);
@@ -1187,8 +1203,12 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
- &dib7070p_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
+ &dib7070p_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80,
&dib7070p_dib7000p_config);
@@ -1244,7 +1264,12 @@ static int stk7070pd_frontend_attach0(struct dvb_usb_adapter *adap)
msleep(10);
dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
- dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, stk7070pd_dib7000p_config);
+ if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 2, 18,
+ stk7070pd_dib7000p_config) != 0) {
+ err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n",
+ __func__);
+ return -ENODEV;
+ }
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &stk7070pd_dib7000p_config[0]);
return adap->fe == NULL ? -ENODEV : 0;
@@ -1347,6 +1372,72 @@ static int xc5000_tuner_attach(struct dvb_usb_adapter *adap)
== NULL ? -ENODEV : 0;
}
+static struct lgdt3305_config hcw_lgdt3305_config = {
+ .i2c_addr = 0x0e,
+ .mpeg_mode = LGDT3305_MPEG_PARALLEL,
+ .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
+ .tpvalid_polarity = LGDT3305_TP_VALID_LOW,
+ .deny_i2c_rptr = 0,
+ .spectral_inversion = 1,
+ .qam_if_khz = 6000,
+ .vsb_if_khz = 6000,
+ .usref_8vsb = 0x0500,
+};
+
+static struct mxl5007t_config hcw_mxl5007t_config = {
+ .xtal_freq_hz = MxL_XTAL_25_MHZ,
+ .if_freq_hz = MxL_IF_6_MHZ,
+ .invert_if = 1,
+};
+
+/* TIGER-ATSC map:
+ GPIO0 - LNA_CTR (H: LNA power enabled, L: LNA power disabled)
+ GPIO1 - ANT_SEL (H: VPA, L: MCX)
+ GPIO4 - SCL2
+ GPIO6 - EN_TUNER
+ GPIO7 - SDA2
+ GPIO10 - DEM_RST
+
+ MXL is behind LG's i2c repeater. LG is on SCL2/SDA2 gpios on the DIB
+ */
+static int lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct dib0700_state *st = adap->dev->priv;
+
+ /* Make use of the new i2c functions from FW 1.20 */
+ st->fw_use_new_i2c_api = 1;
+
+ st->disable_streaming_master_mode = 1;
+
+ /* fe power enable */
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
+ msleep(30);
+
+ /* demod reset */
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
+ msleep(30);
+ dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
+ msleep(30);
+
+ adap->fe = dvb_attach(lgdt3305_attach,
+ &hcw_lgdt3305_config,
+ &adap->dev->i2c_adap);
+
+ return adap->fe == NULL ? -ENODEV : 0;
+}
+
+static int mxl5007t_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ return dvb_attach(mxl5007t_attach, adap->fe,
+ &adap->dev->i2c_adap, 0x60,
+ &hcw_mxl5007t_config) == NULL ? -ENODEV : 0;
+}
+
+
/* DVB-USB and USB stuff follows */
struct usb_device_id dib0700_usb_id_table[] = {
/* 0 */ { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7700P) },
@@ -1396,6 +1487,12 @@ struct usb_device_id dib0700_usb_id_table[] = {
{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_EXPRESS) },
{ USB_DEVICE(USB_VID_TERRATEC,
USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY_2) },
+ { USB_DEVICE(USB_VID_SONY, USB_PID_SONY_PLAYTV) },
+/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
+ { USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
+ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
+ { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1595,7 +1692,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 9,
+ .num_device_descs = 11,
.devices = {
{ "DiBcom STK7070P reference design",
{ &dib0700_usb_id_table[15], NULL },
@@ -1633,6 +1730,14 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[33], NULL },
{ NULL },
},
+ { "Elgato EyeTV DTT",
+ { &dib0700_usb_id_table[49], NULL },
+ { NULL },
+ },
+ { "Yuan PD378S",
+ { &dib0700_usb_id_table[45], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
@@ -1661,7 +1766,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
}
},
- .num_device_descs = 5,
+ .num_device_descs = 6,
.devices = {
{ "DiBcom STK7070PD reference design",
{ &dib0700_usb_id_table[17], NULL },
@@ -1682,8 +1787,16 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ "Terratec Cinergy DT USB XS Diversity",
{ &dib0700_usb_id_table[43], NULL },
{ NULL },
+ },
+ { "Sony PlayTV",
+ { &dib0700_usb_id_table[44], NULL },
+ { NULL },
}
- }
+ },
+ .rc_interval = DEFAULT_RC_INTERVAL,
+ .rc_key_map = dib0700_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
+ .rc_query = dib0700_rc_query
}, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
@@ -1699,7 +1812,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 5,
+ .num_device_descs = 7,
.devices = {
{ "Terratec Cinergy HT USB XE",
{ &dib0700_usb_id_table[27], NULL },
@@ -1725,6 +1838,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[39], NULL },
{ NULL },
},
+ { "YUAN High-Tech MC770",
+ { &dib0700_usb_id_table[48], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dib0700_rc_keys,
@@ -1759,6 +1876,31 @@ struct dvb_usb_device_properties dib0700_devices[] = {
.rc_key_map = dib0700_rc_keys,
.rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
.rc_query = dib0700_rc_query
+ }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
+ .num_adapters = 1,
+ .adapter = {
+ {
+ .frontend_attach = lgdt3305_frontend_attach,
+ .tuner_attach = mxl5007t_tuner_attach,
+
+ DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
+
+ .size_of_priv = sizeof(struct
+ dib0700_adapter_state),
+ },
+ },
+
+ .num_device_descs = 2,
+ .devices = {
+ { "Hauppauge ATSC MiniCard (B200)",
+ { &dib0700_usb_id_table[46], NULL },
+ { NULL },
+ },
+ { "Hauppauge ATSC MiniCard (B210)",
+ { &dib0700_usb_id_table[47], NULL },
+ { NULL },
+ },
+ },
},
};
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 0db0c06ee6f..dc7ea21cd13 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -27,12 +27,14 @@
#define USB_VID_DIBCOM 0x10b8
#define USB_VID_DPOSH 0x1498
#define USB_VID_DVICO 0x0fe9
+#define USB_VID_ELGATO 0x0fd9
#define USB_VID_EMPIA 0xeb1a
#define USB_VID_GENPIX 0x09c0
#define USB_VID_GRANDTEC 0x5032
#define USB_VID_HANFTEK 0x15f4
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
+#define USB_VID_INTEL 0x8086
#define USB_VID_KWORLD 0xeb2a
#define USB_VID_KWORLD_2 0x1b80
#define USB_VID_KYE 0x0458
@@ -48,6 +50,7 @@
#define USB_VID_TERRATEC 0x0ccd
#define USB_VID_TELESTAR 0x10b9
#define USB_VID_VISIONPLUS 0x13d3
+#define USB_VID_SONY 0x1415
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
#define USB_VID_UNIWILL 0x1584
@@ -95,8 +98,10 @@
#define USB_PID_UNIWILL_STK7700P 0x6003
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
+#define USB_PID_INTEL_CE9500 0x9500
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_395U 0xe396
+#define USB_PID_KWORLD_395U_2 0xe39b
#define USB_PID_KWORLD_PC160_2T 0xc160
#define USB_PID_KWORLD_VSTREAM_COLD 0x17de
#define USB_PID_KWORLD_VSTREAM_WARM 0x17df
@@ -149,6 +154,8 @@
#define USB_PID_HAUPPAUGE_MYTV_T 0x7080
#define USB_PID_HAUPPAUGE_NOVA_TD_STICK 0x9580
#define USB_PID_HAUPPAUGE_NOVA_TD_STICK_52009 0x5200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC 0xb200
+#define USB_PID_HAUPPAUGE_TIGER_ATSC_B210 0xb210
#define USB_PID_AVERMEDIA_EXPRESS 0xb568
#define USB_PID_AVERMEDIA_VOLAR 0xa807
#define USB_PID_AVERMEDIA_VOLAR_2 0xb808
@@ -232,9 +239,13 @@
#define USB_PID_ASUS_U3100 0x173f
#define USB_PID_YUAN_EC372S 0x1edc
#define USB_PID_YUAN_STK7700PH 0x1f08
+#define USB_PID_YUAN_PD378S 0x2edc
+#define USB_PID_YUAN_MC770 0x0871
#define USB_PID_DW2102 0x2102
#define USB_PID_XTENSIONS_XD_380 0x0381
#define USB_PID_TELESTAR_STARSTICK_2 0x8000
#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
+#define USB_PID_SONY_PLAYTV 0x0003
+#define USB_PID_ELGATO_EYETV_DTT 0x0021
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index b1de0f7e26e..2d5352e54dc 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -223,7 +223,7 @@ struct dvb_usb_device_properties {
int generic_bulk_ctrl_endpoint;
int num_device_descs;
- struct dvb_usb_device_description devices[9];
+ struct dvb_usb_device_description devices[11];
};
/**
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index 32526f103b5..12f7730184a 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -151,7 +151,7 @@ static void debug_fcp(const u8 *data, int length)
subunit_type = data[1] >> 3;
subunit_id = data[1] & 7;
op = subunit_type == 0x1e || subunit_id == 5 ? ~0 : data[2];
- printk(KERN_INFO "%ssu=%x.%x l=%d: %-8s - %s\n",
+ printk(KERN_INFO "%ssu=%x.%x l=%zu: %-8s - %s\n",
prefix, subunit_type, subunit_id, length,
debug_fcp_ctype(data[0]),
debug_fcp_opcode(op, data, length));
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index 00269560793..a486a7f81fa 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -1,17 +1,21 @@
-menu "Customise DVB Frontends"
- depends on DVB_CORE
-
config DVB_FE_CUSTOMISE
bool "Customise the frontend modules to build"
+ depends on DVB_CORE
default N
help
- This allows the user to deselect frontend drivers unnecessary
- for their hardware from the build. Use this option with care
- as deselecting frontends which are in fact necessary will result
- in DVB devices which cannot be tuned due to lack of driver support.
+ This allows the user to select/deselect frontend drivers for their
+ hardware from the build.
+
+ Use this option with care as deselecting frontends which are in fact
+ necessary will result in DVB devices which cannot be tuned due to lack
+ of driver support.
If unsure say N.
+if DVB_FE_CUSTOMISE
+
+menu "Customise DVB Frontends"
+
comment "Multistandard (satellite) frontends"
depends on DVB_CORE
@@ -55,6 +59,13 @@ config DVB_MT312
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_ZL10036
+ tristate "Zarlink ZL10036 silicon tuner"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
config DVB_S5H1420
tristate "Samsung S5H1420 based"
depends on DVB_CORE && I2C
@@ -83,6 +94,20 @@ config DVB_STV0299
help
A DVB-S tuner module. Say Y when you want to support this frontend.
+config DVB_STV6110
+ tristate "ST STV6110 silicon tuner"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_STV0900
+ tristate "ST STV0900 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S/S2 demodulator. Say Y when you want to support this frontend.
+
config DVB_TDA8083
tristate "Philips TDA8083 based"
depends on DVB_CORE && I2C
@@ -288,6 +313,13 @@ config DVB_TDA10048
help
A DVB-T tuner module. Say Y when you want to support this frontend.
+config DVB_AF9013
+ tristate "Afatech AF9013 demodulator"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ Say Y when you want to support this frontend.
+
comment "DVB-C (cable) frontends"
depends on DVB_CORE
@@ -387,6 +419,14 @@ config DVB_LGDT3304
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
+config DVB_LGDT3305
+ tristate "LG Electronics LGDT3305 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+ to support this frontend.
+
config DVB_S5H1409
tristate "Samsung S5H1409 based"
depends on DVB_CORE && I2C
@@ -397,7 +437,7 @@ config DVB_S5H1409
config DVB_AU8522
tristate "Auvitek AU8522 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && VIDEO_V4L2
default m if DVB_FE_CUSTOMISE
help
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -439,18 +479,18 @@ config DVB_TUNER_DIB0070
default m if DVB_FE_CUSTOMISE
help
A driver for the silicon baseband tuner DiB0070 from DiBcom.
- This device is only used inside a SiP called togther with a
+ This device is only used inside a SiP called together with a
demodulator for now.
comment "SEC control devices for DVB-S"
depends on DVB_CORE
config DVB_LNBP21
- tristate "LNBP21 SEC controller"
+ tristate "LNBP21/LNBH24 SEC controllers"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
- An SEC control chip.
+ An SEC control chips.
config DVB_ISL6405
tristate "ISL6405 SEC controller"
@@ -478,11 +518,6 @@ comment "Tools to develop new frontends"
config DVB_DUMMY_FE
tristate "Dummy frontend driver"
default n
-
-config DVB_AF9013
- tristate "Afatech AF9013 demodulator"
- depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
- help
- Say Y when you want to support this frontend.
endmenu
+
+endif
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index af7bdf0ad4c..65a336aa1db 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -7,6 +7,8 @@ EXTRA_CFLAGS += -Idrivers/media/common/tuners/
s921-objs := s921_module.o s921_core.o
stb0899-objs = stb0899_drv.o stb0899_algo.o
+stv0900-objs = stv0900_core.o stv0900_sw.o
+au8522-objs = au8522_dig.o au8522_decoder.o
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -28,6 +30,7 @@ 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_ZL10036) += zl10036.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
@@ -41,6 +44,7 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o
+obj-$(CONFIG_DVB_LGDT3305) += lgdt3305.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6405) += isl6405.o
@@ -64,4 +68,6 @@ obj-$(CONFIG_DVB_SI21XX) += si21xx.o
obj-$(CONFIG_DVB_STV0288) += stv0288.o
obj-$(CONFIG_DVB_STB6000) += stb6000.o
obj-$(CONFIG_DVB_S921) += s921.o
+obj-$(CONFIG_DVB_STV6110) += stv6110.o
+obj-$(CONFIG_DVB_STV0900) += stv0900.o
diff --git a/drivers/media/dvb/frontends/au8522.h b/drivers/media/dvb/frontends/au8522.h
index 7b94f554a09..565dcf31af5 100644
--- a/drivers/media/dvb/frontends/au8522.h
+++ b/drivers/media/dvb/frontends/au8522.h
@@ -74,6 +74,22 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
}
#endif /* CONFIG_DVB_AU8522 */
+/* Other modes may need to be added later */
+enum au8522_video_input {
+ AU8522_COMPOSITE_CH1 = 1,
+ AU8522_COMPOSITE_CH2,
+ AU8522_COMPOSITE_CH3,
+ AU8522_COMPOSITE_CH4,
+ AU8522_COMPOSITE_CH4_SIF,
+ AU8522_SVIDEO_CH13,
+ AU8522_SVIDEO_CH24,
+};
+
+enum au8522_audio_input {
+ AU8522_AUDIO_NONE,
+ AU8522_AUDIO_SIF,
+};
+
#endif /* __AU8522_H__ */
/*
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
new file mode 100644
index 00000000000..d63e1527dc8
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -0,0 +1,835 @@
+/*
+ * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ */
+
+/* Developer notes:
+ *
+ * VBI support is not yet working
+ * Saturation and hue setting are not yet working
+ * Enough is implemented here for CVBS and S-Video inputs, but the actual
+ * analog demodulator code isn't implemented (not needed for xc5000 since it
+ * has its own demodulator and outputs CVBS)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/videodev2.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
+#include <media/v4l2-device.h>
+#include "au8522.h"
+#include "au8522_priv.h"
+
+MODULE_AUTHOR("Devin Heitmueller");
+MODULE_LICENSE("GPL");
+
+static int au8522_analog_debug;
+
+
+module_param_named(analog_debug, au8522_analog_debug, int, 0644);
+
+MODULE_PARM_DESC(analog_debug,
+ "Analog debugging messages [0=Off (default) 1=On]");
+
+struct au8522_register_config {
+ u16 reg_name;
+ u8 reg_val[8];
+};
+
+
+/* Video Decoder Filter Coefficients
+ The values are as follows from left to right
+ 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
+*/
+struct au8522_register_config filter_coef[] = {
+ {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
+ {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
+ {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
+ {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
+ {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
+ {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
+ {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
+ {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
+ {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
+ {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
+ {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
+ {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
+ {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
+ {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
+ {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
+ {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
+ {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
+ {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
+ {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
+ {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
+ {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
+ {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
+
+};
+#define NUM_FILTER_COEF (sizeof(filter_coef)\
+ / sizeof(struct au8522_register_config))
+
+
+/* Registers 0x060b through 0x0652 are the LP Filter coefficients
+ The values are as follows from left to right
+ 0="SIF" 1="ATVRF/ATVRF13"
+ Note: the "ATVRF/ATVRF13" mode has never been tested
+*/
+struct au8522_register_config lpfilter_coef[] = {
+ {0x060b, {0x21, 0x0b} },
+ {0x060c, {0xad, 0xad} },
+ {0x060d, {0x70, 0xf0} },
+ {0x060e, {0xea, 0xe9} },
+ {0x060f, {0xdd, 0xdd} },
+ {0x0610, {0x08, 0x64} },
+ {0x0611, {0x60, 0x60} },
+ {0x0612, {0xf8, 0xb2} },
+ {0x0613, {0x01, 0x02} },
+ {0x0614, {0xe4, 0xb4} },
+ {0x0615, {0x19, 0x02} },
+ {0x0616, {0xae, 0x2e} },
+ {0x0617, {0xee, 0xc5} },
+ {0x0618, {0x56, 0x56} },
+ {0x0619, {0x30, 0x58} },
+ {0x061a, {0xf9, 0xf8} },
+ {0x061b, {0x24, 0x64} },
+ {0x061c, {0x07, 0x07} },
+ {0x061d, {0x30, 0x30} },
+ {0x061e, {0xa9, 0xed} },
+ {0x061f, {0x09, 0x0b} },
+ {0x0620, {0x42, 0xc2} },
+ {0x0621, {0x1d, 0x2a} },
+ {0x0622, {0xd6, 0x56} },
+ {0x0623, {0x95, 0x8b} },
+ {0x0624, {0x2b, 0x2b} },
+ {0x0625, {0x30, 0x24} },
+ {0x0626, {0x3e, 0x3e} },
+ {0x0627, {0x62, 0xe2} },
+ {0x0628, {0xe9, 0xf5} },
+ {0x0629, {0x99, 0x19} },
+ {0x062a, {0xd4, 0x11} },
+ {0x062b, {0x03, 0x04} },
+ {0x062c, {0xb5, 0x85} },
+ {0x062d, {0x1e, 0x20} },
+ {0x062e, {0x2a, 0xea} },
+ {0x062f, {0xd7, 0xd2} },
+ {0x0630, {0x15, 0x15} },
+ {0x0631, {0xa3, 0xa9} },
+ {0x0632, {0x1f, 0x1f} },
+ {0x0633, {0xf9, 0xd1} },
+ {0x0634, {0xc0, 0xc3} },
+ {0x0635, {0x4d, 0x8d} },
+ {0x0636, {0x21, 0x31} },
+ {0x0637, {0x83, 0x83} },
+ {0x0638, {0x08, 0x8c} },
+ {0x0639, {0x19, 0x19} },
+ {0x063a, {0x45, 0xa5} },
+ {0x063b, {0xef, 0xec} },
+ {0x063c, {0x8a, 0x8a} },
+ {0x063d, {0xf4, 0xf6} },
+ {0x063e, {0x8f, 0x8f} },
+ {0x063f, {0x44, 0x0c} },
+ {0x0640, {0xef, 0xf0} },
+ {0x0641, {0x66, 0x66} },
+ {0x0642, {0xcc, 0xd2} },
+ {0x0643, {0x41, 0x41} },
+ {0x0644, {0x63, 0x93} },
+ {0x0645, {0x8e, 0x8e} },
+ {0x0646, {0xa2, 0x42} },
+ {0x0647, {0x7b, 0x7b} },
+ {0x0648, {0x04, 0x04} },
+ {0x0649, {0x00, 0x00} },
+ {0x064a, {0x40, 0x40} },
+ {0x064b, {0x8c, 0x98} },
+ {0x064c, {0x00, 0x00} },
+ {0x064d, {0x63, 0xc3} },
+ {0x064e, {0x04, 0x04} },
+ {0x064f, {0x20, 0x20} },
+ {0x0650, {0x00, 0x00} },
+ {0x0651, {0x40, 0x40} },
+ {0x0652, {0x01, 0x01} },
+};
+#define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
+ / sizeof(struct au8522_register_config))
+
+static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct au8522_state, sd);
+}
+
+static void setup_vbi(struct au8522_state *state, int aud_input)
+{
+ int i;
+
+ /* These are set to zero regardless of what mode we're in */
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
+ 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
+ 0x00);
+ au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
+ 0x00);
+
+ /* Setup the VBI registers */
+ for (i = 0x30; i < 0x60; i++)
+ au8522_writereg(state, i, 0x40);
+
+ /* For some reason, every register is 0x40 except register 0x44
+ (confirmed via the HVR-950q USB capture) */
+ au8522_writereg(state, 0x44, 0x60);
+
+ /* Enable VBI (we always do this regardless of whether the user is
+ viewing closed caption info) */
+ au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
+ AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
+
+}
+
+static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
+{
+ int i;
+ int filter_coef_type;
+
+ /* Provide reasonable defaults for picture tuning values */
+ au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
+ au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
+ state->brightness = 0xed - 128;
+ au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
+ state->contrast = 0x79;
+ au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
+ au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
+ au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
+ au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
+
+ /* Other decoder registers */
+ au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
+
+ if (input_mode == 0x23) {
+ /* S-Video input mapping */
+ au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
+ } else {
+ /* All other modes (CVBS/ATVRF etc.) */
+ au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
+ }
+
+ au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
+ AU8522_TVDEC_PGA_REG012H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
+ AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
+ au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
+ AU8522_TVDED_DBG_MODE_REG060H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
+ AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
+ au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
+ AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
+ au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
+ AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
+ AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
+ AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
+ AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
+ AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
+ AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
+ AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
+ AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
+ AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
+ AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
+ AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
+ AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
+ AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
+ AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
+ au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
+ au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
+ AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
+ au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
+ au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
+ AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
+ AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
+ AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
+ AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
+ AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
+ au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
+ AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
+ au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
+ AU8522_TOREGAAGC_REG0E5H_CVBS);
+ au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
+
+ setup_vbi(state, 0);
+
+ if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
+ input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
+ /* Despite what the table says, for the HVR-950q we still need
+ to be in CVBS mode for the S-Video input (reason uknown). */
+ /* filter_coef_type = 3; */
+ filter_coef_type = 5;
+ } else {
+ filter_coef_type = 5;
+ }
+
+ /* Load the Video Decoder Filter Coefficients */
+ for (i = 0; i < NUM_FILTER_COEF; i++) {
+ au8522_writereg(state, filter_coef[i].reg_name,
+ filter_coef[i].reg_val[filter_coef_type]);
+ }
+
+ /* It's not clear what these registers are for, but they are always
+ set to the same value regardless of what mode we're in */
+ au8522_writereg(state, AU8522_REG42EH, 0x87);
+ au8522_writereg(state, AU8522_REG42FH, 0xa2);
+ au8522_writereg(state, AU8522_REG430H, 0xbf);
+ au8522_writereg(state, AU8522_REG431H, 0xcb);
+ au8522_writereg(state, AU8522_REG432H, 0xa1);
+ au8522_writereg(state, AU8522_REG433H, 0x41);
+ au8522_writereg(state, AU8522_REG434H, 0x88);
+ au8522_writereg(state, AU8522_REG435H, 0xc2);
+ au8522_writereg(state, AU8522_REG436H, 0x3c);
+}
+
+static void au8522_setup_cvbs_mode(struct au8522_state *state)
+{
+ /* here we're going to try the pre-programmed route */
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+ setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
+{
+ /* here we're going to try the pre-programmed route */
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
+
+ /* It's not clear why they turn off the PGA before enabling the clamp
+ control, but the Windows trace does it so we will too... */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
+
+ /* Enable clamping control */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
+
+ /* Turn on the PGA */
+ au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
+
+ /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+ setup_decoder_defaults(state,
+ AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+static void au8522_setup_svideo_mode(struct au8522_state *state)
+{
+ au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
+ AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
+
+ /* Set input to Y on Channe1, C on Channel 3 */
+ au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
+ AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+ /* Disable clamping control (required for S-video) */
+ au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
+
+ setup_decoder_defaults(state,
+ AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static void disable_audio_input(struct au8522_state *state)
+{
+ /* This can probably be optimized */
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+
+ au8522_writereg(state, AU8522_ENA_USB_REG101H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+ au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x40);
+
+ au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x11);
+ msleep(5);
+ au8522_writereg(state, AU8522_GPIO_DATA_REG0E2H, 0x00);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
+ au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+ au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
+
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+}
+
+/* 0=disable, 1=SIF */
+static void set_audio_input(struct au8522_state *state, int aud_input)
+{
+ int i;
+
+ /* Note that this function needs to be used in conjunction with setting
+ the input routing via register 0x81 */
+
+ if (aud_input == AU8522_AUDIO_NONE) {
+ disable_audio_input(state);
+ return;
+ }
+
+ if (aud_input != AU8522_AUDIO_SIF) {
+ /* The caller asked for a mode we don't currently support */
+ printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
+ aud_input);
+ return;
+ }
+
+ /* Load the Audio Decoder Filter Coefficients */
+ for (i = 0; i < NUM_LPFILTER_COEF; i++) {
+ au8522_writereg(state, lpfilter_coef[i].reg_name,
+ lpfilter_coef[i].reg_val[0]);
+ }
+
+ /* Setup audio */
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
+ au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
+ msleep(150);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
+ msleep(1);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
+ msleep(50);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
+ msleep(80);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
+ au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
+ au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
+ au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
+ msleep(70);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
+ au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
+ au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct au8522_state *state = to_state(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ state->brightness = ctrl->value;
+ au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
+ ctrl->value - 128);
+ break;
+ case V4L2_CID_CONTRAST:
+ state->contrast = ctrl->value;
+ au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
+ ctrl->value);
+ break;
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ /* Not yet implemented */
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct au8522_state *state = to_state(sd);
+
+ /* Note that we are using values cached in the state structure instead
+ of reading the registers due to issues with i2c reads not working
+ properly/consistently yet on the HVR-950q */
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = state->brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = state->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ case V4L2_CID_AUDIO_VOLUME:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_MUTE:
+ /* Not yet supported */
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ switch (fmt->type) {
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int au8522_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ switch (fmt->type) {
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Not yet implemented */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int au8522_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct au8522_state *state = to_state(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reg->val = au8522_readreg(state, reg->reg & 0xffff);
+ return 0;
+}
+
+static int au8522_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct au8522_state *state = to_state(sd);
+
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ au8522_writereg(state, reg->reg, reg->val & 0xff);
+ return 0;
+}
+#endif
+
+static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct au8522_state *state = to_state(sd);
+
+ if (enable) {
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ 0x01);
+ msleep(1);
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
+ } else {
+ /* This does not completely power down the device
+ (it only reduces it from around 140ma to 80ma) */
+ au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
+ 1 << 5);
+ }
+ return 0;
+}
+
+static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1,
+ AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_SATURATION:
+ case V4L2_CID_HUE:
+ /* Not yet implemented */
+ default:
+ break;
+ }
+
+ qc->type = 0;
+ return -EINVAL;
+}
+
+static int au8522_reset(struct v4l2_subdev *sd, u32 val)
+{
+ struct au8522_state *state = to_state(sd);
+
+ au8522_writereg(state, 0xa4, 1 << 5);
+
+ return 0;
+}
+
+static int au8522_s_video_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct au8522_state *state = to_state(sd);
+
+ au8522_reset(sd, 0);
+
+ /* Jam open the i2c gate to the tuner. We do this here to handle the
+ case where the user went into digital mode (causing the gate to be
+ closed), and then came back to analog mode */
+ au8522_writereg(state, 0x106, 1);
+
+ if (route->input == AU8522_COMPOSITE_CH1) {
+ au8522_setup_cvbs_mode(state);
+ } else if (route->input == AU8522_SVIDEO_CH13) {
+ au8522_setup_svideo_mode(state);
+ } else if (route->input == AU8522_COMPOSITE_CH4_SIF) {
+ au8522_setup_cvbs_tuner_mode(state);
+ } else {
+ printk(KERN_ERR "au8522 mode not currently supported\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int au8522_s_audio_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct au8522_state *state = to_state(sd);
+ set_audio_input(state, route->input);
+ return 0;
+}
+
+static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+ int val = 0;
+ struct au8522_state *state = to_state(sd);
+ u8 lock_status;
+
+ /* Interrogate the decoder to see if we are getting a real signal */
+ lock_status = au8522_readreg(state, 0x00);
+ if (lock_status == 0xa2)
+ vt->signal = 0x01;
+ else
+ vt->signal = 0x00;
+
+ vt->capability |=
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+ V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+ val = V4L2_TUNER_SUB_MONO;
+ vt->rxsubchans = val;
+ vt->audmode = V4L2_TUNER_MODE_STEREO;
+ return 0;
+}
+
+static int au8522_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct au8522_state *state = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
+}
+
+static int au8522_log_status(struct v4l2_subdev *sd)
+{
+ /* FIXME: Add some status info here */
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops au8522_core_ops = {
+ .log_status = au8522_log_status,
+ .g_chip_ident = au8522_g_chip_ident,
+ .g_ctrl = au8522_g_ctrl,
+ .s_ctrl = au8522_s_ctrl,
+ .queryctrl = au8522_queryctrl,
+ .reset = au8522_reset,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = au8522_g_register,
+ .s_register = au8522_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
+ .g_tuner = au8522_g_tuner,
+};
+
+static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
+ .s_routing = au8522_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops au8522_video_ops = {
+ .s_routing = au8522_s_video_routing,
+ .g_fmt = au8522_g_fmt,
+ .s_fmt = au8522_s_fmt,
+ .s_stream = au8522_s_stream,
+};
+
+static const struct v4l2_subdev_ops au8522_ops = {
+ .core = &au8522_core_ops,
+ .tuner = &au8522_tuner_ops,
+ .audio = &au8522_audio_ops,
+ .video = &au8522_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int au8522_probe(struct i2c_client *client,
+ const struct i2c_device_id *did)
+{
+ struct au8522_state *state;
+ struct v4l2_subdev *sd;
+ int instance;
+ struct au8522_config *demod_config;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
+ return -EIO;
+ }
+
+ /* allocate memory for the internal state */
+ instance = au8522_get_state(&state, client->adapter, client->addr);
+ switch (instance) {
+ case 0:
+ printk(KERN_ERR "au8522_decoder allocation failed\n");
+ return -EIO;
+ case 1:
+ /* new demod instance */
+ printk(KERN_INFO "au8522_decoder creating new instance...\n");
+ break;
+ default:
+ /* existing demod instance */
+ printk(KERN_INFO "au8522_decoder attach existing instance.\n");
+ break;
+ }
+
+ demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
+ demod_config->demod_address = 0x8e >> 1;
+
+ state->config = demod_config;
+ state->i2c = client->adapter;
+
+ sd = &state->sd;
+ v4l2_i2c_subdev_init(sd, client, &au8522_ops);
+
+ state->c = client;
+ state->vid_input = AU8522_COMPOSITE_CH1;
+ state->aud_input = AU8522_AUDIO_NONE;
+ state->id = 8522;
+ state->rev = 0;
+
+ /* Jam open the i2c gate to the tuner */
+ au8522_writereg(state, 0x106, 1);
+
+ return 0;
+}
+
+static int au8522_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ v4l2_device_unregister_subdev(sd);
+ au8522_release_state(to_state(sd));
+ return 0;
+}
+
+static const struct i2c_device_id au8522_id[] = {
+ {"au8522", 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, au8522_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "au8522",
+ .probe = au8522_probe,
+ .remove = au8522_remove,
+ .id_table = au8522_id,
+};
diff --git a/drivers/media/dvb/frontends/au8522.c b/drivers/media/dvb/frontends/au8522_dig.c
index eabf9a68e7e..35731258bb0 100644
--- a/drivers/media/dvb/frontends/au8522.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -27,35 +27,25 @@
#include <linux/delay.h>
#include "dvb_frontend.h"
#include "au8522.h"
-
-struct au8522_state {
-
- struct i2c_adapter *i2c;
-
- /* configuration settings */
- const struct au8522_config *config;
-
- struct dvb_frontend frontend;
-
- u32 current_frequency;
- fe_modulation_t current_modulation;
-
- u32 fe_status;
- unsigned int led_state;
-};
+#include "au8522_priv.h"
static int debug;
-#define dprintk(arg...) do { \
- if (debug) \
- printk(arg); \
+/* Despite the name "hybrid_tuner", the framework works just as well for
+ hybrid demodulators as well... */
+static LIST_HEAD(hybrid_tuner_instance_list);
+static DEFINE_MUTEX(au8522_list_mutex);
+
+#define dprintk(arg...)\
+ do { if (debug)\
+ printk(arg);\
} while (0)
/* 16 bit registers, 8 bit values */
-static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
{
int ret;
- u8 buf [] = { reg >> 8, reg & 0xff, data };
+ u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data };
struct i2c_msg msg = { .addr = state->config->demod_address,
.flags = 0, .buf = buf, .len = 3 };
@@ -69,13 +59,13 @@ static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
return (ret != 1) ? -1 : 0;
}
-static u8 au8522_readreg(struct au8522_state *state, u16 reg)
+u8 au8522_readreg(struct au8522_state *state, u16 reg)
{
int ret;
- u8 b0 [] = { reg >> 8, reg & 0xff };
- u8 b1 [] = { 0 };
+ u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff };
+ u8 b1[] = { 0 };
- struct i2c_msg msg [] = {
+ struct i2c_msg msg[] = {
{ .addr = state->config->demod_address, .flags = 0,
.buf = b0, .len = 2 },
{ .addr = state->config->demod_address, .flags = I2C_M_RD,
@@ -528,7 +518,7 @@ static int au8522_set_frontend(struct dvb_frontend *fe,
/* Reset the demod hardware and reset all of the configuration registers
to a default state. */
-static int au8522_init(struct dvb_frontend *fe)
+int au8522_init(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -624,7 +614,7 @@ static int au8522_led_ctrl(struct au8522_state *state, int led)
return 0;
}
-static int au8522_sleep(struct dvb_frontend *fe)
+int au8522_sleep(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
dprintk("%s()\n", __func__);
@@ -632,6 +622,9 @@ static int au8522_sleep(struct dvb_frontend *fe)
/* turn off led */
au8522_led_ctrl(state, 0);
+ /* Power down the chip */
+ au8522_writereg(state, 0xa4, 1 << 5);
+
state->current_frequency = 0;
return 0;
@@ -798,23 +791,58 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
return 0;
}
+static struct dvb_frontend_ops au8522_ops;
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+ u8 client_address)
+{
+ int ret;
+
+ mutex_lock(&au8522_list_mutex);
+ ret = hybrid_tuner_request_state(struct au8522_state, (*state),
+ hybrid_tuner_instance_list,
+ i2c, client_address, "au8522");
+ mutex_unlock(&au8522_list_mutex);
+
+ return ret;
+}
+
+void au8522_release_state(struct au8522_state *state)
+{
+ mutex_lock(&au8522_list_mutex);
+ if (state != NULL)
+ hybrid_tuner_release_state(state);
+ mutex_unlock(&au8522_list_mutex);
+}
+
+
static void au8522_release(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
- kfree(state);
+ au8522_release_state(state);
}
-static struct dvb_frontend_ops au8522_ops;
-
struct dvb_frontend *au8522_attach(const struct au8522_config *config,
struct i2c_adapter *i2c)
{
struct au8522_state *state = NULL;
+ int instance;
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ instance = au8522_get_state(&state, i2c, config->demod_address);
+ switch (instance) {
+ case 0:
+ dprintk("%s state allocation failed\n", __func__);
+ break;
+ case 1:
+ /* new demod instance */
+ dprintk("%s using new instance\n", __func__);
+ break;
+ default:
+ /* existing demod instance */
+ dprintk("%s using existing instance\n", __func__);
+ break;
+ }
/* setup the state */
state->config = config;
@@ -836,7 +864,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
return &state->frontend;
error:
- kfree(state);
+ au8522_release_state(state);
return NULL;
}
EXPORT_SYMBOL(au8522_attach);
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
new file mode 100644
index 00000000000..f328f2b3ad3
--- /dev/null
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -0,0 +1,412 @@
+/*
+ Auvitek AU8522 QAM/8VSB demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
+ Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org>
+ Copyright (C) 2005-2008 Auvitek International, 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 program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+#include "tuner-i2c.h"
+
+struct au8522_state {
+ struct i2c_client *c;
+ struct i2c_adapter *i2c;
+
+ /* Used for sharing of the state between analog and digital mode */
+ struct tuner_i2c_props i2c_props;
+ struct list_head hybrid_tuner_instance_list;
+
+ /* configuration settings */
+ const struct au8522_config *config;
+
+ struct dvb_frontend frontend;
+
+ u32 current_frequency;
+ fe_modulation_t current_modulation;
+
+ u32 fe_status;
+ unsigned int led_state;
+
+ /* Analog settings */
+ struct v4l2_subdev sd;
+ v4l2_std_id std;
+ int vid_input;
+ int aud_input;
+ u32 id;
+ u32 rev;
+ u8 brightness;
+ u8 contrast;
+};
+
+/* These are routines shared by both the VSB/QAM demodulator and the analog
+ decoder */
+int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
+u8 au8522_readreg(struct au8522_state *state, u16 reg);
+int au8522_init(struct dvb_frontend *fe);
+int au8522_sleep(struct dvb_frontend *fe);
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+ u8 client_address);
+void au8522_release_state(struct au8522_state *state);
+
+/* REGISTERS */
+#define AU8522_INPUT_CONTROL_REG081H 0x081
+#define AU8522_PGA_CONTROL_REG082H 0x082
+#define AU8522_CLAMPING_CONTROL_REG083H 0x083
+
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H 0x0A3
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H 0x0A4
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H 0x0A5
+#define AU8522_AGC_CONTROL_RANGE_REG0A6H 0x0A6
+#define AU8522_SYSTEM_GAIN_CONTROL_REG0A7H 0x0A7
+#define AU8522_TUNER_AGC_RF_STOP_REG0A8H 0x0A8
+#define AU8522_TUNER_AGC_RF_START_REG0A9H 0x0A9
+#define AU8522_TUNER_RF_AGC_DEFAULT_REG0AAH 0x0AA
+#define AU8522_TUNER_AGC_IF_STOP_REG0ABH 0x0AB
+#define AU8522_TUNER_AGC_IF_START_REG0ACH 0x0AC
+#define AU8522_TUNER_AGC_IF_DEFAULT_REG0ADH 0x0AD
+#define AU8522_TUNER_AGC_STEP_REG0AEH 0x0AE
+#define AU8522_TUNER_GAIN_STEP_REG0AFH 0x0AF
+
+/* Receiver registers */
+#define AU8522_FRMREGTHRD1_REG0B0H 0x0B0
+#define AU8522_FRMREGAGC1H_REG0B1H 0x0B1
+#define AU8522_FRMREGSHIFT1_REG0B2H 0x0B2
+#define AU8522_TOREGAGC1_REG0B3H 0x0B3
+#define AU8522_TOREGASHIFT1_REG0B4H 0x0B4
+#define AU8522_FRMREGBBH_REG0B5H 0x0B5
+#define AU8522_FRMREGBBM_REG0B6H 0x0B6
+#define AU8522_FRMREGBBL_REG0B7H 0x0B7
+/* 0xB8 TO 0xD7 are the filter coefficients */
+#define AU8522_FRMREGTHRD2_REG0D8H 0x0D8
+#define AU8522_FRMREGAGC2H_REG0D9H 0x0D9
+#define AU8522_TOREGAGC2_REG0DAH 0x0DA
+#define AU8522_TOREGSHIFT2_REG0DBH 0x0DB
+#define AU8522_FRMREGPILOTH_REG0DCH 0x0DC
+#define AU8522_FRMREGPILOTM_REG0DDH 0x0DD
+#define AU8522_FRMREGPILOTL_REG0DEH 0x0DE
+#define AU8522_TOREGFREQ_REG0DFH 0x0DF
+
+#define AU8522_RX_PGA_RFOUT_REG0EBH 0x0EB
+#define AU8522_RX_PGA_IFOUT_REG0ECH 0x0EC
+#define AU8522_RX_PGA_PGAOUT_REG0EDH 0x0ED
+
+#define AU8522_CHIP_MODE_REG0FEH 0x0FE
+
+/* I2C bus control registers */
+#define AU8522_I2C_CONTROL_REG0_REG090H 0x090
+#define AU8522_I2C_CONTROL_REG1_REG091H 0x091
+#define AU8522_I2C_STATUS_REG092H 0x092
+#define AU8522_I2C_WR_DATA0_REG093H 0x093
+#define AU8522_I2C_WR_DATA1_REG094H 0x094
+#define AU8522_I2C_WR_DATA2_REG095H 0x095
+#define AU8522_I2C_WR_DATA3_REG096H 0x096
+#define AU8522_I2C_WR_DATA4_REG097H 0x097
+#define AU8522_I2C_WR_DATA5_REG098H 0x098
+#define AU8522_I2C_WR_DATA6_REG099H 0x099
+#define AU8522_I2C_WR_DATA7_REG09AH 0x09A
+#define AU8522_I2C_RD_DATA0_REG09BH 0x09B
+#define AU8522_I2C_RD_DATA1_REG09CH 0x09C
+#define AU8522_I2C_RD_DATA2_REG09DH 0x09D
+#define AU8522_I2C_RD_DATA3_REG09EH 0x09E
+#define AU8522_I2C_RD_DATA4_REG09FH 0x09F
+#define AU8522_I2C_RD_DATA5_REG0A0H 0x0A0
+#define AU8522_I2C_RD_DATA6_REG0A1H 0x0A1
+#define AU8522_I2C_RD_DATA7_REG0A2H 0x0A2
+
+#define AU8522_ENA_USB_REG101H 0x101
+
+#define AU8522_I2S_CTRL_0_REG110H 0x110
+#define AU8522_I2S_CTRL_1_REG111H 0x111
+#define AU8522_I2S_CTRL_2_REG112H 0x112
+
+#define AU8522_FRMREGFFECONTROL_REG121H 0x121
+#define AU8522_FRMREGDFECONTROL_REG122H 0x122
+
+#define AU8522_CARRFREQOFFSET0_REG201H 0x201
+#define AU8522_CARRFREQOFFSET1_REG202H 0x202
+
+#define AU8522_DECIMATION_GAIN_REG21AH 0x21A
+#define AU8522_FRMREGIFSLP_REG21BH 0x21B
+#define AU8522_FRMREGTHRDL2_REG21CH 0x21C
+#define AU8522_FRMREGSTEP3DB_REG21DH 0x21D
+#define AU8522_DAGC_GAIN_ADJUSTMENT_REG21EH 0x21E
+#define AU8522_FRMREGPLLMODE_REG21FH 0x21F
+#define AU8522_FRMREGCSTHRD_REG220H 0x220
+#define AU8522_FRMREGCRLOCKDMAX_REG221H 0x221
+#define AU8522_FRMREGCRPERIODMASK_REG222H 0x222
+#define AU8522_FRMREGCRLOCK0THH_REG223H 0x223
+#define AU8522_FRMREGCRLOCK1THH_REG224H 0x224
+#define AU8522_FRMREGCRLOCK0THL_REG225H 0x225
+#define AU8522_FRMREGCRLOCK1THL_REG226H 0x226
+#define AU_FRMREGPLLACQPHASESCL_REG227H 0x227
+#define AU8522_FRMREGFREQFBCTRL_REG228H 0x228
+
+/* Analog TV Decoder */
+#define AU8522_TVDEC_STATUS_REG000H 0x000
+#define AU8522_TVDEC_INT_STATUS_REG001H 0x001
+#define AU8522_TVDEC_MACROVISION_STATUS_REG002H 0x002
+#define AU8522_TVDEC_SHARPNESSREG009H 0x009
+#define AU8522_TVDEC_BRIGHTNESS_REG00AH 0x00A
+#define AU8522_TVDEC_CONTRAST_REG00BH 0x00B
+#define AU8522_TVDEC_SATURATION_CB_REG00CH 0x00C
+#define AU8522_TVDEC_SATURATION_CR_REG00DH 0x00D
+#define AU8522_TVDEC_HUE_H_REG00EH 0x00E
+#define AU8522_TVDEC_HUE_L_REG00FH 0x00F
+#define AU8522_TVDEC_INT_MASK_REG010H 0x010
+#define AU8522_VIDEO_MODE_REG011H 0x011
+#define AU8522_TVDEC_PGA_REG012H 0x012
+#define AU8522_TVDEC_COMB_MODE_REG015H 0x015
+#define AU8522_REG016H 0x016
+#define AU8522_TVDED_DBG_MODE_REG060H 0x060
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H 0x061
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H 0x062
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H 0x063
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H 0x064
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H 0x065
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H 0x066
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H 0x067
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H 0x068
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H 0x069
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH 0x06A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH 0x06B
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH 0x06C
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH 0x06D
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH 0x06E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH 0x06F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H 0x070
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H 0x073
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H 0x077
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H 0x078
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H 0x079
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH 0x07A
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH 0x07B
+#define AU8522_TVDEC_PLL_STATUS_REG07EH 0x07E
+#define AU8522_TVDEC_FSC_FREQ_REG07FH 0x07F
+
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H 0x0E4
+#define AU8522_TOREGAAGC_REG0E5H 0x0E5
+
+#define AU8522_TVDEC_CHROMA_AGC_REG401H 0x401
+#define AU8522_TVDEC_CHROMA_SFT_REG402H 0x402
+#define AU8522_FILTER_COEF_R410 0x410
+#define AU8522_FILTER_COEF_R411 0x411
+#define AU8522_FILTER_COEF_R412 0x412
+#define AU8522_FILTER_COEF_R413 0x413
+#define AU8522_FILTER_COEF_R414 0x414
+#define AU8522_FILTER_COEF_R415 0x415
+#define AU8522_FILTER_COEF_R416 0x416
+#define AU8522_FILTER_COEF_R417 0x417
+#define AU8522_FILTER_COEF_R418 0x418
+#define AU8522_FILTER_COEF_R419 0x419
+#define AU8522_FILTER_COEF_R41A 0x41A
+#define AU8522_FILTER_COEF_R41B 0x41B
+#define AU8522_FILTER_COEF_R41C 0x41C
+#define AU8522_FILTER_COEF_R41D 0x41D
+#define AU8522_FILTER_COEF_R41E 0x41E
+#define AU8522_FILTER_COEF_R41F 0x41F
+#define AU8522_FILTER_COEF_R420 0x420
+#define AU8522_FILTER_COEF_R421 0x421
+#define AU8522_FILTER_COEF_R422 0x422
+#define AU8522_FILTER_COEF_R423 0x423
+#define AU8522_FILTER_COEF_R424 0x424
+#define AU8522_FILTER_COEF_R425 0x425
+#define AU8522_FILTER_COEF_R426 0x426
+#define AU8522_FILTER_COEF_R427 0x427
+#define AU8522_FILTER_COEF_R428 0x428
+#define AU8522_FILTER_COEF_R429 0x429
+#define AU8522_FILTER_COEF_R42A 0x42A
+#define AU8522_FILTER_COEF_R42B 0x42B
+#define AU8522_FILTER_COEF_R42C 0x42C
+#define AU8522_FILTER_COEF_R42D 0x42D
+
+/* VBI Control Registers */
+#define AU8522_TVDEC_VBI_RX_FIFO_CONTAIN_REG004H 0x004
+#define AU8522_TVDEC_VBI_TX_FIFO_CONTAIN_REG005H 0x005
+#define AU8522_TVDEC_VBI_RX_FIFO_READ_REG006H 0x006
+#define AU8522_TVDEC_VBI_FIFO_STATUS_REG007H 0x007
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H 0x017
+#define AU8522_TVDEC_VBI_CTRL_L_REG018H 0x018
+#define AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H 0x019
+#define AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH 0x01A
+#define AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH 0x01B
+#define AU8522_TVDEC_VBI_USER_THRESH1_REG01CH 0x01C
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH 0x01E
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH 0x01F
+#define AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H 0x020
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H 0x021
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H 0x022
+#define AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H 0x023
+
+#define AU8522_REG071H 0x071
+#define AU8522_REG072H 0x072
+#define AU8522_REG074H 0x074
+#define AU8522_REG075H 0x075
+
+/* Digital Demodulator Registers */
+#define AU8522_FRAME_COUNT0_REG084H 0x084
+#define AU8522_RS_STATUS_G0_REG085H 0x085
+#define AU8522_RS_STATUS_B0_REG086H 0x086
+#define AU8522_RS_STATUS_E_REG087H 0x087
+#define AU8522_DEMODULATION_STATUS_REG088H 0x088
+#define AU8522_TOREGTRESTATUS_REG0E6H 0x0E6
+#define AU8522_TSPORT_CONTROL_REG10BH 0x10B
+#define AU8522_TSTHES_REG10CH 0x10C
+#define AU8522_FRMREGDFEKEEP_REG301H 0x301
+#define AU8522_DFE_AVERAGE_REG302H 0x302
+#define AU8522_FRMREGEQLERRWIN_REG303H 0x303
+#define AU8522_FRMREGFFEKEEP_REG304H 0x304
+#define AU8522_FRMREGDFECONTROL1_REG305H 0x305
+#define AU8522_FRMREGEQLERRLOW_REG306H 0x306
+
+#define AU8522_REG42EH 0x42E
+#define AU8522_REG42FH 0x42F
+#define AU8522_REG430H 0x430
+#define AU8522_REG431H 0x431
+#define AU8522_REG432H 0x432
+#define AU8522_REG433H 0x433
+#define AU8522_REG434H 0x434
+#define AU8522_REG435H 0x435
+#define AU8522_REG436H 0x436
+
+/* GPIO Registers */
+#define AU8522_GPIO_CONTROL_REG0E0H 0x0E0
+#define AU8522_GPIO_STATUS_REG0E1H 0x0E1
+#define AU8522_GPIO_DATA_REG0E2H 0x0E2
+
+/* Audio Control Registers */
+#define AU8522_AUDIOAGC_REG0EEH 0x0EE
+#define AU8522_AUDIO_STATUS_REG0F0H 0x0F0
+#define AU8522_AUDIO_MODE_REG0F1H 0x0F1
+#define AU8522_AUDIO_VOLUME_L_REG0F2H 0x0F2
+#define AU8522_AUDIO_VOLUME_R_REG0F3H 0x0F3
+#define AU8522_AUDIO_VOLUME_REG0F4H 0x0F4
+#define AU8522_FRMREGAUPHASE_REG0F7H 0x0F7
+#define AU8522_REG0F9H 0x0F9
+
+#define AU8522_AUDIOAGC2_REG605H 0x605
+#define AU8522_AUDIOFREQ_REG606H 0x606
+
+
+/**************************************************************/
+
+#define AU8522_INPUT_CONTROL_REG081H_ATSC 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_ATVRF13 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B64 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_J83B256 0xC4
+#define AU8522_INPUT_CONTROL_REG081H_CVBS 0x20
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH1 0xA2
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH2 0xA0
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH3 0x69
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4 0x68
+#define AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF 0x28
+/* CH1 AS Y,CH3 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 0x23
+/* CH2 AS Y,CH4 AS C */
+#define AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24 0x20
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATSC 0x0C
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B64 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_J83B256 0x09
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS 0x12
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF 0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_ATVRF13 0x1A
+#define AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO 0x02
+
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CLEAR 0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO 0x9C
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS 0x9D
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATSC 0xE8
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B256 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_J83B64 0xCA
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_ATVRF13 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_PAL 0xDD
+#define AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_FM 0xDD
+
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATSC 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B256 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_J83B64 0x80
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_ATSC 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B256 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_J83B64 0x40
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_DONGLE_CLEAR 0x00
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_ATVRF13 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_SVIDEO 0x04
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_CVBS 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PWM 0x03
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_IIS 0x09
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_PAL 0x01
+#define AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H_FM 0x01
+
+/* STILL NEED TO BE REFACTORED @@@@@@@@@@@@@@ */
+#define AU8522_TVDEC_CONTRAST_REG00BH_CVBS 0x79
+#define AU8522_TVDEC_SATURATION_CB_REG00CH_CVBS 0x80
+#define AU8522_TVDEC_SATURATION_CR_REG00DH_CVBS 0x80
+#define AU8522_TVDEC_HUE_H_REG00EH_CVBS 0x00
+#define AU8522_TVDEC_HUE_L_REG00FH_CVBS 0x00
+#define AU8522_TVDEC_PGA_REG012H_CVBS 0x0F
+#define AU8522_TVDEC_COMB_MODE_REG015H_CVBS 0x00
+#define AU8522_REG016H_CVBS 0x00
+#define AU8522_TVDED_DBG_MODE_REG060H_CVBS 0x00
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS 0x0B
+#define AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13 0x03
+#define AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13 0x00
+#define AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS 0x19
+#define AU8522_REG0F9H_AUDIO 0x20
+#define AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS 0xA7
+#define AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS 0x0A
+#define AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS 0x32
+#define AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS 0x19
+#define AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS 0x23
+#define AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS 0x41
+#define AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS 0x0A
+#define AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS 0x32
+#define AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS 0x34
+#define AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS 0x05
+#define AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS 0x6E
+#define AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS 0x0F
+#define AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS 0x80
+#define AU8522_REG071H_CVBS 0x18
+#define AU8522_REG072H_CVBS 0x30
+#define AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS 0xF0
+#define AU8522_REG074H_CVBS 0x80
+#define AU8522_REG075H_CVBS 0xF0
+#define AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS 0xFB
+#define AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS 0x04
+#define AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS 0x00
+#define AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS 0x00
+#define AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS 0xEE
+#define AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS 0xFE
+#define AU8522_TOREGAAGC_REG0E5H_CVBS 0x00
+#define AU8522_TVDEC_VBI6A_REG035H_CVBS 0x40
+
+/* Enables Closed captioning */
+#define AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON 0x21
diff --git a/drivers/media/dvb/frontends/cx24113.c b/drivers/media/dvb/frontends/cx24113.c
index f6e7b0380a5..e4fd533a427 100644
--- a/drivers/media/dvb/frontends/cx24113.c
+++ b/drivers/media/dvb/frontends/cx24113.c
@@ -559,7 +559,7 @@ struct dvb_frontend *cx24113_attach(struct dvb_frontend *fe,
kzalloc(sizeof(struct cx24113_state), GFP_KERNEL);
int rc;
if (state == NULL) {
- err("Unable to kmalloc\n");
+ err("Unable to kzalloc\n");
goto error;
}
diff --git a/drivers/media/dvb/frontends/cx24116.c b/drivers/media/dvb/frontends/cx24116.c
index 28ad609e73f..9b9f57264ce 100644
--- a/drivers/media/dvb/frontends/cx24116.c
+++ b/drivers/media/dvb/frontends/cx24116.c
@@ -15,6 +15,9 @@
September, 9th 2008
Fixed locking on high symbol rates (>30000).
Implement MPEG initialization parameter.
+ January, 17th 2009
+ Fill set_voltage with actually control voltage code.
+ Correct set tone to not affect voltage.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -146,7 +149,7 @@ enum cmds {
CMD_GETAGC = 0x19,
CMD_LNBCONFIG = 0x20,
CMD_LNBSEND = 0x21, /* Formerly CMD_SEND_DISEQC */
- CMD_SET_TONEPRE = 0x22,
+ CMD_LNBDCLEVEL = 0x22,
CMD_SET_TONE = 0x23,
CMD_UPDFWVERS = 0x35,
CMD_TUNERSLEEP = 0x36,
@@ -667,16 +670,6 @@ static int cx24116_load_firmware(struct dvb_frontend *fe,
return 0;
}
-static int cx24116_set_voltage(struct dvb_frontend *fe,
- fe_sec_voltage_t voltage)
-{
- /* The isl6421 module will override this function in the fops. */
- dprintk("%s() This should never appear if the isl6421 module "
- "is loaded correctly\n", __func__);
-
- return -EOPNOTSUPP;
-}
-
static int cx24116_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
struct cx24116_state *state = fe->demodulator_priv;
@@ -837,6 +830,34 @@ static int cx24116_wait_for_lnb(struct dvb_frontend *fe)
return -ETIMEDOUT; /* -EBUSY ? */
}
+static int cx24116_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
+{
+ struct cx24116_cmd cmd;
+ int ret;
+
+ dprintk("%s: %s\n", __func__,
+ voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
+ voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
+
+ /* Wait for LNB ready */
+ ret = cx24116_wait_for_lnb(fe);
+ if (ret != 0)
+ return ret;
+
+ /* Wait for voltage/min repeat delay */
+ msleep(100);
+
+ cmd.args[0x00] = CMD_LNBDCLEVEL;
+ cmd.args[0x01] = (voltage == SEC_VOLTAGE_18 ? 0x01 : 0x00);
+ cmd.len = 0x02;
+
+ /* Min delay time before DiSEqC send */
+ msleep(15);
+
+ return cx24116_cmd_execute(fe, &cmd);
+}
+
static int cx24116_set_tone(struct dvb_frontend *fe,
fe_sec_tone_mode_t tone)
{
@@ -857,14 +878,6 @@ static int cx24116_set_tone(struct dvb_frontend *fe,
/* Min delay time after DiSEqC send */
msleep(15); /* XXX determine is FW does this, see send_diseqc/burst */
- /* This is always done before the tone is set */
- cmd.args[0x00] = CMD_SET_TONEPRE;
- cmd.args[0x01] = 0x00;
- cmd.len = 0x02;
- ret = cx24116_cmd_execute(fe, &cmd);
- if (ret != 0)
- return ret;
-
/* Now we set the tone */
cmd.args[0x00] = CMD_SET_TONE;
cmd.args[0x01] = 0x00;
@@ -1099,13 +1112,10 @@ struct dvb_frontend *cx24116_attach(const struct cx24116_config *config,
dprintk("%s\n", __func__);
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct cx24116_state), GFP_KERNEL);
+ state = kzalloc(sizeof(struct cx24116_state), GFP_KERNEL);
if (state == NULL)
goto error1;
- /* setup the state */
- memset(state, 0, sizeof(struct cx24116_state));
-
state->config = config;
state->i2c = i2c;
@@ -1154,7 +1164,12 @@ static int cx24116_initfe(struct dvb_frontend *fe)
if (ret != 0)
return ret;
- return cx24116_diseqc_init(fe);
+ ret = cx24116_diseqc_init(fe);
+ if (ret != 0)
+ return ret;
+
+ /* HVR-4000 needs this */
+ return cx24116_set_voltage(fe, SEC_VOLTAGE_13);
}
/*
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 1a8c36f7606..0592f043ea6 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -1069,13 +1069,13 @@ static struct dvb_frontend_ops cx24123_ops;
struct dvb_frontend *cx24123_attach(const struct cx24123_config *config,
struct i2c_adapter *i2c)
{
+ /* allocate memory for the internal state */
struct cx24123_state *state =
kzalloc(sizeof(struct cx24123_state), GFP_KERNEL);
dprintk("\n");
- /* allocate memory for the internal state */
if (state == NULL) {
- err("Unable to kmalloc\n");
+ err("Unable to kzalloc\n");
goto error;
}
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 21f2c5161af..9670f5d20cf 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -58,6 +58,4 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
}
#endif
-extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
-
#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
index 4142ed7a47d..d75ffad2d75 100644
--- a/drivers/media/dvb/frontends/dib3000mc.h
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -39,19 +39,43 @@ struct dib3000mc_config {
#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
#define DEFAULT_DIB3000P_I2C_ADDRESS 24
-#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && defined(MODULE))
-extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg);
+#if defined(CONFIG_DVB_DIB3000MC) || (defined(CONFIG_DVB_DIB3000MC_MODULE) && \
+ defined(MODULE))
+extern struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr,
+ struct dib3000mc_config *cfg);
+extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+ int no_of_demods, u8 default_addr,
+ struct dib3000mc_config cfg[]);
+extern
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+ int gating);
#else
-static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
+static inline
+struct dvb_frontend *dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
+ struct dib3000mc_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_DIB3000MC
-extern int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]);
+static inline
+int dib3000mc_i2c_enumeration(struct i2c_adapter *i2c,
+ int no_of_demods, u8 default_addr,
+ struct dib3000mc_config cfg[])
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
-extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
+static inline
+struct i2c_adapter *dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod,
+ int gating)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif // CONFIG_DVB_DIB3000MC
extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
diff --git a/drivers/media/dvb/frontends/dib7000m.h b/drivers/media/dvb/frontends/dib7000m.h
index 597e9cc2da6..113819ce9f0 100644
--- a/drivers/media/dvb/frontends/dib7000m.h
+++ b/drivers/media/dvb/frontends/dib7000m.h
@@ -38,8 +38,32 @@ struct dib7000m_config {
#define DEFAULT_DIB7000M_I2C_ADDRESS 18
-extern struct dvb_frontend * dib7000m_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000m_config *cfg);
-extern struct i2c_adapter * dib7000m_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
+#if defined(CONFIG_DVB_DIB7000M) || (defined(CONFIG_DVB_DIB7000M_MODULE) && \
+ defined(MODULE))
+extern struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr,
+ struct dib7000m_config *cfg);
+extern struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *,
+ enum dibx000_i2c_interface,
+ int);
+#else
+static inline
+struct dvb_frontend *dib7000m_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr, struct dib7000m_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+static inline
+struct i2c_adapter *dib7000m_get_i2c_master(struct dvb_frontend *demod,
+ enum dibx000_i2c_interface intf,
+ int gating)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
/* TODO
extern INT dib7000m_set_gpio(struct dibDemod *demod, UCHAR num, UCHAR dir, UCHAR val);
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index aab8112e2db..02a4c82f0c7 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -37,7 +37,8 @@ struct dib7000p_config {
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
-#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE))
+#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
+ defined(MODULE))
extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
u8 i2c_addr,
struct dib7000p_config *cfg);
@@ -49,10 +50,11 @@ extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
struct dib7000p_config cfg[]);
extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
+extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
#else
-static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
- u8 i2c_addr,
- struct dib7000p_config *cfg)
+static inline
+struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
+ struct dib7000p_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
@@ -60,36 +62,39 @@ static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
static inline
struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
- enum dibx000_i2c_interface i, int x)
+ enum dibx000_i2c_interface i,
+ int x)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-static inline
-int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
- int no_of_demods, u8 default_addr,
- struct dib7000p_config cfg[])
+static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
+ int no_of_demods, u8 default_addr,
+ struct dib7000p_config cfg[])
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline
-int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
+static inline int dib7000p_set_gpio(struct dvb_frontend *fe,
+ u8 num, u8 dir, u8 val)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-static inline
-int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
+static inline int dib7000p_set_wbd_ref(struct dvb_frontend *fe, u16 value)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return -ENODEV;
}
-#endif
-extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
+static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return -ENODEV;
+}
+#endif
#endif
diff --git a/drivers/media/dvb/frontends/drx397xD.c b/drivers/media/dvb/frontends/drx397xD.c
index 1e81e713df6..172f1f928f0 100644
--- a/drivers/media/dvb/frontends/drx397xD.c
+++ b/drivers/media/dvb/frontends/drx397xD.c
@@ -74,7 +74,7 @@ static struct {
} fw[] = {
#define _FW_ENTRY(a, b, c) { \
.name = a, \
- .file = 0, \
+ .file = NULL, \
.lock = __RW_LOCK_UNLOCKED(fw[c].lock), \
.refcnt = 0, \
.data = { } }
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.h b/drivers/media/dvb/frontends/dvb_dummy_fe.h
index 8210f19d56c..1fcb987d638 100644
--- a/drivers/media/dvb/frontends/dvb_dummy_fe.h
+++ b/drivers/media/dvb/frontends/dvb_dummy_fe.h
@@ -25,8 +25,27 @@
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"
+#if defined(CONFIG_DVB_DUMMY_FE) || (defined(CONFIG_DVB_DUMMY_FE_MODULE) && \
+defined(MODULE))
extern struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qpsk_attach(void);
extern struct dvb_frontend* dvb_dummy_fe_qam_attach(void);
+#else
+static inline struct dvb_frontend *dvb_dummy_fe_ofdm_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qpsk_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+static inline struct dvb_frontend *dvb_dummy_fe_qam_attach(void)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_DUMMY_FE */
#endif // DVB_DUMMY_FE_H
diff --git a/drivers/media/dvb/frontends/itd1000_priv.h b/drivers/media/dvb/frontends/itd1000_priv.h
index 8cdc54e5790..08ca851223c 100644
--- a/drivers/media/dvb/frontends/itd1000_priv.h
+++ b/drivers/media/dvb/frontends/itd1000_priv.h
@@ -31,7 +31,7 @@ struct itd1000_state {
/* ugly workaround for flexcop's incapable i2c-controller
* FIXME, if possible
*/
- u8 shadow[255];
+ u8 shadow[256];
};
enum itd1000_register {
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
index 3bb0c4394f8..eb72a9866c9 100644
--- a/drivers/media/dvb/frontends/lgdt3304.c
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -363,7 +363,6 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
struct lgdt3304_state *state;
state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
- memset(state, 0x0, sizeof(struct lgdt3304_state));
state->addr = config->i2c_address;
state->i2c = i2c;
diff --git a/drivers/media/dvb/frontends/lgdt3305.c b/drivers/media/dvb/frontends/lgdt3305.c
new file mode 100644
index 00000000000..d92d0557a80
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.c
@@ -0,0 +1,1087 @@
+/*
+ * Support for LGDT3305 - VSB/QAM
+ *
+ * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <linux/dvb/frontend.h>
+#include "dvb_math.h"
+#include "lgdt3305.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, reg=2 (or-able))");
+
+#define DBG_INFO 1
+#define DBG_REG 2
+
+#define lg_printk(kern, fmt, arg...) \
+ printk(kern "%s: " fmt, __func__, ##arg)
+
+#define lg_info(fmt, arg...) printk(KERN_INFO "lgdt3305: " fmt, ##arg)
+#define lg_warn(fmt, arg...) lg_printk(KERN_WARNING, fmt, ##arg)
+#define lg_err(fmt, arg...) lg_printk(KERN_ERR, fmt, ##arg)
+#define lg_dbg(fmt, arg...) if (debug & DBG_INFO) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
+#define lg_reg(fmt, arg...) if (debug & DBG_REG) \
+ lg_printk(KERN_DEBUG, fmt, ##arg)
+
+#define lg_fail(ret) \
+({ \
+ int __ret; \
+ __ret = (ret < 0); \
+ if (__ret) \
+ lg_err("error %d on line %d\n", ret, __LINE__); \
+ __ret; \
+})
+
+struct lgdt3305_state {
+ struct i2c_adapter *i2c_adap;
+ const struct lgdt3305_config *cfg;
+
+ struct dvb_frontend frontend;
+
+ fe_modulation_t current_modulation;
+ u32 current_frequency;
+ u32 snr;
+};
+
+/* ------------------------------------------------------------------------ */
+
+#define LGDT3305_GEN_CTRL_1 0x0000
+#define LGDT3305_GEN_CTRL_2 0x0001
+#define LGDT3305_GEN_CTRL_3 0x0002
+#define LGDT3305_GEN_STATUS 0x0003
+#define LGDT3305_GEN_CONTROL 0x0007
+#define LGDT3305_GEN_CTRL_4 0x000a
+#define LGDT3305_DGTL_AGC_REF_1 0x0012
+#define LGDT3305_DGTL_AGC_REF_2 0x0013
+#define LGDT3305_CR_CTR_FREQ_1 0x0106
+#define LGDT3305_CR_CTR_FREQ_2 0x0107
+#define LGDT3305_CR_CTR_FREQ_3 0x0108
+#define LGDT3305_CR_CTR_FREQ_4 0x0109
+#define LGDT3305_CR_MSE_1 0x011b
+#define LGDT3305_CR_MSE_2 0x011c
+#define LGDT3305_CR_LOCK_STATUS 0x011d
+#define LGDT3305_CR_CTRL_7 0x0126
+#define LGDT3305_AGC_POWER_REF_1 0x0300
+#define LGDT3305_AGC_POWER_REF_2 0x0301
+#define LGDT3305_AGC_DELAY_PT_1 0x0302
+#define LGDT3305_AGC_DELAY_PT_2 0x0303
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_1 0x0306
+#define LGDT3305_RFAGC_LOOP_FLTR_BW_2 0x0307
+#define LGDT3305_IFBW_1 0x0308
+#define LGDT3305_IFBW_2 0x0309
+#define LGDT3305_AGC_CTRL_1 0x030c
+#define LGDT3305_AGC_CTRL_4 0x0314
+#define LGDT3305_EQ_MSE_1 0x0413
+#define LGDT3305_EQ_MSE_2 0x0414
+#define LGDT3305_EQ_MSE_3 0x0415
+#define LGDT3305_PT_MSE_1 0x0417
+#define LGDT3305_PT_MSE_2 0x0418
+#define LGDT3305_PT_MSE_3 0x0419
+#define LGDT3305_FEC_BLOCK_CTRL 0x0504
+#define LGDT3305_FEC_LOCK_STATUS 0x050a
+#define LGDT3305_FEC_PKT_ERR_1 0x050c
+#define LGDT3305_FEC_PKT_ERR_2 0x050d
+#define LGDT3305_TP_CTRL_1 0x050e
+#define LGDT3305_BERT_PERIOD 0x0801
+#define LGDT3305_BERT_ERROR_COUNT_1 0x080a
+#define LGDT3305_BERT_ERROR_COUNT_2 0x080b
+#define LGDT3305_BERT_ERROR_COUNT_3 0x080c
+#define LGDT3305_BERT_ERROR_COUNT_4 0x080d
+
+static int lgdt3305_write_reg(struct lgdt3305_state *state, u16 reg, u8 val)
+{
+ int ret;
+ u8 buf[] = { reg >> 8, reg & 0xff, val };
+ struct i2c_msg msg = {
+ .addr = state->cfg->i2c_addr, .flags = 0,
+ .buf = buf, .len = 3,
+ };
+
+ lg_reg("reg: 0x%04x, val: 0x%02x\n", reg, val);
+
+ ret = i2c_transfer(state->i2c_adap, &msg, 1);
+
+ if (ret != 1) {
+ lg_err("error (addr %02x %02x <- %02x, err = %i)\n",
+ msg.buf[0], msg.buf[1], msg.buf[2], ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int lgdt3305_read_reg(struct lgdt3305_state *state, u16 reg, u8 *val)
+{
+ int ret;
+ u8 reg_buf[] = { reg >> 8, reg & 0xff };
+ struct i2c_msg msg[] = {
+ { .addr = state->cfg->i2c_addr,
+ .flags = 0, .buf = reg_buf, .len = 2 },
+ { .addr = state->cfg->i2c_addr,
+ .flags = I2C_M_RD, .buf = val, .len = 1 },
+ };
+
+ lg_reg("reg: 0x%04x\n", reg);
+
+ ret = i2c_transfer(state->i2c_adap, msg, 2);
+
+ if (ret != 2) {
+ lg_err("error (addr %02x reg %04x error (ret == %i)\n",
+ state->cfg->i2c_addr, reg, ret);
+ if (ret < 0)
+ return ret;
+ else
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+#define read_reg(state, reg) \
+({ \
+ u8 __val; \
+ int ret = lgdt3305_read_reg(state, reg, &__val); \
+ if (lg_fail(ret)) \
+ __val = 0; \
+ __val; \
+})
+
+static int lgdt3305_set_reg_bit(struct lgdt3305_state *state,
+ u16 reg, int bit, int onoff)
+{
+ u8 val;
+ int ret;
+
+ lg_reg("reg: 0x%04x, bit: %d, level: %d\n", reg, bit, onoff);
+
+ ret = lgdt3305_read_reg(state, reg, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ val &= ~(1 << bit);
+ val |= (onoff & 1) << bit;
+
+ ret = lgdt3305_write_reg(state, reg, val);
+fail:
+ return ret;
+}
+
+struct lgdt3305_reg {
+ u16 reg;
+ u8 val;
+};
+
+static int lgdt3305_write_regs(struct lgdt3305_state *state,
+ struct lgdt3305_reg *regs, int len)
+{
+ int i, ret;
+
+ lg_reg("writing %d registers...\n", len);
+
+ for (i = 0; i < len - 1; i++) {
+ ret = lgdt3305_write_reg(state, regs[i].reg, regs[i].val);
+ if (lg_fail(ret))
+ return ret;
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_soft_reset(struct lgdt3305_state *state)
+{
+ int ret;
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 0);
+ if (lg_fail(ret))
+ goto fail;
+
+ msleep(20);
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_3, 0, 1);
+fail:
+ return ret;
+}
+
+static inline int lgdt3305_mpeg_mode(struct lgdt3305_state *state,
+ enum lgdt3305_mpeg_mode mode)
+{
+ lg_dbg("(%d)\n", mode);
+ return lgdt3305_set_reg_bit(state, LGDT3305_TP_CTRL_1, 5, mode);
+}
+
+static int lgdt3305_mpeg_mode_polarity(struct lgdt3305_state *state,
+ enum lgdt3305_tp_clock_edge edge,
+ enum lgdt3305_tp_valid_polarity valid)
+{
+ u8 val;
+ int ret;
+
+ lg_dbg("edge = %d, valid = %d\n", edge, valid);
+
+ ret = lgdt3305_read_reg(state, LGDT3305_TP_CTRL_1, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ val &= ~0x09;
+
+ if (edge)
+ val |= 0x08;
+ if (valid)
+ val |= 0x01;
+
+ ret = lgdt3305_write_reg(state, LGDT3305_TP_CTRL_1, val);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_soft_reset(state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_modulation(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u8 opermode;
+ int ret;
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_1, &opermode);
+ if (lg_fail(ret))
+ goto fail;
+
+ opermode &= ~0x03;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ opermode |= 0x03;
+ break;
+ case QAM_64:
+ opermode |= 0x00;
+ break;
+ case QAM_256:
+ opermode |= 0x01;
+ break;
+ default:
+ return -EINVAL;
+ }
+ ret = lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_1, opermode);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_filter_extension(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ int val;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ val = 0;
+ break;
+ case QAM_64:
+ case QAM_256:
+ val = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ lg_dbg("val = %d\n", val);
+
+ return lgdt3305_set_reg_bit(state, 0x043f, 2, val);
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_passband_digital_agc(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 agc_ref;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ agc_ref = 0x32c4;
+ break;
+ case QAM_64:
+ agc_ref = 0x2a00;
+ break;
+ case QAM_256:
+ agc_ref = 0x2a80;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ lg_dbg("agc ref: 0x%04x\n", agc_ref);
+
+ lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_1, agc_ref >> 8);
+ lgdt3305_write_reg(state, LGDT3305_DGTL_AGC_REF_2, agc_ref & 0xff);
+
+ return 0;
+}
+
+static int lgdt3305_rfagc_loop(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 ifbw, rfbw, agcdelay;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ agcdelay = 0x04c0;
+ rfbw = 0x8000;
+ ifbw = 0x8000;
+ break;
+ case QAM_64:
+ case QAM_256:
+ agcdelay = 0x046b;
+ rfbw = 0x8889;
+ ifbw = 0x8888;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (state->cfg->rf_agc_loop) {
+ lg_dbg("agcdelay: 0x%04x, rfbw: 0x%04x\n", agcdelay, rfbw);
+
+ /* rf agc loop filter bandwidth */
+ lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_1,
+ agcdelay >> 8);
+ lgdt3305_write_reg(state, LGDT3305_AGC_DELAY_PT_2,
+ agcdelay & 0xff);
+
+ lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+ rfbw >> 8);
+ lgdt3305_write_reg(state, LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+ rfbw & 0xff);
+ } else {
+ lg_dbg("ifbw: 0x%04x\n", ifbw);
+
+ /* if agc loop filter bandwidth */
+ lgdt3305_write_reg(state, LGDT3305_IFBW_1, ifbw >> 8);
+ lgdt3305_write_reg(state, LGDT3305_IFBW_2, ifbw & 0xff);
+ }
+
+ return 0;
+}
+
+static int lgdt3305_agc_setup(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ int lockdten, acqen;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ lockdten = 0;
+ acqen = 0;
+ break;
+ case QAM_64:
+ case QAM_256:
+ lockdten = 1;
+ acqen = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ lg_dbg("lockdten = %d, acqen = %d\n", lockdten, acqen);
+
+ /* control agc function */
+ lgdt3305_write_reg(state, LGDT3305_AGC_CTRL_4, 0xe1 | lockdten << 1);
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 2, acqen);
+
+ return lgdt3305_rfagc_loop(state, param);
+}
+
+static int lgdt3305_set_agc_power_ref(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 usref = 0;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ if (state->cfg->usref_8vsb)
+ usref = state->cfg->usref_8vsb;
+ break;
+ case QAM_64:
+ if (state->cfg->usref_qam64)
+ usref = state->cfg->usref_qam64;
+ break;
+ case QAM_256:
+ if (state->cfg->usref_qam256)
+ usref = state->cfg->usref_qam256;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (usref) {
+ lg_dbg("set manual mode: 0x%04x\n", usref);
+
+ lgdt3305_set_reg_bit(state, LGDT3305_AGC_CTRL_1, 3, 1);
+
+ lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_1,
+ 0xff & (usref >> 8));
+ lgdt3305_write_reg(state, LGDT3305_AGC_POWER_REF_2,
+ 0xff & (usref >> 0));
+ }
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_spectral_inversion(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param,
+ int inversion)
+{
+ int ret;
+
+ lg_dbg("(%d)\n", inversion);
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ ret = lgdt3305_write_reg(state, LGDT3305_CR_CTRL_7,
+ inversion ? 0xf9 : 0x79);
+ break;
+ case QAM_64:
+ case QAM_256:
+ ret = lgdt3305_write_reg(state, LGDT3305_FEC_BLOCK_CTRL,
+ inversion ? 0xfd : 0xff);
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ return ret;
+}
+
+static int lgdt3305_set_if(struct lgdt3305_state *state,
+ struct dvb_frontend_parameters *param)
+{
+ u16 if_freq_khz;
+ u8 nco1, nco2, nco3, nco4;
+ u64 nco;
+
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+ if_freq_khz = state->cfg->vsb_if_khz;
+ break;
+ case QAM_64:
+ case QAM_256:
+ if_freq_khz = state->cfg->qam_if_khz;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ nco = if_freq_khz / 10;
+
+#define LGDT3305_64BIT_DIVISION_ENABLED 0
+ /* FIXME: 64bit division disabled to avoid linking error:
+ * WARNING: "__udivdi3" [lgdt3305.ko] undefined!
+ */
+ switch (param->u.vsb.modulation) {
+ case VSB_8:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+ nco <<= 24;
+ nco /= 625;
+#else
+ nco *= ((1 << 24) / 625);
+#endif
+ break;
+ case QAM_64:
+ case QAM_256:
+#if LGDT3305_64BIT_DIVISION_ENABLED
+ nco <<= 28;
+ nco /= 625;
+#else
+ nco *= ((1 << 28) / 625);
+#endif
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ nco1 = (nco >> 24) & 0x3f;
+ nco1 |= 0x40;
+ nco2 = (nco >> 16) & 0xff;
+ nco3 = (nco >> 8) & 0xff;
+ nco4 = nco & 0xff;
+
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_1, nco1);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_2, nco2);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_3, nco3);
+ lgdt3305_write_reg(state, LGDT3305_CR_CTR_FREQ_4, nco4);
+
+ lg_dbg("%d KHz -> [%02x%02x%02x%02x]\n",
+ if_freq_khz, nco1, nco2, nco3, nco4);
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ if (state->cfg->deny_i2c_rptr)
+ return 0;
+
+ lg_dbg("(%d)\n", enable);
+
+ return lgdt3305_set_reg_bit(state, LGDT3305_GEN_CTRL_2, 5,
+ enable ? 0 : 1);
+}
+
+static int lgdt3305_sleep(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u8 gen_ctrl_3, gen_ctrl_4;
+
+ lg_dbg("\n");
+
+ gen_ctrl_3 = read_reg(state, LGDT3305_GEN_CTRL_3);
+ gen_ctrl_4 = read_reg(state, LGDT3305_GEN_CTRL_4);
+
+ /* hold in software reset while sleeping */
+ gen_ctrl_3 &= ~0x01;
+ /* tristate the IF-AGC pin */
+ gen_ctrl_3 |= 0x02;
+ /* tristate the RF-AGC pin */
+ gen_ctrl_3 |= 0x04;
+
+ /* disable vsb/qam module */
+ gen_ctrl_4 &= ~0x01;
+ /* disable adc module */
+ gen_ctrl_4 &= ~0x02;
+
+ lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_3, gen_ctrl_3);
+ lgdt3305_write_reg(state, LGDT3305_GEN_CTRL_4, gen_ctrl_4);
+
+ return 0;
+}
+
+static int lgdt3305_init(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ int ret;
+
+ static struct lgdt3305_reg lgdt3305_init_data[] = {
+ { .reg = LGDT3305_GEN_CTRL_1,
+ .val = 0x03, },
+ { .reg = LGDT3305_GEN_CTRL_2,
+ .val = 0xb0, },
+ { .reg = LGDT3305_GEN_CTRL_3,
+ .val = 0x01, },
+ { .reg = LGDT3305_GEN_CONTROL,
+ .val = 0x6f, },
+ { .reg = LGDT3305_GEN_CTRL_4,
+ .val = 0x03, },
+ { .reg = LGDT3305_DGTL_AGC_REF_1,
+ .val = 0x32, },
+ { .reg = LGDT3305_DGTL_AGC_REF_2,
+ .val = 0xc4, },
+ { .reg = LGDT3305_CR_CTR_FREQ_1,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_3,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTR_FREQ_4,
+ .val = 0x00, },
+ { .reg = LGDT3305_CR_CTRL_7,
+ .val = 0x79, },
+ { .reg = LGDT3305_AGC_POWER_REF_1,
+ .val = 0x32, },
+ { .reg = LGDT3305_AGC_POWER_REF_2,
+ .val = 0xc4, },
+ { .reg = LGDT3305_AGC_DELAY_PT_1,
+ .val = 0x0d, },
+ { .reg = LGDT3305_AGC_DELAY_PT_2,
+ .val = 0x30, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_1,
+ .val = 0x80, },
+ { .reg = LGDT3305_RFAGC_LOOP_FLTR_BW_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_IFBW_1,
+ .val = 0x80, },
+ { .reg = LGDT3305_IFBW_2,
+ .val = 0x00, },
+ { .reg = LGDT3305_AGC_CTRL_1,
+ .val = 0x30, },
+ { .reg = LGDT3305_AGC_CTRL_4,
+ .val = 0x61, },
+ { .reg = LGDT3305_FEC_BLOCK_CTRL,
+ .val = 0xff, },
+ { .reg = LGDT3305_TP_CTRL_1,
+ .val = 0x1b, },
+ };
+
+ lg_dbg("\n");
+
+ ret = lgdt3305_write_regs(state, lgdt3305_init_data,
+ ARRAY_SIZE(lgdt3305_init_data));
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_soft_reset(state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_set_parameters(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ int ret;
+
+ lg_dbg("(%d, %d)\n", param->frequency, param->u.vsb.modulation);
+
+ if (fe->ops.tuner_ops.set_params) {
+ ret = fe->ops.tuner_ops.set_params(fe, param);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ if (lg_fail(ret))
+ goto fail;
+ state->current_frequency = param->frequency;
+ }
+
+ ret = lgdt3305_set_modulation(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_passband_digital_agc(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_set_agc_power_ref(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_agc_setup(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* low if */
+ ret = lgdt3305_write_reg(state, LGDT3305_GEN_CONTROL, 0x2f);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_set_reg_bit(state, LGDT3305_CR_CTR_FREQ_1, 6, 1);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_set_if(state, param);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_spectral_inversion(state, param,
+ state->cfg->spectral_inversion
+ ? 1 : 0);
+ if (lg_fail(ret))
+ goto fail;
+
+ ret = lgdt3305_set_filter_extension(state, param);
+ if (lg_fail(ret))
+ goto fail;
+
+ state->current_modulation = param->u.vsb.modulation;
+
+ ret = lgdt3305_mpeg_mode(state, state->cfg->mpeg_mode);
+ if (lg_fail(ret))
+ goto fail;
+
+ /* lgdt3305_mpeg_mode_polarity calls lgdt3305_soft_reset */
+ ret = lgdt3305_mpeg_mode_polarity(state,
+ state->cfg->tpclk_edge,
+ state->cfg->tpvalid_polarity);
+fail:
+ return ret;
+}
+
+static int lgdt3305_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *param)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ lg_dbg("\n");
+
+ param->u.vsb.modulation = state->current_modulation;
+ param->frequency = state->current_frequency;
+ return 0;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_cr_lock_status(struct lgdt3305_state *state,
+ int *locked)
+{
+ u8 val;
+ int ret;
+ char *cr_lock_state = "";
+
+ *locked = 0;
+
+ ret = lgdt3305_read_reg(state, LGDT3305_CR_LOCK_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ if (val & (1 << 1))
+ *locked = 1;
+
+ switch (val & 0x07) {
+ case 0:
+ cr_lock_state = "QAM UNLOCK";
+ break;
+ case 4:
+ cr_lock_state = "QAM 1stLock";
+ break;
+ case 6:
+ cr_lock_state = "QAM 2ndLock";
+ break;
+ case 7:
+ cr_lock_state = "QAM FinalLock";
+ break;
+ default:
+ cr_lock_state = "CLOCKQAM-INVALID!";
+ break;
+ }
+ break;
+ case VSB_8:
+ if (val & (1 << 7)) {
+ *locked = 1;
+ cr_lock_state = "CLOCKVSB";
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ }
+ lg_dbg("(%d) %s\n", *locked, cr_lock_state);
+fail:
+ return ret;
+}
+
+static int lgdt3305_read_fec_lock_status(struct lgdt3305_state *state,
+ int *locked)
+{
+ u8 val;
+ int ret, mpeg_lock, fec_lock, viterbi_lock;
+
+ *locked = 0;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ ret = lgdt3305_read_reg(state,
+ LGDT3305_FEC_LOCK_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ mpeg_lock = (val & (1 << 0)) ? 1 : 0;
+ fec_lock = (val & (1 << 2)) ? 1 : 0;
+ viterbi_lock = (val & (1 << 3)) ? 1 : 0;
+
+ *locked = mpeg_lock && fec_lock && viterbi_lock;
+
+ lg_dbg("(%d) %s%s%s\n", *locked,
+ mpeg_lock ? "mpeg lock " : "",
+ fec_lock ? "fec lock " : "",
+ viterbi_lock ? "viterbi lock" : "");
+ break;
+ case VSB_8:
+ default:
+ ret = -EINVAL;
+ }
+fail:
+ return ret;
+}
+
+static int lgdt3305_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u8 val;
+ int ret, signal, inlock, nofecerr, snrgood,
+ cr_lock, fec_lock, sync_lock;
+
+ *status = 0;
+
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_STATUS, &val);
+ if (lg_fail(ret))
+ goto fail;
+
+ signal = (val & (1 << 4)) ? 1 : 0;
+ inlock = (val & (1 << 3)) ? 0 : 1;
+ sync_lock = (val & (1 << 2)) ? 1 : 0;
+ nofecerr = (val & (1 << 1)) ? 1 : 0;
+ snrgood = (val & (1 << 0)) ? 1 : 0;
+
+ lg_dbg("%s%s%s%s%s\n",
+ signal ? "SIGNALEXIST " : "",
+ inlock ? "INLOCK " : "",
+ sync_lock ? "SYNCLOCK " : "",
+ nofecerr ? "NOFECERR " : "",
+ snrgood ? "SNRGOOD " : "");
+
+ ret = lgdt3305_read_cr_lock_status(state, &cr_lock);
+ if (lg_fail(ret))
+ goto fail;
+
+ if (signal)
+ *status |= FE_HAS_SIGNAL;
+ if (cr_lock)
+ *status |= FE_HAS_CARRIER;
+ if (nofecerr)
+ *status |= FE_HAS_VITERBI;
+ if (sync_lock)
+ *status |= FE_HAS_SYNC;
+
+ switch (state->current_modulation) {
+ case QAM_256:
+ case QAM_64:
+ ret = lgdt3305_read_fec_lock_status(state, &fec_lock);
+ if (lg_fail(ret))
+ goto fail;
+
+ if (fec_lock)
+ *status |= FE_HAS_LOCK;
+ break;
+ case VSB_8:
+ if (inlock)
+ *status |= FE_HAS_LOCK;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/* borrowed from lgdt330x.c */
+static u32 calculate_snr(u32 mse, u32 c)
+{
+ if (mse == 0) /* no signal */
+ return 0;
+
+ mse = intlog10(mse);
+ if (mse > c) {
+ /* Negative SNR, which is possible, but realisticly the
+ demod will lose lock before the signal gets this bad. The
+ API only allows for unsigned values, so just return 0 */
+ return 0;
+ }
+ return 10*(c - mse);
+}
+
+static int lgdt3305_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u32 noise; /* noise value */
+ u32 c; /* per-modulation SNR calculation constant */
+
+ switch (state->current_modulation) {
+ case VSB_8:
+#ifdef USE_PTMSE
+ /* Use Phase Tracker Mean-Square Error Register */
+ /* SNR for ranges from -13.11 to +44.08 */
+ noise = ((read_reg(state, LGDT3305_PT_MSE_1) & 0x07) << 16) |
+ (read_reg(state, LGDT3305_PT_MSE_2) << 8) |
+ (read_reg(state, LGDT3305_PT_MSE_3) & 0xff);
+ c = 73957994; /* log10(25*32^2)*2^24 */
+#else
+ /* Use Equalizer Mean-Square Error Register */
+ /* SNR for ranges from -16.12 to +44.08 */
+ noise = ((read_reg(state, LGDT3305_EQ_MSE_1) & 0x0f) << 16) |
+ (read_reg(state, LGDT3305_EQ_MSE_2) << 8) |
+ (read_reg(state, LGDT3305_EQ_MSE_3) & 0xff);
+ c = 73957994; /* log10(25*32^2)*2^24 */
+#endif
+ break;
+ case QAM_64:
+ case QAM_256:
+ noise = (read_reg(state, LGDT3305_CR_MSE_1) << 8) |
+ (read_reg(state, LGDT3305_CR_MSE_2) & 0xff);
+
+ c = (state->current_modulation == QAM_64) ?
+ 97939837 : 98026066;
+ /* log10(688128)*2^24 and log10(696320)*2^24 */
+ break;
+ default:
+ return -EINVAL;
+ }
+ state->snr = calculate_snr(noise, c);
+ /* report SNR in dB * 10 */
+ *snr = (state->snr / ((1 << 24) / 10));
+ lg_dbg("noise = 0x%08x, snr = %d.%02d dB\n", noise,
+ state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
+
+ return 0;
+}
+
+static int lgdt3305_read_signal_strength(struct dvb_frontend *fe,
+ u16 *strength)
+{
+ /* borrowed from lgdt330x.c
+ *
+ * Calculate strength from SNR up to 35dB
+ * Even though the SNR can go higher than 35dB,
+ * there is some comfort factor in having a range of
+ * strong signals that can show at 100%
+ */
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ u16 snr;
+ int ret;
+
+ *strength = 0;
+
+ ret = fe->ops.read_snr(fe, &snr);
+ if (lg_fail(ret))
+ goto fail;
+ /* Rather than use the 8.8 value snr, use state->snr which is 8.24 */
+ /* scale the range 0 - 35*2^24 into 0 - 65535 */
+ if (state->snr >= 8960 * 0x10000)
+ *strength = 0xffff;
+ else
+ *strength = state->snr / 8960;
+fail:
+ return ret;
+}
+
+/* ------------------------------------------------------------------------ */
+
+static int lgdt3305_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ *ber = 0;
+ return 0;
+}
+
+static int lgdt3305_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+
+ *ucblocks =
+ (read_reg(state, LGDT3305_FEC_PKT_ERR_1) << 8) |
+ (read_reg(state, LGDT3305_FEC_PKT_ERR_2) & 0xff);
+
+ return 0;
+}
+
+static int lgdt3305_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings
+ *fe_tune_settings)
+{
+ fe_tune_settings->min_delay_ms = 500;
+ lg_dbg("\n");
+ return 0;
+}
+
+static void lgdt3305_release(struct dvb_frontend *fe)
+{
+ struct lgdt3305_state *state = fe->demodulator_priv;
+ lg_dbg("\n");
+ kfree(state);
+}
+
+static struct dvb_frontend_ops lgdt3305_ops;
+
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap)
+{
+ struct lgdt3305_state *state = NULL;
+ int ret;
+ u8 val;
+
+ lg_dbg("(%d-%04x)\n",
+ i2c_adap ? i2c_adapter_id(i2c_adap) : 0,
+ config ? config->i2c_addr : 0);
+
+ state = kzalloc(sizeof(struct lgdt3305_state), GFP_KERNEL);
+ if (state == NULL)
+ goto fail;
+
+ state->cfg = config;
+ state->i2c_adap = i2c_adap;
+
+ memcpy(&state->frontend.ops, &lgdt3305_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ /* verify that we're talking to a lg dt3305 */
+ ret = lgdt3305_read_reg(state, LGDT3305_GEN_CTRL_2, &val);
+ if ((lg_fail(ret)) | (val == 0))
+ goto fail;
+ ret = lgdt3305_write_reg(state, 0x0808, 0x80);
+ if (lg_fail(ret))
+ goto fail;
+ ret = lgdt3305_read_reg(state, 0x0808, &val);
+ if ((lg_fail(ret)) | (val != 0x80))
+ goto fail;
+ ret = lgdt3305_write_reg(state, 0x0808, 0x00);
+ if (lg_fail(ret))
+ goto fail;
+
+ state->current_frequency = -1;
+ state->current_modulation = -1;
+
+ return &state->frontend;
+fail:
+ lg_warn("unable to detect LGDT3305 hardware\n");
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(lgdt3305_attach);
+
+static struct dvb_frontend_ops lgdt3305_ops = {
+ .info = {
+ .name = "LG Electronics LGDT3305 VSB/QAM Frontend",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 62500,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+ .i2c_gate_ctrl = lgdt3305_i2c_gate_ctrl,
+ .init = lgdt3305_init,
+ .sleep = lgdt3305_sleep,
+ .set_frontend = lgdt3305_set_parameters,
+ .get_frontend = lgdt3305_get_frontend,
+ .get_tune_settings = lgdt3305_get_tune_settings,
+ .read_status = lgdt3305_read_status,
+ .read_ber = lgdt3305_read_ber,
+ .read_signal_strength = lgdt3305_read_signal_strength,
+ .read_snr = lgdt3305_read_snr,
+ .read_ucblocks = lgdt3305_read_ucblocks,
+ .release = lgdt3305_release,
+};
+
+MODULE_DESCRIPTION("LG Electronics LGDT3305 ATSC/QAM-B Demodulator Driver");
+MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("0.1");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/media/dvb/frontends/lgdt3305.h b/drivers/media/dvb/frontends/lgdt3305.h
new file mode 100644
index 00000000000..4fa6e52d1fe
--- /dev/null
+++ b/drivers/media/dvb/frontends/lgdt3305.h
@@ -0,0 +1,85 @@
+/*
+ * Support for LGDT3305 - VSB/QAM
+ *
+ * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef _LGDT3305_H_
+#define _LGDT3305_H_
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+
+enum lgdt3305_mpeg_mode {
+ LGDT3305_MPEG_PARALLEL = 0,
+ LGDT3305_MPEG_SERIAL = 1,
+};
+
+enum lgdt3305_tp_clock_edge {
+ LGDT3305_TPCLK_RISING_EDGE = 0,
+ LGDT3305_TPCLK_FALLING_EDGE = 1,
+};
+
+enum lgdt3305_tp_valid_polarity {
+ LGDT3305_TP_VALID_LOW = 0,
+ LGDT3305_TP_VALID_HIGH = 1,
+};
+
+struct lgdt3305_config {
+ u8 i2c_addr;
+
+ /* user defined IF frequency in KHz */
+ u16 qam_if_khz;
+ u16 vsb_if_khz;
+
+ /* AGC Power reference - defaults are used if left unset */
+ u16 usref_8vsb; /* default: 0x32c4 */
+ u16 usref_qam64; /* default: 0x5400 */
+ u16 usref_qam256; /* default: 0x2a80 */
+
+ /* disable i2c repeater - 0:repeater enabled 1:repeater disabled */
+ int deny_i2c_rptr:1;
+
+ /* spectral inversion - 0:disabled 1:enabled */
+ int spectral_inversion:1;
+
+ /* use RF AGC loop - 0:disabled 1:enabled */
+ int rf_agc_loop:1;
+
+ enum lgdt3305_mpeg_mode mpeg_mode;
+ enum lgdt3305_tp_clock_edge tpclk_edge;
+ enum lgdt3305_tp_valid_polarity tpvalid_polarity;
+};
+
+#if defined(CONFIG_DVB_LGDT3305) || (defined(CONFIG_DVB_LGDT3305_MODULE) && \
+ defined(MODULE))
+extern
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap);
+#else
+static inline
+struct dvb_frontend *lgdt3305_attach(const struct lgdt3305_config *config,
+ struct i2c_adapter *i2c_adap)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_LGDT3305 */
+
+#endif /* _LGDT3305_H_ */
diff --git a/drivers/media/dvb/frontends/lnbh24.h b/drivers/media/dvb/frontends/lnbh24.h
new file mode 100644
index 00000000000..c059b165318
--- /dev/null
+++ b/drivers/media/dvb/frontends/lnbh24.h
@@ -0,0 +1,55 @@
+/*
+ * lnbh24.h - driver for lnb supply and control ic lnbh24
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _LNBH24_H
+#define _LNBH24_H
+
+/* system register bits */
+#define LNBH24_OLF 0x01
+#define LNBH24_OTF 0x02
+#define LNBH24_EN 0x04
+#define LNBH24_VSEL 0x08
+#define LNBH24_LLC 0x10
+#define LNBH24_TEN 0x20
+#define LNBH24_TTX 0x40
+#define LNBH24_PCL 0x80
+
+#include <linux/dvb/frontend.h>
+
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+ && defined(MODULE))
+/* override_set and override_clear control which
+ system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr);
+#else
+static inline struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
index 76f935d9755..1dcc56f32bf 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -1,7 +1,8 @@
/*
- * lnbp21.h - driver for lnb supply and control ic lnbp21
+ * lnbp21.c - driver for lnb supply and control ic lnbp21
*
* Copyright (C) 2006 Oliver Endriss
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -33,18 +34,21 @@
#include "dvb_frontend.h"
#include "lnbp21.h"
+#include "lnbh24.h"
struct lnbp21 {
u8 config;
u8 override_or;
u8 override_and;
struct i2c_adapter *i2c;
+ u8 i2c_addr;
};
-static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+static int lnbp21_set_voltage(struct dvb_frontend *fe,
+ fe_sec_voltage_t voltage)
{
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
- struct i2c_msg msg = { .addr = 0x08, .flags = 0,
+ struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -72,7 +76,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
{
struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
- struct i2c_msg msg = { .addr = 0x08, .flags = 0,
+ struct i2c_msg msg = { .addr = lnbp21->i2c_addr, .flags = 0,
.buf = &lnbp21->config,
.len = sizeof(lnbp21->config) };
@@ -97,15 +101,18 @@ static void lnbp21_release(struct dvb_frontend *fe)
fe->sec_priv = NULL;
}
-struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+static struct dvb_frontend *lnbx2x_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr, u8 config)
{
struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
if (!lnbp21)
return NULL;
/* default configuration */
- lnbp21->config = LNBP21_ISEL;
+ lnbp21->config = config;
lnbp21->i2c = i2c;
+ lnbp21->i2c_addr = i2c_addr;
fe->sec_priv = lnbp21;
/* bits which should be forced to '1' */
@@ -126,11 +133,29 @@ struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *
/* override frontend ops */
fe->ops.set_voltage = lnbp21_set_voltage;
fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
+ printk(KERN_INFO "LNBx2x attached on addr=%x", lnbp21->i2c_addr);
return fe;
}
+
+struct dvb_frontend *lnbh24_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear, u8 i2c_addr)
+{
+ return lnbx2x_attach(fe, i2c, override_set, override_clear,
+ i2c_addr, LNBH24_TTX);
+}
+EXPORT_SYMBOL(lnbh24_attach);
+
+struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear)
+{
+ return lnbx2x_attach(fe, i2c, override_set, override_clear,
+ 0x08, LNBP21_ISEL);
+}
EXPORT_SYMBOL(lnbp21_attach);
-MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21");
-MODULE_AUTHOR("Oliver Endriss");
+MODULE_DESCRIPTION("Driver for lnb supply and control ic lnbp21, lnbh24");
+MODULE_AUTHOR("Oliver Endriss, Igor M. Liplianin");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 8fe094bd968..fcdf1c650dd 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -28,26 +28,48 @@
#define _LNBP21_H
/* system register bits */
+/* [RO] 0=OK; 1=over current limit flag */
#define LNBP21_OLF 0x01
+/* [RO] 0=OK; 1=over temperature flag (150 C) */
#define LNBP21_OTF 0x02
+/* [RW] 0=disable LNB power, enable loopthrough
+ 1=enable LNB power, disable loopthrough */
#define LNBP21_EN 0x04
+/* [RW] 0=low voltage (13/14V, vert pol)
+ 1=high voltage (18/19V,horiz pol) */
#define LNBP21_VSEL 0x08
+/* [RW] increase LNB voltage by 1V:
+ 0=13/18V; 1=14/19V */
#define LNBP21_LLC 0x10
+/* [RW] 0=tone controlled by DSQIN pin
+ 1=tone enable, disable DSQIN */
#define LNBP21_TEN 0x20
+/* [RW] current limit select:
+ 0:Iout=500-650mA Isc=300mA
+ 1:Iout=400-550mA Isc=200mA */
#define LNBP21_ISEL 0x40
+/* [RW] short-circuit protect:
+ 0=pulsed (dynamic) curr limiting
+ 1=static curr limiting */
#define LNBP21_PCL 0x80
#include <linux/dvb/frontend.h>
-#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) && defined(MODULE))
-/* override_set and override_clear control which system register bits (above) to always set & clear */
-extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
+#if defined(CONFIG_DVB_LNBP21) || (defined(CONFIG_DVB_LNBP21_MODULE) \
+ && defined(MODULE))
+/* override_set and override_clear control which
+ system register bits (above) to always set & clear */
+extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear);
#else
-static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
+static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c, u8 override_set,
+ u8 override_clear)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_LNBP21
+#endif
-#endif // _LNBP21_H
+#endif
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
index 892af8c9ed5..3f5a0e1dfdf 100644
--- a/drivers/media/dvb/frontends/s921_module.c
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -169,7 +169,6 @@ struct dvb_frontend* s921_attach(const struct s921_config *config,
struct s921_state *state;
state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
- memset(state, 0x0, sizeof(struct s921_state));
state->addr = config->i2c_address;
state->i2c = i2c;
diff --git a/drivers/media/dvb/frontends/stb6100_cfg.h b/drivers/media/dvb/frontends/stb6100_cfg.h
index d3133405dc0..6314d18c797 100644
--- a/drivers/media/dvb/frontends/stb6100_cfg.h
+++ b/drivers/media/dvb/frontends/stb6100_cfg.h
@@ -36,7 +36,6 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
return err;
}
*frequency = t_state.frequency;
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
}
return 0;
}
@@ -59,7 +58,6 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
return err;
}
}
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
return 0;
}
@@ -81,7 +79,6 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
}
*bandwidth = t_state.bandwidth;
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
@@ -103,6 +100,5 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
return err;
}
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
new file mode 100644
index 00000000000..8a1332c2031
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -0,0 +1,62 @@
+/*
+ * stv0900.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_H
+#define STV0900_H
+
+#include <linux/dvb/frontend.h>
+#include "dvb_frontend.h"
+
+struct stv0900_config {
+ u8 demod_address;
+ u32 xtal;
+ u8 clkmode;/* 0 for CLKI, 2 for XTALI */
+
+ u8 diseqc_mode;
+
+ u8 path1_mode;
+ u8 path2_mode;
+
+ u8 tun1_maddress;/* 0, 1, 2, 3 for 0xc0, 0xc2, 0xc4, 0xc6 */
+ u8 tun2_maddress;
+ u8 tun1_adc;/* 1 for stv6110, 2 for stb6100 */
+ u8 tun2_adc;
+};
+
+#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c, int demod);
+#else
+static inline struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c, int demod)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
+
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
new file mode 100644
index 00000000000..8499bcf7f25
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -0,0 +1,1949 @@
+/*
+ * stv0900_core.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+#include "stv0900_init.h"
+
+static int stvdebug = 1;
+module_param_named(debug, stvdebug, int, 0644);
+
+/* internal params node */
+struct stv0900_inode {
+ /* pointer for internal params, one for each pair of demods */
+ struct stv0900_internal *internal;
+ struct stv0900_inode *next_inode;
+};
+
+/* first internal params */
+static struct stv0900_inode *stv0900_first_inode;
+
+/* find chip by i2c adapter and i2c address */
+static struct stv0900_inode *find_inode(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr)
+{
+ struct stv0900_inode *temp_chip = stv0900_first_inode;
+
+ if (temp_chip != NULL) {
+ /*
+ Search of the last stv0900 chip or
+ find it by i2c adapter and i2c address */
+ while ((temp_chip != NULL) &&
+ ((temp_chip->internal->i2c_adap != i2c_adap) ||
+ (temp_chip->internal->i2c_addr != i2c_addr)))
+
+ temp_chip = temp_chip->next_inode;
+
+ }
+
+ return temp_chip;
+}
+
+/* deallocating chip */
+static void remove_inode(struct stv0900_internal *internal)
+{
+ struct stv0900_inode *prev_node = stv0900_first_inode;
+ struct stv0900_inode *del_node = find_inode(internal->i2c_adap,
+ internal->i2c_addr);
+
+ if (del_node != NULL) {
+ if (del_node == stv0900_first_inode) {
+ stv0900_first_inode = del_node->next_inode;
+ } else {
+ while (prev_node->next_inode != del_node)
+ prev_node = prev_node->next_inode;
+
+ if (del_node->next_inode == NULL)
+ prev_node->next_inode = NULL;
+ else
+ prev_node->next_inode =
+ prev_node->next_inode->next_inode;
+ }
+
+ kfree(del_node);
+ }
+}
+
+/* allocating new chip */
+static struct stv0900_inode *append_internal(struct stv0900_internal *internal)
+{
+ struct stv0900_inode *new_node = stv0900_first_inode;
+
+ if (new_node == NULL) {
+ new_node = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+ stv0900_first_inode = new_node;
+ } else {
+ while (new_node->next_inode != NULL)
+ new_node = new_node->next_inode;
+
+ new_node->next_inode = kmalloc(sizeof(struct stv0900_inode), GFP_KERNEL);
+ if (new_node->next_inode != NULL)
+ new_node = new_node->next_inode;
+ else
+ new_node = NULL;
+ }
+
+ if (new_node != NULL) {
+ new_node->internal = internal;
+ new_node->next_inode = NULL;
+ }
+
+ return new_node;
+}
+
+s32 ge2comp(s32 a, s32 width)
+{
+ if (width == 32)
+ return a;
+ else
+ return (a >= (1 << (width - 1))) ? (a - (1 << width)) : a;
+}
+
+void stv0900_write_reg(struct stv0900_internal *i_params, u16 reg_addr,
+ u8 reg_data)
+{
+ u8 data[3];
+ int ret;
+ struct i2c_msg i2cmsg = {
+ .addr = i_params->i2c_addr,
+ .flags = 0,
+ .len = 3,
+ .buf = data,
+ };
+
+ data[0] = MSB(reg_addr);
+ data[1] = LSB(reg_addr);
+ data[2] = reg_data;
+
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+}
+
+u8 stv0900_read_reg(struct stv0900_internal *i_params, u16 reg_addr)
+{
+ u8 data[2];
+ int ret;
+ struct i2c_msg i2cmsg = {
+ .addr = i_params->i2c_addr,
+ .flags = 0,
+ .len = 2,
+ .buf = data,
+ };
+
+ data[0] = MSB(reg_addr);
+ data[1] = LSB(reg_addr);
+
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+ i2cmsg.flags = I2C_M_RD;
+ i2cmsg.len = 1;
+ ret = i2c_transfer(i_params->i2c_adap, &i2cmsg, 1);
+ if (ret != 1)
+ dprintk(KERN_ERR "%s: i2c error %d\n", __func__, ret);
+
+ return data[0];
+}
+
+void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
+{
+ u8 position = 0, i = 0;
+
+ (*mask) = label & 0xff;
+
+ while ((position == 0) && (i < 8)) {
+ position = ((*mask) >> i) & 0x01;
+ i++;
+ }
+
+ (*pos) = (i - 1);
+}
+
+void stv0900_write_bits(struct stv0900_internal *i_params, u32 label, u8 val)
+{
+ u8 reg, mask, pos;
+
+ reg = stv0900_read_reg(i_params, (label >> 16) & 0xffff);
+ extract_mask_pos(label, &mask, &pos);
+
+ val = mask & (val << pos);
+
+ reg = (reg & (~mask)) | val;
+ stv0900_write_reg(i_params, (label >> 16) & 0xffff, reg);
+
+}
+
+u8 stv0900_get_bits(struct stv0900_internal *i_params, u32 label)
+{
+ u8 val = 0xff;
+ u8 mask, pos;
+
+ extract_mask_pos(label, &mask, &pos);
+
+ val = stv0900_read_reg(i_params, label >> 16);
+ val = (val & mask) >> pos;
+
+ return val;
+}
+
+enum fe_stv0900_error stv0900_initialize(struct stv0900_internal *i_params)
+{
+ s32 i;
+ enum fe_stv0900_error error;
+
+ if (i_params != NULL) {
+ i_params->chip_id = stv0900_read_reg(i_params, R0900_MID);
+ if (i_params->errs == STV0900_NO_ERROR) {
+ /*Startup sequence*/
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5c);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5c);
+ stv0900_write_reg(i_params, R0900_P1_TNRCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_P2_TNRCFG, 0x6f);
+ stv0900_write_reg(i_params, R0900_P1_I2CRPT, 0x24);
+ stv0900_write_reg(i_params, R0900_P2_I2CRPT, 0x24);
+ stv0900_write_reg(i_params, R0900_NCOARSE, 0x13);
+ msleep(3);
+ stv0900_write_reg(i_params, R0900_I2CCFG, 0x08);
+
+ switch (i_params->clkmode) {
+ case 0:
+ case 2:
+ stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20
+ | i_params->clkmode);
+ break;
+ default:
+ /* preserve SELOSCI bit */
+ i = 0x02 & stv0900_read_reg(i_params, R0900_SYNTCTRL);
+ stv0900_write_reg(i_params, R0900_SYNTCTRL, 0x20 | i);
+ break;
+ }
+
+ msleep(3);
+ for (i = 0; i < 182; i++)
+ stv0900_write_reg(i_params, STV0900_InitVal[i][0], STV0900_InitVal[i][1]);
+
+ if (stv0900_read_reg(i_params, R0900_MID) >= 0x20) {
+ stv0900_write_reg(i_params, R0900_TSGENERAL, 0x0c);
+ for (i = 0; i < 32; i++)
+ stv0900_write_reg(i_params, STV0900_Cut20_AddOnVal[i][0], STV0900_Cut20_AddOnVal[i][1]);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_FSPYCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_P2_FSPYCFG, 0x6c);
+ stv0900_write_reg(i_params, R0900_TSTRES0, 0x80);
+ stv0900_write_reg(i_params, R0900_TSTRES0, 0x00);
+ }
+ error = i_params->errs;
+ } else
+ error = STV0900_INVALID_HANDLE;
+
+ return error;
+
+}
+
+u32 stv0900_get_mclk_freq(struct stv0900_internal *i_params, u32 ext_clk)
+{
+ u32 mclk = 90000000, div = 0, ad_div = 0;
+
+ div = stv0900_get_bits(i_params, F0900_M_DIV);
+ ad_div = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+
+ mclk = (div + 1) * ext_clk / ad_div;
+
+ dprintk(KERN_INFO "%s: Calculated Mclk = %d\n", __func__, mclk);
+
+ return mclk;
+}
+
+enum fe_stv0900_error stv0900_set_mclk(struct stv0900_internal *i_params, u32 mclk)
+{
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+ u32 m_div, clk_sel;
+
+ dprintk(KERN_INFO "%s: Mclk set to %d, Quartz = %d\n", __func__, mclk,
+ i_params->quartz);
+
+ if (i_params == NULL)
+ error = STV0900_INVALID_HANDLE;
+ else {
+ if (i_params->errs)
+ error = STV0900_I2C_ERROR;
+ else {
+ clk_sel = ((stv0900_get_bits(i_params, F0900_SELX1RATIO) == 1) ? 4 : 6);
+ m_div = ((clk_sel * mclk) / i_params->quartz) - 1;
+ stv0900_write_bits(i_params, F0900_M_DIV, m_div);
+ i_params->mclk = stv0900_get_mclk_freq(i_params,
+ i_params->quartz);
+
+ /*Set the DiseqC frequency to 22KHz */
+ /*
+ Formula:
+ DiseqC_TX_Freq= MasterClock/(32*F22TX_Reg)
+ DiseqC_RX_Freq= MasterClock/(32*F22RX_Reg)
+ */
+ m_div = i_params->mclk / 704000;
+ stv0900_write_reg(i_params, R0900_P1_F22TX, m_div);
+ stv0900_write_reg(i_params, R0900_P1_F22RX, m_div);
+
+ stv0900_write_reg(i_params, R0900_P2_F22TX, m_div);
+ stv0900_write_reg(i_params, R0900_P2_F22RX, m_div);
+
+ if ((i_params->errs))
+ error = STV0900_I2C_ERROR;
+ }
+ }
+
+ return error;
+}
+
+u32 stv0900_get_err_count(struct stv0900_internal *i_params, int cntr,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 lsb, msb, hsb, err_val;
+ s32 err1field_hsb, err1field_msb, err1field_lsb;
+ s32 err2field_hsb, err2field_msb, err2field_lsb;
+
+ dmd_reg(err1field_hsb, F0900_P1_ERR_CNT12, F0900_P2_ERR_CNT12);
+ dmd_reg(err1field_msb, F0900_P1_ERR_CNT11, F0900_P2_ERR_CNT11);
+ dmd_reg(err1field_lsb, F0900_P1_ERR_CNT10, F0900_P2_ERR_CNT10);
+
+ dmd_reg(err2field_hsb, F0900_P1_ERR_CNT22, F0900_P2_ERR_CNT22);
+ dmd_reg(err2field_msb, F0900_P1_ERR_CNT21, F0900_P2_ERR_CNT21);
+ dmd_reg(err2field_lsb, F0900_P1_ERR_CNT20, F0900_P2_ERR_CNT20);
+
+ switch (cntr) {
+ case 0:
+ default:
+ hsb = stv0900_get_bits(i_params, err1field_hsb);
+ msb = stv0900_get_bits(i_params, err1field_msb);
+ lsb = stv0900_get_bits(i_params, err1field_lsb);
+ break;
+ case 1:
+ hsb = stv0900_get_bits(i_params, err2field_hsb);
+ msb = stv0900_get_bits(i_params, err2field_msb);
+ lsb = stv0900_get_bits(i_params, err2field_lsb);
+ break;
+ }
+
+ err_val = (hsb << 16) + (msb << 8) + (lsb);
+
+ return err_val;
+}
+
+static int stv0900_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ u32 fi2c;
+
+ dmd_reg(fi2c, F0900_P1_I2CT_ON, F0900_P2_I2CT_ON);
+ if (enable)
+ stv0900_write_bits(i_params, fi2c, 1);
+
+ return 0;
+}
+
+static void stv0900_set_ts_parallel_serial(struct stv0900_internal *i_params,
+ enum fe_stv0900_clock_type path1_ts,
+ enum fe_stv0900_clock_type path2_ts)
+{
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id >= 0x20) {
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL,
+ 0x00);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL,
+ 0x06);
+ stv0900_write_bits(i_params,
+ F0900_P1_TSFIFO_MANSPEED, 3);
+ stv0900_write_bits(i_params,
+ F0900_P2_TSFIFO_MANSPEED, 0);
+ stv0900_write_reg(i_params,
+ R0900_P1_TSSPEED, 0x14);
+ stv0900_write_reg(i_params,
+ R0900_P2_TSSPEED, 0x28);
+ break;
+ }
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params,
+ R0900_TSGENERAL, 0x0C);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params,
+ R0900_TSGENERAL, 0x0A);
+ dprintk(KERN_INFO "%s: 0x0a\n", __func__);
+ break;
+ }
+ break;
+ }
+ } else {
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x10);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x16);
+ stv0900_write_bits(i_params,
+ F0900_P1_TSFIFO_MANSPEED, 3);
+ stv0900_write_bits(i_params,
+ F0900_P2_TSFIFO_MANSPEED, 0);
+ stv0900_write_reg(i_params, R0900_P1_TSSPEED,
+ 0x14);
+ stv0900_write_reg(i_params, R0900_P2_TSSPEED,
+ 0x28);
+ break;
+ }
+
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ switch (path2_ts) {
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ case STV0900_SERIAL_CONT_CLOCK:
+ default:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x14);
+ break;
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_reg(i_params, R0900_TSGENERAL1X,
+ 0x12);
+ dprintk(KERN_INFO "%s: 0x12\n", __func__);
+ break;
+ }
+
+ break;
+ }
+ }
+
+ switch (path1_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_SERIAL_CONT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P1_TSFIFO_DVBCI, 0x01);
+ break;
+ default:
+ break;
+ }
+
+ switch (path2_ts) {
+ case STV0900_PARALLEL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_DVBCI_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+ break;
+ case STV0900_SERIAL_PUNCT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x00);
+ break;
+ case STV0900_SERIAL_CONT_CLOCK:
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_SERIAL, 0x01);
+ stv0900_write_bits(i_params, F0900_P2_TSFIFO_DVBCI, 0x01);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 0);
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 0);
+}
+
+void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+ u32 bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->set_frequency) {
+ if ((tuner_ops->set_frequency(fe, frequency)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+ }
+
+ if (tuner_ops->set_bandwidth) {
+ if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+ }
+}
+
+void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->set_bandwidth) {
+ if ((tuner_ops->set_bandwidth(fe, bandwidth)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Bandwidth=%d\n", __func__, bandwidth);
+
+ }
+}
+
+static s32 stv0900_get_rf_level(struct stv0900_internal *i_params,
+ const struct stv0900_table *lookup,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 agc_gain = 0,
+ imin,
+ imax,
+ i,
+ rf_lvl = 0;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if ((lookup != NULL) && lookup->size) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE1),
+ stv0900_get_bits(i_params, F0900_P1_AGCIQ_VALUE0));
+ break;
+ case STV0900_DEMOD_2:
+ agc_gain = MAKEWORD(stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE1),
+ stv0900_get_bits(i_params, F0900_P2_AGCIQ_VALUE0));
+ break;
+ }
+
+ imin = 0;
+ imax = lookup->size - 1;
+ if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[imax].regval)) {
+ while ((imax - imin) > 1) {
+ i = (imax + imin) >> 1;
+
+ if (INRANGE(lookup->table[imin].regval, agc_gain, lookup->table[i].regval))
+ imax = i;
+ else
+ imin = i;
+ }
+
+ rf_lvl = (((s32)agc_gain - lookup->table[imin].regval)
+ * (lookup->table[imax].realval - lookup->table[imin].realval)
+ / (lookup->table[imax].regval - lookup->table[imin].regval))
+ + lookup->table[imin].realval;
+ } else if (agc_gain > lookup->table[0].regval)
+ rf_lvl = 5;
+ else if (agc_gain < lookup->table[lookup->size-1].regval)
+ rf_lvl = -100;
+
+ }
+
+ dprintk(KERN_INFO "%s: RFLevel = %d\n", __func__, rf_lvl);
+
+ return rf_lvl;
+}
+
+static int stv0900_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *internal = state->internal;
+ s32 rflevel = stv0900_get_rf_level(internal, &stv0900_rf,
+ state->demod);
+
+ *strength = (rflevel + 100) * (16383 / 105);
+
+ return 0;
+}
+
+
+static s32 stv0900_carr_get_quality(struct dvb_frontend *fe,
+ const struct stv0900_table *lookup)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 c_n = -100,
+ regval, imin, imax,
+ i,
+ lock_flag_field,
+ noise_field1,
+ noise_field0;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(lock_flag_field, F0900_P1_LOCK_DEFINITIF,
+ F0900_P2_LOCK_DEFINITIF);
+ if (stv0900_get_standard(fe, demod) == STV0900_DVBS2_STANDARD) {
+ dmd_reg(noise_field1, F0900_P1_NOSPLHT_NORMED1,
+ F0900_P2_NOSPLHT_NORMED1);
+ dmd_reg(noise_field0, F0900_P1_NOSPLHT_NORMED0,
+ F0900_P2_NOSPLHT_NORMED0);
+ } else {
+ dmd_reg(noise_field1, F0900_P1_NOSDATAT_NORMED1,
+ F0900_P2_NOSDATAT_NORMED1);
+ dmd_reg(noise_field0, F0900_P1_NOSDATAT_NORMED0,
+ F0900_P2_NOSDATAT_NORMED0);
+ }
+
+ if (stv0900_get_bits(i_params, lock_flag_field)) {
+ if ((lookup != NULL) && lookup->size) {
+ regval = 0;
+ msleep(5);
+ for (i = 0; i < 16; i++) {
+ regval += MAKEWORD(stv0900_get_bits(i_params,
+ noise_field1),
+ stv0900_get_bits(i_params,
+ noise_field0));
+ msleep(1);
+ }
+
+ regval /= 16;
+ imin = 0;
+ imax = lookup->size - 1;
+ if (INRANGE(lookup->table[imin].regval,
+ regval,
+ lookup->table[imax].regval)) {
+ while ((imax - imin) > 1) {
+ i = (imax + imin) >> 1;
+ if (INRANGE(lookup->table[imin].regval,
+ regval,
+ lookup->table[i].regval))
+ imax = i;
+ else
+ imin = i;
+ }
+
+ c_n = ((regval - lookup->table[imin].regval)
+ * (lookup->table[imax].realval
+ - lookup->table[imin].realval)
+ / (lookup->table[imax].regval
+ - lookup->table[imin].regval))
+ + lookup->table[imin].realval;
+ } else if (regval < lookup->table[imin].regval)
+ c_n = 1000;
+ }
+ }
+
+ return c_n;
+}
+
+static int stv0900_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ *snr = stv0900_carr_get_quality(fe,
+ (const struct stv0900_table *)&stv0900_s2_cn);
+ *snr += 30;
+ *snr *= (16383 / 1030);
+
+ return 0;
+}
+
+static u32 stv0900_get_ber(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 ber = 10000000, i;
+ s32 dmd_state_reg;
+ s32 demod_state;
+ s32 vstatus_reg;
+ s32 prvit_field;
+ s32 pdel_status_reg;
+ s32 pdel_lock_field;
+
+ dmd_reg(dmd_state_reg, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(vstatus_reg, R0900_P1_VSTATUSVIT, R0900_P2_VSTATUSVIT);
+ dmd_reg(prvit_field, F0900_P1_PRFVIT, F0900_P2_PRFVIT);
+ dmd_reg(pdel_status_reg, R0900_P1_PDELSTATUS1, R0900_P2_PDELSTATUS1);
+ dmd_reg(pdel_lock_field, F0900_P1_PKTDELIN_LOCK,
+ F0900_P2_PKTDELIN_LOCK);
+
+ demod_state = stv0900_get_bits(i_params, dmd_state_reg);
+
+ switch (demod_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ ber = 10000000;
+ break;
+ case STV0900_DVBS_FOUND:
+ ber = 0;
+ for (i = 0; i < 5; i++) {
+ msleep(5);
+ ber += stv0900_get_err_count(i_params, 0, demod);
+ }
+
+ ber /= 5;
+ if (stv0900_get_bits(i_params, prvit_field)) {
+ ber *= 9766;
+ ber = ber >> 13;
+ }
+
+ break;
+ case STV0900_DVBS2_FOUND:
+ ber = 0;
+ for (i = 0; i < 5; i++) {
+ msleep(5);
+ ber += stv0900_get_err_count(i_params, 0, demod);
+ }
+
+ ber /= 5;
+ if (stv0900_get_bits(i_params, pdel_lock_field)) {
+ ber *= 9766;
+ ber = ber >> 13;
+ }
+
+ break;
+ }
+
+ return ber;
+}
+
+static int stv0900_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *internal = state->internal;
+
+ *ber = stv0900_get_ber(internal, state->demod);
+
+ return 0;
+}
+
+int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod, s32 time_out)
+{
+ s32 timer = 0,
+ lock = 0,
+ header_field,
+ lock_field;
+
+ enum fe_stv0900_search_state dmd_state;
+
+ dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
+ while ((timer < time_out) && (lock == 0)) {
+ dmd_state = stv0900_get_bits(i_params, header_field);
+ dprintk("Demod State = %d\n", dmd_state);
+ switch (dmd_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ lock = 0;
+ break;
+ case STV0900_DVBS2_FOUND:
+ case STV0900_DVBS_FOUND:
+ lock = stv0900_get_bits(i_params, lock_field);
+ break;
+ }
+
+ if (lock == 0)
+ msleep(10);
+
+ timer += 10;
+ }
+
+ if (lock)
+ dprintk("DEMOD LOCK OK\n");
+ else
+ dprintk("DEMOD LOCK FAIL\n");
+
+ return lock;
+}
+
+void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 regflist,
+ i;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(regflist, R0900_P1_MODCODLST0, R0900_P2_MODCODLST0);
+
+ for (i = 0; i < 16; i++)
+ stv0900_write_reg(i_params, regflist + i, 0xff);
+}
+
+void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 matype,
+ mod_code,
+ fmod,
+ reg_index,
+ field_index;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id <= 0x11) {
+ msleep(5);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ mod_code = stv0900_read_reg(i_params,
+ R0900_P1_PLHMODCOD);
+ matype = mod_code & 0x3;
+ mod_code = (mod_code & 0x7f) >> 2;
+
+ reg_index = R0900_P1_MODCODLSTF - mod_code / 2;
+ field_index = mod_code % 2;
+ break;
+ case STV0900_DEMOD_2:
+ mod_code = stv0900_read_reg(i_params,
+ R0900_P2_PLHMODCOD);
+ matype = mod_code & 0x3;
+ mod_code = (mod_code & 0x7f) >> 2;
+
+ reg_index = R0900_P2_MODCODLSTF - mod_code / 2;
+ field_index = mod_code % 2;
+ break;
+ }
+
+
+ switch (matype) {
+ case 0:
+ default:
+ fmod = 14;
+ break;
+ case 1:
+ fmod = 13;
+ break;
+ case 2:
+ fmod = 11;
+ break;
+ case 3:
+ fmod = 7;
+ break;
+ }
+
+ if ((INRANGE(STV0900_QPSK_12, mod_code, STV0900_8PSK_910))
+ && (matype <= 1)) {
+ if (field_index == 0)
+ stv0900_write_reg(i_params, reg_index,
+ 0xf0 | fmod);
+ else
+ stv0900_write_reg(i_params, reg_index,
+ (fmod << 4) | 0xf);
+ }
+ } else if (i_params->chip_id >= 0x12) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ for (reg_index = 0; reg_index < 7; reg_index++)
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST0 + reg_index, 0xff);
+
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTE, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0xcf);
+ for (reg_index = 0; reg_index < 8; reg_index++)
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST7 + reg_index, 0xcc);
+
+ break;
+ case STV0900_DEMOD_2:
+ for (reg_index = 0; reg_index < 7; reg_index++)
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST0 + reg_index, 0xff);
+
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTE, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0xcf);
+ for (reg_index = 0; reg_index < 8; reg_index++)
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST7 + reg_index, 0xcc);
+
+ break;
+ }
+
+ }
+}
+
+void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 reg_index;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST0, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLST1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_MODCODLSTF, 0x0f);
+ for (reg_index = 0; reg_index < 13; reg_index++)
+ stv0900_write_reg(i_params,
+ R0900_P1_MODCODLST2 + reg_index, 0);
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST0, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLST1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_MODCODLSTF, 0x0f);
+ for (reg_index = 0; reg_index < 13; reg_index++)
+ stv0900_write_reg(i_params,
+ R0900_P2_MODCODLST2 + reg_index, 0);
+
+ break;
+ }
+}
+
+static enum dvbfe_algo stv0900_frontend_algo(struct dvb_frontend *fe)
+{
+ return DVBFE_ALGO_CUSTOM;
+}
+
+static int stb0900_set_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk(KERN_INFO "%s(..)\n", __func__);
+
+ return 0;
+}
+
+static int stb0900_get_property(struct dvb_frontend *fe,
+ struct dtv_property *tvp)
+{
+ dprintk(KERN_INFO "%s(..)\n", __func__);
+
+ return 0;
+}
+
+void stv0900_start_search(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1f);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xaa);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+
+ if (i_params->dmd1_symbol_rate <= 5000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0x44);
+ stv0900_write_reg(i_params, R0900_P1_CFRUP1, 0x0f);
+ stv0900_write_reg(i_params, R0900_P1_CFRUP0, 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRLOW1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_CFRLOW0, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xc4);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
+
+ if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xe0);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xc0);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P1_S1S2_SEQUENTIAL, 0);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
+ if (i_params->chip_id >= 0x20) {
+ if (i_params->dmd1_symbol_rate < 2000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x39);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x40);
+ }
+
+ if (i_params->dmd1_symbol_rate < 10000000) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4c);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x4b);
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x20);
+ }
+
+ } else {
+ if (i_params->dmd1_symbol_rate < 10000000)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xef);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+ }
+
+ switch (i_params->dmd1_srch_algo) {
+ case STV0900_WARM_START:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ break;
+ case STV0900_COLD_START:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1f);
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xaa);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+
+ if (i_params->dmd2_symbol_rate <= 5000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0x44);
+ stv0900_write_reg(i_params, R0900_P2_CFRUP1, 0x0f);
+ stv0900_write_reg(i_params, R0900_P2_CFRUP0, 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRLOW1, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_CFRLOW0, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xc4);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
+ if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xe0);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xc0);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P2_S1S2_SEQUENTIAL, 0);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
+ if (i_params->chip_id >= 0x20) {
+ if (i_params->dmd2_symbol_rate < 2000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x39);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x40);
+ }
+
+ if (i_params->dmd2_symbol_rate < 10000000) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4c);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x4b);
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x20);
+ }
+
+ } else {
+ if (i_params->dmd2_symbol_rate < 10000000)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xef);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+ }
+
+ switch (i_params->dmd2_srch_algo) {
+ case STV0900_WARM_START:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ break;
+ case STV0900_COLD_START:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ break;
+ default:
+ break;
+ }
+
+ break;
+ }
+}
+
+u8 stv0900_get_optim_carr_loop(s32 srate, enum fe_stv0900_modcode modcode,
+ s32 pilot, u8 chip_id)
+{
+ u8 aclc_value = 0x29;
+ s32 i;
+ const struct stv0900_car_loop_optim *car_loop_s2;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (chip_id <= 0x12)
+ car_loop_s2 = FE_STV0900_S2CarLoop;
+ else if (chip_id == 0x20)
+ car_loop_s2 = FE_STV0900_S2CarLoopCut20;
+ else
+ car_loop_s2 = FE_STV0900_S2CarLoop;
+
+ if (modcode < STV0900_QPSK_12) {
+ i = 0;
+ while ((i < 3) && (modcode != FE_STV0900_S2LowQPCarLoopCut20[i].modcode))
+ i++;
+
+ if (i >= 3)
+ i = 2;
+ } else {
+ i = 0;
+ while ((i < 14) && (modcode != car_loop_s2[i].modcode))
+ i++;
+
+ if (i >= 14) {
+ i = 0;
+ while ((i < 11) && (modcode != FE_STV0900_S2APSKCarLoopCut20[i].modcode))
+ i++;
+
+ if (i >= 11)
+ i = 10;
+ }
+ }
+
+ if (modcode <= STV0900_QPSK_25) {
+ if (pilot) {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_20;
+ else
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_on_30;
+ } else {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_20;
+ else
+ aclc_value = FE_STV0900_S2LowQPCarLoopCut20[i].car_loop_pilots_off_30;
+ }
+
+ } else if (modcode <= STV0900_8PSK_910) {
+ if (pilot) {
+ if (srate <= 3000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_20;
+ else
+ aclc_value = car_loop_s2[i].car_loop_pilots_on_30;
+ } else {
+ if (srate <= 3000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_2;
+ else if (srate <= 7000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_5;
+ else if (srate <= 15000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_10;
+ else if (srate <= 25000000)
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_20;
+ else
+ aclc_value = car_loop_s2[i].car_loop_pilots_off_30;
+ }
+
+ } else {
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_20;
+ else
+ aclc_value = FE_STV0900_S2APSKCarLoopCut20[i].car_loop_pilots_on_30;
+ }
+
+ return aclc_value;
+}
+
+u8 stv0900_get_optim_short_carr_loop(s32 srate, enum fe_stv0900_modulation modulation, u8 chip_id)
+{
+ s32 mod_index = 0;
+
+ u8 aclc_value = 0x0b;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (modulation) {
+ case STV0900_QPSK:
+ default:
+ mod_index = 0;
+ break;
+ case STV0900_8PSK:
+ mod_index = 1;
+ break;
+ case STV0900_16APSK:
+ mod_index = 2;
+ break;
+ case STV0900_32APSK:
+ mod_index = 3;
+ break;
+ }
+
+ switch (chip_id) {
+ case 0x20:
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_20;
+ else
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut20_30;
+
+ break;
+ case 0x12:
+ default:
+ if (srate <= 3000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_2;
+ else if (srate <= 7000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_5;
+ else if (srate <= 15000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_10;
+ else if (srate <= 25000000)
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_20;
+ else
+ aclc_value = FE_STV0900_S2ShortCarLoop[mod_index].car_loop_cut12_30;
+
+ break;
+ }
+
+ return aclc_value;
+}
+
+static enum fe_stv0900_error stv0900_st_dvbs2_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_mode LDPC_Mode,
+ enum fe_stv0900_demod_num demod)
+{
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (LDPC_Mode) {
+ case STV0900_DUAL:
+ default:
+ if ((i_params->demod_mode != STV0900_DUAL)
+ || (stv0900_get_bits(i_params, F0900_DDEMOD) != 1)) {
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x1d);
+
+ i_params->demod_mode = STV0900_DUAL;
+
+ stv0900_write_bits(i_params, F0900_FRESFEC, 1);
+ stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+ }
+
+ break;
+ case STV0900_SINGLE:
+ if (demod == STV0900_DEMOD_2)
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x06);
+ else
+ stv0900_write_reg(i_params, R0900_GENCFG, 0x04);
+
+ i_params->demod_mode = STV0900_SINGLE;
+
+ stv0900_write_bits(i_params, F0900_FRESFEC, 1);
+ stv0900_write_bits(i_params, F0900_FRESFEC, 0);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+ break;
+ }
+
+ return error;
+}
+
+static enum fe_stv0900_error stv0900_init_internal(struct dvb_frontend *fe,
+ struct stv0900_init_params *p_init)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+ enum fe_stv0900_error demodError = STV0900_NO_ERROR;
+ int selosci;
+
+ struct stv0900_inode *temp_int = find_inode(state->i2c_adap,
+ state->config->demod_address);
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (temp_int != NULL) {
+ state->internal = temp_int->internal;
+ (state->internal->dmds_used)++;
+ dprintk(KERN_INFO "%s: Find Internal Structure!\n", __func__);
+ return STV0900_NO_ERROR;
+ } else {
+ state->internal = kmalloc(sizeof(struct stv0900_internal), GFP_KERNEL);
+ temp_int = append_internal(state->internal);
+ state->internal->dmds_used = 1;
+ state->internal->i2c_adap = state->i2c_adap;
+ state->internal->i2c_addr = state->config->demod_address;
+ state->internal->clkmode = state->config->clkmode;
+ state->internal->errs = STV0900_NO_ERROR;
+ dprintk(KERN_INFO "%s: Create New Internal Structure!\n", __func__);
+ }
+
+ if (state->internal != NULL) {
+ demodError = stv0900_initialize(state->internal);
+ if (demodError == STV0900_NO_ERROR) {
+ error = STV0900_NO_ERROR;
+ } else {
+ if (demodError == STV0900_INVALID_HANDLE)
+ error = STV0900_INVALID_HANDLE;
+ else
+ error = STV0900_I2C_ERROR;
+ }
+
+ if (state->internal != NULL) {
+ if (error == STV0900_NO_ERROR) {
+ state->internal->demod_mode = p_init->demod_mode;
+
+ stv0900_st_dvbs2_single(state->internal, state->internal->demod_mode, STV0900_DEMOD_1);
+
+ state->internal->chip_id = stv0900_read_reg(state->internal, R0900_MID);
+ state->internal->rolloff = p_init->rolloff;
+ state->internal->quartz = p_init->dmd_ref_clk;
+
+ stv0900_write_bits(state->internal, F0900_P1_ROLLOFF_CONTROL, p_init->rolloff);
+ stv0900_write_bits(state->internal, F0900_P2_ROLLOFF_CONTROL, p_init->rolloff);
+
+ stv0900_set_ts_parallel_serial(state->internal, p_init->path1_ts_clock, p_init->path2_ts_clock);
+ stv0900_write_bits(state->internal, F0900_P1_TUN_MADDRESS, p_init->tun1_maddress);
+ switch (p_init->tuner1_adc) {
+ case 1:
+ stv0900_write_reg(state->internal, R0900_TSTTNR1, 0x26);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(state->internal, F0900_P2_TUN_MADDRESS, p_init->tun2_maddress);
+ switch (p_init->tuner2_adc) {
+ case 1:
+ stv0900_write_reg(state->internal, R0900_TSTTNR3, 0x26);
+ break;
+ default:
+ break;
+ }
+
+ stv0900_write_bits(state->internal, F0900_P1_TUN_IQSWAP, p_init->tun1_iq_inversion);
+ stv0900_write_bits(state->internal, F0900_P2_TUN_IQSWAP, p_init->tun2_iq_inversion);
+ stv0900_set_mclk(state->internal, 135000000);
+ msleep(3);
+
+ switch (state->internal->clkmode) {
+ case 0:
+ case 2:
+ stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | state->internal->clkmode);
+ break;
+ default:
+ selosci = 0x02 & stv0900_read_reg(state->internal, R0900_SYNTCTRL);
+ stv0900_write_reg(state->internal, R0900_SYNTCTRL, 0x20 | selosci);
+ break;
+ }
+ msleep(3);
+
+ state->internal->mclk = stv0900_get_mclk_freq(state->internal, state->internal->quartz);
+ if (state->internal->errs)
+ error = STV0900_I2C_ERROR;
+ }
+ } else {
+ error = STV0900_INVALID_HANDLE;
+ }
+ }
+
+ return error;
+}
+
+static int stv0900_status(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ enum fe_stv0900_search_state demod_state;
+ s32 mode_field, delin_field, lock_field, fifo_field, lockedvit_field;
+ int locked = FALSE;
+
+ dmd_reg(mode_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(lock_field, F0900_P1_LOCK_DEFINITIF, F0900_P2_LOCK_DEFINITIF);
+ dmd_reg(delin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
+ dmd_reg(fifo_field, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
+ dmd_reg(lockedvit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
+
+ demod_state = stv0900_get_bits(i_params, mode_field);
+ switch (demod_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ locked = FALSE;
+ break;
+ case STV0900_DVBS2_FOUND:
+ locked = stv0900_get_bits(i_params, lock_field) &&
+ stv0900_get_bits(i_params, delin_field) &&
+ stv0900_get_bits(i_params, fifo_field);
+ break;
+ case STV0900_DVBS_FOUND:
+ locked = stv0900_get_bits(i_params, lock_field) &&
+ stv0900_get_bits(i_params, lockedvit_field) &&
+ stv0900_get_bits(i_params, fifo_field);
+ break;
+ }
+
+ return locked;
+}
+
+static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+
+ struct stv0900_search_params p_search;
+ struct stv0900_signal_info p_result;
+
+ enum fe_stv0900_error error = STV0900_NO_ERROR;
+
+ dprintk(KERN_INFO "%s: ", __func__);
+
+ p_result.locked = FALSE;
+ p_search.path = state->demod;
+ p_search.frequency = c->frequency;
+ p_search.symbol_rate = c->symbol_rate;
+ p_search.search_range = 10000000;
+ p_search.fec = STV0900_FEC_UNKNOWN;
+ p_search.standard = STV0900_AUTO_SEARCH;
+ p_search.iq_inversion = STV0900_IQ_AUTO;
+ p_search.search_algo = STV0900_BLIND_SEARCH;
+
+ if ((INRANGE(100000, p_search.symbol_rate, 70000000)) &&
+ (INRANGE(100000, p_search.search_range, 50000000))) {
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_srch_standard = p_search.standard;
+ i_params->dmd1_symbol_rate = p_search.symbol_rate;
+ i_params->dmd1_srch_range = p_search.search_range;
+ i_params->tuner1_freq = p_search.frequency;
+ i_params->dmd1_srch_algo = p_search.search_algo;
+ i_params->dmd1_srch_iq_inv = p_search.iq_inversion;
+ i_params->dmd1_fec = p_search.fec;
+ break;
+
+ case STV0900_DEMOD_2:
+ i_params->dmd2_srch_stndrd = p_search.standard;
+ i_params->dmd2_symbol_rate = p_search.symbol_rate;
+ i_params->dmd2_srch_range = p_search.search_range;
+ i_params->tuner2_freq = p_search.frequency;
+ i_params->dmd2_srch_algo = p_search.search_algo;
+ i_params->dmd2_srch_iq_inv = p_search.iq_inversion;
+ i_params->dmd2_fec = p_search.fec;
+ break;
+ }
+
+ if ((stv0900_algo(fe) == STV0900_RANGEOK) &&
+ (i_params->errs == STV0900_NO_ERROR)) {
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ default:
+ p_result.locked = i_params->dmd1_rslts.locked;
+ p_result.standard = i_params->dmd1_rslts.standard;
+ p_result.frequency = i_params->dmd1_rslts.frequency;
+ p_result.symbol_rate = i_params->dmd1_rslts.symbol_rate;
+ p_result.fec = i_params->dmd1_rslts.fec;
+ p_result.modcode = i_params->dmd1_rslts.modcode;
+ p_result.pilot = i_params->dmd1_rslts.pilot;
+ p_result.frame_length = i_params->dmd1_rslts.frame_length;
+ p_result.spectrum = i_params->dmd1_rslts.spectrum;
+ p_result.rolloff = i_params->dmd1_rslts.rolloff;
+ p_result.modulation = i_params->dmd1_rslts.modulation;
+ break;
+ case STV0900_DEMOD_2:
+ p_result.locked = i_params->dmd2_rslts.locked;
+ p_result.standard = i_params->dmd2_rslts.standard;
+ p_result.frequency = i_params->dmd2_rslts.frequency;
+ p_result.symbol_rate = i_params->dmd2_rslts.symbol_rate;
+ p_result.fec = i_params->dmd2_rslts.fec;
+ p_result.modcode = i_params->dmd2_rslts.modcode;
+ p_result.pilot = i_params->dmd2_rslts.pilot;
+ p_result.frame_length = i_params->dmd2_rslts.frame_length;
+ p_result.spectrum = i_params->dmd2_rslts.spectrum;
+ p_result.rolloff = i_params->dmd2_rslts.rolloff;
+ p_result.modulation = i_params->dmd2_rslts.modulation;
+ break;
+ }
+
+ } else {
+ p_result.locked = FALSE;
+ switch (p_search.path) {
+ case STV0900_DEMOD_1:
+ switch (i_params->dmd1_err) {
+ case STV0900_I2C_ERROR:
+ error = STV0900_I2C_ERROR;
+ break;
+ case STV0900_NO_ERROR:
+ default:
+ error = STV0900_SEARCH_FAILED;
+ break;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_err) {
+ case STV0900_I2C_ERROR:
+ error = STV0900_I2C_ERROR;
+ break;
+ case STV0900_NO_ERROR:
+ default:
+ error = STV0900_SEARCH_FAILED;
+ break;
+ }
+ break;
+ }
+ }
+
+ } else
+ error = STV0900_BAD_PARAMETER;
+
+ if ((p_result.locked == TRUE) && (error == STV0900_NO_ERROR)) {
+ dprintk(KERN_INFO "Search Success\n");
+ return DVBFE_ALGO_SEARCH_SUCCESS;
+ } else {
+ dprintk(KERN_INFO "Search Fail\n");
+ return DVBFE_ALGO_SEARCH_FAILED;
+ }
+
+ return DVBFE_ALGO_SEARCH_ERROR;
+}
+
+static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ dprintk("%s: ", __func__);
+
+ if ((stv0900_status(state->internal, state->demod)) == TRUE) {
+ dprintk("DEMOD LOCK OK\n");
+ *status = FE_HAS_CARRIER
+ | FE_HAS_VITERBI
+ | FE_HAS_SYNC
+ | FE_HAS_LOCK;
+ } else
+ dprintk("DEMOD LOCK FAIL\n");
+
+ return 0;
+}
+
+static int stv0900_track(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ return 0;
+}
+
+static int stv0900_stop_ts(struct dvb_frontend *fe, int stop_ts)
+{
+
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 rst_field;
+
+ dmd_reg(rst_field, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
+
+ if (stop_ts == TRUE)
+ stv0900_write_bits(i_params, rst_field, 1);
+ else
+ stv0900_write_bits(i_params, rst_field, 0);
+
+ return 0;
+}
+
+static int stv0900_diseqc_init(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field, reset_field;
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
+
+ stv0900_write_bits(i_params, mode_field, state->config->diseqc_mode);
+ stv0900_write_bits(i_params, reset_field, 1);
+ stv0900_write_bits(i_params, reset_field, 0);
+
+ return 0;
+}
+
+static int stv0900_init(struct dvb_frontend *fe)
+{
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ stv0900_stop_ts(fe, 1);
+ stv0900_diseqc_init(fe);
+
+ return 0;
+}
+
+static int stv0900_diseqc_send(struct stv0900_internal *i_params , u8 *Data,
+ u32 NbData, enum fe_stv0900_demod_num demod)
+{
+ s32 i = 0;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 1);
+ while (i < NbData) {
+ while (stv0900_get_bits(i_params, F0900_P1_FIFO_FULL))
+ ;/* checkpatch complains */
+ stv0900_write_reg(i_params, R0900_P1_DISTXDATA, Data[i]);
+ i++;
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_DIS_PRECHARGE, 0);
+ i = 0;
+ while ((stv0900_get_bits(i_params, F0900_P1_TX_IDLE) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 1);
+
+ while (i < NbData) {
+ while (stv0900_get_bits(i_params, F0900_P2_FIFO_FULL))
+ ;/* checkpatch complains */
+ stv0900_write_reg(i_params, R0900_P2_DISTXDATA, Data[i]);
+ i++;
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_DIS_PRECHARGE, 0);
+ i = 0;
+ while ((stv0900_get_bits(i_params, F0900_P2_TX_IDLE) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_send_master_cmd(struct dvb_frontend *fe,
+ struct dvb_diseqc_master_cmd *cmd)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ return stv0900_diseqc_send(state->internal,
+ cmd->msg,
+ cmd->msg_len,
+ state->demod);
+}
+
+static int stv0900_send_burst(struct dvb_frontend *fe, fe_sec_mini_cmd_t burst)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field;
+ u32 diseqc_fifo;
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(diseqc_fifo, R0900_P1_DISTXDATA, R0900_P2_DISTXDATA);
+
+ switch (burst) {
+ case SEC_MINI_A:
+ stv0900_write_bits(i_params, mode_field, 3);/* Unmodulated */
+ stv0900_write_reg(i_params, diseqc_fifo, 0x00);
+ break;
+ case SEC_MINI_B:
+ stv0900_write_bits(i_params, mode_field, 2);/* Modulated */
+ stv0900_write_reg(i_params, diseqc_fifo, 0xff);
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_recv_slave_reply(struct dvb_frontend *fe,
+ struct dvb_diseqc_slave_reply *reply)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ s32 i = 0;
+
+ switch (state->demod) {
+ case STV0900_DEMOD_1:
+ default:
+ reply->msg_len = 0;
+
+ while ((stv0900_get_bits(i_params, F0900_P1_RX_END) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ if (stv0900_get_bits(i_params, F0900_P1_RX_END)) {
+ reply->msg_len = stv0900_get_bits(i_params, F0900_P1_FIFO_BYTENBR);
+
+ for (i = 0; i < reply->msg_len; i++)
+ reply->msg[i] = stv0900_read_reg(i_params, R0900_P1_DISRXDATA);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ reply->msg_len = 0;
+
+ while ((stv0900_get_bits(i_params, F0900_P2_RX_END) != 1) && (i < 10)) {
+ msleep(10);
+ i++;
+ }
+
+ if (stv0900_get_bits(i_params, F0900_P2_RX_END)) {
+ reply->msg_len = stv0900_get_bits(i_params, F0900_P2_FIFO_BYTENBR);
+
+ for (i = 0; i < reply->msg_len; i++)
+ reply->msg[i] = stv0900_read_reg(i_params, R0900_P2_DISRXDATA);
+ }
+ break;
+ }
+
+ return 0;
+}
+
+static int stv0900_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ s32 mode_field, reset_field;
+
+ dprintk(KERN_INFO "%s: %s\n", __func__, ((tone == 0) ? "Off" : "On"));
+
+ dmd_reg(mode_field, F0900_P1_DISTX_MODE, F0900_P2_DISTX_MODE);
+ dmd_reg(reset_field, F0900_P1_DISEQC_RESET, F0900_P2_DISEQC_RESET);
+
+ if (tone) {
+ /*Set the DiseqC mode to 22Khz continues tone*/
+ stv0900_write_bits(i_params, mode_field, 0);
+ stv0900_write_bits(i_params, reset_field, 1);
+ /*release DiseqC reset to enable the 22KHz tone*/
+ stv0900_write_bits(i_params, reset_field, 0);
+ } else {
+ stv0900_write_bits(i_params, mode_field, 0);
+ /*maintain the DiseqC reset to disable the 22KHz tone*/
+ stv0900_write_bits(i_params, reset_field, 1);
+ }
+
+ return 0;
+}
+
+static void stv0900_release(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if ((--(state->internal->dmds_used)) <= 0) {
+
+ dprintk(KERN_INFO "%s: Actually removing\n", __func__);
+
+ remove_inode(state->internal);
+ kfree(state->internal);
+ }
+
+ kfree(state);
+}
+
+static struct dvb_frontend_ops stv0900_ops = {
+
+ .info = {
+ .name = "STV0900 frontend",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 125,
+ .frequency_tolerance = 0,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = 500,
+ .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_QPSK |
+ FE_CAN_2G_MODULATION |
+ FE_CAN_FEC_AUTO
+ },
+ .release = stv0900_release,
+ .init = stv0900_init,
+ .get_frontend_algo = stv0900_frontend_algo,
+ .i2c_gate_ctrl = stv0900_i2c_gate_ctrl,
+ .diseqc_send_master_cmd = stv0900_send_master_cmd,
+ .diseqc_send_burst = stv0900_send_burst,
+ .diseqc_recv_slave_reply = stv0900_recv_slave_reply,
+ .set_tone = stv0900_set_tone,
+ .set_property = stb0900_set_property,
+ .get_property = stb0900_get_property,
+ .search = stv0900_search,
+ .track = stv0900_track,
+ .read_status = stv0900_read_status,
+ .read_ber = stv0900_read_ber,
+ .read_signal_strength = stv0900_read_signal_strength,
+ .read_snr = stv0900_read_snr,
+};
+
+struct dvb_frontend *stv0900_attach(const struct stv0900_config *config,
+ struct i2c_adapter *i2c,
+ int demod)
+{
+ struct stv0900_state *state = NULL;
+ struct stv0900_init_params init_params;
+ enum fe_stv0900_error err_stv0900;
+
+ state = kzalloc(sizeof(struct stv0900_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ state->demod = demod;
+ state->config = config;
+ state->i2c_adap = i2c;
+
+ memcpy(&state->frontend.ops, &stv0900_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ switch (demod) {
+ case 0:
+ case 1:
+ init_params.dmd_ref_clk = config->xtal;
+ init_params.demod_mode = STV0900_DUAL;
+ init_params.rolloff = STV0900_35;
+ init_params.path1_ts_clock = config->path1_mode;
+ init_params.tun1_maddress = config->tun1_maddress;
+ init_params.tun1_iq_inversion = STV0900_IQ_NORMAL;
+ init_params.tuner1_adc = config->tun1_adc;
+ init_params.path2_ts_clock = config->path2_mode;
+ init_params.tun2_maddress = config->tun2_maddress;
+ init_params.tuner2_adc = config->tun2_adc;
+ init_params.tun2_iq_inversion = STV0900_IQ_SWAPPED;
+
+ err_stv0900 = stv0900_init_internal(&state->frontend,
+ &init_params);
+
+ if (err_stv0900)
+ goto error;
+
+ break;
+ default:
+ goto error;
+ break;
+ }
+
+ dprintk("%s: Attaching STV0900 demodulator(%d) \n", __func__, demod);
+ return &state->frontend;
+
+error:
+ dprintk("%s: Failed to attach STV0900 demodulator(%d) \n",
+ __func__, demod);
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(stv0900_attach);
+
+MODULE_PARM_DESC(debug, "Set debug");
+
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_DESCRIPTION("ST STV0900 frontend");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0900_init.h b/drivers/media/dvb/frontends/stv0900_init.h
new file mode 100644
index 00000000000..ff388b47a4e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_init.h
@@ -0,0 +1,441 @@
+/*
+ * stv0900_init.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_INIT_H
+#define STV0900_INIT_H
+
+#include "stv0900_priv.h"
+
+/* DVBS2 C/N Look-Up table */
+static const struct stv0900_table stv0900_s2_cn = {
+ 55,
+ {
+ { -30, 13348 }, /*C/N=-3dB*/
+ { -20, 12640 }, /*C/N=-2dB*/
+ { -10, 11883 }, /*C/N=-1dB*/
+ { 0, 11101 }, /*C/N=-0dB*/
+ { 5, 10718 }, /*C/N=0.5dB*/
+ { 10, 10339 }, /*C/N=1.0dB*/
+ { 15, 9947 }, /*C/N=1.5dB*/
+ { 20, 9552 }, /*C/N=2.0dB*/
+ { 25, 9183 }, /*C/N=2.5dB*/
+ { 30, 8799 }, /*C/N=3.0dB*/
+ { 35, 8422 }, /*C/N=3.5dB*/
+ { 40, 8062 }, /*C/N=4.0dB*/
+ { 45, 7707 }, /*C/N=4.5dB*/
+ { 50, 7353 }, /*C/N=5.0dB*/
+ { 55, 7025 }, /*C/N=5.5dB*/
+ { 60, 6684 }, /*C/N=6.0dB*/
+ { 65, 6331 }, /*C/N=6.5dB*/
+ { 70, 6036 }, /*C/N=7.0dB*/
+ { 75, 5727 }, /*C/N=7.5dB*/
+ { 80, 5437 }, /*C/N=8.0dB*/
+ { 85, 5164 }, /*C/N=8.5dB*/
+ { 90, 4902 }, /*C/N=9.0dB*/
+ { 95, 4653 }, /*C/N=9.5dB*/
+ { 100, 4408 }, /*C/N=10.0dB*/
+ { 105, 4187 }, /*C/N=10.5dB*/
+ { 110, 3961 }, /*C/N=11.0dB*/
+ { 115, 3751 }, /*C/N=11.5dB*/
+ { 120, 3558 }, /*C/N=12.0dB*/
+ { 125, 3368 }, /*C/N=12.5dB*/
+ { 130, 3191 }, /*C/N=13.0dB*/
+ { 135, 3017 }, /*C/N=13.5dB*/
+ { 140, 2862 }, /*C/N=14.0dB*/
+ { 145, 2710 }, /*C/N=14.5dB*/
+ { 150, 2565 }, /*C/N=15.0dB*/
+ { 160, 2300 }, /*C/N=16.0dB*/
+ { 170, 2058 }, /*C/N=17.0dB*/
+ { 180, 1849 }, /*C/N=18.0dB*/
+ { 190, 1663 }, /*C/N=19.0dB*/
+ { 200, 1495 }, /*C/N=20.0dB*/
+ { 210, 1349 }, /*C/N=21.0dB*/
+ { 220, 1222 }, /*C/N=22.0dB*/
+ { 230, 1110 }, /*C/N=23.0dB*/
+ { 240, 1011 }, /*C/N=24.0dB*/
+ { 250, 925 }, /*C/N=25.0dB*/
+ { 260, 853 }, /*C/N=26.0dB*/
+ { 270, 789 }, /*C/N=27.0dB*/
+ { 280, 734 }, /*C/N=28.0dB*/
+ { 290, 690 }, /*C/N=29.0dB*/
+ { 300, 650 }, /*C/N=30.0dB*/
+ { 310, 619 }, /*C/N=31.0dB*/
+ { 320, 593 }, /*C/N=32.0dB*/
+ { 330, 571 }, /*C/N=33.0dB*/
+ { 400, 498 }, /*C/N=40.0dB*/
+ { 450, 484 }, /*C/N=45.0dB*/
+ { 500, 481 } /*C/N=50.0dB*/
+ }
+};
+
+/* RF level C/N Look-Up table */
+static const struct stv0900_table stv0900_rf = {
+ 14,
+ {
+ { -5, 0xCAA1 }, /*-5dBm*/
+ { -10, 0xC229 }, /*-10dBm*/
+ { -15, 0xBB08 }, /*-15dBm*/
+ { -20, 0xB4BC }, /*-20dBm*/
+ { -25, 0xAD5A }, /*-25dBm*/
+ { -30, 0xA298 }, /*-30dBm*/
+ { -35, 0x98A8 }, /*-35dBm*/
+ { -40, 0x8389 }, /*-40dBm*/
+ { -45, 0x59BE }, /*-45dBm*/
+ { -50, 0x3A14 }, /*-50dBm*/
+ { -55, 0x2D11 }, /*-55dBm*/
+ { -60, 0x210D }, /*-60dBm*/
+ { -65, 0xA14F }, /*-65dBm*/
+ { -70, 0x7AA } /*-70dBm*/
+ }
+};
+
+struct stv0900_car_loop_optim {
+ enum fe_stv0900_modcode modcode;
+ u8 car_loop_pilots_on_2;
+ u8 car_loop_pilots_off_2;
+ u8 car_loop_pilots_on_5;
+ u8 car_loop_pilots_off_5;
+ u8 car_loop_pilots_on_10;
+ u8 car_loop_pilots_off_10;
+ u8 car_loop_pilots_on_20;
+ u8 car_loop_pilots_off_20;
+ u8 car_loop_pilots_on_30;
+ u8 car_loop_pilots_off_30;
+
+};
+
+struct stv0900_short_frames_car_loop_optim {
+ enum fe_stv0900_modulation modulation;
+ u8 car_loop_cut12_2; /* Cut 1.2, SR<=3msps */
+ u8 car_loop_cut20_2; /* Cut 2.0, SR<3msps */
+ u8 car_loop_cut12_5; /* Cut 1.2, 3<SR<=7msps */
+ u8 car_loop_cut20_5; /* Cut 2.0, 3<SR<=7msps */
+ u8 car_loop_cut12_10; /* Cut 1.2, 7<SR<=15msps */
+ u8 car_loop_cut20_10; /* Cut 2.0, 7<SR<=15msps */
+ u8 car_loop_cut12_20; /* Cut 1.2, 10<SR<=25msps */
+ u8 car_loop_cut20_20; /* Cut 2.0, 10<SR<=25msps */
+ u8 car_loop_cut12_30; /* Cut 1.2, 25<SR<=45msps */
+ u8 car_loop_cut20_30; /* Cut 2.0, 10<SR<=45msps */
+
+};
+
+/* Cut 1.x Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoop[14] = {
+ /*Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_12, 0x1C, 0x0D, 0x1B, 0x2C, 0x3A, 0x1C, 0x2A, 0x3B, 0x2A, 0x1B },
+ { STV0900_QPSK_35, 0x2C, 0x0D, 0x2B, 0x2C, 0x3A, 0x0C, 0x3A, 0x2B, 0x2A, 0x0B },
+ { STV0900_QPSK_23, 0x2C, 0x0D, 0x2B, 0x2C, 0x0B, 0x0C, 0x3A, 0x1B, 0x2A, 0x3A },
+ { STV0900_QPSK_34, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_45, 0x3C, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_56, 0x0D, 0x0D, 0x3B, 0x1C, 0x0B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_89, 0x0D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_QPSK_910, 0x1D, 0x0D, 0x3B, 0x1C, 0x1B, 0x3B, 0x3A, 0x0B, 0x2A, 0x3A },
+ { STV0900_8PSK_35, 0x29, 0x3B, 0x09, 0x2B, 0x38, 0x0B, 0x18, 0x1A, 0x08, 0x0A },
+ { STV0900_8PSK_23, 0x0A, 0x3B, 0x29, 0x2B, 0x19, 0x0B, 0x38, 0x1A, 0x18, 0x0A },
+ { STV0900_8PSK_34, 0x3A, 0x3B, 0x2A, 0x2B, 0x39, 0x0B, 0x19, 0x1A, 0x38, 0x0A },
+ { STV0900_8PSK_56, 0x1B, 0x3B, 0x0B, 0x2B, 0x1A, 0x0B, 0x39, 0x1A, 0x19, 0x0A },
+ { STV0900_8PSK_89, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 },
+ { STV0900_8PSK_910, 0x3B, 0x3B, 0x0B, 0x2B, 0x2A, 0x0B, 0x39, 0x1A, 0x29, 0x39 }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/2 to 8PSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2CarLoopCut20[14] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_12, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x1E },
+ { STV0900_QPSK_35, 0x2F, 0x3F, 0x2E, 0x2F, 0x3D, 0x0F, 0x0E, 0x2E, 0x3D, 0x0E },
+ { STV0900_QPSK_23, 0x2F, 0x3F, 0x2E, 0x2F, 0x0E, 0x0F, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_34, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_45, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_56, 0x3F, 0x3F, 0x3E, 0x1F, 0x0E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_89, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_QPSK_910, 0x3F, 0x3F, 0x3E, 0x1F, 0x1E, 0x3E, 0x0E, 0x1E, 0x3D, 0x3D },
+ { STV0900_8PSK_35, 0x3c, 0x0c, 0x1c, 0x3b, 0x0c, 0x3b, 0x2b, 0x2b, 0x1b, 0x2b },
+ { STV0900_8PSK_23, 0x1d, 0x0c, 0x3c, 0x0c, 0x2c, 0x3b, 0x0c, 0x2b, 0x2b, 0x2b },
+ { STV0900_8PSK_34, 0x0e, 0x1c, 0x3d, 0x0c, 0x0d, 0x3b, 0x2c, 0x3b, 0x0c, 0x2b },
+ { STV0900_8PSK_56, 0x2e, 0x3e, 0x1e, 0x2e, 0x2d, 0x1e, 0x3c, 0x2d, 0x2c, 0x1d },
+ { STV0900_8PSK_89, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x0d, 0x2d, 0x3c, 0x1d },
+ { STV0900_8PSK_910, 0x3e, 0x3e, 0x1e, 0x2e, 0x3d, 0x1e, 0x1d, 0x2d, 0x0d, 0x1d }
+};
+
+
+
+/* Cut 2.0 Tracking carrier loop carrier 16APSK 2/3 to 32APSK 9/10 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2APSKCarLoopCut20[11] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_16APSK_23, 0x0C, 0x0C, 0x0C, 0x0C, 0x1D, 0x0C, 0x3C, 0x0C, 0x2C, 0x0C },
+ { STV0900_16APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x0C, 0x2D, 0x0C, 0x1D, 0x0C },
+ { STV0900_16APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
+ { STV0900_16APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x0C, 0x3D, 0x0C, 0x2D, 0x0C },
+ { STV0900_16APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
+ { STV0900_16APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x2E, 0x0C, 0x0E, 0x0C, 0x3D, 0x0C },
+ { STV0900_32APSK_34, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_45, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_56, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_89, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C },
+ { STV0900_32APSK_910, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier QPSK 1/4 to QPSK 2/5 long Frame */
+static const struct stv0900_car_loop_optim FE_STV0900_S2LowQPCarLoopCut20[3] = {
+ /* Modcod 2MPon 2MPoff 5MPon 5MPoff 10MPon 10MPoff 20MPon 20MPoff 30MPon 30MPoff */
+ { STV0900_QPSK_14, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x2D, 0x1F, 0x3D, 0x3E },
+ { STV0900_QPSK_13, 0x0F, 0x3F, 0x0E, 0x3F, 0x2D, 0x2F, 0x3D, 0x0F, 0x3D, 0x2E },
+ { STV0900_QPSK_25, 0x1F, 0x3F, 0x1E, 0x3F, 0x3D, 0x1F, 0x3D, 0x3E, 0x3D, 0x2E }
+};
+
+
+/* Cut 2.0 Tracking carrier loop carrier short Frame, cut 1.2 and 2.0 */
+static const struct stv0900_short_frames_car_loop_optim FE_STV0900_S2ShortCarLoop[4] = {
+ /*Mod 2M_cut1.2 2M_cut2.0 5M_cut1.2 5M_cut2.0 10M_cut1.2 10M_cut2.0 20M_cut1.2 20M_cut2.0 30M_cut1.2 30M_cut2.0 */
+ { STV0900_QPSK, 0x3C, 0x2F, 0x2B, 0x2E, 0x0B, 0x0E, 0x3A, 0x0E, 0x2A, 0x3D },
+ { STV0900_8PSK, 0x0B, 0x3E, 0x2A, 0x0E, 0x0A, 0x2D, 0x19, 0x0D, 0x09, 0x3C },
+ { STV0900_16APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D },
+ { STV0900_32APSK, 0x1B, 0x1E, 0x1B, 0x1E, 0x1B, 0x1E, 0x3A, 0x3D, 0x2A, 0x2D }
+};
+
+static const u16 STV0900_InitVal[182][2] = {
+ { R0900_OUTCFG , 0x00 },
+ { R0900_MODECFG , 0xff },
+ { R0900_AGCRF1CFG , 0x11 },
+ { R0900_AGCRF2CFG , 0x13 },
+ { R0900_TSGENERAL1X , 0x14 },
+ { R0900_TSTTNR2 , 0x21 },
+ { R0900_TSTTNR4 , 0x21 },
+ { R0900_P2_DISTXCTL , 0x22 },
+ { R0900_P2_F22TX , 0xc0 },
+ { R0900_P2_F22RX , 0xc0 },
+ { R0900_P2_DISRXCTL , 0x00 },
+ { R0900_P2_TNRSTEPS , 0x87 },
+ { R0900_P2_TNRGAIN , 0x09 },
+ { R0900_P2_DMDCFGMD , 0xF9 },
+ { R0900_P2_DEMOD , 0x08 },
+ { R0900_P2_DMDCFG3 , 0xc4 },
+ { R0900_P2_CARFREQ , 0xed },
+ { R0900_P2_TNRCFG2 , 0x02 },
+ { R0900_P2_TNRCFG3 , 0x02 },
+ { R0900_P2_LDT , 0xd0 },
+ { R0900_P2_LDT2 , 0xb8 },
+ { R0900_P2_TMGCFG , 0xd2 },
+ { R0900_P2_TMGTHRISE , 0x20 },
+ { R0900_P2_TMGTHFALL , 0x00 },
+ { R0900_P2_FECSPY , 0x88 },
+ { R0900_P2_FSPYDATA , 0x3a },
+ { R0900_P2_FBERCPT4 , 0x00 },
+ { R0900_P2_FSPYBER , 0x10 },
+ { R0900_P2_ERRCTRL1 , 0x35 },
+ { R0900_P2_ERRCTRL2 , 0xc1 },
+ { R0900_P2_CFRICFG , 0xf8 },
+ { R0900_P2_NOSCFG , 0x1c },
+ { R0900_P2_DMDT0M , 0x20 },
+ { R0900_P2_CORRELMANT , 0x70 },
+ { R0900_P2_CORRELABS , 0x88 },
+ { R0900_P2_AGC2O , 0x5b },
+ { R0900_P2_AGC2REF , 0x38 },
+ { R0900_P2_CARCFG , 0xe4 },
+ { R0900_P2_ACLC , 0x1A },
+ { R0900_P2_BCLC , 0x09 },
+ { R0900_P2_CARHDR , 0x08 },
+ { R0900_P2_KREFTMG , 0xc1 },
+ { R0900_P2_SFRUPRATIO , 0xf0 },
+ { R0900_P2_SFRLOWRATIO , 0x70 },
+ { R0900_P2_SFRSTEP , 0x58 },
+ { R0900_P2_TMGCFG2 , 0x01 },
+ { R0900_P2_CAR2CFG , 0x26 },
+ { R0900_P2_BCLC2S2Q , 0x86 },
+ { R0900_P2_BCLC2S28 , 0x86 },
+ { R0900_P2_SMAPCOEF7 , 0x77 },
+ { R0900_P2_SMAPCOEF6 , 0x85 },
+ { R0900_P2_SMAPCOEF5 , 0x77 },
+ { R0900_P2_TSCFGL , 0x20 },
+ { R0900_P2_DMDCFG2 , 0x3b },
+ { R0900_P2_MODCODLST0 , 0xff },
+ { R0900_P2_MODCODLST1 , 0xff },
+ { R0900_P2_MODCODLST2 , 0xff },
+ { R0900_P2_MODCODLST3 , 0xff },
+ { R0900_P2_MODCODLST4 , 0xff },
+ { R0900_P2_MODCODLST5 , 0xff },
+ { R0900_P2_MODCODLST6 , 0xff },
+ { R0900_P2_MODCODLST7 , 0xcc },
+ { R0900_P2_MODCODLST8 , 0xcc },
+ { R0900_P2_MODCODLST9 , 0xcc },
+ { R0900_P2_MODCODLSTA , 0xcc },
+ { R0900_P2_MODCODLSTB , 0xcc },
+ { R0900_P2_MODCODLSTC , 0xcc },
+ { R0900_P2_MODCODLSTD , 0xcc },
+ { R0900_P2_MODCODLSTE , 0xcc },
+ { R0900_P2_MODCODLSTF , 0xcf },
+ { R0900_P1_DISTXCTL , 0x22 },
+ { R0900_P1_F22TX , 0xc0 },
+ { R0900_P1_F22RX , 0xc0 },
+ { R0900_P1_DISRXCTL , 0x00 },
+ { R0900_P1_TNRSTEPS , 0x87 },
+ { R0900_P1_TNRGAIN , 0x09 },
+ { R0900_P1_DMDCFGMD , 0xf9 },
+ { R0900_P1_DEMOD , 0x08 },
+ { R0900_P1_DMDCFG3 , 0xc4 },
+ { R0900_P1_DMDT0M , 0x20 },
+ { R0900_P1_CARFREQ , 0xed },
+ { R0900_P1_TNRCFG2 , 0x82 },
+ { R0900_P1_TNRCFG3 , 0x02 },
+ { R0900_P1_LDT , 0xd0 },
+ { R0900_P1_LDT2 , 0xb8 },
+ { R0900_P1_TMGCFG , 0xd2 },
+ { R0900_P1_TMGTHRISE , 0x20 },
+ { R0900_P1_TMGTHFALL , 0x00 },
+ { R0900_P1_SFRUPRATIO , 0xf0 },
+ { R0900_P1_SFRLOWRATIO , 0x70 },
+ { R0900_P1_TSCFGL , 0x20 },
+ { R0900_P1_FECSPY , 0x88 },
+ { R0900_P1_FSPYDATA , 0x3a },
+ { R0900_P1_FBERCPT4 , 0x00 },
+ { R0900_P1_FSPYBER , 0x10 },
+ { R0900_P1_ERRCTRL1 , 0x35 },
+ { R0900_P1_ERRCTRL2 , 0xc1 },
+ { R0900_P1_CFRICFG , 0xf8 },
+ { R0900_P1_NOSCFG , 0x1c },
+ { R0900_P1_CORRELMANT , 0x70 },
+ { R0900_P1_CORRELABS , 0x88 },
+ { R0900_P1_AGC2O , 0x5b },
+ { R0900_P1_AGC2REF , 0x38 },
+ { R0900_P1_CARCFG , 0xe4 },
+ { R0900_P1_ACLC , 0x1A },
+ { R0900_P1_BCLC , 0x09 },
+ { R0900_P1_CARHDR , 0x08 },
+ { R0900_P1_KREFTMG , 0xc1 },
+ { R0900_P1_SFRSTEP , 0x58 },
+ { R0900_P1_TMGCFG2 , 0x01 },
+ { R0900_P1_CAR2CFG , 0x26 },
+ { R0900_P1_BCLC2S2Q , 0x86 },
+ { R0900_P1_BCLC2S28 , 0x86 },
+ { R0900_P1_SMAPCOEF7 , 0x77 },
+ { R0900_P1_SMAPCOEF6 , 0x85 },
+ { R0900_P1_SMAPCOEF5 , 0x77 },
+ { R0900_P1_DMDCFG2 , 0x3b },
+ { R0900_P1_MODCODLST0 , 0xff },
+ { R0900_P1_MODCODLST1 , 0xff },
+ { R0900_P1_MODCODLST2 , 0xff },
+ { R0900_P1_MODCODLST3 , 0xff },
+ { R0900_P1_MODCODLST4 , 0xff },
+ { R0900_P1_MODCODLST5 , 0xff },
+ { R0900_P1_MODCODLST6 , 0xff },
+ { R0900_P1_MODCODLST7 , 0xcc },
+ { R0900_P1_MODCODLST8 , 0xcc },
+ { R0900_P1_MODCODLST9 , 0xcc },
+ { R0900_P1_MODCODLSTA , 0xcc },
+ { R0900_P1_MODCODLSTB , 0xcc },
+ { R0900_P1_MODCODLSTC , 0xcc },
+ { R0900_P1_MODCODLSTD , 0xcc },
+ { R0900_P1_MODCODLSTE , 0xcc },
+ { R0900_P1_MODCODLSTF , 0xcf },
+ { R0900_GENCFG , 0x1d },
+ { R0900_NBITER_NF4 , 0x37 },
+ { R0900_NBITER_NF5 , 0x29 },
+ { R0900_NBITER_NF6 , 0x37 },
+ { R0900_NBITER_NF7 , 0x33 },
+ { R0900_NBITER_NF8 , 0x31 },
+ { R0900_NBITER_NF9 , 0x2f },
+ { R0900_NBITER_NF10 , 0x39 },
+ { R0900_NBITER_NF11 , 0x3a },
+ { R0900_NBITER_NF12 , 0x29 },
+ { R0900_NBITER_NF13 , 0x37 },
+ { R0900_NBITER_NF14 , 0x33 },
+ { R0900_NBITER_NF15 , 0x2f },
+ { R0900_NBITER_NF16 , 0x39 },
+ { R0900_NBITER_NF17 , 0x3a },
+ { R0900_NBITERNOERR , 0x04 },
+ { R0900_GAINLLR_NF4 , 0x0C },
+ { R0900_GAINLLR_NF5 , 0x0F },
+ { R0900_GAINLLR_NF6 , 0x11 },
+ { R0900_GAINLLR_NF7 , 0x14 },
+ { R0900_GAINLLR_NF8 , 0x17 },
+ { R0900_GAINLLR_NF9 , 0x19 },
+ { R0900_GAINLLR_NF10 , 0x20 },
+ { R0900_GAINLLR_NF11 , 0x21 },
+ { R0900_GAINLLR_NF12 , 0x0D },
+ { R0900_GAINLLR_NF13 , 0x0F },
+ { R0900_GAINLLR_NF14 , 0x13 },
+ { R0900_GAINLLR_NF15 , 0x1A },
+ { R0900_GAINLLR_NF16 , 0x1F },
+ { R0900_GAINLLR_NF17 , 0x21 },
+ { R0900_RCCFGH , 0x20 },
+ { R0900_P1_FECM , 0x01 }, /*disable DSS modes*/
+ { R0900_P2_FECM , 0x01 }, /*disable DSS modes*/
+ { R0900_P1_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
+ { R0900_P2_PRVIT , 0x2F }, /*disable puncture rate 6/7*/
+ { R0900_STROUT1CFG , 0x4c },
+ { R0900_STROUT2CFG , 0x4c },
+ { R0900_CLKOUT1CFG , 0x50 },
+ { R0900_CLKOUT2CFG , 0x50 },
+ { R0900_DPN1CFG , 0x4a },
+ { R0900_DPN2CFG , 0x4a },
+ { R0900_DATA71CFG , 0x52 },
+ { R0900_DATA72CFG , 0x52 },
+ { R0900_P1_TSCFGM , 0xc0 },
+ { R0900_P2_TSCFGM , 0xc0 },
+ { R0900_P1_TSCFGH , 0xe0 }, /* DVB-CI timings */
+ { R0900_P2_TSCFGH , 0xe0 }, /* DVB-CI timings */
+ { R0900_P1_TSSPEED , 0x40 },
+ { R0900_P2_TSSPEED , 0x40 },
+};
+
+static const u16 STV0900_Cut20_AddOnVal[32][2] = {
+ { R0900_P2_DMDCFG3 , 0xe8 },
+ { R0900_P2_DMDCFG4 , 0x10 },
+ { R0900_P2_CARFREQ , 0x38 },
+ { R0900_P2_CARHDR , 0x20 },
+ { R0900_P2_KREFTMG , 0x5a },
+ { R0900_P2_SMAPCOEF7 , 0x06 },
+ { R0900_P2_SMAPCOEF6 , 0x00 },
+ { R0900_P2_SMAPCOEF5 , 0x04 },
+ { R0900_P2_NOSCFG , 0x0c },
+ { R0900_P1_DMDCFG3 , 0xe8 },
+ { R0900_P1_DMDCFG4 , 0x10 },
+ { R0900_P1_CARFREQ , 0x38 },
+ { R0900_P1_CARHDR , 0x20 },
+ { R0900_P1_KREFTMG , 0x5a },
+ { R0900_P1_SMAPCOEF7 , 0x06 },
+ { R0900_P1_SMAPCOEF6 , 0x00 },
+ { R0900_P1_SMAPCOEF5 , 0x04 },
+ { R0900_P1_NOSCFG , 0x0c },
+ { R0900_GAINLLR_NF4 , 0x21 },
+ { R0900_GAINLLR_NF5 , 0x21 },
+ { R0900_GAINLLR_NF6 , 0x20 },
+ { R0900_GAINLLR_NF7 , 0x1F },
+ { R0900_GAINLLR_NF8 , 0x1E },
+ { R0900_GAINLLR_NF9 , 0x1E },
+ { R0900_GAINLLR_NF10 , 0x1D },
+ { R0900_GAINLLR_NF11 , 0x1B },
+ { R0900_GAINLLR_NF12 , 0x20 },
+ { R0900_GAINLLR_NF13 , 0x20 },
+ { R0900_GAINLLR_NF14 , 0x20 },
+ { R0900_GAINLLR_NF15 , 0x20 },
+ { R0900_GAINLLR_NF16 , 0x20 },
+ { R0900_GAINLLR_NF17 , 0x21 }
+
+};
+
+#endif
diff --git a/drivers/media/dvb/frontends/stv0900_priv.h b/drivers/media/dvb/frontends/stv0900_priv.h
new file mode 100644
index 00000000000..762d5af62d7
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_priv.h
@@ -0,0 +1,430 @@
+/*
+ * stv0900_priv.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_PRIV_H
+#define STV0900_PRIV_H
+
+#include <linux/i2c.h>
+
+#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
+#define INRANGE(X, Y, Z) ((((X) <= (Y)) && ((Y) <= (Z))) \
+ || (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
+
+#ifndef MAKEWORD
+#define MAKEWORD(X, Y) (((X) << 8) + (Y))
+#endif
+
+#define LSB(X) (((X) & 0xFF))
+#define MSB(Y) (((Y) >> 8) & 0xFF)
+
+#ifndef TRUE
+#define TRUE (1 == 1)
+#endif
+#ifndef FALSE
+#define FALSE (!TRUE)
+#endif
+
+#define dmd_reg(a, b, c) \
+ do { \
+ a = 0; \
+ switch (demod) { \
+ case STV0900_DEMOD_1: \
+ default: \
+ a = b; \
+ break; \
+ case STV0900_DEMOD_2: \
+ a = c; \
+ break; \
+ } \
+ } while (0)
+
+#define dmd_choose(a, b) (demod = STV0900_DEMOD_2 ? b : a))
+
+static int stvdebug;
+
+#define dprintk(args...) \
+ do { \
+ if (stvdebug) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+#define STV0900_MAXLOOKUPSIZE 500
+#define STV0900_BLIND_SEARCH_AGC2_TH 700
+
+/* One point of the lookup table */
+struct stv000_lookpoint {
+ s32 realval;/* real value */
+ s32 regval;/* binary value */
+};
+
+/* Lookup table definition */
+struct stv0900_table{
+ s32 size;/* Size of the lookup table */
+ struct stv000_lookpoint table[STV0900_MAXLOOKUPSIZE];/* Lookup table */
+};
+
+enum fe_stv0900_error {
+ STV0900_NO_ERROR = 0,
+ STV0900_INVALID_HANDLE,
+ STV0900_BAD_PARAMETER,
+ STV0900_I2C_ERROR,
+ STV0900_SEARCH_FAILED,
+};
+
+enum fe_stv0900_clock_type {
+ STV0900_USE_REGISTERS_DEFAULT,
+ STV0900_SERIAL_PUNCT_CLOCK,/*Serial punctured clock */
+ STV0900_SERIAL_CONT_CLOCK,/*Serial continues clock */
+ STV0900_PARALLEL_PUNCT_CLOCK,/*Parallel punctured clock */
+ STV0900_DVBCI_CLOCK/*Parallel continues clock : DVBCI */
+};
+
+enum fe_stv0900_search_state {
+ STV0900_SEARCH = 0,
+ STV0900_PLH_DETECTED,
+ STV0900_DVBS2_FOUND,
+ STV0900_DVBS_FOUND
+
+};
+
+enum fe_stv0900_ldpc_state {
+ STV0900_PATH1_OFF_PATH2_OFF = 0,
+ STV0900_PATH1_ON_PATH2_OFF = 1,
+ STV0900_PATH1_OFF_PATH2_ON = 2,
+ STV0900_PATH1_ON_PATH2_ON = 3
+};
+
+enum fe_stv0900_signal_type {
+ STV0900_NOAGC1 = 0,
+ STV0900_AGC1OK,
+ STV0900_NOTIMING,
+ STV0900_ANALOGCARRIER,
+ STV0900_TIMINGOK,
+ STV0900_NOAGC2,
+ STV0900_AGC2OK,
+ STV0900_NOCARRIER,
+ STV0900_CARRIEROK,
+ STV0900_NODATA,
+ STV0900_DATAOK,
+ STV0900_OUTOFRANGE,
+ STV0900_RANGEOK
+};
+
+enum fe_stv0900_demod_num {
+ STV0900_DEMOD_1,
+ STV0900_DEMOD_2
+};
+
+enum fe_stv0900_tracking_standard {
+ STV0900_DVBS1_STANDARD,/* Found Standard*/
+ STV0900_DVBS2_STANDARD,
+ STV0900_DSS_STANDARD,
+ STV0900_TURBOCODE_STANDARD,
+ STV0900_UNKNOWN_STANDARD
+};
+
+enum fe_stv0900_search_standard {
+ STV0900_AUTO_SEARCH,
+ STV0900_SEARCH_DVBS1,/* Search Standard*/
+ STV0900_SEARCH_DVBS2,
+ STV0900_SEARCH_DSS,
+ STV0900_SEARCH_TURBOCODE
+};
+
+enum fe_stv0900_search_algo {
+ STV0900_BLIND_SEARCH,/* offset freq and SR are Unknown */
+ STV0900_COLD_START,/* only the SR is known */
+ STV0900_WARM_START/* offset freq and SR are known */
+};
+
+enum fe_stv0900_modulation {
+ STV0900_QPSK,
+ STV0900_8PSK,
+ STV0900_16APSK,
+ STV0900_32APSK,
+ STV0900_UNKNOWN
+};
+
+enum fe_stv0900_modcode {
+ STV0900_DUMMY_PLF,
+ STV0900_QPSK_14,
+ STV0900_QPSK_13,
+ STV0900_QPSK_25,
+ STV0900_QPSK_12,
+ STV0900_QPSK_35,
+ STV0900_QPSK_23,
+ STV0900_QPSK_34,
+ STV0900_QPSK_45,
+ STV0900_QPSK_56,
+ STV0900_QPSK_89,
+ STV0900_QPSK_910,
+ STV0900_8PSK_35,
+ STV0900_8PSK_23,
+ STV0900_8PSK_34,
+ STV0900_8PSK_56,
+ STV0900_8PSK_89,
+ STV0900_8PSK_910,
+ STV0900_16APSK_23,
+ STV0900_16APSK_34,
+ STV0900_16APSK_45,
+ STV0900_16APSK_56,
+ STV0900_16APSK_89,
+ STV0900_16APSK_910,
+ STV0900_32APSK_34,
+ STV0900_32APSK_45,
+ STV0900_32APSK_56,
+ STV0900_32APSK_89,
+ STV0900_32APSK_910,
+ STV0900_MODCODE_UNKNOWN
+};
+
+enum fe_stv0900_fec {/*DVBS1, DSS and turbo code puncture rate*/
+ STV0900_FEC_1_2 = 0,
+ STV0900_FEC_2_3,
+ STV0900_FEC_3_4,
+ STV0900_FEC_4_5,/*for turbo code only*/
+ STV0900_FEC_5_6,
+ STV0900_FEC_6_7,/*for DSS only */
+ STV0900_FEC_7_8,
+ STV0900_FEC_8_9,/*for turbo code only*/
+ STV0900_FEC_UNKNOWN
+};
+
+enum fe_stv0900_frame_length {
+ STV0900_LONG_FRAME,
+ STV0900_SHORT_FRAME
+};
+
+enum fe_stv0900_pilot {
+ STV0900_PILOTS_OFF,
+ STV0900_PILOTS_ON
+};
+
+enum fe_stv0900_rolloff {
+ STV0900_35,
+ STV0900_25,
+ STV0900_20
+};
+
+enum fe_stv0900_search_iq {
+ STV0900_IQ_AUTO,
+ STV0900_IQ_AUTO_NORMAL_FIRST,
+ STV0900_IQ_FORCE_NORMAL,
+ STV0900_IQ_FORCE_SWAPPED
+};
+
+enum stv0900_iq_inversion {
+ STV0900_IQ_NORMAL,
+ STV0900_IQ_SWAPPED
+};
+
+enum fe_stv0900_diseqc_mode {
+ STV0900_22KHZ_Continues = 0,
+ STV0900_DISEQC_2_3_PWM = 2,
+ STV0900_DISEQC_3_3_PWM = 3,
+ STV0900_DISEQC_2_3_ENVELOP = 4,
+ STV0900_DISEQC_3_3_ENVELOP = 5
+};
+
+enum fe_stv0900_demod_mode {
+ STV0900_SINGLE = 0,
+ STV0900_DUAL
+};
+
+struct stv0900_init_params{
+ u32 dmd_ref_clk;/* Refrence,Input clock for the demod in Hz */
+
+ /* Demodulator Type (single demod or dual demod) */
+ enum fe_stv0900_demod_mode demod_mode;
+ enum fe_stv0900_rolloff rolloff;
+ enum fe_stv0900_clock_type path1_ts_clock;
+
+ u8 tun1_maddress;
+ int tuner1_adc;
+
+ /* IQ from the tuner1 to the demod */
+ enum stv0900_iq_inversion tun1_iq_inversion;
+ enum fe_stv0900_clock_type path2_ts_clock;
+
+ u8 tun2_maddress;
+ int tuner2_adc;
+
+ /* IQ from the tuner2 to the demod */
+ enum stv0900_iq_inversion tun2_iq_inversion;
+};
+
+struct stv0900_search_params {
+ enum fe_stv0900_demod_num path;/* Path Used demod1 or 2 */
+
+ u32 frequency;/* Transponder frequency (in KHz) */
+ u32 symbol_rate;/* Transponder symbol rate (in bds)*/
+ u32 search_range;/* Range of the search (in Hz) */
+
+ enum fe_stv0900_search_standard standard;
+ enum fe_stv0900_modulation modulation;
+ enum fe_stv0900_fec fec;
+ enum fe_stv0900_modcode modcode;
+ enum fe_stv0900_search_iq iq_inversion;
+ enum fe_stv0900_search_algo search_algo;
+
+};
+
+struct stv0900_signal_info {
+ int locked;/* Transponder locked */
+ u32 frequency;/* Transponder frequency (in KHz) */
+ u32 symbol_rate;/* Transponder symbol rate (in Mbds) */
+
+ enum fe_stv0900_tracking_standard standard;
+ enum fe_stv0900_fec fec;
+ enum fe_stv0900_modcode modcode;
+ enum fe_stv0900_modulation modulation;
+ enum fe_stv0900_pilot pilot;
+ enum fe_stv0900_frame_length frame_length;
+ enum stv0900_iq_inversion spectrum;
+ enum fe_stv0900_rolloff rolloff;
+
+ s32 Power;/* Power of the RF signal (dBm) */
+ s32 C_N;/* Carrier to noise ratio (dB x10)*/
+ u32 BER;/* Bit error rate (x10^7) */
+
+};
+
+struct stv0900_internal{
+ s32 quartz;
+ s32 mclk;
+ /* manual RollOff for DVBS1/DSS only */
+ enum fe_stv0900_rolloff rolloff;
+ /* Demodulator use for single demod or for dual demod) */
+ enum fe_stv0900_demod_mode demod_mode;
+
+ /*Demod 1*/
+ s32 tuner1_freq;
+ s32 tuner1_bw;
+ s32 dmd1_symbol_rate;
+ s32 dmd1_srch_range;
+
+ /* algorithm for search Blind, Cold or Warm*/
+ enum fe_stv0900_search_algo dmd1_srch_algo;
+ /* search standard: Auto, DVBS1/DSS only or DVBS2 only*/
+ enum fe_stv0900_search_standard dmd1_srch_standard;
+ /* inversion search : auto, auto norma first, normal or inverted */
+ enum fe_stv0900_search_iq dmd1_srch_iq_inv;
+ enum fe_stv0900_modcode dmd1_modcode;
+ enum fe_stv0900_modulation dmd1_modulation;
+ enum fe_stv0900_fec dmd1_fec;
+
+ struct stv0900_signal_info dmd1_rslts;
+ enum fe_stv0900_signal_type dmd1_state;
+
+ enum fe_stv0900_error dmd1_err;
+
+ /*Demod 2*/
+ s32 tuner2_freq;
+ s32 tuner2_bw;
+ s32 dmd2_symbol_rate;
+ s32 dmd2_srch_range;
+
+ enum fe_stv0900_search_algo dmd2_srch_algo;
+ enum fe_stv0900_search_standard dmd2_srch_stndrd;
+ /* inversion search : auto, auto normal first, normal or inverted */
+ enum fe_stv0900_search_iq dmd2_srch_iq_inv;
+ enum fe_stv0900_modcode dmd2_modcode;
+ enum fe_stv0900_modulation dmd2_modulation;
+ enum fe_stv0900_fec dmd2_fec;
+
+ /* results of the search*/
+ struct stv0900_signal_info dmd2_rslts;
+ /* current state of the search algorithm */
+ enum fe_stv0900_signal_type dmd2_state;
+
+ enum fe_stv0900_error dmd2_err;
+
+ struct i2c_adapter *i2c_adap;
+ u8 i2c_addr;
+ u8 clkmode;/* 0 for CLKI, 2 for XTALI */
+ u8 chip_id;
+ enum fe_stv0900_error errs;
+ int dmds_used;
+};
+
+/* state for each demod */
+struct stv0900_state {
+ /* pointer for internal params, one for each pair of demods */
+ struct stv0900_internal *internal;
+ struct i2c_adapter *i2c_adap;
+ const struct stv0900_config *config;
+ struct dvb_frontend frontend;
+ int demod;
+};
+
+extern s32 ge2comp(s32 a, s32 width);
+
+extern void stv0900_write_reg(struct stv0900_internal *i_params,
+ u16 reg_addr, u8 reg_data);
+
+extern u8 stv0900_read_reg(struct stv0900_internal *i_params,
+ u16 reg_addr);
+
+extern void stv0900_write_bits(struct stv0900_internal *i_params,
+ u32 label, u8 val);
+
+extern u8 stv0900_get_bits(struct stv0900_internal *i_params,
+ u32 label);
+
+extern int stv0900_get_demod_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod, s32 time_out);
+extern int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe);
+
+extern void stv0900_set_tuner(struct dvb_frontend *fe, u32 frequency,
+ u32 bandwidth);
+extern void stv0900_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth);
+
+extern void stv0900_start_search(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern u8 stv0900_get_optim_carr_loop(s32 srate,
+ enum fe_stv0900_modcode modcode,
+ s32 pilot, u8 chip_id);
+
+extern u8 stv0900_get_optim_short_carr_loop(s32 srate,
+ enum fe_stv0900_modulation modulation,
+ u8 chip_id);
+
+extern void stv0900_stop_all_s2_modcod(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcode(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern void stv0900_activate_s2_modcode_single(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod);
+
+extern enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+ enum fe_stv0900_demod_num demod);
+
+#endif
diff --git a/drivers/media/dvb/frontends/stv0900_reg.h b/drivers/media/dvb/frontends/stv0900_reg.h
new file mode 100644
index 00000000000..264f9cf9a17
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_reg.h
@@ -0,0 +1,3787 @@
+/*
+ * stv0900_reg.h
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef STV0900_REG_H
+#define STV0900_REG_H
+
+/*MID*/
+#define R0900_MID 0xf100
+#define F0900_MCHIP_IDENT 0xf10000f0
+#define F0900_MRELEASE 0xf100000f
+
+/*DACR1*/
+#define R0900_DACR1 0xf113
+#define F0900_DAC_MODE 0xf11300e0
+#define F0900_DAC_VALUE1 0xf113000f
+
+/*DACR2*/
+#define R0900_DACR2 0xf114
+#define F0900_DAC_VALUE0 0xf11400ff
+
+/*OUTCFG*/
+#define R0900_OUTCFG 0xf11c
+#define F0900_INV_DATA6 0xf11c0080
+#define F0900_OUTSERRS1_HZ 0xf11c0040
+#define F0900_OUTSERRS2_HZ 0xf11c0020
+#define F0900_OUTSERRS3_HZ 0xf11c0010
+#define F0900_OUTPARRS3_HZ 0xf11c0008
+#define F0900_OUTHZ3_CONTROL 0xf11c0007
+
+/*MODECFG*/
+#define R0900_MODECFG 0xf11d
+#define F0900_FECSPY_SEL_2 0xf11d0020
+#define F0900_HWARE_SEL_2 0xf11d0010
+#define F0900_PKTDEL_SEL_2 0xf11d0008
+#define F0900_DISEQC_SEL_2 0xf11d0004
+#define F0900_VIT_SEL_2 0xf11d0002
+#define F0900_DEMOD_SEL_2 0xf11d0001
+
+/*IRQSTATUS3*/
+#define R0900_IRQSTATUS3 0xf120
+#define F0900_SPLL_LOCK 0xf1200020
+#define F0900_SSTREAM_LCK_3 0xf1200010
+#define F0900_SSTREAM_LCK_2 0xf1200008
+#define F0900_SSTREAM_LCK_1 0xf1200004
+#define F0900_SDVBS1_PRF_2 0xf1200002
+#define F0900_SDVBS1_PRF_1 0xf1200001
+
+/*IRQSTATUS2*/
+#define R0900_IRQSTATUS2 0xf121
+#define F0900_SSPY_ENDSIM_3 0xf1210080
+#define F0900_SSPY_ENDSIM_2 0xf1210040
+#define F0900_SSPY_ENDSIM_1 0xf1210020
+#define F0900_SPKTDEL_ERROR_2 0xf1210010
+#define F0900_SPKTDEL_LOCKB_2 0xf1210008
+#define F0900_SPKTDEL_LOCK_2 0xf1210004
+#define F0900_SPKTDEL_ERROR_1 0xf1210002
+#define F0900_SPKTDEL_LOCKB_1 0xf1210001
+
+/*IRQSTATUS1*/
+#define R0900_IRQSTATUS1 0xf122
+#define F0900_SPKTDEL_LOCK_1 0xf1220080
+#define F0900_SEXTPINB2 0xf1220040
+#define F0900_SEXTPIN2 0xf1220020
+#define F0900_SEXTPINB1 0xf1220010
+#define F0900_SEXTPIN1 0xf1220008
+#define F0900_SDEMOD_LOCKB_2 0xf1220004
+#define F0900_SDEMOD_LOCK_2 0xf1220002
+#define F0900_SDEMOD_IRQ_2 0xf1220001
+
+/*IRQSTATUS0*/
+#define R0900_IRQSTATUS0 0xf123
+#define F0900_SDEMOD_LOCKB_1 0xf1230080
+#define F0900_SDEMOD_LOCK_1 0xf1230040
+#define F0900_SDEMOD_IRQ_1 0xf1230020
+#define F0900_SBCH_ERRFLAG 0xf1230010
+#define F0900_SDISEQC2RX_IRQ 0xf1230008
+#define F0900_SDISEQC2TX_IRQ 0xf1230004
+#define F0900_SDISEQC1RX_IRQ 0xf1230002
+#define F0900_SDISEQC1TX_IRQ 0xf1230001
+
+/*IRQMASK3*/
+#define R0900_IRQMASK3 0xf124
+#define F0900_MPLL_LOCK 0xf1240020
+#define F0900_MSTREAM_LCK_3 0xf1240010
+#define F0900_MSTREAM_LCK_2 0xf1240008
+#define F0900_MSTREAM_LCK_1 0xf1240004
+#define F0900_MDVBS1_PRF_2 0xf1240002
+#define F0900_MDVBS1_PRF_1 0xf1240001
+
+/*IRQMASK2*/
+#define R0900_IRQMASK2 0xf125
+#define F0900_MSPY_ENDSIM_3 0xf1250080
+#define F0900_MSPY_ENDSIM_2 0xf1250040
+#define F0900_MSPY_ENDSIM_1 0xf1250020
+#define F0900_MPKTDEL_ERROR_2 0xf1250010
+#define F0900_MPKTDEL_LOCKB_2 0xf1250008
+#define F0900_MPKTDEL_LOCK_2 0xf1250004
+#define F0900_MPKTDEL_ERROR_1 0xf1250002
+#define F0900_MPKTDEL_LOCKB_1 0xf1250001
+
+/*IRQMASK1*/
+#define R0900_IRQMASK1 0xf126
+#define F0900_MPKTDEL_LOCK_1 0xf1260080
+#define F0900_MEXTPINB2 0xf1260040
+#define F0900_MEXTPIN2 0xf1260020
+#define F0900_MEXTPINB1 0xf1260010
+#define F0900_MEXTPIN1 0xf1260008
+#define F0900_MDEMOD_LOCKB_2 0xf1260004
+#define F0900_MDEMOD_LOCK_2 0xf1260002
+#define F0900_MDEMOD_IRQ_2 0xf1260001
+
+/*IRQMASK0*/
+#define R0900_IRQMASK0 0xf127
+#define F0900_MDEMOD_LOCKB_1 0xf1270080
+#define F0900_MDEMOD_LOCK_1 0xf1270040
+#define F0900_MDEMOD_IRQ_1 0xf1270020
+#define F0900_MBCH_ERRFLAG 0xf1270010
+#define F0900_MDISEQC2RX_IRQ 0xf1270008
+#define F0900_MDISEQC2TX_IRQ 0xf1270004
+#define F0900_MDISEQC1RX_IRQ 0xf1270002
+#define F0900_MDISEQC1TX_IRQ 0xf1270001
+
+/*I2CCFG*/
+#define R0900_I2CCFG 0xf129
+#define F0900_I2C2_FASTMODE 0xf1290080
+#define F0900_STATUS_WR2 0xf1290040
+#define F0900_I2C2ADDR_INC 0xf1290030
+#define F0900_I2C_FASTMODE 0xf1290008
+#define F0900_STATUS_WR 0xf1290004
+#define F0900_I2CADDR_INC 0xf1290003
+
+/*P1_I2CRPT*/
+#define R0900_P1_I2CRPT 0xf12a
+#define F0900_P1_I2CT_ON 0xf12a0080
+#define F0900_P1_ENARPT_LEVEL 0xf12a0070
+#define F0900_P1_SCLT_DELAY 0xf12a0008
+#define F0900_P1_STOP_ENABLE 0xf12a0004
+#define F0900_P1_STOP_SDAT2SDA 0xf12a0002
+
+/*P2_I2CRPT*/
+#define R0900_P2_I2CRPT 0xf12b
+#define F0900_P2_I2CT_ON 0xf12b0080
+#define F0900_P2_ENARPT_LEVEL 0xf12b0070
+#define F0900_P2_SCLT_DELAY 0xf12b0008
+#define F0900_P2_STOP_ENABLE 0xf12b0004
+#define F0900_P2_STOP_SDAT2SDA 0xf12b0002
+
+/*CLKI2CFG*/
+#define R0900_CLKI2CFG 0xf140
+#define F0900_CLKI2_OPD 0xf1400080
+#define F0900_CLKI2_CONFIG 0xf140007e
+#define F0900_CLKI2_XOR 0xf1400001
+
+/*GPIO1CFG*/
+#define R0900_GPIO1CFG 0xf141
+#define F0900_GPIO1_OPD 0xf1410080
+#define F0900_GPIO1_CONFIG 0xf141007e
+#define F0900_GPIO1_XOR 0xf1410001
+
+/*GPIO2CFG*/
+#define R0900_GPIO2CFG 0xf142
+#define F0900_GPIO2_OPD 0xf1420080
+#define F0900_GPIO2_CONFIG 0xf142007e
+#define F0900_GPIO2_XOR 0xf1420001
+
+/*GPIO3CFG*/
+#define R0900_GPIO3CFG 0xf143
+#define F0900_GPIO3_OPD 0xf1430080
+#define F0900_GPIO3_CONFIG 0xf143007e
+#define F0900_GPIO3_XOR 0xf1430001
+
+/*GPIO4CFG*/
+#define R0900_GPIO4CFG 0xf144
+#define F0900_GPIO4_OPD 0xf1440080
+#define F0900_GPIO4_CONFIG 0xf144007e
+#define F0900_GPIO4_XOR 0xf1440001
+
+/*GPIO5CFG*/
+#define R0900_GPIO5CFG 0xf145
+#define F0900_GPIO5_OPD 0xf1450080
+#define F0900_GPIO5_CONFIG 0xf145007e
+#define F0900_GPIO5_XOR 0xf1450001
+
+/*GPIO6CFG*/
+#define R0900_GPIO6CFG 0xf146
+#define F0900_GPIO6_OPD 0xf1460080
+#define F0900_GPIO6_CONFIG 0xf146007e
+#define F0900_GPIO6_XOR 0xf1460001
+
+/*GPIO7CFG*/
+#define R0900_GPIO7CFG 0xf147
+#define F0900_GPIO7_OPD 0xf1470080
+#define F0900_GPIO7_CONFIG 0xf147007e
+#define F0900_GPIO7_XOR 0xf1470001
+
+/*GPIO8CFG*/
+#define R0900_GPIO8CFG 0xf148
+#define F0900_GPIO8_OPD 0xf1480080
+#define F0900_GPIO8_CONFIG 0xf148007e
+#define F0900_GPIO8_XOR 0xf1480001
+
+/*GPIO9CFG*/
+#define R0900_GPIO9CFG 0xf149
+#define F0900_GPIO9_OPD 0xf1490080
+#define F0900_GPIO9_CONFIG 0xf149007e
+#define F0900_GPIO9_XOR 0xf1490001
+
+/*GPIO10CFG*/
+#define R0900_GPIO10CFG 0xf14a
+#define F0900_GPIO10_OPD 0xf14a0080
+#define F0900_GPIO10_CONFIG 0xf14a007e
+#define F0900_GPIO10_XOR 0xf14a0001
+
+/*GPIO11CFG*/
+#define R0900_GPIO11CFG 0xf14b
+#define F0900_GPIO11_OPD 0xf14b0080
+#define F0900_GPIO11_CONFIG 0xf14b007e
+#define F0900_GPIO11_XOR 0xf14b0001
+
+/*GPIO12CFG*/
+#define R0900_GPIO12CFG 0xf14c
+#define F0900_GPIO12_OPD 0xf14c0080
+#define F0900_GPIO12_CONFIG 0xf14c007e
+#define F0900_GPIO12_XOR 0xf14c0001
+
+/*GPIO13CFG*/
+#define R0900_GPIO13CFG 0xf14d
+#define F0900_GPIO13_OPD 0xf14d0080
+#define F0900_GPIO13_CONFIG 0xf14d007e
+#define F0900_GPIO13_XOR 0xf14d0001
+
+/*CS0CFG*/
+#define R0900_CS0CFG 0xf14e
+#define F0900_CS0_OPD 0xf14e0080
+#define F0900_CS0_CONFIG 0xf14e007e
+#define F0900_CS0_XOR 0xf14e0001
+
+/*CS1CFG*/
+#define R0900_CS1CFG 0xf14f
+#define F0900_CS1_OPD 0xf14f0080
+#define F0900_CS1_CONFIG 0xf14f007e
+#define F0900_CS1_XOR 0xf14f0001
+
+/*STDBYCFG*/
+#define R0900_STDBYCFG 0xf150
+#define F0900_STDBY_OPD 0xf1500080
+#define F0900_STDBY_CONFIG 0xf150007e
+#define F0900_STBDY_XOR 0xf1500001
+
+/*DIRCLKCFG*/
+#define R0900_DIRCLKCFG 0xf151
+#define F0900_DIRCLK_OPD 0xf1510080
+#define F0900_DIRCLK_CONFIG 0xf151007e
+#define F0900_DIRCLK_XOR 0xf1510001
+
+/*AGCRF1CFG*/
+#define R0900_AGCRF1CFG 0xf152
+#define F0900_AGCRF1_OPD 0xf1520080
+#define F0900_AGCRF1_CONFIG 0xf152007e
+#define F0900_AGCRF1_XOR 0xf1520001
+
+/*SDAT1CFG*/
+#define R0900_SDAT1CFG 0xf153
+#define F0900_SDAT1_OPD 0xf1530080
+#define F0900_SDAT1_CONFIG 0xf153007e
+#define F0900_SDAT1_XOR 0xf1530001
+
+/*SCLT1CFG*/
+#define R0900_SCLT1CFG 0xf154
+#define F0900_SCLT1_OPD 0xf1540080
+#define F0900_SCLT1_CONFIG 0xf154007e
+#define F0900_SCLT1_XOR 0xf1540001
+
+/*DISEQCO1CFG*/
+#define R0900_DISEQCO1CFG 0xf155
+#define F0900_DISEQCO1_OPD 0xf1550080
+#define F0900_DISEQCO1_CONFIG 0xf155007e
+#define F0900_DISEQC1_XOR 0xf1550001
+
+/*AGCRF2CFG*/
+#define R0900_AGCRF2CFG 0xf156
+#define F0900_AGCRF2_OPD 0xf1560080
+#define F0900_AGCRF2_CONFIG 0xf156007e
+#define F0900_AGCRF2_XOR 0xf1560001
+
+/*SDAT2CFG*/
+#define R0900_SDAT2CFG 0xf157
+#define F0900_SDAT2_OPD 0xf1570080
+#define F0900_SDAT2_CONFIG 0xf157007e
+#define F0900_SDAT2_XOR 0xf1570001
+
+/*SCLT2CFG*/
+#define R0900_SCLT2CFG 0xf158
+#define F0900_SCLT2_OPD 0xf1580080
+#define F0900_SCLT2_CONFIG 0xf158007e
+#define F0900_SCLT2_XOR 0xf1580001
+
+/*DISEQCO2CFG*/
+#define R0900_DISEQCO2CFG 0xf159
+#define F0900_DISEQCO2_OPD 0xf1590080
+#define F0900_DISEQCO2_CONFIG 0xf159007e
+#define F0900_DISEQC2_XOR 0xf1590001
+
+/*CLKOUT27CFG*/
+#define R0900_CLKOUT27CFG 0xf15a
+#define F0900_CLKOUT27_OPD 0xf15a0080
+#define F0900_CLKOUT27_CONFIG 0xf15a007e
+#define F0900_CLKOUT27_XOR 0xf15a0001
+
+/*ERROR1CFG*/
+#define R0900_ERROR1CFG 0xf15b
+#define F0900_ERROR1_OPD 0xf15b0080
+#define F0900_ERROR1_CONFIG 0xf15b007e
+#define F0900_ERROR1_XOR 0xf15b0001
+
+/*DPN1CFG*/
+#define R0900_DPN1CFG 0xf15c
+#define F0900_DPN1_OPD 0xf15c0080
+#define F0900_DPN1_CONFIG 0xf15c007e
+#define F0900_DPN1_XOR 0xf15c0001
+
+/*STROUT1CFG*/
+#define R0900_STROUT1CFG 0xf15d
+#define F0900_STROUT1_OPD 0xf15d0080
+#define F0900_STROUT1_CONFIG 0xf15d007e
+#define F0900_STROUT1_XOR 0xf15d0001
+
+/*CLKOUT1CFG*/
+#define R0900_CLKOUT1CFG 0xf15e
+#define F0900_CLKOUT1_OPD 0xf15e0080
+#define F0900_CLKOUT1_CONFIG 0xf15e007e
+#define F0900_CLKOUT1_XOR 0xf15e0001
+
+/*DATA71CFG*/
+#define R0900_DATA71CFG 0xf15f
+#define F0900_DATA71_OPD 0xf15f0080
+#define F0900_DATA71_CONFIG 0xf15f007e
+#define F0900_DATA71_XOR 0xf15f0001
+
+/*ERROR2CFG*/
+#define R0900_ERROR2CFG 0xf160
+#define F0900_ERROR2_OPD 0xf1600080
+#define F0900_ERROR2_CONFIG 0xf160007e
+#define F0900_ERROR2_XOR 0xf1600001
+
+/*DPN2CFG*/
+#define R0900_DPN2CFG 0xf161
+#define F0900_DPN2_OPD 0xf1610080
+#define F0900_DPN2_CONFIG 0xf161007e
+#define F0900_DPN2_XOR 0xf1610001
+
+/*STROUT2CFG*/
+#define R0900_STROUT2CFG 0xf162
+#define F0900_STROUT2_OPD 0xf1620080
+#define F0900_STROUT2_CONFIG 0xf162007e
+#define F0900_STROUT2_XOR 0xf1620001
+
+/*CLKOUT2CFG*/
+#define R0900_CLKOUT2CFG 0xf163
+#define F0900_CLKOUT2_OPD 0xf1630080
+#define F0900_CLKOUT2_CONFIG 0xf163007e
+#define F0900_CLKOUT2_XOR 0xf1630001
+
+/*DATA72CFG*/
+#define R0900_DATA72CFG 0xf164
+#define F0900_DATA72_OPD 0xf1640080
+#define F0900_DATA72_CONFIG 0xf164007e
+#define F0900_DATA72_XOR 0xf1640001
+
+/*ERROR3CFG*/
+#define R0900_ERROR3CFG 0xf165
+#define F0900_ERROR3_OPD 0xf1650080
+#define F0900_ERROR3_CONFIG 0xf165007e
+#define F0900_ERROR3_XOR 0xf1650001
+
+/*DPN3CFG*/
+#define R0900_DPN3CFG 0xf166
+#define F0900_DPN3_OPD 0xf1660080
+#define F0900_DPN3_CONFIG 0xf166007e
+#define F0900_DPN3_XOR 0xf1660001
+
+/*STROUT3CFG*/
+#define R0900_STROUT3CFG 0xf167
+#define F0900_STROUT3_OPD 0xf1670080
+#define F0900_STROUT3_CONFIG 0xf167007e
+#define F0900_STROUT3_XOR 0xf1670001
+
+/*CLKOUT3CFG*/
+#define R0900_CLKOUT3CFG 0xf168
+#define F0900_CLKOUT3_OPD 0xf1680080
+#define F0900_CLKOUT3_CONFIG 0xf168007e
+#define F0900_CLKOUT3_XOR 0xf1680001
+
+/*DATA73CFG*/
+#define R0900_DATA73CFG 0xf169
+#define F0900_DATA73_OPD 0xf1690080
+#define F0900_DATA73_CONFIG 0xf169007e
+#define F0900_DATA73_XOR 0xf1690001
+
+/*FSKTFC2*/
+#define R0900_FSKTFC2 0xf170
+#define F0900_FSKT_KMOD 0xf17000fc
+#define F0900_FSKT_CAR2 0xf1700003
+
+/*FSKTFC1*/
+#define R0900_FSKTFC1 0xf171
+#define F0900_FSKT_CAR1 0xf17100ff
+
+/*FSKTFC0*/
+#define R0900_FSKTFC0 0xf172
+#define F0900_FSKT_CAR0 0xf17200ff
+
+/*FSKTDELTAF1*/
+#define R0900_FSKTDELTAF1 0xf173
+#define F0900_FSKT_DELTAF1 0xf173000f
+
+/*FSKTDELTAF0*/
+#define R0900_FSKTDELTAF0 0xf174
+#define F0900_FSKT_DELTAF0 0xf17400ff
+
+/*FSKTCTRL*/
+#define R0900_FSKTCTRL 0xf175
+#define F0900_FSKT_EN_SGN 0xf1750040
+#define F0900_FSKT_MOD_SGN 0xf1750020
+#define F0900_FSKT_MOD_EN 0xf175001c
+#define F0900_FSKT_DACMODE 0xf1750003
+
+/*FSKRFC2*/
+#define R0900_FSKRFC2 0xf176
+#define F0900_FSKR_DETSGN 0xf1760040
+#define F0900_FSKR_OUTSGN 0xf1760020
+#define F0900_FSKR_KAGC 0xf176001c
+#define F0900_FSKR_CAR2 0xf1760003
+
+/*FSKRFC1*/
+#define R0900_FSKRFC1 0xf177
+#define F0900_FSKR_CAR1 0xf17700ff
+
+/*FSKRFC0*/
+#define R0900_FSKRFC0 0xf178
+#define F0900_FSKR_CAR0 0xf17800ff
+
+/*FSKRK1*/
+#define R0900_FSKRK1 0xf179
+#define F0900_FSKR_K1_EXP 0xf17900e0
+#define F0900_FSKR_K1_MANT 0xf179001f
+
+/*FSKRK2*/
+#define R0900_FSKRK2 0xf17a
+#define F0900_FSKR_K2_EXP 0xf17a00e0
+#define F0900_FSKR_K2_MANT 0xf17a001f
+
+/*FSKRAGCR*/
+#define R0900_FSKRAGCR 0xf17b
+#define F0900_FSKR_OUTCTL 0xf17b00c0
+#define F0900_FSKR_AGC_REF 0xf17b003f
+
+/*FSKRAGC*/
+#define R0900_FSKRAGC 0xf17c
+#define F0900_FSKR_AGC_ACCU 0xf17c00ff
+
+/*FSKRALPHA*/
+#define R0900_FSKRALPHA 0xf17d
+#define F0900_FSKR_ALPHA_EXP 0xf17d001c
+#define F0900_FSKR_ALPHA_M 0xf17d0003
+
+/*FSKRPLTH1*/
+#define R0900_FSKRPLTH1 0xf17e
+#define F0900_FSKR_BETA 0xf17e00f0
+#define F0900_FSKR_PLL_TRESH1 0xf17e000f
+
+/*FSKRPLTH0*/
+#define R0900_FSKRPLTH0 0xf17f
+#define F0900_FSKR_PLL_TRESH0 0xf17f00ff
+
+/*FSKRDF1*/
+#define R0900_FSKRDF1 0xf180
+#define F0900_FSKR_OUT 0xf1800080
+#define F0900_FSKR_DELTAF1 0xf180001f
+
+/*FSKRDF0*/
+#define R0900_FSKRDF0 0xf181
+#define F0900_FSKR_DELTAF0 0xf18100ff
+
+/*FSKRSTEPP*/
+#define R0900_FSKRSTEPP 0xf182
+#define F0900_FSKR_STEP_PLUS 0xf18200ff
+
+/*FSKRSTEPM*/
+#define R0900_FSKRSTEPM 0xf183
+#define F0900_FSKR_STEP_MINUS 0xf18300ff
+
+/*FSKRDET1*/
+#define R0900_FSKRDET1 0xf184
+#define F0900_FSKR_DETECT 0xf1840080
+#define F0900_FSKR_CARDET_ACCU1 0xf184000f
+
+/*FSKRDET0*/
+#define R0900_FSKRDET0 0xf185
+#define F0900_FSKR_CARDET_ACCU0 0xf18500ff
+
+/*FSKRDTH1*/
+#define R0900_FSKRDTH1 0xf186
+#define F0900_FSKR_CARLOSS_THRESH1 0xf18600f0
+#define F0900_FSKR_CARDET_THRESH1 0xf186000f
+
+/*FSKRDTH0*/
+#define R0900_FSKRDTH0 0xf187
+#define F0900_FSKR_CARDET_THRESH0 0xf18700ff
+
+/*FSKRLOSS*/
+#define R0900_FSKRLOSS 0xf188
+#define F0900_FSKR_CARLOSS_THRESH0 0xf18800ff
+
+/*P2_DISTXCTL*/
+#define R0900_P2_DISTXCTL 0xf190
+#define F0900_P2_TIM_OFF 0xf1900080
+#define F0900_P2_DISEQC_RESET 0xf1900040
+#define F0900_P2_TIM_CMD 0xf1900030
+#define F0900_P2_DIS_PRECHARGE 0xf1900008
+#define F0900_P2_DISTX_MODE 0xf1900007
+
+/*P2_DISRXCTL*/
+#define R0900_P2_DISRXCTL 0xf191
+#define F0900_P2_RECEIVER_ON 0xf1910080
+#define F0900_P2_IGNO_SHORT22K 0xf1910040
+#define F0900_P2_ONECHIP_TRX 0xf1910020
+#define F0900_P2_EXT_ENVELOP 0xf1910010
+#define F0900_P2_PIN_SELECT 0xf191000c
+#define F0900_P2_IRQ_RXEND 0xf1910002
+#define F0900_P2_IRQ_4NBYTES 0xf1910001
+
+/*P2_DISRX_ST0*/
+#define R0900_P2_DISRX_ST0 0xf194
+#define F0900_P2_RX_END 0xf1940080
+#define F0900_P2_RX_ACTIVE 0xf1940040
+#define F0900_P2_SHORT_22KHZ 0xf1940020
+#define F0900_P2_CONT_TONE 0xf1940010
+#define F0900_P2_FIFO_4BREADY 0xf1940008
+#define F0900_P2_FIFO_EMPTY 0xf1940004
+#define F0900_P2_ABORT_DISRX 0xf1940001
+
+/*P2_DISRX_ST1*/
+#define R0900_P2_DISRX_ST1 0xf195
+#define F0900_P2_RX_FAIL 0xf1950080
+#define F0900_P2_FIFO_PARITYFAIL 0xf1950040
+#define F0900_P2_RX_NONBYTE 0xf1950020
+#define F0900_P2_FIFO_OVERFLOW 0xf1950010
+#define F0900_P2_FIFO_BYTENBR 0xf195000f
+
+/*P2_DISRXDATA*/
+#define R0900_P2_DISRXDATA 0xf196
+#define F0900_P2_DISRX_DATA 0xf19600ff
+
+/*P2_DISTXDATA*/
+#define R0900_P2_DISTXDATA 0xf197
+#define F0900_P2_DISEQC_FIFO 0xf19700ff
+
+/*P2_DISTXSTATUS*/
+#define R0900_P2_DISTXSTATUS 0xf198
+#define F0900_P2_TX_FAIL 0xf1980080
+#define F0900_P2_FIFO_FULL 0xf1980040
+#define F0900_P2_TX_IDLE 0xf1980020
+#define F0900_P2_GAP_BURST 0xf1980010
+#define F0900_P2_TXFIFO_BYTES 0xf198000f
+
+/*P2_F22TX*/
+#define R0900_P2_F22TX 0xf199
+#define F0900_P2_F22_REG 0xf19900ff
+
+/*P2_F22RX*/
+#define R0900_P2_F22RX 0xf19a
+#define F0900_P2_F22RX_REG 0xf19a00ff
+
+/*P2_ACRPRESC*/
+#define R0900_P2_ACRPRESC 0xf19c
+#define F0900_P2_ACR_CODFRDY 0xf19c0008
+#define F0900_P2_ACR_PRESC 0xf19c0007
+
+/*P2_ACRDIV*/
+#define R0900_P2_ACRDIV 0xf19d
+#define F0900_P2_ACR_DIV 0xf19d00ff
+
+/*P1_DISTXCTL*/
+#define R0900_P1_DISTXCTL 0xf1a0
+#define F0900_P1_TIM_OFF 0xf1a00080
+#define F0900_P1_DISEQC_RESET 0xf1a00040
+#define F0900_P1_TIM_CMD 0xf1a00030
+#define F0900_P1_DIS_PRECHARGE 0xf1a00008
+#define F0900_P1_DISTX_MODE 0xf1a00007
+
+/*P1_DISRXCTL*/
+#define R0900_P1_DISRXCTL 0xf1a1
+#define F0900_P1_RECEIVER_ON 0xf1a10080
+#define F0900_P1_IGNO_SHORT22K 0xf1a10040
+#define F0900_P1_ONECHIP_TRX 0xf1a10020
+#define F0900_P1_EXT_ENVELOP 0xf1a10010
+#define F0900_P1_PIN_SELECT 0xf1a1000c
+#define F0900_P1_IRQ_RXEND 0xf1a10002
+#define F0900_P1_IRQ_4NBYTES 0xf1a10001
+
+/*P1_DISRX_ST0*/
+#define R0900_P1_DISRX_ST0 0xf1a4
+#define F0900_P1_RX_END 0xf1a40080
+#define F0900_P1_RX_ACTIVE 0xf1a40040
+#define F0900_P1_SHORT_22KHZ 0xf1a40020
+#define F0900_P1_CONT_TONE 0xf1a40010
+#define F0900_P1_FIFO_4BREADY 0xf1a40008
+#define F0900_P1_FIFO_EMPTY 0xf1a40004
+#define F0900_P1_ABORT_DISRX 0xf1a40001
+
+/*P1_DISRX_ST1*/
+#define R0900_P1_DISRX_ST1 0xf1a5
+#define F0900_P1_RX_FAIL 0xf1a50080
+#define F0900_P1_FIFO_PARITYFAIL 0xf1a50040
+#define F0900_P1_RX_NONBYTE 0xf1a50020
+#define F0900_P1_FIFO_OVERFLOW 0xf1a50010
+#define F0900_P1_FIFO_BYTENBR 0xf1a5000f
+
+/*P1_DISRXDATA*/
+#define R0900_P1_DISRXDATA 0xf1a6
+#define F0900_P1_DISRX_DATA 0xf1a600ff
+
+/*P1_DISTXDATA*/
+#define R0900_P1_DISTXDATA 0xf1a7
+#define F0900_P1_DISEQC_FIFO 0xf1a700ff
+
+/*P1_DISTXSTATUS*/
+#define R0900_P1_DISTXSTATUS 0xf1a8
+#define F0900_P1_TX_FAIL 0xf1a80080
+#define F0900_P1_FIFO_FULL 0xf1a80040
+#define F0900_P1_TX_IDLE 0xf1a80020
+#define F0900_P1_GAP_BURST 0xf1a80010
+#define F0900_P1_TXFIFO_BYTES 0xf1a8000f
+
+/*P1_F22TX*/
+#define R0900_P1_F22TX 0xf1a9
+#define F0900_P1_F22_REG 0xf1a900ff
+
+/*P1_F22RX*/
+#define R0900_P1_F22RX 0xf1aa
+#define F0900_P1_F22RX_REG 0xf1aa00ff
+
+/*P1_ACRPRESC*/
+#define R0900_P1_ACRPRESC 0xf1ac
+#define F0900_P1_ACR_CODFRDY 0xf1ac0008
+#define F0900_P1_ACR_PRESC 0xf1ac0007
+
+/*P1_ACRDIV*/
+#define R0900_P1_ACRDIV 0xf1ad
+#define F0900_P1_ACR_DIV 0xf1ad00ff
+
+/*NCOARSE*/
+#define R0900_NCOARSE 0xf1b3
+#define F0900_M_DIV 0xf1b300ff
+
+/*SYNTCTRL*/
+#define R0900_SYNTCTRL 0xf1b6
+#define F0900_STANDBY 0xf1b60080
+#define F0900_BYPASSPLLCORE 0xf1b60040
+#define F0900_SELX1RATIO 0xf1b60020
+#define F0900_I2C_TUD 0xf1b60010
+#define F0900_STOP_PLL 0xf1b60008
+#define F0900_BYPASSPLLFSK 0xf1b60004
+#define F0900_SELOSCI 0xf1b60002
+#define F0900_BYPASSPLLADC 0xf1b60001
+
+/*FILTCTRL*/
+#define R0900_FILTCTRL 0xf1b7
+#define F0900_INV_CLK135 0xf1b70080
+#define F0900_PERM_BYPDIS 0xf1b70040
+#define F0900_SEL_FSKCKDIV 0xf1b70004
+#define F0900_INV_CLKFSK 0xf1b70002
+#define F0900_BYPASS_APPLI 0xf1b70001
+
+/*PLLSTAT*/
+#define R0900_PLLSTAT 0xf1b8
+#define F0900_ACM_SEL 0xf1b80080
+#define F0900_DTV_SEL 0xf1b80040
+#define F0900_PLLLOCK 0xf1b80001
+
+/*STOPCLK1*/
+#define R0900_STOPCLK1 0xf1c2
+#define F0900_STOP_CLKPKDT2 0xf1c20040
+#define F0900_STOP_CLKPKDT1 0xf1c20020
+#define F0900_STOP_CLKFEC 0xf1c20010
+#define F0900_STOP_CLKADCI2 0xf1c20008
+#define F0900_INV_CLKADCI2 0xf1c20004
+#define F0900_STOP_CLKADCI1 0xf1c20002
+#define F0900_INV_CLKADCI1 0xf1c20001
+
+/*STOPCLK2*/
+#define R0900_STOPCLK2 0xf1c3
+#define F0900_STOP_CLKSAMP2 0xf1c30010
+#define F0900_STOP_CLKSAMP1 0xf1c30008
+#define F0900_STOP_CLKVIT2 0xf1c30004
+#define F0900_STOP_CLKVIT1 0xf1c30002
+#define F0900_STOP_CLKTS 0xf1c30001
+
+/*TSTTNR0*/
+#define R0900_TSTTNR0 0xf1df
+#define F0900_SEL_FSK 0xf1df0080
+#define F0900_FSK_PON 0xf1df0004
+#define F0900_FSK_OPENLOOP 0xf1df0002
+
+/*TSTTNR1*/
+#define R0900_TSTTNR1 0xf1e0
+#define F0900_BYPASS_ADC1 0xf1e00080
+#define F0900_INVADC1_CKOUT 0xf1e00040
+#define F0900_SELIQSRC1 0xf1e00030
+#define F0900_ADC1_PON 0xf1e00002
+#define F0900_ADC1_INMODE 0xf1e00001
+
+/*TSTTNR2*/
+#define R0900_TSTTNR2 0xf1e1
+#define F0900_DISEQC1_PON 0xf1e10020
+#define F0900_DISEQC1_TEST 0xf1e1001f
+
+/*TSTTNR3*/
+#define R0900_TSTTNR3 0xf1e2
+#define F0900_BYPASS_ADC2 0xf1e20080
+#define F0900_INVADC2_CKOUT 0xf1e20040
+#define F0900_SELIQSRC2 0xf1e20030
+#define F0900_ADC2_PON 0xf1e20002
+#define F0900_ADC2_INMODE 0xf1e20001
+
+/*TSTTNR4*/
+#define R0900_TSTTNR4 0xf1e3
+#define F0900_DISEQC2_PON 0xf1e30020
+#define F0900_DISEQC2_TEST 0xf1e3001f
+
+/*P2_IQCONST*/
+#define R0900_P2_IQCONST 0xf200
+#define F0900_P2_CONSTEL_SELECT 0xf2000060
+#define F0900_P2_IQSYMB_SEL 0xf200001f
+
+/*P2_NOSCFG*/
+#define R0900_P2_NOSCFG 0xf201
+#define F0900_P2_DUMMYPL_NOSDATA 0xf2010020
+#define F0900_P2_NOSPLH_BETA 0xf2010018
+#define F0900_P2_NOSDATA_BETA 0xf2010007
+
+/*P2_ISYMB*/
+#define R0900_P2_ISYMB 0xf202
+#define F0900_P2_I_SYMBOL 0xf20201ff
+
+/*P2_QSYMB*/
+#define R0900_P2_QSYMB 0xf203
+#define F0900_P2_Q_SYMBOL 0xf20301ff
+
+/*P2_AGC1CFG*/
+#define R0900_P2_AGC1CFG 0xf204
+#define F0900_P2_DC_FROZEN 0xf2040080
+#define F0900_P2_DC_CORRECT 0xf2040040
+#define F0900_P2_AMM_FROZEN 0xf2040020
+#define F0900_P2_AMM_CORRECT 0xf2040010
+#define F0900_P2_QUAD_FROZEN 0xf2040008
+#define F0900_P2_QUAD_CORRECT 0xf2040004
+#define F0900_P2_DCCOMP_SLOW 0xf2040002
+#define F0900_P2_IQMISM_SLOW 0xf2040001
+
+/*P2_AGC1CN*/
+#define R0900_P2_AGC1CN 0xf206
+#define F0900_P2_AGC1_LOCKED 0xf2060080
+#define F0900_P2_AGC1_OVERFLOW 0xf2060040
+#define F0900_P2_AGC1_NOSLOWLK 0xf2060020
+#define F0900_P2_AGC1_MINPOWER 0xf2060010
+#define F0900_P2_AGCOUT_FAST 0xf2060008
+#define F0900_P2_AGCIQ_BETA 0xf2060007
+
+/*P2_AGC1REF*/
+#define R0900_P2_AGC1REF 0xf207
+#define F0900_P2_AGCIQ_REF 0xf20700ff
+
+/*P2_IDCCOMP*/
+#define R0900_P2_IDCCOMP 0xf208
+#define F0900_P2_IAVERAGE_ADJ 0xf20801ff
+
+/*P2_QDCCOMP*/
+#define R0900_P2_QDCCOMP 0xf209
+#define F0900_P2_QAVERAGE_ADJ 0xf20901ff
+
+/*P2_POWERI*/
+#define R0900_P2_POWERI 0xf20a
+#define F0900_P2_POWER_I 0xf20a00ff
+
+/*P2_POWERQ*/
+#define R0900_P2_POWERQ 0xf20b
+#define F0900_P2_POWER_Q 0xf20b00ff
+
+/*P2_AGC1AMM*/
+#define R0900_P2_AGC1AMM 0xf20c
+#define F0900_P2_AMM_VALUE 0xf20c00ff
+
+/*P2_AGC1QUAD*/
+#define R0900_P2_AGC1QUAD 0xf20d
+#define F0900_P2_QUAD_VALUE 0xf20d01ff
+
+/*P2_AGCIQIN1*/
+#define R0900_P2_AGCIQIN1 0xf20e
+#define F0900_P2_AGCIQ_VALUE1 0xf20e00ff
+
+/*P2_AGCIQIN0*/
+#define R0900_P2_AGCIQIN0 0xf20f
+#define F0900_P2_AGCIQ_VALUE0 0xf20f00ff
+
+/*P2_DEMOD*/
+#define R0900_P2_DEMOD 0xf210
+#define F0900_P2_DEMOD_STOP 0xf2100040
+#define F0900_P2_SPECINV_CONTROL 0xf2100030
+#define F0900_P2_FORCE_ENASAMP 0xf2100008
+#define F0900_P2_MANUAL_ROLLOFF 0xf2100004
+#define F0900_P2_ROLLOFF_CONTROL 0xf2100003
+
+/*P2_DMDMODCOD*/
+#define R0900_P2_DMDMODCOD 0xf211
+#define F0900_P2_MANUAL_MODCOD 0xf2110080
+#define F0900_P2_DEMOD_MODCOD 0xf211007c
+#define F0900_P2_DEMOD_TYPE 0xf2110003
+
+/*P2_DSTATUS*/
+#define R0900_P2_DSTATUS 0xf212
+#define F0900_P2_CAR_LOCK 0xf2120080
+#define F0900_P2_TMGLOCK_QUALITY 0xf2120060
+#define F0900_P2_SDVBS1_ENABLE 0xf2120010
+#define F0900_P2_LOCK_DEFINITIF 0xf2120008
+#define F0900_P2_TIMING_IS_LOCKED 0xf2120004
+#define F0900_P2_COARSE_TMGLOCK 0xf2120002
+#define F0900_P2_COARSE_CARLOCK 0xf2120001
+
+/*P2_DSTATUS2*/
+#define R0900_P2_DSTATUS2 0xf213
+#define F0900_P2_DEMOD_DELOCK 0xf2130080
+#define F0900_P2_DEMOD_TIMEOUT 0xf2130040
+#define F0900_P2_MODCODRQ_SYNCTAG 0xf2130020
+#define F0900_P2_POLYPH_SATEVENT 0xf2130010
+#define F0900_P2_AGC1_NOSIGNALACK 0xf2130008
+#define F0900_P2_AGC2_OVERFLOW 0xf2130004
+#define F0900_P2_CFR_OVERFLOW 0xf2130002
+#define F0900_P2_GAMMA_OVERUNDER 0xf2130001
+
+/*P2_DMDCFGMD*/
+#define R0900_P2_DMDCFGMD 0xf214
+#define F0900_P2_DVBS2_ENABLE 0xf2140080
+#define F0900_P2_DVBS1_ENABLE 0xf2140040
+#define F0900_P2_CFR_AUTOSCAN 0xf2140020
+#define F0900_P2_SCAN_ENABLE 0xf2140010
+#define F0900_P2_TUN_AUTOSCAN 0xf2140008
+#define F0900_P2_NOFORCE_RELOCK 0xf2140004
+#define F0900_P2_TUN_RNG 0xf2140003
+
+/*P2_DMDCFG2*/
+#define R0900_P2_DMDCFG2 0xf215
+#define F0900_P2_AGC1_WAITLOCK 0xf2150080
+#define F0900_P2_S1S2_SEQUENTIAL 0xf2150040
+#define F0900_P2_OVERFLOW_TIMEOUT 0xf2150020
+#define F0900_P2_SCANFAIL_TIMEOUT 0xf2150010
+#define F0900_P2_DMDTOUT_BACK 0xf2150008
+#define F0900_P2_CARLOCK_S1ENABLE 0xf2150004
+#define F0900_P2_COARSE_LK3MODE 0xf2150002
+#define F0900_P2_COARSE_LK2MODE 0xf2150001
+
+/*P2_DMDISTATE*/
+#define R0900_P2_DMDISTATE 0xf216
+#define F0900_P2_I2C_NORESETDMODE 0xf2160080
+#define F0900_P2_FORCE_ETAPED 0xf2160040
+#define F0900_P2_SDMDRST_DIRCLK 0xf2160020
+#define F0900_P2_I2C_DEMOD_MODE 0xf216001f
+
+/*P2_DMDT0M*/
+#define R0900_P2_DMDT0M 0xf217
+#define F0900_P2_DMDT0_MIN 0xf21700ff
+
+/*P2_DMDSTATE*/
+#define R0900_P2_DMDSTATE 0xf21b
+#define F0900_P2_DEMOD_LOCKED 0xf21b0080
+#define F0900_P2_HEADER_MODE 0xf21b0060
+#define F0900_P2_DEMOD_MODE 0xf21b001f
+
+/*P2_DMDFLYW*/
+#define R0900_P2_DMDFLYW 0xf21c
+#define F0900_P2_I2C_IRQVAL 0xf21c00f0
+#define F0900_P2_FLYWHEEL_CPT 0xf21c000f
+
+/*P2_DSTATUS3*/
+#define R0900_P2_DSTATUS3 0xf21d
+#define F0900_P2_CFR_ZIGZAG 0xf21d0080
+#define F0900_P2_DEMOD_CFGMODE 0xf21d0060
+#define F0900_P2_GAMMA_LOWBAUDRATE 0xf21d0010
+#define F0900_P2_RELOCK_MODE 0xf21d0008
+#define F0900_P2_DEMOD_FAIL 0xf21d0004
+#define F0900_P2_ETAPE1A_DVBXMEM 0xf21d0003
+
+/*P2_DMDCFG3*/
+#define R0900_P2_DMDCFG3 0xf21e
+#define F0900_P2_DVBS1_TMGWAIT 0xf21e0080
+#define F0900_P2_NO_BWCENTERING 0xf21e0040
+#define F0900_P2_INV_SEQSRCH 0xf21e0020
+#define F0900_P2_DIS_SFRUPLOW_TRK 0xf21e0010
+#define F0900_P2_NOSTOP_FIFOFULL 0xf21e0008
+#define F0900_P2_LOCKTIME_MODE 0xf21e0007
+
+/*P2_DMDCFG4*/
+#define R0900_P2_DMDCFG4 0xf21f
+#define F0900_P2_TUNER_NRELAUNCH 0xf21f0008
+#define F0900_P2_DIS_CLKENABLE 0xf21f0004
+#define F0900_P2_DIS_HDRDIVLOCK 0xf21f0002
+#define F0900_P2_NO_TNRWBINIT 0xf21f0001
+
+/*P2_CORRELMANT*/
+#define R0900_P2_CORRELMANT 0xf220
+#define F0900_P2_CORREL_MANT 0xf22000ff
+
+/*P2_CORRELABS*/
+#define R0900_P2_CORRELABS 0xf221
+#define F0900_P2_CORREL_ABS 0xf22100ff
+
+/*P2_CORRELEXP*/
+#define R0900_P2_CORRELEXP 0xf222
+#define F0900_P2_CORREL_ABSEXP 0xf22200f0
+#define F0900_P2_CORREL_EXP 0xf222000f
+
+/*P2_PLHMODCOD*/
+#define R0900_P2_PLHMODCOD 0xf224
+#define F0900_P2_SPECINV_DEMOD 0xf2240080
+#define F0900_P2_PLH_MODCOD 0xf224007c
+#define F0900_P2_PLH_TYPE 0xf2240003
+
+/*P2_AGCK32*/
+#define R0900_P2_AGCK32 0xf22b
+#define F0900_P2_R3ADJOFF_32APSK 0xf22b0080
+#define F0900_P2_R2ADJOFF_32APSK 0xf22b0040
+#define F0900_P2_R1ADJOFF_32APSK 0xf22b0020
+#define F0900_P2_RADJ_32APSK 0xf22b001f
+
+/*P2_AGC2O*/
+#define R0900_P2_AGC2O 0xf22c
+#define F0900_P2_AGC2REF_ADJUSTING 0xf22c0080
+#define F0900_P2_AGC2_COARSEFAST 0xf22c0040
+#define F0900_P2_AGC2_LKSQRT 0xf22c0020
+#define F0900_P2_AGC2_LKMODE 0xf22c0010
+#define F0900_P2_AGC2_LKEQUA 0xf22c0008
+#define F0900_P2_AGC2_COEF 0xf22c0007
+
+/*P2_AGC2REF*/
+#define R0900_P2_AGC2REF 0xf22d
+#define F0900_P2_AGC2_REF 0xf22d00ff
+
+/*P2_AGC1ADJ*/
+#define R0900_P2_AGC1ADJ 0xf22e
+#define F0900_P2_AGC1ADJ_MANUAL 0xf22e0080
+#define F0900_P2_AGC1_ADJUSTED 0xf22e017f
+
+/*P2_AGC2I1*/
+#define R0900_P2_AGC2I1 0xf236
+#define F0900_P2_AGC2_INTEGRATOR1 0xf23600ff
+
+/*P2_AGC2I0*/
+#define R0900_P2_AGC2I0 0xf237
+#define F0900_P2_AGC2_INTEGRATOR0 0xf23700ff
+
+/*P2_CARCFG*/
+#define R0900_P2_CARCFG 0xf238
+#define F0900_P2_CFRUPLOW_AUTO 0xf2380080
+#define F0900_P2_CFRUPLOW_TEST 0xf2380040
+#define F0900_P2_EN_CAR2CENTER 0xf2380020
+#define F0900_P2_CARHDR_NODIV8 0xf2380010
+#define F0900_P2_I2C_ROTA 0xf2380008
+#define F0900_P2_ROTAON 0xf2380004
+#define F0900_P2_PH_DET_ALGO 0xf2380003
+
+/*P2_ACLC*/
+#define R0900_P2_ACLC 0xf239
+#define F0900_P2_STOP_S2ALPHA 0xf23900c0
+#define F0900_P2_CAR_ALPHA_MANT 0xf2390030
+#define F0900_P2_CAR_ALPHA_EXP 0xf239000f
+
+/*P2_BCLC*/
+#define R0900_P2_BCLC 0xf23a
+#define F0900_P2_STOP_S2BETA 0xf23a00c0
+#define F0900_P2_CAR_BETA_MANT 0xf23a0030
+#define F0900_P2_CAR_BETA_EXP 0xf23a000f
+
+/*P2_CARFREQ*/
+#define R0900_P2_CARFREQ 0xf23d
+#define F0900_P2_KC_COARSE_EXP 0xf23d00f0
+#define F0900_P2_BETA_FREQ 0xf23d000f
+
+/*P2_CARHDR*/
+#define R0900_P2_CARHDR 0xf23e
+#define F0900_P2_K_FREQ_HDR 0xf23e00ff
+
+/*P2_LDT*/
+#define R0900_P2_LDT 0xf23f
+#define F0900_P2_CARLOCK_THRES 0xf23f01ff
+
+/*P2_LDT2*/
+#define R0900_P2_LDT2 0xf240
+#define F0900_P2_CARLOCK_THRES2 0xf24001ff
+
+/*P2_CFRICFG*/
+#define R0900_P2_CFRICFG 0xf241
+#define F0900_P2_CFRINIT_UNVALRNG 0xf2410080
+#define F0900_P2_CFRINIT_LUNVALCPT 0xf2410040
+#define F0900_P2_CFRINIT_ABORTDBL 0xf2410020
+#define F0900_P2_CFRINIT_ABORTPRED 0xf2410010
+#define F0900_P2_CFRINIT_UNVALSKIP 0xf2410008
+#define F0900_P2_CFRINIT_CSTINC 0xf2410004
+#define F0900_P2_NEG_CFRSTEP 0xf2410001
+
+/*P2_CFRUP1*/
+#define R0900_P2_CFRUP1 0xf242
+#define F0900_P2_CFR_UP1 0xf24201ff
+
+/*P2_CFRUP0*/
+#define R0900_P2_CFRUP0 0xf243
+#define F0900_P2_CFR_UP0 0xf24300ff
+
+/*P2_CFRLOW1*/
+#define R0900_P2_CFRLOW1 0xf246
+#define F0900_P2_CFR_LOW1 0xf24601ff
+
+/*P2_CFRLOW0*/
+#define R0900_P2_CFRLOW0 0xf247
+#define F0900_P2_CFR_LOW0 0xf24700ff
+
+/*P2_CFRINIT1*/
+#define R0900_P2_CFRINIT1 0xf248
+#define F0900_P2_CFR_INIT1 0xf24801ff
+
+/*P2_CFRINIT0*/
+#define R0900_P2_CFRINIT0 0xf249
+#define F0900_P2_CFR_INIT0 0xf24900ff
+
+/*P2_CFRINC1*/
+#define R0900_P2_CFRINC1 0xf24a
+#define F0900_P2_MANUAL_CFRINC 0xf24a0080
+#define F0900_P2_CFR_INC1 0xf24a017f
+
+/*P2_CFRINC0*/
+#define R0900_P2_CFRINC0 0xf24b
+#define F0900_P2_CFR_INC0 0xf24b00f0
+
+/*P2_CFR2*/
+#define R0900_P2_CFR2 0xf24c
+#define F0900_P2_CAR_FREQ2 0xf24c01ff
+
+/*P2_CFR1*/
+#define R0900_P2_CFR1 0xf24d
+#define F0900_P2_CAR_FREQ1 0xf24d00ff
+
+/*P2_CFR0*/
+#define R0900_P2_CFR0 0xf24e
+#define F0900_P2_CAR_FREQ0 0xf24e00ff
+
+/*P2_LDI*/
+#define R0900_P2_LDI 0xf24f
+#define F0900_P2_LOCK_DET_INTEGR 0xf24f01ff
+
+/*P2_TMGCFG*/
+#define R0900_P2_TMGCFG 0xf250
+#define F0900_P2_TMGLOCK_BETA 0xf25000c0
+#define F0900_P2_NOTMG_GROUPDELAY 0xf2500020
+#define F0900_P2_DO_TIMING_CORR 0xf2500010
+#define F0900_P2_MANUAL_SCAN 0xf250000c
+#define F0900_P2_TMG_MINFREQ 0xf2500003
+
+/*P2_RTC*/
+#define R0900_P2_RTC 0xf251
+#define F0900_P2_TMGALPHA_EXP 0xf25100f0
+#define F0900_P2_TMGBETA_EXP 0xf251000f
+
+/*P2_RTCS2*/
+#define R0900_P2_RTCS2 0xf252
+#define F0900_P2_TMGALPHAS2_EXP 0xf25200f0
+#define F0900_P2_TMGBETAS2_EXP 0xf252000f
+
+/*P2_TMGTHRISE*/
+#define R0900_P2_TMGTHRISE 0xf253
+#define F0900_P2_TMGLOCK_THRISE 0xf25300ff
+
+/*P2_TMGTHFALL*/
+#define R0900_P2_TMGTHFALL 0xf254
+#define F0900_P2_TMGLOCK_THFALL 0xf25400ff
+
+/*P2_SFRUPRATIO*/
+#define R0900_P2_SFRUPRATIO 0xf255
+#define F0900_P2_SFR_UPRATIO 0xf25500ff
+
+/*P2_SFRLOWRATIO*/
+#define R0900_P2_SFRLOWRATIO 0xf256
+#define F0900_P2_SFR_LOWRATIO 0xf25600ff
+
+/*P2_KREFTMG*/
+#define R0900_P2_KREFTMG 0xf258
+#define F0900_P2_KREF_TMG 0xf25800ff
+
+/*P2_SFRSTEP*/
+#define R0900_P2_SFRSTEP 0xf259
+#define F0900_P2_SFR_SCANSTEP 0xf25900f0
+#define F0900_P2_SFR_CENTERSTEP 0xf259000f
+
+/*P2_TMGCFG2*/
+#define R0900_P2_TMGCFG2 0xf25a
+#define F0900_P2_DIS_AUTOSAMP 0xf25a0008
+#define F0900_P2_SCANINIT_QUART 0xf25a0004
+#define F0900_P2_NOTMG_DVBS1DERAT 0xf25a0002
+#define F0900_P2_SFRRATIO_FINE 0xf25a0001
+
+/*P2_SFRINIT1*/
+#define R0900_P2_SFRINIT1 0xf25e
+#define F0900_P2_SFR_INIT1 0xf25e00ff
+
+/*P2_SFRINIT0*/
+#define R0900_P2_SFRINIT0 0xf25f
+#define F0900_P2_SFR_INIT0 0xf25f00ff
+
+/*P2_SFRUP1*/
+#define R0900_P2_SFRUP1 0xf260
+#define F0900_P2_AUTO_GUP 0xf2600080
+#define F0900_P2_SYMB_FREQ_UP1 0xf260007f
+
+/*P2_SFRUP0*/
+#define R0900_P2_SFRUP0 0xf261
+#define F0900_P2_SYMB_FREQ_UP0 0xf26100ff
+
+/*P2_SFRLOW1*/
+#define R0900_P2_SFRLOW1 0xf262
+#define F0900_P2_AUTO_GLOW 0xf2620080
+#define F0900_P2_SYMB_FREQ_LOW1 0xf262007f
+
+/*P2_SFRLOW0*/
+#define R0900_P2_SFRLOW0 0xf263
+#define F0900_P2_SYMB_FREQ_LOW0 0xf26300ff
+
+/*P2_SFR3*/
+#define R0900_P2_SFR3 0xf264
+#define F0900_P2_SYMB_FREQ3 0xf26400ff
+
+/*P2_SFR2*/
+#define R0900_P2_SFR2 0xf265
+#define F0900_P2_SYMB_FREQ2 0xf26500ff
+
+/*P2_SFR1*/
+#define R0900_P2_SFR1 0xf266
+#define F0900_P2_SYMB_FREQ1 0xf26600ff
+
+/*P2_SFR0*/
+#define R0900_P2_SFR0 0xf267
+#define F0900_P2_SYMB_FREQ0 0xf26700ff
+
+/*P2_TMGREG2*/
+#define R0900_P2_TMGREG2 0xf268
+#define F0900_P2_TMGREG2 0xf26800ff
+
+/*P2_TMGREG1*/
+#define R0900_P2_TMGREG1 0xf269
+#define F0900_P2_TMGREG1 0xf26900ff
+
+/*P2_TMGREG0*/
+#define R0900_P2_TMGREG0 0xf26a
+#define F0900_P2_TMGREG0 0xf26a00ff
+
+/*P2_TMGLOCK1*/
+#define R0900_P2_TMGLOCK1 0xf26b
+#define F0900_P2_TMGLOCK_LEVEL1 0xf26b01ff
+
+/*P2_TMGLOCK0*/
+#define R0900_P2_TMGLOCK0 0xf26c
+#define F0900_P2_TMGLOCK_LEVEL0 0xf26c00ff
+
+/*P2_TMGOBS*/
+#define R0900_P2_TMGOBS 0xf26d
+#define F0900_P2_ROLLOFF_STATUS 0xf26d00c0
+#define F0900_P2_SCAN_SIGN 0xf26d0030
+#define F0900_P2_TMG_SCANNING 0xf26d0008
+#define F0900_P2_CHCENTERING_MODE 0xf26d0004
+#define F0900_P2_TMG_SCANFAIL 0xf26d0002
+
+/*P2_EQUALCFG*/
+#define R0900_P2_EQUALCFG 0xf26f
+#define F0900_P2_NOTMG_NEGALWAIT 0xf26f0080
+#define F0900_P2_EQUAL_ON 0xf26f0040
+#define F0900_P2_SEL_EQUALCOR 0xf26f0038
+#define F0900_P2_MU_EQUALDFE 0xf26f0007
+
+/*P2_EQUAI1*/
+#define R0900_P2_EQUAI1 0xf270
+#define F0900_P2_EQUA_ACCI1 0xf27001ff
+
+/*P2_EQUAQ1*/
+#define R0900_P2_EQUAQ1 0xf271
+#define F0900_P2_EQUA_ACCQ1 0xf27101ff
+
+/*P2_EQUAI2*/
+#define R0900_P2_EQUAI2 0xf272
+#define F0900_P2_EQUA_ACCI2 0xf27201ff
+
+/*P2_EQUAQ2*/
+#define R0900_P2_EQUAQ2 0xf273
+#define F0900_P2_EQUA_ACCQ2 0xf27301ff
+
+/*P2_EQUAI3*/
+#define R0900_P2_EQUAI3 0xf274
+#define F0900_P2_EQUA_ACCI3 0xf27401ff
+
+/*P2_EQUAQ3*/
+#define R0900_P2_EQUAQ3 0xf275
+#define F0900_P2_EQUA_ACCQ3 0xf27501ff
+
+/*P2_EQUAI4*/
+#define R0900_P2_EQUAI4 0xf276
+#define F0900_P2_EQUA_ACCI4 0xf27601ff
+
+/*P2_EQUAQ4*/
+#define R0900_P2_EQUAQ4 0xf277
+#define F0900_P2_EQUA_ACCQ4 0xf27701ff
+
+/*P2_EQUAI5*/
+#define R0900_P2_EQUAI5 0xf278
+#define F0900_P2_EQUA_ACCI5 0xf27801ff
+
+/*P2_EQUAQ5*/
+#define R0900_P2_EQUAQ5 0xf279
+#define F0900_P2_EQUA_ACCQ5 0xf27901ff
+
+/*P2_EQUAI6*/
+#define R0900_P2_EQUAI6 0xf27a
+#define F0900_P2_EQUA_ACCI6 0xf27a01ff
+
+/*P2_EQUAQ6*/
+#define R0900_P2_EQUAQ6 0xf27b
+#define F0900_P2_EQUA_ACCQ6 0xf27b01ff
+
+/*P2_EQUAI7*/
+#define R0900_P2_EQUAI7 0xf27c
+#define F0900_P2_EQUA_ACCI7 0xf27c01ff
+
+/*P2_EQUAQ7*/
+#define R0900_P2_EQUAQ7 0xf27d
+#define F0900_P2_EQUA_ACCQ7 0xf27d01ff
+
+/*P2_EQUAI8*/
+#define R0900_P2_EQUAI8 0xf27e
+#define F0900_P2_EQUA_ACCI8 0xf27e01ff
+
+/*P2_EQUAQ8*/
+#define R0900_P2_EQUAQ8 0xf27f
+#define F0900_P2_EQUA_ACCQ8 0xf27f01ff
+
+/*P2_NNOSDATAT1*/
+#define R0900_P2_NNOSDATAT1 0xf280
+#define F0900_P2_NOSDATAT_NORMED1 0xf28000ff
+
+/*P2_NNOSDATAT0*/
+#define R0900_P2_NNOSDATAT0 0xf281
+#define F0900_P2_NOSDATAT_NORMED0 0xf28100ff
+
+/*P2_NNOSDATA1*/
+#define R0900_P2_NNOSDATA1 0xf282
+#define F0900_P2_NOSDATA_NORMED1 0xf28200ff
+
+/*P2_NNOSDATA0*/
+#define R0900_P2_NNOSDATA0 0xf283
+#define F0900_P2_NOSDATA_NORMED0 0xf28300ff
+
+/*P2_NNOSPLHT1*/
+#define R0900_P2_NNOSPLHT1 0xf284
+#define F0900_P2_NOSPLHT_NORMED1 0xf28400ff
+
+/*P2_NNOSPLHT0*/
+#define R0900_P2_NNOSPLHT0 0xf285
+#define F0900_P2_NOSPLHT_NORMED0 0xf28500ff
+
+/*P2_NNOSPLH1*/
+#define R0900_P2_NNOSPLH1 0xf286
+#define F0900_P2_NOSPLH_NORMED1 0xf28600ff
+
+/*P2_NNOSPLH0*/
+#define R0900_P2_NNOSPLH0 0xf287
+#define F0900_P2_NOSPLH_NORMED0 0xf28700ff
+
+/*P2_NOSDATAT1*/
+#define R0900_P2_NOSDATAT1 0xf288
+#define F0900_P2_NOSDATAT_UNNORMED1 0xf28800ff
+
+/*P2_NOSDATAT0*/
+#define R0900_P2_NOSDATAT0 0xf289
+#define F0900_P2_NOSDATAT_UNNORMED0 0xf28900ff
+
+/*P2_NOSDATA1*/
+#define R0900_P2_NOSDATA1 0xf28a
+#define F0900_P2_NOSDATA_UNNORMED1 0xf28a00ff
+
+/*P2_NOSDATA0*/
+#define R0900_P2_NOSDATA0 0xf28b
+#define F0900_P2_NOSDATA_UNNORMED0 0xf28b00ff
+
+/*P2_NOSPLHT1*/
+#define R0900_P2_NOSPLHT1 0xf28c
+#define F0900_P2_NOSPLHT_UNNORMED1 0xf28c00ff
+
+/*P2_NOSPLHT0*/
+#define R0900_P2_NOSPLHT0 0xf28d
+#define F0900_P2_NOSPLHT_UNNORMED0 0xf28d00ff
+
+/*P2_NOSPLH1*/
+#define R0900_P2_NOSPLH1 0xf28e
+#define F0900_P2_NOSPLH_UNNORMED1 0xf28e00ff
+
+/*P2_NOSPLH0*/
+#define R0900_P2_NOSPLH0 0xf28f
+#define F0900_P2_NOSPLH_UNNORMED0 0xf28f00ff
+
+/*P2_CAR2CFG*/
+#define R0900_P2_CAR2CFG 0xf290
+#define F0900_P2_DESCRAMB_OFF 0xf2900080
+#define F0900_P2_PN4_SELECT 0xf2900040
+#define F0900_P2_CFR2_STOPDVBS1 0xf2900020
+#define F0900_P2_STOP_CFR2UPDATE 0xf2900010
+#define F0900_P2_STOP_NCO2UPDATE 0xf2900008
+#define F0900_P2_ROTA2ON 0xf2900004
+#define F0900_P2_PH_DET_ALGO2 0xf2900003
+
+/*P2_ACLC2*/
+#define R0900_P2_ACLC2 0xf291
+#define F0900_P2_CAR2_PUNCT_ADERAT 0xf2910040
+#define F0900_P2_CAR2_ALPHA_MANT 0xf2910030
+#define F0900_P2_CAR2_ALPHA_EXP 0xf291000f
+
+/*P2_BCLC2*/
+#define R0900_P2_BCLC2 0xf292
+#define F0900_P2_DVBS2_NIP 0xf2920080
+#define F0900_P2_CAR2_PUNCT_BDERAT 0xf2920040
+#define F0900_P2_CAR2_BETA_MANT 0xf2920030
+#define F0900_P2_CAR2_BETA_EXP 0xf292000f
+
+/*P2_CFR22*/
+#define R0900_P2_CFR22 0xf293
+#define F0900_P2_CAR2_FREQ2 0xf29301ff
+
+/*P2_CFR21*/
+#define R0900_P2_CFR21 0xf294
+#define F0900_P2_CAR2_FREQ1 0xf29400ff
+
+/*P2_CFR20*/
+#define R0900_P2_CFR20 0xf295
+#define F0900_P2_CAR2_FREQ0 0xf29500ff
+
+/*P2_ACLC2S2Q*/
+#define R0900_P2_ACLC2S2Q 0xf297
+#define F0900_P2_ENAB_SPSKSYMB 0xf2970080
+#define F0900_P2_CAR2S2_QADERAT 0xf2970040
+#define F0900_P2_CAR2S2_Q_ALPH_M 0xf2970030
+#define F0900_P2_CAR2S2_Q_ALPH_E 0xf297000f
+
+/*P2_ACLC2S28*/
+#define R0900_P2_ACLC2S28 0xf298
+#define F0900_P2_OLDI3Q_MODE 0xf2980080
+#define F0900_P2_CAR2S2_8ADERAT 0xf2980040
+#define F0900_P2_CAR2S2_8_ALPH_M 0xf2980030
+#define F0900_P2_CAR2S2_8_ALPH_E 0xf298000f
+
+/*P2_ACLC2S216A*/
+#define R0900_P2_ACLC2S216A 0xf299
+#define F0900_P2_CAR2S2_16ADERAT 0xf2990040
+#define F0900_P2_CAR2S2_16A_ALPH_M 0xf2990030
+#define F0900_P2_CAR2S2_16A_ALPH_E 0xf299000f
+
+/*P2_ACLC2S232A*/
+#define R0900_P2_ACLC2S232A 0xf29a
+#define F0900_P2_CAR2S2_32ADERAT 0xf29a0040
+#define F0900_P2_CAR2S2_32A_ALPH_M 0xf29a0030
+#define F0900_P2_CAR2S2_32A_ALPH_E 0xf29a000f
+
+/*P2_BCLC2S2Q*/
+#define R0900_P2_BCLC2S2Q 0xf29c
+#define F0900_P2_DVBS2S2Q_NIP 0xf29c0080
+#define F0900_P2_CAR2S2_QBDERAT 0xf29c0040
+#define F0900_P2_CAR2S2_Q_BETA_M 0xf29c0030
+#define F0900_P2_CAR2S2_Q_BETA_E 0xf29c000f
+
+/*P2_BCLC2S28*/
+#define R0900_P2_BCLC2S28 0xf29d
+#define F0900_P2_DVBS2S28_NIP 0xf29d0080
+#define F0900_P2_CAR2S2_8BDERAT 0xf29d0040
+#define F0900_P2_CAR2S2_8_BETA_M 0xf29d0030
+#define F0900_P2_CAR2S2_8_BETA_E 0xf29d000f
+
+/*P2_BCLC2S216A*/
+#define R0900_P2_BCLC2S216A 0xf29e
+#define F0900_P2_DVBS2S216A_NIP 0xf29e0080
+#define F0900_P2_CAR2S2_16BDERAT 0xf29e0040
+#define F0900_P2_CAR2S2_16A_BETA_M 0xf29e0030
+#define F0900_P2_CAR2S2_16A_BETA_E 0xf29e000f
+
+/*P2_BCLC2S232A*/
+#define R0900_P2_BCLC2S232A 0xf29f
+#define F0900_P2_DVBS2S232A_NIP 0xf29f0080
+#define F0900_P2_CAR2S2_32BDERAT 0xf29f0040
+#define F0900_P2_CAR2S2_32A_BETA_M 0xf29f0030
+#define F0900_P2_CAR2S2_32A_BETA_E 0xf29f000f
+
+/*P2_PLROOT2*/
+#define R0900_P2_PLROOT2 0xf2ac
+#define F0900_P2_SHORTFR_DISABLE 0xf2ac0080
+#define F0900_P2_LONGFR_DISABLE 0xf2ac0040
+#define F0900_P2_DUMMYPL_DISABLE 0xf2ac0020
+#define F0900_P2_SHORTFR_AVOID 0xf2ac0010
+#define F0900_P2_PLSCRAMB_MODE 0xf2ac000c
+#define F0900_P2_PLSCRAMB_ROOT2 0xf2ac0003
+
+/*P2_PLROOT1*/
+#define R0900_P2_PLROOT1 0xf2ad
+#define F0900_P2_PLSCRAMB_ROOT1 0xf2ad00ff
+
+/*P2_PLROOT0*/
+#define R0900_P2_PLROOT0 0xf2ae
+#define F0900_P2_PLSCRAMB_ROOT0 0xf2ae00ff
+
+/*P2_MODCODLST0*/
+#define R0900_P2_MODCODLST0 0xf2b0
+#define F0900_P2_EN_TOKEN31 0xf2b00080
+#define F0900_P2_SYNCTAG_SELECT 0xf2b00040
+#define F0900_P2_MODCODRQ_MODE 0xf2b00030
+
+/*P2_MODCODLST1*/
+#define R0900_P2_MODCODLST1 0xf2b1
+#define F0900_P2_DIS_MODCOD29 0xf2b100f0
+#define F0900_P2_DIS_32PSK_9_10 0xf2b1000f
+
+/*P2_MODCODLST2*/
+#define R0900_P2_MODCODLST2 0xf2b2
+#define F0900_P2_DIS_32PSK_8_9 0xf2b200f0
+#define F0900_P2_DIS_32PSK_5_6 0xf2b2000f
+
+/*P2_MODCODLST3*/
+#define R0900_P2_MODCODLST3 0xf2b3
+#define F0900_P2_DIS_32PSK_4_5 0xf2b300f0
+#define F0900_P2_DIS_32PSK_3_4 0xf2b3000f
+
+/*P2_MODCODLST4*/
+#define R0900_P2_MODCODLST4 0xf2b4
+#define F0900_P2_DIS_16PSK_9_10 0xf2b400f0
+#define F0900_P2_DIS_16PSK_8_9 0xf2b4000f
+
+/*P2_MODCODLST5*/
+#define R0900_P2_MODCODLST5 0xf2b5
+#define F0900_P2_DIS_16PSK_5_6 0xf2b500f0
+#define F0900_P2_DIS_16PSK_4_5 0xf2b5000f
+
+/*P2_MODCODLST6*/
+#define R0900_P2_MODCODLST6 0xf2b6
+#define F0900_P2_DIS_16PSK_3_4 0xf2b600f0
+#define F0900_P2_DIS_16PSK_2_3 0xf2b6000f
+
+/*P2_MODCODLST7*/
+#define R0900_P2_MODCODLST7 0xf2b7
+#define F0900_P2_DIS_8P_9_10 0xf2b700f0
+#define F0900_P2_DIS_8P_8_9 0xf2b7000f
+
+/*P2_MODCODLST8*/
+#define R0900_P2_MODCODLST8 0xf2b8
+#define F0900_P2_DIS_8P_5_6 0xf2b800f0
+#define F0900_P2_DIS_8P_3_4 0xf2b8000f
+
+/*P2_MODCODLST9*/
+#define R0900_P2_MODCODLST9 0xf2b9
+#define F0900_P2_DIS_8P_2_3 0xf2b900f0
+#define F0900_P2_DIS_8P_3_5 0xf2b9000f
+
+/*P2_MODCODLSTA*/
+#define R0900_P2_MODCODLSTA 0xf2ba
+#define F0900_P2_DIS_QP_9_10 0xf2ba00f0
+#define F0900_P2_DIS_QP_8_9 0xf2ba000f
+
+/*P2_MODCODLSTB*/
+#define R0900_P2_MODCODLSTB 0xf2bb
+#define F0900_P2_DIS_QP_5_6 0xf2bb00f0
+#define F0900_P2_DIS_QP_4_5 0xf2bb000f
+
+/*P2_MODCODLSTC*/
+#define R0900_P2_MODCODLSTC 0xf2bc
+#define F0900_P2_DIS_QP_3_4 0xf2bc00f0
+#define F0900_P2_DIS_QP_2_3 0xf2bc000f
+
+/*P2_MODCODLSTD*/
+#define R0900_P2_MODCODLSTD 0xf2bd
+#define F0900_P2_DIS_QP_3_5 0xf2bd00f0
+#define F0900_P2_DIS_QP_1_2 0xf2bd000f
+
+/*P2_MODCODLSTE*/
+#define R0900_P2_MODCODLSTE 0xf2be
+#define F0900_P2_DIS_QP_2_5 0xf2be00f0
+#define F0900_P2_DIS_QP_1_3 0xf2be000f
+
+/*P2_MODCODLSTF*/
+#define R0900_P2_MODCODLSTF 0xf2bf
+#define F0900_P2_DIS_QP_1_4 0xf2bf00f0
+#define F0900_P2_DDEMOD_SET 0xf2bf0002
+#define F0900_P2_DDEMOD_MASK 0xf2bf0001
+
+/*P2_DMDRESCFG*/
+#define R0900_P2_DMDRESCFG 0xf2c6
+#define F0900_P2_DMDRES_RESET 0xf2c60080
+#define F0900_P2_DMDRES_NOISESQR 0xf2c60010
+#define F0900_P2_DMDRES_STRALL 0xf2c60008
+#define F0900_P2_DMDRES_NEWONLY 0xf2c60004
+#define F0900_P2_DMDRES_NOSTORE 0xf2c60002
+#define F0900_P2_DMDRES_AGC2MEM 0xf2c60001
+
+/*P2_DMDRESADR*/
+#define R0900_P2_DMDRESADR 0xf2c7
+#define F0900_P2_SUSP_PREDCANAL 0xf2c70080
+#define F0900_P2_DMDRES_VALIDCFR 0xf2c70040
+#define F0900_P2_DMDRES_MEMFULL 0xf2c70030
+#define F0900_P2_DMDRES_RESNBR 0xf2c7000f
+
+/*P2_DMDRESDATA7*/
+#define R0900_P2_DMDRESDATA7 0xf2c8
+#define F0900_P2_DMDRES_DATA7 0xf2c800ff
+
+/*P2_DMDRESDATA6*/
+#define R0900_P2_DMDRESDATA6 0xf2c9
+#define F0900_P2_DMDRES_DATA6 0xf2c900ff
+
+/*P2_DMDRESDATA5*/
+#define R0900_P2_DMDRESDATA5 0xf2ca
+#define F0900_P2_DMDRES_DATA5 0xf2ca00ff
+
+/*P2_DMDRESDATA4*/
+#define R0900_P2_DMDRESDATA4 0xf2cb
+#define F0900_P2_DMDRES_DATA4 0xf2cb00ff
+
+/*P2_DMDRESDATA3*/
+#define R0900_P2_DMDRESDATA3 0xf2cc
+#define F0900_P2_DMDRES_DATA3 0xf2cc00ff
+
+/*P2_DMDRESDATA2*/
+#define R0900_P2_DMDRESDATA2 0xf2cd
+#define F0900_P2_DMDRES_DATA2 0xf2cd00ff
+
+/*P2_DMDRESDATA1*/
+#define R0900_P2_DMDRESDATA1 0xf2ce
+#define F0900_P2_DMDRES_DATA1 0xf2ce00ff
+
+/*P2_DMDRESDATA0*/
+#define R0900_P2_DMDRESDATA0 0xf2cf
+#define F0900_P2_DMDRES_DATA0 0xf2cf00ff
+
+/*P2_FFEI1*/
+#define R0900_P2_FFEI1 0xf2d0
+#define F0900_P2_FFE_ACCI1 0xf2d001ff
+
+/*P2_FFEQ1*/
+#define R0900_P2_FFEQ1 0xf2d1
+#define F0900_P2_FFE_ACCQ1 0xf2d101ff
+
+/*P2_FFEI2*/
+#define R0900_P2_FFEI2 0xf2d2
+#define F0900_P2_FFE_ACCI2 0xf2d201ff
+
+/*P2_FFEQ2*/
+#define R0900_P2_FFEQ2 0xf2d3
+#define F0900_P2_FFE_ACCQ2 0xf2d301ff
+
+/*P2_FFEI3*/
+#define R0900_P2_FFEI3 0xf2d4
+#define F0900_P2_FFE_ACCI3 0xf2d401ff
+
+/*P2_FFEQ3*/
+#define R0900_P2_FFEQ3 0xf2d5
+#define F0900_P2_FFE_ACCQ3 0xf2d501ff
+
+/*P2_FFEI4*/
+#define R0900_P2_FFEI4 0xf2d6
+#define F0900_P2_FFE_ACCI4 0xf2d601ff
+
+/*P2_FFEQ4*/
+#define R0900_P2_FFEQ4 0xf2d7
+#define F0900_P2_FFE_ACCQ4 0xf2d701ff
+
+/*P2_FFECFG*/
+#define R0900_P2_FFECFG 0xf2d8
+#define F0900_P2_EQUALFFE_ON 0xf2d80040
+#define F0900_P2_EQUAL_USEDSYMB 0xf2d80030
+#define F0900_P2_MU_EQUALFFE 0xf2d80007
+
+/*P2_TNRCFG*/
+#define R0900_P2_TNRCFG 0xf2e0
+#define F0900_P2_TUN_ACKFAIL 0xf2e00080
+#define F0900_P2_TUN_TYPE 0xf2e00070
+#define F0900_P2_TUN_SECSTOP 0xf2e00008
+#define F0900_P2_TUN_VCOSRCH 0xf2e00004
+#define F0900_P2_TUN_MADDRESS 0xf2e00003
+
+/*P2_TNRCFG2*/
+#define R0900_P2_TNRCFG2 0xf2e1
+#define F0900_P2_TUN_IQSWAP 0xf2e10080
+#define F0900_P2_STB6110_STEP2MHZ 0xf2e10040
+#define F0900_P2_STB6120_DBLI2C 0xf2e10020
+#define F0900_P2_DIS_FCCK 0xf2e10010
+#define F0900_P2_DIS_LPEN 0xf2e10008
+#define F0900_P2_DIS_BWCALC 0xf2e10004
+#define F0900_P2_SHORT_WAITSTATES 0xf2e10002
+#define F0900_P2_DIS_2BWAGC1 0xf2e10001
+
+/*P2_TNRXTAL*/
+#define R0900_P2_TNRXTAL 0xf2e4
+#define F0900_P2_TUN_MCLKDECIMAL 0xf2e400e0
+#define F0900_P2_TUN_XTALFREQ 0xf2e4001f
+
+/*P2_TNRSTEPS*/
+#define R0900_P2_TNRSTEPS 0xf2e7
+#define F0900_P2_TUNER_BW1P6 0xf2e70080
+#define F0900_P2_BWINC_OFFSET 0xf2e70070
+#define F0900_P2_SOFTSTEP_RNG 0xf2e70008
+#define F0900_P2_TUN_BWOFFSET 0xf2e70107
+
+/*P2_TNRGAIN*/
+#define R0900_P2_TNRGAIN 0xf2e8
+#define F0900_P2_TUN_KDIVEN 0xf2e800c0
+#define F0900_P2_STB6X00_OCK 0xf2e80030
+#define F0900_P2_TUN_GAIN 0xf2e8000f
+
+/*P2_TNRRF1*/
+#define R0900_P2_TNRRF1 0xf2e9
+#define F0900_P2_TUN_RFFREQ2 0xf2e900ff
+
+/*P2_TNRRF0*/
+#define R0900_P2_TNRRF0 0xf2ea
+#define F0900_P2_TUN_RFFREQ1 0xf2ea00ff
+
+/*P2_TNRBW*/
+#define R0900_P2_TNRBW 0xf2eb
+#define F0900_P2_TUN_RFFREQ0 0xf2eb00c0
+#define F0900_P2_TUN_BW 0xf2eb003f
+
+/*P2_TNRADJ*/
+#define R0900_P2_TNRADJ 0xf2ec
+#define F0900_P2_STB61X0_RCLK 0xf2ec0080
+#define F0900_P2_STB61X0_CALTIME 0xf2ec0040
+#define F0900_P2_STB6X00_DLB 0xf2ec0038
+#define F0900_P2_STB6000_FCL 0xf2ec0007
+
+/*P2_TNRCTL2*/
+#define R0900_P2_TNRCTL2 0xf2ed
+#define F0900_P2_STB61X0_LCP1_RCCKOFF 0xf2ed0080
+#define F0900_P2_STB61X0_LCP0 0xf2ed0040
+#define F0900_P2_STB61X0_XTOUT_RFOUTS 0xf2ed0020
+#define F0900_P2_STB61X0_XTON_MCKDV 0xf2ed0010
+#define F0900_P2_STB61X0_CALOFF_DCOFF 0xf2ed0008
+#define F0900_P2_STB6110_LPT 0xf2ed0004
+#define F0900_P2_STB6110_RX 0xf2ed0002
+#define F0900_P2_STB6110_SYN 0xf2ed0001
+
+/*P2_TNRCFG3*/
+#define R0900_P2_TNRCFG3 0xf2ee
+#define F0900_P2_STB6120_DISCTRL1 0xf2ee0080
+#define F0900_P2_STB6120_INVORDER 0xf2ee0040
+#define F0900_P2_STB6120_ENCTRL6 0xf2ee0020
+#define F0900_P2_TUN_PLLFREQ 0xf2ee001c
+#define F0900_P2_TUN_I2CFREQ_MODE 0xf2ee0003
+
+/*P2_TNRLAUNCH*/
+#define R0900_P2_TNRLAUNCH 0xf2f0
+
+/*P2_TNRLD*/
+#define R0900_P2_TNRLD 0xf2f0
+#define F0900_P2_TUNLD_VCOING 0xf2f00080
+#define F0900_P2_TUN_REG1FAIL 0xf2f00040
+#define F0900_P2_TUN_REG2FAIL 0xf2f00020
+#define F0900_P2_TUN_REG3FAIL 0xf2f00010
+#define F0900_P2_TUN_REG4FAIL 0xf2f00008
+#define F0900_P2_TUN_REG5FAIL 0xf2f00004
+#define F0900_P2_TUN_BWING 0xf2f00002
+#define F0900_P2_TUN_LOCKED 0xf2f00001
+
+/*P2_TNROBSL*/
+#define R0900_P2_TNROBSL 0xf2f6
+#define F0900_P2_TUN_I2CABORTED 0xf2f60080
+#define F0900_P2_TUN_LPEN 0xf2f60040
+#define F0900_P2_TUN_FCCK 0xf2f60020
+#define F0900_P2_TUN_I2CLOCKED 0xf2f60010
+#define F0900_P2_TUN_PROGDONE 0xf2f6000c
+#define F0900_P2_TUN_RFRESTE1 0xf2f60003
+
+/*P2_TNRRESTE*/
+#define R0900_P2_TNRRESTE 0xf2f7
+#define F0900_P2_TUN_RFRESTE0 0xf2f700ff
+
+/*P2_SMAPCOEF7*/
+#define R0900_P2_SMAPCOEF7 0xf300
+#define F0900_P2_DIS_QSCALE 0xf3000080
+#define F0900_P2_SMAPCOEF_Q_LLR12 0xf300017f
+
+/*P2_SMAPCOEF6*/
+#define R0900_P2_SMAPCOEF6 0xf301
+#define F0900_P2_DIS_NEWSCALE 0xf3010008
+#define F0900_P2_ADJ_8PSKLLR1 0xf3010004
+#define F0900_P2_OLD_8PSKLLR1 0xf3010002
+#define F0900_P2_DIS_AB8PSK 0xf3010001
+
+/*P2_SMAPCOEF5*/
+#define R0900_P2_SMAPCOEF5 0xf302
+#define F0900_P2_DIS_8SCALE 0xf3020080
+#define F0900_P2_SMAPCOEF_8P_LLR23 0xf302017f
+
+/*P2_DMDPLHSTAT*/
+#define R0900_P2_DMDPLHSTAT 0xf320
+#define F0900_P2_PLH_STATISTIC 0xf32000ff
+
+/*P2_LOCKTIME3*/
+#define R0900_P2_LOCKTIME3 0xf322
+#define F0900_P2_DEMOD_LOCKTIME3 0xf32200ff
+
+/*P2_LOCKTIME2*/
+#define R0900_P2_LOCKTIME2 0xf323
+#define F0900_P2_DEMOD_LOCKTIME2 0xf32300ff
+
+/*P2_LOCKTIME1*/
+#define R0900_P2_LOCKTIME1 0xf324
+#define F0900_P2_DEMOD_LOCKTIME1 0xf32400ff
+
+/*P2_LOCKTIME0*/
+#define R0900_P2_LOCKTIME0 0xf325
+#define F0900_P2_DEMOD_LOCKTIME0 0xf32500ff
+
+/*P2_VITSCALE*/
+#define R0900_P2_VITSCALE 0xf332
+#define F0900_P2_NVTH_NOSRANGE 0xf3320080
+#define F0900_P2_VERROR_MAXMODE 0xf3320040
+#define F0900_P2_KDIV_MODE 0xf3320030
+#define F0900_P2_NSLOWSN_LOCKED 0xf3320008
+#define F0900_P2_DELOCK_PRFLOSS 0xf3320004
+#define F0900_P2_DIS_RSFLOCK 0xf3320002
+
+/*P2_FECM*/
+#define R0900_P2_FECM 0xf333
+#define F0900_P2_DSS_DVB 0xf3330080
+#define F0900_P2_DEMOD_BYPASS 0xf3330040
+#define F0900_P2_CMP_SLOWMODE 0xf3330020
+#define F0900_P2_DSS_SRCH 0xf3330010
+#define F0900_P2_DIFF_MODEVIT 0xf3330004
+#define F0900_P2_SYNCVIT 0xf3330002
+#define F0900_P2_IQINV 0xf3330001
+
+/*P2_VTH12*/
+#define R0900_P2_VTH12 0xf334
+#define F0900_P2_VTH12 0xf33400ff
+
+/*P2_VTH23*/
+#define R0900_P2_VTH23 0xf335
+#define F0900_P2_VTH23 0xf33500ff
+
+/*P2_VTH34*/
+#define R0900_P2_VTH34 0xf336
+#define F0900_P2_VTH34 0xf33600ff
+
+/*P2_VTH56*/
+#define R0900_P2_VTH56 0xf337
+#define F0900_P2_VTH56 0xf33700ff
+
+/*P2_VTH67*/
+#define R0900_P2_VTH67 0xf338
+#define F0900_P2_VTH67 0xf33800ff
+
+/*P2_VTH78*/
+#define R0900_P2_VTH78 0xf339
+#define F0900_P2_VTH78 0xf33900ff
+
+/*P2_VITCURPUN*/
+#define R0900_P2_VITCURPUN 0xf33a
+#define F0900_P2_VIT_MAPPING 0xf33a00e0
+#define F0900_P2_VIT_CURPUN 0xf33a001f
+
+/*P2_VERROR*/
+#define R0900_P2_VERROR 0xf33b
+#define F0900_P2_REGERR_VIT 0xf33b00ff
+
+/*P2_PRVIT*/
+#define R0900_P2_PRVIT 0xf33c
+#define F0900_P2_DIS_VTHLOCK 0xf33c0040
+#define F0900_P2_E7_8VIT 0xf33c0020
+#define F0900_P2_E6_7VIT 0xf33c0010
+#define F0900_P2_E5_6VIT 0xf33c0008
+#define F0900_P2_E3_4VIT 0xf33c0004
+#define F0900_P2_E2_3VIT 0xf33c0002
+#define F0900_P2_E1_2VIT 0xf33c0001
+
+/*P2_VAVSRVIT*/
+#define R0900_P2_VAVSRVIT 0xf33d
+#define F0900_P2_AMVIT 0xf33d0080
+#define F0900_P2_FROZENVIT 0xf33d0040
+#define F0900_P2_SNVIT 0xf33d0030
+#define F0900_P2_TOVVIT 0xf33d000c
+#define F0900_P2_HYPVIT 0xf33d0003
+
+/*P2_VSTATUSVIT*/
+#define R0900_P2_VSTATUSVIT 0xf33e
+#define F0900_P2_VITERBI_ON 0xf33e0080
+#define F0900_P2_END_LOOPVIT 0xf33e0040
+#define F0900_P2_VITERBI_DEPRF 0xf33e0020
+#define F0900_P2_PRFVIT 0xf33e0010
+#define F0900_P2_LOCKEDVIT 0xf33e0008
+#define F0900_P2_VITERBI_DELOCK 0xf33e0004
+#define F0900_P2_VIT_DEMODSEL 0xf33e0002
+#define F0900_P2_VITERBI_COMPOUT 0xf33e0001
+
+/*P2_VTHINUSE*/
+#define R0900_P2_VTHINUSE 0xf33f
+#define F0900_P2_VIT_INUSE 0xf33f00ff
+
+/*P2_KDIV12*/
+#define R0900_P2_KDIV12 0xf340
+#define F0900_P2_KDIV12_MANUAL 0xf3400080
+#define F0900_P2_K_DIVIDER_12 0xf340007f
+
+/*P2_KDIV23*/
+#define R0900_P2_KDIV23 0xf341
+#define F0900_P2_KDIV23_MANUAL 0xf3410080
+#define F0900_P2_K_DIVIDER_23 0xf341007f
+
+/*P2_KDIV34*/
+#define R0900_P2_KDIV34 0xf342
+#define F0900_P2_KDIV34_MANUAL 0xf3420080
+#define F0900_P2_K_DIVIDER_34 0xf342007f
+
+/*P2_KDIV56*/
+#define R0900_P2_KDIV56 0xf343
+#define F0900_P2_KDIV56_MANUAL 0xf3430080
+#define F0900_P2_K_DIVIDER_56 0xf343007f
+
+/*P2_KDIV67*/
+#define R0900_P2_KDIV67 0xf344
+#define F0900_P2_KDIV67_MANUAL 0xf3440080
+#define F0900_P2_K_DIVIDER_67 0xf344007f
+
+/*P2_KDIV78*/
+#define R0900_P2_KDIV78 0xf345
+#define F0900_P2_KDIV78_MANUAL 0xf3450080
+#define F0900_P2_K_DIVIDER_78 0xf345007f
+
+/*P2_PDELCTRL1*/
+#define R0900_P2_PDELCTRL1 0xf350
+#define F0900_P2_INV_MISMASK 0xf3500080
+#define F0900_P2_FORCE_ACCEPTED 0xf3500040
+#define F0900_P2_FILTER_EN 0xf3500020
+#define F0900_P2_FORCE_PKTDELINUSE 0xf3500010
+#define F0900_P2_HYSTEN 0xf3500008
+#define F0900_P2_HYSTSWRST 0xf3500004
+#define F0900_P2_EN_MIS00 0xf3500002
+#define F0900_P2_ALGOSWRST 0xf3500001
+
+/*P2_PDELCTRL2*/
+#define R0900_P2_PDELCTRL2 0xf351
+#define F0900_P2_FORCE_CONTINUOUS 0xf3510080
+#define F0900_P2_RESET_UPKO_COUNT 0xf3510040
+#define F0900_P2_USER_PKTDELIN_NB 0xf3510020
+#define F0900_P2_FORCE_LOCKED 0xf3510010
+#define F0900_P2_DATA_UNBBSCRAM 0xf3510008
+#define F0900_P2_FORCE_LONGPKT 0xf3510004
+#define F0900_P2_FRAME_MODE 0xf3510002
+
+/*P2_HYSTTHRESH*/
+#define R0900_P2_HYSTTHRESH 0xf354
+#define F0900_P2_UNLCK_THRESH 0xf35400f0
+#define F0900_P2_DELIN_LCK_THRESH 0xf354000f
+
+/*P2_ISIENTRY*/
+#define R0900_P2_ISIENTRY 0xf35e
+#define F0900_P2_ISI_ENTRY 0xf35e00ff
+
+/*P2_ISIBITENA*/
+#define R0900_P2_ISIBITENA 0xf35f
+#define F0900_P2_ISI_BIT_EN 0xf35f00ff
+
+/*P2_MATSTR1*/
+#define R0900_P2_MATSTR1 0xf360
+#define F0900_P2_MATYPE_CURRENT1 0xf36000ff
+
+/*P2_MATSTR0*/
+#define R0900_P2_MATSTR0 0xf361
+#define F0900_P2_MATYPE_CURRENT0 0xf36100ff
+
+/*P2_UPLSTR1*/
+#define R0900_P2_UPLSTR1 0xf362
+#define F0900_P2_UPL_CURRENT1 0xf36200ff
+
+/*P2_UPLSTR0*/
+#define R0900_P2_UPLSTR0 0xf363
+#define F0900_P2_UPL_CURRENT0 0xf36300ff
+
+/*P2_DFLSTR1*/
+#define R0900_P2_DFLSTR1 0xf364
+#define F0900_P2_DFL_CURRENT1 0xf36400ff
+
+/*P2_DFLSTR0*/
+#define R0900_P2_DFLSTR0 0xf365
+#define F0900_P2_DFL_CURRENT0 0xf36500ff
+
+/*P2_SYNCSTR*/
+#define R0900_P2_SYNCSTR 0xf366
+#define F0900_P2_SYNC_CURRENT 0xf36600ff
+
+/*P2_SYNCDSTR1*/
+#define R0900_P2_SYNCDSTR1 0xf367
+#define F0900_P2_SYNCD_CURRENT1 0xf36700ff
+
+/*P2_SYNCDSTR0*/
+#define R0900_P2_SYNCDSTR0 0xf368
+#define F0900_P2_SYNCD_CURRENT0 0xf36800ff
+
+/*P2_PDELSTATUS1*/
+#define R0900_P2_PDELSTATUS1 0xf369
+#define F0900_P2_PKTDELIN_DELOCK 0xf3690080
+#define F0900_P2_SYNCDUPDFL_BADDFL 0xf3690040
+#define F0900_P2_CONTINUOUS_STREAM 0xf3690020
+#define F0900_P2_UNACCEPTED_STREAM 0xf3690010
+#define F0900_P2_BCH_ERROR_FLAG 0xf3690008
+#define F0900_P2_BBHCRCKO 0xf3690004
+#define F0900_P2_PKTDELIN_LOCK 0xf3690002
+#define F0900_P2_FIRST_LOCK 0xf3690001
+
+/*P2_PDELSTATUS2*/
+#define R0900_P2_PDELSTATUS2 0xf36a
+#define F0900_P2_PKTDEL_DEMODSEL 0xf36a0080
+#define F0900_P2_FRAME_MODCOD 0xf36a007c
+#define F0900_P2_FRAME_TYPE 0xf36a0003
+
+/*P2_BBFCRCKO1*/
+#define R0900_P2_BBFCRCKO1 0xf36b
+#define F0900_P2_BBHCRC_KOCNT1 0xf36b00ff
+
+/*P2_BBFCRCKO0*/
+#define R0900_P2_BBFCRCKO0 0xf36c
+#define F0900_P2_BBHCRC_KOCNT0 0xf36c00ff
+
+/*P2_UPCRCKO1*/
+#define R0900_P2_UPCRCKO1 0xf36d
+#define F0900_P2_PKTCRC_KOCNT1 0xf36d00ff
+
+/*P2_UPCRCKO0*/
+#define R0900_P2_UPCRCKO0 0xf36e
+#define F0900_P2_PKTCRC_KOCNT0 0xf36e00ff
+
+/*P2_TSSTATEM*/
+#define R0900_P2_TSSTATEM 0xf370
+#define F0900_P2_TSDIL_ON 0xf3700080
+#define F0900_P2_TSSKIPRS_ON 0xf3700040
+#define F0900_P2_TSRS_ON 0xf3700020
+#define F0900_P2_TSDESCRAMB_ON 0xf3700010
+#define F0900_P2_TSFRAME_MODE 0xf3700008
+#define F0900_P2_TS_DISABLE 0xf3700004
+#define F0900_P2_TSACM_MODE 0xf3700002
+#define F0900_P2_TSOUT_NOSYNC 0xf3700001
+
+/*P2_TSCFGH*/
+#define R0900_P2_TSCFGH 0xf372
+#define F0900_P2_TSFIFO_DVBCI 0xf3720080
+#define F0900_P2_TSFIFO_SERIAL 0xf3720040
+#define F0900_P2_TSFIFO_TEIUPDATE 0xf3720020
+#define F0900_P2_TSFIFO_DUTY50 0xf3720010
+#define F0900_P2_TSFIFO_HSGNLOUT 0xf3720008
+#define F0900_P2_TSFIFO_ERRMODE 0xf3720006
+#define F0900_P2_RST_HWARE 0xf3720001
+
+/*P2_TSCFGM*/
+#define R0900_P2_TSCFGM 0xf373
+#define F0900_P2_TSFIFO_MANSPEED 0xf37300c0
+#define F0900_P2_TSFIFO_PERMDATA 0xf3730020
+#define F0900_P2_TSFIFO_NONEWSGNL 0xf3730010
+#define F0900_P2_TSFIFO_BITSPEED 0xf3730008
+#define F0900_P2_NPD_SPECDVBS2 0xf3730004
+#define F0900_P2_TSFIFO_STOPCKDIS 0xf3730002
+#define F0900_P2_TSFIFO_INVDATA 0xf3730001
+
+/*P2_TSCFGL*/
+#define R0900_P2_TSCFGL 0xf374
+#define F0900_P2_TSFIFO_BCLKDEL1CK 0xf37400c0
+#define F0900_P2_BCHERROR_MODE 0xf3740030
+#define F0900_P2_TSFIFO_NSGNL2DATA 0xf3740008
+#define F0900_P2_TSFIFO_EMBINDVB 0xf3740004
+#define F0900_P2_TSFIFO_DPUNACT 0xf3740002
+#define F0900_P2_TSFIFO_NPDOFF 0xf3740001
+
+/*P2_TSINSDELH*/
+#define R0900_P2_TSINSDELH 0xf376
+#define F0900_P2_TSDEL_SYNCBYTE 0xf3760080
+#define F0900_P2_TSDEL_XXHEADER 0xf3760040
+#define F0900_P2_TSDEL_BBHEADER 0xf3760020
+#define F0900_P2_TSDEL_DATAFIELD 0xf3760010
+#define F0900_P2_TSINSDEL_ISCR 0xf3760008
+#define F0900_P2_TSINSDEL_NPD 0xf3760004
+#define F0900_P2_TSINSDEL_RSPARITY 0xf3760002
+#define F0900_P2_TSINSDEL_CRC8 0xf3760001
+
+/*P2_TSSPEED*/
+#define R0900_P2_TSSPEED 0xf380
+#define F0900_P2_TSFIFO_OUTSPEED 0xf38000ff
+
+/*P2_TSSTATUS*/
+#define R0900_P2_TSSTATUS 0xf381
+#define F0900_P2_TSFIFO_LINEOK 0xf3810080
+#define F0900_P2_TSFIFO_ERROR 0xf3810040
+#define F0900_P2_TSFIFO_DATA7 0xf3810020
+#define F0900_P2_TSFIFO_NOSYNC 0xf3810010
+#define F0900_P2_ISCR_INITIALIZED 0xf3810008
+#define F0900_P2_ISCR_UPDATED 0xf3810004
+#define F0900_P2_SOFFIFO_UNREGUL 0xf3810002
+#define F0900_P2_DIL_READY 0xf3810001
+
+/*P2_TSSTATUS2*/
+#define R0900_P2_TSSTATUS2 0xf382
+#define F0900_P2_TSFIFO_DEMODSEL 0xf3820080
+#define F0900_P2_TSFIFOSPEED_STORE 0xf3820040
+#define F0900_P2_DILXX_RESET 0xf3820020
+#define F0900_P2_TSSERIAL_IMPOS 0xf3820010
+#define F0900_P2_TSFIFO_LINENOK 0xf3820008
+#define F0900_P2_BITSPEED_EVENT 0xf3820004
+#define F0900_P2_SCRAMBDETECT 0xf3820002
+#define F0900_P2_ULDTV67_FALSELOCK 0xf3820001
+
+/*P2_TSBITRATE1*/
+#define R0900_P2_TSBITRATE1 0xf383
+#define F0900_P2_TSFIFO_BITRATE1 0xf38300ff
+
+/*P2_TSBITRATE0*/
+#define R0900_P2_TSBITRATE0 0xf384
+#define F0900_P2_TSFIFO_BITRATE0 0xf38400ff
+
+/*P2_ERRCTRL1*/
+#define R0900_P2_ERRCTRL1 0xf398
+#define F0900_P2_ERR_SOURCE1 0xf39800f0
+#define F0900_P2_NUM_EVENT1 0xf3980007
+
+/*P2_ERRCNT12*/
+#define R0900_P2_ERRCNT12 0xf399
+#define F0900_P2_ERRCNT1_OLDVALUE 0xf3990080
+#define F0900_P2_ERR_CNT12 0xf399007f
+
+/*P2_ERRCNT11*/
+#define R0900_P2_ERRCNT11 0xf39a
+#define F0900_P2_ERR_CNT11 0xf39a00ff
+
+/*P2_ERRCNT10*/
+#define R0900_P2_ERRCNT10 0xf39b
+#define F0900_P2_ERR_CNT10 0xf39b00ff
+
+/*P2_ERRCTRL2*/
+#define R0900_P2_ERRCTRL2 0xf39c
+#define F0900_P2_ERR_SOURCE2 0xf39c00f0
+#define F0900_P2_NUM_EVENT2 0xf39c0007
+
+/*P2_ERRCNT22*/
+#define R0900_P2_ERRCNT22 0xf39d
+#define F0900_P2_ERRCNT2_OLDVALUE 0xf39d0080
+#define F0900_P2_ERR_CNT22 0xf39d007f
+
+/*P2_ERRCNT21*/
+#define R0900_P2_ERRCNT21 0xf39e
+#define F0900_P2_ERR_CNT21 0xf39e00ff
+
+/*P2_ERRCNT20*/
+#define R0900_P2_ERRCNT20 0xf39f
+#define F0900_P2_ERR_CNT20 0xf39f00ff
+
+/*P2_FECSPY*/
+#define R0900_P2_FECSPY 0xf3a0
+#define F0900_P2_SPY_ENABLE 0xf3a00080
+#define F0900_P2_NO_SYNCBYTE 0xf3a00040
+#define F0900_P2_SERIAL_MODE 0xf3a00020
+#define F0900_P2_UNUSUAL_PACKET 0xf3a00010
+#define F0900_P2_BER_PACKMODE 0xf3a00008
+#define F0900_P2_BERMETER_LMODE 0xf3a00002
+#define F0900_P2_BERMETER_RESET 0xf3a00001
+
+/*P2_FSPYCFG*/
+#define R0900_P2_FSPYCFG 0xf3a1
+#define F0900_P2_FECSPY_INPUT 0xf3a100c0
+#define F0900_P2_RST_ON_ERROR 0xf3a10020
+#define F0900_P2_ONE_SHOT 0xf3a10010
+#define F0900_P2_I2C_MODE 0xf3a1000c
+#define F0900_P2_SPY_HYSTERESIS 0xf3a10003
+
+/*P2_FSPYDATA*/
+#define R0900_P2_FSPYDATA 0xf3a2
+#define F0900_P2_SPY_STUFFING 0xf3a20080
+#define F0900_P2_NOERROR_PKTJITTER 0xf3a20040
+#define F0900_P2_SPY_CNULLPKT 0xf3a20020
+#define F0900_P2_SPY_OUTDATA_MODE 0xf3a2001f
+
+/*P2_FSPYOUT*/
+#define R0900_P2_FSPYOUT 0xf3a3
+#define F0900_P2_FSPY_DIRECT 0xf3a30080
+#define F0900_P2_SPY_OUTDATA_BUS 0xf3a30038
+#define F0900_P2_STUFF_MODE 0xf3a30007
+
+/*P2_FSTATUS*/
+#define R0900_P2_FSTATUS 0xf3a4
+#define F0900_P2_SPY_ENDSIM 0xf3a40080
+#define F0900_P2_VALID_SIM 0xf3a40040
+#define F0900_P2_FOUND_SIGNAL 0xf3a40020
+#define F0900_P2_DSS_SYNCBYTE 0xf3a40010
+#define F0900_P2_RESULT_STATE 0xf3a4000f
+
+/*P2_FBERCPT4*/
+#define R0900_P2_FBERCPT4 0xf3a8
+#define F0900_P2_FBERMETER_CPT4 0xf3a800ff
+
+/*P2_FBERCPT3*/
+#define R0900_P2_FBERCPT3 0xf3a9
+#define F0900_P2_FBERMETER_CPT3 0xf3a900ff
+
+/*P2_FBERCPT2*/
+#define R0900_P2_FBERCPT2 0xf3aa
+#define F0900_P2_FBERMETER_CPT2 0xf3aa00ff
+
+/*P2_FBERCPT1*/
+#define R0900_P2_FBERCPT1 0xf3ab
+#define F0900_P2_FBERMETER_CPT1 0xf3ab00ff
+
+/*P2_FBERCPT0*/
+#define R0900_P2_FBERCPT0 0xf3ac
+#define F0900_P2_FBERMETER_CPT0 0xf3ac00ff
+
+/*P2_FBERERR2*/
+#define R0900_P2_FBERERR2 0xf3ad
+#define F0900_P2_FBERMETER_ERR2 0xf3ad00ff
+
+/*P2_FBERERR1*/
+#define R0900_P2_FBERERR1 0xf3ae
+#define F0900_P2_FBERMETER_ERR1 0xf3ae00ff
+
+/*P2_FBERERR0*/
+#define R0900_P2_FBERERR0 0xf3af
+#define F0900_P2_FBERMETER_ERR0 0xf3af00ff
+
+/*P2_FSPYBER*/
+#define R0900_P2_FSPYBER 0xf3b2
+#define F0900_P2_FSPYOBS_XORREAD 0xf3b20040
+#define F0900_P2_FSPYBER_OBSMODE 0xf3b20020
+#define F0900_P2_FSPYBER_SYNCBYTE 0xf3b20010
+#define F0900_P2_FSPYBER_UNSYNC 0xf3b20008
+#define F0900_P2_FSPYBER_CTIME 0xf3b20007
+
+/*P1_IQCONST*/
+#define R0900_P1_IQCONST 0xf400
+#define F0900_P1_CONSTEL_SELECT 0xf4000060
+#define F0900_P1_IQSYMB_SEL 0xf400001f
+
+/*P1_NOSCFG*/
+#define R0900_P1_NOSCFG 0xf401
+#define F0900_P1_DUMMYPL_NOSDATA 0xf4010020
+#define F0900_P1_NOSPLH_BETA 0xf4010018
+#define F0900_P1_NOSDATA_BETA 0xf4010007
+
+/*P1_ISYMB*/
+#define R0900_P1_ISYMB 0xf402
+#define F0900_P1_I_SYMBOL 0xf40201ff
+
+/*P1_QSYMB*/
+#define R0900_P1_QSYMB 0xf403
+#define F0900_P1_Q_SYMBOL 0xf40301ff
+
+/*P1_AGC1CFG*/
+#define R0900_P1_AGC1CFG 0xf404
+#define F0900_P1_DC_FROZEN 0xf4040080
+#define F0900_P1_DC_CORRECT 0xf4040040
+#define F0900_P1_AMM_FROZEN 0xf4040020
+#define F0900_P1_AMM_CORRECT 0xf4040010
+#define F0900_P1_QUAD_FROZEN 0xf4040008
+#define F0900_P1_QUAD_CORRECT 0xf4040004
+#define F0900_P1_DCCOMP_SLOW 0xf4040002
+#define F0900_P1_IQMISM_SLOW 0xf4040001
+
+/*P1_AGC1CN*/
+#define R0900_P1_AGC1CN 0xf406
+#define F0900_P1_AGC1_LOCKED 0xf4060080
+#define F0900_P1_AGC1_OVERFLOW 0xf4060040
+#define F0900_P1_AGC1_NOSLOWLK 0xf4060020
+#define F0900_P1_AGC1_MINPOWER 0xf4060010
+#define F0900_P1_AGCOUT_FAST 0xf4060008
+#define F0900_P1_AGCIQ_BETA 0xf4060007
+
+/*P1_AGC1REF*/
+#define R0900_P1_AGC1REF 0xf407
+#define F0900_P1_AGCIQ_REF 0xf40700ff
+
+/*P1_IDCCOMP*/
+#define R0900_P1_IDCCOMP 0xf408
+#define F0900_P1_IAVERAGE_ADJ 0xf40801ff
+
+/*P1_QDCCOMP*/
+#define R0900_P1_QDCCOMP 0xf409
+#define F0900_P1_QAVERAGE_ADJ 0xf40901ff
+
+/*P1_POWERI*/
+#define R0900_P1_POWERI 0xf40a
+#define F0900_P1_POWER_I 0xf40a00ff
+
+/*P1_POWERQ*/
+#define R0900_P1_POWERQ 0xf40b
+#define F0900_P1_POWER_Q 0xf40b00ff
+
+/*P1_AGC1AMM*/
+#define R0900_P1_AGC1AMM 0xf40c
+#define F0900_P1_AMM_VALUE 0xf40c00ff
+
+/*P1_AGC1QUAD*/
+#define R0900_P1_AGC1QUAD 0xf40d
+#define F0900_P1_QUAD_VALUE 0xf40d01ff
+
+/*P1_AGCIQIN1*/
+#define R0900_P1_AGCIQIN1 0xf40e
+#define F0900_P1_AGCIQ_VALUE1 0xf40e00ff
+
+/*P1_AGCIQIN0*/
+#define R0900_P1_AGCIQIN0 0xf40f
+#define F0900_P1_AGCIQ_VALUE0 0xf40f00ff
+
+/*P1_DEMOD*/
+#define R0900_P1_DEMOD 0xf410
+#define F0900_P1_DEMOD_STOP 0xf4100040
+#define F0900_P1_SPECINV_CONTROL 0xf4100030
+#define F0900_P1_FORCE_ENASAMP 0xf4100008
+#define F0900_P1_MANUAL_ROLLOFF 0xf4100004
+#define F0900_P1_ROLLOFF_CONTROL 0xf4100003
+
+/*P1_DMDMODCOD*/
+#define R0900_P1_DMDMODCOD 0xf411
+#define F0900_P1_MANUAL_MODCOD 0xf4110080
+#define F0900_P1_DEMOD_MODCOD 0xf411007c
+#define F0900_P1_DEMOD_TYPE 0xf4110003
+
+/*P1_DSTATUS*/
+#define R0900_P1_DSTATUS 0xf412
+#define F0900_P1_CAR_LOCK 0xf4120080
+#define F0900_P1_TMGLOCK_QUALITY 0xf4120060
+#define F0900_P1_SDVBS1_ENABLE 0xf4120010
+#define F0900_P1_LOCK_DEFINITIF 0xf4120008
+#define F0900_P1_TIMING_IS_LOCKED 0xf4120004
+#define F0900_P1_COARSE_TMGLOCK 0xf4120002
+#define F0900_P1_COARSE_CARLOCK 0xf4120001
+
+/*P1_DSTATUS2*/
+#define R0900_P1_DSTATUS2 0xf413
+#define F0900_P1_DEMOD_DELOCK 0xf4130080
+#define F0900_P1_DEMOD_TIMEOUT 0xf4130040
+#define F0900_P1_MODCODRQ_SYNCTAG 0xf4130020
+#define F0900_P1_POLYPH_SATEVENT 0xf4130010
+#define F0900_P1_AGC1_NOSIGNALACK 0xf4130008
+#define F0900_P1_AGC2_OVERFLOW 0xf4130004
+#define F0900_P1_CFR_OVERFLOW 0xf4130002
+#define F0900_P1_GAMMA_OVERUNDER 0xf4130001
+
+/*P1_DMDCFGMD*/
+#define R0900_P1_DMDCFGMD 0xf414
+#define F0900_P1_DVBS2_ENABLE 0xf4140080
+#define F0900_P1_DVBS1_ENABLE 0xf4140040
+#define F0900_P1_CFR_AUTOSCAN 0xf4140020
+#define F0900_P1_SCAN_ENABLE 0xf4140010
+#define F0900_P1_TUN_AUTOSCAN 0xf4140008
+#define F0900_P1_NOFORCE_RELOCK 0xf4140004
+#define F0900_P1_TUN_RNG 0xf4140003
+
+/*P1_DMDCFG2*/
+#define R0900_P1_DMDCFG2 0xf415
+#define F0900_P1_AGC1_WAITLOCK 0xf4150080
+#define F0900_P1_S1S2_SEQUENTIAL 0xf4150040
+#define F0900_P1_OVERFLOW_TIMEOUT 0xf4150020
+#define F0900_P1_SCANFAIL_TIMEOUT 0xf4150010
+#define F0900_P1_DMDTOUT_BACK 0xf4150008
+#define F0900_P1_CARLOCK_S1ENABLE 0xf4150004
+#define F0900_P1_COARSE_LK3MODE 0xf4150002
+#define F0900_P1_COARSE_LK2MODE 0xf4150001
+
+/*P1_DMDISTATE*/
+#define R0900_P1_DMDISTATE 0xf416
+#define F0900_P1_I2C_NORESETDMODE 0xf4160080
+#define F0900_P1_FORCE_ETAPED 0xf4160040
+#define F0900_P1_SDMDRST_DIRCLK 0xf4160020
+#define F0900_P1_I2C_DEMOD_MODE 0xf416001f
+
+/*P1_DMDT0M*/
+#define R0900_P1_DMDT0M 0xf417
+#define F0900_P1_DMDT0_MIN 0xf41700ff
+
+/*P1_DMDSTATE*/
+#define R0900_P1_DMDSTATE 0xf41b
+#define F0900_P1_DEMOD_LOCKED 0xf41b0080
+#define F0900_P1_HEADER_MODE 0xf41b0060
+#define F0900_P1_DEMOD_MODE 0xf41b001f
+
+/*P1_DMDFLYW*/
+#define R0900_P1_DMDFLYW 0xf41c
+#define F0900_P1_I2C_IRQVAL 0xf41c00f0
+#define F0900_P1_FLYWHEEL_CPT 0xf41c000f
+
+/*P1_DSTATUS3*/
+#define R0900_P1_DSTATUS3 0xf41d
+#define F0900_P1_CFR_ZIGZAG 0xf41d0080
+#define F0900_P1_DEMOD_CFGMODE 0xf41d0060
+#define F0900_P1_GAMMA_LOWBAUDRATE 0xf41d0010
+#define F0900_P1_RELOCK_MODE 0xf41d0008
+#define F0900_P1_DEMOD_FAIL 0xf41d0004
+#define F0900_P1_ETAPE1A_DVBXMEM 0xf41d0003
+
+/*P1_DMDCFG3*/
+#define R0900_P1_DMDCFG3 0xf41e
+#define F0900_P1_DVBS1_TMGWAIT 0xf41e0080
+#define F0900_P1_NO_BWCENTERING 0xf41e0040
+#define F0900_P1_INV_SEQSRCH 0xf41e0020
+#define F0900_P1_DIS_SFRUPLOW_TRK 0xf41e0010
+#define F0900_P1_NOSTOP_FIFOFULL 0xf41e0008
+#define F0900_P1_LOCKTIME_MODE 0xf41e0007
+
+/*P1_DMDCFG4*/
+#define R0900_P1_DMDCFG4 0xf41f
+#define F0900_P1_TUNER_NRELAUNCH 0xf41f0008
+#define F0900_P1_DIS_CLKENABLE 0xf41f0004
+#define F0900_P1_DIS_HDRDIVLOCK 0xf41f0002
+#define F0900_P1_NO_TNRWBINIT 0xf41f0001
+
+/*P1_CORRELMANT*/
+#define R0900_P1_CORRELMANT 0xf420
+#define F0900_P1_CORREL_MANT 0xf42000ff
+
+/*P1_CORRELABS*/
+#define R0900_P1_CORRELABS 0xf421
+#define F0900_P1_CORREL_ABS 0xf42100ff
+
+/*P1_CORRELEXP*/
+#define R0900_P1_CORRELEXP 0xf422
+#define F0900_P1_CORREL_ABSEXP 0xf42200f0
+#define F0900_P1_CORREL_EXP 0xf422000f
+
+/*P1_PLHMODCOD*/
+#define R0900_P1_PLHMODCOD 0xf424
+#define F0900_P1_SPECINV_DEMOD 0xf4240080
+#define F0900_P1_PLH_MODCOD 0xf424007c
+#define F0900_P1_PLH_TYPE 0xf4240003
+
+/*P1_AGCK32*/
+#define R0900_P1_AGCK32 0xf42b
+#define F0900_P1_R3ADJOFF_32APSK 0xf42b0080
+#define F0900_P1_R2ADJOFF_32APSK 0xf42b0040
+#define F0900_P1_R1ADJOFF_32APSK 0xf42b0020
+#define F0900_P1_RADJ_32APSK 0xf42b001f
+
+/*P1_AGC2O*/
+#define R0900_P1_AGC2O 0xf42c
+#define F0900_P1_AGC2REF_ADJUSTING 0xf42c0080
+#define F0900_P1_AGC2_COARSEFAST 0xf42c0040
+#define F0900_P1_AGC2_LKSQRT 0xf42c0020
+#define F0900_P1_AGC2_LKMODE 0xf42c0010
+#define F0900_P1_AGC2_LKEQUA 0xf42c0008
+#define F0900_P1_AGC2_COEF 0xf42c0007
+
+/*P1_AGC2REF*/
+#define R0900_P1_AGC2REF 0xf42d
+#define F0900_P1_AGC2_REF 0xf42d00ff
+
+/*P1_AGC1ADJ*/
+#define R0900_P1_AGC1ADJ 0xf42e
+#define F0900_P1_AGC1ADJ_MANUAL 0xf42e0080
+#define F0900_P1_AGC1_ADJUSTED 0xf42e017f
+
+/*P1_AGC2I1*/
+#define R0900_P1_AGC2I1 0xf436
+#define F0900_P1_AGC2_INTEGRATOR1 0xf43600ff
+
+/*P1_AGC2I0*/
+#define R0900_P1_AGC2I0 0xf437
+#define F0900_P1_AGC2_INTEGRATOR0 0xf43700ff
+
+/*P1_CARCFG*/
+#define R0900_P1_CARCFG 0xf438
+#define F0900_P1_CFRUPLOW_AUTO 0xf4380080
+#define F0900_P1_CFRUPLOW_TEST 0xf4380040
+#define F0900_P1_EN_CAR2CENTER 0xf4380020
+#define F0900_P1_CARHDR_NODIV8 0xf4380010
+#define F0900_P1_I2C_ROTA 0xf4380008
+#define F0900_P1_ROTAON 0xf4380004
+#define F0900_P1_PH_DET_ALGO 0xf4380003
+
+/*P1_ACLC*/
+#define R0900_P1_ACLC 0xf439
+#define F0900_P1_STOP_S2ALPHA 0xf43900c0
+#define F0900_P1_CAR_ALPHA_MANT 0xf4390030
+#define F0900_P1_CAR_ALPHA_EXP 0xf439000f
+
+/*P1_BCLC*/
+#define R0900_P1_BCLC 0xf43a
+#define F0900_P1_STOP_S2BETA 0xf43a00c0
+#define F0900_P1_CAR_BETA_MANT 0xf43a0030
+#define F0900_P1_CAR_BETA_EXP 0xf43a000f
+
+/*P1_CARFREQ*/
+#define R0900_P1_CARFREQ 0xf43d
+#define F0900_P1_KC_COARSE_EXP 0xf43d00f0
+#define F0900_P1_BETA_FREQ 0xf43d000f
+
+/*P1_CARHDR*/
+#define R0900_P1_CARHDR 0xf43e
+#define F0900_P1_K_FREQ_HDR 0xf43e00ff
+
+/*P1_LDT*/
+#define R0900_P1_LDT 0xf43f
+#define F0900_P1_CARLOCK_THRES 0xf43f01ff
+
+/*P1_LDT2*/
+#define R0900_P1_LDT2 0xf440
+#define F0900_P1_CARLOCK_THRES2 0xf44001ff
+
+/*P1_CFRICFG*/
+#define R0900_P1_CFRICFG 0xf441
+#define F0900_P1_CFRINIT_UNVALRNG 0xf4410080
+#define F0900_P1_CFRINIT_LUNVALCPT 0xf4410040
+#define F0900_P1_CFRINIT_ABORTDBL 0xf4410020
+#define F0900_P1_CFRINIT_ABORTPRED 0xf4410010
+#define F0900_P1_CFRINIT_UNVALSKIP 0xf4410008
+#define F0900_P1_CFRINIT_CSTINC 0xf4410004
+#define F0900_P1_NEG_CFRSTEP 0xf4410001
+
+/*P1_CFRUP1*/
+#define R0900_P1_CFRUP1 0xf442
+#define F0900_P1_CFR_UP1 0xf44201ff
+
+/*P1_CFRUP0*/
+#define R0900_P1_CFRUP0 0xf443
+#define F0900_P1_CFR_UP0 0xf44300ff
+
+/*P1_CFRLOW1*/
+#define R0900_P1_CFRLOW1 0xf446
+#define F0900_P1_CFR_LOW1 0xf44601ff
+
+/*P1_CFRLOW0*/
+#define R0900_P1_CFRLOW0 0xf447
+#define F0900_P1_CFR_LOW0 0xf44700ff
+
+/*P1_CFRINIT1*/
+#define R0900_P1_CFRINIT1 0xf448
+#define F0900_P1_CFR_INIT1 0xf44801ff
+
+/*P1_CFRINIT0*/
+#define R0900_P1_CFRINIT0 0xf449
+#define F0900_P1_CFR_INIT0 0xf44900ff
+
+/*P1_CFRINC1*/
+#define R0900_P1_CFRINC1 0xf44a
+#define F0900_P1_MANUAL_CFRINC 0xf44a0080
+#define F0900_P1_CFR_INC1 0xf44a017f
+
+/*P1_CFRINC0*/
+#define R0900_P1_CFRINC0 0xf44b
+#define F0900_P1_CFR_INC0 0xf44b00f0
+
+/*P1_CFR2*/
+#define R0900_P1_CFR2 0xf44c
+#define F0900_P1_CAR_FREQ2 0xf44c01ff
+
+/*P1_CFR1*/
+#define R0900_P1_CFR1 0xf44d
+#define F0900_P1_CAR_FREQ1 0xf44d00ff
+
+/*P1_CFR0*/
+#define R0900_P1_CFR0 0xf44e
+#define F0900_P1_CAR_FREQ0 0xf44e00ff
+
+/*P1_LDI*/
+#define R0900_P1_LDI 0xf44f
+#define F0900_P1_LOCK_DET_INTEGR 0xf44f01ff
+
+/*P1_TMGCFG*/
+#define R0900_P1_TMGCFG 0xf450
+#define F0900_P1_TMGLOCK_BETA 0xf45000c0
+#define F0900_P1_NOTMG_GROUPDELAY 0xf4500020
+#define F0900_P1_DO_TIMING_CORR 0xf4500010
+#define F0900_P1_MANUAL_SCAN 0xf450000c
+#define F0900_P1_TMG_MINFREQ 0xf4500003
+
+/*P1_RTC*/
+#define R0900_P1_RTC 0xf451
+#define F0900_P1_TMGALPHA_EXP 0xf45100f0
+#define F0900_P1_TMGBETA_EXP 0xf451000f
+
+/*P1_RTCS2*/
+#define R0900_P1_RTCS2 0xf452
+#define F0900_P1_TMGALPHAS2_EXP 0xf45200f0
+#define F0900_P1_TMGBETAS2_EXP 0xf452000f
+
+/*P1_TMGTHRISE*/
+#define R0900_P1_TMGTHRISE 0xf453
+#define F0900_P1_TMGLOCK_THRISE 0xf45300ff
+
+/*P1_TMGTHFALL*/
+#define R0900_P1_TMGTHFALL 0xf454
+#define F0900_P1_TMGLOCK_THFALL 0xf45400ff
+
+/*P1_SFRUPRATIO*/
+#define R0900_P1_SFRUPRATIO 0xf455
+#define F0900_P1_SFR_UPRATIO 0xf45500ff
+
+/*P1_SFRLOWRATIO*/
+#define R0900_P1_SFRLOWRATIO 0xf456
+#define F0900_P1_SFR_LOWRATIO 0xf45600ff
+
+/*P1_KREFTMG*/
+#define R0900_P1_KREFTMG 0xf458
+#define F0900_P1_KREF_TMG 0xf45800ff
+
+/*P1_SFRSTEP*/
+#define R0900_P1_SFRSTEP 0xf459
+#define F0900_P1_SFR_SCANSTEP 0xf45900f0
+#define F0900_P1_SFR_CENTERSTEP 0xf459000f
+
+/*P1_TMGCFG2*/
+#define R0900_P1_TMGCFG2 0xf45a
+#define F0900_P1_DIS_AUTOSAMP 0xf45a0008
+#define F0900_P1_SCANINIT_QUART 0xf45a0004
+#define F0900_P1_NOTMG_DVBS1DERAT 0xf45a0002
+#define F0900_P1_SFRRATIO_FINE 0xf45a0001
+
+/*P1_SFRINIT1*/
+#define R0900_P1_SFRINIT1 0xf45e
+#define F0900_P1_SFR_INIT1 0xf45e00ff
+
+/*P1_SFRINIT0*/
+#define R0900_P1_SFRINIT0 0xf45f
+#define F0900_P1_SFR_INIT0 0xf45f00ff
+
+/*P1_SFRUP1*/
+#define R0900_P1_SFRUP1 0xf460
+#define F0900_P1_AUTO_GUP 0xf4600080
+#define F0900_P1_SYMB_FREQ_UP1 0xf460007f
+
+/*P1_SFRUP0*/
+#define R0900_P1_SFRUP0 0xf461
+#define F0900_P1_SYMB_FREQ_UP0 0xf46100ff
+
+/*P1_SFRLOW1*/
+#define R0900_P1_SFRLOW1 0xf462
+#define F0900_P1_AUTO_GLOW 0xf4620080
+#define F0900_P1_SYMB_FREQ_LOW1 0xf462007f
+
+/*P1_SFRLOW0*/
+#define R0900_P1_SFRLOW0 0xf463
+#define F0900_P1_SYMB_FREQ_LOW0 0xf46300ff
+
+/*P1_SFR3*/
+#define R0900_P1_SFR3 0xf464
+#define F0900_P1_SYMB_FREQ3 0xf46400ff
+
+/*P1_SFR2*/
+#define R0900_P1_SFR2 0xf465
+#define F0900_P1_SYMB_FREQ2 0xf46500ff
+
+/*P1_SFR1*/
+#define R0900_P1_SFR1 0xf466
+#define F0900_P1_SYMB_FREQ1 0xf46600ff
+
+/*P1_SFR0*/
+#define R0900_P1_SFR0 0xf467
+#define F0900_P1_SYMB_FREQ0 0xf46700ff
+
+/*P1_TMGREG2*/
+#define R0900_P1_TMGREG2 0xf468
+#define F0900_P1_TMGREG2 0xf46800ff
+
+/*P1_TMGREG1*/
+#define R0900_P1_TMGREG1 0xf469
+#define F0900_P1_TMGREG1 0xf46900ff
+
+/*P1_TMGREG0*/
+#define R0900_P1_TMGREG0 0xf46a
+#define F0900_P1_TMGREG0 0xf46a00ff
+
+/*P1_TMGLOCK1*/
+#define R0900_P1_TMGLOCK1 0xf46b
+#define F0900_P1_TMGLOCK_LEVEL1 0xf46b01ff
+
+/*P1_TMGLOCK0*/
+#define R0900_P1_TMGLOCK0 0xf46c
+#define F0900_P1_TMGLOCK_LEVEL0 0xf46c00ff
+
+/*P1_TMGOBS*/
+#define R0900_P1_TMGOBS 0xf46d
+#define F0900_P1_ROLLOFF_STATUS 0xf46d00c0
+#define F0900_P1_SCAN_SIGN 0xf46d0030
+#define F0900_P1_TMG_SCANNING 0xf46d0008
+#define F0900_P1_CHCENTERING_MODE 0xf46d0004
+#define F0900_P1_TMG_SCANFAIL 0xf46d0002
+
+/*P1_EQUALCFG*/
+#define R0900_P1_EQUALCFG 0xf46f
+#define F0900_P1_NOTMG_NEGALWAIT 0xf46f0080
+#define F0900_P1_EQUAL_ON 0xf46f0040
+#define F0900_P1_SEL_EQUALCOR 0xf46f0038
+#define F0900_P1_MU_EQUALDFE 0xf46f0007
+
+/*P1_EQUAI1*/
+#define R0900_P1_EQUAI1 0xf470
+#define F0900_P1_EQUA_ACCI1 0xf47001ff
+
+/*P1_EQUAQ1*/
+#define R0900_P1_EQUAQ1 0xf471
+#define F0900_P1_EQUA_ACCQ1 0xf47101ff
+
+/*P1_EQUAI2*/
+#define R0900_P1_EQUAI2 0xf472
+#define F0900_P1_EQUA_ACCI2 0xf47201ff
+
+/*P1_EQUAQ2*/
+#define R0900_P1_EQUAQ2 0xf473
+#define F0900_P1_EQUA_ACCQ2 0xf47301ff
+
+/*P1_EQUAI3*/
+#define R0900_P1_EQUAI3 0xf474
+#define F0900_P1_EQUA_ACCI3 0xf47401ff
+
+/*P1_EQUAQ3*/
+#define R0900_P1_EQUAQ3 0xf475
+#define F0900_P1_EQUA_ACCQ3 0xf47501ff
+
+/*P1_EQUAI4*/
+#define R0900_P1_EQUAI4 0xf476
+#define F0900_P1_EQUA_ACCI4 0xf47601ff
+
+/*P1_EQUAQ4*/
+#define R0900_P1_EQUAQ4 0xf477
+#define F0900_P1_EQUA_ACCQ4 0xf47701ff
+
+/*P1_EQUAI5*/
+#define R0900_P1_EQUAI5 0xf478
+#define F0900_P1_EQUA_ACCI5 0xf47801ff
+
+/*P1_EQUAQ5*/
+#define R0900_P1_EQUAQ5 0xf479
+#define F0900_P1_EQUA_ACCQ5 0xf47901ff
+
+/*P1_EQUAI6*/
+#define R0900_P1_EQUAI6 0xf47a
+#define F0900_P1_EQUA_ACCI6 0xf47a01ff
+
+/*P1_EQUAQ6*/
+#define R0900_P1_EQUAQ6 0xf47b
+#define F0900_P1_EQUA_ACCQ6 0xf47b01ff
+
+/*P1_EQUAI7*/
+#define R0900_P1_EQUAI7 0xf47c
+#define F0900_P1_EQUA_ACCI7 0xf47c01ff
+
+/*P1_EQUAQ7*/
+#define R0900_P1_EQUAQ7 0xf47d
+#define F0900_P1_EQUA_ACCQ7 0xf47d01ff
+
+/*P1_EQUAI8*/
+#define R0900_P1_EQUAI8 0xf47e
+#define F0900_P1_EQUA_ACCI8 0xf47e01ff
+
+/*P1_EQUAQ8*/
+#define R0900_P1_EQUAQ8 0xf47f
+#define F0900_P1_EQUA_ACCQ8 0xf47f01ff
+
+/*P1_NNOSDATAT1*/
+#define R0900_P1_NNOSDATAT1 0xf480
+#define F0900_P1_NOSDATAT_NORMED1 0xf48000ff
+
+/*P1_NNOSDATAT0*/
+#define R0900_P1_NNOSDATAT0 0xf481
+#define F0900_P1_NOSDATAT_NORMED0 0xf48100ff
+
+/*P1_NNOSDATA1*/
+#define R0900_P1_NNOSDATA1 0xf482
+#define F0900_P1_NOSDATA_NORMED1 0xf48200ff
+
+/*P1_NNOSDATA0*/
+#define R0900_P1_NNOSDATA0 0xf483
+#define F0900_P1_NOSDATA_NORMED0 0xf48300ff
+
+/*P1_NNOSPLHT1*/
+#define R0900_P1_NNOSPLHT1 0xf484
+#define F0900_P1_NOSPLHT_NORMED1 0xf48400ff
+
+/*P1_NNOSPLHT0*/
+#define R0900_P1_NNOSPLHT0 0xf485
+#define F0900_P1_NOSPLHT_NORMED0 0xf48500ff
+
+/*P1_NNOSPLH1*/
+#define R0900_P1_NNOSPLH1 0xf486
+#define F0900_P1_NOSPLH_NORMED1 0xf48600ff
+
+/*P1_NNOSPLH0*/
+#define R0900_P1_NNOSPLH0 0xf487
+#define F0900_P1_NOSPLH_NORMED0 0xf48700ff
+
+/*P1_NOSDATAT1*/
+#define R0900_P1_NOSDATAT1 0xf488
+#define F0900_P1_NOSDATAT_UNNORMED1 0xf48800ff
+
+/*P1_NOSDATAT0*/
+#define R0900_P1_NOSDATAT0 0xf489
+#define F0900_P1_NOSDATAT_UNNORMED0 0xf48900ff
+
+/*P1_NOSDATA1*/
+#define R0900_P1_NOSDATA1 0xf48a
+#define F0900_P1_NOSDATA_UNNORMED1 0xf48a00ff
+
+/*P1_NOSDATA0*/
+#define R0900_P1_NOSDATA0 0xf48b
+#define F0900_P1_NOSDATA_UNNORMED0 0xf48b00ff
+
+/*P1_NOSPLHT1*/
+#define R0900_P1_NOSPLHT1 0xf48c
+#define F0900_P1_NOSPLHT_UNNORMED1 0xf48c00ff
+
+/*P1_NOSPLHT0*/
+#define R0900_P1_NOSPLHT0 0xf48d
+#define F0900_P1_NOSPLHT_UNNORMED0 0xf48d00ff
+
+/*P1_NOSPLH1*/
+#define R0900_P1_NOSPLH1 0xf48e
+#define F0900_P1_NOSPLH_UNNORMED1 0xf48e00ff
+
+/*P1_NOSPLH0*/
+#define R0900_P1_NOSPLH0 0xf48f
+#define F0900_P1_NOSPLH_UNNORMED0 0xf48f00ff
+
+/*P1_CAR2CFG*/
+#define R0900_P1_CAR2CFG 0xf490
+#define F0900_P1_DESCRAMB_OFF 0xf4900080
+#define F0900_P1_PN4_SELECT 0xf4900040
+#define F0900_P1_CFR2_STOPDVBS1 0xf4900020
+#define F0900_P1_STOP_CFR2UPDATE 0xf4900010
+#define F0900_P1_STOP_NCO2UPDATE 0xf4900008
+#define F0900_P1_ROTA2ON 0xf4900004
+#define F0900_P1_PH_DET_ALGO2 0xf4900003
+
+/*P1_ACLC2*/
+#define R0900_P1_ACLC2 0xf491
+#define F0900_P1_CAR2_PUNCT_ADERAT 0xf4910040
+#define F0900_P1_CAR2_ALPHA_MANT 0xf4910030
+#define F0900_P1_CAR2_ALPHA_EXP 0xf491000f
+
+/*P1_BCLC2*/
+#define R0900_P1_BCLC2 0xf492
+#define F0900_P1_DVBS2_NIP 0xf4920080
+#define F0900_P1_CAR2_PUNCT_BDERAT 0xf4920040
+#define F0900_P1_CAR2_BETA_MANT 0xf4920030
+#define F0900_P1_CAR2_BETA_EXP 0xf492000f
+
+/*P1_CFR22*/
+#define R0900_P1_CFR22 0xf493
+#define F0900_P1_CAR2_FREQ2 0xf49301ff
+
+/*P1_CFR21*/
+#define R0900_P1_CFR21 0xf494
+#define F0900_P1_CAR2_FREQ1 0xf49400ff
+
+/*P1_CFR20*/
+#define R0900_P1_CFR20 0xf495
+#define F0900_P1_CAR2_FREQ0 0xf49500ff
+
+/*P1_ACLC2S2Q*/
+#define R0900_P1_ACLC2S2Q 0xf497
+#define F0900_P1_ENAB_SPSKSYMB 0xf4970080
+#define F0900_P1_CAR2S2_QADERAT 0xf4970040
+#define F0900_P1_CAR2S2_Q_ALPH_M 0xf4970030
+#define F0900_P1_CAR2S2_Q_ALPH_E 0xf497000f
+
+/*P1_ACLC2S28*/
+#define R0900_P1_ACLC2S28 0xf498
+#define F0900_P1_OLDI3Q_MODE 0xf4980080
+#define F0900_P1_CAR2S2_8ADERAT 0xf4980040
+#define F0900_P1_CAR2S2_8_ALPH_M 0xf4980030
+#define F0900_P1_CAR2S2_8_ALPH_E 0xf498000f
+
+/*P1_ACLC2S216A*/
+#define R0900_P1_ACLC2S216A 0xf499
+#define F0900_P1_CAR2S2_16ADERAT 0xf4990040
+#define F0900_P1_CAR2S2_16A_ALPH_M 0xf4990030
+#define F0900_P1_CAR2S2_16A_ALPH_E 0xf499000f
+
+/*P1_ACLC2S232A*/
+#define R0900_P1_ACLC2S232A 0xf49a
+#define F0900_P1_CAR2S2_32ADERAT 0xf49a0040
+#define F0900_P1_CAR2S2_32A_ALPH_M 0xf49a0030
+#define F0900_P1_CAR2S2_32A_ALPH_E 0xf49a000f
+
+/*P1_BCLC2S2Q*/
+#define R0900_P1_BCLC2S2Q 0xf49c
+#define F0900_P1_DVBS2S2Q_NIP 0xf49c0080
+#define F0900_P1_CAR2S2_QBDERAT 0xf49c0040
+#define F0900_P1_CAR2S2_Q_BETA_M 0xf49c0030
+#define F0900_P1_CAR2S2_Q_BETA_E 0xf49c000f
+
+/*P1_BCLC2S28*/
+#define R0900_P1_BCLC2S28 0xf49d
+#define F0900_P1_DVBS2S28_NIP 0xf49d0080
+#define F0900_P1_CAR2S2_8BDERAT 0xf49d0040
+#define F0900_P1_CAR2S2_8_BETA_M 0xf49d0030
+#define F0900_P1_CAR2S2_8_BETA_E 0xf49d000f
+
+/*P1_BCLC2S216A*/
+#define R0900_P1_BCLC2S216A 0xf49e
+#define F0900_P1_DVBS2S216A_NIP 0xf49e0080
+#define F0900_P1_CAR2S2_16BDERAT 0xf49e0040
+#define F0900_P1_CAR2S2_16A_BETA_M 0xf49e0030
+#define F0900_P1_CAR2S2_16A_BETA_E 0xf49e000f
+
+/*P1_BCLC2S232A*/
+#define R0900_P1_BCLC2S232A 0xf49f
+#define F0900_P1_DVBS2S232A_NIP 0xf49f0080
+#define F0900_P1_CAR2S2_32BDERAT 0xf49f0040
+#define F0900_P1_CAR2S2_32A_BETA_M 0xf49f0030
+#define F0900_P1_CAR2S2_32A_BETA_E 0xf49f000f
+
+/*P1_PLROOT2*/
+#define R0900_P1_PLROOT2 0xf4ac
+#define F0900_P1_SHORTFR_DISABLE 0xf4ac0080
+#define F0900_P1_LONGFR_DISABLE 0xf4ac0040
+#define F0900_P1_DUMMYPL_DISABLE 0xf4ac0020
+#define F0900_P1_SHORTFR_AVOID 0xf4ac0010
+#define F0900_P1_PLSCRAMB_MODE 0xf4ac000c
+#define F0900_P1_PLSCRAMB_ROOT2 0xf4ac0003
+
+/*P1_PLROOT1*/
+#define R0900_P1_PLROOT1 0xf4ad
+#define F0900_P1_PLSCRAMB_ROOT1 0xf4ad00ff
+
+/*P1_PLROOT0*/
+#define R0900_P1_PLROOT0 0xf4ae
+#define F0900_P1_PLSCRAMB_ROOT0 0xf4ae00ff
+
+/*P1_MODCODLST0*/
+#define R0900_P1_MODCODLST0 0xf4b0
+#define F0900_P1_EN_TOKEN31 0xf4b00080
+#define F0900_P1_SYNCTAG_SELECT 0xf4b00040
+#define F0900_P1_MODCODRQ_MODE 0xf4b00030
+
+/*P1_MODCODLST1*/
+#define R0900_P1_MODCODLST1 0xf4b1
+#define F0900_P1_DIS_MODCOD29 0xf4b100f0
+#define F0900_P1_DIS_32PSK_9_10 0xf4b1000f
+
+/*P1_MODCODLST2*/
+#define R0900_P1_MODCODLST2 0xf4b2
+#define F0900_P1_DIS_32PSK_8_9 0xf4b200f0
+#define F0900_P1_DIS_32PSK_5_6 0xf4b2000f
+
+/*P1_MODCODLST3*/
+#define R0900_P1_MODCODLST3 0xf4b3
+#define F0900_P1_DIS_32PSK_4_5 0xf4b300f0
+#define F0900_P1_DIS_32PSK_3_4 0xf4b3000f
+
+/*P1_MODCODLST4*/
+#define R0900_P1_MODCODLST4 0xf4b4
+#define F0900_P1_DIS_16PSK_9_10 0xf4b400f0
+#define F0900_P1_DIS_16PSK_8_9 0xf4b4000f
+
+/*P1_MODCODLST5*/
+#define R0900_P1_MODCODLST5 0xf4b5
+#define F0900_P1_DIS_16PSK_5_6 0xf4b500f0
+#define F0900_P1_DIS_16PSK_4_5 0xf4b5000f
+
+/*P1_MODCODLST6*/
+#define R0900_P1_MODCODLST6 0xf4b6
+#define F0900_P1_DIS_16PSK_3_4 0xf4b600f0
+#define F0900_P1_DIS_16PSK_2_3 0xf4b6000f
+
+/*P1_MODCODLST7*/
+#define R0900_P1_MODCODLST7 0xf4b7
+#define F0900_P1_DIS_8P_9_10 0xf4b700f0
+#define F0900_P1_DIS_8P_8_9 0xf4b7000f
+
+/*P1_MODCODLST8*/
+#define R0900_P1_MODCODLST8 0xf4b8
+#define F0900_P1_DIS_8P_5_6 0xf4b800f0
+#define F0900_P1_DIS_8P_3_4 0xf4b8000f
+
+/*P1_MODCODLST9*/
+#define R0900_P1_MODCODLST9 0xf4b9
+#define F0900_P1_DIS_8P_2_3 0xf4b900f0
+#define F0900_P1_DIS_8P_3_5 0xf4b9000f
+
+/*P1_MODCODLSTA*/
+#define R0900_P1_MODCODLSTA 0xf4ba
+#define F0900_P1_DIS_QP_9_10 0xf4ba00f0
+#define F0900_P1_DIS_QP_8_9 0xf4ba000f
+
+/*P1_MODCODLSTB*/
+#define R0900_P1_MODCODLSTB 0xf4bb
+#define F0900_P1_DIS_QP_5_6 0xf4bb00f0
+#define F0900_P1_DIS_QP_4_5 0xf4bb000f
+
+/*P1_MODCODLSTC*/
+#define R0900_P1_MODCODLSTC 0xf4bc
+#define F0900_P1_DIS_QP_3_4 0xf4bc00f0
+#define F0900_P1_DIS_QP_2_3 0xf4bc000f
+
+/*P1_MODCODLSTD*/
+#define R0900_P1_MODCODLSTD 0xf4bd
+#define F0900_P1_DIS_QP_3_5 0xf4bd00f0
+#define F0900_P1_DIS_QP_1_2 0xf4bd000f
+
+/*P1_MODCODLSTE*/
+#define R0900_P1_MODCODLSTE 0xf4be
+#define F0900_P1_DIS_QP_2_5 0xf4be00f0
+#define F0900_P1_DIS_QP_1_3 0xf4be000f
+
+/*P1_MODCODLSTF*/
+#define R0900_P1_MODCODLSTF 0xf4bf
+#define F0900_P1_DIS_QP_1_4 0xf4bf00f0
+#define F0900_P1_DDEMOD_SET 0xf4bf0002
+#define F0900_P1_DDEMOD_MASK 0xf4bf0001
+
+/*P1_DMDRESCFG*/
+#define R0900_P1_DMDRESCFG 0xf4c6
+#define F0900_P1_DMDRES_RESET 0xf4c60080
+#define F0900_P1_DMDRES_NOISESQR 0xf4c60010
+#define F0900_P1_DMDRES_STRALL 0xf4c60008
+#define F0900_P1_DMDRES_NEWONLY 0xf4c60004
+#define F0900_P1_DMDRES_NOSTORE 0xf4c60002
+#define F0900_P1_DMDRES_AGC2MEM 0xf4c60001
+
+/*P1_DMDRESADR*/
+#define R0900_P1_DMDRESADR 0xf4c7
+#define F0900_P1_SUSP_PREDCANAL 0xf4c70080
+#define F0900_P1_DMDRES_VALIDCFR 0xf4c70040
+#define F0900_P1_DMDRES_MEMFULL 0xf4c70030
+#define F0900_P1_DMDRES_RESNBR 0xf4c7000f
+
+/*P1_DMDRESDATA7*/
+#define R0900_P1_DMDRESDATA7 0xf4c8
+#define F0900_P1_DMDRES_DATA7 0xf4c800ff
+
+/*P1_DMDRESDATA6*/
+#define R0900_P1_DMDRESDATA6 0xf4c9
+#define F0900_P1_DMDRES_DATA6 0xf4c900ff
+
+/*P1_DMDRESDATA5*/
+#define R0900_P1_DMDRESDATA5 0xf4ca
+#define F0900_P1_DMDRES_DATA5 0xf4ca00ff
+
+/*P1_DMDRESDATA4*/
+#define R0900_P1_DMDRESDATA4 0xf4cb
+#define F0900_P1_DMDRES_DATA4 0xf4cb00ff
+
+/*P1_DMDRESDATA3*/
+#define R0900_P1_DMDRESDATA3 0xf4cc
+#define F0900_P1_DMDRES_DATA3 0xf4cc00ff
+
+/*P1_DMDRESDATA2*/
+#define R0900_P1_DMDRESDATA2 0xf4cd
+#define F0900_P1_DMDRES_DATA2 0xf4cd00ff
+
+/*P1_DMDRESDATA1*/
+#define R0900_P1_DMDRESDATA1 0xf4ce
+#define F0900_P1_DMDRES_DATA1 0xf4ce00ff
+
+/*P1_DMDRESDATA0*/
+#define R0900_P1_DMDRESDATA0 0xf4cf
+#define F0900_P1_DMDRES_DATA0 0xf4cf00ff
+
+/*P1_FFEI1*/
+#define R0900_P1_FFEI1 0xf4d0
+#define F0900_P1_FFE_ACCI1 0xf4d001ff
+
+/*P1_FFEQ1*/
+#define R0900_P1_FFEQ1 0xf4d1
+#define F0900_P1_FFE_ACCQ1 0xf4d101ff
+
+/*P1_FFEI2*/
+#define R0900_P1_FFEI2 0xf4d2
+#define F0900_P1_FFE_ACCI2 0xf4d201ff
+
+/*P1_FFEQ2*/
+#define R0900_P1_FFEQ2 0xf4d3
+#define F0900_P1_FFE_ACCQ2 0xf4d301ff
+
+/*P1_FFEI3*/
+#define R0900_P1_FFEI3 0xf4d4
+#define F0900_P1_FFE_ACCI3 0xf4d401ff
+
+/*P1_FFEQ3*/
+#define R0900_P1_FFEQ3 0xf4d5
+#define F0900_P1_FFE_ACCQ3 0xf4d501ff
+
+/*P1_FFEI4*/
+#define R0900_P1_FFEI4 0xf4d6
+#define F0900_P1_FFE_ACCI4 0xf4d601ff
+
+/*P1_FFEQ4*/
+#define R0900_P1_FFEQ4 0xf4d7
+#define F0900_P1_FFE_ACCQ4 0xf4d701ff
+
+/*P1_FFECFG*/
+#define R0900_P1_FFECFG 0xf4d8
+#define F0900_P1_EQUALFFE_ON 0xf4d80040
+#define F0900_P1_EQUAL_USEDSYMB 0xf4d80030
+#define F0900_P1_MU_EQUALFFE 0xf4d80007
+
+/*P1_TNRCFG*/
+#define R0900_P1_TNRCFG 0xf4e0
+#define F0900_P1_TUN_ACKFAIL 0xf4e00080
+#define F0900_P1_TUN_TYPE 0xf4e00070
+#define F0900_P1_TUN_SECSTOP 0xf4e00008
+#define F0900_P1_TUN_VCOSRCH 0xf4e00004
+#define F0900_P1_TUN_MADDRESS 0xf4e00003
+
+/*P1_TNRCFG2*/
+#define R0900_P1_TNRCFG2 0xf4e1
+#define F0900_P1_TUN_IQSWAP 0xf4e10080
+#define F0900_P1_STB6110_STEP2MHZ 0xf4e10040
+#define F0900_P1_STB6120_DBLI2C 0xf4e10020
+#define F0900_P1_DIS_FCCK 0xf4e10010
+#define F0900_P1_DIS_LPEN 0xf4e10008
+#define F0900_P1_DIS_BWCALC 0xf4e10004
+#define F0900_P1_SHORT_WAITSTATES 0xf4e10002
+#define F0900_P1_DIS_2BWAGC1 0xf4e10001
+
+/*P1_TNRXTAL*/
+#define R0900_P1_TNRXTAL 0xf4e4
+#define F0900_P1_TUN_MCLKDECIMAL 0xf4e400e0
+#define F0900_P1_TUN_XTALFREQ 0xf4e4001f
+
+/*P1_TNRSTEPS*/
+#define R0900_P1_TNRSTEPS 0xf4e7
+#define F0900_P1_TUNER_BW1P6 0xf4e70080
+#define F0900_P1_BWINC_OFFSET 0xf4e70070
+#define F0900_P1_SOFTSTEP_RNG 0xf4e70008
+#define F0900_P1_TUN_BWOFFSET 0xf4e70107
+
+/*P1_TNRGAIN*/
+#define R0900_P1_TNRGAIN 0xf4e8
+#define F0900_P1_TUN_KDIVEN 0xf4e800c0
+#define F0900_P1_STB6X00_OCK 0xf4e80030
+#define F0900_P1_TUN_GAIN 0xf4e8000f
+
+/*P1_TNRRF1*/
+#define R0900_P1_TNRRF1 0xf4e9
+#define F0900_P1_TUN_RFFREQ2 0xf4e900ff
+
+/*P1_TNRRF0*/
+#define R0900_P1_TNRRF0 0xf4ea
+#define F0900_P1_TUN_RFFREQ1 0xf4ea00ff
+
+/*P1_TNRBW*/
+#define R0900_P1_TNRBW 0xf4eb
+#define F0900_P1_TUN_RFFREQ0 0xf4eb00c0
+#define F0900_P1_TUN_BW 0xf4eb003f
+
+/*P1_TNRADJ*/
+#define R0900_P1_TNRADJ 0xf4ec
+#define F0900_P1_STB61X0_RCLK 0xf4ec0080
+#define F0900_P1_STB61X0_CALTIME 0xf4ec0040
+#define F0900_P1_STB6X00_DLB 0xf4ec0038
+#define F0900_P1_STB6000_FCL 0xf4ec0007
+
+/*P1_TNRCTL2*/
+#define R0900_P1_TNRCTL2 0xf4ed
+#define F0900_P1_STB61X0_LCP1_RCCKOFF 0xf4ed0080
+#define F0900_P1_STB61X0_LCP0 0xf4ed0040
+#define F0900_P1_STB61X0_XTOUT_RFOUTS 0xf4ed0020
+#define F0900_P1_STB61X0_XTON_MCKDV 0xf4ed0010
+#define F0900_P1_STB61X0_CALOFF_DCOFF 0xf4ed0008
+#define F0900_P1_STB6110_LPT 0xf4ed0004
+#define F0900_P1_STB6110_RX 0xf4ed0002
+#define F0900_P1_STB6110_SYN 0xf4ed0001
+
+/*P1_TNRCFG3*/
+#define R0900_P1_TNRCFG3 0xf4ee
+#define F0900_P1_STB6120_DISCTRL1 0xf4ee0080
+#define F0900_P1_STB6120_INVORDER 0xf4ee0040
+#define F0900_P1_STB6120_ENCTRL6 0xf4ee0020
+#define F0900_P1_TUN_PLLFREQ 0xf4ee001c
+#define F0900_P1_TUN_I2CFREQ_MODE 0xf4ee0003
+
+/*P1_TNRLAUNCH*/
+#define R0900_P1_TNRLAUNCH 0xf4f0
+
+/*P1_TNRLD*/
+#define R0900_P1_TNRLD 0xf4f0
+#define F0900_P1_TUNLD_VCOING 0xf4f00080
+#define F0900_P1_TUN_REG1FAIL 0xf4f00040
+#define F0900_P1_TUN_REG2FAIL 0xf4f00020
+#define F0900_P1_TUN_REG3FAIL 0xf4f00010
+#define F0900_P1_TUN_REG4FAIL 0xf4f00008
+#define F0900_P1_TUN_REG5FAIL 0xf4f00004
+#define F0900_P1_TUN_BWING 0xf4f00002
+#define F0900_P1_TUN_LOCKED 0xf4f00001
+
+/*P1_TNROBSL*/
+#define R0900_P1_TNROBSL 0xf4f6
+#define F0900_P1_TUN_I2CABORTED 0xf4f60080
+#define F0900_P1_TUN_LPEN 0xf4f60040
+#define F0900_P1_TUN_FCCK 0xf4f60020
+#define F0900_P1_TUN_I2CLOCKED 0xf4f60010
+#define F0900_P1_TUN_PROGDONE 0xf4f6000c
+#define F0900_P1_TUN_RFRESTE1 0xf4f60003
+
+/*P1_TNRRESTE*/
+#define R0900_P1_TNRRESTE 0xf4f7
+#define F0900_P1_TUN_RFRESTE0 0xf4f700ff
+
+/*P1_SMAPCOEF7*/
+#define R0900_P1_SMAPCOEF7 0xf500
+#define F0900_P1_DIS_QSCALE 0xf5000080
+#define F0900_P1_SMAPCOEF_Q_LLR12 0xf500017f
+
+/*P1_SMAPCOEF6*/
+#define R0900_P1_SMAPCOEF6 0xf501
+#define F0900_P1_DIS_NEWSCALE 0xf5010008
+#define F0900_P1_ADJ_8PSKLLR1 0xf5010004
+#define F0900_P1_OLD_8PSKLLR1 0xf5010002
+#define F0900_P1_DIS_AB8PSK 0xf5010001
+
+/*P1_SMAPCOEF5*/
+#define R0900_P1_SMAPCOEF5 0xf502
+#define F0900_P1_DIS_8SCALE 0xf5020080
+#define F0900_P1_SMAPCOEF_8P_LLR23 0xf502017f
+
+/*P1_DMDPLHSTAT*/
+#define R0900_P1_DMDPLHSTAT 0xf520
+#define F0900_P1_PLH_STATISTIC 0xf52000ff
+
+/*P1_LOCKTIME3*/
+#define R0900_P1_LOCKTIME3 0xf522
+#define F0900_P1_DEMOD_LOCKTIME3 0xf52200ff
+
+/*P1_LOCKTIME2*/
+#define R0900_P1_LOCKTIME2 0xf523
+#define F0900_P1_DEMOD_LOCKTIME2 0xf52300ff
+
+/*P1_LOCKTIME1*/
+#define R0900_P1_LOCKTIME1 0xf524
+#define F0900_P1_DEMOD_LOCKTIME1 0xf52400ff
+
+/*P1_LOCKTIME0*/
+#define R0900_P1_LOCKTIME0 0xf525
+#define F0900_P1_DEMOD_LOCKTIME0 0xf52500ff
+
+/*P1_VITSCALE*/
+#define R0900_P1_VITSCALE 0xf532
+#define F0900_P1_NVTH_NOSRANGE 0xf5320080
+#define F0900_P1_VERROR_MAXMODE 0xf5320040
+#define F0900_P1_KDIV_MODE 0xf5320030
+#define F0900_P1_NSLOWSN_LOCKED 0xf5320008
+#define F0900_P1_DELOCK_PRFLOSS 0xf5320004
+#define F0900_P1_DIS_RSFLOCK 0xf5320002
+
+/*P1_FECM*/
+#define R0900_P1_FECM 0xf533
+#define F0900_P1_DSS_DVB 0xf5330080
+#define F0900_P1_DEMOD_BYPASS 0xf5330040
+#define F0900_P1_CMP_SLOWMODE 0xf5330020
+#define F0900_P1_DSS_SRCH 0xf5330010
+#define F0900_P1_DIFF_MODEVIT 0xf5330004
+#define F0900_P1_SYNCVIT 0xf5330002
+#define F0900_P1_IQINV 0xf5330001
+
+/*P1_VTH12*/
+#define R0900_P1_VTH12 0xf534
+#define F0900_P1_VTH12 0xf53400ff
+
+/*P1_VTH23*/
+#define R0900_P1_VTH23 0xf535
+#define F0900_P1_VTH23 0xf53500ff
+
+/*P1_VTH34*/
+#define R0900_P1_VTH34 0xf536
+#define F0900_P1_VTH34 0xf53600ff
+
+/*P1_VTH56*/
+#define R0900_P1_VTH56 0xf537
+#define F0900_P1_VTH56 0xf53700ff
+
+/*P1_VTH67*/
+#define R0900_P1_VTH67 0xf538
+#define F0900_P1_VTH67 0xf53800ff
+
+/*P1_VTH78*/
+#define R0900_P1_VTH78 0xf539
+#define F0900_P1_VTH78 0xf53900ff
+
+/*P1_VITCURPUN*/
+#define R0900_P1_VITCURPUN 0xf53a
+#define F0900_P1_VIT_MAPPING 0xf53a00e0
+#define F0900_P1_VIT_CURPUN 0xf53a001f
+
+/*P1_VERROR*/
+#define R0900_P1_VERROR 0xf53b
+#define F0900_P1_REGERR_VIT 0xf53b00ff
+
+/*P1_PRVIT*/
+#define R0900_P1_PRVIT 0xf53c
+#define F0900_P1_DIS_VTHLOCK 0xf53c0040
+#define F0900_P1_E7_8VIT 0xf53c0020
+#define F0900_P1_E6_7VIT 0xf53c0010
+#define F0900_P1_E5_6VIT 0xf53c0008
+#define F0900_P1_E3_4VIT 0xf53c0004
+#define F0900_P1_E2_3VIT 0xf53c0002
+#define F0900_P1_E1_2VIT 0xf53c0001
+
+/*P1_VAVSRVIT*/
+#define R0900_P1_VAVSRVIT 0xf53d
+#define F0900_P1_AMVIT 0xf53d0080
+#define F0900_P1_FROZENVIT 0xf53d0040
+#define F0900_P1_SNVIT 0xf53d0030
+#define F0900_P1_TOVVIT 0xf53d000c
+#define F0900_P1_HYPVIT 0xf53d0003
+
+/*P1_VSTATUSVIT*/
+#define R0900_P1_VSTATUSVIT 0xf53e
+#define F0900_P1_VITERBI_ON 0xf53e0080
+#define F0900_P1_END_LOOPVIT 0xf53e0040
+#define F0900_P1_VITERBI_DEPRF 0xf53e0020
+#define F0900_P1_PRFVIT 0xf53e0010
+#define F0900_P1_LOCKEDVIT 0xf53e0008
+#define F0900_P1_VITERBI_DELOCK 0xf53e0004
+#define F0900_P1_VIT_DEMODSEL 0xf53e0002
+#define F0900_P1_VITERBI_COMPOUT 0xf53e0001
+
+/*P1_VTHINUSE*/
+#define R0900_P1_VTHINUSE 0xf53f
+#define F0900_P1_VIT_INUSE 0xf53f00ff
+
+/*P1_KDIV12*/
+#define R0900_P1_KDIV12 0xf540
+#define F0900_P1_KDIV12_MANUAL 0xf5400080
+#define F0900_P1_K_DIVIDER_12 0xf540007f
+
+/*P1_KDIV23*/
+#define R0900_P1_KDIV23 0xf541
+#define F0900_P1_KDIV23_MANUAL 0xf5410080
+#define F0900_P1_K_DIVIDER_23 0xf541007f
+
+/*P1_KDIV34*/
+#define R0900_P1_KDIV34 0xf542
+#define F0900_P1_KDIV34_MANUAL 0xf5420080
+#define F0900_P1_K_DIVIDER_34 0xf542007f
+
+/*P1_KDIV56*/
+#define R0900_P1_KDIV56 0xf543
+#define F0900_P1_KDIV56_MANUAL 0xf5430080
+#define F0900_P1_K_DIVIDER_56 0xf543007f
+
+/*P1_KDIV67*/
+#define R0900_P1_KDIV67 0xf544
+#define F0900_P1_KDIV67_MANUAL 0xf5440080
+#define F0900_P1_K_DIVIDER_67 0xf544007f
+
+/*P1_KDIV78*/
+#define R0900_P1_KDIV78 0xf545
+#define F0900_P1_KDIV78_MANUAL 0xf5450080
+#define F0900_P1_K_DIVIDER_78 0xf545007f
+
+/*P1_PDELCTRL1*/
+#define R0900_P1_PDELCTRL1 0xf550
+#define F0900_P1_INV_MISMASK 0xf5500080
+#define F0900_P1_FORCE_ACCEPTED 0xf5500040
+#define F0900_P1_FILTER_EN 0xf5500020
+#define F0900_P1_FORCE_PKTDELINUSE 0xf5500010
+#define F0900_P1_HYSTEN 0xf5500008
+#define F0900_P1_HYSTSWRST 0xf5500004
+#define F0900_P1_EN_MIS00 0xf5500002
+#define F0900_P1_ALGOSWRST 0xf5500001
+
+/*P1_PDELCTRL2*/
+#define R0900_P1_PDELCTRL2 0xf551
+#define F0900_P1_FORCE_CONTINUOUS 0xf5510080
+#define F0900_P1_RESET_UPKO_COUNT 0xf5510040
+#define F0900_P1_USER_PKTDELIN_NB 0xf5510020
+#define F0900_P1_FORCE_LOCKED 0xf5510010
+#define F0900_P1_DATA_UNBBSCRAM 0xf5510008
+#define F0900_P1_FORCE_LONGPKT 0xf5510004
+#define F0900_P1_FRAME_MODE 0xf5510002
+
+/*P1_HYSTTHRESH*/
+#define R0900_P1_HYSTTHRESH 0xf554
+#define F0900_P1_UNLCK_THRESH 0xf55400f0
+#define F0900_P1_DELIN_LCK_THRESH 0xf554000f
+
+/*P1_ISIENTRY*/
+#define R0900_P1_ISIENTRY 0xf55e
+#define F0900_P1_ISI_ENTRY 0xf55e00ff
+
+/*P1_ISIBITENA*/
+#define R0900_P1_ISIBITENA 0xf55f
+#define F0900_P1_ISI_BIT_EN 0xf55f00ff
+
+/*P1_MATSTR1*/
+#define R0900_P1_MATSTR1 0xf560
+#define F0900_P1_MATYPE_CURRENT1 0xf56000ff
+
+/*P1_MATSTR0*/
+#define R0900_P1_MATSTR0 0xf561
+#define F0900_P1_MATYPE_CURRENT0 0xf56100ff
+
+/*P1_UPLSTR1*/
+#define R0900_P1_UPLSTR1 0xf562
+#define F0900_P1_UPL_CURRENT1 0xf56200ff
+
+/*P1_UPLSTR0*/
+#define R0900_P1_UPLSTR0 0xf563
+#define F0900_P1_UPL_CURRENT0 0xf56300ff
+
+/*P1_DFLSTR1*/
+#define R0900_P1_DFLSTR1 0xf564
+#define F0900_P1_DFL_CURRENT1 0xf56400ff
+
+/*P1_DFLSTR0*/
+#define R0900_P1_DFLSTR0 0xf565
+#define F0900_P1_DFL_CURRENT0 0xf56500ff
+
+/*P1_SYNCSTR*/
+#define R0900_P1_SYNCSTR 0xf566
+#define F0900_P1_SYNC_CURRENT 0xf56600ff
+
+/*P1_SYNCDSTR1*/
+#define R0900_P1_SYNCDSTR1 0xf567
+#define F0900_P1_SYNCD_CURRENT1 0xf56700ff
+
+/*P1_SYNCDSTR0*/
+#define R0900_P1_SYNCDSTR0 0xf568
+#define F0900_P1_SYNCD_CURRENT0 0xf56800ff
+
+/*P1_PDELSTATUS1*/
+#define R0900_P1_PDELSTATUS1 0xf569
+#define F0900_P1_PKTDELIN_DELOCK 0xf5690080
+#define F0900_P1_SYNCDUPDFL_BADDFL 0xf5690040
+#define F0900_P1_CONTINUOUS_STREAM 0xf5690020
+#define F0900_P1_UNACCEPTED_STREAM 0xf5690010
+#define F0900_P1_BCH_ERROR_FLAG 0xf5690008
+#define F0900_P1_BBHCRCKO 0xf5690004
+#define F0900_P1_PKTDELIN_LOCK 0xf5690002
+#define F0900_P1_FIRST_LOCK 0xf5690001
+
+/*P1_PDELSTATUS2*/
+#define R0900_P1_PDELSTATUS2 0xf56a
+#define F0900_P1_PKTDEL_DEMODSEL 0xf56a0080
+#define F0900_P1_FRAME_MODCOD 0xf56a007c
+#define F0900_P1_FRAME_TYPE 0xf56a0003
+
+/*P1_BBFCRCKO1*/
+#define R0900_P1_BBFCRCKO1 0xf56b
+#define F0900_P1_BBHCRC_KOCNT1 0xf56b00ff
+
+/*P1_BBFCRCKO0*/
+#define R0900_P1_BBFCRCKO0 0xf56c
+#define F0900_P1_BBHCRC_KOCNT0 0xf56c00ff
+
+/*P1_UPCRCKO1*/
+#define R0900_P1_UPCRCKO1 0xf56d
+#define F0900_P1_PKTCRC_KOCNT1 0xf56d00ff
+
+/*P1_UPCRCKO0*/
+#define R0900_P1_UPCRCKO0 0xf56e
+#define F0900_P1_PKTCRC_KOCNT0 0xf56e00ff
+
+/*P1_TSSTATEM*/
+#define R0900_P1_TSSTATEM 0xf570
+#define F0900_P1_TSDIL_ON 0xf5700080
+#define F0900_P1_TSSKIPRS_ON 0xf5700040
+#define F0900_P1_TSRS_ON 0xf5700020
+#define F0900_P1_TSDESCRAMB_ON 0xf5700010
+#define F0900_P1_TSFRAME_MODE 0xf5700008
+#define F0900_P1_TS_DISABLE 0xf5700004
+#define F0900_P1_TSACM_MODE 0xf5700002
+#define F0900_P1_TSOUT_NOSYNC 0xf5700001
+
+/*P1_TSCFGH*/
+#define R0900_P1_TSCFGH 0xf572
+#define F0900_P1_TSFIFO_DVBCI 0xf5720080
+#define F0900_P1_TSFIFO_SERIAL 0xf5720040
+#define F0900_P1_TSFIFO_TEIUPDATE 0xf5720020
+#define F0900_P1_TSFIFO_DUTY50 0xf5720010
+#define F0900_P1_TSFIFO_HSGNLOUT 0xf5720008
+#define F0900_P1_TSFIFO_ERRMODE 0xf5720006
+#define F0900_P1_RST_HWARE 0xf5720001
+
+/*P1_TSCFGM*/
+#define R0900_P1_TSCFGM 0xf573
+#define F0900_P1_TSFIFO_MANSPEED 0xf57300c0
+#define F0900_P1_TSFIFO_PERMDATA 0xf5730020
+#define F0900_P1_TSFIFO_NONEWSGNL 0xf5730010
+#define F0900_P1_TSFIFO_BITSPEED 0xf5730008
+#define F0900_P1_NPD_SPECDVBS2 0xf5730004
+#define F0900_P1_TSFIFO_STOPCKDIS 0xf5730002
+#define F0900_P1_TSFIFO_INVDATA 0xf5730001
+
+/*P1_TSCFGL*/
+#define R0900_P1_TSCFGL 0xf574
+#define F0900_P1_TSFIFO_BCLKDEL1CK 0xf57400c0
+#define F0900_P1_BCHERROR_MODE 0xf5740030
+#define F0900_P1_TSFIFO_NSGNL2DATA 0xf5740008
+#define F0900_P1_TSFIFO_EMBINDVB 0xf5740004
+#define F0900_P1_TSFIFO_DPUNACT 0xf5740002
+#define F0900_P1_TSFIFO_NPDOFF 0xf5740001
+
+/*P1_TSINSDELH*/
+#define R0900_P1_TSINSDELH 0xf576
+#define F0900_P1_TSDEL_SYNCBYTE 0xf5760080
+#define F0900_P1_TSDEL_XXHEADER 0xf5760040
+#define F0900_P1_TSDEL_BBHEADER 0xf5760020
+#define F0900_P1_TSDEL_DATAFIELD 0xf5760010
+#define F0900_P1_TSINSDEL_ISCR 0xf5760008
+#define F0900_P1_TSINSDEL_NPD 0xf5760004
+#define F0900_P1_TSINSDEL_RSPARITY 0xf5760002
+#define F0900_P1_TSINSDEL_CRC8 0xf5760001
+
+/*P1_TSSPEED*/
+#define R0900_P1_TSSPEED 0xf580
+#define F0900_P1_TSFIFO_OUTSPEED 0xf58000ff
+
+/*P1_TSSTATUS*/
+#define R0900_P1_TSSTATUS 0xf581
+#define F0900_P1_TSFIFO_LINEOK 0xf5810080
+#define F0900_P1_TSFIFO_ERROR 0xf5810040
+#define F0900_P1_TSFIFO_DATA7 0xf5810020
+#define F0900_P1_TSFIFO_NOSYNC 0xf5810010
+#define F0900_P1_ISCR_INITIALIZED 0xf5810008
+#define F0900_P1_ISCR_UPDATED 0xf5810004
+#define F0900_P1_SOFFIFO_UNREGUL 0xf5810002
+#define F0900_P1_DIL_READY 0xf5810001
+
+/*P1_TSSTATUS2*/
+#define R0900_P1_TSSTATUS2 0xf582
+#define F0900_P1_TSFIFO_DEMODSEL 0xf5820080
+#define F0900_P1_TSFIFOSPEED_STORE 0xf5820040
+#define F0900_P1_DILXX_RESET 0xf5820020
+#define F0900_P1_TSSERIAL_IMPOS 0xf5820010
+#define F0900_P1_TSFIFO_LINENOK 0xf5820008
+#define F0900_P1_BITSPEED_EVENT 0xf5820004
+#define F0900_P1_SCRAMBDETECT 0xf5820002
+#define F0900_P1_ULDTV67_FALSELOCK 0xf5820001
+
+/*P1_TSBITRATE1*/
+#define R0900_P1_TSBITRATE1 0xf583
+#define F0900_P1_TSFIFO_BITRATE1 0xf58300ff
+
+/*P1_TSBITRATE0*/
+#define R0900_P1_TSBITRATE0 0xf584
+#define F0900_P1_TSFIFO_BITRATE0 0xf58400ff
+
+/*P1_ERRCTRL1*/
+#define R0900_P1_ERRCTRL1 0xf598
+#define F0900_P1_ERR_SOURCE1 0xf59800f0
+#define F0900_P1_NUM_EVENT1 0xf5980007
+
+/*P1_ERRCNT12*/
+#define R0900_P1_ERRCNT12 0xf599
+#define F0900_P1_ERRCNT1_OLDVALUE 0xf5990080
+#define F0900_P1_ERR_CNT12 0xf599007f
+
+/*P1_ERRCNT11*/
+#define R0900_P1_ERRCNT11 0xf59a
+#define F0900_P1_ERR_CNT11 0xf59a00ff
+
+/*P1_ERRCNT10*/
+#define R0900_P1_ERRCNT10 0xf59b
+#define F0900_P1_ERR_CNT10 0xf59b00ff
+
+/*P1_ERRCTRL2*/
+#define R0900_P1_ERRCTRL2 0xf59c
+#define F0900_P1_ERR_SOURCE2 0xf59c00f0
+#define F0900_P1_NUM_EVENT2 0xf59c0007
+
+/*P1_ERRCNT22*/
+#define R0900_P1_ERRCNT22 0xf59d
+#define F0900_P1_ERRCNT2_OLDVALUE 0xf59d0080
+#define F0900_P1_ERR_CNT22 0xf59d007f
+
+/*P1_ERRCNT21*/
+#define R0900_P1_ERRCNT21 0xf59e
+#define F0900_P1_ERR_CNT21 0xf59e00ff
+
+/*P1_ERRCNT20*/
+#define R0900_P1_ERRCNT20 0xf59f
+#define F0900_P1_ERR_CNT20 0xf59f00ff
+
+/*P1_FECSPY*/
+#define R0900_P1_FECSPY 0xf5a0
+#define F0900_P1_SPY_ENABLE 0xf5a00080
+#define F0900_P1_NO_SYNCBYTE 0xf5a00040
+#define F0900_P1_SERIAL_MODE 0xf5a00020
+#define F0900_P1_UNUSUAL_PACKET 0xf5a00010
+#define F0900_P1_BER_PACKMODE 0xf5a00008
+#define F0900_P1_BERMETER_LMODE 0xf5a00002
+#define F0900_P1_BERMETER_RESET 0xf5a00001
+
+/*P1_FSPYCFG*/
+#define R0900_P1_FSPYCFG 0xf5a1
+#define F0900_P1_FECSPY_INPUT 0xf5a100c0
+#define F0900_P1_RST_ON_ERROR 0xf5a10020
+#define F0900_P1_ONE_SHOT 0xf5a10010
+#define F0900_P1_I2C_MODE 0xf5a1000c
+#define F0900_P1_SPY_HYSTERESIS 0xf5a10003
+
+/*P1_FSPYDATA*/
+#define R0900_P1_FSPYDATA 0xf5a2
+#define F0900_P1_SPY_STUFFING 0xf5a20080
+#define F0900_P1_NOERROR_PKTJITTER 0xf5a20040
+#define F0900_P1_SPY_CNULLPKT 0xf5a20020
+#define F0900_P1_SPY_OUTDATA_MODE 0xf5a2001f
+
+/*P1_FSPYOUT*/
+#define R0900_P1_FSPYOUT 0xf5a3
+#define F0900_P1_FSPY_DIRECT 0xf5a30080
+#define F0900_P1_SPY_OUTDATA_BUS 0xf5a30038
+#define F0900_P1_STUFF_MODE 0xf5a30007
+
+/*P1_FSTATUS*/
+#define R0900_P1_FSTATUS 0xf5a4
+#define F0900_P1_SPY_ENDSIM 0xf5a40080
+#define F0900_P1_VALID_SIM 0xf5a40040
+#define F0900_P1_FOUND_SIGNAL 0xf5a40020
+#define F0900_P1_DSS_SYNCBYTE 0xf5a40010
+#define F0900_P1_RESULT_STATE 0xf5a4000f
+
+/*P1_FBERCPT4*/
+#define R0900_P1_FBERCPT4 0xf5a8
+#define F0900_P1_FBERMETER_CPT4 0xf5a800ff
+
+/*P1_FBERCPT3*/
+#define R0900_P1_FBERCPT3 0xf5a9
+#define F0900_P1_FBERMETER_CPT3 0xf5a900ff
+
+/*P1_FBERCPT2*/
+#define R0900_P1_FBERCPT2 0xf5aa
+#define F0900_P1_FBERMETER_CPT2 0xf5aa00ff
+
+/*P1_FBERCPT1*/
+#define R0900_P1_FBERCPT1 0xf5ab
+#define F0900_P1_FBERMETER_CPT1 0xf5ab00ff
+
+/*P1_FBERCPT0*/
+#define R0900_P1_FBERCPT0 0xf5ac
+#define F0900_P1_FBERMETER_CPT0 0xf5ac00ff
+
+/*P1_FBERERR2*/
+#define R0900_P1_FBERERR2 0xf5ad
+#define F0900_P1_FBERMETER_ERR2 0xf5ad00ff
+
+/*P1_FBERERR1*/
+#define R0900_P1_FBERERR1 0xf5ae
+#define F0900_P1_FBERMETER_ERR1 0xf5ae00ff
+
+/*P1_FBERERR0*/
+#define R0900_P1_FBERERR0 0xf5af
+#define F0900_P1_FBERMETER_ERR0 0xf5af00ff
+
+/*P1_FSPYBER*/
+#define R0900_P1_FSPYBER 0xf5b2
+#define F0900_P1_FSPYOBS_XORREAD 0xf5b20040
+#define F0900_P1_FSPYBER_OBSMODE 0xf5b20020
+#define F0900_P1_FSPYBER_SYNCBYTE 0xf5b20010
+#define F0900_P1_FSPYBER_UNSYNC 0xf5b20008
+#define F0900_P1_FSPYBER_CTIME 0xf5b20007
+
+/*RCCFGH*/
+#define R0900_RCCFGH 0xf600
+#define F0900_TSRCFIFO_DVBCI 0xf6000080
+#define F0900_TSRCFIFO_SERIAL 0xf6000040
+#define F0900_TSRCFIFO_DISABLE 0xf6000020
+#define F0900_TSFIFO_2TORC 0xf6000010
+#define F0900_TSRCFIFO_HSGNLOUT 0xf6000008
+#define F0900_TSRCFIFO_ERRMODE 0xf6000006
+
+/*TSGENERAL*/
+#define R0900_TSGENERAL 0xf630
+#define F0900_TSFIFO_BCLK1ALL 0xf6300020
+#define F0900_MUXSTREAM_OUTMODE 0xf6300008
+#define F0900_TSFIFO_PERMPARAL 0xf6300006
+#define F0900_RST_REEDSOLO 0xf6300001
+
+/*TSGENERAL1X*/
+#define R0900_TSGENERAL1X 0xf670
+#define F0900_TSFIFO1X_BCLK1ALL 0xf6700020
+#define F0900_MUXSTREAM1X_OUTMODE 0xf6700008
+#define F0900_TSFIFO1X_PERMPARAL 0xf6700006
+#define F0900_RST1X_REEDSOLO 0xf6700001
+
+/*NBITER_NF4*/
+#define R0900_NBITER_NF4 0xfa03
+#define F0900_NBITER_NF_QP_1_2 0xfa0300ff
+
+/*NBITER_NF5*/
+#define R0900_NBITER_NF5 0xfa04
+#define F0900_NBITER_NF_QP_3_5 0xfa0400ff
+
+/*NBITER_NF6*/
+#define R0900_NBITER_NF6 0xfa05
+#define F0900_NBITER_NF_QP_2_3 0xfa0500ff
+
+/*NBITER_NF7*/
+#define R0900_NBITER_NF7 0xfa06
+#define F0900_NBITER_NF_QP_3_4 0xfa0600ff
+
+/*NBITER_NF8*/
+#define R0900_NBITER_NF8 0xfa07
+#define F0900_NBITER_NF_QP_4_5 0xfa0700ff
+
+/*NBITER_NF9*/
+#define R0900_NBITER_NF9 0xfa08
+#define F0900_NBITER_NF_QP_5_6 0xfa0800ff
+
+/*NBITER_NF10*/
+#define R0900_NBITER_NF10 0xfa09
+#define F0900_NBITER_NF_QP_8_9 0xfa0900ff
+
+/*NBITER_NF11*/
+#define R0900_NBITER_NF11 0xfa0a
+#define F0900_NBITER_NF_QP_9_10 0xfa0a00ff
+
+/*NBITER_NF12*/
+#define R0900_NBITER_NF12 0xfa0b
+#define F0900_NBITER_NF_8P_3_5 0xfa0b00ff
+
+/*NBITER_NF13*/
+#define R0900_NBITER_NF13 0xfa0c
+#define F0900_NBITER_NF_8P_2_3 0xfa0c00ff
+
+/*NBITER_NF14*/
+#define R0900_NBITER_NF14 0xfa0d
+#define F0900_NBITER_NF_8P_3_4 0xfa0d00ff
+
+/*NBITER_NF15*/
+#define R0900_NBITER_NF15 0xfa0e
+#define F0900_NBITER_NF_8P_5_6 0xfa0e00ff
+
+/*NBITER_NF16*/
+#define R0900_NBITER_NF16 0xfa0f
+#define F0900_NBITER_NF_8P_8_9 0xfa0f00ff
+
+/*NBITER_NF17*/
+#define R0900_NBITER_NF17 0xfa10
+#define F0900_NBITER_NF_8P_9_10 0xfa1000ff
+
+/*NBITERNOERR*/
+#define R0900_NBITERNOERR 0xfa3f
+#define F0900_NBITER_STOP_CRIT 0xfa3f000f
+
+/*GAINLLR_NF4*/
+#define R0900_GAINLLR_NF4 0xfa43
+#define F0900_GAINLLR_NF_QP_1_2 0xfa43007f
+
+/*GAINLLR_NF5*/
+#define R0900_GAINLLR_NF5 0xfa44
+#define F0900_GAINLLR_NF_QP_3_5 0xfa44007f
+
+/*GAINLLR_NF6*/
+#define R0900_GAINLLR_NF6 0xfa45
+#define F0900_GAINLLR_NF_QP_2_3 0xfa45007f
+
+/*GAINLLR_NF7*/
+#define R0900_GAINLLR_NF7 0xfa46
+#define F0900_GAINLLR_NF_QP_3_4 0xfa46007f
+
+/*GAINLLR_NF8*/
+#define R0900_GAINLLR_NF8 0xfa47
+#define F0900_GAINLLR_NF_QP_4_5 0xfa47007f
+
+/*GAINLLR_NF9*/
+#define R0900_GAINLLR_NF9 0xfa48
+#define F0900_GAINLLR_NF_QP_5_6 0xfa48007f
+
+/*GAINLLR_NF10*/
+#define R0900_GAINLLR_NF10 0xfa49
+#define F0900_GAINLLR_NF_QP_8_9 0xfa49007f
+
+/*GAINLLR_NF11*/
+#define R0900_GAINLLR_NF11 0xfa4a
+#define F0900_GAINLLR_NF_QP_9_10 0xfa4a007f
+
+/*GAINLLR_NF12*/
+#define R0900_GAINLLR_NF12 0xfa4b
+#define F0900_GAINLLR_NF_8P_3_5 0xfa4b007f
+
+/*GAINLLR_NF13*/
+#define R0900_GAINLLR_NF13 0xfa4c
+#define F0900_GAINLLR_NF_8P_2_3 0xfa4c007f
+
+/*GAINLLR_NF14*/
+#define R0900_GAINLLR_NF14 0xfa4d
+#define F0900_GAINLLR_NF_8P_3_4 0xfa4d007f
+
+/*GAINLLR_NF15*/
+#define R0900_GAINLLR_NF15 0xfa4e
+#define F0900_GAINLLR_NF_8P_5_6 0xfa4e007f
+
+/*GAINLLR_NF16*/
+#define R0900_GAINLLR_NF16 0xfa4f
+#define F0900_GAINLLR_NF_8P_8_9 0xfa4f007f
+
+/*GAINLLR_NF17*/
+#define R0900_GAINLLR_NF17 0xfa50
+#define F0900_GAINLLR_NF_8P_9_10 0xfa50007f
+
+/*CFGEXT*/
+#define R0900_CFGEXT 0xfa80
+#define F0900_STAGMODE 0xfa800080
+#define F0900_BYPBCH 0xfa800040
+#define F0900_BYPLDPC 0xfa800020
+#define F0900_LDPCMODE 0xfa800010
+#define F0900_INVLLRSIGN 0xfa800008
+#define F0900_SHORTMULT 0xfa800004
+#define F0900_EXTERNTX 0xfa800001
+
+/*GENCFG*/
+#define R0900_GENCFG 0xfa86
+#define F0900_BROADCAST 0xfa860010
+#define F0900_NOSHFRD2 0xfa860008
+#define F0900_BCHERRFLAG 0xfa860004
+#define F0900_PRIORITY 0xfa860002
+#define F0900_DDEMOD 0xfa860001
+
+/*LDPCERR1*/
+#define R0900_LDPCERR1 0xfa96
+#define F0900_LDPC_ERRORS_COUNTER1 0xfa9600ff
+
+/*LDPCERR0*/
+#define R0900_LDPCERR0 0xfa97
+#define F0900_LDPC_ERRORS_COUNTER0 0xfa9700ff
+
+/*BCHERR*/
+#define R0900_BCHERR 0xfa98
+#define F0900_ERRORFLAG 0xfa980010
+#define F0900_BCH_ERRORS_COUNTER 0xfa98000f
+
+/*TSTRES0*/
+#define R0900_TSTRES0 0xff11
+#define F0900_FRESFEC 0xff110080
+#define F0900_FRESTS 0xff110040
+#define F0900_FRESVIT1 0xff110020
+#define F0900_FRESVIT2 0xff110010
+#define F0900_FRESSYM1 0xff110008
+#define F0900_FRESSYM2 0xff110004
+#define F0900_FRESMAS 0xff110002
+#define F0900_FRESINT 0xff110001
+
+/*P2_TSTDISRX*/
+#define R0900_P2_TSTDISRX 0xff65
+#define F0900_P2_EN_DISRX 0xff650080
+#define F0900_P2_TST_CURRSRC 0xff650040
+#define F0900_P2_IN_DIGSIGNAL 0xff650020
+#define F0900_P2_HIZ_CURRENTSRC 0xff650010
+#define F0900_TST_P2_PIN_SELECT 0xff650008
+#define F0900_P2_TST_DISRX 0xff650007
+
+/*P1_TSTDISRX*/
+#define R0900_P1_TSTDISRX 0xff67
+#define F0900_P1_EN_DISRX 0xff670080
+#define F0900_P1_TST_CURRSRC 0xff670040
+#define F0900_P1_IN_DIGSIGNAL 0xff670020
+#define F0900_P1_HIZ_CURRENTSRC 0xff670010
+#define F0900_TST_P1_PIN_SELECT 0xff670008
+#define F0900_P1_TST_DISRX 0xff670007
+
+#define STV0900_NBREGS 684
+#define STV0900_NBFIELDS 1702
+
+#endif
+
diff --git a/drivers/media/dvb/frontends/stv0900_sw.c b/drivers/media/dvb/frontends/stv0900_sw.c
new file mode 100644
index 00000000000..a5a31536cbc
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0900_sw.c
@@ -0,0 +1,2847 @@
+/*
+ * stv0900_sw.c
+ *
+ * Driver for ST STV0900 satellite demodulator IC.
+ *
+ * Copyright (C) ST Microelectronics.
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "stv0900.h"
+#include "stv0900_reg.h"
+#include "stv0900_priv.h"
+
+int stv0900_check_signal_presence(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 carr_offset,
+ agc2_integr,
+ max_carrier;
+
+ int no_signal;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ carr_offset = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P1_CFR1);
+ carr_offset = ge2comp(carr_offset, 16);
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P1_AGC2I0);
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ break;
+ case STV0900_DEMOD_2:
+ carr_offset = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P2_CFR1);
+ carr_offset = ge2comp(carr_offset, 16);
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params,
+ R0900_P2_AGC2I0);
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ break;
+ }
+
+ max_carrier += (max_carrier / 10);
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ if ((agc2_integr > 0x2000)
+ || (carr_offset > + 2*max_carrier)
+ || (carr_offset < -2*max_carrier))
+ no_signal = TRUE;
+ else
+ no_signal = FALSE;
+
+ return no_signal;
+}
+
+static void stv0900_get_sw_loop_params(struct stv0900_internal *i_params,
+ s32 *frequency_inc, s32 *sw_timeout,
+ s32 *steps,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 timeout, freq_inc, max_steps, srate, max_carrier;
+
+ enum fe_stv0900_search_standard standard;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ srate = i_params->dmd1_symbol_rate;
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ max_carrier += max_carrier / 10;
+ standard = i_params->dmd1_srch_standard;
+ break;
+ case STV0900_DEMOD_2:
+ srate = i_params->dmd2_symbol_rate;
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ max_carrier += max_carrier / 10;
+ standard = i_params->dmd2_srch_stndrd;
+ break;
+ }
+
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ freq_inc = srate;
+ freq_inc /= i_params->mclk >> 10;
+ freq_inc = freq_inc << 6;
+
+ switch (standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ freq_inc *= 3;
+ timeout = 20;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ freq_inc *= 4;
+ timeout = 25;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ freq_inc *= 3;
+ timeout = 25;
+ break;
+ }
+
+ freq_inc /= 100;
+
+ if ((freq_inc > max_carrier) || (freq_inc < 0))
+ freq_inc = max_carrier / 2;
+
+ timeout *= 27500;
+
+ if (srate > 0)
+ timeout /= srate / 1000;
+
+ if ((timeout > 100) || (timeout < 0))
+ timeout = 100;
+
+ max_steps = (max_carrier / freq_inc) + 1;
+
+ if ((max_steps > 100) || (max_steps < 0)) {
+ max_steps = 100;
+ freq_inc = max_carrier / max_steps;
+ }
+
+ *frequency_inc = freq_inc;
+ *sw_timeout = timeout;
+ *steps = max_steps;
+
+}
+
+static int stv0900_search_carr_sw_loop(struct stv0900_internal *i_params,
+ s32 FreqIncr, s32 Timeout, int zigzag,
+ s32 MaxStep, enum fe_stv0900_demod_num demod)
+{
+ int no_signal,
+ lock = FALSE;
+ s32 stepCpt,
+ freqOffset,
+ max_carrier;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ max_carrier = i_params->dmd1_srch_range / 1000;
+ max_carrier += (max_carrier / 10);
+ break;
+ case STV0900_DEMOD_2:
+ max_carrier = i_params->dmd2_srch_range / 1000;
+ max_carrier += (max_carrier / 10);
+ break;
+ }
+
+ max_carrier = 65536 * (max_carrier / 2);
+ max_carrier /= i_params->mclk / 1000;
+
+ if (max_carrier > 0x4000)
+ max_carrier = 0x4000;
+
+ if (zigzag == TRUE)
+ freqOffset = 0;
+ else
+ freqOffset = -max_carrier + FreqIncr;
+
+ stepCpt = 0;
+
+ do {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1,
+ (freqOffset / 256) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0,
+ freqOffset & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 1);
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params,
+ F0900_P1_RST_HWARE, 1);
+ stv0900_write_bits(i_params,
+ F0900_P1_RST_HWARE, 0);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1,
+ (freqOffset / 256) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0,
+ freqOffset & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 1);
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params,
+ F0900_P2_RST_HWARE, 1);
+ stv0900_write_bits(i_params,
+ F0900_P2_RST_HWARE, 0);
+ }
+ break;
+ }
+
+ if (zigzag == TRUE) {
+ if (freqOffset >= 0)
+ freqOffset = -freqOffset - 2 * FreqIncr;
+ else
+ freqOffset = -freqOffset;
+ } else
+ freqOffset += + 2 * FreqIncr;
+
+ stepCpt++;
+ lock = stv0900_get_demod_lock(i_params, demod, Timeout);
+ no_signal = stv0900_check_signal_presence(i_params, demod);
+
+ } while ((lock == FALSE)
+ && (no_signal == FALSE)
+ && ((freqOffset - FreqIncr) < max_carrier)
+ && ((freqOffset + FreqIncr) > -max_carrier)
+ && (stepCpt < MaxStep));
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_ALGOSWRST, 0);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_ALGOSWRST, 0);
+ break;
+ }
+
+ return lock;
+}
+
+int stv0900_sw_algo(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ int lock = FALSE;
+
+ int no_signal,
+ zigzag;
+ s32 dvbs2_fly_wheel;
+
+ s32 freqIncrement, softStepTimeout, trialCounter, max_steps;
+
+ stv0900_get_sw_loop_params(i_params, &freqIncrement, &softStepTimeout,
+ &max_steps, demod);
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_srch_standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0x3B);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0xef);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x49);
+ zigzag = FALSE;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x68);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
+ 0x89);
+
+ zigzag = TRUE;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0x3B);
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x79);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ,
+ 0xef);
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS,
+ 0x68);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD,
+ 0xc9);
+ zigzag = FALSE;
+ break;
+ }
+
+ trialCounter = 0;
+ do {
+ lock = stv0900_search_carr_sw_loop(i_params,
+ freqIncrement,
+ softStepTimeout,
+ zigzag,
+ max_steps,
+ demod);
+ no_signal = stv0900_check_signal_presence(i_params,
+ demod);
+ trialCounter++;
+ if ((lock == TRUE)
+ || (no_signal == TRUE)
+ || (trialCounter == 2)) {
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params,
+ R0900_P1_CARFREQ,
+ 0x49);
+ stv0900_write_reg(i_params,
+ R0900_P1_CORRELABS,
+ 0x9e);
+ } else {
+ stv0900_write_reg(i_params,
+ R0900_P1_CARFREQ,
+ 0xed);
+ stv0900_write_reg(i_params,
+ R0900_P1_CORRELABS,
+ 0x88);
+ }
+
+ if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
+
+ if (dvbs2_fly_wheel < 0xd) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P1_FLYWHEEL_CPT);
+ }
+
+ if (dvbs2_fly_wheel < 0xd) {
+ lock = FALSE;
+
+ if (trialCounter < 2) {
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x68);
+
+ stv0900_write_reg(i_params, R0900_P1_DMDCFGMD, 0x89);
+ }
+ }
+ }
+ }
+
+ } while ((lock == FALSE)
+ && (trialCounter < 2)
+ && (no_signal == FALSE));
+
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_srch_stndrd) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0x3b);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0xef);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD,
+ 0x49);
+ zigzag = FALSE;
+ break;
+ case STV0900_SEARCH_DVBS2:
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x68);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
+ zigzag = TRUE;
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0x3b);
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x79);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ,
+ 0xef);
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS,
+ 0x68);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0xc9);
+
+ zigzag = FALSE;
+ break;
+ }
+
+ trialCounter = 0;
+
+ do {
+ lock = stv0900_search_carr_sw_loop(i_params,
+ freqIncrement,
+ softStepTimeout,
+ zigzag,
+ max_steps,
+ demod);
+ no_signal = stv0900_check_signal_presence(i_params,
+ demod);
+ trialCounter++;
+ if ((lock == TRUE)
+ || (no_signal == TRUE)
+ || (trialCounter == 2)) {
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params,
+ R0900_P2_CARFREQ,
+ 0x49);
+ stv0900_write_reg(i_params,
+ R0900_P2_CORRELABS,
+ 0x9e);
+ } else {
+ stv0900_write_reg(i_params,
+ R0900_P2_CARFREQ,
+ 0xed);
+ stv0900_write_reg(i_params,
+ R0900_P2_CORRELABS,
+ 0x88);
+ }
+
+ if ((lock == TRUE) && (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS2_FOUND)) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
+ if (dvbs2_fly_wheel < 0xd) {
+ msleep(softStepTimeout);
+ dvbs2_fly_wheel = stv0900_get_bits(i_params, F0900_P2_FLYWHEEL_CPT);
+ }
+
+ if (dvbs2_fly_wheel < 0xd) {
+ lock = FALSE;
+ if (trialCounter < 2) {
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x79);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x68);
+
+ stv0900_write_reg(i_params, R0900_P2_DMDCFGMD, 0x89);
+ }
+ }
+ }
+ }
+
+ } while ((lock == FALSE) && (trialCounter < 2) && (no_signal == FALSE));
+
+ break;
+ }
+
+ return lock;
+}
+
+static u32 stv0900_get_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_field3, sfr_field2, sfr_field1, sfr_field0,
+ rem1, rem2, intval1, intval2, srate;
+
+ dmd_reg(sfr_field3, F0900_P1_SYMB_FREQ3, F0900_P2_SYMB_FREQ3);
+ dmd_reg(sfr_field2, F0900_P1_SYMB_FREQ2, F0900_P2_SYMB_FREQ2);
+ dmd_reg(sfr_field1, F0900_P1_SYMB_FREQ1, F0900_P2_SYMB_FREQ1);
+ dmd_reg(sfr_field0, F0900_P1_SYMB_FREQ0, F0900_P2_SYMB_FREQ0);
+
+ srate = (stv0900_get_bits(i_params, sfr_field3) << 24) +
+ (stv0900_get_bits(i_params, sfr_field2) << 16) +
+ (stv0900_get_bits(i_params, sfr_field1) << 8) +
+ (stv0900_get_bits(i_params, sfr_field0));
+ dprintk("lock: srate=%d r0=0x%x r1=0x%x r2=0x%x r3=0x%x \n",
+ srate, stv0900_get_bits(i_params, sfr_field0),
+ stv0900_get_bits(i_params, sfr_field1),
+ stv0900_get_bits(i_params, sfr_field2),
+ stv0900_get_bits(i_params, sfr_field3));
+
+ intval1 = (mclk) >> 16;
+ intval2 = (srate) >> 16;
+
+ rem1 = (mclk) % 0x10000;
+ rem2 = (srate) % 0x10000;
+ srate = (intval1 * intval2) +
+ ((intval1 * rem2) >> 16) +
+ ((intval2 * rem1) >> 16);
+
+ return srate;
+}
+
+static void stv0900_set_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_init_reg;
+ u32 symb;
+
+ dprintk(KERN_INFO "%s: Mclk %d, SR %d, Dmd %d\n", __func__, mclk,
+ srate, demod);
+
+ dmd_reg(sfr_init_reg, R0900_P1_SFRINIT1, R0900_P2_SFRINIT1);
+
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ stv0900_write_reg(i_params, sfr_init_reg, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, sfr_init_reg + 1, (symb & 0xFF));
+}
+
+static void stv0900_set_max_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_max_reg;
+ u32 symb;
+
+ dmd_reg(sfr_max_reg, R0900_P1_SFRUP1, R0900_P2_SFRUP1);
+
+ srate = 105 * (srate / 100);
+
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ if (symb < 0x7fff) {
+ stv0900_write_reg(i_params, sfr_max_reg, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, sfr_max_reg + 1, (symb & 0xFF));
+ } else {
+ stv0900_write_reg(i_params, sfr_max_reg, 0x7F);
+ stv0900_write_reg(i_params, sfr_max_reg + 1, 0xFF);
+ }
+}
+
+static void stv0900_set_min_symbol_rate(struct stv0900_internal *i_params,
+ u32 mclk, u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 sfr_min_reg;
+ u32 symb;
+
+ dmd_reg(sfr_min_reg, R0900_P1_SFRLOW1, R0900_P2_SFRLOW1);
+
+ srate = 95 * (srate / 100);
+ if (srate > 60000000) {
+ symb = srate << 4;
+ symb /= (mclk >> 12);
+
+ } else if (srate > 6000000) {
+ symb = srate << 6;
+ symb /= (mclk >> 10);
+
+ } else {
+ symb = srate << 9;
+ symb /= (mclk >> 7);
+ }
+
+ stv0900_write_reg(i_params, sfr_min_reg, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, sfr_min_reg + 1, (symb & 0xFF));
+}
+
+static s32 stv0900_get_timing_offst(struct stv0900_internal *i_params,
+ u32 srate,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 tmgreg,
+ timingoffset;
+
+ dmd_reg(tmgreg, R0900_P1_TMGREG2, R0900_P2_TMGREG2);
+
+ timingoffset = (stv0900_read_reg(i_params, tmgreg) << 16) +
+ (stv0900_read_reg(i_params, tmgreg + 1) << 8) +
+ (stv0900_read_reg(i_params, tmgreg + 2));
+
+ timingoffset = ge2comp(timingoffset, 24);
+
+
+ if (timingoffset == 0)
+ timingoffset = 1;
+
+ timingoffset = ((s32)srate * 10) / ((s32)0x1000000 / timingoffset);
+ timingoffset /= 320;
+
+ return timingoffset;
+}
+
+static void stv0900_set_dvbs2_rolloff(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 rolloff, man_fld, matstr_reg, rolloff_ctl_fld;
+
+ dmd_reg(man_fld, F0900_P1_MANUAL_ROLLOFF, F0900_P2_MANUAL_ROLLOFF);
+ dmd_reg(matstr_reg, R0900_P1_MATSTR1, R0900_P2_MATSTR1);
+ dmd_reg(rolloff_ctl_fld, F0900_P1_ROLLOFF_CONTROL,
+ F0900_P2_ROLLOFF_CONTROL);
+
+ if (i_params->chip_id == 0x10) {
+ stv0900_write_bits(i_params, man_fld, 1);
+ rolloff = stv0900_read_reg(i_params, matstr_reg) & 0x03;
+ stv0900_write_bits(i_params, rolloff_ctl_fld, rolloff);
+ } else
+ stv0900_write_bits(i_params, man_fld, 0);
+}
+
+static u32 stv0900_carrier_width(u32 srate, enum fe_stv0900_rolloff ro)
+{
+ u32 rolloff;
+
+ switch (ro) {
+ case STV0900_20:
+ rolloff = 20;
+ break;
+ case STV0900_25:
+ rolloff = 25;
+ break;
+ case STV0900_35:
+ default:
+ rolloff = 35;
+ break;
+ }
+
+ return srate + (srate * rolloff) / 100;
+}
+
+static int stv0900_check_timing_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ int timingLock = FALSE;
+ s32 i,
+ timingcpt = 0;
+ u8 carFreq,
+ tmgTHhigh,
+ tmgTHLow;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ carFreq = stv0900_read_reg(i_params, R0900_P1_CARFREQ);
+ tmgTHhigh = stv0900_read_reg(i_params, R0900_P1_TMGTHRISE);
+ tmgTHLow = stv0900_read_reg(i_params, R0900_P1_TMGTHFALL);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x80);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x40);
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x65);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ msleep(7);
+
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ msleep(1);
+ }
+
+ if (timingcpt >= 3)
+ timingLock = TRUE;
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ stv0900_write_reg(i_params, R0900_P1_RTC, 0x88);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x68);
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, carFreq);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, tmgTHhigh);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, tmgTHLow);
+ break;
+ case STV0900_DEMOD_2:
+ carFreq = stv0900_read_reg(i_params, R0900_P2_CARFREQ);
+ tmgTHhigh = stv0900_read_reg(i_params, R0900_P2_TMGTHRISE);
+ tmgTHLow = stv0900_read_reg(i_params, R0900_P2_TMGTHFALL);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x80);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x40);
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x65);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ msleep(5);
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ msleep(1);
+ }
+
+ if (timingcpt >= 3)
+ timingLock = TRUE;
+
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ stv0900_write_reg(i_params, R0900_P2_RTC, 0x88);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x68);
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, carFreq);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, tmgTHhigh);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, tmgTHLow);
+ break;
+ }
+
+ return timingLock;
+}
+
+static int stv0900_get_demod_cold_lock(struct dvb_frontend *fe,
+ s32 demod_timeout)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ int lock = FALSE;
+ s32 srate, search_range, locktimeout,
+ currier_step, nb_steps, current_step,
+ direction, tuner_freq, timeout;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ srate = i_params->dmd1_symbol_rate;
+ search_range = i_params->dmd1_srch_range;
+ break;
+
+ case STV0900_DEMOD_2:
+ srate = i_params->dmd2_symbol_rate;
+ search_range = i_params->dmd2_srch_range;
+ break;
+ }
+
+ if (srate >= 10000000)
+ locktimeout = demod_timeout / 3;
+ else
+ locktimeout = demod_timeout / 2;
+
+ lock = stv0900_get_demod_lock(i_params, demod, locktimeout);
+
+ if (lock == FALSE) {
+ if (srate >= 10000000) {
+ if (stv0900_check_timing_lock(i_params, demod) == TRUE) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1f);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ break;
+ }
+
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+ } else
+ lock = FALSE;
+ } else {
+ if (srate <= 4000000)
+ currier_step = 1000;
+ else if (srate <= 7000000)
+ currier_step = 2000;
+ else if (srate <= 10000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+ nb_steps = ((search_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * (nb_steps + 1));
+ if (nb_steps < 0)
+ nb_steps = 2;
+ else if (nb_steps > 12)
+ nb_steps = 12;
+
+ current_step = 1;
+ direction = 1;
+ timeout = (demod_timeout / 3);
+ if (timeout > 1000)
+ timeout = 1000;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (lock == FALSE) {
+ tuner_freq = i_params->tuner1_freq;
+ i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + i_params->dmd1_symbol_rate;
+
+ while ((current_step <= nb_steps) && (lock == FALSE)) {
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ if (i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS2) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, 0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ lock = stv0900_get_demod_lock(i_params, demod, timeout);
+ direction *= -1;
+ current_step++;
+ }
+ }
+ break;
+ case STV0900_DEMOD_2:
+ if (lock == FALSE) {
+ tuner_freq = i_params->tuner2_freq;
+ i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + srate;
+
+ while ((current_step <= nb_steps) && (lock == FALSE)) {
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ if (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS2) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, 0);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, 0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ lock = stv0900_get_demod_lock(i_params, demod, timeout);
+ direction *= -1;
+ current_step++;
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return lock;
+}
+
+static void stv0900_get_lock_timeout(s32 *demod_timeout, s32 *fec_timeout,
+ s32 srate,
+ enum fe_stv0900_search_algo algo)
+{
+ switch (algo) {
+ case STV0900_BLIND_SEARCH:
+ if (srate <= 1500000) {
+ (*demod_timeout) = 1500;
+ (*fec_timeout) = 400;
+ } else if (srate <= 5000000) {
+ (*demod_timeout) = 1000;
+ (*fec_timeout) = 300;
+ } else {
+ (*demod_timeout) = 700;
+ (*fec_timeout) = 100;
+ }
+
+ break;
+ case STV0900_COLD_START:
+ case STV0900_WARM_START:
+ default:
+ if (srate <= 1000000) {
+ (*demod_timeout) = 3000;
+ (*fec_timeout) = 1700;
+ } else if (srate <= 2000000) {
+ (*demod_timeout) = 2500;
+ (*fec_timeout) = 1100;
+ } else if (srate <= 5000000) {
+ (*demod_timeout) = 1000;
+ (*fec_timeout) = 550;
+ } else if (srate <= 10000000) {
+ (*demod_timeout) = 700;
+ (*fec_timeout) = 250;
+ } else if (srate <= 20000000) {
+ (*demod_timeout) = 400;
+ (*fec_timeout) = 130;
+ }
+
+ else {
+ (*demod_timeout) = 300;
+ (*fec_timeout) = 100;
+ }
+
+ break;
+
+ }
+
+ if (algo == STV0900_WARM_START)
+ (*demod_timeout) /= 2;
+}
+
+static void stv0900_set_viterbi_tracq(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ s32 vth_reg;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+ stv0900_write_reg(i_params, vth_reg++, 0xd0);
+ stv0900_write_reg(i_params, vth_reg++, 0x7d);
+ stv0900_write_reg(i_params, vth_reg++, 0x53);
+ stv0900_write_reg(i_params, vth_reg++, 0x2F);
+ stv0900_write_reg(i_params, vth_reg++, 0x24);
+ stv0900_write_reg(i_params, vth_reg++, 0x1F);
+}
+
+static void stv0900_set_viterbi_standard(struct stv0900_internal *i_params,
+ enum fe_stv0900_search_standard Standard,
+ enum fe_stv0900_fec PunctureRate,
+ enum fe_stv0900_demod_num demod)
+{
+
+ s32 fecmReg,
+ prvitReg;
+
+ dprintk(KERN_INFO "%s: ViterbiStandard = ", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ fecmReg = R0900_P1_FECM;
+ prvitReg = R0900_P1_PRVIT;
+ break;
+ case STV0900_DEMOD_2:
+ fecmReg = R0900_P2_FECM;
+ prvitReg = R0900_P2_PRVIT;
+ break;
+ }
+
+ switch (Standard) {
+ case STV0900_AUTO_SEARCH:
+ dprintk("Auto\n");
+ stv0900_write_reg(i_params, fecmReg, 0x10);
+ stv0900_write_reg(i_params, prvitReg, 0x3F);
+ break;
+ case STV0900_SEARCH_DVBS1:
+ dprintk("DVBS1\n");
+ stv0900_write_reg(i_params, fecmReg, 0x00);
+ switch (PunctureRate) {
+ case STV0900_FEC_UNKNOWN:
+ default:
+ stv0900_write_reg(i_params, prvitReg, 0x2F);
+ break;
+ case STV0900_FEC_1_2:
+ stv0900_write_reg(i_params, prvitReg, 0x01);
+ break;
+ case STV0900_FEC_2_3:
+ stv0900_write_reg(i_params, prvitReg, 0x02);
+ break;
+ case STV0900_FEC_3_4:
+ stv0900_write_reg(i_params, prvitReg, 0x04);
+ break;
+ case STV0900_FEC_5_6:
+ stv0900_write_reg(i_params, prvitReg, 0x08);
+ break;
+ case STV0900_FEC_7_8:
+ stv0900_write_reg(i_params, prvitReg, 0x20);
+ break;
+ }
+
+ break;
+ case STV0900_SEARCH_DSS:
+ dprintk("DSS\n");
+ stv0900_write_reg(i_params, fecmReg, 0x80);
+ switch (PunctureRate) {
+ case STV0900_FEC_UNKNOWN:
+ default:
+ stv0900_write_reg(i_params, prvitReg, 0x13);
+ break;
+ case STV0900_FEC_1_2:
+ stv0900_write_reg(i_params, prvitReg, 0x01);
+ break;
+ case STV0900_FEC_2_3:
+ stv0900_write_reg(i_params, prvitReg, 0x02);
+ break;
+ case STV0900_FEC_6_7:
+ stv0900_write_reg(i_params, prvitReg, 0x10);
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void stv0900_track_optimization(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 srate, pilots, aclc, freq1, freq0,
+ i = 0, timed, timef, blindTunSw = 0;
+
+ enum fe_stv0900_rolloff rolloff;
+ enum fe_stv0900_modcode foundModcod;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_rslts.standard) {
+ case STV0900_DVBS1_STANDARD:
+ if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DSS_STANDARD:
+ if (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P1_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DVBS2_STANDARD:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0);
+ if (i_params->dmd1_rslts.frame_length == STV0900_LONG_FRAME) {
+ foundModcod = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
+ pilots = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
+ aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
+ if (foundModcod <= STV0900_QPSK_910)
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
+ else if (foundModcod <= STV0900_8PSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
+ }
+
+ if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
+ if (foundModcod <= STV0900_16APSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
+ } else if (foundModcod <= STV0900_32APSK_910) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
+ }
+ }
+
+ } else {
+ aclc = stv0900_get_optim_short_carr_loop(srate, i_params->dmd1_rslts.modulation, i_params->chip_id);
+ if (i_params->dmd1_rslts.modulation == STV0900_QPSK)
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, aclc);
+
+ else if (i_params->dmd1_rslts.modulation == STV0900_8PSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S28, aclc);
+ } else if (i_params->dmd1_rslts.modulation == STV0900_16APSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S216A, aclc);
+ } else if (i_params->dmd1_rslts.modulation == STV0900_32APSK) {
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P1_ACLC2S232A, aclc);
+ }
+
+ }
+
+ if (i_params->chip_id <= 0x11) {
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
+ break;
+ case STV0900_UNKNOWN_STANDARD:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ break;
+ }
+
+ freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
+ rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x00);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
+ blindTunSw = 1;
+ }
+
+ if (i_params->chip_id >= 0x20) {
+ if ((i_params->dmd1_srch_standard == STV0900_SEARCH_DVBS1) || (i_params->dmd1_srch_standard == STV0900_SEARCH_DSS) || (i_params->dmd1_srch_standard == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0a);
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x0);
+ }
+ }
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x08);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0x0A);
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd1_symbol_rate < 10000000)) {
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ i_params->tuner1_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
+ if (i_params->dmd1_srch_algo != STV0900_WARM_START)
+ stv0900_set_bandwidth(fe, i_params->tuner1_bw);
+ }
+
+ if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000))
+ msleep(50);
+ else
+ msleep(5);
+
+ stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
+
+ if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ i = 0;
+ while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ i++;
+ }
+ }
+
+ }
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+
+ if ((i_params->dmd1_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd1_rslts.standard == STV0900_DSS_STANDARD))
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_rslts.standard) {
+ case STV0900_DVBS1_STANDARD:
+
+ if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DSS_STANDARD:
+ if (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH) {
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ }
+
+ stv0900_write_bits(i_params, F0900_P2_ROLLOFF_CONTROL, i_params->rolloff);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ break;
+ case STV0900_DVBS2_STANDARD:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0);
+ if (i_params->dmd2_rslts.frame_length == STV0900_LONG_FRAME) {
+ foundModcod = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
+ pilots = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
+ aclc = stv0900_get_optim_carr_loop(srate, foundModcod, pilots, i_params->chip_id);
+ if (foundModcod <= STV0900_QPSK_910)
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
+ else if (foundModcod <= STV0900_8PSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
+ }
+
+ if ((i_params->demod_mode == STV0900_SINGLE) && (foundModcod > STV0900_8PSK_910)) {
+ if (foundModcod <= STV0900_16APSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
+ } else if (foundModcod <= STV0900_32APSK_910) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
+ }
+
+ }
+
+ } else {
+ aclc = stv0900_get_optim_short_carr_loop(srate,
+ i_params->dmd2_rslts.modulation,
+ i_params->chip_id);
+
+ if (i_params->dmd2_rslts.modulation == STV0900_QPSK)
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, aclc);
+
+ else if (i_params->dmd2_rslts.modulation == STV0900_8PSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S28, aclc);
+ } else if (i_params->dmd2_rslts.modulation == STV0900_16APSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S216A, aclc);
+ } else if (i_params->dmd2_rslts.modulation == STV0900_32APSK) {
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S2Q, 0x2a);
+ stv0900_write_reg(i_params, R0900_P2_ACLC2S232A, aclc);
+ }
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
+
+ break;
+ case STV0900_UNKNOWN_STANDARD:
+ default:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ break;
+ }
+
+ freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
+ rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x00);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, srate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, srate, demod);
+ blindTunSw = 1;
+ }
+
+ if (i_params->chip_id >= 0x20) {
+ if ((i_params->dmd2_srch_stndrd == STV0900_SEARCH_DVBS1) || (i_params->dmd2_srch_stndrd == STV0900_SEARCH_DSS) || (i_params->dmd2_srch_stndrd == STV0900_AUTO_SEARCH)) {
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0a);
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x0);
+ }
+ }
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x08);
+
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0x0a);
+
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1) || (i_params->dmd2_symbol_rate < 10000000)) {
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ i_params->tuner2_bw = stv0900_carrier_width(srate, i_params->rolloff) + 10000000;
+
+ if ((i_params->chip_id >= 0x20) || (blindTunSw == 1)) {
+ if (i_params->dmd2_srch_algo != STV0900_WARM_START)
+ stv0900_set_bandwidth(fe, i_params->tuner2_bw);
+ }
+
+ if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000))
+ msleep(50);
+ else
+ msleep(5);
+
+ stv0900_get_lock_timeout(&timed, &timef, srate, STV0900_WARM_START);
+ if (stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ i = 0;
+ while ((stv0900_get_demod_lock(i_params, demod, timed / 2) == FALSE) && (i <= 2)) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+ i++;
+ }
+ }
+ }
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
+
+ if ((i_params->dmd2_rslts.standard == STV0900_DVBS1_STANDARD) || (i_params->dmd2_rslts.standard == STV0900_DSS_STANDARD))
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+ }
+}
+
+static int stv0900_get_fec_lock(struct stv0900_internal *i_params, enum fe_stv0900_demod_num demod, s32 time_out)
+{
+ s32 timer = 0, lock = 0, header_field, pktdelin_field, lock_vit_field;
+
+ enum fe_stv0900_search_state dmd_state;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(header_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(pktdelin_field, F0900_P1_PKTDELIN_LOCK, F0900_P2_PKTDELIN_LOCK);
+ dmd_reg(lock_vit_field, F0900_P1_LOCKEDVIT, F0900_P2_LOCKEDVIT);
+
+ dmd_state = stv0900_get_bits(i_params, header_field);
+
+ while ((timer < time_out) && (lock == 0)) {
+ switch (dmd_state) {
+ case STV0900_SEARCH:
+ case STV0900_PLH_DETECTED:
+ default:
+ lock = 0;
+ break;
+ case STV0900_DVBS2_FOUND:
+ lock = stv0900_get_bits(i_params, pktdelin_field);
+ break;
+ case STV0900_DVBS_FOUND:
+ lock = stv0900_get_bits(i_params, lock_vit_field);
+ break;
+ }
+
+ if (lock == 0) {
+ msleep(10);
+ timer += 10;
+ }
+ }
+
+ if (lock)
+ dprintk("DEMOD FEC LOCK OK\n");
+ else
+ dprintk("DEMOD FEC LOCK FAIL\n");
+
+ return lock;
+}
+
+static int stv0900_wait_for_lock(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod,
+ s32 dmd_timeout, s32 fec_timeout)
+{
+
+ s32 timer = 0, lock = 0, str_merg_rst_fld, str_merg_lock_fld;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(str_merg_rst_fld, F0900_P1_RST_HWARE, F0900_P2_RST_HWARE);
+ dmd_reg(str_merg_lock_fld, F0900_P1_TSFIFO_LINEOK, F0900_P2_TSFIFO_LINEOK);
+
+ lock = stv0900_get_demod_lock(i_params, demod, dmd_timeout);
+
+ if (lock)
+ lock = lock && stv0900_get_fec_lock(i_params, demod, fec_timeout);
+
+ if (lock) {
+ lock = 0;
+
+ dprintk(KERN_INFO "%s: Timer = %d, time_out = %d\n", __func__, timer, fec_timeout);
+
+ while ((timer < fec_timeout) && (lock == 0)) {
+ lock = stv0900_get_bits(i_params, str_merg_lock_fld);
+ msleep(1);
+ timer++;
+ }
+ }
+
+ if (lock)
+ dprintk(KERN_INFO "%s: DEMOD LOCK OK\n", __func__);
+ else
+ dprintk(KERN_INFO "%s: DEMOD LOCK FAIL\n", __func__);
+
+ if (lock)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+enum fe_stv0900_tracking_standard stv0900_get_standard(struct dvb_frontend *fe,
+ enum fe_stv0900_demod_num demod)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_tracking_standard fnd_standard;
+ s32 state_field,
+ dss_dvb_field;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(state_field, F0900_P1_HEADER_MODE, F0900_P2_HEADER_MODE);
+ dmd_reg(dss_dvb_field, F0900_P1_DSS_DVB, F0900_P2_DSS_DVB);
+
+ if (stv0900_get_bits(i_params, state_field) == 2)
+ fnd_standard = STV0900_DVBS2_STANDARD;
+
+ else if (stv0900_get_bits(i_params, state_field) == 3) {
+ if (stv0900_get_bits(i_params, dss_dvb_field) == 1)
+ fnd_standard = STV0900_DSS_STANDARD;
+ else
+ fnd_standard = STV0900_DVBS1_STANDARD;
+ } else
+ fnd_standard = STV0900_UNKNOWN_STANDARD;
+
+ return fnd_standard;
+}
+
+static s32 stv0900_get_carr_freq(struct stv0900_internal *i_params, u32 mclk,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 cfr_field2, cfr_field1, cfr_field0,
+ derot, rem1, rem2, intval1, intval2;
+
+ dmd_reg(cfr_field2, F0900_P1_CAR_FREQ2, F0900_P2_CAR_FREQ2);
+ dmd_reg(cfr_field1, F0900_P1_CAR_FREQ1, F0900_P2_CAR_FREQ1);
+ dmd_reg(cfr_field0, F0900_P1_CAR_FREQ0, F0900_P2_CAR_FREQ0);
+
+ derot = (stv0900_get_bits(i_params, cfr_field2) << 16) +
+ (stv0900_get_bits(i_params, cfr_field1) << 8) +
+ (stv0900_get_bits(i_params, cfr_field0));
+
+ derot = ge2comp(derot, 24);
+ intval1 = mclk >> 12;
+ intval2 = derot >> 12;
+ rem1 = mclk % 0x1000;
+ rem2 = derot % 0x1000;
+ derot = (intval1 * intval2) +
+ ((intval1 * rem2) >> 12) +
+ ((intval2 * rem1) >> 12);
+
+ return derot;
+}
+
+static u32 stv0900_get_tuner_freq(struct dvb_frontend *fe)
+{
+ struct dvb_frontend_ops *frontend_ops = NULL;
+ struct dvb_tuner_ops *tuner_ops = NULL;
+ u32 frequency = 0;
+
+ if (&fe->ops)
+ frontend_ops = &fe->ops;
+
+ if (&frontend_ops->tuner_ops)
+ tuner_ops = &frontend_ops->tuner_ops;
+
+ if (tuner_ops->get_frequency) {
+ if ((tuner_ops->get_frequency(fe, &frequency)) < 0)
+ dprintk("%s: Invalid parameter\n", __func__);
+ else
+ dprintk("%s: Frequency=%d\n", __func__, frequency);
+
+ }
+
+ return frequency;
+}
+
+static enum fe_stv0900_fec stv0900_get_vit_fec(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 rate_fld, vit_curpun_fld;
+ enum fe_stv0900_fec prate;
+
+ dmd_reg(vit_curpun_fld, F0900_P1_VIT_CURPUN, F0900_P2_VIT_CURPUN);
+ rate_fld = stv0900_get_bits(i_params, vit_curpun_fld);
+
+ switch (rate_fld) {
+ case 13:
+ prate = STV0900_FEC_1_2;
+ break;
+ case 18:
+ prate = STV0900_FEC_2_3;
+ break;
+ case 21:
+ prate = STV0900_FEC_3_4;
+ break;
+ case 24:
+ prate = STV0900_FEC_5_6;
+ break;
+ case 25:
+ prate = STV0900_FEC_6_7;
+ break;
+ case 26:
+ prate = STV0900_FEC_7_8;
+ break;
+ default:
+ prate = STV0900_FEC_UNKNOWN;
+ break;
+ }
+
+ return prate;
+}
+
+static enum fe_stv0900_signal_type stv0900_get_signal_params(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ enum fe_stv0900_signal_type range = STV0900_OUTOFRANGE;
+ s32 offsetFreq,
+ srate_offset,
+ i = 0;
+
+ u8 timing;
+
+ msleep(5);
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
+ i = 0;
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x5c);
+
+ while ((i <= 50) && (timing != 0) && (timing != 0xFF)) {
+ timing = stv0900_read_reg(i_params, R0900_P1_TMGREG2);
+ msleep(5);
+ i += 5;
+ }
+ }
+
+ i_params->dmd1_rslts.standard = stv0900_get_standard(fe, demod);
+ i_params->dmd1_rslts.frequency = stv0900_get_tuner_freq(fe);
+ offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
+ i_params->dmd1_rslts.frequency += offsetFreq;
+ i_params->dmd1_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd1_rslts.symbol_rate, demod);
+ i_params->dmd1_rslts.symbol_rate += srate_offset;
+ i_params->dmd1_rslts.fec = stv0900_get_vit_fec(i_params, demod);
+ i_params->dmd1_rslts.modcode = stv0900_get_bits(i_params, F0900_P1_DEMOD_MODCOD);
+ i_params->dmd1_rslts.pilot = stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE) & 0x01;
+ i_params->dmd1_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P1_DEMOD_TYPE)) >> 1;
+ i_params->dmd1_rslts.rolloff = stv0900_get_bits(i_params, F0900_P1_ROLLOFF_STATUS);
+ switch (i_params->dmd1_rslts.standard) {
+ case STV0900_DVBS2_STANDARD:
+ i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_SPECINV_DEMOD);
+ if (i_params->dmd1_rslts.modcode <= STV0900_QPSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_QPSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_8PSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_8PSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_16APSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_16APSK;
+ else if (i_params->dmd1_rslts.modcode <= STV0900_32APSK_910)
+ i_params->dmd1_rslts.modulation = STV0900_32APSK;
+ else
+ i_params->dmd1_rslts.modulation = STV0900_UNKNOWN;
+ break;
+ case STV0900_DVBS1_STANDARD:
+ case STV0900_DSS_STANDARD:
+ i_params->dmd1_rslts.spectrum = stv0900_get_bits(i_params, F0900_P1_IQINV);
+ i_params->dmd1_rslts.modulation = STV0900_QPSK;
+ break;
+ default:
+ break;
+ }
+
+ if ((i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd1_symbol_rate < 10000000)) {
+ offsetFreq = i_params->dmd1_rslts.frequency - i_params->tuner1_freq;
+ i_params->tuner1_freq = stv0900_get_tuner_freq(fe);
+ if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd1_rslts.symbol_rate, i_params->dmd1_rslts.rolloff) / 2000))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+
+ } else {
+ if (ABS(offsetFreq) <= ((i_params->dmd1_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
+ i = 0;
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x5c);
+
+ while ((i <= 50) && (timing != 0) && (timing != 0xff)) {
+ timing = stv0900_read_reg(i_params, R0900_P2_TMGREG2);
+ msleep(5);
+ i += 5;
+ }
+ }
+
+ i_params->dmd2_rslts.standard = stv0900_get_standard(fe, demod);
+ i_params->dmd2_rslts.frequency = stv0900_get_tuner_freq(fe);
+ offsetFreq = stv0900_get_carr_freq(i_params, i_params->mclk, demod) / 1000;
+ i_params->dmd2_rslts.frequency += offsetFreq;
+ i_params->dmd2_rslts.symbol_rate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate_offset = stv0900_get_timing_offst(i_params, i_params->dmd2_rslts.symbol_rate, demod);
+ i_params->dmd2_rslts.symbol_rate += srate_offset;
+ i_params->dmd2_rslts.fec = stv0900_get_vit_fec(i_params, demod);
+ i_params->dmd2_rslts.modcode = stv0900_get_bits(i_params, F0900_P2_DEMOD_MODCOD);
+ i_params->dmd2_rslts.pilot = stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE) & 0x01;
+ i_params->dmd2_rslts.frame_length = ((u32)stv0900_get_bits(i_params, F0900_P2_DEMOD_TYPE)) >> 1;
+ i_params->dmd2_rslts.rolloff = stv0900_get_bits(i_params, F0900_P2_ROLLOFF_STATUS);
+ switch (i_params->dmd2_rslts.standard) {
+ case STV0900_DVBS2_STANDARD:
+ i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_SPECINV_DEMOD);
+ if (i_params->dmd2_rslts.modcode <= STV0900_QPSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_QPSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_8PSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_8PSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_16APSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_16APSK;
+ else if (i_params->dmd2_rslts.modcode <= STV0900_32APSK_910)
+ i_params->dmd2_rslts.modulation = STV0900_32APSK;
+ else
+ i_params->dmd2_rslts.modulation = STV0900_UNKNOWN;
+ break;
+ case STV0900_DVBS1_STANDARD:
+ case STV0900_DSS_STANDARD:
+ i_params->dmd2_rslts.spectrum = stv0900_get_bits(i_params, F0900_P2_IQINV);
+ i_params->dmd2_rslts.modulation = STV0900_QPSK;
+ break;
+ default:
+ break;
+ }
+
+ if ((i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) || (i_params->dmd2_symbol_rate < 10000000)) {
+ offsetFreq = i_params->dmd2_rslts.frequency - i_params->tuner2_freq;
+ i_params->tuner2_freq = stv0900_get_tuner_freq(fe);
+
+ if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ if (ABS(offsetFreq) <= (stv0900_carrier_width(i_params->dmd2_rslts.symbol_rate, i_params->dmd2_rslts.rolloff) / 2000))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ } else {
+ if (ABS(offsetFreq) <= ((i_params->dmd2_srch_range / 2000) + 500))
+ range = STV0900_RANGEOK;
+ else
+ range = STV0900_OUTOFRANGE;
+ }
+
+ break;
+ }
+
+ return range;
+}
+
+static enum fe_stv0900_signal_type stv0900_dvbs1_acq_workaround(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 srate, demod_timeout,
+ fec_timeout, freq1, freq0;
+ enum fe_stv0900_signal_type signal_type = STV0900_NODATA;;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = FALSE;
+ if (stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) {
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH)
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
+ freq1 = stv0900_read_reg(i_params, R0900_P1_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P1_CFR1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd1_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ } else {
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1c);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x18);
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd1_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ }
+
+ }
+
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = FALSE;
+ if (stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) {
+ srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ srate += stv0900_get_timing_offst(i_params, srate, demod);
+
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH)
+ stv0900_set_symbol_rate(i_params, i_params->mclk, srate, demod);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, srate, STV0900_WARM_START);
+ freq1 = stv0900_read_reg(i_params, R0900_P2_CFR2);
+ freq0 = stv0900_read_reg(i_params, R0900_P2_CFR1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_SWAPPED);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd2_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ } else {
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, STV0900_IQ_FORCE_NORMAL);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1c);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, freq1);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, freq0);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x18);
+
+ if (stv0900_wait_for_lock(i_params, demod, demod_timeout, fec_timeout) == TRUE) {
+ i_params->dmd2_rslts.locked = TRUE;
+ signal_type = stv0900_get_signal_params(fe);
+ stv0900_track_optimization(fe);
+ }
+
+ }
+
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ }
+
+ return signal_type;
+}
+
+static u16 stv0900_blind_check_agc2_min_level(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ u32 minagc2level = 0xffff,
+ agc2level,
+ init_freq, freq_step;
+
+ s32 i, j, nb_steps, direction;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ nb_steps = -1 + (i_params->dmd1_srch_range / 1000000);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ direction = 1;
+
+ freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+
+ init_freq = 0;
+
+ for (i = 0; i < nb_steps; i++) {
+ if (direction > 0)
+ init_freq = init_freq + (freq_step * i);
+ else
+ init_freq = init_freq - (freq_step * i);
+
+ direction *= -1;
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (init_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, init_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x58);
+ msleep(10);
+ agc2level = 0;
+
+ for (j = 0; j < 10; j++)
+ agc2level += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ agc2level /= 10;
+
+ if (agc2level < minagc2level)
+ minagc2level = agc2level;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ nb_steps = -1 + (i_params->dmd2_srch_range / 1000000);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ direction = 1;
+ freq_step = (1000000 << 8) / (i_params->mclk >> 8);
+ init_freq = 0;
+ for (i = 0; i < nb_steps; i++) {
+ if (direction > 0)
+ init_freq = init_freq + (freq_step * i);
+ else
+ init_freq = init_freq - (freq_step * i);
+
+ direction *= -1;
+
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (init_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, init_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x58);
+
+ msleep(10);
+ agc2level = 0;
+ for (j = 0; j < 10; j++)
+ agc2level += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+
+ agc2level /= 10;
+
+ if (agc2level < minagc2level)
+ minagc2level = agc2level;
+ }
+ break;
+ }
+
+ return (u16)minagc2level;
+}
+
+static u32 stv0900_search_srate_coarse(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ int timingLock = FALSE;
+ s32 i, timingcpt = 0,
+ direction = 1,
+ nb_steps,
+ current_step = 0,
+ tuner_freq;
+
+ u32 coarse_srate = 0, agc2_integr = 0, currier_step = 1200;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0x12);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0xf0);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0xe0);
+ stv0900_write_bits(i_params, F0900_P1_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x0);
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x50);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x6a);
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x95);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+ stv0900_write_reg(i_params, R0900_P1_SFRSTEP, 0x73);
+ }
+
+ if (i_params->dmd1_symbol_rate <= 2000000)
+ currier_step = 1000;
+ else if (i_params->dmd1_symbol_rate <= 5000000)
+ currier_step = 2000;
+ else if (i_params->dmd1_symbol_rate <= 12000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+ nb_steps = -1 + ((i_params->dmd1_srch_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+
+ else if (nb_steps > 10) {
+ nb_steps = 11;
+ currier_step = (i_params->dmd1_srch_range / 1000) / 10;
+ }
+
+ current_step = 0;
+
+ direction = 1;
+ tuner_freq = i_params->tuner1_freq;
+
+ while ((timingLock == FALSE) && (current_step < nb_steps)) {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5F);
+ stv0900_write_bits(i_params, F0900_P1_I2C_DEMOD_MODE, 0x0);
+
+ msleep(50);
+
+ for (i = 0; i < 10; i++) {
+ if (stv0900_get_bits(i_params, F0900_P1_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+
+ agc2_integr += (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8) | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ }
+
+ agc2_integr /= 10;
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ current_step++;
+ direction *= -1;
+
+ dprintk("lock: I2C_DEMOD_MODE_FIELD =0. Search started. tuner freq=%d agc2=0x%x srate_coarse=%d tmg_cpt=%d\n", tuner_freq, agc2_integr, coarse_srate, timingcpt);
+
+ if ((timingcpt >= 5) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000)) {
+ timingLock = TRUE;
+ }
+
+ else if (current_step < nb_steps) {
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner1_bw);
+ }
+ }
+
+ if (timingLock == FALSE)
+ coarse_srate = 0;
+ else
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ break;
+ case STV0900_DEMOD_2:
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0x12);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0xf0);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0xe0);
+ stv0900_write_bits(i_params, F0900_P2_SCAN_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 1);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, 0x83);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, 0xc0);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, 0xa0);
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x0);
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x50);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x6a);
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x95);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+ stv0900_write_reg(i_params, R0900_P2_SFRSTEP, 0x73);
+ }
+
+ if (i_params->dmd2_symbol_rate <= 2000000)
+ currier_step = 1000;
+ else if (i_params->dmd2_symbol_rate <= 5000000)
+ currier_step = 2000;
+ else if (i_params->dmd2_symbol_rate <= 12000000)
+ currier_step = 3000;
+ else
+ currier_step = 5000;
+
+
+ nb_steps = -1 + ((i_params->dmd2_srch_range / 1000) / currier_step);
+ nb_steps /= 2;
+ nb_steps = (2 * nb_steps) + 1;
+
+ if (nb_steps < 0)
+ nb_steps = 1;
+ else if (nb_steps > 10) {
+ nb_steps = 11;
+ currier_step = (i_params->dmd2_srch_range / 1000) / 10;
+ }
+
+ current_step = 0;
+ direction = 1;
+ tuner_freq = i_params->tuner2_freq;
+
+ while ((timingLock == FALSE) && (current_step < nb_steps)) {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5F);
+ stv0900_write_bits(i_params, F0900_P2_I2C_DEMOD_MODE, 0x0);
+
+ msleep(50);
+ timingcpt = 0;
+
+ for (i = 0; i < 20; i++) {
+ if (stv0900_get_bits(i_params, F0900_P2_TMGLOCK_QUALITY) >= 2)
+ timingcpt++;
+ agc2_integr += (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+ }
+
+ agc2_integr /= 20;
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ if ((timingcpt >= 10) && (agc2_integr < 0x1F00) && (coarse_srate < 55000000) && (coarse_srate > 850000))
+ timingLock = TRUE;
+ else {
+ current_step++;
+ direction *= -1;
+
+ if (direction > 0)
+ tuner_freq += (current_step * currier_step);
+ else
+ tuner_freq -= (current_step * currier_step);
+
+ stv0900_set_tuner(fe, tuner_freq, i_params->tuner2_bw);
+ }
+ }
+
+ if (timingLock == FALSE)
+ coarse_srate = 0;
+ else
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+ break;
+ }
+
+ return coarse_srate;
+}
+
+static u32 stv0900_search_srate_fine(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ u32 coarse_srate,
+ coarse_freq,
+ symb;
+
+ coarse_srate = stv0900_get_symbol_rate(i_params, i_params->mclk, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ coarse_freq = (stv0900_read_reg(i_params, R0900_P1_CFR2) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_CFR1);
+ symb = 13 * (coarse_srate / 10);
+
+ if (symb < i_params->dmd1_symbol_rate)
+ coarse_srate = 0;
+ else {
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGTHFALL, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
+ stv0900_write_bits(i_params, F0900_P1_CFR_AUTOSCAN, 0);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0x49);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CARFREQ, 0xed);
+
+ if (coarse_srate > 3000000) {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 13);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
+ } else {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 14);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P1_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P1_SFRINIT0, (symb & 0xFF));
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT1, (coarse_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_CFRINIT0, coarse_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x15);
+ }
+ break;
+ case STV0900_DEMOD_2:
+ coarse_freq = (stv0900_read_reg(i_params, R0900_P2_CFR2) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_CFR1);
+
+ symb = 13 * (coarse_srate / 10);
+
+ if (symb < i_params->dmd2_symbol_rate)
+ coarse_srate = 0;
+ else {
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x1F);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHRISE, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGTHFALL, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
+ stv0900_write_bits(i_params, F0900_P2_CFR_AUTOSCAN, 0);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0x49);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CARFREQ, 0xed);
+
+ if (coarse_srate > 3000000) {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 13);
+ symb = (symb / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 1000) * 65536;
+ symb /= (i_params->mclk / 1000);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
+ } else {
+ symb = 13 * (coarse_srate / 10);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRUP0, (symb & 0xFF));
+
+ symb = 10 * (coarse_srate / 14);
+ symb = (symb / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW1, (symb >> 8) & 0x7F);
+ stv0900_write_reg(i_params, R0900_P2_SFRLOW0, (symb & 0xFF));
+
+ symb = (coarse_srate / 100) * 65536;
+ symb /= (i_params->mclk / 100);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT1, (symb >> 8) & 0xFF);
+ stv0900_write_reg(i_params, R0900_P2_SFRINIT0, (symb & 0xFF));
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT1, (coarse_freq >> 8) & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_CFRINIT0, coarse_freq & 0xff);
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x15);
+ }
+
+ break;
+ }
+
+ return coarse_srate;
+}
+
+static int stv0900_blind_search_algo(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+ u8 k_ref_tmg, k_ref_tmg_max, k_ref_tmg_min;
+ u32 coarse_srate;
+ int lock = FALSE, coarse_fail = FALSE;
+ s32 demod_timeout = 500, fec_timeout = 50, kref_tmg_reg, fail_cpt, i, agc2_overflow;
+ u16 agc2_integr;
+ u8 dstatus2;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ if (i_params->chip_id < 0x20) {
+ k_ref_tmg_max = 233;
+ k_ref_tmg_min = 143;
+ } else {
+ k_ref_tmg_max = 120;
+ k_ref_tmg_min = 30;
+ }
+
+ agc2_integr = stv0900_blind_check_agc2_min_level(i_params, demod);
+
+ if (agc2_integr > STV0900_BLIND_SEARCH_AGC2_TH) {
+ lock = FALSE;
+
+ } else {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P1_CORRELEXP, 0xAA);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CARHDR, 0x55);
+
+ stv0900_write_reg(i_params, R0900_P1_CARCFG, 0xC4);
+ stv0900_write_reg(i_params, R0900_P1_RTCS2, 0x44);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_FFECFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P1_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P1_VAVSRVIT, 0x0);
+ }
+
+ kref_tmg_reg = R0900_P1_KREFTMG;
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->chip_id == 0x10)
+ stv0900_write_reg(i_params, R0900_P2_CORRELEXP, 0xAA);
+
+ if (i_params->chip_id < 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CARHDR, 0x55);
+
+ stv0900_write_reg(i_params, R0900_P2_CARCFG, 0xC4);
+ stv0900_write_reg(i_params, R0900_P2_RTCS2, 0x44);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_EQUALCFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_FFECFG, 0x41);
+ stv0900_write_reg(i_params, R0900_P2_VITSCALE, 0x82);
+ stv0900_write_reg(i_params, R0900_P2_VAVSRVIT, 0x0);
+ }
+
+ kref_tmg_reg = R0900_P2_KREFTMG;
+ break;
+ }
+
+ k_ref_tmg = k_ref_tmg_max;
+
+ do {
+ stv0900_write_reg(i_params, kref_tmg_reg, k_ref_tmg);
+ if (stv0900_search_srate_coarse(fe) != 0) {
+ coarse_srate = stv0900_search_srate_fine(fe);
+
+ if (coarse_srate != 0) {
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, coarse_srate, STV0900_BLIND_SEARCH);
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+ } else
+ lock = FALSE;
+ } else {
+ fail_cpt = 0;
+ agc2_overflow = 0;
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ for (i = 0; i < 10; i++) {
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P1_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P1_AGC2I0);
+
+ if (agc2_integr >= 0xff00)
+ agc2_overflow++;
+
+ dstatus2 = stv0900_read_reg(i_params, R0900_P1_DSTATUS2);
+
+ if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
+ fail_cpt++;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ for (i = 0; i < 10; i++) {
+ agc2_integr = (stv0900_read_reg(i_params, R0900_P2_AGC2I1) << 8)
+ | stv0900_read_reg(i_params, R0900_P2_AGC2I0);
+
+ if (agc2_integr >= 0xff00)
+ agc2_overflow++;
+
+ dstatus2 = stv0900_read_reg(i_params, R0900_P2_DSTATUS2);
+
+ if (((dstatus2 & 0x1) == 0x1) && ((dstatus2 >> 7) == 1))
+ fail_cpt++;
+ }
+ break;
+ }
+
+ if ((fail_cpt > 7) || (agc2_overflow > 7))
+ coarse_fail = TRUE;
+
+ lock = FALSE;
+ }
+ k_ref_tmg -= 30;
+ } while ((k_ref_tmg >= k_ref_tmg_min) && (lock == FALSE) && (coarse_fail == FALSE));
+ }
+
+ return lock;
+}
+
+static void stv0900_set_viterbi_acq(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+ s32 vth_reg;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ dmd_reg(vth_reg, R0900_P1_VTH12, R0900_P2_VTH12);
+
+ stv0900_write_reg(i_params, vth_reg++, 0x96);
+ stv0900_write_reg(i_params, vth_reg++, 0x64);
+ stv0900_write_reg(i_params, vth_reg++, 0x36);
+ stv0900_write_reg(i_params, vth_reg++, 0x23);
+ stv0900_write_reg(i_params, vth_reg++, 0x1E);
+ stv0900_write_reg(i_params, vth_reg++, 0x19);
+}
+
+static void stv0900_set_search_standard(struct stv0900_internal *i_params,
+ enum fe_stv0900_demod_num demod)
+{
+
+ int sstndrd;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ sstndrd = i_params->dmd1_srch_standard;
+ if (demod == 1)
+ sstndrd = i_params->dmd2_srch_stndrd;
+
+ switch (sstndrd) {
+ case STV0900_SEARCH_DVBS1:
+ dprintk("Search Standard = DVBS1\n");
+ break;
+ case STV0900_SEARCH_DSS:
+ dprintk("Search Standard = DSS\n");
+ case STV0900_SEARCH_DVBS2:
+ break;
+ dprintk("Search Standard = DVBS2\n");
+ case STV0900_AUTO_SEARCH:
+ default:
+ dprintk("Search Standard = AUTO\n");
+ break;
+ }
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ switch (i_params->dmd1_srch_standard) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x22);
+
+ stv0900_set_viterbi_acq(i_params, demod);
+ stv0900_set_viterbi_standard(i_params,
+ i_params->dmd1_srch_standard,
+ i_params->dmd1_fec, demod);
+
+ break;
+ case STV0900_SEARCH_DVBS2:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 1);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE) {
+ if (i_params->chip_id <= 0x11)
+ stv0900_stop_all_s2_modcod(i_params, demod);
+ else
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ } else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P1_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P1_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT1, 0);
+ stv0900_write_reg(i_params, R0900_P1_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P1_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P1_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE) {
+ if (i_params->chip_id <= 0x11)
+ stv0900_stop_all_s2_modcod(i_params, demod);
+ else
+ stv0900_activate_s2_modcode(i_params, demod);
+
+ } else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ if (i_params->dmd1_symbol_rate >= 2000000)
+ stv0900_set_viterbi_acq(i_params, demod);
+ else
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ stv0900_set_viterbi_standard(i_params, i_params->dmd1_srch_standard, i_params->dmd1_fec, demod);
+
+ break;
+ }
+ break;
+ case STV0900_DEMOD_2:
+ switch (i_params->dmd2_srch_stndrd) {
+ case STV0900_SEARCH_DVBS1:
+ case STV0900_SEARCH_DSS:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x22);
+ stv0900_set_viterbi_acq(i_params, demod);
+ stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+ break;
+ case STV0900_SEARCH_DVBS2:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 1);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+ else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ stv0900_set_viterbi_tracq(i_params, demod);
+ break;
+ case STV0900_AUTO_SEARCH:
+ default:
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 0);
+ stv0900_write_bits(i_params, F0900_P2_DVBS1_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_P2_DVBS2_ENABLE, 1);
+ stv0900_write_bits(i_params, F0900_STOP_CLKVIT2, 0);
+ stv0900_write_reg(i_params, R0900_P2_ACLC, 0x1a);
+ stv0900_write_reg(i_params, R0900_P2_BCLC, 0x09);
+ stv0900_write_reg(i_params, R0900_P2_CAR2CFG, 0x26);
+ if (i_params->demod_mode != STV0900_SINGLE)
+ stv0900_activate_s2_modcode(i_params, demod);
+ else
+ stv0900_activate_s2_modcode_single(i_params, demod);
+
+ if (i_params->dmd2_symbol_rate >= 2000000)
+ stv0900_set_viterbi_acq(i_params, demod);
+ else
+ stv0900_set_viterbi_tracq(i_params, demod);
+
+ stv0900_set_viterbi_standard(i_params, i_params->dmd2_srch_stndrd, i_params->dmd2_fec, demod);
+
+ break;
+ }
+
+ break;
+ }
+}
+
+enum fe_stv0900_signal_type stv0900_algo(struct dvb_frontend *fe)
+{
+ struct stv0900_state *state = fe->demodulator_priv;
+ struct stv0900_internal *i_params = state->internal;
+ enum fe_stv0900_demod_num demod = state->demod;
+
+ s32 demod_timeout = 500, fec_timeout = 50, stream_merger_field;
+
+ int lock = FALSE, low_sr = FALSE;
+
+ enum fe_stv0900_signal_type signal_type = STV0900_NOCARRIER;
+ enum fe_stv0900_search_algo algo;
+ int no_signal = FALSE;
+
+ dprintk(KERN_INFO "%s\n", __func__);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ algo = i_params->dmd1_srch_algo;
+
+ stv0900_write_bits(i_params, F0900_P1_RST_HWARE, 1);
+ stream_merger_field = F0900_P1_RST_HWARE;
+
+ stv0900_write_reg(i_params, R0900_P1_DMDISTATE, 0x5C);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x9e);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELABS, 0x88);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd1_symbol_rate, i_params->dmd1_srch_algo);
+
+ if (i_params->dmd1_srch_algo == STV0900_BLIND_SEARCH) {
+ i_params->tuner1_bw = 2 * 36000000;
+
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x00);
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG, 0xd2);
+
+ if (i_params->dmd1_symbol_rate < 2000000)
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x63);
+ else
+ stv0900_write_reg(i_params, R0900_P1_CORRELMANT, 0x70);
+
+ stv0900_write_reg(i_params, R0900_P1_AGC2REF, 0x38);
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0x5a);
+
+ if (i_params->dmd1_srch_algo == STV0900_COLD_START)
+ i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
+ else if (i_params->dmd1_srch_algo == STV0900_WARM_START)
+ i_params->tuner1_bw = stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000;
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_KREFTMG, 0xc1);
+ i_params->tuner1_bw = (15 * (stv0900_carrier_width(i_params->dmd1_symbol_rate, i_params->rolloff) + 10000000)) / 10;
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_TMGCFG2, 0x01);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd1_symbol_rate, demod);
+ if (i_params->dmd1_symbol_rate >= 10000000)
+ low_sr = FALSE;
+ else
+ low_sr = TRUE;
+
+ }
+
+ stv0900_set_tuner(fe, i_params->tuner1_freq, i_params->tuner1_bw);
+
+ stv0900_write_bits(i_params, F0900_P1_SPECINV_CONTROL, i_params->dmd1_srch_iq_inv);
+ stv0900_write_bits(i_params, F0900_P1_MANUAL_ROLLOFF, 1);
+
+ stv0900_set_search_standard(i_params, demod);
+
+ if (i_params->dmd1_srch_algo != STV0900_BLIND_SEARCH)
+ stv0900_start_search(i_params, demod);
+ break;
+ case STV0900_DEMOD_2:
+ algo = i_params->dmd2_srch_algo;
+
+ stv0900_write_bits(i_params, F0900_P2_RST_HWARE, 1);
+
+ stream_merger_field = F0900_P2_RST_HWARE;
+
+ stv0900_write_reg(i_params, R0900_P2_DMDISTATE, 0x5C);
+
+ if (i_params->chip_id >= 0x20)
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x9e);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELABS, 0x88);
+
+ stv0900_get_lock_timeout(&demod_timeout, &fec_timeout, i_params->dmd2_symbol_rate, i_params->dmd2_srch_algo);
+
+ if (i_params->dmd2_srch_algo == STV0900_BLIND_SEARCH) {
+ i_params->tuner2_bw = 2 * 36000000;
+
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x00);
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, 1000000, demod);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_DMDT0M, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG, 0xd2);
+
+ if (i_params->dmd2_symbol_rate < 2000000)
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x63);
+ else
+ stv0900_write_reg(i_params, R0900_P2_CORRELMANT, 0x70);
+
+ if (i_params->dmd2_symbol_rate >= 10000000)
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x38);
+ else
+ stv0900_write_reg(i_params, R0900_P2_AGC2REF, 0x60);
+
+ if (i_params->chip_id >= 0x20) {
+ stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0x5a);
+
+ if (i_params->dmd2_srch_algo == STV0900_COLD_START)
+ i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000)) / 10;
+ else if (i_params->dmd2_srch_algo == STV0900_WARM_START)
+ i_params->tuner2_bw = stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000;
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_KREFTMG, 0xc1);
+ i_params->tuner2_bw = (15 * (stv0900_carrier_width(i_params->dmd2_symbol_rate,
+ i_params->rolloff) + 10000000)) / 10;
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_TMGCFG2, 0x01);
+
+ stv0900_set_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ stv0900_set_max_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ stv0900_set_min_symbol_rate(i_params, i_params->mclk, i_params->dmd2_symbol_rate, demod);
+ if (i_params->dmd2_symbol_rate >= 10000000)
+ low_sr = FALSE;
+ else
+ low_sr = TRUE;
+
+ }
+
+ stv0900_set_tuner(fe, i_params->tuner2_freq, i_params->tuner2_bw);
+
+ stv0900_write_bits(i_params, F0900_P2_SPECINV_CONTROL, i_params->dmd2_srch_iq_inv);
+ stv0900_write_bits(i_params, F0900_P2_MANUAL_ROLLOFF, 1);
+
+ stv0900_set_search_standard(i_params, demod);
+
+ if (i_params->dmd2_srch_algo != STV0900_BLIND_SEARCH)
+ stv0900_start_search(i_params, demod);
+ break;
+ }
+
+ if (i_params->chip_id == 0x12) {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+
+ if (algo == STV0900_BLIND_SEARCH)
+ lock = stv0900_blind_search_algo(fe);
+ else if (algo == STV0900_COLD_START)
+ lock = stv0900_get_demod_cold_lock(fe, demod_timeout);
+ else if (algo == STV0900_WARM_START)
+ lock = stv0900_get_demod_lock(i_params, demod, demod_timeout);
+
+ if ((lock == FALSE) && (algo == STV0900_COLD_START)) {
+ if (low_sr == FALSE) {
+ if (stv0900_check_timing_lock(i_params, demod) == TRUE)
+ lock = stv0900_sw_algo(i_params, demod);
+ }
+ }
+
+ if (lock == TRUE)
+ signal_type = stv0900_get_signal_params(fe);
+
+ if ((lock == TRUE) && (signal_type == STV0900_RANGEOK)) {
+ stv0900_track_optimization(fe);
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_standard(fe, STV0900_DEMOD_1) == STV0900_DVBS1_STANDARD) && (stv0900_get_standard(fe, STV0900_DEMOD_2) == STV0900_DVBS1_STANDARD)) {
+ msleep(20);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ } else {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+ } else if (i_params->chip_id == 0x20) {
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ msleep(3);
+ stv0900_write_bits(i_params, stream_merger_field, 1);
+ stv0900_write_bits(i_params, stream_merger_field, 0);
+ }
+
+ if (stv0900_wait_for_lock(i_params, demod, fec_timeout, fec_timeout) == TRUE) {
+ lock = TRUE;
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = TRUE;
+ if (i_params->dmd1_rslts.standard == STV0900_DVBS2_STANDARD) {
+ stv0900_set_dvbs2_rolloff(i_params, demod);
+ stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0x40);
+ stv0900_write_reg(i_params, R0900_P1_PDELCTRL2, 0);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x67);
+ } else {
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL1, 0x75);
+ }
+
+ stv0900_write_reg(i_params, R0900_P1_FBERCPT4, 0);
+ stv0900_write_reg(i_params, R0900_P1_ERRCTRL2, 0xc1);
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = TRUE;
+
+ if (i_params->dmd2_rslts.standard == STV0900_DVBS2_STANDARD) {
+ stv0900_set_dvbs2_rolloff(i_params, demod);
+ stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x60);
+ stv0900_write_reg(i_params, R0900_P2_PDELCTRL2, 0x20);
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x67);
+ } else {
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL1, 0x75);
+ }
+
+ stv0900_write_reg(i_params, R0900_P2_FBERCPT4, 0);
+
+ stv0900_write_reg(i_params, R0900_P2_ERRCTRL2, 0xc1);
+ break;
+ }
+ } else {
+ lock = FALSE;
+ signal_type = STV0900_NODATA;
+ no_signal = stv0900_check_signal_presence(i_params, demod);
+
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ i_params->dmd1_rslts.locked = FALSE;
+ break;
+ case STV0900_DEMOD_2:
+ i_params->dmd2_rslts.locked = FALSE;
+ break;
+ }
+ }
+ }
+
+ if ((signal_type == STV0900_NODATA) && (no_signal == FALSE)) {
+ switch (demod) {
+ case STV0900_DEMOD_1:
+ default:
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_bits(i_params, F0900_P1_HEADER_MODE) == STV0900_DVBS_FOUND) &&
+ (i_params->dmd1_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
+ signal_type = stv0900_dvbs1_acq_workaround(fe);
+ } else
+ i_params->dmd1_rslts.locked = FALSE;
+
+ break;
+ case STV0900_DEMOD_2:
+ if (i_params->chip_id <= 0x11) {
+ if ((stv0900_get_bits(i_params, F0900_P2_HEADER_MODE) == STV0900_DVBS_FOUND) &&
+ (i_params->dmd2_srch_iq_inv <= STV0900_IQ_AUTO_NORMAL_FIRST))
+ signal_type = stv0900_dvbs1_acq_workaround(fe);
+ } else
+ i_params->dmd2_rslts.locked = FALSE;
+ break;
+ }
+ }
+
+ return signal_type;
+}
+
diff --git a/drivers/media/dvb/frontends/stv6110.c b/drivers/media/dvb/frontends/stv6110.c
new file mode 100644
index 00000000000..70efac869d2
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.c
@@ -0,0 +1,456 @@
+/*
+ * stv6110.c
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+
+#include <linux/types.h>
+
+#include "stv6110.h"
+
+static int debug;
+
+struct stv6110_priv {
+ int i2c_address;
+ struct i2c_adapter *i2c;
+
+ u32 mclk;
+ u8 regs[8];
+};
+
+#define dprintk(args...) \
+ do { \
+ if (debug) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+static s32 abssub(s32 a, s32 b)
+{
+ if (a > b)
+ return a - b;
+ else
+ return b - a;
+};
+
+static int stv6110_release(struct dvb_frontend *fe)
+{
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static int stv6110_write_regs(struct dvb_frontend *fe, u8 buf[],
+ int start, int len)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ int rc;
+ u8 cmdbuf[len + 1];
+ struct i2c_msg msg = {
+ .addr = priv->i2c_address,
+ .flags = 0,
+ .buf = cmdbuf,
+ .len = len + 1
+ };
+
+ dprintk("%s\n", __func__);
+
+ if (start + len > 8)
+ return -EINVAL;
+
+ memcpy(&cmdbuf[1], buf, len);
+ cmdbuf[0] = start;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ return 0;
+}
+
+static int stv6110_read_regs(struct dvb_frontend *fe, u8 regs[],
+ int start, int len)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ int rc;
+ u8 reg[] = { start };
+ struct i2c_msg msg_wr = {
+ .addr = priv->i2c_address,
+ .flags = 0,
+ .buf = reg,
+ .len = 1,
+ };
+
+ struct i2c_msg msg_rd = {
+ .addr = priv->i2c_address,
+ .flags = I2C_M_RD,
+ .buf = regs,
+ .len = len,
+ };
+ /* write subaddr */
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg_wr, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ /* read registers */
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ rc = i2c_transfer(priv->i2c, &msg_rd, 1);
+ if (rc != 1)
+ dprintk("%s: i2c error\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ memcpy(&priv->regs[start], regs, len);
+
+ return 0;
+}
+
+static int stv6110_read_reg(struct dvb_frontend *fe, int start)
+{
+ u8 buf[] = { 0 };
+ stv6110_read_regs(fe, buf, start, 1);
+
+ return buf[0];
+}
+
+static int stv6110_sleep(struct dvb_frontend *fe)
+{
+ u8 reg[] = { 0 };
+ stv6110_write_regs(fe, reg, 0, 1);
+
+ return 0;
+}
+
+static u32 carrier_width(u32 symbol_rate, fe_rolloff_t rolloff)
+{
+ u32 rlf;
+
+ switch (rolloff) {
+ case ROLLOFF_20:
+ rlf = 20;
+ break;
+ case ROLLOFF_25:
+ rlf = 25;
+ break;
+ default:
+ rlf = 35;
+ break;
+ }
+
+ return symbol_rate + ((symbol_rate * rlf) / 100);
+}
+
+static int stv6110_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 r8, ret = 0x04;
+ int i;
+
+ if ((bandwidth / 2) > 36000000) /*BW/2 max=31+5=36 mhz for r8=31*/
+ r8 = 31;
+ else if ((bandwidth / 2) < 5000000) /* BW/2 min=5Mhz for F=0 */
+ r8 = 0;
+ else /*if 5 < BW/2 < 36*/
+ r8 = (bandwidth / 2) / 1000000 - 5;
+
+ /* ctrl3, RCCLKOFF = 0 Activate the calibration Clock */
+ /* ctrl3, CF = r8 Set the LPF value */
+ priv->regs[RSTV6110_CTRL3] &= ~((1 << 6) | 0x1f);
+ priv->regs[RSTV6110_CTRL3] |= (r8 & 0x1f);
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+ /* stat1, CALRCSTRT = 1 Start LPF auto calibration*/
+ priv->regs[RSTV6110_STAT1] |= 0x02;
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_STAT1], RSTV6110_STAT1, 1);
+
+ i = 0;
+ /* Wait for CALRCSTRT == 0 */
+ while ((i < 10) && (ret != 0)) {
+ ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x02);
+ mdelay(1); /* wait for LPF auto calibration */
+ i++;
+ }
+
+ /* RCCLKOFF = 1 calibration done, desactivate the calibration Clock */
+ priv->regs[RSTV6110_CTRL3] |= (1 << 6);
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL3], RSTV6110_CTRL3, 1);
+ return 0;
+}
+
+static int stv6110_init(struct dvb_frontend *fe)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 buf0[] = { 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+ memcpy(priv->regs, buf0, 8);
+ /* K = (Reference / 1000000) - 16 */
+ priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+ priv->regs[RSTV6110_CTRL1] |=
+ ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1], RSTV6110_CTRL1, 8);
+ msleep(1);
+ stv6110_set_bandwidth(fe, 72000000);
+
+ return 0;
+}
+
+static int stv6110_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u32 nbsteps, divider, psd2, freq;
+ u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+
+ stv6110_read_regs(fe, regs, 0, 8);
+ /*N*/
+ divider = (priv->regs[RSTV6110_TUNING2] & 0x0f) << 8;
+ divider += priv->regs[RSTV6110_TUNING1];
+
+ /*R*/
+ nbsteps = (priv->regs[RSTV6110_TUNING2] >> 6) & 3;
+ /*p*/
+ psd2 = (priv->regs[RSTV6110_TUNING2] >> 4) & 1;
+
+ freq = divider * (priv->mclk / 1000);
+ freq /= (1 << (nbsteps + psd2));
+ freq /= 4;
+
+ *frequency = freq;
+
+ return 0;
+}
+
+static int stv6110_set_frequency(struct dvb_frontend *fe, u32 frequency)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u8 ret = 0x04;
+ u32 divider, ref, p, presc, i, result_freq, vco_freq;
+ s32 p_calc, p_calc_opt = 1000, r_div, r_div_opt = 0, p_val;
+ s32 srate; u8 gain;
+
+ dprintk("%s, freq=%d kHz, mclk=%d Hz\n", __func__,
+ frequency, priv->mclk);
+
+ /* K = (Reference / 1000000) - 16 */
+ priv->regs[RSTV6110_CTRL1] &= ~(0x1f << 3);
+ priv->regs[RSTV6110_CTRL1] |=
+ ((((priv->mclk / 1000000) - 16) & 0x1f) << 3);
+
+ /* BB_GAIN = db/2 */
+ if (fe->ops.set_property && fe->ops.get_property) {
+ srate = c->symbol_rate;
+ dprintk("%s: Get Frontend parameters: srate=%d\n",
+ __func__, srate);
+ } else
+ srate = 15000000;
+
+ if (srate >= 15000000)
+ gain = 3; /* +6 dB */
+ else if (srate >= 5000000)
+ gain = 3; /* +6 dB */
+ else
+ gain = 3; /* +6 dB */
+
+ priv->regs[RSTV6110_CTRL2] &= ~0x0f;
+ priv->regs[RSTV6110_CTRL2] |= (gain & 0x0f);
+
+ if (frequency <= 1023000) {
+ p = 1;
+ presc = 0;
+ } else if (frequency <= 1300000) {
+ p = 1;
+ presc = 1;
+ } else if (frequency <= 2046000) {
+ p = 0;
+ presc = 0;
+ } else {
+ p = 0;
+ presc = 1;
+ }
+ /* DIV4SEL = p*/
+ priv->regs[RSTV6110_TUNING2] &= ~(1 << 4);
+ priv->regs[RSTV6110_TUNING2] |= (p << 4);
+
+ /* PRESC32ON = presc */
+ priv->regs[RSTV6110_TUNING2] &= ~(1 << 5);
+ priv->regs[RSTV6110_TUNING2] |= (presc << 5);
+
+ p_val = (int)(1 << (p + 1)) * 10;/* P = 2 or P = 4 */
+ for (r_div = 0; r_div <= 3; r_div++) {
+ p_calc = (priv->mclk / 100000);
+ p_calc /= (1 << (r_div + 1));
+ if ((abssub(p_calc, p_val)) < (abssub(p_calc_opt, p_val)))
+ r_div_opt = r_div;
+
+ p_calc_opt = (priv->mclk / 100000);
+ p_calc_opt /= (1 << (r_div_opt + 1));
+ }
+
+ ref = priv->mclk / ((1 << (r_div_opt + 1)) * (1 << (p + 1)));
+ divider = (((frequency * 1000) + (ref >> 1)) / ref);
+
+ /* RDIV = r_div_opt */
+ priv->regs[RSTV6110_TUNING2] &= ~(3 << 6);
+ priv->regs[RSTV6110_TUNING2] |= (((r_div_opt) & 3) << 6);
+
+ /* NDIV_MSB = MSB(divider) */
+ priv->regs[RSTV6110_TUNING2] &= ~0x0f;
+ priv->regs[RSTV6110_TUNING2] |= (((divider) >> 8) & 0x0f);
+
+ /* NDIV_LSB, LSB(divider) */
+ priv->regs[RSTV6110_TUNING1] = (divider & 0xff);
+
+ /* CALVCOSTRT = 1 VCO Auto Calibration */
+ priv->regs[RSTV6110_STAT1] |= 0x04;
+ stv6110_write_regs(fe, &priv->regs[RSTV6110_CTRL1],
+ RSTV6110_CTRL1, 8);
+
+ i = 0;
+ /* Wait for CALVCOSTRT == 0 */
+ while ((i < 10) && (ret != 0)) {
+ ret = ((stv6110_read_reg(fe, RSTV6110_STAT1)) & 0x04);
+ msleep(1); /* wait for VCO auto calibration */
+ i++;
+ }
+
+ ret = stv6110_read_reg(fe, RSTV6110_STAT1);
+ stv6110_get_frequency(fe, &result_freq);
+
+ vco_freq = divider * ((priv->mclk / 1000) / ((1 << (r_div_opt + 1))));
+ dprintk("%s, stat1=%x, lo_freq=%d kHz, vco_frec=%d kHz\n", __func__,
+ ret, result_freq, vco_freq);
+
+ return 0;
+}
+
+static int stv6110_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct dtv_frontend_properties *c = &fe->dtv_property_cache;
+ u32 bandwidth = carrier_width(c->symbol_rate, c->rolloff);
+
+ stv6110_set_frequency(fe, c->frequency);
+ stv6110_set_bandwidth(fe, bandwidth);
+
+ return 0;
+}
+
+static int stv6110_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ struct stv6110_priv *priv = fe->tuner_priv;
+ u8 r8 = 0;
+ u8 regs[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ stv6110_read_regs(fe, regs, 0, 8);
+
+ /* CF */
+ r8 = priv->regs[RSTV6110_CTRL3] & 0x1f;
+ *bandwidth = (r8 + 5) * 2000000;/* x2 for ZIF tuner BW/2 = F+5 Mhz */
+
+ return 0;
+}
+
+static struct dvb_tuner_ops stv6110_tuner_ops = {
+ .info = {
+ .name = "ST STV6110",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 1000,
+ },
+ .init = stv6110_init,
+ .release = stv6110_release,
+ .sleep = stv6110_sleep,
+ .set_params = stv6110_set_params,
+ .get_frequency = stv6110_get_frequency,
+ .set_frequency = stv6110_set_frequency,
+ .get_bandwidth = stv6110_get_bandwidth,
+ .set_bandwidth = stv6110_set_bandwidth,
+
+};
+
+struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct stv6110_priv *priv = NULL;
+ u8 reg0[] = { 0x00, 0x07, 0x11, 0xdc, 0x85, 0x17, 0x01, 0xe6, 0x1e };
+
+ struct i2c_msg msg[] = {
+ {
+ .addr = config->i2c_address,
+ .flags = 0,
+ .buf = reg0,
+ .len = 9
+ }
+ };
+ int ret;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ ret = i2c_transfer(i2c, msg, 1);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+
+ if (ret != 1)
+ return NULL;
+
+ priv = kzalloc(sizeof(struct stv6110_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return NULL;
+
+ priv->i2c_address = config->i2c_address;
+ priv->i2c = i2c;
+ priv->mclk = config->mclk;
+
+ memcpy(&priv->regs, &reg0[1], 8);
+
+ memcpy(&fe->ops.tuner_ops, &stv6110_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ fe->tuner_priv = priv;
+ printk(KERN_INFO "STV6110 attached on addr=%x!\n", priv->i2c_address);
+
+ return fe;
+}
+EXPORT_SYMBOL(stv6110_attach);
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+
+MODULE_DESCRIPTION("ST STV6110 driver");
+MODULE_AUTHOR("Igor M. Liplianin");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv6110.h b/drivers/media/dvb/frontends/stv6110.h
new file mode 100644
index 00000000000..1c0314d6aa5
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv6110.h
@@ -0,0 +1,62 @@
+/*
+ * stv6110.h
+ *
+ * Driver for ST STV6110 satellite tuner IC.
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __DVB_STV6110_H__
+#define __DVB_STV6110_H__
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/* registers */
+#define RSTV6110_CTRL1 0
+#define RSTV6110_CTRL2 1
+#define RSTV6110_TUNING1 2
+#define RSTV6110_TUNING2 3
+#define RSTV6110_CTRL3 4
+#define RSTV6110_STAT1 5
+#define RSTV6110_STAT2 6
+#define RSTV6110_STAT3 7
+
+struct stv6110_config {
+ u8 i2c_address;
+ u32 mclk;
+ int iq_wiring;
+};
+
+#if defined(CONFIG_DVB_STV6110) || (defined(CONFIG_DVB_STV6110_MODULE) \
+ && defined(MODULE))
+extern struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *stv6110_attach(struct dvb_frontend *fe,
+ const struct stv6110_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 1465ff77b0c..4981cef8b44 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -162,7 +162,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
if (ret != 2) {
dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
ret);
- return -1;
+ return -EINVAL;
}
dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
@@ -481,16 +481,18 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
static int tda10046_fwupload(struct dvb_frontend* fe)
{
struct tda1004x_state* state = fe->demodulator_priv;
- int ret;
+ int ret, confc4;
const struct firmware *fw;
/* reset + wake up chip */
if (state->config->xtal_freq == TDA10046_XTAL_4M) {
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
+ confc4 = 0;
} else {
dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
- tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
+ confc4 = 0x80;
}
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
/* set GPIO 1 and 3 */
if (state->config->gpio_config != TDA10046_GPTRI) {
@@ -508,13 +510,29 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /*
+ For i2c normal work, we need to slow down the bus speed.
+ However, the slow down breaks the eeprom firmware load.
+ So, use normal speed for eeprom booting and then restore the
+ i2c speed after that. Tested with MSI TV @nyware A/D board,
+ that comes with firmware version 29 inside their eeprom.
+
+ It should also be noticed that no other I2C transfer should
+ be in course while booting from eeprom, otherwise, tda10046
+ goes into an instable state. So, proper locking are needed
+ at the i2c bus master.
+ */
printk(KERN_INFO "tda1004x: trying to boot from eeprom\n");
- tda1004x_write_mask(state, TDA1004X_CONFC4, 4, 4);
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 4);
msleep(300);
- /* don't re-upload unless necessary */
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, confc4);
+
+ /* Checks if eeprom firmware went without troubles */
if (tda1004x_check_upload_ok(state) == 0)
return 0;
+ /* eeprom firmware didn't work. Load one manually. */
+
if (state->config->request_firmware != NULL) {
/* request the firmware, this will block until someone uploads it */
printk(KERN_INFO "tda1004x: waiting for firmware upload...\n");
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
new file mode 100644
index 00000000000..e22a0b381dc
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -0,0 +1,519 @@
+/**
+ * Driver for Zarlink zl10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ *
+ **
+ * The data sheet for this tuner can be found at:
+ * http://www.mcmilk.de/projects/dvb-card/datasheets/ZL10036.pdf
+ *
+ * This one is working: (at my Avermedia DVB-S Pro)
+ * - zl10036 (40pin, FTA)
+ *
+ * A driver for zl10038 should be very similar.
+ */
+
+#include <linux/module.h>
+#include <linux/dvb/frontend.h>
+#include <asm/types.h>
+
+#include "zl10036.h"
+
+static int zl10036_debug;
+#define dprintk(level, args...) \
+ do { if (zl10036_debug & level) printk(KERN_DEBUG "zl10036: " args); \
+ } while (0)
+
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_i2c(args...) dprintk(0x02, args)
+
+struct zl10036_state {
+ struct i2c_adapter *i2c;
+ const struct zl10036_config *config;
+ u32 frequency;
+ u8 br, bf;
+};
+
+
+/* This driver assumes the tuner is driven by a 10.111MHz Cristal */
+#define _XTAL 10111
+
+/* Some of the possible dividers:
+ * 64, (write 0x05 to reg), freq step size 158kHz
+ * 10, (write 0x0a to reg), freq step size 1.011kHz (used here)
+ * 5, (write 0x09 to reg), freq step size 2.022kHz
+ */
+
+#define _RDIV 10
+#define _RDIV_REG 0x0a
+#define _FR (_XTAL/_RDIV)
+
+#define STATUS_POR 0x80 /* Power on Reset */
+#define STATUS_FL 0x40 /* Frequency & Phase Lock */
+
+/* read/write for zl10036 and zl10038 */
+
+static int zl10036_read_status_reg(struct zl10036_state *state)
+{
+ u8 status;
+ struct i2c_msg msg[1] = {
+ { .addr = state->config->tuner_address, .flags = I2C_M_RD,
+ .buf = &status, .len = sizeof(status) },
+ };
+
+ if (i2c_transfer(state->i2c, msg, 1) != 1) {
+ printk(KERN_ERR "%s: i2c read failed at addr=%02x\n",
+ __func__, state->config->tuner_address);
+ return -EIO;
+ }
+
+ deb_i2c("R(status): %02x [FL=%d]\n", status,
+ (status & STATUS_FL) ? 1 : 0);
+ if (status & STATUS_POR)
+ deb_info("%s: Power-On-Reset bit enabled - "
+ "need to initialize the tuner\n", __func__);
+
+ return status;
+}
+
+static int zl10036_write(struct zl10036_state *state, u8 buf[], u8 count)
+{
+ struct i2c_msg msg[1] = {
+ { .addr = state->config->tuner_address, .flags = 0,
+ .buf = buf, .len = count },
+ };
+ u8 reg = 0;
+ int ret;
+
+ if (zl10036_debug & 0x02) {
+ /* every 8bit-value satisifes this!
+ * so only check for debug log */
+ if ((buf[0] & 0x80) == 0x00)
+ reg = 2;
+ else if ((buf[0] & 0xc0) == 0x80)
+ reg = 4;
+ else if ((buf[0] & 0xf0) == 0xc0)
+ reg = 6;
+ else if ((buf[0] & 0xf0) == 0xd0)
+ reg = 8;
+ else if ((buf[0] & 0xf0) == 0xe0)
+ reg = 10;
+ else if ((buf[0] & 0xf0) == 0xf0)
+ reg = 12;
+
+ deb_i2c("W(%d):", reg);
+ {
+ int i;
+ for (i = 0; i < count; i++)
+ printk(KERN_CONT " %02x", buf[i]);
+ printk(KERN_CONT "\n");
+ }
+ }
+
+ ret = i2c_transfer(state->i2c, msg, 1);
+ if (ret != 1) {
+ printk(KERN_ERR "%s: i2c error, ret=%d\n", __func__, ret);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int zl10036_release(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+
+ fe->tuner_priv = NULL;
+ kfree(state);
+
+ return 0;
+}
+
+static int zl10036_sleep(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ u8 buf[] = { 0xf0, 0x80 }; /* regs 12/13 */
+ int ret;
+
+ deb_info("%s\n", __func__);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_write(state, buf, sizeof(buf));
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+/**
+ * register map of the ZL10036/ZL10038
+ *
+ * reg[default] content
+ * 2[0x00]: 0 | N14 | N13 | N12 | N11 | N10 | N9 | N8
+ * 3[0x00]: N7 | N6 | N5 | N4 | N3 | N2 | N1 | N0
+ * 4[0x80]: 1 | 0 | RFG | BA1 | BA0 | BG1 | BG0 | LEN
+ * 5[0x00]: P0 | C1 | C0 | R4 | R3 | R2 | R1 | R0
+ * 6[0xc0]: 1 | 1 | 0 | 0 | RSD | 0 | 0 | 0
+ * 7[0x20]: P1 | BF6 | BF5 | BF4 | BF3 | BF2 | BF1 | 0
+ * 8[0xdb]: 1 | 1 | 0 | 1 | 0 | CC | 1 | 1
+ * 9[0x30]: VSD | V2 | V1 | V0 | S3 | S2 | S1 | S0
+ * 10[0xe1]: 1 | 1 | 1 | 0 | 0 | LS2 | LS1 | LS0
+ * 11[0xf5]: WS | WH2 | WH1 | WH0 | WL2 | WL1 | WL0 | WRE
+ * 12[0xf0]: 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0
+ * 13[0x28]: PD | BR4 | BR3 | BR2 | BR1 | BR0 | CLR | TL
+ */
+
+static int zl10036_set_frequency(struct zl10036_state *state, u32 frequency)
+{
+ u8 buf[2];
+ u32 div, foffset;
+
+ div = (frequency + _FR/2) / _FR;
+ state->frequency = div * _FR;
+
+ foffset = frequency - state->frequency;
+
+ buf[0] = (div >> 8) & 0x7f;
+ buf[1] = (div >> 0) & 0xff;
+
+ deb_info("%s: ftodo=%u fpriv=%u ferr=%d div=%u\n", __func__,
+ frequency, state->frequency, foffset, div);
+
+ return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_bandwidth(struct zl10036_state *state, u32 fbw)
+{
+ /* fbw is measured in kHz */
+ u8 br, bf;
+ int ret;
+ u8 buf_bf[] = {
+ 0xc0, 0x00, /* 6/7: rsd=0 bf=0 */
+ };
+ u8 buf_br[] = {
+ 0xf0, 0x00, /* 12/13: br=0xa clr=0 tl=0*/
+ };
+ u8 zl10036_rsd_off[] = { 0xc8 }; /* set RSD=1 */
+
+ /* ensure correct values */
+ if (fbw > 35000)
+ fbw = 35000;
+ if (fbw < 8000)
+ fbw = 8000;
+
+#define _BR_MAXIMUM (_XTAL/575) /* _XTAL / 575kHz = 17 */
+
+ /* <= 28,82 MHz */
+ if (fbw <= 28820) {
+ br = _BR_MAXIMUM;
+ } else {
+ /**
+ * f(bw)=34,6MHz f(xtal)=10.111MHz
+ * br = (10111/34600) * 63 * 1/K = 14;
+ */
+ br = ((_XTAL * 21 * 1000) / (fbw * 419));
+ }
+
+ /* ensure correct values */
+ if (br < 4)
+ br = 4;
+ if (br > _BR_MAXIMUM)
+ br = _BR_MAXIMUM;
+
+ /*
+ * k = 1.257
+ * bf = fbw/_XTAL * br * k - 1 */
+
+ bf = (fbw * br * 1257) / (_XTAL * 1000) - 1;
+
+ /* ensure correct values */
+ if (bf > 62)
+ bf = 62;
+
+ buf_bf[1] = (bf << 1) & 0x7e;
+ buf_br[1] = (br << 2) & 0x7c;
+ deb_info("%s: BW=%d br=%u bf=%u\n", __func__, fbw, br, bf);
+
+ if (br != state->br) {
+ ret = zl10036_write(state, buf_br, sizeof(buf_br));
+ if (ret < 0)
+ return ret;
+ }
+
+ if (bf != state->bf) {
+ ret = zl10036_write(state, buf_bf, sizeof(buf_bf));
+ if (ret < 0)
+ return ret;
+
+ /* time = br/(32* fxtal) */
+ /* minimal sleep time to be calculated
+ * maximum br is 63 -> max time = 2 /10 MHz = 2e-7 */
+ msleep(1);
+
+ ret = zl10036_write(state, zl10036_rsd_off,
+ sizeof(zl10036_rsd_off));
+ if (ret < 0)
+ return ret;
+ }
+
+ state->br = br;
+ state->bf = bf;
+
+ return 0;
+}
+
+static int zl10036_set_gain_params(struct zl10036_state *state,
+ int c)
+{
+ u8 buf[2];
+ u8 rfg, ba, bg;
+
+ /* default values */
+ rfg = 0; /* enable when using an lna */
+ ba = 1;
+ bg = 1;
+
+ /* reg 4 */
+ buf[0] = 0x80 | ((rfg << 5) & 0x20)
+ | ((ba << 3) & 0x18) | ((bg << 1) & 0x06);
+
+ if (!state->config->rf_loop_enable)
+ buf[0] |= 0x01;
+
+ /* P0=0 */
+ buf[1] = _RDIV_REG | ((c << 5) & 0x60);
+
+ deb_info("%s: c=%u rfg=%u ba=%u bg=%u\n", __func__, c, rfg, ba, bg);
+ return zl10036_write(state, buf, sizeof(buf));
+}
+
+static int zl10036_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ int ret = 0;
+ u32 frequency = params->frequency;
+ u32 fbw;
+ int i;
+ u8 c;
+
+ /* ensure correct values
+ * maybe redundant as core already checks this */
+ if ((frequency < fe->ops.info.frequency_min)
+ || (frequency > fe->ops.info.frequency_max))
+ return -EINVAL;
+
+ /**
+ * alpha = 1.35 for dvb-s
+ * fBW = (alpha*symbolrate)/(2*0.8)
+ * 1.35 / (2*0.8) = 27 / 32
+ */
+ fbw = (27 * params->u.qpsk.symbol_rate) / 32;
+
+ /* scale to kHz */
+ fbw /= 1000;
+
+ /* Add safe margin of 3MHz */
+ fbw += 3000;
+
+ /* setting the charge pump - guessed values */
+ if (frequency < 950000)
+ return -EINVAL;
+ else if (frequency < 1250000)
+ c = 0;
+ else if (frequency < 1750000)
+ c = 1;
+ else if (frequency < 2175000)
+ c = 2;
+ else
+ return -EINVAL;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_set_gain_params(state, c);
+ if (ret < 0)
+ goto error;
+
+ ret = zl10036_set_frequency(state, params->frequency);
+ if (ret < 0)
+ goto error;
+
+ ret = zl10036_set_bandwidth(state, fbw);
+ if (ret < 0)
+ goto error;
+
+ /* wait for tuner lock - no idea if this is really needed */
+ for (i = 0; i < 20; i++) {
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0)
+ goto error;
+
+ /* check Frequency & Phase Lock Bit */
+ if (ret & STATUS_FL)
+ break;
+
+ msleep(10);
+ }
+
+error:
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+static int zl10036_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+
+ *frequency = state->frequency;
+
+ return 0;
+}
+
+static int zl10036_init_regs(struct zl10036_state *state)
+{
+ int ret;
+ int i;
+
+ /* could also be one block from reg 2 to 13 and additional 10/11 */
+ u8 zl10036_init_tab[][2] = {
+ { 0x04, 0x00 }, /* 2/3: div=0x400 - arbitrary value */
+ { 0x8b, _RDIV_REG }, /* 4/5: rfg=0 ba=1 bg=1 len=? */
+ /* p0=0 c=0 r=_RDIV_REG */
+ { 0xc0, 0x20 }, /* 6/7: rsd=0 bf=0x10 */
+ { 0xd3, 0x40 }, /* 8/9: from datasheet */
+ { 0xe3, 0x5b }, /* 10/11: lock window level */
+ { 0xf0, 0x28 }, /* 12/13: br=0xa clr=0 tl=0*/
+ { 0xe3, 0xf9 }, /* 10/11: unlock window level */
+ };
+
+ /* invalid values to trigger writing */
+ state->br = 0xff;
+ state->bf = 0xff;
+
+ if (!state->config->rf_loop_enable)
+ zl10036_init_tab[1][2] |= 0x01;
+
+ deb_info("%s\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(zl10036_init_tab); i++) {
+ ret = zl10036_write(state, zl10036_init_tab[i], 2);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int zl10036_init(struct dvb_frontend *fe)
+{
+ struct zl10036_state *state = fe->tuner_priv;
+ int ret = 0;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0)
+ return ret;
+
+ /* Only init if Power-on-Reset bit is set? */
+ ret = zl10036_init_regs(state);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ return ret;
+}
+
+static struct dvb_tuner_ops zl10036_tuner_ops = {
+ .info = {
+ .name = "Zarlink ZL10036",
+ .frequency_min = 950000,
+ .frequency_max = 2175000
+ },
+ .init = zl10036_init,
+ .release = zl10036_release,
+ .sleep = zl10036_sleep,
+ .set_params = zl10036_set_params,
+ .get_frequency = zl10036_get_frequency,
+};
+
+struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct zl10036_state *state = NULL;
+ int ret;
+
+ if (NULL == config) {
+ printk(KERN_ERR "%s: no config specified", __func__);
+ goto error;
+ }
+
+ state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
+ if (NULL == state)
+ return NULL;
+
+ state->config = config;
+ state->i2c = i2c;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+ ret = zl10036_read_status_reg(state);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: No zl10036 found\n", __func__);
+ goto error;
+ }
+
+ ret = zl10036_init_regs(state);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: tuner initialization failed\n",
+ __func__);
+ goto error;
+ }
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+ fe->tuner_priv = state;
+
+ memcpy(&fe->ops.tuner_ops, &zl10036_tuner_ops,
+ sizeof(struct dvb_tuner_ops));
+ printk(KERN_INFO "%s: tuner initialization (%s addr=0x%02x) ok\n",
+ __func__, fe->ops.tuner_ops.info.name, config->tuner_address);
+
+ return fe;
+
+error:
+ zl10036_release(fe);
+ return NULL;
+}
+EXPORT_SYMBOL(zl10036_attach);
+
+module_param_named(debug, zl10036_debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
+MODULE_DESCRIPTION("DVB ZL10036 driver");
+MODULE_AUTHOR("Tino Reichardt");
+MODULE_AUTHOR("Matthias Schwarzott");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/zl10036.h b/drivers/media/dvb/frontends/zl10036.h
new file mode 100644
index 00000000000..d84b8f8215e
--- /dev/null
+++ b/drivers/media/dvb/frontends/zl10036.h
@@ -0,0 +1,53 @@
+/**
+ * Driver for Zarlink ZL10036 DVB-S silicon tuner
+ *
+ * Copyright (C) 2006 Tino Reichardt
+ * Copyright (C) 2007-2009 Matthias Schwarzott <zzam@gentoo.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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 DVB_ZL10036_H
+#define DVB_ZL10036_H
+
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+
+/**
+ * Attach a zl10036 tuner to the supplied frontend structure.
+ *
+ * @param fe Frontend to attach to.
+ * @param config zl10036_config structure
+ * @return FE pointer on success, NULL on failure.
+ */
+
+struct zl10036_config {
+ u8 tuner_address;
+ int rf_loop_enable;
+};
+
+#if defined(CONFIG_DVB_ZL10036) || \
+ (defined(CONFIG_DVB_ZL10036_MODULE) && defined(MODULE))
+extern struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config, struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
+ const struct zl10036_config *config, struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
+#endif /* DVB_ZL10036_H */
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index b150ed30669..148b6f7f6cb 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -572,6 +572,10 @@ static int zl10353_init(struct dvb_frontend *fe)
zl10353_dump_regs(fe);
if (state->config.parallel_ts)
zl10353_reset_attach[2] &= ~0x20;
+ if (state->config.clock_ctl_1)
+ zl10353_reset_attach[3] = state->config.clock_ctl_1;
+ if (state->config.pll_0)
+ zl10353_reset_attach[4] = state->config.pll_0;
/* Do a "hard" reset if not already done */
if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
@@ -614,6 +618,7 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
struct i2c_adapter *i2c)
{
struct zl10353_state *state = NULL;
+ int id;
/* allocate memory for the internal state */
state = kzalloc(sizeof(struct zl10353_state), GFP_KERNEL);
@@ -625,7 +630,8 @@ struct dvb_frontend *zl10353_attach(const struct zl10353_config *config,
memcpy(&state->config, config, sizeof(struct zl10353_config));
/* check if the demod is there */
- if (zl10353_read_register(state, CHIP_ID) != ID_ZL10353)
+ id = zl10353_read_register(state, CHIP_ID);
+ if ((id != ID_ZL10353) && (id != ID_CE6230) && (id != ID_CE6231))
goto error;
/* create dvb_frontend */
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 2287bac4624..6e3ca9eed04 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -41,6 +41,10 @@ struct zl10353_config
/* set if i2c_gate_ctrl disable is required */
u8 disable_i2c_gate_ctrl:1;
+
+ /* clock control registers (0x51-0x54) */
+ u8 clock_ctl_1; /* default: 0x46 */
+ u8 pll_0; /* default: 0x15 */
};
#if defined(CONFIG_DVB_ZL10353) || (defined(CONFIG_DVB_ZL10353_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/frontends/zl10353_priv.h b/drivers/media/dvb/frontends/zl10353_priv.h
index 055ff1f7e34..e0dd1d3e09d 100644
--- a/drivers/media/dvb/frontends/zl10353_priv.h
+++ b/drivers/media/dvb/frontends/zl10353_priv.h
@@ -22,7 +22,9 @@
#ifndef _ZL10353_PRIV_
#define _ZL10353_PRIV_
-#define ID_ZL10353 0x14
+#define ID_ZL10353 0x14 /* Zarlink ZL10353 */
+#define ID_CE6230 0x18 /* Intel CE6230 */
+#define ID_CE6231 0x19 /* Intel CE6231 */
#define msb(x) (((x) >> 8) & 0xff)
#define lsb(x) ((x) & 0xff)
@@ -50,6 +52,10 @@ enum zl10353_reg_addr {
TPS_RECEIVED_0 = 0x1E,
TPS_CURRENT_1 = 0x1F,
TPS_CURRENT_0 = 0x20,
+ CLOCK_CTL_0 = 0x51,
+ CLOCK_CTL_1 = 0x52,
+ PLL_0 = 0x53,
+ PLL_1 = 0x54,
RESET = 0x55,
AGC_TARGET = 0x56,
MCLK_RATIO = 0x5C,
diff --git a/drivers/media/dvb/pluto2/pluto2.c b/drivers/media/dvb/pluto2/pluto2.c
index d101b304e9b..ee89623be85 100644
--- a/drivers/media/dvb/pluto2/pluto2.c
+++ b/drivers/media/dvb/pluto2/pluto2.c
@@ -116,6 +116,7 @@ struct pluto {
/* irq */
unsigned int overflow;
+ unsigned int dead;
/* dma */
dma_addr_t dma_addr;
@@ -336,8 +337,10 @@ static irqreturn_t pluto_irq(int irq, void *dev_id)
return IRQ_NONE;
if (tscr == 0xffffffff) {
- // FIXME: maybe recover somehow
- dev_err(&pluto->pdev->dev, "card hung up :(\n");
+ if (pluto->dead == 0)
+ dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
+ /* It's dead Jim */
+ pluto->dead = 1;
return IRQ_HANDLED;
}
diff --git a/drivers/media/dvb/siano/Makefile b/drivers/media/dvb/siano/Makefile
index ee0737af98c..bcf93f4828b 100644
--- a/drivers/media/dvb/siano/Makefile
+++ b/drivers/media/dvb/siano/Makefile
@@ -1,6 +1,8 @@
-sms1xxx-objs := smscoreapi.o smsusb.o smsdvb.o sms-cards.o
+sms1xxx-objs := smscoreapi.o sms-cards.o
obj-$(CONFIG_DVB_SIANO_SMS1XXX) += sms1xxx.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsusb.o
+obj-$(CONFIG_DVB_SIANO_SMS1XXX) += smsdvb.o
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 4307e4e8aa3..63e4d0ec658 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -19,50 +19,9 @@
#include "sms-cards.h"
-struct usb_device_id smsusb_id_table[] = {
-#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
- { USB_DEVICE(0x187f, 0x0010),
- .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
- { USB_DEVICE(0x187f, 0x0100),
- .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
- { USB_DEVICE(0x187f, 0x0200),
- .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
- { USB_DEVICE(0x187f, 0x0201),
- .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
- { USB_DEVICE(0x187f, 0x0300),
- .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
-#endif
- { USB_DEVICE(0x2040, 0x1700),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
- { USB_DEVICE(0x2040, 0x1800),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
- { USB_DEVICE(0x2040, 0x1801),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
- { USB_DEVICE(0x2040, 0x2000),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x2009),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
- { USB_DEVICE(0x2040, 0x200a),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x2010),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x2019),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
- { USB_DEVICE(0x2040, 0x5500),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5510),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5520),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5530),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5580),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { USB_DEVICE(0x2040, 0x5590),
- .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
- { } /* Terminating entry */
-};
-MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+static int sms_dbg;
+module_param_named(cards_dbg, sms_dbg, int, 0644);
+MODULE_PARM_DESC(cards_dbg, "set debug level (info=1, adv=2 (or-able))");
static struct sms_board sms_boards[] = {
[SMS_BOARD_UNKNOWN] = {
@@ -115,6 +74,7 @@ static struct sms_board sms_boards[] = {
.type = SMS_NOVA_B0,
.fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
.lna_ctrl = 29,
+ .rf_switch = 17,
},
[SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2] = {
.name = "Hauppauge WinTV MiniCard",
@@ -130,6 +90,7 @@ struct sms_board *sms_get_board(int id)
return &sms_boards[id];
}
+EXPORT_SYMBOL_GPL(sms_get_board);
static int sms_set_gpio(struct smscore_device_t *coredev, int pin, int enable)
{
@@ -182,6 +143,7 @@ int sms_board_setup(struct smscore_device_t *coredev)
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_setup);
int sms_board_power(struct smscore_device_t *coredev, int onoff)
{
@@ -197,12 +159,13 @@ int sms_board_power(struct smscore_device_t *coredev, int onoff)
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
/* LNA */
- sms_set_gpio(coredev,
- board->lna_ctrl, onoff ? 1 : 0);
+ if (!onoff)
+ sms_set_gpio(coredev, board->lna_ctrl, 0);
break;
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_power);
int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
{
@@ -225,3 +188,40 @@ int sms_board_led_feedback(struct smscore_device_t *coredev, int led)
}
return 0;
}
+EXPORT_SYMBOL_GPL(sms_board_led_feedback);
+
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff)
+{
+ int board_id = smscore_get_board_id(coredev);
+ struct sms_board *board = sms_get_board(board_id);
+
+ sms_debug("%s: LNA %s", __func__, onoff ? "enabled" : "disabled");
+
+ switch (board_id) {
+ case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2:
+ case SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD:
+ sms_set_gpio(coredev,
+ board->rf_switch, onoff ? 1 : 0);
+ return sms_set_gpio(coredev,
+ board->lna_ctrl, onoff ? 1 : 0);
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(sms_board_lna_control);
+
+int sms_board_load_modules(int id)
+{
+ switch (id) {
+ case SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT:
+ case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A:
+ case SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B:
+ case SMS1XXX_BOARD_HAUPPAUGE_WINDHAM:
+ request_module("smsdvb");
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sms_board_load_modules);
diff --git a/drivers/media/dvb/siano/sms-cards.h b/drivers/media/dvb/siano/sms-cards.h
index 8e0fe9fd261..64d74c59c33 100644
--- a/drivers/media/dvb/siano/sms-cards.h
+++ b/drivers/media/dvb/siano/sms-cards.h
@@ -40,7 +40,7 @@ struct sms_board {
char *name, *fw[DEVICE_MODE_MAX];
/* gpios */
- int led_power, led_hi, led_lo, lna_ctrl;
+ int led_power, led_hi, led_lo, lna_ctrl, rf_switch;
};
struct sms_board *sms_get_board(int id);
@@ -52,7 +52,8 @@ int sms_board_setup(struct smscore_device_t *coredev);
#define SMS_LED_HI 2
int sms_board_led_feedback(struct smscore_device_t *coredev, int led);
int sms_board_power(struct smscore_device_t *coredev, int onoff);
+int sms_board_lna_control(struct smscore_device_t *coredev, int onoff);
-extern struct usb_device_id smsusb_id_table[];
+extern int sms_board_load_modules(int id);
#endif /* __SMS_CARDS_H__ */
diff --git a/drivers/media/dvb/siano/smscoreapi.c b/drivers/media/dvb/siano/smscoreapi.c
index cf613f22fb8..7bd4d1dee2b 100644
--- a/drivers/media/dvb/siano/smscoreapi.c
+++ b/drivers/media/dvb/siano/smscoreapi.c
@@ -3,7 +3,7 @@
*
* This file contains implementation for the interface to sms core component
*
- * author: Anatoly Greenblat
+ * author: Uri Shkolnik
*
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
*
@@ -34,8 +34,8 @@
#include "smscoreapi.h"
#include "sms-cards.h"
-int sms_debug;
-module_param_named(debug, sms_debug, int, 0644);
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
struct smscore_device_notifyee_t {
@@ -105,11 +105,13 @@ int smscore_led_state(struct smscore_device_t *core, int led)
core->led_state = led;
return core->led_state;
}
+EXPORT_SYMBOL_GPL(smscore_set_board_id);
int smscore_get_board_id(struct smscore_device_t *core)
{
return core->board_id;
}
+EXPORT_SYMBOL_GPL(smscore_get_board_id);
struct smscore_registry_entry_t {
struct list_head entry;
@@ -170,6 +172,7 @@ int smscore_registry_getmode(char *devpath)
return default_mode;
}
+EXPORT_SYMBOL_GPL(smscore_registry_getmode);
static enum sms_device_type_st smscore_registry_gettype(char *devpath)
{
@@ -261,6 +264,7 @@ int smscore_register_hotplug(hotplug_t hotplug)
return rc;
}
+EXPORT_SYMBOL_GPL(smscore_register_hotplug);
/**
* unregister a client callback that called when device plugged in/unplugged
@@ -289,6 +293,7 @@ void smscore_unregister_hotplug(hotplug_t hotplug)
kmutex_unlock(&g_smscore_deviceslock);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_hotplug);
static void smscore_notify_clients(struct smscore_device_t *coredev)
{
@@ -432,6 +437,7 @@ int smscore_register_device(struct smsdevice_params_t *params,
return 0;
}
+EXPORT_SYMBOL_GPL(smscore_register_device);
/**
* sets initial device mode and notifies client hotplugs that device is ready
@@ -460,6 +466,7 @@ int smscore_start_device(struct smscore_device_t *coredev)
return rc;
}
+EXPORT_SYMBOL_GPL(smscore_start_device);
static int smscore_sendrequest_and_wait(struct smscore_device_t *coredev,
void *buffer, size_t size,
@@ -688,6 +695,7 @@ void smscore_unregister_device(struct smscore_device_t *coredev)
sms_info("device %p destroyed", coredev);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_device);
static int smscore_detect_mode(struct smscore_device_t *coredev)
{
@@ -732,7 +740,7 @@ static char *smscore_fw_lkup[][SMS_NUM_OF_DEVICE_TYPES] = {
/*DVBH*/
{"none", "dvb_nova_12mhz.inp", "dvb_nova_12mhz_b0.inp", "none"},
/*TDMB*/
- {"none", "tdmb_nova_12mhz.inp", "none", "none"},
+ {"none", "tdmb_nova_12mhz.inp", "tdmb_nova_12mhz_b0.inp", "none"},
/*DABIP*/
{"none", "none", "none", "none"},
/*BDA*/
@@ -879,6 +887,7 @@ int smscore_get_device_mode(struct smscore_device_t *coredev)
{
return coredev->mode;
}
+EXPORT_SYMBOL_GPL(smscore_get_device_mode);
/**
* find client by response id & type within the clients list.
@@ -1006,6 +1015,7 @@ void smscore_onresponse(struct smscore_device_t *coredev,
smscore_putbuffer(coredev, cb);
}
}
+EXPORT_SYMBOL_GPL(smscore_onresponse);
/**
* return pointer to next free buffer descriptor from core pool
@@ -1031,6 +1041,7 @@ struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
return cb;
}
+EXPORT_SYMBOL_GPL(smscore_getbuffer);
/**
* return buffer descriptor to a pool
@@ -1045,6 +1056,7 @@ void smscore_putbuffer(struct smscore_device_t *coredev,
{
list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock);
}
+EXPORT_SYMBOL_GPL(smscore_putbuffer);
static int smscore_validate_client(struct smscore_device_t *coredev,
struct smscore_client_t *client,
@@ -1124,6 +1136,7 @@ int smscore_register_client(struct smscore_device_t *coredev,
return 0;
}
+EXPORT_SYMBOL_GPL(smscore_register_client);
/**
* frees smsclient object and all subclients associated with it
@@ -1154,6 +1167,7 @@ void smscore_unregister_client(struct smscore_client_t *client)
spin_unlock_irqrestore(&coredev->clientslock, flags);
}
+EXPORT_SYMBOL_GPL(smscore_unregister_client);
/**
* verifies that source id is not taken by another client,
@@ -1193,6 +1207,7 @@ int smsclient_sendrequest(struct smscore_client_t *client,
return coredev->sendrequest_handler(coredev->context, buffer, size);
}
+EXPORT_SYMBOL_GPL(smsclient_sendrequest);
int smscore_configure_gpio(struct smscore_device_t *coredev, u32 pin,
@@ -1276,12 +1291,12 @@ static int __init smscore_module_init(void)
INIT_LIST_HEAD(&g_smscore_registry);
kmutex_init(&g_smscore_registrylock);
- /* USB Register */
- rc = smsusb_register();
- /* DVB Register */
- rc = smsdvb_register();
+
+
+
+ return rc;
sms_debug("rc %d", rc);
return rc;
@@ -1290,6 +1305,10 @@ static int __init smscore_module_init(void)
static void __exit smscore_module_exit(void)
{
+
+
+
+
kmutex_lock(&g_smscore_deviceslock);
while (!list_empty(&g_smscore_notifyees)) {
struct smscore_device_notifyee_t *notifyee =
@@ -1312,18 +1331,12 @@ static void __exit smscore_module_exit(void)
}
kmutex_unlock(&g_smscore_registrylock);
- /* DVB UnRegister */
- smsdvb_unregister();
-
- /* Unregister USB */
- smsusb_unregister();
-
sms_debug("");
}
module_init(smscore_module_init);
module_exit(smscore_module_exit);
-MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
-MODULE_AUTHOR("Siano Mobile Silicon,,, (doronc@siano-ms.com)");
+MODULE_DESCRIPTION("Siano MDTV Core module");
+MODULE_AUTHOR("Siano Mobile Silicon, Inc. (uris@siano-ms.com)");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smscoreapi.h b/drivers/media/dvb/siano/smscoreapi.h
index 760e233fcbc..548de9056e8 100644
--- a/drivers/media/dvb/siano/smscoreapi.h
+++ b/drivers/media/dvb/siano/smscoreapi.h
@@ -29,13 +29,13 @@
#include <linux/scatterlist.h>
#include <linux/types.h>
#include <asm/page.h>
+#include <linux/mutex.h>
#include "dmxdev.h"
#include "dvbdev.h"
#include "dvb_demux.h"
#include "dvb_frontend.h"
-#include <linux/mutex.h>
#define kmutex_init(_p_) mutex_init(_p_)
#define kmutex_lock(_p_) mutex_lock(_p_)
@@ -369,27 +369,6 @@ struct smscore_gpio_config {
u8 outputdriving;
};
-struct smsdvb_client_t {
- struct list_head entry;
-
- struct smscore_device_t *coredev;
- struct smscore_client_t *smsclient;
-
- struct dvb_adapter adapter;
- struct dvb_demux demux;
- struct dmxdev dmxdev;
- struct dvb_frontend frontend;
-
- fe_status_t fe_status;
- int fe_ber, fe_snr, fe_unc, fe_signal_strength;
-
- struct completion tune_done, stat_done;
-
- /* todo: save freq/band instead whole struct */
- struct dvb_frontend_parameters fe_params;
-
-};
-
extern void smscore_registry_setmode(char *devpath, int mode);
extern int smscore_registry_getmode(char *devpath);
@@ -418,6 +397,13 @@ extern int smsclient_sendrequest(struct smscore_client_t *client,
extern void smscore_onresponse(struct smscore_device_t *coredev,
struct smscore_buffer_t *cb);
+extern int smscore_get_common_buffer_size(struct smscore_device_t *coredev);
+extern int smscore_map_common_buffer(struct smscore_device_t *coredev,
+ struct vm_area_struct *vma);
+extern int smscore_get_fw_filename(struct smscore_device_t *coredev,
+ int mode, char *filename);
+extern int smscore_send_fw_file(struct smscore_device_t *coredev,
+ u8 *ufwbuf, int size);
extern
struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev);
@@ -433,18 +419,9 @@ int smscore_get_board_id(struct smscore_device_t *core);
int smscore_led_state(struct smscore_device_t *core, int led);
-/* smsdvb.c */
-int smsdvb_register(void);
-void smsdvb_unregister(void);
-
-/* smsusb.c */
-int smsusb_register(void);
-void smsusb_unregister(void);
/* ------------------------------------------------------------------------ */
-extern int sms_debug;
-
#define DBG_INFO 1
#define DBG_ADV 2
@@ -452,7 +429,7 @@ extern int sms_debug;
printk(kern "%s: " fmt "\n", __func__, ##arg)
#define dprintk(kern, lvl, fmt, arg...) do {\
- if (sms_debug & lvl) \
+ if (sms_dbg & lvl) \
sms_printk(kern, fmt, ##arg); } while (0)
#define sms_log(fmt, arg...) sms_printk(KERN_INFO, fmt, ##arg)
diff --git a/drivers/media/dvb/siano/smsdvb.c b/drivers/media/dvb/siano/smsdvb.c
index 2da953a4f4f..ba080b95bef 100644
--- a/drivers/media/dvb/siano/smsdvb.c
+++ b/drivers/media/dvb/siano/smsdvb.c
@@ -1,7 +1,7 @@
/*
* Driver for the Siano SMS1xxx USB dongle
*
- * author: Anatoly Greenblat
+ * Author: Uri Shkolni
*
* Copyright (c), 2005-2008 Siano Mobile Silicon, Inc.
*
@@ -27,9 +27,33 @@
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
+struct smsdvb_client_t {
+ struct list_head entry;
+
+ struct smscore_device_t *coredev;
+ struct smscore_client_t *smsclient;
+
+ struct dvb_adapter adapter;
+ struct dvb_demux demux;
+ struct dmxdev dmxdev;
+ struct dvb_frontend frontend;
+
+ fe_status_t fe_status;
+ int fe_ber, fe_snr, fe_unc, fe_signal_strength;
+
+ struct completion tune_done, stat_done;
+
+ /* todo: save freq/band instead whole struct */
+ struct dvb_frontend_parameters fe_params;
+};
+
static struct list_head g_smsdvb_clients;
static struct mutex g_smsdvb_clientslock;
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
@@ -262,6 +286,7 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
struct SmsMsgHdr_ST Msg;
u32 Data[3];
} Msg;
+ int ret;
Msg.Msg.msgSrcId = DVBT_BDA_CONTROL_MSG_ID;
Msg.Msg.msgDstId = HIF_TASK;
@@ -282,6 +307,24 @@ static int smsdvb_set_frontend(struct dvb_frontend *fe,
default: return -EINVAL;
}
+ /* Disable LNA, if any. An error is returned if no LNA is present */
+ ret = sms_board_lna_control(client->coredev, 0);
+ if (ret == 0) {
+ fe_status_t status;
+
+ /* tune with LNA off at first */
+ ret = smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
+ &client->tune_done);
+
+ smsdvb_read_status(fe, &status);
+
+ if (status & FE_HAS_LOCK)
+ return ret;
+
+ /* previous tune didnt lock - enable LNA and tune again */
+ sms_board_lna_control(client->coredev, 1);
+ }
+
return smsdvb_sendrequest_and_wait(client, &Msg, sizeof(Msg),
&client->tune_done);
}
@@ -329,7 +372,7 @@ static void smsdvb_release(struct dvb_frontend *fe)
static struct dvb_frontend_ops smsdvb_fe_ops = {
.info = {
- .name = "Siano Mobile Digital SMS1xxx",
+ .name = "Siano Mobile Digital MDTV Receiver",
.type = FE_OFDM,
.frequency_min = 44250000,
.frequency_max = 867250000,
@@ -371,7 +414,7 @@ static int smsdvb_hotplug(struct smscore_device_t *coredev,
if (!arrival)
return 0;
- if (smscore_get_device_mode(coredev) != 4) {
+ if (smscore_get_device_mode(coredev) != DEVICE_MODE_DVBT_BDA) {
sms_err("SMS Device mode is not set for "
"DVB operation.");
return 0;
@@ -473,7 +516,7 @@ adapter_error:
return rc;
}
-int smsdvb_register(void)
+int smsdvb_module_init(void)
{
int rc;
@@ -487,7 +530,7 @@ int smsdvb_register(void)
return rc;
}
-void smsdvb_unregister(void)
+void smsdvb_module_exit(void)
{
smscore_unregister_hotplug(smsdvb_hotplug);
@@ -499,3 +542,10 @@ void smsdvb_unregister(void)
kmutex_unlock(&g_smsdvb_clientslock);
}
+
+module_init(smsdvb_module_init);
+module_exit(smsdvb_module_exit);
+
+MODULE_DESCRIPTION("SMS DVB subsystem adaptation module");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c
index 5d7ca341771..71c65f544c0 100644
--- a/drivers/media/dvb/siano/smsusb.c
+++ b/drivers/media/dvb/siano/smsusb.c
@@ -27,6 +27,10 @@
#include "smscoreapi.h"
#include "sms-cards.h"
+static int sms_dbg;
+module_param_named(debug, sms_dbg, int, 0644);
+MODULE_PARM_DESC(debug, "set debug level (info=1, adv=2 (or-able))");
+
#define USB1_BUFFER_SIZE 0x1000
#define USB2_BUFFER_SIZE 0x4000
@@ -424,6 +428,7 @@ static int smsusb_probe(struct usb_interface *intf,
rc = smsusb_init_device(intf, id->driver_info);
sms_info("rc %d", rc);
+ sms_board_load_modules(id->driver_info);
return rc;
}
@@ -436,7 +441,7 @@ static int smsusb_suspend(struct usb_interface *intf, pm_message_t msg)
{
struct smsusb_device_t *dev =
(struct smsusb_device_t *)usb_get_intfdata(intf);
- printk(KERN_INFO "%s Entering status %d.\n", __func__, msg.event);
+ printk(KERN_INFO "%s: Entering status %d.\n", __func__, msg.event);
smsusb_stop_streaming(dev);
return 0;
}
@@ -448,7 +453,7 @@ static int smsusb_resume(struct usb_interface *intf)
(struct smsusb_device_t *)usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf);
- printk(KERN_INFO "%s Entering.\n", __func__);
+ printk(KERN_INFO "%s: Entering.\n", __func__);
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x81));
usb_clear_halt(udev, usb_rcvbulkpipe(udev, 0x02));
@@ -463,9 +468,8 @@ static int smsusb_resume(struct usb_interface *intf)
intf->cur_altsetting->desc.
bInterfaceNumber, 0);
if (rc < 0) {
- printk(KERN_INFO
- "%s usb_set_interface failed, rc %d\n",
- __func__, rc);
+ printk(KERN_INFO "%s usb_set_interface failed, "
+ "rc %d\n", __func__, rc);
return rc;
}
}
@@ -474,8 +478,55 @@ static int smsusb_resume(struct usb_interface *intf)
return 0;
}
+struct usb_device_id smsusb_id_table[] = {
+#ifdef CONFIG_DVB_SIANO_SMS1XXX_SMS_IDS
+ { USB_DEVICE(0x187f, 0x0010),
+ .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+ { USB_DEVICE(0x187f, 0x0100),
+ .driver_info = SMS1XXX_BOARD_SIANO_STELLAR },
+ { USB_DEVICE(0x187f, 0x0200),
+ .driver_info = SMS1XXX_BOARD_SIANO_NOVA_A },
+ { USB_DEVICE(0x187f, 0x0201),
+ .driver_info = SMS1XXX_BOARD_SIANO_NOVA_B },
+ { USB_DEVICE(0x187f, 0x0300),
+ .driver_info = SMS1XXX_BOARD_SIANO_VEGA },
+#endif
+ { USB_DEVICE(0x2040, 0x1700),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_CATAMOUNT },
+ { USB_DEVICE(0x2040, 0x1800),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_A },
+ { USB_DEVICE(0x2040, 0x1801),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_OKEMO_B },
+ { USB_DEVICE(0x2040, 0x2000),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2009),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD_R2 },
+ { USB_DEVICE(0x2040, 0x200a),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2010),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2011),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x2019),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_TIGER_MINICARD },
+ { USB_DEVICE(0x2040, 0x5500),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5510),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5520),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5530),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5580),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { USB_DEVICE(0x2040, 0x5590),
+ .driver_info = SMS1XXX_BOARD_HAUPPAUGE_WINDHAM },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, smsusb_id_table);
+
static struct usb_driver smsusb_driver = {
- .name = "sms1xxx",
+ .name = "smsusb",
.probe = smsusb_probe,
.disconnect = smsusb_disconnect,
.id_table = smsusb_id_table,
@@ -484,7 +535,7 @@ static struct usb_driver smsusb_driver = {
.resume = smsusb_resume,
};
-int smsusb_register(void)
+int smsusb_module_init(void)
{
int rc = usb_register(&smsusb_driver);
if (rc)
@@ -495,10 +546,16 @@ int smsusb_register(void)
return rc;
}
-void smsusb_unregister(void)
+void smsusb_module_exit(void)
{
sms_debug("");
/* Regular USB Cleanup */
usb_deregister(&smsusb_driver);
}
+module_init(smsusb_module_init);
+module_exit(smsusb_module_exit);
+
+MODULE_DESCRIPTION("Driver for the Siano SMS1XXX USB dongle");
+MODULE_AUTHOR("Siano Mobile Silicon, INC. (uris@siano-ms.com)");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/ttpci/Kconfig b/drivers/media/dvb/ttpci/Kconfig
index ab0bcd208c7..772990415f9 100644
--- a/drivers/media/dvb/ttpci/Kconfig
+++ b/drivers/media/dvb/ttpci/Kconfig
@@ -108,7 +108,7 @@ config DVB_BUDGET_CI
select DVB_STB6100 if !DVB_FE_CUSTOMISE
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_TDA10023 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
select VIDEO_IR
help
Support for simple SAA7146 based DVB cards
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c
index aa1ff524256..4624cee93e7 100644
--- a/drivers/media/dvb/ttpci/av7110.c
+++ b/drivers/media/dvb/ttpci/av7110.c
@@ -725,7 +725,7 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file,
}
-static struct file_operations dvb_osd_fops = {
+static const struct file_operations dvb_osd_fops = {
.owner = THIS_MODULE,
.ioctl = dvb_generic_ioctl,
.open = dvb_generic_open,
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c
index bdc62acf209..e4d0900d512 100644
--- a/drivers/media/dvb/ttpci/av7110_av.c
+++ b/drivers/media/dvb/ttpci/av7110_av.c
@@ -1456,7 +1456,7 @@ static int dvb_audio_release(struct inode *inode, struct file *file)
* driver registration
******************************************************************************/
-static struct file_operations dvb_video_fops = {
+static const struct file_operations dvb_video_fops = {
.owner = THIS_MODULE,
.write = dvb_video_write,
.ioctl = dvb_generic_ioctl,
@@ -1474,7 +1474,7 @@ static struct dvb_device dvbdev_video = {
.kernel_ioctl = dvb_video_ioctl,
};
-static struct file_operations dvb_audio_fops = {
+static const struct file_operations dvb_audio_fops = {
.owner = THIS_MODULE,
.write = dvb_audio_write,
.ioctl = dvb_generic_ioctl,
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c
index 261135ded48..c7a65b1544a 100644
--- a/drivers/media/dvb/ttpci/av7110_ca.c
+++ b/drivers/media/dvb/ttpci/av7110_ca.c
@@ -345,7 +345,7 @@ static ssize_t dvb_ca_read(struct file *file, char __user *buf,
return ci_ll_read(&av7110->ci_rbuffer, file, buf, count, ppos);
}
-static struct file_operations dvb_ca_fops = {
+static const struct file_operations dvb_ca_fops = {
.owner = THIS_MODULE,
.read = dvb_ca_read,
.write = dvb_ca_write,
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c
index c5b9c70563d..2210cff738e 100644
--- a/drivers/media/dvb/ttpci/av7110_v4l.c
+++ b/drivers/media/dvb/ttpci/av7110_v4l.c
@@ -316,253 +316,261 @@ static int av7110_dvb_c_switch(struct saa7146_fh *fh)
return 0;
}
-static long av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
{
- struct saa7146_dev *dev = fh->dev;
- struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
- dprintk(4, "saa7146_dev: %p\n", dev);
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 stereo_det;
+ s8 stereo;
- switch (cmd) {
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- u16 stereo_det;
- s8 stereo;
+ dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
- dprintk(2, "VIDIOC_G_TUNER: %d\n", t->index);
+ if (!av7110->analog_tuner_flags || t->index != 0)
+ return -EINVAL;
- if (!av7110->analog_tuner_flags || t->index != 0)
- return -EINVAL;
+ memset(t, 0, sizeof(*t));
+ strcpy((char *)t->name, "Television");
+
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+ t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
+ t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
+ /* FIXME: add the real signal strength here */
+ t->signal = 0xffff;
+ t->afc = 0;
+
+ /* FIXME: standard / stereo detection is still broken */
+ msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
+ msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
+ dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
+ stereo = (s8)(stereo_det >> 8);
+ if (stereo > 0x10) {
+ /* stereo */
+ t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
+ t->audmode = V4L2_TUNER_MODE_STEREO;
+ } else if (stereo < -0x10) {
+ /* bilingual */
+ t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+ t->audmode = V4L2_TUNER_MODE_LANG1;
+ } else /* mono */
+ t->rxsubchans = V4L2_TUNER_SUB_MONO;
- memset(t, 0, sizeof(*t));
- strcpy((char *)t->name, "Television");
-
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
- t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
- /* FIXME: add the real signal strength here */
- t->signal = 0xffff;
- t->afc = 0;
-
- // FIXME: standard / stereo detection is still broken
- msp_readreg(av7110, MSP_RD_DEM, 0x007e, &stereo_det);
- dprintk(1, "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n", stereo_det);
- msp_readreg(av7110, MSP_RD_DSP, 0x0018, &stereo_det);
- dprintk(1, "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n", stereo_det);
- stereo = (s8)(stereo_det >> 8);
- if (stereo > 0x10) {
- /* stereo */
- t->rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO;
- t->audmode = V4L2_TUNER_MODE_STEREO;
- }
- else if (stereo < -0x10) {
- /* bilingual */
- t->rxsubchans = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
- t->audmode = V4L2_TUNER_MODE_LANG1;
- }
- else /* mono */
- t->rxsubchans = V4L2_TUNER_SUB_MONO;
+ return 0;
+}
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
- u16 fm_matrix, src;
- dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+ u16 fm_matrix, src;
+ dprintk(2, "VIDIOC_S_TUNER: %d\n", t->index);
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- switch (t->audmode) {
- case V4L2_TUNER_MODE_STEREO:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
- 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
- src = 0x0000;
- break;
- case V4L2_TUNER_MODE_LANG2:
- dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
- fm_matrix = 0x3000; // mono
- src = 0x0010;
- break;
- default: /* case V4L2_TUNER_MODE_MONO: */
- dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
- fm_matrix = 0x3000; // mono
- src = 0x0030;
- break;
- }
- msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
- msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
- msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
- msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
- return 0;
+ switch (t->audmode) {
+ case V4L2_TUNER_MODE_STEREO:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_STEREO\n");
+ 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 */
+ src = 0x0000;
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ dprintk(2, "VIDIOC_S_TUNER: V4L2_TUNER_MODE_LANG2\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0010;
+ break;
+ default: /* case V4L2_TUNER_MODE_MONO: */
+ dprintk(2, "VIDIOC_S_TUNER: TDA9840_SET_MONO\n");
+ fm_matrix = 0x3000; /* mono */
+ src = 0x0030;
+ break;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ msp_writereg(av7110, MSP_WR_DSP, 0x000e, fm_matrix);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0008, src);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0009, src);
+ msp_writereg(av7110, MSP_WR_DSP, 0x000a, src);
+ return 0;
+}
- dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+ dprintk(2, "VIDIOC_G_FREQ: freq:0x%08x.\n", f->frequency);
- memset(f, 0, sizeof(*f));
- f->type = V4L2_TUNER_ANALOG_TV;
- f->frequency = av7110->current_freq;
- return 0;
- }
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
+ memset(f, 0, sizeof(*f));
+ f->type = V4L2_TUNER_ANALOG_TV;
+ f->frequency = av7110->current_freq;
+ return 0;
+}
- if (!av7110->analog_tuner_flags || av7110->current_input != 1)
- return -EINVAL;
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+ dprintk(2, "VIDIOC_S_FREQUENCY: freq:0x%08x.\n", f->frequency);
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); // fast mute
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
+ if (!av7110->analog_tuner_flags || av7110->current_input != 1)
+ return -EINVAL;
- /* tune in desired frequency */
- if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820) {
- ves1820_set_tv_freq(dev, f->frequency);
- } else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297) {
- stv0297_set_tv_freq(dev, f->frequency);
- }
- av7110->current_freq = f->frequency;
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); // start stereo detection
- msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
- msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); // loudspeaker + headphone
- msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); // SCART 1 volume
- return 0;
- }
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0xffe0); /* fast mute */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0xffe0);
- dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+ /* tune in desired frequency */
+ if (av7110->analog_tuner_flags & ANALOG_TUNER_VES1820)
+ ves1820_set_tv_freq(dev, f->frequency);
+ else if (av7110->analog_tuner_flags & ANALOG_TUNER_STV0297)
+ stv0297_set_tv_freq(dev, f->frequency);
+ av7110->current_freq = f->frequency;
- if (av7110->analog_tuner_flags) {
- if (i->index < 0 || i->index >= 4)
- return -EINVAL;
- } else {
- if (i->index != 0)
- return -EINVAL;
- }
+ msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x003f); /* start stereo detection */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0015, 0x0000);
+ msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x4f00); /* loudspeaker + headphone */
+ msp_writereg(av7110, MSP_WR_DSP, 0x0007, 0x4f00); /* SCART 1 volume */
+ return 0;
+}
- memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
- return 0;
+ dprintk(2, "VIDIOC_ENUMINPUT: %d\n", i->index);
+
+ if (av7110->analog_tuner_flags) {
+ if (i->index < 0 || i->index >= 4)
+ return -EINVAL;
+ } else {
+ if (i->index != 0)
+ return -EINVAL;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = av7110->current_input;
- dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+
+ memcpy(i, &inputs[i->index], sizeof(struct v4l2_input));
+
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ *input = av7110->current_input;
+ dprintk(2, "VIDIOC_G_INPUT: %d\n", *input);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+
+ if (!av7110->analog_tuner_flags)
return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- dprintk(2, "VIDIOC_S_INPUT: %d\n", input);
+ if (input < 0 || input >= 4)
+ return -EINVAL;
- if (!av7110->analog_tuner_flags)
- return 0;
+ av7110->current_input = input;
+ return av7110_dvb_c_switch(fh);
+}
- if (input < 0 || input >= 4)
- return -EINVAL;
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
+ if (a->index != 0)
+ return -EINVAL;
+ memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
+ return 0;
+}
- av7110->current_input = input;
- return av7110_dvb_c_switch(fh);
- }
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
+ return 0;
+}
- dprintk(2, "VIDIOC_G_AUDIO: %d\n", a->index);
- if (a->index != 0)
- return -EINVAL;
- memcpy(a, &msp3400_v4l2_audio, sizeof(struct v4l2_audio));
- break;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *a = arg;
- dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
- break;
- }
- case VIDIOC_G_SLICED_VBI_CAP:
- {
- struct v4l2_sliced_vbi_cap *cap = arg;
- dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
- memset(cap, 0, sizeof *cap);
- if (FW_VERSION(av7110->arm_app) >= 0x2623) {
- cap->service_set = V4L2_SLICED_WSS_625;
- cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
- }
- break;
- }
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
- dprintk(2, "VIDIOC_G_FMT:\n");
- if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
- FW_VERSION(av7110->arm_app) < 0x2623)
- return -EAGAIN; /* handled by core driver */
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- if (av7110->wssMode) {
- f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
- f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
- f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
- }
- break;
+static int vidioc_g_sliced_vbi_cap(struct file *file, void *fh,
+ struct v4l2_sliced_vbi_cap *cap)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
+ if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
+ return -EINVAL;
+ if (FW_VERSION(av7110->arm_app) >= 0x2623) {
+ cap->service_set = V4L2_SLICED_WSS_625;
+ cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
- dprintk(2, "VIDIOC_S_FMT\n");
- if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
- FW_VERSION(av7110->arm_app) < 0x2623)
- return -EAGAIN; /* handled by core driver */
- if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
- f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- /* WSS controlled by firmware */
- av7110->wssMode = 0;
- av7110->wssData = 0;
- return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
- SetWSSConfig, 1, 0);
- } else {
- memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
- f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
- f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
- f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
- /* WSS controlled by userspace */
- av7110->wssMode = 1;
- av7110->wssData = 0;
- }
- break;
+ return 0;
+}
+
+static int vidioc_g_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_G_FMT:\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
+ if (av7110->wssMode) {
+ f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
}
- default:
- printk("no such ioctl\n");
- return -ENOIOCTLCMD;
+ return 0;
+}
+
+static int vidioc_s_fmt_sliced_vbi_out(struct file *file, void *fh,
+ struct v4l2_format *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
+
+ dprintk(2, "VIDIOC_S_FMT\n");
+ if (FW_VERSION(av7110->arm_app) < 0x2623)
+ return -EINVAL;
+ if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
+ f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
+ memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+ /* WSS controlled by firmware */
+ av7110->wssMode = 0;
+ av7110->wssData = 0;
+ return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
+ SetWSSConfig, 1, 0);
+ } else {
+ memset(&f->fmt.sliced, 0, sizeof(f->fmt.sliced));
+ f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
+ f->fmt.sliced.io_size = sizeof(struct v4l2_sliced_vbi_data);
+ /* WSS controlled by userspace */
+ av7110->wssMode = 1;
+ av7110->wssData = 0;
}
return 0;
}
@@ -609,22 +617,6 @@ static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size
* INITIALIZATION
****************************************************************************/
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FMT, SAA7146_BEFORE },
- { VIDIOC_S_FMT, SAA7146_BEFORE },
- { 0, 0 }
-};
-
static u8 saa7113_init_regs[] = {
0x02, 0xd0,
0x03, 0x23,
@@ -788,20 +780,34 @@ int av7110_init_analog_module(struct av7110 *av7110)
int av7110_init_v4l(struct av7110 *av7110)
{
struct saa7146_dev* dev = av7110->dev;
+ struct saa7146_ext_vv *vv_data;
int ret;
/* special case DVB-C: these cards have an analog tuner
plus need some special handling, so we have separate
saa7146_ext_vv data for these... */
if (av7110->analog_tuner_flags)
- ret = saa7146_vv_init(dev, &av7110_vv_data_c);
+ vv_data = &av7110_vv_data_c;
else
- ret = saa7146_vv_init(dev, &av7110_vv_data_st);
+ vv_data = &av7110_vv_data_st;
+ ret = saa7146_vv_init(dev, vv_data);
if (ret) {
ERR(("cannot init capture device. skipping.\n"));
return -ENODEV;
}
+ vv_data->ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data->ops.vidioc_g_input = vidioc_g_input;
+ vv_data->ops.vidioc_s_input = vidioc_s_input;
+ vv_data->ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data->ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data->ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data->ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data->ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data->ops.vidioc_s_audio = vidioc_s_audio;
+ vv_data->ops.vidioc_g_sliced_vbi_cap = vidioc_g_sliced_vbi_cap;
+ vv_data->ops.vidioc_g_fmt_sliced_vbi_out = vidioc_g_fmt_sliced_vbi_out;
+ vv_data->ops.vidioc_s_fmt_sliced_vbi_out = vidioc_s_fmt_sliced_vbi_out;
if (saa7146_register_device(&av7110->v4l_dev, dev, "av7110", VFL_TYPE_GRABBER)) {
ERR(("cannot register capture device. skipping.\n"));
@@ -900,9 +906,6 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = av7110_ioctl,
-
.vbi_fops.open = av7110_vbi_reset,
.vbi_fops.release = av7110_vbi_reset,
.vbi_fops.write = av7110_vbi_write,
@@ -918,9 +921,6 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
.num_stds = ARRAY_SIZE(standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = av7110_ioctl,
-
.vbi_fops.open = av7110_vbi_reset,
.vbi_fops.release = av7110_vbi_reset,
.vbi_fops.write = av7110_vbi_write,
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 4182121d7e5..855fe74b640 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -1404,6 +1404,41 @@ static int budget_av_detach(struct saa7146_dev *dev)
return err;
}
+#define KNC1_INPUTS 2
+static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
+ {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+ {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
+};
+
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
+ if (i->index < 0 || i->index >= KNC1_INPUTS)
+ return -EINVAL;
+ memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ *i = budget_av->cur_input;
+
+ dprintk(1, "VIDIOC_G_INPUT %d.\n", *i);
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
+
+ dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
+ return saa7113_setinput(budget_av, input);
+}
+
static struct saa7146_ext_vv vv_data;
static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
@@ -1442,6 +1477,9 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
ERR(("cannot init vv subsystem.\n"));
return err;
}
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
/* fixme: proper cleanup here */
@@ -1480,54 +1518,6 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio
return 0;
}
-#define KNC1_INPUTS 2
-static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
- {0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
- {1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG | V4L2_STD_NTSC_M, 0},
-};
-
-static struct saa7146_extension_ioctls ioctls[] = {
- {VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE},
- {VIDIOC_G_INPUT, SAA7146_EXCLUSIVE},
- {VIDIOC_S_INPUT, SAA7146_EXCLUSIVE},
- {0, 0}
-};
-
-static long av_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
-{
- struct saa7146_dev *dev = fh->dev;
- struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
-
- switch (cmd) {
- case VIDIOC_ENUMINPUT:{
- struct v4l2_input *i = arg;
-
- dprintk(1, "VIDIOC_ENUMINPUT %d.\n", i->index);
- if (i->index < 0 || i->index >= KNC1_INPUTS) {
- return -EINVAL;
- }
- memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
- }
- case VIDIOC_G_INPUT:{
- int *input = (int *) arg;
-
- *input = budget_av->cur_input;
-
- dprintk(1, "VIDIOC_G_INPUT %d.\n", *input);
- return 0;
- }
- case VIDIOC_S_INPUT:{
- int input = *(int *) arg;
- dprintk(1, "VIDIOC_S_INPUT %d.\n", input);
- return saa7113_setinput(budget_av, input);
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static struct saa7146_standard standard[] = {
{.name = "PAL",.id = V4L2_STD_PAL,
.v_offset = 0x17,.v_field = 288,
@@ -1546,8 +1536,6 @@ static struct saa7146_ext_vv vv_data = {
.flags = 0,
.stds = &standard[0],
.num_stds = ARRAY_SIZE(standard),
- .ioctls = &ioctls[0],
- .ioctl = av_ioctl,
};
static struct saa7146_extension budget_extension;
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index bcbc5d41a0f..371a7161681 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -1076,6 +1076,10 @@ static struct tda10023_config tda10023_config = {
.deltaf = 0xa511,
};
+static struct tda827x_config tda827x_config = {
+ .config = 0,
+};
+
/* TT S2-3200 DVB-S (STB0899) Inittab */
static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
@@ -1414,7 +1418,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
if (budget_ci->budget.dvb_frontend) {
- if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
+ if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
printk(KERN_ERR "%s: No tda827x found!\n", __func__);
dvb_frontend_detach(budget_ci->budget.dvb_frontend);
budget_ci->budget.dvb_frontend = NULL;
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index 2014ebc4e98..cc54ed4efc4 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -390,9 +390,11 @@ static void usb_dsbr100_disconnect(struct usb_interface *intf)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct dsbr100_device *radio = video_drvdata(file);
+
strlcpy(v->driver, "dsbr100", sizeof(v->driver));
strlcpy(v->card, "D-Link R-100 USB FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "USB");
+ usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER;
return 0;
@@ -450,7 +452,10 @@ static int vidioc_s_frequency(struct file *file, void *priv,
if (radio->removed)
return -EIO;
+ mutex_lock(&radio->lock);
radio->curfreq = f->frequency;
+ mutex_unlock(&radio->lock);
+
retval = dsbr100_setfreq(radio, radio->curfreq);
if (retval < 0)
dev_warn(&radio->usbdev->dev, "Set frequency failed\n");
@@ -601,7 +606,10 @@ static int usb_dsbr100_close(struct file *file)
if (!radio)
return -ENODEV;
+ mutex_lock(&radio->lock);
radio->users = 0;
+ mutex_unlock(&radio->lock);
+
if (!radio->removed) {
retval = dsbr100_stop(radio);
if (retval < 0) {
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c
index bfa13b8b304..ac82e33cb6f 100644
--- a/drivers/media/radio/radio-aimslab.c
+++ b/drivers/media/radio/radio-aimslab.c
@@ -32,14 +32,15 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("M.Kirkwood");
+MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_RTRACK_PORT
#define CONFIG_RADIO_RTRACK_PORT -1
@@ -47,86 +48,95 @@
static int io = CONFIG_RADIO_RTRACK_PORT;
static int radio_nr = -1;
-static struct mutex lock;
-struct rt_device
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct rtrack
{
- unsigned long in_use;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
int port;
int curvol;
unsigned long curfreq;
int muted;
+ int io;
+ struct mutex lock;
};
+static struct rtrack rtrack_card;
/* local things */
static void sleep_delay(long n)
{
/* Sleep nicely for 'n' uS */
- int d=n/msecs_to_jiffies(1000);
- if(!d)
+ int d = n / msecs_to_jiffies(1000);
+ if (!d)
udelay(n);
else
msleep(jiffies_to_msecs(d));
}
-static void rt_decvol(void)
+static void rt_decvol(struct rtrack *rt)
{
- outb(0x58, io); /* volume down + sigstr + on */
+ outb(0x58, rt->io); /* volume down + sigstr + on */
sleep_delay(100000);
- outb(0xd8, io); /* volume steady + sigstr + on */
+ outb(0xd8, rt->io); /* volume steady + sigstr + on */
}
-static void rt_incvol(void)
+static void rt_incvol(struct rtrack *rt)
{
- outb(0x98, io); /* volume up + sigstr + on */
+ outb(0x98, rt->io); /* volume up + sigstr + on */
sleep_delay(100000);
- outb(0xd8, io); /* volume steady + sigstr + on */
+ outb(0xd8, rt->io); /* volume steady + sigstr + on */
}
-static void rt_mute(struct rt_device *dev)
+static void rt_mute(struct rtrack *rt)
{
- dev->muted = 1;
- mutex_lock(&lock);
- outb(0xd0, io); /* volume steady, off */
- mutex_unlock(&lock);
+ rt->muted = 1;
+ mutex_lock(&rt->lock);
+ outb(0xd0, rt->io); /* volume steady, off */
+ mutex_unlock(&rt->lock);
}
-static int rt_setvol(struct rt_device *dev, int vol)
+static int rt_setvol(struct rtrack *rt, int vol)
{
int i;
- mutex_lock(&lock);
+ mutex_lock(&rt->lock);
- if(vol == dev->curvol) { /* requested volume = current */
- if (dev->muted) { /* user is unmuting the card */
- dev->muted = 0;
- outb (0xd8, io); /* enable card */
+ if (vol == rt->curvol) { /* requested volume = current */
+ if (rt->muted) { /* user is unmuting the card */
+ rt->muted = 0;
+ outb(0xd8, rt->io); /* enable card */
}
- mutex_unlock(&lock);
+ mutex_unlock(&rt->lock);
return 0;
}
- if(vol == 0) { /* volume = 0 means mute the card */
- outb(0x48, io); /* volume down but still "on" */
+ if (vol == 0) { /* volume = 0 means mute the card */
+ outb(0x48, rt->io); /* volume down but still "on" */
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);
+ outb(0xd0, rt->io); /* volume steady, off */
+ rt->curvol = 0; /* track the volume state! */
+ mutex_unlock(&rt->lock);
return 0;
}
- dev->muted = 0;
- if(vol > dev->curvol)
- for(i = dev->curvol; i < vol; i++)
- rt_incvol();
+ rt->muted = 0;
+ if (vol > rt->curvol)
+ for (i = rt->curvol; i < vol; i++)
+ rt_incvol(rt);
else
- for(i = dev->curvol; i > vol; i--)
- rt_decvol();
+ for (i = rt->curvol; i > vol; i--)
+ rt_decvol(rt);
- dev->curvol = vol;
- mutex_unlock(&lock);
+ rt->curvol = vol;
+ mutex_unlock(&rt->lock);
return 0;
}
@@ -135,155 +145,137 @@ static int rt_setvol(struct rt_device *dev, int vol)
* and bit 4 (+16) is to keep the signal strength meter enabled
*/
-static void send_0_byte(int port, struct rt_device *dev)
+static void send_0_byte(struct rtrack *rt)
{
- if ((dev->curvol == 0) || (dev->muted)) {
- outb_p(128+64+16+ 1, port); /* wr-enable + data low */
- outb_p(128+64+16+2+1, port); /* clock */
+ if (rt->curvol == 0 || rt->muted) {
+ outb_p(128+64+16+ 1, rt->io); /* wr-enable + data low */
+ outb_p(128+64+16+2+1, rt->io); /* clock */
}
else {
- outb_p(128+64+16+8+ 1, port); /* on + wr-enable + data low */
- outb_p(128+64+16+8+2+1, port); /* clock */
+ outb_p(128+64+16+8+ 1, rt->io); /* on + wr-enable + data low */
+ outb_p(128+64+16+8+2+1, rt->io); /* clock */
}
sleep_delay(1000);
}
-static void send_1_byte(int port, struct rt_device *dev)
+static void send_1_byte(struct rtrack *rt)
{
- if ((dev->curvol == 0) || (dev->muted)) {
- outb_p(128+64+16+4 +1, port); /* wr-enable+data high */
- outb_p(128+64+16+4+2+1, port); /* clock */
+ if (rt->curvol == 0 || rt->muted) {
+ outb_p(128+64+16+4 +1, rt->io); /* wr-enable+data high */
+ outb_p(128+64+16+4+2+1, rt->io); /* clock */
}
else {
- outb_p(128+64+16+8+4 +1, port); /* on+wr-enable+data high */
- outb_p(128+64+16+8+4+2+1, port); /* clock */
+ outb_p(128+64+16+8+4 +1, rt->io); /* on+wr-enable+data high */
+ outb_p(128+64+16+8+4+2+1, rt->io); /* clock */
}
sleep_delay(1000);
}
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+static int rt_setfreq(struct rtrack *rt, unsigned long freq)
{
int i;
- /* adapted from radio-aztech.c */
+ mutex_lock(&rt->lock); /* Stop other ops interfering */
+
+ rt->curfreq = freq;
/* now uses VIDEO_TUNER_LOW for fine tuning */
freq += 171200; /* Add 10.7 MHz IF */
freq /= 800; /* Convert to 50 kHz units */
- mutex_lock(&lock); /* Stop other ops interfering */
-
- send_0_byte (io, dev); /* 0: LSB of frequency */
+ send_0_byte(rt); /* 0: LSB of frequency */
for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
if (freq & (1 << i))
- send_1_byte (io, dev);
+ send_1_byte(rt);
else
- send_0_byte (io, dev);
+ send_0_byte(rt);
- send_0_byte (io, dev); /* 14: test bit - always 0 */
- send_0_byte (io, dev); /* 15: test bit - always 0 */
+ send_0_byte(rt); /* 14: test bit - always 0 */
+ send_0_byte(rt); /* 15: test bit - always 0 */
- send_0_byte (io, dev); /* 16: band data 0 - always 0 */
- send_0_byte (io, dev); /* 17: band data 1 - always 0 */
- send_0_byte (io, dev); /* 18: band data 2 - always 0 */
- send_0_byte (io, dev); /* 19: time base - always 0 */
+ send_0_byte(rt); /* 16: band data 0 - always 0 */
+ send_0_byte(rt); /* 17: band data 1 - always 0 */
+ send_0_byte(rt); /* 18: band data 2 - always 0 */
+ send_0_byte(rt); /* 19: time base - always 0 */
- send_0_byte (io, dev); /* 20: spacing (0 = 25 kHz) */
- send_1_byte (io, dev); /* 21: spacing (1 = 25 kHz) */
- send_0_byte (io, dev); /* 22: spacing (0 = 25 kHz) */
- send_1_byte (io, dev); /* 23: AM/FM (FM = 1, always) */
+ send_0_byte(rt); /* 20: spacing (0 = 25 kHz) */
+ send_1_byte(rt); /* 21: spacing (1 = 25 kHz) */
+ send_0_byte(rt); /* 22: spacing (0 = 25 kHz) */
+ send_1_byte(rt); /* 23: AM/FM (FM = 1, always) */
- if ((dev->curvol == 0) || (dev->muted))
- outb (0xd0, io); /* volume steady + sigstr */
+ if (rt->curvol == 0 || rt->muted)
+ outb(0xd0, rt->io); /* volume steady + sigstr */
else
- outb (0xd8, io); /* volume steady + sigstr + on */
+ outb(0xd8, rt->io); /* volume steady + sigstr + on */
- mutex_unlock(&lock);
+ mutex_unlock(&rt->lock);
return 0;
}
-static int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rtrack *rt)
{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
+ int sig = 1;
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+ mutex_lock(&rt->lock);
+ if (inb(rt->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&rt->lock);
+ return sig;
+}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
strlcpy(v->driver, "radio-aimslab", sizeof(v->driver));
strlcpy(v->card, "RadioTrack", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 87 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xffff*rt_getsigstr(rt);
+ v->signal = 0xffff * rt_getsigstr(rt);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
+ rt_setfreq(rt, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = rt->curfreq;
@@ -293,14 +285,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
}
return -EINVAL;
}
@@ -308,14 +297,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
ctrl->value = rt->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = rt->curvol * 6554;
+ ctrl->value = rt->curvol;
return 0;
}
return -EINVAL;
@@ -324,33 +313,22 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
rt_mute(rt);
else
- rt_setvol(rt,rt->curvol);
+ rt_setvol(rt, rt->curvol);
return 0;
case V4L2_CID_AUDIO_VOLUME:
- rt_setvol(rt,ctrl->value);
+ rt_setvol(rt, ctrl->value);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio (struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -359,36 +337,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct rt_device rtrack_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int rtrack_exclusive_open(struct file *file)
+static int rtrack_open(struct file *file)
{
- return test_and_set_bit(0, &rtrack_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int rtrack_exclusive_release(struct file *file)
+static int rtrack_release(struct file *file)
{
- clear_bit(0, &rtrack_unit.in_use);
return 0;
}
static const struct v4l2_file_operations rtrack_fops = {
.owner = THIS_MODULE,
- .open = rtrack_exclusive_open,
- .release = rtrack_exclusive_release,
+ .open = rtrack_open,
+ .release = rtrack_release,
.ioctl = video_ioctl2,
};
@@ -407,64 +387,69 @@ static const struct v4l2_ioctl_ops rtrack_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device rtrack_radio = {
- .name = "RadioTrack radio",
- .fops = &rtrack_fops,
- .ioctl_ops = &rtrack_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init rtrack_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct rtrack *rt = &rtrack_card;
+ struct v4l2_device *v4l2_dev = &rt->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "rtrack", sizeof(v4l2_dev->name));
+ rt->io = io;
+
+ if (rt->io == -1) {
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x20f or 0x30f\n");
return -EINVAL;
}
- if (!request_region(io, 2, "rtrack"))
- {
- printk(KERN_ERR "rtrack: port 0x%x already in use\n", io);
+ if (!request_region(rt->io, 2, "rtrack")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", rt->io);
return -EBUSY;
}
- video_set_drvdata(&rtrack_radio, &rtrack_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(rt->io, 2);
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
+ return res;
+ }
- if (video_register_device(&rtrack_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+ strlcpy(rt->vdev.name, v4l2_dev->name, sizeof(rt->vdev.name));
+ rt->vdev.v4l2_dev = v4l2_dev;
+ rt->vdev.fops = &rtrack_fops;
+ rt->vdev.ioctl_ops = &rtrack_ioctl_ops;
+ rt->vdev.release = video_device_release_empty;
+ video_set_drvdata(&rt->vdev, rt);
+
+ if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&rt->v4l2_dev);
+ release_region(rt->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "AIMSlab RadioTrack/RadioReveal card driver.\n");
+ v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n");
/* Set up the I/O locking */
- mutex_init(&lock);
+ mutex_init(&rt->lock);
/* mute card - prevents noisy bootups */
/* this ensures that the volume is all the way down */
- outb(0x48, io); /* volume down but still "on" */
+ outb(0x48, rt->io); /* volume down but still "on" */
sleep_delay(2000000); /* make sure it's totally down */
- outb(0xc0, io); /* steady volume, mute card */
- rtrack_unit.curvol = 0;
+ outb(0xc0, rt->io); /* steady volume, mute card */
return 0;
}
-MODULE_AUTHOR("M.Kirkwood");
-MODULE_DESCRIPTION("A driver for the RadioTrack/RadioReveal radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20f or 0x30f)");
-module_param(radio_nr, int, 0);
-
-static void __exit cleanup_rtrack_module(void)
+static void __exit rtrack_exit(void)
{
- video_unregister_device(&rtrack_radio);
- release_region(io,2);
+ struct rtrack *rt = &rtrack_card;
+
+ video_unregister_device(&rt->vdev);
+ v4l2_device_unregister(&rt->v4l2_dev);
+ release_region(rt->io, 2);
}
module_init(rtrack_init);
-module_exit(cleanup_rtrack_module);
+module_exit(rtrack_exit);
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c
index 5604e881e96..49299f7fd83 100644
--- a/drivers/media/radio/radio-aztech.c
+++ b/drivers/media/radio/radio-aztech.c
@@ -29,33 +29,15 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Aztech radio card.");
+MODULE_LICENSE("GPL");
/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -66,55 +48,64 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_AZTECH_PORT;
static int radio_nr = -1;
static int radio_wait_time = 1000;
-static struct mutex lock;
-struct az_device
+module_param(io, int, 0);
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct aztech
{
- unsigned long in_use;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
unsigned long curfreq;
int stereo;
+ struct mutex lock;
};
+static struct aztech aztech_card;
+
static int volconvert(int level)
{
- level>>=14; /* Map 16bits down to 2 bit */
- level&=3;
+ level >>= 14; /* Map 16bits down to 2 bit */
+ level &= 3;
/* convert to card-friendly values */
- switch (level)
- {
- case 0:
- return 0;
- case 1:
- return 1;
- case 2:
- return 4;
- case 3:
- return 5;
+ switch (level) {
+ case 0:
+ return 0;
+ case 1:
+ return 1;
+ case 2:
+ return 4;
+ case 3:
+ return 5;
}
return 0; /* Quieten gcc */
}
-static void send_0_byte (struct az_device *dev)
+static void send_0_byte(struct aztech *az)
{
udelay(radio_wait_time);
- outb_p(2+volconvert(dev->curvol), io);
- outb_p(64+2+volconvert(dev->curvol), io);
+ outb_p(2 + volconvert(az->curvol), az->io);
+ outb_p(64 + 2 + volconvert(az->curvol), az->io);
}
-static void send_1_byte (struct az_device *dev)
+static void send_1_byte(struct aztech *az)
{
udelay (radio_wait_time);
- outb_p(128+2+volconvert(dev->curvol), io);
- outb_p(128+64+2+volconvert(dev->curvol), io);
+ outb_p(128 + 2 + volconvert(az->curvol), az->io);
+ outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io);
}
-static int az_setvol(struct az_device *dev, int vol)
+static int az_setvol(struct aztech *az, int vol)
{
- mutex_lock(&lock);
- outb (volconvert(vol), io);
- mutex_unlock(&lock);
+ mutex_lock(&az->lock);
+ outb(volconvert(vol), az->io);
+ mutex_unlock(&az->lock);
return 0;
}
@@ -126,116 +117,110 @@ static int az_setvol(struct az_device *dev, int vol)
*
*/
-static int az_getsigstr(struct az_device *dev)
+static int az_getsigstr(struct aztech *az)
{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
+ int sig = 1;
+
+ mutex_lock(&az->lock);
+ if (inb(az->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&az->lock);
+ return sig;
}
-static int az_getstereo(struct az_device *dev)
+static int az_getstereo(struct aztech *az)
{
- if (inb(io) & 1) /* bit set = mono */
- return 0;
- return 1; /* stereo */
+ int stereo = 1;
+
+ mutex_lock(&az->lock);
+ if (inb(az->io) & 1) /* bit set = mono */
+ stereo = 0;
+ mutex_unlock(&az->lock);
+ return stereo;
}
-static int az_setfreq(struct az_device *dev, unsigned long frequency)
+static int az_setfreq(struct aztech *az, unsigned long frequency)
{
int i;
+ mutex_lock(&az->lock);
+
+ az->curfreq = frequency;
frequency += 171200; /* Add 10.7 MHz IF */
frequency /= 800; /* Convert to 50 kHz units */
- mutex_lock(&lock);
-
- send_0_byte (dev); /* 0: LSB of frequency */
+ send_0_byte(az); /* 0: LSB of frequency */
for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
if (frequency & (1 << i))
- send_1_byte (dev);
+ send_1_byte(az);
else
- send_0_byte (dev);
+ send_0_byte(az);
- send_0_byte (dev); /* 14: test bit - always 0 */
- send_0_byte (dev); /* 15: test bit - always 0 */
- send_0_byte (dev); /* 16: band data 0 - always 0 */
- if (dev->stereo) /* 17: stereo (1 to enable) */
- send_1_byte (dev);
+ send_0_byte(az); /* 14: test bit - always 0 */
+ send_0_byte(az); /* 15: test bit - always 0 */
+ send_0_byte(az); /* 16: band data 0 - always 0 */
+ if (az->stereo) /* 17: stereo (1 to enable) */
+ send_1_byte(az);
else
- send_0_byte (dev);
+ send_0_byte(az);
- send_1_byte (dev); /* 18: band data 1 - unknown */
- send_0_byte (dev); /* 19: time base - always 0 */
- send_0_byte (dev); /* 20: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 21: spacing (1 = 25 kHz) */
- send_0_byte (dev); /* 22: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 23: AM/FM (FM = 1, always) */
+ send_1_byte(az); /* 18: band data 1 - unknown */
+ send_0_byte(az); /* 19: time base - always 0 */
+ send_0_byte(az); /* 20: spacing (0 = 25 kHz) */
+ send_1_byte(az); /* 21: spacing (1 = 25 kHz) */
+ send_0_byte(az); /* 22: spacing (0 = 25 kHz) */
+ send_1_byte(az); /* 23: AM/FM (FM = 1, always) */
/* latch frequency */
- udelay (radio_wait_time);
- outb_p(128+64+volconvert(dev->curvol), io);
+ udelay(radio_wait_time);
+ outb_p(128 + 64 + volconvert(az->curvol), az->io);
- mutex_unlock(&lock);
+ mutex_unlock(&az->lock);
return 0;
}
-static int vidioc_querycap (struct file *file, void *priv,
+static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
- strlcpy(v->driver, "radio-aztech", sizeof (v->driver));
- strlcpy(v->card, "Aztech Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
+ strlcpy(v->driver, "radio-aztech", sizeof(v->driver));
+ strlcpy(v->card, "Aztech Radio", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
-static int vidioc_g_tuner (struct file *file, void *priv,
+static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(az_getstereo(az))
+ v->rangelow = 87 * 16000;
+ v->rangehigh = 108 * 16000;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (az_getstereo(az))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*az_getsigstr(az);
+ v->signal = 0xFFFF * az_getsigstr(az);
return 0;
}
-
-static int vidioc_s_tuner (struct file *file, void *priv,
+static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_audio (struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
@@ -246,113 +231,107 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-
-static int vidioc_s_audio (struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
-
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static int vidioc_s_frequency (struct file *file, void *priv,
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
- az->curfreq = f->frequency;
- az_setfreq(az, az->curfreq);
+ az_setfreq(az, f->frequency);
return 0;
}
-static int vidioc_g_frequency (struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = az->curfreq;
-
return 0;
}
-static int vidioc_queryctrl (struct file *file, void *priv,
+static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return (0);
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
}
return -EINVAL;
}
-static int vidioc_g_ctrl (struct file *file, void *priv,
+static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (az->curvol==0)
- ctrl->value=1;
- else
- ctrl->value=0;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=az->curvol * 6554;
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ if (az->curvol == 0)
+ ctrl->value = 1;
+ else
+ ctrl->value = 0;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = az->curvol * 6554;
+ return 0;
}
return -EINVAL;
}
-static int vidioc_s_ctrl (struct file *file, void *priv,
+static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- az_setvol(az,0);
- } else {
- az_setvol(az,az->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- az_setvol(az,ctrl->value);
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ az_setvol(az, 0);
+ else
+ az_setvol(az, az->curvol);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ az_setvol(az, ctrl->value);
+ return 0;
}
return -EINVAL;
}
-static struct az_device aztech_unit;
-
-static int aztech_exclusive_open(struct file *file)
+static int aztech_open(struct file *file)
{
- return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int aztech_exclusive_release(struct file *file)
+static int aztech_release(struct file *file)
{
- clear_bit(0, &aztech_unit.in_use);
return 0;
}
static const struct v4l2_file_operations aztech_fops = {
.owner = THIS_MODULE,
- .open = aztech_exclusive_open,
- .release = aztech_exclusive_release,
+ .open = aztech_open,
+ .release = aztech_release,
.ioctl = video_ioctl2,
};
@@ -371,57 +350,60 @@ static const struct v4l2_ioctl_ops aztech_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device aztech_radio = {
- .name = "Aztech radio",
- .fops = &aztech_fops,
- .ioctl_ops = &aztech_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-module_param_named(debug,aztech_radio.debug, int, 0644);
-MODULE_PARM_DESC(debug,"activates debug info");
-
static int __init aztech_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct aztech *az = &aztech_card;
+ struct v4l2_device *v4l2_dev = &az->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name));
+ az->io = io;
+
+ if (az->io == -1) {
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x350 or 0x358\n");
return -EINVAL;
}
- if (!request_region(io, 2, "aztech"))
- {
- printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
+ if (!request_region(az->io, 2, "aztech")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io);
return -EBUSY;
}
- mutex_init(&lock);
- video_set_drvdata(&aztech_radio, &aztech_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(az->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
- if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io,2);
+ mutex_init(&az->lock);
+ strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name));
+ az->vdev.v4l2_dev = v4l2_dev;
+ az->vdev.fops = &aztech_fops;
+ az->vdev.ioctl_ops = &aztech_ioctl_ops;
+ az->vdev.release = video_device_release_empty;
+ video_set_drvdata(&az->vdev, az);
+
+ if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(az->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
+ v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n");
/* mute card - prevents noisy bootups */
- outb (0, io);
+ outb(0, az->io);
return 0;
}
-MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Aztech radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-module_param(radio_nr, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
-
-static void __exit aztech_cleanup(void)
+static void __exit aztech_exit(void)
{
- video_unregister_device(&aztech_radio);
- release_region(io,2);
+ struct aztech *az = &aztech_card;
+
+ video_unregister_device(&az->vdev);
+ v4l2_device_unregister(&az->v4l2_dev);
+ release_region(az->io, 2);
}
module_init(aztech_init);
-module_exit(aztech_cleanup);
+module_exit(aztech_exit);
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c
index cb3075ac104..d30fc0ce82c 100644
--- a/drivers/media/radio/radio-cadet.c
+++ b/drivers/media/radio/radio-cadet.c
@@ -35,333 +35,318 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* V4L2 API defs */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/param.h>
#include <linux/pnp.h>
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+
+MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
+MODULE_LICENSE("GPL");
+
+static int io = -1; /* default to isapnp activation */
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
+module_param(radio_nr, int, 0);
+
+#define CADET_VERSION KERNEL_VERSION(0, 3, 3)
#define RDS_BUFFER 256
#define RDS_RX_FLAG 1
#define MBS_RX_FLAG 2
-#define CADET_VERSION KERNEL_VERSION(0,3,3)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 0xff,
- .step = 1,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
+struct cadet {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
+ int users;
+ int curtuner;
+ int tunestat;
+ int sigstrength;
+ wait_queue_head_t read_queue;
+ struct timer_list readtimer;
+ __u8 rdsin, rdsout, rdsstat;
+ unsigned char rdsbuf[RDS_BUFFER];
+ struct mutex lock;
+ int reading;
};
-static int io=-1; /* default to isapnp activation */
-static int radio_nr = -1;
-static int users;
-static int curtuner;
-static int tunestat;
-static int sigstrength;
-static wait_queue_head_t read_queue;
-static struct timer_list readtimer;
-static __u8 rdsin, rdsout, rdsstat;
-static unsigned char rdsbuf[RDS_BUFFER];
-static spinlock_t cadet_io_lock;
-
-static int cadet_probe(void);
+static struct cadet cadet_card;
/*
* Signal Strength Threshold Values
* The V4L API spec does not define any particular unit for the signal
* strength value. These values are in microvolts of RF at the tuner's input.
*/
-static __u16 sigtable[2][4]={{5,10,30,150},{28,40,63,1000}};
+static __u16 sigtable[2][4] = {
+ { 5, 10, 30, 150 },
+ { 28, 40, 63, 1000 }
+};
-static int
-cadet_getstereo(void)
+static int cadet_getstereo(struct cadet *dev)
{
int ret = V4L2_TUNER_SUB_MONO;
- if(curtuner != 0) /* Only FM has stereo capability! */
+
+ if (dev->curtuner != 0) /* Only FM has stereo capability! */
return V4L2_TUNER_SUB_MONO;
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- if( (inb(io+1) & 0x40) == 0)
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ if ((inb(dev->io + 1) & 0x40) == 0)
ret = V4L2_TUNER_SUB_STEREO;
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
return ret;
}
-static unsigned
-cadet_gettune(void)
+static unsigned cadet_gettune(struct cadet *dev)
{
- int curvol,i;
- unsigned fifo=0;
+ int curvol, i;
+ unsigned fifo = 0;
/*
* Prepare for read
*/
- spin_lock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
- outb(7,io); /* Select tuner control */
- curvol=inb(io+1); /* Save current volume/mute setting */
- outb(0x00,io+1); /* Ensure WRITE-ENABLE is LOW */
- tunestat=0xffff;
+ outb(7, dev->io); /* Select tuner control */
+ curvol = inb(dev->io + 1); /* Save current volume/mute setting */
+ outb(0x00, dev->io + 1); /* Ensure WRITE-ENABLE is LOW */
+ dev->tunestat = 0xffff;
/*
* Read the shift register
*/
- for(i=0;i<25;i++) {
- fifo=(fifo<<1)|((inb(io+1)>>7)&0x01);
- if(i<24) {
- outb(0x01,io+1);
- tunestat&=inb(io+1);
- outb(0x00,io+1);
+ for (i = 0; i < 25; i++) {
+ fifo = (fifo << 1) | ((inb(dev->io + 1) >> 7) & 0x01);
+ if (i < 24) {
+ outb(0x01, dev->io + 1);
+ dev->tunestat &= inb(dev->io + 1);
+ outb(0x00, dev->io + 1);
}
}
/*
* Restore volume/mute setting
*/
- outb(curvol,io+1);
- spin_unlock(&cadet_io_lock);
+ outb(curvol, dev->io + 1);
+ mutex_unlock(&dev->lock);
return fifo;
}
-static unsigned
-cadet_getfreq(void)
+static unsigned cadet_getfreq(struct cadet *dev)
{
int i;
- unsigned freq=0,test,fifo=0;
+ unsigned freq = 0, test, fifo = 0;
/*
* Read current tuning
*/
- fifo=cadet_gettune();
+ fifo = cadet_gettune(dev);
/*
* Convert to actual frequency
*/
- if(curtuner==0) { /* FM */
- test=12500;
- for(i=0;i<14;i++) {
- if((fifo&0x01)!=0) {
- freq+=test;
- }
- test=test<<1;
- fifo=fifo>>1;
+ if (dev->curtuner == 0) { /* FM */
+ test = 12500;
+ for (i = 0; i < 14; i++) {
+ if ((fifo & 0x01) != 0)
+ freq += test;
+ test = test << 1;
+ fifo = fifo >> 1;
}
- freq-=10700000; /* IF frequency is 10.7 MHz */
- freq=(freq*16)/1000000; /* Make it 1/16 MHz */
- }
- if(curtuner==1) { /* AM */
- freq=((fifo&0x7fff)-2010)*16;
+ freq -= 10700000; /* IF frequency is 10.7 MHz */
+ freq = (freq * 16) / 1000000; /* Make it 1/16 MHz */
}
+ if (dev->curtuner == 1) /* AM */
+ freq = ((fifo & 0x7fff) - 2010) * 16;
return freq;
}
-static void
-cadet_settune(unsigned fifo)
+static void cadet_settune(struct cadet *dev, unsigned fifo)
{
int i;
unsigned test;
- spin_lock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
- outb(7,io); /* Select tuner control */
+ outb(7, dev->io); /* Select tuner control */
/*
* Write the shift register
*/
- test=0;
- test=(fifo>>23)&0x02; /* Align data for SDO */
- test|=0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */
- outb(7,io); /* Select tuner control */
- outb(test,io+1); /* Initialize for write */
- for(i=0;i<25;i++) {
- test|=0x01; /* Toggle SCK High */
- outb(test,io+1);
- test&=0xfe; /* Toggle SCK Low */
- outb(test,io+1);
- fifo=fifo<<1; /* Prepare the next bit */
- test=0x1c|((fifo>>23)&0x02);
- outb(test,io+1);
+ test = 0;
+ test = (fifo >> 23) & 0x02; /* Align data for SDO */
+ test |= 0x1c; /* SDM=1, SWE=1, SEN=1, SCK=0 */
+ outb(7, dev->io); /* Select tuner control */
+ outb(test, dev->io + 1); /* Initialize for write */
+ for (i = 0; i < 25; i++) {
+ test |= 0x01; /* Toggle SCK High */
+ outb(test, dev->io + 1);
+ test &= 0xfe; /* Toggle SCK Low */
+ outb(test, dev->io + 1);
+ fifo = fifo << 1; /* Prepare the next bit */
+ test = 0x1c | ((fifo >> 23) & 0x02);
+ outb(test, dev->io + 1);
}
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
}
-static void
-cadet_setfreq(unsigned freq)
+static void cadet_setfreq(struct cadet *dev, unsigned freq)
{
unsigned fifo;
- int i,j,test;
+ int i, j, test;
int curvol;
/*
* Formulate a fifo command
*/
- fifo=0;
- if(curtuner==0) { /* FM */
- test=102400;
- freq=(freq*1000)/16; /* Make it kHz */
- freq+=10700; /* IF is 10700 kHz */
- for(i=0;i<14;i++) {
- fifo=fifo<<1;
- if(freq>=test) {
- fifo|=0x01;
- freq-=test;
+ fifo = 0;
+ if (dev->curtuner == 0) { /* FM */
+ test = 102400;
+ freq = (freq * 1000) / 16; /* Make it kHz */
+ freq += 10700; /* IF is 10700 kHz */
+ for (i = 0; i < 14; i++) {
+ fifo = fifo << 1;
+ if (freq >= test) {
+ fifo |= 0x01;
+ freq -= test;
}
- test=test>>1;
+ test = test >> 1;
}
}
- if(curtuner==1) { /* AM */
- fifo=(freq/16)+2010; /* Make it kHz */
- fifo|=0x100000; /* Select AM Band */
+ if (dev->curtuner == 1) { /* AM */
+ fifo = (freq / 16) + 2010; /* Make it kHz */
+ fifo |= 0x100000; /* Select AM Band */
}
/*
* Save current volume/mute setting
*/
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- curvol=inb(io+1);
- spin_unlock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ curvol = inb(dev->io + 1);
+ mutex_unlock(&dev->lock);
/*
* Tune the card
*/
- for(j=3;j>-1;j--) {
- cadet_settune(fifo|(j<<16));
+ for (j = 3; j > -1; j--) {
+ cadet_settune(dev, fifo | (j << 16));
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- outb(curvol,io+1);
- spin_unlock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ outb(curvol, dev->io + 1);
+ mutex_unlock(&dev->lock);
msleep(100);
- cadet_gettune();
- if((tunestat & 0x40) == 0) { /* Tuned */
- sigstrength=sigtable[curtuner][j];
+ cadet_gettune(dev);
+ if ((dev->tunestat & 0x40) == 0) { /* Tuned */
+ dev->sigstrength = sigtable[dev->curtuner][j];
return;
}
}
- sigstrength=0;
+ dev->sigstrength = 0;
}
-static int
-cadet_getvol(void)
+static int cadet_getvol(struct cadet *dev)
{
int ret = 0;
- spin_lock(&cadet_io_lock);
+ mutex_lock(&dev->lock);
- outb(7,io); /* Select tuner control */
- if((inb(io + 1) & 0x20) != 0)
+ outb(7, dev->io); /* Select tuner control */
+ if ((inb(dev->io + 1) & 0x20) != 0)
ret = 0xffff;
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
return ret;
}
-static void
-cadet_setvol(int vol)
+static void cadet_setvol(struct cadet *dev, int vol)
{
- spin_lock(&cadet_io_lock);
- outb(7,io); /* Select tuner control */
- if(vol>0)
- outb(0x20,io+1);
+ mutex_lock(&dev->lock);
+ outb(7, dev->io); /* Select tuner control */
+ if (vol > 0)
+ outb(0x20, dev->io + 1);
else
- outb(0x00,io+1);
- spin_unlock(&cadet_io_lock);
+ outb(0x00, dev->io + 1);
+ mutex_unlock(&dev->lock);
}
-static void
-cadet_handler(unsigned long data)
+static void cadet_handler(unsigned long data)
{
- /*
- * Service the RDS fifo
- */
+ struct cadet *dev = (void *)data;
- if(spin_trylock(&cadet_io_lock))
- {
- outb(0x3,io); /* Select RDS Decoder Control */
- if((inb(io+1)&0x20)!=0) {
+ /* Service the RDS fifo */
+ if (mutex_trylock(&dev->lock)) {
+ outb(0x3, dev->io); /* Select RDS Decoder Control */
+ if ((inb(dev->io + 1) & 0x20) != 0)
printk(KERN_CRIT "cadet: RDS fifo overflow\n");
- }
- outb(0x80,io); /* Select RDS fifo */
- while((inb(io)&0x80)!=0) {
- rdsbuf[rdsin]=inb(io+1);
- if(rdsin==rdsout)
+ outb(0x80, dev->io); /* Select RDS fifo */
+ while ((inb(dev->io) & 0x80) != 0) {
+ dev->rdsbuf[dev->rdsin] = inb(dev->io + 1);
+ if (dev->rdsin == dev->rdsout)
printk(KERN_WARNING "cadet: RDS buffer overflow\n");
else
- rdsin++;
+ dev->rdsin++;
}
- spin_unlock(&cadet_io_lock);
+ mutex_unlock(&dev->lock);
}
/*
* Service pending read
*/
- if( rdsin!=rdsout)
- wake_up_interruptible(&read_queue);
+ if (dev->rdsin != dev->rdsout)
+ wake_up_interruptible(&dev->read_queue);
/*
* Clean up and exit
*/
- init_timer(&readtimer);
- readtimer.function=cadet_handler;
- readtimer.data=(unsigned long)0;
- readtimer.expires=jiffies+msecs_to_jiffies(50);
- add_timer(&readtimer);
+ init_timer(&dev->readtimer);
+ dev->readtimer.function = cadet_handler;
+ dev->readtimer.data = (unsigned long)0;
+ dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
+ add_timer(&dev->readtimer);
}
-
-static ssize_t
-cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
+static ssize_t cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
- int i=0;
+ struct cadet *dev = video_drvdata(file);
unsigned char readbuf[RDS_BUFFER];
-
- if(rdsstat==0) {
- spin_lock(&cadet_io_lock);
- rdsstat=1;
- outb(0x80,io); /* Select RDS fifo */
- spin_unlock(&cadet_io_lock);
- init_timer(&readtimer);
- readtimer.function=cadet_handler;
- readtimer.data=(unsigned long)0;
- readtimer.expires=jiffies+msecs_to_jiffies(50);
- add_timer(&readtimer);
+ int i = 0;
+
+ if (dev->rdsstat == 0) {
+ mutex_lock(&dev->lock);
+ dev->rdsstat = 1;
+ outb(0x80, dev->io); /* Select RDS fifo */
+ mutex_unlock(&dev->lock);
+ init_timer(&dev->readtimer);
+ dev->readtimer.function = cadet_handler;
+ dev->readtimer.data = (unsigned long)dev;
+ dev->readtimer.expires = jiffies + msecs_to_jiffies(50);
+ add_timer(&dev->readtimer);
}
- if(rdsin==rdsout) {
+ if (dev->rdsin == dev->rdsout) {
if (file->f_flags & O_NONBLOCK)
return -EWOULDBLOCK;
- interruptible_sleep_on(&read_queue);
+ interruptible_sleep_on(&dev->read_queue);
}
- while( i<count && rdsin!=rdsout)
- readbuf[i++]=rdsbuf[rdsout++];
+ while (i < count && dev->rdsin != dev->rdsout)
+ readbuf[i++] = dev->rdsbuf[dev->rdsout++];
- if (copy_to_user(data,readbuf,i))
+ if (copy_to_user(data, readbuf, i))
return -EFAULT;
return i;
}
@@ -370,38 +355,40 @@ cadet_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
- v->capabilities =
- V4L2_CAP_TUNER |
- V4L2_CAP_READWRITE;
+ strlcpy(v->driver, "ADS Cadet", sizeof(v->driver));
+ strlcpy(v->card, "ADS Cadet", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = CADET_VERSION;
- strcpy(v->driver, "ADS Cadet");
- strcpy(v->card, "ADS Cadet");
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_READWRITE;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
+ struct cadet *dev = video_drvdata(file);
+
v->type = V4L2_TUNER_RADIO;
switch (v->index) {
case 0:
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->capability = V4L2_TUNER_CAP_STEREO;
v->rangelow = 1400; /* 87.5 MHz */
v->rangehigh = 1728; /* 108.0 MHz */
- v->rxsubchans=cadet_getstereo();
- switch (v->rxsubchans){
+ v->rxsubchans = cadet_getstereo(dev);
+ switch (v->rxsubchans) {
case V4L2_TUNER_SUB_MONO:
v->audmode = V4L2_TUNER_MODE_MONO;
break;
case V4L2_TUNER_SUB_STEREO:
v->audmode = V4L2_TUNER_MODE_STEREO;
break;
- default: ;
+ default:
+ break;
}
break;
case 1:
- strcpy(v->name, "AM");
+ strlcpy(v->name, "AM", sizeof(v->name));
v->capability = V4L2_TUNER_CAP_LOW;
v->rangelow = 8320; /* 520 kHz */
v->rangehigh = 26400; /* 1650 kHz */
@@ -411,25 +398,29 @@ static int vidioc_g_tuner(struct file *file, void *priv,
default:
return -EINVAL;
}
- v->signal = sigstrength; /* We might need to modify scaling of this */
+ v->signal = dev->sigstrength; /* We might need to modify scaling of this */
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if((v->index != 0)&&(v->index != 1))
+ struct cadet *dev = video_drvdata(file);
+
+ if (v->index != 0 && v->index != 1)
return -EINVAL;
- curtuner = v->index;
+ dev->curtuner = v->index;
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- f->tuner = curtuner;
+ struct cadet *dev = video_drvdata(file);
+
+ f->tuner = dev->curtuner;
f->type = V4L2_TUNER_RADIO;
- f->frequency = cadet_getfreq();
+ f->frequency = cadet_getfreq(dev);
return 0;
}
@@ -437,27 +428,26 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
+ struct cadet *dev = video_drvdata(file);
+
if (f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- if((curtuner==0)&&((f->frequency<1400)||(f->frequency>1728)))
+ if (dev->curtuner == 0 && (f->frequency < 1400 || f->frequency > 1728))
return -EINVAL;
- if((curtuner==1)&&((f->frequency<8320)||(f->frequency>26400)))
+ if (dev->curtuner == 1 && (f->frequency < 8320 || f->frequency > 26400))
return -EINVAL;
- cadet_setfreq(f->frequency);
+ cadet_setfreq(dev, f->frequency);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 0xff, 1, 0xff);
}
return -EINVAL;
}
@@ -465,12 +455,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- switch (ctrl->id){
+ struct cadet *dev = video_drvdata(file);
+
+ switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
- ctrl->value = (cadet_getvol() == 0);
+ ctrl->value = (cadet_getvol(dev) == 0);
break;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = cadet_getvol();
+ ctrl->value = cadet_getvol(dev);
break;
default:
return -EINVAL;
@@ -481,15 +473,17 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct cadet *dev = video_drvdata(file);
+
switch (ctrl->id){
case V4L2_CID_AUDIO_MUTE: /* TODO: Handle this correctly */
if (ctrl->value)
- cadet_setvol(0);
+ cadet_setvol(dev, 0);
else
- cadet_setvol(0xffff);
+ cadet_setvol(dev, 0xffff);
break;
case V4L2_CID_AUDIO_VOLUME:
- cadet_setvol(ctrl->value);
+ cadet_setvol(dev, ctrl->value);
break;
default:
return -EINVAL;
@@ -497,16 +491,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return 0;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -515,43 +499,52 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int
-cadet_open(struct file *file)
+static int cadet_open(struct file *file)
{
- users++;
- if (1 == users) init_waitqueue_head(&read_queue);
+ struct cadet *dev = video_drvdata(file);
+
+ dev->users++;
+ if (1 == dev->users)
+ init_waitqueue_head(&dev->read_queue);
return 0;
}
-static int
-cadet_release(struct file *file)
+static int cadet_release(struct file *file)
{
- users--;
- if (0 == users){
- del_timer_sync(&readtimer);
- rdsstat=0;
+ struct cadet *dev = video_drvdata(file);
+
+ dev->users--;
+ if (0 == dev->users) {
+ del_timer_sync(&dev->readtimer);
+ dev->rdsstat = 0;
}
return 0;
}
-static unsigned int
-cadet_poll(struct file *file, struct poll_table_struct *wait)
+static unsigned int cadet_poll(struct file *file, struct poll_table_struct *wait)
{
- poll_wait(file,&read_queue,wait);
- if(rdsin != rdsout)
+ struct cadet *dev = video_drvdata(file);
+
+ poll_wait(file, &dev->read_queue, wait);
+ if (dev->rdsin != dev->rdsout)
return POLLIN | POLLRDNORM;
return 0;
}
@@ -581,13 +574,6 @@ static const struct v4l2_ioctl_ops cadet_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device cadet_radio = {
- .name = "Cadet radio",
- .fops = &cadet_fops,
- .ioctl_ops = &cadet_ioctl_ops,
- .release = video_device_release_empty,
-};
-
#ifdef CONFIG_PNP
static struct pnp_device_id cadet_pnp_devices[] = {
@@ -598,7 +584,7 @@ static struct pnp_device_id cadet_pnp_devices[] = {
MODULE_DEVICE_TABLE(pnp, cadet_pnp_devices);
-static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id)
+static int cadet_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
{
if (!dev)
return -ENODEV;
@@ -606,13 +592,12 @@ static int cadet_pnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev
if (io > 0)
return -EBUSY;
- if (!pnp_port_valid(dev, 0)) {
+ if (!pnp_port_valid(dev, 0))
return -ENODEV;
- }
io = pnp_port_start(dev, 0);
- printk ("radio-cadet: PnP reports device at %#x\n", io);
+ printk(KERN_INFO "radio-cadet: PnP reports device at %#x\n", io);
return io;
}
@@ -628,23 +613,23 @@ static struct pnp_driver cadet_pnp_driver = {
static struct pnp_driver cadet_pnp_driver;
#endif
-static int cadet_probe(void)
+static void cadet_probe(struct cadet *dev)
{
- static int iovals[8]={0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e};
+ static int iovals[8] = { 0x330, 0x332, 0x334, 0x336, 0x338, 0x33a, 0x33c, 0x33e };
int i;
- for(i=0;i<8;i++) {
- io=iovals[i];
- if (request_region(io, 2, "cadet-probe")) {
- cadet_setfreq(1410);
- if(cadet_getfreq()==1410) {
- release_region(io, 2);
- return io;
+ for (i = 0; i < 8; i++) {
+ dev->io = iovals[i];
+ if (request_region(dev->io, 2, "cadet-probe")) {
+ cadet_setfreq(dev, 1410);
+ if (cadet_getfreq(dev) == 1410) {
+ release_region(dev->io, 2);
+ return;
}
- release_region(io, 2);
+ release_region(dev->io, 2);
}
}
- return -1;
+ dev->io = -1;
}
/*
@@ -654,59 +639,69 @@ static int cadet_probe(void)
static int __init cadet_init(void)
{
- spin_lock_init(&cadet_io_lock);
+ struct cadet *dev = &cadet_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
- /*
- * If a probe was requested then probe ISAPnP first (safest)
- */
+ strlcpy(v4l2_dev->name, "cadet", sizeof(v4l2_dev->name));
+ mutex_init(&dev->lock);
+
+ /* If a probe was requested then probe ISAPnP first (safest) */
if (io < 0)
pnp_register_driver(&cadet_pnp_driver);
- /*
- * If that fails then probe unsafely if probe is requested
- */
- if(io < 0)
- io = cadet_probe ();
+ dev->io = io;
- /*
- * Else we bail out
- */
+ /* If that fails then probe unsafely if probe is requested */
+ if (dev->io < 0)
+ cadet_probe(dev);
- if(io < 0) {
+ /* Else we bail out */
+ if (dev->io < 0) {
#ifdef MODULE
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x330, 0x332, 0x334,\n");
+ v4l2_err(v4l2_dev, "0x336, 0x338, 0x33a, 0x33c or 0x33e\n");
#endif
goto fail;
}
- if (!request_region(io,2,"cadet"))
+ if (!request_region(dev->io, 2, "cadet"))
+ goto fail;
+
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(dev->io, 2);
+ v4l2_err(v4l2_dev, "could not register v4l2_device\n");
goto fail;
- if (video_register_device(&cadet_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io,2);
+ }
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &cadet_fops;
+ dev->vdev.ioctl_ops = &cadet_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(dev->io, 2);
goto fail;
}
- printk(KERN_INFO "ADS Cadet Radio Card at 0x%x\n",io);
+ v4l2_info(v4l2_dev, "ADS Cadet Radio Card at 0x%x\n", dev->io);
return 0;
fail:
pnp_unregister_driver(&cadet_pnp_driver);
- return -1;
+ return -ENODEV;
}
-
-
-MODULE_AUTHOR("Fred Gleason, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the ADS Cadet AM/FM/RDS radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of Cadet card (0x330,0x332,0x334,0x336,0x338,0x33a,0x33c,0x33e)");
-module_param(radio_nr, int, 0);
-
-static void __exit cadet_cleanup_module(void)
+static void __exit cadet_exit(void)
{
- video_unregister_device(&cadet_radio);
- release_region(io,2);
+ struct cadet *dev = &cadet_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 2);
pnp_unregister_driver(&cadet_pnp_driver);
}
module_init(cadet_init);
-module_exit(cadet_cleanup_module);
+module_exit(cadet_exit);
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c
index 0c96bf8525b..09265d25725 100644
--- a/drivers/media/radio/radio-gemtek-pci.c
+++ b/drivers/media/radio/radio-gemtek-pci.c
@@ -45,34 +45,25 @@
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/errno.h>
-
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+#include <linux/io.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+MODULE_AUTHOR("Vladimir Shebordaev <vshebordaev@mail.ru>");
+MODULE_DESCRIPTION("The video4linux driver for the Gemtek PCI Radio Card");
+MODULE_LICENSE("GPL");
+
+static int nr_radio = -1;
+static int mx = 1;
+
+module_param(mx, bool, 0);
+MODULE_PARM_DESC(mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not");
+module_param(nr_radio, int, 0);
+MODULE_PARM_DESC(nr_radio, "video4linux device number to use");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
#ifndef PCI_VENDOR_ID_GEMTEK
#define PCI_VENDOR_ID_GEMTEK 0x5046
@@ -90,8 +81,11 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define GEMTEK_PCI_RANGE_HIGH (108*16000)
#endif
-struct gemtek_pci_card {
- struct video_device *videodev;
+struct gemtek_pci {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct mutex lock;
+ struct pci_dev *pdev;
u32 iobase;
u32 length;
@@ -100,116 +94,133 @@ struct gemtek_pci_card {
u8 mute;
};
-static int nr_radio = -1;
-static unsigned long in_use;
+static inline struct gemtek_pci *to_gemtek_pci(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct gemtek_pci, v4l2_dev);
+}
-static inline u8 gemtek_pci_out( u16 value, u32 port )
+static inline u8 gemtek_pci_out(u16 value, u32 port)
{
- outw( value, port );
+ outw(value, port);
return (u8)value;
}
-#define _b0( v ) *((u8 *)&v)
-static void __gemtek_pci_cmd( u16 value, u32 port, u8 *last_byte, int keep )
+#define _b0(v) (*((u8 *)&v))
+
+static void __gemtek_pci_cmd(u16 value, u32 port, u8 *last_byte, int keep)
{
- register u8 byte = *last_byte;
+ u8 byte = *last_byte;
- if ( !value ) {
- if ( !keep )
+ if (!value) {
+ if (!keep)
value = (u16)port;
byte &= 0xfd;
} else
byte |= 2;
- _b0( value ) = byte;
- outw( value, port );
+ _b0(value) = byte;
+ outw(value, port);
byte |= 1;
- _b0( value ) = byte;
- outw( value, port );
+ _b0(value) = byte;
+ outw(value, port);
byte &= 0xfe;
- _b0( value ) = byte;
- outw( value, port );
+ _b0(value) = byte;
+ outw(value, port);
*last_byte = byte;
}
-static inline void gemtek_pci_nil( u32 port, u8 *last_byte )
+static inline void gemtek_pci_nil(u32 port, u8 *last_byte)
{
- __gemtek_pci_cmd( 0x00, port, last_byte, false );
+ __gemtek_pci_cmd(0x00, port, last_byte, false);
}
-static inline void gemtek_pci_cmd( u16 cmd, u32 port, u8 *last_byte )
+static inline void gemtek_pci_cmd(u16 cmd, u32 port, u8 *last_byte)
{
- __gemtek_pci_cmd( cmd, port, last_byte, true );
+ __gemtek_pci_cmd(cmd, port, last_byte, true);
}
-static void gemtek_pci_setfrequency( struct gemtek_pci_card *card, unsigned long frequency )
+static void gemtek_pci_setfrequency(struct gemtek_pci *card, unsigned long frequency)
{
- register int i;
- register u32 value = frequency / 200 + 856;
- register u16 mask = 0x8000;
+ int i;
+ u32 value = frequency / 200 + 856;
+ u16 mask = 0x8000;
u8 last_byte;
u32 port = card->iobase;
- last_byte = gemtek_pci_out( 0x06, port );
+ mutex_lock(&card->lock);
+ card->current_frequency = frequency;
+ last_byte = gemtek_pci_out(0x06, port);
i = 0;
do {
- gemtek_pci_nil( port, &last_byte );
+ gemtek_pci_nil(port, &last_byte);
i++;
- } while ( i < 9 );
+ } while (i < 9);
i = 0;
do {
- gemtek_pci_cmd( value & mask, port, &last_byte );
+ gemtek_pci_cmd(value & mask, port, &last_byte);
mask >>= 1;
i++;
- } while ( i < 16 );
+ } while (i < 16);
- outw( 0x10, port );
+ outw(0x10, port);
+ mutex_unlock(&card->lock);
}
-static inline void gemtek_pci_mute( struct gemtek_pci_card *card )
+static void gemtek_pci_mute(struct gemtek_pci *card)
{
- outb( 0x1f, card->iobase );
+ mutex_lock(&card->lock);
+ outb(0x1f, card->iobase);
card->mute = true;
+ mutex_unlock(&card->lock);
}
-static inline void gemtek_pci_unmute( struct gemtek_pci_card *card )
+static void gemtek_pci_unmute(struct gemtek_pci *card)
{
- if ( card->mute ) {
- gemtek_pci_setfrequency( card, card->current_frequency );
+ mutex_lock(&card->lock);
+ if (card->mute) {
+ gemtek_pci_setfrequency(card, card->current_frequency);
card->mute = false;
}
+ mutex_unlock(&card->lock);
}
-static inline unsigned int gemtek_pci_getsignal( struct gemtek_pci_card *card )
+static int gemtek_pci_getsignal(struct gemtek_pci *card)
{
- return ( inb( card->iobase ) & 0x08 ) ? 0 : 1;
+ int sig;
+
+ mutex_lock(&card->lock);
+ sig = (inb(card->iobase) & 0x08) ? 0 : 1;
+ mutex_unlock(&card->lock);
+ return sig;
}
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct gemtek_pci *card = video_drvdata(file);
+
strlcpy(v->driver, "radio-gemtek-pci", sizeof(v->driver));
strlcpy(v->card, "GemTek PCI Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(card->pdev));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->rangelow = GEMTEK_PCI_RANGE_LOW;
v->rangehigh = GEMTEK_PCI_RANGE_HIGH;
@@ -223,21 +234,18 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
- if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) ||
- (f->frequency > GEMTEK_PCI_RANGE_HIGH) )
+ if (f->frequency < GEMTEK_PCI_RANGE_LOW ||
+ f->frequency > GEMTEK_PCI_RANGE_HIGH)
return -EINVAL;
gemtek_pci_setfrequency(card, f->frequency);
- card->current_frequency = f->frequency;
card->mute = false;
return 0;
}
@@ -245,7 +253,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = card->current_frequency;
@@ -255,13 +263,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
}
return -EINVAL;
}
@@ -269,7 +275,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -288,7 +294,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_pci_card *card = video_drvdata(file);
+ struct gemtek_pci *card = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -307,17 +313,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -326,17 +321,22 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
enum {
@@ -354,25 +354,22 @@ static struct pci_device_id gemtek_pci_id[] =
{ 0 }
};
-MODULE_DEVICE_TABLE( pci, gemtek_pci_id );
-
-static int mx = 1;
+MODULE_DEVICE_TABLE(pci, gemtek_pci_id);
-static int gemtek_pci_exclusive_open(struct file *file)
+static int gemtek_pci_open(struct file *file)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return 0;
}
-static int gemtek_pci_exclusive_release(struct file *file)
+static int gemtek_pci_release(struct file *file)
{
- clear_bit(0, &in_use);
return 0;
}
static const struct v4l2_file_operations gemtek_pci_fops = {
.owner = THIS_MODULE,
- .open = gemtek_pci_exclusive_open,
- .release = gemtek_pci_exclusive_release,
+ .open = gemtek_pci_open,
+ .release = gemtek_pci_release,
.ioctl = video_ioctl2,
};
@@ -391,108 +388,100 @@ static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device vdev_template = {
- .name = "Gemtek PCI Radio",
- .fops = &gemtek_pci_fops,
- .ioctl_ops = &gemtek_pci_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-static int __devinit gemtek_pci_probe( struct pci_dev *pci_dev, const struct pci_device_id *pci_id )
+static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
{
- struct gemtek_pci_card *card;
- struct video_device *devradio;
+ struct gemtek_pci *card;
+ struct v4l2_device *v4l2_dev;
+ int res;
- if ( (card = kzalloc( sizeof( struct gemtek_pci_card ), GFP_KERNEL )) == NULL ) {
- printk( KERN_ERR "gemtek_pci: out of memory\n" );
+ card = kzalloc(sizeof(struct gemtek_pci), GFP_KERNEL);
+ if (card == NULL) {
+ dev_err(&pdev->dev, "out of memory\n");
return -ENOMEM;
}
- if ( pci_enable_device( pci_dev ) )
- goto err_pci;
+ v4l2_dev = &card->v4l2_dev;
+ mutex_init(&card->lock);
+ card->pdev = pdev;
- card->iobase = pci_resource_start( pci_dev, 0 );
- card->length = pci_resource_len( pci_dev, 0 );
+ strlcpy(v4l2_dev->name, "gemtek_pci", sizeof(v4l2_dev->name));
- if ( request_region( card->iobase, card->length, card_names[pci_id->driver_data] ) == NULL ) {
- printk( KERN_ERR "gemtek_pci: i/o port already in use\n" );
- goto err_pci;
+ res = v4l2_device_register(&pdev->dev, v4l2_dev);
+ if (res < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ kfree(card);
+ return res;
}
- pci_set_drvdata( pci_dev, card );
+ if (pci_enable_device(pdev))
+ goto err_pci;
- if ( (devradio = kmalloc( sizeof( struct video_device ), GFP_KERNEL )) == NULL ) {
- printk( KERN_ERR "gemtek_pci: out of memory\n" );
- goto err_video;
+ card->iobase = pci_resource_start(pdev, 0);
+ card->length = pci_resource_len(pdev, 0);
+
+ if (request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
+ v4l2_err(v4l2_dev, "i/o port already in use\n");
+ goto err_pci;
}
- *devradio = vdev_template;
- if (video_register_device(devradio, VFL_TYPE_RADIO, nr_radio) < 0) {
- kfree( devradio );
+ strlcpy(card->vdev.name, v4l2_dev->name, sizeof(card->vdev.name));
+ card->vdev.v4l2_dev = v4l2_dev;
+ card->vdev.fops = &gemtek_pci_fops;
+ card->vdev.ioctl_ops = &gemtek_pci_ioctl_ops;
+ card->vdev.release = video_device_release_empty;
+ video_set_drvdata(&card->vdev, card);
+
+ if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0)
goto err_video;
- }
- card->videodev = devradio;
- video_set_drvdata(devradio, card);
- gemtek_pci_mute( card );
+ gemtek_pci_mute(card);
- printk( KERN_INFO "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
- pci_dev->revision, card->iobase, card->iobase + card->length - 1 );
+ v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n",
+ pdev->revision, card->iobase, card->iobase + card->length - 1);
return 0;
err_video:
- release_region( card->iobase, card->length );
+ release_region(card->iobase, card->length);
err_pci:
- kfree( card );
+ v4l2_device_unregister(v4l2_dev);
+ kfree(card);
return -ENODEV;
}
-static void __devexit gemtek_pci_remove( struct pci_dev *pci_dev )
+static void __devexit gemtek_pci_remove(struct pci_dev *pdev)
{
- struct gemtek_pci_card *card = pci_get_drvdata( pci_dev );
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct gemtek_pci *card = to_gemtek_pci(v4l2_dev);
- video_unregister_device( card->videodev );
- kfree( card->videodev );
+ video_unregister_device(&card->vdev);
+ v4l2_device_unregister(v4l2_dev);
- release_region( card->iobase, card->length );
+ release_region(card->iobase, card->length);
- if ( mx )
- gemtek_pci_mute( card );
+ if (mx)
+ gemtek_pci_mute(card);
- kfree( card );
-
- pci_set_drvdata( pci_dev, NULL );
+ kfree(card);
}
-static struct pci_driver gemtek_pci_driver =
-{
+static struct pci_driver gemtek_pci_driver = {
.name = "gemtek_pci",
.id_table = gemtek_pci_id,
.probe = gemtek_pci_probe,
.remove = __devexit_p(gemtek_pci_remove),
};
-static int __init gemtek_pci_init_module( void )
+static int __init gemtek_pci_init(void)
{
- return pci_register_driver( &gemtek_pci_driver );
+ return pci_register_driver(&gemtek_pci_driver);
}
-static void __exit gemtek_pci_cleanup_module( void )
+static void __exit gemtek_pci_exit(void)
{
pci_unregister_driver(&gemtek_pci_driver);
}
-MODULE_AUTHOR( "Vladimir Shebordaev <vshebordaev@mail.ru>" );
-MODULE_DESCRIPTION( "The video4linux driver for the Gemtek PCI Radio Card" );
-MODULE_LICENSE("GPL");
-
-module_param(mx, bool, 0);
-MODULE_PARM_DESC( mx, "single digit: 1 - turn off the turner upon module exit (default), 0 - do not" );
-module_param(nr_radio, int, 0);
-MODULE_PARM_DESC( nr_radio, "video4linux device number to use");
-
-module_init( gemtek_pci_init_module );
-module_exit( gemtek_pci_cleanup_module );
-
+module_init(gemtek_pci_init);
+module_exit(gemtek_pci_exit);
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index 2b68be773f1..150464426d1 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -20,16 +20,14 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/mutex.h>
+#include <linux/io.h> /* outb, outb_p */
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-common.h>
-#include <linux/spinlock.h>
+#include <media/v4l2-device.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,3)
-#define RADIO_BANNER "GemTek Radio card driver: v0.0.3"
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 3)
/*
* Module info.
@@ -57,7 +55,6 @@ static int shutdown = 1;
static int keepmuted = 1;
static int initmute = 1;
static int radio_nr = -1;
-static unsigned long in_use;
module_param(io, int, 0444);
MODULE_PARM_DESC(io, "Force I/O port for the GemTek Radio card if automatic "
@@ -112,12 +109,19 @@ module_param(radio_nr, int, 0444);
#define SHORT_DELAY 5 /* usec */
#define LONG_DELAY 75 /* usec */
-struct gemtek_device {
+struct gemtek {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct mutex lock;
unsigned long lastfreq;
int muted;
+ int verified;
+ int io;
u32 bu2614data;
};
+static struct gemtek gemtek_card;
+
#define BU2614_FREQ_BITS 16 /* D0..D15, Frequency data */
#define BU2614_PORT_BITS 3 /* P0..P2, Output port control data */
#define BU2614_VOID_BITS 4 /* unused */
@@ -153,10 +157,6 @@ struct gemtek_device {
#define BU2614_FMUN_MASK MKMASK(FMUN)
#define BU2614_TEST_MASK MKMASK(TEST)
-static struct gemtek_device gemtek_unit;
-
-static spinlock_t lock;
-
/*
* Set data which will be sent to BU2614FS.
*/
@@ -166,33 +166,33 @@ static spinlock_t lock;
/*
* Transmit settings to BU2614FS over GemTek IC.
*/
-static void gemtek_bu2614_transmit(struct gemtek_device *dev)
+static void gemtek_bu2614_transmit(struct gemtek *gt)
{
int i, bit, q, mute;
- spin_lock(&lock);
+ mutex_lock(&gt->lock);
- mute = dev->muted ? GEMTEK_MT : 0x00;
+ mute = gt->muted ? GEMTEK_MT : 0x00;
- outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(SHORT_DELAY);
- outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(LONG_DELAY);
- for (i = 0, q = dev->bu2614data; i < 32; i++, q >>= 1) {
- bit = (q & 1) ? GEMTEK_DA : 0;
- outb_p(mute | GEMTEK_CE | bit, io);
- udelay(SHORT_DELAY);
- outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, io);
- udelay(SHORT_DELAY);
+ for (i = 0, q = gt->bu2614data; i < 32; i++, q >>= 1) {
+ bit = (q & 1) ? GEMTEK_DA : 0;
+ outb_p(mute | GEMTEK_CE | bit, gt->io);
+ udelay(SHORT_DELAY);
+ outb_p(mute | GEMTEK_CE | bit | GEMTEK_CK, gt->io);
+ udelay(SHORT_DELAY);
}
- outb_p(mute | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(SHORT_DELAY);
- outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, io);
+ outb_p(mute | GEMTEK_CE | GEMTEK_DA | GEMTEK_CK, gt->io);
udelay(LONG_DELAY);
- spin_unlock(&lock);
+ mutex_unlock(&gt->lock);
}
/*
@@ -206,107 +206,109 @@ static unsigned long gemtek_convfreq(unsigned long freq)
/*
* Set FM-frequency.
*/
-static void gemtek_setfreq(struct gemtek_device *dev, unsigned long freq)
+static void gemtek_setfreq(struct gemtek *gt, unsigned long freq)
{
-
- if (keepmuted && hardmute && dev->muted)
+ if (keepmuted && hardmute && gt->muted)
return;
- if (freq < GEMTEK_LOWFREQ)
- freq = GEMTEK_LOWFREQ;
- else if (freq > GEMTEK_HIGHFREQ)
- freq = GEMTEK_HIGHFREQ;
+ freq = clamp_val(freq, GEMTEK_LOWFREQ, GEMTEK_HIGHFREQ);
- dev->lastfreq = freq;
- dev->muted = 0;
+ gt->lastfreq = freq;
+ gt->muted = 0;
- gemtek_bu2614_set(dev, BU2614_PORT, 0);
- gemtek_bu2614_set(dev, BU2614_FMES, 0);
- gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode */
- gemtek_bu2614_set(dev, BU2614_SWAL, 0);
- gemtek_bu2614_set(dev, BU2614_FMUN, 1); /* GT bit set */
- gemtek_bu2614_set(dev, BU2614_TEST, 0);
+ gemtek_bu2614_set(gt, BU2614_PORT, 0);
+ gemtek_bu2614_set(gt, BU2614_FMES, 0);
+ gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */
+ gemtek_bu2614_set(gt, BU2614_SWAL, 0);
+ gemtek_bu2614_set(gt, BU2614_FMUN, 1); /* GT bit set */
+ gemtek_bu2614_set(gt, BU2614_TEST, 0);
- gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
- gemtek_bu2614_set(dev, BU2614_FREQ, gemtek_convfreq(freq));
+ gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_STDF_3_125_KHZ);
+ gemtek_bu2614_set(gt, BU2614_FREQ, gemtek_convfreq(freq));
- gemtek_bu2614_transmit(dev);
+ gemtek_bu2614_transmit(gt);
}
/*
* Set mute flag.
*/
-static void gemtek_mute(struct gemtek_device *dev)
+static void gemtek_mute(struct gemtek *gt)
{
int i;
- dev->muted = 1;
+
+ gt->muted = 1;
if (hardmute) {
/* Turn off PLL, disable data output */
- gemtek_bu2614_set(dev, BU2614_PORT, 0);
- gemtek_bu2614_set(dev, BU2614_FMES, 0); /* CT bit off */
- gemtek_bu2614_set(dev, BU2614_SWIN, 0); /* FM-mode */
- gemtek_bu2614_set(dev, BU2614_SWAL, 0);
- gemtek_bu2614_set(dev, BU2614_FMUN, 0); /* GT bit off */
- gemtek_bu2614_set(dev, BU2614_TEST, 0);
- gemtek_bu2614_set(dev, BU2614_STDF, GEMTEK_PLL_OFF);
- gemtek_bu2614_set(dev, BU2614_FREQ, 0);
- gemtek_bu2614_transmit(dev);
- } else {
- spin_lock(&lock);
+ gemtek_bu2614_set(gt, BU2614_PORT, 0);
+ gemtek_bu2614_set(gt, BU2614_FMES, 0); /* CT bit off */
+ gemtek_bu2614_set(gt, BU2614_SWIN, 0); /* FM-mode */
+ gemtek_bu2614_set(gt, BU2614_SWAL, 0);
+ gemtek_bu2614_set(gt, BU2614_FMUN, 0); /* GT bit off */
+ gemtek_bu2614_set(gt, BU2614_TEST, 0);
+ gemtek_bu2614_set(gt, BU2614_STDF, GEMTEK_PLL_OFF);
+ gemtek_bu2614_set(gt, BU2614_FREQ, 0);
+ gemtek_bu2614_transmit(gt);
+ return;
+ }
- /* Read bus contents (CE, CK and DA). */
- i = inb_p(io);
- /* Write it back with mute flag set. */
- outb_p((i >> 5) | GEMTEK_MT, io);
- udelay(SHORT_DELAY);
+ mutex_lock(&gt->lock);
- spin_unlock(&lock);
- }
+ /* Read bus contents (CE, CK and DA). */
+ i = inb_p(gt->io);
+ /* Write it back with mute flag set. */
+ outb_p((i >> 5) | GEMTEK_MT, gt->io);
+ udelay(SHORT_DELAY);
+
+ mutex_unlock(&gt->lock);
}
/*
* Unset mute flag.
*/
-static void gemtek_unmute(struct gemtek_device *dev)
+static void gemtek_unmute(struct gemtek *gt)
{
int i;
- dev->muted = 0;
+ gt->muted = 0;
if (hardmute) {
/* Turn PLL back on. */
- gemtek_setfreq(dev, dev->lastfreq);
- } else {
- spin_lock(&lock);
+ gemtek_setfreq(gt, gt->lastfreq);
+ return;
+ }
+ mutex_lock(&gt->lock);
- i = inb_p(io);
- outb_p(i >> 5, io);
- udelay(SHORT_DELAY);
+ i = inb_p(gt->io);
+ outb_p(i >> 5, gt->io);
+ udelay(SHORT_DELAY);
- spin_unlock(&lock);
- }
+ mutex_unlock(&gt->lock);
}
/*
* Get signal strength (= stereo status).
*/
-static inline int gemtek_getsigstr(void)
+static inline int gemtek_getsigstr(struct gemtek *gt)
{
- return inb_p(io) & GEMTEK_NS ? 0 : 1;
+ int sig;
+
+ mutex_lock(&gt->lock);
+ sig = inb_p(gt->io) & GEMTEK_NS ? 0 : 1;
+ mutex_unlock(&gt->lock);
+ return sig;
}
/*
* Check if requested card acts like GemTek Radio card.
*/
-static int gemtek_verify(int port)
+static int gemtek_verify(struct gemtek *gt, int port)
{
- static int verified = -1;
int i, q;
- if (verified == port)
+ if (gt->verified == port)
return 1;
- spin_lock(&lock);
+ mutex_lock(&gt->lock);
q = inb_p(port); /* Read bus contents before probing. */
/* Try to turn on CE, CK and DA respectively and check if card responds
@@ -316,15 +318,15 @@ static int gemtek_verify(int port)
udelay(SHORT_DELAY);
if ((inb_p(port) & (~GEMTEK_NS)) != (0x17 | (1 << (i + 5)))) {
- spin_unlock(&lock);
+ mutex_unlock(&gt->lock);
return 0;
}
}
outb_p(q >> 5, port); /* Write bus contents back. */
udelay(SHORT_DELAY);
- spin_unlock(&lock);
- verified = port;
+ mutex_unlock(&gt->lock);
+ gt->verified = port;
return 1;
}
@@ -332,83 +334,61 @@ static int gemtek_verify(int port)
/*
* Automatic probing for card.
*/
-static int gemtek_probe(void)
+static int gemtek_probe(struct gemtek *gt)
{
+ struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
int ioports[] = { 0x20c, 0x30c, 0x24c, 0x34c, 0x248, 0x28c };
int i;
if (!probe) {
- printk(KERN_INFO "Automatic device probing disabled.\n");
+ v4l2_info(v4l2_dev, "Automatic device probing disabled.\n");
return -1;
}
- printk(KERN_INFO "Automatic device probing enabled.\n");
+ v4l2_info(v4l2_dev, "Automatic device probing enabled.\n");
for (i = 0; i < ARRAY_SIZE(ioports); ++i) {
- printk(KERN_INFO "Trying I/O port 0x%x...\n", ioports[i]);
+ v4l2_info(v4l2_dev, "Trying I/O port 0x%x...\n", ioports[i]);
if (!request_region(ioports[i], 1, "gemtek-probe")) {
- printk(KERN_WARNING "I/O port 0x%x busy!\n",
+ v4l2_warn(v4l2_dev, "I/O port 0x%x busy!\n",
ioports[i]);
continue;
}
- if (gemtek_verify(ioports[i])) {
- printk(KERN_INFO "Card found from I/O port "
+ if (gemtek_verify(gt, ioports[i])) {
+ v4l2_info(v4l2_dev, "Card found from I/O port "
"0x%x!\n", ioports[i]);
release_region(ioports[i], 1);
-
- io = ioports[i];
- return io;
+ gt->io = ioports[i];
+ return gt->io;
}
release_region(ioports[i], 1);
}
- printk(KERN_ERR "Automatic probing failed!\n");
-
+ v4l2_err(v4l2_dev, "Automatic probing failed!\n");
return -1;
}
/*
* Video 4 Linux stuff.
*/
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }, {
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-
-static int gemtek_exclusive_open(struct file *file)
+static int gemtek_open(struct file *file)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return 0;
}
-static int gemtek_exclusive_release(struct file *file)
+static int gemtek_release(struct file *file)
{
- clear_bit(0, &in_use);
return 0;
}
static const struct v4l2_file_operations gemtek_fops = {
.owner = THIS_MODULE,
- .open = gemtek_exclusive_open,
- .release = gemtek_exclusive_release,
+ .open = gemtek_open,
+ .release = gemtek_release,
.ioctl = video_ioctl2,
};
@@ -417,23 +397,25 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-gemtek", sizeof(v->driver));
strlcpy(v->card, "GemTek", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
{
+ struct gemtek *gt = video_drvdata(file);
+
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->rangelow = GEMTEK_LOWFREQ;
v->rangehigh = GEMTEK_HIGHFREQ;
v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
- v->signal = 0xffff * gemtek_getsigstr();
+ v->signal = 0xffff * gemtek_getsigstr(gt);
if (v->signal) {
v->audmode = V4L2_TUNER_MODE_STEREO;
v->rxsubchans = V4L2_TUNER_SUB_STEREO;
@@ -441,65 +423,56 @@ static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
v->audmode = V4L2_TUNER_MODE_MONO;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
}
-
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return (v->index != 0) ? -EINVAL : 0;
}
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_device *rt = video_drvdata(file);
-
- gemtek_setfreq(rt, f->frequency);
+ struct gemtek *gt = video_drvdata(file);
+ if (f->tuner != 0)
+ return -EINVAL;
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = gt->lastfreq;
return 0;
}
-static int vidioc_g_frequency(struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct gemtek_device *rt = video_drvdata(file);
+ struct gemtek *gt = video_drvdata(file);
- f->type = V4L2_TUNER_RADIO;
- f->frequency = rt->lastfreq;
+ if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
+ return -EINVAL;
+ gemtek_setfreq(gt, f->frequency);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); ++i) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ default:
+ return -EINVAL;
}
- return -EINVAL;
}
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_device *rt = video_drvdata(file);
+ struct gemtek *gt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = rt->muted;
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- if (rt->muted)
- ctrl->value = 0;
- else
- ctrl->value = 65535;
+ ctrl->value = gt->muted;
return 0;
}
return -EINVAL;
@@ -508,35 +481,19 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct gemtek_device *rt = video_drvdata(file);
+ struct gemtek *gt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
- gemtek_mute(rt);
- else
- gemtek_unmute(rt);
- return 0;
- case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value)
- gemtek_unmute(rt);
+ gemtek_mute(gt);
else
- gemtek_mute(rt);
+ gemtek_unmute(gt);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -545,16 +502,20 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return (i != 0) ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return (a->index != 0) ? -EINVAL : 0;
}
static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
@@ -572,62 +533,73 @@ static const struct v4l2_ioctl_ops gemtek_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl
};
-static struct video_device gemtek_radio = {
- .name = "GemTek Radio card",
- .fops = &gemtek_fops,
- .ioctl_ops = &gemtek_ioctl_ops,
- .release = video_device_release_empty,
-};
-
/*
* Initialization / cleanup related stuff.
*/
-/*
- * Initilize card.
- */
static int __init gemtek_init(void)
{
- printk(KERN_INFO RADIO_BANNER "\n");
+ struct gemtek *gt = &gemtek_card;
+ struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
+ int res;
- spin_lock_init(&lock);
+ strlcpy(v4l2_dev->name, "gemtek", sizeof(v4l2_dev->name));
- gemtek_probe();
- if (io) {
- if (!request_region(io, 1, "gemtek")) {
- printk(KERN_ERR "I/O port 0x%x already in use.\n", io);
+ v4l2_info(v4l2_dev, "GemTek Radio card driver: v0.0.3\n");
+
+ mutex_init(&gt->lock);
+
+ gt->verified = -1;
+ gt->io = io;
+ gemtek_probe(gt);
+ if (gt->io) {
+ if (!request_region(gt->io, 1, "gemtek")) {
+ v4l2_err(v4l2_dev, "I/O port 0x%x already in use.\n", gt->io);
return -EBUSY;
}
- if (!gemtek_verify(io))
- printk(KERN_WARNING "Card at I/O port 0x%x does not "
+ if (!gemtek_verify(gt, gt->io))
+ v4l2_warn(v4l2_dev, "Card at I/O port 0x%x does not "
"respond properly, check your "
- "configuration.\n", io);
+ "configuration.\n", gt->io);
else
- printk(KERN_INFO "Using I/O port 0x%x.\n", io);
+ v4l2_info(v4l2_dev, "Using I/O port 0x%x.\n", gt->io);
} else if (probe) {
- printk(KERN_ERR "Automatic probing failed and no "
+ v4l2_err(v4l2_dev, "Automatic probing failed and no "
"fixed I/O port defined.\n");
return -ENODEV;
} else {
- printk(KERN_ERR "Automatic probing disabled but no fixed "
+ v4l2_err(v4l2_dev, "Automatic probing disabled but no fixed "
"I/O port defined.");
return -EINVAL;
}
- video_set_drvdata(&gemtek_radio, &gemtek_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ release_region(gt->io, 1);
+ return res;
+ }
- if (video_register_device(&gemtek_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 1);
+ strlcpy(gt->vdev.name, v4l2_dev->name, sizeof(gt->vdev.name));
+ gt->vdev.v4l2_dev = v4l2_dev;
+ gt->vdev.fops = &gemtek_fops;
+ gt->vdev.ioctl_ops = &gemtek_ioctl_ops;
+ gt->vdev.release = video_device_release_empty;
+ video_set_drvdata(&gt->vdev, gt);
+
+ if (video_register_device(&gt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(gt->io, 1);
return -EBUSY;
}
/* Set defaults */
- gemtek_unit.lastfreq = GEMTEK_LOWFREQ;
- gemtek_unit.bu2614data = 0;
+ gt->lastfreq = GEMTEK_LOWFREQ;
+ gt->bu2614data = 0;
if (initmute)
- gemtek_mute(&gemtek_unit);
+ gemtek_mute(gt);
return 0;
}
@@ -637,15 +609,19 @@ static int __init gemtek_init(void)
*/
static void __exit gemtek_exit(void)
{
+ struct gemtek *gt = &gemtek_card;
+ struct v4l2_device *v4l2_dev = &gt->v4l2_dev;
+
if (shutdown) {
hardmute = 1; /* Turn off PLL */
- gemtek_mute(&gemtek_unit);
+ gemtek_mute(gt);
} else {
- printk(KERN_INFO "Module unloaded but card not muted!\n");
+ v4l2_info(v4l2_dev, "Module unloaded but card not muted!\n");
}
- video_unregister_device(&gemtek_radio);
- release_region(io, 1);
+ video_unregister_device(&gt->vdev);
+ v4l2_device_unregister(&gt->v4l2_dev);
+ release_region(gt->io, 1);
}
module_init(gemtek_init);
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c
index ba3a13a9001..01a6d22950a 100644
--- a/drivers/media/radio/radio-maestro.c
+++ b/drivers/media/radio/radio-maestro.c
@@ -22,27 +22,22 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/pci.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,6)
-#define DRIVER_VERSION "0.06"
+MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
+MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
+MODULE_LICENSE("GPL");
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
+#define DRIVER_VERSION "0.06"
#define GPIO_DATA 0x60 /* port offset from ESS_IO_BASE */
@@ -72,62 +67,27 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
+struct maestro {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct pci_dev *pdev;
+ struct mutex lock;
-static unsigned long in_use;
-
-static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
+ u16 io; /* base of Maestro card radio io (GPIO_DATA)*/
+ u16 muted; /* VIDEO_AUDIO_MUTE */
+ u16 stereo; /* VIDEO_TUNER_STEREO_ON */
+ u16 tuned; /* signal strength (0 or 0xffff) */
+};
-static int maestro_exclusive_open(struct file *file)
+static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return container_of(v4l2_dev, struct maestro, v4l2_dev);
}
-static int maestro_exclusive_release(struct file *file)
+static u32 radio_bits_get(struct maestro *dev)
{
- clear_bit(0, &in_use);
- return 0;
-}
-
-static void maestro_remove(struct pci_dev *pdev);
-
-static struct pci_device_id maestro_r_pci_tbl[] = {
- { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
- .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
- .class_mask = 0xffff00 },
- { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
- .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
- .class_mask = 0xffff00 },
- { 0 }
-};
-MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
-
-static struct pci_driver maestro_r_driver = {
- .name = "maestro_radio",
- .id_table = maestro_r_pci_tbl,
- .probe = maestro_probe,
- .remove = __devexit_p(maestro_remove),
-};
-
-static const struct v4l2_file_operations maestro_fops = {
- .owner = THIS_MODULE,
- .open = maestro_exclusive_open,
- .release = maestro_exclusive_release,
- .ioctl = video_ioctl2,
-};
-
-struct radio_device {
- u16 io, /* base of Maestro card radio io (GPIO_DATA)*/
- muted, /* VIDEO_AUDIO_MUTE */
- stereo, /* VIDEO_TUNER_STEREO_ON */
- tuned; /* signal strength (0 or 0xffff) */
-};
-
-static u32 radio_bits_get(struct radio_device *dev)
-{
- register u16 io=dev->io, l, rdata;
- register u32 data=0;
+ u16 io = dev->io, l, rdata;
+ u32 data = 0;
u16 omask;
omask = inw(io + IO_MASK);
@@ -135,25 +95,23 @@ static u32 radio_bits_get(struct radio_device *dev)
outw(0, io);
udelay(16);
- for (l=24;l--;) {
+ for (l = 24; l--;) {
outw(STR_CLK, io); /* HI state */
udelay(2);
- if(!l)
+ if (!l)
dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
outw(0, io); /* LO state */
udelay(2);
data <<= 1; /* shift data */
rdata = inw(io);
- if(!l)
- dev->stereo = rdata & STR_MOST ?
- 0 : 1;
- else
- if(rdata & STR_DATA)
- data++;
+ if (!l)
+ dev->stereo = (rdata & STR_MOST) ? 0 : 1;
+ else if (rdata & STR_DATA)
+ data++;
udelay(2);
}
- if(dev->muted)
+ if (dev->muted)
outw(STR_WREN, io);
udelay(4);
@@ -162,18 +120,18 @@ static u32 radio_bits_get(struct radio_device *dev)
return data & 0x3ffe;
}
-static void radio_bits_set(struct radio_device *dev, u32 data)
+static void radio_bits_set(struct maestro *dev, u32 data)
{
- register u16 io=dev->io, l, bits;
+ u16 io = dev->io, l, bits;
u16 omask, odir;
omask = inw(io + IO_MASK);
- odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+ odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
outw(odir | STR_DATA, io + IO_DIR);
outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
udelay(16);
- for (l=25;l;l--) {
- bits = ((data >> 18) & STR_DATA) | STR_WREN ;
+ for (l = 25; l; l--) {
+ bits = ((data >> 18) & STR_DATA) | STR_WREN;
data <<= 1; /* shift data */
outw(bits, io); /* start strobe */
udelay(2);
@@ -183,7 +141,7 @@ static void radio_bits_set(struct radio_device *dev, u32 data)
udelay(4);
}
- if(!dev->muted)
+ if (!dev->muted)
outw(0, io);
udelay(4);
@@ -195,78 +153,79 @@ static void radio_bits_set(struct radio_device *dev, u32 data)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct maestro *dev = video_drvdata(file);
+
strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
strlcpy(v->card, "Maestro Radio", sizeof(v->card));
- sprintf(v->bus_info, "PCI");
+ snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- (void)radio_bits_get(card);
+ mutex_lock(&dev->lock);
+ radio_bits_get(dev);
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
v->rangelow = FREQ_LO;
v->rangehigh = FREQ_HI;
- v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = V4L2_TUNER_CAP_LOW;
- if(card->stereo)
+ if (dev->stereo)
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = card->tuned;
+ v->signal = dev->tuned;
+ mutex_unlock(&dev->lock);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
return -EINVAL;
- radio_bits_set(card, FREQ2BITS(f->frequency));
+ mutex_lock(&dev->lock);
+ radio_bits_set(dev, FREQ2BITS(f->frequency));
+ mutex_unlock(&dev->lock);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
- f->frequency = BITS2FREQ(radio_bits_get(card));
+ mutex_lock(&dev->lock);
+ f->frequency = BITS2FREQ(radio_bits_get(dev));
+ mutex_unlock(&dev->lock);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
return -EINVAL;
}
@@ -274,11 +233,11 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
+ struct maestro *dev = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = card->muted;
+ ctrl->value = dev->muted;
return 0;
}
return -EINVAL;
@@ -287,56 +246,85 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
- register u16 io = card->io;
- register u16 omask = inw(io + IO_MASK);
+ struct maestro *dev = video_drvdata(file);
+ u16 io = dev->io;
+ u16 omask;
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ mutex_lock(&dev->lock);
+ omask = inw(io + IO_MASK);
outw(~STR_WREN, io + IO_MASK);
- outw((card->muted = ctrl->value ) ?
- STR_WREN : 0, io);
+ dev->muted = ctrl->value;
+ outw(dev->muted ? STR_WREN : 0, io);
udelay(4);
outw(omask, io + IO_MASK);
msleep(125);
+ mutex_unlock(&dev->lock);
return 0;
}
return -EINVAL;
}
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
{
- *i = 0;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+static int maestro_open(struct file *file)
{
- if (i != 0)
- return -EINVAL;
return 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
+static int maestro_release(struct file *file)
{
- if (a->index != 0)
- return -EINVAL;
return 0;
}
-static u16 __devinit radio_power_on(struct radio_device *dev)
+static const struct v4l2_file_operations maestro_fops = {
+ .owner = THIS_MODULE,
+ .open = maestro_open,
+ .release = maestro_release,
+ .ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+};
+
+static u16 __devinit radio_power_on(struct maestro *dev)
{
register u16 io = dev->io;
register u32 ofreq;
@@ -360,33 +348,11 @@ static u16 __devinit radio_power_on(struct radio_device *dev)
return (ofreq == radio_bits_get(dev));
}
-static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
-};
-
-static struct video_device maestro_radio = {
- .name = "Maestro radio",
- .fops = &maestro_fops,
- .ioctl_ops = &maestro_ioctl_ops,
- .release = video_device_release,
-};
-
static int __devinit maestro_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
- struct radio_device *radio_unit;
- struct video_device *maestro_radio_inst;
+ struct maestro *dev;
+ struct v4l2_device *v4l2_dev;
int retval;
retval = pci_enable_device(pdev);
@@ -397,46 +363,53 @@ static int __devinit maestro_probe(struct pci_dev *pdev,
retval = -ENOMEM;
- radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL);
- if (radio_unit == NULL) {
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
dev_err(&pdev->dev, "not enough memory\n");
goto err;
}
- radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
+ v4l2_dev = &dev->v4l2_dev;
+ mutex_init(&dev->lock);
+ dev->pdev = pdev;
- maestro_radio_inst = video_device_alloc();
- if (maestro_radio_inst == NULL) {
- dev_err(&pdev->dev, "not enough memory\n");
+ strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
+
+ retval = v4l2_device_register(&pdev->dev, v4l2_dev);
+ if (retval < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
goto errfr;
}
- memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio));
- video_set_drvdata(maestro_radio_inst, radio_unit);
- pci_set_drvdata(pdev, maestro_radio_inst);
+ dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
- retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, radio_nr);
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &maestro_fops;
+ dev->vdev.ioctl_ops = &maestro_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
if (retval) {
- printk(KERN_ERR "can't register video device!\n");
+ v4l2_err(v4l2_dev, "can't register video device!\n");
goto errfr1;
}
- if (!radio_power_on(radio_unit)) {
+ if (!radio_power_on(dev)) {
retval = -EIO;
goto errunr;
}
- dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ " "
- __DATE__ "\n");
- dev_info(&pdev->dev, "radio chip initialized\n");
+ v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
return 0;
errunr:
- video_unregister_device(maestro_radio_inst);
+ video_unregister_device(&dev->vdev);
errfr1:
- video_device_release(maestro_radio_inst);
+ v4l2_device_unregister(v4l2_dev);
errfr:
- kfree(radio_unit);
+ kfree(dev);
err:
return retval;
@@ -444,11 +417,31 @@ err:
static void __devexit maestro_remove(struct pci_dev *pdev)
{
- struct video_device *vdev = pci_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct maestro *dev = to_maestro(v4l2_dev);
- video_unregister_device(vdev);
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
}
+static struct pci_device_id maestro_r_pci_tbl[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
+ .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+ .class_mask = 0xffff00 },
+ { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
+ .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+ .class_mask = 0xffff00 },
+ { 0 }
+};
+MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
+
+static struct pci_driver maestro_r_driver = {
+ .name = "maestro_radio",
+ .id_table = maestro_r_pci_tbl,
+ .probe = maestro_probe,
+ .remove = __devexit_p(maestro_remove),
+};
+
static int __init maestro_radio_init(void)
{
int retval = pci_register_driver(&maestro_r_driver);
@@ -466,7 +459,3 @@ static void __exit maestro_radio_exit(void)
module_init(maestro_radio_init);
module_exit(maestro_radio_exit);
-
-MODULE_AUTHOR("Adam Tlalka, atlka@pg.gda.pl");
-MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
-MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c
index c5dc00aa9c9..2606f0b3035 100644
--- a/drivers/media/radio/radio-maxiradio.c
+++ b/drivers/media/radio/radio-maxiradio.c
@@ -37,38 +37,32 @@
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
#include <linux/mutex.h>
-
#include <linux/pci.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
+MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
+MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
+MODULE_LICENSE("GPL");
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
#define DRIVER_VERSION "0.77"
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,7,7)
-
-static struct video_device maxiradio_radio;
-
-#define dprintk(num, fmt, arg...) \
- do { \
- if (maxiradio_radio.debug >= num) \
- printk(KERN_DEBUG "%s: " fmt, \
- maxiradio_radio.name, ## arg); } while (0)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
+#define RADIO_VERSION KERNEL_VERSION(0, 7, 7)
+
+#define dprintk(dev, num, fmt, arg...) \
+ v4l2_dbg(num, debug, &dev->v4l2_dev, fmt, ## arg)
#ifndef PCI_VENDOR_ID_GUILLEMOT
#define PCI_VENDOR_ID_GUILLEMOT 0x5046
@@ -80,90 +74,70 @@ static struct v4l2_queryctrl radio_qctrl[] = {
/* TEA5757 pin mappings */
-static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16 ;
-
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
+static const int clk = 1, data = 2, wren = 4, mo_st = 8, power = 16;
-static unsigned long in_use;
-
-#define FREQ_LO 50*16000
-#define FREQ_HI 150*16000
+#define FREQ_LO (50 * 16000)
+#define FREQ_HI (150 * 16000)
#define FREQ_IF 171200 /* 10.7*16000 */
#define FREQ_STEP 200 /* 12.5*16 */
/* (x==fmhz*16*1000) -> bits */
-#define FREQ2BITS(x) ((( (unsigned int)(x)+FREQ_IF+(FREQ_STEP<<1)) \
- /(FREQ_STEP<<2))<<2)
+#define FREQ2BITS(x) \
+ ((((unsigned int)(x) + FREQ_IF + (FREQ_STEP << 1)) / (FREQ_STEP << 2)) << 2)
#define BITS2FREQ(x) ((x) * FREQ_STEP - FREQ_IF)
-static int maxiradio_exclusive_open(struct file *file)
+struct maxiradio
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
-
-static int maxiradio_exclusive_release(struct file *file)
-{
- clear_bit(0, &in_use);
- return 0;
-}
-
-static const struct v4l2_file_operations maxiradio_fops = {
- .owner = THIS_MODULE,
- .open = maxiradio_exclusive_open,
- .release = maxiradio_exclusive_release,
- .ioctl = video_ioctl2,
-};
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct pci_dev *pdev;
-static struct radio_device
-{
- __u16 io, /* base of radio io */
- muted, /* VIDEO_AUDIO_MUTE */
- stereo, /* VIDEO_TUNER_STEREO_ON */
- tuned; /* signal strength (0 or 0xffff) */
+ u16 io; /* base of radio io */
+ u16 muted; /* VIDEO_AUDIO_MUTE */
+ u16 stereo; /* VIDEO_TUNER_STEREO_ON */
+ u16 tuned; /* signal strength (0 or 0xffff) */
unsigned long freq;
struct mutex lock;
-} radio_unit = {
- .muted =1,
- .freq = FREQ_LO,
};
-static void outbit(unsigned long bit, __u16 io)
+static inline struct maxiradio *to_maxiradio(struct v4l2_device *v4l2_dev)
{
- if (bit != 0)
- {
- outb( power|wren|data ,io); udelay(4);
- outb( power|wren|data|clk ,io); udelay(4);
- outb( power|wren|data ,io); udelay(4);
- }
- else
- {
- outb( power|wren ,io); udelay(4);
- outb( power|wren|clk ,io); udelay(4);
- outb( power|wren ,io); udelay(4);
- }
+ return container_of(v4l2_dev, struct maxiradio, v4l2_dev);
}
-static void turn_power(__u16 io, int p)
+static void outbit(unsigned long bit, u16 io)
+{
+ int val = power | wren | (bit ? data : 0);
+
+ outb(val, io);
+ udelay(4);
+ outb(val | clk, io);
+ udelay(4);
+ outb(val, io);
+ udelay(4);
+}
+
+static void turn_power(struct maxiradio *dev, int p)
{
if (p != 0) {
- dprintk(1, "Radio powered on\n");
- outb(power, io);
+ dprintk(dev, 1, "Radio powered on\n");
+ outb(power, dev->io);
} else {
- dprintk(1, "Radio powered off\n");
- outb(0,io);
+ dprintk(dev, 1, "Radio powered off\n");
+ outb(0, dev->io);
}
}
-static void set_freq(__u16 io, __u32 freq)
+static void set_freq(struct maxiradio *dev, u32 freq)
{
unsigned long int si;
int bl;
+ int io = dev->io;
int val = FREQ2BITS(freq);
/* TEA5757 shift register bits (see pdf) */
@@ -188,14 +162,14 @@ static void set_freq(__u16 io, __u32 freq)
si >>= 1;
}
- dprintk(1, "Radio freq set to %d.%02d MHz\n",
+ dprintk(dev, 1, "Radio freq set to %d.%02d MHz\n",
freq / 16000,
freq % 16000 * 100 / 16000);
- turn_power(io, 1);
+ turn_power(dev, 1);
}
-static int get_stereo(__u16 io)
+static int get_stereo(u16 io)
{
outb(power,io);
udelay(4);
@@ -203,7 +177,7 @@ static int get_stereo(__u16 io)
return !(inb(io) & mo_st);
}
-static int get_tune(__u16 io)
+static int get_tune(u16 io)
{
outb(power+clk,io);
udelay(4);
@@ -212,95 +186,84 @@ static int get_tune(__u16 io)
}
-static int vidioc_querycap (struct file *file, void *priv,
+static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
- strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver));
- strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
- v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ struct maxiradio *dev = video_drvdata(file);
+ strlcpy(v->driver, "radio-maxiradio", sizeof(v->driver));
+ strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof(v->card));
+ snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", pci_name(dev->pdev));
+ v->version = RADIO_VERSION;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
-static int vidioc_g_tuner (struct file *file, void *priv,
+static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- memset(v,0,sizeof(*v));
- strcpy(v->name, "FM");
+ mutex_lock(&dev->lock);
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
-
- v->rangelow=FREQ_LO;
- v->rangehigh=FREQ_HI;
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(get_stereo(card->io))
+ v->rangelow = FREQ_LO;
+ v->rangehigh = FREQ_HI;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (get_stereo(dev->io))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xffff*get_tune(card->io);
+ v->signal = 0xffff * get_tune(dev->io);
+ mutex_unlock(&dev->lock);
return 0;
}
-static int vidioc_s_tuner (struct file *file, void *priv,
+static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_audio (struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "FM");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
-
return 0;
}
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static int vidioc_s_audio (struct file *file, void *priv,
+static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
-
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int vidioc_s_frequency (struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) {
- dprintk(1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
+ dprintk(dev, 1, "radio freq (%d.%02d MHz) out of range (%d-%d)\n",
f->frequency / 16000,
f->frequency % 16000 * 100 / 16000,
FREQ_LO / 16000, FREQ_HI / 16000);
@@ -308,75 +271,91 @@ static int vidioc_s_frequency (struct file *file, void *priv,
return -EINVAL;
}
- card->freq = f->frequency;
- set_freq(card->io, card->freq);
+ mutex_lock(&dev->lock);
+ dev->freq = f->frequency;
+ set_freq(dev, dev->freq);
msleep(125);
+ mutex_unlock(&dev->lock);
return 0;
}
-static int vidioc_g_frequency (struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
- f->frequency = card->freq;
+ f->frequency = dev->freq;
- dprintk(4, "radio freq is %d.%02d MHz",
+ dprintk(dev, 4, "radio freq is %d.%02d MHz",
f->frequency / 16000,
f->frequency % 16000 * 100 / 16000);
return 0;
}
-static int vidioc_queryctrl (struct file *file, void *priv,
+static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
- return (0);
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
-
return -EINVAL;
}
-static int vidioc_g_ctrl (struct file *file, void *priv,
- struct v4l2_control *ctrl)
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value=card->muted;
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = dev->muted;
+ return 0;
}
return -EINVAL;
}
-static int vidioc_s_ctrl (struct file *file, void *priv,
- struct v4l2_control *ctrl)
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
{
- struct radio_device *card = video_drvdata(file);
+ struct maxiradio *dev = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- card->muted = ctrl->value;
- if(card->muted)
- turn_power(card->io, 0);
- else
- set_freq(card->io, card->freq);
- return 0;
+ case V4L2_CID_AUDIO_MUTE:
+ mutex_lock(&dev->lock);
+ dev->muted = ctrl->value;
+ if (dev->muted)
+ turn_power(dev, 0);
+ else
+ set_freq(dev, dev->freq);
+ mutex_unlock(&dev->lock);
+ return 0;
}
return -EINVAL;
}
+static int maxiradio_open(struct file *file)
+{
+ return 0;
+}
+
+static int maxiradio_release(struct file *file)
+{
+ return 0;
+}
+
+static const struct v4l2_file_operations maxiradio_fops = {
+ .owner = THIS_MODULE,
+ .open = maxiradio_open,
+ .release = maxiradio_release,
+ .ioctl = video_ioctl2,
+};
+
static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
@@ -392,60 +371,84 @@ static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device maxiradio_radio = {
- .name = "Maxi Radio FM2000 radio",
- .fops = &maxiradio_fops,
- .ioctl_ops = &maxiradio_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __devinit maxiradio_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- if(!request_region(pci_resource_start(pdev, 0),
+ struct maxiradio *dev;
+ struct v4l2_device *v4l2_dev;
+ int retval = -ENOMEM;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev == NULL) {
+ dev_err(&pdev->dev, "not enough memory\n");
+ return -ENOMEM;
+ }
+
+ v4l2_dev = &dev->v4l2_dev;
+ mutex_init(&dev->lock);
+ dev->pdev = pdev;
+ dev->muted = 1;
+ dev->freq = FREQ_LO;
+
+ strlcpy(v4l2_dev->name, "maxiradio", sizeof(v4l2_dev->name));
+
+ retval = v4l2_device_register(&pdev->dev, v4l2_dev);
+ if (retval < 0) {
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ goto errfr;
+ }
+
+ if (!request_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0), "Maxi Radio FM 2000")) {
- printk(KERN_ERR "radio-maxiradio: can't reserve I/O ports\n");
+ v4l2_err(v4l2_dev, "can't reserve I/O ports\n");
goto err_out;
}
if (pci_enable_device(pdev))
goto err_out_free_region;
- radio_unit.io = pci_resource_start(pdev, 0);
- mutex_init(&radio_unit.lock);
- video_set_drvdata(&maxiradio_radio, &radio_unit);
+ dev->io = pci_resource_start(pdev, 0);
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &maxiradio_fops;
+ dev->vdev.ioctl_ops = &maxiradio_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
- if (video_register_device(&maxiradio_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- printk("radio-maxiradio: can't register device!");
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_err(v4l2_dev, "can't register device!");
goto err_out_free_region;
}
- printk(KERN_INFO "radio-maxiradio: version "
- DRIVER_VERSION
- " time "
- __TIME__ " "
- __DATE__
- "\n");
+ v4l2_info(v4l2_dev, "version " DRIVER_VERSION
+ " time " __TIME__ " " __DATE__ "\n");
- printk(KERN_INFO "radio-maxiradio: found Guillemot MAXI Radio device (io = 0x%x)\n",
- radio_unit.io);
+ v4l2_info(v4l2_dev, "found Guillemot MAXI Radio device (io = 0x%x)\n",
+ dev->io);
return 0;
err_out_free_region:
release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
err_out:
+ v4l2_device_unregister(v4l2_dev);
+errfr:
+ kfree(dev);
return -ENODEV;
}
static void __devexit maxiradio_remove_one(struct pci_dev *pdev)
{
- video_unregister_device(&maxiradio_radio);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct maxiradio *dev = to_maxiradio(v4l2_dev);
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
release_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
}
static struct pci_device_id maxiradio_pci_tbl[] = {
{ PCI_VENDOR_ID_GUILLEMOT, PCI_DEVICE_ID_GUILLEMOT_MAXIRADIO,
PCI_ANY_ID, PCI_ANY_ID, },
- { 0,}
+ { 0 }
};
MODULE_DEVICE_TABLE(pci, maxiradio_pci_tbl);
@@ -469,10 +472,3 @@ static void __exit maxiradio_radio_exit(void)
module_init(maxiradio_radio_init);
module_exit(maxiradio_radio_exit);
-
-MODULE_AUTHOR("Dimitromanolakis Apostolos, apdim@grecian.net");
-MODULE_DESCRIPTION("Radio driver for the Guillemot Maxi Radio FM2000 radio.");
-MODULE_LICENSE("GPL");
-
-module_param_named(debug,maxiradio_radio.debug, int, 0644);
-MODULE_PARM_DESC(debug,"activates debug info");
diff --git a/drivers/media/radio/radio-mr800.c b/drivers/media/radio/radio-mr800.c
index fdfc7bf86b9..ded25bfb366 100644
--- a/drivers/media/radio/radio-mr800.c
+++ b/drivers/media/radio/radio-mr800.c
@@ -22,7 +22,7 @@
*/
/*
- * Big thanks to authors of dsbr100.c and radio-si470x.c
+ * Big thanks to authors and contributors of dsbr100.c and radio-si470x.c
*
* When work was looked pretty good, i discover this:
* http://av-usbradio.sourceforge.net/index.php
@@ -30,18 +30,23 @@
* Latest release of theirs project was in 2005.
* Probably, this driver could be improved trough using their
* achievements (specifications given).
- * So, we have smth to begin with.
+ * Also, Faidon Liambotis <paravoid@debian.org> wrote nice driver for this radio
+ * in 2007. He allowed to use his driver to improve current mr800 radio driver.
+ * http://kerneltrap.org/mailarchive/linux-usb-devel/2007/10/11/342492
*
- * History:
* Version 0.01: First working version.
* It's required to blacklist AverMedia USB Radio
* in usbhid/hid-quirks.c
+ * Version 0.10: A lot of cleanups and fixes: unpluging the device,
+ * few mutex locks were added, codinstyle issues, etc.
+ * Added stereo support. Thanks to
+ * Douglas Schilling Landgraf <dougsland@gmail.com> and
+ * David Ellingsworth <david@identd.dyndns.org>
+ * for discussion, help and support.
*
* Many things to do:
* - Correct power managment of device (suspend & resume)
- * - Make x86 independance (little-endian and big-endian stuff)
* - Add code for scanning and smooth tuning
- * - Checked and add stereo&mono stuff
* - Add code for sensitivity value
* - Correct mistakes
* - In Japan another FREQ_MIN and FREQ_MAX
@@ -62,8 +67,8 @@
/* driver and module definitions */
#define DRIVER_AUTHOR "Alexey Klimov <klimov.linux@gmail.com>"
#define DRIVER_DESC "AverMedia MR 800 USB FM radio driver"
-#define DRIVER_VERSION "0.01"
-#define RADIO_VERSION KERNEL_VERSION(0, 0, 1)
+#define DRIVER_VERSION "0.10"
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 0)
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
@@ -87,6 +92,22 @@ devices, that would be 76 and 91. */
#define FREQ_MAX 108.0
#define FREQ_MUL 16000
+/*
+ * Commands that device should understand
+ * List isnt full and will be updated with implementation of new functions
+ */
+#define AMRADIO_SET_FREQ 0xa4
+#define AMRADIO_SET_MUTE 0xab
+#define AMRADIO_SET_MONO 0xae
+
+/* Comfortable defines for amradio_set_mute */
+#define AMRADIO_START 0x00
+#define AMRADIO_STOP 0x01
+
+/* Comfortable defines for amradio_set_stereo */
+#define WANT_STEREO 0x00
+#define WANT_MONO 0x01
+
/* module parameter */
static int radio_nr = -1;
module_param(radio_nr, int, 0);
@@ -169,43 +190,48 @@ static struct usb_driver usb_amradio_driver = {
.supports_autosuspend = 0,
};
-/* switch on radio. Send 8 bytes to device. */
-static int amradio_start(struct amradio_device *radio)
+/* switch on/off the radio. Send 8 bytes to device */
+static int amradio_set_mute(struct amradio_device *radio, char argument)
{
int retval;
int size;
+ /* safety check */
+ if (radio->removed)
+ return -EIO;
+
mutex_lock(&radio->lock);
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
radio->buffer[3] = 0x00;
- radio->buffer[4] = 0xab;
- radio->buffer[5] = 0x00;
+ radio->buffer[4] = AMRADIO_SET_MUTE;
+ radio->buffer[5] = argument;
radio->buffer[6] = 0x00;
radio->buffer[7] = 0x00;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
mutex_unlock(&radio->lock);
return retval;
}
- radio->muted = 0;
+ radio->muted = argument;
mutex_unlock(&radio->lock);
return retval;
}
-/* switch off radio */
-static int amradio_stop(struct amradio_device *radio)
+/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
+static int amradio_setfreq(struct amradio_device *radio, int freq)
{
int retval;
int size;
+ unsigned short freq_send = 0x10 + (freq >> 3) / 25;
/* safety check */
if (radio->removed)
@@ -216,33 +242,46 @@ static int amradio_stop(struct amradio_device *radio)
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
- radio->buffer[3] = 0x00;
- radio->buffer[4] = 0xab;
- radio->buffer[5] = 0x01;
+ radio->buffer[3] = 0x03;
+ radio->buffer[4] = AMRADIO_SET_FREQ;
+ radio->buffer[5] = 0x00;
radio->buffer[6] = 0x00;
- radio->buffer[7] = 0x00;
+ radio->buffer[7] = 0x08;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
mutex_unlock(&radio->lock);
return retval;
}
- radio->muted = 1;
+ /* frequency is calculated from freq_send and placed in first 2 bytes */
+ radio->buffer[0] = (freq_send >> 8) & 0xff;
+ radio->buffer[1] = freq_send & 0xff;
+ radio->buffer[2] = 0x01;
+ radio->buffer[3] = 0x00;
+ radio->buffer[4] = 0x00;
+ /* 5 and 6 bytes of buffer already = 0x00 */
+ radio->buffer[7] = 0x00;
+
+ retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
+ (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
+
+ if (retval < 0 || size != BUFFER_LENGTH) {
+ mutex_unlock(&radio->lock);
+ return retval;
+ }
mutex_unlock(&radio->lock);
return retval;
}
-/* set a frequency, freq is defined by v4l's TUNER_LOW, i.e. 1/16th kHz */
-static int amradio_setfreq(struct amradio_device *radio, int freq)
+static int amradio_set_stereo(struct amradio_device *radio, char argument)
{
int retval;
int size;
- unsigned short freq_send = 0x13 + (freq >> 3) / 25;
/* safety check */
if (radio->removed)
@@ -253,50 +292,33 @@ static int amradio_setfreq(struct amradio_device *radio, int freq)
radio->buffer[0] = 0x00;
radio->buffer[1] = 0x55;
radio->buffer[2] = 0xaa;
- radio->buffer[3] = 0x03;
- radio->buffer[4] = 0xa4;
- radio->buffer[5] = 0x00;
- radio->buffer[6] = 0x00;
- radio->buffer[7] = 0x08;
-
- retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
- (void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
-
- if (retval) {
- mutex_unlock(&radio->lock);
- return retval;
- }
-
- /* frequency is calculated from freq_send and placed in first 2 bytes */
- radio->buffer[0] = (freq_send >> 8) & 0xff;
- radio->buffer[1] = freq_send & 0xff;
- radio->buffer[2] = 0x01;
radio->buffer[3] = 0x00;
- radio->buffer[4] = 0x00;
- /* 5 and 6 bytes of buffer already = 0x00 */
+ radio->buffer[4] = AMRADIO_SET_MONO;
+ radio->buffer[5] = argument;
+ radio->buffer[6] = 0x00;
radio->buffer[7] = 0x00;
retval = usb_bulk_msg(radio->usbdev, usb_sndintpipe(radio->usbdev, 2),
(void *) (radio->buffer), BUFFER_LENGTH, &size, USB_TIMEOUT);
- if (retval) {
+ if (retval < 0 || size != BUFFER_LENGTH) {
+ radio->stereo = -1;
mutex_unlock(&radio->lock);
return retval;
}
- radio->stereo = 0;
+ radio->stereo = 1;
mutex_unlock(&radio->lock);
return retval;
}
-/* USB subsystem interface begins here */
-
-/* handle unplugging of the device, release data structures
-if nothing keeps us from doing it. If something is still
-keeping us busy, the release callback of v4l will take care
-of releasing it. */
+/* Handle unplugging the device.
+ * We call video_unregister_device in any case.
+ * The last function called in this procedure is
+ * usb_amradio_device_release.
+ */
static void usb_amradio_disconnect(struct usb_interface *intf)
{
struct amradio_device *radio = usb_get_intfdata(intf);
@@ -313,9 +335,11 @@ static void usb_amradio_disconnect(struct usb_interface *intf)
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
+ struct amradio_device *radio = video_drvdata(file);
+
strlcpy(v->driver, "radio-mr800", sizeof(v->driver));
strlcpy(v->card, "AverMedia MR 800 USB FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "USB");
+ usb_make_path(radio->usbdev, v->bus_info, sizeof(v->bus_info));
v->version = RADIO_VERSION;
v->capabilities = V4L2_CAP_TUNER;
return 0;
@@ -326,6 +350,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -337,7 +362,16 @@ static int vidioc_g_tuner(struct file *file, void *priv,
/* TODO: Add function which look is signal stereo or not
* amradio_getstat(radio);
*/
- radio->stereo = -1;
+
+/* we call amradio_set_stereo to set radio->stereo
+ * Honestly, amradio_getstat should cover this in future and
+ * amradio_set_stereo shouldn't be here
+ */
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+
strcpy(v->name, "FM");
v->type = V4L2_TUNER_RADIO;
v->rangelow = FREQ_MIN * FREQ_MUL;
@@ -358,6 +392,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -365,6 +400,25 @@ static int vidioc_s_tuner(struct file *file, void *priv,
if (v->index > 0)
return -EINVAL;
+
+ /* mono/stereo selector */
+ switch (v->audmode) {
+ case V4L2_TUNER_MODE_MONO:
+ retval = amradio_set_stereo(radio, WANT_MONO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set mono failed\n");
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+ break;
+ default:
+ return -EINVAL;
+ }
+
return 0;
}
@@ -373,13 +427,18 @@ static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
return -EIO;
+ mutex_lock(&radio->lock);
radio->curfreq = f->frequency;
- if (amradio_setfreq(radio, radio->curfreq) < 0)
+ mutex_unlock(&radio->lock);
+
+ retval = amradio_setfreq(radio, radio->curfreq);
+ if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"set frequency failed\n");
return 0;
@@ -438,6 +497,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
/* safety check */
if (radio->removed)
@@ -446,13 +506,15 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value) {
- if (amradio_stop(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"amradio_stop failed\n");
return -1;
}
} else {
- if (amradio_start(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"amradio_start failed\n");
return -1;
@@ -503,20 +565,29 @@ static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
static int usb_amradio_open(struct file *file)
{
struct amradio_device *radio = video_get_drvdata(video_devdata(file));
+ int retval;
lock_kernel();
radio->users = 1;
radio->muted = 1;
- if (amradio_start(radio) < 0) {
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0) {
amradio_dev_warn(&radio->videodev->dev,
"radio did not start up properly\n");
radio->users = 0;
unlock_kernel();
return -EIO;
}
- if (amradio_setfreq(radio, radio->curfreq) < 0)
+
+ retval = amradio_set_stereo(radio, WANT_STEREO);
+ if (retval < 0)
+ amradio_dev_warn(&radio->videodev->dev,
+ "set stereo failed\n");
+
+ retval = amradio_setfreq(radio, radio->curfreq);
+ if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"set frequency failed\n");
@@ -533,10 +604,12 @@ static int usb_amradio_close(struct file *file)
if (!radio)
return -ENODEV;
+ mutex_lock(&radio->lock);
radio->users = 0;
+ mutex_unlock(&radio->lock);
if (!radio->removed) {
- retval = amradio_stop(radio);
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
if (retval < 0)
amradio_dev_warn(&radio->videodev->dev,
"amradio_stop failed\n");
@@ -549,8 +622,10 @@ static int usb_amradio_close(struct file *file)
static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
{
struct amradio_device *radio = usb_get_intfdata(intf);
+ int retval;
- if (amradio_stop(radio) < 0)
+ retval = amradio_set_mute(radio, AMRADIO_STOP);
+ if (retval < 0)
dev_warn(&intf->dev, "amradio_stop failed\n");
dev_info(&intf->dev, "going into suspend..\n");
@@ -562,8 +637,10 @@ static int usb_amradio_suspend(struct usb_interface *intf, pm_message_t message)
static int usb_amradio_resume(struct usb_interface *intf)
{
struct amradio_device *radio = usb_get_intfdata(intf);
+ int retval;
- if (amradio_start(radio) < 0)
+ retval = amradio_set_mute(radio, AMRADIO_START);
+ if (retval < 0)
dev_warn(&intf->dev, "amradio_start failed\n");
dev_info(&intf->dev, "coming out of suspend..\n");
@@ -614,28 +691,32 @@ static struct video_device amradio_videodev_template = {
.release = usb_amradio_device_release,
};
-/* check if the device is present and register with v4l and
-usb if it is */
+/* check if the device is present and register with v4l and usb if it is */
static int usb_amradio_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct amradio_device *radio;
+ int retval;
radio = kmalloc(sizeof(struct amradio_device), GFP_KERNEL);
- if (!(radio))
+ if (!radio) {
+ dev_err(&intf->dev, "kmalloc for amradio_device failed\n");
return -ENOMEM;
+ }
radio->buffer = kmalloc(BUFFER_LENGTH, GFP_KERNEL);
- if (!(radio->buffer)) {
+ if (!radio->buffer) {
+ dev_err(&intf->dev, "kmalloc for radio->buffer failed\n");
kfree(radio);
return -ENOMEM;
}
radio->videodev = video_device_alloc();
- if (!(radio->videodev)) {
+ if (!radio->videodev) {
+ dev_err(&intf->dev, "video_device_alloc failed\n");
kfree(radio->buffer);
kfree(radio);
return -ENOMEM;
@@ -648,12 +729,14 @@ static int usb_amradio_probe(struct usb_interface *intf,
radio->users = 0;
radio->usbdev = interface_to_usbdev(intf);
radio->curfreq = 95.16 * FREQ_MUL;
+ radio->stereo = -1;
mutex_init(&radio->lock);
video_set_drvdata(radio->videodev, radio);
- if (video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr)) {
- dev_warn(&intf->dev, "could not register video device\n");
+ retval = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr);
+ if (retval < 0) {
+ dev_err(&intf->dev, "could not register video device\n");
video_device_release(radio->videodev);
kfree(radio->buffer);
kfree(radio);
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c
index 2587227214b..d1e6b01d4ec 100644
--- a/drivers/media/radio/radio-rtrack2.c
+++ b/drivers/media/radio/radio-rtrack2.c
@@ -13,34 +13,16 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+MODULE_AUTHOR("Ben Pfaff");
+MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_RTRACK2_PORT
#define CONFIG_RADIO_RTRACK2_PORT -1
@@ -48,79 +30,88 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_RTRACK2_PORT;
static int radio_nr = -1;
-static spinlock_t lock;
-struct rt_device
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct rtrack2
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
unsigned long curfreq;
int muted;
+ struct mutex lock;
};
+static struct rtrack2 rtrack2_card;
+
/* local things */
-static void rt_mute(struct rt_device *dev)
+static void rt_mute(struct rtrack2 *dev)
{
- if(dev->muted)
+ if (dev->muted)
return;
- spin_lock(&lock);
- outb(1, io);
- spin_unlock(&lock);
+ mutex_lock(&dev->lock);
+ outb(1, dev->io);
+ mutex_unlock(&dev->lock);
dev->muted = 1;
}
-static void rt_unmute(struct rt_device *dev)
+static void rt_unmute(struct rtrack2 *dev)
{
if(dev->muted == 0)
return;
- spin_lock(&lock);
- outb(0, io);
- spin_unlock(&lock);
+ mutex_lock(&dev->lock);
+ outb(0, dev->io);
+ mutex_unlock(&dev->lock);
dev->muted = 0;
}
-static void zero(void)
+static void zero(struct rtrack2 *dev)
{
- outb_p(1, io);
- outb_p(3, io);
- outb_p(1, io);
+ outb_p(1, dev->io);
+ outb_p(3, dev->io);
+ outb_p(1, dev->io);
}
-static void one(void)
+static void one(struct rtrack2 *dev)
{
- outb_p(5, io);
- outb_p(7, io);
- outb_p(5, io);
+ outb_p(5, dev->io);
+ outb_p(7, dev->io);
+ outb_p(5, dev->io);
}
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+static int rt_setfreq(struct rtrack2 *dev, unsigned long freq)
{
int i;
+ mutex_lock(&dev->lock);
+ dev->curfreq = freq;
freq = freq / 200 + 856;
- spin_lock(&lock);
-
- outb_p(0xc8, io);
- outb_p(0xc9, io);
- outb_p(0xc9, io);
+ outb_p(0xc8, dev->io);
+ outb_p(0xc9, dev->io);
+ outb_p(0xc9, dev->io);
for (i = 0; i < 10; i++)
- zero ();
+ zero(dev);
for (i = 14; i >= 0; i--)
if (freq & (1 << i))
- one ();
+ one(dev);
else
- zero ();
+ zero(dev);
- outb_p(0xc8, io);
+ outb_p(0xc8, dev->io);
if (!dev->muted)
- outb_p(0, io);
+ outb_p(0, dev->io);
- spin_unlock(&lock);
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -129,61 +120,61 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
strlcpy(v->card, "RadioTrack II", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
+ return v->index ? -EINVAL : 0;
}
-static int rt_getsigstr(struct rt_device *dev)
+static int rt_getsigstr(struct rtrack2 *dev)
{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
+ int sig = 1;
+
+ mutex_lock(&dev->lock);
+ if (inb(dev->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&dev->lock);
+ return sig;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (88*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 88 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF*rt_getsigstr(rt);
+ v->signal = 0xFFFF * rt_getsigstr(rt);
return 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
+ rt_setfreq(rt, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = rt->curfreq;
@@ -193,14 +184,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
}
return -EINVAL;
}
@@ -208,7 +196,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -227,7 +215,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -246,17 +234,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -265,36 +242,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct rt_device rtrack2_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int rtrack2_exclusive_open(struct file *file)
+static int rtrack2_open(struct file *file)
{
- return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int rtrack2_exclusive_release(struct file *file)
+static int rtrack2_release(struct file *file)
{
- clear_bit(0, &rtrack2_unit.in_use);
return 0;
}
static const struct v4l2_file_operations rtrack2_fops = {
.owner = THIS_MODULE,
- .open = rtrack2_exclusive_open,
- .release = rtrack2_exclusive_release,
+ .open = rtrack2_open,
+ .release = rtrack2_release,
.ioctl = video_ioctl2,
};
@@ -313,62 +292,61 @@ static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device rtrack2_radio = {
- .name = "RadioTrack II radio",
- .fops = &rtrack2_fops,
- .ioctl_ops = &rtrack2_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init rtrack2_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
+ struct rtrack2 *dev = &rtrack2_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name));
+ dev->io = io;
+ if (dev->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or io=0x30c\n");
return -EINVAL;
}
- if (!request_region(io, 4, "rtrack2"))
- {
- printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
+ if (!request_region(dev->io, 4, "rtrack2")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io);
return -EBUSY;
}
- video_set_drvdata(&rtrack2_radio, &rtrack2_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(dev->io, 4);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
- spin_lock_init(&lock);
- if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 4);
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &rtrack2_fops;
+ dev->vdev.ioctl_ops = &rtrack2_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ mutex_init(&dev->lock);
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(dev->io, 4);
return -EINVAL;
}
- printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
+ v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
/* mute card - prevents noisy bootups */
- outb(1, io);
- rtrack2_unit.muted = 1;
+ outb(1, dev->io);
+ dev->muted = 1;
return 0;
}
-MODULE_AUTHOR("Ben Pfaff");
-MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit rtrack2_cleanup_module(void)
+static void __exit rtrack2_exit(void)
{
- video_unregister_device(&rtrack2_radio);
- release_region(io,4);
+ struct rtrack2 *dev = &rtrack2_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 4);
}
module_init(rtrack2_init);
-module_exit(rtrack2_cleanup_module);
-
-/*
- Local variables:
- compile-command: "mmake"
- End:
-*/
+module_exit(rtrack2_exit);
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index d358e48c242..f4784f0d1a8 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -22,113 +22,109 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/isapnp.h>
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/mutex.h>
+#include <linux/videodev2.h> /* kernel radio structs */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
+MODULE_DESCRIPTION("A driver for the SF16MI radio.");
+MODULE_LICENSE("GPL");
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- }
-};
+static int io = -1;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
-struct fmi_device
+struct fmi
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol; /* 1 or 0 */
unsigned long curfreq; /* freq in kHz */
__u32 flags;
+ struct mutex lock;
};
-static int io = -1;
-static int radio_nr = -1;
-static struct pnp_dev *dev = NULL;
-static struct mutex lock;
+static struct fmi fmi_card;
+static struct pnp_dev *dev;
/* 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),
* other bits will be truncated, e.g 92.7400016 -> 92.7, but
* 92.7400017 -> 92.75
*/
-#define RSF16_ENCODE(x) ((x)/800+214)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
+#define RSF16_ENCODE(x) ((x) / 800 + 214)
+#define RSF16_MINFREQ (87 * 16000)
+#define RSF16_MAXFREQ (108 * 16000)
-static void outbits(int bits, unsigned int data, int port)
+static void outbits(int bits, unsigned int data, int io)
{
- while(bits--) {
- if(data & 1) {
- outb(5, port);
+ while (bits--) {
+ if (data & 1) {
+ outb(5, io);
udelay(6);
- outb(7, port);
+ outb(7, io);
udelay(6);
} else {
- outb(1, port);
+ outb(1, io);
udelay(6);
- outb(3, port);
+ outb(3, io);
udelay(6);
}
- data>>=1;
+ data >>= 1;
}
}
-static inline void fmi_mute(int port)
+static inline void fmi_mute(struct fmi *fmi)
{
- mutex_lock(&lock);
- outb(0x00, port);
- mutex_unlock(&lock);
+ mutex_lock(&fmi->lock);
+ outb(0x00, fmi->io);
+ mutex_unlock(&fmi->lock);
}
-static inline void fmi_unmute(int port)
+static inline void fmi_unmute(struct fmi *fmi)
{
- mutex_lock(&lock);
- outb(0x08, port);
- mutex_unlock(&lock);
+ mutex_lock(&fmi->lock);
+ outb(0x08, fmi->io);
+ mutex_unlock(&fmi->lock);
}
-static inline int fmi_setfreq(struct fmi_device *dev)
+static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq)
{
- int myport = dev->port;
- unsigned long freq = dev->curfreq;
+ mutex_lock(&fmi->lock);
+ fmi->curfreq = freq;
- mutex_lock(&lock);
-
- outbits(16, RSF16_ENCODE(freq), myport);
- outbits(8, 0xC0, myport);
+ outbits(16, RSF16_ENCODE(freq), fmi->io);
+ outbits(8, 0xC0, fmi->io);
msleep(143); /* was schedule_timeout(HZ/7) */
- mutex_unlock(&lock);
- if (dev->curvol) fmi_unmute(myport);
+ mutex_unlock(&fmi->lock);
+ if (fmi->curvol)
+ fmi_unmute(fmi);
return 0;
}
-static inline int fmi_getsigstr(struct fmi_device *dev)
+static inline int fmi_getsigstr(struct fmi *fmi)
{
int val;
int res;
- int myport = dev->port;
-
- mutex_lock(&lock);
- val = dev->curvol ? 0x08 : 0x00; /* unmute/mute */
- outb(val, myport);
- outb(val | 0x10, myport);
+ mutex_lock(&fmi->lock);
+ val = fmi->curvol ? 0x08 : 0x00; /* unmute/mute */
+ outb(val, fmi->io);
+ outb(val | 0x10, fmi->io);
msleep(143); /* was schedule_timeout(HZ/7) */
- res = (int)inb(myport+1);
- outb(val, myport);
+ res = (int)inb(fmi->io + 1);
+ outb(val, fmi->io);
- mutex_unlock(&lock);
+ mutex_unlock(&fmi->lock);
return (res & 2) ? 0 : 0xFFFF;
}
@@ -137,9 +133,9 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
strlcpy(v->card, "SF16-FMx radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
@@ -147,18 +143,18 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
int mult;
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rangelow = RSF16_MINFREQ / mult;
+ v->rangehigh = RSF16_MAXFREQ / mult;
v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
- v->capability = fmi->flags&V4L2_TUNER_CAP_LOW;
+ v->capability = fmi->flags & V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_STEREO;
v->signal = fmi_getsigstr(fmi);
return 0;
@@ -167,32 +163,29 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
f->frequency *= 1000;
if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
+ f->frequency > RSF16_MAXFREQ)
return -EINVAL;
- /*rounding in steps of 800 to match th freq
- that will be used */
- fmi->curfreq = (f->frequency/800)*800;
- fmi_setfreq(fmi);
+ /* rounding in steps of 800 to match the freq
+ that will be used */
+ fmi_setfreq(fmi, (f->frequency / 800) * 800);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = fmi->curfreq;
@@ -204,14 +197,9 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
}
return -EINVAL;
}
@@ -219,7 +207,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -232,31 +220,20 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmi_device *fmi = video_drvdata(file);
+ struct fmi *fmi = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
- fmi_mute(fmi->port);
+ fmi_mute(fmi);
else
- fmi_unmute(fmi->port);
+ fmi_unmute(fmi);
fmi->curvol = ctrl->value;
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -265,36 +242,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct fmi_device fmi_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int fmi_exclusive_open(struct file *file)
+static int fmi_open(struct file *file)
{
- return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int fmi_exclusive_release(struct file *file)
+static int fmi_release(struct file *file)
{
- clear_bit(0, &fmi_unit.in_use);
return 0;
}
static const struct v4l2_file_operations fmi_fops = {
.owner = THIS_MODULE,
- .open = fmi_exclusive_open,
- .release = fmi_exclusive_release,
+ .open = fmi_open,
+ .release = fmi_release,
.ioctl = video_ioctl2,
};
@@ -313,13 +292,6 @@ static const struct v4l2_ioctl_ops fmi_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device fmi_radio = {
- .name = "SF16FMx radio",
- .fops = &fmi_fops,
- .ioctl_ops = &fmi_ioctl_ops,
- .release = video_device_release_empty,
-};
-
/* ladis: this is my card. does any other types exist? */
static struct isapnp_device_id id_table[] __devinitdata = {
{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,
@@ -344,7 +316,7 @@ static int __init isapnp_fmi_probe(void)
if (pnp_device_attach(dev) < 0)
return -EAGAIN;
if (pnp_activate_dev(dev) < 0) {
- printk ("radio-sf16fmi: PnP configure failed (out of resources?)\n");
+ printk(KERN_ERR "radio-sf16fmi: PnP configure failed (out of resources?)\n");
pnp_device_detach(dev);
return -ENOMEM;
}
@@ -354,59 +326,72 @@ static int __init isapnp_fmi_probe(void)
}
i = pnp_port_start(dev, 0);
- printk ("radio-sf16fmi: PnP reports card at %#x\n", i);
+ printk(KERN_INFO "radio-sf16fmi: PnP reports card at %#x\n", i);
return i;
}
static int __init fmi_init(void)
{
+ struct fmi *fmi = &fmi_card;
+ struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
+ int res;
+
if (io < 0)
io = isapnp_fmi_probe();
- if (io < 0) {
- printk(KERN_ERR "radio-sf16fmi: No PnP card found.\n");
- return io;
+ strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
+ fmi->io = io;
+ if (fmi->io < 0) {
+ v4l2_err(v4l2_dev, "No PnP card found.\n");
+ return fmi->io;
}
if (!request_region(io, 2, "radio-sf16fmi")) {
- printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
pnp_device_detach(dev);
return -EBUSY;
}
- fmi_unit.port = io;
- fmi_unit.curvol = 0;
- fmi_unit.curfreq = 0;
- fmi_unit.flags = V4L2_TUNER_CAP_LOW;
- video_set_drvdata(&fmi_radio, &fmi_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(fmi->io, 2);
+ pnp_device_detach(dev);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ fmi->flags = V4L2_TUNER_CAP_LOW;
+ strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
+ fmi->vdev.v4l2_dev = v4l2_dev;
+ fmi->vdev.fops = &fmi_fops;
+ fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
+ fmi->vdev.release = video_device_release_empty;
+ video_set_drvdata(&fmi->vdev, fmi);
- mutex_init(&lock);
+ mutex_init(&fmi->lock);
- if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+ if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(fmi->io, 2);
+ pnp_device_detach(dev);
return -EINVAL;
}
- printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io);
+ v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
/* mute card - prevents noisy bootups */
- fmi_mute(io);
+ fmi_mute(fmi);
return 0;
}
-MODULE_AUTHOR("Petr Vandrovec, vandrove@vc.cvut.cz and M. Kirkwood");
-MODULE_DESCRIPTION("A driver for the SF16MI radio.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
-module_param(radio_nr, int, 0);
-
-static void __exit fmi_cleanup_module(void)
+static void __exit fmi_exit(void)
{
- video_unregister_device(&fmi_radio);
- release_region(io, 2);
+ struct fmi *fmi = &fmi_card;
+
+ video_unregister_device(&fmi->vdev);
+ v4l2_device_unregister(&fmi->v4l2_dev);
+ release_region(fmi->io, 2);
if (dev)
pnp_device_detach(dev);
}
module_init(fmi_init);
-module_exit(fmi_cleanup_module);
+module_exit(fmi_exit);
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c
index 92f17a347fa..0ba9d88a80f 100644
--- a/drivers/media/radio/radio-sf16fmr2.c
+++ b/drivers/media/radio/radio-sf16fmr2.c
@@ -18,40 +18,28 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
-static struct mutex lock;
+MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com");
+MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
+MODULE_LICENSE("GPL");
+
+static int io = 0x384;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
+module_param(radio_nr, int, 0);
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#define RADIO_VERSION KERNEL_VERSION(0,0,2)
#define AUD_VOL_INDEX 1
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },
- [AUD_VOL_INDEX] = {
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 15,
- .step = 1,
- .default_value = 0,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-
#undef DEBUG
//#define DEBUG 1
@@ -62,156 +50,160 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#endif
/* this should be static vars for module size */
-struct fmr2_device
+struct fmr2
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ struct mutex lock;
+ int io;
int curvol; /* 0-15 */
int mute;
int stereo; /* card is producing stereo audio */
unsigned long curfreq; /* freq in kHz */
int card_type;
- __u32 flags;
+ u32 flags;
};
-static int io = 0x384;
-static int radio_nr = -1;
+static struct fmr2 fmr2_card;
/* hw precision is 12.5 kHz
* It is only useful to give freq in intervall of 200 (=0.0125Mhz),
* other bits will be truncated
*/
-#define RSF16_ENCODE(x) ((x)/200+856)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
+#define RSF16_ENCODE(x) ((x) / 200 + 856)
+#define RSF16_MINFREQ (87 * 16000)
+#define RSF16_MAXFREQ (108 * 16000)
-static inline void wait(int n,int port)
+static inline void wait(int n, int io)
{
- for (;n;--n) inb(port);
+ for (; n; --n)
+ inb(io);
}
-static void outbits(int bits, unsigned int data, int nWait, int port)
+static void outbits(int bits, unsigned int data, int nWait, int io)
{
int bit;
- for(;--bits>=0;) {
- bit = (data>>bits) & 1;
- outb(bit,port);
- wait(nWait,port);
- outb(bit|2,port);
- wait(nWait,port);
- outb(bit,port);
- wait(nWait,port);
+
+ for (; --bits >= 0;) {
+ bit = (data >> bits) & 1;
+ outb(bit, io);
+ wait(nWait, io);
+ outb(bit | 2, io);
+ wait(nWait, io);
+ outb(bit, io);
+ wait(nWait, io);
}
}
-static inline void fmr2_mute(int port)
+static inline void fmr2_mute(int io)
{
- outb(0x00, port);
- wait(4,port);
+ outb(0x00, io);
+ wait(4, io);
}
-static inline void fmr2_unmute(int port)
+static inline void fmr2_unmute(int io)
{
- outb(0x04, port);
- wait(4,port);
+ outb(0x04, io);
+ wait(4, io);
}
-static inline int fmr2_stereo_mode(int port)
+static inline int fmr2_stereo_mode(int io)
{
- int n = inb(port);
- outb(6,port);
- inb(port);
- n = ((n>>3)&1)^1;
+ int n = inb(io);
+
+ outb(6, io);
+ inb(io);
+ n = ((n >> 3) & 1) ^ 1;
debug_print((KERN_DEBUG "stereo: %d\n", n));
return n;
}
-static int fmr2_product_info(struct fmr2_device *dev)
+static int fmr2_product_info(struct fmr2 *dev)
{
- int n = inb(dev->port);
+ int n = inb(dev->io);
+
n &= 0xC1;
- if (n == 0)
- {
+ if (n == 0) {
/* this should support volume set */
dev->card_type = 12;
return 0;
}
/* not volume (mine is 11) */
- dev->card_type = (n==128)?11:0;
+ dev->card_type = (n == 128) ? 11 : 0;
return n;
}
-static inline int fmr2_getsigstr(struct fmr2_device *dev)
+static inline int fmr2_getsigstr(struct fmr2 *dev)
{
- /* !!! work only if scanning freq */
- int port = dev->port, res = 0xffff;
- outb(5,port);
- wait(4,port);
- if (!(inb(port)&1)) res = 0;
+ /* !!! works only if scanning freq */
+ int res = 0xffff;
+
+ outb(5, dev->io);
+ wait(4, dev->io);
+ if (!(inb(dev->io) & 1))
+ res = 0;
debug_print((KERN_DEBUG "signal: %d\n", res));
return res;
}
/* set frequency and unmute card */
-static int fmr2_setfreq(struct fmr2_device *dev)
+static int fmr2_setfreq(struct fmr2 *dev)
{
- int port = dev->port;
unsigned long freq = dev->curfreq;
- fmr2_mute(port);
+ fmr2_mute(dev->io);
/* 0x42 for mono output
* 0x102 forward scanning
* 0x182 scansione avanti
*/
- outbits(9,0x2,3,port);
- outbits(16,RSF16_ENCODE(freq),2,port);
+ outbits(9, 0x2, 3, dev->io);
+ outbits(16, RSF16_ENCODE(freq), 2, dev->io);
- fmr2_unmute(port);
+ fmr2_unmute(dev->io);
/* wait 0.11 sec */
msleep(110);
/* NOTE if mute this stop radio
you must set freq on unmute */
- dev->stereo = fmr2_stereo_mode(port);
+ dev->stereo = fmr2_stereo_mode(dev->io);
return 0;
}
/* !!! not tested, in my card this does't work !!! */
-static int fmr2_setvolume(struct fmr2_device *dev)
+static int fmr2_setvolume(struct fmr2 *dev)
{
int vol[16] = { 0x021, 0x084, 0x090, 0x104,
0x110, 0x204, 0x210, 0x402,
0x404, 0x408, 0x410, 0x801,
0x802, 0x804, 0x808, 0x810 };
- int i, a, port = dev->port;
+ int i, a;
int n = vol[dev->curvol & 0x0f];
if (dev->card_type != 11)
return 1;
for (i = 12; --i >= 0; ) {
- a = ((n >> i) & 1) << 6; /* if (a=0) a= 0; else a= 0x40; */
- outb(a | 4, port);
- wait(4, port);
- outb(a | 0x24, port);
- wait(4, port);
- outb(a | 4, port);
- wait(4, port);
+ a = ((n >> i) & 1) << 6; /* if (a==0) a = 0; else a = 0x40; */
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
+ outb(a | 0x24, dev->io);
+ wait(4, dev->io);
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
}
for (i = 6; --i >= 0; ) {
a = ((0x18 >> i) & 1) << 6;
- outb(a | 4, port);
- wait(4,port);
- outb(a | 0x24, port);
- wait(4,port);
- outb(a|4, port);
- wait(4,port);
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
+ outb(a | 0x24, dev->io);
+ wait(4, dev->io);
+ outb(a | 4, dev->io);
+ wait(4, dev->io);
}
- wait(4, port);
- outb(0x14, port);
-
+ wait(4, dev->io);
+ outb(0x14, dev->io);
return 0;
}
@@ -220,9 +212,9 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-sf16fmr2", sizeof(v->driver));
strlcpy(v->card, "SF16-FMR2 radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
@@ -230,54 +222,52 @@ static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
int mult;
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
- v->rangelow = RSF16_MINFREQ/mult;
- v->rangehigh = RSF16_MAXFREQ/mult;
+ v->rangelow = RSF16_MINFREQ / mult;
+ v->rangehigh = RSF16_MAXFREQ / mult;
v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
v->capability = fmr2->flags&V4L2_TUNER_CAP_LOW;
v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO:
V4L2_TUNER_MODE_MONO;
- mutex_lock(&lock);
+ mutex_lock(&fmr2->lock);
v->signal = fmr2_getsigstr(fmr2);
- mutex_unlock(&lock);
+ mutex_unlock(&fmr2->lock);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
if (!(fmr2->flags & V4L2_TUNER_CAP_LOW))
f->frequency *= 1000;
if (f->frequency < RSF16_MINFREQ ||
- f->frequency > RSF16_MAXFREQ )
+ f->frequency > RSF16_MAXFREQ)
return -EINVAL;
- /*rounding in steps of 200 to match th freq
- that will be used */
- fmr2->curfreq = (f->frequency/200)*200;
+ /* rounding in steps of 200 to match the freq
+ that will be used */
+ fmr2->curfreq = (f->frequency / 200) * 200;
/* set card freq (if not muted) */
if (fmr2->curvol && !fmr2->mute) {
- mutex_lock(&lock);
+ mutex_lock(&fmr2->lock);
fmr2_setfreq(fmr2);
- mutex_unlock(&lock);
+ mutex_unlock(&fmr2->lock);
}
return 0;
}
@@ -285,7 +275,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = fmr2->curfreq;
@@ -297,13 +287,16 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
+ struct fmr2 *fmr2 = video_drvdata(file);
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &radio_qctrl[i], sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ /* Only card_type == 11 implements volume */
+ if (fmr2->card_type == 11)
+ return v4l2_ctrl_query_fill(qc, 0, 15, 1, 0);
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
}
return -EINVAL;
}
@@ -311,7 +304,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -327,18 +320,14 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct fmr2_device *fmr2 = video_drvdata(file);
+ struct fmr2 *fmr2 = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
fmr2->mute = ctrl->value;
break;
case V4L2_CID_AUDIO_VOLUME:
- if (ctrl->value > radio_qctrl[AUD_VOL_INDEX].maximum)
- fmr2->curvol = radio_qctrl[AUD_VOL_INDEX].maximum;
- else
- fmr2->curvol = ctrl->value;
-
+ fmr2->curvol = ctrl->value;
break;
default:
return -EINVAL;
@@ -351,25 +340,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
printk(KERN_DEBUG "mute\n");
#endif
- mutex_lock(&lock);
+ mutex_lock(&fmr2->lock);
if (fmr2->curvol && !fmr2->mute) {
fmr2_setvolume(fmr2);
/* Set frequency and unmute card */
fmr2_setfreq(fmr2);
} else
- fmr2_mute(fmr2->port);
- mutex_unlock(&lock);
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
+ fmr2_mute(fmr2->io);
+ mutex_unlock(&fmr2->lock);
return 0;
}
@@ -381,36 +359,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct fmr2_device fmr2_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int fmr2_exclusive_open(struct file *file)
+static int fmr2_open(struct file *file)
{
- return test_and_set_bit(0, &fmr2_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int fmr2_exclusive_release(struct file *file)
+static int fmr2_release(struct file *file)
{
- clear_bit(0, &fmr2_unit.in_use);
return 0;
}
static const struct v4l2_file_operations fmr2_fops = {
.owner = THIS_MODULE,
- .open = fmr2_exclusive_open,
- .release = fmr2_exclusive_release,
+ .open = fmr2_open,
+ .release = fmr2_release,
.ioctl = video_ioctl2,
};
@@ -429,67 +409,64 @@ static const struct v4l2_ioctl_ops fmr2_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device fmr2_radio = {
- .name = "SF16FMR2 radio",
- .fops = &fmr2_fops,
- .ioctl_ops = &fmr2_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init fmr2_init(void)
{
- fmr2_unit.port = io;
- fmr2_unit.curvol = 0;
- fmr2_unit.mute = 0;
- fmr2_unit.curfreq = 0;
- fmr2_unit.stereo = 1;
- fmr2_unit.flags = V4L2_TUNER_CAP_LOW;
- fmr2_unit.card_type = 0;
- video_set_drvdata(&fmr2_radio, &fmr2_unit);
-
- mutex_init(&lock);
-
- if (!request_region(io, 2, "sf16fmr2")) {
- printk(KERN_ERR "radio-sf16fmr2: request_region failed!\n");
+ struct fmr2 *fmr2 = &fmr2_card;
+ struct v4l2_device *v4l2_dev = &fmr2->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "sf16fmr2", sizeof(v4l2_dev->name));
+ fmr2->io = io;
+ fmr2->stereo = 1;
+ fmr2->flags = V4L2_TUNER_CAP_LOW;
+ mutex_init(&fmr2->lock);
+
+ if (!request_region(fmr2->io, 2, "sf16fmr2")) {
+ v4l2_err(v4l2_dev, "request_region failed!\n");
return -EBUSY;
}
- if (video_register_device(&fmr2_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
- return -EINVAL;
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(fmr2->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
}
- printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io);
- /* mute card - prevents noisy bootups */
- mutex_lock(&lock);
- fmr2_mute(io);
- fmr2_product_info(&fmr2_unit);
- mutex_unlock(&lock);
- debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type));
+ strlcpy(fmr2->vdev.name, v4l2_dev->name, sizeof(fmr2->vdev.name));
+ fmr2->vdev.v4l2_dev = v4l2_dev;
+ fmr2->vdev.fops = &fmr2_fops;
+ fmr2->vdev.ioctl_ops = &fmr2_ioctl_ops;
+ fmr2->vdev.release = video_device_release_empty;
+ video_set_drvdata(&fmr2->vdev, fmr2);
- /* Only card_type == 11 implements volume */
- if (fmr2_unit.card_type != 11)
- radio_qctrl[AUD_VOL_INDEX].maximum = 1;
+ if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(fmr2->io, 2);
+ return -EINVAL;
+ }
+ v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io);
+ /* mute card - prevents noisy bootups */
+ mutex_lock(&fmr2->lock);
+ fmr2_mute(fmr2->io);
+ fmr2_product_info(fmr2);
+ mutex_unlock(&fmr2->lock);
+ debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type));
return 0;
}
-MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com");
-MODULE_DESCRIPTION("A driver for the SF16FMR2 radio.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)");
-module_param(radio_nr, int, 0);
-
-static void __exit fmr2_cleanup_module(void)
+static void __exit fmr2_exit(void)
{
- video_unregister_device(&fmr2_radio);
- release_region(io,2);
+ struct fmr2 *fmr2 = &fmr2_card;
+
+ video_unregister_device(&fmr2->vdev);
+ v4l2_device_unregister(&fmr2->v4l2_dev);
+ release_region(fmr2->io, 2);
}
module_init(fmr2_init);
-module_exit(fmr2_cleanup_module);
+module_exit(fmr2_exit);
#ifndef MODULE
diff --git a/drivers/media/radio/radio-si470x.c b/drivers/media/radio/radio-si470x.c
index 4dfed6aa2db..713e242ba8b 100644
--- a/drivers/media/radio/radio-si470x.c
+++ b/drivers/media/radio/radio-si470x.c
@@ -5,8 +5,9 @@
* - Silicon Labs USB FM Radio Reference Design
* - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF)
* - KWorld USB FM Radio SnapMusic Mobile 700 (FM700)
+ * - Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear)
*
- * Copyright (c) 2008 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * Copyright (c) 2009 Tobias Lorenz <tobias.lorenz@gmx.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -29,7 +30,7 @@
* 2008-01-12 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.0
* - First working version
- * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
+ * 2008-01-13 Tobias Lorenz <tobias.lorenz@gmx.net>
* Version 1.0.1
* - Improved error handling, every function now returns errno
* - Improved multi user access (start/mute/stop)
@@ -104,6 +105,7 @@
* 2009-01-31 Rick Bronson <rick@efn.org>
* Tobias Lorenz <tobias.lorenz@gmx.net>
* - add LED status output
+ * - get HW/SW version from scratchpad
*
* ToDo:
* - add firmware download/update support
@@ -114,10 +116,10 @@
/* driver definitions */
#define DRIVER_AUTHOR "Tobias Lorenz <tobias.lorenz@gmx.net>"
#define DRIVER_NAME "radio-si470x"
-#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 8)
+#define DRIVER_KERNEL_VERSION KERNEL_VERSION(1, 0, 9)
#define DRIVER_CARD "Silicon Labs Si470x FM Radio Receiver"
#define DRIVER_DESC "USB radio driver for Si470x FM Radio Receivers"
-#define DRIVER_VERSION "1.0.8"
+#define DRIVER_VERSION "1.0.9"
/* kernel includes */
@@ -145,7 +147,7 @@ static struct usb_device_id si470x_usb_driver_id_table[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) },
/* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) },
- /* DealExtreme USB Radio */
+ /* Sanei Electric, Inc. FM USB Radio (sold as DealExtreme.com PCear) */
{ USB_DEVICE_AND_INTERFACE_INFO(0x10c5, 0x819a, USB_CLASS_HID, 0, 0) },
/* Terminating entry */
{ }
@@ -345,7 +347,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
/* Report 19: stream */
#define STREAM_REPORT_SIZE 3
-#define STREAM_REPORT 19
+#define STREAM_REPORT 19
/* Report 20: scratch */
#define SCRATCH_PAGE_SIZE 63
@@ -353,9 +355,13 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
#define SCRATCH_REPORT 20
/* Reports 19-22: flash upgrade of the C8051F321 */
+#define WRITE_REPORT_SIZE 4
#define WRITE_REPORT 19
+#define FLASH_REPORT_SIZE 64
#define FLASH_REPORT 20
+#define CRC_REPORT_SIZE 3
#define CRC_REPORT 21
+#define RESPONSE_REPORT_SIZE 2
#define RESPONSE_REPORT 22
/* Report 23: currently unused, but can accept 60 byte reports on the HID */
@@ -414,7 +420,7 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
/* bootloader commands */
#define GET_SW_VERSION_COMMAND 0x00
-#define SET_PAGE_COMMAND 0x01
+#define SET_PAGE_COMMAND 0x01
#define ERASE_PAGE_COMMAND 0x02
#define WRITE_PAGE_COMMAND 0x03
#define CRC_ON_PAGE_COMMAND 0x04
@@ -428,12 +434,6 @@ MODULE_PARM_DESC(rds_poll_time, "RDS poll time (ms): *40*");
#define COMMAND_FAILED 0x02
#define COMMAND_PENDING 0x03
-/* buffer sizes */
-#define COMMAND_BUFFER_SIZE 4
-#define RESPONSE_BUFFER_SIZE 2
-#define FLASH_BUFFER_SIZE 64
-#define CRC_BUFFER_SIZE 3
-
/**************************************************************************
@@ -465,6 +465,10 @@ struct si470x_device {
unsigned int buf_size;
unsigned int rd_index;
unsigned int wr_index;
+
+ /* scratch page */
+ unsigned char software_version;
+ unsigned char hardware_version;
};
@@ -480,7 +484,7 @@ struct si470x_device {
/**************************************************************************
- * General Driver Functions
+ * General Driver Functions - REGISTER_REPORTs
**************************************************************************/
/*
@@ -566,60 +570,6 @@ static int si470x_set_register(struct si470x_device *radio, int regnr)
/*
- * si470x_get_all_registers - read entire registers
- */
-static int si470x_get_all_registers(struct si470x_device *radio)
-{
- unsigned char buf[ENTIRE_REPORT_SIZE];
- int retval;
- unsigned char regnr;
-
- buf[0] = ENTIRE_REPORT;
-
- retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
-
- if (retval >= 0)
- for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
- radio->registers[regnr] = get_unaligned_be16(
- &buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
- return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
- * si470x_get_rds_registers - read rds registers
- */
-static int si470x_get_rds_registers(struct si470x_device *radio)
-{
- unsigned char buf[RDS_REPORT_SIZE];
- int retval;
- int size;
- unsigned char regnr;
-
- buf[0] = RDS_REPORT;
-
- retval = usb_interrupt_msg(radio->usbdev,
- usb_rcvintpipe(radio->usbdev, 1),
- (void *) &buf, sizeof(buf), &size, usb_timeout);
- if (size != sizeof(buf))
- printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
- "return size differs: %d != %zu\n", size, sizeof(buf));
- if (retval < 0)
- printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
- "usb_interrupt_msg returned %d\n", retval);
-
- if (retval >= 0)
- for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
- radio->registers[STATUSRSSI + regnr] =
- get_unaligned_be16(
- &buf[regnr * RADIO_REGISTER_SIZE + 1]);
-
- return (retval < 0) ? -EINVAL : 0;
-}
-
-
-/*
* si470x_set_chan - set the channel
*/
static int si470x_set_chan(struct si470x_device *radio, unsigned short chan)
@@ -887,6 +837,70 @@ static int si470x_rds_on(struct si470x_device *radio)
/**************************************************************************
+ * General Driver Functions - ENTIRE_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_all_registers - read entire registers
+ */
+static int si470x_get_all_registers(struct si470x_device *radio)
+{
+ unsigned char buf[ENTIRE_REPORT_SIZE];
+ int retval;
+ unsigned char regnr;
+
+ buf[0] = ENTIRE_REPORT;
+
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+ if (retval >= 0)
+ for (regnr = 0; regnr < RADIO_REGISTER_NUM; regnr++)
+ radio->registers[regnr] = get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
+ * General Driver Functions - RDS_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_rds_registers - read rds registers
+ */
+static int si470x_get_rds_registers(struct si470x_device *radio)
+{
+ unsigned char buf[RDS_REPORT_SIZE];
+ int retval;
+ int size;
+ unsigned char regnr;
+
+ buf[0] = RDS_REPORT;
+
+ retval = usb_interrupt_msg(radio->usbdev,
+ usb_rcvintpipe(radio->usbdev, 1),
+ (void *) &buf, sizeof(buf), &size, usb_timeout);
+ if (size != sizeof(buf))
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ "return size differs: %d != %zu\n", size, sizeof(buf));
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_rds_registers: "
+ "usb_interrupt_msg returned %d\n", retval);
+
+ if (retval >= 0)
+ for (regnr = 0; regnr < RDS_REGISTER_NUM; regnr++)
+ radio->registers[STATUSRSSI + regnr] =
+ get_unaligned_be16(
+ &buf[regnr * RADIO_REGISTER_SIZE + 1]);
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
* General Driver Functions - LED_REPORT
**************************************************************************/
@@ -911,6 +925,35 @@ static int si470x_set_led_state(struct si470x_device *radio,
/**************************************************************************
+ * General Driver Functions - SCRATCH_REPORT
+ **************************************************************************/
+
+/*
+ * si470x_get_scratch_versions - gets the scratch page and version infos
+ */
+static int si470x_get_scratch_page_versions(struct si470x_device *radio)
+{
+ unsigned char buf[SCRATCH_REPORT_SIZE];
+ int retval;
+
+ buf[0] = SCRATCH_REPORT;
+
+ retval = si470x_get_report(radio, (void *) &buf, sizeof(buf));
+
+ if (retval < 0)
+ printk(KERN_WARNING DRIVER_NAME ": si470x_get_scratch: "
+ "si470x_get_report returned %d\n", retval);
+ else {
+ radio->software_version = buf[1];
+ radio->hardware_version = buf[2];
+ }
+
+ return (retval < 0) ? -EINVAL : 0;
+}
+
+
+
+/**************************************************************************
* RDS Driver Functions
**************************************************************************/
@@ -1124,6 +1167,7 @@ static int si470x_fops_open(struct file *file)
}
if (radio->users == 1) {
+ /* start radio */
retval = si470x_start(radio);
if (retval < 0)
usb_autopm_put_interface(radio->intf);
@@ -1165,6 +1209,7 @@ static int si470x_fops_release(struct file *file)
/* cancel read processes */
wake_up_interruptible(&radio->read_queue);
+ /* stop radio */
retval = si470x_stop(radio);
usb_autopm_put_interface(radio->intf);
}
@@ -1226,9 +1271,11 @@ static struct v4l2_queryctrl si470x_v4l2_queryctrl[] = {
static int si470x_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *capability)
{
+ struct si470x_device *radio = video_drvdata(file);
+
strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver));
strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card));
- sprintf(capability->bus_info, "USB");
+ usb_make_path(radio->usbdev, capability->bus_info, sizeof(capability->bus_info));
capability->version = DRIVER_KERNEL_VERSION;
capability->capabilities = V4L2_CAP_HW_FREQ_SEEK |
V4L2_CAP_TUNER | V4L2_CAP_RADIO;
@@ -1636,7 +1683,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
sizeof(si470x_viddev_template));
video_set_drvdata(radio->videodev, radio);
- /* show some infos about the specific device */
+ /* show some infos about the specific si470x device */
if (si470x_get_all_registers(radio) < 0) {
retval = -EIO;
goto err_all;
@@ -1644,7 +1691,16 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
printk(KERN_INFO DRIVER_NAME ": DeviceID=0x%4.4hx ChipID=0x%4.4hx\n",
radio->registers[DEVICEID], radio->registers[CHIPID]);
- /* check if firmware is current */
+ /* get software and hardware versions */
+ if (si470x_get_scratch_page_versions(radio) < 0) {
+ retval = -EIO;
+ goto err_all;
+ }
+ printk(KERN_INFO DRIVER_NAME
+ ": software version %d, hardware version %d\n",
+ radio->software_version, radio->hardware_version);
+
+ /* check if device and firmware is current */
if ((radio->registers[CHIPID] & CHIPID_FIRMWARE)
< RADIO_SW_VERSION_CURRENT) {
printk(KERN_WARNING DRIVER_NAME
@@ -1657,7 +1713,7 @@ static int si470x_usb_driver_probe(struct usb_interface *intf,
": If you have some trouble using this driver,\n");
printk(KERN_WARNING DRIVER_NAME
": please report to V4L ML at "
- "video4linux-list@redhat.com\n");
+ "linux-media@vger.kernel.org\n");
}
/* set initial frequency */
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c
index 0798d71abd0..5b007f5c74b 100644
--- a/drivers/media/radio/radio-terratec.c
+++ b/drivers/media/radio/radio-terratec.c
@@ -27,16 +27,29 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
-#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/spinlock.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+MODULE_AUTHOR("R.OFFERMANNS & others");
+MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
+MODULE_LICENSE("GPL");
+
+#ifndef CONFIG_RADIO_TERRATEC_PORT
+#define CONFIG_RADIO_TERRATEC_PORT 0x590
+#endif
+
+static int io = CONFIG_RADIO_TERRATEC_PORT;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
static struct v4l2_queryctrl radio_qctrl[] = {
{
@@ -57,13 +70,6 @@ static struct v4l2_queryctrl radio_qctrl[] = {
}
};
-#ifndef CONFIG_RADIO_TERRATEC_PORT
-#define CONFIG_RADIO_TERRATEC_PORT 0x590
-#endif
-
-/**************** this ones are for the terratec *******************/
-#define BASEPORT 0x590
-#define VOLPORT 0x591
#define WRT_DIS 0x00
#define CLK_OFF 0x00
#define IIC_DATA 0x01
@@ -71,138 +77,124 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define DATA 0x04
#define CLK_ON 0x08
#define WRT_EN 0x10
-/*******************************************************************/
-static int io = CONFIG_RADIO_TERRATEC_PORT;
-static int radio_nr = -1;
-static spinlock_t lock;
-
-struct tt_device
+struct terratec
{
- unsigned long in_use;
- int port;
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
unsigned long curfreq;
int muted;
+ struct mutex lock;
};
+static struct terratec terratec_card;
/* local things */
-static void cardWriteVol(int volume)
+static void tt_write_vol(struct terratec *tt, int volume)
{
int i;
- volume = volume+(volume * 32); // change both channels
- spin_lock(&lock);
- for (i=0;i<8;i++)
- {
- if (volume & (0x80>>i))
- outb(0x80, VOLPORT);
- else outb(0x00, VOLPORT);
+
+ volume = volume + (volume * 32); /* change both channels */
+ mutex_lock(&tt->lock);
+ for (i = 0; i < 8; i++) {
+ if (volume & (0x80 >> i))
+ outb(0x80, tt->io + 1);
+ else
+ outb(0x00, tt->io + 1);
}
- spin_unlock(&lock);
+ mutex_unlock(&tt->lock);
}
-static void tt_mute(struct tt_device *dev)
+static void tt_mute(struct terratec *tt)
{
- dev->muted = 1;
- cardWriteVol(0);
+ tt->muted = 1;
+ tt_write_vol(tt, 0);
}
-static int tt_setvol(struct tt_device *dev, int vol)
+static int tt_setvol(struct terratec *tt, int vol)
{
-
-// printk(KERN_ERR "setvol called, vol = %d\n", vol);
-
- if(vol == dev->curvol) { /* requested volume = current */
- if (dev->muted) { /* user is unmuting the card */
- dev->muted = 0;
- cardWriteVol(vol); /* enable card */
+ if (vol == tt->curvol) { /* requested volume = current */
+ if (tt->muted) { /* user is unmuting the card */
+ tt->muted = 0;
+ tt_write_vol(tt, vol); /* enable card */
}
-
return 0;
}
- if(vol == 0) { /* volume = 0 means mute the card */
- cardWriteVol(0); /* "turn off card" by setting vol to 0 */
- dev->curvol = vol; /* track the volume state! */
+ if (vol == 0) { /* volume = 0 means mute the card */
+ tt_write_vol(tt, 0); /* "turn off card" by setting vol to 0 */
+ tt->curvol = vol; /* track the volume state! */
return 0;
}
- dev->muted = 0;
-
- cardWriteVol(vol);
-
- dev->curvol = vol;
-
+ tt->muted = 0;
+ tt_write_vol(tt, vol);
+ tt->curvol = vol;
return 0;
-
}
/* this is the worst part in this driver */
/* many more or less strange things are going on here, but hey, it works :) */
-static int tt_setfreq(struct tt_device *dev, unsigned long freq1)
+static int tt_setfreq(struct terratec *tt, unsigned long freq1)
{
int freq;
int i;
int p;
int temp;
long rest;
-
unsigned char buffer[25]; /* we have to bit shift 25 registers */
- freq = freq1/160; /* convert the freq. to a nice to handle value */
- for(i=24;i>-1;i--)
- buffer[i]=0;
- rest = freq*10+10700; /* i once had understood what is going on here */
+ mutex_lock(&tt->lock);
+
+ tt->curfreq = freq1;
+
+ freq = freq1 / 160; /* convert the freq. to a nice to handle value */
+ memset(buffer, 0, sizeof(buffer));
+
+ rest = freq * 10 + 10700; /* I once had understood what is going on here */
/* maybe some wise guy (friedhelm?) can comment this stuff */
- i=13;
- p=10;
- temp=102400;
- while (rest!=0)
- {
- if (rest%temp == rest)
+ i = 13;
+ p = 10;
+ temp = 102400;
+ while (rest != 0) {
+ if (rest % temp == rest)
buffer[i] = 0;
- else
- {
+ else {
buffer[i] = 1;
- rest = rest-temp;
+ rest = rest - temp;
}
i--;
p--;
- temp = temp/2;
+ temp = temp / 2;
}
- spin_lock(&lock);
-
- for (i=24;i>-1;i--) /* bit shift the values to the radiocard */
- {
- if (buffer[i]==1)
- {
- outb(WRT_EN|DATA, BASEPORT);
- outb(WRT_EN|DATA|CLK_ON , BASEPORT);
- outb(WRT_EN|DATA, BASEPORT);
- }
- else
- {
- outb(WRT_EN|0x00, BASEPORT);
- outb(WRT_EN|0x00|CLK_ON , BASEPORT);
+ for (i = 24; i > -1; i--) { /* bit shift the values to the radiocard */
+ if (buffer[i] == 1) {
+ outb(WRT_EN | DATA, tt->io);
+ outb(WRT_EN | DATA | CLK_ON, tt->io);
+ outb(WRT_EN | DATA, tt->io);
+ } else {
+ outb(WRT_EN | 0x00, tt->io);
+ outb(WRT_EN | 0x00 | CLK_ON, tt->io);
}
}
- outb(0x00, BASEPORT);
+ outb(0x00, tt->io);
- spin_unlock(&lock);
+ mutex_unlock(&tt->lock);
return 0;
}
-static int tt_getsigstr(struct tt_device *dev) /* TODO */
+static int tt_getsigstr(struct terratec *tt)
{
- if (inb(io) & 2) /* bit set = no signal present */
+ if (inb(tt->io) & 2) /* bit set = no signal present */
return 0;
return 1; /* signal present */
}
@@ -212,53 +204,50 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-terratec", sizeof(v->driver));
strlcpy(v->card, "ActiveRadio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 87 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF*tt_getsigstr(tt);
+ v->signal = 0xFFFF * tt_getsigstr(tt);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
- tt->curfreq = f->frequency;
- tt_setfreq(tt, tt->curfreq);
+ tt_setfreq(tt, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = tt->curfreq;
@@ -272,8 +261,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
+ memcpy(qc, &(radio_qctrl[i]), sizeof(*qc));
return 0;
}
}
@@ -283,7 +271,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -302,7 +290,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct tt_device *tt = video_drvdata(file);
+ struct terratec *tt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -318,17 +306,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -337,36 +314,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct tt_device terratec_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int terratec_exclusive_open(struct file *file)
+static int terratec_open(struct file *file)
{
- return test_and_set_bit(0, &terratec_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int terratec_exclusive_release(struct file *file)
+static int terratec_release(struct file *file)
{
- clear_bit(0, &terratec_unit.in_use);
return 0;
}
static const struct v4l2_file_operations terratec_fops = {
.owner = THIS_MODULE,
- .open = terratec_exclusive_open,
- .release = terratec_exclusive_release,
+ .open = terratec_open,
+ .release = terratec_release,
.ioctl = video_ioctl2,
};
@@ -385,60 +364,63 @@ static const struct v4l2_ioctl_ops terratec_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device terratec_radio = {
- .name = "TerraTec ActiveRadio",
- .fops = &terratec_fops,
- .ioctl_ops = &terratec_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init terratec_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct terratec *tt = &terratec_card;
+ struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "terratec", sizeof(v4l2_dev->name));
+ tt->io = io;
+ if (tt->io == -1) {
+ v4l2_err(v4l2_dev, "you must set an I/O address with io=0x590 or 0x591\n");
return -EINVAL;
}
- if (!request_region(io, 2, "terratec"))
- {
- printk(KERN_ERR "TerraTec: port 0x%x already in use\n", io);
+ if (!request_region(tt->io, 2, "terratec")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", io);
return -EBUSY;
}
- video_set_drvdata(&terratec_radio, &terratec_unit);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(tt->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ strlcpy(tt->vdev.name, v4l2_dev->name, sizeof(tt->vdev.name));
+ tt->vdev.v4l2_dev = v4l2_dev;
+ tt->vdev.fops = &terratec_fops;
+ tt->vdev.ioctl_ops = &terratec_ioctl_ops;
+ tt->vdev.release = video_device_release_empty;
+ video_set_drvdata(&tt->vdev, tt);
- spin_lock_init(&lock);
+ mutex_init(&tt->lock);
- if (video_register_device(&terratec_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io,2);
+ if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&tt->v4l2_dev);
+ release_region(tt->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver.\n");
+ v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n");
/* mute card - prevents noisy bootups */
-
- /* this ensures that the volume is all the way down */
- cardWriteVol(0);
- terratec_unit.curvol = 0;
-
+ tt_write_vol(tt, 0);
return 0;
}
-MODULE_AUTHOR("R.OFFERMANNS & others");
-MODULE_DESCRIPTION("A driver for the TerraTec ActiveRadio Standalone radio card.");
-MODULE_LICENSE("GPL");
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the TerraTec ActiveRadio card (0x590 or 0x591)");
-module_param(radio_nr, int, 0);
-
-static void __exit terratec_cleanup_module(void)
+static void __exit terratec_exit(void)
{
- video_unregister_device(&terratec_radio);
- release_region(io,2);
- printk(KERN_INFO "TERRATEC ActivRadio Standalone card driver unloaded.\n");
+ struct terratec *tt = &terratec_card;
+ struct v4l2_device *v4l2_dev = &tt->v4l2_dev;
+
+ video_unregister_device(&tt->vdev);
+ v4l2_device_unregister(&tt->v4l2_dev);
+ release_region(tt->io, 2);
+ v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver unloaded.\n");
}
module_init(terratec_init);
-module_exit(terratec_cleanup_module);
+module_exit(terratec_exit);
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c
index bdf9cb6a75f..d1be6492a07 100644
--- a/drivers/media/radio/radio-trust.c
+++ b/drivers/media/radio/radio-trust.c
@@ -19,49 +19,15 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/ioport.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 2048,
- .default_value = 65535,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_AUDIO_BASS,
- .name = "Bass",
- .minimum = 0,
- .maximum = 65535,
- .step = 4370,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },{
- .id = V4L2_CID_AUDIO_TREBLE,
- .name = "Treble",
- .minimum = 0,
- .maximum = 65535,
- .step = 4370,
- .default_value = 32768,
- .type = V4L2_CTRL_TYPE_INTEGER,
- },
-};
+MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
+MODULE_LICENSE("GPL");
/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -71,26 +37,41 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_TRUST_PORT;
static int radio_nr = -1;
-static int ioval = 0xf;
-static __u16 curvol;
-static __u16 curbass;
-static __u16 curtreble;
-static unsigned long curfreq;
-static int curstereo;
-static int curmute;
-static unsigned long in_use;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct trust {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
+ int ioval;
+ __u16 curvol;
+ __u16 curbass;
+ __u16 curtreble;
+ int muted;
+ unsigned long curfreq;
+ int curstereo;
+ int curmute;
+ struct mutex lock;
+};
+
+static struct trust trust_card;
/* i2c addresses */
#define TDA7318_ADDR 0x88
#define TSA6060T_ADDR 0xc4
-#define TR_DELAY do { inb(io); inb(io); inb(io); } while(0)
-#define TR_SET_SCL outb(ioval |= 2, io)
-#define TR_CLR_SCL outb(ioval &= 0xfd, io)
-#define TR_SET_SDA outb(ioval |= 1, io)
-#define TR_CLR_SDA outb(ioval &= 0xfe, io)
+#define TR_DELAY do { inb(tr->io); inb(tr->io); inb(tr->io); } while (0)
+#define TR_SET_SCL outb(tr->ioval |= 2, tr->io)
+#define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->io)
+#define TR_SET_SDA outb(tr->ioval |= 1, tr->io)
+#define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->io)
-static void write_i2c(int n, ...)
+static void write_i2c(struct trust *tr, int n, ...)
{
unsigned char val, mask;
va_list args;
@@ -136,62 +117,77 @@ static void write_i2c(int n, ...)
va_end(args);
}
-static void tr_setvol(__u16 vol)
+static void tr_setvol(struct trust *tr, __u16 vol)
{
- curvol = vol / 2048;
- write_i2c(2, TDA7318_ADDR, curvol ^ 0x1f);
+ mutex_lock(&tr->lock);
+ tr->curvol = vol / 2048;
+ write_i2c(tr, 2, TDA7318_ADDR, tr->curvol ^ 0x1f);
+ mutex_unlock(&tr->lock);
}
static int basstreble2chip[15] = {
0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
};
-static void tr_setbass(__u16 bass)
+static void tr_setbass(struct trust *tr, __u16 bass)
{
- curbass = bass / 4370;
- write_i2c(2, TDA7318_ADDR, 0x60 | basstreble2chip[curbass]);
+ mutex_lock(&tr->lock);
+ tr->curbass = bass / 4370;
+ write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[tr->curbass]);
+ mutex_unlock(&tr->lock);
}
-static void tr_settreble(__u16 treble)
+static void tr_settreble(struct trust *tr, __u16 treble)
{
- curtreble = treble / 4370;
- write_i2c(2, TDA7318_ADDR, 0x70 | basstreble2chip[curtreble]);
+ mutex_lock(&tr->lock);
+ tr->curtreble = treble / 4370;
+ write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[tr->curtreble]);
+ mutex_unlock(&tr->lock);
}
-static void tr_setstereo(int stereo)
+static void tr_setstereo(struct trust *tr, int stereo)
{
- curstereo = !!stereo;
- ioval = (ioval & 0xfb) | (!curstereo << 2);
- outb(ioval, io);
+ mutex_lock(&tr->lock);
+ tr->curstereo = !!stereo;
+ tr->ioval = (tr->ioval & 0xfb) | (!tr->curstereo << 2);
+ outb(tr->ioval, tr->io);
+ mutex_unlock(&tr->lock);
}
-static void tr_setmute(int mute)
+static void tr_setmute(struct trust *tr, int mute)
{
- curmute = !!mute;
- ioval = (ioval & 0xf7) | (curmute << 3);
- outb(ioval, io);
+ mutex_lock(&tr->lock);
+ tr->curmute = !!mute;
+ tr->ioval = (tr->ioval & 0xf7) | (tr->curmute << 3);
+ outb(tr->ioval, tr->io);
+ mutex_unlock(&tr->lock);
}
-static int tr_getsigstr(void)
+static int tr_getsigstr(struct trust *tr)
{
int i, v;
- for(i = 0, v = 0; i < 100; i++) v |= inb(io);
- return (v & 1)? 0 : 0xffff;
+ mutex_lock(&tr->lock);
+ for (i = 0, v = 0; i < 100; i++)
+ v |= inb(tr->io);
+ mutex_unlock(&tr->lock);
+ return (v & 1) ? 0 : 0xffff;
}
-static int tr_getstereo(void)
+static int tr_getstereo(struct trust *tr)
{
/* don't know how to determine it, just return the setting */
- return curstereo;
+ return tr->curstereo;
}
-static void tr_setfreq(unsigned long f)
+static void tr_setfreq(struct trust *tr, unsigned long f)
{
+ mutex_lock(&tr->lock);
+ tr->curfreq = f;
f /= 160; /* Convert to 10 kHz units */
- f += 1070; /* Add 10.7 MHz IF */
-
- write_i2c(5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
+ f += 1070; /* Add 10.7 MHz IF */
+ write_i2c(tr, 5, TSA6060T_ADDR, (f << 1) | 1, f >> 7, 0x60 | ((f >> 15) & 1), 0);
+ mutex_unlock(&tr->lock);
}
static int vidioc_querycap(struct file *file, void *priv,
@@ -199,68 +195,75 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-trust", sizeof(v->driver));
strlcpy(v->card, "Trust FM Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
+ struct trust *tr = video_drvdata(file);
+
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87.5*16000);
- v->rangehigh = (108*16000);
- v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->rangelow = 87.5 * 16000;
+ v->rangehigh = 108 * 16000;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = V4L2_TUNER_CAP_LOW;
- if (tr_getstereo())
+ if (tr_getstereo(tr))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = tr_getsigstr();
+ v->signal = tr_getsigstr(tr);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
+ struct trust *tr = video_drvdata(file);
+ if (v->index)
+ return -EINVAL;
+ tr_setstereo(tr, v->audmode == V4L2_TUNER_MODE_STEREO);
return 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- curfreq = f->frequency;
- tr_setfreq(curfreq);
+ struct trust *tr = video_drvdata(file);
+
+ tr_setfreq(tr, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
+ struct trust *tr = video_drvdata(file);
+
f->type = V4L2_TUNER_RADIO;
- f->frequency = curfreq;
+ f->frequency = tr->curfreq;
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 2048, 65535);
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 4370, 32768);
}
return -EINVAL;
}
@@ -268,18 +271,20 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct trust *tr = video_drvdata(file);
+
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = curmute;
+ ctrl->value = tr->curmute;
return 0;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = curvol * 2048;
+ ctrl->value = tr->curvol * 2048;
return 0;
case V4L2_CID_AUDIO_BASS:
- ctrl->value = curbass * 4370;
+ ctrl->value = tr->curbass * 4370;
return 0;
case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = curtreble * 4370;
+ ctrl->value = tr->curtreble * 4370;
return 0;
}
return -EINVAL;
@@ -288,34 +293,25 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct trust *tr = video_drvdata(file);
+
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- tr_setmute(ctrl->value);
+ tr_setmute(tr, ctrl->value);
return 0;
case V4L2_CID_AUDIO_VOLUME:
- tr_setvol(ctrl->value);
+ tr_setvol(tr, ctrl->value);
return 0;
case V4L2_CID_AUDIO_BASS:
- tr_setbass(ctrl->value);
+ tr_setbass(tr, ctrl->value);
return 0;
case V4L2_CID_AUDIO_TREBLE:
- tr_settreble(ctrl->value);
+ tr_settreble(tr, ctrl->value);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -324,34 +320,38 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static int trust_exclusive_open(struct file *file)
+static int trust_open(struct file *file)
{
- return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
+ return 0;
}
-static int trust_exclusive_release(struct file *file)
+static int trust_release(struct file *file)
{
- clear_bit(0, &in_use);
return 0;
}
static const struct v4l2_file_operations trust_fops = {
.owner = THIS_MODULE,
- .open = trust_exclusive_open,
- .release = trust_exclusive_release,
+ .open = trust_open,
+ .release = trust_release,
.ioctl = video_ioctl2,
};
@@ -370,59 +370,72 @@ static const struct v4l2_ioctl_ops trust_ioctl_ops = {
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device trust_radio = {
- .name = "Trust FM Radio",
- .fops = &trust_fops,
- .ioctl_ops = &trust_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init trust_init(void)
{
- if(io == -1) {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct trust *tr = &trust_card;
+ struct v4l2_device *v4l2_dev = &tr->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "trust", sizeof(v4l2_dev->name));
+ tr->io = io;
+ tr->ioval = 0xf;
+ mutex_init(&tr->lock);
+
+ if (tr->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x0x350 or 0x358\n");
return -EINVAL;
}
- if(!request_region(io, 2, "Trust FM Radio")) {
- printk(KERN_ERR "trust: port 0x%x already in use\n", io);
+ if (!request_region(tr->io, 2, "Trust FM Radio")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", tr->io);
return -EBUSY;
}
- if (video_register_device(&trust_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(tr->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ strlcpy(tr->vdev.name, v4l2_dev->name, sizeof(tr->vdev.name));
+ tr->vdev.v4l2_dev = v4l2_dev;
+ tr->vdev.fops = &trust_fops;
+ tr->vdev.ioctl_ops = &trust_ioctl_ops;
+ tr->vdev.release = video_device_release_empty;
+ video_set_drvdata(&tr->vdev, tr);
+
+ if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(tr->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "Trust FM Radio card driver v1.0.\n");
+ v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n");
- write_i2c(2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
- write_i2c(2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0xe0); /* speaker att. RR = 0 dB */
+ write_i2c(tr, 2, TDA7318_ADDR, 0x40); /* stereo 1 input, gain = 18.75 dB */
- tr_setvol(0x8000);
- tr_setbass(0x8000);
- tr_settreble(0x8000);
- tr_setstereo(1);
+ tr_setvol(tr, 0xffff);
+ tr_setbass(tr, 0x8000);
+ tr_settreble(tr, 0x8000);
+ tr_setstereo(tr, 1);
/* mute card - prevents noisy bootups */
- tr_setmute(1);
+ tr_setmute(tr, 1);
return 0;
}
-MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Trust FM Radio card (0x350 or 0x358)");
-module_param(radio_nr, int, 0);
-
static void __exit cleanup_trust_module(void)
{
- video_unregister_device(&trust_radio);
- release_region(io, 2);
+ struct trust *tr = &trust_card;
+
+ video_unregister_device(&tr->vdev);
+ v4l2_device_unregister(&tr->v4l2_dev);
+ release_region(tr->io, 2);
}
module_init(trust_init);
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c
index 5c3b319dab3..92d923c7f36 100644
--- a/drivers/media/radio/radio-typhoon.c
+++ b/drivers/media/radio/radio-typhoon.c
@@ -34,37 +34,15 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
-#include <linux/proc_fs.h> /* radio card status report */
-#include <linux/seq_file.h>
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,1,1)
-#define BANNER "Typhoon Radio Card driver v0.1.1\n"
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 1<<14,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
-
+MODULE_AUTHOR("Dr. Henrik Seidel");
+MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_TYPHOON_PORT
#define CONFIG_RADIO_TYPHOON_PORT -1
@@ -74,13 +52,26 @@ static struct v4l2_queryctrl radio_qctrl[] = {
#define CONFIG_RADIO_TYPHOON_MUTEFREQ 0
#endif
-#ifndef CONFIG_PROC_FS
-#undef CONFIG_RADIO_TYPHOON_PROC_FS
-#endif
+static int io = CONFIG_RADIO_TYPHOON_PORT;
+static int radio_nr = -1;
-struct typhoon_device {
- unsigned long in_use;
- int iobase;
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
+
+module_param(radio_nr, int, 0);
+
+static unsigned long mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ;
+module_param(mutefreq, ulong, 0);
+MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 1, 1)
+
+#define BANNER "Typhoon Radio Card driver v0.1.1\n"
+
+struct typhoon {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
int muted;
unsigned long curfreq;
@@ -88,25 +79,19 @@ struct typhoon_device {
struct mutex lock;
};
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol);
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
- unsigned long frequency);
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency);
-static void typhoon_mute(struct typhoon_device *dev);
-static void typhoon_unmute(struct typhoon_device *dev);
-static int typhoon_setvol(struct typhoon_device *dev, int vol);
+static struct typhoon typhoon_card;
-static void typhoon_setvol_generic(struct typhoon_device *dev, int vol)
+static void typhoon_setvol_generic(struct typhoon *dev, int vol)
{
mutex_lock(&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. */
+ outb_p(vol / 2, dev->io); /* Set the volume, high bit. */
+ outb_p(vol % 2, dev->io + 2); /* Set the volume, low bit. */
mutex_unlock(&dev->lock);
}
-static int typhoon_setfreq_generic(struct typhoon_device *dev,
+static int typhoon_setfreq_generic(struct typhoon *dev,
unsigned long frequency)
{
unsigned long outval;
@@ -130,22 +115,22 @@ static int typhoon_setfreq_generic(struct typhoon_device *dev,
outval -= (10 * x * x + 10433) / 20866;
outval += 4 * x - 11505;
- outb_p((outval >> 8) & 0x01, dev->iobase + 4);
- outb_p(outval >> 9, dev->iobase + 6);
- outb_p(outval & 0xff, dev->iobase + 8);
+ outb_p((outval >> 8) & 0x01, dev->io + 4);
+ outb_p(outval >> 9, dev->io + 6);
+ outb_p(outval & 0xff, dev->io + 8);
mutex_unlock(&dev->lock);
return 0;
}
-static int typhoon_setfreq(struct typhoon_device *dev, unsigned long frequency)
+static int typhoon_setfreq(struct typhoon *dev, unsigned long frequency)
{
typhoon_setfreq_generic(dev, frequency);
dev->curfreq = frequency;
return 0;
}
-static void typhoon_mute(struct typhoon_device *dev)
+static void typhoon_mute(struct typhoon *dev)
{
if (dev->muted == 1)
return;
@@ -154,7 +139,7 @@ static void typhoon_mute(struct typhoon_device *dev)
dev->muted = 1;
}
-static void typhoon_unmute(struct typhoon_device *dev)
+static void typhoon_unmute(struct typhoon *dev)
{
if (dev->muted == 0)
return;
@@ -163,7 +148,7 @@ static void typhoon_unmute(struct typhoon_device *dev)
dev->muted = 0;
}
-static int typhoon_setvol(struct typhoon_device *dev, int vol)
+static int typhoon_setvol(struct typhoon *dev, int vol)
{
if (dev->muted && vol != 0) { /* user is unmuting the card */
dev->curvol = vol;
@@ -188,9 +173,9 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-typhoon", sizeof(v->driver));
strlcpy(v->card, "Typhoon Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
@@ -200,10 +185,10 @@ static int vidioc_g_tuner(struct file *file, void *priv,
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (87.5*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 87.5 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
@@ -214,44 +199,37 @@ static int vidioc_g_tuner(struct file *file, void *priv,
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
+ return v->index ? -EINVAL : 0;
}
-static int vidioc_s_frequency(struct file *file, void *priv,
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct typhoon_device *typhoon = video_drvdata(file);
+ struct typhoon *dev = video_drvdata(file);
- typhoon->curfreq = f->frequency;
- typhoon_setfreq(typhoon, typhoon->curfreq);
+ f->type = V4L2_TUNER_RADIO;
+ f->frequency = dev->curfreq;
return 0;
}
-static int vidioc_g_frequency(struct file *file, void *priv,
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct typhoon_device *typhoon = video_drvdata(file);
-
- f->type = V4L2_TUNER_RADIO;
- f->frequency = typhoon->curfreq;
+ struct typhoon *dev = video_drvdata(file);
+ dev->curfreq = f->frequency;
+ typhoon_setfreq(dev, dev->curfreq);
return 0;
}
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 16384, 65535);
}
return -EINVAL;
}
@@ -259,14 +237,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct typhoon_device *typhoon = video_drvdata(file);
+ struct typhoon *dev = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
- ctrl->value = typhoon->muted;
+ ctrl->value = dev->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = typhoon->curvol;
+ ctrl->value = dev->curvol;
return 0;
}
return -EINVAL;
@@ -275,33 +253,22 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl (struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct typhoon_device *typhoon = video_drvdata(file);
+ struct typhoon *dev = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
if (ctrl->value)
- typhoon_mute(typhoon);
+ typhoon_mute(dev);
else
- typhoon_unmute(typhoon);
+ typhoon_unmute(dev);
return 0;
case V4L2_CID_AUDIO_VOLUME:
- typhoon_setvol(typhoon, ctrl->value);
+ typhoon_setvol(dev, ctrl->value);
return 0;
}
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -310,45 +277,62 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
+ return i ? -EINVAL : 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
+ return a->index ? -EINVAL : 0;
}
-static struct typhoon_device typhoon_unit =
+static int vidioc_log_status(struct file *file, void *priv)
{
- .iobase = CONFIG_RADIO_TYPHOON_PORT,
- .curfreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
- .mutefreq = CONFIG_RADIO_TYPHOON_MUTEFREQ,
-};
+ struct typhoon *dev = video_drvdata(file);
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+
+ v4l2_info(v4l2_dev, BANNER);
+#ifdef MODULE
+ v4l2_info(v4l2_dev, "Load type: Driver loaded as a module\n\n");
+#else
+ v4l2_info(v4l2_dev, "Load type: Driver compiled into kernel\n\n");
+#endif
+ v4l2_info(v4l2_dev, "frequency = %lu kHz\n", dev->curfreq >> 4);
+ v4l2_info(v4l2_dev, "volume = %d\n", dev->curvol);
+ v4l2_info(v4l2_dev, "mute = %s\n", dev->muted ? "on" : "off");
+ v4l2_info(v4l2_dev, "io = 0x%x\n", dev->io);
+ v4l2_info(v4l2_dev, "mute frequency = %lu kHz\n", dev->mutefreq >> 4);
+ return 0;
+}
-static int typhoon_exclusive_open(struct file *file)
+static int typhoon_open(struct file *file)
{
- return test_and_set_bit(0, &typhoon_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int typhoon_exclusive_release(struct file *file)
+static int typhoon_release(struct file *file)
{
- clear_bit(0, &typhoon_unit.in_use);
return 0;
}
static const struct v4l2_file_operations typhoon_fops = {
.owner = THIS_MODULE,
- .open = typhoon_exclusive_open,
- .release = typhoon_exclusive_release,
+ .open = typhoon_open,
+ .release = typhoon_release,
.ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
+ .vidioc_log_status = vidioc_log_status,
.vidioc_querycap = vidioc_querycap,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
@@ -363,125 +347,72 @@ static const struct v4l2_ioctl_ops typhoon_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device typhoon_radio = {
- .name = "Typhoon Radio",
- .fops = &typhoon_fops,
- .ioctl_ops = &typhoon_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
-
-static int typhoon_proc_show(struct seq_file *m, void *v)
-{
- #ifdef MODULE
- #define MODULEPROCSTRING "Driver loaded as a module"
- #else
- #define MODULEPROCSTRING "Driver compiled into kernel"
- #endif
-
- seq_puts(m, BANNER);
- seq_puts(m, "Load type: " MODULEPROCSTRING "\n\n");
- seq_printf(m, "frequency = %lu kHz\n",
- typhoon_unit.curfreq >> 4);
- seq_printf(m, "volume = %d\n", typhoon_unit.curvol);
- seq_printf(m, "mute = %s\n", typhoon_unit.muted ?
- "on" : "off");
- seq_printf(m, "iobase = 0x%x\n", typhoon_unit.iobase);
- seq_printf(m, "mute frequency = %lu kHz\n",
- typhoon_unit.mutefreq >> 4);
- return 0;
-}
-
-static int typhoon_proc_open(struct inode *inode, struct file *file)
+static int __init typhoon_init(void)
{
- return single_open(file, typhoon_proc_show, NULL);
-}
-
-static const struct file_operations typhoon_proc_fops = {
- .owner = THIS_MODULE,
- .open = typhoon_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif /* CONFIG_RADIO_TYPHOON_PROC_FS */
-
-MODULE_AUTHOR("Dr. Henrik Seidel");
-MODULE_DESCRIPTION("A driver for the Typhoon radio card (a.k.a. EcoRadio).");
-MODULE_LICENSE("GPL");
-
-static int io = -1;
-static int radio_nr = -1;
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Typhoon card (0x316 or 0x336)");
-module_param(radio_nr, int, 0);
+ struct typhoon *dev = &typhoon_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
-#ifdef MODULE
-static unsigned long mutefreq;
-module_param(mutefreq, ulong, 0);
-MODULE_PARM_DESC(mutefreq, "Frequency used when muting the card (in kHz)");
-#endif
+ strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name));
+ dev->io = io;
+ dev->curfreq = dev->mutefreq = mutefreq;
-static int __init typhoon_init(void)
-{
-#ifdef MODULE
- if (io == -1) {
- printk(KERN_ERR "radio-typhoon: You must set an I/O address with io=0x316 or io=0x336\n");
+ if (dev->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n");
return -EINVAL;
}
- typhoon_unit.iobase = io;
- if (mutefreq < 87000 || mutefreq > 108500) {
- printk(KERN_ERR "radio-typhoon: You must set a frequency (in kHz) used when muting the card,\n");
- printk(KERN_ERR "radio-typhoon: e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
+ if (dev->mutefreq < 87000 || dev->mutefreq > 108500) {
+ v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n");
+ v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n");
return -EINVAL;
}
- typhoon_unit.mutefreq = mutefreq;
-#endif /* MODULE */
-
- printk(KERN_INFO BANNER);
- mutex_init(&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",
- typhoon_unit.iobase);
+
+ mutex_init(&dev->lock);
+ if (!request_region(dev->io, 8, "typhoon")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n",
+ dev->io);
return -EBUSY;
}
- video_set_drvdata(&typhoon_radio, &typhoon_unit);
- if (video_register_device(&typhoon_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 8);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(dev->io, 8);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+ v4l2_info(v4l2_dev, BANNER);
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &typhoon_fops;
+ dev->vdev.ioctl_ops = &typhoon_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 8);
return -EINVAL;
}
- printk(KERN_INFO "radio-typhoon: port 0x%x.\n", typhoon_unit.iobase);
- printk(KERN_INFO "radio-typhoon: mute frequency is %lu kHz.\n",
- typhoon_unit.mutefreq);
- typhoon_unit.mutefreq <<= 4;
+ v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io);
+ v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq);
+ dev->mutefreq <<= 4;
/* mute card - prevents noisy bootups */
- typhoon_mute(&typhoon_unit);
-
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
- if (!proc_create("driver/radio-typhoon", 0, NULL, &typhoon_proc_fops))
- printk(KERN_ERR "radio-typhoon: registering /proc/driver/radio-typhoon failed\n");
-#endif
+ typhoon_mute(dev);
return 0;
}
-static void __exit typhoon_cleanup_module(void)
+static void __exit typhoon_exit(void)
{
+ struct typhoon *dev = &typhoon_card;
-#ifdef CONFIG_RADIO_TYPHOON_PROC_FS
- remove_proc_entry("driver/radio-typhoon", NULL);
-#endif
-
- video_unregister_device(&typhoon_radio);
- release_region(io, 8);
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 8);
}
module_init(typhoon_init);
-module_exit(typhoon_cleanup_module);
+module_exit(typhoon_exit);
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c
index d2ac17eeec5..1f85f2024dc 100644
--- a/drivers/media/radio/radio-zoltrix.c
+++ b/drivers/media/radio/radio-zoltrix.c
@@ -33,33 +33,16 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay, msleep */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
+#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 4096,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+MODULE_AUTHOR("C.van Schaik");
+MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_ZOLTRIX_PORT
#define CONFIG_RADIO_ZOLTRIX_PORT -1
@@ -68,9 +51,16 @@ static struct v4l2_queryctrl radio_qctrl[] = {
static int io = CONFIG_RADIO_ZOLTRIX_PORT;
static int radio_nr = -1;
-struct zol_device {
- unsigned long in_use;
- int port;
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct zoltrix {
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
unsigned long curfreq;
int muted;
@@ -78,161 +68,158 @@ struct zol_device {
struct mutex lock;
};
-static int zol_setvol(struct zol_device *dev, int vol)
+static struct zoltrix zoltrix_card;
+
+static int zol_setvol(struct zoltrix *zol, int vol)
{
- dev->curvol = vol;
- if (dev->muted)
+ zol->curvol = vol;
+ if (zol->muted)
return 0;
- mutex_lock(&dev->lock);
+ mutex_lock(&zol->lock);
if (vol == 0) {
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
- mutex_unlock(&dev->lock);
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
+ mutex_unlock(&zol->lock);
return 0;
}
- outb(dev->curvol-1, io);
+ outb(zol->curvol-1, zol->io);
msleep(10);
- inb(io + 2);
- mutex_unlock(&dev->lock);
+ inb(zol->io + 2);
+ mutex_unlock(&zol->lock);
return 0;
}
-static void zol_mute(struct zol_device *dev)
+static void zol_mute(struct zoltrix *zol)
{
- dev->muted = 1;
- mutex_lock(&dev->lock);
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
- mutex_unlock(&dev->lock);
+ zol->muted = 1;
+ mutex_lock(&zol->lock);
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
+ mutex_unlock(&zol->lock);
}
-static void zol_unmute(struct zol_device *dev)
+static void zol_unmute(struct zoltrix *zol)
{
- dev->muted = 0;
- zol_setvol(dev, dev->curvol);
+ zol->muted = 0;
+ zol_setvol(zol, zol->curvol);
}
-static int zol_setfreq(struct zol_device *dev, unsigned long freq)
+static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
{
/* tunes the radio to the desired frequency */
+ struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
unsigned long long bitmask, f, m;
- unsigned int stereo = dev->stereo;
+ unsigned int stereo = zol->stereo;
int i;
if (freq == 0) {
- printk(KERN_WARNING "zoltrix: received zero freq. Failed to set.\n");
+ v4l2_warn(v4l2_dev, "cannot set a frequency of 0.\n");
return -EINVAL;
}
m = (freq / 160 - 8800) * 2;
- f = (unsigned long long) m + 0x4d1c;
+ f = (unsigned long long)m + 0x4d1c;
bitmask = 0xc480402c10080000ull;
i = 45;
- mutex_lock(&dev->lock);
+ mutex_lock(&zol->lock);
- outb(0, io);
- outb(0, io);
- inb(io + 3); /* Zoltrix needs to be read to confirm */
+ zol->curfreq = freq;
- outb(0x40, io);
- outb(0xc0, io);
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3); /* Zoltrix needs to be read to confirm */
- bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( stereo << 31));
+ outb(0x40, zol->io);
+ outb(0xc0, zol->io);
+
+ bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ (stereo << 31));
while (i--) {
if ((bitmask & 0x8000000000000000ull) != 0) {
- outb(0x80, io);
+ outb(0x80, zol->io);
udelay(50);
- outb(0x00, io);
+ outb(0x00, zol->io);
udelay(50);
- outb(0x80, io);
+ outb(0x80, zol->io);
udelay(50);
} else {
- outb(0xc0, io);
+ outb(0xc0, zol->io);
udelay(50);
- outb(0x40, io);
+ outb(0x40, zol->io);
udelay(50);
- outb(0xc0, io);
+ outb(0xc0, zol->io);
udelay(50);
}
bitmask *= 2;
}
/* termination sequence */
- outb(0x80, io);
- outb(0xc0, io);
- outb(0x40, io);
+ outb(0x80, zol->io);
+ outb(0xc0, zol->io);
+ outb(0x40, zol->io);
udelay(1000);
- inb(io+2);
+ inb(zol->io + 2);
udelay(1000);
- if (dev->muted)
- {
- outb(0, io);
- outb(0, io);
- inb(io + 3);
+ if (zol->muted) {
+ outb(0, zol->io);
+ outb(0, zol->io);
+ inb(zol->io + 3);
udelay(1000);
}
- mutex_unlock(&dev->lock);
+ mutex_unlock(&zol->lock);
- if(!dev->muted)
- {
- zol_setvol(dev, dev->curvol);
- }
+ if (!zol->muted)
+ zol_setvol(zol, zol->curvol);
return 0;
}
/* Get signal strength */
-
-static int zol_getsigstr(struct zol_device *dev)
+static int zol_getsigstr(struct zoltrix *zol)
{
int a, b;
- mutex_lock(&dev->lock);
- outb(0x00, io); /* This stuff I found to do nothing */
- outb(dev->curvol, io);
+ mutex_lock(&zol->lock);
+ outb(0x00, zol->io); /* This stuff I found to do nothing */
+ outb(zol->curvol, zol->io);
msleep(20);
- a = inb(io);
+ a = inb(zol->io);
msleep(10);
- b = inb(io);
+ b = inb(zol->io);
- mutex_unlock(&dev->lock);
+ mutex_unlock(&zol->lock);
if (a != b)
- return (0);
+ return 0;
- if ((a == 0xcf) || (a == 0xdf) /* I found this out by playing */
- || (a == 0xef)) /* with a binary scanner on the card io */
- return (1);
- return (0);
+ /* I found this out by playing with a binary scanner on the card io */
+ return a == 0xcf || a == 0xdf || a == 0xef;
}
-static int zol_is_stereo (struct zol_device *dev)
+static int zol_is_stereo(struct zoltrix *zol)
{
int x1, x2;
- mutex_lock(&dev->lock);
+ mutex_lock(&zol->lock);
- outb(0x00, io);
- outb(dev->curvol, io);
+ outb(0x00, zol->io);
+ outb(zol->curvol, zol->io);
msleep(20);
- x1 = inb(io);
+ x1 = inb(zol->io);
msleep(10);
- x2 = inb(io);
+ x2 = inb(zol->io);
- mutex_unlock(&dev->lock);
+ mutex_unlock(&zol->lock);
- if ((x1 == x2) && (x1 == 0xcf))
- return 1;
- return 0;
+ return x1 == x2 && x1 == 0xcf;
}
static int vidioc_querycap(struct file *file, void *priv,
@@ -240,59 +227,54 @@ static int vidioc_querycap(struct file *file, void *priv,
{
strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
strlcpy(v->card, "Zoltrix Radio", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
if (v->index > 0)
return -EINVAL;
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (88*16000);
- v->rangehigh = (108*16000);
- v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+ v->rangelow = 88 * 16000;
+ v->rangehigh = 108 * 16000;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
v->capability = V4L2_TUNER_CAP_LOW;
if (zol_is_stereo(zol))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF*zol_getsigstr(zol);
+ v->signal = 0xFFFF * zol_getsigstr(zol);
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
- return 0;
+ return v->index ? -EINVAL : 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
- zol->curfreq = f->frequency;
- if (zol_setfreq(zol, zol->curfreq) != 0) {
- printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
+ if (zol_setfreq(zol, f->frequency) != 0)
return -EINVAL;
- }
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = zol->curfreq;
@@ -302,14 +284,11 @@ static int vidioc_g_frequency(struct file *file, void *priv,
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 4096, 65535);
}
return -EINVAL;
}
@@ -317,7 +296,7 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -333,7 +312,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct zol_device *zol = video_drvdata(file);
+ struct zoltrix *zol = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -341,43 +320,30 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
zol_mute(zol);
else {
zol_unmute(zol);
- zol_setvol(zol,zol->curvol);
+ zol_setvol(zol, zol->curvol);
}
return 0;
case V4L2_CID_AUDIO_VOLUME:
- zol_setvol(zol,ctrl->value/4096);
+ zol_setvol(zol, ctrl->value / 4096);
return 0;
}
zol->stereo = 1;
- if (zol_setfreq(zol, zol->curfreq) != 0) {
- printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
+ if (zol_setfreq(zol, zol->curfreq) != 0)
return -EINVAL;
- }
#if 0
/* FIXME: Implement stereo/mono switch on V4L2 */
- if (v->mode & VIDEO_SOUND_STEREO) {
- zol->stereo = 1;
- zol_setfreq(zol, zol->curfreq);
- }
- if (v->mode & VIDEO_SOUND_MONO) {
- zol->stereo = 0;
- zol_setfreq(zol, zol->curfreq);
- }
+ if (v->mode & VIDEO_SOUND_STEREO) {
+ zol->stereo = 1;
+ zol_setfreq(zol, zol->curfreq);
+ }
+ if (v->mode & VIDEO_SOUND_MONO) {
+ zol->stereo = 0;
+ zol_setfreq(zol, zol->curfreq);
+ }
#endif
return -EINVAL;
}
-static int vidioc_g_audio(struct file *file, void *priv,
- struct v4l2_audio *a)
-{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
- a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
{
*i = 0;
@@ -386,37 +352,39 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
{
- if (i != 0)
- return -EINVAL;
- return 0;
+ return i ? -EINVAL : 0;
}
-static int vidioc_s_audio(struct file *file, void *priv,
+static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
+ a->capability = V4L2_AUDCAP_STEREO;
return 0;
}
-static struct zol_device zoltrix_unit;
+static int vidioc_s_audio(struct file *file, void *priv,
+ struct v4l2_audio *a)
+{
+ return a->index ? -EINVAL : 0;
+}
-static int zoltrix_exclusive_open(struct file *file)
+static int zoltrix_open(struct file *file)
{
- return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0;
+ return 0;
}
-static int zoltrix_exclusive_release(struct file *file)
+static int zoltrix_release(struct file *file)
{
- clear_bit(0, &zoltrix_unit.in_use);
return 0;
}
static const struct v4l2_file_operations zoltrix_fops =
{
.owner = THIS_MODULE,
- .open = zoltrix_exclusive_open,
- .release = zoltrix_exclusive_release,
+ .open = zoltrix_open,
+ .release = zoltrix_release,
.ioctl = video_ioctl2,
};
@@ -435,67 +403,75 @@ static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = {
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device zoltrix_radio = {
- .name = "Zoltrix Radio Plus",
- .fops = &zoltrix_fops,
- .ioctl_ops = &zoltrix_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init zoltrix_init(void)
{
- if (io == -1) {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct zoltrix *zol = &zoltrix_card;
+ struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name));
+ zol->io = io;
+ if (zol->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c or 0x30c\n");
return -EINVAL;
}
- if ((io != 0x20c) && (io != 0x30c)) {
- printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
+ if (zol->io != 0x20c && zol->io != 0x30c) {
+ v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n");
return -ENXIO;
}
- video_set_drvdata(&zoltrix_radio, &zoltrix_unit);
- if (!request_region(io, 2, "zoltrix")) {
- printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
+ if (!request_region(zol->io, 2, "zoltrix")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io);
return -EBUSY;
}
- if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
- release_region(io, 2);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(zol->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+ zol->vdev.v4l2_dev = v4l2_dev;
+ zol->vdev.fops = &zoltrix_fops;
+ zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+ zol->vdev.release = video_device_release_empty;
+ video_set_drvdata(&zol->vdev, zol);
+
+ if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(zol->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
+ v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
- mutex_init(&zoltrix_unit.lock);
+ mutex_init(&zol->lock);
/* mute card - prevents noisy bootups */
/* this ensures that the volume is all the way down */
- outb(0, io);
- outb(0, io);
+ outb(0, zol->io);
+ outb(0, zol->io);
msleep(20);
- inb(io + 3);
+ inb(zol->io + 3);
- zoltrix_unit.curvol = 0;
- zoltrix_unit.stereo = 1;
+ zol->curvol = 0;
+ zol->stereo = 1;
return 0;
}
-MODULE_AUTHOR("C.van Schaik");
-MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit zoltrix_cleanup_module(void)
+static void __exit zoltrix_exit(void)
{
- video_unregister_device(&zoltrix_radio);
- release_region(io, 2);
+ struct zoltrix *zol = &zoltrix_card;
+
+ video_unregister_device(&zol->vdev);
+ v4l2_device_unregister(&zol->v4l2_dev);
+ release_region(zol->io, 2);
}
module_init(zoltrix_init);
-module_exit(zoltrix_cleanup_module);
+module_exit(zoltrix_exit);
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 19cf3b8f67c..76bad581959 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -249,11 +249,25 @@ config VIDEO_VP27SMPX
To compile this driver as a module, choose M here: the
module will be called vp27smpx.
+comment "RDS decoders"
+
+config VIDEO_SAA6588
+ tristate "SAA6588 Radio Chip RDS decoder support"
+ depends on VIDEO_V4L2 && I2C
+
+ help
+ Support for this Radio Data System (RDS) decoder. This allows
+ seeing radio station identification transmitted using this
+ standard.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa6588.
+
comment "Video decoders"
config VIDEO_BT819
tristate "BT819A VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT819A video decoder.
@@ -262,7 +276,7 @@ config VIDEO_BT819
config VIDEO_BT856
tristate "BT856 VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT856 video decoder.
@@ -271,7 +285,7 @@ config VIDEO_BT856
config VIDEO_BT866
tristate "BT866 VideoStream decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for BT866 video decoder.
@@ -280,7 +294,7 @@ config VIDEO_BT866
config VIDEO_KS0127
tristate "KS0127 video decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for KS0127 video decoder.
@@ -307,38 +321,18 @@ config VIDEO_TCM825X
config VIDEO_SAA7110
tristate "Philips SAA7110 video decoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7110 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7110.
-config VIDEO_SAA7111
- tristate "Philips SAA7111 video decoder"
- depends on VIDEO_V4L1 && I2C
- ---help---
- Support for the Philips SAA711 video decoder.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7111.
-
-config VIDEO_SAA7114
- tristate "Philips SAA7114 video decoder"
- depends on VIDEO_V4L1 && I2C
- ---help---
- Support for the Philips SAA7114 video decoder. This driver
- is used only on Zoran driver and should be moved soon to
- SAA711x module.
-
- To compile this driver as a module, choose M here: the
- module will be called saa7114.
-
config VIDEO_SAA711X
- tristate "Philips SAA7113/4/5 video decoders"
+ tristate "Philips SAA7111/3/4/5 video decoders"
depends on VIDEO_V4L2 && I2C
---help---
- Support for the Philips SAA7113/4/5 video decoders.
+ Support for the Philips SAA7111/3/4/5 video decoders.
To compile this driver as a module, choose M here: the
module will be called saa7115.
@@ -383,7 +377,7 @@ config VIDEO_TVP5150
config VIDEO_VPX3220
tristate "vpx3220a, vpx3216b & vpx3214c video decoders"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for VPX322x video decoders.
@@ -421,7 +415,7 @@ config VIDEO_SAA7127
config VIDEO_SAA7185
tristate "Philips SAA7185 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7185 video encoder.
@@ -430,7 +424,7 @@ config VIDEO_SAA7185
config VIDEO_ADV7170
tristate "Analog Devices ADV7170 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Analog Devices ADV7170 video encoder driver
@@ -439,7 +433,7 @@ config VIDEO_ADV7170
config VIDEO_ADV7175
tristate "Analog Devices ADV7175 video encoder"
- depends on VIDEO_V4L1 && I2C
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Analog Devices ADV7175 video encoder driver
@@ -487,18 +481,6 @@ config VIDEO_VIVI
source "drivers/media/video/bt8xx/Kconfig"
-config VIDEO_SAA6588
- tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
- depends on I2C && VIDEO_BT848
-
- help
- Support for Radio Data System (RDS) decoder. This allows seeing
- radio station identification transmitted using this standard.
- Currently, it works only with bt8x8 chips.
-
- To compile this driver as a module, choose M here: the
- module will be called saa6588.
-
config VIDEO_PMS
tristate "Mediavision Pro Movie Studio Video For Linux"
depends on ISA && VIDEO_V4L1
@@ -602,7 +584,6 @@ config VIDEO_SAA5249
config VIDEO_VINO
tristate "SGI Vino Video For Linux (EXPERIMENTAL)"
depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2
- select I2C_ALGO_SGI
select VIDEO_SAA7191 if VIDEO_HELPER_CHIPS_AUTO
help
Say Y here to build in support for the Vino video input system found
@@ -639,7 +620,7 @@ config VIDEO_MXB
depends on PCI && VIDEO_V4L1 && I2C
select VIDEO_SAA7146_VV
select VIDEO_TUNER
- select VIDEO_SAA7115 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TDA9840 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TEA6415C if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TEA6420 if VIDEO_HELPER_CHIPS_AUTO
@@ -728,13 +709,6 @@ config SOC_CAMERA_MT9M001
This driver supports MT9M001 cameras from Micron, monochrome
and colour models.
-config MT9M001_PCA9536_SWITCH
- bool "pca9536 datawidth switch for mt9m001"
- depends on SOC_CAMERA_MT9M001 && GENERIC_GPIO
- help
- Select this if your MT9M001 camera uses a PCA9536 I2C GPIO
- extender to switch between 8 and 10 bit datawidth modes
-
config SOC_CAMERA_MT9M111
tristate "mt9m111 and mt9m112 support"
depends on SOC_CAMERA && I2C
@@ -754,13 +728,6 @@ config SOC_CAMERA_MT9V022
help
This driver supports MT9V022 cameras from Micron
-config MT9V022_PCA9536_SWITCH
- bool "pca9536 datawidth switch for mt9v022"
- depends on SOC_CAMERA_MT9V022 && GENERIC_GPIO
- help
- Select this if your MT9V022 camera uses a PCA9536 I2C GPIO
- extender to switch between 8 and 10 bit datawidth modes
-
config SOC_CAMERA_TW9910
tristate "tw9910 support"
depends on SOC_CAMERA && I2C
@@ -779,6 +746,13 @@ config SOC_CAMERA_OV772X
help
This is a ov772x camera driver
+config VIDEO_MX3
+ tristate "i.MX3x Camera Sensor Interface driver"
+ depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
+ select VIDEOBUF_DMA_CONTIG
+ ---help---
+ This is a v4l2 driver for the i.MX3x Camera Sensor Interface
+
config VIDEO_PXA27x
tristate "PXA27x Quick Capture Interface driver"
depends on VIDEO_DEV && PXA27x && SOC_CAMERA
@@ -817,6 +791,8 @@ source "drivers/media/video/gspca/Kconfig"
source "drivers/media/video/pvrusb2/Kconfig"
+source "drivers/media/video/hdpvr/Kconfig"
+
source "drivers/media/video/em28xx/Kconfig"
source "drivers/media/video/usbvision/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 72f6d03d2d8..b9046744463 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -30,7 +30,6 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o
obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o
obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o
-obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o
obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o
obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o
@@ -43,8 +42,6 @@ obj-$(CONFIG_VIDEO_TDA9840) += tda9840.o
obj-$(CONFIG_VIDEO_TEA6415C) += tea6415c.o
obj-$(CONFIG_VIDEO_TEA6420) += tea6420.o
obj-$(CONFIG_VIDEO_SAA7110) += saa7110.o
-obj-$(CONFIG_VIDEO_SAA7111) += saa7111.o
-obj-$(CONFIG_VIDEO_SAA7114) += saa7114.o
obj-$(CONFIG_VIDEO_SAA711X) += saa7115.o
obj-$(CONFIG_VIDEO_SAA717X) += saa717x.o
obj-$(CONFIG_VIDEO_SAA7127) += saa7127.o
@@ -122,6 +119,8 @@ obj-$(CONFIG_USB_PWC) += pwc/
obj-$(CONFIG_USB_ZC0301) += zc0301/
obj-$(CONFIG_USB_GSPCA) += gspca/
+obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/
+
obj-$(CONFIG_USB_IBMCAM) += usbvideo/
obj-$(CONFIG_USB_KONICAWC) += usbvideo/
obj-$(CONFIG_USB_VICAM) += usbvideo/
@@ -134,10 +133,11 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/
obj-$(CONFIG_VIDEO_VIVI) += vivi.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885/
-obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
+obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
+obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o
-obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
+obj-$(CONFIG_SOC_CAMERA) += soc_camera.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o
obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o
diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c
index e0eb4f32144..873c30a41bd 100644
--- a/drivers/media/video/adv7170.c
+++ b/drivers/media/video/adv7170.c
@@ -34,15 +34,16 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Analog Devices ADV7170 video encoder driver");
MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
+
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -50,38 +51,43 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
struct adv7170 {
+ struct v4l2_subdev sd;
unsigned char reg[128];
- int norm;
+ v4l2_std_id norm;
int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
+static inline struct adv7170 *to_adv7170(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct adv7170, sd);
+}
+
static char *inputs[] = { "pass_through", "play_back" };
-static char *norms[] = { "PAL", "NTSC" };
/* ----------------------------------------------------------------------- */
-static inline int adv7170_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int adv7170_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- struct adv7170 *encoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct adv7170 *encoder = to_adv7170(sd);
encoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int adv7170_read(struct i2c_client *client, u8 reg)
+static inline int adv7170_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int adv7170_write_block(struct i2c_client *client,
+static int adv7170_write_block(struct v4l2_subdev *sd,
const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct adv7170 *encoder = to_adv7170(sd);
int ret = -1;
u8 reg;
@@ -89,7 +95,6 @@ static int adv7170_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 adv7170 *encoder = i2c_get_clientdata(client);
u8 block_data[32];
int block_len;
@@ -110,7 +115,7 @@ static int adv7170_write_block(struct i2c_client *client,
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- ret = adv7170_write(client, reg, *data++);
+ ret = adv7170_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -128,203 +133,161 @@ static int adv7170_write_block(struct i2c_client *client,
#define TR1PLAY 0x00
static const unsigned char init_NTSC[] = {
- 0x00, 0x10, // MR0
- 0x01, 0x20, // MR1
- 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
- 0x03, 0x80, // MR3
- 0x04, 0x30, // MR4
- 0x05, 0x00, // Reserved
- 0x06, 0x00, // Reserved
- 0x07, TR0MODE, // TM0
- 0x08, TR1CAPT, // TM1
- 0x09, 0x16, // Fsc0
- 0x0a, 0x7c, // Fsc1
- 0x0b, 0xf0, // Fsc2
- 0x0c, 0x21, // Fsc3
- 0x0d, 0x00, // Subcarrier Phase
- 0x0e, 0x00, // Closed Capt. Ext 0
- 0x0f, 0x00, // Closed Capt. Ext 1
- 0x10, 0x00, // Closed Capt. 0
- 0x11, 0x00, // Closed Capt. 1
- 0x12, 0x00, // Pedestal Ctl 0
- 0x13, 0x00, // Pedestal Ctl 1
- 0x14, 0x00, // Pedestal Ctl 2
- 0x15, 0x00, // Pedestal Ctl 3
- 0x16, 0x00, // CGMS_WSS_0
- 0x17, 0x00, // CGMS_WSS_1
- 0x18, 0x00, // CGMS_WSS_2
- 0x19, 0x00, // Teletext Ctl
+ 0x00, 0x10, /* MR0 */
+ 0x01, 0x20, /* MR1 */
+ 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */
+ 0x03, 0x80, /* MR3 */
+ 0x04, 0x30, /* MR4 */
+ 0x05, 0x00, /* Reserved */
+ 0x06, 0x00, /* Reserved */
+ 0x07, TR0MODE, /* TM0 */
+ 0x08, TR1CAPT, /* TM1 */
+ 0x09, 0x16, /* Fsc0 */
+ 0x0a, 0x7c, /* Fsc1 */
+ 0x0b, 0xf0, /* Fsc2 */
+ 0x0c, 0x21, /* Fsc3 */
+ 0x0d, 0x00, /* Subcarrier Phase */
+ 0x0e, 0x00, /* Closed Capt. Ext 0 */
+ 0x0f, 0x00, /* Closed Capt. Ext 1 */
+ 0x10, 0x00, /* Closed Capt. 0 */
+ 0x11, 0x00, /* Closed Capt. 1 */
+ 0x12, 0x00, /* Pedestal Ctl 0 */
+ 0x13, 0x00, /* Pedestal Ctl 1 */
+ 0x14, 0x00, /* Pedestal Ctl 2 */
+ 0x15, 0x00, /* Pedestal Ctl 3 */
+ 0x16, 0x00, /* CGMS_WSS_0 */
+ 0x17, 0x00, /* CGMS_WSS_1 */
+ 0x18, 0x00, /* CGMS_WSS_2 */
+ 0x19, 0x00, /* Teletext Ctl */
};
static const unsigned char init_PAL[] = {
- 0x00, 0x71, // MR0
- 0x01, 0x20, // MR1
- 0x02, 0x0e, // MR2 RTC control: bits 2 and 1
- 0x03, 0x80, // MR3
- 0x04, 0x30, // MR4
- 0x05, 0x00, // Reserved
- 0x06, 0x00, // Reserved
- 0x07, TR0MODE, // TM0
- 0x08, TR1CAPT, // TM1
- 0x09, 0xcb, // Fsc0
- 0x0a, 0x8a, // Fsc1
- 0x0b, 0x09, // Fsc2
- 0x0c, 0x2a, // Fsc3
- 0x0d, 0x00, // Subcarrier Phase
- 0x0e, 0x00, // Closed Capt. Ext 0
- 0x0f, 0x00, // Closed Capt. Ext 1
- 0x10, 0x00, // Closed Capt. 0
- 0x11, 0x00, // Closed Capt. 1
- 0x12, 0x00, // Pedestal Ctl 0
- 0x13, 0x00, // Pedestal Ctl 1
- 0x14, 0x00, // Pedestal Ctl 2
- 0x15, 0x00, // Pedestal Ctl 3
- 0x16, 0x00, // CGMS_WSS_0
- 0x17, 0x00, // CGMS_WSS_1
- 0x18, 0x00, // CGMS_WSS_2
- 0x19, 0x00, // Teletext Ctl
+ 0x00, 0x71, /* MR0 */
+ 0x01, 0x20, /* MR1 */
+ 0x02, 0x0e, /* MR2 RTC control: bits 2 and 1 */
+ 0x03, 0x80, /* MR3 */
+ 0x04, 0x30, /* MR4 */
+ 0x05, 0x00, /* Reserved */
+ 0x06, 0x00, /* Reserved */
+ 0x07, TR0MODE, /* TM0 */
+ 0x08, TR1CAPT, /* TM1 */
+ 0x09, 0xcb, /* Fsc0 */
+ 0x0a, 0x8a, /* Fsc1 */
+ 0x0b, 0x09, /* Fsc2 */
+ 0x0c, 0x2a, /* Fsc3 */
+ 0x0d, 0x00, /* Subcarrier Phase */
+ 0x0e, 0x00, /* Closed Capt. Ext 0 */
+ 0x0f, 0x00, /* Closed Capt. Ext 1 */
+ 0x10, 0x00, /* Closed Capt. 0 */
+ 0x11, 0x00, /* Closed Capt. 1 */
+ 0x12, 0x00, /* Pedestal Ctl 0 */
+ 0x13, 0x00, /* Pedestal Ctl 1 */
+ 0x14, 0x00, /* Pedestal Ctl 2 */
+ 0x15, 0x00, /* Pedestal Ctl 3 */
+ 0x16, 0x00, /* CGMS_WSS_0 */
+ 0x17, 0x00, /* CGMS_WSS_1 */
+ 0x18, 0x00, /* CGMS_WSS_2 */
+ 0x19, 0x00, /* Teletext Ctl */
};
-static int adv7170_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int adv7170_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
{
- struct adv7170 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
-#if 0
- /* This is just for testing!!! */
- adv7170_write_block(client, init_common,
- sizeof(init_common));
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
-#endif
- break;
-
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
-
- cap->flags = VIDEO_ENCODER_PAL |
- VIDEO_ENCODER_NTSC;
- cap->inputs = 2;
- cap->outputs = 1;
- break;
+ struct adv7170 *encoder = to_adv7170(sd);
+
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
+
+ if (std & V4L2_STD_NTSC) {
+ adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
+ if (encoder->input == 0)
+ adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ } else if (std & V4L2_STD_PAL) {
+ adv7170_write_block(sd, init_PAL, sizeof(init_PAL));
+ if (encoder->input == 0)
+ adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ } else {
+ v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
+ (unsigned long long)std);
+ return -EINVAL;
}
+ v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
+ encoder->norm = std;
+ return 0;
+}
- case ENCODER_SET_NORM:
- {
- int iarg = *(int *) arg;
-
- v4l_dbg(1, debug, client, "set norm %d\n", iarg);
-
- switch (iarg) {
- case VIDEO_MODE_NTSC:
- adv7170_write_block(client, init_NTSC,
- sizeof(init_NTSC));
- if (encoder->input == 0)
- adv7170_write(client, 0x02, 0x0e); // Enable genlock
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- break;
-
- case VIDEO_MODE_PAL:
- adv7170_write_block(client, init_PAL,
- sizeof(init_PAL));
- if (encoder->input == 0)
- adv7170_write(client, 0x02, 0x0e); // Enable genlock
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- break;
-
- default:
- v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
- encoder->norm = iarg;
- break;
- }
+static int adv7170_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct adv7170 *encoder = to_adv7170(sd);
- case ENCODER_SET_INPUT:
- {
- int iarg = *(int *) arg;
-
- /* RJ: *iarg = 0: input is from decoder
- *iarg = 1: input is from ZR36060
- *iarg = 2: color bar */
-
- v4l_dbg(1, debug, client, "set input from %s\n",
- iarg == 0 ? "decoder" : "ZR36060");
-
- switch (iarg) {
- case 0:
- adv7170_write(client, 0x01, 0x20);
- adv7170_write(client, 0x08, TR1CAPT); /* TR1 */
- adv7170_write(client, 0x02, 0x0e); // Enable genlock
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- case 1:
- adv7170_write(client, 0x01, 0x00);
- adv7170_write(client, 0x08, TR1PLAY); /* TR1 */
- adv7170_write(client, 0x02, 0x08);
- adv7170_write(client, 0x07, TR0MODE | TR0RST);
- adv7170_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- default:
- v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
- encoder->input = iarg;
- break;
- }
+ /* RJ: route->input = 0: input is from decoder
+ route->input = 1: input is from ZR36060
+ route->input = 2: color bar */
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ v4l2_dbg(1, debug, sd, "set input from %s\n",
+ route->input == 0 ? "decoder" : "ZR36060");
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
+ switch (route->input) {
+ case 0:
+ adv7170_write(sd, 0x01, 0x20);
+ adv7170_write(sd, 0x08, TR1CAPT); /* TR1 */
+ adv7170_write(sd, 0x02, 0x0e); /* Enable genlock */
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- encoder->enable = !!*iarg;
+ case 1:
+ adv7170_write(sd, 0x01, 0x00);
+ adv7170_write(sd, 0x08, TR1PLAY); /* TR1 */
+ adv7170_write(sd, 0x02, 0x08);
+ adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7170_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
default:
+ v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
return -EINVAL;
}
-
+ v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
+ encoder->input = route->input;
return 0;
}
+static int adv7170_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7170, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = {
- 0xd4 >> 1, 0xd6 >> 1, /* adv7170 IDs */
- 0x54 >> 1, 0x56 >> 1, /* adv7171 IDs */
- I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops adv7170_core_ops = {
+ .g_chip_ident = adv7170_g_chip_ident,
};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops adv7170_video_ops = {
+ .s_std_output = adv7170_s_std_output,
+ .s_routing = adv7170_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7170_ops = {
+ .core = &adv7170_core_ops,
+ .video = &adv7170_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int adv7170_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct adv7170 *encoder;
+ struct v4l2_subdev *sd;
int i;
/* Check if the adapter supports the needed features */
@@ -337,26 +300,29 @@ static int adv7170_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct adv7170), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_NTSC;
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &adv7170_ops);
+ encoder->norm = V4L2_STD_NTSC;
encoder->input = 0;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
- i = adv7170_write_block(client, init_NTSC, sizeof(init_NTSC));
+ i = adv7170_write_block(sd, init_NTSC, sizeof(init_NTSC));
if (i >= 0) {
- i = adv7170_write(client, 0x07, TR0MODE | TR0RST);
- i = adv7170_write(client, 0x07, TR0MODE);
- i = adv7170_read(client, 0x12);
- v4l_dbg(1, debug, client, "revision %d\n", i & 1);
+ i = adv7170_write(sd, 0x07, TR0MODE | TR0RST);
+ i = adv7170_write(sd, 0x07, TR0MODE);
+ i = adv7170_read(sd, 0x12);
+ v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
}
if (i < 0)
- v4l_dbg(1, debug, client, "init error 0x%x\n", i);
+ v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
return 0;
}
static int adv7170_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_adv7170(sd));
return 0;
}
@@ -371,8 +337,6 @@ MODULE_DEVICE_TABLE(i2c, adv7170_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "adv7170",
- .driverid = I2C_DRIVERID_ADV7170,
- .command = adv7170_command,
.probe = adv7170_probe,
.remove = adv7170_remove,
.id_table = adv7170_id,
diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c
index 6008e84653f..ff121030329 100644
--- a/drivers/media/video/adv7175.c
+++ b/drivers/media/video/adv7175.c
@@ -30,15 +30,19 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Analog Devices ADV7175 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
+#define I2C_ADV7175 0xd4
+#define I2C_ADV7176 0x54
+
+
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -46,36 +50,38 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
/* ----------------------------------------------------------------------- */
struct adv7175 {
- int norm;
+ struct v4l2_subdev sd;
+ v4l2_std_id norm;
int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
-#define I2C_ADV7175 0xd4
-#define I2C_ADV7176 0x54
+static inline struct adv7175 *to_adv7175(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct adv7175, sd);
+}
static char *inputs[] = { "pass_through", "play_back", "color_bar" };
-static char *norms[] = { "PAL", "NTSC", "SECAM->PAL (may not work!)" };
/* ----------------------------------------------------------------------- */
-static inline int adv7175_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int adv7175_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int adv7175_read(struct i2c_client *client, u8 reg)
+static inline int adv7175_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int adv7175_write_block(struct i2c_client *client,
+static int adv7175_write_block(struct v4l2_subdev *sd,
const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret = -1;
u8 reg;
@@ -103,7 +109,7 @@ static int adv7175_write_block(struct i2c_client *client,
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- ret = adv7175_write(client, reg, *data++);
+ ret = adv7175_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -113,18 +119,18 @@ static int adv7175_write_block(struct i2c_client *client,
return ret;
}
-static void set_subcarrier_freq(struct i2c_client *client, int pass_through)
+static void set_subcarrier_freq(struct v4l2_subdev *sd, int pass_through)
{
/* for some reason pass_through NTSC needs
* a different sub-carrier freq to remain stable. */
if (pass_through)
- adv7175_write(client, 0x02, 0x00);
+ adv7175_write(sd, 0x02, 0x00);
else
- adv7175_write(client, 0x02, 0x55);
+ adv7175_write(sd, 0x02, 0x55);
- adv7175_write(client, 0x03, 0x55);
- adv7175_write(client, 0x04, 0x55);
- adv7175_write(client, 0x05, 0x25);
+ adv7175_write(sd, 0x03, 0x55);
+ adv7175_write(sd, 0x04, 0x55);
+ adv7175_write(sd, 0x05, 0x25);
}
/* ----------------------------------------------------------------------- */
@@ -184,180 +190,144 @@ static const unsigned char init_ntsc[] = {
0x06, 0x1a, /* subc. phase */
};
-static int adv7175_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int adv7175_init(struct v4l2_subdev *sd, u32 val)
{
- struct adv7175 *encoder = i2c_get_clientdata(client);
+ /* This is just for testing!!! */
+ adv7175_write_block(sd, init_common, sizeof(init_common));
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ return 0;
+}
- switch (cmd) {
- case 0:
- /* This is just for testing!!! */
- adv7175_write_block(client, init_common,
- sizeof(init_common));
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
+static int adv7175_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct adv7175 *encoder = to_adv7175(sd);
+
+ if (std & V4L2_STD_NTSC) {
+ adv7175_write_block(sd, init_ntsc, sizeof(init_ntsc));
+ if (encoder->input == 0)
+ adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ } else if (std & V4L2_STD_PAL) {
+ adv7175_write_block(sd, init_pal, sizeof(init_pal));
+ if (encoder->input == 0)
+ adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ } else if (std & V4L2_STD_SECAM) {
+ /* This is an attempt to convert
+ * SECAM->PAL (typically it does not work
+ * due to genlock: when decoder is in SECAM
+ * and encoder in in PAL the subcarrier can
+ * not be syncronized with horizontal
+ * quency) */
+ adv7175_write_block(sd, init_pal, sizeof(init_pal));
+ if (encoder->input == 0)
+ adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ } else {
+ v4l2_dbg(1, debug, sd, "illegal norm: %llx\n",
+ (unsigned long long)std);
+ return -EINVAL;
+ }
+ v4l2_dbg(1, debug, sd, "switched to %llx\n", (unsigned long long)std);
+ encoder->norm = std;
+ return 0;
+}
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
+static int adv7175_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct adv7175 *encoder = to_adv7175(sd);
- cap->flags = VIDEO_ENCODER_PAL |
- VIDEO_ENCODER_NTSC |
- VIDEO_ENCODER_SECAM; /* well, hacky */
- cap->inputs = 2;
- cap->outputs = 1;
- break;
- }
+ /* RJ: route->input = 0: input is from decoder
+ route->input = 1: input is from ZR36060
+ route->input = 2: color bar */
- case ENCODER_SET_NORM:
- {
- int iarg = *(int *) arg;
-
- switch (iarg) {
- case VIDEO_MODE_NTSC:
- adv7175_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- if (encoder->input == 0)
- adv7175_write(client, 0x0d, 0x4f); // Enable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
-
- case VIDEO_MODE_PAL:
- adv7175_write_block(client, init_pal,
- sizeof(init_pal));
- if (encoder->input == 0)
- adv7175_write(client, 0x0d, 0x4f); // Enable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
-
- case VIDEO_MODE_SECAM: // WARNING! ADV7176 does not support SECAM.
- /* This is an attempt to convert
- * SECAM->PAL (typically it does not work
- * due to genlock: when decoder is in SECAM
- * and encoder in in PAL the subcarrier can
- * not be syncronized with horizontal
- * quency) */
- adv7175_write_block(client, init_pal,
- sizeof(init_pal));
- if (encoder->input == 0)
- adv7175_write(client, 0x0d, 0x49); // Disable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- break;
- default:
- v4l_dbg(1, debug, client, "illegal norm: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", norms[iarg]);
- encoder->norm = iarg;
+ switch (route->input) {
+ case 0:
+ adv7175_write(sd, 0x01, 0x00);
+
+ if (encoder->norm & V4L2_STD_NTSC)
+ set_subcarrier_freq(sd, 1);
+
+ adv7175_write(sd, 0x0c, TR1CAPT); /* TR1 */
+ if (encoder->norm & V4L2_STD_SECAM)
+ adv7175_write(sd, 0x0d, 0x49); /* Disable genlock */
+ else
+ adv7175_write(sd, 0x0d, 0x4f); /* Enable genlock */
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ /*udelay(10);*/
break;
- }
- case ENCODER_SET_INPUT:
- {
- int iarg = *(int *) arg;
-
- /* RJ: *iarg = 0: input is from SAA7110
- *iarg = 1: input is from ZR36060
- *iarg = 2: color bar */
-
- switch (iarg) {
- case 0:
- adv7175_write(client, 0x01, 0x00);
-
- if (encoder->norm == VIDEO_MODE_NTSC)
- set_subcarrier_freq(client, 1);
-
- adv7175_write(client, 0x0c, TR1CAPT); /* TR1 */
- if (encoder->norm == VIDEO_MODE_SECAM)
- adv7175_write(client, 0x0d, 0x49); // Disable genlock
- else
- adv7175_write(client, 0x0d, 0x4f); // Enable genlock
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- //udelay(10);
- break;
-
- case 1:
- adv7175_write(client, 0x01, 0x00);
-
- if (encoder->norm == VIDEO_MODE_NTSC)
- set_subcarrier_freq(client, 0);
-
- adv7175_write(client, 0x0c, TR1PLAY); /* TR1 */
- adv7175_write(client, 0x0d, 0x49);
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- case 2:
- adv7175_write(client, 0x01, 0x80);
-
- if (encoder->norm == VIDEO_MODE_NTSC)
- set_subcarrier_freq(client, 0);
-
- adv7175_write(client, 0x0d, 0x49);
- adv7175_write(client, 0x07, TR0MODE | TR0RST);
- adv7175_write(client, 0x07, TR0MODE);
- /* udelay(10); */
- break;
-
- default:
- v4l_dbg(1, debug, client, "illegal input: %d\n", iarg);
- return -EINVAL;
- }
- v4l_dbg(1, debug, client, "switched to %s\n", inputs[iarg]);
- encoder->input = iarg;
- break;
- }
+ case 1:
+ adv7175_write(sd, 0x01, 0x00);
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ if (encoder->norm & V4L2_STD_NTSC)
+ set_subcarrier_freq(sd, 0);
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ adv7175_write(sd, 0x0c, TR1PLAY); /* TR1 */
+ adv7175_write(sd, 0x0d, 0x49);
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
+ case 2:
+ adv7175_write(sd, 0x01, 0x80);
+
+ if (encoder->norm & V4L2_STD_NTSC)
+ set_subcarrier_freq(sd, 0);
- encoder->enable = !!*iarg;
+ adv7175_write(sd, 0x0d, 0x49);
+ adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ adv7175_write(sd, 0x07, TR0MODE);
+ /* udelay(10); */
break;
- }
default:
+ v4l2_dbg(1, debug, sd, "illegal input: %d\n", route->input);
return -EINVAL;
}
-
+ v4l2_dbg(1, debug, sd, "switched to %s\n", inputs[route->input]);
+ encoder->input = route->input;
return 0;
}
+static int adv7175_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7175, 0);
+}
+
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
-static unsigned short normal_i2c[] = {
- I2C_ADV7175 >> 1, (I2C_ADV7175 >> 1) + 1,
- I2C_ADV7176 >> 1, (I2C_ADV7176 >> 1) + 1,
- I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops adv7175_core_ops = {
+ .g_chip_ident = adv7175_g_chip_ident,
+ .init = adv7175_init,
};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops adv7175_video_ops = {
+ .s_std_output = adv7175_s_std_output,
+ .s_routing = adv7175_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7175_ops = {
+ .core = &adv7175_core_ops,
+ .video = &adv7175_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int adv7175_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i;
struct adv7175 *encoder;
+ struct v4l2_subdev *sd;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -369,26 +339,29 @@ static int adv7175_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct adv7175), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_PAL;
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &adv7175_ops);
+ encoder->norm = V4L2_STD_NTSC;
encoder->input = 0;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
- i = adv7175_write_block(client, init_common, sizeof(init_common));
+ i = adv7175_write_block(sd, init_common, sizeof(init_common));
if (i >= 0) {
- i = adv7175_write(client, 0x07, TR0MODE | TR0RST);
- i = adv7175_write(client, 0x07, TR0MODE);
- i = adv7175_read(client, 0x12);
- v4l_dbg(1, debug, client, "revision %d\n", i & 1);
+ i = adv7175_write(sd, 0x07, TR0MODE | TR0RST);
+ i = adv7175_write(sd, 0x07, TR0MODE);
+ i = adv7175_read(sd, 0x12);
+ v4l2_dbg(1, debug, sd, "revision %d\n", i & 1);
}
if (i < 0)
- v4l_dbg(1, debug, client, "init error 0x%x\n", i);
+ v4l2_dbg(1, debug, sd, "init error 0x%x\n", i);
return 0;
}
static int adv7175_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_adv7175(sd));
return 0;
}
@@ -403,8 +376,6 @@ MODULE_DEVICE_TABLE(i2c, adv7175_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "adv7175",
- .driverid = I2C_DRIVERID_ADV7175,
- .command = adv7175_command,
.probe = adv7175_probe,
.remove = adv7175_remove,
.id_table = adv7175_id,
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig
index 018f72b8e3e..05cdf494dfb 100644
--- a/drivers/media/video/au0828/Kconfig
+++ b/drivers/media/video/au0828/Kconfig
@@ -1,13 +1,13 @@
config VIDEO_AU0828
tristate "Auvitek AU0828 support"
- depends on I2C && INPUT && DVB_CORE && USB
+ depends on I2C && INPUT && DVB_CORE && USB && VIDEO_V4L2
select I2C_ALGOBIT
select VIDEO_TVEEPROM
- select DVB_AU8522 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_MXL5007T if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
+ select DVB_AU8522 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
---help---
This is a video4linux driver for Auvitek's USB device.
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
index cd2c58281b4..4d262315818 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/video/au0828/Makefile
@@ -1,4 +1,4 @@
-au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o
+au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o
obj-$(CONFIG_VIDEO_AU0828) += au0828.o
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index d60123b413f..1aabaa7e55b 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -21,25 +21,89 @@
#include "au0828.h"
#include "au0828-cards.h"
+#include "au8522.h"
+#include "media/tuner.h"
+#include "media/v4l2-common.h"
+
+void hvr950q_cs5340_audio(void *priv, int enable)
+{
+ /* Because the HVR-950q shares an i2s bus between the cs5340 and the
+ au8522, we need to hold cs5340 in reset when using the au8522 */
+ struct au0828_dev *dev = priv;
+ if (enable == 1)
+ au0828_set(dev, REG_000, 0x10);
+ else
+ au0828_clear(dev, REG_000, 0x10);
+}
struct au0828_board au0828_boards[] = {
[AU0828_BOARD_UNKNOWN] = {
.name = "Unknown board",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_HAUPPAUGE_HVR850] = {
.name = "Hauppauge HVR850",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
+ .input = {
+ {
+ .type = AU0828_VMUX_TELEVISION,
+ .vmux = AU8522_COMPOSITE_CH4_SIF,
+ .amux = AU8522_AUDIO_SIF,
+ },
+ {
+ .type = AU0828_VMUX_COMPOSITE,
+ .vmux = AU8522_COMPOSITE_CH1,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ {
+ .type = AU0828_VMUX_SVIDEO,
+ .vmux = AU8522_SVIDEO_CH13,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ },
},
[AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
.name = "Hauppauge HVR950Q",
+ .tuner_type = TUNER_XC5000,
+ .tuner_addr = 0x61,
+ .input = {
+ {
+ .type = AU0828_VMUX_TELEVISION,
+ .vmux = AU8522_COMPOSITE_CH4_SIF,
+ .amux = AU8522_AUDIO_SIF,
+ },
+ {
+ .type = AU0828_VMUX_COMPOSITE,
+ .vmux = AU8522_COMPOSITE_CH1,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ {
+ .type = AU0828_VMUX_SVIDEO,
+ .vmux = AU8522_SVIDEO_CH13,
+ .amux = AU8522_AUDIO_NONE,
+ .audio_setup = hvr950q_cs5340_audio,
+ },
+ },
},
[AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
.name = "Hauppauge HVR950Q rev xxF8",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_DVICO_FUSIONHDTV7] = {
.name = "DViCO FusionHDTV USB",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
[AU0828_BOARD_HAUPPAUGE_WOODBURY] = {
.name = "Hauppauge Woodbury",
+ .tuner_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
},
};
@@ -52,7 +116,7 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg)
dprintk(1, "%s()\n", __func__);
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -81,17 +145,18 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
struct tveeprom tv;
tveeprom_hauppauge_analog(&dev->i2c_client, &tv, eeprom_data);
+ dev->board.tuner_type = tv.tuner_type;
/* Make sure we support the board model */
switch (tv.model) {
case 72000: /* WinTV-HVR950q (Retail, IR, ATSC/QAM */
- case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
- case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
- case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
- case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and basic analog video */
- case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and basic analog video */
- case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and basic analog video */
- case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and basic analog video */
+ case 72001: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
+ case 72211: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+ case 72221: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+ case 72231: /* WinTV-HVR950q (OEM, IR, ATSC/QAM and analog video */
+ case 72241: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM and analog video */
+ case 72251: /* WinTV-HVR950q (Retail, IR, ATSC/QAM and analog video */
+ case 72301: /* WinTV-HVR850 (Retail, IR, ATSC and analog video */
case 72500: /* WinTV-HVR950q (OEM, No IR, ATSC/QAM */
break;
default:
@@ -107,15 +172,21 @@ static void hauppauge_eeprom(struct au0828_dev *dev, u8 *eeprom_data)
void au0828_card_setup(struct au0828_dev *dev)
{
static u8 eeprom[256];
+ struct tuner_setup tun_setup;
+ struct v4l2_subdev *sd;
+ unsigned int mode_mask = T_ANALOG_TV |
+ T_DIGITAL_TV;
dprintk(1, "%s()\n", __func__);
+ memcpy(&dev->board, &au0828_boards[dev->boardnr], sizeof(dev->board));
+
if (dev->i2c_rc == 0) {
dev->i2c_client.addr = 0xa0 >> 1;
tveeprom_read(&dev->i2c_client, eeprom, sizeof(eeprom));
}
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -124,6 +195,32 @@ void au0828_card_setup(struct au0828_dev *dev)
hauppauge_eeprom(dev, eeprom+0xa0);
break;
}
+
+ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED) {
+ /* Load the analog demodulator driver (note this would need to
+ be abstracted out if we ever need to support a different
+ demod) */
+ sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "au8522", "au8522",
+ 0x8e >> 1);
+ if (sd == NULL)
+ printk(KERN_ERR "analog subdev registration failed\n");
+ }
+
+ /* Setup tuners */
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ /* Load the tuner module, which does the attach */
+ sd = v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner", "tuner",
+ dev->board.tuner_addr);
+ if (sd == NULL)
+ printk(KERN_ERR "tuner subdev registration fail\n");
+
+ tun_setup.mode_mask = mode_mask;
+ tun_setup.type = dev->board.tuner_type;
+ tun_setup.addr = dev->board.tuner_addr;
+ tun_setup.tuner_callback = au0828_tuner_callback;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr,
+ &tun_setup);
+ }
}
/*
@@ -135,7 +232,7 @@ void au0828_gpio_setup(struct au0828_dev *dev)
{
dprintk(1, "%s()\n", __func__);
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
case AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL:
@@ -144,21 +241,23 @@ void au0828_gpio_setup(struct au0828_dev *dev)
* 4 - CS5340
* 5 - AU8522 Demodulator
* 6 - eeprom W/P
+ * 7 - power supply
* 9 - XC5000 Tuner
*/
/* Into reset */
au0828_write(dev, REG_003, 0x02);
- au0828_write(dev, REG_002, 0x88 | 0x20);
+ au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
au0828_write(dev, REG_001, 0x0);
au0828_write(dev, REG_000, 0x0);
msleep(100);
- /* Out of reset */
+ /* Out of reset (leave the cs5340 in reset until needed) */
au0828_write(dev, REG_003, 0x02);
au0828_write(dev, REG_001, 0x02);
- au0828_write(dev, REG_002, 0x88 | 0x20);
- au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40);
+ au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
+ au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20);
+
msleep(250);
break;
case AU0828_BOARD_DVICO_FUSIONHDTV7:
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 5765e865637..8c761d16444 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -36,6 +36,8 @@ int au0828_debug;
module_param_named(debug, au0828_debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");
+static atomic_t au0828_instance = ATOMIC_INIT(0);
+
#define _AU0828_BULKPIPE 0x03
#define _BULKPIPESIZE 0xffff
@@ -51,13 +53,13 @@ static int recv_control_msg(struct au0828_dev *dev, u16 request, u32 value,
u32 au0828_readreg(struct au0828_dev *dev, u16 reg)
{
recv_control_msg(dev, CMD_REQUEST_IN, 0, reg, dev->ctrlmsg, 1);
- dprintk(8, "%s(0x%x) = 0x%x\n", __func__, reg, dev->ctrlmsg[0]);
+ dprintk(8, "%s(0x%04x) = 0x%02x\n", __func__, reg, dev->ctrlmsg[0]);
return dev->ctrlmsg[0];
}
u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
{
- dprintk(8, "%s(0x%x, 0x%x)\n", __func__, reg, val);
+ dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
return send_control_msg(dev, CMD_REQUEST_OUT, val, reg,
dev->ctrlmsg, 0);
}
@@ -146,9 +148,14 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
/* Digital TV */
au0828_dvb_unregister(dev);
+ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
+ au0828_analog_unregister(dev);
+
/* I2C */
au0828_i2c_unregister(dev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+
usb_set_intfdata(interface, NULL);
mutex_lock(&dev->mutex);
@@ -162,7 +169,7 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
static int au0828_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
- int ifnum;
+ int ifnum, retval, i;
struct au0828_dev *dev;
struct usb_device *usbdev = interface_to_usbdev(interface);
@@ -185,10 +192,22 @@ static int au0828_usb_probe(struct usb_interface *interface,
mutex_init(&dev->mutex);
mutex_init(&dev->dvb.lock);
dev->usbdev = usbdev;
- dev->board = id->driver_info;
+ dev->boardnr = id->driver_info;
usb_set_intfdata(interface, dev);
+ /* Create the v4l2_device */
+ i = atomic_inc_return(&au0828_instance) - 1;
+ snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name), "%s-%03d",
+ "au0828", i);
+ retval = v4l2_device_register(&dev->usbdev->dev, &dev->v4l2_dev);
+ if (retval) {
+ printk(KERN_ERR "%s() v4l2_device_register failed\n",
+ __func__);
+ kfree(dev);
+ return -EIO;
+ }
+
/* Power Up the bridge */
au0828_write(dev, REG_600, 1 << 4);
@@ -201,12 +220,15 @@ static int au0828_usb_probe(struct usb_interface *interface,
/* Setup */
au0828_card_setup(dev);
+ /* Analog TV */
+ if (AUVI_INPUT(0).type != AU0828_VMUX_UNDEFINED)
+ au0828_analog_register(dev, interface);
+
/* Digital TV */
au0828_dvb_register(dev);
printk(KERN_INFO "Registered device AU0828 [%s]\n",
- au0828_boards[dev->board].name == NULL ? "Unset" :
- au0828_boards[dev->board].name);
+ dev->board.name == NULL ? "Unset" : dev->board.name);
return 0;
}
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index a882cf546d0..14baffc2219 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -378,7 +378,7 @@ int au0828_dvb_register(struct au0828_dev *dev)
dprintk(1, "%s()\n", __func__);
/* init frontend */
- switch (dev->board) {
+ switch (dev->boardnr) {
case AU0828_BOARD_HAUPPAUGE_HVR850:
case AU0828_BOARD_HAUPPAUGE_HVR950Q:
dvb->frontend = dvb_attach(au8522_attach,
diff --git a/drivers/media/video/au0828/au0828-i2c.c b/drivers/media/video/au0828/au0828-i2c.c
index d618fbaade1..f9a958d0aef 100644
--- a/drivers/media/video/au0828/au0828-i2c.c
+++ b/drivers/media/video/au0828/au0828-i2c.c
@@ -140,13 +140,39 @@ static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
dprintk(4, "%s()\n", __func__);
au0828_write(dev, REG_2FF, 0x01);
- au0828_write(dev, REG_202, 0x07);
+
+ /* FIXME: There is a problem with i2c communications with xc5000 that
+ requires us to slow down the i2c clock until we have a better
+ strategy (such as using the secondary i2c bus to do firmware
+ loading */
+ if ((msg->addr << 1) == 0xc2)
+ au0828_write(dev, REG_202, 0x40);
+ else
+ au0828_write(dev, REG_202, 0x07);
/* Hardware needs 8 bit addresses */
au0828_write(dev, REG_203, msg->addr << 1);
dprintk(4, "SEND: %02x\n", msg->addr);
+ /* Deal with i2c_scan */
+ if (msg->len == 0) {
+ /* The analog tuner detection code makes use of the SMBUS_QUICK
+ message (which involves a zero length i2c write). To avoid
+ checking the status register when we didn't strobe out any
+ actual bytes to the bus, just do a read check. This is
+ consistent with how I saw i2c device checking done in the
+ USB trace of the Windows driver */
+ au0828_write(dev, REG_200, 0x20);
+ if (!i2c_wait_done(i2c_adap))
+ return -EIO;
+
+ if (i2c_wait_read_ack(i2c_adap))
+ return -EIO;
+
+ return 0;
+ }
+
for (i = 0; i < msg->len;) {
dprintk(4, " %02x\n", msg->buf[i]);
@@ -191,7 +217,15 @@ static int i2c_readbytes(struct i2c_adapter *i2c_adap,
dprintk(4, "%s()\n", __func__);
au0828_write(dev, REG_2FF, 0x01);
- au0828_write(dev, REG_202, 0x07);
+
+ /* FIXME: There is a problem with i2c communications with xc5000 that
+ requires us to slow down the i2c clock until we have a better
+ strategy (such as using the secondary i2c bus to do firmware
+ loading */
+ if ((msg->addr << 1) == 0xc2)
+ au0828_write(dev, REG_202, 0x40);
+ else
+ au0828_write(dev, REG_202, 0x07);
/* Hardware needs 8 bit addresses */
au0828_write(dev, REG_203, msg->addr << 1);
@@ -265,33 +299,6 @@ err:
return retval;
}
-static int attach_inform(struct i2c_client *client)
-{
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- if (!client->driver->command)
- return 0;
-
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- dprintk(1, "i2c detach [client=%s]\n", client->name);
-
- return 0;
-}
-
-void au0828_call_i2c_clients(struct au0828_dev *dev,
- unsigned int cmd, void *arg)
-{
- if (dev->i2c_rc != 0)
- return;
-
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
static u32 au0828_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -309,9 +316,6 @@ static struct i2c_adapter au0828_i2c_adap_template = {
.owner = THIS_MODULE,
.id = I2C_HW_B_AU0828,
.algo = &au0828_i2c_algo_template,
- .class = I2C_CLASS_TV_ANALOG,
- .client_register = attach_inform,
- .client_unregister = detach_inform,
};
static struct i2c_client au0828_i2c_client_template = {
@@ -356,9 +360,9 @@ int au0828_i2c_register(struct au0828_dev *dev)
strlcpy(dev->i2c_adap.name, DRIVER_NAME,
sizeof(dev->i2c_adap.name));
- dev->i2c_algo.data = dev;
+ dev->i2c_adap.algo = &dev->i2c_algo;
dev->i2c_adap.algo_data = dev;
- i2c_set_adapdata(&dev->i2c_adap, dev);
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&dev->i2c_adap);
dev->i2c_client.adapter = &dev->i2c_adap;
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h
index 1e87fa0c684..b15e4a3b6fc 100644
--- a/drivers/media/video/au0828/au0828-reg.h
+++ b/drivers/media/video/au0828/au0828-reg.h
@@ -27,6 +27,9 @@
#define REG_002 0x002
#define REG_003 0x003
+#define AU0828_SENSORCTRL_100 0x100
+#define AU0828_SENSORCTRL_VBI_103 0x103
+
#define REG_200 0x200
#define REG_201 0x201
#define REG_202 0x202
@@ -35,4 +38,7 @@
#define REG_209 0x209
#define REG_2FF 0x2ff
+/* Audio registers */
+#define AU0828_AUDIOCTRL_50C 0x50C
+
#define REG_600 0x600
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
new file mode 100644
index 00000000000..f7ad4958b94
--- /dev/null
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -0,0 +1,1712 @@
+/*
+ * Auvitek AU0828 USB Bridge (Analog video support)
+ *
+ * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
+ * Copyright (C) 2005-2008 Auvitek International, 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 program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You 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.
+ */
+
+/* Developer Notes:
+ *
+ * VBI support is not yet working
+ * The hardware scaler supported is unimplemented
+ * AC97 audio support is unimplemented (only i2s audio mode)
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <linux/version.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/tuner.h>
+#include "au0828.h"
+#include "au0828-reg.h"
+
+static LIST_HEAD(au0828_devlist);
+static DEFINE_MUTEX(au0828_sysfs_lock);
+
+#define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1)
+
+/* ------------------------------------------------------------------
+ Videobuf operations
+ ------------------------------------------------------------------*/
+
+static unsigned int isoc_debug;
+module_param(isoc_debug, int, 0644);
+MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
+
+#define au0828_isocdbg(fmt, arg...) \
+do {\
+ if (isoc_debug) { \
+ printk(KERN_INFO "au0828 %s :"fmt, \
+ __func__ , ##arg); \
+ } \
+ } while (0)
+
+static inline void print_err_status(struct au0828_dev *dev,
+ int packet, int status)
+{
+ char *errmsg = "Unknown";
+
+ switch (status) {
+ case -ENOENT:
+ errmsg = "unlinked synchronuously";
+ break;
+ case -ECONNRESET:
+ errmsg = "unlinked asynchronuously";
+ break;
+ case -ENOSR:
+ errmsg = "Buffer error (overrun)";
+ break;
+ case -EPIPE:
+ errmsg = "Stalled (device not responding)";
+ break;
+ case -EOVERFLOW:
+ errmsg = "Babble (bad cable?)";
+ break;
+ case -EPROTO:
+ errmsg = "Bit-stuff error (bad cable?)";
+ break;
+ case -EILSEQ:
+ errmsg = "CRC/Timeout (could be anything)";
+ break;
+ case -ETIME:
+ errmsg = "Device does not respond";
+ break;
+ }
+ if (packet < 0) {
+ au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
+ } else {
+ au0828_isocdbg("URB packet %d, status %d [%s].\n",
+ packet, status, errmsg);
+ }
+}
+
+static int check_dev(struct au0828_dev *dev)
+{
+ if (dev->dev_state & DEV_DISCONNECTED) {
+ printk(KERN_INFO "v4l2 ioctl: device not present\n");
+ return -ENODEV;
+ }
+
+ if (dev->dev_state & DEV_MISCONFIGURED) {
+ printk(KERN_INFO "v4l2 ioctl: device is misconfigured; "
+ "close and open it again\n");
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * IRQ callback, called by URB callback
+ */
+static void au0828_irq_callback(struct urb *urb)
+{
+ struct au0828_dmaqueue *dma_q = urb->context;
+ struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+ int rc, i;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ au0828_isocdbg("au0828_irq_callback called: status kill\n");
+ return;
+ default: /* unknown error */
+ au0828_isocdbg("urb completition error %d.\n", urb->status);
+ break;
+ }
+
+ /* Copy data from URB */
+ spin_lock(&dev->slock);
+ rc = dev->isoc_ctl.isoc_copy(dev, urb);
+ spin_unlock(&dev->slock);
+
+ /* Reset urb buffers */
+ for (i = 0; i < urb->number_of_packets; i++) {
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+ urb->status = 0;
+
+ urb->status = usb_submit_urb(urb, GFP_ATOMIC);
+ if (urb->status) {
+ au0828_isocdbg("urb resubmit failed (error=%i)\n",
+ urb->status);
+ }
+}
+
+/*
+ * Stop and Deallocate URBs
+ */
+void au0828_uninit_isoc(struct au0828_dev *dev)
+{
+ struct urb *urb;
+ int i;
+
+ au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
+
+ dev->isoc_ctl.nfields = -1;
+ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+ urb = dev->isoc_ctl.urb[i];
+ if (urb) {
+ if (!irqs_disabled())
+ usb_kill_urb(urb);
+ else
+ usb_unlink_urb(urb);
+
+ if (dev->isoc_ctl.transfer_buffer[i]) {
+ usb_buffer_free(dev->usbdev,
+ urb->transfer_buffer_length,
+ dev->isoc_ctl.transfer_buffer[i],
+ urb->transfer_dma);
+ }
+ usb_free_urb(urb);
+ dev->isoc_ctl.urb[i] = NULL;
+ }
+ dev->isoc_ctl.transfer_buffer[i] = NULL;
+ }
+
+ kfree(dev->isoc_ctl.urb);
+ kfree(dev->isoc_ctl.transfer_buffer);
+
+ dev->isoc_ctl.urb = NULL;
+ dev->isoc_ctl.transfer_buffer = NULL;
+ dev->isoc_ctl.num_bufs = 0;
+}
+
+/*
+ * Allocate URBs and start IRQ
+ */
+int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
+ int num_bufs, int max_pkt_size,
+ int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
+{
+ struct au0828_dmaqueue *dma_q = &dev->vidq;
+ int i;
+ int sb_size, pipe;
+ struct urb *urb;
+ int j, k;
+ int rc;
+
+ au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
+
+ /* De-allocates all pending stuff */
+ au0828_uninit_isoc(dev);
+
+ dev->isoc_ctl.isoc_copy = isoc_copy;
+ dev->isoc_ctl.num_bufs = num_bufs;
+
+ dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
+ if (!dev->isoc_ctl.urb) {
+ au0828_isocdbg("cannot alloc memory for usb buffers\n");
+ return -ENOMEM;
+ }
+
+ dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
+ GFP_KERNEL);
+ if (!dev->isoc_ctl.transfer_buffer) {
+ au0828_isocdbg("cannot allocate memory for usb transfer\n");
+ kfree(dev->isoc_ctl.urb);
+ return -ENOMEM;
+ }
+
+ dev->isoc_ctl.max_pkt_size = max_pkt_size;
+ dev->isoc_ctl.buf = NULL;
+
+ sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
+
+ /* allocate urbs and transfer buffers */
+ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+ urb = usb_alloc_urb(max_packets, GFP_KERNEL);
+ if (!urb) {
+ au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i);
+ au0828_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ dev->isoc_ctl.urb[i] = urb;
+
+ dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev,
+ sb_size, GFP_KERNEL, &urb->transfer_dma);
+ if (!dev->isoc_ctl.transfer_buffer[i]) {
+ printk("unable to allocate %i bytes for transfer"
+ " buffer %i%s\n",
+ sb_size, i,
+ in_interrupt() ? " while in int" : "");
+ au0828_uninit_isoc(dev);
+ return -ENOMEM;
+ }
+ memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
+
+ pipe = usb_rcvisocpipe(dev->usbdev,
+ dev->isoc_in_endpointaddr),
+
+ usb_fill_int_urb(urb, dev->usbdev, pipe,
+ dev->isoc_ctl.transfer_buffer[i], sb_size,
+ au0828_irq_callback, dma_q, 1);
+
+ urb->number_of_packets = max_packets;
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+
+ k = 0;
+ for (j = 0; j < max_packets; j++) {
+ urb->iso_frame_desc[j].offset = k;
+ urb->iso_frame_desc[j].length =
+ dev->isoc_ctl.max_pkt_size;
+ k += dev->isoc_ctl.max_pkt_size;
+ }
+ }
+
+ init_waitqueue_head(&dma_q->wq);
+
+ /* submit urbs and enables IRQ */
+ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
+ rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
+ if (rc) {
+ au0828_isocdbg("submit of urb %i failed (error=%i)\n",
+ i, rc);
+ au0828_uninit_isoc(dev);
+ return rc;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Announces that a buffer were filled and request the next
+ */
+static inline void buffer_filled(struct au0828_dev *dev,
+ struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer *buf)
+{
+ /* Advice that buffer was filled */
+ au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
+
+ buf->vb.state = VIDEOBUF_DONE;
+ buf->vb.field_count++;
+ do_gettimeofday(&buf->vb.ts);
+
+ dev->isoc_ctl.buf = NULL;
+
+ list_del(&buf->vb.queue);
+ wake_up(&buf->vb.done);
+}
+
+/*
+ * Identify the buffer header type and properly handles
+ */
+static void au0828_copy_video(struct au0828_dev *dev,
+ struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer *buf,
+ unsigned char *p,
+ unsigned char *outp, unsigned long len)
+{
+ void *fieldstart, *startwrite, *startread;
+ int linesdone, currlinedone, offset, lencopy, remain;
+ int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
+
+ if (dma_q->pos + len > buf->vb.size)
+ len = buf->vb.size - dma_q->pos;
+
+ startread = p;
+ remain = len;
+
+ /* Interlaces frame */
+ if (buf->top_field)
+ fieldstart = outp;
+ else
+ fieldstart = outp + bytesperline;
+
+ linesdone = dma_q->pos / bytesperline;
+ currlinedone = dma_q->pos % bytesperline;
+ offset = linesdone * bytesperline * 2 + currlinedone;
+ startwrite = fieldstart + offset;
+ lencopy = bytesperline - currlinedone;
+ lencopy = lencopy > remain ? remain : lencopy;
+
+ if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+ au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
+ ((char *)startwrite + lencopy) -
+ ((char *)outp + buf->vb.size));
+ remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ lencopy = remain;
+ }
+ if (lencopy <= 0)
+ return;
+ memcpy(startwrite, startread, lencopy);
+
+ remain -= lencopy;
+
+ while (remain > 0) {
+ startwrite += lencopy + bytesperline;
+ startread += lencopy;
+ if (bytesperline > remain)
+ lencopy = remain;
+ else
+ lencopy = bytesperline;
+
+ if ((char *)startwrite + lencopy > (char *)outp +
+ buf->vb.size) {
+ au0828_isocdbg("Overflow %zi bytes past buf end (2)\n",
+ ((char *)startwrite + lencopy) -
+ ((char *)outp + buf->vb.size));
+ lencopy = remain = (char *)outp + buf->vb.size -
+ (char *)startwrite;
+ }
+ if (lencopy <= 0)
+ break;
+
+ memcpy(startwrite, startread, lencopy);
+
+ remain -= lencopy;
+ }
+
+ if (offset > 1440) {
+ /* We have enough data to check for greenscreen */
+ if (outp[0] < 0x60 && outp[1440] < 0x60)
+ dev->greenscreen_detected = 1;
+ }
+
+ dma_q->pos += len;
+}
+
+/*
+ * video-buf generic routine to get the next available buffer
+ */
+static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
+ struct au0828_buffer **buf)
+{
+ struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
+
+ if (list_empty(&dma_q->active)) {
+ au0828_isocdbg("No active queue to serve\n");
+ dev->isoc_ctl.buf = NULL;
+ *buf = NULL;
+ return;
+ }
+
+ /* Get the next buffer */
+ *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
+ dev->isoc_ctl.buf = *buf;
+
+ return;
+}
+
+/*
+ * Controls the isoc copy of each urb packet
+ */
+static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
+{
+ struct au0828_buffer *buf;
+ struct au0828_dmaqueue *dma_q = urb->context;
+ unsigned char *outp = NULL;
+ int i, len = 0, rc = 1;
+ unsigned char *p;
+ unsigned char fbyte;
+
+ if (!dev)
+ return 0;
+
+ if ((dev->dev_state & DEV_DISCONNECTED) ||
+ (dev->dev_state & DEV_MISCONFIGURED))
+ return 0;
+
+ if (urb->status < 0) {
+ print_err_status(dev, -1, urb->status);
+ if (urb->status == -ENOENT)
+ return 0;
+ }
+
+ buf = dev->isoc_ctl.buf;
+ if (buf != NULL)
+ outp = videobuf_to_vmalloc(&buf->vb);
+
+ for (i = 0; i < urb->number_of_packets; i++) {
+ int status = urb->iso_frame_desc[i].status;
+
+ if (status < 0) {
+ print_err_status(dev, i, status);
+ if (urb->iso_frame_desc[i].status != -EPROTO)
+ continue;
+ }
+
+ if (urb->iso_frame_desc[i].actual_length <= 0)
+ continue;
+
+ if (urb->iso_frame_desc[i].actual_length >
+ dev->max_pkt_size) {
+ au0828_isocdbg("packet bigger than packet size");
+ continue;
+ }
+
+ p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
+ fbyte = p[0];
+ len = urb->iso_frame_desc[i].actual_length - 4;
+ p += 4;
+
+ if (fbyte & 0x80) {
+ len -= 4;
+ p += 4;
+ au0828_isocdbg("Video frame %s\n",
+ (fbyte & 0x40) ? "odd" : "even");
+ if (!(fbyte & 0x40)) {
+ if (buf != NULL)
+ buffer_filled(dev, dma_q, buf);
+ get_next_buf(dma_q, &buf);
+ if (buf == NULL)
+ outp = NULL;
+ else
+ outp = videobuf_to_vmalloc(&buf->vb);
+ }
+
+ if (buf != NULL) {
+ if (fbyte & 0x40)
+ buf->top_field = 1;
+ else
+ buf->top_field = 0;
+ }
+
+ dma_q->pos = 0;
+ }
+ if (buf != NULL)
+ au0828_copy_video(dev, dma_q, buf, p, outp, len);
+ }
+ return rc;
+}
+
+static int
+buffer_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct au0828_fh *fh = vq->priv_data;
+ *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
+
+ if (0 == *count)
+ *count = AU0828_DEF_BUF;
+
+ if (*count < AU0828_MIN_BUF)
+ *count = AU0828_MIN_BUF;
+ return 0;
+}
+
+/* This is called *without* dev->slock held; please keep it that way */
+static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
+{
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_dev *dev = fh->dev;
+ unsigned long flags = 0;
+ if (in_interrupt())
+ BUG();
+
+ /* We used to wait for the buffer to finish here, but this didn't work
+ because, as we were keeping the state as VIDEOBUF_QUEUED,
+ videobuf_queue_cancel marked it as finished for us.
+ (Also, it could wedge forever if the hardware was misconfigured.)
+
+ This should be safe; by the time we get here, the buffer isn't
+ queued anymore. If we ever start marking the buffers as
+ VIDEOBUF_ACTIVE, it won't be, though.
+ */
+ spin_lock_irqsave(&dev->slock, flags);
+ if (dev->isoc_ctl.buf == buf)
+ dev->isoc_ctl.buf = NULL;
+ spin_unlock_irqrestore(&dev->slock, flags);
+
+ videobuf_vmalloc_free(&buf->vb);
+ buf->vb.state = VIDEOBUF_NEEDS_INIT;
+}
+
+static int
+buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
+ enum v4l2_field field)
+{
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
+ struct au0828_dev *dev = fh->dev;
+ int rc = 0, urb_init = 0;
+
+ buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
+
+ if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
+ return -EINVAL;
+
+ buf->vb.width = dev->width;
+ buf->vb.height = dev->height;
+ buf->vb.field = field;
+
+ if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
+ rc = videobuf_iolock(vq, &buf->vb, NULL);
+ if (rc < 0) {
+ printk(KERN_INFO "videobuf_iolock failed\n");
+ goto fail;
+ }
+ }
+
+ if (!dev->isoc_ctl.num_bufs)
+ urb_init = 1;
+
+ if (urb_init) {
+ rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
+ AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
+ au0828_isoc_copy);
+ if (rc < 0) {
+ printk(KERN_INFO "au0828_init_isoc failed\n");
+ goto fail;
+ }
+ }
+
+ buf->vb.state = VIDEOBUF_PREPARED;
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+ return rc;
+}
+
+static void
+buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
+{
+ struct au0828_buffer *buf = container_of(vb,
+ struct au0828_buffer,
+ vb);
+ struct au0828_fh *fh = vq->priv_data;
+ struct au0828_dev *dev = fh->dev;
+ struct au0828_dmaqueue *vidq = &dev->vidq;
+
+ buf->vb.state = VIDEOBUF_QUEUED;
+ list_add_tail(&buf->vb.queue, &vidq->active);
+}
+
+static void buffer_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct au0828_buffer *buf = container_of(vb,
+ struct au0828_buffer,
+ vb);
+
+ free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops au0828_video_qops = {
+ .buf_setup = buffer_setup,
+ .buf_prepare = buffer_prepare,
+ .buf_queue = buffer_queue,
+ .buf_release = buffer_release,
+};
+
+/* ------------------------------------------------------------------
+ V4L2 interface
+ ------------------------------------------------------------------*/
+
+static int au0828_i2s_init(struct au0828_dev *dev)
+{
+ /* Enable i2s mode */
+ au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
+ return 0;
+}
+
+/*
+ * Auvitek au0828 analog stream enable
+ * Please set interface0 to AS5 before enable the stream
+ */
+int au0828_analog_stream_enable(struct au0828_dev *d)
+{
+ dprintk(1, "au0828_analog_stream_enable called\n");
+ au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
+ au0828_writereg(d, 0x106, 0x00);
+ /* set x position */
+ au0828_writereg(d, 0x110, 0x00);
+ au0828_writereg(d, 0x111, 0x00);
+ au0828_writereg(d, 0x114, 0xa0);
+ au0828_writereg(d, 0x115, 0x05);
+ /* set y position */
+ au0828_writereg(d, 0x112, 0x02);
+ au0828_writereg(d, 0x113, 0x00);
+ au0828_writereg(d, 0x116, 0xf2);
+ au0828_writereg(d, 0x117, 0x00);
+ au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
+
+ return 0;
+}
+
+int au0828_analog_stream_disable(struct au0828_dev *d)
+{
+ dprintk(1, "au0828_analog_stream_disable called\n");
+ au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
+ return 0;
+}
+
+void au0828_analog_stream_reset(struct au0828_dev *dev)
+{
+ dprintk(1, "au0828_analog_stream_reset called\n");
+ au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
+ mdelay(30);
+ au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
+}
+
+/*
+ * Some operations needs to stop current streaming
+ */
+static int au0828_stream_interrupt(struct au0828_dev *dev)
+{
+ int ret = 0;
+
+ dev->stream_state = STREAM_INTERRUPT;
+ if (dev->dev_state == DEV_DISCONNECTED)
+ return -ENODEV;
+ else if (ret) {
+ dev->dev_state = DEV_MISCONFIGURED;
+ dprintk(1, "%s device is misconfigured!\n", __func__);
+ return ret;
+ }
+ return 0;
+}
+
+/*
+ * au0828_release_resources
+ * unregister v4l2 devices
+ */
+void au0828_analog_unregister(struct au0828_dev *dev)
+{
+ dprintk(1, "au0828_release_resources called\n");
+ mutex_lock(&au0828_sysfs_lock);
+
+ if (dev->vdev) {
+ list_del(&dev->au0828list);
+ video_unregister_device(dev->vdev);
+ }
+ if (dev->vbi_dev)
+ video_unregister_device(dev->vbi_dev);
+
+ mutex_unlock(&au0828_sysfs_lock);
+}
+
+
+/* Usage lock check functions */
+static int res_get(struct au0828_fh *fh)
+{
+ struct au0828_dev *dev = fh->dev;
+ int rc = 0;
+
+ /* This instance already has stream_on */
+ if (fh->stream_on)
+ return rc;
+
+ if (dev->stream_on)
+ return -EBUSY;
+
+ dev->stream_on = 1;
+ fh->stream_on = 1;
+ return rc;
+}
+
+static int res_check(struct au0828_fh *fh)
+{
+ return fh->stream_on;
+}
+
+static void res_free(struct au0828_fh *fh)
+{
+ struct au0828_dev *dev = fh->dev;
+
+ fh->stream_on = 0;
+ dev->stream_on = 0;
+}
+
+static int au0828_v4l2_open(struct file *filp)
+{
+ int minor = video_devdata(filp)->minor;
+ int ret = 0;
+ struct au0828_dev *h, *dev = NULL;
+ struct au0828_fh *fh;
+ int type = 0;
+ struct list_head *list;
+
+ list_for_each(list, &au0828_devlist) {
+ h = list_entry(list, struct au0828_dev, au0828list);
+ if (h->vdev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ }
+#ifdef VBI_IS_WORKING
+ if (h->vbi_dev->minor == minor) {
+ dev = h;
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ }
+#endif
+ }
+
+ if (NULL == dev)
+ return -ENODEV;
+
+ fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
+ if (NULL == fh) {
+ dprintk(1, "Failed allocate au0828_fh struct!\n");
+ return -ENOMEM;
+ }
+
+ fh->type = type;
+ fh->dev = dev;
+ filp->private_data = fh;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
+ /* set au0828 interface0 to AS5 here again */
+ ret = usb_set_interface(dev->usbdev, 0, 5);
+ if (ret < 0) {
+ printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
+ return -EBUSY;
+ }
+ dev->width = NTSC_STD_W;
+ dev->height = NTSC_STD_H;
+ dev->frame_size = dev->width * dev->height * 2;
+ dev->field_size = dev->width * dev->height;
+ dev->bytesperline = dev->width * 2;
+
+ au0828_analog_stream_enable(dev);
+ au0828_analog_stream_reset(dev);
+
+ /* If we were doing ac97 instead of i2s, it would go here...*/
+ au0828_i2s_init(dev);
+
+ dev->stream_state = STREAM_OFF;
+ dev->dev_state |= DEV_INITIALIZED;
+ }
+
+ dev->users++;
+
+ videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
+ NULL, &dev->slock, fh->type,
+ V4L2_FIELD_INTERLACED,
+ sizeof(struct au0828_buffer), fh);
+
+ return ret;
+}
+
+static int au0828_v4l2_close(struct file *filp)
+{
+ int ret;
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+
+ mutex_lock(&dev->lock);
+ if (res_check(fh))
+ res_free(fh);
+
+ if (dev->users == 1) {
+ videobuf_stop(&fh->vb_vidq);
+ videobuf_mmap_free(&fh->vb_vidq);
+
+ if (dev->dev_state & DEV_DISCONNECTED) {
+ au0828_analog_unregister(dev);
+ mutex_unlock(&dev->lock);
+ kfree(dev);
+ return 0;
+ }
+
+ au0828_analog_stream_disable(dev);
+
+ au0828_uninit_isoc(dev);
+
+ /* When close the device, set the usb intf0 into alt0 to free
+ USB bandwidth */
+ ret = usb_set_interface(dev->usbdev, 0, 0);
+ if (ret < 0)
+ printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
+ }
+
+ kfree(fh);
+ dev->users--;
+ wake_up_interruptible_nr(&dev->open, 1);
+ mutex_unlock(&dev->lock);
+ return 0;
+}
+
+static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return rc;
+
+ return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
+ filp->f_flags & O_NONBLOCK);
+ }
+ return 0;
+}
+
+static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
+{
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return POLLERR;
+
+ if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
+ return POLLERR;
+
+ return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
+}
+
+static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct au0828_fh *fh = filp->private_data;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+ mutex_unlock(&dev->lock);
+
+ if (unlikely(rc < 0))
+ return rc;
+
+ rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
+
+ dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
+ (unsigned long)vma->vm_start,
+ (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
+ rc);
+
+ return rc;
+}
+
+static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
+ struct v4l2_format *format)
+{
+ int ret;
+ int width = format->fmt.pix.width;
+ int height = format->fmt.pix.height;
+ unsigned int maxwidth, maxheight;
+
+ maxwidth = 720;
+ maxheight = 480;
+
+#ifdef VBI_IS_WORKING
+ if (format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
+ dprintk(1, "VBI format set: to be supported!\n");
+ return 0;
+ }
+ if (format->type == V4L2_BUF_TYPE_VBI_CAPTURE)
+ return 0;
+#endif
+ if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ /* If they are demanding a format other than the one we support,
+ bail out (tvtime asks for UYVY and then retries with YUYV) */
+ if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
+ return -EINVAL;
+
+ /* format->fmt.pix.width only support 720 and height 480 */
+ if (width != 720)
+ width = 720;
+ if (height != 480)
+ height = 480;
+
+ format->fmt.pix.width = width;
+ format->fmt.pix.height = height;
+ format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ format->fmt.pix.bytesperline = width * 2;
+ format->fmt.pix.sizeimage = width * height * 2;
+ format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ format->fmt.pix.field = V4L2_FIELD_INTERLACED;
+
+ if (cmd == VIDIOC_TRY_FMT)
+ return 0;
+
+ /* maybe set new image format, driver current only support 720*480 */
+ dev->width = width;
+ dev->height = height;
+ dev->frame_size = width * height * 2;
+ dev->field_size = width * height;
+ dev->bytesperline = width * 2;
+
+ if (dev->stream_state == STREAM_ON) {
+ dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
+ ret = au0828_stream_interrupt(dev);
+ if (ret != 0) {
+ dprintk(1, "error interrupting video stream!\n");
+ return ret;
+ }
+ }
+
+ /* set au0828 interface0 to AS5 here again */
+ ret = usb_set_interface(dev->usbdev, 0, 5);
+ if (ret < 0) {
+ printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
+ return -EBUSY;
+ }
+
+ au0828_analog_stream_enable(dev);
+
+ return 0;
+}
+
+
+static int vidioc_queryctrl(struct file *file, void *priv,
+ struct v4l2_queryctrl *qc)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
+ if (qc->type)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ strlcpy(cap->driver, "au0828", sizeof(cap->driver));
+ strlcpy(cap->card, dev->board.name, sizeof(cap->card));
+ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
+
+ cap->version = AU0828_VERSION_CODE;
+
+ /*set the device capabilities */
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+#ifdef VBI_IS_WORKING
+ V4L2_CAP_VBI_CAPTURE |
+#endif
+ V4L2_CAP_AUDIO |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_STREAMING |
+ V4L2_CAP_TUNER;
+ return 0;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_fmtdesc *f)
+{
+ if (f->index)
+ return -EINVAL;
+
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ strcpy(f->description, "Packed YUV2");
+
+ f->flags = 0;
+ f->pixelformat = V4L2_PIX_FMT_UYVY;
+
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ f->fmt.pix.width = dev->width;
+ f->fmt.pix.height = dev->height;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
+ f->fmt.pix.bytesperline = dev->bytesperline;
+ f->fmt.pix.sizeimage = dev->frame_size;
+ f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
+ f->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ return 0;
+}
+
+static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
+}
+
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ printk(KERN_INFO "%s queue busy\n", __func__);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ if (dev->stream_on && !fh->stream_on) {
+ printk(KERN_INFO "%s device in use by another fh\n", __func__);
+ rc = -EBUSY;
+ goto out;
+ }
+
+ return au0828_set_format(dev, VIDIOC_S_FMT, f);
+out:
+ return rc;
+}
+
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ /* FIXME: when we support something other than NTSC, we are going to
+ have to make the au0828 bridge adjust the size of its capture
+ buffer, which is currently hardcoded at 720x480 */
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_std, *norm);
+ return 0;
+}
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *input)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ unsigned int tmp;
+
+ static const char *inames[] = {
+ [AU0828_VMUX_UNDEFINED] = "Undefined",
+ [AU0828_VMUX_COMPOSITE] = "Composite",
+ [AU0828_VMUX_SVIDEO] = "S-Video",
+ [AU0828_VMUX_CABLE] = "Cable TV",
+ [AU0828_VMUX_TELEVISION] = "Television",
+ [AU0828_VMUX_DVB] = "DVB",
+ [AU0828_VMUX_DEBUG] = "tv debug"
+ };
+
+ tmp = input->index;
+
+ if (tmp > AU0828_MAX_INPUT)
+ return -EINVAL;
+ if (AUVI_INPUT(tmp).type == 0)
+ return -EINVAL;
+
+ input->index = tmp;
+ strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
+ if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
+ (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE))
+ input->type |= V4L2_INPUT_TYPE_TUNER;
+ else
+ input->type |= V4L2_INPUT_TYPE_CAMERA;
+
+ input->std = dev->vdev->tvnorms;
+
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ *i = dev->ctrl_input;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int i;
+ struct v4l2_routing route;
+
+ dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
+ index);
+ if (index >= AU0828_MAX_INPUT)
+ return -EINVAL;
+ if (AUVI_INPUT(index).type == 0)
+ return -EINVAL;
+ dev->ctrl_input = index;
+
+ switch (AUVI_INPUT(index).type) {
+ case AU0828_VMUX_SVIDEO:
+ dev->input_type = AU0828_VMUX_SVIDEO;
+ break;
+ case AU0828_VMUX_COMPOSITE:
+ dev->input_type = AU0828_VMUX_COMPOSITE;
+ break;
+ case AU0828_VMUX_TELEVISION:
+ dev->input_type = AU0828_VMUX_TELEVISION;
+ break;
+ default:
+ dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n",
+ AUVI_INPUT(index).type);
+ break;
+ }
+
+ route.input = AUVI_INPUT(index).vmux;
+ route.output = 0;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
+
+ for (i = 0; i < AU0828_MAX_INPUT; i++) {
+ int enable = 0;
+ if (AUVI_INPUT(i).audio_setup == NULL)
+ continue;
+
+ if (i == index)
+ enable = 1;
+ else
+ enable = 0;
+ if (enable) {
+ (AUVI_INPUT(i).audio_setup)(dev, enable);
+ } else {
+ /* Make sure we leave it turned on if some
+ other input is routed to this callback */
+ if ((AUVI_INPUT(i).audio_setup) !=
+ ((AUVI_INPUT(index).audio_setup))) {
+ (AUVI_INPUT(i).audio_setup)(dev, enable);
+ }
+ }
+ }
+
+ route.input = AUVI_INPUT(index).amux;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ unsigned int index = a->index;
+
+ if (a->index > 1)
+ return -EINVAL;
+
+ index = dev->ctrl_ainput;
+ if (index == 0)
+ strcpy(a->name, "Television");
+ else
+ strcpy(a->name, "Line in");
+
+ a->capability = V4L2_AUDCAP_STEREO;
+ a->index = index;
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ if (a->index != dev->ctrl_ainput)
+ return -EINVAL;
+ return 0;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
+ return 0;
+
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+ struct v4l2_control *ctrl)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (t->index != 0)
+ return -EINVAL;
+
+ strcpy(t->name, "Auvitek tuner");
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *t)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (t->index != 0)
+ return -EINVAL;
+
+ t->type = V4L2_TUNER_ANALOG_TV;
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
+ dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
+ t->afc);
+ return 0;
+
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ freq->type = V4L2_TUNER_ANALOG_TV;
+ freq->frequency = dev->ctrl_freq;
+ return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+ struct v4l2_frequency *freq)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (freq->tuner != 0)
+ return -EINVAL;
+ if (freq->type != V4L2_TUNER_ANALOG_TV)
+ return -EINVAL;
+
+ dev->ctrl_freq = freq->frequency;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
+
+ au0828_analog_stream_reset(dev);
+
+ return 0;
+}
+
+static int vidioc_g_chip_ident(struct file *file, void *priv,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+
+ if (v4l2_chip_match_host(&chip->match)) {
+ chip->ident = V4L2_IDENT_AU0828;
+ return 0;
+ }
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
+ if (chip->ident == V4L2_IDENT_NONE)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int vidioc_cropcap(struct file *file, void *priv,
+ struct v4l2_cropcap *cc)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ cc->bounds.left = 0;
+ cc->bounds.top = 0;
+ cc->bounds.width = dev->width;
+ cc->bounds.height = dev->height;
+
+ cc->defrect = cc->bounds;
+
+ cc->pixelaspect.numerator = 54;
+ cc->pixelaspect.denominator = 59;
+
+ return 0;
+}
+
+static int vidioc_streamon(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ au0828_analog_stream_enable(dev);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
+ }
+
+ mutex_lock(&dev->lock);
+ rc = res_get(fh);
+
+ if (likely(rc >= 0))
+ rc = videobuf_streamon(&fh->vb_vidq);
+ mutex_unlock(&dev->lock);
+
+ return rc;
+}
+
+static int vidioc_streamoff(struct file *file, void *priv,
+ enum v4l2_buf_type type)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int i;
+ int ret;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ if (type != fh->type)
+ return -EINVAL;
+
+ if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
+ ret = au0828_stream_interrupt(dev);
+ if (ret != 0)
+ return ret;
+ }
+
+ for (i = 0; i < AU0828_MAX_INPUT; i++) {
+ if (AUVI_INPUT(i).audio_setup == NULL)
+ continue;
+ (AUVI_INPUT(i).audio_setup)(dev, 0);
+ }
+
+ mutex_lock(&dev->lock);
+ videobuf_streamoff(&fh->vb_vidq);
+ res_free(fh);
+ mutex_unlock(&dev->lock);
+
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vidioc_s_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+
+ switch (reg->match.type) {
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+#endif
+
+static int vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
+}
+
+static int vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_querybuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ return videobuf_qbuf(&fh->vb_vidq, b);
+}
+
+static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
+{
+ struct au0828_fh *fh = priv;
+ struct au0828_dev *dev = fh->dev;
+ int rc;
+
+ rc = check_dev(dev);
+ if (rc < 0)
+ return rc;
+
+ /* Workaround for a bug in the au0828 hardware design that sometimes
+ results in the colorspace being inverted */
+ if (dev->greenscreen_detected == 1) {
+ dprintk(1, "Detected green frame. Resetting stream...\n");
+ au0828_analog_stream_reset(dev);
+ dev->greenscreen_detected = 0;
+ }
+
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
+}
+
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
+{
+ struct au0828_fh *fh = priv;
+
+ return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
+}
+#endif
+
+static struct v4l2_file_operations au0828_v4l_fops = {
+ .owner = THIS_MODULE,
+ .open = au0828_v4l2_open,
+ .release = au0828_v4l2_close,
+ .read = au0828_v4l2_read,
+ .poll = au0828_v4l2_poll,
+ .mmap = au0828_v4l2_mmap,
+ .ioctl = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops video_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
+#ifdef VBI_IS_WORKING
+ .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
+ .vidioc_try_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
+ .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
+#endif
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_cropcap = vidioc_cropcap,
+#ifdef VBI_IS_WORKING
+ .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
+ .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+ .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
+#endif
+ .vidioc_reqbufs = vidioc_reqbufs,
+ .vidioc_querybuf = vidioc_querybuf,
+ .vidioc_qbuf = vidioc_qbuf,
+ .vidioc_dqbuf = vidioc_dqbuf,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_streamon = vidioc_streamon,
+ .vidioc_streamoff = vidioc_streamoff,
+ .vidioc_g_tuner = vidioc_g_tuner,
+ .vidioc_s_tuner = vidioc_s_tuner,
+ .vidioc_g_frequency = vidioc_g_frequency,
+ .vidioc_s_frequency = vidioc_s_frequency,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = vidioc_g_register,
+ .vidioc_s_register = vidioc_s_register,
+#endif
+ .vidioc_g_chip_ident = vidioc_g_chip_ident,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidiocgmbuf = vidiocgmbuf,
+#endif
+};
+
+static const struct video_device au0828_video_template = {
+ .fops = &au0828_v4l_fops,
+ .release = video_device_release,
+ .ioctl_ops = &video_ioctl_ops,
+ .minor = -1,
+ .tvnorms = V4L2_STD_NTSC_M,
+ .current_norm = V4L2_STD_NTSC_M,
+};
+
+/**************************************************************************/
+
+int au0828_analog_register(struct au0828_dev *dev,
+ struct usb_interface *interface)
+{
+ int retval = -ENOMEM;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ int i;
+
+ dprintk(1, "au0828_analog_register called!\n");
+
+ /* set au0828 usb interface0 to as5 */
+ retval = usb_set_interface(dev->usbdev,
+ interface->cur_altsetting->desc.bInterfaceNumber, 5);
+ if (retval != 0) {
+ printk(KERN_INFO "Failure setting usb interface0 to as5\n");
+ return retval;
+ }
+
+ /* Figure out which endpoint has the isoc interface */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
+ endpoint = &iface_desc->endpoint[i].desc;
+ if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ == USB_DIR_IN) &&
+ ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
+ == USB_ENDPOINT_XFER_ISOC)) {
+
+ /* we find our isoc in endpoint */
+ u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
+ dev->max_pkt_size = (tmp & 0x07ff) *
+ (((tmp & 0x1800) >> 11) + 1);
+ dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
+ }
+ }
+ if (!(dev->isoc_in_endpointaddr)) {
+ printk(KERN_INFO "Could not locate isoc endpoint\n");
+ kfree(dev);
+ return -ENODEV;
+ }
+
+ init_waitqueue_head(&dev->open);
+ spin_lock_init(&dev->slock);
+ mutex_init(&dev->lock);
+
+ INIT_LIST_HEAD(&dev->vidq.active);
+ INIT_LIST_HEAD(&dev->vidq.queued);
+
+ dev->width = NTSC_STD_W;
+ dev->height = NTSC_STD_H;
+ dev->field_size = dev->width * dev->height;
+ dev->frame_size = dev->field_size << 1;
+ dev->bytesperline = dev->width << 1;
+ dev->ctrl_ainput = 0;
+
+ /* allocate and fill v4l2 video struct */
+ dev->vdev = video_device_alloc();
+ if (NULL == dev->vdev) {
+ dprintk(1, "Can't allocate video_device.\n");
+ return -ENOMEM;
+ }
+
+#ifdef VBI_IS_WORKING
+ dev->vbi_dev = video_device_alloc();
+ if (NULL == dev->vbi_dev) {
+ dprintk(1, "Can't allocate vbi_device.\n");
+ kfree(dev->vdev);
+ return -ENOMEM;
+ }
+#endif
+
+ /* Fill the video capture device struct */
+ *dev->vdev = au0828_video_template;
+ dev->vdev->parent = &dev->usbdev->dev;
+ strcpy(dev->vdev->name, "au0828a video");
+
+#ifdef VBI_IS_WORKING
+ /* Setup the VBI device */
+ *dev->vbi_dev = au0828_video_template;
+ dev->vbi_dev->parent = &dev->usbdev->dev;
+ strcpy(dev->vbi_dev->name, "au0828a vbi");
+#endif
+
+ list_add_tail(&dev->au0828list, &au0828_devlist);
+
+ /* Register the v4l2 device */
+ retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
+ if (retval != 0) {
+ dprintk(1, "unable to register video device (error = %d).\n",
+ retval);
+ list_del(&dev->au0828list);
+ video_device_release(dev->vdev);
+ return -ENODEV;
+ }
+
+#ifdef VBI_IS_WORKING
+ /* Register the vbi device */
+ retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
+ if (retval != 0) {
+ dprintk(1, "unable to register vbi device (error = %d).\n",
+ retval);
+ list_del(&dev->au0828list);
+ video_device_release(dev->vbi_dev);
+ video_device_release(dev->vdev);
+ return -ENODEV;
+ }
+#endif
+
+ dprintk(1, "%s completed!\n", __func__);
+
+ return 0;
+}
+
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 9d6a1161dc9..6ed1a612973 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -24,6 +24,11 @@
#include <linux/i2c-algo-bit.h>
#include <media/tveeprom.h>
+/* Analog */
+#include <linux/videodev2.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+
/* DVB */
#include "demux.h"
#include "dmxdev.h"
@@ -39,8 +44,45 @@
#define URB_COUNT 16
#define URB_BUFSIZE (0xe522)
+/* Analog constants */
+#define NTSC_STD_W 720
+#define NTSC_STD_H 480
+
+#define AU0828_INTERLACED_DEFAULT 1
+#define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
+
+/* Defination for AU0828 USB transfer */
+#define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */
+#define AU0828_ISO_PACKETS_PER_URB 10
+
+#define AU0828_MIN_BUF 4
+#define AU0828_DEF_BUF 8
+
+#define AU0828_MAX_INPUT 4
+
+enum au0828_itype {
+ AU0828_VMUX_UNDEFINED = 0,
+ AU0828_VMUX_COMPOSITE,
+ AU0828_VMUX_SVIDEO,
+ AU0828_VMUX_CABLE,
+ AU0828_VMUX_TELEVISION,
+ AU0828_VMUX_DVB,
+ AU0828_VMUX_DEBUG
+};
+
+struct au0828_input {
+ enum au0828_itype type;
+ unsigned int vmux;
+ unsigned int amux;
+ void (*audio_setup) (void *priv, int enable);
+};
+
struct au0828_board {
char *name;
+ unsigned int tuner_type;
+ unsigned char tuner_addr;
+ struct au0828_input input[AU0828_MAX_INPUT];
+
};
struct au0828_dvb {
@@ -55,31 +97,143 @@ struct au0828_dvb {
int feeding;
};
+enum au0828_stream_state {
+ STREAM_OFF,
+ STREAM_INTERRUPT,
+ STREAM_ON
+};
+
+#define AUVI_INPUT(nr) (dev->board.input[nr])
+
+/* device state */
+enum au0828_dev_state {
+ DEV_INITIALIZED = 0x01,
+ DEV_DISCONNECTED = 0x02,
+ DEV_MISCONFIGURED = 0x04
+};
+
+struct au0828_fh {
+ struct au0828_dev *dev;
+ unsigned int stream_on:1; /* Locks streams */
+ struct videobuf_queue vb_vidq;
+ enum v4l2_buf_type type;
+};
+
+struct au0828_usb_isoc_ctl {
+ /* max packet size of isoc transaction */
+ int max_pkt_size;
+
+ /* number of allocated urbs */
+ int num_bufs;
+
+ /* urb for isoc transfers */
+ struct urb **urb;
+
+ /* transfer buffers for isoc transfer */
+ char **transfer_buffer;
+
+ /* Last buffer command and region */
+ u8 cmd;
+ int pos, size, pktsize;
+
+ /* Last field: ODD or EVEN? */
+ int field;
+
+ /* Stores incomplete commands */
+ u32 tmp_buf;
+ int tmp_buf_len;
+
+ /* Stores already requested buffers */
+ struct au0828_buffer *buf;
+
+ /* Stores the number of received fields */
+ int nfields;
+
+ /* isoc urb callback */
+ int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb);
+
+};
+
+/* buffer for one video frame */
+struct au0828_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+
+ struct list_head frame;
+ int top_field;
+ int receiving;
+};
+
+struct au0828_dmaqueue {
+ struct list_head active;
+ struct list_head queued;
+
+ wait_queue_head_t wq;
+
+ /* Counters to control buffer fill */
+ int pos;
+};
+
struct au0828_dev {
struct mutex mutex;
struct usb_device *usbdev;
- int board;
+ int boardnr;
+ struct au0828_board board;
u8 ctrlmsg[64];
/* I2C */
struct i2c_adapter i2c_adap;
- struct i2c_algo_bit_data i2c_algo;
+ struct i2c_algorithm i2c_algo;
struct i2c_client i2c_client;
u32 i2c_rc;
/* Digital */
struct au0828_dvb dvb;
+ /* Analog */
+ struct list_head au0828list;
+ struct v4l2_device v4l2_dev;
+ int users;
+ unsigned int stream_on:1; /* Locks streams */
+ struct video_device *vdev;
+ struct video_device *vbi_dev;
+ int width;
+ int height;
+ u32 field_size;
+ u32 frame_size;
+ u32 bytesperline;
+ int type;
+ u8 ctrl_ainput;
+ __u8 isoc_in_endpointaddr;
+ u8 isoc_init_ok;
+ int greenscreen_detected;
+ unsigned int frame_count;
+ int ctrl_freq;
+ int input_type;
+ unsigned int ctrl_input;
+ enum au0828_dev_state dev_state;
+ enum au0828_stream_state stream_state;
+ wait_queue_head_t open;
+
+ struct mutex lock;
+
+ /* Isoc control struct */
+ struct au0828_dmaqueue vidq;
+ struct au0828_usb_isoc_ctl isoc_ctl;
+ spinlock_t slock;
+
+ /* usb transfer */
+ int alt; /* alternate */
+ int max_pkt_size; /* max packet size of isoc transaction */
+ int num_alt; /* Number of alternative settings */
+ unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
+ struct urb *urb[AU0828_MAX_ISO_BUFS]; /* urb for isoc transfers */
+ char *transfer_buffer[AU0828_MAX_ISO_BUFS];/* transfer buffers for isoc
+ transfer */
+
/* USB / URB Related */
int urb_streaming;
struct urb *urbs[URB_COUNT];
-
-};
-
-struct au0828_buff {
- struct au0828_dev *dev;
- struct urb *purb;
- struct list_head buff_list;
};
/* ----------------------------------------------------------- */
@@ -111,8 +265,13 @@ extern void au0828_card_setup(struct au0828_dev *dev);
/* au0828-i2c.c */
extern int au0828_i2c_register(struct au0828_dev *dev);
extern int au0828_i2c_unregister(struct au0828_dev *dev);
-extern void au0828_call_i2c_clients(struct au0828_dev *dev,
- unsigned int cmd, void *arg);
+
+/* ----------------------------------------------------------- */
+/* au0828-video.c */
+int au0828_analog_register(struct au0828_dev *dev,
+ struct usb_interface *interface);
+int au0828_analog_stream_disable(struct au0828_dev *d);
+void au0828_analog_unregister(struct au0828_dev *dev);
/* ----------------------------------------------------------- */
/* au0828-dvb.c */
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index a07b7b88e5b..df4516d8dca 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -29,16 +29,16 @@
*/
#include <linux/module.h>
-#include <linux/delay.h>
#include <linux/types.h>
#include <linux/ioctl.h>
-#include <asm/uaccess.h>
+#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
+#include <media/bt819.h>
MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -48,13 +48,15 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
struct bt819 {
+ struct v4l2_subdev sd;
unsigned char reg[32];
- int initialized;
- int norm;
+ v4l2_std_id norm;
+ int ident;
int input;
int enable;
int bright;
@@ -63,6 +65,11 @@ struct bt819 {
int sat;
};
+static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct bt819, sd);
+}
+
struct timing {
int hactive;
int hdelay;
@@ -80,24 +87,23 @@ static struct timing timing_data[] = {
/* ----------------------------------------------------------------------- */
-static inline int bt819_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int bt819_write(struct bt819 *decoder, u8 reg, u8 value)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
decoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int bt819_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
+static inline int bt819_setbit(struct bt819 *decoder, u8 reg, u8 bit, u8 value)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
-
- return bt819_write(client, reg,
+ return bt819_write(decoder, reg,
(decoder->reg[reg] & ~(1 << bit)) | (value ? (1 << bit) : 0));
}
-static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int bt819_write_block(struct bt819 *decoder, const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
int ret = -1;
u8 reg;
@@ -105,7 +111,6 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned
* the adapter understands raw I2C */
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
/* do raw I2C, not smbus compatible */
- struct bt819 *decoder = i2c_get_clientdata(client);
u8 block_data[32];
int block_len;
@@ -126,7 +131,8 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- if ((ret = bt819_write(client, reg, *data++)) < 0)
+ ret = bt819_write(decoder, reg, *data++);
+ if (ret < 0)
break;
len -= 2;
}
@@ -135,15 +141,15 @@ static int bt819_write_block(struct i2c_client *client, const u8 *data, unsigned
return ret;
}
-static inline int bt819_read(struct i2c_client *client, u8 reg)
+static inline int bt819_read(struct bt819 *decoder, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&decoder->sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int bt819_init(struct i2c_client *client)
+static int bt819_init(struct v4l2_subdev *sd)
{
- struct bt819 *decoder = i2c_get_clientdata(client);
-
static unsigned char init[] = {
/*0x1f, 0x00,*/ /* Reset */
0x01, 0x59, /* 0x01 input format */
@@ -178,7 +184,8 @@ static int bt819_init(struct i2c_client *client)
0x1a, 0x80, /* 0x1a ADC Interface */
};
- struct timing *timing = &timing_data[decoder->norm];
+ struct bt819 *decoder = to_bt819(sd);
+ struct timing *timing = &timing_data[(decoder->norm & V4L2_STD_525_60) ? 1 : 0];
init[0x03 * 2 - 1] =
(((timing->vdelay >> 8) & 0x03) << 6) |
@@ -192,266 +199,306 @@ static int bt819_init(struct i2c_client *client)
init[0x08 * 2 - 1] = timing->hscale >> 8;
init[0x09 * 2 - 1] = timing->hscale & 0xff;
/* 0x15 in array is address 0x19 */
- init[0x15 * 2 - 1] = (decoder->norm == 0) ? 115 : 93; /* Chroma burst delay */
+ init[0x15 * 2 - 1] = (decoder->norm & V4L2_STD_625_50) ? 115 : 93; /* Chroma burst delay */
/* reset */
- bt819_write(client, 0x1f, 0x00);
+ bt819_write(decoder, 0x1f, 0x00);
mdelay(1);
/* init */
- return bt819_write_block(client, init, sizeof(init));
+ return bt819_write_block(decoder, init, sizeof(init));
}
/* ----------------------------------------------------------------------- */
-static int bt819_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt819_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
{
- int temp;
+ struct bt819 *decoder = to_bt819(sd);
+ int status = bt819_read(decoder, 0x00);
+ int res = V4L2_IN_ST_NO_SIGNAL;
+ v4l2_std_id std;
- struct bt819 *decoder = i2c_get_clientdata(client);
+ if ((status & 0x80))
+ res = 0;
- if (!decoder->initialized) { /* First call to bt819_init could be */
- bt819_init(client); /* without #FRST = 0 */
- decoder->initialized = 1;
- }
+ if ((status & 0x10))
+ std = V4L2_STD_PAL;
+ else
+ std = V4L2_STD_NTSC;
+ if (pstd)
+ *pstd = std;
+ if (pstatus)
+ *pstatus = status;
- switch (cmd) {
- case 0:
- /* This is just for testing!!! */
- bt819_init(client);
- break;
+ v4l2_dbg(1, debug, sd, "get status %x\n", status);
+ return 0;
+}
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
+static int bt819_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ return bt819_status(sd, NULL, std);
+}
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 8;
- cap->outputs = 1;
- break;
+static int bt819_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ return bt819_status(sd, status, NULL);
+}
+
+static int bt819_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct bt819 *decoder = to_bt819(sd);
+ struct timing *timing = NULL;
+
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
+
+ if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
+ v4l2_err(sd, "no notify found!\n");
+
+ if (std & V4L2_STD_NTSC) {
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+ bt819_setbit(decoder, 0x01, 0, 1);
+ bt819_setbit(decoder, 0x01, 1, 0);
+ bt819_setbit(decoder, 0x01, 5, 0);
+ bt819_write(decoder, 0x18, 0x68);
+ bt819_write(decoder, 0x19, 0x5d);
+ /* bt819_setbit(decoder, 0x1a, 5, 1); */
+ timing = &timing_data[1];
+ } else if (std & V4L2_STD_PAL) {
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+ bt819_setbit(decoder, 0x01, 0, 1);
+ bt819_setbit(decoder, 0x01, 1, 1);
+ bt819_setbit(decoder, 0x01, 5, 1);
+ bt819_write(decoder, 0x18, 0x7f);
+ bt819_write(decoder, 0x19, 0x72);
+ /* bt819_setbit(decoder, 0x1a, 5, 0); */
+ timing = &timing_data[0];
+ } else {
+ v4l2_dbg(1, debug, sd, "unsupported norm %llx\n",
+ (unsigned long long)std);
+ return -EINVAL;
}
+ bt819_write(decoder, 0x03,
+ (((timing->vdelay >> 8) & 0x03) << 6) |
+ (((timing->vactive >> 8) & 0x03) << 4) |
+ (((timing->hdelay >> 8) & 0x03) << 2) |
+ ((timing->hactive >> 8) & 0x03));
+ bt819_write(decoder, 0x04, timing->vdelay & 0xff);
+ bt819_write(decoder, 0x05, timing->vactive & 0xff);
+ bt819_write(decoder, 0x06, timing->hdelay & 0xff);
+ bt819_write(decoder, 0x07, timing->hactive & 0xff);
+ bt819_write(decoder, 0x08, (timing->hscale >> 8) & 0xff);
+ bt819_write(decoder, 0x09, timing->hscale & 0xff);
+ decoder->norm = std;
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0);
+ return 0;
+}
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
+static int bt819_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct bt819 *decoder = to_bt819(sd);
- status = bt819_read(client, 0x00);
- res = 0;
- if ((status & 0x80))
- res |= DECODER_STATUS_GOOD;
+ v4l2_dbg(1, debug, sd, "set input %x\n", route->input);
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & 0x10))
- res |= DECODER_STATUS_PAL;
- else
- res |= DECODER_STATUS_NTSC;
- break;
- }
- res |= DECODER_STATUS_COLOR;
- *iarg = res;
+ if (route->input < 0 || route->input > 7)
+ return -EINVAL;
- v4l_dbg(1, debug, client, "get status %x\n", *iarg);
- break;
+ if (sd->v4l2_dev == NULL || sd->v4l2_dev->notify == NULL)
+ v4l2_err(sd, "no notify found!\n");
+
+ if (decoder->input != route->input) {
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_LOW, 0);
+ decoder->input = route->input;
+ /* select mode */
+ if (decoder->input == 0) {
+ bt819_setbit(decoder, 0x0b, 6, 0);
+ bt819_setbit(decoder, 0x1a, 1, 1);
+ } else {
+ bt819_setbit(decoder, 0x0b, 6, 1);
+ bt819_setbit(decoder, 0x1a, 1, 0);
+ }
+ v4l2_subdev_notify(sd, BT819_FIFO_RESET_HIGH, 0);
}
+ return 0;
+}
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
- struct timing *timing = NULL;
-
- v4l_dbg(1, debug, client, "set norm %x\n", *iarg);
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- bt819_setbit(client, 0x01, 0, 1);
- bt819_setbit(client, 0x01, 1, 0);
- bt819_setbit(client, 0x01, 5, 0);
- bt819_write(client, 0x18, 0x68);
- bt819_write(client, 0x19, 0x5d);
- /* bt819_setbit(client, 0x1a, 5, 1); */
- timing = &timing_data[VIDEO_MODE_NTSC];
- break;
- case VIDEO_MODE_PAL:
- bt819_setbit(client, 0x01, 0, 1);
- bt819_setbit(client, 0x01, 1, 1);
- bt819_setbit(client, 0x01, 5, 1);
- bt819_write(client, 0x18, 0x7f);
- bt819_write(client, 0x19, 0x72);
- /* bt819_setbit(client, 0x1a, 5, 0); */
- timing = &timing_data[VIDEO_MODE_PAL];
- break;
- case VIDEO_MODE_AUTO:
- bt819_setbit(client, 0x01, 0, 0);
- bt819_setbit(client, 0x01, 1, 0);
- break;
- default:
- v4l_dbg(1, debug, client, "unsupported norm %x\n", *iarg);
- return -EINVAL;
- }
+static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct bt819 *decoder = to_bt819(sd);
- if (timing) {
- bt819_write(client, 0x03,
- (((timing->vdelay >> 8) & 0x03) << 6) |
- (((timing->vactive >> 8) & 0x03) << 4) |
- (((timing->hdelay >> 8) & 0x03) << 2) |
- ((timing->hactive >> 8) & 0x03) );
- bt819_write(client, 0x04, timing->vdelay & 0xff);
- bt819_write(client, 0x05, timing->vactive & 0xff);
- bt819_write(client, 0x06, timing->hdelay & 0xff);
- bt819_write(client, 0x07, timing->hactive & 0xff);
- bt819_write(client, 0x08, (timing->hscale >> 8) & 0xff);
- bt819_write(client, 0x09, timing->hscale & 0xff);
- }
+ v4l2_dbg(1, debug, sd, "enable output %x\n", enable);
- decoder->norm = *iarg;
- break;
+ if (decoder->enable != enable) {
+ decoder->enable = enable;
+ bt819_setbit(decoder, 0x16, 7, !enable);
}
+ return 0;
+}
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set input %x\n", *iarg);
-
- if (*iarg < 0 || *iarg > 7)
- return -EINVAL;
-
- if (decoder->input != *iarg) {
- decoder->input = *iarg;
- /* select mode */
- if (decoder->input == 0) {
- bt819_setbit(client, 0x0b, 6, 0);
- bt819_setbit(client, 0x1a, 1, 1);
- } else {
- bt819_setbit(client, 0x0b, 6, 1);
- bt819_setbit(client, 0x1a, 1, 0);
- }
- }
+static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
- }
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ case V4L2_CID_CONTRAST:
+ v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
+ break;
- v4l_dbg(1, debug, client, "set output %x\n", *iarg);
+ case V4L2_CID_SATURATION:
+ v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
+ break;
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ case V4L2_CID_HUE:
+ v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
- }
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- int enable = (*iarg != 0);
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- v4l_dbg(1, debug, client, "enable output %x\n", *iarg);
+static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct bt819 *decoder = to_bt819(sd);
+ int temp;
- if (decoder->enable != enable) {
- decoder->enable = enable;
- bt819_setbit(client, 0x16, 7, !enable);
- }
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (decoder->bright == ctrl->value)
+ break;
+ decoder->bright = ctrl->value;
+ bt819_write(decoder, 0x0a, decoder->bright);
break;
- }
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- v4l_dbg(1, debug, client,
- "set picture brightness %d contrast %d colour %d\n",
- pic->brightness, pic->contrast, pic->colour);
+ case V4L2_CID_CONTRAST:
+ if (decoder->contrast == ctrl->value)
+ break;
+ decoder->contrast = ctrl->value;
+ bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
+ bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01));
+ break;
+ case V4L2_CID_SATURATION:
+ if (decoder->sat == ctrl->value)
+ break;
+ decoder->sat = ctrl->value;
+ bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
+ bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
+
+ /* Ratio between U gain and V gain must stay the same as
+ the ratio between the default U and V gain values. */
+ temp = (decoder->sat * 180) / 254;
+ bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
+ bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
+ break;
- if (decoder->bright != pic->brightness) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->bright = pic->brightness;
- bt819_write(client, 0x0a,
- (decoder->bright >> 8) - 128);
- }
+ case V4L2_CID_HUE:
+ if (decoder->hue == ctrl->value)
+ break;
+ decoder->hue = ctrl->value;
+ bt819_write(decoder, 0x0f, decoder->hue);
+ break;
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 511 we get 0-65535 */
- decoder->contrast = pic->contrast;
- bt819_write(client, 0x0c,
- (decoder->contrast >> 7) & 0xff);
- bt819_setbit(client, 0x0b, 2,
- ((decoder->contrast >> 15) & 0x01));
- }
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- if (decoder->sat != pic->colour) {
- /* We want 0 to 511 we get 0-65535 */
- decoder->sat = pic->colour;
- bt819_write(client, 0x0d,
- (decoder->sat >> 7) & 0xff);
- bt819_setbit(client, 0x0b, 1,
- ((decoder->sat >> 15) & 0x01));
-
- temp = (decoder->sat * 201) / 237;
- bt819_write(client, 0x0e, (temp >> 7) & 0xff);
- bt819_setbit(client, 0x0b, 0, (temp >> 15) & 0x01);
- }
+static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct bt819 *decoder = to_bt819(sd);
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- bt819_write(client, 0x0f,
- 128 - (decoder->hue >> 8));
- }
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = decoder->bright;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = decoder->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = decoder->sat;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = decoder->hue;
break;
- }
-
default:
return -EINVAL;
}
-
return 0;
}
+static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct bt819 *decoder = to_bt819(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = { 0x8a >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops bt819_core_ops = {
+ .g_chip_ident = bt819_g_chip_ident,
+ .g_ctrl = bt819_g_ctrl,
+ .s_ctrl = bt819_s_ctrl,
+ .queryctrl = bt819_queryctrl,
+};
+
+static const struct v4l2_subdev_tuner_ops bt819_tuner_ops = {
+ .s_std = bt819_s_std,
+};
+
+static const struct v4l2_subdev_video_ops bt819_video_ops = {
+ .s_routing = bt819_s_routing,
+ .s_stream = bt819_s_stream,
+ .querystd = bt819_querystd,
+ .g_input_status = bt819_g_input_status,
+};
+
+static const struct v4l2_subdev_ops bt819_ops = {
+ .core = &bt819_core_ops,
+ .tuner = &bt819_tuner_ops,
+ .video = &bt819_video_ops,
+};
-I2C_CLIENT_INSMOD;
+/* ----------------------------------------------------------------------- */
static int bt819_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i, ver;
struct bt819 *decoder;
+ struct v4l2_subdev *sd;
const char *name;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -ENODEV;
- ver = bt819_read(client, 0x17);
+ decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
+ if (decoder == NULL)
+ return -ENOMEM;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &bt819_ops);
+
+ ver = bt819_read(decoder, 0x17);
switch (ver & 0xf0) {
case 0x70:
name = "bt819a";
+ decoder->ident = V4L2_IDENT_BT819A;
break;
case 0x60:
name = "bt817a";
+ decoder->ident = V4L2_IDENT_BT817A;
break;
case 0x20:
name = "bt815a";
+ decoder->ident = V4L2_IDENT_BT815A;
break;
default:
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"unknown chip version 0x%02x\n", ver);
return -ENODEV;
}
@@ -459,28 +506,26 @@ static int bt819_probe(struct i2c_client *client,
v4l_info(client, "%s found @ 0x%x (%s)\n", name,
client->addr << 1, client->adapter->name);
- decoder = kzalloc(sizeof(struct bt819), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
- decoder->norm = VIDEO_MODE_NTSC;
+ decoder->norm = V4L2_STD_NTSC;
decoder->input = 0;
decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
- decoder->initialized = 0;
- i2c_set_clientdata(client, decoder);
-
- i = bt819_init(client);
+ decoder->bright = 0;
+ decoder->contrast = 0xd8; /* 100% of original signal */
+ decoder->hue = 0;
+ decoder->sat = 0xfe; /* 100% of original signal */
+
+ i = bt819_init(sd);
if (i < 0)
- v4l_dbg(1, debug, client, "init status %d\n", i);
+ v4l2_dbg(1, debug, sd, "init status %d\n", i);
return 0;
}
static int bt819_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_bt819(sd));
return 0;
}
@@ -496,8 +541,6 @@ MODULE_DEVICE_TABLE(i2c, bt819_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "bt819",
- .driverid = I2C_DRIVERID_BT819,
- .command = bt819_command,
.probe = bt819_probe,
.remove = bt819_remove,
.id_table = bt819_id,
diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c
index 4213867507f..78db3950394 100644
--- a/drivers/media/video/bt856.c
+++ b/drivers/media/video/bt856.c
@@ -34,10 +34,10 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Brooktree-856A video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -47,43 +47,46 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
#define BT856_REG_OFFSET 0xDA
#define BT856_NR_REG 6
struct bt856 {
+ struct v4l2_subdev sd;
unsigned char reg[BT856_NR_REG];
- int norm;
- int enable;
+ v4l2_std_id norm;
};
+static inline struct bt856 *to_bt856(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct bt856, sd);
+}
+
/* ----------------------------------------------------------------------- */
-static inline int bt856_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int bt856_write(struct bt856 *encoder, u8 reg, u8 value)
{
- struct bt856 *encoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
encoder->reg[reg - BT856_REG_OFFSET] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int bt856_setbit(struct i2c_client *client, u8 reg, u8 bit, u8 value)
+static inline int bt856_setbit(struct bt856 *encoder, u8 reg, u8 bit, u8 value)
{
- struct bt856 *encoder = i2c_get_clientdata(client);
-
- return bt856_write(client, reg,
+ return bt856_write(encoder, reg,
(encoder->reg[reg - BT856_REG_OFFSET] & ~(1 << bit)) |
(value ? (1 << bit) : 0));
}
-static void bt856_dump(struct i2c_client *client)
+static void bt856_dump(struct bt856 *encoder)
{
int i;
- struct bt856 *encoder = i2c_get_clientdata(client);
- v4l_info(client, "register dump:\n");
+ v4l2_info(&encoder->sd, "register dump:\n");
for (i = 0; i < BT856_NR_REG; i += 2)
printk(KERN_CONT " %02x", encoder->reg[i]);
printk(KERN_CONT "\n");
@@ -91,153 +94,120 @@ static void bt856_dump(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
-static int bt856_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt856_init(struct v4l2_subdev *sd, u32 arg)
{
- struct bt856 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- /* This is just for testing!!! */
- v4l_dbg(1, debug, client, "init\n");
- bt856_write(client, 0xdc, 0x18);
- bt856_write(client, 0xda, 0);
- bt856_write(client, 0xde, 0);
-
- bt856_setbit(client, 0xdc, 3, 1);
- //bt856_setbit(client, 0xdc, 6, 0);
- bt856_setbit(client, 0xdc, 4, 1);
-
- switch (encoder->norm) {
- case VIDEO_MODE_NTSC:
- bt856_setbit(client, 0xdc, 2, 0);
- break;
-
- case VIDEO_MODE_PAL:
- bt856_setbit(client, 0xdc, 2, 1);
- break;
- }
-
- bt856_setbit(client, 0xdc, 1, 1);
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
- if (debug != 0)
- bt856_dump(client);
- break;
-
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
-
- v4l_dbg(1, debug, client, "get capabilities\n");
+ struct bt856 *encoder = to_bt856(sd);
+
+ /* This is just for testing!!! */
+ v4l2_dbg(1, debug, sd, "init\n");
+ bt856_write(encoder, 0xdc, 0x18);
+ bt856_write(encoder, 0xda, 0);
+ bt856_write(encoder, 0xde, 0);
+
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ /*bt856_setbit(encoder, 0xdc, 6, 0);*/
+ bt856_setbit(encoder, 0xdc, 4, 1);
+
+ if (encoder->norm & V4L2_STD_NTSC)
+ bt856_setbit(encoder, 0xdc, 2, 0);
+ else
+ bt856_setbit(encoder, 0xdc, 2, 1);
+
+ bt856_setbit(encoder, 0xdc, 1, 1);
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
+ if (debug != 0)
+ bt856_dump(encoder);
+ return 0;
+}
- cap->flags = VIDEO_ENCODER_PAL |
- VIDEO_ENCODER_NTSC |
- VIDEO_ENCODER_CCIR;
- cap->inputs = 2;
- cap->outputs = 1;
- break;
- }
+static int bt856_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct bt856 *encoder = to_bt856(sd);
- case ENCODER_SET_NORM:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- bt856_setbit(client, 0xdc, 2, 0);
- break;
-
- case VIDEO_MODE_PAL:
- bt856_setbit(client, 0xdc, 2, 1);
- bt856_setbit(client, 0xda, 0, 0);
- //bt856_setbit(client, 0xda, 0, 1);
- break;
-
- default:
- return -EINVAL;
- }
- encoder->norm = *iarg;
- if (debug != 0)
- bt856_dump(client);
- break;
- }
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
- case ENCODER_SET_INPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set input %d\n", *iarg);
-
- /* We only have video bus.
- * iarg = 0: input is from bt819
- * iarg = 1: input is from ZR36060 */
- switch (*iarg) {
- case 0:
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
- bt856_setbit(client, 0xdc, 3, 1);
- bt856_setbit(client, 0xdc, 6, 0);
- break;
- case 1:
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
- bt856_setbit(client, 0xdc, 3, 1);
- bt856_setbit(client, 0xdc, 6, 1);
- break;
- case 2: // Color bar
- bt856_setbit(client, 0xdc, 3, 0);
- bt856_setbit(client, 0xde, 4, 1);
- break;
- default:
- return -EINVAL;
- }
-
- if (debug != 0)
- bt856_dump(client);
- break;
+ if (std & V4L2_STD_NTSC) {
+ bt856_setbit(encoder, 0xdc, 2, 0);
+ } else if (std & V4L2_STD_PAL) {
+ bt856_setbit(encoder, 0xdc, 2, 1);
+ bt856_setbit(encoder, 0xda, 0, 0);
+ /*bt856_setbit(encoder, 0xda, 0, 1);*/
+ } else {
+ return -EINVAL;
}
+ encoder->norm = std;
+ if (debug != 0)
+ bt856_dump(encoder);
+ return 0;
+}
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
+static int bt856_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct bt856 *encoder = to_bt856(sd);
- v4l_dbg(1, debug, client, "set output %d\n", *iarg);
+ v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ /* We only have video bus.
+ * route->input= 0: input is from bt819
+ * route->input= 1: input is from ZR36060 */
+ switch (route->input) {
+ case 0:
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ bt856_setbit(encoder, 0xdc, 6, 0);
break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
-
- encoder->enable = !!*iarg;
-
- v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
+ case 1:
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ bt856_setbit(encoder, 0xdc, 6, 1);
+ break;
+ case 2: /* Color bar */
+ bt856_setbit(encoder, 0xdc, 3, 0);
+ bt856_setbit(encoder, 0xde, 4, 1);
break;
- }
-
default:
return -EINVAL;
}
+ if (debug != 0)
+ bt856_dump(encoder);
return 0;
}
+static int bt856_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT856, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops bt856_core_ops = {
+ .g_chip_ident = bt856_g_chip_ident,
+ .init = bt856_init,
+};
+
+static const struct v4l2_subdev_video_ops bt856_video_ops = {
+ .s_std_output = bt856_s_std_output,
+ .s_routing = bt856_s_routing,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_ops bt856_ops = {
+ .core = &bt856_core_ops,
+ .video = &bt856_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int bt856_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bt856 *encoder;
+ struct v4l2_subdev *sd;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -249,41 +219,38 @@ static int bt856_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct bt856), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_NTSC;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &bt856_ops);
+ encoder->norm = V4L2_STD_NTSC;
- bt856_write(client, 0xdc, 0x18);
- bt856_write(client, 0xda, 0);
- bt856_write(client, 0xde, 0);
+ bt856_write(encoder, 0xdc, 0x18);
+ bt856_write(encoder, 0xda, 0);
+ bt856_write(encoder, 0xde, 0);
- bt856_setbit(client, 0xdc, 3, 1);
- //bt856_setbit(client, 0xdc, 6, 0);
- bt856_setbit(client, 0xdc, 4, 1);
+ bt856_setbit(encoder, 0xdc, 3, 1);
+ /*bt856_setbit(encoder, 0xdc, 6, 0);*/
+ bt856_setbit(encoder, 0xdc, 4, 1);
- switch (encoder->norm) {
+ if (encoder->norm & V4L2_STD_NTSC)
+ bt856_setbit(encoder, 0xdc, 2, 0);
+ else
+ bt856_setbit(encoder, 0xdc, 2, 1);
- case VIDEO_MODE_NTSC:
- bt856_setbit(client, 0xdc, 2, 0);
- break;
-
- case VIDEO_MODE_PAL:
- bt856_setbit(client, 0xdc, 2, 1);
- break;
- }
-
- bt856_setbit(client, 0xdc, 1, 1);
- bt856_setbit(client, 0xde, 4, 0);
- bt856_setbit(client, 0xde, 3, 1);
+ bt856_setbit(encoder, 0xdc, 1, 1);
+ bt856_setbit(encoder, 0xde, 4, 0);
+ bt856_setbit(encoder, 0xde, 3, 1);
if (debug != 0)
- bt856_dump(client);
+ bt856_dump(encoder);
return 0;
}
static int bt856_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_bt856(sd));
return 0;
}
@@ -295,8 +262,6 @@ MODULE_DEVICE_TABLE(i2c, bt856_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "bt856",
- .driverid = I2C_DRIVERID_BT856,
- .command = bt856_command,
.probe = bt856_probe,
.remove = bt856_remove,
.id_table = bt856_id,
diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c
index 596f9e2376b..350cae4b02c 100644
--- a/drivers/media/video/bt866.c
+++ b/drivers/media/video/bt866.c
@@ -34,10 +34,10 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Brooktree-866 video encoder driver");
MODULE_AUTHOR("Mike Bernson & Dave Perks");
@@ -47,22 +47,22 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
struct bt866 {
+ struct v4l2_subdev sd;
u8 reg[256];
-
- int norm;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
};
-static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
+static inline struct bt866 *to_bt866(struct v4l2_subdev *sd)
{
- struct bt866 *encoder = i2c_get_clientdata(client);
+ return container_of(sd, struct bt866, sd);
+}
+
+static int bt866_write(struct bt866 *encoder, u8 subaddr, u8 data)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(&encoder->sd);
u8 buffer[2];
int err;
@@ -89,163 +89,120 @@ static int bt866_write(struct i2c_client *client, u8 subaddr, u8 data)
return 0;
}
-static int bt866_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int bt866_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
{
- struct bt866 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
-
- v4l_dbg(1, debug, client, "get capabilities\n");
-
- cap->flags
- = VIDEO_ENCODER_PAL
- | VIDEO_ENCODER_NTSC
- | VIDEO_ENCODER_CCIR;
- cap->inputs = 2;
- cap->outputs = 1;
- break;
- }
-
- case ENCODER_SET_NORM:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set norm %d\n", *iarg);
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- break;
-
- case VIDEO_MODE_PAL:
- break;
-
- default:
- return -EINVAL;
- }
- encoder->norm = *iarg;
- break;
- }
-
- case ENCODER_SET_INPUT:
- {
- int *iarg = arg;
- static const __u8 init[] = {
- 0xc8, 0xcc, /* CRSCALE */
- 0xca, 0x91, /* CBSCALE */
- 0xcc, 0x24, /* YC16 | OSDNUM */
- 0xda, 0x00, /* */
- 0xdc, 0x24, /* SETMODE | PAL */
- 0xde, 0x02, /* EACTIVE */
-
- /* overlay colors */
- 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
- 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
- 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
- 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
- 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
- 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
- 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
- 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
-
- 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
- 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
- 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
- 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
- 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
- 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
- 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
- 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
- };
- int i;
- u8 val;
-
- for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
- bt866_write(client, init[i], init[i+1]);
-
- val = encoder->reg[0xdc];
-
- if (*iarg == 0)
- val |= 0x40; /* CBSWAP */
- else
- val &= ~0x40; /* !CBSWAP */
-
- bt866_write(client, 0xdc, val);
-
- val = encoder->reg[0xcc];
- if (*iarg == 2)
- val |= 0x01; /* OSDBAR */
- else
- val &= ~0x01; /* !OSDBAR */
- bt866_write(client, 0xcc, val);
-
- v4l_dbg(1, debug, client, "set input %d\n", *iarg);
-
- switch (*iarg) {
- case 0:
- break;
- case 1:
- break;
- default:
- return -EINVAL;
- }
- break;
- }
-
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set output %d\n", *iarg);
-
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- encoder->enable = !!*iarg;
+ v4l2_dbg(1, debug, sd, "set norm %llx\n", (unsigned long long)std);
- v4l_dbg(1, debug, client, "enable output %d\n", encoder->enable);
- break;
- }
-
- case 4711:
- {
- int *iarg = arg;
- __u8 val;
-
- v4l_dbg(1, debug, client, "square %d\n", *iarg);
+ /* Only PAL supported by this driver at the moment! */
+ if (!(std & V4L2_STD_NTSC))
+ return -EINVAL;
+ return 0;
+}
- val = encoder->reg[0xdc];
- if (*iarg)
- val |= 1; /* SQUARE */
- else
- val &= ~1; /* !SQUARE */
- bt866_write(client, 0xdc, val);
+static int bt866_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ static const __u8 init[] = {
+ 0xc8, 0xcc, /* CRSCALE */
+ 0xca, 0x91, /* CBSCALE */
+ 0xcc, 0x24, /* YC16 | OSDNUM */
+ 0xda, 0x00, /* */
+ 0xdc, 0x24, /* SETMODE | PAL */
+ 0xde, 0x02, /* EACTIVE */
+
+ /* overlay colors */
+ 0x70, 0xEB, 0x90, 0x80, 0xB0, 0x80, /* white */
+ 0x72, 0xA2, 0x92, 0x8E, 0xB2, 0x2C, /* yellow */
+ 0x74, 0x83, 0x94, 0x2C, 0xB4, 0x9C, /* cyan */
+ 0x76, 0x70, 0x96, 0x3A, 0xB6, 0x48, /* green */
+ 0x78, 0x54, 0x98, 0xC6, 0xB8, 0xB8, /* magenta */
+ 0x7A, 0x41, 0x9A, 0xD4, 0xBA, 0x64, /* red */
+ 0x7C, 0x23, 0x9C, 0x72, 0xBC, 0xD4, /* blue */
+ 0x7E, 0x10, 0x9E, 0x80, 0xBE, 0x80, /* black */
+
+ 0x60, 0xEB, 0x80, 0x80, 0xc0, 0x80, /* white */
+ 0x62, 0xA2, 0x82, 0x8E, 0xc2, 0x2C, /* yellow */
+ 0x64, 0x83, 0x84, 0x2C, 0xc4, 0x9C, /* cyan */
+ 0x66, 0x70, 0x86, 0x3A, 0xc6, 0x48, /* green */
+ 0x68, 0x54, 0x88, 0xC6, 0xc8, 0xB8, /* magenta */
+ 0x6A, 0x41, 0x8A, 0xD4, 0xcA, 0x64, /* red */
+ 0x6C, 0x23, 0x8C, 0x72, 0xcC, 0xD4, /* blue */
+ 0x6E, 0x10, 0x8E, 0x80, 0xcE, 0x80, /* black */
+ };
+ struct bt866 *encoder = to_bt866(sd);
+ u8 val;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(init) / 2; i += 2)
+ bt866_write(encoder, init[i], init[i+1]);
+
+ val = encoder->reg[0xdc];
+
+ if (route->input == 0)
+ val |= 0x40; /* CBSWAP */
+ else
+ val &= ~0x40; /* !CBSWAP */
+
+ bt866_write(encoder, 0xdc, val);
+
+ val = encoder->reg[0xcc];
+ if (route->input == 2)
+ val |= 0x01; /* OSDBAR */
+ else
+ val &= ~0x01; /* !OSDBAR */
+ bt866_write(encoder, 0xcc, val);
+
+ v4l2_dbg(1, debug, sd, "set input %d\n", route->input);
+
+ switch (route->input) {
+ case 0:
+ case 1:
+ case 2:
break;
- }
-
default:
return -EINVAL;
}
-
return 0;
}
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+#if 0
+/* Code to setup square pixels, might be of some use in the future,
+ but is currently unused. */
+ val = encoder->reg[0xdc];
+ if (*iarg)
+ val |= 1; /* SQUARE */
+ else
+ val &= ~1; /* !SQUARE */
+ bt866_write(client, 0xdc, val);
+#endif
+
+static int bt866_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_BT866, 0);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops bt866_core_ops = {
+ .g_chip_ident = bt866_g_chip_ident,
+};
+
+static const struct v4l2_subdev_video_ops bt866_video_ops = {
+ .s_std_output = bt866_s_std_output,
+ .s_routing = bt866_s_routing,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_ops bt866_ops = {
+ .core = &bt866_core_ops,
+ .video = &bt866_video_ops,
+};
static int bt866_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct bt866 *encoder;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -253,20 +210,18 @@ static int bt866_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(*encoder), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
-
- i2c_set_clientdata(client, encoder);
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &bt866_ops);
return 0;
}
static int bt866_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
- return 0;
-}
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
-static int bt866_legacy_probe(struct i2c_adapter *adapter)
-{
- return adapter->id == I2C_HW_B_ZR36067;
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_bt866(sd));
+ return 0;
}
static const struct i2c_device_id bt866_id[] = {
@@ -277,10 +232,7 @@ MODULE_DEVICE_TABLE(i2c, bt866_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "bt866",
- .driverid = I2C_DRIVERID_BT866,
- .command = bt866_command,
.probe = bt866_probe,
.remove = bt866_remove,
- .legacy_probe = bt866_legacy_probe,
.id_table = bt866_id,
};
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
index ce71e8e7b83..3077c45015f 100644
--- a/drivers/media/video/bt8xx/Kconfig
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -10,7 +10,7 @@ config VIDEO_BT848
select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TDA9875 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
---help---
Support for BT848 based frame grabber/overlay boards. This includes
the Miro, Hauppauge and STB boards. Please read the material in
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index d24dcc025e3..b9c3ba51fb8 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -73,6 +73,11 @@ static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
static void geovision_muxsel(struct bttv *btv, unsigned int input);
+static void phytec_muxsel(struct bttv *btv, unsigned int input);
+
+static void gv800s_muxsel(struct bttv *btv, unsigned int input);
+static void gv800s_init(struct bttv *btv);
+
static int terratec_active_radio_upgrade(struct bttv *btv);
static int tea5757_read(struct bttv *btv);
static int tea5757_write(struct bttv *btv, int value);
@@ -91,12 +96,10 @@ static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
+static unsigned int audiodev[BTTV_MAX];
+static unsigned int saa6588[BTTV_MAX];
static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
-#ifdef MODULE
-static unsigned int autoload = 1;
-#else
-static unsigned int autoload;
-#endif
+static unsigned int autoload = UNSET;
static unsigned int gpiomask = UNSET;
static unsigned int audioall = UNSET;
static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
@@ -115,6 +118,7 @@ module_param_array(pll, int, NULL, 0444);
module_param_array(tuner, int, NULL, 0444);
module_param_array(svhs, int, NULL, 0444);
module_param_array(remote, int, NULL, 0444);
+module_param_array(audiodev, int, NULL, 0444);
module_param_array(audiomux, int, NULL, 0444);
MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
@@ -125,7 +129,14 @@ MODULE_PARM_DESC(latency,"pci latency timer");
MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
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(autoload, "obsolete option, please do not use anymore");
+MODULE_PARM_DESC(audiodev, "specify audio device:\n"
+ "\t\t-1 = no audio\n"
+ "\t\t 0 = autodetect (default)\n"
+ "\t\t 1 = msp3400\n"
+ "\t\t 2 = tda7432\n"
+ "\t\t 3 = tvaudio");
+MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition.");
MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
" [some VIA/SIS chipsets are known to have problem with overlay]");
@@ -246,6 +257,10 @@ static struct CARD {
{ 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
{ 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
+ { 0xf0500000, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500001, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500002, BTTV_BOARD_IVCE8784, "IVCE-8784" },
+ { 0xf0500003, BTTV_BOARD_IVCE8784, "IVCE-8784" },
{ 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
{ 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
@@ -289,6 +304,8 @@ static struct CARD {
/* Duplicate PCI ID, reconfigure for this board during the eeprom read.
* { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */
+ { 0x109e036e, BTTV_BOARD_CONCEPTRONIC_CTVFMI2, "Conceptronic CTVFMi v2"},
+
/* 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" },
@@ -305,6 +322,20 @@ static struct CARD {
{ 0xd200dbc0, BTTV_BOARD_DVICO_FUSIONHDTV_2, "DViCO FusionHDTV 2" },
{ 0x763c008a, BTTV_BOARD_GEOVISION_GV600, "GeoVision GV-600" },
{ 0x18011000, BTTV_BOARD_ENLTV_FM_2, "Encore ENL TV-FM-2" },
+ { 0x763d800a, BTTV_BOARD_GEOVISION_GV800S, "GeoVision GV-800(S) (master)" },
+ { 0x763d800b, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
+ { 0x763d800c, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
+ { 0x763d800d, BTTV_BOARD_GEOVISION_GV800S_SL, "GeoVision GV-800(S) (slave)" },
+
+ { 0x15401830, BTTV_BOARD_PV183, "Provideo PV183-1" },
+ { 0x15401831, BTTV_BOARD_PV183, "Provideo PV183-2" },
+ { 0x15401832, BTTV_BOARD_PV183, "Provideo PV183-3" },
+ { 0x15401833, BTTV_BOARD_PV183, "Provideo PV183-4" },
+ { 0x15401834, BTTV_BOARD_PV183, "Provideo PV183-5" },
+ { 0x15401835, BTTV_BOARD_PV183, "Provideo PV183-6" },
+ { 0x15401836, BTTV_BOARD_PV183, "Provideo PV183-7" },
+ { 0x15401837, BTTV_BOARD_PV183, "Provideo PV183-8" },
+
{ 0, -1, NULL }
};
@@ -316,59 +347,50 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_UNKNOWN] = {
.name = " *** UNKNOWN/GENERIC *** ",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MIRO] = {
.name = "MIRO PCTV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_HAUPPAUGE] = {
.name = "Hauppauge (bt848)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_STB] = {
.name = "STB, Gateway P/N 6000699 (bt848)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 4, 0, 2, 3 },
.gpiomute = 1,
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -377,202 +399,177 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_INTEL] = {
.name = "Intel Create and Share PCI/ Smart Video Recorder III",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_DIAMOND] = {
.name = "Diamond DTV2000",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0, 1, 0, 1 },
.gpiomute = 3,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AVERMEDIA] = {
.name = "AVerMedia TVPhone",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0x0f,
.gpiomux = { 0x0c, 0x04, 0x08, 0x04 },
/* 0x04 for some cards ?? */
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= avermedia_tvphone_audio,
.has_remote = 1,
},
[BTTV_BOARD_MATRIX_VISION] = {
.name = "MATRIX-Vision MV-Delta",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x08 ---------------------------------- */
[BTTV_BOARD_FLYVIDEO] = {
.name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0xc00, 0x800, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TURBOTV] = {
.name = "IMS/IXmicro TurboTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 2, 3 },
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_HAUPPAUGE878] = {
.name = "Hauppauge (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0f, /* old: 7 */
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MIROPRO] = {
.name = "MIRO PCTV pro",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3014f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20001,0x10001, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x0c ---------------------------------- */
[BTTV_BOARD_ADSTECH_TV] = {
.name = "ADS Technologies Channel Surfer TV (bt848)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 14, 11, 7 },
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AVERMEDIA98] = {
.name = "AVerMedia TVCapture 98",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 14, 11, 7 },
.needs_tvaudio = 1,
.msp34xx_alt = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= avermedia_tv_stereo_audio,
.no_gpioirq = 1,
},
[BTTV_BOARD_VHX] = {
.name = "Aimslab Video Highway Xtreme (VHX)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ZOLTRIX] = {
.name = "Zoltrix TV-Max",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 1, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x10 ---------------------------------- */
[BTTV_BOARD_PIXVIEWPLAYTV] = {
.name = "Prolink Pixelview PlayTV (bt878)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
/* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
.gpiomute = 0x002000,
@@ -580,194 +577,170 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_WINVIEW_601] = {
.name = "Leadtek WinView 601",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x8300f8,
- .muxsel = { 2, 3, 1, 1,0 },
+ .muxsel = MUXSEL(2, 3, 1, 1, 0),
.gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
.gpiomute = 0xcfa007,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.volume_gpio = winview_volume,
.has_radio = 1,
},
[BTTV_BOARD_AVEC_INTERCAP] = {
.name = "AVEC Intercapture",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0, 0, 0 },
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_LIFE_FLYKIT] = {
.name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x8dff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.no_msp34xx = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x14 ---------------------------------- */
[BTTV_BOARD_CEI_RAFFLES] = {
.name = "CEI Raffles Card",
.video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_CONFERENCETV] = {
.name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
.video_inputs = 4,
- .audio_inputs = 2, /* tuner, line in */
- .tuner = 0,
+ /* .audio_inputs= 2, tuner, line in */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_PHOEBE_TVMAS] = {
.name = "Askey CPH050/ Phoebe Tv Master + FM",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xc00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 0x800, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MODTEC_205] = {
.name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
+ .has_dig_in = 1,
.gpiomask = 7,
- .muxsel = { 2, 3, -1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
+ .muxsel = MUXSEL(2, 3, 0), /* input 2 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
.gpiomux = { 0, 0, 0, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSBB5_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x18 ---------------------------------- */
[BTTV_BOARD_MAGICTVIEW061] = {
.name = "Askey CPH05X/06X (bt878) [many vendors]",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = {0x400, 0x400, 0x400, 0x400 },
.gpiomute = 0xc00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_VOBIS_BOOSTAR] = {
.name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
.gpiomute = 0x40000,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
},
[BTTV_BOARD_HAUPPAUG_WCAM] = {
.name = "Hauppauge WinCam newer (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 7,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MAXI] = {
.name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
.video_inputs = 4,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_SECAM,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x1c ---------------------------------- */
[BTTV_BOARD_TERRATV] = {
.name = "Terratec TerraTV+ Version 1.1 (bt878)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1f0fff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 },
.gpiomute = 0x40000,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= terratv_audio,
/* GPIO wiring:
External 20 pin connector (for Active Radio Upgrade board)
@@ -805,87 +778,77 @@ struct tvcard bttv_tvcards[] = {
/* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
.name = "Imagenation PXC200",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1, /* was: 4 */
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0},
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = PXC200_muxsel,
},
[BTTV_BOARD_FLYVIDEO_98] = {
.name = "Lifeview FlyVideo 98 LR50",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x1800, /* 0x8dfe00 */
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x0800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_IPROTV] = {
.name = "Formac iProTV, Formac ProTV I (bt848)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 1,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0, 0, 0 },
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x20 ---------------------------------- */
[BTTV_BOARD_INTEL_C_S_PCI] = {
.name = "Intel Create and Share PCI/ Smart Video Recorder III",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVALUE] = {
.name = "Terratec TerraTValue Version Bt878",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x500, 0, 0x300, 0x900 },
.gpiomute = 0x900,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_WINFAST2000] = {
.name = "Leadtek WinFast 2000/ WinFast 2000 XP",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */
+ /* TV, CVid, SVid, CVid over SVid connector */
+ .muxsel = MUXSEL(2, 3, 1, 1, 0),
/* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
.gpiomask = 0xb33000,
.gpiomux = { 0x122000,0x1000,0x0000,0x620000 },
@@ -906,217 +869,191 @@ struct tvcard bttv_tvcards[] = {
.has_radio = 1,
.tuner_type = TUNER_PHILIPS_PAL, /* default for now, gpio reads BFFF06 for Pal bg+dk */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= winfast2000_audio,
.has_remote = 1,
},
[BTTV_BOARD_CHRONOS_VS2] = {
.name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x24 ---------------------------------- */
[BTTV_BOARD_TYPHOON_TVIEW] = {
.name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_PXELVWPLTVPRO] = {
.name = "Prolink PixelView PlayTV pro",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xff,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
.gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MAGICTVIEW063] = {
.name = "Askey CPH06X TView99",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x551e00,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0x551400, 0x551200, 0, 0 },
.gpiomute = 0x551c00,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_PINNACLE] = {
.name = "Pinnacle PCTV Studio/Rave",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0xd0001, 0, 0 },
.gpiomute = 1,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x28 ---------------------------------- */
[BTTV_BOARD_STB2] = {
.name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 4, 0, 2, 3 },
.gpiomute = 1,
.no_msp34xx = 1,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
[BTTV_BOARD_AVPHONE98] = {
.name = "AVerMedia TVPhone 98",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 13, 4, 11, 7 },
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.audio_mode_gpio= avermedia_tvphone_audio,
},
[BTTV_BOARD_PV951] = {
.name = "ProVideo PV951", /* pic16c54 */
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0, 0},
.needs_tvaudio = 1,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ONAIR_TV] = {
.name = "Little OnAir TV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00b,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
.gpiomute = 0xff3ffc,
.no_msp34xx = 1,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x2c ---------------------------------- */
[BTTV_BOARD_SIGMA_TVII_FM] = {
.name = "Sigma TVII-FM",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 0, 2 },
.gpiomute = 3,
.no_msp34xx = 1,
.pll = PLL_NONE,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MATRIX_VISION2] = {
.name = "MATRIX-Vision MV-Delta 2",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ZOLTRIX_GENIE] = {
.name = "Zoltrix Genie TV/FM",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xbcf03f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
.gpiomute = 0xbcb03f,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4039FR5_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVRADIO] = {
.name = "Terratec TV/Radio+",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x70000,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
.gpiomute = 0x40000,
.needs_tvaudio = 1,
@@ -1124,7 +1061,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_35,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
@@ -1132,51 +1068,46 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_DYNALINK] = {
.name = "Askey CPH03x/ Dynalink Magic TView",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = {2,0,0,0 },
.gpiomute = 1,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GVBCTV3PCI] = {
.name = "IODATA GV-BCTV3/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = {0x10000, 0, 0x10000, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_ALPS_TSHC6_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv3pci_audio,
},
[BTTV_BOARD_PXELVWPLTVPAK] = {
.name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
.video_inputs = 5,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
+ .has_dig_in = 1,
.gpiomask = 0xAA0000,
- .muxsel = { 2,3,1,1,-1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
+ .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
.gpiomux = { 0x20000, 0, 0x80000, 0x80000 },
.gpiomute = 0xa8000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring: (different from Rev.4C !)
GPIO17: U4.A0 (first hef4052bt)
@@ -1191,17 +1122,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_EAGLE] = {
.name = "Eagle Wireless Capricorn2 (bt878A)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.pll = PLL_28,
.tuner_type = UNSET /* TUNER_ALPS_TMDH2_NTSC */,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x34 ---------------------------------- */
@@ -1209,11 +1138,10 @@ struct tvcard bttv_tvcards[] = {
/* David Härdeman <david@2gen.com> */
.name = "Pinnacle PCTV Studio Pro",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 0xd0001, 0, 0 },
.gpiomute = 10,
/* sound path (5 sources):
@@ -1229,25 +1157,22 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TVIEW_RDS_FM] = {
/* Claas Langbehn <claas@bigfoot.com>,
Sven Grothklags <sven@upb.de> */
.name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1c,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0x10, 8 },
.gpiomute = 4,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_LIFETEC_9415] = {
@@ -1258,11 +1183,10 @@ struct tvcard bttv_tvcards[] = {
options tuner type=5 */
.name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x18e0,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
.gpiomute = 0x18e0,
/* For cards with tda9820/tda9821:
@@ -1272,25 +1196,22 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_BESTBUY_EASYTV] = {
/* Miguel Angel Alvarez <maacruz@navegalia.com>
old Easy TV BT848 version (model CPH031) */
.name = "Askey CPH031/ BESTBUY Easy TV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xF,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x38 ---------------------------------- */
@@ -1298,17 +1219,15 @@ struct tvcard bttv_tvcards[] = {
/* Gordon Heydon <gjheydon@bigfoot.com ('98) */
.name = "Lifeview FlyVideo 98FM LR50",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x1800,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0x800, 0x1000, 0x1000 },
.gpiomute = 0x1800,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* This is the ultimate cheapo capture card
* just a BT848A on a small PCB!
@@ -1316,51 +1235,45 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_GRANDTEC] = {
.name = "GrandTec 'Grand Video Capture' (Bt848)",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
.gpiomask = 0,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_35,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ASKEY_CPH060] = {
/* Daniel Herrington <daniel.herrington@home.com> */
.name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xe00,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x400, 0x400, 0x400, 0x400 },
.gpiomute = 0x800,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4036FY5_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ASKEY_CPH03X] = {
/* Matti Mottus <mottus@physic.ut.ee> */
.name = "Askey CPH03x TV Capturer",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x03000F,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x3c ---------------------------------- */
@@ -1368,34 +1281,30 @@ struct tvcard bttv_tvcards[] = {
/* Philip Blundell <philb@gnu.org> */
.name = "Modular Technology MM100PCTV",
.video_inputs = 2,
- .audio_inputs = 2,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 2, */
+ .svhs = NO_SVHS,
.gpiomask = 11,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 1 },
.gpiomute = 8,
.pll = PLL_35,
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GMV1] = {
/* Adrian Cox <adrian@humboldt.co.uk */
.name = "AG Electronics GMV1",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
.gpiomask = 0xF,
- .muxsel = { 2, 2 },
+ .muxsel = MUXSEL(2, 2),
.gpiomux = { },
.no_msp34xx = 1,
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_BESTBUY_EASYTV2] = {
/* Miguel Angel Alvarez <maacruz@navegalia.com>
@@ -1403,34 +1312,30 @@ struct tvcard bttv_tvcards[] = {
special thanks to Informatica Mieres for providing the card */
.name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 1, 0, 4, 4 },
.gpiomute = 9,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_ATI_TVWONDER] = {
/* Lukas Gebauer <geby@volny.cz> */
.name = "ATI TV-Wonder",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xf03f,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0xbffe, 0, 0xbfff, 0 },
.gpiomute = 0xbffe,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x40 ---------------------------------- */
@@ -1438,27 +1343,24 @@ struct tvcard bttv_tvcards[] = {
/* Lukas Gebauer <geby@volny.cz> */
.name = "ATI TV-Wonder VE",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 1,
- .muxsel = { 2, 3, 0, 1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.gpiomux = { 0, 0, 1, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_FLYVIDEO2000] = {
/* DeeJay <deejay@westel900.net (2000S) */
.name = "Lifeview FlyVideo 2000S LR90",
.video_inputs = 3,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 0x18e0,
- .muxsel = { 2, 3, 0, 1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
/* Radio changed from 1e80 to 0x800 to make
FlyVideo2000S in .hu happy (gm)*/
/* -dk-???: set mute=0x1800 for tda9874h daughterboard */
@@ -1471,40 +1373,35 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TERRATVALUER] = {
.name = "Terratec TValueRadio",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0xffff00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x500, 0x500, 0x300, 0x900 },
.gpiomute = 0x900,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
},
[BTTV_BOARD_GVBCTV4PCI] = {
/* TANAKA Kei <peg00625@nifty.com> */
.name = "IODATA GV-BCTV4/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x010f00,
- .muxsel = {2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = {0x10000, 0, 0x10000, 0 },
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv3pci_audio,
},
@@ -1514,9 +1411,8 @@ struct tvcard bttv_tvcards[] = {
/* try "insmod msp3400 simple=0" if you have
* sound problems with this card. */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x4f8a00,
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1524,10 +1420,9 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = { 2, 3 ,0 ,1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.tuner_type = TUNER_MT2032,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1536,9 +1431,8 @@ struct tvcard bttv_tvcards[] = {
/* try "insmod msp3400 simple=0" if you have
* sound problems with this card. */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0x4f8a00,
/* 0x100000: 1=MSP enabled (0=disable again)
* 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
@@ -1546,10 +1440,9 @@ struct tvcard bttv_tvcards[] = {
.gpiomute = 0x947fff,
/* tvtuner, radio, external,internal, mute, stereo
* tuner, Composit, SVid, Composit-on-Svid-adapter */
- .muxsel = { 2, 3 ,0 ,1 },
+ .muxsel = MUXSEL(2, 3, 0, 1),
.tuner_type = TUNER_MT2032,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1557,31 +1450,27 @@ struct tvcard bttv_tvcards[] = {
/* Philip Blundell <pb@nexus.co.uk> */
.name = "Active Imaging AIMMS",
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
- .muxsel = { 2 },
+ .muxsel = MUXSEL(2),
.gpiomask = 0
},
[BTTV_BOARD_PV_BT878P_PLUS] = {
/* Tomasz Pyra <hellfire@sedez.iq.pl> */
.name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
.video_inputs = 3,
- .audio_inputs = 4,
- .tuner = 0,
+ /* .audio_inputs= 4, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
.gpiomute = 13,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_LG_PAL_I_FM,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
/* GPIO wiring:
GPIO0: U4.A0 (hef4052bt)
@@ -1594,15 +1483,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_FLYVIDEO98EZ] = {
.name = "Lifeview FlyVideo 98EZ (capture only) LR51",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */
+ /* AV1, AV2, SVHS, CVid adapter on SVHS */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.pll = PLL_28,
.no_msp34xx = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x48 ---------------------------------- */
@@ -1610,11 +1498,10 @@ struct tvcard bttv_tvcards[] = {
/* Dariusz Kowalewski <darekk@automex.pl> */
.name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x01, 0x00, 0x03, 0x03 },
.gpiomute = 0x09,
.needs_tvaudio = 1,
@@ -1623,7 +1510,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= pvbt878p9b_audio, /* Note: not all cards have stereo */
.has_radio = 1, /* Note: not all cards have radio */
.has_remote = 1,
@@ -1640,49 +1526,42 @@ struct tvcard bttv_tvcards[] = {
/* you must jumper JP5 for the card to work */
.name = "Sensoray 311",
.video_inputs = 5,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 4,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_RV605] = {
/* Miguel Freitas <miguel@cetuc.puc-rio.br> */
.name = "RemoteVision MX (RV605)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x00,
.gpiomask2 = 0x07ff,
- .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
- 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = rv605_muxsel,
},
[BTTV_BOARD_POWERCLR_MTV878] = {
.name = "Powercolor MTV878/ MTV878R/ MTV878F",
.video_inputs = 3,
- .audio_inputs = 2,
- .tuner = 0,
+ /* .audio_inputs= 2, */
.svhs = 2,
.gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
- .muxsel = { 2, 1, 1, },
+ .muxsel = MUXSEL(2, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 4,
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
},
@@ -1692,42 +1571,38 @@ struct tvcard bttv_tvcards[] = {
/* Masaki Suzuki <masaki@btree.org> */
.name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x140007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= windvr_audio,
},
[BTTV_BOARD_GRANDTEC_MULTI] = {
.name = "GrandTec Multi Capture Card (Bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_KWORLD] = {
.name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
.video_inputs = 4,
- .audio_inputs = 3,
- .tuner = 0,
+ /* .audio_inputs= 3, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ /* Tuner, SVid, SVHS, SVid to SVHS connector */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 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.
@@ -1741,7 +1616,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
radio signal strength indicators work fine. */
.has_radio = 1,
@@ -1759,27 +1633,24 @@ struct tvcard bttv_tvcards[] = {
/* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
.name = "DSP Design TCVIDEO",
.video_inputs = 4,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x50 ---------------------------------- */
[BTTV_BOARD_HAUPPAUGEPVR] = {
.name = "Hauppauge WinTV PVR",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 0, 1, 1 },
+ .muxsel = MUXSEL(2, 0, 1, 1),
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask = 7,
.gpiomux = {7},
@@ -1787,32 +1658,28 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_GVBCTV5PCI] = {
.name = "IODATA GV-BCTV5/PCI",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0f0f80,
- .muxsel = {2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x030000, 0x010000, 0, 0 },
.gpiomute = 0x020000,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= gvbctv5pci_audio,
.has_radio = 1,
},
[BTTV_BOARD_OSPREY1x0] = {
.name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
.video_inputs = 4, /* id-inputs-clock */
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 3,
- .muxsel = { 3, 2, 0, 1 },
+ .muxsel = MUXSEL(3, 2, 0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1820,14 +1687,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x0_848] = {
.name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
.video_inputs = 3,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1837,14 +1702,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY101_848] = {
.name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1852,14 +1715,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x1] = {
.name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1867,14 +1728,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY1x1_SVID] = {
.name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 0, 1 },
+ .muxsel = MUXSEL(0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1882,14 +1741,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2xx] = {
.name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
.video_inputs = 1,
- .audio_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0 },
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1899,14 +1756,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2x0_SVID] = {
.name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 0, 1 },
+ .muxsel = MUXSEL(0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1914,14 +1769,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2x0] = {
.name = "Osprey 210/220/230", /* 0x1(A|B)-04C0-C1 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1929,14 +1782,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY500] = {
.name = "Osprey 500", /* 500 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1944,12 +1795,10 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY540] = {
.name = "Osprey 540", /* 540 */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -1959,14 +1808,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY2000] = {
.name = "Osprey 2000", /* 2000 */
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = UNSET,
+ /* .audio_inputs= 1, */
.svhs = 1,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
@@ -1975,14 +1822,12 @@ struct tvcard bttv_tvcards[] = {
/* M G Berberich <berberic@forwiss.uni-passau.de> */
.name = "IDS Eagle",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 0, 1, 2, 3 },
+ .muxsel = MUXSEL(2, 2, 2, 2),
.muxsel_hook = eagle_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -1991,16 +1836,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PINNACLESAT] = {
.name = "Pinnacle PCTV Sat",
.video_inputs = 2,
- .audio_inputs = 0,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = { 3, 1 },
+ .muxsel = MUXSEL(3, 1),
.pll = PLL_28,
.no_gpioirq = 1,
.has_dvb = 1,
@@ -2008,18 +1851,16 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_FORMAC_PROTV] = {
.name = "Formac ProTV II (bt878)",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 3,
.gpiomask = 2,
/* TV, Comp1, Composite over SVID con, SVID */
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 2, 0, 0 },
.pll = PLL_28,
.has_radio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* sound routing:
GPIO=0x00,0x01,0x03: mute (?)
0x02: both TV and radio (tuner: FM1216/I)
@@ -2033,62 +1874,55 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_MACHTV] = {
.name = "MachTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1},
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3},
.gpiomute = 4,
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
[BTTV_BOARD_EURESYS_PICOLO] = {
.name = "Euresys Picolo",
.video_inputs = 3,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 2,
.gpiomask = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = { 2, 0, 1},
+ .muxsel = MUXSEL(2, 0, 1),
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_PV150] = {
/* Luc Van Hoeylandt <luc@e-magic.be> */
.name = "ProVideo PV150", /* 0x4f */
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3 },
+ .muxsel = MUXSEL(2, 3),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_AD_TVK503] = {
/* Hiroshi Takekawa <sian@big.or.jp> */
/* This card lacks subsystem ID */
.name = "AD-TVK503", /* 0x63 */
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x001e8007,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
/* Tuner, Radio, external, internal, off, on */
.gpiomux = { 0x08, 0x0f, 0x0a, 0x08 },
.gpiomute = 0x0f,
@@ -2097,7 +1931,6 @@ struct tvcard bttv_tvcards[] = {
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.audio_mode_gpio= adtvk503_audio,
},
@@ -2105,17 +1938,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_HERCULES_SM_TV] = {
.name = "Hercules Smart TV Stereo",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.needs_tvaudio = 1,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
/* Notes:
- card lacks subsystem ID
- stereo variant w/ daughter board with tda9874a @0xb0
@@ -2129,16 +1960,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PACETV] = {
.name = "Pace TV & Radio Card",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */
+ /* Tuner, CVid, SVid, CVid over SVid connector */
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomask = 0,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.pll = PLL_28,
/* Bt878, Bt832, FI1246 tuner; no pci subsystem id
@@ -2152,27 +1982,34 @@ struct tvcard bttv_tvcards[] = {
/* Chris Willing <chris@vislab.usyd.edu.au> */
.name = "IVC-200",
.video_inputs = 1,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
+ .gpiomask = 0xdf,
+ .muxsel = MUXSEL(2),
+ .pll = PLL_28,
+ },
+ [BTTV_BOARD_IVCE8784] = {
+ .name = "IVCE-8784",
+ .video_inputs = 1,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0xdf,
- .muxsel = { 2 },
+ .muxsel = MUXSEL(2),
.pll = PLL_28,
},
[BTTV_BOARD_XGUARD] = {
.name = "Grand X-Guard / Trust 814PCI",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask2 = 0xff,
- .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
+ .muxsel = MUXSEL(2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0),
.muxsel_hook = xguard_muxsel,
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -2184,16 +2021,14 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_NEBULA_DIGITV] = {
.name = "Nebula Electronics DigiTV",
.video_inputs = 1,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
.has_remote = 1,
.gpiomask = 0x1b,
@@ -2203,118 +2038,101 @@ struct tvcard bttv_tvcards[] = {
/* Jorge Boncompte - DTI2 <jorge@dti2.net> */
.name = "ProVideo PV143",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0 },
.needs_tvaudio = 0,
.no_msp34xx = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009X1_VD011_MINIDIN] = {
/* M.Klahr@phytec.de */
.name = "PHYTEC VD-009-X1 VD-011 MiniDIN (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009X1_VD011_COMBI] = {
.name = "PHYTEC VD-009-X1 VD-011 Combi (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x6c ---------------------------------- */
[BTTV_BOARD_VD009_MINIDIN] = {
.name = "PHYTEC VD-009 MiniDIN (bt878)",
.video_inputs = 10,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 9,
.gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
+ .gpiomask2 = 0x03, /* used for external vodeo mux */
+ .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 0),
+ .muxsel_hook = phytec_muxsel,
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD009_COMBI] = {
.name = "PHYTEC VD-009 Combi (bt878)",
.video_inputs = 10,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 9,
.gpiomask = 0x00,
- .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
- via the upper nibble of muxsel. here: used for
- xternal video-mux */
- .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
+ .gpiomask2 = 0x03, /* used for external vodeo mux */
+ .muxsel = MUXSEL(2, 2, 2, 2, 3, 3, 3, 3, 1, 1),
+ .muxsel_hook = phytec_muxsel,
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_IVC100] = {
.name = "IVC-100",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0xdf,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.pll = PLL_28,
},
[BTTV_BOARD_IVC120] = {
/* IVC-120G - Alan Garfield <alan@fromorbit.com> */
.name = "IVC-120G",
.video_inputs = 16,
- .audio_inputs = 0, /* card has no audio */
- .tuner = UNSET, /* card has no tuner */
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET, /* card has no svhs */
+ .svhs = NO_SVHS, /* card has no svhs */
.needs_tvaudio = 0,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.gpiomask = 0x00,
- .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
- 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
+ .muxsel = MUXSEL(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
.muxsel_hook = ivc120_muxsel,
.pll = PLL_28,
},
@@ -2323,13 +2141,11 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_PC_HDTV] = {
.name = "pcHDTV HD-2000 TV",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_PHILIPS_FCV1236D,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
},
[BTTV_BOARD_TWINHAN_DST] = {
@@ -2339,38 +2155,34 @@ struct tvcard bttv_tvcards[] = {
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_video = 1,
.has_dvb = 1,
},
[BTTV_BOARD_WINFASTVC100] = {
.name = "Winfast VC100",
.video_inputs = 3,
- .audio_inputs = 0,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .tuner = UNSET,
- .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */
+ /* Vid In, SVid In, Vid over SVid in connector */
+ .muxsel = MUXSEL(3, 1, 1, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
[BTTV_BOARD_TEV560] = {
.name = "Teppro TEV-560/InterVision IV-560",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 3,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 1, 1, 1, 1 },
.needs_tvaudio = 1,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_35,
},
@@ -2378,14 +2190,12 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_SIMUS_GVC1100] = {
.name = "SIMUS GVC1100",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
- .muxsel = { 2, 2, 2, 2 },
+ .muxsel = MUXSEL(2, 2, 2, 2),
.gpiomask = 0x3F,
.muxsel_hook = gvc1100_muxsel,
},
@@ -2393,47 +2203,41 @@ struct tvcard bttv_tvcards[] = {
/* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
.name = "NGS NGSTV+",
.video_inputs = 3,
- .tuner = 0,
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 0, 0 },
+ .muxsel = MUXSEL(2, 3, 0, 0),
.gpiomux = { 0, 0, 0, 0 },
.gpiomute = 0x000003,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
},
[BTTV_BOARD_LMLBT4] = {
/* http://linuxmedialabs.com */
.name = "LMLBT4",
.video_inputs = 4, /* IN1,IN2,IN3,IN4 */
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 1, 0 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 1, 0),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.needs_tvaudio = 0,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_TEKRAM_M205] = {
/* Helmroos Harri <harri.helmroos@pp.inet.fi> */
.name = "Tekram M205 PRO",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.svhs = 2,
.needs_tvaudio = 0,
.gpiomask = 0x68,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomux = { 0x68, 0x68, 0x61, 0x61 },
.pll = PLL_28,
},
@@ -2444,18 +2248,16 @@ struct tvcard bttv_tvcards[] = {
/* bt878 TV + FM without subsystem ID */
.name = "Conceptronic CONTVFMi",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 3,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
},
@@ -2466,37 +2268,34 @@ struct tvcard bttv_tvcards[] = {
/*0x79 in bttv.h*/
.name = "Euresys Picolo Tetra",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0,
.gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
+ /*878A input is always MUX0, see above.*/
+ .muxsel = MUXSEL(2, 2, 2, 2),
.gpiomux = { 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*/
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_SPIRIT_TV] = {
/* Spirit TV Tuner from http://spiritmodems.com.au */
/* Stafford Goodsell <surge@goliath.homeunix.org> */
.name = "Spirit TV Tuner",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x0000000f,
- .muxsel = { 2, 1, 1 },
+ .muxsel = MUXSEL(2, 1, 1),
.gpiomux = { 0x02, 0x00, 0x00, 0x00 },
.tuner_type = TUNER_TEMIC_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
},
@@ -2505,11 +2304,9 @@ struct tvcard bttv_tvcards[] = {
.name = "AVerMedia AVerTV DVB-T 771",
.video_inputs = 2,
.svhs = 1,
- .tuner = UNSET,
.tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .muxsel = { 3 , 3 },
+ .muxsel = MUXSEL(3, 3),
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -2524,54 +2321,47 @@ struct tvcard bttv_tvcards[] = {
/* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
.name = "AverMedia AverTV DVB-T 761",
.video_inputs = 2,
- .tuner = UNSET,
.svhs = 1,
- .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */
+ .muxsel = MUXSEL(3, 1, 2, 0), /* Comp0, S-Video, ?, ? */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_dvb = 1,
.no_gpioirq = 1,
.has_remote = 1,
},
[BTTV_BOARD_MATRIX_VISIONSQ] = {
/* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SQ",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3 },
- .muxsel_hook = sigmaSQ_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "MATRIX Vision Sigma-SQ",
+ .video_inputs = 16,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3),
+ .muxsel_hook = sigmaSQ_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_MATRIX_VISIONSLC] = {
/* andre.schwarz@matrix-vision.de */
- .name = "MATRIX Vision Sigma-SLC",
- .video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2 },
- .muxsel_hook = sigmaSLC_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "MATRIX Vision Sigma-SLC",
+ .video_inputs = 4,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .muxsel_hook = sigmaSLC_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
/* BTTV_BOARD_APAC_VIEWCOMP */
[BTTV_BOARD_APAC_VIEWCOMP] = {
@@ -2579,18 +2369,16 @@ struct tvcard bttv_tvcards[] = {
/* bt878 TV + FM 0x00000000 subsystem ID */
.name = "APAC Viewcomp 878(AMAX)",
.video_inputs = 2,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = UNSET,
+ /* .audio_inputs= 1, */
+ .svhs = NO_SVHS,
.gpiomask = 0xFF,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
.has_radio = 1, /* not every card has radio */
},
@@ -2599,46 +2387,40 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_DVICO_DVBT_LITE] = {
/* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
.name = "DViCO FusionHDTV DVB-T Lite",
- .tuner = UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
.pll = PLL_28,
.no_video = 1,
.has_dvb = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VGEAR_MYVCD] = {
/* Steven <photon38@pchome.com.tw> */
.name = "V-Gear MyVCD",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = {2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.gpiomux = {0x31, 0x31, 0x31, 0x31 },
.gpiomute = 0x31,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC_M,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 0,
},
[BTTV_BOARD_SUPER_TV] = {
/* Rick C <cryptdragoon@gmail.com> */
.name = "Super TV Tuner",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.gpiomask = 0x008007,
.gpiomux = { 0, 0x000001,0,0 },
.needs_tvaudio = 1,
@@ -2648,17 +2430,15 @@ struct tvcard bttv_tvcards[] = {
/* Chris Fanning <video4linux@haydon.net> */
.name = "Tibet Systems 'Progress DVR' CS16",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.muxsel_hook = tibetCS16_muxsel,
},
[BTTV_BOARD_KODICOM_4400R] = {
@@ -2675,12 +2455,10 @@ struct tvcard bttv_tvcards[] = {
*/
.name = "Kodicom 4400R (master)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
/* GPIO bits 0-9 used for analog switch:
* 00 - 03: camera selector
* 04 - 06: channel (controller) selector
@@ -2691,7 +2469,7 @@ struct tvcard bttv_tvcards[] = {
*/
.gpiomask = 0x0003ff,
.no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
@@ -2707,15 +2485,13 @@ struct tvcard bttv_tvcards[] = {
*/
.name = "Kodicom 4400R (slave)",
.video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .svhs = UNSET,
+ .svhs = NO_SVHS,
.gpiomask = 0x010000,
.no_gpioirq = 1,
- .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
+ .muxsel = MUXSEL(3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
.pll = PLL_28,
.no_msp34xx = 1,
.no_tda7432 = 1,
@@ -2728,27 +2504,23 @@ struct tvcard bttv_tvcards[] = {
/* Adlink RTV24 with special unlock codes */
.name = "Adlink RTV24",
.video_inputs = 4,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1, 0 },
+ .muxsel = MUXSEL(2, 3, 1, 0),
.tuner_type = UNSET,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
},
/* ---- card 0x87---------------------------------- */
[BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
/* Michael Krufky <mkrufky@m1k.net> */
.name = "DViCO FusionHDTV 5 Lite",
- .tuner = 0,
.tuner_type = TUNER_LG_TDVS_H06XF, /* TDVS-H064F */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.video_inputs = 3,
- .audio_inputs = 1,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
@@ -2762,75 +2534,68 @@ struct tvcard bttv_tvcards[] = {
/* Mauro Carvalho Chehab <mchehab@infradead.org> */
.name = "Acorp Y878F",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x01fe00,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
.gpiomute = 0x002000,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
.tuner_addr = 0xc1 >>1,
- .radio_addr = 0xc1 >>1,
.has_radio = 1,
},
/* ---- card 0x89 ---------------------------------- */
[BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
.name = "Conceptronic CTVFMi v2",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x001c0007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 },
.gpiomute = 3,
.needs_tvaudio = 0,
.pll = PLL_28,
.tuner_type = TUNER_TENA_9533_DI,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_remote = 1,
.has_radio = 1,
},
/* ---- card 0x8a ---------------------------------- */
[BTTV_BOARD_PV_BT878P_2E] = {
- .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
- .video_inputs = 5,
- .audio_inputs = 1,
- .tuner = 0,
- .svhs = 3,
- .gpiomask = 0x01fe00,
- .muxsel = { 2,3,1,1,-1 },
- .digital_mode = DIGITAL_MODE_CAMERA,
- .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
- .gpiomute = 0x12400,
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = TUNER_LG_PAL_FM,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- .has_remote = 1,
+ .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
+ .video_inputs = 5,
+ /* .audio_inputs= 1, */
+ .svhs = 3,
+ .has_dig_in = 1,
+ .gpiomask = 0x01fe00,
+ .muxsel = MUXSEL(2, 3, 1, 1, 0), /* in 4 is digital */
+ /* .digital_mode= DIGITAL_MODE_CAMERA, */
+ .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
+ .gpiomute = 0x12400,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_LG_PAL_FM,
+ .tuner_addr = ADDR_UNSET,
+ .has_remote = 1,
},
/* ---- card 0x8b ---------------------------------- */
[BTTV_BOARD_PV_M4900] = {
/* Sérgio Fortier <sergiofortier@yahoo.com.br> */
.name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x21, 0x20, 0x24, 0x2c },
.gpiomute = 0x29,
.no_msp34xx = 1,
.pll = PLL_28,
.tuner_type = TUNER_YMEC_TVF_5533MF,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.has_radio = 1,
.has_remote = 1,
},
@@ -2850,17 +2615,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_OSPREY440] = {
.name = "Osprey 440",
.video_inputs = 4,
- .audio_inputs = 2, /* this is meaningless */
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 2, 3, 0, 1 }, /* 3,0,1 are guesses */
+ /* .audio_inputs= 2, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(2, 3, 0, 1), /* 3,0,1 are guesses */
.gpiomask = 0x303,
.gpiomute = 0x000, /* int + 32kHz */
.gpiomux = { 0, 0, 0x000, 0x100},
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
@@ -2869,28 +2632,25 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_ASOUND_SKYEYE] = {
.name = "Asound Skyeye PCTV",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 15,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 2, 0, 0, 0 },
.gpiomute = 1,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_NTSC,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x8e ---------------------------------- */
[BTTV_BOARD_SABRENT_TVFM] = {
.name = "Sabrent TV-FM (bttv version)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x108007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 100000, 100002, 100002, 100000 },
.no_msp34xx = 1,
.no_tda9875 = 1,
@@ -2904,17 +2664,15 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
.name = "Hauppauge ImpactVCB (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x0f, /* old: 7 */
- .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */
+ .muxsel = MUXSEL(0, 1, 3, 2), /* Composite 0-3 */
.no_msp34xx = 1,
.no_tda9875 = 1,
.no_tda7432 = 1,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_MACHTV_MAGICTV] = {
/* Julian Calaby <julian.calaby@gmail.com>
@@ -2926,16 +2684,14 @@ struct tvcard bttv_tvcards[] = {
.name = "MagicTV", /* rebranded MachTV */
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 7,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 3 },
.gpiomute = 4,
.tuner_type = TUNER_TEMIC_4009FR5_PAL,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -2943,36 +2699,30 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_SSAI_SECURITY] = {
.name = "SSAI Security Video Interface",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .muxsel = { 0, 1, 2, 3 },
- .tuner_type = UNSET,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .muxsel = MUXSEL(0, 1, 2, 3),
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_SSAI_ULTRASOUND] = {
.name = "SSAI Ultrasound Video Interface",
.video_inputs = 2,
- .audio_inputs = 0,
- .tuner = UNSET,
+ /* .audio_inputs= 0, */
.svhs = 1,
- .muxsel = { 2, 0, 1, 3 },
- .tuner_type = UNSET,
+ .muxsel = MUXSEL(2, 0, 1, 3),
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
/* ---- card 0x94---------------------------------- */
[BTTV_BOARD_DVICO_FUSIONHDTV_2] = {
.name = "DViCO FusionHDTV 2",
- .tuner = 0,
.tuner_type = TUNER_PHILIPS_FCV1236D,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.video_inputs = 3,
- .audio_inputs = 1,
+ /* .audio_inputs= 1, */
.svhs = 2,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomask = 0x00e00007,
.gpiomux = { 0x00400005, 0, 0x00000001, 0 },
.gpiomute = 0x00c00007,
@@ -2984,36 +2734,31 @@ struct tvcard bttv_tvcards[] = {
[BTTV_BOARD_TYPHOON_TVTUNERPCI] = {
.name = "Typhoon TV-Tuner PCI (50684)",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x3014f,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0x20001,0x10001, 0, 0 },
.gpiomute = 10,
.needs_tvaudio = 1,
.pll = PLL_28,
.tuner_type = TUNER_PHILIPS_PAL_I,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_GEOVISION_GV600] = {
/* emhn@usb.ve */
- .name = "Geovision GV-600",
- .video_inputs = 16,
- .audio_inputs = 0,
- .tuner = UNSET,
- .svhs = UNSET,
- .gpiomask = 0x0,
- .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2 },
- .muxsel_hook = geovision_muxsel,
- .gpiomux = { 0 },
- .no_msp34xx = 1,
- .pll = PLL_28,
- .tuner_type = UNSET,
- .tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .name = "Geovision GV-600",
+ .video_inputs = 16,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0x0,
+ .muxsel = MUXSEL(2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2),
+ .muxsel_hook = geovision_muxsel,
+ .gpiomux = { 0 },
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
},
[BTTV_BOARD_KOZUMI_KTV_01C] = {
/* Mauro Lacy <mauro@lacy.com.ar>
@@ -3021,17 +2766,15 @@ struct tvcard bttv_tvcards[] = {
.name = "Kozumi KTV-01C",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
.gpiomask = 0x008007,
- .muxsel = { 2, 3, 1, 1 },
+ .muxsel = MUXSEL(2, 3, 1, 1),
.gpiomux = { 0, 1, 2, 2 }, /* CONTVFMi */
.gpiomute = 3, /* CONTVFMi */
.needs_tvaudio = 0,
.tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* TCL MK3 */
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -3041,8 +2784,7 @@ struct tvcard bttv_tvcards[] = {
Mauro Carvalho Chehab <mchehab@infradead.org */
.name = "Encore ENL TV-FM-2",
.video_inputs = 3,
- .audio_inputs = 1,
- .tuner = 0,
+ /* .audio_inputs= 1, */
.svhs = 2,
/* bit 6 -> IR disabled
bit 18/17 = 00 -> mute
@@ -3051,12 +2793,11 @@ struct tvcard bttv_tvcards[] = {
11 -> internal audio input
*/
.gpiomask = 0x060040,
- .muxsel = { 2, 3, 3 },
+ .muxsel = MUXSEL(2, 3, 3),
.gpiomux = { 0x60000, 0x60000, 0x20000, 0x20000 },
.gpiomute = 0,
.tuner_type = TUNER_TCL_MF02GIP_5N,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
.pll = PLL_28,
.has_radio = 1,
.has_remote = 1,
@@ -3065,50 +2806,111 @@ struct tvcard bttv_tvcards[] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
- .svhs = UNSET, /* card has no s-video */
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
.gpiomask = 0x00,
- .muxsel = { 0, 2, 3, 1 },
+ .muxsel = MUXSEL(0, 2, 3, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD012_X1] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X1 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 2, 3, 1 },
+ .muxsel = MUXSEL(2, 3, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
},
[BTTV_BOARD_VD012_X2] = {
/* D.Heer@Phytec.de */
.name = "PHYTEC VD-012-X2 (bt878)",
.video_inputs = 4,
- .audio_inputs = 0,
- .tuner = UNSET, /* card has no tuner */
+ /* .audio_inputs= 0, */
.svhs = 3,
.gpiomask = 0x00,
- .muxsel = { 3, 2, 1 },
+ .muxsel = MUXSEL(3, 2, 1),
.gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
.needs_tvaudio = 0,
.pll = PLL_28,
- .tuner_type = UNSET,
+ .tuner_type = TUNER_ABSENT,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
- }
+ },
+ [BTTV_BOARD_GEOVISION_GV800S] = {
+ /* Bruno Christo <bchristo@inf.ufsm.br>
+ *
+ * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
+ * 1 audio input per BT878A = 4 audio inputs
+ * 4 video inputs per BT878A = 16 video inputs
+ * This is the first BT878A chip of the GV-800(S). It's the
+ * "master" chip and it controls the video inputs through an
+ * analog multiplexer (a CD22M3494) via some GPIO pins. The
+ * slaves should use card type 0x9e (following this one).
+ * There is a EEPROM on the card which is currently not handled.
+ * The audio input is not working yet.
+ */
+ .name = "Geovision GV-800(S) (master)",
+ .video_inputs = 4,
+ /* .audio_inputs= 1, */
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = NO_SVHS,
+ .gpiomask = 0xf107f,
+ .no_gpioirq = 1,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda7432 = 1,
+ .no_tda9875 = 1,
+ .muxsel_hook = gv800s_muxsel,
+ },
+ [BTTV_BOARD_GEOVISION_GV800S_SL] = {
+ /* Bruno Christo <bchristo@inf.ufsm.br>
+ *
+ * GeoVision GV-800(S) has 4 Conexant Fusion 878A:
+ * 1 audio input per BT878A = 4 audio inputs
+ * 4 video inputs per BT878A = 16 video inputs
+ * The 3 other BT878A chips are "slave" chips of the GV-800(S)
+ * and should use this card type.
+ * The audio input is not working yet.
+ */
+ .name = "Geovision GV-800(S) (slave)",
+ .video_inputs = 4,
+ /* .audio_inputs= 1, */
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ .svhs = NO_SVHS,
+ .gpiomask = 0x00,
+ .no_gpioirq = 1,
+ .muxsel = MUXSEL(2, 2, 2, 2),
+ .pll = PLL_28,
+ .no_msp34xx = 1,
+ .no_tda7432 = 1,
+ .no_tda9875 = 1,
+ .muxsel_hook = gv800s_muxsel,
+ },
+ [BTTV_BOARD_PV183] = {
+ .name = "ProVideo PV183", /* 0x9f */
+ .video_inputs = 2,
+ /* .audio_inputs= 0, */
+ .svhs = NO_SVHS,
+ .gpiomask = 0,
+ .muxsel = MUXSEL(2, 3),
+ .gpiomux = { 0 },
+ .needs_tvaudio = 0,
+ .no_msp34xx = 1,
+ .pll = PLL_28,
+ .tuner_type = TUNER_ABSENT,
+ .tuner_addr = ADDR_UNSET,
+ },
};
static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
@@ -3152,7 +2954,7 @@ void __devinit bttv_idcard(struct bttv *btv)
btv->c.nr, btv->cardid & 0xffff,
(btv->cardid >> 16) & 0xffff);
printk(KERN_DEBUG "please mail id, board name and "
- "the correct card= insmod option to video4linux-list@redhat.com\n");
+ "the correct card= insmod option to linux-media@vger.kernel.org\n");
}
}
@@ -3403,8 +3205,7 @@ static void init_ids_eagle(struct bttv *btv)
* has its own multiplexer */
static void eagle_muxsel(struct bttv *btv, unsigned int input)
{
- btaor((2)<<5, ~(3<<5), BT848_IFORM);
- gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
+ gpio_bits(3, input & 3);
/* composite */
/* set chroma ADC to sleep */
@@ -3523,6 +3324,17 @@ void __devinit bttv_init_card1(struct bttv *btv)
/* initialization part two -- after registering i2c bus */
void __devinit bttv_init_card2(struct bttv *btv)
{
+ static const unsigned short tvaudio_addrs[] = {
+ I2C_ADDR_TDA8425 >> 1,
+ I2C_ADDR_TEA6300 >> 1,
+ I2C_ADDR_TEA6420 >> 1,
+ I2C_ADDR_TDA9840 >> 1,
+ I2C_ADDR_TDA985x_L >> 1,
+ I2C_ADDR_TDA985x_H >> 1,
+ I2C_ADDR_TDA9874 >> 1,
+ I2C_ADDR_PIC16C54 >> 1,
+ I2C_CLIENT_END
+ };
int addr=ADDR_UNSET;
btv->tuner_type = UNSET;
@@ -3629,6 +3441,9 @@ void __devinit bttv_init_card2(struct bttv *btv)
case BTTV_BOARD_KODICOM_4400R:
kodicom4400r_init(btv);
break;
+ case BTTV_BOARD_GEOVISION_GV800S:
+ gv800s_init(btv);
+ break;
}
/* pll configuration */
@@ -3670,13 +3485,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
addr = bttv_tvcards[btv->c.type].tuner_addr;
if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
- if(UNSET == btv->tuner_type)
+ if (UNSET == btv->tuner_type)
btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
if (UNSET != tuner[btv->c.nr])
btv->tuner_type = tuner[btv->c.nr];
- if (btv->tuner_type == TUNER_ABSENT ||
- bttv_tvcards[btv->c.type].tuner == UNSET)
+ if (btv->tuner_type == TUNER_ABSENT)
printk(KERN_INFO "bttv%d: tuner absent\n", btv->c.nr);
else if(btv->tuner_type == UNSET)
printk(KERN_WARNING "bttv%d: tuner type unset\n", btv->c.nr);
@@ -3684,14 +3498,35 @@ void __devinit bttv_init_card2(struct bttv *btv)
printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr,
btv->tuner_type);
- if (btv->tuner_type != UNSET) {
+ if (autoload != UNSET) {
+ printk(KERN_WARNING "bttv%d: the autoload option is obsolete.\n", btv->c.nr);
+ printk(KERN_WARNING "bttv%d: use option msp3400, tda7432 or tvaudio to\n", btv->c.nr);
+ printk(KERN_WARNING "bttv%d: override which audio module should be used.\n", btv->c.nr);
+ }
+
+ if (UNSET == btv->tuner_type)
+ btv->tuner_type = TUNER_ABSENT;
+
+ if (btv->tuner_type != TUNER_ABSENT) {
struct tuner_setup tun_setup;
+ /* Load tuner module before issuing tuner config call! */
+ if (bttv_tvcards[btv->c.type].has_radio)
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
+
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
tun_setup.type = btv->tuner_type;
tun_setup.addr = addr;
- bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+ if (bttv_tvcards[btv->c.type].has_radio)
+ tun_setup.mode_mask |= T_RADIO;
+
+ bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
}
if (btv->tda9887_conf) {
@@ -3700,10 +3535,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &btv->tda9887_conf;
- bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
+ bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
}
- btv->svhs = bttv_tvcards[btv->c.type].svhs;
+ btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
+ bttv_tvcards[btv->c.type].video_inputs - 1 : UNSET;
+ btv->svhs = bttv_tvcards[btv->c.type].svhs == NO_SVHS ?
+ UNSET : bttv_tvcards[btv->c.type].svhs;
if (svhs[btv->c.nr] != UNSET)
btv->svhs = svhs[btv->c.nr];
if (remote[btv->c.nr] != UNSET)
@@ -3720,34 +3558,127 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (bttv_tvcards[btv->c.type].audio_mode_gpio)
btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
- if (!autoload)
- return;
-
- if (bttv_tvcards[btv->c.type].tuner == UNSET)
+ if (btv->tuner_type == TUNER_ABSENT)
return; /* no tuner or related drivers to load */
+ if (btv->has_saa6588 || saa6588[btv->c.nr]) {
+ /* Probe for RDS receiver chip */
+ static const unsigned short addrs[] = {
+ 0x20 >> 1,
+ 0x22 >> 1,
+ I2C_CLIENT_END
+ };
+ struct v4l2_subdev *sd;
+
+ sd = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "saa6588", "saa6588", addrs);
+ btv->has_saa6588 = (sd != NULL);
+ }
+
/* try to detect audio/fader chips */
- if (!bttv_tvcards[btv->c.type].no_msp34xx &&
- bttv_I2CRead(btv, I2C_ADDR_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)
- request_module("msp3400");
+ /* First check if the user specified the audio chip via a module
+ option. */
+
+ switch (audiodev[btv->c.nr]) {
+ case -1:
+ return; /* do not load any audio module */
+
+ case 0: /* autodetect */
+ break;
+
+ case 1: {
+ /* The user specified that we should probe for msp3400 */
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400 >> 1,
+ I2C_ADDR_MSP3400_ALT >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ if (btv->sd_msp34xx)
+ return;
+ goto no_audio;
+ }
+
+ case 2: {
+ /* The user specified that we should probe for tda7432 */
+ static const unsigned short addrs[] = {
+ I2C_ADDR_TDA7432 >> 1,
+ I2C_CLIENT_END
+ };
+
+ if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tda7432", "tda7432", addrs))
+ return;
+ goto no_audio;
+ }
+
+ case 3: {
+ /* The user specified that we should probe for tvaudio */
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tvaudio", "tvaudio", tvaudio_addrs);
+ if (btv->sd_tvaudio)
+ return;
+ goto no_audio;
+ }
+
+ default:
+ printk(KERN_WARNING "bttv%d: unknown audiodev value!\n",
+ btv->c.nr);
+ return;
+ }
- if (!bttv_tvcards[btv->c.type].no_tda9875 &&
- bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0)
- request_module("tda9875");
+ /* There were no overrides, so now we try to discover this through the
+ card definition */
+
+ /* probe for msp3400 first: this driver can detect whether or not
+ it really is a msp3400, so it will return NULL when the device
+ found is really something else (e.g. a tea6300). */
+ if (!bttv_tvcards[btv->c.type].no_msp34xx) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400 >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400_ALT >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ }
- if (!bttv_tvcards[btv->c.type].no_tda7432 &&
- bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0)
- request_module("tda7432");
+ /* If we found a msp34xx, then we're done. */
+ if (btv->sd_msp34xx)
+ return;
- if (bttv_tvcards[btv->c.type].needs_tvaudio)
- request_module("tvaudio");
+ /* it might also be a tda7432. */
+ if (!bttv_tvcards[btv->c.type].no_tda7432) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_TDA7432 >> 1,
+ I2C_CLIENT_END
+ };
- if (btv->tuner_type != UNSET && btv->tuner_type != TUNER_ABSENT)
- request_module("tuner");
+ if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tda7432", "tda7432", addrs))
+ return;
+ }
+
+ /* Now see if we can find one of the tvaudio devices. */
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tvaudio", "tvaudio", tvaudio_addrs);
+ if (btv->sd_tvaudio)
+ return;
+
+no_audio:
+ printk(KERN_WARNING "bttv%d: audio absent, no audio device found!\n",
+ btv->c.nr);
}
@@ -3819,6 +3750,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
printk("bttv%d: Terratec Active Radio Upgrade found.\n",
btv->c.nr);
btv->has_radio = 1;
+ btv->has_saa6588 = 1;
btv->has_matchbox = 1;
} else {
btv->has_radio = 0;
@@ -4067,27 +3999,26 @@ static void __devinit avermedia_eeprom(struct bttv *btv)
btv->has_remote ? "yes" : "no");
}
-/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
-void bttv_tda9880_setnorm(struct bttv *btv, int norm)
+/*
+ * For Voodoo TV/FM and Voodoo 200. These cards' tuners use a TDA9880
+ * analog demod, which is not I2C controlled like the newer and more common
+ * TDA9887 series. Instead is has two tri-state input pins, S0 and S1,
+ * that control the IF for the video and audio. Apparently, bttv GPIO
+ * 0x10000 is connected to S0. S0 low selects a 38.9 MHz VIF for B/G/D/K/I
+ * (i.e., PAL) while high selects 45.75 MHz for M/N (i.e., NTSC).
+ */
+u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits)
{
- /* fix up our card entry */
- if(norm==V4L2_STD_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_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=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_200].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
- bttv_tvcards[BTTV_BOARD_VOODOOTV_200].gpiomute=0x947fff;
- dprintk("bttv_tda9880_setnorm to PAL\n");
+
+ if (btv->audio == TVAUDIO_INPUT_TUNER) {
+ if (bttv_tvnorms[btv->tvnorm].v4l2_id & V4L2_STD_MN)
+ gpiobits |= 0x10000;
+ else
+ gpiobits &= ~0x10000;
}
- /* set GPIO according */
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
- bttv_tvcards[btv->c.type].gpiomux[btv->audio]);
+
+ gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpiobits);
+ return gpiobits;
}
@@ -4463,6 +4394,11 @@ void tea5757_set_freq(struct bttv *btv, unsigned short freq)
*/
static void rv605_muxsel(struct bttv *btv, unsigned int input)
{
+ static const u8 muxgpio[] = { 0x3, 0x1, 0x2, 0x4, 0xf, 0x7, 0xe, 0x0,
+ 0xd, 0xb, 0xc, 0x6, 0x9, 0x5, 0x8, 0xa };
+
+ gpio_bits(0x07f, muxgpio[input]);
+
/* reset all conections */
gpio_bits(0x200,0x200);
mdelay(1);
@@ -4470,7 +4406,6 @@ static void rv605_muxsel(struct bttv *btv, unsigned int input)
mdelay(1);
/* create a new connection */
- gpio_bits(0x480,0x080);
gpio_bits(0x480,0x480);
mdelay(1);
gpio_bits(0x480,0x080);
@@ -4729,8 +4664,7 @@ static void ivc120_muxsel(struct bttv *btv, unsigned int input)
bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */
- /* Selects MUX0 for input on the 878 */
- btaor((0)<<5, ~(3<<5), BT848_IFORM);
+ /* 878's MUX0 is already selected for input via muxsel values */
}
@@ -4814,6 +4748,132 @@ static void PXC200_muxsel(struct bttv *btv, unsigned int input)
printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux);
}
+static void phytec_muxsel(struct bttv *btv, unsigned int input)
+{
+ unsigned int mux = input % 4;
+
+ if (input == btv->svhs)
+ mux = 0;
+
+ gpio_bits(0x3, mux);
+}
+
+/*
+ * GeoVision GV-800(S) functions
+ * Bruno Christo <bchristo@inf.ufsm.br>
+*/
+
+/* This is a function to control the analog switch, which determines which
+ * camera is routed to which controller. The switch comprises an X-address
+ * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
+ * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
+ * A data value (gpio bit 18) of '1' enables the switch, and '0' disables
+ * the switch. A STROBE bit (gpio bit 17) latches the data value into the
+ * specified address. There is also a chip select (gpio bit 16).
+ * The idea is to set the address and chip select together, bring
+ * STROBE high, write the data, and finally bring STROBE back to low.
+ */
+static void gv800s_write(struct bttv *btv,
+ unsigned char xaddr,
+ unsigned char yaddr,
+ unsigned char data) {
+ /* On the "master" 878A:
+ * GPIO bits 0-9 are used for the analog switch:
+ * 00 - 03: camera selector
+ * 04 - 06: 878A (controller) selector
+ * 16: cselect
+ * 17: strobe
+ * 18: data (1->on, 0->off)
+ * 19: reset
+ */
+ const u32 ADDRESS = ((xaddr&0xf) | (yaddr&3)<<4);
+ const u32 CSELECT = 1<<16;
+ const u32 STROBE = 1<<17;
+ const u32 DATA = data<<18;
+
+ gpio_bits(0x1007f, ADDRESS | CSELECT); /* write ADDRESS and CSELECT */
+ gpio_bits(0x20000, STROBE); /* STROBE high */
+ gpio_bits(0x40000, DATA); /* write DATA */
+ gpio_bits(0x20000, ~STROBE); /* STROBE low */
+}
+
+/*
+ * GeoVision GV-800(S) muxsel
+ *
+ * Each of the 4 cards (controllers) use this function.
+ * The controller using this function selects the input through the GPIO pins
+ * of the "master" card. A pointer to this card is stored in master[btv->c.nr].
+ *
+ * The parameter 'input' is the requested camera number (0-4) on the controller.
+ * The map array has the address of each input. Note that the addresses in the
+ * array are in the sequence the original GeoVision driver uses, that is, set
+ * every controller to input 0, then to input 1, 2, 3, repeat. This means that
+ * the physical "camera 1" connector corresponds to controller 0 input 0,
+ * "camera 2" corresponds to controller 1 input 0, and so on.
+ *
+ * After getting the input address, the function then writes the appropriate
+ * data to the analog switch, and housekeeps the local copy of the switch
+ * information.
+ */
+static void gv800s_muxsel(struct bttv *btv, unsigned int input)
+{
+ struct bttv *mctlr;
+ char *sw_status;
+ int xaddr, yaddr;
+ static unsigned int map[4][4] = { { 0x0, 0x4, 0xa, 0x6 },
+ { 0x1, 0x5, 0xb, 0x7 },
+ { 0x2, 0x8, 0xc, 0xe },
+ { 0x3, 0x9, 0xd, 0xf } };
+ input = input%4;
+ mctlr = master[btv->c.nr];
+ if (mctlr == NULL) {
+ /* do nothing until the "master" is detected */
+ return;
+ }
+ yaddr = (btv->c.nr - mctlr->c.nr) & 3;
+ sw_status = (char *)(&mctlr->mbox_we);
+ xaddr = map[yaddr][input] & 0xf;
+
+ /* Check if the controller/camera pair has changed, ignore otherwise */
+ if (sw_status[yaddr] != xaddr) {
+ /* disable the old switch, enable the new one and save status */
+ gv800s_write(mctlr, sw_status[yaddr], yaddr, 0);
+ sw_status[yaddr] = xaddr;
+ gv800s_write(mctlr, xaddr, yaddr, 1);
+ }
+}
+
+/* GeoVision GV-800(S) "master" chip init */
+static void gv800s_init(struct bttv *btv)
+{
+ char *sw_status = (char *)(&btv->mbox_we);
+ int ix;
+
+ gpio_inout(0xf107f, 0xf107f);
+ gpio_write(1<<19); /* reset the analog MUX */
+ gpio_write(0);
+
+ /* Preset camera 0 to the 4 controllers */
+ for (ix = 0; ix < 4; ix++) {
+ sw_status[ix] = ix;
+ gv800s_write(btv, ix, ix, 1);
+ }
+
+ /* Inputs on the "master" controller need this brightness fix */
+ bttv_I2CWrite(btv, 0x18, 0x5, 0x90, 1);
+
+ if (btv->c.nr > BTTV_MAX-4)
+ return;
+ /*
+ * Store the "master" controller pointer in the master
+ * array for later use in the muxsel function.
+ */
+ master[btv->c.nr] = btv;
+ master[btv->c.nr+1] = btv;
+ master[btv->c.nr+2] = btv;
+ master[btv->c.nr+3] = btv;
+}
+
/* ----------------------------------------------------------------------- */
/* motherboard chipset specific stuff */
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
index c71f394fc0e..7a8ca0d8356 100644
--- a/drivers/media/video/bt8xx/bttv-driver.c
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -58,7 +58,7 @@
unsigned int bttv_num; /* number of Bt848s in use */
-struct bttv bttvs[BTTV_MAX];
+struct bttv *bttvs[BTTV_MAX];
unsigned int bttv_debug;
unsigned int bttv_verbose = 1;
@@ -167,7 +167,7 @@ static ssize_t show_card(struct device *cd,
struct device_attribute *attr, char *buf)
{
struct video_device *vfd = container_of(cd, struct video_device, dev);
- struct bttv *btv = dev_get_drvdata(vfd->parent);
+ struct bttv *btv = video_get_drvdata(vfd);
return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
}
static DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
@@ -1040,7 +1040,7 @@ static void bt848A_set_timing(struct bttv *btv)
int table_idx = bttv_tvnorms[btv->tvnorm].sram;
int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
- if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
+ if (btv->input == btv->dig) {
dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
btv->c.nr,table_idx);
@@ -1142,7 +1142,7 @@ video_mux(struct bttv *btv, unsigned int input)
btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
}
- mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
+ mux = bttv_muxsel(btv, input);
btaor(mux<<5, ~(3<<5), BT848_IFORM);
dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
btv->c.nr,input,mux);
@@ -1163,7 +1163,6 @@ audio_mux(struct bttv *btv, int input, int mute)
{
int gpio_val, signal;
struct v4l2_control ctrl;
- struct i2c_client *c;
gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
bttv_tvcards[btv->c.type].gpiomask);
@@ -1180,7 +1179,16 @@ audio_mux(struct bttv *btv, int input, int mute)
else
gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
- gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+ switch (btv->c.type) {
+ case BTTV_BOARD_VOODOOTV_FM:
+ case BTTV_BOARD_VOODOOTV_200:
+ gpio_val = bttv_tda9880_setnorm(btv, gpio_val);
+ break;
+
+ default:
+ gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
+ }
+
if (bttv_gpio)
bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
if (in_interrupt())
@@ -1188,9 +1196,8 @@ audio_mux(struct bttv *btv, int input, int mute)
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) {
+ bttv_call_all(btv, core, s_ctrl, &ctrl);
+ if (btv->sd_msp34xx) {
struct v4l2_routing route;
/* Note: the inputs tuner/radio/extern/intern are translated
@@ -1229,15 +1236,14 @@ audio_mux(struct bttv *btv, int input, int mute)
break;
}
route.output = MSP_OUTPUT_DEFAULT;
- c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, &route);
}
- c = btv->i2c_tvaudio_client;
- if (c) {
+ if (btv->sd_tvaudio) {
struct v4l2_routing route;
route.input = input;
route.output = 0;
- c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, &route);
}
return 0;
}
@@ -1277,7 +1283,7 @@ bttv_crop_calc_limits(struct bttv_crop *c)
}
static void
-bttv_crop_reset(struct bttv_crop *c, int norm)
+bttv_crop_reset(struct bttv_crop *c, unsigned int norm)
{
c->rect = bttv_tvnorms[norm].cropcap.defrect;
bttv_crop_calc_limits(c);
@@ -1290,16 +1296,13 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
const struct bttv_tvnorm *tvnorm;
v4l2_std_id id;
- if (norm < 0 || norm >= BTTV_TVNORMS)
- return -EINVAL;
+ BUG_ON(norm >= BTTV_TVNORMS);
+ BUG_ON(btv->tvnorm >= BTTV_TVNORMS);
tvnorm = &bttv_tvnorms[norm];
- if (btv->tvnorm < 0 ||
- btv->tvnorm >= BTTV_TVNORMS ||
- 0 != memcmp(&bttv_tvnorms[btv->tvnorm].cropcap,
- &tvnorm->cropcap,
- sizeof (tvnorm->cropcap))) {
+ if (!memcmp(&bttv_tvnorms[btv->tvnorm].cropcap, &tvnorm->cropcap,
+ sizeof (tvnorm->cropcap))) {
bttv_crop_reset(&btv->crop[0], norm);
btv->crop[1] = btv->crop[0]; /* current = default */
@@ -1322,11 +1325,11 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
switch (btv->c.type) {
case BTTV_BOARD_VOODOOTV_FM:
case BTTV_BOARD_VOODOOTV_200:
- bttv_tda9880_setnorm(btv,norm);
+ bttv_tda9880_setnorm(btv, gpio_read());
break;
}
id = tvnorm->v4l2_id;
- bttv_call_i2c_clients(btv, VIDIOC_S_STD, &id);
+ bttv_call_all(btv, tuner, s_std, id);
return 0;
}
@@ -1350,8 +1353,8 @@ set_input(struct bttv *btv, unsigned int input, unsigned int norm)
} else {
video_mux(btv,input);
}
- audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
- TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
+ audio_input(btv, (btv->tuner_type != TUNER_ABSENT && input == 0) ?
+ TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN);
set_tvnorm(btv, norm);
}
@@ -1470,7 +1473,7 @@ static int bttv_g_ctrl(struct file *file, void *priv,
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- bttv_call_i2c_clients(btv, VIDIOC_G_CTRL, c);
+ bttv_call_all(btv, core, g_ctrl, c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1544,12 +1547,12 @@ static int bttv_s_ctrl(struct file *file, void *f,
if (btv->volume_gpio)
btv->volume_gpio(btv, c->value);
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+ bttv_call_all(btv, core, s_ctrl, c);
break;
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+ bttv_call_all(btv, core, s_ctrl, c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1888,20 +1891,15 @@ static int bttv_enum_input(struct file *file, void *priv,
{
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- unsigned int n;
-
- n = i->index;
+ int n;
- if (n >= bttv_tvcards[btv->c.type].video_inputs)
+ if (i->index >= bttv_tvcards[btv->c.type].video_inputs)
return -EINVAL;
- memset(i, 0, sizeof(*i));
-
- i->index = n;
i->type = V4L2_INPUT_TYPE_CAMERA;
i->audioset = 1;
- if (i->index == bttv_tvcards[btv->c.type].tuner) {
+ if (btv->tuner_type != TUNER_ABSENT && i->index == 0) {
sprintf(i->name, "Television");
i->type = V4L2_INPUT_TYPE_TUNER;
i->tuner = 0;
@@ -1965,14 +1963,14 @@ static int bttv_s_tuner(struct file *file, void *priv,
if (0 != err)
return err;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
mutex_lock(&btv->lock);
- bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t);
+ bttv_call_all(btv, tuner, s_tuner, t);
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 1);
@@ -2017,7 +2015,7 @@ static int bttv_s_frequency(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&btv->lock);
btv->freq = f->frequency;
- bttv_call_i2c_clients(btv, VIDIOC_S_FREQUENCY, f);
+ bttv_call_all(btv, tuner, s_frequency, f);
if (btv->has_matchbox && btv->radio_user)
tea5757_set_freq(btv, btv->freq);
mutex_unlock(&btv->lock);
@@ -2031,7 +2029,7 @@ static int bttv_log_status(struct file *file, void *f)
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);
+ bttv_call_all(btv, core, log_status);
printk(KERN_INFO "bttv%d: ======== END STATUS CARD #%d ========\n",
btv->c.nr, btv->c.nr);
return 0;
@@ -2659,8 +2657,7 @@ static int bttv_querycap(struct file *file, void *priv,
if (no_overlay <= 0)
cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
- if (bttv_tvcards[btv->c.type].tuner != UNSET &&
- bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
+ if (btv->tuner_type != TUNER_ABSENT)
cap->capabilities |= V4L2_CAP_TUNER;
return 0;
}
@@ -2927,13 +2924,9 @@ static int bttv_g_parm(struct file *file, void *f,
{
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- struct v4l2_standard s;
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
- bttv_tvnorms[btv->tvnorm].name);
- parm->parm.capture.timeperframe = s.frameperiod;
+ v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
+ &parm->parm.capture.timeperframe);
return 0;
}
@@ -2943,15 +2936,14 @@ static int bttv_g_tuner(struct file *file, void *priv,
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
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);
+ bttv_call_all(btv, tuner, g_tuner, t);
strcpy(t->name, "Television");
t->capability = V4L2_TUNER_CAP_NORM;
t->type = V4L2_TUNER_ANALOG_TV;
@@ -3212,29 +3204,19 @@ err:
static int bttv_open(struct file *file)
{
int minor = video_devdata(file)->minor;
- struct bttv *btv = NULL;
+ struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
enum v4l2_buf_type type = 0;
- unsigned int i;
dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
lock_kernel();
- for (i = 0; i < bttv_num; i++) {
- if (bttvs[i].video_dev &&
- bttvs[i].video_dev->minor == minor) {
- btv = &bttvs[i];
- type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- break;
- }
- if (bttvs[i].vbi_dev &&
- bttvs[i].vbi_dev->minor == minor) {
- btv = &bttvs[i];
- type = V4L2_BUF_TYPE_VBI_CAPTURE;
- break;
- }
- }
- if (NULL == btv) {
+ if (btv->video_dev->minor == minor) {
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ } else if (btv->vbi_dev->minor == minor) {
+ type = V4L2_BUF_TYPE_VBI_CAPTURE;
+ } else {
+ WARN_ON(1);
unlock_kernel();
return -ENODEV;
}
@@ -3424,20 +3406,14 @@ static struct video_device bttv_video_template = {
static int radio_open(struct file *file)
{
int minor = video_devdata(file)->minor;
- struct bttv *btv = NULL;
+ struct bttv *btv = video_drvdata(file);
struct bttv_fh *fh;
- unsigned int i;
dprintk("bttv: open minor=%d\n",minor);
lock_kernel();
- for (i = 0; i < bttv_num; i++) {
- if (bttvs[i].radio_dev && bttvs[i].radio_dev->minor == minor) {
- btv = &bttvs[i];
- break;
- }
- }
- if (NULL == btv) {
+ WARN_ON(btv->radio_dev && btv->radio_dev->minor != minor);
+ if (!btv->radio_dev || btv->radio_dev->minor != minor) {
unlock_kernel();
return -ENODEV;
}
@@ -3458,7 +3434,7 @@ static int radio_open(struct file *file)
btv->radio_user++;
- bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
+ bttv_call_all(btv, tuner, s_radio);
audio_input(btv,TVAUDIO_INPUT_RADIO);
mutex_unlock(&btv->lock);
@@ -3478,7 +3454,7 @@ static int radio_release(struct file *file)
btv->radio_user--;
- bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
return 0;
}
@@ -3503,16 +3479,15 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
struct bttv_fh *fh = priv;
struct bttv *btv = fh->btv;
- if (UNSET == bttv_tvcards[btv->c.type].tuner)
+ if (btv->tuner_type == TUNER_ABSENT)
return -EINVAL;
if (0 != t->index)
return -EINVAL;
mutex_lock(&btv->lock);
- memset(t, 0, sizeof(*t));
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 0);
@@ -3554,7 +3529,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
return 0;
}
@@ -3615,7 +3590,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
cmd.instance = file;
cmd.result = -ENODEV;
- bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd);
return cmd.result;
}
@@ -3628,7 +3603,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
cmd.instance = file;
cmd.event_list = wait;
cmd.result = -ENODEV;
- bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd);
return cmd.result;
}
@@ -3712,14 +3687,14 @@ static void bttv_risc_disasm(struct bttv *btv,
unsigned int i,j,n;
printk("%s: risc disasm: %p [dma=0x%08lx]\n",
- btv->c.name, risc->cpu, (unsigned long)risc->dma);
+ btv->c.v4l2_dev.name, risc->cpu, (unsigned long)risc->dma);
for (i = 0; i < (risc->size >> 2); i += n) {
- printk("%s: 0x%lx: ", btv->c.name,
+ printk("%s: 0x%lx: ", btv->c.v4l2_dev.name,
(unsigned long)(risc->dma + (i<<2)));
n = bttv_risc_decode(le32_to_cpu(risc->cpu[i]));
for (j = 1; j < n; j++)
printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
- btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
+ btv->c.v4l2_dev.name, (unsigned long)(risc->dma + ((i+j)<<2)),
risc->cpu[i+j], j);
if (0 == risc->cpu[i])
break;
@@ -4195,9 +4170,10 @@ static struct video_device *vdev_init(struct bttv *btv,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->parent = &btv->c.pci->dev;
+ vfd->v4l2_dev = &btv->c.v4l2_dev;
vfd->release = video_device_release;
vfd->debug = bttv_debug;
+ video_set_drvdata(vfd, btv);
snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
type_name, bttv_tvcards[btv->c.type].name);
@@ -4307,10 +4283,14 @@ static int __devinit bttv_probe(struct pci_dev *dev,
if (bttv_num == BTTV_MAX)
return -ENOMEM;
printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
- btv=&bttvs[bttv_num];
- memset(btv,0,sizeof(*btv));
+ bttvs[bttv_num] = btv = kzalloc(sizeof(*btv), GFP_KERNEL);
+ if (btv == NULL) {
+ printk(KERN_ERR "bttv: out of memory.\n");
+ return -ENOMEM;
+ }
btv->c.nr = bttv_num;
- sprintf(btv->c.name,"bttv%d",btv->c.nr);
+ snprintf(btv->c.v4l2_dev.name, sizeof(btv->c.v4l2_dev.name),
+ "bttv%d", btv->c.nr);
/* initialize structs / fill in defaults */
mutex_init(&btv->lock);
@@ -4347,7 +4327,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
}
if (!request_mem_region(pci_resource_start(dev,0),
pci_resource_len(dev,0),
- btv->c.name)) {
+ btv->c.v4l2_dev.name)) {
printk(KERN_WARNING "bttv%d: can't request iomem (0x%llx).\n",
btv->c.nr,
(unsigned long long)pci_resource_start(dev,0));
@@ -4355,7 +4335,12 @@ static int __devinit bttv_probe(struct pci_dev *dev,
}
pci_set_master(dev);
pci_set_command(dev);
- pci_set_drvdata(dev,btv);
+
+ result = v4l2_device_register(&dev->dev, &btv->c.v4l2_dev);
+ if (result < 0) {
+ printk(KERN_WARNING "bttv%d: v4l2_device_register() failed\n", btv->c.nr);
+ goto fail0;
+ }
pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
@@ -4379,7 +4364,7 @@ static int __devinit bttv_probe(struct pci_dev *dev,
/* disable irqs, register irq handler */
btwrite(0, BT848_INT_MASK);
result = request_irq(btv->c.pci->irq, bttv_irq,
- IRQF_SHARED | IRQF_DISABLED,btv->c.name,(void *)btv);
+ IRQF_SHARED | IRQF_DISABLED, btv->c.v4l2_dev.name, (void *)btv);
if (result < 0) {
printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
bttv_num,btv->c.pci->irq);
@@ -4463,21 +4448,24 @@ static int __devinit bttv_probe(struct pci_dev *dev,
bttv_num++;
return 0;
- fail2:
+fail2:
free_irq(btv->c.pci->irq,btv);
- fail1:
+fail1:
+ v4l2_device_unregister(&btv->c.v4l2_dev);
+
+fail0:
if (btv->bt848_mmio)
iounmap(btv->bt848_mmio);
release_mem_region(pci_resource_start(btv->c.pci,0),
pci_resource_len(btv->c.pci,0));
- pci_set_drvdata(dev,NULL);
return result;
}
static void __devexit bttv_remove(struct pci_dev *pci_dev)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct bttv *btv = to_bttv(v4l2_dev);
if (bttv_verbose)
printk("bttv%d: unloading\n",btv->c.nr);
@@ -4511,14 +4499,18 @@ static void __devexit bttv_remove(struct pci_dev *pci_dev)
release_mem_region(pci_resource_start(btv->c.pci,0),
pci_resource_len(btv->c.pci,0));
- pci_set_drvdata(pci_dev, NULL);
+ v4l2_device_unregister(&btv->c.v4l2_dev);
+ bttvs[btv->c.nr] = NULL;
+ kfree(btv);
+
return;
}
#ifdef CONFIG_PM
static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct bttv *btv = to_bttv(v4l2_dev);
struct bttv_buffer_set idle;
unsigned long flags;
@@ -4553,7 +4545,8 @@ static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
static int bttv_resume(struct pci_dev *pci_dev)
{
- struct bttv *btv = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct bttv *btv = to_bttv(v4l2_dev);
unsigned long flags;
int err;
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
index bcd2cd240a1..a99d92fac3d 100644
--- a/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -36,8 +36,6 @@
#include <linux/jiffies.h>
#include <asm/io.h>
-static int attach_inform(struct i2c_client *client);
-
static int i2c_debug;
static int i2c_hw;
static int i2c_scan;
@@ -231,7 +229,8 @@ bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
{
- struct bttv *btv = i2c_get_adapdata(i2c_adap);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
+ struct bttv *btv = to_bttv(v4l2_dev);
int retval = 0;
int i;
@@ -265,52 +264,6 @@ static const struct i2c_algorithm bttv_algo = {
/* ----------------------------------------------------------------------- */
/* I2C functions - common stuff */
-static int attach_inform(struct i2c_client *client)
-{
- struct bttv *btv = i2c_get_adapdata(client->adapter);
- int addr=ADDR_UNSET;
-
-
- if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
- addr = bttv_tvcards[btv->c.type].tuner_addr;
-
-
- if (bttv_debug)
- printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
- btv->c.nr, client->driver->driver.name, client->addr,
- client->name);
- 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;
-
- if ((addr==ADDR_UNSET) ||
- (addr==client->addr)) {
-
- tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
- tun_setup.type = btv->tuner_type;
- tun_setup.addr = addr;
- bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
- }
-
- }
-
- return 0;
-}
-
-void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
-{
- if (0 != btv->i2c_rc)
- return;
- i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
-}
-
-
/* read I2C */
int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
{
@@ -417,21 +370,15 @@ int __devinit init_bttv_i2c(struct bttv *btv)
btv->c.i2c_adap.algo_data = &btv->i2c_algo;
}
btv->c.i2c_adap.owner = THIS_MODULE;
- btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG;
- btv->c.i2c_adap.client_register = attach_inform;
btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
"bt%d #%d [%s]", btv->id, btv->c.nr,
btv->use_i2c_hw ? "hw" : "sw");
- i2c_set_adapdata(&btv->c.i2c_adap, btv);
+ i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);
btv->i2c_client.adapter = &btv->c.i2c_adap;
- if (bttv_tvcards[btv->c.type].no_video)
- btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
- if (bttv_tvcards[btv->c.type].has_dvb)
- btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
if (btv->use_i2c_hw) {
btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
@@ -441,7 +388,7 @@ int __devinit init_bttv_i2c(struct bttv *btv)
btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
}
if (0 == btv->i2c_rc && i2c_scan)
- do_i2c_scan(btv->c.name,&btv->i2c_client);
+ do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
return btv->i2c_rc;
}
diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bt8xx/bttv-if.c
index ecf07988cd3..a6a540dc9e4 100644
--- a/drivers/media/video/bt8xx/bttv-if.c
+++ b/drivers/media/video/bt8xx/bttv-if.c
@@ -47,7 +47,10 @@ struct pci_dev* bttv_get_pcidev(unsigned int card)
{
if (card >= bttv_num)
return NULL;
- return bttvs[card].c.pci;
+ if (!bttvs[card])
+ return NULL;
+
+ return bttvs[card]->c.pci;
}
@@ -59,7 +62,10 @@ int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
+
gpio_inout(mask,data);
if (bttv_gpio)
bttv_gpio_tracking(btv,"extern enable");
@@ -74,7 +80,9 @@ int bttv_read_gpio(unsigned int card, unsigned long *data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
if(btv->shutdown) {
return -ENODEV;
@@ -94,7 +102,9 @@ int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
return -EINVAL;
}
- btv = &bttvs[card];
+ btv = bttvs[card];
+ if (!btv)
+ return -ENODEV;
/* prior setting BT848_GPIO_REG_INP is (probably) not needed
because direct input is set on init */
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
index 5b1b8e4c78b..d16af283637 100644
--- a/drivers/media/video/bt8xx/bttv-risc.c
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -341,7 +341,7 @@ bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
int totalwidth = tvnorm->totalwidth;
int scaledtwidth = tvnorm->scaledtwidth;
- if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+ if (btv->input == btv->dig) {
swidth = 720;
totalwidth = 858;
scaledtwidth = 858;
@@ -391,7 +391,7 @@ bttv_calc_geo (struct bttv * btv,
&& crop->width == tvnorm->cropcap.defrect.width
&& crop->height == tvnorm->cropcap.defrect.height
&& width <= tvnorm->swidth /* see PAL-Nc et al */)
- || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
+ || btv->input == btv->dig) {
bttv_calc_geo_old(btv, geo, width, height,
both_fields, tvnorm);
return;
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
index 6819e21a377..e79a402fa6c 100644
--- a/drivers/media/video/bt8xx/bttv-vbi.c
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -411,7 +411,7 @@ int bttv_g_fmt_vbi_cap(struct file *file, void *f, struct v4l2_format *frt)
return 0;
}
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm)
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm)
{
const struct bttv_tvnorm *tvnorm;
unsigned int real_samples_per_line;
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
index 529bf6cf634..3d36daf206f 100644
--- a/drivers/media/video/bt8xx/bttv.h
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -14,8 +14,9 @@
#ifndef _BTTV_H_
#define _BTTV_H_
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
+#include <media/v4l2-device.h>
#include <media/ir-common.h>
#include <media/ir-kbd-i2c.h>
#include <media/i2c-addr.h>
@@ -180,6 +181,10 @@
#define BTTV_BOARD_VD012 0x99
#define BTTV_BOARD_VD012_X1 0x9a
#define BTTV_BOARD_VD012_X2 0x9b
+#define BTTV_BOARD_IVCE8784 0x9c
+#define BTTV_BOARD_GEOVISION_GV800S 0x9d
+#define BTTV_BOARD_GEOVISION_GV800S_SL 0x9e
+#define BTTV_BOARD_PV183 0x9f
/* more card-specific defines */
@@ -191,12 +196,9 @@
#define WINVIEW_PT2254_DATA 0x20
#define WINVIEW_PT2254_STROBE 0x80
-/* digital_mode */
-#define DIGITAL_MODE_VIDEO 1
-#define DIGITAL_MODE_CAMERA 2
-
struct bttv_core {
/* device structs */
+ struct v4l2_device v4l2_dev;
struct pci_dev *pci;
struct i2c_adapter i2c_adap;
struct list_head subs; /* struct bttv_sub_device */
@@ -204,59 +206,79 @@ struct bttv_core {
/* device config */
unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
unsigned int type; /* card type (pointer into tvcards[]) */
- char name[8]; /* dev name */
};
struct bttv;
-
-struct tvcard
-{
+struct tvcard {
char *name;
- unsigned int video_inputs;
- unsigned int audio_inputs;
- unsigned int tuner;
- unsigned int svhs;
- unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
+ void (*volume_gpio)(struct bttv *btv, __u16 volume);
+ void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
+ void (*muxsel_hook)(struct bttv *btv, unsigned int input);
+
+ /* MUX bits for each input, two bits per input starting with the LSB */
+ u32 muxsel; /* Use MUXSEL() to set */
+
u32 gpiomask;
- u32 muxsel[16];
u32 gpiomux[4]; /* Tuner, Radio, external, internal */
u32 gpiomute; /* GPIO mute setting */
u32 gpiomask2; /* GPIO MUX mask */
+ unsigned int tuner_type;
+ u8 tuner_addr;
+ u8 video_inputs; /* Number of inputs */
+ unsigned int svhs:4; /* Which input is s-video */
+#define NO_SVHS 15
+ unsigned int pll:2;
+#define PLL_NONE 0
+#define PLL_28 1
+#define PLL_35 2
+
/* i2c audio flags */
unsigned int no_msp34xx:1;
unsigned int no_tda9875:1;
unsigned int no_tda7432:1;
unsigned int needs_tvaudio:1;
unsigned int msp34xx_alt:1;
+ /* Note: currently no card definition needs to mark the presence
+ of a RDS saa6588 chip. If this is ever needed, then add a new
+ 'has_saa6588' bit here. */
- /* flag: video pci function is unused */
- unsigned int no_video:1;
+ unsigned int no_video:1; /* video pci function is unused */
unsigned int has_dvb:1;
unsigned int has_remote:1;
+ unsigned int has_radio:1;
+ unsigned int has_dig_in:1; /* Has digital input (always last input) */
unsigned int no_gpioirq:1;
-
- /* other settings */
- unsigned int pll;
-#define PLL_NONE 0
-#define PLL_28 1
-#define PLL_35 2
-
- unsigned int tuner_type;
- unsigned int tuner_addr;
- unsigned int radio_addr;
-
- unsigned int has_radio;
-
- void (*volume_gpio)(struct bttv *btv, __u16 volume);
- void (*audio_mode_gpio)(struct bttv *btv, struct v4l2_tuner *tuner, int set);
-
- void (*muxsel_hook)(struct bttv *btv, unsigned int input);
};
extern struct tvcard bttv_tvcards[];
+/*
+ * This bit of cpp voodoo is used to create a macro with a variable number of
+ * arguments (1 to 16). It will pack each argument into a word two bits at a
+ * time. It can't be a function because it needs to be compile time constant to
+ * initialize structures. Since each argument must fit in two bits, it's ok
+ * that they are changed to octal. One should not use hex number, macros, or
+ * anything else with this macro. Just use plain integers from 0 to 3.
+ */
+#define _MUXSELf(a) 0##a << 30
+#define _MUXSELe(a, b...) 0##a << 28 | _MUXSELf(b)
+#define _MUXSELd(a, b...) 0##a << 26 | _MUXSELe(b)
+#define _MUXSELc(a, b...) 0##a << 24 | _MUXSELd(b)
+#define _MUXSELb(a, b...) 0##a << 22 | _MUXSELc(b)
+#define _MUXSELa(a, b...) 0##a << 20 | _MUXSELb(b)
+#define _MUXSEL9(a, b...) 0##a << 18 | _MUXSELa(b)
+#define _MUXSEL8(a, b...) 0##a << 16 | _MUXSEL9(b)
+#define _MUXSEL7(a, b...) 0##a << 14 | _MUXSEL8(b)
+#define _MUXSEL6(a, b...) 0##a << 12 | _MUXSEL7(b)
+#define _MUXSEL5(a, b...) 0##a << 10 | _MUXSEL6(b)
+#define _MUXSEL4(a, b...) 0##a << 8 | _MUXSEL5(b)
+#define _MUXSEL3(a, b...) 0##a << 6 | _MUXSEL4(b)
+#define _MUXSEL2(a, b...) 0##a << 4 | _MUXSEL3(b)
+#define _MUXSEL1(a, b...) 0##a << 2 | _MUXSEL2(b)
+#define MUXSEL(a, b...) (a | _MUXSEL1(b))
+
/* identification / initialization of the card */
extern void bttv_idcard(struct bttv *btv);
extern void bttv_init_card1(struct bttv *btv);
@@ -264,7 +286,7 @@ extern void bttv_init_card2(struct bttv *btv);
/* card-specific funtions */
extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
-extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
+extern u32 bttv_tda9880_setnorm(struct bttv *btv, u32 gpiobits);
/* extra tweaks for some chipsets */
extern void bttv_check_chipset(void);
@@ -336,7 +358,9 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);
/* ---------------------------------------------------------- */
/* i2c */
-extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
+#define bttv_call_all(btv, o, f, args...) \
+ v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args)
+
extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
unsigned char b2, int both);
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
index 199a4d225ca..96498489199 100644
--- a/drivers/media/video/bt8xx/bttvp.h
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -32,7 +32,6 @@
#include <linux/wait.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
#include <linux/pci.h>
#include <linux/input.h>
#include <linux/mutex.h>
@@ -135,7 +134,7 @@ struct bttv_buffer {
/* bttv specific */
const struct bttv_format *fmt;
- int tvnorm;
+ unsigned int tvnorm;
int btformat;
int btswap;
struct bttv_geometry geo;
@@ -154,7 +153,7 @@ struct bttv_buffer_set {
};
struct bttv_overlay {
- int tvnorm;
+ unsigned int tvnorm;
struct v4l2_rect w;
enum v4l2_field field;
struct v4l2_clip *clips;
@@ -174,7 +173,7 @@ struct bttv_vbi_fmt {
};
/* bttv-vbi.c */
-void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, int norm);
+void bttv_vbi_fmt_reset(struct bttv_vbi_fmt *f, unsigned int norm);
struct bttv_crop {
/* A cropping rectangle in struct bttv_tvnorm.cropcap units. */
@@ -329,7 +328,8 @@ struct bttv {
unsigned int cardid; /* pci subsystem id (bt878 based ones) */
unsigned int tuner_type; /* tuner chip type */
unsigned int tda9887_conf;
- unsigned int svhs;
+ unsigned int svhs, dig;
+ unsigned int has_saa6588:1;
struct bttv_pll_info pll;
int triton1;
int gpioirq;
@@ -353,8 +353,8 @@ 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;
+ struct v4l2_subdev *sd_msp34xx;
+ struct v4l2_subdev *sd_tvaudio;
/* video4linux (1) */
struct video_device *video_dev;
@@ -378,7 +378,8 @@ struct bttv {
unsigned int audio;
unsigned int mute;
unsigned long freq;
- int tvnorm,hue,contrast,bright,saturation;
+ unsigned int tvnorm;
+ int hue, contrast, bright, saturation;
struct v4l2_framebuffer fbuf;
unsigned int field_count;
@@ -458,10 +459,21 @@ struct bttv {
__s32 crop_start;
};
+static inline struct bttv *to_bttv(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct bttv, c.v4l2_dev);
+}
+
/* our devices */
#define BTTV_MAX 32
extern unsigned int bttv_num;
-extern struct bttv bttvs[BTTV_MAX];
+extern struct bttv *bttvs[BTTV_MAX];
+
+static inline unsigned int bttv_muxsel(const struct bttv *btv,
+ unsigned int input)
+{
+ return (bttv_tvcards[btv->c.type].muxsel >> (input * 2)) & 3;
+}
#endif
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 46fd573a4f1..7abe94d9fb4 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -11,6 +11,12 @@
*
* Written by Jonathan Corbet, corbet@lwn.net.
*
+ * v4l2_device/v4l2_subdev conversion by:
+ * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: this conversion is untested! Please contact the linux-media
+ * mailinglist if you can test this, together with the test results.
+ *
* This file may be distributed under the terms of the GNU General
* Public License, version 2.
*/
@@ -25,7 +31,7 @@
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-chip-ident.h>
#include <linux/device.h>
@@ -33,7 +39,6 @@
#include <linux/list.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
-#include <linux/debugfs.h>
#include <linux/jiffies.h>
#include <linux/vmalloc.h>
@@ -136,6 +141,7 @@ struct cafe_sio_buffer {
*/
struct cafe_camera
{
+ struct v4l2_device v4l2_dev;
enum cafe_state state;
unsigned long flags; /* Buffer status, mainly (dev_lock) */
int users; /* How many open FDs */
@@ -145,9 +151,10 @@ struct cafe_camera
* Subsystem structures.
*/
struct pci_dev *pdev;
- struct video_device v4ldev;
+ struct video_device vdev;
struct i2c_adapter i2c_adapter;
- struct i2c_client *sensor;
+ struct v4l2_subdev *sensor;
+ unsigned short sensor_addr;
unsigned char __iomem *regs;
struct list_head dev_list; /* link to other devices */
@@ -180,10 +187,6 @@ struct cafe_camera
/* Misc */
wait_queue_head_t smbus_wait; /* Waiting on i2c events */
wait_queue_head_t iowait; /* Waiting on frame data */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct dentry *dfs_regs;
- struct dentry *dfs_cam_regs;
-#endif
};
/*
@@ -195,6 +198,13 @@ struct cafe_camera
#define CF_DMA_ACTIVE 3 /* A frame is incoming */
#define CF_CONFIG_NEEDED 4 /* Must configure hardware */
+#define sensor_call(cam, o, f, args...) \
+ v4l2_subdev_call(cam->sensor, o, f, ##args)
+
+static inline struct cafe_camera *to_cam(struct v4l2_device *dev)
+{
+ return container_of(dev, struct cafe_camera, v4l2_dev);
+}
/*
@@ -238,59 +248,7 @@ static void cafe_set_config_needed(struct cafe_camera *cam, int needed)
/* ---------------------------------------------------------------------*/
-/*
- * We keep a simple list of known devices to search at open time.
- */
-static LIST_HEAD(cafe_dev_list);
-static DEFINE_MUTEX(cafe_dev_list_lock);
-
-static void cafe_add_dev(struct cafe_camera *cam)
-{
- mutex_lock(&cafe_dev_list_lock);
- list_add_tail(&cam->dev_list, &cafe_dev_list);
- mutex_unlock(&cafe_dev_list_lock);
-}
-
-static void cafe_remove_dev(struct cafe_camera *cam)
-{
- mutex_lock(&cafe_dev_list_lock);
- list_del(&cam->dev_list);
- mutex_unlock(&cafe_dev_list_lock);
-}
-
-static struct cafe_camera *cafe_find_dev(int minor)
-{
- struct cafe_camera *cam;
-
- mutex_lock(&cafe_dev_list_lock);
- list_for_each_entry(cam, &cafe_dev_list, dev_list) {
- if (cam->v4ldev.minor == minor)
- goto done;
- }
- cam = NULL;
- done:
- mutex_unlock(&cafe_dev_list_lock);
- return cam;
-}
-
-
-static struct cafe_camera *cafe_find_by_pdev(struct pci_dev *pdev)
-{
- struct cafe_camera *cam;
- mutex_lock(&cafe_dev_list_lock);
- list_for_each_entry(cam, &cafe_dev_list, dev_list) {
- if (cam->pdev == pdev)
- goto done;
- }
- cam = NULL;
- done:
- mutex_unlock(&cafe_dev_list_lock);
- return cam;
-}
-
-
-/* ------------------------------------------------------------------------ */
/*
* Device register I/O
*/
@@ -481,18 +439,11 @@ static int cafe_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
unsigned short flags, char rw, u8 command,
int size, union i2c_smbus_data *data)
{
- struct cafe_camera *cam = i2c_get_adapdata(adapter);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
int ret = -EINVAL;
/*
- * Refuse to talk to anything but OV cam chips. We should
- * never even see an attempt to do so, but one never knows.
- */
- if (cam->sensor && addr != cam->sensor->addr) {
- cam_err(cam, "funky smbus addr %d\n", addr);
- return -EINVAL;
- }
- /*
* This interface would appear to only do byte data ops. OK
* it can do word too, but the cam chip has no use for that.
*/
@@ -530,38 +481,9 @@ static struct i2c_algorithm cafe_smbus_algo = {
};
/* Somebody is on the bus */
-static int cafe_cam_init(struct cafe_camera *cam);
static void cafe_ctlr_stop_dma(struct cafe_camera *cam);
static void cafe_ctlr_power_down(struct cafe_camera *cam);
-static int cafe_smbus_attach(struct i2c_client *client)
-{
- struct cafe_camera *cam = i2c_get_adapdata(client->adapter);
-
- /*
- * Don't talk to chips we don't recognize.
- */
- if (client->driver->id == I2C_DRIVERID_OV7670) {
- cam->sensor = client;
- return cafe_cam_init(cam);
- }
- return -EINVAL;
-}
-
-static int cafe_smbus_detach(struct i2c_client *client)
-{
- struct cafe_camera *cam = i2c_get_adapdata(client->adapter);
-
- if (cam->sensor == client) {
- cafe_ctlr_stop_dma(cam);
- cafe_ctlr_power_down(cam);
- cam_err(cam, "lost the sensor!\n");
- cam->sensor = NULL; /* Bummer, no camera */
- cam->state = S_NOTREADY;
- }
- return 0;
-}
-
static int cafe_smbus_setup(struct cafe_camera *cam)
{
struct i2c_adapter *adap = &cam->i2c_adapter;
@@ -570,12 +492,10 @@ static int cafe_smbus_setup(struct cafe_camera *cam)
cafe_smbus_enable_irq(cam);
adap->id = I2C_HW_SMBUS_CAFE;
adap->owner = THIS_MODULE;
- adap->client_register = cafe_smbus_attach;
- adap->client_unregister = cafe_smbus_detach;
adap->algo = &cafe_smbus_algo;
strcpy(adap->name, "cafe_ccic");
adap->dev.parent = &cam->pdev->dev;
- i2c_set_adapdata(adap, cam);
+ i2c_set_adapdata(adap, &cam->v4l2_dev);
ret = i2c_add_adapter(adap);
if (ret)
printk(KERN_ERR "Unable to register cafe i2c adapter\n");
@@ -809,9 +729,9 @@ static void cafe_ctlr_power_up(struct cafe_camera *cam)
* Control 1 is power down, set to 0 to operate.
*/
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN); /* pwr up, reset */
-// mdelay(1); /* Marvell says 1ms will do it */
+/* mdelay(1); */ /* Marvell says 1ms will do it */
cafe_reg_write(cam, REG_GPR, GPR_C1EN|GPR_C0EN|GPR_C0);
-// mdelay(1); /* Enough? */
+/* mdelay(1); */ /* Enough? */
spin_unlock_irqrestore(&cam->dev_lock, flags);
msleep(5); /* Just to be sure */
}
@@ -833,23 +753,9 @@ static void cafe_ctlr_power_down(struct cafe_camera *cam)
* Communications with the sensor.
*/
-static int __cafe_cam_cmd(struct cafe_camera *cam, int cmd, void *arg)
-{
- struct i2c_client *sc = cam->sensor;
- int ret;
-
- if (sc == NULL || sc->driver == NULL || sc->driver->command == NULL)
- return -EINVAL;
- ret = sc->driver->command(sc, cmd, arg);
- if (ret == -EPERM) /* Unsupported command */
- return 0;
- return ret;
-}
-
static int __cafe_cam_reset(struct cafe_camera *cam)
{
- int zero = 0;
- return __cafe_cam_cmd(cam, VIDIOC_INT_RESET, &zero);
+ return sensor_call(cam, core, reset, 0);
}
/*
@@ -869,14 +775,13 @@ static int cafe_cam_init(struct cafe_camera *cam)
if (ret)
goto out;
chip.match.type = V4L2_CHIP_MATCH_I2C_ADDR;
- chip.match.addr = cam->sensor->addr;
- ret = __cafe_cam_cmd(cam, VIDIOC_DBG_G_CHIP_IDENT, &chip);
+ chip.match.addr = cam->sensor_addr;
+ ret = sensor_call(cam, core, g_chip_ident, &chip);
if (ret)
goto out;
cam->sensor_type = chip.ident;
-// if (cam->sensor->addr != OV7xx0_SID) {
if (cam->sensor_type != V4L2_IDENT_OV7670) {
- cam_err(cam, "Unsupported sensor type %d", cam->sensor->addr);
+ cam_err(cam, "Unsupported sensor type 0x%x", cam->sensor_type);
ret = -EINVAL;
goto out;
}
@@ -900,21 +805,21 @@ static int cafe_cam_set_flip(struct cafe_camera *cam)
memset(&ctrl, 0, sizeof(ctrl));
ctrl.id = V4L2_CID_VFLIP;
ctrl.value = flip;
- return __cafe_cam_cmd(cam, VIDIOC_S_CTRL, &ctrl);
+ return sensor_call(cam, core, s_ctrl, &ctrl);
}
static int cafe_cam_configure(struct cafe_camera *cam)
{
struct v4l2_format fmt;
- int ret, zero = 0;
+ int ret;
if (cam->state != S_IDLE)
return -EINVAL;
fmt.fmt.pix = cam->pix_format;
- ret = __cafe_cam_cmd(cam, VIDIOC_INT_INIT, &zero);
+ ret = sensor_call(cam, core, init, 0);
if (ret == 0)
- ret = __cafe_cam_cmd(cam, VIDIOC_S_FMT, &fmt);
+ ret = sensor_call(cam, video, s_fmt, &fmt);
/*
* OV7670 does weird things if flip is set *before* format...
*/
@@ -1246,8 +1151,6 @@ static int cafe_vidioc_reqbufs(struct file *filp, void *priv,
* Make sure it's something we can do. User pointers could be
* implemented without great pain, but that's not been done yet.
*/
- if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (req->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
/*
@@ -1311,9 +1214,7 @@ static int cafe_vidioc_querybuf(struct file *filp, void *priv,
int ret = -EINVAL;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out;
- if (buf->index < 0 || buf->index >= cam->n_sbufs)
+ if (buf->index >= cam->n_sbufs)
goto out;
*buf = cam->sb_bufs[buf->index].v4lbuf;
ret = 0;
@@ -1331,9 +1232,7 @@ static int cafe_vidioc_qbuf(struct file *filp, void *priv,
unsigned long flags;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out;
- if (buf->index < 0 || buf->index >= cam->n_sbufs)
+ if (buf->index >= cam->n_sbufs)
goto out;
sbuf = cam->sb_bufs + buf->index;
if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) {
@@ -1364,8 +1263,6 @@ static int cafe_vidioc_dqbuf(struct file *filp, void *priv,
unsigned long flags;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out_unlock;
if (cam->state != S_STREAMING)
goto out_unlock;
if (list_empty(&cam->sb_full) && filp->f_flags & O_NONBLOCK) {
@@ -1474,11 +1371,8 @@ static int cafe_v4l_mmap(struct file *filp, struct vm_area_struct *vma)
static int cafe_v4l_open(struct file *filp)
{
- struct cafe_camera *cam;
+ struct cafe_camera *cam = video_drvdata(filp);
- cam = cafe_find_dev(video_devdata(filp)->minor);
- if (cam == NULL)
- return -ENODEV;
filp->private_data = cam;
mutex_lock(&cam->s_mutex);
@@ -1532,11 +1426,11 @@ static unsigned int cafe_v4l_poll(struct file *filp,
static int cafe_vidioc_queryctrl(struct file *filp, void *priv,
struct v4l2_queryctrl *qc)
{
- struct cafe_camera *cam = filp->private_data;
+ struct cafe_camera *cam = priv;
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_QUERYCTRL, qc);
+ ret = sensor_call(cam, core, queryctrl, qc);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1545,11 +1439,11 @@ static int cafe_vidioc_queryctrl(struct file *filp, void *priv,
static int cafe_vidioc_g_ctrl(struct file *filp, void *priv,
struct v4l2_control *ctrl)
{
- struct cafe_camera *cam = filp->private_data;
+ struct cafe_camera *cam = priv;
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_G_CTRL, ctrl);
+ ret = sensor_call(cam, core, g_ctrl, ctrl);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1558,11 +1452,11 @@ static int cafe_vidioc_g_ctrl(struct file *filp, void *priv,
static int cafe_vidioc_s_ctrl(struct file *filp, void *priv,
struct v4l2_control *ctrl)
{
- struct cafe_camera *cam = filp->private_data;
+ struct cafe_camera *cam = priv;
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_S_CTRL, ctrl);
+ ret = sensor_call(cam, core, s_ctrl, ctrl);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1601,10 +1495,8 @@ static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp,
struct cafe_camera *cam = priv;
int ret;
- if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_ENUM_FMT, fmt);
+ ret = sensor_call(cam, video, enum_fmt, fmt);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1617,7 +1509,7 @@ static int cafe_vidioc_try_fmt_vid_cap(struct file *filp, void *priv,
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_TRY_FMT, fmt);
+ ret = sensor_call(cam, video, try_fmt, fmt);
mutex_unlock(&cam->s_mutex);
return ret;
}
@@ -1726,7 +1618,7 @@ static int cafe_vidioc_g_parm(struct file *filp, void *priv,
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_G_PARM, parms);
+ ret = sensor_call(cam, video, g_parm, parms);
mutex_unlock(&cam->s_mutex);
parms->parm.capture.readbuffers = n_dma_bufs;
return ret;
@@ -1739,20 +1631,52 @@ static int cafe_vidioc_s_parm(struct file *filp, void *priv,
int ret;
mutex_lock(&cam->s_mutex);
- ret = __cafe_cam_cmd(cam, VIDIOC_S_PARM, parms);
+ ret = sensor_call(cam, video, s_parm, parms);
mutex_unlock(&cam->s_mutex);
parms->parm.capture.readbuffers = n_dma_bufs;
return ret;
}
+static int cafe_vidioc_g_chip_ident(struct file *file, void *priv,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct cafe_camera *cam = priv;
-static void cafe_v4l_dev_release(struct video_device *vd)
+ chip->ident = V4L2_IDENT_NONE;
+ chip->revision = 0;
+ if (v4l2_chip_match_host(&chip->match)) {
+ chip->ident = V4L2_IDENT_CAFE;
+ return 0;
+ }
+ return sensor_call(cam, core, g_chip_ident, chip);
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cafe_vidioc_g_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
{
- struct cafe_camera *cam = container_of(vd, struct cafe_camera, v4ldev);
+ struct cafe_camera *cam = priv;
- kfree(cam);
+ if (v4l2_chip_match_host(&reg->match)) {
+ reg->val = cafe_reg_read(cam, reg->reg);
+ reg->size = 4;
+ return 0;
+ }
+ return sensor_call(cam, core, g_register, reg);
}
+static int cafe_vidioc_s_register(struct file *file, void *priv,
+ struct v4l2_dbg_register *reg)
+{
+ struct cafe_camera *cam = priv;
+
+ if (v4l2_chip_match_host(&reg->match)) {
+ cafe_reg_write(cam, reg->reg, reg->val);
+ return 0;
+ }
+ return sensor_call(cam, core, s_register, reg);
+}
+#endif
/*
* This template device holds all of those v4l2 methods; we
@@ -1790,6 +1714,11 @@ static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = {
.vidioc_s_ctrl = cafe_vidioc_s_ctrl,
.vidioc_g_parm = cafe_vidioc_g_parm,
.vidioc_s_parm = cafe_vidioc_s_parm,
+ .vidioc_g_chip_ident = cafe_vidioc_g_chip_ident,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .vidioc_g_register = cafe_vidioc_g_register,
+ .vidioc_s_register = cafe_vidioc_s_register,
+#endif
};
static struct video_device cafe_v4l_template = {
@@ -1800,15 +1729,10 @@ static struct video_device cafe_v4l_template = {
.fops = &cafe_v4l_fops,
.ioctl_ops = &cafe_v4l_ioctl_ops,
- .release = cafe_v4l_dev_release,
+ .release = video_device_release_empty,
};
-
-
-
-
-
/* ---------------------------------------------------------------------- */
/*
* Interrupt handler stuff
@@ -1962,127 +1886,6 @@ static irqreturn_t cafe_irq(int irq, void *data)
/* -------------------------------------------------------------------------- */
-#ifdef CONFIG_VIDEO_ADV_DEBUG
-/*
- * Debugfs stuff.
- */
-
-static char cafe_debug_buf[1024];
-static struct dentry *cafe_dfs_root;
-
-static void cafe_dfs_setup(void)
-{
- cafe_dfs_root = debugfs_create_dir("cafe_ccic", NULL);
- if (IS_ERR(cafe_dfs_root)) {
- cafe_dfs_root = NULL; /* Never mind */
- printk(KERN_NOTICE "cafe_ccic unable to set up debugfs\n");
- }
-}
-
-static void cafe_dfs_shutdown(void)
-{
- if (cafe_dfs_root)
- debugfs_remove(cafe_dfs_root);
-}
-
-static int cafe_dfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
-static ssize_t cafe_dfs_read_regs(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
-{
- struct cafe_camera *cam = file->private_data;
- char *s = cafe_debug_buf;
- int offset;
-
- for (offset = 0; offset < 0x44; offset += 4)
- s += sprintf(s, "%02x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- for (offset = 0x88; offset <= 0x90; offset += 4)
- s += sprintf(s, "%02x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- for (offset = 0xb4; offset <= 0xbc; offset += 4)
- s += sprintf(s, "%02x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- for (offset = 0x3000; offset <= 0x300c; offset += 4)
- s += sprintf(s, "%04x: %08x\n", offset,
- cafe_reg_read(cam, offset));
- return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
- s - cafe_debug_buf);
-}
-
-static const struct file_operations cafe_dfs_reg_ops = {
- .owner = THIS_MODULE,
- .read = cafe_dfs_read_regs,
- .open = cafe_dfs_open
-};
-
-static ssize_t cafe_dfs_read_cam(struct file *file,
- char __user *buf, size_t count, loff_t *ppos)
-{
- struct cafe_camera *cam = file->private_data;
- char *s = cafe_debug_buf;
- int offset;
-
- if (! cam->sensor)
- return -EINVAL;
- for (offset = 0x0; offset < 0x8a; offset++)
- {
- u8 v;
-
- cafe_smbus_read_data(cam, cam->sensor->addr, offset, &v);
- s += sprintf(s, "%02x: %02x\n", offset, v);
- }
- return simple_read_from_buffer(buf, count, ppos, cafe_debug_buf,
- s - cafe_debug_buf);
-}
-
-static const struct file_operations cafe_dfs_cam_ops = {
- .owner = THIS_MODULE,
- .read = cafe_dfs_read_cam,
- .open = cafe_dfs_open
-};
-
-
-
-static void cafe_dfs_cam_setup(struct cafe_camera *cam)
-{
- char fname[40];
-
- if (!cafe_dfs_root)
- return;
- sprintf(fname, "regs-%d", cam->v4ldev.num);
- cam->dfs_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
- cam, &cafe_dfs_reg_ops);
- sprintf(fname, "cam-%d", cam->v4ldev.num);
- cam->dfs_cam_regs = debugfs_create_file(fname, 0444, cafe_dfs_root,
- cam, &cafe_dfs_cam_ops);
-}
-
-
-static void cafe_dfs_cam_shutdown(struct cafe_camera *cam)
-{
- if (! IS_ERR(cam->dfs_regs))
- debugfs_remove(cam->dfs_regs);
- if (! IS_ERR(cam->dfs_cam_regs))
- debugfs_remove(cam->dfs_cam_regs);
-}
-
-#else
-
-#define cafe_dfs_setup()
-#define cafe_dfs_shutdown()
-#define cafe_dfs_cam_setup(cam)
-#define cafe_dfs_cam_shutdown(cam)
-#endif /* CONFIG_VIDEO_ADV_DEBUG */
-
-
-
-
-/* ------------------------------------------------------------------------*/
/*
* PCI interface stuff.
*/
@@ -2100,6 +1903,10 @@ static int cafe_pci_probe(struct pci_dev *pdev,
cam = kzalloc(sizeof(struct cafe_camera), GFP_KERNEL);
if (cam == NULL)
goto out;
+ ret = v4l2_device_register(&pdev->dev, &cam->v4l2_dev);
+ if (ret)
+ goto out_free;
+
mutex_init(&cam->s_mutex);
mutex_lock(&cam->s_mutex);
spin_lock_init(&cam->dev_lock);
@@ -2118,14 +1925,14 @@ static int cafe_pci_probe(struct pci_dev *pdev,
*/
ret = pci_enable_device(pdev);
if (ret)
- goto out_free;
+ goto out_unreg;
pci_set_master(pdev);
ret = -EIO;
cam->regs = pci_iomap(pdev, 0, 0);
if (! cam->regs) {
printk(KERN_ERR "Unable to ioremap cafe-ccic regs\n");
- goto out_free;
+ goto out_unreg;
}
ret = request_irq(pdev->irq, cafe_irq, IRQF_SHARED, "cafe-ccic", cam);
if (ret)
@@ -2145,17 +1952,31 @@ static int cafe_pci_probe(struct pci_dev *pdev,
ret = cafe_smbus_setup(cam);
if (ret)
goto out_freeirq;
+
+ cam->sensor_addr = 0x42;
+ cam->sensor = v4l2_i2c_new_subdev(&cam->i2c_adapter,
+ "ov7670", "ov7670", cam->sensor_addr);
+ if (cam->sensor == NULL) {
+ ret = -ENODEV;
+ goto out_smbus;
+ }
+ ret = cafe_cam_init(cam);
+ if (ret)
+ goto out_smbus;
+
/*
* Get the v4l2 setup done.
*/
mutex_lock(&cam->s_mutex);
- cam->v4ldev = cafe_v4l_template;
- cam->v4ldev.debug = 0;
-// cam->v4ldev.debug = V4L2_DEBUG_IOCTL_ARG;
- cam->v4ldev.parent = &pdev->dev;
- ret = video_register_device(&cam->v4ldev, VFL_TYPE_GRABBER, -1);
+ cam->vdev = cafe_v4l_template;
+ cam->vdev.debug = 0;
+/* cam->vdev.debug = V4L2_DEBUG_IOCTL_ARG;*/
+ cam->vdev.v4l2_dev = &cam->v4l2_dev;
+ ret = video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1);
if (ret)
goto out_smbus;
+ video_set_drvdata(&cam->vdev, cam);
+
/*
* If so requested, try to get our DMA buffers now.
*/
@@ -2165,21 +1986,21 @@ static int cafe_pci_probe(struct pci_dev *pdev,
" will try again later.");
}
- cafe_dfs_cam_setup(cam);
mutex_unlock(&cam->s_mutex);
- cafe_add_dev(cam);
return 0;
- out_smbus:
+out_smbus:
cafe_smbus_shutdown(cam);
- out_freeirq:
+out_freeirq:
cafe_ctlr_power_down(cam);
free_irq(pdev->irq, cam);
- out_iounmap:
+out_iounmap:
pci_iounmap(pdev, cam->regs);
- out_free:
+out_free:
+ v4l2_device_unregister(&cam->v4l2_dev);
+out_unreg:
kfree(cam);
- out:
+out:
return ret;
}
@@ -2190,25 +2011,23 @@ static int cafe_pci_probe(struct pci_dev *pdev,
static void cafe_shutdown(struct cafe_camera *cam)
{
/* FIXME: Make sure we take care of everything here */
- cafe_dfs_cam_shutdown(cam);
if (cam->n_sbufs > 0)
/* What if they are still mapped? Shouldn't be, but... */
cafe_free_sio_buffers(cam);
- cafe_remove_dev(cam);
cafe_ctlr_stop_dma(cam);
cafe_ctlr_power_down(cam);
cafe_smbus_shutdown(cam);
cafe_free_dma_bufs(cam);
free_irq(cam->pdev->irq, cam);
pci_iounmap(cam->pdev, cam->regs);
- video_unregister_device(&cam->v4ldev);
- /* kfree(cam); done in v4l_release () */
+ video_unregister_device(&cam->vdev);
}
static void cafe_pci_remove(struct pci_dev *pdev)
{
- struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
if (cam == NULL) {
printk(KERN_WARNING "pci_remove on unknown pdev %p\n", pdev);
@@ -2218,6 +2037,8 @@ static void cafe_pci_remove(struct pci_dev *pdev)
if (cam->users > 0)
cam_warn(cam, "Removing a device with users!\n");
cafe_shutdown(cam);
+ v4l2_device_unregister(&cam->v4l2_dev);
+ kfree(cam);
/* No unlock - it no longer exists */
}
@@ -2228,7 +2049,8 @@ static void cafe_pci_remove(struct pci_dev *pdev)
*/
static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
{
- struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
int ret;
enum cafe_state cstate;
@@ -2246,7 +2068,8 @@ static int cafe_pci_suspend(struct pci_dev *pdev, pm_message_t state)
static int cafe_pci_resume(struct pci_dev *pdev)
{
- struct cafe_camera *cam = cafe_find_by_pdev(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct cafe_camera *cam = to_cam(v4l2_dev);
int ret = 0;
ret = pci_restore_state(pdev);
@@ -2307,13 +2130,11 @@ static int __init cafe_init(void)
printk(KERN_NOTICE "Marvell M88ALP01 'CAFE' Camera Controller version %d\n",
CAFE_VERSION);
- cafe_dfs_setup();
ret = pci_register_driver(&cafe_pci_driver);
if (ret) {
printk(KERN_ERR "Unable to register cafe_ccic driver\n");
goto out;
}
- request_module("ov7670"); /* FIXME want something more general */
ret = 0;
out:
@@ -2324,7 +2145,6 @@ static int __init cafe_init(void)
static void __exit cafe_exit(void)
{
pci_unregister_driver(&cafe_pci_driver);
- cafe_dfs_shutdown();
}
module_init(cafe_init);
diff --git a/drivers/media/video/cpia.c b/drivers/media/video/cpia.c
index c3b0c8c63c7..43ab0adf3b6 100644
--- a/drivers/media/video/cpia.c
+++ b/drivers/media/video/cpia.c
@@ -1381,9 +1381,7 @@ static void proc_cpia_create(void)
{
cpia_proc_root = proc_mkdir("cpia", NULL);
- if (cpia_proc_root)
- cpia_proc_root->owner = THIS_MODULE;
- else
+ if (!cpia_proc_root)
LOG("Unable to initialise /proc/cpia\n");
}
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 9c25894fdd8..d4099f5312a 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -37,6 +37,7 @@
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/videodev.h>
#include <media/v4l2-ioctl.h>
#include "cpia2.h"
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 87e91072627..9714059ee94 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -141,11 +141,6 @@ static int cs5345_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cs5345_core_ops = {
@@ -214,8 +209,6 @@ MODULE_DEVICE_TABLE(i2c, cs5345_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cs5345",
- .driverid = I2C_DRIVERID_CS5345,
- .command = cs5345_command,
.probe = cs5345_probe,
.remove = cs5345_remove,
.id_table = cs5345_id,
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index 7292a6316e6..5aeb066857a 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -29,7 +29,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
MODULE_AUTHOR("Martin Vaughan");
@@ -41,9 +41,6 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -122,11 +119,6 @@ static int cs53l32a_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
@@ -218,8 +210,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cs53l32a",
- .driverid = I2C_DRIVERID_CS53L32A,
- .command = cs53l32a_command,
.remove = cs53l32a_remove,
.probe = cs53l32a_probe,
.id_table = cs53l32a_id,
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig
index 8940b5387de..e8a50a611eb 100644
--- a/drivers/media/video/cx18/Kconfig
+++ b/drivers/media/video/cx18/Kconfig
@@ -9,7 +9,7 @@ config VIDEO_CX18
select VIDEO_CX2341X
select VIDEO_CS5345
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
---help---
This is a video4linux driver for Conexant cx23418 based
PCI combo video recorder devices.
diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c
index 57beddf0af4..bb5c5165dd5 100644
--- a/drivers/media/video/cx18/cx18-audio.c
+++ b/drivers/media/video/cx18/cx18-audio.c
@@ -23,7 +23,6 @@
#include "cx18-driver.h"
#include "cx18-io.h"
-#include "cx18-i2c.h"
#include "cx18-cards.h"
#include "cx18-audio.h"
@@ -33,55 +32,32 @@
settings. */
int cx18_audio_set_io(struct cx18 *cx)
{
+ const struct cx18_card_audio_input *in;
struct v4l2_routing route;
- u32 audio_input;
u32 val;
- int mux_input;
int err;
/* Determine which input to use */
- if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
- audio_input = cx->card->radio_input.audio_input;
- mux_input = cx->card->radio_input.muxer_input;
- } else {
- audio_input =
- cx->card->audio_inputs[cx->audio_input].audio_input;
- mux_input =
- cx->card->audio_inputs[cx->audio_input].muxer_input;
- }
+ if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
+ in = &cx->card->radio_input;
+ else
+ in = &cx->card->audio_inputs[cx->audio_input];
/* handle muxer chips */
- route.input = mux_input;
+ route.input = in->muxer_input;
route.output = 0;
- cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(cx->sd_extmux, audio, s_routing, &route);
- route.input = audio_input;
- err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ route.input = in->audio_input;
+ err = cx18_call_hw_err(cx, cx->card->hw_audio_ctrl,
+ audio, s_routing, &route);
if (err)
return err;
+ /* FIXME - this internal mux should be abstracted to a subdev */
val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
- val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
- (audio_input << 4);
- cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE);
- cx18_vapi(cx, CX18_APU_RESETAI, 1, 0);
+ val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
+ (in->audio_input << 4);
+ cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30);
return 0;
}
-
-void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route)
-{
- cx18_i2c_hw(cx, cx->card->hw_audio_ctrl,
- VIDIOC_INT_S_AUDIO_ROUTING, route);
-}
-
-void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq)
-{
- static u32 freqs[3] = { 44100, 48000, 32000 };
-
- /* The audio clock of the digitizer must match the codec sample
- rate otherwise you get some very strange effects. */
- if (freq > 2)
- return;
- cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]);
-}
diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h
index cb569a69379..2731d29b0ab 100644
--- a/drivers/media/video/cx18/cx18-audio.h
+++ b/drivers/media/video/cx18/cx18-audio.h
@@ -22,5 +22,3 @@
*/
int cx18_audio_set_io(struct cx18 *cx);
-void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route);
-void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq);
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index a2f0ad57043..9e30983f2ff 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -464,82 +464,76 @@ static void set_mute(struct cx18 *cx, int mute)
}
}
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
struct cx18_av_state *state = &cx->av_state;
- struct v4l2_control *ctrl = arg;
int retval;
+ u8 v;
- switch (cmd) {
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- {
- u8 v;
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) & ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- cx18_av_write(cx, 0x8d3, 0x1f);
- }
- v = cx18_av_read(cx, 0x810) | 0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+ v = cx18_av_read(cx, 0x803) & ~0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+ cx18_av_write(cx, 0x8d3, 0x1f);
+ }
+ v = cx18_av_read(cx, 0x810) | 0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- retval = set_audclk_freq(cx, *(u32 *)arg);
+ retval = set_audclk_freq(cx, freq);
- v = cx18_av_read(cx, 0x810) & ~0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) | 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
- return retval;
+ v = cx18_av_read(cx, 0x810) & ~0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+ v = cx18_av_read(cx, 0x803) | 0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
}
+ return retval;
+}
- case VIDIOC_G_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = get_volume(cx);
- break;
- case V4L2_CID_AUDIO_BASS:
- ctrl->value = get_bass(cx);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = get_treble(cx);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- ctrl->value = get_balance(cx);
- break;
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = get_mute(cx);
- break;
- default:
- return -EINVAL;
- }
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = get_volume(cx);
break;
-
- case VIDIOC_S_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(cx, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = get_bass(cx);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = get_treble(cx);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = get_balance(cx);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = get_mute(cx);
break;
-
default:
return -EINVAL;
}
+ return 0;
+}
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ set_volume(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ set_bass(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ set_treble(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ set_balance(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ set_mute(cx, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index 0b1c84b4ddd..f4dd9d78eb3 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -22,8 +22,10 @@
* 02110-1301, USA.
*/
+#include <media/v4l2-chip-ident.h>
#include "cx18-driver.h"
#include "cx18-io.h"
+#include "cx18-cards.h"
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value)
{
@@ -97,15 +99,6 @@ int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask,
or_value);
}
-/* ----------------------------------------------------------------------- */
-
-static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
- enum cx18_av_audio_input aud_input);
-static void log_audio_status(struct cx18 *cx);
-static void log_video_status(struct cx18 *cx);
-
-/* ----------------------------------------------------------------------- */
-
static void cx18_av_initialize(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
@@ -169,9 +162,14 @@ static void cx18_av_initialize(struct cx18 *cx)
/* Set VGA_TRACK_RANGE to 0x20 */
cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000);
- /* Enable VBI capture */
- cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F);
- /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */
+ /*
+ * Initial VBI setup
+ * VIP-1.1, 10 bit mode, enable Raw, disable sliced,
+ * don't clamp raw samples when codes are in use, 1 byte user D-words,
+ * IDID0 has line #, RP code V bit transition on VBLANK, data during
+ * blanking intervals
+ */
+ cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4013252e);
/* Set the video input.
The setting in MODE_CTRL gets lost when we do the above setup */
@@ -195,11 +193,61 @@ static void cx18_av_initialize(struct cx18 *cx)
state->default_volume = ((state->default_volume / 2) + 23) << 9;
}
-/* ----------------------------------------------------------------------- */
+static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ cx18_av_initialize(cx);
+ return 0;
+}
+
+static int cx18_av_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ switch (val) {
+ case CX18_AV_INIT_PLLS:
+ /*
+ * The crystal freq used in calculations in this driver will be
+ * 28.636360 MHz.
+ * Aim to run the PLLs' VCOs near 400 MHz to minimze errors.
+ */
+
+ /*
+ * VDCLK Integer = 0x0f, Post Divider = 0x04
+ * AIMCLK Integer = 0x0e, Post Divider = 0x16
+ */
+ cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
+
+ /* VDCLK Fraction = 0x2be2fe */
+ /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
+ cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
+
+ /* AIMCLK Fraction = 0x05227ad */
+ /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz pre post-div*/
+ cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
+
+ /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
+ cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
+ break;
+
+ case CX18_AV_INIT_NORMAL:
+ default:
+ if (!state->is_initialized) {
+ /* initialize on first use */
+ state->is_initialized = 1;
+ cx18_av_initialize(cx);
+ }
+ break;
+ }
+ return 0;
+}
void cx18_av_std_setup(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
v4l2_std_id std = state->std;
int hblank, hactive, burst, vblank, vactive, sc;
int vblank656, src_decimation;
@@ -213,6 +261,7 @@ void cx18_av_std_setup(struct cx18 *cx)
cx18_av_write(cx, 0x49f, 0x14);
if (std & V4L2_STD_625_50) {
+ /* FIXME - revisit these for Sliced VBI */
hblank = 132;
hactive = 720;
burst = 93;
@@ -236,13 +285,40 @@ void cx18_av_std_setup(struct cx18 *cx)
sc = 672351;
}
} else {
+ /*
+ * The following relationships of half line counts should hold:
+ * 525 = vsync + vactive + vblank656
+ * 12 = vblank656 - vblank
+ *
+ * vsync: always 6 half-lines of vsync pulses
+ * vactive: half lines of active video
+ * vblank656: half lines, after line 3/mid-266, of blanked video
+ * vblank: half lines, after line 9/272, of blanked video
+ *
+ * As far as I can tell:
+ * vblank656 starts counting from the falling edge of the first
+ * vsync pulse (start of line 4 or mid-266)
+ * vblank starts counting from the after the 6 vsync pulses and
+ * 6 or 5 equalization pulses (start of line 10 or 272)
+ *
+ * For 525 line systems the driver will extract VBI information
+ * from lines 10-21 and lines 273-284.
+ */
+ vblank656 = 38; /* lines 4 - 22 & 266 - 284 */
+ vblank = 26; /* lines 10 - 22 & 272 - 284 */
+ vactive = 481; /* lines 23 - 263 & 285 - 525 */
+
+ /*
+ * For a 13.5 Mpps clock and 15,734.26 Hz line rate, a line is
+ * is 858 pixels = 720 active + 138 blanking. The Hsync leading
+ * edge should happen 1.2 us * 13.5 Mpps ~= 16 pixels after the
+ * end of active video, leaving 122 pixels of hblank to ignore
+ * before active video starts.
+ */
hactive = 720;
hblank = 122;
- vactive = 487;
luma_lpf = 1;
uv_lpf = 1;
- vblank = 26;
- vblank656 = 26;
src_decimation = 0x21f;
if (std == V4L2_STD_PAL_60) {
@@ -265,33 +341,35 @@ void cx18_av_std_setup(struct cx18 *cx)
pll_int = cx18_av_read(cx, 0x108);
pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff;
pll_post = cx18_av_read(cx, 0x109);
- CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n",
- pll_int, pll_frac, pll_post);
+ CX18_DEBUG_INFO_DEV(sd, "PLL regs = int: %u, frac: %u, post: %u\n",
+ pll_int, pll_frac, pll_post);
if (pll_post) {
int fin, fsc, pll;
pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25;
pll /= pll_post;
- CX18_DEBUG_INFO("PLL = %d.%06d MHz\n",
- pll / 1000000, pll % 1000000);
- CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n",
- pll / 8000000, (pll / 8) % 1000000);
+ CX18_DEBUG_INFO_DEV(sd, "PLL = %d.%06d MHz\n",
+ pll / 1000000, pll % 1000000);
+ CX18_DEBUG_INFO_DEV(sd, "PLL/8 = %d.%06d MHz\n",
+ pll / 8000000, (pll / 8) % 1000000);
fin = ((u64)src_decimation * pll) >> 12;
- CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n",
- fin / 1000000, fin % 1000000);
+ CX18_DEBUG_INFO_DEV(sd, "ADC Sampling freq = %d.%06d MHz\n",
+ fin / 1000000, fin % 1000000);
fsc = (((u64)sc) * pll) >> 24L;
- CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n",
- fsc / 1000000, fsc % 1000000);
-
- CX18_DEBUG_INFO("hblank %i, hactive %i, "
- "vblank %i , vactive %i, vblank656 %i, src_dec %i,"
- "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x,"
- " sc 0x%06x\n",
- hblank, hactive, vblank, vactive, vblank656,
- src_decimation, burst, luma_lpf, uv_lpf, comb, sc);
+ CX18_DEBUG_INFO_DEV(sd,
+ "Chroma sub-carrier freq = %d.%06d MHz\n",
+ fsc / 1000000, fsc % 1000000);
+
+ CX18_DEBUG_INFO_DEV(sd, "hblank %i, hactive %i, vblank %i, "
+ "vactive %i, vblank656 %i, src_dec %i, "
+ "burst 0x%02x, luma_lpf %i, uv_lpf %i, "
+ "comb 0x%02x, sc 0x%06x\n",
+ hblank, hactive, vblank, vactive, vblank656,
+ src_decimation, burst, luma_lpf, uv_lpf,
+ comb, sc);
}
/* Sets horizontal blanking delay and active lines */
@@ -325,18 +403,16 @@ void cx18_av_std_setup(struct cx18 *cx)
cx18_av_write(cx, 0x47d, 0xff & sc >> 8);
cx18_av_write(cx, 0x47e, 0xff & sc >> 16);
- /* Sets VBI parameters */
if (std & V4L2_STD_625_50) {
- cx18_av_write(cx, 0x47f, 0x01);
- state->vbi_line_offset = 5;
+ state->slicer_line_delay = 1;
+ state->slicer_line_offset = (6 + state->slicer_line_delay - 2);
} else {
- cx18_av_write(cx, 0x47f, 0x00);
- state->vbi_line_offset = 8;
+ state->slicer_line_delay = 0;
+ state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
}
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
}
-/* ----------------------------------------------------------------------- */
-
static void input_change(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
@@ -382,17 +458,26 @@ static void input_change(struct cx18 *cx)
}
}
+static int cx18_av_s_frequency(struct v4l2_subdev *sd,
+ struct v4l2_frequency *freq)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ input_change(cx);
+ return 0;
+}
+
static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
enum cx18_av_audio_input aud_input)
{
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 &&
vid_input <= CX18_AV_COMPOSITE8);
u8 reg;
u8 v;
- CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n",
- vid_input, aud_input);
+ CX18_DEBUG_INFO_DEV(sd, "decoder set video input %d, audio input %d\n",
+ vid_input, aud_input);
if (is_composite) {
reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1);
@@ -405,8 +490,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
luma > CX18_AV_SVIDEO_LUMA8 ||
chroma < CX18_AV_SVIDEO_CHROMA4 ||
chroma > CX18_AV_SVIDEO_CHROMA8) {
- CX18_ERR("0x%04x is not a valid video input!\n",
- vid_input);
+ CX18_ERR_DEV(sd, "0x%04x is not a valid video input!\n",
+ vid_input);
return -EINVAL;
}
reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4);
@@ -431,7 +516,8 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break;
default:
- CX18_ERR("0x%04x is not a valid audio input!\n", aud_input);
+ CX18_ERR_DEV(sd, "0x%04x is not a valid audio input!\n",
+ aud_input);
return -EINVAL;
}
@@ -461,14 +547,118 @@ static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input,
return 0;
}
-/* ----------------------------------------------------------------------- */
+static int cx18_av_s_video_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ return set_input(cx, route->input, state->aud_input);
+}
+
+static int cx18_av_s_audio_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ return set_input(cx, state->vid_input, route->input);
+}
-static int set_v4lstd(struct cx18 *cx)
+static int cx18_av_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
{
- struct cx18_av_state *state = &cx->av_state;
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u8 vpres;
+ u8 mode;
+ int val = 0;
+
+ if (state->radio)
+ return 0;
+
+ vpres = cx18_av_read(cx, 0x40e) & 0x20;
+ vt->signal = vpres ? 0xffff : 0x0;
+
+ vt->capability |=
+ V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
+ V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+
+ mode = cx18_av_read(cx, 0x804);
+
+ /* get rxsubchans and audmode */
+ if ((mode & 0xf) == 1)
+ val |= V4L2_TUNER_SUB_STEREO;
+ else
+ val |= V4L2_TUNER_SUB_MONO;
+
+ if (mode == 2 || mode == 4)
+ val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
+
+ if (mode & 0x10)
+ val |= V4L2_TUNER_SUB_SAP;
+
+ vt->rxsubchans = val;
+ vt->audmode = state->audmode;
+ return 0;
+}
+
+static int cx18_av_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u8 v;
+
+ if (state->radio)
+ return 0;
+
+ v = cx18_av_read(cx, 0x809);
+ v &= ~0xf;
+
+ switch (vt->audmode) {
+ case V4L2_TUNER_MODE_MONO:
+ /* mono -> mono
+ stereo -> mono
+ bilingual -> lang1 */
+ break;
+ case V4L2_TUNER_MODE_STEREO:
+ case V4L2_TUNER_MODE_LANG1:
+ /* mono -> mono
+ stereo -> stereo
+ bilingual -> lang1 */
+ v |= 0x4;
+ break;
+ case V4L2_TUNER_MODE_LANG1_LANG2:
+ /* mono -> mono
+ stereo -> stereo
+ bilingual -> lang1/lang2 */
+ v |= 0x7;
+ break;
+ case V4L2_TUNER_MODE_LANG2:
+ /* mono -> mono
+ stereo -> stereo
+ bilingual -> lang2 */
+ v |= 0x1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ cx18_av_write_expect(cx, 0x809, v, v, 0xff);
+ state->audmode = vt->audmode;
+ return 0;
+}
+
+static int cx18_av_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
u8 fmt = 0; /* zero is autodetect */
u8 pal_m = 0;
+ if (state->radio == 0 && state->std == norm)
+ return 0;
+
+ state->radio = 0;
+ state->std = norm;
+
/* First tests should be against specific std */
if (state->std == V4L2_STD_NTSC_M_JP) {
fmt = 0x2;
@@ -493,7 +683,7 @@ static int set_v4lstd(struct cx18 *cx)
fmt = 0xc;
}
- CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt);
+ CX18_DEBUG_INFO_DEV(sd, "changing video std to fmt %i\n", fmt);
/* Follow step 9 of section 3.16 in the cx18_av datasheet.
Without this PAL may display a vertical ghosting effect.
@@ -511,15 +701,22 @@ static int set_v4lstd(struct cx18 *cx)
return 0;
}
-/* ----------------------------------------------------------------------- */
+static int cx18_av_s_radio(struct v4l2_subdev *sd)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ state->radio = 1;
+ return 0;
+}
-static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
if (ctrl->value < 0 || ctrl->value > 255) {
- CX18_ERR("invalid brightness setting %d\n",
- ctrl->value);
+ CX18_ERR_DEV(sd, "invalid brightness setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -528,8 +725,8 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_CONTRAST:
if (ctrl->value < 0 || ctrl->value > 127) {
- CX18_ERR("invalid contrast setting %d\n",
- ctrl->value);
+ CX18_ERR_DEV(sd, "invalid contrast setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -538,8 +735,8 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_SATURATION:
if (ctrl->value < 0 || ctrl->value > 127) {
- CX18_ERR("invalid saturation setting %d\n",
- ctrl->value);
+ CX18_ERR_DEV(sd, "invalid saturation setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -548,8 +745,9 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
- CX18_ERR("invalid hue setting %d\n", ctrl->value);
+ if (ctrl->value < -128 || ctrl->value > 127) {
+ CX18_ERR_DEV(sd, "invalid hue setting %d\n",
+ ctrl->value);
return -ERANGE;
}
@@ -561,17 +759,18 @@ static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
- return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
+ return cx18_av_audio_s_ctrl(cx, ctrl);
default:
return -EINVAL;
}
-
return 0;
}
-static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
@@ -590,31 +789,57 @@ static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
- return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
+ return cx18_av_audio_g_ctrl(cx, ctrl);
default:
return -EINVAL;
}
-
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
+static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
- switch (fmt->type) {
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_CONTRAST:
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+ default:
+ break;
+ }
+
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535,
+ 65535 / 100, state->default_volume);
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
default:
return -EINVAL;
}
+ return -EINVAL;
+}
- return 0;
+static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ return cx18_av_vbi_g_fmt(cx, fmt);
}
-static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
+static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct cx18_av_state *state = &cx->av_state;
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
struct v4l2_pix_format *pix;
int HSC, VSC, Vsrc, Hsrc, filter, Vlines;
int is_50Hz = !(state->std & V4L2_STD_525_60);
@@ -629,12 +854,26 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4;
Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4;
- Vlines = pix->height + (is_50Hz ? 4 : 7);
-
+ /*
+ * This adjustment reflects the excess of vactive, set in
+ * cx18_av_std_setup(), above standard values:
+ *
+ * 480 + 1 for 60 Hz systems
+ * 576 + 4 for 50 Hz systems
+ */
+ Vlines = pix->height + (is_50Hz ? 4 : 1);
+
+ /*
+ * Invalid height and width scaling requests are:
+ * 1. width less than 1/16 of the source width
+ * 2. width greater than the source width
+ * 3. height less than 1/8 of the source height
+ * 4. height greater than the source height
+ */
if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) ||
(Vlines * 8 < Vsrc) || (Vsrc < Vlines)) {
- CX18_ERR("%dx%d is not a valid size!\n",
- pix->width, pix->height);
+ CX18_ERR_DEV(sd, "%dx%d is not a valid size!\n",
+ pix->width, pix->height);
return -ERANGE;
}
@@ -651,8 +890,9 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
else
filter = 3;
- CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n",
- pix->width, pix->height, HSC, VSC);
+ CX18_DEBUG_INFO_DEV(sd,
+ "decoder set size %dx%d -> scale %ux%u\n",
+ pix->width, pix->height, HSC, VSC);
/* HSCALE=HSC */
cx18_av_write(cx, 0x418, HSC & 0xff);
@@ -666,231 +906,32 @@ static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt)
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+ return cx18_av_vbi_s_fmt(cx, fmt);
case V4L2_BUF_TYPE_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+ return cx18_av_vbi_s_fmt(cx, fmt);
default:
return -EINVAL;
}
-
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg)
+static int cx18_av_s_stream(struct v4l2_subdev *sd, int enable)
{
- struct cx18_av_state *state = &cx->av_state;
- struct v4l2_tuner *vt = arg;
- struct v4l2_routing *route = arg;
-
- /* ignore these commands */
- switch (cmd) {
- case TUNER_SET_TYPE_ADDR:
- return 0;
- }
-
- if (!state->is_initialized) {
- CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd);
- /* initialize on first use */
- state->is_initialized = 1;
- cx18_av_initialize(cx);
- }
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
- switch (cmd) {
- case VIDIOC_INT_DECODE_VBI_LINE:
- return cx18_av_vbi(cx, cmd, arg);
-
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- return cx18_av_audio(cx, cmd, arg);
-
- case VIDIOC_STREAMON:
- CX18_DEBUG_INFO("enable output\n");
+ CX18_DEBUG_INFO_DEV(sd, "%s output\n", enable ? "enable" : "disable");
+ if (enable) {
cx18_av_write(cx, 0x115, 0x8c);
cx18_av_write(cx, 0x116, 0x07);
- break;
-
- case VIDIOC_STREAMOFF:
- CX18_DEBUG_INFO("disable output\n");
+ } else {
cx18_av_write(cx, 0x115, 0x00);
cx18_av_write(cx, 0x116, 0x00);
- break;
-
- case VIDIOC_LOG_STATUS:
- log_video_status(cx);
- log_audio_status(cx);
- break;
-
- case VIDIOC_G_CTRL:
- return get_v4lctrl(cx, (struct v4l2_control *)arg);
-
- case VIDIOC_S_CTRL:
- return set_v4lctrl(cx, (struct v4l2_control *)arg);
-
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
-
- switch (qc->id) {
- case V4L2_CID_BRIGHTNESS:
- case V4L2_CID_CONTRAST:
- case V4L2_CID_SATURATION:
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- break;
- }
-
- switch (qc->id) {
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(qc, 0, 65535,
- 65535 / 100, state->default_volume);
- case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- return -EINVAL;
- }
- return -EINVAL;
- }
-
- case VIDIOC_G_STD:
- *(v4l2_std_id *)arg = state->std;
- break;
-
- case VIDIOC_S_STD:
- if (state->radio == 0 && state->std == *(v4l2_std_id *)arg)
- return 0;
- state->radio = 0;
- state->std = *(v4l2_std_id *)arg;
- return set_v4lstd(cx);
-
- case AUDC_SET_RADIO:
- state->radio = 1;
- break;
-
- case VIDIOC_INT_G_VIDEO_ROUTING:
- route->input = state->vid_input;
- route->output = 0;
- break;
-
- case VIDIOC_INT_S_VIDEO_ROUTING:
- return set_input(cx, route->input, state->aud_input);
-
- case VIDIOC_INT_G_AUDIO_ROUTING:
- route->input = state->aud_input;
- route->output = 0;
- break;
-
- case VIDIOC_INT_S_AUDIO_ROUTING:
- return set_input(cx, state->vid_input, route->input);
-
- case VIDIOC_S_FREQUENCY:
- input_change(cx);
- break;
-
- case VIDIOC_G_TUNER:
- {
- u8 vpres = cx18_av_read(cx, 0x40e) & 0x20;
- u8 mode;
- int val = 0;
-
- if (state->radio)
- break;
-
- vt->signal = vpres ? 0xffff : 0x0;
-
- vt->capability |=
- V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
- V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
-
- mode = cx18_av_read(cx, 0x804);
-
- /* get rxsubchans and audmode */
- if ((mode & 0xf) == 1)
- val |= V4L2_TUNER_SUB_STEREO;
- else
- val |= V4L2_TUNER_SUB_MONO;
-
- if (mode == 2 || mode == 4)
- val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2;
-
- if (mode & 0x10)
- val |= V4L2_TUNER_SUB_SAP;
-
- vt->rxsubchans = val;
- vt->audmode = state->audmode;
- break;
- }
-
- case VIDIOC_S_TUNER:
- {
- u8 v;
-
- if (state->radio)
- break;
-
- v = cx18_av_read(cx, 0x809);
- v &= ~0xf;
-
- switch (vt->audmode) {
- case V4L2_TUNER_MODE_MONO:
- /* mono -> mono
- stereo -> mono
- bilingual -> lang1 */
- break;
- case V4L2_TUNER_MODE_STEREO:
- case V4L2_TUNER_MODE_LANG1:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1 */
- v |= 0x4;
- break;
- case V4L2_TUNER_MODE_LANG1_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang1/lang2 */
- v |= 0x7;
- break;
- case V4L2_TUNER_MODE_LANG2:
- /* mono -> mono
- stereo -> stereo
- bilingual -> lang2 */
- v |= 0x1;
- break;
- default:
- return -EINVAL;
- }
- cx18_av_write_expect(cx, 0x809, v, v, 0xff);
- state->audmode = vt->audmode;
- break;
}
-
- case VIDIOC_G_FMT:
- return get_v4lfmt(cx, (struct v4l2_format *)arg);
-
- case VIDIOC_S_FMT:
- return set_v4lfmt(cx, (struct v4l2_format *)arg);
-
- case VIDIOC_INT_RESET:
- cx18_av_initialize(cx);
- break;
-
- default:
- return -EINVAL;
- }
-
return 0;
}
-/* ----------------------------------------------------------------------- */
-
-/* ----------------------------------------------------------------------- */
-
static void log_video_status(struct cx18 *cx)
{
static const char *const fmt_strs[] = {
@@ -903,36 +944,40 @@ static void log_video_status(struct cx18 *cx)
};
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf;
u8 gen_stat1 = cx18_av_read(cx, 0x40d);
u8 gen_stat2 = cx18_av_read(cx, 0x40e);
int vid_input = state->vid_input;
- CX18_INFO("Video signal: %spresent\n",
- (gen_stat2 & 0x20) ? "" : "not ");
- CX18_INFO("Detected format: %s\n",
- fmt_strs[gen_stat1 & 0xf]);
+ CX18_INFO_DEV(sd, "Video signal: %spresent\n",
+ (gen_stat2 & 0x20) ? "" : "not ");
+ CX18_INFO_DEV(sd, "Detected format: %s\n",
+ fmt_strs[gen_stat1 & 0xf]);
- CX18_INFO("Specified standard: %s\n",
- vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection");
+ CX18_INFO_DEV(sd, "Specified standard: %s\n",
+ vidfmt_sel ? fmt_strs[vidfmt_sel]
+ : "automatic detection");
if (vid_input >= CX18_AV_COMPOSITE1 &&
vid_input <= CX18_AV_COMPOSITE8) {
- CX18_INFO("Specified video input: Composite %d\n",
- vid_input - CX18_AV_COMPOSITE1 + 1);
+ CX18_INFO_DEV(sd, "Specified video input: Composite %d\n",
+ vid_input - CX18_AV_COMPOSITE1 + 1);
} else {
- CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n",
- (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8);
+ CX18_INFO_DEV(sd, "Specified video input: "
+ "S-Video (Luma In%d, Chroma In%d)\n",
+ (vid_input & 0xf0) >> 4,
+ (vid_input & 0xf00) >> 8);
}
- CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq);
+ CX18_INFO_DEV(sd, "Specified audioclock freq: %d Hz\n",
+ state->audclk_freq);
}
-/* ----------------------------------------------------------------------- */
-
static void log_audio_status(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd = &state->sd;
u8 download_ctl = cx18_av_read(cx, 0x803);
u8 mod_det_stat0 = cx18_av_read(cx, 0x804);
u8 mod_det_stat1 = cx18_av_read(cx, 0x805);
@@ -955,7 +1000,7 @@ static void log_audio_status(struct cx18 *cx)
case 0xfe: p = "forced mode"; break;
default: p = "not defined"; break;
}
- CX18_INFO("Detected audio mode: %s\n", p);
+ CX18_INFO_DEV(sd, "Detected audio mode: %s\n", p);
switch (mod_det_stat1) {
case 0x00: p = "not defined"; break;
@@ -980,11 +1025,11 @@ static void log_audio_status(struct cx18 *cx)
case 0xff: p = "no detected audio standard"; break;
default: p = "not defined"; break;
}
- CX18_INFO("Detected audio standard: %s\n", p);
- CX18_INFO("Audio muted: %s\n",
- (mute_ctl & 0x2) ? "yes" : "no");
- CX18_INFO("Audio microcontroller: %s\n",
- (download_ctl & 0x10) ? "running" : "stopped");
+ CX18_INFO_DEV(sd, "Detected audio standard: %s\n", p);
+ CX18_INFO_DEV(sd, "Audio muted: %s\n",
+ (mute_ctl & 0x2) ? "yes" : "no");
+ CX18_INFO_DEV(sd, "Audio microcontroller: %s\n",
+ (download_ctl & 0x10) ? "running" : "stopped");
switch (audio_config >> 4) {
case 0x00: p = "undefined"; break;
@@ -1005,7 +1050,7 @@ static void log_audio_status(struct cx18 *cx)
case 0x0f: p = "automatic detection"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Configured audio standard: %s\n", p);
+ CX18_INFO_DEV(sd, "Configured audio standard: %s\n", p);
if ((audio_config >> 4) < 0xF) {
switch (audio_config & 0xF) {
@@ -1019,7 +1064,7 @@ static void log_audio_status(struct cx18 *cx)
case 0x07: p = "DUAL3 (AB)"; break;
default: p = "undefined";
}
- CX18_INFO("Configured audio mode: %s\n", p);
+ CX18_INFO_DEV(sd, "Configured audio mode: %s\n", p);
} else {
switch (audio_config & 0xF) {
case 0x00: p = "BG"; break;
@@ -1037,14 +1082,14 @@ static void log_audio_status(struct cx18 *cx)
case 0x0f: p = "automatic standard and mode detection"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Configured audio system: %s\n", p);
+ CX18_INFO_DEV(sd, "Configured audio system: %s\n", p);
}
if (aud_input)
- CX18_INFO("Specified audio input: Tuner (In%d)\n",
- aud_input);
+ CX18_INFO_DEV(sd, "Specified audio input: Tuner (In%d)\n",
+ aud_input);
else
- CX18_INFO("Specified audio input: External\n");
+ CX18_INFO_DEV(sd, "Specified audio input: External\n");
switch (pref_mode & 0xf) {
case 0: p = "mono/language A"; break;
@@ -1057,14 +1102,14 @@ static void log_audio_status(struct cx18 *cx)
case 7: p = "language AB"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Preferred audio mode: %s\n", p);
+ CX18_INFO_DEV(sd, "Preferred audio mode: %s\n", p);
if ((audio_config & 0xf) == 0xf) {
switch ((afc0 >> 3) & 0x1) {
case 0: p = "system DK"; break;
case 1: p = "system L"; break;
}
- CX18_INFO("Selected 65 MHz format: %s\n", p);
+ CX18_INFO_DEV(sd, "Selected 65 MHz format: %s\n", p);
switch (afc0 & 0x7) {
case 0: p = "Chroma"; break;
@@ -1074,6 +1119,131 @@ static void log_audio_status(struct cx18 *cx)
case 4: p = "autodetect"; break;
default: p = "undefined"; break;
}
- CX18_INFO("Selected 45 MHz format: %s\n", p);
+ CX18_INFO_DEV(sd, "Selected 45 MHz format: %s\n", p);
}
}
+
+static int cx18_av_log_status(struct v4l2_subdev *sd)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ log_video_status(cx);
+ log_audio_status(cx);
+ return 0;
+}
+
+static inline int cx18_av_dbg_match(const struct v4l2_dbg_match *match)
+{
+ return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 1;
+}
+
+static int cx18_av_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct cx18_av_state *state = to_cx18_av_state(sd);
+
+ if (cx18_av_dbg_match(&chip->match)) {
+ chip->ident = state->id;
+ chip->revision = state->rev;
+ }
+ return 0;
+}
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int cx18_av_g_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ if (!cx18_av_dbg_match(&reg->match))
+ return -EINVAL;
+ if ((reg->reg & 0x3) != 0)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ reg->size = 4;
+ reg->val = cx18_av_read4(cx, reg->reg & 0x00000ffc);
+ return 0;
+}
+
+static int cx18_av_s_register(struct v4l2_subdev *sd,
+ struct v4l2_dbg_register *reg)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ if (!cx18_av_dbg_match(&reg->match))
+ return -EINVAL;
+ if ((reg->reg & 0x3) != 0)
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ cx18_av_write4(cx, reg->reg & 0x00000ffc, reg->val);
+ return 0;
+}
+#endif
+
+static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
+ .g_chip_ident = cx18_av_g_chip_ident,
+ .log_status = cx18_av_log_status,
+ .init = cx18_av_init,
+ .reset = cx18_av_reset,
+ .queryctrl = cx18_av_queryctrl,
+ .g_ctrl = cx18_av_g_ctrl,
+ .s_ctrl = cx18_av_s_ctrl,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = cx18_av_g_register,
+ .s_register = cx18_av_s_register,
+#endif
+};
+
+static const struct v4l2_subdev_tuner_ops cx18_av_tuner_ops = {
+ .s_radio = cx18_av_s_radio,
+ .s_frequency = cx18_av_s_frequency,
+ .g_tuner = cx18_av_g_tuner,
+ .s_tuner = cx18_av_s_tuner,
+ .s_std = cx18_av_s_std,
+};
+
+static const struct v4l2_subdev_audio_ops cx18_av_audio_ops = {
+ .s_clock_freq = cx18_av_s_clock_freq,
+ .s_routing = cx18_av_s_audio_routing,
+};
+
+static const struct v4l2_subdev_video_ops cx18_av_video_ops = {
+ .s_routing = cx18_av_s_video_routing,
+ .decode_vbi_line = cx18_av_decode_vbi_line,
+ .s_stream = cx18_av_s_stream,
+ .g_fmt = cx18_av_g_fmt,
+ .s_fmt = cx18_av_s_fmt,
+};
+
+static const struct v4l2_subdev_ops cx18_av_ops = {
+ .core = &cx18_av_general_ops,
+ .tuner = &cx18_av_tuner_ops,
+ .audio = &cx18_av_audio_ops,
+ .video = &cx18_av_video_ops,
+};
+
+int cx18_av_probe(struct cx18 *cx)
+{
+ struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_subdev *sd;
+
+ state->rev = cx18_av_read4(cx, CXADEC_CHIP_CTRL) & 0xffff;
+ state->id = ((state->rev >> 4) == CXADEC_CHIP_TYPE_MAKO)
+ ? V4L2_IDENT_CX23418_843 : V4L2_IDENT_UNKNOWN;
+
+ state->vid_input = CX18_AV_COMPOSITE7;
+ state->aud_input = CX18_AV_AUDIO8;
+ state->audclk_freq = 48000;
+ state->audmode = V4L2_TUNER_MODE_LANG1;
+ state->slicer_line_delay = 0;
+ state->slicer_line_offset = (10 + state->slicer_line_delay - 2);
+
+ sd = &state->sd;
+ v4l2_subdev_init(sd, &cx18_av_ops);
+ v4l2_set_subdevdata(sd, cx);
+ snprintf(sd->name, sizeof(sd->name),
+ "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
+ sd->grp_id = CX18_HW_418_AV;
+ return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index cf68a603909..c458120e8c9 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -25,6 +25,8 @@
#ifndef _CX18_AV_CORE_H_
#define _CX18_AV_CORE_H_
+#include <media/v4l2-device.h>
+
struct cx18;
enum cx18_av_video_input {
@@ -73,17 +75,40 @@ enum cx18_av_audio_input {
};
struct cx18_av_state {
+ struct v4l2_subdev sd;
int radio;
v4l2_std_id std;
enum cx18_av_video_input vid_input;
enum cx18_av_audio_input aud_input;
u32 audclk_freq;
int audmode;
- int vbi_line_offset;
int default_volume;
u32 id;
u32 rev;
int is_initialized;
+
+ /*
+ * The VBI slicer starts operating and counting lines, begining at
+ * slicer line count of 1, at D lines after the deassertion of VRESET.
+ * This staring field line, S, is 6 (& 319) or 10 (& 273) for 625 or 525
+ * line systems respectively. Sliced ancillary data captured on VBI
+ * slicer line M is inserted after the VBI slicer is done with line M,
+ * when VBI slicer line count is N = M+1. Thus when the VBI slicer
+ * reports a VBI slicer line number with ancillary data, the IDID0 byte
+ * indicates VBI slicer line N. The actual field line that the captured
+ * data comes from is
+ *
+ * L = M+(S+D-1) = N-1+(S+D-1) = N + (S+D-2).
+ *
+ * L is the line in the field, not frame, from which the VBI data came.
+ * N is the line reported by the slicer in the ancillary data.
+ * D is the slicer_line_delay value programmed into register 0x47f.
+ * S is 6 for 625 line systems or 10 for 525 line systems
+ * (S+D-2) is the slicer_line_offset used to convert slicer reported
+ * line counts to actual field lines.
+ */
+ int slicer_line_delay;
+ int slicer_line_offset;
};
@@ -298,6 +323,16 @@ struct cx18_av_state {
#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */
#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */
+static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct cx18_av_state, sd);
+}
+
+enum cx18_av_subdev_init_arg {
+ CX18_AV_INIT_NORMAL = 0,
+ CX18_AV_INIT_PLLS = 1,
+};
+
/* ----------------------------------------------------------------------- */
/* cx18_av-core.c */
int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
@@ -310,20 +345,26 @@ u8 cx18_av_read(struct cx18 *cx, u16 addr);
u32 cx18_av_read4(struct cx18 *cx, u16 addr);
int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value);
int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value);
-int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg);
void cx18_av_std_setup(struct cx18 *cx);
+int cx18_av_probe(struct cx18 *cx);
+
/* ----------------------------------------------------------------------- */
/* cx18_av-firmware.c */
int cx18_av_loadfw(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-audio.c */
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
void cx18_av_audio_set_path(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-vbi.c */
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+ struct v4l2_decode_vbi_line *vbi);
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt);
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt);
#endif
diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c
index c64fd0a05a9..49a55cc8d83 100644
--- a/drivers/media/video/cx18/cx18-av-firmware.c
+++ b/drivers/media/video/cx18/cx18-av-firmware.c
@@ -29,6 +29,7 @@
int cx18_av_loadfw(struct cx18 *cx)
{
+ struct v4l2_subdev *sd = &cx->av_state.sd;
const struct firmware *fw = NULL;
u32 size;
u32 v;
@@ -36,8 +37,8 @@ int cx18_av_loadfw(struct cx18 *cx)
int i;
int retries1 = 0;
- if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) {
- CX18_ERR("unable to open firmware %s\n", FWFILE);
+ if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) {
+ CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE);
return -EINVAL;
}
@@ -88,7 +89,7 @@ int cx18_av_loadfw(struct cx18 *cx)
retries1++;
}
if (retries1 >= 5) {
- CX18_ERR("unable to load firmware %s\n", FWFILE);
+ CX18_ERR_DEV(sd, "unable to load firmware %s\n", FWFILE);
release_firmware(fw);
return -EIO;
}
@@ -115,9 +116,9 @@ int cx18_av_loadfw(struct cx18 *cx)
are generated) */
cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0);
- /* set alt I2s master clock to /16 and enable alt divider i2s
+ /* set alt I2s master clock to /0x16 and enable alt divider i2s
passthrough */
- cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687);
+ cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5600B687);
cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6,
0x3F00FFFF);
@@ -131,7 +132,8 @@ int cx18_av_loadfw(struct cx18 *cx)
v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
/* If bit 11 is 1, clear bit 10 */
if (v & 0x800)
- cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE);
+ cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
+ 0, 0x400);
/* Enable WW auto audio standard detection */
v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
@@ -142,6 +144,6 @@ int cx18_av_loadfw(struct cx18 *cx)
release_firmware(fw);
- CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size);
+ CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 1527ea4f6b0..23b31670bf1 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -24,6 +24,52 @@
#include "cx18-driver.h"
+/*
+ * For sliced VBI output, we set up to use VIP-1.1, 8-bit mode,
+ * NN counts 1 byte Dwords, an IDID with the VBI line # in it.
+ * Thus, according to the VIP-2 Spec, our VBI ancillary data lines
+ * (should!) look like:
+ * 4 byte EAV code: 0xff 0x00 0x00 0xRP
+ * unknown number of possible idle bytes
+ * 3 byte Anc data preamble: 0x00 0xff 0xff
+ * 1 byte data identifier: ne010iii (parity bits, 010, DID bits)
+ * 1 byte secondary data id: nessssss (parity bits, SDID bits)
+ * 1 byte data word count: necccccc (parity bits, NN Dword count)
+ * 2 byte Internal DID: VBI-line-# 0x80
+ * NN data bytes
+ * 1 byte checksum
+ * Fill bytes needed to fil out to 4*NN bytes of payload
+ *
+ * The RP codes for EAVs when in VIP-1.1 mode, not in raw mode, &
+ * in the vertical blanking interval are:
+ * 0xb0 (Task 0 VerticalBlank HorizontalBlank 0 0 0 0)
+ * 0xf0 (Task EvenField VerticalBlank HorizontalBlank 0 0 0 0)
+ *
+ * Since the V bit is only allowed to toggle in the EAV RP code, just
+ * before the first active region line and for active lines, they are:
+ * 0x90 (Task 0 0 HorizontalBlank 0 0 0 0)
+ * 0xd0 (Task EvenField 0 HorizontalBlank 0 0 0 0)
+ *
+ * The user application DID bytes we care about are:
+ * 0x91 (1 0 010 0 !ActiveLine AncDataPresent)
+ * 0x55 (0 1 010 2ndField !ActiveLine AncDataPresent)
+ *
+ */
+static const u8 sliced_vbi_did[2] = { 0x91, 0x55 };
+
+struct vbi_anc_data {
+ /* u8 eav[4]; */
+ /* u8 idle[]; Variable number of idle bytes */
+ u8 preamble[3];
+ u8 did;
+ u8 sdid;
+ u8 data_count;
+ u8 idid[2];
+ u8 payload[1]; /* data_count of payload */
+ /* u8 checksum; */
+ /* u8 fill[]; Variable number of fill bytes */
+};
+
static int odd_parity(u8 c)
{
c ^= (c >> 4);
@@ -83,188 +129,189 @@ static int decode_vps(u8 *dst, u8 *p)
return err & 0xf0;
}
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
{
struct cx18_av_state *state = &cx->av_state;
- struct v4l2_format *fmt;
struct v4l2_sliced_vbi_format *svbi;
+ static const u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_WSS_625, 0, /* 4 */
+ V4L2_SLICED_CAPTION_525, /* 6 */
+ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ 0, 0, 0, 0
+ };
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i;
- switch (cmd) {
- case VIDIOC_G_FMT:
- {
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
- break;
-
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 7);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- } else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- }
- break;
- }
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ memset(svbi, 0, sizeof(*svbi));
+ /* we're done if raw VBI is active */
+ if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
+ return 0;
- case VIDIOC_S_FMT:
- {
- int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
- int i, x;
- u8 lcr[24];
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
- fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- /* raw VBI */
- memset(svbi, 0, sizeof(*svbi));
-
- /* Setup standard */
- cx18_av_std_setup(cx);
-
- /* VBI Offset */
- cx18_av_write(cx, 0x47f, vbi_offset);
- cx18_av_write(cx, 0x404, 0x2e);
- break;
+ if (is_pal) {
+ for (i = 7; i <= 23; i++) {
+ u8 v = cx18_av_read(cx, 0x424 + i - 7);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
+ }
+ } else {
+ for (i = 10; i <= 21; i++) {
+ u8 v = cx18_av_read(cx, 0x424 + i - 10);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
+ }
+ return 0;
+}
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
+{
+ struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_sliced_vbi_format *svbi;
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i, x;
+ u8 lcr[24];
+
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+ fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* raw VBI */
+ memset(svbi, 0, sizeof(*svbi));
/* Setup standard */
cx18_av_std_setup(cx);
- /* Sliced VBI */
- cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
- cx18_av_write(cx, 0x406, 0x13);
- cx18_av_write(cx, 0x47f, vbi_offset);
-
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
+ /* VBI Offset */
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+ cx18_av_write(cx, 0x404, 0x2e);
+ return 0;
+ }
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
+ for (x = 0; x <= 23; x++)
+ lcr[x] = 0x00;
+
+ /* Setup standard */
+ cx18_av_std_setup(cx);
+
+ /* Sliced VBI */
+ cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
+ cx18_av_write(cx, 0x406, 0x13);
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+
+ /* Force impossible lines to 0 */
+ if (is_pal) {
+ for (i = 0; i <= 6; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ } else {
+ for (i = 0; i <= 9; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+
+ for (i = 22; i <= 23; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ }
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++)
- cx18_av_write(cx, i, lcr[6 + x]);
- } else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++)
- cx18_av_write(cx, i, lcr[9 + x]);
- for (i = 0x431; i <= 0x434; i++)
- cx18_av_write(cx, i, 0);
+ /* Build register values for requested service lines */
+ for (i = 7; i <= 23; i++) {
+ for (x = 0; x <= 1; x++) {
+ switch (svbi->service_lines[1-x][i]) {
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 6 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 9 << (4 * x);
+ break;
+ }
}
+ }
- cx18_av_write(cx, 0x43c, 0x16);
- cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22);
- break;
+ if (is_pal) {
+ for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+ cx18_av_write(cx, i, lcr[6 + x]);
+ } else {
+ for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+ cx18_av_write(cx, i, lcr[9 + x]);
+ for (i = 0x431; i <= 0x434; i++)
+ cx18_av_write(cx, i, 0);
}
- case VIDIOC_INT_DECODE_VBI_LINE:
- {
- struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
+ cx18_av_write(cx, 0x43c, 0x16);
+ /* FIXME - should match vblank set in cx18_av_std_setup() */
+ cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
+ return 0;
+}
+
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+ struct v4l2_decode_vbi_line *vbi)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ struct cx18_av_state *state = &cx->av_state;
+ struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
+ u8 *p;
+ int did, sdid, l, err = 0;
+
+ /*
+ * Check for the ancillary data header for sliced VBI
+ */
+ if (anc->preamble[0] ||
+ anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
+ (anc->did != sliced_vbi_did[0] &&
+ anc->did != sliced_vbi_did[1])) {
+ vbi->line = vbi->type = 0;
+ return 0;
+ }
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
- vbi->line = vbi->type = 0;
- break;
- }
+ did = anc->did;
+ sdid = anc->sdid & 0xf;
+ l = anc->idid[0] & 0x3f;
+ l += state->slicer_line_offset;
+ p = anc->payload;
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += state->vbi_line_offset;
- p += 4;
-
- switch (id2) {
- case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- id2 = V4L2_SLICED_WSS_625;
- break;
- case 6:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- id2 = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0)
- err = 1;
- break;
- default:
- id2 = 0;
+ /* Decode the SDID set by the slicer */
+ switch (sdid) {
+ case 1:
+ sdid = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ sdid = V4L2_SLICED_WSS_625;
+ break;
+ case 6:
+ sdid = V4L2_SLICED_CAPTION_525;
+ err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ break;
+ case 9:
+ sdid = V4L2_SLICED_VPS;
+ if (decode_vps(p, p) != 0)
err = 1;
- break;
- }
-
- vbi->type = err ? 0 : id2;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
- vbi->p = p;
break;
- }
+ default:
+ sdid = 0;
+ err = 1;
+ break;
}
+ vbi->type = err ? 0 : sdid;
+ vbi->line = err ? 0 : l;
+ vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
+ vbi->p = p;
return 0;
}
diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c
index e274043657d..9bc22183784 100644
--- a/drivers/media/video/cx18/cx18-cards.c
+++ b/drivers/media/video/cx18/cx18-cards.c
@@ -51,12 +51,12 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
static const struct cx18_card cx18_card_hvr1600_esmt = {
.type = CX18_CARD_HVR_1600_ESMT,
.name = "Hauppauge HVR-1600",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Simultaneous Digital and Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
+ .hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+ CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@@ -97,12 +97,12 @@ static const struct cx18_card cx18_card_hvr1600_esmt = {
static const struct cx18_card cx18_card_hvr1600_samsung = {
.type = CX18_CARD_HVR_1600_SAMSUNG,
.name = "Hauppauge HVR-1600 (Preproduction)",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Simultaneous Digital and Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
+ .hw_audio_ctrl = CX18_HW_418_AV,
.hw_muxer = CX18_HW_CS5345,
- .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER |
- CX18_HW_CS5345 | CX18_HW_DVB,
+ .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
+ CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
{ CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
@@ -152,10 +152,10 @@ static const struct cx18_card_pci_info cx18_pci_h900[] = {
static const struct cx18_card cx18_card_h900 = {
.type = CX18_CARD_COMPRO_H900,
.name = "Compro VideoMate H900",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_all = CX18_HW_TUNER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -201,8 +201,8 @@ static const struct cx18_card cx18_card_mpc718 = {
.name = "Yuan MPC718",
.comment = "Analog video capture works; some audio line in may not.\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_all = CX18_HW_TUNER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -249,11 +249,11 @@ static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
static const struct cx18_card cx18_card_cnxt_raptor_pal = {
.type = CX18_CARD_CNXT_RAPTOR_PAL,
.name = "Conexant Raptor PAL/SECAM",
- .comment = "Raw VBI supported; Sliced VBI is not yet supported\n",
+ .comment = "Analog TV capture supported\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_muxer = CX18_HW_GPIO,
- .hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_muxer = CX18_HW_GPIO_MUX,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -306,8 +306,8 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
.comment = "Experimenters and photos needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_all = CX18_HW_TUNER,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
@@ -339,19 +339,21 @@ static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
/* Leadtek WinFast PVR2100 */
static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
- { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 },
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, /* PVR2100 */
+ { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 }, /* DVR3100 H */
{ 0, 0, 0 }
};
static const struct cx18_card cx18_card_leadtek_pvr2100 = {
.type = CX18_CARD_LEADTEK_PVR2100,
- .name = "Leadtek WinFast PVR2100",
+ .name = "Leadtek WinFast PVR2100/DVR3100 H",
.comment = "Experimenters and photos needed for device to work well.\n"
"\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
.v4l2_capabilities = CX18_CAP_ENCODER,
- .hw_audio_ctrl = CX18_HW_CX23418,
- .hw_muxer = CX18_HW_GPIO,
- .hw_all = CX18_HW_TUNER | CX18_HW_GPIO,
+ .hw_audio_ctrl = CX18_HW_418_AV,
+ .hw_muxer = CX18_HW_GPIO_MUX,
+ .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
+ CX18_HW_GPIO_RESET_CTRL,
.video_inputs = {
{ CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
{ CX18_CARD_INPUT_SVIDEO1, 1,
diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h
index 6fa7bcb42dd..3c552b6b7c4 100644
--- a/drivers/media/video/cx18/cx18-cards.h
+++ b/drivers/media/video/cx18/cx18-cards.h
@@ -22,12 +22,13 @@
*/
/* hardware flags */
-#define CX18_HW_TUNER (1 << 0)
-#define CX18_HW_TVEEPROM (1 << 1)
-#define CX18_HW_CS5345 (1 << 2)
-#define CX18_HW_GPIO (1 << 3)
-#define CX18_HW_CX23418 (1 << 4)
-#define CX18_HW_DVB (1 << 5)
+#define CX18_HW_TUNER (1 << 0)
+#define CX18_HW_TVEEPROM (1 << 1)
+#define CX18_HW_CS5345 (1 << 2)
+#define CX18_HW_DVB (1 << 3)
+#define CX18_HW_418_AV (1 << 4)
+#define CX18_HW_GPIO_MUX (1 << 5)
+#define CX18_HW_GPIO_RESET_CTRL (1 << 6)
/* video inputs */
#define CX18_CARD_INPUT_VID_TUNER 1
@@ -49,8 +50,7 @@
/* V4L2 capability aliases */
#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \
V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \
- V4L2_CAP_VBI_CAPTURE)
-/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */
+ V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE)
struct cx18_card_video_input {
u8 video_type; /* video input type */
@@ -122,7 +122,7 @@ struct cx18_card {
char *comment;
u32 v4l2_capabilities;
u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only
- 1 dev allowed) */
+ 1 dev allowed currently) */
u32 hw_muxer; /* hardware used to multiplex audio input */
u32 hw_all; /* all hardware used by the board */
struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS];
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 17edf305d64..82fc2f9d402 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -22,14 +22,13 @@
*/
#include "cx18-driver.h"
-#include "cx18-av-core.h"
#include "cx18-cards.h"
#include "cx18-ioctl.h"
#include "cx18-audio.h"
-#include "cx18-i2c.h"
#include "cx18-mailbox.h"
#include "cx18-controls.h"
+/* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -66,7 +65,7 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
- if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl))
+ if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
@@ -76,7 +75,7 @@ int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
- if (cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl))
+ if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
@@ -125,7 +124,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
- return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_MUTE:
@@ -133,7 +132,7 @@ static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
- return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
default:
CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
@@ -150,7 +149,7 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
- return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_MUTE:
@@ -158,7 +157,8 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
- return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl);
+ return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
+
default:
CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
@@ -166,38 +166,57 @@ static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
return 0;
}
-static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt)
+static int cx18_setup_vbi_fmt(struct cx18 *cx,
+ enum v4l2_mpeg_stream_vbi_fmt fmt,
+ enum v4l2_mpeg_stream_type type)
{
if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
return -EINVAL;
if (atomic_read(&cx->ana_capturing) > 0)
return -EBUSY;
- /* First try to allocate sliced VBI buffers if needed. */
- if (fmt && cx->vbi.sliced_mpeg_data[0] == NULL) {
+ if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
+ type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
+ /* We don't do VBI insertion aside from IVTV format in a PS */
+ cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
+ CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
+ "the MPEG stream\n");
+ return 0;
+ }
+
+ /* Allocate sliced VBI buffers if needed. */
+ if (cx->vbi.sliced_mpeg_data[0] == NULL) {
int i;
for (i = 0; i < CX18_VBI_FRAMES; i++) {
- /* Yuck, hardcoded. Needs to be a define */
- cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL);
+ cx->vbi.sliced_mpeg_data[i] =
+ kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL);
if (cx->vbi.sliced_mpeg_data[i] == NULL) {
while (--i >= 0) {
kfree(cx->vbi.sliced_mpeg_data[i]);
cx->vbi.sliced_mpeg_data[i] = NULL;
}
+ cx->vbi.insert_mpeg =
+ V4L2_MPEG_STREAM_VBI_FMT_NONE;
+ CX18_WARN("Unable to allocate buffers for "
+ "sliced VBI data insertion\n");
return -ENOMEM;
}
}
}
cx->vbi.insert_mpeg = fmt;
+ CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS,"
+ "when sliced VBI is enabled\n");
- if (cx->vbi.insert_mpeg == 0)
- return 0;
- /* Need sliced data for mpeg insertion */
+ /*
+ * If our current settings have no lines set for capture, store a valid,
+ * default set of service lines to capture, in our current settings.
+ */
if (cx18_get_service_set(cx->vbi.sliced_in) == 0) {
if (cx->is_60hz)
- cx->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525;
+ cx->vbi.sliced_in->service_set =
+ V4L2_SLICED_CAPTION_525;
else
cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625;
cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz);
@@ -259,10 +278,12 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
return err;
}
if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ static u32 freqs[3] = { 44100, 48000, 32000 };
struct cx18_api_func_private priv;
struct cx2341x_mpeg_params p = cx->params;
int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
c, VIDIOC_S_EXT_CTRLS);
+ unsigned int idx;
if (err)
return err;
@@ -277,16 +298,23 @@ int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
fmt.fmt.pix.width = cx->params.width
/ (is_mpeg1 ? 2 : 1);
fmt.fmt.pix.height = cx->params.height;
- cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt);
+ v4l2_subdev_call(cx->sd_av, video, s_fmt, &fmt);
}
priv.cx = cx;
priv.s = &cx->streams[id->type];
err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p);
- if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt)
- err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt);
+ if (!err &&
+ (cx->params.stream_vbi_fmt != p.stream_vbi_fmt ||
+ cx->params.stream_type != p.stream_type))
+ err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt,
+ p.stream_type);
cx->params = p;
cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
- cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03);
+ idx = p.audio_properties & 0x03;
+ /* The audio clock of the digitizer must match the codec sample
+ rate otherwise you get some very strange effects. */
+ if (idx < sizeof(freqs))
+ cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
return err;
}
return -EINVAL;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index f50cf2167ad..210c68aaae0 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -39,10 +39,6 @@
#include <media/tveeprom.h>
-
-/* var to keep track of the number of array elements in use */
-int cx18_cards_active;
-
/* If you have already X v4l cards, then set this to X. This way
the device numbers stay matched. Example: you have a WinTV card
without radio and a Compro H900 with. Normally this would give a
@@ -50,12 +46,6 @@ int cx18_cards_active;
setting this to 1 you ensure that radio0 is now also radio1. */
int cx18_first_minor;
-/* Master variable for all cx18 info */
-struct cx18 *cx18_cards[CX18_MAX_CARDS];
-
-/* Protects cx18_cards_active */
-DEFINE_SPINLOCK(cx18_cards_lock);
-
/* add your revision and whatnot here */
static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
{PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418,
@@ -65,6 +55,8 @@ static struct pci_device_id cx18_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, cx18_pci_tbl);
+static atomic_t cx18_instance = ATOMIC_INIT(0);
+
/* Parameter declarations */
static int cardtype[CX18_MAX_CARDS];
static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
@@ -159,7 +151,7 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t 4 = Yuan MPC718\n"
"\t\t\t 5 = Conexant Raptor PAL/SECAM\n"
"\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n"
- "\t\t\t 7 = Leadtek WinFast PVR2100\n"
+ "\t\t\t 7 = Leadtek WinFast PVR2100/DVR3100 H\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -277,11 +269,16 @@ static void cx18_iounmap(struct cx18 *cx)
/* Hauppauge card? get values from tveeprom */
void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv)
{
+ struct i2c_client c;
u8 eedata[256];
- cx->i2c_client[0].addr = 0xA0 >> 1;
- tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata));
- tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata);
+ memset(&c, 0, sizeof(c));
+ strlcpy(c.name, "cx18 tveeprom tmp", sizeof(c.name));
+ c.adapter = &cx->i2c_adap[0];
+ c.addr = 0xA0 >> 1;
+
+ tveeprom_read(&c, eedata, sizeof(eedata));
+ tveeprom_hauppauge_analog(&c, tv, eedata);
}
static void cx18_process_eeprom(struct cx18 *cx)
@@ -448,34 +445,38 @@ static void cx18_process_options(struct cx18 *cx)
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */
+ cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_active_samples * 36;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize;
cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */
- /* Except for VBI ensure stream_buffers & stream_buf_size are valid */
+ /* Ensure stream_buffers & stream_buf_size are valid */
for (i = 0; i < CX18_MAX_STREAMS; i++) {
- /* User said to use 0 buffers */
- if (cx->stream_buffers[i] == 0) {
- cx->options.megabytes[i] = 0;
- cx->stream_buf_size[i] = 0;
- continue;
- }
- /* User said to use 0 MB total */
- if (cx->options.megabytes[i] <= 0) {
+ if (cx->stream_buffers[i] == 0 || /* User said 0 buffers */
+ cx->options.megabytes[i] <= 0 || /* User said 0 MB total */
+ cx->stream_buf_size[i] <= 0) { /* User said buf size 0 */
cx->options.megabytes[i] = 0;
cx->stream_buffers[i] = 0;
cx->stream_buf_size[i] = 0;
continue;
}
- /* VBI is computed later or user said buffer has size 0 */
- if (cx->stream_buf_size[i] <= 0) {
- if (i != CX18_ENC_STREAM_TYPE_VBI) {
- cx->options.megabytes[i] = 0;
- cx->stream_buffers[i] = 0;
- cx->stream_buf_size[i] = 0;
+ /*
+ * VBI is a special case where the stream_buf_size is fixed
+ * and already in bytes
+ */
+ if (i == CX18_ENC_STREAM_TYPE_VBI) {
+ if (cx->stream_buffers[i] < 0) {
+ cx->stream_buffers[i] =
+ cx->options.megabytes[i] * 1024 * 1024
+ / cx->stream_buf_size[i];
+ } else {
+ /* N.B. This might round down to 0 */
+ cx->options.megabytes[i] =
+ cx->stream_buffers[i]
+ * cx->stream_buf_size[i]/(1024 * 1024);
}
continue;
}
+ /* All other streams have stream_buf_size in kB at this point */
if (cx->stream_buffers[i] < 0) {
cx->stream_buffers[i] = cx->options.megabytes[i] * 1024
/ cx->stream_buf_size[i];
@@ -487,9 +488,9 @@ static void cx18_process_options(struct cx18 *cx)
cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */
}
- cx->options.cardtype = cardtype[cx->num];
- cx->options.tuner = tuner[cx->num];
- cx->options.radio = radio[cx->num];
+ cx->options.cardtype = cardtype[cx->instance];
+ cx->options.tuner = tuner[cx->instance];
+ cx->options.radio = radio[cx->instance];
cx->std = cx18_parse_std(cx);
if (cx->options.cardtype == -1) {
@@ -502,7 +503,7 @@ static void cx18_process_options(struct cx18 *cx)
else if (cx->options.cardtype != 0)
CX18_ERR("Unknown user specified type, trying to autodetect card\n");
if (cx->card == NULL) {
- if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
+ if (cx->pci_dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_INFO("Autodetected Hauppauge card\n");
}
@@ -512,13 +513,13 @@ static void cx18_process_options(struct cx18 *cx)
if (cx->card->pci_list == NULL)
continue;
for (j = 0; cx->card->pci_list[j].device; j++) {
- if (cx->dev->device !=
+ if (cx->pci_dev->device !=
cx->card->pci_list[j].device)
continue;
- if (cx->dev->subsystem_vendor !=
+ if (cx->pci_dev->subsystem_vendor !=
cx->card->pci_list[j].subsystem_vendor)
continue;
- if (cx->dev->subsystem_device !=
+ if (cx->pci_dev->subsystem_device !=
cx->card->pci_list[j].subsystem_device)
continue;
CX18_INFO("Autodetected %s card\n", cx->card->name);
@@ -531,9 +532,10 @@ done:
if (cx->card == NULL) {
cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT);
CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- cx->dev->vendor, cx->dev->device);
+ cx->pci_dev->vendor, cx->pci_dev->device);
CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- cx->dev->subsystem_vendor, cx->dev->subsystem_device);
+ cx->pci_dev->subsystem_vendor,
+ cx->pci_dev->subsystem_device);
CX18_ERR("Defaulting to %s card\n", cx->card->name);
CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n");
@@ -545,7 +547,7 @@ done:
}
/* Precondition: the cx18 structure has been memset to 0. Only
- the dev and num fields have been filled in.
+ the dev and instance fields have been filled in.
No assumptions on the card type may be made here (see cx18_init_struct2
for that).
*/
@@ -553,18 +555,14 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
{
int i;
- cx->base_addr = pci_resource_start(cx->dev, 0);
+ cx->base_addr = pci_resource_start(cx->pci_dev, 0);
mutex_init(&cx->serialize_lock);
- mutex_init(&cx->i2c_bus_lock[0]);
- mutex_init(&cx->i2c_bus_lock[1]);
mutex_init(&cx->gpio_lock);
mutex_init(&cx->epu2apu_mb_lock);
mutex_init(&cx->epu2cpu_mb_lock);
- spin_lock_init(&cx->lock);
-
- cx->work_queue = create_singlethread_workqueue(cx->name);
+ cx->work_queue = create_singlethread_workqueue(cx->v4l2_dev.name);
if (cx->work_queue == NULL) {
CX18_ERR("Unable to create work hander thread\n");
return -ENOMEM;
@@ -587,7 +585,8 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
(cx->params.video_temporal_filter_mode << 1) |
(cx->params.video_median_filter_type << 2);
cx->params.port = CX2341X_PORT_MEMORY;
- cx->params.capabilities = CX2341X_CAP_HAS_TS;
+ cx->params.capabilities =
+ CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
init_waitqueue_head(&cx->cap_w);
init_waitqueue_head(&cx->mb_apu_waitq);
init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -597,49 +596,6 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced;
- /*
- * The VBI line sizes depend on the pixel clock and the horiz rate
- *
- * (1/Fh)*(2*Fp) = Samples/line
- * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
- *
- * Sliced VBI is sent as ancillary data during horizontal blanking
- * Raw VBI is sent as active video samples during vertcal blanking
- *
- * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
- * length of 720 pixels @ 4:2:2 sampling. Thus...
- *
- * For systems that use a 15.734 kHz horizontal rate, such as
- * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
- *
- * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
- * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- * For systems that use a 15.625 kHz horizontal rate, such as
- * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
- *
- * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
- * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
- *
- */
-
- /* FIXME: init these based on tuner std & modify when std changes */
- /* CX18-AV-Core number of VBI samples output per horizontal line */
- cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */
- cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */
-
- /* CX18-AV-Core VBI samples/line possibly rounded up */
- cx->vbi.raw_size = 1444; /* Real max size is 1444 */
- cx->vbi.sliced_size = 284; /* Real max size is 284 */
-
- /*
- * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode
- * Task Field VerticalBlank HorizontalBlank 0 0 0 0
- */
- cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */
- cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */
- cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */
- cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */
return 0;
}
@@ -668,15 +624,9 @@ static void __devinit cx18_init_struct2(struct cx18 *cx)
i = 0;
cx->active_input = i;
cx->audio_input = cx->card->video_inputs[i].audio_index;
- cx->av_state.vid_input = CX18_AV_COMPOSITE7;
- cx->av_state.aud_input = CX18_AV_AUDIO8;
- cx->av_state.audclk_freq = 48000;
- cx->av_state.audmode = V4L2_TUNER_MODE_LANG1;
- /* FIXME - 8 is NTSC value, investigate */
- cx->av_state.vbi_line_offset = 8;
}
-static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
+static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
u16 cmd;
@@ -684,124 +634,125 @@ static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev,
CX18_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(dev)) {
- CX18_ERR("Can't enable device %d!\n", cx->num);
+ if (pci_enable_device(pci_dev)) {
+ CX18_ERR("Can't enable device %d!\n", cx->instance);
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
- CX18_ERR("No suitable DMA available on card %d.\n", cx->num);
+ if (pci_set_dma_mask(pci_dev, 0xffffffff)) {
+ CX18_ERR("No suitable DMA available, card %d\n", cx->instance);
return -EIO;
}
if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) {
- CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num);
+ CX18_ERR("Cannot request encoder memory region, card %d\n",
+ cx->instance);
return -EIO;
}
/* Enable bus mastering and memory mapped IO for the CX23418 */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_read_config_word(pci_dev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER;
- pci_write_config_word(dev, PCI_COMMAND, cmd);
+ pci_write_config_word(pci_dev, PCI_COMMAND, cmd);
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &cx->card_rev);
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < 64 && cx18_pci_latency) {
CX18_INFO("Unreasonably low latency timer, "
"setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, 64);
+ pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &pci_latency);
}
CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, "
"irq: %d, latency: %d, memory: 0x%lx\n",
- cx->dev->device, cx->card_rev, dev->bus->number,
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
- cx->dev->irq, pci_latency, (unsigned long)cx->base_addr);
+ cx->pci_dev->device, cx->card_rev, pci_dev->bus->number,
+ PCI_SLOT(pci_dev->devfn), PCI_FUNC(pci_dev->devfn),
+ cx->pci_dev->irq, pci_latency, (unsigned long)cx->base_addr);
return 0;
}
-#ifdef MODULE
-static u32 cx18_request_module(struct cx18 *cx, u32 hw,
- const char *name, u32 id)
-{
- if ((hw & id) == 0)
- return hw;
- if (request_module(name) != 0) {
- CX18_ERR("Failed to load module %s\n", name);
- return hw & ~id;
- }
- CX18_DEBUG_INFO("Loaded module %s\n", name);
- return hw;
-}
-#endif
-
-static void cx18_load_and_init_modules(struct cx18 *cx)
+static void cx18_init_subdevs(struct cx18 *cx)
{
u32 hw = cx->card->hw_all;
+ u32 device;
int i;
-#ifdef MODULE
- /* load modules */
-#ifdef CONFIG_MEDIA_TUNER_MODULE
- hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER);
-#endif
-#ifdef CONFIG_VIDEO_CS5345_MODULE
- hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345);
-#endif
-#endif
-
- /* check which i2c devices are actually found */
- for (i = 0; i < 32; i++) {
- u32 device = 1 << i;
+ for (i = 0, device = 1; i < 32; i++, device <<= 1) {
if (!(device & hw))
continue;
- if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM ||
- device == CX18_HW_CX23418 || device == CX18_HW_DVB) {
- /* These 'devices' do not use i2c probing */
+
+ switch (device) {
+ case CX18_HW_DVB:
+ case CX18_HW_TVEEPROM:
+ /* These subordinate devices do not use probing */
cx->hw_flags |= device;
- continue;
- }
- cx18_i2c_register(cx, i);
- if (cx18_i2c_hw_addr(cx, device) > 0)
+ break;
+ case CX18_HW_418_AV:
+ /* The A/V decoder gets probed earlier to set PLLs */
+ /* Just note that the card uses it (i.e. has analog) */
cx->hw_flags |= device;
+ break;
+ case CX18_HW_GPIO_RESET_CTRL:
+ /*
+ * The Reset Controller gets probed and added to
+ * hw_flags earlier for i2c adapter/bus initialization
+ */
+ break;
+ case CX18_HW_GPIO_MUX:
+ if (cx18_gpio_register(cx, device) == 0)
+ cx->hw_flags |= device;
+ break;
+ default:
+ if (cx18_i2c_register(cx, i) == 0)
+ cx->hw_flags |= device;
+ break;
+ }
}
- hw = cx->hw_flags;
+ if (cx->hw_flags & CX18_HW_418_AV)
+ cx->sd_av = cx18_find_hw(cx, CX18_HW_418_AV);
+
+ if (cx->card->hw_muxer != 0)
+ cx->sd_extmux = cx18_find_hw(cx, cx->card->hw_muxer);
}
-static int __devinit cx18_probe(struct pci_dev *dev,
+static int __devinit cx18_probe(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
int retval = 0;
int i;
- int vbi_buf_size;
u32 devtype;
struct cx18 *cx;
- spin_lock(&cx18_cards_lock);
-
- /* Make sure we've got a place for this card */
- if (cx18_cards_active == CX18_MAX_CARDS) {
- printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n",
- cx18_cards_active);
- spin_unlock(&cx18_cards_lock);
+ /* FIXME - module parameter arrays constrain max instances */
+ i = atomic_inc_return(&cx18_instance) - 1;
+ if (i >= CX18_MAX_CARDS) {
+ printk(KERN_ERR "cx18: cannot manage card %d, driver has a "
+ "limit of 0 - %d\n", i, CX18_MAX_CARDS - 1);
return -ENOMEM;
}
cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC);
- if (!cx) {
- spin_unlock(&cx18_cards_lock);
+ if (cx == NULL) {
+ printk(KERN_ERR "cx18: cannot manage card %d, out of memory\n",
+ i);
return -ENOMEM;
}
- cx18_cards[cx18_cards_active] = cx;
- cx->dev = dev;
- cx->num = cx18_cards_active++;
- snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num);
- CX18_INFO("Initializing card #%d\n", cx->num);
+ cx->pci_dev = pci_dev;
+ cx->instance = i;
- spin_unlock(&cx18_cards_lock);
+ retval = v4l2_device_register(&pci_dev->dev, &cx->v4l2_dev);
+ if (retval) {
+ printk(KERN_ERR "cx18: v4l2_device_register of card %d failed"
+ "\n", cx->instance);
+ kfree(cx);
+ return retval;
+ }
+ snprintf(cx->v4l2_dev.name, sizeof(cx->v4l2_dev.name), "cx18-%d",
+ cx->instance);
+ CX18_INFO("Initializing card %d\n", cx->instance);
cx18_process_options(cx);
if (cx->options.cardtype == -1) {
@@ -816,13 +767,10 @@ static int __devinit cx18_probe(struct pci_dev *dev,
CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr);
/* PCI Device Setup */
- retval = cx18_setup_pci(cx, dev, pci_id);
+ retval = cx18_setup_pci(cx, pci_dev, pci_id);
if (retval != 0)
goto free_workqueue;
- /* save cx in the pci struct for later use */
- pci_set_drvdata(dev, cx);
-
/* map io memory */
CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE);
@@ -856,6 +804,23 @@ static int __devinit cx18_probe(struct pci_dev *dev,
cx18_gpio_init(cx);
+ /* Initialize integrated A/V decoder early to set PLLs, just in case */
+ retval = cx18_av_probe(cx);
+ if (retval) {
+ CX18_ERR("Could not register A/V decoder subdevice\n");
+ goto free_map;
+ }
+ cx18_call_hw(cx, CX18_HW_418_AV, core, init, (u32) CX18_AV_INIT_PLLS);
+
+ /* Initialize GPIO Reset Controller to do chip resets during i2c init */
+ if (cx->card->hw_all & CX18_HW_GPIO_RESET_CTRL) {
+ if (cx18_gpio_register(cx, CX18_HW_GPIO_RESET_CTRL) != 0)
+ CX18_WARN("Could not register GPIO reset controller"
+ "subdevice; proceeding anyway.\n");
+ else
+ cx->hw_flags |= CX18_HW_GPIO_RESET_CTRL;
+ }
+
/* active i2c */
CX18_DEBUG_INFO("activating i2c...\n");
retval = init_cx18_i2c(cx);
@@ -864,8 +829,6 @@ static int __devinit cx18_probe(struct pci_dev *dev,
goto free_map;
}
- CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active);
-
if (cx->card->hw_all & CX18_HW_TVEEPROM) {
/* Based on the model number the cardtype may be changed.
The PCI IDs are not always reliable. */
@@ -881,8 +844,9 @@ static int __devinit cx18_probe(struct pci_dev *dev,
cx18_init_scb(cx);
/* Register IRQ */
- retval = request_irq(cx->dev->irq, cx18_irq_handler,
- IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx);
+ retval = request_irq(cx->pci_dev->irq, cx18_irq_handler,
+ IRQF_SHARED | IRQF_DISABLED,
+ cx->v4l2_dev.name, (void *)cx);
if (retval) {
CX18_ERR("Failed to register irq %d\n", retval);
goto free_i2c;
@@ -917,33 +881,14 @@ static int __devinit cx18_probe(struct pci_dev *dev,
initialization. */
cx18_init_struct2(cx);
- cx18_load_and_init_modules(cx);
+ cx18_init_subdevs(cx);
- if (cx->std & V4L2_STD_525_60) {
+ if (cx->std & V4L2_STD_525_60)
cx->is_60hz = 1;
- cx->is_out_60hz = 1;
- } else {
+ else
cx->is_50hz = 1;
- cx->is_out_50hz = 1;
- }
- cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
-
- /*
- * FIXME: setting the buffer size based on the tuner standard is
- * suboptimal, as the CVBS and SVideo inputs could use a different std
- * and the buffer could end up being too small in that case.
- */
- vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2;
- cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size;
- if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0)
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] =
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024
- / vbi_buf_size;
- else
- cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] =
- cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size
- / (1024 * 1024);
+ cx->params.video_gop_size = cx->is_60hz ? 15 : 12;
if (cx->options.radio > 0)
cx->v4l2_cap |= V4L2_CAP_RADIO;
@@ -956,7 +901,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
setup.tuner_callback = (setup.type == TUNER_XC2028) ?
cx18_reset_tuner_gpio : NULL;
- cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup);
+ cx18_call_all(cx, tuner, s_type_addr, &setup);
if (setup.type == TUNER_XC2028) {
static struct xc2028_ctrl ctrl = {
.fname = XC2028_DEFAULT_FIRMWARE,
@@ -966,7 +911,7 @@ static int __devinit cx18_probe(struct pci_dev *dev,
.tuner = cx->options.tuner,
.priv = &ctrl,
};
- cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg);
+ cx18_call_all(cx, tuner, s_config, &cfg);
}
}
@@ -985,14 +930,13 @@ static int __devinit cx18_probe(struct pci_dev *dev,
goto free_streams;
}
- CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name);
-
+ CX18_INFO("Initialized card: %s\n", cx->card_name);
return 0;
free_streams:
cx18_streams_cleanup(cx, 1);
free_irq:
- free_irq(cx->dev->irq, (void *)cx);
+ free_irq(cx->pci_dev->irq, (void *)cx);
free_i2c:
exit_cx18_i2c(cx);
free_map:
@@ -1006,11 +950,8 @@ err:
retval = -ENODEV;
CX18_ERR("Error %d on initialization\n", retval);
- i = cx->num;
- spin_lock(&cx18_cards_lock);
- kfree(cx18_cards[i]);
- cx18_cards[i] = NULL;
- spin_unlock(&cx18_cards_lock);
+ v4l2_device_unregister(&cx->v4l2_dev);
+ kfree(cx);
return retval;
}
@@ -1043,8 +984,21 @@ int cx18_init_on_first_open(struct cx18 *cx)
}
set_bit(CX18_F_I_LOADED_FW, &cx->i_flags);
- /* Init the firmware twice to work around a silicon bug
- * transport related. */
+ /*
+ * Init the firmware twice to work around a silicon bug
+ * with the digital TS.
+ *
+ * The second firmware load requires us to normalize the APU state,
+ * or the audio for the first analog capture will be badly incorrect.
+ *
+ * I can't seem to call APU_RESETAI and have it succeed without the
+ * APU capturing audio, so we start and stop it here to do the reset
+ */
+
+ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+ cx18_vapi(cx, CX18_APU_RESETAI, 0);
+ cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
fw_retry_count = 3;
while (--fw_retry_count > 0) {
@@ -1060,6 +1014,22 @@ int cx18_init_on_first_open(struct cx18 *cx)
return -ENXIO;
}
+ /*
+ * The second firmware load requires us to normalize the APU state,
+ * or the audio for the first analog capture will be badly incorrect.
+ *
+ * I can't seem to call APU_RESETAI and have it succeed without the
+ * APU capturing audio, so we start and stop it here to do the reset
+ */
+
+ /* MPEG Encoding, 224 kbps, MPEG Layer II, 48 ksps */
+ cx18_vapi(cx, CX18_APU_START, 2, CX18_APU_ENCODING_METHOD_MPEG|0xb9, 0);
+ cx18_vapi(cx, CX18_APU_RESETAI, 0);
+ cx18_vapi(cx, CX18_APU_STOP, 1, CX18_APU_ENCODING_METHOD_MPEG);
+
+ /* Init the A/V decoder, if it hasn't been already */
+ v4l2_subdev_call(cx->sd_av, core, init, (u32) CX18_AV_INIT_NORMAL);
+
vf.tuner = 0;
vf.type = V4L2_TUNER_ANALOG_TV;
vf.frequency = 6400; /* the tuner 'baseline' frequency */
@@ -1092,9 +1062,11 @@ static void cx18_cancel_epu_work_orders(struct cx18 *cx)
static void cx18_remove(struct pci_dev *pci_dev)
{
- struct cx18 *cx = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct cx18 *cx = to_cx18(v4l2_dev);
+ int i;
- CX18_DEBUG_INFO("Removing Card #%d\n", cx->num);
+ CX18_DEBUG_INFO("Removing Card\n");
/* Stop all captures */
CX18_DEBUG_INFO("Stopping all streams\n");
@@ -1115,15 +1087,22 @@ static void cx18_remove(struct pci_dev *pci_dev)
exit_cx18_i2c(cx);
- free_irq(cx->dev->irq, (void *)cx);
+ free_irq(cx->pci_dev->irq, (void *)cx);
cx18_iounmap(cx);
release_mem_region(cx->base_addr, CX18_MEM_SIZE);
- pci_disable_device(cx->dev);
+ pci_disable_device(cx->pci_dev);
+
+ if (cx->vbi.sliced_mpeg_data[0] != NULL)
+ for (i = 0; i < CX18_VBI_FRAMES; i++)
+ kfree(cx->vbi.sliced_mpeg_data[i]);
+
+ CX18_INFO("Removed %s\n", cx->card_name);
- CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num);
+ v4l2_device_unregister(v4l2_dev);
+ kfree(cx);
}
/* define a pci_driver for card detection */
@@ -1138,8 +1117,6 @@ static int module_start(void)
{
printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION);
- memset(cx18_cards, 0, sizeof(cx18_cards));
-
/* Validate parameters */
if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) {
printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n",
@@ -1162,16 +1139,7 @@ static int module_start(void)
static void module_cleanup(void)
{
- int i;
-
pci_unregister_driver(&cx18_pci_driver);
-
- for (i = 0; i < cx18_cards_active; i++) {
- if (cx18_cards[i] == NULL)
- continue;
- kfree(cx18_cards[i]);
- }
-
}
module_init(module_start);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index 0d2edebc39b..ece4f281ef4 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -48,6 +48,7 @@
#include <linux/dvb/audio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include "cx18-mailbox.h"
#include "cx18-av-core.h"
@@ -79,7 +80,7 @@
#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */
#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */
#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/
-#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */
+#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100/DVR3100 H */
#define CX18_CARD_LAST 6
#define CX18_ENC_STREAM_TYPE_MPG 0
@@ -143,12 +144,12 @@
/* Flag to turn on high volume debugging */
#define CX18_DBGFLG_HIGHVOL (1 << 8)
-/* NOTE: extra space before comma in 'cx->num , ## args' is required for
+/* NOTE: extra space before comma in 'fmt , ## args' is required for
gcc-2.95, otherwise it won't compile. */
#define CX18_DEBUG(x, type, fmt, args...) \
do { \
if ((x) & cx18_debug) \
- printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \
+ v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
} while (0)
#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args)
#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -162,7 +163,7 @@
#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \
do { \
if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
- printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \
+ v4l2_info(&cx->v4l2_dev, " " type ": " fmt , ## args); \
} while (0)
#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args)
#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args)
@@ -174,9 +175,58 @@
#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args)
/* Standard kernel messages */
-#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args)
-#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args)
-#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args)
+#define CX18_ERR(fmt, args...) v4l2_err(&cx->v4l2_dev, fmt , ## args)
+#define CX18_WARN(fmt, args...) v4l2_warn(&cx->v4l2_dev, fmt , ## args)
+#define CX18_INFO(fmt, args...) v4l2_info(&cx->v4l2_dev, fmt , ## args)
+
+/* Messages for internal subdevs to use */
+#define CX18_DEBUG_DEV(x, dev, type, fmt, args...) \
+ do { \
+ if ((x) & cx18_debug) \
+ v4l2_info(dev, " " type ": " fmt , ## args); \
+ } while (0)
+#define CX18_DEBUG_WARN_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
+#define CX18_DEBUG_INFO_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
+#define CX18_DEBUG_API_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
+#define CX18_DEBUG_DMA_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
+#define CX18_DEBUG_IOCTL_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
+#define CX18_DEBUG_FILE_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
+#define CX18_DEBUG_I2C_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
+#define CX18_DEBUG_IRQ_DEV(dev, fmt, args...) \
+ CX18_DEBUG_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
+
+#define CX18_DEBUG_HIGH_VOL_DEV(x, dev, type, fmt, args...) \
+ do { \
+ if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \
+ v4l2_info(dev, " " type ": " fmt , ## args); \
+ } while (0)
+#define CX18_DEBUG_HI_WARN_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_WARN, dev, "warning", fmt , ## args)
+#define CX18_DEBUG_HI_INFO_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_INFO, dev, "info", fmt , ## args)
+#define CX18_DEBUG_HI_API_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_API, dev, "api", fmt , ## args)
+#define CX18_DEBUG_HI_DMA_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_DMA, dev, "dma", fmt , ## args)
+#define CX18_DEBUG_HI_IOCTL_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IOCTL, dev, "ioctl", fmt , ## args)
+#define CX18_DEBUG_HI_FILE_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_FILE, dev, "file", fmt , ## args)
+#define CX18_DEBUG_HI_I2C_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_I2C, dev, "i2c", fmt , ## args)
+#define CX18_DEBUG_HI_IRQ_DEV(dev, fmt, args...) \
+ CX18_DEBUG_HIGH_VOL_DEV(CX18_DBGFLG_IRQ, dev, "irq", fmt , ## args)
+
+#define CX18_ERR_DEV(dev, fmt, args...) v4l2_err(dev, fmt , ## args)
+#define CX18_WARN_DEV(dev, fmt, args...) v4l2_warn(dev, fmt , ## args)
+#define CX18_INFO_DEV(dev, fmt, args...) v4l2_info(dev, fmt , ## args)
/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */
#define MPEG_FRAME_TYPE_IFRAME 1
@@ -279,7 +329,7 @@ struct cx18_epu_work_order {
struct cx18_stream {
/* These first four fields are always set, even if the stream
is not actually created. */
- struct video_device *v4l2dev; /* NULL when stream not created */
+ struct video_device *video_dev; /* NULL when stream not created */
struct cx18 *cx; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
@@ -292,7 +342,6 @@ struct cx18_stream {
int dma; /* can be PCI_DMA_TODEVICE,
PCI_DMA_FROMDEVICE or
PCI_DMA_NONE */
- u64 dma_pts;
wait_queue_head_t waitq;
/* Buffer Stats */
@@ -318,59 +367,121 @@ struct cx18_open_id {
/* forward declaration of struct defined in cx18-cards.h */
struct cx18_card;
+/*
+ * A note about "sliced" VBI data as implemented in this driver:
+ *
+ * Currently we collect the sliced VBI in the form of Ancillary Data
+ * packets, inserted by the AV core decoder/digitizer/slicer in the
+ * horizontal blanking region of the VBI lines, in "raw" mode as far as
+ * the Encoder is concerned. We don't ever tell the Encoder itself
+ * to provide sliced VBI. (AV Core: sliced mode - Encoder: raw mode)
+ *
+ * We then process the ancillary data ourselves to send the sliced data
+ * to the user application directly or build up MPEG-2 private stream 1
+ * packets to splice into (only!) MPEG-2 PS streams for the user app.
+ *
+ * (That's how ivtv essentially does it.)
+ *
+ * The Encoder should be able to extract certain sliced VBI data for
+ * us and provide it in a separate stream or splice it into any type of
+ * MPEG PS or TS stream, but this isn't implemented yet.
+ */
+
+/*
+ * Number of "raw" VBI samples per horizontal line we tell the Encoder to
+ * grab from the decoder/digitizer/slicer output for raw or sliced VBI.
+ * It depends on the pixel clock and the horiz rate:
+ *
+ * (1/Fh)*(2*Fp) = Samples/line
+ * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples
+ *
+ * Sliced VBI data is sent as ancillary data during horizontal blanking
+ * Raw VBI is sent as active video samples during vertcal blanking
+ *
+ * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line
+ * length of 720 pixels @ 4:2:2 sampling. Thus...
+ *
+ * For systems that use a 15.734 kHz horizontal rate, such as
+ * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have:
+ *
+ * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line =
+ * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples
+ *
+ * For systems that use a 15.625 kHz horizontal rate, such as
+ * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have:
+ *
+ * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line =
+ * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples
+ */
+static const u32 vbi_active_samples = 1444; /* 4 byte SAV + 720 Y + 720 U/V */
+static const u32 vbi_hblank_samples_60Hz = 272; /* 4 byte EAV + 268 anc/fill */
+static const u32 vbi_hblank_samples_50Hz = 284; /* 4 byte EAV + 280 anc/fill */
#define CX18_VBI_FRAMES 32
-/* VBI data */
struct vbi_info {
- u32 enc_size;
- u32 frame;
- u8 cc_data_odd[256];
- u8 cc_data_even[256];
- int cc_pos;
- u8 cc_no_update;
- u8 vps[5];
- u8 vps_found;
- int wss;
- u8 wss_found;
- u8 wss_no_update;
- u32 raw_decoder_line_size;
- u8 raw_decoder_sav_odd_field;
- u8 raw_decoder_sav_even_field;
- u32 sliced_decoder_line_size;
- u8 sliced_decoder_sav_odd_field;
- u8 sliced_decoder_sav_even_field;
+ /* Current state of v4l2 VBI settings for this device */
struct v4l2_format in;
- /* convenience pointer to sliced struct in vbi_in union */
- struct v4l2_sliced_vbi_format *sliced_in;
- u32 service_set_in;
- int insert_mpeg;
+ struct v4l2_sliced_vbi_format *sliced_in; /* pointer to in.fmt.sliced */
+ u32 count; /* Count of VBI data lines: 60 Hz: 12 or 50 Hz: 18 */
+ u32 start[2]; /* First VBI data line per field: 10 & 273 or 6 & 318 */
- /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
- One for /dev/vbi0 and one for /dev/vbi8 */
- struct v4l2_sliced_vbi_data sliced_data[36];
+ u32 frame; /* Count of VBI buffers/frames received from Encoder */
- /* Buffer for VBI data inserted into MPEG stream.
- The first byte is a dummy byte that's never used.
- The next 16 bytes contain the MPEG header for the VBI data,
- the remainder is the actual VBI data.
- The max size accepted by the MPEG VBI reinsertion turns out
- to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes,
- where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is
- a single line header byte and 2 * 18 is the number of VBI lines per frame.
+ /*
+ * Vars for creation and insertion of MPEG Private Stream 1 packets
+ * of sliced VBI data into an MPEG PS
+ */
- However, it seems that the data must be 1K aligned, so we have to
- pad the data until the 1 or 2 K boundary.
+ /* Boolean: create and insert Private Stream 1 packets into the PS */
+ int insert_mpeg;
+
+ /*
+ * Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines.
+ * Used in cx18-vbi.c only for collecting sliced data, and as a source
+ * during conversion of sliced VBI data into MPEG Priv Stream 1 packets.
+ * We don't need to save state here, but the array may have been a bit
+ * too big (2304 bytes) to alloc from the stack.
+ */
+ struct v4l2_sliced_vbi_data sliced_data[36];
- This pointer array will allocate 2049 bytes to store each VBI frame. */
+ /*
+ * A ring buffer of driver-generated MPEG-2 PS
+ * Program Pack/Private Stream 1 packets for sliced VBI data insertion
+ * into the MPEG PS stream.
+ *
+ * In each sliced_mpeg_data[] buffer is:
+ * 16 byte MPEG-2 PS Program Pack Header
+ * 16 byte MPEG-2 Private Stream 1 PES Header
+ * 4 byte magic number: "itv0" or "ITV0"
+ * 4 byte first field line mask, if "itv0"
+ * 4 byte second field line mask, if "itv0"
+ * 36 lines, if "ITV0"; or <36 lines, if "itv0"; of sliced VBI data
+ *
+ * Each line in the payload is
+ * 1 byte line header derived from the SDID (WSS, CC, VPS, etc.)
+ * 42 bytes of line data
+ *
+ * That's a maximum 1552 bytes of payload in the Private Stream 1 packet
+ * which is the payload size a PVR-350 (CX23415) MPEG decoder will
+ * accept for VBI data. So, including the headers, it's a maximum 1584
+ * bytes total.
+ */
+#define CX18_SLICED_MPEG_DATA_MAXSZ 1584
+ /* copy_vbi_buf() needs 8 temp bytes on the end for the worst case */
+#define CX18_SLICED_MPEG_DATA_BUFSZ (CX18_SLICED_MPEG_DATA_MAXSZ+8)
u8 *sliced_mpeg_data[CX18_VBI_FRAMES];
u32 sliced_mpeg_size[CX18_VBI_FRAMES];
- struct cx18_buffer sliced_mpeg_buf;
+
+ /* Count of Program Pack/Program Stream 1 packets inserted into PS */
u32 inserted_frame;
- u32 start[2], count;
- u32 raw_size;
- u32 sliced_size;
+ /*
+ * A dummy driver stream transfer buffer with a copy of the next
+ * sliced_mpeg_data[] buffer for output to userland apps.
+ * Only used in cx18-fileops.c, but its state needs to persist at times.
+ */
+ struct cx18_buffer sliced_mpeg_buf;
};
/* Per cx23418, per I2C bus private algo callback data */
@@ -383,16 +494,17 @@ struct cx18_i2c_algo_callback_data {
/* Struct to hold info about cx18 cards */
struct cx18 {
- int num; /* board number, -1 during init! */
- char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */
- struct pci_dev *dev; /* PCI device */
+ int instance;
+ struct pci_dev *pci_dev;
+ struct v4l2_device v4l2_dev;
+ struct v4l2_subdev *sd_av; /* A/V decoder/digitizer sub-device */
+ struct v4l2_subdev *sd_extmux; /* External multiplexer sub-dev */
+
const struct cx18_card *card; /* card information */
const char *card_name; /* full name of the card */
const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
u8 is_50hz;
u8 is_60hz;
- u8 is_out_50hz;
- u8 is_out_60hz;
u8 nof_inputs; /* number of video inputs */
u8 nof_audio_inputs; /* number of audio inputs */
u16 buffer_id; /* buffer ID counter */
@@ -413,10 +525,7 @@ struct cx18 {
/* dualwatch */
unsigned long dualwatch_jiffies;
- u16 dualwatch_stereo_mode;
-
- /* Digitizer type */
- int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */
+ u32 dualwatch_stereo_mode;
struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */
struct cx18_options options; /* User options */
@@ -426,7 +535,6 @@ struct cx18 {
unsigned long i_flags; /* global cx18 flags */
atomic_t ana_capturing; /* count number of active analog capture streams */
atomic_t tot_capturing; /* total count number of active capture streams */
- spinlock_t lock; /* lock access to this struct */
int search_pack_header;
int open_id; /* incremented each time an open occurs, used as
@@ -468,30 +576,30 @@ struct cx18 {
struct i2c_adapter i2c_adap[2];
struct i2c_algo_bit_data i2c_algo[2];
struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2];
- struct i2c_client i2c_client[2];
- struct mutex i2c_bus_lock[2];
- struct i2c_client *i2c_clients[I2C_CLIENTS_MAX];
/* gpio */
u32 gpio_dir;
u32 gpio_val;
struct mutex gpio_lock;
+ struct v4l2_subdev sd_gpiomux;
+ struct v4l2_subdev sd_resetctrl;
/* v4l2 and User settings */
/* codec settings */
u32 audio_input;
u32 active_input;
- u32 active_output;
v4l2_std_id std;
v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */
};
+static inline struct cx18 *to_cx18(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct cx18, v4l2_dev);
+}
+
/* Globals */
-extern struct cx18 *cx18_cards[];
-extern int cx18_cards_active;
extern int cx18_first_minor;
-extern spinlock_t cx18_cards_lock;
/*==============Prototypes==================*/
@@ -511,4 +619,22 @@ static inline int cx18_raw_vbi(const struct cx18 *cx)
return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE;
}
+/* Call the specified callback for all subdevs with a grp_id bit matching the
+ * mask in hw (if 0, then match them all). Ignore any errors. */
+#define cx18_call_hw(cx, hw, o, f, args...) \
+ __v4l2_device_call_subdevs(&(cx)->v4l2_dev, \
+ !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+
+#define cx18_call_all(cx, o, f, args...) cx18_call_hw(cx, 0, o, f , ##args)
+
+/* Call the specified callback for all subdevs with a grp_id bit matching the
+ * mask in hw (if 0, then match them all). If the callback returns an error
+ * other than 0 or -ENOIOCTLCMD, then return with that error code. */
+#define cx18_call_hw_err(cx, hw, o, f, args...) \
+ __v4l2_device_call_subdevs_until_err( \
+ &(cx)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+
+#define cx18_call_all_err(cx, o, f, args...) \
+ cx18_call_hw_err(cx, 0, o, f , ##args)
+
#endif /* CX18_DRIVER_H */
diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c
index bd5e6f3fd4d..3b86f57cd15 100644
--- a/drivers/media/video/cx18/cx18-dvb.c
+++ b/drivers/media/video/cx18/cx18-dvb.c
@@ -167,7 +167,7 @@ int cx18_dvb_register(struct cx18_stream *stream)
ret = dvb_register_adapter(&dvb->dvb_adapter,
CX18_DRIVER_NAME,
- THIS_MODULE, &cx->dev->dev, adapter_nr);
+ THIS_MODULE, &cx->pci_dev->dev, adapter_nr);
if (ret < 0)
goto err_out;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 055f6e004b2..4d7d6d5a7f8 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -128,15 +128,15 @@ static void cx18_release_stream(struct cx18_stream *s)
static void cx18_dualwatch(struct cx18 *cx)
{
struct v4l2_tuner vt;
- u16 new_bitmap;
- u16 new_stereo_mode;
- const u16 stereo_mask = 0x0300;
- const u16 dual = 0x0200;
+ u32 new_bitmap;
+ u32 new_stereo_mode;
+ const u32 stereo_mask = 0x0300;
+ const u32 dual = 0x0200;
u32 h;
new_stereo_mode = cx->params.audio_properties & stereo_mask;
memset(&vt, 0, sizeof(vt));
- cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, &vt);
+ cx18_call_all(cx, tuner, g_tuner, &vt);
if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
(vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
new_stereo_mode = dual;
@@ -176,6 +176,8 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
*err = 0;
while (1) {
if (s->type == CX18_ENC_STREAM_TYPE_MPG) {
+ /* Process pending program info updates and pending
+ VBI data */
if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) {
cx->dualwatch_jiffies = jiffies;
@@ -186,7 +188,6 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) {
/* byteswap and process VBI data */
cx18_process_vbi_data(cx, buf,
- s_vbi->dma_pts,
s_vbi->type);
cx18_stream_put_buf_fw(s_vbi, buf);
}
@@ -207,8 +208,7 @@ static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block,
cx18_buf_swap(buf);
else {
/* byteswap and process VBI data */
- cx18_process_vbi_data(cx, buf,
- s->dma_pts, s->type);
+ cx18_process_vbi_data(cx, buf, s->type);
}
return buf;
}
@@ -260,6 +260,20 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
len = ucount;
if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG &&
!cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) {
+ /*
+ * Try to find a good splice point in the PS, just before
+ * an MPEG-2 Program Pack start code, and provide only
+ * up to that point to the user, so it's easy to insert VBI data
+ * the next time around.
+ */
+ /* FIXME - This only works for an MPEG-2 PS, not a TS */
+ /*
+ * An MPEG-2 Program Stream (PS) is a series of
+ * MPEG-2 Program Packs terminated by an
+ * MPEG Program End Code after the last Program Pack.
+ * A Program Pack may hold a PS System Header packet and any
+ * number of Program Elementary Stream (PES) Packets
+ */
const char *start = buf->buf + buf->readpos;
const char *p = start + 1;
const u8 *q;
@@ -267,38 +281,54 @@ static size_t cx18_copy_buf_to_user(struct cx18_stream *s,
int stuffing, i;
while (start + len > p) {
+ /* Scan for a 0 to find a potential MPEG-2 start code */
q = memchr(p, 0, start + len - p);
if (q == NULL)
break;
p = q + 1;
+ /*
+ * Keep looking if not a
+ * MPEG-2 Pack header start code: 0x00 0x00 0x01 0xba
+ * or MPEG-2 video PES start code: 0x00 0x00 0x01 0xe0
+ */
if ((char *)q + 15 >= buf->buf + buf->bytesused ||
q[1] != 0 || q[2] != 1 || q[3] != ch)
continue;
+
+ /* If expecting the primary video PES */
if (!cx->search_pack_header) {
+ /* Continue if it couldn't be a PES packet */
if ((q[6] & 0xc0) != 0x80)
continue;
- if (((q[7] & 0xc0) == 0x80 &&
- (q[9] & 0xf0) == 0x20) ||
- ((q[7] & 0xc0) == 0xc0 &&
- (q[9] & 0xf0) == 0x30)) {
- ch = 0xba;
+ /* Check if a PTS or PTS & DTS follow */
+ if (((q[7] & 0xc0) == 0x80 && /* PTS only */
+ (q[9] & 0xf0) == 0x20) || /* PTS only */
+ ((q[7] & 0xc0) == 0xc0 && /* PTS & DTS */
+ (q[9] & 0xf0) == 0x30)) { /* DTS follows */
+ /* Assume we found the video PES hdr */
+ ch = 0xba; /* next want a Program Pack*/
cx->search_pack_header = 1;
- p = q + 9;
+ p = q + 9; /* Skip this video PES hdr */
}
continue;
}
+
+ /* We may have found a Program Pack start code */
+
+ /* Get the count of stuffing bytes & verify them */
stuffing = q[13] & 7;
/* all stuffing bytes must be 0xff */
for (i = 0; i < stuffing; i++)
if (q[14 + i] != 0xff)
break;
- if (i == stuffing &&
- (q[4] & 0xc4) == 0x44 &&
- (q[12] & 3) == 3 &&
- q[14 + stuffing] == 0 &&
+ if (i == stuffing && /* right number of stuffing bytes*/
+ (q[4] & 0xc4) == 0x44 && /* marker check */
+ (q[12] & 3) == 3 && /* marker check */
+ q[14 + stuffing] == 0 && /* PES Pack or Sys Hdr */
q[15 + stuffing] == 0 &&
q[16 + stuffing] == 1) {
- cx->search_pack_header = 0;
+ /* We declare we actually found a Program Pack*/
+ cx->search_pack_header = 0; /* expect vid PES */
len = (char *)q - start;
cx18_setup_sliced_vbi_buf(cx);
break;
@@ -578,7 +608,7 @@ int cx18_v4l2_close(struct file *filp)
/* Mark that the radio is no longer in use */
clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags);
/* Switch tuner to TV */
- cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+ cx18_call_all(cx, tuner, s_std, cx->std);
/* Select correct audio input (i.e. TV tuner or Line in) */
cx18_audio_set_io(cx);
if (atomic_read(&cx->ana_capturing) > 0) {
@@ -641,7 +671,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
/* We have the radio */
cx18_mute(cx);
/* Switch tuner to radio */
- cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL);
+ cx18_call_all(cx, tuner, s_radio);
/* Select the correct audio input (i.e. radio tuner) */
cx18_audio_set_io(cx);
/* Done! Unmute and continue. */
@@ -652,38 +682,15 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
int cx18_v4l2_open(struct file *filp)
{
- int res, x, y = 0;
- struct cx18 *cx = NULL;
- struct cx18_stream *s = NULL;
- int minor = video_devdata(filp)->minor;
-
- /* Find which card this open was on */
- spin_lock(&cx18_cards_lock);
- for (x = 0; cx == NULL && x < cx18_cards_active; x++) {
- /* find out which stream this open was on */
- for (y = 0; y < CX18_MAX_STREAMS; y++) {
- if (cx18_cards[x] == NULL)
- continue;
- s = &cx18_cards[x]->streams[y];
- if (s->v4l2dev && s->v4l2dev->minor == minor) {
- cx = cx18_cards[x];
- break;
- }
- }
- }
- spin_unlock(&cx18_cards_lock);
-
- if (cx == NULL) {
- /* Couldn't find a device registered
- on that minor, shouldn't happen! */
- printk(KERN_WARNING "No cx18 device found on minor %d\n",
- minor);
- return -ENXIO;
- }
+ int res;
+ struct video_device *video_dev = video_devdata(filp);
+ struct cx18_stream *s = video_get_drvdata(video_dev);
+ struct cx18 *cx = s->cx;;
mutex_lock(&cx->serialize_lock);
if (cx18_init_on_first_open(cx)) {
- CX18_ERR("Failed to initialize on minor %d\n", minor);
+ CX18_ERR("Failed to initialize on minor %d\n",
+ video_dev->minor);
mutex_unlock(&cx->serialize_lock);
return -ENXIO;
}
diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c
index 1fa95da1575..83cd559cc60 100644
--- a/drivers/media/video/cx18/cx18-firmware.c
+++ b/drivers/media/video/cx18/cx18-firmware.c
@@ -26,7 +26,6 @@
#include "cx18-irq.h"
#include "cx18-firmware.h"
#include "cx18-cards.h"
-#include "cx18-av-core.h"
#include <linux/firmware.h>
#define CX18_PROC_SOFT_RESET 0xc70010
@@ -107,7 +106,7 @@ static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx)
u32 __iomem *dst = (u32 __iomem *)mem;
const u32 *src;
- if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("Unable to open firmware %s\n", fn);
CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n");
return -ENOMEM;
@@ -151,7 +150,7 @@ static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx,
u32 apu_version = 0;
int sz;
- if (request_firmware(&fw, fn, &cx->dev->dev)) {
+ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) {
CX18_ERR("unable to open firmware %s\n", fn);
CX18_ERR("did you put the firmware in the hotplug firmware directory?\n");
cx18_setup_page(cx, 0);
@@ -286,23 +285,6 @@ void cx18_init_power(struct cx18 *cx, int lowpwr)
cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC);
cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST);
- /*
- * VDCLK Integer = 0x0f, Post Divider = 0x04
- * AIMCLK Integer = 0x0e, Post Divider = 0x16
- */
- cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f);
-
- /* VDCLK Fraction = 0x2be2fe */
- /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */
- cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe);
-
- /* AIMCLK Fraction = 0x05227ad */
- /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */
- cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad);
-
- /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */
- cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56);
-
/* Defaults */
/* APU = SC or SC/2 = 125/62.5 */
/* EPU = SC = 125 */
diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c
index 1a99329f33c..5518d1424f8 100644
--- a/drivers/media/video/cx18/cx18-gpio.c
+++ b/drivers/media/video/cx18/cx18-gpio.c
@@ -46,6 +46,9 @@
* gpio13: cs5345 reset pin
*/
+/*
+ * File scope utility functions
+ */
static void gpio_write(struct cx18 *cx)
{
u32 dir_lo = cx->gpio_dir & 0xffff;
@@ -63,73 +66,201 @@ static void gpio_write(struct cx18 *cx)
CX18_REG_GPIO_OUT2, val_hi, dir_hi);
}
-void cx18_reset_i2c_slaves_gpio(struct cx18 *cx)
+static void gpio_update(struct cx18 *cx, u32 mask, u32 data)
{
- const struct cx18_gpio_i2c_slave_reset *p;
+ if (mask == 0)
+ return;
- p = &cx->card->gpio_i2c_slave_reset;
+ mutex_lock(&cx->gpio_lock);
+ cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
+ gpio_write(cx);
+ mutex_unlock(&cx->gpio_lock);
+}
+
+static void gpio_reset_seq(struct cx18 *cx, u32 active_lo, u32 active_hi,
+ unsigned int assert_msecs,
+ unsigned int recovery_msecs)
+{
+ u32 mask;
- if ((p->active_lo_mask | p->active_hi_mask) == 0)
+ mask = active_lo | active_hi;
+ if (mask == 0)
return;
- /* Assuming that the masks are a subset of the bits in gpio_dir */
+ /*
+ * Assuming that active_hi and active_lo are a subsets of the bits in
+ * gpio_dir. Also assumes that active_lo and active_hi don't overlap
+ * in any bit position
+ */
/* Assert */
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val =
- (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask);
- gpio_write(cx);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+ gpio_update(cx, mask, ~active_lo);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(assert_msecs));
/* Deassert */
- cx->gpio_val =
- (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask);
- gpio_write(cx);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+ gpio_update(cx, mask, ~active_hi);
+ schedule_timeout_uninterruptible(msecs_to_jiffies(recovery_msecs));
+}
+
+/*
+ * GPIO Multiplexer - logical device
+ */
+static int gpiomux_log_status(struct v4l2_subdev *sd)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+
+ mutex_lock(&cx->gpio_lock);
+ CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
+ cx->gpio_dir, cx->gpio_val);
mutex_unlock(&cx->gpio_lock);
+ return 0;
}
-void cx18_reset_ir_gpio(void *data)
+static int gpiomux_s_radio(struct v4l2_subdev *sd)
{
- struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx;
- const struct cx18_gpio_i2c_slave_reset *p;
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
- p = &cx->card->gpio_i2c_slave_reset;
+ /*
+ * FIXME - work out the cx->active/audio_input mess - this is
+ * intended to handle the switch to radio mode and set the
+ * audio routing, but we need to update the state in cx
+ */
+ gpio_update(cx, cx->card->gpio_audio_input.mask,
+ cx->card->gpio_audio_input.radio);
+ return 0;
+}
- if (p->ir_reset_mask == 0)
- return;
+static int gpiomux_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u32 data;
- CX18_DEBUG_INFO("Resetting IR microcontroller\n");
+ switch (cx->card->audio_inputs[cx->audio_input].muxer_input) {
+ case 1:
+ data = cx->card->gpio_audio_input.linein;
+ break;
+ case 0:
+ data = cx->card->gpio_audio_input.tuner;
+ break;
+ default:
+ /*
+ * FIXME - work out the cx->active/audio_input mess - this is
+ * intended to handle the switch from radio mode and set the
+ * audio routing, but we need to update the state in cx
+ */
+ data = cx->card->gpio_audio_input.tuner;
+ break;
+ }
+ gpio_update(cx, cx->card->gpio_audio_input.mask, data);
+ return 0;
+}
- /*
- Assert timing for the Z8F0811 on HVR-1600 boards:
- 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate
- 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles
- (6,601,085 nanoseconds ~= 7 milliseconds)
- 3. DBG pin must be high before chip exits reset for normal operation.
- DBG is open drain and hopefully pulled high since we don't
- normally drive it (GPIO 1?) for the HVR-1600
- 4. Z8F0811 won't exit reset until RESET is deasserted
- */
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask;
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted));
+static int gpiomux_s_audio_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ u32 data;
+
+ switch (route->input) {
+ case 0:
+ data = cx->card->gpio_audio_input.tuner;
+ break;
+ case 1:
+ data = cx->card->gpio_audio_input.linein;
+ break;
+ case 2:
+ data = cx->card->gpio_audio_input.radio;
+ break;
+ default:
+ return -EINVAL;
+ }
+ gpio_update(cx, cx->card->gpio_audio_input.mask, data);
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops gpiomux_core_ops = {
+ .log_status = gpiomux_log_status,
+};
+
+static const struct v4l2_subdev_tuner_ops gpiomux_tuner_ops = {
+ .s_std = gpiomux_s_std,
+ .s_radio = gpiomux_s_radio,
+};
+
+static const struct v4l2_subdev_audio_ops gpiomux_audio_ops = {
+ .s_routing = gpiomux_s_audio_routing,
+};
+
+static const struct v4l2_subdev_ops gpiomux_ops = {
+ .core = &gpiomux_core_ops,
+ .tuner = &gpiomux_tuner_ops,
+ .audio = &gpiomux_audio_ops,
+};
+
+/*
+ * GPIO Reset Controller - logical device
+ */
+static int resetctrl_log_status(struct v4l2_subdev *sd)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
- /*
- Zilog comes out of reset, loads reset vector address and executes
- from there. Required recovery delay unknown.
- */
mutex_lock(&cx->gpio_lock);
- cx->gpio_val = cx->gpio_val | p->ir_reset_mask;
- gpio_write(cx);
+ CX18_INFO_DEV(sd, "GPIO: direction 0x%08x, value 0x%08x\n",
+ cx->gpio_dir, cx->gpio_val);
mutex_unlock(&cx->gpio_lock);
- schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery));
+ return 0;
}
-EXPORT_SYMBOL(cx18_reset_ir_gpio);
-/* This symbol is exported for use by an infrared module for the IR-blaster */
+static int resetctrl_reset(struct v4l2_subdev *sd, u32 val)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ const struct cx18_gpio_i2c_slave_reset *p;
+
+ p = &cx->card->gpio_i2c_slave_reset;
+ switch (val) {
+ case CX18_GPIO_RESET_I2C:
+ gpio_reset_seq(cx, p->active_lo_mask, p->active_hi_mask,
+ p->msecs_asserted, p->msecs_recovery);
+ break;
+ case CX18_GPIO_RESET_Z8F0811:
+ /*
+ * Assert timing for the Z8F0811 on HVR-1600 boards:
+ * 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to
+ * initiate
+ * 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock
+ * cycles (6,601,085 nanoseconds ~= 7 milliseconds)
+ * 3. DBG pin must be high before chip exits reset for normal
+ * operation. DBG is open drain and hopefully pulled high
+ * since we don't normally drive it (GPIO 1?) for the
+ * HVR-1600
+ * 4. Z8F0811 won't exit reset until RESET is deasserted
+ * 5. Zilog comes out of reset, loads reset vector address and
+ * executes from there. Required recovery delay unknown.
+ */
+ gpio_reset_seq(cx, p->ir_reset_mask, 0,
+ p->msecs_asserted, p->msecs_recovery);
+ break;
+ case CX18_GPIO_RESET_XC2028:
+ if (cx->card->tuners[0].tuner == TUNER_XC2028)
+ gpio_reset_seq(cx, (1 << cx->card->xceive_pin), 0,
+ 1, 1);
+ break;
+ }
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops resetctrl_core_ops = {
+ .log_status = resetctrl_log_status,
+ .reset = resetctrl_reset,
+};
+
+static const struct v4l2_subdev_ops resetctrl_ops = {
+ .core = &resetctrl_core_ops,
+};
+
+/*
+ * External entry points
+ */
void cx18_gpio_init(struct cx18 *cx)
{
mutex_lock(&cx->gpio_lock);
@@ -156,6 +287,49 @@ void cx18_gpio_init(struct cx18 *cx)
mutex_unlock(&cx->gpio_lock);
}
+int cx18_gpio_register(struct cx18 *cx, u32 hw)
+{
+ struct v4l2_subdev *sd;
+ const struct v4l2_subdev_ops *ops;
+ char *str;
+
+ switch (hw) {
+ case CX18_HW_GPIO_MUX:
+ sd = &cx->sd_gpiomux;
+ ops = &gpiomux_ops;
+ str = "gpio-mux";
+ break;
+ case CX18_HW_GPIO_RESET_CTRL:
+ sd = &cx->sd_resetctrl;
+ ops = &resetctrl_ops;
+ str = "gpio-reset-ctrl";
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ v4l2_subdev_init(sd, ops);
+ v4l2_set_subdevdata(sd, cx);
+ snprintf(sd->name, sizeof(sd->name), "%s %s", cx->v4l2_dev.name, str);
+ sd->grp_id = hw;
+ return v4l2_device_register_subdev(&cx->v4l2_dev, sd);
+}
+
+void cx18_reset_ir_gpio(void *data)
+{
+ struct cx18 *cx = to_cx18((struct v4l2_device *)data);
+
+ if (cx->card->gpio_i2c_slave_reset.ir_reset_mask == 0)
+ return;
+
+ CX18_DEBUG_INFO("Resetting IR microcontroller\n");
+
+ v4l2_subdev_call(&cx->sd_resetctrl,
+ core, reset, CX18_GPIO_RESET_Z8F0811);
+}
+EXPORT_SYMBOL(cx18_reset_ir_gpio);
+/* This symbol is exported for use by lirc_pvr150 for the IR-blaster */
+
/* Xceive tuner reset function */
int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
{
@@ -163,56 +337,11 @@ int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value)
struct cx18_i2c_algo_callback_data *cb_data = algo->data;
struct cx18 *cx = cb_data->cx;
- if (cmd != XC2028_TUNER_RESET)
+ if (cmd != XC2028_TUNER_RESET ||
+ cx->card->tuners[0].tuner != TUNER_XC2028)
return 0;
- CX18_DEBUG_INFO("Resetting tuner\n");
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val &= ~(1 << cx->card->xceive_pin);
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
-
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val |= 1 << cx->card->xceive_pin;
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- schedule_timeout_interruptible(msecs_to_jiffies(1));
- return 0;
-}
-
-int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg)
-{
- struct v4l2_routing *route = arg;
- u32 mask, data;
-
- switch (command) {
- case VIDIOC_INT_S_AUDIO_ROUTING:
- if (route->input > 2)
- return -EINVAL;
- mask = cx->card->gpio_audio_input.mask;
- switch (route->input) {
- case 0:
- data = cx->card->gpio_audio_input.tuner;
- break;
- case 1:
- data = cx->card->gpio_audio_input.linein;
- break;
- case 2:
- default:
- data = cx->card->gpio_audio_input.radio;
- break;
- }
- break;
-
- default:
- return -EINVAL;
- }
- if (mask) {
- mutex_lock(&cx->gpio_lock);
- cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask);
- gpio_write(cx);
- mutex_unlock(&cx->gpio_lock);
- }
- return 0;
+ CX18_DEBUG_INFO("Resetting XCeive tuner\n");
+ return v4l2_subdev_call(&cx->sd_resetctrl,
+ core, reset, CX18_GPIO_RESET_XC2028);
}
diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h
index 39ffccc19d8..f9a5ca3566a 100644
--- a/drivers/media/video/cx18/cx18-gpio.h
+++ b/drivers/media/video/cx18/cx18-gpio.h
@@ -22,7 +22,13 @@
*/
void cx18_gpio_init(struct cx18 *cx);
-void cx18_reset_i2c_slaves_gpio(struct cx18 *cx);
+int cx18_gpio_register(struct cx18 *cx, u32 hw);
+
+enum cx18_gpio_reset_type {
+ CX18_GPIO_RESET_I2C = 0,
+ CX18_GPIO_RESET_Z8F0811 = 1,
+ CX18_GPIO_RESET_XC2028 = 2,
+};
+
void cx18_reset_ir_gpio(void *data);
int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value);
-int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg);
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index 83e1c633312..d092643faf4 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -26,7 +26,6 @@
#include "cx18-io.h"
#include "cx18-cards.h"
#include "cx18-gpio.h"
-#include "cx18-av-core.h"
#include "cx18-i2c.h"
#include "cx18-irq.h"
@@ -43,31 +42,37 @@
#define CX18_CS5345_I2C_ADDR 0x4c
/* This array should match the CX18_HW_ defines */
-static const u8 hw_driverids[] = {
- I2C_DRIVERID_TUNER,
- I2C_DRIVERID_TVEEPROM,
- I2C_DRIVERID_CS5345,
- 0, /* CX18_HW_GPIO dummy driver ID */
- 0 /* CX18_HW_CX23418 dummy driver ID */
-};
-
-/* This array should match the CX18_HW_ defines */
static const u8 hw_addrs[] = {
- 0,
- 0,
- CX18_CS5345_I2C_ADDR,
- 0, /* CX18_HW_GPIO dummy driver ID */
- 0, /* CX18_HW_CX23418 dummy driver ID */
+ 0, /* CX18_HW_TUNER */
+ 0, /* CX18_HW_TVEEPROM */
+ CX18_CS5345_I2C_ADDR, /* CX18_HW_CS5345 */
+ 0, /* CX18_HW_DVB */
+ 0, /* CX18_HW_418_AV */
+ 0, /* CX18_HW_GPIO_MUX */
+ 0, /* CX18_HW_GPIO_RESET_CTRL */
};
/* This array should match the CX18_HW_ defines */
/* This might well become a card-specific array */
static const u8 hw_bus[] = {
- 0,
- 0,
- 0,
- 0, /* CX18_HW_GPIO dummy driver ID */
- 0, /* CX18_HW_CX23418 dummy driver ID */
+ 1, /* CX18_HW_TUNER */
+ 0, /* CX18_HW_TVEEPROM */
+ 0, /* CX18_HW_CS5345 */
+ 0, /* CX18_HW_DVB */
+ 0, /* CX18_HW_418_AV */
+ 0, /* CX18_HW_GPIO_MUX */
+ 0, /* CX18_HW_GPIO_RESET_CTRL */
+};
+
+/* This array should match the CX18_HW_ defines */
+static const char * const hw_modules[] = {
+ "tuner", /* CX18_HW_TUNER */
+ NULL, /* CX18_HW_TVEEPROM */
+ "cs5345", /* CX18_HW_CS5345 */
+ NULL, /* CX18_HW_DVB */
+ NULL, /* CX18_HW_418_AV */
+ NULL, /* CX18_HW_GPIO_MUX */
+ NULL, /* CX18_HW_GPIO_RESET_CTRL */
};
/* This array should match the CX18_HW_ defines */
@@ -75,83 +80,67 @@ static const char * const hw_devicenames[] = {
"tuner",
"tveeprom",
"cs5345",
- "gpio",
- "cx23418",
+ "cx23418_DTV",
+ "cx23418_AV",
+ "gpio_mux",
+ "gpio_reset_ctrl",
};
int cx18_i2c_register(struct cx18 *cx, unsigned idx)
{
- struct i2c_board_info info;
- struct i2c_client *c;
- u8 id, bus;
- int i;
-
- CX18_DEBUG_I2C("i2c client register\n");
- if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
+ struct v4l2_subdev *sd;
+ int bus = hw_bus[idx];
+ struct i2c_adapter *adap = &cx->i2c_adap[bus];
+ const char *mod = hw_modules[idx];
+ const char *type = hw_devicenames[idx];
+ u32 hw = 1 << idx;
+
+ if (idx >= ARRAY_SIZE(hw_addrs))
return -1;
- id = hw_driverids[idx];
- bus = hw_bus[idx];
- memset(&info, 0, sizeof(info));
- strlcpy(info.type, hw_devicenames[idx], sizeof(info.type));
- info.addr = hw_addrs[idx];
- for (i = 0; i < I2C_CLIENTS_MAX; i++)
- if (cx->i2c_clients[i] == NULL)
- break;
-
- if (i == I2C_CLIENTS_MAX) {
- CX18_ERR("insufficient room for new I2C client!\n");
- return -ENOMEM;
- }
- if (id != I2C_DRIVERID_TUNER) {
- c = i2c_new_device(&cx->i2c_adap[bus], &info);
- if (c->driver == NULL)
- i2c_unregister_device(c);
- else
- cx->i2c_clients[i] = c;
- return cx->i2c_clients[i] ? 0 : -ENODEV;
+ if (hw == CX18_HW_TUNER) {
+ /* special tuner group handling */
+ sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ cx->card_i2c->radio);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ cx->card_i2c->demod);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
+ cx->card_i2c->tv);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ return sd != NULL ? 0 : -1;
}
- /* special tuner handling */
- c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio);
- if (c && c->driver == NULL)
- i2c_unregister_device(c);
- else if (c)
- cx->i2c_clients[i++] = c;
- c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod);
- if (c && c->driver == NULL)
- i2c_unregister_device(c);
- else if (c)
- cx->i2c_clients[i++] = c;
- c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv);
- if (c && c->driver == NULL)
- i2c_unregister_device(c);
- else if (c)
- cx->i2c_clients[i++] = c;
- return 0;
-}
+ /* Is it not an I2C device or one we do not wish to register? */
+ if (!hw_addrs[idx])
+ return -1;
-static int attach_inform(struct i2c_client *client)
-{
- return 0;
+ /* It's an I2C device other than an analog tuner */
+ sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]);
+ if (sd != NULL)
+ sd->grp_id = hw;
+ return sd != NULL ? 0 : -1;
}
-static int detach_inform(struct i2c_client *client)
+/* Find the first member of the subdev group id in hw */
+struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw)
{
- int i;
- struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter);
+ struct v4l2_subdev *result = NULL;
+ struct v4l2_subdev *sd;
- CX18_DEBUG_I2C("i2c client detach\n");
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- if (cx->i2c_clients[i] == client) {
- cx->i2c_clients[i] = NULL;
+ spin_lock(&cx->v4l2_dev.lock);
+ v4l2_device_for_each_subdev(sd, &cx->v4l2_dev) {
+ if (sd->grp_id == hw) {
+ result = sd;
break;
}
}
- CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n",
- client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed");
-
- return 0;
+ spin_unlock(&cx->v4l2_dev.lock);
+ return result;
}
static void cx18_setscl(void *data, int state)
@@ -204,8 +193,6 @@ static struct i2c_adapter cx18_i2c_adap_template = {
.id = I2C_HW_B_CX2341X,
.algo = NULL, /* set by i2c-algo-bit */
.algo_data = NULL, /* filled from template */
- .client_register = attach_inform,
- .client_unregister = detach_inform,
.owner = THIS_MODULE,
};
@@ -221,152 +208,28 @@ static struct i2c_algo_bit_data cx18_i2c_algo_template = {
.timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */
};
-static struct i2c_client cx18_i2c_client_template = {
- .name = "cx18 internal",
-};
-
-int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg)
-{
- struct i2c_client *client;
- int retval;
- int i;
-
- CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- client = cx->i2c_clients[i];
- if (client == NULL || client->driver == NULL ||
- client->driver->command == NULL)
- continue;
- if (addr == client->addr) {
- retval = client->driver->command(client, cmd, arg);
- return retval;
- }
- }
- if (cmd != VIDIOC_DBG_G_CHIP_IDENT)
- CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n",
- addr, cmd);
- return -ENODEV;
-}
-
-/* Find the i2c device based on the driver ID and return
- its i2c address or -ENODEV if no matching device was found. */
-static int cx18_i2c_id_addr(struct cx18 *cx, u32 id)
-{
- struct i2c_client *client;
- int retval = -ENODEV;
- int i;
-
- for (i = 0; i < I2C_CLIENTS_MAX; i++) {
- client = cx->i2c_clients[i];
- if (client == NULL || client->driver == NULL)
- continue;
- if (id == client->driver->id) {
- retval = client->addr;
- break;
- }
- }
- return retval;
-}
-
-/* Find the i2c device name matching the CX18_HW_ flag */
-static const char *cx18_i2c_hw_name(u32 hw)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
- if (1 << i == hw)
- return hw_devicenames[i];
- return "unknown device";
-}
-
-/* Find the i2c device matching the CX18_HW_ flag and return
- its i2c address or -ENODEV if no matching device was found. */
-int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
- if (1 << i == hw)
- return cx18_i2c_id_addr(cx, hw_driverids[i]);
- return -ENODEV;
-}
-
-/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing.
- If hw == CX18_HW_GPIO then call the gpio handler. */
-int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg)
-{
- int addr;
-
- if (hw == 0)
- return 0;
-
- if (hw == CX18_HW_GPIO)
- return cx18_gpio(cx, cmd, arg);
-
- if (hw == CX18_HW_CX23418)
- return cx18_av_cmd(cx, cmd, arg);
-
- addr = cx18_i2c_hw_addr(cx, hw);
- if (addr < 0) {
- CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n",
- hw, cx18_i2c_hw_name(hw), cmd);
- return addr;
- }
- return cx18_call_i2c_client(cx, addr, cmd, arg);
-}
-
-/* broadcast cmd for all I2C clients and for the gpio subsystem */
-void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg)
-{
- if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) {
- CX18_ERR("adapter is not set\n");
- return;
- }
- cx18_av_cmd(cx, cmd, arg);
- i2c_clients_command(&cx->i2c_adap[0], cmd, arg);
- i2c_clients_command(&cx->i2c_adap[1], cmd, arg);
- if (cx->hw_flags & CX18_HW_GPIO)
- cx18_gpio(cx, cmd, arg);
-}
-
/* init + register i2c algo-bit adapter */
int init_cx18_i2c(struct cx18 *cx)
{
int i;
CX18_DEBUG_I2C("i2c init\n");
- /* Sanity checks for the I2C hardware arrays. They must be the
- * same size and GPIO/CX23418 must be the last entries.
- */
- if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) ||
- ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
- CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) ||
- CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) ||
- hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
- CX18_ERR("Mismatched I2C hardware arrays\n");
- return -ENODEV;
- }
-
for (i = 0; i < 2; i++) {
- memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
- sizeof(struct i2c_adapter));
+ /* Setup algorithm for adapter */
memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template,
sizeof(struct i2c_algo_bit_data));
cx->i2c_algo_cb_data[i].cx = cx;
cx->i2c_algo_cb_data[i].bus_index = i;
cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i];
- cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
+ /* Setup adapter */
+ memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template,
+ sizeof(struct i2c_adapter));
+ cx->i2c_adap[i].algo_data = &cx->i2c_algo[i];
sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name),
- " #%d-%d", cx->num, i);
- i2c_set_adapdata(&cx->i2c_adap[i], cx);
-
- memcpy(&cx->i2c_client[i], &cx18_i2c_client_template,
- sizeof(struct i2c_client));
- sprintf(cx->i2c_client[i].name +
- strlen(cx->i2c_client[i].name), "%d", i);
- cx->i2c_client[i].adapter = &cx->i2c_adap[i];
- cx->i2c_adap[i].dev.parent = &cx->dev->dev;
+ " #%d-%d", cx->instance, i);
+ i2c_set_adapdata(&cx->i2c_adap[i], &cx->v4l2_dev);
+ cx->i2c_adap[i].dev.parent = &cx->pci_dev->dev;
}
if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) {
@@ -402,7 +265,8 @@ int init_cx18_i2c(struct cx18 *cx)
cx18_setscl(&cx->i2c_algo_cb_data[1], 1);
cx18_setsda(&cx->i2c_algo_cb_data[1], 1);
- cx18_reset_i2c_slaves_gpio(cx);
+ cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
+ core, reset, (u32) CX18_GPIO_RESET_I2C);
return i2c_bit_add_bus(&cx->i2c_adap[0]) ||
i2c_bit_add_bus(&cx->i2c_adap[1]);
diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h
index 4869739013b..bdfd1921e30 100644
--- a/drivers/media/video/cx18/cx18-i2c.h
+++ b/drivers/media/video/cx18/cx18-i2c.h
@@ -21,11 +21,8 @@
* 02111-1307 USA
*/
-int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw);
-int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg);
-int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg);
-void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg);
int cx18_i2c_register(struct cx18 *cx, unsigned idx);
+struct v4l2_subdev *cx18_find_hw(struct cx18 *cx, u32 hw);
/* init + register i2c algo-bit adapter */
int init_cx18_i2c(struct cx18 *cx);
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 7086aaba77d..e4c9e3d8bac 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -58,12 +58,21 @@ u16 cx18_service2vbi(int type)
}
}
+/* Check if VBI services are allowed on the (field, line) for the video std */
static int valid_service_line(int field, int line, int is_pal)
{
- return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
+ return (is_pal && line >= 6 &&
+ ((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
(!is_pal && line >= 10 && line < 22);
}
+/*
+ * For a (field, line, std) and inbound potential set of services for that line,
+ * return the first valid service of those passed in the incoming set for that
+ * line in priority order:
+ * CC, VPS, or WSS over TELETEXT for well known lines
+ * TELETEXT, before VPS, before CC, before WSS, for other lines
+ */
static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
{
u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
@@ -90,6 +99,10 @@ static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
return 0;
}
+/*
+ * Expand the service_set of *fmt into valid service_lines for the std,
+ * and clear the passed in fmt->service_set
+ */
void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
{
u16 set = fmt->service_set;
@@ -102,7 +115,25 @@ void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
}
}
+/*
+ * Sanitize the service_lines in *fmt per the video std, and return 1
+ * if any service_line is left as valid after santization
+ */
+static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
+{
+ int f, l;
+ u16 set = 0;
+
+ for (f = 0; f < 2; f++) {
+ for (l = 0; l < 24; l++) {
+ fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
+ set |= fmt->service_lines[f][l];
+ }
+ }
+ return set != 0;
+}
+/* Compute the service_set from the assumed valid service_lines of *fmt */
u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
{
int f, l;
@@ -129,10 +160,8 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
pixfmt->priv = 0;
if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- pixfmt->height * pixfmt->width +
- pixfmt->height * (pixfmt->width / 2);
+ /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+ pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
pixfmt->bytesperline = 720;
} else {
pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -149,8 +178,8 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
vbifmt->sampling_rate = 27000000;
- vbifmt->offset = 248;
- vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4;
+ vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
+ vbifmt->samples_per_line = vbi_active_samples - 4;
vbifmt->sample_format = V4L2_PIX_FMT_GREY;
vbifmt->start[0] = cx->vbi.start[0];
vbifmt->start[1] = cx->vbi.start[1];
@@ -164,7 +193,30 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ /* sane, V4L2 spec compliant, defaults */
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
+ vbifmt->service_set = 0;
+
+ /*
+ * Fetch the configured service_lines and total service_set from the
+ * digitizer/slicer. Note, cx18_av_vbi() wipes the passed in
+ * fmt->fmt.sliced under valid calling conditions
+ */
+ if (v4l2_subdev_call(cx->sd_av, video, g_fmt, fmt))
+ return -EINVAL;
+
+ /* Ensure V4L2 spec compliant output */
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ vbifmt->service_set = cx18_get_service_set(vbifmt);
+ return 0;
}
static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
@@ -174,11 +226,18 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
struct cx18 *cx = id->cx;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
+ int min_h = 2;
w = min(w, 720);
- w = max(w, 1);
+ w = max(w, 2);
+ if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
+ /* YUV height must be a multiple of 32 */
+ h &= ~0x1f;
+ min_h = 32;
+ }
h = min(h, cx->is_50hz ? 576 : 480);
- h = max(h, 2);
+ h = max(h, min_h);
+
cx18_g_fmt_vid_cap(file, fh, fmt);
fmt->fmt.pix.width = w;
fmt->fmt.pix.height = h;
@@ -194,7 +253,20 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
+ vbifmt->reserved[0] = 0;
+ vbifmt->reserved[1] = 0;
+
+ /* If given a service set, expand it validly & clear passed in set */
+ if (vbifmt->service_set)
+ cx18_expand_service_set(vbifmt, cx->is_50hz);
+ /* Sanitize the service_lines, and compute the new set if any valid */
+ if (check_service_set(vbifmt, cx->is_50hz))
+ vbifmt->service_set = cx18_get_service_set(vbifmt);
+ return 0;
}
static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
@@ -223,7 +295,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
cx->params.width = w;
cx->params.height = h;
- cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+ v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
return cx18_g_fmt_vid_cap(file, fh, fmt);
}
@@ -238,54 +310,131 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
if (ret)
return ret;
+ /*
+ * Changing the Encoder's Raw VBI parameters won't have any effect
+ * if any analog capture is ongoing
+ */
if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
return -EBUSY;
+ /*
+ * Set the digitizer registers for raw active VBI.
+ * Note cx18_av_vbi_wipes out alot of the passed in fmt under valid
+ * calling conditions
+ */
+ ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
+ if (ret)
+ return ret;
+
+ /* Store our new v4l2 (non-)sliced VBI state */
cx->vbi.sliced_in->service_set = 0;
cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
- cx18_av_cmd(cx, VIDIOC_S_FMT, fmt);
+
return cx18_g_fmt_vbi_cap(file, fh, fmt);
}
static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_format *fmt)
{
- return -EINVAL;
+ struct cx18_open_id *id = fh;
+ struct cx18 *cx = id->cx;
+ int ret;
+ struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
+
+ ret = v4l2_prio_check(&cx->prio, &id->prio);
+ if (ret)
+ return ret;
+
+ cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
+
+ /*
+ * Changing the Encoder's Raw VBI parameters won't have any effect
+ * if any analog capture is ongoing
+ */
+ if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
+ return -EBUSY;
+
+ /*
+ * Set the service_lines requested in the digitizer/slicer registers.
+ * Note, cx18_av_vbi() wipes some "impossible" service lines in the
+ * passed in fmt->fmt.sliced under valid calling conditions
+ */
+ ret = v4l2_subdev_call(cx->sd_av, video, s_fmt, fmt);
+ if (ret)
+ return ret;
+ /* Store our current v4l2 sliced VBI settings */
+ cx->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
+ return 0;
}
static int cx18_g_chip_ident(struct file *file, void *fh,
struct v4l2_dbg_chip_ident *chip)
{
struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ int err = 0;
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- if (v4l2_chip_match_host(&chip->match)) {
- chip->ident = V4L2_IDENT_CX23418;
- return 0;
+ switch (chip->match.type) {
+ case V4L2_CHIP_MATCH_HOST:
+ switch (chip->match.addr) {
+ case 0:
+ chip->ident = V4L2_IDENT_CX23418;
+ chip->revision = cx18_read_reg(cx, 0xC72028);
+ break;
+ case 1:
+ /*
+ * The A/V decoder is always present, but in the rare
+ * case that the card doesn't have analog, we don't
+ * use it. We find it w/o using the cx->sd_av pointer
+ */
+ cx18_call_hw(cx, CX18_HW_418_AV,
+ core, g_chip_ident, chip);
+ break;
+ default:
+ /*
+ * Could return ident = V4L2_IDENT_UNKNOWN if we had
+ * other host chips at higher addresses, but we don't
+ */
+ err = -EINVAL; /* per V4L2 spec */
+ break;
+ }
+ break;
+ case V4L2_CHIP_MATCH_I2C_DRIVER:
+ /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */
+ cx18_call_all(cx, core, g_chip_ident, chip);
+ break;
+ case V4L2_CHIP_MATCH_I2C_ADDR:
+ /*
+ * We could return V4L2_IDENT_UNKNOWN, but we don't do the work
+ * to look if a chip is at the address with no driver. That's a
+ * dangerous thing to do with EEPROMs anyway.
+ */
+ cx18_call_all(cx, core, g_chip_ident, chip);
+ break;
+ default:
+ err = -EINVAL;
+ break;
}
- cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip);
- return 0;
+ return err;
}
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
{
struct v4l2_dbg_register *regs = arg;
- unsigned long flags;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
return -EINVAL;
- spin_lock_irqsave(&cx18_cards_lock, flags);
regs->size = 4;
- if (cmd == VIDIOC_DBG_G_REGISTER)
- regs->val = cx18_read_enc(cx, regs->reg);
- else
+ if (cmd == VIDIOC_DBG_S_REGISTER)
cx18_write_enc(cx, regs->val, regs->reg);
- spin_unlock_irqrestore(&cx18_cards_lock, flags);
+ else
+ regs->val = cx18_read_enc(cx, regs->reg);
return 0;
}
@@ -296,7 +445,8 @@ static int cx18_g_register(struct file *file, void *fh,
if (v4l2_chip_match_host(&reg->match))
return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
- cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg);
+ /* FIXME - errors shouldn't be ignored */
+ cx18_call_all(cx, core, g_register, reg);
return 0;
}
@@ -307,7 +457,8 @@ static int cx18_s_register(struct file *file, void *fh,
if (v4l2_chip_match_host(&reg->match))
return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
- cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg);
+ /* FIXME - errors shouldn't be ignored */
+ cx18_call_all(cx, core, s_register, reg);
return 0;
}
#endif
@@ -335,7 +486,8 @@ static int cx18_querycap(struct file *file, void *fh,
strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev));
+ snprintf(vcap->bus_info, sizeof(vcap->bus_info),
+ "PCI:%s", pci_name(cx->pci_dev));
vcap->version = CX18_DRIVER_VERSION; /* version */
vcap->capabilities = cx->v4l2_cap; /* capabilities */
return 0;
@@ -403,7 +555,8 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- return cx18_av_cmd(cx, VIDIOC_S_CROP, crop);
+ CX18_DEBUG_WARN("VIDIOC_S_CROP not implemented\n");
+ return -EINVAL;
}
static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
@@ -412,7 +565,8 @@ static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- return cx18_av_cmd(cx, VIDIOC_G_CROP, crop);
+ CX18_DEBUG_WARN("VIDIOC_G_CROP not implemented\n");
+ return -EINVAL;
}
static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
@@ -483,7 +637,7 @@ static int cx18_g_frequency(struct file *file, void *fh,
if (vf->tuner != 0)
return -EINVAL;
- cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf);
+ cx18_call_all(cx, tuner, g_frequency, vf);
return 0;
}
@@ -502,7 +656,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
cx18_mute(cx);
CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
- cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf);
+ cx18_call_all(cx, tuner, s_frequency, vf);
cx18_unmute(cx);
return 0;
}
@@ -547,12 +701,11 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
cx->vbi.count = cx->is_50hz ? 18 : 12;
cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
- cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284;
CX18_DEBUG_INFO("Switching standard to %llx.\n",
(unsigned long long) cx->std);
/* Tuner */
- cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std);
+ cx18_call_all(cx, tuner, s_std, cx->std);
return 0;
}
@@ -569,9 +722,7 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
if (vt->index != 0)
return -EINVAL;
- /* Setting tuner can only set audio mode */
- cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt);
-
+ cx18_call_all(cx, tuner, s_tuner, vt);
return 0;
}
@@ -582,7 +733,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
if (vt->index != 0)
return -EINVAL;
- cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt);
+ cx18_call_all(cx, tuner, g_tuner, vt);
if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) {
strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
@@ -598,7 +749,30 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
struct v4l2_sliced_vbi_cap *cap)
{
- return -EINVAL;
+ struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
+ int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
+ int f, l;
+
+ if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+
+ cap->service_set = 0;
+ for (f = 0; f < 2; f++) {
+ for (l = 0; l < 24; l++) {
+ if (valid_service_line(f, l, cx->is_50hz)) {
+ /*
+ * We can find all v4l2 supported vbi services
+ * for the standard, on a valid line for the std
+ */
+ cap->service_lines[f][l] = set;
+ cap->service_set |= set;
+ } else
+ cap->service_lines[f][l] = 0;
+ }
+ }
+ for (f = 0; f < 3; f++)
+ cap->reserved[f] = 0;
+ return 0;
}
static int cx18_g_enc_index(struct file *file, void *fh,
@@ -708,13 +882,15 @@ static int cx18_log_status(struct file *file, void *fh)
struct v4l2_audio audin;
int i;
- CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num);
+ CX18_INFO("================= START STATUS CARD #%d "
+ "=================\n", cx->instance);
+ CX18_INFO("Version: %s Card: %s\n", CX18_VERSION, cx->card_name);
if (cx->hw_flags & CX18_HW_TVEEPROM) {
struct tveeprom tv;
cx18_read_eeprom(cx, &tv);
}
- cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL);
+ cx18_call_all(cx, core, log_status);
cx18_get_input(cx, cx->active_input, &vidin);
cx18_get_audio_input(cx, cx->audio_input, &audin);
CX18_INFO("Video Input: %s\n", vidin.name);
@@ -725,12 +901,12 @@ static int cx18_log_status(struct file *file, void *fh)
mutex_unlock(&cx->gpio_lock);
CX18_INFO("Tuner: %s\n",
test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
- cx2341x_log_status(&cx->params, cx->name);
+ cx2341x_log_status(&cx->params, cx->v4l2_dev.name);
CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev == NULL || s->buffers == 0)
+ if (s->video_dev == NULL || s->buffers == 0)
continue;
CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
s->name, s->s_flags,
@@ -740,7 +916,8 @@ static int cx18_log_status(struct file *file, void *fh)
CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
(long long)cx->mpg_data_received,
(long long)cx->vbi_data_inserted);
- CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num);
+ CX18_INFO("================== END STATUS CARD #%d "
+ "==================\n", cx->instance);
return 0;
}
@@ -754,7 +931,8 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n",
route->input, route->output);
- cx18_audio_set_route(cx, route);
+ cx18_call_hw(cx, cx->card->hw_audio_ctrl, audio, s_routing,
+ route);
break;
}
@@ -762,7 +940,8 @@ static long cx18_default(struct file *file, void *fh, int cmd, void *arg)
u32 val = *(u32 *)arg;
if ((val == 0) || (val & 0x01))
- cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]);
+ cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
+ (u32) CX18_GPIO_RESET_Z8F0811);
break;
}
@@ -782,6 +961,8 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
mutex_lock(&cx->serialize_lock);
+ /* FIXME - consolidate v4l2_prio_check()'s here */
+
if (cx18_debug & CX18_DBGFLG_IOCTL)
vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
res = video_ioctl2(filp, cmd, arg);
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index de5e723fdf4..2226e5791e9 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -83,6 +83,8 @@ static const struct cx18_api_info api_info[] = {
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0),
API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST),
API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW),
+ API_ENTRY(APU, CX18_APU_START, 0),
+ API_ENTRY(APU, CX18_APU_STOP, 0),
API_ENTRY(APU, CX18_APU_RESETAI, 0),
API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0),
API_ENTRY(0, 0, 0),
@@ -98,21 +100,30 @@ static const struct cx18_api_info *find_api_info(u32 cmd)
return NULL;
}
-static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+/* Call with buf of n*11+1 bytes */
+static char *u32arr2hex(u32 data[], int n, char *buf)
{
- char argstr[MAX_MB_ARGUMENTS*11+1];
char *p;
int i;
+ for (i = 0, p = buf; i < n; i++, p += 11) {
+ /* kernel snprintf() appends '\0' always */
+ snprintf(p, 12, " %#010x", data[i]);
+ }
+ *p = '\0';
+ return buf;
+}
+
+static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name)
+{
+ char argstr[MAX_MB_ARGUMENTS*11+1];
+
if (!(cx18_debug & CX18_DBGFLG_API))
return;
- for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) {
- /* kernel snprintf() appends '\0' always */
- snprintf(p, 12, " %#010x", mb->args[i]);
- }
CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s"
- "\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr);
+ "\n", name, mb->request, mb->ack, mb->cmd, mb->error,
+ u32arr2hex(mb->args, MAX_MB_ARGUMENTS, argstr));
}
@@ -439,7 +450,8 @@ void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu)
"incoming %s to EPU mailbox (sequence no. %u)"
"\n",
rpu_str[rpu], rpu_str[rpu], order_mb->request);
- dump_mb(cx, order_mb, "incoming");
+ if (cx18_debug & CX18_DBGFLG_WARN)
+ dump_mb(cx, order_mb, "incoming");
order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT;
}
@@ -468,16 +480,24 @@ static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[])
struct mutex *mb_lock;
long int timeout, ret;
int i;
+ char argstr[MAX_MB_ARGUMENTS*11+1];
if (info == NULL) {
CX18_WARN("unknown cmd %x\n", cmd);
return -EINVAL;
}
- if (cmd == CX18_CPU_DE_SET_MDL)
- CX18_DEBUG_HI_API("%s\n", info->name);
- else
- CX18_DEBUG_API("%s\n", info->name);
+ if (cx18_debug & CX18_DBGFLG_API) { /* only call u32arr2hex if needed */
+ if (cmd == CX18_CPU_DE_SET_MDL) {
+ if (cx18_debug & CX18_DBGFLG_HIGHVOL)
+ CX18_DEBUG_HI_API("%s\tcmd %#010x args%s\n",
+ info->name, cmd,
+ u32arr2hex(data, args, argstr));
+ } else
+ CX18_DEBUG_API("%s\tcmd %#010x args%s\n",
+ info->name, cmd,
+ u32arr2hex(data, args, argstr));
+ }
switch (info->rpu) {
case APU:
diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c
index 8d9441e88c4..3046b8e7434 100644
--- a/drivers/media/video/cx18/cx18-queue.c
+++ b/drivers/media/video/cx18/cx18-queue.c
@@ -204,7 +204,7 @@ int cx18_stream_alloc(struct cx18_stream *s)
}
buf->id = cx->buffer_id++;
INIT_LIST_HEAD(&buf->list);
- buf->dma_handle = pci_map_single(s->cx->dev,
+ buf->dma_handle = pci_map_single(s->cx->pci_dev,
buf->buf, s->buf_size, s->dma);
cx18_buf_sync_for_cpu(s, buf);
cx18_enqueue(s, buf, &s->q_free);
@@ -227,7 +227,7 @@ void cx18_stream_free(struct cx18_stream *s)
/* empty q_free */
while ((buf = cx18_dequeue(s, &s->q_free))) {
- pci_unmap_single(s->cx->dev, buf->dma_handle,
+ pci_unmap_single(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
kfree(buf->buf);
kfree(buf);
diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h
index 456cec3bc28..4de06269d88 100644
--- a/drivers/media/video/cx18/cx18-queue.h
+++ b/drivers/media/video/cx18/cx18-queue.h
@@ -29,14 +29,14 @@
static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s,
struct cx18_buffer *buf)
{
- pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle,
+ pci_dma_sync_single_for_cpu(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
}
static inline void cx18_buf_sync_for_device(struct cx18_stream *s,
struct cx18_buffer *buf)
{
- pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle,
+ pci_dma_sync_single_for_device(s->cx->pci_dev, buf->dma_handle,
s->buf_size, s->dma);
}
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 89c1ec94f33..0932b76b237 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -32,7 +32,6 @@
#include "cx18-streams.h"
#include "cx18-cards.h"
#include "cx18-scb.h"
-#include "cx18-av-core.h"
#include "cx18-dvb.h"
#define CX18_DSP0_INTERRUPT_MASK 0xd0004C
@@ -101,11 +100,11 @@ static struct {
static void cx18_stream_init(struct cx18 *cx, int type)
{
struct cx18_stream *s = &cx->streams[type];
- struct video_device *dev = s->v4l2dev;
+ struct video_device *video_dev = s->video_dev;
- /* we need to keep v4l2dev, so restore it afterwards */
+ /* we need to keep video_dev, so restore it afterwards */
memset(s, 0, sizeof(*s));
- s->v4l2dev = dev;
+ s->video_dev = video_dev;
/* initialize cx18_stream fields */
s->cx = cx;
@@ -130,12 +129,12 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
struct cx18_stream *s = &cx->streams[type];
u32 cap = cx->v4l2_cap;
int num_offset = cx18_stream_info[type].num_offset;
- int num = cx->num + cx18_first_minor + num_offset;
+ int num = cx->instance + cx18_first_minor + num_offset;
- /* These four fields are always initialized. If v4l2dev == NULL, then
+ /* These four fields are always initialized. If video_dev == NULL, then
this stream is not in use. In that case no other fields but these
four can be used. */
- s->v4l2dev = NULL;
+ s->video_dev = NULL;
s->cx = cx;
s->type = type;
s->name = cx18_stream_info[type].name;
@@ -163,22 +162,22 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
return 0;
/* allocate and initialize the v4l2 video device structure */
- s->v4l2dev = video_device_alloc();
- if (s->v4l2dev == NULL) {
+ s->video_dev = video_device_alloc();
+ if (s->video_dev == NULL) {
CX18_ERR("Couldn't allocate v4l2 video_device for %s\n",
s->name);
return -ENOMEM;
}
- snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d",
- cx->num);
+ snprintf(s->video_dev->name, sizeof(s->video_dev->name), "%s %s",
+ cx->v4l2_dev.name, s->name);
- s->v4l2dev->num = num;
- s->v4l2dev->parent = &cx->dev->dev;
- s->v4l2dev->fops = &cx18_v4l2_enc_fops;
- s->v4l2dev->release = video_device_release;
- s->v4l2dev->tvnorms = V4L2_STD_ALL;
- cx18_set_funcs(s->v4l2dev);
+ s->video_dev->num = num;
+ s->video_dev->v4l2_dev = &cx->v4l2_dev;
+ s->video_dev->fops = &cx18_v4l2_enc_fops;
+ s->video_dev->release = video_device_release;
+ s->video_dev->tvnorms = V4L2_STD_ALL;
+ cx18_set_funcs(s->video_dev);
return 0;
}
@@ -227,28 +226,30 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
}
}
- if (s->v4l2dev == NULL)
+ if (s->video_dev == NULL)
return 0;
- num = s->v4l2dev->num;
+ num = s->video_dev->num;
/* card number + user defined offset + device offset */
if (type != CX18_ENC_STREAM_TYPE_MPG) {
struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
- if (s_mpg->v4l2dev)
- num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset;
+ if (s_mpg->video_dev)
+ num = s_mpg->video_dev->num
+ + cx18_stream_info[type].num_offset;
}
+ video_set_drvdata(s->video_dev, s);
/* Register device. First try the desired minor, then any free one. */
- ret = video_register_device(s->v4l2dev, vfl_type, num);
+ ret = video_register_device(s->video_dev, vfl_type, num);
if (ret < 0) {
CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
s->name, num);
- video_device_release(s->v4l2dev);
- s->v4l2dev = NULL;
+ video_device_release(s->video_dev);
+ s->video_dev = NULL;
return ret;
}
- num = s->v4l2dev->num;
+ num = s->video_dev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
@@ -312,9 +313,9 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
cx->streams[type].dvb.enabled = false;
}
- vdev = cx->streams[type].v4l2dev;
+ vdev = cx->streams[type].video_dev;
- cx->streams[type].v4l2dev = NULL;
+ cx->streams[type].video_dev = NULL;
if (vdev == NULL)
continue;
@@ -346,46 +347,88 @@ static void cx18_vbi_setup(struct cx18_stream *s)
}
/* setup VBI registers */
- cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
-
- /* determine number of lines and total number of VBI bytes.
- A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720
- A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal
- header, 42 data bytes + checksum (to be confirmed) */
+ v4l2_subdev_call(cx->sd_av, video, s_fmt, &cx->vbi.in);
+
+ /*
+ * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
+ * VBI when the first analog capture channel starts, as once it starts
+ * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
+ * (i.e. for the VBI capture channels). We also send it for each
+ * analog capture channel anyway just to make sure we get the proper
+ * behavior
+ */
if (raw) {
lines = cx->vbi.count * 2;
} else {
- lines = cx->is_60hz ? 24 : 38;
- if (cx->is_60hz)
- lines += 2;
+ /*
+ * For 525/60 systems, according to the VIP 2 & BT.656 std:
+ * The EAV RP code's Field bit toggles on line 4, a few lines
+ * after the Vertcal Blank bit has already toggled.
+ * Tell the encoder to capture 21-4+1=18 lines per field,
+ * since we want lines 10 through 21.
+ *
+ * FIXME - revisit for 625/50 systems
+ */
+ lines = cx->is_60hz ? (21 - 4 + 1) * 2 : 38;
}
- cx->vbi.enc_size = lines *
- (raw ? cx->vbi.raw_size : cx->vbi.sliced_size);
-
data[0] = s->handle;
/* Lines per field */
data[1] = (lines / 2) | ((lines / 2) << 16);
/* bytes per line */
- data[2] = (raw ? cx->vbi.raw_decoder_line_size
- : cx->vbi.sliced_decoder_line_size);
+ data[2] = (raw ? vbi_active_samples
+ : (cx->is_60hz ? vbi_hblank_samples_60Hz
+ : vbi_hblank_samples_50Hz));
/* Every X number of frames a VBI interrupt arrives
(frames as in 25 or 30 fps) */
data[3] = 1;
- /* Setup VBI for the cx25840 digitizer */
+ /*
+ * Set the SAV/EAV RP codes to look for as start/stop points
+ * when in VIP-1.1 mode
+ */
if (raw) {
+ /*
+ * Start codes for beginning of "active" line in vertical blank
+ * 0x20 ( VerticalBlank )
+ * 0x60 ( EvenField VerticalBlank )
+ */
data[4] = 0x20602060;
+ /*
+ * End codes for end of "active" raw lines and regular lines
+ * 0x30 ( VerticalBlank HorizontalBlank)
+ * 0x70 ( EvenField VerticalBlank HorizontalBlank)
+ * 0x90 (Task HorizontalBlank)
+ * 0xd0 (Task EvenField HorizontalBlank)
+ */
data[5] = 0x307090d0;
} else {
+ /*
+ * End codes for active video, we want data in the hblank region
+ * 0xb0 (Task 0 VerticalBlank HorizontalBlank)
+ * 0xf0 (Task EvenField VerticalBlank HorizontalBlank)
+ *
+ * Since the V bit is only allowed to toggle in the EAV RP code,
+ * just before the first active region line, these two
+ * are problematic:
+ * 0x90 (Task HorizontalBlank)
+ * 0xd0 (Task EvenField HorizontalBlank)
+ *
+ * We have set the digitzer such that we don't have to worry
+ * about these problem codes.
+ */
data[4] = 0xB0F0B0F0;
+ /*
+ * Start codes for beginning of active line in vertical blank
+ * 0xa0 (Task VerticalBlank )
+ * 0xe0 (Task EvenField VerticalBlank )
+ */
data[5] = 0xA0E0A0E0;
}
CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
data[0], data[1], data[2], data[3], data[4], data[5]);
- if (s->type == CX18_ENC_STREAM_TYPE_VBI)
- cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
+ cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
}
struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
@@ -434,10 +477,10 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
u32 data[MAX_MB_ARGUMENTS];
struct cx18 *cx = s->cx;
struct cx18_buffer *buf;
- int ts = 0;
int captype = 0;
+ struct cx18_api_func_private priv;
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
return -EINVAL;
CX18_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -453,7 +496,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
case CX18_ENC_STREAM_TYPE_TS:
captype = CAPTURE_CHANNEL_TYPE_TS;
- ts = 1;
break;
case CX18_ENC_STREAM_TYPE_YUV:
captype = CAPTURE_CHANNEL_TYPE_YUV;
@@ -462,8 +504,16 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
captype = CAPTURE_CHANNEL_TYPE_PCM;
break;
case CX18_ENC_STREAM_TYPE_VBI:
+#ifdef CX18_ENCODER_PARSES_SLICED
captype = cx18_raw_vbi(cx) ?
CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
+#else
+ /*
+ * Currently we set things up so that Sliced VBI from the
+ * digitizer is handled as Raw VBI by the encoder
+ */
+ captype = CAPTURE_CHANNEL_TYPE_VBI;
+#endif
cx->vbi.frame = 0;
cx->vbi.inserted_frame = 0;
memset(cx->vbi.sliced_mpeg_size,
@@ -473,10 +523,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
return -EINVAL;
}
- /* mute/unmute video */
- cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
- s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
-
/* Clear Streamoff flags in case left from last capture */
clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
@@ -484,31 +530,63 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
s->handle = data[0];
cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
- if (atomic_read(&cx->ana_capturing) == 0 && !ts) {
- struct cx18_api_func_private priv;
-
- /* Stuff from Windows, we don't know what it is */
+ /*
+ * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
+ * set up all the parameters, as it is not obvious which parameters the
+ * firmware shares across capture channel types and which it does not.
+ *
+ * Some of the cx18_vapi() calls below apply to only certain capture
+ * channel types. We're hoping there's no harm in calling most of them
+ * anyway, as long as the values are all consistent. Setting some
+ * shared parameters will have no effect once an analog capture channel
+ * has started streaming.
+ */
+ if (captype != CAPTURE_CHANNEL_TYPE_TS) {
cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
- cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
+ /*
+ * Audio related reset according to
+ * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+ */
+ if (atomic_read(&cx->ana_capturing) == 0)
+ cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
+ s->handle, 12);
+
+ /*
+ * Number of lines for Field 1 & Field 2 according to
+ * Documentation/video4linux/cx2341x/fw-encoder-api.txt
+ * Field 1 is 312 for 625 line systems in BT.656
+ * Field 2 is 313 for 625 line systems in BT.656
+ */
cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
- s->handle, cx->digitizer, cx->digitizer);
+ s->handle, 312, 313);
- /* Setup VBI */
if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
cx18_vbi_setup(s);
- /* assign program index info.
- Mask 7: select I/P/B, Num_req: 400 max */
+ /*
+ * assign program index info.
+ * Mask 7: select I/P/B, Num_req: 400 max
+ * FIXME - currently we have this hardcoded as disabled
+ */
cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
- /* Setup API for Stream */
+ /* Call out to the common CX2341x API setup for user controls */
priv.cx = cx;
priv.s = s;
cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
+
+ /*
+ * When starting a capture and we're set for radio,
+ * ensure the video is muted, despite the user control.
+ */
+ if (!cx->params.video_mute &&
+ test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
+ cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
+ (cx->params.video_mute_yuv << 8) | 1);
}
if (atomic_read(&cx->tot_capturing) == 0) {
@@ -552,7 +630,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
}
/* you're live! sit back and await interrupts :) */
- if (!ts)
+ if (captype != CAPTURE_CHANNEL_TYPE_TS)
atomic_inc(&cx->ana_capturing);
atomic_inc(&cx->tot_capturing);
return 0;
@@ -565,7 +643,7 @@ void cx18_stop_all_captures(struct cx18 *cx)
for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
continue;
if (test_bit(CX18_F_S_STREAMING, &s->s_flags))
cx18_stop_v4l2_encode_stream(s, 0);
@@ -577,7 +655,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
struct cx18 *cx = s->cx;
unsigned long then;
- if (s->v4l2dev == NULL && s->dvb.enabled == 0)
+ if (s->video_dev == NULL && s->dvb.enabled == 0)
return -EINVAL;
/* This function assumes that you are allowed to stop the capture
@@ -629,7 +707,7 @@ u32 cx18_find_handle(struct cx18 *cx)
for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i];
- if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE))
+ if (s->video_dev && (s->handle != CX18_INVALID_TASK_HANDLE))
return s->handle;
}
return CX18_INVALID_TASK_HANDLE;
@@ -647,7 +725,7 @@ struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle)
s = &cx->streams[i];
if (s->handle != handle)
continue;
- if (s->v4l2dev || s->dvb.enabled)
+ if (s->video_dev || s->dvb.enabled)
return s;
}
return NULL;
diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c
index fb595bd548e..c2aef4add31 100644
--- a/drivers/media/video/cx18/cx18-vbi.c
+++ b/drivers/media/video/cx18/cx18-vbi.c
@@ -25,7 +25,16 @@
#include "cx18-vbi.h"
#include "cx18-ioctl.h"
#include "cx18-queue.h"
-#include "cx18-av-core.h"
+
+/*
+ * Raster Reference/Protection (RP) bytes, used in Start/End Active
+ * Video codes emitted from the digitzer in VIP 1.x mode, that flag the start
+ * of VBI sample or VBI ancilliary data regions in the digitial ratser line.
+ *
+ * Task FieldEven VerticalBlank HorizontalBlank 0 0 0 0
+ */
+static const u8 raw_vbi_sav_rp[2] = { 0x20, 0x60 }; /* __V_, _FV_ */
+static const u8 sliced_vbi_eav_rp[2] = { 0xb0, 0xf0 }; /* T_VH, TFVH */
static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
{
@@ -34,10 +43,17 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
u32 linemask[2] = { 0, 0 };
unsigned short size;
static const u8 mpeg_hdr_data[] = {
- 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66,
- 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff,
- 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80,
- 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff
+ /* MPEG-2 Program Pack */
+ 0x00, 0x00, 0x01, 0xba, /* Prog Pack start code */
+ 0x44, 0x00, 0x0c, 0x66, 0x24, 0x01, /* SCR, SCR Ext, markers */
+ 0x01, 0xd1, 0xd3, /* Mux Rate, markers */
+ 0xfa, 0xff, 0xff, /* Res, Suff cnt, Stuff */
+ /* MPEG-2 Private Stream 1 PES Packet */
+ 0x00, 0x00, 0x01, 0xbd, /* Priv Stream 1 start */
+ 0x00, 0x1a, /* length */
+ 0x84, 0x80, 0x07, /* flags, hdr data len */
+ 0x21, 0x00, 0x5d, 0x63, 0xa7, /* PTS, markers */
+ 0xff, 0xff /* stuffing */
};
const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */
int idx = cx->vbi.frame % CX18_VBI_FRAMES;
@@ -71,7 +87,9 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
memcpy(dst + sd + 4, dst + sd + 12, line * 43);
size = 4 + ((43 * line + 3) & ~3);
} else {
- memcpy(dst + sd, "cx0", 4);
+ memcpy(dst + sd, "itv0", 4);
+ cpu_to_le32s(&linemask[0]);
+ cpu_to_le32s(&linemask[1]);
memcpy(dst + sd + 4, &linemask[0], 8);
size = 12 + ((43 * line + 3) & ~3);
}
@@ -86,58 +104,76 @@ static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp)
}
/* Compress raw VBI format, removes leading SAV codes and surplus space
- after the field.
- Returns new compressed size. */
-static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size)
+ after the frame. Returns new compressed size. */
+static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size, u32 hdr_size)
{
- u32 line_size = cx->vbi.raw_decoder_line_size;
- u32 lines = cx->vbi.count;
- u8 sav1 = cx->vbi.raw_decoder_sav_odd_field;
- u8 sav2 = cx->vbi.raw_decoder_sav_even_field;
+ u32 line_size = vbi_active_samples;
+ u32 lines = cx->vbi.count * 2;
u8 *q = buf;
u8 *p;
int i;
+ /* Skip the header */
+ buf += hdr_size;
+
for (i = 0; i < lines; i++) {
p = buf + i * line_size;
/* Look for SAV code */
if (p[0] != 0xff || p[1] || p[2] ||
- (p[3] != sav1 && p[3] != sav2))
+ (p[3] != raw_vbi_sav_rp[0] &&
+ p[3] != raw_vbi_sav_rp[1]))
break;
- memcpy(q, p + 4, line_size - 4);
- q += line_size - 4;
+ if (i == lines - 1) {
+ /* last line is hdr_size bytes short - extrapolate it */
+ memcpy(q, p + 4, line_size - 4 - hdr_size);
+ q += line_size - 4 - hdr_size;
+ p += line_size - hdr_size - 1;
+ memset(q, (int) *p, hdr_size);
+ } else {
+ memcpy(q, p + 4, line_size - 4);
+ q += line_size - 4;
+ }
}
return lines * (line_size - 4);
}
-
-/* Compressed VBI format, all found sliced blocks put next to one another
- Returns new compressed size */
-static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
- u32 size, u8 sav)
+static u32 compress_sliced_buf(struct cx18 *cx, u8 *buf, u32 size,
+ const u32 hdr_size)
{
- u32 line_size = cx->vbi.sliced_decoder_line_size;
struct v4l2_decode_vbi_line vbi;
int i;
+ u32 line = 0;
+ u32 line_size = cx->is_60hz ? vbi_hblank_samples_60Hz
+ : vbi_hblank_samples_50Hz;
/* find the first valid line */
- for (i = 0; i < size; i++, buf++) {
- if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav)
+ for (i = hdr_size, buf += hdr_size; i < size; i++, buf++) {
+ if (buf[0] == 0xff && !buf[1] && !buf[2] &&
+ (buf[3] == sliced_vbi_eav_rp[0] ||
+ buf[3] == sliced_vbi_eav_rp[1]))
break;
}
- size -= i;
+ /*
+ * The last line is short by hdr_size bytes, but for the remaining
+ * checks against size, we pretend that it is not, by counting the
+ * header bytes we knowingly skipped
+ */
+ size -= (i - hdr_size);
if (size < line_size)
return line;
+
for (i = 0; i < size / line_size; i++) {
u8 *p = buf + i * line_size;
- /* Look for SAV code */
- if (p[0] != 0xff || p[1] || p[2] || p[3] != sav)
+ /* Look for EAV code */
+ if (p[0] != 0xff || p[1] || p[2] ||
+ (p[3] != sliced_vbi_eav_rp[0] &&
+ p[3] != sliced_vbi_eav_rp[1]))
continue;
vbi.p = p + 4;
- cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi);
+ v4l2_subdev_call(cx->sd_av, video, decode_vbi_line, &vbi);
if (vbi.type) {
cx->vbi.sliced_data[line].id = vbi.type;
cx->vbi.sliced_data[line].field = vbi.is_second_field;
@@ -150,51 +186,56 @@ static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf,
}
void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
- u64 pts_stamp, int streamtype)
+ int streamtype)
{
+ /*
+ * The CX23418 provides a 12 byte header in its raw VBI buffers to us:
+ * 0x3fffffff [4 bytes of something] [4 byte presentation time stamp]
+ */
+ struct vbi_data_hdr {
+ __be32 magic;
+ __be32 unknown;
+ __be32 pts;
+ } *hdr = (struct vbi_data_hdr *) buf->buf;
+
u8 *p = (u8 *) buf->buf;
u32 size = buf->bytesused;
+ u32 pts;
int lines;
if (streamtype != CX18_ENC_STREAM_TYPE_VBI)
return;
+ /*
+ * The CX23418 sends us data that is 32 bit little-endian swapped,
+ * but we want the raw VBI bytes in the order they were in the raster
+ * line. This has a side effect of making the header big endian
+ */
+ cx18_buf_swap(buf);
+
/* Raw VBI data */
if (cx18_raw_vbi(cx)) {
- u8 type;
-
- cx18_buf_swap(buf);
-
- /* Skip 12 bytes of header that gets stuffed in */
- size -= 12;
- memcpy(p, &buf->buf[12], size);
- type = p[3];
- size = buf->bytesused = compress_raw_buf(cx, p, size);
+ size = buf->bytesused =
+ compress_raw_buf(cx, p, size, sizeof(struct vbi_data_hdr));
- /* second field of the frame? */
- if (type == cx->vbi.raw_decoder_sav_even_field) {
- /* Dirty hack needed for backwards
- compatibility of old VBI software. */
- p += size - 4;
- memcpy(p, &cx->vbi.frame, 4);
- cx->vbi.frame++;
- }
+ /*
+ * Hack needed for compatibility with old VBI software.
+ * Write the frame # at the last 4 bytes of the frame
+ */
+ p += size - 4;
+ memcpy(p, &cx->vbi.frame, 4);
+ cx->vbi.frame++;
return;
}
/* Sliced VBI data with data insertion */
- cx18_buf_swap(buf);
- /* first field */
- lines = compress_sliced_buf(cx, 0, p, size / 2,
- cx->vbi.sliced_decoder_sav_odd_field);
- /* second field */
- /* experimentation shows that the second half does not always
- begin at the exact address. So start a bit earlier
- (hence 32). */
- lines = compress_sliced_buf(cx, lines, p + size / 2 - 32,
- size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field);
+ pts = (be32_to_cpu(hdr->magic) == 0x3fffffff) ? be32_to_cpu(hdr->pts)
+ : 0;
+
+ lines = compress_sliced_buf(cx, p, size, sizeof(struct vbi_data_hdr));
+
/* always return at least one empty line */
if (lines == 0) {
cx->vbi.sliced_data[0].id = 0;
@@ -206,6 +247,6 @@ void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
memcpy(p, &cx->vbi.sliced_data[0], size);
if (cx->vbi.insert_mpeg)
- copy_vbi_data(cx, lines, pts_stamp);
+ copy_vbi_data(cx, lines, pts);
cx->vbi.frame++;
}
diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h
index c56ff7d28f2..e7e1ae427f3 100644
--- a/drivers/media/video/cx18/cx18-vbi.h
+++ b/drivers/media/video/cx18/cx18-vbi.h
@@ -22,5 +22,5 @@
*/
void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf,
- u64 pts_stamp, int streamtype);
+ int streamtype);
int cx18_used_line(struct cx18 *cx, int line, int field);
diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h
index 84c0ff13b60..bd9bd44da79 100644
--- a/drivers/media/video/cx18/cx18-version.h
+++ b/drivers/media/video/cx18/cx18-version.h
@@ -24,8 +24,8 @@
#define CX18_DRIVER_NAME "cx18"
#define CX18_DRIVER_VERSION_MAJOR 1
-#define CX18_DRIVER_VERSION_MINOR 0
-#define CX18_DRIVER_VERSION_PATCHLEVEL 4
+#define CX18_DRIVER_VERSION_MINOR 1
+#define CX18_DRIVER_VERSION_PATCHLEVEL 0
#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL)
#define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \
diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c
index 2e5c4193933..6fdadedf17a 100644
--- a/drivers/media/video/cx18/cx18-video.c
+++ b/drivers/media/video/cx18/cx18-video.c
@@ -21,7 +21,6 @@
#include "cx18-driver.h"
#include "cx18-video.h"
-#include "cx18-av-core.h"
#include "cx18-cards.h"
void cx18_video_set_io(struct cx18 *cx)
@@ -32,7 +31,7 @@ void cx18_video_set_io(struct cx18 *cx)
route.input = cx->card->video_inputs[inp].video_input;
route.output = 0;
- cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_subdev_call(cx->sd_av, video, s_routing, &route);
type = cx->card->video_inputs[inp].video_type;
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 601f3a2ab74..9956abf576c 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -56,6 +56,22 @@
#define APU_CMD_MASK 0x10000000
#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000)
+#define CX18_APU_ENCODING_METHOD_MPEG (0 << 28)
+#define CX18_APU_ENCODING_METHOD_AC3 (1 << 28)
+
+/* Description: Command APU to start audio
+ IN[0] - audio parameters (same as CX18_CPU_SET_AUDIO_PARAMETERS?)
+ IN[1] - caller buffer address, or 0
+ ReturnCode - ??? */
+#define CX18_APU_START (APU_CMD_MASK | 0x01)
+
+/* Description: Command APU to stop audio
+ IN[0] - encoding method to stop
+ ReturnCode - ??? */
+#define CX18_APU_STOP (APU_CMD_MASK | 0x02)
+
+/* Description: Command APU to reset the AI
+ ReturnCode - ??? */
#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05)
/* Description: This command indicates that a Memory Descriptor List has been
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index cbbe47fb87b..8ded5294633 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -1,5 +1,5 @@
/*
- * cx2341x - generic code for cx23415/6 based devices
+ * cx2341x - generic code for cx23415/6/8 based devices
*
* Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
*
@@ -30,7 +30,7 @@
#include <media/cx2341x.h>
#include <media/v4l2-common.h>
-MODULE_DESCRIPTION("cx23415/6 driver");
+MODULE_DESCRIPTION("cx23415/6/8 driver");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL");
@@ -38,6 +38,7 @@ static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+/* Must be sorted from low to high control ID! */
const u32 cx2341x_mpeg_ctrls[] = {
V4L2_CID_MPEG_CLASS,
V4L2_CID_MPEG_STREAM_TYPE,
@@ -50,6 +51,7 @@ const u32 cx2341x_mpeg_ctrls[] = {
V4L2_CID_MPEG_AUDIO_EMPHASIS,
V4L2_CID_MPEG_AUDIO_CRC,
V4L2_CID_MPEG_AUDIO_MUTE,
+ V4L2_CID_MPEG_AUDIO_AC3_BITRATE,
V4L2_CID_MPEG_VIDEO_ENCODING,
V4L2_CID_MPEG_VIDEO_ASPECT,
V4L2_CID_MPEG_VIDEO_B_FRAMES,
@@ -94,6 +96,7 @@ static const struct cx2341x_mpeg_params default_params = {
.audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
.audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
.audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
+ .audio_ac3_bitrate = V4L2_MPEG_AUDIO_AC3_BITRATE_224K,
.audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
.audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
.audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
@@ -148,6 +151,9 @@ static int cx2341x_get_ctrl(const struct cx2341x_mpeg_params *params,
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
ctrl->value = params->audio_l2_bitrate;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ ctrl->value = params->audio_ac3_bitrate;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
ctrl->value = params->audio_mode;
break;
@@ -256,6 +262,12 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
params->audio_sampling_freq = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (busy)
+ return -EBUSY;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3)
+ if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
+ return -ERANGE;
params->audio_encoding = ctrl->value;
break;
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
@@ -263,6 +275,13 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
return -EBUSY;
params->audio_l2_bitrate = ctrl->value;
break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (busy)
+ return -EBUSY;
+ if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
+ return -EINVAL;
+ params->audio_ac3_bitrate = ctrl->value;
+ break;
case V4L2_CID_MPEG_AUDIO_MODE:
params->audio_mode = ctrl->value;
break;
@@ -481,29 +500,106 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
int err;
switch (qctrl->id) {
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
+ V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
+
+ case V4L2_CID_MPEG_STREAM_VBI_FMT:
+ if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE);
+ return cx2341x_ctrl_query_fill(qctrl,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE,
+ V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
+ default_params.stream_vbi_fmt);
+
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
+ V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
+
case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ /*
+ * The state of L2 & AC3 bitrate controls can change
+ * when this control changes, but v4l2_ctrl_query_fill()
+ * already sets V4L2_CTRL_FLAG_UPDATE for
+ * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
+ */
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
+ V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
+ default_params.audio_encoding);
+ }
+
return v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
default_params.audio_encoding);
case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
+ err = v4l2_ctrl_query_fill(qctrl,
V4L2_MPEG_AUDIO_L2_BITRATE_192K,
V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
default_params.audio_l2_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
+ params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return 0;
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
- return -EINVAL;
+ case V4L2_CID_MPEG_AUDIO_MODE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_MODE_STEREO,
+ V4L2_MPEG_AUDIO_MODE_MONO, 1,
+ V4L2_MPEG_AUDIO_MODE_STEREO);
case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
+ V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
if (err == 0 &&
params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
return err;
+ case V4L2_CID_MPEG_AUDIO_EMPHASIS:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE,
+ V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
+ V4L2_MPEG_AUDIO_EMPHASIS_NONE);
+
+ case V4L2_CID_MPEG_AUDIO_CRC:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_CRC_NONE,
+ V4L2_MPEG_AUDIO_CRC_CRC16, 1,
+ V4L2_MPEG_AUDIO_CRC_NONE);
+
+ case V4L2_CID_MPEG_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
+ V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
+ default_params.audio_ac3_bitrate);
+ if (err)
+ return err;
+ if (params->capabilities & CX2341X_CAP_HAS_AC3) {
+ if (params->audio_encoding !=
+ V4L2_MPEG_AUDIO_ENCODING_AC3)
+ qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ } else
+ qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
+ return 0;
+
case V4L2_CID_MPEG_VIDEO_ENCODING:
/* this setting is read-only for the cx2341x since the
V4L2_CID_MPEG_STREAM_TYPE really determines the
@@ -516,32 +612,51 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
return err;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_ASPECT_1x1,
+ V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
+ V4L2_MPEG_VIDEO_ASPECT_4x3);
+
+ case V4L2_CID_MPEG_VIDEO_B_FRAMES:
+ return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
+ return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
+ params->is_50hz ? 12 : 15);
+
+ case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
+
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
if (err == 0 &&
params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
return err;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
+
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
if (err == 0 &&
params->video_bitrate_mode ==
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
return err;
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
- return v4l2_ctrl_query_fill_std(qctrl);
- return cx2341x_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_VBI_FMT_NONE,
- V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
- default_params.stream_vbi_fmt);
+ case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
+ return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(qctrl, 1, 34, 1,
- params->is_50hz ? 12 : 15);
+ case V4L2_CID_MPEG_VIDEO_MUTE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
+
+ case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
+ return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
/* CX23415/6 specific */
case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
@@ -643,7 +758,7 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
default_params.stream_insert_nav_packets);
default:
- return v4l2_ctrl_query_fill_std(qctrl);
+ return -EINVAL;
}
}
@@ -671,6 +786,15 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
NULL
};
+ static const char *mpeg_audio_encoding_l2_ac3[] = {
+ "",
+ "MPEG-1/2 Layer II",
+ "",
+ "",
+ "AC-3",
+ NULL
+ };
+
static const char *cx2341x_video_spatial_filter_mode_menu[] = {
"Manual",
"Auto",
@@ -711,6 +835,9 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
case V4L2_CID_MPEG_STREAM_TYPE:
return (p->capabilities & CX2341X_CAP_HAS_TS) ?
mpeg_stream_type_with_ts : mpeg_stream_type_without_ts;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return (p->capabilities & CX2341X_CAP_HAS_AC3) ?
+ mpeg_audio_encoding_l2_ac3 : v4l2_ctrl_get_menu(id);
case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
return NULL;
@@ -730,16 +857,34 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
}
EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
+/* definitions for audio properties bits 29-28 */
+#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
+#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
+#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
+
static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
{
- params->audio_properties = (params->audio_sampling_freq << 0) |
- ((3 - params->audio_encoding) << 2) |
- ((1 + params->audio_l2_bitrate) << 4) |
+ params->audio_properties =
+ (params->audio_sampling_freq << 0) |
(params->audio_mode << 8) |
(params->audio_mode_extension << 10) |
(((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17)
? 3 : params->audio_emphasis) << 12) |
(params->audio_crc << 14);
+
+ if ((params->capabilities & CX2341X_CAP_HAS_AC3) &&
+ params->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) {
+ params->audio_properties |=
+ /* Not sure if this MPEG Layer II setting is required */
+ ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
+ (params->audio_ac3_bitrate << 4) |
+ (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
+ } else {
+ /* Assuming MPEG Layer II */
+ params->audio_properties |=
+ ((3 - params->audio_encoding) << 2) |
+ ((1 + params->audio_l2_bitrate) << 4);
+ }
}
int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
@@ -1022,7 +1167,10 @@ void cx2341x_log_status(const struct cx2341x_mpeg_params *p, const char *prefix)
prefix,
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
- cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
+ cx2341x_menu_item(p,
+ p->audio_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3
+ ? V4L2_CID_MPEG_AUDIO_AC3_BITRATE
+ : V4L2_CID_MPEG_AUDIO_L2_BITRATE),
cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
p->audio_mute ? " (muted)" : "");
if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 00f1e2e8889..fd3fc3e3198 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -15,12 +15,15 @@ config VIDEO_CX23885
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_XC2028 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_XC5000 if !DVB_FE_CUSTOMIZE
+ select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_STV6110 if !DVB_FE_CUSTOMISE
+ select DVB_STV0900 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
---help---
This is a video4linux driver for Conexant 23885 based
TV cards.
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index 29c23b44c13..ab8ea35c9bf 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -1,4 +1,6 @@
-cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o
+cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
+ cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \
+ netup-init.o cimax2.o netup-eeprom.o
obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
new file mode 100644
index 00000000000..9a6536998d9
--- /dev/null
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -0,0 +1,472 @@
+/*
+ * cimax2.c
+ *
+ * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "cx23885.h"
+#include "dvb_ca_en50221.h"
+/**** Bit definitions for MC417_RWD and MC417_OEN registers ***
+ bits 31-16
++-----------+
+| Reserved |
++-----------+
+ bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
++-------+-------+-------+-------+-------+-------+-------+-------+
+| WR# | RD# | | ACK# | ADHI | ADLO | CS1# | CS0# |
++-------+-------+-------+-------+-------+-------+-------+-------+
+ bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
++-------+-------+-------+-------+-------+-------+-------+-------+
+| DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
++-------+-------+-------+-------+-------+-------+-------+-------+
+***/
+/* MC417 */
+#define NETUP_DATA 0x000000ff
+#define NETUP_WR 0x00008000
+#define NETUP_RD 0x00004000
+#define NETUP_ACK 0x00001000
+#define NETUP_ADHI 0x00000800
+#define NETUP_ADLO 0x00000400
+#define NETUP_CS1 0x00000200
+#define NETUP_CS0 0x00000100
+#define NETUP_EN_ALL 0x00001000
+#define NETUP_CTRL_OFF (NETUP_CS1 | NETUP_CS0 | NETUP_WR | NETUP_RD)
+#define NETUP_CI_CTL 0x04
+#define NETUP_CI_RD 1
+
+
+static unsigned int ci_dbg;
+module_param(ci_dbg, int, 0644);
+MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
+
+#define ci_dbg_print(args...) \
+ do { \
+ if (ci_dbg) \
+ printk(KERN_DEBUG args); \
+ } while (0)
+
+/* stores all private variables for communication with CI */
+struct netup_ci_state {
+ struct dvb_ca_en50221 ca;
+ struct mutex ca_mutex;
+ struct i2c_adapter *i2c_adap;
+ u8 ci_i2c_addr;
+ int status;
+ struct work_struct work;
+ void *priv;
+};
+
+struct mutex gpio_mutex;/* Two CiMax's uses same GPIO lines */
+
+int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+ u8 *buf, int len)
+{
+ int ret;
+ struct i2c_msg msg[] = {
+ {
+ .addr = addr,
+ .flags = 0,
+ .buf = &reg,
+ .len = 1
+ }, {
+ .addr = addr,
+ .flags = I2C_M_RD,
+ .buf = buf,
+ .len = len
+ }
+ };
+
+ ret = i2c_transfer(i2c_adap, msg, 2);
+
+ if (ret != 2) {
+ ci_dbg_print("%s: i2c read error, Reg = 0x%02x, Status = %d\n",
+ __func__, reg, ret);
+
+ return -1;
+ }
+
+ ci_dbg_print("%s: i2c read Addr=0x%04x, Reg = 0x%02x, data = %02x\n",
+ __func__, addr, reg, buf[0]);
+
+ return 0;
+}
+
+int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
+ u8 *buf, int len)
+{
+ int ret;
+ u8 buffer[len + 1];
+
+ struct i2c_msg msg = {
+ .addr = addr,
+ .flags = 0,
+ .buf = &buffer[0],
+ .len = len + 1
+ };
+
+ buffer[0] = reg;
+ memcpy(&buffer[1], buf, len);
+
+ ret = i2c_transfer(i2c_adap, &msg, 1);
+
+ if (ret != 1) {
+ ci_dbg_print("%s: i2c write error, Reg=[0x%02x], Status=%d\n",
+ __func__, reg, ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+int netup_ci_get_mem(struct cx23885_dev *dev)
+{
+ int mem;
+ unsigned long timeout = jiffies + msecs_to_jiffies(1);
+
+ for (;;) {
+ mem = cx_read(MC417_RWD);
+ if ((mem & NETUP_ACK) == 0)
+ break;
+ if (time_after(jiffies, timeout))
+ break;
+ udelay(1);
+ }
+
+ cx_set(MC417_RWD, NETUP_CTRL_OFF);
+
+ return mem & 0xff;
+}
+
+int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
+ u8 flag, u8 read, int addr, u8 data)
+{
+ struct netup_ci_state *state = en50221->data;
+ struct cx23885_tsport *port = state->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ u8 store;
+ int mem;
+ int ret;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &store, 1);
+ if (ret != 0)
+ return ret;
+
+ store &= ~0x0c;
+ store |= flag;
+
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &store, 1);
+ if (ret != 0)
+ return ret;
+
+ mutex_lock(&gpio_mutex);
+
+ /* write addr */
+ cx_write(MC417_OEN, NETUP_EN_ALL);
+ cx_write(MC417_RWD, NETUP_CTRL_OFF |
+ NETUP_ADLO | (0xff & addr));
+ cx_clear(MC417_RWD, NETUP_ADLO);
+ cx_write(MC417_RWD, NETUP_CTRL_OFF |
+ NETUP_ADHI | (0xff & (addr >> 8)));
+ cx_clear(MC417_RWD, NETUP_ADHI);
+
+ if (read) /* data in */
+ cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
+ else /* data out */
+ cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
+
+ /* choose chip */
+ cx_clear(MC417_RWD,
+ (state->ci_i2c_addr == 0x40) ? NETUP_CS0 : NETUP_CS1);
+ /* read/write */
+ cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
+ mem = netup_ci_get_mem(dev);
+
+ mutex_unlock(&gpio_mutex);
+
+ if (!read)
+ if (mem < 0)
+ return -EREMOTEIO;
+
+ ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
+ (read) ? "read" : "write", addr,
+ (flag == NETUP_CI_CTL) ? "ctl" : "mem",
+ (read) ? mem : data);
+
+ if (read)
+ return mem;
+
+ return 0;
+}
+
+int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr)
+{
+ return netup_ci_op_cam(en50221, slot, 0, NETUP_CI_RD, addr, 0);
+}
+
+int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr, u8 data)
+{
+ return netup_ci_op_cam(en50221, slot, 0, 0, addr, data);
+}
+
+int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
+{
+ return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL,
+ NETUP_CI_RD, addr, 0);
+}
+
+int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
+ u8 addr, u8 data)
+{
+ return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, 0, addr, data);
+}
+
+int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
+{
+ struct netup_ci_state *state = en50221->data;
+ u8 buf = 0x80;
+ int ret;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ udelay(500);
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf, 1);
+
+ if (ret != 0)
+ return ret;
+
+ udelay(500);
+
+ buf = 0x00;
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf, 1);
+
+ msleep(1000);
+ dvb_ca_en50221_camready_irq(&state->ca, 0);
+
+ return 0;
+
+}
+
+int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
+{
+ /* not implemented */
+ return 0;
+}
+
+int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
+{
+ struct netup_ci_state *state = en50221->data;
+ u8 buf = 0x60;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf, 1);
+}
+
+/* work handler */
+static void netup_read_ci_status(struct work_struct *work)
+{
+ struct netup_ci_state *state =
+ container_of(work, struct netup_ci_state, work);
+ u8 buf[33];
+ int ret;
+
+ ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &buf[0], 33);
+
+ if (ret != 0)
+ return;
+
+ ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, "
+ "TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
+ buf[32]);
+
+ if (buf[0] && 1)
+ state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
+ DVB_CA_EN50221_POLL_CAM_READY;
+ else
+ state->status = 0;
+}
+
+/* CI irq handler */
+int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status)
+{
+ struct cx23885_tsport *port = NULL;
+ struct netup_ci_state *state = NULL;
+
+ if (pci_status & PCI_MSK_GPIO0)
+ port = &dev->ts1;
+ else if (pci_status & PCI_MSK_GPIO1)
+ port = &dev->ts2;
+ else /* who calls ? */
+ return 0;
+
+ state = port->port_priv;
+
+ schedule_work(&state->work);
+
+ return 1;
+}
+
+int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
+{
+ struct netup_ci_state *state = en50221->data;
+
+ if (0 != slot)
+ return -EINVAL;
+
+ return state->status;
+}
+
+int netup_ci_init(struct cx23885_tsport *port)
+{
+ struct netup_ci_state *state;
+ u8 cimax_init[34] = {
+ 0x00, /* module A control*/
+ 0x00, /* auto select mask high A */
+ 0x00, /* auto select mask low A */
+ 0x00, /* auto select pattern high A */
+ 0x00, /* auto select pattern low A */
+ 0x44, /* memory access time A */
+ 0x00, /* invert input A */
+ 0x00, /* RFU */
+ 0x00, /* RFU */
+ 0x00, /* module B control*/
+ 0x00, /* auto select mask high B */
+ 0x00, /* auto select mask low B */
+ 0x00, /* auto select pattern high B */
+ 0x00, /* auto select pattern low B */
+ 0x44, /* memory access time B */
+ 0x00, /* invert input B */
+ 0x00, /* RFU */
+ 0x00, /* RFU */
+ 0x00, /* auto select mask high Ext */
+ 0x00, /* auto select mask low Ext */
+ 0x00, /* auto select pattern high Ext */
+ 0x00, /* auto select pattern low Ext */
+ 0x00, /* RFU */
+ 0x02, /* destination - module A */
+ 0x01, /* power on (use it like store place) */
+ 0x00, /* RFU */
+ 0x00, /* int status read only */
+ 0x01, /* all int unmasked */
+ 0x04, /* int config */
+ 0x00, /* USCG1 */
+ 0x04, /* ack active low */
+ 0x00, /* LOCK = 0 */
+ 0x33, /* serial mode, rising in, rising out, MSB first*/
+ 0x31, /* syncronization */
+ };
+ int ret;
+
+ ci_dbg_print("%s\n", __func__);
+ state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL);
+ if (!state) {
+ ci_dbg_print("%s: Unable create CI structure!\n", __func__);
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ port->port_priv = state;
+
+ switch (port->nr) {
+ case 1:
+ state->ci_i2c_addr = 0x40;
+ mutex_init(&gpio_mutex);
+ break;
+ case 2:
+ state->ci_i2c_addr = 0x41;
+ break;
+ }
+
+ state->i2c_adap = &port->dev->i2c_bus[0].i2c_adap;
+ state->ca.owner = THIS_MODULE;
+ state->ca.read_attribute_mem = netup_ci_read_attribute_mem;
+ state->ca.write_attribute_mem = netup_ci_write_attribute_mem;
+ state->ca.read_cam_control = netup_ci_read_cam_ctl;
+ state->ca.write_cam_control = netup_ci_write_cam_ctl;
+ state->ca.slot_reset = netup_ci_slot_reset;
+ state->ca.slot_shutdown = netup_ci_slot_shutdown;
+ state->ca.slot_ts_enable = netup_ci_slot_ts_ctl;
+ state->ca.poll_slot_status = netup_poll_ci_slot_status;
+ state->ca.data = state;
+ state->priv = port;
+
+ ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0, &cimax_init[0], 34);
+ /* lock registers */
+ ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0x1f, &cimax_init[0x18], 1);
+ /* power on slots */
+ ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
+ 0x18, &cimax_init[0x18], 1);
+
+ if (0 != ret)
+ goto err;
+
+ ret = dvb_ca_en50221_init(&port->frontends.adapter,
+ &state->ca,
+ /* flags */ 0,
+ /* n_slots */ 1);
+ if (0 != ret)
+ goto err;
+
+ INIT_WORK(&state->work, netup_read_ci_status);
+
+ ci_dbg_print("%s: CI initialized!\n", __func__);
+
+ return 0;
+err:
+ ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
+ kfree(state);
+ return ret;
+}
+
+void netup_ci_exit(struct cx23885_tsport *port)
+{
+ struct netup_ci_state *state;
+
+ if (NULL == port)
+ return;
+
+ state = (struct netup_ci_state *)port->port_priv;
+ if (NULL == state)
+ return;
+
+ if (NULL == state->ca.data)
+ return;
+
+ dvb_ca_en50221_release(&state->ca);
+ kfree(state);
+}
diff --git a/drivers/media/video/cx23885/cimax2.h b/drivers/media/video/cx23885/cimax2.h
new file mode 100644
index 00000000000..518744a4c8a
--- /dev/null
+++ b/drivers/media/video/cx23885/cimax2.h
@@ -0,0 +1,47 @@
+/*
+ * cimax2.h
+ *
+ * CIMax(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef CIMAX2_H
+#define CIMAX2_H
+#include "dvb_ca_en50221.h"
+
+extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr);
+extern int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
+ int slot, int addr, u8 data);
+extern int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr);
+extern int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221,
+ int slot, u8 addr, u8 data);
+extern int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot);
+extern int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status);
+extern int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
+ int slot, int open);
+extern int netup_ci_init(struct cx23885_tsport *port);
+extern void netup_ci_exit(struct cx23885_tsport *port);
+
+#endif
diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c
index bfe25841dbf..6f5df90af93 100644
--- a/drivers/media/video/cx23885/cx23885-417.c
+++ b/drivers/media/video/cx23885/cx23885-417.c
@@ -896,7 +896,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
if (retval != 0) {
printk(KERN_ERR
"ERROR: Hotplug firmware request failed (%s).\n",
- CX2341X_FIRM_ENC_FILENAME);
+ CX23885_FIRM_IMAGE_NAME);
printk(KERN_ERR "Please fix your hotplug setup, the board will "
"not work without firmware loaded!\n");
return -1;
@@ -1198,21 +1198,16 @@ static int vidioc_enum_input(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_input *input;
- unsigned int n;
+ int n;
- n = i->index;
-
- if (n >= 4)
+ if (i->index >= 4)
return -EINVAL;
- input = &cx23885_boards[dev->board].input[n];
+ input = &cx23885_boards[dev->board].input[i->index];
if (input->type == 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = n;
-
/* FIXME
* strcpy(i->name, input->name); */
strcpy(i->name, "unset");
@@ -1255,10 +1250,8 @@ static int vidioc_g_tuner(struct file *file, void *priv,
return -EINVAL;
if (0 != t->index)
return -EINVAL;
- memset(t, 0, sizeof(*t));
strcpy(t->name, "Television");
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+ call_all(dev, tuner, g_tuner, t);
dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
@@ -1275,7 +1268,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+ call_all(dev, tuner, s_tuner, t);
return 0;
}
@@ -1286,14 +1279,12 @@ static int vidioc_g_frequency(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- memset(f, 0, sizeof(*f));
if (UNSET == dev->tuner_type)
return -EINVAL;
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1320,8 +1311,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return -EINVAL;
dev->freq = f->frequency;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
cx23885_initialize_codec(dev);
@@ -1335,7 +1325,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct cx23885_dev *dev = fh->dev;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+ call_all(dev, core, s_ctrl, ctl);
return 0;
}
@@ -1346,7 +1336,6 @@ static int vidioc_querycap(struct file *file, void *priv,
struct cx23885_dev *dev = fh->dev;
struct cx23885_tsport *tsport = &dev->ts1;
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, dev->name);
strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
sizeof(cap->card));
@@ -1366,16 +1355,10 @@ static int vidioc_querycap(struct file *file, void *priv,
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- int index;
-
- index = f->index;
- if (index != 0)
+ if (f->index != 0)
return -EINVAL;
- memset(f, 0, sizeof(*f));
- f->index = index;
strlcpy(f->description, "MPEG", sizeof(f->description));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
@@ -1387,8 +1370,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- memset(f, 0, sizeof(*f));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
@@ -1408,12 +1389,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.sizeimage =
f->fmt.pix.colorspace = 0;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
dev->ts1.width, dev->ts1.height, fh->mpegq.field);
@@ -1426,7 +1405,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
@@ -1543,12 +1521,7 @@ static int vidioc_log_status(struct file *file, void *priv)
printk(KERN_INFO
"%s/2: ============ START LOG STATUS ============\n",
dev->name);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
- NULL);
+ call_all(dev, core, log_status);
cx2341x_log_status(&dev->mpeg_params, name);
printk(KERN_INFO
"%s/2: ============= END LOG STATUS =============\n",
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index caa098beeec..5e4b7e790d9 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -27,6 +27,7 @@
#include "cx23885.h"
#include "tuner-xc2028.h"
+#include "netup-init.h"
/* ------------------------------------------------------------------ */
/* board config info */
@@ -162,6 +163,24 @@ struct cx23885_board cx23885_boards[] = {
.name = "Compro VideoMate E650F",
.portc = CX23885_MPEG_DVB,
},
+ [CX23885_BOARD_TBS_6920] = {
+ .name = "TurboSight TBS 6920",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_TEVII_S470] = {
+ .name = "TeVii S470",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_DVBWORLD_2005] = {
+ .name = "DVBWorld DVB-S2 2005",
+ .portb = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = {
+ .cimax = 1,
+ .name = "NetUP Dual DVB-S2 CI",
+ .portb = CX23885_MPEG_DVB,
+ .portc = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -245,6 +264,22 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x185b,
.subdevice = 0xe800,
.card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F,
+ }, {
+ .subvendor = 0x6920,
+ .subdevice = 0x8888,
+ .card = CX23885_BOARD_TBS_6920,
+ }, {
+ .subvendor = 0xd470,
+ .subdevice = 0x9022,
+ .card = CX23885_BOARD_TEVII_S470,
+ }, {
+ .subvendor = 0x0001,
+ .subdevice = 0x2005,
+ .card = CX23885_BOARD_DVBWORLD_2005,
+ }, {
+ .subvendor = 0x1b55,
+ .subdevice = 0x2a2c,
+ .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -552,6 +587,38 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
mdelay(20);
cx_set(GP0_IO, 0x00040004);
break;
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_TEVII_S470:
+ cx_write(MC417_CTL, 0x00000036);
+ cx_write(MC417_OEN, 0x00001000);
+ cx_write(MC417_RWD, 0x00001800);
+ break;
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ /* GPIO-0 INTA from CiMax1
+ GPIO-1 INTB from CiMax2
+ GPIO-2 reset chips
+ GPIO-3 to GPIO-10 data/addr for CA
+ GPIO-11 ~CS0 to CiMax1
+ GPIO-12 ~CS1 to CiMax2
+ GPIO-13 ADL0 load LSB addr
+ GPIO-14 ADL1 load MSB addr
+ GPIO-15 ~RDY from CiMax
+ GPIO-17 ~RD to CiMax
+ GPIO-18 ~WR to CiMax
+ */
+ cx_set(GP0_IO, 0x00040000); /* GPIO as out */
+ /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */
+ cx_clear(GP0_IO, 0x00030004);
+ mdelay(100);/* reset delay */
+ cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */
+ cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */
+ /* GPIO-15 IN as ~ACK, rest as OUT */
+ cx_write(MC417_OEN, 0x00001000);
+ /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */
+ cx_write(MC417_RWD, 0x0000c300);
+ /* enable irq */
+ cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
+ break;
}
}
@@ -632,6 +699,21 @@ void cx23885_card_setup(struct cx23885_dev *dev)
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
break;
+ case CX23885_BOARD_TEVII_S470:
+ case CX23885_BOARD_TBS_6920:
+ case CX23885_BOARD_DVBWORLD_2005:
+ ts1->gen_ctrl_val = 0x5; /* Parallel */
+ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ break;
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
+ ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
+ ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
+ ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
+ break;
case CX23885_BOARD_HAUPPAUGE_HVR1250:
case CX23885_BOARD_HAUPPAUGE_HVR1500:
case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
@@ -656,7 +738,17 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1700:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
- request_module("cx25840");
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->i2c_bus[2].i2c_adap,
+ "cx25840", "cx25840", 0x88 >> 1);
+ v4l2_subdev_call(dev->sd_cx25840, core, init, 0);
+ break;
+ }
+
+ /* AUX-PLL 27MHz CLK */
+ switch (dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ netup_initialize(dev);
break;
}
}
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 8f6fb2add7d..dc7fff22cfd 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -31,6 +31,7 @@
#include <asm/div64.h>
#include "cx23885.h"
+#include "cimax2.h"
MODULE_DESCRIPTION("Driver for cx23885 based TV cards");
MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
@@ -791,6 +792,8 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
dev->pci_bus = dev->pci->bus->number;
dev->pci_slot = PCI_SLOT(dev->pci->devfn);
dev->pci_irqmask = 0x001f00;
+ if (cx23885_boards[dev->board].cimax > 0)
+ dev->pci_irqmask |= 0x01800000; /* for CiMaxes */
/* External Master 1 Bus */
dev->i2c_bus[0].nr = 0;
@@ -872,7 +875,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
cx23885_i2c_register(&dev->i2c_bus[1]);
cx23885_i2c_register(&dev->i2c_bus[2]);
cx23885_card_setup(dev);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+ call_all(dev, core, s_standby, 0);
cx23885_ir_init(dev);
if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1643,7 +1646,9 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
(pci_status & PCI_MSK_VID_B) ||
(pci_status & PCI_MSK_VID_A) ||
(pci_status & PCI_MSK_AUD_INT) ||
- (pci_status & PCI_MSK_AUD_EXT)) {
+ (pci_status & PCI_MSK_AUD_EXT) ||
+ (pci_status & PCI_MSK_GPIO0) ||
+ (pci_status & PCI_MSK_GPIO1)) {
if (pci_status & PCI_MSK_RISC_RD)
dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n",
@@ -1685,8 +1690,20 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n",
PCI_MSK_AUD_EXT);
+ if (pci_status & PCI_MSK_GPIO0)
+ dprintk(7, " (PCI_MSK_GPIO0 0x%08x)\n",
+ PCI_MSK_GPIO0);
+
+ if (pci_status & PCI_MSK_GPIO1)
+ dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n",
+ PCI_MSK_GPIO1);
}
+ if (cx23885_boards[dev->board].cimax > 0 &&
+ ((pci_status & PCI_MSK_GPIO0) || (pci_status & PCI_MSK_GPIO1)))
+ /* handled += cx23885_irq_gpio(dev, pci_status); */
+ handled += netup_ci_slot_status(dev, pci_status);
+
if (ts1_status) {
if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
handled += cx23885_irq_ts(ts1, ts1_status);
@@ -1722,16 +1739,20 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
if (NULL == dev)
return -ENOMEM;
+ err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+ if (err < 0)
+ goto fail_free;
+
/* pci init */
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
err = -EIO;
- goto fail_free;
+ goto fail_unreg;
}
if (cx23885_dev_setup(dev) < 0) {
err = -EINVAL;
- goto fail_free;
+ goto fail_unreg;
}
/* print pci info */
@@ -1758,11 +1779,18 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
goto fail_irq;
}
- pci_set_drvdata(pci_dev, dev);
+ switch (dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ cx_set(PCI_INT_MSK, 0x01800000); /* for NetUP */
+ break;
+ }
+
return 0;
fail_irq:
cx23885_dev_unregister(dev);
+fail_unreg:
+ v4l2_device_unregister(&dev->v4l2_dev);
fail_free:
kfree(dev);
return err;
@@ -1770,7 +1798,8 @@ fail_free:
static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
{
- struct cx23885_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct cx23885_dev *dev = to_cx23885(v4l2_dev);
cx23885_shutdown(dev);
@@ -1778,13 +1807,13 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
/* unregister stuff */
free_irq(pci_dev->irq, dev);
- pci_set_drvdata(pci_dev, NULL);
mutex_lock(&devlist);
list_del(&dev->devlist);
mutex_unlock(&devlist);
cx23885_dev_unregister(dev);
+ v4l2_device_unregister(v4l2_dev);
kfree(dev);
}
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 1c454128a9d..d43c7439676 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -30,6 +30,7 @@
#include "cx23885.h"
#include <media/v4l2-common.h>
+#include "dvb_ca_en50221.h"
#include "s5h1409.h"
#include "s5h1411.h"
#include "mt2131.h"
@@ -43,6 +44,13 @@
#include "dib7000p.h"
#include "dibx000_common.h"
#include "zl10353.h"
+#include "stv0900.h"
+#include "stv6110.h"
+#include "lnbh24.h"
+#include "cx24116.h"
+#include "cimax2.h"
+#include "netup-eeprom.h"
+#include "netup-init.h"
static unsigned int debug;
@@ -308,11 +316,63 @@ static struct zl10353_config dvico_fusionhdtv_xc3028 = {
.no_tuner = 1,
};
+static struct stv0900_config netup_stv0900_config = {
+ .demod_address = 0x68,
+ .xtal = 27000000,
+ .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */
+ .diseqc_mode = 2,/* 2/3 PWM */
+ .path1_mode = 2,/*Serial continues clock */
+ .path2_mode = 2,/*Serial continues clock */
+ .tun1_maddress = 0,/* 0x60 */
+ .tun2_maddress = 3,/* 0x63 */
+ .tun1_adc = 1,/* 1 Vpp */
+ .tun2_adc = 1,/* 1 Vpp */
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_a = {
+ .i2c_address = 0x60,
+ .mclk = 27000000,
+ .iq_wiring = 0,
+};
+
+static struct stv6110_config netup_stv6110_tunerconfig_b = {
+ .i2c_address = 0x63,
+ .mclk = 27000000,
+ .iq_wiring = 1,
+};
+
+static int tbs_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
+{
+ struct cx23885_tsport *port = fe->dvb->priv;
+ struct cx23885_dev *dev = port->dev;
+
+ if (voltage == SEC_VOLTAGE_18)
+ cx_write(MC417_RWD, 0x00001e00);/* GPIO-13 high */
+ else if (voltage == SEC_VOLTAGE_13)
+ cx_write(MC417_RWD, 0x00001a00);/* GPIO-13 low */
+ else
+ cx_write(MC417_RWD, 0x00001800);/* GPIO-12 low */
+ return 0;
+}
+
+static struct cx24116_config tbs_cx24116_config = {
+ .demod_address = 0x05,
+};
+
+static struct cx24116_config tevii_cx24116_config = {
+ .demod_address = 0x55,
+};
+
+static struct cx24116_config dvbworld_cx24116_config = {
+ .demod_address = 0x05,
+};
+
static int dvb_register(struct cx23885_tsport *port)
{
struct cx23885_dev *dev = port->dev;
struct cx23885_i2c *i2c_bus = NULL;
struct videobuf_dvb_frontend *fe0;
+ int ret;
/* Get the first frontend */
fe0 = videobuf_dvb_get_frontend(&port->frontends, 1);
@@ -526,6 +586,78 @@ static int dvb_register(struct cx23885_tsport *port)
fe->ops.tuner_ops.set_config(fe, &ctl);
}
break;
+ case CX23885_BOARD_TBS_6920:
+ i2c_bus = &dev->i2c_bus[0];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tbs_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_TEVII_S470:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &tevii_cx24116_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL)
+ fe0->dvb.frontend->ops.set_voltage = tbs_set_voltage;
+
+ break;
+ case CX23885_BOARD_DVBWORLD_2005:
+ i2c_bus = &dev->i2c_bus[1];
+
+ fe0->dvb.frontend = dvb_attach(cx24116_attach,
+ &dvbworld_cx24116_config,
+ &i2c_bus->i2c_adap);
+ break;
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ i2c_bus = &dev->i2c_bus[0];
+ switch (port->nr) {
+ /* port B */
+ case 1:
+ fe0->dvb.frontend = dvb_attach(stv0900_attach,
+ &netup_stv0900_config,
+ &i2c_bus->i2c_adap, 0);
+ if (fe0->dvb.frontend != NULL) {
+ if (dvb_attach(stv6110_attach,
+ fe0->dvb.frontend,
+ &netup_stv6110_tunerconfig_a,
+ &i2c_bus->i2c_adap)) {
+ if (!dvb_attach(lnbh24_attach,
+ fe0->dvb.frontend,
+ &i2c_bus->i2c_adap,
+ LNBH24_PCL, 0, 0x09))
+ printk(KERN_ERR
+ "No LNBH24 found!\n");
+
+ }
+ }
+ break;
+ /* port C */
+ case 2:
+ fe0->dvb.frontend = dvb_attach(stv0900_attach,
+ &netup_stv0900_config,
+ &i2c_bus->i2c_adap, 1);
+ if (fe0->dvb.frontend != NULL) {
+ if (dvb_attach(stv6110_attach,
+ fe0->dvb.frontend,
+ &netup_stv6110_tunerconfig_b,
+ &i2c_bus->i2c_adap)) {
+ if (!dvb_attach(lnbh24_attach,
+ fe0->dvb.frontend,
+ &i2c_bus->i2c_adap,
+ LNBH24_PCL, 0, 0x0a))
+ printk(KERN_ERR
+ "No LNBH24 found!\n");
+
+ }
+ }
+ break;
+ }
+ break;
default:
printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
" isn't supported yet\n",
@@ -541,15 +673,39 @@ static int dvb_register(struct cx23885_tsport *port)
fe0->dvb.frontend->callback = cx23885_tuner_callback;
/* Put the analog decoder in standby to keep it quiet */
- cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+ call_all(dev, core, s_standby, 0);
if (fe0->dvb.frontend->ops.analog_ops.standby)
fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
/* register everything */
- return videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
+ ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
&dev->pci->dev, adapter_nr, 0);
+ /* init CI & MAC */
+ switch (dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: {
+ static struct netup_card_info cinfo;
+
+ netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo);
+ memcpy(port->frontends.adapter.proposed_mac,
+ cinfo.port[port->nr - 1].mac, 6);
+ printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC="
+ "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ port->nr,
+ port->frontends.adapter.proposed_mac[0],
+ port->frontends.adapter.proposed_mac[1],
+ port->frontends.adapter.proposed_mac[2],
+ port->frontends.adapter.proposed_mac[3],
+ port->frontends.adapter.proposed_mac[4],
+ port->frontends.adapter.proposed_mac[5]);
+
+ netup_ci_init(port);
+ break;
+ }
+ }
+
+ return ret;
}
int cx23885_dvb_register(struct cx23885_tsport *port)
@@ -622,6 +778,12 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
if (fe0->dvb.frontend)
videobuf_dvb_unregister_bus(&port->frontends);
+ switch (port->dev->board) {
+ case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
+ netup_ci_exit(port);
+ break;
+ }
+
return 0;
}
diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c
index bb7f71a1fcb..3421bd12056 100644
--- a/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/drivers/media/video/cx23885/cx23885-i2c.c
@@ -268,64 +268,6 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap,
return retval;
}
-static int attach_inform(struct i2c_client *client)
-{
- struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter);
- struct cx23885_dev *dev = bus->dev;
- struct tuner_setup tun_setup;
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- if (!client->driver->command)
- return 0;
-
- if (dev->tuner_type != UNSET) {
-
- dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr,
- client->name);
-
- if ((dev->tuner_addr == ADDR_UNSET) ||
- (dev->tuner_addr == client->addr)) {
-
- dprintk(1, "%s (tuner || addr UNSET)\n",
- client->driver->driver.name);
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name,
- client->addr, client->name);
-
- tun_setup.mode_mask = T_ANALOG_TV;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
-
- client->driver->command(client, TUNER_SET_TYPE_ADDR,
- &tun_setup);
- }
- }
-
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
-
- dprintk(1, "i2c detach [client=%s]\n", client->name);
-
- return 0;
-}
-
-void cx23885_call_i2c_clients(struct cx23885_i2c *bus,
- unsigned int cmd, void *arg)
-{
- if (bus->i2c_rc != 0)
- return;
-
- i2c_clients_command(&bus->i2c_adap, cmd, arg);
-}
-
static u32 cx23885_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -343,9 +285,6 @@ static struct i2c_adapter cx23885_i2c_adap_template = {
.owner = THIS_MODULE,
.id = I2C_HW_B_CX23885,
.algo = &cx23885_i2c_algo_template,
- .class = I2C_CLASS_TV_ANALOG,
- .client_register = attach_inform,
- .client_unregister = detach_inform,
};
static struct i2c_client cx23885_i2c_client_template = {
@@ -402,15 +341,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
bus->i2c_algo.data = bus;
bus->i2c_adap.algo_data = bus;
- i2c_set_adapdata(&bus->i2c_adap, bus);
+ i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&bus->i2c_adap);
bus->i2c_client.adapter = &bus->i2c_adap;
if (0 == bus->i2c_rc) {
dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
- if (i2c_scan)
+ if (i2c_scan) {
+ printk(KERN_INFO "%s: scan bus %d:\n",
+ dev->name, bus->nr);
do_i2c_scan(dev->name, &bus->i2c_client);
+ }
} else
printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index 20b68a23626..eafbe5226ba 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -212,6 +212,8 @@ Channel manager Data Structure entry = 20 DWORD
#define DEV_CNTRL2 0x00040000
+#define PCI_MSK_GPIO1 (1 << 24)
+#define PCI_MSK_GPIO0 (1 << 23)
#define PCI_MSK_APB_DMA (1 << 12)
#define PCI_MSK_AL_WR (1 << 11)
#define PCI_MSK_AL_RD (1 << 10)
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index eaa11893bfe..f0ac62c5dc8 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -35,11 +35,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
-
MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards");
MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
MODULE_LICENSE("GPL");
@@ -244,6 +239,7 @@ static struct cx23885_ctrl cx23885_ctls[] = {
};
static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls);
+/* Must be sorted from low to high control ID! */
static const u32 cx23885_user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -303,11 +299,7 @@ static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
dev->tvnorm = norm;
- /* Tell the analog tuner/demods */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm);
-
- /* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm);
+ call_all(dev, tuner, s_std, norm);
return 0;
}
@@ -324,8 +316,8 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
if (NULL == vfd)
return NULL;
*vfd = *template;
- vfd->minor = -1;
- vfd->parent = &pci->dev;
+ vfd->minor = -1;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
dev->name, type, cx23885_boards[dev->board].name);
@@ -414,8 +406,7 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
route.input = INPUT(input)->vmux;
/* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2],
- VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route);
return 0;
}
@@ -891,7 +882,7 @@ static int cx23885_get_control(struct cx23885_dev *dev,
struct v4l2_control *ctl)
{
dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
+ call_all(dev, core, g_ctrl, ctl);
return 0;
}
@@ -1005,7 +996,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
fh->vidq.field = f->fmt.pix.field;
dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
fh->width, fh->height, fh->vidq.field);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f);
+ call_all(dev, video, s_fmt, f);
return 0;
}
@@ -1285,7 +1276,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1300,7 +1291,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
mutex_lock(&dev->lock);
dev->freq = f->frequency;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
/* When changing channels it is required to reset TVAUDIO */
msleep(10);
@@ -1334,7 +1325,7 @@ static int vidioc_g_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg);
+ call_all(dev, core, g_register, reg);
return 0;
}
@@ -1347,7 +1338,7 @@ static int vidioc_s_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg);
+ call_all(dev, core, s_register, reg);
return 0;
}
@@ -1528,6 +1519,26 @@ int cx23885_video_register(struct cx23885_dev *dev)
/* Don't enable VBI yet */
cx_set(PCI_INT_MSK, 1);
+ if (TUNER_ABSENT != dev->tuner_type) {
+ struct v4l2_subdev *sd = NULL;
+
+ if (dev->tuner_addr)
+ sd = v4l2_i2c_new_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ else
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
+ if (sd) {
+ struct tuner_setup tun_setup;
+
+ tun_setup.mode_mask = T_ANALOG_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+
+ v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
+ }
+ }
+
/* register v4l devices */
dev->video_dev = cx23885_vdev_init(dev, dev->pci,
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 67828029fc6..02d980a2996 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -24,7 +24,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/kdev_t.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
@@ -67,6 +67,10 @@
#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11
#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12
#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13
+#define CX23885_BOARD_TBS_6920 14
+#define CX23885_BOARD_TEVII_S470 15
+#define CX23885_BOARD_DVBWORLD_2005 16
+#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\
@@ -184,6 +188,7 @@ struct cx23885_board {
*/
u32 clk_freq;
struct cx23885_input input[MAX_CX23885_INPUT];
+ int cimax; /* for NetUP */
};
struct cx23885_subid {
@@ -266,11 +271,13 @@ struct cx23885_tsport {
/* Allow a single tsport to have multiple frontends */
u32 num_frontends;
+ void *port_priv;
};
struct cx23885_dev {
struct list_head devlist;
atomic_t refcount;
+ struct v4l2_device v4l2_dev;
/* pci stuff */
struct pci_dev *pci;
@@ -316,6 +323,7 @@ struct cx23885_dev {
unsigned int radio_type;
unsigned char radio_addr;
unsigned int has_radio;
+ struct v4l2_subdev *sd_cx25840;
/* V4l */
u32 freq;
@@ -336,6 +344,14 @@ struct cx23885_dev {
};
+static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev);
+}
+
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
+
extern struct list_head cx23885_devlist;
#define SRAM_CH01 0 /* Video A */
@@ -452,8 +468,6 @@ extern struct videobuf_queue_ops cx23885_vbi_qops;
/* cx23885-i2c.c */
extern int cx23885_i2c_register(struct cx23885_i2c *bus);
extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
-extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
- void *arg);
extern void cx23885_av_clk(struct cx23885_dev *dev, int enable);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/video/cx23885/netup-eeprom.c
new file mode 100644
index 00000000000..042bbbbd48f
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-eeprom.c
@@ -0,0 +1,107 @@
+
+/*
+ * netup-eeprom.c
+ *
+ * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#
+#include "cx23885.h"
+#include "netup-eeprom.h"
+
+#define EEPROM_I2C_ADDR 0x50
+
+int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr)
+{
+ int ret;
+ unsigned char buf[2];
+
+ /* Read from EEPROM */
+ struct i2c_msg msg[] = {
+ {
+ .addr = EEPROM_I2C_ADDR,
+ .flags = 0,
+ .buf = &buf[0],
+ .len = 1
+ }, {
+ .addr = EEPROM_I2C_ADDR,
+ .flags = I2C_M_RD,
+ .buf = &buf[1],
+ .len = 1
+ }
+
+ };
+
+ buf[0] = addr;
+ buf[1] = 0x0;
+
+ ret = i2c_transfer(i2c_adap, msg, 2);
+
+ if (ret != 2) {
+ printk(KERN_ERR "eeprom i2c read error, status=%d\n", ret);
+ return -1;
+ }
+
+ return buf[1];
+};
+
+int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data)
+{
+ int ret;
+ unsigned char bufw[2];
+
+ /* Write into EEPROM */
+ struct i2c_msg msg[] = {
+ {
+ .addr = EEPROM_I2C_ADDR,
+ .flags = 0,
+ .buf = &bufw[0],
+ .len = 2
+ }
+ };
+
+ bufw[0] = addr;
+ bufw[1] = data;
+
+ ret = i2c_transfer(i2c_adap, msg, 1);
+
+ if (ret != 1) {
+ printk(KERN_ERR "eeprom i2c write error, status=%d\n", ret);
+ return -1;
+ }
+
+ mdelay(10); /* prophylactic delay, datasheet write cycle time = 5 ms */
+ return 0;
+};
+
+void netup_get_card_info(struct i2c_adapter *i2c_adap,
+ struct netup_card_info *cinfo)
+{
+ int i, j;
+
+ cinfo->rev = netup_eeprom_read(i2c_adap, 13);
+
+ for (i = 0, j = 0; i < 6; i++, j++)
+ cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i);
+
+ for (i = 6, j = 0; i < 12; i++, j++)
+ cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i);
+};
diff --git a/drivers/media/video/cx23885/netup-eeprom.h b/drivers/media/video/cx23885/netup-eeprom.h
new file mode 100644
index 00000000000..13926e18feb
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-eeprom.h
@@ -0,0 +1,42 @@
+/*
+ * netup-eeprom.h
+ *
+ * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef NETUP_EEPROM_H
+#define NETUP_EEPROM_H
+
+struct netup_port_info {
+ u8 mac[6];/* card MAC address */
+};
+
+struct netup_card_info {
+ struct netup_port_info port[2];/* ports - 1,2 */
+ u8 rev;/* card revision */
+};
+
+extern int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr);
+extern int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data);
+extern void netup_get_card_info(struct i2c_adapter *i2c_adap,
+ struct netup_card_info *cinfo);
+
+#endif
diff --git a/drivers/media/video/cx23885/netup-init.c b/drivers/media/video/cx23885/netup-init.c
new file mode 100644
index 00000000000..f4893e69cd8
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-init.c
@@ -0,0 +1,125 @@
+/*
+ * netup-init.c
+ *
+ * NetUP Dual DVB-S2 CI driver
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "cx23885.h"
+
+static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val)
+{
+ int ret;
+ u8 buf[3];
+ struct i2c_msg msg = {
+ .addr = 0x88 >> 1,
+ .flags = 0,
+ .buf = buf,
+ .len = 3
+ };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ buf[2] = val;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c write error!\n", __func__);
+}
+
+static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val)
+{
+ int ret;
+ u8 buf[6];
+ struct i2c_msg msg = {
+ .addr = 0x88 >> 1,
+ .flags = 0,
+ .buf = buf,
+ .len = 6
+ };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+ buf[2] = val & 0xff;
+ buf[3] = (val >> 8) & 0xff;
+ buf[4] = (val >> 16) & 0xff;
+ buf[5] = val >> 24;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c write error!\n", __func__);
+}
+
+static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg)
+{
+ int ret;
+ u8 buf[2];
+ struct i2c_msg msg = {
+ .addr = 0x88 >> 1,
+ .flags = 0,
+ .buf = buf,
+ .len = 2
+ };
+
+ buf[0] = reg >> 8;
+ buf[1] = reg & 0xff;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c write error!\n", __func__);
+
+ msg.flags = I2C_M_RD;
+ msg.len = 1;
+
+ ret = i2c_transfer(i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: i2c read error!\n", __func__);
+
+ return buf[0];
+}
+
+static void i2c_av_and_or(struct i2c_adapter *i2c, u16 reg, unsigned and_mask,
+ u8 or_value)
+{
+ i2c_av_write(i2c, reg, (i2c_av_read(i2c, reg) & and_mask) | or_value);
+}
+/* set 27MHz on AUX_CLK */
+void netup_initialize(struct cx23885_dev *dev)
+{
+ struct cx23885_i2c *i2c_bus = &dev->i2c_bus[2];
+ struct i2c_adapter *i2c = &i2c_bus->i2c_adap;
+
+ /* Stop microcontroller */
+ i2c_av_and_or(i2c, 0x803, ~0x10, 0x00);
+
+ /* Aux PLL frac for 27 MHz */
+ i2c_av_write4(i2c, 0x114, 0xea0eb3);
+
+ /* Aux PLL int for 27 MHz */
+ i2c_av_write4(i2c, 0x110, 0x090319);
+
+ /* start microcontroller */
+ i2c_av_and_or(i2c, 0x803, ~0x10, 0x10);
+}
diff --git a/drivers/media/video/cx23885/netup-init.h b/drivers/media/video/cx23885/netup-init.h
new file mode 100644
index 00000000000..d26ae4b1590
--- /dev/null
+++ b/drivers/media/video/cx23885/netup-init.h
@@ -0,0 +1,25 @@
+/*
+ * netup-init.h
+ *
+ * NetUP Dual DVB-S2 CI driver
+ *
+ * Copyright (C) 2009 NetUP Inc.
+ * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
+ * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+extern void netup_initialize(struct cx23885_dev *dev);
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index d199d80ea0a..93d74bee292 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -363,75 +363,74 @@ static void set_mute(struct i2c_client *client, int mute)
}
}
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct v4l2_control *ctrl = arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
int retval;
- switch (cmd) {
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- if (!state->is_cx25836)
- cx25840_and_or(client, 0x810, ~0x1, 1);
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- cx25840_and_or(client, 0x803, ~0x10, 0);
- cx25840_write(client, 0x8d3, 0x1f);
- }
- retval = set_audclk_freq(client, *(u32 *)arg);
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- }
- if (!state->is_cx25836)
- cx25840_and_or(client, 0x810, ~0x1, 0);
- return retval;
-
- case VIDIOC_G_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = get_volume(client);
- break;
- case V4L2_CID_AUDIO_BASS:
- ctrl->value = get_bass(client);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = get_treble(client);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- ctrl->value = get_balance(client);
- break;
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = get_mute(client);
- break;
- default:
- return -EINVAL;
- }
- break;
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 1);
+ if (state->aud_input != CX25840_AUDIO_SERIAL) {
+ cx25840_and_or(client, 0x803, ~0x10, 0);
+ cx25840_write(client, 0x8d3, 0x1f);
+ }
+ retval = set_audclk_freq(client, freq);
+ if (state->aud_input != CX25840_AUDIO_SERIAL)
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 0);
+ return retval;
+}
- case VIDIOC_S_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(client, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
- break;
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = get_volume(client);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = get_bass(client);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = get_treble(client);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = get_balance(client);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = get_mute(client);
+ break;
default:
return -EINVAL;
}
+ return 0;
+}
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ set_volume(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ set_bass(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ set_treble(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ set_balance(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ set_mute(client, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 25eb3bec9e5..737ee4ea883 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -39,7 +39,7 @@
#include <linux/delay.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/cx25840.h>
#include "cx25840-core.h"
@@ -48,15 +48,12 @@ MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
MODULE_LICENSE("GPL");
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-
static int cx25840_debug;
module_param_named(debug,cx25840_debug, int, 0644);
MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -763,7 +760,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l_err(client, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -778,7 +775,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_MUTE:
if (state->is_cx25836)
return -EINVAL;
- return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
+ return cx25840_audio_s_ctrl(sd, ctrl);
default:
return -EINVAL;
@@ -815,7 +812,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_MUTE:
if (state->is_cx25836)
return -EINVAL;
- return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
+ return cx25840_audio_g_ctrl(sd, ctrl);
default:
return -EINVAL;
}
@@ -827,11 +824,9 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
switch (fmt->type) {
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
+ return cx25840_vbi_g_fmt(sd, fmt);
default:
return -EINVAL;
}
@@ -893,10 +888,10 @@ static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+ return cx25840_vbi_s_fmt(sd, fmt);
case V4L2_BUF_TYPE_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+ return cx25840_vbi_s_fmt(sd, fmt);
default:
return -EINVAL;
@@ -1101,6 +1096,16 @@ static void log_audio_status(struct i2c_client *client)
/* ----------------------------------------------------------------------- */
+/* This init operation must be called to load the driver's firmware.
+ Without this the audio standard detection will fail and you will
+ only get mono.
+
+ Since loading the firmware is often problematic when the driver is
+ compiled into the kernel I recommend postponing calling this function
+ until the first open of the video device. Another reason for
+ postponing it is that loading this firmware takes a long time (seconds)
+ due to the slow i2c bus speed. So it will speed up the boot process if
+ you can avoid loading the fw as long as the video device isn't used. */
static int cx25840_init(struct v4l2_subdev *sd, u32 val)
{
struct cx25840_state *state = to_state(sd);
@@ -1146,20 +1151,6 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
}
#endif
-static int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return cx25840_vbi(client, VIDIOC_INT_DECODE_VBI_LINE, vbi);
-}
-
-static int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return cx25840_audio(client, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq);
-}
-
static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
{
struct cx25840_state *state = to_state(sd);
@@ -1195,10 +1186,12 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
default:
break;
}
@@ -1210,10 +1203,11 @@ static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return v4l2_ctrl_query_fill(qc, 0, 65535,
65535 / 100, state->default_volume);
case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
default:
return -EINVAL;
}
@@ -1380,19 +1374,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- /* ignore this command */
- if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
- return 0;
-
- /* Old-style drivers rely on initialization on first use, so
- call the init whenever a command is issued to this driver.
- New-style drivers using v4l2_subdev should call init explicitly. */
- cx25840_init(i2c_get_clientdata(client), 0);
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cx25840_core_ops = {
@@ -1528,8 +1509,6 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cx25840",
- .driverid = I2C_DRIVERID_CX25840,
- .command = cx25840_command,
.probe = cx25840_probe,
.remove = cx25840_remove,
.id_table = cx25840_id,
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index be0558277ca..9ad0eb86ecf 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -75,11 +75,15 @@ 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);
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
/* ----------------------------------------------------------------------- */
/* cx25850-vbi.c */
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi);
#endif
diff --git a/drivers/media/video/cx25840/cx25840-vbi.c b/drivers/media/video/cx25840/cx25840-vbi.c
index 03f09b288eb..35f6592f6c4 100644
--- a/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/drivers/media/video/cx25840/cx25840-vbi.c
@@ -82,199 +82,181 @@ static int decode_vps(u8 * dst, u8 * p)
return err & 0xf0;
}
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct v4l2_format *fmt;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
struct v4l2_sliced_vbi_format *svbi;
+ static const u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_WSS_625, 0, /* 4 */
+ V4L2_SLICED_CAPTION_525, /* 6 */
+ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ 0, 0, 0, 0
+ };
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i;
- switch (cmd) {
- case VIDIOC_G_FMT:
- {
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx25840_read(client, 0x404) & 0x10) == 0)
- break;
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ memset(svbi, 0, sizeof(*svbi));
+ /* we're done if raw VBI is active */
+ if ((cx25840_read(client, 0x404) & 0x10) == 0)
+ return 0;
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 7);
+ if (is_pal) {
+ for (i = 7; i <= 23; i++) {
+ u8 v = cx25840_read(client, 0x424 + i - 7);
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |=
- svbi->service_lines[0][i] | svbi->service_lines[1][i];
- }
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
- else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |=
- svbi->service_lines[0][i] | svbi->service_lines[1][i];
- }
+ } else {
+ for (i = 10; i <= 21; i++) {
+ u8 v = cx25840_read(client, 0x424 + i - 10);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
- break;
}
+ return 0;
+}
- case VIDIOC_S_FMT:
- {
- int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
- int i, x;
- u8 lcr[24];
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
- fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- /* raw VBI */
- memset(svbi, 0, sizeof(*svbi));
-
- /* Setup standard */
- cx25840_std_setup(client);
-
- /* VBI Offset */
- cx25840_write(client, 0x47f, vbi_offset);
- cx25840_write(client, 0x404, 0x2e);
- break;
- }
-
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
+ struct v4l2_sliced_vbi_format *svbi;
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int vbi_offset = is_pal ? 1 : 0;
+ int i, x;
+ u8 lcr[24];
+
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+ fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* raw VBI */
+ memset(svbi, 0, sizeof(*svbi));
/* Setup standard */
cx25840_std_setup(client);
- /* Sliced VBI */
- cx25840_write(client, 0x404, 0x32); /* Ancillary data */
- cx25840_write(client, 0x406, 0x13);
+ /* VBI Offset */
cx25840_write(client, 0x47f, vbi_offset);
+ cx25840_write(client, 0x404, 0x2e);
+ return 0;
+ }
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
-
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
+ for (x = 0; x <= 23; x++)
+ lcr[x] = 0x00;
+
+ /* Setup standard */
+ cx25840_std_setup(client);
+
+ /* Sliced VBI */
+ cx25840_write(client, 0x404, 0x32); /* Ancillary data */
+ cx25840_write(client, 0x406, 0x13);
+ cx25840_write(client, 0x47f, vbi_offset);
+
+ if (is_pal) {
+ for (i = 0; i <= 6; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ } else {
+ for (i = 0; i <= 9; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+
+ for (i = 22; i <= 23; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ }
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
- cx25840_write(client, i, lcr[6 + x]);
- }
- }
- else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++) {
- cx25840_write(client, i, lcr[9 + x]);
- }
- for (i = 0x431; i <= 0x434; i++) {
- cx25840_write(client, i, 0);
+ for (i = 7; i <= 23; i++) {
+ for (x = 0; x <= 1; x++) {
+ switch (svbi->service_lines[1-x][i]) {
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 6 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 9 << (4 * x);
+ break;
}
}
+ }
- cx25840_write(client, 0x43c, 0x16);
-
- if (is_pal) {
- cx25840_write(client, 0x474, 0x2a);
- } else {
- cx25840_write(client, 0x474, 0x22);
- }
- break;
+ if (is_pal) {
+ for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+ cx25840_write(client, i, lcr[6 + x]);
+ } else {
+ for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+ cx25840_write(client, i, lcr[9 + x]);
+ for (i = 0x431; i <= 0x434; i++)
+ cx25840_write(client, i, 0);
}
- case VIDIOC_INT_DECODE_VBI_LINE:
- {
- struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
+ cx25840_write(client, 0x43c, 0x16);
+ cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
+ return 0;
+}
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
- vbi->line = vbi->type = 0;
- break;
- }
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
+{
+ struct cx25840_state *state = to_state(sd);
+ u8 *p = vbi->p;
+ int id1, id2, l, err = 0;
+
+ if (p[0] || p[1] != 0xff || p[2] != 0xff ||
+ (p[3] != 0x55 && p[3] != 0x91)) {
+ vbi->line = vbi->type = 0;
+ return 0;
+ }
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += state->vbi_line_offset;
- p += 4;
+ p += 4;
+ id1 = p[-1];
+ id2 = p[0] & 0xf;
+ l = p[2] & 0x3f;
+ l += state->vbi_line_offset;
+ p += 4;
- switch (id2) {
- case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- id2 = V4L2_SLICED_WSS_625;
- break;
- case 6:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- id2 = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0) {
- err = 1;
- }
- break;
- default:
- id2 = 0;
+ switch (id2) {
+ case 1:
+ id2 = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ id2 = V4L2_SLICED_WSS_625;
+ break;
+ case 6:
+ id2 = V4L2_SLICED_CAPTION_525;
+ err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ break;
+ case 9:
+ id2 = V4L2_SLICED_VPS;
+ if (decode_vps(p, p) != 0)
err = 1;
- break;
- }
-
- vbi->type = err ? 0 : id2;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
- vbi->p = p;
break;
- }
+ default:
+ id2 = 0;
+ err = 1;
+ break;
}
+ vbi->type = err ? 0 : id2;
+ vbi->line = err ? 0 : l;
+ vbi->is_second_field = err ? 0 : (id1 == 0x55);
+ vbi->p = p;
return 0;
}
diff --git a/drivers/media/video/cx88/Kconfig b/drivers/media/video/cx88/Kconfig
index 2d250a2a7bc..49952980dab 100644
--- a/drivers/media/video/cx88/Kconfig
+++ b/drivers/media/video/cx88/Kconfig
@@ -61,7 +61,7 @@ config VIDEO_CX88_DVB
select DVB_STV0299 if !DVB_FE_CUSTOMISE
select DVB_STV0288 if !DVB_FE_CUSTOMISE
select DVB_STB6000 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
---help---
This adds support for DVB/ATSC cards based on the
Conexant 2388x chip.
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index 7f5b8bfd08a..44eacfb0d0d 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -746,7 +746,6 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
return -EINVAL;
strlcpy(f->description, "MPEG", sizeof(f->description));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
}
@@ -757,7 +756,6 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_fh *fh = priv;
struct cx8802_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
@@ -776,7 +774,6 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_fh *fh = priv;
struct cx8802_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -793,7 +790,6 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_dev *dev = fh->dev;
struct cx88_core *core = dev->core;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -919,7 +915,7 @@ static int vidioc_log_status (struct file *file, void *priv)
snprintf(name, sizeof(name), "%s/2", core->name);
printk("%s/2: ============ START LOG STATUS ============\n",
core->name);
- cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL);
+ call_all(core, core, log_status);
cx2341x_log_status(&dev->params, name);
printk("%s/2: ============= END LOG STATUS =============\n",
core->name);
@@ -974,7 +970,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = core->freq;
- cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+ call_all(core, tuner, g_frequency, f);
return 0;
}
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 733ede34f93..0363971a23a 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -732,6 +732,8 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ /* Some variants use a tda9874 and so need the tvaudio module. */
+ .audio_chip = V4L2_IDENT_TVAUDIO,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -1934,6 +1936,39 @@ static const struct cx88_board cx88_boards[] = {
} },
.mpeg = CX88_MPEG_DVB,
},
+ [CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII] = {
+ .name = "Terratec Cinergy HT PCI MKII",
+ .tuner_type = TUNER_XC2028,
+ .tuner_addr = 0x61,
+ .radio_type = TUNER_XC2028,
+ .radio_addr = 0x61,
+ .input = { {
+ .type = CX88_VMUX_TELEVISION,
+ .vmux = 0,
+ .gpio0 = 0x004ff,
+ .gpio1 = 0x010ff,
+ .gpio2 = 0x00001,
+ }, {
+ .type = CX88_VMUX_COMPOSITE1,
+ .vmux = 1,
+ .gpio0 = 0x004fb,
+ .gpio1 = 0x010ef,
+ .audioroute = 1,
+ }, {
+ .type = CX88_VMUX_SVIDEO,
+ .vmux = 2,
+ .gpio0 = 0x004fb,
+ .gpio1 = 0x010ef,
+ .audioroute = 1,
+ } },
+ .radio = {
+ .type = CX88_RADIO,
+ .gpio0 = 0x004ff,
+ .gpio1 = 0x010ff,
+ .gpio2 = 0x0ff,
+ },
+ .mpeg = CX88_MPEG_DVB,
+ },
};
/* ------------------------------------------------------------------ */
@@ -2343,6 +2378,10 @@ static const struct cx88_subid cx88_subids[] = {
.subvendor = 0xb200,
.subdevice = 0x4200,
.card = CX88_BOARD_SATTRADE_ST4200,
+ }, {
+ .subvendor = 0x153b,
+ .subdevice = 0x1177,
+ .card = CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII,
},
};
@@ -2819,6 +2858,7 @@ void cx88_setup_xc3028(struct cx88_core *core, struct xc2028_ctrl *ctl)
*/
break;
case CX88_BOARD_PINNACLE_HYBRID_PCTV:
+ case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
ctl->demod = XC3028_FE_ZARLINK456;
ctl->mts = 1;
break;
@@ -2947,7 +2987,7 @@ static void cx88_card_setup(struct cx88_core *core)
tea5767_cfg.tuner = TUNER_TEA5767;
tea5767_cfg.priv = &ctl;
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
+ call_all(core, tuner, s_config, &tea5767_cfg);
break;
}
case CX88_BOARD_TEVII_S420:
@@ -2972,7 +3012,7 @@ static void cx88_card_setup(struct cx88_core *core)
tun_setup.type = core->board.radio_type;
tun_setup.addr = core->board.radio_addr;
tun_setup.tuner_callback = cx88_tuner_callback;
- cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+ call_all(core, tuner, s_type_addr, &tun_setup);
mode_mask &= ~T_RADIO;
}
@@ -2982,7 +3022,7 @@ static void cx88_card_setup(struct cx88_core *core)
tun_setup.addr = core->board.tuner_addr;
tun_setup.tuner_callback = cx88_tuner_callback;
- cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+ call_all(core, tuner, s_type_addr, &tun_setup);
}
if (core->board.tda9887_conf) {
@@ -2991,7 +3031,7 @@ static void cx88_card_setup(struct cx88_core *core)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &core->board.tda9887_conf;
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
+ call_all(core, tuner, s_config, &tda9887_cfg);
}
if (core->board.tuner_type == TUNER_XC2028) {
@@ -3007,9 +3047,9 @@ static void cx88_card_setup(struct cx88_core *core)
xc2028_cfg.priv = &ctl;
info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
ctl.fname);
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
+ call_all(core, tuner, s_config, &xc2028_cfg);
}
- cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
+ call_all(core, core, s_standby, 0);
}
/* ------------------------------------------------------------------ */
@@ -3089,6 +3129,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
int i;
core = kzalloc(sizeof(*core), GFP_KERNEL);
+ if (core == NULL)
+ return NULL;
atomic_inc(&core->refcount);
core->pci_bus = pci->bus->number;
@@ -3100,7 +3142,15 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
core->nr = nr;
sprintf(core->name, "cx88[%d]", core->nr);
+
+ strcpy(core->v4l2_dev.name, core->name);
+ if (v4l2_device_register(NULL, &core->v4l2_dev)) {
+ kfree(core);
+ return NULL;
+ }
+
if (0 != cx88_get_resources(core, pci)) {
+ v4l2_device_unregister(&core->v4l2_dev);
kfree(core);
return NULL;
}
@@ -3111,6 +3161,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
pci_resource_len(pci, 0));
core->bmmio = (u8 __iomem *)core->lmmio;
+ if (core->lmmio == NULL) {
+ kfree(core);
+ return NULL;
+ }
+
/* board config */
core->boardnr = UNSET;
if (card[core->nr] < ARRAY_SIZE(cx88_boards))
@@ -3149,8 +3204,36 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
cx88_i2c_init(core, pci);
/* load tuner module, if needed */
- if (TUNER_ABSENT != core->board.tuner_type)
- request_module("tuner");
+ if (TUNER_ABSENT != core->board.tuner_type) {
+ /* Ignore 0x6b and 0x6f on cx88 boards.
+ * FusionHDTV5 RT Gold has an ir receiver at 0x6b
+ * and an RTC at 0x6f which can get corrupted if probed. */
+ static const unsigned short tv_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e,
+ I2C_CLIENT_END
+ };
+ int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT);
+
+ /* I don't trust the radio_type as is stored in the card
+ definitions, so we just probe for it.
+ The radio_type is sometimes missing, or set to UNSET but
+ later code configures a tea5767.
+ */
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (core->board.tuner_addr == ADDR_UNSET) {
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
+ "tuner", has_demod ? tv_addrs + 4 : tv_addrs);
+ } else {
+ v4l2_i2c_new_subdev(&core->i2c_adap,
+ "tuner", "tuner", core->board.tuner_addr);
+ }
+ }
cx88_card_setup(core);
cx88_ir_init(core, pci);
diff --git a/drivers/media/video/cx88/cx88-core.c b/drivers/media/video/cx88/cx88-core.c
index b045874ad04..f2fb9f30bfc 100644
--- a/drivers/media/video/cx88/cx88-core.c
+++ b/drivers/media/video/cx88/cx88-core.c
@@ -991,7 +991,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
set_tvaudio(core);
// tell i2c chips
- cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm);
+ call_all(core, tuner, s_std, norm);
// done
return 0;
@@ -1011,7 +1011,8 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->parent = &pci->dev;
+ vfd->v4l2_dev = &core->v4l2_dev;
+ vfd->parent = &pci->dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
core->name, type, core->board.name);
@@ -1058,12 +1059,16 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
mutex_lock(&devlist);
cx88_ir_fini(core);
- if (0 == core->i2c_rc)
+ if (0 == core->i2c_rc) {
+ if (core->i2c_rtc)
+ i2c_unregister_device(core->i2c_rtc);
i2c_del_adapter(&core->i2c_adap);
+ }
list_del(&core->devlist);
iounmap(core->lmmio);
cx88_devcount--;
mutex_unlock(&devlist);
+ v4l2_device_unregister(&core->v4l2_dev);
kfree(core);
}
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index aef5297534a..4ff4d9fe035 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -241,6 +241,12 @@ static struct mt352_config dvico_fusionhdtv_dual = {
.demod_init = dvico_dual_demod_init,
};
+static struct zl10353_config cx88_terratec_cinergy_ht_pci_mkii_config = {
+ .demod_address = (0x1e >> 1),
+ .no_tuner = 1,
+ .if2 = 45600,
+};
+
#if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE))
static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe)
{
@@ -1131,6 +1137,16 @@ static int dvb_register(struct cx8802_dev *dev)
if (fe0->dvb.frontend != NULL)
fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
break;
+ case CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII:
+ fe0->dvb.frontend = dvb_attach(zl10353_attach,
+ &cx88_terratec_cinergy_ht_pci_mkii_config,
+ &core->i2c_adap);
+ if (fe0->dvb.frontend) {
+ fe0->dvb.frontend->ops.i2c_gate_ctrl = NULL;
+ if (attach_xc3028(0x61, dev) < 0)
+ goto frontend_detach;
+ }
+ break;
default:
printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n",
core->name);
@@ -1152,7 +1168,7 @@ static int dvb_register(struct cx8802_dev *dev)
fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
/* Put the analog decoder in standby to keep it quiet */
- cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
+ call_all(core, core, s_standby, 0);
/* register everything */
return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
diff --git a/drivers/media/video/cx88/cx88-i2c.c b/drivers/media/video/cx88/cx88-i2c.c
index c0ff2305d80..996b4ed5a4f 100644
--- a/drivers/media/video/cx88/cx88-i2c.c
+++ b/drivers/media/video/cx88/cx88-i2c.c
@@ -97,37 +97,6 @@ static int cx8800_bit_getsda(void *data)
/* ----------------------------------------------------------------------- */
-static int attach_inform(struct i2c_client *client)
-{
- struct cx88_core *core = i2c_get_adapdata(client->adapter);
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct cx88_core *core = i2c_get_adapdata(client->adapter);
-
- dprintk(1, "i2c detach [client=%s]\n", client->name);
- return 0;
-}
-
-void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
-{
- if (0 != core->i2c_rc)
- return;
-
- if (core->gate_ctrl)
- core->gate_ctrl(core, 1);
-
- i2c_clients_command(&core->i2c_adap, cmd, arg);
-
- if (core->gate_ctrl)
- core->gate_ctrl(core, 0);
-}
-
static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
.setsda = cx8800_bit_setsda,
.setscl = cx8800_bit_setscl,
@@ -173,20 +142,14 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
sizeof(core->i2c_algo));
- if (core->board.tuner_type != TUNER_ABSENT)
- core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
- if (core->board.mpeg & CX88_MPEG_DVB)
- core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
core->i2c_adap.dev.parent = &pci->dev;
strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
core->i2c_adap.owner = THIS_MODULE;
core->i2c_adap.id = I2C_HW_B_CX2388x;
- core->i2c_adap.client_register = attach_inform;
- core->i2c_adap.client_unregister = detach_inform;
core->i2c_algo.udelay = i2c_udelay;
core->i2c_algo.data = core;
- i2c_set_adapdata(&core->i2c_adap,core);
+ i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
core->i2c_adap.algo_data = &core->i2c_algo;
core->i2c_client.adapter = &core->i2c_adap;
strlcpy(core->i2c_client.name, "cx88xx internal", I2C_NAME_SIZE);
@@ -222,8 +185,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
/* ----------------------------------------------------------------------- */
-EXPORT_SYMBOL(cx88_call_i2c_clients);
-
/*
* Local variables:
* c-basic-offset: 8
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 8683d104de7..ec05312a9b6 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -48,8 +48,7 @@ struct cx88_IR {
/* poll external decoder */
int polling;
- struct work_struct work;
- struct timer_list timer;
+ struct delayed_work work;
u32 gpio_addr;
u32 last_gpio;
u32 mask_keycode;
@@ -143,27 +142,19 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
}
}
-static void ir_timer(unsigned long data)
-{
- struct cx88_IR *ir = (struct cx88_IR *)data;
-
- schedule_work(&ir->work);
-}
-
static void cx88_ir_work(struct work_struct *work)
{
- struct cx88_IR *ir = container_of(work, struct cx88_IR, work);
+ struct cx88_IR *ir = container_of(work, struct cx88_IR, work.work);
cx88_ir_handle_key(ir);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
void cx88_ir_start(struct cx88_core *core, struct cx88_IR *ir)
{
if (ir->polling) {
- setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
- INIT_WORK(&ir->work, cx88_ir_work);
- schedule_work(&ir->work);
+ INIT_DELAYED_WORK(&ir->work, cx88_ir_work);
+ schedule_delayed_work(&ir->work, 0);
}
if (ir->sampling) {
core->pci_irqmask |= PCI_INT_IR_SMPINT;
@@ -179,10 +170,8 @@ void cx88_ir_stop(struct cx88_core *core, struct cx88_IR *ir)
core->pci_irqmask &= ~PCI_INT_IR_SMPINT;
}
- if (ir->polling) {
- del_timer_sync(&ir->timer);
- flush_scheduled_work();
- }
+ if (ir->polling)
+ cancel_delayed_work_sync(&ir->work);
}
/* ---------------------------------------------------------------------- */
@@ -226,6 +215,8 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
case CX88_BOARD_HAUPPAUGE_HVR3000:
case CX88_BOARD_HAUPPAUGE_HVR4000:
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+ case CX88_BOARD_PCHDTV_HD3000:
+ case CX88_BOARD_PCHDTV_HD5500:
ir_codes = ir_codes_hauppauge_new;
ir_type = IR_TYPE_RC5;
ir->sampling = 1;
@@ -466,6 +457,8 @@ void cx88_ir_irq(struct cx88_core *core)
case CX88_BOARD_HAUPPAUGE_HVR3000:
case CX88_BOARD_HAUPPAUGE_HVR4000:
case CX88_BOARD_HAUPPAUGE_HVR4000LITE:
+ case CX88_BOARD_PCHDTV_HD3000:
+ case CX88_BOARD_PCHDTV_HD5500:
ircode = ir_decode_biphase(ir->samples, ir->scount, 5, 7);
ir_dprintk("biphase decoded: %x\n", ircode);
/*
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 791e69d804f..434237af518 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -41,11 +41,6 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
-
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -298,6 +293,7 @@ static struct cx88_ctrl cx8800_ctls[] = {
};
static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
+/* Must be sorted from low to high control ID! */
const u32 cx88_user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -435,8 +431,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
struct v4l2_routing route;
route.input = INPUT(input).audioroute;
- cx88_call_i2c_clients(core,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ call_all(core, audio, s_routing, &route);
}
/* cx2388's C-ADC is connected to the tuner only.
When used with S-Video, that ADC is busy dealing with
@@ -831,8 +826,7 @@ static int video_open(struct file *file)
struct v4l2_routing route;
route.input = core->board.radio.audioroute;
- cx88_call_i2c_clients(core,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ call_all(core, audio, s_routing, &route);
}
/* "I2S ADC mode" */
core->tvaudio = WW_I2SADC;
@@ -843,7 +837,7 @@ static int video_open(struct file *file)
cx88_set_tvaudio(core);
cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
}
- cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
+ call_all(core, tuner, s_radio);
}
unlock_kernel();
@@ -937,7 +931,7 @@ static int video_release(struct file *file)
kfree(fh);
if(atomic_dec_and_test(&dev->core->users))
- cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ call_all(dev->core, core, s_standby, 0);
return 0;
}
@@ -1276,15 +1270,12 @@ int cx88_enum_input (struct cx88_core *core,struct v4l2_input *i)
[ CX88_VMUX_DVB ] = "DVB",
[ CX88_VMUX_DEBUG ] = "for debug only",
};
- unsigned int n;
+ unsigned int n = i->index;
- n = i->index;
if (n >= 4)
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 ((CX88_VMUX_TELEVISION == INPUT(n).type) ||
@@ -1402,7 +1393,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = core->freq;
- cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+ call_all(core, tuner, g_frequency, f);
return 0;
}
@@ -1418,7 +1409,7 @@ int cx88_set_freq (struct cx88_core *core,
mutex_lock(&core->lock);
core->freq = f->frequency;
cx88_newstation(core);
- cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
+ call_all(core, tuner, s_frequency, f);
/* When changing channels it is required to reset TVAUDIO */
msleep (10);
@@ -1500,7 +1491,7 @@ static int radio_g_tuner (struct file *file, void *priv,
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
+ call_all(core, tuner, g_tuner, t);
return 0;
}
@@ -1520,7 +1511,6 @@ static int radio_g_audio (struct file *file, void *priv, struct v4l2_audio *a)
if (unlikely(a->index))
return -EINVAL;
- memset(a,0,sizeof(*a));
strcpy(a->name,"Radio");
return 0;
}
@@ -1535,7 +1525,7 @@ static int radio_s_tuner (struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t);
+ call_all(core, tuner, s_tuner, t);
return 0;
}
@@ -1892,12 +1882,30 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
/* load and configure helper modules */
if (core->board.audio_chip == V4L2_IDENT_WM8775)
- request_module("wm8775");
+ v4l2_i2c_new_subdev(&core->i2c_adap,
+ "wm8775", "wm8775", 0x36 >> 1);
+
+ if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
+ /* This probes for a tda9874 as is used on some
+ Pixelview Ultra boards. */
+ static const unsigned short i2c_addr[] = {
+ 0xb0 >> 1, I2C_CLIENT_END
+ };
+
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap,
+ "tvaudio", "tvaudio", i2c_addr);
+ }
switch (core->boardnr) {
case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
- case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
+ case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: {
+ static struct i2c_board_info rtc_info = {
+ I2C_BOARD_INFO("isl1208", 0x6f)
+ };
+
request_module("rtc-isl1208");
+ core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info);
+ }
/* break intentionally omitted */
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
request_module("ir-kbd-i2c");
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index 6025fdd2334..9a43fdf20fa 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -25,7 +25,7 @@
#include <linux/videodev2.h>
#include <linux/kdev_t.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
@@ -231,6 +231,7 @@ extern struct sram_channel cx88_sram_channels[];
#define CX88_BOARD_SATTRADE_ST4200 76
#define CX88_BOARD_TBS_8910 77
#define CX88_BOARD_PROF_6200 78
+#define CX88_BOARD_TERRATEC_CINERGY_HT_PCI_MKII 79
enum cx88_itype {
CX88_VMUX_COMPOSITE1 = 1,
@@ -302,7 +303,6 @@ struct cx88_dmaqueue {
struct btcx_riscmem stopper;
u32 count;
};
-struct cx88_core;
struct cx88_core {
struct list_head devlist;
@@ -327,6 +327,8 @@ struct cx88_core {
u32 i2c_state, i2c_rc;
/* config info -- analog */
+ struct v4l2_device v4l2_dev;
+ struct i2c_client *i2c_rtc;
unsigned int boardnr;
struct cx88_board board;
@@ -365,6 +367,22 @@ struct cx88_core {
int active_fe_id;
};
+static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
+}
+
+#define call_all(core, o, f, args...) \
+ do { \
+ if (!core->i2c_rc) { \
+ if (core->gate_ctrl) \
+ core->gate_ctrl(core, 1); \
+ v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \
+ if (core->gate_ctrl) \
+ core->gate_ctrl(core, 0); \
+ } \
+ } while (0)
+
struct cx8800_dev;
struct cx8802_dev;
@@ -610,8 +628,6 @@ extern struct videobuf_queue_ops cx8800_vbi_qops;
/* cx88-i2c.c */
extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
-extern void cx88_call_i2c_clients(struct cx88_core *core,
- unsigned int cmd, void *arg);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/dabusb.c b/drivers/media/video/dabusb.c
index 298810d5262..ba3709bec3f 100644
--- a/drivers/media/video/dabusb.c
+++ b/drivers/media/video/dabusb.c
@@ -189,17 +189,20 @@ static void dabusb_iso_complete (struct urb *purb)
dst += len;
}
else
- err("dabusb_iso_complete: invalid len %d", len);
+ dev_err(&purb->dev->dev,
+ "dabusb_iso_complete: invalid len %d\n", len);
}
else
dev_warn(&purb->dev->dev, "dabusb_iso_complete: corrupted packet status: %d\n", purb->iso_frame_desc[i].status);
if (dst != purb->actual_length)
- err("dst!=purb->actual_length:%d!=%d", dst, purb->actual_length);
+ dev_err(&purb->dev->dev,
+ "dst!=purb->actual_length:%d!=%d\n",
+ dst, purb->actual_length);
}
if (atomic_dec_and_test (&s->pending_io) && !s->remove_pending && s->state != _stopped) {
s->overruns++;
- err("overrun (%d)", s->overruns);
+ dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
}
wake_up (&s->wait);
}
@@ -220,13 +223,14 @@ static int dabusb_alloc_buffers (pdabusb_t s)
while (transfer_len < (s->total_buffer_size << 10)) {
b = kzalloc(sizeof (buff_t), GFP_KERNEL);
if (!b) {
- err("kzalloc(sizeof(buff_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kzalloc(sizeof(buff_t))==NULL\n");
goto err;
}
b->s = s;
b->purb = usb_alloc_urb(packets, GFP_KERNEL);
if (!b->purb) {
- err("usb_alloc_urb == NULL");
+ dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
kfree (b);
goto err;
}
@@ -235,7 +239,8 @@ static int dabusb_alloc_buffers (pdabusb_t s)
if (!b->purb->transfer_buffer) {
kfree (b->purb);
kfree (b);
- err("kmalloc(%d)==NULL", transfer_buffer_length);
+ dev_err(&s->usbdev->dev,
+ "kmalloc(%d)==NULL\n", transfer_buffer_length);
goto err;
}
@@ -279,10 +284,11 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
ret=usb_bulk_msg(s->usbdev, pipe, pb->data, pb->size, &actual_length, 100);
if(ret<0) {
- err("dabusb: usb_bulk_msg failed(%d)",ret);
+ dev_err(&s->usbdev->dev,
+ "usb_bulk_msg failed(%d)\n", ret);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
@@ -291,7 +297,7 @@ static int dabusb_bulk (pdabusb_t s, pbulk_transfer_t pb)
if( ret == -EPIPE ) {
dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
if(usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
- err("request failed");
+ dev_err(&s->usbdev->dev, "request failed\n");
}
pb->size = actual_length;
@@ -305,7 +311,8 @@ static int dabusb_writemem (pdabusb_t s, int pos, const unsigned char *data,
unsigned char *transfer_buffer = kmalloc (len, GFP_KERNEL);
if (!transfer_buffer) {
- err("dabusb_writemem: kmalloc(%d) failed.", len);
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem: kmalloc(%d) failed.\n", len);
return -ENOMEM;
}
@@ -327,13 +334,14 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
{
int ret;
const struct ihex_binrec *rec;
- const struct firmware *fw;
+ const struct firmware *uninitialized_var(fw);
dbg("Enter dabusb_loadmem (internal)");
ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/firmware.fw\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
goto out;
}
ret = dabusb_8051_reset (s, 1);
@@ -346,9 +354,10 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
be16_to_cpu(rec->len));
if (ret < 0) {
- err("dabusb_writemem failed (%d %04X %p %d)", ret,
- be32_to_cpu(rec->addr), rec->data,
- be16_to_cpu(rec->len));
+ dev_err(&s->usbdev->dev,
+ "dabusb_writemem failed (%d %04X %p %d)\n",
+ ret, be32_to_cpu(rec->addr),
+ rec->data, be16_to_cpu(rec->len));
break;
}
}
@@ -396,13 +405,15 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
dbg("Enter dabusb_fpga_download (internal)");
if (!b) {
- err("kmalloc(sizeof(bulk_transfer_t))==NULL");
+ dev_err(&s->usbdev->dev,
+ "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
return -ENOMEM;
}
ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
if (ret) {
- err("Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
+ dev_err(&s->usbdev->dev,
+ "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
kfree(b);
return ret;
}
@@ -425,7 +436,7 @@ static int dabusb_fpga_download (pdabusb_t s, const char *fname)
memcpy (b->data + 4, fw->data + 74 + n, 60);
ret = dabusb_bulk (s, b);
if (ret < 0) {
- err("dabusb_bulk failed.");
+ dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
break;
}
mdelay (1);
@@ -478,9 +489,11 @@ static int dabusb_startrek (pdabusb_t s)
ret = usb_submit_urb (end->purb, GFP_KERNEL);
if (ret) {
- err("usb_submit_urb returned:%d", ret);
+ dev_err(&s->usbdev->dev,
+ "usb_submit_urb returned:%d\n", ret);
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("startrek: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "startrek: dabusb_add_buf_tail failed\n");
break;
}
else
@@ -523,7 +536,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
spin_unlock_irqrestore(&s->lock, flags);
- err("error: rec_buf_list is empty");
+ dev_err(&s->usbdev->dev,
+ "error: rec_buf_list is empty\n");
goto err;
}
@@ -552,7 +566,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (list_empty (&s->rec_buff_list)) {
spin_unlock_irqrestore(&s->lock, flags);
- err("error: still no buffer available.");
+ dev_err(&s->usbdev->dev,
+ "error: still no buffer available.\n");
goto err;
}
spin_unlock_irqrestore(&s->lock, flags);
@@ -573,7 +588,7 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
dbg("copy_to_user:%p %p %d",buf, purb->transfer_buffer + s->readptr, cnt);
if (copy_to_user (buf, purb->transfer_buffer + s->readptr, cnt)) {
- err("read: copy_to_user failed");
+ dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
if (!ret)
ret = -EFAULT;
goto err;
@@ -587,7 +602,8 @@ static ssize_t dabusb_read (struct file *file, char __user *buf, size_t count, l
if (s->readptr == purb->actual_length) {
// finished, take next buffer
if (dabusb_add_buf_tail (s, &s->free_buff_list, &s->rec_buff_list))
- err("read: dabusb_add_buf_tail failed");
+ dev_err(&s->usbdev->dev,
+ "read: dabusb_add_buf_tail failed\n");
s->readptr = 0;
}
}
@@ -623,7 +639,7 @@ static int dabusb_open (struct inode *inode, struct file *file)
}
if (usb_set_interface (s->usbdev, _DABUSB_IF, 1) < 0) {
mutex_unlock(&s->mutex);
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
return -EINVAL;
}
s->opened = 1;
@@ -648,7 +664,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
if (!s->remove_pending) {
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0)
- err("set_interface failed");
+ dev_err(&s->usbdev->dev, "set_interface failed\n");
}
else
wake_up (&s->remove_ok);
@@ -657,7 +673,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
return 0;
}
-static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
{
pdabusb_t s = (pdabusb_t) file->private_data;
pbulk_transfer_t pbulk;
@@ -666,13 +682,17 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
dbg("dabusb_ioctl");
- if (s->remove_pending)
+ lock_kernel();
+ if (s->remove_pending) {
+ unlock_kernel();
return -EIO;
+ }
mutex_lock(&s->mutex);
if (!s->usbdev) {
mutex_unlock(&s->mutex);
+ unlock_kernel();
return -EIO;
}
@@ -713,6 +733,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
break;
}
mutex_unlock(&s->mutex);
+ unlock_kernel();
return ret;
}
@@ -721,7 +742,7 @@ static const struct file_operations dabusb_fops =
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = dabusb_read,
- .ioctl = dabusb_ioctl,
+ .unlocked_ioctl = dabusb_ioctl,
.open = dabusb_open,
.release = dabusb_release,
};
@@ -764,7 +785,7 @@ static int dabusb_probe (struct usb_interface *intf,
s->devnum = intf->minor;
if (usb_reset_configuration (usbdev) < 0) {
- err("reset_configuration failed");
+ dev_err(&intf->dev, "reset_configuration failed\n");
goto reject;
}
if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
@@ -775,7 +796,7 @@ static int dabusb_probe (struct usb_interface *intf,
dabusb_fpga_download (s, NULL);
if (usb_set_interface (s->usbdev, _DABUSB_IF, 0) < 0) {
- err("set_interface failed");
+ dev_err(&intf->dev, "set_interface failed\n");
goto reject;
}
}
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c
index f132e31f6ed..0131322475b 100644
--- a/drivers/media/video/em28xx/em28xx-audio.c
+++ b/drivers/media/video/em28xx/em28xx-audio.c
@@ -56,7 +56,7 @@ MODULE_PARM_DESC(debug, "activates debug info");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
-static int em28xx_isoc_audio_deinit(struct em28xx *dev)
+static int em28xx_deinit_isoc_audio(struct em28xx *dev)
{
int i;
@@ -66,6 +66,7 @@ static int em28xx_isoc_audio_deinit(struct em28xx *dev)
usb_kill_urb(dev->adev.urb[i]);
else
usb_unlink_urb(dev->adev.urb[i]);
+
usb_free_urb(dev->adev.urb[i]);
dev->adev.urb[i] = NULL;
@@ -87,6 +88,20 @@ static void em28xx_audio_isocirq(struct urb *urb)
unsigned int stride;
struct snd_pcm_substream *substream;
struct snd_pcm_runtime *runtime;
+
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ dprintk("urb completition error %d.\n", urb->status);
+ break;
+ }
+
if (dev->adev.capture_pcm_substream) {
substream = dev->adev.capture_pcm_substream;
runtime = substream->runtime;
@@ -137,9 +152,6 @@ static void em28xx_audio_isocirq(struct urb *urb)
}
urb->status = 0;
- if (dev->adev.shutdown)
- return;
-
status = usb_submit_urb(urb, GFP_ATOMIC);
if (status < 0) {
em28xx_errdev("resubmit of audio urb failed (error=%i)\n",
@@ -197,8 +209,7 @@ static int em28xx_init_audio_isoc(struct em28xx *dev)
for (i = 0; i < EM28XX_AUDIO_BUFS; i++) {
errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC);
if (errCode) {
- em28xx_isoc_audio_deinit(dev);
-
+ em28xx_deinit_isoc_audio(dev);
return errCode;
}
}
@@ -213,14 +224,16 @@ static int em28xx_cmd(struct em28xx *dev, int cmd, int arg)
switch (cmd) {
case EM28XX_CAPTURE_STREAM_EN:
- if (dev->adev.capture_stream == STREAM_OFF && arg == 1) {
+ if (dev->adev.capture_stream == STREAM_OFF &&
+ arg == EM28XX_START_AUDIO) {
dev->adev.capture_stream = STREAM_ON;
em28xx_init_audio_isoc(dev);
- } else if (dev->adev.capture_stream == STREAM_ON && arg == 0) {
+ } else if (dev->adev.capture_stream == STREAM_ON &&
+ arg == EM28XX_STOP_AUDIO) {
dev->adev.capture_stream = STREAM_OFF;
- em28xx_isoc_audio_deinit(dev);
+ em28xx_deinit_isoc_audio(dev);
} else {
- printk(KERN_ERR "An underrun very likely occurred. "
+ em28xx_errdev("An underrun very likely occurred. "
"Ignoring it.\n");
}
return 0;
@@ -234,7 +247,7 @@ static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs,
{
struct snd_pcm_runtime *runtime = subs->runtime;
- dprintk("Alocating vbuffer\n");
+ dprintk("Allocating vbuffer\n");
if (runtime->dma_area) {
if (runtime->dma_bytes > size)
return 0;
@@ -302,7 +315,9 @@ static int snd_em28xx_capture_open(struct snd_pcm_substream *substream)
dprintk("changing alternate number to 7\n");
}
+ mutex_lock(&dev->lock);
dev->adev.users++;
+ mutex_unlock(&dev->lock);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
dev->adev.capture_pcm_substream = substream;
@@ -317,22 +332,15 @@ err:
static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream)
{
struct em28xx *dev = snd_pcm_substream_chip(substream);
- dev->adev.users--;
dprintk("closing device\n");
dev->mute = 1;
mutex_lock(&dev->lock);
+ dev->adev.users--;
em28xx_audio_analog_set(dev);
mutex_unlock(&dev->lock);
- if (dev->adev.users == 0 && dev->adev.shutdown == 1) {
- dprintk("audio users: %d\n", dev->adev.users);
- dprintk("disabling audio stream!\n");
- dev->adev.shutdown = 0;
- dprintk("released lock\n");
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
- }
return 0;
}
@@ -363,7 +371,7 @@ static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream)
dprintk("Stop capture, if needed\n");
if (dev->adev.capture_stream == STREAM_ON)
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 0);
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
return 0;
}
@@ -377,33 +385,40 @@ static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream,
int cmd)
{
struct em28xx *dev = snd_pcm_substream_chip(substream);
+ int retval;
- dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START)?
- "start": "stop");
+ dprintk("Should %s capture\n", (cmd == SNDRV_PCM_TRIGGER_START) ?
+ "start" : "stop");
+
+ spin_lock(&dev->adev.slock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, 1);
- return 0;
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_START_AUDIO);
+ retval = 0;
+ break;
case SNDRV_PCM_TRIGGER_STOP:
- dev->adev.shutdown = 1;
- return 0;
+ em28xx_cmd(dev, EM28XX_CAPTURE_STREAM_EN, EM28XX_STOP_AUDIO);
+ retval = 0;
+ break;
default:
- return -EINVAL;
+ retval = -EINVAL;
}
+
+ spin_unlock(&dev->adev.slock);
+ return retval;
}
static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream
*substream)
{
- unsigned long flags;
-
+ unsigned long flags;
struct em28xx *dev;
snd_pcm_uframes_t hwptr_done;
dev = snd_pcm_substream_chip(substream);
- spin_lock_irqsave(&dev->adev.slock, flags);
+ spin_lock_irqsave(&dev->adev.slock, flags);
hwptr_done = dev->adev.hwptr_done_capture;
- spin_unlock_irqrestore(&dev->adev.slock, flags);
+ spin_unlock_irqrestore(&dev->adev.slock, flags);
return hwptr_done;
}
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 3b3ca3f46d5..0f48c0ff5ac 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -122,6 +122,22 @@ static struct em28xx_reg_seq default_tuner_gpio[] = {
{ -1, -1, -1, -1},
};
+/* Mute/unmute */
+static struct em28xx_reg_seq compro_unmute_tv_gpio[] = {
+ {EM28XX_R08_GPIO, 5, 7, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq compro_unmute_svid_gpio[] = {
+ {EM28XX_R08_GPIO, 4, 7, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq compro_mute_gpio[] = {
+ {EM28XX_R08_GPIO, 6, 7, 10},
+ { -1, -1, -1, -1},
+};
+
/*
* Board definitions
*/
@@ -183,6 +199,25 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_LINE_IN,
} },
},
+ [EM2820_BOARD_GADMEI_TVR200] = {
+ .name = "Gadmei TVR200",
+ .tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_SAA711X,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = SAA7115_COMPOSITE2,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
[EM2820_BOARD_TERRATEC_CINERGY_250] = {
.name = "Terratec Cinergy 250 USB",
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
@@ -225,7 +260,7 @@ struct em28xx_board em28xx_boards[] = {
.name = "Hauppauge WinTV USB 2",
.tuner_type = TUNER_PHILIPS_FM1236_MK3,
.tda9887_conf = TDA9887_PRESENT |
- TDA9887_PORT1_ACTIVE|
+ TDA9887_PORT1_ACTIVE |
TDA9887_PORT2_ACTIVE,
.decoder = EM28XX_TVP5150,
.has_msp34xx = 1,
@@ -350,26 +385,6 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_VIDEO,
} },
},
- [EM2821_BOARD_PROLINK_PLAYTV_USB2] = {
- .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0",
- .valid = EM28XX_BOARD_NOT_VALIDATED,
- .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */
- .tda9887_conf = TDA9887_PRESENT, /* unknown? */
- .decoder = EM28XX_SAA711X,
- .input = { {
- .type = EM28XX_VMUX_TELEVISION,
- .vmux = SAA7115_COMPOSITE2,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_COMPOSITE1,
- .vmux = SAA7115_COMPOSITE0,
- .amux = EM28XX_AMUX_LINE_IN,
- }, {
- .type = EM28XX_VMUX_SVIDEO,
- .vmux = SAA7115_SVIDEO3,
- .amux = EM28XX_AMUX_LINE_IN,
- } },
- },
[EM2821_BOARD_SUPERCOMP_USB_2] = {
.name = "Supercomp USB 2.0 TV",
.valid = EM28XX_BOARD_NOT_VALIDATED,
@@ -498,7 +513,7 @@ struct em28xx_board em28xx_boards[] = {
},
[EM2861_BOARD_YAKUMO_MOVIE_MIXER] = {
.name = "Yakumo MovieMixer",
- .tuner_type = TUNER_ABSENT, /* Capture only device */
+ .tuner_type = TUNER_ABSENT, /* Capture only device */
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -604,6 +619,7 @@ struct em28xx_board em28xx_boards[] = {
.mts_firmware = 1,
.has_dvb = 1,
.dvb_gpio = hauppauge_wintv_hvr_900_digital,
+ .ir_codes = ir_codes_hauppauge_new,
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -628,6 +644,7 @@ struct em28xx_board em28xx_boards[] = {
.tuner_type = TUNER_XC2028,
.tuner_gpio = default_tuner_gpio,
.mts_firmware = 1,
+ .ir_codes = ir_codes_hauppauge_new,
.decoder = EM28XX_TVP5150,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
@@ -842,11 +859,11 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2800_BOARD_GRABBEEX_USB2800] = {
- .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
- .is_em2800 = 1,
- .decoder = EM28XX_SAA711X,
- .tuner_type = TUNER_ABSENT, /* capture only board */
- .input = { {
+ .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder",
+ .is_em2800 = 1,
+ .decoder = EM28XX_SAA711X,
+ .tuner_type = TUNER_ABSENT, /* capture only board */
+ .input = { {
.type = EM28XX_VMUX_COMPOSITE1,
.vmux = SAA7115_COMPOSITE0,
.amux = EM28XX_AMUX_LINE_IN,
@@ -897,7 +914,7 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2820_BOARD_PINNACLE_DVC_90] = {
- .name = "Pinnacle Dazzle DVC 90/DVC 100",
+ .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker",
.tuner_type = TUNER_ABSENT, /* capture only board */
.decoder = EM28XX_SAA711X,
.input = { {
@@ -952,7 +969,7 @@ struct em28xx_board em28xx_boards[] = {
} },
},
[EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
- .name = "Pixelview Prolink PlayTV USB 2.0",
+ .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0",
.has_snapshot_button = 1,
.tda9887_conf = TDA9887_PRESENT,
.tuner_type = TUNER_YMEC_TVF_5533MF,
@@ -1198,7 +1215,9 @@ struct em28xx_board em28xx_boards[] = {
.has_dvb = 1,
.dvb_gpio = kworld_330u_digital,
.xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
- .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_EEPROM_ON_BOARD | EM28XX_I2C_EEPROM_KEY_VALID,
+ .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE |
+ EM28XX_I2C_EEPROM_ON_BOARD |
+ EM28XX_I2C_EEPROM_KEY_VALID,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
@@ -1223,21 +1242,88 @@ struct em28xx_board em28xx_boards[] = {
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
.tda9887_conf = TDA9887_PRESENT,
.decoder = EM28XX_TVP5150,
+ .adecoder = EM28XX_TVAUDIO,
+ .mute_gpio = compro_mute_gpio,
.input = { {
.type = EM28XX_VMUX_TELEVISION,
.vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+ .gpio = compro_unmute_tv_gpio,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ .gpio = compro_unmute_svid_gpio,
+ } },
+ },
+ [EM2860_BOARD_KAIOMY_TVNPC_U2] = {
+ .name = "Kaiomy TVnPC U2",
+ .vchannels = 3,
+ .tuner_type = TUNER_XC2028,
+ .tuner_addr = 0x61,
+ .mts_firmware = 1,
+ .decoder = EM28XX_TVP5150,
+ .tuner_gpio = default_tuner_gpio,
+ .ir_codes = ir_codes_kaiomy,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+
+ }, {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
.amux = EM28XX_AMUX_LINE_IN,
}, {
.type = EM28XX_VMUX_SVIDEO,
.vmux = TVP5150_SVIDEO,
.amux = EM28XX_AMUX_LINE_IN,
} },
+ .radio = {
+ .type = EM28XX_RADIO,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }
+ },
+ [EM2860_BOARD_EASYCAP] = {
+ .name = "Easy Cap Capture DC-60",
+ .vchannels = 2,
+ .tuner_type = TUNER_ABSENT,
+ .decoder = EM28XX_SAA711X,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = EM28XX_AMUX_LINE_IN,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = EM28XX_AMUX_LINE_IN,
+ } },
+ },
+ [EM2820_BOARD_IODATA_GVMVP_SZ] = {
+ .name = "IO-DATA GV-MVP/SZ",
+ .tuner_type = TUNER_PHILIPS_FM1236_MK3,
+ .tuner_gpio = default_tuner_gpio,
+ .tda9887_conf = TDA9887_PRESENT,
+ .decoder = EM28XX_TVP5150,
+ .input = { {
+ .type = EM28XX_VMUX_TELEVISION,
+ .vmux = TVP5150_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO,
+ }, { /* Composite has not been tested yet */
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = EM28XX_AMUX_VIDEO,
+ }, { /* S-video has not been tested yet */
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AMUX_VIDEO,
+ } },
},
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
/* table of devices that work with this driver */
-struct usb_device_id em28xx_id_table [] = {
+struct usb_device_id em28xx_id_table[] = {
{ USB_DEVICE(0xeb1a, 0x2750),
.driver_info = EM2750_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0x2751),
@@ -1260,6 +1346,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2820_BOARD_UNKNOWN },
{ USB_DEVICE(0xeb1a, 0xe300),
.driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
+ { USB_DEVICE(0xeb1a, 0xe303),
+ .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 },
{ USB_DEVICE(0xeb1a, 0xe305),
.driver_info = EM2880_BOARD_KWORLD_DVB_305U },
{ USB_DEVICE(0xeb1a, 0xe310),
@@ -1278,6 +1366,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2800_BOARD_GRABBEEX_USB2800 },
{ USB_DEVICE(0xeb1a, 0xe357),
.driver_info = EM2870_BOARD_KWORLD_355U },
+ { USB_DEVICE(0x1b80, 0xe302),
+ .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */
{ USB_DEVICE(0x0ccd, 0x0036),
.driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
{ USB_DEVICE(0x0ccd, 0x004c),
@@ -1330,6 +1420,8 @@ struct usb_device_id em28xx_id_table [] = {
.driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII },
{ USB_DEVICE(0x093b, 0xa005),
.driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U },
+ { USB_DEVICE(0x04bb, 0x0515),
+ .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ },
{ },
};
MODULE_DEVICE_TABLE(usb, em28xx_id_table);
@@ -1337,7 +1429,7 @@ MODULE_DEVICE_TABLE(usb, em28xx_id_table);
/*
* EEPROM hash table for devices with generic USB IDs
*/
-static struct em28xx_hash_table em28xx_eeprom_hash [] = {
+static struct em28xx_hash_table em28xx_eeprom_hash[] = {
/* P/N: SA 60002070465 Tuner: TVF7533-MF */
{0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
{0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF},
@@ -1349,6 +1441,7 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
{0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
{0x1ba50080, EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA, TUNER_ABSENT},
+ {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
};
int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
@@ -1368,7 +1461,7 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
}
EXPORT_SYMBOL_GPL(em28xx_tuner_callback);
-static void inline em28xx_set_model(struct em28xx *dev)
+static inline void em28xx_set_model(struct em28xx *dev)
{
memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board));
@@ -1504,6 +1597,34 @@ void em28xx_pre_card_setup(struct em28xx *dev)
/* enables audio for that devices */
em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
break;
+
+ case EM2860_BOARD_KAIOMY_TVNPC_U2:
+ em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1);
+ em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1);
+ em28xx_write_regs(dev, 0x0d, "\x42", 1);
+ em28xx_write_regs(dev, 0x08, "\xfd", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\xff", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x7f", 1);
+ msleep(10);
+ em28xx_write_regs(dev, 0x08, "\x6b", 1);
+
+ break;
+ case EM2860_BOARD_EASYCAP:
+ em28xx_write_regs(dev, 0x08, "\xf8", 1);
+ break;
+
+ case EM2820_BOARD_IODATA_GVMVP_SZ:
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff);
+ msleep(70);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7);
+ msleep(10);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe);
+ msleep(70);
+ em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd);
+ msleep(70);
+ break;
}
em28xx_gpio_set(dev, dev->board.tuner_gpio);
@@ -1610,7 +1731,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("If the board were missdetected, "
"please email this log to:\n");
em28xx_errdev("\tV4L Mailing List "
- " <video4linux-list@redhat.com>\n");
+ " <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board detected as %s\n",
em28xx_boards[dev->model].name);
@@ -1642,7 +1763,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("If the board were missdetected, "
"please email this log to:\n");
em28xx_errdev("\tV4L Mailing List "
- " <video4linux-list@redhat.com>\n");
+ " <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board detected as %s\n",
em28xx_boards[dev->model].name);
@@ -1655,7 +1776,7 @@ static int em28xx_hint_board(struct em28xx *dev)
em28xx_errdev("You may try to use card=<n> insmod option to "
"workaround that.\n");
em28xx_errdev("Please send an email with this log to:\n");
- em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
+ em28xx_errdev("\tV4L Mailing List <linux-media@vger.kernel.org>\n");
em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
@@ -1800,6 +1921,8 @@ void em28xx_card_setup(struct em28xx *dev)
request_module("tvp5150");
if (dev->board.tuner_type != TUNER_ABSENT)
request_module("tuner");
+ if (dev->board.adecoder == EM28XX_TVAUDIO)
+ request_module("tvaudio");
#endif
em28xx_config_tuner(dev);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 94fb1b639a2..8f1999ca480 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -33,8 +33,8 @@
/* #define ENABLE_DEBUG_ISOC_FRAMES */
static unsigned int core_debug;
-module_param(core_debug,int,0644);
-MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
+module_param(core_debug, int, 0644);
+MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
#define em28xx_coredbg(fmt, arg...) do {\
if (core_debug) \
@@ -42,8 +42,8 @@ MODULE_PARM_DESC(core_debug,"enable debug messages [core]");
dev->name, __func__ , ##arg); } while (0)
static unsigned int reg_debug;
-module_param(reg_debug,int,0644);
-MODULE_PARM_DESC(reg_debug,"enable debug messages [URB reg]");
+module_param(reg_debug, int, 0644);
+MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]");
#define em28xx_regdbg(fmt, arg...) do {\
if (reg_debug) \
@@ -77,7 +77,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg,
return -EINVAL;
if (reg_debug) {
- printk( KERN_DEBUG "(pipe 0x%08x): "
+ printk(KERN_DEBUG "(pipe 0x%08x): "
"IN: %02x %02x %02x %02x %02x %02x %02x %02x ",
pipe,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -154,7 +154,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf,
if (reg_debug) {
int byte;
- printk( KERN_DEBUG "(pipe 0x%08x): "
+ printk(KERN_DEBUG "(pipe 0x%08x): "
"OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>",
pipe,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
@@ -378,6 +378,11 @@ static int em28xx_set_audio_source(struct em28xx *dev)
}
}
+ if (dev->board.mute_gpio && dev->mute)
+ em28xx_gpio_set(dev, dev->board.mute_gpio);
+ else
+ em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio);
+
ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0);
if (ret < 0)
return ret;
@@ -424,7 +429,7 @@ int em28xx_audio_analog_set(struct em28xx *dev)
xclk = dev->board.xclk & 0x7f;
if (!dev->mute)
- xclk |= 0x80;
+ xclk |= EM28XX_XCLK_AUDIO_UNMUTE;
ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk);
if (ret < 0)
@@ -462,7 +467,8 @@ int em28xx_audio_analog_set(struct em28xx *dev)
if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) {
int sel = ac97_return_record_select(dev->ctl_aoutput);
- /* Use the same input for both left and right channels */
+ /* Use the same input for both left and right
+ channels */
sel |= (sel << 8);
em28xx_write_ac97(dev, AC97_RECORD_SELECT, sel);
@@ -698,7 +704,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v)
em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2);
/* it seems that both H and V scalers must be active
to work correctly */
- mode = (h || v)? 0x30: 0x00;
+ mode = (h || v) ? 0x30 : 0x00;
}
return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30);
}
@@ -827,6 +833,19 @@ static void em28xx_irq_callback(struct urb *urb)
struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
int rc, i;
+ switch (urb->status) {
+ case 0: /* success */
+ case -ETIMEDOUT: /* NAK */
+ break;
+ case -ECONNRESET: /* kill */
+ case -ENOENT:
+ case -ESHUTDOWN:
+ return;
+ default: /* error */
+ em28xx_isocdbg("urb completition error %d.\n", urb->status);
+ break;
+ }
+
/* Copy data from URB */
spin_lock(&dev->slock);
rc = dev->isoc_ctl.isoc_copy(dev, urb);
@@ -945,7 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
em28xx_err("unable to allocate %i bytes for transfer"
" buffer %i%s\n",
sb_size, i,
- in_interrupt()?" while in int":"");
+ in_interrupt() ? " while in int" : "");
em28xx_uninit_isoc(dev);
return -ENOMEM;
}
@@ -963,7 +982,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
em28xx_irq_callback, dma_q, 1);
urb->number_of_packets = max_packets;
- urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
k = 0;
for (j = 0; j < max_packets; j++) {
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index 9ad8527b3fd..fcd25511209 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -29,9 +29,6 @@
#include "lgdt330x.h"
#include "zl10353.h"
#include "s5h1409.h"
-#ifdef EM28XX_DRX397XD_SUPPORT
-#include "drx397xD.h"
-#endif
MODULE_DESCRIPTION("driver for em28xx based DVB cards");
MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index d69f0efcc9a..02c12fe6361 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -402,10 +402,12 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len)
dev->name);
break;
case 2:
- printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name);
+ printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n",
+ dev->name);
break;
case 3:
- printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name);
+ printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n",
+ dev->name);
break;
}
@@ -508,12 +510,17 @@ static int attach_inform(struct i2c_client *client)
dprintk1(1, "attach_inform: tvp5150 detected.\n");
break;
+ case 0xb0:
+ dprintk1(1, "attach_inform: tda9874 detected\n");
+ break;
+
default:
if (!dev->tuner_addr)
dev->tuner_addr = client->addr;
dprintk1(1, "attach inform: detected I2C address %x\n",
client->addr << 1);
+ dprintk1(1, "driver id %d\n", client->driver->id);
}
@@ -552,6 +559,7 @@ static char *i2c_devs[128] = {
[0x80 >> 1] = "msp34xx",
[0x88 >> 1] = "msp34xx",
[0xa0 >> 1] = "eeprom",
+ [0xb0 >> 1] = "tda9874",
[0xb8 >> 1] = "tvp5150a",
[0xba >> 1] = "tvp5150a",
[0xc0 >> 1] = "tuner (analog)",
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c
index 0443afe09ff..a5abfd7a19f 100644
--- a/drivers/media/video/em28xx/em28xx-input.c
+++ b/drivers/media/video/em28xx/em28xx-input.c
@@ -68,8 +68,7 @@ struct em28xx_IR {
/* poll external decoder */
int polling;
- struct work_struct work;
- struct timer_list timer;
+ struct delayed_work work;
unsigned int last_toggle:1;
unsigned int last_readcount;
unsigned int repeat_interval;
@@ -292,32 +291,23 @@ static void em28xx_ir_handle_key(struct em28xx_IR *ir)
return;
}
-static void ir_timer(unsigned long data)
-{
- struct em28xx_IR *ir = (struct em28xx_IR *)data;
-
- schedule_work(&ir->work);
-}
-
static void em28xx_ir_work(struct work_struct *work)
{
- struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work);
+ struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work);
em28xx_ir_handle_key(ir);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling));
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
}
static void em28xx_ir_start(struct em28xx_IR *ir)
{
- setup_timer(&ir->timer, ir_timer, (unsigned long)ir);
- INIT_WORK(&ir->work, em28xx_ir_work);
- schedule_work(&ir->work);
+ INIT_DELAYED_WORK(&ir->work, em28xx_ir_work);
+ schedule_delayed_work(&ir->work, 0);
}
static void em28xx_ir_stop(struct em28xx_IR *ir)
{
- del_timer_sync(&ir->timer);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ir->work);
}
int em28xx_ir_init(struct em28xx *dev)
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 8e61b2ca916..575472f1e70 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -186,7 +186,8 @@ static void em28xx_copy_video(struct em28xx *dev,
em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
((char *)startwrite + lencopy) -
((char *)outp + buf->vb.size));
- lencopy = remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ remain = (char *)outp + buf->vb.size - (char *)startwrite;
+ lencopy = remain;
}
if (lencopy <= 0)
return;
@@ -202,7 +203,8 @@ static void em28xx_copy_video(struct em28xx *dev,
else
lencopy = bytesperline;
- if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
+ if ((char *)startwrite + lencopy > (char *)outp +
+ buf->vb.size) {
em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
((char *)startwrite + lencopy) -
((char *)outp + buf->vb.size));
@@ -347,7 +349,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
}
if (p[0] == 0x22 && p[1] == 0x5a) {
em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
- len, (p[2] & 1)? "odd" : "even");
+ len, (p[2] & 1) ? "odd" : "even");
if (!(p[2] & 1)) {
if (buf != NULL)
@@ -476,7 +478,9 @@ fail:
static void
buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
{
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf = container_of(vb,
+ struct em28xx_buffer,
+ vb);
struct em28xx_fh *fh = vq->priv_data;
struct em28xx *dev = fh->dev;
struct em28xx_dmaqueue *vidq = &dev->vidq;
@@ -489,7 +493,9 @@ buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
static void buffer_release(struct videobuf_queue *vq,
struct videobuf_buffer *vb)
{
- struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
+ struct em28xx_buffer *buf = container_of(vb,
+ struct em28xx_buffer,
+ vb);
struct em28xx_fh *fh = vq->priv_data;
struct em28xx *dev = (struct em28xx *)fh->dev;
@@ -534,6 +540,13 @@ static void video_mux(struct em28xx *dev, int index)
&route);
}
+ if (dev->board.adecoder != EM28XX_NOADECODER) {
+ route.input = dev->ctl_ainput;
+ route.output = dev->ctl_aoutput;
+ em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
+ &route);
+ }
+
em28xx_audio_analog_set(dev);
}
@@ -557,7 +570,7 @@ static int res_get(struct em28xx_fh *fh)
static int res_check(struct em28xx_fh *fh)
{
- return (fh->stream_on);
+ return fh->stream_on;
}
static void res_free(struct em28xx_fh *fh)
@@ -791,7 +804,7 @@ out:
return rc;
}
-static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
+static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
{
struct em28xx_fh *fh = priv;
struct em28xx *dev = fh->dev;
@@ -1008,8 +1021,13 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
if (dev->board.has_msp34xx)
em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
- else
+ else {
rc = em28xx_get_ctrl(dev, ctrl);
+ if (rc < 0) {
+ em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ rc = 0;
+ }
+ }
mutex_unlock(&dev->lock);
return rc;
@@ -1345,7 +1363,7 @@ static int vidioc_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
@@ -1431,7 +1449,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
if (rc < 0)
return rc;
- return (videobuf_reqbufs(&fh->vb_vidq, rb));
+ return videobuf_reqbufs(&fh->vb_vidq, rb);
}
static int vidioc_querybuf(struct file *file, void *priv,
@@ -1445,7 +1463,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
if (rc < 0)
return rc;
- return (videobuf_querybuf(&fh->vb_vidq, b));
+ return videobuf_querybuf(&fh->vb_vidq, b);
}
static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1458,7 +1476,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
if (rc < 0)
return rc;
- return (videobuf_qbuf(&fh->vb_vidq, b));
+ return videobuf_qbuf(&fh->vb_vidq, b);
}
static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1471,8 +1489,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
if (rc < 0)
return rc;
- return (videobuf_dqbuf(&fh->vb_vidq, b,
- file->f_flags & O_NONBLOCK));
+ return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
}
#ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1496,7 +1513,7 @@ static int radio_querycap(struct file *file, void *priv,
strlcpy(cap->driver, "em28xx", sizeof(cap->driver));
strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = EM28XX_VERSION_CODE;
cap->capabilities = V4L2_CAP_TUNER;
@@ -1781,7 +1798,7 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
* em28xx_v4l2_poll()
* will allocate buffers when called for the first time
*/
-static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
+static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
{
struct em28xx_fh *fh = filp->private_data;
struct em28xx *dev = fh->dev;
@@ -1934,8 +1951,8 @@ static struct video_device em28xx_radio_template = {
static struct video_device *em28xx_vdev_init(struct em28xx *dev,
- const struct video_device *template,
- const char *type_name)
+ const struct video_device *template,
+ const char *type_name)
{
struct video_device *vfd;
@@ -1984,8 +2001,9 @@ int em28xx_register_analog_devices(struct em28xx *dev)
/* enable vbi capturing */
/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
- val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
- em28xx_write_reg(dev, EM28XX_R0F_XCLK, (EM28XX_XCLK_AUDIO_UNMUTE | val));
+ val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
+ em28xx_write_reg(dev, EM28XX_R0F_XCLK,
+ (EM28XX_XCLK_AUDIO_UNMUTE | val));
em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
em28xx_set_outfmt(dev);
@@ -2020,7 +2038,8 @@ int em28xx_register_analog_devices(struct em28xx *dev)
}
if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
- dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, "radio");
+ dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template,
+ "radio");
if (!dev->radio_dev) {
em28xx_errdev("cannot allocate video_device.\n");
return -ENODEV;
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index dd2cd36fb1b..a33a58da016 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -70,7 +70,6 @@
#define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30
#define EM2821_BOARD_USBGEAR_VD204 31
#define EM2821_BOARD_SUPERCOMP_USB_2 32
-#define EM2821_BOARD_PROLINK_PLAYTV_USB2 33
#define EM2860_BOARD_TERRATEC_HYBRID_XS 34
#define EM2860_BOARD_TYPHOON_DVD_MAKER 35
#define EM2860_BOARD_NETGMBH_CAM 36
@@ -98,6 +97,10 @@
#define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58
#define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60
#define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61
+#define EM2820_BOARD_GADMEI_TVR200 62
+#define EM2860_BOARD_KAIOMY_TVNPC_U2 63
+#define EM2860_BOARD_EASYCAP 64
+#define EM2820_BOARD_IODATA_GVMVP_SZ 65
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -110,6 +113,10 @@
#define EM28XX_BOARD_NOT_VALIDATED 1
#define EM28XX_BOARD_VALIDATED 0
+/* Params for em28xx_cmd() audio */
+#define EM28XX_START_AUDIO 1
+#define EM28XX_STOP_AUDIO 0
+
/* maximum number of em28xx boards */
#define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */
@@ -154,7 +161,8 @@
*/
/* time to wait when stopping the isoc transfer */
-#define EM28XX_URB_TIMEOUT msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
+#define EM28XX_URB_TIMEOUT \
+ msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS)
/* time in msecs to wait for i2c writes to finish */
#define EM2800_I2C_WRITE_TIMEOUT 20
@@ -348,6 +356,11 @@ enum em28xx_decoder {
EM28XX_SAA711X,
};
+enum em28xx_adecoder {
+ EM28XX_NOADECODER = 0,
+ EM28XX_TVAUDIO,
+};
+
struct em28xx_board {
char *name;
int vchannels;
@@ -361,6 +374,7 @@ struct em28xx_board {
struct em28xx_reg_seq *dvb_gpio;
struct em28xx_reg_seq *suspend_gpio;
struct em28xx_reg_seq *tuner_gpio;
+ struct em28xx_reg_seq *mute_gpio;
unsigned int is_em2800:1;
unsigned int has_msp34xx:1;
@@ -373,6 +387,7 @@ struct em28xx_board {
unsigned char xclk, i2c_speed;
enum em28xx_decoder decoder;
+ enum em28xx_adecoder adecoder;
struct em28xx_input input[MAX_EM28XX_INPUT];
struct em28xx_input radio;
@@ -420,7 +435,7 @@ struct em28xx_audio {
unsigned int hwptr_done_capture;
struct snd_card *sndcard;
- int users, shutdown;
+ int users;
enum em28xx_stream_state capture_stream;
spinlock_t slock;
};
@@ -523,7 +538,8 @@ struct em28xx {
int num_alt; /* Number of alternative settings */
unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
struct urb *urb[EM28XX_NUM_BUFS]; /* urb for isoc transfers */
- char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc transfer */
+ char *transfer_buffer[EM28XX_NUM_BUFS]; /* transfer buffers for isoc
+ transfer */
char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */
/* helper funcs that call usb_control_msg */
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index ee6a691dff2..578dc4ffc96 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -56,6 +56,15 @@ config USB_GSPCA_MARS
To compile this driver as a module, choose M here: the
module will be called gspca_mars.
+config USB_GSPCA_MR97310A
+ tristate "Mars-Semi MR97310A USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the MR97310A chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_mr97310a.
+
config USB_GSPCA_OV519
tristate "OV519 USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
@@ -167,6 +176,24 @@ config USB_GSPCA_SPCA561
To compile this driver as a module, choose M here: the
module will be called gspca_spca561.
+config USB_GSPCA_SQ905
+ tristate "SQ Technologies SQ905 based USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SQ905 chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sq905.
+
+config USB_GSPCA_SQ905C
+ tristate "SQ Technologies SQ905C based USB Camera Driver"
+ depends on VIDEO_V4L2 && USB_GSPCA
+ help
+ Say Y here if you want support for cameras based on the SQ905C chip.
+
+ To compile this driver as a module, choose M here: the
+ module will be called gspca_sq905c.
+
config USB_GSPCA_STK014
tristate "Syntek DV4000 (STK014) USB Camera Driver"
depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index bd8d9ee4050..8a6643e8eb9 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -1,50 +1,56 @@
-obj-$(CONFIG_USB_GSPCA) += gspca_main.o
-obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
-obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
-obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
-obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
-obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
-obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
-obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
-obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
-obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
-obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
-obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
-obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
-obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
-obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
-obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
-obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
-obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
-obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
-obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
-obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
-obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
-obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
+obj-$(CONFIG_USB_GSPCA) += gspca_main.o
+obj-$(CONFIG_USB_GSPCA_CONEX) += gspca_conex.o
+obj-$(CONFIG_USB_GSPCA_ETOMS) += gspca_etoms.o
+obj-$(CONFIG_USB_GSPCA_FINEPIX) += gspca_finepix.o
+obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
+obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
+obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
+obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
+obj-$(CONFIG_USB_GSPCA_PAC207) += gspca_pac207.o
+obj-$(CONFIG_USB_GSPCA_PAC7311) += gspca_pac7311.o
+obj-$(CONFIG_USB_GSPCA_SONIXB) += gspca_sonixb.o
+obj-$(CONFIG_USB_GSPCA_SONIXJ) += gspca_sonixj.o
+obj-$(CONFIG_USB_GSPCA_SPCA500) += gspca_spca500.o
+obj-$(CONFIG_USB_GSPCA_SPCA501) += gspca_spca501.o
+obj-$(CONFIG_USB_GSPCA_SPCA505) += gspca_spca505.o
+obj-$(CONFIG_USB_GSPCA_SPCA506) += gspca_spca506.o
+obj-$(CONFIG_USB_GSPCA_SPCA508) += gspca_spca508.o
+obj-$(CONFIG_USB_GSPCA_SPCA561) += gspca_spca561.o
+obj-$(CONFIG_USB_GSPCA_SQ905) += gspca_sq905.o
+obj-$(CONFIG_USB_GSPCA_SQ905C) += gspca_sq905c.o
+obj-$(CONFIG_USB_GSPCA_SUNPLUS) += gspca_sunplus.o
+obj-$(CONFIG_USB_GSPCA_STK014) += gspca_stk014.o
+obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
+obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
+obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
+obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
-gspca_main-objs := gspca.o
-gspca_conex-objs := conex.o
-gspca_etoms-objs := etoms.o
-gspca_finepix-objs := finepix.o
-gspca_mars-objs := mars.o
-gspca_ov519-objs := ov519.o
-gspca_ov534-objs := ov534.o
-gspca_pac207-objs := pac207.o
-gspca_pac7311-objs := pac7311.o
-gspca_sonixb-objs := sonixb.o
-gspca_sonixj-objs := sonixj.o
-gspca_spca500-objs := spca500.o
-gspca_spca501-objs := spca501.o
-gspca_spca505-objs := spca505.o
-gspca_spca506-objs := spca506.o
-gspca_spca508-objs := spca508.o
-gspca_spca561-objs := spca561.o
-gspca_stk014-objs := stk014.o
-gspca_sunplus-objs := sunplus.o
-gspca_t613-objs := t613.o
-gspca_tv8532-objs := tv8532.o
-gspca_vc032x-objs := vc032x.o
-gspca_zc3xx-objs := zc3xx.o
+gspca_main-objs := gspca.o
+gspca_conex-objs := conex.o
+gspca_etoms-objs := etoms.o
+gspca_finepix-objs := finepix.o
+gspca_mars-objs := mars.o
+gspca_mr97310a-objs := mr97310a.o
+gspca_ov519-objs := ov519.o
+gspca_ov534-objs := ov534.o
+gspca_pac207-objs := pac207.o
+gspca_pac7311-objs := pac7311.o
+gspca_sonixb-objs := sonixb.o
+gspca_sonixj-objs := sonixj.o
+gspca_spca500-objs := spca500.o
+gspca_spca501-objs := spca501.o
+gspca_spca505-objs := spca505.o
+gspca_spca506-objs := spca506.o
+gspca_spca508-objs := spca508.o
+gspca_spca561-objs := spca561.o
+gspca_sq905-objs := sq905.o
+gspca_sq905c-objs := sq905c.o
+gspca_stk014-objs := stk014.o
+gspca_sunplus-objs := sunplus.o
+gspca_t613-objs := t613.o
+gspca_tv8532-objs := tv8532.o
+gspca_vc032x-objs := vc032x.o
+gspca_zc3xx-objs := zc3xx.o
-obj-$(CONFIG_USB_M5602) += m5602/
-obj-$(CONFIG_USB_STV06XX) += stv06xx/
+obj-$(CONFIG_USB_M5602) += m5602/
+obj-$(CONFIG_USB_STV06XX) += stv06xx/
diff --git a/drivers/media/video/gspca/conex.c b/drivers/media/video/gspca/conex.c
index 1753f5bb354..219cfa6fb87 100644
--- a/drivers/media/video/gspca/conex.c
+++ b/drivers/media/video/gspca/conex.c
@@ -36,8 +36,12 @@ struct sd {
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
+ u8 quality;
+#define QUALITY_MIN 30
+#define QUALITY_MAX 60
+#define QUALITY_DEF 40
- unsigned char qindex;
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -815,14 +819,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
- sd->qindex = 0; /* set the quantization */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -839,6 +842,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
cx11646_initsize(gspca_dev);
cx11646_fw(gspca_dev);
cx_sensor(gspca_dev);
@@ -849,8 +860,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* called on streamoff with alt 0 and on disconnect */
static void sd_stop0(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int retry = 50;
+ kfree(sd->jpeg_hdr);
+
if (!gspca_dev->present)
return;
reg_w_val(gspca_dev, 0x0000, 0x00);
@@ -876,6 +890,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
+ struct sd *sd = (struct sd *) gspca_dev;
+
if (data[0] == 0xff && data[1] == 0xd8) {
/* start of frame */
@@ -883,9 +899,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
data += 2;
len -= 2;
}
@@ -988,6 +1003,34 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -998,6 +1041,8 @@ static struct sd_desc sd_desc = {
.start = sd_start,
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1029,8 +1074,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/etoms.c b/drivers/media/video/gspca/etoms.c
index f3cd8ff5cc9..2c20d06a03e 100644
--- a/drivers/media/video/gspca/etoms.c
+++ b/drivers/media/video/gspca/etoms.c
@@ -472,19 +472,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_w_val(gspca_dev, ET_O_RED + i, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int brightness = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_O_RED + i, 1);
- brightness += gspca_dev->usb_buf[0];
- }
- sd->brightness = brightness >> 3;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -495,19 +482,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, ET_G_RED, RGBG, 6);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int i;
- int contrast = 0;
-
- for (i = 0; i < 4; i++) {
- reg_r(gspca_dev, ET_G_RED + i, 1);
- contrast += gspca_dev->usb_buf[0];
- }
- sd->contrast = contrast >> 2;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -658,7 +632,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 1;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAS106) {
cam->cam_mode = sif_mode;
@@ -821,7 +794,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -840,7 +812,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -859,7 +830,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -928,8 +898,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/finepix.c b/drivers/media/video/gspca/finepix.c
index afc8b2dd307..00e6863ed66 100644
--- a/drivers/media/video/gspca/finepix.c
+++ b/drivers/media/video/gspca/finepix.c
@@ -27,7 +27,7 @@ MODULE_DESCRIPTION("Fujifilm FinePix USB V4L2 driver");
MODULE_LICENSE("GPL");
/* Default timeout, in ms */
-#define FPIX_TIMEOUT (HZ / 10)
+#define FPIX_TIMEOUT 250
/* Maximum transfer size to use. The windows driver reads by chunks of
* 0x2000 bytes, so do the same. Note: reading more seems to work
@@ -38,38 +38,15 @@ MODULE_LICENSE("GPL");
struct usb_fpix {
struct gspca_dev gspca_dev; /* !! must be the first item */
- /*
- * USB stuff
- */
- struct usb_ctrlrequest ctrlreq;
- struct urb *control_urb;
- struct timer_list bulk_timer;
-
- enum {
- FPIX_NOP, /* inactive, else streaming */
- FPIX_RESET, /* must reset */
- FPIX_REQ_FRAME, /* requesting a frame */
- FPIX_READ_FRAME, /* reading frame */
- } state;
-
- /*
- * Driver stuff
- */
- struct delayed_work wqe;
- struct completion can_close;
- int streaming;
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
};
/* Delay after which claim the next frame. If the delay is too small,
* the camera will return old frames. On the 4800Z, 20ms is bad, 25ms
- * will fail every 4 or 5 frames, but 30ms is perfect. */
-#define NEXT_FRAME_DELAY (((HZ * 30) + 999) / 1000)
-
-#define dev_new_state(new_state) { \
- PDEBUG(D_STREAM, "new state from %d to %d at %s:%d", \
- dev->state, new_state, __func__, __LINE__); \
- dev->state = new_state; \
-}
+ * will fail every 4 or 5 frames, but 30ms is perfect. On the A210,
+ * 30ms is bad while 35ms is perfect. */
+#define NEXT_FRAME_DELAY 35
/* These cameras only support 320x200. */
static const struct v4l2_pix_format fpix_mode[1] = {
@@ -80,316 +57,183 @@ static const struct v4l2_pix_format fpix_mode[1] = {
.priv = 0}
};
-/* Reads part of a frame */
-static void read_frame_part(struct usb_fpix *dev)
+/* send a command to the webcam */
+static int command(struct gspca_dev *gspca_dev,
+ int order) /* 0: reset, 1: frame request */
{
- int ret;
+ static u8 order_values[2][12] = {
+ {0xc6, 0, 0, 0, 0, 0, 0, 0, 0x20, 0, 0, 0}, /* reset */
+ {0xd3, 0, 0, 0, 0, 0, 0, 0x01, 0, 0, 0, 0}, /* fr req */
+ };
- PDEBUG(D_STREAM, "read_frame_part");
-
- /* Reads part of a frame */
- ret = usb_submit_urb(dev->gspca_dev.urb[0], GFP_ATOMIC);
- if (ret) {
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- PDEBUG(D_STREAM, "usb_submit_urb failed with %d",
- ret);
- } else {
- /* Sometimes we never get a callback, so use a timer.
- * Is this masking a bug somewhere else? */
- dev->bulk_timer.expires = jiffies + msecs_to_jiffies(150);
- add_timer(&dev->bulk_timer);
- }
+ memcpy(gspca_dev->usb_buf, order_values[order], 12);
+ return usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_GET_STATUS,
+ USB_DIR_OUT | USB_TYPE_CLASS |
+ USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
+ 12, FPIX_TIMEOUT);
}
-/* Callback for URBs. */
-static void urb_callback(struct urb *urb)
+/* workqueue */
+static void dostream(struct work_struct *work)
{
- struct gspca_dev *gspca_dev = urb->context;
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- PDEBUG(D_PACK,
- "enter urb_callback - status=%d, length=%d",
- urb->status, urb->actual_length);
-
- if (dev->state == FPIX_READ_FRAME)
- del_timer(&dev->bulk_timer);
-
- if (urb->status != 0) {
- /* We kill a stuck urb every 50 frames on average, so don't
- * display a log message for that. */
- if (urb->status != -ECONNRESET)
- PDEBUG(D_STREAM, "bad URB status %d", urb->status);
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- }
-
- switch (dev->state) {
- case FPIX_REQ_FRAME:
- dev_new_state(FPIX_READ_FRAME);
- read_frame_part(dev);
- break;
-
- case FPIX_READ_FRAME: {
- unsigned char *data = urb->transfer_buffer;
- struct gspca_frame *frame;
-
- frame = gspca_get_i_frame(&dev->gspca_dev);
- if (frame == NULL)
- gspca_dev->last_packet_type = DISCARD_PACKET;
- if (urb->actual_length < FPIX_MAX_TRANSFER ||
- (data[urb->actual_length-2] == 0xff &&
- data[urb->actual_length-1] == 0xd9)) {
-
- /* If the result is less than what was asked
- * for, then it's the end of the
- * frame. Sometime the jpeg is not complete,
- * but there's nothing we can do. We also end
- * here if the the jpeg ends right at the end
- * of the frame. */
- if (frame)
- gspca_frame_add(gspca_dev, LAST_PACKET,
- frame,
- data, urb->actual_length);
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, NEXT_FRAME_DELAY);
- } else {
+ struct usb_fpix *dev = container_of(work, struct usb_fpix, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct urb *urb = gspca_dev->urb[0];
+ u8 *data = urb->transfer_buffer;
+ struct gspca_frame *frame;
+ int ret = 0;
+ int len;
+
+ /* synchronize with the main driver */
+ mutex_lock(&gspca_dev->usb_lock);
+ mutex_unlock(&gspca_dev->usb_lock);
+ PDEBUG(D_STREAM, "dostream started");
+
+ /* loop reading a frame */
+again:
+ while (gspca_dev->present && gspca_dev->streaming) {
+
+ /* request a frame */
+ mutex_lock(&gspca_dev->usb_lock);
+ ret = command(gspca_dev, 1);
+ mutex_unlock(&gspca_dev->usb_lock);
+ if (ret < 0)
+ break;
+ if (!gspca_dev->present || !gspca_dev->streaming)
+ break;
+
+ /* the frame comes in parts */
+ for (;;) {
+ ret = usb_bulk_msg(gspca_dev->dev,
+ urb->pipe,
+ data,
+ FPIX_MAX_TRANSFER,
+ &len, FPIX_TIMEOUT);
+ if (ret < 0) {
+ /* Most of the time we get a timeout
+ * error. Just restart. */
+ goto again;
+ }
+ if (!gspca_dev->present || !gspca_dev->streaming)
+ goto out;
+ frame = gspca_get_i_frame(&dev->gspca_dev);
+ if (frame == NULL)
+ gspca_dev->last_packet_type = DISCARD_PACKET;
+
+ if (len < FPIX_MAX_TRANSFER ||
+ (data[len - 2] == 0xff &&
+ data[len - 1] == 0xd9)) {
+
+ /* If the result is less than what was asked
+ * for, then it's the end of the
+ * frame. Sometimes the jpeg is not complete,
+ * but there's nothing we can do. We also end
+ * here if the the jpeg ends right at the end
+ * of the frame. */
+ if (frame)
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame,
+ data, len);
+ break;
+ }
/* got a partial image */
if (frame)
gspca_frame_add(gspca_dev,
gspca_dev->last_packet_type
- == LAST_PACKET
+ == LAST_PACKET
? FIRST_PACKET : INTER_PACKET,
- frame,
- data, urb->actual_length);
- read_frame_part(dev);
+ frame, data, len);
}
- break;
- }
-
- case FPIX_NOP:
- case FPIX_RESET:
- PDEBUG(D_STREAM, "invalid state %d", dev->state);
- break;
- }
-}
-/* Request a new frame */
-static void request_frame(struct usb_fpix *dev)
-{
- int ret;
- struct gspca_dev *gspca_dev = &dev->gspca_dev;
-
- /* Setup command packet */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xd3;
- gspca_dev->usb_buf[7] = 0x01;
-
- /* Request a frame */
- dev->ctrlreq.bRequestType =
- USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE;
- dev->ctrlreq.bRequest = USB_REQ_GET_STATUS;
- dev->ctrlreq.wValue = 0;
- dev->ctrlreq.wIndex = 0;
- dev->ctrlreq.wLength = cpu_to_le16(12);
-
- usb_fill_control_urb(dev->control_urb,
- gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- (unsigned char *) &dev->ctrlreq,
- gspca_dev->usb_buf,
- 12, urb_callback, gspca_dev);
-
- ret = usb_submit_urb(dev->control_urb, GFP_ATOMIC);
- if (ret) {
- dev_new_state(FPIX_RESET);
- schedule_delayed_work(&dev->wqe, 1);
- PDEBUG(D_STREAM, "usb_submit_urb failed with %d", ret);
- }
-}
-
-/*--------------------------------------------------------------------------*/
-
-/* State machine. */
-static void fpix_sm(struct work_struct *work)
-{
- struct usb_fpix *dev = container_of(work, struct usb_fpix, wqe.work);
-
- PDEBUG(D_STREAM, "fpix_sm state %d", dev->state);
-
- /* verify that the device wasn't unplugged */
- if (!dev->gspca_dev.present) {
- PDEBUG(D_STREAM, "device is gone");
- dev_new_state(FPIX_NOP);
- complete(&dev->can_close);
- return;
- }
-
- if (!dev->streaming) {
- PDEBUG(D_STREAM, "stopping state machine");
- dev_new_state(FPIX_NOP);
- complete(&dev->can_close);
- return;
+ /* We must wait before trying reading the next
+ * frame. If we don't, or if the delay is too short,
+ * the camera will disconnect. */
+ msleep(NEXT_FRAME_DELAY);
}
- switch (dev->state) {
- case FPIX_RESET:
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, HZ / 10);
- break;
-
- case FPIX_REQ_FRAME:
- /* get an image */
- request_frame(dev);
- break;
-
- case FPIX_NOP:
- case FPIX_READ_FRAME:
- PDEBUG(D_STREAM, "invalid state %d", dev->state);
- break;
- }
+out:
+ PDEBUG(D_STREAM, "dostream stopped");
}
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
+ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
struct cam *cam = &gspca_dev->cam;
cam->cam_mode = fpix_mode;
cam->nmodes = 1;
- cam->epaddr = 0x01; /* todo: correct for all cams? */
cam->bulk_size = FPIX_MAX_TRANSFER;
-/* gspca_dev->nbalt = 1; * use bulk transfer */
- return 0;
-}
-
-/* Stop streaming and free the ressources allocated by sd_start. */
-static void sd_stopN(struct gspca_dev *gspca_dev)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- dev->streaming = 0;
-
- /* Stop the state machine */
- if (dev->state != FPIX_NOP)
- wait_for_completion(&dev->can_close);
-}
-
-/* called on streamoff with alt 0 and disconnect */
-static void sd_stop0(struct gspca_dev *gspca_dev)
-{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- usb_free_urb(dev->control_urb);
- dev->control_urb = NULL;
-}
-
-/* Kill an URB that hasn't completed. */
-static void timeout_kill(unsigned long data)
-{
- struct urb *urb = (struct urb *) data;
+ INIT_WORK(&dev->work_struct, dostream);
- usb_unlink_urb(urb);
+ return 0;
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-
- INIT_DELAYED_WORK(&dev->wqe, fpix_sm);
-
- init_timer(&dev->bulk_timer);
- dev->bulk_timer.function = timeout_kill;
-
return 0;
}
+/* start the camera */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
- int ret;
- int size_ret;
+ int ret, len;
/* Init the device */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xc6;
- gspca_dev->usb_buf[8] = 0x20;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
- 12, FPIX_TIMEOUT);
-
- if (ret != 12) {
- PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ ret = command(gspca_dev, 0);
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "init failed %d", ret);
+ return ret;
}
/* Read the result of the command. Ignore the result, for it
* varies with the device. */
ret = usb_bulk_msg(gspca_dev->dev,
- usb_rcvbulkpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr),
- gspca_dev->usb_buf, FPIX_MAX_TRANSFER, &size_ret,
+ gspca_dev->urb[0]->pipe,
+ gspca_dev->urb[0]->transfer_buffer,
+ FPIX_MAX_TRANSFER, &len,
FPIX_TIMEOUT);
- if (ret != 0) {
- PDEBUG(D_STREAM, "usb_bulk_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "usb_bulk_msg failed %d", ret);
+ return ret;
}
/* Request a frame, but don't read it */
- memset(gspca_dev->usb_buf, 0, 12);
- gspca_dev->usb_buf[0] = 0xd3;
- gspca_dev->usb_buf[7] = 0x01;
-
- ret = usb_control_msg(gspca_dev->dev,
- usb_sndctrlpipe(gspca_dev->dev, 0),
- USB_REQ_GET_STATUS,
- USB_DIR_OUT | USB_TYPE_CLASS |
- USB_RECIP_INTERFACE, 0, 0, gspca_dev->usb_buf,
- 12, FPIX_TIMEOUT);
- if (ret != 12) {
- PDEBUG(D_STREAM, "usb_control_msg failed (%d)", ret);
- ret = -EIO;
- goto error;
+ ret = command(gspca_dev, 1);
+ if (ret < 0) {
+ PDEBUG(D_STREAM, "frame request failed %d", ret);
+ return ret;
}
/* Again, reset bulk in endpoint */
- usb_clear_halt(gspca_dev->dev, gspca_dev->cam.epaddr);
-
- /* Allocate a control URB */
- dev->control_urb = usb_alloc_urb(0, GFP_KERNEL);
- if (!dev->control_urb) {
- PDEBUG(D_STREAM, "No free urbs available");
- ret = -EIO;
- goto error;
- }
-
- /* Various initializations. */
- init_completion(&dev->can_close);
- dev->bulk_timer.data = (unsigned long)dev->gspca_dev.urb[0];
- dev->gspca_dev.urb[0]->complete = urb_callback;
- dev->streaming = 1;
+ usb_clear_halt(gspca_dev->dev, gspca_dev->urb[0]->pipe);
- /* Schedule a frame request. */
- dev_new_state(FPIX_REQ_FRAME);
- schedule_delayed_work(&dev->wqe, 1);
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct usb_fpix *dev = (struct usb_fpix *) gspca_dev;
-error:
- /* Free the ressources */
- sd_stopN(gspca_dev);
- sd_stop0(gspca_dev);
- return ret;
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ destroy_workqueue(dev->work_thread);
+ mutex_lock(&gspca_dev->usb_lock);
+ dev->work_thread = NULL;
}
/* Table of supported USB devices */
@@ -424,12 +268,11 @@ MODULE_DEVICE_TABLE(usb, device_table);
/* sub-driver description */
static const struct sd_desc sd_desc = {
- .name = MODULE_NAME,
+ .name = MODULE_NAME,
.config = sd_config,
- .init = sd_init,
- .start = sd_start,
- .stopN = sd_stopN,
- .stop0 = sd_stop0,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
};
/* -- device connect -- */
@@ -443,24 +286,28 @@ static int sd_probe(struct usb_interface *intf,
}
static struct usb_driver sd_driver = {
- .name = MODULE_NAME,
- .id_table = device_table,
- .probe = sd_probe,
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
.disconnect = gspca_disconnect,
#ifdef CONFIG_PM
.suspend = gspca_suspend,
- .resume = gspca_resume,
+ .resume = gspca_resume,
#endif
};
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
+
static void __exit sd_mod_exit(void)
{
usb_deregister(&sd_driver);
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index 65e4901f4db..a75c1ca2db4 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -38,15 +38,16 @@
#include "gspca.h"
/* global values */
-#define DEF_NURBS 2 /* default number of URBs */
+#define DEF_NURBS 3 /* default number of URBs */
+#if DEF_NURBS > MAX_NURBS
+#error "DEF_NURBS too big"
+#endif
MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
MODULE_DESCRIPTION("GSPCA USB Camera Driver");
MODULE_LICENSE("GPL");
-#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 4, 0)
-
-static int video_nr = -1;
+#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 5, 0)
#ifdef GSPCA_DEBUG
int gspca_debug = D_ERR | D_PROBE;
@@ -126,16 +127,18 @@ static void fill_frame(struct gspca_dev *gspca_dev,
struct urb *urb)
{
struct gspca_frame *frame;
- __u8 *data; /* address of data in the iso message */
+ u8 *data; /* address of data in the iso message */
int i, len, st;
cam_pkt_op pkt_scan;
if (urb->status != 0) {
+ if (urb->status == -ESHUTDOWN)
+ return; /* disconnection */
#ifdef CONFIG_PM
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
pkt_scan = gspca_dev->sd_desc->pkt_scan;
for (i = 0; i < urb->number_of_packets; i++) {
@@ -166,7 +169,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
/* let the packet be analyzed by the subdriver */
PDEBUG(D_PACK, "packet [%d] o:%d l:%d",
i, urb->iso_frame_desc[i].offset, len);
- data = (__u8 *) urb->transfer_buffer
+ data = (u8 *) urb->transfer_buffer
+ urb->iso_frame_desc[i].offset;
pkt_scan(gspca_dev, frame, data, len);
}
@@ -182,8 +185,7 @@ static void fill_frame(struct gspca_dev *gspca_dev,
*
* Analyse each packet and call the subdriver for copy to the frame buffer.
*/
-static void isoc_irq(struct urb *urb
-)
+static void isoc_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
@@ -196,8 +198,7 @@ static void isoc_irq(struct urb *urb
/*
* bulk message interrupt from the USB device
*/
-static void bulk_irq(struct urb *urb
-)
+static void bulk_irq(struct urb *urb)
{
struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context;
struct gspca_frame *frame;
@@ -209,6 +210,8 @@ static void bulk_irq(struct urb *urb
switch (urb->status) {
case 0:
break;
+ case -ESHUTDOWN:
+ return; /* disconnection */
case -ECONNRESET:
urb->status = 0;
break;
@@ -217,7 +220,7 @@ static void bulk_irq(struct urb *urb
if (!gspca_dev->frozen)
#endif
PDEBUG(D_ERR|D_PACK, "urb status: %d", urb->status);
- return; /* disconnection ? */
+ return;
}
/* check the availability of the frame buffer */
@@ -322,6 +325,7 @@ static int gspca_is_compressed(__u32 format)
case V4L2_PIX_FMT_JPEG:
case V4L2_PIX_FMT_SPCA561:
case V4L2_PIX_FMT_PAC207:
+ case V4L2_PIX_FMT_MR97310A:
return 1;
}
return 0;
@@ -422,10 +426,8 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
if (urb == NULL)
break;
- BUG_ON(!gspca_dev->dev);
gspca_dev->urb[i] = NULL;
- if (!gspca_dev->present)
- usb_kill_urb(urb);
+ usb_kill_urb(urb);
if (urb->transfer_buffer != NULL)
usb_buffer_free(gspca_dev->dev,
urb->transfer_buffer_length,
@@ -439,22 +441,16 @@ static void destroy_urbs(struct gspca_dev *gspca_dev)
* look for an input transfer endpoint in an alternate setting
*/
static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
- __u8 epaddr,
__u8 xfer)
{
struct usb_host_endpoint *ep;
int i, attr;
- epaddr |= USB_DIR_IN;
for (i = 0; i < alt->desc.bNumEndpoints; i++) {
ep = &alt->endpoint[i];
- if (ep->desc.bEndpointAddress == epaddr) {
- attr = ep->desc.bmAttributes
- & USB_ENDPOINT_XFERTYPE_MASK;
- if (attr == xfer)
- return ep;
- break;
- }
+ attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
+ if (attr == xfer)
+ return ep;
}
return NULL;
}
@@ -478,23 +474,23 @@ static struct usb_host_endpoint *get_ep(struct gspca_dev *gspca_dev)
i = gspca_dev->alt; /* previous alt setting */
/* try isoc */
- while (--i > 0) { /* alt 0 is unusable */
+ while (--i >= 0) {
ep = alt_xfer(&intf->altsetting[i],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_ISOC);
if (ep)
break;
}
- /* if no isoc, try bulk */
+ /* if no isoc, try bulk (alt 0 only) */
if (ep == NULL) {
ep = alt_xfer(&intf->altsetting[0],
- gspca_dev->cam.epaddr,
USB_ENDPOINT_XFER_BULK);
if (ep == NULL) {
err("no transfer endpoint found");
return NULL;
}
+ i = 0;
+ gspca_dev->bulk = 1;
}
PDEBUG(D_STREAM, "use alt %d ep 0x%02x",
i, ep->desc.bEndpointAddress);
@@ -521,7 +517,7 @@ static int create_urbs(struct gspca_dev *gspca_dev,
/* calculate the packet size and the number of packets */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
- if (gspca_dev->alt != 0) { /* isoc */
+ if (!gspca_dev->bulk) { /* isoc */
/* See paragraph 5.9 / table 5-11 of the usb 2.0 spec. */
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
@@ -601,6 +597,11 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
+
/* set the higher alternate setting and
* loop until urb submit succeeds */
gspca_dev->alt = gspca_dev->nbalt;
@@ -616,10 +617,9 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
goto out;
/* clear the bulk endpoint */
- if (gspca_dev->alt == 0) /* if bulk transfer */
+ if (gspca_dev->bulk)
usb_clear_halt(gspca_dev->dev,
- usb_rcvintpipe(gspca_dev->dev,
- gspca_dev->cam.epaddr));
+ gspca_dev->urb[0]->pipe);
/* start the cam */
ret = gspca_dev->sd_desc->start(gspca_dev);
@@ -630,7 +630,7 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev)
gspca_dev->streaming = 1;
/* some bulk transfers are started by the subdriver */
- if (gspca_dev->alt == 0 && gspca_dev->cam.bulk_nurbs == 0)
+ if (gspca_dev->bulk && gspca_dev->cam.bulk_nurbs == 0)
break;
/* submit the URBs */
@@ -671,11 +671,14 @@ static int gspca_set_alt0(struct gspca_dev *gspca_dev)
static void gspca_stream_off(struct gspca_dev *gspca_dev)
{
gspca_dev->streaming = 0;
- if (gspca_dev->present
- && gspca_dev->sd_desc->stopN)
- gspca_dev->sd_desc->stopN(gspca_dev);
- destroy_urbs(gspca_dev);
- gspca_set_alt0(gspca_dev);
+ if (gspca_dev->present) {
+ if (gspca_dev->sd_desc->stopN)
+ gspca_dev->sd_desc->stopN(gspca_dev);
+ destroy_urbs(gspca_dev);
+ gspca_set_alt0(gspca_dev);
+ }
+
+ /* always call stop0 to free the subdriver's resources */
if (gspca_dev->sd_desc->stop0)
gspca_dev->sd_desc->stop0(gspca_dev);
PDEBUG(D_STREAM, "stream off OK");
@@ -762,7 +765,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
fmtdesc->pixelformat = fmt_tb[index];
if (gspca_is_compressed(fmt_tb[index]))
fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
- fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
@@ -957,8 +959,15 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
struct gspca_dev *gspca_dev = priv;
+ int ret;
- memset(cap, 0, sizeof *cap);
+ /* protect the access to the usb device */
+ if (mutex_lock_interruptible(&gspca_dev->usb_lock))
+ return -ERESTARTSYS;
+ if (!gspca_dev->present) {
+ ret = -ENODEV;
+ goto out;
+ }
strncpy(cap->driver, gspca_dev->sd_desc->name, sizeof cap->driver);
if (gspca_dev->dev->product != NULL) {
strncpy(cap->card, gspca_dev->dev->product,
@@ -969,13 +978,15 @@ static int vidioc_querycap(struct file *file, void *priv,
le16_to_cpu(gspca_dev->dev->descriptor.idVendor),
le16_to_cpu(gspca_dev->dev->descriptor.idProduct));
}
- strncpy(cap->bus_info, gspca_dev->dev->bus->bus_name,
- sizeof cap->bus_info);
+ usb_make_path(gspca_dev->dev, cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
| V4L2_CAP_STREAMING
| V4L2_CAP_READWRITE;
- return 0;
+ ret = 0;
+out:
+ mutex_unlock(&gspca_dev->usb_lock);
+ return ret;
}
static int vidioc_queryctrl(struct file *file, void *priv,
@@ -1038,7 +1049,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
PDEBUG(D_CONF, "set ctrl [%08x] = %d", ctrl->id, ctrl->value);
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->set(gspca_dev, ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->set(gspca_dev, ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1062,7 +1076,10 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = ctrls->get(gspca_dev, &ctrl->value);
+ if (gspca_dev->present)
+ ret = ctrls->get(gspca_dev, &ctrl->value);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1081,7 +1098,6 @@ static int vidioc_s_audio(struct file *file, void *priv,
static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *audio)
{
- memset(audio, 0, sizeof *audio);
strcpy(audio->name, "Microphone");
return 0;
}
@@ -1115,7 +1131,6 @@ static int vidioc_enum_input(struct file *file, void *priv,
if (input->index != 0)
return -EINVAL;
- memset(input, 0, sizeof *input);
input->type = V4L2_INPUT_TYPE_CAMERA;
strncpy(input->name, gspca_dev->sd_desc->name,
sizeof input->name);
@@ -1224,10 +1239,7 @@ static int vidioc_streamon(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->queue_lock))
return -ERESTARTSYS;
- if (!gspca_dev->present) {
- ret = -ENODEV;
- goto out;
- }
+
if (gspca_dev->nframes == 0
|| !(gspca_dev->frame[0].v4l2_buf.flags & V4L2_BUF_FLAG_QUEUED)) {
ret = -EINVAL;
@@ -1295,7 +1307,10 @@ static int vidioc_g_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1310,7 +1325,10 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
return -EINVAL;
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_jcomp(gspca_dev, jpegcomp);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1320,8 +1338,6 @@ static int vidioc_g_parm(struct file *filp, void *priv,
{
struct gspca_dev *gspca_dev = priv;
- memset(parm, 0, sizeof *parm);
- parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
parm->parm.capture.readbuffers = gspca_dev->nbufread;
if (gspca_dev->sd_desc->get_streamparm) {
@@ -1329,7 +1345,11 @@ static int vidioc_g_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->get_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->get_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1354,7 +1374,11 @@ static int vidioc_s_parm(struct file *filp, void *priv,
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
- ret = gspca_dev->sd_desc->set_streamparm(gspca_dev, parm);
+ if (gspca_dev->present)
+ ret = gspca_dev->sd_desc->set_streamparm(gspca_dev,
+ parm);
+ else
+ ret = -ENODEV;
mutex_unlock(&gspca_dev->usb_lock);
return ret;
}
@@ -1382,7 +1406,6 @@ static int vidiocgmbuf(struct file *file, void *priv,
{
struct v4l2_format fmt;
- memset(&fmt, 0, sizeof fmt);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
i = gspca_dev->cam.nmodes - 1; /* highest mode */
fmt.fmt.pix.width = gspca_dev->cam.cam_mode[i].width;
@@ -1528,7 +1551,8 @@ static int frame_wait(struct gspca_dev *gspca_dev,
if (gspca_dev->sd_desc->dq_callback) {
mutex_lock(&gspca_dev->usb_lock);
- gspca_dev->sd_desc->dq_callback(gspca_dev);
+ if (gspca_dev->present)
+ gspca_dev->sd_desc->dq_callback(gspca_dev);
mutex_unlock(&gspca_dev->usb_lock);
}
return j;
@@ -1550,6 +1574,9 @@ static int vidioc_dqbuf(struct file *file, void *priv,
if (v4l2_buf->memory != gspca_dev->memory)
return -EINVAL;
+ if (!gspca_dev->present)
+ return -ENODEV;
+
/* if not streaming, be sure the application will not loop forever */
if (!(file->f_flags & O_NONBLOCK)
&& !gspca_dev->streaming && gspca_dev->users == 1)
@@ -1700,8 +1727,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
PDEBUG(D_FRAM, "poll");
poll_wait(file, &gspca_dev->wq, wait);
- if (!gspca_dev->present)
- return POLLERR;
/* if reqbufs is not done, the user would use read() */
if (gspca_dev->nframes == 0) {
@@ -1714,10 +1739,6 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0)
return POLLERR;
- if (!gspca_dev->present) {
- ret = POLLERR;
- goto out;
- }
/* check the next incoming buffer */
i = gspca_dev->fr_o;
@@ -1726,8 +1747,9 @@ static unsigned int dev_poll(struct file *file, poll_table *wait)
ret = POLLIN | POLLRDNORM; /* something to read */
else
ret = 0;
-out:
mutex_unlock(&gspca_dev->queue_lock);
+ if (!gspca_dev->present)
+ return POLLHUP;
return ret;
}
@@ -1925,7 +1947,7 @@ int gspca_dev_probe(struct usb_interface *intf,
gspca_dev->present = 1;
ret = video_register_device(&gspca_dev->vdev,
VFL_TYPE_GRABBER,
- video_nr);
+ -1);
if (ret < 0) {
err("video_register_device err %d", ret);
goto out;
@@ -1953,10 +1975,16 @@ void gspca_disconnect(struct usb_interface *intf)
mutex_lock(&gspca_dev->usb_lock);
gspca_dev->present = 0;
- mutex_unlock(&gspca_dev->usb_lock);
- destroy_urbs(gspca_dev);
+ if (gspca_dev->streaming) {
+ destroy_urbs(gspca_dev);
+ wake_up_interruptible(&gspca_dev->wq);
+ }
+
+ /* the device is freed at exit of this function */
gspca_dev->dev = NULL;
+ mutex_unlock(&gspca_dev->usb_lock);
+
usb_set_intfdata(intf, NULL);
/* release the device */
diff --git a/drivers/media/video/gspca/gspca.h b/drivers/media/video/gspca/gspca.h
index c90af9cb1e0..e4d4cf6ce05 100644
--- a/drivers/media/video/gspca/gspca.h
+++ b/drivers/media/video/gspca/gspca.h
@@ -33,19 +33,13 @@ extern int gspca_debug;
#endif
#undef err
#define err(fmt, args...) \
- do {\
- printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_ERR MODULE_NAME ": " fmt "\n", ## args)
#undef info
#define info(fmt, args...) \
- do {\
- printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_INFO MODULE_NAME ": " fmt "\n", ## args)
#undef warn
#define warn(fmt, args...) \
- do {\
- printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args); \
- } while (0)
+ printk(KERN_WARNING MODULE_NAME ": " fmt "\n", ## args)
#define GSPCA_MAX_FRAMES 16 /* maximum number of video frame buffers */
/* image transfers */
@@ -62,7 +56,6 @@ struct cam {
* - cannot be > MAX_NURBS
* - when 0 and bulk_size != 0 means
* 1 URB and submit done by subdriver */
- __u8 epaddr;
};
struct gspca_dev;
@@ -174,6 +167,7 @@ struct gspca_dev {
__u8 iface; /* USB interface number */
__u8 alt; /* USB alternate setting */
__u8 nbalt; /* number of USB alternate settings */
+ u8 bulk; /* image transfer by 0:isoc / 1:bulk */
};
int gspca_dev_probe(struct usb_interface *intf,
diff --git a/drivers/media/video/gspca/jpeg.h b/drivers/media/video/gspca/jpeg.h
index d823b47bd4e..de63c36806c 100644
--- a/drivers/media/video/gspca/jpeg.h
+++ b/drivers/media/video/gspca/jpeg.h
@@ -24,171 +24,39 @@
*
*/
-/* start of jpeg frame + quantization table */
-static const unsigned char quant[][0x88] = {
-/* index 0 - Q40*/
- {
+/*
+ * generation options
+ * CONEX_CAM Conexant if present
+ */
+
+/* JPEG header */
+static const u8 jpeg_head[] = {
0xff, 0xd8, /* jpeg */
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0, /* quantization table part 1 */
- 20, 14, 15, 18, 15, 13, 20, 18, 16, 18, 23, 21, 20, 24, 30, 50,
- 33, 30, 28, 28, 30, 61, 44, 46, 36, 50, 73, 64, 76, 75, 71, 64,
- 70, 69, 80, 90, 115, 98, 80, 85, 109, 86, 69, 70, 100, 136, 101,
- 109,
- 119, 123, 129, 130, 129, 78, 96, 141, 151, 140, 125, 150, 115,
- 126, 129, 124,
-1, /* quantization table part 2 */
- 21, 23, 23, 30, 26, 30, 59, 33, 33, 59, 124, 83, 70, 83, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124,
- 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
- 124, 124, 124},
-/* index 1 - Q50 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
- 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
- 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81, 87,
- 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92, 101,
- 103, 99,
-1,
- 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99},
-/* index 2 Q60 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 13, 9, 10, 11, 10, 8, 13, 11, 10, 11, 14, 14, 13, 15, 19, 32,
- 21, 19, 18, 18, 19, 39, 28, 30, 23, 32, 46, 41, 49, 48, 46, 41,
- 45, 44, 51, 58, 74, 62, 51, 54, 70, 55, 44, 45, 64, 87, 65, 70,
- 76, 78, 82, 83, 82, 50, 62, 90, 97, 90, 80, 96, 74, 81, 82, 79,
-1,
- 14, 14, 14, 19, 17, 19, 38, 21, 21, 38, 79, 53, 45, 53, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79},
-/* index 3 - Q70 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 10, 7, 7, 8, 7, 6, 10, 8, 8, 8, 11, 10, 10, 11, 14, 24,
- 16, 14, 13, 13, 14, 29, 21, 22, 17, 24, 35, 31, 37, 36, 34, 31,
- 34, 33, 38, 43, 55, 47, 38, 41, 52, 41, 33, 34, 48, 65, 49, 52,
- 57, 59, 62, 62, 62, 37, 46, 68, 73, 67, 60, 72, 55, 61, 62, 59,
-1,
- 10, 11, 11, 14, 13, 14, 28, 16, 16, 28, 59, 40, 34, 40, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
- 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59},
-/* index 4 - Q80 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 6, 4, 5, 6, 5, 4, 6, 6, 5, 6, 7, 7, 6, 8, 10, 16,
- 10, 10, 9, 9, 10, 20, 14, 15, 12, 16, 23, 20, 24, 24, 23, 20,
- 22, 22, 26, 29, 37, 31, 26, 27, 35, 28, 22, 22, 32, 44, 32, 35,
- 38, 39, 41, 42, 41, 25, 31, 45, 48, 45, 40, 48, 37, 40, 41, 40,
-1,
- 7, 7, 7, 10, 8, 10, 19, 10, 10, 19, 40, 26, 22, 26, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
- 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40},
-/* index 5 - Q85 */
- {
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 5, 3, 4, 4, 4, 3, 5, 4, 4, 4, 5, 5, 5, 6, 7, 12,
- 8, 7, 7, 7, 7, 15, 11, 11, 9, 12, 17, 15, 18, 18, 17, 15,
- 17, 17, 19, 22, 28, 23, 19, 20, 26, 21, 17, 17, 24, 33, 24, 26,
- 29, 29, 31, 31, 31, 19, 23, 34, 36, 34, 30, 36, 28, 30, 31, 30,
-1,
- 5, 5, 5, 7, 6, 7, 14, 8, 8, 14, 30, 20, 17, 20, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30,
- 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30},
-/* index 6 - 86 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 0x04, 0x03, 0x03, 0x04, 0x03, 0x03, 0x04, 0x04,
- 0x04, 0x04, 0x05, 0x05, 0x04, 0x05, 0x07, 0x0B,
- 0x07, 0x07, 0x06, 0x06, 0x07, 0x0E, 0x0A, 0x0A,
- 0x08, 0x0B, 0x10, 0x0E, 0x11, 0x11, 0x10, 0x0E,
- 0x10, 0x0F, 0x12, 0x14, 0x1A, 0x16, 0x12, 0x13,
- 0x18, 0x13, 0x0F, 0x10, 0x16, 0x1F, 0x17, 0x18,
- 0x1B, 0x1B, 0x1D, 0x1D, 0x1D, 0x11, 0x16, 0x20,
- 0x22, 0x1F, 0x1C, 0x22, 0x1A, 0x1C, 0x1D, 0x1C,
-1,
- 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x0D, 0x07,
- 0x07, 0x0D, 0x1C, 0x12, 0x10, 0x12, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
- },
-/* index 7 - 88 */
-{
- 0xff, 0xd8,
- 0xff, 0xdb, 0x00, 0x84, /* DQT */
-0,
- 0x04, 0x03, 0x03, 0x03, 0x03, 0x02, 0x04, 0x03,
- 0x03, 0x03, 0x04, 0x04, 0x04, 0x05, 0x06, 0x0A,
- 0x06, 0x06, 0x05, 0x05, 0x06, 0x0C, 0x08, 0x09,
- 0x07, 0x0A, 0x0E, 0x0C, 0x0F, 0x0E, 0x0E, 0x0C,
- 0x0D, 0x0D, 0x0F, 0x11, 0x16, 0x13, 0x0F, 0x10,
- 0x15, 0x11, 0x0D, 0x0D, 0x13, 0x1A, 0x13, 0x15,
- 0x17, 0x18, 0x19, 0x19, 0x19, 0x0F, 0x12, 0x1B,
- 0x1D, 0x1B, 0x18, 0x1D, 0x16, 0x18, 0x19, 0x18,
-1,
- 0x04, 0x04, 0x04, 0x06, 0x05, 0x06, 0x0B, 0x06,
- 0x06, 0x0B, 0x18, 0x10, 0x0D, 0x10, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
-},
-/* index 8 - ?? */
-{
- 0xff, 0xd8,
+
+/* quantization table quality 50% */
0xff, 0xdb, 0x00, 0x84, /* DQT */
0,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x05,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x06, 0x04, 0x05,
- 0x04, 0x05, 0x07, 0x06, 0x08, 0x08, 0x07, 0x06,
- 0x07, 0x07, 0x08, 0x09, 0x0C, 0x0A, 0x08, 0x09,
- 0x0B, 0x09, 0x07, 0x07, 0x0A, 0x0E, 0x0A, 0x0B,
- 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x08, 0x0A, 0x0E,
- 0x0F, 0x0E, 0x0D, 0x0F, 0x0C, 0x0D, 0x0D, 0x0C,
+#define JPEG_QT0_OFFSET 7
+ 0x10, 0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e,
+ 0x0d, 0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28,
+ 0x1a, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25,
+ 0x1d, 0x28, 0x3a, 0x33, 0x3d, 0x3c, 0x39, 0x33,
+ 0x38, 0x37, 0x40, 0x48, 0x5c, 0x4e, 0x40, 0x44,
+ 0x57, 0x45, 0x37, 0x38, 0x50, 0x6d, 0x51, 0x57,
+ 0x5f, 0x62, 0x67, 0x68, 0x67, 0x3e, 0x4d, 0x71,
+ 0x79, 0x70, 0x64, 0x78, 0x5c, 0x65, 0x67, 0x63,
1,
- 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x06, 0x03,
- 0x03, 0x06, 0x0C, 0x08, 0x07, 0x08, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C,
- 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C
-}
-};
+#define JPEG_QT1_OFFSET 72
+ 0x11, 0x12, 0x12, 0x18, 0x15, 0x18, 0x2f, 0x1a,
+ 0x1a, 0x2f, 0x63, 0x42, 0x38, 0x42, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
+ 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
-/* huffman table + start of SOF0 */
-static unsigned char huffman[] = {
+/* huffman table */
0xff, 0xc4, 0x01, 0xa2,
0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -244,58 +112,57 @@ static unsigned char huffman[] = {
0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
#ifdef CONEX_CAM
/* the Conexant frames start with SOF0 */
+#define JPEG_HDR_SZ 556
#else
0xff, 0xc0, 0x00, 0x11, /* SOF0 (start of frame 0 */
0x08, /* data precision */
-#endif
-};
-
-#ifndef CONEX_CAM
-/* variable part:
- * 0x01, 0xe0, height
- * 0x02, 0x80, width
- * 0x03, component number
- * 0x01,
- * 0x21, samples Y
- */
-
-/* end of header */
-static unsigned char eoh[] = {
+#define JPEG_HEIGHT_OFFSET 561
+ 0x01, 0xe0, /* height */
+ 0x02, 0x80, /* width */
+ 0x03, /* component number */
+ 0x01,
+ 0x21, /* samples Y */
0x00, /* quant Y */
0x02, 0x11, 0x01, /* samples CbCr - quant CbCr */
0x03, 0x11, 0x01,
0xff, 0xda, 0x00, 0x0c, /* SOS (start of scan) */
0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00
-};
+#define JPEG_HDR_SZ 589
#endif
+};
-/* -- output the JPEG header -- */
-static void jpeg_put_header(struct gspca_dev *gspca_dev,
- struct gspca_frame *frame,
- int qindex,
- int samplesY)
+/* define the JPEG header */
+static void jpeg_define(u8 *jpeg_hdr,
+ int height,
+ int width,
+ int samplesY)
{
+ memcpy(jpeg_hdr, jpeg_head, sizeof jpeg_head);
#ifndef CONEX_CAM
- unsigned char tmpbuf[8];
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 0] = height >> 8;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 1] = height & 0xff;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 2] = width >> 8;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 3] = width & 0xff;
+ jpeg_hdr[JPEG_HEIGHT_OFFSET + 6] = samplesY;
#endif
+}
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
- (unsigned char *) quant[qindex], sizeof quant[0]);
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- (unsigned char *) huffman, sizeof huffman);
-#ifndef CONEX_CAM
- tmpbuf[0] = gspca_dev->height >> 8;
- tmpbuf[1] = gspca_dev->height & 0xff;
- tmpbuf[2] = gspca_dev->width >> 8;
- tmpbuf[3] = gspca_dev->width & 0xff;
- tmpbuf[4] = 0x03; /* component number */
- tmpbuf[5] = 0x01; /* first component */
- tmpbuf[6] = samplesY;
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- tmpbuf, 7);
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- eoh, sizeof eoh);
-#endif
+/* set the JPEG quality */
+static void jpeg_set_qual(u8 *jpeg_hdr,
+ int quality)
+{
+ int i, sc;
+
+ if (quality < 50)
+ sc = 5000 / quality;
+ else
+ sc = 200 - quality * 2;
+ for (i = 0; i < 64; i++) {
+ jpeg_hdr[JPEG_QT0_OFFSET + i] =
+ (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+ jpeg_hdr[JPEG_QT1_OFFSET + i] =
+ (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+ }
}
#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index ed906fe3128..b35e4838a6e 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -332,7 +332,6 @@ static int m5602_configure(struct gspca_dev *gspca_dev,
int err;
cam = &gspca_dev->cam;
- cam->epaddr = M5602_ISOC_ENDPOINT_ADDR;
sd->desc = &sd_desc;
if (dump_bridge)
@@ -374,8 +373,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init mod_m5602_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mars.c b/drivers/media/video/gspca/mars.c
index 3d2090e67a6..75e8d14e4ac 100644
--- a/drivers/media/video/gspca/mars.c
+++ b/drivers/media/video/gspca/mars.c
@@ -32,17 +32,91 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- char qindex;
+ u8 brightness;
+ u8 colors;
+ u8 gamma;
+ u8 sharpness;
+ u8 quality;
+#define QUALITY_MIN 40
+#define QUALITY_MAX 70
+#define QUALITY_DEF 50
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
+
static struct ctrl sd_ctrls[] = {
+ {
+ {
+ .id = V4L2_CID_BRIGHTNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Brightness",
+ .minimum = 0,
+ .maximum = 30,
+ .step = 1,
+#define BRIGHTNESS_DEF 15
+ .default_value = BRIGHTNESS_DEF,
+ },
+ .set = sd_setbrightness,
+ .get = sd_getbrightness,
+ },
+ {
+ {
+ .id = V4L2_CID_SATURATION,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Color",
+ .minimum = 1,
+ .maximum = 255,
+ .step = 1,
+#define COLOR_DEF 200
+ .default_value = COLOR_DEF,
+ },
+ .set = sd_setcolors,
+ .get = sd_getcolors,
+ },
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 3,
+ .step = 1,
+#define GAMMA_DEF 1
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
+ {
+ {
+ .id = V4L2_CID_SHARPNESS,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Sharpness",
+ .minimum = 0,
+ .maximum = 2,
+ .step = 1,
+#define SHARPNESS_DEF 1
+ .default_value = SHARPNESS_DEF,
+ },
+ .set = sd_setsharpness,
+ .get = sd_getsharpness,
+ },
};
static const struct v4l2_pix_format vga_mode[] = {
{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 320,
- .sizeimage = 320 * 240 * 3 / 8 + 589,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 2},
{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
@@ -52,65 +126,45 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 1},
};
-/* MI Register table //elvis */
-enum {
- REG_HW_MI_0,
- REG_HW_MI_1,
- REG_HW_MI_2,
- REG_HW_MI_3,
- REG_HW_MI_4,
- REG_HW_MI_5,
- REG_HW_MI_6,
- REG_HW_MI_7,
- REG_HW_MI_9 = 0x09,
- REG_HW_MI_B = 0x0B,
- REG_HW_MI_C,
- REG_HW_MI_D,
- REG_HW_MI_1E = 0x1E,
- REG_HW_MI_20 = 0x20,
- REG_HW_MI_2B = 0x2B,
- REG_HW_MI_2C,
- REG_HW_MI_2D,
- REG_HW_MI_2E,
- REG_HW_MI_35 = 0x35,
- REG_HW_MI_5F = 0x5f,
- REG_HW_MI_60,
- REG_HW_MI_61,
- REG_HW_MI_62,
- REG_HW_MI_63,
- REG_HW_MI_64,
- REG_HW_MI_F1 = 0xf1,
- ATTR_TOTAL_MI_REG = 0xf2
+static const __u8 mi_data[0x20] = {
+/* 01 02 03 04 05 06 07 08 */
+ 0x48, 0x22, 0x01, 0x47, 0x10, 0x00, 0x00, 0x00,
+/* 09 0a 0b 0c 0d 0e 0f 10 */
+ 0x00, 0x01, 0x30, 0x01, 0x30, 0x01, 0x30, 0x01,
+/* 11 12 13 14 15 16 17 18 */
+ 0x30, 0x00, 0x04, 0x00, 0x06, 0x01, 0xe2, 0x02,
+/* 19 1a 1b 1c 1d 1e 1f 20 */
+ 0x82, 0x00, 0x20, 0x17, 0x80, 0x08, 0x0c, 0x00
};
-/* the bytes to write are in gspca_dev->usb_buf */
+/* write <len> bytes from gspca_dev->usb_buf */
static int reg_w(struct gspca_dev *gspca_dev,
- __u16 index, int len)
+ int len)
{
- int rc;
-
- rc = usb_control_msg(gspca_dev->dev,
- usb_sndbulkpipe(gspca_dev->dev, 4),
- 0x12,
- 0xc8, /* ?? */
- 0, /* value */
- index, gspca_dev->usb_buf, len, 500);
- if (rc < 0)
- PDEBUG(D_ERR, "reg write [%02x] error %d", index, rc);
- return rc;
+ int alen, ret;
+
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf,
+ len,
+ &alen,
+ 500); /* timeout in milliseconds */
+ if (ret < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], ret);
+ return ret;
}
-static void bulk_w(struct gspca_dev *gspca_dev,
- __u16 *pch,
- __u16 Address)
+static void mi_w(struct gspca_dev *gspca_dev,
+ u8 addr,
+ u8 value)
{
gspca_dev->usb_buf[0] = 0x1f;
gspca_dev->usb_buf[1] = 0; /* control byte */
- gspca_dev->usb_buf[2] = Address;
- gspca_dev->usb_buf[3] = *pch >> 8; /* high byte */
- gspca_dev->usb_buf[4] = *pch; /* low byte */
+ gspca_dev->usb_buf[2] = addr;
+ gspca_dev->usb_buf[3] = value;
- reg_w(gspca_dev, Address, 5);
+ reg_w(gspca_dev, 4);
}
/* this function is called at probe time */
@@ -121,10 +175,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
- sd->qindex = 1; /* set the quantization table */
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->colors = COLOR_DEF;
+ sd->gamma = GAMMA_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ sd->quality = QUALITY_DEF;
+ gspca_dev->nbalt = 9; /* use the altsetting 08 */
return 0;
}
@@ -136,24 +194,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int err_code;
- __u8 *data;
- __u16 *MI_buf;
- int h_size, v_size;
- int intpipe;
-
- PDEBUG(D_STREAM, "camera start, iface %d, alt 8", gspca_dev->iface);
- err_code = usb_set_interface(gspca_dev->dev, gspca_dev->iface, 8);
- if (err_code < 0) {
- PDEBUG(D_ERR|D_STREAM, "Set packet size: set interface error");
- return err_code;
- }
+ u8 *data;
+ int i;
+
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
data = gspca_dev->usb_buf;
+
data[0] = 0x01; /* address */
data[1] = 0x01;
-
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -163,30 +219,28 @@ static int sd_start(struct gspca_dev *gspca_dev)
data[0] = 0x00; /* address */
data[1] = 0x0c | 0x01; /* reg 0 */
data[2] = 0x01; /* reg 1 */
- h_size = gspca_dev->width;
- v_size = gspca_dev->height;
- data[3] = h_size / 8; /* h_size , reg 2 */
- data[4] = v_size / 8; /* v_size , reg 3 */
+ data[3] = gspca_dev->width / 8; /* h_size , reg 2 */
+ data[4] = gspca_dev->height / 8; /* v_size , reg 3 */
data[5] = 0x30; /* reg 4, MI, PAS5101 :
* 0x30 for 24mhz , 0x28 for 12mhz */
- data[6] = 4; /* reg 5, H start */
- data[7] = 0xc0; /* reg 6, gamma 1.5 */
- data[8] = 3; /* reg 7, V start */
+ data[6] = 0x02; /* reg 5, H start - was 0x04 */
+ data[7] = sd->gamma * 0x40; /* reg 0x06: gamma */
+ data[8] = 0x01; /* reg 7, V start - was 0x03 */
/* if (h_size == 320 ) */
/* data[9]= 0x56; * reg 8, 24MHz, 2:1 scale down */
/* else */
data[9] = 0x52; /* reg 8, 24MHz, no scale down */
- data[10] = 0x5d; /* reg 9, I2C device address
- * [for PAS5101 (0x40)] [for MI (0x5d)] */
+/*jfm: from win trace*/
+ data[10] = 0x18;
- err_code = reg_w(gspca_dev, data[0], 11);
+ err_code = reg_w(gspca_dev, 11);
if (err_code < 0)
return err_code;
data[0] = 0x23; /* address */
data[1] = 0x09; /* reg 35, append frame header */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
@@ -197,137 +251,57 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* else */
data[1] = 50; /* 50 reg 60, pc-cam frame size
* (unit: 4KB) 200KB */
- err_code = reg_w(gspca_dev, data[0], 2);
+ err_code = reg_w(gspca_dev, 2);
if (err_code < 0)
return err_code;
- if (0) { /* fixed dark-gain */
- data[1] = 0; /* reg 94, Y Gain (1.75) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x3f; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- data[4] = 0; /* reg 97, set fixed dark level */
- data[5] = 0; /* reg 98, don't care */
- } else { /* auto dark-gain */
- data[1] = 0; /* reg 94, Y Gain (auto) */
- data[2] = 0; /* reg 95, UV Gain (1.75) */
- data[3] = 0x78; /* reg 96, Y Gain/UV Gain/disable
- * auto dark-gain */
- switch (gspca_dev->width) {
-/* case 1280: */
-/* data[4] = 154;
- * reg 97, %3 shadow point (unit: 256 pixel) */
-/* data[5] = 51;
- * reg 98, %1 highlight point
- * (uint: 256 pixel) */
-/* break; */
- default:
-/* case 640: */
- data[4] = 36; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 12; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- case 320:
- data[4] = 9; /* reg 97, %3 shadow point
- * (unit: 256 pixel) */
- data[5] = 3; /* reg 98, %1 highlight point
- * (uint: 256 pixel) */
- break;
- }
- }
/* auto dark-gain */
data[0] = 0x5e; /* address */
-
- err_code = reg_w(gspca_dev, data[0], 6);
+ data[1] = 0; /* reg 94, Y Gain (auto) */
+/*jfm: from win trace*/
+ /* reg 0x5f/0x60 (LE) = saturation */
+ /* h (60): xxxx x100
+ * l (5f): xxxx x000 */
+ data[2] = sd->colors << 3;
+ data[3] = ((sd->colors >> 2) & 0xf8) | 0x04;
+ data[4] = sd->brightness; /* reg 0x61 = brightness */
+ data[5] = 0x00;
+
+ err_code = reg_w(gspca_dev, 6);
if (err_code < 0)
return err_code;
data[0] = 0x67;
- data[1] = 0x13; /* reg 103, first pixel B, disable sharpness */
- err_code = reg_w(gspca_dev, data[0], 2);
+/*jfm: from win trace*/
+ data[1] = sd->sharpness * 4 + 3;
+ data[2] = 0x14;
+ err_code = reg_w(gspca_dev, 3);
if (err_code < 0)
return err_code;
- /*
- * initialize the value of MI sensor...
- */
- MI_buf = kzalloc(ATTR_TOTAL_MI_REG * sizeof *MI_buf, GFP_KERNEL);
- MI_buf[REG_HW_MI_1] = 0x000a;
- MI_buf[REG_HW_MI_2] = 0x000c;
- MI_buf[REG_HW_MI_3] = 0x0405;
- MI_buf[REG_HW_MI_4] = 0x0507;
- /* mi_Attr_Reg_[REG_HW_MI_5] = 0x01ff;//13 */
- MI_buf[REG_HW_MI_5] = 0x0013; /* 13 */
- MI_buf[REG_HW_MI_6] = 0x001f; /* vertical blanking */
- /* mi_Attr_Reg_[REG_HW_MI_6] = 0x0400; // vertical blanking */
- MI_buf[REG_HW_MI_7] = 0x0002;
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x015f; */
- /* mi_Attr_Reg_[REG_HW_MI_9] = 0x030f; */
- MI_buf[REG_HW_MI_9] = 0x0374;
- MI_buf[REG_HW_MI_B] = 0x0000;
- MI_buf[REG_HW_MI_C] = 0x0000;
- MI_buf[REG_HW_MI_D] = 0x0000;
- MI_buf[REG_HW_MI_1E] = 0x8000;
-/* mi_Attr_Reg_[REG_HW_MI_20] = 0x1104; */
- MI_buf[REG_HW_MI_20] = 0x1104; /* 0x111c; */
- MI_buf[REG_HW_MI_2B] = 0x0008;
-/* mi_Attr_Reg_[REG_HW_MI_2C] = 0x000f; */
- MI_buf[REG_HW_MI_2C] = 0x001f; /* lita suggest */
- MI_buf[REG_HW_MI_2D] = 0x0008;
- MI_buf[REG_HW_MI_2E] = 0x0008;
- MI_buf[REG_HW_MI_35] = 0x0051;
- MI_buf[REG_HW_MI_5F] = 0x0904; /* fail to write */
- MI_buf[REG_HW_MI_60] = 0x0000;
- MI_buf[REG_HW_MI_61] = 0x0000;
- MI_buf[REG_HW_MI_62] = 0x0498;
- MI_buf[REG_HW_MI_63] = 0x0000;
- MI_buf[REG_HW_MI_64] = 0x0000;
- MI_buf[REG_HW_MI_F1] = 0x0001;
- /* changing while setting up the different value of dx/dy */
-
- if (gspca_dev->width != 1280) {
- MI_buf[0x01] = 0x010a;
- MI_buf[0x02] = 0x014c;
- MI_buf[0x03] = 0x01e5;
- MI_buf[0x04] = 0x0287;
- }
- MI_buf[0x20] = 0x1104;
-
- bulk_w(gspca_dev, MI_buf + 1, 1);
- bulk_w(gspca_dev, MI_buf + 2, 2);
- bulk_w(gspca_dev, MI_buf + 3, 3);
- bulk_w(gspca_dev, MI_buf + 4, 4);
- bulk_w(gspca_dev, MI_buf + 5, 5);
- bulk_w(gspca_dev, MI_buf + 6, 6);
- bulk_w(gspca_dev, MI_buf + 7, 7);
- bulk_w(gspca_dev, MI_buf + 9, 9);
- bulk_w(gspca_dev, MI_buf + 0x0b, 0x0b);
- bulk_w(gspca_dev, MI_buf + 0x0c, 0x0c);
- bulk_w(gspca_dev, MI_buf + 0x0d, 0x0d);
- bulk_w(gspca_dev, MI_buf + 0x1e, 0x1e);
- bulk_w(gspca_dev, MI_buf + 0x20, 0x20);
- bulk_w(gspca_dev, MI_buf + 0x2b, 0x2b);
- bulk_w(gspca_dev, MI_buf + 0x2c, 0x2c);
- bulk_w(gspca_dev, MI_buf + 0x2d, 0x2d);
- bulk_w(gspca_dev, MI_buf + 0x2e, 0x2e);
- bulk_w(gspca_dev, MI_buf + 0x35, 0x35);
- bulk_w(gspca_dev, MI_buf + 0x5f, 0x5f);
- bulk_w(gspca_dev, MI_buf + 0x60, 0x60);
- bulk_w(gspca_dev, MI_buf + 0x61, 0x61);
- bulk_w(gspca_dev, MI_buf + 0x62, 0x62);
- bulk_w(gspca_dev, MI_buf + 0x63, 0x63);
- bulk_w(gspca_dev, MI_buf + 0x64, 0x64);
- bulk_w(gspca_dev, MI_buf + 0xf1, 0xf1);
- kfree(MI_buf);
-
- intpipe = usb_sndintpipe(gspca_dev->dev, 0);
- err_code = usb_clear_halt(gspca_dev->dev, intpipe);
+ data[0] = 0x69;
+ data[1] = 0x2f;
+ data[2] = 0x28;
+ data[3] = 0x42;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x63;
+ data[1] = 0x07;
+ err_code = reg_w(gspca_dev, 2);
+/*jfm: win trace - many writes here to reg 0x64*/
+ if (err_code < 0)
+ return err_code;
+
+ /* initialize the MI sensor */
+ for (i = 0; i < sizeof mi_data; i++)
+ mi_w(gspca_dev, i + 1, mi_data[i]);
data[0] = 0x00;
data[1] = 0x4d; /* ISOC transfering enable... */
- reg_w(gspca_dev, data[0], 2);
- return err_code;
+ reg_w(gspca_dev, 2);
+ return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
@@ -336,11 +310,18 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0] = 1;
gspca_dev->usb_buf[1] = 0;
- result = reg_w(gspca_dev, gspca_dev->usb_buf[0], 2);
+ result = reg_w(gspca_dev, 2);
if (result < 0)
PDEBUG(D_ERR, "Camera Stop failed");
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -363,16 +344,16 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
|| data[5 + p] == 0x65
|| data[5 + p] == 0x66
|| data[5 + p] == 0x67) {
- PDEBUG(D_PACK, "sof offset: %d leng: %d",
+ PDEBUG(D_PACK, "sof offset: %d len: %d",
p, len);
frame = gspca_frame_add(gspca_dev, LAST_PACKET,
- frame, data, 0);
+ frame, data, p);
/* put the JPEG header */
- jpeg_put_header(gspca_dev, frame,
- sd->qindex, 0x21);
- data += 16;
- len -= 16;
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+ data += p + 16;
+ len -= p + 16;
break;
}
}
@@ -380,6 +361,121 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
+static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->brightness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x61;
+ gspca_dev->usb_buf[1] = val;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->brightness;
+ return 0;
+}
+
+static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->colors = val;
+ if (gspca_dev->streaming) {
+
+ /* see sd_start */
+ gspca_dev->usb_buf[0] = 0x5f;
+ gspca_dev->usb_buf[1] = sd->colors << 3;
+ gspca_dev->usb_buf[2] = ((sd->colors >> 2) & 0xf8) | 0x04;
+ reg_w(gspca_dev, 3);
+ }
+ return 0;
+}
+
+static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->colors;
+ return 0;
+}
+
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x06;
+ gspca_dev->usb_buf[1] = val * 0x40;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
+static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->sharpness = val;
+ if (gspca_dev->streaming) {
+ gspca_dev->usb_buf[0] = 0x67;
+ gspca_dev->usb_buf[1] = val * 4 + 3;
+ reg_w(gspca_dev, 2);
+ }
+ return 0;
+}
+
+static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->sharpness;
+ return 0;
+}
+
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -389,7 +485,10 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -421,8 +520,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/mr97310a.c b/drivers/media/video/gspca/mr97310a.c
new file mode 100644
index 00000000000..2a901a4a6f0
--- /dev/null
+++ b/drivers/media/video/gspca/mr97310a.c
@@ -0,0 +1,362 @@
+/*
+ * Mars MR97310A library
+ *
+ * Copyright (C) 2009 Kyle Guinn <elyk03@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 MODULE_NAME "mr97310a"
+
+#include "gspca.h"
+
+MODULE_AUTHOR("Kyle Guinn <elyk03@gmail.com>");
+MODULE_DESCRIPTION("GSPCA/Mars-Semi MR97310A USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* specific webcam descriptor */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ u8 sof_read;
+};
+
+/* V4L2 controls supported by the driver */
+static struct ctrl sd_ctrls[] = {
+};
+
+static const struct v4l2_pix_format vga_mode[] = {
+ {160, 120, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+ {176, 144, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 176,
+ .sizeimage = 176 * 144,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 3},
+ {320, 240, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+ {352, 288, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 352,
+ .sizeimage = 352 * 288,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1},
+ {640, 480, V4L2_PIX_FMT_MR97310A, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+};
+
+/* the bytes to write are in gspca_dev->usb_buf */
+static int reg_w(struct gspca_dev *gspca_dev, int len)
+{
+ int rc;
+
+ rc = usb_bulk_msg(gspca_dev->dev,
+ usb_sndbulkpipe(gspca_dev->dev, 4),
+ gspca_dev->usb_buf, len, NULL, 500);
+ if (rc < 0)
+ PDEBUG(D_ERR, "reg write [%02x] error %d",
+ gspca_dev->usb_buf[0], rc);
+ return rc;
+}
+
+/* this function is called at probe time */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam;
+
+ cam = &gspca_dev->cam;
+ cam->cam_mode = vga_mode;
+ cam->nmodes = ARRAY_SIZE(vga_mode);
+ return 0;
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ return 0;
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ __u8 *data = gspca_dev->usb_buf;
+ int err_code;
+
+ sd->sof_read = 0;
+
+ /* Note: register descriptions guessed from MR97113A driver */
+
+ data[0] = 0x01;
+ data[1] = 0x01;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x0d;
+ data[2] = 0x01;
+ data[5] = 0x2b;
+ data[7] = 0x00;
+ data[9] = 0x50; /* reg 8, no scale down */
+ data[10] = 0xc0;
+
+ switch (gspca_dev->width) {
+ case 160:
+ data[9] |= 0x0c; /* reg 8, 4:1 scale down */
+ /* fall thru */
+ case 320:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 640:
+ default:
+ data[3] = 0x50; /* reg 2, H size */
+ data[4] = 0x78; /* reg 3, V size */
+ data[6] = 0x04; /* reg 5, H start */
+ data[8] = 0x03; /* reg 7, V start */
+ break;
+
+ case 176:
+ data[9] |= 0x04; /* reg 8, 2:1 scale down */
+ /* fall thru */
+ case 352:
+ data[3] = 0x2c; /* reg 2, H size */
+ data[4] = 0x48; /* reg 3, V size */
+ data[6] = 0x94; /* reg 5, H start */
+ data[8] = 0x63; /* reg 7, V start */
+ break;
+ }
+
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x0a;
+ data[1] = 0x80;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x14;
+ data[1] = 0x0a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1b;
+ data[1] = 0x00;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x15;
+ data[1] = 0x16;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x16;
+ data[1] = 0x10;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x17;
+ data[1] = 0x3a;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x18;
+ data[1] = 0x68;
+ err_code = reg_w(gspca_dev, 2);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x02;
+ data[3] = 0x06;
+ data[4] = 0x59;
+ data[5] = 0x0c;
+ data[6] = 0x16;
+ data[7] = 0x00;
+ data[8] = 0x07;
+ data[9] = 0x00;
+ data[10] = 0x01;
+ err_code = reg_w(gspca_dev, 11);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x0a;
+ data[3] = 0x00;
+ data[4] = 0x01;
+ data[5] = 0x00;
+ data[6] = 0x00;
+ data[7] = 0x01;
+ data[8] = 0x00;
+ data[9] = 0x0a;
+ err_code = reg_w(gspca_dev, 10);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x00;
+ data[2] = 0x12;
+ data[3] = 0x00;
+ data[4] = 0x63;
+ data[5] = 0x00;
+ data[6] = 0x70;
+ data[7] = 0x00;
+ data[8] = 0x00;
+ err_code = reg_w(gspca_dev, 9);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x1f;
+ data[1] = 0x04;
+ data[2] = 0x11;
+ data[3] = 0x01;
+ err_code = reg_w(gspca_dev, 4);
+ if (err_code < 0)
+ return err_code;
+
+ data[0] = 0x00;
+ data[1] = 0x4d; /* ISOC transfering enable... */
+ err_code = reg_w(gspca_dev, 2);
+ return err_code;
+}
+
+static void sd_stopN(struct gspca_dev *gspca_dev)
+{
+ int result;
+
+ gspca_dev->usb_buf[0] = 1;
+ gspca_dev->usb_buf[1] = 0;
+ result = reg_w(gspca_dev, 2);
+ if (result < 0)
+ PDEBUG(D_ERR, "Camera Stop failed");
+}
+
+/* Include pac common sof detection functions */
+#include "pac_common.h"
+
+static void sd_pkt_scan(struct gspca_dev *gspca_dev,
+ struct gspca_frame *frame, /* target */
+ __u8 *data, /* isoc packet */
+ int len) /* iso packet length */
+{
+ unsigned char *sof;
+
+ sof = pac_find_sof(gspca_dev, data, len);
+ if (sof) {
+ int n;
+
+ /* finish decoding current frame */
+ n = sof - data;
+ if (n > sizeof pac_sof_marker)
+ n -= sizeof pac_sof_marker;
+ else
+ n = 0;
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ data, n);
+ /* Start next frame. */
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ pac_sof_marker, sizeof pac_sof_marker);
+ len -= sof - data;
+ data = sof;
+ }
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
+}
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .ctrls = sd_ctrls,
+ .nctrls = ARRAY_SIZE(sd_ctrls),
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stopN = sd_stopN,
+ .pkt_scan = sd_pkt_scan,
+};
+
+/* -- module initialisation -- */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x08ca, 0x0111)},
+ {}
+};
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ if (usb_register(&sd_driver) < 0)
+ return -1;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index ee232956c81..1fff37b7989 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1360,7 +1360,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = OV511_ENDPOINT_ADDRESS;
if (!sd->sif) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -2177,8 +2176,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 3bf15e40169..19e0bc60de1 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,7 +1,8 @@
/*
- * ov534/ov772x gspca driver
+ * ov534 gspca driver
* Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
* Copyright (C) 2008 Jim Paris <jim@jtan.com>
+ * Copyright (C) 2009 Jean-Francois Moine http://moinejf.free.fr
*
* Based on a prototype written by Mark Ferrell <majortrips@gmail.com>
* USB protocol reverse engineered by Jim Paris <jim@jtan.com>
@@ -26,7 +27,7 @@
#include "gspca.h"
-#define OV534_REG_ADDRESS 0xf1 /* ? */
+#define OV534_REG_ADDRESS 0xf1 /* sensor address */
#define OV534_REG_SUBADDR 0xf2
#define OV534_REG_WRITE 0xf3
#define OV534_REG_READ 0xf4
@@ -46,9 +47,13 @@ MODULE_LICENSE("GPL");
/* specific webcam descriptor */
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- __u32 last_fid;
__u32 last_pts;
- int frame_rate;
+ u16 last_fid;
+ u8 frame_rate;
+
+ u8 sensor;
+#define SENSOR_OV772X 0
+#define SENSOR_OV965X 1
};
/* V4L2 controls supported by the driver */
@@ -63,114 +68,7 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
-static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
- gspca_dev->usb_buf[0] = val;
- ret = usb_control_msg(udev,
- usb_sndctrlpipe(udev, 0),
- 0x1,
- USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- if (ret < 0)
- PDEBUG(D_ERR, "write failed");
-}
-
-static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- struct usb_device *udev = gspca_dev->dev;
- int ret;
-
- ret = usb_control_msg(udev,
- usb_rcvctrlpipe(udev, 0),
- 0x1,
- USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- 0x0, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
- PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
- if (ret < 0)
- PDEBUG(D_ERR, "read failed");
- return gspca_dev->usb_buf[0];
-}
-
-/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
- * (direction and output)? */
-static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
-{
- u8 data;
-
- PDEBUG(D_CONF, "led status: %d", status);
-
- data = ov534_reg_read(gspca_dev, 0x21);
- data |= 0x80;
- ov534_reg_write(gspca_dev, 0x21, data);
-
- data = ov534_reg_read(gspca_dev, 0x23);
- if (status)
- data |= 0x80;
- else
- data &= ~(0x80);
-
- ov534_reg_write(gspca_dev, 0x23, data);
-}
-
-static int sccb_check_status(struct gspca_dev *gspca_dev)
-{
- u8 data;
- int i;
-
- for (i = 0; i < 5; i++) {
- data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
-
- switch (data) {
- case 0x00:
- return 1;
- case 0x04:
- return 0;
- case 0x03:
- break;
- default:
- PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
- data, i + 1);
- }
- }
- return 0;
-}
-
-static void sccb_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
-{
- PDEBUG(D_USBO, "reg: 0x%04x, val: 0x%02x", reg, val);
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
-
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_write failed");
-}
-
-#ifdef GSPCA_DEBUG
-static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
-{
- ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_read failed 1");
-
- ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
- if (!sccb_check_status(gspca_dev))
- PDEBUG(D_ERR, "sccb_reg_read failed 2");
-
- return ov534_reg_read(gspca_dev, OV534_REG_READ);
-}
-#endif
-
-static const __u8 ov534_reg_initdata[][2] = {
- { 0xe7, 0x3a },
-
- { OV534_REG_ADDRESS, 0x42 }, /* select OV772x sensor */
-
+static const u8 bridge_init_ov722x[][2] = {
{ 0xc2, 0x0c },
{ 0x88, 0xf8 },
{ 0xc3, 0x69 },
@@ -228,7 +126,7 @@ static const __u8 ov534_reg_initdata[][2] = {
{ 0xc2, 0x0c },
};
-static const __u8 ov772x_reg_initdata[][2] = {
+static const u8 sensor_init_ov722x[][2] = {
{ 0x12, 0x80 },
{ 0x11, 0x01 },
@@ -311,6 +209,456 @@ static const __u8 ov772x_reg_initdata[][2] = {
{ 0x0c, 0xd0 }
};
+static const u8 bridge_init_ov965x[][2] = {
+ {0x88, 0xf8},
+ {0x89, 0xff},
+ {0x76, 0x03},
+ {0x92, 0x03},
+ {0x95, 0x10},
+ {0xe2, 0x00},
+ {0xe7, 0x3e},
+ {0x8d, 0x1c},
+ {0x8e, 0x00},
+ {0x8f, 0x00},
+ {0x1f, 0x00},
+ {0xc3, 0xf9},
+ {0x89, 0xff},
+ {0x88, 0xf8},
+ {0x76, 0x03},
+ {0x92, 0x01},
+ {0x93, 0x18},
+ {0x1c, 0x0a},
+ {0x1d, 0x48},
+ {0xc0, 0x50},
+ {0xc1, 0x3c},
+ {0x34, 0x05},
+ {0xc2, 0x0c},
+ {0xc3, 0xf9},
+ {0x34, 0x05},
+ {0xe7, 0x2e},
+ {0x31, 0xf9},
+ {0x35, 0x02},
+ {0xd9, 0x10},
+ {0x25, 0x42},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x[][2] = {
+ {0x12, 0x80}, /* com7 - reset */
+ {0x00, 0x00}, /* gain */
+ {0x01, 0x80}, /* blue */
+ {0x02, 0x80}, /* red */
+ {0x03, 0x1b}, /* vref */
+ {0x04, 0x03}, /* com1 - exposure low bits */
+ {0x0b, 0x57}, /* ver */
+ {0x0e, 0x61}, /* com5 */
+ {0x0f, 0x42}, /* com6 */
+ {0x11, 0x00}, /* clkrc */
+ {0x12, 0x02}, /* com7 */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x14, 0x28}, /* com9 */
+ {0x16, 0x24}, /* rsvd16 */
+ {0x17, 0x1d}, /* hstart*/
+ {0x18, 0xbd}, /* hstop */
+ {0x19, 0x01}, /* vstrt */
+ {0x1a, 0x81}, /* vstop*/
+ {0x1e, 0x04}, /* mvfp */
+ {0x24, 0x3c}, /* aew */
+ {0x25, 0x36}, /* aeb */
+ {0x26, 0x71}, /* vpt */
+ {0x27, 0x08}, /* bbias */
+ {0x28, 0x08}, /* gbbias */
+ {0x29, 0x15}, /* gr com */
+ {0x2a, 0x00},
+ {0x2b, 0x00},
+ {0x2c, 0x08}, /* rbias */
+ {0x32, 0xff}, /* href */
+ {0x33, 0x00}, /* chlf */
+ {0x34, 0x3f}, /* arblm */
+ {0x35, 0x00}, /* rsvd35 */
+ {0x36, 0xf8}, /* rsvd36 */
+ {0x38, 0x72}, /* acom38 */
+ {0x39, 0x57}, /* ofon */
+ {0x3a, 0x80}, /* tslb */
+ {0x3b, 0xc4},
+ {0x3d, 0x99}, /* com13 */
+ {0x3f, 0xc1},
+ {0x40, 0xc0}, /* com15 */
+ {0x41, 0x40}, /* com16 */
+ {0x42, 0xc0},
+ {0x43, 0x0a},
+ {0x44, 0xf0},
+ {0x45, 0x46},
+ {0x46, 0x62},
+ {0x47, 0x2a},
+ {0x48, 0x3c},
+ {0x4a, 0xfc},
+ {0x4b, 0xfc},
+ {0x4c, 0x7f},
+ {0x4d, 0x7f},
+ {0x4e, 0x7f},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0x59, 0x85},
+ {0x5a, 0xa9},
+ {0x5b, 0x64},
+ {0x5c, 0x84},
+ {0x5d, 0x53},
+ {0x5e, 0x0e},
+ {0x5f, 0xf0},
+ {0x60, 0xf0},
+ {0x61, 0xf0},
+ {0x62, 0x00}, /* lcc1 */
+ {0x63, 0x00}, /* lcc2 */
+ {0x64, 0x02}, /* lcc3 */
+ {0x65, 0x16}, /* lcc4 */
+ {0x66, 0x01}, /* lcc5 */
+ {0x69, 0x02}, /* hv */
+ {0x6b, 0x5a}, /* dbvl */
+ {0x6c, 0x04},
+ {0x6d, 0x55},
+ {0x6e, 0x00},
+ {0x6f, 0x9d},
+ {0x70, 0x21},
+ {0x71, 0x78},
+ {0x72, 0x00},
+ {0x73, 0x01},
+ {0x74, 0x3a},
+ {0x75, 0x35},
+ {0x76, 0x01},
+ {0x77, 0x02},
+ {0x7a, 0x12},
+ {0x7b, 0x08},
+ {0x7c, 0x16},
+ {0x7d, 0x30},
+ {0x7e, 0x5e},
+ {0x7f, 0x72},
+ {0x80, 0x82},
+ {0x81, 0x8e},
+ {0x82, 0x9a},
+ {0x83, 0xa4},
+ {0x84, 0xac},
+ {0x85, 0xb8},
+ {0x86, 0xc3},
+ {0x87, 0xd6},
+ {0x88, 0xe6},
+ {0x89, 0xf2},
+ {0x8a, 0x03},
+ {0x8c, 0x89},
+ {0x14, 0x28}, /* com9 */
+ {0x90, 0x7d},
+ {0x91, 0x7b},
+ {0x9d, 0x03},
+ {0x9e, 0x04},
+ {0x9f, 0x7a},
+ {0xa0, 0x79},
+ {0xa1, 0x40}, /* aechm */
+ {0xa4, 0x50},
+ {0xa5, 0x68}, /* com26 */
+ {0xa6, 0x4a},
+ {0xa8, 0xc1}, /* acoma8 */
+ {0xa9, 0xef}, /* acoma9 */
+ {0xaa, 0x92},
+ {0xab, 0x04},
+ {0xac, 0x80},
+ {0xad, 0x80},
+ {0xae, 0x80},
+ {0xaf, 0x80},
+ {0xb2, 0xf2},
+ {0xb3, 0x20},
+ {0xb4, 0x20},
+ {0xb5, 0x00},
+ {0xb6, 0xaf},
+ {0xbb, 0xae},
+ {0xbc, 0x7f},
+ {0xdb, 0x7f},
+ {0xbe, 0x7f},
+ {0xbf, 0x7f},
+ {0xc0, 0xe2},
+ {0xc1, 0xc0},
+ {0xc2, 0x01},
+ {0xc3, 0x4e},
+ {0xc6, 0x85},
+ {0xc7, 0x80},
+ {0xc9, 0xe0},
+ {0xca, 0xe8},
+ {0xcb, 0xf0},
+ {0xcc, 0xd8},
+ {0xcd, 0xf1},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0xff, 0x41}, /* read 41, write ff 00 */
+ {0x41, 0x40}, /* com16 */
+ {0xc5, 0x03},
+ {0x6a, 0x02},
+
+ {0x12, 0x62}, /* com7 - VGA + CIF */
+ {0x36, 0xfa}, /* rsvd36 */
+ {0x69, 0x0a}, /* hv */
+ {0x8c, 0x89}, /* com22 */
+ {0x14, 0x28}, /* com9 */
+ {0x3e, 0x0c},
+ {0x41, 0x40}, /* com16 */
+ {0x72, 0x00},
+ {0x73, 0x00},
+ {0x74, 0x3a},
+ {0x75, 0x35},
+ {0x76, 0x01},
+ {0xc7, 0x80},
+ {0x03, 0x12}, /* vref */
+ {0x17, 0x16}, /* hstart */
+ {0x18, 0x02}, /* hstop */
+ {0x19, 0x01}, /* vstrt */
+ {0x1a, 0x3d}, /* vstop */
+ {0x32, 0xff}, /* href */
+ {0xc0, 0xaa},
+};
+
+static const u8 bridge_init_ov965x_2[][2] = {
+ {0x94, 0xaa},
+ {0xf1, 0x60},
+ {0xe5, 0x04},
+ {0xc0, 0x50},
+ {0xc1, 0x3c},
+ {0x8c, 0x00},
+ {0x8d, 0x1c},
+ {0x34, 0x05},
+
+ {0xc2, 0x0c},
+ {0xc3, 0xf9},
+ {0xda, 0x01},
+ {0x50, 0x00},
+ {0x51, 0xa0},
+ {0x52, 0x3c},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x57, 0x00},
+ {0x5c, 0x00},
+ {0x5a, 0xa0},
+ {0x5b, 0x78},
+ {0x35, 0x02},
+ {0xd9, 0x10},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_init_ov965x_2[][2] = {
+ {0x3b, 0xc4},
+ {0x1e, 0x04}, /* mvfp */
+ {0x13, 0xe0}, /* com8 */
+ {0x00, 0x00}, /* gain */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x11, 0x03}, /* clkrc */
+ {0x6b, 0x5a}, /* dblv */
+ {0x6a, 0x05},
+ {0xc5, 0x07},
+ {0xa2, 0x4b},
+ {0xa3, 0x3e},
+ {0x2d, 0x00},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc0},
+ {0x2d, 0x00},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+ {0x3f, 0x01},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+ {0x4f, 0x98},
+ {0x50, 0x98},
+ {0x51, 0x00},
+ {0x52, 0x28},
+ {0x53, 0x70},
+ {0x54, 0x98},
+ {0x58, 0x1a},
+ {0xff, 0x41}, /* read 41, write ff 00 */
+ {0x41, 0x40}, /* com16 */
+ {0x56, 0x40},
+ {0x55, 0x8f},
+ {0x10, 0x25}, /* aech - exposure high bits */
+ {0xff, 0x13}, /* read 13, write ff 00 */
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+};
+
+static const u8 bridge_start_ov965x[][2] = {
+ {0xc2, 0x4c},
+ {0xc3, 0xf9},
+ {0x50, 0x00},
+ {0x51, 0xa0},
+ {0x52, 0x78},
+ {0x53, 0x00},
+ {0x54, 0x00},
+ {0x55, 0x00},
+ {0x57, 0x00},
+ {0x5c, 0x00},
+ {0x5a, 0x28},
+ {0x5b, 0x1e},
+ {0x35, 0x00},
+ {0xd9, 0x21},
+ {0x94, 0x11},
+};
+
+static const u8 sensor_start_ov965x[][2] = {
+ {0x3b, 0xe4},
+ {0x1e, 0x04}, /* mvfp */
+ {0x13, 0xe0}, /* com8 */
+ {0x00, 0x00},
+ {0x13, 0xe7}, /* com8 - everything (AGC, AWB and AEC) */
+ {0x11, 0x01}, /* clkrc */
+ {0x6b, 0x5a}, /* dblv */
+ {0x6a, 0x02},
+ {0xc5, 0x03},
+ {0xa2, 0x96},
+ {0xa3, 0x7d},
+ {0xff, 0x13}, /* read 13, write ff 00 */
+ {0x13, 0xe7},
+ {0x3a, 0x80},
+ {0xff, 0x42}, /* read 42, write ff 00 */
+ {0x42, 0xc1},
+};
+
+
+static void ov534_reg_write(struct gspca_dev *gspca_dev, u16 reg, u8 val)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int ret;
+
+ PDEBUG(D_USBO, "reg=0x%04x, val=0%02x", reg, val);
+ gspca_dev->usb_buf[0] = val;
+ ret = usb_control_msg(udev,
+ usb_sndctrlpipe(udev, 0),
+ 0x01,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+ if (ret < 0)
+ PDEBUG(D_ERR, "write failed");
+}
+
+static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+ struct usb_device *udev = gspca_dev->dev;
+ int ret;
+
+ ret = usb_control_msg(udev,
+ usb_rcvctrlpipe(udev, 0),
+ 0x01,
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x00, reg, gspca_dev->usb_buf, 1, CTRL_TIMEOUT);
+ PDEBUG(D_USBI, "reg=0x%04x, data=0x%02x", reg, gspca_dev->usb_buf[0]);
+ if (ret < 0)
+ PDEBUG(D_ERR, "read failed");
+ return gspca_dev->usb_buf[0];
+}
+
+/* Two bits control LED: 0x21 bit 7 and 0x23 bit 7.
+ * (direction and output)? */
+static void ov534_set_led(struct gspca_dev *gspca_dev, int status)
+{
+ u8 data;
+
+ PDEBUG(D_CONF, "led status: %d", status);
+
+ data = ov534_reg_read(gspca_dev, 0x21);
+ data |= 0x80;
+ ov534_reg_write(gspca_dev, 0x21, data);
+
+ data = ov534_reg_read(gspca_dev, 0x23);
+ if (status)
+ data |= 0x80;
+ else
+ data &= ~0x80;
+
+ ov534_reg_write(gspca_dev, 0x23, data);
+
+ if (!status) {
+ data = ov534_reg_read(gspca_dev, 0x21);
+ data &= ~0x80;
+ ov534_reg_write(gspca_dev, 0x21, data);
+ }
+}
+
+static int sccb_check_status(struct gspca_dev *gspca_dev)
+{
+ u8 data;
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ data = ov534_reg_read(gspca_dev, OV534_REG_STATUS);
+
+ switch (data) {
+ case 0x00:
+ return 1;
+ case 0x04:
+ return 0;
+ case 0x03:
+ break;
+ default:
+ PDEBUG(D_ERR, "sccb status 0x%02x, attempt %d/5",
+ data, i + 1);
+ }
+ }
+ return 0;
+}
+
+static void sccb_reg_write(struct gspca_dev *gspca_dev, u8 reg, u8 val)
+{
+ PDEBUG(D_USBO, "reg: 0x%02x, val: 0x%02x", reg, val);
+ ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+ ov534_reg_write(gspca_dev, OV534_REG_WRITE, val);
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_3);
+
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_write failed");
+}
+
+static u8 sccb_reg_read(struct gspca_dev *gspca_dev, u16 reg)
+{
+ ov534_reg_write(gspca_dev, OV534_REG_SUBADDR, reg);
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_WRITE_2);
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_read failed 1");
+
+ ov534_reg_write(gspca_dev, OV534_REG_OPERATION, OV534_OP_READ_2);
+ if (!sccb_check_status(gspca_dev))
+ PDEBUG(D_ERR, "sccb_reg_read failed 2");
+
+ return ov534_reg_read(gspca_dev, OV534_REG_READ);
+}
+
+/* output a bridge sequence (reg - val) */
+static void reg_w_array(struct gspca_dev *gspca_dev,
+ const u8 (*data)[2], int len)
+{
+ while (--len >= 0) {
+ ov534_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+ data++;
+ }
+}
+
+/* output a sensor sequence (reg - val) */
+static void sccb_w_array(struct gspca_dev *gspca_dev,
+ const u8 (*data)[2], int len)
+{
+ while (--len >= 0) {
+ if ((*data)[0] != 0xff) {
+ sccb_reg_write(gspca_dev, (*data)[0], (*data)[1]);
+ } else {
+ sccb_reg_read(gspca_dev, (*data)[1]);
+ sccb_reg_write(gspca_dev, 0xff, 0x00);
+ }
+ data++;
+ }
+}
+
/* set framerate */
static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
{
@@ -346,40 +694,17 @@ static void ov534_set_frame_rate(struct gspca_dev *gspca_dev)
PDEBUG(D_PROBE, "frame_rate: %d", fr);
}
-/* setup method */
-static void ov534_setup(struct gspca_dev *gspca_dev)
-{
- int i;
-
- /* Initialize bridge chip */
- for (i = 0; i < ARRAY_SIZE(ov534_reg_initdata); i++)
- ov534_reg_write(gspca_dev, ov534_reg_initdata[i][0],
- ov534_reg_initdata[i][1]);
-
- PDEBUG(D_PROBE, "sensor is ov%02x%02x",
- sccb_reg_read(gspca_dev, 0x0a),
- sccb_reg_read(gspca_dev, 0x0b));
-
- ov534_set_led(gspca_dev, 1);
-
- /* Initialize sensor */
- for (i = 0; i < ARRAY_SIZE(ov772x_reg_initdata); i++)
- sccb_reg_write(gspca_dev, ov772x_reg_initdata[i][0],
- ov772x_reg_initdata[i][1]);
-
- ov534_reg_write(gspca_dev, 0xe0, 0x09);
- ov534_set_led(gspca_dev, 0);
-}
-
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
+ struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
+ sd->sensor = id->driver_info;
+
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -392,26 +717,102 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- ov534_setup(gspca_dev);
- ov534_set_frame_rate(gspca_dev);
+ struct sd *sd = (struct sd *) gspca_dev;
+ u16 sensor_id;
+ static const u8 sensor_addr[2] = {
+ 0x42, /* 0 SENSOR_OV772X */
+ 0x60, /* 1 SENSOR_OV965X */
+ };
+
+ /* reset bridge */
+ ov534_reg_write(gspca_dev, 0xe7, 0x3a);
+ ov534_reg_write(gspca_dev, 0xe0, 0x08);
+ msleep(100);
+
+ /* initialize the sensor address */
+ ov534_reg_write(gspca_dev, OV534_REG_ADDRESS,
+ sensor_addr[sd->sensor]);
+
+ /* reset sensor */
+ sccb_reg_write(gspca_dev, 0x12, 0x80);
+ msleep(10);
+
+ /* probe the sensor */
+ sccb_reg_read(gspca_dev, 0x0a);
+ sensor_id = sccb_reg_read(gspca_dev, 0x0a) << 8;
+ sccb_reg_read(gspca_dev, 0x0b);
+ sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
+ PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
+
+ /* initialize */
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ reg_w_array(gspca_dev, bridge_init_ov722x,
+ ARRAY_SIZE(bridge_init_ov722x));
+ ov534_set_led(gspca_dev, 1);
+ sccb_w_array(gspca_dev, sensor_init_ov722x,
+ ARRAY_SIZE(sensor_init_ov722x));
+ ov534_reg_write(gspca_dev, 0xe0, 0x09);
+ ov534_set_led(gspca_dev, 0);
+ ov534_set_frame_rate(gspca_dev);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ reg_w_array(gspca_dev, bridge_init_ov965x,
+ ARRAY_SIZE(bridge_init_ov965x));
+ sccb_w_array(gspca_dev, sensor_init_ov965x,
+ ARRAY_SIZE(sensor_init_ov965x));
+ reg_w_array(gspca_dev, bridge_init_ov965x_2,
+ ARRAY_SIZE(bridge_init_ov965x_2));
+ sccb_w_array(gspca_dev, sensor_init_ov965x_2,
+ ARRAY_SIZE(sensor_init_ov965x_2));
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ ov534_reg_write(gspca_dev, 0xe0, 0x01);
+ ov534_set_led(gspca_dev, 0);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ }
return 0;
}
static int sd_start(struct gspca_dev *gspca_dev)
{
- /* start streaming data */
- ov534_set_led(gspca_dev, 1);
- ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ struct sd *sd = (struct sd *) gspca_dev;
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ ov534_set_led(gspca_dev, 1);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ reg_w_array(gspca_dev, bridge_start_ov965x,
+ ARRAY_SIZE(bridge_start_ov965x));
+ sccb_w_array(gspca_dev, sensor_start_ov965x,
+ ARRAY_SIZE(sensor_start_ov965x));
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ ov534_set_led(gspca_dev, 1);
+/*fixme: other sensor start omitted*/
+ }
return 0;
}
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- /* stop streaming data */
- ov534_reg_write(gspca_dev, 0xe0, 0x09);
- ov534_set_led(gspca_dev, 0);
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ switch (sd->sensor) {
+ case SENSOR_OV772X:
+ ov534_reg_write(gspca_dev, 0xe0, 0x09);
+ ov534_set_led(gspca_dev, 0);
+ break;
+ default:
+/* case SENSOR_OV965X: */
+ ov534_reg_write(gspca_dev, 0xe0, 0x01);
+ ov534_set_led(gspca_dev, 0);
+ ov534_reg_write(gspca_dev, 0xe0, 0x00);
+ break;
+ }
}
/* Values for bmHeaderInfo (Video and Still Image Payload Headers, 2.4.3.3) */
@@ -429,75 +830,75 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev, struct gspca_frame *frame,
{
struct sd *sd = (struct sd *) gspca_dev;
__u32 this_pts;
- int this_fid;
+ u16 this_fid;
int remaining_len = len;
- __u8 *next_data = data;
-scan_next:
- if (remaining_len <= 0)
- return;
-
- data = next_data;
- len = min(remaining_len, 2048);
- remaining_len -= len;
- next_data += len;
-
- /* Payloads are prefixed with a UVC-style header. We
- consider a frame to start when the FID toggles, or the PTS
- changes. A frame ends when EOF is set, and we've received
- the correct number of bytes. */
-
- /* Verify UVC header. Header length is always 12 */
- if (data[0] != 12 || len < 12) {
- PDEBUG(D_PACK, "bad header");
- goto discard;
- }
-
- /* Check errors */
- if (data[1] & UVC_STREAM_ERR) {
- PDEBUG(D_PACK, "payload error");
- goto discard;
- }
+ do {
+ len = min(remaining_len, 2040); /*fixme: was 2048*/
- /* Extract PTS and FID */
- if (!(data[1] & UVC_STREAM_PTS)) {
- PDEBUG(D_PACK, "PTS not present");
- goto discard;
- }
- this_pts = (data[5] << 24) | (data[4] << 16) | (data[3] << 8) | data[2];
- this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
-
- /* If PTS or FID has changed, start a new frame. */
- if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
- gspca_frame_add(gspca_dev, FIRST_PACKET, frame, NULL, 0);
- sd->last_pts = this_pts;
- sd->last_fid = this_fid;
- }
+ /* Payloads are prefixed with a UVC-style header. We
+ consider a frame to start when the FID toggles, or the PTS
+ changes. A frame ends when EOF is set, and we've received
+ the correct number of bytes. */
- /* Add the data from this payload */
- gspca_frame_add(gspca_dev, INTER_PACKET, frame,
- data + 12, len - 12);
+ /* Verify UVC header. Header length is always 12 */
+ if (data[0] != 12 || len < 12) {
+ PDEBUG(D_PACK, "bad header");
+ goto discard;
+ }
- /* If this packet is marked as EOF, end the frame */
- if (data[1] & UVC_STREAM_EOF) {
- sd->last_pts = 0;
+ /* Check errors */
+ if (data[1] & UVC_STREAM_ERR) {
+ PDEBUG(D_PACK, "payload error");
+ goto discard;
+ }
- if ((frame->data_end - frame->data) !=
- (gspca_dev->width * gspca_dev->height * 2)) {
- PDEBUG(D_PACK, "short frame");
+ /* Extract PTS and FID */
+ if (!(data[1] & UVC_STREAM_PTS)) {
+ PDEBUG(D_PACK, "PTS not present");
goto discard;
}
+ this_pts = (data[5] << 24) | (data[4] << 16)
+ | (data[3] << 8) | data[2];
+ this_fid = (data[1] & UVC_STREAM_FID) ? 1 : 0;
+
+ /* If PTS or FID has changed, start a new frame. */
+ if (this_pts != sd->last_pts || this_fid != sd->last_fid) {
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ NULL, 0);
+ sd->last_pts = this_pts;
+ sd->last_fid = this_fid;
+ }
- gspca_frame_add(gspca_dev, LAST_PACKET, frame, NULL, 0);
- }
+ /* Add the data from this payload */
+ gspca_frame_add(gspca_dev, INTER_PACKET, frame,
+ data + 12, len - 12);
- /* Done this payload */
- goto scan_next;
+ /* If this packet is marked as EOF, end the frame */
+ if (data[1] & UVC_STREAM_EOF) {
+ sd->last_pts = 0;
+
+ if (frame->data_end - frame->data !=
+ gspca_dev->width * gspca_dev->height * 2) {
+ PDEBUG(D_PACK, "short frame");
+ goto discard;
+ }
+
+ frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
+ NULL, 0);
+ }
+
+ /* Done this payload */
+ goto scan_next;
discard:
- /* Discard data until a new frame starts. */
- gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
- goto scan_next;
+ /* Discard data until a new frame starts. */
+ gspca_frame_add(gspca_dev, DISCARD_PACKET, frame, NULL, 0);
+
+scan_next:
+ remaining_len -= len;
+ data += len;
+ } while (remaining_len > 0);
}
/* get stream parameters (framerate) */
@@ -556,9 +957,8 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
- {USB_DEVICE(0x06f8, 0x3002)}, /* Hercules Blog Webcam */
- {USB_DEVICE(0x06f8, 0x3003)}, /* Hercules Dualpix HD Weblog */
- {USB_DEVICE(0x1415, 0x2000)}, /* Sony HD Eye for PS3 (SLEH 00201) */
+ {USB_DEVICE(0x06f8, 0x3003), .driver_info = SENSOR_OV965X},
+ {USB_DEVICE(0x1415, 0x2000), .driver_info = SENSOR_OV772X},
{}
};
@@ -585,8 +985,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac207.c b/drivers/media/video/gspca/pac207.c
index c90ac852bac..95a97ab684c 100644
--- a/drivers/media/video/gspca/pac207.c
+++ b/drivers/media/video/gspca/pac207.c
@@ -256,7 +256,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
" (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
sd->brightness = PAC207_BRIGHTNESS_DEFAULT;
@@ -536,6 +535,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x093a, 0x2470)},
{USB_DEVICE(0x093a, 0x2471)},
{USB_DEVICE(0x093a, 0x2472)},
+ {USB_DEVICE(0x093a, 0x2474)},
{USB_DEVICE(0x093a, 0x2476)},
{USB_DEVICE(0x145f, 0x013a)},
{USB_DEVICE(0x2001, 0xf115)},
@@ -565,8 +565,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/pac7311.c b/drivers/media/video/gspca/pac7311.c
index a9c95cba710..e1e3a3a5048 100644
--- a/drivers/media/video/gspca/pac7311.c
+++ b/drivers/media/video/gspca/pac7311.c
@@ -498,7 +498,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x05;
sd->sensor = id->driver_info;
if (sd->sensor == SENSOR_PAC7302) {
@@ -1097,8 +1096,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index b3e4e0677b6..153d0a91d4b 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -870,7 +870,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
if (!(sensor_data[sd->sensor].flags & F_SIF)) {
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1272,8 +1271,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index 3373b8d9d2a..c72e19d3ac3 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -35,36 +35,47 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
atomic_t avg_lum;
- unsigned int exposure;
-
- __u16 brightness;
- __u8 contrast;
- __u8 colors;
- __u8 autogain;
- __u8 blue;
- __u8 red;
- __u8 vflip; /* ov7630 only */
- __u8 infrared; /* mi0360 only */
-
- __s8 ag_cnt;
+ u32 exposure;
+
+ u16 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 blue;
+ u8 red;
+ u8 gamma;
+ u8 vflip; /* ov7630/ov7648 only */
+ u8 infrared; /* mt9v111 only */
+ u8 quality; /* image quality */
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
+ u8 jpegqual; /* webcam quality */
+
+ u8 reg18;
+
+ s8 ag_cnt;
#define AG_CNT_START 13
- __u8 qindex;
- __u8 bridge;
+ u8 bridge;
#define BRIDGE_SN9C102P 0
#define BRIDGE_SN9C105 1
#define BRIDGE_SN9C110 2
#define BRIDGE_SN9C120 3
#define BRIDGE_SN9C325 4
- __u8 sensor; /* Type of image sensor chip */
+ u8 sensor; /* Type of image sensor chip */
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
#define SENSOR_MO4000 2
-#define SENSOR_OM6802 3
-#define SENSOR_OV7630 4
-#define SENSOR_OV7648 5
-#define SENSOR_OV7660 6
- __u8 i2c_base;
+#define SENSOR_MT9V111 3
+#define SENSOR_OM6802 4
+#define SENSOR_OV7630 5
+#define SENSOR_OV7648 6
+#define SENSOR_OV7660 7
+#define SENSOR_SP80708 8
+ u8 i2c_base;
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -78,6 +89,8 @@ static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
@@ -158,6 +171,20 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setred_balance,
.get = sd_getred_balance,
},
+ {
+ {
+ .id = V4L2_CID_GAMMA,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gamma",
+ .minimum = 0,
+ .maximum = 40,
+ .step = 1,
+#define GAMMA_DEF 20
+ .default_value = GAMMA_DEF,
+ },
+ .set = sd_setgamma,
+ .get = sd_getgamma,
+ },
#define AUTOGAIN_IDX 5
{
{
@@ -173,7 +200,7 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setautogain,
.get = sd_getautogain,
},
-/* ov7630 only */
+/* ov7630/ov7648 only */
#define VFLIP_IDX 6
{
{
@@ -183,13 +210,13 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
-#define VFLIP_DEF 1
+#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */
.default_value = VFLIP_DEF,
},
.set = sd_setvflip,
.get = sd_getvflip,
},
-/* mi0360 only */
+/* mt9v111 only */
#define INFRARED_IDX 7
{
{
@@ -211,18 +238,22 @@ static struct ctrl sd_ctrls[] = {
static __u32 ctrl_dis[] = {
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_HV7131R 0 */
- (1 << VFLIP_IDX),
+ (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MI0360 1 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
/* SENSOR_MO4000 2 */
+ (1 << VFLIP_IDX),
+ /* SENSOR_MT9V111 3 */
(1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OM6802 3 */
+ /* SENSOR_OM6802 4 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
- /* SENSOR_OV7630 4 */
+ /* SENSOR_OV7630 5 */
+ (1 << INFRARED_IDX),
+ /* SENSOR_OV7648 6 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7648 5 */
+ /* SENSOR_OV7660 7 */
(1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
- /* SENSOR_OV7660 6 */
+ /* SENSOR_SP80708 8 */
};
static const struct v4l2_pix_format vga_mode[] = {
@@ -243,196 +274,228 @@ static const struct v4l2_pix_format vga_mode[] = {
.priv = 0},
};
-/*Data from sn9c102p+hv71331r */
-static const __u8 sn_hv7131[] = {
+/*Data from sn9c102p+hv7131r */
+static const u8 sn_hv7131[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0a, 0x00, 0x00, 0x00
};
-static const __u8 sn_mi0360[] = {
+static const u8 sn_mi0360[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
};
-static const __u8 sn_mo4000[] = {
+static const u8 sn_mo4000[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
- 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
+ 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x08, 0x00, 0x00, 0x00
};
-static const __u8 sn_om6802[] = {
+static const u8 sn_mt9v111[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
+/* reg18 reg19 reg1a reg1b */
+ 0x06, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_om6802[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
- 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
- 0xf7
+/* reg18 reg19 reg1a reg1b */
+ 0x05, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7630[] = {
+static const u8 sn_ov7630[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7648[] = {
+static const u8 sn_ov7648[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
+/* reg18 reg19 reg1a reg1b */
+ 0x0b, 0x00, 0x00, 0x00
};
-static const __u8 sn_ov7660[] = {
+static const u8 sn_ov7660[0x1c] = {
/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
/* reg8 reg9 rega regb regc regd rege regf */
0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
-/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
+};
+
+static const u8 sn_sp80708[0x1c] = {
+/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
+ 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
+/* reg8 reg9 rega regb regc regd rege regf */
+ 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
+ 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
+/* reg18 reg19 reg1a reg1b */
+ 0x07, 0x00, 0x00, 0x00
};
/* sequence specific to the sensors - !! index = SENSOR_xxx */
-static const __u8 *sn_tb[] = {
+static const u8 *sn_tb[] = {
sn_hv7131,
sn_mi0360,
sn_mo4000,
+ sn_mt9v111,
sn_om6802,
sn_ov7630,
sn_ov7648,
- sn_ov7660
+ sn_ov7660,
+ sn_sp80708
};
-static const __u8 gamma_def[] = {
+/* default gamma table */
+static const u8 gamma_def[17] = {
0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
};
+/* gamma for sensors HV7131R and MT9V111 */
+static const u8 gamma_spec_1[17] = {
+ 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
+ 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
+};
+/* gamma for sensor SP80708 */
+static const u8 gamma_spec_2[17] = {
+ 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
+ 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
+};
/* color matrix and offsets */
-static const __u8 reg84[] = {
+static const u8 reg84[] = {
0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
0x00, 0x00, 0x00 /* YUV offsets */
};
-static const __u8 hv7131r_sensor_init[][8] = {
- {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
- {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
- {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
- {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
- {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
- {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
-
- {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
+static const u8 hv7131r_sensor_init[][8] = {
+ {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
+/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+ {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
+/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
+ {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
+ {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
+ {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
+ {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
+
+ {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
{}
};
-static const __u8 mi0360_sensor_init[][8] = {
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
- {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
- {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
- {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
- {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
- {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
- {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
- {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
- {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
- {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
-
- {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
- {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
-
- {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
- {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
- {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
-
- {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
- {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
-/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
- {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
- {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
+static const u8 mi0360_sensor_init[][8] = {
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
+ {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
+ {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
+ {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
+ {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
+ {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
+ {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
+ {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
+ {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
+ {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
+
+ {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
+ {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
+
+ {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
+ {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
+ {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
+
+ {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
+ {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
+/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
+ {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
+ {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
{}
};
-static const __u8 mo4000_sensor_init[][8] = {
+static const u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -455,7 +518,49 @@ static const __u8 mo4000_sensor_init[][8] = {
{0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
{}
};
-static __u8 om6802_sensor_init[][8] = {
+static const u8 mt9v111_sensor_init[][8] = {
+ {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
+ /* delay 20 ms */
+ {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
+ {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
+ {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
+ {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
+ {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
+ {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
+ {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
+ {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
+ {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
+ {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ /*******/
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
+ {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
+ {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
+ /*******/
+ {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
+ {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
+ {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
+ {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
+ {}
+};
+static const u8 om6802_sensor_init[][8] = {
{0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
{0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
@@ -489,7 +594,7 @@ static __u8 om6802_sensor_init[][8] = {
/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
{}
};
-static const __u8 ov7630_sensor_init[][8] = {
+static const u8 ov7630_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
/* win: delay 20ms */
@@ -543,7 +648,7 @@ static const __u8 ov7630_sensor_init[][8] = {
{}
};
-static const __u8 ov7648_sensor_init[][8] = {
+static const u8 ov7648_sensor_init[][8] = {
{0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
{0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
@@ -572,7 +677,8 @@ static const __u8 ov7648_sensor_init[][8] = {
{0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
/*...*/
/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
-/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
+/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
+ * set by setvflip */
{0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
{0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
@@ -589,7 +695,7 @@ static const __u8 ov7648_sensor_init[][8] = {
{}
};
-static const __u8 ov7660_sensor_init[][8] = {
+static const u8 ov7660_sensor_init[][8] = {
{0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
/* (delay 20ms) */
{0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
@@ -678,28 +784,92 @@ static const __u8 ov7660_sensor_init[][8] = {
{}
};
-static const __u8 qtable4[] = {
- 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
- 0x06, 0x08, 0x0A, 0x11,
- 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
- 0x19, 0x19, 0x17, 0x15,
- 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
- 0x21, 0x2E, 0x21, 0x23,
- 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
- 0x25, 0x29, 0x2C, 0x29,
- 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
- 0x17, 0x1B, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29
+static const u8 sp80708_sensor_init[][8] = {
+ {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
+ /********/
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
+ {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
+ {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
+ {}
};
/* read <len> bytes to gspca_dev->usb_buf */
static void reg_r(struct gspca_dev *gspca_dev,
- __u16 value, int len)
+ u16 value, int len)
{
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -718,10 +888,10 @@ static void reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w1(struct gspca_dev *gspca_dev,
- __u16 value,
- __u8 data)
+ u16 value,
+ u8 data)
{
- PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
+ PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
gspca_dev->usb_buf[0] = data;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -733,11 +903,11 @@ static void reg_w1(struct gspca_dev *gspca_dev,
500);
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 value,
- const __u8 *buffer,
+ u16 value,
+ const u8 *buffer,
int len)
{
- PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
+ PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
value, buffer[0], buffer[1]);
#ifdef GSPCA_DEBUG
if (len > USB_BUF_SZ) {
@@ -756,7 +926,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
/* I2C write 1 byte */
-static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
+static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -781,7 +951,7 @@ static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
/* I2C write 8 bytes */
static void i2c_w8(struct gspca_dev *gspca_dev,
- const __u8 *buffer)
+ const u8 *buffer)
{
memcpy(gspca_dev->usb_buf, buffer, 8);
usb_control_msg(gspca_dev->dev,
@@ -795,10 +965,10 @@ static void i2c_w8(struct gspca_dev *gspca_dev,
}
/* read 5 bytes in gspca_dev->usb_buf */
-static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
+static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 mode[8];
+ u8 mode[8];
mode[0] = 0x81 | 0x10;
mode[1] = sd->i2c_base;
@@ -817,7 +987,7 @@ static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
reg_r(gspca_dev, 0x0a, 5);
}
-static int probesensor(struct gspca_dev *gspca_dev)
+static int hv7131r_probe(struct gspca_dev *gspca_dev)
{
i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
msleep(10);
@@ -839,16 +1009,66 @@ static int probesensor(struct gspca_dev *gspca_dev)
return -ENODEV;
}
+static void mi0360_probe(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, j;
+ u16 val = 0;
+ static const u8 probe_tb[][4][8] = {
+ { /* mi0360 */
+ {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
+ {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
+ },
+ { /* mt9v111 */
+ {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
+ {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
+ {}
+ },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
+ reg_w1(gspca_dev, 0x17, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x08);
+ for (j = 0; j < 3; j++)
+ i2c_w8(gspca_dev, probe_tb[i][j]);
+ msleep(2);
+ reg_r(gspca_dev, 0x0a, 5);
+ val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
+ if (probe_tb[i][3][0] != 0)
+ i2c_w8(gspca_dev, probe_tb[i][3]);
+ reg_w1(gspca_dev, 0x01, 0x29);
+ reg_w1(gspca_dev, 0x17, 0x42);
+ if (val != 0xffff)
+ break;
+ }
+ switch (val) {
+ case 0x823a:
+ PDEBUG(D_PROBE, "Sensor mt9v111");
+ sd->sensor = SENSOR_MT9V111;
+ sd->i2c_base = 0x5c;
+ break;
+ case 0x8243:
+ PDEBUG(D_PROBE, "Sensor mi0360");
+ break;
+ default:
+ PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
+ break;
+ }
+}
+
static int configure_gpio(struct gspca_dev *gspca_dev,
- const __u8 *sn9c1xx)
+ const u8 *sn9c1xx)
{
struct sd *sd = (struct sd *) gspca_dev;
- const __u8 *reg9a;
- static const __u8 reg9a_def[] =
+ const u8 *reg9a;
+ static const u8 reg9a_def[] =
{0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
- static const __u8 reg9a_sn9c325[] =
+ static const u8 reg9a_sn9c325[] =
{0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
- static const __u8 regd4[] = {0x60, 0x00, 0x00};
+ static const u8 regd4[] = {0x60, 0x00, 0x00};
reg_w1(gspca_dev, 0xf1, 0x00);
reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
@@ -872,6 +1092,12 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x01, 0x61);
+ reg_w1(gspca_dev, 0x17, 0x61);
+ reg_w1(gspca_dev, 0x01, 0x60);
+ reg_w1(gspca_dev, 0x01, 0x40);
+ break;
case SENSOR_OM6802:
reg_w1(gspca_dev, 0x02, 0x71);
reg_w1(gspca_dev, 0x01, 0x42);
@@ -900,12 +1126,20 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
break;
}
/* fall thru */
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x01, 0x63);
+ reg_w1(gspca_dev, 0x17, 0x20);
+ reg_w1(gspca_dev, 0x01, 0x62);
+ reg_w1(gspca_dev, 0x01, 0x42);
+ mdelay(100);
+ reg_w1(gspca_dev, 0x02, 0x62);
+ break;
default:
reg_w1(gspca_dev, 0x01, 0x43);
reg_w1(gspca_dev, 0x17, 0x61);
reg_w1(gspca_dev, 0x01, 0x42);
if (sd->sensor == SENSOR_HV7131R) {
- if (probesensor(gspca_dev) < 0)
+ if (hv7131r_probe(gspca_dev) < 0)
return -ENODEV;
}
break;
@@ -916,7 +1150,7 @@ static int configure_gpio(struct gspca_dev *gspca_dev,
static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
- static const __u8 SetSensorClk[] = /* 0x08 Mclk */
+ static const u8 SetSensorClk[] = /* 0x08 Mclk */
{ 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
while (hv7131r_sensor_init[i][0]) {
@@ -946,6 +1180,19 @@ static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ msleep(20);
+ while (mt9v111_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
+ i++;
+ }
+}
+
static void om6802_InitSensor(struct gspca_dev *gspca_dev)
{
int i = 0;
@@ -1010,6 +1257,19 @@ static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
}
}
+static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
+{
+ int i = 0;
+
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
+ i++;
+ msleep(20);
+ while (sp80708_sensor_init[i][0]) {
+ i2c_w8(gspca_dev, sp80708_sensor_init[i]);
+ i++;
+ }
+}
+
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
@@ -1018,7 +1278,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1026,16 +1285,21 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info >> 8;
sd->i2c_base = id->driver_info;
- sd->qindex = 4; /* set the quantization table */
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
sd->blue = BLUE_BALANCE_DEF;
sd->red = RED_BALANCE_DEF;
+ sd->gamma = GAMMA_DEF;
sd->autogain = AUTOGAIN_DEF;
sd->ag_cnt = -1;
- sd->vflip = VFLIP_DEF;
+ if (sd->sensor != SENSOR_OV7630)
+ sd->vflip = 0;
+ else
+ sd->vflip = 1;
sd->infrared = INFRARED_DEF;
+ sd->quality = QUALITY_DEF;
+ sd->jpegqual = 80;
gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
return 0;
@@ -1045,8 +1309,8 @@ static int sd_config(struct gspca_dev *gspca_dev,
static int sd_init(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 regGpio[] = { 0x29, 0x74 };
- __u8 regF1;
+ u8 regGpio[] = { 0x29, 0x74 };
+ u8 regF1;
/* setup a selector by bridge */
reg_w1(gspca_dev, 0xf1, 0x01);
@@ -1064,11 +1328,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
case BRIDGE_SN9C105:
if (regF1 != 0x11)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
case BRIDGE_SN9C120:
if (regF1 != 0x12)
return -ENODEV;
+ if (sd->sensor == SENSOR_MI0360)
+ mi0360_probe(gspca_dev);
regGpio[1] = 0x70;
reg_w(gspca_dev, 0x01, regGpio, 2);
break;
@@ -1086,20 +1354,14 @@ static int sd_init(struct gspca_dev *gspca_dev)
return 0;
}
-static unsigned int setexposure(struct gspca_dev *gspca_dev,
- unsigned int expo)
+static u32 setexposure(struct gspca_dev *gspca_dev,
+ u32 expo)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 doit[] = /* update sensor */
- { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
- static const __u8 sensorgo[] = /* sensor on */
- { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
- static const __u8 gainMo[] =
- { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
switch (sd->sensor) {
case SENSOR_HV7131R: {
- __u8 Expodoit[] =
+ u8 Expodoit[] =
{ 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
Expodoit[3] = expo >> 16;
@@ -1109,8 +1371,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MI0360: {
- __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
+ u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
{ 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
+ static const u8 doit[] = /* update sensor */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
+ static const u8 sensorgo[] = /* sensor on */
+ { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
if (expo > 0x0635)
expo = 0x0635;
@@ -1124,10 +1390,12 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
break;
}
case SENSOR_MO4000: {
- __u8 expoMof[] =
+ u8 expoMof[] =
{ 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 expoMo10[] =
+ u8 expoMo10[] =
{ 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
+ static const u8 gainMo[] =
+ { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
if (expo > 0x1fff)
expo = 0x1fff;
@@ -1139,14 +1407,27 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
| ((expo & 0x0003) << 4);
i2c_w8(gspca_dev, expoMo10);
i2c_w8(gspca_dev, gainMo);
- PDEBUG(D_CONF, "set exposure %d",
+ PDEBUG(D_FRAM, "set exposure %d",
((expoMo10[3] & 0x07) << 10)
| (expoMof[3] << 2)
| ((expoMo10[3] & 0x30) >> 4));
break;
}
+ case SENSOR_MT9V111: {
+ u8 expo_c1[] =
+ { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
+
+ if (expo > 0x0280)
+ expo = 0x0280;
+ else if (expo < 0x0040)
+ expo = 0x0040;
+ expo_c1[3] = expo >> 8;
+ expo_c1[4] = expo;
+ i2c_w8(gspca_dev, expo_c1);
+ break;
+ }
case SENSOR_OM6802: {
- __u8 gainOm[] =
+ u8 gainOm[] =
{ 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
if (expo > 0x03ff)
@@ -1156,7 +1437,7 @@ static unsigned int setexposure(struct gspca_dev *gspca_dev,
gainOm[3] = expo >> 2;
i2c_w8(gspca_dev, gainOm);
reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
- PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
+ PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
break;
}
}
@@ -1167,7 +1448,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int expo;
- __u8 k2;
+ u8 k2;
k2 = ((int) sd->brightness - 0x8000) >> 10;
switch (sd->sensor) {
@@ -1184,6 +1465,10 @@ static void setbrightness(struct gspca_dev *gspca_dev)
expo = sd->brightness >> 4;
sd->exposure = setexposure(gspca_dev, expo);
break;
+ case SENSOR_MT9V111:
+ expo = sd->brightness >> 8;
+ sd->exposure = setexposure(gspca_dev, expo);
+ break;
case SENSOR_OM6802:
expo = sd->brightness >> 6;
sd->exposure = setexposure(gspca_dev, expo);
@@ -1191,14 +1476,15 @@ static void setbrightness(struct gspca_dev *gspca_dev)
break;
}
- reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
+ if (sd->sensor != SENSOR_MT9V111)
+ reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
}
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 k2;
- __u8 contrast[6];
+ u8 k2;
+ u8 contrast[6];
k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
contrast[0] = (k2 + 1) / 2; /* red */
@@ -1214,8 +1500,8 @@ static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, v;
- __u8 reg8a[12]; /* U & V gains */
- static __s16 uv[6] = { /* same as reg84 in signed decimal */
+ u8 reg8a[12]; /* U & V gains */
+ static s16 uv[6] = { /* same as reg84 in signed decimal */
-24, -38, 64, /* UR UG UB */
62, -51, -9 /* VR VG VB */
};
@@ -1236,22 +1522,75 @@ static void setredblue(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x06, sd->blue);
}
+static void setgamma(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i;
+ u8 gamma[17];
+ const u8 *gamma_base;
+ static const u8 delta[17] = {
+ 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
+ 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
+ };
+
+ switch (sd->sensor) {
+ case SENSOR_HV7131R:
+ case SENSOR_MT9V111:
+ gamma_base = gamma_spec_1;
+ break;
+ case SENSOR_SP80708:
+ gamma_base = gamma_spec_2;
+ break;
+ default:
+ gamma_base = gamma_def;
+ break;
+ }
+
+ for (i = 0; i < sizeof gamma; i++)
+ gamma[i] = gamma_base[i]
+ + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
+ reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
+}
+
static void setautogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
return;
+ switch (sd->sensor) {
+ case SENSOR_OV7630:
+ case SENSOR_OV7648: {
+ u8 comb;
+
+ if (sd->sensor == SENSOR_OV7630)
+ comb = 0xc0;
+ else
+ comb = 0xa0;
+ if (sd->autogain)
+ comb |= 0x02;
+ i2c_w1(&sd->gspca_dev, 0x13, comb);
+ return;
+ }
+ }
if (sd->autogain)
sd->ag_cnt = AG_CNT_START;
else
sd->ag_cnt = -1;
}
+/* ov7630/ov7648 only */
static void setvflip(struct sd *sd)
{
- i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
- sd->vflip ? 0x82 : 0x02);
+ u8 comn;
+
+ if (sd->sensor == SENSOR_OV7630)
+ comn = 0x02;
+ else
+ comn = 0x06;
+ if (sd->vflip)
+ comn |= 0x80;
+ i2c_w1(&sd->gspca_dev, 0x75, comn);
}
static void setinfrared(struct sd *sd)
@@ -1262,20 +1601,63 @@ static void setinfrared(struct sd *sd)
sd->infrared ? 0x66 : 0x64);
}
+static void setjpegqual(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ int i, sc;
+
+ if (sd->jpegqual < 50)
+ sc = 5000 / sd->jpegqual;
+ else
+ sc = 200 - sd->jpegqual * 2;
+#if USB_BUF_SZ < 64
+#error "No room enough in usb_buf for quantization table"
+#endif
+ for (i = 0; i < 64; i++)
+ gspca_dev->usb_buf[i] =
+ (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x0100, 0,
+ gspca_dev->usb_buf, 64,
+ 500);
+ for (i = 0; i < 64; i++)
+ gspca_dev->usb_buf[i] =
+ (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0x08,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
+ 0x0140, 0,
+ gspca_dev->usb_buf, 64,
+ 500);
+
+ sd->reg18 ^= 0x40;
+ reg_w1(gspca_dev, 0x18, sd->reg18);
+}
+
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 reg1, reg17, reg18;
- const __u8 *sn9c1xx;
+ u8 reg1, reg17;
+ const u8 *sn9c1xx;
int mode;
- static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
- static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
- static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
- static const __u8 CE_ov76xx[] =
+ static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
+ static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
+ static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
+ static const u8 CE_ov76xx[] =
{ 0x32, 0xdd, 0x32, 0xdd };
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
sn9c1xx = sn_tb[(int) sd->sensor];
configure_gpio(gspca_dev, sn9c1xx);
@@ -1292,6 +1674,9 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0xc9, 0x3c);
reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg17 = 0xe0;
+ break;
case SENSOR_OV7630:
reg17 = 0xe2;
break;
@@ -1315,14 +1700,24 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
- reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
+
+ setgamma(gspca_dev);
+
for (i = 0; i < 8; i++)
reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
switch (sd->sensor) {
+ case SENSOR_MT9V111:
+ reg_w1(gspca_dev, 0x9a, 0x07);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7648:
reg_w1(gspca_dev, 0x9a, 0x0a);
reg_w1(gspca_dev, 0x99, 0x60);
break;
+ case SENSOR_SP80708:
+ reg_w1(gspca_dev, 0x9a, 0x05);
+ reg_w1(gspca_dev, 0x99, 0x59);
+ break;
case SENSOR_OV7660:
if (sd->bridge == BRIDGE_SN9C120) {
reg_w1(gspca_dev, 0x9a, 0x05);
@@ -1358,6 +1753,15 @@ static int sd_start(struct gspca_dev *gspca_dev)
/* reg1 = 0x06; * 640 clk 24Mz (done) */
}
break;
+ case SENSOR_MT9V111:
+ mt9v111_InitSensor(gspca_dev);
+ if (mode) {
+ reg1 = 0x04; /* 320 clk 48Mhz */
+ } else {
+/* reg1 = 0x06; * 640 clk 24Mz (done) */
+ reg17 = 0xc2;
+ }
+ break;
case SENSOR_OM6802:
om6802_InitSensor(gspca_dev);
reg17 = 0x64; /* 640 MCKSIZE */
@@ -1373,8 +1777,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg17 = 0x21;
/* reg1 = 0x42; * 42 - 46? */
break;
- default:
-/* case SENSOR_OV7660: */
+ case SENSOR_OV7660:
ov7660_InitSensor(gspca_dev);
if (sd->bridge == BRIDGE_SN9C120) {
if (mode) { /* 320x240 - 160x120 */
@@ -1387,6 +1790,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
* inverse power down */
}
break;
+ default:
+/* case SENSOR_SP80708: */
+ sp80708_InitSensor(gspca_dev);
+ if (mode) {
+/*?? reg1 = 0x04; * 320 clk 48Mhz */
+ } else {
+ reg1 = 0x46; /* 640 clk 48Mz */
+ reg17 = 0xa2;
+ }
+ break;
}
reg_w(gspca_dev, 0xc0, C0, 6);
reg_w(gspca_dev, 0xca, CA, 4);
@@ -1403,20 +1816,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
}
/* here change size mode 0 -> VGA; 1 -> CIF */
- reg18 = sn9c1xx[0x18] | (mode << 4);
- reg_w1(gspca_dev, 0x18, reg18 | 0x40);
-
- reg_w(gspca_dev, 0x100, qtable4, 0x40);
- reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
-
- reg_w1(gspca_dev, 0x18, reg18);
+ sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
+ reg_w1(gspca_dev, 0x18, sd->reg18);
+ setjpegqual(gspca_dev);
reg_w1(gspca_dev, 0x17, reg17);
reg_w1(gspca_dev, 0x01, reg1);
switch (sd->sensor) {
- case SENSOR_MI0360:
- setinfrared(sd);
- break;
case SENSOR_OV7630:
setvflip(sd);
break;
@@ -1430,14 +1836,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 stophv7131[] =
+ static const u8 stophv7131[] =
{ 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopmi0360[] =
+ static const u8 stopmi0360[] =
{ 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
- static const __u8 stopov7648[] =
+ static const u8 stopov7648[] =
{ 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
- __u8 data;
- const __u8 *sn9c1xx;
+ u8 data;
+ const u8 *sn9c1xx;
data = 0x0b;
switch (sd->sensor) {
@@ -1452,6 +1858,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
case SENSOR_OV7648:
i2c_w8(gspca_dev, stopov7648);
/* fall thru */
+ case SENSOR_MT9V111:
case SENSOR_OV7630:
data = 0x29;
break;
@@ -1468,13 +1875,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
reg_w1(gspca_dev, 0xf1, 0x00);
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void do_autogain(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int delta;
int expotimes;
- __u8 luma_mean = 130;
- __u8 luma_delta = 20;
+ u8 luma_mean = 130;
+ u8 luma_delta = 20;
/* Thanks S., without your advice, autobright should not work :) */
if (sd->ag_cnt < 0)
@@ -1499,6 +1913,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
default:
/* case SENSOR_MO4000: */
/* case SENSOR_MI0360: */
+/* case SENSOR_MT9V111: */
/* case SENSOR_OM6802: */
expotimes = sd->exposure;
expotimes += (luma_mean - delta) >> 6;
@@ -1516,7 +1931,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
/* This function is run at interrupt level. */
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1550,7 +1965,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
if (gspca_dev->last_packet_type == LAST_PACKET) {
/* put the JPEG 422 header */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
}
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1645,6 +2061,24 @@ static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ sd->gamma = val;
+ if (gspca_dev->streaming)
+ setgamma(gspca_dev);
+ return 0;
+}
+
+static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ *val = sd->gamma;
+ return 0;
+}
+
static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1699,6 +2133,34 @@ static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1708,8 +2170,11 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.dq_callback = do_autogain,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1724,9 +2189,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
#endif
{USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
{USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
-#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
-#endif
{USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
{USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
@@ -1764,10 +2227,10 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
{USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
+#endif
{USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
-#endif
- {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
+ {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
{}
};
MODULE_DEVICE_TABLE(usb, device_table);
@@ -1794,8 +2257,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca500.c b/drivers/media/video/gspca/spca500.c
index 942f04cd44d..6f38fa6d86b 100644
--- a/drivers/media/video/gspca/spca500.c
+++ b/drivers/media/video/gspca/spca500.c
@@ -38,8 +38,11 @@ struct sd {
unsigned char brightness;
unsigned char contrast;
unsigned char colors;
+ u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
- char qindex;
char subtype;
#define AgfaCl20 0
#define AiptekPocketDV 1
@@ -56,6 +59,8 @@ struct sd {
#define Optimedia 12
#define PalmPixDC85 13
#define ToptroIndus 14
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -629,7 +634,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->subtype = id->driver_info;
if (sd->subtype != LogitechClickSmart310) {
cam->cam_mode = vga_mode;
@@ -638,10 +642,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 5;
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -667,6 +671,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
__u8 Data;
__u8 xmult, ymult;
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
if (sd->subtype == LogitechClickSmart310) {
xmult = 0x16;
ymult = 0x12;
@@ -713,7 +723,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
write_vector(gspca_dev, spca500_visual_defaults);
spca500_setmode(gspca_dev, xmult, ymult);
/* enable drop packet */
- reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
+ if (err < 0)
PDEBUG(D_ERR, "failed to enable drop packet");
reg_w(gspca_dev, 0x00, 0x8880, 3);
err = spca50x_setup_qtable(gspca_dev,
@@ -881,6 +892,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
gspca_dev->usb_buf[0]);
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -901,7 +919,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame, sd->qindex, 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
data += SPCA500_OFFSET_DATA;
len -= SPCA500_OFFSET_DATA;
@@ -937,16 +956,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
(__u8) (sd->brightness - 128));
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x00, 0x8167, 1);
- if (ret >= 0)
- sd->brightness = ret + 128;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -954,16 +963,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8168, sd->contrast);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8168, 1);
- if (ret >= 0)
- sd->contrast = ret;
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -971,16 +970,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_w(gspca_dev, 0x00, 0x8169, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- int ret;
-
- ret = reg_r_12(gspca_dev, 0x0, 0x8169, 1);
- if (ret >= 0)
- sd->colors = ret;
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -995,7 +984,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1014,7 +1002,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1033,11 +1020,38 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1047,7 +1061,10 @@ static struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1093,8 +1110,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca501.c b/drivers/media/video/gspca/spca501.c
index 82e3e3e2ada..d48b27c648c 100644
--- a/drivers/media/video/gspca/spca501.c
+++ b/drivers/media/video/gspca/spca501.c
@@ -1883,10 +1883,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x12, sd->brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1897,10 +1893,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
sd->contrast & 0xff);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1908,10 +1900,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, SPCA501_REG_CCDSP, 0x0c, sd->colors);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
-}
-
static void setblue_balance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1934,7 +1922,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->subtype = id->driver_info;
@@ -2084,7 +2071,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -2103,7 +2089,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -2122,7 +2107,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -2211,8 +2195,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca505.c b/drivers/media/video/gspca/spca505.c
index 2a33a29010e..2acec58b1b9 100644
--- a/drivers/media/video/gspca/spca505.c
+++ b/drivers/media/video/gspca/spca505.c
@@ -31,9 +31,9 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
+ u8 brightness;
- char subtype;
+ u8 subtype;
#define IntelPCCameraPro 0
#define Nxultra 1
};
@@ -43,7 +43,6 @@ static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -52,7 +51,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 255,
.step = 1,
- .default_value = 127,
+#define BRIGHTNESS_DEF 127
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
@@ -64,12 +64,12 @@ static const struct v4l2_pix_format vga_mode[] = {
.bytesperline = 160,
.sizeimage = 160 * 120 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 5},
+ .priv = 4},
{176, 144, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 176,
.sizeimage = 176 * 144 * 3 / 2,
.colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 4},
+ .priv = 3},
{320, 240, V4L2_PIX_FMT_SPCA505, V4L2_FIELD_NONE,
.bytesperline = 320,
.sizeimage = 320 * 240 * 3 / 2,
@@ -93,6 +93,7 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_USB_CTRL 0x00 /* spca505 */
#define SPCA50X_CUSB_ENABLE 0x01 /* spca505 */
+
#define SPCA50X_REG_GLOBAL 0x03 /* spca505 */
#define SPCA50X_GMISC0_IDSEL 0x01 /* Global control device ID select spca505 */
#define SPCA50X_GLOBAL_MISC0 0x00 /* Global control miscellaneous 0 spca505 */
@@ -101,230 +102,230 @@ static const struct v4l2_pix_format vga_mode[] = {
#define SPCA50X_GLOBAL_MISC3 0x03 /* 505 */
#define SPCA50X_GMISC3_SAA7113RST 0x20 /* Not sure about this one spca505 */
+/* Image format and compression control */
+#define SPCA50X_REG_COMPRESS 0x04
+
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505_init_data[][3] = {
- /* line bmRequest,value,index */
- /* 1819 */
+static const u8 spca505_init_data[][3] = {
+ /* bmRequest,value,index */
{SPCA50X_REG_GLOBAL, SPCA50X_GMISC3_SAA7113RST, SPCA50X_GLOBAL_MISC3},
/* Sensor reset */
- /* 1822 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
- /* 1825 */ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC3},
+ {SPCA50X_REG_GLOBAL, 0x00, SPCA50X_GLOBAL_MISC1},
/* Block USB reset */
- /* 1828 */ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL,
- SPCA50X_GLOBAL_MISC0},
+ {SPCA50X_REG_GLOBAL, SPCA50X_GMISC0_IDSEL, SPCA50X_GLOBAL_MISC0},
- /* 1831 */ {0x5, 0x01, 0x10},
+ {0x05, 0x01, 0x10},
/* Maybe power down some stuff */
- /* 1834 */ {0x5, 0x0f, 0x11},
+ {0x05, 0x0f, 0x11},
/* Setup internal CCD ? */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
{}
};
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505_open_data_ccd[][3] = {
- /* line bmRequest,value,index */
+static const u8 spca505_open_data_ccd[][3] = {
+ /* bmRequest,value,index */
/* Internal CCD data set */
- /* 1891 */ {0x3, 0x04, 0x01},
+ {0x03, 0x04, 0x01},
/* This could be a reset */
- /* 1894 */ {0x3, 0x00, 0x01},
+ {0x03, 0x00, 0x01},
/* Setup compression and image registers. 0x6 and 0x7 seem to be
related to H&V hold, and are resolution mode specific */
- /* 1897 */ {0x4, 0x10, 0x01},
+ {0x04, 0x10, 0x01},
/* DIFF(0x50), was (0x10) */
- /* 1900 */ {0x4, 0x00, 0x04},
- /* 1903 */ {0x4, 0x00, 0x05},
- /* 1906 */ {0x4, 0x20, 0x06},
- /* 1909 */ {0x4, 0x20, 0x07},
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x20, 0x06},
+ {0x04, 0x20, 0x07},
- /* 1912 */ {0x8, 0x0a, 0x00},
+ {0x08, 0x0a, 0x00},
/* DIFF (0x4a), was (0xa) */
- /* 1915 */ {0x5, 0x00, 0x10},
- /* 1918 */ {0x5, 0x00, 0x11},
- /* 1921 */ {0x5, 0x00, 0x00},
+ {0x05, 0x00, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x00, 0x00},
/* DIFF not written */
- /* 1924 */ {0x5, 0x00, 0x01},
+ {0x05, 0x00, 0x01},
/* DIFF not written */
- /* 1927 */ {0x5, 0x00, 0x02},
+ {0x05, 0x00, 0x02},
/* DIFF not written */
- /* 1930 */ {0x5, 0x00, 0x03},
+ {0x05, 0x00, 0x03},
/* DIFF not written */
- /* 1933 */ {0x5, 0x00, 0x04},
+ {0x05, 0x00, 0x04},
/* DIFF not written */
- /* 1936 */ {0x5, 0x80, 0x05},
+ {0x05, 0x80, 0x05},
/* DIFF not written */
- /* 1939 */ {0x5, 0xe0, 0x06},
+ {0x05, 0xe0, 0x06},
/* DIFF not written */
- /* 1942 */ {0x5, 0x20, 0x07},
+ {0x05, 0x20, 0x07},
/* DIFF not written */
- /* 1945 */ {0x5, 0xa0, 0x08},
+ {0x05, 0xa0, 0x08},
/* DIFF not written */
- /* 1948 */ {0x5, 0x0, 0x12},
+ {0x05, 0x0, 0x12},
/* DIFF not written */
- /* 1951 */ {0x5, 0x02, 0x0f},
+ {0x05, 0x02, 0x0f},
/* DIFF not written */
- /* 1954 */ {0x5, 0x10, 0x46},
+ {0x05, 0x10, 0x46},
/* DIFF not written */
- /* 1957 */ {0x5, 0x8, 0x4a},
+ {0x05, 0x8, 0x4a},
/* DIFF not written */
- /* 1960 */ {0x3, 0x08, 0x03},
+ {0x03, 0x08, 0x03},
/* DIFF (0x3,0x28,0x3) */
- /* 1963 */ {0x3, 0x08, 0x01},
- /* 1966 */ {0x3, 0x0c, 0x03},
+ {0x03, 0x08, 0x01},
+ {0x03, 0x0c, 0x03},
/* DIFF not written */
- /* 1969 */ {0x3, 0x21, 0x00},
+ {0x03, 0x21, 0x00},
/* DIFF (0x39) */
/* Extra block copied from init to hopefully ensure CCD is in a sane state */
- /* 1837 */ {0x6, 0x10, 0x08},
- /* 1840 */ {0x6, 0x00, 0x09},
- /* 1843 */ {0x6, 0x00, 0x0a},
- /* 1846 */ {0x6, 0x00, 0x0b},
- /* 1849 */ {0x6, 0x10, 0x0c},
- /* 1852 */ {0x6, 0x00, 0x0d},
- /* 1855 */ {0x6, 0x00, 0x0e},
- /* 1858 */ {0x6, 0x00, 0x0f},
- /* 1861 */ {0x6, 0x10, 0x10},
- /* 1864 */ {0x6, 0x02, 0x11},
- /* 1867 */ {0x6, 0x00, 0x12},
- /* 1870 */ {0x6, 0x04, 0x13},
- /* 1873 */ {0x6, 0x02, 0x14},
- /* 1876 */ {0x6, 0x8a, 0x51},
- /* 1879 */ {0x6, 0x40, 0x52},
- /* 1882 */ {0x6, 0xb6, 0x53},
- /* 1885 */ {0x6, 0x3d, 0x54},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
/* End of extra block */
- /* 1972 */ {0x6, 0x3f, 0x1},
+ {0x06, 0x3f, 0x1},
/* Block skipped */
- /* 1975 */ {0x6, 0x10, 0x02},
- /* 1978 */ {0x6, 0x64, 0x07},
- /* 1981 */ {0x6, 0x10, 0x08},
- /* 1984 */ {0x6, 0x00, 0x09},
- /* 1987 */ {0x6, 0x00, 0x0a},
- /* 1990 */ {0x6, 0x00, 0x0b},
- /* 1993 */ {0x6, 0x10, 0x0c},
- /* 1996 */ {0x6, 0x00, 0x0d},
- /* 1999 */ {0x6, 0x00, 0x0e},
- /* 2002 */ {0x6, 0x00, 0x0f},
- /* 2005 */ {0x6, 0x10, 0x10},
- /* 2008 */ {0x6, 0x02, 0x11},
- /* 2011 */ {0x6, 0x00, 0x12},
- /* 2014 */ {0x6, 0x04, 0x13},
- /* 2017 */ {0x6, 0x02, 0x14},
- /* 2020 */ {0x6, 0x8a, 0x51},
- /* 2023 */ {0x6, 0x40, 0x52},
- /* 2026 */ {0x6, 0xb6, 0x53},
- /* 2029 */ {0x6, 0x3d, 0x54},
- /* 2032 */ {0x6, 0x60, 0x57},
- /* 2035 */ {0x6, 0x20, 0x58},
- /* 2038 */ {0x6, 0x15, 0x59},
- /* 2041 */ {0x6, 0x05, 0x5a},
-
- /* 2044 */ {0x5, 0x01, 0xc0},
- /* 2047 */ {0x5, 0x10, 0xcb},
- /* 2050 */ {0x5, 0x80, 0xc1},
+ {0x06, 0x10, 0x02},
+ {0x06, 0x64, 0x07},
+ {0x06, 0x10, 0x08},
+ {0x06, 0x00, 0x09},
+ {0x06, 0x00, 0x0a},
+ {0x06, 0x00, 0x0b},
+ {0x06, 0x10, 0x0c},
+ {0x06, 0x00, 0x0d},
+ {0x06, 0x00, 0x0e},
+ {0x06, 0x00, 0x0f},
+ {0x06, 0x10, 0x10},
+ {0x06, 0x02, 0x11},
+ {0x06, 0x00, 0x12},
+ {0x06, 0x04, 0x13},
+ {0x06, 0x02, 0x14},
+ {0x06, 0x8a, 0x51},
+ {0x06, 0x40, 0x52},
+ {0x06, 0xb6, 0x53},
+ {0x06, 0x3d, 0x54},
+ {0x06, 0x60, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x15, 0x59},
+ {0x06, 0x05, 0x5a},
+
+ {0x05, 0x01, 0xc0},
+ {0x05, 0x10, 0xcb},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2053 */ {0x5, 0x0, 0xc2},
+ {0x05, 0x0, 0xc2},
/* 4 was 0 */
- /* 2056 */ {0x5, 0x00, 0xca},
- /* 2059 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2062 */ {0x5, 0x04, 0xc2},
- /* 2065 */ {0x5, 0x00, 0xca},
- /* 2068 */ {0x5, 0x0, 0xc1},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x0, 0xc1},
/* */
- /* 2071 */ {0x5, 0x00, 0xc2},
- /* 2074 */ {0x5, 0x00, 0xca},
- /* 2077 */ {0x5, 0x40, 0xc1},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x40, 0xc1},
/* */
- /* 2080 */ {0x5, 0x17, 0xc2},
- /* 2083 */ {0x5, 0x00, 0xca},
- /* 2086 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x17, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2089 */ {0x5, 0x06, 0xc2},
- /* 2092 */ {0x5, 0x00, 0xca},
- /* 2095 */ {0x5, 0x80, 0xc1},
+ {0x05, 0x06, 0xc2},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x80, 0xc1},
/* */
- /* 2098 */ {0x5, 0x04, 0xc2},
- /* 2101 */ {0x5, 0x00, 0xca},
+ {0x05, 0x04, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2104 */ {0x3, 0x4c, 0x3},
- /* 2107 */ {0x3, 0x18, 0x1},
+ {0x03, 0x4c, 0x3},
+ {0x03, 0x18, 0x1},
- /* 2110 */ {0x6, 0x70, 0x51},
- /* 2113 */ {0x6, 0xbe, 0x53},
- /* 2116 */ {0x6, 0x71, 0x57},
- /* 2119 */ {0x6, 0x20, 0x58},
- /* 2122 */ {0x6, 0x05, 0x59},
- /* 2125 */ {0x6, 0x15, 0x5a},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
+ {0x06, 0x71, 0x57},
+ {0x06, 0x20, 0x58},
+ {0x06, 0x05, 0x59},
+ {0x06, 0x15, 0x5a},
- /* 2128 */ {0x4, 0x00, 0x08},
+ {0x04, 0x00, 0x08},
/* Compress = OFF (0x1 to turn on) */
- /* 2131 */ {0x4, 0x12, 0x09},
- /* 2134 */ {0x4, 0x21, 0x0a},
- /* 2137 */ {0x4, 0x10, 0x0b},
- /* 2140 */ {0x4, 0x21, 0x0c},
- /* 2143 */ {0x4, 0x05, 0x00},
+ {0x04, 0x12, 0x09},
+ {0x04, 0x21, 0x0a},
+ {0x04, 0x10, 0x0b},
+ {0x04, 0x21, 0x0c},
+ {0x04, 0x05, 0x00},
/* was 5 (Image Type ? ) */
- /* 2146 */ {0x4, 0x00, 0x01},
-
- /* 2149 */ {0x6, 0x3f, 0x01},
-
- /* 2152 */ {0x4, 0x00, 0x04},
- /* 2155 */ {0x4, 0x00, 0x05},
- /* 2158 */ {0x4, 0x40, 0x06},
- /* 2161 */ {0x4, 0x40, 0x07},
-
- /* 2164 */ {0x6, 0x1c, 0x17},
- /* 2167 */ {0x6, 0xe2, 0x19},
- /* 2170 */ {0x6, 0x1c, 0x1b},
- /* 2173 */ {0x6, 0xe2, 0x1d},
- /* 2176 */ {0x6, 0xaa, 0x1f},
- /* 2179 */ {0x6, 0x70, 0x20},
-
- /* 2182 */ {0x5, 0x01, 0x10},
- /* 2185 */ {0x5, 0x00, 0x11},
- /* 2188 */ {0x5, 0x01, 0x00},
- /* 2191 */ {0x5, 0x05, 0x01},
- /* 2194 */ {0x5, 0x00, 0xc1},
+ {0x04, 0x00, 0x01},
+
+ {0x06, 0x3f, 0x01},
+
+ {0x04, 0x00, 0x04},
+ {0x04, 0x00, 0x05},
+ {0x04, 0x40, 0x06},
+ {0x04, 0x40, 0x07},
+
+ {0x06, 0x1c, 0x17},
+ {0x06, 0xe2, 0x19},
+ {0x06, 0x1c, 0x1b},
+ {0x06, 0xe2, 0x1d},
+ {0x06, 0xaa, 0x1f},
+ {0x06, 0x70, 0x20},
+
+ {0x05, 0x01, 0x10},
+ {0x05, 0x00, 0x11},
+ {0x05, 0x01, 0x00},
+ {0x05, 0x05, 0x01},
+ {0x05, 0x00, 0xc1},
/* */
- /* 2197 */ {0x5, 0x00, 0xc2},
- /* 2200 */ {0x5, 0x00, 0xca},
+ {0x05, 0x00, 0xc2},
+ {0x05, 0x00, 0xca},
- /* 2203 */ {0x6, 0x70, 0x51},
- /* 2206 */ {0x6, 0xbe, 0x53},
+ {0x06, 0x70, 0x51},
+ {0x06, 0xbe, 0x53},
{}
};
/*
- Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
+ * Made by Tomasz Zablocki (skalamandra@poczta.onet.pl)
* SPCA505b chip based cameras initialization data
- *
*/
/* jfm */
#define initial_brightness 0x7f /* 0x0(white)-0xff(black) */
@@ -332,7 +333,7 @@ static const __u16 spca505_open_data_ccd[][3] = {
/*
* Data to initialize a SPCA505. Common to the CCD and external modes
*/
-static const __u16 spca505b_init_data[][3] = {
+static const u8 spca505b_init_data[][3] = {
/* start */
{0x02, 0x00, 0x00}, /* init */
{0x02, 0x00, 0x01},
@@ -396,7 +397,7 @@ static const __u16 spca505b_init_data[][3] = {
/*
* Data to initialize the camera using the internal CCD
*/
-static const __u16 spca505b_open_data_ccd[][3] = {
+static const u8 spca505b_open_data_ccd[][3] = {
/* {0x02,0x00,0x00}, */
{0x03, 0x04, 0x01}, /* rst */
@@ -426,7 +427,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0x00, 0x12},
{0x05, 0x6f, 0x00},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x00, 0x02},
{0x05, 0x01, 0x03},
{0x05, 0x00, 0x04},
@@ -436,7 +437,7 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x05, 0xa0, 0x08},
{0x05, 0x00, 0x12},
{0x05, 0x02, 0x0f},
- {0x05, 128, 0x14}, /* max exposure off (0=on) */
+ {0x05, 0x80, 0x14}, /* max exposure off (0=on) */
{0x05, 0x01, 0xb0},
{0x05, 0x01, 0xbf},
{0x03, 0x02, 0x06},
@@ -560,26 +561,26 @@ static const __u16 spca505b_open_data_ccd[][3] = {
{0x06, 0x32, 0x20},
{0x05, initial_brightness >> 6, 0x00},
- {0x05, initial_brightness << 2, 0x01},
+ {0x05, (initial_brightness << 2) & 0xff, 0x01},
{0x05, 0x06, 0xc1},
{0x05, 0x58, 0xc2},
- {0x05, 0x0, 0xca},
- {0x05, 0x0, 0x11},
+ {0x05, 0x00, 0xca},
+ {0x05, 0x00, 0x11},
{}
};
static int reg_write(struct usb_device *dev,
- __u16 reg, __u16 index, __u16 value)
+ u16 req, u16 index, u16 value)
{
int ret;
ret = usb_control_msg(dev,
usb_sndctrlpipe(dev, 0),
- reg,
+ req,
USB_TYPE_VENDOR | USB_RECIP_DEVICE,
value, index, NULL, 0, 500);
- PDEBUG(D_PACK, "reg write: 0x%02x,0x%02x:0x%02x, 0x%x",
- reg, index, value, ret);
+ PDEBUG(D_USBO, "reg write: 0x%02x,0x%02x:0x%02x, %d",
+ req, index, value, ret);
if (ret < 0)
PDEBUG(D_ERR, "reg write: error %d", ret);
return ret;
@@ -587,42 +588,34 @@ static int reg_write(struct usb_device *dev,
/* returns: negative is error, pos or zero is data */
static int reg_read(struct gspca_dev *gspca_dev,
- __u16 reg, /* bRequest */
- __u16 index, /* wIndex */
- __u16 length) /* wLength (1 or 2 only) */
+ u16 req, /* bRequest */
+ u16 index) /* wIndex */
{
int ret;
- gspca_dev->usb_buf[1] = 0;
ret = usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- reg,
+ req,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
- (__u16) 0, /* value */
- (__u16) index,
- gspca_dev->usb_buf, length,
+ 0, /* value */
+ index,
+ gspca_dev->usb_buf, 2,
500); /* timeout */
- if (ret < 0) {
- PDEBUG(D_ERR, "reg_read err %d", ret);
- return -1;
- }
+ if (ret < 0)
+ return ret;
return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u8 data[][3])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
- while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
+ while (data[i][0] != 0) {
ret = reg_write(dev, data[i][0], data[i][2], data[i][1]);
- if (ret < 0) {
- PDEBUG(D_ERR,
- "Register write failed for 0x%x,0x%x,0x%x",
- data[i][0], data[i][1], data[i][2]);
+ if (ret < 0)
return ret;
- }
i++;
}
return 0;
@@ -636,14 +629,13 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
sd->subtype = id->driver_info;
if (sd->subtype != IntelPCCameraPro)
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
+ cam->nmodes = ARRAY_SIZE(vga_mode);
else /* no 640x480 for IntelPCCameraPro */
- cam->nmodes = sizeof vga_mode / sizeof vga_mode[0] - 1;
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
+ cam->nmodes = ARRAY_SIZE(vga_mode) - 1;
+ sd->brightness = BRIGHTNESS_DEF;
if (sd->subtype == Nxultra) {
if (write_vector(gspca_dev, spca505b_init_data))
@@ -658,81 +650,71 @@ static int sd_config(struct gspca_dev *gspca_dev,
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
+ return 0;
+}
+
+static void setbrightness(struct gspca_dev *gspca_dev)
+{
struct sd *sd = (struct sd *) gspca_dev;
- int ret;
+ u8 brightness = sd->brightness;
+
+ reg_write(gspca_dev->dev, 0x05, 0x00, (255 - brightness) >> 6);
+ reg_write(gspca_dev->dev, 0x05, 0x01, (255 - brightness) << 2);
+}
+
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+ struct usb_device *dev = gspca_dev->dev;
+ int ret, mode;
+ static u8 mode_tb[][3] = {
+ /* r00 r06 r07 */
+ {0x00, 0x10, 0x10}, /* 640x480 */
+ {0x01, 0x1a, 0x1a}, /* 352x288 */
+ {0x02, 0x1c, 0x1d}, /* 320x240 */
+ {0x04, 0x34, 0x34}, /* 176x144 */
+ {0x05, 0x40, 0x40} /* 160x120 */
+ };
- PDEBUG(D_STREAM, "Initializing SPCA505");
if (sd->subtype == Nxultra)
write_vector(gspca_dev, spca505b_open_data_ccd);
else
write_vector(gspca_dev, spca505_open_data_ccd);
- ret = reg_read(gspca_dev, 6, 0x16, 2);
+ ret = reg_read(gspca_dev, 0x06, 0x16);
if (ret < 0) {
- PDEBUG(D_ERR|D_STREAM,
- "register read failed for after vector read err = %d",
+ PDEBUG(D_ERR|D_CONF,
+ "register read failed err: %d",
ret);
- return -EIO;
+ return ret;
}
- PDEBUG(D_STREAM,
- "After vector read returns : 0x%x should be 0x0101",
- ret & 0xffff);
-
- ret = reg_write(gspca_dev->dev, 6, 0x16, 0x0a);
- if (ret < 0) {
- PDEBUG(D_ERR, "register write failed for (6,0xa,0x16) err=%d",
- ret);
- return -EIO;
+ if (ret != 0x0101) {
+ PDEBUG(D_ERR|D_CONF,
+ "After vector read returns 0x%04x should be 0x0101",
+ ret);
}
- reg_write(gspca_dev->dev, 5, 0xc2, 18);
- return 0;
-}
-static int sd_start(struct gspca_dev *gspca_dev)
-{
- struct usb_device *dev = gspca_dev->dev;
- int ret;
+ ret = reg_write(gspca_dev->dev, 0x06, 0x16, 0x0a);
+ if (ret < 0)
+ return ret;
+ reg_write(gspca_dev->dev, 0x05, 0xc2, 0x12);
/* necessary because without it we can see stream
* only once after loading module */
/* stopping usb registers Tomasz change */
- reg_write(dev, 0x02, 0x0, 0x0);
- switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
- case 0:
- reg_write(dev, 0x04, 0x00, 0x00);
- reg_write(dev, 0x04, 0x06, 0x10);
- reg_write(dev, 0x04, 0x07, 0x10);
- break;
- case 1:
- reg_write(dev, 0x04, 0x00, 0x01);
- reg_write(dev, 0x04, 0x06, 0x1a);
- reg_write(dev, 0x04, 0x07, 0x1a);
- break;
- case 2:
- reg_write(dev, 0x04, 0x00, 0x02);
- reg_write(dev, 0x04, 0x06, 0x1c);
- reg_write(dev, 0x04, 0x07, 0x1d);
- break;
- case 4:
- reg_write(dev, 0x04, 0x00, 0x04);
- reg_write(dev, 0x04, 0x06, 0x34);
- reg_write(dev, 0x04, 0x07, 0x34);
- break;
- default:
-/* case 5: */
- reg_write(dev, 0x04, 0x00, 0x05);
- reg_write(dev, 0x04, 0x06, 0x40);
- reg_write(dev, 0x04, 0x07, 0x40);
- break;
- }
-/* Enable ISO packet machine - should we do this here or in ISOC init ? */
+ reg_write(dev, 0x02, 0x00, 0x00);
+
+ mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x00, mode_tb[mode][0]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x06, mode_tb[mode][1]);
+ reg_write(dev, SPCA50X_REG_COMPRESS, 0x07, mode_tb[mode][2]);
+
ret = reg_write(dev, SPCA50X_REG_USB,
SPCA50X_USB_CTRL,
SPCA50X_CUSB_ENABLE);
-/* reg_write(dev, 0x5, 0x0, 0x0); */
-/* reg_write(dev, 0x5, 0x0, 0x1); */
-/* reg_write(dev, 0x5, 0x11, 0x2); */
+ setbrightness(gspca_dev);
+
return ret;
}
@@ -750,15 +732,15 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
/* This maybe reset or power control */
reg_write(gspca_dev->dev, 0x03, 0x03, 0x20);
- reg_write(gspca_dev->dev, 0x03, 0x01, 0x0);
- reg_write(gspca_dev->dev, 0x03, 0x00, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x10, 0x1);
- reg_write(gspca_dev->dev, 0x05, 0x11, 0xf);
+ reg_write(gspca_dev->dev, 0x03, 0x01, 0x00);
+ reg_write(gspca_dev->dev, 0x03, 0x00, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x10, 0x01);
+ reg_write(gspca_dev->dev, 0x05, 0x11, 0x0f);
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
switch (data[0]) {
@@ -771,7 +753,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
data, len);
break;
case 0xff: /* drop */
-/* gspca_dev->last_packet_type = DISCARD_PACKET; */
break;
default:
data += 1;
@@ -782,24 +763,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
}
}
-static void setbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- __u8 brightness = sd->brightness;
- reg_write(gspca_dev->dev, 5, 0x00, (255 - brightness) >> 6);
- reg_write(gspca_dev->dev, 5, 0x01, (255 - brightness) << 2);
-
-}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = 255
- - ((reg_read(gspca_dev, 5, 0x01, 1) >> 2)
- + (reg_read(gspca_dev, 5, 0x0, 1) << 6));
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -814,7 +777,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -863,8 +825,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c
index 96e2512e062..3a0c893f942 100644
--- a/drivers/media/video/gspca/spca506.c
+++ b/drivers/media/video/gspca/spca506.c
@@ -193,24 +193,6 @@ static void spca506_WriteI2c(struct gspca_dev *gspca_dev, __u16 valeur,
}
}
-static int spca506_ReadI2c(struct gspca_dev *gspca_dev, __u16 reg)
-{
- int retry = 60;
-
- reg_w(gspca_dev->dev, 0x07, SAA7113_I2C_BASE_WRITE, 0x0004);
- reg_w(gspca_dev->dev, 0x07, reg, 0x0001);
- reg_w(gspca_dev->dev, 0x07, 0x01, 0x0002);
- while (--retry) {
- reg_r(gspca_dev, 0x07, 0x0003, 2);
- if ((gspca_dev->usb_buf[0] | gspca_dev->usb_buf[1]) == 0x00)
- break;
- }
- if (retry == 0)
- return -1;
- reg_r(gspca_dev, 0x07, 0x0000, 1);
- return gspca_dev->usb_buf[0];
-}
-
static void spca506_SetNormeInput(struct gspca_dev *gspca_dev,
__u16 norme,
__u16 channel)
@@ -303,7 +285,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode;
cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
@@ -596,13 +577,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = spca506_ReadI2c(gspca_dev, SAA7113_bright);
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -612,13 +586,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = spca506_ReadI2c(gspca_dev, SAA7113_contrast);
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -628,13 +595,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->colors = spca506_ReadI2c(gspca_dev, SAA7113_saturation);
-}
-
static void sethue(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -644,13 +604,6 @@ static void sethue(struct gspca_dev *gspca_dev)
spca506_WriteI2c(gspca_dev, 0x01, 0x09);
}
-static void gethue(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->hue = spca506_ReadI2c(gspca_dev, SAA7113_hue);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -665,7 +618,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -684,7 +636,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -703,7 +654,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -722,7 +672,6 @@ static int sd_gethue(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- gethue(gspca_dev);
*val = sd->hue;
return 0;
}
@@ -772,8 +721,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca508.c b/drivers/media/video/gspca/spca508.c
index be5d740a315..adacf843766 100644
--- a/drivers/media/video/gspca/spca508.c
+++ b/drivers/media/video/gspca/spca508.c
@@ -101,8 +101,7 @@ static const struct v4l2_pix_format sif_mode[] = {
* Initialization data: this is the first set-up data written to the
* device (before the open data).
*/
-static const __u16 spca508_init_data[][3] =
-#define IGN(x) /* nothing */
+static const u16 spca508_init_data[][2] =
{
/* line URB value, index */
/* 44274 1804 */ {0x0000, 0x870b},
@@ -589,11 +588,10 @@ static const __u16 spca508_init_data[][3] =
{}
};
-
/*
* Initialization data for Intel EasyPC Camera CS110
*/
-static const __u16 spca508cs110_init_data[][3] = {
+static const u16 spca508cs110_init_data[][2] = {
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0003, 0x8111}, /* Soft Reset compression, memory, TG & CDSP */
{0x0000, 0x8111}, /* Normal operation on reset */
@@ -677,7 +675,7 @@ static const __u16 spca508cs110_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam_init_data[][3] = {
+static const u16 spca508_sightcam_init_data[][2] = {
/* This line seems to setup the frame/canvas */
/*368 */ {0x000f, 0x8402},
@@ -760,7 +758,7 @@ static const __u16 spca508_sightcam_init_data[][3] = {
{}
};
-static const __u16 spca508_sightcam2_init_data[][3] = {
+static const u16 spca508_sightcam2_init_data[][2] = {
/* 35 */ {0x0020, 0x8112},
/* 36 */ {0x000f, 0x8402},
@@ -1107,7 +1105,7 @@ static const __u16 spca508_sightcam2_init_data[][3] = {
/*
* Initialization data for Creative Webcam Vista
*/
-static const __u16 spca508_vista_init_data[][3] = {
+static const u16 spca508_vista_init_data[][2] = {
{0x0008, 0x8200}, /* Clear register */
{0x0000, 0x870b}, /* Reset CTL3 */
{0x0020, 0x8112}, /* Video Drop packet enable */
@@ -1309,18 +1307,18 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0050, 0x8703},
{0x0002, 0x8704}, /* External input CKIx1 */
- {0x0001, 0x870C}, /* Select CKOx2 output */
- {0x009A, 0x8600}, /* Line memory Read Counter (L) */
+ {0x0001, 0x870c}, /* Select CKOx2 output */
+ {0x009a, 0x8600}, /* Line memory Read Counter (L) */
{0x0001, 0x8606}, /* 1 Line memory Read Counter (H) Result: (d)410 */
{0x0023, 0x8601},
{0x0010, 0x8602},
- {0x000A, 0x8603},
+ {0x000a, 0x8603},
{0x009A, 0x8600},
- {0x0001, 0x865B}, /* 1 Horizontal Offset for Valid Pixel(L) */
- {0x0003, 0x865C}, /* Vertical offset for valid lines (L) */
- {0x0058, 0x865D}, /* Horizontal valid pixels window (L) */
- {0x0048, 0x865E}, /* Vertical valid lines window (L) */
- {0x0000, 0x865F},
+ {0x0001, 0x865b}, /* 1 Horizontal Offset for Valid Pixel(L) */
+ {0x0003, 0x865c}, /* Vertical offset for valid lines (L) */
+ {0x0058, 0x865d}, /* Horizontal valid pixels window (L) */
+ {0x0048, 0x865e}, /* Vertical valid lines window (L) */
+ {0x0000, 0x865f},
{0x0006, 0x8660},
/* Enable nibble data input, select nibble input order */
@@ -1328,63 +1326,63 @@ static const __u16 spca508_vista_init_data[][3] = {
{0x0013, 0x8608}, /* A11 Coeficients for color correction */
{0x0028, 0x8609},
/* Note: these values are confirmed at the end of array */
- {0x0005, 0x860A}, /* ... */
- {0x0025, 0x860B},
- {0x00E1, 0x860C},
- {0x00FA, 0x860D},
- {0x00F4, 0x860E},
- {0x00E8, 0x860F},
+ {0x0005, 0x860a}, /* ... */
+ {0x0025, 0x860b},
+ {0x00e1, 0x860c},
+ {0x00fa, 0x860D},
+ {0x00f4, 0x860e},
+ {0x00e8, 0x860f},
{0x0025, 0x8610}, /* A33 Coef. */
- {0x00FC, 0x8611}, /* White balance offset: R */
+ {0x00fc, 0x8611}, /* White balance offset: R */
{0x0001, 0x8612}, /* White balance offset: Gr */
- {0x00FE, 0x8613}, /* White balance offset: B */
+ {0x00fe, 0x8613}, /* White balance offset: B */
{0x0000, 0x8614}, /* White balance offset: Gb */
{0x0064, 0x8651}, /* R gain for white balance (L) */
{0x0040, 0x8652}, /* Gr gain for white balance (L) */
{0x0066, 0x8653}, /* B gain for white balance (L) */
{0x0040, 0x8654}, /* Gb gain for white balance (L) */
- {0x0001, 0x863F}, /* Enable fixed gamma correction */
+ {0x0001, 0x863f}, /* Enable fixed gamma correction */
- {0x00A1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
+ {0x00a1, 0x8656}, /* Size - Window1: 256x256, Window2: 128x128 */
/* UV division: UV no change, Enable New edge enhancement */
{0x0018, 0x8657}, /* Edge gain high threshold */
{0x0020, 0x8658}, /* Edge gain low threshold */
{0x000A, 0x8659}, /* Edge bandwidth high threshold */
- {0x0005, 0x865A}, /* Edge bandwidth low threshold */
+ {0x0005, 0x865a}, /* Edge bandwidth low threshold */
{0x0064, 0x8607}, /* UV filter enable */
{0x0016, 0x8660},
- {0x0000, 0x86B0}, /* Bad pixels compensation address */
- {0x00DC, 0x86B1}, /* X coord for bad pixels compensation (L) */
- {0x0000, 0x86B2},
- {0x0009, 0x86B3}, /* Y coord for bad pixels compensation (L) */
- {0x0000, 0x86B4},
-
- {0x0001, 0x86B0},
- {0x00F5, 0x86B1},
- {0x0000, 0x86B2},
- {0x00C6, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0002, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D7, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0003, 0x86B0},
- {0x001C, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
-
- {0x0004, 0x86B0},
- {0x001D, 0x86B1},
- {0x0001, 0x86B2},
- {0x00D8, 0x86B3},
- {0x0000, 0x86B4},
- {0x001E, 0x8660},
+ {0x0000, 0x86b0}, /* Bad pixels compensation address */
+ {0x00dc, 0x86b1}, /* X coord for bad pixels compensation (L) */
+ {0x0000, 0x86b2},
+ {0x0009, 0x86b3}, /* Y coord for bad pixels compensation (L) */
+ {0x0000, 0x86b4},
+
+ {0x0001, 0x86b0},
+ {0x00f5, 0x86b1},
+ {0x0000, 0x86b2},
+ {0x00c6, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0002, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d7, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0003, 0x86b0},
+ {0x001c, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+
+ {0x0004, 0x86b0},
+ {0x001d, 0x86b1},
+ {0x0001, 0x86b2},
+ {0x00d8, 0x86b3},
+ {0x0000, 0x86b4},
+ {0x001e, 0x8660},
/* READ { 0, 0x0000, 0x8608 } ->
0000: 13 */
@@ -1449,7 +1447,7 @@ static int reg_read(struct gspca_dev *gspca_dev,
}
static int write_vector(struct gspca_dev *gspca_dev,
- const __u16 data[][3])
+ const u16 data[][2])
{
struct usb_device *dev = gspca_dev->dev;
int ret, i = 0;
@@ -1487,7 +1485,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Window 1 average luminance: %d", data1);
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
@@ -1593,13 +1590,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
reg_write(gspca_dev->dev, 0x8654, brightness);
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->brightness = reg_read(gspca_dev, 0x8651);
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1614,7 +1604,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1666,8 +1655,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/spca561.c b/drivers/media/video/gspca/spca561.c
index 3c9288019e9..c99c5e34e21 100644
--- a/drivers/media/video/gspca/spca561.c
+++ b/drivers/media/video/gspca/spca561.c
@@ -141,38 +141,38 @@ static const struct v4l2_pix_format sif_072a_mode[] = {
#define SPCA561_OFFSET_WIN1GBAVE 14
#define SPCA561_OFFSET_FREQ 15
#define SPCA561_OFFSET_VSYNC 16
-#define SPCA561_OFFSET_DATA 1
#define SPCA561_INDEX_I2C_BASE 0x8800
#define SPCA561_SNAPBIT 0x20
#define SPCA561_SNAPCTRL 0x40
-static const __u16 rev72a_init_data1[][2] = {
+static const u16 rev72a_reset[][2] = {
{0x0000, 0x8114}, /* Software GPIO output data */
{0x0001, 0x8114}, /* Software GPIO output data */
{0x0000, 0x8112}, /* Some kind of reset */
+ {}
+};
+static const __u16 rev72a_init_data1[][2] = {
{0x0003, 0x8701}, /* PCLK clock delay adjustment */
{0x0001, 0x8703}, /* HSYNC from cmos inverted */
{0x0011, 0x8118}, /* Enable and conf sensor */
{0x0001, 0x8118}, /* Conf sensor */
{0x0092, 0x8804}, /* I know nothing about these */
{0x0010, 0x8802}, /* 0x88xx registers, so I won't */
- {0x000d, 0x8805}, /* sensor default setting */
{}
};
-static const __u16 rev72a_init_sensor1[][2] = {
- /* ms-win values */
- {0x0001, 0x0018}, /* 0x01 <- 0x0d */
- {0x0002, 0x0065}, /* 0x02 <- 0x18 */
- {0x0004, 0x0121}, /* 0x04 <- 0x0165 */
- {0x0005, 0x00aa}, /* 0x05 <- 0x21 */
- {0x0007, 0x0004}, /* 0x07 <- 0xaa */
- {0x0020, 0x1502}, /* 0x20 <- 0x1504 */
- {0x0039, 0x0010}, /* 0x39 <- 0x02 */
- {0x0035, 0x0049}, /* 0x35 <- 0x10 */
- {0x0009, 0x100b}, /* 0x09 <- 0x1049 */
- {0x0028, 0x000f}, /* 0x28 <- 0x0b */
- {0x003b, 0x003c}, /* 0x3b <- 0x0f */
- {0x003c, 0x0000}, /* 0x3c <- 0x00 */
+static const u16 rev72a_init_sensor1[][2] = {
+ {0x0001, 0x000d},
+ {0x0002, 0x0018},
+ {0x0004, 0x0165},
+ {0x0005, 0x0021},
+ {0x0007, 0x00aa},
+ {0x0020, 0x1504},
+ {0x0039, 0x0002},
+ {0x0035, 0x0010},
+ {0x0009, 0x1049},
+ {0x0028, 0x000b},
+ {0x003b, 0x000f},
+ {0x003c, 0x0000},
{}
};
static const __u16 rev72a_init_data2[][2] = {
@@ -190,15 +190,10 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0002, 0x8201}, /* Output address for r/w serial EEPROM */
{0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
{0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0007, 0x8201}, /* Output address for r/w serial EEPROM */
- {0x0008, 0x8200}, /* Clear valid bit for serial EEPROM */
- {0x0001, 0x8200}, /* OprMode to be executed by hardware */
- {0x0010, 0x8660}, /* Compensation memory stuff */
- {0x0018, 0x8660}, /* Compensation memory stuff */
-
- {0x0004, 0x8611}, /* R offset for white balance */
- {0x0004, 0x8612}, /* Gr offset for white balance */
- {0x0007, 0x8613}, /* B offset for white balance */
+/* from ms-win */
+ {0x0000, 0x8611}, /* R offset for white balance */
+ {0x00fd, 0x8612}, /* Gr offset for white balance */
+ {0x0003, 0x8613}, /* B offset for white balance */
{0x0000, 0x8614}, /* Gb offset for white balance */
/* from ms-win */
{0x0035, 0x8651}, /* R gain for white balance */
@@ -206,8 +201,8 @@ static const __u16 rev72a_init_data2[][2] = {
{0x005f, 0x8653}, /* B gain for white balance */
{0x0040, 0x8654}, /* Gb gain for white balance */
{0x0002, 0x8502}, /* Maximum average bit rate stuff */
-
{0x0011, 0x8802},
+
{0x0087, 0x8700}, /* Set master clock (96Mhz????) */
{0x0081, 0x8702}, /* Master clock output enable */
@@ -218,104 +213,15 @@ static const __u16 rev72a_init_data2[][2] = {
{0x0003, 0x865c}, /* Vertical offset for valid lines */
{}
};
-static const __u16 rev72a_init_sensor2[][2] = {
- /* ms-win values */
- {0x0003, 0x0121}, /* 0x03 <- 0x01 0x21 //289 */
- {0x0004, 0x0165}, /* 0x04 <- 0x01 0x65 //357 */
- {0x0005, 0x002f}, /* 0x05 <- 0x2f */
- {0x0006, 0x0000}, /* 0x06 <- 0 */
- {0x000a, 0x0002}, /* 0x0a <- 2 */
- {0x0009, 0x1061}, /* 0x09 <- 0x1061 */
- {0x0035, 0x0014}, /* 0x35 <- 0x14 */
- {}
-};
-static const __u16 rev72a_init_data3[][2] = {
- {0x0030, 0x8112}, /* ISO and drop packet enable */
-/*fixme: should stop here*/
- {0x0000, 0x8112}, /* Some kind of reset ???? */
- {0x0009, 0x8118}, /* Enable sensor and set standby */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8114}, /* Software GPIO output data */
- {0x0001, 0x8114}, /* Software GPIO output data */
- {0x0000, 0x8112}, /* Some kind of reset ??? */
- {0x0003, 0x8701},
- {0x0001, 0x8703},
- {0x0011, 0x8118},
- {0x0001, 0x8118},
- /***************/
- {0x0092, 0x8804},
- {0x0010, 0x8802},
- {0x000d, 0x8805},
- {0x0001, 0x8801},
- {0x0000, 0x8800},
- {0x0018, 0x8805},
- {0x0002, 0x8801},
- {0x0000, 0x8800},
- {0x0065, 0x8805},
- {0x0004, 0x8801},
- {0x0001, 0x8800},
- {0x0021, 0x8805},
- {0x0005, 0x8801},
- {0x0000, 0x8800},
- {0x00aa, 0x8805},
- {0x0007, 0x8801}, /* mode 0xaa */
- {0x0000, 0x8800},
- {0x0004, 0x8805},
- {0x0020, 0x8801},
- {0x0015, 0x8800}, /* mode 0x0415 */
- {0x0002, 0x8805},
- {0x0039, 0x8801},
- {0x0000, 0x8800},
- {0x0010, 0x8805},
- {0x0035, 0x8801},
- {0x0000, 0x8800},
- {0x0049, 0x8805},
- {0x0009, 0x8801},
- {0x0010, 0x8800},
- {0x000b, 0x8805},
- {0x0028, 0x8801},
- {0x0000, 0x8800},
- {0x000f, 0x8805},
- {0x003b, 0x8801},
- {0x0000, 0x8800},
- {0x0000, 0x8805},
- {0x003c, 0x8801},
- {0x0000, 0x8800},
- {0x0002, 0x8502},
- {0x0039, 0x8801},
- {0x0000, 0x8805},
- {0x0000, 0x8800},
-
- {0x0087, 0x8700}, /* overwrite by start */
- {0x0081, 0x8702},
- {0x0000, 0x8500},
-/* {0x0010, 0x8500}, -- Previous line was this */
- {0x0002, 0x865b},
- {0x0003, 0x865c},
- /***************/
- {0x0003, 0x8801}, /* 0x121-> 289 */
- {0x0021, 0x8805},
- {0x0001, 0x8800},
- {0x0004, 0x8801}, /* 0x165 -> 357 */
- {0x0065, 0x8805},
- {0x0001, 0x8800},
- {0x0005, 0x8801}, /* 0x2f //blanking control colonne */
- {0x002f, 0x8805},
- {0x0000, 0x8800},
- {0x0006, 0x8801}, /* 0x00 //blanking mode row */
- {0x0000, 0x8805},
- {0x0000, 0x8800},
- {0x000a, 0x8801}, /* 0x01 //0x02 */
- {0x0001, 0x8805},
- {0x0000, 0x8800},
- {0x0009, 0x8801}, /* 0x1061 - setexposure times && pixel clock
+static const u16 rev72a_init_sensor2[][2] = {
+ {0x0003, 0x0121},
+ {0x0004, 0x0165},
+ {0x0005, 0x002f}, /* blanking control column */
+ {0x0006, 0x0000}, /* blanking mode row*/
+ {0x000a, 0x0002},
+ {0x0009, 0x1061}, /* setexposure times && pixel clock
* 0001 0 | 000 0110 0001 */
- {0x0061, 0x8805}, /* 61 31 */
- {0x0008, 0x8800}, /* 08 */
- {0x0035, 0x8801}, /* 0x14 - set gain general */
- {0x001f, 0x8805}, /* 0x14 */
- {0x0000, 0x8800},
- {0x000e, 0x8112}, /* white balance - was 30 */
+ {0x0035, 0x0014},
{}
};
@@ -460,6 +366,7 @@ static void i2c_write(struct gspca_dev *gspca_dev, __u16 value, __u16 reg)
reg_r(gspca_dev, 0x8803, 1);
if (!gspca_dev->usb_buf[0])
return;
+ msleep(10);
} while (--retry);
}
@@ -479,6 +386,7 @@ static int i2c_read(struct gspca_dev *gspca_dev, __u16 reg, __u8 mode)
reg_r(gspca_dev, 0x8805, 1);
return ((int) value << 8) | gspca_dev->usb_buf[0];
}
+ msleep(10);
} while (--retry);
return -1;
}
@@ -541,7 +449,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
gspca_dev->nbalt = 7 + 1; /* choose alternate 7 first */
sd->chip_revision = id->driver_info;
@@ -572,11 +479,13 @@ static int sd_init_12a(struct gspca_dev *gspca_dev)
static int sd_init_72a(struct gspca_dev *gspca_dev)
{
PDEBUG(D_STREAM, "Chip revision: 072a");
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
write_vector(gspca_dev, rev72a_init_data1);
write_sensor_72a(gspca_dev, rev72a_init_sensor1);
write_vector(gspca_dev, rev72a_init_data2);
write_sensor_72a(gspca_dev, rev72a_init_sensor2);
- write_vector(gspca_dev, rev72a_init_data3);
+ reg_w_val(gspca_dev->dev, 0x8112, 0x30);
return 0;
}
@@ -731,11 +640,18 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
int Clck;
int mode;
+ write_vector(gspca_dev, rev72a_reset);
+ msleep(200);
+ write_vector(gspca_dev, rev72a_init_data1);
+ write_sensor_72a(gspca_dev, rev72a_init_sensor1);
+
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
switch (mode) {
default:
-/* case 0:
- case 1: */
+ case 0:
+ Clck = 0x27; /* ms-win 0x87 */
+ break;
+ case 1:
Clck = 0x25;
break;
case 2:
@@ -745,13 +661,14 @@ static int sd_start_72a(struct gspca_dev *gspca_dev)
Clck = 0x21;
break;
}
- reg_w_val(dev, 0x8500, mode); /* mode */
reg_w_val(dev, 0x8700, Clck); /* 0x27 clock */
- reg_w_val(dev, 0x8112, 0x10 | 0x20);
+ reg_w_val(dev, 0x8702, 0x81);
+ reg_w_val(dev, 0x8500, mode); /* mode */
+ write_sensor_72a(gspca_dev, rev72a_init_sensor2);
setcontrast(gspca_dev);
/* setbrightness(gspca_dev); * fixme: bad values */
- setwhite(gspca_dev);
setautogain(gspca_dev);
+ reg_w_val(dev, 0x8112, 0x10 | 0x20);
return 0;
}
@@ -867,12 +784,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
{
struct sd *sd = (struct sd *) gspca_dev;
- switch (data[0]) { /* sequence number */
+ len--;
+ switch (*data++) { /* sequence number */
case 0: /* start of frame */
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
- data += SPCA561_OFFSET_DATA;
- len -= SPCA561_OFFSET_DATA;
if (data[1] & 0x10) {
/* compressed bayer */
gspca_frame_add(gspca_dev, FIRST_PACKET,
@@ -893,8 +809,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
case 0xff: /* drop (empty mpackets) */
return;
}
- data++;
- len--;
gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
}
@@ -1197,8 +1111,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/sq905.c b/drivers/media/video/gspca/sq905.c
new file mode 100644
index 00000000000..04e3ae57a2e
--- /dev/null
+++ b/drivers/media/video/gspca/sq905.c
@@ -0,0 +1,456 @@
+/*
+ * SQ905 subdriver
+ *
+ * Copyright (C) 2008, 2009 Adam Baker and Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 and Acknowledgments
+ *
+ * The original Linux driver for SQ905 based cameras was written by
+ * Marcell Lengyel and furter developed by many other contributers
+ * and is available from http://sourceforge.net/projects/sqcam/
+ *
+ * This driver takes advantage of the reverse engineering work done for
+ * that driver and for libgphoto2 but shares no code with them.
+ *
+ * This driver has used as a base the finepix driver and other gspca
+ * based drivers and may still contain code fragments taken from those
+ * drivers.
+ */
+
+#define MODULE_NAME "sq905"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Adam Baker <linux@baker-net.org.uk>, "
+ "Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905 USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905_CMD_TIMEOUT 500
+#define SQ905_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905_MAX_TRANSFER 0x8000
+#define FRAME_HEADER_LEN 64
+
+/* The known modes, or registers. These go in the "value" slot. */
+
+/* 00 is "none" obviously */
+
+#define SQ905_BULK_READ 0x03 /* precedes any bulk read */
+#define SQ905_COMMAND 0x06 /* precedes the command codes below */
+#define SQ905_PING 0x07 /* when reading an "idling" command */
+#define SQ905_READ_DONE 0xc0 /* ack bulk read completed */
+
+/* Any non-zero value in the bottom 2 bits of the 2nd byte of
+ * the ID appears to indicate the camera can do 640*480. If the
+ * LSB of that byte is set the image is just upside down, otherwise
+ * it is rotated 180 degrees. */
+#define SQ905_HIRES_MASK 0x00000300
+#define SQ905_ORIENTATION_MASK 0x00000100
+
+/* Some command codes. These go in the "index" slot. */
+
+#define SQ905_ID 0xf0 /* asks for model string */
+#define SQ905_CONFIG 0x20 /* gets photo alloc. table, not used here */
+#define SQ905_DATA 0x30 /* accesses photo data, not used here */
+#define SQ905_CLEAR 0xa0 /* clear everything */
+#define SQ905_CAPTURE_LOW 0x60 /* Starts capture at 160x120 */
+#define SQ905_CAPTURE_MED 0x61 /* Starts capture at 320x240 */
+#define SQ905_CAPTURE_HIGH 0x62 /* Starts capture at 640x480 (some cams only) */
+/* note that the capture command also controls the output dimensions */
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+
+ /*
+ * Driver stuff
+ */
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
+};
+
+static struct v4l2_pix_format sq905_mode[] = {
+ { 160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 160,
+ .sizeimage = 160 * 120,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0}
+};
+
+/*
+ * Send a command to the camera.
+ */
+static int sq905_command(struct gspca_dev *gspca_dev, u16 index)
+{
+ int ret;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_COMMAND, index, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_PING, 0, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed 2 (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * Acknowledge the end of a frame - see warning on sq905_command.
+ */
+static int sq905_ack_frame(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_READ_DONE, 0, gspca_dev->usb_buf, 1,
+ SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ * request and read a block of data - see warning on sq905_command.
+ */
+static int
+sq905_read_data(struct gspca_dev *gspca_dev, u8 *data, int size)
+{
+ int ret;
+ int act_len;
+
+ gspca_dev->usb_buf[0] = '\0';
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ SQ905_BULK_READ, size, gspca_dev->usb_buf,
+ 1, SQ905_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)", __func__, ret);
+ return ret;
+ }
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ data, size, &act_len, SQ905_DATA_TIMEOUT);
+
+ /* successful, it returns 0, otherwise negative */
+ if (ret < 0 || act_len != size) {
+ PDEBUG(D_ERR, "bulk read fail (%d) len %d/%d",
+ ret, act_len, size);
+ return -EIO;
+ }
+ return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface we take the gspca
+ * usb_lock when performing USB operations. In practice the only thing we need
+ * to protect against is the usb_set_interface call that gspca makes during
+ * stream_off as the camera doesn't provide any controls that the user could try
+ * to change.
+ */
+static void sq905_dostream(struct work_struct *work)
+{
+ struct sd *dev = container_of(work, struct sd, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct gspca_frame *frame;
+ int bytes_left; /* bytes remaining in current frame. */
+ int data_len; /* size to use for the next read. */
+ int header_read; /* true if we have already read the frame header. */
+ int discarding; /* true if we failed to get space for frame. */
+ int packet_type;
+ int frame_sz;
+ int ret;
+ u8 *data;
+ u8 *buffer;
+
+ buffer = kmalloc(SQ905_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!buffer) {
+ PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+ goto quit_stream;
+ }
+
+ frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage
+ + FRAME_HEADER_LEN;
+
+ while (gspca_dev->present && gspca_dev->streaming) {
+ /* Need a short delay to ensure streaming flag was set by
+ * gspca and to make sure gspca can grab the mutex. */
+ mutex_unlock(&gspca_dev->usb_lock);
+ msleep(1);
+
+ /* request some data and then read it until we have
+ * a complete frame. */
+ bytes_left = frame_sz;
+ header_read = 0;
+ discarding = 0;
+
+ while (bytes_left > 0) {
+ data_len = bytes_left > SQ905_MAX_TRANSFER ?
+ SQ905_MAX_TRANSFER : bytes_left;
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = sq905_read_data(gspca_dev, buffer, data_len);
+ if (ret < 0)
+ goto quit_stream;
+ mutex_unlock(&gspca_dev->usb_lock);
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for frame",
+ data_len, bytes_left);
+ bytes_left -= data_len;
+ data = buffer;
+ if (!header_read) {
+ packet_type = FIRST_PACKET;
+ /* The first 64 bytes of each frame are
+ * a header full of FF 00 bytes */
+ data += FRAME_HEADER_LEN;
+ data_len -= FRAME_HEADER_LEN;
+ header_read = 1;
+ } else if (bytes_left == 0) {
+ packet_type = LAST_PACKET;
+ } else {
+ packet_type = INTER_PACKET;
+ }
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding) {
+ frame = gspca_frame_add(gspca_dev, packet_type,
+ frame, data, data_len);
+ /* If entire frame fits in one packet we still
+ need to add a LAST_PACKET */
+ if (packet_type == FIRST_PACKET &&
+ bytes_left == 0)
+ frame = gspca_frame_add(gspca_dev,
+ LAST_PACKET,
+ frame, data, 0);
+ } else {
+ discarding = 1;
+ }
+ }
+ /* acknowledge the frame */
+ mutex_lock(&gspca_dev->usb_lock);
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = sq905_ack_frame(gspca_dev);
+ if (ret < 0)
+ goto quit_stream;
+ }
+quit_stream:
+ /* the usb_lock is already acquired */
+ if (gspca_dev->present)
+ sq905_command(gspca_dev, SQ905_CLEAR);
+ mutex_unlock(&gspca_dev->usb_lock);
+ kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam = &gspca_dev->cam;
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk_size = 64;
+
+ INIT_WORK(&dev->work_struct, sq905_dostream);
+
+ return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ /* This waits for sq905_dostream to finish */
+ destroy_workqueue(dev->work_thread);
+ dev->work_thread = NULL;
+ mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ u32 ident;
+ int ret;
+
+ /* connect to the camera and read
+ * the model ID and process that and put it away.
+ */
+ ret = sq905_command(gspca_dev, SQ905_CLEAR);
+ if (ret < 0)
+ return ret;
+ ret = sq905_command(gspca_dev, SQ905_ID);
+ if (ret < 0)
+ return ret;
+ ret = sq905_read_data(gspca_dev, gspca_dev->usb_buf, 4);
+ if (ret < 0)
+ return ret;
+ /* usb_buf is allocated with kmalloc so is aligned.
+ * Camera model number is the right way round if we assume this
+ * reverse engineered ID is supposed to be big endian. */
+ ident = be32_to_cpup((__be32 *)gspca_dev->usb_buf);
+ ret = sq905_command(gspca_dev, SQ905_CLEAR);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_CONF, "SQ905 camera ID %08x detected", ident);
+ gspca_dev->cam.cam_mode = sq905_mode;
+ gspca_dev->cam.nmodes = ARRAY_SIZE(sq905_mode);
+ if (!(ident & SQ905_HIRES_MASK))
+ gspca_dev->cam.nmodes--;
+ return 0;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+ int ret;
+
+ /* "Open the shutter" and set size, to start capture */
+ switch (gspca_dev->curr_mode) {
+ default:
+/* case 2: */
+ PDEBUG(D_STREAM, "Start streaming at high resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_HIGH);
+ break;
+ case 1:
+ PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_MED);
+ break;
+ case 0:
+ PDEBUG(D_STREAM, "Start streaming at low resolution");
+ ret = sq905_command(&dev->gspca_dev, SQ905_CAPTURE_LOW);
+ }
+
+ if (ret < 0) {
+ PDEBUG(D_ERR, "Start streaming command failed");
+ return ret;
+ }
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
+
+ return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x2770, 0x9120)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
+};
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id,
+ &sd_desc,
+ sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/sq905c.c b/drivers/media/video/gspca/sq905c.c
new file mode 100644
index 00000000000..0bcb74a1b14
--- /dev/null
+++ b/drivers/media/video/gspca/sq905c.c
@@ -0,0 +1,328 @@
+/*
+ * SQ905C subdriver
+ *
+ * Copyright (C) 2009 Theodore Kilgore
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 driver uses work done in
+ * libgphoto2/camlibs/digigr8, Copyright (C) Theodore Kilgore.
+ *
+ * This driver has also used as a base the sq905c driver
+ * and may contain code fragments from it.
+ */
+
+#define MODULE_NAME "sq905c"
+
+#include <linux/workqueue.h>
+#include "gspca.h"
+
+MODULE_AUTHOR("Theodore Kilgore <kilgota@auburn.edu>");
+MODULE_DESCRIPTION("GSPCA/SQ905C USB Camera Driver");
+MODULE_LICENSE("GPL");
+
+/* Default timeouts, in ms */
+#define SQ905C_CMD_TIMEOUT 500
+#define SQ905C_DATA_TIMEOUT 1000
+
+/* Maximum transfer size to use. */
+#define SQ905C_MAX_TRANSFER 0x8000
+
+#define FRAME_HEADER_LEN 0x50
+
+/* Commands. These go in the "value" slot. */
+#define SQ905C_CLEAR 0xa0 /* clear everything */
+#define SQ905C_CAPTURE_LOW 0xa040 /* Starts capture at 160x120 */
+#define SQ905C_CAPTURE_MED 0x1440 /* Starts capture at 320x240 */
+#define SQ905C_CAPTURE_HI 0x2840 /* Starts capture at 320x240 */
+
+/* For capture, this must go in the "index" slot. */
+#define SQ905C_CAPTURE_INDEX 0x110f
+
+/* Structure to hold all of our device specific stuff */
+struct sd {
+ struct gspca_dev gspca_dev; /* !! must be the first item */
+ const struct v4l2_pix_format *cap_mode;
+ /* Driver stuff */
+ struct work_struct work_struct;
+ struct workqueue_struct *work_thread;
+};
+
+/*
+ * Most of these cameras will do 640x480 and 320x240. 160x120 works
+ * in theory but gives very poor output. Therefore, not supported.
+ * The 0x2770:0x9050 cameras have max resolution of 320x240.
+ */
+static struct v4l2_pix_format sq905c_mode[] = {
+ { 320, 240, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
+ { 640, 480, V4L2_PIX_FMT_SQ905C, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0}
+};
+
+/* Send a command to the camera. */
+static int sq905c_command(struct gspca_dev *gspca_dev, u16 command, u16 index)
+{
+ int ret;
+
+ ret = usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ USB_REQ_SYNCH_FRAME, /* request */
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ command, index, NULL, 0,
+ SQ905C_CMD_TIMEOUT);
+ if (ret < 0) {
+ PDEBUG(D_ERR, "%s: usb_control_msg failed (%d)",
+ __func__, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* This function is called as a workqueue function and runs whenever the camera
+ * is streaming data. Because it is a workqueue function it is allowed to sleep
+ * so we can use synchronous USB calls. To avoid possible collisions with other
+ * threads attempting to use the camera's USB interface the gspca usb_lock is
+ * used when performing the one USB control operation inside the workqueue,
+ * which tells the camera to close the stream. In practice the only thing
+ * which needs to be protected against is the usb_set_interface call that
+ * gspca makes during stream_off. Otherwise the camera doesn't provide any
+ * controls that the user could try to change.
+ */
+static void sq905c_dostream(struct work_struct *work)
+{
+ struct sd *dev = container_of(work, struct sd, work_struct);
+ struct gspca_dev *gspca_dev = &dev->gspca_dev;
+ struct gspca_frame *frame;
+ int bytes_left; /* bytes remaining in current frame. */
+ int data_len; /* size to use for the next read. */
+ int act_len;
+ int discarding = 0; /* true if we failed to get space for frame. */
+ int packet_type;
+ int ret;
+ u8 *buffer;
+
+ buffer = kmalloc(SQ905C_MAX_TRANSFER, GFP_KERNEL | GFP_DMA);
+ if (!buffer) {
+ PDEBUG(D_ERR, "Couldn't allocate USB buffer");
+ goto quit_stream;
+ }
+
+ while (gspca_dev->present && gspca_dev->streaming) {
+ if (!gspca_dev->present)
+ goto quit_stream;
+ /* Request the header, which tells the size to download */
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ buffer, FRAME_HEADER_LEN, &act_len,
+ SQ905C_DATA_TIMEOUT);
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for header",
+ act_len, FRAME_HEADER_LEN);
+ if (ret < 0 || act_len < FRAME_HEADER_LEN)
+ goto quit_stream;
+ /* size is read from 4 bytes starting 0x40, little endian */
+ bytes_left = buffer[0x40]|(buffer[0x41]<<8)|(buffer[0x42]<<16)
+ |(buffer[0x43]<<24);
+ PDEBUG(D_STREAM, "bytes_left = 0x%x", bytes_left);
+ /* We keep the header. It has other information, too. */
+ packet_type = FIRST_PACKET;
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding) {
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer, FRAME_HEADER_LEN);
+ } else
+ discarding = 1;
+ while (bytes_left > 0) {
+ data_len = bytes_left > SQ905C_MAX_TRANSFER ?
+ SQ905C_MAX_TRANSFER : bytes_left;
+ if (!gspca_dev->present)
+ goto quit_stream;
+ ret = usb_bulk_msg(gspca_dev->dev,
+ usb_rcvbulkpipe(gspca_dev->dev, 0x81),
+ buffer, data_len, &act_len,
+ SQ905C_DATA_TIMEOUT);
+ if (ret < 0 || act_len < data_len)
+ goto quit_stream;
+ PDEBUG(D_STREAM,
+ "Got %d bytes out of %d for frame",
+ data_len, bytes_left);
+ bytes_left -= data_len;
+ if (bytes_left == 0)
+ packet_type = LAST_PACKET;
+ else
+ packet_type = INTER_PACKET;
+ frame = gspca_get_i_frame(gspca_dev);
+ if (frame && !discarding)
+ gspca_frame_add(gspca_dev, packet_type,
+ frame, buffer, data_len);
+ else
+ discarding = 1;
+ }
+ }
+quit_stream:
+ mutex_lock(&gspca_dev->usb_lock);
+ if (gspca_dev->present)
+ sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+ mutex_unlock(&gspca_dev->usb_lock);
+ kfree(buffer);
+}
+
+/* This function is called at probe time just before sd_init */
+static int sd_config(struct gspca_dev *gspca_dev,
+ const struct usb_device_id *id)
+{
+ struct cam *cam = &gspca_dev->cam;
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ PDEBUG(D_PROBE,
+ "SQ9050 camera detected"
+ " (vid/pid 0x%04X:0x%04X)", id->idVendor, id->idProduct);
+ cam->cam_mode = sq905c_mode;
+ cam->nmodes = 2;
+ if (id->idProduct == 0x9050)
+ cam->nmodes = 1;
+ /* We don't use the buffer gspca allocates so make it small. */
+ cam->bulk_size = 32;
+ INIT_WORK(&dev->work_struct, sq905c_dostream);
+ return 0;
+}
+
+/* called on streamoff with alt==0 and on disconnect */
+/* the usb_lock is held at entry - restore on exit */
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+
+ /* wait for the work queue to terminate */
+ mutex_unlock(&gspca_dev->usb_lock);
+ /* This waits for sq905c_dostream to finish */
+ destroy_workqueue(dev->work_thread);
+ dev->work_thread = NULL;
+ mutex_lock(&gspca_dev->usb_lock);
+}
+
+/* this function is called at probe and resume time */
+static int sd_init(struct gspca_dev *gspca_dev)
+{
+ int ret;
+
+ /* connect to the camera and reset it. */
+ ret = sq905c_command(gspca_dev, SQ905C_CLEAR, 0);
+ return ret;
+}
+
+/* Set up for getting frames. */
+static int sd_start(struct gspca_dev *gspca_dev)
+{
+ struct sd *dev = (struct sd *) gspca_dev;
+ int ret;
+
+ dev->cap_mode = gspca_dev->cam.cam_mode;
+ /* "Open the shutter" and set size, to start capture */
+ switch (gspca_dev->width) {
+ case 640:
+ PDEBUG(D_STREAM, "Start streaming at high resolution");
+ dev->cap_mode++;
+ ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_HI,
+ SQ905C_CAPTURE_INDEX);
+ break;
+ default: /* 320 */
+ PDEBUG(D_STREAM, "Start streaming at medium resolution");
+ ret = sq905c_command(gspca_dev, SQ905C_CAPTURE_MED,
+ SQ905C_CAPTURE_INDEX);
+ }
+
+ if (ret < 0) {
+ PDEBUG(D_ERR, "Start streaming command failed");
+ return ret;
+ }
+ /* Start the workqueue function to do the streaming */
+ dev->work_thread = create_singlethread_workqueue(MODULE_NAME);
+ queue_work(dev->work_thread, &dev->work_struct);
+
+ return 0;
+}
+
+/* Table of supported USB devices */
+static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x2770, 0x905c)},
+ {USB_DEVICE(0x2770, 0x9050)},
+ {USB_DEVICE(0x2770, 0x913d)},
+ {}
+};
+
+MODULE_DEVICE_TABLE(usb, device_table);
+
+/* sub-driver description */
+static const struct sd_desc sd_desc = {
+ .name = MODULE_NAME,
+ .config = sd_config,
+ .init = sd_init,
+ .start = sd_start,
+ .stop0 = sd_stop0,
+};
+
+/* -- device connect -- */
+static int sd_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return gspca_dev_probe(intf, id,
+ &sd_desc,
+ sizeof(struct sd),
+ THIS_MODULE);
+}
+
+static struct usb_driver sd_driver = {
+ .name = MODULE_NAME,
+ .id_table = device_table,
+ .probe = sd_probe,
+ .disconnect = gspca_disconnect,
+#ifdef CONFIG_PM
+ .suspend = gspca_suspend,
+ .resume = gspca_resume,
+#endif
+};
+
+/* -- module insert / remove -- */
+static int __init sd_mod_init(void)
+{
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
+ PDEBUG(D_PROBE, "registered");
+ return 0;
+}
+
+static void __exit sd_mod_exit(void)
+{
+ usb_deregister(&sd_driver);
+ PDEBUG(D_PROBE, "deregistered");
+}
+
+module_init(sd_mod_init);
+module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/stk014.c b/drivers/media/video/gspca/stk014.c
index 60de9af87fb..f25be20cf1a 100644
--- a/drivers/media/video/gspca/stk014.c
+++ b/drivers/media/video/gspca/stk014.c
@@ -35,10 +35,13 @@ struct sd {
unsigned char contrast;
unsigned char colors;
unsigned char lightfreq;
-};
+ u8 quality;
+#define QUALITY_MIN 60
+#define QUALITY_MAX 95
+#define QUALITY_DEF 80
-/* global parameters */
-static int sd_quant = 7; /* <= 4 KO - 7: good (enough!) */
+ u8 *jpeg_hdr;
+};
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
@@ -180,7 +183,7 @@ static int rcv_val(struct gspca_dev *gspca_dev,
reg_w(gspca_dev, 0x63b, 0);
reg_w(gspca_dev, 0x630, 5);
ret = usb_bulk_msg(dev,
- usb_rcvbulkpipe(dev, 5),
+ usb_rcvbulkpipe(dev, 0x05),
gspca_dev->usb_buf,
4, /* length */
&alen,
@@ -294,15 +297,14 @@ static int sd_config(struct gspca_dev *gspca_dev,
const struct usb_device_id *id)
{
struct sd *sd = (struct sd *) gspca_dev;
- struct cam *cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
gspca_dev->cam.cam_mode = vga_mode;
gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
sd->brightness = BRIGHTNESS_DEF;
sd->contrast = CONTRAST_DEF;
sd->colors = COLOR_DEF;
sd->lightfreq = FREQ_DEF;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -326,8 +328,15 @@ static int sd_init(struct gspca_dev *gspca_dev)
/* -- start the camera -- */
static int sd_start(struct gspca_dev *gspca_dev)
{
+ struct sd *sd = (struct sd *) gspca_dev;
int ret, value;
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
/* work on alternate 1 */
usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
@@ -399,11 +408,19 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
PDEBUG(D_STREAM, "camera stopped");
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
int len) /* iso packet length */
{
+ struct sd *sd = (struct sd *) gspca_dev;
static unsigned char ffd9[] = {0xff, 0xd9};
/* a frame starts with:
@@ -420,7 +437,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG 411 header */
- jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
/* beginning of the frame */
#define STKHDRSZ 12
@@ -520,6 +538,34 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
return -EINVAL;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -529,8 +575,11 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -562,8 +611,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
info("registered");
return 0;
}
@@ -575,6 +626,3 @@ static void __exit sd_mod_exit(void)
module_init(sd_mod_init);
module_exit(sd_mod_exit);
-
-module_param_named(quant, sd_quant, int, 0644);
-MODULE_PARM_DESC(quant, "Quantization index (0..8)");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 13a021e3cbb..9dff2e65b11 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -429,7 +429,6 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Configuring camera");
cam = &gspca_dev->cam;
- cam->epaddr = STV_ISOC_ENDPOINT_ADDR;
sd->desc = sd_desc;
gspca_dev->sd_desc = &sd->desc;
@@ -501,8 +500,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index 14335a9e4bb..b1690381420 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -30,6 +30,66 @@
#include "stv06xx_hdcs.h"
+static const struct ctrl hdcs1x00_ctrl[] = {
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "exposure",
+ .minimum = 0x00,
+ .maximum = 0xffff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_EXPOSURE,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_exposure,
+ .get = hdcs_get_exposure
+ }, {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "gain",
+ .minimum = 0x00,
+ .maximum = 0xff,
+ .step = 0x1,
+ .default_value = HDCS_DEFAULT_GAIN,
+ .flags = V4L2_CTRL_FLAG_SLIDER
+ },
+ .set = hdcs_set_gain,
+ .get = hdcs_get_gain
+ }
+};
+
+static struct v4l2_pix_format hdcs1x00_mode[] = {
+ {
+ HDCS_1X00_DEF_WIDTH,
+ HDCS_1X00_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
+ .bytesperline = HDCS_1X00_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
+static const struct ctrl hdcs1020_ctrl[] = {};
+
+static struct v4l2_pix_format hdcs1020_mode[] = {
+ {
+ HDCS_1020_DEF_WIDTH,
+ HDCS_1020_DEF_HEIGHT,
+ V4L2_PIX_FMT_SBGGR8,
+ V4L2_FIELD_NONE,
+ .sizeimage =
+ HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
+ .bytesperline = HDCS_1020_DEF_WIDTH,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 1
+ }
+};
+
enum hdcs_power_state {
HDCS_STATE_SLEEP,
HDCS_STATE_IDLE,
@@ -353,10 +413,10 @@ static int hdcs_probe_1x00(struct sd *sd)
info("HDCS-1000/1100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1x00.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1x00.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1x00.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1x00.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1x00_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1x00_mode);
+ sd->desc.ctrls = hdcs1x00_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1x00_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
@@ -412,10 +472,10 @@ static int hdcs_probe_1020(struct sd *sd)
info("HDCS-1020 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_hdcs1020.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_hdcs1020.nmodes;
- sd->desc.ctrls = stv06xx_sensor_hdcs1020.ctrls;
- sd->desc.nctrls = stv06xx_sensor_hdcs1020.nctrls;
+ sd->gspca_dev.cam.cam_mode = hdcs1020_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(hdcs1020_mode);
+ sd->desc.ctrls = hdcs1020_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(hdcs1020_ctrl);
hdcs = kmalloc(sizeof(struct hdcs), GFP_KERNEL);
if (!hdcs)
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 9c7279a4cd8..412f06cf3d5 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -152,53 +152,6 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1x00 = {
.stop = hdcs_stop,
.disconnect = hdcs_disconnect,
.dump = hdcs_dump,
-
- .nctrls = 2,
- .ctrls = {
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "exposure",
- .minimum = 0x00,
- .maximum = 0xffff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_EXPOSURE,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_exposure,
- .get = hdcs_get_exposure
- },
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "gain",
- .minimum = 0x00,
- .maximum = 0xff,
- .step = 0x1,
- .default_value = HDCS_DEFAULT_GAIN,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .set = hdcs_set_gain,
- .get = hdcs_get_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1X00_DEF_WIDTH,
- HDCS_1X00_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1X00_DEF_WIDTH * HDCS_1X00_DEF_HEIGHT,
- .bytesperline = HDCS_1X00_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
@@ -207,29 +160,11 @@ const struct stv06xx_sensor stv06xx_sensor_hdcs1020 = {
.i2c_addr = (0x55 << 1),
.i2c_len = 1,
- .nctrls = 0,
- .ctrls = {},
-
.init = hdcs_init,
.probe = hdcs_probe_1020,
.start = hdcs_start,
.stop = hdcs_stop,
.dump = hdcs_dump,
-
- .nmodes = 1,
- .modes = {
- {
- HDCS_1020_DEF_WIDTH,
- HDCS_1020_DEF_HEIGHT,
- V4L2_PIX_FMT_SBGGR8,
- V4L2_FIELD_NONE,
- .sizeimage =
- HDCS_1020_DEF_WIDTH * HDCS_1020_DEF_HEIGHT,
- .bytesperline = HDCS_1020_DEF_WIDTH,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 1
- }
- }
};
static const u16 stv_bridge_init[][2] = {
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
index d0a0f859645..285221e6b39 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.c
@@ -46,6 +46,132 @@
#include "stv06xx_pb0100.h"
+static const struct ctrl pb0100_ctrl[] = {
+#define GAIN_IDX 0
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Gain",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_gain,
+ .get = pb0100_get_gain
+ },
+#define RED_BALANCE_IDX 1
+ {
+ {
+ .id = V4L2_CID_RED_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Red Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_red_balance,
+ .get = pb0100_get_red_balance
+ },
+#define BLUE_BALANCE_IDX 2
+ {
+ {
+ .id = V4L2_CID_BLUE_BALANCE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Blue Balance",
+ .minimum = -255,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = pb0100_set_blue_balance,
+ .get = pb0100_get_blue_balance
+ },
+#define EXPOSURE_IDX 3
+ {
+ {
+ .id = V4L2_CID_EXPOSURE,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Exposure",
+ .minimum = 0,
+ .maximum = 511,
+ .step = 1,
+ .default_value = 12
+ },
+ .set = pb0100_set_exposure,
+ .get = pb0100_get_exposure
+ },
+#define AUTOGAIN_IDX 4
+ {
+ {
+ .id = V4L2_CID_AUTOGAIN,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Automatic Gain and Exposure",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_autogain,
+ .get = pb0100_get_autogain
+ },
+#define AUTOGAIN_TARGET_IDX 5
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1000,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "Automatic Gain Target",
+ .minimum = 0,
+ .maximum = 255,
+ .step = 1,
+ .default_value = 128
+ },
+ .set = pb0100_set_autogain_target,
+ .get = pb0100_get_autogain_target
+ },
+#define NATURAL_IDX 6
+ {
+ {
+ .id = V4L2_CTRL_CLASS_USER + 0x1001,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Natural Light Source",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 1
+ },
+ .set = pb0100_set_natural,
+ .get = pb0100_get_natural
+ }
+};
+
+static struct v4l2_pix_format pb0100_mode[] = {
+/* low res / subsample modes disabled as they are only half res horizontal,
+ halving the vertical resolution does not seem to work */
+ {
+ 320,
+ 240,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 320 * 240,
+ .bytesperline = 320,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = PB0100_CROP_TO_VGA
+ },
+ {
+ 352,
+ 288,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 352 * 288,
+ .bytesperline = 352,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
static int pb0100_probe(struct sd *sd)
{
u16 sensor;
@@ -59,20 +185,19 @@ static int pb0100_probe(struct sd *sd)
if ((sensor >> 8) == 0x64) {
sensor_settings = kmalloc(
- stv06xx_sensor_pb0100.nctrls * sizeof(s32),
+ ARRAY_SIZE(pb0100_ctrl) * sizeof(s32),
GFP_KERNEL);
if (!sensor_settings)
return -ENOMEM;
info("Photobit pb0100 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_pb0100.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_pb0100.nmodes;
- sd->desc.ctrls = stv06xx_sensor_pb0100.ctrls;
- sd->desc.nctrls = stv06xx_sensor_pb0100.nctrls;
- for (i = 0; i < stv06xx_sensor_pb0100.nctrls; i++)
- sensor_settings[i] = stv06xx_sensor_pb0100.
- ctrls[i].qctrl.default_value;
+ sd->gspca_dev.cam.cam_mode = pb0100_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(pb0100_mode);
+ sd->desc.ctrls = pb0100_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(pb0100_ctrl);
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = pb0100_ctrl[i].qctrl.default_value;
sd->sensor_priv = sensor_settings;
return 0;
@@ -143,6 +268,12 @@ out:
return (err < 0) ? err : 0;
}
+static void pb0100_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
/* FIXME: Sort the init commands out and put them into tables,
this is only for getting the camera to work */
/* FIXME: No error handling for now,
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
index 5ea21a1154c..4de4fa5ebc5 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_pb0100.h
@@ -114,6 +114,7 @@ static int pb0100_start(struct sd *sd);
static int pb0100_init(struct sd *sd);
static int pb0100_stop(struct sd *sd);
static int pb0100_dump(struct sd *sd);
+static void pb0100_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int pb0100_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
@@ -137,139 +138,12 @@ const struct stv06xx_sensor stv06xx_sensor_pb0100 = {
.i2c_addr = 0xba,
.i2c_len = 2,
- .nctrls = 7,
- .ctrls = {
-#define GAIN_IDX 0
- {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Gain",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_gain,
- .get = pb0100_get_gain
- },
-#define RED_BALANCE_IDX 1
- {
- {
- .id = V4L2_CID_RED_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Red Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_red_balance,
- .get = pb0100_get_red_balance
- },
-#define BLUE_BALANCE_IDX 2
- {
- {
- .id = V4L2_CID_BLUE_BALANCE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Blue Balance",
- .minimum = -255,
- .maximum = 255,
- .step = 1,
- .default_value = 0
- },
- .set = pb0100_set_blue_balance,
- .get = pb0100_get_blue_balance
- },
-#define EXPOSURE_IDX 3
- {
- {
- .id = V4L2_CID_EXPOSURE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Exposure",
- .minimum = 0,
- .maximum = 511,
- .step = 1,
- .default_value = 12
- },
- .set = pb0100_set_exposure,
- .get = pb0100_get_exposure
- },
-#define AUTOGAIN_IDX 4
- {
- {
- .id = V4L2_CID_AUTOGAIN,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Automatic Gain and Exposure",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_autogain,
- .get = pb0100_get_autogain
- },
-#define AUTOGAIN_TARGET_IDX 5
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1000,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Automatic Gain Target",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 128
- },
- .set = pb0100_set_autogain_target,
- .get = pb0100_get_autogain_target
- },
-#define NATURAL_IDX 6
- {
- {
- .id = V4L2_CTRL_CLASS_USER + 0x1001,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Natural Light Source",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 1
- },
- .set = pb0100_set_natural,
- .get = pb0100_get_natural
- },
- },
-
.init = pb0100_init,
.probe = pb0100_probe,
.start = pb0100_start,
.stop = pb0100_stop,
.dump = pb0100_dump,
-
- .nmodes = 2,
- .modes = {
-/* low res / subsample modes disabled as they are only half res horizontal,
- halving the vertical resolution does not seem to work */
- {
- 320,
- 240,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 320 * 240,
- .bytesperline = 320,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = PB0100_CROP_TO_VGA
- },
- {
- 352,
- 288,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage = 352 * 288,
- .bytesperline = 352,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- },
- }
+ .disconnect = pb0100_disconnect,
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
index c726dacefa1..e88c42f7d2f 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_sensor.h
@@ -41,8 +41,6 @@ extern const struct stv06xx_sensor stv06xx_sensor_hdcs1x00;
extern const struct stv06xx_sensor stv06xx_sensor_hdcs1020;
extern const struct stv06xx_sensor stv06xx_sensor_pb0100;
-#define STV06XX_MAX_CTRLS (V4L2_CID_LASTP1 - V4L2_CID_BASE + 10)
-
struct stv06xx_sensor {
/* Defines the name of a sensor */
char name[32];
@@ -81,12 +79,6 @@ struct stv06xx_sensor {
/* Instructs the sensor to dump all its contents */
int (*dump)(struct sd *sd);
-
- int nctrls;
- struct ctrl ctrls[STV06XX_MAX_CTRLS];
-
- char nmodes;
- struct v4l2_pix_format modes[];
};
#endif
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
index 1ca91f2a6de..69c77c932fc 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.c
@@ -29,26 +29,92 @@
#include "stv06xx_vv6410.h"
+static struct v4l2_pix_format vv6410_mode[] = {
+ {
+ 356,
+ 292,
+ V4L2_PIX_FMT_SGRBG8,
+ V4L2_FIELD_NONE,
+ .sizeimage = 356 * 292,
+ .bytesperline = 356,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0
+ }
+};
+
+static const struct ctrl vv6410_ctrl[] = {
+#define HFLIP_IDX 0
+ {
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "horizontal flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_hflip,
+ .get = vv6410_get_hflip
+ },
+#define VFLIP_IDX 1
+ {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "vertical flip",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_vflip,
+ .get = vv6410_get_vflip
+ },
+#define GAIN_IDX 2
+ {
+ {
+ .id = V4L2_CID_GAIN,
+ .type = V4L2_CTRL_TYPE_INTEGER,
+ .name = "analog gain",
+ .minimum = 0,
+ .maximum = 15,
+ .step = 1,
+ .default_value = 0
+ },
+ .set = vv6410_set_analog_gain,
+ .get = vv6410_get_analog_gain
+ }
+};
+
static int vv6410_probe(struct sd *sd)
{
u16 data;
- int err;
+ int err, i;
+ s32 *sensor_settings;
err = stv06xx_read_sensor(sd, VV6410_DEVICEH, &data);
-
if (err < 0)
return -ENODEV;
if (data == 0x19) {
info("vv6410 sensor detected");
- sd->gspca_dev.cam.cam_mode = stv06xx_sensor_vv6410.modes;
- sd->gspca_dev.cam.nmodes = stv06xx_sensor_vv6410.nmodes;
- sd->desc.ctrls = stv06xx_sensor_vv6410.ctrls;
- sd->desc.nctrls = stv06xx_sensor_vv6410.nctrls;
+ sensor_settings = kmalloc(ARRAY_SIZE(vv6410_ctrl) * sizeof(s32),
+ GFP_KERNEL);
+ if (!sensor_settings)
+ return -ENOMEM;
+
+ sd->gspca_dev.cam.cam_mode = vv6410_mode;
+ sd->gspca_dev.cam.nmodes = ARRAY_SIZE(vv6410_mode);
+ sd->desc.ctrls = vv6410_ctrl;
+ sd->desc.nctrls = ARRAY_SIZE(vv6410_ctrl);
+
+ for (i = 0; i < sd->desc.nctrls; i++)
+ sensor_settings[i] = vv6410_ctrl[i].qctrl.default_value;
+ sd->sensor_priv = sensor_settings;
return 0;
}
-
return -ENODEV;
}
@@ -80,6 +146,12 @@ static int vv6410_init(struct sd *sd)
return (err < 0) ? err : 0;
}
+static void vv6410_disconnect(struct sd *sd)
+{
+ sd->sensor = NULL;
+ kfree(sd->sensor_priv);
+}
+
static int vv6410_start(struct sd *sd)
{
int err;
@@ -156,17 +228,13 @@ static int vv6410_dump(struct sd *sd)
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_HFLIP) ? 1 : 0;
-
+ *val = sensor_settings[HFLIP_IDX];
PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -174,6 +242,9 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[HFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -191,17 +262,13 @@ static int vv6410_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
-
- *val = (i2c_data & VV6410_VFLIP) ? 1 : 0;
-
+ *val = sensor_settings[VFLIP_IDX];
PDEBUG(D_V4L2, "Read vertical flip %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
@@ -209,6 +276,9 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
int err;
u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+
+ sensor_settings[VFLIP_IDX] = val;
err = stv06xx_read_sensor(sd, VV6410_DATAFORMAT, &i2c_data);
if (err < 0)
return err;
@@ -226,24 +296,23 @@ static int vv6410_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
static int vv6410_get_analog_gain(struct gspca_dev *gspca_dev, __s32 *val)
{
- int err;
- u16 i2c_data;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
- err = stv06xx_read_sensor(sd, VV6410_ANALOGGAIN, &i2c_data);
-
- *val = i2c_data & 0xf;
+ *val = sensor_settings[GAIN_IDX];
PDEBUG(D_V4L2, "Read analog gain %d", *val);
- return (err < 0) ? err : 0;
+ return 0;
}
static int vv6410_set_analog_gain(struct gspca_dev *gspca_dev, __s32 val)
{
int err;
struct sd *sd = (struct sd *) gspca_dev;
+ s32 *sensor_settings = sd->sensor_priv;
+ sensor_settings[GAIN_IDX] = val;
PDEBUG(D_V4L2, "Set analog gain to %d", val);
err = stv06xx_write_sensor(sd, VV6410_ANALOGGAIN, 0xf0 | (val & 0xf));
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
index 3ff8c4ea336..95ac55891bd 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_vv6410.h
@@ -178,6 +178,7 @@ static int vv6410_start(struct sd *sd);
static int vv6410_init(struct sd *sd);
static int vv6410_stop(struct sd *sd);
static int vv6410_dump(struct sd *sd);
+static void vv6410_disconnect(struct sd *sd);
/* V4L2 controls supported by the driver */
static int vv6410_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
@@ -197,62 +198,7 @@ const struct stv06xx_sensor stv06xx_sensor_vv6410 = {
.start = vv6410_start,
.stop = vv6410_stop,
.dump = vv6410_dump,
-
- .nctrls = 3,
- .ctrls = {
- {
- {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "horizontal flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_hflip,
- .get = vv6410_get_hflip
- }, {
- {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_vflip,
- .get = vv6410_get_vflip
- }, {
- {
- .id = V4L2_CID_GAIN,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "analog gain",
- .minimum = 0,
- .maximum = 15,
- .step = 1,
- .default_value = 0
- },
- .set = vv6410_set_analog_gain,
- .get = vv6410_get_analog_gain
- }
- },
-
- .nmodes = 1,
- .modes = {
- {
- 356,
- 292,
- V4L2_PIX_FMT_SGRBG8,
- V4L2_FIELD_NONE,
- .sizeimage =
- 356 * 292,
- .bytesperline = 356,
- .colorspace = V4L2_COLORSPACE_SRGB,
- .priv = 0
- }
- }
+ .disconnect = vv6410_disconnect,
};
/* If NULL, only single value to write, stored in len */
diff --git a/drivers/media/video/gspca/sunplus.c b/drivers/media/video/gspca/sunplus.c
index 6d904d5e4c7..c2b8c10c075 100644
--- a/drivers/media/video/gspca/sunplus.c
+++ b/drivers/media/video/gspca/sunplus.c
@@ -39,8 +39,11 @@ struct sd {
unsigned char contrast;
unsigned char colors;
unsigned char autogain;
+ u8 quality;
+#define QUALITY_MIN 70
+#define QUALITY_MAX 95
+#define QUALITY_DEF 85
- char qindex;
char bridge;
#define BRIDGE_SPCA504 0
#define BRIDGE_SPCA504B 1
@@ -52,6 +55,8 @@ struct sd {
#define LogitechClickSmart420 2
#define LogitechClickSmart820 3
#define MegapixV4 4
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -812,7 +817,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
sd->bridge = id->driver_info >> 8;
sd->subtype = id->driver_info;
@@ -850,10 +854,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->nmodes = sizeof vga_mode2 / sizeof vga_mode2[0];
break;
}
- sd->qindex = 5; /* set the quantization table */
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->quality = QUALITY_DEF;
return 0;
}
@@ -970,6 +974,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
__u8 i;
__u8 info[6];
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x22); /* JPEG 411 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
if (sd->bridge == BRIDGE_SPCA504B)
spca504B_setQtable(gspca_dev);
spca504B_SetSizeType(gspca_dev);
@@ -1079,6 +1089,13 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
}
}
+static void sd_stop0(struct gspca_dev *gspca_dev)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ kfree(sd->jpeg_hdr);
+}
+
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
__u8 *data, /* isoc packet */
@@ -1155,9 +1172,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
ffd9, 2);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x22);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
}
/* add 0x00 after 0xff */
@@ -1198,26 +1214,6 @@ static void setbrightness(struct gspca_dev *gspca_dev)
}
}
-static void getbrightness(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
- __u16 brightness = 0;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- brightness = reg_r_12(gspca_dev, 0x00, 0x21a7, 2);
- break;
- case BRIDGE_SPCA536:
- brightness = reg_r_12(gspca_dev, 0x00, 0x20f0, 2);
- break;
- }
- sd->brightness = ((brightness & 0xff) - 128) % 255;
-}
-
static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1237,24 +1233,6 @@ static void setcontrast(struct gspca_dev *gspca_dev)
}
}
-static void getcontrast(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x21a8, 2);
- break;
- case BRIDGE_SPCA536:
- sd->contrast = reg_r_12(gspca_dev, 0x00, 0x20f1, 2);
- break;
- }
-}
-
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1274,24 +1252,6 @@ static void setcolors(struct gspca_dev *gspca_dev)
}
}
-static void getcolors(struct gspca_dev *gspca_dev)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- switch (sd->bridge) {
- default:
-/* case BRIDGE_SPCA533: */
-/* case BRIDGE_SPCA504B: */
-/* case BRIDGE_SPCA504: */
-/* case BRIDGE_SPCA504C: */
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x21ae, 2) >> 1;
- break;
- case BRIDGE_SPCA536:
- sd->colors = reg_r_12(gspca_dev, 0x00, 0x20f6, 2) >> 1;
- break;
- }
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -1306,7 +1266,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getbrightness(gspca_dev);
*val = sd->brightness;
return 0;
}
@@ -1325,7 +1284,6 @@ static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcontrast(gspca_dev);
*val = sd->contrast;
return 0;
}
@@ -1344,7 +1302,6 @@ static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
{
struct sd *sd = (struct sd *) gspca_dev;
- getcolors(gspca_dev);
*val = sd->colors;
return 0;
}
@@ -1365,6 +1322,34 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -1374,7 +1359,10 @@ static const struct sd_desc sd_desc = {
.init = sd_init,
.start = sd_start,
.stopN = sd_stopN,
+ .stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
/* -- module initialisation -- */
@@ -1465,8 +1453,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/t613.c b/drivers/media/video/gspca/t613.c
index 6ee111a3cbd..f63e37e2e4f 100644
--- a/drivers/media/video/gspca/t613.c
+++ b/drivers/media/video/gspca/t613.c
@@ -37,20 +37,21 @@ MODULE_LICENSE("GPL");
struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
- unsigned char brightness;
- unsigned char contrast;
- unsigned char colors;
- unsigned char autogain;
- unsigned char gamma;
- unsigned char sharpness;
- unsigned char freq;
- unsigned char whitebalance;
- unsigned char mirror;
- unsigned char effect;
-
- __u8 sensor;
-#define SENSOR_TAS5130A 0
-#define SENSOR_OM6802 1
+ u8 brightness;
+ u8 contrast;
+ u8 colors;
+ u8 autogain;
+ u8 gamma;
+ u8 sharpness;
+ u8 freq;
+ u8 whitebalance;
+ u8 mirror;
+ u8 effect;
+
+ u8 sensor;
+#define SENSOR_OM6802 0
+#define SENSOR_OTHER 1
+#define SENSOR_TAS5130A 2
};
/* V4L2 controls supported by the driver */
@@ -78,7 +79,6 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
struct v4l2_querymenu *menu);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
@@ -87,12 +87,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 14,
.step = 1,
- .default_value = 8,
+#define BRIGHTNESS_DEF 8
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
{
{
.id = V4L2_CID_CONTRAST,
@@ -101,12 +101,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0d,
.step = 1,
- .default_value = 0x07,
+#define CONTRAST_DEF 0x07
+ .default_value = CONTRAST_DEF,
},
.set = sd_setcontrast,
.get = sd_getcontrast,
},
-#define SD_COLOR 2
{
{
.id = V4L2_CID_SATURATION,
@@ -115,7 +115,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 0x0f,
.step = 1,
- .default_value = 0x05,
+#define COLORS_DEF 0x05
+ .default_value = COLORS_DEF,
},
.set = sd_setcolors,
.get = sd_getcolors,
@@ -135,7 +136,6 @@ static struct ctrl sd_ctrls[] = {
.set = sd_setgamma,
.get = sd_getgamma,
},
-#define SD_AUTOGAIN 4
{
{
.id = V4L2_CID_GAIN, /* here, i activate only the lowlight,
@@ -146,12 +146,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0x01,
+#define AUTOGAIN_DEF 0x01
+ .default_value = AUTOGAIN_DEF,
},
.set = sd_setlowlight,
.get = sd_getlowlight,
},
-#define SD_MIRROR 5
{
{
.id = V4L2_CID_HFLIP,
@@ -160,12 +160,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define MIRROR_DEF 0
+ .default_value = MIRROR_DEF,
},
.set = sd_setflip,
.get = sd_getflip
},
-#define SD_LIGHTFREQ 6
{
{
.id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -174,12 +174,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 1, /* 1 -> 0x50, 2->0x60 */
.maximum = 2,
.step = 1,
- .default_value = 1,
+#define FREQ_DEF 1
+ .default_value = FREQ_DEF,
},
.set = sd_setfreq,
.get = sd_getfreq},
-#define SD_WHITE_BALANCE 7
{
{
.id = V4L2_CID_WHITE_BALANCE_TEMPERATURE,
@@ -188,12 +188,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 1,
.step = 1,
- .default_value = 0,
+#define WHITE_BALANCE_DEF 0
+ .default_value = WHITE_BALANCE_DEF,
},
.set = sd_setwhitebalance,
.get = sd_getwhitebalance
},
-#define SD_SHARPNESS 8 /* (aka definition on win) */
{
{
.id = V4L2_CID_SHARPNESS,
@@ -202,12 +202,12 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 15,
.step = 1,
- .default_value = 0x06,
+#define SHARPNESS_DEF 0x06
+ .default_value = SHARPNESS_DEF,
},
.set = sd_setsharpness,
.get = sd_getsharpness,
},
-#define SD_EFFECTS 9
{
{
.id = V4L2_CID_EFFECTS,
@@ -216,7 +216,8 @@ static struct ctrl sd_ctrls[] = {
.minimum = 0,
.maximum = 4,
.step = 1,
- .default_value = 0,
+#define EFFECTS_DEF 0
+ .default_value = EFFECTS_DEF,
},
.set = sd_seteffect,
.get = sd_geteffect
@@ -263,28 +264,50 @@ static const struct v4l2_pix_format vga_mode_t16[] = {
/* sensor specific data */
struct additional_sensor_data {
- const __u8 data1[20];
- const __u8 data2[18];
- const __u8 data3[18];
- const __u8 data4[4];
- const __u8 data5[6];
- const __u8 stream[4];
+ const u8 data1[10];
+ const u8 data2[9];
+ const u8 data3[9];
+ const u8 data4[4];
+ const u8 data5[6];
+ const u8 stream[4];
};
-const static struct additional_sensor_data sensor_data[] = {
+static const struct additional_sensor_data sensor_data[] = {
+ { /* OM6802 */
+ .data1 =
+ {0xc2, 0x28, 0x0f, 0x22, 0xcd, 0x27, 0x2c, 0x06,
+ 0xb3, 0xfc},
+ .data2 =
+ {0x80, 0xff, 0xff, 0x80, 0xff, 0xff, 0x80, 0xff,
+ 0xff},
+ .data4 = /*Freq (50/60Hz). Splitted for test purpose */
+ {0x66, 0xca, 0xa8, 0xf0},
+ .data5 = /* this could be removed later */
+ {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x78},
+ },
+ { /* OTHER */
+ .data1 =
+ {0xc1, 0x48, 0x04, 0x1b, 0xca, 0x2e, 0x33, 0x3a,
+ 0xe8, 0xfc},
+ .data2 =
+ {0x4e, 0x9c, 0xec, 0x40, 0x80, 0xc0, 0x48, 0x96,
+ 0xd9},
+ .data4 =
+ {0x66, 0x00, 0xa8, 0xa8},
+ .data5 =
+ {0x0c, 0x03, 0xab, 0x29, 0x81, 0x69},
+ .stream =
+ {0x0b, 0x04, 0x0a, 0x00},
+ },
{ /* TAS5130A */
.data1 =
- {0xd0, 0xbb, 0xd1, 0x28, 0xd2, 0x10, 0xd3, 0x10,
- 0xd4, 0xbb, 0xd5, 0x28, 0xd6, 0x1e, 0xd7, 0x27,
- 0xd8, 0xc8, 0xd9, 0xfc},
+ {0xbb, 0x28, 0x10, 0x10, 0xbb, 0x28, 0x1e, 0x27,
+ 0xc8, 0xfc},
.data2 =
- {0xe0, 0x60, 0xe1, 0xa8, 0xe2, 0xe0, 0xe3, 0x60,
- 0xe4, 0xa8, 0xe5, 0xe0, 0xe6, 0x60, 0xe7, 0xa8,
- 0xe8, 0xe0},
- .data3 =
- {0xc7, 0x60, 0xc8, 0xa8, 0xc9, 0xe0, 0xca, 0x60,
- 0xcb, 0xa8, 0xcc, 0xe0, 0xcd, 0x60, 0xce, 0xa8,
- 0xcf, 0xe0},
+ {0x60, 0xa8, 0xe0, 0x60, 0xa8, 0xe0, 0x60, 0xa8,
+ 0xe0},
.data4 = /* Freq (50/60Hz). Splitted for test purpose */
{0x66, 0x00, 0xa8, 0xe8},
.data5 =
@@ -292,32 +315,12 @@ const static struct additional_sensor_data sensor_data[] = {
.stream =
{0x0b, 0x04, 0x0a, 0x40},
},
- { /* OM6802 */
- .data1 =
- {0xd0, 0xc2, 0xd1, 0x28, 0xd2, 0x0f, 0xd3, 0x22,
- 0xd4, 0xcd, 0xd5, 0x27, 0xd6, 0x2c, 0xd7, 0x06,
- 0xd8, 0xb3, 0xd9, 0xfc},
- .data2 =
- {0xe0, 0x80, 0xe1, 0xff, 0xe2, 0xff, 0xe3, 0x80,
- 0xe4, 0xff, 0xe5, 0xff, 0xe6, 0x80, 0xe7, 0xff,
- 0xe8, 0xff},
- .data3 =
- {0xc7, 0x80, 0xc8, 0xff, 0xc9, 0xff, 0xca, 0x80,
- 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0x80, 0xce, 0xff,
- 0xcf, 0xff},
- .data4 = /*Freq (50/60Hz). Splitted for test purpose */
- {0x66, 0xca, 0xa8, 0xf0 },
- .data5 = /* this could be removed later */
- {0x0c, 0x03, 0xab, 0x13, 0x81, 0x23},
- .stream =
- {0x0b, 0x04, 0x0a, 0x78},
- }
};
#define MAX_EFFECTS 7
/* easily done by soft, this table could be removed,
* i keep it here just in case */
-static const __u8 effects_table[MAX_EFFECTS][6] = {
+static const u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x00}, /* Normal */
{0xa8, 0xc8, 0xc6, 0x52, 0xc0, 0x04}, /* Repujar */
{0xa8, 0xe8, 0xc6, 0xd2, 0xc0, 0x20}, /* Monochrome */
@@ -327,90 +330,58 @@ static const __u8 effects_table[MAX_EFFECTS][6] = {
{0xa8, 0xc8, 0xc6, 0xd2, 0xc0, 0x40}, /* Negative */
};
-static const __u8 gamma_table[GAMMA_MAX][34] = {
- {0x90, 0x00, 0x91, 0x3e, 0x92, 0x69, 0x93, 0x85, /* 0 */
- 0x94, 0x95, 0x95, 0xa1, 0x96, 0xae, 0x97, 0xb9,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdb,
- 0x9c, 0xe3, 0x9d, 0xea, 0x9e, 0xf1, 0x9f, 0xf8,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x33, 0x92, 0x5a, 0x93, 0x75, /* 1 */
- 0x94, 0x85, 0x95, 0x93, 0x96, 0xa1, 0x97, 0xad,
- 0x98, 0xb7, 0x99, 0xc2, 0x9a, 0xcb, 0x9b, 0xd4,
- 0x9c, 0xde, 0x9D, 0xe7, 0x9e, 0xf0, 0x9f, 0xf7,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x2f, 0x92, 0x51, 0x93, 0x6b, /* 2 */
- 0x94, 0x7c, 0x95, 0x8a, 0x96, 0x99, 0x97, 0xa6,
- 0x98, 0xb1, 0x99, 0xbc, 0x9a, 0xc6, 0x9b, 0xd0,
- 0x9c, 0xdb, 0x9d, 0xe4, 0x9e, 0xed, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x29, 0x92, 0x48, 0x93, 0x60, /* 3 */
- 0x94, 0x72, 0x95, 0x81, 0x96, 0x90, 0x97, 0x9e,
- 0x98, 0xaa, 0x99, 0xb5, 0x9a, 0xbf, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x23, 0x92, 0x3f, 0x93, 0x55, /* 4 */
- 0x94, 0x68, 0x95, 0x77, 0x96, 0x86, 0x97, 0x95,
- 0x98, 0xa2, 0x99, 0xad, 0x9a, 0xb9, 0x9b, 0xc6,
- 0x9c, 0xd2, 0x9d, 0xde, 0x9e, 0xe9, 0x9f, 0xf4,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1b, 0x92, 0x33, 0x93, 0x48, /* 5 */
- 0x94, 0x59, 0x95, 0x69, 0x96, 0x79, 0x97, 0x87,
- 0x98, 0x96, 0x99, 0xa3, 0x9a, 0xb1, 0x9b, 0xbe,
- 0x9c, 0xcc, 0x9d, 0xda, 0x9e, 0xe7, 0x9f, 0xf3,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x10, 0x93, 0x20, /* 6 */
- 0x94, 0x32, 0x95, 0x40, 0x96, 0x57, 0x97, 0x67,
- 0x98, 0x77, 0x99, 0x88, 0x9a, 0x99, 0x9b, 0xaa,
- 0x9c, 0xbb, 0x9d, 0xcc, 0x9e, 0xdd, 0x9f, 0xee,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x02, 0x92, 0x14, 0x93, 0x26, /* 7 */
- 0x94, 0x38, 0x95, 0x4a, 0x96, 0x60, 0x97, 0x70,
- 0x98, 0x80, 0x99, 0x90, 0x9a, 0xa0, 0x9b, 0xb0,
- 0x9c, 0xc0, 0x9D, 0xd0, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x22, 0x93, 0x35, /* 8 */
- 0x94, 0x47, 0x95, 0x5a, 0x96, 0x69, 0x97, 0x79,
- 0x98, 0x88, 0x99, 0x97, 0x9a, 0xa7, 0x9b, 0xb6,
- 0x9c, 0xc4, 0x9d, 0xd3, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x10, 0x92, 0x26, 0x93, 0x40, /* 9 */
- 0x94, 0x54, 0x95, 0x65, 0x96, 0x75, 0x97, 0x84,
- 0x98, 0x93, 0x99, 0xa1, 0x9a, 0xb0, 0x9b, 0xbd,
- 0x9c, 0xca, 0x9d, 0xd6, 0x9e, 0xe0, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x18, 0x92, 0x2b, 0x93, 0x44, /* 10 */
- 0x94, 0x60, 0x95, 0x70, 0x96, 0x80, 0x97, 0x8e,
- 0x98, 0x9c, 0x99, 0xaa, 0x9a, 0xb7, 0x9b, 0xc4,
- 0x9c, 0xd0, 0x9d, 0xd8, 0x9e, 0xe2, 0x9f, 0xf0,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x1a, 0x92, 0x34, 0x93, 0x52, /* 11 */
- 0x94, 0x66, 0x95, 0x7e, 0x96, 0x8D, 0x97, 0x9B,
- 0x98, 0xa8, 0x99, 0xb4, 0x9a, 0xc0, 0x9b, 0xcb,
- 0x9c, 0xd6, 0x9d, 0xe1, 0x9e, 0xeb, 0x9f, 0xf5,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x3f, 0x92, 0x5a, 0x93, 0x6e, /* 12 */
- 0x94, 0x7f, 0x95, 0x8e, 0x96, 0x9c, 0x97, 0xa8,
- 0x98, 0xb4, 0x99, 0xbf, 0x9a, 0xc9, 0x9b, 0xd3,
- 0x9c, 0xdc, 0x9d, 0xe5, 0x9e, 0xee, 0x9f, 0xf6,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x54, 0x92, 0x6f, 0x93, 0x83, /* 13 */
- 0x94, 0x93, 0x95, 0xa0, 0x96, 0xad, 0x97, 0xb7,
- 0x98, 0xc2, 0x99, 0xcb, 0x9a, 0xd4, 0x9b, 0xdc,
- 0x9c, 0xe4, 0x9d, 0xeb, 0x9e, 0xf2, 0x9f, 0xf9,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x6e, 0x92, 0x88, 0x93, 0x9a, /* 14 */
- 0x94, 0xa8, 0x95, 0xb3, 0x96, 0xbd, 0x97, 0xc6,
- 0x98, 0xcf, 0x99, 0xd6, 0x9a, 0xdd, 0x9b, 0xe3,
- 0x9c, 0xe9, 0x9d, 0xef, 0x9e, 0xf4, 0x9f, 0xfa,
- 0xa0, 0xff},
- {0x90, 0x00, 0x91, 0x93, 0x92, 0xa8, 0x93, 0xb7, /* 15 */
- 0x94, 0xc1, 0x95, 0xca, 0x96, 0xd2, 0x97, 0xd8,
- 0x98, 0xde, 0x99, 0xe3, 0x9a, 0xe8, 0x9b, 0xed,
- 0x9c, 0xf1, 0x9d, 0xf5, 0x9e, 0xf8, 0x9f, 0xfc,
- 0xa0, 0xff}
+static const u8 gamma_table[GAMMA_MAX][17] = {
+ {0x00, 0x3e, 0x69, 0x85, 0x95, 0xa1, 0xae, 0xb9, /* 0 */
+ 0xc2, 0xcb, 0xd4, 0xdb, 0xe3, 0xea, 0xf1, 0xf8,
+ 0xff},
+ {0x00, 0x33, 0x5a, 0x75, 0x85, 0x93, 0xa1, 0xad, /* 1 */
+ 0xb7, 0xc2, 0xcb, 0xd4, 0xde, 0xe7, 0xf0, 0xf7,
+ 0xff},
+ {0x00, 0x2f, 0x51, 0x6b, 0x7c, 0x8a, 0x99, 0xa6, /* 2 */
+ 0xb1, 0xbc, 0xc6, 0xd0, 0xdb, 0xe4, 0xed, 0xf6,
+ 0xff},
+ {0x00, 0x29, 0x48, 0x60, 0x72, 0x81, 0x90, 0x9e, /* 3 */
+ 0xaa, 0xb5, 0xbf, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x23, 0x3f, 0x55, 0x68, 0x77, 0x86, 0x95, /* 4 */
+ 0xa2, 0xad, 0xb9, 0xc6, 0xd2, 0xde, 0xe9, 0xf4,
+ 0xff},
+ {0x00, 0x1b, 0x33, 0x48, 0x59, 0x69, 0x79, 0x87, /* 5 */
+ 0x96, 0xa3, 0xb1, 0xbe, 0xcc, 0xda, 0xe7, 0xf3,
+ 0xff},
+ {0x00, 0x02, 0x10, 0x20, 0x32, 0x40, 0x57, 0x67, /* 6 */
+ 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee,
+ 0xff},
+ {0x00, 0x02, 0x14, 0x26, 0x38, 0x4a, 0x60, 0x70, /* 7 */
+ 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x22, 0x35, 0x47, 0x5a, 0x69, 0x79, /* 8 */
+ 0x88, 0x97, 0xa7, 0xb6, 0xc4, 0xd3, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x10, 0x26, 0x40, 0x54, 0x65, 0x75, 0x84, /* 9 */
+ 0x93, 0xa1, 0xb0, 0xbd, 0xca, 0xd6, 0xe0, 0xf0,
+ 0xff},
+ {0x00, 0x18, 0x2b, 0x44, 0x60, 0x70, 0x80, 0x8e, /* 10 */
+ 0x9c, 0xaa, 0xb7, 0xc4, 0xd0, 0xd8, 0xe2, 0xf0,
+ 0xff},
+ {0x00, 0x1a, 0x34, 0x52, 0x66, 0x7e, 0x8D, 0x9B, /* 11 */
+ 0xa8, 0xb4, 0xc0, 0xcb, 0xd6, 0xe1, 0xeb, 0xf5,
+ 0xff},
+ {0x00, 0x3f, 0x5a, 0x6e, 0x7f, 0x8e, 0x9c, 0xa8, /* 12 */
+ 0xb4, 0xbf, 0xc9, 0xd3, 0xdc, 0xe5, 0xee, 0xf6,
+ 0xff},
+ {0x00, 0x54, 0x6f, 0x83, 0x93, 0xa0, 0xad, 0xb7, /* 13 */
+ 0xc2, 0xcb, 0xd4, 0xdc, 0xe4, 0xeb, 0xf2, 0xf9,
+ 0xff},
+ {0x00, 0x6e, 0x88, 0x9a, 0xa8, 0xb3, 0xbd, 0xc6, /* 14 */
+ 0xcf, 0xd6, 0xdd, 0xe3, 0xe9, 0xef, 0xf4, 0xfa,
+ 0xff},
+ {0x00, 0x93, 0xa8, 0xb7, 0xc1, 0xca, 0xd2, 0xd8, /* 15 */
+ 0xde, 0xe3, 0xe8, 0xed, 0xf1, 0xf5, 0xf8, 0xfc,
+ 0xff}
};
-static const __u8 tas5130a_sensor_init[][8] = {
+static const u8 tas5130a_sensor_init[][8] = {
{0x62, 0x08, 0x63, 0x70, 0x64, 0x1d, 0x60, 0x09},
{0x62, 0x20, 0x63, 0x01, 0x64, 0x02, 0x60, 0x09},
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09},
@@ -418,11 +389,11 @@ static const __u8 tas5130a_sensor_init[][8] = {
{},
};
-static __u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
+static u8 sensor_reset[] = {0x61, 0x68, 0x62, 0xff, 0x60, 0x07};
/* read 1 byte */
-static int reg_r(struct gspca_dev *gspca_dev,
- __u16 index)
+static u8 reg_r(struct gspca_dev *gspca_dev,
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
@@ -435,7 +406,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
static void reg_w(struct gspca_dev *gspca_dev,
- __u16 index)
+ u16 index)
{
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
@@ -446,7 +417,7 @@ static void reg_w(struct gspca_dev *gspca_dev,
}
static void reg_w_buf(struct gspca_dev *gspca_dev,
- const __u8 *buffer, __u16 len)
+ const u8 *buffer, u16 len)
{
if (len <= USB_BUF_SZ) {
memcpy(gspca_dev->usb_buf, buffer, len);
@@ -457,7 +428,7 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
0x01, 0,
gspca_dev->usb_buf, len, 500);
} else {
- __u8 *tmpbuf;
+ u8 *tmpbuf;
tmpbuf = kmalloc(len, GFP_KERNEL);
memcpy(tmpbuf, buffer, len);
@@ -471,14 +442,41 @@ static void reg_w_buf(struct gspca_dev *gspca_dev,
}
}
+/* write values to consecutive registers */
+static void reg_w_ixbuf(struct gspca_dev *gspca_dev,
+ u8 reg,
+ const u8 *buffer, u16 len)
+{
+ int i;
+ u8 *p, *tmpbuf;
+
+ if (len * 2 <= USB_BUF_SZ)
+ p = tmpbuf = gspca_dev->usb_buf;
+ else
+ p = tmpbuf = kmalloc(len * 2, GFP_KERNEL);
+ i = len;
+ while (--i >= 0) {
+ *p++ = reg++;
+ *p++ = *buffer++;
+ }
+ usb_control_msg(gspca_dev->dev,
+ usb_sndctrlpipe(gspca_dev->dev, 0),
+ 0,
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+ 0x01, 0,
+ tmpbuf, len * 2, 500);
+ if (len * 2 > USB_BUF_SZ)
+ kfree(tmpbuf);
+}
+
/* Reported as OM6802*/
static void om6802_sensor_init(struct gspca_dev *gspca_dev)
{
int i;
- const __u8 *p;
- __u8 byte;
- __u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
- static const __u8 sensor_init[] = {
+ const u8 *p;
+ u8 byte;
+ u8 val[6] = {0x62, 0, 0x64, 0, 0x60, 0x05};
+ static const u8 sensor_init[] = {
0xdf, 0x6d,
0xdd, 0x18,
0x5a, 0xe0,
@@ -497,7 +495,7 @@ static void om6802_sensor_init(struct gspca_dev *gspca_dev)
};
reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- msleep(5);
+ msleep(100);
i = 4;
while (--i > 0) {
byte = reg_r(gspca_dev, 0x0060);
@@ -538,20 +536,20 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct cam *cam;
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
cam->cam_mode = vga_mode_t16;
cam->nmodes = ARRAY_SIZE(vga_mode_t16);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
- sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
+ sd->contrast = CONTRAST_DEF;
+ sd->colors = COLORS_DEF;
sd->gamma = GAMMA_DEF;
- sd->mirror = sd_ctrls[SD_MIRROR].qctrl.default_value;
- sd->freq = sd_ctrls[SD_LIGHTFREQ].qctrl.default_value;
- sd->whitebalance = sd_ctrls[SD_WHITE_BALANCE].qctrl.default_value;
- sd->sharpness = sd_ctrls[SD_SHARPNESS].qctrl.default_value;
- sd->effect = sd_ctrls[SD_EFFECTS].qctrl.default_value;
+ sd->autogain = AUTOGAIN_DEF;
+ sd->mirror = MIRROR_DEF;
+ sd->freq = FREQ_DEF;
+ sd->whitebalance = WHITE_BALANCE_DEF;
+ sd->sharpness = SHARPNESS_DEF;
+ sd->effect = EFFECTS_DEF;
return 0;
}
@@ -559,7 +557,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int brightness;
- __u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
+ u8 set6[4] = { 0x8f, 0x24, 0xc3, 0x00 };
brightness = sd->brightness;
if (brightness < 7) {
@@ -576,7 +574,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
unsigned int contrast = sd->contrast;
- __u16 reg_to_write;
+ u16 reg_to_write;
if (contrast < 7)
reg_to_write = 0x8ea9 - contrast * 0x200;
@@ -589,7 +587,7 @@ static void setcontrast(struct gspca_dev *gspca_dev)
static void setcolors(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x80bb + sd->colors * 0x100; /* was 0xc0 */
reg_w(gspca_dev, reg_to_write);
@@ -600,14 +598,15 @@ static void setgamma(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
PDEBUG(D_CONF, "Gamma: %d", sd->gamma);
- reg_w_buf(gspca_dev, gamma_table[sd->gamma], sizeof gamma_table[0]);
+ reg_w_ixbuf(gspca_dev, 0x90,
+ gamma_table[sd->gamma], sizeof gamma_table[0]);
}
static void setwhitebalance(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 white_balance[8] =
+ u8 white_balance[8] =
{0x87, 0x20, 0x88, 0x20, 0x89, 0x20, 0x80, 0x38};
if (sd->whitebalance)
@@ -619,7 +618,7 @@ static void setwhitebalance(struct gspca_dev *gspca_dev)
static void setsharpness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u16 reg_to_write;
+ u16 reg_to_write;
reg_to_write = 0x0aa6 + 0x1000 * sd->sharpness;
@@ -635,18 +634,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
* to see the initial parameters.*/
struct sd *sd = (struct sd *) gspca_dev;
int i;
- __u8 byte, test_byte;
-
- static const __u8 read_indexs[] =
- { 0x06, 0x07, 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
- 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00, 0x00 };
- static const __u8 n1[] =
+ u16 sensor_id;
+ u8 test_byte = 0;
+ u16 reg80, reg8e;
+
+ static const u8 read_indexs[] =
+ { 0x0a, 0x0b, 0x66, 0x80, 0x81, 0x8e, 0x8f, 0xa5,
+ 0xa6, 0xa8, 0xbb, 0xbc, 0xc6, 0x00 };
+ static const u8 n1[] =
{0x08, 0x03, 0x09, 0x03, 0x12, 0x04};
- static const __u8 n2[] =
+ static const u8 n2[] =
{0x08, 0x00};
- static const __u8 n3[] =
+ static const u8 n3[6] =
{0x61, 0x68, 0x65, 0x0a, 0x60, 0x04};
- static const __u8 n4[] =
+ static const u8 n3_other[6] =
+ {0x61, 0xc2, 0x65, 0x88, 0x60, 0x00};
+ static const u8 n4[] =
{0x09, 0x01, 0x12, 0x04, 0x66, 0x8a, 0x80, 0x3c,
0x81, 0x22, 0x84, 0x50, 0x8a, 0x78, 0x8b, 0x68,
0x8c, 0x88, 0x8e, 0x33, 0x8f, 0x24, 0xaa, 0xb1,
@@ -656,40 +659,61 @@ static int sd_init(struct gspca_dev *gspca_dev)
0x65, 0x0a, 0xbb, 0x86, 0xaf, 0x58, 0xb0, 0x68,
0x87, 0x40, 0x89, 0x2b, 0x8d, 0xff, 0x83, 0x40,
0xac, 0x84, 0xad, 0x86, 0xaf, 0x46};
- static const __u8 nset9[4] =
- { 0x0b, 0x04, 0x0a, 0x78 };
- static const __u8 nset8[6] =
+ static const u8 n4_other[] =
+ {0x66, 0x00, 0x7f, 0x00, 0x80, 0xac, 0x81, 0x69,
+ 0x84, 0x40, 0x85, 0x70, 0x86, 0x20, 0x8a, 0x68,
+ 0x8b, 0x58, 0x8c, 0x88, 0x8d, 0xff, 0x8e, 0xb8,
+ 0x8f, 0x28, 0xa2, 0x60, 0xa5, 0x40, 0xa8, 0xa8,
+ 0xac, 0x84, 0xad, 0x84, 0xae, 0x24, 0xaf, 0x56,
+ 0xb0, 0x68, 0xb1, 0x00, 0xb2, 0x88, 0xbb, 0xc5,
+ 0xbc, 0x4a, 0xbe, 0x36, 0xc2, 0x88, 0xc5, 0xc0,
+ 0xc6, 0xda, 0xe9, 0x26, 0xeb, 0x00};
+ static const u8 nset8[6] =
{ 0xa8, 0xf0, 0xc6, 0x88, 0xc0, 0x00 };
-
- byte = reg_r(gspca_dev, 0x06);
- test_byte = reg_r(gspca_dev, 0x07);
- if (byte == 0x08 && test_byte == 0x07) {
- PDEBUG(D_CONF, "sensor om6802");
- sd->sensor = SENSOR_OM6802;
- } else if (byte == 0x08 && test_byte == 0x01) {
- PDEBUG(D_CONF, "sensor tas5130a");
- sd->sensor = SENSOR_TAS5130A;
- } else {
- PDEBUG(D_CONF, "unknown sensor %02x %02x", byte, test_byte);
+ static const u8 nset8_other[6] =
+ { 0xa8, 0xa8, 0xc6, 0xda, 0xc0, 0x00 };
+ static const u8 nset9[4] =
+ { 0x0b, 0x04, 0x0a, 0x78 };
+ static const u8 nset9_other[4] =
+ { 0x0b, 0x04, 0x0a, 0x00 };
+
+ sensor_id = (reg_r(gspca_dev, 0x06) << 8)
+ | reg_r(gspca_dev, 0x07);
+ switch (sensor_id & 0xff0f) {
+ case 0x0801:
+ PDEBUG(D_PROBE, "sensor tas5130a");
sd->sensor = SENSOR_TAS5130A;
+ break;
+ case 0x0803:
+ PDEBUG(D_PROBE, "sensor 'other'");
+ sd->sensor = SENSOR_OTHER;
+ break;
+ case 0x0807:
+ PDEBUG(D_PROBE, "sensor om6802");
+ sd->sensor = SENSOR_OM6802;
+ break;
+ default:
+ PDEBUG(D_ERR|D_PROBE, "unknown sensor %04x", sensor_id);
+ return -EINVAL;
}
- reg_w_buf(gspca_dev, n1, sizeof n1);
- test_byte = 0;
- i = 5;
- while (--i >= 0) {
- reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
- test_byte = reg_r(gspca_dev, 0x0063);
- msleep(100);
- if (test_byte == 0x17)
- break; /* OK */
- }
- if (i < 0) {
- err("Bad sensor reset %02x", test_byte);
-/* return -EIO; */
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n1, sizeof n1);
+ i = 5;
+ while (--i >= 0) {
+ reg_w_buf(gspca_dev, sensor_reset, sizeof sensor_reset);
+ test_byte = reg_r(gspca_dev, 0x0063);
+ msleep(100);
+ if (test_byte == 0x17)
+ break; /* OK */
+ }
+ if (i < 0) {
+ err("Bad sensor reset %02x", test_byte);
+/* return -EIO; */
/*fixme: test - continue */
+ }
+ reg_w_buf(gspca_dev, n2, sizeof n2);
}
- reg_w_buf(gspca_dev, n2, sizeof n2);
i = 0;
while (read_indexs[i] != 0x00) {
@@ -699,21 +723,31 @@ static int sd_init(struct gspca_dev *gspca_dev)
i++;
}
- reg_w_buf(gspca_dev, n3, sizeof n3);
- reg_w_buf(gspca_dev, n4, sizeof n4);
- reg_r(gspca_dev, 0x0080);
- reg_w(gspca_dev, 0x2c80);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, n3, sizeof n3);
+ reg_w_buf(gspca_dev, n4, sizeof n4);
+ reg_r(gspca_dev, 0x0080);
+ reg_w(gspca_dev, 0x2c80);
+ reg80 = 0x3880;
+ reg8e = 0x338e;
+ } else {
+ reg_w_buf(gspca_dev, n3_other, sizeof n3_other);
+ reg_w_buf(gspca_dev, n4_other, sizeof n4_other);
+ sd->gamma = 5;
+ reg80 = 0xac80;
+ reg8e = 0xb88e;
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x3880);
- reg_w(gspca_dev, 0x338e);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg80);
+ reg_w(gspca_dev, reg8e);
setbrightness(gspca_dev);
setcontrast(gspca_dev);
@@ -730,16 +764,20 @@ static int sd_init(struct gspca_dev *gspca_dev)
sizeof sensor_data[sd->sensor].data4);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data5,
sizeof sensor_data[sd->sensor].data5);
- reg_w_buf(gspca_dev, nset8, sizeof nset8);
- reg_w_buf(gspca_dev, nset9, sizeof nset9);
-
- reg_w(gspca_dev, 0x2880);
+ if (sd->sensor != SENSOR_OTHER) {
+ reg_w_buf(gspca_dev, nset8, sizeof nset8);
+ reg_w_buf(gspca_dev, nset9, sizeof nset9);
+ reg_w(gspca_dev, 0x2880);
+ } else {
+ reg_w_buf(gspca_dev, nset8_other, sizeof nset8_other);
+ reg_w_buf(gspca_dev, nset9_other, sizeof nset9_other);
+ }
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data1,
+ reg_w_ixbuf(gspca_dev, 0xd0, sensor_data[sd->sensor].data1,
sizeof sensor_data[sd->sensor].data1);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data3,
- sizeof sensor_data[sd->sensor].data3);
- reg_w_buf(gspca_dev, sensor_data[sd->sensor].data2,
+ reg_w_ixbuf(gspca_dev, 0xc7, sensor_data[sd->sensor].data2,
+ sizeof sensor_data[sd->sensor].data2);
+ reg_w_ixbuf(gspca_dev, 0xe0, sensor_data[sd->sensor].data2,
sizeof sensor_data[sd->sensor].data2);
return 0;
@@ -748,7 +786,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setflip(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 flipcmd[8] =
+ u8 flipcmd[8] =
{0x62, 0x07, 0x63, 0x03, 0x64, 0x00, 0x60, 0x09};
if (sd->mirror)
@@ -778,7 +816,7 @@ static void seteffect(struct gspca_dev *gspca_dev)
static void setlightfreq(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- __u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
+ u8 freq[4] = { 0x66, 0x40, 0xa8, 0xe8 };
if (sd->freq == 2) /* 60hz */
freq[1] = 0x00;
@@ -791,22 +829,22 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
static void poll_sensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- static const __u8 poll1[] =
+ static const u8 poll1[] =
{0x67, 0x05, 0x68, 0x81, 0x69, 0x80, 0x6a, 0x82,
0x6b, 0x68, 0x6c, 0x69, 0x72, 0xd9, 0x73, 0x34,
0x74, 0x32, 0x75, 0x92, 0x76, 0x00, 0x09, 0x01,
0x60, 0x14};
- static const __u8 poll2[] =
+ static const u8 poll2[] =
{0x67, 0x02, 0x68, 0x71, 0x69, 0x72, 0x72, 0xa9,
0x73, 0x02, 0x73, 0x02, 0x60, 0x14};
- static const __u8 poll3[] =
+ static const u8 poll3[] =
{0x87, 0x3f, 0x88, 0x20, 0x89, 0x2d};
- static const __u8 poll4[] =
+ static const u8 poll4[] =
{0xa6, 0x0a, 0xea, 0xcf, 0xbe, 0x26, 0xb1, 0x5f,
0xa1, 0xb1, 0xda, 0x6b, 0xdb, 0x98, 0xdf, 0x0c,
0xc2, 0x80, 0xc3, 0x10};
- if (sd->sensor != SENSOR_TAS5130A) {
+ if (sd->sensor == SENSOR_OM6802) {
PDEBUG(D_STREAM, "[Sensor requires polling]");
reg_w_buf(gspca_dev, poll1, sizeof poll1);
reg_w_buf(gspca_dev, poll2, sizeof poll2);
@@ -819,13 +857,14 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
int i, mode;
- __u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
- static const __u8 t3[] =
- { 0xb3, 0x07, 0xb4, 0x00, 0xb5, 0x88, 0xb6, 0x02, 0xb7, 0x06,
- 0xb8, 0x00, 0xb9, 0xe7, 0xba, 0x01 };
+ u8 t2[] = { 0x07, 0x00, 0x0d, 0x60, 0x0e, 0x80 };
+ static const u8 t3[] =
+ { 0x07, 0x00, 0x88, 0x02, 0x06, 0x00, 0xe7, 0x01 };
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode]. priv;
switch (mode) {
+ case 0: /* 640x480 (0x00) */
+ break;
case 1: /* 352x288 */
t2[1] = 0x40;
break;
@@ -835,14 +874,20 @@ static int sd_start(struct gspca_dev *gspca_dev)
case 3: /* 176x144 */
t2[1] = 0x50;
break;
- case 4: /* 160x120 */
+ default:
+/* case 4: * 160x120 */
t2[1] = 0x20;
break;
- default: /* 640x480 (0x00) */
- break;
}
- if (sd->sensor == SENSOR_TAS5130A) {
+ switch (sd->sensor) {
+ case SENSOR_OM6802:
+ om6802_sensor_init(gspca_dev);
+ break;
+ case SENSOR_OTHER:
+ break;
+ default:
+/* case SENSOR_TAS5130A: */
i = 0;
while (tas5130a_sensor_init[i][0] != 0) {
reg_w_buf(gspca_dev, tas5130a_sensor_init[i],
@@ -854,14 +899,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w_buf(gspca_dev, tas5130a_sensor_init[3],
sizeof tas5130a_sensor_init[0]);
reg_w(gspca_dev, 0x3c80);
- } else {
- om6802_sensor_init(gspca_dev);
+ break;
}
reg_w_buf(gspca_dev, sensor_data[sd->sensor].data4,
sizeof sensor_data[sd->sensor].data4);
reg_r(gspca_dev, 0x0012);
reg_w_buf(gspca_dev, t2, sizeof t2);
- reg_w_buf(gspca_dev, t3, sizeof t3);
+ reg_w_ixbuf(gspca_dev, 0xb3, t3, sizeof t3);
reg_w(gspca_dev, 0x0013);
msleep(15);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
@@ -885,16 +929,18 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
msleep(20);
reg_w_buf(gspca_dev, sensor_data[sd->sensor].stream,
sizeof sensor_data[sd->sensor].stream);
- msleep(20);
- reg_w(gspca_dev, 0x0309);
+ if (sd->sensor != SENSOR_OTHER) {
+ msleep(20);
+ reg_w(gspca_dev, 0x0309);
+ }
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
struct gspca_frame *frame, /* target */
- __u8 *data, /* isoc packet */
+ u8 *data, /* isoc packet */
int len) /* iso packet length */
{
- static __u8 ffd9[] = { 0xff, 0xd9 };
+ static u8 ffd9[] = { 0xff, 0xd9 };
if (data[0] == 0x5a) {
/* Control Packet, after this came the header again,
@@ -1172,8 +1218,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/tv8532.c b/drivers/media/video/gspca/tv8532.c
index 94163cceb28..9f243d7e311 100644
--- a/drivers/media/video/gspca/tv8532.c
+++ b/drivers/media/video/gspca/tv8532.c
@@ -31,7 +31,6 @@ struct sd {
struct gspca_dev gspca_dev; /* !! must be the first item */
__u16 brightness;
- __u16 contrast;
__u8 packet;
};
@@ -39,38 +38,22 @@ struct sd {
/* V4L2 controls supported by the driver */
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
static struct ctrl sd_ctrls[] = {
-#define SD_BRIGHTNESS 0
{
{
.id = V4L2_CID_BRIGHTNESS,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Brightness",
.minimum = 1,
- .maximum = 0x2ff,
+ .maximum = 0x15f, /* = 352 - 1 */
.step = 1,
- .default_value = 0x18f,
+#define BRIGHTNESS_DEF 0x14c
+ .default_value = BRIGHTNESS_DEF,
},
.set = sd_setbrightness,
.get = sd_getbrightness,
},
-#define SD_CONTRAST 1
- {
- {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 0xffff,
- .step = 1,
- .default_value = 0x7fff,
- },
- .set = sd_setcontrast,
- .get = sd_getcontrast,
- },
};
static const struct v4l2_pix_format sif_mode[] = {
@@ -86,78 +69,64 @@ static const struct v4l2_pix_format sif_mode[] = {
.priv = 0},
};
-/*
- * Initialization data: this is the first set-up data written to the
- * device (before the open data).
- */
-#define TESTCLK 0x10 /* reg 0x2c -> 0x12 //10 */
-#define TESTCOMP 0x90 /* reg 0x28 -> 0x80 */
-#define TESTLINE 0x81 /* reg 0x29 -> 0x81 */
-#define QCIFLINE 0x41 /* reg 0x29 -> 0x81 */
-#define TESTPTL 0x14 /* reg 0x2D -> 0x14 */
-#define TESTPTH 0x01 /* reg 0x2E -> 0x01 */
-#define TESTPTBL 0x12 /* reg 0x2F -> 0x0a */
-#define TESTPTBH 0x01 /* reg 0x30 -> 0x01 */
-#define ADWIDTHL 0xe8 /* reg 0x0c -> 0xe8 */
-#define ADWIDTHH 0x03 /* reg 0x0d -> 0x03 */
-#define ADHEIGHL 0x90 /* reg 0x0e -> 0x91 //93 */
-#define ADHEIGHH 0x01 /* reg 0x0f -> 0x01 */
-#define EXPOL 0x8f /* reg 0x1c -> 0x8f */
-#define EXPOH 0x01 /* reg 0x1d -> 0x01 */
-#define ADCBEGINL 0x44 /* reg 0x10 -> 0x46 //47 */
-#define ADCBEGINH 0x00 /* reg 0x11 -> 0x00 */
-#define ADRBEGINL 0x0a /* reg 0x14 -> 0x0b //0x0c */
-#define ADRBEGINH 0x00 /* reg 0x15 -> 0x00 */
-#define TV8532_CMD_UPDATE 0x84
-
-#define TV8532_EEprom_Add 0x03
-#define TV8532_EEprom_DataL 0x04
-#define TV8532_EEprom_DataM 0x05
-#define TV8532_EEprom_DataH 0x06
-#define TV8532_EEprom_TableLength 0x07
-#define TV8532_EEprom_Write 0x08
-#define TV8532_PART_CTRL 0x00
-#define TV8532_CTRL 0x01
-#define TV8532_CMD_EEprom_Open 0x30
-#define TV8532_CMD_EEprom_Close 0x29
-#define TV8532_UDP_UPDATE 0x31
-#define TV8532_GPIO 0x39
-#define TV8532_GPIO_OE 0x3B
-#define TV8532_REQ_RegWrite 0x02
-#define TV8532_REQ_RegRead 0x03
-
-#define TV8532_ADWIDTH_L 0x0C
-#define TV8532_ADWIDTH_H 0x0D
-#define TV8532_ADHEIGHT_L 0x0E
-#define TV8532_ADHEIGHT_H 0x0F
-#define TV8532_EXPOSURE 0x1C
-#define TV8532_QUANT_COMP 0x28
-#define TV8532_MODE_PACKET 0x29
-#define TV8532_SETCLK 0x2C
-#define TV8532_POINT_L 0x2D
-#define TV8532_POINT_H 0x2E
-#define TV8532_POINTB_L 0x2F
-#define TV8532_POINTB_H 0x30
-#define TV8532_BUDGET_L 0x2A
-#define TV8532_BUDGET_H 0x2B
-#define TV8532_VID_L 0x34
-#define TV8532_VID_H 0x35
-#define TV8532_PID_L 0x36
-#define TV8532_PID_H 0x37
-#define TV8532_DeviceID 0x83
-#define TV8532_AD_SLOPE 0x91
-#define TV8532_AD_BITCTRL 0x94
-#define TV8532_AD_COLBEGIN_L 0x10
-#define TV8532_AD_COLBEGIN_H 0x11
-#define TV8532_AD_ROWBEGIN_L 0x14
-#define TV8532_AD_ROWBEGIN_H 0x15
-
-static const __u32 tv_8532_eeprom_data[] = {
-/* add dataL dataM dataH */
- 0x00010001, 0x01018011, 0x02050014, 0x0305001c,
- 0x040d001e, 0x0505001f, 0x06050519, 0x0705011b,
- 0x0805091e, 0x090d892e, 0x0a05892f, 0x0b050dd9,
- 0x0c0509f1, 0
+/* TV-8532A (ICM532A) registers (LE) */
+#define R00_PART_CONTROL 0x00
+#define LATENT_CHANGE 0x80
+#define EXPO_CHANGE 0x04
+#define R01_TIMING_CONTROL_LOW 0x01
+#define CMD_EEprom_Open 0x30
+#define CMD_EEprom_Close 0x29
+#define R03_TABLE_ADDR 0x03
+#define R04_WTRAM_DATA_L 0x04
+#define R05_WTRAM_DATA_M 0x05
+#define R06_WTRAM_DATA_H 0x06
+#define R07_TABLE_LEN 0x07
+#define R08_RAM_WRITE_ACTION 0x08
+#define R0C_AD_WIDTHL 0x0c
+#define R0D_AD_WIDTHH 0x0d
+#define R0E_AD_HEIGHTL 0x0e
+#define R0F_AD_HEIGHTH 0x0f
+#define R10_AD_COL_BEGINL 0x10
+#define R11_AD_COL_BEGINH 0x11
+#define MIRROR 0x04 /* [10] */
+#define R14_AD_ROW_BEGINL 0x14
+#define R15_AD_ROWBEGINH 0x15
+#define R1C_AD_EXPOSE_TIMEL 0x1c
+#define R28_QUANT 0x28
+#define R29_LINE 0x29
+#define R2C_POLARITY 0x2c
+#define R2D_POINT 0x2d
+#define R2E_POINTH 0x2e
+#define R2F_POINTB 0x2f
+#define R30_POINTBH 0x30
+#define R31_UPD 0x31
+#define R2A_HIGH_BUDGET 0x2a
+#define R2B_LOW_BUDGET 0x2b
+#define R34_VID 0x34
+#define R35_VIDH 0x35
+#define R36_PID 0x36
+#define R37_PIDH 0x37
+#define R39_Test1 0x39 /* GPIO */
+#define R3B_Test3 0x3B /* GPIO */
+#define R83_AD_IDH 0x83
+#define R91_AD_SLOPEREG 0x91
+#define R94_AD_BITCONTROL 0x94
+
+static const u8 eeprom_data[][3] = {
+/* dataH dataM dataL */
+ {0x01, 0x00, 0x01},
+ {0x01, 0x80, 0x11},
+ {0x05, 0x00, 0x14},
+ {0x05, 0x00, 0x1c},
+ {0x0d, 0x00, 0x1e},
+ {0x05, 0x00, 0x1f},
+ {0x05, 0x05, 0x19},
+ {0x05, 0x01, 0x1b},
+ {0x05, 0x09, 0x1e},
+ {0x0d, 0x89, 0x2e},
+ {0x05, 0x89, 0x2f},
+ {0x05, 0x0d, 0xd9},
+ {0x05, 0x09, 0xf1},
};
static int reg_r(struct gspca_dev *gspca_dev,
@@ -165,7 +134,7 @@ static int reg_r(struct gspca_dev *gspca_dev,
{
usb_control_msg(gspca_dev->dev,
usb_rcvctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegRead,
+ 0x03,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1,
@@ -174,27 +143,27 @@ static int reg_r(struct gspca_dev *gspca_dev,
}
/* write 1 byte */
-static void reg_w_1(struct gspca_dev *gspca_dev,
+static void reg_w1(struct gspca_dev *gspca_dev,
__u16 index, __u8 value)
{
gspca_dev->usb_buf[0] = value;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 1, 500);
}
/* write 2 bytes */
-static void reg_w_2(struct gspca_dev *gspca_dev,
- __u16 index, __u8 val1, __u8 val2)
+static void reg_w2(struct gspca_dev *gspca_dev,
+ u16 index, u16 value)
{
- gspca_dev->usb_buf[0] = val1;
- gspca_dev->usb_buf[1] = val2;
+ gspca_dev->usb_buf[0] = value;
+ gspca_dev->usb_buf[1] = value >> 8;
usb_control_msg(gspca_dev->dev,
usb_sndctrlpipe(gspca_dev->dev, 0),
- TV8532_REQ_RegWrite,
+ 0x02,
USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
0, /* value */
index, gspca_dev->usb_buf, 2, 500);
@@ -202,32 +171,18 @@ static void reg_w_2(struct gspca_dev *gspca_dev,
static void tv_8532WriteEEprom(struct gspca_dev *gspca_dev)
{
- int i = 0;
- __u8 reg, data0, data1, data2;
-
- reg_w_1(gspca_dev, TV8532_GPIO, 0xb0);
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Open);
-/* msleep(1); */
- while (tv_8532_eeprom_data[i]) {
- reg = (tv_8532_eeprom_data[i] & 0xff000000) >> 24;
- reg_w_1(gspca_dev, TV8532_EEprom_Add, reg);
- /* msleep(1); */
- data0 = (tv_8532_eeprom_data[i] & 0x000000ff);
- reg_w_1(gspca_dev, TV8532_EEprom_DataL, data0);
- /* msleep(1); */
- data1 = (tv_8532_eeprom_data[i] & 0x0000ff00) >> 8;
- reg_w_1(gspca_dev, TV8532_EEprom_DataM, data1);
- /* msleep(1); */
- data2 = (tv_8532_eeprom_data[i] & 0x00ff0000) >> 16;
- reg_w_1(gspca_dev, TV8532_EEprom_DataH, data2);
- /* msleep(1); */
- reg_w_1(gspca_dev, TV8532_EEprom_Write, 0);
- /* msleep(10); */
- i++;
+ int i;
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Open);
+ for (i = 0; i < ARRAY_SIZE(eeprom_data); i++) {
+ reg_w1(gspca_dev, R03_TABLE_ADDR, i);
+ reg_w1(gspca_dev, R04_WTRAM_DATA_L, eeprom_data[i][2]);
+ reg_w1(gspca_dev, R05_WTRAM_DATA_M, eeprom_data[i][1]);
+ reg_w1(gspca_dev, R06_WTRAM_DATA_H, eeprom_data[i][0]);
+ reg_w1(gspca_dev, R08_RAM_WRITE_ACTION, 0);
}
- reg_w_1(gspca_dev, TV8532_EEprom_TableLength, i);
-/* msleep(1); */
- reg_w_1(gspca_dev, TV8532_CTRL, TV8532_CMD_EEprom_Close);
+ reg_w1(gspca_dev, R07_TABLE_LEN, i);
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
msleep(10);
}
@@ -238,79 +193,76 @@ static int sd_config(struct gspca_dev *gspca_dev,
struct sd *sd = (struct sd *) gspca_dev;
struct cam *cam;
- tv_8532WriteEEprom(gspca_dev);
-
cam = &gspca_dev->cam;
- cam->epaddr = 1;
cam->cam_mode = sif_mode;
- cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
+ cam->nmodes = ARRAY_SIZE(sif_mode);
- sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
- sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
+ sd->brightness = BRIGHTNESS_DEF;
return 0;
}
static void tv_8532ReadRegisters(struct gspca_dev *gspca_dev)
{
- __u8 data;
-
- data = reg_r(gspca_dev, 0x0001);
- PDEBUG(D_USBI, "register 0x01-> %x", data);
- data = reg_r(gspca_dev, 0x0002);
- PDEBUG(D_USBI, "register 0x02-> %x", data);
- reg_r(gspca_dev, TV8532_ADWIDTH_L);
- reg_r(gspca_dev, TV8532_ADWIDTH_H);
- reg_r(gspca_dev, TV8532_QUANT_COMP);
- reg_r(gspca_dev, TV8532_MODE_PACKET);
- reg_r(gspca_dev, TV8532_SETCLK);
- reg_r(gspca_dev, TV8532_POINT_L);
- reg_r(gspca_dev, TV8532_POINT_H);
- reg_r(gspca_dev, TV8532_POINTB_L);
- reg_r(gspca_dev, TV8532_POINTB_H);
- reg_r(gspca_dev, TV8532_BUDGET_L);
- reg_r(gspca_dev, TV8532_BUDGET_H);
- reg_r(gspca_dev, TV8532_VID_L);
- reg_r(gspca_dev, TV8532_VID_H);
- reg_r(gspca_dev, TV8532_PID_L);
- reg_r(gspca_dev, TV8532_PID_H);
- reg_r(gspca_dev, TV8532_DeviceID);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_COLBEGIN_H);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_L);
- reg_r(gspca_dev, TV8532_AD_ROWBEGIN_H);
+ int i;
+ static u8 reg_tb[] = {
+ R0C_AD_WIDTHL,
+ R0D_AD_WIDTHH,
+ R28_QUANT,
+ R29_LINE,
+ R2C_POLARITY,
+ R2D_POINT,
+ R2E_POINTH,
+ R2F_POINTB,
+ R30_POINTBH,
+ R2A_HIGH_BUDGET,
+ R2B_LOW_BUDGET,
+ R34_VID,
+ R35_VIDH,
+ R36_PID,
+ R37_PIDH,
+ R83_AD_IDH,
+ R10_AD_COL_BEGINL,
+ R11_AD_COL_BEGINH,
+ R14_AD_ROW_BEGINL,
+ R15_AD_ROWBEGINH,
+ 0
+ };
+
+ i = 0;
+ do {
+ reg_r(gspca_dev, reg_tb[i]);
+ i++;
+ } while (reg_tb[i] != 0);
}
static void tv_8532_setReg(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
-
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0a);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
+
+ reg_w1(gspca_dev, R3B_Test3, 0x0a); /* Test0Sel = 10 */
/******************************************************/
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL); /* 0e */
- reg_w_1(gspca_dev, TV8532_ADHEIGHT_H, ADHEIGHH); /* 0f */
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_L,
- ADCBEGINL); /* 0x10 */
- reg_w_1(gspca_dev, TV8532_AD_COLBEGIN_H,
- ADCBEGINH); /* also digital gain */
- reg_w_1(gspca_dev, TV8532_AD_ROWBEGIN_L,
- ADRBEGINL); /* 0x14 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x02); /* 0x94 */
-
- reg_w_1(gspca_dev, TV8532_CTRL,
- TV8532_CMD_EEprom_Close); /* 0x01 */
-
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x00); /* 0x91 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R0E_AD_HEIGHTL, 0x90);
+ reg_w1(gspca_dev, R0F_AD_HEIGHTH, 0x01);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R10_AD_COL_BEGINL, 0x44);
+ /* begin active line */
+ reg_w1(gspca_dev, R11_AD_COL_BEGINH, 0x00);
+ /* mirror and digital gain */
+ reg_w1(gspca_dev, R14_AD_ROW_BEGINL, 0x0a);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x02);
+
+ reg_w1(gspca_dev, R01_TIMING_CONTROL_LOW, CMD_EEprom_Close);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x00);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* = 0x84 */
}
static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
@@ -319,54 +271,55 @@ static void tv_8532_PollReg(struct gspca_dev *gspca_dev)
/* strange polling from tgc */
for (i = 0; i < 10; i++) {
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ reg_w1(gspca_dev, R00_PART_CONTROL,
+ LATENT_CHANGE | EXPO_CHANGE);
+ reg_w1(gspca_dev, R31_UPD, 0x01);
}
}
/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ tv_8532WriteEEprom(gspca_dev);
+
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L, ADHEIGHL,
- ADHEIGHH); /* 401d 0x0169; 0e */
- reg_w_2(gspca_dev, TV8532_EXPOSURE, EXPOL,
- EXPOH); /* 350d 0x014c; 1c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, 0x018f);
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8);
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/*******************************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* no compress - fixed Q - quant 0 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* 0x84; // CIF | 4 packet 0x29 */
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10);
+ /* 0x48; //0x08; 0x2c */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ /* 0x38; 0x2d */
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ /* 0x04; 0x2e */
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ /* 0x04; 0x2f */
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ /* 0x04; 0x30 */
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x00<-0x84 */
/*************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/*************************************************/
tv_8532_setReg(gspca_dev);
/*************************************************/
@@ -377,11 +330,10 @@ static int sd_init(struct gspca_dev *gspca_dev)
static void setbrightness(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int brightness = sd->brightness;
- reg_w_2(gspca_dev, TV8532_EXPOSURE,
- brightness >> 8, brightness); /* 1c */
- reg_w_1(gspca_dev, TV8532_PART_CTRL, TV8532_CMD_UPDATE);
+ reg_w2(gspca_dev, R1C_AD_EXPOSE_TIMEL, sd->brightness);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
+ /* 0x84 */
}
/* -- start the camera -- */
@@ -389,57 +341,50 @@ static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- reg_w_1(gspca_dev, TV8532_AD_SLOPE, 0x32);
- reg_w_1(gspca_dev, TV8532_AD_BITCTRL, 0x00);
+ reg_w1(gspca_dev, R91_AD_SLOPEREG, 0x32); /* slope begin 1,7V,
+ * slope rate 2 */
+ reg_w1(gspca_dev, R94_AD_BITCONTROL, 0x00);
tv_8532ReadRegisters(gspca_dev);
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
- reg_w_2(gspca_dev, TV8532_ADHEIGHT_L,
- ADHEIGHL, ADHEIGHH); /* 401d 0x0169; 0e */
-/* reg_w_2(gspca_dev, TV8532_EXPOSURE,
- EXPOL, EXPOH); * 350d 0x014c; 1c */
+ reg_w1(gspca_dev, R3B_Test3, 0x0b);
+
+ reg_w2(gspca_dev, R0E_AD_HEIGHTL, 0x0190);
setbrightness(gspca_dev);
- reg_w_1(gspca_dev, TV8532_ADWIDTH_L, ADWIDTHL); /* 0x20; 0x0c */
- reg_w_1(gspca_dev, TV8532_ADWIDTH_H, ADWIDTHH); /* 0x0d */
+ reg_w1(gspca_dev, R0C_AD_WIDTHL, 0xe8); /* 0x20; 0x0c */
+ reg_w1(gspca_dev, R0D_AD_WIDTHH, 0x03);
/************************************************/
- reg_w_1(gspca_dev, TV8532_QUANT_COMP,
- TESTCOMP); /* 0x72 compressed mode 0x28 */
+ reg_w1(gspca_dev, R28_QUANT, 0x90);
+ /* 0x72 compressed mode 0x28 */
if (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
/* 176x144 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- QCIFLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x41);
+ /* CIF - 2 lines/packet */
} else {
/* 352x288 */
- reg_w_1(gspca_dev, TV8532_MODE_PACKET,
- TESTLINE); /* 0x84; // CIF | 4 packet 0x29 */
+ reg_w1(gspca_dev, R29_LINE, 0x81);
+ /* CIF - 2 lines/packet */
}
/************************************************/
- reg_w_1(gspca_dev, TV8532_SETCLK,
- TESTCLK); /* 0x48; //0x08; 0x2c */
- reg_w_1(gspca_dev, TV8532_POINT_L,
- TESTPTL); /* 0x38; 0x2d */
- reg_w_1(gspca_dev, TV8532_POINT_H,
- TESTPTH); /* 0x04; 0x2e */
- reg_w_1(gspca_dev, TV8532_POINTB_L,
- TESTPTBL); /* 0x04; 0x2f */
- reg_w_1(gspca_dev, TV8532_POINTB_H,
- TESTPTBH); /* 0x04; 0x30 */
- reg_w_1(gspca_dev, TV8532_PART_CTRL,
- TV8532_CMD_UPDATE); /* 0x00<-0x84 */
+ reg_w1(gspca_dev, R2C_POLARITY, 0x10); /* slow clock */
+ reg_w1(gspca_dev, R2D_POINT, 0x14);
+ reg_w1(gspca_dev, R2E_POINTH, 0x01);
+ reg_w1(gspca_dev, R2F_POINTB, 0x12);
+ reg_w1(gspca_dev, R30_POINTBH, 0x01);
+ reg_w1(gspca_dev, R00_PART_CONTROL, LATENT_CHANGE | EXPO_CHANGE);
/************************************************/
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x01); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x01); /* update registers */
msleep(200);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
/************************************************/
tv_8532_setReg(gspca_dev);
/************************************************/
tv_8532_PollReg(gspca_dev);
- reg_w_1(gspca_dev, TV8532_UDP_UPDATE, 0x00); /* 0x31 */
+ reg_w1(gspca_dev, R31_UPD, 0x00); /* end update */
gspca_dev->empty_packet = 0; /* check the empty packets */
sd->packet = 0; /* ignore the first packets */
@@ -449,7 +394,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
static void sd_stopN(struct gspca_dev *gspca_dev)
{
- reg_w_1(gspca_dev, TV8532_GPIO_OE, 0x0b);
+ reg_w1(gspca_dev, R3B_Test3, 0x0b); /* Test0Sel = 11 = GPIO */
}
static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -473,9 +418,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
/* each packet contains:
* - header 2 bytes
- * - RG line
+ * - RGRG line
* - 4 bytes
- * - GB line
+ * - GBGB line
* - 4 bytes
*/
gspca_frame_add(gspca_dev, packet_type0,
@@ -484,10 +429,6 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
frame, data + gspca_dev->width + 6, gspca_dev->width);
}
-static void setcontrast(struct gspca_dev *gspca_dev)
-{
-}
-
static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
{
struct sd *sd = (struct sd *) gspca_dev;
@@ -506,24 +447,6 @@ static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
return 0;
}
-static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- sd->contrast = val;
- if (gspca_dev->streaming)
- setcontrast(gspca_dev);
- return 0;
-}
-
-static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
-{
- struct sd *sd = (struct sd *) gspca_dev;
-
- *val = sd->contrast;
- return 0;
-}
-
/* sub-driver description */
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
@@ -570,8 +493,10 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 0525ea51a6d..4c802fb12cd 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -37,18 +37,21 @@ struct sd {
__u8 lightfreq;
__u8 sharpness;
+ u8 image_offset;
+
char bridge;
#define BRIDGE_VC0321 0
#define BRIDGE_VC0323 1
char sensor;
#define SENSOR_HV7131R 0
#define SENSOR_MI0360 1
-#define SENSOR_MI1320 2
-#define SENSOR_MI1310_SOC 3
-#define SENSOR_OV7660 4
-#define SENSOR_OV7670 5
-#define SENSOR_PO1200 6
-#define SENSOR_PO3130NC 7
+#define SENSOR_MI1310_SOC 2
+#define SENSOR_MI1320 3
+#define SENSOR_MI1320_SOC 4
+#define SENSOR_OV7660 5
+#define SENSOR_OV7670 6
+#define SENSOR_PO1200 7
+#define SENSOR_PO3130NC 8
};
/* V4L2 controls supported by the driver */
@@ -149,8 +152,50 @@ static const struct v4l2_pix_format vc0323_mode[] = {
.sizeimage = 640 * 480 * 3 / 8 + 590,
.colorspace = V4L2_COLORSPACE_JPEG,
.priv = 0},
+ {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, /* mi13x0_soc only */
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 2},
+};
+static const struct v4l2_pix_format bi_mode[] = {
+/*fixme: jeg does not work
+ {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 5},
+*/
+ {320, 240, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 320,
+ .sizeimage = 320 * 240 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 4},
+/*
+ {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 3 / 8 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 3},
+*/
+ {640, 480, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 640,
+ .sizeimage = 640 * 480 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 2},
+/*
+ {1280, 1024, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 1 / 4 + 590,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ .priv = 1},
+*/
+ {1280, 1024, V4L2_PIX_FMT_YVYU, V4L2_FIELD_NONE,
+ .bytesperline = 1280,
+ .sizeimage = 1280 * 1024 * 2,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ .priv = 0},
};
-
static const struct v4l2_pix_format svga_mode[] = {
{800, 600, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
.bytesperline = 800,
@@ -400,92 +445,208 @@ static const __u8 mi0360_initQVGA_JPG[][4] = {
static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xb0, 0x03, 0x19, 0xcc},
{0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc},
- {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
{0xb3, 0x08, 0x01, 0xcc},
{0xb3, 0x09, 0x0c, 0xcc},
{0xb3, 0x34, 0x02, 0xcc},
{0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc},
{0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
{0xb3, 0x20, 0x00, 0xcc},
{0xb3, 0x21, 0x00, 0xcc},
- {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
{0xb3, 0x14, 0x00, 0xcc},
{0xb3, 0x15, 0x00, 0xcc},
- {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc},
- {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc},
- {0xbc, 0x00, 0xd0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc},
- {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb},
- {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
{0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
{0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb},
- {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb},
- {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb},
- {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb},
- {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb},
- {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb},
- {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
{0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb},
- {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb},
- {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb},
- {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb},
- {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb},
- {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb},
- {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb},
- {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb},
- {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc},
- {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
{0xb6, 0x00, 0x00, 0xcc},
{0xb6, 0x03, 0x02, 0xcc},
{0xb6, 0x02, 0x80, 0xcc},
{0xb6, 0x05, 0x01, 0xcc},
{0xb6, 0x04, 0xe0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc},
- {0xb6, 0x13, 0x25, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
{0xb6, 0x18, 0x02, 0xcc},
{0xb6, 0x17, 0x58, 0xcc},
{0xb6, 0x16, 0x00, 0xcc},
{0xb6, 0x22, 0x12, 0xcc},
{0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
{0xbf, 0xc0, 0x39, 0xcc},
{0xbf, 0xc1, 0x04, 0xcc},
- {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {},
+};
+static const __u8 mi1310_socinitQVGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x03, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x13, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xb8, 0x35, 0x00, 0xcc},
+ {0xb8, 0x36, 0x00, 0xcc},
+ {0xb8, 0x37, 0x00, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x0f, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc},
+ {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc},
+ {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0x78, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc},
+ {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x0a, 0xcc},
+ {0xb9, 0x14, 0x0a, 0xcc},
+ {0xb9, 0x15, 0x0a, 0xcc},
+ {0xb9, 0x16, 0x0a, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x0f, 0xcc},
+ {0xb9, 0x1a, 0x0f, 0xcc},
+ {0xb9, 0x1b, 0x0f, 0xcc},
+ {0xb9, 0x1c, 0x0f, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
{0xbc, 0x02, 0x18, 0xcc},
{0xbc, 0x03, 0x50, 0xcc},
{0xbc, 0x04, 0x18, 0xcc},
@@ -496,131 +657,123 @@ static const __u8 mi1310_socinitVGA_JPG[][4] = {
{0xbc, 0x0a, 0x10, 0xcc},
{0xbc, 0x0b, 0x00, 0xcc},
{0xbc, 0x0c, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb},
- {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb},
- {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb},
- {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb},
- {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb},
- {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb},
- {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb},
- {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb},
- {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb},
- {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb},
- {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb},
- {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb},
- {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb},
- {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb},
- {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb},
- {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb},
- {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb},
- {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb},
- {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb},
- {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd},
- {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb},
- {0x34, 0x0c, 0x50, 0xbb},
{0xb3, 0x01, 0x41, 0xcc},
- {0xf0, 0x00, 0x00, 0xbb},
{0x03, 0x03, 0xc0, 0xbb},
+ {0x06, 0x00, 0x10, 0xbb},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
{},
};
-static const __u8 mi1310_socinitQVGA_JPG[][4] = {
- {0xb0, 0x03, 0x19, 0xcc}, {0xb0, 0x04, 0x02, 0xcc},
- {0xb3, 0x00, 0x64, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb3, 0x05, 0x00, 0xcc}, {0xb3, 0x06, 0x00, 0xcc},
- {0xb3, 0x08, 0x01, 0xcc}, {0xb3, 0x09, 0x0c, 0xcc},
- {0xb3, 0x34, 0x02, 0xcc}, {0xb3, 0x35, 0xdd, 0xcc},
- {0xb3, 0x02, 0x00, 0xcc}, {0xb3, 0x03, 0x0a, 0xcc},
- {0xb3, 0x04, 0x05, 0xcc}, {0xb3, 0x20, 0x00, 0xcc},
- {0xb3, 0x21, 0x00, 0xcc}, {0xb3, 0x22, 0x03, 0xcc},
- {0xb3, 0x23, 0xc0, 0xcc}, {0xb3, 0x14, 0x00, 0xcc},
- {0xb3, 0x15, 0x00, 0xcc}, {0xb3, 0x16, 0x04, 0xcc},
- {0xb3, 0x17, 0xff, 0xcc}, {0xb3, 0x00, 0x65, 0xcc},
- {0xb8, 0x00, 0x00, 0xcc}, {0xbc, 0x00, 0xf0, 0xcc},
- {0xbc, 0x01, 0x01, 0xcc}, {0xf0, 0x00, 0x02, 0xbb},
- {0xc8, 0x9f, 0x0b, 0xbb}, {0x5b, 0x00, 0x01, 0xbb},
- {0x2f, 0xde, 0x20, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x20, 0x03, 0x02, 0xbb}, {0xf0, 0x00, 0x01, 0xbb},
- {0x05, 0x00, 0x07, 0xbb}, {0x34, 0x00, 0x00, 0xbb},
- {0x35, 0xff, 0x00, 0xbb}, {0xdc, 0x07, 0x02, 0xbb},
- {0xdd, 0x3c, 0x18, 0xbb}, {0xde, 0x92, 0x6d, 0xbb},
- {0xdf, 0xcd, 0xb1, 0xbb}, {0xe0, 0xff, 0xe7, 0xbb},
- {0x06, 0xf0, 0x0d, 0xbb}, {0x06, 0x70, 0x0e, 0xbb},
- {0x4c, 0x00, 0x01, 0xbb}, {0x4d, 0x00, 0x01, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x2e, 0x0c, 0x55, 0xbb},
- {0x21, 0xb6, 0x6e, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc1, 0xbb}, {0xf0, 0x00, 0x00, 0xbb},
- {0x07, 0x00, 0x84, 0xbb}, {0x08, 0x02, 0x4a, 0xbb},
- {0x05, 0x01, 0x10, 0xbb}, {0x06, 0x00, 0x39, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x58, 0x02, 0x67, 0xbb},
- {0x57, 0x02, 0x00, 0xbb}, {0x5a, 0x02, 0x67, 0xbb},
- {0x59, 0x02, 0x00, 0xbb}, {0x5c, 0x12, 0x0d, 0xbb},
- {0x5d, 0x16, 0x11, 0xbb}, {0x39, 0x06, 0x18, 0xbb},
- {0x3a, 0x06, 0x18, 0xbb}, {0x3b, 0x06, 0x18, 0xbb},
- {0x3c, 0x06, 0x18, 0xbb}, {0x64, 0x7b, 0x5b, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x36, 0x30, 0x10, 0xbb},
- {0x37, 0x00, 0xc0, 0xbb}, {0xbc, 0x0e, 0x00, 0xcc},
- {0xbc, 0x0f, 0x05, 0xcc}, {0xbc, 0x10, 0xc0, 0xcc},
- {0xbc, 0x11, 0x03, 0xcc}, {0xb6, 0x00, 0x00, 0xcc},
- {0xb6, 0x03, 0x01, 0xcc}, {0xb6, 0x02, 0x40, 0xcc},
- {0xb6, 0x05, 0x00, 0xcc}, {0xb6, 0x04, 0xf0, 0xcc},
- {0xb6, 0x12, 0xf8, 0xcc}, {0xb6, 0x13, 0x25, 0xcc},
- {0xb6, 0x18, 0x00, 0xcc}, {0xb6, 0x17, 0x96, 0xcc},
- {0xb6, 0x16, 0x00, 0xcc}, {0xb6, 0x22, 0x12, 0xcc},
- {0xb6, 0x23, 0x0b, 0xcc}, {0xbf, 0xc0, 0x39, 0xcc},
- {0xbf, 0xc1, 0x04, 0xcc}, {0xbf, 0xcc, 0x00, 0xcc},
- {0xb3, 0x5c, 0x01, 0xcc}, {0xf0, 0x00, 0x01, 0xbb},
- {0x80, 0x00, 0x03, 0xbb}, {0x81, 0xc7, 0x14, 0xbb},
- {0x82, 0xeb, 0xe8, 0xbb}, {0x83, 0xfe, 0xf4, 0xbb},
- {0x84, 0xcd, 0x10, 0xbb}, {0x85, 0xf3, 0xee, 0xbb},
- {0x86, 0xff, 0xf1, 0xbb}, {0x87, 0xcd, 0x10, 0xbb},
- {0x88, 0xf3, 0xee, 0xbb}, {0x89, 0x01, 0xf1, 0xbb},
- {0x8a, 0xe5, 0x17, 0xbb}, {0x8b, 0xe8, 0xe2, 0xbb},
- {0x8c, 0xf7, 0xed, 0xbb}, {0x8d, 0x00, 0xff, 0xbb},
- {0x8e, 0xec, 0x10, 0xbb}, {0x8f, 0xf0, 0xed, 0xbb},
- {0x90, 0xf9, 0xf2, 0xbb}, {0x91, 0x00, 0x00, 0xbb},
- {0x92, 0xe9, 0x0d, 0xbb}, {0x93, 0xf4, 0xf2, 0xbb},
- {0x94, 0xfb, 0xf5, 0xbb}, {0x95, 0x00, 0xff, 0xbb},
- {0xb6, 0x0f, 0x08, 0xbb}, {0xb7, 0x3d, 0x16, 0xbb},
- {0xb8, 0x0c, 0x04, 0xbb}, {0xb9, 0x1c, 0x07, 0xbb},
- {0xba, 0x0a, 0x03, 0xbb}, {0xbb, 0x1b, 0x09, 0xbb},
- {0xbc, 0x17, 0x0d, 0xbb}, {0xbd, 0x23, 0x1d, 0xbb},
- {0xbe, 0x00, 0x28, 0xbb}, {0xbf, 0x11, 0x09, 0xbb},
- {0xc0, 0x16, 0x15, 0xbb}, {0xc1, 0x00, 0x1b, 0xbb},
- {0xc2, 0x0e, 0x07, 0xbb}, {0xc3, 0x14, 0x10, 0xbb},
- {0xc4, 0x00, 0x17, 0xbb}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x01, 0xbb}, {0x06, 0xf4, 0x8e, 0xbb},
- {0x00, 0x00, 0x50, 0xdd}, {0x06, 0x74, 0x8e, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x24, 0x50, 0x20, 0xbb},
- {0xf0, 0x00, 0x02, 0xbb}, {0x34, 0x0c, 0x50, 0xbb},
- {0xb3, 0x01, 0x41, 0xcc}, {0xf0, 0x00, 0x00, 0xbb},
- {0x03, 0x03, 0xc0, 0xbb},
- {},
+static const u8 mi1310_soc_InitSXGA_JPG[][4] = {
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0xb3, 0x00, 0x24, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xdd, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x0d, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb8, 0x01, 0x7d, 0xcc},
+ {0xb8, 0x81, 0x09, 0xcc},
+ {0xb8, 0x27, 0x20, 0xcc},
+ {0xb8, 0x26, 0x80, 0xcc},
+ {0xb8, 0x06, 0x00, 0xcc},
+ {0xb8, 0x07, 0x05, 0xcc},
+ {0xb8, 0x08, 0x00, 0xcc},
+ {0xb8, 0x09, 0x04, 0xcc},
+ {0xb3, 0x00, 0x25, 0xcc},
+ {0xb8, 0x00, 0x11, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xb8, 0x81, 0x01, 0xcc},
+ {0xb8, 0x2c, 0x5a, 0xcc},
+ {0xb8, 0x2d, 0xff, 0xcc},
+ {0xb8, 0x2e, 0xee, 0xcc},
+ {0xb8, 0x2f, 0xfb, 0xcc},
+ {0xb8, 0x30, 0x52, 0xcc},
+ {0xb8, 0x31, 0xf8, 0xcc},
+ {0xb8, 0x32, 0xf1, 0xcc},
+ {0xb8, 0x33, 0xff, 0xcc},
+ {0xb8, 0x34, 0x54, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x0d, 0x00, 0x09, 0xbb},
+ {0x0d, 0x00, 0x08, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x06, 0x00, 0x14, 0xbb},
+ {0x3a, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x9b, 0x10, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x01, 0x00, 0xdd},
+ {0x2b, 0x00, 0x28, 0xbb},
+ {0x2c, 0x00, 0x30, 0xbb},
+ {0x2d, 0x00, 0x30, 0xbb},
+ {0x2e, 0x00, 0x28, 0xbb},
+ {0x41, 0x00, 0xd7, 0xbb},
+ {0x09, 0x02, 0x3a, 0xbb},
+ {0x0c, 0x00, 0x00, 0xbb},
+ {0x20, 0x00, 0x00, 0xbb},
+ {0x05, 0x00, 0x8c, 0xbb},
+ {0x06, 0x00, 0x32, 0xbb},
+ {0x07, 0x00, 0xc6, 0xbb},
+ {0x08, 0x00, 0x19, 0xbb},
+ {0x24, 0x80, 0x6f, 0xbb},
+ {0xc8, 0x00, 0x0f, 0xbb},
+ {0x20, 0x00, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc},
+ {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc},
+ {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc},
+ {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xb3, 0x02, 0x02, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x10, 0xcc},
+ {0xb9, 0x12, 0x00, 0xcc},
+ {0xb9, 0x13, 0x14, 0xcc},
+ {0xb9, 0x14, 0x14, 0xcc},
+ {0xb9, 0x15, 0x14, 0xcc},
+ {0xb9, 0x16, 0x14, 0xcc},
+ {0xb9, 0x18, 0x00, 0xcc},
+ {0xb9, 0x19, 0x1e, 0xcc},
+ {0xb9, 0x1a, 0x1e, 0xcc},
+ {0xb9, 0x1b, 0x1e, 0xcc},
+ {0xb9, 0x1c, 0x1e, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xb8, 0x8e, 0x00, 0xcc},
+ {0xb8, 0x8f, 0xff, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb8, 0x0c, 0x20, 0xcc},
+ {0xb8, 0x0d, 0x70, 0xcc},
+ {0xb6, 0x13, 0x13, 0xcc},
+ {0x2f, 0x00, 0xC0, 0xbb},
+ {0xb8, 0xa0, 0x12, 0xcc},
+ {}
};
static const __u8 mi1320_gamma[17] = {
@@ -778,6 +931,722 @@ static const __u8 mi1320_initQVGA_data[][4] = {
{}
};
+static const u8 mi1320_soc_InitVGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x02, 0xcc},
+ {0xb6, 0x02, 0x80, 0xcc},
+ {0xb6, 0x05, 0x01, 0xcc},
+ {0xb6, 0x04, 0xe0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x05, 0xcc},
+ {0xb6, 0x18, 0x02, 0xcc},
+ {0xb6, 0x17, 0x58, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitQVGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitQVGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x01, 0xcc},
+ {0xb3, 0x23, 0xe0, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x02, 0xcc},
+ {0xb3, 0x17, 0x7f, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb8, 0x00, 0x00, 0xcc},
+ {0xbc, 0x00, 0xd1, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0xc8, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x10, 0xdd},
+ {0x07, 0x00, 0xe0, 0xbb},
+ {0x08, 0x00, 0x0b, 0xbb},
+ {0x21, 0x00, 0x0c, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x01, 0xcc},
+ {0xb6, 0x02, 0x40, 0xcc},
+ {0xb6, 0x05, 0x00, 0xcc},
+ {0xb6, 0x04, 0xf0, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x05, 0xcc},
+ {0xb6, 0x18, 0x00, 0xcc},
+ {0xb6, 0x17, 0x96, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xbc, 0x02, 0x18, 0xcc},
+ {0xbc, 0x03, 0x50, 0xcc},
+ {0xbc, 0x04, 0x18, 0xcc},
+ {0xbc, 0x05, 0x00, 0xcc},
+ {0xbc, 0x06, 0x00, 0xcc},
+ {0xbc, 0x08, 0x30, 0xcc},
+ {0xbc, 0x09, 0x40, 0xcc},
+ {0xbc, 0x0a, 0x10, 0xcc},
+ {0xbc, 0x0b, 0x00, 0xcc},
+ {0xbc, 0x0c, 0x00, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {}
+};
+static const u8 mi1320_soc_InitSXGA_JPG[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0xb0, 0x04, 0x02, 0xcc},
+ {0x00, 0x00, 0x33, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x00, 0xcc},
+ {0xb3, 0x06, 0x00, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x5b, 0x00, 0x01, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xb6, 0x00, 0x00, 0xcc},
+ {0xb6, 0x03, 0x05, 0xcc},
+ {0xb6, 0x02, 0x00, 0xcc},
+ {0xb6, 0x05, 0x04, 0xcc},
+ {0xb6, 0x04, 0x00, 0xcc},
+ {0xb6, 0x12, 0xf8, 0xcc},
+ {0xb6, 0x13, 0x29, 0xcc},
+ {0xb6, 0x18, 0x0a, 0xcc},
+ {0xb6, 0x17, 0x00, 0xcc},
+ {0xb6, 0x16, 0x00, 0xcc},
+ {0xb6, 0x22, 0x12, 0xcc},
+ {0xb6, 0x23, 0x0b, 0xcc},
+ {0xbf, 0xc0, 0x39, 0xcc},
+ {0xbf, 0xc1, 0x04, 0xcc},
+ {0xbf, 0xcc, 0x00, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x13, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x00, 0x85, 0xbb},
+ {0x08, 0x00, 0x27, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0x0d, 0xbb},
+ {0x3a, 0x06, 0x1b, 0xbb},
+ {0x3b, 0x00, 0x95, 0xbb},
+ {0x3c, 0x04, 0xdb, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb},
+ {0x58, 0x02, 0x66, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0x5a, 0x01, 0x33, 0xbb},
+ {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb},
+ {0x64, 0x5e, 0x1c, 0xbb},
+ {0x2f, 0x90, 0x00, 0xbb},
+ {}
+};
+static const u8 mi1320_soc_InitSXGA[][4] = {
+ {0xb3, 0x01, 0x01, 0xcc},
+ {0xb0, 0x03, 0x19, 0xcc},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xb3, 0x00, 0x64, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xb3, 0x05, 0x01, 0xcc},
+ {0xb3, 0x06, 0x01, 0xcc},
+ {0xb3, 0x08, 0x01, 0xcc},
+ {0xb3, 0x09, 0x0c, 0xcc},
+ {0xb3, 0x34, 0x02, 0xcc},
+ {0xb3, 0x35, 0xc8, 0xcc},
+ {0xb3, 0x02, 0x00, 0xcc},
+ {0xb3, 0x03, 0x0a, 0xcc},
+ {0xb3, 0x04, 0x05, 0xcc},
+ {0xb3, 0x20, 0x00, 0xcc},
+ {0xb3, 0x21, 0x00, 0xcc},
+ {0xb3, 0x22, 0x04, 0xcc},
+ {0xb3, 0x23, 0x00, 0xcc},
+ {0xb3, 0x14, 0x00, 0xcc},
+ {0xb3, 0x15, 0x00, 0xcc},
+ {0xb3, 0x16, 0x04, 0xcc},
+ {0xb3, 0x17, 0xff, 0xcc},
+ {0xb3, 0x00, 0x67, 0xcc},
+ {0xbc, 0x00, 0x71, 0xcc},
+ {0xbc, 0x01, 0x01, 0xcc},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0xc8, 0x9f, 0x0b, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0x5b, 0x00, 0x01, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x00, 0x00, 0x30, 0xdd},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x00, 0x00, 0x20, 0xdd},
+ {0xbf, 0xc0, 0x26, 0xcc},
+ {0xbf, 0xc1, 0x02, 0xcc},
+ {0xbf, 0xcc, 0x04, 0xcc},
+ {0xb3, 0x01, 0x41, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x78, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x01, 0x42, 0xbb},
+ {0x08, 0x00, 0x11, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0xca, 0xbb},
+ {0x3a, 0x06, 0x80, 0xbb},
+ {0x3b, 0x01, 0x52, 0xbb},
+ {0x3c, 0x05, 0x40, 0xbb},
+ {0x57, 0x01, 0x9c, 0xbb},
+ {0x58, 0x01, 0xee, 0xbb},
+ {0x59, 0x00, 0xf0, 0xbb},
+ {0x5a, 0x01, 0x20, 0xbb},
+ {0x5c, 0x1d, 0x17, 0xbb},
+ {0x5d, 0x22, 0x1c, 0xbb},
+ {0x64, 0x1e, 0x1c, 0xbb},
+ {0x5b, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x22, 0xa0, 0x78, 0xbb},
+ {0x23, 0xa0, 0x78, 0xbb},
+ {0x24, 0x7f, 0x00, 0xbb},
+ {0x28, 0xea, 0x02, 0xbb},
+ {0x29, 0x86, 0x7a, 0xbb},
+ {0x5e, 0x52, 0x4c, 0xbb},
+ {0x5f, 0x20, 0x24, 0xbb},
+ {0x60, 0x00, 0x02, 0xbb},
+ {0x02, 0x00, 0xee, 0xbb},
+ {0x03, 0x39, 0x23, 0xbb},
+ {0x04, 0x07, 0x24, 0xbb},
+ {0x09, 0x00, 0xc0, 0xbb},
+ {0x0a, 0x00, 0x79, 0xbb},
+ {0x0b, 0x00, 0x04, 0xbb},
+ {0x0c, 0x00, 0x5c, 0xbb},
+ {0x0d, 0x00, 0xd9, 0xbb},
+ {0x0e, 0x00, 0x53, 0xbb},
+ {0x0f, 0x00, 0x21, 0xbb},
+ {0x10, 0x00, 0xa4, 0xbb},
+ {0x11, 0x00, 0xe5, 0xbb},
+ {0x15, 0x00, 0x00, 0xbb},
+ {0x16, 0x00, 0x00, 0xbb},
+ {0x17, 0x00, 0x00, 0xbb},
+ {0x18, 0x00, 0x00, 0xbb},
+ {0x19, 0x00, 0x00, 0xbb},
+ {0x1a, 0x00, 0x00, 0xbb},
+ {0x1b, 0x00, 0x00, 0xbb},
+ {0x1c, 0x00, 0x00, 0xbb},
+ {0x1d, 0x00, 0x00, 0xbb},
+ {0x1e, 0x00, 0x00, 0xbb},
+ {0xf0, 0x00, 0x01, 0xbb},
+ {0x06, 0xe0, 0x0e, 0xbb},
+ {0x06, 0x60, 0x0e, 0xbb},
+ {0xb3, 0x5c, 0x01, 0xcc},
+ {0xf0, 0x00, 0x00, 0xbb},
+ {0x05, 0x01, 0x13, 0xbb},
+ {0x06, 0x00, 0x11, 0xbb},
+ {0x07, 0x00, 0x85, 0xbb},
+ {0x08, 0x00, 0x27, 0xbb},
+ {0x20, 0x01, 0x03, 0xbb},
+ {0x21, 0x80, 0x00, 0xbb},
+ {0x22, 0x0d, 0x0f, 0xbb},
+ {0x24, 0x80, 0x00, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0xf0, 0x00, 0x02, 0xbb},
+ {0x39, 0x03, 0x0d, 0xbb},
+ {0x3a, 0x06, 0x1b, 0xbb},
+ {0x3b, 0x00, 0x95, 0xbb},
+ {0x3c, 0x04, 0xdb, 0xbb},
+ {0x57, 0x02, 0x00, 0xbb},
+ {0x58, 0x02, 0x66, 0xbb},
+ {0x59, 0x00, 0xff, 0xbb},
+ {0x5a, 0x01, 0x33, 0xbb},
+ {0x5c, 0x12, 0x0d, 0xbb},
+ {0x5d, 0x16, 0x11, 0xbb},
+ {0x64, 0x5e, 0x1c, 0xbb},
+ {}
+};
static const __u8 po3130_gamma[17] = {
0x00, 0x13, 0x38, 0x59, 0x79, 0x92, 0xa7, 0xb9, 0xc8,
0xd4, 0xdf, 0xe7, 0xee, 0xf4, 0xf9, 0xfc, 0xff
@@ -1764,26 +2633,43 @@ static const __u8 po1200_initVGA_data[][4] = {
};
struct sensor_info {
- int sensorId;
- __u8 I2cAdd;
- __u8 IdAdd;
- __u16 VpId;
- __u8 m1;
- __u8 m2;
- __u8 op;
- };
+ s8 sensorId;
+ u8 I2cAdd;
+ u8 IdAdd;
+ u16 VpId;
+ u8 m1;
+ u8 m2;
+ u8 op;
+};
static const struct sensor_info sensor_info_data[] = {
/* sensorId, I2cAdd, IdAdd, VpId, m1, m2, op */
- {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
- {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+ {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05},
+ {-1, 0x80 | 0x20, 0x82, 0x0000, 0x24, 0x25, 0x01},
+/* (tested in vc032x_probe_sensor) */
+/* {-1, 0x80 | 0x20, 0x83, 0x0000, 0x24, 0x25, 0x01}, */
{SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x3130, 0x24, 0x25, 0x01},
- {SENSOR_MI1320, 0x80 | 0xc8, 0x00, 0x148c, 0x64, 0x65, 0x01},
- {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
{SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x143a, 0x24, 0x25, 0x01},
/* (tested in vc032x_probe_sensor) */
/* {SENSOR_MI0360, 0x80 | 0x5d, 0x00, 0x8243, 0x24, 0x25, 0x01}, */
+ {SENSOR_HV7131R, 0x80 | 0x11, 0x00, 0x0209, 0x24, 0x25, 0x01},
+ {-1, 0x80 | 0x21, 0x0a, 0x0000, 0x21, 0x20, 0x05},
+ {-1, 0x80 | 0x40, 0x00, 0x0000, 0x20, 0x22, 0x05},
+ {SENSOR_OV7660, 0x80 | 0x21, 0x0a, 0x7660, 0x26, 0x26, 0x05},
+/* {SENSOR_PO3130NC, 0x80 | 0x76, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+ {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+/* {SENSOR_MI1310_SOC, 0x80 | 0x5d, 0x00, 0x0000, 0x24, 0x25, 0x01}, */
+/* {-1, 0x80 | 0x30, 0x0a, 0x0000, 0x25, 0x24, 0x05}, */
+ {-1, 0x80 | 0x11, 0x39, 0x0000, 0x24, 0x25, 0x01},
{SENSOR_PO1200, 0x80 | 0x5c, 0x00, 0x1200, 0x67, 0x67, 0x01},
+ {-1, 0x80 | 0x2d, 0x00, 0x0000, 0x65, 0x67, 0x01},
+ {-1, 0x80 | 0x6e, 0x00, 0x0000, 0x24, 0x25, 0x01},
+ {-1, 0x80 | 0x56, 0x01, 0x0000, 0x64, 0x67, 0x01},
+ {SENSOR_MI1320_SOC, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x67, 0x01},
+/*fixme: previously detected?*/
+ {SENSOR_MI1320, 0x80 | 0x48, 0x00, 0x148c, 0x64, 0x65, 0x01},
+/*fixme: not in the ms-win probe - may be found before?*/
+ {SENSOR_OV7670, 0x80 | 0x21, 0x0a, 0x7673, 0x66, 0x67, 0x05},
};
/* read 'len' bytes in gspca_dev->usb_buf */
@@ -1814,51 +2700,49 @@ static void reg_w(struct usb_device *dev,
500);
}
-static void read_sensor_register(struct gspca_dev *gspca_dev,
- __u16 address, __u16 *value)
+static u16 read_sensor_register(struct gspca_dev *gspca_dev,
+ u16 address)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 ldata, mdata, hdata;
+ u8 ldata, mdata, hdata;
int retry = 50;
- *value = 0;
-
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
- /*PDEBUG(D_PROBE, " I2c Bus Busy Wait 0x%02X ", tmpvalue); */
if (!(gspca_dev->usb_buf[0] & 0x02)) {
- PDEBUG(D_ERR, "I2c Bus Busy Wait %d",
- gspca_dev->usb_buf[0] & 0x02);
- return;
+ PDEBUG(D_ERR, "I2c Bus Busy Wait %02x",
+ gspca_dev->usb_buf[0]);
+ return 0;
}
reg_w(dev, 0xa0, address, 0xb33a);
reg_w(dev, 0xa0, 0x02, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- while (retry-- && gspca_dev->usb_buf[0]) {
+ do {
reg_r(gspca_dev, 0xa1, 0xb33b, 1);
-/* PDEBUG(D_PROBE, "Read again 0xb33b %d", tmpvalue); */
- msleep(1);
- }
+ if (gspca_dev->usb_buf[0] == 0x00)
+ break;
+ msleep(40);
+ } while (--retry >= 0);
+
reg_r(gspca_dev, 0xa1, 0xb33e, 1);
ldata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33d, 1);
mdata = gspca_dev->usb_buf[0];
reg_r(gspca_dev, 0xa1, 0xb33c, 1);
hdata = gspca_dev->usb_buf[0];
- PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
- hdata, mdata, ldata);
+ if (hdata != 0 && mdata != 0 && ldata != 0)
+ PDEBUG(D_PROBE, "Read Sensor %02x%02x %02x",
+ hdata, mdata, ldata);
reg_r(gspca_dev, 0xa1, 0xb334, 1);
if (gspca_dev->usb_buf[0] == 0x02)
- *value = (hdata << 8) + mdata;
- else
- *value = hdata;
+ return (hdata << 8) + mdata;
+ return hdata;
}
static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
int i;
- __u16 value;
+ u16 value;
const struct sensor_info *ptsensor_info;
reg_r(gspca_dev, 0xa1, 0xbfcf, 1);
@@ -1872,48 +2756,51 @@ static int vc032x_probe_sensor(struct gspca_dev *gspca_dev)
reg_w(dev, 0xa0, 0x0c, 0xb309);
reg_w(dev, 0xa0, ptsensor_info->I2cAdd, 0xb335);
reg_w(dev, 0xa0, ptsensor_info->op, 0xb301);
- read_sensor_register(gspca_dev, ptsensor_info->IdAdd, &value);
- if (value == ptsensor_info->VpId)
- return ptsensor_info->sensorId;
-
- /* special case for MI0360 */
- if (ptsensor_info->sensorId == SENSOR_MI1310_SOC
- && value == 0x8243)
- return SENSOR_MI0360;
+ value = read_sensor_register(gspca_dev, ptsensor_info->IdAdd);
+ if (value == 0 && ptsensor_info->IdAdd == 0x82)
+ value = read_sensor_register(gspca_dev, 0x83);
+ if (value != 0) {
+ PDEBUG(D_ERR|D_PROBE, "Sensor ID %04x (%d)",
+ value, i);
+ if (value == ptsensor_info->VpId)
+ return ptsensor_info->sensorId;
+
+ switch (value) {
+ case 0x7673:
+ return SENSOR_OV7670;
+ case 0x8243:
+ return SENSOR_MI0360;
+ }
+/*fixme: should return here*/
+ }
}
return -1;
}
-static __u8 i2c_write(struct gspca_dev *gspca_dev,
- __u8 reg, const __u8 *val, __u8 size)
+static void i2c_write(struct gspca_dev *gspca_dev,
+ u8 reg, const u8 *val,
+ u8 size) /* 1 or 2 */
{
struct usb_device *dev = gspca_dev->dev;
+ int retry;
- if (size > 3 || size < 1)
- return -EINVAL;
reg_r(gspca_dev, 0xa1, 0xb33f, 1);
+/*fixme:should check if (!(gspca_dev->usb_buf[0] & 0x02)) error*/
reg_w(dev, 0xa0, size, 0xb334);
reg_w(dev, 0xa0, reg, 0xb33a);
- switch (size) {
- case 1:
- reg_w(dev, 0xa0, val[0], 0xb336);
- break;
- case 2:
- reg_w(dev, 0xa0, val[0], 0xb336);
+ reg_w(dev, 0xa0, val[0], 0xb336);
+ if (size > 1)
reg_w(dev, 0xa0, val[1], 0xb337);
- break;
- case 3:
- reg_w(dev, 0xa0, val[0], 0xb336);
- reg_w(dev, 0xa0, val[1], 0xb337);
- reg_w(dev, 0xa0, val[2], 0xb338);
- break;
- default:
- reg_w(dev, 0xa0, 0x01, 0xb334);
- return -EINVAL;
- }
reg_w(dev, 0xa0, 0x01, 0xb339);
- reg_r(gspca_dev, 0xa1, 0xb33b, 1);
- return gspca_dev->usb_buf[0] == 0;
+ retry = 4;
+ do {
+ reg_r(gspca_dev, 0xa1, 0xb33b, 1);
+ if (gspca_dev->usb_buf[0] == 0)
+ break;
+ msleep(20);
+ } while (--retry > 0);
+ if (retry <= 0)
+ PDEBUG(D_ERR, "i2c_write failed");
}
static void put_tab_to_reg(struct gspca_dev *gspca_dev,
@@ -1938,7 +2825,7 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
return;
case 0xcc: /* normal write */
reg_w(dev, 0xa0, data[i][2],
- ((data[i][0])<<8) | data[i][1]);
+ (data[i][0]) << 8 | data[i][1]);
break;
case 0xaa: /* i2c op */
i2c_write(gspca_dev, data[i][1], &data[i][2], 1);
@@ -1955,19 +2842,6 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
/*not reached*/
}
-/*
- "GammaT"=hex:04,17,31,4f,6a,83,99,ad,bf,ce,da,e5,ee,f5,fb,ff,ff
- "MatrixT"=hex:60,f9,e5,e7,50,05,f3,e6,66
- */
-
-static void vc0321_reset(struct gspca_dev *gspca_dev)
-{
- reg_w(gspca_dev->dev, 0xa0, 0x00, 0xb04d);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb301);
- msleep(100);
- reg_w(gspca_dev->dev, 0xa0, 0x01, 0xb003);
- msleep(100);
-}
/* this function is called at probe time */
static int sd_config(struct gspca_dev *gspca_dev,
@@ -1979,10 +2853,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
cam = &gspca_dev->cam;
- cam->epaddr = 0x02;
sd->bridge = id->driver_info;
-
- vc0321_reset(gspca_dev);
sensor = vc032x_probe_sensor(gspca_dev);
switch (sensor) {
case -1:
@@ -2001,6 +2872,9 @@ static int sd_config(struct gspca_dev *gspca_dev,
case SENSOR_MI1320:
PDEBUG(D_PROBE, "Find Sensor MI1320");
break;
+ case SENSOR_MI1320_SOC:
+ PDEBUG(D_PROBE, "Find Sensor MI1320_SOC");
+ break;
case SENSOR_OV7660:
PDEBUG(D_PROBE, "Find Sensor OV7660");
break;
@@ -2020,12 +2894,23 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = vc0321_mode;
cam->nmodes = ARRAY_SIZE(vc0321_mode);
} else {
- if (sensor != SENSOR_PO1200) {
- cam->cam_mode = vc0323_mode;
- cam->nmodes = ARRAY_SIZE(vc0323_mode);
- } else {
+ switch (sensor) {
+ case SENSOR_PO1200:
cam->cam_mode = svga_mode;
cam->nmodes = ARRAY_SIZE(svga_mode);
+ break;
+ case SENSOR_MI1310_SOC:
+ cam->cam_mode = vc0323_mode;
+ cam->nmodes = ARRAY_SIZE(vc0323_mode);
+ break;
+ case SENSOR_MI1320_SOC:
+ cam->cam_mode = bi_mode;
+ cam->nmodes = ARRAY_SIZE(bi_mode);
+ break;
+ default:
+ cam->cam_mode = vc0323_mode;
+ cam->nmodes = ARRAY_SIZE(vc0323_mode) - 1;
+ break;
}
}
@@ -2061,7 +2946,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
return 0;
}
-/* this function is called at probe and time */
+/* this function is called at probe and resume time */
static int sd_init(struct gspca_dev *gspca_dev)
{
return 0;
@@ -2124,9 +3009,18 @@ static void setsharpness(struct gspca_dev *gspca_dev)
static int sd_start(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ const __u8 (*init)[4];
const __u8 *GammaT = NULL;
const __u8 *MatrixT = NULL;
int mode;
+ static const u8 (*mi1320_soc_init[])[4] = {
+ mi1320_soc_InitSXGA,
+ mi1320_soc_InitSXGA_JPG,
+ mi1320_soc_InitVGA,
+ mi1320_soc_InitVGA_JPG,
+ mi1320_soc_InitQVGA,
+ mi1320_soc_InitQVGA_JPG
+ };
/* Assume start use the good resolution from gspca_dev->mode */
if (sd->bridge == BRIDGE_VC0321) {
@@ -2134,6 +3028,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfed);
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfee);
reg_w(gspca_dev->dev, 0xa0, 0xff, 0xbfef);
+ sd->image_offset = 46;
+ } else {
+ if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].pixelformat
+ == V4L2_PIX_FMT_JPEG)
+ sd->image_offset = 0;
+ else
+ sd->image_offset = 32;
}
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
@@ -2141,115 +3042,87 @@ static int sd_start(struct gspca_dev *gspca_dev)
case SENSOR_HV7131R:
GammaT = hv7131r_gamma;
MatrixT = hv7131r_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, hv7131r_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, hv7131r_initVGA_data);
- }
+ if (mode)
+ init = hv7131r_initQVGA_data; /* 320x240 */
+ else
+ init = hv7131r_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7660:
GammaT = ov7660_gamma;
MatrixT = ov7660_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7660_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7660_initVGA_data);
- }
+ if (mode)
+ init = ov7660_initQVGA_data; /* 320x240 */
+ else
+ init = ov7660_initVGA_data; /* 640x480 */
break;
case SENSOR_OV7670:
/*GammaT = ov7660_gamma; */
/*MatrixT = ov7660_matrix; */
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, ov7670_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, ov7670_initVGA_JPG);
- }
+ if (mode)
+ init = ov7670_initQVGA_JPG; /* 320x240 */
+ else
+ init = ov7670_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI0360:
GammaT = mi1320_gamma;
MatrixT = mi0360_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi0360_initQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi0360_initVGA_JPG);
- }
+ if (mode)
+ init = mi0360_initQVGA_JPG; /* 320x240 */
+ else
+ init = mi0360_initVGA_JPG; /* 640x480 */
break;
case SENSOR_MI1310_SOC:
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1310_socinitQVGA_JPG);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1310_socinitVGA_JPG);
+ GammaT = mi1320_gamma;
+ MatrixT = mi1320_matrix;
+ switch (mode) {
+ case 1:
+ init = mi1310_socinitQVGA_JPG; /* 320x240 */
+ break;
+ case 0:
+ init = mi1310_socinitVGA_JPG; /* 640x480 */
+ break;
+ default:
+ init = mi1310_soc_InitSXGA_JPG; /* 1280x1024 */
+ break;
}
break;
case SENSOR_MI1320:
GammaT = mi1320_gamma;
MatrixT = mi1320_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, mi1320_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, mi1320_initVGA_data);
- }
+ if (mode)
+ init = mi1320_initQVGA_data; /* 320x240 */
+ else
+ init = mi1320_initVGA_data; /* 640x480 */
+ break;
+ case SENSOR_MI1320_SOC:
+ GammaT = mi1320_gamma;
+ MatrixT = mi1320_matrix;
+ init = mi1320_soc_init[mode];
break;
case SENSOR_PO3130NC:
GammaT = po3130_gamma;
MatrixT = po3130_matrix;
- if (mode) {
- /* 320x240 */
- usb_exchange(gspca_dev, po3130_initQVGA_data);
- } else {
- /* 640x480 */
- usb_exchange(gspca_dev, po3130_initVGA_data);
- }
- usb_exchange(gspca_dev, po3130_rundata);
+ if (mode)
+ init = po3130_initQVGA_data; /* 320x240 */
+ else
+ init = po3130_initVGA_data; /* 640x480 */
+ usb_exchange(gspca_dev, init);
+ init = po3130_rundata;
break;
- case SENSOR_PO1200:
+ default:
+/* case SENSOR_PO1200: */
GammaT = po1200_gamma;
MatrixT = po1200_matrix;
- usb_exchange(gspca_dev, po1200_initVGA_data);
+ init = po1200_initVGA_data;
break;
- default:
- PDEBUG(D_PROBE, "Damned !! no sensor found Bye");
- return -EMEDIUMTYPE;
}
+ usb_exchange(gspca_dev, init);
if (GammaT && MatrixT) {
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb84a);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb85b);
put_tab_to_reg(gspca_dev, GammaT, 17, 0xb86c);
put_tab_to_reg(gspca_dev, MatrixT, 9, 0xb82c);
- /* Seem SHARPNESS */
- /*
- reg_w(gspca_dev->dev, 0xa0, 0x80, 0xb80a);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80b);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb80e);
- */
- /* all 0x40 ??? do nothing
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb822);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb823);
- reg_w(gspca_dev->dev, 0xa0, 0x40, 0xb824);
- */
- /* Only works for HV7131R ??
- reg_r (gspca_dev, 0xa1, 0xb881, 1);
- reg_w(gspca_dev->dev, 0xa0, 0xfe01, 0xb881);
- reg_w(gspca_dev->dev, 0xa0, 0x79, 0xb801);
- */
- /* only hv7131r et ov7660
- reg_w(gspca_dev->dev, 0xa0, 0x20, 0xb827);
- reg_w(gspca_dev->dev, 0xa0, 0xff, 0xb826); * ISP_GAIN 80
- reg_w(gspca_dev->dev, 0xa0, 0x23, 0xb800); * ISP CTRL_BAS
- */
/* set the led on 0x0892 0x0896 */
if (sd->sensor != SENSOR_PO1200) {
reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
@@ -2296,12 +3169,8 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
"vc032x header packet found len %d", len);
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
- if (sd->bridge == BRIDGE_VC0321) {
-#define VCHDRSZ 46
- data += VCHDRSZ;
- len -= VCHDRSZ;
-#undef VCHDRSZ
- }
+ data += sd->image_offset;
+ len -= sd->image_offset;
gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
data, len);
return;
@@ -2399,7 +3268,8 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
strcpy((char *) menu->name, "50 Hz");
return 0;
- case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
+ default:
+/* case 2: * V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
strcpy((char *) menu->name, "60 Hz");
return 0;
}
@@ -2424,6 +3294,7 @@ static const struct sd_desc sd_desc = {
/* -- module initialisation -- */
static const __devinitdata struct usb_device_id device_table[] = {
+ {USB_DEVICE(0x041e, 0x405b), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x046d, 0x0892), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0896), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x046d, 0x0897), .driver_info = BRIDGE_VC0321},
@@ -2432,6 +3303,7 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x0ac8, 0x0328), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x0ac8, 0xc001), .driver_info = BRIDGE_VC0321},
{USB_DEVICE(0x0ac8, 0xc002), .driver_info = BRIDGE_VC0321},
+ {USB_DEVICE(0x15b8, 0x6001), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x15b8, 0x6002), .driver_info = BRIDGE_VC0323},
{USB_DEVICE(0x17ef, 0x4802), .driver_info = BRIDGE_VC0323},
{}
@@ -2460,8 +3332,11 @@ static struct usb_driver sd_driver = {
/* -- module insert / remove -- */
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index ec2a53d53fe..4fe01d8b6c8 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -23,6 +23,7 @@
#define MODULE_NAME "zc3xx"
#include "gspca.h"
+#include "jpeg.h"
MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>, "
"Serge A. Suchkov <Serge.A.S@tochka.ru>");
@@ -31,7 +32,7 @@ MODULE_LICENSE("GPL");
static int force_sensor = -1;
-#include "jpeg.h"
+#define QUANT_VAL 1 /* quantization table */
#include "zc3xx-reg.h"
/* specific webcam descriptor */
@@ -44,30 +45,36 @@ struct sd {
__u8 autogain;
__u8 lightfreq;
__u8 sharpness;
+ u8 quality; /* image quality */
+#define QUALITY_MIN 40
+#define QUALITY_MAX 60
+#define QUALITY_DEF 50
- char qindex;
signed char sensor; /* Type of image sensor chip */
/* !! values used in different tables */
-#define SENSOR_CS2102 0
-#define SENSOR_CS2102K 1
-#define SENSOR_GC0305 2
-#define SENSOR_HDCS2020b 3
-#define SENSOR_HV7131B 4
-#define SENSOR_HV7131C 5
-#define SENSOR_ICM105A 6
-#define SENSOR_MC501CB 7
-#define SENSOR_OV7620 8
-/*#define SENSOR_OV7648 8 - same values */
-#define SENSOR_OV7630C 9
-#define SENSOR_PAS106 10
-#define SENSOR_PAS202B 11
-#define SENSOR_PB0330 12
-#define SENSOR_PO2030 13
-#define SENSOR_TAS5130CK 14
-#define SENSOR_TAS5130CXX 15
-#define SENSOR_TAS5130C_VF0250 16
-#define SENSOR_MAX 17
+#define SENSOR_ADCM2700 0
+#define SENSOR_CS2102 1
+#define SENSOR_CS2102K 2
+#define SENSOR_GC0305 3
+#define SENSOR_HDCS2020b 4
+#define SENSOR_HV7131B 5
+#define SENSOR_HV7131C 6
+#define SENSOR_ICM105A 7
+#define SENSOR_MC501CB 8
+#define SENSOR_OV7620 9
+/*#define SENSOR_OV7648 9 - same values */
+#define SENSOR_OV7630C 10
+#define SENSOR_PAS106 11
+#define SENSOR_PAS202B 12
+#define SENSOR_PB0330 13
+#define SENSOR_PO2030 14
+#define SENSOR_TAS5130CK 15
+#define SENSOR_TAS5130CXX 16
+#define SENSOR_TAS5130C_VF0250 17
+#define SENSOR_MAX 18
unsigned short chip_revision;
+
+ u8 *jpeg_hdr;
};
/* V4L2 controls supported by the driver */
@@ -206,6 +213,213 @@ struct usb_action {
__u16 idx;
};
+static const struct usb_action adcm2700_Initial[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x04, ZC3XX_R002_CLOCKSELECT}, /* 00,02,04,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd8, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d8,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xde, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,de,cc */
+ {0xa0, 0x86, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,86,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,86,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,86,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+/*mswin+*/
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xfe, 0x0002},
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT},
+ {0xaa, 0xb4, 0xcd37},
+ {0xaa, 0xa4, 0x0004},
+ {0xaa, 0xa8, 0x0007},
+ {0xaa, 0xac, 0x0004},
+/*mswin-*/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_InitialScale[] = {
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, /* 00,00,01,cc */
+ {0xa0, 0x10, ZC3XX_R002_CLOCKSELECT}, /* 00,02,10,cc */
+ {0xa0, 0x00, ZC3XX_R008_CLOCKSETTING}, /* 00,08,03,cc */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH}, /* 00,03,02,cc */
+ {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, /* 00,04,80,cc */
+ {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, /* 00,05,01,cc */
+ {0xa0, 0xd0, ZC3XX_R006_FRAMEHEIGHTLOW}, /* 00,06,d0,cc */
+ {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING}, /* 00,01,01,cc */
+ {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,03,cc */
+ {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,01,cc */
+ {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC}, /* 00,12,05,cc */
+ {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, /* 00,98,00,cc */
+ {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, /* 00,9a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW}, /* 01,1a,00,cc */
+ {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW}, /* 01,1c,00,cc */
+ {0xa0, 0xd8, ZC3XX_R09C_WINHEIGHTLOW}, /* 00,9c,d8,cc */
+ {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW}, /* 00,9e,88,cc */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xa0, 0xb7, ZC3XX_R101_SENSORCORRECTION}, /* 01,01,37,cc */
+ {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE}, /* 01,00,0d,cc */
+ {0xa0, 0x06, ZC3XX_R189_AWBSTATUS}, /* 01,89,06,cc */
+ {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE}, /* 01,c5,03,cc */
+ {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05}, /* 01,cb,13,cc */
+ {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE}, /* 02,50,08,cc */
+ {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS}, /* 03,01,08,cc */
+ {0xa0, 0x58, ZC3XX_R116_RGAIN}, /* 01,16,58,cc */
+ {0xa0, 0x5a, ZC3XX_R118_BGAIN}, /* 01,18,5a,cc */
+ {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE}, /* 01,80,02,cc */
+ {0xa0, 0xd3, ZC3XX_R08B_I2CDEVICEADDR}, /* 00,8b,d3,cc */
+ {0xbb, 0x00, 0x0408}, /* 04,00,08,bb */
+ {0xdd, 0x00, 0x0200}, /* 00,02,00,dd */
+ {0xbb, 0x00, 0x0400}, /* 04,00,00,bb */
+ {0xdd, 0x00, 0x0050}, /* 00,00,50,dd */
+ {0xbb, 0x0f, 0x140f}, /* 14,0f,0f,bb */
+ {0xbb, 0xe0, 0x0c2e}, /* 0c,e0,2e,bb */
+ {0xbb, 0x01, 0x2000}, /* 20,01,00,bb */
+ {0xbb, 0x96, 0x2400}, /* 24,96,00,bb */
+ {0xbb, 0x06, 0x1006}, /* 10,06,06,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x5f, 0x2090}, /* 20,5f,90,bb */
+ {0xbb, 0x01, 0x8000}, /* 80,01,00,bb */
+ {0xbb, 0x09, 0x8400}, /* 84,09,00,bb */
+ {0xbb, 0x86, 0x0002}, /* 00,88,02,bb */
+ {0xbb, 0xe6, 0x0401}, /* 04,e6,01,bb */
+ {0xbb, 0x86, 0x0802}, /* 08,88,02,bb */
+ {0xbb, 0xe6, 0x0c01}, /* 0c,e6,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0020}, /* 00,fe,20,aa */
+ /*******/
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xaa, 0xfe, 0x0000}, /* 00,fe,00,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xdd, 0x00, 0x0010}, /* 00,00,10,dd */
+ {0xbb, 0x04, 0x0400}, /* 04,04,00,bb */
+ {0xdd, 0x00, 0x0100}, /* 00,01,00,dd */
+ {0xbb, 0x01, 0x0400}, /* 04,01,00,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x41, 0x2803}, /* 28,41,03,bb */
+ {0xbb, 0x40, 0x2c03}, /* 2c,40,03,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
+static const struct usb_action adcm2700_50HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x05, 0x8400}, /* 84,05,00,bb */
+ {0xbb, 0xd0, 0xb007}, /* b0,d0,07,bb */
+ {0xbb, 0xa0, 0xb80f}, /* b8,a0,0f,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x00d0}, /* 00,26,d0,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_60HZ[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x82, 0xb006}, /* b0,82,06,bb */
+ {0xbb, 0x04, 0xb80d}, /* b8,04,0d,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {0xaa, 0x26, 0x0057}, /* 00,26,57,aa */
+ {0xaa, 0x28, 0x0002}, /* 00,28,02,aa */
+ {}
+};
+static const struct usb_action adcm2700_NoFliker[] = {
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0002}, /* 00,fe,02,aa */
+ {0xa0, 0x0a, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,0a,cc */
+ {0xbb, 0x07, 0x8400}, /* 84,07,00,bb */
+ {0xbb, 0x05, 0xb000}, /* b0,05,00,bb */
+ {0xbb, 0xa0, 0xb801}, /* b8,a0,01,bb */
+ {0xa0, 0x01, ZC3XX_R010_CMOSSENSORSELECT}, /* 00,10,01,cc */
+ {0xaa, 0xfe, 0x0010}, /* 00,fe,10,aa */
+ {}
+};
static const struct usb_action cs2102_Initial[] = {
{0xa1, 0x01, 0x0008},
{0xa1, 0x01, 0x0008},
@@ -877,7 +1091,7 @@ static const struct usb_action cs2102K_Initial[] = {
};
static const struct usb_action cs2102K_InitialScale[] = {
- {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
+ {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
{0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
{0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
{0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
@@ -894,6 +1108,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
{0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
{0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
+/*fixme: next sequence = i2c exchanges*/
{0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
{0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
@@ -1077,207 +1292,6 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x60, ZC3XX_R116_RGAIN},
{0xa0, 0x40, ZC3XX_R117_GGAIN},
{0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
- {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
- {0xa0, 0x08, ZC3XX_R010_CMOSSENSORSELECT},
- {0xa0, 0x02, ZC3XX_R003_FRAMEWIDTHHIGH},
- {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
- {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
- {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
- {0xa0, 0x01, ZC3XX_R001_SYSTEMOPERATING},
- {0xa0, 0x03, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x01, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
- {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
- {0xa0, 0x00, ZC3XX_R11A_FIRSTYLOW},
- {0xa0, 0x00, ZC3XX_R11C_FIRSTXLOW},
- {0xa0, 0xe8, ZC3XX_R09C_WINHEIGHTLOW},
- {0xa0, 0x88, ZC3XX_R09E_WINWIDTHLOW},
- {0xa0, 0x55, ZC3XX_R08B_I2CDEVICEADDR},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0A, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0B, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x02, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0C, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x7b, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0D, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xA3, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x03, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0xfb, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x05, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x06, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x03, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x09, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x08, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0E, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x0f, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x10, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x11, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x12, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x18, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x15, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x16, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0c, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x17, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x0C, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0xf7, ZC3XX_R101_SENSORCORRECTION},
- {0xa0, 0x05, ZC3XX_R012_VIDEOCONTROLFUNC},
- {0xa0, 0x78, ZC3XX_R18D_YTARGET},
- {0xa0, 0x0d, ZC3XX_R100_OPERATIONMODE},
- {0xa0, 0x06, ZC3XX_R189_AWBSTATUS},
- {0xa0, 0x03, ZC3XX_R1C5_SHARPNESSMODE},
- {0xa0, 0x13, ZC3XX_R1CB_SHARPNESS05},
- {0xa0, 0x20, ZC3XX_R087_EXPTIMEMID},
- {0xa0, 0x21, ZC3XX_R088_EXPTIMELOW},
- {0xa0, 0x08, ZC3XX_R250_DEADPIXELSMODE},
- {0xa0, 0x08, ZC3XX_R301_EEPROMACCESS},
- {0xa0, 0x00, 0x01ad},
- {0xa0, 0x01, 0x01b1},
- {0xa0, 0x02, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
- {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* clock ? */
- {0xa0, 0x08, ZC3XX_R1C6_SHARPNESS00}, /* sharpness+ */
- {0xa0, 0x0f, ZC3XX_R1CB_SHARPNESS05}, /* sharpness- */
- {0xa0, 0x13, ZC3XX_R120_GAMMA00}, /* gamma 4 */
- {0xa0, 0x38, ZC3XX_R121_GAMMA01},
- {0xa0, 0x59, ZC3XX_R122_GAMMA02},
- {0xa0, 0x79, ZC3XX_R123_GAMMA03},
- {0xa0, 0x92, ZC3XX_R124_GAMMA04},
- {0xa0, 0xa7, ZC3XX_R125_GAMMA05},
- {0xa0, 0xb9, ZC3XX_R126_GAMMA06},
- {0xa0, 0xc8, ZC3XX_R127_GAMMA07},
- {0xa0, 0xd4, ZC3XX_R128_GAMMA08},
- {0xa0, 0xdf, ZC3XX_R129_GAMMA09},
- {0xa0, 0xe7, ZC3XX_R12A_GAMMA0A},
- {0xa0, 0xee, ZC3XX_R12B_GAMMA0B},
- {0xa0, 0xf4, ZC3XX_R12C_GAMMA0C},
- {0xa0, 0xf9, ZC3XX_R12D_GAMMA0D},
- {0xa0, 0xfc, ZC3XX_R12E_GAMMA0E},
- {0xa0, 0xff, ZC3XX_R12F_GAMMA0F},
- {0xa0, 0x26, ZC3XX_R130_GAMMA10},
- {0xa0, 0x22, ZC3XX_R131_GAMMA11},
- {0xa0, 0x20, ZC3XX_R132_GAMMA12},
- {0xa0, 0x1c, ZC3XX_R133_GAMMA13},
- {0xa0, 0x16, ZC3XX_R134_GAMMA14},
- {0xa0, 0x13, ZC3XX_R135_GAMMA15},
- {0xa0, 0x10, ZC3XX_R136_GAMMA16},
- {0xa0, 0x0d, ZC3XX_R137_GAMMA17},
- {0xa0, 0x0b, ZC3XX_R138_GAMMA18},
- {0xa0, 0x09, ZC3XX_R139_GAMMA19},
- {0xa0, 0x07, ZC3XX_R13A_GAMMA1A},
- {0xa0, 0x06, ZC3XX_R13B_GAMMA1B},
- {0xa0, 0x05, ZC3XX_R13C_GAMMA1C},
- {0xa0, 0x04, ZC3XX_R13D_GAMMA1D},
- {0xa0, 0x03, ZC3XX_R13E_GAMMA1E},
- {0xa0, 0x02, ZC3XX_R13F_GAMMA1F},
- {0xa0, 0x58, ZC3XX_R10A_RGB00}, /* matrix */
- {0xa0, 0xf4, ZC3XX_R10B_RGB01},
- {0xa0, 0xf4, ZC3XX_R10C_RGB02},
- {0xa0, 0xf4, ZC3XX_R10D_RGB10},
- {0xa0, 0x58, ZC3XX_R10E_RGB11},
- {0xa0, 0xf4, ZC3XX_R10F_RGB12},
- {0xa0, 0xf4, ZC3XX_R110_RGB20},
- {0xa0, 0xf4, ZC3XX_R111_RGB21},
- {0xa0, 0x58, ZC3XX_R112_RGB22},
- {0xa0, 0x00, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x00, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x13, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x14, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x21, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x22, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x18, ZC3XX_R092_I2CADDRESSSELECT},
- {0xa0, 0x04, ZC3XX_R093_I2CSETVALUE},
- {0xa0, 0x00, ZC3XX_R094_I2CWRITEACK},
- {0xa0, 0x01, ZC3XX_R090_I2CCOMMAND},
- {0xa0, 0x01, ZC3XX_R0A3_EXPOSURETIMEHIGH},
- {0xa0, 0x22, ZC3XX_R0A4_EXPOSURETIMELOW},
- {0xa0, 0x00, ZC3XX_R190_EXPOSURELIMITHIGH},
- {0xa0, 0x07, ZC3XX_R191_EXPOSURELIMITMID},
- {0xa0, 0xee, ZC3XX_R192_EXPOSURELIMITLOW},
- {0xa0, 0x00, ZC3XX_R195_ANTIFLICKERHIGH},
- {0xa0, 0x00, ZC3XX_R196_ANTIFLICKERMID},
- {0xa0, 0x3a, ZC3XX_R197_ANTIFLICKERLOW},
- {0xa0, 0x10, ZC3XX_R18C_AEFREEZE},
- {0xa0, 0x20, ZC3XX_R18F_AEUNFREEZE},
- {0xa0, 0x0c, ZC3XX_R1A9_DIGITALLIMITDIFF},
- {0xa0, 0x28, ZC3XX_R1AA_DIGITALGAINSTEP},
- {0xa0, 0x04, ZC3XX_R01D_HSYNC_0},
- {0xa0, 0x0f, ZC3XX_R01E_HSYNC_1},
- {0xa0, 0x19, ZC3XX_R01F_HSYNC_2},
- {0xa0, 0x1f, ZC3XX_R020_HSYNC_3},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x60, ZC3XX_R11D_GLOBALGAIN},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x42, ZC3XX_R180_AUTOCORRECTENABLE},
- {0xa0, 0x60, ZC3XX_R116_RGAIN},
- {0xa0, 0x40, ZC3XX_R117_GGAIN},
- {0xa0, 0x4c, ZC3XX_R118_BGAIN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x20, ZC3XX_R092_I2CADDRESSSELECT},
{0xa0, 0x01, ZC3XX_R093_I2CSETVALUE},
@@ -1334,6 +1348,7 @@ static const struct usb_action cs2102K_InitialScale[] = {
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
+/*fixme:what does the next sequence?*/
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN},
{0xa0, 0x04, ZC3XX_R1A7_CALCGLOBALMEAN},
@@ -6237,7 +6252,7 @@ static const struct usb_action tas5130c_vf0250_NoFlikerScale[] = {
{}
};
-static int reg_r_i(struct gspca_dev *gspca_dev,
+static u8 reg_r_i(struct gspca_dev *gspca_dev,
__u16 index)
{
usb_control_msg(gspca_dev->dev,
@@ -6250,10 +6265,10 @@ static int reg_r_i(struct gspca_dev *gspca_dev,
return gspca_dev->usb_buf[0];
}
-static int reg_r(struct gspca_dev *gspca_dev,
+static u8 reg_r(struct gspca_dev *gspca_dev,
__u16 index)
{
- int ret;
+ u8 ret;
ret = reg_r_i(gspca_dev, index);
PDEBUG(D_USBI, "reg r [%04x] -> %02x", index, ret);
@@ -6286,8 +6301,8 @@ static __u16 i2c_read(struct gspca_dev *gspca_dev,
__u8 retbyte;
__u16 retval;
- reg_w_i(gspca_dev->dev, reg, 0x92);
- reg_w_i(gspca_dev->dev, 0x02, 0x90); /* <- read command */
+ reg_w_i(gspca_dev->dev, reg, 0x0092);
+ reg_w_i(gspca_dev->dev, 0x02, 0x0090); /* <- read command */
msleep(25);
retbyte = reg_r_i(gspca_dev, 0x0091); /* read status */
retval = reg_r_i(gspca_dev, 0x0095); /* read Lowbyte */
@@ -6332,6 +6347,12 @@ static void usb_exchange(struct gspca_dev *gspca_dev,
action->idx & 0xff, /* valL */
action->idx >> 8); /* valH */
break;
+ case 0xbb:
+ i2c_write(gspca_dev,
+ action->idx >> 8, /* reg */
+ action->idx & 0xff, /* valL */
+ action->val); /* valH */
+ break;
default:
/* case 0xdd: * delay */
msleep(action->val / 64 + 10);
@@ -6347,6 +6368,10 @@ static void setmatrix(struct gspca_dev *gspca_dev)
struct sd *sd = (struct sd *) gspca_dev;
int i;
const __u8 *matrix;
+ static const u8 adcm2700_matrix[9] =
+/* {0x66, 0xed, 0xed, 0xed, 0x66, 0xed, 0xed, 0xed, 0x66}; */
+/*ms-win*/
+ {0x74, 0xed, 0xed, 0xed, 0x74, 0xed, 0xed, 0xed, 0x74};
static const __u8 gc0305_matrix[9] =
{0x50, 0xf8, 0xf8, 0xf8, 0x50, 0xf8, 0xf8, 0xf8, 0x50};
static const __u8 ov7620_matrix[9] =
@@ -6358,23 +6383,24 @@ static void setmatrix(struct gspca_dev *gspca_dev)
static const __u8 vf0250_matrix[9] =
{0x7b, 0xea, 0xea, 0xea, 0x7b, 0xea, 0xea, 0xea, 0x7b};
static const __u8 *matrix_tb[SENSOR_MAX] = {
- NULL, /* SENSOR_CS2102 0 */
- NULL, /* SENSOR_CS2102K 1 */
- gc0305_matrix, /* SENSOR_GC0305 2 */
- NULL, /* SENSOR_HDCS2020b 3 */
- NULL, /* SENSOR_HV7131B 4 */
- NULL, /* SENSOR_HV7131C 5 */
- NULL, /* SENSOR_ICM105A 6 */
- NULL, /* SENSOR_MC501CB 7 */
- ov7620_matrix, /* SENSOR_OV7620 8 */
- NULL, /* SENSOR_OV7630C 9 */
- NULL, /* SENSOR_PAS106 10 */
- pas202b_matrix, /* SENSOR_PAS202B 11 */
- NULL, /* SENSOR_PB0330 12 */
- po2030_matrix, /* SENSOR_PO2030 13 */
- NULL, /* SENSOR_TAS5130CK 14 */
- NULL, /* SENSOR_TAS5130CXX 15 */
- vf0250_matrix, /* SENSOR_TAS5130C_VF0250 16 */
+ adcm2700_matrix, /* SENSOR_ADCM2700 0 */
+ NULL, /* SENSOR_CS2102 1 */
+ NULL, /* SENSOR_CS2102K 2 */
+ gc0305_matrix, /* SENSOR_GC0305 3 */
+ NULL, /* SENSOR_HDCS2020b 4 */
+ NULL, /* SENSOR_HV7131B 5 */
+ NULL, /* SENSOR_HV7131C 6 */
+ NULL, /* SENSOR_ICM105A 7 */
+ NULL, /* SENSOR_MC501CB 8 */
+ ov7620_matrix, /* SENSOR_OV7620 9 */
+ NULL, /* SENSOR_OV7630C 10 */
+ NULL, /* SENSOR_PAS106 11 */
+ pas202b_matrix, /* SENSOR_PAS202B 12 */
+ NULL, /* SENSOR_PB0330 13 */
+ po2030_matrix, /* SENSOR_PO2030 14 */
+ NULL, /* SENSOR_TAS5130CK 15 */
+ NULL, /* SENSOR_TAS5130CXX 16 */
+ vf0250_matrix, /* SENSOR_TAS5130C_VF0250 17 */
};
matrix = matrix_tb[sd->sensor];
@@ -6398,8 +6424,11 @@ static void setbrightness(struct gspca_dev *gspca_dev)
/*fixme: is it really write to 011d and 018d for all other sensors? */
brightness = sd->brightness;
reg_w(gspca_dev->dev, brightness, 0x011d);
- if (sd->sensor == SENSOR_HV7131B)
+ switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ case SENSOR_HV7131B:
return;
+ }
if (brightness < 0x70)
brightness += 0x10;
else
@@ -6536,10 +6565,10 @@ static void setquality(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
struct usb_device *dev = gspca_dev->dev;
- __u8 quality;
__u8 frxt;
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_HV7131B:
case SENSOR_OV7620:
@@ -6547,26 +6576,18 @@ static void setquality(struct gspca_dev *gspca_dev)
return;
}
/*fixme: is it really 0008 0007 0018 for all other sensors? */
- quality = sd->qindex;
- reg_w(dev, quality, 0x0008);
+ reg_w(dev, QUANT_VAL, 0x0008);
frxt = 0x30;
reg_w(dev, frxt, 0x0007);
- switch (quality) {
- case 0:
- case 1:
- case 2:
- frxt = 0xff;
- break;
- case 3:
- frxt = 0xf0;
- break;
- case 4:
- frxt = 0xe0;
- break;
- case 5:
- frxt = 0x20;
- break;
- }
+#if QUANT_VAL == 0 || QUANT_VAL == 1 || QUANT_VAL == 2
+ frxt = 0xff;
+#elif QUANT_VAL == 3
+ frxt = 0xf0;
+#elif QUANT_VAL == 4
+ frxt = 0xe0;
+#else
+ frxt = 0x20;
+#endif
reg_w(dev, frxt, 0x0018);
}
@@ -6583,71 +6604,75 @@ static int setlightfreq(struct gspca_dev *gspca_dev)
int i, mode;
const struct usb_action *zc3_freq;
static const struct usb_action *freq_tb[SENSOR_MAX][6] = {
-/* SENSOR_CS2102 0 */
+/* SENSOR_ADCM2700 0 */
+ {adcm2700_NoFliker, adcm2700_NoFliker,
+ adcm2700_50HZ, adcm2700_50HZ,
+ adcm2700_60HZ, adcm2700_60HZ},
+/* SENSOR_CS2102 1 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
cs2102_50HZ, cs2102_50HZScale,
cs2102_60HZ, cs2102_60HZScale},
-/* SENSOR_CS2102K 1 */
+/* SENSOR_CS2102K 2 */
{cs2102_NoFliker, cs2102_NoFlikerScale,
NULL, NULL, /* currently disabled */
NULL, NULL},
-/* SENSOR_GC0305 2 */
+/* SENSOR_GC0305 3 */
{gc0305_NoFliker, gc0305_NoFliker,
gc0305_50HZ, gc0305_50HZ,
gc0305_60HZ, gc0305_60HZ},
-/* SENSOR_HDCS2020b 3 */
+/* SENSOR_HDCS2020b 4 */
{hdcs2020b_NoFliker, hdcs2020b_NoFliker,
hdcs2020b_50HZ, hdcs2020b_50HZ,
hdcs2020b_60HZ, hdcs2020b_60HZ},
-/* SENSOR_HV7131B 4 */
+/* SENSOR_HV7131B 5 */
{hv7131b_NoFlikerScale, hv7131b_NoFliker,
hv7131b_50HZScale, hv7131b_50HZ,
hv7131b_60HZScale, hv7131b_60HZ},
-/* SENSOR_HV7131C 5 */
+/* SENSOR_HV7131C 6 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_ICM105A 6 */
+/* SENSOR_ICM105A 7 */
{icm105a_NoFliker, icm105a_NoFlikerScale,
icm105a_50HZ, icm105a_50HZScale,
icm105a_60HZ, icm105a_60HZScale},
-/* SENSOR_MC501CB 7 */
+/* SENSOR_MC501CB 8 */
{MC501CB_NoFliker, MC501CB_NoFlikerScale,
MC501CB_50HZ, MC501CB_50HZScale,
MC501CB_60HZ, MC501CB_60HZScale},
-/* SENSOR_OV7620 8 */
+/* SENSOR_OV7620 9 */
{OV7620_NoFliker, OV7620_NoFliker,
OV7620_50HZ, OV7620_50HZ,
OV7620_60HZ, OV7620_60HZ},
-/* SENSOR_OV7630C 9 */
+/* SENSOR_OV7630C 10 */
{NULL, NULL,
NULL, NULL,
NULL, NULL},
-/* SENSOR_PAS106 10 */
+/* SENSOR_PAS106 11 */
{pas106b_NoFliker, pas106b_NoFliker,
pas106b_50HZ, pas106b_50HZ,
pas106b_60HZ, pas106b_60HZ},
-/* SENSOR_PAS202B 11 */
+/* SENSOR_PAS202B 12 */
{pas202b_NoFlikerScale, pas202b_NoFliker,
pas202b_50HZScale, pas202b_50HZ,
pas202b_60HZScale, pas202b_60HZ},
-/* SENSOR_PB0330 12 */
+/* SENSOR_PB0330 13 */
{pb0330_NoFliker, pb0330_NoFlikerScale,
pb0330_50HZ, pb0330_50HZScale,
pb0330_60HZ, pb0330_60HZScale},
-/* SENSOR_PO2030 13 */
+/* SENSOR_PO2030 14 */
{PO2030_NoFliker, PO2030_NoFliker,
PO2030_50HZ, PO2030_50HZ,
PO2030_60HZ, PO2030_60HZ},
-/* SENSOR_TAS5130CK 14 */
+/* SENSOR_TAS5130CK 15 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130CXX 15 */
+/* SENSOR_TAS5130CXX 16 */
{tas5130cxx_NoFliker, tas5130cxx_NoFlikerScale,
tas5130cxx_50HZ, tas5130cxx_50HZScale,
tas5130cxx_60HZ, tas5130cxx_60HZScale},
-/* SENSOR_TAS5130C_VF0250 16 */
+/* SENSOR_TAS5130C_VF0250 17 */
{tas5130c_vf0250_NoFliker, tas5130c_vf0250_NoFlikerScale,
tas5130c_vf0250_50HZ, tas5130c_vf0250_50HZScale,
tas5130c_vf0250_60HZ, tas5130c_vf0250_60HZScale},
@@ -6701,6 +6726,7 @@ static void send_unknown(struct usb_device *dev, int sensor)
reg_w(dev, 0x0c, 0x003b);
reg_w(dev, 0x08, 0x0038);
break;
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PB0330:
@@ -6743,26 +6769,25 @@ static int sif_probe(struct gspca_dev *gspca_dev)
static int vga_2wr_probe(struct gspca_dev *gspca_dev)
{
struct usb_device *dev = gspca_dev->dev;
- __u8 retbyte;
- __u16 checkword;
+ u16 retword;
start_2wr_probe(dev, 0x00); /* HV7131B */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x00; /* HV7131B */
start_2wr_probe(dev, 0x04); /* CS2102 */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x04; /* CS2102 */
start_2wr_probe(dev, 0x06); /* OmniVision */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x11, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x11);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x11);
+ if (retword != 0) {
/* (should have returned 0xaa) --> Omnivision? */
/* reg_r 0x10 -> 0x06 --> */
goto ov_check;
@@ -6770,40 +6795,40 @@ static int vga_2wr_probe(struct gspca_dev *gspca_dev)
start_2wr_probe(dev, 0x08); /* HDCS2020 */
i2c_write(gspca_dev, 0x15, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x08; /* HDCS2020 */
start_2wr_probe(dev, 0x0a); /* PB0330 */
i2c_write(gspca_dev, 0x07, 0xaa, 0xaa);
- retbyte = i2c_read(gspca_dev, 0x07);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x07);
+ if (retword != 0)
return 0x0a; /* PB0330 */
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
- retbyte = i2c_read(gspca_dev, 0x04);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x04);
+ if (retword != 0)
return 0x0a; /* PB0330 ?? */
start_2wr_probe(dev, 0x0c); /* ICM105A */
i2c_write(gspca_dev, 0x01, 0x11, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x0c; /* ICM105A */
start_2wr_probe(dev, 0x0e); /* PAS202BCB */
reg_w(dev, 0x08, 0x008d);
i2c_write(gspca_dev, 0x03, 0xaa, 0x00);
msleep(500);
- retbyte = i2c_read(gspca_dev, 0x03);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x03);
+ if (retword != 0)
return 0x0e; /* PAS202BCB */
start_2wr_probe(dev, 0x02); /* ?? */
i2c_write(gspca_dev, 0x01, 0xaa, 0x00);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0)
return 0x02; /* ?? */
ov_check:
reg_r(gspca_dev, 0x0010); /* ?? */
@@ -6817,12 +6842,10 @@ ov_check:
msleep(500);
reg_w(dev, 0x01, 0x0012);
i2c_write(gspca_dev, 0x12, 0x80, 0x00); /* sensor reset */
- retbyte = i2c_read(gspca_dev, 0x0a);
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0b);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", checkword);
- switch (checkword) {
+ retword = i2c_read(gspca_dev, 0x0a) << 8;
+ retword |= i2c_read(gspca_dev, 0x0b);
+ PDEBUG(D_PROBE, "probe 2wr ov vga 0x%04x", retword);
+ switch (retword) {
case 0x7631: /* OV7630C */
reg_w(dev, 0x06, 0x0010);
break;
@@ -6832,7 +6855,7 @@ ov_check:
default:
return -1; /* not OmniVision */
}
- return checkword;
+ return retword;
}
struct sensor_by_chipset_revision {
@@ -6845,6 +6868,7 @@ static const struct sensor_by_chipset_revision chipset_revision_sensor[] = {
{0x8001, 0x13},
{0x8000, 0x14}, /* CS2102K */
{0x8400, 0x15}, /* TAS5130K */
+ {0x4001, 0x16}, /* ADCM2700 */
};
static int vga_3wr_probe(struct gspca_dev *gspca_dev)
@@ -6853,7 +6877,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
struct usb_device *dev = gspca_dev->dev;
int i;
__u8 retbyte;
- __u16 checkword;
+ u16 retword;
/*fixme: lack of 8b=b3 (11,12)-> 10, 8b=e0 (14,15,16)-> 12 found in gspcav1*/
reg_w(dev, 0x02, 0x0010);
@@ -6865,27 +6889,25 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x14);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x14);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x15);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x15);
+ if (retword != 0)
return 0x11; /* HV7131R */
- retbyte = i2c_read(gspca_dev, 0x16);
- if (retbyte != 0)
+ retword = i2c_read(gspca_dev, 0x16);
+ if (retword != 0)
return 0x11; /* HV7131R */
reg_w(dev, 0x02, 0x0010);
- retbyte = reg_r(gspca_dev, 0x000b);
- checkword = retbyte << 8;
- retbyte = reg_r(gspca_dev, 0x000a);
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", checkword);
+ retword = reg_r(gspca_dev, 0x000b) << 8;
+ retword |= reg_r(gspca_dev, 0x000a);
+ PDEBUG(D_PROBE, "probe 3wr vga 1 0x%04x", retword);
reg_r(gspca_dev, 0x0010);
/* this is tested only once anyway */
for (i = 0; i < ARRAY_SIZE(chipset_revision_sensor); i++) {
- if (chipset_revision_sensor[i].revision == checkword) {
- sd->chip_revision = checkword;
+ if (chipset_revision_sensor[i].revision == retword) {
+ sd->chip_revision = retword;
send_unknown(dev, SENSOR_PB0330);
return chipset_revision_sensor[i].internal_sensor_id;
}
@@ -6897,8 +6919,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x0a, 0x0010);
reg_w(dev, 0x03, 0x0012);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
return 0x0a; /* ?? */
}
@@ -6910,14 +6932,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x03, 0x0012);
msleep(2);
reg_w(dev, 0x01, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x00);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type %02x", retbyte);
- if (retbyte == 0x11) /* VF0250 */
+ retword = i2c_read(gspca_dev, 0x00);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type %02x", retword);
+ if (retword == 0x0011) /* VF0250 */
return 0x0250;
- if (retbyte == 0x29) /* gc0305 */
+ if (retword == 0x0029) /* gc0305 */
send_unknown(dev, SENSOR_GC0305);
- return retbyte;
+ return retword;
}
reg_w(dev, 0x01, 0x0000); /* check OmniVision */
@@ -6927,8 +6949,8 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x06, 0x0010);
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- if (i2c_read(gspca_dev, 0x1c) == 0x7f /* OV7610 - manufacturer ID */
- && i2c_read(gspca_dev, 0x1d) == 0xa2) {
+ if (i2c_read(gspca_dev, 0x1c) == 0x007f /* OV7610 - manufacturer ID */
+ && i2c_read(gspca_dev, 0x1d) == 0x00a2) {
send_unknown(dev, SENSOR_OV7620);
return 0x06; /* OmniVision confirm ? */
}
@@ -6942,16 +6964,14 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
/* msleep(150); */
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0012);
- retbyte = i2c_read(gspca_dev, 0x0000); /* ID 0 */
- checkword = retbyte << 8;
- retbyte = i2c_read(gspca_dev, 0x0001); /* ID 1 */
- checkword |= retbyte;
- PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", checkword);
- if (checkword == 0x2030) {
+ retword = i2c_read(gspca_dev, 0x00) << 8; /* ID 0 */
+ retword |= i2c_read(gspca_dev, 0x01); /* ID 1 */
+ PDEBUG(D_PROBE, "probe 3wr vga 2 0x%04x", retword);
+ if (retword == 0x2030) {
retbyte = i2c_read(gspca_dev, 0x02); /* revision number */
PDEBUG(D_PROBE, "sensor PO2030 rev 0x%02x", retbyte);
send_unknown(dev, SENSOR_PO2030);
- return checkword;
+ return retword;
}
reg_w(dev, 0x01, 0x0000);
@@ -6962,10 +6982,10 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
reg_w(dev, 0x01, 0x0012);
reg_w(dev, 0x05, 0x0001);
reg_w(dev, 0xd3, 0x008b);
- retbyte = i2c_read(gspca_dev, 0x01);
- if (retbyte != 0) {
- PDEBUG(D_PROBE, "probe 3wr vga type 0a ?");
- return 0x0a; /* ?? */
+ retword = i2c_read(gspca_dev, 0x01);
+ if (retword != 0) {
+ PDEBUG(D_PROBE, "probe 3wr vga type 0a ? ret: %04x", retword);
+ return retword;
}
return -1;
}
@@ -6973,7 +6993,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
- int sensor, sensor2;
+ int sensor;
switch (sd->sensor) {
case SENSOR_MC501CB:
@@ -6988,16 +7008,9 @@ static int zcxx_probeSensor(struct gspca_dev *gspca_dev)
break;
}
sensor = vga_2wr_probe(gspca_dev);
- if (sensor >= 0) {
- if (sensor < 0x7600)
- return sensor;
- /* next probe is needed for OmniVision ? */
- }
- sensor2 = vga_3wr_probe(gspca_dev);
- if (sensor2 >= 0
- && sensor >= 0)
+ if (sensor >= 0)
return sensor;
- return sensor2;
+ return vga_3wr_probe(gspca_dev);
}
/* this function is called at probe time */
@@ -7009,23 +7022,24 @@ static int sd_config(struct gspca_dev *gspca_dev,
int sensor;
int vga = 1; /* 1: vga, 0: sif */
static const __u8 gamma[SENSOR_MAX] = {
- 5, /* SENSOR_CS2102 0 */
- 5, /* SENSOR_CS2102K 1 */
- 4, /* SENSOR_GC0305 2 */
- 4, /* SENSOR_HDCS2020b 3 */
- 4, /* SENSOR_HV7131B 4 */
- 4, /* SENSOR_HV7131C 5 */
- 4, /* SENSOR_ICM105A 6 */
- 4, /* SENSOR_MC501CB 7 */
- 3, /* SENSOR_OV7620 8 */
- 4, /* SENSOR_OV7630C 9 */
- 4, /* SENSOR_PAS106 10 */
- 4, /* SENSOR_PAS202B 11 */
- 4, /* SENSOR_PB0330 12 */
- 4, /* SENSOR_PO2030 13 */
- 4, /* SENSOR_TAS5130CK 14 */
- 4, /* SENSOR_TAS5130CXX 15 */
- 3, /* SENSOR_TAS5130C_VF0250 16 */
+ 4, /* SENSOR_ADCM2700 0 */
+ 5, /* SENSOR_CS2102 1 */
+ 5, /* SENSOR_CS2102K 2 */
+ 4, /* SENSOR_GC0305 3 */
+ 4, /* SENSOR_HDCS2020b 4 */
+ 4, /* SENSOR_HV7131B 5 */
+ 4, /* SENSOR_HV7131C 6 */
+ 4, /* SENSOR_ICM105A 7 */
+ 4, /* SENSOR_MC501CB 8 */
+ 3, /* SENSOR_OV7620 9 */
+ 4, /* SENSOR_OV7630C 10 */
+ 4, /* SENSOR_PAS106 11 */
+ 4, /* SENSOR_PAS202B 12 */
+ 4, /* SENSOR_PB0330 13 */
+ 4, /* SENSOR_PO2030 14 */
+ 4, /* SENSOR_TAS5130CK 15 */
+ 4, /* SENSOR_TAS5130CXX 16 */
+ 3, /* SENSOR_TAS5130C_VF0250 17 */
};
/* define some sensors from the vendor/product */
@@ -7033,7 +7047,7 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->sensor = id->driver_info;
sensor = zcxx_probeSensor(gspca_dev);
if (sensor >= 0)
- PDEBUG(D_PROBE, "probe sensor -> %02x", sensor);
+ PDEBUG(D_PROBE, "probe sensor -> %04x", sensor);
if ((unsigned) force_sensor < SENSOR_MAX) {
sd->sensor = force_sensor;
PDEBUG(D_PROBE, "sensor forced to %d", force_sensor);
@@ -7112,6 +7126,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
sd->chip_revision);
sd->sensor = SENSOR_TAS5130CK;
break;
+ case 0x16:
+ PDEBUG(D_PROBE, "Find Sensor ADCM2700");
+ sd->sensor = SENSOR_ADCM2700;
+ break;
case 0x29:
PDEBUG(D_PROBE, "Find Sensor GC0305");
sd->sensor = SENSOR_GC0305;
@@ -7129,12 +7147,16 @@ static int sd_config(struct gspca_dev *gspca_dev,
PDEBUG(D_PROBE, "Find Sensor OV7620");
sd->sensor = SENSOR_OV7620;
break;
+ case 0x7631:
+ PDEBUG(D_PROBE, "Find Sensor OV7630C");
+ sd->sensor = SENSOR_OV7630C;
+ break;
case 0x7648:
PDEBUG(D_PROBE, "Find Sensor OV7648");
sd->sensor = SENSOR_OV7620; /* same sensor (?) */
break;
default:
- PDEBUG(D_ERR|D_PROBE, "Unknown sensor %02x", sensor);
+ PDEBUG(D_ERR|D_PROBE, "Unknown sensor %04x", sensor);
return -EINVAL;
}
}
@@ -7147,7 +7169,6 @@ static int sd_config(struct gspca_dev *gspca_dev,
}
cam = &gspca_dev->cam;
- cam->epaddr = 0x01;
/*fixme:test*/
gspca_dev->nbalt--;
if (vga) {
@@ -7157,12 +7178,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
cam->cam_mode = sif_mode;
cam->nmodes = ARRAY_SIZE(sif_mode);
}
- sd->qindex = 1;
sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
sd->gamma = gamma[(int) sd->sensor];
sd->autogain = sd_ctrls[SD_AUTOGAIN].qctrl.default_value;
sd->lightfreq = sd_ctrls[SD_FREQ].qctrl.default_value;
+ sd->quality = QUALITY_DEF;
switch (sd->sensor) {
case SENSOR_GC0305:
@@ -7196,27 +7217,34 @@ static int sd_start(struct gspca_dev *gspca_dev)
const struct usb_action *zc3_init;
int mode;
static const struct usb_action *init_tb[SENSOR_MAX][2] = {
- {cs2102_InitialScale, cs2102_Initial}, /* 0 */
- {cs2102K_InitialScale, cs2102K_Initial}, /* 1 */
- {gc0305_Initial, gc0305_InitialScale}, /* 2 */
- {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 3 */
- {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 4 */
- {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 5 */
- {icm105axx_InitialScale, icm105axx_Initial}, /* 6 */
- {MC501CB_InitialScale, MC501CB_Initial}, /* 7 */
- {OV7620_mode0, OV7620_mode1}, /* 8 */
- {ov7630c_InitialScale, ov7630c_Initial}, /* 9 */
- {pas106b_InitialScale, pas106b_Initial}, /* 10 */
- {pas202b_Initial, pas202b_InitialScale}, /* 11 */
- {pb0330xx_InitialScale, pb0330xx_Initial}, /* 12 */
+ {adcm2700_Initial, adcm2700_InitialScale}, /* 0 */
+ {cs2102_InitialScale, cs2102_Initial}, /* 1 */
+ {cs2102K_InitialScale, cs2102K_Initial}, /* 2 */
+ {gc0305_Initial, gc0305_InitialScale}, /* 3 */
+ {hdcs2020xb_InitialScale, hdcs2020xb_Initial}, /* 4 */
+ {hv7131bxx_InitialScale, hv7131bxx_Initial}, /* 5 */
+ {hv7131cxx_InitialScale, hv7131cxx_Initial}, /* 6 */
+ {icm105axx_InitialScale, icm105axx_Initial}, /* 7 */
+ {MC501CB_InitialScale, MC501CB_Initial}, /* 8 */
+ {OV7620_mode0, OV7620_mode1}, /* 9 */
+ {ov7630c_InitialScale, ov7630c_Initial}, /* 10 */
+ {pas106b_InitialScale, pas106b_Initial}, /* 11 */
+ {pas202b_Initial, pas202b_InitialScale}, /* 12 */
+ {pb0330xx_InitialScale, pb0330xx_Initial}, /* 13 */
/* or {pb03303x_InitialScale, pb03303x_Initial}, */
- {PO2030_mode0, PO2030_mode1}, /* 13 */
- {tas5130CK_InitialScale, tas5130CK_Initial}, /* 14 */
- {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 15 */
+ {PO2030_mode0, PO2030_mode1}, /* 14 */
+ {tas5130CK_InitialScale, tas5130CK_Initial}, /* 15 */
+ {tas5130cxx_InitialScale, tas5130cxx_Initial}, /* 16 */
{tas5130c_vf0250_InitialScale, tas5130c_vf0250_Initial},
- /* 16 */
+ /* 17 */
};
+ /* create the JPEG header */
+ sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
+ jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
+ 0x21); /* JPEG 422 */
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+
mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
zc3_init = init_tb[(int) sd->sensor][mode];
switch (sd->sensor) {
@@ -7243,11 +7271,12 @@ static int sd_start(struct gspca_dev *gspca_dev)
usb_exchange(gspca_dev, zc3_init);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_GC0305:
case SENSOR_OV7620:
case SENSOR_PO2030:
case SENSOR_TAS5130C_VF0250:
- msleep(100); /* ?? */
+/* msleep(100); * ?? */
reg_r(gspca_dev, 0x0002); /* --> 0x40 */
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7260,6 +7289,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
setmatrix(gspca_dev);
setbrightness(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
case SENSOR_OV7620:
reg_r(gspca_dev, 0x0008);
reg_w(dev, 0x00, 0x0008);
@@ -7301,6 +7331,13 @@ static int sd_start(struct gspca_dev *gspca_dev)
setlightfreq(gspca_dev);
switch (sd->sensor) {
+ case SENSOR_ADCM2700:
+ reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
+ reg_w(dev, 0x15, 0x01ae);
+ reg_w(dev, 0x02, 0x0180);
+ /* ms-win + */
+ reg_w(dev, 0x40, 0x0117);
+ break;
case SENSOR_GC0305:
reg_w(dev, 0x09, 0x01ad); /* (from win traces) */
reg_w(dev, 0x15, 0x01ae);
@@ -7323,19 +7360,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
setautogain(gspca_dev);
switch (sd->sensor) {
- case SENSOR_PAS202B:
- reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- break;
case SENSOR_PO2030:
msleep(500);
reg_r(gspca_dev, 0x0008);
reg_r(gspca_dev, 0x0007);
+ /*fall thru*/
+ case SENSOR_PAS202B:
reg_w(dev, 0x00, 0x0007); /* (from win traces) */
- reg_w(dev, 0x02, 0x0008);
+ reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
break;
}
- if (sd->sensor == SENSOR_PAS202B)
- reg_w(dev, 0x02, ZC3XX_R008_CLOCKSETTING);
return 0;
}
@@ -7344,6 +7378,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
{
struct sd *sd = (struct sd *) gspca_dev;
+ kfree(sd->jpeg_hdr);
if (!gspca_dev->present)
return;
send_unknown(gspca_dev->dev, sd->sensor);
@@ -7354,14 +7389,15 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
__u8 *data,
int len)
{
+ struct sd *sd = (struct sd *) gspca_dev;
if (data[0] == 0xff && data[1] == 0xd8) { /* start of frame */
frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
data, 0);
/* put the JPEG header in the new frame */
- jpeg_put_header(gspca_dev, frame,
- ((struct sd *) gspca_dev)->qindex,
- 0x21);
+ gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
+ sd->jpeg_hdr, JPEG_HDR_SZ);
+
/* remove the webcam's header:
* ff d8 ff fe 00 0e 00 00 ss ss 00 01 ww ww hh hh pp pp
* - 'ss ss' is the frame sequence number (BE)
@@ -7503,6 +7539,34 @@ static int sd_querymenu(struct gspca_dev *gspca_dev,
return -EINVAL;
}
+static int sd_set_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ if (jcomp->quality < QUALITY_MIN)
+ sd->quality = QUALITY_MIN;
+ else if (jcomp->quality > QUALITY_MAX)
+ sd->quality = QUALITY_MAX;
+ else
+ sd->quality = jcomp->quality;
+ if (gspca_dev->streaming)
+ jpeg_set_qual(sd->jpeg_hdr, sd->quality);
+ return 0;
+}
+
+static int sd_get_jcomp(struct gspca_dev *gspca_dev,
+ struct v4l2_jpegcompression *jcomp)
+{
+ struct sd *sd = (struct sd *) gspca_dev;
+
+ memset(jcomp, 0, sizeof *jcomp);
+ jcomp->quality = sd->quality;
+ jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
+ | V4L2_JPEG_MARKER_DQT;
+ return 0;
+}
+
static const struct sd_desc sd_desc = {
.name = MODULE_NAME,
.ctrls = sd_ctrls,
@@ -7513,6 +7577,8 @@ static const struct sd_desc sd_desc = {
.stop0 = sd_stop0,
.pkt_scan = sd_pkt_scan,
.querymenu = sd_querymenu,
+ .get_jcomp = sd_get_jcomp,
+ .set_jcomp = sd_set_jcomp,
};
static const __devinitdata struct usb_device_id device_table[] = {
@@ -7563,11 +7629,9 @@ static const __devinitdata struct usb_device_id device_table[] = {
{USB_DEVICE(0x055f, 0xd004)},
{USB_DEVICE(0x0698, 0x2003)},
{USB_DEVICE(0x0ac8, 0x0301), .driver_info = SENSOR_PAS106},
- {USB_DEVICE(0x0ac8, 0x0302)},
+ {USB_DEVICE(0x0ac8, 0x0302), .driver_info = SENSOR_PAS106},
{USB_DEVICE(0x0ac8, 0x301b)},
-#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE
{USB_DEVICE(0x0ac8, 0x303b)},
-#endif
{USB_DEVICE(0x0ac8, 0x305b), .driver_info = SENSOR_TAS5130C_VF0250},
{USB_DEVICE(0x0ac8, 0x307b)},
{USB_DEVICE(0x10fd, 0x0128)},
@@ -7600,8 +7664,10 @@ static struct usb_driver sd_driver = {
static int __init sd_mod_init(void)
{
- if (usb_register(&sd_driver) < 0)
- return -1;
+ int ret;
+ ret = usb_register(&sd_driver);
+ if (ret < 0)
+ return ret;
PDEBUG(D_PROBE, "registered");
return 0;
}
diff --git a/drivers/media/video/hdpvr/Kconfig b/drivers/media/video/hdpvr/Kconfig
new file mode 100644
index 00000000000..de247f3c7d0
--- /dev/null
+++ b/drivers/media/video/hdpvr/Kconfig
@@ -0,0 +1,10 @@
+
+config VIDEO_HDPVR
+ tristate "Hauppauge HD PVR support"
+ depends on VIDEO_DEV
+ ---help---
+ This is a video4linux driver for Hauppauge's HD PVR USB device.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hdpvr
+
diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile
new file mode 100644
index 00000000000..e0230fcb2e3
--- /dev/null
+++ b/drivers/media/video/hdpvr/Makefile
@@ -0,0 +1,9 @@
+hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o
+
+hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o
+
+obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o
+
+EXTRA_CFLAGS += -Idrivers/media/video
+
+EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/hdpvr/hdpvr-control.c b/drivers/media/video/hdpvr/hdpvr-control.c
new file mode 100644
index 00000000000..06791749d1a
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-control.c
@@ -0,0 +1,201 @@
+/*
+ * Hauppauge HD PVR USB driver - video 4 linux 2 interface
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+
+#include <linux/videodev2.h>
+
+#include <media/v4l2-common.h>
+
+#include "hdpvr.h"
+
+
+int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf)
+{
+ int ret;
+ char request_type = 0x38, snd_request = 0x01;
+
+ msleep(10);
+
+ mutex_lock(&dev->usbc_mutex);
+ dev->usbc_buf[0] = valbuf;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ snd_request, 0x00 | request_type,
+ value, CTRL_DEFAULT_INDEX,
+ dev->usbc_buf, 1, 10000);
+
+ mutex_unlock(&dev->usbc_mutex);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "config call request for value 0x%x returned %d\n", value,
+ ret);
+
+ return ret < 0 ? ret : 0;
+}
+
+struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
+{
+ struct hdpvr_video_info *vidinf = NULL;
+#ifdef HDPVR_DEBUG
+ char print_buf[15];
+#endif
+ int ret;
+
+ vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
+ if (!vidinf) {
+ v4l2_err(&dev->v4l2_dev, "out of memory\n");
+ goto err;
+ }
+
+ mutex_lock(&dev->usbc_mutex);
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ 0x81, 0x80 | 0x38,
+ 0x1400, 0x0003,
+ dev->usbc_buf, 5,
+ 1000);
+ if (ret == 5) {
+ vidinf->width = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+ vidinf->height = dev->usbc_buf[3] << 8 | dev->usbc_buf[2];
+ vidinf->fps = dev->usbc_buf[4];
+ }
+
+#ifdef HDPVR_DEBUG
+ if (hdpvr_debug & MSG_INFO) {
+ hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
+ sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get video info returned: %d, %s\n", ret, print_buf);
+ }
+#endif
+ mutex_unlock(&dev->usbc_mutex);
+
+ if (!vidinf->width || !vidinf->height || !vidinf->fps) {
+ kfree(vidinf);
+ vidinf = NULL;
+ }
+err:
+ return vidinf;
+}
+
+int get_input_lines_info(struct hdpvr_device *dev)
+{
+#ifdef HDPVR_DEBUG
+ char print_buf[9];
+#endif
+ int ret, lines;
+
+ mutex_lock(&dev->usbc_mutex);
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ 0x81, 0x80 | 0x38,
+ 0x1800, 0x0003,
+ dev->usbc_buf, 3,
+ 1000);
+
+#ifdef HDPVR_DEBUG
+ if (hdpvr_debug & MSG_INFO) {
+ hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,
+ sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get input lines info returned: %d, %s\n", ret,
+ print_buf);
+ }
+#endif
+ lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
+ mutex_unlock(&dev->usbc_mutex);
+ return lines;
+}
+
+
+int hdpvr_set_bitrate(struct hdpvr_device *dev)
+{
+ int ret;
+
+ mutex_lock(&dev->usbc_mutex);
+ memset(dev->usbc_buf, 0, 4);
+ dev->usbc_buf[0] = dev->options.bitrate;
+ dev->usbc_buf[2] = dev->options.peak_bitrate;
+
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0x01, 0x38, CTRL_BITRATE_VALUE,
+ CTRL_DEFAULT_INDEX, dev->usbc_buf, 4, 1000);
+ mutex_unlock(&dev->usbc_mutex);
+
+ return ret;
+}
+
+int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
+ enum v4l2_mpeg_audio_encoding codec)
+{
+ int ret = 0;
+
+ if (dev->flags & HDPVR_FLAG_AC3_CAP) {
+ mutex_lock(&dev->usbc_mutex);
+ memset(dev->usbc_buf, 0, 2);
+ dev->usbc_buf[0] = input;
+ if (codec == V4L2_MPEG_AUDIO_ENCODING_AAC)
+ dev->usbc_buf[1] = 0;
+ else if (codec == V4L2_MPEG_AUDIO_ENCODING_AC3)
+ dev->usbc_buf[1] = 1;
+ else {
+ mutex_unlock(&dev->usbc_mutex);
+ v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n",
+ codec);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0x01, 0x38, CTRL_AUDIO_INPUT_VALUE,
+ CTRL_DEFAULT_INDEX, dev->usbc_buf, 2,
+ 1000);
+ mutex_unlock(&dev->usbc_mutex);
+ if (ret == 2)
+ ret = 0;
+ } else
+ ret = hdpvr_config_call(dev, CTRL_AUDIO_INPUT_VALUE,
+ dev->options.audio_input+1);
+error:
+ return ret;
+}
+
+int hdpvr_set_options(struct hdpvr_device *dev)
+{
+ hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, dev->options.video_std);
+
+ hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE,
+ dev->options.video_input+1);
+
+ hdpvr_set_audio(dev, dev->options.audio_input+1,
+ dev->options.audio_codec);
+
+ hdpvr_set_bitrate(dev);
+ hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+ dev->options.bitrate_mode);
+ hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, dev->options.gop_mode);
+
+ hdpvr_config_call(dev, CTRL_BRIGHTNESS, dev->options.brightness);
+ hdpvr_config_call(dev, CTRL_CONTRAST, dev->options.contrast);
+ hdpvr_config_call(dev, CTRL_HUE, dev->options.hue);
+ hdpvr_config_call(dev, CTRL_SATURATION, dev->options.saturation);
+ hdpvr_config_call(dev, CTRL_SHARPNESS, dev->options.sharpness);
+
+ return 0;
+}
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
new file mode 100644
index 00000000000..188bd5aea25
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -0,0 +1,466 @@
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ * Copyright (C) 2008 John Poet
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <asm/atomic.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/i2c.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-common.h>
+
+#include "hdpvr.h"
+
+static int video_nr[HDPVR_MAX] = {[0 ... (HDPVR_MAX - 1)] = UNSET};
+module_param_array(video_nr, int, NULL, 0);
+MODULE_PARM_DESC(video_nr, "video device number (-1=Auto)");
+
+/* holds the number of currently registered devices */
+static atomic_t dev_nr = ATOMIC_INIT(-1);
+
+int hdpvr_debug;
+module_param(hdpvr_debug, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(hdpvr_debug, "enable debugging output");
+
+uint default_video_input = HDPVR_VIDEO_INPUTS;
+module_param(default_video_input, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_video_input, "default video input: 0=Component / "
+ "1=S-Video / 2=Composite");
+
+uint default_audio_input = HDPVR_AUDIO_INPUTS;
+module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
+ "1=RCA front / 2=S/PDIF");
+
+static int boost_audio;
+module_param(boost_audio, bool, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(boost_audio, "boost the audio signal");
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id hdpvr_table[] = {
+ { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID) },
+ { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID1) },
+ { USB_DEVICE(HD_PVR_VENDOR_ID, HD_PVR_PRODUCT_ID2) },
+ { } /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, hdpvr_table);
+
+
+void hdpvr_delete(struct hdpvr_device *dev)
+{
+ hdpvr_free_buffers(dev);
+
+ if (dev->video_dev)
+ video_device_release(dev->video_dev);
+
+ usb_put_dev(dev->udev);
+}
+
+static void challenge(u8 *bytes)
+{
+ u64 *i64P, tmp64;
+ uint i, idx;
+
+ for (idx = 0; idx < 32; ++idx) {
+
+ if (idx & 0x3)
+ bytes[(idx >> 3) + 3] = bytes[(idx >> 2) & 0x3];
+
+ switch (idx & 0x3) {
+ case 0x3:
+ bytes[2] += bytes[3] * 4 + bytes[4] + bytes[5];
+ bytes[4] += bytes[(idx & 0x1) * 2] * 9 + 9;
+ break;
+ case 0x1:
+ bytes[0] *= 8;
+ bytes[0] += 7*idx + 4;
+ bytes[6] += bytes[3] * 3;
+ break;
+ case 0x0:
+ bytes[3 - (idx >> 3)] = bytes[idx >> 2];
+ bytes[5] += bytes[6] * 3;
+ for (i = 0; i < 3; i++)
+ bytes[3] *= bytes[3] + 1;
+ break;
+ case 0x2:
+ for (i = 0; i < 3; i++)
+ bytes[1] *= bytes[6] + 1;
+ for (i = 0; i < 3; i++) {
+ i64P = (u64 *)bytes;
+ tmp64 = le64_to_cpup(i64P);
+ tmp64 <<= bytes[7] & 0x0f;
+ *i64P += cpu_to_le64(tmp64);
+ }
+ break;
+ }
+ }
+}
+
+/* try to init the device like the windows driver */
+static int device_authorization(struct hdpvr_device *dev)
+{
+
+ int ret, retval = -ENOMEM;
+ char request_type = 0x38, rcv_request = 0x81;
+ char *response;
+#ifdef HDPVR_DEBUG
+ size_t buf_size = 46;
+ char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
+ if (!print_buf) {
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+ goto error;
+ }
+#endif
+
+ mutex_lock(&dev->usbc_mutex);
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ rcv_request, 0x80 | request_type,
+ 0x0400, 0x0003,
+ dev->usbc_buf, 46,
+ 10000);
+ if (ret != 46) {
+ v4l2_err(&dev->v4l2_dev,
+ "unexpected answer of status request, len %d\n", ret);
+ goto error;
+ }
+#ifdef HDPVR_DEBUG
+ else {
+ hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
+ sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "Status request returned, len %d: %s\n",
+ ret, print_buf);
+ }
+#endif
+ if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) {
+ dev->flags &= ~HDPVR_FLAG_AC3_CAP;
+ } else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
+ dev->flags |= HDPVR_FLAG_AC3_CAP;
+ } else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) {
+ v4l2_info(&dev->v4l2_dev, "untested firmware version 0x%x, "
+ "the driver might not work\n", dev->usbc_buf[1]);
+ dev->flags |= HDPVR_FLAG_AC3_CAP;
+ } else {
+ v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n",
+ dev->usbc_buf[1]);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ response = dev->usbc_buf+38;
+#ifdef HDPVR_DEBUG
+ hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n",
+ print_buf);
+#endif
+ challenge(response);
+#ifdef HDPVR_DEBUG
+ hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
+ print_buf);
+#endif
+
+ msleep(100);
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xd1, 0x00 | request_type,
+ 0x0000, 0x0000,
+ response, 8,
+ 10000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "magic request returned %d\n", ret);
+ mutex_unlock(&dev->usbc_mutex);
+
+ retval = ret != 8;
+error:
+ return retval;
+}
+
+static int hdpvr_device_init(struct hdpvr_device *dev)
+{
+ int ret;
+ u8 *buf;
+ struct hdpvr_video_info *vidinf;
+
+ if (device_authorization(dev))
+ return -EACCES;
+
+ /* default options for init */
+ hdpvr_set_options(dev);
+
+ /* set filter options */
+ mutex_lock(&dev->usbc_mutex);
+ buf = dev->usbc_buf;
+ buf[0] = 0x03; buf[1] = 0x03; buf[2] = 0x00; buf[3] = 0x00;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0x01, 0x38,
+ CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
+ buf, 4,
+ 1000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
+ mutex_unlock(&dev->usbc_mutex);
+
+ vidinf = get_video_info(dev);
+ if (!vidinf)
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "no valid video signal or device init failed\n");
+ else
+ kfree(vidinf);
+
+ /* enable fan and bling leds */
+ mutex_lock(&dev->usbc_mutex);
+ buf[0] = 0x1;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xd4, 0x38, 0, 0, buf, 1,
+ 1000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
+
+ /* boost analog audio */
+ buf[0] = boost_audio;
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xd5, 0x38, 0, 0, buf, 1,
+ 1000);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
+ mutex_unlock(&dev->usbc_mutex);
+
+ dev->status = STATUS_IDLE;
+ return 0;
+}
+
+static const struct hdpvr_options hdpvr_default_options = {
+ .video_std = HDPVR_60HZ,
+ .video_input = HDPVR_COMPONENT,
+ .audio_input = HDPVR_RCA_BACK,
+ .bitrate = 65, /* 6 mbps */
+ .peak_bitrate = 90, /* 9 mbps */
+ .bitrate_mode = HDPVR_CONSTANT,
+ .gop_mode = HDPVR_SIMPLE_IDR_GOP,
+ .audio_codec = V4L2_MPEG_AUDIO_ENCODING_AAC,
+ .brightness = 0x86,
+ .contrast = 0x80,
+ .hue = 0x80,
+ .saturation = 0x80,
+ .sharpness = 0x80,
+};
+
+static int hdpvr_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct hdpvr_device *dev;
+ struct usb_host_interface *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ size_t buffer_size;
+ int i;
+ int retval = -ENOMEM;
+
+ /* allocate memory for our device state and initialize it */
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev) {
+ err("Out of memory");
+ goto error;
+ }
+
+ /* register v4l2_device early so it can be used for printks */
+ if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+ err("v4l2_device_register failed");
+ goto error;
+ }
+
+ mutex_init(&dev->io_mutex);
+ mutex_init(&dev->i2c_mutex);
+ mutex_init(&dev->usbc_mutex);
+ dev->usbc_buf = kmalloc(64, GFP_KERNEL);
+ if (!dev->usbc_buf) {
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+ goto error;
+ }
+
+ init_waitqueue_head(&dev->wait_buffer);
+ init_waitqueue_head(&dev->wait_data);
+
+ dev->workqueue = create_singlethread_workqueue("hdpvr_buffer");
+ if (!dev->workqueue)
+ goto error;
+
+ /* init video transfer queues */
+ INIT_LIST_HEAD(&dev->free_buff_list);
+ INIT_LIST_HEAD(&dev->rec_buff_list);
+
+ dev->options = hdpvr_default_options;
+
+ if (default_video_input < HDPVR_VIDEO_INPUTS)
+ dev->options.video_input = default_video_input;
+
+ if (default_audio_input < HDPVR_AUDIO_INPUTS)
+ dev->options.audio_input = default_audio_input;
+
+ dev->udev = usb_get_dev(interface_to_usbdev(interface));
+
+ /* set up the endpoint information */
+ /* use only the first bulk-in and bulk-out endpoints */
+ iface_desc = interface->cur_altsetting;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if (!dev->bulk_in_endpointAddr &&
+ usb_endpoint_is_bulk_in(endpoint)) {
+ /* USB interface description is buggy, reported max
+ * packet size is 512 bytes, windows driver uses 8192 */
+ buffer_size = 8192;
+ dev->bulk_in_size = buffer_size;
+ dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+ }
+
+ }
+ if (!dev->bulk_in_endpointAddr) {
+ v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
+ goto error;
+ }
+
+ /* init the device */
+ if (hdpvr_device_init(dev)) {
+ v4l2_err(&dev->v4l2_dev, "device init failed\n");
+ goto error;
+ }
+
+ mutex_lock(&dev->io_mutex);
+ if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
+ v4l2_err(&dev->v4l2_dev,
+ "allocating transfer buffers failed\n");
+ goto error;
+ }
+ mutex_unlock(&dev->io_mutex);
+
+ if (hdpvr_register_videodev(dev, &interface->dev,
+ video_nr[atomic_inc_return(&dev_nr)])) {
+ v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
+ goto error;
+ }
+
+#ifdef CONFIG_I2C
+ /* until i2c is working properly */
+ retval = 0; /* hdpvr_register_i2c_adapter(dev); */
+ if (retval < 0) {
+ v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
+ goto error;
+ }
+#endif /* CONFIG_I2C */
+
+ /* save our data pointer in this interface device */
+ usb_set_intfdata(interface, dev);
+
+ /* let the user know what node this device is now attached to */
+ v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n",
+ dev->video_dev->minor);
+ return 0;
+
+error:
+ if (dev) {
+ mutex_unlock(&dev->io_mutex);
+ /* this frees allocated memory */
+ hdpvr_delete(dev);
+ }
+ return retval;
+}
+
+static void hdpvr_disconnect(struct usb_interface *interface)
+{
+ struct hdpvr_device *dev;
+ int minor;
+
+ dev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
+
+ minor = dev->video_dev->minor;
+
+ /* prevent more I/O from starting and stop any ongoing */
+ mutex_lock(&dev->io_mutex);
+ dev->status = STATUS_DISCONNECTED;
+ v4l2_device_disconnect(&dev->v4l2_dev);
+ video_unregister_device(dev->video_dev);
+ wake_up_interruptible(&dev->wait_data);
+ wake_up_interruptible(&dev->wait_buffer);
+ mutex_unlock(&dev->io_mutex);
+ msleep(100);
+ flush_workqueue(dev->workqueue);
+ mutex_lock(&dev->io_mutex);
+ hdpvr_cancel_queue(dev);
+ destroy_workqueue(dev->workqueue);
+ mutex_unlock(&dev->io_mutex);
+
+ /* deregister I2C adapter */
+#ifdef CONFIG_I2C
+ mutex_lock(&dev->i2c_mutex);
+ if (dev->i2c_adapter)
+ i2c_del_adapter(dev->i2c_adapter);
+ kfree(dev->i2c_adapter);
+ dev->i2c_adapter = NULL;
+ mutex_unlock(&dev->i2c_mutex);
+#endif /* CONFIG_I2C */
+
+ atomic_dec(&dev_nr);
+
+ v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev->usbc_buf);
+ kfree(dev);
+}
+
+
+static struct usb_driver hdpvr_usb_driver = {
+ .name = "hdpvr",
+ .probe = hdpvr_probe,
+ .disconnect = hdpvr_disconnect,
+ .id_table = hdpvr_table,
+};
+
+static int __init hdpvr_init(void)
+{
+ int result;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&hdpvr_usb_driver);
+ if (result)
+ err("usb_register failed. Error number %d", result);
+
+ return result;
+}
+
+static void __exit hdpvr_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&hdpvr_usb_driver);
+}
+
+module_init(hdpvr_init);
+module_exit(hdpvr_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Janne Grunau");
+MODULE_DESCRIPTION("Hauppauge HD PVR driver");
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
new file mode 100644
index 00000000000..c4b5d1515c1
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -0,0 +1,145 @@
+
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/i2c.h>
+
+#include "hdpvr.h"
+
+#define CTRL_READ_REQUEST 0xb8
+#define CTRL_WRITE_REQUEST 0x38
+
+#define REQTYPE_I2C_READ 0xb1
+#define REQTYPE_I2C_WRITE 0xb0
+#define REQTYPE_I2C_WRITE_STATT 0xd0
+
+static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr,
+ char *data, int len)
+{
+ int ret;
+ char *buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ REQTYPE_I2C_READ, CTRL_READ_REQUEST,
+ 0x100|addr, 0, buf, len, 1000);
+
+ if (ret == len) {
+ memcpy(data, buf, len);
+ ret = 0;
+ } else if (ret >= 0)
+ ret = -EIO;
+
+ kfree(buf);
+
+ return ret;
+}
+
+static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr,
+ char *data, int len)
+{
+ int ret;
+ char *buf = kmalloc(len, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ memcpy(buf, data, len);
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
+ 0x100|addr, 0, buf, len, 1000);
+
+ if (ret < 0)
+ goto error;
+
+ ret = usb_control_msg(dev->udev,
+ usb_rcvctrlpipe(dev->udev, 0),
+ REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
+ 0, 0, buf, 2, 1000);
+
+ if (ret == 2)
+ ret = 0;
+ else if (ret >= 0)
+ ret = -EIO;
+
+error:
+ kfree(buf);
+ return ret;
+}
+
+static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
+ int num)
+{
+ struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
+ int retval = 0, i, addr;
+
+ if (num <= 0)
+ return 0;
+
+ mutex_lock(&dev->i2c_mutex);
+
+ for (i = 0; i < num && !retval; i++) {
+ addr = msgs[i].addr << 1;
+
+ if (msgs[i].flags & I2C_M_RD)
+ retval = hdpvr_i2c_read(dev, addr, msgs[i].buf,
+ msgs[i].len);
+ else
+ retval = hdpvr_i2c_write(dev, addr, msgs[i].buf,
+ msgs[i].len);
+ }
+
+ mutex_unlock(&dev->i2c_mutex);
+
+ return retval ? retval : num;
+}
+
+static u32 hdpvr_functionality(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm hdpvr_algo = {
+ .master_xfer = hdpvr_transfer,
+ .functionality = hdpvr_functionality,
+};
+
+int hdpvr_register_i2c_adapter(struct hdpvr_device *dev)
+{
+ struct i2c_adapter *i2c_adap;
+ int retval = -ENOMEM;
+
+ i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL);
+ if (i2c_adap == NULL)
+ goto error;
+
+ strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C",
+ sizeof(i2c_adap->name));
+ i2c_adap->algo = &hdpvr_algo;
+ i2c_adap->class = I2C_CLASS_TV_ANALOG;
+ i2c_adap->id = I2C_HW_B_HDPVR;
+ i2c_adap->owner = THIS_MODULE;
+ i2c_adap->dev.parent = &dev->udev->dev;
+
+ i2c_set_adapdata(i2c_adap, dev);
+
+ retval = i2c_add_adapter(i2c_adap);
+
+ if (!retval)
+ dev->i2c_adapter = i2c_adap;
+ else
+ kfree(i2c_adap);
+
+error:
+ return retval;
+}
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
new file mode 100644
index 00000000000..3e6ffee8dfe
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -0,0 +1,1248 @@
+/*
+ * Hauppauge HD PVR USB driver - video 4 linux 2 interface
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/mutex.h>
+#include <linux/version.h>
+#include <linux/workqueue.h>
+
+#include <linux/videodev2.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-ioctl.h>
+#include "hdpvr.h"
+
+#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */
+
+#define print_buffer_status() { \
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \
+ "%s:%d buffer stat: %d free, %d proc\n", \
+ __func__, __LINE__, \
+ list_size(&dev->free_buff_list), \
+ list_size(&dev->rec_buff_list)); }
+
+struct hdpvr_fh {
+ struct hdpvr_device *dev;
+};
+
+static uint list_size(struct list_head *list)
+{
+ struct list_head *tmp;
+ uint count = 0;
+
+ list_for_each(tmp, list) {
+ count++;
+ }
+
+ return count;
+}
+
+/*=========================================================================*/
+/* urb callback */
+static void hdpvr_read_bulk_callback(struct urb *urb)
+{
+ struct hdpvr_buffer *buf = (struct hdpvr_buffer *)urb->context;
+ struct hdpvr_device *dev = buf->dev;
+
+ /* marking buffer as received and wake waiting */
+ buf->status = BUFSTAT_READY;
+ wake_up_interruptible(&dev->wait_data);
+}
+
+/*=========================================================================*/
+/* bufffer bits */
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_cancel_queue(struct hdpvr_device *dev)
+{
+ struct hdpvr_buffer *buf;
+
+ list_for_each_entry(buf, &dev->rec_buff_list, buff_list) {
+ usb_kill_urb(buf->urb);
+ buf->status = BUFSTAT_AVAILABLE;
+ }
+
+ list_splice_init(&dev->rec_buff_list, dev->free_buff_list.prev);
+
+ return 0;
+}
+
+static int hdpvr_free_queue(struct list_head *q)
+{
+ struct list_head *tmp;
+ struct list_head *p;
+ struct hdpvr_buffer *buf;
+ struct urb *urb;
+
+ for (p = q->next; p != q;) {
+ buf = list_entry(p, struct hdpvr_buffer, buff_list);
+
+ urb = buf->urb;
+ usb_buffer_free(urb->dev, urb->transfer_buffer_length,
+ urb->transfer_buffer, urb->transfer_dma);
+ usb_free_urb(urb);
+ tmp = p->next;
+ list_del(p);
+ kfree(buf);
+ p = tmp;
+ }
+
+ return 0;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_free_buffers(struct hdpvr_device *dev)
+{
+ hdpvr_cancel_queue(dev);
+
+ hdpvr_free_queue(&dev->free_buff_list);
+ hdpvr_free_queue(&dev->rec_buff_list);
+
+ return 0;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
+{
+ uint i;
+ int retval = -ENOMEM;
+ u8 *mem;
+ struct hdpvr_buffer *buf;
+ struct urb *urb;
+
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "allocating %u buffers\n", count);
+
+ for (i = 0; i < count; i++) {
+
+ buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
+ if (!buf) {
+ v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
+ goto exit;
+ }
+ buf->dev = dev;
+
+ urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!urb) {
+ v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
+ goto exit;
+ }
+ buf->urb = urb;
+
+ mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
+ &urb->transfer_dma);
+ if (!mem) {
+ v4l2_err(&dev->v4l2_dev,
+ "cannot allocate usb transfer buffer\n");
+ goto exit;
+ }
+
+ usb_fill_bulk_urb(buf->urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in_endpointAddr),
+ mem, dev->bulk_in_size,
+ hdpvr_read_bulk_callback, buf);
+
+ buf->status = BUFSTAT_AVAILABLE;
+ list_add_tail(&buf->buff_list, &dev->free_buff_list);
+ }
+ return 0;
+exit:
+ hdpvr_free_buffers(dev);
+ return retval;
+}
+
+static int hdpvr_submit_buffers(struct hdpvr_device *dev)
+{
+ struct hdpvr_buffer *buf;
+ struct urb *urb;
+ int ret = 0, err_count = 0;
+
+ mutex_lock(&dev->io_mutex);
+
+ while (dev->status == STATUS_STREAMING &&
+ !list_empty(&dev->free_buff_list)) {
+
+ buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
+ buff_list);
+ if (buf->status != BUFSTAT_AVAILABLE) {
+ v4l2_err(&dev->v4l2_dev,
+ "buffer not marked as availbale\n");
+ ret = -EFAULT;
+ goto err;
+ }
+
+ urb = buf->urb;
+ urb->status = 0;
+ urb->actual_length = 0;
+ ret = usb_submit_urb(urb, GFP_KERNEL);
+ if (ret) {
+ v4l2_err(&dev->v4l2_dev,
+ "usb_submit_urb in %s returned %d\n",
+ __func__, ret);
+ if (++err_count > 2)
+ break;
+ continue;
+ }
+ buf->status = BUFSTAT_INPROGRESS;
+ list_move_tail(&buf->buff_list, &dev->rec_buff_list);
+ }
+err:
+ print_buffer_status();
+ mutex_unlock(&dev->io_mutex);
+ return ret;
+}
+
+static struct hdpvr_buffer *hdpvr_get_next_buffer(struct hdpvr_device *dev)
+{
+ struct hdpvr_buffer *buf;
+
+ mutex_lock(&dev->io_mutex);
+
+ if (list_empty(&dev->rec_buff_list)) {
+ mutex_unlock(&dev->io_mutex);
+ return NULL;
+ }
+
+ buf = list_entry(dev->rec_buff_list.next, struct hdpvr_buffer,
+ buff_list);
+ mutex_unlock(&dev->io_mutex);
+
+ return buf;
+}
+
+static void hdpvr_transmit_buffers(struct work_struct *work)
+{
+ struct hdpvr_device *dev = container_of(work, struct hdpvr_device,
+ worker);
+
+ while (dev->status == STATUS_STREAMING) {
+
+ if (hdpvr_submit_buffers(dev)) {
+ v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
+ goto error;
+ }
+ if (wait_event_interruptible(dev->wait_buffer,
+ !list_empty(&dev->free_buff_list) ||
+ dev->status != STATUS_STREAMING))
+ goto error;
+ }
+
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "transmit worker exited\n");
+ return;
+error:
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "transmit buffers errored\n");
+ dev->status = STATUS_ERROR;
+}
+
+/* function expects dev->io_mutex to be hold by caller */
+static int hdpvr_start_streaming(struct hdpvr_device *dev)
+{
+ int ret;
+ struct hdpvr_video_info *vidinf;
+
+ if (dev->status == STATUS_STREAMING)
+ return 0;
+ else if (dev->status != STATUS_IDLE)
+ return -EAGAIN;
+
+ vidinf = get_video_info(dev);
+
+ if (vidinf) {
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "video signal: %dx%d@%dhz\n", vidinf->width,
+ vidinf->height, vidinf->fps);
+ kfree(vidinf);
+
+ /* start streaming 2 request */
+ ret = usb_control_msg(dev->udev,
+ usb_sndctrlpipe(dev->udev, 0),
+ 0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "encoder start control request returned %d\n", ret);
+
+ hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+
+ INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
+ queue_work(dev->workqueue, &dev->worker);
+
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "streaming started\n");
+ dev->status = STATUS_STREAMING;
+
+ return 0;
+ }
+ msleep(250);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "no video signal at input %d\n", dev->options.video_input);
+ return -EAGAIN;
+}
+
+
+/* function expects dev->io_mutex to be hold by caller */
+static int hdpvr_stop_streaming(struct hdpvr_device *dev)
+{
+ uint actual_length, c = 0;
+ u8 *buf;
+
+ if (dev->status == STATUS_IDLE)
+ return 0;
+ else if (dev->status != STATUS_STREAMING)
+ return -EAGAIN;
+
+ buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
+ if (!buf)
+ v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
+ "for emptying the internal device buffer. "
+ "Next capture start will be slow\n");
+
+ dev->status = STATUS_SHUTTING_DOWN;
+ hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
+ mutex_unlock(&dev->io_mutex);
+
+ wake_up_interruptible(&dev->wait_buffer);
+ msleep(50);
+
+ flush_workqueue(dev->workqueue);
+
+ mutex_lock(&dev->io_mutex);
+ /* kill the still outstanding urbs */
+ hdpvr_cancel_queue(dev);
+
+ /* emptying the device buffer beforeshutting it down */
+ while (buf && ++c < 500 &&
+ !usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in_endpointAddr),
+ buf, dev->bulk_in_size, &actual_length,
+ BULK_URB_TIMEOUT)) {
+ /* wait */
+ msleep(5);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "%2d: got %d bytes\n", c, actual_length);
+ }
+ kfree(buf);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "used %d urbs to empty device buffers\n", c-1);
+ msleep(10);
+
+ dev->status = STATUS_IDLE;
+
+ return 0;
+}
+
+
+/*=======================================================================*/
+/*
+ * video 4 linux 2 file operations
+ */
+
+static int hdpvr_open(struct file *file)
+{
+ struct hdpvr_device *dev;
+ struct hdpvr_fh *fh;
+ int retval = -ENOMEM;
+
+ dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
+ if (!dev) {
+ v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n");
+ retval = -ENODEV;
+ goto err;
+ }
+
+ fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
+ if (!fh) {
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
+ goto err;
+ }
+ /* lock the device to allow correctly handling errors
+ * in resumption */
+ mutex_lock(&dev->io_mutex);
+ dev->open_count++;
+
+ fh->dev = dev;
+
+ /* save our object in the file's private structure */
+ file->private_data = fh;
+
+ retval = 0;
+err:
+ mutex_unlock(&dev->io_mutex);
+ return retval;
+}
+
+static int hdpvr_release(struct file *file)
+{
+ struct hdpvr_fh *fh = (struct hdpvr_fh *)file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->io_mutex);
+ if (!(--dev->open_count) && dev->status == STATUS_STREAMING)
+ hdpvr_stop_streaming(dev);
+
+ mutex_unlock(&dev->io_mutex);
+
+ return 0;
+}
+
+/*
+ * hdpvr_v4l2_read()
+ * will allocate buffers when called for the first time
+ */
+static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
+ loff_t *pos)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ struct hdpvr_buffer *buf = NULL;
+ struct urb *urb;
+ unsigned int ret = 0;
+ int rem, cnt;
+
+ if (*pos)
+ return -ESPIPE;
+
+ if (!dev)
+ return -ENODEV;
+
+ mutex_lock(&dev->io_mutex);
+ if (dev->status == STATUS_IDLE) {
+ if (hdpvr_start_streaming(dev)) {
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
+ ret = -EIO;
+ msleep(200);
+ dev->status = STATUS_IDLE;
+ mutex_unlock(&dev->io_mutex);
+ goto err;
+ }
+ print_buffer_status();
+ }
+ mutex_unlock(&dev->io_mutex);
+
+ /* wait for the first buffer */
+ if (!(file->f_flags & O_NONBLOCK)) {
+ if (wait_event_interruptible(dev->wait_data,
+ hdpvr_get_next_buffer(dev)))
+ return -ERESTARTSYS;
+ }
+
+ buf = hdpvr_get_next_buffer(dev);
+
+ while (count > 0 && buf) {
+
+ if (buf->status != BUFSTAT_READY &&
+ dev->status != STATUS_DISCONNECTED) {
+ /* return nonblocking */
+ if (file->f_flags & O_NONBLOCK) {
+ if (!ret)
+ ret = -EAGAIN;
+ goto err;
+ }
+
+ if (wait_event_interruptible(dev->wait_data,
+ buf->status == BUFSTAT_READY)) {
+ ret = -ERESTARTSYS;
+ goto err;
+ }
+ }
+
+ if (buf->status != BUFSTAT_READY)
+ break;
+
+ /* set remaining bytes to copy */
+ urb = buf->urb;
+ rem = urb->actual_length - buf->pos;
+ cnt = rem > count ? count : rem;
+
+ if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
+ cnt)) {
+ v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
+ if (!ret)
+ ret = -EFAULT;
+ goto err;
+ }
+
+ buf->pos += cnt;
+ count -= cnt;
+ buffer += cnt;
+ ret += cnt;
+
+ /* finished, take next buffer */
+ if (buf->pos == urb->actual_length) {
+ mutex_lock(&dev->io_mutex);
+ buf->pos = 0;
+ buf->status = BUFSTAT_AVAILABLE;
+
+ list_move_tail(&buf->buff_list, &dev->free_buff_list);
+
+ print_buffer_status();
+
+ mutex_unlock(&dev->io_mutex);
+
+ wake_up_interruptible(&dev->wait_buffer);
+
+ buf = hdpvr_get_next_buffer(dev);
+ }
+ }
+err:
+ if (!ret && !buf)
+ ret = -EAGAIN;
+ return ret;
+}
+
+static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
+{
+ struct hdpvr_buffer *buf = NULL;
+ struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ unsigned int mask = 0;
+
+ mutex_lock(&dev->io_mutex);
+
+ if (video_is_unregistered(dev->video_dev))
+ return -EIO;
+
+ if (dev->status == STATUS_IDLE) {
+ if (hdpvr_start_streaming(dev)) {
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
+ dev->status = STATUS_IDLE;
+ }
+
+ print_buffer_status();
+ }
+ mutex_unlock(&dev->io_mutex);
+
+ buf = hdpvr_get_next_buffer(dev);
+ /* only wait if no data is available */
+ if (!buf || buf->status != BUFSTAT_READY) {
+ poll_wait(filp, &dev->wait_data, wait);
+ buf = hdpvr_get_next_buffer(dev);
+ }
+ if (buf && buf->status == BUFSTAT_READY)
+ mask |= POLLIN | POLLRDNORM;
+
+ return mask;
+}
+
+
+static const struct v4l2_file_operations hdpvr_fops = {
+ .owner = THIS_MODULE,
+ .open = hdpvr_open,
+ .release = hdpvr_release,
+ .read = hdpvr_read,
+ .poll = hdpvr_poll,
+ .unlocked_ioctl = video_ioctl2,
+};
+
+/*=======================================================================*/
+/*
+ * V4L2 ioctl handling
+ */
+
+static int vidioc_querycap(struct file *file, void *priv,
+ struct v4l2_capability *cap)
+{
+ struct hdpvr_device *dev = video_drvdata(file);
+
+ strcpy(cap->driver, "hdpvr");
+ strcpy(cap->card, "Haupauge HD PVR");
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
+ cap->version = HDPVR_VERSION;
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_AUDIO |
+ V4L2_CAP_READWRITE;
+ return 0;
+}
+
+static int vidioc_s_std(struct file *file, void *private_data,
+ v4l2_std_id *std)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ u8 std_type = 1;
+
+ if (*std & (V4L2_STD_NTSC | V4L2_STD_PAL_60))
+ std_type = 0;
+
+ return hdpvr_config_call(dev, CTRL_VIDEO_STD_TYPE, std_type);
+}
+
+static const char *iname[] = {
+ [HDPVR_COMPONENT] = "Component",
+ [HDPVR_SVIDEO] = "S-Video",
+ [HDPVR_COMPOSITE] = "Composite",
+};
+
+static int vidioc_enum_input(struct file *file, void *priv,
+ struct v4l2_input *i)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ unsigned int n;
+
+ n = i->index;
+ if (n >= HDPVR_VIDEO_INPUTS)
+ return -EINVAL;
+
+ i->type = V4L2_INPUT_TYPE_CAMERA;
+
+ strncpy(i->name, iname[n], sizeof(i->name) - 1);
+ i->name[sizeof(i->name) - 1] = '\0';
+
+ i->audioset = 1<<HDPVR_RCA_FRONT | 1<<HDPVR_RCA_BACK | 1<<HDPVR_SPDIF;
+
+ i->std = dev->video_dev->tvnorms;
+
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *private_data,
+ unsigned int index)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int retval;
+
+ if (index >= HDPVR_VIDEO_INPUTS)
+ return -EINVAL;
+
+ if (dev->status != STATUS_IDLE)
+ return -EAGAIN;
+
+ retval = hdpvr_config_call(dev, CTRL_VIDEO_INPUT_VALUE, index+1);
+ if (!retval)
+ dev->options.video_input = index;
+
+ return retval;
+}
+
+static int vidioc_g_input(struct file *file, void *private_data,
+ unsigned int *index)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ *index = dev->options.video_input;
+ return 0;
+}
+
+
+static const char *audio_iname[] = {
+ [HDPVR_RCA_FRONT] = "RCA front",
+ [HDPVR_RCA_BACK] = "RCA back",
+ [HDPVR_SPDIF] = "SPDIF",
+};
+
+static int vidioc_enumaudio(struct file *file, void *priv,
+ struct v4l2_audio *audio)
+{
+ unsigned int n;
+
+ n = audio->index;
+ if (n >= HDPVR_AUDIO_INPUTS)
+ return -EINVAL;
+
+ audio->capability = V4L2_AUDCAP_STEREO;
+
+ strncpy(audio->name, audio_iname[n], sizeof(audio->name) - 1);
+ audio->name[sizeof(audio->name) - 1] = '\0';
+
+ return 0;
+}
+
+static int vidioc_s_audio(struct file *file, void *private_data,
+ struct v4l2_audio *audio)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int retval;
+
+ if (audio->index >= HDPVR_AUDIO_INPUTS)
+ return -EINVAL;
+
+ if (dev->status != STATUS_IDLE)
+ return -EAGAIN;
+
+ retval = hdpvr_set_audio(dev, audio->index+1, dev->options.audio_codec);
+ if (!retval)
+ dev->options.audio_input = audio->index;
+
+ return retval;
+}
+
+static int vidioc_g_audio(struct file *file, void *private_data,
+ struct v4l2_audio *audio)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ audio->index = dev->options.audio_input;
+ audio->capability = V4L2_AUDCAP_STEREO;
+ strncpy(audio->name, audio_iname[audio->index], sizeof(audio->name));
+ audio->name[sizeof(audio->name) - 1] = '\0';
+ return 0;
+}
+
+static const s32 supported_v4l2_ctrls[] = {
+ V4L2_CID_BRIGHTNESS,
+ V4L2_CID_CONTRAST,
+ V4L2_CID_SATURATION,
+ V4L2_CID_HUE,
+ V4L2_CID_SHARPNESS,
+ V4L2_CID_MPEG_AUDIO_ENCODING,
+ V4L2_CID_MPEG_VIDEO_ENCODING,
+ V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
+ V4L2_CID_MPEG_VIDEO_BITRATE,
+ V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
+};
+
+static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
+ int ac3)
+{
+ int err;
+
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_SHARPNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ return v4l2_ctrl_query_fill(
+ qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
+ ac3 ? V4L2_MPEG_AUDIO_ENCODING_AC3
+ : V4L2_MPEG_AUDIO_ENCODING_AAC,
+ 1, V4L2_MPEG_AUDIO_ENCODING_AAC);
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ return v4l2_ctrl_query_fill(
+ qc, V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
+ V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC);
+
+/* case V4L2_CID_MPEG_VIDEO_? maybe keyframe interval: */
+/* return v4l2_ctrl_query_fill(qc, 0, 128, 128, 0); */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ return v4l2_ctrl_query_fill(
+ qc, V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR);
+
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(qc, 1000000, 13500000, 100000,
+ 6500000);
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ err = v4l2_ctrl_query_fill(qc, 1100000, 20200000, 100000,
+ 9000000);
+ if (!err && opt->bitrate_mode == HDPVR_CONSTANT)
+ qc->flags |= V4L2_CTRL_FLAG_INACTIVE;
+ return err;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int vidioc_queryctrl(struct file *file, void *private_data,
+ struct v4l2_queryctrl *qc)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, next;
+ u32 id = qc->id;
+
+ memset(qc, 0, sizeof(*qc));
+
+ next = !!(id & V4L2_CTRL_FLAG_NEXT_CTRL);
+ qc->id = id & ~V4L2_CTRL_FLAG_NEXT_CTRL;
+
+ for (i = 0; i < ARRAY_SIZE(supported_v4l2_ctrls); i++) {
+ if (next) {
+ if (qc->id < supported_v4l2_ctrls[i])
+ qc->id = supported_v4l2_ctrls[i];
+ else
+ continue;
+ }
+
+ if (qc->id == supported_v4l2_ctrls[i])
+ return fill_queryctrl(&dev->options, qc,
+ dev->flags & HDPVR_FLAG_AC3_CAP);
+
+ if (qc->id < supported_v4l2_ctrls[i])
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *private_data,
+ struct v4l2_control *ctrl)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = dev->options.brightness;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = dev->options.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = dev->options.saturation;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = dev->options.hue;
+ break;
+ case V4L2_CID_SHARPNESS:
+ ctrl->value = dev->options.sharpness;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *private_data,
+ struct v4l2_control *ctrl)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int retval;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ retval = hdpvr_config_call(dev, CTRL_BRIGHTNESS, ctrl->value);
+ if (!retval)
+ dev->options.brightness = ctrl->value;
+ break;
+ case V4L2_CID_CONTRAST:
+ retval = hdpvr_config_call(dev, CTRL_CONTRAST, ctrl->value);
+ if (!retval)
+ dev->options.contrast = ctrl->value;
+ break;
+ case V4L2_CID_SATURATION:
+ retval = hdpvr_config_call(dev, CTRL_SATURATION, ctrl->value);
+ if (!retval)
+ dev->options.saturation = ctrl->value;
+ break;
+ case V4L2_CID_HUE:
+ retval = hdpvr_config_call(dev, CTRL_HUE, ctrl->value);
+ if (!retval)
+ dev->options.hue = ctrl->value;
+ break;
+ case V4L2_CID_SHARPNESS:
+ retval = hdpvr_config_call(dev, CTRL_SHARPNESS, ctrl->value);
+ if (!retval)
+ dev->options.sharpness = ctrl->value;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return retval;
+}
+
+
+static int hdpvr_get_ctrl(struct hdpvr_options *opt,
+ struct v4l2_ext_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ ctrl->value = opt->audio_codec;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC;
+ break;
+/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* ctrl->value = (opt->gop_mode & 0x2) ? 0 : 128; */
+/* break; */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ ctrl->value = opt->bitrate_mode == HDPVR_CONSTANT
+ ? V4L2_MPEG_VIDEO_BITRATE_MODE_CBR
+ : V4L2_MPEG_VIDEO_BITRATE_MODE_VBR;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ ctrl->value = opt->bitrate * 100000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ ctrl->value = opt->peak_bitrate * 100000;
+ break;
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_g_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, err = 0;
+
+ if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+ err = hdpvr_get_ctrl(&dev->options, ctrl);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+
+ }
+
+ return -EINVAL;
+}
+
+
+static int hdpvr_try_ctrl(struct v4l2_ext_control *ctrl, int ac3)
+{
+ int ret = -EINVAL;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AAC ||
+ (ac3 && ctrl->value == V4L2_MPEG_AUDIO_ENCODING_AC3))
+ ret = 0;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ if (ctrl->value == V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC)
+ ret = 0;
+ break;
+/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* if (ctrl->value == 0 || ctrl->value == 128) */
+/* ret = 0; */
+/* break; */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR ||
+ ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR)
+ ret = 0;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ {
+ uint bitrate = ctrl->value / 100000;
+ if (bitrate >= 10 && bitrate <= 135)
+ ret = 0;
+ break;
+ }
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ {
+ uint peak_bitrate = ctrl->value / 100000;
+ if (peak_bitrate >= 10 && peak_bitrate <= 202)
+ ret = 0;
+ break;
+ }
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ if (ctrl->value == V4L2_MPEG_STREAM_TYPE_MPEG2_TS)
+ ret = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int vidioc_try_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, err = 0;
+
+ if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+ err = hdpvr_try_ctrl(ctrl,
+ dev->flags & HDPVR_FLAG_AC3_CAP);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+ }
+
+ return -EINVAL;
+}
+
+
+static int hdpvr_set_ctrl(struct hdpvr_device *dev,
+ struct v4l2_ext_control *ctrl)
+{
+ struct hdpvr_options *opt = &dev->options;
+ int ret = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ if (dev->flags & HDPVR_FLAG_AC3_CAP) {
+ opt->audio_codec = ctrl->value;
+ ret = hdpvr_set_audio(dev, opt->audio_input,
+ opt->audio_codec);
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ break;
+/* case V4L2_CID_MPEG_VIDEO_B_FRAMES: */
+/* if (ctrl->value == 0 && !(opt->gop_mode & 0x2)) { */
+/* opt->gop_mode |= 0x2; */
+/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* opt->gop_mode); */
+/* } */
+/* if (ctrl->value == 128 && opt->gop_mode & 0x2) { */
+/* opt->gop_mode &= ~0x2; */
+/* hdpvr_config_call(dev, CTRL_GOP_MODE_VALUE, */
+/* opt->gop_mode); */
+/* } */
+/* break; */
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR &&
+ opt->bitrate_mode != HDPVR_CONSTANT) {
+ opt->bitrate_mode = HDPVR_CONSTANT;
+ hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+ opt->bitrate_mode);
+ }
+ if (ctrl->value == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
+ opt->bitrate_mode == HDPVR_CONSTANT) {
+ opt->bitrate_mode = HDPVR_VARIABLE_AVERAGE;
+ hdpvr_config_call(dev, CTRL_BITRATE_MODE_VALUE,
+ opt->bitrate_mode);
+ }
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE: {
+ uint bitrate = ctrl->value / 100000;
+
+ opt->bitrate = bitrate;
+ if (bitrate >= opt->peak_bitrate)
+ opt->peak_bitrate = bitrate+1;
+
+ hdpvr_set_bitrate(dev);
+ break;
+ }
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK: {
+ uint peak_bitrate = ctrl->value / 100000;
+
+ if (opt->bitrate_mode == HDPVR_CONSTANT)
+ break;
+
+ if (opt->bitrate < peak_bitrate) {
+ opt->peak_bitrate = peak_bitrate;
+ hdpvr_set_bitrate(dev);
+ } else
+ ret = -EINVAL;
+ break;
+ }
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ break;
+ default:
+ return -EINVAL;
+ }
+ return ret;
+}
+
+static int vidioc_s_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int i, err = 0;
+
+ if (ctrls->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
+ for (i = 0; i < ctrls->count; i++) {
+ struct v4l2_ext_control *ctrl = ctrls->controls + i;
+
+ err = hdpvr_try_ctrl(ctrl,
+ dev->flags & HDPVR_FLAG_AC3_CAP);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ err = hdpvr_set_ctrl(dev, ctrl);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+
+ }
+
+ return -EINVAL;
+}
+
+static int vidioc_enum_fmt_vid_cap(struct file *file, void *private_data,
+ struct v4l2_fmtdesc *f)
+{
+
+ if (f->index != 0 || f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ f->flags = V4L2_FMT_FLAG_COMPRESSED;
+ strncpy(f->description, "MPEG2-TS with AVC/AAC streams", 32);
+ f->pixelformat = V4L2_PIX_FMT_MPEG;
+
+ return 0;
+}
+
+static int vidioc_g_fmt_vid_cap(struct file *file, void *private_data,
+ struct v4l2_format *f)
+{
+ struct hdpvr_fh *fh = file->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ struct hdpvr_video_info *vid_info;
+
+ if (!dev)
+ return -ENODEV;
+
+ vid_info = get_video_info(dev);
+ if (!vid_info)
+ return -EFAULT;
+
+ f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
+ f->fmt.pix.width = vid_info->width;
+ f->fmt.pix.height = vid_info->height;
+ f->fmt.pix.sizeimage = dev->bulk_in_size;
+ f->fmt.pix.colorspace = 0;
+ f->fmt.pix.bytesperline = 0;
+ f->fmt.pix.field = V4L2_FIELD_ANY;
+
+ kfree(vid_info);
+ return 0;
+}
+
+static int vidioc_encoder_cmd(struct file *filp, void *priv,
+ struct v4l2_encoder_cmd *a)
+{
+ struct hdpvr_fh *fh = filp->private_data;
+ struct hdpvr_device *dev = fh->dev;
+ int res;
+
+ mutex_lock(&dev->io_mutex);
+
+ memset(&a->raw, 0, sizeof(a->raw));
+ switch (a->cmd) {
+ case V4L2_ENC_CMD_START:
+ a->flags = 0;
+ res = hdpvr_start_streaming(dev);
+ break;
+ case V4L2_ENC_CMD_STOP:
+ res = hdpvr_stop_streaming(dev);
+ break;
+ default:
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "Unsupported encoder cmd %d\n", a->cmd);
+ res = -EINVAL;
+ }
+ mutex_unlock(&dev->io_mutex);
+ return res;
+}
+
+static int vidioc_try_encoder_cmd(struct file *filp, void *priv,
+ struct v4l2_encoder_cmd *a)
+{
+ switch (a->cmd) {
+ case V4L2_ENC_CMD_START:
+ case V4L2_ENC_CMD_STOP:
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct v4l2_ioctl_ops hdpvr_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_s_std = vidioc_s_std,
+ .vidioc_enum_input = vidioc_enum_input,
+ .vidioc_g_input = vidioc_g_input,
+ .vidioc_s_input = vidioc_s_input,
+ .vidioc_enumaudio = vidioc_enumaudio,
+ .vidioc_g_audio = vidioc_g_audio,
+ .vidioc_s_audio = vidioc_s_audio,
+ .vidioc_queryctrl = vidioc_queryctrl,
+ .vidioc_g_ctrl = vidioc_g_ctrl,
+ .vidioc_s_ctrl = vidioc_s_ctrl,
+ .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
+ .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
+ .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
+ .vidioc_encoder_cmd = vidioc_encoder_cmd,
+ .vidioc_try_encoder_cmd = vidioc_try_encoder_cmd,
+};
+
+static void hdpvr_device_release(struct video_device *vdev)
+{
+ struct hdpvr_device *dev = video_get_drvdata(vdev);
+
+ hdpvr_delete(dev);
+}
+
+static const struct video_device hdpvr_video_template = {
+/* .type = VFL_TYPE_GRABBER, */
+/* .type2 = VID_TYPE_CAPTURE | VID_TYPE_MPEG_ENCODER, */
+ .fops = &hdpvr_fops,
+ .release = hdpvr_device_release,
+ .ioctl_ops = &hdpvr_ioctl_ops,
+ .tvnorms =
+ V4L2_STD_NTSC | V4L2_STD_SECAM | V4L2_STD_PAL_B |
+ V4L2_STD_PAL_G | V4L2_STD_PAL_H | V4L2_STD_PAL_I |
+ V4L2_STD_PAL_D | V4L2_STD_PAL_M | V4L2_STD_PAL_N |
+ V4L2_STD_PAL_60,
+};
+
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+ int devnum)
+{
+ /* setup and register video device */
+ dev->video_dev = video_device_alloc();
+ if (!dev->video_dev) {
+ v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
+ goto error;
+ }
+
+ *(dev->video_dev) = hdpvr_video_template;
+ strcpy(dev->video_dev->name, "Hauppauge HD PVR");
+ dev->video_dev->parent = parent;
+ video_set_drvdata(dev->video_dev, dev);
+
+ if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
+ v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
+ goto error;
+ }
+
+ return 0;
+error:
+ return -ENOMEM;
+}
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
new file mode 100644
index 00000000000..1edd8759121
--- /dev/null
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -0,0 +1,303 @@
+/*
+ * Hauppauge HD PVR USB driver
+ *
+ * Copyright (C) 2008 Janne Grunau (j@jannau.net)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include <linux/usb.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/workqueue.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+
+#define HDPVR_MAJOR_VERSION 0
+#define HDPVR_MINOR_VERSION 2
+#define HDPVR_RELEASE 0
+#define HDPVR_VERSION \
+ KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE)
+
+#define HDPVR_MAX 8
+
+/* Define these values to match your devices */
+#define HD_PVR_VENDOR_ID 0x2040
+#define HD_PVR_PRODUCT_ID 0x4900
+#define HD_PVR_PRODUCT_ID1 0x4901
+#define HD_PVR_PRODUCT_ID2 0x4902
+
+#define UNSET (-1U)
+
+#define NUM_BUFFERS 64
+
+#define HDPVR_FIRMWARE_VERSION 0x8
+#define HDPVR_FIRMWARE_VERSION_AC3 0xd
+
+/* #define HDPVR_DEBUG */
+
+extern int hdpvr_debug;
+
+#define MSG_INFO 1
+#define MSG_BUFFER 2
+
+struct hdpvr_options {
+ u8 video_std;
+ u8 video_input;
+ u8 audio_input;
+ u8 bitrate; /* in 100kbps */
+ u8 peak_bitrate; /* in 100kbps */
+ u8 bitrate_mode;
+ u8 gop_mode;
+ enum v4l2_mpeg_audio_encoding audio_codec;
+ u8 brightness;
+ u8 contrast;
+ u8 hue;
+ u8 saturation;
+ u8 sharpness;
+};
+
+/* Structure to hold all of our device specific stuff */
+struct hdpvr_device {
+ /* the v4l device for this device */
+ struct video_device *video_dev;
+ /* the usb device for this device */
+ struct usb_device *udev;
+ /* v4l2-device unused */
+ struct v4l2_device v4l2_dev;
+
+ /* the max packet size of the bulk endpoint */
+ size_t bulk_in_size;
+ /* the address of the bulk in endpoint */
+ __u8 bulk_in_endpointAddr;
+
+ /* holds the current device status */
+ __u8 status;
+ /* count the number of openers */
+ uint open_count;
+
+ /* holds the cureent set options */
+ struct hdpvr_options options;
+
+ uint flags;
+
+ /* synchronize I/O */
+ struct mutex io_mutex;
+ /* available buffers */
+ struct list_head free_buff_list;
+ /* in progress buffers */
+ struct list_head rec_buff_list;
+ /* waitqueue for buffers */
+ wait_queue_head_t wait_buffer;
+ /* waitqueue for data */
+ wait_queue_head_t wait_data;
+ /**/
+ struct workqueue_struct *workqueue;
+ /**/
+ struct work_struct worker;
+
+ /* I2C adapter */
+ struct i2c_adapter *i2c_adapter;
+ /* I2C lock */
+ struct mutex i2c_mutex;
+
+ /* usb control transfer buffer and lock */
+ struct mutex usbc_mutex;
+ u8 *usbc_buf;
+};
+
+
+/* buffer one bulk urb of data */
+struct hdpvr_buffer {
+ struct list_head buff_list;
+
+ struct urb *urb;
+
+ struct hdpvr_device *dev;
+
+ uint pos;
+
+ __u8 status;
+};
+
+/* */
+
+struct hdpvr_video_info {
+ u16 width;
+ u16 height;
+ u8 fps;
+};
+
+enum {
+ STATUS_UNINITIALIZED = 0,
+ STATUS_IDLE,
+ STATUS_STARTING,
+ STATUS_SHUTTING_DOWN,
+ STATUS_STREAMING,
+ STATUS_ERROR,
+ STATUS_DISCONNECTED,
+};
+
+enum {
+ HDPVR_FLAG_AC3_CAP = 1,
+};
+
+enum {
+ BUFSTAT_UNINITIALIZED = 0,
+ BUFSTAT_AVAILABLE,
+ BUFSTAT_INPROGRESS,
+ BUFSTAT_READY,
+};
+
+#define CTRL_START_STREAMING_VALUE 0x0700
+#define CTRL_STOP_STREAMING_VALUE 0x0800
+#define CTRL_BITRATE_VALUE 0x1000
+#define CTRL_BITRATE_MODE_VALUE 0x1200
+#define CTRL_GOP_MODE_VALUE 0x1300
+#define CTRL_VIDEO_INPUT_VALUE 0x1500
+#define CTRL_VIDEO_STD_TYPE 0x1700
+#define CTRL_AUDIO_INPUT_VALUE 0x2500
+#define CTRL_BRIGHTNESS 0x2900
+#define CTRL_CONTRAST 0x2a00
+#define CTRL_HUE 0x2b00
+#define CTRL_SATURATION 0x2c00
+#define CTRL_SHARPNESS 0x2d00
+#define CTRL_LOW_PASS_FILTER_VALUE 0x3100
+
+#define CTRL_DEFAULT_INDEX 0x0003
+
+
+ /* :0 s 38 01 1000 0003 0004 4 = 0a00ca00
+ * BITRATE SETTING
+ * 1st and 2nd byte (little endian): average bitrate in 100 000 bit/s
+ * min: 1 mbit/s, max: 13.5 mbit/s
+ * 3rd and 4th byte (little endian): peak bitrate in 100 000 bit/s
+ * min: average + 100kbit/s,
+ * max: 20.2 mbit/s
+ */
+
+ /* :0 s 38 01 1200 0003 0001 1 = 02
+ * BIT RATE MODE
+ * constant = 1, variable (peak) = 2, variable (average) = 3
+ */
+
+ /* :0 s 38 01 1300 0003 0001 1 = 03
+ * GOP MODE (2 bit)
+ * low bit 0/1: advanced/simple GOP
+ * high bit 0/1: IDR(4/32/128) / no IDR (4/32/0)
+ */
+
+ /* :0 s 38 01 1700 0003 0001 1 = 00
+ * VIDEO STANDARD or FREQUNCY 0 = 60hz, 1 = 50hz
+ */
+
+ /* :0 s 38 01 3100 0003 0004 4 = 03030000
+ * FILTER CONTROL
+ * 1st byte luma low pass filter strength,
+ * 2nd byte chroma low pass filter strength,
+ * 3rd byte MF enable chroma, min=0, max=1
+ * 4th byte n
+ */
+
+
+ /* :0 s 38 b9 0001 0000 0000 0 */
+
+
+
+/* :0 s 38 d3 0000 0000 0001 1 = 00 */
+/* ret = usb_control_msg(dev->udev, */
+/* usb_sndctrlpipe(dev->udev, 0), */
+/* 0xd3, 0x38, */
+/* 0, 0, */
+/* "\0", 1, */
+/* 1000); */
+
+/* info("control request returned %d", ret); */
+/* msleep(5000); */
+
+
+ /* :0 s b8 81 1400 0003 0005 5 <
+ * :0 0 5 = d0024002 19
+ * QUERY FRAME SIZE AND RATE
+ * 1st and 2nd byte (little endian): horizontal resolution
+ * 3rd and 4th byte (little endian): vertical resolution
+ * 5th byte: frame rate
+ */
+
+ /* :0 s b8 81 1800 0003 0003 3 <
+ * :0 0 3 = 030104
+ * QUERY SIGNAL AND DETECTED LINES, maybe INPUT
+ */
+
+enum hdpvr_video_std {
+ HDPVR_60HZ = 0,
+ HDPVR_50HZ,
+};
+
+enum hdpvr_video_input {
+ HDPVR_COMPONENT = 0,
+ HDPVR_SVIDEO,
+ HDPVR_COMPOSITE,
+ HDPVR_VIDEO_INPUTS
+};
+
+enum hdpvr_audio_inputs {
+ HDPVR_RCA_BACK = 0,
+ HDPVR_RCA_FRONT,
+ HDPVR_SPDIF,
+ HDPVR_AUDIO_INPUTS
+};
+
+enum hdpvr_bitrate_mode {
+ HDPVR_CONSTANT = 1,
+ HDPVR_VARIABLE_PEAK,
+ HDPVR_VARIABLE_AVERAGE,
+};
+
+enum hdpvr_gop_mode {
+ HDPVR_ADVANCED_IDR_GOP = 0,
+ HDPVR_SIMPLE_IDR_GOP,
+ HDPVR_ADVANCED_NOIDR_GOP,
+ HDPVR_SIMPLE_NOIDR_GOP,
+};
+
+void hdpvr_delete(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* hardware control functions */
+int hdpvr_set_options(struct hdpvr_device *dev);
+
+int hdpvr_set_bitrate(struct hdpvr_device *dev);
+
+int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
+ enum v4l2_mpeg_audio_encoding codec);
+
+int hdpvr_config_call(struct hdpvr_device *dev, uint value,
+ unsigned char valbuf);
+
+struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev);
+
+/* :0 s b8 81 1800 0003 0003 3 < */
+/* :0 0 3 = 0301ff */
+int get_input_lines_info(struct hdpvr_device *dev);
+
+
+/*========================================================================*/
+/* v4l2 registration */
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+ int devnumber);
+
+int hdpvr_cancel_queue(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* i2c adapter registration */
+int hdpvr_register_i2c_adapter(struct hdpvr_device *dev);
+
+/*========================================================================*/
+/* buffer management */
+int hdpvr_free_buffers(struct hdpvr_device *dev);
+int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count);
diff --git a/drivers/media/video/hexium_gemini.c b/drivers/media/video/hexium_gemini.c
index 79393d1772e..8e1463ee1b6 100644
--- a/drivers/media/video/hexium_gemini.c
+++ b/drivers/media/video/hexium_gemini.c
@@ -56,17 +56,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { 0, 0 }
-};
-
#define HEXIUM_CONTROLS 1
static struct v4l2_queryctrl hexium_controls[] = {
{ V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
@@ -231,6 +220,132 @@ static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+ return 0;
+}
+
+/* the saa7146 provides some controls (brightness, contrast, saturation)
+ which gets registered *after* this function. because of this we have
+ to return with a value != 0 even if the function succeded.. */
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == qc->id) {
+ *qc = hexium_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
+ }
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
+
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE) {
+ vc->value = hexium->cur_bw;
+ DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+ int i = 0;
+
+ for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
+ if (hexium_controls[i].id == vc->id)
+ break;
+ }
+
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_PRIVATE_BASE)
+ hexium->cur_bw = vc->value;
+
+ DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
+
+ if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc);
+ return 0;
+ }
+ if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_secam);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_pal_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
+ hexium_set_standard(hexium, hexium_ntsc_bw);
+ return 0;
+ }
+ if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
+ /* fixme: is there no bw secam mode? */
+ return -EINVAL;
+
+ return -EINVAL;
+}
+
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -279,6 +394,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
hexium->cur_input = 0;
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER)) {
printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -306,153 +427,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long 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;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == qc->id) {
- *qc = hexium_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- vc->value = hexium->cur_bw;
- DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
- return 0;
- }
- }
- return -EINVAL;
- }
-
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
-
- for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
- if (hexium_controls[i].id == vc->id) {
- break;
- }
- }
-
- if (i < 0) {
- return -EAGAIN;
- }
-
- switch (vc->id) {
- case V4L2_CID_PRIVATE_BASE:{
- hexium->cur_bw = vc->value;
- break;
- }
- }
-
- DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
-
- if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc);
- return 0;
- }
- if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_secam);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_pal_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
- hexium_set_standard(hexium, hexium_ntsc_bw);
- return 0;
- }
- if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
- /* fixme: is there no bw secam mode? */
- return -EINVAL;
- }
-
- return -EINVAL;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
struct hexium *hexium = (struct hexium *) dev->ext_priv;
@@ -514,8 +488,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension hexium_extension = {
diff --git a/drivers/media/video/hexium_orion.c b/drivers/media/video/hexium_orion.c
index 074bec711fe..2bc39f62845 100644
--- a/drivers/media/video/hexium_orion.c
+++ b/drivers/media/video/hexium_orion.c
@@ -57,14 +57,6 @@ struct hexium_data
u8 byte;
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_STD, SAA7146_AFTER },
- { 0, 0 }
-};
-
struct hexium
{
int type;
@@ -329,6 +321,44 @@ static int hexium_set_input(struct hexium *hexium, int input)
return 0;
}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+
+ if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
+
+ DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
+ return 0;
+}
+
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ *input = hexium->cur_input;
+
+ DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
+ return 0;
+}
+
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct hexium *hexium = (struct hexium *) dev->ext_priv;
+
+ if (input < 0 || input >= HEXIUM_INPUTS)
+ return -EINVAL;
+
+ hexium->cur_input = input;
+ hexium_set_input(hexium, input);
+
+ return 0;
+}
+
static struct saa7146_ext_vv vv_data;
/* this function only gets called when the probing was successful */
@@ -339,6 +369,9 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d
DEB_EE((".\n"));
saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
printk("hexium_orion: cannot register capture v4l2 device. skipping.\n");
return -1;
@@ -370,58 +403,6 @@ static int hexium_detach(struct saa7146_dev *dev)
return 0;
}
-static long 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;
-*/
- switch (cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
-
- if (i->index < 0 || i->index >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
-
- DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
- return 0;
- }
- case VIDIOC_G_INPUT:
- {
- int *input = (int *) arg;
- *input = hexium->cur_input;
-
- DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
- return 0;
- }
- case VIDIOC_S_INPUT:
- {
- int input = *(int *) arg;
-
- if (input < 0 || input >= HEXIUM_INPUTS) {
- return -EINVAL;
- }
-
- hexium->cur_input = input;
- hexium_set_input(hexium, input);
-
- return 0;
- }
- default:
-/*
- DEB_D(("hexium_ioctl() does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
{
return 0;
@@ -479,8 +460,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &hexium_standards[0],
.num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = hexium_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c
index 84b9e4f2b3b..3d6940163b1 100644
--- a/drivers/media/video/indycam.c
+++ b/drivers/media/video/indycam.c
@@ -19,10 +19,12 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
/* IndyCam decodes stream of photons into digital image representation ;-) */
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "indycam.h"
@@ -33,6 +35,7 @@ MODULE_VERSION(INDYCAM_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
+
// #define INDYCAM_DEBUG
#ifdef INDYCAM_DEBUG
@@ -44,11 +47,14 @@ MODULE_LICENSE("GPL");
#endif
struct indycam {
- struct i2c_client *client;
+ struct v4l2_subdev sd;
u8 version;
};
-static struct i2c_driver i2c_driver_indycam;
+static inline struct indycam *to_indycam(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct indycam, sd);
+}
static const u8 initseq[] = {
INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
@@ -63,8 +69,9 @@ static const u8 initseq[] = {
/* IndyCam register handling */
-static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value)
+static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
if (reg == INDYCAM_REG_RESET) {
@@ -87,12 +94,12 @@ static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value)
return 0;
}
-static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value)
+static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int err;
- if ((reg == INDYCAM_REG_BRIGHTNESS)
- || (reg == INDYCAM_REG_VERSION)) {
+ if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) {
dprintk("indycam_write_reg(): "
"skipping read-only register %d\n", reg);
return 0;
@@ -108,13 +115,13 @@ static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value)
return err;
}
-static int indycam_write_block(struct i2c_client *client, u8 reg,
+static int indycam_write_block(struct v4l2_subdev *sd, u8 reg,
u8 length, u8 *data)
{
int i, err;
for (i = 0; i < length; i++) {
- err = indycam_write_reg(client, reg + i, data[i]);
+ err = indycam_write_reg(sd, reg + i, data[i]);
if (err)
return err;
}
@@ -125,79 +132,78 @@ static int indycam_write_block(struct i2c_client *client, u8 reg,
/* Helper functions */
#ifdef INDYCAM_DEBUG
-static void indycam_regdump_debug(struct i2c_client *client)
+static void indycam_regdump_debug(struct v4l2_subdev *sd)
{
int i;
u8 val;
for (i = 0; i < 9; i++) {
- indycam_read_reg(client, i, &val);
+ indycam_read_reg(sd, i, &val);
dprintk("Reg %d = 0x%02x\n", i, val);
}
}
#endif
-static int indycam_get_control(struct i2c_client *client,
- struct indycam_control *ctrl)
+static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct indycam *camera = i2c_get_clientdata(client);
+ struct indycam *camera = to_indycam(sd);
u8 reg;
int ret = 0;
- switch (ctrl->type) {
- case INDYCAM_CONTROL_AGC:
- case INDYCAM_CONTROL_AWB:
- ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+ switch (ctrl->id) {
+ case V4L2_CID_AUTOGAIN:
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
if (ret)
return -EIO;
- if (ctrl->type == INDYCAM_CONTROL_AGC)
+ if (ctrl->id == V4L2_CID_AUTOGAIN)
ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
? 1 : 0;
else
ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
? 1 : 0;
break;
- case INDYCAM_CONTROL_SHUTTER:
- ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, &reg);
+ case V4L2_CID_EXPOSURE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, &reg);
if (ret)
return -EIO;
ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
break;
- case INDYCAM_CONTROL_GAIN:
- ret = indycam_read_reg(client, INDYCAM_REG_GAIN, &reg);
+ case V4L2_CID_GAIN:
+ ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
- case INDYCAM_CONTROL_RED_BALANCE:
- ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, &reg);
+ case V4L2_CID_RED_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
- case INDYCAM_CONTROL_BLUE_BALANCE:
- ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, &reg);
+ case V4L2_CID_BLUE_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case INDYCAM_CONTROL_RED_SATURATION:
- ret = indycam_read_reg(client,
+ ret = indycam_read_reg(sd,
INDYCAM_REG_RED_SATURATION, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case INDYCAM_CONTROL_BLUE_SATURATION:
- ret = indycam_read_reg(client,
+ ret = indycam_read_reg(sd,
INDYCAM_REG_BLUE_SATURATION, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
- case INDYCAM_CONTROL_GAMMA:
+ case V4L2_CID_GAMMA:
if (camera->version == CAMERA_VERSION_MOOSE) {
- ret = indycam_read_reg(client,
+ ret = indycam_read_reg(sd,
INDYCAM_REG_GAMMA, &reg);
if (ret)
return -EIO;
@@ -213,21 +219,20 @@ static int indycam_get_control(struct i2c_client *client,
return ret;
}
-static int indycam_set_control(struct i2c_client *client,
- struct indycam_control *ctrl)
+static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- struct indycam *camera = i2c_get_clientdata(client);
+ struct indycam *camera = to_indycam(sd);
u8 reg;
int ret = 0;
- switch (ctrl->type) {
- case INDYCAM_CONTROL_AGC:
- case INDYCAM_CONTROL_AWB:
- ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, &reg);
+ switch (ctrl->id) {
+ case V4L2_CID_AUTOGAIN:
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
if (ret)
break;
- if (ctrl->type == INDYCAM_CONTROL_AGC) {
+ if (ctrl->id == V4L2_CID_AUTOGAIN) {
if (ctrl->value)
reg |= INDYCAM_CONTROL_AGCENA;
else
@@ -239,34 +244,34 @@ static int indycam_set_control(struct i2c_client *client,
reg &= ~INDYCAM_CONTROL_AWBCTL;
}
- ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg);
+ ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg);
break;
- case INDYCAM_CONTROL_SHUTTER:
+ case V4L2_CID_EXPOSURE:
reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
- ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg);
+ ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg);
break;
- case INDYCAM_CONTROL_GAIN:
- ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value);
+ case V4L2_CID_GAIN:
+ ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value);
break;
- case INDYCAM_CONTROL_RED_BALANCE:
- ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE,
+ case V4L2_CID_RED_BALANCE:
+ ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE,
ctrl->value);
break;
- case INDYCAM_CONTROL_BLUE_BALANCE:
- ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE,
+ case V4L2_CID_BLUE_BALANCE:
+ ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE,
ctrl->value);
break;
case INDYCAM_CONTROL_RED_SATURATION:
- ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION,
+ ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION,
ctrl->value);
break;
case INDYCAM_CONTROL_BLUE_SATURATION:
- ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION,
+ ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION,
ctrl->value);
break;
- case INDYCAM_CONTROL_GAMMA:
+ case V4L2_CID_GAMMA:
if (camera->version == CAMERA_VERSION_MOOSE) {
- ret = indycam_write_reg(client, INDYCAM_REG_GAMMA,
+ ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA,
ctrl->value);
}
break;
@@ -279,192 +284,103 @@ static int indycam_set_control(struct i2c_client *client,
/* I2C-interface */
-static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
+static int indycam_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct indycam *camera = to_indycam(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_INDYCAM,
+ camera->version);
+}
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops indycam_core_ops = {
+ .g_chip_ident = indycam_g_chip_ident,
+ .g_ctrl = indycam_g_ctrl,
+ .s_ctrl = indycam_s_ctrl,
+};
+
+static const struct v4l2_subdev_ops indycam_ops = {
+ .core = &indycam_core_ops,
+};
+
+static int indycam_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
int err = 0;
struct indycam *camera;
- struct i2c_client *client;
+ struct v4l2_subdev *sd;
- printk(KERN_INFO "SGI IndyCam driver version %s\n",
- INDYCAM_MODULE_VERSION);
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
- client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
camera = kzalloc(sizeof(struct indycam), GFP_KERNEL);
- if (!camera) {
- err = -ENOMEM;
- goto out_free_client;
- }
-
- client->addr = addr;
- client->adapter = adap;
- client->driver = &i2c_driver_indycam;
- client->flags = 0;
- strcpy(client->name, "IndyCam client");
- i2c_set_clientdata(client, camera);
-
- camera->client = client;
+ if (!camera)
+ return -ENOMEM;
- err = i2c_attach_client(client);
- if (err)
- goto out_free_camera;
+ sd = &camera->sd;
+ v4l2_i2c_subdev_init(sd, client, &indycam_ops);
camera->version = i2c_smbus_read_byte_data(client,
INDYCAM_REG_VERSION);
if (camera->version != CAMERA_VERSION_INDY &&
camera->version != CAMERA_VERSION_MOOSE) {
- err = -ENODEV;
- goto out_detach_client;
+ kfree(camera);
+ return -ENODEV;
}
+
printk(KERN_INFO "IndyCam v%d.%d detected\n",
INDYCAM_VERSION_MAJOR(camera->version),
INDYCAM_VERSION_MINOR(camera->version));
- indycam_regdump(client);
+ indycam_regdump(sd);
// initialize
- err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq);
+ err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq);
if (err) {
printk(KERN_ERR "IndyCam initialization failed\n");
- err = -EIO;
- goto out_detach_client;
+ kfree(camera);
+ return -EIO;
}
- indycam_regdump(client);
+ indycam_regdump(sd);
// white balance
- err = indycam_write_reg(client, INDYCAM_REG_CONTROL,
+ err = indycam_write_reg(sd, INDYCAM_REG_CONTROL,
INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
if (err) {
printk(KERN_ERR "IndyCam: White balancing camera failed\n");
- err = -EIO;
- goto out_detach_client;
+ kfree(camera);
+ return -EIO;
}
- indycam_regdump(client);
+ indycam_regdump(sd);
printk(KERN_INFO "IndyCam initialized\n");
return 0;
-
-out_detach_client:
- i2c_detach_client(client);
-out_free_camera:
- kfree(camera);
-out_free_client:
- kfree(client);
- return err;
}
-static int indycam_probe(struct i2c_adapter *adap)
+static int indycam_remove(struct i2c_client *client)
{
- /* Indy specific crap */
- if (adap->id == I2C_HW_SGI_VINO)
- return indycam_attach(adap, INDYCAM_ADDR, 0);
- /* Feel free to add probe here :-) */
- return -ENODEV;
-}
-
-static int indycam_detach(struct i2c_client *client)
-{
- struct indycam *camera = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
- i2c_detach_client(client);
- kfree(camera);
- kfree(client);
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_indycam(sd));
return 0;
}
-static int indycam_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- // struct indycam *camera = i2c_get_clientdata(client);
-
- /* The old video_decoder interface just isn't enough,
- * so we'll use some custom commands. */
- switch (cmd) {
- case DECODER_GET_CAPABILITIES: {
- struct video_decoder_capability *cap = arg;
-
- cap->flags = VIDEO_DECODER_NTSC;
- cap->inputs = 1;
- cap->outputs = 1;
- break;
- }
- case DECODER_GET_STATUS: {
- int *iarg = arg;
-
- *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC |
- DECODER_STATUS_COLOR;
- break;
- }
- case DECODER_SET_NORM: {
- int *iarg = arg;
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- break;
- default:
- return -EINVAL;
- }
- break;
- }
- case DECODER_SET_INPUT: {
- int *iarg = arg;
-
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
- case DECODER_SET_OUTPUT: {
- int *iarg = arg;
-
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
- case DECODER_ENABLE_OUTPUT: {
- /* Always enabled */
- break;
- }
- case DECODER_SET_PICTURE: {
- // struct video_picture *pic = arg;
- /* TODO: convert values for indycam_set_controls() */
- break;
- }
- case DECODER_INDYCAM_GET_CONTROL: {
- return indycam_get_control(client, arg);
- }
- case DECODER_INDYCAM_SET_CONTROL: {
- return indycam_set_control(client, arg);
- }
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-static struct i2c_driver i2c_driver_indycam = {
- .driver = {
- .name = "indycam",
- },
- .id = I2C_DRIVERID_INDYCAM,
- .attach_adapter = indycam_probe,
- .detach_client = indycam_detach,
- .command = indycam_command,
+static const struct i2c_device_id indycam_id[] = {
+ { "indycam", 0 },
+ { }
};
+MODULE_DEVICE_TABLE(i2c, indycam_id);
-static int __init indycam_init(void)
-{
- return i2c_add_driver(&i2c_driver_indycam);
-}
-
-static void __exit indycam_exit(void)
-{
- i2c_del_driver(&i2c_driver_indycam);
-}
-
-module_init(indycam_init);
-module_exit(indycam_exit);
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "indycam",
+ .probe = indycam_probe,
+ .remove = indycam_remove,
+ .id_table = indycam_id,
+};
diff --git a/drivers/media/video/indycam.h b/drivers/media/video/indycam.h
index e6ee82063ed..881f21c474c 100644
--- a/drivers/media/video/indycam.h
+++ b/drivers/media/video/indycam.h
@@ -87,22 +87,7 @@
/* Driver interface definitions */
-#define INDYCAM_CONTROL_AGC 0 /* boolean */
-#define INDYCAM_CONTROL_AWB 1 /* boolean */
-#define INDYCAM_CONTROL_SHUTTER 2
-#define INDYCAM_CONTROL_GAIN 3
-#define INDYCAM_CONTROL_RED_BALANCE 4
-#define INDYCAM_CONTROL_BLUE_BALANCE 5
-#define INDYCAM_CONTROL_RED_SATURATION 6
-#define INDYCAM_CONTROL_BLUE_SATURATION 7
-#define INDYCAM_CONTROL_GAMMA 8
-
-struct indycam_control {
- u8 type;
- s32 value;
-};
-
-#define DECODER_INDYCAM_GET_CONTROL _IOR('d', 193, struct indycam_control)
-#define DECODER_INDYCAM_SET_CONTROL _IOW('d', 194, struct indycam_control)
+#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0)
+#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1)
#endif
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index d4658c56edd..092c7da0f37 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -16,6 +16,8 @@
* Henry Wong <henry@stuffedcow.net>
* Mark Schultz <n9xmj@yahoo.com>
* Brian Rogers <brian_rogers@comcast.net>
+ * modified for AVerMedia Cardbus by
+ * Oldrich Jedlicka <oldium.pro@seznam.cz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -216,6 +218,46 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
return 1;
}
+static int get_key_avermedia_cardbus(struct IR_i2c *ir,
+ u32 *ir_key, u32 *ir_raw)
+{
+ unsigned char subaddr, key, keygroup;
+ struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+ .buf = &subaddr, .len = 1},
+ { .addr = ir->c.addr, .flags = I2C_M_RD,
+ .buf = &key, .len = 1} };
+ subaddr = 0x0d;
+ if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ dprintk(1, "read error\n");
+ return -EIO;
+ }
+
+ if (key == 0xff)
+ return 0;
+
+ subaddr = 0x0b;
+ msg[1].buf = &keygroup;
+ if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ dprintk(1, "read error\n");
+ return -EIO;
+ }
+
+ if (keygroup == 0xff)
+ return 0;
+
+ dprintk(1, "read key 0x%02x/0x%02x\n", key, keygroup);
+ if (keygroup < 2 || keygroup > 3) {
+ /* Only a warning */
+ dprintk(1, "warning: invalid key group 0x%02x for key 0x%02x\n",
+ keygroup, key);
+ }
+ key |= (keygroup & 1) << 6;
+
+ *ir_key = key;
+ *ir_raw = key;
+ return 1;
+}
+
/* ----------------------------------------------------------------------- */
static void ir_key_poll(struct IR_i2c *ir)
@@ -237,15 +279,9 @@ static void ir_key_poll(struct IR_i2c *ir)
}
}
-static void ir_timer(unsigned long data)
-{
- struct IR_i2c *ir = (struct IR_i2c*)data;
- schedule_work(&ir->work);
-}
-
static void ir_work(struct work_struct *work)
{
- struct IR_i2c *ir = container_of(work, struct IR_i2c, work);
+ struct IR_i2c *ir = container_of(work, struct IR_i2c, work.work);
int polling_interval = 100;
/* MSI TV@nywhere Plus requires more frequent polling
@@ -254,7 +290,7 @@ static void ir_work(struct work_struct *work)
polling_interval = 50;
ir_key_poll(ir);
- mod_timer(&ir->timer, jiffies + msecs_to_jiffies(polling_interval));
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(polling_interval));
}
/* ----------------------------------------------------------------------- */
@@ -360,6 +396,12 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir_type = IR_TYPE_OTHER;
}
break;
+ case 0x40:
+ name = "AVerMedia Cardbus remote";
+ ir->get_key = get_key_avermedia_cardbus;
+ ir_type = IR_TYPE_OTHER;
+ ir_codes = ir_codes_avermedia_cardbus;
+ break;
default:
/* shouldn't happen */
printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
@@ -404,11 +446,8 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir->input->name, ir->input->phys, adap->name);
/* start polling via eventd */
- INIT_WORK(&ir->work, ir_work);
- init_timer(&ir->timer);
- ir->timer.function = ir_timer;
- ir->timer.data = (unsigned long)ir;
- schedule_work(&ir->work);
+ INIT_DELAYED_WORK(&ir->work, ir_work);
+ schedule_delayed_work(&ir->work, 0);
return 0;
@@ -425,8 +464,7 @@ static int ir_detach(struct i2c_client *client)
struct IR_i2c *ir = i2c_get_clientdata(client);
/* kill outstanding polls */
- del_timer_sync(&ir->timer);
- flush_scheduled_work();
+ cancel_delayed_work_sync(&ir->work);
/* unregister devices */
input_unregister_device(ir->input);
@@ -524,6 +562,22 @@ static int ir_probe(struct i2c_adapter *adap)
ir_attach(adap, msg.addr, 0, 0);
}
+ /* Special case for AVerMedia Cardbus remote */
+ if (adap->id == I2C_HW_SAA7134) {
+ unsigned char subaddr, data;
+ struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
+ .buf = &subaddr, .len = 1},
+ { .addr = 0x40, .flags = I2C_M_RD,
+ .buf = &data, .len = 1} };
+ subaddr = 0x0d;
+ rc = i2c_transfer(adap, msg, 2);
+ dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
+ msg[0].addr, subaddr, adap->name,
+ (2 == rc) ? "yes" : "no");
+ if (2 == rc)
+ ir_attach(adap, msg[0].addr, 0, 0);
+ }
+
return 0;
}
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index 62aa06f5d16..84995bcf4a7 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -26,6 +26,7 @@
#include "ivtv-mailbox.h"
#include "ivtv-controls.h"
+/* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index c46c990987f..eca8bf92a22 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -357,7 +357,7 @@ void ivtv_read_eeprom(struct ivtv *itv, struct tveeprom *tv)
static void ivtv_process_eeprom(struct ivtv *itv)
{
struct tveeprom tv;
- int pci_slot = PCI_SLOT(itv->dev->devfn);
+ int pci_slot = PCI_SLOT(itv->pdev->devfn);
ivtv_read_eeprom(itv, &tv);
@@ -604,7 +604,7 @@ static void ivtv_process_options(struct ivtv *itv)
itv->std = ivtv_parse_std(itv);
if (itv->std == 0 && tunertype >= 0)
itv->std = tunertype ? V4L2_STD_MN : (V4L2_STD_ALL & ~V4L2_STD_MN);
- itv->has_cx23415 = (itv->dev->device == PCI_DEVICE_ID_IVTV15);
+ itv->has_cx23415 = (itv->pdev->device == PCI_DEVICE_ID_IVTV15);
chipname = itv->has_cx23415 ? "cx23415" : "cx23416";
if (itv->options.cardtype == -1) {
IVTV_INFO("Ignore card (detected %s based chip)\n", chipname);
@@ -617,9 +617,9 @@ static void ivtv_process_options(struct ivtv *itv)
IVTV_ERR("Unknown user specified type, trying to autodetect card\n");
}
if (itv->card == NULL) {
- if (itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
- itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
- itv->dev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
+ if (itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE ||
+ itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT1 ||
+ itv->pdev->subsystem_vendor == IVTV_PCI_ID_HAUPPAUGE_ALT2) {
itv->card = ivtv_get_card(itv->has_cx23415 ? IVTV_CARD_PVR_350 : IVTV_CARD_PVR_150);
IVTV_INFO("Autodetected Hauppauge card (%s based)\n",
chipname);
@@ -630,13 +630,13 @@ static void ivtv_process_options(struct ivtv *itv)
if (itv->card->pci_list == NULL)
continue;
for (j = 0; itv->card->pci_list[j].device; j++) {
- if (itv->dev->device !=
+ if (itv->pdev->device !=
itv->card->pci_list[j].device)
continue;
- if (itv->dev->subsystem_vendor !=
+ if (itv->pdev->subsystem_vendor !=
itv->card->pci_list[j].subsystem_vendor)
continue;
- if (itv->dev->subsystem_device !=
+ if (itv->pdev->subsystem_device !=
itv->card->pci_list[j].subsystem_device)
continue;
IVTV_INFO("Autodetected %s card (%s based)\n",
@@ -650,9 +650,9 @@ done:
if (itv->card == NULL) {
itv->card = ivtv_get_card(IVTV_CARD_PVR_150);
IVTV_ERR("Unknown card: vendor/device: [%04x:%04x]\n",
- itv->dev->vendor, itv->dev->device);
+ itv->pdev->vendor, itv->pdev->device);
IVTV_ERR(" subsystem vendor/device: [%04x:%04x]\n",
- itv->dev->subsystem_vendor, itv->dev->subsystem_device);
+ itv->pdev->subsystem_vendor, itv->pdev->subsystem_device);
IVTV_ERR(" %s based\n", chipname);
IVTV_ERR("Defaulting to %s card\n", itv->card->name);
IVTV_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n");
@@ -671,7 +671,7 @@ done:
*/
static int __devinit ivtv_init_struct1(struct ivtv *itv)
{
- itv->base_addr = pci_resource_start(itv->dev, 0);
+ itv->base_addr = pci_resource_start(itv->pdev, 0);
itv->enc_mbox.max_mbox = 2; /* the encoder has 3 mailboxes (0-2) */
itv->dec_mbox.max_mbox = 1; /* the decoder has 2 mailboxes (0-1) */
@@ -682,7 +682,7 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
spin_lock_init(&itv->lock);
spin_lock_init(&itv->dma_reg_lock);
- itv->irq_work_queues = create_singlethread_workqueue(itv->device.name);
+ itv->irq_work_queues = create_singlethread_workqueue(itv->v4l2_dev.name);
if (itv->irq_work_queues == NULL) {
IVTV_ERR("Could not create ivtv workqueue\n");
return -1;
@@ -766,7 +766,7 @@ static void __devinit ivtv_init_struct2(struct ivtv *itv)
itv->audio_input = itv->card->video_inputs[i].audio_index;
}
-static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
+static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
u16 cmd;
@@ -775,11 +775,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
IVTV_DEBUG_INFO("Enabling pci device\n");
- if (pci_enable_device(dev)) {
+ if (pci_enable_device(pdev)) {
IVTV_ERR("Can't enable device!\n");
return -EIO;
}
- if (pci_set_dma_mask(dev, 0xffffffff)) {
+ if (pci_set_dma_mask(pdev, 0xffffffff)) {
IVTV_ERR("No suitable DMA available.\n");
return -EIO;
}
@@ -805,11 +805,11 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
}
/* Check for bus mastering */
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_DEBUG_INFO("Attempting to enable Bus Mastering\n");
- pci_set_master(dev);
- pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_set_master(pdev);
+ pci_read_config_word(pdev, PCI_COMMAND, &cmd);
if (!(cmd & PCI_COMMAND_MASTER)) {
IVTV_ERR("Bus Mastering is not enabled\n");
return -ENXIO;
@@ -817,26 +817,26 @@ static int ivtv_setup_pci(struct ivtv *itv, struct pci_dev *dev,
}
IVTV_DEBUG_INFO("Bus Mastering Enabled.\n");
- pci_read_config_byte(dev, PCI_CLASS_REVISION, &card_rev);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_read_config_byte(pdev, PCI_CLASS_REVISION, &card_rev);
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
if (pci_latency < 64 && ivtv_pci_latency) {
IVTV_INFO("Unreasonably low latency timer, "
"setting to 64 (was %d)\n", pci_latency);
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
- pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency);
+ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
+ pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
}
/* This config space value relates to DMA latencies. The
default value 0x8080 is too low however and will lead
to DMA errors. 0xffff is the max value which solves
these problems. */
- pci_write_config_dword(dev, 0x40, 0xffff);
+ pci_write_config_dword(pdev, 0x40, 0xffff);
IVTV_DEBUG_INFO("%d (rev %d) at %02x:%02x.%x, "
"irq: %d, latency: %d, memory: 0x%lx\n",
- itv->dev->device, card_rev, dev->bus->number,
- PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn),
- itv->dev->irq, pci_latency, (unsigned long)itv->base_addr);
+ pdev->device, card_rev, pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
+ pdev->irq, pci_latency, (unsigned long)itv->base_addr);
return 0;
}
@@ -935,7 +935,7 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
}
}
-static int __devinit ivtv_probe(struct pci_dev *dev,
+static int __devinit ivtv_probe(struct pci_dev *pdev,
const struct pci_device_id *pci_id)
{
int retval = 0;
@@ -945,17 +945,17 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
itv = kzalloc(sizeof(struct ivtv), GFP_ATOMIC);
if (itv == NULL)
return -ENOMEM;
- itv->dev = dev;
+ itv->pdev = pdev;
itv->instance = atomic_inc_return(&ivtv_instance) - 1;
- retval = v4l2_device_register(&dev->dev, &itv->device);
+ retval = v4l2_device_register(&pdev->dev, &itv->v4l2_dev);
if (retval) {
kfree(itv);
return retval;
}
/* "ivtv + PCI ID" is a bit of a mouthful, so use
"ivtv + instance" instead. */
- snprintf(itv->device.name, sizeof(itv->device.name),
+ snprintf(itv->v4l2_dev.name, sizeof(itv->v4l2_dev.name),
"ivtv%d", itv->instance);
IVTV_INFO("Initializing card %d\n", itv->instance);
@@ -972,12 +972,11 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
/* PCI Device Setup */
- if ((retval = ivtv_setup_pci(itv, dev, pci_id)) != 0) {
- if (retval == -EIO)
- goto free_workqueue;
- else if (retval == -ENXIO)
- goto free_mem;
- }
+ retval = ivtv_setup_pci(itv, pdev, pci_id);
+ if (retval == -EIO)
+ goto free_workqueue;
+ if (retval == -ENXIO)
+ goto free_mem;
/* map io memory */
IVTV_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n",
@@ -1154,8 +1153,8 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
ivtv_set_irq_mask(itv, 0xffffffff);
/* Register IRQ */
- retval = request_irq(itv->dev->irq, ivtv_irq_handler,
- IRQF_SHARED | IRQF_DISABLED, itv->device.name, (void *)itv);
+ retval = request_irq(itv->pdev->irq, ivtv_irq_handler,
+ IRQF_SHARED | IRQF_DISABLED, itv->v4l2_dev.name, (void *)itv);
if (retval) {
IVTV_ERR("Failed to register irq %d\n", retval);
goto free_i2c;
@@ -1177,7 +1176,7 @@ static int __devinit ivtv_probe(struct pci_dev *dev,
free_streams:
ivtv_streams_cleanup(itv, 1);
free_irq:
- free_irq(itv->dev->irq, (void *)itv);
+ free_irq(itv->pdev->irq, (void *)itv);
free_i2c:
exit_ivtv_i2c(itv);
free_io:
@@ -1194,7 +1193,7 @@ err:
retval = -ENODEV;
IVTV_ERR("Error %d on initialization\n", retval);
- v4l2_device_unregister(&itv->device);
+ v4l2_device_unregister(&itv->v4l2_dev);
kfree(itv);
return retval;
}
@@ -1292,10 +1291,10 @@ int ivtv_init_on_first_open(struct ivtv *itv)
return 0;
}
-static void ivtv_remove(struct pci_dev *pci_dev)
+static void ivtv_remove(struct pci_dev *pdev)
{
- struct v4l2_device *dev = dev_get_drvdata(&pci_dev->dev);
- struct ivtv *itv = to_ivtv(dev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct ivtv *itv = to_ivtv(v4l2_dev);
int i;
IVTV_DEBUG_INFO("Removing card\n");
@@ -1336,11 +1335,9 @@ static void ivtv_remove(struct pci_dev *pci_dev)
ivtv_streams_cleanup(itv, 1);
ivtv_udma_free(itv);
- v4l2_device_unregister(&itv->device);
-
exit_ivtv_i2c(itv);
- free_irq(itv->dev->irq, (void *)itv);
+ free_irq(itv->pdev->irq, (void *)itv);
ivtv_iounmap(itv);
release_mem_region(itv->base_addr, IVTV_ENCODER_SIZE);
@@ -1348,11 +1345,13 @@ static void ivtv_remove(struct pci_dev *pci_dev)
if (itv->has_cx23415)
release_mem_region(itv->base_addr + IVTV_DECODER_OFFSET, IVTV_DECODER_SIZE);
- pci_disable_device(itv->dev);
+ pci_disable_device(itv->pdev);
for (i = 0; i < IVTV_VBI_FRAMES; i++)
kfree(itv->vbi.sliced_mpeg_data[i]);
printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
+
+ v4l2_device_unregister(&itv->v4l2_dev);
kfree(itv);
}
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index ce8d9b74357..440f7328a7e 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -133,7 +133,7 @@ extern int ivtv_debug;
#define IVTV_DEBUG(x, type, fmt, args...) \
do { \
if ((x) & ivtv_debug) \
- v4l2_info(&itv->device, " " type ": " fmt , ##args); \
+ v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
} while (0)
#define IVTV_DEBUG_WARN(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
#define IVTV_DEBUG_INFO(fmt, args...) IVTV_DEBUG(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -149,7 +149,7 @@ extern int ivtv_debug;
#define IVTV_DEBUG_HIGH_VOL(x, type, fmt, args...) \
do { \
if (((x) & ivtv_debug) && (ivtv_debug & IVTV_DBGFLG_HIGHVOL)) \
- v4l2_info(&itv->device, " " type ": " fmt , ##args); \
+ v4l2_info(&itv->v4l2_dev, " " type ": " fmt , ##args); \
} while (0)
#define IVTV_DEBUG_HI_WARN(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_WARN, "warn", fmt , ## args)
#define IVTV_DEBUG_HI_INFO(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_INFO, "info", fmt , ## args)
@@ -163,9 +163,9 @@ extern int ivtv_debug;
#define IVTV_DEBUG_HI_YUV(fmt, args...) IVTV_DEBUG_HIGH_VOL(IVTV_DBGFLG_YUV, "yuv", fmt , ## args)
/* Standard kernel messages */
-#define IVTV_ERR(fmt, args...) v4l2_err(&itv->device, fmt , ## args)
-#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->device, fmt , ## args)
-#define IVTV_INFO(fmt, args...) v4l2_info(&itv->device, fmt , ## args)
+#define IVTV_ERR(fmt, args...) v4l2_err(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_WARN(fmt, args...) v4l2_warn(&itv->v4l2_dev, fmt , ## args)
+#define IVTV_INFO(fmt, args...) v4l2_info(&itv->v4l2_dev, fmt , ## args)
/* output modes (cx23415 only) */
#define OUT_NONE 0
@@ -315,7 +315,7 @@ struct ivtv; /* forward reference */
struct ivtv_stream {
/* These first four fields are always set, even if the stream
is not actually created. */
- struct video_device *v4l2dev; /* NULL when stream not created */
+ struct video_device *vdev; /* NULL when stream not created */
struct ivtv *itv; /* for ease of use */
const char *name; /* name of the stream */
int type; /* stream type */
@@ -592,7 +592,7 @@ struct ivtv_card;
/* Struct to hold info about ivtv cards */
struct ivtv {
/* General fixed card data */
- struct pci_dev *dev; /* PCI device */
+ struct pci_dev *pdev; /* PCI device */
const struct ivtv_card *card; /* card information */
const char *card_name; /* full name of the card */
const struct ivtv_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */
@@ -612,7 +612,7 @@ struct ivtv {
volatile void __iomem *reg_mem; /* pointer to mapped registers */
struct ivtv_options options; /* user options */
- struct v4l2_device device;
+ struct v4l2_device v4l2_dev;
struct v4l2_subdev sd_gpio; /* GPIO sub-device */
u16 instance;
@@ -696,7 +696,7 @@ struct ivtv {
u64 vbi_data_inserted; /* number of VBI bytes inserted into the MPEG stream */
u32 last_dec_timing[3]; /* cache last retrieved pts/scr/frame values */
unsigned long dualwatch_jiffies;/* jiffies value of the previous dualwatch check */
- u16 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
+ u32 dualwatch_stereo_mode; /* current detected dualwatch stereo mode */
/* VBI state info */
@@ -719,9 +719,9 @@ struct ivtv {
struct osd_info *osd_info; /* ivtvfb private OSD info */
};
-static inline struct ivtv *to_ivtv(struct v4l2_device *dev)
+static inline struct ivtv *to_ivtv(struct v4l2_device *v4l2_dev)
{
- return container_of(dev, struct ivtv, device);
+ return container_of(v4l2_dev, struct ivtv, v4l2_dev);
}
/* Globals */
@@ -788,7 +788,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
/* Call the specified callback for all subdevs matching hw (if 0, then
match them all). Ignore any errors. */
#define ivtv_call_hw(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+ __v4l2_device_call_subdevs(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
#define ivtv_call_all(itv, o, f, args...) ivtv_call_hw(itv, 0, o, f , ##args)
@@ -796,7 +796,7 @@ static inline int ivtv_raw_vbi(const struct ivtv *itv)
match them all). If the callback returns an error other than 0 or
-ENOIOCTLCMD, then return with that error code. */
#define ivtv_call_hw_err(itv, hw, o, f, args...) \
- __v4l2_device_call_subdevs_until_err(&(itv)->device, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
+ __v4l2_device_call_subdevs_until_err(&(itv)->v4l2_dev, !(hw) || (sd->grp_id & (hw)), o, f , ##args)
#define ivtv_call_all_err(itv, o, f, args...) ivtv_call_hw_err(itv, 0, o, f , ##args)
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index d594bc29f07..cfaacf6096d 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -148,10 +148,10 @@ void ivtv_release_stream(struct ivtv_stream *s)
static void ivtv_dualwatch(struct ivtv *itv)
{
struct v4l2_tuner vt;
- u16 new_bitmap;
- u16 new_stereo_mode;
- const u16 stereo_mask = 0x0300;
- const u16 dual = 0x0200;
+ u32 new_bitmap;
+ u32 new_stereo_mode;
+ const u32 stereo_mask = 0x0300;
+ const u32 dual = 0x0200;
new_stereo_mode = itv->params.audio_properties & stereo_mask;
memset(&vt, 0, sizeof(vt));
@@ -991,7 +991,7 @@ int ivtv_v4l2_open(struct file *filp)
mutex_lock(&itv->serialize_lock);
if (ivtv_init_on_first_open(itv)) {
IVTV_ERR("Failed to initialize on minor %d\n",
- s->v4l2dev->minor);
+ vdev->minor);
mutex_unlock(&itv->serialize_lock);
return -ENXIO;
}
diff --git a/drivers/media/video/ivtv/ivtv-firmware.c b/drivers/media/video/ivtv/ivtv-firmware.c
index 6dba55b7e25..c1b7ec475c2 100644
--- a/drivers/media/video/ivtv/ivtv-firmware.c
+++ b/drivers/media/video/ivtv/ivtv-firmware.c
@@ -52,7 +52,7 @@ static int load_fw_direct(const char *fn, volatile u8 __iomem *mem, struct ivtv
int retries = 3;
retry:
- if (retries && request_firmware(&fw, fn, &itv->dev->dev) == 0) {
+ if (retries && request_firmware(&fw, fn, &itv->pdev->dev) == 0) {
int i;
volatile u32 __iomem *dst = (volatile u32 __iomem *)mem;
const u32 *src = (const u32 *)fw->data;
diff --git a/drivers/media/video/ivtv/ivtv-gpio.c b/drivers/media/video/ivtv/ivtv-gpio.c
index dc2850e87a7..3321983d89e 100644
--- a/drivers/media/video/ivtv/ivtv-gpio.c
+++ b/drivers/media/video/ivtv/ivtv-gpio.c
@@ -384,7 +384,7 @@ int ivtv_gpio_init(struct ivtv *itv)
write_reg(itv->card->gpio_init.initial_value | pin, IVTV_REG_GPIO_OUT);
write_reg(itv->card->gpio_init.direction | pin, IVTV_REG_GPIO_DIR);
v4l2_subdev_init(&itv->sd_gpio, &subdev_ops);
- snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->device.name);
+ snprintf(itv->sd_gpio.name, sizeof(itv->sd_gpio.name), "%s-gpio", itv->v4l2_dev.name);
itv->sd_gpio.grp_id = IVTV_HW_GPIO;
- return v4l2_device_register_subdev(&itv->device, &itv->sd_gpio);
+ return v4l2_device_register_subdev(&itv->v4l2_dev, &itv->sd_gpio);
}
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index ca1d9557945..e73a196ecc7 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -194,14 +194,14 @@ struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
struct v4l2_subdev *result = NULL;
struct v4l2_subdev *sd;
- spin_lock(&itv->device.lock);
- v4l2_device_for_each_subdev(sd, &itv->device) {
+ spin_lock(&itv->v4l2_dev.lock);
+ v4l2_device_for_each_subdev(sd, &itv->v4l2_dev) {
if (sd->grp_id == hw) {
result = sd;
break;
}
}
- spin_unlock(&itv->device.lock);
+ spin_unlock(&itv->v4l2_dev.lock);
return result;
}
@@ -472,8 +472,8 @@ static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data,
intervening stop condition */
static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
{
- struct v4l2_device *drv = i2c_get_adapdata(i2c_adap);
- struct ivtv *itv = to_ivtv(drv);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(i2c_adap);
+ struct ivtv *itv = to_ivtv(v4l2_dev);
int retval;
int i;
@@ -604,12 +604,12 @@ int init_ivtv_i2c(struct ivtv *itv)
sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
itv->instance);
- i2c_set_adapdata(&itv->i2c_adap, &itv->device);
+ i2c_set_adapdata(&itv->i2c_adap, &itv->v4l2_dev);
memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
sizeof(struct i2c_client));
itv->i2c_client.adapter = &itv->i2c_adap;
- itv->i2c_adap.dev.parent = &itv->dev->dev;
+ itv->i2c_adap.dev.parent = &itv->pdev->dev;
IVTV_DEBUG_I2C("setting scl and sda to 1\n");
ivtv_setscl(itv, 1);
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index c13bd2aa0be..9a0424298af 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -345,10 +345,8 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
pixfmt->priv = 0;
if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
pixfmt->pixelformat = V4L2_PIX_FMT_HM12;
- /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
- pixfmt->sizeimage =
- pixfmt->height * pixfmt->width +
- pixfmt->height * (pixfmt->width / 2);
+ /* YUV size is (Y=(h*720) + UV=(h*(720/2))) */
+ pixfmt->sizeimage = pixfmt->height * 720 * 3 / 2;
pixfmt->bytesperline = 720;
} else {
pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
@@ -469,11 +467,17 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format
struct ivtv *itv = id->itv;
int w = fmt->fmt.pix.width;
int h = fmt->fmt.pix.height;
+ int min_h = 2;
w = min(w, 720);
w = max(w, 2);
+ if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
+ /* YUV height must be a multiple of 32 */
+ h &= ~0x1f;
+ min_h = 32;
+ }
h = min(h, itv->is_50hz ? 576 : 480);
- h = max(h, 2);
+ h = max(h, min_h);
ivtv_g_fmt_vid_cap(file, fh, fmt);
fmt->fmt.pix.width = w;
fmt->fmt.pix.height = h;
@@ -766,7 +770,7 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
- snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->dev));
+ snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev));
vcap->version = IVTV_DRIVER_VERSION; /* version */
vcap->capabilities = itv->v4l2_cap; /* capabilities */
return 0;
@@ -1513,12 +1517,12 @@ static int ivtv_log_status(struct file *file, void *fh)
}
IVTV_INFO("Tuner: %s\n",
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
- cx2341x_log_status(&itv->params, itv->device.name);
+ cx2341x_log_status(&itv->params, itv->v4l2_dev.name);
IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
for (i = 0; i < IVTV_MAX_STREAMS; i++) {
struct ivtv_stream *s = &itv->streams[i];
- if (s->v4l2dev == NULL || s->buffers == 0)
+ if (s->vdev == NULL || s->buffers == 0)
continue;
IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
(s->buffers - s->q_free.buffers) * 100 / s->buffers,
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c
index f5d00ec5da7..01c14d2b381 100644
--- a/drivers/media/video/ivtv/ivtv-irq.c
+++ b/drivers/media/video/ivtv/ivtv-irq.c
@@ -46,7 +46,7 @@ static void ivtv_pio_work_handler(struct ivtv *itv)
IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
- s->v4l2dev == NULL || !ivtv_use_pio(s)) {
+ s->vdev == NULL || !ivtv_use_pio(s)) {
itv->cur_pio_stream = -1;
/* trigger PIO complete user interrupt */
write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
@@ -109,7 +109,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA
int rc;
/* sanity checks */
- if (s->v4l2dev == NULL) {
+ if (s->vdev == NULL) {
IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
return -1;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.c b/drivers/media/video/ivtv/ivtv-queue.c
index 71bd13e22e2..ff7b7deded4 100644
--- a/drivers/media/video/ivtv/ivtv-queue.c
+++ b/drivers/media/video/ivtv/ivtv-queue.c
@@ -230,7 +230,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
return -ENOMEM;
}
if (ivtv_might_use_dma(s)) {
- s->sg_handle = pci_map_single(itv->dev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
+ s->sg_handle = pci_map_single(itv->pdev, s->sg_dma, sizeof(struct ivtv_sg_element), s->dma);
ivtv_stream_sync_for_cpu(s);
}
@@ -248,7 +248,7 @@ int ivtv_stream_alloc(struct ivtv_stream *s)
}
INIT_LIST_HEAD(&buf->list);
if (ivtv_might_use_dma(s)) {
- buf->dma_handle = pci_map_single(s->itv->dev,
+ buf->dma_handle = pci_map_single(s->itv->pdev,
buf->buf, s->buf_size + 256, s->dma);
ivtv_buf_sync_for_cpu(s, buf);
}
@@ -271,7 +271,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* empty q_free */
while ((buf = ivtv_dequeue(s, &s->q_free))) {
if (ivtv_might_use_dma(s))
- pci_unmap_single(s->itv->dev, buf->dma_handle,
+ pci_unmap_single(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
kfree(buf->buf);
kfree(buf);
@@ -280,7 +280,7 @@ void ivtv_stream_free(struct ivtv_stream *s)
/* Free SG Array/Lists */
if (s->sg_dma != NULL) {
if (s->sg_handle != IVTV_DMA_UNMAPPED) {
- pci_unmap_single(s->itv->dev, s->sg_handle,
+ pci_unmap_single(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
s->sg_handle = IVTV_DMA_UNMAPPED;
}
diff --git a/drivers/media/video/ivtv/ivtv-queue.h b/drivers/media/video/ivtv/ivtv-queue.h
index 476556afd39..91233839a26 100644
--- a/drivers/media/video/ivtv/ivtv-queue.h
+++ b/drivers/media/video/ivtv/ivtv-queue.h
@@ -53,14 +53,14 @@ static inline int ivtv_use_dma(struct ivtv_stream *s)
static inline void ivtv_buf_sync_for_cpu(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->dev, buf->dma_handle,
+ pci_dma_sync_single_for_cpu(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
static inline void ivtv_buf_sync_for_device(struct ivtv_stream *s, struct ivtv_buffer *buf)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->dev, buf->dma_handle,
+ pci_dma_sync_single_for_device(s->itv->pdev, buf->dma_handle,
s->buf_size + 256, s->dma);
}
@@ -82,14 +82,14 @@ void ivtv_stream_free(struct ivtv_stream *s);
static inline void ivtv_stream_sync_for_cpu(struct ivtv_stream *s)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_cpu(s->itv->dev, s->sg_handle,
+ pci_dma_sync_single_for_cpu(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
}
static inline void ivtv_stream_sync_for_device(struct ivtv_stream *s)
{
if (ivtv_use_dma(s))
- pci_dma_sync_single_for_device(s->itv->dev, s->sg_handle,
+ pci_dma_sync_single_for_device(s->itv->pdev, s->sg_handle,
sizeof(struct ivtv_sg_element), PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 854a950af78..15da01710ef 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -137,11 +137,11 @@ static struct {
static void ivtv_stream_init(struct ivtv *itv, int type)
{
struct ivtv_stream *s = &itv->streams[type];
- struct video_device *dev = s->v4l2dev;
+ struct video_device *vdev = s->vdev;
- /* we need to keep v4l2dev, so restore it afterwards */
+ /* we need to keep vdev, so restore it afterwards */
memset(s, 0, sizeof(*s));
- s->v4l2dev = dev;
+ s->vdev = vdev;
/* initialize ivtv_stream fields */
s->itv = itv;
@@ -172,10 +172,10 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
int num_offset = ivtv_stream_info[type].num_offset;
int num = itv->instance + ivtv_first_minor + num_offset;
- /* These four fields are always initialized. If v4l2dev == NULL, then
+ /* These four fields are always initialized. If vdev == NULL, then
this stream is not in use. In that case no other fields but these
four can be used. */
- s->v4l2dev = NULL;
+ s->vdev = NULL;
s->itv = itv;
s->type = type;
s->name = ivtv_stream_info[type].name;
@@ -197,21 +197,21 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
ivtv_stream_init(itv, type);
/* allocate and initialize the v4l2 video device structure */
- s->v4l2dev = video_device_alloc();
- if (s->v4l2dev == NULL) {
+ s->vdev = video_device_alloc();
+ if (s->vdev == NULL) {
IVTV_ERR("Couldn't allocate v4l2 video_device for %s\n", s->name);
return -ENOMEM;
}
- snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "%s %s",
- itv->device.name, s->name);
+ snprintf(s->vdev->name, sizeof(s->vdev->name), "%s %s",
+ itv->v4l2_dev.name, s->name);
- s->v4l2dev->num = num;
- s->v4l2dev->v4l2_dev = &itv->device;
- s->v4l2dev->fops = ivtv_stream_info[type].fops;
- s->v4l2dev->release = video_device_release;
- s->v4l2dev->tvnorms = V4L2_STD_ALL;
- ivtv_set_funcs(s->v4l2dev);
+ s->vdev->num = num;
+ s->vdev->v4l2_dev = &itv->v4l2_dev;
+ s->vdev->fops = ivtv_stream_info[type].fops;
+ s->vdev->release = video_device_release;
+ s->vdev->tvnorms = V4L2_STD_ALL;
+ ivtv_set_funcs(s->vdev);
return 0;
}
@@ -226,7 +226,7 @@ int ivtv_streams_setup(struct ivtv *itv)
if (ivtv_prep_dev(itv, type))
break;
- if (itv->streams[type].v4l2dev == NULL)
+ if (itv->streams[type].vdev == NULL)
continue;
/* Allocate Stream */
@@ -247,28 +247,28 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
int vfl_type = ivtv_stream_info[type].vfl_type;
int num;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return 0;
- num = s->v4l2dev->num;
+ num = s->vdev->num;
/* card number + user defined offset + device offset */
if (type != IVTV_ENC_STREAM_TYPE_MPG) {
struct ivtv_stream *s_mpg = &itv->streams[IVTV_ENC_STREAM_TYPE_MPG];
- if (s_mpg->v4l2dev)
- num = s_mpg->v4l2dev->num + ivtv_stream_info[type].num_offset;
+ if (s_mpg->vdev)
+ num = s_mpg->vdev->num + ivtv_stream_info[type].num_offset;
}
- video_set_drvdata(s->v4l2dev, s);
+ video_set_drvdata(s->vdev, s);
/* Register device. First try the desired minor, then any free one. */
- if (video_register_device(s->v4l2dev, vfl_type, num)) {
+ if (video_register_device(s->vdev, vfl_type, num)) {
IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n",
s->name, num);
- video_device_release(s->v4l2dev);
- s->v4l2dev = NULL;
+ video_device_release(s->vdev);
+ s->vdev = NULL;
return -ENOMEM;
}
- num = s->v4l2dev->num;
+ num = s->vdev->num;
switch (vfl_type) {
case VFL_TYPE_GRABBER:
@@ -316,9 +316,9 @@ void ivtv_streams_cleanup(struct ivtv *itv, int unregister)
/* Teardown all streams */
for (type = 0; type < IVTV_MAX_STREAMS; type++) {
- struct video_device *vdev = itv->streams[type].v4l2dev;
+ struct video_device *vdev = itv->streams[type].vdev;
- itv->streams[type].v4l2dev = NULL;
+ itv->streams[type].vdev = NULL;
if (vdev == NULL)
continue;
@@ -449,7 +449,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
int captype = 0, subtype = 0;
int enable_passthrough = 0;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("Start encoder stream %s\n", s->name);
@@ -611,7 +611,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
struct cx2341x_mpeg_params *p = &itv->params;
int datatype;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
@@ -657,7 +657,7 @@ int ivtv_start_v4l2_decode_stream(struct ivtv_stream *s, int gop_offset)
{
struct ivtv *itv = s->itv;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
if (test_and_set_bit(IVTV_F_S_STREAMING, &s->s_flags))
@@ -705,7 +705,7 @@ void ivtv_stop_all_captures(struct ivtv *itv)
for (i = IVTV_MAX_STREAMS - 1; i >= 0; i--) {
struct ivtv_stream *s = &itv->streams[i];
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
continue;
if (test_bit(IVTV_F_S_STREAMING, &s->s_flags)) {
ivtv_stop_v4l2_encode_stream(s, 0);
@@ -720,7 +720,7 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
int cap_type;
int stopmode;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
/* This function assumes that you are allowed to stop the capture
@@ -834,7 +834,7 @@ int ivtv_stop_v4l2_decode_stream(struct ivtv_stream *s, int flags, u64 pts)
{
struct ivtv *itv = s->itv;
- if (s->v4l2dev == NULL)
+ if (s->vdev == NULL)
return -EINVAL;
if (s->type != IVTV_DEC_STREAM_TYPE_YUV && s->type != IVTV_DEC_STREAM_TYPE_MPG)
@@ -895,7 +895,7 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable)
struct ivtv_stream *yuv_stream = &itv->streams[IVTV_ENC_STREAM_TYPE_YUV];
struct ivtv_stream *dec_stream = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
- if (yuv_stream->v4l2dev == NULL || dec_stream->v4l2dev == NULL)
+ if (yuv_stream->vdev == NULL || dec_stream->vdev == NULL)
return -EINVAL;
IVTV_DEBUG_INFO("ivtv ioctl: Select passthrough mode\n");
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index 460db03b0ba..d07ad6c3902 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -93,7 +93,7 @@ void ivtv_udma_alloc(struct ivtv *itv)
{
if (itv->udma.SG_handle == 0) {
/* Map DMA Page Array Buffer */
- itv->udma.SG_handle = pci_map_single(itv->dev, itv->udma.SGarray,
+ itv->udma.SG_handle = pci_map_single(itv->pdev, itv->udma.SGarray,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
ivtv_udma_sync_for_cpu(itv);
}
@@ -147,7 +147,7 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
}
/* Map SG List */
- dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array (dma, ivtv_dest_addr, 0, -1);
@@ -172,7 +172,7 @@ void ivtv_udma_unmap(struct ivtv *itv)
/* Unmap Scatterlist */
if (dma->SG_length) {
- pci_unmap_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ pci_unmap_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
dma->SG_length = 0;
}
/* sync DMA */
@@ -191,13 +191,13 @@ void ivtv_udma_free(struct ivtv *itv)
/* Unmap SG Array */
if (itv->udma.SG_handle) {
- pci_unmap_single(itv->dev, itv->udma.SG_handle,
+ pci_unmap_single(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
/* Unmap Scatterlist */
if (itv->udma.SG_length) {
- pci_unmap_sg(itv->dev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
+ pci_unmap_sg(itv->pdev, itv->udma.SGlist, itv->udma.page_count, PCI_DMA_TODEVICE);
}
for (i = 0; i < IVTV_DMA_SG_OSD_ENT; i++) {
diff --git a/drivers/media/video/ivtv/ivtv-udma.h b/drivers/media/video/ivtv/ivtv-udma.h
index df727e23be0..ee3c9efb5b7 100644
--- a/drivers/media/video/ivtv/ivtv-udma.h
+++ b/drivers/media/video/ivtv/ivtv-udma.h
@@ -35,13 +35,13 @@ void ivtv_udma_start(struct ivtv *itv);
static inline void ivtv_udma_sync_for_device(struct ivtv *itv)
{
- pci_dma_sync_single_for_device((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+ pci_dma_sync_single_for_device(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
static inline void ivtv_udma_sync_for_cpu(struct ivtv *itv)
{
- pci_dma_sync_single_for_cpu((struct pci_dev *)itv->dev, itv->udma.SG_handle,
+ pci_dma_sync_single_for_cpu(itv->pdev, itv->udma.SG_handle,
sizeof(itv->udma.SGarray), PCI_DMA_TODEVICE);
}
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 5c5d1c462fe..f420d31b937 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -185,6 +185,8 @@ static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
size = 4 + ((43 * line + 3) & ~3);
} else {
memcpy(dst + sd, "itv0", 4);
+ cpu_to_le32s(&linemask[0]);
+ cpu_to_le32s(&linemask[1]);
memcpy(dst + sd + 4, &linemask[0], 8);
size = 12 + ((43 * line + 3) & ~3);
}
diff --git a/drivers/media/video/ivtv/ivtv-version.h b/drivers/media/video/ivtv/ivtv-version.h
index 8cd753d30bf..b530dec399d 100644
--- a/drivers/media/video/ivtv/ivtv-version.h
+++ b/drivers/media/video/ivtv/ivtv-version.h
@@ -23,7 +23,7 @@
#define IVTV_DRIVER_NAME "ivtv"
#define IVTV_DRIVER_VERSION_MAJOR 1
#define IVTV_DRIVER_VERSION_MINOR 4
-#define IVTV_DRIVER_VERSION_PATCHLEVEL 0
+#define IVTV_DRIVER_VERSION_PATCHLEVEL 1
#define IVTV_VERSION __stringify(IVTV_DRIVER_VERSION_MAJOR) "." __stringify(IVTV_DRIVER_VERSION_MINOR) "." __stringify(IVTV_DRIVER_VERSION_PATCHLEVEL)
#define IVTV_DRIVER_VERSION KERNEL_VERSION(IVTV_DRIVER_VERSION_MAJOR,IVTV_DRIVER_VERSION_MINOR,IVTV_DRIVER_VERSION_PATCHLEVEL)
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index ee91107376c..7912ed6b72e 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -103,7 +103,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
dma->page_count = 0;
return -ENOMEM;
}
- dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
+ dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
/* Fill SG Array with new values */
ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
@@ -910,7 +910,7 @@ static void ivtv_yuv_init(struct ivtv *itv)
/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
if (yi->blanking_ptr) {
- yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
+ yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
} else {
yi->blanking_dmaptr = 0;
IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
@@ -1237,7 +1237,7 @@ void ivtv_yuv_close(struct ivtv *itv)
if (yi->blanking_ptr) {
kfree(yi->blanking_ptr);
yi->blanking_ptr = NULL;
- pci_unmap_single(itv->dev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
+ pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
}
/* Invalidate the old dimension information */
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 36abd2aef6f..66e6eb51307 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -1192,12 +1192,12 @@ static int ivtvfb_init_card(struct ivtv *itv)
static int __init ivtvfb_callback_init(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+ struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (ivtvfb_init_card(itv) == 0) {
IVTVFB_INFO("Framebuffer registered on %s\n",
- itv->device.name);
+ itv->v4l2_dev.name);
(*(int *)p)++;
}
}
@@ -1207,7 +1207,7 @@ static int __init ivtvfb_callback_init(struct device *dev, void *p)
static int ivtvfb_callback_cleanup(struct device *dev, void *p)
{
struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
- struct ivtv *itv = container_of(v4l2_dev, struct ivtv, device);
+ struct ivtv *itv = container_of(v4l2_dev, struct ivtv, v4l2_dev);
if (itv && (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
if (unregister_framebuffer(&itv->osd_info->ivtvfb_info)) {
diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c
index bae2d2beb70..841024b6bcd 100644
--- a/drivers/media/video/ks0127.c
+++ b/drivers/media/video/ks0127.c
@@ -39,19 +39,20 @@
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/i2c.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "ks0127.h"
MODULE_DESCRIPTION("KS0127 video decoder driver");
MODULE_AUTHOR("Ryan Drake");
MODULE_LICENSE("GPL");
-#define KS_TYPE_UNKNOWN 0
-#define KS_TYPE_0122S 1
-#define KS_TYPE_0127 2
-#define KS_TYPE_0127B 3
+/* Addresses */
+#define I2C_KS0127_ADDON 0xD8
+#define I2C_KS0127_ONBOARD 0xDA
+
/* ks0127 control registers */
#define KS_STAT 0x00
@@ -197,15 +198,17 @@ struct adjust {
};
struct ks0127 {
- int format_width;
- int format_height;
- int cap_width;
- int cap_height;
- int norm;
- int ks_type;
+ struct v4l2_subdev sd;
+ v4l2_std_id norm;
+ int ident;
u8 regs[256];
};
+static inline struct ks0127 *to_ks0127(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ks0127, sd);
+}
+
static int debug; /* insmod parameter */
@@ -311,43 +314,45 @@ static void init_reg_defaults(void)
*/
-static u8 ks0127_read(struct i2c_client *c, u8 reg)
+static u8 ks0127_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
char val = 0;
struct i2c_msg msgs[] = {
- { c->addr, 0, sizeof(reg), &reg },
- { c->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
+ { client->addr, 0, sizeof(reg), &reg },
+ { client->addr, I2C_M_RD | I2C_M_NO_RD_ACK, sizeof(val), &val }
};
int ret;
- ret = i2c_transfer(c->adapter, msgs, ARRAY_SIZE(msgs));
+ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
if (ret != ARRAY_SIZE(msgs))
- v4l_dbg(1, debug, c, "read error\n");
+ v4l2_dbg(1, debug, sd, "read error\n");
return val;
}
-static void ks0127_write(struct i2c_client *c, u8 reg, u8 val)
+static void ks0127_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ks0127 *ks = to_ks0127(sd);
char msg[] = { reg, val };
- if (i2c_master_send(c, msg, sizeof(msg)) != sizeof(msg))
- v4l_dbg(1, debug, c, "write error\n");
+ if (i2c_master_send(client, msg, sizeof(msg)) != sizeof(msg))
+ v4l2_dbg(1, debug, sd, "write error\n");
ks->regs[reg] = val;
}
/* generic bit-twiddling */
-static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
+static void ks0127_and_or(struct v4l2_subdev *sd, u8 reg, u8 and_v, u8 or_v)
{
- struct ks0127 *ks = i2c_get_clientdata(client);
+ struct ks0127 *ks = to_ks0127(sd);
u8 val = ks->regs[reg];
val = (val & and_v) | or_v;
- ks0127_write(client, reg, val);
+ ks0127_write(sd, reg, val);
}
@@ -355,439 +360,363 @@ static void ks0127_and_or(struct i2c_client *client, u8 reg, u8 and_v, u8 or_v)
/****************************************************************************
* ks0127 private api
****************************************************************************/
-static void ks0127_reset(struct i2c_client *c)
+static void ks0127_init(struct v4l2_subdev *sd)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
+ struct ks0127 *ks = to_ks0127(sd);
u8 *table = reg_defaults;
int i;
- ks->ks_type = KS_TYPE_UNKNOWN;
+ ks->ident = V4L2_IDENT_KS0127;
- v4l_dbg(1, debug, c, "reset\n");
+ v4l2_dbg(1, debug, sd, "reset\n");
msleep(1);
/* initialize all registers to known values */
/* (except STAT, 0x21, 0x22, TEST and 0x38,0x39) */
for (i = 1; i < 33; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
for (i = 35; i < 40; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
for (i = 41; i < 56; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
for (i = 58; i < 64; i++)
- ks0127_write(c, i, table[i]);
+ ks0127_write(sd, i, table[i]);
- if ((ks0127_read(c, KS_STAT) & 0x80) == 0) {
- ks->ks_type = KS_TYPE_0122S;
- v4l_dbg(1, debug, c, "ks0122s found\n");
+ if ((ks0127_read(sd, KS_STAT) & 0x80) == 0) {
+ ks->ident = V4L2_IDENT_KS0122S;
+ v4l2_dbg(1, debug, sd, "ks0122s found\n");
return;
}
- switch (ks0127_read(c, KS_CMDE) & 0x0f) {
+ switch (ks0127_read(sd, KS_CMDE) & 0x0f) {
case 0:
- ks->ks_type = KS_TYPE_0127;
- v4l_dbg(1, debug, c, "ks0127 found\n");
+ v4l2_dbg(1, debug, sd, "ks0127 found\n");
break;
case 9:
- ks->ks_type = KS_TYPE_0127B;
- v4l_dbg(1, debug, c, "ks0127B Revision A found\n");
+ ks->ident = V4L2_IDENT_KS0127B;
+ v4l2_dbg(1, debug, sd, "ks0127B Revision A found\n");
break;
default:
- v4l_dbg(1, debug, c, "unknown revision\n");
+ v4l2_dbg(1, debug, sd, "unknown revision\n");
break;
}
}
-static int ks0127_command(struct i2c_client *c, unsigned cmd, void *arg)
+static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
- int *iarg = (int *)arg;
- int status;
-
- if (!ks)
- return -ENODEV;
+ struct ks0127 *ks = to_ks0127(sd);
+
+ switch (route->input) {
+ case KS_INPUT_COMPOSITE_1:
+ case KS_INPUT_COMPOSITE_2:
+ case KS_INPUT_COMPOSITE_3:
+ case KS_INPUT_COMPOSITE_4:
+ case KS_INPUT_COMPOSITE_5:
+ case KS_INPUT_COMPOSITE_6:
+ v4l2_dbg(1, debug, sd,
+ "s_routing %d: Composite\n", route->input);
+ /* autodetect 50/60 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
+ /* VSE=0 */
+ ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
+ /* set input line */
+ ks0127_and_or(sd, KS_CMDB, 0xb0, route->input);
+ /* non-freerunning mode */
+ ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
+ /* analog input */
+ ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
+ /* enable chroma demodulation */
+ ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
+ /* chroma trap, HYBWR=1 */
+ ks0127_and_or(sd, KS_LUMA, 0x00,
+ (reg_defaults[KS_LUMA])|0x0c);
+ /* scaler fullbw, luma comb off */
+ ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
+ /* manual chroma comb .25 .5 .25 */
+ ks0127_and_or(sd, KS_VERTIC, 0x0f, 0x90);
+
+ /* chroma path delay */
+ ks0127_and_or(sd, KS_CHROMB, 0x0f, 0x90);
+
+ ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
+ break;
- switch (cmd) {
- case DECODER_INIT:
- v4l_dbg(1, debug, c, "DECODER_INIT\n");
- ks0127_reset(c);
+ case KS_INPUT_SVIDEO_1:
+ case KS_INPUT_SVIDEO_2:
+ case KS_INPUT_SVIDEO_3:
+ v4l2_dbg(1, debug, sd,
+ "s_routing %d: S-Video\n", route->input);
+ /* autodetect 50/60 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
+ /* VSE=0 */
+ ks0127_and_or(sd, KS_CMDA, ~0x40, 0x00);
+ /* set input line */
+ ks0127_and_or(sd, KS_CMDB, 0xb0, route->input);
+ /* non-freerunning mode */
+ ks0127_and_or(sd, KS_CMDC, 0x70, 0x0a);
+ /* analog input */
+ ks0127_and_or(sd, KS_CMDD, 0x03, 0x00);
+ /* enable chroma demodulation */
+ ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x00);
+ ks0127_and_or(sd, KS_LUMA, 0x00,
+ reg_defaults[KS_LUMA]);
+ /* disable luma comb */
+ ks0127_and_or(sd, KS_VERTIA, 0x08,
+ (reg_defaults[KS_VERTIA]&0xf0)|0x01);
+ ks0127_and_or(sd, KS_VERTIC, 0x0f,
+ reg_defaults[KS_VERTIC]&0xf0);
+
+ ks0127_and_or(sd, KS_CHROMB, 0x0f,
+ reg_defaults[KS_CHROMB]&0xf0);
+
+ ks0127_write(sd, KS_UGAIN, reg_defaults[KS_UGAIN]);
+ ks0127_write(sd, KS_VGAIN, reg_defaults[KS_VGAIN]);
+ ks0127_write(sd, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
+ ks0127_write(sd, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
break;
- case DECODER_SET_INPUT:
- switch(*iarg) {
- case KS_INPUT_COMPOSITE_1:
- case KS_INPUT_COMPOSITE_2:
- case KS_INPUT_COMPOSITE_3:
- case KS_INPUT_COMPOSITE_4:
- case KS_INPUT_COMPOSITE_5:
- case KS_INPUT_COMPOSITE_6:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT %d: Composite\n", *iarg);
- /* autodetect 50/60 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
- /* VSE=0 */
- ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
- /* set input line */
- ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
- /* non-freerunning mode */
- ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
- /* analog input */
- ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
- /* enable chroma demodulation */
- ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
- /* chroma trap, HYBWR=1 */
- ks0127_and_or(c, KS_LUMA, 0x00,
- (reg_defaults[KS_LUMA])|0x0c);
- /* scaler fullbw, luma comb off */
- ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
- /* manual chroma comb .25 .5 .25 */
- ks0127_and_or(c, KS_VERTIC, 0x0f, 0x90);
-
- /* chroma path delay */
- ks0127_and_or(c, KS_CHROMB, 0x0f, 0x90);
-
- ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
- break;
-
- case KS_INPUT_SVIDEO_1:
- case KS_INPUT_SVIDEO_2:
- case KS_INPUT_SVIDEO_3:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT %d: S-Video\n", *iarg);
- /* autodetect 50/60 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
- /* VSE=0 */
- ks0127_and_or(c, KS_CMDA, ~0x40, 0x00);
- /* set input line */
- ks0127_and_or(c, KS_CMDB, 0xb0, *iarg);
- /* non-freerunning mode */
- ks0127_and_or(c, KS_CMDC, 0x70, 0x0a);
- /* analog input */
- ks0127_and_or(c, KS_CMDD, 0x03, 0x00);
- /* enable chroma demodulation */
- ks0127_and_or(c, KS_CTRACK, 0xcf, 0x00);
- ks0127_and_or(c, KS_LUMA, 0x00,
- reg_defaults[KS_LUMA]);
- /* disable luma comb */
- ks0127_and_or(c, KS_VERTIA, 0x08,
- (reg_defaults[KS_VERTIA]&0xf0)|0x01);
- ks0127_and_or(c, KS_VERTIC, 0x0f,
- reg_defaults[KS_VERTIC]&0xf0);
-
- ks0127_and_or(c, KS_CHROMB, 0x0f,
- reg_defaults[KS_CHROMB]&0xf0);
-
- ks0127_write(c, KS_UGAIN, reg_defaults[KS_UGAIN]);
- ks0127_write(c, KS_VGAIN, reg_defaults[KS_VGAIN]);
- ks0127_write(c, KS_UVOFFH, reg_defaults[KS_UVOFFH]);
- ks0127_write(c, KS_UVOFFL, reg_defaults[KS_UVOFFL]);
- break;
-
- case KS_INPUT_YUV656:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT 15: YUV656\n");
- if (ks->norm == VIDEO_MODE_NTSC ||
- ks->norm == KS_STD_PAL_M)
- /* force 60 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x03);
- else
- /* force 50 Hz */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x02);
-
- ks0127_and_or(c, KS_CMDA, 0xff, 0x40); /* VSE=1 */
- /* set input line and VALIGN */
- ks0127_and_or(c, KS_CMDB, 0xb0, (*iarg | 0x40));
- /* freerunning mode, */
- /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
- ks0127_and_or(c, KS_CMDC, 0x70, 0x87);
- /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
- ks0127_and_or(c, KS_CMDD, 0x03, 0x08);
- /* disable chroma demodulation */
- ks0127_and_or(c, KS_CTRACK, 0xcf, 0x30);
- /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
- ks0127_and_or(c, KS_LUMA, 0x00, 0x71);
- ks0127_and_or(c, KS_VERTIC, 0x0f,
- reg_defaults[KS_VERTIC]&0xf0);
-
- /* scaler fullbw, luma comb off */
- ks0127_and_or(c, KS_VERTIA, 0x08, 0x81);
-
- ks0127_and_or(c, KS_CHROMB, 0x0f,
- reg_defaults[KS_CHROMB]&0xf0);
-
- ks0127_and_or(c, KS_CON, 0x00, 0x00);
- ks0127_and_or(c, KS_BRT, 0x00, 32); /* spec: 34 */
- /* spec: 229 (e5) */
- ks0127_and_or(c, KS_SAT, 0x00, 0xe8);
- ks0127_and_or(c, KS_HUE, 0x00, 0);
-
- ks0127_and_or(c, KS_UGAIN, 0x00, 238);
- ks0127_and_or(c, KS_VGAIN, 0x00, 0x00);
-
- /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
- ks0127_and_or(c, KS_UVOFFH, 0x00, 0x4f);
- ks0127_and_or(c, KS_UVOFFL, 0x00, 0x00);
- break;
-
- default:
- v4l_dbg(1, debug, c,
- "DECODER_SET_INPUT: Unknown input %d\n", *iarg);
- break;
- }
-
- /* hack: CDMLPF sometimes spontaneously switches on; */
- /* force back off */
- ks0127_write(c, KS_DEMOD, reg_defaults[KS_DEMOD]);
+ case KS_INPUT_YUV656:
+ v4l2_dbg(1, debug, sd, "s_routing 15: YUV656\n");
+ if (ks->norm & V4L2_STD_525_60)
+ /* force 60 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x03);
+ else
+ /* force 50 Hz */
+ ks0127_and_or(sd, KS_CMDA, 0xfc, 0x02);
+
+ ks0127_and_or(sd, KS_CMDA, 0xff, 0x40); /* VSE=1 */
+ /* set input line and VALIGN */
+ ks0127_and_or(sd, KS_CMDB, 0xb0, (route->input | 0x40));
+ /* freerunning mode, */
+ /* TSTGEN = 1 TSTGFR=11 TSTGPH=0 TSTGPK=0 VMEM=1*/
+ ks0127_and_or(sd, KS_CMDC, 0x70, 0x87);
+ /* digital input, SYNDIR = 0 INPSL=01 CLKDIR=0 EAV=0 */
+ ks0127_and_or(sd, KS_CMDD, 0x03, 0x08);
+ /* disable chroma demodulation */
+ ks0127_and_or(sd, KS_CTRACK, 0xcf, 0x30);
+ /* HYPK =01 CTRAP = 0 HYBWR=0 PED=1 RGBH=1 UNIT=1 */
+ ks0127_and_or(sd, KS_LUMA, 0x00, 0x71);
+ ks0127_and_or(sd, KS_VERTIC, 0x0f,
+ reg_defaults[KS_VERTIC]&0xf0);
+
+ /* scaler fullbw, luma comb off */
+ ks0127_and_or(sd, KS_VERTIA, 0x08, 0x81);
+
+ ks0127_and_or(sd, KS_CHROMB, 0x0f,
+ reg_defaults[KS_CHROMB]&0xf0);
+
+ ks0127_and_or(sd, KS_CON, 0x00, 0x00);
+ ks0127_and_or(sd, KS_BRT, 0x00, 32); /* spec: 34 */
+ /* spec: 229 (e5) */
+ ks0127_and_or(sd, KS_SAT, 0x00, 0xe8);
+ ks0127_and_or(sd, KS_HUE, 0x00, 0);
+
+ ks0127_and_or(sd, KS_UGAIN, 0x00, 238);
+ ks0127_and_or(sd, KS_VGAIN, 0x00, 0x00);
+
+ /*UOFF:0x30, VOFF:0x30, TSTCGN=1 */
+ ks0127_and_or(sd, KS_UVOFFH, 0x00, 0x4f);
+ ks0127_and_or(sd, KS_UVOFFL, 0x00, 0x00);
break;
- case DECODER_SET_OUTPUT:
- switch(*iarg) {
- case KS_OUTPUT_YUV656E:
- v4l_dbg(1, debug, c,
- "DECODER_SET_OUTPUT: OUTPUT_YUV656E (Missing)\n");
- return -EINVAL;
-
- case KS_OUTPUT_EXV:
- v4l_dbg(1, debug, c,
- "DECODER_SET_OUTPUT: OUTPUT_EXV\n");
- ks0127_and_or(c, KS_OFMTA, 0xf0, 0x09);
- break;
- }
+ default:
+ v4l2_dbg(1, debug, sd,
+ "s_routing: Unknown input %d\n", route->input);
break;
+ }
- case DECODER_SET_NORM: /* sam This block mixes old and new norm names... */
- /* Set to automatic SECAM/Fsc mode */
- ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
-
- ks->norm = *iarg;
- switch (*iarg) {
- /* this is untested !! */
- /* It just detects PAL_N/NTSC_M (no special frequencies) */
- /* And you have to set the standard a second time afterwards */
- case VIDEO_MODE_AUTO:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: AUTO\n");
-
- /* The chip determines the format */
- /* based on the current field rate */
- ks0127_and_or(c, KS_CMDA, 0xfc, 0x00);
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
- /* This is wrong for PAL ! As I said, */
- /* you need to set the standard once again !! */
- ks->format_height = 240;
- ks->format_width = 704;
- break;
-
- case VIDEO_MODE_NTSC:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: NTSC_M\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
- ks->format_height = 240;
- ks->format_width = 704;
- break;
-
- case KS_STD_NTSC_N:
- v4l_dbg(1, debug, c,
- "KS0127_SET_NORM: NTSC_N (fixme)\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
- ks->format_height = 240;
- ks->format_width = 704;
- break;
-
- case VIDEO_MODE_PAL:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: PAL_N\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x20);
- ks->format_height = 290;
- ks->format_width = 704;
- break;
-
- case KS_STD_PAL_M:
- v4l_dbg(1, debug, c,
- "KS0127_SET_NORM: PAL_M (fixme)\n");
- ks0127_and_or(c, KS_CHROMA, 0x9f, 0x40);
- ks->format_height = 290;
- ks->format_width = 704;
- break;
-
- case VIDEO_MODE_SECAM:
- v4l_dbg(1, debug, c,
- "KS0127_SET_NORM: SECAM\n");
- ks->format_height = 290;
- ks->format_width = 704;
-
- /* set to secam autodetection */
- ks0127_and_or(c, KS_CHROMA, 0xdf, 0x20);
- ks0127_and_or(c, KS_DEMOD, 0xf0, 0x00);
- schedule_timeout_interruptible(HZ/10+1);
-
- /* did it autodetect? */
- if (ks0127_read(c, KS_DEMOD) & 0x40)
- break;
+ /* hack: CDMLPF sometimes spontaneously switches on; */
+ /* force back off */
+ ks0127_write(sd, KS_DEMOD, reg_defaults[KS_DEMOD]);
+ return 0;
+}
+static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct ks0127 *ks = to_ks0127(sd);
+
+ /* Set to automatic SECAM/Fsc mode */
+ ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
+
+ ks->norm = std;
+ if (std & V4L2_STD_NTSC) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: NTSC_M\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
+ } else if (std & V4L2_STD_PAL_N) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: NTSC_N (fixme)\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
+ } else if (std & V4L2_STD_PAL) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: PAL_N\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
+ } else if (std & V4L2_STD_PAL_M) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: PAL_M (fixme)\n");
+ ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
+ } else if (std & V4L2_STD_SECAM) {
+ v4l2_dbg(1, debug, sd,
+ "s_std: SECAM\n");
+
+ /* set to secam autodetection */
+ ks0127_and_or(sd, KS_CHROMA, 0xdf, 0x20);
+ ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x00);
+ schedule_timeout_interruptible(HZ/10+1);
+
+ /* did it autodetect? */
+ if (!(ks0127_read(sd, KS_DEMOD) & 0x40))
/* force to secam mode */
- ks0127_and_or(c, KS_DEMOD, 0xf0, 0x0f);
- break;
-
- default:
- v4l_dbg(1, debug, c,
- "DECODER_SET_NORM: Unknown norm %d\n", *iarg);
- break;
- }
- break;
-
- case DECODER_SET_PICTURE:
- v4l_dbg(1, debug, c,
- "DECODER_SET_PICTURE: not yet supported\n");
- return -EINVAL;
-
- /* sam todo: KS0127_SET_BRIGHTNESS: Merge into DECODER_SET_PICTURE */
- /* sam todo: KS0127_SET_CONTRAST: Merge into DECODER_SET_PICTURE */
- /* sam todo: KS0127_SET_HUE: Merge into DECODER_SET_PICTURE? */
- /* sam todo: KS0127_SET_SATURATION: Merge into DECODER_SET_PICTURE */
- /* sam todo: KS0127_SET_AGC_MODE: */
- /* sam todo: KS0127_SET_AGC: */
- /* sam todo: KS0127_SET_CHROMA_MODE: */
- /* sam todo: KS0127_SET_PIXCLK_MODE: */
- /* sam todo: KS0127_SET_GAMMA_MODE: */
- /* sam todo: KS0127_SET_UGAIN: */
- /* sam todo: KS0127_SET_VGAIN: */
- /* sam todo: KS0127_SET_INVALY: */
- /* sam todo: KS0127_SET_INVALU: */
- /* sam todo: KS0127_SET_INVALV: */
- /* sam todo: KS0127_SET_UNUSEY: */
- /* sam todo: KS0127_SET_UNUSEU: */
- /* sam todo: KS0127_SET_UNUSEV: */
- /* sam todo: KS0127_SET_VSALIGN_MODE: */
-
- case DECODER_ENABLE_OUTPUT:
- {
- int enable;
-
- iarg = arg;
- enable = (*iarg != 0);
- if (enable) {
- v4l_dbg(1, debug, c,
- "DECODER_ENABLE_OUTPUT on\n");
- /* All output pins on */
- ks0127_and_or(c, KS_OFMTA, 0xcf, 0x30);
- /* Obey the OEN pin */
- ks0127_and_or(c, KS_CDEM, 0x7f, 0x00);
- } else {
- v4l_dbg(1, debug, c,
- "DECODER_ENABLE_OUTPUT off\n");
- /* Video output pins off */
- ks0127_and_or(c, KS_OFMTA, 0xcf, 0x00);
- /* Ignore the OEN pin */
- ks0127_and_or(c, KS_CDEM, 0x7f, 0x80);
- }
- break;
+ ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x0f);
+ } else {
+ v4l2_dbg(1, debug, sd, "s_std: Unknown norm %llx\n",
+ (unsigned long long)std);
}
+ return 0;
+}
- /* sam todo: KS0127_SET_OUTPUT_MODE: */
- /* sam todo: KS0127_SET_WIDTH: */
- /* sam todo: KS0127_SET_HEIGHT: */
- /* sam todo: KS0127_SET_HSCALE: */
-
- case DECODER_GET_STATUS:
- v4l_dbg(1, debug, c, "DECODER_GET_STATUS\n");
- *iarg = 0;
- status = ks0127_read(c, KS_STAT);
- if (!(status & 0x20)) /* NOVID not set */
- *iarg = (*iarg | DECODER_STATUS_GOOD);
- if ((status & 0x01)) /* CLOCK set */
- *iarg = (*iarg | DECODER_STATUS_COLOR);
- if ((status & 0x08)) /* PALDET set */
- *iarg = (*iarg | DECODER_STATUS_PAL);
- else
- *iarg = (*iarg | DECODER_STATUS_NTSC);
- break;
-
- /* Catch any unknown command */
- default:
- v4l_dbg(1, debug, c, "unknown: 0x%08x\n", cmd);
- return -EINVAL;
+static int ks0127_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ v4l2_dbg(1, debug, sd, "s_stream(%d)\n", enable);
+ if (enable) {
+ /* All output pins on */
+ ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x30);
+ /* Obey the OEN pin */
+ ks0127_and_or(sd, KS_CDEM, 0x7f, 0x00);
+ } else {
+ /* Video output pins off */
+ ks0127_and_or(sd, KS_OFMTA, 0xcf, 0x00);
+ /* Ignore the OEN pin */
+ ks0127_and_or(sd, KS_CDEM, 0x7f, 0x80);
}
return 0;
}
+static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
+{
+ int stat = V4L2_IN_ST_NO_SIGNAL;
+ u8 status;
+ v4l2_std_id std = V4L2_STD_ALL;
+
+ status = ks0127_read(sd, KS_STAT);
+ if (!(status & 0x20)) /* NOVID not set */
+ stat = 0;
+ if (!(status & 0x01)) /* CLOCK set */
+ stat |= V4L2_IN_ST_NO_COLOR;
+ if ((status & 0x08)) /* PALDET set */
+ std = V4L2_STD_PAL;
+ else
+ std = V4L2_STD_NTSC;
+ if (pstd)
+ *pstd = std;
+ if (pstatus)
+ *pstatus = stat;
+ return 0;
+}
+
+static int ks0127_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ v4l2_dbg(1, debug, sd, "querystd\n");
+ return ks0127_status(sd, NULL, std);
+}
-/* Addresses to scan */
-#define I2C_KS0127_ADDON 0xD8
-#define I2C_KS0127_ONBOARD 0xDA
+static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ v4l2_dbg(1, debug, sd, "g_input_status\n");
+ return ks0127_status(sd, status, NULL);
+}
+
+static int ks0127_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct ks0127 *ks = to_ks0127(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, ks->ident, 0);
+}
+
+/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = {
- I2C_KS0127_ADDON >> 1,
- I2C_KS0127_ONBOARD >> 1,
- I2C_CLIENT_END
+static const struct v4l2_subdev_core_ops ks0127_core_ops = {
+ .g_chip_ident = ks0127_g_chip_ident,
};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_tuner_ops ks0127_tuner_ops = {
+ .s_std = ks0127_s_std,
+};
+
+static const struct v4l2_subdev_video_ops ks0127_video_ops = {
+ .s_routing = ks0127_s_routing,
+ .s_stream = ks0127_s_stream,
+ .querystd = ks0127_querystd,
+ .g_input_status = ks0127_g_input_status,
+};
+
+static const struct v4l2_subdev_ops ks0127_ops = {
+ .core = &ks0127_core_ops,
+ .tuner = &ks0127_tuner_ops,
+ .video = &ks0127_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
+
-static int ks0127_probe(struct i2c_client *c, const struct i2c_device_id *id)
+static int ks0127_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct ks0127 *ks;
+ struct v4l2_subdev *sd;
- v4l_info(c, "%s chip found @ 0x%x (%s)\n",
- c->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
- c->addr << 1, c->adapter->name);
+ v4l_info(client, "%s chip found @ 0x%x (%s)\n",
+ client->addr == (I2C_KS0127_ADDON >> 1) ? "addon" : "on-board",
+ client->addr << 1, client->adapter->name);
ks = kzalloc(sizeof(*ks), GFP_KERNEL);
if (ks == NULL)
return -ENOMEM;
-
- i2c_set_clientdata(c, ks);
-
- ks->ks_type = KS_TYPE_UNKNOWN;
+ sd = &ks->sd;
+ v4l2_i2c_subdev_init(sd, client, &ks0127_ops);
/* power up */
init_reg_defaults();
- ks0127_write(c, KS_CMDA, 0x2c);
+ ks0127_write(sd, KS_CMDA, 0x2c);
mdelay(10);
/* reset the device */
- ks0127_reset(c);
+ ks0127_init(sd);
return 0;
}
-static int ks0127_remove(struct i2c_client *c)
+static int ks0127_remove(struct i2c_client *client)
{
- struct ks0127 *ks = i2c_get_clientdata(c);
-
- ks0127_write(c, KS_OFMTA, 0x20); /* tristate */
- ks0127_write(c, KS_CMDA, 0x2c | 0x80); /* power down */
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
- kfree(ks);
+ v4l2_device_unregister_subdev(sd);
+ ks0127_write(sd, KS_OFMTA, 0x20); /* tristate */
+ ks0127_write(sd, KS_CMDA, 0x2c | 0x80); /* power down */
+ kfree(to_ks0127(sd));
return 0;
}
-static int ks0127_legacy_probe(struct i2c_adapter *adapter)
-{
- return adapter->id == I2C_HW_B_ZR36067;
-}
-
static const struct i2c_device_id ks0127_id[] = {
{ "ks0127", 0 },
+ { "ks0127b", 0 },
+ { "ks0122s", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ks0127_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "ks0127",
- .driverid = I2C_DRIVERID_KS0127,
- .command = ks0127_command,
.probe = ks0127_probe,
.remove = ks0127_remove,
- .legacy_probe = ks0127_legacy_probe,
.id_table = ks0127_id,
};
diff --git a/drivers/media/video/ks0127.h b/drivers/media/video/ks0127.h
index 1ec578833ae..cb8abd5403b 100644
--- a/drivers/media/video/ks0127.h
+++ b/drivers/media/video/ks0127.h
@@ -24,8 +24,6 @@
#ifndef KS0127_H
#define KS0127_H
-#include <linux/videodev.h>
-
/* input channels */
#define KS_INPUT_COMPOSITE_1 0
#define KS_INPUT_COMPOSITE_2 1
diff --git a/drivers/media/video/m52790.c b/drivers/media/video/m52790.c
index de397ef57b4..1f340fefc49 100644
--- a/drivers/media/video/m52790.c
+++ b/drivers/media/video/m52790.c
@@ -132,11 +132,6 @@ static int m52790_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int m52790_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops m52790_core_ops = {
@@ -210,8 +205,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "m52790",
- .driverid = I2C_DRIVERID_M52790,
- .command = m52790_command,
.probe = m52790_probe,
.remove = m52790_remove,
.id_table = m52790_id,
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index b76e33d5c86..2ad11f0999c 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1017,7 +1017,6 @@ static int meyeioc_stilljcapt(int *len)
static int vidioc_querycap(struct file *file, void *fh,
struct v4l2_capability *cap)
{
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, "meye");
strcpy(cap->card, "meye");
sprintf(cap->bus_info, "PCI:%s", pci_name(meye.mchip_dev));
@@ -1036,8 +1035,6 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
if (i->index != 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = 0;
strcpy(i->name, "Camera");
i->type = V4L2_INPUT_TYPE_CAMERA;
@@ -1259,22 +1256,13 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
if (f->index > 1)
return -EINVAL;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->index == 0) {
/* standard YUV 422 capture */
- memset(f, 0, sizeof(*f));
- f->index = 0;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = 0;
strcpy(f->description, "YUV422");
f->pixelformat = V4L2_PIX_FMT_YUYV;
} else {
/* compressed MJPEG capture */
- memset(f, 0, sizeof(*f));
- f->index = 1;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strcpy(f->description, "MJPEG");
f->pixelformat = V4L2_PIX_FMT_MJPEG;
@@ -1286,9 +1274,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
return -EINVAL;
@@ -1319,12 +1304,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
switch (meye.mchip_mode) {
case MCHIP_HIC_MODE_CONT_OUT:
default:
@@ -1341,8 +1320,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
f->fmt.pix.bytesperline = f->fmt.pix.width * 2;
f->fmt.pix.sizeimage = f->fmt.pix.height *
f->fmt.pix.bytesperline;
- f->fmt.pix.colorspace = 0;
- f->fmt.pix.priv = 0;
return 0;
}
@@ -1350,9 +1327,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
return -EINVAL;
@@ -1398,9 +1372,6 @@ static int vidioc_reqbufs(struct file *file, void *fh,
{
int i;
- if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (req->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
@@ -1441,15 +1412,11 @@ static int vidioc_reqbufs(struct file *file, void *fh,
static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
- int index = buf->index;
+ unsigned int index = buf->index;
- if (index < 0 || index >= gbuffers)
+ if (index >= gbuffers)
return -EINVAL;
- memset(buf, 0, sizeof(*buf));
-
- buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf->index = index;
buf->bytesused = meye.grab_buffer[index].size;
buf->flags = V4L2_BUF_FLAG_MAPPED;
@@ -1471,13 +1438,10 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
- if (buf->index < 0 || buf->index >= gbuffers)
+ if (buf->index >= gbuffers)
return -EINVAL;
if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
@@ -1497,9 +1461,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
int reqnr;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index 4d7a9185211..9e8e06cfe5c 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -366,29 +366,6 @@ int msp_sleep(struct msp_state *state, int timeout)
}
/* ------------------------------------------------------------------------ */
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static int msp_mode_v4l2_to_v4l1(int rxsubchans, int audmode)
-{
- 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;
-}
-
-static int msp_mode_v4l1_to_v4l2(int mode)
-{
- if (mode & VIDEO_SOUND_STEREO)
- return V4L2_TUNER_MODE_STEREO;
- if (mode & VIDEO_SOUND_LANG2)
- return V4L2_TUNER_MODE_LANG2;
- if (mode & VIDEO_SOUND_LANG1)
- return V4L2_TUNER_MODE_LANG1;
- return V4L2_TUNER_MODE_MONO;
-}
-#endif
static int msp_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
@@ -482,96 +459,6 @@ static int msp_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return 0;
}
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static long msp_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct msp_state *state = to_state(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- switch (cmd) {
- /* --- v4l ioctls --- */
- /* take care: bttv does userspace copying, we'll get a
- kernel pointer here... */
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- va->flags |= VIDEO_AUDIO_VOLUME | VIDEO_AUDIO_MUTABLE;
- if (state->has_sound_processing)
- va->flags |= VIDEO_AUDIO_BALANCE |
- VIDEO_AUDIO_BASS |
- VIDEO_AUDIO_TREBLE;
- if (state->muted)
- va->flags |= VIDEO_AUDIO_MUTE;
- va->volume = state->volume;
- va->balance = state->volume ? state->balance : 32768;
- va->bass = state->bass;
- va->treble = state->treble;
-
- if (state->radio)
- break;
- if (state->opmode == OPMODE_AUTOSELECT)
- msp_detect_stereo(client);
- va->mode = msp_mode_v4l2_to_v4l1(state->rxsubchans, state->audmode);
- break;
- }
-
- case VIDIOCSAUDIO:
- {
- struct video_audio *va = arg;
-
- state->muted = (va->flags & VIDEO_AUDIO_MUTE);
- state->volume = va->volume;
- state->balance = va->balance;
- state->bass = va->bass;
- 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);
- }
- break;
- }
-
- case VIDIOCSCHAN:
- {
- struct video_channel *vc = arg;
- int update = 0;
- v4l2_std_id std;
-
- if (state->radio)
- update = 1;
- state->radio = 0;
- if (vc->norm == VIDEO_MODE_PAL)
- std = V4L2_STD_PAL;
- else if (vc->norm == VIDEO_MODE_SECAM)
- std = V4L2_STD_SECAM;
- else
- std = V4L2_STD_NTSC;
- if (std != state->v4l2_std) {
- state->v4l2_std = std;
- update = 1;
- }
- if (update)
- msp_wake_thread(client);
- break;
- }
-
- case VIDIOCSFREQ:
- {
- /* new channel -- kick audio carrier scan */
- msp_wake_thread(client);
- break;
- }
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
-#endif
-
/* --- v4l2 ioctls --- */
static int msp_s_radio(struct v4l2_subdev *sd)
{
@@ -713,22 +600,24 @@ static int msp_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
struct msp_state *state = to_state(sd);
switch (qc->id) {
- case V4L2_CID_AUDIO_VOLUME:
- case V4L2_CID_AUDIO_MUTE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- break;
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ default:
+ break;
}
if (!state->has_sound_processing)
return -EINVAL;
switch (qc->id) {
- case V4L2_CID_AUDIO_LOUDNESS:
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
- default:
- return -EINVAL;
+ case V4L2_CID_AUDIO_LOUDNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ case V4L2_CID_AUDIO_BALANCE:
+ case V4L2_CID_AUDIO_BASS:
+ case V4L2_CID_AUDIO_TREBLE:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
+ default:
+ return -EINVAL;
}
return 0;
}
@@ -820,9 +709,6 @@ static const struct v4l2_subdev_core_ops msp_core_ops = {
.g_ctrl = msp_g_ctrl,
.s_ctrl = msp_s_ctrl,
.queryctrl = msp_queryctrl,
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
- .ioctl = msp_ioctl,
-#endif
};
static const struct v4l2_subdev_tuner_ops msp_tuner_ops = {
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index c1bf75ef274..fa7e5093ede 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -12,7 +12,6 @@
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/log2.h>
-#include <linux/gpio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -73,9 +72,7 @@ struct mt9m001 {
struct i2c_client *client;
struct soc_camera_device icd;
int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
- int switch_gpio;
unsigned char autoexposure;
- unsigned char datawidth;
};
static int reg_read(struct soc_camera_device *icd, const u8 reg)
@@ -181,92 +178,28 @@ static int mt9m001_stop_capture(struct soc_camera_device *icd)
return 0;
}
-static int bus_switch_request(struct mt9m001 *mt9m001,
- struct soc_camera_link *icl)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- int ret;
- unsigned int gpio = icl->gpio;
-
- if (gpio_is_valid(gpio)) {
- /* We have a data bus switch. */
- ret = gpio_request(gpio, "mt9m001");
- if (ret < 0) {
- dev_err(&mt9m001->client->dev, "Cannot get GPIO %u\n",
- gpio);
- return ret;
- }
-
- ret = gpio_direction_output(gpio, 0);
- if (ret < 0) {
- dev_err(&mt9m001->client->dev,
- "Cannot set GPIO %u to output\n", gpio);
- gpio_free(gpio);
- return ret;
- }
- }
-
- mt9m001->switch_gpio = gpio;
-#else
- mt9m001->switch_gpio = -EINVAL;
-#endif
- return 0;
-}
-
-static void bus_switch_release(struct mt9m001 *mt9m001)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- if (gpio_is_valid(mt9m001->switch_gpio))
- gpio_free(mt9m001->switch_gpio);
-#endif
-}
-
-static int bus_switch_act(struct mt9m001 *mt9m001, int go8bit)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- if (!gpio_is_valid(mt9m001->switch_gpio))
- return -ENODEV;
-
- gpio_set_value_cansleep(mt9m001->switch_gpio, go8bit);
- return 0;
-#else
- return -ENODEV;
-#endif
-}
-
-static int bus_switch_possible(struct mt9m001 *mt9m001)
-{
-#ifdef CONFIG_MT9M001_PCA9536_SWITCH
- return gpio_is_valid(mt9m001->switch_gpio);
-#else
- return 0;
-#endif
-}
-
static int mt9m001_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
- unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
- int ret;
+ struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
+ unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
- /* Flags validity verified in test_bus_param */
+ /* Only one width bit may be set */
+ if (!is_power_of_2(width_flag))
+ return -EINVAL;
- if ((mt9m001->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) ||
- (mt9m001->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) ||
- (mt9m001->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) {
- /* Well, we actually only can do 10 or 8 bits... */
- if (width_flag == SOCAM_DATAWIDTH_9)
- return -EINVAL;
- ret = bus_switch_act(mt9m001,
- width_flag == SOCAM_DATAWIDTH_8);
- if (ret < 0)
- return ret;
+ if (icl->set_bus_param)
+ return icl->set_bus_param(icl, width_flag);
- mt9m001->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
- }
+ /*
+ * Without board specific bus width settings we only support the
+ * sensors native bus width
+ */
+ if (width_flag == SOCAM_DATAWIDTH_10)
+ return 0;
- return 0;
+ return -EINVAL;
}
static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
@@ -274,18 +207,20 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
/* MT9M001 has all capture_format parameters fixed */
- unsigned long flags = SOCAM_DATAWIDTH_10 | SOCAM_PCLK_SAMPLE_RISING |
+ unsigned long flags = SOCAM_PCLK_SAMPLE_RISING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
- SOCAM_MASTER;
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
- if (bus_switch_possible(mt9m001))
- flags |= SOCAM_DATAWIDTH_8;
+ if (icl->query_bus_param)
+ flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
+ else
+ flags |= SOCAM_DATAWIDTH_10;
return soc_camera_apply_sensor_flags(icl, flags);
}
-static int mt9m001_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+static int mt9m001_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
int ret;
@@ -324,6 +259,20 @@ static int mt9m001_set_fmt(struct soc_camera_device *icd,
return ret;
}
+static int mt9m001_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = f->fmt.pix.width,
+ .height = f->fmt.pix.height,
+ };
+
+ /* No support for scaling so far, just crop. TODO: use skipping */
+ return mt9m001_set_crop(icd, &rect);
+}
+
static int mt9m001_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
@@ -449,6 +398,7 @@ static struct soc_camera_ops mt9m001_ops = {
.release = mt9m001_release,
.start_capture = mt9m001_start_capture,
.stop_capture = mt9m001_stop_capture,
+ .set_crop = mt9m001_set_crop,
.set_fmt = mt9m001_set_fmt,
.try_fmt = mt9m001_try_fmt,
.set_bus_param = mt9m001_set_bus_param,
@@ -583,6 +533,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
s32 data;
int ret;
+ unsigned long flags;
/* We must have a parent by now. And it cannot be a wrong one.
* So this entire test is completely redundant. */
@@ -603,18 +554,10 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
case 0x8421:
mt9m001->model = V4L2_IDENT_MT9M001C12ST;
icd->formats = mt9m001_colour_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9m001_colour_formats);
- else
- icd->num_formats = 1;
break;
case 0x8431:
mt9m001->model = V4L2_IDENT_MT9M001C12STM;
icd->formats = mt9m001_monochrome_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9m001_monochrome_formats);
- else
- icd->num_formats = 1;
break;
default:
ret = -ENODEV;
@@ -623,6 +566,26 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
goto ei2c;
}
+ icd->num_formats = 0;
+
+ /*
+ * This is a 10bit sensor, so by default we only allow 10bit.
+ * The platform may support different bus widths due to
+ * different routing of the data lines.
+ */
+ if (icl->query_bus_param)
+ flags = icl->query_bus_param(icl);
+ else
+ flags = SOCAM_DATAWIDTH_10;
+
+ if (flags & SOCAM_DATAWIDTH_10)
+ icd->num_formats++;
+ else
+ icd->formats++;
+
+ if (flags & SOCAM_DATAWIDTH_8)
+ icd->num_formats++;
+
dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
data == 0x8431 ? "C12STM" : "C12ST");
@@ -688,18 +651,10 @@ static int mt9m001_probe(struct i2c_client *client,
icd->height_max = 1024;
icd->y_skip_top = 1;
icd->iface = icl->bus_id;
- /* Default datawidth - this is the only width this camera (normally)
- * supports. It is only with extra logic that it can support
- * other widths. Therefore it seems to be a sensible default. */
- mt9m001->datawidth = 10;
/* Simulated autoexposure. If enabled, we calculate shutter width
* ourselves in the driver based on vertical blanking and frame width */
mt9m001->autoexposure = 1;
- ret = bus_switch_request(mt9m001, icl);
- if (ret)
- goto eswinit;
-
ret = soc_camera_device_register(icd);
if (ret)
goto eisdr;
@@ -707,8 +662,6 @@ static int mt9m001_probe(struct i2c_client *client,
return 0;
eisdr:
- bus_switch_release(mt9m001);
-eswinit:
kfree(mt9m001);
return ret;
}
@@ -718,7 +671,6 @@ static int mt9m001_remove(struct i2c_client *client)
struct mt9m001 *mt9m001 = i2c_get_clientdata(client);
soc_camera_device_unregister(&mt9m001->icd);
- bus_switch_release(mt9m001);
kfree(mt9m001);
return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 5b8e20979cc..cdd1ddb5138 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -152,7 +152,7 @@ struct mt9m111 {
struct soc_camera_device icd;
int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
enum mt9m111_context context;
- unsigned int left, top, width, height;
+ struct v4l2_rect rect;
u32 pixfmt;
unsigned char autoexposure;
unsigned char datawidth;
@@ -249,12 +249,13 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
return reg_write(CONTEXT_CONTROL, valA);
}
-static int mt9m111_setup_rect(struct soc_camera_device *icd)
+static int mt9m111_setup_rect(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
int ret, is_raw_format;
- int width = mt9m111->width;
- int height = mt9m111->height;
+ int width = rect->width;
+ int height = rect->height;
if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8)
|| (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16))
@@ -262,9 +263,9 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd)
else
is_raw_format = 0;
- ret = reg_write(COLUMN_START, mt9m111->left);
+ ret = reg_write(COLUMN_START, rect->left);
if (!ret)
- ret = reg_write(ROW_START, mt9m111->top);
+ ret = reg_write(ROW_START, rect->top);
if (is_raw_format) {
if (!ret)
@@ -393,6 +394,8 @@ static int mt9m111_disable(struct soc_camera_device *icd)
static int mt9m111_reset(struct soc_camera_device *icd)
{
+ struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
int ret;
ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -401,6 +404,10 @@ static int mt9m111_reset(struct soc_camera_device *icd)
if (!ret)
ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
| MT9M111_RESET_RESET_SOC);
+
+ if (icl->reset)
+ icl->reset(&mt9m111->client->dev);
+
return ret;
}
@@ -420,7 +427,7 @@ static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
- SOCAM_DATAWIDTH_8;
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
return soc_camera_apply_sensor_flags(icl, flags);
}
@@ -430,6 +437,22 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
return 0;
}
+static int mt9m111_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ int ret;
+
+ dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
+ __func__, rect->left, rect->top, rect->width,
+ rect->height);
+
+ ret = mt9m111_setup_rect(icd, rect);
+ if (!ret)
+ mt9m111->rect = *rect;
+ return ret;
+}
+
static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
@@ -480,23 +503,27 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
}
static int mt9m111_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = mt9m111->rect.left,
+ .top = mt9m111->rect.top,
+ .width = pix->width,
+ .height = pix->height,
+ };
int ret;
- mt9m111->left = rect->left;
- mt9m111->top = rect->top;
- mt9m111->width = rect->width;
- mt9m111->height = rect->height;
-
dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n",
- __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width,
- mt9m111->height);
+ __func__, pix->pixelformat, rect.left, rect.top, rect.width,
+ rect.height);
- ret = mt9m111_setup_rect(icd);
+ ret = mt9m111_setup_rect(icd, &rect);
+ if (!ret)
+ ret = mt9m111_set_pixfmt(icd, pix->pixelformat);
if (!ret)
- ret = mt9m111_set_pixfmt(icd, pixfmt);
+ mt9m111->rect = rect;
return ret;
}
@@ -627,6 +654,7 @@ static struct soc_camera_ops mt9m111_ops = {
.release = mt9m111_release,
.start_capture = mt9m111_start_capture,
.stop_capture = mt9m111_stop_capture,
+ .set_crop = mt9m111_set_crop,
.set_fmt = mt9m111_set_fmt,
.try_fmt = mt9m111_try_fmt,
.query_bus_param = mt9m111_query_bus_param,
@@ -811,7 +839,7 @@ static int mt9m111_restore_state(struct soc_camera_device *icd)
mt9m111_set_context(icd, mt9m111->context);
mt9m111_set_pixfmt(icd, mt9m111->pixfmt);
- mt9m111_setup_rect(icd);
+ mt9m111_setup_rect(icd, &mt9m111->rect);
mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
mt9m111_set_global_gain(icd, icd->gain);
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 349d8e36553..23f9ce9d67e 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -144,13 +144,11 @@ static int mt9t031_init(struct soc_camera_device *icd)
int ret;
/* Disable chip output, synchronous option update */
- dev_dbg(icd->vdev->parent, "%s\n", __func__);
-
ret = reg_write(icd, MT9T031_RESET, 1);
if (ret >= 0)
ret = reg_write(icd, MT9T031_RESET, 0);
if (ret >= 0)
- ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
+ ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
return ret >= 0 ? 0 : -EIO;
}
@@ -158,14 +156,14 @@ static int mt9t031_init(struct soc_camera_device *icd)
static int mt9t031_release(struct soc_camera_device *icd)
{
/* Disable the chip */
- reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3);
+ reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2);
return 0;
}
static int mt9t031_start_capture(struct soc_camera_device *icd)
{
/* Switch to master "normal" mode */
- if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
+ if (reg_set(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
return -EIO;
return 0;
}
@@ -173,7 +171,7 @@ static int mt9t031_start_capture(struct soc_camera_device *icd)
static int mt9t031_stop_capture(struct soc_camera_device *icd)
{
/* Stop sensor readout */
- if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 3) < 0)
+ if (reg_clear(icd, MT9T031_OUTPUT_CONTROL, 2) < 0)
return -EIO;
return 0;
}
@@ -186,9 +184,9 @@ static int mt9t031_set_bus_param(struct soc_camera_device *icd,
return -EINVAL;
if (flags & SOCAM_PCLK_SAMPLE_FALLING)
- reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
- else
reg_clear(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
+ else
+ reg_set(icd, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
return 0;
}
@@ -201,67 +199,73 @@ static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
}
-static int mt9t031_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+/* Round up minima and round down maxima */
+static void recalculate_limits(struct soc_camera_device *icd,
+ u16 xskip, u16 yskip)
+{
+ icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip;
+ icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip;
+ icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip;
+ icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip;
+ icd->width_max = MT9T031_MAX_WIDTH / xskip;
+ icd->height_max = MT9T031_MAX_HEIGHT / yskip;
+}
+
+static int mt9t031_set_params(struct soc_camera_device *icd,
+ struct v4l2_rect *rect, u16 xskip, u16 yskip)
{
struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
int ret;
+ u16 xbin, ybin, width, height, left, top;
const u16 hblank = MT9T031_HORIZONTAL_BLANK,
vblank = MT9T031_VERTICAL_BLANK;
- u16 xbin, xskip = mt9t031->xskip, ybin, yskip = mt9t031->yskip,
- width = rect->width * xskip, height = rect->height * yskip;
- if (pixfmt) {
- /* S_FMT - use binning and skipping for scaling, recalculate */
- /* Is this more optimal than just a division? */
- for (xskip = 8; xskip > 1; xskip--)
- if (rect->width * xskip <= icd->width_max)
- break;
+ /* Make sure we don't exceed sensor limits */
+ if (rect->left + rect->width > icd->width_max)
+ rect->left = (icd->width_max - rect->width) / 2 + icd->x_min;
- for (yskip = 8; yskip > 1; yskip--)
- if (rect->height * yskip <= icd->height_max)
- break;
+ if (rect->top + rect->height > icd->height_max)
+ rect->top = (icd->height_max - rect->height) / 2 + icd->y_min;
- width = rect->width * xskip;
- height = rect->height * yskip;
-
- dev_dbg(&icd->dev, "xskip %u, width %u, yskip %u, height %u\n",
- xskip, width, yskip, height);
- }
+ width = rect->width * xskip;
+ height = rect->height * yskip;
+ left = rect->left * xskip;
+ top = rect->top * yskip;
xbin = min(xskip, (u16)3);
ybin = min(yskip, (u16)3);
- /* Make sure we don't exceed frame limits */
- if (rect->left + width > icd->width_max)
- rect->left = (icd->width_max - width) / 2;
-
- if (rect->top + height > icd->height_max)
- rect->top = (icd->height_max - height) / 2;
+ dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n",
+ xskip, width, rect->width, yskip, height, rect->height);
- /* Could just do roundup(rect->left, [xy]bin); but this is cheaper */
+ /* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */
switch (xbin) {
case 2:
- rect->left = (rect->left + 1) & ~1;
+ left = (left + 3) & ~3;
break;
case 3:
- rect->left = roundup(rect->left, 3);
+ left = roundup(left, 6);
}
switch (ybin) {
case 2:
- rect->top = (rect->top + 1) & ~1;
+ top = (top + 3) & ~3;
break;
case 3:
- rect->top = roundup(rect->top, 3);
+ top = roundup(top, 6);
}
+ /* Disable register update, reconfigure atomically */
+ ret = reg_set(icd, MT9T031_OUTPUT_CONTROL, 1);
+ if (ret < 0)
+ return ret;
+
/* Blanking and start values - default... */
ret = reg_write(icd, MT9T031_HORIZONTAL_BLANKING, hblank);
if (ret >= 0)
ret = reg_write(icd, MT9T031_VERTICAL_BLANKING, vblank);
- if (pixfmt) {
+ if (yskip != mt9t031->yskip || xskip != mt9t031->xskip) {
/* Binning, skipping */
if (ret >= 0)
ret = reg_write(icd, MT9T031_COLUMN_ADDRESS_MODE,
@@ -270,14 +274,14 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd,
ret = reg_write(icd, MT9T031_ROW_ADDRESS_MODE,
((ybin - 1) << 4) | (yskip - 1));
}
- dev_dbg(&icd->dev, "new left %u, top %u\n", rect->left, rect->top);
+ dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top);
/* The caller provides a supported format, as guaranteed by
* icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
if (ret >= 0)
- ret = reg_write(icd, MT9T031_COLUMN_START, rect->left);
+ ret = reg_write(icd, MT9T031_COLUMN_START, left);
if (ret >= 0)
- ret = reg_write(icd, MT9T031_ROW_START, rect->top);
+ ret = reg_write(icd, MT9T031_ROW_START, top);
if (ret >= 0)
ret = reg_write(icd, MT9T031_WINDOW_WIDTH, width - 1);
if (ret >= 0)
@@ -297,12 +301,58 @@ static int mt9t031_set_fmt(struct soc_camera_device *icd,
}
}
- if (!ret && pixfmt) {
+ /* Re-enable register update, commit all changes */
+ if (ret >= 0)
+ ret = reg_clear(icd, MT9T031_OUTPUT_CONTROL, 1);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int mt9t031_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+
+ /* CROP - no change in scaling, or in limits */
+ return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
+}
+
+static int mt9t031_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd);
+ int ret;
+ u16 xskip, yskip;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = f->fmt.pix.width,
+ .height = f->fmt.pix.height,
+ };
+
+ /*
+ * try_fmt has put rectangle within limits.
+ * S_FMT - use binning and skipping for scaling, recalculate
+ * limits, used for cropping
+ */
+ /* Is this more optimal than just a division? */
+ for (xskip = 8; xskip > 1; xskip--)
+ if (rect.width * xskip <= MT9T031_MAX_WIDTH)
+ break;
+
+ for (yskip = 8; yskip > 1; yskip--)
+ if (rect.height * yskip <= MT9T031_MAX_HEIGHT)
+ break;
+
+ recalculate_limits(icd, xskip, yskip);
+
+ ret = mt9t031_set_params(icd, &rect, xskip, yskip);
+ if (!ret) {
mt9t031->xskip = xskip;
mt9t031->yskip = yskip;
}
- return ret < 0 ? ret : 0;
+ return ret;
}
static int mt9t031_try_fmt(struct soc_camera_device *icd,
@@ -310,14 +360,14 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
{
struct v4l2_pix_format *pix = &f->fmt.pix;
- if (pix->height < icd->height_min)
- pix->height = icd->height_min;
- if (pix->height > icd->height_max)
- pix->height = icd->height_max;
- if (pix->width < icd->width_min)
- pix->width = icd->width_min;
- if (pix->width > icd->width_max)
- pix->width = icd->width_max;
+ if (pix->height < MT9T031_MIN_HEIGHT)
+ pix->height = MT9T031_MIN_HEIGHT;
+ if (pix->height > MT9T031_MAX_HEIGHT)
+ pix->height = MT9T031_MAX_HEIGHT;
+ if (pix->width < MT9T031_MIN_WIDTH)
+ pix->width = MT9T031_MIN_WIDTH;
+ if (pix->width > MT9T031_MAX_WIDTH)
+ pix->width = MT9T031_MAX_WIDTH;
pix->width &= ~0x01; /* has to be even */
pix->height &= ~0x01; /* has to be even */
@@ -390,6 +440,14 @@ static const struct v4l2_queryctrl mt9t031_controls[] = {
.step = 1,
.default_value = 0,
}, {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Horizontally",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ }, {
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gain",
@@ -431,6 +489,7 @@ static struct soc_camera_ops mt9t031_ops = {
.release = mt9t031_release,
.start_capture = mt9t031_start_capture,
.stop_capture = mt9t031_stop_capture,
+ .set_crop = mt9t031_set_crop,
.set_fmt = mt9t031_set_fmt,
.try_fmt = mt9t031_try_fmt,
.set_bus_param = mt9t031_set_bus_param,
@@ -513,21 +572,23 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
if (data < 0)
return -EIO;
} else {
- /* Pack it into 1.125..15 variable step, register values 9..67 */
+ /* Pack it into 1.125..128 variable step, register values 9..0x7860 */
/* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
unsigned long range = qctrl->maximum - qctrl->default_value - 1;
+ /* calculated gain: map 65..127 to 9..1024 step 0.125 */
unsigned long gain = ((ctrl->value - qctrl->default_value - 1) *
- 111 + range / 2) / range + 9;
+ 1015 + range / 2) / range + 9;
- if (gain <= 32)
+ if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
data = gain;
- else if (gain <= 64)
+ else if (gain <= 64) /* calculated gain 33..64 -> 0x51..0x60 */
data = ((gain - 32) * 16 + 16) / 32 + 80;
else
- data = ((gain - 64) * 7 + 28) / 56 + 96;
+ /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */
+ data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
- dev_dbg(&icd->dev, "Setting gain from %d to %d\n",
- reg_read(icd, MT9T031_GLOBAL_GAIN), data);
+ dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n",
+ reg_read(icd, MT9T031_GLOBAL_GAIN), data);
data = reg_write(icd, MT9T031_GLOBAL_GAIN, data);
if (data < 0)
return -EIO;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index b04c8cb1644..4d3b4813c32 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -13,7 +13,6 @@
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/log2.h>
-#include <linux/gpio.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -89,9 +88,7 @@ struct mt9v022 {
struct i2c_client *client;
struct soc_camera_device icd;
int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
- int switch_gpio;
u16 chip_control;
- unsigned char datawidth;
};
static int reg_read(struct soc_camera_device *icd, const u8 reg)
@@ -209,66 +206,6 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
return 0;
}
-static int bus_switch_request(struct mt9v022 *mt9v022, struct soc_camera_link *icl)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- int ret;
- unsigned int gpio = icl->gpio;
-
- if (gpio_is_valid(gpio)) {
- /* We have a data bus switch. */
- ret = gpio_request(gpio, "mt9v022");
- if (ret < 0) {
- dev_err(&mt9v022->client->dev, "Cannot get GPIO %u\n", gpio);
- return ret;
- }
-
- ret = gpio_direction_output(gpio, 0);
- if (ret < 0) {
- dev_err(&mt9v022->client->dev,
- "Cannot set GPIO %u to output\n", gpio);
- gpio_free(gpio);
- return ret;
- }
- }
-
- mt9v022->switch_gpio = gpio;
-#else
- mt9v022->switch_gpio = -EINVAL;
-#endif
- return 0;
-}
-
-static void bus_switch_release(struct mt9v022 *mt9v022)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- if (gpio_is_valid(mt9v022->switch_gpio))
- gpio_free(mt9v022->switch_gpio);
-#endif
-}
-
-static int bus_switch_act(struct mt9v022 *mt9v022, int go8bit)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- if (!gpio_is_valid(mt9v022->switch_gpio))
- return -ENODEV;
-
- gpio_set_value_cansleep(mt9v022->switch_gpio, go8bit);
- return 0;
-#else
- return -ENODEV;
-#endif
-}
-
-static int bus_switch_possible(struct mt9v022 *mt9v022)
-{
-#ifdef CONFIG_MT9V022_PCA9536_SWITCH
- return gpio_is_valid(mt9v022->switch_gpio);
-#else
- return 0;
-#endif
-}
-
static int mt9v022_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
@@ -282,19 +219,17 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
if (!is_power_of_2(width_flag))
return -EINVAL;
- if ((mt9v022->datawidth != 10 && (width_flag == SOCAM_DATAWIDTH_10)) ||
- (mt9v022->datawidth != 9 && (width_flag == SOCAM_DATAWIDTH_9)) ||
- (mt9v022->datawidth != 8 && (width_flag == SOCAM_DATAWIDTH_8))) {
- /* Well, we actually only can do 10 or 8 bits... */
- if (width_flag == SOCAM_DATAWIDTH_9)
- return -EINVAL;
-
- ret = bus_switch_act(mt9v022,
- width_flag == SOCAM_DATAWIDTH_8);
- if (ret < 0)
+ if (icl->set_bus_param) {
+ ret = icl->set_bus_param(icl, width_flag);
+ if (ret)
return ret;
-
- mt9v022->datawidth = width_flag == SOCAM_DATAWIDTH_8 ? 8 : 10;
+ } else {
+ /*
+ * Without board specific bus width settings we only support the
+ * sensors native bus width
+ */
+ if (width_flag != SOCAM_DATAWIDTH_10)
+ return -EINVAL;
}
flags = soc_camera_apply_sensor_flags(icl, flags);
@@ -328,44 +263,27 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
{
struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
- unsigned int width_flag = SOCAM_DATAWIDTH_10;
+ struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
+ unsigned int width_flag;
- if (bus_switch_possible(mt9v022))
- width_flag |= SOCAM_DATAWIDTH_8;
+ if (icl->query_bus_param)
+ width_flag = icl->query_bus_param(icl) &
+ SOCAM_DATAWIDTH_MASK;
+ else
+ width_flag = SOCAM_DATAWIDTH_10;
return SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
- SOCAM_MASTER | SOCAM_SLAVE |
+ SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_SLAVE |
width_flag;
}
-static int mt9v022_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+static int mt9v022_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
- struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
int ret;
- /* The caller provides a supported format, as verified per call to
- * icd->try_fmt(), datawidth is from our supported format list */
- switch (pixfmt) {
- case V4L2_PIX_FMT_GREY:
- case V4L2_PIX_FMT_Y16:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
- return -EINVAL;
- break;
- case V4L2_PIX_FMT_SBGGR8:
- case V4L2_PIX_FMT_SBGGR16:
- if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
- return -EINVAL;
- break;
- case 0:
- /* No format change, only geometry */
- break;
- default:
- return -EINVAL;
- }
-
/* Like in example app. Contradicts the datasheet though */
ret = reg_read(icd, MT9V022_AEC_AGC_ENABLE);
if (ret >= 0) {
@@ -403,6 +321,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
return 0;
}
+static int mt9v022_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = pix->width,
+ .height = pix->height,
+ };
+
+ /* The caller provides a supported format, as verified per call to
+ * icd->try_fmt(), datawidth is from our supported format list */
+ switch (pix->pixelformat) {
+ case V4L2_PIX_FMT_GREY:
+ case V4L2_PIX_FMT_Y16:
+ if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
+ return -EINVAL;
+ break;
+ case V4L2_PIX_FMT_SBGGR8:
+ case V4L2_PIX_FMT_SBGGR16:
+ if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATC)
+ return -EINVAL;
+ break;
+ case 0:
+ /* No format change, only geometry */
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* No support for scaling on this camera, just crop. */
+ return mt9v022_set_crop(icd, &rect);
+}
+
static int mt9v022_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
@@ -544,6 +498,7 @@ static struct soc_camera_ops mt9v022_ops = {
.release = mt9v022_release,
.start_capture = mt9v022_start_capture,
.stop_capture = mt9v022_stop_capture,
+ .set_crop = mt9v022_set_crop,
.set_fmt = mt9v022_set_fmt,
.try_fmt = mt9v022_try_fmt,
.set_bus_param = mt9v022_set_bus_param,
@@ -699,6 +654,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
s32 data;
int ret;
+ unsigned long flags;
if (!icd->dev.parent ||
to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
@@ -732,22 +688,36 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 4 | 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATC;
icd->formats = mt9v022_colour_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9v022_colour_formats);
- else
- icd->num_formats = 1;
} else {
ret = reg_write(icd, MT9V022_PIXEL_OPERATION_MODE, 0x11);
mt9v022->model = V4L2_IDENT_MT9V022IX7ATM;
icd->formats = mt9v022_monochrome_formats;
- if (gpio_is_valid(icl->gpio))
- icd->num_formats = ARRAY_SIZE(mt9v022_monochrome_formats);
- else
- icd->num_formats = 1;
}
- if (!ret)
- ret = soc_camera_video_start(icd);
+ if (ret < 0)
+ goto eisis;
+
+ icd->num_formats = 0;
+
+ /*
+ * This is a 10bit sensor, so by default we only allow 10bit.
+ * The platform may support different bus widths due to
+ * different routing of the data lines.
+ */
+ if (icl->query_bus_param)
+ flags = icl->query_bus_param(icl);
+ else
+ flags = SOCAM_DATAWIDTH_10;
+
+ if (flags & SOCAM_DATAWIDTH_10)
+ icd->num_formats++;
+ else
+ icd->formats++;
+
+ if (flags & SOCAM_DATAWIDTH_8)
+ icd->num_formats++;
+
+ ret = soc_camera_video_start(icd);
if (ret < 0)
goto eisis;
@@ -812,14 +782,6 @@ static int mt9v022_probe(struct i2c_client *client,
icd->height_max = 480;
icd->y_skip_top = 1;
icd->iface = icl->bus_id;
- /* Default datawidth - this is the only width this camera (normally)
- * supports. It is only with extra logic that it can support
- * other widths. Therefore it seems to be a sensible default. */
- mt9v022->datawidth = 10;
-
- ret = bus_switch_request(mt9v022, icl);
- if (ret)
- goto eswinit;
ret = soc_camera_device_register(icd);
if (ret)
@@ -828,8 +790,6 @@ static int mt9v022_probe(struct i2c_client *client,
return 0;
eisdr:
- bus_switch_release(mt9v022);
-eswinit:
kfree(mt9v022);
return ret;
}
@@ -839,7 +799,6 @@ static int mt9v022_remove(struct i2c_client *client)
struct mt9v022 *mt9v022 = i2c_get_clientdata(client);
soc_camera_device_unregister(&mt9v022->icd);
- bus_switch_release(mt9v022);
kfree(mt9v022);
return 0;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
new file mode 100644
index 00000000000..70629e172e6
--- /dev/null
+++ b/drivers/media/video/mx3_camera.c
@@ -0,0 +1,1220 @@
+/*
+ * V4L2 Driver for i.MX3x camera host
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/videodev2.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/videobuf-dma-contig.h>
+#include <media/soc_camera.h>
+
+#include <mach/ipu.h>
+#include <mach/mx3_camera.h>
+
+#define MX3_CAM_DRV_NAME "mx3-camera"
+
+/* CMOS Sensor Interface Registers */
+#define CSI_REG_START 0x60
+
+#define CSI_SENS_CONF (0x60 - CSI_REG_START)
+#define CSI_SENS_FRM_SIZE (0x64 - CSI_REG_START)
+#define CSI_ACT_FRM_SIZE (0x68 - CSI_REG_START)
+#define CSI_OUT_FRM_CTRL (0x6C - CSI_REG_START)
+#define CSI_TST_CTRL (0x70 - CSI_REG_START)
+#define CSI_CCIR_CODE_1 (0x74 - CSI_REG_START)
+#define CSI_CCIR_CODE_2 (0x78 - CSI_REG_START)
+#define CSI_CCIR_CODE_3 (0x7C - CSI_REG_START)
+#define CSI_FLASH_STROBE_1 (0x80 - CSI_REG_START)
+#define CSI_FLASH_STROBE_2 (0x84 - CSI_REG_START)
+
+#define CSI_SENS_CONF_VSYNC_POL_SHIFT 0
+#define CSI_SENS_CONF_HSYNC_POL_SHIFT 1
+#define CSI_SENS_CONF_DATA_POL_SHIFT 2
+#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT 3
+#define CSI_SENS_CONF_SENS_PRTCL_SHIFT 4
+#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT 7
+#define CSI_SENS_CONF_DATA_FMT_SHIFT 8
+#define CSI_SENS_CONF_DATA_WIDTH_SHIFT 10
+#define CSI_SENS_CONF_EXT_VSYNC_SHIFT 15
+#define CSI_SENS_CONF_DIVRATIO_SHIFT 16
+
+#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444 (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+#define CSI_SENS_CONF_DATA_FMT_YUV422 (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+#define CSI_SENS_CONF_DATA_FMT_BAYER (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT)
+
+#define MAX_VIDEO_MEM 16
+
+struct mx3_camera_buffer {
+ /* common v4l buffer stuff -- must be first */
+ struct videobuf_buffer vb;
+ const struct soc_camera_data_format *fmt;
+
+ /* One descriptot per scatterlist (per frame) */
+ struct dma_async_tx_descriptor *txd;
+
+ /* We have to "build" a scatterlist ourselves - one element per frame */
+ struct scatterlist sg;
+};
+
+/**
+ * struct mx3_camera_dev - i.MX3x camera (CSI) object
+ * @dev: camera device, to which the coherent buffer is attached
+ * @icd: currently attached camera sensor
+ * @clk: pointer to clock
+ * @base: remapped register base address
+ * @pdata: platform data
+ * @platform_flags: platform flags
+ * @mclk: master clock frequency in Hz
+ * @capture: list of capture videobuffers
+ * @lock: protects video buffer lists
+ * @active: active video buffer
+ * @idmac_channel: array of pointers to IPU DMAC DMA channels
+ * @soc_host: embedded soc_host object
+ */
+struct mx3_camera_dev {
+ struct device *dev;
+ /*
+ * i.MX3x is only supposed to handle one camera on its Camera Sensor
+ * Interface. If anyone ever builds hardware to enable more than one
+ * camera _simultaneously_, they will have to modify this driver too
+ */
+ struct soc_camera_device *icd;
+ struct clk *clk;
+
+ void __iomem *base;
+
+ struct mx3_camera_pdata *pdata;
+
+ unsigned long platform_flags;
+ unsigned long mclk;
+
+ struct list_head capture;
+ spinlock_t lock; /* Protects video buffer lists */
+ struct mx3_camera_buffer *active;
+
+ /* IDMAC / dmaengine interface */
+ struct idmac_channel *idmac_channel[1]; /* We need one channel */
+
+ struct soc_camera_host soc_host;
+};
+
+struct dma_chan_request {
+ struct mx3_camera_dev *mx3_cam;
+ enum ipu_channel id;
+};
+
+static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt);
+
+static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg)
+{
+ return __raw_readl(mx3->base + reg);
+}
+
+static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
+{
+ __raw_writel(value, mx3->base + reg);
+}
+
+/* Called from the IPU IDMAC ISR */
+static void mx3_cam_dma_done(void *arg)
+{
+ struct idmac_tx_desc *desc = to_tx_desc(arg);
+ struct dma_chan *chan = desc->txd.chan;
+ struct idmac_channel *ichannel = to_idmac_chan(chan);
+ struct mx3_camera_dev *mx3_cam = ichannel->client;
+ struct videobuf_buffer *vb;
+
+ dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
+ desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
+
+ spin_lock(&mx3_cam->lock);
+ if (mx3_cam->active) {
+ vb = &mx3_cam->active->vb;
+
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_DONE;
+ do_gettimeofday(&vb->ts);
+ vb->field_count++;
+ wake_up(&vb->done);
+ }
+
+ if (list_empty(&mx3_cam->capture)) {
+ mx3_cam->active = NULL;
+ spin_unlock(&mx3_cam->lock);
+
+ /*
+ * stop capture - without further buffers IPU_CHA_BUF0_RDY will
+ * not get updated
+ */
+ return;
+ }
+
+ mx3_cam->active = list_entry(mx3_cam->capture.next,
+ struct mx3_camera_buffer, vb.queue);
+ mx3_cam->active->vb.state = VIDEOBUF_ACTIVE;
+ spin_unlock(&mx3_cam->lock);
+}
+
+static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct videobuf_buffer *vb = &buf->vb;
+ struct dma_async_tx_descriptor *txd = buf->txd;
+ struct idmac_channel *ichan;
+
+ BUG_ON(in_interrupt());
+
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
+ vb, vb->baddr, vb->bsize);
+
+ /*
+ * This waits until this buffer is out of danger, i.e., until it is no
+ * longer in STATE_QUEUED or STATE_ACTIVE
+ */
+ videobuf_waiton(vb, 0, 0);
+ if (txd) {
+ ichan = to_idmac_chan(txd->chan);
+ async_tx_ack(txd);
+ }
+ videobuf_dma_contig_free(vq, vb);
+ buf->txd = NULL;
+
+ vb->state = VIDEOBUF_NEEDS_INIT;
+}
+
+/*
+ * Videobuf operations
+ */
+
+/*
+ * Calculate the __buffer__ (not data) size and number of buffers.
+ * Called with .vb_lock held
+ */
+static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
+ unsigned int *size)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ /*
+ * bits-per-pixel (depth) as specified in camera's pixel format does
+ * not necessarily match what the camera interface writes to RAM, but
+ * it should be good enough for now.
+ */
+ unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8);
+
+ if (!mx3_cam->idmac_channel[0])
+ return -EINVAL;
+
+ *size = icd->width * icd->height * bpp;
+
+ if (!*count)
+ *count = 32;
+
+ if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
+ *count = MAX_VIDEO_MEM * 1024 * 1024 / *size;
+
+ return 0;
+}
+
+/* Called with .vb_lock held */
+static int mx3_videobuf_prepare(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb, enum v4l2_field field)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct mx3_camera_buffer *buf =
+ container_of(vb, struct mx3_camera_buffer, vb);
+ /* current_fmt _must_ always be set */
+ size_t new_size = icd->width * icd->height *
+ ((icd->current_fmt->depth + 7) >> 3);
+ int ret;
+
+ /*
+ * I think, in buf_prepare you only have to protect global data,
+ * the actual buffer is yours
+ */
+
+ if (buf->fmt != icd->current_fmt ||
+ vb->width != icd->width ||
+ vb->height != icd->height ||
+ vb->field != field) {
+ buf->fmt = icd->current_fmt;
+ vb->width = icd->width;
+ vb->height = icd->height;
+ vb->field = field;
+ if (vb->state != VIDEOBUF_NEEDS_INIT)
+ free_buffer(vq, buf);
+ }
+
+ if (vb->baddr && vb->bsize < new_size) {
+ /* User provided buffer, but it is too small */
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ if (vb->state == VIDEOBUF_NEEDS_INIT) {
+ struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
+ struct scatterlist *sg = &buf->sg;
+
+ /*
+ * The total size of video-buffers that will be allocated / mapped.
+ * *size that we calculated in videobuf_setup gets assigned to
+ * vb->bsize, and now we use the same calculation to get vb->size.
+ */
+ vb->size = new_size;
+
+ /* This actually (allocates and) maps buffers */
+ ret = videobuf_iolock(vq, vb, NULL);
+ if (ret)
+ goto fail;
+
+ /*
+ * We will have to configure the IDMAC channel. It has two slots
+ * for DMA buffers, we shall enter the first two buffers there,
+ * and then submit new buffers in DMA-ready interrupts
+ */
+ sg_init_table(sg, 1);
+ sg_dma_address(sg) = videobuf_to_dma_contig(vb);
+ sg_dma_len(sg) = vb->size;
+
+ buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
+ &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
+ DMA_PREP_INTERRUPT);
+ if (!buf->txd) {
+ ret = -EIO;
+ goto fail;
+ }
+
+ buf->txd->callback_param = buf->txd;
+ buf->txd->callback = mx3_cam_dma_done;
+
+ vb->state = VIDEOBUF_PREPARED;
+ }
+
+ return 0;
+
+fail:
+ free_buffer(vq, buf);
+out:
+ return ret;
+}
+
+static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
+{
+ /* Add more formats as need arises and test possibilities appear... */
+ switch (fourcc) {
+ case V4L2_PIX_FMT_RGB565:
+ return IPU_PIX_FMT_RGB565;
+ case V4L2_PIX_FMT_RGB24:
+ return IPU_PIX_FMT_RGB24;
+ case V4L2_PIX_FMT_RGB332:
+ return IPU_PIX_FMT_RGB332;
+ case V4L2_PIX_FMT_YUV422P:
+ return IPU_PIX_FMT_YVU422P;
+ default:
+ return IPU_PIX_FMT_GENERIC;
+ }
+}
+
+/* Called with .vb_lock held */
+static void mx3_videobuf_queue(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct mx3_camera_buffer *buf =
+ container_of(vb, struct mx3_camera_buffer, vb);
+ struct dma_async_tx_descriptor *txd = buf->txd;
+ struct idmac_channel *ichan = to_idmac_chan(txd->chan);
+ struct idmac_video_param *video = &ichan->params.video;
+ const struct soc_camera_data_format *data_fmt = icd->current_fmt;
+ dma_cookie_t cookie;
+ unsigned long flags;
+
+ /* This is the configuration of one sg-element */
+ video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc);
+ video->out_width = icd->width;
+ video->out_height = icd->height;
+ video->out_stride = icd->width;
+
+#ifdef DEBUG
+ /* helps to see what DMA actually has written */
+ memset((void *)vb->baddr, 0xaa, vb->bsize);
+#endif
+
+ spin_lock_irqsave(&mx3_cam->lock, flags);
+
+ list_add_tail(&vb->queue, &mx3_cam->capture);
+
+ if (!mx3_cam->active) {
+ mx3_cam->active = buf;
+ vb->state = VIDEOBUF_ACTIVE;
+ } else {
+ vb->state = VIDEOBUF_QUEUED;
+ }
+
+ spin_unlock_irqrestore(&mx3_cam->lock, flags);
+
+ cookie = txd->tx_submit(txd);
+ dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg));
+ if (cookie >= 0)
+ return;
+
+ /* Submit error */
+ vb->state = VIDEOBUF_PREPARED;
+
+ spin_lock_irqsave(&mx3_cam->lock, flags);
+
+ list_del_init(&vb->queue);
+
+ if (mx3_cam->active == buf)
+ mx3_cam->active = NULL;
+
+ spin_unlock_irqrestore(&mx3_cam->lock, flags);
+}
+
+/* Called with .vb_lock held */
+static void mx3_videobuf_release(struct videobuf_queue *vq,
+ struct videobuf_buffer *vb)
+{
+ struct soc_camera_device *icd = vq->priv_data;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct mx3_camera_buffer *buf =
+ container_of(vb, struct mx3_camera_buffer, vb);
+ unsigned long flags;
+
+ dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n",
+ mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
+ vb->state, list_empty(&vb->queue) ? "" : "not ");
+ spin_lock_irqsave(&mx3_cam->lock, flags);
+ if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
+ !list_empty(&vb->queue)) {
+ vb->state = VIDEOBUF_ERROR;
+
+ list_del_init(&vb->queue);
+ if (mx3_cam->active == buf)
+ mx3_cam->active = NULL;
+ }
+ spin_unlock_irqrestore(&mx3_cam->lock, flags);
+ free_buffer(vq, buf);
+}
+
+static struct videobuf_queue_ops mx3_videobuf_ops = {
+ .buf_setup = mx3_videobuf_setup,
+ .buf_prepare = mx3_videobuf_prepare,
+ .buf_queue = mx3_videobuf_queue,
+ .buf_release = mx3_videobuf_release,
+};
+
+static void mx3_camera_init_videobuf(struct videobuf_queue *q,
+ struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev,
+ &mx3_cam->lock,
+ V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ V4L2_FIELD_NONE,
+ sizeof(struct mx3_camera_buffer), icd);
+}
+
+/* First part of ipu_csi_init_interface() */
+static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
+ struct soc_camera_device *icd)
+{
+ u32 conf;
+ long rate;
+
+ /* Set default size: ipu_csi_set_window_size() */
+ csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE);
+ /* ...and position to 0:0: ipu_csi_set_window_pos() */
+ conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
+ csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL);
+
+ /* We use only gated clock synchronisation mode so far */
+ conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT;
+
+ /* Set generic data, platform-biggest bus-width */
+ conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
+
+ if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
+ conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
+ conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
+ conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/
+ conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+
+ if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC)
+ conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC)
+ conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_DP)
+ conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
+ conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
+ conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
+ if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
+ conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
+
+ /* ipu_csi_init_interface() */
+ csi_reg_write(mx3_cam, conf, CSI_SENS_CONF);
+
+ clk_enable(mx3_cam->clk);
+ rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
+ dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
+ if (rate)
+ clk_set_rate(mx3_cam->clk, rate);
+}
+
+/* Called with .video_lock held */
+static int mx3_camera_add_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ int ret;
+
+ if (mx3_cam->icd) {
+ ret = -EBUSY;
+ goto ebusy;
+ }
+
+ mx3_camera_activate(mx3_cam, icd);
+ ret = icd->ops->init(icd);
+ if (ret < 0) {
+ clk_disable(mx3_cam->clk);
+ goto einit;
+ }
+
+ mx3_cam->icd = icd;
+
+einit:
+ebusy:
+ if (!ret)
+ dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
+ icd->devnum);
+
+ return ret;
+}
+
+/* Called with .video_lock held */
+static void mx3_camera_remove_device(struct soc_camera_device *icd)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
+
+ BUG_ON(icd != mx3_cam->icd);
+
+ if (*ichan) {
+ dma_release_channel(&(*ichan)->dma_chan);
+ *ichan = NULL;
+ }
+
+ icd->ops->release(icd);
+
+ clk_disable(mx3_cam->clk);
+
+ mx3_cam->icd = NULL;
+
+ dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n",
+ icd->devnum);
+}
+
+static bool channel_change_requested(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
+
+ /* Do buffers have to be re-allocated or channel re-configured? */
+ return ichan && rect->width * rect->height > icd->width * icd->height;
+}
+
+static int test_platform_param(struct mx3_camera_dev *mx3_cam,
+ unsigned char buswidth, unsigned long *flags)
+{
+ /*
+ * Platform specified synchronization and pixel clock polarities are
+ * only a recommendation and are only used during probing. MX3x
+ * camera interface only works in master mode, i.e., uses HSYNC and
+ * VSYNC signals from the sensor
+ */
+ *flags = SOCAM_MASTER |
+ SOCAM_HSYNC_ACTIVE_HIGH |
+ SOCAM_HSYNC_ACTIVE_LOW |
+ SOCAM_VSYNC_ACTIVE_HIGH |
+ SOCAM_VSYNC_ACTIVE_LOW |
+ SOCAM_PCLK_SAMPLE_RISING |
+ SOCAM_PCLK_SAMPLE_FALLING |
+ SOCAM_DATA_ACTIVE_HIGH |
+ SOCAM_DATA_ACTIVE_LOW;
+
+ /* If requested data width is supported by the platform, use it or any
+ * possible lower value - i.MX31 is smart enough to schift bits */
+ switch (buswidth) {
+ case 15:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
+ SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
+ break;
+ case 10:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
+ SOCAM_DATAWIDTH_4;
+ break;
+ case 8:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
+ break;
+ case 4:
+ if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4))
+ return -EINVAL;
+ *flags |= SOCAM_DATAWIDTH_4;
+ break;
+ default:
+ dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
+ const unsigned int depth)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ unsigned long bus_flags, camera_flags;
+ int ret = test_platform_param(mx3_cam, depth, &bus_flags);
+
+ dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret);
+
+ if (ret < 0)
+ return ret;
+
+ camera_flags = icd->ops->query_bus_param(icd);
+
+ ret = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+ if (ret < 0)
+ dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n",
+ camera_flags, bus_flags);
+
+ return ret;
+}
+
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ struct dma_chan_request *rq = arg;
+ struct mx3_camera_pdata *pdata;
+
+ if (!rq)
+ return false;
+
+ pdata = rq->mx3_cam->dev->platform_data;
+
+ return rq->id == chan->chan_id &&
+ pdata->dma_dev == chan->device->dev;
+}
+
+static const struct soc_camera_data_format mx3_camera_formats[] = {
+ {
+ .name = "Bayer (sRGB) 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_SBGGR8,
+ .colorspace = V4L2_COLORSPACE_SRGB,
+ }, {
+ .name = "Monochrome 8 bit",
+ .depth = 8,
+ .fourcc = V4L2_PIX_FMT_GREY,
+ .colorspace = V4L2_COLORSPACE_JPEG,
+ },
+};
+
+static bool buswidth_supported(struct soc_camera_host *ici, int depth)
+{
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ switch (depth) {
+ case 4:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4);
+ case 8:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8);
+ case 10:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10);
+ case 15:
+ return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15);
+ }
+ return false;
+}
+
+static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
+ struct soc_camera_format_xlate *xlate)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ int formats = 0, buswidth, ret;
+
+ buswidth = icd->formats[idx].depth;
+
+ if (!buswidth_supported(ici, buswidth))
+ return 0;
+
+ ret = mx3_camera_try_bus_param(icd, buswidth);
+ if (ret < 0)
+ return 0;
+
+ switch (icd->formats[idx].fourcc) {
+ case V4L2_PIX_FMT_SGRBG10:
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = &mx3_camera_formats[0];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
+ dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ mx3_camera_formats[0].name,
+ icd->formats[idx].name);
+ }
+ goto passthrough;
+ case V4L2_PIX_FMT_Y16:
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = &mx3_camera_formats[1];
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
+ dev_dbg(&ici->dev, "Providing format %s using %s\n",
+ mx3_camera_formats[0].name,
+ icd->formats[idx].name);
+ }
+ default:
+passthrough:
+ /* Generic pass-through */
+ formats++;
+ if (xlate) {
+ xlate->host_fmt = icd->formats + idx;
+ xlate->cam_fmt = icd->formats + idx;
+ xlate->buswidth = buswidth;
+ xlate++;
+ dev_dbg(&ici->dev,
+ "Providing format %s in pass-through mode\n",
+ icd->formats[idx].name);
+ }
+ }
+
+ return formats;
+}
+
+static void configure_geometry(struct mx3_camera_dev *mx3_cam,
+ struct v4l2_rect *rect)
+{
+ u32 ctrl, width_field, height_field;
+
+ /* Setup frame size - this cannot be changed on-the-fly... */
+ width_field = rect->width - 1;
+ height_field = rect->height - 1;
+ csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
+
+ csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
+ csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2);
+
+ csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE);
+
+ /* ...and position */
+ ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
+ /* Sensor does the cropping */
+ csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
+
+ /*
+ * No need to free resources here if we fail, we'll see if we need to
+ * do this next time we are called
+ */
+}
+
+static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
+{
+ dma_cap_mask_t mask;
+ struct dma_chan *chan;
+ struct idmac_channel **ichan = &mx3_cam->idmac_channel[0];
+ /* We have to use IDMAC_IC_7 for Bayer / generic data */
+ struct dma_chan_request rq = {.mx3_cam = mx3_cam,
+ .id = IDMAC_IC_7};
+
+ if (*ichan) {
+ struct videobuf_buffer *vb, *_vb;
+ dma_release_channel(&(*ichan)->dma_chan);
+ *ichan = NULL;
+ mx3_cam->active = NULL;
+ list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) {
+ list_del_init(&vb->queue);
+ vb->state = VIDEOBUF_ERROR;
+ wake_up(&vb->done);
+ }
+ }
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+ dma_cap_set(DMA_PRIVATE, mask);
+ chan = dma_request_channel(mask, chan_filter, &rq);
+ if (!chan)
+ return -EBUSY;
+
+ *ichan = to_idmac_chan(chan);
+ (*ichan)->client = mx3_cam;
+
+ return 0;
+}
+
+static int mx3_camera_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+
+ /*
+ * We now know pixel formats and can decide upon DMA-channel(s)
+ * So far only direct camera-to-memory is supported
+ */
+ if (channel_change_requested(icd, rect)) {
+ int ret = acquire_dma_channel(mx3_cam);
+ if (ret < 0)
+ return ret;
+ }
+
+ configure_geometry(mx3_cam, rect);
+
+ return icd->ops->set_crop(icd, rect);
+}
+
+static int mx3_camera_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ const struct soc_camera_format_xlate *xlate;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = pix->width,
+ .height = pix->height,
+ };
+ int ret;
+
+ xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ return -EINVAL;
+ }
+
+ ret = acquire_dma_channel(mx3_cam);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * Might have to perform a complete interface initialisation like in
+ * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
+ * mxc_v4l2_s_fmt()
+ */
+
+ configure_geometry(mx3_cam, &rect);
+
+ ret = icd->ops->set_fmt(icd, f);
+ if (!ret) {
+ icd->buswidth = xlate->buswidth;
+ icd->current_fmt = xlate->host_fmt;
+ }
+
+ return ret;
+}
+
+static int mx3_camera_try_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ const struct soc_camera_format_xlate *xlate;
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ __u32 pixfmt = pix->pixelformat;
+ enum v4l2_field field;
+ int ret;
+
+ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+ if (pixfmt && !xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ return -EINVAL;
+ }
+
+ /* limit to MX3 hardware capabilities */
+ if (pix->height > 4096)
+ pix->height = 4096;
+ if (pix->width > 4096)
+ pix->width = 4096;
+
+ pix->bytesperline = pix->width *
+ DIV_ROUND_UP(xlate->host_fmt->depth, 8);
+ pix->sizeimage = pix->height * pix->bytesperline;
+
+ /* camera has to see its format, but the user the original one */
+ pix->pixelformat = xlate->cam_fmt->fourcc;
+ /* limit to sensor capabilities */
+ ret = icd->ops->try_fmt(icd, f);
+ pix->pixelformat = xlate->host_fmt->fourcc;
+
+ field = pix->field;
+
+ if (field == V4L2_FIELD_ANY) {
+ pix->field = V4L2_FIELD_NONE;
+ } else if (field != V4L2_FIELD_NONE) {
+ dev_err(&icd->dev, "Field type %d unsupported.\n", field);
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int mx3_camera_reqbufs(struct soc_camera_file *icf,
+ struct v4l2_requestbuffers *p)
+{
+ return 0;
+}
+
+static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
+{
+ struct soc_camera_file *icf = file->private_data;
+
+ return videobuf_poll_stream(file, &icf->vb_vidq, pt);
+}
+
+static int mx3_camera_querycap(struct soc_camera_host *ici,
+ struct v4l2_capability *cap)
+{
+ /* cap->name is set by the firendly caller:-> */
+ strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card));
+ cap->version = KERNEL_VERSION(0, 2, 2);
+ cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
+
+ return 0;
+}
+
+static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct mx3_camera_dev *mx3_cam = ici->priv;
+ unsigned long bus_flags, camera_flags, common_flags;
+ u32 dw, sens_conf;
+ int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags);
+ const struct soc_camera_format_xlate *xlate;
+
+ xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
+ return -EINVAL;
+ }
+
+ dev_dbg(&ici->dev, "requested bus width %d bit: %d\n",
+ icd->buswidth, ret);
+
+ if (ret < 0)
+ return ret;
+
+ camera_flags = icd->ops->query_bus_param(icd);
+
+ common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
+ if (!common_flags) {
+ dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n",
+ camera_flags, bus_flags);
+ return -EINVAL;
+ }
+
+ /* Make choices, based on platform preferences */
+ if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
+ common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
+ else
+ common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
+ }
+
+ if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
+ common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
+ else
+ common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
+ }
+
+ if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
+ (common_flags & SOCAM_DATA_ACTIVE_LOW)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_DP)
+ common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
+ else
+ common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
+ }
+
+ if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
+ (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
+ if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
+ common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
+ else
+ common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
+ }
+
+ /* Make the camera work in widest common mode, we'll take care of
+ * the rest */
+ if (common_flags & SOCAM_DATAWIDTH_15)
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_15;
+ else if (common_flags & SOCAM_DATAWIDTH_10)
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_10;
+ else if (common_flags & SOCAM_DATAWIDTH_8)
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_8;
+ else
+ common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
+ SOCAM_DATAWIDTH_4;
+
+ ret = icd->ops->set_bus_param(icd, common_flags);
+ if (ret < 0)
+ return ret;
+
+ /*
+ * So far only gated clock mode is supported. Add a line
+ * (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) |
+ * below and select the required mode when supporting other
+ * synchronisation protocols.
+ */
+ sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) &
+ ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) |
+ (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) |
+ (1 << CSI_SENS_CONF_DATA_POL_SHIFT) |
+ (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) |
+ (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) |
+ (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT));
+
+ /* TODO: Support RGB and YUV formats */
+
+ /* This has been set in mx3_camera_activate(), but we clear it above */
+ sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
+
+ if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
+ sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
+ if (common_flags & SOCAM_HSYNC_ACTIVE_LOW)
+ sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
+ if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
+ sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
+ if (common_flags & SOCAM_DATA_ACTIVE_LOW)
+ sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
+
+ /* Just do what we're asked to do */
+ switch (xlate->host_fmt->depth) {
+ case 4:
+ dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ break;
+ case 8:
+ dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ break;
+ case 10:
+ dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ break;
+ default:
+ /*
+ * Actually it can only be 15 now, default is just to silence
+ * compiler warnings
+ */
+ case 15:
+ dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT;
+ }
+
+ csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
+
+ dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw);
+
+ return 0;
+}
+
+static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
+ .owner = THIS_MODULE,
+ .add = mx3_camera_add_device,
+ .remove = mx3_camera_remove_device,
+#ifdef CONFIG_PM
+ .suspend = mx3_camera_suspend,
+ .resume = mx3_camera_resume,
+#endif
+ .set_crop = mx3_camera_set_crop,
+ .set_fmt = mx3_camera_set_fmt,
+ .try_fmt = mx3_camera_try_fmt,
+ .get_formats = mx3_camera_get_formats,
+ .init_videobuf = mx3_camera_init_videobuf,
+ .reqbufs = mx3_camera_reqbufs,
+ .poll = mx3_camera_poll,
+ .querycap = mx3_camera_querycap,
+ .set_bus_param = mx3_camera_set_bus_param,
+};
+
+static int mx3_camera_probe(struct platform_device *pdev)
+{
+ struct mx3_camera_dev *mx3_cam;
+ struct resource *res;
+ void __iomem *base;
+ int err = 0;
+ struct soc_camera_host *soc_host;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ err = -ENODEV;
+ goto egetres;
+ }
+
+ mx3_cam = vmalloc(sizeof(*mx3_cam));
+ if (!mx3_cam) {
+ dev_err(&pdev->dev, "Could not allocate mx3 camera object\n");
+ err = -ENOMEM;
+ goto ealloc;
+ }
+ memset(mx3_cam, 0, sizeof(*mx3_cam));
+
+ mx3_cam->clk = clk_get(&pdev->dev, "csi_clk");
+ if (IS_ERR(mx3_cam->clk)) {
+ err = PTR_ERR(mx3_cam->clk);
+ goto eclkget;
+ }
+
+ dev_set_drvdata(&pdev->dev, mx3_cam);
+
+ mx3_cam->pdata = pdev->dev.platform_data;
+ mx3_cam->platform_flags = mx3_cam->pdata->flags;
+ if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 |
+ MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 |
+ MX3_CAMERA_DATAWIDTH_15))) {
+ /* Platform hasn't set available data widths. This is bad.
+ * Warn and use a default. */
+ dev_warn(&pdev->dev, "WARNING! Platform hasn't set available "
+ "data widths, using default 8 bit\n");
+ mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
+ }
+
+ mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
+ if (!mx3_cam->mclk) {
+ dev_warn(&pdev->dev,
+ "mclk_10khz == 0! Please, fix your platform data. "
+ "Using default 20MHz\n");
+ mx3_cam->mclk = 20000000;
+ }
+
+ /* list of video-buffers */
+ INIT_LIST_HEAD(&mx3_cam->capture);
+ spin_lock_init(&mx3_cam->lock);
+
+ base = ioremap(res->start, res->end - res->start + 1);
+ if (!base) {
+ err = -ENOMEM;
+ goto eioremap;
+ }
+
+ mx3_cam->base = base;
+ mx3_cam->dev = &pdev->dev;
+
+ soc_host = &mx3_cam->soc_host;
+ soc_host->drv_name = MX3_CAM_DRV_NAME;
+ soc_host->ops = &mx3_soc_camera_host_ops;
+ soc_host->priv = mx3_cam;
+ soc_host->dev.parent = &pdev->dev;
+ soc_host->nr = pdev->id;
+ err = soc_camera_host_register(soc_host);
+ if (err)
+ goto ecamhostreg;
+
+ /* IDMAC interface */
+ dmaengine_get();
+
+ return 0;
+
+ecamhostreg:
+ iounmap(base);
+eioremap:
+ clk_put(mx3_cam->clk);
+eclkget:
+ vfree(mx3_cam);
+ealloc:
+egetres:
+ return err;
+}
+
+static int __devexit mx3_camera_remove(struct platform_device *pdev)
+{
+ struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev);
+
+ clk_put(mx3_cam->clk);
+
+ soc_camera_host_unregister(&mx3_cam->soc_host);
+
+ iounmap(mx3_cam->base);
+
+ /*
+ * The channel has either not been allocated,
+ * or should have been released
+ */
+ if (WARN_ON(mx3_cam->idmac_channel[0]))
+ dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
+
+ vfree(mx3_cam);
+
+ dmaengine_put();
+
+ dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n");
+
+ return 0;
+}
+
+static struct platform_driver mx3_camera_driver = {
+ .driver = {
+ .name = MX3_CAM_DRV_NAME,
+ },
+ .probe = mx3_camera_probe,
+ .remove = __exit_p(mx3_camera_remove),
+};
+
+
+static int __devinit mx3_camera_init(void)
+{
+ return platform_driver_register(&mx3_camera_driver);
+}
+
+static void __exit mx3_camera_exit(void)
+{
+ platform_driver_unregister(&mx3_camera_driver);
+}
+
+module_init(mx3_camera_init);
+module_exit(mx3_camera_exit);
+
+MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
+MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index e3cbe14c349..84aec62e845 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -25,16 +25,20 @@
#include <media/saa7146_vv.h>
#include <media/tuner.h>
-#include <linux/video_decoder.h>
#include <media/v4l2-common.h>
#include <media/saa7115.h>
#include "mxb.h"
#include "tea6415c.h"
#include "tea6420.h"
-#include "tda9840.h"
-#define I2C_SAA7111 0x24
+#define I2C_SAA5246A 0x11
+#define I2C_SAA7111A 0x24
+#define I2C_TDA9840 0x42
+#define I2C_TEA6415C 0x43
+#define I2C_TEA6420_1 0x4c
+#define I2C_TEA6420_2 0x4d
+#define I2C_TUNER 0x60
#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
@@ -79,57 +83,35 @@ static struct {
static int video_audio_connect[MXB_INPUTS] =
{ 0, 1, 3, 3 };
-/* 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 */
- {{3,1,0},{6,1,0}}, /* AUX 3 */
- {{1,1,0},{3,1,0}}, /* Radio */
- {{1,1,0},{2,1,0}}, /* CD-Rom */
- {{6,1,0},{6,1,0}} /* Mute */
- };
-
-/* these are the necessary input-output-pins for bringing one audio source
-(see above) to the line-output */
-static struct tea6420_multiplex TEA6420_line[MXB_AUDIOS+1][2] =
- {
- {{2,3,0},{1,2,0}},
- {{5,3,0},{6,2,0}},
- {{4,3,0},{6,2,0}},
- {{3,3,0},{6,2,0}},
- {{2,3,0},{3,2,0}},
- {{2,3,0},{2,2,0}},
- {{6,3,0},{6,2,0}} /* Mute */
- };
+/* These are the necessary input-output-pins for bringing one audio source
+ (see above) to the CD-output. Note that gain is set to 0 in this table. */
+static struct v4l2_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
+ { { 1, 1 }, { 1, 1 } }, /* Tuner */
+ { { 5, 1 }, { 6, 1 } }, /* AUX 1 */
+ { { 4, 1 }, { 6, 1 } }, /* AUX 2 */
+ { { 3, 1 }, { 6, 1 } }, /* AUX 3 */
+ { { 1, 1 }, { 3, 1 } }, /* Radio */
+ { { 1, 1 }, { 2, 1 } }, /* CD-Rom */
+ { { 6, 1 }, { 6, 1 } } /* Mute */
+};
+
+/* These are the necessary input-output-pins for bringing one audio source
+ (see above) to the line-output. Note that gain is set to 0 in this table. */
+static struct v4l2_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
+ { { 2, 3 }, { 1, 2 } },
+ { { 5, 3 }, { 6, 2 } },
+ { { 4, 3 }, { 6, 2 } },
+ { { 3, 3 }, { 6, 2 } },
+ { { 2, 3 }, { 3, 2 } },
+ { { 2, 3 }, { 2, 2 } },
+ { { 6, 3 }, { 6, 2 } } /* Mute */
+};
#define MAXCONTROLS 1
static struct v4l2_queryctrl mxb_controls[] = {
{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
};
-static struct saa7146_extension_ioctls ioctls[] = {
- { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE },
- { VIDIOC_QUERYCTRL, SAA7146_BEFORE },
- { VIDIOC_G_CTRL, SAA7146_BEFORE },
- { VIDIOC_S_CTRL, SAA7146_BEFORE },
- { VIDIOC_G_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
- { VIDIOC_G_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_S_FREQUENCY, SAA7146_EXCLUSIVE },
- { VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_G_REGISTER, SAA7146_EXCLUSIVE },
- { VIDIOC_DBG_S_REGISTER, SAA7146_EXCLUSIVE },
- { MXB_S_AUDIO_CD, SAA7146_EXCLUSIVE }, /* custom control */
- { MXB_S_AUDIO_LINE, SAA7146_EXCLUSIVE }, /* custom control */
- { 0, 0 }
-};
-
struct mxb
{
struct video_device *video_dev;
@@ -137,12 +119,12 @@ struct mxb
struct i2c_adapter i2c_adapter;
- struct i2c_client *saa7111a;
- struct i2c_client *tda9840;
- struct i2c_client *tea6415c;
- struct i2c_client *tuner;
- struct i2c_client *tea6420_1;
- struct i2c_client *tea6420_2;
+ struct v4l2_subdev *saa7111a;
+ struct v4l2_subdev *tda9840;
+ struct v4l2_subdev *tea6415c;
+ struct v4l2_subdev *tuner;
+ struct v4l2_subdev *tea6420_1;
+ struct v4l2_subdev *tea6420_2;
int cur_mode; /* current audio mode (mono, stereo, ...) */
int cur_input; /* current input */
@@ -150,84 +132,51 @@ struct mxb
struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */
};
-static struct saa7146_extension extension;
-
-static int mxb_check_clients(struct device *dev, void *data)
-{
- struct mxb *mxb = data;
- struct i2c_client *client = i2c_verify_client(dev);
-
- if (!client)
- return 0;
-
- if (I2C_ADDR_TEA6420_1 == client->addr)
- mxb->tea6420_1 = client;
- if (I2C_ADDR_TEA6420_2 == client->addr)
- mxb->tea6420_2 = client;
- if (I2C_TEA6415C_2 == client->addr)
- mxb->tea6415c = client;
- if (I2C_ADDR_TDA9840 == client->addr)
- mxb->tda9840 = client;
- if (I2C_SAA7111 == client->addr)
- mxb->saa7111a = client;
- if (0x60 == client->addr)
- mxb->tuner = client;
+#define saa7111a_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
+#define tea6420_1_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6420_1, o, f, ##args)
+#define tea6420_2_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6420_2, o, f, ##args)
+#define tda9840_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tda9840, o, f, ##args)
+#define tea6415c_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
+#define tuner_call(mxb, o, f, args...) \
+ v4l2_subdev_call(mxb->tuner, o, f, ##args)
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
- return 0;
-}
+static struct saa7146_extension extension;
-static int mxb_probe(struct saa7146_dev* dev)
+static int mxb_probe(struct saa7146_dev *dev)
{
- struct mxb* mxb = NULL;
- int result;
-
- result = request_module("saa7115");
- if (result < 0) {
- printk("mxb: saa7111 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tea6420");
- if (result < 0) {
- printk("mxb: tea6420 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tea6415c");
- if (result < 0) {
- printk("mxb: tea6415c i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tda9840");
- if (result < 0) {
- printk("mxb: tda9840 i2c module not available.\n");
- return -ENODEV;
- }
- result = request_module("tuner");
- if (result < 0) {
- printk("mxb: tuner i2c module not available.\n");
- return -ENODEV;
- }
+ struct mxb *mxb = NULL;
mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
- if( NULL == mxb ) {
+ if (mxb == NULL) {
DEB_D(("not enough kernel memory.\n"));
return -ENOMEM;
}
- mxb->i2c_adapter = (struct i2c_adapter) {
- .class = I2C_CLASS_TV_ANALOG,
- };
-
snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
- if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
+ if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
DEB_S(("cannot register i2c-device. skipping.\n"));
kfree(mxb);
return -EFAULT;
}
- /* loop through all i2c-devices on the bus and look who is there */
- device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
+ mxb->saa7111a = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa7115", "saa7111", I2C_SAA7111A);
+ mxb->tea6420_1 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_1);
+ mxb->tea6420_2 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6420", "tea6420", I2C_TEA6420_2);
+ mxb->tea6415c = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tea6415c", "tea6415c", I2C_TEA6415C);
+ mxb->tda9840 = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tda9840", "tda9840", I2C_TDA9840);
+ mxb->tuner = v4l2_i2c_new_subdev(&mxb->i2c_adapter, "tuner", "tuner", I2C_TUNER);
+ if (v4l2_i2c_new_subdev(&mxb->i2c_adapter, "saa5246a", "saa5246a", I2C_SAA5246A)) {
+ printk(KERN_INFO "mxb: found teletext decoder\n");
+ }
/* check if all devices are present */
if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
@@ -315,47 +264,45 @@ static int mxb_init_done(struct saa7146_dev* dev)
struct v4l2_routing route;
int i = 0, err = 0;
- struct tea6415c_multiplex vm;
/* select video mode in saa7111a */
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, tuner, s_std, std);
/* select tuner-output on saa7111a */
i = 0;
route.input = SAA7115_COMPOSITE0;
route.output = SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS;
- mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ saa7111a_call(mxb, video, s_routing, &route);
/* select a tuner type */
tun_setup.mode_mask = T_ANALOG_TV;
tun_setup.addr = ADDR_UNSET;
tun_setup.type = TUNER_PHILIPS_PAL;
- mxb->tuner->driver->command(mxb->tuner, TUNER_SET_TYPE_ADDR, &tun_setup);
+ tuner_call(mxb, tuner, s_type_addr, &tun_setup);
/* tune in some frequency on tuner */
mxb->cur_freq.tuner = 0;
mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
mxb->cur_freq.frequency = freq;
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY,
- &mxb->cur_freq);
+ tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
/* set a default video standard */
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ tuner_call(mxb, tuner, s_std, std);
/* mute audio on tea6420s */
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_line[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_line[6][1]);
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH, &TEA6420_cd[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH, &TEA6420_cd[6][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[6][1]);
- /* switch to tuner-channel on tea6415c*/
- vm.out = 17;
- vm.in = 3;
- mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+ /* switch to tuner-channel on tea6415c */
+ route.input = 3;
+ route.output = 17;
+ tea6415c_call(mxb, video, s_routing, &route);
- /* select tuner-output on multicable on tea6415c*/
- vm.in = 3;
- vm.out = 13;
- mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm);
+ /* select tuner-output on multicable on tea6415c */
+ route.input = 3;
+ route.output = 13;
+ tea6415c_call(mxb, video, s_routing, &route);
/* the rest for mxb */
mxb->cur_input = 0;
@@ -424,395 +371,414 @@ void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
}
*/
-static struct saa7146_ext_vv vv_data;
-
-/* this function only gets called when the probing was successful */
-static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
{
- struct mxb *mxb = (struct mxb *)dev->ext_priv;
-
- DEB_EE(("dev:%p\n", dev));
-
- /* checking for i2c-devices can be omitted here, because we
- already did this in "mxb_vl42_probe" */
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ int i;
- saa7146_vv_init(dev, &vv_data);
- if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
- ERR(("cannot register capture v4l2 device. skipping.\n"));
- return -1;
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == qc->id) {
+ *qc = mxb_controls[i];
+ DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
+ return 0;
+ }
}
+ return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
+}
- /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
- if (MXB_BOARD_CAN_DO_VBI(dev)) {
- if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
- ERR(("cannot register vbi v4l2 device. skipping.\n"));
- }
+static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i;
+
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
}
- i2c_use_client(mxb->tea6420_1);
- i2c_use_client(mxb->tea6420_2);
- i2c_use_client(mxb->tea6415c);
- i2c_use_client(mxb->tda9840);
- i2c_use_client(mxb->saa7111a);
- i2c_use_client(mxb->tuner);
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
- printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ vc->value = mxb->cur_mute;
+ DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
+ return 0;
+ }
- mxb_num++;
- mxb_init_done(dev);
+ DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
return 0;
}
-static int mxb_detach(struct saa7146_dev *dev)
+static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ int i = 0;
- DEB_EE(("dev:%p\n", dev));
-
- i2c_release_client(mxb->tea6420_1);
- i2c_release_client(mxb->tea6420_2);
- i2c_release_client(mxb->tea6415c);
- i2c_release_client(mxb->tda9840);
- i2c_release_client(mxb->saa7111a);
- i2c_release_client(mxb->tuner);
-
- saa7146_unregister_device(&mxb->video_dev,dev);
- if (MXB_BOARD_CAN_DO_VBI(dev))
- saa7146_unregister_device(&mxb->vbi_dev, dev);
- saa7146_vv_release(dev);
-
- mxb_num--;
+ for (i = MAXCONTROLS - 1; i >= 0; i--) {
+ if (mxb_controls[i].id == vc->id)
+ break;
+ }
- i2c_del_adapter(&mxb->i2c_adapter);
- kfree(mxb);
+ if (i < 0)
+ return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
+
+ if (vc->id == V4L2_CID_AUDIO_MUTE) {
+ mxb->cur_mute = vc->value;
+ if (!vc->value) {
+ /* switch the audio-source */
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
+ } else {
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[6][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[6][1]);
+ }
+ DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ }
+ return 0;
+}
+static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
+{
+ DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
+ if (i->index < 0 || i->index >= MXB_INPUTS)
+ return -EINVAL;
+ memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
return 0;
}
-static long mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
+static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
{
- struct saa7146_dev *dev = fh->dev;
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- struct saa7146_vv *vv = dev->vv_data;
+ *i = mxb->cur_input;
- switch(cmd) {
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *i = arg;
+ DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
+ return 0;
+}
- DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index));
- if (i->index < 0 || i->index >= MXB_INPUTS)
- return -EINVAL;
- memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
- return 0;
- }
- /* the saa7146 provides some controls (brightness, contrast, saturation)
- which gets registered *after* this function. because of this we have
- to return with a value != 0 even if the function succeded.. */
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *qc = arg;
- int i;
-
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == qc->id) {
- *qc = mxb_controls[i];
- DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
- return 0;
- }
- }
- return -EAGAIN;
- }
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i;
+static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct v4l2_routing route;
+ int i = 0;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
- }
+ DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
- if (i < 0)
- return -EAGAIN;
+ if (input < 0 || input >= MXB_INPUTS)
+ return -EINVAL;
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- vc->value = mxb->cur_mute;
- DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ mxb->cur_input = input;
- DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
- return 0;
- }
+ saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
+ input_port_selection[input].hps_sync);
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *vc = arg;
- int i = 0;
+ /* prepare switching of tea6415c and saa7111a;
+ have a look at the 'background'-file for further informations */
+ switch (input) {
+ case TUNER:
+ i = SAA7115_COMPOSITE0;
+ route.input = 3;
+ route.output = 17;
- for (i = MAXCONTROLS - 1; i >= 0; i--) {
- if (mxb_controls[i].id == vc->id)
- break;
+ if (tea6415c_call(mxb, video, s_routing, &route)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
+ return -EFAULT;
}
+ /* connect tuner-output always to multicable */
+ route.input = 3;
+ route.output = 13;
+ break;
+ case AUX3_YC:
+ /* nothing to be done here. aux3_yc is
+ directly connected to the saa711a */
+ i = SAA7115_SVIDEO1;
+ break;
+ case AUX3:
+ /* nothing to be done here. aux3 is
+ directly connected to the saa711a */
+ i = SAA7115_COMPOSITE1;
+ break;
+ case AUX1:
+ i = SAA7115_COMPOSITE0;
+ route.input = 1;
+ route.output = 17;
+ break;
+ }
- if (i < 0)
- return -EAGAIN;
-
- if (vc->id == V4L2_CID_AUDIO_MUTE) {
- mxb->cur_mute = vc->value;
- if (!vc->value) {
- /* switch the audio-source */
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[mxb->cur_input]][1]);
- } else {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[6][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[6][1]);
- }
- DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
+ /* switch video in tea6415c only if necessary */
+ switch (input) {
+ case TUNER:
+ case AUX1:
+ if (tea6415c_call(mxb, video, s_routing, &route)) {
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
+ return -EFAULT;
}
- return 0;
+ break;
+ default:
+ break;
}
- case VIDIOC_G_INPUT:
- {
- int *input = (int *)arg;
- *input = mxb->cur_input;
- DEB_EE(("VIDIOC_G_INPUT %d.\n", *input));
- return 0;
+ /* switch video in saa7111a */
+ route.input = i;
+ route.output = 0;
+ if (saa7111a_call(mxb, video, s_routing, &route))
+ printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
+
+ /* switch the audio-source only if necessary */
+ if (0 == mxb->cur_mute) {
+ tea6420_1_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[input]][0]);
+ tea6420_2_call(mxb, audio, s_routing,
+ &TEA6420_line[video_audio_connect[input]][1]);
}
- case VIDIOC_S_INPUT:
- {
- int input = *(int *)arg;
- struct tea6415c_multiplex vm;
- struct v4l2_routing route;
- int i = 0;
- DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
+ return 0;
+}
- if (input < 0 || input >= MXB_INPUTS)
- return -EINVAL;
+static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- mxb->cur_input = input;
+ if (t->index) {
+ DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
- input_port_selection[input].hps_sync);
+ DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
- /* prepare switching of tea6415c and saa7111a;
- have a look at the 'background'-file for further informations */
- switch (input) {
- case TUNER:
- i = SAA7115_COMPOSITE0;
- vm.in = 3;
- vm.out = 17;
+ memset(t, 0, sizeof(*t));
+ strlcpy(t->name, "TV Tuner", sizeof(t->name));
+ t->type = V4L2_TUNER_ANALOG_TV;
+ t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
+ V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
+ t->audmode = mxb->cur_mode;
+ return call_all(dev, tuner, g_tuner, t);
+}
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #1\n");
- return -EFAULT;
- }
- /* connect tuner-output always to multicable */
- vm.in = 3;
- vm.out = 13;
- break;
- case AUX3_YC:
- /* nothing to be done here. aux3_yc is
- directly connected to the saa711a */
- i = SAA7115_SVIDEO1;
- break;
- case AUX3:
- /* nothing to be done here. aux3 is
- directly connected to the saa711a */
- i = SAA7115_COMPOSITE1;
- break;
- case AUX1:
- i = SAA7115_COMPOSITE0;
- vm.in = 1;
- vm.out = 17;
- break;
- }
+static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- /* switch video in tea6415c only if necessary */
- switch (input) {
- case TUNER:
- case AUX1:
- if (mxb->tea6415c->driver->command(mxb->tea6415c, TEA6415C_SWITCH, &vm)) {
- printk(KERN_ERR "VIDIOC_S_INPUT: could not address tea6415c #3\n");
- return -EFAULT;
- }
- break;
- default:
- break;
- }
+ if (t->index) {
+ DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
+ return -EINVAL;
+ }
- /* switch video in saa7111a */
- route.input = i;
- route.output = 0;
- if (mxb->saa7111a->driver->command(mxb->saa7111a, VIDIOC_INT_S_VIDEO_ROUTING, &route))
- printk("VIDIOC_S_INPUT: could not address saa7111a #1.\n");
-
- /* switch the audio-source only if necessary */
- if( 0 == mxb->cur_mute ) {
- mxb->tea6420_1->driver->command(mxb->tea6420_1, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2, TEA6420_SWITCH,
- &TEA6420_line[video_audio_connect[input]][1]);
- }
+ mxb->cur_mode = t->audmode;
+ return call_all(dev, tuner, s_tuner, t);
+}
- return 0;
+static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
+ mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_TUNER:
- {
- struct v4l2_tuner *t = arg;
- if (t->index) {
- DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
- return -EINVAL;
- }
+ *f = mxb->cur_freq;
- DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
+ DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ return 0;
+}
- memset(t, 0, sizeof(*t));
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
+static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+ struct saa7146_vv *vv = dev->vv_data;
- strlcpy(t->name, "TV Tuner", sizeof(t->name));
- t->type = V4L2_TUNER_ANALOG_TV;
- t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | \
- V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
- t->audmode = mxb->cur_mode;
- return 0;
- }
- case VIDIOC_S_TUNER:
- {
- struct v4l2_tuner *t = arg;
+ if (f->tuner)
+ return -EINVAL;
- if (t->index) {
- DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n",t->index));
- return -EINVAL;
- }
+ if (V4L2_TUNER_ANALOG_TV != f->type)
+ return -EINVAL;
- mxb->cur_mode = t->audmode;
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ if (mxb->cur_input) {
+ DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
+ return -EINVAL;
}
- case VIDIOC_G_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
- mxb->cur_input));
- return -EINVAL;
- }
+ mxb->cur_freq = *f;
+ DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
- *f = mxb->cur_freq;
+ /* tune in desired frequency */
+ tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
- DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
- return 0;
+ /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
+ spin_lock(&dev->slock);
+ vv->vbi_fieldcount = 0;
+ spin_unlock(&dev->slock);
+
+ return 0;
+}
+
+static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ if (a->index < 0 || a->index > MXB_INPUTS) {
+ DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
+ return -EINVAL;
}
- case VIDIOC_S_FREQUENCY:
- {
- struct v4l2_frequency *f = arg;
- if (f->tuner)
- return -EINVAL;
+ 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;
+}
- if (V4L2_TUNER_ANALOG_TV != f->type)
- return -EINVAL;
+static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
+{
+ DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
+ return 0;
+}
- if (mxb->cur_input) {
- DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
- return -EINVAL;
- }
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- mxb->cur_freq = *f;
- DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
+ return call_all(dev, core, g_register, reg);
+}
- /* tune in desired frequency */
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_FREQUENCY, &mxb->cur_freq);
+static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
- /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
- spin_lock(&dev->slock);
- vv->vbi_fieldcount = 0;
- spin_unlock(&dev->slock);
+ return call_all(dev, core, s_register, reg);
+}
+#endif
- return 0;
- }
+static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
+{
+ struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ switch (cmd) {
case MXB_S_AUDIO_CD:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n",i));
+ 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));
+ DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
- mxb->tea6420_1->driver->command(mxb->tea6420_1,TEA6420_SWITCH, &TEA6420_cd[i][0]);
- mxb->tea6420_2->driver->command(mxb->tea6420_2,TEA6420_SWITCH, &TEA6420_cd[i][1]);
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_cd[i][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_cd[i][1]);
return 0;
}
case MXB_S_AUDIO_LINE:
{
- int i = *(int*)arg;
+ int i = *(int *)arg;
if (i < 0 || i >= MXB_AUDIOS) {
- DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n",i));
+ 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]);
+ DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
+ tea6420_1_call(mxb, audio, s_routing, &TEA6420_line[i][0]);
+ tea6420_2_call(mxb, audio, s_routing, &TEA6420_line[i][1]);
return 0;
}
- case VIDIOC_G_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ default:
+/*
+ DEB2(printk("does not handle this ioctl.\n"));
+*/
+ return -ENOIOCTLCMD;
+ }
+ return 0;
+}
- if (a->index < 0 || a->index > MXB_INPUTS) {
- DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
- return -EINVAL;
- }
+static struct saa7146_ext_vv vv_data;
- DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
- memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
+/* this function only gets called when the probing was successful */
+static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
- return 0;
- }
- case VIDIOC_S_AUDIO:
- {
- struct v4l2_audio *a = arg;
+ DEB_EE(("dev:%p\n", dev));
- DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
- return 0;
- }
+ /* checking for i2c-devices can be omitted here, because we
+ already did this in "mxb_vl42_probe" */
+
+ saa7146_vv_init(dev, &vv_data);
+ vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
+ vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
+ vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
+ vv_data.ops.vidioc_enum_input = vidioc_enum_input;
+ vv_data.ops.vidioc_g_input = vidioc_g_input;
+ vv_data.ops.vidioc_s_input = vidioc_s_input;
+ vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
+ vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
+ vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
+ vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
+ vv_data.ops.vidioc_g_audio = vidioc_g_audio;
+ vv_data.ops.vidioc_s_audio = vidioc_s_audio;
#ifdef CONFIG_VIDEO_ADV_DEBUG
- case VIDIOC_DBG_S_REGISTER:
- case VIDIOC_DBG_G_REGISTER:
- i2c_clients_command(&mxb->i2c_adapter, cmd, arg);
- return 0;
+ vv_data.ops.vidioc_g_register = vidioc_g_register;
+ vv_data.ops.vidioc_s_register = vidioc_s_register;
#endif
- default:
-/*
- DEB2(printk("does not handle this ioctl.\n"));
-*/
- return -ENOIOCTLCMD;
+ vv_data.ops.vidioc_default = vidioc_default;
+ if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
+ ERR(("cannot register capture v4l2 device. skipping.\n"));
+ return -1;
}
+
+ /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
+ if (MXB_BOARD_CAN_DO_VBI(dev)) {
+ if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
+ ERR(("cannot register vbi v4l2 device. skipping.\n"));
+ }
+ }
+
+ printk("mxb: found Multimedia eXtension Board #%d.\n", mxb_num);
+
+ mxb_num++;
+ mxb_init_done(dev);
+ return 0;
+}
+
+static int mxb_detach(struct saa7146_dev *dev)
+{
+ struct mxb *mxb = (struct mxb *)dev->ext_priv;
+
+ DEB_EE(("dev:%p\n", dev));
+
+ saa7146_unregister_device(&mxb->video_dev,dev);
+ if (MXB_BOARD_CAN_DO_VBI(dev))
+ saa7146_unregister_device(&mxb->vbi_dev, dev);
+ saa7146_vv_release(dev);
+
+ mxb_num--;
+
+ i2c_del_adapter(&mxb->i2c_adapter);
+ kfree(mxb);
+
return 0;
}
static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
{
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- int zero = 0;
- int one = 1;
if (V4L2_STD_PAL_I == standard->id) {
v4l2_std_id std = V4L2_STD_PAL_I;
@@ -821,8 +787,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* set the 7146 gpio register -- I don't know what this does exactly */
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, VIDIOC_INT_S_GPIO, &zero);
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, core, s_gpio, 0);
+ tuner_call(mxb, tuner, s_std, std);
} else {
v4l2_std_id std = V4L2_STD_PAL_BG;
@@ -830,8 +796,8 @@ static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standa
/* set the 7146 gpio register -- I don't know what this does exactly */
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, VIDIOC_INT_S_GPIO, &one);
- mxb->tuner->driver->command(mxb->tuner, VIDIOC_S_STD, &std);
+ saa7111a_call(mxb, core, s_gpio, 1);
+ tuner_call(mxb, tuner, s_std, std);
}
return 0;
}
@@ -885,8 +851,6 @@ static struct saa7146_ext_vv vv_data = {
.stds = &standard[0],
.num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .ioctls = &ioctls[0],
- .ioctl = mxb_ioctl,
};
static struct saa7146_extension extension = {
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index 805faaea644..5fc4ac0d88f 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -1285,9 +1285,6 @@ static int vidioc_g_parm(struct file *file, void *fh,
struct omap24xxcam_device *cam = ofh->cam;
int rval;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
mutex_lock(&cam->mutex);
rval = vidioc_int_g_parm(cam->sdev, a);
mutex_unlock(&cam->mutex);
@@ -1303,9 +1300,6 @@ static int vidioc_s_parm(struct file *file, void *fh,
struct v4l2_streamparm old_streamparm;
int rval;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
mutex_lock(&cam->mutex);
if (cam->streaming) {
rval = -EBUSY;
@@ -1665,7 +1659,6 @@ static int omap24xxcam_device_register(struct v4l2_int_device *s)
vfd->parent = cam->dev;
strlcpy(vfd->name, CAM_NAME, sizeof(vfd->name));
- vfd->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_CHROMAKEY;
vfd->fops = &omap24xxcam_fops;
vfd->minor = -1;
vfd->ioctl_ops = &omap24xxcam_ioctl_fops;
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 05c14a29375..0e2184ec994 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -12,18 +12,22 @@
*/
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/slab.h>
+#include <linux/i2c.h>
#include <linux/delay.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <linux/i2c.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
MODULE_LICENSE("GPL");
+static int debug;
+module_param(debug, bool, 0644);
+MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/*
* Basic window sizes. These probably belong somewhere more globally
* useful.
@@ -189,11 +193,16 @@ MODULE_LICENSE("GPL");
*/
struct ov7670_format_struct; /* coming later */
struct ov7670_info {
+ struct v4l2_subdev sd;
struct ov7670_format_struct *fmt; /* Current format */
unsigned char sat; /* Saturation value */
int hue; /* Hue value */
};
+static inline struct ov7670_info *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ov7670_info, sd);
+}
@@ -400,24 +409,27 @@ static struct regval_list ov7670_fmt_raw[] = {
* Low-level register I/O.
*/
-static int ov7670_read(struct i2c_client *c, unsigned char reg,
+static int ov7670_read(struct v4l2_subdev *sd, unsigned char reg,
unsigned char *value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
- ret = i2c_smbus_read_byte_data(c, reg);
+ ret = i2c_smbus_read_byte_data(client, reg);
if (ret >= 0) {
- *value = (unsigned char) ret;
+ *value = (unsigned char)ret;
ret = 0;
}
return ret;
}
-static int ov7670_write(struct i2c_client *c, unsigned char reg,
+static int ov7670_write(struct v4l2_subdev *sd, unsigned char reg,
unsigned char value)
{
- int ret = i2c_smbus_write_byte_data(c, reg, value);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = i2c_smbus_write_byte_data(client, reg, value);
+
if (reg == REG_COM7 && (value & COM7_RESET))
msleep(2); /* Wait for reset to run */
return ret;
@@ -427,10 +439,10 @@ static int ov7670_write(struct i2c_client *c, unsigned char reg,
/*
* Write a list of register settings; ff/ff stops the process.
*/
-static int ov7670_write_array(struct i2c_client *c, struct regval_list *vals)
+static int ov7670_write_array(struct v4l2_subdev *sd, struct regval_list *vals)
{
while (vals->reg_num != 0xff || vals->value != 0xff) {
- int ret = ov7670_write(c, vals->reg_num, vals->value);
+ int ret = ov7670_write(sd, vals->reg_num, vals->value);
if (ret < 0)
return ret;
vals++;
@@ -442,34 +454,35 @@ static int ov7670_write_array(struct i2c_client *c, struct regval_list *vals)
/*
* Stuff that knows about the sensor.
*/
-static void ov7670_reset(struct i2c_client *client)
+static int ov7670_reset(struct v4l2_subdev *sd, u32 val)
{
- ov7670_write(client, REG_COM7, COM7_RESET);
+ ov7670_write(sd, REG_COM7, COM7_RESET);
msleep(1);
+ return 0;
}
-static int ov7670_init(struct i2c_client *client)
+static int ov7670_init(struct v4l2_subdev *sd, u32 val)
{
- return ov7670_write_array(client, ov7670_default_regs);
+ return ov7670_write_array(sd, ov7670_default_regs);
}
-static int ov7670_detect(struct i2c_client *client)
+static int ov7670_detect(struct v4l2_subdev *sd)
{
unsigned char v;
int ret;
- ret = ov7670_init(client);
+ ret = ov7670_init(sd, 0);
if (ret < 0)
return ret;
- ret = ov7670_read(client, REG_MIDH, &v);
+ ret = ov7670_read(sd, REG_MIDH, &v);
if (ret < 0)
return ret;
if (v != 0x7f) /* OV manuf. id. */
return -ENODEV;
- ret = ov7670_read(client, REG_MIDL, &v);
+ ret = ov7670_read(sd, REG_MIDL, &v);
if (ret < 0)
return ret;
if (v != 0xa2)
@@ -477,12 +490,12 @@ static int ov7670_detect(struct i2c_client *client)
/*
* OK, we know we have an OmniVision chip...but which one?
*/
- ret = ov7670_read(client, REG_PID, &v);
+ ret = ov7670_read(sd, REG_PID, &v);
if (ret < 0)
return ret;
if (v != 0x76) /* PID + VER = 0x76 / 0x73 */
return -ENODEV;
- ret = ov7670_read(client, REG_VER, &v);
+ ret = ov7670_read(sd, REG_VER, &v);
if (ret < 0)
return ret;
if (v != 0x73) /* PID + VER = 0x76 / 0x73 */
@@ -627,7 +640,7 @@ static struct ov7670_win_size {
/*
* Store a set of start/stop values into the camera.
*/
-static int ov7670_set_hw(struct i2c_client *client, int hstart, int hstop,
+static int ov7670_set_hw(struct v4l2_subdev *sd, int hstart, int hstop,
int vstart, int vstop)
{
int ret;
@@ -637,26 +650,26 @@ static int ov7670_set_hw(struct i2c_client *client, int hstart, int hstop,
* hstart are in href[2:0], bottom 3 of hstop in href[5:3]. There is
* a mystery "edge offset" value in the top two bits of href.
*/
- ret = ov7670_write(client, REG_HSTART, (hstart >> 3) & 0xff);
- ret += ov7670_write(client, REG_HSTOP, (hstop >> 3) & 0xff);
- ret += ov7670_read(client, REG_HREF, &v);
+ ret = ov7670_write(sd, REG_HSTART, (hstart >> 3) & 0xff);
+ ret += ov7670_write(sd, REG_HSTOP, (hstop >> 3) & 0xff);
+ ret += ov7670_read(sd, REG_HREF, &v);
v = (v & 0xc0) | ((hstop & 0x7) << 3) | (hstart & 0x7);
msleep(10);
- ret += ov7670_write(client, REG_HREF, v);
+ ret += ov7670_write(sd, REG_HREF, v);
/*
* Vertical: similar arrangement, but only 10 bits.
*/
- ret += ov7670_write(client, REG_VSTART, (vstart >> 2) & 0xff);
- ret += ov7670_write(client, REG_VSTOP, (vstop >> 2) & 0xff);
- ret += ov7670_read(client, REG_VREF, &v);
+ ret += ov7670_write(sd, REG_VSTART, (vstart >> 2) & 0xff);
+ ret += ov7670_write(sd, REG_VSTOP, (vstop >> 2) & 0xff);
+ ret += ov7670_read(sd, REG_VREF, &v);
v = (v & 0xf0) | ((vstop & 0x3) << 2) | (vstart & 0x3);
msleep(10);
- ret += ov7670_write(client, REG_VREF, v);
+ ret += ov7670_write(sd, REG_VREF, v);
return ret;
}
-static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt)
+static int ov7670_enum_fmt(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
{
struct ov7670_format_struct *ofmt;
@@ -671,7 +684,8 @@ static int ov7670_enum_fmt(struct i2c_client *c, struct v4l2_fmtdesc *fmt)
}
-static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
+static int ov7670_try_fmt_internal(struct v4l2_subdev *sd,
+ struct v4l2_format *fmt,
struct ov7670_format_struct **ret_fmt,
struct ov7670_win_size **ret_wsize)
{
@@ -715,18 +729,23 @@ static int ov7670_try_fmt(struct i2c_client *c, struct v4l2_format *fmt,
return 0;
}
+static int ov7670_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ return ov7670_try_fmt_internal(sd, fmt, NULL, NULL);
+}
+
/*
* Set a format.
*/
-static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
+static int ov7670_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
int ret;
struct ov7670_format_struct *ovfmt;
struct ov7670_win_size *wsize;
- struct ov7670_info *info = i2c_get_clientdata(c);
- unsigned char com7, clkrc;
+ struct ov7670_info *info = to_state(sd);
+ unsigned char com7, clkrc = 0;
- ret = ov7670_try_fmt(c, fmt, &ovfmt, &wsize);
+ ret = ov7670_try_fmt_internal(sd, fmt, &ovfmt, &wsize);
if (ret)
return ret;
/*
@@ -735,7 +754,7 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
* the colors.
*/
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565) {
- ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ ret = ov7670_read(sd, REG_CLKRC, &clkrc);
if (ret)
return ret;
}
@@ -747,20 +766,20 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
*/
com7 = ovfmt->regs[0].value;
com7 |= wsize->com7_bit;
- ov7670_write(c, REG_COM7, com7);
+ ov7670_write(sd, REG_COM7, com7);
/*
* Now write the rest of the array. Also store start/stops
*/
- ov7670_write_array(c, ovfmt->regs + 1);
- ov7670_set_hw(c, wsize->hstart, wsize->hstop, wsize->vstart,
+ ov7670_write_array(sd, ovfmt->regs + 1);
+ ov7670_set_hw(sd, wsize->hstart, wsize->hstop, wsize->vstart,
wsize->vstop);
ret = 0;
if (wsize->regs)
- ret = ov7670_write_array(c, wsize->regs);
+ ret = ov7670_write_array(sd, wsize->regs);
info->fmt = ovfmt;
if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_RGB565 && ret == 0)
- ret = ov7670_write(c, REG_CLKRC, clkrc);
+ ret = ov7670_write(sd, REG_CLKRC, clkrc);
return ret;
}
@@ -768,7 +787,7 @@ static int ov7670_s_fmt(struct i2c_client *c, struct v4l2_format *fmt)
* Implement G/S_PARM. There is a "high quality" mode we could try
* to do someday; for now, we just do the frame rate tweak.
*/
-static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
+static int ov7670_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
{
struct v4l2_captureparm *cp = &parms->parm.capture;
unsigned char clkrc;
@@ -776,7 +795,7 @@ static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ ret = ov7670_read(sd, REG_CLKRC, &clkrc);
if (ret < 0)
return ret;
memset(cp, 0, sizeof(struct v4l2_captureparm));
@@ -788,7 +807,7 @@ static int ov7670_g_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
return 0;
}
-static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
+static int ov7670_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
{
struct v4l2_captureparm *cp = &parms->parm.capture;
struct v4l2_fract *tpf = &cp->timeperframe;
@@ -802,7 +821,7 @@ static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
/*
* CLKRC has a reserved bit, so let's preserve it.
*/
- ret = ov7670_read(c, REG_CLKRC, &clkrc);
+ ret = ov7670_read(sd, REG_CLKRC, &clkrc);
if (ret < 0)
return ret;
if (tpf->numerator == 0 || tpf->denominator == 0)
@@ -816,7 +835,7 @@ static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
clkrc = (clkrc & 0x80) | div;
tpf->numerator = 1;
tpf->denominator = OV7670_FRAME_RATE/div;
- return ov7670_write(c, REG_CLKRC, clkrc);
+ return ov7670_write(sd, REG_CLKRC, clkrc);
}
@@ -829,7 +848,7 @@ static int ov7670_s_parm(struct i2c_client *c, struct v4l2_streamparm *parms)
-static int ov7670_store_cmatrix(struct i2c_client *client,
+static int ov7670_store_cmatrix(struct v4l2_subdev *sd,
int matrix[CMATRIX_LEN])
{
int i, ret;
@@ -839,7 +858,7 @@ static int ov7670_store_cmatrix(struct i2c_client *client,
* Weird crap seems to exist in the upper part of
* the sign bits register, so let's preserve it.
*/
- ret = ov7670_read(client, REG_CMATRIX_SIGN, &signbits);
+ ret = ov7670_read(sd, REG_CMATRIX_SIGN, &signbits);
signbits &= 0xc0;
for (i = 0; i < CMATRIX_LEN; i++) {
@@ -858,9 +877,9 @@ static int ov7670_store_cmatrix(struct i2c_client *client,
else
raw = matrix[i] & 0xff;
}
- ret += ov7670_write(client, REG_CMATRIX_BASE + i, raw);
+ ret += ov7670_write(sd, REG_CMATRIX_BASE + i, raw);
}
- ret += ov7670_write(client, REG_CMATRIX_SIGN, signbits);
+ ret += ov7670_write(sd, REG_CMATRIX_SIGN, signbits);
return ret;
}
@@ -943,29 +962,29 @@ static void ov7670_calc_cmatrix(struct ov7670_info *info,
-static int ov7670_t_sat(struct i2c_client *client, int value)
+static int ov7670_s_sat(struct v4l2_subdev *sd, int value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
int matrix[CMATRIX_LEN];
int ret;
info->sat = value;
ov7670_calc_cmatrix(info, matrix);
- ret = ov7670_store_cmatrix(client, matrix);
+ ret = ov7670_store_cmatrix(sd, matrix);
return ret;
}
-static int ov7670_q_sat(struct i2c_client *client, __s32 *value)
+static int ov7670_g_sat(struct v4l2_subdev *sd, __s32 *value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
*value = info->sat;
return 0;
}
-static int ov7670_t_hue(struct i2c_client *client, int value)
+static int ov7670_s_hue(struct v4l2_subdev *sd, int value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
int matrix[CMATRIX_LEN];
int ret;
@@ -973,14 +992,14 @@ static int ov7670_t_hue(struct i2c_client *client, int value)
return -EINVAL;
info->hue = value;
ov7670_calc_cmatrix(info, matrix);
- ret = ov7670_store_cmatrix(client, matrix);
+ ret = ov7670_store_cmatrix(sd, matrix);
return ret;
}
-static int ov7670_q_hue(struct i2c_client *client, __s32 *value)
+static int ov7670_g_hue(struct v4l2_subdev *sd, __s32 *value)
{
- struct ov7670_info *info = i2c_get_clientdata(client);
+ struct ov7670_info *info = to_state(sd);
*value = info->hue;
return 0;
@@ -994,8 +1013,7 @@ static unsigned char ov7670_sm_to_abs(unsigned char v)
{
if ((v & 0x80) == 0)
return v + 128;
- else
- return 128 - (v & 0x7f);
+ return 128 - (v & 0x7f);
}
@@ -1003,369 +1021,275 @@ static unsigned char ov7670_abs_to_sm(unsigned char v)
{
if (v > 127)
return v & 0x7f;
- else
- return (128 - v) | 0x80;
+ return (128 - v) | 0x80;
}
-static int ov7670_t_brightness(struct i2c_client *client, int value)
+static int ov7670_s_brightness(struct v4l2_subdev *sd, int value)
{
unsigned char com8 = 0, v;
int ret;
- ov7670_read(client, REG_COM8, &com8);
+ ov7670_read(sd, REG_COM8, &com8);
com8 &= ~COM8_AEC;
- ov7670_write(client, REG_COM8, com8);
+ ov7670_write(sd, REG_COM8, com8);
v = ov7670_abs_to_sm(value);
- ret = ov7670_write(client, REG_BRIGHT, v);
+ ret = ov7670_write(sd, REG_BRIGHT, v);
return ret;
}
-static int ov7670_q_brightness(struct i2c_client *client, __s32 *value)
+static int ov7670_g_brightness(struct v4l2_subdev *sd, __s32 *value)
{
unsigned char v = 0;
- int ret = ov7670_read(client, REG_BRIGHT, &v);
+ int ret = ov7670_read(sd, REG_BRIGHT, &v);
*value = ov7670_sm_to_abs(v);
return ret;
}
-static int ov7670_t_contrast(struct i2c_client *client, int value)
+static int ov7670_s_contrast(struct v4l2_subdev *sd, int value)
{
- return ov7670_write(client, REG_CONTRAS, (unsigned char) value);
+ return ov7670_write(sd, REG_CONTRAS, (unsigned char) value);
}
-static int ov7670_q_contrast(struct i2c_client *client, __s32 *value)
+static int ov7670_g_contrast(struct v4l2_subdev *sd, __s32 *value)
{
unsigned char v = 0;
- int ret = ov7670_read(client, REG_CONTRAS, &v);
+ int ret = ov7670_read(sd, REG_CONTRAS, &v);
*value = v;
return ret;
}
-static int ov7670_q_hflip(struct i2c_client *client, __s32 *value)
+static int ov7670_g_hflip(struct v4l2_subdev *sd, __s32 *value)
{
int ret;
unsigned char v = 0;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
*value = (v & MVFP_MIRROR) == MVFP_MIRROR;
return ret;
}
-static int ov7670_t_hflip(struct i2c_client *client, int value)
+static int ov7670_s_hflip(struct v4l2_subdev *sd, int value)
{
unsigned char v = 0;
int ret;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
if (value)
v |= MVFP_MIRROR;
else
v &= ~MVFP_MIRROR;
msleep(10); /* FIXME */
- ret += ov7670_write(client, REG_MVFP, v);
+ ret += ov7670_write(sd, REG_MVFP, v);
return ret;
}
-static int ov7670_q_vflip(struct i2c_client *client, __s32 *value)
+static int ov7670_g_vflip(struct v4l2_subdev *sd, __s32 *value)
{
int ret;
unsigned char v = 0;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
*value = (v & MVFP_FLIP) == MVFP_FLIP;
return ret;
}
-static int ov7670_t_vflip(struct i2c_client *client, int value)
+static int ov7670_s_vflip(struct v4l2_subdev *sd, int value)
{
unsigned char v = 0;
int ret;
- ret = ov7670_read(client, REG_MVFP, &v);
+ ret = ov7670_read(sd, REG_MVFP, &v);
if (value)
v |= MVFP_FLIP;
else
v &= ~MVFP_FLIP;
msleep(10); /* FIXME */
- ret += ov7670_write(client, REG_MVFP, v);
+ ret += ov7670_write(sd, REG_MVFP, v);
return ret;
}
-
-static struct ov7670_control {
- struct v4l2_queryctrl qc;
- int (*query)(struct i2c_client *c, __s32 *value);
- int (*tweak)(struct i2c_client *c, int value);
-} ov7670_controls[] =
+static int ov7670_queryctrl(struct v4l2_subdev *sd,
+ struct v4l2_queryctrl *qc)
{
- {
- .qc = {
- .id = V4L2_CID_BRIGHTNESS,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Brightness",
- .minimum = 0,
- .maximum = 255,
- .step = 1,
- .default_value = 0x80,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_brightness,
- .query = ov7670_q_brightness,
- },
- {
- .qc = {
- .id = V4L2_CID_CONTRAST,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Contrast",
- .minimum = 0,
- .maximum = 127,
- .step = 1,
- .default_value = 0x40, /* XXX ov7670 spec */
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_contrast,
- .query = ov7670_q_contrast,
- },
- {
- .qc = {
- .id = V4L2_CID_SATURATION,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "Saturation",
- .minimum = 0,
- .maximum = 256,
- .step = 1,
- .default_value = 0x80,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_sat,
- .query = ov7670_q_sat,
- },
- {
- .qc = {
- .id = V4L2_CID_HUE,
- .type = V4L2_CTRL_TYPE_INTEGER,
- .name = "HUE",
- .minimum = -180,
- .maximum = 180,
- .step = 5,
- .default_value = 0,
- .flags = V4L2_CTRL_FLAG_SLIDER
- },
- .tweak = ov7670_t_hue,
- .query = ov7670_q_hue,
- },
- {
- .qc = {
- .id = V4L2_CID_VFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Vertical flip",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .tweak = ov7670_t_vflip,
- .query = ov7670_q_vflip,
- },
- {
- .qc = {
- .id = V4L2_CID_HFLIP,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- .name = "Horizontal mirror",
- .minimum = 0,
- .maximum = 1,
- .step = 1,
- .default_value = 0,
- },
- .tweak = ov7670_t_hflip,
- .query = ov7670_q_hflip,
- },
-};
-#define N_CONTROLS (ARRAY_SIZE(ov7670_controls))
+ /* Fill in min, max, step and default value for these controls. */
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+ case V4L2_CID_VFLIP:
+ case V4L2_CID_HFLIP:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 256, 1, 128);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, -180, 180, 5, 0);
+ }
+ return -EINVAL;
+}
-static struct ov7670_control *ov7670_find_control(__u32 id)
+static int ov7670_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- int i;
-
- for (i = 0; i < N_CONTROLS; i++)
- if (ov7670_controls[i].qc.id == id)
- return ov7670_controls + i;
- return NULL;
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return ov7670_g_brightness(sd, &ctrl->value);
+ case V4L2_CID_CONTRAST:
+ return ov7670_g_contrast(sd, &ctrl->value);
+ case V4L2_CID_SATURATION:
+ return ov7670_g_sat(sd, &ctrl->value);
+ case V4L2_CID_HUE:
+ return ov7670_g_hue(sd, &ctrl->value);
+ case V4L2_CID_VFLIP:
+ return ov7670_g_vflip(sd, &ctrl->value);
+ case V4L2_CID_HFLIP:
+ return ov7670_g_hflip(sd, &ctrl->value);
+ }
+ return -EINVAL;
}
+static int ov7670_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return ov7670_s_brightness(sd, ctrl->value);
+ case V4L2_CID_CONTRAST:
+ return ov7670_s_contrast(sd, ctrl->value);
+ case V4L2_CID_SATURATION:
+ return ov7670_s_sat(sd, ctrl->value);
+ case V4L2_CID_HUE:
+ return ov7670_s_hue(sd, ctrl->value);
+ case V4L2_CID_VFLIP:
+ return ov7670_s_vflip(sd, ctrl->value);
+ case V4L2_CID_HFLIP:
+ return ov7670_s_hflip(sd, ctrl->value);
+ }
+ return -EINVAL;
+}
-static int ov7670_queryctrl(struct i2c_client *client,
- struct v4l2_queryctrl *qc)
+static int ov7670_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
{
- struct ov7670_control *ctrl = ov7670_find_control(qc->id);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (ctrl == NULL)
- return -EINVAL;
- *qc = ctrl->qc;
- return 0;
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_OV7670, 0);
}
-static int ov7670_g_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+static int ov7670_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ unsigned char val = 0;
int ret;
- if (octrl == NULL)
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
return -EINVAL;
- ret = octrl->query(client, &ctrl->value);
- if (ret >= 0)
- return 0;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ret = ov7670_read(sd, reg->reg & 0xff, &val);
+ reg->val = val;
+ reg->size = 1;
return ret;
}
-static int ov7670_s_ctrl(struct i2c_client *client, struct v4l2_control *ctrl)
+static int ov7670_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
- struct ov7670_control *octrl = ov7670_find_control(ctrl->id);
- int ret;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (octrl == NULL)
+ if (!v4l2_chip_match_i2c_client(client, &reg->match))
return -EINVAL;
- ret = octrl->tweak(client, ctrl->value);
- if (ret >= 0)
- return 0;
- return ret;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ ov7670_write(sd, reg->reg & 0xff, reg->val & 0xff);
+ return 0;
}
+#endif
+
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops ov7670_core_ops = {
+ .g_chip_ident = ov7670_g_chip_ident,
+ .g_ctrl = ov7670_g_ctrl,
+ .s_ctrl = ov7670_s_ctrl,
+ .queryctrl = ov7670_queryctrl,
+ .reset = ov7670_reset,
+ .init = ov7670_init,
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ .g_register = ov7670_g_register,
+ .s_register = ov7670_s_register,
+#endif
+};
+static const struct v4l2_subdev_video_ops ov7670_video_ops = {
+ .enum_fmt = ov7670_enum_fmt,
+ .try_fmt = ov7670_try_fmt,
+ .s_fmt = ov7670_s_fmt,
+ .s_parm = ov7670_s_parm,
+ .g_parm = ov7670_g_parm,
+};
+static const struct v4l2_subdev_ops ov7670_ops = {
+ .core = &ov7670_core_ops,
+ .video = &ov7670_video_ops,
+};
+/* ----------------------------------------------------------------------- */
-
-
-/*
- * Basic i2c stuff.
- */
-static struct i2c_driver ov7670_driver;
-
-static int ov7670_attach(struct i2c_adapter *adapter)
+static int ov7670_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- int ret;
- struct i2c_client *client;
+ struct v4l2_subdev *sd;
struct ov7670_info *info;
+ int ret;
- /*
- * For now: only deal with adapters we recognize.
- */
- if (adapter->id != I2C_HW_SMBUS_CAFE)
- return -ENODEV;
-
- client = kzalloc(sizeof (struct i2c_client), GFP_KERNEL);
- if (! client)
+ info = kzalloc(sizeof(struct ov7670_info), GFP_KERNEL);
+ if (info == NULL)
return -ENOMEM;
- client->adapter = adapter;
- client->addr = OV7670_I2C_ADDR;
- client->driver = &ov7670_driver,
- strcpy(client->name, "OV7670");
- /*
- * Set up our info structure.
- */
- info = kzalloc(sizeof (struct ov7670_info), GFP_KERNEL);
- if (! info) {
- ret = -ENOMEM;
- goto out_free;
+ sd = &info->sd;
+ v4l2_i2c_subdev_init(sd, client, &ov7670_ops);
+
+ /* Make sure it's an ov7670 */
+ ret = ov7670_detect(sd);
+ if (ret) {
+ v4l_dbg(1, debug, client,
+ "chip found @ 0x%x (%s) is not an ov7670 chip.\n",
+ client->addr << 1, client->adapter->name);
+ kfree(info);
+ return ret;
}
+ v4l_info(client, "chip found @ 0x%02x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
info->fmt = &ov7670_formats[0];
info->sat = 128; /* Review this */
- i2c_set_clientdata(client, info);
- /*
- * Make sure it's an ov7670
- */
- ret = ov7670_detect(client);
- if (ret)
- goto out_free_info;
- ret = i2c_attach_client(client);
- if (ret)
- goto out_free_info;
return 0;
-
- out_free_info:
- kfree(info);
- out_free:
- kfree(client);
- return ret;
}
-static int ov7670_detach(struct i2c_client *client)
+static int ov7670_remove(struct i2c_client *client)
{
- i2c_detach_client(client);
- kfree(i2c_get_clientdata(client));
- kfree(client);
- return 0;
-}
-
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
-static int ov7670_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- switch (cmd) {
- case VIDIOC_DBG_G_CHIP_IDENT:
- return v4l2_chip_ident_i2c_client(client, arg, V4L2_IDENT_OV7670, 0);
-
- case VIDIOC_INT_RESET:
- ov7670_reset(client);
- return 0;
-
- case VIDIOC_INT_INIT:
- return ov7670_init(client);
-
- case VIDIOC_ENUM_FMT:
- return ov7670_enum_fmt(client, (struct v4l2_fmtdesc *) arg);
- case VIDIOC_TRY_FMT:
- return ov7670_try_fmt(client, (struct v4l2_format *) arg, NULL, NULL);
- case VIDIOC_S_FMT:
- return ov7670_s_fmt(client, (struct v4l2_format *) arg);
- case VIDIOC_QUERYCTRL:
- return ov7670_queryctrl(client, (struct v4l2_queryctrl *) arg);
- case VIDIOC_S_CTRL:
- return ov7670_s_ctrl(client, (struct v4l2_control *) arg);
- case VIDIOC_G_CTRL:
- return ov7670_g_ctrl(client, (struct v4l2_control *) arg);
- case VIDIOC_S_PARM:
- return ov7670_s_parm(client, (struct v4l2_streamparm *) arg);
- case VIDIOC_G_PARM:
- return ov7670_g_parm(client, (struct v4l2_streamparm *) arg);
- }
- return -EINVAL;
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
+ return 0;
}
-
-
-static struct i2c_driver ov7670_driver = {
- .driver = {
- .name = "ov7670",
- },
- .id = I2C_DRIVERID_OV7670,
- .attach_adapter = ov7670_attach,
- .detach_client = ov7670_detach,
- .command = ov7670_command,
+static const struct i2c_device_id ov7670_id[] = {
+ { "ov7670", 0 },
+ { }
};
+MODULE_DEVICE_TABLE(i2c, ov7670_id);
-
-/*
- * Module initialization
- */
-static int __init ov7670_mod_init(void)
-{
- printk(KERN_NOTICE "OmniVision ov7670 sensor driver, at your service\n");
- return i2c_add_driver(&ov7670_driver);
-}
-
-static void __exit ov7670_mod_exit(void)
-{
- i2c_del_driver(&ov7670_driver);
-}
-
-module_init(ov7670_mod_init);
-module_exit(ov7670_mod_exit);
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "ov7670",
+ .probe = ov7670_probe,
+ .remove = ov7670_remove,
+ .id_table = ov7670_id,
+};
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 3c9e0ba974e..84b0fc1bb23 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -217,10 +217,11 @@
#define OCAP_4x 0x03 /* 4x */
/* COM3 */
-#define SWAP_MASK 0x38
+#define SWAP_MASK (SWAP_RGB | SWAP_YUV | SWAP_ML)
+#define IMG_MASK (VFLIP_IMG | HFLIP_IMG)
-#define VFIMG_ON_OFF 0x80 /* Vertical flip image ON/OFF selection */
-#define HMIMG_ON_OFF 0x40 /* Horizontal mirror image ON/OFF selection */
+#define VFLIP_IMG 0x80 /* Vertical flip image ON/OFF selection */
+#define HFLIP_IMG 0x40 /* Horizontal mirror image ON/OFF selection */
#define SWAP_RGB 0x20 /* Swap B/R output sequence in RGB mode */
#define SWAP_YUV 0x10 /* Swap Y/UV output sequence in YUV mode */
#define SWAP_ML 0x08 /* Swap output MSB/LSB */
@@ -271,11 +272,13 @@
#define SLCT_QVGA 0x40 /* 1 : QVGA */
#define ITU656_ON_OFF 0x20 /* ITU656 protocol ON/OFF selection */
/* RGB output format control */
+#define FMT_MASK 0x0c /* Mask of color format */
#define FMT_GBR422 0x00 /* 00 : GBR 4:2:2 */
#define FMT_RGB565 0x04 /* 01 : RGB 565 */
#define FMT_RGB555 0x08 /* 10 : RGB 555 */
#define FMT_RGB444 0x0c /* 11 : RGB 444 */
/* Output format control */
+#define OFMT_MASK 0x03 /* Mask of output format */
#define OFMT_YUV 0x00 /* 00 : YUV */
#define OFMT_P_BRAW 0x01 /* 01 : Processed Bayer RAW */
#define OFMT_RGB 0x02 /* 10 : RGB */
@@ -299,7 +302,7 @@
#define GAIN_2x 0x00 /* 000 : 2x */
#define GAIN_4x 0x10 /* 001 : 4x */
#define GAIN_8x 0x20 /* 010 : 8x */
-#define GAIN_16x 0x30 /* 011 : 16x */
+#define GAIN_16x 0x30 /* 011 : 16x */
#define GAIN_32x 0x40 /* 100 : 32x */
#define GAIN_64x 0x50 /* 101 : 64x */
#define GAIN_128x 0x60 /* 110 : 128x */
@@ -356,13 +359,6 @@
#define VOSZ_QVGA 0x78
/*
- * bit configure (32 bit)
- * this is used in struct ov772x_color_format :: option
- */
-#define OP_UV 0x00000001
-#define OP_SWAP_RGB 0x00000002
-
-/*
* ID
*/
#define OV7720 0x7720
@@ -380,8 +376,9 @@ struct regval_list {
struct ov772x_color_format {
char *name;
__u32 fourcc;
- const struct regval_list *regs;
- unsigned int option;
+ u8 dsp3;
+ u8 com3;
+ u8 com7;
};
struct ov772x_win_size {
@@ -399,39 +396,13 @@ struct ov772x_priv {
const struct ov772x_color_format *fmt;
const struct ov772x_win_size *win;
int model;
+ unsigned int flag_vflip:1;
+ unsigned int flag_hflip:1;
};
#define ENDMARKER { 0xff, 0xff }
/*
- * register setting for color format
- */
-static const struct regval_list ov772x_RGB555_regs[] = {
- { COM3, 0x00 },
- { COM7, FMT_RGB555 | OFMT_RGB },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_RGB565_regs[] = {
- { COM3, 0x00 },
- { COM7, FMT_RGB565 | OFMT_RGB },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_YYUV_regs[] = {
- { COM3, SWAP_YUV },
- { COM7, OFMT_YUV },
- ENDMARKER,
-};
-
-static const struct regval_list ov772x_UVYY_regs[] = {
- { COM3, 0x00 },
- { COM7, OFMT_YUV },
- ENDMARKER,
-};
-
-
-/*
* register setting for window size
*/
static const struct regval_list ov772x_qvga_regs[] = {
@@ -500,38 +471,48 @@ static const struct soc_camera_data_format ov772x_fmt_lists[] = {
/*
* color format list
*/
-#define T_YUYV 0
static const struct ov772x_color_format ov772x_cfmts[] = {
- [T_YUYV] = {
+ {
SETFOURCC(YUYV),
- .regs = ov772x_YYUV_regs,
+ .dsp3 = 0x0,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(YVYU),
- .regs = ov772x_YYUV_regs,
- .option = OP_UV,
+ .dsp3 = UV_ON,
+ .com3 = SWAP_YUV,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(UYVY),
- .regs = ov772x_UVYY_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = OFMT_YUV,
},
{
SETFOURCC(RGB555),
- .regs = ov772x_RGB555_regs,
- .option = OP_SWAP_RGB,
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
SETFOURCC(RGB555X),
- .regs = ov772x_RGB555_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB555 | OFMT_RGB,
},
{
SETFOURCC(RGB565),
- .regs = ov772x_RGB565_regs,
- .option = OP_SWAP_RGB,
+ .dsp3 = 0x0,
+ .com3 = SWAP_RGB,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
{
SETFOURCC(RGB565X),
- .regs = ov772x_RGB565_regs,
+ .dsp3 = 0x0,
+ .com3 = 0x0,
+ .com7 = FMT_RGB565 | OFMT_RGB,
},
};
@@ -562,6 +543,27 @@ static const struct ov772x_win_size ov772x_win_qvga = {
.regs = ov772x_qvga_regs,
};
+static const struct v4l2_queryctrl ov772x_controls[] = {
+ {
+ .id = V4L2_CID_VFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Vertically",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+ {
+ .id = V4L2_CID_HFLIP,
+ .type = V4L2_CTRL_TYPE_BOOLEAN,
+ .name = "Flip Horizontally",
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .default_value = 0,
+ },
+};
+
/*
* general function
@@ -587,8 +589,11 @@ static int ov772x_mask_set(struct i2c_client *client,
u8 set)
{
s32 val = i2c_smbus_read_byte_data(client, command);
+ if (val < 0)
+ return val;
+
val &= ~mask;
- val |= set;
+ val |= set & mask;
return i2c_smbus_write_byte_data(client, command, val);
}
@@ -635,74 +640,24 @@ static int ov772x_release(struct soc_camera_device *icd)
static int ov772x_start_capture(struct soc_camera_device *icd)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- int ret;
-
- if (!priv->win)
- priv->win = &ov772x_win_vga;
- if (!priv->fmt)
- priv->fmt = &ov772x_cfmts[T_YUYV];
-
- /*
- * reset hardware
- */
- ov772x_reset(priv->client);
- /*
- * set color format
- */
- ret = ov772x_write_array(priv->client, priv->fmt->regs);
- if (ret < 0)
- goto start_end;
-
- /*
- * set size format
- */
- ret = ov772x_write_array(priv->client, priv->win->regs);
- if (ret < 0)
- goto start_end;
-
- /*
- * set COM7 bit ( QVGA or VGA )
- */
- ret = ov772x_mask_set(priv->client,
- COM7, SLCT_MASK, priv->win->com7_bit);
- if (ret < 0)
- goto start_end;
-
- /*
- * set UV setting
- */
- if (priv->fmt->option & OP_UV) {
- ret = ov772x_mask_set(priv->client,
- DSP_CTRL3, UV_MASK, UV_ON);
- if (ret < 0)
- goto start_end;
+ if (!priv->win || !priv->fmt) {
+ dev_err(&icd->dev, "norm or win select error\n");
+ return -EPERM;
}
- /*
- * set SWAP setting
- */
- if (priv->fmt->option & OP_SWAP_RGB) {
- ret = ov772x_mask_set(priv->client,
- COM3, SWAP_MASK, SWAP_RGB);
- if (ret < 0)
- goto start_end;
- }
+ ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0);
dev_dbg(&icd->dev,
"format %s, win %s\n", priv->fmt->name, priv->win->name);
-start_end:
- priv->fmt = NULL;
- priv->win = NULL;
-
- return ret;
+ return 0;
}
static int ov772x_stop_capture(struct soc_camera_device *icd)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- ov772x_reset(priv->client);
+ ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
return 0;
}
@@ -718,11 +673,54 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
struct soc_camera_link *icl = priv->client->dev.platform_data;
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
- priv->info->buswidth;
+ SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
return soc_camera_apply_sensor_flags(icl, flags);
}
+static int ov772x_get_control(struct soc_camera_device *icd,
+ struct v4l2_control *ctrl)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_VFLIP:
+ ctrl->value = priv->flag_vflip;
+ break;
+ case V4L2_CID_HFLIP:
+ ctrl->value = priv->flag_hflip;
+ break;
+ }
+ return 0;
+}
+
+static int ov772x_set_control(struct soc_camera_device *icd,
+ struct v4l2_control *ctrl)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ int ret = 0;
+ u8 val;
+
+ switch (ctrl->id) {
+ case V4L2_CID_VFLIP:
+ val = ctrl->value ? VFLIP_IMG : 0x00;
+ priv->flag_vflip = ctrl->value;
+ if (priv->info->flags & OV772X_FLAG_VFLIP)
+ val ^= VFLIP_IMG;
+ ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val);
+ break;
+ case V4L2_CID_HFLIP:
+ val = ctrl->value ? HFLIP_IMG : 0x00;
+ priv->flag_hflip = ctrl->value;
+ if (priv->info->flags & OV772X_FLAG_HFLIP)
+ val ^= HFLIP_IMG;
+ ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val);
+ break;
+ }
+
+ return ret;
+}
+
static int ov772x_get_chip_id(struct soc_camera_device *icd,
struct v4l2_dbg_chip_ident *id)
{
@@ -787,13 +785,11 @@ ov772x_select_win(u32 width, u32 height)
return win;
}
-
-static int ov772x_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt,
- struct v4l2_rect *rect)
+static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
+ u32 pixfmt)
{
- struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
int ret = -EINVAL;
+ u8 val;
int i;
/*
@@ -803,19 +799,101 @@ static int ov772x_set_fmt(struct soc_camera_device *icd,
for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
if (pixfmt == ov772x_cfmts[i].fourcc) {
priv->fmt = ov772x_cfmts + i;
- ret = 0;
break;
}
}
+ if (!priv->fmt)
+ goto ov772x_set_fmt_error;
/*
* select win
*/
- priv->win = ov772x_select_win(rect->width, rect->height);
+ priv->win = ov772x_select_win(width, height);
+
+ /*
+ * reset hardware
+ */
+ ov772x_reset(priv->client);
+
+ /*
+ * set size format
+ */
+ ret = ov772x_write_array(priv->client, priv->win->regs);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ /*
+ * set DSP_CTRL3
+ */
+ val = priv->fmt->dsp3;
+ if (val) {
+ ret = ov772x_mask_set(priv->client,
+ DSP_CTRL3, UV_MASK, val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ }
+
+ /*
+ * set COM3
+ */
+ val = priv->fmt->com3;
+ if (priv->info->flags & OV772X_FLAG_VFLIP)
+ val |= VFLIP_IMG;
+ if (priv->info->flags & OV772X_FLAG_HFLIP)
+ val |= HFLIP_IMG;
+ if (priv->flag_vflip)
+ val ^= VFLIP_IMG;
+ if (priv->flag_hflip)
+ val ^= HFLIP_IMG;
+
+ ret = ov772x_mask_set(priv->client,
+ COM3, SWAP_MASK | IMG_MASK, val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ /*
+ * set COM7
+ */
+ val = priv->win->com7_bit | priv->fmt->com7;
+ ret = ov772x_mask_set(priv->client,
+ COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
+ val);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ return ret;
+
+ov772x_set_fmt_error:
+
+ ov772x_reset(priv->client);
+ priv->win = NULL;
+ priv->fmt = NULL;
return ret;
}
+static int ov772x_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+
+ if (!priv->fmt)
+ return -EINVAL;
+
+ return ov772x_set_params(priv, rect->width, rect->height,
+ priv->fmt->fourcc);
+}
+
+static int ov772x_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+
+ return ov772x_set_params(priv, pix->width, pix->height,
+ pix->pixelformat);
+}
+
static int ov772x_try_fmt(struct soc_camera_device *icd,
struct v4l2_format *f)
{
@@ -889,7 +967,6 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
i2c_smbus_read_byte_data(priv->client, MIDH),
i2c_smbus_read_byte_data(priv->client, MIDL));
-
return soc_camera_video_start(icd);
}
@@ -906,10 +983,15 @@ static struct soc_camera_ops ov772x_ops = {
.release = ov772x_release,
.start_capture = ov772x_start_capture,
.stop_capture = ov772x_stop_capture,
+ .set_crop = ov772x_set_crop,
.set_fmt = ov772x_set_fmt,
.try_fmt = ov772x_try_fmt,
.set_bus_param = ov772x_set_bus_param,
.query_bus_param = ov772x_query_bus_param,
+ .controls = ov772x_controls,
+ .num_controls = ARRAY_SIZE(ov772x_controls),
+ .get_control = ov772x_get_control,
+ .set_control = ov772x_set_control,
.get_chip_id = ov772x_get_chip_id,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.get_register = ov772x_get_register,
diff --git a/drivers/media/video/ovcamchip/ovcamchip_core.c b/drivers/media/video/ovcamchip/ovcamchip_core.c
index c841f4e4fbe..d573d842899 100644
--- a/drivers/media/video/ovcamchip/ovcamchip_core.c
+++ b/drivers/media/video/ovcamchip/ovcamchip_core.c
@@ -15,6 +15,9 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-i2c-drv.h>
#include "ovcamchip_priv.h"
#define DRIVER_VERSION "v2.27 for Linux 2.6"
@@ -44,6 +47,7 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
+
/* Registers common to all chips, that are needed for detection */
#define GENERIC_REG_ID_HIGH 0x1C /* manufacturer ID MSB */
#define GENERIC_REG_ID_LOW 0x1D /* manufacturer ID LSB */
@@ -61,10 +65,6 @@ static char *chip_names[NUM_CC_TYPES] = {
[CC_OV6630AF] = "OV6630AF",
};
-/* Forward declarations */
-static struct i2c_driver driver;
-static struct i2c_client client_template;
-
/* ----------------------------------------------------------------------- */
int ov_write_regvals(struct i2c_client *c, struct ovcamchip_regvals *rvals)
@@ -253,112 +253,36 @@ static int ovcamchip_detect(struct i2c_client *c)
/* Test for 7xx0 */
PDEBUG(3, "Testing for 0V7xx0");
- c->addr = OV7xx0_SID;
- if (init_camchip(c) < 0) {
- /* Test for 6xx0 */
- PDEBUG(3, "Testing for 0V6xx0");
- c->addr = OV6xx0_SID;
- if (init_camchip(c) < 0) {
- return -ENODEV;
- } else {
- if (ov6xx0_detect(c) < 0) {
- PERROR("Failed to init OV6xx0");
- return -EIO;
- }
- }
- } else {
+ if (init_camchip(c) < 0)
+ return -ENODEV;
+ /* 7-bit addresses with bit 0 set are for the OV7xx0 */
+ if (c->addr & 1) {
if (ov7xx0_detect(c) < 0) {
PERROR("Failed to init OV7xx0");
return -EIO;
}
+ return 0;
+ }
+ /* Test for 6xx0 */
+ PDEBUG(3, "Testing for 0V6xx0");
+ if (ov6xx0_detect(c) < 0) {
+ PERROR("Failed to init OV6xx0");
+ return -EIO;
}
-
return 0;
}
/* ----------------------------------------------------------------------- */
-static int ovcamchip_attach(struct i2c_adapter *adap)
+static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
- int rc = 0;
- struct ovcamchip *ov;
- struct i2c_client *c;
-
- /* I2C is not a PnP bus, so we can never be certain that we're talking
- * to the right chip. To prevent damage to EEPROMS and such, only
- * attach to adapters that are known to contain OV camera chips. */
-
- switch (adap->id) {
- case I2C_HW_SMBUS_OV511:
- case I2C_HW_SMBUS_OV518:
- case I2C_HW_SMBUS_W9968CF:
- PDEBUG(1, "Adapter ID 0x%06x accepted", adap->id);
- break;
- default:
- PDEBUG(1, "Adapter ID 0x%06x rejected", adap->id);
- return -ENODEV;
- }
-
- c = kmalloc(sizeof *c, GFP_KERNEL);
- if (!c) {
- rc = -ENOMEM;
- goto no_client;
- }
- memcpy(c, &client_template, sizeof *c);
- c->adapter = adap;
- strcpy(c->name, "OV????");
-
- ov = kzalloc(sizeof *ov, GFP_KERNEL);
- if (!ov) {
- rc = -ENOMEM;
- goto no_ov;
- }
- i2c_set_clientdata(c, ov);
-
- rc = ovcamchip_detect(c);
- if (rc < 0)
- goto error;
-
- strcpy(c->name, chip_names[ov->subtype]);
-
- PDEBUG(1, "Camera chip detection complete");
-
- i2c_attach_client(c);
-
- return rc;
-error:
- kfree(ov);
-no_ov:
- kfree(c);
-no_client:
- PDEBUG(1, "returning %d", rc);
- return rc;
-}
-
-static int ovcamchip_detach(struct i2c_client *c)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
- int rc;
-
- rc = ov->sops->free(c);
- if (rc < 0)
- return rc;
-
- i2c_detach_client(c);
-
- kfree(ov);
- kfree(c);
- return 0;
-}
-
-static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
-{
- struct ovcamchip *ov = i2c_get_clientdata(c);
+ struct ovcamchip *ov = to_ovcamchip(sd);
+ struct i2c_client *c = v4l2_get_subdevdata(sd);
if (!ov->initialized &&
cmd != OVCAMCHIP_CMD_Q_SUBTYPE &&
cmd != OVCAMCHIP_CMD_INITIALIZE) {
- dev_err(&c->dev, "ERROR: Camera chip not initialized yet!\n");
+ v4l2_err(sd, "Camera chip not initialized yet!\n");
return -EPERM;
}
@@ -379,10 +303,10 @@ static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
if (ov->mono) {
if (ov->subtype != CC_OV7620)
- dev_warn(&c->dev, "Warning: Monochrome not "
+ v4l2_warn(sd, "Monochrome not "
"implemented for this chip\n");
else
- dev_info(&c->dev, "Initializing chip as "
+ v4l2_info(sd, "Initializing chip as "
"monochrome\n");
}
@@ -400,35 +324,72 @@ static int ovcamchip_command(struct i2c_client *c, unsigned int cmd, void *arg)
/* ----------------------------------------------------------------------- */
-static struct i2c_driver driver = {
- .driver = {
- .name = "ovcamchip",
- },
- .id = I2C_DRIVERID_OVCAMCHIP,
- .attach_adapter = ovcamchip_attach,
- .detach_client = ovcamchip_detach,
- .command = ovcamchip_command,
+static const struct v4l2_subdev_core_ops ovcamchip_core_ops = {
+ .ioctl = ovcamchip_ioctl,
};
-static struct i2c_client client_template = {
- .name = "(unset)",
- .driver = &driver,
+static const struct v4l2_subdev_ops ovcamchip_ops = {
+ .core = &ovcamchip_core_ops,
};
-static int __init ovcamchip_init(void)
+static int ovcamchip_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
-#ifdef DEBUG
- ovcamchip_debug = debug;
-#endif
+ struct ovcamchip *ov;
+ struct v4l2_subdev *sd;
+ int rc = 0;
+
+ ov = kzalloc(sizeof *ov, GFP_KERNEL);
+ if (!ov) {
+ rc = -ENOMEM;
+ goto no_ov;
+ }
+ sd = &ov->sd;
+ v4l2_i2c_subdev_init(sd, client, &ovcamchip_ops);
+
+ rc = ovcamchip_detect(client);
+ if (rc < 0)
+ goto error;
+
+ v4l_info(client, "%s found @ 0x%02x (%s)\n",
+ chip_names[ov->subtype], client->addr << 1, client->adapter->name);
+
+ PDEBUG(1, "Camera chip detection complete");
- PINFO(DRIVER_VERSION " : " DRIVER_DESC);
- return i2c_add_driver(&driver);
+ return rc;
+error:
+ kfree(ov);
+no_ov:
+ PDEBUG(1, "returning %d", rc);
+ return rc;
}
-static void __exit ovcamchip_exit(void)
+static int ovcamchip_remove(struct i2c_client *client)
{
- i2c_del_driver(&driver);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct ovcamchip *ov = to_ovcamchip(sd);
+ int rc;
+
+ v4l2_device_unregister_subdev(sd);
+ rc = ov->sops->free(client);
+ if (rc < 0)
+ return rc;
+
+ kfree(ov);
+ return 0;
}
-module_init(ovcamchip_init);
-module_exit(ovcamchip_exit);
+/* ----------------------------------------------------------------------- */
+
+static const struct i2c_device_id ovcamchip_id[] = {
+ { "ovcamchip", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, ovcamchip_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "ovcamchip",
+ .probe = ovcamchip_probe,
+ .remove = ovcamchip_remove,
+ .id_table = ovcamchip_id,
+};
diff --git a/drivers/media/video/ovcamchip/ovcamchip_priv.h b/drivers/media/video/ovcamchip/ovcamchip_priv.h
index a05650faedd..4f07b78c88b 100644
--- a/drivers/media/video/ovcamchip/ovcamchip_priv.h
+++ b/drivers/media/video/ovcamchip/ovcamchip_priv.h
@@ -16,6 +16,7 @@
#define __LINUX_OVCAMCHIP_PRIV_H
#include <linux/i2c.h>
+#include <media/v4l2-subdev.h>
#include <media/ovcamchip.h>
#ifdef DEBUG
@@ -46,6 +47,7 @@ struct ovcamchip_ops {
};
struct ovcamchip {
+ struct v4l2_subdev sd;
struct ovcamchip_ops *sops;
void *spriv; /* Private data for OV7x10.c etc... */
int subtype; /* = SEN_OV7610 etc... */
@@ -53,6 +55,11 @@ struct ovcamchip {
int initialized; /* OVCAMCHIP_CMD_INITIALIZE was successful */
};
+static inline struct ovcamchip *to_ovcamchip(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct ovcamchip, sd);
+}
+
extern struct ovcamchip_ops ov6x20_ops;
extern struct ovcamchip_ops ov6x30_ops;
extern struct ovcamchip_ops ov7x10_ops;
diff --git a/drivers/media/video/pvrusb2/Kconfig b/drivers/media/video/pvrusb2/Kconfig
index 854c2a88535..f9b6001e1dd 100644
--- a/drivers/media/video/pvrusb2/Kconfig
+++ b/drivers/media/video/pvrusb2/Kconfig
@@ -40,10 +40,10 @@ config VIDEO_PVRUSB2_DVB
select DVB_LGDT330X if !DVB_FE_CUSTOMISE
select DVB_S5H1409 if !DVB_FE_CUSTOMISE
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
- select DVB_TDA10048 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_TDA18271 if !DVB_FE_CUSTOMIZE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_TDA8290 if !DVB_FE_CUSTOMIZE
+ select DVB_TDA10048 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
---help---
This option enables a DVB interface for the pvrusb2 driver.
diff --git a/drivers/media/video/pvrusb2/Makefile b/drivers/media/video/pvrusb2/Makefile
index 4fda2de69ab..de2fc14f043 100644
--- a/drivers/media/video/pvrusb2/Makefile
+++ b/drivers/media/video/pvrusb2/Makefile
@@ -2,14 +2,15 @@ obj-pvrusb2-sysfs-$(CONFIG_VIDEO_PVRUSB2_SYSFS) := pvrusb2-sysfs.o
obj-pvrusb2-debugifc-$(CONFIG_VIDEO_PVRUSB2_DEBUGIFC) := pvrusb2-debugifc.o
obj-pvrusb2-dvb-$(CONFIG_VIDEO_PVRUSB2_DVB) := pvrusb2-dvb.o
-pvrusb2-objs := pvrusb2-i2c-core.o pvrusb2-i2c-cmd-v4l2.o \
- pvrusb2-audio.o pvrusb2-i2c-chips-v4l2.o \
+pvrusb2-objs := pvrusb2-i2c-core.o \
+ pvrusb2-audio.o \
pvrusb2-encoder.o pvrusb2-video-v4l.o \
- pvrusb2-eeprom.o pvrusb2-tuner.o \
+ pvrusb2-eeprom.o \
pvrusb2-main.o pvrusb2-hdw.o pvrusb2-v4l2.o \
pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
+ pvrusb2-cs53l32a.o \
$(obj-pvrusb2-dvb-y) \
$(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.c b/drivers/media/video/pvrusb2/pvrusb2-audio.c
index cdedaa55f15..ccf2a3c7ad0 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.c
@@ -26,14 +26,6 @@
#include <media/msp3400.h>
#include <media/v4l2-common.h>
-struct pvr2_msp3400_handler {
- struct pvr2_hdw *hdw;
- struct pvr2_i2c_client *client;
- struct pvr2_i2c_handler i2c_handler;
- unsigned long stale_mask;
-};
-
-
struct routing_scheme {
const int *def;
@@ -63,123 +55,33 @@ static const struct routing_scheme routing_schemes[] = {
},
};
-/* This function selects the correct audio input source */
-static void set_stereo(struct pvr2_msp3400_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c msp3400 v4l2 set_stereo");
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c msp3400 v4l2 set_stereo:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
- route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_stereo(struct pvr2_msp3400_handler *ctxt)
+void pvr2_msp3400_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty;
-}
-
-
-struct pvr2_msp3400_ops {
- void (*update)(struct pvr2_msp3400_handler *);
- int (*check)(struct pvr2_msp3400_handler *);
-};
-
-
-static const struct pvr2_msp3400_ops msp3400_ops[] = {
- { .update = set_stereo, .check = check_stereo},
-};
-
-
-static int msp3400_check(struct pvr2_msp3400_handler *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (msp3400_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev msp3400 v4l2 set_stereo");
+
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ route.input = sp->def[hdw->input_val];
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev msp3400 set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
}
+ route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
+ sd->ops->audio->s_routing(sd, &route);
}
- return ctxt->stale_mask != 0;
}
-
-static void msp3400_update(struct pvr2_msp3400_handler *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(msp3400_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- msp3400_ops[idx].update(ctxt);
- }
-}
-
-
-static void pvr2_msp3400_detach(struct pvr2_msp3400_handler *ctxt)
-{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static unsigned int pvr2_msp3400_describe(struct pvr2_msp3400_handler *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-audio v4l2");
-}
-
-
-static const struct pvr2_i2c_handler_functions msp3400_funcs = {
- .detach = (void (*)(void *))pvr2_msp3400_detach,
- .check = (int (*)(void *))msp3400_check,
- .update = (void (*)(void *))msp3400_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_msp3400_describe,
-};
-
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_msp3400_handler *ctxt;
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->i2c_handler.func_data = ctxt;
- ctxt->i2c_handler.func_table = &msp3400_funcs;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(msp3400_ops)) - 1;
- cp->handler = &ctxt->i2c_handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x msp3400 V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
*** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-audio.h b/drivers/media/video/pvrusb2/pvrusb2-audio.h
index ac54eed3721..e3e63d75089 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-audio.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-audio.h
@@ -22,10 +22,8 @@
#ifndef __PVRUSB2_AUDIO_H
#define __PVRUSB2_AUDIO_H
-#include "pvrusb2-i2c-core.h"
-
-int pvr2_i2c_msp3400_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
+#include "pvrusb2-hdw-internal.h"
+void pvr2_msp3400_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
#endif /* __PVRUSB2_AUDIO_H */
/*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
new file mode 100644
index 00000000000..b5c3428ebb9
--- /dev/null
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.c
@@ -0,0 +1,95 @@
+/*
+ *
+ *
+ * Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public 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 source file is specifically designed to interface with the
+ v4l-dvb cs53l32a module.
+
+*/
+
+#include "pvrusb2-cs53l32a.h"
+
+
+#include "pvrusb2-hdw-internal.h"
+#include "pvrusb2-debug.h"
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+
+struct routing_scheme {
+ const int *def;
+ unsigned int cnt;
+};
+
+
+static const int routing_scheme1[] = {
+ [PVR2_CVAL_INPUT_TV] = 2, /* 1 or 2 seems to work here */
+ [PVR2_CVAL_INPUT_RADIO] = 2,
+ [PVR2_CVAL_INPUT_COMPOSITE] = 0,
+ [PVR2_CVAL_INPUT_SVIDEO] = 0,
+};
+
+static const struct routing_scheme routing_schemes[] = {
+ [PVR2_ROUTING_SCHEME_ONAIR] = {
+ .def = routing_scheme1,
+ .cnt = ARRAY_SIZE(routing_scheme1),
+ },
+};
+
+
+void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
+{
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
+ hdw->input_val);
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ route.input = sp->def[hdw->input_val];
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev v4l2 set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
+ }
+ route.output = 0;
+ sd->ops->audio->s_routing(sd, &route);
+ }
+}
+
+
+/*
+ Stuff for Emacs to see, in order to encourage consistent editing style:
+ *** Local Variables: ***
+ *** mode: c ***
+ *** fill-column: 70 ***
+ *** tab-width: 8 ***
+ *** c-basic-offset: 8 ***
+ *** End: ***
+ */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.h b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
index ef4afaf37b0..53ba548b72a 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-cs53l32a.h
@@ -2,6 +2,7 @@
*
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
+ * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,14 +18,24 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#ifndef __PVRUSB2_TUNER_H
-#define __PVRUSB2_TUNER_H
-#include "pvrusb2-i2c-core.h"
+#ifndef __PVRUSB2_CS53L32A_H
+#define __PVRUSB2_CS53L32A_H
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+/*
+
+ This module connects the pvrusb2 driver to the I2C chip level
+ driver which handles device video processing. This interface is
+ used internally by the driver; higher level code should only
+ interact through the interface provided by pvrusb2-hdw.h.
+
+*/
+
+
+#include "pvrusb2-hdw-internal.h"
+void pvr2_cs53l32a_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
-#endif /* __PVRUSB2_TUNER_H */
+#endif /* __PVRUSB2_AUDIO_CS53L32A_H */
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 895859ec495..4e017ff26c3 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -28,7 +28,6 @@
#include "pvrusb2-cx2584x-v4l.h"
#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h"
@@ -39,14 +38,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
-struct pvr2_v4l_cx2584x {
- struct pvr2_i2c_handler handler;
- struct pvr2_decoder_ctrl ctrl;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
struct routing_scheme_item {
int vid;
@@ -110,218 +101,44 @@ static const struct routing_scheme routing_schemes[] = {
},
};
-static void set_input(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- enum cx25840_video_input vid_input;
- enum cx25840_audio_input aud_input;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- memset(&route,0,sizeof(route));
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- vid_input = sp->def[hdw->input_val].vid;
- aud_input = sp->def[hdw->input_val].aud;
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c cx2584x set_input:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_input vid=0x%x aud=0x%x",
- vid_input,aud_input);
- route.input = (u32)vid_input;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
- route.input = (u32)aud_input;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
- u32 val;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx2584x set_audio %d",
- hdw->srate_val);
- switch (hdw->srate_val) {
- default:
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
- val = 48000;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
- val = 44100;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
- val = 32000;
- break;
- }
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_cx2584x *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_cx2584x_ops {
- void (*update)(struct pvr2_v4l_cx2584x *);
- int (*check)(struct pvr2_v4l_cx2584x *);
-};
-
-
-static const struct pvr2_v4l_cx2584x_ops decoder_ops[] = {
- { .update = set_input, .check = check_input},
- { .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_cx2584x *ctxt)
+void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- ctxt->client->handler = NULL;
- pvr2_hdw_set_decoder(ctxt->hdw,NULL);
- kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_cx2584x *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (decoder_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ enum cx25840_video_input vid_input;
+ enum cx25840_audio_input aud_input;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+
+ memset(&route, 0, sizeof(route));
+
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ vid_input = sp->def[hdw->input_val].vid;
+ aud_input = sp->def[hdw->input_val].aud;
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev cx2584x set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
}
- }
- return ctxt->stale_mask != 0;
-}
-
-static void decoder_update(struct pvr2_v4l_cx2584x *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- decoder_ops[idx].update(ctxt);
+ pvr2_trace(PVR2_TRACE_CHIPS,
+ "subdev cx2584x set_input vid=0x%x aud=0x%x",
+ vid_input, aud_input);
+ route.input = (u32)vid_input;
+ sd->ops->video->s_routing(sd, &route);
+ route.input = (u32)aud_input;
+ sd->ops->audio->s_routing(sd, &route);
}
}
-static void decoder_enable(struct pvr2_v4l_cx2584x *ctxt,int fl)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_enable(%d)",fl);
- pvr2_v4l2_cmd_stream(ctxt->client,fl);
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
- int ret;
- /* Attempt to query the decoder - let's see if it will answer */
- struct v4l2_queryctrl qc;
-
- memset(&qc,0,sizeof(qc));
-
- qc.id = V4L2_CID_BRIGHTNESS;
-
- ret = pvr2_i2c_client_cmd(cp,VIDIOC_QUERYCTRL,&qc);
- return ret == 0; /* Return true if it answered */
-}
-
-
-static unsigned int decoder_describe(struct pvr2_v4l_cx2584x *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-cx2584x-v4l");
-}
-
-
-static void decoder_reset(struct pvr2_v4l_cx2584x *ctxt)
-{
- int ret;
- ret = pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_RESET,NULL);
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c cx25840 decoder_reset (ret=%d)",ret);
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))decoder_detach,
- .check = (int (*)(void *))decoder_check,
- .update = (void (*)(void *))decoder_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
- struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_cx2584x *ctxt;
-
- if (hdw->decoder_ctrl) return 0;
- if (cp->handler) return 0;
- if (!decoder_detect(cp)) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->ctrl.ctxt = ctxt;
- ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
- ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
- ctxt->ctrl.force_reset = (void (*)(void*))decoder_reset;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
- pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
- cp->handler = &ctxt->handler;
- {
- /*
- Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
- of nuttiness for cx25840 causes that module to
- correctly set up its video scaling. This is really
- a problem in the cx25840 module itself, but we work
- around it here. The problem has not been seen in
- ivtv because there VBI is supported and set up. We
- don't do VBI here (at least not yet) and thus we
- never attempted to even set it up.
- */
- struct v4l2_format fmt;
- memset(&fmt,0,sizeof(fmt));
- fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
- }
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
index 66abf77f51f..e35c2322a08 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.h
@@ -34,9 +34,9 @@
-#include "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
-int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+void pvr2_cx25840_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
#endif /* __PVRUSB2_CX2584X_V4L_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
index ca892fb78a5..fbe3856bdca 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.c
@@ -23,7 +23,6 @@
#include "pvrusb2-debugifc.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-core.h"
struct debugifc_mask_item {
const char *name;
@@ -147,10 +146,6 @@ int pvr2_debugifc_print_info(struct pvr2_hdw *hdw,char *buf,unsigned int acnt)
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
ccnt = pvr2_hdw_state_report(hdw,buf,acnt);
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = scnprintf(buf,acnt,"Attached I2C modules:\n");
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
- ccnt = pvr2_i2c_report(hdw,buf,acnt);
- bcnt += ccnt; acnt -= ccnt; buf += ccnt;
return bcnt;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
index e24ff59f860..2f8d46761cd 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-debugifc.h
@@ -22,16 +22,16 @@
struct pvr2_hdw;
-/* Non-intrusively print some useful debugging info from inside the
- driver. This should work even if the driver appears to be
- wedged. */
-int pvr2_debugifc_print_info(struct pvr2_hdw *,
- char *buf_ptr,unsigned int buf_size);
-
/* Print general status of driver. This will also trigger a probe of
the USB link. Unlike print_info(), this one synchronizes with the
driver so the information should be self-consistent (but it will
hang if the driver is wedged). */
+int pvr2_debugifc_print_info(struct pvr2_hdw *,
+ char *buf_ptr, unsigned int buf_size);
+
+/* Non-intrusively print some useful debugging info from inside the
+ driver. This should work even if the driver appears to be
+ wedged. */
int pvr2_debugifc_print_status(struct pvr2_hdw *,
char *buf_ptr,unsigned int buf_size);
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index cbe2a341785..1cb6a260e8b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -46,10 +46,11 @@ pvr2_device_desc structures.
/*------------------------------------------------------------------------*/
/* Hauppauge PVR-USB2 Model 29xxx */
-static const char *pvr2_client_29xxx[] = {
- "msp3400",
- "saa7115",
- "tuner",
+static const struct pvr2_device_client_desc pvr2_cli_29xxx[] = {
+ { .module_id = PVR2_CLIENT_ID_SAA7115 },
+ { .module_id = PVR2_CLIENT_ID_MSP3400 },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
+ { .module_id = PVR2_CLIENT_ID_DEMOD },
};
static const char *pvr2_fw1_names_29xxx[] = {
@@ -59,8 +60,8 @@ static const char *pvr2_fw1_names_29xxx[] = {
static const struct pvr2_device_desc pvr2_device_29xxx = {
.description = "WinTV PVR USB2 Model Category 29xxx",
.shortname = "29xxx",
- .client_modules.lst = pvr2_client_29xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_29xxx),
+ .client_table.lst = pvr2_cli_29xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_29xxx),
.fx2_firmware.lst = pvr2_fw1_names_29xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_29xxx),
.flag_has_hauppauge_rom = !0,
@@ -77,10 +78,11 @@ static const struct pvr2_device_desc pvr2_device_29xxx = {
/*------------------------------------------------------------------------*/
/* Hauppauge PVR-USB2 Model 24xxx */
-static const char *pvr2_client_24xxx[] = {
- "cx25840",
- "tuner",
- "wm8775",
+static const struct pvr2_device_client_desc pvr2_cli_24xxx[] = {
+ { .module_id = PVR2_CLIENT_ID_CX25840 },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
+ { .module_id = PVR2_CLIENT_ID_WM8775 },
+ { .module_id = PVR2_CLIENT_ID_DEMOD },
};
static const char *pvr2_fw1_names_24xxx[] = {
@@ -90,8 +92,8 @@ static const char *pvr2_fw1_names_24xxx[] = {
static const struct pvr2_device_desc pvr2_device_24xxx = {
.description = "WinTV PVR USB2 Model Category 24xxx",
.shortname = "24xxx",
- .client_modules.lst = pvr2_client_24xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_24xxx),
+ .client_table.lst = pvr2_cli_24xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_24xxx),
.fx2_firmware.lst = pvr2_fw1_names_24xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_24xxx),
.flag_has_cx25840 = !0,
@@ -111,16 +113,16 @@ static const struct pvr2_device_desc pvr2_device_24xxx = {
/*------------------------------------------------------------------------*/
/* GOTVIEW USB2.0 DVD2 */
-static const char *pvr2_client_gotview_2[] = {
- "cx25840",
- "tuner",
+static const struct pvr2_device_client_desc pvr2_cli_gotview_2[] = {
+ { .module_id = PVR2_CLIENT_ID_CX25840 },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
};
static const struct pvr2_device_desc pvr2_device_gotview_2 = {
.description = "Gotview USB 2.0 DVD 2",
.shortname = "gv2",
- .client_modules.lst = pvr2_client_gotview_2,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2),
+ .client_table.lst = pvr2_cli_gotview_2,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
.flag_has_cx25840 = !0,
.default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.flag_has_analogtuner = !0,
@@ -140,8 +142,8 @@ static const struct pvr2_device_desc pvr2_device_gotview_2 = {
static const struct pvr2_device_desc pvr2_device_gotview_2d = {
.description = "Gotview USB 2.0 DVD Deluxe",
.shortname = "gv2d",
- .client_modules.lst = pvr2_client_gotview_2,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_gotview_2),
+ .client_table.lst = pvr2_cli_gotview_2,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_gotview_2),
.flag_has_cx25840 = !0,
.default_tuner_type = TUNER_PHILIPS_FM1216ME_MK3,
.flag_has_analogtuner = !0,
@@ -181,29 +183,29 @@ static int pvr2_lgh06xf_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
+static const struct pvr2_dvb_props pvr2_onair_creator_fe_props = {
.frontend_attach = pvr2_lgdt3303_attach,
.tuner_attach = pvr2_lgh06xf_attach,
};
#endif
-static const char *pvr2_client_onair_creator[] = {
- "saa7115",
- "tuner",
- "cs53l32a",
+static const struct pvr2_device_client_desc pvr2_cli_onair_creator[] = {
+ { .module_id = PVR2_CLIENT_ID_SAA7115 },
+ { .module_id = PVR2_CLIENT_ID_CS53L32A },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
};
static const struct pvr2_device_desc pvr2_device_onair_creator = {
.description = "OnAir Creator Hybrid USB tuner",
.shortname = "oac",
- .client_modules.lst = pvr2_client_onair_creator,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_creator),
+ .client_table.lst = pvr2_cli_onair_creator,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_creator),
.default_tuner_type = TUNER_LG_TDVS_H06XF,
.flag_has_analogtuner = !0,
.flag_has_composite = !0,
.flag_has_svideo = !0,
.flag_digital_requires_cx23416 = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+ .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
.digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
.default_std_mask = V4L2_STD_NTSC_M,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -241,29 +243,29 @@ static int pvr2_fcv1236d_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
+static const struct pvr2_dvb_props pvr2_onair_usb2_fe_props = {
.frontend_attach = pvr2_lgdt3302_attach,
.tuner_attach = pvr2_fcv1236d_attach,
};
#endif
-static const char *pvr2_client_onair_usb2[] = {
- "saa7115",
- "tuner",
- "cs53l32a",
+static const struct pvr2_device_client_desc pvr2_cli_onair_usb2[] = {
+ { .module_id = PVR2_CLIENT_ID_SAA7115 },
+ { .module_id = PVR2_CLIENT_ID_CS53L32A },
+ { .module_id = PVR2_CLIENT_ID_TUNER },
};
static const struct pvr2_device_desc pvr2_device_onair_usb2 = {
.description = "OnAir USB2 Hybrid USB tuner",
.shortname = "oa2",
- .client_modules.lst = pvr2_client_onair_usb2,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_onair_usb2),
+ .client_table.lst = pvr2_cli_onair_usb2,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_onair_usb2),
.default_tuner_type = TUNER_PHILIPS_FCV1236D,
.flag_has_analogtuner = !0,
.flag_has_composite = !0,
.flag_has_svideo = !0,
.flag_digital_requires_cx23416 = !0,
- .signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
+ .signal_routing_scheme = PVR2_ROUTING_SCHEME_ONAIR,
.digital_control_scheme = PVR2_DIGITAL_SCHEME_ONAIR,
.default_std_mask = V4L2_STD_NTSC_M,
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -314,15 +316,16 @@ static int pvr2_73xxx_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_73xxx_dvb_props = {
.frontend_attach = pvr2_tda10048_attach,
.tuner_attach = pvr2_73xxx_tda18271_8295_attach,
};
#endif
-static const char *pvr2_client_73xxx[] = {
- "cx25840",
- "tuner",
+static const struct pvr2_device_client_desc pvr2_cli_73xxx[] = {
+ { .module_id = PVR2_CLIENT_ID_CX25840 },
+ { .module_id = PVR2_CLIENT_ID_TUNER,
+ .i2c_address_list = "\x42"},
};
static const char *pvr2_fw1_names_73xxx[] = {
@@ -332,8 +335,8 @@ static const char *pvr2_fw1_names_73xxx[] = {
static const struct pvr2_device_desc pvr2_device_73xxx = {
.description = "WinTV HVR-1900 Model Category 73xxx",
.shortname = "73xxx",
- .client_modules.lst = pvr2_client_73xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_73xxx),
+ .client_table.lst = pvr2_cli_73xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
.fx2_firmware.lst = pvr2_fw1_names_73xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_73xxx),
.flag_has_cx25840 = !0,
@@ -418,22 +421,17 @@ static int pvr2_tda18271_8295_attach(struct pvr2_dvb_adapter *adap)
return 0;
}
-static struct pvr2_dvb_props pvr2_750xx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_750xx_dvb_props = {
.frontend_attach = pvr2_s5h1409_attach,
.tuner_attach = pvr2_tda18271_8295_attach,
};
-static struct pvr2_dvb_props pvr2_751xx_dvb_props = {
+static const struct pvr2_dvb_props pvr2_751xx_dvb_props = {
.frontend_attach = pvr2_s5h1411_attach,
.tuner_attach = pvr2_tda18271_8295_attach,
};
#endif
-static const char *pvr2_client_75xxx[] = {
- "cx25840",
- "tuner",
-};
-
static const char *pvr2_fw1_names_75xxx[] = {
"v4l-pvrusb2-73xxx-01.fw",
};
@@ -441,8 +439,8 @@ static const char *pvr2_fw1_names_75xxx[] = {
static const struct pvr2_device_desc pvr2_device_750xx = {
.description = "WinTV HVR-1950 Model Category 750xx",
.shortname = "750xx",
- .client_modules.lst = pvr2_client_75xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
+ .client_table.lst = pvr2_cli_73xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
.fx2_firmware.lst = pvr2_fw1_names_75xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
.flag_has_cx25840 = !0,
@@ -463,8 +461,8 @@ static const struct pvr2_device_desc pvr2_device_750xx = {
static const struct pvr2_device_desc pvr2_device_751xx = {
.description = "WinTV HVR-1950 Model Category 751xx",
.shortname = "751xx",
- .client_modules.lst = pvr2_client_75xxx,
- .client_modules.cnt = ARRAY_SIZE(pvr2_client_75xxx),
+ .client_table.lst = pvr2_cli_73xxx,
+ .client_table.cnt = ARRAY_SIZE(pvr2_cli_73xxx),
.fx2_firmware.lst = pvr2_fw1_names_75xxx,
.fx2_firmware.cnt = ARRAY_SIZE(pvr2_fw1_names_75xxx),
.flag_has_cx25840 = !0,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index cb3a33eb027..3e553389cbc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -33,6 +33,34 @@
*/
+#define PVR2_CLIENT_ID_NULL 0
+#define PVR2_CLIENT_ID_MSP3400 1
+#define PVR2_CLIENT_ID_CX25840 2
+#define PVR2_CLIENT_ID_SAA7115 3
+#define PVR2_CLIENT_ID_TUNER 4
+#define PVR2_CLIENT_ID_CS53L32A 5
+#define PVR2_CLIENT_ID_WM8775 6
+#define PVR2_CLIENT_ID_DEMOD 7
+
+struct pvr2_device_client_desc {
+ /* One ovr PVR2_CLIENT_ID_xxxx */
+ unsigned char module_id;
+
+ /* Null-terminated array of I2C addresses to try in order
+ initialize the module. It's safe to make this null terminated
+ since we're never going to encounter an i2c device with an
+ address of zero. If this is a null pointer or zero-length,
+ then no I2C addresses have been specified, in which case we'll
+ try some compiled in defaults for now. */
+ unsigned char *i2c_address_list;
+};
+
+struct pvr2_device_client_table {
+ const struct pvr2_device_client_desc *lst;
+ unsigned char cnt;
+};
+
+
struct pvr2_string_table {
const char **lst;
unsigned int cnt;
@@ -40,6 +68,7 @@ struct pvr2_string_table {
#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
#define PVR2_ROUTING_SCHEME_GOTVIEW 1
+#define PVR2_ROUTING_SCHEME_ONAIR 2
#define PVR2_DIGITAL_SCHEME_NONE 0
#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
@@ -66,6 +95,9 @@ struct pvr2_device_desc {
/* List of additional client modules we need to load */
struct pvr2_string_table client_modules;
+ /* List of defined client modules we need to load */
+ struct pvr2_device_client_table client_table;
+
/* List of FX2 firmware file names we should search; if empty then
FX2 firmware check / load is skipped and we assume the device
was initialized from internal ROM. */
@@ -73,7 +105,7 @@ struct pvr2_device_desc {
#ifdef CONFIG_VIDEO_PVRUSB2_DVB
/* callback functions to handle attachment of digital tuner & demod */
- struct pvr2_dvb_props *dvb_props;
+ const struct pvr2_dvb_props *dvb_props;
#endif
/* Initial standard bits to use for this device, if not zero.
diff --git a/drivers/media/video/pvrusb2/pvrusb2-dvb.c b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
index 77b3c338506..b7f5c49b1db 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-dvb.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-dvb.c
@@ -321,7 +321,7 @@ static int pvr2_dvb_adapter_exit(struct pvr2_dvb_adapter *adap)
static int pvr2_dvb_frontend_init(struct pvr2_dvb_adapter *adap)
{
struct pvr2_hdw *hdw = adap->channel.hdw;
- struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
+ const struct pvr2_dvb_props *dvb_props = hdw->hdw_desc->dvb_props;
int ret = 0;
if (dvb_props == NULL) {
diff --git a/drivers/media/video/pvrusb2/pvrusb2-encoder.c b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
index 273d2a1aa22..54ac5349dee 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-encoder.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-encoder.c
@@ -347,7 +347,7 @@ static int pvr2_encoder_prep_config(struct pvr2_hdw *hdw)
int encMisc3Arg = 0;
#if 0
- /* This inexplicable bit happens in the Hauppage windows
+ /* This inexplicable bit happens in the Hauppauge windows
driver (for both 24xxx and 29xxx devices). However I
currently see no difference in behavior with or without
this stuff. Leave this here as a note of its existence,
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index de7ee7264be..5d75eb5211b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -38,6 +38,7 @@
#include <linux/mutex.h>
#include "pvrusb2-hdw.h"
#include "pvrusb2-io.h"
+#include <media/v4l2-device.h>
#include <media/cx2341x.h>
#include "pvrusb2-devattr.h"
@@ -57,8 +58,6 @@
#define LOCK_TAKE(x) do { mutex_lock(&x##_mutex); x##_held = !0; } while (0)
#define LOCK_GIVE(x) do { x##_held = 0; mutex_unlock(&x##_mutex); } while (0)
-struct pvr2_decoder;
-
typedef int (*pvr2_ctlf_is_dirty)(struct pvr2_ctrl *);
typedef void (*pvr2_ctlf_clear_dirty)(struct pvr2_ctrl *);
typedef int (*pvr2_ctlf_check_value)(struct pvr2_ctrl *,int);
@@ -139,22 +138,6 @@ struct pvr2_ctrl {
};
-struct pvr2_decoder_ctrl {
- void *ctxt;
- void (*detach)(void *);
- void (*enable)(void *,int);
- void (*force_reset)(void *);
-};
-
-#define PVR2_I2C_PEND_DETECT 0x01 /* Need to detect a client type */
-#define PVR2_I2C_PEND_CLIENT 0x02 /* Client needs a specific update */
-#define PVR2_I2C_PEND_REFRESH 0x04 /* Client has specific pending bits */
-#define PVR2_I2C_PEND_STALE 0x08 /* Broadcast pending bits */
-
-#define PVR2_I2C_PEND_ALL (PVR2_I2C_PEND_DETECT |\
- PVR2_I2C_PEND_CLIENT |\
- PVR2_I2C_PEND_REFRESH |\
- PVR2_I2C_PEND_STALE)
/* Disposition of firmware1 loading situation */
#define FW1_STATE_UNKNOWN 0
@@ -179,6 +162,8 @@ struct pvr2_hdw {
struct usb_device *usb_dev;
struct usb_interface *usb_intf;
+ /* Our handle into the v4l2 sub-device architecture */
+ struct v4l2_device v4l2_dev;
/* Device description, anything that must adjust behavior based on
device specific info will use information held here. */
const struct pvr2_device_desc *hdw_desc;
@@ -186,7 +171,6 @@ struct pvr2_hdw {
/* Kernel worker thread handling */
struct workqueue_struct *workqueue;
struct work_struct workpoll; /* Update driver state */
- struct work_struct worki2csync; /* Update i2c clients */
/* Video spigot */
struct pvr2_stream *vid_stream;
@@ -195,20 +179,26 @@ struct pvr2_hdw {
struct mutex big_lock_mutex;
int big_lock_held; /* For debugging */
+ /* This is a simple string which identifies the instance of this
+ driver. It is unique within the set of existing devices, but
+ there is no attempt to keep the name consistent with the same
+ physical device each time. */
char name[32];
+ /* This is a simple string which identifies the physical device
+ instance itself - if possible. (If not possible, then it is
+ based on the specific driver instance, similar to name above.)
+ The idea here is that userspace might hopefully be able to use
+ this recognize specific tuners. It will encode a serial number,
+ if available. */
+ char identifier[32];
+
/* I2C stuff */
struct i2c_adapter i2c_adap;
struct i2c_algorithm i2c_algo;
pvr2_i2c_func i2c_func[PVR2_I2C_FUNC_CNT];
int i2c_cx25840_hack_state;
int i2c_linked;
- unsigned int i2c_pend_types; /* Which types of update are needed */
- unsigned long i2c_pend_mask; /* Change bits we need to scan */
- unsigned long i2c_stale_mask; /* Pending broadcast change bits */
- unsigned long i2c_active_mask; /* All change bits currently in use */
- struct list_head i2c_clients;
- struct mutex i2c_list_lock;
/* Frequency table */
unsigned int freqTable[FREQTABLE_SIZE];
@@ -275,6 +265,7 @@ struct pvr2_hdw {
wait_queue_head_t state_wait_data;
+ int force_dirty; /* consider all controls dirty if true */
int flag_ok; /* device in known good state */
int flag_disconnected; /* flag_ok == 0 due to disconnect */
int flag_init_ok; /* true if structure is fully initialized */
@@ -283,17 +274,13 @@ struct pvr2_hdw {
int flag_decoder_missed;/* We've noticed missing decoder */
int flag_tripped; /* Indicates overall failure to start */
- struct pvr2_decoder_ctrl *decoder_ctrl;
+ unsigned int decoder_client_id;
// CPU firmware info (used to help find / save firmware data)
char *fw_buffer;
unsigned int fw_size;
int fw_cpu_flag; /* True if we are dealing with the CPU */
- // True if there is a request to trigger logging of state in each
- // module.
- int log_requested;
-
/* Tuner / frequency control stuff */
unsigned int tuner_type;
int tuner_updated;
@@ -391,7 +378,8 @@ struct pvr2_hdw {
/* This function gets the current frequency */
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *);
-void pvr2_hdw_set_decoder(struct pvr2_hdw *,struct pvr2_decoder_ctrl *);
+
+void pvr2_hdw_status_poll(struct pvr2_hdw *);
#endif /* __PVRUSB2_HDW_INTERNAL_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index fa304e5f252..7a65b42a4f5 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -24,17 +24,22 @@
#include <linux/firmware.h>
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+#include <media/tuner.h>
#include "pvrusb2.h"
#include "pvrusb2-std.h"
#include "pvrusb2-util.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-tuner.h"
#include "pvrusb2-eeprom.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-encoder.h"
#include "pvrusb2-debug.h"
#include "pvrusb2-fx2-cmd.h"
+#include "pvrusb2-wm8775.h"
+#include "pvrusb2-video-v4l.h"
+#include "pvrusb2-cx2584x-v4l.h"
+#include "pvrusb2-cs53l32a.h"
+#include "pvrusb2-audio.h"
#define TV_MIN_FREQ 55250000L
#define TV_MAX_FREQ 850000000L
@@ -104,6 +109,39 @@ MODULE_PARM_DESC(radio_freq, "specify initial radio frequency");
/* size of a firmware chunk */
#define FIRMWARE_CHUNK_SIZE 0x2000
+typedef void (*pvr2_subdev_update_func)(struct pvr2_hdw *,
+ struct v4l2_subdev *);
+
+static const pvr2_subdev_update_func pvr2_module_update_functions[] = {
+ [PVR2_CLIENT_ID_WM8775] = pvr2_wm8775_subdev_update,
+ [PVR2_CLIENT_ID_SAA7115] = pvr2_saa7115_subdev_update,
+ [PVR2_CLIENT_ID_MSP3400] = pvr2_msp3400_subdev_update,
+ [PVR2_CLIENT_ID_CX25840] = pvr2_cx25840_subdev_update,
+ [PVR2_CLIENT_ID_CS53L32A] = pvr2_cs53l32a_subdev_update,
+};
+
+static const char *module_names[] = {
+ [PVR2_CLIENT_ID_MSP3400] = "msp3400",
+ [PVR2_CLIENT_ID_CX25840] = "cx25840",
+ [PVR2_CLIENT_ID_SAA7115] = "saa7115",
+ [PVR2_CLIENT_ID_TUNER] = "tuner",
+ [PVR2_CLIENT_ID_DEMOD] = "tuner",
+ [PVR2_CLIENT_ID_CS53L32A] = "cs53l32a",
+ [PVR2_CLIENT_ID_WM8775] = "wm8775",
+};
+
+
+static const unsigned char *module_i2c_addresses[] = {
+ [PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63",
+ [PVR2_CLIENT_ID_DEMOD] = "\x43",
+ [PVR2_CLIENT_ID_MSP3400] = "\x40",
+ [PVR2_CLIENT_ID_SAA7115] = "\x21",
+ [PVR2_CLIENT_ID_WM8775] = "\x1b",
+ [PVR2_CLIENT_ID_CX25840] = "\x44",
+ [PVR2_CLIENT_ID_CS53L32A] = "\x11",
+};
+
+
/* Define the list of additional controls we'll dynamically construct based
on query of the cx2341x module. */
struct pvr2_mpeg_ids {
@@ -277,7 +315,6 @@ static int pvr2_hdw_set_input(struct pvr2_hdw *hdw,int v);
static void pvr2_hdw_state_sched(struct pvr2_hdw *);
static int pvr2_hdw_state_eval(struct pvr2_hdw *);
static void pvr2_hdw_set_cur_freq(struct pvr2_hdw *,unsigned long);
-static void pvr2_hdw_worker_i2c(struct work_struct *work);
static void pvr2_hdw_worker_poll(struct work_struct *work);
static int pvr2_hdw_wait(struct pvr2_hdw *,int state);
static int pvr2_hdw_untrip_unlocked(struct pvr2_hdw *);
@@ -642,7 +679,7 @@ static int ctrl_freq_max_get(struct pvr2_ctrl *cptr, int *vp)
unsigned long fv;
struct pvr2_hdw *hdw = cptr->hdw;
if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
}
fv = hdw->tuner_signal_info.rangehigh;
if (!fv) {
@@ -664,7 +701,7 @@ static int ctrl_freq_min_get(struct pvr2_ctrl *cptr, int *vp)
unsigned long fv;
struct pvr2_hdw *hdw = cptr->hdw;
if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
}
fv = hdw->tuner_signal_info.rangelow;
if (!fv) {
@@ -858,7 +895,7 @@ static void ctrl_stdcur_clear_dirty(struct pvr2_ctrl *cptr)
static int ctrl_signal_get(struct pvr2_ctrl *cptr,int *vp)
{
struct pvr2_hdw *hdw = cptr->hdw;
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
*vp = hdw->tuner_signal_info.signal;
return 0;
}
@@ -868,7 +905,7 @@ static int ctrl_audio_modes_present_get(struct pvr2_ctrl *cptr,int *vp)
int val = 0;
unsigned int subchan;
struct pvr2_hdw *hdw = cptr->hdw;
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
subchan = hdw->tuner_signal_info.rxsubchans;
if (subchan & V4L2_TUNER_SUB_MONO) {
val |= (1 << V4L2_TUNER_MODE_MONO);
@@ -1283,6 +1320,12 @@ const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *hdw)
}
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *hdw)
+{
+ return hdw->identifier;
+}
+
+
unsigned long pvr2_hdw_get_cur_freq(struct pvr2_hdw *hdw)
{
return hdw->freqSelector ? hdw->freqValTelevision : hdw->freqValRadio;
@@ -1634,33 +1677,27 @@ static const char *pvr2_get_state_name(unsigned int st)
static int pvr2_decoder_enable(struct pvr2_hdw *hdw,int enablefl)
{
- if (!hdw->decoder_ctrl) {
- if (!hdw->flag_decoder_missed) {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "WARNING: No decoder present");
- hdw->flag_decoder_missed = !0;
- trace_stbit("flag_decoder_missed",
- hdw->flag_decoder_missed);
- }
- return -EIO;
+ /* Even though we really only care about the video decoder chip at
+ this point, we'll broadcast stream on/off to all sub-devices
+ anyway, just in case somebody else wants to hear the
+ command... */
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 stream=%s",
+ (enablefl ? "on" : "off"));
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_stream, enablefl);
+ if (hdw->decoder_client_id) {
+ /* We get here if the encoder has been noticed. Otherwise
+ we'll issue a warning to the user (which should
+ normally never happen). */
+ return 0;
}
- hdw->decoder_ctrl->enable(hdw->decoder_ctrl->ctxt,enablefl);
- return 0;
-}
-
-
-void pvr2_hdw_set_decoder(struct pvr2_hdw *hdw,struct pvr2_decoder_ctrl *ptr)
-{
- if (hdw->decoder_ctrl == ptr) return;
- hdw->decoder_ctrl = ptr;
- if (hdw->decoder_ctrl && hdw->flag_decoder_missed) {
- hdw->flag_decoder_missed = 0;
+ if (!hdw->flag_decoder_missed) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "WARNING: No decoder present");
+ hdw->flag_decoder_missed = !0;
trace_stbit("flag_decoder_missed",
hdw->flag_decoder_missed);
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "Decoder has appeared");
- pvr2_hdw_state_sched(hdw);
}
+ return -EIO;
}
@@ -1927,6 +1964,166 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
}
+static unsigned int pvr2_copy_i2c_addr_list(
+ unsigned short *dst, const unsigned char *src,
+ unsigned int dst_max)
+{
+ unsigned int cnt = 0;
+ if (!src) return 0;
+ while (src[cnt] && (cnt + 1) < dst_max) {
+ dst[cnt] = src[cnt];
+ cnt++;
+ }
+ dst[cnt] = I2C_CLIENT_END;
+ return cnt;
+}
+
+
+static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
+ const struct pvr2_device_client_desc *cd)
+{
+ const char *fname;
+ unsigned char mid;
+ struct v4l2_subdev *sd;
+ unsigned int i2ccnt;
+ const unsigned char *p;
+ /* Arbitrary count - max # i2c addresses we will probe */
+ unsigned short i2caddr[25];
+
+ mid = cd->module_id;
+ fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
+ if (!fname) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Module ID %u for device %s has no name",
+ mid,
+ hdw->hdw_desc->description);
+ return -EINVAL;
+ }
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u (%s) for device %s being loaded...",
+ mid, fname,
+ hdw->hdw_desc->description);
+
+ i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
+ ARRAY_SIZE(i2caddr));
+ if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ?
+ module_i2c_addresses[mid] : NULL) != NULL)) {
+ /* Second chance: Try default i2c address list */
+ i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p,
+ ARRAY_SIZE(i2caddr));
+ if (i2ccnt) {
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Using default i2c address list",
+ mid);
+ }
+ }
+
+ if (!i2ccnt) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Module ID %u (%s) for device %s:"
+ " No i2c addresses",
+ mid, fname, hdw->hdw_desc->description);
+ return -EINVAL;
+ }
+
+ /* Note how the 2nd and 3rd arguments are the same for both
+ * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev(). Why?
+ * Well the 2nd argument is the module name to load, while the 3rd
+ * argument is documented in the framework as being the "chipid" -
+ * and every other place where I can find examples of this, the
+ * "chipid" appears to just be the module name again. So here we
+ * just do the same thing. */
+ if (i2ccnt == 1) {
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Setting up with specified i2c address 0x%x",
+ mid, i2caddr[0]);
+ sd = v4l2_i2c_new_subdev(&hdw->i2c_adap,
+ fname, fname,
+ i2caddr[0]);
+ } else {
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Setting up with address probe list",
+ mid);
+ sd = v4l2_i2c_new_probed_subdev(&hdw->i2c_adap,
+ fname, fname,
+ i2caddr);
+ }
+
+ if (!sd) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Module ID %u (%s) for device %s failed to load",
+ mid, fname, hdw->hdw_desc->description);
+ return -EIO;
+ }
+
+ /* Tag this sub-device instance with the module ID we know about.
+ In other places we'll use that tag to determine if the instance
+ requires special handling. */
+ sd->grp_id = mid;
+
+ pvr2_trace(PVR2_TRACE_INFO, "Attached sub-driver %s", fname);
+
+
+ /* client-specific setup... */
+ switch (mid) {
+ case PVR2_CLIENT_ID_CX25840:
+ hdw->decoder_client_id = mid;
+ {
+ /*
+ Mike Isely <isely@pobox.com> 19-Nov-2006 - This
+ bit of nuttiness for cx25840 causes that module
+ to correctly set up its video scaling. This is
+ really a problem in the cx25840 module itself,
+ but we work around it here. The problem has not
+ been seen in ivtv because there VBI is supported
+ and set up. We don't do VBI here (at least not
+ yet) and thus we never attempted to even set it
+ up.
+ */
+ struct v4l2_format fmt;
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Module ID %u:"
+ " Executing cx25840 VBI hack",
+ mid);
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ v4l2_device_call_all(&hdw->v4l2_dev, mid,
+ video, s_fmt, &fmt);
+ }
+ break;
+ case PVR2_CLIENT_ID_SAA7115:
+ hdw->decoder_client_id = mid;
+ break;
+ default: break;
+ }
+
+ return 0;
+}
+
+
+static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
+{
+ unsigned int idx;
+ const struct pvr2_string_table *cm;
+ const struct pvr2_device_client_table *ct;
+ int okFl = !0;
+
+ cm = &hdw->hdw_desc->client_modules;
+ for (idx = 0; idx < cm->cnt; idx++) {
+ request_module(cm->lst[idx]);
+ }
+
+ ct = &hdw->hdw_desc->client_table;
+ for (idx = 0; idx < ct->cnt; idx++) {
+ if (pvr2_hdw_load_subdev(hdw, &ct->lst[idx]) < 0) okFl = 0;
+ }
+ if (!okFl) pvr2_hdw_render_useless(hdw);
+}
+
+
static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
{
int ret;
@@ -1966,9 +2163,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
if (!pvr2_hdw_dev_ok(hdw)) return;
- for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
- request_module(hdw->hdw_desc->client_modules.lst[idx]);
- }
+ hdw->force_dirty = !0;
if (!hdw->hdw_desc->flag_no_powerup) {
pvr2_hdw_cmd_powerup(hdw);
@@ -1987,6 +2182,11 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
pvr2_i2c_core_init(hdw);
if (!pvr2_hdw_dev_ok(hdw)) return;
+ pvr2_hdw_load_modules(hdw);
+ if (!pvr2_hdw_dev_ok(hdw)) return;
+
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, init, 0);
+
for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
cptr = hdw->controls + idx;
if (cptr->info->skip_init) continue;
@@ -2024,6 +2224,19 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
hdw->std_mask_eeprom = V4L2_STD_ALL;
}
+ if (hdw->serial_number) {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "sn-%lu", hdw->serial_number);
+ } else if (hdw->unit_number >= 0) {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "unit-%c",
+ hdw->unit_number + 'a');
+ } else {
+ idx = scnprintf(hdw->identifier, sizeof(hdw->identifier) - 1,
+ "unit-??");
+ }
+ hdw->identifier[idx] = 0;
+
pvr2_hdw_setup_std(hdw);
if (!get_default_tuner_type(hdw)) {
@@ -2032,8 +2245,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
hdw->tuner_type);
}
- pvr2_i2c_core_check_stale(hdw);
- hdw->tuner_updated = 0;
if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -2171,11 +2382,14 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
struct pvr2_hdw *hdw = NULL;
int valid_std_mask;
struct pvr2_ctrl *cptr;
+ struct usb_device *usb_dev;
const struct pvr2_device_desc *hdw_desc;
__u8 ifnum;
struct v4l2_queryctrl qctrl;
struct pvr2_ctl_info *ciptr;
+ usb_dev = interface_to_usbdev(intf);
+
hdw_desc = (const struct pvr2_device_desc *)(devid->driver_info);
if (hdw_desc == NULL) {
@@ -2360,6 +2574,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->ctl_read_urb = usb_alloc_urb(0,GFP_KERNEL);
if (!hdw->ctl_read_urb) goto fail;
+ if (v4l2_device_register(&usb_dev->dev, &hdw->v4l2_dev) != 0) {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "Error registering with v4l core, giving up");
+ goto fail;
+ }
mutex_lock(&pvr2_unit_mtx); do {
for (idx = 0; idx < PVR_NUM; idx++) {
if (unit_pointers[idx]) continue;
@@ -2382,7 +2601,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->workqueue = create_singlethread_workqueue(hdw->name);
INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll);
- INIT_WORK(&hdw->worki2csync,pvr2_hdw_worker_i2c);
pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s",
hdw->unit_number,hdw->name);
@@ -2391,12 +2609,9 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
hdw->flag_ok = !0;
hdw->usb_intf = intf;
- hdw->usb_dev = interface_to_usbdev(intf);
+ hdw->usb_dev = usb_dev;
- scnprintf(hdw->bus_info,sizeof(hdw->bus_info),
- "usb %s address %d",
- dev_name(&hdw->usb_dev->dev),
- hdw->usb_dev->devnum);
+ usb_make_path(hdw->usb_dev, hdw->bus_info, sizeof(hdw->bus_info));
ifnum = hdw->usb_intf->cur_altsetting->desc.bInterfaceNumber;
usb_set_interface(hdw->usb_dev,ifnum,0);
@@ -2454,6 +2669,10 @@ static void pvr2_hdw_remove_usb_stuff(struct pvr2_hdw *hdw)
hdw->ctl_write_buffer = NULL;
}
hdw->flag_disconnected = !0;
+ /* If we don't do this, then there will be a dangling struct device
+ reference to our disappearing device persisting inside the V4L
+ core... */
+ v4l2_device_disconnect(&hdw->v4l2_dev);
hdw->usb_dev = NULL;
hdw->usb_intf = NULL;
pvr2_hdw_render_useless(hdw);
@@ -2481,10 +2700,8 @@ void pvr2_hdw_destroy(struct pvr2_hdw *hdw)
pvr2_stream_destroy(hdw->vid_stream);
hdw->vid_stream = NULL;
}
- if (hdw->decoder_ctrl) {
- hdw->decoder_ctrl->detach(hdw->decoder_ctrl->ctxt);
- }
pvr2_i2c_core_done(hdw);
+ v4l2_device_unregister(&hdw->v4l2_dev);
pvr2_hdw_remove_usb_stuff(hdw);
mutex_lock(&pvr2_unit_mtx); do {
if ((hdw->unit_number >= 0) &&
@@ -2678,6 +2895,150 @@ static const char *get_ctrl_typename(enum pvr2_ctl_type tp)
}
+static void pvr2_subdev_set_control(struct pvr2_hdw *hdw, int id,
+ const char *name, int val)
+{
+ struct v4l2_control ctrl;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 %s=%d", name, val);
+ memset(&ctrl, 0, sizeof(ctrl));
+ ctrl.id = id;
+ ctrl.value = val;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, s_ctrl, &ctrl);
+}
+
+#define PVR2_SUBDEV_SET_CONTROL(hdw, id, lab) \
+ if ((hdw)->lab##_dirty || (hdw)->force_dirty) { \
+ pvr2_subdev_set_control(hdw, id, #lab, (hdw)->lab##_val); \
+ }
+
+/* Execute whatever commands are required to update the state of all the
+ sub-devices so that they match our current control values. */
+static void pvr2_subdev_update(struct pvr2_hdw *hdw)
+{
+ struct v4l2_subdev *sd;
+ unsigned int id;
+ pvr2_subdev_update_func fp;
+
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev update...");
+
+ if (hdw->tuner_updated || hdw->force_dirty) {
+ struct tuner_setup setup;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
+ hdw->tuner_type);
+ if (((int)(hdw->tuner_type)) >= 0) {
+ setup.addr = ADDR_UNSET;
+ setup.type = hdw->tuner_type;
+ setup.mode_mask = T_RADIO | T_ANALOG_TV;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ tuner, s_type_addr, &setup);
+ }
+ }
+
+ if (hdw->input_dirty || hdw->std_dirty || hdw->force_dirty) {
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_standard");
+ if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ tuner, s_radio);
+ } else {
+ v4l2_std_id vs;
+ vs = hdw->std_mask_cur;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ tuner, s_std, vs);
+ }
+ hdw->tuner_signal_stale = !0;
+ hdw->cropcap_stale = !0;
+ }
+
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_BRIGHTNESS, brightness);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_CONTRAST, contrast);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_SATURATION, saturation);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_HUE, hue);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_MUTE, mute);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_VOLUME, volume);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BALANCE, balance);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_BASS, bass);
+ PVR2_SUBDEV_SET_CONTROL(hdw, V4L2_CID_AUDIO_TREBLE, treble);
+
+ if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) {
+ struct v4l2_tuner vt;
+ memset(&vt, 0, sizeof(vt));
+ vt.audmode = hdw->audiomode_val;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt);
+ }
+
+ if (hdw->freqDirty || hdw->force_dirty) {
+ unsigned long fv;
+ struct v4l2_frequency freq;
+ fv = pvr2_hdw_get_cur_freq(hdw);
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_freq(%lu)", fv);
+ if (hdw->tuner_signal_stale) pvr2_hdw_status_poll(hdw);
+ memset(&freq, 0, sizeof(freq));
+ if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
+ /* ((fv * 1000) / 62500) */
+ freq.frequency = (fv * 2) / 125;
+ } else {
+ freq.frequency = fv / 62500;
+ }
+ /* tuner-core currently doesn't seem to care about this, but
+ let's set it anyway for completeness. */
+ if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
+ freq.type = V4L2_TUNER_RADIO;
+ } else {
+ freq.type = V4L2_TUNER_ANALOG_TV;
+ }
+ freq.tuner = 0;
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner,
+ s_frequency, &freq);
+ }
+
+ if (hdw->res_hor_dirty || hdw->res_ver_dirty || hdw->force_dirty) {
+ struct v4l2_format fmt;
+ memset(&fmt, 0, sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ fmt.fmt.pix.width = hdw->res_hor_val;
+ fmt.fmt.pix.height = hdw->res_ver_val;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_size(%dx%d)",
+ fmt.fmt.pix.width, fmt.fmt.pix.height);
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, video, s_fmt, &fmt);
+ }
+
+ if (hdw->srate_dirty || hdw->force_dirty) {
+ u32 val;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_audio %d",
+ hdw->srate_val);
+ switch (hdw->srate_val) {
+ default:
+ case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
+ val = 48000;
+ break;
+ case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
+ val = 44100;
+ break;
+ case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
+ val = 32000;
+ break;
+ }
+ v4l2_device_call_all(&hdw->v4l2_dev, 0,
+ audio, s_clock_freq, val);
+ }
+
+ /* Unable to set crop parameters; there is apparently no equivalent
+ for VIDIOC_S_CROP */
+
+ v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+ id = sd->grp_id;
+ if (id >= ARRAY_SIZE(pvr2_module_update_functions)) continue;
+ fp = pvr2_module_update_functions[id];
+ if (!fp) continue;
+ (*fp)(hdw, sd);
+ }
+
+ if (hdw->tuner_signal_stale || hdw->cropcap_stale) {
+ pvr2_hdw_status_poll(hdw);
+ }
+}
+
+
/* Figure out if we need to commit control changes. If so, mark internal
state flags to indicate this fact and return true. Otherwise do nothing
else and return false. */
@@ -2686,7 +3047,7 @@ static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
unsigned int idx;
struct pvr2_ctrl *cptr;
int value;
- int commit_flag = 0;
+ int commit_flag = hdw->force_dirty;
char buf[100];
unsigned int bcnt,ccnt;
@@ -2842,18 +3203,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
cx2341x_ext_ctrls(&hdw->enc_ctl_state, 0, &cs,VIDIOC_S_EXT_CTRLS);
}
- /* Scan i2c core at this point - before we clear all the dirty
- bits. Various parts of the i2c core will notice dirty bits as
- appropriate and arrange to broadcast or directly send updates to
- the client drivers in order to keep everything in sync */
- pvr2_i2c_core_check_stale(hdw);
-
- for (idx = 0; idx < hdw->control_cnt; idx++) {
- cptr = hdw->controls + idx;
- if (!cptr->info->clear_dirty) continue;
- cptr->info->clear_dirty(cptr);
- }
-
if (hdw->active_stream_type != hdw->desired_stream_type) {
/* Handle any side effects of stream config here */
hdw->active_stream_type = hdw->desired_stream_type;
@@ -2873,8 +3222,16 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
}
}
- /* Now execute i2c core update */
- pvr2_i2c_core_sync(hdw);
+ /* Check and update state for all sub-devices. */
+ pvr2_subdev_update(hdw);
+
+ hdw->tuner_updated = 0;
+ hdw->force_dirty = 0;
+ for (idx = 0; idx < hdw->control_cnt; idx++) {
+ cptr = hdw->controls + idx;
+ if (!cptr->info->clear_dirty) continue;
+ cptr->info->clear_dirty(cptr);
+ }
if ((hdw->pathway_state == PVR2_PATHWAY_ANALOG) &&
hdw->state_encoder_run) {
@@ -2904,15 +3261,6 @@ int pvr2_hdw_commit_ctl(struct pvr2_hdw *hdw)
}
-static void pvr2_hdw_worker_i2c(struct work_struct *work)
-{
- struct pvr2_hdw *hdw = container_of(work,struct pvr2_hdw,worki2csync);
- LOCK_TAKE(hdw->big_lock); do {
- pvr2_i2c_core_sync(hdw);
- } while (0); LOCK_GIVE(hdw->big_lock);
-}
-
-
static void pvr2_hdw_worker_poll(struct work_struct *work)
{
int fl = 0;
@@ -2973,7 +3321,7 @@ int pvr2_hdw_is_hsm(struct pvr2_hdw *hdw)
void pvr2_hdw_execute_tuner_poll(struct pvr2_hdw *hdw)
{
LOCK_TAKE(hdw->big_lock); do {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
} while (0); LOCK_GIVE(hdw->big_lock);
}
@@ -2983,7 +3331,7 @@ static int pvr2_hdw_check_cropcap(struct pvr2_hdw *hdw)
if (!hdw->cropcap_stale) {
return 0;
}
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
if (hdw->cropcap_stale) {
return -EIO;
}
@@ -3010,7 +3358,7 @@ int pvr2_hdw_get_tuner_status(struct pvr2_hdw *hdw,struct v4l2_tuner *vtp)
{
LOCK_TAKE(hdw->big_lock); do {
if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
+ pvr2_hdw_status_poll(hdw);
}
memcpy(vtp,&hdw->tuner_signal_info,sizeof(struct v4l2_tuner));
} while (0); LOCK_GIVE(hdw->big_lock);
@@ -3029,11 +3377,8 @@ void pvr2_hdw_trigger_module_log(struct pvr2_hdw *hdw)
{
int nr = pvr2_hdw_get_unit_number(hdw);
LOCK_TAKE(hdw->big_lock); do {
- hdw->log_requested = !0;
printk(KERN_INFO "pvrusb2: ================= START STATUS CARD #%d =================\n", nr);
- pvr2_i2c_core_check_stale(hdw);
- hdw->log_requested = 0;
- pvr2_i2c_core_sync(hdw);
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, log_status);
pvr2_trace(PVR2_TRACE_INFO,"cx2341x config:");
cx2341x_log_status(&hdw->enc_ctl_state, "pvrusb2");
pvr2_hdw_state_log_state(hdw);
@@ -3716,22 +4061,16 @@ int pvr2_hdw_cmd_powerdown(struct pvr2_hdw *hdw)
int pvr2_hdw_cmd_decoder_reset(struct pvr2_hdw *hdw)
{
- if (!hdw->decoder_ctrl) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Unable to reset decoder: nothing attached");
- return -ENOTTY;
- }
-
- if (!hdw->decoder_ctrl->force_reset) {
- pvr2_trace(PVR2_TRACE_INIT,
- "Unable to reset decoder: not implemented");
- return -ENOTTY;
- }
-
pvr2_trace(PVR2_TRACE_INIT,
"Requesting decoder reset");
- hdw->decoder_ctrl->force_reset(hdw->decoder_ctrl->ctxt);
- return 0;
+ if (hdw->decoder_client_id) {
+ v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
+ core, reset, 0);
+ return 0;
+ }
+ pvr2_trace(PVR2_TRACE_INIT,
+ "Unable to reset decoder: nothing attached");
+ return -ENOTTY;
}
@@ -4476,6 +4815,79 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
}
+/* Generate report containing info about attached sub-devices and attached
+ i2c clients, including an indication of which attached i2c clients are
+ actually sub-devices. */
+static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
+ char *buf, unsigned int acnt)
+{
+ struct v4l2_subdev *sd;
+ unsigned int tcnt = 0;
+ unsigned int ccnt;
+ struct i2c_client *client;
+ struct list_head *item;
+ void *cd;
+ const char *p;
+ unsigned int id;
+
+ ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:");
+ tcnt += ccnt;
+ v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+ id = sd->grp_id;
+ p = NULL;
+ if (id < ARRAY_SIZE(module_names)) p = module_names[id];
+ if (p) {
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p);
+ tcnt += ccnt;
+ } else {
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+ " (unknown id=%u)", id);
+ tcnt += ccnt;
+ }
+ }
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
+ tcnt += ccnt;
+
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n");
+ tcnt += ccnt;
+
+ mutex_lock(&hdw->i2c_adap.clist_lock);
+ list_for_each(item, &hdw->i2c_adap.clients) {
+ client = list_entry(item, struct i2c_client, list);
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+ " %s: i2c=%02x", client->name, client->addr);
+ tcnt += ccnt;
+ cd = i2c_get_clientdata(client);
+ v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
+ if (cd == sd) {
+ id = sd->grp_id;
+ p = NULL;
+ if (id < ARRAY_SIZE(module_names)) {
+ p = module_names[id];
+ }
+ if (p) {
+ ccnt = scnprintf(buf + tcnt,
+ acnt - tcnt,
+ " subdev=%s", p);
+ tcnt += ccnt;
+ } else {
+ ccnt = scnprintf(buf + tcnt,
+ acnt - tcnt,
+ " subdev= id %u)",
+ id);
+ tcnt += ccnt;
+ }
+ break;
+ }
+ }
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
+ tcnt += ccnt;
+ }
+ mutex_unlock(&hdw->i2c_adap.clist_lock);
+ return tcnt;
+}
+
+
unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
char *buf,unsigned int acnt)
{
@@ -4490,6 +4902,8 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
buf[0] = '\n'; ccnt = 1;
bcnt += ccnt; acnt -= ccnt; buf += ccnt;
}
+ ccnt = pvr2_hdw_report_clients(hdw, buf, acnt);
+ bcnt += ccnt; acnt -= ccnt; buf += ccnt;
LOCK_GIVE(hdw->big_lock);
return bcnt;
}
@@ -4497,14 +4911,25 @@ unsigned int pvr2_hdw_state_report(struct pvr2_hdw *hdw,
static void pvr2_hdw_state_log_state(struct pvr2_hdw *hdw)
{
- char buf[128];
- unsigned int idx,ccnt;
+ char buf[256];
+ unsigned int idx, ccnt;
+ unsigned int lcnt, ucnt;
for (idx = 0; ; idx++) {
ccnt = pvr2_hdw_report_unlocked(hdw,idx,buf,sizeof(buf));
if (!ccnt) break;
printk(KERN_INFO "%s %.*s\n",hdw->name,ccnt,buf);
}
+ ccnt = pvr2_hdw_report_clients(hdw, buf, sizeof(buf));
+ ucnt = 0;
+ while (ucnt < ccnt) {
+ lcnt = 0;
+ while ((lcnt + ucnt < ccnt) && (buf[lcnt + ucnt] != '\n')) {
+ lcnt++;
+ }
+ printk(KERN_INFO "%s %.*s\n", hdw->name, lcnt, buf + ucnt);
+ ucnt += lcnt + 1;
+ }
}
@@ -4641,6 +5066,30 @@ int pvr2_hdw_gpio_chg_out(struct pvr2_hdw *hdw,u32 msk,u32 val)
}
+void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
+{
+ struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
+ memset(vtp, 0, sizeof(*vtp));
+ hdw->tuner_signal_stale = 0;
+ /* Note: There apparently is no replacement for VIDIOC_CROPCAP
+ using v4l2-subdev - therefore we can't support that AT ALL right
+ now. (Of course, no sub-drivers seem to implement it either.
+ But now it's a a chicken and egg problem...) */
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner,
+ &hdw->tuner_signal_info);
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll"
+ " type=%u strength=%u audio=0x%x cap=0x%x"
+ " low=%u hi=%u",
+ vtp->type,
+ vtp->signal, vtp->rxsubchans, vtp->capability,
+ vtp->rangelow, vtp->rangehigh);
+
+ /* We have to do this to avoid getting into constant polling if
+ there's nobody to answer a poll of cropcap info. */
+ hdw->cropcap_stale = 0;
+}
+
+
unsigned int pvr2_hdw_get_input_available(struct pvr2_hdw *hdw)
{
return hdw->input_avail_mask;
@@ -4736,7 +5185,6 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
int setFl, u64 *val_ptr)
{
#ifdef CONFIG_VIDEO_ADV_DEBUG
- struct pvr2_i2c_client *cp;
struct v4l2_dbg_register req;
int stat = 0;
int okFl = 0;
@@ -4746,21 +5194,9 @@ int pvr2_hdw_register_access(struct pvr2_hdw *hdw,
req.match = *match;
req.reg = reg_id;
if (setFl) req.val = *val_ptr;
- mutex_lock(&hdw->i2c_list_lock); do {
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!v4l2_chip_match_i2c_client(
- cp->client,
- &req.match)) {
- continue;
- }
- stat = pvr2_i2c_client_cmd(
- cp,(setFl ? VIDIOC_DBG_S_REGISTER :
- VIDIOC_DBG_G_REGISTER),&req);
- if (!setFl) *val_ptr = req.val;
- okFl = !0;
- break;
- }
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
+ /* It would be nice to know if a sub-device answered the request */
+ v4l2_device_call_all(&hdw->v4l2_dev, 0, core, g_register, &req);
+ if (!setFl) *val_ptr = req.val;
if (okFl) {
return stat;
}
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.h b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
index 1b4fec337c6..7b6940554e9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.h
@@ -132,6 +132,9 @@ unsigned long pvr2_hdw_get_sn(struct pvr2_hdw *);
/* Retrieve bus location info of device */
const char *pvr2_hdw_get_bus_info(struct pvr2_hdw *);
+/* Retrieve per-instance string identifier for this specific device */
+const char *pvr2_hdw_get_device_identifier(struct pvr2_hdw *);
+
/* Called when hardware has been unplugged */
void pvr2_hdw_disconnect(struct pvr2_hdw *);
@@ -236,8 +239,7 @@ void pvr2_hdw_v4l_store_minor_number(struct pvr2_hdw *,
enum pvr2_v4l_type index,int);
/* Direct read/write access to chip's registers:
- match_type - how to interpret match_chip (e.g. driver ID, i2c address)
- match_chip - chip match value (e.g. I2C_DRIVERD_xxxx)
+ match - specify criteria to identify target chip (this is a v4l dbg struct)
reg_id - register number to access
setFl - true to set the register, false to read it
val_ptr - storage location for source / result. */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
deleted file mode 100644
index 94a47718e88..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-chips-v4l2.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-
-#include <linux/kernel.h>
-#include "pvrusb2-i2c-core.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
-#include "pvrusb2-audio.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-cx2584x-v4l.h"
-#include "pvrusb2-wm8775.h"
-
-#define trace_i2c(...) pvr2_trace(PVR2_TRACE_I2C,__VA_ARGS__)
-
-#define OP_STANDARD 0
-#define OP_AUDIOMODE 1
-#define OP_BCSH 2
-#define OP_VOLUME 3
-#define OP_FREQ 4
-#define OP_AUDIORATE 5
-#define OP_CROP 6
-#define OP_SIZE 7
-#define OP_LOG 8
-
-static const struct pvr2_i2c_op * const ops[] = {
- [OP_STANDARD] = &pvr2_i2c_op_v4l2_standard,
- [OP_AUDIOMODE] = &pvr2_i2c_op_v4l2_audiomode,
- [OP_BCSH] = &pvr2_i2c_op_v4l2_bcsh,
- [OP_VOLUME] = &pvr2_i2c_op_v4l2_volume,
- [OP_FREQ] = &pvr2_i2c_op_v4l2_frequency,
- [OP_CROP] = &pvr2_i2c_op_v4l2_crop,
- [OP_SIZE] = &pvr2_i2c_op_v4l2_size,
- [OP_LOG] = &pvr2_i2c_op_v4l2_log,
-};
-
-void pvr2_i2c_probe(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- int id;
- id = cp->client->driver->id;
- cp->ctl_mask = ((1 << OP_STANDARD) |
- (1 << OP_AUDIOMODE) |
- (1 << OP_BCSH) |
- (1 << OP_VOLUME) |
- (1 << OP_FREQ) |
- (1 << OP_CROP) |
- (1 << OP_SIZE) |
- (1 << OP_LOG));
- cp->status_poll = pvr2_v4l2_cmd_status_poll;
-
- if (id == I2C_DRIVERID_MSP3400) {
- if (pvr2_i2c_msp3400_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_TUNER) {
- if (pvr2_i2c_tuner_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_CX25840) {
- if (pvr2_i2c_cx2584x_v4l_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_WM8775) {
- if (pvr2_i2c_wm8775_setup(hdw,cp)) {
- return;
- }
- }
- if (id == I2C_DRIVERID_SAA711X) {
- if (pvr2_i2c_decoder_v4l_setup(hdw,cp)) {
- return;
- }
- }
-}
-
-
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx)
-{
- if (idx >= ARRAY_SIZE(ops))
- return NULL;
- return ops[idx];
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 75 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
deleted file mode 100644
index 16bb11902a5..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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 "pvrusb2-i2c-cmd-v4l2.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
-
-static void set_standard(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_standard");
-
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- pvr2_i2c_core_cmd(hdw,AUDC_SET_RADIO,NULL);
- } else {
- v4l2_std_id vs;
- vs = hdw->std_mask_cur;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_STD,&vs);
- }
- hdw->tuner_signal_stale = !0;
- hdw->cropcap_stale = !0;
-}
-
-
-static int check_standard(struct pvr2_hdw *hdw)
-{
- return (hdw->input_dirty != 0) || (hdw->std_dirty != 0);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard = {
- .check = check_standard,
- .update = set_standard,
- .name = "v4l2_standard",
-};
-
-
-static void set_bcsh(struct pvr2_hdw *hdw)
-{
- struct v4l2_control ctrl;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_bcsh"
- " b=%d c=%d s=%d h=%d",
- hdw->brightness_val,hdw->contrast_val,
- hdw->saturation_val,hdw->hue_val);
- memset(&ctrl,0,sizeof(ctrl));
- ctrl.id = V4L2_CID_BRIGHTNESS;
- ctrl.value = hdw->brightness_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_CONTRAST;
- ctrl.value = hdw->contrast_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_SATURATION;
- ctrl.value = hdw->saturation_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_HUE;
- ctrl.value = hdw->hue_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_bcsh(struct pvr2_hdw *hdw)
-{
- return (hdw->brightness_dirty ||
- hdw->contrast_dirty ||
- hdw->saturation_dirty ||
- hdw->hue_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh = {
- .check = check_bcsh,
- .update = set_bcsh,
- .name = "v4l2_bcsh",
-};
-
-
-static void set_volume(struct pvr2_hdw *hdw)
-{
- struct v4l2_control ctrl;
- pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_volume"
- "(vol=%d bal=%d bas=%d treb=%d mute=%d)",
- hdw->volume_val,
- hdw->balance_val,
- hdw->bass_val,
- hdw->treble_val,
- hdw->mute_val);
- memset(&ctrl,0,sizeof(ctrl));
- ctrl.id = V4L2_CID_AUDIO_MUTE;
- ctrl.value = hdw->mute_val ? 1 : 0;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_VOLUME;
- ctrl.value = hdw->volume_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_BALANCE;
- ctrl.value = hdw->balance_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_BASS;
- ctrl.value = hdw->bass_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
- ctrl.id = V4L2_CID_AUDIO_TREBLE;
- ctrl.value = hdw->treble_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_CTRL,&ctrl);
-}
-
-
-static int check_volume(struct pvr2_hdw *hdw)
-{
- return (hdw->volume_dirty ||
- hdw->balance_dirty ||
- hdw->bass_dirty ||
- hdw->treble_dirty ||
- hdw->mute_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume = {
- .check = check_volume,
- .update = set_volume,
- .name = "v4l2_volume",
-};
-
-
-static void set_audiomode(struct pvr2_hdw *hdw)
-{
- struct v4l2_tuner vt;
- memset(&vt,0,sizeof(vt));
- vt.audmode = hdw->audiomode_val;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_TUNER,&vt);
-}
-
-
-static int check_audiomode(struct pvr2_hdw *hdw)
-{
- return (hdw->input_dirty ||
- hdw->audiomode_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode = {
- .check = check_audiomode,
- .update = set_audiomode,
- .name = "v4l2_audiomode",
-};
-
-
-static void set_frequency(struct pvr2_hdw *hdw)
-{
- unsigned long fv;
- struct v4l2_frequency freq;
- fv = pvr2_hdw_get_cur_freq(hdw);
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_freq(%lu)",fv);
- if (hdw->tuner_signal_stale) {
- pvr2_i2c_core_status_poll(hdw);
- }
- memset(&freq,0,sizeof(freq));
- if (hdw->tuner_signal_info.capability & V4L2_TUNER_CAP_LOW) {
- // ((fv * 1000) / 62500)
- freq.frequency = (fv * 2) / 125;
- } else {
- freq.frequency = fv / 62500;
- }
- /* tuner-core currently doesn't seem to care about this, but
- let's set it anyway for completeness. */
- if (hdw->input_val == PVR2_CVAL_INPUT_RADIO) {
- freq.type = V4L2_TUNER_RADIO;
- } else {
- freq.type = V4L2_TUNER_ANALOG_TV;
- }
- freq.tuner = 0;
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
-}
-
-
-static int check_frequency(struct pvr2_hdw *hdw)
-{
- return hdw->freqDirty != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency = {
- .check = check_frequency,
- .update = set_frequency,
- .name = "v4l2_freq",
-};
-
-
-static void set_size(struct pvr2_hdw *hdw)
-{
- struct v4l2_format fmt;
-
- memset(&fmt,0,sizeof(fmt));
-
- fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- fmt.fmt.pix.width = hdw->res_hor_val;
- fmt.fmt.pix.height = hdw->res_ver_val;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_size(%dx%d)",
- fmt.fmt.pix.width,fmt.fmt.pix.height);
-
- pvr2_i2c_core_cmd(hdw,VIDIOC_S_FMT,&fmt);
-}
-
-
-static int check_size(struct pvr2_hdw *hdw)
-{
- return (hdw->res_hor_dirty || hdw->res_ver_dirty);
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size = {
- .check = check_size,
- .update = set_size,
- .name = "v4l2_size",
-};
-
-
-static void set_crop(struct pvr2_hdw *hdw)
-{
- struct v4l2_crop crop;
-
- memset(&crop, 0, sizeof crop);
- crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- crop.c.left = hdw->cropl_val;
- crop.c.top = hdw->cropt_val;
- crop.c.height = hdw->croph_val;
- crop.c.width = hdw->cropw_val;
-
- pvr2_trace(PVR2_TRACE_CHIPS,
- "i2c v4l2 set_crop crop=%d:%d:%d:%d",
- crop.c.width, crop.c.height, crop.c.left, crop.c.top);
-
- pvr2_i2c_core_cmd(hdw, VIDIOC_S_CROP, &crop);
-}
-
-static int check_crop(struct pvr2_hdw *hdw)
-{
- return (hdw->cropl_dirty || hdw->cropt_dirty ||
- hdw->cropw_dirty || hdw->croph_dirty);
-}
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop = {
- .check = check_crop,
- .update = set_crop,
- .name = "v4l2_crop",
-};
-
-
-static void do_log(struct pvr2_hdw *hdw)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 do_log()");
- pvr2_i2c_core_cmd(hdw,VIDIOC_LOG_STATUS,NULL);
-
-}
-
-
-static int check_log(struct pvr2_hdw *hdw)
-{
- return hdw->log_requested != 0;
-}
-
-
-const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log = {
- .check = check_log,
- .update = do_log,
- .name = "v4l2_log",
-};
-
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *cp,int fl)
-{
- pvr2_i2c_client_cmd(cp,
- (fl ? VIDIOC_STREAMON : VIDIOC_STREAMOFF),NULL);
-}
-
-
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *cp)
-{
- int stat;
- struct pvr2_hdw *hdw = cp->hdw;
- if (hdw->cropcap_stale) {
- hdw->cropcap_info.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- stat = pvr2_i2c_client_cmd(cp, VIDIOC_CROPCAP,
- &hdw->cropcap_info);
- if (stat == 0) {
- /* Check was successful, so the data is no
- longer considered stale. */
- hdw->cropcap_stale = 0;
- }
- }
- pvr2_i2c_client_cmd(cp, VIDIOC_G_TUNER, &hdw->tuner_signal_info);
-}
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
deleted file mode 100644
index eb744a20610..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-cmd-v4l2.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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 __PVRUSB2_CMD_V4L2_H
-#define __PVRUSB2_CMD_V4L2_H
-
-#include "pvrusb2-i2c-core.h"
-
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_standard;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_radio;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_bcsh;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_volume;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_frequency;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_crop;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_size;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_audiomode;
-extern const struct pvr2_i2c_op pvr2_i2c_op_v4l2_log;
-
-void pvr2_v4l2_cmd_stream(struct pvr2_i2c_client *,int);
-void pvr2_v4l2_cmd_status_poll(struct pvr2_i2c_client *);
-
-#endif /* __PVRUSB2_CMD_V4L2_H */
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index d6a35401fef..9464862745f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -18,6 +18,7 @@
*
*/
+#include <linux/i2c.h>
#include "pvrusb2-i2c-core.h"
#include "pvrusb2-hdw-internal.h"
#include "pvrusb2-debug.h"
@@ -29,8 +30,7 @@
/*
This module attempts to implement a compliant I2C adapter for the pvrusb2
- device. By doing this we can then make use of existing functionality in
- V4L (e.g. tuner.c) rather than rolling our own.
+ device.
*/
@@ -42,10 +42,6 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
module_param_array(ir_mode, int, NULL, 0444);
MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
- unsigned int detail,
- char *buf,unsigned int maxlen);
-
static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
u8 i2c_addr, /* I2C address we're talking to */
u8 *data, /* Data to write */
@@ -524,414 +520,13 @@ static u32 pvr2_i2c_functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
}
-static int pvr2_i2c_core_singleton(struct i2c_client *cp,
- unsigned int cmd,void *arg)
-{
- int stat;
- if (!cp) return -EINVAL;
- if (!(cp->driver)) return -EINVAL;
- if (!(cp->driver->command)) return -EINVAL;
- if (!try_module_get(cp->driver->driver.owner)) return -EAGAIN;
- stat = cp->driver->command(cp,cmd,arg);
- module_put(cp->driver->driver.owner);
- return stat;
-}
-
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *cp,unsigned int cmd,void *arg)
-{
- int stat;
- if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
- char buf[100];
- unsigned int cnt;
- cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
- buf,sizeof(buf));
- pvr2_trace(PVR2_TRACE_I2C_CMD,
- "i2c COMMAND (code=%u 0x%x) to %.*s",
- cmd,cmd,cnt,buf);
- }
- stat = pvr2_i2c_core_singleton(cp->client,cmd,arg);
- if (pvrusb2_debug & PVR2_TRACE_I2C_CMD) {
- char buf[100];
- unsigned int cnt;
- cnt = pvr2_i2c_client_describe(cp,PVR2_I2C_DETAIL_DEBUG,
- buf,sizeof(buf));
- pvr2_trace(PVR2_TRACE_I2C_CMD,
- "i2c COMMAND to %.*s (ret=%d)",cnt,buf,stat);
- }
- return stat;
-}
-
-int pvr2_i2c_core_cmd(struct pvr2_hdw *hdw,unsigned int cmd,void *arg)
-{
- struct pvr2_i2c_client *cp, *ncp;
- int stat = -EINVAL;
-
- if (!hdw) return stat;
-
- mutex_lock(&hdw->i2c_list_lock);
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
- if (!cp->recv_enable) continue;
- mutex_unlock(&hdw->i2c_list_lock);
- stat = pvr2_i2c_client_cmd(cp,cmd,arg);
- mutex_lock(&hdw->i2c_list_lock);
- }
- mutex_unlock(&hdw->i2c_list_lock);
- return stat;
-}
-
-
-static int handler_check(struct pvr2_i2c_client *cp)
-{
- struct pvr2_i2c_handler *hp = cp->handler;
- if (!hp) return 0;
- if (!hp->func_table->check) return 0;
- return hp->func_table->check(hp->func_data) != 0;
-}
-
-#define BUFSIZE 500
-
-
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *hdw)
-{
- struct pvr2_i2c_client *cp;
- mutex_lock(&hdw->i2c_list_lock); do {
- struct v4l2_tuner *vtp = &hdw->tuner_signal_info;
- memset(vtp,0,sizeof(*vtp));
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!cp->detected_flag) continue;
- if (!cp->status_poll) continue;
- cp->status_poll(cp);
- }
- hdw->tuner_signal_stale = 0;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c status poll"
- " type=%u strength=%u audio=0x%x cap=0x%x"
- " low=%u hi=%u",
- vtp->type,
- vtp->signal,vtp->rxsubchans,vtp->capability,
- vtp->rangelow,vtp->rangehigh);
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-
-/* Issue various I2C operations to bring chip-level drivers into sync with
- state stored in this driver. */
-void pvr2_i2c_core_sync(struct pvr2_hdw *hdw)
-{
- unsigned long msk;
- unsigned int idx;
- struct pvr2_i2c_client *cp, *ncp;
-
- if (!hdw->i2c_linked) return;
- if (!(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL)) {
- return;
- }
- mutex_lock(&hdw->i2c_list_lock); do {
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync BEGIN");
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_DETECT) {
- /* One or more I2C clients have attached since we
- last synced. So scan the list and identify the
- new clients. */
- char *buf;
- unsigned int cnt;
- unsigned long amask = 0;
- buf = kmalloc(BUFSIZE,GFP_KERNEL);
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_DETECT");
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_DETECT;
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- if (!cp->detected_flag) {
- cp->ctl_mask = 0;
- pvr2_i2c_probe(hdw,cp);
- cp->detected_flag = !0;
- msk = cp->ctl_mask;
- cnt = 0;
- if (buf) {
- cnt = pvr2_i2c_client_describe(
- cp,
- PVR2_I2C_DETAIL_ALL,
- buf,BUFSIZE);
- }
- trace_i2c("Probed: %.*s",cnt,buf);
- if (handler_check(cp)) {
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_CLIENT;
- }
- cp->pend_mask = msk;
- hdw->i2c_pend_mask |= msk;
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_REFRESH;
- }
- amask |= cp->ctl_mask;
- }
- hdw->i2c_active_mask = amask;
- if (buf) kfree(buf);
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_STALE) {
- /* Need to do one or more global updates. Arrange
- for this to happen. */
- unsigned long m2;
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: PEND_STALE (0x%lx)",
- hdw->i2c_stale_mask);
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_STALE;
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- m2 = hdw->i2c_stale_mask;
- m2 &= cp->ctl_mask;
- m2 &= ~cp->pend_mask;
- if (m2) {
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: cp=%p setting 0x%lx",
- cp,m2);
- cp->pend_mask |= m2;
- }
- }
- hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
- hdw->i2c_stale_mask = 0;
- hdw->i2c_pend_types |= PVR2_I2C_PEND_REFRESH;
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_CLIENT) {
- /* One or more client handlers are asking for an
- update. Run through the list of known clients
- and update each one. */
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_CLIENT");
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_CLIENT;
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients,
- list) {
- if (!cp->handler) continue;
- if (!cp->handler->func_table->update) continue;
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: cp=%p update",cp);
- mutex_unlock(&hdw->i2c_list_lock);
- cp->handler->func_table->update(
- cp->handler->func_data);
- mutex_lock(&hdw->i2c_list_lock);
- /* If client's update function set some
- additional pending bits, account for that
- here. */
- if (cp->pend_mask & ~hdw->i2c_pend_mask) {
- hdw->i2c_pend_mask |= cp->pend_mask;
- hdw->i2c_pend_types |=
- PVR2_I2C_PEND_REFRESH;
- }
- }
- }
- if (hdw->i2c_pend_types & PVR2_I2C_PEND_REFRESH) {
- const struct pvr2_i2c_op *opf;
- unsigned long pm;
- /* Some actual updates are pending. Walk through
- each update type and perform it. */
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: PEND_REFRESH"
- " (0x%lx)",hdw->i2c_pend_mask);
- hdw->i2c_pend_types &= ~PVR2_I2C_PEND_REFRESH;
- pm = hdw->i2c_pend_mask;
- hdw->i2c_pend_mask = 0;
- for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
- if (!(pm & msk)) continue;
- pm &= ~msk;
- list_for_each_entry(cp, &hdw->i2c_clients,
- list) {
- if (cp->pend_mask & msk) {
- cp->pend_mask &= ~msk;
- cp->recv_enable = !0;
- } else {
- cp->recv_enable = 0;
- }
- }
- opf = pvr2_i2c_get_op(idx);
- if (!opf) continue;
- mutex_unlock(&hdw->i2c_list_lock);
- opf->update(hdw);
- mutex_lock(&hdw->i2c_list_lock);
- }
- }
- pvr2_trace(PVR2_TRACE_I2C_CORE,"i2c: core_sync END");
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
-}
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *hdw)
-{
- unsigned long msk,sm,pm;
- unsigned int idx;
- const struct pvr2_i2c_op *opf;
- struct pvr2_i2c_client *cp;
- unsigned int pt = 0;
-
- pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale BEGIN");
-
- pm = hdw->i2c_active_mask;
- sm = 0;
- for (idx = 0, msk = 1; pm; idx++, msk <<= 1) {
- if (!(msk & pm)) continue;
- pm &= ~msk;
- opf = pvr2_i2c_get_op(idx);
- if (!opf) continue;
- if (opf->check(hdw)) {
- sm |= msk;
- }
- }
- if (sm) pt |= PVR2_I2C_PEND_STALE;
-
- list_for_each_entry(cp, &hdw->i2c_clients, list)
- if (handler_check(cp))
- pt |= PVR2_I2C_PEND_CLIENT;
-
- if (pt) {
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->i2c_pend_types |= pt;
- hdw->i2c_stale_mask |= sm;
- hdw->i2c_pend_mask |= hdw->i2c_stale_mask;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- }
-
- pvr2_trace(PVR2_TRACE_I2C_CORE,
- "i2c: types=0x%x stale=0x%lx pend=0x%lx",
- hdw->i2c_pend_types,
- hdw->i2c_stale_mask,
- hdw->i2c_pend_mask);
- pvr2_trace(PVR2_TRACE_I2C_CORE,"pvr2_i2c_core_check_stale END");
-
- return (hdw->i2c_pend_types & PVR2_I2C_PEND_ALL) != 0;
-}
-
-static unsigned int pvr2_i2c_client_describe(struct pvr2_i2c_client *cp,
- unsigned int detail,
- char *buf,unsigned int maxlen)
-{
- unsigned int ccnt,bcnt;
- int spcfl = 0;
- const struct pvr2_i2c_op *opf;
-
- ccnt = 0;
- if (detail & PVR2_I2C_DETAIL_DEBUG) {
- bcnt = scnprintf(buf,maxlen,
- "ctxt=%p ctl_mask=0x%lx",
- cp,cp->ctl_mask);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- spcfl = !0;
- }
- bcnt = scnprintf(buf,maxlen,
- "%s%s @ 0x%x",
- (spcfl ? " " : ""),
- cp->client->name,
- cp->client->addr);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- if ((detail & PVR2_I2C_DETAIL_HANDLER) &&
- cp->handler && cp->handler->func_table->describe) {
- bcnt = scnprintf(buf,maxlen," (");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = cp->handler->func_table->describe(
- cp->handler->func_data,buf,maxlen);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = scnprintf(buf,maxlen,")");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- if ((detail & PVR2_I2C_DETAIL_CTLMASK) && cp->ctl_mask) {
- unsigned int idx;
- unsigned long msk,sm;
-
- bcnt = scnprintf(buf,maxlen," [");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- sm = 0;
- spcfl = 0;
- for (idx = 0, msk = 1; msk; idx++, msk <<= 1) {
- if (!(cp->ctl_mask & msk)) continue;
- opf = pvr2_i2c_get_op(idx);
- if (opf) {
- bcnt = scnprintf(buf,maxlen,"%s%s",
- spcfl ? " " : "",
- opf->name);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- spcfl = !0;
- } else {
- sm |= msk;
- }
- }
- if (sm) {
- bcnt = scnprintf(buf,maxlen,"%s%lx",
- idx != 0 ? " " : "",sm);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- bcnt = scnprintf(buf,maxlen,"]");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- return ccnt;
-}
-
-unsigned int pvr2_i2c_report(struct pvr2_hdw *hdw,
- char *buf,unsigned int maxlen)
-{
- unsigned int ccnt,bcnt;
- struct pvr2_i2c_client *cp;
- ccnt = 0;
- mutex_lock(&hdw->i2c_list_lock); do {
- list_for_each_entry(cp, &hdw->i2c_clients, list) {
- bcnt = pvr2_i2c_client_describe(
- cp,
- (PVR2_I2C_DETAIL_HANDLER|
- PVR2_I2C_DETAIL_CTLMASK),
- buf,maxlen);
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- bcnt = scnprintf(buf,maxlen,"\n");
- ccnt += bcnt; buf += bcnt; maxlen -= bcnt;
- }
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- return ccnt;
-}
-
static int pvr2_i2c_attach_inform(struct i2c_client *client)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
- struct pvr2_i2c_client *cp;
- int fl = !(hdw->i2c_pend_types & PVR2_I2C_PEND_ALL);
- cp = kzalloc(sizeof(*cp),GFP_KERNEL);
- trace_i2c("i2c_attach [client=%s @ 0x%x ctxt=%p]",
- client->name,
- client->addr,cp);
- if (!cp) return -ENOMEM;
- cp->hdw = hdw;
- INIT_LIST_HEAD(&cp->list);
- cp->client = client;
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->cropcap_stale = !0;
- list_add_tail(&cp->list,&hdw->i2c_clients);
- hdw->i2c_pend_types |= PVR2_I2C_PEND_DETECT;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- if (fl) queue_work(hdw->workqueue,&hdw->worki2csync);
return 0;
}
static int pvr2_i2c_detach_inform(struct i2c_client *client)
{
- struct pvr2_hdw *hdw = (struct pvr2_hdw *)(client->adapter->algo_data);
- struct pvr2_i2c_client *cp, *ncp;
- unsigned long amask = 0;
- int foundfl = 0;
- mutex_lock(&hdw->i2c_list_lock); do {
- hdw->cropcap_stale = !0;
- list_for_each_entry_safe(cp, ncp, &hdw->i2c_clients, list) {
- if (cp->client == client) {
- trace_i2c("pvr2_i2c_detach"
- " [client=%s @ 0x%x ctxt=%p]",
- client->name,
- client->addr,cp);
- if (cp->handler &&
- cp->handler->func_table->detach) {
- cp->handler->func_table->detach(
- cp->handler->func_data);
- }
- list_del(&cp->list);
- kfree(cp);
- foundfl = !0;
- continue;
- }
- amask |= cp->ctl_mask;
- }
- hdw->i2c_active_mask = amask;
- } while (0); mutex_unlock(&hdw->i2c_list_lock);
- if (!foundfl) {
- trace_i2c("pvr2_i2c_detach [client=%s @ 0x%x ctxt=<unknown>]",
- client->name,
- client->addr);
- }
return 0;
}
@@ -942,7 +537,7 @@ static struct i2c_algorithm pvr2_i2c_algo_template = {
static struct i2c_adapter pvr2_i2c_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
+ .class = 0,
.id = I2C_HW_B_BT848,
.client_register = pvr2_i2c_attach_inform,
.client_unregister = pvr2_i2c_detach_inform,
@@ -1009,12 +604,8 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
hdw->i2c_adap.dev.parent = &hdw->usb_dev->dev;
hdw->i2c_adap.algo = &hdw->i2c_algo;
hdw->i2c_adap.algo_data = hdw;
- hdw->i2c_pend_mask = 0;
- hdw->i2c_stale_mask = 0;
- hdw->i2c_active_mask = 0;
- INIT_LIST_HEAD(&hdw->i2c_clients);
- mutex_init(&hdw->i2c_list_lock);
hdw->i2c_linked = !0;
+ i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
i2c_add_adapter(&hdw->i2c_adap);
if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
/* Probe for a different type of IR receiver on this
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
index 6ef7a1c0e93..6a75769200b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.h
@@ -20,68 +20,13 @@
#ifndef __PVRUSB2_I2C_CORE_H
#define __PVRUSB2_I2C_CORE_H
-#include <linux/list.h>
-#include <linux/i2c.h>
-
struct pvr2_hdw;
-struct pvr2_i2c_client;
-struct pvr2_i2c_handler;
-struct pvr2_i2c_handler_functions;
-struct pvr2_i2c_op;
-struct pvr2_i2c_op_functions;
-
-struct pvr2_i2c_client {
- struct i2c_client *client;
- struct pvr2_i2c_handler *handler;
- struct list_head list;
- struct pvr2_hdw *hdw;
- int detected_flag;
- int recv_enable;
- unsigned long pend_mask;
- unsigned long ctl_mask;
- void (*status_poll)(struct pvr2_i2c_client *);
-};
-
-struct pvr2_i2c_handler {
- void *func_data;
- const struct pvr2_i2c_handler_functions *func_table;
-};
-
-struct pvr2_i2c_handler_functions {
- void (*detach)(void *);
- int (*check)(void *);
- void (*update)(void *);
- unsigned int (*describe)(void *,char *,unsigned int);
-};
-
-struct pvr2_i2c_op {
- int (*check)(struct pvr2_hdw *);
- void (*update)(struct pvr2_hdw *);
- const char *name;
-};
void pvr2_i2c_core_init(struct pvr2_hdw *);
void pvr2_i2c_core_done(struct pvr2_hdw *);
-int pvr2_i2c_client_cmd(struct pvr2_i2c_client *,unsigned int cmd,void *arg);
-int pvr2_i2c_core_cmd(struct pvr2_hdw *,unsigned int cmd,void *arg);
-
-int pvr2_i2c_core_check_stale(struct pvr2_hdw *);
-void pvr2_i2c_core_sync(struct pvr2_hdw *);
-void pvr2_i2c_core_status_poll(struct pvr2_hdw *);
-unsigned int pvr2_i2c_report(struct pvr2_hdw *,char *buf,unsigned int maxlen);
-#define PVR2_I2C_DETAIL_DEBUG 0x0001
-#define PVR2_I2C_DETAIL_HANDLER 0x0002
-#define PVR2_I2C_DETAIL_CTLMASK 0x0004
-#define PVR2_I2C_DETAIL_ALL (\
- PVR2_I2C_DETAIL_DEBUG |\
- PVR2_I2C_DETAIL_HANDLER |\
- PVR2_I2C_DETAIL_CTLMASK)
-
-void pvr2_i2c_probe(struct pvr2_hdw *,struct pvr2_i2c_client *);
-const struct pvr2_i2c_op *pvr2_i2c_get_op(unsigned int idx);
-#endif /* __PVRUSB2_I2C_CORE_H */
+#endif /* __PVRUSB2_I2C_ADAPTER_H */
/*
diff --git a/drivers/media/video/pvrusb2/pvrusb2-main.c b/drivers/media/video/pvrusb2/pvrusb2-main.c
index 9b3c874d96d..8689ddb5442 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-main.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-main.c
@@ -137,10 +137,10 @@ static int __init pvr_init(void)
ret = usb_register(&pvr_driver);
if (ret == 0)
- printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
+ printk(KERN_INFO "pvrusb2: " DRIVER_VERSION ":"
DRIVER_DESC "\n");
if (pvrusb2_debug)
- printk(KERN_INFO KBUILD_MODNAME ": Debug mask is %d (0x%x)\n",
+ printk(KERN_INFO "pvrusb2: Debug mask is %d (0x%x)\n",
pvrusb2_debug,pvrusb2_debug);
pvr2_trace(PVR2_TRACE_INIT,"pvr_init complete");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index e641cd97145..e20ba1e6e0e 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -627,16 +627,8 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
pvr2_sysfs_trace("Creating class_dev id=%p",class_dev);
class_dev->class = &class_ptr->class;
- if (pvr2_hdw_get_sn(sfp->channel.hdw)) {
- dev_set_name(class_dev, "sn-%lu",
- pvr2_hdw_get_sn(sfp->channel.hdw));
- } else if (pvr2_hdw_get_unit_number(sfp->channel.hdw) >= 0) {
- dev_set_name(class_dev, "unit-%c",
- pvr2_hdw_get_unit_number(sfp->channel.hdw) + 'a');
- } else {
- kfree(class_dev);
- return;
- }
+ dev_set_name(class_dev, "%s",
+ pvr2_hdw_get_device_identifier(sfp->channel.hdw));
class_dev->parent = &usb_dev->dev;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-tuner.c b/drivers/media/video/pvrusb2/pvrusb2-tuner.c
deleted file mode 100644
index 07775d1aad4..00000000000
--- a/drivers/media/video/pvrusb2/pvrusb2-tuner.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- *
- *
- * Copyright (C) 2005 Mike Isely <isely@pobox.com>
- * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public 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 "pvrusb2.h"
-#include "pvrusb2-util.h"
-#include "pvrusb2-tuner.h"
-#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-debug.h"
-#include <linux/videodev2.h>
-#include <media/tuner.h>
-#include <media/v4l2-common.h>
-
-struct pvr2_tuner_handler {
- struct pvr2_hdw *hdw;
- struct pvr2_i2c_client *client;
- struct pvr2_i2c_handler i2c_handler;
- int type_update_fl;
-};
-
-
-static void set_type(struct pvr2_tuner_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct tuner_setup setup;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
- if (((int)(hdw->tuner_type)) < 0) return;
-
- setup.addr = ADDR_UNSET;
- setup.type = hdw->tuner_type;
- setup.mode_mask = T_RADIO | T_ANALOG_TV;
- /* We may really want mode_mask to be T_ANALOG_TV for now */
- pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
- ctxt->type_update_fl = 0;
-}
-
-
-static int tuner_check(struct pvr2_tuner_handler *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- if (hdw->tuner_updated) ctxt->type_update_fl = !0;
- return ctxt->type_update_fl != 0;
-}
-
-
-static void tuner_update(struct pvr2_tuner_handler *ctxt)
-{
- if (ctxt->type_update_fl) set_type(ctxt);
-}
-
-
-static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
-{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static unsigned int pvr2_tuner_describe(struct pvr2_tuner_handler *ctxt,char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-tuner");
-}
-
-
-static const struct pvr2_i2c_handler_functions tuner_funcs = {
- .detach = (void (*)(void *))pvr2_tuner_detach,
- .check = (int (*)(void *))tuner_check,
- .update = (void (*)(void *))tuner_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))pvr2_tuner_describe,
-};
-
-
-int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_tuner_handler *ctxt;
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->i2c_handler.func_data = ctxt;
- ctxt->i2c_handler.func_table = &tuner_funcs;
- ctxt->type_update_fl = !0;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- cp->handler = &ctxt->i2c_handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x tuner handler set up",
- cp->client->addr);
- return !0;
-}
-
-
-
-
-/*
- Stuff for Emacs to see, in order to encourage consistent editing style:
- *** Local Variables: ***
- *** mode: c ***
- *** fill-column: 70 ***
- *** tab-width: 8 ***
- *** c-basic-offset: 8 ***
- *** End: ***
- */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 878fd52a73b..9e0f2b07b93 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -91,7 +91,7 @@ static struct v4l2_capability pvr_capability ={
.card = "Hauppauge WinTV pvr-usb2",
.bus_info = "usb",
.version = KERNEL_VERSION(0,8,0),
- .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VBI_CAPTURE |
+ .capabilities = (V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
V4L2_CAP_READWRITE),
.reserved = {0,0,0,0}
@@ -952,10 +952,6 @@ static long pvr2_v4l2_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
-/* Temporary hack : use ivtv api until a v4l2 one is available. */
-#define IVTV_IOC_G_CODEC 0xFFEE7703
-#define IVTV_IOC_S_CODEC 0xFFEE7704
- if (cmd == IVTV_IOC_G_CODEC || cmd == IVTV_IOC_S_CODEC) return 0;
return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
}
@@ -1268,8 +1264,9 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->minor_type = pvr2_v4l_type_video;
nr_ptr = video_nr;
if (!dip->stream) {
- err("Failed to set up pvrusb2 v4l video dev"
- " due to missing stream instance");
+ pr_err(KBUILD_MODNAME
+ ": Failed to set up pvrusb2 v4l video dev"
+ " due to missing stream instance\n");
return;
}
break;
@@ -1286,8 +1283,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
break;
default:
/* Bail out (this should be impossible) */
- err("Failed to set up pvrusb2 v4l dev"
- " due to unrecognized config");
+ pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
+ " due to unrecognized config\n");
return;
}
@@ -1303,7 +1300,8 @@ static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
dip->v4l_type, mindevnum) < 0) &&
(video_register_device(&dip->devbase,
dip->v4l_type, -1) < 0)) {
- err("Failed to register pvrusb2 v4l device");
+ pr_err(KBUILD_MODNAME
+ ": Failed to register pvrusb2 v4l device\n");
}
printk(KERN_INFO "pvrusb2: registered device %s%u [%s]\n",
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
index 4059648c705..b3862f5554b 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.c
@@ -28,7 +28,7 @@
*/
#include "pvrusb2-video-v4l.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
+
#include "pvrusb2-hdw-internal.h"
@@ -39,15 +39,6 @@
#include <linux/errno.h>
#include <linux/slab.h>
-struct pvr2_v4l_decoder {
- struct pvr2_i2c_handler handler;
- struct pvr2_decoder_ctrl ctrl;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
-
struct routing_scheme {
const int *def;
unsigned int cnt;
@@ -63,190 +54,51 @@ static const int routing_scheme0[] = {
[PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
};
+static const int routing_scheme1[] = {
+ [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
+ [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
+ [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3,
+ [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
+};
+
static const struct routing_scheme routing_schemes[] = {
[PVR2_ROUTING_SCHEME_HAUPPAUGE] = {
.def = routing_scheme0,
.cnt = ARRAY_SIZE(routing_scheme0),
},
+ [PVR2_ROUTING_SCHEME_ONAIR] = {
+ .def = routing_scheme1,
+ .cnt = ARRAY_SIZE(routing_scheme1),
+ },
};
-static void set_input(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- struct v4l2_routing route;
- const struct routing_scheme *sp;
- unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_input(%d)",hdw->input_val);
-
- if ((sid < ARRAY_SIZE(routing_schemes)) &&
- ((sp = routing_schemes + sid) != NULL) &&
- (hdw->input_val >= 0) &&
- (hdw->input_val < sp->cnt)) {
- route.input = sp->def[hdw->input_val];
- } else {
- pvr2_trace(PVR2_TRACE_ERROR_LEGS,
- "*** WARNING *** i2c v4l2 set_input:"
- " Invalid routing scheme (%u) and/or input (%d)",
- sid,hdw->input_val);
- return;
- }
-
- route.output = 0;
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_VIDEO_ROUTING,&route);
-}
-
-
-static int check_input(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-static void set_audio(struct pvr2_v4l_decoder *ctxt)
-{
- u32 val;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 set_audio %d",
- hdw->srate_val);
- switch (hdw->srate_val) {
- default:
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000:
- val = 48000;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100:
- val = 44100;
- break;
- case V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000:
- val = 32000;
- break;
- }
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_AUDIO_CLOCK_FREQ,&val);
-}
-
-
-static int check_audio(struct pvr2_v4l_decoder *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->srate_dirty != 0;
-}
-
-
-struct pvr2_v4l_decoder_ops {
- void (*update)(struct pvr2_v4l_decoder *);
- int (*check)(struct pvr2_v4l_decoder *);
-};
-
-
-static const struct pvr2_v4l_decoder_ops decoder_ops[] = {
- { .update = set_input, .check = check_input},
- { .update = set_audio, .check = check_audio},
-};
-
-
-static void decoder_detach(struct pvr2_v4l_decoder *ctxt)
+void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- ctxt->client->handler = NULL;
- pvr2_hdw_set_decoder(ctxt->hdw,NULL);
- kfree(ctxt);
-}
-
-
-static int decoder_check(struct pvr2_v4l_decoder *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (decoder_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+ const struct routing_scheme *sp;
+ unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
+ hdw->input_val);
+ if ((sid < ARRAY_SIZE(routing_schemes)) &&
+ ((sp = routing_schemes + sid) != NULL) &&
+ (hdw->input_val >= 0) &&
+ (hdw->input_val < sp->cnt)) {
+ route.input = sp->def[hdw->input_val];
+ } else {
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS,
+ "*** WARNING *** subdev v4l2 set_input:"
+ " Invalid routing scheme (%u)"
+ " and/or input (%d)",
+ sid, hdw->input_val);
+ return;
}
+ route.output = 0;
+ sd->ops->video->s_routing(sd, &route);
}
- return ctxt->stale_mask != 0;
-}
-
-
-static void decoder_update(struct pvr2_v4l_decoder *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(decoder_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- decoder_ops[idx].update(ctxt);
- }
-}
-
-
-static int decoder_detect(struct pvr2_i2c_client *cp)
-{
- /* Attempt to query the decoder - let's see if it will answer */
- struct v4l2_tuner vt;
- int ret;
-
- memset(&vt,0,sizeof(vt));
- ret = pvr2_i2c_client_cmd(cp,VIDIOC_G_TUNER,&vt);
- return ret == 0; /* Return true if it answered */
-}
-
-
-static void decoder_enable(struct pvr2_v4l_decoder *ctxt,int fl)
-{
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c v4l2 decoder_enable(%d)",fl);
- pvr2_v4l2_cmd_stream(ctxt->client,fl);
-}
-
-
-static unsigned int decoder_describe(struct pvr2_v4l_decoder *ctxt,char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-video-v4l");
-}
-
-
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))decoder_detach,
- .check = (int (*)(void *))decoder_check,
- .update = (void (*)(void *))decoder_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))decoder_describe,
-};
-
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *hdw,
- struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_decoder *ctxt;
-
- if (hdw->decoder_ctrl) return 0;
- if (cp->handler) return 0;
- if (!decoder_detect(cp)) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->ctrl.ctxt = ctxt;
- ctxt->ctrl.detach = (void (*)(void *))decoder_detach;
- ctxt->ctrl.enable = (void (*)(void *,int))decoder_enable;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(decoder_ops)) - 1;
- pvr2_hdw_set_decoder(hdw,&ctxt->ctrl);
- cp->handler = &ctxt->handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x saa711x V4L2 handler set up",
- cp->client->addr);
- return !0;
}
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
*** Local Variables: ***
diff --git a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
index 4ff5b892b30..3b0bd5db602 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-video-v4l.h
@@ -32,11 +32,8 @@
*/
-
-#include "pvrusb2-i2c-core.h"
-
-int pvr2_i2c_decoder_v4l_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
-
+#include "pvrusb2-hdw-internal.h"
+void pvr2_saa7115_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *);
#endif /* __PVRUSB2_VIDEO_V4L_H */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
index f6fcf0ac611..1670aa4051c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.c
@@ -27,7 +27,6 @@
*/
#include "pvrusb2-wm8775.h"
-#include "pvrusb2-i2c-cmd-v4l2.h"
#include "pvrusb2-hdw-internal.h"
@@ -37,128 +36,31 @@
#include <linux/errno.h>
#include <linux/slab.h>
-struct pvr2_v4l_wm8775 {
- struct pvr2_i2c_handler handler;
- struct pvr2_i2c_client *client;
- struct pvr2_hdw *hdw;
- unsigned long stale_mask;
-};
-
-
-static void set_input(struct pvr2_v4l_wm8775 *ctxt)
-{
- struct v4l2_routing route;
- struct pvr2_hdw *hdw = ctxt->hdw;
-
- memset(&route,0,sizeof(route));
-
- switch(hdw->input_val) {
- case PVR2_CVAL_INPUT_RADIO:
- route.input = 1;
- break;
- default:
- /* All other cases just use the second input */
- route.input = 2;
- break;
- }
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c wm8775 set_input(val=%d route=0x%x)",
- hdw->input_val,route.input);
-
- pvr2_i2c_client_cmd(ctxt->client,VIDIOC_INT_S_AUDIO_ROUTING,&route);
-}
-
-static int check_input(struct pvr2_v4l_wm8775 *ctxt)
-{
- struct pvr2_hdw *hdw = ctxt->hdw;
- return hdw->input_dirty != 0;
-}
-
-
-struct pvr2_v4l_wm8775_ops {
- void (*update)(struct pvr2_v4l_wm8775 *);
- int (*check)(struct pvr2_v4l_wm8775 *);
-};
-
-
-static const struct pvr2_v4l_wm8775_ops wm8775_ops[] = {
- { .update = set_input, .check = check_input},
-};
-
-
-static unsigned int wm8775_describe(struct pvr2_v4l_wm8775 *ctxt,
- char *buf,unsigned int cnt)
-{
- return scnprintf(buf,cnt,"handler: pvrusb2-wm8775");
-}
-
-
-static void wm8775_detach(struct pvr2_v4l_wm8775 *ctxt)
+void pvr2_wm8775_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
{
- ctxt->client->handler = NULL;
- kfree(ctxt);
-}
-
-
-static int wm8775_check(struct pvr2_v4l_wm8775 *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
-
- for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
- msk = 1 << idx;
- if (ctxt->stale_mask & msk) continue;
- if (wm8775_ops[idx].check(ctxt)) {
- ctxt->stale_mask |= msk;
+ if (hdw->input_dirty || hdw->force_dirty) {
+ struct v4l2_routing route;
+
+ memset(&route, 0, sizeof(route));
+
+ switch (hdw->input_val) {
+ case PVR2_CVAL_INPUT_RADIO:
+ route.input = 1;
+ break;
+ default:
+ /* All other cases just use the second input */
+ route.input = 2;
+ break;
}
- }
- return ctxt->stale_mask != 0;
-}
-
-
-static void wm8775_update(struct pvr2_v4l_wm8775 *ctxt)
-{
- unsigned long msk;
- unsigned int idx;
+ pvr2_trace(PVR2_TRACE_CHIPS, "subdev wm8775"
+ " set_input(val=%d route=0x%x)",
+ hdw->input_val, route.input);
- for (idx = 0; idx < ARRAY_SIZE(wm8775_ops); idx++) {
- msk = 1 << idx;
- if (!(ctxt->stale_mask & msk)) continue;
- ctxt->stale_mask &= ~msk;
- wm8775_ops[idx].update(ctxt);
+ sd->ops->audio->s_routing(sd, &route);
}
}
-static const struct pvr2_i2c_handler_functions hfuncs = {
- .detach = (void (*)(void *))wm8775_detach,
- .check = (int (*)(void *))wm8775_check,
- .update = (void (*)(void *))wm8775_update,
- .describe = (unsigned int (*)(void *,char *,unsigned int))wm8775_describe,
-};
-
-
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
-{
- struct pvr2_v4l_wm8775 *ctxt;
-
- if (cp->handler) return 0;
-
- ctxt = kzalloc(sizeof(*ctxt),GFP_KERNEL);
- if (!ctxt) return 0;
-
- ctxt->handler.func_data = ctxt;
- ctxt->handler.func_table = &hfuncs;
- ctxt->client = cp;
- ctxt->hdw = hdw;
- ctxt->stale_mask = (1 << ARRAY_SIZE(wm8775_ops)) - 1;
- cp->handler = &ctxt->handler;
- pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x wm8775 V4L2 handler set up",
- cp->client->addr);
- return !0;
-}
-
-
-
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
diff --git a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
index 80709096125..0577bc7246f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-wm8775.h
@@ -34,9 +34,9 @@
-#include "pvrusb2-i2c-core.h"
+#include "pvrusb2-hdw-internal.h"
-int pvr2_i2c_wm8775_setup(struct pvr2_hdw *,struct pvr2_i2c_client *);
+void pvr2_wm8775_subdev_update(struct pvr2_hdw *, struct v4l2_subdev *sd);
#endif /* __PVRUSB2_WM8775_H */
diff --git a/drivers/media/video/pwc/Kconfig b/drivers/media/video/pwc/Kconfig
index 7298cf2e165..8b9f0aa844a 100644
--- a/drivers/media/video/pwc/Kconfig
+++ b/drivers/media/video/pwc/Kconfig
@@ -35,3 +35,13 @@ config USB_PWC_DEBUG
Say Y here in order to have the pwc driver generate verbose debugging
messages.
A special module options 'trace' is used to control the verbosity.
+
+config USB_PWC_INPUT_EVDEV
+ bool "USB Philips Cameras input events device support"
+ default y
+ depends on USB_PWC && INPUT
+ ---help---
+ This option makes USB Philips cameras register the snapshot button as
+ an input device to report button events.
+
+ If you are in doubt, say Y.
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 0d810189dd8..7c542caf248 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -53,6 +53,7 @@
- Xavier Roche: QuickCam Pro 4000 ID
- Jens Knudsen: QuickCam Zoom ID
- J. Debert: QuickCam for Notebooks ID
+ - Pham Thanh Nam: webcam snapshot button as an event input device
*/
#include <linux/errno.h>
@@ -61,6 +62,9 @@
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/slab.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/usb/input.h>
+#endif
#include <linux/vmalloc.h>
#include <asm/io.h>
@@ -586,6 +590,23 @@ static void pwc_frame_dumped(struct pwc_device *pdev)
pdev->vframe_count);
}
+static void pwc_snapshot_button(struct pwc_device *pdev, int down)
+{
+ if (down) {
+ PWC_TRACE("Snapshot button pressed.\n");
+ pdev->snapshot_button_status = 1;
+ } else {
+ PWC_TRACE("Snapshot button released.\n");
+ }
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ if (pdev->button_dev) {
+ input_report_key(pdev->button_dev, BTN_0, down);
+ input_sync(pdev->button_dev);
+ }
+#endif
+}
+
static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_buf *fbuf)
{
int awake = 0;
@@ -603,13 +624,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
pdev->vframes_error++;
}
if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- if (ptr[0] & 0x01) {
- pdev->snapshot_button_status = 1;
- PWC_TRACE("Snapshot button pressed.\n");
- }
- else {
- PWC_TRACE("Snapshot button released.\n");
- }
+ pwc_snapshot_button(pdev, ptr[0] & 0x01);
}
if ((ptr[0] ^ pdev->vmirror) & 0x02) {
if (ptr[0] & 0x02)
@@ -633,12 +648,7 @@ static int pwc_rcv_short_packet(struct pwc_device *pdev, const struct pwc_frame_
else if (pdev->type == 740 || pdev->type == 720) {
unsigned char *ptr = (unsigned char *)fbuf->data;
if ((ptr[0] ^ pdev->vmirror) & 0x01) {
- if (ptr[0] & 0x01) {
- pdev->snapshot_button_status = 1;
- PWC_TRACE("Snapshot button pressed.\n");
- }
- else
- PWC_TRACE("Snapshot button released.\n");
+ pwc_snapshot_button(pdev, ptr[0] & 0x01);
}
pdev->vmirror = ptr[0] & 0x03;
}
@@ -1115,6 +1125,7 @@ static int pwc_video_open(struct file *file)
}
mutex_lock(&pdev->modlock);
+ pwc_construct(pdev); /* set min/max sizes correct */
if (!pdev->usb_init) {
PWC_DEBUG_OPEN("Doing first time initialization.\n");
pdev->usb_init = 1;
@@ -1139,7 +1150,6 @@ static int pwc_video_open(struct file *file)
if (pwc_set_leds(pdev, led_on, led_off) < 0)
PWC_DEBUG_OPEN("Failed to set LED on/off time.\n");
- pwc_construct(pdev); /* set min/max sizes correct */
/* So far, so good. Allocate memory. */
i = pwc_allocate_buffers(pdev);
@@ -1216,6 +1226,15 @@ static void pwc_cleanup(struct pwc_device *pdev)
{
pwc_remove_sysfs_files(pdev->vdev);
video_unregister_device(pdev->vdev);
+
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ if (pdev->button_dev) {
+ input_unregister_device(pdev->button_dev);
+ input_free_device(pdev->button_dev);
+ kfree(pdev->button_dev->phys);
+ pdev->button_dev = NULL;
+ }
+#endif
}
/* Note that all cleanup is done in the reverse order as in _open */
@@ -1483,6 +1502,9 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
int features = 0;
int video_nr = -1; /* default: use next available device */
char serial_number[30], *name;
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ char *phys = NULL;
+#endif
vendor_id = le16_to_cpu(udev->descriptor.idVendor);
product_id = le16_to_cpu(udev->descriptor.idProduct);
@@ -1807,6 +1829,35 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
pwc_set_leds(pdev, 0, 0);
pwc_camera_power(pdev, 0);
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ /* register webcam snapshot button input device */
+ pdev->button_dev = input_allocate_device();
+ if (!pdev->button_dev) {
+ PWC_ERROR("Err, insufficient memory for webcam snapshot button device.");
+ return -ENOMEM;
+ }
+
+ pdev->button_dev->name = "PWC snapshot button";
+ phys = kasprintf(GFP_KERNEL,"usb-%s-%s", pdev->udev->bus->bus_name, pdev->udev->devpath);
+ if (!phys) {
+ input_free_device(pdev->button_dev);
+ return -ENOMEM;
+ }
+ pdev->button_dev->phys = phys;
+ usb_to_input_id(pdev->udev, &pdev->button_dev->id);
+ pdev->button_dev->dev.parent = &pdev->udev->dev;
+ pdev->button_dev->evbit[0] = BIT_MASK(EV_KEY);
+ pdev->button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0);
+
+ rc = input_register_device(pdev->button_dev);
+ if (rc) {
+ input_free_device(pdev->button_dev);
+ kfree(pdev->button_dev->phys);
+ pdev->button_dev = NULL;
+ return rc;
+ }
+#endif
+
return 0;
err_unreg:
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 01411fb2337..0be6f814f53 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -37,6 +37,9 @@
#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+#include <linux/input.h>
+#endif
#include "pwc-uncompress.h"
#include <media/pwc-ioctl.h>
@@ -255,6 +258,9 @@ struct pwc_device
int pan_angle; /* in degrees * 100 */
int tilt_angle; /* absolute angle; 0,0 is home position */
int snapshot_button_status; /* set to 1 when the user push the button, reset to 0 when this value is read */
+#ifdef CONFIG_USB_PWC_INPUT_EVDEV
+ struct input_dev *button_dev; /* webcam snapshot button input */
+#endif
/*** Misc. data ***/
wait_queue_head_t frameq; /* When waiting for a frame to finish... */
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 0c4ce58c53d..c522616ef38 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -878,6 +878,7 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
SOCAM_HSYNC_ACTIVE_LOW |
SOCAM_VSYNC_ACTIVE_HIGH |
SOCAM_VSYNC_ACTIVE_LOW |
+ SOCAM_DATA_ACTIVE_HIGH |
SOCAM_PCLK_SAMPLE_RISING |
SOCAM_PCLK_SAMPLE_FALLING;
@@ -1149,8 +1150,43 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
return formats;
}
+static int pxa_camera_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct pxa_camera_dev *pcdev = ici->priv;
+ struct soc_camera_sense sense = {
+ .master_clock = pcdev->mclk,
+ .pixel_clock_max = pcdev->ciclk / 4,
+ };
+ int ret;
+
+ /* If PCLK is used to latch data from the sensor, check sense */
+ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
+ icd->sense = &sense;
+
+ ret = icd->ops->set_crop(icd, rect);
+
+ icd->sense = NULL;
+
+ if (ret < 0) {
+ dev_warn(&ici->dev, "Failed to crop to %ux%u@%u:%u\n",
+ rect->width, rect->height, rect->left, rect->top);
+ } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
+ if (sense.pixel_clock > sense.pixel_clock_max) {
+ dev_err(&ici->dev,
+ "pixel clock %lu set by the camera too high!",
+ sense.pixel_clock);
+ return -EIO;
+ }
+ recalculate_fifo_timeout(pcdev, sense.pixel_clock);
+ }
+
+ return ret;
+}
+
static int pxa_camera_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
@@ -1160,35 +1196,30 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
.master_clock = pcdev->mclk,
.pixel_clock_max = pcdev->ciclk / 4,
};
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_format cam_f = *f;
int ret;
- if (pixfmt) {
- xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
- if (!xlate) {
- dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
- return -EINVAL;
- }
-
- cam_fmt = xlate->cam_fmt;
+ xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
+ if (!xlate) {
+ dev_warn(&ici->dev, "Format %x not found\n", pix->pixelformat);
+ return -EINVAL;
}
+ cam_fmt = xlate->cam_fmt;
+
/* If PCLK is used to latch data from the sensor, check sense */
if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
icd->sense = &sense;
- switch (pixfmt) {
- case 0: /* Only geometry change */
- ret = icd->ops->set_fmt(icd, pixfmt, rect);
- break;
- default:
- ret = icd->ops->set_fmt(icd, cam_fmt->fourcc, rect);
- }
+ cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
+ ret = icd->ops->set_fmt(icd, &cam_f);
icd->sense = NULL;
if (ret < 0) {
dev_warn(&ici->dev, "Failed to configure for format %x\n",
- pixfmt);
+ pix->pixelformat);
} else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
if (sense.pixel_clock > sense.pixel_clock_max) {
dev_err(&ici->dev,
@@ -1199,7 +1230,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
recalculate_fifo_timeout(pcdev, sense.pixel_clock);
}
- if (pixfmt && !ret) {
+ if (!ret) {
icd->buswidth = xlate->buswidth;
icd->current_fmt = xlate->host_fmt;
}
@@ -1363,6 +1394,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
.remove = pxa_camera_remove_device,
.suspend = pxa_camera_suspend,
.resume = pxa_camera_resume,
+ .set_crop = pxa_camera_set_crop,
.get_formats = pxa_camera_get_formats,
.set_fmt = pxa_camera_set_fmt,
.try_fmt = pxa_camera_try_fmt,
diff --git a/drivers/media/video/s2255drv.c b/drivers/media/video/s2255drv.c
index 13f85ad363c..b5be633e3bb 100644
--- a/drivers/media/video/s2255drv.c
+++ b/drivers/media/video/s2255drv.c
@@ -336,14 +336,19 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char req,
u16 index, u16 value, void *buf,
s32 buf_len, int bOut);
+/* dev_err macro with driver name */
+#define S2255_DRIVER_NAME "s2255"
+#define s2255_dev_err(dev, fmt, arg...) \
+ dev_err(dev, S2255_DRIVER_NAME " - " fmt, ##arg)
+
#define dprintk(level, fmt, arg...) \
do { \
if (*s2255_debug >= (level)) { \
- printk(KERN_DEBUG "s2255: " fmt, ##arg); \
+ printk(KERN_DEBUG S2255_DRIVER_NAME \
+ ": " fmt, ##arg); \
} \
} while (0)
-
static struct usb_driver s2255_driver;
@@ -528,14 +533,14 @@ static void s2255_fwchunk_complete(struct urb *urb)
int len;
dprintk(100, "udev %p urb %p", udev, urb);
if (urb->status) {
- dev_err(&udev->dev, "URB failed with status %d", urb->status);
+ dev_err(&udev->dev, "URB failed with status %d\n", urb->status);
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
return;
}
if (data->fw_urb == NULL) {
- dev_err(&udev->dev, "s2255 disconnected\n");
+ s2255_dev_err(&udev->dev, "disconnected\n");
atomic_set(&data->fw_state, S2255_FW_FAILED);
/* wake up anything waiting for the firmware */
wake_up(&data->wait_fw);
@@ -841,8 +846,7 @@ static int vidioc_querycap(struct file *file, void *priv,
struct s2255_dev *dev = fh->dev;
strlcpy(cap->driver, "s2255", sizeof(cap->driver));
strlcpy(cap->card, "s2255", sizeof(cap->card));
- strlcpy(cap->bus_info, dev_name(&dev->udev->dev),
- sizeof(cap->bus_info));
+ usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info));
cap->version = S2255_VERSION;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
return 0;
@@ -1278,7 +1282,7 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
}
if (!res_get(dev, fh)) {
- dev_err(&dev->udev->dev, "s2255: stream busy\n");
+ s2255_dev_err(&dev->udev->dev, "stream busy\n");
return -EBUSY;
}
@@ -1545,7 +1549,8 @@ static int s2255_open(struct file *file)
switch (atomic_read(&dev->fw_data->fw_state)) {
case S2255_FW_FAILED:
- err("2255 firmware load failed. retrying.\n");
+ s2255_dev_err(&dev->udev->dev,
+ "firmware load failed. retrying.\n");
s2255_fwload_start(dev, 1);
wait_event_timeout(dev->fw_data->wait_fw,
((atomic_read(&dev->fw_data->fw_state)
@@ -2173,7 +2178,8 @@ static int s2255_board_init(struct s2255_dev *dev)
printk(KERN_INFO "2255 usb firmware version %d \n", fw_ver);
if (fw_ver < CUR_USB_FWVER)
- err("usb firmware not up to date %d\n", fw_ver);
+ dev_err(&dev->udev->dev,
+ "usb firmware not up to date %d\n", fw_ver);
for (j = 0; j < MAX_CHANNELS; j++) {
dev->b_acquire[j] = 0;
@@ -2228,13 +2234,13 @@ static void read_pipe_completion(struct urb *purb)
dprintk(100, "read pipe completion %p, status %d\n", purb,
purb->status);
if (pipe_info == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
dev = pipe_info->dev;
if (dev == NULL) {
- err("no context !");
+ dev_err(&purb->dev->dev, "no context!\n");
return;
}
status = purb->status;
@@ -2286,7 +2292,7 @@ static int s2255_start_readpipe(struct s2255_dev *dev)
pipe_info->stream_urb = usb_alloc_urb(0, GFP_KERNEL);
if (!pipe_info->stream_urb) {
dev_err(&dev->udev->dev,
- "ReadStream: Unable to alloc URB");
+ "ReadStream: Unable to alloc URB\n");
return -ENOMEM;
}
/* transfer buffer allocated in board_init */
@@ -2391,7 +2397,7 @@ static void s2255_stop_readpipe(struct s2255_dev *dev)
int j;
if (dev == NULL) {
- err("s2255: invalid device");
+ s2255_dev_err(&dev->udev->dev, "invalid device\n");
return;
}
dprintk(4, "stop read pipe\n");
@@ -2453,7 +2459,7 @@ static int s2255_probe(struct usb_interface *interface,
/* allocate memory for our device state and initialize it to zero */
dev = kzalloc(sizeof(struct s2255_dev), GFP_KERNEL);
if (dev == NULL) {
- err("s2255: out of memory");
+ s2255_dev_err(&interface->dev, "out of memory\n");
goto error;
}
@@ -2487,7 +2493,7 @@ static int s2255_probe(struct usb_interface *interface,
}
if (!dev->read_endpoint) {
- dev_err(&interface->dev, "Could not find bulk-in endpoint");
+ dev_err(&interface->dev, "Could not find bulk-in endpoint\n");
goto error;
}
@@ -2583,7 +2589,7 @@ static void s2255_disconnect(struct usb_interface *interface)
}
static struct usb_driver s2255_driver = {
- .name = "s2255",
+ .name = S2255_DRIVER_NAME,
.probe = s2255_probe,
.disconnect = s2255_disconnect,
.id_table = s2255_table,
@@ -2597,7 +2603,8 @@ static int __init usb_s2255_init(void)
result = usb_register(&s2255_driver);
if (result)
- err("usb_register failed. Error number %d", result);
+ pr_err(KBUILD_MODNAME
+ ": usb_register failed. Error number %d\n", result);
dprintk(2, "s2255_init: done\n");
return result;
diff --git a/drivers/media/video/saa5246a.c b/drivers/media/video/saa5246a.c
index e637e440b6d..da47b2f0528 100644
--- a/drivers/media/video/saa5246a.c
+++ b/drivers/media/video/saa5246a.c
@@ -46,10 +46,11 @@
#include <linux/smp_lock.h>
#include <linux/mutex.h>
#include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
MODULE_DESCRIPTION("Philips SAA5246A, SAA5281 Teletext decoder driver");
@@ -388,13 +389,19 @@ MODULE_LICENSE("GPL");
struct saa5246a_device
{
+ struct v4l2_subdev sd;
+ struct video_device *vdev;
u8 pgbuf[NUM_DAUS][VTX_VIRTUALSIZE];
int is_searching[NUM_DAUS];
- struct i2c_client *client;
unsigned long in_use;
struct mutex lock;
};
+static inline struct saa5246a_device *to_dev(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa5246a_device, sd);
+}
+
static struct video_device saa_template; /* Declared near bottom */
/*
@@ -403,12 +410,13 @@ static struct video_device saa_template; /* Declared near bottom */
static int i2c_sendbuf(struct saa5246a_device *t, int reg, int count, u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
char buf[64];
buf[0] = reg;
memcpy(buf+1, data, count);
- if(i2c_master_send(t->client, buf, count+1)==count+1)
+ if (i2c_master_send(client, buf, count + 1) == count + 1)
return 0;
return -1;
}
@@ -436,7 +444,9 @@ static int i2c_senddata(struct saa5246a_device *t, ...)
*/
static int i2c_getdata(struct saa5246a_device *t, int count, u8 *buf)
{
- if(i2c_master_recv(t->client, buf, count)!=count)
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+ if (i2c_master_recv(client, buf, count) != count)
return -1;
return 0;
}
@@ -961,9 +971,6 @@ static int saa5246a_open(struct file *file)
{
struct saa5246a_device *t = video_drvdata(file);
- if (t->client == NULL)
- return -ENODEV;
-
if (test_and_set_bit(0, &t->in_use))
return -EBUSY;
@@ -1033,18 +1040,29 @@ static struct video_device saa_template =
.minor = -1,
};
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5246a_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5246A, 0);
+}
+
+static const struct v4l2_subdev_core_ops saa5246a_core_ops = {
+ .g_chip_ident = saa5246a_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5246a_ops = {
+ .core = &saa5246a_core_ops,
+};
-I2C_CLIENT_INSMOD;
static int saa5246a_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int pgbuf;
int err;
- struct video_device *vd;
struct saa5246a_device *t;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -1053,40 +1071,43 @@ static int saa5246a_probe(struct i2c_client *client,
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL)
return -ENOMEM;
+ sd = &t->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa5246a_ops);
mutex_init(&t->lock);
/* Now create a video4linux device */
- vd = video_device_alloc();
- if (vd == NULL) {
+ t->vdev = video_device_alloc();
+ if (t->vdev == NULL) {
kfree(t);
return -ENOMEM;
}
- i2c_set_clientdata(client, vd);
- memcpy(vd, &saa_template, sizeof(*vd));
+ memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
memset(t->pgbuf[pgbuf], ' ', sizeof(t->pgbuf[0]));
t->is_searching[pgbuf] = false;
}
- video_set_drvdata(vd, t);
+ video_set_drvdata(t->vdev, t);
/* Register it */
- err = video_register_device(vd, VFL_TYPE_VTX, -1);
+ err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
if (err < 0) {
kfree(t);
- video_device_release(vd);
+ video_device_release(t->vdev);
+ t->vdev = NULL;
return err;
}
- t->client = client;
return 0;
}
static int saa5246a_remove(struct i2c_client *client)
{
- struct video_device *vd = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa5246a_device *t = to_dev(sd);
- video_unregister_device(vd);
- kfree(video_get_drvdata(vd));
+ video_unregister_device(t->vdev);
+ v4l2_device_unregister_subdev(sd);
+ kfree(t);
return 0;
}
@@ -1098,7 +1119,6 @@ MODULE_DEVICE_TABLE(i2c, saa5246a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa5246a",
- .driverid = I2C_DRIVERID_SAA5249,
.probe = saa5246a_probe,
.remove = saa5246a_remove,
.id_table = saa5246a_id,
diff --git a/drivers/media/video/saa5249.c b/drivers/media/video/saa5249.c
index e2976519246..48b27fe4808 100644
--- a/drivers/media/video/saa5249.c
+++ b/drivers/media/video/saa5249.c
@@ -50,15 +50,17 @@
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/videotext.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
#include <media/v4l2-ioctl.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Geng <linux@MichaelGeng.de>");
MODULE_DESCRIPTION("Philips SAA5249 Teletext decoder driver");
MODULE_LICENSE("GPL");
+
#define VTX_VER_MAJ 1
#define VTX_VER_MIN 8
@@ -95,17 +97,23 @@ typedef struct {
struct saa5249_device
{
+ struct v4l2_subdev sd;
+ struct video_device *vdev;
vdau_t vdau[NUM_DAUS]; /* Data for virtual DAUs (the 5249 only has one */
/* real DAU, so we have to simulate some more) */
int vtx_use_count;
int is_searching[NUM_DAUS];
int disp_mode;
int virtual_mode;
- struct i2c_client *client;
unsigned long in_use;
struct mutex lock;
};
+static inline struct saa5249_device *to_dev(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa5249_device, sd);
+}
+
#define CCTWR 34 /* I²C write/read-address of vtx-chip */
#define CCTRD 35
@@ -147,12 +155,13 @@ static void jdelay(unsigned long delay)
static int i2c_sendbuf(struct saa5249_device *t, int reg, int count, u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
char buf[64];
buf[0] = reg;
memcpy(buf+1, data, count);
- if (i2c_master_send(t->client, buf, count + 1) == count + 1)
+ if (i2c_master_send(client, buf, count + 1) == count + 1)
return 0;
return -1;
}
@@ -180,7 +189,9 @@ static int i2c_senddata(struct saa5249_device *t, ...)
static int i2c_getdata(struct saa5249_device *t, int count, u8 *buf)
{
- if(i2c_master_recv(t->client, buf, count)!=count)
+ struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
+
+ if (i2c_master_recv(client, buf, count) != count)
return -1;
return 0;
}
@@ -497,9 +508,6 @@ static int saa5249_open(struct file *file)
struct saa5249_device *t = video_drvdata(file);
int pgbuf;
- if (t->client == NULL)
- return -ENODEV;
-
if (test_and_set_bit(0, &t->in_use))
return -EBUSY;
@@ -553,18 +561,28 @@ static struct video_device saa_template =
.release = video_device_release,
};
-/* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
+static int saa5249_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA5249, 0);
+}
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_core_ops saa5249_core_ops = {
+ .g_chip_ident = saa5249_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops saa5249_ops = {
+ .core = &saa5249_core_ops,
+};
static int saa5249_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int pgbuf;
int err;
- struct video_device *vd;
struct saa5249_device *t;
+ struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
@@ -573,16 +591,17 @@ static int saa5249_probe(struct i2c_client *client,
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL)
return -ENOMEM;
+ sd = &t->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa5249_ops);
mutex_init(&t->lock);
/* Now create a video4linux device */
- vd = kmalloc(sizeof(struct video_device), GFP_KERNEL);
- if (vd == NULL) {
+ t->vdev = video_device_alloc();
+ if (t->vdev == NULL) {
kfree(client);
return -ENOMEM;
}
- i2c_set_clientdata(client, vd);
- memcpy(vd, &saa_template, sizeof(*vd));
+ memcpy(t->vdev, &saa_template, sizeof(*t->vdev));
for (pgbuf = 0; pgbuf < NUM_DAUS; pgbuf++) {
memset(t->vdau[pgbuf].pgbuf, ' ', sizeof(t->vdau[0].pgbuf));
@@ -593,26 +612,27 @@ static int saa5249_probe(struct i2c_client *client,
t->vdau[pgbuf].stopped = true;
t->is_searching[pgbuf] = false;
}
- video_set_drvdata(vd, t);
+ video_set_drvdata(t->vdev, t);
/* Register it */
- err = video_register_device(vd, VFL_TYPE_VTX, -1);
+ err = video_register_device(t->vdev, VFL_TYPE_VTX, -1);
if (err < 0) {
kfree(t);
- kfree(vd);
+ video_device_release(t->vdev);
+ t->vdev = NULL;
return err;
}
- t->client = client;
return 0;
}
static int saa5249_remove(struct i2c_client *client)
{
- struct video_device *vd = i2c_get_clientdata(client);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa5249_device *t = to_dev(sd);
- video_unregister_device(vd);
- kfree(video_get_drvdata(vd));
- kfree(vd);
+ video_unregister_device(t->vdev);
+ v4l2_device_unregister_subdev(sd);
+ kfree(t);
return 0;
}
@@ -624,7 +644,6 @@ MODULE_DEVICE_TABLE(i2c, saa5249_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa5249",
- .driverid = I2C_DRIVERID_SAA5249,
.probe = saa5249_probe,
.remove = saa5249_remove,
.id_table = saa5249_id,
diff --git a/drivers/media/video/saa6588.c b/drivers/media/video/saa6588.c
index f05024259f0..c25e81af5ce 100644
--- a/drivers/media/video/saa6588.c
+++ b/drivers/media/video/saa6588.c
@@ -23,7 +23,7 @@
#include <linux/kernel.h>
#include <linux/i2c.h>
#include <linux/types.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/slab.h>
@@ -32,15 +32,10 @@
#include <asm/uaccess.h>
#include <media/rds.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {
- 0x20 >> 1,
- 0x22 >> 1,
- I2C_CLIENT_END,
-};
-
-I2C_CLIENT_INSMOD;
/* insmod options */
static unsigned int debug;
@@ -72,9 +67,8 @@ MODULE_LICENSE("GPL");
#define dprintk if (debug) printk
struct saa6588 {
- struct i2c_client client;
- struct work_struct work;
- struct timer_list timer;
+ struct v4l2_subdev sd;
+ struct delayed_work work;
spinlock_t lock;
unsigned char *buffer;
unsigned int buf_size;
@@ -86,8 +80,10 @@ struct saa6588 {
int data_available_for_read;
};
-static struct i2c_driver driver;
-static struct i2c_client client_template;
+static inline struct saa6588 *to_saa6588(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa6588, sd);
+}
/* ---------------------------------------------------------------------- */
@@ -258,6 +254,7 @@ static void block_to_buf(struct saa6588 *s, unsigned char *blockbuf)
static void saa6588_i2c_poll(struct saa6588 *s)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
unsigned long flags;
unsigned char tmpbuf[6];
unsigned char blocknum;
@@ -265,7 +262,7 @@ static void saa6588_i2c_poll(struct saa6588 *s)
/* Although we only need 3 bytes, we have to read at least 6.
SAA6588 returns garbage otherwise */
- if (6 != i2c_master_recv(&s->client, &tmpbuf[0], 6)) {
+ if (6 != i2c_master_recv(client, &tmpbuf[0], 6)) {
if (debug > 1)
dprintk(PREFIX "read error!\n");
return;
@@ -316,23 +313,17 @@ static void saa6588_i2c_poll(struct saa6588 *s)
wake_up_interruptible(&s->read_queue);
}
-static void saa6588_timer(unsigned long data)
-{
- struct saa6588 *s = (struct saa6588 *)data;
-
- schedule_work(&s->work);
-}
-
static void saa6588_work(struct work_struct *work)
{
- struct saa6588 *s = container_of(work, struct saa6588, work);
+ struct saa6588 *s = container_of(work, struct saa6588, work.work);
saa6588_i2c_poll(s);
- mod_timer(&s->timer, jiffies + msecs_to_jiffies(20));
+ schedule_delayed_work(&s->work, msecs_to_jiffies(20));
}
static int saa6588_configure(struct saa6588 *s)
{
+ struct i2c_client *client = v4l2_get_subdevdata(&s->sd);
unsigned char buf[3];
int rc;
@@ -380,7 +371,8 @@ static int saa6588_configure(struct saa6588 *s)
dprintk(PREFIX "writing: 0w=0x%02x 1w=0x%02x 2w=0x%02x\n",
buf[0], buf[1], buf[2]);
- if (3 != (rc = i2c_master_send(&s->client, buf, 3)))
+ rc = i2c_master_send(client, buf, 3);
+ if (rc != 3)
printk(PREFIX "i2c i/o error: rc == %d (should be 3)\n", rc);
return 0;
@@ -388,70 +380,10 @@ static int saa6588_configure(struct saa6588 *s)
/* ---------------------------------------------------------------------- */
-static int saa6588_attach(struct i2c_adapter *adap, int addr, int kind)
-{
- struct saa6588 *s;
- client_template.adapter = adap;
- client_template.addr = addr;
-
- printk(PREFIX "chip found @ 0x%x\n", addr << 1);
-
- if (NULL == (s = kmalloc(sizeof(*s), GFP_KERNEL)))
- return -ENOMEM;
-
- s->buf_size = bufblocks * 3;
-
- if (NULL == (s->buffer = kmalloc(s->buf_size, GFP_KERNEL))) {
- kfree(s);
- return -ENOMEM;
- }
- spin_lock_init(&s->lock);
- s->client = client_template;
- s->block_count = 0;
- s->wr_index = 0;
- s->rd_index = 0;
- s->last_blocknum = 0xff;
- init_waitqueue_head(&s->read_queue);
- s->data_available_for_read = 0;
- i2c_set_clientdata(&s->client, s);
- i2c_attach_client(&s->client);
-
- saa6588_configure(s);
-
- /* start polling via eventd */
- INIT_WORK(&s->work, saa6588_work);
- init_timer(&s->timer);
- s->timer.function = saa6588_timer;
- s->timer.data = (unsigned long)s;
- schedule_work(&s->work);
- return 0;
-}
-
-static int saa6588_probe(struct i2c_adapter *adap)
-{
- if (adap->class & I2C_CLASS_TV_ANALOG)
- return i2c_probe(adap, &addr_data, saa6588_attach);
- return 0;
-}
-
-static int saa6588_detach(struct i2c_client *client)
-{
- struct saa6588 *s = i2c_get_clientdata(client);
-
- del_timer_sync(&s->timer);
- flush_scheduled_work();
-
- i2c_detach_client(client);
- kfree(s->buffer);
- kfree(s);
- return 0;
-}
-
-static int saa6588_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
+static long saa6588_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
{
- struct saa6588 *s = i2c_get_clientdata(client);
- struct rds_command *a = (struct rds_command *)arg;
+ struct saa6588 *s = to_saa6588(sd);
+ struct rds_command *a = arg;
switch (cmd) {
/* --- open() for /dev/radio --- */
@@ -479,45 +411,94 @@ static int saa6588_command(struct i2c_client *client, unsigned int cmd,
default:
/* nothing */
- break;
+ return -ENOIOCTLCMD;
}
return 0;
}
+static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static struct i2c_driver driver = {
- .driver = {
- .name = "saa6588",
- },
- .id = -1, /* FIXME */
- .attach_adapter = saa6588_probe,
- .detach_client = saa6588_detach,
- .command = saa6588_command,
+static const struct v4l2_subdev_core_ops saa6588_core_ops = {
+ .g_chip_ident = saa6588_g_chip_ident,
+ .ioctl = saa6588_ioctl,
};
-static struct i2c_client client_template = {
- .name = "saa6588",
- .driver = &driver,
+static const struct v4l2_subdev_ops saa6588_ops = {
+ .core = &saa6588_core_ops,
};
-static int __init saa6588_init_module(void)
+/* ---------------------------------------------------------------------- */
+
+static int saa6588_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
{
- return i2c_add_driver(&driver);
+ struct saa6588 *s;
+ struct v4l2_subdev *sd;
+
+ v4l_info(client, "saa6588 found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
+ if (s == NULL)
+ return -ENOMEM;
+
+ s->buf_size = bufblocks * 3;
+
+ s->buffer = kmalloc(s->buf_size, GFP_KERNEL);
+ if (s->buffer == NULL) {
+ kfree(s);
+ return -ENOMEM;
+ }
+ sd = &s->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa6588_ops);
+ spin_lock_init(&s->lock);
+ s->block_count = 0;
+ s->wr_index = 0;
+ s->rd_index = 0;
+ s->last_blocknum = 0xff;
+ init_waitqueue_head(&s->read_queue);
+ s->data_available_for_read = 0;
+
+ saa6588_configure(s);
+
+ /* start polling via eventd */
+ INIT_DELAYED_WORK(&s->work, saa6588_work);
+ schedule_delayed_work(&s->work, 0);
+ return 0;
}
-static void __exit saa6588_cleanup_module(void)
+static int saa6588_remove(struct i2c_client *client)
{
- i2c_del_driver(&driver);
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa6588 *s = to_saa6588(sd);
+
+ v4l2_device_unregister_subdev(sd);
+
+ cancel_delayed_work_sync(&s->work);
+
+ kfree(s->buffer);
+ kfree(s);
+ return 0;
}
-module_init(saa6588_init_module);
-module_exit(saa6588_cleanup_module);
+/* ----------------------------------------------------------------------- */
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
+static const struct i2c_device_id saa6588_id[] = {
+ { "saa6588", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa6588_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa6588",
+ .probe = saa6588_probe,
+ .remove = saa6588_remove,
+ .id_table = saa6588_id,
+};
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 37860698f78..df4e08d2dce 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -33,15 +33,16 @@
#include <linux/wait.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
MODULE_AUTHOR("Pauline Middelink");
MODULE_LICENSE("GPL");
+
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
@@ -52,9 +53,10 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define SAA7110_NR_REG 0x35
struct saa7110 {
+ struct v4l2_subdev sd;
u8 reg[SAA7110_NR_REG];
- int norm;
+ v4l2_std_id norm;
int input;
int enable;
int bright;
@@ -65,20 +67,28 @@ struct saa7110 {
wait_queue_head_t wq;
};
+static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa7110, sd);
+}
+
/* ----------------------------------------------------------------------- */
/* I2C support functions */
/* ----------------------------------------------------------------------- */
-static int saa7110_write(struct i2c_client *client, u8 reg, u8 value)
+static int saa7110_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- struct saa7110 *decoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7110 *decoder = to_saa7110(sd);
decoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int saa7110_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7110 *decoder = to_saa7110(sd);
int ret = -1;
u8 reg = *data; /* first register to write to */
@@ -89,15 +99,13 @@ static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsign
/* the saa7110 has an autoincrement function, use it if
* the adapter understands raw I2C */
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- struct saa7110 *decoder = i2c_get_clientdata(client);
-
ret = i2c_master_send(client, data, len);
/* Cache the written data */
memcpy(decoder->reg + reg, data + 1, len - 1);
} else {
for (++data, --len; len; len--) {
- ret = saa7110_write(client, reg++, *data++);
+ ret = saa7110_write(sd, reg++, *data++);
if (ret < 0)
break;
}
@@ -106,8 +114,10 @@ static int saa7110_write_block(struct i2c_client *client, const u8 *data, unsign
return ret;
}
-static inline int saa7110_read(struct i2c_client *client)
+static inline int saa7110_read(struct v4l2_subdev *sd)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte(client);
}
@@ -115,11 +125,11 @@ static inline int saa7110_read(struct i2c_client *client)
/* SAA7110 functions */
/* ----------------------------------------------------------------------- */
-#define FRESP_06H_COMPST 0x03 //0x13
-#define FRESP_06H_SVIDEO 0x83 //0xC0
+#define FRESP_06H_COMPST 0x03 /*0x13*/
+#define FRESP_06H_SVIDEO 0x83 /*0xC0*/
-static int saa7110_selmux(struct i2c_client *client, int chan)
+static int saa7110_selmux(struct v4l2_subdev *sd, int chan)
{
static const unsigned char modes[9][8] = {
/* mode 0 */
@@ -150,17 +160,17 @@ static int saa7110_selmux(struct i2c_client *client, int chan)
{FRESP_06H_SVIDEO, 0x3C, 0x27, 0xC1, 0x23,
0x44, 0x75, 0x21}
};
- struct saa7110 *decoder = i2c_get_clientdata(client);
+ struct saa7110 *decoder = to_saa7110(sd);
const unsigned char *ptr = modes[chan];
- saa7110_write(client, 0x06, ptr[0]); /* Luminance control */
- saa7110_write(client, 0x20, ptr[1]); /* Analog Control #1 */
- saa7110_write(client, 0x21, ptr[2]); /* Analog Control #2 */
- saa7110_write(client, 0x22, ptr[3]); /* Mixer Control #1 */
- saa7110_write(client, 0x2C, ptr[4]); /* Mixer Control #2 */
- saa7110_write(client, 0x30, ptr[5]); /* ADCs gain control */
- saa7110_write(client, 0x31, ptr[6]); /* Mixer Control #3 */
- saa7110_write(client, 0x21, ptr[7]); /* Analog Control #2 */
+ saa7110_write(sd, 0x06, ptr[0]); /* Luminance control */
+ saa7110_write(sd, 0x20, ptr[1]); /* Analog Control #1 */
+ saa7110_write(sd, 0x21, ptr[2]); /* Analog Control #2 */
+ saa7110_write(sd, 0x22, ptr[3]); /* Mixer Control #1 */
+ saa7110_write(sd, 0x2C, ptr[4]); /* Mixer Control #2 */
+ saa7110_write(sd, 0x30, ptr[5]); /* ADCs gain control */
+ saa7110_write(sd, 0x31, ptr[6]); /* Mixer Control #3 */
+ saa7110_write(sd, 0x21, ptr[7]); /* Analog Control #2 */
decoder->input = chan;
return 0;
@@ -176,246 +186,260 @@ static const unsigned char initseq[1 + SAA7110_NR_REG] = {
/* 0x30 */ 0x44, 0x71, 0x02, 0x8C, 0x02
};
-static int determine_norm(struct i2c_client *client)
+static v4l2_std_id determine_norm(struct v4l2_subdev *sd)
{
DEFINE_WAIT(wait);
- struct saa7110 *decoder = i2c_get_clientdata(client);
+ struct saa7110 *decoder = to_saa7110(sd);
int status;
/* mode changed, start automatic detection */
- saa7110_write_block(client, initseq, sizeof(initseq));
- saa7110_selmux(client, decoder->input);
+ saa7110_write_block(sd, initseq, sizeof(initseq));
+ saa7110_selmux(sd, decoder->input);
prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(250));
finish_wait(&decoder->wq, &wait);
- status = saa7110_read(client);
+ status = saa7110_read(sd);
if (status & 0x40) {
- v4l_dbg(1, debug, client, "status=0x%02x (no signal)\n", status);
- return decoder->norm; // no change
+ v4l2_dbg(1, debug, sd, "status=0x%02x (no signal)\n", status);
+ return decoder->norm; /* no change*/
}
if ((status & 3) == 0) {
- saa7110_write(client, 0x06, 0x83);
+ saa7110_write(sd, 0x06, 0x83);
if (status & 0x20) {
- v4l_dbg(1, debug, client, "status=0x%02x (NTSC/no color)\n", status);
- //saa7110_write(client,0x2E,0x81);
- return VIDEO_MODE_NTSC;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC/no color)\n", status);
+ /*saa7110_write(sd,0x2E,0x81);*/
+ return V4L2_STD_NTSC;
}
- v4l_dbg(1, debug, client, "status=0x%02x (PAL/no color)\n", status);
- //saa7110_write(client,0x2E,0x9A);
- return VIDEO_MODE_PAL;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (PAL/no color)\n", status);
+ /*saa7110_write(sd,0x2E,0x9A);*/
+ return V4L2_STD_PAL;
}
- //saa7110_write(client,0x06,0x03);
+ /*saa7110_write(sd,0x06,0x03);*/
if (status & 0x20) { /* 60Hz */
- v4l_dbg(1, debug, client, "status=0x%02x (NTSC)\n", status);
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x50);
- saa7110_write(client, 0x11, 0x2C);
- //saa7110_write(client,0x2E,0x81);
- return VIDEO_MODE_NTSC;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (NTSC)\n", status);
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x50);
+ saa7110_write(sd, 0x11, 0x2C);
+ /*saa7110_write(sd,0x2E,0x81);*/
+ return V4L2_STD_NTSC;
}
/* 50Hz -> PAL/SECAM */
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client,0x2E,0x9A);
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd,0x2E,0x9A);*/
prepare_to_wait(&decoder->wq, &wait, TASK_UNINTERRUPTIBLE);
schedule_timeout(msecs_to_jiffies(250));
finish_wait(&decoder->wq, &wait);
- status = saa7110_read(client);
+ status = saa7110_read(sd);
if ((status & 0x03) == 0x01) {
- v4l_dbg(1, debug, client, "status=0x%02x (SECAM)\n", status);
- saa7110_write(client, 0x0D, 0x87);
- return VIDEO_MODE_SECAM;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (SECAM)\n", status);
+ saa7110_write(sd, 0x0D, 0x87);
+ return V4L2_STD_SECAM;
}
- v4l_dbg(1, debug, client, "status=0x%02x (PAL)\n", status);
- return VIDEO_MODE_PAL;
+ v4l2_dbg(1, debug, sd, "status=0x%02x (PAL)\n", status);
+ return V4L2_STD_PAL;
}
-static int
-saa7110_command (struct i2c_client *client,
- unsigned int cmd,
- void *arg)
+static int saa7110_g_input_status(struct v4l2_subdev *sd, u32 *pstatus)
{
- struct saa7110 *decoder = i2c_get_clientdata(client);
- int v;
+ struct saa7110 *decoder = to_saa7110(sd);
+ int res = V4L2_IN_ST_NO_SIGNAL;
+ int status = saa7110_read(sd);
+
+ v4l2_dbg(1, debug, sd, "status=0x%02x norm=%llx\n",
+ status, (unsigned long long)decoder->norm);
+ if (!(status & 0x40))
+ res = 0;
+ if (!(status & 0x03))
+ res |= V4L2_IN_ST_NO_COLOR;
+
+ *pstatus = res;
+ return 0;
+}
- switch (cmd) {
- case 0:
- //saa7110_write_block(client, initseq, sizeof(initseq));
- break;
+static int saa7110_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ *(v4l2_std_id *)std = determine_norm(sd);
+ return 0;
+}
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *dc = arg;
+static int saa7110_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
+
+ if (decoder->norm != std) {
+ decoder->norm = std;
+ /*saa7110_write(sd, 0x06, 0x03);*/
+ if (std & V4L2_STD_NTSC) {
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x50);
+ saa7110_write(sd, 0x11, 0x2C);
+ /*saa7110_write(sd, 0x2E, 0x81);*/
+ v4l2_dbg(1, debug, sd, "switched to NTSC\n");
+ } else if (std & V4L2_STD_PAL) {
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd, 0x2E, 0x9A);*/
+ v4l2_dbg(1, debug, sd, "switched to PAL\n");
+ } else if (std & V4L2_STD_SECAM) {
+ saa7110_write(sd, 0x0D, 0x87);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd, 0x2E, 0x9A);*/
+ v4l2_dbg(1, debug, sd, "switched to SECAM\n");
+ } else {
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
- dc->flags =
- VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
- dc->inputs = SAA7110_MAX_INPUT;
- dc->outputs = SAA7110_MAX_OUTPUT;
- break;
+static int saa7110_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
+
+ if (route->input < 0 || route->input >= SAA7110_MAX_INPUT) {
+ v4l2_dbg(1, debug, sd, "input=%d not available\n", route->input);
+ return -EINVAL;
+ }
+ if (decoder->input != route->input) {
+ saa7110_selmux(sd, route->input);
+ v4l2_dbg(1, debug, sd, "switched to input=%d\n", route->input);
}
+ return 0;
+}
- case DECODER_GET_STATUS:
- {
- int status;
- int res = 0;
-
- status = saa7110_read(client);
- v4l_dbg(1, debug, client, "status=0x%02x norm=%d\n",
- status, decoder->norm);
- if (!(status & 0x40))
- res |= DECODER_STATUS_GOOD;
- if (status & 0x03)
- res |= DECODER_STATUS_COLOR;
-
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- }
- *(int *) arg = res;
- break;
+static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
+
+ if (decoder->enable != enable) {
+ decoder->enable = enable;
+ saa7110_write(sd, 0x0E, enable ? 0x18 : 0x80);
+ v4l2_dbg(1, debug, sd, "YUV %s\n", enable ? "on" : "off");
}
+ return 0;
+}
- case DECODER_SET_NORM:
- v = *(int *) arg;
- if (decoder->norm != v) {
- decoder->norm = v;
- //saa7110_write(client, 0x06, 0x03);
- switch (v) {
- case VIDEO_MODE_NTSC:
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x50);
- saa7110_write(client, 0x11, 0x2C);
- //saa7110_write(client, 0x2E, 0x81);
- v4l_dbg(1, debug, client, "switched to NTSC\n");
- break;
- case VIDEO_MODE_PAL:
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client, 0x2E, 0x9A);
- v4l_dbg(1, debug, client, "switched to PAL\n");
- break;
- case VIDEO_MODE_SECAM:
- saa7110_write(client, 0x0D, 0x87);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client, 0x2E, 0x9A);
- v4l_dbg(1, debug, client, "switched to SECAM\n");
- break;
- case VIDEO_MODE_AUTO:
- v4l_dbg(1, debug, client, "switched to AUTO\n");
- decoder->norm = determine_norm(client);
- *(int *) arg = decoder->norm;
- break;
- default:
- return -EPERM;
- }
- }
- break;
+static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
+ case V4L2_CID_CONTRAST:
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- case DECODER_SET_INPUT:
- v = *(int *) arg;
- if (v < 0 || v >= SAA7110_MAX_INPUT) {
- v4l_dbg(1, debug, client, "input=%d not available\n", v);
- return -EINVAL;
- }
- if (decoder->input != v) {
- saa7110_selmux(client, v);
- v4l_dbg(1, debug, client, "switched to input=%d\n", v);
- }
- break;
+static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
- case DECODER_SET_OUTPUT:
- v = *(int *) arg;
- /* not much choice of outputs */
- if (v != 0)
- return -EINVAL;
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = decoder->bright;
break;
-
- case DECODER_ENABLE_OUTPUT:
- v = *(int *) arg;
- if (decoder->enable != v) {
- decoder->enable = v;
- saa7110_write(client, 0x0E, v ? 0x18 : 0x80);
- v4l_dbg(1, debug, client, "YUV %s\n", v ? "on" : "off");
- }
+ case V4L2_CID_CONTRAST:
+ ctrl->value = decoder->contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = decoder->sat;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = decoder->hue;
break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
+static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct saa7110 *decoder = to_saa7110(sd);
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7110_write(client, 0x19, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7110_write(client, 0x13,
- decoder->contrast >> 9);
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (decoder->bright != ctrl->value) {
+ decoder->bright = ctrl->value;
+ saa7110_write(sd, 0x19, decoder->bright);
}
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7110_write(client, 0x12, decoder->sat >> 9);
+ break;
+ case V4L2_CID_CONTRAST:
+ if (decoder->contrast != ctrl->value) {
+ decoder->contrast = ctrl->value;
+ saa7110_write(sd, 0x13, decoder->contrast);
}
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7110_write(client, 0x07,
- (decoder->hue >> 8) - 128);
+ break;
+ case V4L2_CID_SATURATION:
+ if (decoder->sat != ctrl->value) {
+ decoder->sat = ctrl->value;
+ saa7110_write(sd, 0x12, decoder->sat);
}
break;
- }
-
- case DECODER_DUMP:
- if (!debug)
- break;
- for (v = 0; v < SAA7110_NR_REG; v += 16) {
- int j;
- v4l_dbg(1, debug, client, "%02x:", v);
- for (j = 0; j < 16 && v + j < SAA7110_NR_REG; j++)
- printk(KERN_CONT " %02x", decoder->reg[v + j]);
- printk(KERN_CONT "\n");
+ case V4L2_CID_HUE:
+ if (decoder->hue != ctrl->value) {
+ decoder->hue = ctrl->value;
+ saa7110_write(sd, 0x07, decoder->hue);
}
break;
-
default:
- v4l_dbg(1, debug, client, "unknown command %08x\n", cmd);
return -EINVAL;
}
return 0;
}
+static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7110, 0);
+}
+
/* ----------------------------------------------------------------------- */
-/*
- * Generic i2c probe
- * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
- */
+static const struct v4l2_subdev_core_ops saa7110_core_ops = {
+ .g_chip_ident = saa7110_g_chip_ident,
+ .g_ctrl = saa7110_g_ctrl,
+ .s_ctrl = saa7110_s_ctrl,
+ .queryctrl = saa7110_queryctrl,
+};
-static unsigned short normal_i2c[] = { 0x9c >> 1, 0x9e >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_tuner_ops saa7110_tuner_ops = {
+ .s_std = saa7110_s_std,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops saa7110_video_ops = {
+ .s_routing = saa7110_s_routing,
+ .s_stream = saa7110_s_stream,
+ .querystd = saa7110_querystd,
+ .g_input_status = saa7110_g_input_status,
+};
+
+static const struct v4l2_subdev_ops saa7110_ops = {
+ .core = &saa7110_core_ops,
+ .tuner = &saa7110_tuner_ops,
+ .video = &saa7110_video_ops,
+};
+
+/* ----------------------------------------------------------------------- */
static int saa7110_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct saa7110 *decoder;
+ struct v4l2_subdev *sd;
int rv;
/* Check if the adapter supports the needed features */
@@ -429,7 +453,9 @@ static int saa7110_probe(struct i2c_client *client,
decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
- decoder->norm = VIDEO_MODE_PAL;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa7110_ops);
+ decoder->norm = V4L2_STD_PAL;
decoder->input = 0;
decoder->enable = 1;
decoder->bright = 32768;
@@ -437,30 +463,29 @@ static int saa7110_probe(struct i2c_client *client,
decoder->hue = 32768;
decoder->sat = 32768;
init_waitqueue_head(&decoder->wq);
- i2c_set_clientdata(client, decoder);
- rv = saa7110_write_block(client, initseq, sizeof(initseq));
+ rv = saa7110_write_block(sd, initseq, sizeof(initseq));
if (rv < 0) {
- v4l_dbg(1, debug, client, "init status %d\n", rv);
+ v4l2_dbg(1, debug, sd, "init status %d\n", rv);
} else {
int ver, status;
- saa7110_write(client, 0x21, 0x10);
- saa7110_write(client, 0x0e, 0x18);
- saa7110_write(client, 0x0D, 0x04);
- ver = saa7110_read(client);
- saa7110_write(client, 0x0D, 0x06);
- //mdelay(150);
- status = saa7110_read(client);
- v4l_dbg(1, debug, client, "version %x, status=0x%02x\n",
+ saa7110_write(sd, 0x21, 0x10);
+ saa7110_write(sd, 0x0e, 0x18);
+ saa7110_write(sd, 0x0D, 0x04);
+ ver = saa7110_read(sd);
+ saa7110_write(sd, 0x0D, 0x06);
+ /*mdelay(150);*/
+ status = saa7110_read(sd);
+ v4l2_dbg(1, debug, sd, "version %x, status=0x%02x\n",
ver, status);
- saa7110_write(client, 0x0D, 0x86);
- saa7110_write(client, 0x0F, 0x10);
- saa7110_write(client, 0x11, 0x59);
- //saa7110_write(client, 0x2E, 0x9A);
+ saa7110_write(sd, 0x0D, 0x86);
+ saa7110_write(sd, 0x0F, 0x10);
+ saa7110_write(sd, 0x11, 0x59);
+ /*saa7110_write(sd, 0x2E, 0x9A);*/
}
- //saa7110_selmux(client,0);
- //determine_norm(client);
+ /*saa7110_selmux(sd,0);*/
+ /*determine_norm(sd);*/
/* setup and implicit mode 0 select has been performed */
return 0;
@@ -468,7 +493,10 @@ static int saa7110_probe(struct i2c_client *client,
static int saa7110_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_saa7110(sd));
return 0;
}
@@ -482,8 +510,6 @@ MODULE_DEVICE_TABLE(i2c, saa7110_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7110",
- .driverid = I2C_DRIVERID_SAA7110,
- .command = saa7110_command,
.probe = saa7110_probe,
.remove = saa7110_remove,
.id_table = saa7110_id,
diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c
deleted file mode 100644
index a4738a2fb4d..00000000000
--- a/drivers/media/video/saa7111.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/*
- * saa7111 - Philips SAA7111A video decoder driver version 0.0.3
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * Changes by Michael Hunold <michael@mihu.de>
- * - implemented DECODER_SET_GPIO, DECODER_INIT, DECODER_SET_VBI_BYPASS
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-
-MODULE_DESCRIPTION("Philips SAA7111 video decoder driver");
-MODULE_AUTHOR("Dave Perks");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-#define SAA7111_NR_REG 0x18
-
-struct saa7111 {
- unsigned char reg[SAA7111_NR_REG];
-
- int norm;
- int input;
- int enable;
-};
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7111_write(struct i2c_client *client, u8 reg, u8 value)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
-
- decoder->reg[reg] = value;
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static inline void saa7111_write_if_changed(struct i2c_client *client, u8 reg, u8 value)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
-
- if (decoder->reg[reg] != value) {
- decoder->reg[reg] = value;
- i2c_smbus_write_byte_data(client, reg, value);
- }
-}
-
-static int saa7111_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
-{
- int ret = -1;
- u8 reg;
-
- /* the saa7111 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- struct saa7111 *decoder = i2c_get_clientdata(client);
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] =
- decoder->reg[reg++] = data[1];
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = saa7111_write(client, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-static int saa7111_init_decoder(struct i2c_client *client,
- struct video_decoder_init *init)
-{
- return saa7111_write_block(client, init->data, init->len);
-}
-
-static inline int saa7111_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const unsigned char saa7111_i2c_init[] = {
- 0x00, 0x00, /* 00 - ID byte */
- 0x01, 0x00, /* 01 - reserved */
-
- /*front end */
- 0x02, 0xd0, /* 02 - FUSE=3, GUDL=2, MODE=0 */
- 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
- * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
- 0x04, 0x00, /* 04 - GAI1=256 */
- 0x05, 0x00, /* 05 - GAI2=256 */
-
- /* decoder */
- 0x06, 0xf3, /* 06 - HSB at 13(50Hz) / 17(60Hz)
- * pixels after end of last line */
- /*0x07, 0x13, * 07 - HSS at 113(50Hz) / 117(60Hz) pixels
- * after end of last line */
- 0x07, 0xe8, /* 07 - HSS seems to be needed to
- * work with NTSC, too */
- 0x08, 0xc8, /* 08 - AUFD=1, FSEL=1, EXFIL=0,
- * VTRC=1, HPLL=0, VNOI=0 */
- 0x09, 0x01, /* 09 - BYPS=0, PREF=0, BPSS=0,
- * VBLB=0, UPTCV=0, APER=1 */
- 0x0a, 0x80, /* 0a - BRIG=128 */
- 0x0b, 0x47, /* 0b - CONT=1.109 */
- 0x0c, 0x40, /* 0c - SATN=1.0 */
- 0x0d, 0x00, /* 0d - HUE=0 */
- 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0,
- * FCTC=0, CHBW=1 */
- 0x0f, 0x00, /* 0f - reserved */
- 0x10, 0x48, /* 10 - OFTS=1, HDEL=0, VRLN=1, YDEL=0 */
- 0x11, 0x1c, /* 11 - GPSW=0, CM99=0, FECO=0, COMPO=1,
- * OEYC=1, OEHV=1, VIPB=0, COLO=0 */
- 0x12, 0x00, /* 12 - output control 2 */
- 0x13, 0x00, /* 13 - output control 3 */
- 0x14, 0x00, /* 14 - reserved */
- 0x15, 0x00, /* 15 - VBI */
- 0x16, 0x00, /* 16 - VBI */
- 0x17, 0x00, /* 17 - VBI */
-};
-
-static int saa7111_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- struct saa7111 *decoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- break;
- case DECODER_INIT:
- {
- struct video_decoder_init *init = arg;
- struct video_decoder_init vdi;
-
- if (NULL != init)
- return saa7111_init_decoder(client, init);
- vdi.data = saa7111_i2c_init;
- vdi.len = sizeof(saa7111_i2c_init);
- return saa7111_init_decoder(client, &vdi);
- }
-
- case DECODER_DUMP:
- {
- int i;
-
- for (i = 0; i < SAA7111_NR_REG; i += 16) {
- int j;
-
- v4l_info(client, "%03x", i);
- for (j = 0; j < 16 && i + j < SAA7111_NR_REG; ++j) {
- printk(KERN_CONT " %02x",
- saa7111_read(client, i + j));
- }
- printk(KERN_CONT "\n");
- }
- break;
- }
-
- 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 = 8;
- cap->outputs = 1;
- break;
- }
-
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
-
- status = saa7111_read(client, 0x1f);
- v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
- res = 0;
- if ((status & (1 << 6)) == 0) {
- res |= DECODER_STATUS_GOOD;
- }
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & (1 << 5)) != 0) {
- res |= DECODER_STATUS_NTSC;
- } else {
- res |= DECODER_STATUS_PAL;
- }
- break;
- }
- if ((status & (1 << 0)) != 0) {
- res |= DECODER_STATUS_COLOR;
- }
- *iarg = res;
- break;
- }
-
- case DECODER_SET_GPIO:
- {
- int *iarg = arg;
- if (0 != *iarg) {
- saa7111_write(client, 0x11,
- (decoder->reg[0x11] | 0x80));
- } else {
- saa7111_write(client, 0x11,
- (decoder->reg[0x11] & 0x7f));
- }
- break;
- }
-
- case DECODER_SET_VBI_BYPASS:
- {
- int *iarg = arg;
- if (0 != *iarg) {
- saa7111_write(client, 0x13,
- (decoder->reg[0x13] & 0xf0) | 0x0a);
- } else {
- saa7111_write(client, 0x13,
- (decoder->reg[0x13] & 0xf0));
- }
- break;
- }
-
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
-
- switch (*iarg) {
-
- case VIDEO_MODE_NTSC:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x40);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- case VIDEO_MODE_PAL:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x00);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- case VIDEO_MODE_SECAM:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x00);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f) | 0x50);
- break;
-
- case VIDEO_MODE_AUTO:
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0x3f) | 0x80);
- saa7111_write(client, 0x0e,
- (decoder->reg[0x0e] & 0x8f));
- break;
-
- default:
- return -EINVAL;
-
- }
- decoder->norm = *iarg;
- break;
- }
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
-
- if (*iarg < 0 || *iarg > 7) {
- return -EINVAL;
- }
-
- if (decoder->input != *iarg) {
- decoder->input = *iarg;
- /* select mode */
- saa7111_write(client, 0x02,
- (decoder->
- reg[0x02] & 0xf8) | decoder->input);
- /* bypass chrominance trap for modes 4..7 */
- saa7111_write(client, 0x09,
- (decoder->
- reg[0x09] & 0x7f) | ((decoder->
- input >
- 3) ? 0x80 :
- 0));
- }
- 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;
- int enable = (*iarg != 0);
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
-
- /* RJ: If output should be disabled (for
- * playing videos), we also need a open PLL.
- * The input is set to 0 (where no input
- * source is connected), although this
- * is not necessary.
- *
- * If output should be enabled, we have to
- * reverse the above.
- */
-
- if (decoder->enable) {
- saa7111_write(client, 0x02,
- (decoder->
- reg[0x02] & 0xf8) |
- decoder->input);
- saa7111_write(client, 0x08,
- (decoder->reg[0x08] & 0xfb));
- saa7111_write(client, 0x11,
- (decoder->
- reg[0x11] & 0xf3) | 0x0c);
- } else {
- saa7111_write(client, 0x02,
- (decoder->reg[0x02] & 0xf8));
- saa7111_write(client, 0x08,
- (decoder->
- reg[0x08] & 0xfb) | 0x04);
- saa7111_write(client, 0x11,
- (decoder->reg[0x11] & 0xf3));
- }
- }
- break;
- }
-
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- /* We want 0 to 255 we get 0-65535 */
- saa7111_write_if_changed(client, 0x0a, pic->brightness >> 8);
- /* We want 0 to 127 we get 0-65535 */
- saa7111_write(client, 0x0b, pic->contrast >> 9);
- /* We want 0 to 127 we get 0-65535 */
- saa7111_write(client, 0x0c, pic->colour >> 9);
- /* We want -128 to 127 we get 0-65535 */
- saa7111_write(client, 0x0d, (pic->hue - 32768) >> 8);
- break;
- }
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned short normal_i2c[] = { 0x48 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
-static int saa7111_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int i;
- struct saa7111 *decoder;
- struct video_decoder_init vdi;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- decoder = kzalloc(sizeof(struct saa7111), GFP_KERNEL);
- if (decoder == NULL) {
- kfree(client);
- return -ENOMEM;
- }
- decoder->norm = VIDEO_MODE_NTSC;
- decoder->input = 0;
- decoder->enable = 1;
- i2c_set_clientdata(client, decoder);
-
- vdi.data = saa7111_i2c_init;
- vdi.len = sizeof(saa7111_i2c_init);
- i = saa7111_init_decoder(client, &vdi);
- if (i < 0) {
- v4l_dbg(1, debug, client, "init status %d\n", i);
- } else {
- v4l_dbg(1, debug, client, "revision %x\n",
- saa7111_read(client, 0x00) >> 4);
- }
- return 0;
-}
-
-static int saa7111_remove(struct i2c_client *client)
-{
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7111_id[] = {
- { "saa7111_old", 0 }, /* "saa7111" maps to the saa7115 driver */
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7111_id);
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data = {
- .name = "saa7111",
- .driverid = I2C_DRIVERID_SAA7111A,
- .command = saa7111_command,
- .probe = saa7111_probe,
- .remove = saa7111_remove,
- .id_table = saa7111_id,
-};
diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c
deleted file mode 100644
index 7ca709fda5f..00000000000
--- a/drivers/media/video/saa7114.c
+++ /dev/null
@@ -1,1068 +0,0 @@
-/*
- * saa7114 - Philips SAA7114H video decoder driver version 0.0.1
- *
- * Copyright (C) 2002 Maxim Yevtyushkin <max@linuxmedialabs.com>
- *
- * Based on saa7111 driver by Dave Perks
- *
- * Copyright (C) 1998 Dave Perks <dperks@ibm.net>
- *
- * Slight changes for video timing and attachment output by
- * Wolfgang Scherr <scherr@net4you.net>
- *
- * Changes by Ronald Bultje <rbultje@ronald.bitfreak.net>
- * - moved over to linux>=2.4.x i2c protocol (1/1/2003)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/ioctl.h>
-#include <asm/uaccess.h>
-#include <linux/i2c.h>
-#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-
-MODULE_DESCRIPTION("Philips SAA7114H video decoder driver");
-MODULE_AUTHOR("Maxim Yevtyushkin");
-MODULE_LICENSE("GPL");
-
-static int debug;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "Debug level (0-1)");
-
-/* ----------------------------------------------------------------------- */
-
-struct saa7114 {
- unsigned char reg[0xf0 * 2];
-
- int norm;
- int input;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
- int playback;
-};
-
-#define I2C_DELAY 10
-
-
-//#define SAA_7114_NTSC_HSYNC_START (-3)
-//#define SAA_7114_NTSC_HSYNC_STOP (-18)
-
-#define SAA_7114_NTSC_HSYNC_START (-17)
-#define SAA_7114_NTSC_HSYNC_STOP (-32)
-
-//#define SAA_7114_NTSC_HOFFSET (5)
-#define SAA_7114_NTSC_HOFFSET (6)
-#define SAA_7114_NTSC_VOFFSET (10)
-#define SAA_7114_NTSC_WIDTH (720)
-#define SAA_7114_NTSC_HEIGHT (250)
-
-#define SAA_7114_SECAM_HSYNC_START (-17)
-#define SAA_7114_SECAM_HSYNC_STOP (-32)
-
-#define SAA_7114_SECAM_HOFFSET (2)
-#define SAA_7114_SECAM_VOFFSET (10)
-#define SAA_7114_SECAM_WIDTH (720)
-#define SAA_7114_SECAM_HEIGHT (300)
-
-#define SAA_7114_PAL_HSYNC_START (-17)
-#define SAA_7114_PAL_HSYNC_STOP (-32)
-
-#define SAA_7114_PAL_HOFFSET (2)
-#define SAA_7114_PAL_VOFFSET (10)
-#define SAA_7114_PAL_WIDTH (720)
-#define SAA_7114_PAL_HEIGHT (300)
-
-
-
-#define SAA_7114_VERTICAL_CHROMA_OFFSET 0 //0x50504040
-#define SAA_7114_VERTICAL_LUMA_OFFSET 0
-
-#define REG_ADDR(x) (((x) << 1) + 1)
-#define LOBYTE(x) ((unsigned char)((x) & 0xff))
-#define HIBYTE(x) ((unsigned char)(((x) >> 8) & 0xff))
-#define LOWORD(x) ((unsigned short int)((x) & 0xffff))
-#define HIWORD(x) ((unsigned short int)(((x) >> 16) & 0xffff))
-
-
-/* ----------------------------------------------------------------------- */
-
-static inline int saa7114_write(struct i2c_client *client, u8 reg, u8 value)
-{
- return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static int saa7114_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
-{
- int ret = -1;
- u8 reg;
-
- /* the saa7114 has an autoincrement function, use it if
- * the adapter understands raw I2C */
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
- /* do raw I2C, not smbus compatible */
- u8 block_data[32];
- int block_len;
-
- while (len >= 2) {
- block_len = 0;
- block_data[block_len++] = reg = data[0];
- do {
- block_data[block_len++] = data[1];
- reg++;
- len -= 2;
- data += 2;
- } while (len >= 2 && data[0] == reg && block_len < 32);
- ret = i2c_master_send(client, block_data, block_len);
- if (ret < 0)
- break;
- }
- } else {
- /* do some slow I2C emulation kind of thing */
- while (len >= 2) {
- reg = *data++;
- ret = saa7114_write(client, reg, *data++);
- if (ret < 0)
- break;
- len -= 2;
- }
- }
-
- return ret;
-}
-
-static inline int saa7114_read(struct i2c_client *client, u8 reg)
-{
- return i2c_smbus_read_byte_data(client, reg);
-}
-
-/* ----------------------------------------------------------------------- */
-
-// initially set NTSC, composite
-
-
-static const unsigned char init[] = {
- 0x00, 0x00, /* 00 - ID byte , chip version,
- * read only */
- 0x01, 0x08, /* 01 - X,X,X,X, IDEL3 to IDEL0 -
- * horizontal increment delay,
- * recommended position */
- 0x02, 0x00, /* 02 - FUSE=3, GUDL=2, MODE=0 ;
- * input control */
- 0x03, 0x10, /* 03 - HLNRS=0, VBSL=1, WPOFF=0,
- * HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
- 0x04, 0x90, /* 04 - GAI1=256 */
- 0x05, 0x90, /* 05 - GAI2=256 */
- 0x06, SAA_7114_NTSC_HSYNC_START, /* 06 - HSB: hsync start,
- * depends on the video standard */
- 0x07, SAA_7114_NTSC_HSYNC_STOP, /* 07 - HSS: hsync stop, depends
- *on the video standard */
- 0x08, 0xb8, /* 08 - AUFD=1, FSEL=1, EXFIL=0, VTRC=1,
- * HPLL: free running in playback, locked
- * in capture, VNOI=0 */
- 0x09, 0x80, /* 09 - BYPS=0, PREF=0, BPSS=0, VBLB=0,
- * UPTCV=0, APER=1; depends from input */
- 0x0a, 0x80, /* 0a - BRIG=128 */
- 0x0b, 0x44, /* 0b - CONT=1.109 */
- 0x0c, 0x40, /* 0c - SATN=1.0 */
- 0x0d, 0x00, /* 0d - HUE=0 */
- 0x0e, 0x84, /* 0e - CDTO, CSTD2 to 0, DCVF, FCTC,
- * CCOMB; depends from video standard */
- 0x0f, 0x24, /* 0f - ACGC,CGAIN6 to CGAIN0; depends
- * from video standard */
- 0x10, 0x03, /* 10 - OFFU1 to 0, OFFV1 to 0, CHBW,
- * LCBW2 to 0 */
- 0x11, 0x59, /* 11 - COLO, RTP1, HEDL1 to 0, RTP0,
- * YDEL2 to 0 */
- 0x12, 0xc9, /* 12 - RT signal control RTSE13 to 10
- * and 03 to 00 */
- 0x13, 0x80, /* 13 - RT/X port output control */
- 0x14, 0x00, /* 14 - analog, ADC, compatibility control */
- 0x15, 0x00, /* 15 - VGATE start FID change */
- 0x16, 0xfe, /* 16 - VGATE stop */
- 0x17, 0x00, /* 17 - Misc., VGATE MSBs */
- 0x18, 0x40, /* RAWG */
- 0x19, 0x80, /* RAWO */
- 0x1a, 0x00,
- 0x1b, 0x00,
- 0x1c, 0x00,
- 0x1d, 0x00,
- 0x1e, 0x00,
- 0x1f, 0x00, /* status byte, read only */
- 0x20, 0x00, /* video decoder reserved part */
- 0x21, 0x00,
- 0x22, 0x00,
- 0x23, 0x00,
- 0x24, 0x00,
- 0x25, 0x00,
- 0x26, 0x00,
- 0x27, 0x00,
- 0x28, 0x00,
- 0x29, 0x00,
- 0x2a, 0x00,
- 0x2b, 0x00,
- 0x2c, 0x00,
- 0x2d, 0x00,
- 0x2e, 0x00,
- 0x2f, 0x00,
- 0x30, 0xbc, /* audio clock generator */
- 0x31, 0xdf,
- 0x32, 0x02,
- 0x33, 0x00,
- 0x34, 0xcd,
- 0x35, 0xcc,
- 0x36, 0x3a,
- 0x37, 0x00,
- 0x38, 0x03,
- 0x39, 0x10,
- 0x3a, 0x00,
- 0x3b, 0x00,
- 0x3c, 0x00,
- 0x3d, 0x00,
- 0x3e, 0x00,
- 0x3f, 0x00,
- 0x40, 0x00, /* VBI data slicer */
- 0x41, 0xff,
- 0x42, 0xff,
- 0x43, 0xff,
- 0x44, 0xff,
- 0x45, 0xff,
- 0x46, 0xff,
- 0x47, 0xff,
- 0x48, 0xff,
- 0x49, 0xff,
- 0x4a, 0xff,
- 0x4b, 0xff,
- 0x4c, 0xff,
- 0x4d, 0xff,
- 0x4e, 0xff,
- 0x4f, 0xff,
- 0x50, 0xff,
- 0x51, 0xff,
- 0x52, 0xff,
- 0x53, 0xff,
- 0x54, 0xff,
- 0x55, 0xff,
- 0x56, 0xff,
- 0x57, 0xff,
- 0x58, 0x40, // framing code
- 0x59, 0x47, // horizontal offset
- 0x5a, 0x06, // vertical offset
- 0x5b, 0x83, // field offset
- 0x5c, 0x00, // reserved
- 0x5d, 0x3e, // header and data
- 0x5e, 0x00, // sliced data
- 0x5f, 0x00, // reserved
- 0x60, 0x00, /* video decoder reserved part */
- 0x61, 0x00,
- 0x62, 0x00,
- 0x63, 0x00,
- 0x64, 0x00,
- 0x65, 0x00,
- 0x66, 0x00,
- 0x67, 0x00,
- 0x68, 0x00,
- 0x69, 0x00,
- 0x6a, 0x00,
- 0x6b, 0x00,
- 0x6c, 0x00,
- 0x6d, 0x00,
- 0x6e, 0x00,
- 0x6f, 0x00,
- 0x70, 0x00, /* video decoder reserved part */
- 0x71, 0x00,
- 0x72, 0x00,
- 0x73, 0x00,
- 0x74, 0x00,
- 0x75, 0x00,
- 0x76, 0x00,
- 0x77, 0x00,
- 0x78, 0x00,
- 0x79, 0x00,
- 0x7a, 0x00,
- 0x7b, 0x00,
- 0x7c, 0x00,
- 0x7d, 0x00,
- 0x7e, 0x00,
- 0x7f, 0x00,
- 0x80, 0x00, /* X-port, I-port and scaler */
- 0x81, 0x00,
- 0x82, 0x00,
- 0x83, 0x00,
- 0x84, 0xc5,
- 0x85, 0x0d, // hsync and vsync ?
- 0x86, 0x40,
- 0x87, 0x01,
- 0x88, 0x00,
- 0x89, 0x00,
- 0x8a, 0x00,
- 0x8b, 0x00,
- 0x8c, 0x00,
- 0x8d, 0x00,
- 0x8e, 0x00,
- 0x8f, 0x00,
- 0x90, 0x03, /* Task A definition */
- 0x91, 0x08,
- 0x92, 0x00,
- 0x93, 0x40,
- 0x94, 0x00, // window settings
- 0x95, 0x00,
- 0x96, 0x00,
- 0x97, 0x00,
- 0x98, 0x00,
- 0x99, 0x00,
- 0x9a, 0x00,
- 0x9b, 0x00,
- 0x9c, 0x00,
- 0x9d, 0x00,
- 0x9e, 0x00,
- 0x9f, 0x00,
- 0xa0, 0x01, /* horizontal integer prescaling ratio */
- 0xa1, 0x00, /* horizontal prescaler accumulation
- * sequence length */
- 0xa2, 0x00, /* UV FIR filter, Y FIR filter, prescaler
- * DC gain */
- 0xa3, 0x00,
- 0xa4, 0x80, // luminance brightness
- 0xa5, 0x40, // luminance gain
- 0xa6, 0x40, // chrominance saturation
- 0xa7, 0x00,
- 0xa8, 0x00, // horizontal luminance scaling increment
- 0xa9, 0x04,
- 0xaa, 0x00, // horizontal luminance phase offset
- 0xab, 0x00,
- 0xac, 0x00, // horizontal chrominance scaling increment
- 0xad, 0x02,
- 0xae, 0x00, // horizontal chrominance phase offset
- 0xaf, 0x00,
- 0xb0, 0x00, // vertical luminance scaling increment
- 0xb1, 0x04,
- 0xb2, 0x00, // vertical chrominance scaling increment
- 0xb3, 0x04,
- 0xb4, 0x00,
- 0xb5, 0x00,
- 0xb6, 0x00,
- 0xb7, 0x00,
- 0xb8, 0x00,
- 0xb9, 0x00,
- 0xba, 0x00,
- 0xbb, 0x00,
- 0xbc, 0x00,
- 0xbd, 0x00,
- 0xbe, 0x00,
- 0xbf, 0x00,
- 0xc0, 0x02, // Task B definition
- 0xc1, 0x08,
- 0xc2, 0x00,
- 0xc3, 0x40,
- 0xc4, 0x00, // window settings
- 0xc5, 0x00,
- 0xc6, 0x00,
- 0xc7, 0x00,
- 0xc8, 0x00,
- 0xc9, 0x00,
- 0xca, 0x00,
- 0xcb, 0x00,
- 0xcc, 0x00,
- 0xcd, 0x00,
- 0xce, 0x00,
- 0xcf, 0x00,
- 0xd0, 0x01, // horizontal integer prescaling ratio
- 0xd1, 0x00, // horizontal prescaler accumulation sequence length
- 0xd2, 0x00, // UV FIR filter, Y FIR filter, prescaler DC gain
- 0xd3, 0x00,
- 0xd4, 0x80, // luminance brightness
- 0xd5, 0x40, // luminance gain
- 0xd6, 0x40, // chrominance saturation
- 0xd7, 0x00,
- 0xd8, 0x00, // horizontal luminance scaling increment
- 0xd9, 0x04,
- 0xda, 0x00, // horizontal luminance phase offset
- 0xdb, 0x00,
- 0xdc, 0x00, // horizontal chrominance scaling increment
- 0xdd, 0x02,
- 0xde, 0x00, // horizontal chrominance phase offset
- 0xdf, 0x00,
- 0xe0, 0x00, // vertical luminance scaling increment
- 0xe1, 0x04,
- 0xe2, 0x00, // vertical chrominance scaling increment
- 0xe3, 0x04,
- 0xe4, 0x00,
- 0xe5, 0x00,
- 0xe6, 0x00,
- 0xe7, 0x00,
- 0xe8, 0x00,
- 0xe9, 0x00,
- 0xea, 0x00,
- 0xeb, 0x00,
- 0xec, 0x00,
- 0xed, 0x00,
- 0xee, 0x00,
- 0xef, 0x00
-};
-
-static int saa7114_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- struct saa7114 *decoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- //dprintk(1, KERN_INFO "%s: writing init\n", I2C_NAME(client));
- //saa7114_write_block(client, init, sizeof(init));
- break;
-
- case DECODER_DUMP:
- {
- int i;
-
- if (!debug)
- break;
- v4l_info(client, "decoder dump\n");
-
- for (i = 0; i < 32; i += 16) {
- int j;
-
- v4l_info(client, "%03x", i);
- for (j = 0; j < 16; ++j) {
- printk(KERN_CONT " %02x",
- saa7114_read(client, i + j));
- }
- printk(KERN_CONT "\n");
- }
- break;
- }
-
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
-
- v4l_dbg(1, debug, client, "get capabilities\n");
-
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 8;
- cap->outputs = 1;
- break;
- }
-
- case DECODER_GET_STATUS:
- {
- int *iarg = arg;
- int status;
- int res;
-
- status = saa7114_read(client, 0x1f);
-
- v4l_dbg(1, debug, client, "status: 0x%02x\n", status);
- res = 0;
- if ((status & (1 << 6)) == 0) {
- res |= DECODER_STATUS_GOOD;
- }
- switch (decoder->norm) {
- case VIDEO_MODE_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case VIDEO_MODE_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case VIDEO_MODE_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- default:
- case VIDEO_MODE_AUTO:
- if ((status & (1 << 5)) != 0) {
- res |= DECODER_STATUS_NTSC;
- } else {
- res |= DECODER_STATUS_PAL;
- }
- break;
- }
- if ((status & (1 << 0)) != 0) {
- res |= DECODER_STATUS_COLOR;
- }
- *iarg = res;
- break;
- }
-
- case DECODER_SET_NORM:
- {
- int *iarg = arg;
-
- short int hoff = 0, voff = 0, w = 0, h = 0;
-
- v4l_dbg(1, debug, client, "set norm\n");
-
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- v4l_dbg(1, debug, client, "NTSC\n");
- decoder->reg[REG_ADDR(0x06)] =
- SAA_7114_NTSC_HSYNC_START;
- decoder->reg[REG_ADDR(0x07)] =
- SAA_7114_NTSC_HSYNC_STOP;
-
- decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
-
- decoder->reg[REG_ADDR(0x0e)] = 0x85;
- decoder->reg[REG_ADDR(0x0f)] = 0x24;
-
- hoff = SAA_7114_NTSC_HOFFSET;
- voff = SAA_7114_NTSC_VOFFSET;
- w = SAA_7114_NTSC_WIDTH;
- h = SAA_7114_NTSC_HEIGHT;
-
- break;
-
- case VIDEO_MODE_PAL:
- v4l_dbg(1, debug, client, "PAL\n");
- decoder->reg[REG_ADDR(0x06)] =
- SAA_7114_PAL_HSYNC_START;
- decoder->reg[REG_ADDR(0x07)] =
- SAA_7114_PAL_HSYNC_STOP;
-
- decoder->reg[REG_ADDR(0x08)] = decoder->playback ? 0x7c : 0xb8; // PLL free when playback, PLL close when capture
-
- decoder->reg[REG_ADDR(0x0e)] = 0x81;
- decoder->reg[REG_ADDR(0x0f)] = 0x24;
-
- hoff = SAA_7114_PAL_HOFFSET;
- voff = SAA_7114_PAL_VOFFSET;
- w = SAA_7114_PAL_WIDTH;
- h = SAA_7114_PAL_HEIGHT;
-
- break;
-
- default:
- v4l_dbg(1, debug, client, "Unknown video mode\n");
- return -EINVAL;
- }
-
-
- decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
-
- decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
-
-
- saa7114_write(client, 0x80, 0x06); // i-port and scaler back end clock selection, task A&B off
- saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
-
- saa7114_write_block(client, decoder->reg + (0x06 << 1),
- 3 << 1);
- saa7114_write_block(client, decoder->reg + (0x0e << 1),
- 2 << 1);
- saa7114_write_block(client, decoder->reg + (0x5a << 1),
- 2 << 1);
-
- saa7114_write_block(client, decoder->reg + (0x94 << 1),
- (0x9f + 1 - 0x94) << 1);
- saa7114_write_block(client, decoder->reg + (0xc4 << 1),
- (0xcf + 1 - 0xc4) << 1);
-
- saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
- saa7114_write(client, 0x80, 0x36); // i-port and scaler back end clock selection
-
- decoder->norm = *iarg;
- break;
- }
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set input (%d)\n", *iarg);
- if (*iarg < 0 || *iarg > 7) {
- return -EINVAL;
- }
-
- if (decoder->input != *iarg) {
- v4l_dbg(1, debug, client, "now setting %s input\n",
- *iarg >= 6 ? "S-Video" : "Composite");
- decoder->input = *iarg;
-
- /* select mode */
- decoder->reg[REG_ADDR(0x02)] =
- (decoder->
- reg[REG_ADDR(0x02)] & 0xf0) | (decoder->
- input <
- 6 ? 0x0 : 0x9);
- saa7114_write(client, 0x02,
- decoder->reg[REG_ADDR(0x02)]);
-
- /* bypass chrominance trap for modes 6..9 */
- decoder->reg[REG_ADDR(0x09)] =
- (decoder->
- reg[REG_ADDR(0x09)] & 0x7f) | (decoder->
- input <
- 6 ? 0x0 :
- 0x80);
- saa7114_write(client, 0x09,
- decoder->reg[REG_ADDR(0x09)]);
-
- decoder->reg[REG_ADDR(0x0e)] =
- decoder->input <
- 6 ? decoder->
- reg[REG_ADDR(0x0e)] | 1 : decoder->
- reg[REG_ADDR(0x0e)] & ~1;
- saa7114_write(client, 0x0e,
- decoder->reg[REG_ADDR(0x0e)]);
- }
- break;
- }
-
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- v4l_dbg(1, debug, client, "set output\n");
-
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
- break;
- }
-
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- int enable = (*iarg != 0);
-
- v4l_dbg(1, debug, client, "%s output\n",
- enable ? "enable" : "disable");
-
- decoder->playback = !enable;
-
- if (decoder->enable != enable) {
- decoder->enable = enable;
-
- /* RJ: If output should be disabled (for
- * playing videos), we also need a open PLL.
- * The input is set to 0 (where no input
- * source is connected), although this
- * is not necessary.
- *
- * If output should be enabled, we have to
- * reverse the above.
- */
-
- if (decoder->enable) {
- decoder->reg[REG_ADDR(0x08)] = 0xb8;
- decoder->reg[REG_ADDR(0x12)] = 0xc9;
- decoder->reg[REG_ADDR(0x13)] = 0x80;
- decoder->reg[REG_ADDR(0x87)] = 0x01;
- } else {
- decoder->reg[REG_ADDR(0x08)] = 0x7c;
- decoder->reg[REG_ADDR(0x12)] = 0x00;
- decoder->reg[REG_ADDR(0x13)] = 0x00;
- decoder->reg[REG_ADDR(0x87)] = 0x00;
- }
-
- saa7114_write_block(client,
- decoder->reg + (0x12 << 1),
- 2 << 1);
- saa7114_write(client, 0x08,
- decoder->reg[REG_ADDR(0x08)]);
- 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, 0x80, 0x36);
-
- }
- break;
- }
-
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
-
- v4l_dbg(1, debug, client,
- "decoder set picture bright=%d contrast=%d saturation=%d hue=%d\n",
- pic->brightness, pic->contrast, pic->colour, pic->hue);
-
- if (decoder->bright != pic->brightness) {
- /* We want 0 to 255 we get 0-65535 */
- decoder->bright = pic->brightness;
- saa7114_write(client, 0x0a, decoder->bright >> 8);
- }
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->contrast = pic->contrast;
- saa7114_write(client, 0x0b,
- decoder->contrast >> 9);
- }
- if (decoder->sat != pic->colour) {
- /* We want 0 to 127 we get 0-65535 */
- decoder->sat = pic->colour;
- saa7114_write(client, 0x0c, decoder->sat >> 9);
- }
- if (decoder->hue != pic->hue) {
- /* We want -128 to 127 we get 0-65535 */
- decoder->hue = pic->hue;
- saa7114_write(client, 0x0d,
- (decoder->hue - 32768) >> 8);
- }
- break;
- }
-
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static unsigned short normal_i2c[] = { 0x42 >> 1, 0x40 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
-static int saa7114_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- int i, err[30];
- short int hoff = SAA_7114_NTSC_HOFFSET;
- short int voff = SAA_7114_NTSC_VOFFSET;
- short int w = SAA_7114_NTSC_WIDTH;
- short int h = SAA_7114_NTSC_HEIGHT;
- struct saa7114 *decoder;
-
- /* Check if the adapter supports the needed features */
- if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
- return -ENODEV;
-
- v4l_info(client, "chip found @ 0x%x (%s)\n",
- client->addr << 1, client->adapter->name);
-
- decoder = kzalloc(sizeof(struct saa7114), GFP_KERNEL);
- if (decoder == NULL)
- return -ENOMEM;
- decoder->norm = VIDEO_MODE_NTSC;
- decoder->input = -1;
- decoder->enable = 1;
- decoder->bright = 32768;
- decoder->contrast = 32768;
- decoder->hue = 32768;
- decoder->sat = 32768;
- decoder->playback = 0; // initially capture mode useda
- i2c_set_clientdata(client, decoder);
-
- memcpy(decoder->reg, init, sizeof(init));
-
- decoder->reg[REG_ADDR(0x94)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0x95)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0x96)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0x97)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0x98)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0x99)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0x9a)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0x9b)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0x9c)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0x9d)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0x9e)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0x9f)] = HIBYTE(h) & 0x0f; // out height high
-
- decoder->reg[REG_ADDR(0xc4)] = LOBYTE(hoff); // hoffset low
- decoder->reg[REG_ADDR(0xc5)] = HIBYTE(hoff) & 0x0f; // hoffset high
- decoder->reg[REG_ADDR(0xc6)] = LOBYTE(w); // width low
- decoder->reg[REG_ADDR(0xc7)] = HIBYTE(w) & 0x0f; // width high
- decoder->reg[REG_ADDR(0xc8)] = LOBYTE(voff); // voffset low
- decoder->reg[REG_ADDR(0xc9)] = HIBYTE(voff) & 0x0f; // voffset high
- decoder->reg[REG_ADDR(0xca)] = LOBYTE(h + 2); // height low
- decoder->reg[REG_ADDR(0xcb)] = HIBYTE(h + 2) & 0x0f; // height high
- decoder->reg[REG_ADDR(0xcc)] = LOBYTE(w); // out width low
- decoder->reg[REG_ADDR(0xcd)] = HIBYTE(w) & 0x0f; // out width high
- decoder->reg[REG_ADDR(0xce)] = LOBYTE(h); // out height low
- decoder->reg[REG_ADDR(0xcf)] = HIBYTE(h) & 0x0f; // out height high
-
- decoder->reg[REG_ADDR(0xb8)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xb9)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xba)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xbb)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-
- decoder->reg[REG_ADDR(0xbc)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xbd)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xbe)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xbf)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-
- decoder->reg[REG_ADDR(0xe8)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xe9)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xea)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
- decoder->reg[REG_ADDR(0xeb)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_CHROMA_OFFSET));
-
- decoder->reg[REG_ADDR(0xec)] =
- LOBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xed)] =
- HIBYTE(LOWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xee)] =
- LOBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
- decoder->reg[REG_ADDR(0xef)] =
- HIBYTE(HIWORD(SAA_7114_VERTICAL_LUMA_OFFSET));
-
-
- decoder->reg[REG_ADDR(0x13)] = 0x80; // RTC0 on
- decoder->reg[REG_ADDR(0x87)] = 0x01; // I-Port
- decoder->reg[REG_ADDR(0x12)] = 0xc9; // RTS0
-
- decoder->reg[REG_ADDR(0x02)] = 0xc0; // set composite1 input, aveasy
- decoder->reg[REG_ADDR(0x09)] = 0x00; // chrominance trap
- decoder->reg[REG_ADDR(0x0e)] |= 1; // combfilter on
-
-
- v4l_dbg(1, debug, client, "starting init\n");
-
- err[0] =
- saa7114_write_block(client, decoder->reg + (0x20 << 1),
- 0x10 << 1);
- err[1] =
- saa7114_write_block(client, decoder->reg + (0x30 << 1),
- 0x10 << 1);
- err[2] =
- saa7114_write_block(client, decoder->reg + (0x63 << 1),
- (0x7f + 1 - 0x63) << 1);
- err[3] =
- saa7114_write_block(client, decoder->reg + (0x89 << 1),
- 6 << 1);
- err[4] =
- saa7114_write_block(client, decoder->reg + (0xb8 << 1),
- 8 << 1);
- err[5] =
- saa7114_write_block(client, decoder->reg + (0xe8 << 1),
- 8 << 1);
-
-
- for (i = 0; i <= 5; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- for (i = 6; i < 8; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
- v4l_dbg(1, debug, client,
- "performing decoder reset sequence\n");
-
- err[6] = saa7114_write(client, 0x80, 0x06); // i-port and scaler backend clock selection, task A&B off
- err[7] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- err[8] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
-
- for (i = 6; i <= 8; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- v4l_dbg(1, debug, client, "performing the rest of init\n");
-
- err[9] = saa7114_write(client, 0x01, decoder->reg[REG_ADDR(0x01)]);
- err[10] = saa7114_write_block(client, decoder->reg + (0x03 << 1), (0x1e + 1 - 0x03) << 1); // big seq
- err[11] = saa7114_write_block(client, decoder->reg + (0x40 << 1), (0x5f + 1 - 0x40) << 1); // slicer
- err[12] = saa7114_write_block(client, decoder->reg + (0x81 << 1), 2 << 1); // ?
- err[13] = saa7114_write_block(client, decoder->reg + (0x83 << 1), 5 << 1); // ?
- err[14] = saa7114_write_block(client, decoder->reg + (0x90 << 1), 4 << 1); // Task A
- err[15] =
- saa7114_write_block(client, decoder->reg + (0x94 << 1),
- 12 << 1);
- err[16] =
- saa7114_write_block(client, decoder->reg + (0xa0 << 1),
- 8 << 1);
- err[17] =
- saa7114_write_block(client, decoder->reg + (0xa8 << 1),
- 8 << 1);
- err[18] =
- saa7114_write_block(client, decoder->reg + (0xb0 << 1),
- 8 << 1);
- err[19] = saa7114_write_block(client, decoder->reg + (0xc0 << 1), 4 << 1); // Task B
- err[15] =
- saa7114_write_block(client, decoder->reg + (0xc4 << 1),
- 12 << 1);
- err[16] =
- saa7114_write_block(client, decoder->reg + (0xd0 << 1),
- 8 << 1);
- err[17] =
- saa7114_write_block(client, decoder->reg + (0xd8 << 1),
- 8 << 1);
- err[18] =
- saa7114_write_block(client, decoder->reg + (0xe0 << 1),
- 8 << 1);
-
- for (i = 9; i <= 18; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
-
- for (i = 6; i < 8; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
-
- for (i = 0x11; i <= 0x13; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
-
- v4l_dbg(1, debug, client, "setting video input\n");
-
- err[19] =
- saa7114_write(client, 0x02, decoder->reg[REG_ADDR(0x02)]);
- err[20] =
- saa7114_write(client, 0x09, decoder->reg[REG_ADDR(0x09)]);
- err[21] =
- saa7114_write(client, 0x0e, decoder->reg[REG_ADDR(0x0e)]);
-
- for (i = 19; i <= 21; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- v4l_dbg(1, debug, client, "performing decoder reset sequence\n");
-
- err[22] = saa7114_write(client, 0x88, 0xd8); // sw reset scaler
- err[23] = saa7114_write(client, 0x88, 0xf8); // sw reset scaler release
- err[24] = saa7114_write(client, 0x80, 0x36); // i-port and scaler backend clock selection, task A&B off
-
-
- for (i = 22; i <= 24; i++) {
- if (err[i] < 0) {
- v4l_dbg(1, debug, client,
- "init error %d at stage %d, leaving attach.\n",
- i, err[i]);
- kfree(decoder);
- return -EIO;
- }
- }
-
- err[25] = saa7114_write(client, 0x06, init[REG_ADDR(0x06)]);
- err[26] = saa7114_write(client, 0x07, init[REG_ADDR(0x07)]);
- err[27] = saa7114_write(client, 0x10, init[REG_ADDR(0x10)]);
-
- v4l_dbg(1, debug, client, "chip version %x, decoder status 0x%02x\n",
- saa7114_read(client, 0x00) >> 4,
- saa7114_read(client, 0x1f));
- v4l_dbg(1, debug, client,
- "power save control: 0x%02x, scaler status: 0x%02x\n",
- saa7114_read(client, 0x88),
- saa7114_read(client, 0x8f));
-
-
- for (i = 0x94; i < 0x96; i++) {
- v4l_dbg(1, debug, client,
- "reg[0x%02x] = 0x%02x (0x%02x)\n",
- i, saa7114_read(client, i),
- decoder->reg[REG_ADDR(i)]);
- }
-
- //i = saa7114_write_block(client, init, sizeof(init));
- return 0;
-}
-
-static int saa7114_remove(struct i2c_client *client)
-{
- kfree(i2c_get_clientdata(client));
- return 0;
-}
-
-/* ----------------------------------------------------------------------- */
-
-static const struct i2c_device_id saa7114_id[] = {
- { "saa7114_old", 0 }, /* "saa7114" maps to the saa7115 driver */
- { }
-};
-MODULE_DEVICE_TABLE(i2c, saa7114_id);
-
-static struct v4l2_i2c_driver_data v4l2_i2c_data = {
- .name = "saa7114",
- .driverid = I2C_DRIVERID_SAA7114,
- .command = saa7114_command,
- .probe = saa7114_probe,
- .remove = saa7114_remove,
- .id_table = saa7114_id,
-};
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 46c796c3fec..cebf159f52c 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -778,7 +778,7 @@ static int saa711x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -931,8 +931,8 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
/* Prevent unnecessary standard changes. During a standard
change the I-Port is temporarily disabled. Any devices
reading from that port can get confused.
- Note that VIDIOC_S_STD is also used to switch from
- radio to TV mode, so if a VIDIOC_S_STD is broadcast to
+ Note that s_std is also used to switch from
+ radio to TV mode, so if a s_std is broadcast to
all I2C devices then you do not want to have an unwanted
side-effect here. */
if (std == state->std)
@@ -1206,10 +1206,12 @@ static int saa711x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
default:
return -EINVAL;
}
@@ -1308,11 +1310,12 @@ static int saa711x_s_stream(struct v4l2_subdev *sd, int enable)
v4l2_dbg(1, debug, sd, "%s output\n",
enable ? "enable" : "disable");
- if (state->enable != enable) {
- state->enable = enable;
- saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED,
- state->enable);
- }
+ if (state->enable == enable)
+ return 0;
+ state->enable = enable;
+ if (!saa711x_has_reg(state->ident, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED))
+ return 0;
+ saa711x_write(sd, R_87_I_PORT_I_O_ENA_OUT_CLK_AND_GATED, state->enable);
return 0;
}
@@ -1370,6 +1373,47 @@ static int saa711x_g_vbi_data(struct v4l2_subdev *sd, struct v4l2_sliced_vbi_dat
}
}
+static int saa711x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ struct saa711x_state *state = to_state(sd);
+ int reg1e;
+
+ *std = V4L2_STD_ALL;
+ if (state->ident != V4L2_IDENT_SAA7115)
+ return 0;
+ reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
+
+ switch (reg1e & 0x03) {
+ case 1:
+ *std = V4L2_STD_NTSC;
+ break;
+ case 2:
+ *std = V4L2_STD_PAL;
+ break;
+ case 3:
+ *std = V4L2_STD_SECAM;
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int saa711x_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ struct saa711x_state *state = to_state(sd);
+ int reg1e = 0x80;
+ int reg1f;
+
+ *status = V4L2_IN_ST_NO_SIGNAL;
+ if (state->ident == V4L2_IDENT_SAA7115)
+ reg1e = saa711x_read(sd, R_1E_STATUS_BYTE_1_VD_DEC);
+ reg1f = saa711x_read(sd, R_1F_STATUS_BYTE_2_VD_DEC);
+ if ((reg1f & 0xc1) == 0x81 && (reg1e & 0xc0) == 0x80)
+ *status = 0;
+ return 0;
+}
+
#ifdef CONFIG_VIDEO_ADV_DEBUG
static int saa711x_g_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
{
@@ -1493,6 +1537,8 @@ static const struct v4l2_subdev_video_ops saa711x_video_ops = {
.g_vbi_data = saa711x_g_vbi_data,
.decode_vbi_line = saa711x_decode_vbi_line,
.s_stream = saa711x_s_stream,
+ .querystd = saa711x_querystd,
+ .g_input_status = saa711x_g_input_status,
};
static const struct v4l2_subdev_ops saa711x_ops = {
diff --git a/drivers/media/video/saa7127.c b/drivers/media/video/saa7127.c
index 05221d47dd4..128bb8b8dbb 100644
--- a/drivers/media/video/saa7127.c
+++ b/drivers/media/video/saa7127.c
@@ -810,7 +810,6 @@ MODULE_DEVICE_TABLE(i2c, saa7127_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7127",
- .driverid = I2C_DRIVERID_SAA7127,
.probe = saa7127_probe,
.remove = saa7127_remove,
.id_table = saa7127_id,
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index fc2164e28e7..0ba68987bfc 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -6,6 +6,7 @@ config VIDEO_SAA7134
select VIDEO_TUNER
select VIDEO_TVEEPROM
select CRC32
+ select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for Philips SAA713x based
TV cards.
@@ -35,8 +36,16 @@ config VIDEO_SAA7134_DVB
select DVB_TDA10086 if !DVB_FE_CUSTOMISE
select DVB_TDA826X if !DVB_FE_CUSTOMISE
select DVB_ISL6421 if !DVB_FE_CUSTOMISE
- select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMIZE
- select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
+ select DVB_ISL6405 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA827X if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
+ select DVB_ZL10036 if !DVB_FE_CUSTOMISE
+ select DVB_MT312 if !DVB_FE_CUSTOMISE
+ select DVB_LNBP21 if !DVB_FE_CUSTOMISE
+ select DVB_ZL10353 if !DVB_FE_CUSTOMISE
+ select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+ select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
+ select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
---help---
This adds support for DVB cards based on the
Philips saa7134 chip.
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c
index 1fee6e84a51..dc2213e2f86 100644
--- a/drivers/media/video/saa7134/saa6752hs.c
+++ b/drivers/media/video/saa7134/saa6752hs.c
@@ -33,9 +33,10 @@
#include <linux/i2c.h>
#include <linux/types.h>
#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <linux/init.h>
#include <linux/crc32.h>
@@ -44,10 +45,6 @@
#define MPEG_TOTAL_TARGET_BITRATE_MAX 27000
#define MPEG_PID_MAX ((1 << 14) - 1)
-/* Addresses to scan */
-static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
-
-I2C_CLIENT_INSMOD;
MODULE_DESCRIPTION("device driver for saa6752hs MPEG2 encoder");
MODULE_AUTHOR("Andrew de Quincey");
@@ -95,6 +92,7 @@ static const struct v4l2_format v4l2_format_table[] =
};
struct saa6752hs_state {
+ struct v4l2_subdev sd;
int chip;
u32 revision;
int has_ac3;
@@ -115,6 +113,11 @@ enum saa6752hs_command {
SAA6752HS_COMMAND_MAX
};
+static inline struct saa6752hs_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa6752hs_state, sd);
+}
+
/* ---------------------------------------------------------------------- */
static u8 PAT[] = {
@@ -360,185 +363,191 @@ static int saa6752hs_set_bitrate(struct i2c_client *client,
return 0;
}
-static void saa6752hs_set_subsampling(struct i2c_client *client,
- struct v4l2_format *f)
-{
- struct saa6752hs_state *h = i2c_get_clientdata(client);
- int dist_352, dist_480, dist_720;
-
- /*
- FIXME: translate and round width/height into EMPRESS
- subsample type:
- type | PAL | NTSC
- ---------------------------
- SIF | 352x288 | 352x240
- 1/2 D1 | 352x576 | 352x480
- 2/3 D1 | 480x576 | 480x480
- D1 | 720x576 | 720x480
- */
-
- dist_352 = abs(f->fmt.pix.width - 352);
- dist_480 = abs(f->fmt.pix.width - 480);
- dist_720 = abs(f->fmt.pix.width - 720);
- if (dist_720 < dist_480) {
- f->fmt.pix.width = 720;
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_D1;
- }
- else if (dist_480 < dist_352) {
- f->fmt.pix.width = 480;
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_2_3_D1;
- }
- else {
- f->fmt.pix.width = 352;
- if (abs(f->fmt.pix.height - 576) <
- abs(f->fmt.pix.height - 288)) {
- f->fmt.pix.height = 576;
- h->video_format = SAA6752HS_VF_1_2_D1;
- }
- else {
- f->fmt.pix.height = 288;
- h->video_format = SAA6752HS_VF_SIF;
- }
+static int get_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
+ struct v4l2_ext_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ ctrl->value = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ ctrl->value = params->ts_pid_pmt;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ ctrl->value = params->ts_pid_audio;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ ctrl->value = params->ts_pid_video;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ ctrl->value = params->ts_pid_pcr;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ ctrl->value = params->au_encoding;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ ctrl->value = params->au_l2_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (!has_ac3)
+ return -EINVAL;
+ ctrl->value = params->au_ac3_bitrate;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ ctrl->value = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ ctrl->value = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ ctrl->value = params->vi_aspect;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ ctrl->value = params->vi_bitrate * 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ ctrl->value = params->vi_bitrate_peak * 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ ctrl->value = params->vi_bitrate_mode;
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
}
-
static int handle_ctrl(int has_ac3, struct saa6752hs_mpeg_params *params,
- struct v4l2_ext_control *ctrl, unsigned int cmd)
+ struct v4l2_ext_control *ctrl, int set)
{
int old = 0, new;
- int set = (cmd == VIDIOC_S_EXT_CTRLS);
new = ctrl->value;
switch (ctrl->id) {
- case V4L2_CID_MPEG_STREAM_TYPE:
- old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- old = params->ts_pid_pmt;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pmt = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- old = params->ts_pid_audio;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_audio = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- old = params->ts_pid_video;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_video = new;
- break;
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- old = params->ts_pid_pcr;
- if (set && new > MPEG_PID_MAX)
- return -ERANGE;
- if (new > MPEG_PID_MAX)
- new = MPEG_PID_MAX;
- params->ts_pid_pcr = new;
- break;
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- old = params->au_encoding;
- if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
- (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- old = params->au_l2_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
- params->au_l2_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- if (!has_ac3)
- return -EINVAL;
- old = params->au_ac3_bitrate;
- if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
- new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
- return -ERANGE;
- if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
- else
- new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
- params->au_ac3_bitrate = new;
- break;
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
- if (set && new != old)
- return -ERANGE;
- new = old;
- break;
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- old = params->vi_aspect;
- if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
- new != V4L2_MPEG_VIDEO_ASPECT_4x3)
- return -ERANGE;
- if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
- new = V4L2_MPEG_VIDEO_ASPECT_4x3;
- params->vi_aspect = new;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- old = params->vi_bitrate * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- old = params->vi_bitrate_peak * 1000;
- new = 1000 * (new / 1000);
- if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- return -ERANGE;
- if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
- new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
- params->vi_bitrate_peak = new / 1000;
- break;
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- old = params->vi_bitrate_mode;
- params->vi_bitrate_mode = new;
- break;
- default:
+ case V4L2_CID_MPEG_STREAM_TYPE:
+ old = V4L2_MPEG_STREAM_TYPE_MPEG2_TS;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PMT:
+ old = params->ts_pid_pmt;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_pmt = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ old = params->ts_pid_audio;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_audio = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ old = params->ts_pid_video;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_video = new;
+ break;
+ case V4L2_CID_MPEG_STREAM_PID_PCR:
+ old = params->ts_pid_pcr;
+ if (set && new > MPEG_PID_MAX)
+ return -ERANGE;
+ if (new > MPEG_PID_MAX)
+ new = MPEG_PID_MAX;
+ params->ts_pid_pcr = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_ENCODING:
+ old = params->au_encoding;
+ if (set && new != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
+ (!has_ac3 || new != V4L2_MPEG_AUDIO_ENCODING_AC3))
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
+ old = params->au_l2_bitrate;
+ if (set && new != V4L2_MPEG_AUDIO_L2_BITRATE_256K &&
+ new != V4L2_MPEG_AUDIO_L2_BITRATE_384K)
+ return -ERANGE;
+ if (new <= V4L2_MPEG_AUDIO_L2_BITRATE_256K)
+ new = V4L2_MPEG_AUDIO_L2_BITRATE_256K;
+ else
+ new = V4L2_MPEG_AUDIO_L2_BITRATE_384K;
+ params->au_l2_bitrate = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
+ if (!has_ac3)
return -EINVAL;
+ old = params->au_ac3_bitrate;
+ if (set && new != V4L2_MPEG_AUDIO_AC3_BITRATE_256K &&
+ new != V4L2_MPEG_AUDIO_AC3_BITRATE_384K)
+ return -ERANGE;
+ if (new <= V4L2_MPEG_AUDIO_AC3_BITRATE_256K)
+ new = V4L2_MPEG_AUDIO_AC3_BITRATE_256K;
+ else
+ new = V4L2_MPEG_AUDIO_AC3_BITRATE_384K;
+ params->au_ac3_bitrate = new;
+ break;
+ case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
+ old = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ENCODING:
+ old = V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
+ if (set && new != old)
+ return -ERANGE;
+ new = old;
+ break;
+ case V4L2_CID_MPEG_VIDEO_ASPECT:
+ old = params->vi_aspect;
+ if (set && new != V4L2_MPEG_VIDEO_ASPECT_16x9 &&
+ new != V4L2_MPEG_VIDEO_ASPECT_4x3)
+ return -ERANGE;
+ if (new != V4L2_MPEG_VIDEO_ASPECT_16x9)
+ new = V4L2_MPEG_VIDEO_ASPECT_4x3;
+ params->vi_aspect = new;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE:
+ old = params->vi_bitrate * 1000;
+ new = 1000 * (new / 1000);
+ if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ return -ERANGE;
+ if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+ params->vi_bitrate = new / 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
+ old = params->vi_bitrate_peak * 1000;
+ new = 1000 * (new / 1000);
+ if (set && new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ return -ERANGE;
+ if (new > MPEG_VIDEO_TARGET_BITRATE_MAX * 1000)
+ new = MPEG_VIDEO_TARGET_BITRATE_MAX * 1000;
+ params->vi_bitrate_peak = new / 1000;
+ break;
+ case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ old = params->vi_bitrate_mode;
+ params->vi_bitrate_mode = new;
+ break;
+ default:
+ return -EINVAL;
}
- if (cmd == VIDIOC_G_EXT_CTRLS)
- ctrl->value = old;
- else
- ctrl->value = new;
+ ctrl->value = new;
return 0;
}
-static int saa6752hs_qctrl(struct saa6752hs_state *h,
- struct v4l2_queryctrl *qctrl)
+
+static int saa6752hs_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
{
+ struct saa6752hs_state *h = to_state(sd);
struct saa6752hs_mpeg_params *params = &h->params;
int err;
@@ -583,7 +592,7 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
V4L2_MPEG_VIDEO_ASPECT_4x3);
case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
if (err == 0 &&
params->vi_bitrate_mode ==
V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
@@ -597,12 +606,20 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
V4L2_MPEG_STREAM_TYPE_MPEG2_TS);
case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
+ return v4l2_ctrl_query_fill(qctrl,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
+ V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
case V4L2_CID_MPEG_VIDEO_BITRATE:
+ return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
case V4L2_CID_MPEG_STREAM_PID_PMT:
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
case V4L2_CID_MPEG_STREAM_PID_AUDIO:
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
case V4L2_CID_MPEG_STREAM_PID_VIDEO:
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
case V4L2_CID_MPEG_STREAM_PID_PCR:
- return v4l2_ctrl_query_fill_std(qctrl);
+ return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
default:
break;
@@ -610,8 +627,7 @@ static int saa6752hs_qctrl(struct saa6752hs_state *h,
return -EINVAL;
}
-static int saa6752hs_qmenu(struct saa6752hs_state *h,
- struct v4l2_querymenu *qmenu)
+static int saa6752hs_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qmenu)
{
static const u32 mpeg_audio_encoding[] = {
V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
@@ -632,11 +648,12 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
V4L2_MPEG_AUDIO_AC3_BITRATE_384K,
V4L2_CTRL_MENU_IDS_END
};
+ struct saa6752hs_state *h = to_state(sd);
struct v4l2_queryctrl qctrl;
int err;
qctrl.id = qmenu->id;
- err = saa6752hs_qctrl(h, &qctrl);
+ err = saa6752hs_queryctrl(sd, &qctrl);
if (err)
return err;
switch (qmenu->id) {
@@ -656,17 +673,16 @@ static int saa6752hs_qmenu(struct saa6752hs_state *h,
return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL);
}
-static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
+static int saa6752hs_init(struct v4l2_subdev *sd, u32 leading_null_bytes)
{
unsigned char buf[9], buf2[4];
- struct saa6752hs_state *h;
+ struct saa6752hs_state *h = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
unsigned size;
u32 crc;
unsigned char localPAT[256];
unsigned char localPMT[256];
- h = i2c_get_clientdata(client);
-
/* Set video format - must be done first as it resets other settings */
set_reg8(client, 0x41, h->video_format);
@@ -762,7 +778,7 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
buf[3] = 0x82;
buf[4] = 0xB0;
buf[5] = buf2[0];
- switch(h->params.vi_aspect) {
+ switch (h->params.vi_aspect) {
case V4L2_MPEG_VIDEO_ASPECT_16x9:
buf[6] = buf2[1] | 0x40;
break;
@@ -770,7 +786,6 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
default:
buf[6] = buf2[1] & 0xBF;
break;
- break;
}
buf[7] = buf2[2];
buf[8] = buf2[3];
@@ -779,81 +794,162 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes)
return 0;
}
-static int
-saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg)
+static int saa6752hs_do_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls, int set)
{
- struct saa6752hs_state *h = i2c_get_clientdata(client);
- struct v4l2_ext_controls *ctrls = arg;
+ struct saa6752hs_state *h = to_state(sd);
struct saa6752hs_mpeg_params params;
- int err = 0;
int i;
- switch (cmd) {
- case VIDIOC_INT_INIT:
- /* apply settings and start encoder */
- saa6752hs_init(client, *(u32 *)arg);
- break;
- case VIDIOC_S_EXT_CTRLS:
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- /* fall through */
- case VIDIOC_TRY_EXT_CTRLS:
- case VIDIOC_G_EXT_CTRLS:
- if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
- return -EINVAL;
- params = h->params;
- for (i = 0; i < ctrls->count; i++) {
- err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, cmd);
- if (err) {
- ctrls->error_idx = i;
- return err;
- }
+ if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ params = h->params;
+ for (i = 0; i < ctrls->count; i++) {
+ int err = handle_ctrl(h->has_ac3, &params, ctrls->controls + i, set);
+
+ if (err) {
+ ctrls->error_idx = i;
+ return err;
}
- h->params = params;
- break;
- case VIDIOC_QUERYCTRL:
- return saa6752hs_qctrl(h, arg);
- case VIDIOC_QUERYMENU:
- return saa6752hs_qmenu(h, arg);
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *f = arg;
-
- if (h->video_format == SAA6752HS_VF_UNKNOWN)
- h->video_format = SAA6752HS_VF_D1;
- f->fmt.pix.width =
- v4l2_format_table[h->video_format].fmt.pix.width;
- f->fmt.pix.height =
- v4l2_format_table[h->video_format].fmt.pix.height;
- break ;
}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *f = arg;
+ if (set)
+ h->params = params;
+ return 0;
+}
- saa6752hs_set_subsampling(client, f);
- break;
+static int saa6752hs_s_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ return saa6752hs_do_ext_ctrls(sd, ctrls, 1);
+}
+
+static int saa6752hs_try_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ return saa6752hs_do_ext_ctrls(sd, ctrls, 0);
+}
+
+static int saa6752hs_g_ext_ctrls(struct v4l2_subdev *sd, struct v4l2_ext_controls *ctrls)
+{
+ struct saa6752hs_state *h = to_state(sd);
+ int i;
+
+ if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
+ return -EINVAL;
+
+ for (i = 0; i < ctrls->count; i++) {
+ int err = get_ctrl(h->has_ac3, &h->params, ctrls->controls + i);
+
+ if (err) {
+ ctrls->error_idx = i;
+ return err;
+ }
}
- case VIDIOC_S_STD:
- h->standard = *((v4l2_std_id *) arg);
- break;
+ return 0;
+}
- case VIDIOC_DBG_G_CHIP_IDENT:
- return v4l2_chip_ident_i2c_client(client,
- arg, h->chip, h->revision);
+static int saa6752hs_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+ struct saa6752hs_state *h = to_state(sd);
- default:
- /* nothing */
- break;
+ if (h->video_format == SAA6752HS_VF_UNKNOWN)
+ h->video_format = SAA6752HS_VF_D1;
+ f->fmt.pix.width =
+ v4l2_format_table[h->video_format].fmt.pix.width;
+ f->fmt.pix.height =
+ v4l2_format_table[h->video_format].fmt.pix.height;
+ return 0;
+}
+
+static int saa6752hs_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
+{
+ struct saa6752hs_state *h = to_state(sd);
+ int dist_352, dist_480, dist_720;
+
+ /*
+ FIXME: translate and round width/height into EMPRESS
+ subsample type:
+
+ type | PAL | NTSC
+ ---------------------------
+ SIF | 352x288 | 352x240
+ 1/2 D1 | 352x576 | 352x480
+ 2/3 D1 | 480x576 | 480x480
+ D1 | 720x576 | 720x480
+ */
+
+ dist_352 = abs(f->fmt.pix.width - 352);
+ dist_480 = abs(f->fmt.pix.width - 480);
+ dist_720 = abs(f->fmt.pix.width - 720);
+ if (dist_720 < dist_480) {
+ f->fmt.pix.width = 720;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_D1;
+ } else if (dist_480 < dist_352) {
+ f->fmt.pix.width = 480;
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_2_3_D1;
+ } else {
+ f->fmt.pix.width = 352;
+ if (abs(f->fmt.pix.height - 576) <
+ abs(f->fmt.pix.height - 288)) {
+ f->fmt.pix.height = 576;
+ h->video_format = SAA6752HS_VF_1_2_D1;
+ } else {
+ f->fmt.pix.height = 288;
+ h->video_format = SAA6752HS_VF_SIF;
+ }
}
+ return 0;
+}
+
+static int saa6752hs_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct saa6752hs_state *h = to_state(sd);
+
+ h->standard = std;
+ return 0;
+}
- return err;
+static int saa6752hs_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa6752hs_state *h = to_state(sd);
+
+ return v4l2_chip_ident_i2c_client(client,
+ chip, h->chip, h->revision);
}
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops saa6752hs_core_ops = {
+ .g_chip_ident = saa6752hs_g_chip_ident,
+ .init = saa6752hs_init,
+ .queryctrl = saa6752hs_queryctrl,
+ .querymenu = saa6752hs_querymenu,
+ .g_ext_ctrls = saa6752hs_g_ext_ctrls,
+ .s_ext_ctrls = saa6752hs_s_ext_ctrls,
+ .try_ext_ctrls = saa6752hs_try_ext_ctrls,
+};
+
+static const struct v4l2_subdev_tuner_ops saa6752hs_tuner_ops = {
+ .s_std = saa6752hs_s_std,
+};
+
+static const struct v4l2_subdev_video_ops saa6752hs_video_ops = {
+ .s_fmt = saa6752hs_s_fmt,
+ .g_fmt = saa6752hs_g_fmt,
+};
+
+static const struct v4l2_subdev_ops saa6752hs_ops = {
+ .core = &saa6752hs_core_ops,
+ .tuner = &saa6752hs_tuner_ops,
+ .video = &saa6752hs_video_ops,
+};
+
static int saa6752hs_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+ const struct i2c_device_id *id)
{
struct saa6752hs_state *h = kzalloc(sizeof(*h), GFP_KERNEL);
+ struct v4l2_subdev *sd;
u8 addr = 0x13;
u8 data[12];
@@ -861,6 +957,8 @@ static int saa6752hs_probe(struct i2c_client *client,
client->addr << 1, client->adapter->name);
if (h == NULL)
return -ENOMEM;
+ sd = &h->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa6752hs_ops);
i2c_master_send(client, &addr, 1);
i2c_master_recv(client, data, sizeof(data));
@@ -874,14 +972,15 @@ static int saa6752hs_probe(struct i2c_client *client,
}
h->params = param_defaults;
h->standard = 0; /* Assume 625 input lines */
-
- i2c_set_clientdata(client, h);
return 0;
}
static int saa6752hs_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
return 0;
}
@@ -893,8 +992,6 @@ MODULE_DEVICE_TABLE(i2c, saa6752hs_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa6752hs",
- .driverid = I2C_DRIVERID_SAA6752HS,
- .command = saa6752hs_command,
.probe = saa6752hs_probe,
.remove = saa6752hs_remove,
.id_table = saa6752hs_id,
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index e2febcd6e52..a790a7246a6 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -31,6 +31,7 @@
#include <media/v4l2-common.h>
#include <media/tveeprom.h>
#include "tea5767.h"
+#include "tda18271.h"
/* commly used strings */
static char name_mute[] = "mute";
@@ -272,6 +273,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
@@ -408,6 +410,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x820000,
.inputs = {{
@@ -818,6 +821,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
.vmux = 4,
@@ -977,6 +981,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
.vmux = 1,
@@ -1699,6 +1704,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -2364,6 +2370,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x21,
.inputs = {{
.name = "Composite 0",
.vmux = 0,
@@ -3291,6 +3298,68 @@ struct saa7134_board saa7134_boards[] = {
.gpio = 0x0200100,
},
},
+ [SAA7134_BOARD_HAUPPAUGE_HVR1120] = {
+ .name = "Hauppauge WinTV-HVR1120 ATSC/QAM-Hybrid",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tuner_config = 3,
+ .mpeg = SAA7134_MPEG_DVB,
+ .ts_type = SAA7134_MPEG_TS_SERIAL,
+ .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x0000100,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0800100, /* GPIO 23 HI for FM */
+ },
+ },
+ [SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
+ .name = "Hauppauge WinTV-HVR1110r3",
+ .audio_clock = 0x00187de7,
+ .tuner_type = TUNER_PHILIPS_TDA8290,
+ .radio_type = UNSET,
+ .tuner_addr = ADDR_UNSET,
+ .radio_addr = ADDR_UNSET,
+ .tuner_config = 3,
+ .gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
+ .inputs = {{
+ .name = name_tv,
+ .vmux = 1,
+ .amux = TV,
+ .tv = 1,
+ .gpio = 0x0000100,
+ }, {
+ .name = name_comp1,
+ .vmux = 3,
+ .amux = LINE1,
+ }, {
+ .name = name_svideo,
+ .vmux = 8,
+ .amux = LINE1,
+ } },
+ .radio = {
+ .name = name_radio,
+ .amux = TV,
+ .gpio = 0x0800100, /* GPIO 23 HI for FM */
+ },
+ },
[SAA7134_BOARD_CINERGY_HT_PCMCIA] = {
.name = "Terratec Cinergy HT PCMCIA",
.audio_clock = 0x00187de7,
@@ -4070,6 +4139,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4106,6 +4176,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4143,6 +4214,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4323,13 +4395,13 @@ struct saa7134_board saa7134_boards[] = {
.amux = TV,
.tv = 1,
}, {
- .name = name_comp,
- .vmux = 0,
+ .name = name_comp1,
+ .vmux = 3,
.amux = LINE1,
}, {
.name = name_svideo,
.vmux = 8,
- .amux = LINE1,
+ .amux = LINE2,
} },
.radio = {
.name = name_radio,
@@ -4421,8 +4493,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* no DVB support for now */
- /* .mpeg = SAA7134_MPEG_DVB, */
+ .mpeg = SAA7134_MPEG_DVB,
.inputs = { {
.name = name_comp,
.vmux = 1,
@@ -4441,8 +4512,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- /* no DVB support for now */
- /* .mpeg = SAA7134_MPEG_DVB, */
+ .mpeg = SAA7134_MPEG_DVB,
.inputs = { {
.name = name_comp,
.vmux = 1,
@@ -4611,7 +4681,7 @@ struct saa7134_board saa7134_boards[] = {
.tuner_type = TUNER_YMEC_TVF_5533MF,
.radio_type = TUNER_TEA5767,
.tuner_addr = ADDR_UNSET,
- .radio_addr = ADDR_UNSET,
+ .radio_addr = 0x60,
.gpiomask = 0x80000700,
.inputs = { {
.name = name_tv,
@@ -5405,6 +5475,36 @@ struct pci_device_id saa7134_pci_tbl[] = {
},{
.vendor = PCI_VENDOR_ID_PHILIPS,
.device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6706,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6707,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6708,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1120,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x6709,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
+ .subvendor = 0x0070,
+ .subdevice = 0x670a,
+ .driver_data = SAA7134_BOARD_HAUPPAUGE_HVR1110R3,
+ },{
+ .vendor = PCI_VENDOR_ID_PHILIPS,
+ .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
.subvendor = 0x153b,
.subdevice = 0x1172,
.driver_data = SAA7134_BOARD_CINERGY_HT_PCMCIA,
@@ -5821,8 +5921,8 @@ static int saa7134_xc2028_callback(struct saa7134_dev *dev,
}
-static int saa7134_tda8290_callback(struct saa7134_dev *dev,
- int command, int arg)
+static int saa7134_tda8290_827x_callback(struct saa7134_dev *dev,
+ int command, int arg)
{
u8 sync_control;
@@ -5848,6 +5948,65 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
return 0;
}
+static inline int saa7134_tda18271_hvr11x0_toggle_agc(struct saa7134_dev *dev,
+ enum tda18271_mode mode)
+{
+ /* toggle AGC switch through GPIO 26 */
+ switch (mode) {
+ case TDA18271_ANALOG:
+ saa7134_set_gpio(dev, 26, 0);
+ break;
+ case TDA18271_DIGITAL:
+ saa7134_set_gpio(dev, 26, 1);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
+ int command, int arg)
+{
+ int ret = 0;
+
+ switch (command) {
+ case TDA18271_CALLBACK_CMD_AGC_ENABLE: /* 0 */
+ switch (dev->board) {
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ ret = saa7134_tda18271_hvr11x0_toggle_agc(dev, arg);
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int saa7134_tda8290_callback(struct saa7134_dev *dev,
+ int command, int arg)
+{
+ int ret;
+
+ switch (dev->board) {
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ /* tda8290 + tda18271 */
+ ret = saa7134_tda8290_18271_callback(dev, command, arg);
+ break;
+ default:
+ /* tda8290 + tda827x */
+ ret = saa7134_tda8290_827x_callback(dev, command, arg);
+ break;
+ }
+ return ret;
+}
+
int saa7134_tuner_callback(void *priv, int component, int command, int arg)
{
struct saa7134_dev *dev = priv;
@@ -5878,11 +6037,16 @@ static void hauppauge_eeprom(struct saa7134_dev *dev, u8 *eeprom_data)
switch (tv.model) {
case 67019: /* WinTV-HVR1110 (Retail, IR Blaster, hybrid, FM, SVid/Comp, 3.5mm audio in) */
case 67109: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
+ case 67201: /* WinTV-HVR1120 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
+ case 67301: /* WinTV-HVR1000 (Retail, IR Receive, analog, no FM, SVid/Comp, 3.5mm audio in) */
+ case 67209: /* WinTV-HVR1110 (Retail, IR Receive, hybrid, FM, SVid/Comp, 3.5mm audio in) */
case 67559: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
case 67569: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM) */
case 67579: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM) */
case 67589: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
case 67599: /* WinTV-HVR1110 (OEM, no IR, hybrid, no FM, SVid/Comp, RCA aud) */
+ case 67651: /* WinTV-HVR1120 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
+ case 67659: /* WinTV-HVR1110 (OEM, no IR, hybrid, FM, SVid/Comp, RCA aud) */
break;
default:
printk(KERN_WARNING "%s: warning: "
@@ -6019,6 +6183,11 @@ int saa7134_board_init1(struct saa7134_dev *dev)
msleep(10);
break;
case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ saa7134_set_gpio(dev, 23, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 23, 1);
+ dev->has_remote = SAA7134_REMOTE_I2C;
+ break;
case SAA7134_BOARD_AVERMEDIA_M103:
saa7134_set_gpio(dev, 23, 0);
msleep(10);
@@ -6054,6 +6223,16 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_writeb (SAA7134_PRODUCTION_TEST_MODE, 0x00);
break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ /* GPIO 26 high for digital, low for analog */
+ saa7134_set_gpio(dev, 26, 0);
+ msleep(1);
+
+ saa7134_set_gpio(dev, 22, 0);
+ msleep(10);
+ saa7134_set_gpio(dev, 22, 1);
+ break;
/* i2c remotes */
case SAA7134_BOARD_PINNACLE_PCTV_110i:
case SAA7134_BOARD_PINNACLE_PCTV_310i:
@@ -6079,15 +6258,15 @@ int saa7134_board_init1(struct saa7134_dev *dev)
saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x8c040007, 0x8c040007);
saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x0c0007cd, 0x0c0007cd);
break;
- case SAA7134_BOARD_AVERMEDIA_A700_PRO:
case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
- /* write windows gpio values */
- saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
- saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
printk("%s: %s: hybrid analog/dvb card\n"
- "%s: Sorry, only analog s-video and composite input "
+ "%s: Sorry, of the analog inputs, only analog s-video and composite "
"are supported for now.\n",
dev->name, card(dev).name, dev->name);
+ case SAA7134_BOARD_AVERMEDIA_A700_PRO:
+ /* write windows gpio values */
+ saa_andorl(SAA7134_GPIO_GPMODE0 >> 2, 0x80040100, 0x80040100);
+ saa_andorl(SAA7134_GPIO_GPSTATUS0 >> 2, 0x80040100, 0x00040100);
break;
}
return 0;
@@ -6109,7 +6288,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tun_setup.mode_mask = T_RADIO;
- saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ saa_call_all(dev, tuner, s_type_addr, &tun_setup);
mode_mask &= ~T_RADIO;
}
@@ -6121,7 +6300,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tun_setup.mode_mask = mode_mask;
- saa7134_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ saa_call_all(dev, tuner, s_type_addr, &tun_setup);
}
if (dev->tda9887_conf) {
@@ -6130,8 +6309,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &dev->tda9887_conf;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
}
if (dev->tuner_type == TUNER_XC2028) {
@@ -6158,7 +6336,7 @@ static void saa7134_tuner_setup(struct saa7134_dev *dev)
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+ saa_call_all(dev, tuner, s_config, &xc2028_cfg);
}
}
@@ -6168,9 +6346,20 @@ int saa7134_board_init2(struct saa7134_dev *dev)
unsigned char buf;
int board;
+ /* Put here the code that enables the chips that are needed
+ for analog mode and doesn't depend on the tuner attachment.
+ It is also a good idea to get tuner type from eeprom, etc before
+ initializing tuner, since we can avoid loading tuner driver
+ on devices that has TUNER_ABSENT
+ */
switch (dev->board) {
case SAA7134_BOARD_BMK_MPEX_NOTUNER:
case SAA7134_BOARD_BMK_MPEX_TUNER:
+ /* Checks if the device has a tuner at 0x60 addr
+ If the device doesn't have a tuner, TUNER_ABSENT
+ will be used at tuner_type, avoiding loading tuner
+ without needing it
+ */
dev->i2c_client.addr = 0x60;
board = (i2c_master_recv(&dev->i2c_client, &buf, 0) < 0)
? SAA7134_BOARD_BMK_MPEX_NOTUNER
@@ -6188,11 +6377,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
u8 subaddr;
u8 data[3];
int ret, tuner_t;
-
struct i2c_msg msg[] = {{.addr=0x50, .flags=0, .buf=&subaddr, .len = 1},
{.addr=0x50, .flags=I2C_M_RD, .buf=data, .len = 3}};
+
subaddr= 0x14;
tuner_t = 0;
+
+ /* Retrieve device data from eeprom, checking for the
+ proper tuner_type.
+ */
ret = i2c_transfer(&dev->i2c_adap, msg, 2);
if (ret != 2) {
printk(KERN_ERR "EEPROM read failure\n");
@@ -6248,12 +6441,14 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name, saa7134_boards[dev->board].name);
break;
}
+ /* break intentionally omitted */
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_ASUS_EUROPA2_HYBRID:
{
- /* The Philips EUROPA based hybrid boards have the tuner connected through
- * the channel decoder. We have to make it transparent to find it
+ /* The Philips EUROPA based hybrid boards have the tuner
+ connected through the channel decoder. We have to make it
+ transparent to find it
*/
u8 data[] = { 0x07, 0x02};
struct i2c_msg msg = {.addr=0x08, .flags=0, .buf=data, .len = sizeof(data)};
@@ -6274,21 +6469,15 @@ int saa7134_board_init2(struct saa7134_dev *dev)
if (dev->board == SAA7134_BOARD_PHILIPS_TIGER_S) {
dev->tuner_type = TUNER_PHILIPS_TDA8290;
- saa7134_tuner_setup(dev);
-
data[2] = 0x68;
i2c_transfer(&dev->i2c_adap, &msg, 1);
-
- /* Tuner setup is handled before I2C transfer.
- Due to that, there's no need to do it later
- */
- return 0;
+ break;
}
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ASUSTeK_TVFM7135:
- /* The card below is detected as card=53, but is different */
+ case SAA7134_BOARD_ASUSTeK_TVFM7135:
+ /* The card below is detected as card=53, but is different */
if (dev->autodetected && (dev->eedata[0x27] == 0x03)) {
dev->board = SAA7134_BOARD_ASUSTeK_P7131_ANALOG;
printk(KERN_INFO "%s: P7131 analog only, using "
@@ -6296,6 +6485,10 @@ int saa7134_board_init2(struct saa7134_dev *dev)
dev->name, saa7134_boards[dev->board].name);
}
break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ hauppauge_eeprom(dev, dev->eedata+0x80);
+ break;
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
hauppauge_eeprom(dev, dev->eedata+0x80);
/* break intentionally omitted */
@@ -6351,22 +6544,6 @@ int saa7134_board_init2(struct saa7134_dev *dev)
i2c_transfer(&dev->i2c_adap, &msg, 1);
break;
}
- case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
- case SAA7134_BOARD_KWORLD_ATSC110:
- {
- /* enable tuner */
- int i;
- static const u8 buffer [] = { 0x10, 0x12, 0x13, 0x04, 0x16,
- 0x00, 0x14, 0x04, 0x17, 0x00 };
- dev->i2c_client.addr = 0x0a;
- for (i = 0; i < 5; i++)
- if (2 != i2c_master_send(&dev->i2c_client,
- &buffer[i*2], 2))
- printk(KERN_WARNING
- "%s: Unable to enable tuner(%i).\n",
- dev->name, i);
- break;
- }
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
/* The T200 and the T200A share the same pci id. Consequently,
@@ -6375,9 +6552,9 @@ int saa7134_board_init2(struct saa7134_dev *dev)
/* Don't do this if the board was specifically selected with an
* insmod option or if we have the default configuration T200*/
- if(!dev->autodetected || (dev->eedata[0x41] == 0xd0))
+ if (!dev->autodetected || (dev->eedata[0x41] == 0xd0))
break;
- if(dev->eedata[0x41] == 0x02) {
+ if (dev->eedata[0x41] == 0x02) {
/* Reconfigure board as T200A */
dev->board = SAA7134_BOARD_VIDEOMATE_DVBT_200A;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
@@ -6390,6 +6567,58 @@ int saa7134_board_init2(struct saa7134_dev *dev)
break;
}
break;
+ case SAA7134_BOARD_ADS_INSTANT_HDTV_PCI:
+ case SAA7134_BOARD_KWORLD_ATSC110:
+ {
+ struct i2c_msg msg = { .addr = 0x0a, .flags = 0 };
+ int i;
+ static u8 buffer[][2] = {
+ { 0x10, 0x12 },
+ { 0x13, 0x04 },
+ { 0x16, 0x00 },
+ { 0x14, 0x04 },
+ { 0x17, 0x00 },
+ };
+
+ for (i = 0; i < ARRAY_SIZE(buffer); i++) {
+ msg.buf = &buffer[i][0];
+ msg.len = ARRAY_SIZE(buffer[0]);
+ if (i2c_transfer(&dev->i2c_adap, &msg, 1) != 1)
+ printk(KERN_WARNING
+ "%s: Unable to enable tuner(%i).\n",
+ dev->name, i);
+ }
+ break;
+ }
+ } /* switch() */
+
+ /* initialize tuner */
+ if (TUNER_ABSENT != dev->tuner_type) {
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+ /* Note: radio tuner address is always filled in,
+ so we do not need to probe for a radio tuner device. */
+ if (dev->radio_type != UNSET)
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->radio_addr);
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == ADDR_UNSET) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+ } else {
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ }
+ }
+
+ saa7134_tuner_setup(dev);
+
+ switch (dev->board) {
case SAA7134_BOARD_BEHOLD_COLUMBUS_TVFM:
{
struct v4l2_priv_tun_config tea5767_cfg;
@@ -6401,12 +6630,10 @@ int saa7134_board_init2(struct saa7134_dev *dev)
ctl.xtal_freq = TEA5767_HIGH_LO_13MHz;
tea5767_cfg.tuner = TUNER_TEA5767;
tea5767_cfg.priv = &ctl;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tea5767_cfg);
+ saa_call_all(dev, tuner, s_config, &tea5767_cfg);
break;
}
} /* switch() */
- saa7134_tuner_setup(dev);
-
return 0;
}
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 99221d726ed..dafa0d88bed 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -54,13 +54,9 @@ static unsigned int gpio_tracking;
module_param(gpio_tracking, int, 0644);
MODULE_PARM_DESC(gpio_tracking,"enable debug messages [gpio]");
-static unsigned int alsa;
+static unsigned int alsa = 1;
module_param(alsa, int, 0644);
-MODULE_PARM_DESC(alsa,"enable ALSA DMA sound [dmasound]");
-
-static unsigned int oss;
-module_param(oss, int, 0644);
-MODULE_PARM_DESC(oss,"enable OSS DMA sound [dmasound]");
+MODULE_PARM_DESC(alsa,"enable/disable ALSA DMA sound [dmasound]");
static unsigned int latency = UNSET;
module_param(latency, int, 0444);
@@ -90,8 +86,10 @@ MODULE_PARM_DESC(radio_nr, "radio device number");
MODULE_PARM_DESC(tuner, "tuner type");
MODULE_PARM_DESC(card, "card type");
-static DEFINE_MUTEX(devlist_lock);
+DEFINE_MUTEX(saa7134_devlist_lock);
+EXPORT_SYMBOL(saa7134_devlist_lock);
LIST_HEAD(saa7134_devlist);
+EXPORT_SYMBOL(saa7134_devlist);
static LIST_HEAD(mops_list);
static unsigned int saa7134_devcount;
@@ -156,10 +154,10 @@ static void request_module_async(struct work_struct *work){
request_module("saa7134-empress");
if (card_is_dvb(dev))
request_module("saa7134-dvb");
- if (alsa)
- request_module("saa7134-alsa");
- if (oss)
- request_module("saa7134-oss");
+ if (alsa) {
+ if (dev->pci->device != PCI_DEVICE_ID_PHILIPS_SAA7130)
+ request_module("saa7134-alsa");
+ }
}
static void request_submodules(struct saa7134_dev *dev)
@@ -778,7 +776,7 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
return NULL;
*vfd = *template;
vfd->minor = -1;
- vfd->parent = &dev->pci->dev;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
@@ -851,6 +849,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
if (NULL == dev)
return -ENOMEM;
+ err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+ if (err)
+ goto fail0;
+
/* pci init */
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
@@ -927,6 +929,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
dev->autodetected = card[dev->nr] != dev->board;
dev->tuner_type = saa7134_boards[dev->board].tuner_type;
dev->tuner_addr = saa7134_boards[dev->board].tuner_addr;
+ dev->radio_type = saa7134_boards[dev->board].radio_type;
+ dev->radio_addr = saa7134_boards[dev->board].radio_addr;
dev->tda9887_conf = saa7134_boards[dev->board].tda9887_conf;
if (UNSET != tuner[dev->nr])
dev->tuner_type = tuner[dev->nr];
@@ -971,23 +975,48 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* wait a bit, register i2c bus */
msleep(100);
saa7134_i2c_register(dev);
-
- /* initialize hardware #2 */
- if (TUNER_ABSENT != dev->tuner_type)
- request_module("tuner");
saa7134_board_init2(dev);
saa7134_hwinit2(dev);
/* load i2c helpers */
if (card_is_empress(dev)) {
- request_module("saa6752hs");
+ struct v4l2_subdev *sd =
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "saa6752hs", "saa6752hs",
+ saa7134_boards[dev->board].empress_addr);
+
+ if (sd)
+ sd->grp_id = GRP_EMPRESS;
+ }
+
+ if (saa7134_boards[dev->board].rds_addr) {
+ unsigned short addrs[2] = { 0, I2C_CLIENT_END };
+ struct v4l2_subdev *sd;
+
+ addrs[0] = saa7134_boards[dev->board].rds_addr;
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "saa6588",
+ "saa6588", addrs);
+ if (sd)
+ printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
}
request_submodules(dev);
v4l2_prio_init(&dev->prio);
+ mutex_lock(&saa7134_devlist_lock);
+ list_for_each_entry(mops, &mops_list, next)
+ mpeg_ops_attach(mops, dev);
+ list_add_tail(&dev->devlist, &saa7134_devlist);
+ mutex_unlock(&saa7134_devlist_lock);
+
+ /* check for signal */
+ saa7134_irq_video_signalchange(dev);
+
+ if (TUNER_ABSENT != dev->tuner_type)
+ saa_call_all(dev, core, s_standby, 0);
+
/* register v4l devices */
if (saa7134_no_overlay > 0)
printk(KERN_INFO "%s: Overlay support disabled.\n", dev->name);
@@ -1023,24 +1052,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
}
/* everything worked */
- pci_set_drvdata(pci_dev,dev);
saa7134_devcount++;
- mutex_lock(&devlist_lock);
- list_for_each_entry(mops, &mops_list, next)
- mpeg_ops_attach(mops, dev);
- list_add_tail(&dev->devlist,&saa7134_devlist);
- mutex_unlock(&devlist_lock);
-
- /* check for signal */
- saa7134_irq_video_signalchange(dev);
-
- if (saa7134_dmasound_init && !dev->dmasound.priv_data) {
+ if (saa7134_dmasound_init && !dev->dmasound.priv_data)
saa7134_dmasound_init(dev);
- }
-
- if (TUNER_ABSENT != dev->tuner_type)
- saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
return 0;
@@ -1055,13 +1070,16 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
fail1:
+ v4l2_device_unregister(&dev->v4l2_dev);
+ fail0:
kfree(dev);
return err;
}
static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
{
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
struct saa7134_mpeg_ops *mops;
/* Release DMA sound modules if present */
@@ -1088,11 +1106,11 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
saa7134_hwfini(dev);
/* unregister */
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&dev->devlist);
list_for_each_entry(mops, &mops_list, next)
mpeg_ops_detach(mops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
saa7134_devcount--;
saa7134_i2c_unregister(dev);
@@ -1113,7 +1131,8 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev)
release_mem_region(pci_resource_start(pci_dev,0),
pci_resource_len(pci_dev,0));
- pci_set_drvdata(pci_dev, NULL);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
/* free memory */
kfree(dev);
@@ -1148,8 +1167,8 @@ static int saa7134_buffer_requeue(struct saa7134_dev *dev,
static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
{
-
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
/* disable overlay - apps should enable it explicitly on resume*/
dev->ovenable = 0;
@@ -1185,7 +1204,8 @@ static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state)
static int saa7134_resume(struct pci_dev *pci_dev)
{
- struct saa7134_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev);
unsigned long flags;
pci_set_power_state(pci_dev, PCI_D0);
@@ -1247,11 +1267,11 @@ int saa7134_ts_register(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_attach(ops, dev);
list_add_tail(&ops->next,&mops_list);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
return 0;
}
@@ -1259,11 +1279,11 @@ void saa7134_ts_unregister(struct saa7134_mpeg_ops *ops)
{
struct saa7134_dev *dev;
- mutex_lock(&devlist_lock);
+ mutex_lock(&saa7134_devlist_lock);
list_del(&ops->next);
list_for_each_entry(dev, &saa7134_devlist, devlist)
mpeg_ops_detach(ops, dev);
- mutex_unlock(&devlist_lock);
+ mutex_unlock(&saa7134_devlist_lock);
}
EXPORT_SYMBOL(saa7134_ts_register);
@@ -1307,8 +1327,6 @@ module_exit(saa7134_fini);
/* ----------------------------------------------------------- */
EXPORT_SYMBOL(saa7134_set_gpio);
-EXPORT_SYMBOL(saa7134_i2c_call_clients);
-EXPORT_SYMBOL(saa7134_devlist);
EXPORT_SYMBOL(saa7134_boards);
/* ----------------- for the DMA sound modules --------------- */
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index b5370b3e1a3..4eff1ca8593 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -48,9 +48,15 @@
#include "isl6405.h"
#include "lnbp21.h"
#include "tuner-simple.h"
+#include "tda18271.h"
+#include "lgdt3305.h"
+#include "tda8290.h"
#include "zl10353.h"
+#include "zl10036.h"
+#include "mt312.h"
+
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
MODULE_LICENSE("GPL");
@@ -189,7 +195,7 @@ static int mt352_pinnacle_tuner_set_params(struct dvb_frontend* fe,
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
i2c_transfer(&dev->i2c_adap, &msg, 1);
- saa7134_i2c_call_clients(dev,VIDIOC_S_FREQUENCY,&f);
+ saa_call_all(dev, tuner, s_frequency, &f);
msg.buf = on;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
@@ -950,6 +956,45 @@ static struct nxt200x_config kworldatsc110 = {
.demod_address = 0x0a,
};
+/* ------------------------------------------------------------------ */
+
+static struct mt312_config avertv_a700_mt312 = {
+ .demod_address = 0x0e,
+ .voltage_inverted = 1,
+};
+
+static struct zl10036_config avertv_a700_tuner = {
+ .tuner_address = 0x60,
+};
+
+static struct lgdt3305_config hcw_lgdt3305_config = {
+ .i2c_addr = 0x0e,
+ .mpeg_mode = LGDT3305_MPEG_SERIAL,
+ .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
+ .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 1,
+ .qam_if_khz = 4000,
+ .vsb_if_khz = 3250,
+};
+
+static struct tda18271_std_map hauppauge_tda18271_std_map = {
+ .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
+ .if_lvl = 1, .rfagc_top = 0x58, },
+ .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
+ .if_lvl = 1, .rfagc_top = 0x58, },
+};
+
+static struct tda18271_config hcw_tda18271_config = {
+ .std_map = &hauppauge_tda18271_std_map,
+ .gate = TDA18271_GATE_ANALOG,
+ .config = 3,
+};
+
+static struct tda829x_config tda829x_no_probe = {
+ .probe_tuner = TDA829X_DONT_PROBE,
+};
+
/* ==================================================================
* Core code
*/
@@ -1076,6 +1121,19 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_1) < 0)
goto dettach_frontend;
break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1120:
+ fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
+ &hcw_lgdt3305_config,
+ &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
+ dvb_attach(tda829x_attach, fe0->dvb.frontend,
+ &dev->i2c_adap, 0x4b,
+ &tda829x_no_probe);
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_adap,
+ &hcw_tda18271_config);
+ }
+ break;
case SAA7134_BOARD_ASUSTeK_P7131_DUAL:
if (configure_tda827x_fe(dev, &asus_p7131_dual_config,
&tda827x_cfg_0) < 0)
@@ -1376,6 +1434,19 @@ static int dvb_init(struct saa7134_dev *dev)
TUNER_PHILIPS_FMD1216ME_MK3);
}
break;
+ case SAA7134_BOARD_AVERMEDIA_A700_PRO:
+ case SAA7134_BOARD_AVERMEDIA_A700_HYBRID:
+ /* Zarlink ZL10313 */
+ fe0->dvb.frontend = dvb_attach(mt312_attach,
+ &avertv_a700_mt312, &dev->i2c_adap);
+ if (fe0->dvb.frontend) {
+ if (dvb_attach(zl10036_attach, fe0->dvb.frontend,
+ &avertv_a700_tuner, &dev->i2c_adap) == NULL) {
+ wprintk("%s: No zl10036 found!\n",
+ __func__);
+ }
+ }
+ break;
default:
wprintk("Huh? unknown DVB card?\n");
break;
@@ -1449,7 +1520,7 @@ static int dvb_fini(struct saa7134_dev *dev)
tda9887_cfg.priv = &on;
/* otherwise we don't detect the tuner on next insmod */
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG, &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
} else if (dev->board == SAA7134_BOARD_MEDION_MD8800_QUADRO) {
if ((dev->eedata[2] == 0x07) && use_frontend) {
/* turn off the 2nd lnb supply */
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index c9d8beb87a6..9db3472667e 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -76,7 +76,7 @@ static int ts_init_encoder(struct saa7134_dev* dev)
break;
}
ts_reset_encoder(dev);
- saa7134_i2c_call_clients(dev, VIDIOC_INT_INIT, &leading_null_bytes);
+ saa_call_all(dev, core, init, leading_null_bytes);
dev->empress_started = 1;
return 0;
}
@@ -234,7 +234,7 @@ static int empress_g_fmt_vid_cap(struct file *file, void *priv,
{
struct saa7134_dev *dev = file->private_data;
- saa7134_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ saa_call_all(dev, video, g_fmt, f);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -247,7 +247,7 @@ static int empress_s_fmt_vid_cap(struct file *file, void *priv,
{
struct saa7134_dev *dev = file->private_data;
- saa7134_i2c_call_clients(dev, VIDIOC_S_FMT, f);
+ saa_call_all(dev, video, s_fmt, f);
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets;
@@ -317,7 +317,7 @@ static int empress_s_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- err = saa7134_i2c_call_saa6752(dev, VIDIOC_S_EXT_CTRLS, ctrls);
+ err = saa_call_empress(dev, core, s_ext_ctrls, ctrls);
ts_init_encoder(dev);
return err;
@@ -330,7 +330,7 @@ static int empress_g_ext_ctrls(struct file *file, void *priv,
if (ctrls->ctrl_class != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- return saa7134_i2c_call_saa6752(dev, VIDIOC_G_EXT_CTRLS, ctrls);
+ return saa_call_empress(dev, core, g_ext_ctrls, ctrls);
}
static int empress_g_ctrl(struct file *file, void *priv,
@@ -352,6 +352,7 @@ static int empress_s_ctrl(struct file *file, void *priv,
static int empress_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *c)
{
+ /* Must be sorted from low to high control ID! */
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
@@ -364,6 +365,7 @@ static int empress_queryctrl(struct file *file, void *priv,
0
};
+ /* Must be sorted from low to high control ID! */
static const u32 mpeg_ctrls[] = {
V4L2_CID_MPEG_CLASS,
V4L2_CID_MPEG_STREAM_TYPE,
@@ -388,10 +390,10 @@ static int empress_queryctrl(struct file *file, void *priv,
if (c->id == 0)
return -EINVAL;
if (c->id == V4L2_CID_USER_CLASS || c->id == V4L2_CID_MPEG_CLASS)
- return v4l2_ctrl_query_fill_std(c);
+ return v4l2_ctrl_query_fill(c, 0, 0, 0, 0);
if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
return saa7134_queryctrl(file, priv, c);
- return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYCTRL, c);
+ return saa_call_empress(dev, core, queryctrl, c);
}
static int empress_querymenu(struct file *file, void *priv,
@@ -401,7 +403,7 @@ static int empress_querymenu(struct file *file, void *priv,
if (V4L2_CTRL_ID2CLASS(c->id) != V4L2_CTRL_CLASS_MPEG)
return -EINVAL;
- return saa7134_i2c_call_saa6752(dev, VIDIOC_QUERYMENU, c);
+ return saa_call_empress(dev, core, querymenu, c);
}
static int empress_g_chip_ident(struct file *file, void *fh,
@@ -411,14 +413,11 @@ static int empress_g_chip_ident(struct file *file, void *fh,
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- if (dev->mpeg_i2c_client == NULL)
- return -EINVAL;
if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
!strcmp(chip->match.name, "saa6752hs"))
- return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
- if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR &&
- chip->match.addr == dev->mpeg_i2c_client->addr)
- return saa7134_i2c_call_saa6752(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+ return saa_call_empress(dev, core, g_chip_ident, chip);
+ if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
+ return saa_call_empress(dev, core, g_chip_ident, chip);
return -EINVAL;
}
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 20c1b33caf7..f3e285aa2fb 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -255,7 +255,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
addr = msgs[i].addr << 1;
if (msgs[i].flags & I2C_M_RD)
addr |= 1;
- if (i > 0 && msgs[i].flags & I2C_M_RD) {
+ if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) {
/* workaround for a saa7134 i2c bug
* needed to talk to the mt352 demux
* thanks to pinnacle for the hint */
@@ -327,8 +327,6 @@ static int attach_inform(struct i2c_client *client)
d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
client->driver->driver.name, client->addr, client->name);
- if (client->addr == 0x20 && client->driver && client->driver->command)
- dev->mpeg_i2c_client = client;
/* Am I an i2c remote control? */
@@ -357,7 +355,6 @@ static struct i2c_algorithm saa7134_algo = {
static struct i2c_adapter saa7134_adap_template = {
.owner = THIS_MODULE,
- .class = I2C_CLASS_TV_ANALOG,
.name = "saa7134",
.id = I2C_HW_SAA7134,
.algo = &saa7134_algo,
@@ -421,29 +418,13 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
}
}
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
- unsigned int cmd, void *arg)
-{
- BUG_ON(NULL == dev->i2c_adap.algo_data);
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
- unsigned int cmd, void *arg)
-{
- if (dev->mpeg_i2c_client == NULL)
- return -EINVAL;
- return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client,
- cmd, arg);
-}
-EXPORT_SYMBOL_GPL(saa7134_i2c_call_saa6752);
-
int saa7134_i2c_register(struct saa7134_dev *dev)
{
dev->i2c_adap = saa7134_adap_template;
dev->i2c_adap.dev.parent = &dev->pci->dev;
strcpy(dev->i2c_adap.name,dev->name);
dev->i2c_adap.algo_data = dev;
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&dev->i2c_adap);
dev->i2c_client = saa7134_client_template;
diff --git a/drivers/media/video/saa7134/saa7134-ts.c b/drivers/media/video/saa7134/saa7134-ts.c
index ef55a59f0cd..cc8b923afbc 100644
--- a/drivers/media/video/saa7134/saa7134-ts.c
+++ b/drivers/media/video/saa7134/saa7134-ts.c
@@ -79,8 +79,19 @@ static int buffer_activate(struct saa7134_dev *dev,
saa_writeb(SAA7134_TS_SERIAL1, 0x00);
/* Start TS stream */
- saa_writeb(SAA7134_TS_SERIAL0, 0x40);
- saa_writeb(SAA7134_TS_PARALLEL, 0xEC);
+ switch (saa7134_boards[dev->board].ts_type) {
+ case SAA7134_MPEG_TS_PARALLEL:
+ saa_writeb(SAA7134_TS_SERIAL0, 0x40);
+ saa_writeb(SAA7134_TS_PARALLEL, 0xec);
+ break;
+ case SAA7134_MPEG_TS_SERIAL:
+ saa_writeb(SAA7134_TS_SERIAL0, 0xd8);
+ saa_writeb(SAA7134_TS_PARALLEL, 0x6c);
+ saa_writeb(SAA7134_TS_PARALLEL_SERIAL, 0xbc);
+ saa_writeb(SAA7134_TS_SERIAL1, 0x02);
+ break;
+ }
+
dev->ts_state = SAA7134_TS_STARTED;
}
diff --git a/drivers/media/video/saa7134/saa7134-video.c b/drivers/media/video/saa7134/saa7134-video.c
index a1f7e351f57..404f70eeb35 100644
--- a/drivers/media/video/saa7134/saa7134-video.c
+++ b/drivers/media/video/saa7134/saa7134-video.c
@@ -30,11 +30,7 @@
#include "saa7134-reg.h"
#include "saa7134.h"
#include <media/v4l2-common.h>
-
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
+#include <media/rds.h>
/* ------------------------------------------------------------------ */
@@ -452,6 +448,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset odd field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -459,6 +456,7 @@ static const struct v4l2_queryctrl video_ctrls[] = {
.name = "y offset even field",
.minimum = 0,
.maximum = 128,
+ .step = 1,
.default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},{
@@ -627,10 +625,10 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev)
saa7134_set_decoder(dev);
if (card_in(dev, dev->ctl_input).tv)
- saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+ saa_call_all(dev, tuner, s_std, dev->tvnorm->id);
/* Set the correct norm for the saa6752hs. This function
does nothing if there is no saa6752hs. */
- saa7134_i2c_call_saa6752(dev, VIDIOC_S_STD, &dev->tvnorm->id);
+ saa_call_empress(dev, tuner, s_std, dev->tvnorm->id);
}
static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale)
@@ -1266,8 +1264,7 @@ int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, str
else
dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
- saa7134_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
+ saa_call_all(dev, tuner, s_config, &tda9887_cfg);
}
break;
}
@@ -1334,7 +1331,7 @@ static int video_open(struct file *file)
enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
int radio = 0;
- lock_kernel();
+ mutex_lock(&saa7134_devlist_lock);
list_for_each_entry(dev, &saa7134_devlist, devlist) {
if (dev->video_dev && (dev->video_dev->minor == minor))
goto found;
@@ -1347,19 +1344,20 @@ static int video_open(struct file *file)
goto found;
}
}
- unlock_kernel();
+ mutex_unlock(&saa7134_devlist_lock);
return -ENODEV;
- found:
+
+found:
+ mutex_unlock(&saa7134_devlist_lock);
dprintk("open minor=%d radio=%d type=%s\n",minor,radio,
v4l2_type_names[type]);
/* allocate + initialize per filehandle data */
fh = kzalloc(sizeof(*fh),GFP_KERNEL);
- if (NULL == fh) {
- unlock_kernel();
+ if (NULL == fh)
return -ENOMEM;
- }
+
file->private_data = fh;
fh->dev = dev;
fh->radio = radio;
@@ -1387,12 +1385,11 @@ static int video_open(struct file *file)
if (fh->radio) {
/* switch to radio mode */
saa7134_tvaudio_setinput(dev,&card(dev).radio);
- saa7134_i2c_call_clients(dev,AUDC_SET_RADIO, NULL);
+ saa_call_all(dev, tuner, s_radio);
} else {
/* switch to video/vbi mode */
video_mux(dev,dev->ctl_input);
}
- unlock_kernel();
return 0;
}
@@ -1466,6 +1463,7 @@ static int video_release(struct file *file)
{
struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
unsigned long flags;
/* turn off overlay */
@@ -1498,7 +1496,9 @@ static int video_release(struct file *file)
saa_andorb(SAA7134_OFMT_DATA_A, 0x1f, 0);
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
- saa7134_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ saa_call_all(dev, core, s_standby, 0);
+ if (fh->radio)
+ saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
/* free stuff */
videobuf_mmap_free(&fh->cap);
@@ -1519,6 +1519,37 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma)
return videobuf_mmap_mapper(saa7134_queue(fh), vma);
}
+static ssize_t radio_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct saa7134_fh *fh = file->private_data;
+ struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
+
+ cmd.block_count = count/3;
+ cmd.buffer = data;
+ cmd.instance = file;
+ cmd.result = -ENODEV;
+
+ saa_call_all(dev, core, ioctl, RDS_CMD_READ, &cmd);
+
+ return cmd.result;
+}
+
+static unsigned int radio_poll(struct file *file, poll_table *wait)
+{
+ struct saa7134_fh *fh = file->private_data;
+ struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
+
+ cmd.instance = file;
+ cmd.event_list = wait;
+ cmd.result = -ENODEV;
+ saa_call_all(dev, core, ioctl, RDS_CMD_POLL, &cmd);
+
+ return cmd.result;
+}
+
/* ------------------------------------------------------------------ */
static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
@@ -2041,7 +2072,7 @@ static int saa7134_s_frequency(struct file *file, void *priv,
mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
- saa7134_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+ saa_call_all(dev, tuner, s_frequency, f);
saa7134_tvaudio_do_scan(dev);
mutex_unlock(&dev->lock);
@@ -2299,7 +2330,7 @@ static int radio_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- saa7134_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+ saa_call_all(dev, tuner, g_tuner, t);
if (dev->input->amux == TV) {
t->signal = 0xf800 - ((saa_readb(0x581) & 0x1f) << 11);
t->rxsubchans = (saa_readb(0x529) & 0x08) ?
@@ -2316,7 +2347,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- saa7134_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+ saa_call_all(dev, tuner, s_tuner, t);
return 0;
}
@@ -2443,8 +2474,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
static const struct v4l2_file_operations radio_fops = {
.owner = THIS_MODULE,
.open = video_open,
+ .read = radio_read,
.release = video_release,
.ioctl = video_ioctl2,
+ .poll = radio_poll,
};
static const struct v4l2_ioctl_ops radio_ioctl_ops = {
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 14ee265f337..a2dd326de5b 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -35,6 +35,7 @@
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/ir-common.h>
#include <media/ir-kbd-i2c.h>
@@ -277,6 +278,8 @@ struct saa7134_format {
#define SAA7134_BOARD_ASUSTeK_TIGER 152
#define SAA7134_BOARD_KWORLD_PLUS_TV_ANALOG 153
#define SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS 154
+#define SAA7134_BOARD_HAUPPAUGE_HVR1120 155
+#define SAA7134_BOARD_HAUPPAUGE_HVR1110R3 156
#define SAA7134_MAXBOARDS 32
#define SAA7134_INPUT_MAX 8
@@ -309,6 +312,11 @@ enum saa7134_mpeg_type {
SAA7134_MPEG_DVB,
};
+enum saa7134_mpeg_ts_type {
+ SAA7134_MPEG_TS_PARALLEL = 0,
+ SAA7134_MPEG_TS_SERIAL,
+};
+
struct saa7134_board {
char *name;
unsigned int audio_clock;
@@ -324,6 +332,8 @@ struct saa7134_board {
unsigned int radio_type;
unsigned char tuner_addr;
unsigned char radio_addr;
+ unsigned char empress_addr;
+ unsigned char rds_addr;
unsigned int tda9887_conf;
unsigned int tuner_config;
@@ -331,6 +341,7 @@ struct saa7134_board {
/* peripheral I/O */
enum saa7134_video_out video_out;
enum saa7134_mpeg_type mpeg;
+ enum saa7134_mpeg_ts_type ts_type;
unsigned int vid_port_opts;
};
@@ -445,7 +456,6 @@ struct saa7134_dmasound {
unsigned int bufsize;
struct saa7134_pgtable pt;
struct videobuf_dmabuf dma;
- wait_queue_head_t wq;
unsigned int dma_blk;
unsigned int read_offset;
unsigned int read_count;
@@ -482,6 +492,7 @@ struct saa7134_dev {
struct mutex lock;
spinlock_t slock;
struct v4l2_prio_state prio;
+ struct v4l2_device v4l2_dev;
/* workstruct for loading modules */
struct work_struct request_module_wk;
@@ -572,7 +583,6 @@ struct saa7134_dev {
enum saa7134_ts_status ts_state;
unsigned int buff_cnt;
struct saa7134_mpeg_ops *mops;
- struct i2c_client *mpeg_i2c_client;
/* SAA7134_MPEG_EMPRESS only */
struct video_device *empress_dev;
@@ -588,6 +598,7 @@ struct saa7134_dev {
int (*original_set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
int (*original_set_high_voltage)(struct dvb_frontend *fe, long arg);
#endif
+ void (*gate_ctrl)(struct saa7134_dev *dev, int open);
};
/* ----------------------------------------------------------- */
@@ -616,10 +627,31 @@ struct saa7134_dev {
V4L2_STD_NTSC | V4L2_STD_PAL_M | \
V4L2_STD_PAL_60)
+#define GRP_EMPRESS (1)
+#define saa_call_all(dev, o, f, args...) do { \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+} while (0)
+
+#define saa_call_empress(dev, o, f, args...) ({ \
+ long _rc; \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 1); \
+ _rc = v4l2_device_call_until_err(&(dev)->v4l2_dev, \
+ GRP_EMPRESS, o, f , ##args); \
+ if (dev->gate_ctrl) \
+ dev->gate_ctrl(dev, 0); \
+ _rc; \
+})
+
/* ----------------------------------------------------------- */
/* saa7134-core.c */
extern struct list_head saa7134_devlist;
+extern struct mutex saa7134_devlist_lock;
extern int saa7134_no_overlay;
void saa7134_track_gpio(struct saa7134_dev *dev, char *msg);
@@ -668,10 +700,6 @@ int saa7134_tuner_callback(void *priv, int component, int command, int arg);
int saa7134_i2c_register(struct saa7134_dev *dev);
int saa7134_i2c_unregister(struct saa7134_dev *dev);
-void saa7134_i2c_call_clients(struct saa7134_dev *dev,
- unsigned int cmd, void *arg);
-int saa7134_i2c_call_saa6752(struct saa7134_dev *dev,
- unsigned int cmd, void *arg);
/* ----------------------------------------------------------- */
diff --git a/drivers/media/video/saa7146.h b/drivers/media/video/saa7146.h
index 2830b5e33ae..9fadb331a40 100644
--- a/drivers/media/video/saa7146.h
+++ b/drivers/media/video/saa7146.h
@@ -25,8 +25,6 @@
#include <linux/types.h>
#include <linux/wait.h>
-#include <linux/videodev.h>
-
#ifndef O_NONCAP
#define O_NONCAP O_TRUNC
#endif
diff --git a/drivers/media/video/saa717x.c b/drivers/media/video/saa717x.c
index 88c5e942f75..25bf2303a6b 100644
--- a/drivers/media/video/saa717x.c
+++ b/drivers/media/video/saa717x.c
@@ -931,7 +931,7 @@ static int saa717x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
break;
case V4L2_CID_HUE:
- if (ctrl->value < -127 || ctrl->value > 127) {
+ if (ctrl->value < -128 || ctrl->value > 127) {
v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
return -ERANGE;
}
@@ -1380,11 +1380,6 @@ static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
return 0;
}
-static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa717x_core_ops = {
@@ -1528,10 +1523,7 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa717x",
- .driverid = I2C_DRIVERID_SAA717X,
- .command = saa717x_command,
.probe = saa717x_probe,
.remove = saa717x_remove,
- .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
.id_table = saa717x_id,
};
diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c
index 6debb65152e..75747b104d0 100644
--- a/drivers/media/video/saa7185.c
+++ b/drivers/media/video/saa7185.c
@@ -30,52 +30,58 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
-#include <linux/videodev.h>
-#include <linux/video_encoder.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("Philips SAA7185 video encoder driver");
MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
-
static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
/* ----------------------------------------------------------------------- */
struct saa7185 {
+ struct v4l2_subdev sd;
unsigned char reg[128];
- int norm;
- int enable;
- int bright;
- int contrast;
- int hue;
- int sat;
+ v4l2_std_id norm;
};
+static inline struct saa7185 *to_saa7185(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa7185, sd);
+}
+
/* ----------------------------------------------------------------------- */
-static inline int saa7185_read(struct i2c_client *client)
+static inline int saa7185_read(struct v4l2_subdev *sd)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte(client);
}
-static int saa7185_write(struct i2c_client *client, u8 reg, u8 value)
+static int saa7185_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- struct saa7185 *encoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7185 *encoder = to_saa7185(sd);
- v4l_dbg(1, debug, client, "%02x set to %02x\n", reg, value);
+ v4l2_dbg(1, debug, sd, "%02x set to %02x\n", reg, value);
encoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static int saa7185_write_block(struct i2c_client *client,
+static int saa7185_write_block(struct v4l2_subdev *sd,
const u8 *data, unsigned int len)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7185 *encoder = to_saa7185(sd);
int ret = -1;
u8 reg;
@@ -83,7 +89,6 @@ static int saa7185_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 saa7185 *encoder = i2c_get_clientdata(client);
u8 block_data[32];
int block_len;
@@ -104,7 +109,7 @@ static int saa7185_write_block(struct i2c_client *client,
/* do some slow I2C emulation kind of thing */
while (len >= 2) {
reg = *data++;
- ret = saa7185_write(client, reg, *data++);
+ ret = saa7185_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -213,133 +218,106 @@ static const unsigned char init_ntsc[] = {
0x66, 0x21, /* FSC3 */
};
-static int saa7185_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- struct saa7185 *encoder = i2c_get_clientdata(client);
-
- switch (cmd) {
- case 0:
- saa7185_write_block(client, init_common,
- sizeof(init_common));
- switch (encoder->norm) {
-
- case VIDEO_MODE_NTSC:
- saa7185_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- break;
-
- case VIDEO_MODE_PAL:
- saa7185_write_block(client, init_pal,
- sizeof(init_pal));
- break;
- }
- break;
- case ENCODER_GET_CAPABILITIES:
- {
- struct video_encoder_capability *cap = arg;
+static int saa7185_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct saa7185 *encoder = to_saa7185(sd);
- cap->flags =
- VIDEO_ENCODER_PAL | VIDEO_ENCODER_NTSC |
- VIDEO_ENCODER_SECAM | VIDEO_ENCODER_CCIR;
- cap->inputs = 1;
- cap->outputs = 1;
- break;
- }
+ saa7185_write_block(sd, init_common, sizeof(init_common));
+ if (encoder->norm & V4L2_STD_NTSC)
+ saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
+ else
+ saa7185_write_block(sd, init_pal, sizeof(init_pal));
+ return 0;
+}
- case ENCODER_SET_NORM:
- {
- int *iarg = arg;
+static int saa7185_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct saa7185 *encoder = to_saa7185(sd);
- //saa7185_write_block(client, init_common, sizeof(init_common));
+ if (std & V4L2_STD_NTSC)
+ saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
+ else if (std & V4L2_STD_PAL)
+ saa7185_write_block(sd, init_pal, sizeof(init_pal));
+ else
+ return -EINVAL;
+ encoder->norm = std;
+ return 0;
+}
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- saa7185_write_block(client, init_ntsc,
- sizeof(init_ntsc));
- break;
+static int saa7185_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ struct saa7185 *encoder = to_saa7185(sd);
- case VIDEO_MODE_PAL:
- saa7185_write_block(client, init_pal,
- sizeof(init_pal));
- break;
+ /* RJ: route->input = 0: input is from SA7111
+ route->input = 1: input is from ZR36060 */
- case VIDEO_MODE_SECAM:
- default:
- return -EINVAL;
- }
- encoder->norm = *iarg;
- break;
- }
-
- case ENCODER_SET_INPUT:
- {
- int *iarg = arg;
-
- /* RJ: *iarg = 0: input is from SA7111
- *iarg = 1: input is from ZR36060 */
-
- switch (*iarg) {
- case 0:
- /* Switch RTCE to 1 */
- saa7185_write(client, 0x61,
- (encoder->reg[0x61] & 0xf7) | 0x08);
- saa7185_write(client, 0x6e, 0x01);
- break;
-
- case 1:
- /* Switch RTCE to 0 */
- saa7185_write(client, 0x61,
- (encoder->reg[0x61] & 0xf7) | 0x00);
- /* SW: a slight sync problem... */
- saa7185_write(client, 0x6e, 0x00);
- break;
-
- default:
- return -EINVAL;
- }
+ switch (route->input) {
+ case 0:
+ /* turn off colorbar */
+ saa7185_write(sd, 0x3a, 0x0f);
+ /* Switch RTCE to 1 */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+ saa7185_write(sd, 0x6e, 0x01);
break;
- }
- case ENCODER_SET_OUTPUT:
- {
- int *iarg = arg;
-
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
+ case 1:
+ /* turn off colorbar */
+ saa7185_write(sd, 0x3a, 0x0f);
+ /* Switch RTCE to 0 */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x00);
+ /* SW: a slight sync problem... */
+ saa7185_write(sd, 0x6e, 0x00);
break;
- }
-
- case ENCODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
- encoder->enable = !!*iarg;
- saa7185_write(client, 0x61,
- (encoder->reg[0x61] & 0xbf) |
- (encoder->enable ? 0x00 : 0x40));
+ case 2:
+ /* turn on colorbar */
+ saa7185_write(sd, 0x3a, 0x8f);
+ /* Switch RTCE to 0 */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61] & 0xf7) | 0x08);
+ /* SW: a slight sync problem... */
+ saa7185_write(sd, 0x6e, 0x01);
break;
- }
default:
return -EINVAL;
}
-
return 0;
}
+static int saa7185_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7185, 0);
+}
+
/* ----------------------------------------------------------------------- */
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+static const struct v4l2_subdev_core_ops saa7185_core_ops = {
+ .g_chip_ident = saa7185_g_chip_ident,
+ .init = saa7185_init,
+};
-I2C_CLIENT_INSMOD;
+static const struct v4l2_subdev_video_ops saa7185_video_ops = {
+ .s_std_output = saa7185_s_std_output,
+ .s_routing = saa7185_s_routing,
+};
+
+static const struct v4l2_subdev_ops saa7185_ops = {
+ .core = &saa7185_core_ops,
+ .video = &saa7185_video_ops,
+};
+
+
+/* ----------------------------------------------------------------------- */
static int saa7185_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int i;
struct saa7185 *encoder;
+ struct v4l2_subdev *sd;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -351,28 +329,29 @@ static int saa7185_probe(struct i2c_client *client,
encoder = kzalloc(sizeof(struct saa7185), GFP_KERNEL);
if (encoder == NULL)
return -ENOMEM;
- encoder->norm = VIDEO_MODE_NTSC;
- encoder->enable = 1;
- i2c_set_clientdata(client, encoder);
+ encoder->norm = V4L2_STD_NTSC;
+ sd = &encoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa7185_ops);
- i = saa7185_write_block(client, init_common, sizeof(init_common));
+ i = saa7185_write_block(sd, init_common, sizeof(init_common));
if (i >= 0)
- i = saa7185_write_block(client, init_ntsc, sizeof(init_ntsc));
+ i = saa7185_write_block(sd, init_ntsc, sizeof(init_ntsc));
if (i < 0)
- v4l_dbg(1, debug, client, "init error %d\n", i);
+ v4l2_dbg(1, debug, sd, "init error %d\n", i);
else
- v4l_dbg(1, debug, client, "revision 0x%x\n",
- saa7185_read(client) >> 5);
+ v4l2_dbg(1, debug, sd, "revision 0x%x\n",
+ saa7185_read(sd) >> 5);
return 0;
}
static int saa7185_remove(struct i2c_client *client)
{
- struct saa7185 *encoder = i2c_get_clientdata(client);
-
- saa7185_write(client, 0x61, (encoder->reg[0x61]) | 0x40); /* SW: output off is active */
- //saa7185_write(client, 0x3a, (encoder->reg[0x3a]) | 0x80); /* SW: color bar */
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct saa7185 *encoder = to_saa7185(sd);
+ v4l2_device_unregister_subdev(sd);
+ /* SW: output off is active */
+ saa7185_write(sd, 0x61, (encoder->reg[0x61]) | 0x40);
kfree(encoder);
return 0;
}
@@ -387,8 +366,6 @@ MODULE_DEVICE_TABLE(i2c, saa7185_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa7185",
- .driverid = I2C_DRIVERID_SAA7185B,
- .command = saa7185_command,
.probe = saa7185_probe,
.remove = saa7185_remove,
.id_table = saa7185_id,
diff --git a/drivers/media/video/saa7191.c b/drivers/media/video/saa7191.c
index b4018cce328..3f523aeec56 100644
--- a/drivers/media/video/saa7191.c
+++ b/drivers/media/video/saa7191.c
@@ -19,9 +19,11 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "saa7191.h"
@@ -32,6 +34,7 @@ MODULE_VERSION(SAA7191_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
+
// #define SAA7191_DEBUG
#ifdef SAA7191_DEBUG
@@ -44,17 +47,20 @@ MODULE_LICENSE("GPL");
#define SAA7191_SYNC_DELAY 100 /* milliseconds */
struct saa7191 {
- struct i2c_client *client;
+ struct v4l2_subdev sd;
/* the register values are stored here as the actual
* I2C-registers are write-only */
u8 reg[25];
int input;
- int norm;
+ v4l2_std_id norm;
};
-static struct i2c_driver i2c_driver_saa7191;
+static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct saa7191, sd);
+}
static const u8 initseq[] = {
0, /* Subaddress */
@@ -100,15 +106,14 @@ static const u8 initseq[] = {
/* SAA7191 register handling */
-static u8 saa7191_read_reg(struct i2c_client *client,
- u8 reg)
+static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg)
{
- return ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg];
+ return to_saa7191(sd)->reg[reg];
}
-static int saa7191_read_status(struct i2c_client *client,
- u8 *value)
+static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
ret = i2c_master_recv(client, value, 1);
@@ -121,21 +126,23 @@ static int saa7191_read_status(struct i2c_client *client,
}
-static int saa7191_write_reg(struct i2c_client *client, u8 reg,
- u8 value)
+static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
{
- ((struct saa7191 *)i2c_get_clientdata(client))->reg[reg] = value;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ to_saa7191(sd)->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
/* the first byte of data must be the first subaddress number (register) */
-static int saa7191_write_block(struct i2c_client *client,
+static int saa7191_write_block(struct v4l2_subdev *sd,
u8 length, const u8 *data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct saa7191 *decoder = to_saa7191(sd);
int i;
int ret;
- struct saa7191 *decoder = (struct saa7191 *)i2c_get_clientdata(client);
for (i = 0; i < (length - 1); i++) {
decoder->reg[data[0] + i] = data[i + 1];
}
@@ -152,14 +159,15 @@ static int saa7191_write_block(struct i2c_client *client,
/* Helper functions */
-static int saa7191_set_input(struct i2c_client *client, int input)
+static int saa7191_s_routing(struct v4l2_subdev *sd,
+ const struct v4l2_routing *route)
{
- struct saa7191 *decoder = i2c_get_clientdata(client);
- u8 luma = saa7191_read_reg(client, SAA7191_REG_LUMA);
- u8 iock = saa7191_read_reg(client, SAA7191_REG_IOCK);
+ struct saa7191 *decoder = to_saa7191(sd);
+ u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+ u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
int err;
- switch (input) {
+ switch (route->input) {
case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
| SAA7191_IOCK_GPSW2);
@@ -175,54 +183,50 @@ static int saa7191_set_input(struct i2c_client *client, int input)
return -EINVAL;
}
- err = saa7191_write_reg(client, SAA7191_REG_LUMA, luma);
+ err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma);
if (err)
return -EIO;
- err = saa7191_write_reg(client, SAA7191_REG_IOCK, iock);
+ err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock);
if (err)
return -EIO;
- decoder->input = input;
+ decoder->input = route->input;
return 0;
}
-static int saa7191_set_norm(struct i2c_client *client, int norm)
+static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
- struct saa7191 *decoder = i2c_get_clientdata(client);
- u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
- u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
- u8 chcv = saa7191_read_reg(client, SAA7191_REG_CHCV);
+ struct saa7191 *decoder = to_saa7191(sd);
+ u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
+ u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
+ u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV);
int err;
- switch(norm) {
- case SAA7191_NORM_PAL:
+ if (norm & V4L2_STD_PAL) {
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
chcv = SAA7191_CHCV_PAL;
- break;
- case SAA7191_NORM_NTSC:
+ } else if (norm & V4L2_STD_NTSC) {
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~SAA7191_CTL3_AUFD;
ctl3 |= SAA7191_CTL3_FSEL;
chcv = SAA7191_CHCV_NTSC;
- break;
- case SAA7191_NORM_SECAM:
+ } else if (norm & V4L2_STD_SECAM) {
stdc |= SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
chcv = SAA7191_CHCV_PAL;
- break;
- default:
+ } else {
return -EINVAL;
}
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err)
return -EIO;
- err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
+ err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
if (err)
return -EIO;
- err = saa7191_write_reg(client, SAA7191_REG_CHCV, chcv);
+ err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv);
if (err)
return -EIO;
@@ -230,19 +234,19 @@ static int saa7191_set_norm(struct i2c_client *client, int norm)
dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
stdc, chcv);
- dprintk("norm: %d\n", norm);
+ dprintk("norm: %llx\n", norm);
return 0;
}
-static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
+static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status)
{
int i = 0;
dprintk("Checking for signal...\n");
for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
- if (saa7191_read_status(client, status))
+ if (saa7191_read_status(sd, status))
return -EIO;
if (((*status) & SAA7191_STATUS_HLCK) == 0) {
@@ -258,31 +262,34 @@ static int saa7191_wait_for_signal(struct i2c_client *client, u8 *status)
return -EBUSY;
}
-static int saa7191_autodetect_norm_extended(struct i2c_client *client)
+static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm)
{
- u8 stdc = saa7191_read_reg(client, SAA7191_REG_STDC);
- u8 ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ struct saa7191 *decoder = to_saa7191(sd);
+ u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
+ u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
u8 status;
+ v4l2_std_id old_norm = decoder->norm;
int err = 0;
dprintk("SAA7191 extended signal auto-detection...\n");
+ *norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_FSEL);
- err = saa7191_write_reg(client, SAA7191_REG_STDC, stdc);
+ err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
if (err) {
err = -EIO;
goto out;
}
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err) {
err = -EIO;
goto out;
}
ctl3 |= SAA7191_CTL3_AUFD;
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
+ err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err) {
err = -EIO;
goto out;
@@ -290,53 +297,54 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client)
msleep(SAA7191_SYNC_DELAY);
- err = saa7191_wait_for_signal(client, &status);
+ err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
if (status & SAA7191_STATUS_FIDT) {
/* 60Hz signal -> NTSC */
dprintk("60Hz signal: NTSC\n");
- return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+ *norm = V4L2_STD_NTSC;
+ return 0;
}
/* 50Hz signal */
dprintk("50Hz signal: Trying PAL...\n");
/* try PAL first */
- err = saa7191_set_norm(client, SAA7191_NORM_PAL);
+ err = saa7191_s_std(sd, V4L2_STD_PAL);
if (err)
goto out;
msleep(SAA7191_SYNC_DELAY);
- err = saa7191_wait_for_signal(client, &status);
+ err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
/* not 50Hz ? */
if (status & SAA7191_STATUS_FIDT) {
dprintk("No 50Hz signal\n");
- err = -EAGAIN;
- goto out;
+ saa7191_s_std(sd, old_norm);
+ return -EAGAIN;
}
if (status & SAA7191_STATUS_CODE) {
dprintk("PAL\n");
- return 0;
+ *norm = V4L2_STD_PAL;
+ return saa7191_s_std(sd, old_norm);
}
dprintk("No color detected with PAL - Trying SECAM...\n");
/* no color detected ? -> try SECAM */
- err = saa7191_set_norm(client,
- SAA7191_NORM_SECAM);
+ err = saa7191_s_std(sd, V4L2_STD_SECAM);
if (err)
goto out;
msleep(SAA7191_SYNC_DELAY);
- err = saa7191_wait_for_signal(client, &status);
+ err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
@@ -350,32 +358,17 @@ static int saa7191_autodetect_norm_extended(struct i2c_client *client)
if (status & SAA7191_STATUS_CODE) {
/* Color detected -> SECAM */
dprintk("SECAM\n");
- return 0;
+ *norm = V4L2_STD_SECAM;
+ return saa7191_s_std(sd, old_norm);
}
dprintk("No color detected with SECAM - Going back to PAL.\n");
- /* still no color detected ?
- * -> set norm back to PAL */
- err = saa7191_set_norm(client,
- SAA7191_NORM_PAL);
- if (err)
- goto out;
-
out:
- ctl3 = saa7191_read_reg(client, SAA7191_REG_CTL3);
- if (ctl3 & SAA7191_CTL3_AUFD) {
- ctl3 &= ~(SAA7191_CTL3_AUFD);
- err = saa7191_write_reg(client, SAA7191_REG_CTL3, ctl3);
- if (err) {
- err = -EIO;
- }
- }
-
- return err;
+ return saa7191_s_std(sd, old_norm);
}
-static int saa7191_autodetect_norm(struct i2c_client *client)
+static int saa7191_autodetect_norm(struct v4l2_subdev *sd)
{
u8 status;
@@ -383,7 +376,7 @@ static int saa7191_autodetect_norm(struct i2c_client *client)
dprintk("Reading status...\n");
- if (saa7191_read_status(client, &status))
+ if (saa7191_read_status(sd, &status))
return -EIO;
dprintk("Checking for signal...\n");
@@ -399,26 +392,25 @@ static int saa7191_autodetect_norm(struct i2c_client *client)
if (status & SAA7191_STATUS_FIDT) {
/* 60hz signal -> NTSC */
dprintk("NTSC\n");
- return saa7191_set_norm(client, SAA7191_NORM_NTSC);
+ return saa7191_s_std(sd, V4L2_STD_NTSC);
} else {
/* 50hz signal -> PAL */
dprintk("PAL\n");
- return saa7191_set_norm(client, SAA7191_NORM_PAL);
+ return saa7191_s_std(sd, V4L2_STD_PAL);
}
}
-static int saa7191_get_control(struct i2c_client *client,
- struct saa7191_control *ctrl)
+static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
u8 reg;
int ret = 0;
- switch (ctrl->type) {
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
case SAA7191_CONTROL_BANDPASS_WEIGHT:
case SAA7191_CONTROL_CORING:
- reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
- switch (ctrl->type) {
+ reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
>> SAA7191_LUMA_BPSS_SHIFT;
@@ -435,15 +427,15 @@ static int saa7191_get_control(struct i2c_client *client,
break;
case SAA7191_CONTROL_FORCE_COLOUR:
case SAA7191_CONTROL_CHROMA_GAIN:
- reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
- if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR)
+ reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
+ if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR)
ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
else
ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
>> SAA7191_GAIN_LFIS_SHIFT;
break;
- case SAA7191_CONTROL_HUE:
- reg = saa7191_read_reg(client, SAA7191_REG_HUEC);
+ case V4L2_CID_HUE:
+ reg = saa7191_read_reg(sd, SAA7191_REG_HUEC);
if (reg < 0x80)
reg += 0x80;
else
@@ -451,18 +443,18 @@ static int saa7191_get_control(struct i2c_client *client,
ctrl->value = (s32)reg;
break;
case SAA7191_CONTROL_VTRC:
- reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+ reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
break;
case SAA7191_CONTROL_LUMA_DELAY:
- reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
>> SAA7191_CTL3_YDEL_SHIFT;
if (ctrl->value >= 4)
ctrl->value -= 8;
break;
case SAA7191_CONTROL_VNR:
- reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
>> SAA7191_CTL4_VNOI_SHIFT;
break;
@@ -473,18 +465,17 @@ static int saa7191_get_control(struct i2c_client *client,
return ret;
}
-static int saa7191_set_control(struct i2c_client *client,
- struct saa7191_control *ctrl)
+static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
u8 reg;
int ret = 0;
- switch (ctrl->type) {
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
case SAA7191_CONTROL_BANDPASS_WEIGHT:
case SAA7191_CONTROL_CORING:
- reg = saa7191_read_reg(client, SAA7191_REG_LUMA);
- switch (ctrl->type) {
+ reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
+ switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
reg &= ~SAA7191_LUMA_BPSS_MASK;
reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
@@ -501,12 +492,12 @@ static int saa7191_set_control(struct i2c_client *client,
& SAA7191_LUMA_CORI_MASK;
break;
}
- ret = saa7191_write_reg(client, SAA7191_REG_LUMA, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg);
break;
case SAA7191_CONTROL_FORCE_COLOUR:
case SAA7191_CONTROL_CHROMA_GAIN:
- reg = saa7191_read_reg(client, SAA7191_REG_GAIN);
- if (ctrl->type == SAA7191_CONTROL_FORCE_COLOUR) {
+ reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
+ if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) {
if (ctrl->value)
reg |= SAA7191_GAIN_COLO;
else
@@ -516,41 +507,41 @@ static int saa7191_set_control(struct i2c_client *client,
reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
& SAA7191_GAIN_LFIS_MASK;
}
- ret = saa7191_write_reg(client, SAA7191_REG_GAIN, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg);
break;
- case SAA7191_CONTROL_HUE:
+ case V4L2_CID_HUE:
reg = ctrl->value & 0xff;
if (reg < 0x80)
reg += 0x80;
else
reg -= 0x80;
- ret = saa7191_write_reg(client, SAA7191_REG_HUEC, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg);
break;
case SAA7191_CONTROL_VTRC:
- reg = saa7191_read_reg(client, SAA7191_REG_STDC);
+ reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
if (ctrl->value)
reg |= SAA7191_STDC_VTRC;
else
reg &= ~SAA7191_STDC_VTRC;
- ret = saa7191_write_reg(client, SAA7191_REG_STDC, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg);
break;
case SAA7191_CONTROL_LUMA_DELAY: {
s32 value = ctrl->value;
if (value < 0)
value += 8;
- reg = saa7191_read_reg(client, SAA7191_REG_CTL3);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
reg &= ~SAA7191_CTL3_YDEL_MASK;
reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
& SAA7191_CTL3_YDEL_MASK;
- ret = saa7191_write_reg(client, SAA7191_REG_CTL3, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg);
break;
}
case SAA7191_CONTROL_VNR:
- reg = saa7191_read_reg(client, SAA7191_REG_CTL4);
+ reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
reg &= ~SAA7191_CTL4_VNOI_MASK;
reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
& SAA7191_CTL4_VNOI_MASK;
- ret = saa7191_write_reg(client, SAA7191_REG_CTL4, reg);
+ ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg);
break;
default:
ret = -EINVAL;
@@ -561,247 +552,108 @@ static int saa7191_set_control(struct i2c_client *client,
/* I2C-interface */
-static int saa7191_attach(struct i2c_adapter *adap, int addr, int kind)
+static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
{
- int err = 0;
- struct saa7191 *decoder;
- struct i2c_client *client;
-
- printk(KERN_INFO "Philips SAA7191 driver version %s\n",
- SAA7191_MODULE_VERSION);
-
- client = kzalloc(sizeof(*client), GFP_KERNEL);
- if (!client)
- return -ENOMEM;
- decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
- if (!decoder) {
- err = -ENOMEM;
- goto out_free_client;
- }
-
- client->addr = addr;
- client->adapter = adap;
- client->driver = &i2c_driver_saa7191;
- client->flags = 0;
- strcpy(client->name, "saa7191 client");
- i2c_set_clientdata(client, decoder);
-
- decoder->client = client;
-
- err = i2c_attach_client(client);
- if (err)
- goto out_free_decoder;
-
- err = saa7191_write_block(client, sizeof(initseq), initseq);
- if (err) {
- printk(KERN_ERR "SAA7191 initialization failed\n");
- goto out_detach_client;
- }
-
- printk(KERN_INFO "SAA7191 initialized\n");
-
- decoder->input = SAA7191_INPUT_COMPOSITE;
- decoder->norm = SAA7191_NORM_PAL;
-
- err = saa7191_autodetect_norm(client);
- if (err && (err != -EBUSY)) {
- printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
- }
+ u8 status_reg;
+ int res = V4L2_IN_ST_NO_SIGNAL;
+ if (saa7191_read_status(sd, &status_reg))
+ return -EIO;
+ if ((status_reg & SAA7191_STATUS_HLCK) == 0)
+ res = 0;
+ if (!(status_reg & SAA7191_STATUS_CODE))
+ res |= V4L2_IN_ST_NO_COLOR;
+ *status = res;
return 0;
-
-out_detach_client:
- i2c_detach_client(client);
-out_free_decoder:
- kfree(decoder);
-out_free_client:
- kfree(client);
- return err;
}
-static int saa7191_probe(struct i2c_adapter *adap)
-{
- /* Always connected to VINO */
- if (adap->id == I2C_HW_SGI_VINO)
- return saa7191_attach(adap, SAA7191_ADDR, 0);
- /* Feel free to add probe here :-) */
- return -ENODEV;
-}
-static int saa7191_detach(struct i2c_client *client)
+static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
{
- struct saa7191 *decoder = i2c_get_clientdata(client);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- i2c_detach_client(client);
- kfree(decoder);
- kfree(client);
- return 0;
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
}
-static int saa7191_command(struct i2c_client *client, unsigned int cmd,
- void *arg)
-{
- struct saa7191 *decoder = i2c_get_clientdata(client);
+/* ----------------------------------------------------------------------- */
- switch (cmd) {
- case DECODER_GET_CAPABILITIES: {
- struct video_decoder_capability *cap = arg;
+static const struct v4l2_subdev_core_ops saa7191_core_ops = {
+ .g_chip_ident = saa7191_g_chip_ident,
+ .g_ctrl = saa7191_g_ctrl,
+ .s_ctrl = saa7191_s_ctrl,
+};
- cap->flags = VIDEO_DECODER_PAL | VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM | VIDEO_DECODER_AUTO;
- cap->inputs = (client->adapter->id == I2C_HW_SGI_VINO) ? 2 : 1;
- cap->outputs = 1;
- break;
- }
- case DECODER_GET_STATUS: {
- int *iarg = arg;
- u8 status;
- int res = 0;
+static const struct v4l2_subdev_tuner_ops saa7191_tuner_ops = {
+ .s_std = saa7191_s_std,
+};
- if (saa7191_read_status(client, &status)) {
- return -EIO;
- }
- if ((status & SAA7191_STATUS_HLCK) == 0)
- res |= DECODER_STATUS_GOOD;
- if (status & SAA7191_STATUS_CODE)
- res |= DECODER_STATUS_COLOR;
- switch (decoder->norm) {
- case SAA7191_NORM_NTSC:
- res |= DECODER_STATUS_NTSC;
- break;
- case SAA7191_NORM_PAL:
- res |= DECODER_STATUS_PAL;
- break;
- case SAA7191_NORM_SECAM:
- res |= DECODER_STATUS_SECAM;
- break;
- case SAA7191_NORM_AUTO:
- default:
- if (status & SAA7191_STATUS_FIDT)
- res |= DECODER_STATUS_NTSC;
- else
- res |= DECODER_STATUS_PAL;
- break;
- }
- *iarg = res;
- break;
- }
- case DECODER_SET_NORM: {
- int *iarg = arg;
-
- switch (*iarg) {
- case VIDEO_MODE_AUTO:
- return saa7191_autodetect_norm(client);
- case VIDEO_MODE_PAL:
- return saa7191_set_norm(client, SAA7191_NORM_PAL);
- case VIDEO_MODE_NTSC:
- return saa7191_set_norm(client, SAA7191_NORM_NTSC);
- case VIDEO_MODE_SECAM:
- return saa7191_set_norm(client, SAA7191_NORM_SECAM);
- default:
- return -EINVAL;
- }
- break;
- }
- case DECODER_SET_INPUT: {
- int *iarg = arg;
-
- switch (client->adapter->id) {
- case I2C_HW_SGI_VINO:
- return saa7191_set_input(client, *iarg);
- default:
- if (*iarg != 0)
- return -EINVAL;
- }
- break;
- }
- case DECODER_SET_OUTPUT: {
- int *iarg = arg;
+static const struct v4l2_subdev_video_ops saa7191_video_ops = {
+ .s_routing = saa7191_s_routing,
+ .querystd = saa7191_querystd,
+ .g_input_status = saa7191_g_input_status,
+};
- /* not much choice of outputs */
- if (*iarg != 0)
- return -EINVAL;
- break;
- }
- case DECODER_ENABLE_OUTPUT: {
- /* Always enabled */
- break;
- }
- case DECODER_SET_PICTURE: {
- struct video_picture *pic = arg;
- unsigned val;
- int err;
+static const struct v4l2_subdev_ops saa7191_ops = {
+ .core = &saa7191_core_ops,
+ .video = &saa7191_video_ops,
+ .tuner = &saa7191_tuner_ops,
+};
- val = (pic->hue >> 8) - 0x80;
+static int saa7191_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ struct saa7191 *decoder;
+ struct v4l2_subdev *sd;
- err = saa7191_write_reg(client, SAA7191_REG_HUEC, val);
- if (err)
- return -EIO;
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
- break;
- }
- case DECODER_SAA7191_GET_STATUS: {
- struct saa7191_status *status = arg;
- u8 status_reg;
+ decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+ if (!decoder)
+ return -ENOMEM;
- if (saa7191_read_status(client, &status_reg))
- return -EIO;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &saa7191_ops);
- status->signal = ((status_reg & SAA7191_STATUS_HLCK) == 0)
- ? 1 : 0;
- status->signal_60hz = (status_reg & SAA7191_STATUS_FIDT)
- ? 1 : 0;
- status->color = (status_reg & SAA7191_STATUS_CODE) ? 1 : 0;
+ err = saa7191_write_block(sd, sizeof(initseq), initseq);
+ if (err) {
+ printk(KERN_ERR "SAA7191 initialization failed\n");
+ kfree(decoder);
+ return err;
+ }
- status->input = decoder->input;
- status->norm = decoder->norm;
+ printk(KERN_INFO "SAA7191 initialized\n");
- break;
- }
- case DECODER_SAA7191_SET_NORM: {
- int *norm = arg;
-
- switch (*norm) {
- case SAA7191_NORM_AUTO:
- return saa7191_autodetect_norm(client);
- case SAA7191_NORM_AUTO_EXT:
- return saa7191_autodetect_norm_extended(client);
- default:
- return saa7191_set_norm(client, *norm);
- }
- }
- case DECODER_SAA7191_GET_CONTROL: {
- return saa7191_get_control(client, arg);
- }
- case DECODER_SAA7191_SET_CONTROL: {
- return saa7191_set_control(client, arg);
- }
- default:
- return -EINVAL;
- }
+ decoder->input = SAA7191_INPUT_COMPOSITE;
+ decoder->norm = V4L2_STD_PAL;
+
+ err = saa7191_autodetect_norm(sd);
+ if (err && (err != -EBUSY))
+ printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
return 0;
}
-static struct i2c_driver i2c_driver_saa7191 = {
- .driver = {
- .name = "saa7191",
- },
- .id = I2C_DRIVERID_SAA7191,
- .attach_adapter = saa7191_probe,
- .detach_client = saa7191_detach,
- .command = saa7191_command
-};
-
-static int saa7191_init(void)
+static int saa7191_remove(struct i2c_client *client)
{
- return i2c_add_driver(&i2c_driver_saa7191);
-}
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
-static void saa7191_exit(void)
-{
- i2c_del_driver(&i2c_driver_saa7191);
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_saa7191(sd));
+ return 0;
}
-module_init(saa7191_init);
-module_exit(saa7191_exit);
+static const struct i2c_device_id saa7191_id[] = {
+ { "saa7191", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, saa7191_id);
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "saa7191",
+ .probe = saa7191_probe,
+ .remove = saa7191_remove,
+ .id_table = saa7191_id,
+};
diff --git a/drivers/media/video/saa7191.h b/drivers/media/video/saa7191.h
index a2310da1940..803c74d6066 100644
--- a/drivers/media/video/saa7191.h
+++ b/drivers/media/video/saa7191.h
@@ -176,11 +176,9 @@
#define SAA7191_INPUT_COMPOSITE 0
#define SAA7191_INPUT_SVIDEO 1
-#define SAA7191_NORM_AUTO 0
#define SAA7191_NORM_PAL 1
#define SAA7191_NORM_NTSC 2
#define SAA7191_NORM_SECAM 3
-#define SAA7191_NORM_AUTO_EXT 4 /* extended auto-detection */
struct saa7191_status {
/* 0=no signal, 1=signal detected */
@@ -232,24 +230,16 @@ struct saa7191_status {
#define SAA7191_VNR_MAX 0x03
#define SAA7191_VNR_DEFAULT 0x00
-#define SAA7191_CONTROL_BANDPASS 0
-#define SAA7191_CONTROL_BANDPASS_WEIGHT 1
-#define SAA7191_CONTROL_CORING 2
-#define SAA7191_CONTROL_FORCE_COLOUR 3 /* boolean */
-#define SAA7191_CONTROL_CHROMA_GAIN 4
-#define SAA7191_CONTROL_HUE 5
-#define SAA7191_CONTROL_VTRC 6 /* boolean */
-#define SAA7191_CONTROL_LUMA_DELAY 7
-#define SAA7191_CONTROL_VNR 8
-
-struct saa7191_control {
- u8 type;
- s32 value;
-};
+#define SAA7191_CONTROL_BANDPASS (V4L2_CID_PRIVATE_BASE + 0)
+#define SAA7191_CONTROL_BANDPASS_WEIGHT (V4L2_CID_PRIVATE_BASE + 1)
+#define SAA7191_CONTROL_CORING (V4L2_CID_PRIVATE_BASE + 2)
+#define SAA7191_CONTROL_FORCE_COLOUR (V4L2_CID_PRIVATE_BASE + 3)
+#define SAA7191_CONTROL_CHROMA_GAIN (V4L2_CID_PRIVATE_BASE + 4)
+#define SAA7191_CONTROL_VTRC (V4L2_CID_PRIVATE_BASE + 5)
+#define SAA7191_CONTROL_LUMA_DELAY (V4L2_CID_PRIVATE_BASE + 6)
+#define SAA7191_CONTROL_VNR (V4L2_CID_PRIVATE_BASE + 7)
#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
-#define DECODER_SAA7191_GET_CONTROL _IOR('d', 197, struct saa7191_control)
-#define DECODER_SAA7191_SET_CONTROL _IOW('d', 198, struct saa7191_control)
#endif
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index ddcb81d0b81..b5e37a530c6 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -94,13 +94,37 @@ struct sh_mobile_ceu_dev {
spinlock_t lock;
struct list_head capture;
struct videobuf_buffer *active;
- int is_interlace;
+ int is_interlaced;
struct sh_mobile_ceu_info *pdata;
const struct soc_camera_data_format *camera_fmt;
};
+static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
+{
+ unsigned long flags;
+
+ flags = SOCAM_MASTER |
+ SOCAM_PCLK_SAMPLE_RISING |
+ SOCAM_HSYNC_ACTIVE_HIGH |
+ SOCAM_HSYNC_ACTIVE_LOW |
+ SOCAM_VSYNC_ACTIVE_HIGH |
+ SOCAM_VSYNC_ACTIVE_LOW |
+ SOCAM_DATA_ACTIVE_HIGH;
+
+ if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS)
+ flags |= SOCAM_DATAWIDTH_8;
+
+ if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS)
+ flags |= SOCAM_DATAWIDTH_16;
+
+ if (flags & SOCAM_DATAWIDTH_MASK)
+ return flags;
+
+ return 0;
+}
+
static void ceu_write(struct sh_mobile_ceu_dev *priv,
unsigned long reg_offs, u32 data)
{
@@ -150,6 +174,7 @@ static void free_buffer(struct videobuf_queue *vq,
if (in_interrupt())
BUG();
+ videobuf_waiton(&buf->vb, 0, 0);
videobuf_dma_contig_free(vq, &buf->vb);
dev_dbg(&icd->dev, "%s freed\n", __func__);
buf->vb.state = VIDEOBUF_NEEDS_INIT;
@@ -181,7 +206,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
phys_addr_top = videobuf_to_dma_contig(pcdev->active);
ceu_write(pcdev, CDAYR, phys_addr_top);
- if (pcdev->is_interlace) {
+ if (pcdev->is_interlaced) {
phys_addr_bottom = phys_addr_top + icd->width;
ceu_write(pcdev, CDBYR, phys_addr_bottom);
}
@@ -193,7 +218,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
case V4L2_PIX_FMT_NV61:
phys_addr_top += icd->width * icd->height;
ceu_write(pcdev, CDACR, phys_addr_top);
- if (pcdev->is_interlace) {
+ if (pcdev->is_interlaced) {
phys_addr_bottom = phys_addr_top + icd->width;
ceu_write(pcdev, CDBCR, phys_addr_bottom);
}
@@ -396,7 +421,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags,
- pcdev->pdata->flags);
+ make_bus_param(pcdev));
if (!common_flags)
return -EINVAL;
@@ -457,7 +482,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
ceu_write(pcdev, CAMCR, value);
ceu_write(pcdev, CAPCR, 0x00300000);
- ceu_write(pcdev, CAIFR, (pcdev->is_interlace) ? 0x101 : 0);
+ ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
mdelay(1);
@@ -473,7 +498,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
}
height = icd->height;
- if (pcdev->is_interlace) {
+ if (pcdev->is_interlaced) {
height /= 2;
cdwdr_width *= 2;
}
@@ -517,7 +542,7 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd)
camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags,
- pcdev->pdata->flags);
+ make_bus_param(pcdev));
if (!common_flags)
return -EINVAL;
@@ -562,11 +587,29 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
if (ret < 0)
return 0;
+ /* Beginning of a pass */
+ if (!idx)
+ icd->host_priv = NULL;
+
switch (icd->formats[idx].fourcc) {
case V4L2_PIX_FMT_UYVY:
case V4L2_PIX_FMT_VYUY:
case V4L2_PIX_FMT_YUYV:
case V4L2_PIX_FMT_YVYU:
+ if (icd->host_priv)
+ goto add_single_format;
+
+ /*
+ * Our case is simple so far: for any of the above four camera
+ * formats we add all our four synthesized NV* formats, so,
+ * just marking the device with a single flag suffices. If
+ * the format generation rules are more complex, you would have
+ * to actually hang your already added / counted formats onto
+ * the host_priv pointer and check whether the format you're
+ * going to add now is already there.
+ */
+ icd->host_priv = (void *)sh_mobile_ceu_formats;
+
n = ARRAY_SIZE(sh_mobile_ceu_formats);
formats += n;
for (k = 0; xlate && k < n; k++) {
@@ -579,6 +622,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
icd->formats[idx].name);
}
default:
+add_single_format:
/* Generic pass-through */
formats++;
if (xlate) {
@@ -595,24 +639,30 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
return formats;
}
+static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ return icd->ops->set_crop(icd, rect);
+}
+
static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct sh_mobile_ceu_dev *pcdev = ici->priv;
+ __u32 pixfmt = f->fmt.pix.pixelformat;
const struct soc_camera_format_xlate *xlate;
+ struct v4l2_format cam_f = *f;
int ret;
- if (!pixfmt)
- return icd->ops->set_fmt(icd, pixfmt, rect);
-
xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
if (!xlate) {
dev_warn(&ici->dev, "Format %x not found\n", pixfmt);
return -EINVAL;
}
- ret = icd->ops->set_fmt(icd, xlate->cam_fmt->fourcc, rect);
+ cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc;
+ ret = icd->ops->set_fmt(icd, &cam_f);
if (!ret) {
icd->buswidth = xlate->buswidth;
@@ -662,13 +712,13 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
switch (f->fmt.pix.field) {
case V4L2_FIELD_INTERLACED:
- pcdev->is_interlace = 1;
+ pcdev->is_interlaced = 1;
break;
case V4L2_FIELD_ANY:
f->fmt.pix.field = V4L2_FIELD_NONE;
/* fall-through */
case V4L2_FIELD_NONE:
- pcdev->is_interlace = 0;
+ pcdev->is_interlaced = 0;
break;
default:
ret = -EINVAL;
@@ -734,7 +784,8 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
&sh_mobile_ceu_videobuf_ops,
&ici->dev, &pcdev->lock,
V4L2_BUF_TYPE_VIDEO_CAPTURE,
- V4L2_FIELD_ANY,
+ pcdev->is_interlaced ?
+ V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
sizeof(struct sh_mobile_ceu_buffer),
icd);
}
@@ -744,6 +795,7 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
.add = sh_mobile_ceu_add_device,
.remove = sh_mobile_ceu_remove_device,
.get_formats = sh_mobile_ceu_get_formats,
+ .set_crop = sh_mobile_ceu_set_crop,
.set_fmt = sh_mobile_ceu_set_fmt,
.try_fmt = sh_mobile_ceu_try_fmt,
.reqbufs = sh_mobile_ceu_reqbufs,
diff --git a/drivers/media/video/sn9c102/sn9c102_devtable.h b/drivers/media/video/sn9c102/sn9c102_devtable.h
index 8cb3457e778..38a716020d7 100644
--- a/drivers/media/video/sn9c102/sn9c102_devtable.h
+++ b/drivers/media/video/sn9c102/sn9c102_devtable.h
@@ -96,9 +96,7 @@ static const struct usb_device_id sn9c102_id_table[] = {
#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x045e, 0x00f5, BRIDGE_SN9C105), },
{ SN9C102_USB_DEVICE(0x045e, 0x00f7, BRIDGE_SN9C105), },
-#endif
{ SN9C102_USB_DEVICE(0x0471, 0x0327, BRIDGE_SN9C105), },
-#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x0471, 0x0328, BRIDGE_SN9C105), },
#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x60c0, BRIDGE_SN9C105), },
@@ -123,7 +121,9 @@ static const struct usb_device_id sn9c102_id_table[] = {
{ SN9C102_USB_DEVICE(0x0c45, 0x613a, BRIDGE_SN9C120), },
#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x613b, BRIDGE_SN9C120), },
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
{ SN9C102_USB_DEVICE(0x0c45, 0x613c, BRIDGE_SN9C120), },
+#endif
{ SN9C102_USB_DEVICE(0x0c45, 0x613e, BRIDGE_SN9C120), },
{ }
};
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index fcb05f06de8..6d8bfd4d97e 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -30,6 +30,10 @@
#include <media/videobuf-core.h>
#include <media/soc_camera.h>
+/* Default to VGA resolution */
+#define DEFAULT_WIDTH 640
+#define DEFAULT_HEIGHT 480
+
static LIST_HEAD(hosts);
static LIST_HEAD(devices);
static DEFINE_MUTEX(list_lock);
@@ -256,6 +260,46 @@ static void soc_camera_free_user_formats(struct soc_camera_device *icd)
vfree(icd->user_formats);
}
+/* Called with .vb_lock held */
+static int soc_camera_set_fmt(struct soc_camera_file *icf,
+ struct v4l2_format *f)
+{
+ struct soc_camera_device *icd = icf->icd;
+ struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ int ret;
+
+ /* We always call try_fmt() before set_fmt() or set_crop() */
+ ret = ici->ops->try_fmt(icd, f);
+ if (ret < 0)
+ return ret;
+
+ ret = ici->ops->set_fmt(icd, f);
+ if (ret < 0) {
+ return ret;
+ } else if (!icd->current_fmt ||
+ icd->current_fmt->fourcc != pix->pixelformat) {
+ dev_err(&ici->dev,
+ "Host driver hasn't set up current format correctly!\n");
+ return -EINVAL;
+ }
+
+ icd->width = pix->width;
+ icd->height = pix->height;
+ icf->vb_vidq.field =
+ icd->field = pix->field;
+
+ if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
+ f->type);
+
+ dev_dbg(&icd->dev, "set width: %d height: %d\n",
+ icd->width, icd->height);
+
+ /* set physical bus parameters */
+ return ici->ops->set_bus_param(icd, pix->pixelformat);
+}
+
static int soc_camera_open(struct file *file)
{
struct video_device *vdev;
@@ -297,14 +341,28 @@ static int soc_camera_open(struct file *file)
/* Now we really have to activate the camera */
if (icd->use_count == 1) {
- ret = soc_camera_init_user_formats(icd);
- if (ret < 0)
- goto eiufmt;
+ /* Restore parameters before the last close() per V4L2 API */
+ struct v4l2_format f = {
+ .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
+ .fmt.pix = {
+ .width = icd->width,
+ .height = icd->height,
+ .field = icd->field,
+ .pixelformat = icd->current_fmt->fourcc,
+ .colorspace = icd->current_fmt->colorspace,
+ },
+ };
+
ret = ici->ops->add(icd);
if (ret < 0) {
dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
goto eiciadd;
}
+
+ /* Try to configure with default parameters */
+ ret = soc_camera_set_fmt(icf, &f);
+ if (ret < 0)
+ goto esfmt;
}
mutex_unlock(&icd->video_lock);
@@ -316,10 +374,13 @@ static int soc_camera_open(struct file *file)
return 0;
- /* First two errors are entered with the .video_lock held */
+ /*
+ * First three errors are entered with the .video_lock held
+ * and use_count == 1
+ */
+esfmt:
+ ici->ops->remove(icd);
eiciadd:
- soc_camera_free_user_formats(icd);
-eiufmt:
icd->use_count--;
mutex_unlock(&icd->video_lock);
module_put(ici->ops->owner);
@@ -339,10 +400,9 @@ static int soc_camera_close(struct file *file)
mutex_lock(&icd->video_lock);
icd->use_count--;
- if (!icd->use_count) {
+ if (!icd->use_count)
ici->ops->remove(icd);
- soc_camera_free_user_formats(icd);
- }
+
mutex_unlock(&icd->video_lock);
module_put(icd->ops->owner);
@@ -415,18 +475,10 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
{
struct soc_camera_file *icf = file->private_data;
struct soc_camera_device *icd = icf->icd;
- struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
- struct v4l2_pix_format *pix = &f->fmt.pix;
- __u32 pixfmt = pix->pixelformat;
int ret;
- struct v4l2_rect rect;
WARN_ON(priv != file->private_data);
- ret = soc_camera_try_fmt_vid_cap(file, priv, f);
- if (ret < 0)
- return ret;
-
mutex_lock(&icf->vb_vidq.vb_lock);
if (videobuf_queue_is_busy(&icf->vb_vidq)) {
@@ -435,33 +487,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
goto unlock;
}
- rect.left = icd->x_current;
- rect.top = icd->y_current;
- rect.width = pix->width;
- rect.height = pix->height;
- ret = ici->ops->set_fmt(icd, pix->pixelformat, &rect);
- if (ret < 0) {
- goto unlock;
- } else if (!icd->current_fmt ||
- icd->current_fmt->fourcc != pixfmt) {
- dev_err(&ici->dev,
- "Host driver hasn't set up current format correctly!\n");
- ret = -EINVAL;
- goto unlock;
- }
-
- icd->width = rect.width;
- icd->height = rect.height;
- icf->vb_vidq.field = pix->field;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
- f->type);
-
- dev_dbg(&icd->dev, "set width: %d height: %d\n",
- icd->width, icd->height);
-
- /* set physical bus parameters */
- ret = ici->ops->set_bus_param(icd, pixfmt);
+ ret = soc_camera_set_fmt(icf, f);
unlock:
mutex_unlock(&icf->vb_vidq.vb_lock);
@@ -648,8 +674,8 @@ static int soc_camera_cropcap(struct file *file, void *fh,
a->bounds.height = icd->height_max;
a->defrect.left = icd->x_min;
a->defrect.top = icd->y_min;
- a->defrect.width = 640;
- a->defrect.height = 480;
+ a->defrect.width = DEFAULT_WIDTH;
+ a->defrect.height = DEFAULT_HEIGHT;
a->pixelaspect.numerator = 1;
a->pixelaspect.denominator = 1;
@@ -685,7 +711,7 @@ static int soc_camera_s_crop(struct file *file, void *fh,
/* Cropping is allowed during a running capture, guard consistency */
mutex_lock(&icf->vb_vidq.vb_lock);
- ret = ici->ops->set_fmt(icd, 0, &a->c);
+ ret = ici->ops->set_crop(icd, &a->c);
if (!ret) {
icd->width = a->c.width;
icd->height = a->c.height;
@@ -844,9 +870,18 @@ static int soc_camera_probe(struct device *dev)
qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
icd->exposure = qctrl ? qctrl->default_value :
(unsigned short)~0;
+
+ ret = soc_camera_init_user_formats(icd);
+ if (ret < 0)
+ goto eiufmt;
+
+ icd->height = DEFAULT_HEIGHT;
+ icd->width = DEFAULT_WIDTH;
+ icd->field = V4L2_FIELD_ANY;
}
- ici->ops->remove(icd);
+eiufmt:
+ ici->ops->remove(icd);
eiadd:
mutex_unlock(&icd->video_lock);
module_put(ici->ops->owner);
@@ -865,6 +900,8 @@ static int soc_camera_remove(struct device *dev)
if (icd->ops->remove)
icd->ops->remove(icd);
+ soc_camera_free_user_formats(icd);
+
return 0;
}
@@ -918,6 +955,7 @@ int soc_camera_host_register(struct soc_camera_host *ici)
if (!ici || !ici->ops ||
!ici->ops->try_fmt ||
!ici->ops->set_fmt ||
+ !ici->ops->set_crop ||
!ici->ops->set_bus_param ||
!ici->ops->querycap ||
!ici->ops->init_videobuf ||
@@ -998,6 +1036,7 @@ int soc_camera_device_register(struct soc_camera_device *icd)
!icd->ops->release ||
!icd->ops->start_capture ||
!icd->ops->stop_capture ||
+ !icd->ops->set_crop ||
!icd->ops->set_fmt ||
!icd->ops->try_fmt ||
!icd->ops->query_bus_param ||
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index 013ab06e318..c48676356ab 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -79,8 +79,14 @@ soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
return p->bus_param;
}
+static int soc_camera_platform_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
+{
+ return 0;
+}
+
static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
- __u32 pixfmt, struct v4l2_rect *rect)
+ struct v4l2_format *f)
{
return 0;
}
@@ -125,6 +131,7 @@ static struct soc_camera_ops soc_camera_platform_ops = {
.release = soc_camera_platform_release,
.start_capture = soc_camera_platform_start_capture,
.stop_capture = soc_camera_platform_stop_capture,
+ .set_crop = soc_camera_platform_set_crop,
.set_fmt = soc_camera_platform_set_fmt,
.try_fmt = soc_camera_platform_try_fmt,
.set_bus_param = soc_camera_platform_set_bus_param,
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index 26378cf390f..1a6d39cbd6f 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -933,8 +933,6 @@ static int stk_vidioc_s_ctrl(struct file *filp,
static int stk_vidioc_enum_fmt_vid_cap(struct file *filp,
void *priv, struct v4l2_fmtdesc *fmtd)
{
- fmtd->flags = 0;
-
switch (fmtd->index) {
case 0:
fmtd->pixelformat = V4L2_PIX_FMT_RGB565;
@@ -992,7 +990,6 @@ static int stk_vidioc_g_fmt_vid_cap(struct file *filp,
pix_format->height = stk_sizes[i].h;
pix_format->field = V4L2_FIELD_NONE;
pix_format->colorspace = V4L2_COLORSPACE_SRGB;
- pix_format->priv = 0;
pix_format->pixelformat = dev->vsettings.palette;
if (dev->vsettings.palette == V4L2_PIX_FMT_SBGGR8)
pix_format->bytesperline = pix_format->width;
@@ -1115,8 +1112,6 @@ static int stk_vidioc_reqbufs(struct file *filp,
if (dev == NULL)
return -ENODEV;
- if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (rb->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if (is_streaming(dev)
@@ -1139,16 +1134,10 @@ static int stk_vidioc_reqbufs(struct file *filp,
static int stk_vidioc_querybuf(struct file *filp,
void *priv, struct v4l2_buffer *buf)
{
- int index;
struct stk_camera *dev = priv;
struct stk_sio_buffer *sbuf;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- index = buf->index;
-
- if (index < 0 || index >= dev->n_sbufs)
+ if (buf->index < 0 || buf->index >= dev->n_sbufs)
return -EINVAL;
sbuf = dev->sio_bufs + buf->index;
*buf = sbuf->v4lbuf;
@@ -1161,8 +1150,6 @@ static int stk_vidioc_qbuf(struct file *filp,
struct stk_camera *dev = priv;
struct stk_sio_buffer *sbuf;
unsigned long flags;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
@@ -1189,8 +1176,7 @@ static int stk_vidioc_dqbuf(struct file *filp,
unsigned long flags;
int ret;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
- || !is_streaming(dev))
+ if (!is_streaming(dev))
return -EINVAL;
if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
@@ -1249,16 +1235,10 @@ static int stk_vidioc_streamoff(struct file *filp,
static int stk_vidioc_g_parm(struct file *filp,
void *priv, struct v4l2_streamparm *sp)
{
- if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
- sp->parm.capture.capability = 0;
- sp->parm.capture.capturemode = 0;
/*FIXME This is not correct */
sp->parm.capture.timeperframe.numerator = 1;
sp->parm.capture.timeperframe.denominator = 30;
sp->parm.capture.readbuffers = 2;
- sp->parm.capture.extendedmode = 0;
return 0;
}
diff --git a/drivers/media/video/tcm825x.c b/drivers/media/video/tcm825x.c
index 29991d1cf13..b30c4924821 100644
--- a/drivers/media/video/tcm825x.c
+++ b/drivers/media/video/tcm825x.c
@@ -50,7 +50,7 @@ struct tcm825x_sensor {
};
/* list of image formats supported by TCM825X sensor */
-const static struct v4l2_fmtdesc tcm825x_formats[] = {
+static const struct v4l2_fmtdesc tcm825x_formats[] = {
{
.description = "YUYV (YUV 4:2:2), packed",
.pixelformat = V4L2_PIX_FMT_UYVY,
@@ -76,15 +76,15 @@ const static struct v4l2_fmtdesc tcm825x_formats[] = {
* TCM825X register configuration for all combinations of pixel format and
* image size
*/
-const static struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ };
-const static struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ };
-const static struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ };
-const static struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ };
-const static struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ };
-const static struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ };
+static const struct tcm825x_reg subqcif = { 0x20, TCM825X_PICSIZ };
+static const struct tcm825x_reg qcif = { 0x18, TCM825X_PICSIZ };
+static const struct tcm825x_reg cif = { 0x14, TCM825X_PICSIZ };
+static const struct tcm825x_reg qqvga = { 0x0c, TCM825X_PICSIZ };
+static const struct tcm825x_reg qvga = { 0x04, TCM825X_PICSIZ };
+static const struct tcm825x_reg vga = { 0x00, TCM825X_PICSIZ };
-const static struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT };
-const static struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT };
+static const struct tcm825x_reg yuv422 = { 0x00, TCM825X_PICFMT };
+static const struct tcm825x_reg rgb565 = { 0x02, TCM825X_PICFMT };
/* Our own specific controls */
#define V4L2_CID_ALC V4L2_CID_PRIVATE_BASE
@@ -248,10 +248,10 @@ static struct vcontrol {
};
-const static struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
+static const struct tcm825x_reg *tcm825x_siz_reg[NUM_IMAGE_SIZES] =
{ &subqcif, &qqvga, &qcif, &qvga, &cif, &vga };
-const static struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
+static const struct tcm825x_reg *tcm825x_fmt_reg[NUM_PIXEL_FORMATS] =
{ &yuv422, &rgb565 };
/*
diff --git a/drivers/media/video/tcm825x.h b/drivers/media/video/tcm825x.h
index 770ebacfa34..5b7e6968236 100644
--- a/drivers/media/video/tcm825x.h
+++ b/drivers/media/video/tcm825x.h
@@ -188,7 +188,7 @@ struct tcm825x_platform_data {
/* Array of image sizes supported by TCM825X. These must be ordered from
* smallest image size to largest.
*/
-const static struct capture_size tcm825x_sizes[] = {
+static const struct capture_size tcm825x_sizes[] = {
{ 128, 96 }, /* subQCIF */
{ 160, 120 }, /* QQVGA */
{ 176, 144 }, /* QCIF */
diff --git a/drivers/media/video/tda7432.c b/drivers/media/video/tda7432.c
index 0c020585fff..005f8a46803 100644
--- a/drivers/media/video/tda7432.c
+++ b/drivers/media/video/tda7432.c
@@ -50,7 +50,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/i2c-addr.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#ifndef VIDEO_AUDIO_BALANCE
# define VIDEO_AUDIO_BALANCE 32
@@ -69,13 +69,6 @@ MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)");
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_CLIENT_END,
-};
-
-I2C_CLIENT_INSMOD;
/* Structure of address and subaddresses for the tda7432 */
@@ -421,21 +414,18 @@ static int tda7432_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
switch (qc->id) {
- case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
}
return -EINVAL;
}
-static int tda7432_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda7432_core_ops = {
@@ -498,8 +488,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda7432",
- .driverid = I2C_DRIVERID_TDA7432,
- .command = tda7432_command,
.probe = tda7432_probe,
.remove = tda7432_remove,
.id_table = tda7432_id,
diff --git a/drivers/media/video/tda9840.c b/drivers/media/video/tda9840.c
index 6afb7059502..fe1158094c2 100644
--- a/drivers/media/video/tda9840.c
+++ b/drivers/media/video/tda9840.c
@@ -30,8 +30,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-#include "tda9840.h"
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("tda9840 driver");
@@ -56,11 +56,6 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
#define TDA9840_SET_BOTH_R 0x16
#define TDA9840_SET_EXTERNAL 0x7a
-/* addresses to scan, found only at 0x42 (7-Bit) */
-static unsigned short normal_i2c[] = { I2C_ADDR_TDA9840, I2C_CLIENT_END };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
static void tda9840_write(struct v4l2_subdev *sd, u8 reg, u8 val)
{
@@ -137,60 +132,17 @@ static int tda9840_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *t)
return 0;
}
-static long tda9840_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tda9840_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- int byte;
-
- switch (cmd) {
- case TDA9840_LEVEL_ADJUST:
- byte = *(int *)arg;
- v4l2_dbg(1, debug, sd, "TDA9840_LEVEL_ADJUST: %d\n", byte);
-
- /* check for correct range */
- if (byte > 25 || byte < -20)
- return -EINVAL;
-
- /* calculate actual value to set, see specs, page 18 */
- byte /= 5;
- if (0 < byte)
- byte += 0x8;
- else
- byte = -byte;
- tda9840_write(sd, LEVEL_ADJUST, byte);
- break;
-
- case TDA9840_STEREO_ADJUST:
- byte = *(int *)arg;
- v4l2_dbg(1, debug, sd, "TDA9840_STEREO_ADJUST: %d\n", byte);
-
- /* check for correct range */
- if (byte > 25 || byte < -24)
- return -EINVAL;
-
- /* calculate actual value to set */
- byte /= 5;
- if (0 < byte)
- byte += 0x20;
- else
- byte = -byte;
-
- tda9840_write(sd, STEREO_ADJUST, byte);
- break;
- default:
- return -ENOIOCTLCMD;
- }
- return 0;
-}
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
-static int tda9840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TDA9840, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda9840_core_ops = {
- .ioctl = tda9840_ioctl,
+ .g_chip_ident = tda9840_g_chip_ident,
};
static const struct v4l2_subdev_tuner_ops tda9840_tuner_ops = {
@@ -209,8 +161,6 @@ static int tda9840_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct v4l2_subdev *sd;
- int result;
- int byte;
/* let's see whether this adapter can support what we need */
if (!i2c_check_functionality(client->adapter,
@@ -227,15 +177,9 @@ static int tda9840_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(sd, client, &tda9840_ops);
/* set initial values for level & stereo - adjustment, mode */
- byte = 0;
- result = tda9840_ioctl(sd, TDA9840_LEVEL_ADJUST, &byte);
- result |= tda9840_ioctl(sd, TDA9840_STEREO_ADJUST, &byte);
+ tda9840_write(sd, LEVEL_ADJUST, 0);
+ tda9840_write(sd, STEREO_ADJUST, 0);
tda9840_write(sd, SWITCH, TDA9840_SET_STEREO);
- if (result) {
- v4l2_dbg(1, debug, sd, "could not initialize tda9840\n");
- kfree(sd);
- return -ENODEV;
- }
return 0;
}
@@ -248,12 +192,7 @@ static int tda9840_remove(struct i2c_client *client)
return 0;
}
-static int tda9840_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
+
static const struct i2c_device_id tda9840_id[] = {
{ "tda9840", 0 },
{ }
@@ -262,10 +201,7 @@ MODULE_DEVICE_TABLE(i2c, tda9840_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda9840",
- .driverid = I2C_DRIVERID_TDA9840,
- .command = tda9840_command,
.probe = tda9840_probe,
.remove = tda9840_remove,
- .legacy_probe = tda9840_legacy_probe,
.id_table = tda9840_id,
};
diff --git a/drivers/media/video/tda9840.h b/drivers/media/video/tda9840.h
deleted file mode 100644
index dc12ae7caf6..00000000000
--- a/drivers/media/video/tda9840.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#ifndef __INCLUDED_TDA9840__
-#define __INCLUDED_TDA9840__
-
-#define I2C_ADDR_TDA9840 0x42
-
-/* values may range between +2.5 and -2.0;
- the value has to be multiplied with 10 */
-#define TDA9840_LEVEL_ADJUST _IOW('v',3,int)
-
-/* values may range between +2.5 and -2.4;
- the value has to be multiplied with 10 */
-#define TDA9840_STEREO_ADJUST _IOW('v',4,int)
-
-#endif
diff --git a/drivers/media/video/tda9875.c b/drivers/media/video/tda9875.c
index 00c6cbe06ab..24e2b7d2ae5 100644
--- a/drivers/media/video/tda9875.c
+++ b/drivers/media/video/tda9875.c
@@ -28,20 +28,13 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/i2c-addr.h>
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_CLIENT_END
-};
-
-I2C_CLIENT_INSMOD;
/* This is a superset of the TDA9875 */
struct tda9875 {
@@ -313,18 +306,14 @@ static int tda9875_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
switch (qc->id) {
case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill_std(qc);
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
}
return -EINVAL;
}
-static int tda9875_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda9875_core_ops = {
@@ -401,8 +390,6 @@ MODULE_DEVICE_TABLE(i2c, tda9875_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda9875",
- .driverid = I2C_DRIVERID_TDA9875,
- .command = tda9875_command,
.probe = tda9875_probe,
.remove = tda9875_remove,
.id_table = tda9875_id,
diff --git a/drivers/media/video/tea6415c.c b/drivers/media/video/tea6415c.c
index 7519fd1f57e..d61c56f42bc 100644
--- a/drivers/media/video/tea6415c.c
+++ b/drivers/media/video/tea6415c.c
@@ -32,7 +32,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "tea6415c.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,25 +45,22 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-/* addresses to scan, found only at 0x03 and/or 0x43 (7-bit) */
-static unsigned short normal_i2c[] = { I2C_TEA6415C_1, I2C_TEA6415C_2, I2C_CLIENT_END };
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
-
-/* makes a connection between the input-pin 'i' and the output-pin 'o'
- for the tea6415c-client 'client' */
-static int switch_matrix(struct i2c_client *client, int i, int o)
+/* makes a connection between the input-pin 'i' and the output-pin 'o' */
+static int tea6415c_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 byte = 0;
+ u32 i = route->input;
+ u32 o = route->output;
int ret;
- v4l_dbg(1, debug, client, "i=%d, o=%d\n", i, o);
+ v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);
/* check if the pins are valid */
if (0 == ((1 == i || 3 == i || 5 == i || 6 == i || 8 == i || 10 == i || 20 == i || 11 == i)
&& (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))
- return -1;
+ return -EINVAL;
/* to understand this, have a look at the tea6415c-specs (p.5) */
switch (o) {
@@ -115,37 +113,33 @@ static int switch_matrix(struct i2c_client *client, int i, int o)
ret = i2c_smbus_write_byte(client, byte);
if (ret) {
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"i2c_smbus_write_byte() failed, ret:%d\n", ret);
return -EIO;
}
return ret;
}
-static long tea6415c_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6415c_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- if (cmd == TEA6415C_SWITCH) {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tea6415c_multiplex *v = (struct tea6415c_multiplex *)arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return switch_matrix(client, v->in, v->out);
- }
- return -ENOIOCTLCMD;
-}
-
-static int tea6415c_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6415C, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tea6415c_core_ops = {
- .ioctl = tea6415c_ioctl,
+ .g_chip_ident = tea6415c_g_chip_ident,
+};
+
+static const struct v4l2_subdev_video_ops tea6415c_video_ops = {
+ .s_routing = tea6415c_s_routing,
};
static const struct v4l2_subdev_ops tea6415c_ops = {
.core = &tea6415c_core_ops,
+ .video = &tea6415c_video_ops,
};
/* this function is called by i2c_probe */
@@ -176,12 +170,6 @@ static int tea6415c_remove(struct i2c_client *client)
return 0;
}
-static int tea6415c_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
static const struct i2c_device_id tea6415c_id[] = {
{ "tea6415c", 0 },
@@ -191,10 +179,7 @@ MODULE_DEVICE_TABLE(i2c, tea6415c_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tea6415c",
- .driverid = I2C_DRIVERID_TEA6415C,
- .command = tea6415c_command,
.probe = tea6415c_probe,
.remove = tea6415c_remove,
- .legacy_probe = tea6415c_legacy_probe,
.id_table = tea6415c_id,
};
diff --git a/drivers/media/video/tea6415c.h b/drivers/media/video/tea6415c.h
index f84ed80050b..3a47d697536 100644
--- a/drivers/media/video/tea6415c.h
+++ b/drivers/media/video/tea6415c.h
@@ -1,10 +1,6 @@
#ifndef __INCLUDED_TEA6415C__
#define __INCLUDED_TEA6415C__
-/* possible i2c-addresses */
-#define I2C_TEA6415C_1 0x03
-#define I2C_TEA6415C_2 0x43
-
/* the tea6415c's design is quite brain-dead. although there are
8 inputs and 6 outputs, these aren't enumerated in any way. because
I don't want to say "connect input pin 20 to output pin 17", I define
@@ -28,12 +24,4 @@
#define TEA6415C_INPUT7 1
#define TEA6415C_INPUT8 11
-struct tea6415c_multiplex
-{
- int in; /* input-pin */
- int out; /* output-pin */
-};
-
-#define TEA6415C_SWITCH _IOW('v',1,struct tea6415c_multiplex)
-
#endif
diff --git a/drivers/media/video/tea6420.c b/drivers/media/video/tea6420.c
index 081e74fa3b2..34922232402 100644
--- a/drivers/media/video/tea6420.c
+++ b/drivers/media/video/tea6420.c
@@ -32,7 +32,8 @@
#include <linux/ioctl.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
#include "tea6420.h"
MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
@@ -44,24 +45,23 @@ module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
-/* 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 };
-
-/* magic definition of all other variables and things */
-I2C_CLIENT_INSMOD;
/* make a connection between the input 'i' and the output 'o'
- with gain 'g' for the tea6420-client 'client' (note: i = 6 means 'mute') */
-static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
+ with gain 'g' (note: i = 6 means 'mute') */
+static int tea6420_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int i = route->input;
+ int o = route->output & 0xf;
+ int g = (route->output >> 4) & 0xf;
u8 byte;
int ret;
- v4l_dbg(1, debug, client, "i=%d, o=%d, g=%d\n", i, o, g);
+ v4l2_dbg(1, debug, sd, "i=%d, o=%d, g=%d\n", i, o, g);
/* check if the parameters are valid */
if (i < 1 || i > 6 || o < 1 || o > 4 || g < 0 || g > 6 || g % 2 != 0)
- return -1;
+ return -EINVAL;
byte = ((o - 1) << 5);
byte |= (i - 1);
@@ -83,37 +83,33 @@ static int tea6420_switch(struct i2c_client *client, int i, int o, int g)
ret = i2c_smbus_write_byte(client, byte);
if (ret) {
- v4l_dbg(1, debug, client,
+ v4l2_dbg(1, debug, sd,
"i2c_smbus_write_byte() failed, ret:%d\n", ret);
return -EIO;
}
return 0;
}
-static long tea6420_ioctl(struct v4l2_subdev *sd, unsigned cmd, void *arg)
+static int tea6420_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- if (cmd == TEA6420_SWITCH) {
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct tea6420_multiplex *a = (struct tea6420_multiplex *)arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return tea6420_switch(client, a->in, a->out, a->gain);
- }
- return -ENOIOCTLCMD;
-}
-
-static int tea6420_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TEA6420, 0);
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tea6420_core_ops = {
- .ioctl = tea6420_ioctl,
+ .g_chip_ident = tea6420_g_chip_ident,
+};
+
+static const struct v4l2_subdev_audio_ops tea6420_audio_ops = {
+ .s_routing = tea6420_s_routing,
};
static const struct v4l2_subdev_ops tea6420_ops = {
.core = &tea6420_core_ops,
+ .audio = &tea6420_audio_ops,
};
/* this function is called by i2c_probe */
@@ -130,20 +126,24 @@ static int tea6420_probe(struct i2c_client *client,
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
+ sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ if (sd == NULL)
+ return -ENOMEM;
+ v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
+
/* set initial values: set "mute"-input to all outputs at gain 0 */
err = 0;
for (i = 1; i < 5; i++) {
- err += tea6420_switch(client, 6, i, 0);
+ struct v4l2_routing route;
+
+ route.input = 6;
+ route.output = i;
+ err += tea6420_s_routing(sd, &route);
}
if (err) {
v4l_dbg(1, debug, client, "could not initialize tea6420\n");
return -ENODEV;
}
-
- sd = kmalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
- if (sd == NULL)
- return -ENOMEM;
- v4l2_i2c_subdev_init(sd, client, &tea6420_ops);
return 0;
}
@@ -156,12 +156,6 @@ static int tea6420_remove(struct i2c_client *client)
return 0;
}
-static int tea6420_legacy_probe(struct i2c_adapter *adapter)
-{
- /* Let's see whether this is a known adapter we can attach to.
- Prevents conflicts with tvaudio.c. */
- return adapter->id == I2C_HW_SAA7146;
-}
static const struct i2c_device_id tea6420_id[] = {
{ "tea6420", 0 },
@@ -171,10 +165,7 @@ MODULE_DEVICE_TABLE(i2c, tea6420_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tea6420",
- .driverid = I2C_DRIVERID_TEA6420,
- .command = tea6420_command,
.probe = tea6420_probe,
.remove = tea6420_remove,
- .legacy_probe = tea6420_legacy_probe,
.id_table = tea6420_id,
};
diff --git a/drivers/media/video/tea6420.h b/drivers/media/video/tea6420.h
index 5ef7c18e0c5..4aa3edb3e19 100644
--- a/drivers/media/video/tea6420.h
+++ b/drivers/media/video/tea6420.h
@@ -1,17 +1,24 @@
#ifndef __INCLUDED_TEA6420__
#define __INCLUDED_TEA6420__
-/* possible addresses */
-#define I2C_ADDR_TEA6420_1 0x4c
-#define I2C_ADDR_TEA6420_2 0x4d
+/* input pins */
+#define TEA6420_OUTPUT1 1
+#define TEA6420_OUTPUT2 2
+#define TEA6420_OUTPUT3 3
+#define TEA6420_OUTPUT4 4
-struct tea6420_multiplex
-{
- int in; /* input of audio switch */
- int out; /* output of audio switch */
- int gain; /* gain of connection */
-};
+/* output pins */
+#define TEA6420_INPUT1 1
+#define TEA6420_INPUT2 2
+#define TEA6420_INPUT3 3
+#define TEA6420_INPUT4 4
+#define TEA6420_INPUT5 5
+#define TEA6420_INPUT6 6
-#define TEA6420_SWITCH _IOW('v',1,struct tea6420_multiplex)
+/* gain on the output pins, ORed with the output pin */
+#define TEA6420_GAIN0 0x00
+#define TEA6420_GAIN2 0x20
+#define TEA6420_GAIN4 0x40
+#define TEA6420_GAIN6 0x60
#endif
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index 5c95ecd09dc..07789c64814 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -31,15 +31,12 @@
#include <linux/i2c-id.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("tlv320aic23b driver");
MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
MODULE_LICENSE("GPL");
-static unsigned short normal_i2c[] = { 0x34 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -121,11 +118,6 @@ static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int tlv320aic23b_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
@@ -208,8 +200,6 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tlv320aic23b",
- .driverid = I2C_DRIVERID_TLV320AIC23B,
- .command = tlv320aic23b_command,
.probe = tlv320aic23b_probe,
.remove = tlv320aic23b_remove,
.id_table = tlv320aic23b_id,
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 30640fbfd0f..72d41032742 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -364,7 +364,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
}
t->type = type;
- t->config = new_config;
+ /* prevent invalid config values */
+ t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0;
if (tuner_callback != NULL) {
tuner_dbg("defining GPIO callback\n");
t->fe.callback = tuner_callback;
@@ -452,7 +453,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
struct dvb_tuner_ops *xc_tuner_ops;
xc5000_cfg.i2c_address = t->i2c->addr;
- xc5000_cfg.if_khz = 5380;
+ /* if_khz will be set when the digital dvb_attach() occurs */
+ xc5000_cfg.if_khz = 0;
if (!dvb_attach(xc5000_attach,
&t->fe, t->i2c->adapter, &xc5000_cfg))
goto attach_failed;
@@ -776,8 +778,7 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
- == -EINVAL)
+ if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
return 0;
if (t->radio_freq)
set_freq(client, t->radio_freq);
@@ -791,7 +792,7 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
tuner_dbg("Putting tuner to sleep\n");
- if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
+ if (check_mode(t, "s_standby") == -EINVAL)
return 0;
t->mode = T_STANDBY;
if (analog_ops->standby)
@@ -799,132 +800,6 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
return 0;
}
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static long tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
- struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-
- switch (cmd) {
- case VIDIOCSAUDIO:
- if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- /* Should be implemented, since bttv calls it */
- tuner_dbg("VIDIOCSAUDIO not implemented.\n");
- break;
- case VIDIOCSCHAN:
- {
- static const v4l2_std_id map[] = {
- [VIDEO_MODE_PAL] = V4L2_STD_PAL,
- [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
- [VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
- [4 /* bttv */ ] = V4L2_STD_PAL_M,
- [5 /* bttv */ ] = V4L2_STD_PAL_N,
- [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
- };
- struct video_channel *vc = arg;
-
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL)
- return 0;
-
- if (vc->norm < ARRAY_SIZE(map))
- t->std = map[vc->norm];
- tuner_fixup_std(t);
- if (t->tv_freq)
- set_tv_freq(client, t->tv_freq);
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long *v = arg;
-
- if (check_mode(t, "VIDIOCSFREQ") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- set_freq(client, *v);
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner *vt = arg;
-
- if (check_mode(t, "VIDIOCGTUNER") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (V4L2_TUNER_RADIO == t->mode) {
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- if (tuner_status & TUNER_STATUS_STEREO)
- vt->flags |= VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &= ~VIDEO_TUNER_STEREO_ON;
- } else {
- if (analog_ops->is_stereo) {
- if (analog_ops->is_stereo(&t->fe))
- vt->flags |=
- VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &=
- ~VIDEO_TUNER_STEREO_ON;
- }
- }
- if (analog_ops->has_signal)
- vt->signal =
- analog_ops->has_signal(&t->fe);
-
- vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
-
- vt->rangelow = radio_range[0] * 16000;
- vt->rangehigh = radio_range[1] * 16000;
-
- } else {
- vt->rangelow = tv_range[0] * 16;
- vt->rangehigh = tv_range[1] * 16;
- }
-
- return 0;
- }
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (V4L2_TUNER_RADIO == t->mode) {
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- va->mode = (tuner_status & TUNER_STATUS_STEREO)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- } else if (analog_ops->is_stereo)
- va->mode = analog_ops->is_stereo(&t->fe)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- }
- return 0;
- }
- }
- return -ENOIOCTLCMD;
-}
-#endif
-
static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
{
struct tuner *t = to_tuner(sd);
@@ -950,8 +825,7 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
- == -EINVAL)
+ if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL)
return 0;
switch_v4l2();
@@ -968,8 +842,7 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, f->type, "VIDIOC_S_FREQUENCY")
- == -EINVAL)
+ if (set_mode(client, t, f->type, "s_frequency") == -EINVAL)
return 0;
switch_v4l2();
set_freq(client, f->frequency);
@@ -982,7 +855,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
struct tuner *t = to_tuner(sd);
struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL)
+ if (check_mode(t, "g_frequency") == -EINVAL)
return 0;
switch_v4l2();
f->type = t->mode;
@@ -1006,7 +879,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL)
+ if (check_mode(t, "g_tuner") == -EINVAL)
return 0;
switch_v4l2();
@@ -1055,7 +928,7 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL)
+ if (check_mode(t, "s_tuner") == -EINVAL)
return 0;
switch_v4l2();
@@ -1112,9 +985,6 @@ static int tuner_resume(struct i2c_client *c)
static const struct v4l2_subdev_core_ops tuner_core_ops = {
.log_status = tuner_log_status,
.s_standby = tuner_s_standby,
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
- .ioctl = tuner_ioctl,
-#endif
};
static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
index 076ed5bf48b..226bf3565ac 100644
--- a/drivers/media/video/tvaudio.c
+++ b/drivers/media/video/tvaudio.c
@@ -26,7 +26,7 @@
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/slab.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/kthread.h>
@@ -1047,6 +1047,116 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
return 0;
}
+/* ---------------------------------------------------------------------- */
+/* audio chip description - defines+functions for tda9875 */
+/* The TDA9875 is made by Philips Semiconductor
+ * http://www.semiconductors.philips.com
+ * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
+ *
+ */
+
+/* subaddresses for TDA9875 */
+#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/
+#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */
+#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/
+#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/
+
+#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/
+#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/
+#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/
+#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/
+
+#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/
+#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/
+#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/
+#define TDA9875_MVL 0x1a /* Main volume gauche */
+#define TDA9875_MVR 0x1b /* Main volume droite */
+#define TDA9875_MBA 0x1d /* Main Basse */
+#define TDA9875_MTR 0x1e /* Main treble */
+#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/
+#define TDA9875_AVL 0x20 /* Auxilary volume gauche */
+#define TDA9875_AVR 0x21 /* Auxilary volume droite */
+#define TDA9875_ABA 0x22 /* Auxilary Basse */
+#define TDA9875_ATR 0x23 /* Auxilary treble */
+
+#define TDA9875_MSR 0x02 /* Monitor select register */
+#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */
+#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */
+#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */
+#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */
+#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */
+#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */
+#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/
+#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/
+#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/
+
+/* values */
+#define TDA9875_MUTE_ON 0xff /* general mute */
+#define TDA9875_MUTE_OFF 0xcc /* general no mute */
+
+static int tda9875_initialize(struct CHIPSTATE *chip)
+{
+ chip_write(chip, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
+ chip_write(chip, TDA9875_MSR, 0x03); /* Monitor 0b00000XXX*/
+ chip_write(chip, TDA9875_C1MSB, 0x00); /*Car1(FM) MSB XMHz*/
+ chip_write(chip, TDA9875_C1MIB, 0x00); /*Car1(FM) MIB XMHz*/
+ chip_write(chip, TDA9875_C1LSB, 0x00); /*Car1(FM) LSB XMHz*/
+ chip_write(chip, TDA9875_C2MSB, 0x00); /*Car2(NICAM) MSB XMHz*/
+ chip_write(chip, TDA9875_C2MIB, 0x00); /*Car2(NICAM) MIB XMHz*/
+ chip_write(chip, TDA9875_C2LSB, 0x00); /*Car2(NICAM) LSB XMHz*/
+ chip_write(chip, TDA9875_DCR, 0x00); /*Demod config 0x00*/
+ chip_write(chip, TDA9875_DEEM, 0x44); /*DE-Emph 0b0100 0100*/
+ chip_write(chip, TDA9875_FMAT, 0x00); /*FM Matrix reg 0x00*/
+ chip_write(chip, TDA9875_SC1, 0x00); /* SCART 1 (SC1)*/
+ chip_write(chip, TDA9875_SC2, 0x01); /* SCART 2 (sc2)*/
+
+ chip_write(chip, TDA9875_CH1V, 0x10); /* Channel volume 1 mute*/
+ chip_write(chip, TDA9875_CH2V, 0x10); /* Channel volume 2 mute */
+ chip_write(chip, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
+ chip_write(chip, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
+ chip_write(chip, TDA9875_LOSR, 0x00); /* line out (in:mono)*/
+ chip_write(chip, TDA9875_AER, 0x00); /*06 Effect (AVL+PSEUDO) */
+ chip_write(chip, TDA9875_MCS, 0x44); /* Main ch select (DAC) */
+ chip_write(chip, TDA9875_MVL, 0x03); /* Vol Main left 10dB */
+ chip_write(chip, TDA9875_MVR, 0x03); /* Vol Main right 10dB*/
+ chip_write(chip, TDA9875_MBA, 0x00); /* Main Bass Main 0dB*/
+ chip_write(chip, TDA9875_MTR, 0x00); /* Main Treble Main 0dB*/
+ chip_write(chip, TDA9875_ACS, 0x44); /* Aux chan select (dac)*/
+ chip_write(chip, TDA9875_AVL, 0x00); /* Vol Aux left 0dB*/
+ chip_write(chip, TDA9875_AVR, 0x00); /* Vol Aux right 0dB*/
+ chip_write(chip, TDA9875_ABA, 0x00); /* Aux Bass Main 0dB*/
+ chip_write(chip, TDA9875_ATR, 0x00); /* Aux Aigus Main 0dB*/
+
+ chip_write(chip, TDA9875_MUT, 0xcc); /* General mute */
+ return 0;
+}
+
+static int tda9875_volume(int val) { return (unsigned char)(val / 602 - 84); }
+static int tda9875_bass(int val) { return (unsigned char)(max(-12, val / 2115 - 15)); }
+static int tda9875_treble(int val) { return (unsigned char)(val / 2622 - 12); }
+
+/* ----------------------------------------------------------------------- */
+
+
+/* *********************** *
+ * i2c interface functions *
+ * *********************** */
+
+static int tda9875_checkit(struct CHIPSTATE *chip)
+{
+ struct v4l2_subdev *sd = &chip->sd;
+ int dic, rev;
+
+ dic = chip_read2(chip, 254);
+ rev = chip_read2(chip, 255);
+
+ if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
+ v4l2_info(sd, "found tda9875%s rev. %d.\n",
+ dic == 0 ? "" : "A", rev);
+ return 1;
+ }
+ return 0;
+}
/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tea6420 */
@@ -1280,6 +1390,7 @@ static int tda9850 = 1;
static int tda9855 = 1;
static int tda9873 = 1;
static int tda9874a = 1;
+static int tda9875 = 1;
static int tea6300; /* default 0 - address clash with msp34xx */
static int tea6320; /* default 0 - address clash with msp34xx */
static int tea6420 = 1;
@@ -1292,6 +1403,7 @@ module_param(tda9850, int, 0444);
module_param(tda9855, int, 0444);
module_param(tda9873, int, 0444);
module_param(tda9874a, int, 0444);
+module_param(tda9875, int, 0444);
module_param(tea6300, int, 0444);
module_param(tea6320, int, 0444);
module_param(tea6420, int, 0444);
@@ -1349,6 +1461,26 @@ static struct CHIPDESC chiplist[] = {
.setmode = tda9874a_setmode,
},
{
+ .name = "tda9875",
+ .insmodopt = &tda9875,
+ .addr_lo = I2C_ADDR_TDA9875 >> 1,
+ .addr_hi = I2C_ADDR_TDA9875 >> 1,
+ .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
+
+ /* callbacks */
+ .initialize = tda9875_initialize,
+ .checkit = tda9875_checkit,
+ .volfunc = tda9875_volume,
+ .bassfunc = tda9875_bass,
+ .treblefunc = tda9875_treble,
+ .leftreg = TDA9875_MVL,
+ .rightreg = TDA9875_MVR,
+ .bassreg = TDA9875_MBA,
+ .treblereg = TDA9875_MTR,
+ .leftinit = 58880,
+ .rightinit = 58880,
+ },
+ {
.name = "tda9850",
.insmodopt = &tda9850,
.addr_lo = I2C_ADDR_TDA985x_L >> 1,
@@ -1511,6 +1643,8 @@ static int tvaudio_g_ctrl(struct v4l2_subdev *sd,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ break;
ctrl->value=chip->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
@@ -1552,6 +1686,9 @@ static int tvaudio_s_ctrl(struct v4l2_subdev *sd,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ break;
+
if (ctrl->value < 0 || ctrl->value >= 2)
return -ERANGE;
chip->muted = ctrl->value;
@@ -1636,21 +1773,26 @@ static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
switch (qc->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (desc->flags & CHIP_HAS_INPUTSEL)
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
break;
case V4L2_CID_AUDIO_VOLUME:
+ if (desc->flags & CHIP_HAS_VOLUME)
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
+ break;
case V4L2_CID_AUDIO_BALANCE:
- if (!(desc->flags & CHIP_HAS_VOLUME))
- return -EINVAL;
+ if (desc->flags & CHIP_HAS_VOLUME)
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
break;
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- if (!(desc->flags & CHIP_HAS_BASSTREBLE))
- return -EINVAL;
+ if (desc->flags & CHIP_HAS_BASSTREBLE)
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
break;
default:
- return -EINVAL;
+ break;
}
- return v4l2_ctrl_query_fill_std(qc);
+ return -EINVAL;
}
static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *rt)
@@ -1658,7 +1800,9 @@ static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
struct CHIPSTATE *chip = to_state(sd);
struct CHIPDESC *desc = chip->desc;
- if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ return 0;
+ if (rt->input >= 4)
return -EINVAL;
/* There are four inputs: tuner, radio, extern and intern. */
chip->input = rt->input;
@@ -1675,8 +1819,11 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct CHIPDESC *desc = chip->desc;
int mode = 0;
+ if (!desc->setmode)
+ return 0;
if (chip->radio)
return 0;
+
switch (vt->audmode) {
case V4L2_TUNER_MODE_MONO:
case V4L2_TUNER_MODE_STEREO:
@@ -1692,7 +1839,7 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
}
chip->audmode = vt->audmode;
- if (desc->setmode && mode) {
+ if (mode) {
chip->watch_stereo = 0;
/* del_timer(&chip->wt); */
chip->mode = mode;
@@ -1707,15 +1854,17 @@ static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct CHIPDESC *desc = chip->desc;
int mode = V4L2_TUNER_MODE_MONO;
+ if (!desc->getmode)
+ return 0;
if (chip->radio)
return 0;
+
vt->audmode = chip->audmode;
vt->rxsubchans = 0;
vt->capability = V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
- if (desc->getmode)
- mode = desc->getmode(chip);
+ mode = desc->getmode(chip);
if (mode & V4L2_TUNER_MODE_MONO)
vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
@@ -1901,6 +2050,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
}
chip->thread = NULL;
+ init_timer(&chip->wt);
if (desc->flags & CHIP_NEED_CHECKMODE) {
if (!desc->getmode || !desc->setmode) {
/* This shouldn't be happen. Warn user, but keep working
@@ -1910,7 +2060,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
return 0;
}
/* start async thread */
- init_timer(&chip->wt);
chip->wt.function = chip_thread_wake;
chip->wt.data = (unsigned long)chip;
chip->thread = kthread_run(chip_thread, chip, client->name);
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c
index 78277abb733..e24a38c7fa4 100644
--- a/drivers/media/video/tveeprom.c
+++ b/drivers/media/video/tveeprom.c
@@ -261,7 +261,12 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "MaxLinear MXL5005_v2"},
{ TUNER_PHILIPS_TDA8290, "Philips 18271_8295"},
/* 150-159 */
- { TUNER_ABSENT, "Xceive XC5000"},
+ { TUNER_XC5000, "Xceive XC5000"},
+ { TUNER_ABSENT, "Xceive XC3028L"},
+ { TUNER_ABSENT, "NXP 18271C2_716x"},
+ { TUNER_ABSENT, "Xceive XC4000"},
+ { TUNER_ABSENT, "Dibcom 7070"},
+ { TUNER_PHILIPS_TDA8290, "NXP 18271C2"},
};
/* Use V4L2_IDENT_AMBIGUOUS for those audio 'chips' that are
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 8e23aa53c29..4262e60b811 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -86,9 +86,12 @@ struct tvp514x_std_info {
struct v4l2_standard standard;
};
+static struct tvp514x_reg tvp514x_reg_list_default[0x40];
/**
- * struct tvp514x_decoded - TVP5146/47 decoder object
+ * struct tvp514x_decoder - TVP5146/47 decoder object
* @v4l2_int_device: Slave handle
+ * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device
+ * @tvp514x_regs: copy of hw's regs with preset values.
* @pdata: Board specific
* @client: I2C client data
* @id: Entry from I2C table
@@ -103,7 +106,9 @@ struct tvp514x_std_info {
* @route: input and output routing at chip level
*/
struct tvp514x_decoder {
- struct v4l2_int_device *v4l2_int_device;
+ struct v4l2_int_device v4l2_int_device;
+ struct v4l2_int_slave tvp514x_slave;
+ struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
const struct tvp514x_platform_data *pdata;
struct i2c_client *client;
@@ -124,7 +129,7 @@ struct tvp514x_decoder {
};
/* TVP514x default register values */
-static struct tvp514x_reg tvp514x_reg_list[] = {
+static struct tvp514x_reg tvp514x_reg_list_default[] = {
{TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */
{TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
{TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */
@@ -422,7 +427,7 @@ static int tvp514x_configure(struct tvp514x_decoder *decoder)
/* common register initialization */
err =
- tvp514x_write_regs(decoder->client, tvp514x_reg_list);
+ tvp514x_write_regs(decoder->client, decoder->tvp514x_regs);
if (err)
return err;
@@ -580,7 +585,8 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
return err;
decoder->current_std = i;
- tvp514x_reg_list[REG_VIDEO_STD].val = decoder->std_list[i].video_std;
+ decoder->tvp514x_regs[REG_VIDEO_STD].val =
+ decoder->std_list[i].video_std;
v4l_dbg(1, debug, decoder->client, "Standard set to: %s",
decoder->std_list[i].standard.name);
@@ -625,8 +631,8 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
if (err)
return err;
- tvp514x_reg_list[REG_INPUT_SEL].val = input_sel;
- tvp514x_reg_list[REG_OUTPUT_FORMATTER1].val = output_sel;
+ decoder->tvp514x_regs[REG_INPUT_SEL].val = input_sel;
+ decoder->tvp514x_regs[REG_OUTPUT_FORMATTER1].val = output_sel;
/* Clear status */
msleep(LOCK_RETRY_DELAY);
@@ -686,7 +692,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
break; /* Input detected */
}
- if ((current_std == STD_INVALID) || (try_count < 0))
+ if ((current_std == STD_INVALID) || (try_count <= 0))
return -EINVAL;
decoder->current_std = current_std;
@@ -719,10 +725,9 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
switch (qctrl->id) {
case V4L2_CID_BRIGHTNESS:
- /* Brightness supported is same as standard one (0-255),
- * so make use of standard API provided.
+ /* Brightness supported is (0-255),
*/
- err = v4l2_ctrl_query_fill_std(qctrl);
+ err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
break;
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
@@ -779,16 +784,16 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
- ctrl->value = tvp514x_reg_list[REG_BRIGHTNESS].val;
+ ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val;
break;
case V4L2_CID_CONTRAST:
- ctrl->value = tvp514x_reg_list[REG_CONTRAST].val;
+ ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val;
break;
case V4L2_CID_SATURATION:
- ctrl->value = tvp514x_reg_list[REG_SATURATION].val;
+ ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val;
break;
case V4L2_CID_HUE:
- ctrl->value = tvp514x_reg_list[REG_HUE].val;
+ ctrl->value = decoder->tvp514x_regs[REG_HUE].val;
if (ctrl->value == 0x7F)
ctrl->value = 180;
else if (ctrl->value == 0x80)
@@ -798,7 +803,7 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
break;
case V4L2_CID_AUTOGAIN:
- ctrl->value = tvp514x_reg_list[REG_AFE_GAIN_CTRL].val;
+ ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val;
if ((ctrl->value & 0x3) == 3)
ctrl->value = 1;
else
@@ -848,7 +853,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_BRIGHTNESS].val = value;
+ decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
break;
case V4L2_CID_CONTRAST:
if (ctrl->value < 0 || ctrl->value > 255) {
@@ -861,7 +866,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_CONTRAST].val = value;
+ decoder->tvp514x_regs[REG_CONTRAST].val = value;
break;
case V4L2_CID_SATURATION:
if (ctrl->value < 0 || ctrl->value > 255) {
@@ -874,7 +879,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_SATURATION].val = value;
+ decoder->tvp514x_regs[REG_SATURATION].val = value;
break;
case V4L2_CID_HUE:
if (value == 180)
@@ -893,7 +898,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_HUE].val = value;
+ decoder->tvp514x_regs[REG_HUE].val = value;
break;
case V4L2_CID_AUTOGAIN:
if (value == 1)
@@ -910,7 +915,7 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
value);
if (err)
return err;
- tvp514x_reg_list[REG_AFE_GAIN_CTRL].val = value;
+ decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
break;
default:
v4l_err(decoder->client,
@@ -1275,7 +1280,7 @@ static int ioctl_init(struct v4l2_int_device *s)
struct tvp514x_decoder *decoder = s->priv;
/* Set default standard to auto */
- tvp514x_reg_list[REG_VIDEO_STD].val =
+ decoder->tvp514x_regs[REG_VIDEO_STD].val =
VIDEO_STD_AUTO_SWITCH_BIT;
return tvp514x_configure(decoder);
@@ -1344,11 +1349,6 @@ static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = {
(v4l2_int_ioctl_func *) ioctl_s_routing},
};
-static struct v4l2_int_slave tvp514x_slave = {
- .ioctls = tvp514x_ioctl_desc,
- .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
-};
-
static struct tvp514x_decoder tvp514x_dev = {
.state = STATE_NOT_DETECTED,
@@ -1369,17 +1369,15 @@ static struct tvp514x_decoder tvp514x_dev = {
.current_std = STD_NTSC_MJ,
.std_list = tvp514x_std_list,
.num_stds = ARRAY_SIZE(tvp514x_std_list),
-
-};
-
-static struct v4l2_int_device tvp514x_int_device = {
- .module = THIS_MODULE,
- .name = TVP514X_MODULE_NAME,
- .priv = &tvp514x_dev,
- .type = v4l2_int_type_slave,
- .u = {
- .slave = &tvp514x_slave,
- },
+ .v4l2_int_device = {
+ .module = THIS_MODULE,
+ .name = TVP514X_MODULE_NAME,
+ .type = v4l2_int_type_slave,
+ },
+ .tvp514x_slave = {
+ .ioctls = tvp514x_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
+ },
};
/**
@@ -1392,26 +1390,37 @@ static struct v4l2_int_device tvp514x_int_device = {
static int
tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
- struct tvp514x_decoder *decoder = &tvp514x_dev;
+ struct tvp514x_decoder *decoder;
int err;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
- decoder->pdata = client->dev.platform_data;
- if (!decoder->pdata) {
+ decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
+ if (!decoder)
+ return -ENOMEM;
+
+ if (!client->dev.platform_data) {
v4l_err(client, "No platform data!!\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto out_free;
}
+
+ *decoder = tvp514x_dev;
+ decoder->v4l2_int_device.priv = decoder;
+ decoder->pdata = client->dev.platform_data;
+ decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave;
+ memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
+ sizeof(tvp514x_reg_list_default));
/*
* Fetch platform specific data, and configure the
* tvp514x_reg_list[] accordingly. Since this is one
* time configuration, no need to preserve.
*/
- tvp514x_reg_list[REG_OUTPUT_FORMATTER2].val |=
+ decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
(decoder->pdata->clk_polarity << 1);
- tvp514x_reg_list[REG_SYNC_CONTROL].val |=
+ decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
((decoder->pdata->hs_polarity << 2) |
(decoder->pdata->vs_polarity << 3));
/*
@@ -1419,23 +1428,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
*/
decoder->id = (struct i2c_device_id *)id;
/* Attach to Master */
- strcpy(tvp514x_int_device.u.slave->attach_to, decoder->pdata->master);
- decoder->v4l2_int_device = &tvp514x_int_device;
+ strcpy(decoder->v4l2_int_device.u.slave->attach_to,
+ decoder->pdata->master);
decoder->client = client;
i2c_set_clientdata(client, decoder);
/* Register with V4L2 layer as slave device */
- err = v4l2_int_device_register(decoder->v4l2_int_device);
+ err = v4l2_int_device_register(&decoder->v4l2_int_device);
if (err) {
i2c_set_clientdata(client, NULL);
v4l_err(client,
"Unable to register to v4l2. Err[%d]\n", err);
+ goto out_free;
} else
v4l_info(client, "Registered to v4l2 master %s!!\n",
decoder->pdata->master);
-
return 0;
+
+out_free:
+ kfree(decoder);
+ return err;
}
/**
@@ -1452,9 +1465,9 @@ static int __exit tvp514x_remove(struct i2c_client *client)
if (!client->adapter)
return -ENODEV; /* our client isn't attached */
- v4l2_int_device_unregister(decoder->v4l2_int_device);
+ v4l2_int_device_unregister(&decoder->v4l2_int_device);
i2c_set_clientdata(client, NULL);
-
+ kfree(decoder);
return 0;
}
/*
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 2cd64ef27b9..3a5a95f134b 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -8,7 +8,6 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <linux/delay.h>
-#include <linux/video_decoder.h>
#include <media/v4l2-device.h>
#include <media/tvp5150.h>
#include <media/v4l2-i2c-drv-legacy.h>
@@ -632,7 +631,7 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
const struct i2c_vbi_ram_value *regs = vbi_ram_default;
int line;
- v4l2_dbg(1, debug, sd, "VIDIOC_G_SLICED_VBI_CAP\n");
+ v4l2_dbg(1, debug, sd, "g_sliced_vbi_cap\n");
memset(cap, 0, sizeof *cap);
while (regs->reg != (u16)-1 ) {
@@ -831,7 +830,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- v4l2_dbg(1, debug, sd, "VIDIOC_G_CTRL called\n");
+ v4l2_dbg(1, debug, sd, "g_ctrl called\n");
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
@@ -861,7 +860,7 @@ static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
if (ctrl->value < tvp5150_qctrl[i].minimum ||
ctrl->value > tvp5150_qctrl[i].maximum)
return -ERANGE;
- v4l2_dbg(1, debug, sd, "VIDIOC_S_CTRL: id=%d, value=%d\n",
+ v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
ctrl->id, ctrl->value);
break;
}
@@ -1015,7 +1014,7 @@ static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
int i;
- v4l2_dbg(1, debug, sd, "VIDIOC_QUERYCTRL called\n");
+ v4l2_dbg(1, debug, sd, "queryctrl called\n");
for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
if (qc->id && qc->id == tvp5150_qctrl[i].id) {
@@ -1126,7 +1125,6 @@ MODULE_DEVICE_TABLE(i2c, tvp5150_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tvp5150",
- .driverid = I2C_DRIVERID_TVP5150,
.command = tvp5150_command,
.probe = tvp5150_probe,
.remove = tvp5150_remove,
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 52c0357faa5..a3994764399 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -460,9 +460,11 @@ static int tw9910_mask_set(struct i2c_client *client, u8 command,
u8 mask, u8 set)
{
s32 val = i2c_smbus_read_byte_data(client, command);
+ if (val < 0)
+ return val;
val &= ~mask;
- val |= set;
+ val |= set & mask;
return i2c_smbus_write_byte_data(client, command, val);
}
@@ -639,8 +641,8 @@ static int tw9910_set_register(struct soc_camera_device *icd,
}
#endif
-static int tw9910_set_fmt(struct soc_camera_device *icd, __u32 pixfmt,
- struct v4l2_rect *rect)
+static int tw9910_set_crop(struct soc_camera_device *icd,
+ struct v4l2_rect *rect)
{
struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
int ret = -EINVAL;
@@ -731,8 +733,33 @@ tw9910_set_fmt_error:
return ret;
}
+static int tw9910_set_fmt(struct soc_camera_device *icd,
+ struct v4l2_format *f)
+{
+ struct v4l2_pix_format *pix = &f->fmt.pix;
+ struct v4l2_rect rect = {
+ .left = icd->x_current,
+ .top = icd->y_current,
+ .width = pix->width,
+ .height = pix->height,
+ };
+ int i;
+
+ /*
+ * check color format
+ */
+ for (i = 0; i < ARRAY_SIZE(tw9910_color_fmt); i++)
+ if (pix->pixelformat == tw9910_color_fmt[i].fourcc)
+ break;
+
+ if (i == ARRAY_SIZE(tw9910_color_fmt))
+ return -EINVAL;
+
+ return tw9910_set_crop(icd, &rect);
+}
+
static int tw9910_try_fmt(struct soc_camera_device *icd,
- struct v4l2_format *f)
+ struct v4l2_format *f)
{
struct v4l2_pix_format *pix = &f->fmt.pix;
const struct tw9910_scale_ctrl *scale;
@@ -820,6 +847,7 @@ static struct soc_camera_ops tw9910_ops = {
.release = tw9910_release,
.start_capture = tw9910_start_capture,
.stop_capture = tw9910_stop_capture,
+ .set_crop = tw9910_set_crop,
.set_fmt = tw9910_set_fmt,
.try_fmt = tw9910_try_fmt,
.set_bus_param = tw9910_set_bus_param,
diff --git a/drivers/media/video/upd64031a.c b/drivers/media/video/upd64031a.c
index f4522bb0891..c0ac651bb35 100644
--- a/drivers/media/video/upd64031a.c
+++ b/drivers/media/video/upd64031a.c
@@ -187,11 +187,6 @@ static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register
}
#endif
-static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
@@ -267,8 +262,6 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64031a",
- .driverid = I2C_DRIVERID_UPD64031A,
- .command = upd64031a_command,
.probe = upd64031a_probe,
.remove = upd64031a_remove,
.id_table = upd64031a_id,
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index a5fb74bf240..410c915d51f 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -164,11 +164,6 @@ static int upd64083_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops upd64083_core_ops = {
@@ -239,8 +234,6 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64083",
- .driverid = I2C_DRIVERID_UPD64083,
- .command = upd64083_command,
.probe = upd64083_probe,
.remove = upd64083_remove,
.id_table = upd64083_id,
diff --git a/drivers/media/video/usbvideo/vicam.c b/drivers/media/video/usbvideo/vicam.c
index 2f1106338c0..8d73979596f 100644
--- a/drivers/media/video/usbvideo/vicam.c
+++ b/drivers/media/video/usbvideo/vicam.c
@@ -191,7 +191,7 @@ initialize_camera(struct vicam_camera *cam)
{
int err;
const struct ihex_binrec *rec;
- const struct firmware *fw;
+ const struct firmware *uninitialized_var(fw);
err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
if (err) {
diff --git a/drivers/media/video/usbvision/usbvision-core.c b/drivers/media/video/usbvision/usbvision-core.c
index 9e4f5063997..a0feb1c9773 100644
--- a/drivers/media/video/usbvision/usbvision-core.c
+++ b/drivers/media/video/usbvision/usbvision-core.c
@@ -36,7 +36,6 @@
#include <linux/spinlock.h>
#include <asm/io.h>
#include <linux/videodev2.h>
-#include <linux/video_decoder.h>
#include <linux/i2c.h>
#include <media/saa7115.h>
@@ -381,8 +380,9 @@ int usbvision_scratch_alloc(struct usb_usbvision *usbvision)
usbvision->scratch = vmalloc_32(scratch_buf_size);
scratch_reset(usbvision);
if(usbvision->scratch == NULL) {
- err("%s: unable to allocate %d bytes for scratch",
- __func__, scratch_buf_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d bytes for scratch\n",
+ __func__, scratch_buf_size);
return -ENOMEM;
}
return 0;
@@ -491,8 +491,9 @@ int usbvision_decompress_alloc(struct usb_usbvision *usbvision)
int IFB_size = MAX_FRAME_WIDTH * MAX_FRAME_HEIGHT * 3 / 2;
usbvision->IntraFrameBuffer = vmalloc_32(IFB_size);
if (usbvision->IntraFrameBuffer == NULL) {
- err("%s: unable to allocate %d for compr. frame buffer",
- __func__, IFB_size);
+ dev_err(&usbvision->dev->dev,
+ "%s: unable to allocate %d for compr. frame buffer\n",
+ __func__, IFB_size);
return -ENOMEM;
}
return 0;
@@ -1514,8 +1515,9 @@ static void usbvision_isocIrq(struct urb *urb)
errCode = usb_submit_urb (urb, GFP_ATOMIC);
if(errCode) {
- err("%s: usb_submit_urb failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb failed: error %d\n",
+ __func__, errCode);
}
return;
@@ -1546,7 +1548,8 @@ int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
0, (__u16) reg, buffer, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
return errCode;
}
return buffer[0];
@@ -1574,7 +1577,8 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
if (errCode < 0) {
- err("%s: failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: failed: error %d\n", __func__, errCode);
}
return errCode;
}
@@ -1850,7 +1854,8 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
0, (__u16) USBVISION_LXSIZE_O, value, 4, HZ);
if (errCode < 0) {
- err("%s failed: error %d", __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s failed: error %d\n", __func__, errCode);
return errCode;
}
usbvision->curwidth = usbvision->stretch_width * UsbWidth;
@@ -2236,7 +2241,7 @@ static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
(__u16) USBVISION_DRM_PRM1, value, 8, HZ);
if (rc < 0) {
- err("%sERROR=%d", __func__, rc);
+ dev_err(&usbvision->dev->dev, "%sERROR=%d\n", __func__, rc);
return rc;
}
@@ -2432,8 +2437,9 @@ int usbvision_set_alternate(struct usb_usbvision *dev)
PDEBUG(DBG_FUNC,"setting alternate %d with wMaxPacketSize=%u", dev->ifaceAlt,dev->isocPacketSize);
errCode = usb_set_interface(dev->dev, dev->iface, dev->ifaceAlt);
if (errCode < 0) {
- err ("cannot change alternate number to %d (error=%i)",
- dev->ifaceAlt, errCode);
+ dev_err(&dev->dev->dev,
+ "cannot change alternate number to %d (error=%i)\n",
+ dev->ifaceAlt, errCode);
return errCode;
}
}
@@ -2484,7 +2490,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
urb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
if (urb == NULL) {
- err("%s: usb_alloc_urb() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_alloc_urb() failed\n", __func__);
return -ENOMEM;
}
usbvision->sbuf[bufIdx].urb = urb;
@@ -2496,7 +2503,7 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
urb->dev = dev;
urb->context = usbvision;
urb->pipe = usb_rcvisocpipe(dev, usbvision->video_endp);
- urb->transfer_flags = URB_ISO_ASAP;
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
urb->interval = 1;
urb->transfer_buffer = usbvision->sbuf[bufIdx].data;
urb->complete = usbvision_isocIrq;
@@ -2516,8 +2523,9 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
errCode = usb_submit_urb(usbvision->sbuf[bufIdx].urb,
GFP_KERNEL);
if (errCode) {
- err("%s: usb_submit_urb(%d) failed: error %d",
- __func__, bufIdx, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_submit_urb(%d) failed: error %d\n",
+ __func__, bufIdx, errCode);
}
}
@@ -2566,8 +2574,9 @@ void usbvision_stop_isoc(struct usb_usbvision *usbvision)
errCode = usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->ifaceAlt);
if (errCode < 0) {
- err("%s: usb_set_interface() failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_set_interface() failed: error %d\n",
+ __func__, errCode);
usbvision->last_error = errCode;
}
regValue = (16-usbvision_read_reg(usbvision, USBVISION_ALTER_REG)) & 0x0F;
@@ -2623,7 +2632,7 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel)
}
route.input = mode[channel];
route.output = 0;
- call_i2c_clients(usbvision, VIDIOC_INT_S_VIDEO_ROUTING,&route);
+ call_all(usbvision, video, s_routing, &route);
usbvision_set_audio(usbvision, audio[channel]);
return 0;
}
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 6b66ae4f430..dd2f8f27c73 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -119,7 +119,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
/* try extended address code... */
ret = try_write_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while writing");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while writing\n");
return -EREMOTEIO;
}
add[0] = addr;
@@ -128,7 +129,8 @@ static inline int usb_find_address(struct i2c_adapter *i2c_adap,
addr |= 0x01;
ret = try_read_address(i2c_adap, addr, retries);
if (ret != 1) {
- err("died at extended address code, while reading");
+ dev_err(&i2c_adap->dev,
+ "died at extended address code, while reading\n");
return -EREMOTEIO;
}
}
@@ -200,72 +202,78 @@ static struct i2c_algorithm usbvision_algo = {
};
-/*
- * registering functions to load algorithms at runtime
- */
-static int usbvision_i2c_usb_add_bus(struct i2c_adapter *adap)
-{
- PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
- PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
-
- /* register new adapter to i2c module... */
-
- adap->algo = &usbvision_algo;
-
- adap->timeout = 100; /* default values, should */
- adap->retries = 3; /* be replaced by defines */
-
- i2c_add_adapter(adap);
-
- PDEBUG(DBG_I2C,"i2c bus for %s registered", adap->name);
-
- return 0;
-}
-
/* ----------------------------------------------------------------------- */
/* usbvision specific I2C functions */
/* ----------------------------------------------------------------------- */
static struct i2c_adapter i2c_adap_template;
-static struct i2c_client i2c_client_template;
int usbvision_i2c_register(struct usb_usbvision *usbvision)
{
+ static unsigned short saa711x_addrs[] = {
+ 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
+ 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
+ I2C_CLIENT_END };
+
memcpy(&usbvision->i2c_adap, &i2c_adap_template,
sizeof(struct i2c_adapter));
- memcpy(&usbvision->i2c_client, &i2c_client_template,
- sizeof(struct i2c_client));
sprintf(usbvision->i2c_adap.name + strlen(usbvision->i2c_adap.name),
" #%d", usbvision->vdev->num);
PDEBUG(DBG_I2C,"Adaptername: %s", usbvision->i2c_adap.name);
usbvision->i2c_adap.dev.parent = &usbvision->dev->dev;
- i2c_set_adapdata(&usbvision->i2c_adap, usbvision);
- i2c_set_clientdata(&usbvision->i2c_client, usbvision);
-
- usbvision->i2c_client.adapter = &usbvision->i2c_adap;
+ i2c_set_adapdata(&usbvision->i2c_adap, &usbvision->v4l2_dev);
if (usbvision_write_reg(usbvision, USBVISION_SER_MODE, USBVISION_IIC_LRNACK) < 0) {
printk(KERN_ERR "usbvision_register: can't write reg\n");
return -EBUSY;
}
-#ifdef CONFIG_MODULES
+ PDEBUG(DBG_I2C, "I2C debugging is enabled [i2c]");
+ PDEBUG(DBG_I2C, "ALGO debugging is enabled [i2c]");
+
+ /* register new adapter to i2c module... */
+
+ usbvision->i2c_adap.algo = &usbvision_algo;
+
+ usbvision->i2c_adap.timeout = 100; /* default values, should */
+ usbvision->i2c_adap.retries = 3; /* be replaced by defines */
+
+ i2c_add_adapter(&usbvision->i2c_adap);
+
+ PDEBUG(DBG_I2C, "i2c bus for %s registered", usbvision->i2c_adap.name);
+
/* Request the load of the i2c modules we need */
switch (usbvision_device_data[usbvision->DevModel].Codec) {
case CODEC_SAA7113:
- request_module("saa7115");
- break;
case CODEC_SAA7111:
- request_module("saa7115");
+ v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "saa7115",
+ "saa7115_auto", saa711x_addrs);
break;
}
if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
- request_module("tuner");
+ struct v4l2_subdev *sd;
+ enum v4l2_i2c_tuner_type type;
+ struct tuner_setup tun_setup;
+
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ /* depending on whether we found a demod or not, select
+ the tuner type. */
+ type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+
+ sd = v4l2_i2c_new_probed_subdev(&usbvision->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+
+ if (usbvision->tuner_type != -1) {
+ tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
+ tun_setup.type = usbvision->tuner_type;
+ tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+ call_all(usbvision, tuner, s_type_addr, &tun_setup);
+ }
}
-#endif
- return usbvision_i2c_usb_add_bus(&usbvision->i2c_adap);
+ return 0;
}
int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
@@ -278,67 +286,6 @@ int usbvision_i2c_unregister(struct usb_usbvision *usbvision)
return 0;
}
-void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,
- void *arg)
-{
- i2c_clients_command(&usbvision->i2c_adap, cmd, arg);
-}
-
-static int attach_inform(struct i2c_client *client)
-{
- struct usb_usbvision *usbvision;
-
- usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-
- switch (client->addr << 1) {
- case 0x42 << 1:
- case 0x43 << 1:
- case 0x4a << 1:
- case 0x4b << 1:
- PDEBUG(DBG_I2C,"attach_inform: tda9887 detected.");
- break;
- case 0x42:
- PDEBUG(DBG_I2C,"attach_inform: saa7114 detected.");
- break;
- case 0x4a:
- PDEBUG(DBG_I2C,"attach_inform: saa7113 detected.");
- break;
- case 0x48:
- PDEBUG(DBG_I2C,"attach_inform: saa7111 detected.");
- break;
- case 0xa0:
- PDEBUG(DBG_I2C,"attach_inform: eeprom detected.");
- break;
-
- default:
- {
- struct tuner_setup tun_setup;
-
- PDEBUG(DBG_I2C,"attach inform: detected I2C address %x", client->addr << 1);
- usbvision->tuner_addr = client->addr;
-
- if ((usbvision->have_tuner) && (usbvision->tuner_type != -1)) {
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = usbvision->tuner_type;
- tun_setup.addr = usbvision->tuner_addr;
- call_i2c_clients(usbvision, TUNER_SET_TYPE_ADDR, &tun_setup);
- }
- }
- break;
- }
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct usb_usbvision *usbvision;
-
- usbvision = (struct usb_usbvision *)i2c_get_adapdata(client->adapter);
-
- PDEBUG(DBG_I2C,"usbvision[%d] detaches %s", usbvision->nr, client->name);
- return 0;
-}
-
static int
usbvision_i2c_read_max4(struct usb_usbvision *usbvision, unsigned char addr,
char *buf, short len)
@@ -511,14 +458,6 @@ static int usbvision_i2c_read(struct usb_usbvision *usbvision, unsigned char add
static struct i2c_adapter i2c_adap_template = {
.owner = THIS_MODULE,
.name = "usbvision",
- .id = I2C_HW_B_BT848, /* FIXME */
- .client_register = attach_inform,
- .client_unregister = detach_inform,
- .class = I2C_CLASS_TV_ANALOG,
-};
-
-static struct i2c_client i2c_client_template = {
- .name = "usbvision internal",
};
/*
diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c
index 2622de003a4..fa62a2fd7b2 100644
--- a/drivers/media/video/usbvision/usbvision-video.c
+++ b/drivers/media/video/usbvision/usbvision-video.c
@@ -59,7 +59,6 @@
#include <linux/spinlock.h>
#include <asm/io.h>
#include <linux/videodev2.h>
-#include <linux/video_decoder.h>
#include <linux/i2c.h>
#include <media/saa7115.h>
@@ -212,7 +211,7 @@ static ssize_t show_hue(struct device *cd,
ctrl.id = V4L2_CID_HUE;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(hue, S_IRUGO, show_hue, NULL);
@@ -227,7 +226,7 @@ static ssize_t show_contrast(struct device *cd,
ctrl.id = V4L2_CID_CONTRAST;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(contrast, S_IRUGO, show_contrast, NULL);
@@ -242,7 +241,7 @@ static ssize_t show_brightness(struct device *cd,
ctrl.id = V4L2_CID_BRIGHTNESS;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(brightness, S_IRUGO, show_brightness, NULL);
@@ -257,7 +256,7 @@ static ssize_t show_saturation(struct device *cd,
ctrl.id = V4L2_CID_SATURATION;
ctrl.value = 0;
if(usbvision->user)
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, &ctrl);
+ call_all(usbvision, core, g_ctrl, &ctrl);
return sprintf(buf, "%d\n", ctrl.value);
}
static DEVICE_ATTR(saturation, S_IRUGO, show_saturation, NULL);
@@ -329,7 +328,7 @@ static void usbvision_create_sysfs(struct video_device *vdev)
return;
} while (0);
- err("%s error: %d\n", __func__, res);
+ dev_err(&vdev->dev, "%s error: %d\n", __func__, res);
}
static void usbvision_remove_sysfs(struct video_device *vdev)
@@ -487,8 +486,9 @@ static int vidioc_g_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_read_reg(usbvision, reg->reg&0xff);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_G_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_G_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
reg->val = errCode;
@@ -507,8 +507,9 @@ static int vidioc_s_register (struct file *file, void *priv,
/* NT100x has a 8-bit register space */
errCode = usbvision_write_reg(usbvision, reg->reg&0xff, reg->val);
if (errCode < 0) {
- err("%s: VIDIOC_DBG_S_REGISTER failed: error %d",
- __func__, errCode);
+ dev_err(&usbvision->vdev->dev,
+ "%s: VIDIOC_DBG_S_REGISTER failed: error %d\n",
+ __func__, errCode);
return errCode;
}
return 0;
@@ -524,8 +525,7 @@ static int vidioc_querycap (struct file *file, void *priv,
strlcpy(vc->card,
usbvision_device_data[usbvision->DevModel].ModelString,
sizeof(vc->card));
- strlcpy(vc->bus_info, dev_name(&usbvision->dev->dev),
- sizeof(vc->bus_info));
+ usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
vc->version = USBVISION_DRIVER_VERSION;
vc->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_AUDIO |
@@ -621,8 +621,7 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *id)
usbvision->tvnormId=*id;
mutex_lock(&usbvision->lock);
- call_i2c_clients(usbvision, VIDIOC_S_STD,
- &usbvision->tvnormId);
+ call_all(usbvision, tuner, s_std, usbvision->tvnormId);
mutex_unlock(&usbvision->lock);
/* propagate the change to the decoder */
usbvision_muxsel(usbvision, usbvision->ctl_input);
@@ -644,7 +643,7 @@ static int vidioc_g_tuner (struct file *file, void *priv,
strcpy(vt->name, "Television");
}
/* Let clients fill in the remainder of this struct */
- call_i2c_clients(usbvision,VIDIOC_G_TUNER,vt);
+ call_all(usbvision, tuner, g_tuner, vt);
return 0;
}
@@ -658,7 +657,7 @@ static int vidioc_s_tuner (struct file *file, void *priv,
if (!usbvision->have_tuner || vt->index)
return -EINVAL;
/* let clients handle this */
- call_i2c_clients(usbvision,VIDIOC_S_TUNER,vt);
+ call_all(usbvision, tuner, s_tuner, vt);
return 0;
}
@@ -689,7 +688,7 @@ static int vidioc_s_frequency (struct file *file, void *priv,
return -EINVAL;
usbvision->freq = freq->frequency;
- call_i2c_clients(usbvision, VIDIOC_S_FREQUENCY, freq);
+ call_all(usbvision, tuner, s_frequency, freq);
return 0;
}
@@ -698,7 +697,6 @@ static int vidioc_g_audio (struct file *file, void *priv, struct v4l2_audio *a)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- memset(a,0,sizeof(*a));
if(usbvision->radio) {
strcpy(a->name,"Radio");
} else {
@@ -722,12 +720,8 @@ static int vidioc_queryctrl (struct file *file, void *priv,
struct v4l2_queryctrl *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int id=ctrl->id;
- memset(ctrl,0,sizeof(*ctrl));
- ctrl->id=id;
-
- call_i2c_clients(usbvision, VIDIOC_QUERYCTRL, ctrl);
+ call_all(usbvision, core, queryctrl, ctrl);
if (!ctrl->type)
return -EINVAL;
@@ -739,7 +733,7 @@ static int vidioc_g_ctrl (struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- call_i2c_clients(usbvision, VIDIOC_G_CTRL, ctrl);
+ call_all(usbvision, core, g_ctrl, ctrl);
return 0;
}
@@ -748,7 +742,7 @@ static int vidioc_s_ctrl (struct file *file, void *priv,
struct v4l2_control *ctrl)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- call_i2c_clients(usbvision, VIDIOC_S_CTRL, ctrl);
+ call_all(usbvision, core, s_ctrl, ctrl);
return 0;
}
@@ -763,8 +757,7 @@ static int vidioc_reqbufs (struct file *file,
/* Check input validity:
the user must do a VIDEO CAPTURE and MMAP method. */
- if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
- (vr->memory != V4L2_MEMORY_MMAP))
+ if (vr->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if(usbvision->streaming == Stream_On) {
@@ -789,9 +782,6 @@ static int vidioc_querybuf (struct file *file,
/* FIXME : must control
that buffers are mapped (VIDIOC_REQBUFS has been called) */
- if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
- return -EINVAL;
- }
if(vb->index>=usbvision->num_frames) {
return -EINVAL;
}
@@ -825,9 +815,6 @@ static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
unsigned long lock_flags;
/* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */
- if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
- return -EINVAL;
- }
if(vb->index>=usbvision->num_frames) {
return -EINVAL;
}
@@ -862,9 +849,6 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
struct usbvision_frame *f;
unsigned long lock_flags;
- if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (list_empty(&(usbvision->outqueue))) {
if (usbvision->streaming == Stream_Idle)
return -EINVAL;
@@ -899,10 +883,9 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int b=V4L2_BUF_TYPE_VIDEO_CAPTURE;
usbvision->streaming = Stream_On;
- call_i2c_clients(usbvision,VIDIOC_STREAMON , &b);
+ call_all(usbvision, video, s_stream, 1);
return 0;
}
@@ -911,7 +894,6 @@ static int vidioc_streamoff(struct file *file,
void *priv, enum v4l2_buf_type type)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int b=V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
@@ -919,7 +901,7 @@ static int vidioc_streamoff(struct file *file,
if(usbvision->streaming == Stream_On) {
usbvision_stream_interrupt(usbvision);
/* Stop all video streamings */
- call_i2c_clients(usbvision,VIDIOC_STREAMOFF , &b);
+ call_all(usbvision, video, s_stream, 0);
}
usbvision_empty_framequeues(usbvision);
@@ -932,11 +914,8 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) {
return -EINVAL;
}
- vfd->flags = 0;
- vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc);
vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
- memset(vfd->reserved, 0, sizeof(vfd->reserved));
return 0;
}
@@ -1042,7 +1021,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char __user *buf,
if(usbvision->streaming != Stream_On) {
/* no stream is running, make it running ! */
usbvision->streaming = Stream_On;
- call_i2c_clients(usbvision,VIDIOC_STREAMON , NULL);
+ call_all(usbvision, video, s_stream, 1);
}
/* Then, enqueue as many frames as possible
@@ -1189,7 +1168,9 @@ static int usbvision_radio_open(struct file *file)
mutex_lock(&usbvision->lock);
if (usbvision->user) {
- err("%s: Someone tried to open an already opened USBVision Radio!", __func__);
+ dev_err(&usbvision->rdev->dev,
+ "%s: Someone tried to open an already opened USBVision Radio!\n",
+ __func__);
errCode = -EBUSY;
}
else {
@@ -1211,7 +1192,7 @@ static int usbvision_radio_open(struct file *file)
// If so far no errors then we shall start the radio
usbvision->radio = 1;
- call_i2c_clients(usbvision,AUDC_SET_RADIO,&usbvision->tuner_type);
+ call_all(usbvision, tuner, s_radio);
usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
usbvision->user++;
}
@@ -1413,7 +1394,8 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
struct video_device *vdev;
if (usb_dev == NULL) {
- err("%s: usbvision->dev is not set", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usbvision->dev is not set\n", __func__);
return NULL;
}
@@ -1423,7 +1405,7 @@ static struct video_device *usbvision_vdev_init(struct usb_usbvision *usbvision,
}
*vdev = *vdev_template;
// vdev->minor = -1;
- vdev->parent = &usb_dev->dev;
+ vdev->v4l2_dev = &usbvision->v4l2_dev;
snprintf(vdev->name, sizeof(vdev->name), "%s", name);
video_set_drvdata(vdev, usbvision);
return vdev;
@@ -1524,7 +1506,9 @@ static int __devinit usbvision_register_video(struct usb_usbvision *usbvision)
return 0;
err_exit:
- err("USBVision[%d]: video_register_device() failed", usbvision->nr);
+ dev_err(&usbvision->dev->dev,
+ "USBVision[%d]: video_register_device() failed\n",
+ usbvision->nr);
usbvision_unregister_video(usbvision);
return -1;
}
@@ -1542,33 +1526,30 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev)
{
struct usb_usbvision *usbvision;
- if ((usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL)) ==
- NULL) {
- goto err_exit;
- }
+ usbvision = kzalloc(sizeof(struct usb_usbvision), GFP_KERNEL);
+ if (usbvision == NULL)
+ return NULL;
usbvision->dev = dev;
+ if (v4l2_device_register(&dev->dev, &usbvision->v4l2_dev))
+ goto err_free;
mutex_init(&usbvision->lock); /* available */
// prepare control urb for control messages during interrupts
usbvision->ctrlUrb = usb_alloc_urb(USBVISION_URB_FRAMES, GFP_KERNEL);
- if (usbvision->ctrlUrb == NULL) {
- goto err_exit;
- }
+ if (usbvision->ctrlUrb == NULL)
+ goto err_unreg;
init_waitqueue_head(&usbvision->ctrlUrb_wq);
usbvision_init_powerOffTimer(usbvision);
return usbvision;
-err_exit:
- if (usbvision && usbvision->ctrlUrb) {
- usb_free_urb(usbvision->ctrlUrb);
- }
- if (usbvision) {
- kfree(usbvision);
- }
+err_unreg:
+ v4l2_device_unregister(&usbvision->v4l2_dev);
+err_free:
+ kfree(usbvision);
return NULL;
}
@@ -1598,6 +1579,7 @@ static void usbvision_release(struct usb_usbvision *usbvision)
usb_free_urb(usbvision->ctrlUrb);
}
+ v4l2_device_unregister(&usbvision->v4l2_dev);
kfree(usbvision);
PDEBUG(DBG_PROBE, "success");
@@ -1675,20 +1657,20 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
}
endpoint = &interface->endpoint[1].desc;
if (!usb_endpoint_xfer_isoc(endpoint)) {
- err("%s: interface %d. has non-ISO endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has non-ISO endpoint!\n",
__func__, ifnum);
- err("%s: Endpoint attributes %d",
+ dev_err(&intf->dev, "%s: Endpoint attributes %d",
__func__, endpoint->bmAttributes);
return -ENODEV;
}
if (usb_endpoint_dir_out(endpoint)) {
- err("%s: interface %d. has ISO OUT endpoint!",
+ dev_err(&intf->dev, "%s: interface %d. has ISO OUT endpoint!\n",
__func__, ifnum);
return -ENODEV;
}
if ((usbvision = usbvision_alloc(dev)) == NULL) {
- err("%s: couldn't allocate USBVision struct", __func__);
+ dev_err(&intf->dev, "%s: couldn't allocate USBVision struct\n", __func__);
return -ENOMEM;
}
@@ -1711,7 +1693,7 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
usbvision->alt_max_pkt_size = kmalloc(32*
usbvision->num_alt,GFP_KERNEL);
if (usbvision->alt_max_pkt_size == NULL) {
- err("usbvision: out of memory!\n");
+ dev_err(&intf->dev, "usbvision: out of memory!\n");
mutex_unlock(&usbvision->lock);
return -ENOMEM;
}
@@ -1733,8 +1715,6 @@ static int __devinit usbvision_probe(struct usb_interface *intf,
usbvision->tuner_type = usbvision_device_data[model].TunerType;
}
- usbvision->tuner_addr = ADDR_UNSET;
-
usbvision->DevModel = model;
usbvision->remove_pending = 0;
usbvision->iface = ifnum;
@@ -1772,7 +1752,8 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
PDEBUG(DBG_PROBE, "");
if (usbvision == NULL) {
- err("%s: usb_get_intfdata() failed", __func__);
+ dev_err(&usbvision->dev->dev,
+ "%s: usb_get_intfdata() failed\n", __func__);
return;
}
usb_set_intfdata (intf, NULL);
@@ -1782,6 +1763,8 @@ static void __devexit usbvision_disconnect(struct usb_interface *intf)
// At this time we ask to cancel outstanding URBs
usbvision_stop_isoc(usbvision);
+ v4l2_device_disconnect(&usbvision->v4l2_dev);
+
if (usbvision->power) {
usbvision_i2c_unregister(usbvision);
usbvision_power_off(usbvision);
diff --git a/drivers/media/video/usbvision/usbvision.h b/drivers/media/video/usbvision/usbvision.h
index 20d7ec62499..f8d7458daf3 100644
--- a/drivers/media/video/usbvision/usbvision.h
+++ b/drivers/media/video/usbvision/usbvision.h
@@ -6,7 +6,7 @@
* Dwaine Garden <dwainegarden@rogers.com>
*
*
- * Report problems to v4l MailingList : http://www.redhat.com/mailman/listinfo/video4linux-list
+ * Report problems to v4l MailingList: linux-media@vger.kernel.org
*
* This module is part of usbvision driver project.
* Updates to driver completed by Dwaine P. Garden
@@ -35,7 +35,7 @@
#include <linux/usb.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <linux/videodev2.h>
@@ -357,13 +357,13 @@ extern struct usbvision_device_data_st usbvision_device_data[];
extern struct usb_device_id usbvision_table[];
struct usb_usbvision {
+ struct v4l2_device v4l2_dev;
struct video_device *vdev; /* Video Device */
struct video_device *rdev; /* Radio Device */
struct video_device *vbi; /* VBI Device */
/* i2c Declaration Section*/
struct i2c_adapter i2c_adap;
- struct i2c_client i2c_client;
struct urb *ctrlUrb;
unsigned char ctrlUrbBuffer[8];
@@ -374,7 +374,6 @@ struct usb_usbvision {
/* configuration part */
int have_tuner;
int tuner_type;
- int tuner_addr;
int bridgeType; // NT1003, NT1004, NT1005
int radio;
int video_inputs; // # of inputs
@@ -464,6 +463,8 @@ struct usb_usbvision {
int ComprBlockTypes[4];
};
+#define call_all(usbvision, o, f, args...) \
+ v4l2_device_call_all(&usbvision->v4l2_dev, 0, o, f, ##args)
/* --------------------------------------------------------------- */
/* defined in usbvision-i2c.c */
@@ -475,7 +476,6 @@ struct usb_usbvision {
/* ----------------------------------------------------------------------- */
int usbvision_i2c_register(struct usb_usbvision *usbvision);
int usbvision_i2c_unregister(struct usb_usbvision *usbvision);
-void call_i2c_clients(struct usb_usbvision *usbvision, unsigned int cmd,void *arg);
/* defined in usbvision-core.c */
int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg);
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index d2576f6391c..0d7e38d6ff6 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -786,7 +786,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
v4l2_ctrl->id = mapping->id;
v4l2_ctrl->type = mapping->v4l2_type;
- strncpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
+ strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
v4l2_ctrl->flags = 0;
if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR))
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index b12873265cc..399412d7f02 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -314,7 +314,7 @@ static int uvc_parse_format(struct uvc_device *dev,
fmtdesc = uvc_format_by_guid(&buffer[5]);
if (fmtdesc != NULL) {
- strncpy(format->name, fmtdesc->name,
+ strlcpy(format->name, fmtdesc->name,
sizeof format->name);
format->fcc = fmtdesc->fcc;
} else {
@@ -345,7 +345,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncpy(format->name, "MJPEG", sizeof format->name);
+ strlcpy(format->name, "MJPEG", sizeof format->name);
format->fcc = V4L2_PIX_FMT_MJPEG;
format->flags = UVC_FMT_FLAG_COMPRESSED;
format->bpp = 0;
@@ -363,13 +363,13 @@ static int uvc_parse_format(struct uvc_device *dev,
switch (buffer[8] & 0x7f) {
case 0:
- strncpy(format->name, "SD-DV", sizeof format->name);
+ strlcpy(format->name, "SD-DV", sizeof format->name);
break;
case 1:
- strncpy(format->name, "SDL-DV", sizeof format->name);
+ strlcpy(format->name, "SDL-DV", sizeof format->name);
break;
case 2:
- strncpy(format->name, "HD-DV", sizeof format->name);
+ strlcpy(format->name, "HD-DV", sizeof format->name);
break;
default:
uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
@@ -379,7 +379,7 @@ static int uvc_parse_format(struct uvc_device *dev,
return -EINVAL;
}
- strncat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
+ strlcat(format->name, buffer[8] & (1 << 7) ? " 60Hz" : " 50Hz",
sizeof format->name);
format->fcc = V4L2_PIX_FMT_DV;
@@ -1526,7 +1526,7 @@ static int uvc_register_video(struct uvc_device *dev)
vdev->minor = -1;
vdev->fops = &uvc_fops;
vdev->release = video_device_release;
- strncpy(vdev->name, dev->name, sizeof vdev->name);
+ strlcpy(vdev->name, dev->name, sizeof vdev->name);
/* Set the driver data before calling video_register_device, otherwise
* uvc_v4l2_open might race us.
@@ -1621,7 +1621,7 @@ static int uvc_probe(struct usb_interface *intf,
dev->quirks = id->driver_info | uvc_quirks_param;
if (udev->product != NULL)
- strncpy(dev->name, udev->product, sizeof dev->name);
+ strlcpy(dev->name, udev->product, sizeof dev->name);
else
snprintf(dev->name, sizeof dev->name,
"UVC Camera (%04x:%04x)",
@@ -1833,6 +1833,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceClass = USB_CLASS_VENDOR_SPEC,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0 },
+ /* Alcor Micro AU3820 (Future Boy PC USB Webcam) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x058f,
+ .idProduct = 0x3820,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_PROBE_MINMAX },
/* Apple Built-In iSight */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1852,6 +1861,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* ViMicro */
+ { .match_flags = USB_DEVICE_ID_MATCH_VENDOR
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x0ac8,
+ .idProduct = 0x0000,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_FIX_BANDWIDTH },
/* MT6227 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
@@ -1879,7 +1897,7 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Asus F9SG */
+ /* Syntek (Asus F9SG) */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x174f,
@@ -1897,6 +1915,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Syntek (JAOtech Smart Terminal) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x174f,
+ .idProduct = 0x8a34,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* Lenovo Thinkpad SL500 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/drivers/media/video/uvc/uvc_status.c b/drivers/media/video/uvc/uvc_status.c
index c705f248da8..21d87124986 100644
--- a/drivers/media/video/uvc/uvc_status.c
+++ b/drivers/media/video/uvc/uvc_status.c
@@ -24,26 +24,19 @@
#ifdef CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV
static int uvc_input_init(struct uvc_device *dev)
{
- struct usb_device *udev = dev->udev;
struct input_dev *input;
- char *phys = NULL;
int ret;
input = input_allocate_device();
if (input == NULL)
return -ENOMEM;
- phys = kmalloc(6 + strlen(udev->bus->bus_name) + strlen(udev->devpath),
- GFP_KERNEL);
- if (phys == NULL) {
- ret = -ENOMEM;
- goto error;
- }
- sprintf(phys, "usb-%s-%s", udev->bus->bus_name, udev->devpath);
+ usb_make_path(dev->udev, dev->input_phys, sizeof(dev->input_phys));
+ strlcat(dev->input_phys, "/button", sizeof(dev->input_phys));
input->name = dev->name;
- input->phys = phys;
- usb_to_input_id(udev, &input->id);
+ input->phys = dev->input_phys;
+ usb_to_input_id(dev->udev, &input->id);
input->dev.parent = &dev->intf->dev;
__set_bit(EV_KEY, input->evbit);
@@ -57,7 +50,6 @@ static int uvc_input_init(struct uvc_device *dev)
error:
input_free_device(input);
- kfree(phys);
return ret;
}
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index d681519d0c8..2a80caa54fb 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -55,7 +55,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
return -EINVAL;
menu_info = &mapping->menu_info[query_menu->index];
- strncpy(query_menu->name, menu_info->name, 32);
+ strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name);
return 0;
}
@@ -486,10 +486,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
struct v4l2_capability *cap = arg;
memset(cap, 0, sizeof *cap);
- strncpy(cap->driver, "uvcvideo", sizeof cap->driver);
- strncpy(cap->card, vdev->name, 32);
- strncpy(cap->bus_info, video->dev->udev->bus->bus_name,
- sizeof cap->bus_info);
+ strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
+ strlcpy(cap->card, vdev->name, sizeof cap->card);
+ usb_make_path(video->dev->udev,
+ cap->bus_info, sizeof(cap->bus_info));
cap->version = DRIVER_VERSION_NUMBER;
if (video->streaming->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE
@@ -620,7 +620,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
memset(input, 0, sizeof *input);
input->index = index;
- strncpy(input->name, iterm->name, sizeof input->name);
+ strlcpy(input->name, iterm->name, sizeof input->name);
if (UVC_ENTITY_TYPE(iterm) == ITT_CAMERA)
input->type = V4L2_INPUT_TYPE_CAMERA;
break;
@@ -673,16 +673,22 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct v4l2_fmtdesc *fmt = arg;
struct uvc_format *format;
+ enum v4l2_buf_type type = fmt->type;
+ __u32 index = fmt->index;
if (fmt->type != video->streaming->type ||
fmt->index >= video->streaming->nformats)
return -EINVAL;
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->index = index;
+ fmt->type = type;
+
format = &video->streaming->format[fmt->index];
fmt->flags = 0;
if (format->flags & UVC_FMT_FLAG_COMPRESSED)
fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
- strncpy(fmt->description, format->name,
+ strlcpy(fmt->description, format->name,
sizeof fmt->description);
fmt->description[sizeof fmt->description - 1] = 0;
fmt->pixelformat = format->fcc;
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 9bc4705be78..a95e17329c5 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -61,7 +61,7 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
return 0;
}
-static void uvc_fixup_buffer_size(struct uvc_video_device *video,
+static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
struct uvc_streaming_control *ctrl)
{
struct uvc_format *format;
@@ -84,6 +84,31 @@ static void uvc_fixup_buffer_size(struct uvc_video_device *video,
video->dev->uvc_version < 0x0110))
ctrl->dwMaxVideoFrameSize =
frame->dwMaxVideoFrameBufferSize;
+
+ if (video->dev->quirks & UVC_QUIRK_FIX_BANDWIDTH &&
+ video->streaming->intf->num_altsetting > 1) {
+ u32 interval;
+ u32 bandwidth;
+
+ interval = (ctrl->dwFrameInterval > 100000)
+ ? ctrl->dwFrameInterval
+ : frame->dwFrameInterval[0];
+
+ /* Compute a bandwidth estimation by multiplying the frame
+ * size by the number of video frames per second, divide the
+ * result by the number of USB frames (or micro-frames for
+ * high-speed devices) per second and add the UVC header size
+ * (assumed to be 12 bytes long).
+ */
+ bandwidth = frame->wWidth * frame->wHeight / 8 * format->bpp;
+ bandwidth *= 10000000 / interval + 1;
+ bandwidth /= 1000;
+ if (video->dev->udev->speed == USB_SPEED_HIGH)
+ bandwidth /= 8;
+ bandwidth += 12;
+
+ ctrl->dwMaxPayloadTransferSize = bandwidth;
+ }
}
static int uvc_get_video_ctrl(struct uvc_video_device *video,
@@ -158,10 +183,11 @@ static int uvc_get_video_ctrl(struct uvc_video_device *video,
ctrl->bMaxVersion = 0;
}
- /* Some broken devices return a null or wrong dwMaxVideoFrameSize.
- * Try to get the value from the format and frame descriptors.
+ /* Some broken devices return null or wrong dwMaxVideoFrameSize and
+ * dwMaxPayloadTransferSize fields. Try to get the value from the
+ * format and frame descriptors.
*/
- uvc_fixup_buffer_size(video, ctrl);
+ uvc_fixup_video_ctrl(video, ctrl);
ret = 0;
out:
@@ -540,6 +566,9 @@ static void uvc_video_decode_bulk(struct urb *urb,
u8 *mem;
int len, ret;
+ if (urb->actual_length == 0)
+ return;
+
mem = urb->transfer_buffer;
len = urb->actual_length;
video->bulk.payload_size += len;
@@ -699,27 +728,47 @@ static void uvc_free_urb_buffers(struct uvc_video_device *video)
* already allocated when resuming from suspend, in which case it will
* return without touching the buffers.
*
- * Return 0 on success or -ENOMEM when out of memory.
+ * Limit the buffer size to UVC_MAX_PACKETS bulk/isochronous packets. If the
+ * system is too low on memory try successively smaller numbers of packets
+ * until allocation succeeds.
+ *
+ * Return the number of allocated packets on success or 0 when out of memory.
*/
static int uvc_alloc_urb_buffers(struct uvc_video_device *video,
- unsigned int size)
+ unsigned int size, unsigned int psize, gfp_t gfp_flags)
{
+ unsigned int npackets;
unsigned int i;
/* Buffers are already allocated, bail out. */
if (video->urb_size)
return 0;
- for (i = 0; i < UVC_URBS; ++i) {
- video->urb_buffer[i] = usb_buffer_alloc(video->dev->udev,
- size, GFP_KERNEL, &video->urb_dma[i]);
- if (video->urb_buffer[i] == NULL) {
- uvc_free_urb_buffers(video);
- return -ENOMEM;
+ /* Compute the number of packets. Bulk endpoints might transfer UVC
+ * payloads accross multiple URBs.
+ */
+ npackets = DIV_ROUND_UP(size, psize);
+ if (npackets > UVC_MAX_PACKETS)
+ npackets = UVC_MAX_PACKETS;
+
+ /* Retry allocations until one succeed. */
+ for (; npackets > 1; npackets /= 2) {
+ for (i = 0; i < UVC_URBS; ++i) {
+ video->urb_buffer[i] = usb_buffer_alloc(
+ video->dev->udev, psize * npackets,
+ gfp_flags | __GFP_NOWARN, &video->urb_dma[i]);
+ if (!video->urb_buffer[i]) {
+ uvc_free_urb_buffers(video);
+ break;
+ }
+ }
+
+ if (i == UVC_URBS) {
+ video->urb_size = psize * npackets;
+ return npackets;
}
}
- video->urb_size = size;
return 0;
}
@@ -753,29 +802,19 @@ static int uvc_init_video_isoc(struct uvc_video_device *video,
{
struct urb *urb;
unsigned int npackets, i, j;
- __u16 psize;
- __u32 size;
+ u16 psize;
+ u32 size;
- /* Compute the number of isochronous packets to allocate by dividing
- * the maximum video frame size by the packet size. Limit the result
- * to UVC_MAX_ISO_PACKETS.
- */
psize = le16_to_cpu(ep->desc.wMaxPacketSize);
psize = (psize & 0x07ff) * (1 + ((psize >> 11) & 3));
-
size = video->streaming->ctrl.dwMaxVideoFrameSize;
- if (size > UVC_MAX_FRAME_SIZE)
- return -EINVAL;
- npackets = DIV_ROUND_UP(size, psize);
- if (npackets > UVC_MAX_ISO_PACKETS)
- npackets = UVC_MAX_ISO_PACKETS;
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
+ return -ENOMEM;
size = npackets * psize;
- if (uvc_alloc_urb_buffers(video, size) < 0)
- return -ENOMEM;
-
for (i = 0; i < UVC_URBS; ++i) {
urb = usb_alloc_urb(npackets, gfp_flags);
if (urb == NULL) {
@@ -814,25 +853,20 @@ static int uvc_init_video_bulk(struct uvc_video_device *video,
struct usb_host_endpoint *ep, gfp_t gfp_flags)
{
struct urb *urb;
- unsigned int pipe, i;
- __u16 psize;
- __u32 size;
-
- /* Compute the bulk URB size. Some devices set the maximum payload
- * size to a value too high for memory-constrained devices. We must
- * then transfer the payload accross multiple URBs. To be consistant
- * with isochronous mode, allocate maximum UVC_MAX_ISO_PACKETS per bulk
- * URB.
- */
+ unsigned int npackets, pipe, i;
+ u16 psize;
+ u32 size;
+
psize = le16_to_cpu(ep->desc.wMaxPacketSize) & 0x07ff;
size = video->streaming->ctrl.dwMaxPayloadTransferSize;
video->bulk.max_payload_size = size;
- if (size > psize * UVC_MAX_ISO_PACKETS)
- size = psize * UVC_MAX_ISO_PACKETS;
- if (uvc_alloc_urb_buffers(video, size) < 0)
+ npackets = uvc_alloc_urb_buffers(video, size, psize, gfp_flags);
+ if (npackets == 0)
return -ENOMEM;
+ size = npackets * psize;
+
if (usb_endpoint_dir_in(&ep->desc))
pipe = usb_rcvbulkpipe(video->dev->udev,
ep->desc.bEndpointAddress);
@@ -1021,11 +1055,20 @@ int uvc_video_init(struct uvc_video_device *video)
*/
usb_set_interface(video->dev->udev, video->streaming->intfnum, 0);
- /* Some webcams don't suport GET_DEF requests on the probe control. We
- * fall back to GET_CUR if GET_DEF fails.
+ /* Set the streaming probe control with default streaming parameters
+ * retrieved from the device. Webcams that don't suport GET_DEF
+ * requests on the probe control will just keep their current streaming
+ * parameters.
+ */
+ if (uvc_get_video_ctrl(video, probe, 1, GET_DEF) == 0)
+ uvc_set_video_ctrl(video, probe, 1);
+
+ /* Initialize the streaming parameters with the probe control current
+ * value. This makes sure SET_CUR requests on the streaming commit
+ * control will always use values retrieved from a successful GET_CUR
+ * request on the probe control, as required by the UVC specification.
*/
- if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_DEF)) < 0 &&
- (ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
+ if ((ret = uvc_get_video_ctrl(video, probe, 1, GET_CUR)) < 0)
return ret;
/* Check if the default format descriptor exists. Use the first
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 027947ea9b6..e5014e668f9 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -296,10 +296,8 @@ struct uvc_xu_control {
/* Number of isochronous URBs. */
#define UVC_URBS 5
-/* Maximum number of packets per isochronous URB. */
-#define UVC_MAX_ISO_PACKETS 40
-/* Maximum frame size in bytes, for sanity checking. */
-#define UVC_MAX_FRAME_SIZE (16*1024*1024)
+/* Maximum number of packets per URB. */
+#define UVC_MAX_PACKETS 32
/* Maximum number of video buffers. */
#define UVC_MAX_VIDEO_BUFFERS 32
/* Maximum status buffer size in bytes of interrupt URB. */
@@ -316,6 +314,7 @@ struct uvc_xu_control {
#define UVC_QUIRK_STREAM_NO_FID 0x00000010
#define UVC_QUIRK_IGNORE_SELECTOR_UNIT 0x00000020
#define UVC_QUIRK_PRUNE_CONTROLS 0x00000040
+#define UVC_QUIRK_FIX_BANDWIDTH 0x00000080
/* Format flags */
#define UVC_FMT_FLAG_COMPRESSED 0x00000001
@@ -649,6 +648,7 @@ struct uvc_device {
struct urb *int_urb;
__u8 *status;
struct input_dev *input;
+ char input_phys[64];
/* Video Streaming interfaces */
struct list_head streaming;
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index b8f2be8d5c0..1da8cb836cb 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -334,6 +334,12 @@ const char **v4l2_ctrl_get_menu(u32 id)
"Aperture Priority Mode",
NULL
};
+ static const char *colorfx[] = {
+ "None",
+ "Black & White",
+ "Sepia",
+ NULL
+ };
switch (id) {
case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -370,6 +376,8 @@ const char **v4l2_ctrl_get_menu(u32 id)
return camera_power_line_frequency;
case V4L2_CID_EXPOSURE_AUTO:
return camera_exposure_auto;
+ case V4L2_CID_COLORFX:
+ return colorfx;
default:
return NULL;
}
@@ -382,16 +390,16 @@ const char *v4l2_ctrl_get_name(u32 id)
switch (id) {
/* USER controls */
case V4L2_CID_USER_CLASS: return "User Controls";
+ case V4L2_CID_BRIGHTNESS: return "Brightness";
+ case V4L2_CID_CONTRAST: return "Contrast";
+ case V4L2_CID_SATURATION: return "Saturation";
+ case V4L2_CID_HUE: return "Hue";
case V4L2_CID_AUDIO_VOLUME: return "Volume";
- case V4L2_CID_AUDIO_MUTE: return "Mute";
case V4L2_CID_AUDIO_BALANCE: return "Balance";
case V4L2_CID_AUDIO_BASS: return "Bass";
case V4L2_CID_AUDIO_TREBLE: return "Treble";
+ case V4L2_CID_AUDIO_MUTE: return "Mute";
case V4L2_CID_AUDIO_LOUDNESS: return "Loudness";
- case V4L2_CID_BRIGHTNESS: return "Brightness";
- case V4L2_CID_CONTRAST: return "Contrast";
- case V4L2_CID_SATURATION: return "Saturation";
- case V4L2_CID_HUE: return "Hue";
case V4L2_CID_BLACK_LEVEL: return "Black Level";
case V4L2_CID_AUTO_WHITE_BALANCE: return "White Balance, Automatic";
case V4L2_CID_DO_WHITE_BALANCE: return "Do White Balance";
@@ -412,6 +420,7 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_BACKLIGHT_COMPENSATION: return "Backlight Compensation";
case V4L2_CID_CHROMA_AGC: return "Chroma AGC";
case V4L2_CID_COLOR_KILLER: return "Color Killer";
+ case V4L2_CID_COLORFX: return "Color Effects";
/* MPEG controls */
case V4L2_CID_MPEG_CLASS: return "MPEG Encoder Controls";
@@ -490,16 +499,25 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_HFLIP:
case V4L2_CID_VFLIP:
case V4L2_CID_HUE_AUTO:
+ case V4L2_CID_CHROMA_AGC:
+ case V4L2_CID_COLOR_KILLER:
case V4L2_CID_MPEG_AUDIO_MUTE:
case V4L2_CID_MPEG_VIDEO_MUTE:
case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
case V4L2_CID_MPEG_VIDEO_PULLDOWN:
case V4L2_CID_EXPOSURE_AUTO_PRIORITY:
+ case V4L2_CID_FOCUS_AUTO:
case V4L2_CID_PRIVACY:
qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
min = 0;
max = step = 1;
break;
+ case V4L2_CID_PAN_RESET:
+ case V4L2_CID_TILT_RESET:
+ qctrl->type = V4L2_CTRL_TYPE_BUTTON;
+ qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
+ min = max = step = def = 0;
+ break;
case V4L2_CID_POWER_LINE_FREQUENCY:
case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
case V4L2_CID_MPEG_AUDIO_ENCODING:
@@ -517,6 +535,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_MPEG_STREAM_TYPE:
case V4L2_CID_MPEG_STREAM_VBI_FMT:
case V4L2_CID_EXPOSURE_AUTO:
+ case V4L2_CID_COLORFX:
qctrl->type = V4L2_CTRL_TYPE_MENU;
step = 1;
break;
@@ -547,161 +566,29 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_CONTRAST:
case V4L2_CID_SATURATION:
case V4L2_CID_HUE:
+ case V4L2_CID_RED_BALANCE:
+ case V4L2_CID_BLUE_BALANCE:
+ case V4L2_CID_GAMMA:
+ case V4L2_CID_SHARPNESS:
qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
break;
+ case V4L2_CID_PAN_RELATIVE:
+ case V4L2_CID_TILT_RELATIVE:
+ case V4L2_CID_FOCUS_RELATIVE:
+ case V4L2_CID_ZOOM_RELATIVE:
+ qctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
+ break;
}
qctrl->minimum = min;
qctrl->maximum = max;
qctrl->step = step;
qctrl->default_value = def;
qctrl->reserved[0] = qctrl->reserved[1] = 0;
- snprintf(qctrl->name, sizeof(qctrl->name), name);
+ strlcpy(qctrl->name, name, sizeof(qctrl->name));
return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_query_fill);
-/* Fill in a struct v4l2_queryctrl with standard values based on
- the control ID. */
-int v4l2_ctrl_query_fill_std(struct v4l2_queryctrl *qctrl)
-{
- switch (qctrl->id) {
- /* USER controls */
- case V4L2_CID_USER_CLASS:
- case V4L2_CID_MPEG_CLASS:
- return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
- case V4L2_CID_AUDIO_VOLUME:
- return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 58880);
- case V4L2_CID_AUDIO_MUTE:
- case V4L2_CID_AUDIO_LOUDNESS:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_AUDIO_BALANCE:
- case V4L2_CID_AUDIO_BASS:
- case V4L2_CID_AUDIO_TREBLE:
- return v4l2_ctrl_query_fill(qctrl, 0, 65535, 65535 / 100, 32768);
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
- case V4L2_CID_CONTRAST:
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(qctrl, 0, 127, 1, 64);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(qctrl, -128, 127, 1, 0);
-
- /* MPEG controls */
- case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000, 1,
- V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000);
- case V4L2_CID_MPEG_AUDIO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_1,
- V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
- V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
- case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L1_BITRATE_32K,
- V4L2_MPEG_AUDIO_L1_BITRATE_448K, 1,
- V4L2_MPEG_AUDIO_L1_BITRATE_256K);
- case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L2_BITRATE_32K,
- V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
- V4L2_MPEG_AUDIO_L2_BITRATE_224K);
- case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_L3_BITRATE_32K,
- V4L2_MPEG_AUDIO_L3_BITRATE_320K, 1,
- V4L2_MPEG_AUDIO_L3_BITRATE_192K);
- case V4L2_CID_MPEG_AUDIO_AAC_BITRATE:
- return v4l2_ctrl_query_fill(qctrl, 0, 6400, 1, 3200000);
- case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_AC3_BITRATE_32K,
- V4L2_MPEG_AUDIO_AC3_BITRATE_640K, 1,
- V4L2_MPEG_AUDIO_AC3_BITRATE_384K);
- case V4L2_CID_MPEG_AUDIO_MODE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_MODE_STEREO,
- V4L2_MPEG_AUDIO_MODE_MONO, 1,
- V4L2_MPEG_AUDIO_MODE_STEREO);
- case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16, 1,
- V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4);
- case V4L2_CID_MPEG_AUDIO_EMPHASIS:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_EMPHASIS_NONE,
- V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17, 1,
- V4L2_MPEG_AUDIO_EMPHASIS_NONE);
- case V4L2_CID_MPEG_AUDIO_CRC:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_AUDIO_CRC_NONE,
- V4L2_MPEG_AUDIO_CRC_CRC16, 1,
- V4L2_MPEG_AUDIO_CRC_NONE);
- case V4L2_CID_MPEG_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_MPEG_VIDEO_ENCODING:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC, 1,
- V4L2_MPEG_VIDEO_ENCODING_MPEG_2);
- case V4L2_CID_MPEG_VIDEO_ASPECT:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_ASPECT_1x1,
- V4L2_MPEG_VIDEO_ASPECT_221x100, 1,
- V4L2_MPEG_VIDEO_ASPECT_4x3);
- case V4L2_CID_MPEG_VIDEO_B_FRAMES:
- return v4l2_ctrl_query_fill(qctrl, 0, 33, 1, 2);
- case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
- return v4l2_ctrl_query_fill(qctrl, 1, 34, 1, 12);
- case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
- case V4L2_CID_MPEG_VIDEO_PULLDOWN:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
- V4L2_MPEG_VIDEO_BITRATE_MODE_CBR, 1,
- V4L2_MPEG_VIDEO_BITRATE_MODE_VBR);
- case V4L2_CID_MPEG_VIDEO_BITRATE:
- return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 6000000);
- case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
- return v4l2_ctrl_query_fill(qctrl, 0, 27000000, 1, 8000000);
- case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_VIDEO_MUTE:
- return v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 0);
- case V4L2_CID_MPEG_VIDEO_MUTE_YUV: /* Init YUV (really YCbCr) to black */
- return v4l2_ctrl_query_fill(qctrl, 0, 0xffffff, 1, 0x008080);
- case V4L2_CID_MPEG_STREAM_TYPE:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
- V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD, 1,
- V4L2_MPEG_STREAM_TYPE_MPEG2_PS);
- case V4L2_CID_MPEG_STREAM_PID_PMT:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 16);
- case V4L2_CID_MPEG_STREAM_PID_AUDIO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 260);
- case V4L2_CID_MPEG_STREAM_PID_VIDEO:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 256);
- case V4L2_CID_MPEG_STREAM_PID_PCR:
- return v4l2_ctrl_query_fill(qctrl, 0, (1 << 14) - 1, 1, 259);
- case V4L2_CID_MPEG_STREAM_PES_ID_AUDIO:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_STREAM_PES_ID_VIDEO:
- return v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 0);
- case V4L2_CID_MPEG_STREAM_VBI_FMT:
- return v4l2_ctrl_query_fill(qctrl,
- V4L2_MPEG_STREAM_VBI_FMT_NONE,
- V4L2_MPEG_STREAM_VBI_FMT_IVTV, 1,
- V4L2_MPEG_STREAM_VBI_FMT_NONE);
- default:
- return -EINVAL;
- }
-}
-EXPORT_SYMBOL(v4l2_ctrl_query_fill_std);
-
/* Fill in a struct v4l2_querymenu based on the struct v4l2_queryctrl and
the menu. The qctrl pointer may be NULL, in which case it is ignored.
If menu_items is NULL, then the menu items are retrieved using
@@ -720,7 +607,7 @@ int v4l2_ctrl_query_menu(struct v4l2_querymenu *qmenu, struct v4l2_queryctrl *qc
for (i = 0; i < qmenu->index && menu_items[i]; i++) ;
if (menu_items[i] == NULL || menu_items[i][0] == '\0')
return -EINVAL;
- snprintf(qmenu->name, sizeof(qmenu->name), menu_items[qmenu->index]);
+ strlcpy(qmenu->name, menu_items[qmenu->index], sizeof(qmenu->name));
return 0;
}
EXPORT_SYMBOL(v4l2_ctrl_query_menu);
@@ -737,8 +624,8 @@ int v4l2_ctrl_query_menu_valid_items(struct v4l2_querymenu *qmenu, const u32 *id
return -EINVAL;
while (*ids != V4L2_CTRL_MENU_IDS_END) {
if (*ids++ == qmenu->index) {
- snprintf(qmenu->name, sizeof(qmenu->name),
- menu_items[qmenu->index]);
+ strlcpy(qmenu->name, menu_items[qmenu->index],
+ sizeof(qmenu->name));
return 0;
}
}
@@ -749,7 +636,7 @@ EXPORT_SYMBOL(v4l2_ctrl_query_menu_valid_items);
/* ctrl_classes points to an array of u32 pointers, the last element is
a NULL pointer. Each u32 array is a 0-terminated array of control IDs.
Each array must be sorted low to high and belong to the same control
- class. The array of u32 pointer must also be sorted, from low class IDs
+ class. The array of u32 pointers must also be sorted, from low class IDs
to high class IDs.
This function returns the first ID that follows after the given ID.
@@ -910,10 +797,10 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
struct i2c_board_info info;
BUG_ON(!dev);
-#ifdef MODULE
+
if (module_name)
request_module(module_name);
-#endif
+
/* Setup the i2c board info with the device type and
the device address. */
memset(&info, 0, sizeof(info));
@@ -927,11 +814,11 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
We need better support from the kernel so that we
can easily wait for the load to finish. */
if (client == NULL || client->driver == NULL)
- return NULL;
+ goto error;
/* Lock the module so we can safely get the v4l2_subdev pointer */
if (!try_module_get(client->driver->driver.owner))
- return NULL;
+ goto error;
sd = i2c_get_clientdata(client);
/* Register with the v4l2_device which increases the module's
@@ -940,8 +827,13 @@ struct v4l2_subdev *v4l2_i2c_new_subdev(struct i2c_adapter *adapter,
sd = NULL;
/* Decrease the module use count to match the first try_module_get. */
module_put(client->driver->driver.owner);
- return sd;
+error:
+ /* If we have a client but no subdev, then something went wrong and
+ we must unregister the client. */
+ if (client && sd == NULL)
+ i2c_unregister_device(client);
+ return sd;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
@@ -958,10 +850,10 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
struct i2c_board_info info;
BUG_ON(!dev);
-#ifdef MODULE
+
if (module_name)
request_module(module_name);
-#endif
+
/* Setup the i2c board info with the device type and
the device address. */
memset(&info, 0, sizeof(info));
@@ -974,11 +866,11 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
We need better support from the kernel so that we
can easily wait for the load to finish. */
if (client == NULL || client->driver == NULL)
- return NULL;
+ goto error;
/* Lock the module so we can safely get the v4l2_subdev pointer */
if (!try_module_get(client->driver->driver.owner))
- return NULL;
+ goto error;
sd = i2c_get_clientdata(client);
/* Register with the v4l2_device which increases the module's
@@ -987,8 +879,59 @@ struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct i2c_adapter *adapter,
sd = NULL;
/* Decrease the module use count to match the first try_module_get. */
module_put(client->driver->driver.owner);
+
+error:
+ /* If we have a client but no subdev, then something went wrong and
+ we must unregister the client. */
+ if (client && sd == NULL)
+ i2c_unregister_device(client);
return sd;
}
EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
+/* Return i2c client address of v4l2_subdev. */
+unsigned short v4l2_i2c_subdev_addr(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return client ? client->addr : I2C_CLIENT_END;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_addr);
+
+/* Return a list of I2C tuner addresses to probe. Use only if the tuner
+ addresses are unknown. */
+const unsigned short *v4l2_i2c_tuner_addrs(enum v4l2_i2c_tuner_type type)
+{
+ static const unsigned short radio_addrs[] = {
+#if defined(CONFIG_MEDIA_TUNER_TEA5761) || defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE)
+ 0x10,
+#endif
+ 0x60,
+ I2C_CLIENT_END
+ };
+ static const unsigned short demod_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b,
+ I2C_CLIENT_END
+ };
+ static const unsigned short tv_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ I2C_CLIENT_END
+ };
+
+ switch (type) {
+ case ADDRS_RADIO:
+ return radio_addrs;
+ case ADDRS_DEMOD:
+ return demod_addrs;
+ case ADDRS_TV:
+ return tv_addrs;
+ case ADDRS_TV_WITH_DEMOD:
+ return tv_addrs + 4;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(v4l2_i2c_tuner_addrs);
+
#endif
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 110376be5d2..0056b115b42 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -1047,7 +1047,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
case VIDIOC_DBG_S_REGISTER:
case VIDIOC_DBG_G_REGISTER:
case VIDIOC_DBG_G_CHIP_IDENT:
- case VIDIOC_G_CHIP_IDENT_OLD:
case VIDIOC_S_HW_FREQ_SEEK:
ret = do_video_ioctl(file, cmd, arg);
break;
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 13f87c22e78..91228b3df07 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -198,6 +198,23 @@ static long v4l2_unlocked_ioctl(struct file *filp,
return vdev->fops->unlocked_ioctl(filp, cmd, arg);
}
+#ifdef CONFIG_MMU
+#define v4l2_get_unmapped_area NULL
+#else
+static unsigned long v4l2_get_unmapped_area(struct file *filp,
+ unsigned long addr, unsigned long len, unsigned long pgoff,
+ unsigned long flags)
+{
+ struct video_device *vdev = video_devdata(filp);
+
+ if (!vdev->fops->get_unmapped_area)
+ return -ENOSYS;
+ if (video_is_unregistered(vdev))
+ return -ENODEV;
+ return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
+}
+#endif
+
static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
{
struct video_device *vdev = video_devdata(filp);
@@ -250,6 +267,7 @@ static const struct file_operations v4l2_unlocked_fops = {
.read = v4l2_read,
.write = v4l2_write,
.open = v4l2_open,
+ .get_unmapped_area = v4l2_get_unmapped_area,
.mmap = v4l2_mmap,
.unlocked_ioctl = v4l2_unlocked_ioctl,
#ifdef CONFIG_COMPAT
@@ -265,6 +283,7 @@ static const struct file_operations v4l2_fops = {
.read = v4l2_read,
.write = v4l2_write,
.open = v4l2_open,
+ .get_unmapped_area = v4l2_get_unmapped_area,
.mmap = v4l2_mmap,
.ioctl = v4l2_ioctl,
#ifdef CONFIG_COMPAT
@@ -288,37 +307,38 @@ static const struct file_operations v4l2_fops = {
*/
static int get_index(struct video_device *vdev, int num)
{
- u32 used = 0;
- const int max_index = sizeof(used) * 8 - 1;
+ /* This can be static since this function is called with the global
+ videodev_lock held. */
+ static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
int i;
- /* Currently a single v4l driver instance cannot create more than
- 32 devices.
- Increase to u64 or an array of u32 if more are needed. */
- if (num > max_index) {
+ if (num >= VIDEO_NUM_DEVICES) {
printk(KERN_ERR "videodev: %s num is too large\n", __func__);
return -EINVAL;
}
- /* Some drivers do not set the parent. In that case always return 0. */
+ /* Some drivers do not set the parent. In that case always return
+ num or 0. */
if (vdev->parent == NULL)
- return 0;
+ return num >= 0 ? num : 0;
+
+ bitmap_zero(used, VIDEO_NUM_DEVICES);
for (i = 0; i < VIDEO_NUM_DEVICES; i++) {
if (video_device[i] != NULL &&
video_device[i]->parent == vdev->parent) {
- used |= 1 << video_device[i]->index;
+ set_bit(video_device[i]->index, used);
}
}
if (num >= 0) {
- if (used & (1 << num))
+ if (test_bit(num, used))
return -ENFILE;
return num;
}
- i = ffz(used);
- return i > max_index ? -ENFILE : i;
+ i = find_first_zero_bit(used, VIDEO_NUM_DEVICES);
+ return i == VIDEO_NUM_DEVICES ? -ENFILE : i;
}
int video_register_device(struct video_device *vdev, int type, int nr)
@@ -365,12 +385,11 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
/* A minor value of -1 marks this video device as never
having been registered */
- if (vdev)
- vdev->minor = -1;
+ vdev->minor = -1;
/* the release callback MUST be present */
- WARN_ON(!vdev || !vdev->release);
- if (!vdev || !vdev->release)
+ WARN_ON(!vdev->release);
+ if (!vdev->release)
return -EINVAL;
/* Part 1: check device type */
@@ -395,7 +414,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
vdev->vfl_type = type;
vdev->cdev = NULL;
- if (vdev->v4l2_dev)
+ if (vdev->v4l2_dev && vdev->v4l2_dev->dev)
vdev->parent = vdev->v4l2_dev->dev;
/* Part 2: find a free minor, kernel number and device index. */
@@ -582,6 +601,7 @@ module_exit(videodev_exit)
MODULE_AUTHOR("Alan Cox, Mauro Carvalho Chehab <mchehab@infradead.org>");
MODULE_DESCRIPTION("Device registrar for Video4Linux drivers v2");
MODULE_LICENSE("GPL");
+MODULE_ALIAS_CHARDEV_MAJOR(VIDEO_MAJOR);
/*
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index 8a4b74f3129..94aa485ade5 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -26,48 +26,66 @@
int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
{
- if (dev == NULL || v4l2_dev == NULL)
+ if (v4l2_dev == NULL)
return -EINVAL;
- /* Warn if we apparently re-register a device */
- WARN_ON(dev_get_drvdata(dev) != NULL);
+
INIT_LIST_HEAD(&v4l2_dev->subdevs);
spin_lock_init(&v4l2_dev->lock);
v4l2_dev->dev = dev;
- snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
+ if (dev == NULL) {
+ /* If dev == NULL, then name must be filled in by the caller */
+ WARN_ON(!v4l2_dev->name[0]);
+ return 0;
+ }
+
+ /* Set name to driver name + device name if it is empty. */
+ if (!v4l2_dev->name[0])
+ snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
dev->driver->name, dev_name(dev));
+ if (dev_get_drvdata(dev))
+ v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n");
dev_set_drvdata(dev, v4l2_dev);
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register);
+void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
+{
+ if (v4l2_dev->dev) {
+ dev_set_drvdata(v4l2_dev->dev, NULL);
+ v4l2_dev->dev = NULL;
+ }
+}
+EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
+
void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
{
struct v4l2_subdev *sd, *next;
- if (v4l2_dev == NULL || v4l2_dev->dev == NULL)
+ if (v4l2_dev == NULL)
return;
- dev_set_drvdata(v4l2_dev->dev, NULL);
- /* unregister subdevs */
+ v4l2_device_disconnect(v4l2_dev);
+
+ /* Unregister subdevs */
list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list)
v4l2_device_unregister_subdev(sd);
-
- v4l2_dev->dev = NULL;
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister);
-int v4l2_device_register_subdev(struct v4l2_device *dev, struct v4l2_subdev *sd)
+int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
+ struct v4l2_subdev *sd)
{
/* Check for valid input */
- if (dev == NULL || sd == NULL || !sd->name[0])
+ if (v4l2_dev == NULL || sd == NULL || !sd->name[0])
return -EINVAL;
/* Warn if we apparently re-register a subdev */
- WARN_ON(sd->dev != NULL);
+ WARN_ON(sd->v4l2_dev != NULL);
if (!try_module_get(sd->owner))
return -ENODEV;
- sd->dev = dev;
- spin_lock(&dev->lock);
- list_add_tail(&sd->list, &dev->subdevs);
- spin_unlock(&dev->lock);
+ sd->v4l2_dev = v4l2_dev;
+ spin_lock(&v4l2_dev->lock);
+ list_add_tail(&sd->list, &v4l2_dev->subdevs);
+ spin_unlock(&v4l2_dev->lock);
return 0;
}
EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
@@ -75,12 +93,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
{
/* return if it isn't registered */
- if (sd == NULL || sd->dev == NULL)
+ if (sd == NULL || sd->v4l2_dev == NULL)
return;
- spin_lock(&sd->dev->lock);
+ spin_lock(&sd->v4l2_dev->lock);
list_del(&sd->list);
- spin_unlock(&sd->dev->lock);
- sd->dev = NULL;
+ spin_unlock(&sd->v4l2_dev->lock);
+ sd->v4l2_dev = NULL;
module_put(sd->owner);
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 52d687b165e..f41c6f506f4 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#define __OLD_VIDIOC_ /* To allow fixing old calls */
+#include <linux/videodev.h>
#include <linux/videodev2.h>
#ifdef CONFIG_VIDEO_V4L1
@@ -24,7 +25,7 @@
#endif
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
-#include <linux/video_decoder.h>
+#include <media/v4l2-chip-ident.h>
#define dbgarg(cmd, fmt, arg...) \
do { \
@@ -100,25 +101,27 @@ const char *v4l2_norm_to_name(v4l2_std_id id)
}
EXPORT_SYMBOL(v4l2_norm_to_name);
+/* Returns frame period for the given standard */
+void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod)
+{
+ if (id & V4L2_STD_525_60) {
+ frameperiod->numerator = 1001;
+ frameperiod->denominator = 30000;
+ } else {
+ frameperiod->numerator = 1;
+ frameperiod->denominator = 25;
+ }
+}
+EXPORT_SYMBOL(v4l2_video_std_frame_period);
+
/* Fill in the fields of a v4l2_standard structure according to the
'id' and 'transmission' parameters. Returns negative on error. */
int v4l2_video_std_construct(struct v4l2_standard *vs,
int id, const char *name)
{
- u32 index = vs->index;
-
- memset(vs, 0, sizeof(struct v4l2_standard));
- vs->index = index;
- vs->id = id;
- if (id & V4L2_STD_525_60) {
- vs->frameperiod.numerator = 1001;
- vs->frameperiod.denominator = 30000;
- vs->framelines = 525;
- } else {
- vs->frameperiod.numerator = 1;
- vs->frameperiod.denominator = 25;
- vs->framelines = 625;
- }
+ vs->id = id;
+ v4l2_video_std_frame_period(id, &vs->frameperiod);
+ vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625;
strlcpy(vs->name, name, sizeof(vs->name));
return 0;
}
@@ -273,19 +276,6 @@ static const char *v4l2_ioctls[] = {
#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
static const char *v4l2_int_ioctls[] = {
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES",
- [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS",
- [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM",
- [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT",
- [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT",
- [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT",
- [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE",
- [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO",
- [_IOC_NR(DECODER_INIT)] = "DECODER_INIT",
- [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS",
- [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP",
-#endif
[_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO",
[_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR",
@@ -654,8 +644,6 @@ static long __video_do_ioctl(struct file *file,
if (cmd == VIDIOCGMBUF) {
struct video_mbuf *p = arg;
- memset(p, 0, sizeof(*p));
-
if (!ops->vidiocgmbuf)
return ret;
ret = ops->vidiocgmbuf(file, fh, p);
@@ -682,7 +670,6 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = (struct v4l2_capability *)arg;
- memset(cap, 0, sizeof(*cap));
if (!ops->vidioc_querycap)
break;
@@ -725,16 +712,8 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_ENUM_FMT:
{
struct v4l2_fmtdesc *f = arg;
- enum v4l2_buf_type type;
- unsigned int index;
-
- index = f->index;
- type = f->type;
- memset(f, 0, sizeof(*f));
- f->index = index;
- f->type = type;
- switch (type) {
+ switch (f->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
if (ops->vidioc_enum_fmt_vid_cap)
ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
@@ -771,8 +750,6 @@ static long __video_do_ioctl(struct file *file,
{
struct v4l2_format *f = (struct v4l2_format *)arg;
- memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data));
-
/* FIXME: Should be one dump per type */
dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names));
@@ -1088,7 +1065,6 @@ static long __video_do_ioctl(struct file *file,
return -EINVAL;
v4l2_video_std_construct(p, curr_id, descr);
- p->index = index;
dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, "
"framelines=%d\n", p->index,
@@ -1153,12 +1129,9 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_ENUMINPUT:
{
struct v4l2_input *p = arg;
- int i = p->index;
if (!ops->vidioc_enum_input)
break;
- memset(p, 0, sizeof(*p));
- p->index = i;
ret = ops->vidioc_enum_input(file, fh, p);
if (!ret)
@@ -1197,12 +1170,9 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_ENUMOUTPUT:
{
struct v4l2_output *p = arg;
- int i = p->index;
if (!ops->vidioc_enum_output)
break;
- memset(p, 0, sizeof(*p));
- p->index = i;
ret = ops->vidioc_enum_output(file, fh, p);
if (!ret)
@@ -1378,13 +1348,10 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_AUDIO:
{
struct v4l2_audio *p = arg;
- __u32 index = p->index;
if (!ops->vidioc_g_audio)
break;
- memset(p, 0, sizeof(*p));
- p->index = index;
ret = ops->vidioc_g_audio(file, fh, p);
if (!ret)
dbgarg(cmd, "index=%d, name=%s, capability=0x%x, "
@@ -1426,7 +1393,7 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_audout)
break;
- dbgarg(cmd, "Enum for index=%d\n", p->index);
+
ret = ops->vidioc_g_audout(file, fh, p);
if (!ret)
dbgarg2("index=%d, name=%s, capability=%d, "
@@ -1479,15 +1446,10 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_CROP:
{
struct v4l2_crop *p = arg;
- __u32 type;
if (!ops->vidioc_g_crop)
break;
- type = p->type;
- memset(p, 0, sizeof(*p));
- p->type = type;
-
dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
ret = ops->vidioc_g_crop(file, fh, p);
if (!ret)
@@ -1508,16 +1470,11 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_CROPCAP:
{
struct v4l2_cropcap *p = arg;
- __u32 type;
/*FIXME: Should also show v4l2_fract pixelaspect */
if (!ops->vidioc_cropcap)
break;
- type = p->type;
- memset(p, 0, sizeof(*p));
- p->type = type;
-
dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
ret = ops->vidioc_cropcap(file, fh, p);
if (!ret) {
@@ -1533,8 +1490,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_jpegcomp)
break;
- memset(p, 0, sizeof(*p));
-
ret = ops->vidioc_g_jpegcomp(file, fh, p);
if (!ret)
dbgarg(cmd, "quality=%d, APPn=%d, "
@@ -1575,7 +1530,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_encoder_cmd)
break;
- memset(&p->raw, 0, sizeof(p->raw));
ret = ops->vidioc_encoder_cmd(file, fh, p);
if (!ret)
dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1587,7 +1541,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_try_encoder_cmd)
break;
- memset(&p->raw, 0, sizeof(p->raw));
ret = ops->vidioc_try_encoder_cmd(file, fh, p);
if (!ret)
dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags);
@@ -1596,23 +1549,18 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_PARM:
{
struct v4l2_streamparm *p = arg;
- __u32 type = p->type;
-
- memset(p, 0, sizeof(*p));
- p->type = type;
if (ops->vidioc_g_parm) {
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
ret = ops->vidioc_g_parm(file, fh, p);
} else {
- struct v4l2_standard s;
-
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
return -EINVAL;
- v4l2_video_std_construct(&s, vfd->current_norm,
- v4l2_norm_to_name(vfd->current_norm));
-
- p->parm.capture.timeperframe = s.frameperiod;
+ v4l2_video_std_frame_period(vfd->current_norm,
+ &p->parm.capture.timeperframe);
ret = 0;
}
@@ -1625,6 +1573,10 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_s_parm)
break;
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
+
dbgarg(cmd, "type=%d\n", p->type);
ret = ops->vidioc_s_parm(file, fh, p);
break;
@@ -1632,14 +1584,10 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_TUNER:
{
struct v4l2_tuner *p = arg;
- __u32 index = p->index;
if (!ops->vidioc_g_tuner)
break;
- memset(p, 0, sizeof(*p));
- p->index = index;
-
ret = ops->vidioc_g_tuner(file, fh, p);
if (!ret)
dbgarg(cmd, "index=%d, name=%s, type=%d, "
@@ -1676,8 +1624,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_frequency)
break;
- memset(p->reserved, 0, sizeof(p->reserved));
-
ret = ops->vidioc_g_frequency(file, fh, p);
if (!ret)
dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n",
@@ -1698,12 +1644,13 @@ static long __video_do_ioctl(struct file *file,
case VIDIOC_G_SLICED_VBI_CAP:
{
struct v4l2_sliced_vbi_cap *p = arg;
- __u32 type = p->type;
if (!ops->vidioc_g_sliced_vbi_cap)
break;
- memset(p, 0, sizeof(*p));
- p->type = type;
+
+ /* Clear up to type, everything after type is zerod already */
+ memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type));
+
dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names));
ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p);
if (!ret)
@@ -1745,16 +1692,13 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_g_chip_ident)
break;
+ p->ident = V4L2_IDENT_NONE;
+ p->revision = 0;
ret = ops->vidioc_g_chip_ident(file, fh, p);
if (!ret)
dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision);
break;
}
- case VIDIOC_G_CHIP_IDENT_OLD:
- printk(KERN_ERR "VIDIOC_G_CHIP_IDENT has been deprecated and will disappear in 2.6.30.\n");
- printk(KERN_ERR "It is a debugging ioctl and must not be used in applications!\n");
- return -EINVAL;
-
case VIDIOC_S_HW_FREQ_SEEK:
{
struct v4l2_hw_freq_seek *p = arg;
@@ -1774,8 +1718,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_enum_framesizes)
break;
- memset(p, 0, sizeof(*p));
-
ret = ops->vidioc_enum_framesizes(file, fh, p);
dbgarg(cmd,
"index=%d, pixelformat=%d, type=%d ",
@@ -1807,8 +1749,6 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_enum_frameintervals)
break;
- memset(p, 0, sizeof(*p));
-
ret = ops->vidioc_enum_frameintervals(file, fh, p);
dbgarg(cmd,
"index=%d, pixelformat=%d, width=%d, height=%d, type=%d ",
@@ -1857,6 +1797,45 @@ static long __video_do_ioctl(struct file *file,
return ret;
}
+/* In some cases, only a few fields are used as input, i.e. when the app sets
+ * "index" and then the driver fills in the rest of the structure for the thing
+ * with that index. We only need to copy up the first non-input field. */
+static unsigned long cmd_input_size(unsigned int cmd)
+{
+ /* Size of structure up to and including 'field' */
+#define CMDINSIZE(cmd, type, field) \
+ case VIDIOC_##cmd: \
+ return offsetof(struct v4l2_##type, field) + \
+ sizeof(((struct v4l2_##type *)0)->field);
+
+ switch (cmd) {
+ CMDINSIZE(ENUM_FMT, fmtdesc, type);
+ CMDINSIZE(G_FMT, format, type);
+ CMDINSIZE(QUERYBUF, buffer, type);
+ CMDINSIZE(G_PARM, streamparm, type);
+ CMDINSIZE(ENUMSTD, standard, index);
+ CMDINSIZE(ENUMINPUT, input, index);
+ CMDINSIZE(G_CTRL, control, id);
+ CMDINSIZE(G_TUNER, tuner, index);
+ CMDINSIZE(QUERYCTRL, queryctrl, id);
+ CMDINSIZE(QUERYMENU, querymenu, index);
+ CMDINSIZE(ENUMOUTPUT, output, index);
+ CMDINSIZE(G_MODULATOR, modulator, index);
+ CMDINSIZE(G_FREQUENCY, frequency, tuner);
+ CMDINSIZE(CROPCAP, cropcap, type);
+ CMDINSIZE(G_CROP, crop, type);
+ CMDINSIZE(ENUMAUDIO, audio, index);
+ CMDINSIZE(ENUMAUDOUT, audioout, index);
+ CMDINSIZE(ENCODER_CMD, encoder_cmd, flags);
+ CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags);
+ CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type);
+ CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format);
+ CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height);
+ default:
+ return _IOC_SIZE(cmd);
+ }
+}
+
long video_ioctl2(struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -1875,13 +1854,7 @@ long video_ioctl2(struct file *file,
cmd == VIDIOC_TRY_EXT_CTRLS);
/* Copy arguments into temp kernel buffer */
- switch (_IOC_DIR(cmd)) {
- case _IOC_NONE:
- parg = NULL;
- break;
- case _IOC_READ:
- case _IOC_WRITE:
- case (_IOC_WRITE | _IOC_READ):
+ if (_IOC_DIR(cmd) != _IOC_NONE) {
if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
parg = sbuf;
} else {
@@ -1893,10 +1866,19 @@ long video_ioctl2(struct file *file,
}
err = -EFAULT;
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
+ if (_IOC_DIR(cmd) & _IOC_WRITE) {
+ unsigned long n = cmd_input_size(cmd);
+
+ if (copy_from_user(parg, (void __user *)arg, n))
goto out;
- break;
+
+ /* zero out anything we don't copy from userspace */
+ if (n < _IOC_SIZE(cmd))
+ memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n);
+ } else {
+ /* read-only ioctl */
+ memset(parg, 0, _IOC_SIZE(cmd));
+ }
}
if (is_ext_ctrl) {
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
index 21208805ea9..dc881671d53 100644
--- a/drivers/media/video/v4l2-subdev.c
+++ b/drivers/media/video/v4l2-subdev.c
@@ -33,6 +33,12 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
return v4l2_subdev_call(sd, core, g_ctrl, arg);
case VIDIOC_S_CTRL:
return v4l2_subdev_call(sd, core, s_ctrl, arg);
+ case VIDIOC_G_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, g_ext_ctrls, arg);
+ case VIDIOC_S_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, s_ext_ctrls, arg);
+ case VIDIOC_TRY_EXT_CTRLS:
+ return v4l2_subdev_call(sd, core, try_ext_ctrls, arg);
case VIDIOC_QUERYMENU:
return v4l2_subdev_call(sd, core, querymenu, arg);
case VIDIOC_LOG_STATUS:
@@ -92,16 +98,28 @@ int v4l2_subdev_command(struct v4l2_subdev *sd, unsigned cmd, void *arg)
return v4l2_subdev_call(sd, video, g_vbi_data, arg);
case VIDIOC_G_SLICED_VBI_CAP:
return v4l2_subdev_call(sd, video, g_sliced_vbi_cap, arg);
+ case VIDIOC_ENUM_FMT:
+ return v4l2_subdev_call(sd, video, enum_fmt, arg);
+ case VIDIOC_TRY_FMT:
+ return v4l2_subdev_call(sd, video, try_fmt, arg);
case VIDIOC_S_FMT:
return v4l2_subdev_call(sd, video, s_fmt, arg);
case VIDIOC_G_FMT:
return v4l2_subdev_call(sd, video, g_fmt, arg);
case VIDIOC_INT_S_STD_OUTPUT:
return v4l2_subdev_call(sd, video, s_std_output, *(v4l2_std_id *)arg);
+ case VIDIOC_QUERYSTD:
+ return v4l2_subdev_call(sd, video, querystd, arg);
+ case VIDIOC_INT_G_INPUT_STATUS:
+ return v4l2_subdev_call(sd, video, g_input_status, arg);
case VIDIOC_STREAMON:
return v4l2_subdev_call(sd, video, s_stream, 1);
case VIDIOC_STREAMOFF:
return v4l2_subdev_call(sd, video, s_stream, 0);
+ case VIDIOC_S_PARM:
+ return v4l2_subdev_call(sd, video, s_parm, arg);
+ case VIDIOC_G_PARM:
+ return v4l2_subdev_call(sd, video, g_parm, arg);
default:
return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index 31944b11e6e..6109fb5f34e 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -400,7 +400,7 @@ void videobuf_dma_contig_free(struct videobuf_queue *q,
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || !buf->baddr)
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)
diff --git a/drivers/media/video/videobuf-vmalloc.c b/drivers/media/video/videobuf-vmalloc.c
index be65a2fb397..30ae30f99cc 100644
--- a/drivers/media/video/videobuf-vmalloc.c
+++ b/drivers/media/video/videobuf-vmalloc.c
@@ -425,7 +425,7 @@ void videobuf_vmalloc_free (struct videobuf_buffer *buf)
So, it should free memory only if the memory were allocated for
read() operation.
*/
- if ((buf->memory != V4L2_MEMORY_USERPTR) || (buf->baddr == 0))
+ if ((buf->memory != V4L2_MEMORY_USERPTR) || buf->baddr)
return;
if (!mem)
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index 88bf845a3d5..8da4dd1e0e9 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -8,6 +8,12 @@
*
* Based on the previous version of the driver for 2.4 kernels by:
* Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
+ *
+ * v4l2_device/v4l2_subdev conversion by:
+ * Copyright (C) 2009 Hans Verkuil <hverkuil@xs4all.nl>
+ *
+ * Note: this conversion is untested! Please contact the linux-media
+ * mailinglist if you can test this, together with the test results.
*/
/*
@@ -33,12 +39,10 @@
#include <linux/kmod.h>
#include <linux/i2c.h>
-#include <linux/i2c-algo-sgi.h>
#include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
-#include <linux/video_decoder.h>
#include <linux/mutex.h>
#include <asm/paccess.h>
@@ -139,13 +143,23 @@ MODULE_LICENSE("GPL");
#define VINO_DATA_NORM_PAL 1
#define VINO_DATA_NORM_SECAM 2
#define VINO_DATA_NORM_D1 3
-/* The following are special entries that can be used to
- * autodetect the norm. */
-#define VINO_DATA_NORM_AUTO 0xfe
-#define VINO_DATA_NORM_AUTO_EXT 0xff
#define VINO_DATA_NORM_COUNT 4
+/* I2C controller flags */
+#define SGI_I2C_FORCE_IDLE (0 << 0)
+#define SGI_I2C_NOT_IDLE (1 << 0)
+#define SGI_I2C_WRITE (0 << 1)
+#define SGI_I2C_READ (1 << 1)
+#define SGI_I2C_RELEASE_BUS (0 << 2)
+#define SGI_I2C_HOLD_BUS (1 << 2)
+#define SGI_I2C_XFER_DONE (0 << 4)
+#define SGI_I2C_XFER_BUSY (1 << 4)
+#define SGI_I2C_ACK (0 << 5)
+#define SGI_I2C_NACK (1 << 5)
+#define SGI_I2C_BUS_OK (0 << 7)
+#define SGI_I2C_BUS_ERR (1 << 7)
+
/* Internal data structure definitions */
struct vino_input {
@@ -289,22 +303,20 @@ struct vino_channel_settings {
struct vino_interrupt_data int_data;
/* V4L support */
- struct video_device *v4l_device;
-};
-
-struct vino_client {
- /* the channel which owns this client:
- * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
- unsigned int owner;
- struct i2c_client *driver;
+ struct video_device *vdev;
};
struct vino_settings {
+ struct v4l2_device v4l2_dev;
struct vino_channel_settings a;
struct vino_channel_settings b;
- struct vino_client decoder;
- struct vino_client camera;
+ /* the channel which owns this client:
+ * VINO_NO_CHANNEL, VINO_CHANNEL_A or VINO_CHANNEL_B */
+ unsigned int decoder_owner;
+ struct v4l2_subdev *decoder;
+ unsigned int camera_owner;
+ struct v4l2_subdev *camera;
/* a lock for vino register access */
spinlock_t vino_lock;
@@ -344,11 +356,16 @@ static struct sgi_vino *vino;
static struct vino_settings *vino_drvdata;
+#define camera_call(o, f, args...) \
+ v4l2_subdev_call(vino_drvdata->camera, o, f, ##args)
+#define decoder_call(o, f, args...) \
+ v4l2_subdev_call(vino_drvdata->decoder, o, f, ##args)
+
static const char *vino_driver_name = "vino";
static const char *vino_driver_description = "SGI VINO";
static const char *vino_bus_name = "GIO64 bus";
-static const char *vino_v4l_device_name_a = "SGI VINO Channel A";
-static const char *vino_v4l_device_name_b = "SGI VINO Channel B";
+static const char *vino_vdev_name_a = "SGI VINO Channel A";
+static const char *vino_vdev_name_b = "SGI VINO Channel B";
static void vino_capture_tasklet(unsigned long channel);
@@ -360,11 +377,11 @@ static const struct vino_input vino_inputs[] = {
.name = "Composite",
.std = V4L2_STD_NTSC | V4L2_STD_PAL
| V4L2_STD_SECAM,
- },{
+ }, {
.name = "S-Video",
.std = V4L2_STD_NTSC | V4L2_STD_PAL
| V4L2_STD_SECAM,
- },{
+ }, {
.name = "D1/IndyCam",
.std = V4L2_STD_NTSC,
}
@@ -376,17 +393,17 @@ static const struct vino_data_format vino_data_formats[] = {
.bpp = 1,
.pixelformat = V4L2_PIX_FMT_GREY,
.colorspace = V4L2_COLORSPACE_SMPTE170M,
- },{
+ }, {
.description = "8-bit dithered RGB 3-3-2",
.bpp = 1,
.pixelformat = V4L2_PIX_FMT_RGB332,
.colorspace = V4L2_COLORSPACE_SRGB,
- },{
+ }, {
.description = "32-bit RGB",
.bpp = 4,
.pixelformat = V4L2_PIX_FMT_RGB32,
.colorspace = V4L2_COLORSPACE_SRGB,
- },{
+ }, {
.description = "YUV 4:2:2",
.bpp = 2,
.pixelformat = V4L2_PIX_FMT_YUYV, // XXX: swapped?
@@ -417,7 +434,7 @@ static const struct vino_data_norm vino_data_norms[] = {
+ VINO_NTSC_HEIGHT / 2 - 1,
.right = VINO_NTSC_WIDTH,
},
- },{
+ }, {
.description = "PAL",
.std = V4L2_STD_PAL,
.fps_min = 5,
@@ -439,7 +456,7 @@ static const struct vino_data_norm vino_data_norms[] = {
+ VINO_PAL_HEIGHT / 2 - 1,
.right = VINO_PAL_WIDTH,
},
- },{
+ }, {
.description = "SECAM",
.std = V4L2_STD_SECAM,
.fps_min = 5,
@@ -461,7 +478,7 @@ static const struct vino_data_norm vino_data_norms[] = {
+ VINO_PAL_HEIGHT / 2 - 1,
.right = VINO_PAL_WIDTH,
},
- },{
+ }, {
.description = "NTSC/D1",
.std = V4L2_STD_NTSC,
.fps_min = 6,
@@ -497,9 +514,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = 1,
.step = 1,
.default_value = INDYCAM_AGC_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_AGC, 0 },
- },{
+ }, {
.id = V4L2_CID_AUTO_WHITE_BALANCE,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Automatic White Balance",
@@ -507,9 +522,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = 1,
.step = 1,
.default_value = INDYCAM_AWB_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_AWB, 0 },
- },{
+ }, {
.id = V4L2_CID_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gain",
@@ -517,29 +530,23 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_GAIN_MAX,
.step = 1,
.default_value = INDYCAM_GAIN_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_GAIN, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE,
+ }, {
+ .id = INDYCAM_CONTROL_RED_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Red Saturation",
.minimum = INDYCAM_RED_SATURATION_MIN,
.maximum = INDYCAM_RED_SATURATION_MAX,
.step = 1,
.default_value = INDYCAM_RED_SATURATION_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_RED_SATURATION, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 1,
+ }, {
+ .id = INDYCAM_CONTROL_BLUE_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Blue Saturation",
.minimum = INDYCAM_BLUE_SATURATION_MIN,
.maximum = INDYCAM_BLUE_SATURATION_MAX,
.step = 1,
.default_value = INDYCAM_BLUE_SATURATION_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_BLUE_SATURATION, 0 },
- },{
+ }, {
.id = V4L2_CID_RED_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Red Balance",
@@ -547,9 +554,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_RED_BALANCE_MAX,
.step = 1,
.default_value = INDYCAM_RED_BALANCE_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_RED_BALANCE, 0 },
- },{
+ }, {
.id = V4L2_CID_BLUE_BALANCE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Blue Balance",
@@ -557,9 +562,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_BLUE_BALANCE_MAX,
.step = 1,
.default_value = INDYCAM_BLUE_BALANCE_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_BLUE_BALANCE, 0 },
- },{
+ }, {
.id = V4L2_CID_EXPOSURE,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Shutter Control",
@@ -567,9 +570,7 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_SHUTTER_MAX,
.step = 1,
.default_value = INDYCAM_SHUTTER_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_SHUTTER, 0 },
- },{
+ }, {
.id = V4L2_CID_GAMMA,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Gamma",
@@ -577,8 +578,6 @@ struct v4l2_queryctrl vino_indycam_v4l2_controls[] = {
.maximum = INDYCAM_GAMMA_MAX,
.step = 1,
.default_value = INDYCAM_GAMMA_DEFAULT,
- .flags = 0,
- .reserved = { INDYCAM_CONTROL_GAMMA, 0 },
}
};
@@ -593,209 +592,73 @@ struct v4l2_queryctrl vino_saa7191_v4l2_controls[] = {
.maximum = SAA7191_HUE_MAX,
.step = 1,
.default_value = SAA7191_HUE_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_HUE, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE,
+ }, {
+ .id = SAA7191_CONTROL_BANDPASS,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Bandpass",
.minimum = SAA7191_BANDPASS_MIN,
.maximum = SAA7191_BANDPASS_MAX,
.step = 1,
.default_value = SAA7191_BANDPASS_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_BANDPASS, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 1,
+ }, {
+ .id = SAA7191_CONTROL_BANDPASS_WEIGHT,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Bandpass Weight",
.minimum = SAA7191_BANDPASS_WEIGHT_MIN,
.maximum = SAA7191_BANDPASS_WEIGHT_MAX,
.step = 1,
.default_value = SAA7191_BANDPASS_WEIGHT_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_BANDPASS_WEIGHT, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 2,
+ }, {
+ .id = SAA7191_CONTROL_CORING,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "HF Luminance Coring",
.minimum = SAA7191_CORING_MIN,
.maximum = SAA7191_CORING_MAX,
.step = 1,
.default_value = SAA7191_CORING_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_CORING, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 3,
+ }, {
+ .id = SAA7191_CONTROL_FORCE_COLOUR,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "Force Colour",
.minimum = SAA7191_FORCE_COLOUR_MIN,
.maximum = SAA7191_FORCE_COLOUR_MAX,
.step = 1,
.default_value = SAA7191_FORCE_COLOUR_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_FORCE_COLOUR, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 4,
+ }, {
+ .id = SAA7191_CONTROL_CHROMA_GAIN,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Chrominance Gain Control",
.minimum = SAA7191_CHROMA_GAIN_MIN,
.maximum = SAA7191_CHROMA_GAIN_MAX,
.step = 1,
.default_value = SAA7191_CHROMA_GAIN_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_CHROMA_GAIN, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 5,
+ }, {
+ .id = SAA7191_CONTROL_VTRC,
.type = V4L2_CTRL_TYPE_BOOLEAN,
.name = "VTR Time Constant",
.minimum = SAA7191_VTRC_MIN,
.maximum = SAA7191_VTRC_MAX,
.step = 1,
.default_value = SAA7191_VTRC_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_VTRC, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 6,
+ }, {
+ .id = SAA7191_CONTROL_LUMA_DELAY,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Luminance Delay Compensation",
.minimum = SAA7191_LUMA_DELAY_MIN,
.maximum = SAA7191_LUMA_DELAY_MAX,
.step = 1,
.default_value = SAA7191_LUMA_DELAY_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_LUMA_DELAY, 0 },
- },{
- .id = V4L2_CID_PRIVATE_BASE + 7,
+ }, {
+ .id = SAA7191_CONTROL_VNR,
.type = V4L2_CTRL_TYPE_INTEGER,
.name = "Vertical Noise Reduction",
.minimum = SAA7191_VNR_MIN,
.maximum = SAA7191_VNR_MAX,
.step = 1,
.default_value = SAA7191_VNR_DEFAULT,
- .flags = 0,
- .reserved = { SAA7191_CONTROL_VNR, 0 },
}
};
-/* VINO I2C bus functions */
-
-unsigned i2c_vino_getctrl(void *data)
-{
- return vino->i2c_control;
-}
-
-void i2c_vino_setctrl(void *data, unsigned val)
-{
- vino->i2c_control = val;
-}
-
-unsigned i2c_vino_rdata(void *data)
-{
- return vino->i2c_data;
-}
-
-void i2c_vino_wdata(void *data, unsigned val)
-{
- vino->i2c_data = val;
-}
-
-static struct i2c_algo_sgi_data i2c_sgi_vino_data =
-{
- .getctrl = &i2c_vino_getctrl,
- .setctrl = &i2c_vino_setctrl,
- .rdata = &i2c_vino_rdata,
- .wdata = &i2c_vino_wdata,
- .xfer_timeout = 200,
- .ack_timeout = 1000,
-};
-
-/*
- * There are two possible clients on VINO I2C bus, so we limit usage only
- * to them.
- */
-static int i2c_vino_client_reg(struct i2c_client *client)
-{
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- switch (client->driver->id) {
- case I2C_DRIVERID_SAA7191:
- if (vino_drvdata->decoder.driver)
- ret = -EBUSY;
- else
- vino_drvdata->decoder.driver = client;
- break;
- case I2C_DRIVERID_INDYCAM:
- if (vino_drvdata->camera.driver)
- ret = -EBUSY;
- else
- vino_drvdata->camera.driver = client;
- break;
- default:
- ret = -ENODEV;
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return ret;
-}
-
-static int i2c_vino_client_unreg(struct i2c_client *client)
-{
- unsigned long flags;
- int ret = 0;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- if (client == vino_drvdata->decoder.driver) {
- if (vino_drvdata->decoder.owner != VINO_NO_CHANNEL)
- ret = -EBUSY;
- else
- vino_drvdata->decoder.driver = NULL;
- } else if (client == vino_drvdata->camera.driver) {
- if (vino_drvdata->camera.owner != VINO_NO_CHANNEL)
- ret = -EBUSY;
- else
- vino_drvdata->camera.driver = NULL;
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return ret;
-}
-
-static struct i2c_adapter vino_i2c_adapter =
-{
- .name = "VINO I2C bus",
- .id = I2C_HW_SGI_VINO,
- .algo_data = &i2c_sgi_vino_data,
- .client_register = &i2c_vino_client_reg,
- .client_unregister = &i2c_vino_client_unreg,
-};
-
-static int vino_i2c_add_bus(void)
-{
- return i2c_sgi_add_bus(&vino_i2c_adapter);
-}
-
-static int vino_i2c_del_bus(void)
-{
- return i2c_del_adapter(&vino_i2c_adapter);
-}
-
-static int i2c_camera_command(unsigned int cmd, void *arg)
-{
- return vino_drvdata->camera.driver->
- driver->command(vino_drvdata->camera.driver,
- cmd, arg);
-}
-
-static int i2c_decoder_command(unsigned int cmd, void *arg)
-{
- return vino_drvdata->decoder.driver->
- driver->command(vino_drvdata->decoder.driver,
- cmd, arg);
-}
-
/* VINO framebuffer/DMA descriptor management */
static void vino_free_buffer_with_count(struct vino_framebuffer *fb,
@@ -1741,6 +1604,184 @@ static inline void vino_set_default_framerate(struct
vino_set_framerate(vcs, vino_data_norms[vcs->data_norm].fps_max);
}
+/* VINO I2C bus functions */
+
+struct i2c_algo_sgi_data {
+ void *data; /* private data for lowlevel routines */
+ unsigned (*getctrl)(void *data);
+ void (*setctrl)(void *data, unsigned val);
+ unsigned (*rdata)(void *data);
+ void (*wdata)(void *data, unsigned val);
+
+ int xfer_timeout;
+ int ack_timeout;
+};
+
+static int wait_xfer_done(struct i2c_algo_sgi_data *adap)
+{
+ int i;
+
+ for (i = 0; i < adap->xfer_timeout; i++) {
+ if ((adap->getctrl(adap->data) & SGI_I2C_XFER_BUSY) == 0)
+ return 0;
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int wait_ack(struct i2c_algo_sgi_data *adap)
+{
+ int i;
+
+ if (wait_xfer_done(adap))
+ return -ETIMEDOUT;
+ for (i = 0; i < adap->ack_timeout; i++) {
+ if ((adap->getctrl(adap->data) & SGI_I2C_NACK) == 0)
+ return 0;
+ udelay(1);
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int force_idle(struct i2c_algo_sgi_data *adap)
+{
+ int i;
+
+ adap->setctrl(adap->data, SGI_I2C_FORCE_IDLE);
+ for (i = 0; i < adap->xfer_timeout; i++) {
+ if ((adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE) == 0)
+ goto out;
+ udelay(1);
+ }
+ return -ETIMEDOUT;
+out:
+ if (adap->getctrl(adap->data) & SGI_I2C_BUS_ERR)
+ return -EIO;
+ return 0;
+}
+
+static int do_address(struct i2c_algo_sgi_data *adap, unsigned int addr,
+ int rd)
+{
+ if (rd)
+ adap->setctrl(adap->data, SGI_I2C_NOT_IDLE);
+ /* Check if bus is idle, eventually force it to do so */
+ if (adap->getctrl(adap->data) & SGI_I2C_NOT_IDLE)
+ if (force_idle(adap))
+ return -EIO;
+ /* Write out the i2c chip address and specify operation */
+ adap->setctrl(adap->data,
+ SGI_I2C_HOLD_BUS | SGI_I2C_WRITE | SGI_I2C_NOT_IDLE);
+ if (rd)
+ addr |= 1;
+ adap->wdata(adap->data, addr);
+ if (wait_ack(adap))
+ return -EIO;
+ return 0;
+}
+
+static int i2c_read(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+ unsigned int len)
+{
+ int i;
+
+ adap->setctrl(adap->data,
+ SGI_I2C_HOLD_BUS | SGI_I2C_READ | SGI_I2C_NOT_IDLE);
+ for (i = 0; i < len; i++) {
+ if (wait_xfer_done(adap))
+ return -EIO;
+ buf[i] = adap->rdata(adap->data);
+ }
+ adap->setctrl(adap->data, SGI_I2C_RELEASE_BUS | SGI_I2C_FORCE_IDLE);
+
+ return 0;
+
+}
+
+static int i2c_write(struct i2c_algo_sgi_data *adap, unsigned char *buf,
+ unsigned int len)
+{
+ int i;
+
+ /* We are already in write state */
+ for (i = 0; i < len; i++) {
+ adap->wdata(adap->data, buf[i]);
+ if (wait_ack(adap))
+ return -EIO;
+ }
+ return 0;
+}
+
+static int sgi_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs,
+ int num)
+{
+ struct i2c_algo_sgi_data *adap = i2c_adap->algo_data;
+ struct i2c_msg *p;
+ int i, err = 0;
+
+ for (i = 0; !err && i < num; i++) {
+ p = &msgs[i];
+ err = do_address(adap, p->addr, p->flags & I2C_M_RD);
+ if (err || !p->len)
+ continue;
+ if (p->flags & I2C_M_RD)
+ err = i2c_read(adap, p->buf, p->len);
+ else
+ err = i2c_write(adap, p->buf, p->len);
+ }
+
+ return (err < 0) ? err : i;
+}
+
+static u32 sgi_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_SMBUS_EMUL;
+}
+
+static const struct i2c_algorithm sgi_algo = {
+ .master_xfer = sgi_xfer,
+ .functionality = sgi_func,
+};
+
+static unsigned i2c_vino_getctrl(void *data)
+{
+ return vino->i2c_control;
+}
+
+static void i2c_vino_setctrl(void *data, unsigned val)
+{
+ vino->i2c_control = val;
+}
+
+static unsigned i2c_vino_rdata(void *data)
+{
+ return vino->i2c_data;
+}
+
+static void i2c_vino_wdata(void *data, unsigned val)
+{
+ vino->i2c_data = val;
+}
+
+static struct i2c_algo_sgi_data i2c_sgi_vino_data = {
+ .getctrl = &i2c_vino_getctrl,
+ .setctrl = &i2c_vino_setctrl,
+ .rdata = &i2c_vino_rdata,
+ .wdata = &i2c_vino_wdata,
+ .xfer_timeout = 200,
+ .ack_timeout = 1000,
+};
+
+static struct i2c_adapter vino_i2c_adapter = {
+ .name = "VINO I2C bus",
+ .id = I2C_HW_SGI_VINO,
+ .algo = &sgi_algo,
+ .algo_data = &i2c_sgi_vino_data,
+ .owner = THIS_MODULE,
+};
+
/*
* Prepare VINO for DMA transfer...
* (execute only with vino_lock and input_lock locked)
@@ -2490,86 +2531,15 @@ static int vino_get_saa7191_input(int input)
}
}
-static int vino_get_saa7191_norm(unsigned int data_norm)
-{
- switch (data_norm) {
- case VINO_DATA_NORM_AUTO:
- return SAA7191_NORM_AUTO;
- case VINO_DATA_NORM_AUTO_EXT:
- return SAA7191_NORM_AUTO_EXT;
- case VINO_DATA_NORM_PAL:
- return SAA7191_NORM_PAL;
- case VINO_DATA_NORM_NTSC:
- return SAA7191_NORM_NTSC;
- case VINO_DATA_NORM_SECAM:
- return SAA7191_NORM_SECAM;
- default:
- printk(KERN_ERR "VINO: vino_get_saa7191_norm(): "
- "invalid norm!\n");
- return -1;
- }
-}
-
-static int vino_get_from_saa7191_norm(int saa7191_norm)
-{
- switch (saa7191_norm) {
- case SAA7191_NORM_PAL:
- return VINO_DATA_NORM_PAL;
- case SAA7191_NORM_NTSC:
- return VINO_DATA_NORM_NTSC;
- case SAA7191_NORM_SECAM:
- return VINO_DATA_NORM_SECAM;
- default:
- printk(KERN_ERR "VINO: vino_get_from_saa7191_norm(): "
- "invalid norm!\n");
- return VINO_DATA_NORM_NONE;
- }
-}
-
-static int vino_saa7191_set_norm(unsigned int *data_norm)
-{
- int saa7191_norm, new_data_norm;
- int err = 0;
-
- saa7191_norm = vino_get_saa7191_norm(*data_norm);
-
- err = i2c_decoder_command(DECODER_SAA7191_SET_NORM,
- &saa7191_norm);
- if (err)
- goto out;
-
- if ((*data_norm == VINO_DATA_NORM_AUTO)
- || (*data_norm == VINO_DATA_NORM_AUTO_EXT)) {
- struct saa7191_status status;
-
- err = i2c_decoder_command(DECODER_SAA7191_GET_STATUS,
- &status);
- if (err)
- goto out;
-
- new_data_norm =
- vino_get_from_saa7191_norm(status.norm);
- if (new_data_norm == VINO_DATA_NORM_NONE) {
- err = -EINVAL;
- goto out;
- }
-
- *data_norm = (unsigned int)new_data_norm;
- }
-
-out:
- return err;
-}
-
/* execute with input_lock locked */
static int vino_is_input_owner(struct vino_channel_settings *vcs)
{
switch(vcs->input) {
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO:
- return (vino_drvdata->decoder.owner == vcs->channel);
+ return vino_drvdata->decoder_owner == vcs->channel;
case VINO_INPUT_D1:
- return (vino_drvdata->camera.owner == vcs->channel);
+ return vino_drvdata->camera_owner == vcs->channel;
default:
return 0;
}
@@ -2585,23 +2555,22 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
/* First try D1 and then SAA7191 */
- if (vino_drvdata->camera.driver
- && (vino_drvdata->camera.owner == VINO_NO_CHANNEL)) {
- i2c_use_client(vino_drvdata->camera.driver);
- vino_drvdata->camera.owner = vcs->channel;
+ if (vino_drvdata->camera
+ && (vino_drvdata->camera_owner == VINO_NO_CHANNEL)) {
+ vino_drvdata->camera_owner = vcs->channel;
vcs->input = VINO_INPUT_D1;
vcs->data_norm = VINO_DATA_NORM_D1;
- } else if (vino_drvdata->decoder.driver
- && (vino_drvdata->decoder.owner == VINO_NO_CHANNEL)) {
- int input, data_norm;
- int saa7191_input;
+ } else if (vino_drvdata->decoder
+ && (vino_drvdata->decoder_owner == VINO_NO_CHANNEL)) {
+ int input;
+ int data_norm;
+ v4l2_std_id norm;
+ struct v4l2_routing route = { 0, 0 };
- i2c_use_client(vino_drvdata->decoder.driver);
input = VINO_INPUT_COMPOSITE;
- saa7191_input = vino_get_saa7191_input(input);
- ret = i2c_decoder_command(DECODER_SET_INPUT,
- &saa7191_input);
+ route.input = vino_get_saa7191_input(input);
+ ret = decoder_call(video, s_routing, &route);
if (ret) {
ret = -EINVAL;
goto out;
@@ -2612,12 +2581,15 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
/* Don't hold spinlocks while auto-detecting norm
* as it may take a while... */
- data_norm = VINO_DATA_NORM_AUTO_EXT;
-
- ret = vino_saa7191_set_norm(&data_norm);
- if ((ret == -EBUSY) || (ret == -EAGAIN)) {
- data_norm = VINO_DATA_NORM_PAL;
- ret = vino_saa7191_set_norm(&data_norm);
+ ret = decoder_call(video, querystd, &norm);
+ if (!ret) {
+ for (data_norm = 0; data_norm < 3; data_norm++) {
+ if (vino_data_norms[data_norm].std & norm)
+ break;
+ }
+ if (data_norm == 3)
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = decoder_call(tuner, s_std, norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -2627,7 +2599,7 @@ static int vino_acquire_input(struct vino_channel_settings *vcs)
goto out;
}
- vino_drvdata->decoder.owner = vcs->channel;
+ vino_drvdata->decoder_owner = vcs->channel;
vcs->input = input;
vcs->data_norm = data_norm;
@@ -2672,25 +2644,24 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
switch (input) {
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO:
- if (!vino_drvdata->decoder.driver) {
+ if (!vino_drvdata->decoder) {
ret = -EINVAL;
goto out;
}
- if (vino_drvdata->decoder.owner == VINO_NO_CHANNEL) {
- i2c_use_client(vino_drvdata->decoder.driver);
- vino_drvdata->decoder.owner = vcs->channel;
+ if (vino_drvdata->decoder_owner == VINO_NO_CHANNEL) {
+ vino_drvdata->decoder_owner = vcs->channel;
}
- if (vino_drvdata->decoder.owner == vcs->channel) {
+ if (vino_drvdata->decoder_owner == vcs->channel) {
int data_norm;
- int saa7191_input;
+ v4l2_std_id norm;
+ struct v4l2_routing route = { 0, 0 };
- saa7191_input = vino_get_saa7191_input(input);
- ret = i2c_decoder_command(DECODER_SET_INPUT,
- &saa7191_input);
+ route.input = vino_get_saa7191_input(input);
+ ret = decoder_call(video, s_routing, &route);
if (ret) {
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
ret = -EINVAL;
goto out;
}
@@ -2700,18 +2671,21 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
/* Don't hold spinlocks while auto-detecting norm
* as it may take a while... */
- data_norm = VINO_DATA_NORM_AUTO_EXT;
-
- ret = vino_saa7191_set_norm(&data_norm);
- if ((ret == -EBUSY) || (ret == -EAGAIN)) {
- data_norm = VINO_DATA_NORM_PAL;
- ret = vino_saa7191_set_norm(&data_norm);
+ ret = decoder_call(video, querystd, &norm);
+ if (!ret) {
+ for (data_norm = 0; data_norm < 3; data_norm++) {
+ if (vino_data_norms[data_norm].std & norm)
+ break;
+ }
+ if (data_norm == 3)
+ data_norm = VINO_DATA_NORM_PAL;
+ ret = decoder_call(tuner, s_std, norm);
}
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
if (ret) {
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
ret = -EINVAL;
goto out;
}
@@ -2728,37 +2702,31 @@ static int vino_set_input(struct vino_channel_settings *vcs, int input)
vcs->data_norm = vcs2->data_norm;
}
- if (vino_drvdata->camera.owner == vcs->channel) {
+ if (vino_drvdata->camera_owner == vcs->channel) {
/* Transfer the ownership or release the input */
if (vcs2->input == VINO_INPUT_D1) {
- vino_drvdata->camera.owner = vcs2->channel;
+ vino_drvdata->camera_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->
- camera.driver);
- vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+ vino_drvdata->camera_owner = VINO_NO_CHANNEL;
}
}
break;
case VINO_INPUT_D1:
- if (!vino_drvdata->camera.driver) {
+ if (!vino_drvdata->camera) {
ret = -EINVAL;
goto out;
}
- if (vino_drvdata->camera.owner == VINO_NO_CHANNEL) {
- i2c_use_client(vino_drvdata->camera.driver);
- vino_drvdata->camera.owner = vcs->channel;
- }
+ if (vino_drvdata->camera_owner == VINO_NO_CHANNEL)
+ vino_drvdata->camera_owner = vcs->channel;
- if (vino_drvdata->decoder.owner == vcs->channel) {
+ if (vino_drvdata->decoder_owner == vcs->channel) {
/* Transfer the ownership or release the input */
if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
(vcs2->input == VINO_INPUT_SVIDEO)) {
- vino_drvdata->decoder.owner = vcs2->channel;
+ vino_drvdata->decoder_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->
- decoder.driver);
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
}
}
@@ -2795,20 +2763,18 @@ static void vino_release_input(struct vino_channel_settings *vcs)
/* Release ownership of the channel
* and if the other channel takes input from
* the same source, transfer the ownership */
- if (vino_drvdata->camera.owner == vcs->channel) {
+ if (vino_drvdata->camera_owner == vcs->channel) {
if (vcs2->input == VINO_INPUT_D1) {
- vino_drvdata->camera.owner = vcs2->channel;
+ vino_drvdata->camera_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->camera.driver);
- vino_drvdata->camera.owner = VINO_NO_CHANNEL;
+ vino_drvdata->camera_owner = VINO_NO_CHANNEL;
}
- } else if (vino_drvdata->decoder.owner == vcs->channel) {
+ } else if (vino_drvdata->decoder_owner == vcs->channel) {
if ((vcs2->input == VINO_INPUT_COMPOSITE) ||
(vcs2->input == VINO_INPUT_SVIDEO)) {
- vino_drvdata->decoder.owner = vcs2->channel;
+ vino_drvdata->decoder_owner = vcs2->channel;
} else {
- i2c_release_client(vino_drvdata->decoder.driver);
- vino_drvdata->decoder.owner = VINO_NO_CHANNEL;
+ vino_drvdata->decoder_owner = VINO_NO_CHANNEL;
}
}
vcs->input = VINO_INPUT_NONE;
@@ -2829,18 +2795,16 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
switch (vcs->input) {
case VINO_INPUT_D1:
/* only one "norm" supported */
- if ((data_norm != VINO_DATA_NORM_D1)
- && (data_norm != VINO_DATA_NORM_AUTO)
- && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+ if (data_norm != VINO_DATA_NORM_D1)
return -EINVAL;
break;
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
+ v4l2_std_id norm;
+
if ((data_norm != VINO_DATA_NORM_PAL)
&& (data_norm != VINO_DATA_NORM_NTSC)
- && (data_norm != VINO_DATA_NORM_SECAM)
- && (data_norm != VINO_DATA_NORM_AUTO)
- && (data_norm != VINO_DATA_NORM_AUTO_EXT))
+ && (data_norm != VINO_DATA_NORM_SECAM))
return -EINVAL;
spin_unlock_irqrestore(&vino_drvdata->input_lock, *flags);
@@ -2848,7 +2812,8 @@ static int vino_set_data_norm(struct vino_channel_settings *vcs,
/* Don't hold spinlocks while setting norm
* as it may take a while... */
- err = vino_saa7191_set_norm(&data_norm);
+ norm = vino_data_norms[data_norm].std;
+ err = decoder_call(tuner, s_std, norm);
spin_lock_irqsave(&vino_drvdata->input_lock, *flags);
@@ -2884,41 +2849,13 @@ static int vino_find_data_format(__u32 pixelformat)
return VINO_DATA_FMT_NONE;
}
-static int vino_enum_data_norm(struct vino_channel_settings *vcs, __u32 index)
-{
- int data_norm = VINO_DATA_NORM_NONE;
- unsigned long flags;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- switch(vcs->input) {
- case VINO_INPUT_COMPOSITE:
- case VINO_INPUT_SVIDEO:
- if (index == 0) {
- data_norm = VINO_DATA_NORM_PAL;
- } else if (index == 1) {
- data_norm = VINO_DATA_NORM_NTSC;
- } else if (index == 2) {
- data_norm = VINO_DATA_NORM_SECAM;
- }
- break;
- case VINO_INPUT_D1:
- if (index == 0) {
- data_norm = VINO_DATA_NORM_D1;
- }
- break;
- }
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- return data_norm;
-}
-
-static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
+static int vino_int_enum_input(struct vino_channel_settings *vcs, __u32 index)
{
int input = VINO_INPUT_NONE;
unsigned long flags;
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+ if (vino_drvdata->decoder && vino_drvdata->camera) {
switch (index) {
case 0:
input = VINO_INPUT_COMPOSITE;
@@ -2930,7 +2867,7 @@ static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
input = VINO_INPUT_D1;
break;
}
- } else if (vino_drvdata->decoder.driver) {
+ } else if (vino_drvdata->decoder) {
switch (index) {
case 0:
input = VINO_INPUT_COMPOSITE;
@@ -2939,7 +2876,7 @@ static int vino_enum_input(struct vino_channel_settings *vcs, __u32 index)
input = VINO_INPUT_SVIDEO;
break;
}
- } else if (vino_drvdata->camera.driver) {
+ } else if (vino_drvdata->camera) {
switch (index) {
case 0:
input = VINO_INPUT_D1;
@@ -2957,7 +2894,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
__u32 index = 0;
// FIXME: detect when no inputs available
- if (vino_drvdata->decoder.driver && vino_drvdata->camera.driver) {
+ if (vino_drvdata->decoder && vino_drvdata->camera) {
switch (vcs->input) {
case VINO_INPUT_COMPOSITE:
index = 0;
@@ -2969,7 +2906,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
index = 2;
break;
}
- } else if (vino_drvdata->decoder.driver) {
+ } else if (vino_drvdata->decoder) {
switch (vcs->input) {
case VINO_INPUT_COMPOSITE:
index = 0;
@@ -2978,7 +2915,7 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
index = 1;
break;
}
- } else if (vino_drvdata->camera.driver) {
+ } else if (vino_drvdata->camera) {
switch (vcs->input) {
case VINO_INPUT_D1:
index = 0;
@@ -2991,7 +2928,8 @@ static __u32 vino_find_input_index(struct vino_channel_settings *vcs)
/* V4L2 ioctls */
-static void vino_v4l2_querycap(struct v4l2_capability *cap)
+static int vino_querycap(struct file *file, void *__fh,
+ struct v4l2_capability *cap)
{
memset(cap, 0, sizeof(struct v4l2_capability));
@@ -3003,16 +2941,18 @@ static void vino_v4l2_querycap(struct v4l2_capability *cap)
V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING;
// V4L2_CAP_OVERLAY, V4L2_CAP_READWRITE
+ return 0;
}
-static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
+static int vino_enum_input(struct file *file, void *__fh,
struct v4l2_input *i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
__u32 index = i->index;
int input;
dprintk("requested index = %d\n", index);
- input = vino_enum_input(vcs, index);
+ input = vino_int_enum_input(vcs, index);
if (input == VINO_INPUT_NONE)
return -EINVAL;
@@ -3023,20 +2963,15 @@ static int vino_v4l2_enuminput(struct vino_channel_settings *vcs,
i->std = vino_inputs[input].std;
strcpy(i->name, vino_inputs[input].name);
- if ((input == VINO_INPUT_COMPOSITE)
- || (input == VINO_INPUT_SVIDEO)) {
- struct saa7191_status status;
- i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
- i->status |= status.signal ? 0 : V4L2_IN_ST_NO_SIGNAL;
- i->status |= status.color ? 0 : V4L2_IN_ST_NO_COLOR;
- }
-
+ if (input == VINO_INPUT_COMPOSITE || input == VINO_INPUT_SVIDEO)
+ decoder_call(video, g_input_status, &i->status);
return 0;
}
-static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
+static int vino_g_input(struct file *file, void *__fh,
unsigned int *i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
__u32 index;
int input;
unsigned long flags;
@@ -3057,52 +2992,24 @@ static int vino_v4l2_g_input(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_s_input(struct vino_channel_settings *vcs,
- unsigned int *i)
+static int vino_s_input(struct file *file, void *__fh,
+ unsigned int i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
int input;
- dprintk("requested input = %d\n", *i);
+ dprintk("requested input = %d\n", i);
- input = vino_enum_input(vcs, *i);
+ input = vino_int_enum_input(vcs, i);
if (input == VINO_INPUT_NONE)
return -EINVAL;
return vino_set_input(vcs, input);
}
-static int vino_v4l2_enumstd(struct vino_channel_settings *vcs,
- struct v4l2_standard *s)
-{
- int index = s->index;
- int data_norm;
-
- data_norm = vino_enum_data_norm(vcs, index);
- dprintk("standard index = %d\n", index);
-
- if (data_norm == VINO_DATA_NORM_NONE)
- return -EINVAL;
-
- dprintk("standard name = %s\n",
- vino_data_norms[data_norm].description);
-
- memset(s, 0, sizeof(struct v4l2_standard));
- s->index = index;
-
- s->id = vino_data_norms[data_norm].std;
- s->frameperiod.numerator = 1;
- s->frameperiod.denominator =
- vino_data_norms[data_norm].fps_max;
- s->framelines =
- vino_data_norms[data_norm].framelines;
- strcpy(s->name,
- vino_data_norms[data_norm].description);
-
- return 0;
-}
-
-static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
+static int vino_querystd(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int err = 0;
@@ -3114,19 +3021,7 @@ static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
break;
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_status status;
-
- i2c_decoder_command(DECODER_SAA7191_GET_STATUS, &status);
-
- if (status.signal) {
- if (status.signal_60hz) {
- *std = V4L2_STD_NTSC;
- } else {
- *std = V4L2_STD_PAL | V4L2_STD_SECAM;
- }
- } else {
- *std = vino_inputs[vcs->input].std;
- }
+ decoder_call(video, querystd, std);
break;
}
default:
@@ -3138,9 +3033,10 @@ static int vino_v4l2_querystd(struct vino_channel_settings *vcs,
return err;
}
-static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
+static int vino_g_std(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
spin_lock_irqsave(&vino_drvdata->input_lock, flags);
@@ -3153,9 +3049,10 @@ static int vino_v4l2_g_std(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
+static int vino_s_std(struct file *file, void *__fh,
v4l2_std_id *std)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int ret = 0;
@@ -3176,12 +3073,7 @@ static int vino_v4l2_s_std(struct vino_channel_settings *vcs,
if (vcs->input == VINO_INPUT_D1)
goto out;
- if (((*std) & V4L2_STD_PAL)
- && ((*std) & V4L2_STD_NTSC)
- && ((*std) & V4L2_STD_SECAM)) {
- ret = vino_set_data_norm(vcs, VINO_DATA_NORM_AUTO_EXT,
- &flags);
- } else if ((*std) & V4L2_STD_PAL) {
+ if ((*std) & V4L2_STD_PAL) {
ret = vino_set_data_norm(vcs, VINO_DATA_NORM_PAL,
&flags);
} else if ((*std) & V4L2_STD_NTSC) {
@@ -3207,185 +3099,144 @@ out:
return ret;
}
-static int vino_v4l2_enum_fmt(struct vino_channel_settings *vcs,
+static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_fmtdesc *fd)
{
- enum v4l2_buf_type type = fd->type;
- int index = fd->index;
- dprintk("format index = %d\n", index);
+ dprintk("format index = %d\n", fd->index);
- switch (fd->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- if ((fd->index < 0) ||
- (fd->index >= VINO_DATA_FMT_COUNT))
- return -EINVAL;
- dprintk("format name = %s\n",
- vino_data_formats[index].description);
-
- memset(fd, 0, sizeof(struct v4l2_fmtdesc));
- fd->index = index;
- fd->type = type;
- fd->pixelformat = vino_data_formats[index].pixelformat;
- strcpy(fd->description, vino_data_formats[index].description);
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
+ if (fd->index >= VINO_DATA_FMT_COUNT)
return -EINVAL;
- }
+ dprintk("format name = %s\n", vino_data_formats[fd->index].description);
+ fd->pixelformat = vino_data_formats[fd->index].pixelformat;
+ strcpy(fd->description, vino_data_formats[fd->index].description);
return 0;
}
-static int vino_v4l2_try_fmt(struct vino_channel_settings *vcs,
+static int vino_try_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
struct vino_channel_settings tempvcs;
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- dprintk("requested: w = %d, h = %d\n",
- pf->width, pf->height);
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+ dprintk("requested: w = %d, h = %d\n",
+ pf->width, pf->height);
- tempvcs.data_format = vino_find_data_format(pf->pixelformat);
- if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
- tempvcs.data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[tempvcs.data_format].
- pixelformat;
- }
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ memcpy(&tempvcs, vcs, sizeof(struct vino_channel_settings));
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- /* data format must be set before clipping/scaling */
- vino_set_scaling(&tempvcs, pf->width, pf->height);
+ tempvcs.data_format = vino_find_data_format(pf->pixelformat);
+ if (tempvcs.data_format == VINO_DATA_FMT_NONE) {
+ tempvcs.data_format = VINO_DATA_FMT_GREY;
+ pf->pixelformat =
+ vino_data_formats[tempvcs.data_format].
+ pixelformat;
+ }
- dprintk("data format = %s\n",
- vino_data_formats[tempvcs.data_format].description);
+ /* data format must be set before clipping/scaling */
+ vino_set_scaling(&tempvcs, pf->width, pf->height);
- pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
- tempvcs.decimation;
- pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
+ dprintk("data format = %s\n",
+ vino_data_formats[tempvcs.data_format].description);
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = tempvcs.line_size;
- pf->sizeimage = tempvcs.line_size *
- (tempvcs.clipping.bottom - tempvcs.clipping.top) /
- tempvcs.decimation;
- pf->colorspace =
- vino_data_formats[tempvcs.data_format].colorspace;
+ pf->width = (tempvcs.clipping.right - tempvcs.clipping.left) /
+ tempvcs.decimation;
+ pf->height = (tempvcs.clipping.bottom - tempvcs.clipping.top) /
+ tempvcs.decimation;
- pf->priv = 0;
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = tempvcs.line_size;
+ pf->sizeimage = tempvcs.line_size *
+ (tempvcs.clipping.bottom - tempvcs.clipping.top) /
+ tempvcs.decimation;
+ pf->colorspace =
+ vino_data_formats[tempvcs.data_format].colorspace;
+ pf->priv = 0;
return 0;
}
-static int vino_v4l2_g_fmt(struct vino_channel_settings *vcs,
+static int vino_g_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- pf->width = (vcs->clipping.right - vcs->clipping.left) /
- vcs->decimation;
- pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].pixelformat;
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
+ pf->width = (vcs->clipping.right - vcs->clipping.left) /
+ vcs->decimation;
+ pf->height = (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->pixelformat =
+ vino_data_formats[vcs->data_format].pixelformat;
- pf->priv = 0;
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = vcs->line_size;
+ pf->sizeimage = vcs->line_size *
+ (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->colorspace =
+ vino_data_formats[vcs->data_format].colorspace;
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->priv = 0;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
-static int vino_v4l2_s_fmt(struct vino_channel_settings *vcs,
+static int vino_s_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_format *f)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
int data_format;
unsigned long flags;
+ struct v4l2_pix_format *pf = &f->fmt.pix;
- switch (f->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_pix_format *pf = &f->fmt.pix;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- data_format = vino_find_data_format(pf->pixelformat);
+ data_format = vino_find_data_format(pf->pixelformat);
- if (data_format == VINO_DATA_FMT_NONE) {
- vcs->data_format = VINO_DATA_FMT_GREY;
- pf->pixelformat =
- vino_data_formats[vcs->data_format].
- pixelformat;
- } else {
- vcs->data_format = data_format;
- }
+ if (data_format == VINO_DATA_FMT_NONE) {
+ vcs->data_format = VINO_DATA_FMT_GREY;
+ pf->pixelformat =
+ vino_data_formats[vcs->data_format].
+ pixelformat;
+ } else {
+ vcs->data_format = data_format;
+ }
- /* data format must be set before clipping/scaling */
- vino_set_scaling(vcs, pf->width, pf->height);
+ /* data format must be set before clipping/scaling */
+ vino_set_scaling(vcs, pf->width, pf->height);
- dprintk("data format = %s\n",
- vino_data_formats[vcs->data_format].description);
+ dprintk("data format = %s\n",
+ vino_data_formats[vcs->data_format].description);
- pf->width = vcs->clipping.right - vcs->clipping.left;
- pf->height = vcs->clipping.bottom - vcs->clipping.top;
+ pf->width = vcs->clipping.right - vcs->clipping.left;
+ pf->height = vcs->clipping.bottom - vcs->clipping.top;
- pf->field = V4L2_FIELD_INTERLACED;
- pf->bytesperline = vcs->line_size;
- pf->sizeimage = vcs->line_size *
- (vcs->clipping.bottom - vcs->clipping.top) /
- vcs->decimation;
- pf->colorspace =
- vino_data_formats[vcs->data_format].colorspace;
+ pf->field = V4L2_FIELD_INTERLACED;
+ pf->bytesperline = vcs->line_size;
+ pf->sizeimage = vcs->line_size *
+ (vcs->clipping.bottom - vcs->clipping.top) /
+ vcs->decimation;
+ pf->colorspace =
+ vino_data_formats[vcs->data_format].colorspace;
- pf->priv = 0;
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ pf->priv = 0;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
return 0;
}
-static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
+static int vino_cropcap(struct file *file, void *__fh,
struct v4l2_cropcap *ccap)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
const struct vino_data_norm *norm;
unsigned long flags;
@@ -3415,9 +3266,10 @@ static int vino_v4l2_cropcap(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
+static int vino_g_crop(struct file *file, void *__fh,
struct v4l2_crop *c)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (c->type) {
@@ -3439,9 +3291,10 @@ static int vino_v4l2_g_crop(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
+static int vino_s_crop(struct file *file, void *__fh,
struct v4l2_crop *c)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
switch (c->type) {
@@ -3461,108 +3314,83 @@ static int vino_v4l2_s_crop(struct vino_channel_settings *vcs,
return 0;
}
-static int vino_v4l2_g_parm(struct vino_channel_settings *vcs,
+static int vino_g_parm(struct file *file, void *__fh,
struct v4l2_streamparm *sp)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
- switch (sp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_captureparm *cp = &sp->parm.capture;
- memset(cp, 0, sizeof(struct v4l2_captureparm));
+ cp->capability = V4L2_CAP_TIMEPERFRAME;
+ cp->timeperframe.numerator = 1;
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = 1;
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ cp->timeperframe.denominator = vcs->fps;
- cp->timeperframe.denominator = vcs->fps;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- // TODO: cp->readbuffers = xxx;
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ /* TODO: cp->readbuffers = xxx; */
return 0;
}
-static int vino_v4l2_s_parm(struct vino_channel_settings *vcs,
+static int vino_s_parm(struct file *file, void *__fh,
struct v4l2_streamparm *sp)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
- switch (sp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_captureparm *cp = &sp->parm.capture;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if ((cp->timeperframe.numerator == 0) ||
- (cp->timeperframe.denominator == 0)) {
- /* reset framerate */
- vino_set_default_framerate(vcs);
- } else {
- vino_set_framerate(vcs, cp->timeperframe.denominator /
- cp->timeperframe.numerator);
- }
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- // TODO: set buffers according to cp->readbuffers
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ if ((cp->timeperframe.numerator == 0) ||
+ (cp->timeperframe.denominator == 0)) {
+ /* reset framerate */
+ vino_set_default_framerate(vcs);
+ } else {
+ vino_set_framerate(vcs, cp->timeperframe.denominator /
+ cp->timeperframe.numerator);
}
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+
return 0;
}
-static int vino_v4l2_reqbufs(struct vino_channel_settings *vcs,
+static int vino_reqbufs(struct file *file, void *__fh,
struct v4l2_requestbuffers *rb)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+
if (vcs->reading)
return -EBUSY;
- switch (rb->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- // TODO: check queue type
- if (rb->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
+ /* TODO: check queue type */
+ if (rb->memory != V4L2_MEMORY_MMAP) {
+ dprintk("type not mmap\n");
+ return -EINVAL;
+ }
- dprintk("count = %d\n", rb->count);
- if (rb->count > 0) {
- if (vino_is_capturing(vcs)) {
- dprintk("busy, capturing\n");
- return -EBUSY;
- }
+ dprintk("count = %d\n", rb->count);
+ if (rb->count > 0) {
+ if (vino_is_capturing(vcs)) {
+ dprintk("busy, capturing\n");
+ return -EBUSY;
+ }
- if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
- dprintk("busy, buffers still mapped\n");
- return -EBUSY;
- } else {
- vcs->streaming = 0;
- vino_queue_free(&vcs->fb_queue);
- vino_queue_init(&vcs->fb_queue, &rb->count);
- }
+ if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
+ dprintk("busy, buffers still mapped\n");
+ return -EBUSY;
} else {
vcs->streaming = 0;
- vino_capture_stop(vcs);
vino_queue_free(&vcs->fb_queue);
+ vino_queue_init(&vcs->fb_queue, &rb->count);
}
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ } else {
+ vcs->streaming = 0;
+ vino_capture_stop(vcs);
+ vino_queue_free(&vcs->fb_queue);
}
return 0;
@@ -3606,156 +3434,135 @@ static void vino_v4l2_get_buffer_status(struct vino_channel_settings *vcs,
fb->id, fb->size, fb->data_size, fb->offset);
}
-static int vino_v4l2_querybuf(struct vino_channel_settings *vcs,
+static int vino_querybuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+ struct vino_framebuffer *fb;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
-
- // TODO: check queue type
- if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
- dprintk("invalid index = %d\n",
- b->index);
- return -EINVAL;
- }
-
- fb = vino_queue_get_buffer(&vcs->fb_queue,
- b->index);
- if (fb == NULL) {
- dprintk("vino_queue_get_buffer() failed");
- return -EINVAL;
- }
-
- vino_v4l2_get_buffer_status(vcs, fb, b);
- break;
+ /* TODO: check queue type */
+ if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
+ dprintk("invalid index = %d\n",
+ b->index);
+ return -EINVAL;
}
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
+
+ fb = vino_queue_get_buffer(&vcs->fb_queue,
+ b->index);
+ if (fb == NULL) {
+ dprintk("vino_queue_get_buffer() failed");
return -EINVAL;
}
+ vino_v4l2_get_buffer_status(vcs, fb, b);
+
return 0;
}
-static int vino_v4l2_qbuf(struct vino_channel_settings *vcs,
+static int vino_qbuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+ struct vino_framebuffer *fb;
+ int ret;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
- int ret;
-
- // TODO: check queue type
- if (b->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
+ /* TODO: check queue type */
+ if (b->memory != V4L2_MEMORY_MMAP) {
+ dprintk("type not mmap\n");
+ return -EINVAL;
+ }
- fb = vino_capture_enqueue(vcs, b->index);
- if (fb == NULL)
- return -EINVAL;
+ fb = vino_capture_enqueue(vcs, b->index);
+ if (fb == NULL)
+ return -EINVAL;
- vino_v4l2_get_buffer_status(vcs, fb, b);
+ vino_v4l2_get_buffer_status(vcs, fb, b);
- if (vcs->streaming) {
- ret = vino_capture_next(vcs, 1);
- if (ret)
- return ret;
- }
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ if (vcs->streaming) {
+ ret = vino_capture_next(vcs, 1);
+ if (ret)
+ return ret;
}
return 0;
}
-static int vino_v4l2_dqbuf(struct vino_channel_settings *vcs,
- struct v4l2_buffer *b,
- unsigned int nonblocking)
+static int vino_dqbuf(struct file *file, void *__fh,
+ struct v4l2_buffer *b)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
+ unsigned int nonblocking = file->f_flags & O_NONBLOCK;
+ struct vino_framebuffer *fb;
+ unsigned int incoming, outgoing;
+ int err;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
- unsigned int incoming, outgoing;
- int err;
+ /* TODO: check queue type */
- // TODO: check queue type
+ err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
+ if (err) {
+ dprintk("vino_queue_get_incoming() failed\n");
+ return -EINVAL;
+ }
+ err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
+ if (err) {
+ dprintk("vino_queue_get_outgoing() failed\n");
+ return -EINVAL;
+ }
- err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
- if (err) {
- dprintk("vino_queue_get_incoming() failed\n");
+ dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
+
+ if (outgoing == 0) {
+ if (incoming == 0) {
+ dprintk("no incoming or outgoing buffers\n");
return -EINVAL;
}
- err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
- if (err) {
- dprintk("vino_queue_get_outgoing() failed\n");
- return -EINVAL;
+ if (nonblocking) {
+ dprintk("non-blocking I/O was selected and "
+ "there are no buffers to dequeue\n");
+ return -EAGAIN;
}
- dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
-
- if (outgoing == 0) {
- if (incoming == 0) {
- dprintk("no incoming or outgoing buffers\n");
- return -EINVAL;
- }
- if (nonblocking) {
- dprintk("non-blocking I/O was selected and "
- "there are no buffers to dequeue\n");
- return -EAGAIN;
- }
-
+ err = vino_wait_for_frame(vcs);
+ if (err) {
err = vino_wait_for_frame(vcs);
if (err) {
- err = vino_wait_for_frame(vcs);
- if (err) {
- /* interrupted or
- * no frames captured because
- * of frame skipping */
- // vino_capture_failed(vcs);
- return -EIO;
- }
+ /* interrupted or no frames captured because of
+ * frame skipping */
+ /* vino_capture_failed(vcs); */
+ return -EIO;
}
}
+ }
- fb = vino_queue_remove(&vcs->fb_queue, &b->index);
- if (fb == NULL) {
- dprintk("vino_queue_remove() failed\n");
- return -EINVAL;
- }
-
- err = vino_check_buffer(vcs, fb);
+ fb = vino_queue_remove(&vcs->fb_queue, &b->index);
+ if (fb == NULL) {
+ dprintk("vino_queue_remove() failed\n");
+ return -EINVAL;
+ }
- vino_v4l2_get_buffer_status(vcs, fb, b);
+ err = vino_check_buffer(vcs, fb);
- if (err)
- return -EIO;
+ vino_v4l2_get_buffer_status(vcs, fb, b);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ if (err)
+ return -EIO;
return 0;
}
-static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
+static int vino_streamon(struct file *file, void *__fh,
+ enum v4l2_buf_type i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned int incoming;
int ret;
if (vcs->reading)
@@ -3792,8 +3599,10 @@ static int vino_v4l2_streamon(struct vino_channel_settings *vcs)
return 0;
}
-static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
+static int vino_streamoff(struct file *file, void *__fh,
+ enum v4l2_buf_type i)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
if (vcs->reading)
return -EBUSY;
@@ -3806,9 +3615,10 @@ static int vino_v4l2_streamoff(struct vino_channel_settings *vcs)
return 0;
}
-static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
+static int vino_queryctrl(struct file *file, void *__fh,
struct v4l2_queryctrl *queryctrl)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
@@ -3855,9 +3665,10 @@ static int vino_v4l2_queryctrl(struct vino_channel_settings *vcs,
return err;
}
-static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
+static int vino_g_ctrl(struct file *file, void *__fh,
struct v4l2_control *control)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
@@ -3866,56 +3677,38 @@ static int vino_v4l2_g_ctrl(struct vino_channel_settings *vcs,
switch (vcs->input) {
case VINO_INPUT_D1: {
- struct indycam_control indycam_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id ==
- control->id) {
- goto found1;
+ if (vino_indycam_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found1:
- indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
-
- err = i2c_camera_command(DECODER_INDYCAM_GET_CONTROL,
- &indycam_ctrl);
- if (err) {
- err = -EINVAL;
+ if (err)
goto out;
- }
- control->value = indycam_ctrl.value;
+ err = camera_call(core, g_ctrl, control);
+ if (err)
+ err = -EINVAL;
break;
}
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_control saa7191_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id ==
- control->id) {
- goto found2;
+ if (vino_saa7191_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found2:
- saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
-
- err = i2c_decoder_command(DECODER_SAA7191_GET_CONTROL,
- &saa7191_ctrl);
- if (err) {
- err = -EINVAL;
+ if (err)
goto out;
- }
- control->value = saa7191_ctrl.value;
+ err = decoder_call(core, g_ctrl, control);
+ if (err)
+ err = -EINVAL;
break;
}
default:
@@ -3928,9 +3721,10 @@ out:
return err;
}
-static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
+static int vino_s_ctrl(struct file *file, void *__fh,
struct v4l2_control *control)
{
+ struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
int i;
int err = 0;
@@ -3944,65 +3738,43 @@ static int vino_v4l2_s_ctrl(struct vino_channel_settings *vcs,
switch (vcs->input) {
case VINO_INPUT_D1: {
- struct indycam_control indycam_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_INDYCAM_V4L2_CONTROL_COUNT; i++) {
- if (vino_indycam_v4l2_controls[i].id ==
- control->id) {
- if ((control->value >=
- vino_indycam_v4l2_controls[i].minimum)
- && (control->value <=
- vino_indycam_v4l2_controls[i].
- maximum)) {
- goto found1;
- } else {
- err = -ERANGE;
- goto out;
- }
+ if (vino_indycam_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
-
- err = -EINVAL;
- goto out;
-
-found1:
- indycam_ctrl.type = vino_indycam_v4l2_controls[i].reserved[0];
- indycam_ctrl.value = control->value;
-
- err = i2c_camera_command(DECODER_INDYCAM_SET_CONTROL,
- &indycam_ctrl);
+ if (err)
+ goto out;
+ if (control->value < vino_indycam_v4l2_controls[i].minimum ||
+ control->value > vino_indycam_v4l2_controls[i].maximum) {
+ err = -ERANGE;
+ goto out;
+ }
+ err = camera_call(core, s_ctrl, control);
if (err)
err = -EINVAL;
break;
}
case VINO_INPUT_COMPOSITE:
case VINO_INPUT_SVIDEO: {
- struct saa7191_control saa7191_ctrl;
-
+ err = -EINVAL;
for (i = 0; i < VINO_SAA7191_V4L2_CONTROL_COUNT; i++) {
- if (vino_saa7191_v4l2_controls[i].id ==
- control->id) {
- if ((control->value >=
- vino_saa7191_v4l2_controls[i].minimum)
- && (control->value <=
- vino_saa7191_v4l2_controls[i].
- maximum)) {
- goto found2;
- } else {
- err = -ERANGE;
- goto out;
- }
+ if (vino_saa7191_v4l2_controls[i].id == control->id) {
+ err = 0;
+ break;
}
}
- err = -EINVAL;
- goto out;
-
-found2:
- saa7191_ctrl.type = vino_saa7191_v4l2_controls[i].reserved[0];
- saa7191_ctrl.value = control->value;
+ if (err)
+ goto out;
+ if (control->value < vino_saa7191_v4l2_controls[i].minimum ||
+ control->value > vino_saa7191_v4l2_controls[i].maximum) {
+ err = -ERANGE;
+ goto out;
+ }
- err = i2c_decoder_command(DECODER_SAA7191_SET_CONTROL,
- &saa7191_ctrl);
+ err = decoder_call(core, s_ctrl, control);
if (err)
err = -EINVAL;
break;
@@ -4233,116 +4005,9 @@ over:
ret = POLLIN | POLLRDNORM;
error:
-
return ret;
}
-static long vino_do_ioctl(struct file *file, unsigned int cmd, void *arg)
-{
- struct vino_channel_settings *vcs = video_drvdata(file);
-
-#ifdef VINO_DEBUG
- switch (_IOC_TYPE(cmd)) {
- case 'v':
- dprintk("ioctl(): V4L1 unsupported (0x%08x)\n", cmd);
- break;
- case 'V':
- dprintk("ioctl(): V4L2 %s (0x%08x)\n",
- v4l2_ioctl_names[_IOC_NR(cmd)], cmd);
- break;
- default:
- dprintk("ioctl(): unsupported command 0x%08x\n", cmd);
- }
-#endif
-
- switch (cmd) {
- /* V4L2 interface */
- case VIDIOC_QUERYCAP: {
- vino_v4l2_querycap(arg);
- break;
- }
- case VIDIOC_ENUMINPUT: {
- return vino_v4l2_enuminput(vcs, arg);
- }
- case VIDIOC_G_INPUT: {
- return vino_v4l2_g_input(vcs, arg);
- }
- case VIDIOC_S_INPUT: {
- return vino_v4l2_s_input(vcs, arg);
- }
- case VIDIOC_ENUMSTD: {
- return vino_v4l2_enumstd(vcs, arg);
- }
- case VIDIOC_QUERYSTD: {
- return vino_v4l2_querystd(vcs, arg);
- }
- case VIDIOC_G_STD: {
- return vino_v4l2_g_std(vcs, arg);
- }
- case VIDIOC_S_STD: {
- return vino_v4l2_s_std(vcs, arg);
- }
- case VIDIOC_ENUM_FMT: {
- return vino_v4l2_enum_fmt(vcs, arg);
- }
- case VIDIOC_TRY_FMT: {
- return vino_v4l2_try_fmt(vcs, arg);
- }
- case VIDIOC_G_FMT: {
- return vino_v4l2_g_fmt(vcs, arg);
- }
- case VIDIOC_S_FMT: {
- return vino_v4l2_s_fmt(vcs, arg);
- }
- case VIDIOC_CROPCAP: {
- return vino_v4l2_cropcap(vcs, arg);
- }
- case VIDIOC_G_CROP: {
- return vino_v4l2_g_crop(vcs, arg);
- }
- case VIDIOC_S_CROP: {
- return vino_v4l2_s_crop(vcs, arg);
- }
- case VIDIOC_G_PARM: {
- return vino_v4l2_g_parm(vcs, arg);
- }
- case VIDIOC_S_PARM: {
- return vino_v4l2_s_parm(vcs, arg);
- }
- case VIDIOC_REQBUFS: {
- return vino_v4l2_reqbufs(vcs, arg);
- }
- case VIDIOC_QUERYBUF: {
- return vino_v4l2_querybuf(vcs, arg);
- }
- case VIDIOC_QBUF: {
- return vino_v4l2_qbuf(vcs, arg);
- }
- case VIDIOC_DQBUF: {
- return vino_v4l2_dqbuf(vcs, arg, file->f_flags & O_NONBLOCK);
- }
- case VIDIOC_STREAMON: {
- return vino_v4l2_streamon(vcs);
- }
- case VIDIOC_STREAMOFF: {
- return vino_v4l2_streamoff(vcs);
- }
- case VIDIOC_QUERYCTRL: {
- return vino_v4l2_queryctrl(vcs, arg);
- }
- case VIDIOC_G_CTRL: {
- return vino_v4l2_g_ctrl(vcs, arg);
- }
- case VIDIOC_S_CTRL: {
- return vino_v4l2_s_ctrl(vcs, arg);
- }
- default:
- return -ENOIOCTLCMD;
- }
-
- return 0;
-}
-
static long vino_ioctl(struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -4352,7 +4017,7 @@ static long vino_ioctl(struct file *file,
if (mutex_lock_interruptible(&vcs->mutex))
return -EINTR;
- ret = video_usercopy(file, cmd, arg, vino_do_ioctl);
+ ret = video_ioctl2(file, cmd, arg);
mutex_unlock(&vcs->mutex);
@@ -4364,45 +4029,75 @@ static long vino_ioctl(struct file *file,
/* __initdata */
static int vino_init_stage;
+const struct v4l2_ioctl_ops vino_ioctl_ops = {
+ .vidioc_enum_fmt_vid_cap = vino_enum_fmt_vid_cap,
+ .vidioc_g_fmt_vid_cap = vino_g_fmt_vid_cap,
+ .vidioc_s_fmt_vid_cap = vino_s_fmt_vid_cap,
+ .vidioc_try_fmt_vid_cap = vino_try_fmt_vid_cap,
+ .vidioc_querycap = vino_querycap,
+ .vidioc_enum_input = vino_enum_input,
+ .vidioc_g_input = vino_g_input,
+ .vidioc_s_input = vino_s_input,
+ .vidioc_g_std = vino_g_std,
+ .vidioc_s_std = vino_s_std,
+ .vidioc_querystd = vino_querystd,
+ .vidioc_cropcap = vino_cropcap,
+ .vidioc_s_crop = vino_s_crop,
+ .vidioc_g_crop = vino_g_crop,
+ .vidioc_s_parm = vino_s_parm,
+ .vidioc_g_parm = vino_g_parm,
+ .vidioc_reqbufs = vino_reqbufs,
+ .vidioc_querybuf = vino_querybuf,
+ .vidioc_qbuf = vino_qbuf,
+ .vidioc_dqbuf = vino_dqbuf,
+ .vidioc_streamon = vino_streamon,
+ .vidioc_streamoff = vino_streamoff,
+ .vidioc_queryctrl = vino_queryctrl,
+ .vidioc_g_ctrl = vino_g_ctrl,
+ .vidioc_s_ctrl = vino_s_ctrl,
+};
+
static const struct v4l2_file_operations vino_fops = {
.owner = THIS_MODULE,
.open = vino_open,
.release = vino_close,
- .ioctl = vino_ioctl,
+ .unlocked_ioctl = vino_ioctl,
.mmap = vino_mmap,
.poll = vino_poll,
};
-static struct video_device v4l_device_template = {
+static struct video_device vdev_template = {
.name = "NOT SET",
.fops = &vino_fops,
+ .ioctl_ops = &vino_ioctl_ops,
+ .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
.minor = -1,
};
static void vino_module_cleanup(int stage)
{
switch(stage) {
+ case 11:
+ video_unregister_device(vino_drvdata->b.vdev);
+ vino_drvdata->b.vdev = NULL;
case 10:
- video_unregister_device(vino_drvdata->b.v4l_device);
- vino_drvdata->b.v4l_device = NULL;
+ video_unregister_device(vino_drvdata->a.vdev);
+ vino_drvdata->a.vdev = NULL;
case 9:
- video_unregister_device(vino_drvdata->a.v4l_device);
- vino_drvdata->a.v4l_device = NULL;
+ i2c_del_adapter(&vino_i2c_adapter);
case 8:
- vino_i2c_del_bus();
- case 7:
free_irq(SGI_VINO_IRQ, NULL);
+ case 7:
+ if (vino_drvdata->b.vdev) {
+ video_device_release(vino_drvdata->b.vdev);
+ vino_drvdata->b.vdev = NULL;
+ }
case 6:
- if (vino_drvdata->b.v4l_device) {
- video_device_release(vino_drvdata->b.v4l_device);
- vino_drvdata->b.v4l_device = NULL;
+ if (vino_drvdata->a.vdev) {
+ video_device_release(vino_drvdata->a.vdev);
+ vino_drvdata->a.vdev = NULL;
}
case 5:
- if (vino_drvdata->a.v4l_device) {
- video_device_release(vino_drvdata->a.v4l_device);
- vino_drvdata->a.v4l_device = NULL;
- }
- case 4:
/* all entries in dma_cpu dummy table have the same address */
dma_unmap_single(NULL,
vino_drvdata->dummy_desc_table.dma_cpu[0],
@@ -4412,8 +4107,10 @@ static void vino_module_cleanup(int stage)
(void *)vino_drvdata->
dummy_desc_table.dma_cpu,
vino_drvdata->dummy_desc_table.dma);
- case 3:
+ case 4:
free_page(vino_drvdata->dummy_page);
+ case 3:
+ v4l2_device_unregister(&vino_drvdata->v4l2_dev);
case 2:
kfree(vino_drvdata);
case 1:
@@ -4468,6 +4165,7 @@ static int vino_probe(void)
static int vino_init(void)
{
dma_addr_t dma_dummy_address;
+ int err;
int i;
vino_drvdata = kzalloc(sizeof(struct vino_settings), GFP_KERNEL);
@@ -4476,6 +4174,12 @@ static int vino_init(void)
return -ENOMEM;
}
vino_init_stage++;
+ strlcpy(vino_drvdata->v4l2_dev.name, "vino",
+ sizeof(vino_drvdata->v4l2_dev.name));
+ err = v4l2_device_register(NULL, &vino_drvdata->v4l2_dev);
+ if (err)
+ return err;
+ vino_init_stage++;
/* create a dummy dma descriptor */
vino_drvdata->dummy_page = get_zeroed_page(GFP_KERNEL | GFP_DMA);
@@ -4542,25 +4246,27 @@ static int vino_init_channel_settings(struct vino_channel_settings *vcs,
spin_lock_init(&vcs->fb_queue.queue_lock);
init_waitqueue_head(&vcs->fb_queue.frame_wait_queue);
- vcs->v4l_device = video_device_alloc();
- if (!vcs->v4l_device) {
+ vcs->vdev = video_device_alloc();
+ if (!vcs->vdev) {
vino_module_cleanup(vino_init_stage);
return -ENOMEM;
}
vino_init_stage++;
- memcpy(vcs->v4l_device, &v4l_device_template,
+ memcpy(vcs->vdev, &vdev_template,
sizeof(struct video_device));
- strcpy(vcs->v4l_device->name, name);
- vcs->v4l_device->release = video_device_release;
+ strcpy(vcs->vdev->name, name);
+ vcs->vdev->release = video_device_release;
+ vcs->vdev->v4l2_dev = &vino_drvdata->v4l2_dev;
- video_set_drvdata(vcs->v4l_device, vcs);
+ video_set_drvdata(vcs->vdev, vcs);
return 0;
}
static int __init vino_module_init(void)
{
+ unsigned short addr[] = { 0, I2C_CLIENT_END };
int ret;
printk(KERN_INFO "SGI VINO driver version %s\n",
@@ -4580,12 +4286,12 @@ static int __init vino_module_init(void)
spin_lock_init(&vino_drvdata->input_lock);
ret = vino_init_channel_settings(&vino_drvdata->a, VINO_CHANNEL_A,
- vino_v4l_device_name_a);
+ vino_vdev_name_a);
if (ret)
return ret;
ret = vino_init_channel_settings(&vino_drvdata->b, VINO_CHANNEL_B,
- vino_v4l_device_name_b);
+ vino_vdev_name_b);
if (ret)
return ret;
@@ -4601,15 +4307,16 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
- ret = vino_i2c_add_bus();
+ ret = i2c_add_adapter(&vino_i2c_adapter);
if (ret) {
printk(KERN_ERR "VINO I2C bus registration failed\n");
vino_module_cleanup(vino_init_stage);
return ret;
}
+ i2c_set_adapdata(&vino_i2c_adapter, &vino_drvdata->v4l2_dev);
vino_init_stage++;
- ret = video_register_device(vino_drvdata->a.v4l_device,
+ ret = video_register_device(vino_drvdata->a.vdev,
VFL_TYPE_GRABBER, -1);
if (ret < 0) {
printk(KERN_ERR "VINO channel A Video4Linux-device "
@@ -4619,7 +4326,7 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
- ret = video_register_device(vino_drvdata->b.v4l_device,
+ ret = video_register_device(vino_drvdata->b.vdev,
VFL_TYPE_GRABBER, -1);
if (ret < 0) {
printk(KERN_ERR "VINO channel B Video4Linux-device "
@@ -4629,10 +4336,12 @@ static int __init vino_module_init(void)
}
vino_init_stage++;
-#ifdef MODULE
- request_module("saa7191");
- request_module("indycam");
-#endif
+ addr[0] = 0x45;
+ vino_drvdata->decoder = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
+ "saa7191", "saa7191", addr);
+ addr[0] = 0x2b;
+ vino_drvdata->camera = v4l2_i2c_new_probed_subdev(&vino_i2c_adapter,
+ "indycam", "indycam", addr);
dprintk("init complete!\n");
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 81d5aa5cf33..fbfefae7886 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -28,17 +28,14 @@
#include <linux/mutex.h>
#include <linux/videodev2.h>
#include <linux/dma-mapping.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
-/* Include V4L1 specific functions. Should be removed soon */
-#include <linux/videodev.h>
-#endif
#include <linux/interrupt.h>
-#include <media/videobuf-vmalloc.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
#include <linux/kthread.h>
#include <linux/highmem.h>
#include <linux/freezer.h>
+#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
+#include "font.h"
#define VIVI_MODULE_NAME "vivi"
@@ -47,18 +44,32 @@
#define WAKE_DENOMINATOR 1001
#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
-#include "font.h"
-
#define VIVI_MAJOR_VERSION 0
-#define VIVI_MINOR_VERSION 5
+#define VIVI_MINOR_VERSION 6
#define VIVI_RELEASE 0
#define VIVI_VERSION \
KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
-/* Declare static vars that will be used as parameters */
-static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
-static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
-static int n_devs = 1; /* Number of virtual devices */
+MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
+MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
+MODULE_LICENSE("Dual BSD/GPL");
+
+static unsigned video_nr = -1;
+module_param(video_nr, uint, 0644);
+MODULE_PARM_DESC(video_nr, "videoX start number, -1 is autodetect");
+
+static unsigned n_devs = 1;
+module_param(n_devs, uint, 0644);
+MODULE_PARM_DESC(n_devs, "number of video devices to create");
+
+static unsigned debug;
+module_param(debug, uint, 0644);
+MODULE_PARM_DESC(debug, "activates debug info");
+
+static unsigned int vid_limit = 16;
+module_param(vid_limit, uint, 0644);
+MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
+
/* supported controls */
static struct v4l2_queryctrl vivi_qctrl[] = {
@@ -69,7 +80,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 65535,
.step = 65535/100,
.default_value = 65535,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
.type = V4L2_CTRL_TYPE_INTEGER,
}, {
.id = V4L2_CID_BRIGHTNESS,
@@ -79,7 +90,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 255,
.step = 1,
.default_value = 127,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}, {
.id = V4L2_CID_CONTRAST,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -88,7 +99,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 255,
.step = 0x1,
.default_value = 0x10,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}, {
.id = V4L2_CID_SATURATION,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -97,7 +108,7 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 255,
.step = 0x1,
.default_value = 127,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}, {
.id = V4L2_CID_HUE,
.type = V4L2_CTRL_TYPE_INTEGER,
@@ -106,17 +117,12 @@ static struct v4l2_queryctrl vivi_qctrl[] = {
.maximum = 127,
.step = 0x1,
.default_value = 0,
- .flags = 0,
+ .flags = V4L2_CTRL_FLAG_SLIDER,
}
};
-static int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
-
-#define dprintk(dev, level, fmt, arg...) \
- do { \
- if (dev->vfd->debug >= (level)) \
- printk(KERN_DEBUG "vivi: " fmt , ## arg); \
- } while (0)
+#define dprintk(dev, level, fmt, arg...) \
+ v4l2_dbg(level, debug, &dev->v4l2_dev, fmt, ## arg)
/* ------------------------------------------------------------------
Basic structures
@@ -206,6 +212,7 @@ static LIST_HEAD(vivi_devlist);
struct vivi_dev {
struct list_head vivi_devlist;
+ struct v4l2_device v4l2_dev;
spinlock_t slock;
struct mutex mutex;
@@ -223,6 +230,12 @@ struct vivi_dev {
char timestr[13];
int mv_count; /* Controls bars movement */
+
+ /* Input Number */
+ int input;
+
+ /* Control 'registers' */
+ int qctl_regs[ARRAY_SIZE(vivi_qctrl)];
};
struct vivi_fh {
@@ -235,6 +248,7 @@ struct vivi_fh {
enum v4l2_buf_type type;
unsigned char bars[8][3];
+ int input; /* Input Number on bars */
};
/* ------------------------------------------------------------------
@@ -254,18 +268,72 @@ enum colors {
BLACK,
};
-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}, /* black */
+#define COLOR_WHITE {204, 204, 204}
+#define COLOR_AMBAR {208, 208, 0}
+#define COLOR_CIAN { 0, 206, 206}
+#define COLOR_GREEN { 0, 239, 0}
+#define COLOR_MAGENTA {239, 0, 239}
+#define COLOR_RED {205, 0, 0}
+#define COLOR_BLUE { 0, 0, 255}
+#define COLOR_BLACK { 0, 0, 0}
+
+struct bar_std {
+ u8 bar[8][3];
};
+/* Maximum number of bars are 10 - otherwise, the input print code
+ should be modified */
+static struct bar_std bars[] = {
+ { /* Standard ITU-R color bar sequence */
+ {
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_CIAN,
+ COLOR_GREEN,
+ COLOR_MAGENTA,
+ COLOR_RED,
+ COLOR_BLUE,
+ COLOR_BLACK,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_AMBAR,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_CIAN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_CIAN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_CIAN,
+ }
+ }, {
+ {
+ COLOR_WHITE,
+ COLOR_GREEN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_GREEN,
+ COLOR_BLACK,
+ COLOR_WHITE,
+ COLOR_GREEN,
+ }
+ },
+};
+
+#define NUM_INPUTS ARRAY_SIZE(bars)
+
#define TO_Y(r, g, b) \
(((16829 * r + 33039 * g + 6416 * b + 32768) >> 16) + 16)
/* RGB to V(Cr) Color transform */
@@ -275,9 +343,10 @@ static u8 bars[8][3] = {
#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
+#define TSTAMP_MIN_Y 24
+#define TSTAMP_MAX_Y (TSTAMP_MIN_Y + 15)
+#define TSTAMP_INPUT_X 10
+#define TSTAMP_MIN_X (54 + TSTAMP_INPUT_X)
static void gen_twopix(struct vivi_fh *fh, unsigned char *buf, int colorpos)
{
@@ -392,9 +461,29 @@ static void gen_line(struct vivi_fh *fh, char *basep, int inipos, int wmax,
pos += 4; /* only 16 bpp supported for now */
}
- /* Checks if it is possible to show timestamp */
+ /* Prints input entry number */
+
+ /* Checks if it is possible to input number */
if (TSTAMP_MAX_Y >= hmax)
goto end;
+
+ if (TSTAMP_INPUT_X + strlen(timestr) >= wmax)
+ goto end;
+
+ if (line >= TSTAMP_MIN_Y && line <= TSTAMP_MAX_Y) {
+ chr = rom8x16_bits[fh->input * 16 + line - TSTAMP_MIN_Y];
+ pos = TSTAMP_INPUT_X;
+ for (i = 0; i < 7; i++) {
+ /* Draw white font on black background */
+ if (chr & 1 << (7 - i))
+ gen_twopix(fh, basep + pos, WHITE);
+ else
+ gen_twopix(fh, basep + pos, BLACK);
+ pos += 2;
+ }
+ }
+
+ /* Checks if it is possible to show timestamp */
if (TSTAMP_MIN_X + strlen(timestr) >= wmax)
goto end;
@@ -577,7 +666,7 @@ static int vivi_start_thread(struct vivi_fh *fh)
dma_q->kthread = kthread_run(vivi_thread, fh, "vivi");
if (IS_ERR(dma_q->kthread)) {
- printk(KERN_ERR "vivi: kernel_thread() failed\n");
+ v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
return PTR_ERR(dma_q->kthread);
}
/* Wakes thread */
@@ -720,8 +809,12 @@ static struct videobuf_queue_ops vivi_video_qops = {
static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
strcpy(cap->driver, "vivi");
strcpy(cap->card, "vivi");
+ strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info));
cap->version = VIVI_VERSION;
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_STREAMING |
@@ -807,38 +900,19 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return 0;
}
-/*FIXME: This seems to be generic enough to be at videodev2 */
-static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
- struct v4l2_format *f)
+/* precalculate color bar values to speed up rendering */
+static void precalculate_bars(struct vivi_fh *fh)
{
- struct vivi_fh *fh = priv;
- struct videobuf_queue *q = &fh->vb_vidq;
+ struct vivi_dev *dev = fh->dev;
unsigned char r, g, b;
int k, is_yuv;
- int ret = vidioc_try_fmt_vid_cap(file, fh, f);
- if (ret < 0)
- return (ret);
-
- mutex_lock(&q->vb_lock);
-
- if (videobuf_queue_is_busy(&fh->vb_vidq)) {
- dprintk(fh->dev, 1, "%s queue busy\n", __func__);
- ret = -EBUSY;
- goto out;
- }
-
- fh->fmt = get_format(f);
- fh->width = f->fmt.pix.width;
- fh->height = f->fmt.pix.height;
- fh->vb_vidq.field = f->fmt.pix.field;
- fh->type = f->type;
+ fh->input = dev->input;
- /* precalculate color bar values to speed up rendering */
for (k = 0; k < 8; k++) {
- r = bars[k][0];
- g = bars[k][1];
- b = bars[k][2];
+ r = bars[fh->input].bar[k][0];
+ g = bars[fh->input].bar[k][1];
+ b = bars[fh->input].bar[k][2];
is_yuv = 0;
switch (fh->fmt->fourcc) {
@@ -871,11 +945,40 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
}
}
+}
+
+/*FIXME: This seems to be generic enough to be at videodev2 */
+static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
+ struct v4l2_format *f)
+{
+ struct vivi_fh *fh = priv;
+ struct videobuf_queue *q = &fh->vb_vidq;
+
+ int ret = vidioc_try_fmt_vid_cap(file, fh, f);
+ if (ret < 0)
+ return ret;
+
+ mutex_lock(&q->vb_lock);
+
+ if (videobuf_queue_is_busy(&fh->vb_vidq)) {
+ dprintk(fh->dev, 1, "%s queue busy\n", __func__);
+ ret = -EBUSY;
+ goto out;
+ }
+
+ fh->fmt = get_format(f);
+ fh->width = f->fmt.pix.width;
+ fh->height = f->fmt.pix.height;
+ fh->vb_vidq.field = f->fmt.pix.field;
+ fh->type = f->type;
+
+ precalculate_bars(fh);
+
ret = 0;
out:
mutex_unlock(&q->vb_lock);
- return (ret);
+ return ret;
}
static int vidioc_reqbufs(struct file *file, void *priv,
@@ -950,27 +1053,36 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
static int vidioc_enum_input(struct file *file, void *priv,
struct v4l2_input *inp)
{
- if (inp->index != 0)
+ if (inp->index >= NUM_INPUTS)
return -EINVAL;
inp->type = V4L2_INPUT_TYPE_CAMERA;
inp->std = V4L2_STD_525_60;
- strcpy(inp->name, "Camera");
+ sprintf(inp->name, "Camera %u", inp->index);
return (0);
}
static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
{
- *i = 0;
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
+ *i = dev->input;
return (0);
}
static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
{
- if (i > 0)
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
+
+ if (i >= NUM_INPUTS)
return -EINVAL;
+ dev->input = i;
+ precalculate_bars(fh);
+
return (0);
}
@@ -993,12 +1105,14 @@ static int vidioc_queryctrl(struct file *file, void *priv,
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
int i;
for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
if (ctrl->id == vivi_qctrl[i].id) {
- ctrl->value = qctl_regs[i];
- return (0);
+ ctrl->value = dev->qctl_regs[i];
+ return 0;
}
return -EINVAL;
@@ -1006,16 +1120,18 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
+ struct vivi_fh *fh = priv;
+ struct vivi_dev *dev = fh->dev;
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) {
- return (-ERANGE);
- }
- qctl_regs[i] = ctrl->value;
- return (0);
+ if (ctrl->value < vivi_qctrl[i].minimum ||
+ ctrl->value > vivi_qctrl[i].maximum) {
+ return -ERANGE;
+ }
+ dev->qctl_regs[i] = ctrl->value;
+ return 0;
}
return -EINVAL;
}
@@ -1026,32 +1142,20 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
static int vivi_open(struct file *file)
{
- int minor = video_devdata(file)->minor;
- struct vivi_dev *dev;
+ struct vivi_dev *dev = video_drvdata(file);
struct vivi_fh *fh = NULL;
- int i;
int retval = 0;
- printk(KERN_DEBUG "vivi: open called (minor=%d)\n", minor);
-
- lock_kernel();
- list_for_each_entry(dev, &vivi_devlist, vivi_devlist)
- if (dev->vfd->minor == minor)
- goto found;
- unlock_kernel();
- return -ENODEV;
-
-found:
mutex_lock(&dev->mutex);
dev->users++;
if (dev->users > 1) {
dev->users--;
- retval = -EBUSY;
- goto unlock;
+ mutex_unlock(&dev->mutex);
+ return -EBUSY;
}
- dprintk(dev, 1, "open minor=%d type=%s users=%d\n", minor,
+ dprintk(dev, 1, "open /dev/video%d type=%s users=%d\n", dev->vfd->num,
v4l2_type_names[V4L2_BUF_TYPE_VIDEO_CAPTURE], dev->users);
/* allocate + initialize per filehandle data */
@@ -1059,14 +1163,11 @@ found:
if (NULL == fh) {
dev->users--;
retval = -ENOMEM;
- goto unlock;
}
-unlock:
mutex_unlock(&dev->mutex);
- if (retval) {
- unlock_kernel();
+
+ if (retval)
return retval;
- }
file->private_data = fh;
fh->dev = dev;
@@ -1076,10 +1177,6 @@ unlock:
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;
-
/* Resets frame counters */
dev->h = 0;
dev->m = 0;
@@ -1095,7 +1192,6 @@ unlock:
sizeof(struct vivi_buffer), fh);
vivi_start_thread(fh);
- unlock_kernel();
return 0;
}
@@ -1151,32 +1247,6 @@ static int vivi_close(struct file *file)
return 0;
}
-static int vivi_release(void)
-{
- struct vivi_dev *dev;
- struct list_head *list;
-
- while (!list_empty(&vivi_devlist)) {
- list = vivi_devlist.next;
- list_del(list);
- dev = list_entry(list, struct vivi_dev, vivi_devlist);
-
- if (-1 != dev->vfd->minor) {
- printk(KERN_INFO "%s: unregistering /dev/video%d\n",
- VIVI_MODULE_NAME, dev->vfd->num);
- video_unregister_device(dev->vfd);
- } else {
- printk(KERN_INFO "%s: releasing /dev/video%d\n",
- VIVI_MODULE_NAME, dev->vfd->num);
- video_device_release(dev->vfd);
- }
-
- kfree(dev);
- }
-
- return 0;
-}
-
static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
{
struct vivi_fh *fh = file->private_data;
@@ -1239,87 +1309,130 @@ static struct video_device vivi_template = {
.tvnorms = V4L2_STD_525_60,
.current_norm = V4L2_STD_NTSC_M,
};
+
/* -----------------------------------------------------------------
Initialization and module stuff
------------------------------------------------------------------*/
-/* This routine allocates from 1 to n_devs virtual drivers.
+static int vivi_release(void)
+{
+ struct vivi_dev *dev;
+ struct list_head *list;
- The real maximum number of virtual drivers will depend on how many drivers
- will succeed. This is limited to the maximum number of devices that
- videodev supports. Since there are 64 minors for video grabbers, this is
- currently the theoretical maximum limit. However, a further limit does
- exist at videodev that forbids any driver to register more than 32 video
- grabbers.
- */
-static int __init vivi_init(void)
+ while (!list_empty(&vivi_devlist)) {
+ list = vivi_devlist.next;
+ list_del(list);
+ dev = list_entry(list, struct vivi_dev, vivi_devlist);
+
+ v4l2_info(&dev->v4l2_dev, "unregistering /dev/video%d\n",
+ dev->vfd->num);
+ video_unregister_device(dev->vfd);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ kfree(dev);
+ }
+
+ return 0;
+}
+
+static int __init vivi_create_instance(int inst)
{
- int ret = -ENOMEM, i;
struct vivi_dev *dev;
struct video_device *vfd;
+ int ret, i;
- if (n_devs <= 0)
- n_devs = 1;
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
- for (i = 0; i < n_devs; i++) {
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
- if (!dev)
- break;
+ snprintf(dev->v4l2_dev.name, sizeof(dev->v4l2_dev.name),
+ "%s-%03d", VIVI_MODULE_NAME, inst);
+ ret = v4l2_device_register(NULL, &dev->v4l2_dev);
+ if (ret)
+ goto free_dev;
- /* init video dma queues */
- INIT_LIST_HEAD(&dev->vidq.active);
- init_waitqueue_head(&dev->vidq.wq);
+ /* init video dma queues */
+ INIT_LIST_HEAD(&dev->vidq.active);
+ init_waitqueue_head(&dev->vidq.wq);
- /* initialize locks */
- spin_lock_init(&dev->slock);
- mutex_init(&dev->mutex);
+ /* initialize locks */
+ spin_lock_init(&dev->slock);
+ mutex_init(&dev->mutex);
- vfd = video_device_alloc();
- if (!vfd) {
- kfree(dev);
- break;
- }
+ ret = -ENOMEM;
+ vfd = video_device_alloc();
+ if (!vfd)
+ goto unreg_dev;
- *vfd = vivi_template;
+ *vfd = vivi_template;
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
- if (ret < 0) {
- video_device_release(vfd);
- kfree(dev);
+ ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
+ if (ret < 0)
+ goto rel_vdev;
- /* If some registers succeeded, keep driver */
- if (i)
- ret = 0;
+ video_set_drvdata(vfd, dev);
- break;
- }
+ /* Set all controls to their default value. */
+ for (i = 0; i < ARRAY_SIZE(vivi_qctrl); i++)
+ dev->qctl_regs[i] = vivi_qctrl[i].default_value;
+
+ /* Now that everything is fine, let's add it to device list */
+ list_add_tail(&dev->vivi_devlist, &vivi_devlist);
+
+ snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
+ vivi_template.name, vfd->num);
+
+ if (video_nr >= 0)
+ video_nr++;
- /* Now that everything is fine, let's add it to device list */
- list_add_tail(&dev->vivi_devlist, &vivi_devlist);
+ dev->vfd = vfd;
+ v4l2_info(&dev->v4l2_dev, "V4L2 device registered as /dev/video%d\n",
+ vfd->num);
+ return 0;
+
+rel_vdev:
+ video_device_release(vfd);
+unreg_dev:
+ v4l2_device_unregister(&dev->v4l2_dev);
+free_dev:
+ kfree(dev);
+ return ret;
+}
+
+/* This routine allocates from 1 to n_devs virtual drivers.
- snprintf(vfd->name, sizeof(vfd->name), "%s (%i)",
- vivi_template.name, vfd->minor);
+ The real maximum number of virtual drivers will depend on how many drivers
+ will succeed. This is limited to the maximum number of devices that
+ videodev supports, which is equal to VIDEO_NUM_DEVICES.
+ */
+static int __init vivi_init(void)
+{
+ int ret = 0, i;
- if (video_nr >= 0)
- video_nr++;
+ if (n_devs <= 0)
+ n_devs = 1;
- dev->vfd = vfd;
- printk(KERN_INFO "%s: V4L2 device registered as /dev/video%d\n",
- VIVI_MODULE_NAME, vfd->num);
+ for (i = 0; i < n_devs; i++) {
+ ret = vivi_create_instance(i);
+ if (ret) {
+ /* If some instantiations succeeded, keep driver */
+ if (i)
+ ret = 0;
+ break;
+ }
}
if (ret < 0) {
- vivi_release();
printk(KERN_INFO "Error %d while loading vivi driver\n", ret);
- } else {
- printk(KERN_INFO "Video Technology Magazine Virtual Video "
+ return ret;
+ }
+
+ printk(KERN_INFO "Video Technology Magazine Virtual Video "
"Capture Board ver %u.%u.%u successfully loaded.\n",
(VIVI_VERSION >> 16) & 0xFF, (VIVI_VERSION >> 8) & 0xFF,
VIVI_VERSION & 0xFF);
- /* n_devs will reflect the actual number of allocated devices */
- n_devs = i;
- }
+ /* n_devs will reflect the actual number of allocated devices */
+ n_devs = i;
return ret;
}
@@ -1331,19 +1444,3 @@ static void __exit vivi_exit(void)
module_init(vivi_init);
module_exit(vivi_exit);
-
-MODULE_DESCRIPTION("Video Technology Magazine Virtual Video Capture Board");
-MODULE_AUTHOR("Mauro Carvalho Chehab, Ted Walther and John Sokol");
-MODULE_LICENSE("Dual BSD/GPL");
-
-module_param(video_nr, uint, 0444);
-MODULE_PARM_DESC(video_nr, "video iminor start number");
-
-module_param(n_devs, uint, 0444);
-MODULE_PARM_DESC(n_devs, "number of video devices to create");
-
-module_param_named(debug, vivi_template.debug, int, 0444);
-MODULE_PARM_DESC(debug, "activates debug info");
-
-module_param(vid_limit, int, 0644);
-MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
diff --git a/drivers/media/video/vp27smpx.c b/drivers/media/video/vp27smpx.c
index 5d73f66d9f5..42e23a4fa60 100644
--- a/drivers/media/video/vp27smpx.c
+++ b/drivers/media/video/vp27smpx.c
@@ -129,11 +129,6 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
@@ -206,8 +201,6 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "vp27smpx",
- .driverid = I2C_DRIVERID_VP27SMPX,
- .command = vp27smpx_command,
.probe = vp27smpx_probe,
.remove = vp27smpx_remove,
.id_table = vp27smpx_id,
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 67aa0db4b81..2fa7e8bb574 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -24,10 +24,10 @@
#include <linux/types.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>
-#include <media/v4l2-common.h>
-#include <media/v4l2-i2c-drv-legacy.h>
-#include <linux/videodev.h>
-#include <linux/video_decoder.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
MODULE_AUTHOR("Laurent Pinchart");
@@ -37,14 +37,17 @@ static int debug;
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
+
#define VPX_TIMEOUT_COUNT 10
/* ----------------------------------------------------------------------- */
struct vpx3220 {
+ struct v4l2_subdev sd;
unsigned char reg[255];
- int norm;
+ v4l2_std_id norm;
+ int ident;
int input;
int enable;
int bright;
@@ -53,30 +56,38 @@ struct vpx3220 {
int sat;
};
+static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct vpx3220, sd);
+}
+
static char *inputs[] = { "internal", "composite", "svideo" };
/* ----------------------------------------------------------------------- */
-static inline int vpx3220_write(struct i2c_client *client, u8 reg, u8 value)
+static inline int vpx3220_write(struct v4l2_subdev *sd, u8 reg, u8 value)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
struct vpx3220 *decoder = i2c_get_clientdata(client);
decoder->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
-static inline int vpx3220_read(struct i2c_client *client, u8 reg)
+static inline int vpx3220_read(struct v4l2_subdev *sd, u8 reg)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
return i2c_smbus_read_byte_data(client, reg);
}
-static int vpx3220_fp_status(struct i2c_client *client)
+static int vpx3220_fp_status(struct v4l2_subdev *sd)
{
unsigned char status;
unsigned int i;
for (i = 0; i < VPX_TIMEOUT_COUNT; i++) {
- status = vpx3220_read(client, 0x29);
+ status = vpx3220_read(sd, 0x29);
if (!(status & 4))
return 0;
@@ -90,57 +101,60 @@ static int vpx3220_fp_status(struct i2c_client *client)
return -1;
}
-static int vpx3220_fp_write(struct i2c_client *client, u8 fpaddr, u16 data)
+static int vpx3220_fp_write(struct v4l2_subdev *sd, u8 fpaddr, u16 data)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
/* Write the 16-bit address to the FPWR register */
if (i2c_smbus_write_word_data(client, 0x27, swab16(fpaddr)) == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
- if (vpx3220_fp_status(client) < 0)
+ if (vpx3220_fp_status(sd) < 0)
return -1;
/* Write the 16-bit data to the FPDAT register */
if (i2c_smbus_write_word_data(client, 0x28, swab16(data)) == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
return 0;
}
-static u16 vpx3220_fp_read(struct i2c_client *client, u16 fpaddr)
+static u16 vpx3220_fp_read(struct v4l2_subdev *sd, u16 fpaddr)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
s16 data;
/* Write the 16-bit address to the FPRD register */
if (i2c_smbus_write_word_data(client, 0x26, swab16(fpaddr)) == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
- if (vpx3220_fp_status(client) < 0)
+ if (vpx3220_fp_status(sd) < 0)
return -1;
/* Read the 16-bit data from the FPDAT register */
data = i2c_smbus_read_word_data(client, 0x28);
if (data == -1) {
- v4l_dbg(1, debug, client, "%s: failed\n", __func__);
+ v4l2_dbg(1, debug, sd, "%s: failed\n", __func__);
return -1;
}
return swab16(data);
}
-static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsigned int len)
+static int vpx3220_write_block(struct v4l2_subdev *sd, const u8 *data, unsigned int len)
{
u8 reg;
int ret = -1;
while (len >= 2) {
reg = *data++;
- ret = vpx3220_write(client, reg, *data++);
+ ret = vpx3220_write(sd, reg, *data++);
if (ret < 0)
break;
len -= 2;
@@ -149,7 +163,7 @@ static int vpx3220_write_block(struct i2c_client *client, const u8 *data, unsign
return ret;
}
-static int vpx3220_write_fp_block(struct i2c_client *client,
+static int vpx3220_write_fp_block(struct v4l2_subdev *sd,
const u16 *data, unsigned int len)
{
u8 reg;
@@ -157,7 +171,7 @@ static int vpx3220_write_fp_block(struct i2c_client *client,
while (len > 1) {
reg = *data++;
- ret |= vpx3220_fp_write(client, reg, *data++);
+ ret |= vpx3220_fp_write(sd, reg, *data++);
len -= 2;
}
@@ -259,276 +273,277 @@ static const unsigned short init_fp[] = {
0x4b, 0x298, /* PLL gain */
};
-static void vpx3220_dump_i2c(struct i2c_client *client)
-{
- int len = sizeof(init_common);
- const unsigned char *data = init_common;
- while (len > 1) {
- v4l_dbg(1, debug, client, "i2c reg 0x%02x data 0x%02x\n",
- *data, vpx3220_read(client, *data));
- data += 2;
- len -= 2;
- }
+static int vpx3220_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
+
+ vpx3220_write_block(sd, init_common, sizeof(init_common));
+ vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
+ if (decoder->norm & V4L2_STD_NTSC)
+ vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
+ else if (decoder->norm & V4L2_STD_PAL)
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+ else if (decoder->norm & V4L2_STD_SECAM)
+ vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
+ else
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+ return 0;
}
-static int vpx3220_command(struct i2c_client *client, unsigned cmd, void *arg)
+static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd)
{
- struct vpx3220 *decoder = i2c_get_clientdata(client);
+ int res = V4L2_IN_ST_NO_SIGNAL, status;
+ v4l2_std_id std = 0;
- switch (cmd) {
- case 0:
- {
- vpx3220_write_block(client, init_common,
- sizeof(init_common));
- 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);
- break;
+ status = vpx3220_fp_read(sd, 0x0f3);
+
+ v4l2_dbg(1, debug, sd, "status: 0x%04x\n", status);
+
+ if (status < 0)
+ return status;
- case VIDEO_MODE_PAL:
- vpx3220_write_fp_block(client, init_pal,
- sizeof(init_pal) >> 1);
+ if ((status & 0x20) == 0) {
+ res = 0;
+
+ switch (status & 0x18) {
+ case 0x00:
+ case 0x10:
+ case 0x14:
+ case 0x18:
+ std = V4L2_STD_PAL;
break;
- case VIDEO_MODE_SECAM:
- vpx3220_write_fp_block(client, init_secam,
- sizeof(init_secam) >> 1);
+
+ case 0x08:
+ std = V4L2_STD_SECAM;
break;
- default:
- vpx3220_write_fp_block(client, init_pal,
- sizeof(init_pal) >> 1);
+
+ case 0x04:
+ case 0x0c:
+ case 0x1c:
+ std = V4L2_STD_NTSC;
break;
}
- break;
- }
-
- case DECODER_DUMP:
- {
- vpx3220_dump_i2c(client);
- break;
}
+ if (pstd)
+ *pstd = std;
+ if (pstatus)
+ *pstatus = status;
+ return 0;
+}
- case DECODER_GET_CAPABILITIES:
- {
- struct video_decoder_capability *cap = arg;
+static int vpx3220_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+ v4l2_dbg(1, debug, sd, "querystd\n");
+ return vpx3220_status(sd, NULL, std);
+}
- v4l_dbg(1, debug, client, "DECODER_GET_CAPABILITIES\n");
+static int vpx3220_g_input_status(struct v4l2_subdev *sd, u32 *status)
+{
+ v4l2_dbg(1, debug, sd, "g_input_status\n");
+ return vpx3220_status(sd, status, NULL);
+}
- cap->flags = VIDEO_DECODER_PAL |
- VIDEO_DECODER_NTSC |
- VIDEO_DECODER_SECAM |
- VIDEO_DECODER_AUTO |
- VIDEO_DECODER_CCIR;
- cap->inputs = 3;
- cap->outputs = 1;
- break;
+static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
+ int temp_input;
+
+ /* Here we back up the input selection because it gets
+ overwritten when we fill the registers with the
+ choosen video norm */
+ temp_input = vpx3220_fp_read(sd, 0xf2);
+
+ v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std);
+ if (std & V4L2_STD_NTSC) {
+ vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
+ v4l2_dbg(1, debug, sd, "norm switched to NTSC\n");
+ } else if (std & V4L2_STD_PAL) {
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
+ v4l2_dbg(1, debug, sd, "norm switched to PAL\n");
+ } else if (std & V4L2_STD_SECAM) {
+ vpx3220_write_fp_block(sd, init_secam, sizeof(init_secam) >> 1);
+ v4l2_dbg(1, debug, sd, "norm switched to SECAM\n");
+ } else {
+ return -EINVAL;
}
- case DECODER_GET_STATUS:
- {
- int res = 0, status;
+ decoder->norm = std;
- v4l_dbg(1, debug, client, "DECODER_GET_STATUS\n");
-
- status = vpx3220_fp_read(client, 0x0f3);
-
- v4l_dbg(1, debug, client, "status: 0x%04x\n", status);
-
- if (status < 0)
- return status;
+ /* And here we set the backed up video input again */
+ vpx3220_fp_write(sd, 0xf2, temp_input | 0x0010);
+ udelay(10);
+ return 0;
+}
- if ((status & 0x20) == 0) {
- res |= DECODER_STATUS_GOOD | DECODER_STATUS_COLOR;
+static int vpx3220_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *route)
+{
+ int data;
- switch (status & 0x18) {
- case 0x00:
- case 0x10:
- case 0x14:
- case 0x18:
- res |= DECODER_STATUS_PAL;
- break;
+ /* RJ: route->input = 0: ST8 (PCTV) input
+ route->input = 1: COMPOSITE input
+ route->input = 2: SVHS input */
- case 0x08:
- res |= DECODER_STATUS_SECAM;
- break;
+ const int input[3][2] = {
+ {0x0c, 0},
+ {0x0d, 0},
+ {0x0e, 1}
+ };
- case 0x04:
- case 0x0c:
- case 0x1c:
- res |= DECODER_STATUS_NTSC;
- break;
- }
- }
+ if (route->input < 0 || route->input > 2)
+ return -EINVAL;
- *(int *) arg = res;
- break;
- }
+ v4l2_dbg(1, debug, sd, "input switched to %s\n", inputs[route->input]);
- case DECODER_SET_NORM:
- {
- int *iarg = arg, data;
- int temp_input;
-
- /* Here we back up the input selection because it gets
- overwritten when we fill the registers with the
- choosen video norm */
- temp_input = vpx3220_fp_read(client, 0xf2);
-
- v4l_dbg(1, debug, client, "DECODER_SET_NORM %d\n", *iarg);
- switch (*iarg) {
- case VIDEO_MODE_NTSC:
- vpx3220_write_fp_block(client, init_ntsc,
- sizeof(init_ntsc) >> 1);
- v4l_dbg(1, debug, client, "norm switched to NTSC\n");
- break;
+ vpx3220_write(sd, 0x33, input[route->input][0]);
- case VIDEO_MODE_PAL:
- vpx3220_write_fp_block(client, init_pal,
- sizeof(init_pal) >> 1);
- v4l_dbg(1, debug, client, "norm switched to PAL\n");
- break;
+ data = vpx3220_fp_read(sd, 0xf2) & ~(0x0020);
+ if (data < 0)
+ return data;
+ /* 0x0010 is required to latch the setting */
+ vpx3220_fp_write(sd, 0xf2,
+ data | (input[route->input][1] << 5) | 0x0010);
- case VIDEO_MODE_SECAM:
- vpx3220_write_fp_block(client, init_secam,
- sizeof(init_secam) >> 1);
- v4l_dbg(1, debug, client, "norm switched to SECAM\n");
- break;
+ udelay(10);
+ return 0;
+}
- case VIDEO_MODE_AUTO:
- /* FIXME This is only preliminary support */
- data = vpx3220_fp_read(client, 0xf2) & 0x20;
- vpx3220_fp_write(client, 0xf2, 0x00c0 | data);
- v4l_dbg(1, debug, client, "norm switched to AUTO\n");
- break;
+static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ v4l2_dbg(1, debug, sd, "s_stream %s\n", enable ? "on" : "off");
- default:
- return -EINVAL;
- }
- decoder->norm = *iarg;
+ vpx3220_write(sd, 0xf2, (enable ? 0x1b : 0x00));
+ return 0;
+}
- /* And here we set the backed up video input again */
- vpx3220_fp_write(client, 0xf2, temp_input | 0x0010);
- udelay(10);
+static int vpx3220_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
break;
- }
-
- case DECODER_SET_INPUT:
- {
- int *iarg = arg, data;
-
- /* RJ: *iarg = 0: ST8 (PCTV) input
- *iarg = 1: COMPOSITE input
- *iarg = 2: SVHS input */
-
- const int input[3][2] = {
- {0x0c, 0},
- {0x0d, 0},
- {0x0e, 1}
- };
- if (*iarg < 0 || *iarg > 2)
- return -EINVAL;
-
- v4l_dbg(1, debug, client, "input switched to %s\n", inputs[*iarg]);
-
- vpx3220_write(client, 0x33, input[*iarg][0]);
-
- data = vpx3220_fp_read(client, 0xf2) & ~(0x0020);
- if (data < 0)
- return data;
- /* 0x0010 is required to latch the setting */
- vpx3220_fp_write(client, 0xf2,
- data | (input[*iarg][1] << 5) | 0x0010);
-
- udelay(10);
+ case V4L2_CID_CONTRAST:
+ v4l2_ctrl_query_fill(qc, 0, 63, 1, 32);
break;
- }
- case DECODER_SET_OUTPUT:
- {
- int *iarg = arg;
+ case V4L2_CID_SATURATION:
+ v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048);
+ break;
- /* not much choice of outputs */
- if (*iarg != 0) {
- return -EINVAL;
- }
+ case V4L2_CID_HUE:
+ v4l2_ctrl_query_fill(qc, -512, 511, 1, 0);
break;
- }
- case DECODER_ENABLE_OUTPUT:
- {
- int *iarg = arg;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
- v4l_dbg(1, debug, client, "DECODER_ENABLE_OUTPUT %d\n", *iarg);
+static int vpx3220_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
- vpx3220_write(client, 0xf2, (*iarg ? 0x1b : 0x00));
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = decoder->bright;
+ break;
+ case V4L2_CID_CONTRAST:
+ ctrl->value = decoder->contrast;
break;
+ case V4L2_CID_SATURATION:
+ ctrl->value = decoder->sat;
+ break;
+ case V4L2_CID_HUE:
+ ctrl->value = decoder->hue;
+ break;
+ default:
+ return -EINVAL;
}
+ return 0;
+}
- case DECODER_SET_PICTURE:
- {
- struct video_picture *pic = arg;
+static int vpx3220_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct vpx3220 *decoder = to_vpx3220(sd);
- if (decoder->bright != pic->brightness) {
- /* We want -128 to 128 we get 0-65535 */
- decoder->bright = pic->brightness;
- vpx3220_write(client, 0xe6,
- (decoder->bright - 32768) >> 8);
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (decoder->bright != ctrl->value) {
+ decoder->bright = ctrl->value;
+ vpx3220_write(sd, 0xe6, decoder->bright);
}
- if (decoder->contrast != pic->contrast) {
- /* We want 0 to 64 we get 0-65535 */
+ break;
+ case V4L2_CID_CONTRAST:
+ if (decoder->contrast != ctrl->value) {
/* Bit 7 and 8 is for noise shaping */
- decoder->contrast = pic->contrast;
- vpx3220_write(client, 0xe7,
- (decoder->contrast >> 10) + 192);
+ decoder->contrast = ctrl->value;
+ vpx3220_write(sd, 0xe7, decoder->contrast + 192);
}
- if (decoder->sat != pic->colour) {
- /* We want 0 to 4096 we get 0-65535 */
- decoder->sat = pic->colour;
- vpx3220_fp_write(client, 0xa0,
- decoder->sat >> 4);
+ break;
+ case V4L2_CID_SATURATION:
+ if (decoder->sat != ctrl->value) {
+ decoder->sat = ctrl->value;
+ vpx3220_fp_write(sd, 0xa0, decoder->sat);
}
- if (decoder->hue != pic->hue) {
- /* We want -512 to 512 we get 0-65535 */
- decoder->hue = pic->hue;
- vpx3220_fp_write(client, 0x1c,
- ((decoder->hue - 32768) >> 6) & 0xFFF);
+ break;
+ case V4L2_CID_HUE:
+ if (decoder->hue != ctrl->value) {
+ decoder->hue = ctrl->value;
+ vpx3220_fp_write(sd, 0x1c, decoder->hue);
}
break;
- }
-
default:
return -EINVAL;
}
-
return 0;
}
-static int vpx3220_init_client(struct i2c_client *client)
+static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
{
- vpx3220_write_block(client, init_common, sizeof(init_common));
- vpx3220_write_fp_block(client, init_fp, sizeof(init_fp) >> 1);
- /* Default to PAL */
- vpx3220_write_fp_block(client, init_pal, sizeof(init_pal) >> 1);
+ struct vpx3220 *decoder = to_vpx3220(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
- return 0;
+ return v4l2_chip_ident_i2c_client(client, chip, decoder->ident, 0);
}
+/* ----------------------------------------------------------------------- */
+
+static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
+ .g_chip_ident = vpx3220_g_chip_ident,
+ .init = vpx3220_init,
+ .g_ctrl = vpx3220_g_ctrl,
+ .s_ctrl = vpx3220_s_ctrl,
+ .queryctrl = vpx3220_queryctrl,
+};
+
+static const struct v4l2_subdev_tuner_ops vpx3220_tuner_ops = {
+ .s_std = vpx3220_s_std,
+};
+
+static const struct v4l2_subdev_video_ops vpx3220_video_ops = {
+ .s_routing = vpx3220_s_routing,
+ .s_stream = vpx3220_s_stream,
+ .querystd = vpx3220_querystd,
+ .g_input_status = vpx3220_g_input_status,
+};
+
+static const struct v4l2_subdev_ops vpx3220_ops = {
+ .core = &vpx3220_core_ops,
+ .tuner = &vpx3220_tuner_ops,
+ .video = &vpx3220_video_ops,
+};
+
/* -----------------------------------------------------------------------
* Client management code
*/
-static unsigned short normal_i2c[] = { 0x86 >> 1, 0x8e >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
-
static int vpx3220_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct vpx3220 *decoder;
+ struct v4l2_subdev *sd;
const char *name = NULL;
u8 ver;
u16 pn;
@@ -541,18 +556,20 @@ static int vpx3220_probe(struct i2c_client *client,
decoder = kzalloc(sizeof(struct vpx3220), GFP_KERNEL);
if (decoder == NULL)
return -ENOMEM;
- decoder->norm = VIDEO_MODE_PAL;
+ sd = &decoder->sd;
+ v4l2_i2c_subdev_init(sd, client, &vpx3220_ops);
+ decoder->norm = V4L2_STD_PAL;
decoder->input = 0;
decoder->enable = 1;
decoder->bright = 32768;
decoder->contrast = 32768;
decoder->hue = 32768;
decoder->sat = 32768;
- i2c_set_clientdata(client, decoder);
ver = i2c_smbus_read_byte_data(client, 0x00);
pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
i2c_smbus_read_byte_data(client, 0x01);
+ decoder->ident = V4L2_IDENT_VPX3220A;
if (ver == 0xec) {
switch (pn) {
case 0x4680:
@@ -560,26 +577,34 @@ static int vpx3220_probe(struct i2c_client *client,
break;
case 0x4260:
name = "vpx3216b";
+ decoder->ident = V4L2_IDENT_VPX3216B;
break;
case 0x4280:
name = "vpx3214c";
+ decoder->ident = V4L2_IDENT_VPX3214C;
break;
}
}
if (name)
- v4l_info(client, "%s found @ 0x%x (%s)\n", name,
+ v4l2_info(sd, "%s found @ 0x%x (%s)\n", name,
client->addr << 1, client->adapter->name);
else
- v4l_info(client, "chip (%02x:%04x) found @ 0x%x (%s)\n",
+ v4l2_info(sd, "chip (%02x:%04x) found @ 0x%x (%s)\n",
ver, pn, client->addr << 1, client->adapter->name);
- vpx3220_init_client(client);
+ vpx3220_write_block(sd, init_common, sizeof(init_common));
+ vpx3220_write_fp_block(sd, init_fp, sizeof(init_fp) >> 1);
+ /* Default to PAL */
+ vpx3220_write_fp_block(sd, init_pal, sizeof(init_pal) >> 1);
return 0;
}
static int vpx3220_remove(struct i2c_client *client)
{
- kfree(i2c_get_clientdata(client));
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_vpx3220(sd));
return 0;
}
@@ -593,8 +618,6 @@ MODULE_DEVICE_TABLE(i2c, vpx3220_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "vpx3220",
- .driverid = I2C_DRIVERID_VPX3220,
- .command = vpx3220_command,
.probe = vpx3220_probe,
.remove = vpx3220_remove,
.id_table = vpx3220_id,
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c
index 038ff32b01b..dcade619cbd 100644
--- a/drivers/media/video/w9966.c
+++ b/drivers/media/video/w9966.c
@@ -57,7 +57,7 @@
#include <linux/module.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <linux/videodev2.h>
+#include <linux/videodev.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
#include <linux/parport.h>
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 105a832531f..3b08bc4af90 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -42,6 +42,7 @@
#include <asm/page.h>
#include <asm/uaccess.h>
#include <linux/page-flags.h>
+#include <linux/videodev.h>
#include <media/v4l2-ioctl.h>
#include "w9968cf.h"
@@ -68,7 +69,6 @@ MODULE_VERSION(W9968CF_MODULE_VERSION);
MODULE_LICENSE(W9968CF_MODULE_LICENSE);
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] =
@@ -111,9 +111,6 @@ static int specific_debug = W9968CF_SPECIFIC_DEBUG;
static unsigned int param_nv[24]; /* number of values per parameter */
-#ifdef CONFIG_MODULES
-module_param(ovmod_load, bool, 0644);
-#endif
module_param(simcams, ushort, 0644);
module_param_array(video_nr, short, &param_nv[0], 0444);
module_param_array(packet_size, uint, &param_nv[1], 0444);
@@ -144,18 +141,6 @@ module_param(debug, ushort, 0644);
module_param(specific_debug, bool, 0644);
#endif
-#ifdef CONFIG_MODULES
-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<n> Number of cameras allowed to stream simultaneously."
"\nn may vary from 0 to "
@@ -443,8 +428,6 @@ 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*);
/* Memory management */
static void* rvmalloc(unsigned long size);
@@ -1443,19 +1426,11 @@ 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);
+ struct v4l2_device *v4l2_dev = i2c_get_adapdata(adapter);
+ struct w9968cf_device *cam = to_cam(v4l2_dev);
u8 i;
int err = 0;
- switch (addr) {
- case OV6xx0_SID:
- case OV7xx0_SID:
- break;
- default:
- DBG(4, "Rejected slave ID 0x%04X", addr)
- return -EINVAL;
- }
-
if (size == I2C_SMBUS_BYTE) {
/* Why addr <<= 1? See OVXXX0_SID defines in ovcamchip.h */
addr <<= 1;
@@ -1463,8 +1438,17 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
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_read_byte(cam,addr,&data->byte);
-
+ for (i = 1; i <= W9968CF_I2C_RW_RETRIES; i++) {
+ err = w9968cf_i2c_adap_read_byte(cam, addr,
+ &data->byte);
+ if (err) {
+ if (w9968cf_smbus_refresh_bus(cam)) {
+ err = -EIO;
+ break;
+ }
+ } else
+ break;
+ }
} else if (size == I2C_SMBUS_BYTE_DATA) {
addr <<= 1;
@@ -1491,7 +1475,6 @@ w9968cf_i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
DBG(4, "Unsupported I2C transfer mode (%d)", size)
return -EINVAL;
}
-
return err;
}
@@ -1504,44 +1487,6 @@ static u32 w9968cf_i2c_func(struct i2c_adapter* adap)
}
-static int w9968cf_i2c_attach_inform(struct i2c_client* client)
-{
- struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
- int id = client->driver->id, err = 0;
-
- if (id == I2C_DRIVERID_OVCAMCHIP) {
- cam->sensor_client = client;
- err = w9968cf_sensor_init(cam);
- if (err) {
- cam->sensor_client = NULL;
- return err;
- }
- } else {
- DBG(4, "Rejected client [%s] with driver [%s]",
- client->name, client->driver->driver.name)
- return -EINVAL;
- }
-
- DBG(5, "I2C attach client [%s] with driver [%s]",
- client->name, client->driver->driver.name)
-
- return 0;
-}
-
-
-static int w9968cf_i2c_detach_inform(struct i2c_client* client)
-{
- struct w9968cf_device* cam = i2c_get_adapdata(client->adapter);
-
- if (cam->sensor_client == client)
- cam->sensor_client = NULL;
-
- DBG(5, "I2C detach client [%s]", client->name)
-
- return 0;
-}
-
-
static int w9968cf_i2c_init(struct w9968cf_device* cam)
{
int err = 0;
@@ -1554,15 +1499,13 @@ static int w9968cf_i2c_init(struct w9968cf_device* cam)
static struct i2c_adapter adap = {
.id = I2C_HW_SMBUS_W9968CF,
.owner = THIS_MODULE,
- .client_register = w9968cf_i2c_attach_inform,
- .client_unregister = w9968cf_i2c_detach_inform,
.algo = &algo,
};
memcpy(&cam->i2c_adapter, &adap, sizeof(struct i2c_adapter));
strcpy(cam->i2c_adapter.name, "w9968cf");
cam->i2c_adapter.dev.parent = &cam->usbdev->dev;
- i2c_set_adapdata(&cam->i2c_adapter, cam);
+ i2c_set_adapdata(&cam->i2c_adapter, &cam->v4l2_dev);
DBG(6, "Registering I2C adapter with kernel...")
@@ -2165,13 +2108,9 @@ w9968cf_sensor_get_control(struct w9968cf_device* cam, int cid, int* val)
static int
w9968cf_sensor_cmd(struct w9968cf_device* cam, unsigned int cmd, void* arg)
{
- struct i2c_client* c = cam->sensor_client;
- int rc = 0;
-
- if (!c || !c->driver || !c->driver->command)
- return -EINVAL;
+ int rc;
- rc = c->driver->command(c, cmd, arg);
+ rc = v4l2_subdev_call(cam->sensor_sd, core, ioctl, cmd, arg);
/* The I2C driver returns -EPERM on non-supported controls */
return (rc < 0 && rc != -EPERM) ? rc : 0;
}
@@ -2346,7 +2285,7 @@ static int w9968cf_sensor_init(struct w9968cf_device* cam)
goto error;
/* NOTE: Make sure width and height are a multiple of 16 */
- switch (cam->sensor_client->addr) {
+ switch (v4l2_i2c_subdev_addr(cam->sensor_sd)) {
case OV6xx0_SID:
cam->maxwidth = 352;
cam->maxheight = 288;
@@ -2651,6 +2590,7 @@ static void w9968cf_release_resources(struct w9968cf_device* cam)
w9968cf_deallocate_memory(cam);
kfree(cam->control_buffer);
kfree(cam->data_buffer);
+ v4l2_device_unregister(&cam->v4l2_dev);
mutex_unlock(&w9968cf_devlist_mutex);
}
@@ -3480,6 +3420,11 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
struct list_head* ptr;
u8 sc = 0; /* number of simultaneous cameras */
static unsigned short dev_nr; /* 0 - we are handling device number n */
+ static unsigned short addrs[] = {
+ OV7xx0_SID,
+ OV6xx0_SID,
+ I2C_CLIENT_END
+ };
if (le16_to_cpu(udev->descriptor.idVendor) == winbond_id_table[0].idVendor &&
le16_to_cpu(udev->descriptor.idProduct) == winbond_id_table[0].idProduct)
@@ -3495,12 +3440,14 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
if (!cam)
return -ENOMEM;
+ err = v4l2_device_register(&udev->dev, &cam->v4l2_dev);
+ if (err)
+ goto fail0;
+
mutex_init(&cam->dev_mutex);
mutex_lock(&cam->dev_mutex);
cam->usbdev = udev;
- /* NOTE: a local copy is used to avoid possible race conditions */
- memcpy(&cam->dev, &udev->dev, sizeof(struct device));
DBG(2, "%s detected", symbolic(camlist, mod_id))
@@ -3549,7 +3496,7 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
cam->v4ldev->minor = video_nr[dev_nr];
cam->v4ldev->release = video_device_release;
video_set_drvdata(cam->v4ldev, cam);
- cam->v4ldev->parent = &cam->dev;
+ cam->v4ldev->v4l2_dev = &cam->v4l2_dev;
err = video_register_device(cam->v4ldev, VFL_TYPE_GRABBER,
video_nr[dev_nr]);
@@ -3576,9 +3523,13 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
w9968cf_turn_on_led(cam);
w9968cf_i2c_init(cam);
+ cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->i2c_adapter,
+ "ovcamchip", "ovcamchip", addrs);
usb_set_intfdata(intf, cam);
mutex_unlock(&cam->dev_mutex);
+
+ err = w9968cf_sensor_init(cam);
return 0;
fail: /* Free unused memory */
@@ -3587,6 +3538,8 @@ fail: /* Free unused memory */
if (cam->v4ldev)
video_device_release(cam->v4ldev);
mutex_unlock(&cam->dev_mutex);
+ v4l2_device_unregister(&cam->v4l2_dev);
+fail0:
kfree(cam);
return err;
}
@@ -3597,15 +3550,16 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
struct w9968cf_device* cam =
(struct w9968cf_device*)usb_get_intfdata(intf);
- down_write(&w9968cf_disconnect);
-
if (cam) {
+ down_write(&w9968cf_disconnect);
/* Prevent concurrent accesses to data */
mutex_lock(&cam->dev_mutex);
cam->disconnected = 1;
- DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id))
+ DBG(2, "Disconnecting %s...", symbolic(camlist, cam->id));
+
+ v4l2_device_disconnect(&cam->v4l2_dev);
wake_up_interruptible_all(&cam->open);
@@ -3621,12 +3575,12 @@ static void w9968cf_usb_disconnect(struct usb_interface* intf)
w9968cf_release_resources(cam);
mutex_unlock(&cam->dev_mutex);
+ up_write(&w9968cf_disconnect);
- if (!cam->users)
+ if (!cam->users) {
kfree(cam);
+ }
}
-
- up_write(&w9968cf_disconnect);
}
@@ -3650,9 +3604,6 @@ static int __init w9968cf_module_init(void)
KDBG(2, W9968CF_MODULE_NAME" "W9968CF_MODULE_VERSION)
KDBG(3, W9968CF_MODULE_AUTHOR)
- if (ovmod_load)
- request_module("ovcamchip");
-
if ((err = usb_register(&w9968cf_usb_driver)))
return err;
diff --git a/drivers/media/video/w9968cf.h b/drivers/media/video/w9968cf.h
index 30032e15e23..fdfc6a4e1c8 100644
--- a/drivers/media/video/w9968cf.h
+++ b/drivers/media/video/w9968cf.h
@@ -33,6 +33,7 @@
#include <linux/rwsem.h>
#include <linux/mutex.h>
+#include <media/v4l2-device.h>
#include <media/ovcamchip.h>
#include "w9968cf_vpp.h"
@@ -42,7 +43,6 @@
* Default values *
****************************************************************************/
-#define W9968CF_OVMOD_LOAD 1 /* automatic 'ovcamchip' module loading */
#define W9968CF_VPPMOD_LOAD 1 /* automatic 'w9968cf-vpp' module loading */
/* Comment/uncomment the following line to enable/disable debugging messages */
@@ -195,10 +195,9 @@ enum w9968cf_vpp_flag {
/* Main device driver structure */
struct w9968cf_device {
- struct device dev; /* device structure */
-
enum w9968cf_model_id id; /* private device identifier */
+ struct v4l2_device v4l2_dev;
struct video_device* v4ldev; /* -> V4L structure */
struct list_head v4llist; /* entry of the list of V4L cameras */
@@ -265,7 +264,7 @@ struct w9968cf_device {
/* I2C interface to kernel */
struct i2c_adapter i2c_adapter;
- struct i2c_client* sensor_client;
+ struct v4l2_subdev *sensor_sd;
/* Locks */
struct mutex dev_mutex, /* for probe, disconnect,open and close */
@@ -277,6 +276,11 @@ struct w9968cf_device {
char command[16]; /* name of the program holding the device */
};
+static inline struct w9968cf_device *to_cam(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct w9968cf_device, v4l2_dev);
+}
+
/****************************************************************************
* Macros for debugging *
@@ -291,14 +295,14 @@ struct w9968cf_device {
if ( ((specific_debug) && (debug == (level))) || \
((!specific_debug) && (debug >= (level))) ) { \
if ((level) == 1) \
- dev_err(&cam->dev, fmt "\n", ## args); \
+ v4l2_err(&cam->v4l2_dev, fmt "\n", ## args); \
else if ((level) == 2 || (level) == 3) \
- dev_info(&cam->dev, fmt "\n", ## args); \
+ v4l2_info(&cam->v4l2_dev, fmt "\n", ## args); \
else if ((level) == 4) \
- dev_warn(&cam->dev, fmt "\n", ## args); \
+ v4l2_warn(&cam->v4l2_dev, fmt "\n", ## args); \
else if ((level) >= 5) \
- dev_info(&cam->dev, "[%s:%d] " fmt "\n", \
- __func__, __LINE__ , ## args); \
+ v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", \
+ __func__, __LINE__ , ## args); \
} \
}
/* For generic kernel (not device specific) messages */
@@ -321,7 +325,7 @@ struct w9968cf_device {
#undef PDBG
#define PDBG(fmt, args...) \
-dev_info(&cam->dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args);
+v4l2_info(&cam->v4l2_dev, "[%s:%d] " fmt "\n", __func__, __LINE__ , ## args);
#undef PDBGG
#define PDBGG(fmt, args...) do {;} while(0); /* nothing: it's a placeholder */
diff --git a/drivers/media/video/wm8739.c b/drivers/media/video/wm8739.c
index f2864d5cd18..b572ce288e1 100644
--- a/drivers/media/video/wm8739.c
+++ b/drivers/media/video/wm8739.c
@@ -252,11 +252,6 @@ static int wm8739_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops wm8739_core_ops = {
@@ -343,8 +338,6 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "wm8739",
- .driverid = I2C_DRIVERID_WM8739,
- .command = wm8739_command,
.probe = wm8739_probe,
.remove = wm8739_remove,
.id_table = wm8739_id,
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index 53fcd42843e..eddf11abe1d 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -34,15 +34,12 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
MODULE_DESCRIPTION("wm8775 driver");
MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
MODULE_LICENSE("GPL");
-static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
-
-I2C_CLIENT_INSMOD;
/* ----------------------------------------------------------------------- */
@@ -161,11 +158,6 @@ static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fre
return 0;
}
-static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops wm8775_core_ops = {
@@ -268,8 +260,6 @@ MODULE_DEVICE_TABLE(i2c, wm8775_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "wm8775",
- .driverid = I2C_DRIVERID_WM8775,
- .command = wm8775_command,
.probe = wm8775_probe,
.remove = wm8775_remove,
.id_table = wm8775_id,
diff --git a/drivers/media/video/zc0301/zc0301_sensor.h b/drivers/media/video/zc0301/zc0301_sensor.h
index b0cd49c438a..3a408de91b9 100644
--- a/drivers/media/video/zc0301/zc0301_sensor.h
+++ b/drivers/media/video/zc0301/zc0301_sensor.h
@@ -58,12 +58,20 @@ zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
.idProduct = (prod), \
.bInterfaceClass = (intclass)
+#if !defined CONFIG_USB_GSPCA && !defined CONFIG_USB_GSPCA_MODULE
#define ZC0301_ID_TABLE \
static const struct usb_device_id zc0301_id_table[] = { \
{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
{ ZC0301_USB_DEVICE(0x0ac8, 0x303b, 0xff), }, /* PB-0330 */ \
{ } \
};
+#else
+#define ZC0301_ID_TABLE \
+static const struct usb_device_id zc0301_id_table[] = { \
+ { ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202 */ \
+ { } \
+};
+#endif
/*****************************************************************************/
diff --git a/drivers/media/video/zoran/Kconfig b/drivers/media/video/zoran/Kconfig
index 8666e19f31a..fd4120e4c10 100644
--- a/drivers/media/video/zoran/Kconfig
+++ b/drivers/media/video/zoran/Kconfig
@@ -1,6 +1,6 @@
config VIDEO_ZORAN
tristate "Zoran ZR36057/36067 Video For Linux"
- depends on PCI && I2C_ALGOBIT && VIDEO_V4L1 && VIRT_TO_BUS
+ depends on PCI && I2C_ALGOBIT && VIDEO_V4L2 && VIRT_TO_BUS
help
Say Y for support for MJPEG capture cards based on the Zoran
36057/36067 PCI controller chipset. This includes the Iomega
@@ -32,7 +32,7 @@ config VIDEO_ZORAN_ZR36060
config VIDEO_ZORAN_BUZ
tristate "Iomega Buz support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_SAA7185 if VIDEO_HELPER_CHIPS_AUTO
help
Support for the Iomega Buz MJPEG capture/playback card.
@@ -58,7 +58,7 @@ config VIDEO_ZORAN_LML33
config VIDEO_ZORAN_LML33R10
tristate "Linux Media Labs LML33R10 support"
depends on VIDEO_ZORAN_ZR36060
- select VIDEO_SAA7114 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_ADV7170 if VIDEO_HELPER_CHIPS_AUTO
help
support for the Linux Media Labs LML33R10 MJPEG capture/playback
@@ -66,7 +66,7 @@ config VIDEO_ZORAN_LML33R10
config VIDEO_ZORAN_AVS6EYES
tristate "AverMedia 6 Eyes support (EXPERIMENTAL)"
- depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL && VIDEO_V4L1
+ depends on VIDEO_ZORAN_ZR36060 && EXPERIMENTAL
select VIDEO_BT856 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_BT866 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_KS0127 if VIDEO_HELPER_CHIPS_AUTO
diff --git a/drivers/media/video/zoran/videocodec.h b/drivers/media/video/zoran/videocodec.h
index 97a3bbeda50..5c27b251354 100644
--- a/drivers/media/video/zoran/videocodec.h
+++ b/drivers/media/video/zoran/videocodec.h
@@ -97,7 +97,7 @@
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_*)
+ the norm param is defined in videodev2.h (V4L2_STD_*)
additional setup may be available, too - but the codec should work with
some default values even without this
@@ -144,9 +144,8 @@ M zr36055[1] 0001 0000c001 00000000 (zr36050[1])
#ifndef __LINUX_VIDEOCODEC_H
#define __LINUX_VIDEOCODEC_H
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
-//should be in videodev.h ??? (VID_DO_....)
#define CODEC_DO_COMPRESSION 0
#define CODEC_DO_EXPANSION 1
@@ -237,10 +236,6 @@ struct vfe_settings {
__u32 width, height; /* Area to capture */
__u16 decimation; /* Decimation divider */
__u16 flags; /* Flags for capture */
-/* flags are the same as in struct video_capture - see videodev.h:
-#define VIDEO_CAPTURE_ODD 0
-#define VIDEO_CAPTURE_EVEN 1
-*/
__u16 quality; /* quality of the video */
};
diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h
index e873a916250..afecf32f1a8 100644
--- a/drivers/media/video/zoran/zoran.h
+++ b/drivers/media/video/zoran/zoran.h
@@ -31,6 +31,8 @@
#ifndef _BUZ_H_
#define _BUZ_H_
+#include <media/v4l2-device.h>
+
struct zoran_requestbuffers {
unsigned long count; /* Number of buffers for MJPEG grabbing */
unsigned long size; /* Size PER BUFFER in bytes */
@@ -170,7 +172,7 @@ Private IOCTL to set up for displaying MJPEG
#endif
#define V4L_MASK_FRAME (V4L_MAX_FRAME - 1)
-#define MAX_KMALLOC_MEM (128*1024)
+#define MAX_FRAME (BUZ_MAX_FRAME > VIDEO_MAX_FRAME ? BUZ_MAX_FRAME : VIDEO_MAX_FRAME)
#include "zr36057.h"
@@ -240,9 +242,6 @@ enum gpcs_type {
struct zoran_format {
char *name;
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
- int palette;
-#endif
__u32 fourcc;
int colorspace;
int depth;
@@ -283,21 +282,21 @@ struct zoran_mapping {
int count;
};
-struct zoran_jpg_buffer {
- struct zoran_mapping *map;
- __le32 *frag_tab; /* addresses of frag table */
- u32 frag_tab_bus; /* same value cached to save time in ISR */
- enum zoran_buffer_state state; /* non-zero if corresponding buffer is in use in grab queue */
- struct zoran_sync bs; /* DONE: info to return to application */
-};
-
-struct zoran_v4l_buffer {
+struct zoran_buffer {
struct zoran_mapping *map;
- char *fbuffer; /* virtual address of frame buffer */
- unsigned long fbuffer_phys; /* physical address of frame buffer */
- unsigned long fbuffer_bus; /* bus address of frame buffer */
- enum zoran_buffer_state state; /* state: unused/pending/done */
- struct zoran_sync bs; /* DONE: info to return to application */
+ enum zoran_buffer_state state; /* state: unused/pending/dma/done */
+ struct zoran_sync bs; /* DONE: info to return to application */
+ union {
+ struct {
+ __le32 *frag_tab; /* addresses of frag table */
+ u32 frag_tab_bus; /* same value cached to save time in ISR */
+ } jpg;
+ struct {
+ char *fbuffer; /* virtual address of frame buffer */
+ unsigned long fbuffer_phys;/* physical address of frame buffer */
+ unsigned long fbuffer_bus;/* bus address of frame buffer */
+ } v4l;
+ };
};
enum zoran_lock_activity {
@@ -307,21 +306,13 @@ enum zoran_lock_activity {
};
/* buffer collections */
-struct zoran_jpg_struct {
+struct zoran_buffer_col {
enum zoran_lock_activity active; /* feature currently in use? */
- struct zoran_jpg_buffer buffer[BUZ_MAX_FRAME]; /* buffers */
- int num_buffers, buffer_size;
+ unsigned int num_buffers, buffer_size;
+ struct zoran_buffer buffer[MAX_FRAME]; /* buffers */
u8 allocated; /* Flag if buffers are allocated */
- u8 ready_to_be_freed; /* hack - see zoran_driver.c */
u8 need_contiguous; /* Flag if contiguous buffers are needed */
-};
-
-struct zoran_v4l_struct {
- enum zoran_lock_activity active; /* feature currently in use? */
- struct zoran_v4l_buffer buffer[VIDEO_MAX_FRAME]; /* buffers */
- int num_buffers, buffer_size;
- u8 allocated; /* Flag if buffers are allocated */
- u8 ready_to_be_freed; /* hack - see zoran_driver.c */
+ /* only applies to jpg buffers, raw buffers are always contiguous */
};
struct zoran;
@@ -330,23 +321,27 @@ struct zoran;
struct zoran_fh {
struct zoran *zr;
- enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
+ enum zoran_map_mode map_mode; /* Flag which bufferset will map by next mmap() */
struct zoran_overlay_settings overlay_settings;
- u32 *overlay_mask; /* overlay mask */
- enum zoran_lock_activity overlay_active; /* feature currently in use? */
+ u32 *overlay_mask; /* overlay mask */
+ enum zoran_lock_activity overlay_active;/* feature currently in use? */
- struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
- struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
+ struct zoran_buffer_col buffers; /* buffers' info */
+ struct zoran_v4l_settings v4l_settings; /* structure with a lot of things to play with */
struct zoran_jpg_settings jpg_settings; /* structure with a lot of things to play with */
- struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
};
struct card_info {
enum card_type type;
char name[32];
- u16 i2c_decoder, i2c_encoder; /* I2C types */
+ const char *i2c_decoder; /* i2c decoder device */
+ const char *mod_decoder; /* i2c decoder module */
+ const unsigned short *addrs_decoder;
+ const char *i2c_encoder; /* i2c encoder device */
+ const char *mod_encoder; /* i2c encoder module */
+ const unsigned short *addrs_encoder;
u16 video_vfe, video_codec; /* videocodec types */
u16 audio_chip; /* audio type */
@@ -356,7 +351,7 @@ struct card_info {
char name[32];
} input[BUZ_MAX_INPUT];
- int norms;
+ v4l2_std_id norms;
struct tvnorm *tvn[3]; /* supported TV norms */
u32 jpeg_int; /* JPEG interrupt */
@@ -377,14 +372,15 @@ struct card_info {
};
struct zoran {
+ struct v4l2_device v4l2_dev;
struct video_device *video_dev;
struct i2c_adapter i2c_adapter; /* */
struct i2c_algo_bit_data i2c_algo; /* */
u32 i2cbr;
- struct i2c_client *decoder; /* video decoder i2c client */
- struct i2c_client *encoder; /* video encoder i2c client */
+ struct v4l2_subdev *decoder; /* video decoder sub-device */
+ struct v4l2_subdev *encoder; /* video encoder sub-device */
struct videocodec *codec; /* video codec */
struct videocodec *vfe; /* video front end */
@@ -405,9 +401,15 @@ struct zoran {
spinlock_t spinlock; /* Spinlock */
/* Video for Linux parameters */
- int input, norm; /* card's norm and input - norm=VIDEO_MODE_* */
- int hue, saturation, contrast, brightness; /* Current picture params */
- struct video_buffer buffer; /* Current buffer params */
+ int input; /* card's norm and input - norm=VIDEO_MODE_* */
+ v4l2_std_id norm;
+
+ /* Current buffer params */
+ void *vbuf_base;
+ int vbuf_height, vbuf_width;
+ int vbuf_depth;
+ int vbuf_bytesperline;
+
struct zoran_overlay_settings overlay_settings;
u32 *overlay_mask; /* overlay mask */
enum zoran_lock_activity overlay_active; /* feature currently in use? */
@@ -427,7 +429,7 @@ struct zoran {
unsigned long v4l_pend_tail;
unsigned long v4l_sync_tail;
int v4l_pend[V4L_MAX_FRAME];
- struct zoran_v4l_struct v4l_buffers; /* V4L buffers' info */
+ struct zoran_buffer_col v4l_buffers; /* V4L buffers' info */
/* Buz MJPEG parameters */
enum zoran_codec_mode codec_mode; /* status of codec */
@@ -454,7 +456,7 @@ struct zoran {
int jpg_pend[BUZ_MAX_FRAME];
/* array indexed by frame number */
- struct zoran_jpg_struct jpg_buffers; /* MJPEG buffers' info */
+ struct zoran_buffer_col jpg_buffers; /* MJPEG buffers' info */
/* Additional stuff for testing */
#ifdef CONFIG_PROC_FS
@@ -488,6 +490,11 @@ struct zoran {
wait_queue_head_t test_q;
};
+static inline struct zoran *to_zoran(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct zoran, v4l2_dev);
+}
+
/* There was something called _ALPHA_BUZ that used the PCI address instead of
* the kernel iomapped address for btread/btwrite. */
#define btwrite(dat,adr) writel((dat), zr->zr36057_mem+(adr))
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 5d2f090aa0f..f91bba435ed 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -38,8 +38,7 @@
#include <linux/proc_fs.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
+#include <linux/videodev2.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
#include <linux/kmod.h>
@@ -47,11 +46,10 @@
#include <linux/pci.h>
#include <linux/interrupt.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
#include <linux/mutex.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
+#include <media/v4l2-common.h>
+#include <media/bt819.h>
#include "videocodec.h"
#include "zoran.h"
@@ -108,25 +106,8 @@ static int video_nr[BUZ_MAX] = { [0 ... (BUZ_MAX-1)] = -1 };
module_param_array(video_nr, int, NULL, 0444);
MODULE_PARM_DESC(video_nr, "Video device number (-1=Auto)");
-/*
- Number and size of grab buffers for Video 4 Linux
- The vast majority of applications should not need more than 2,
- the very popular BTTV driver actually does ONLY have 2.
- Time sensitive applications might need more, the maximum
- is VIDEO_MAX_FRAME (defined in <linux/videodev.h>).
-
- The size is set so that the maximum possible request
- can be satisfied. Decrease it, if bigphys_area alloc'd
- memory is low. If you don't have the bigphys_area patch,
- set it to 128 KB. Will you allow only to grab small
- images with V4L, but that's better than nothing.
-
- v4l_bufsize has to be given in KB !
-
-*/
-
-int v4l_nbufs = 2;
-int v4l_bufsize = 128; /* Everybody should be able to work with this setting */
+int v4l_nbufs = 4;
+int v4l_bufsize = 864; /* Everybody should be able to work with this setting */
module_param(v4l_nbufs, int, 0644);
MODULE_PARM_DESC(v4l_nbufs, "Maximum number of V4L buffers to use");
module_param(v4l_bufsize, int, 0644);
@@ -273,7 +254,7 @@ zr36016_write (struct videocodec *codec,
static void
dc10_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: dc10_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
/* Pixel clock selection */
GPIO(zr, 4, 0);
@@ -285,13 +266,13 @@ dc10_init (struct zoran *zr)
static void
dc10plus_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: dc10plus_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
}
static void
buz_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: buz_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
/* some stuff from Iomega */
pci_write_config_dword(zr->pci_dev, 0xfc, 0x90680f15);
@@ -302,7 +283,7 @@ buz_init (struct zoran *zr)
static void
lml33_init (struct zoran *zr)
{
- dprintk(3, KERN_DEBUG "%s: lml33_init()\n", ZR_DEVNAME(zr));
+ dprintk(3, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
GPIO(zr, 2, 1); // Set Composite input/output
}
@@ -332,50 +313,6 @@ avs6eyes_init (struct zoran *zr)
}
static char *
-i2cid_to_modulename (u16 i2c_id)
-{
- char *name = NULL;
-
- switch (i2c_id) {
- case I2C_DRIVERID_SAA7110:
- name = "saa7110";
- break;
- case I2C_DRIVERID_SAA7111A:
- name = "saa7111";
- break;
- case I2C_DRIVERID_SAA7114:
- name = "saa7114";
- break;
- case I2C_DRIVERID_SAA7185B:
- name = "saa7185";
- break;
- case I2C_DRIVERID_ADV7170:
- name = "adv7170";
- break;
- case I2C_DRIVERID_ADV7175:
- name = "adv7175";
- break;
- case I2C_DRIVERID_BT819:
- name = "bt819";
- break;
- case I2C_DRIVERID_BT856:
- name = "bt856";
- break;
- case I2C_DRIVERID_BT866:
- name = "bt866";
- break;
- case I2C_DRIVERID_VPX3220:
- name = "vpx3220";
- break;
- case I2C_DRIVERID_KS0127:
- name = "ks0127";
- break;
- }
-
- return name;
-}
-
-static char *
codecid_to_modulename (u16 codecid)
{
char *name = NULL;
@@ -425,11 +362,24 @@ static struct tvnorm f60ccir601_lm33r10 = { 858, 720, 56+54, 788, 525, 480, 16 }
static struct tvnorm f50ccir601_avs6eyes = { 864, 720, 74, 804, 625, 576, 18 };
static struct tvnorm f60ccir601_avs6eyes = { 858, 720, 56, 788, 525, 480, 16 };
+static const unsigned short vpx3220_addrs[] = { 0x43, 0x47, I2C_CLIENT_END };
+static const unsigned short saa7110_addrs[] = { 0x4e, 0x4f, I2C_CLIENT_END };
+static const unsigned short saa7111_addrs[] = { 0x25, 0x24, I2C_CLIENT_END };
+static const unsigned short saa7114_addrs[] = { 0x21, 0x20, I2C_CLIENT_END };
+static const unsigned short adv717x_addrs[] = { 0x6a, 0x6b, 0x2a, 0x2b, I2C_CLIENT_END };
+static const unsigned short ks0127_addrs[] = { 0x6c, 0x6d, I2C_CLIENT_END };
+static const unsigned short saa7185_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt819_addrs[] = { 0x45, I2C_CLIENT_END };
+static const unsigned short bt856_addrs[] = { 0x44, I2C_CLIENT_END };
+static const unsigned short bt866_addrs[] = { 0x44, I2C_CLIENT_END };
+
static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{
.type = DC10_old,
.name = "DC10(old)",
- .i2c_decoder = I2C_DRIVERID_VPX3220,
+ .i2c_decoder = "vpx3220a",
+ .mod_decoder = "vpx3220",
+ .addrs_decoder = vpx3220_addrs,
.video_codec = CODEC_TYPE_ZR36050,
.video_vfe = CODEC_TYPE_ZR36016,
@@ -439,7 +389,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
@@ -457,8 +407,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC10_new,
.name = "DC10(new)",
- .i2c_decoder = I2C_DRIVERID_SAA7110,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "saa7110",
+ .mod_decoder = "saa7110",
+ .addrs_decoder = saa7110_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 3,
@@ -467,7 +421,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 7, "S-Video" },
{ 5, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel,
&f60sqpixel,
@@ -484,8 +438,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC10plus,
.name = "DC10plus",
- .i2c_decoder = I2C_DRIVERID_SAA7110,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "saa7110",
+ .mod_decoder = "saa7110",
+ .addrs_decoder = saa7110_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 3,
@@ -494,7 +452,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 7, "S-Video" },
{ 5, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel,
&f60sqpixel,
@@ -512,8 +470,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC30,
.name = "DC30",
- .i2c_decoder = I2C_DRIVERID_VPX3220,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "vpx3220a",
+ .mod_decoder = "vpx3220",
+ .addrs_decoder = vpx3220_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36050,
.video_vfe = CODEC_TYPE_ZR36016,
@@ -523,7 +485,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
@@ -541,8 +503,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = DC30plus,
.name = "DC30plus",
- .i2c_decoder = I2C_DRIVERID_VPX3220,
- .i2c_encoder = I2C_DRIVERID_ADV7175,
+ .i2c_decoder = "vpx3220a",
+ .mod_decoder = "vpx3220",
+ .addrs_decoder = vpx3220_addrs,
+ .i2c_encoder = "adv7175",
+ .mod_encoder = "adv7175",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36050,
.video_vfe = CODEC_TYPE_ZR36016,
@@ -552,7 +518,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 2, "S-Video" },
{ 0, "Internal/comp" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50sqpixel_dc10,
&f60sqpixel_dc10,
@@ -570,8 +536,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33,
.name = "LML33",
- .i2c_decoder = I2C_DRIVERID_BT819,
- .i2c_encoder = I2C_DRIVERID_BT856,
+ .i2c_decoder = "bt819a",
+ .mod_decoder = "bt819",
+ .addrs_decoder = bt819_addrs,
+ .i2c_encoder = "bt856",
+ .mod_encoder = "bt856",
+ .addrs_encoder = bt856_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 2,
@@ -579,7 +549,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 0, "Composite" },
{ 7, "S-Video" }
},
- .norms = 2,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_lml33,
&f60ccir601_lml33,
@@ -597,8 +567,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = LML33R10,
.name = "LML33R10",
- .i2c_decoder = I2C_DRIVERID_SAA7114,
- .i2c_encoder = I2C_DRIVERID_ADV7170,
+ .i2c_decoder = "saa7114",
+ .mod_decoder = "saa7115",
+ .addrs_decoder = saa7114_addrs,
+ .i2c_encoder = "adv7170",
+ .mod_encoder = "adv7170",
+ .addrs_encoder = adv717x_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 2,
@@ -606,7 +580,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 0, "Composite" },
{ 7, "S-Video" }
},
- .norms = 2,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_lm33r10,
&f60ccir601_lm33r10,
@@ -624,8 +598,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
}, {
.type = BUZ,
.name = "Buz",
- .i2c_decoder = I2C_DRIVERID_SAA7111A,
- .i2c_encoder = I2C_DRIVERID_SAA7185B,
+ .i2c_decoder = "saa7111",
+ .mod_decoder = "saa7115",
+ .addrs_decoder = saa7111_addrs,
+ .i2c_encoder = "saa7185",
+ .mod_encoder = "saa7185",
+ .addrs_encoder = saa7185_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 2,
@@ -633,7 +611,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{ 3, "Composite" },
{ 7, "S-Video" }
},
- .norms = 3,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL|V4L2_STD_SECAM,
.tvn = {
&f50ccir601,
&f60ccir601,
@@ -653,8 +631,12 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
.name = "6-Eyes",
/* AverMedia chose not to brand the 6-Eyes. Thus it
can't be autodetected, and requires card=x. */
- .i2c_decoder = I2C_DRIVERID_KS0127,
- .i2c_encoder = I2C_DRIVERID_BT866,
+ .i2c_decoder = "ks0127",
+ .mod_decoder = "ks0127",
+ .addrs_decoder = ks0127_addrs,
+ .i2c_encoder = "bt866",
+ .mod_encoder = "bt866",
+ .addrs_encoder = bt866_addrs,
.video_codec = CODEC_TYPE_ZR36060,
.inputs = 10,
@@ -670,7 +652,7 @@ static struct card_info zoran_cards[NUM_CARDS] __devinitdata = {
{10, "S-Video 3" },
{15, "YCbCr" }
},
- .norms = 2,
+ .norms = V4L2_STD_NTSC|V4L2_STD_PAL,
.tvn = {
&f50ccir601_avs6eyes,
&f60ccir601_avs6eyes,
@@ -735,69 +717,6 @@ zoran_i2c_setscl (void *data,
btwrite(zr->i2cbr, ZR36057_I2CBR);
}
-static int
-zoran_i2c_client_register (struct i2c_client *client)
-{
- struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
- int res = 0;
-
- dprintk(2,
- KERN_DEBUG "%s: i2c_client_register() - driver id = %d\n",
- ZR_DEVNAME(zr), client->driver->id);
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->user > 0) {
- /* we're already busy, so we keep a reference to
- * them... Could do a lot of stuff here, but this
- * is easiest. (Did I ever mention I'm a lazy ass?)
- */
- res = -EBUSY;
- goto clientreg_unlock_and_return;
- }
-
- if (client->driver->id == zr->card.i2c_decoder)
- zr->decoder = client;
- else if (client->driver->id == zr->card.i2c_encoder)
- zr->encoder = client;
- else {
- res = -ENODEV;
- goto clientreg_unlock_and_return;
- }
-
-clientreg_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
-}
-
-static int
-zoran_i2c_client_unregister (struct i2c_client *client)
-{
- struct zoran *zr = (struct zoran *) i2c_get_adapdata(client->adapter);
- int res = 0;
-
- dprintk(2, KERN_DEBUG "%s: i2c_client_unregister()\n", ZR_DEVNAME(zr));
-
- mutex_lock(&zr->resource_lock);
-
- if (zr->user > 0) {
- res = -EBUSY;
- goto clientunreg_unlock_and_return;
- }
-
- /* try to locate it */
- if (client == zr->encoder) {
- zr->encoder = NULL;
- } else if (client == zr->decoder) {
- zr->decoder = NULL;
- snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%d]", zr->id);
- }
-clientunreg_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
-}
-
static const struct i2c_algo_bit_data zoran_i2c_bit_data_template = {
.setsda = zoran_i2c_setsda,
.setscl = zoran_i2c_setscl,
@@ -813,13 +732,10 @@ zoran_register_i2c (struct zoran *zr)
memcpy(&zr->i2c_algo, &zoran_i2c_bit_data_template,
sizeof(struct i2c_algo_bit_data));
zr->i2c_algo.data = zr;
- zr->i2c_adapter.class = I2C_CLASS_TV_ANALOG;
zr->i2c_adapter.id = I2C_HW_B_ZR36067;
- zr->i2c_adapter.client_register = zoran_i2c_client_register;
- zr->i2c_adapter.client_unregister = zoran_i2c_client_unregister;
strlcpy(zr->i2c_adapter.name, ZR_DEVNAME(zr),
sizeof(zr->i2c_adapter.name));
- i2c_set_adapdata(&zr->i2c_adapter, zr);
+ i2c_set_adapdata(&zr->i2c_adapter, &zr->v4l2_dev);
zr->i2c_adapter.algo_data = &zr->i2c_algo;
zr->i2c_adapter.dev.parent = &zr->pci_dev->dev;
return i2c_bit_add_bus(&zr->i2c_adapter);
@@ -835,19 +751,20 @@ zoran_unregister_i2c (struct zoran *zr)
int
zoran_check_jpg_settings (struct zoran *zr,
- struct zoran_jpg_settings *settings)
+ struct zoran_jpg_settings *settings,
+ int try)
{
int err = 0, err0 = 0;
dprintk(4,
KERN_DEBUG
- "%s: check_jpg_settings() - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
- ZR_DEVNAME(zr), settings->decimation, settings->HorDcm,
+ "%s: %s - dec: %d, Hdcm: %d, Vdcm: %d, Tdcm: %d\n",
+ ZR_DEVNAME(zr), __func__, settings->decimation, settings->HorDcm,
settings->VerDcm, settings->TmpDcm);
dprintk(4,
KERN_DEBUG
- "%s: check_jpg_settings() - x: %d, y: %d, w: %d, y: %d\n",
- ZR_DEVNAME(zr), settings->img_x, settings->img_y,
+ "%s: %s - x: %d, y: %d, w: %d, y: %d\n",
+ ZR_DEVNAME(zr), __func__, settings->img_x, settings->img_y,
settings->img_width, settings->img_height);
/* Check decimation, set default values for decimation = 1, 2, 4 */
switch (settings->decimation) {
@@ -879,8 +796,8 @@ zoran_check_jpg_settings (struct zoran *zr,
if (zr->card.type == DC10_new) {
dprintk(1,
KERN_DEBUG
- "%s: check_jpg_settings() - HDec by 4 is not supported on the DC10\n",
- ZR_DEVNAME(zr));
+ "%s: %s - HDec by 4 is not supported on the DC10\n",
+ ZR_DEVNAME(zr), __func__);
err0++;
break;
}
@@ -900,50 +817,73 @@ zoran_check_jpg_settings (struct zoran *zr,
/* We have to check the data the user has set */
if (settings->HorDcm != 1 && settings->HorDcm != 2 &&
- (zr->card.type == DC10_new || settings->HorDcm != 4))
+ (zr->card.type == DC10_new || settings->HorDcm != 4)) {
+ settings->HorDcm = clamp(settings->HorDcm, 1, 2);
err0++;
- if (settings->VerDcm != 1 && settings->VerDcm != 2)
+ }
+ if (settings->VerDcm != 1 && settings->VerDcm != 2) {
+ settings->VerDcm = clamp(settings->VerDcm, 1, 2);
err0++;
- if (settings->TmpDcm != 1 && settings->TmpDcm != 2)
+ }
+ if (settings->TmpDcm != 1 && settings->TmpDcm != 2) {
+ settings->TmpDcm = clamp(settings->TmpDcm, 1, 2);
err0++;
+ }
if (settings->field_per_buff != 1 &&
- settings->field_per_buff != 2)
+ settings->field_per_buff != 2) {
+ settings->field_per_buff = clamp(settings->field_per_buff, 1, 2);
err0++;
- if (settings->img_x < 0)
+ }
+ if (settings->img_x < 0) {
+ settings->img_x = 0;
err0++;
- if (settings->img_y < 0)
+ }
+ if (settings->img_y < 0) {
+ settings->img_y = 0;
err0++;
- if (settings->img_width < 0)
+ }
+ if (settings->img_width < 0 || settings->img_width > BUZ_MAX_WIDTH) {
+ settings->img_width = clamp(settings->img_width, 0, (int)BUZ_MAX_WIDTH);
err0++;
- if (settings->img_height < 0)
+ }
+ if (settings->img_height < 0 || settings->img_height > BUZ_MAX_HEIGHT / 2) {
+ settings->img_height = clamp(settings->img_height, 0, BUZ_MAX_HEIGHT / 2);
err0++;
- if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH)
+ }
+ if (settings->img_x + settings->img_width > BUZ_MAX_WIDTH) {
+ settings->img_x = BUZ_MAX_WIDTH - settings->img_width;
err0++;
- if (settings->img_y + settings->img_height >
- BUZ_MAX_HEIGHT / 2)
+ }
+ if (settings->img_y + settings->img_height > BUZ_MAX_HEIGHT / 2) {
+ settings->img_y = BUZ_MAX_HEIGHT / 2 - settings->img_height;
+ err0++;
+ }
+ if (settings->img_width % (16 * settings->HorDcm) != 0) {
+ settings->img_width -= settings->img_width % (16 * settings->HorDcm);
+ if (settings->img_width == 0)
+ settings->img_width = 16 * settings->HorDcm;
+ err0++;
+ }
+ if (settings->img_height % (8 * settings->VerDcm) != 0) {
+ settings->img_height -= settings->img_height % (8 * settings->VerDcm);
+ if (settings->img_height == 0)
+ settings->img_height = 8 * settings->VerDcm;
err0++;
- if (settings->HorDcm && settings->VerDcm) {
- if (settings->img_width %
- (16 * settings->HorDcm) != 0)
- err0++;
- if (settings->img_height %
- (8 * settings->VerDcm) != 0)
- err0++;
}
- if (err0) {
+ if (!try && err0) {
dprintk(1,
KERN_ERR
- "%s: check_jpg_settings() - error in params for decimation = 0\n",
- ZR_DEVNAME(zr));
+ "%s: %s - error in params for decimation = 0\n",
+ ZR_DEVNAME(zr), __func__);
err++;
}
break;
default:
dprintk(1,
KERN_ERR
- "%s: check_jpg_settings() - decimation = %d, must be 0, 1, 2 or 4\n",
- ZR_DEVNAME(zr), settings->decimation);
+ "%s: %s - decimation = %d, must be 0, 1, 2 or 4\n",
+ ZR_DEVNAME(zr), __func__, settings->decimation);
err++;
break;
}
@@ -1021,12 +961,10 @@ zoran_open_init_params (struct zoran *zr)
sizeof(zr->jpg_settings.jpg_comp.COM_data));
zr->jpg_settings.jpg_comp.jpeg_markers =
JPEG_MARKER_DHT | JPEG_MARKER_DQT;
- i = zoran_check_jpg_settings(zr, &zr->jpg_settings);
+ i = zoran_check_jpg_settings(zr, &zr->jpg_settings, 0);
if (i)
- dprintk(1,
- KERN_ERR
- "%s: zoran_open_init_params() internal error\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s internal error\n",
+ ZR_DEVNAME(zr), __func__);
clear_interrupt_counters(zr);
zr->testing = 0;
@@ -1062,13 +1000,11 @@ static int __devinit
zr36057_init (struct zoran *zr)
{
int j, err;
- int two = 2;
- int zero = 0;
dprintk(1,
KERN_INFO
- "%s: zr36057_init() - initializing card[%d], zr=%p\n",
- ZR_DEVNAME(zr), zr->id, zr);
+ "%s: %s - initializing card[%d], zr=%p\n",
+ ZR_DEVNAME(zr), __func__, zr->id, zr);
/* default setup of all parameters which will persist between opens */
zr->user = 0;
@@ -1079,24 +1015,32 @@ zr36057_init (struct zoran *zr)
zr->jpg_buffers.allocated = 0;
zr->v4l_buffers.allocated = 0;
- zr->buffer.base = (void *) vidmem;
- zr->buffer.width = 0;
- zr->buffer.height = 0;
- zr->buffer.depth = 0;
- zr->buffer.bytesperline = 0;
+ zr->vbuf_base = (void *) vidmem;
+ zr->vbuf_width = 0;
+ zr->vbuf_height = 0;
+ zr->vbuf_depth = 0;
+ zr->vbuf_bytesperline = 0;
/* Avoid nonsense settings from user for default input/norm */
- if (default_norm < VIDEO_MODE_PAL &&
- default_norm > VIDEO_MODE_SECAM)
- default_norm = VIDEO_MODE_PAL;
- zr->norm = default_norm;
- if (!(zr->timing = zr->card.tvn[zr->norm])) {
+ if (default_norm < 0 && default_norm > 2)
+ default_norm = 0;
+ if (default_norm == 0) {
+ zr->norm = V4L2_STD_PAL;
+ zr->timing = zr->card.tvn[0];
+ } else if (default_norm == 1) {
+ zr->norm = V4L2_STD_NTSC;
+ zr->timing = zr->card.tvn[1];
+ } else {
+ zr->norm = V4L2_STD_SECAM;
+ zr->timing = zr->card.tvn[2];
+ }
+ if (zr->timing == NULL) {
dprintk(1,
KERN_WARNING
- "%s: zr36057_init() - default TV standard not supported by hardware. PAL will be used.\n",
- ZR_DEVNAME(zr));
- zr->norm = VIDEO_MODE_PAL;
- zr->timing = zr->card.tvn[zr->norm];
+ "%s: %s - default TV standard not supported by hardware. PAL will be used.\n",
+ ZR_DEVNAME(zr), __func__);
+ zr->norm = V4L2_STD_PAL;
+ zr->timing = zr->card.tvn[0];
}
if (default_input > zr->card.inputs-1) {
@@ -1108,12 +1052,6 @@ zr36057_init (struct zoran *zr)
}
zr->input = default_input;
- /* Should the following be reset at every open ? */
- zr->hue = 32768;
- zr->contrast = 32768;
- zr->saturation = 32768;
- zr->brightness = 32768;
-
/* default setup (will be repeated at every open) */
zoran_open_init_params(zr);
@@ -1124,8 +1062,8 @@ zr36057_init (struct zoran *zr)
if (!zr->stat_com || !zr->video_dev) {
dprintk(1,
KERN_ERR
- "%s: zr36057_init() - kmalloc (STAT_COM) failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - kmalloc (STAT_COM) failed\n",
+ ZR_DEVNAME(zr), __func__);
err = -ENOMEM;
goto exit_free;
}
@@ -1137,6 +1075,7 @@ zr36057_init (struct zoran *zr)
* Now add the template and register the device unit.
*/
memcpy(zr->video_dev, &zoran_template, sizeof(zoran_template));
+ zr->video_dev->parent = &zr->pci_dev->dev;
strcpy(zr->video_dev->name, ZR_DEVNAME(zr));
err = video_register_device(zr->video_dev, VFL_TYPE_GRABBER, video_nr[zr->id]);
if (err < 0)
@@ -1148,8 +1087,10 @@ zr36057_init (struct zoran *zr)
detect_guest_activity(zr);
test_interrupts(zr);
if (!pass_through) {
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
- encoder_command(zr, ENCODER_SET_INPUT, &two);
+ struct v4l2_routing route = { 2, 0 };
+
+ decoder_call(zr, video, s_stream, 0);
+ encoder_call(zr, video, s_routing, &route);
}
zr->zoran_proc = NULL;
@@ -1164,7 +1105,8 @@ exit_free:
static void __devexit zoran_remove(struct pci_dev *pdev)
{
- struct zoran *zr = pci_get_drvdata(pdev);
+ struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+ struct zoran *zr = to_zoran(v4l2_dev);
if (!zr->initialized)
goto exit_free;
@@ -1197,7 +1139,7 @@ static void __devexit zoran_remove(struct pci_dev *pdev)
pci_disable_device(zr->pci_dev);
video_unregister_device(zr->video_dev);
exit_free:
- pci_set_drvdata(pdev, NULL);
+ v4l2_device_unregister(&zr->v4l2_dev);
kfree(zr);
}
@@ -1215,10 +1157,8 @@ zoran_setup_videocodec (struct zoran *zr,
m = kmalloc(sizeof(struct videocodec_master), GFP_KERNEL);
if (!m) {
- dprintk(1,
- KERN_ERR
- "%s: zoran_setup_videocodec() - no memory\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - no memory\n",
+ ZR_DEVNAME(zr), __func__);
return m;
}
@@ -1256,6 +1196,18 @@ zoran_setup_videocodec (struct zoran *zr,
return m;
}
+static void zoran_subdev_notify(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
+{
+ struct zoran *zr = to_zoran(sd->v4l2_dev);
+
+ /* Bt819 needs to reset its FIFO buffer using #FRST pin and
+ LML33 card uses GPIO(7) for that. */
+ if (cmd == BT819_FIFO_RESET_LOW)
+ GPIO(zr, 7, 0);
+ else if (cmd == BT819_FIFO_RESET_HIGH)
+ GPIO(zr, 7, 1);
+}
+
/*
* Scan for a Buz card (actually for the PCI controller ZR36057),
* request the irq and map the io memory
@@ -1269,34 +1221,33 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
struct videocodec_master *master_vfe = NULL;
struct videocodec_master *master_codec = NULL;
int card_num;
- char *i2c_enc_name, *i2c_dec_name, *codec_name, *vfe_name;
+ char *codec_name, *vfe_name;
unsigned int nr;
nr = zoran_num++;
if (nr >= BUZ_MAX) {
- dprintk(1,
- KERN_ERR
- "%s: driver limited to %d card(s) maximum\n",
+ dprintk(1, KERN_ERR "%s: driver limited to %d card(s) maximum\n",
ZORAN_NAME, BUZ_MAX);
return -ENOENT;
}
zr = kzalloc(sizeof(struct zoran), GFP_KERNEL);
if (!zr) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - kzalloc failed\n",
- ZORAN_NAME);
+ dprintk(1, KERN_ERR "%s: %s - kzalloc failed\n",
+ ZORAN_NAME, __func__);
return -ENOMEM;
}
+ zr->v4l2_dev.notify = zoran_subdev_notify;
+ if (v4l2_device_register(&pdev->dev, &zr->v4l2_dev))
+ goto zr_free_mem;
zr->pci_dev = pdev;
zr->id = nr;
snprintf(ZR_DEVNAME(zr), sizeof(ZR_DEVNAME(zr)), "MJPEG[%u]", zr->id);
spin_lock_init(&zr->spinlock);
mutex_init(&zr->resource_lock);
if (pci_enable_device(pdev))
- goto zr_free_mem;
+ goto zr_unreg;
pci_read_config_byte(zr->pci_dev, PCI_CLASS_REVISION, &zr->revision);
dprintk(1,
@@ -1323,7 +1274,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
KERN_ERR
"%s: It is not possible to auto-detect ZR36057 based cards\n",
ZR_DEVNAME(zr));
- goto zr_free_mem;
+ goto zr_unreg;
}
card_num = ent->driver_data;
@@ -1332,7 +1283,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
KERN_ERR
"%s: Unknown card, try specifying card=X module parameter\n",
ZR_DEVNAME(zr));
- goto zr_free_mem;
+ goto zr_unreg;
}
dprintk(3,
KERN_DEBUG
@@ -1345,7 +1296,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
KERN_ERR
"%s: User specified card type %d out of range (0 .. %d)\n",
ZR_DEVNAME(zr), card_num, NUM_CARDS - 1);
- goto zr_free_mem;
+ goto zr_unreg;
}
}
@@ -1360,11 +1311,9 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
zr->zr36057_mem = pci_ioremap_bar(zr->pci_dev, 0);
if (!zr->zr36057_mem) {
- dprintk(1,
- KERN_ERR
- "%s: %s() - ioremap failed\n",
+ dprintk(1, KERN_ERR "%s: %s() - ioremap failed\n",
ZR_DEVNAME(zr), __func__);
- goto zr_free_mem;
+ goto zr_unreg;
}
result = request_irq(zr->pci_dev->irq, zoran_irq,
@@ -1373,18 +1322,18 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
if (result == -EINVAL) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - bad irq number or handler\n",
- ZR_DEVNAME(zr));
+ "%s: %s - bad irq number or handler\n",
+ ZR_DEVNAME(zr), __func__);
} else if (result == -EBUSY) {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - IRQ %d busy, change your PnP config in BIOS\n",
- ZR_DEVNAME(zr), zr->pci_dev->irq);
+ "%s: %s - IRQ %d busy, change your PnP config in BIOS\n",
+ ZR_DEVNAME(zr), __func__, zr->pci_dev->irq);
} else {
dprintk(1,
KERN_ERR
- "%s: find_zr36057() - can't assign irq, error code %d\n",
- ZR_DEVNAME(zr), result);
+ "%s: %s - can't assign irq, error code %d\n",
+ ZR_DEVNAME(zr), __func__, result);
}
goto zr_unmap;
}
@@ -1394,9 +1343,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
&latency);
need_latency = zr->revision > 1 ? 32 : 48;
if (latency != need_latency) {
- dprintk(2,
- KERN_INFO
- "%s: Changing PCI latency from %d to %d\n",
+ dprintk(2, KERN_INFO "%s: Changing PCI latency from %d to %d\n",
ZR_DEVNAME(zr), latency, need_latency);
pci_write_config_byte(zr->pci_dev, PCI_LATENCY_TIMER,
need_latency);
@@ -1407,54 +1354,20 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
dprintk(2, KERN_INFO "%s: Initializing i2c bus...\n",
ZR_DEVNAME(zr));
- /* i2c decoder */
- if (decoder[zr->id] != -1) {
- i2c_dec_name = i2cid_to_modulename(decoder[zr->id]);
- zr->card.i2c_decoder = decoder[zr->id];
- } else if (zr->card.i2c_decoder != 0) {
- i2c_dec_name = i2cid_to_modulename(zr->card.i2c_decoder);
- } else {
- i2c_dec_name = NULL;
- }
-
- if (i2c_dec_name) {
- result = request_module(i2c_dec_name);
- if (result < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_dec_name, result);
- }
- }
-
- /* i2c encoder */
- if (encoder[zr->id] != -1) {
- i2c_enc_name = i2cid_to_modulename(encoder[zr->id]);
- zr->card.i2c_encoder = encoder[zr->id];
- } else if (zr->card.i2c_encoder != 0) {
- i2c_enc_name = i2cid_to_modulename(zr->card.i2c_encoder);
- } else {
- i2c_enc_name = NULL;
- }
-
- if (i2c_enc_name) {
- result = request_module(i2c_enc_name);
- if (result < 0) {
- dprintk(1,
- KERN_ERR
- "%s: failed to load module %s: %d\n",
- ZR_DEVNAME(zr), i2c_enc_name, result);
- }
- }
-
if (zoran_register_i2c(zr) < 0) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - can't initialize i2c bus\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - can't initialize i2c bus\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_free_irq;
}
+ zr->decoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
+ zr->card.mod_decoder, zr->card.i2c_decoder, zr->card.addrs_decoder);
+
+ if (zr->card.mod_encoder)
+ zr->encoder = v4l2_i2c_new_probed_subdev(&zr->i2c_adapter,
+ zr->card.mod_encoder, zr->card.i2c_encoder,
+ zr->card.addrs_encoder);
+
dprintk(2,
KERN_INFO "%s: Initializing videocodec bus...\n",
ZR_DEVNAME(zr));
@@ -1495,17 +1408,13 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
goto zr_unreg_i2c;
zr->codec = videocodec_attach(master_codec);
if (!zr->codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no codec found\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - no codec found\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_free_codec;
}
if (zr->codec->type != zr->card.video_codec) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - wrong codec\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - wrong codec\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_detach_codec;
}
}
@@ -1515,17 +1424,13 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
goto zr_detach_codec;
zr->vfe = videocodec_attach(master_vfe);
if (!zr->vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() - no VFE found\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s - no VFE found\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_free_vfe;
}
if (zr->vfe->type != zr->card.video_vfe) {
- dprintk(1,
- KERN_ERR
- "%s: find_zr36057() = wrong VFE\n",
- ZR_DEVNAME(zr));
+ dprintk(1, KERN_ERR "%s: %s = wrong VFE\n",
+ ZR_DEVNAME(zr), __func__);
goto zr_detach_vfe;
}
}
@@ -1533,8 +1438,7 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
/* take care of Natoma chipset and a revision 1 zr36057 */
if ((pci_pci_problems & PCIPCI_NATOMA) && zr->revision <= 1) {
zr->jpg_buffers.need_contiguous = 1;
- dprintk(1,
- KERN_INFO
+ dprintk(1, KERN_INFO
"%s: ZR36057/Natoma bug, max. buffer size is 128K\n",
ZR_DEVNAME(zr));
}
@@ -1544,8 +1448,6 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
zoran_proc_init(zr);
- pci_set_drvdata(pdev, zr);
-
return 0;
zr_detach_vfe:
@@ -1563,6 +1465,8 @@ zr_free_irq:
free_irq(zr->pci_dev->irq, zr);
zr_unmap:
iounmap(zr->zr36057_mem);
+zr_unreg:
+ v4l2_device_unregister(&zr->v4l2_dev);
zr_free_mem:
kfree(zr);
@@ -1613,9 +1517,6 @@ static int __init zoran_init(void)
ZORAN_NAME, vidmem);
}
- /* random nonsense */
- dprintk(6, KERN_DEBUG "Jotti is een held!\n");
-
/* some mainboards might not do PCI-PCI data transfer well */
if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL|PCIPCI_ALIMAGIK)) {
dprintk(1,
diff --git a/drivers/media/video/zoran/zoran_card.h b/drivers/media/video/zoran/zoran_card.h
index 4507bdc5e33..4936fead73e 100644
--- a/drivers/media/video/zoran/zoran_card.h
+++ b/drivers/media/video/zoran/zoran_card.h
@@ -44,7 +44,8 @@ extern int zr36067_debug;
extern struct video_device zoran_template;
extern int zoran_check_jpg_settings(struct zoran *zr,
- struct zoran_jpg_settings *settings);
+ struct zoran_jpg_settings *settings,
+ int try);
extern void zoran_open_init_params(struct zoran *zr);
extern void zoran_vdev_release(struct video_device *vdev);
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index 5d948ff7faf..e0223deed35 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -36,13 +36,12 @@
#include <linux/proc_fs.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-common.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
#include <linux/pci.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
#include <linux/delay.h>
#include <linux/wait.h>
@@ -312,9 +311,9 @@ zr36057_adjust_vfe (struct zoran *zr,
case BUZ_MODE_MOTION_COMPRESS:
case BUZ_MODE_IDLE:
default:
- if (zr->norm == VIDEO_MODE_NTSC ||
+ if ((zr->norm & V4L2_STD_NTSC) ||
(zr->card.type == LML33R10 &&
- zr->norm == VIDEO_MODE_PAL))
+ (zr->norm & V4L2_STD_PAL)))
btand(~ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
else
btor(ZR36057_VFESPFR_ExtFl, ZR36057_VFESPFR);
@@ -355,14 +354,6 @@ zr36057_set_vfe (struct zoran *zr,
dprintk(2, KERN_INFO "%s: set_vfe() - width = %d, height = %d\n",
ZR_DEVNAME(zr), video_width, video_height);
- if (zr->norm != VIDEO_MODE_PAL &&
- zr->norm != VIDEO_MODE_NTSC &&
- zr->norm != VIDEO_MODE_SECAM) {
- dprintk(1,
- KERN_ERR "%s: set_vfe() - norm = %d not valid\n",
- ZR_DEVNAME(zr), zr->norm);
- return;
- }
if (video_width < BUZ_MIN_WIDTH ||
video_height < BUZ_MIN_HEIGHT ||
video_width > Wa || video_height > Ha) {
@@ -426,7 +417,7 @@ zr36057_set_vfe (struct zoran *zr,
* we get the correct colors when uncompressing to the screen */
//reg |= ZR36057_VFESPFR_VCLKPol; /**/
/* RJ: Don't know if that is needed for NTSC also */
- if (zr->norm != VIDEO_MODE_NTSC)
+ if (!(zr->norm & V4L2_STD_NTSC))
reg |= ZR36057_VFESPFR_ExtFl; // NEEDED!!!!!!! Wolfgang
reg |= ZR36057_VFESPFR_TopField;
if (HorDcm >= 48) {
@@ -497,11 +488,11 @@ zr36057_overlay (struct zoran *zr,
* All error messages are internal driver checking only! */
/* video display top and bottom registers */
- reg = (long) zr->buffer.base +
+ reg = (long) zr->vbuf_base +
zr->overlay_settings.x *
((zr->overlay_settings.format->depth + 7) / 8) +
zr->overlay_settings.y *
- zr->buffer.bytesperline;
+ zr->vbuf_bytesperline;
btwrite(reg, ZR36057_VDTR);
if (reg & 3)
dprintk(1,
@@ -509,15 +500,15 @@ zr36057_overlay (struct zoran *zr,
"%s: zr36057_overlay() - video_address not aligned\n",
ZR_DEVNAME(zr));
if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->buffer.bytesperline;
+ reg += zr->vbuf_bytesperline;
btwrite(reg, ZR36057_VDBR);
/* video stride, status, and frame grab register */
- reg = zr->buffer.bytesperline -
+ reg = zr->vbuf_bytesperline -
zr->overlay_settings.width *
((zr->overlay_settings.format->depth + 7) / 8);
if (zr->overlay_settings.height > BUZ_MAX_HEIGHT / 2)
- reg += zr->buffer.bytesperline;
+ reg += zr->vbuf_bytesperline;
if (reg & 3)
dprintk(1,
KERN_ERR
@@ -544,12 +535,8 @@ zr36057_overlay (struct zoran *zr,
* and the maximum window size is BUZ_MAX_WIDTH * BUZ_MAX_HEIGHT pixels.
*/
-void
-write_overlay_mask (struct file *file,
- struct video_clip *vp,
- int count)
+void write_overlay_mask(struct zoran_fh *fh, struct v4l2_clip *vp, int count)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned mask_line_size = (BUZ_MAX_WIDTH + 31) / 32;
u32 *mask;
@@ -563,10 +550,10 @@ write_overlay_mask (struct file *file,
for (i = 0; i < count; ++i) {
/* pick up local copy of clip */
- x = vp[i].x;
- y = vp[i].y;
- width = vp[i].width;
- height = vp[i].height;
+ x = vp[i].c.left;
+ y = vp[i].c.top;
+ width = vp[i].c.width;
+ height = vp[i].c.height;
/* trim clips that extend beyond the window */
if (x < 0) {
@@ -981,11 +968,10 @@ void
zr36057_enable_jpg (struct zoran *zr,
enum zoran_codec_mode mode)
{
- static int zero;
- static int one = 1;
struct vfe_settings cap;
int field_size =
zr->jpg_buffers.buffer_size / zr->jpg_settings.field_per_buff;
+ struct v4l2_routing route = { 0, 0 };
zr->codec_mode = mode;
@@ -1007,8 +993,9 @@ zr36057_enable_jpg (struct zoran *zr,
* the video bus direction set to input.
*/
set_videobus_dir(zr, 0);
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
- encoder_command(zr, ENCODER_SET_INPUT, &zero);
+ decoder_call(zr, video, s_stream, 1);
+ route.input = 0;
+ encoder_call(zr, video, s_routing, &route);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
@@ -1054,9 +1041,10 @@ zr36057_enable_jpg (struct zoran *zr,
/* In motion decompression mode, the decoder output must be disabled, and
* the video bus direction set to output.
*/
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
+ decoder_call(zr, video, s_stream, 0);
set_videobus_dir(zr, 1);
- encoder_command(zr, ENCODER_SET_INPUT, &one);
+ route.input = 1;
+ encoder_call(zr, video, s_routing, &route);
/* Take the JPEG codec and the VFE out of sleep */
jpeg_codec_sleep(zr, 0);
@@ -1100,8 +1088,9 @@ zr36057_enable_jpg (struct zoran *zr,
jpeg_codec_sleep(zr, 1);
zr36057_adjust_vfe(zr, mode);
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &one);
- encoder_command(zr, ENCODER_SET_INPUT, &zero);
+ decoder_call(zr, video, s_stream, 1);
+ route.input = 0;
+ encoder_call(zr, video, s_routing, &route);
dprintk(2, KERN_INFO "%s: enable_jpg(IDLE)\n", ZR_DEVNAME(zr));
break;
@@ -1132,7 +1121,7 @@ zoran_feed_stat_com (struct zoran *zr)
if (!(zr->stat_com[i] & cpu_to_le32(1)))
break;
zr->stat_com[i] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+ cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
} else {
/* fill 2 stat_com entries */
i = ((zr->jpg_dma_head -
@@ -1140,9 +1129,9 @@ zoran_feed_stat_com (struct zoran *zr)
if (!(zr->stat_com[i] & cpu_to_le32(1)))
break;
zr->stat_com[i] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+ cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
zr->stat_com[i + 1] =
- cpu_to_le32(zr->jpg_buffers.buffer[frame].frag_tab_bus);
+ cpu_to_le32(zr->jpg_buffers.buffer[frame].jpg.frag_tab_bus);
}
zr->jpg_buffers.buffer[frame].state = BUZ_STATE_DMA;
zr->jpg_dma_head++;
@@ -1162,7 +1151,7 @@ zoran_reap_stat_com (struct zoran *zr)
u32 stat_com;
unsigned int seq;
unsigned int dif;
- struct zoran_jpg_buffer *buffer;
+ struct zoran_buffer *buffer;
int frame;
/* In motion decompress we don't have a hardware frame counter,
@@ -1208,22 +1197,52 @@ zoran_reap_stat_com (struct zoran *zr)
}
}
+static void zoran_restart(struct zoran *zr)
+{
+ /* Now the stat_comm buffer is ready for restart */
+ int status = 0, mode;
+
+ if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
+ decoder_call(zr, video, g_input_status, &status);
+ mode = CODEC_DO_COMPRESSION;
+ } else {
+ status = V4L2_IN_ST_NO_SIGNAL;
+ mode = CODEC_DO_EXPANSION;
+ }
+ if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
+ !(status & V4L2_IN_ST_NO_SIGNAL)) {
+ /********** RESTART code *************/
+ jpeg_codec_reset(zr);
+ zr->codec->set_mode(zr->codec, mode);
+ zr36057_set_jpg(zr, zr->codec_mode);
+ jpeg_start(zr);
+
+ if (zr->num_errors <= 8)
+ dprintk(2, KERN_INFO "%s: Restart\n",
+ ZR_DEVNAME(zr));
+
+ zr->JPEG_missed = 0;
+ zr->JPEG_error = 2;
+ /********** End RESTART code ***********/
+ }
+}
+
static void
error_handler (struct zoran *zr,
u32 astat,
u32 stat)
{
+ int i, j;
+
/* This is JPEG error handling part */
- if ((zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) &&
- (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS)) {
- //dprintk(1, KERN_ERR "%s: Internal error: error handling request in mode %d\n", ZR_DEVNAME(zr), zr->codec_mode);
+ if (zr->codec_mode != BUZ_MODE_MOTION_COMPRESS &&
+ zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS) {
return;
}
if ((stat & 1) == 0 &&
zr->codec_mode == BUZ_MODE_MOTION_COMPRESS &&
- zr->jpg_dma_tail - zr->jpg_que_tail >=
- zr->jpg_buffers.num_buffers) {
+ zr->jpg_dma_tail - zr->jpg_que_tail >= zr->jpg_buffers.num_buffers) {
/* No free buffers... */
zoran_reap_stat_com(zr);
zoran_feed_stat_com(zr);
@@ -1232,142 +1251,95 @@ error_handler (struct zoran *zr,
return;
}
- 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.
- */
- btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
- udelay(1);
- stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
- btwrite(0, ZR36057_JPC);
- btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
- jpeg_codec_reset(zr);
- jpeg_codec_sleep(zr, 1);
- zr->JPEG_error = 1;
- zr->num_errors++;
-
- /* Report error */
- if (zr36067_debug > 1 && zr->num_errors <= 8) {
- long frame;
- frame =
- zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
- printk(KERN_ERR
- "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
- ZR_DEVNAME(zr), stat, zr->last_isr,
- zr->jpg_que_tail, zr->jpg_dma_tail,
- zr->jpg_dma_head, zr->jpg_que_head,
- zr->jpg_seq_num, frame);
- printk("stat_com frames:");
- {
- int i, j;
- for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- for (i = 0;
- i < zr->jpg_buffers.num_buffers;
- i++) {
- if (le32_to_cpu(zr->stat_com[j]) ==
- zr->jpg_buffers.
- buffer[i].
- frag_tab_bus) {
- printk("% d->%d",
- j, i);
- }
- }
- }
- printk("\n");
- }
- }
- /* Find an entry in stat_com and rotate contents */
- {
- int i;
-
- if (zr->jpg_settings.TmpDcm == 1)
- i = (zr->jpg_dma_tail -
- zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
- else
- i = ((zr->jpg_dma_tail -
- zr->jpg_err_shift) & 1) * 2;
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
- /* Mimic zr36067 operation */
- zr->stat_com[i] |= cpu_to_le32(1);
- if (zr->jpg_settings.TmpDcm != 1)
- zr->stat_com[i + 1] |= cpu_to_le32(1);
- /* Refill */
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- /* Find an entry in stat_com again after refill */
- if (zr->jpg_settings.TmpDcm == 1)
- i = (zr->jpg_dma_tail -
- zr->jpg_err_shift) &
- BUZ_MASK_STAT_COM;
- else
- i = ((zr->jpg_dma_tail -
- zr->jpg_err_shift) & 1) * 2;
- }
- if (i) {
- /* Rotate stat_comm entries to make current entry first */
- int j;
- __le32 bus_addr[BUZ_NUM_STAT_COM];
-
- /* Here we are copying the stat_com array, which
- * is already in little endian format, so
- * no endian conversions here
- */
- memcpy(bus_addr, zr->stat_com,
- sizeof(bus_addr));
- for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
- zr->stat_com[j] =
- bus_addr[(i + j) &
- BUZ_MASK_STAT_COM];
+ if (zr->JPEG_error == 1) {
+ zoran_restart(zr);
+ return;
+ }
- }
- zr->jpg_err_shift += i;
- zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
+ /*
+ * 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.
+ */
+ btand(~ZR36057_JMC_Go_en, ZR36057_JMC);
+ udelay(1);
+ stat = stat | (post_office_read(zr, 7, 0) & 3) << 8;
+ btwrite(0, ZR36057_JPC);
+ btor(ZR36057_MCTCR_CFlush, ZR36057_MCTCR);
+ jpeg_codec_reset(zr);
+ jpeg_codec_sleep(zr, 1);
+ zr->JPEG_error = 1;
+ zr->num_errors++;
+
+ /* Report error */
+ if (zr36067_debug > 1 && zr->num_errors <= 8) {
+ long frame;
+
+ frame = zr->jpg_pend[zr->jpg_dma_tail & BUZ_MASK_FRAME];
+ printk(KERN_ERR
+ "%s: JPEG error stat=0x%08x(0x%08x) queue_state=%ld/%ld/%ld/%ld seq=%ld frame=%ld. Codec stopped. ",
+ ZR_DEVNAME(zr), stat, zr->last_isr,
+ zr->jpg_que_tail, zr->jpg_dma_tail,
+ zr->jpg_dma_head, zr->jpg_que_head,
+ zr->jpg_seq_num, frame);
+ printk(KERN_INFO "stat_com frames:");
+ for (j = 0; j < BUZ_NUM_STAT_COM; j++) {
+ for (i = 0; i < zr->jpg_buffers.num_buffers; i++) {
+ if (le32_to_cpu(zr->stat_com[j]) == zr->jpg_buffers.buffer[i].jpg.frag_tab_bus)
+ printk(KERN_CONT "% d->%d", j, i);
}
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
- zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */
}
+ printk(KERN_CONT "\n");
}
+ /* Find an entry in stat_com and rotate contents */
+ if (zr->jpg_settings.TmpDcm == 1)
+ i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+ else
+ i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
+ if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) {
+ /* Mimic zr36067 operation */
+ zr->stat_com[i] |= cpu_to_le32(1);
+ if (zr->jpg_settings.TmpDcm != 1)
+ zr->stat_com[i + 1] |= cpu_to_le32(1);
+ /* Refill */
+ zoran_reap_stat_com(zr);
+ zoran_feed_stat_com(zr);
+ wake_up_interruptible(&zr->jpg_capq);
+ /* Find an entry in stat_com again after refill */
+ if (zr->jpg_settings.TmpDcm == 1)
+ i = (zr->jpg_dma_tail - zr->jpg_err_shift) & BUZ_MASK_STAT_COM;
+ else
+ i = ((zr->jpg_dma_tail - zr->jpg_err_shift) & 1) * 2;
+ }
+ if (i) {
+ /* Rotate stat_comm entries to make current entry first */
+ int j;
+ __le32 bus_addr[BUZ_NUM_STAT_COM];
+
+ /* Here we are copying the stat_com array, which
+ * is already in little endian format, so
+ * no endian conversions here
+ */
+ memcpy(bus_addr, zr->stat_com, sizeof(bus_addr));
- /* Now the stat_comm buffer is ready for restart */
- do {
- int status, mode;
-
- if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- decoder_command(zr, DECODER_GET_STATUS, &status);
- mode = CODEC_DO_COMPRESSION;
- } else {
- status = 0;
- mode = CODEC_DO_EXPANSION;
- }
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- (status & DECODER_STATUS_GOOD)) {
- /********** RESTART code *************/
- jpeg_codec_reset(zr);
- zr->codec->set_mode(zr->codec, mode);
- zr36057_set_jpg(zr, zr->codec_mode);
- jpeg_start(zr);
-
- if (zr->num_errors <= 8)
- dprintk(2, KERN_INFO "%s: Restart\n",
- ZR_DEVNAME(zr));
+ for (j = 0; j < BUZ_NUM_STAT_COM; j++)
+ zr->stat_com[j] = bus_addr[(i + j) & BUZ_MASK_STAT_COM];
- zr->JPEG_missed = 0;
- zr->JPEG_error = 2;
- /********** End RESTART code ***********/
- }
- } while (0);
+ zr->jpg_err_shift += i;
+ zr->jpg_err_shift &= BUZ_MASK_STAT_COM;
+ }
+ if (zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)
+ zr->jpg_err_seq = zr->jpg_seq_num; /* + 1; */
+ zoran_restart(zr);
}
irqreturn_t
@@ -1425,10 +1397,8 @@ zoran_irq (int irq,
* We simply ignore them */
if (zr->v4l_memgrab_active) {
-
/* A lot more checks should be here ... */
- if ((btread(ZR36057_VSSFGR) &
- ZR36057_VSSFGR_SnapShot) == 0)
+ if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_SnapShot) == 0)
dprintk(1,
KERN_WARNING
"%s: BuzIRQ with SnapShot off ???\n",
@@ -1436,10 +1406,7 @@ zoran_irq (int irq,
if (zr->v4l_grab_frame != NO_GRAB_ACTIVE) {
/* There is a grab on a frame going on, check if it has finished */
-
- if ((btread(ZR36057_VSSFGR) &
- ZR36057_VSSFGR_FrameGrab) ==
- 0) {
+ if ((btread(ZR36057_VSSFGR) & ZR36057_VSSFGR_FrameGrab) == 0) {
/* it is finished, notify the user */
zr->v4l_buffers.buffer[zr->v4l_grab_frame].state = BUZ_STATE_DONE;
@@ -1457,9 +1424,7 @@ zoran_irq (int irq,
if (zr->v4l_grab_frame == NO_GRAB_ACTIVE &&
zr->v4l_pend_tail != zr->v4l_pend_head) {
-
- int frame = zr->v4l_pend[zr->v4l_pend_tail &
- V4L_MASK_FRAME];
+ int frame = zr->v4l_pend[zr->v4l_pend_tail & V4L_MASK_FRAME];
u32 reg;
zr->v4l_grab_frame = frame;
@@ -1468,27 +1433,17 @@ zoran_irq (int irq,
/* Buffer address */
- reg =
- zr->v4l_buffers.buffer[frame].
- fbuffer_bus;
+ reg = zr->v4l_buffers.buffer[frame].v4l.fbuffer_bus;
btwrite(reg, ZR36057_VDTR);
- if (zr->v4l_settings.height >
- BUZ_MAX_HEIGHT / 2)
- reg +=
- zr->v4l_settings.
- bytesperline;
+ if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+ reg += zr->v4l_settings.bytesperline;
btwrite(reg, ZR36057_VDBR);
/* video stride, status, and frame grab register */
reg = 0;
- if (zr->v4l_settings.height >
- BUZ_MAX_HEIGHT / 2)
- reg +=
- zr->v4l_settings.
- bytesperline;
- reg =
- (reg <<
- ZR36057_VSSFGR_DispStride);
+ if (zr->v4l_settings.height > BUZ_MAX_HEIGHT / 2)
+ reg += zr->v4l_settings.bytesperline;
+ reg = (reg << ZR36057_VSSFGR_DispStride);
reg |= ZR36057_VSSFGR_VidOvf;
reg |= ZR36057_VSSFGR_SnapShot;
reg |= ZR36057_VSSFGR_FrameGrab;
@@ -1506,77 +1461,66 @@ zoran_irq (int irq,
#if (IRQ_MASK & ZR36057_ISR_CodRepIRQ)
if (astat & ZR36057_ISR_CodRepIRQ) {
zr->intr_counter_CodRepIRQ++;
- IDEBUG(printk
- (KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
+ IDEBUG(printk(KERN_DEBUG "%s: ZR36057_ISR_CodRepIRQ\n",
ZR_DEVNAME(zr)));
btand(~ZR36057_ICR_CodRepIRQ, ZR36057_ICR);
}
#endif /* (IRQ_MASK & ZR36057_ISR_CodRepIRQ) */
#if (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ)
- if (astat & ZR36057_ISR_JPEGRepIRQ) {
-
- if (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
- zr->codec_mode == BUZ_MODE_MOTION_COMPRESS) {
- if (zr36067_debug > 1 &&
- (!zr->frame_num || zr->JPEG_error)) {
- printk(KERN_INFO
- "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
- ZR_DEVNAME(zr), stat,
- zr->jpg_settings.odd_even,
- zr->jpg_settings.
- field_per_buff,
- zr->JPEG_missed);
- {
- char sc[] = "0000";
- char sv[5];
- int i;
- strcpy(sv, sc);
- for (i = 0; i < 4; i++) {
- if (le32_to_cpu(zr->stat_com[i]) & 1)
- sv[i] = '1';
- }
- sv[4] = 0;
- printk(KERN_INFO
- "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
- ZR_DEVNAME(zr), sv,
- zr->jpg_que_tail,
- zr->jpg_dma_tail,
- zr->jpg_dma_head,
- zr->jpg_que_head);
- }
- } else {
- if (zr->JPEG_missed > zr->JPEG_max_missed) // Get statistics
- zr->JPEG_max_missed =
- zr->JPEG_missed;
- if (zr->JPEG_missed <
- zr->JPEG_min_missed)
- zr->JPEG_min_missed =
- zr->JPEG_missed;
+ if ((astat & ZR36057_ISR_JPEGRepIRQ) &&
+ (zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS ||
+ zr->codec_mode == BUZ_MODE_MOTION_COMPRESS)) {
+ if (zr36067_debug > 1 && (!zr->frame_num || zr->JPEG_error)) {
+ char sc[] = "0000";
+ char sv[5];
+ int i;
+
+ printk(KERN_INFO
+ "%s: first frame ready: state=0x%08x odd_even=%d field_per_buff=%d delay=%d\n",
+ ZR_DEVNAME(zr), stat,
+ zr->jpg_settings.odd_even,
+ zr->jpg_settings.field_per_buff,
+ zr->JPEG_missed);
+
+ strcpy(sv, sc);
+ for (i = 0; i < 4; i++) {
+ if (le32_to_cpu(zr->stat_com[i]) & 1)
+ sv[i] = '1';
}
+ sv[4] = 0;
+ printk(KERN_INFO
+ "%s: stat_com=%s queue_state=%ld/%ld/%ld/%ld\n",
+ ZR_DEVNAME(zr), sv,
+ zr->jpg_que_tail,
+ zr->jpg_dma_tail,
+ zr->jpg_dma_head,
+ zr->jpg_que_head);
+ } else {
+ /* Get statistics */
+ if (zr->JPEG_missed > zr->JPEG_max_missed)
+ zr->JPEG_max_missed = zr->JPEG_missed;
+ if (zr->JPEG_missed < zr->JPEG_min_missed)
+ zr->JPEG_min_missed = zr->JPEG_missed;
+ }
- if (zr36067_debug > 2 && zr->frame_num < 6) {
- int i;
- printk("%s: seq=%ld stat_com:",
- ZR_DEVNAME(zr), zr->jpg_seq_num);
- for (i = 0; i < 4; i++) {
- printk(" %08x",
- le32_to_cpu(zr->stat_com[i]));
- }
- printk("\n");
+ if (zr36067_debug > 2 && zr->frame_num < 6) {
+ int i;
+
+ printk(KERN_INFO "%s: seq=%ld stat_com:",
+ ZR_DEVNAME(zr), zr->jpg_seq_num);
+ for (i = 0; i < 4; i++) {
+ printk(KERN_CONT " %08x",
+ le32_to_cpu(zr->stat_com[i]));
}
- zr->frame_num++;
- zr->JPEG_missed = 0;
- zr->JPEG_error = 0;
- zoran_reap_stat_com(zr);
- zoran_feed_stat_com(zr);
- wake_up_interruptible(&zr->jpg_capq);
- } /*else {
- dprintk(1,
- KERN_ERR
- "%s: JPEG interrupt while not in motion (de)compress mode!\n",
- ZR_DEVNAME(zr));
- }*/
+ printk(KERN_CONT "\n");
+ }
+ zr->frame_num++;
+ zr->JPEG_missed = 0;
+ zr->JPEG_error = 0;
+ zoran_reap_stat_com(zr);
+ zoran_feed_stat_com(zr);
+ wake_up_interruptible(&zr->jpg_capq);
}
#endif /* (IRQ_MASK & ZR36057_ISR_JPEGRepIRQ) */
@@ -1585,8 +1529,7 @@ zoran_irq (int irq,
zr->JPEG_missed > 25 ||
zr->JPEG_error == 1 ||
((zr->codec_mode == BUZ_MODE_MOTION_DECOMPRESS) &&
- (zr->frame_num & (zr->JPEG_missed >
- zr->jpg_settings.field_per_buff)))) {
+ (zr->frame_num & (zr->JPEG_missed > zr->jpg_settings.field_per_buff)))) {
error_handler(zr, astat, stat);
}
@@ -1628,7 +1571,7 @@ zoran_set_pci_master (struct zoran *zr,
void
zoran_init_hardware (struct zoran *zr)
{
- int j, zero = 0;
+ struct v4l2_routing route = { 0, 0 };
/* Enable bus-mastering */
zoran_set_pci_master(zr, 1);
@@ -1638,15 +1581,16 @@ zoran_init_hardware (struct zoran *zr)
zr->card.init(zr);
}
- j = zr->card.input[zr->input].muxsel;
+ route.input = zr->card.input[zr->input].muxsel;
- decoder_command(zr, 0, NULL);
- decoder_command(zr, DECODER_SET_NORM, &zr->norm);
- decoder_command(zr, DECODER_SET_INPUT, &j);
+ decoder_call(zr, core, init, 0);
+ decoder_call(zr, tuner, s_std, zr->norm);
+ decoder_call(zr, video, s_routing, &route);
- encoder_command(zr, 0, NULL);
- encoder_command(zr, ENCODER_SET_NORM, &zr->norm);
- encoder_command(zr, ENCODER_SET_INPUT, &zero);
+ encoder_call(zr, core, init, 0);
+ encoder_call(zr, video, s_std_output, zr->norm);
+ route.input = 0;
+ encoder_call(zr, video, s_routing, &route);
/* toggle JPEG codec sleep to sync PLL */
jpeg_codec_sleep(zr, 1);
@@ -1706,42 +1650,3 @@ zr36057_init_vfe (struct zoran *zr)
reg |= ZR36057_VDCR_Triton;
btwrite(reg, ZR36057_VDCR);
}
-
-/*
- * Interface to decoder and encoder chips using i2c bus
- */
-
-int
-decoder_command (struct zoran *zr,
- int cmd,
- void *data)
-{
- if (zr->decoder == NULL)
- return -EIO;
-
- if (zr->card.type == LML33 &&
- (cmd == DECODER_SET_NORM || cmd == DECODER_SET_INPUT)) {
- int res;
-
- // Bt819 needs to reset its FIFO buffer using #FRST pin and
- // LML33 card uses GPIO(7) for that.
- GPIO(zr, 7, 0);
- res = zr->decoder->driver->command(zr->decoder, cmd, data);
- // Pull #FRST high.
- GPIO(zr, 7, 1);
- return res;
- } else
- return zr->decoder->driver->command(zr->decoder, cmd,
- data);
-}
-
-int
-encoder_command (struct zoran *zr,
- int cmd,
- void *data)
-{
- if (zr->encoder == NULL)
- return -1;
-
- return zr->encoder->driver->command(zr->encoder, cmd, data);
-}
diff --git a/drivers/media/video/zoran/zoran_device.h b/drivers/media/video/zoran/zoran_device.h
index 74c6c8edb7d..07f2c23ff74 100644
--- a/drivers/media/video/zoran/zoran_device.h
+++ b/drivers/media/video/zoran/zoran_device.h
@@ -54,8 +54,8 @@ extern int jpeg_codec_reset(struct zoran *zr);
/* zr360x7 access to raw capture */
extern void zr36057_overlay(struct zoran *zr,
int on);
-extern void write_overlay_mask(struct file *file,
- struct video_clip *vp,
+extern void write_overlay_mask(struct zoran_fh *fh,
+ struct v4l2_clip *vp,
int count);
extern void zr36057_set_memgrab(struct zoran *zr,
int mode);
@@ -87,11 +87,9 @@ extern int jpg_bufsize;
extern int pass_through;
/* i2c */
-extern int decoder_command(struct zoran *zr,
- int cmd,
- void *data);
-extern int encoder_command(struct zoran *zr,
- int cmd,
- void *data);
+#define decoder_call(zr, o, f, args...) \
+ v4l2_subdev_call(zr->decoder, o, f, ##args)
+#define encoder_call(zr, o, f, args...) \
+ v4l2_subdev_call(zr->encoder, o, f, ##args)
#endif /* __ZORAN_DEVICE_H__ */
diff --git a/drivers/media/video/zoran/zoran_driver.c b/drivers/media/video/zoran/zoran_driver.c
index 120ef235e63..f16e57cf11e 100644
--- a/drivers/media/video/zoran/zoran_driver.c
+++ b/drivers/media/video/zoran/zoran_driver.c
@@ -58,16 +58,6 @@
#include <linux/i2c-algo-bit.h>
#include <linux/spinlock.h>
-#define MAP_NR(x) virt_to_page(x)
-#define ZORAN_VID_TYPE ( \
- VID_TYPE_CAPTURE | \
- VID_TYPE_OVERLAY | \
- VID_TYPE_CLIPPING | \
- VID_TYPE_FRAMERAM | \
- VID_TYPE_SCALES | \
- VID_TYPE_MJPEG_DECODER | \
- VID_TYPE_MJPEG_ENCODER \
- )
#include <linux/videodev.h>
#include <media/v4l2-common.h>
@@ -79,36 +69,17 @@
#include <asm/uaccess.h>
#include <linux/proc_fs.h>
-#include <linux/video_decoder.h>
-#include <linux/video_encoder.h>
#include <linux/mutex.h>
#include "zoran.h"
#include "zoran_device.h"
#include "zoran_card.h"
- /* we declare some card type definitions here, they mean
- * the same as the v4l1 ZORAN_VID_TYPE above, except it's v4l2 */
-#define ZORAN_V4L2_VID_FLAGS ( \
- V4L2_CAP_STREAMING |\
- V4L2_CAP_VIDEO_CAPTURE |\
- V4L2_CAP_VIDEO_OUTPUT |\
- V4L2_CAP_VIDEO_OVERLAY \
- )
-
-
-#if defined(CONFIG_VIDEO_V4L1_COMPAT)
-#define ZFMT(pal, fcc, cs) \
- .palette = (pal), .fourcc = (fcc), .colorspace = (cs)
-#else
-#define ZFMT(pal, fcc, cs) \
- .fourcc = (fcc), .colorspace = (cs)
-#endif
const struct zoran_format zoran_formats[] = {
{
.name = "15-bit RGB LE",
- ZFMT(VIDEO_PALETTE_RGB555,
- V4L2_PIX_FMT_RGB555, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB555,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 15,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
@@ -116,16 +87,16 @@ const struct zoran_format zoran_formats[] = {
ZR36057_VFESPFR_LittleEndian,
}, {
.name = "15-bit RGB BE",
- ZFMT(-1,
- V4L2_PIX_FMT_RGB555X, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB555X,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 15,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB555|ZR36057_VFESPFR_ErrDif,
}, {
.name = "16-bit RGB LE",
- ZFMT(VIDEO_PALETTE_RGB565,
- V4L2_PIX_FMT_RGB565, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
@@ -133,56 +104,56 @@ const struct zoran_format zoran_formats[] = {
ZR36057_VFESPFR_LittleEndian,
}, {
.name = "16-bit RGB BE",
- ZFMT(-1,
- V4L2_PIX_FMT_RGB565X, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB565X,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB565|ZR36057_VFESPFR_ErrDif,
}, {
.name = "24-bit RGB",
- ZFMT(VIDEO_PALETTE_RGB24,
- V4L2_PIX_FMT_BGR24, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_BGR24,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 24,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_Pack24,
}, {
.name = "32-bit RGB LE",
- ZFMT(VIDEO_PALETTE_RGB32,
- V4L2_PIX_FMT_BGR32, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_BGR32,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 32,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB888|ZR36057_VFESPFR_LittleEndian,
}, {
.name = "32-bit RGB BE",
- ZFMT(-1,
- V4L2_PIX_FMT_RGB32, V4L2_COLORSPACE_SRGB),
+ .fourcc = V4L2_PIX_FMT_RGB32,
+ .colorspace = V4L2_COLORSPACE_SRGB,
.depth = 32,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_RGB888,
}, {
.name = "4:2:2, packed, YUYV",
- ZFMT(VIDEO_PALETTE_YUV422,
- V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_SMPTE170M),
+ .fourcc = V4L2_PIX_FMT_YUYV,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_YUV422,
}, {
.name = "4:2:2, packed, UYVY",
- ZFMT(VIDEO_PALETTE_UYVY,
- V4L2_PIX_FMT_UYVY, V4L2_COLORSPACE_SMPTE170M),
+ .fourcc = V4L2_PIX_FMT_UYVY,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
.depth = 16,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_OVERLAY,
.vfespfr = ZR36057_VFESPFR_YUV422|ZR36057_VFESPFR_LittleEndian,
}, {
.name = "Hardware-encoded Motion-JPEG",
- ZFMT(-1,
- V4L2_PIX_FMT_MJPEG, V4L2_COLORSPACE_SMPTE170M),
+ .fourcc = V4L2_PIX_FMT_MJPEG,
+ .colorspace = V4L2_COLORSPACE_SMPTE170M,
.depth = 0,
.flags = ZORAN_FORMAT_CAPTURE |
ZORAN_FORMAT_PLAYBACK |
@@ -191,13 +162,6 @@ const struct zoran_format zoran_formats[] = {
};
#define NUM_FORMATS ARRAY_SIZE(zoran_formats)
-// RJ: Test only - want to test BUZ_USE_HIMEM even when CONFIG_BIGPHYS_AREA is defined
-
-
-static int lock_norm; /* 0 = default 1 = Don't change TV standard (norm) */
-module_param(lock_norm, int, 0644);
-MODULE_PARM_DESC(lock_norm, "Prevent norm changes (1 = ignore, >1 = fail)");
-
/* small helper function for calculating buffersizes for v4l2
* we calculate the nearest higher power-of-two, which
* will be the recommended buffersize */
@@ -222,221 +186,106 @@ zoran_v4l2_calc_bufsize (struct zoran_jpg_settings *settings)
}
/* forward references */
-static void v4l_fbuffer_free(struct file *file);
-static void jpg_fbuffer_free(struct file *file);
+static void v4l_fbuffer_free(struct zoran_fh *fh);
+static void jpg_fbuffer_free(struct zoran_fh *fh);
+
+/* Set mapping mode */
+static void map_mode_raw(struct zoran_fh *fh)
+{
+ fh->map_mode = ZORAN_MAP_MODE_RAW;
+ fh->buffers.buffer_size = v4l_bufsize;
+ fh->buffers.num_buffers = v4l_nbufs;
+}
+static void map_mode_jpg(struct zoran_fh *fh, int play)
+{
+ fh->map_mode = play ? ZORAN_MAP_MODE_JPG_PLAY : ZORAN_MAP_MODE_JPG_REC;
+ fh->buffers.buffer_size = jpg_bufsize;
+ fh->buffers.num_buffers = jpg_nbufs;
+}
+static inline const char *mode_name(enum zoran_map_mode mode)
+{
+ return mode == ZORAN_MAP_MODE_RAW ? "V4L" : "JPG";
+}
/*
* Allocate the V4L grab buffers
*
* These have to be pysically contiguous.
- * If v4l_bufsize <= MAX_KMALLOC_MEM we use kmalloc
- * else we try to allocate them with bigphysarea_alloc_pages
- * if the bigphysarea patch is present in the kernel,
- * else we try to use high memory (if the user has bootet
- * Linux with the necessary memory left over).
*/
-static unsigned long
-get_high_mem (unsigned long size)
+static int v4l_fbuffer_alloc(struct zoran_fh *fh)
{
-/*
- * Check if there is usable memory at the end of Linux memory
- * of at least size. Return the physical address of this memory,
- * return 0 on failure.
- *
- * The idea is from Alexandro Rubini's book "Linux device drivers".
- * The driver from him which is downloadable from O'Reilly's
- * web site misses the "virt_to_phys(high_memory)" part
- * (and therefore doesn't work at all - at least with 2.2.x kernels).
- *
- * It should be unnecessary to mention that THIS IS DANGEROUS,
- * if more than one driver at a time has the idea to use this memory!!!!
- */
-
- volatile unsigned char __iomem *mem;
- unsigned char c;
- unsigned long hi_mem_ph;
- unsigned long i;
-
- /* Map the high memory to user space */
-
- hi_mem_ph = virt_to_phys(high_memory);
-
- mem = ioremap(hi_mem_ph, size);
- if (!mem) {
- dprintk(1,
- KERN_ERR "%s: get_high_mem() - ioremap failed\n",
- ZORAN_NAME);
- return 0;
- }
-
- for (i = 0; i < size; i++) {
- /* Check if it is memory */
- c = i & 0xff;
- writeb(c, mem + i);
- if (readb(mem + i) != c)
- break;
- c = 255 - c;
- writeb(c, mem + i);
- if (readb(mem + i) != c)
- break;
- writeb(0, mem + i); /* zero out memory */
-
- /* give the kernel air to breath */
- if ((i & 0x3ffff) == 0x3ffff)
- schedule();
- }
-
- iounmap(mem);
-
- if (i != size) {
- dprintk(1,
- KERN_ERR
- "%s: get_high_mem() - requested %lu, avail %lu\n",
- ZORAN_NAME, size, i);
- return 0;
- }
-
- return hi_mem_ph;
-}
-
-static int
-v4l_fbuffer_alloc (struct file *file)
-{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, off;
unsigned char *mem;
- unsigned long pmem = 0;
- /* we might have old buffers lying around... */
- if (fh->v4l_buffers.ready_to_be_freed) {
- v4l_fbuffer_free(file);
- }
-
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
- if (fh->v4l_buffers.buffer[i].fbuffer)
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (fh->buffers.buffer[i].v4l.fbuffer)
dprintk(2,
KERN_WARNING
- "%s: v4l_fbuffer_alloc() - buffer %d allready allocated!?\n",
- ZR_DEVNAME(zr), i);
+ "%s: %s - buffer %d already allocated!?\n",
+ ZR_DEVNAME(zr), __func__, i);
//udelay(20);
- if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
- /* Use kmalloc */
-
- mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
- if (!mem) {
- dprintk(1,
- KERN_ERR
- "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
- ZR_DEVNAME(zr), i);
- v4l_fbuffer_free(file);
- return -ENOBUFS;
- }
- fh->v4l_buffers.buffer[i].fbuffer = mem;
- fh->v4l_buffers.buffer[i].fbuffer_phys =
- virt_to_phys(mem);
- fh->v4l_buffers.buffer[i].fbuffer_bus =
- virt_to_bus(mem);
- for (off = 0; off < fh->v4l_buffers.buffer_size;
- off += PAGE_SIZE)
- SetPageReserved(MAP_NR(mem + off));
- dprintk(4,
- KERN_INFO
- "%s: v4l_fbuffer_alloc() - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
- ZR_DEVNAME(zr), i, (unsigned long) mem,
- virt_to_bus(mem));
- } else {
-
- /* Use high memory which has been left at boot time */
-
- /* Ok., Ok. this is an evil hack - we make
- * the assumption that physical addresses are
- * the same as bus addresses (true at least
- * for Intel processors). The whole method of
- * obtaining and using this memory is not very
- * nice - but I hope it saves some poor users
- * from kernel hacking, which might have even
- * more evil results */
-
- if (i == 0) {
- int size =
- fh->v4l_buffers.num_buffers *
- fh->v4l_buffers.buffer_size;
-
- pmem = get_high_mem(size);
- if (pmem == 0) {
- dprintk(1,
- KERN_ERR
- "%s: v4l_fbuffer_alloc() - get_high_mem (size = %d KB) for V4L bufs failed\n",
- ZR_DEVNAME(zr), size >> 10);
- return -ENOBUFS;
- }
- fh->v4l_buffers.buffer[0].fbuffer = NULL;
- fh->v4l_buffers.buffer[0].fbuffer_phys = pmem;
- fh->v4l_buffers.buffer[0].fbuffer_bus = pmem;
- dprintk(4,
- KERN_INFO
- "%s: v4l_fbuffer_alloc() - using %d KB high memory\n",
- ZR_DEVNAME(zr), size >> 10);
- } else {
- fh->v4l_buffers.buffer[i].fbuffer = NULL;
- fh->v4l_buffers.buffer[i].fbuffer_phys =
- pmem + i * fh->v4l_buffers.buffer_size;
- fh->v4l_buffers.buffer[i].fbuffer_bus =
- pmem + i * fh->v4l_buffers.buffer_size;
- }
+ mem = kmalloc(fh->buffers.buffer_size,
+ GFP_KERNEL | __GFP_NOWARN);
+ if (!mem) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s - kmalloc for V4L buf %d failed\n",
+ ZR_DEVNAME(zr), __func__, i);
+ v4l_fbuffer_free(fh);
+ return -ENOBUFS;
}
+ fh->buffers.buffer[i].v4l.fbuffer = mem;
+ fh->buffers.buffer[i].v4l.fbuffer_phys = virt_to_phys(mem);
+ fh->buffers.buffer[i].v4l.fbuffer_bus = virt_to_bus(mem);
+ for (off = 0; off < fh->buffers.buffer_size;
+ off += PAGE_SIZE)
+ SetPageReserved(virt_to_page(mem + off));
+ dprintk(4,
+ KERN_INFO
+ "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n",
+ ZR_DEVNAME(zr), __func__, i, (unsigned long) mem,
+ (unsigned long long)virt_to_bus(mem));
}
- fh->v4l_buffers.allocated = 1;
+ fh->buffers.allocated = 1;
return 0;
}
/* free the V4L grab buffers */
-static void
-v4l_fbuffer_free (struct file *file)
+static void v4l_fbuffer_free(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, off;
unsigned char *mem;
- dprintk(4, KERN_INFO "%s: v4l_fbuffer_free()\n", ZR_DEVNAME(zr));
+ dprintk(4, KERN_INFO "%s: %s\n", ZR_DEVNAME(zr), __func__);
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
- if (!fh->v4l_buffers.buffer[i].fbuffer)
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (!fh->buffers.buffer[i].v4l.fbuffer)
continue;
- if (fh->v4l_buffers.buffer_size <= MAX_KMALLOC_MEM) {
- mem = fh->v4l_buffers.buffer[i].fbuffer;
- for (off = 0; off < fh->v4l_buffers.buffer_size;
- off += PAGE_SIZE)
- ClearPageReserved(MAP_NR(mem + off));
- kfree((void *) fh->v4l_buffers.buffer[i].fbuffer);
- }
- fh->v4l_buffers.buffer[i].fbuffer = NULL;
+ mem = fh->buffers.buffer[i].v4l.fbuffer;
+ for (off = 0; off < fh->buffers.buffer_size;
+ off += PAGE_SIZE)
+ ClearPageReserved(virt_to_page(mem + off));
+ kfree(fh->buffers.buffer[i].v4l.fbuffer);
+ fh->buffers.buffer[i].v4l.fbuffer = NULL;
}
- fh->v4l_buffers.allocated = 0;
- fh->v4l_buffers.ready_to_be_freed = 0;
+ fh->buffers.allocated = 0;
}
/*
* Allocate the MJPEG grab buffers.
*
- * If the requested buffer size is smaller than MAX_KMALLOC_MEM,
- * kmalloc is used to request a physically contiguous area,
- * else we allocate the memory in framgents with get_zeroed_page.
- *
* If a Natoma chipset is present and this is a revision 1 zr36057,
* each MJPEG buffer needs to be physically contiguous.
* (RJ: This statement is from Dave Perks' original driver,
* I could never check it because I have a zr36067)
- * The driver cares about this because it reduces the buffer
- * size to MAX_KMALLOC_MEM in that case (which forces contiguous allocation).
*
* RJ: The contents grab buffers needs never be accessed in the driver.
* Therefore there is no need to allocate them with vmalloc in order
@@ -458,162 +307,128 @@ v4l_fbuffer_free (struct file *file)
* and fragment buffers are not little-endian.
*/
-static int
-jpg_fbuffer_alloc (struct file *file)
+static int jpg_fbuffer_alloc(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, j, off;
- unsigned long mem;
-
- /* we might have old buffers lying around */
- if (fh->jpg_buffers.ready_to_be_freed) {
- jpg_fbuffer_free(file);
- }
+ u8 *mem;
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
- if (fh->jpg_buffers.buffer[i].frag_tab)
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (fh->buffers.buffer[i].jpg.frag_tab)
dprintk(2,
KERN_WARNING
- "%s: jpg_fbuffer_alloc() - buffer %d allready allocated!?\n",
- ZR_DEVNAME(zr), i);
+ "%s: %s - buffer %d already allocated!?\n",
+ ZR_DEVNAME(zr), __func__, i);
/* Allocate fragment table for this buffer */
- mem = get_zeroed_page(GFP_KERNEL);
+ mem = (void *)get_zeroed_page(GFP_KERNEL);
if (mem == 0) {
dprintk(1,
KERN_ERR
- "%s: jpg_fbuffer_alloc() - get_zeroed_page (frag_tab) failed for buffer %d\n",
- ZR_DEVNAME(zr), i);
- jpg_fbuffer_free(file);
+ "%s: %s - get_zeroed_page (frag_tab) failed for buffer %d\n",
+ ZR_DEVNAME(zr), __func__, i);
+ jpg_fbuffer_free(fh);
return -ENOBUFS;
}
- fh->jpg_buffers.buffer[i].frag_tab = (__le32 *) mem;
- fh->jpg_buffers.buffer[i].frag_tab_bus =
- virt_to_bus((void *) mem);
-
- //if (alloc_contig) {
- if (fh->jpg_buffers.need_contiguous) {
- mem =
- (unsigned long) kmalloc(fh->jpg_buffers.
- buffer_size,
- GFP_KERNEL);
- if (mem == 0) {
+ fh->buffers.buffer[i].jpg.frag_tab = (__le32 *)mem;
+ fh->buffers.buffer[i].jpg.frag_tab_bus = virt_to_bus(mem);
+
+ if (fh->buffers.need_contiguous) {
+ mem = kmalloc(fh->buffers.buffer_size, GFP_KERNEL);
+ if (mem == NULL) {
dprintk(1,
KERN_ERR
- "%s: jpg_fbuffer_alloc() - kmalloc failed for buffer %d\n",
- ZR_DEVNAME(zr), i);
- jpg_fbuffer_free(file);
+ "%s: %s - kmalloc failed for buffer %d\n",
+ ZR_DEVNAME(zr), __func__, i);
+ jpg_fbuffer_free(fh);
return -ENOBUFS;
}
- fh->jpg_buffers.buffer[i].frag_tab[0] =
- cpu_to_le32(virt_to_bus((void *) mem));
- fh->jpg_buffers.buffer[i].frag_tab[1] =
- cpu_to_le32(((fh->jpg_buffers.buffer_size / 4) << 1) | 1);
- for (off = 0; off < fh->jpg_buffers.buffer_size;
- off += PAGE_SIZE)
- SetPageReserved(MAP_NR(mem + off));
+ fh->buffers.buffer[i].jpg.frag_tab[0] =
+ cpu_to_le32(virt_to_bus(mem));
+ fh->buffers.buffer[i].jpg.frag_tab[1] =
+ cpu_to_le32((fh->buffers.buffer_size >> 1) | 1);
+ for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
+ SetPageReserved(virt_to_page(mem + off));
} else {
- /* jpg_bufsize is allreay page aligned */
- for (j = 0;
- j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
- j++) {
- mem = get_zeroed_page(GFP_KERNEL);
- if (mem == 0) {
+ /* jpg_bufsize is already page aligned */
+ for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
+ mem = (void *)get_zeroed_page(GFP_KERNEL);
+ if (mem == NULL) {
dprintk(1,
KERN_ERR
- "%s: jpg_fbuffer_alloc() - get_zeroed_page failed for buffer %d\n",
- ZR_DEVNAME(zr), i);
- jpg_fbuffer_free(file);
+ "%s: %s - get_zeroed_page failed for buffer %d\n",
+ ZR_DEVNAME(zr), __func__, i);
+ jpg_fbuffer_free(fh);
return -ENOBUFS;
}
- fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
- cpu_to_le32(virt_to_bus((void *) mem));
- fh->jpg_buffers.buffer[i].frag_tab[2 * j +
- 1] =
- cpu_to_le32((PAGE_SIZE / 4) << 1);
- SetPageReserved(MAP_NR(mem));
+ fh->buffers.buffer[i].jpg.frag_tab[2 * j] =
+ cpu_to_le32(virt_to_bus(mem));
+ fh->buffers.buffer[i].jpg.frag_tab[2 * j + 1] =
+ cpu_to_le32((PAGE_SIZE >> 2) << 1);
+ SetPageReserved(virt_to_page(mem));
}
- fh->jpg_buffers.buffer[i].frag_tab[2 * j - 1] |= cpu_to_le32(1);
+ fh->buffers.buffer[i].jpg.frag_tab[2 * j - 1] |= cpu_to_le32(1);
}
}
dprintk(4,
- KERN_DEBUG "%s: jpg_fbuffer_alloc() - %d KB allocated\n",
- ZR_DEVNAME(zr),
- (fh->jpg_buffers.num_buffers *
- fh->jpg_buffers.buffer_size) >> 10);
+ KERN_DEBUG "%s: %s - %d KB allocated\n",
+ ZR_DEVNAME(zr), __func__,
+ (fh->buffers.num_buffers * fh->buffers.buffer_size) >> 10);
- fh->jpg_buffers.allocated = 1;
+ fh->buffers.allocated = 1;
return 0;
}
/* free the MJPEG grab buffers */
-static void
-jpg_fbuffer_free (struct file *file)
+static void jpg_fbuffer_free(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int i, j, off;
unsigned char *mem;
+ __le32 frag_tab;
+ struct zoran_buffer *buffer;
- dprintk(4, KERN_DEBUG "%s: jpg_fbuffer_free()\n", ZR_DEVNAME(zr));
+ dprintk(4, KERN_DEBUG "%s: %s\n", ZR_DEVNAME(zr), __func__);
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
- if (!fh->jpg_buffers.buffer[i].frag_tab)
+ for (i = 0, buffer = &fh->buffers.buffer[0];
+ i < fh->buffers.num_buffers; i++, buffer++) {
+ if (!buffer->jpg.frag_tab)
continue;
- //if (alloc_contig) {
- if (fh->jpg_buffers.need_contiguous) {
- if (fh->jpg_buffers.buffer[i].frag_tab[0]) {
- mem = (unsigned char *) bus_to_virt(le32_to_cpu(
- fh->jpg_buffers.buffer[i].frag_tab[0]));
- for (off = 0;
- off < fh->jpg_buffers.buffer_size;
- off += PAGE_SIZE)
- ClearPageReserved(MAP_NR
- (mem + off));
+ if (fh->buffers.need_contiguous) {
+ frag_tab = buffer->jpg.frag_tab[0];
+
+ if (frag_tab) {
+ mem = bus_to_virt(le32_to_cpu(frag_tab));
+ for (off = 0; off < fh->buffers.buffer_size; off += PAGE_SIZE)
+ ClearPageReserved(virt_to_page(mem + off));
kfree(mem);
- fh->jpg_buffers.buffer[i].frag_tab[0] = 0;
- fh->jpg_buffers.buffer[i].frag_tab[1] = 0;
+ buffer->jpg.frag_tab[0] = 0;
+ buffer->jpg.frag_tab[1] = 0;
}
} else {
- for (j = 0;
- j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
- j++) {
- if (!fh->jpg_buffers.buffer[i].
- frag_tab[2 * j])
+ for (j = 0; j < fh->buffers.buffer_size / PAGE_SIZE; j++) {
+ frag_tab = buffer->jpg.frag_tab[2 * j];
+
+ if (!frag_tab)
break;
- ClearPageReserved(MAP_NR
- (bus_to_virt
- (le32_to_cpu
- (fh->jpg_buffers.
- buffer[i].frag_tab[2 *
- j]))));
- free_page((unsigned long)
- bus_to_virt
- (le32_to_cpu
- (fh->jpg_buffers.
- buffer[i].
- frag_tab[2 * j])));
- fh->jpg_buffers.buffer[i].frag_tab[2 * j] =
- 0;
- fh->jpg_buffers.buffer[i].frag_tab[2 * j +
- 1] = 0;
+ ClearPageReserved(virt_to_page(bus_to_virt(le32_to_cpu(frag_tab))));
+ free_page((unsigned long)bus_to_virt(le32_to_cpu(frag_tab)));
+ buffer->jpg.frag_tab[2 * j] = 0;
+ buffer->jpg.frag_tab[2 * j + 1] = 0;
}
}
- free_page((unsigned long) fh->jpg_buffers.buffer[i].
- frag_tab);
- fh->jpg_buffers.buffer[i].frag_tab = NULL;
+ free_page((unsigned long)buffer->jpg.frag_tab);
+ buffer->jpg.frag_tab = NULL;
}
- fh->jpg_buffers.allocated = 0;
- fh->jpg_buffers.ready_to_be_freed = 0;
+ fh->buffers.allocated = 0;
}
/*
@@ -621,12 +436,11 @@ jpg_fbuffer_free (struct file *file)
*/
static int
-zoran_v4l_set_format (struct file *file,
+zoran_v4l_set_format (struct zoran_fh *fh,
int width,
int height,
const struct zoran_format *format)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int bpp;
@@ -636,19 +450,19 @@ zoran_v4l_set_format (struct file *file,
height > BUZ_MAX_HEIGHT || width > BUZ_MAX_WIDTH) {
dprintk(1,
KERN_ERR
- "%s: v4l_set_format() - wrong frame size (%dx%d)\n",
- ZR_DEVNAME(zr), width, height);
+ "%s: %s - wrong frame size (%dx%d)\n",
+ ZR_DEVNAME(zr), __func__, width, height);
return -EINVAL;
}
bpp = (format->depth + 7) / 8;
/* Check against available buffer size */
- if (height * width * bpp > fh->v4l_buffers.buffer_size) {
+ if (height * width * bpp > fh->buffers.buffer_size) {
dprintk(1,
KERN_ERR
- "%s: v4l_set_format() - video buffer size (%d kB) is too small\n",
- ZR_DEVNAME(zr), fh->v4l_buffers.buffer_size >> 10);
+ "%s: %s - video buffer size (%d kB) is too small\n",
+ ZR_DEVNAME(zr), __func__, fh->buffers.buffer_size >> 10);
return -EINVAL;
}
@@ -657,8 +471,8 @@ zoran_v4l_set_format (struct file *file,
if ((bpp == 2 && (width & 1)) || (bpp == 3 && (width & 3))) {
dprintk(1,
KERN_ERR
- "%s: v4l_set_format() - wrong frame alingment\n",
- ZR_DEVNAME(zr));
+ "%s: %s - wrong frame alignment\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
@@ -670,43 +484,40 @@ zoran_v4l_set_format (struct file *file,
return 0;
}
-static int
-zoran_v4l_queue_frame (struct file *file,
- int num)
+static int zoran_v4l_queue_frame(struct zoran_fh *fh, int num)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
int res = 0;
- if (!fh->v4l_buffers.allocated) {
+ if (!fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: v4l_queue_frame() - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - buffers not yet allocated\n",
+ ZR_DEVNAME(zr), __func__);
res = -ENOMEM;
}
/* No grabbing outside the buffer range! */
- if (num >= fh->v4l_buffers.num_buffers || num < 0) {
+ if (num >= fh->buffers.num_buffers || num < 0) {
dprintk(1,
KERN_ERR
- "%s: v4l_queue_frame() - buffer %d is out of range\n",
- ZR_DEVNAME(zr), num);
+ "%s: %s - buffer %d is out of range\n",
+ ZR_DEVNAME(zr), __func__, num);
res = -EINVAL;
}
spin_lock_irqsave(&zr->spinlock, flags);
- if (fh->v4l_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
if (zr->v4l_buffers.active == ZORAN_FREE) {
- zr->v4l_buffers = fh->v4l_buffers;
- fh->v4l_buffers.active = ZORAN_ACTIVE;
+ zr->v4l_buffers = fh->buffers;
+ fh->buffers.active = ZORAN_ACTIVE;
} else {
dprintk(1,
KERN_ERR
- "%s: v4l_queue_frame() - another session is already capturing\n",
- ZR_DEVNAME(zr));
+ "%s: %s - another session is already capturing\n",
+ ZR_DEVNAME(zr), __func__);
res = -EBUSY;
}
}
@@ -717,7 +528,7 @@ zoran_v4l_queue_frame (struct file *file,
default:
case BUZ_STATE_PEND:
if (zr->v4l_buffers.active == ZORAN_FREE) {
- fh->v4l_buffers.active = ZORAN_FREE;
+ fh->buffers.active = ZORAN_FREE;
zr->v4l_buffers.allocated = 0;
}
res = -EBUSY; /* what are you doing? */
@@ -725,19 +536,17 @@ zoran_v4l_queue_frame (struct file *file,
case BUZ_STATE_DONE:
dprintk(2,
KERN_WARNING
- "%s: v4l_queue_frame() - queueing buffer %d in state DONE!?\n",
- ZR_DEVNAME(zr), num);
+ "%s: %s - queueing buffer %d in state DONE!?\n",
+ ZR_DEVNAME(zr), __func__, num);
case BUZ_STATE_USER:
/* since there is at least one unused buffer there's room for at least
* one more pend[] entry */
- zr->v4l_pend[zr->v4l_pend_head++ &
- V4L_MASK_FRAME] = num;
+ zr->v4l_pend[zr->v4l_pend_head++ & V4L_MASK_FRAME] = num;
zr->v4l_buffers.buffer[num].state = BUZ_STATE_PEND;
zr->v4l_buffers.buffer[num].bs.length =
fh->v4l_settings.bytesperline *
zr->v4l_settings.height;
- fh->v4l_buffers.buffer[num] =
- zr->v4l_buffers.buffer[num];
+ fh->buffers.buffer[num] = zr->v4l_buffers.buffer[num];
break;
}
}
@@ -745,65 +554,7 @@ zoran_v4l_queue_frame (struct file *file,
spin_unlock_irqrestore(&zr->spinlock, flags);
if (!res && zr->v4l_buffers.active == ZORAN_FREE)
- zr->v4l_buffers.active = fh->v4l_buffers.active;
-
- return res;
-}
-
-static int
-v4l_grab (struct file *file,
- struct video_mmap *mp)
-{
- struct zoran_fh *fh = file->private_data;
- struct zoran *zr = fh->zr;
- int res = 0, i;
-
- for (i = 0; i < NUM_FORMATS; i++) {
- if (zoran_formats[i].palette == mp->format &&
- zoran_formats[i].flags & ZORAN_FORMAT_CAPTURE &&
- !(zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED))
- break;
- }
- if (i == NUM_FORMATS || zoran_formats[i].depth == 0) {
- dprintk(1,
- KERN_ERR
- "%s: v4l_grab() - wrong bytes-per-pixel format\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
-
- /*
- * To minimize the time spent in the IRQ routine, we avoid setting up
- * the video front end there.
- * If this grab has different parameters from a running streaming capture
- * we stop the streaming capture and start it over again.
- */
- if (zr->v4l_memgrab_active &&
- (zr->v4l_settings.width != mp->width ||
- zr->v4l_settings.height != mp->height ||
- zr->v4l_settings.format->palette != mp->format)) {
- res = wait_grab_pending(zr);
- if (res)
- return res;
- }
- if ((res = zoran_v4l_set_format(file,
- mp->width,
- mp->height,
- &zoran_formats[i])))
- return res;
- zr->v4l_settings = fh->v4l_settings;
-
- /* queue the frame in the pending queue */
- if ((res = zoran_v4l_queue_frame(file, mp->frame))) {
- fh->v4l_buffers.active = ZORAN_FREE;
- return res;
- }
-
- /* put the 36057 into frame grabbing mode */
- if (!res && !zr->v4l_memgrab_active)
- zr36057_set_memgrab(zr, 1);
-
- //dprintk(4, KERN_INFO "%s: Frame grab 3...\n", ZR_DEVNAME(zr));
+ zr->v4l_buffers.active = fh->buffers.active;
return res;
}
@@ -812,27 +563,24 @@ v4l_grab (struct file *file,
* Sync on a V4L buffer
*/
-static int
-v4l_sync (struct file *file,
- int frame)
+static int v4l_sync(struct zoran_fh *fh, int frame)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
- if (fh->v4l_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: v4l_sync() - no grab active for this session\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no grab active for this session\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
/* check passed-in frame number */
- if (frame >= fh->v4l_buffers.num_buffers || frame < 0) {
+ if (frame >= fh->buffers.num_buffers || frame < 0) {
dprintk(1,
- KERN_ERR "%s: v4l_sync() - frame %d is invalid\n",
- ZR_DEVNAME(zr), frame);
+ KERN_ERR "%s: %s - frame %d is invalid\n",
+ ZR_DEVNAME(zr), __func__, frame);
return -EINVAL;
}
@@ -840,15 +588,14 @@ v4l_sync (struct file *file,
if (zr->v4l_buffers.buffer[frame].state == BUZ_STATE_USER) {
dprintk(1,
KERN_ERR
- "%s: v4l_sync() - attempt to sync on a buffer which was not queued?\n",
- ZR_DEVNAME(zr));
+ "%s: %s - attempt to sync on a buffer which was not queued?\n",
+ ZR_DEVNAME(zr), __func__);
return -EPROTO;
}
/* wait on this buffer to get ready */
if (!wait_event_interruptible_timeout(zr->v4l_capq,
- (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND),
- 10*HZ))
+ (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_PEND), 10*HZ))
return -ETIME;
if (signal_pending(current))
return -ERESTARTSYS;
@@ -856,11 +603,11 @@ v4l_sync (struct file *file,
/* buffer should now be in BUZ_STATE_DONE */
if (zr->v4l_buffers.buffer[frame].state != BUZ_STATE_DONE)
dprintk(2,
- KERN_ERR "%s: v4l_sync() - internal state error\n",
- ZR_DEVNAME(zr));
+ KERN_ERR "%s: %s - internal state error\n",
+ ZR_DEVNAME(zr), __func__);
zr->v4l_buffers.buffer[frame].state = BUZ_STATE_USER;
- fh->v4l_buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
+ fh->buffers.buffer[frame] = zr->v4l_buffers.buffer[frame];
spin_lock_irqsave(&zr->spinlock, flags);
@@ -868,8 +615,7 @@ v4l_sync (struct file *file,
if (zr->v4l_pend_tail == zr->v4l_pend_head) {
zr36057_set_memgrab(zr, 0);
if (zr->v4l_buffers.active == ZORAN_ACTIVE) {
- fh->v4l_buffers.active = zr->v4l_buffers.active =
- ZORAN_FREE;
+ fh->buffers.active = zr->v4l_buffers.active = ZORAN_FREE;
zr->v4l_buffers.allocated = 0;
}
}
@@ -883,31 +629,28 @@ v4l_sync (struct file *file,
* Queue a MJPEG buffer for capture/playback
*/
-static int
-zoran_jpg_queue_frame (struct file *file,
- int num,
- enum zoran_codec_mode mode)
+static int zoran_jpg_queue_frame(struct zoran_fh *fh, int num,
+ enum zoran_codec_mode mode)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
int res = 0;
/* Check if buffers are allocated */
- if (!fh->jpg_buffers.allocated) {
+ if (!fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - buffers not yet allocated\n",
+ ZR_DEVNAME(zr), __func__);
return -ENOMEM;
}
/* No grabbing outside the buffer range! */
- if (num >= fh->jpg_buffers.num_buffers || num < 0) {
+ if (num >= fh->buffers.num_buffers || num < 0) {
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - buffer %d out of range\n",
- ZR_DEVNAME(zr), num);
+ "%s: %s - buffer %d out of range\n",
+ ZR_DEVNAME(zr), __func__, num);
return -EINVAL;
}
@@ -918,20 +661,20 @@ zoran_jpg_queue_frame (struct file *file,
/* wrong codec mode active - invalid */
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - codec in wrong mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s - codec in wrong mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
- if (fh->jpg_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
if (zr->jpg_buffers.active == ZORAN_FREE) {
- zr->jpg_buffers = fh->jpg_buffers;
- fh->jpg_buffers.active = ZORAN_ACTIVE;
+ zr->jpg_buffers = fh->buffers;
+ fh->buffers.active = ZORAN_ACTIVE;
} else {
dprintk(1,
KERN_ERR
- "%s: jpg_queue_frame() - another session is already capturing\n",
- ZR_DEVNAME(zr));
+ "%s: %s - another session is already capturing\n",
+ ZR_DEVNAME(zr), __func__);
res = -EBUSY;
}
}
@@ -948,23 +691,21 @@ zoran_jpg_queue_frame (struct file *file,
case BUZ_STATE_DONE:
dprintk(2,
KERN_WARNING
- "%s: jpg_queue_frame() - queing frame in BUZ_STATE_DONE state!?\n",
- ZR_DEVNAME(zr));
+ "%s: %s - queing frame in BUZ_STATE_DONE state!?\n",
+ ZR_DEVNAME(zr), __func__);
case BUZ_STATE_USER:
/* since there is at least one unused buffer there's room for at
*least one more pend[] entry */
- zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] =
- num;
+ zr->jpg_pend[zr->jpg_que_head++ & BUZ_MASK_FRAME] = num;
zr->jpg_buffers.buffer[num].state = BUZ_STATE_PEND;
- fh->jpg_buffers.buffer[num] =
- zr->jpg_buffers.buffer[num];
+ fh->buffers.buffer[num] = zr->jpg_buffers.buffer[num];
zoran_feed_stat_com(zr);
break;
default:
case BUZ_STATE_DMA:
case BUZ_STATE_PEND:
if (zr->jpg_buffers.active == ZORAN_FREE) {
- fh->jpg_buffers.active = ZORAN_FREE;
+ fh->buffers.active = ZORAN_FREE;
zr->jpg_buffers.allocated = 0;
}
res = -EBUSY; /* what are you doing? */
@@ -974,47 +715,41 @@ zoran_jpg_queue_frame (struct file *file,
spin_unlock_irqrestore(&zr->spinlock, flags);
- if (!res && zr->jpg_buffers.active == ZORAN_FREE) {
- zr->jpg_buffers.active = fh->jpg_buffers.active;
- }
+ if (!res && zr->jpg_buffers.active == ZORAN_FREE)
+ zr->jpg_buffers.active = fh->buffers.active;
return res;
}
-static int
-jpg_qbuf (struct file *file,
- int frame,
- enum zoran_codec_mode mode)
+static int jpg_qbuf(struct zoran_fh *fh, int frame, enum zoran_codec_mode mode)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
int res = 0;
/* Does the user want to stop streaming? */
if (frame < 0) {
if (zr->codec_mode == mode) {
- if (fh->jpg_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: jpg_qbuf(-1) - session not active\n",
- ZR_DEVNAME(zr));
+ "%s: %s(-1) - session not active\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
- fh->jpg_buffers.active = zr->jpg_buffers.active =
- ZORAN_FREE;
+ fh->buffers.active = zr->jpg_buffers.active = ZORAN_FREE;
zr->jpg_buffers.allocated = 0;
zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
return 0;
} else {
dprintk(1,
KERN_ERR
- "%s: jpg_qbuf() - stop streaming but not in streaming mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s - stop streaming but not in streaming mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
}
- if ((res = zoran_jpg_queue_frame(file, frame, mode)))
+ if ((res = zoran_jpg_queue_frame(fh, frame, mode)))
return res;
/* Start the jpeg codec when the first frame is queued */
@@ -1028,28 +763,25 @@ jpg_qbuf (struct file *file,
* Sync on a MJPEG buffer
*/
-static int
-jpg_sync (struct file *file,
- struct zoran_sync *bs)
+static int jpg_sync(struct zoran_fh *fh, struct zoran_sync *bs)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
unsigned long flags;
int frame;
- if (fh->jpg_buffers.active == ZORAN_FREE) {
+ if (fh->buffers.active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: jpg_sync() - capture is not currently active\n",
- ZR_DEVNAME(zr));
+ "%s: %s - capture is not currently active\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (zr->codec_mode != BUZ_MODE_MOTION_DECOMPRESS &&
zr->codec_mode != BUZ_MODE_MOTION_COMPRESS) {
dprintk(1,
KERN_ERR
- "%s: jpg_sync() - codec not in streaming mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s - codec not in streaming mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (!wait_event_interruptible_timeout(zr->jpg_capq,
@@ -1064,8 +796,8 @@ jpg_sync (struct file *file,
sizeof(isr), &isr);
dprintk(1,
KERN_ERR
- "%s: jpg_sync() - timeout: codec isr=0x%02x\n",
- ZR_DEVNAME(zr), isr);
+ "%s: %s - timeout: codec isr=0x%02x\n",
+ ZR_DEVNAME(zr), __func__, isr);
return -ETIME;
@@ -1083,28 +815,26 @@ jpg_sync (struct file *file,
/* buffer should now be in BUZ_STATE_DONE */
if (zr->jpg_buffers.buffer[frame].state != BUZ_STATE_DONE)
dprintk(2,
- KERN_ERR "%s: jpg_sync() - internal state error\n",
- ZR_DEVNAME(zr));
+ KERN_ERR "%s: %s - internal state error\n",
+ ZR_DEVNAME(zr), __func__);
*bs = zr->jpg_buffers.buffer[frame].bs;
bs->frame = frame;
zr->jpg_buffers.buffer[frame].state = BUZ_STATE_USER;
- fh->jpg_buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
+ fh->buffers.buffer[frame] = zr->jpg_buffers.buffer[frame];
spin_unlock_irqrestore(&zr->spinlock, flags);
return 0;
}
-static void
-zoran_open_init_session (struct file *file)
+static void zoran_open_init_session(struct zoran_fh *fh)
{
int i;
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* Per default, map the V4L Buffers */
- fh->map_mode = ZORAN_MAP_MODE_RAW;
+ map_mode_raw(fh);
/* take over the card's current settings */
fh->overlay_settings = zr->overlay_settings;
@@ -1114,40 +844,21 @@ zoran_open_init_session (struct file *file)
/* v4l settings */
fh->v4l_settings = zr->v4l_settings;
-
- /* v4l_buffers */
- memset(&fh->v4l_buffers, 0, sizeof(struct zoran_v4l_struct));
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- fh->v4l_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- fh->v4l_buffers.buffer[i].bs.frame = i;
- }
- fh->v4l_buffers.allocated = 0;
- fh->v4l_buffers.ready_to_be_freed = 0;
- fh->v4l_buffers.active = ZORAN_FREE;
- fh->v4l_buffers.buffer_size = v4l_bufsize;
- fh->v4l_buffers.num_buffers = v4l_nbufs;
-
/* jpg settings */
fh->jpg_settings = zr->jpg_settings;
- /* jpg_buffers */
- memset(&fh->jpg_buffers, 0, sizeof(struct zoran_jpg_struct));
- for (i = 0; i < BUZ_MAX_FRAME; i++) {
- fh->jpg_buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
- fh->jpg_buffers.buffer[i].bs.frame = i;
+ /* buffers */
+ memset(&fh->buffers, 0, sizeof(fh->buffers));
+ for (i = 0; i < MAX_FRAME; i++) {
+ fh->buffers.buffer[i].state = BUZ_STATE_USER; /* nothing going on */
+ fh->buffers.buffer[i].bs.frame = i;
}
- fh->jpg_buffers.need_contiguous = zr->jpg_buffers.need_contiguous;
- fh->jpg_buffers.allocated = 0;
- fh->jpg_buffers.ready_to_be_freed = 0;
- fh->jpg_buffers.active = ZORAN_FREE;
- fh->jpg_buffers.buffer_size = jpg_bufsize;
- fh->jpg_buffers.num_buffers = jpg_nbufs;
+ fh->buffers.allocated = 0;
+ fh->buffers.active = ZORAN_FREE;
}
-static void
-zoran_close_end_session (struct file *file)
+static void zoran_close_end_session(struct zoran_fh *fh)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* overlay */
@@ -1159,36 +870,32 @@ zoran_close_end_session (struct file *file)
zr->overlay_mask = NULL;
}
- /* v4l capture */
- if (fh->v4l_buffers.active != ZORAN_FREE) {
- unsigned long flags;
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+ /* v4l capture */
+ if (fh->buffers.active != ZORAN_FREE) {
+ unsigned long flags;
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- zr->v4l_buffers.allocated = 0;
- zr->v4l_buffers.active = fh->v4l_buffers.active =
- ZORAN_FREE;
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
-
- /* v4l buffers */
- if (fh->v4l_buffers.allocated ||
- fh->v4l_buffers.ready_to_be_freed) {
- v4l_fbuffer_free(file);
- }
+ spin_lock_irqsave(&zr->spinlock, flags);
+ zr36057_set_memgrab(zr, 0);
+ zr->v4l_buffers.allocated = 0;
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
+ spin_unlock_irqrestore(&zr->spinlock, flags);
+ }
- /* jpg capture */
- if (fh->jpg_buffers.active != ZORAN_FREE) {
- zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
- zr->jpg_buffers.allocated = 0;
- zr->jpg_buffers.active = fh->jpg_buffers.active =
- ZORAN_FREE;
- }
+ /* v4l buffers */
+ if (fh->buffers.allocated)
+ v4l_fbuffer_free(fh);
+ } else {
+ /* jpg capture */
+ if (fh->buffers.active != ZORAN_FREE) {
+ zr36057_enable_jpg(zr, BUZ_MODE_IDLE);
+ zr->jpg_buffers.allocated = 0;
+ zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
+ }
- /* jpg buffers */
- if (fh->jpg_buffers.allocated ||
- fh->jpg_buffers.ready_to_be_freed) {
- jpg_fbuffer_free(file);
+ /* jpg buffers */
+ if (fh->buffers.allocated)
+ jpg_fbuffer_free(fh);
}
}
@@ -1202,15 +909,11 @@ static int zoran_open(struct file *file)
struct zoran_fh *fh;
int res, first_open = 0;
- dprintk(2, KERN_INFO "%s: zoran_open(%s, pid=[%d]), users(-)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user + 1);
+ dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(-)=%d\n",
+ ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user + 1);
lock_kernel();
- /* see fs/device.c - the kernel already locks during open(),
- * so locking ourselves only causes deadlocks */
- /*mutex_lock(&zr->resource_lock);*/
-
if (zr->user >= 2048) {
dprintk(1, KERN_ERR "%s: too many users (%d) on device\n",
ZR_DEVNAME(zr), zr->user);
@@ -1218,41 +921,15 @@ static int zoran_open(struct file *file)
goto fail_unlock;
}
- if (!zr->decoder) {
- dprintk(1,
- KERN_ERR "%s: no TV decoder loaded for device!\n",
- ZR_DEVNAME(zr));
- res = -EIO;
- goto fail_unlock;
- }
-
- if (!try_module_get(zr->decoder->driver->driver.owner)) {
- dprintk(1,
- KERN_ERR
- "%s: failed to grab ownership of video decoder\n",
- ZR_DEVNAME(zr));
- res = -EIO;
- goto fail_unlock;
- }
- if (zr->encoder &&
- !try_module_get(zr->encoder->driver->driver.owner)) {
- dprintk(1,
- KERN_ERR
- "%s: failed to grab ownership of video encoder\n",
- ZR_DEVNAME(zr));
- res = -EIO;
- goto fail_decoder;
- }
-
/* now, create the open()-specific file_ops struct */
fh = kzalloc(sizeof(struct zoran_fh), GFP_KERNEL);
if (!fh) {
dprintk(1,
KERN_ERR
- "%s: zoran_open() - allocation of zoran_fh failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - allocation of zoran_fh failed\n",
+ ZR_DEVNAME(zr), __func__);
res = -ENOMEM;
- goto fail_encoder;
+ goto fail_unlock;
}
/* used to be BUZ_MAX_WIDTH/HEIGHT, but that gives overflows
* on norm-change! */
@@ -1261,8 +938,8 @@ static int zoran_open(struct file *file)
if (!fh->overlay_mask) {
dprintk(1,
KERN_ERR
- "%s: zoran_open() - allocation of overlay_mask failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - allocation of overlay_mask failed\n",
+ ZR_DEVNAME(zr), __func__);
res = -ENOMEM;
goto fail_fh;
}
@@ -1284,18 +961,13 @@ static int zoran_open(struct file *file)
/* set file_ops stuff */
file->private_data = fh;
fh->zr = zr;
- zoran_open_init_session(file);
+ zoran_open_init_session(fh);
unlock_kernel();
return 0;
fail_fh:
kfree(fh);
-fail_encoder:
- if (zr->encoder)
- module_put(zr->encoder->driver->driver.owner);
-fail_decoder:
- module_put(zr->decoder->driver->driver.owner);
fail_unlock:
unlock_kernel();
@@ -1311,14 +983,14 @@ zoran_close(struct file *file)
struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
- dprintk(2, KERN_INFO "%s: zoran_close(%s, pid=[%d]), users(+)=%d\n",
- ZR_DEVNAME(zr), current->comm, task_pid_nr(current), zr->user - 1);
+ dprintk(2, KERN_INFO "%s: %s(%s, pid=[%d]), users(+)=%d\n",
+ ZR_DEVNAME(zr), __func__, current->comm, task_pid_nr(current), zr->user - 1);
/* kernel locks (fs/device.c), so don't do that ourselves
* (prevents deadlocks) */
/*mutex_lock(&zr->resource_lock);*/
- zoran_close_end_session(file);
+ zoran_close_end_session(fh);
if (zr->user-- == 1) { /* Last process */
/* Clean up JPEG process */
@@ -1346,9 +1018,10 @@ zoran_close(struct file *file)
zoran_set_pci_master(zr, 0);
if (!pass_through) { /* Switch to color bar */
- int zero = 0, two = 2;
- decoder_command(zr, DECODER_ENABLE_OUTPUT, &zero);
- encoder_command(zr, ENCODER_SET_INPUT, &two);
+ struct v4l2_routing route = { 2, 0 };
+
+ decoder_call(zr, video, s_stream, 0);
+ encoder_call(zr, video, s_routing, &route);
}
}
@@ -1356,14 +1029,7 @@ zoran_close(struct file *file)
kfree(fh->overlay_mask);
kfree(fh);
- /* release locks on the i2c modules */
- module_put(zr->decoder->driver->driver.owner);
- if (zr->encoder)
- module_put(zr->encoder->driver->driver.owner);
-
- /*mutex_unlock(&zr->resource_lock);*/
-
- dprintk(4, KERN_INFO "%s: zoran_close() done\n", ZR_DEVNAME(zr));
+ dprintk(4, KERN_INFO "%s: %s done\n", ZR_DEVNAME(zr), __func__);
return 0;
}
@@ -1391,15 +1057,13 @@ zoran_write (struct file *file,
return -EINVAL;
}
-static int
-setup_fbuffer (struct file *file,
+static int setup_fbuffer(struct zoran_fh *fh,
void *base,
const struct zoran_format *fmt,
int width,
int height,
int bytesperline)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* (Ronald) v4l/v4l2 guidelines */
@@ -1427,8 +1091,8 @@ setup_fbuffer (struct file *file,
* friendly and silently do as if nothing went wrong */
dprintk(3,
KERN_ERR
- "%s: setup_fbuffer() - forced overlay turnoff because framebuffer changed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - forced overlay turnoff because framebuffer changed\n",
+ ZR_DEVNAME(zr), __func__);
zr36057_overlay(zr, 0);
}
#endif
@@ -1436,31 +1100,31 @@ setup_fbuffer (struct file *file,
if (!(fmt->flags & ZORAN_FORMAT_OVERLAY)) {
dprintk(1,
KERN_ERR
- "%s: setup_fbuffer() - no valid overlay format given\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no valid overlay format given\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (height <= 0 || width <= 0 || bytesperline <= 0) {
dprintk(1,
KERN_ERR
- "%s: setup_fbuffer() - invalid height/width/bpl value (%d|%d|%d)\n",
- ZR_DEVNAME(zr), width, height, bytesperline);
+ "%s: %s - invalid height/width/bpl value (%d|%d|%d)\n",
+ ZR_DEVNAME(zr), __func__, width, height, bytesperline);
return -EINVAL;
}
if (bytesperline & 3) {
dprintk(1,
KERN_ERR
- "%s: setup_fbuffer() - bytesperline (%d) must be 4-byte aligned\n",
- ZR_DEVNAME(zr), bytesperline);
+ "%s: %s - bytesperline (%d) must be 4-byte aligned\n",
+ ZR_DEVNAME(zr), __func__, bytesperline);
return -EINVAL;
}
- zr->buffer.base = (void *) ((unsigned long) base & ~3);
- zr->buffer.height = height;
- zr->buffer.width = width;
- zr->buffer.depth = fmt->depth;
+ zr->vbuf_base = (void *) ((unsigned long) base & ~3);
+ zr->vbuf_height = height;
+ zr->vbuf_width = width;
+ zr->vbuf_depth = fmt->depth;
zr->overlay_settings.format = fmt;
- zr->buffer.bytesperline = bytesperline;
+ zr->vbuf_bytesperline = bytesperline;
/* The user should set new window parameters */
zr->overlay_settings.is_set = 0;
@@ -1469,35 +1133,27 @@ setup_fbuffer (struct file *file,
}
-static int
-setup_window (struct file *file,
- int x,
- int y,
- int width,
- int height,
- struct video_clip __user *clips,
- int clipcount,
- void __user *bitmap)
+static int setup_window(struct zoran_fh *fh, int x, int y, int width, int height,
+ struct v4l2_clip __user *clips, int clipcount, void __user *bitmap)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
- struct video_clip *vcp = NULL;
+ struct v4l2_clip *vcp = NULL;
int on, end;
- if (!zr->buffer.base) {
+ if (!zr->vbuf_base) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - frame buffer has to be set first\n",
- ZR_DEVNAME(zr));
+ "%s: %s - frame buffer has to be set first\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (!fh->overlay_settings.format) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - no overlay format set\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no overlay format set\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
@@ -1505,13 +1161,13 @@ setup_window (struct file *file,
* The video front end needs 4-byte alinged line sizes, we correct that
* silently here if necessary
*/
- if (zr->buffer.depth == 15 || zr->buffer.depth == 16) {
+ if (zr->vbuf_depth == 15 || zr->vbuf_depth == 16) {
end = (x + width) & ~1; /* round down */
x = (x + 1) & ~1; /* round up */
width = end - x;
}
- if (zr->buffer.depth == 24) {
+ if (zr->vbuf_depth == 24) {
end = (x + width) & ~3; /* round down */
x = (x + 3) & ~3; /* round up */
width = end - x;
@@ -1527,8 +1183,8 @@ setup_window (struct file *file,
width > BUZ_MAX_WIDTH || height > BUZ_MAX_HEIGHT) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - width = %d or height = %d invalid\n",
- ZR_DEVNAME(zr), width, height);
+ "%s: %s - width = %d or height = %d invalid\n",
+ ZR_DEVNAME(zr), __func__, width, height);
return -EINVAL;
}
@@ -1566,20 +1222,20 @@ setup_window (struct file *file,
}
} else if (clipcount > 0) {
/* write our own bitmap from the clips */
- vcp = vmalloc(sizeof(struct video_clip) * (clipcount + 4));
+ vcp = vmalloc(sizeof(struct v4l2_clip) * (clipcount + 4));
if (vcp == NULL) {
dprintk(1,
KERN_ERR
- "%s: setup_window() - Alloc of clip mask failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s - Alloc of clip mask failed\n",
+ ZR_DEVNAME(zr), __func__);
return -ENOMEM;
}
if (copy_from_user
- (vcp, clips, sizeof(struct video_clip) * clipcount)) {
+ (vcp, clips, sizeof(struct v4l2_clip) * clipcount)) {
vfree(vcp);
return -EFAULT;
}
- write_overlay_mask(file, vcp, clipcount);
+ write_overlay_mask(fh, vcp, clipcount);
vfree(vcp);
}
@@ -1595,11 +1251,8 @@ setup_window (struct file *file,
return wait_grab_pending(zr);
}
-static int
-setup_overlay (struct file *file,
- int on)
+static int setup_overlay(struct zoran_fh *fh, int on)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
/* If there is nothing to do, return immediatly */
@@ -1612,16 +1265,16 @@ setup_overlay (struct file *file,
fh->overlay_active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - overlay is already active for another session\n",
- ZR_DEVNAME(zr));
+ "%s: %s - overlay is already active for another session\n",
+ ZR_DEVNAME(zr), __func__);
return -EBUSY;
}
if (!on && zr->overlay_active != ZORAN_FREE &&
fh->overlay_active == ZORAN_FREE) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - you cannot cancel someone else's session\n",
- ZR_DEVNAME(zr));
+ "%s: %s - you cannot cancel someone else's session\n",
+ ZR_DEVNAME(zr), __func__);
return -EPERM;
}
@@ -1634,18 +1287,18 @@ setup_overlay (struct file *file,
zr36057_overlay(zr, 0);
zr->overlay_mask = NULL;
} else {
- if (!zr->buffer.base || !fh->overlay_settings.is_set) {
+ if (!zr->vbuf_base || !fh->overlay_settings.is_set) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - buffer or window not set\n",
- ZR_DEVNAME(zr));
+ "%s: %s - buffer or window not set\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
if (!fh->overlay_settings.format) {
dprintk(1,
KERN_ERR
- "%s: setup_overlay() - no overlay format set\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no overlay format set\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
zr->overlay_active = fh->overlay_active = ZORAN_LOCKED;
@@ -1662,41 +1315,47 @@ setup_overlay (struct file *file,
return wait_grab_pending(zr);
}
- /* get the status of a buffer in the clients buffer queue */
-static int
-zoran_v4l2_buffer_status (struct file *file,
- struct v4l2_buffer *buf,
- int num)
+/* get the status of a buffer in the clients buffer queue */
+static int zoran_v4l2_buffer_status(struct zoran_fh *fh,
+ struct v4l2_buffer *buf, int num)
{
- struct zoran_fh *fh = file->private_data;
struct zoran *zr = fh->zr;
+ unsigned long flags;
buf->flags = V4L2_BUF_FLAG_MAPPED;
switch (fh->map_mode) {
case ZORAN_MAP_MODE_RAW:
-
/* check range */
- if (num < 0 || num >= fh->v4l_buffers.num_buffers ||
- !fh->v4l_buffers.allocated) {
+ if (num < 0 || num >= fh->buffers.num_buffers ||
+ !fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - wrong number or buffers not allocated\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
+ spin_lock_irqsave(&zr->spinlock, flags);
+ dprintk(3,
+ KERN_DEBUG
+ "%s: %s() - raw active=%c, buffer %d: state=%c, map=%c\n",
+ ZR_DEVNAME(zr), __func__,
+ "FAL"[fh->buffers.active], num,
+ "UPMD"[zr->v4l_buffers.buffer[num].state],
+ fh->buffers.buffer[num].map ? 'Y' : 'N');
+ spin_unlock_irqrestore(&zr->spinlock, flags);
+
buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- buf->length = fh->v4l_buffers.buffer_size;
+ buf->length = fh->buffers.buffer_size;
/* get buffer */
- buf->bytesused = fh->v4l_buffers.buffer[num].bs.length;
- if (fh->v4l_buffers.buffer[num].state == BUZ_STATE_DONE ||
- fh->v4l_buffers.buffer[num].state == BUZ_STATE_USER) {
- buf->sequence = fh->v4l_buffers.buffer[num].bs.seq;
+ buf->bytesused = fh->buffers.buffer[num].bs.length;
+ if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
+ fh->buffers.buffer[num].state == BUZ_STATE_USER) {
+ buf->sequence = fh->buffers.buffer[num].bs.seq;
buf->flags |= V4L2_BUF_FLAG_DONE;
- buf->timestamp =
- fh->v4l_buffers.buffer[num].bs.timestamp;
+ buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
} else {
buf->flags |= V4L2_BUF_FLAG_QUEUED;
}
@@ -1712,28 +1371,26 @@ zoran_v4l2_buffer_status (struct file *file,
case ZORAN_MAP_MODE_JPG_PLAY:
/* check range */
- if (num < 0 || num >= fh->jpg_buffers.num_buffers ||
- !fh->jpg_buffers.allocated) {
+ if (num < 0 || num >= fh->buffers.num_buffers ||
+ !fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: v4l2_buffer_status() - wrong number or buffers not allocated\n",
- ZR_DEVNAME(zr));
+ "%s: %s - wrong number or buffers not allocated\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
buf->type = (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
V4L2_BUF_TYPE_VIDEO_CAPTURE :
V4L2_BUF_TYPE_VIDEO_OUTPUT;
- buf->length = fh->jpg_buffers.buffer_size;
+ buf->length = fh->buffers.buffer_size;
/* these variables are only written after frame has been captured */
- if (fh->jpg_buffers.buffer[num].state == BUZ_STATE_DONE ||
- fh->jpg_buffers.buffer[num].state == BUZ_STATE_USER) {
- buf->sequence = fh->jpg_buffers.buffer[num].bs.seq;
- buf->timestamp =
- fh->jpg_buffers.buffer[num].bs.timestamp;
- buf->bytesused =
- fh->jpg_buffers.buffer[num].bs.length;
+ if (fh->buffers.buffer[num].state == BUZ_STATE_DONE ||
+ fh->buffers.buffer[num].state == BUZ_STATE_USER) {
+ buf->sequence = fh->buffers.buffer[num].bs.seq;
+ buf->timestamp = fh->buffers.buffer[num].bs.timestamp;
+ buf->bytesused = fh->buffers.buffer[num].bs.length;
buf->flags |= V4L2_BUF_FLAG_DONE;
} else {
buf->flags |= V4L2_BUF_FLAG_QUEUED;
@@ -1741,14 +1398,11 @@ zoran_v4l2_buffer_status (struct file *file,
/* which fields are these? */
if (fh->jpg_settings.TmpDcm != 1)
- buf->field =
- fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
+ buf->field = fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM;
else
- buf->field =
- fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_TB :
- V4L2_FIELD_SEQ_BT;
+ buf->field = fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT;
break;
@@ -1756,8 +1410,8 @@ zoran_v4l2_buffer_status (struct file *file,
dprintk(5,
KERN_ERR
- "%s: v4l2_buffer_status() - invalid buffer type|map_mode (%d|%d)\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ "%s: %s - invalid buffer type|map_mode (%d|%d)\n",
+ ZR_DEVNAME(zr), __func__, buf->type, fh->map_mode);
return -EINVAL;
}
@@ -1770,81 +1424,55 @@ zoran_v4l2_buffer_status (struct file *file,
static int
zoran_set_norm (struct zoran *zr,
- int norm) /* VIDEO_MODE_* */
+ v4l2_std_id norm)
{
- int norm_encoder, on;
+ int on;
if (zr->v4l_buffers.active != ZORAN_FREE ||
zr->jpg_buffers.active != ZORAN_FREE) {
dprintk(1,
KERN_WARNING
- "%s: set_norm() called while in playback/capture mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s called while in playback/capture mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EBUSY;
}
- if (lock_norm && norm != zr->norm) {
- if (lock_norm > 1) {
- dprintk(1,
- KERN_WARNING
- "%s: set_norm() - TV standard is locked, can not switch norm\n",
- ZR_DEVNAME(zr));
- return -EPERM;
- } else {
- dprintk(1,
- KERN_WARNING
- "%s: set_norm() - TV standard is locked, norm was not changed\n",
- ZR_DEVNAME(zr));
- norm = zr->norm;
- }
- }
-
- if (norm != VIDEO_MODE_AUTO &&
- (norm < 0 || norm >= zr->card.norms ||
- !zr->card.tvn[norm])) {
+ if (!(norm & zr->card.norms)) {
dprintk(1,
- KERN_ERR "%s: set_norm() - unsupported norm %d\n",
- ZR_DEVNAME(zr), norm);
+ KERN_ERR "%s: %s - unsupported norm %llx\n",
+ ZR_DEVNAME(zr), __func__, norm);
return -EINVAL;
}
- if (norm == VIDEO_MODE_AUTO) {
- int status;
+ if (norm == V4L2_STD_ALL) {
+ int status = 0;
+ v4l2_std_id std = 0;
- /* if we have autodetect, ... */
- struct video_decoder_capability caps;
- decoder_command(zr, DECODER_GET_CAPABILITIES, &caps);
- if (!(caps.flags & VIDEO_DECODER_AUTO)) {
- dprintk(1, KERN_ERR "%s: norm=auto unsupported\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
-
- decoder_command(zr, DECODER_SET_NORM, &norm);
+ decoder_call(zr, video, querystd, &std);
+ decoder_call(zr, tuner, s_std, std);
/* let changes come into effect */
ssleep(2);
- decoder_command(zr, DECODER_GET_STATUS, &status);
- if (!(status & DECODER_STATUS_GOOD)) {
+ decoder_call(zr, video, g_input_status, &status);
+ if (status & V4L2_IN_ST_NO_SIGNAL) {
dprintk(1,
KERN_ERR
- "%s: set_norm() - no norm detected\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no norm detected\n",
+ ZR_DEVNAME(zr), __func__);
/* reset norm */
- decoder_command(zr, DECODER_SET_NORM, &zr->norm);
+ decoder_call(zr, tuner, s_std, zr->norm);
return -EIO;
}
- if (status & DECODER_STATUS_NTSC)
- norm = VIDEO_MODE_NTSC;
- else if (status & DECODER_STATUS_SECAM)
- norm = VIDEO_MODE_SECAM;
- else
- norm = VIDEO_MODE_PAL;
+ norm = std;
}
- zr->timing = zr->card.tvn[norm];
- norm_encoder = norm;
+ if (norm & V4L2_STD_SECAM)
+ zr->timing = zr->card.tvn[2];
+ else if (norm & V4L2_STD_NTSC)
+ zr->timing = zr->card.tvn[1];
+ else
+ zr->timing = zr->card.tvn[0];
/* We switch overlay off and on since a change in the
* norm needs different VFE settings */
@@ -1852,8 +1480,8 @@ zoran_set_norm (struct zoran *zr,
if (on)
zr36057_overlay(zr, 0);
- decoder_command(zr, DECODER_SET_NORM, &norm);
- encoder_command(zr, ENCODER_SET_NORM, &norm_encoder);
+ decoder_call(zr, tuner, s_std, norm);
+ encoder_call(zr, video, s_std_output, norm);
if (on)
zr36057_overlay(zr, 1);
@@ -1868,7 +1496,7 @@ static int
zoran_set_input (struct zoran *zr,
int input)
{
- int realinput;
+ struct v4l2_routing route = { 0, 0 };
if (input == zr->input) {
return 0;
@@ -1878,23 +1506,23 @@ zoran_set_input (struct zoran *zr,
zr->jpg_buffers.active != ZORAN_FREE) {
dprintk(1,
KERN_WARNING
- "%s: set_input() called while in playback/capture mode\n",
- ZR_DEVNAME(zr));
+ "%s: %s called while in playback/capture mode\n",
+ ZR_DEVNAME(zr), __func__);
return -EBUSY;
}
if (input < 0 || input >= zr->card.inputs) {
dprintk(1,
KERN_ERR
- "%s: set_input() - unnsupported input %d\n",
- ZR_DEVNAME(zr), input);
+ "%s: %s - unnsupported input %d\n",
+ ZR_DEVNAME(zr), __func__, input);
return -EINVAL;
}
- realinput = zr->card.input[input].muxsel;
+ route.input = zr->card.input[input].muxsel;
zr->input = input;
- decoder_command(zr, DECODER_SET_INPUT, &realinput);
+ decoder_call(zr, video, s_routing, &route);
return 0;
}
@@ -1903,410 +1531,14 @@ zoran_set_input (struct zoran *zr,
* ioctl routine
*/
-static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+static long zoran_default(struct file *file, void *__fh, int cmd, void *arg)
{
- struct zoran_fh *fh = file->private_data;
+ struct zoran_fh *fh = __fh;
struct zoran *zr = fh->zr;
- /* CAREFUL: used in multiple places here */
struct zoran_jpg_settings settings;
- /* we might have older buffers lying around... We don't want
- * to wait, but we do want to try cleaning them up ASAP. So
- * we try to obtain the lock and free them. If that fails, we
- * don't do anything and wait for the next turn. In the end,
- * zoran_close() or a new allocation will still free them...
- * This is just a 'the sooner the better' extra 'feature'
- *
- * We don't free the buffers right on munmap() because that
- * causes oopses (kfree() inside munmap() oopses for no
- * apparent reason - it's also not reproduceable in any way,
- * 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)) {
- /* 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);
- }
-
switch (cmd) {
-
- case VIDIOCGCAP:
- {
- struct video_capability *vcap = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGCAP\n", ZR_DEVNAME(zr));
-
- memset(vcap, 0, sizeof(struct video_capability));
- strncpy(vcap->name, ZR_DEVNAME(zr), sizeof(vcap->name)-1);
- vcap->type = ZORAN_VID_TYPE;
-
- vcap->channels = zr->card.inputs;
- vcap->audios = 0;
- mutex_lock(&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);
-
- return 0;
- }
- break;
-
- case VIDIOCGCHAN:
- {
- struct video_channel *vchan = arg;
- int channel = vchan->channel;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGCHAN - channel=%d\n",
- ZR_DEVNAME(zr), vchan->channel);
-
- memset(vchan, 0, sizeof(struct video_channel));
- if (channel > zr->card.inputs || channel < 0) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCGCHAN on not existing channel %d\n",
- ZR_DEVNAME(zr), channel);
- return -EINVAL;
- }
-
- strcpy(vchan->name, zr->card.input[channel].name);
-
- vchan->tuners = 0;
- vchan->flags = 0;
- vchan->type = VIDEO_TYPE_CAMERA;
- mutex_lock(&zr->resource_lock);
- vchan->norm = zr->norm;
- mutex_unlock(&zr->resource_lock);
- vchan->channel = channel;
-
- return 0;
- }
- 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
- * * and we follow it for compatibility reasons
- * *
- * * BTW: this is the only way the user can set the norm!
- */
-
- case VIDIOCSCHAN:
- {
- struct video_channel *vchan = arg;
- int res;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSCHAN - channel=%d, norm=%d\n",
- ZR_DEVNAME(zr), vchan->channel, vchan->norm);
-
- mutex_lock(&zr->resource_lock);
- if ((res = zoran_set_input(zr, vchan->channel)))
- goto schan_unlock_and_return;
- if ((res = zoran_set_norm(zr, vchan->norm)))
- goto schan_unlock_and_return;
-
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
- schan_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
-
- case VIDIOCGPICT:
- {
- struct video_picture *vpict = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGPICT\n", ZR_DEVNAME(zr));
-
- memset(vpict, 0, sizeof(struct video_picture));
- mutex_lock(&zr->resource_lock);
- vpict->hue = zr->hue;
- vpict->brightness = zr->brightness;
- vpict->contrast = zr->contrast;
- vpict->colour = zr->saturation;
- if (fh->overlay_settings.format) {
- vpict->depth = fh->overlay_settings.format->depth;
- vpict->palette = fh->overlay_settings.format->palette;
- } else {
- vpict->depth = 0;
- }
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
- break;
-
- case VIDIOCSPICT:
- {
- struct video_picture *vpict = arg;
- int i;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSPICT - bri=%d, hue=%d, col=%d, con=%d, dep=%d, pal=%d\n",
- ZR_DEVNAME(zr), vpict->brightness, vpict->hue,
- vpict->colour, vpict->contrast, vpict->depth,
- vpict->palette);
-
- for (i = 0; i < NUM_FORMATS; i++) {
- const struct zoran_format *fmt = &zoran_formats[i];
-
- if (fmt->palette != -1 &&
- fmt->flags & ZORAN_FORMAT_OVERLAY &&
- fmt->palette == vpict->palette &&
- fmt->depth == vpict->depth)
- break;
- }
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCSPICT - Invalid palette %d\n",
- ZR_DEVNAME(zr), vpict->palette);
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
-
- decoder_command(zr, DECODER_SET_PICTURE, vpict);
-
- zr->hue = vpict->hue;
- zr->contrast = vpict->contrast;
- zr->saturation = vpict->colour;
- zr->brightness = vpict->brightness;
-
- fh->overlay_settings.format = &zoran_formats[i];
-
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
- break;
-
- case VIDIOCCAPTURE:
- {
- int *on = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCCAPTURE - on=%d\n",
- ZR_DEVNAME(zr), *on);
-
- mutex_lock(&zr->resource_lock);
- res = setup_overlay(file, *on);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
- break;
-
- case VIDIOCGWIN:
- {
- struct video_window *vwin = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGWIN\n", ZR_DEVNAME(zr));
-
- memset(vwin, 0, sizeof(struct video_window));
- mutex_lock(&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);
- vwin->clipcount = 0;
- return 0;
- }
- break;
-
- case VIDIOCSWIN:
- {
- struct video_window *vwin = arg;
- int res;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSWIN - x=%d, y=%d, w=%d, h=%d, clipcount=%d\n",
- ZR_DEVNAME(zr), vwin->x, vwin->y, vwin->width,
- vwin->height, vwin->clipcount);
-
- mutex_lock(&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);
-
- return res;
- }
- break;
-
- case VIDIOCGFBUF:
- {
- struct video_buffer *vbuf = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGFBUF\n", ZR_DEVNAME(zr));
-
- mutex_lock(&zr->resource_lock);
- *vbuf = zr->buffer;
- mutex_unlock(&zr->resource_lock);
- return 0;
- }
- break;
-
- case VIDIOCSFBUF:
- {
- struct video_buffer *vbuf = arg;
- int i, res = 0;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCSFBUF - base=%p, w=%d, h=%d, depth=%d, bpl=%d\n",
- ZR_DEVNAME(zr), vbuf->base, vbuf->width,
- vbuf->height, vbuf->depth, vbuf->bytesperline);
-
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].depth == vbuf->depth)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCSFBUF - invalid fbuf depth %d\n",
- ZR_DEVNAME(zr), vbuf->depth);
- return -EINVAL;
- }
-
- mutex_lock(&zr->resource_lock);
- res =
- setup_fbuffer(file, vbuf->base, &zoran_formats[i],
- vbuf->width, vbuf->height,
- vbuf->bytesperline);
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
- break;
-
- case VIDIOCSYNC:
- {
- int *frame = arg, res;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCSYNC - frame=%d\n",
- ZR_DEVNAME(zr), *frame);
-
- mutex_lock(&zr->resource_lock);
- res = v4l_sync(file, *frame);
- mutex_unlock(&zr->resource_lock);
- if (!res)
- zr->v4l_sync_tail++;
- return res;
- }
- break;
-
- case VIDIOCMCAPTURE:
- {
- struct video_mmap *vmap = arg;
- int res;
-
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOCMCAPTURE - frame=%d, geom=%dx%d, fmt=%d\n",
- ZR_DEVNAME(zr), vmap->frame, vmap->width, vmap->height,
- vmap->format);
-
- mutex_lock(&zr->resource_lock);
- res = v4l_grab(file, vmap);
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
-
- case VIDIOCGMBUF:
- {
- struct video_mbuf *vmbuf = arg;
- int i, res = 0;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGMBUF\n", ZR_DEVNAME(zr));
-
- vmbuf->size =
- fh->v4l_buffers.num_buffers *
- fh->v4l_buffers.buffer_size;
- vmbuf->frames = fh->v4l_buffers.num_buffers;
- for (i = 0; i < vmbuf->frames; i++) {
- vmbuf->offsets[i] =
- i * fh->v4l_buffers.buffer_size;
- }
-
- mutex_lock(&zr->resource_lock);
-
- if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOCGMBUF - buffers already allocated\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- if (v4l_fbuffer_alloc(file)) {
- res = -ENOMEM;
- goto v4l1reqbuf_unlock_and_return;
- }
-
- /* The next mmap will map the V4L buffers */
- fh->map_mode = ZORAN_MAP_MODE_RAW;
- v4l1reqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
- }
- break;
-
- case VIDIOCGUNIT:
- {
- struct video_unit *vunit = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOCGUNIT\n", ZR_DEVNAME(zr));
-
- vunit->video = zr->video_dev->minor;
- vunit->vbi = VIDEO_NO_UNIT;
- vunit->radio = VIDEO_NO_UNIT;
- vunit->audio = VIDEO_NO_UNIT;
- vunit->teletext = VIDEO_NO_UNIT;
-
- return 0;
- }
- break;
-
- /*
- * RJ: In principal we could support subcaptures for V4L grabbing.
- * Not even the famous BTTV driver has them, however.
- * If there should be a strong demand, one could consider
- * to implement them.
- */
- case VIDIOCGCAPTURE:
- {
- dprintk(3, KERN_ERR "%s: VIDIOCGCAPTURE not supported\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
- break;
-
- case VIDIOCSCAPTURE:
- {
- dprintk(3, KERN_ERR "%s: VIDIOCSCAPTURE not supported\n",
- ZR_DEVNAME(zr));
- return -EINVAL;
- }
- break;
-
case BUZIOC_G_PARAMS:
{
struct zoran_params *bparams = arg;
@@ -2319,7 +1551,13 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
mutex_lock(&zr->resource_lock);
- bparams->norm = zr->norm;
+ if (zr->norm & V4L2_STD_NTSC)
+ bparams->norm = VIDEO_MODE_NTSC;
+ else if (zr->norm & V4L2_STD_PAL)
+ bparams->norm = VIDEO_MODE_PAL;
+ else
+ bparams->norm = VIDEO_MODE_SECAM;
+
bparams->input = zr->input;
bparams->decimation = fh->jpg_settings.decimation;
@@ -2352,7 +1590,6 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return 0;
}
- break;
case BUZIOC_S_PARAMS:
{
@@ -2395,18 +1632,17 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
/* Check the params first before overwriting our
* nternal values */
- if (zoran_check_jpg_settings(zr, &settings)) {
+ if (zoran_check_jpg_settings(zr, &settings, 0)) {
res = -EINVAL;
goto sparams_unlock_and_return;
}
fh->jpg_settings = settings;
- sparams_unlock_and_return:
+sparams_unlock_and_return:
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_REQBUFS:
{
@@ -2430,38 +1666,34 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
* tables to a Maximum of 2 MB */
if (breq->size > jpg_bufsize)
breq->size = jpg_bufsize;
- if (fh->jpg_buffers.need_contiguous &&
- breq->size > MAX_KMALLOC_MEM)
- breq->size = MAX_KMALLOC_MEM;
mutex_lock(&zr->resource_lock);
- if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
+ if (fh->buffers.allocated) {
dprintk(1,
KERN_ERR
- "%s: BUZIOC_REQBUFS - buffers allready allocated\n",
+ "%s: BUZIOC_REQBUFS - buffers already allocated\n",
ZR_DEVNAME(zr));
res = -EBUSY;
goto jpgreqbuf_unlock_and_return;
}
- fh->jpg_buffers.num_buffers = breq->count;
- fh->jpg_buffers.buffer_size = breq->size;
+ /* The next mmap will map the MJPEG buffers - could
+ * also be *_PLAY, but it doesn't matter here */
+ map_mode_jpg(fh, 0);
+ fh->buffers.num_buffers = breq->count;
+ fh->buffers.buffer_size = breq->size;
- if (jpg_fbuffer_alloc(file)) {
+ if (jpg_fbuffer_alloc(fh)) {
res = -ENOMEM;
goto jpgreqbuf_unlock_and_return;
}
- /* The next mmap will map the MJPEG buffers - could
- * also be *_PLAY, but it doesn't matter here */
- fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
- jpgreqbuf_unlock_and_return:
+jpgreqbuf_unlock_and_return:
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_QBUF_CAPT:
{
@@ -2471,12 +1703,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
ZR_DEVNAME(zr), *frame);
mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_COMPRESS);
+ res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_COMPRESS);
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_QBUF_PLAY:
{
@@ -2486,12 +1717,11 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
ZR_DEVNAME(zr), *frame);
mutex_lock(&zr->resource_lock);
- res = jpg_qbuf(file, *frame, BUZ_MODE_MOTION_DECOMPRESS);
+ res = jpg_qbuf(fh, *frame, BUZ_MODE_MOTION_DECOMPRESS);
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_SYNC:
{
@@ -2501,17 +1731,26 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
dprintk(3, KERN_DEBUG "%s: BUZIOC_SYNC\n", ZR_DEVNAME(zr));
mutex_lock(&zr->resource_lock);
- res = jpg_sync(file, bsync);
+
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+ dprintk(2, KERN_WARNING
+ "%s: %s - not in jpg capture mode\n",
+ ZR_DEVNAME(zr), __func__);
+ res = -EINVAL;
+ } else {
+ res = jpg_sync(fh, bsync);
+ }
mutex_unlock(&zr->resource_lock);
return res;
}
- break;
case BUZIOC_G_STATUS:
{
struct zoran_status *bstat = arg;
- int norm, input, status, res = 0;
+ struct v4l2_routing route = { 0, 0 };
+ int status = 0, res = 0;
+ v4l2_std_id norm;
dprintk(3, KERN_DEBUG "%s: BUZIOC_G_STATUS\n", ZR_DEVNAME(zr));
@@ -2523,8 +1762,7 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return -EINVAL;
}
- input = zr->card.input[bstat->input].muxsel;
- norm = VIDEO_MODE_AUTO;
+ route.input = zr->card.input[bstat->input].muxsel;
mutex_lock(&zr->resource_lock);
@@ -2537,1629 +1775,1262 @@ static long zoran_do_ioctl(struct file *file, unsigned int cmd, void *arg)
goto gstat_unlock_and_return;
}
- decoder_command(zr, DECODER_SET_INPUT, &input);
- decoder_command(zr, DECODER_SET_NORM, &norm);
+ decoder_call(zr, video, s_routing, &route);
/* sleep 1 second */
ssleep(1);
/* Get status of video decoder */
- decoder_command(zr, DECODER_GET_STATUS, &status);
+ decoder_call(zr, video, querystd, &norm);
+ decoder_call(zr, video, g_input_status, &status);
/* restore previous input and norm */
- input = zr->card.input[zr->input].muxsel;
- decoder_command(zr, DECODER_SET_INPUT, &input);
- decoder_command(zr, DECODER_SET_NORM, &zr->norm);
- gstat_unlock_and_return:
+ route.input = zr->card.input[zr->input].muxsel;
+ decoder_call(zr, video, s_routing, &route);
+gstat_unlock_and_return:
mutex_unlock(&zr->resource_lock);
if (!res) {
bstat->signal =
- (status & DECODER_STATUS_GOOD) ? 1 : 0;
- if (status & DECODER_STATUS_NTSC)
+ (status & V4L2_IN_ST_NO_SIGNAL) ? 0 : 1;
+ if (norm & V4L2_STD_NTSC)
bstat->norm = VIDEO_MODE_NTSC;
- else if (status & DECODER_STATUS_SECAM)
+ else if (norm & V4L2_STD_SECAM)
bstat->norm = VIDEO_MODE_SECAM;
else
bstat->norm = VIDEO_MODE_PAL;
bstat->color =
- (status & DECODER_STATUS_COLOR) ? 1 : 0;
+ (status & V4L2_IN_ST_NO_COLOR) ? 0 : 1;
}
return res;
}
- break;
-
- /* The new video4linux2 capture interface - much nicer than video4linux1, since
- * it allows for integrating the JPEG capturing calls inside standard v4l2
- */
-
- case VIDIOC_QUERYCAP:
- {
- struct v4l2_capability *cap = arg;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCAP\n", ZR_DEVNAME(zr));
-
- memset(cap, 0, sizeof(*cap));
- strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
- strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
- snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
- pci_name(zr->pci_dev));
- cap->version =
- KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
- RELEASE_VERSION);
- cap->capabilities = ZORAN_V4L2_VID_FLAGS;
-
- return 0;
+ default:
+ return -EINVAL;
}
- break;
+}
- case VIDIOC_ENUM_FMT:
- {
- struct v4l2_fmtdesc *fmt = arg;
- int index = fmt->index, num = -1, i, flag = 0, type =
- fmt->type;
+static int zoran_vidiocgmbuf(struct file *file, void *__fh, struct video_mbuf *vmbuf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i, res = 0;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUM_FMT - index=%d\n",
- ZR_DEVNAME(zr), fmt->index);
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- flag = ZORAN_FORMAT_CAPTURE;
- break;
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- flag = ZORAN_FORMAT_PLAYBACK;
- break;
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- flag = ZORAN_FORMAT_OVERLAY;
- break;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_ENUM_FMT - unknown type %d\n",
- ZR_DEVNAME(zr), fmt->type);
- return -EINVAL;
- }
+ mutex_lock(&zr->resource_lock);
- for (i = 0; i < NUM_FORMATS; i++) {
- if (zoran_formats[i].flags & flag)
- num++;
- if (num == fmt->index)
- break;
- }
- if (fmt->index < 0 /* late, but not too late */ ||
- i == NUM_FORMATS)
- return -EINVAL;
+ if (fh->buffers.allocated) {
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOCGMBUF - buffers already allocated\n",
+ ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto v4l1reqbuf_unlock_and_return;
+ }
- memset(fmt, 0, sizeof(*fmt));
- fmt->index = index;
- fmt->type = type;
- strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
- fmt->pixelformat = zoran_formats[i].fourcc;
- if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
- fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ /* The next mmap will map the V4L buffers */
+ map_mode_raw(fh);
- return 0;
+ if (v4l_fbuffer_alloc(fh)) {
+ res = -ENOMEM;
+ goto v4l1reqbuf_unlock_and_return;
}
- break;
-
- case VIDIOC_G_FMT:
- {
- struct v4l2_format *fmt = arg;
- int type = fmt->type;
- dprintk(5, KERN_DEBUG "%s: VIDIOC_G_FMT\n", ZR_DEVNAME(zr));
+ vmbuf->size = fh->buffers.num_buffers * fh->buffers.buffer_size;
+ vmbuf->frames = fh->buffers.num_buffers;
+ for (i = 0; i < vmbuf->frames; i++)
+ vmbuf->offsets[i] = i * fh->buffers.buffer_size;
- memset(fmt, 0, sizeof(*fmt));
- fmt->type = type;
+v4l1reqbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ return res;
+}
+#endif
- mutex_lock(&zr->resource_lock);
+static int zoran_querycap(struct file *file, void *__fh, struct v4l2_capability *cap)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- fmt->fmt.win.w.left = fh->overlay_settings.x;
- fmt->fmt.win.w.top = fh->overlay_settings.y;
- fmt->fmt.win.w.width = fh->overlay_settings.width;
- fmt->fmt.win.w.height =
- fh->overlay_settings.height;
- if (fh->overlay_settings.width * 2 >
- BUZ_MAX_HEIGHT)
- fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.win.field = V4L2_FIELD_TOP;
+ memset(cap, 0, sizeof(*cap));
+ strncpy(cap->card, ZR_DEVNAME(zr), sizeof(cap->card)-1);
+ strncpy(cap->driver, "zoran", sizeof(cap->driver)-1);
+ snprintf(cap->bus_info, sizeof(cap->bus_info), "PCI:%s",
+ pci_name(zr->pci_dev));
+ cap->version = KERNEL_VERSION(MAJOR_VERSION, MINOR_VERSION,
+ RELEASE_VERSION);
+ cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OVERLAY;
+ return 0;
+}
- mutex_unlock(&zr->resource_lock);
+static int zoran_enum_fmt(struct zoran *zr, struct v4l2_fmtdesc *fmt, int flag)
+{
+ int num = -1, i;
+ for (i = 0; i < NUM_FORMATS; i++) {
+ if (zoran_formats[i].flags & flag)
+ num++;
+ if (num == fmt->index)
break;
+ }
+ if (fmt->index < 0 /* late, but not too late */ || i == NUM_FORMATS)
+ return -EINVAL;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-
- mutex_lock(&zr->resource_lock);
-
- if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
- fh->map_mode == ZORAN_MAP_MODE_RAW) {
-
- fmt->fmt.pix.width =
- fh->v4l_settings.width;
- fmt->fmt.pix.height =
- fh->v4l_settings.height;
- fmt->fmt.pix.sizeimage =
- fh->v4l_settings.bytesperline *
- fh->v4l_settings.height;
- fmt->fmt.pix.pixelformat =
- fh->v4l_settings.format->fourcc;
- fmt->fmt.pix.colorspace =
- fh->v4l_settings.format->colorspace;
- fmt->fmt.pix.bytesperline =
- fh->v4l_settings.bytesperline;
- if (BUZ_MAX_HEIGHT <
- (fh->v4l_settings.height * 2))
- fmt->fmt.pix.field =
- V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.pix.field =
- V4L2_FIELD_TOP;
-
- } else {
-
- fmt->fmt.pix.width =
- fh->jpg_settings.img_width /
- fh->jpg_settings.HorDcm;
- fmt->fmt.pix.height =
- fh->jpg_settings.img_height /
- (fh->jpg_settings.VerDcm *
- fh->jpg_settings.TmpDcm);
- fmt->fmt.pix.sizeimage =
- zoran_v4l2_calc_bufsize(&fh->
- jpg_settings);
- fmt->fmt.pix.pixelformat =
- V4L2_PIX_FMT_MJPEG;
- if (fh->jpg_settings.TmpDcm == 1)
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_BT :
- V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP :
- V4L2_FIELD_BOTTOM);
-
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.colorspace =
- V4L2_COLORSPACE_SMPTE170M;
- }
-
- mutex_unlock(&zr->resource_lock);
+ strncpy(fmt->description, zoran_formats[i].name, sizeof(fmt->description)-1);
+ fmt->pixelformat = zoran_formats[i].fourcc;
+ if (zoran_formats[i].flags & ZORAN_FORMAT_COMPRESSED)
+ fmt->flags |= V4L2_FMT_FLAG_COMPRESSED;
+ return 0;
+}
- break;
+static int zoran_enum_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_G_FMT - unsupported type %d\n",
- ZR_DEVNAME(zr), fmt->type);
- return -EINVAL;
- }
- return 0;
- }
- break;
+ return zoran_enum_fmt(zr, f, ZORAN_FORMAT_CAPTURE);
+}
- case VIDIOC_S_FMT:
- {
- struct v4l2_format *fmt = arg;
- int i, res = 0;
- __le32 printformat;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_FMT - type=%d, ",
- ZR_DEVNAME(zr), fmt->type);
-
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
-
- dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
- fmt->fmt.win.w.left, fmt->fmt.win.w.top,
- fmt->fmt.win.w.width,
- fmt->fmt.win.w.height,
- fmt->fmt.win.clipcount,
- fmt->fmt.win.bitmap);
- mutex_lock(&zr->resource_lock);
- res =
- setup_window(file, fmt->fmt.win.w.left,
- fmt->fmt.win.w.top,
- fmt->fmt.win.w.width,
- fmt->fmt.win.w.height,
- (struct video_clip __user *)
- fmt->fmt.win.clips,
- fmt->fmt.win.clipcount,
- fmt->fmt.win.bitmap);
- mutex_unlock(&zr->resource_lock);
- return res;
- break;
+static int zoran_enum_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
-
- printformat =
- __cpu_to_le32(fmt->fmt.pix.pixelformat);
- dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
- fmt->fmt.pix.width, fmt->fmt.pix.height,
- fmt->fmt.pix.pixelformat,
- (char *) &printformat);
-
- /* we can be requested to do JPEG/raw playback/capture */
- if (!
- (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- fmt->fmt.pix.pixelformat ==
- V4L2_PIX_FMT_MJPEG))) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - unknown type %d/0x%x(%4.4s) combination\n",
- ZR_DEVNAME(zr), fmt->type,
- fmt->fmt.pix.pixelformat,
- (char *) &printformat);
- return -EINVAL;
- }
+ return zoran_enum_fmt(zr, f, ZORAN_FORMAT_PLAYBACK);
+}
- if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
- mutex_lock(&zr->resource_lock);
+static int zoran_enum_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_fmtdesc *f)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- settings = fh->jpg_settings;
+ return zoran_enum_fmt(zr, f, ZORAN_FORMAT_OVERLAY);
+}
- if (fh->v4l_buffers.allocated ||
- fh->jpg_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - cannot change capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sfmtjpg_unlock_and_return;
- }
+static int zoran_g_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- /* we actually need to set 'real' parameters now */
- if ((fmt->fmt.pix.height * 2) >
- BUZ_MAX_HEIGHT)
- settings.TmpDcm = 1;
- else
- settings.TmpDcm = 2;
- settings.decimation = 0;
- if (fmt->fmt.pix.height <=
- fh->jpg_settings.img_height / 2)
- settings.VerDcm = 2;
- else
- settings.VerDcm = 1;
- if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 4)
- settings.HorDcm = 4;
- else if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 2)
- settings.HorDcm = 2;
- else
- settings.HorDcm = 1;
- if (settings.TmpDcm == 1)
- settings.field_per_buff = 2;
- else
- settings.field_per_buff = 1;
-
- /* check */
- if ((res =
- zoran_check_jpg_settings(zr,
- &settings)))
- goto sfmtjpg_unlock_and_return;
-
- /* it's ok, so set them */
- fh->jpg_settings = settings;
-
- /* tell the user what we actually did */
- fmt->fmt.pix.width =
- settings.img_width / settings.HorDcm;
- fmt->fmt.pix.height =
- settings.img_height * 2 /
- (settings.TmpDcm * settings.VerDcm);
- if (settings.TmpDcm == 1)
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_TB :
- V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP :
- V4L2_FIELD_BOTTOM);
- fh->jpg_buffers.buffer_size =
- zoran_v4l2_calc_bufsize(&fh->
- jpg_settings);
- fmt->fmt.pix.bytesperline = 0;
- fmt->fmt.pix.sizeimage =
- fh->jpg_buffers.buffer_size;
- fmt->fmt.pix.colorspace =
- V4L2_COLORSPACE_SMPTE170M;
-
- /* we hereby abuse this variable to show that
- * we're gonna do mjpeg capture */
- fh->map_mode =
- (fmt->type ==
- V4L2_BUF_TYPE_VIDEO_CAPTURE) ?
- ZORAN_MAP_MODE_JPG_REC :
- ZORAN_MAP_MODE_JPG_PLAY;
- sfmtjpg_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- } else {
- for (i = 0; i < NUM_FORMATS; i++)
- if (fmt->fmt.pix.pixelformat ==
- zoran_formats[i].fourcc)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x (%4.4s)\n",
- ZR_DEVNAME(zr),
- fmt->fmt.pix.pixelformat,
- (char *) &printformat);
- return -EINVAL;
- }
- mutex_lock(&zr->resource_lock);
- if (fh->jpg_buffers.allocated ||
- (fh->v4l_buffers.allocated &&
- fh->v4l_buffers.active !=
- ZORAN_FREE)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - cannot change capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sfmtv4l_unlock_and_return;
- }
- if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
- fmt->fmt.pix.height =
- BUZ_MAX_HEIGHT;
- if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
- fmt->fmt.pix.width = BUZ_MAX_WIDTH;
-
- if ((res =
- zoran_v4l_set_format(file,
- fmt->fmt.pix.
- width,
- fmt->fmt.pix.
- height,
- &zoran_formats
- [i])))
- goto sfmtv4l_unlock_and_return;
-
- /* tell the user the
- * results/missing stuff */
- fmt->fmt.pix.bytesperline =
- fh->v4l_settings.bytesperline;
- fmt->fmt.pix.sizeimage =
- fh->v4l_settings.height *
- fh->v4l_settings.bytesperline;
- fmt->fmt.pix.colorspace =
- fh->v4l_settings.format->colorspace;
- if (BUZ_MAX_HEIGHT <
- (fh->v4l_settings.height * 2))
- fmt->fmt.pix.field =
- V4L2_FIELD_INTERLACED;
- else
- fmt->fmt.pix.field =
- V4L2_FIELD_TOP;
-
- fh->map_mode = ZORAN_MAP_MODE_RAW;
- sfmtv4l_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- }
+ mutex_lock(&zr->resource_lock);
- break;
+ fmt->fmt.pix.width = fh->jpg_settings.img_width / fh->jpg_settings.HorDcm;
+ fmt->fmt.pix.height = fh->jpg_settings.img_height * 2 /
+ (fh->jpg_settings.VerDcm * fh->jpg_settings.TmpDcm);
+ fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+ fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
+ if (fh->jpg_settings.TmpDcm == 1)
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+ else
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FMT - unsupported type %d\n",
- ZR_DEVNAME(zr), fmt->type);
- return -EINVAL;
- }
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- return res;
- }
- break;
+static int zoran_g_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- case VIDIOC_G_FBUF:
- {
- struct v4l2_framebuffer *fb = arg;
+ if (fh->map_mode != ZORAN_MAP_MODE_RAW)
+ return zoran_g_fmt_vid_out(file, fh, fmt);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_FBUF\n", ZR_DEVNAME(zr));
+ mutex_lock(&zr->resource_lock);
+ fmt->fmt.pix.width = fh->v4l_settings.width;
+ fmt->fmt.pix.height = fh->v4l_settings.height;
+ fmt->fmt.pix.sizeimage = fh->v4l_settings.bytesperline *
+ fh->v4l_settings.height;
+ fmt->fmt.pix.pixelformat = fh->v4l_settings.format->fourcc;
+ fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
+ fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
+ if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
+ fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ else
+ fmt->fmt.pix.field = V4L2_FIELD_TOP;
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- memset(fb, 0, sizeof(*fb));
- mutex_lock(&zr->resource_lock);
- fb->base = zr->buffer.base;
- fb->fmt.width = zr->buffer.width;
- fb->fmt.height = zr->buffer.height;
- if (zr->overlay_settings.format) {
- fb->fmt.pixelformat =
- fh->overlay_settings.format->fourcc;
- }
- fb->fmt.bytesperline = zr->buffer.bytesperline;
- mutex_unlock(&zr->resource_lock);
- fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
- fb->fmt.field = V4L2_FIELD_INTERLACED;
- fb->flags = V4L2_FBUF_FLAG_OVERLAY;
- fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
+static int zoran_g_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- return 0;
- }
- break;
+ mutex_lock(&zr->resource_lock);
- case VIDIOC_S_FBUF:
- {
- int i, res = 0;
- struct v4l2_framebuffer *fb = arg;
- __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
+ fmt->fmt.win.w.left = fh->overlay_settings.x;
+ fmt->fmt.win.w.top = fh->overlay_settings.y;
+ fmt->fmt.win.w.width = fh->overlay_settings.width;
+ fmt->fmt.win.w.height = fh->overlay_settings.height;
+ if (fh->overlay_settings.width * 2 > BUZ_MAX_HEIGHT)
+ fmt->fmt.win.field = V4L2_FIELD_INTERLACED;
+ else
+ fmt->fmt.win.field = V4L2_FIELD_TOP;
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOC_S_FBUF - base=0x%p, size=%dx%d, bpl=%d, fmt=0x%x (%4.4s)\n",
- ZR_DEVNAME(zr), fb->base, fb->fmt.width, fb->fmt.height,
- fb->fmt.bytesperline, fb->fmt.pixelformat,
- (char *) &printformat);
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
- break;
- if (i == NUM_FORMATS) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
- ZR_DEVNAME(zr), fb->fmt.pixelformat,
- (char *) &printformat);
- return -EINVAL;
- }
+static int zoran_try_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- mutex_lock(&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);
+ mutex_lock(&zr->resource_lock);
- return res;
- }
- break;
+ if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
+ fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
+ if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
+ fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
+ if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
+ fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
+ if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
+ fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
- case VIDIOC_OVERLAY:
- {
- int *on = arg, res;
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_PREVIEW - on=%d\n",
- ZR_DEVNAME(zr), *on);
+static int zoran_try_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ struct zoran_jpg_settings settings;
+ int res = 0;
- mutex_lock(&zr->resource_lock);
- res = setup_overlay(file, *on);
- mutex_unlock(&zr->resource_lock);
+ if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+ return -EINVAL;
- return res;
- }
- break;
+ mutex_lock(&zr->resource_lock);
+ settings = fh->jpg_settings;
- case VIDIOC_REQBUFS:
- {
- struct v4l2_requestbuffers *req = arg;
- int res = 0;
+ /* we actually need to set 'real' parameters now */
+ if ((fmt->fmt.pix.height * 2) > BUZ_MAX_HEIGHT)
+ settings.TmpDcm = 1;
+ else
+ settings.TmpDcm = 2;
+ settings.decimation = 0;
+ if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
+ settings.VerDcm = 2;
+ else
+ settings.VerDcm = 1;
+ if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
+ settings.HorDcm = 4;
+ else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
+ settings.HorDcm = 2;
+ else
+ settings.HorDcm = 1;
+ if (settings.TmpDcm == 1)
+ settings.field_per_buff = 2;
+ else
+ settings.field_per_buff = 1;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_REQBUFS - type=%d\n",
- ZR_DEVNAME(zr), req->type);
+ if (settings.HorDcm > 1) {
+ settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+ settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+ } else {
+ settings.img_x = 0;
+ settings.img_width = BUZ_MAX_WIDTH;
+ }
+
+ /* check */
+ res = zoran_check_jpg_settings(zr, &settings, 1);
+ if (res)
+ goto tryfmt_unlock_and_return;
+
+ /* tell the user what we actually did */
+ fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
+ fmt->fmt.pix.height = settings.img_height * 2 /
+ (settings.TmpDcm * settings.VerDcm);
+ if (settings.TmpDcm == 1)
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+ else
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
- if (req->memory != V4L2_MEMORY_MMAP) {
- dprintk(1,
- KERN_ERR
- "%s: only MEMORY_MMAP capture is supported, not %d\n",
- ZR_DEVNAME(zr), req->memory);
- return -EINVAL;
- }
+ fmt->fmt.pix.sizeimage = zoran_v4l2_calc_bufsize(&settings);
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+tryfmt_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_try_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int bpp;
+ int i;
- if (fh->v4l_buffers.allocated || fh->jpg_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_REQBUFS - buffers allready allocated\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto v4l2reqbuf_unlock_and_return;
- }
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+ return zoran_try_fmt_vid_out(file, fh, fmt);
- if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
- req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ mutex_lock(&zr->resource_lock);
- /* control user input */
- if (req->count < 2)
- req->count = 2;
- if (req->count > v4l_nbufs)
- req->count = v4l_nbufs;
- fh->v4l_buffers.num_buffers = req->count;
+ for (i = 0; i < NUM_FORMATS; i++)
+ if (zoran_formats[i].fourcc == fmt->fmt.pix.pixelformat)
+ break;
- if (v4l_fbuffer_alloc(file)) {
- res = -ENOMEM;
- goto v4l2reqbuf_unlock_and_return;
- }
+ if (i == NUM_FORMATS) {
+ mutex_unlock(&zr->resource_lock);
+ return -EINVAL;
+ }
- /* The next mmap will map the V4L buffers */
- fh->map_mode = ZORAN_MAP_MODE_RAW;
+ bpp = (zoran_formats[i].depth + 7) / 8;
+ fmt->fmt.pix.width &= ~((bpp == 2) ? 1 : 3);
+ if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
+ fmt->fmt.pix.width = BUZ_MAX_WIDTH;
+ if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
+ fmt->fmt.pix.width = BUZ_MIN_WIDTH;
+ if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
+ fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
+ if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
+ fmt->fmt.pix.height = BUZ_MIN_HEIGHT;
+ mutex_unlock(&zr->resource_lock);
- } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
- fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+ return 0;
+}
- /* we need to calculate size ourselves now */
- if (req->count < 4)
- req->count = 4;
- if (req->count > jpg_nbufs)
- req->count = jpg_nbufs;
- fh->jpg_buffers.num_buffers = req->count;
- fh->jpg_buffers.buffer_size =
- zoran_v4l2_calc_bufsize(&fh->jpg_settings);
+static int zoran_s_fmt_vid_overlay(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
+
+ dprintk(3, "x=%d, y=%d, w=%d, h=%d, cnt=%d, map=0x%p\n",
+ fmt->fmt.win.w.left, fmt->fmt.win.w.top,
+ fmt->fmt.win.w.width,
+ fmt->fmt.win.w.height,
+ fmt->fmt.win.clipcount,
+ fmt->fmt.win.bitmap);
+ mutex_lock(&zr->resource_lock);
+ res = setup_window(fh, fmt->fmt.win.w.left, fmt->fmt.win.w.top,
+ fmt->fmt.win.w.width, fmt->fmt.win.w.height,
+ (struct v4l2_clip __user *)fmt->fmt.win.clips,
+ fmt->fmt.win.clipcount, fmt->fmt.win.bitmap);
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- if (jpg_fbuffer_alloc(file)) {
- res = -ENOMEM;
- goto v4l2reqbuf_unlock_and_return;
- }
+static int zoran_s_fmt_vid_out(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ __le32 printformat = __cpu_to_le32(fmt->fmt.pix.pixelformat);
+ struct zoran_jpg_settings settings;
+ int res = 0;
- /* The next mmap will map the MJPEG buffers */
- if (req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
- fh->map_mode = ZORAN_MAP_MODE_JPG_REC;
- else
- fh->map_mode = ZORAN_MAP_MODE_JPG_PLAY;
+ dprintk(3, "size=%dx%d, fmt=0x%x (%4.4s)\n",
+ fmt->fmt.pix.width, fmt->fmt.pix.height,
+ fmt->fmt.pix.pixelformat,
+ (char *) &printformat);
+ if (fmt->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
+ return -EINVAL;
- } else {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_REQBUFS - unknown type %d\n",
- ZR_DEVNAME(zr), req->type);
- res = -EINVAL;
- goto v4l2reqbuf_unlock_and_return;
- }
- v4l2reqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- return 0;
+ if (fh->buffers.allocated) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto sfmtjpg_unlock_and_return;
}
- break;
- case VIDIOC_QUERYBUF:
- {
- struct v4l2_buffer *buf = arg;
- __u32 type = buf->type;
- int index = buf->index, res;
+ settings = fh->jpg_settings;
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOC_QUERYBUF - index=%d, type=%d\n",
- ZR_DEVNAME(zr), buf->index, buf->type);
-
- memset(buf, 0, sizeof(*buf));
- buf->type = type;
- buf->index = index;
-
- mutex_lock(&zr->resource_lock);
- res = zoran_v4l2_buffer_status(file, buf, buf->index);
- mutex_unlock(&zr->resource_lock);
+ /* we actually need to set 'real' parameters now */
+ if (fmt->fmt.pix.height * 2 > BUZ_MAX_HEIGHT)
+ settings.TmpDcm = 1;
+ else
+ settings.TmpDcm = 2;
+ settings.decimation = 0;
+ if (fmt->fmt.pix.height <= fh->jpg_settings.img_height / 2)
+ settings.VerDcm = 2;
+ else
+ settings.VerDcm = 1;
+ if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 4)
+ settings.HorDcm = 4;
+ else if (fmt->fmt.pix.width <= fh->jpg_settings.img_width / 2)
+ settings.HorDcm = 2;
+ else
+ settings.HorDcm = 1;
+ if (settings.TmpDcm == 1)
+ settings.field_per_buff = 2;
+ else
+ settings.field_per_buff = 1;
- return res;
+ if (settings.HorDcm > 1) {
+ settings.img_x = (BUZ_MAX_WIDTH == 720) ? 8 : 0;
+ settings.img_width = (BUZ_MAX_WIDTH == 720) ? 704 : BUZ_MAX_WIDTH;
+ } else {
+ settings.img_x = 0;
+ settings.img_width = BUZ_MAX_WIDTH;
}
- break;
- case VIDIOC_QBUF:
- {
- struct v4l2_buffer *buf = arg;
- int res = 0, codec_mode, buf_type;
+ /* check */
+ res = zoran_check_jpg_settings(zr, &settings, 0);
+ if (res)
+ goto sfmtjpg_unlock_and_return;
- dprintk(3,
- KERN_DEBUG "%s: VIDIOC_QBUF - type=%d, index=%d\n",
- ZR_DEVNAME(zr), buf->type, buf->index);
+ /* it's ok, so set them */
+ fh->jpg_settings = settings;
- mutex_lock(&zr->resource_lock);
+ map_mode_jpg(fh, fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
+ /* tell the user what we actually did */
+ fmt->fmt.pix.width = settings.img_width / settings.HorDcm;
+ fmt->fmt.pix.height = settings.img_height * 2 /
+ (settings.TmpDcm * settings.VerDcm);
+ if (settings.TmpDcm == 1)
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_SEQ_TB : V4L2_FIELD_SEQ_BT);
+ else
+ fmt->fmt.pix.field = (fh->jpg_settings.odd_even ?
+ V4L2_FIELD_TOP : V4L2_FIELD_BOTTOM);
+ fmt->fmt.pix.bytesperline = 0;
+ fmt->fmt.pix.sizeimage = fh->buffers.buffer_size;
+ fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
- res = zoran_v4l_queue_frame(file, buf->index);
- if (res)
- goto qbuf_unlock_and_return;
- if (!zr->v4l_memgrab_active &&
- fh->v4l_buffers.active == ZORAN_LOCKED)
- zr36057_set_memgrab(zr, 1);
- break;
+sfmtjpg_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
- } else {
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- codec_mode = BUZ_MODE_MOTION_COMPRESS;
- }
+static int zoran_s_fmt_vid_cap(struct file *file, void *__fh,
+ struct v4l2_format *fmt)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i;
+ int res = 0;
- if (buf->type != buf_type) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
+ if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG)
+ return zoran_s_fmt_vid_out(file, fh, fmt);
- res =
- zoran_jpg_queue_frame(file, buf->index,
- codec_mode);
- if (res != 0)
- goto qbuf_unlock_and_return;
- if (zr->codec_mode == BUZ_MODE_IDLE &&
- fh->jpg_buffers.active == ZORAN_LOCKED) {
- zr36057_enable_jpg(zr, codec_mode);
- }
+ for (i = 0; i < NUM_FORMATS; i++)
+ if (fmt->fmt.pix.pixelformat == zoran_formats[i].fourcc)
break;
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - unsupported type %d\n",
- ZR_DEVNAME(zr), buf->type);
- res = -EINVAL;
- goto qbuf_unlock_and_return;
- }
- qbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
+ if (i == NUM_FORMATS) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - unknown/unsupported format 0x%x\n",
+ ZR_DEVNAME(zr), fmt->fmt.pix.pixelformat);
+ return -EINVAL;
}
- break;
- case VIDIOC_DQBUF:
- {
- struct v4l2_buffer *buf = arg;
- int res = 0, buf_type, num = -1; /* compiler borks here (?) */
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_DQBUF - type=%d\n",
- ZR_DEVNAME(zr), buf->type);
-
- mutex_lock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW:
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
+ if ((fh->map_mode != ZORAN_MAP_MODE_RAW && fh->buffers.allocated) ||
+ fh->buffers.active != ZORAN_FREE) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FMT - cannot change capture mode\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto sfmtv4l_unlock_and_return;
+ }
+ if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
+ fmt->fmt.pix.height = BUZ_MAX_HEIGHT;
+ if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
+ fmt->fmt.pix.width = BUZ_MAX_WIDTH;
+
+ map_mode_raw(fh);
+
+ res = zoran_v4l_set_format(fh, fmt->fmt.pix.width, fmt->fmt.pix.height,
+ &zoran_formats[i]);
+ if (res)
+ goto sfmtv4l_unlock_and_return;
+
+ /* tell the user the results/missing stuff */
+ fmt->fmt.pix.bytesperline = fh->v4l_settings.bytesperline;
+ fmt->fmt.pix.sizeimage = fh->v4l_settings.height * fh->v4l_settings.bytesperline;
+ fmt->fmt.pix.colorspace = fh->v4l_settings.format->colorspace;
+ if (BUZ_MAX_HEIGHT < (fh->v4l_settings.height * 2))
+ fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
+ else
+ fmt->fmt.pix.field = V4L2_FIELD_TOP;
- num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
- if (file->f_flags & O_NONBLOCK &&
- zr->v4l_buffers.buffer[num].state !=
- BUZ_STATE_DONE) {
- res = -EAGAIN;
- goto dqbuf_unlock_and_return;
- }
- res = v4l_sync(file, num);
- if (res)
- goto dqbuf_unlock_and_return;
- else
- zr->v4l_sync_tail++;
- res = zoran_v4l2_buffer_status(file, buf, num);
- break;
+sfmtv4l_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- {
- struct zoran_sync bs;
+static int zoran_g_fbuf(struct file *file, void *__fh,
+ struct v4l2_framebuffer *fb)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
- buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
- else
- buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ memset(fb, 0, sizeof(*fb));
+ mutex_lock(&zr->resource_lock);
+ fb->base = zr->vbuf_base;
+ fb->fmt.width = zr->vbuf_width;
+ fb->fmt.height = zr->vbuf_height;
+ if (zr->overlay_settings.format)
+ fb->fmt.pixelformat = fh->overlay_settings.format->fourcc;
+ fb->fmt.bytesperline = zr->vbuf_bytesperline;
+ mutex_unlock(&zr->resource_lock);
+ fb->fmt.colorspace = V4L2_COLORSPACE_SRGB;
+ fb->fmt.field = V4L2_FIELD_INTERLACED;
+ fb->flags = V4L2_FBUF_FLAG_OVERLAY;
+ fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
- if (buf->type != buf_type) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
- ZR_DEVNAME(zr), buf->type, fh->map_mode);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
+ return 0;
+}
- num =
- zr->jpg_pend[zr->
- jpg_que_tail & BUZ_MASK_FRAME];
+static int zoran_s_fbuf(struct file *file, void *__fh,
+ struct v4l2_framebuffer *fb)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i, res = 0;
+ __le32 printformat = __cpu_to_le32(fb->fmt.pixelformat);
- if (file->f_flags & O_NONBLOCK &&
- zr->jpg_buffers.buffer[num].state !=
- BUZ_STATE_DONE) {
- res = -EAGAIN;
- goto dqbuf_unlock_and_return;
- }
- res = jpg_sync(file, &bs);
- if (res)
- goto dqbuf_unlock_and_return;
- res =
- zoran_v4l2_buffer_status(file, buf, bs.frame);
+ for (i = 0; i < NUM_FORMATS; i++)
+ if (zoran_formats[i].fourcc == fb->fmt.pixelformat)
break;
- }
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_DQBUF - unsupported type %d\n",
- ZR_DEVNAME(zr), buf->type);
- res = -EINVAL;
- goto dqbuf_unlock_and_return;
- }
- dqbuf_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
+ if (i == NUM_FORMATS) {
+ dprintk(1, KERN_ERR "%s: VIDIOC_S_FBUF - format=0x%x (%4.4s) not allowed\n",
+ ZR_DEVNAME(zr), fb->fmt.pixelformat,
+ (char *)&printformat);
+ return -EINVAL;
}
- break;
- case VIDIOC_STREAMON:
- {
- int res = 0;
+ mutex_lock(&zr->resource_lock);
+ res = setup_fbuffer(fh, fb->base, &zoran_formats[i], fb->fmt.width,
+ fb->fmt.height, fb->fmt.bytesperline);
+ mutex_unlock(&zr->resource_lock);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMON\n", ZR_DEVNAME(zr));
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_overlay(struct file *file, void *__fh, unsigned int on)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW: /* raw capture */
- if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
- fh->v4l_buffers.active != ZORAN_ACTIVE) {
- res = -EBUSY;
- goto strmon_unlock_and_return;
- }
+ mutex_lock(&zr->resource_lock);
+ res = setup_overlay(fh, on);
+ mutex_unlock(&zr->resource_lock);
- zr->v4l_buffers.active = fh->v4l_buffers.active =
- ZORAN_LOCKED;
- zr->v4l_settings = fh->v4l_settings;
+ return res;
+}
- zr->v4l_sync_tail = zr->v4l_pend_tail;
- if (!zr->v4l_memgrab_active &&
- zr->v4l_pend_head != zr->v4l_pend_tail) {
- zr36057_set_memgrab(zr, 1);
- }
- break;
+static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type);
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- /* what is the codec mode right now? */
- if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
- fh->jpg_buffers.active != ZORAN_ACTIVE) {
- res = -EBUSY;
- goto strmon_unlock_and_return;
- }
+static int zoran_reqbufs(struct file *file, void *__fh, struct v4l2_requestbuffers *req)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
- zr->jpg_buffers.active = fh->jpg_buffers.active =
- ZORAN_LOCKED;
+ if (req->memory != V4L2_MEMORY_MMAP) {
+ dprintk(2,
+ KERN_ERR
+ "%s: only MEMORY_MMAP capture is supported, not %d\n",
+ ZR_DEVNAME(zr), req->memory);
+ return -EINVAL;
+ }
- if (zr->jpg_que_head != zr->jpg_que_tail) {
- /* Start the jpeg codec when the first frame is queued */
- jpeg_start(zr);
- }
+ if (req->count == 0)
+ return zoran_streamoff(file, fh, req->type);
- break;
- default:
- dprintk(1,
+ mutex_lock(&zr->resource_lock);
+ if (fh->buffers.allocated) {
+ dprintk(2,
KERN_ERR
- "%s: VIDIOC_STREAMON - invalid map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- res = -EINVAL;
- goto strmon_unlock_and_return;
- }
- strmon_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- return res;
+ "%s: VIDIOC_REQBUFS - buffers already allocated\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto v4l2reqbuf_unlock_and_return;
}
- break;
- case VIDIOC_STREAMOFF:
- {
- int i, res = 0;
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW &&
+ req->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ /* control user input */
+ if (req->count < 2)
+ req->count = 2;
+ if (req->count > v4l_nbufs)
+ req->count = v4l_nbufs;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_STREAMOFF\n", ZR_DEVNAME(zr));
+ /* The next mmap will map the V4L buffers */
+ map_mode_raw(fh);
+ fh->buffers.num_buffers = req->count;
- mutex_lock(&zr->resource_lock);
+ if (v4l_fbuffer_alloc(fh)) {
+ res = -ENOMEM;
+ goto v4l2reqbuf_unlock_and_return;
+ }
+ } else if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC ||
+ fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+ /* we need to calculate size ourselves now */
+ if (req->count < 4)
+ req->count = 4;
+ if (req->count > jpg_nbufs)
+ req->count = jpg_nbufs;
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_RAW: /* raw capture */
- if (fh->v4l_buffers.active == ZORAN_FREE &&
- zr->v4l_buffers.active != ZORAN_FREE) {
- res = -EPERM; /* stay off other's settings! */
- goto strmoff_unlock_and_return;
- }
- if (zr->v4l_buffers.active == ZORAN_FREE)
- goto strmoff_unlock_and_return;
+ /* The next mmap will map the MJPEG buffers */
+ map_mode_jpg(fh, req->type == V4L2_BUF_TYPE_VIDEO_OUTPUT);
+ fh->buffers.num_buffers = req->count;
+ fh->buffers.buffer_size = zoran_v4l2_calc_bufsize(&fh->jpg_settings);
- /* unload capture */
- if (zr->v4l_memgrab_active) {
- unsigned long flags;
+ if (jpg_fbuffer_alloc(fh)) {
+ res = -ENOMEM;
+ goto v4l2reqbuf_unlock_and_return;
+ }
+ } else {
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOC_REQBUFS - unknown type %d\n",
+ ZR_DEVNAME(zr), req->type);
+ res = -EINVAL;
+ goto v4l2reqbuf_unlock_and_return;
+ }
+v4l2reqbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
+ return res;
+}
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
- zr->v4l_buffers.buffer[i].state =
- BUZ_STATE_USER;
- fh->v4l_buffers = zr->v4l_buffers;
+static int zoran_querybuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
- zr->v4l_buffers.active = fh->v4l_buffers.active =
- ZORAN_FREE;
+ mutex_lock(&zr->resource_lock);
+ res = zoran_v4l2_buffer_status(fh, buf, buf->index);
+ mutex_unlock(&zr->resource_lock);
- zr->v4l_grab_seq = 0;
- zr->v4l_pend_head = zr->v4l_pend_tail = 0;
- zr->v4l_sync_tail = 0;
+ return res;
+}
- break;
+static int zoran_qbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0, codec_mode, buf_type;
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
- if (fh->jpg_buffers.active == ZORAN_FREE &&
- zr->jpg_buffers.active != ZORAN_FREE) {
- res = -EPERM; /* stay off other's settings! */
- goto strmoff_unlock_and_return;
- }
- if (zr->jpg_buffers.active == ZORAN_FREE)
- goto strmoff_unlock_and_return;
-
- res =
- jpg_qbuf(file, -1,
- (fh->map_mode ==
- ZORAN_MAP_MODE_JPG_REC) ?
- BUZ_MODE_MOTION_COMPRESS :
- BUZ_MODE_MOTION_DECOMPRESS);
- if (res)
- goto strmoff_unlock_and_return;
- break;
- default:
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
+ mutex_lock(&zr->resource_lock);
+
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW:
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
res = -EINVAL;
- goto strmoff_unlock_and_return;
+ goto qbuf_unlock_and_return;
}
- strmoff_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
+ res = zoran_v4l_queue_frame(fh, buf->index);
+ if (res)
+ goto qbuf_unlock_and_return;
+ if (!zr->v4l_memgrab_active && fh->buffers.active == ZORAN_LOCKED)
+ zr36057_set_memgrab(zr, 1);
break;
- case VIDIOC_QUERYCTRL:
- {
- struct v4l2_queryctrl *ctrl = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_QUERYCTRL - id=%d\n",
- ZR_DEVNAME(zr), ctrl->id);
-
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
- else {
- int id = ctrl->id;
- memset(ctrl, 0, sizeof(*ctrl));
- ctrl->id = id;
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
+ if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY) {
+ buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ codec_mode = BUZ_MODE_MOTION_DECOMPRESS;
+ } else {
+ buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ codec_mode = BUZ_MODE_MOTION_COMPRESS;
}
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- strncpy(ctrl->name, "Brightness", sizeof(ctrl->name)-1);
- break;
- case V4L2_CID_CONTRAST:
- strncpy(ctrl->name, "Contrast", sizeof(ctrl->name)-1);
- break;
- case V4L2_CID_SATURATION:
- strncpy(ctrl->name, "Saturation", sizeof(ctrl->name)-1);
- break;
- case V4L2_CID_HUE:
- strncpy(ctrl->name, "Hue", sizeof(ctrl->name)-1);
- break;
+ if (buf->type != buf_type) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ res = -EINVAL;
+ goto qbuf_unlock_and_return;
}
- ctrl->minimum = 0;
- ctrl->maximum = 65535;
- ctrl->step = 1;
- ctrl->default_value = 32768;
- ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ res = zoran_jpg_queue_frame(fh, buf->index, codec_mode);
+ if (res != 0)
+ goto qbuf_unlock_and_return;
+ if (zr->codec_mode == BUZ_MODE_IDLE &&
+ fh->buffers.active == ZORAN_LOCKED)
+ zr36057_enable_jpg(zr, codec_mode);
- return 0;
- }
break;
- case VIDIOC_G_CTRL:
- {
- struct v4l2_control *ctrl = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_CTRL - id=%d\n",
- ZR_DEVNAME(zr), ctrl->id);
-
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
-
- mutex_lock(&zr->resource_lock);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- ctrl->value = zr->brightness;
- break;
- case V4L2_CID_CONTRAST:
- ctrl->value = zr->contrast;
- break;
- case V4L2_CID_SATURATION:
- ctrl->value = zr->saturation;
- break;
- case V4L2_CID_HUE:
- ctrl->value = zr->hue;
- break;
- }
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
+ default:
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - unsupported type %d\n",
+ ZR_DEVNAME(zr), buf->type);
+ res = -EINVAL;
break;
+ }
+qbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- case VIDIOC_S_CTRL:
- {
- struct v4l2_control *ctrl = arg;
- struct video_picture pict;
+ return res;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_CTRL - id=%d\n",
- ZR_DEVNAME(zr), ctrl->id);
+static int zoran_dqbuf(struct file *file, void *__fh, struct v4l2_buffer *buf)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0, buf_type, num = -1; /* compiler borks here (?) */
- /* we only support hue/saturation/contrast/brightness */
- if (ctrl->id < V4L2_CID_BRIGHTNESS ||
- ctrl->id > V4L2_CID_HUE)
- return -EINVAL;
+ mutex_lock(&zr->resource_lock);
- if (ctrl->value < 0 || ctrl->value > 65535) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_CTRL - invalid value %d for id=%d\n",
- ZR_DEVNAME(zr), ctrl->value, ctrl->id);
- return -EINVAL;
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW:
+ if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ res = -EINVAL;
+ goto dqbuf_unlock_and_return;
}
- mutex_lock(&zr->resource_lock);
- switch (ctrl->id) {
- case V4L2_CID_BRIGHTNESS:
- zr->brightness = ctrl->value;
- break;
- case V4L2_CID_CONTRAST:
- zr->contrast = ctrl->value;
- break;
- case V4L2_CID_SATURATION:
- zr->saturation = ctrl->value;
- break;
- case V4L2_CID_HUE:
- zr->hue = ctrl->value;
- break;
+ num = zr->v4l_pend[zr->v4l_sync_tail & V4L_MASK_FRAME];
+ if (file->f_flags & O_NONBLOCK &&
+ zr->v4l_buffers.buffer[num].state != BUZ_STATE_DONE) {
+ res = -EAGAIN;
+ goto dqbuf_unlock_and_return;
}
- pict.brightness = zr->brightness;
- pict.contrast = zr->contrast;
- pict.colour = zr->saturation;
- pict.hue = zr->hue;
-
- decoder_command(zr, DECODER_SET_PICTURE, &pict);
-
- mutex_unlock(&zr->resource_lock);
-
- return 0;
- }
+ res = v4l_sync(fh, num);
+ if (res)
+ goto dqbuf_unlock_and_return;
+ zr->v4l_sync_tail++;
+ res = zoran_v4l2_buffer_status(fh, buf, num);
break;
- case VIDIOC_ENUMSTD:
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
{
- struct v4l2_standard *std = arg;
+ struct zoran_sync bs;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMSTD - index=%d\n",
- ZR_DEVNAME(zr), std->index);
+ if (fh->map_mode == ZORAN_MAP_MODE_JPG_PLAY)
+ buf_type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
+ else
+ buf_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- if (std->index < 0 || std->index >= (zr->card.norms + 1))
- return -EINVAL;
- else {
- int id = std->index;
- memset(std, 0, sizeof(*std));
- std->index = id;
+ if (buf->type != buf_type) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_QBUF - invalid buf->type=%d for map_mode=%d\n",
+ ZR_DEVNAME(zr), buf->type, fh->map_mode);
+ res = -EINVAL;
+ goto dqbuf_unlock_and_return;
}
- if (std->index == zr->card.norms) {
- /* if we have autodetect, ... */
- struct video_decoder_capability caps;
- decoder_command(zr, DECODER_GET_CAPABILITIES,
- &caps);
- if (caps.flags & VIDEO_DECODER_AUTO) {
- std->id = V4L2_STD_ALL;
- strncpy(std->name, "Autodetect", sizeof(std->name)-1);
- return 0;
- } else
- return -EINVAL;
- }
- switch (std->index) {
- case 0:
- std->id = V4L2_STD_PAL;
- strncpy(std->name, "PAL", sizeof(std->name)-1);
- std->frameperiod.numerator = 1;
- std->frameperiod.denominator = 25;
- std->framelines = zr->card.tvn[0]->Ht;
- break;
- case 1:
- std->id = V4L2_STD_NTSC;
- strncpy(std->name, "NTSC", sizeof(std->name)-1);
- std->frameperiod.numerator = 1001;
- std->frameperiod.denominator = 30000;
- std->framelines = zr->card.tvn[1]->Ht;
- break;
- case 2:
- std->id = V4L2_STD_SECAM;
- strncpy(std->name, "SECAM", sizeof(std->name)-1);
- std->frameperiod.numerator = 1;
- std->frameperiod.denominator = 25;
- std->framelines = zr->card.tvn[2]->Ht;
- break;
- }
+ num = zr->jpg_pend[zr->jpg_que_tail & BUZ_MASK_FRAME];
- return 0;
+ if (file->f_flags & O_NONBLOCK &&
+ zr->jpg_buffers.buffer[num].state != BUZ_STATE_DONE) {
+ res = -EAGAIN;
+ goto dqbuf_unlock_and_return;
+ }
+ res = jpg_sync(fh, &bs);
+ if (res)
+ goto dqbuf_unlock_and_return;
+ res = zoran_v4l2_buffer_status(fh, buf, bs.frame);
+ break;
}
+
+ default:
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_DQBUF - unsupported type %d\n",
+ ZR_DEVNAME(zr), buf->type);
+ res = -EINVAL;
break;
+ }
+dqbuf_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- case VIDIOC_G_STD:
- {
- v4l2_std_id *std = arg;
- int norm;
+ return res;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_STD\n", ZR_DEVNAME(zr));
+static int zoran_streamon(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
- mutex_lock(&zr->resource_lock);
- norm = zr->norm;
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- switch (norm) {
- case VIDEO_MODE_PAL:
- *std = V4L2_STD_PAL;
- break;
- case VIDEO_MODE_NTSC:
- *std = V4L2_STD_NTSC;
- break;
- case VIDEO_MODE_SECAM:
- *std = V4L2_STD_SECAM;
- break;
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW: /* raw capture */
+ if (zr->v4l_buffers.active != ZORAN_ACTIVE ||
+ fh->buffers.active != ZORAN_ACTIVE) {
+ res = -EBUSY;
+ goto strmon_unlock_and_return;
}
- return 0;
- }
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_LOCKED;
+ zr->v4l_settings = fh->v4l_settings;
+
+ zr->v4l_sync_tail = zr->v4l_pend_tail;
+ if (!zr->v4l_memgrab_active &&
+ zr->v4l_pend_head != zr->v4l_pend_tail) {
+ zr36057_set_memgrab(zr, 1);
+ }
break;
- case VIDIOC_S_STD:
- {
- int norm = -1, res = 0;
- v4l2_std_id *std = arg;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_STD - norm=0x%llx\n",
- ZR_DEVNAME(zr), (unsigned long long)*std);
-
- if ((*std & V4L2_STD_PAL) && !(*std & ~V4L2_STD_PAL))
- norm = VIDEO_MODE_PAL;
- else if ((*std & V4L2_STD_NTSC) && !(*std & ~V4L2_STD_NTSC))
- norm = VIDEO_MODE_NTSC;
- else if ((*std & V4L2_STD_SECAM) && !(*std & ~V4L2_STD_SECAM))
- norm = VIDEO_MODE_SECAM;
- else if (*std == V4L2_STD_ALL)
- norm = VIDEO_MODE_AUTO;
- else {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_STD - invalid norm 0x%llx\n",
- ZR_DEVNAME(zr), (unsigned long long)*std);
- return -EINVAL;
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
+ /* what is the codec mode right now? */
+ if (zr->jpg_buffers.active != ZORAN_ACTIVE ||
+ fh->buffers.active != ZORAN_ACTIVE) {
+ res = -EBUSY;
+ goto strmon_unlock_and_return;
}
- mutex_lock(&zr->resource_lock);
- if ((res = zoran_set_norm(zr, norm)))
- goto sstd_unlock_and_return;
+ zr->jpg_buffers.active = fh->buffers.active = ZORAN_LOCKED;
- res = wait_grab_pending(zr);
- sstd_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
+ if (zr->jpg_que_head != zr->jpg_que_tail) {
+ /* Start the jpeg codec when the first frame is queued */
+ jpeg_start(zr);
+ }
break;
- case VIDIOC_ENUMINPUT:
- {
- struct v4l2_input *inp = arg;
- int status;
-
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMINPUT - index=%d\n",
- ZR_DEVNAME(zr), inp->index);
+ default:
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOC_STREAMON - invalid map mode %d\n",
+ ZR_DEVNAME(zr), fh->map_mode);
+ res = -EINVAL;
+ break;
+ }
+strmon_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- if (inp->index < 0 || inp->index >= zr->card.inputs)
- return -EINVAL;
- else {
- int id = inp->index;
- memset(inp, 0, sizeof(*inp));
- inp->index = id;
- }
+ return res;
+}
- strncpy(inp->name, zr->card.input[inp->index].name,
- sizeof(inp->name) - 1);
- inp->type = V4L2_INPUT_TYPE_CAMERA;
- inp->std = V4L2_STD_ALL;
+static int zoran_streamoff(struct file *file, void *__fh, enum v4l2_buf_type type)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int i, res = 0;
+ unsigned long flags;
- /* Get status of video decoder */
- mutex_lock(&zr->resource_lock);
- decoder_command(zr, DECODER_GET_STATUS, &status);
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- if (!(status & DECODER_STATUS_GOOD)) {
- inp->status |= V4L2_IN_ST_NO_POWER;
- inp->status |= V4L2_IN_ST_NO_SIGNAL;
+ switch (fh->map_mode) {
+ case ZORAN_MAP_MODE_RAW: /* raw capture */
+ if (fh->buffers.active == ZORAN_FREE &&
+ zr->v4l_buffers.active != ZORAN_FREE) {
+ res = -EPERM; /* stay off other's settings! */
+ goto strmoff_unlock_and_return;
}
- if (!(status & DECODER_STATUS_COLOR))
- inp->status |= V4L2_IN_ST_NO_COLOR;
+ if (zr->v4l_buffers.active == ZORAN_FREE)
+ goto strmoff_unlock_and_return;
- return 0;
- }
- break;
+ spin_lock_irqsave(&zr->spinlock, flags);
+ /* unload capture */
+ if (zr->v4l_memgrab_active) {
- case VIDIOC_G_INPUT:
- {
- int *input = arg;
+ zr36057_set_memgrab(zr, 0);
+ }
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_INPUT\n", ZR_DEVNAME(zr));
+ for (i = 0; i < fh->buffers.num_buffers; i++)
+ zr->v4l_buffers.buffer[i].state = BUZ_STATE_USER;
+ fh->buffers = zr->v4l_buffers;
- mutex_lock(&zr->resource_lock);
- *input = zr->input;
- mutex_unlock(&zr->resource_lock);
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
- return 0;
- }
- break;
+ zr->v4l_grab_seq = 0;
+ zr->v4l_pend_head = zr->v4l_pend_tail = 0;
+ zr->v4l_sync_tail = 0;
- case VIDIOC_S_INPUT:
- {
- int *input = arg, res = 0;
+ spin_unlock_irqrestore(&zr->spinlock, flags);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_INPUT - input=%d\n",
- ZR_DEVNAME(zr), *input);
+ break;
- mutex_lock(&zr->resource_lock);
- if ((res = zoran_set_input(zr, *input)))
- goto sinput_unlock_and_return;
+ case ZORAN_MAP_MODE_JPG_REC:
+ case ZORAN_MAP_MODE_JPG_PLAY:
+ if (fh->buffers.active == ZORAN_FREE &&
+ zr->jpg_buffers.active != ZORAN_FREE) {
+ res = -EPERM; /* stay off other's settings! */
+ goto strmoff_unlock_and_return;
+ }
+ if (zr->jpg_buffers.active == ZORAN_FREE)
+ goto strmoff_unlock_and_return;
- /* Make sure the changes come into effect */
- res = wait_grab_pending(zr);
- sinput_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
+ res = jpg_qbuf(fh, -1,
+ (fh->map_mode == ZORAN_MAP_MODE_JPG_REC) ?
+ BUZ_MODE_MOTION_COMPRESS :
+ BUZ_MODE_MOTION_DECOMPRESS);
+ if (res)
+ goto strmoff_unlock_and_return;
+ break;
+ default:
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_STREAMOFF - invalid map mode %d\n",
+ ZR_DEVNAME(zr), fh->map_mode);
+ res = -EINVAL;
break;
+ }
+strmoff_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- case VIDIOC_ENUMOUTPUT:
- {
- struct v4l2_output *outp = arg;
+ return res;
+}
- dprintk(3, KERN_DEBUG "%s: VIDIOC_ENUMOUTPUT - index=%d\n",
- ZR_DEVNAME(zr), outp->index);
+static int zoran_queryctrl(struct file *file, void *__fh,
+ struct v4l2_queryctrl *ctrl)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- if (outp->index != 0)
- return -EINVAL;
+ /* we only support hue/saturation/contrast/brightness */
+ if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+ ctrl->id > V4L2_CID_HUE)
+ return -EINVAL;
- memset(outp, 0, sizeof(*outp));
- outp->index = 0;
- outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
- strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
+ decoder_call(zr, core, queryctrl, ctrl);
- return 0;
- }
- break;
+ return 0;
+}
- case VIDIOC_G_OUTPUT:
- {
- int *output = arg;
+static int zoran_g_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_OUTPUT\n", ZR_DEVNAME(zr));
+ /* we only support hue/saturation/contrast/brightness */
+ if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+ ctrl->id > V4L2_CID_HUE)
+ return -EINVAL;
- *output = 0;
+ mutex_lock(&zr->resource_lock);
+ decoder_call(zr, core, g_ctrl, ctrl);
+ mutex_unlock(&zr->resource_lock);
- return 0;
- }
- break;
+ return 0;
+}
- case VIDIOC_S_OUTPUT:
- {
- int *output = arg;
+static int zoran_s_ctrl(struct file *file, void *__fh, struct v4l2_control *ctrl)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_S_OUTPUT - output=%d\n",
- ZR_DEVNAME(zr), *output);
+ /* we only support hue/saturation/contrast/brightness */
+ if (ctrl->id < V4L2_CID_BRIGHTNESS ||
+ ctrl->id > V4L2_CID_HUE)
+ return -EINVAL;
- if (*output != 0)
- return -EINVAL;
+ mutex_lock(&zr->resource_lock);
+ decoder_call(zr, core, s_ctrl, ctrl);
+ mutex_unlock(&zr->resource_lock);
- return 0;
- }
- break;
+ return 0;
+}
- /* cropping (sub-frame capture) */
- case VIDIOC_CROPCAP:
- {
- struct v4l2_cropcap *cropcap = arg;
- int type = cropcap->type, res = 0;
+static int zoran_g_std(struct file *file, void *__fh, v4l2_std_id *std)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- dprintk(3, KERN_ERR "%s: VIDIOC_CROPCAP - type=%d\n",
- ZR_DEVNAME(zr), cropcap->type);
+ mutex_lock(&zr->resource_lock);
+ *std = zr->norm;
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- memset(cropcap, 0, sizeof(*cropcap));
- cropcap->type = type;
+static int zoran_s_std(struct file *file, void *__fh, v4l2_std_id *std)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
- mutex_lock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
+ res = zoran_set_norm(zr, *std);
+ if (res)
+ goto sstd_unlock_and_return;
- if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto cropcap_unlock_and_return;
- }
+ res = wait_grab_pending(zr);
+sstd_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- cropcap->bounds.top = cropcap->bounds.left = 0;
- cropcap->bounds.width = BUZ_MAX_WIDTH;
- cropcap->bounds.height = BUZ_MAX_HEIGHT;
- cropcap->defrect.top = cropcap->defrect.left = 0;
- cropcap->defrect.width = BUZ_MIN_WIDTH;
- cropcap->defrect.height = BUZ_MIN_HEIGHT;
- cropcap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
+static int zoran_enum_input(struct file *file, void *__fh,
+ struct v4l2_input *inp)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- case VIDIOC_G_CROP:
- {
- struct v4l2_crop *crop = arg;
- int type = crop->type, res = 0;
+ if (inp->index < 0 || inp->index >= zr->card.inputs)
+ return -EINVAL;
+ else {
+ int id = inp->index;
+ memset(inp, 0, sizeof(*inp));
+ inp->index = id;
+ }
- dprintk(3, KERN_ERR "%s: VIDIOC_G_CROP - type=%d\n",
- ZR_DEVNAME(zr), crop->type);
+ strncpy(inp->name, zr->card.input[inp->index].name,
+ sizeof(inp->name) - 1);
+ inp->type = V4L2_INPUT_TYPE_CAMERA;
+ inp->std = V4L2_STD_ALL;
- memset(crop, 0, sizeof(*crop));
- crop->type = type;
+ /* Get status of video decoder */
+ mutex_lock(&zr->resource_lock);
+ decoder_call(zr, video, g_input_status, &inp->status);
+ mutex_unlock(&zr->resource_lock);
+ return 0;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_g_input(struct file *file, void *__fh, unsigned int *input)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto gcrop_unlock_and_return;
- }
+ mutex_lock(&zr->resource_lock);
+ *input = zr->input;
+ mutex_unlock(&zr->resource_lock);
- crop->c.top = fh->jpg_settings.img_y;
- crop->c.left = fh->jpg_settings.img_x;
- crop->c.width = fh->jpg_settings.img_width;
- crop->c.height = fh->jpg_settings.img_height;
+ return 0;
+}
- gcrop_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
+static int zoran_s_input(struct file *file, void *__fh, unsigned int input)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res;
- return res;
- }
- break;
+ mutex_lock(&zr->resource_lock);
+ res = zoran_set_input(zr, input);
+ if (res)
+ goto sinput_unlock_and_return;
- case VIDIOC_S_CROP:
- {
- struct v4l2_crop *crop = arg;
- int res = 0;
+ /* Make sure the changes come into effect */
+ res = wait_grab_pending(zr);
+sinput_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- settings = fh->jpg_settings;
+static int zoran_enum_output(struct file *file, void *__fh,
+ struct v4l2_output *outp)
+{
+ if (outp->index != 0)
+ return -EINVAL;
- dprintk(3,
- KERN_ERR
- "%s: VIDIOC_S_CROP - type=%d, x=%d,y=%d,w=%d,h=%d\n",
- ZR_DEVNAME(zr), crop->type, crop->c.left, crop->c.top,
- crop->c.width, crop->c.height);
+ memset(outp, 0, sizeof(*outp));
+ outp->index = 0;
+ outp->type = V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY;
+ strncpy(outp->name, "Autodetect", sizeof(outp->name)-1);
- mutex_lock(&zr->resource_lock);
+ return 0;
+}
- if (fh->jpg_buffers.allocated || fh->v4l_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_S_CROP - cannot change settings while active\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto scrop_unlock_and_return;
- }
+static int zoran_g_output(struct file *file, void *__fh, unsigned int *output)
+{
+ *output = 0;
- if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
- (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
- fh->map_mode == ZORAN_MAP_MODE_RAW)) {
- dprintk(1,
- KERN_ERR
- "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
- ZR_DEVNAME(zr));
- res = -EINVAL;
- goto scrop_unlock_and_return;
- }
+ return 0;
+}
- /* move into a form that we understand */
- settings.img_x = crop->c.left;
- settings.img_y = crop->c.top;
- settings.img_width = crop->c.width;
- settings.img_height = crop->c.height;
+static int zoran_s_output(struct file *file, void *__fh, unsigned int output)
+{
+ if (output != 0)
+ return -EINVAL;
- /* check validity */
- if ((res = zoran_check_jpg_settings(zr, &settings)))
- goto scrop_unlock_and_return;
+ return 0;
+}
- /* accept */
- fh->jpg_settings = settings;
+/* cropping (sub-frame capture) */
+static int zoran_cropcap(struct file *file, void *__fh,
+ struct v4l2_cropcap *cropcap)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int type = cropcap->type, res = 0;
- scrop_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
- return res;
- }
- break;
+ memset(cropcap, 0, sizeof(*cropcap));
+ cropcap->type = type;
- case VIDIOC_G_JPEGCOMP:
- {
- struct v4l2_jpegcompression *params = arg;
+ mutex_lock(&zr->resource_lock);
- dprintk(3, KERN_DEBUG "%s: VIDIOC_G_JPEGCOMP\n",
+ if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_CROPCAP - subcapture only supported for compressed capture\n",
ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto cropcap_unlock_and_return;
+ }
- memset(params, 0, sizeof(*params));
+ cropcap->bounds.top = cropcap->bounds.left = 0;
+ cropcap->bounds.width = BUZ_MAX_WIDTH;
+ cropcap->bounds.height = BUZ_MAX_HEIGHT;
+ cropcap->defrect.top = cropcap->defrect.left = 0;
+ cropcap->defrect.width = BUZ_MIN_WIDTH;
+ cropcap->defrect.height = BUZ_MIN_HEIGHT;
+cropcap_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_g_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int type = crop->type, res = 0;
- params->quality = fh->jpg_settings.jpg_comp.quality;
- params->APPn = fh->jpg_settings.jpg_comp.APPn;
- memcpy(params->APP_data,
- fh->jpg_settings.jpg_comp.APP_data,
- fh->jpg_settings.jpg_comp.APP_len);
- params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
- memcpy(params->COM_data,
- fh->jpg_settings.jpg_comp.COM_data,
- fh->jpg_settings.jpg_comp.COM_len);
- params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
- params->jpeg_markers =
- fh->jpg_settings.jpg_comp.jpeg_markers;
+ memset(crop, 0, sizeof(*crop));
+ crop->type = type;
- mutex_unlock(&zr->resource_lock);
+ mutex_lock(&zr->resource_lock);
- return 0;
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+ dprintk(1,
+ KERN_ERR
+ "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
+ ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto gcrop_unlock_and_return;
}
- break;
-
- case VIDIOC_S_JPEGCOMP:
- {
- struct v4l2_jpegcompression *params = arg;
- int res = 0;
- settings = fh->jpg_settings;
+ crop->c.top = fh->jpg_settings.img_y;
+ crop->c.left = fh->jpg_settings.img_x;
+ crop->c.width = fh->jpg_settings.img_width;
+ crop->c.height = fh->jpg_settings.img_height;
- dprintk(3,
- KERN_DEBUG
- "%s: VIDIOC_S_JPEGCOMP - quality=%d, APPN=%d, APP_len=%d, COM_len=%d\n",
- ZR_DEVNAME(zr), params->quality, params->APPn,
- params->APP_len, params->COM_len);
+gcrop_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
- settings.jpg_comp = *params;
+ return res;
+}
- mutex_lock(&zr->resource_lock);
+static int zoran_s_crop(struct file *file, void *__fh, struct v4l2_crop *crop)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
+ struct zoran_jpg_settings settings;
- if (fh->v4l_buffers.active != ZORAN_FREE ||
- fh->jpg_buffers.active != ZORAN_FREE) {
- dprintk(1,
- KERN_WARNING
- "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
- ZR_DEVNAME(zr));
- res = -EBUSY;
- goto sjpegc_unlock_and_return;
- }
+ settings = fh->jpg_settings;
- if ((res = zoran_check_jpg_settings(zr, &settings)))
- goto sjpegc_unlock_and_return;
- if (!fh->jpg_buffers.allocated)
- fh->jpg_buffers.buffer_size =
- 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);
+ mutex_lock(&zr->resource_lock);
- return 0;
+ if (fh->buffers.allocated) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_S_CROP - cannot change settings while active\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto scrop_unlock_and_return;
}
- break;
- case VIDIOC_QUERYSTD: /* why is this useful? */
- {
- v4l2_std_id *std = arg;
-
- dprintk(3,
- KERN_DEBUG "%s: VIDIOC_QUERY_STD - std=0x%llx\n",
- ZR_DEVNAME(zr), (unsigned long long)*std);
-
- if (*std == V4L2_STD_ALL || *std == V4L2_STD_NTSC ||
- *std == V4L2_STD_PAL || (*std == V4L2_STD_SECAM &&
- zr->card.norms == 3)) {
- return 0;
- }
-
- return -EINVAL;
+ if (crop->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
+ (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
+ fh->map_mode == ZORAN_MAP_MODE_RAW)) {
+ dprintk(1, KERN_ERR
+ "%s: VIDIOC_G_CROP - subcapture only supported for compressed capture\n",
+ ZR_DEVNAME(zr));
+ res = -EINVAL;
+ goto scrop_unlock_and_return;
}
- break;
- case VIDIOC_TRY_FMT:
- {
- struct v4l2_format *fmt = arg;
- int res = 0;
+ /* move into a form that we understand */
+ settings.img_x = crop->c.left;
+ settings.img_y = crop->c.top;
+ settings.img_width = crop->c.width;
+ settings.img_height = crop->c.height;
- dprintk(3, KERN_DEBUG "%s: VIDIOC_TRY_FMT - type=%d\n",
- ZR_DEVNAME(zr), fmt->type);
+ /* check validity */
+ res = zoran_check_jpg_settings(zr, &settings, 0);
+ if (res)
+ goto scrop_unlock_and_return;
- switch (fmt->type) {
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- mutex_lock(&zr->resource_lock);
+ /* accept */
+ fh->jpg_settings = settings;
- if (fmt->fmt.win.w.width > BUZ_MAX_WIDTH)
- fmt->fmt.win.w.width = BUZ_MAX_WIDTH;
- if (fmt->fmt.win.w.width < BUZ_MIN_WIDTH)
- fmt->fmt.win.w.width = BUZ_MIN_WIDTH;
- if (fmt->fmt.win.w.height > BUZ_MAX_HEIGHT)
- fmt->fmt.win.w.height = BUZ_MAX_HEIGHT;
- if (fmt->fmt.win.w.height < BUZ_MIN_HEIGHT)
- fmt->fmt.win.w.height = BUZ_MIN_HEIGHT;
+scrop_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+ return res;
+}
- mutex_unlock(&zr->resource_lock);
- break;
+static int zoran_g_jpegcomp(struct file *file, void *__fh,
+ struct v4l2_jpegcompression *params)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ memset(params, 0, sizeof(*params));
- case V4L2_BUF_TYPE_VIDEO_CAPTURE:
- case V4L2_BUF_TYPE_VIDEO_OUTPUT:
- if (fmt->fmt.pix.bytesperline > 0)
- return -EINVAL;
+ mutex_lock(&zr->resource_lock);
- mutex_lock(&zr->resource_lock);
-
- if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
- settings = fh->jpg_settings;
-
- /* we actually need to set 'real' parameters now */
- if ((fmt->fmt.pix.height * 2) >
- BUZ_MAX_HEIGHT)
- settings.TmpDcm = 1;
- else
- settings.TmpDcm = 2;
- settings.decimation = 0;
- if (fmt->fmt.pix.height <=
- fh->jpg_settings.img_height / 2)
- settings.VerDcm = 2;
- else
- settings.VerDcm = 1;
- if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 4)
- settings.HorDcm = 4;
- else if (fmt->fmt.pix.width <=
- fh->jpg_settings.img_width / 2)
- settings.HorDcm = 2;
- else
- settings.HorDcm = 1;
- if (settings.TmpDcm == 1)
- settings.field_per_buff = 2;
- else
- settings.field_per_buff = 1;
-
- /* check */
- if ((res =
- zoran_check_jpg_settings(zr,
- &settings)))
- goto tryfmt_unlock_and_return;
-
- /* tell the user what we actually did */
- fmt->fmt.pix.width =
- settings.img_width / settings.HorDcm;
- fmt->fmt.pix.height =
- settings.img_height * 2 /
- (settings.TmpDcm * settings.VerDcm);
- if (settings.TmpDcm == 1)
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_SEQ_TB :
- V4L2_FIELD_SEQ_BT);
- else
- fmt->fmt.pix.field =
- (fh->jpg_settings.
- odd_even ? V4L2_FIELD_TOP :
- V4L2_FIELD_BOTTOM);
-
- fmt->fmt.pix.sizeimage =
- zoran_v4l2_calc_bufsize(&settings);
- } else if (fmt->type ==
- V4L2_BUF_TYPE_VIDEO_CAPTURE) {
- int i;
-
- for (i = 0; i < NUM_FORMATS; i++)
- if (zoran_formats[i].fourcc ==
- fmt->fmt.pix.pixelformat)
- break;
- if (i == NUM_FORMATS) {
- res = -EINVAL;
- goto tryfmt_unlock_and_return;
- }
+ params->quality = fh->jpg_settings.jpg_comp.quality;
+ params->APPn = fh->jpg_settings.jpg_comp.APPn;
+ memcpy(params->APP_data,
+ fh->jpg_settings.jpg_comp.APP_data,
+ fh->jpg_settings.jpg_comp.APP_len);
+ params->APP_len = fh->jpg_settings.jpg_comp.APP_len;
+ memcpy(params->COM_data,
+ fh->jpg_settings.jpg_comp.COM_data,
+ fh->jpg_settings.jpg_comp.COM_len);
+ params->COM_len = fh->jpg_settings.jpg_comp.COM_len;
+ params->jpeg_markers =
+ fh->jpg_settings.jpg_comp.jpeg_markers;
- if (fmt->fmt.pix.width > BUZ_MAX_WIDTH)
- fmt->fmt.pix.width = BUZ_MAX_WIDTH;
- if (fmt->fmt.pix.width < BUZ_MIN_WIDTH)
- fmt->fmt.pix.width = BUZ_MIN_WIDTH;
- if (fmt->fmt.pix.height > BUZ_MAX_HEIGHT)
- fmt->fmt.pix.height =
- BUZ_MAX_HEIGHT;
- if (fmt->fmt.pix.height < BUZ_MIN_HEIGHT)
- fmt->fmt.pix.height =
- BUZ_MIN_HEIGHT;
- } else {
- res = -EINVAL;
- goto tryfmt_unlock_and_return;
- }
- tryfmt_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
+ mutex_unlock(&zr->resource_lock);
- return res;
- break;
+ return 0;
+}
- default:
- return -EINVAL;
- }
+static int zoran_s_jpegcomp(struct file *file, void *__fh,
+ struct v4l2_jpegcompression *params)
+{
+ struct zoran_fh *fh = __fh;
+ struct zoran *zr = fh->zr;
+ int res = 0;
+ struct zoran_jpg_settings settings;
- return 0;
- }
- break;
+ settings = fh->jpg_settings;
- default:
- dprintk(1, KERN_DEBUG "%s: UNKNOWN ioctl cmd: 0x%x\n",
- ZR_DEVNAME(zr), cmd);
- return -ENOIOCTLCMD;
- break;
+ settings.jpg_comp = *params;
+
+ mutex_lock(&zr->resource_lock);
+ if (fh->buffers.active != ZORAN_FREE) {
+ dprintk(1, KERN_WARNING
+ "%s: VIDIOC_S_JPEGCOMP called while in playback/capture mode\n",
+ ZR_DEVNAME(zr));
+ res = -EBUSY;
+ goto sjpegc_unlock_and_return;
}
- return 0;
-}
+ res = zoran_check_jpg_settings(zr, &settings, 0);
+ if (res)
+ goto sjpegc_unlock_and_return;
+ if (!fh->buffers.allocated)
+ fh->buffers.buffer_size =
+ 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);
-static long
-zoran_ioctl(struct file *file,
- unsigned int cmd,
- unsigned long arg)
-{
- return video_usercopy(file, cmd, arg, zoran_do_ioctl);
+ return res;
}
static unsigned int
@@ -4191,11 +3062,11 @@ zoran_poll (struct file *file,
KERN_DEBUG
"%s: %s() raw - active=%c, sync_tail=%lu/%c, pend_tail=%lu, pend_head=%lu\n",
ZR_DEVNAME(zr), __func__,
- "FAL"[fh->v4l_buffers.active], zr->v4l_sync_tail,
+ "FAL"[fh->buffers.active], zr->v4l_sync_tail,
"UPMD"[zr->v4l_buffers.buffer[frame].state],
zr->v4l_pend_tail, zr->v4l_pend_head);
/* Process is the one capturing? */
- if (fh->v4l_buffers.active != ZORAN_FREE &&
+ if (fh->buffers.active != ZORAN_FREE &&
/* Buffer ready to DQBUF? */
zr->v4l_buffers.buffer[frame].state == BUZ_STATE_DONE)
res = POLLIN | POLLRDNORM;
@@ -4213,10 +3084,10 @@ zoran_poll (struct file *file,
KERN_DEBUG
"%s: %s() jpg - active=%c, que_tail=%lu/%c, que_head=%lu, dma=%lu/%lu\n",
ZR_DEVNAME(zr), __func__,
- "FAL"[fh->jpg_buffers.active], zr->jpg_que_tail,
+ "FAL"[fh->buffers.active], zr->jpg_que_tail,
"UPMD"[zr->jpg_buffers.buffer[frame].state],
zr->jpg_que_head, zr->jpg_dma_tail, zr->jpg_dma_head);
- if (fh->jpg_buffers.active != ZORAN_FREE &&
+ if (fh->buffers.active != ZORAN_FREE &&
zr->jpg_buffers.buffer[frame].state == BUZ_STATE_DONE) {
if (fh->map_mode == ZORAN_MAP_MODE_JPG_REC)
res = POLLIN | POLLRDNORM;
@@ -4230,8 +3101,8 @@ zoran_poll (struct file *file,
default:
dprintk(1,
KERN_ERR
- "%s: zoran_poll() - internal error, unknown map_mode=%d\n",
- ZR_DEVNAME(zr), fh->map_mode);
+ "%s: %s - internal error, unknown map_mode=%d\n",
+ ZR_DEVNAME(zr), __func__, fh->map_mode);
res = POLLNVAL;
}
@@ -4265,98 +3136,53 @@ static void
zoran_vm_close (struct vm_area_struct *vma)
{
struct zoran_mapping *map = vma->vm_private_data;
- struct file *file = map->file;
- struct zoran_fh *fh = file->private_data;
+ struct zoran_fh *fh = map->file->private_data;
struct zoran *zr = fh->zr;
int i;
- map->count--;
- if (map->count == 0) {
- switch (fh->map_mode) {
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
-
- dprintk(3, KERN_INFO "%s: munmap(MJPEG)\n",
- ZR_DEVNAME(zr));
+ if (--map->count > 0)
+ return;
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++) {
- if (fh->jpg_buffers.buffer[i].map == map) {
- fh->jpg_buffers.buffer[i].map =
- NULL;
- }
- }
- kfree(map);
-
- for (i = 0; i < fh->jpg_buffers.num_buffers; i++)
- if (fh->jpg_buffers.buffer[i].map)
- break;
- if (i == fh->jpg_buffers.num_buffers) {
- mutex_lock(&zr->resource_lock);
-
- if (fh->jpg_buffers.active != ZORAN_FREE) {
- jpg_qbuf(file, -1, zr->codec_mode);
- zr->jpg_buffers.allocated = 0;
- zr->jpg_buffers.active =
- fh->jpg_buffers.active =
- ZORAN_FREE;
- }
- //jpg_fbuffer_free(file);
- fh->jpg_buffers.allocated = 0;
- fh->jpg_buffers.ready_to_be_freed = 1;
-
- mutex_unlock(&zr->resource_lock);
- }
+ dprintk(3, KERN_INFO "%s: %s - munmap(%s)\n", ZR_DEVNAME(zr),
+ __func__, mode_name(fh->map_mode));
- break;
-
- case ZORAN_MAP_MODE_RAW:
-
- dprintk(3, KERN_INFO "%s: munmap(V4L)\n",
- ZR_DEVNAME(zr));
-
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++) {
- if (fh->v4l_buffers.buffer[i].map == map) {
- /* unqueue/unmap */
- fh->v4l_buffers.buffer[i].map =
- NULL;
- }
- }
- kfree(map);
+ for (i = 0; i < fh->buffers.num_buffers; i++) {
+ if (fh->buffers.buffer[i].map == map)
+ fh->buffers.buffer[i].map = NULL;
+ }
+ kfree(map);
- for (i = 0; i < fh->v4l_buffers.num_buffers; i++)
- if (fh->v4l_buffers.buffer[i].map)
- break;
- if (i == fh->v4l_buffers.num_buffers) {
- mutex_lock(&zr->resource_lock);
-
- if (fh->v4l_buffers.active != ZORAN_FREE) {
- unsigned long flags;
-
- spin_lock_irqsave(&zr->spinlock, flags);
- zr36057_set_memgrab(zr, 0);
- zr->v4l_buffers.allocated = 0;
- zr->v4l_buffers.active =
- fh->v4l_buffers.active =
- ZORAN_FREE;
- spin_unlock_irqrestore(&zr->spinlock, flags);
- }
- //v4l_fbuffer_free(file);
- fh->v4l_buffers.allocated = 0;
- fh->v4l_buffers.ready_to_be_freed = 1;
+ /* Any buffers still mapped? */
+ for (i = 0; i < fh->buffers.num_buffers; i++)
+ if (fh->buffers.buffer[i].map)
+ return;
- mutex_unlock(&zr->resource_lock);
- }
+ dprintk(3, KERN_INFO "%s: %s - free %s buffers\n", ZR_DEVNAME(zr),
+ __func__, mode_name(fh->map_mode));
- break;
+ mutex_lock(&zr->resource_lock);
- default:
- printk(KERN_ERR
- "%s: munmap() - internal error - unknown map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- break;
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
+ if (fh->buffers.active != ZORAN_FREE) {
+ unsigned long flags;
+ spin_lock_irqsave(&zr->spinlock, flags);
+ zr36057_set_memgrab(zr, 0);
+ zr->v4l_buffers.allocated = 0;
+ zr->v4l_buffers.active = fh->buffers.active = ZORAN_FREE;
+ spin_unlock_irqrestore(&zr->spinlock, flags);
}
+ v4l_fbuffer_free(fh);
+ } else {
+ if (fh->buffers.active != ZORAN_FREE) {
+ jpg_qbuf(fh, -1, zr->codec_mode);
+ zr->jpg_buffers.allocated = 0;
+ zr->jpg_buffers.active = fh->buffers.active = ZORAN_FREE;
+ }
+ jpg_fbuffer_free(fh);
}
+
+ mutex_unlock(&zr->resource_lock);
}
static struct vm_operations_struct zoran_vm_ops = {
@@ -4379,90 +3205,106 @@ zoran_mmap (struct file *file,
int res = 0;
dprintk(3,
- KERN_INFO "%s: mmap(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
- ZR_DEVNAME(zr),
- fh->map_mode == ZORAN_MAP_MODE_RAW ? "V4L" : "MJPEG",
- vma->vm_start, vma->vm_end, size);
+ KERN_INFO "%s: %s(%s) of 0x%08lx-0x%08lx (size=%lu)\n",
+ ZR_DEVNAME(zr), __func__,
+ mode_name(fh->map_mode), vma->vm_start, vma->vm_end, size);
if (!(vma->vm_flags & VM_SHARED) || !(vma->vm_flags & VM_READ) ||
!(vma->vm_flags & VM_WRITE)) {
dprintk(1,
KERN_ERR
- "%s: mmap() - no MAP_SHARED/PROT_{READ,WRITE} given\n",
- ZR_DEVNAME(zr));
+ "%s: %s - no MAP_SHARED/PROT_{READ,WRITE} given\n",
+ ZR_DEVNAME(zr), __func__);
return -EINVAL;
}
- switch (fh->map_mode) {
+ mutex_lock(&zr->resource_lock);
- case ZORAN_MAP_MODE_JPG_REC:
- case ZORAN_MAP_MODE_JPG_PLAY:
+ if (!fh->buffers.allocated) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s(%s) - buffers not yet allocated\n",
+ ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode));
+ res = -ENOMEM;
+ goto mmap_unlock_and_return;
+ }
- /* lock */
- mutex_lock(&zr->resource_lock);
+ first = offset / fh->buffers.buffer_size;
+ last = first - 1 + size / fh->buffers.buffer_size;
+ if (offset % fh->buffers.buffer_size != 0 ||
+ size % fh->buffers.buffer_size != 0 || first < 0 ||
+ last < 0 || first >= fh->buffers.num_buffers ||
+ last >= fh->buffers.buffer_size) {
+ dprintk(1,
+ KERN_ERR
+ "%s: %s(%s) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
+ ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), offset, size,
+ fh->buffers.buffer_size,
+ fh->buffers.num_buffers);
+ res = -EINVAL;
+ goto mmap_unlock_and_return;
+ }
- /* Map the MJPEG buffers */
- if (!fh->jpg_buffers.allocated) {
+ /* Check if any buffers are already mapped */
+ for (i = first; i <= last; i++) {
+ if (fh->buffers.buffer[i].map) {
dprintk(1,
KERN_ERR
- "%s: zoran_mmap(MJPEG) - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
- res = -ENOMEM;
- goto jpg_mmap_unlock_and_return;
+ "%s: %s(%s) - buffer %d already mapped\n",
+ ZR_DEVNAME(zr), __func__, mode_name(fh->map_mode), i);
+ res = -EBUSY;
+ goto mmap_unlock_and_return;
}
+ }
- first = offset / fh->jpg_buffers.buffer_size;
- last = first - 1 + size / fh->jpg_buffers.buffer_size;
- if (offset % fh->jpg_buffers.buffer_size != 0 ||
- size % fh->jpg_buffers.buffer_size != 0 || first < 0 ||
- last < 0 || first >= fh->jpg_buffers.num_buffers ||
- last >= fh->jpg_buffers.num_buffers) {
- dprintk(1,
- KERN_ERR
- "%s: mmap(MJPEG) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
- ZR_DEVNAME(zr), offset, size,
- fh->jpg_buffers.buffer_size,
- fh->jpg_buffers.num_buffers);
- res = -EINVAL;
- goto jpg_mmap_unlock_and_return;
- }
+ /* map these buffers */
+ map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
+ if (!map) {
+ res = -ENOMEM;
+ goto mmap_unlock_and_return;
+ }
+ map->file = file;
+ map->count = 1;
+
+ vma->vm_ops = &zoran_vm_ops;
+ vma->vm_flags |= VM_DONTEXPAND;
+ vma->vm_private_data = map;
+
+ if (fh->map_mode == ZORAN_MAP_MODE_RAW) {
for (i = first; i <= last; i++) {
- if (fh->jpg_buffers.buffer[i].map) {
+ todo = size;
+ if (todo > fh->buffers.buffer_size)
+ todo = fh->buffers.buffer_size;
+ page = fh->buffers.buffer[i].v4l.fbuffer_phys;
+ if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
+ todo, PAGE_SHARED)) {
dprintk(1,
KERN_ERR
- "%s: mmap(MJPEG) - buffer %d already mapped\n",
- ZR_DEVNAME(zr), i);
- res = -EBUSY;
- goto jpg_mmap_unlock_and_return;
+ "%s: %s(V4L) - remap_pfn_range failed\n",
+ ZR_DEVNAME(zr), __func__);
+ res = -EAGAIN;
+ goto mmap_unlock_and_return;
}
+ size -= todo;
+ start += todo;
+ fh->buffers.buffer[i].map = map;
+ if (size == 0)
+ break;
}
-
- /* map these buffers (v4l_buffers[i]) */
- map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
- if (!map) {
- res = -ENOMEM;
- goto jpg_mmap_unlock_and_return;
- }
- map->file = file;
- map->count = 1;
-
- vma->vm_ops = &zoran_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = map;
-
+ } else {
for (i = first; i <= last; i++) {
for (j = 0;
- j < fh->jpg_buffers.buffer_size / PAGE_SIZE;
+ j < fh->buffers.buffer_size / PAGE_SIZE;
j++) {
fraglen =
- (le32_to_cpu(fh->jpg_buffers.buffer[i].
+ (le32_to_cpu(fh->buffers.buffer[i].jpg.
frag_tab[2 * j + 1]) & ~1) << 1;
todo = size;
if (todo > fraglen)
todo = fraglen;
pos =
- le32_to_cpu(fh->jpg_buffers.
- buffer[i].frag_tab[2 * j]);
+ le32_to_cpu(fh->buffers.
+ buffer[i].jpg.frag_tab[2 * j]);
/* should just be pos on i386 */
page = virt_to_phys(bus_to_virt(pos))
>> PAGE_SHIFT;
@@ -4470,123 +3312,82 @@ zoran_mmap (struct file *file,
todo, PAGE_SHARED)) {
dprintk(1,
KERN_ERR
- "%s: zoran_mmap(V4L) - remap_pfn_range failed\n",
- ZR_DEVNAME(zr));
+ "%s: %s(V4L) - remap_pfn_range failed\n",
+ ZR_DEVNAME(zr), __func__);
res = -EAGAIN;
- goto jpg_mmap_unlock_and_return;
+ goto mmap_unlock_and_return;
}
size -= todo;
start += todo;
if (size == 0)
break;
- if (le32_to_cpu(fh->jpg_buffers.buffer[i].
+ if (le32_to_cpu(fh->buffers.buffer[i].jpg.
frag_tab[2 * j + 1]) & 1)
break; /* was last fragment */
}
- fh->jpg_buffers.buffer[i].map = map;
+ fh->buffers.buffer[i].map = map;
if (size == 0)
break;
}
- jpg_mmap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- break;
-
- case ZORAN_MAP_MODE_RAW:
-
- mutex_lock(&zr->resource_lock);
-
- /* Map the V4L buffers */
- if (!fh->v4l_buffers.allocated) {
- dprintk(1,
- KERN_ERR
- "%s: zoran_mmap(V4L) - buffers not yet allocated\n",
- ZR_DEVNAME(zr));
- res = -ENOMEM;
- goto v4l_mmap_unlock_and_return;
- }
-
- first = offset / fh->v4l_buffers.buffer_size;
- last = first - 1 + size / fh->v4l_buffers.buffer_size;
- if (offset % fh->v4l_buffers.buffer_size != 0 ||
- size % fh->v4l_buffers.buffer_size != 0 || first < 0 ||
- last < 0 || first >= fh->v4l_buffers.num_buffers ||
- last >= fh->v4l_buffers.buffer_size) {
- dprintk(1,
- KERN_ERR
- "%s: mmap(V4L) - offset=%lu or size=%lu invalid for bufsize=%d and numbufs=%d\n",
- ZR_DEVNAME(zr), offset, size,
- fh->v4l_buffers.buffer_size,
- fh->v4l_buffers.num_buffers);
- res = -EINVAL;
- goto v4l_mmap_unlock_and_return;
- }
- for (i = first; i <= last; i++) {
- if (fh->v4l_buffers.buffer[i].map) {
- dprintk(1,
- KERN_ERR
- "%s: mmap(V4L) - buffer %d already mapped\n",
- ZR_DEVNAME(zr), i);
- res = -EBUSY;
- goto v4l_mmap_unlock_and_return;
- }
- }
-
- /* map these buffers (v4l_buffers[i]) */
- map = kmalloc(sizeof(struct zoran_mapping), GFP_KERNEL);
- if (!map) {
- res = -ENOMEM;
- goto v4l_mmap_unlock_and_return;
- }
- map->file = file;
- map->count = 1;
-
- vma->vm_ops = &zoran_vm_ops;
- vma->vm_flags |= VM_DONTEXPAND;
- vma->vm_private_data = map;
-
- for (i = first; i <= last; i++) {
- todo = size;
- if (todo > fh->v4l_buffers.buffer_size)
- todo = fh->v4l_buffers.buffer_size;
- page = fh->v4l_buffers.buffer[i].fbuffer_phys;
- if (remap_pfn_range(vma, start, page >> PAGE_SHIFT,
- todo, PAGE_SHARED)) {
- dprintk(1,
- KERN_ERR
- "%s: zoran_mmap(V4L)i - remap_pfn_range failed\n",
- ZR_DEVNAME(zr));
- res = -EAGAIN;
- goto v4l_mmap_unlock_and_return;
- }
- size -= todo;
- start += todo;
- fh->v4l_buffers.buffer[i].map = map;
- if (size == 0)
- break;
- }
- v4l_mmap_unlock_and_return:
- mutex_unlock(&zr->resource_lock);
-
- break;
-
- default:
- dprintk(1,
- KERN_ERR
- "%s: zoran_mmap() - internal error - unknown map mode %d\n",
- ZR_DEVNAME(zr), fh->map_mode);
- break;
}
+mmap_unlock_and_return:
+ mutex_unlock(&zr->resource_lock);
+
return 0;
}
+static const struct v4l2_ioctl_ops zoran_ioctl_ops = {
+ .vidioc_querycap = zoran_querycap,
+ .vidioc_cropcap = zoran_cropcap,
+ .vidioc_s_crop = zoran_s_crop,
+ .vidioc_g_crop = zoran_g_crop,
+ .vidioc_enum_input = zoran_enum_input,
+ .vidioc_g_input = zoran_g_input,
+ .vidioc_s_input = zoran_s_input,
+ .vidioc_enum_output = zoran_enum_output,
+ .vidioc_g_output = zoran_g_output,
+ .vidioc_s_output = zoran_s_output,
+ .vidioc_g_fbuf = zoran_g_fbuf,
+ .vidioc_s_fbuf = zoran_s_fbuf,
+ .vidioc_g_std = zoran_g_std,
+ .vidioc_s_std = zoran_s_std,
+ .vidioc_g_jpegcomp = zoran_g_jpegcomp,
+ .vidioc_s_jpegcomp = zoran_s_jpegcomp,
+ .vidioc_overlay = zoran_overlay,
+ .vidioc_reqbufs = zoran_reqbufs,
+ .vidioc_querybuf = zoran_querybuf,
+ .vidioc_qbuf = zoran_qbuf,
+ .vidioc_dqbuf = zoran_dqbuf,
+ .vidioc_streamon = zoran_streamon,
+ .vidioc_streamoff = zoran_streamoff,
+ .vidioc_enum_fmt_vid_cap = zoran_enum_fmt_vid_cap,
+ .vidioc_enum_fmt_vid_out = zoran_enum_fmt_vid_out,
+ .vidioc_enum_fmt_vid_overlay = zoran_enum_fmt_vid_overlay,
+ .vidioc_g_fmt_vid_cap = zoran_g_fmt_vid_cap,
+ .vidioc_g_fmt_vid_out = zoran_g_fmt_vid_out,
+ .vidioc_g_fmt_vid_overlay = zoran_g_fmt_vid_overlay,
+ .vidioc_s_fmt_vid_cap = zoran_s_fmt_vid_cap,
+ .vidioc_s_fmt_vid_out = zoran_s_fmt_vid_out,
+ .vidioc_s_fmt_vid_overlay = zoran_s_fmt_vid_overlay,
+ .vidioc_try_fmt_vid_cap = zoran_try_fmt_vid_cap,
+ .vidioc_try_fmt_vid_out = zoran_try_fmt_vid_out,
+ .vidioc_try_fmt_vid_overlay = zoran_try_fmt_vid_overlay,
+ .vidioc_queryctrl = zoran_queryctrl,
+ .vidioc_s_ctrl = zoran_s_ctrl,
+ .vidioc_g_ctrl = zoran_g_ctrl,
+#ifdef CONFIG_VIDEO_V4L1_COMPAT
+ .vidioc_default = zoran_default,
+ .vidiocgmbuf = zoran_vidiocgmbuf,
+#endif
+};
+
static const struct v4l2_file_operations zoran_fops = {
.owner = THIS_MODULE,
.open = zoran_open,
.release = zoran_close,
- .ioctl = zoran_ioctl,
+ .ioctl = video_ioctl2,
.read = zoran_read,
.write = zoran_write,
.mmap = zoran_mmap,
@@ -4596,7 +3397,9 @@ static const struct v4l2_file_operations zoran_fops = {
struct video_device zoran_template __devinitdata = {
.name = ZORAN_NAME,
.fops = &zoran_fops,
+ .ioctl_ops = &zoran_ioctl_ops,
.release = &zoran_vdev_release,
+ .tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM,
.minor = -1
};
diff --git a/drivers/media/video/zoran/zoran_procfs.c b/drivers/media/video/zoran/zoran_procfs.c
index 870bc5a70e3..f1423b777db 100644
--- a/drivers/media/video/zoran/zoran_procfs.c
+++ b/drivers/media/video/zoran/zoran_procfs.c
@@ -36,7 +36,7 @@
#include <linux/pci.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <linux/spinlock.h>
#include <linux/sem.h>
#include <linux/seq_file.h>
diff --git a/drivers/media/video/zoran/zr36016.c b/drivers/media/video/zoran/zr36016.c
index 00d132bcd1e..21c088ea904 100644
--- a/drivers/media/video/zoran/zr36016.c
+++ b/drivers/media/video/zoran/zr36016.c
@@ -34,15 +34,10 @@
#include <linux/types.h>
#include <linux/wait.h>
-/* includes for structures and defines regarding video
- #include<linux/videodev.h> */
-
/* I/O commands, error codes */
#include <asm/io.h>
-//#include<errno.h>
/* v4l API */
-#include <linux/videodev.h>
/* headerfile of this module */
#include"zr36016.h"
diff --git a/drivers/media/video/zoran/zr36050.c b/drivers/media/video/zoran/zr36050.c
index cf8b271a1c8..639dd87c663 100644
--- a/drivers/media/video/zoran/zr36050.c
+++ b/drivers/media/video/zoran/zr36050.c
@@ -34,12 +34,8 @@
#include <linux/types.h>
#include <linux/wait.h>
-/* includes for structures and defines regarding video
- #include<linux/videodev.h> */
-
/* I/O commands, error codes */
#include <asm/io.h>
-//#include<errno.h>
/* headerfile of this module */
#include "zr36050.h"
diff --git a/drivers/media/video/zoran/zr36060.c b/drivers/media/video/zoran/zr36060.c
index 8e74054d5ef..008746ff774 100644
--- a/drivers/media/video/zoran/zr36060.c
+++ b/drivers/media/video/zoran/zr36060.c
@@ -34,12 +34,8 @@
#include <linux/types.h>
#include <linux/wait.h>
-/* includes for structures and defines regarding video
- #include<linux/videodev.h> */
-
/* I/O commands, error codes */
#include <asm/io.h>
-//#include<errno.h>
/* headerfile of this module */
#include "zr36060.h"
diff --git a/drivers/media/video/zr364xx.c b/drivers/media/video/zr364xx.c
index 93023560f32..221409fe168 100644
--- a/drivers/media/video/zr364xx.c
+++ b/drivers/media/video/zr364xx.c
@@ -96,6 +96,7 @@ static struct usb_device_id device_table[] = {
{USB_DEVICE(0x06d6, 0x003b), .driver_info = METHOD0 },
{USB_DEVICE(0x0a17, 0x004e), .driver_info = METHOD2 },
{USB_DEVICE(0x041e, 0x405d), .driver_info = METHOD2 },
+ {USB_DEVICE(0x08ca, 0x2102), .driver_info = METHOD2 },
{} /* Terminating entry */
};
@@ -425,7 +426,6 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
static int zr364xx_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, DRIVER_DESC);
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
return 0;
@@ -436,8 +436,6 @@ static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
{
if (i->index != 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = 0;
strcpy(i->name, DRIVER_DESC " Camera");
i->type = V4L2_INPUT_TYPE_CAMERA;
return 0;
@@ -529,11 +527,6 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
{
if (f->index > 0)
return -EINVAL;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- memset(f, 0, sizeof(*f));
- f->index = 0;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strcpy(f->description, "JPEG");
f->pixelformat = V4L2_PIX_FMT_JPEG;
@@ -550,8 +543,6 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
return -EINVAL;
if (f->fmt.pix.field != V4L2_FIELD_ANY &&
@@ -577,10 +568,6 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
f->fmt.pix.field = V4L2_FIELD_NONE;
f->fmt.pix.width = cam->width;
@@ -602,8 +589,6 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
return -EINVAL;
if (f->fmt.pix.field != V4L2_FIELD_ANY &&
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 12b732512e5..a9019f081b9 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -2279,9 +2279,8 @@ mptsas_delete_expander_phys(MPT_ADAPTER *ioc)
mutex_lock(&ioc->sas_topology_mutex);
list_for_each_entry_safe(port_info, n, &ioc->sas_topology, list) {
- if (port_info->phy_info &&
- (!(port_info->phy_info[0].identify.device_info &
- MPI_SAS_DEVICE_INFO_SMP_TARGET)))
+ if (!(port_info->phy_info[0].identify.device_info &
+ MPI_SAS_DEVICE_INFO_SMP_TARGET))
continue;
if (mptsas_sas_expander_pg0(ioc, &buffer,
diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c
index 9a36b5a7de5..7045c45da9b 100644
--- a/drivers/message/i2o/i2o_proc.c
+++ b/drivers/message/i2o/i2o_proc.c
@@ -2037,8 +2037,6 @@ static int __init i2o_proc_fs_create(void)
if (!i2o_proc_dir_root)
return -1;
- i2o_proc_dir_root->owner = THIS_MODULE;
-
list_for_each_entry(c, &i2o_controllers, list)
i2o_proc_iop_add(i2o_proc_dir_root, c);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 06a2b0f7737..ee3927ab11e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -52,6 +52,7 @@ config HTC_EGPIO
config HTC_PASIC3
tristate "HTC PASIC3 LED/DS1WM chip support"
+ select MFD_CORE
help
This core driver provides register access for the LED/DS1WM
chips labeled "AIC2" and "AIC3", found on HTC Blueangel and
@@ -88,7 +89,7 @@ config MENELAUS
help
If you say yes here you get support for the Texas Instruments
TWL92330/Menelaus Power Management chip. This include voltage
- regulators, Dual slot memory card tranceivers, real-time clock
+ regulators, Dual slot memory card transceivers, real-time clock
and other features that are often used in portable devices like
cell phones and PDAs.
diff --git a/drivers/mfd/da903x.c b/drivers/mfd/da903x.c
index 99f8dcfe3d9..7283d88656a 100644
--- a/drivers/mfd/da903x.c
+++ b/drivers/mfd/da903x.c
@@ -413,7 +413,7 @@ static void da903x_irq_work(struct work_struct *work)
enable_irq(chip->client->irq);
}
-static int da903x_irq_handler(int irq, void *data)
+static irqreturn_t da903x_irq_handler(int irq, void *data)
{
struct da903x_chip *chip = data;
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c
index 91b294dcc13..386da1566fc 100644
--- a/drivers/mfd/htc-pasic3.c
+++ b/drivers/mfd/htc-pasic3.c
@@ -12,18 +12,17 @@
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/ds1wm.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
#include <linux/mfd/htc-pasic3.h>
struct pasic3_data {
void __iomem *mapping;
unsigned int bus_shift;
- struct platform_device *ds1wm_pdev;
- struct platform_device *led_pdev;
};
#define REG_ADDR 5
@@ -65,46 +64,15 @@ EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */
* LEDs
*/
-static int led_device_add(struct device *pasic3_dev,
- const struct pasic3_leds_machinfo *pdata)
-{
- struct pasic3_data *asic = pasic3_dev->driver_data;
- struct platform_device *pdev;
- int ret;
-
- pdev = platform_device_alloc("pasic3-led", -1);
- if (!pdev) {
- dev_dbg(pasic3_dev, "failed to allocate LED platform device\n");
- return -ENOMEM;
- }
-
- ret = platform_device_add_data(pdev, pdata,
- sizeof(struct pasic3_leds_machinfo));
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add LED platform data\n");
- goto exit_pdev_put;
- }
-
- pdev->dev.parent = pasic3_dev;
- ret = platform_device_add(pdev);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add LED platform device\n");
- goto exit_pdev_put;
- }
-
- asic->led_pdev = pdev;
- return 0;
-
-exit_pdev_put:
- platform_device_put(pdev);
- return ret;
-}
+static struct mfd_cell led_cell __initdata = {
+ .name = "leds-pasic3",
+};
/*
* DS1WM
*/
-static void ds1wm_enable(struct platform_device *pdev)
+static int ds1wm_enable(struct platform_device *pdev)
{
struct device *dev = pdev->dev.parent;
int c;
@@ -113,9 +81,10 @@ static void ds1wm_enable(struct platform_device *pdev)
pasic3_write_register(dev, 0x28, c & 0x7f);
dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
+ return 0;
}
-static void ds1wm_disable(struct platform_device *pdev)
+static int ds1wm_disable(struct platform_device *pdev)
{
struct device *dev = pdev->dev.parent;
int c;
@@ -124,56 +93,33 @@ static void ds1wm_disable(struct platform_device *pdev)
pasic3_write_register(dev, 0x28, c | 0x80);
dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
+ return 0;
}
-static struct ds1wm_platform_data ds1wm_pdata = {
- .bus_shift = 2,
- .enable = ds1wm_enable,
- .disable = ds1wm_disable,
+static struct ds1wm_driver_data ds1wm_pdata = {
+ .active_high = 0,
};
-static int ds1wm_device_add(struct platform_device *pasic3_pdev, int bus_shift)
-{
- struct device *pasic3_dev = &pasic3_pdev->dev;
- struct pasic3_data *asic = pasic3_dev->driver_data;
- struct platform_device *pdev;
- int ret;
-
- pdev = platform_device_alloc("ds1wm", -1);
- if (!pdev) {
- dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n");
- return -ENOMEM;
- }
-
- ret = platform_device_add_resources(pdev, pasic3_pdev->resource,
- pasic3_pdev->num_resources);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
- goto exit_pdev_put;
- }
-
- ds1wm_pdata.bus_shift = asic->bus_shift;
- ret = platform_device_add_data(pdev, &ds1wm_pdata,
- sizeof(struct ds1wm_platform_data));
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n");
- goto exit_pdev_put;
- }
-
- pdev->dev.parent = pasic3_dev;
- ret = platform_device_add(pdev);
- if (ret < 0) {
- dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n");
- goto exit_pdev_put;
- }
-
- asic->ds1wm_pdev = pdev;
- return 0;
+static struct resource ds1wm_resources[] __initdata = {
+ [0] = {
+ .start = 0,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
-exit_pdev_put:
- platform_device_put(pdev);
- return ret;
-}
+static struct mfd_cell ds1wm_cell __initdata = {
+ .name = "ds1wm",
+ .enable = ds1wm_enable,
+ .disable = ds1wm_disable,
+ .driver_data = &ds1wm_pdata,
+ .num_resources = 2,
+ .resources = ds1wm_resources,
+};
static int __init pasic3_probe(struct platform_device *pdev)
{
@@ -182,12 +128,27 @@ static int __init pasic3_probe(struct platform_device *pdev)
struct pasic3_data *asic;
struct resource *r;
int ret;
+ int irq = 0;
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (r) {
+ ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+ (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+ irq = r->start;
+ }
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (r) {
+ ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags &
+ (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE));
+ irq = r->start;
+ }
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!r)
return -ENXIO;
- if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3"))
+ if (!request_mem_region(r->start, resource_size(r), "pasic3"))
return -EBUSY;
asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
@@ -196,24 +157,33 @@ static int __init pasic3_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, asic);
- if (pdata && pdata->bus_shift)
- asic->bus_shift = pdata->bus_shift;
- else
- asic->bus_shift = 2;
-
- asic->mapping = ioremap(r->start, r->end - r->start + 1);
+ asic->mapping = ioremap(r->start, resource_size(r));
if (!asic->mapping) {
dev_err(dev, "couldn't ioremap PASIC3\n");
kfree(asic);
return -ENOMEM;
}
- ret = ds1wm_device_add(pdev, asic->bus_shift);
- if (ret < 0)
- dev_warn(dev, "failed to register DS1WM\n");
+ /* calculate bus shift from mem resource */
+ asic->bus_shift = (resource_size(r) - 5) >> 3;
+
+ if (pdata && pdata->clock_rate) {
+ ds1wm_pdata.clock_rate = pdata->clock_rate;
+ /* the first 5 PASIC3 registers control the DS1WM */
+ ds1wm_resources[0].end = (5 << asic->bus_shift) - 1;
+ ds1wm_cell.platform_data = &ds1wm_cell;
+ ds1wm_cell.data_size = sizeof(ds1wm_cell);
+ ret = mfd_add_devices(&pdev->dev, pdev->id,
+ &ds1wm_cell, 1, r, irq);
+ if (ret < 0)
+ dev_warn(dev, "failed to register DS1WM\n");
+ }
- if (pdata->led_pdata) {
- ret = led_device_add(dev, pdata->led_pdata);
+ if (pdata && pdata->led_pdata) {
+ led_cell.driver_data = pdata->led_pdata;
+ led_cell.platform_data = &led_cell;
+ led_cell.data_size = sizeof(ds1wm_cell);
+ ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0);
if (ret < 0)
dev_warn(dev, "failed to register LED device\n");
}
@@ -226,14 +196,11 @@ static int pasic3_remove(struct platform_device *pdev)
struct pasic3_data *asic = platform_get_drvdata(pdev);
struct resource *r;
- if (asic->led_pdev)
- platform_device_unregister(asic->led_pdev);
- if (asic->ds1wm_pdev)
- platform_device_unregister(asic->ds1wm_pdev);
+ mfd_remove_devices(&pdev->dev);
iounmap(asic->mapping);
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
kfree(asic);
return 0;
}
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 2e36057659e..7793932a513 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -15,7 +15,6 @@
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/sysfs.h>
-#include <linux/device.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/interrupt.h>
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 9f7024c0f8e..e9f4323dd2c 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -108,7 +108,7 @@ static int t7l66xb_mmc_disable(struct platform_device *mmc)
/*--------------------------------------------------------------------------*/
-const static struct resource t7l66xb_mmc_resources[] = {
+static const struct resource t7l66xb_mmc_resources[] = {
{
.start = 0x800,
.end = 0x9ff,
@@ -126,7 +126,7 @@ const static struct resource t7l66xb_mmc_resources[] = {
},
};
-const static struct resource t7l66xb_nand_resources[] = {
+static const struct resource t7l66xb_nand_resources[] = {
{
.start = 0xc00,
.end = 0xc07,
diff --git a/drivers/mfd/tc6393xb.c b/drivers/mfd/tc6393xb.c
index f856e9463a9..77a12fc8045 100644
--- a/drivers/mfd/tc6393xb.c
+++ b/drivers/mfd/tc6393xb.c
@@ -172,7 +172,7 @@ static struct resource __devinitdata tc6393xb_mmc_resources[] = {
},
};
-const static struct resource tc6393xb_ohci_resources[] = {
+static const struct resource tc6393xb_ohci_resources[] = {
{
.start = 0x3000,
.end = 0x31ff,
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index 68826f1e36b..ec90e953adc 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -592,11 +592,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features)
/* maybe add LDOs that are omitted on cost-reduced parts */
if (twl_has_regulator() && !(features & TPS_SUBSET)) {
- /*
child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2);
if (IS_ERR(child))
return PTR_ERR(child);
- */
child = add_regulator(TWL4030_REG_VMMC2, pdata->vmmc2);
if (IS_ERR(child))
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index b1087603698..aca2670afd7 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -182,7 +182,7 @@ static int twl4030_irq_thread(void *data)
long irq = (long)data;
struct irq_desc *desc = irq_to_desc(irq);
static unsigned i2c_errors;
- const static unsigned max_i2c_errors = 100;
+ static const unsigned max_i2c_errors = 100;
if (!desc) {
pr_err("twl4030: Invalid IRQ: %ld\n", irq);
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index b457a05b28d..c2be3088e2e 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -1111,7 +1111,7 @@ int wm8350_read_auxadc(struct wm8350 *wm8350, int channel, int scale, int vref)
do {
schedule_timeout_interruptible(1);
reg = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_1);
- } while (--tries && (reg & WM8350_AUXADC_POLL));
+ } while ((reg & WM8350_AUXADC_POLL) && --tries);
if (!tries)
dev_err(wm8350->dev, "adc chn %d read timeout\n", channel);
@@ -1238,7 +1238,7 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
}
wm8350->reg_cache =
- kzalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
+ kmalloc(sizeof(u16) * (WM8350_MAX_REGISTER + 1), GFP_KERNEL);
if (wm8350->reg_cache == NULL)
return -ENOMEM;
@@ -1246,17 +1246,20 @@ static int wm8350_create_cache(struct wm8350 *wm8350, int type, int mode)
* a PMIC so the device many not be in a virgin state and we
* can't rely on the silicon values.
*/
+ ret = wm8350->read_dev(wm8350, 0,
+ sizeof(u16) * (WM8350_MAX_REGISTER + 1),
+ wm8350->reg_cache);
+ if (ret < 0) {
+ dev_err(wm8350->dev,
+ "failed to read initial cache values\n");
+ goto out;
+ }
+
+ /* Mask out uncacheable/unreadable bits and the audio. */
for (i = 0; i < WM8350_MAX_REGISTER; i++) {
- /* audio register range */
if (wm8350_reg_io_map[i].readable &&
(i < WM8350_CLOCK_CONTROL_1 || i > WM8350_AIF_TEST)) {
- ret = wm8350->read_dev(wm8350, i, 2, (char *)&value);
- if (ret < 0) {
- dev_err(wm8350->dev,
- "failed to read initial cache value\n");
- goto out;
- }
- value = be16_to_cpu(value);
+ value = be16_to_cpu(wm8350->reg_cache[i]);
value &= wm8350_reg_io_map[i].readable;
value &= ~wm8350_reg_io_map[i].vol;
wm8350->reg_cache[i] = value;
@@ -1435,7 +1438,21 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
mutex_init(&wm8350->irq_mutex);
INIT_WORK(&wm8350->irq_work, wm8350_irq_worker);
if (irq) {
- ret = request_irq(irq, wm8350_irq, 0,
+ int flags = 0;
+
+ if (pdata && pdata->irq_high) {
+ flags |= IRQF_TRIGGER_HIGH;
+
+ wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+ WM8350_IRQ_POL);
+ } else {
+ flags |= IRQF_TRIGGER_LOW;
+
+ wm8350_clear_bits(wm8350, WM8350_SYSTEM_CONTROL_1,
+ WM8350_IRQ_POL);
+ }
+
+ ret = request_irq(irq, wm8350_irq, flags,
"wm8350", wm8350);
if (ret != 0) {
dev_err(wm8350->dev, "Failed to request IRQ: %d\n",
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1c484084ed4..6d1ac180f6e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -18,8 +18,8 @@ config ATMEL_PWM
depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
help
This option enables device driver support for the PWM channels
- on certain Atmel prcoessors. Pulse Width Modulation is used for
- purposes including software controlled power-efficent backlights
+ on certain Atmel processors. Pulse Width Modulation is used for
+ purposes including software controlled power-efficient backlights
on LCD displays, motor control, and waveform generation.
config ATMEL_TCLIB
@@ -142,7 +142,7 @@ config ATMEL_SSC
tristate "Device driver for Atmel SSC peripheral"
depends on AVR32 || ARCH_AT91
---help---
- This option enables device driver support for Atmel Syncronized
+ This option enables device driver support for Atmel Synchronized
Serial Communication peripheral (SSC).
The SSC peripheral supports a wide variety of serial frame based
@@ -165,7 +165,7 @@ config SGI_XP
depends on (IA64_GENERIC || IA64_SGI_SN2 || IA64_SGI_UV || X86_UV) && SMP
select IA64_UNCACHED_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
select GENERIC_ALLOCATOR if IA64_GENERIC || IA64_SGI_SN2
- select SGI_GRU if (IA64_GENERIC || IA64_SGI_UV || X86_64) && SMP
+ select SGI_GRU if X86_64 && SMP
---help---
An SGI machine can be divided into multiple Single System
Images which act independently of each other and have
@@ -189,7 +189,7 @@ config HP_ILO
config SGI_GRU
tristate "SGI GRU driver"
- depends on (X86_UV || IA64_SGI_UV || IA64_GENERIC) && SMP
+ depends on X86_UV && SMP
default n
select MMU_NOTIFIER
---help---
@@ -223,6 +223,16 @@ config DELL_LAPTOP
This driver adds support for rfkill and backlight control to Dell
laptops.
+config ISL29003
+ tristate "Intersil ISL29003 ambient light sensor"
+ depends on I2C && SYSFS
+ help
+ If you say yes here you get support for the Intersil ISL29003
+ ambient light sensor.
+
+ This driver can also be built as a module. If so, the module
+ will be called isl29003.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index bc119983055..7871f05dcb9 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -18,5 +18,6 @@ obj-$(CONFIG_KGDB_TESTS) += kgdbts.o
obj-$(CONFIG_SGI_XP) += sgi-xp/
obj-$(CONFIG_SGI_GRU) += sgi-gru/
obj-$(CONFIG_HP_ILO) += hpilo.o
+obj-$(CONFIG_ISL29003) += isl29003.o
obj-$(CONFIG_C2PORT) += c2port/
obj-y += eeprom/
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c
index d4775528abc..d184dfab963 100644
--- a/drivers/misc/eeprom/at24.c
+++ b/drivers/misc/eeprom/at24.c
@@ -53,6 +53,7 @@
struct at24_data {
struct at24_platform_data chip;
+ struct memory_accessor macc;
bool use_smbus;
/*
@@ -225,14 +226,11 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf,
return status;
}
-static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
+static ssize_t at24_read(struct at24_data *at24,
char *buf, loff_t off, size_t count)
{
- struct at24_data *at24;
ssize_t retval = 0;
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
if (unlikely(!count))
return count;
@@ -262,12 +260,14 @@ static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
return retval;
}
+static ssize_t at24_bin_read(struct kobject *kobj, struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct at24_data *at24;
-/*
- * REVISIT: export at24_bin{read,write}() to let other kernel code use
- * eeprom data. For example, it might hold a board's Ethernet address, or
- * board-specific calibration data generated on the manufacturing floor.
- */
+ at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
+ return at24_read(at24, buf, off, count);
+}
/*
@@ -347,14 +347,11 @@ static ssize_t at24_eeprom_write(struct at24_data *at24, char *buf,
return -ETIMEDOUT;
}
-static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
+static ssize_t at24_write(struct at24_data *at24,
char *buf, loff_t off, size_t count)
{
- struct at24_data *at24;
ssize_t retval = 0;
- at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
-
if (unlikely(!count))
return count;
@@ -384,6 +381,39 @@ static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
return retval;
}
+static ssize_t at24_bin_write(struct kobject *kobj, struct bin_attribute *attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct at24_data *at24;
+
+ at24 = dev_get_drvdata(container_of(kobj, struct device, kobj));
+ return at24_write(at24, buf, off, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * This lets other kernel code access the eeprom data. For example, it
+ * might hold a board's Ethernet address, or board-specific calibration
+ * data generated on the manufacturing floor.
+ */
+
+static ssize_t at24_macc_read(struct memory_accessor *macc, char *buf,
+ off_t offset, size_t count)
+{
+ struct at24_data *at24 = container_of(macc, struct at24_data, macc);
+
+ return at24_read(at24, buf, offset, count);
+}
+
+static ssize_t at24_macc_write(struct memory_accessor *macc, char *buf,
+ off_t offset, size_t count)
+{
+ struct at24_data *at24 = container_of(macc, struct at24_data, macc);
+
+ return at24_write(at24, buf, offset, count);
+}
+
/*-------------------------------------------------------------------------*/
static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
@@ -413,6 +443,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
* is recommended anyhow.
*/
chip.page_size = 1;
+
+ chip.setup = NULL;
+ chip.context = NULL;
}
if (!is_power_of_2(chip.byte_len))
@@ -463,6 +496,8 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
at24->bin.read = at24_bin_read;
at24->bin.size = chip.byte_len;
+ at24->macc.read = at24_macc_read;
+
writable = !(chip.flags & AT24_FLAG_READONLY);
if (writable) {
if (!use_smbus || i2c_check_functionality(client->adapter,
@@ -470,6 +505,8 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
unsigned write_max = chip.page_size;
+ at24->macc.write = at24_macc_write;
+
at24->bin.write = at24_bin_write;
at24->bin.attr.mode |= S_IWUSR;
@@ -520,6 +557,10 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id)
at24->write_max,
use_smbus ? ", use_smbus" : "");
+ /* export data to kernel code */
+ if (chip.setup)
+ chip.setup(&at24->macc, chip.context);
+
return 0;
err_clients:
diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c
index 290dbe99647..6bc0dac5c1e 100644
--- a/drivers/misc/eeprom/at25.c
+++ b/drivers/misc/eeprom/at25.c
@@ -30,6 +30,7 @@
struct at25_data {
struct spi_device *spi;
+ struct memory_accessor mem;
struct mutex lock;
struct spi_eeprom chip;
struct bin_attribute bin;
@@ -75,6 +76,13 @@ at25_ee_read(
struct spi_transfer t[2];
struct spi_message m;
+ if (unlikely(offset >= at25->bin.size))
+ return 0;
+ if ((offset + count) > at25->bin.size)
+ count = at25->bin.size - offset;
+ if (unlikely(!count))
+ return count;
+
cp = command;
*cp++ = AT25_READ;
@@ -127,13 +135,6 @@ at25_bin_read(struct kobject *kobj, struct bin_attribute *bin_attr,
dev = container_of(kobj, struct device, kobj);
at25 = dev_get_drvdata(dev);
- if (unlikely(off >= at25->bin.size))
- return 0;
- if ((off + count) > at25->bin.size)
- count = at25->bin.size - off;
- if (unlikely(!count))
- return count;
-
return at25_ee_read(at25, buf, off, count);
}
@@ -146,6 +147,13 @@ at25_ee_write(struct at25_data *at25, char *buf, loff_t off, size_t count)
unsigned buf_size;
u8 *bounce;
+ if (unlikely(off >= at25->bin.size))
+ return -EFBIG;
+ if ((off + count) > at25->bin.size)
+ count = at25->bin.size - off;
+ if (unlikely(!count))
+ return count;
+
/* Temp buffer starts with command and address */
buf_size = at25->chip.page_size;
if (buf_size > io_limit)
@@ -253,18 +261,31 @@ at25_bin_write(struct kobject *kobj, struct bin_attribute *bin_attr,
dev = container_of(kobj, struct device, kobj);
at25 = dev_get_drvdata(dev);
- if (unlikely(off >= at25->bin.size))
- return -EFBIG;
- if ((off + count) > at25->bin.size)
- count = at25->bin.size - off;
- if (unlikely(!count))
- return count;
-
return at25_ee_write(at25, buf, off, count);
}
/*-------------------------------------------------------------------------*/
+/* Let in-kernel code access the eeprom data. */
+
+static ssize_t at25_mem_read(struct memory_accessor *mem, char *buf,
+ off_t offset, size_t count)
+{
+ struct at25_data *at25 = container_of(mem, struct at25_data, mem);
+
+ return at25_ee_read(at25, buf, offset, count);
+}
+
+static ssize_t at25_mem_write(struct memory_accessor *mem, char *buf,
+ off_t offset, size_t count)
+{
+ struct at25_data *at25 = container_of(mem, struct at25_data, mem);
+
+ return at25_ee_write(at25, buf, offset, count);
+}
+
+/*-------------------------------------------------------------------------*/
+
static int at25_probe(struct spi_device *spi)
{
struct at25_data *at25 = NULL;
@@ -317,6 +338,10 @@ static int at25_probe(struct spi_device *spi)
at25->addrlen = addrlen;
/* Export the EEPROM bytes through sysfs, since that's convenient.
+ * And maybe to other kernel code; it might hold a board's Ethernet
+ * address, or board-specific calibration data generated on the
+ * manufacturing floor.
+ *
* Default to root-only access to the data; EEPROMs often hold data
* that's sensitive for read and/or write, like ethernet addresses,
* security codes, board-specific manufacturing calibrations, etc.
@@ -324,17 +349,22 @@ static int at25_probe(struct spi_device *spi)
at25->bin.attr.name = "eeprom";
at25->bin.attr.mode = S_IRUSR;
at25->bin.read = at25_bin_read;
+ at25->mem.read = at25_mem_read;
at25->bin.size = at25->chip.byte_len;
if (!(chip->flags & EE_READONLY)) {
at25->bin.write = at25_bin_write;
at25->bin.attr.mode |= S_IWUSR;
+ at25->mem.write = at25_mem_write;
}
err = sysfs_create_bin_file(&spi->dev.kobj, &at25->bin);
if (err)
goto fail;
+ if (chip->setup)
+ chip->setup(&at25->mem, chip->context);
+
dev_info(&spi->dev, "%Zd %s %s eeprom%s, pagesize %u\n",
(at25->bin.size < 1024)
? at25->bin.size
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
index cf991850f01..880ccf39e23 100644
--- a/drivers/misc/hpilo.c
+++ b/drivers/misc/hpilo.c
@@ -209,7 +209,7 @@ static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
/* give iLO some time to process stop request */
for (retries = MAX_WAIT; retries > 0; retries--) {
doorbell_set(driver_ccb);
- udelay(1);
+ udelay(WAIT_TIME);
if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
&&
!(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A)))
@@ -312,7 +312,7 @@ static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
for (i = MAX_WAIT; i > 0; i--) {
if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
break;
- udelay(1);
+ udelay(WAIT_TIME);
}
if (i) {
@@ -759,7 +759,7 @@ static void __exit ilo_exit(void)
class_destroy(ilo_class);
}
-MODULE_VERSION("1.0");
+MODULE_VERSION("1.1");
MODULE_ALIAS(ILO_NAME);
MODULE_DESCRIPTION(ILO_NAME);
MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
index b64a20ef07e..03a14c82aad 100644
--- a/drivers/misc/hpilo.h
+++ b/drivers/misc/hpilo.h
@@ -19,8 +19,12 @@
#define MAX_ILO_DEV 1
/* max number of files */
#define MAX_OPEN (MAX_CCB * MAX_ILO_DEV)
+/* total wait time in usec */
+#define MAX_WAIT_TIME 10000
+/* per spin wait time in usec */
+#define WAIT_TIME 10
/* spin counter for open/close delay */
-#define MAX_WAIT 10000
+#define MAX_WAIT (MAX_WAIT_TIME / WAIT_TIME)
/*
* Per device, used to track global memory allocations.
diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c
new file mode 100644
index 00000000000..2e2a5923d4c
--- /dev/null
+++ b/drivers/misc/isl29003.c
@@ -0,0 +1,470 @@
+/*
+ * isl29003.c - Linux kernel module for
+ * Intersil ISL29003 ambient light sensor
+ *
+ * See file:Documentation/misc-devices/isl29003
+ *
+ * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ *
+ * Based on code written by
+ * Rodolfo Giometti <giometti@linux.it>
+ * Eurotech S.p.A. <info@eurotech.it>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define ISL29003_DRV_NAME "isl29003"
+#define DRIVER_VERSION "1.0"
+
+#define ISL29003_REG_COMMAND 0x00
+#define ISL29003_ADC_ENABLED (1 << 7)
+#define ISL29003_ADC_PD (1 << 6)
+#define ISL29003_TIMING_INT (1 << 5)
+#define ISL29003_MODE_SHIFT (2)
+#define ISL29003_MODE_MASK (0x3 << ISL29003_MODE_SHIFT)
+#define ISL29003_RES_SHIFT (0)
+#define ISL29003_RES_MASK (0x3 << ISL29003_RES_SHIFT)
+
+#define ISL29003_REG_CONTROL 0x01
+#define ISL29003_INT_FLG (1 << 5)
+#define ISL29003_RANGE_SHIFT (2)
+#define ISL29003_RANGE_MASK (0x3 << ISL29003_RANGE_SHIFT)
+#define ISL29003_INT_PERSISTS_SHIFT (0)
+#define ISL29003_INT_PERSISTS_MASK (0xf << ISL29003_INT_PERSISTS_SHIFT)
+
+#define ISL29003_REG_IRQ_THRESH_HI 0x02
+#define ISL29003_REG_IRQ_THRESH_LO 0x03
+#define ISL29003_REG_LSB_SENSOR 0x04
+#define ISL29003_REG_MSB_SENSOR 0x05
+#define ISL29003_REG_LSB_TIMER 0x06
+#define ISL29003_REG_MSB_TIMER 0x07
+
+#define ISL29003_NUM_CACHABLE_REGS 4
+
+struct isl29003_data {
+ struct i2c_client *client;
+ struct mutex lock;
+ u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
+};
+
+static int gain_range[] = {
+ 1000, 4000, 16000, 64000
+};
+
+/*
+ * register access helpers
+ */
+
+static int __isl29003_read_reg(struct i2c_client *client,
+ u32 reg, u8 mask, u8 shift)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ return (data->reg_cache[reg] & mask) >> shift;
+}
+
+static int __isl29003_write_reg(struct i2c_client *client,
+ u32 reg, u8 mask, u8 shift, u8 val)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ int ret = 0;
+ u8 tmp;
+
+ if (reg >= ISL29003_NUM_CACHABLE_REGS)
+ return -EINVAL;
+
+ mutex_lock(&data->lock);
+
+ tmp = data->reg_cache[reg];
+ tmp &= ~mask;
+ tmp |= val << shift;
+
+ ret = i2c_smbus_write_byte_data(client, reg, tmp);
+ if (!ret)
+ data->reg_cache[reg] = tmp;
+
+ mutex_unlock(&data->lock);
+ return ret;
+}
+
+/*
+ * internally used functions
+ */
+
+/* range */
+static int isl29003_get_range(struct i2c_client *client)
+{
+ return __isl29003_read_reg(client, ISL29003_REG_CONTROL,
+ ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT);
+}
+
+static int isl29003_set_range(struct i2c_client *client, int range)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_CONTROL,
+ ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range);
+}
+
+/* resolution */
+static int isl29003_get_resolution(struct i2c_client *client)
+{
+ return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_resolution(struct i2c_client *client, int res)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT, res);
+}
+
+/* mode */
+static int isl29003_get_mode(struct i2c_client *client)
+{
+ return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT);
+}
+
+static int isl29003_set_mode(struct i2c_client *client, int mode)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode);
+}
+
+/* power_state */
+static int isl29003_set_power_state(struct i2c_client *client, int state)
+{
+ return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
+ ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0,
+ state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD);
+}
+
+static int isl29003_get_power_state(struct i2c_client *client)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND];
+ return ~cmdreg & ISL29003_ADC_PD;
+}
+
+static int isl29003_get_adc_value(struct i2c_client *client)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ int lsb, msb, range, bitdepth;
+
+ mutex_lock(&data->lock);
+ lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR);
+
+ if (lsb < 0) {
+ mutex_unlock(&data->lock);
+ return lsb;
+ }
+
+ msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR);
+ mutex_unlock(&data->lock);
+
+ if (msb < 0)
+ return msb;
+
+ range = isl29003_get_range(client);
+ bitdepth = (4 - isl29003_get_resolution(client)) * 4;
+ return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth;
+}
+
+/*
+ * sysfs layer
+ */
+
+/* range */
+static ssize_t isl29003_show_range(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%i\n", isl29003_get_range(client));
+}
+
+static ssize_t isl29003_store_range(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+ return -EINVAL;
+
+ ret = isl29003_set_range(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
+ isl29003_show_range, isl29003_store_range);
+
+
+/* resolution */
+static ssize_t isl29003_show_resolution(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29003_get_resolution(client));
+}
+
+static ssize_t isl29003_store_resolution(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 3))
+ return -EINVAL;
+
+ ret = isl29003_set_resolution(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
+ isl29003_show_resolution, isl29003_store_resolution);
+
+/* mode */
+static ssize_t isl29003_show_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29003_get_mode(client));
+}
+
+static ssize_t isl29003_store_mode(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 2))
+ return -EINVAL;
+
+ ret = isl29003_set_mode(client, val);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
+ isl29003_show_mode, isl29003_store_mode);
+
+
+/* power state */
+static ssize_t isl29003_show_power_state(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ return sprintf(buf, "%d\n", isl29003_get_power_state(client));
+}
+
+static ssize_t isl29003_store_power_state(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ unsigned long val;
+ int ret;
+
+ if ((strict_strtoul(buf, 10, &val) < 0) || (val > 1))
+ return -EINVAL;
+
+ ret = isl29003_set_power_state(client, val);
+ return ret ? ret : count;
+}
+
+static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
+ isl29003_show_power_state, isl29003_store_power_state);
+
+
+/* lux */
+static ssize_t isl29003_show_lux(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+
+ /* No LUX data if not operational */
+ if (!isl29003_get_power_state(client))
+ return -EBUSY;
+
+ return sprintf(buf, "%d\n", isl29003_get_adc_value(client));
+}
+
+static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL);
+
+static struct attribute *isl29003_attributes[] = {
+ &dev_attr_range.attr,
+ &dev_attr_resolution.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_power_state.attr,
+ &dev_attr_lux.attr,
+ NULL
+};
+
+static const struct attribute_group isl29003_attr_group = {
+ .attrs = isl29003_attributes,
+};
+
+static int isl29003_init_client(struct i2c_client *client)
+{
+ struct isl29003_data *data = i2c_get_clientdata(client);
+ int i;
+
+ /* read all the registers once to fill the cache.
+ * if one of the reads fails, we consider the init failed */
+ for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
+ int v = i2c_smbus_read_byte_data(client, i);
+ if (v < 0)
+ return -ENODEV;
+
+ data->reg_cache[i] = v;
+ }
+
+ /* set defaults */
+ isl29003_set_range(client, 0);
+ isl29003_set_resolution(client, 0);
+ isl29003_set_mode(client, 0);
+ isl29003_set_power_state(client, 0);
+
+ return 0;
+}
+
+/*
+ * I2C layer
+ */
+
+static int __devinit isl29003_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct isl29003_data *data;
+ int err = 0;
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
+ return -EIO;
+
+ data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL);
+ if (!data)
+ return -ENOMEM;
+
+ data->client = client;
+ i2c_set_clientdata(client, data);
+ mutex_init(&data->lock);
+
+ /* initialize the ISL29003 chip */
+ err = isl29003_init_client(client);
+ if (err)
+ goto exit_kfree;
+
+ /* register sysfs hooks */
+ err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group);
+ if (err)
+ goto exit_kfree;
+
+ dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
+ return 0;
+
+exit_kfree:
+ kfree(data);
+ return err;
+}
+
+static int __devexit isl29003_remove(struct i2c_client *client)
+{
+ sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
+ isl29003_set_power_state(client, 0);
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int isl29003_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ return isl29003_set_power_state(client, 0);
+}
+
+static int isl29003_resume(struct i2c_client *client)
+{
+ int i;
+ struct isl29003_data *data = i2c_get_clientdata(client);
+
+ /* restore registers from cache */
+ for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
+ if (!i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
+ return -EIO;
+
+ return 0;
+}
+
+#else
+#define isl29003_suspend NULL
+#define isl29003_resume NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id isl29003_id[] = {
+ { "isl29003", 0 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, isl29003_id);
+
+static struct i2c_driver isl29003_driver = {
+ .driver = {
+ .name = ISL29003_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .suspend = isl29003_suspend,
+ .resume = isl29003_resume,
+ .probe = isl29003_probe,
+ .remove = __devexit_p(isl29003_remove),
+ .id_table = isl29003_id,
+};
+
+static int __init isl29003_init(void)
+{
+ return i2c_add_driver(&isl29003_driver);
+}
+
+static void __exit isl29003_exit(void)
+{
+ i2c_del_driver(&isl29003_driver);
+}
+
+MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
+MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(isl29003_init);
+module_exit(isl29003_exit);
+
diff --git a/drivers/misc/sgi-gru/Makefile b/drivers/misc/sgi-gru/Makefile
index 9e9170b3599..bcd8136d2f9 100644
--- a/drivers/misc/sgi-gru/Makefile
+++ b/drivers/misc/sgi-gru/Makefile
@@ -3,5 +3,5 @@ ifdef CONFIG_SGI_GRU_DEBUG
endif
obj-$(CONFIG_SGI_GRU) := gru.o
-gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o
+gru-y := grufile.o grumain.o grufault.o grutlbpurge.o gruprocfs.o grukservices.o gruhandles.o
diff --git a/drivers/misc/sgi-gru/gru_instructions.h b/drivers/misc/sgi-gru/gru_instructions.h
index 48762e7b98b..3fde33c1e8f 100644
--- a/drivers/misc/sgi-gru/gru_instructions.h
+++ b/drivers/misc/sgi-gru/gru_instructions.h
@@ -19,8 +19,11 @@
#ifndef __GRU_INSTRUCTIONS_H__
#define __GRU_INSTRUCTIONS_H__
-#define gru_flush_cache_hook(p)
-#define gru_emulator_wait_hook(p, w)
+extern int gru_check_status_proc(void *cb);
+extern int gru_wait_proc(void *cb);
+extern void gru_wait_abort_proc(void *cb);
+
+
/*
* Architecture dependent functions
@@ -29,16 +32,16 @@
#if defined(CONFIG_IA64)
#include <linux/compiler.h>
#include <asm/intrinsics.h>
-#define __flush_cache(p) ia64_fc(p)
+#define __flush_cache(p) ia64_fc((unsigned long)p)
/* Use volatile on IA64 to ensure ordering via st4.rel */
-#define gru_ordered_store_int(p,v) \
+#define gru_ordered_store_int(p, v) \
do { \
barrier(); \
*((volatile int *)(p)) = v; /* force st.rel */ \
} while (0)
#elif defined(CONFIG_X86_64)
#define __flush_cache(p) clflush(p)
-#define gru_ordered_store_int(p,v) \
+#define gru_ordered_store_int(p, v) \
do { \
barrier(); \
*(int *)p = v; \
@@ -558,20 +561,19 @@ extern int gru_get_cb_exception_detail(void *cb,
#define GRU_EXC_STR_SIZE 256
-extern int gru_check_status_proc(void *cb);
-extern int gru_wait_proc(void *cb);
-extern void gru_wait_abort_proc(void *cb);
/*
* Control block definition for checking status
*/
struct gru_control_block_status {
unsigned int icmd :1;
- unsigned int unused1 :31;
+ unsigned int ima :3;
+ unsigned int reserved0 :4;
+ unsigned int unused1 :24;
unsigned int unused2 :24;
unsigned int istatus :2;
unsigned int isubstatus :4;
- unsigned int inused3 :2;
+ unsigned int unused3 :2;
};
/* Get CB status */
diff --git a/drivers/misc/sgi-gru/grufault.c b/drivers/misc/sgi-gru/grufault.c
index 3ee698ad859..ab118558552 100644
--- a/drivers/misc/sgi-gru/grufault.c
+++ b/drivers/misc/sgi-gru/grufault.c
@@ -32,6 +32,7 @@
#include <linux/device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/security.h>
#include <asm/pgtable.h>
#include "gru.h"
#include "grutables.h"
@@ -266,6 +267,44 @@ err:
return 1;
}
+static int gru_vtop(struct gru_thread_state *gts, unsigned long vaddr,
+ int write, int atomic, unsigned long *gpa, int *pageshift)
+{
+ struct mm_struct *mm = gts->ts_mm;
+ struct vm_area_struct *vma;
+ unsigned long paddr;
+ int ret, ps;
+
+ vma = find_vma(mm, vaddr);
+ if (!vma)
+ goto inval;
+
+ /*
+ * Atomic lookup is faster & usually works even if called in non-atomic
+ * context.
+ */
+ rmb(); /* Must/check ms_range_active before loading PTEs */
+ ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &ps);
+ if (ret) {
+ if (atomic)
+ goto upm;
+ if (non_atomic_pte_lookup(vma, vaddr, write, &paddr, &ps))
+ goto inval;
+ }
+ if (is_gru_paddr(paddr))
+ goto inval;
+ paddr = paddr & ~((1UL << ps) - 1);
+ *gpa = uv_soc_phys_ram_to_gpa(paddr);
+ *pageshift = ps;
+ return 0;
+
+inval:
+ return -1;
+upm:
+ return -2;
+}
+
+
/*
* Drop a TLB entry into the GRU. The fault is described by info in an TFH.
* Input:
@@ -280,10 +319,8 @@ static int gru_try_dropin(struct gru_thread_state *gts,
struct gru_tlb_fault_handle *tfh,
unsigned long __user *cb)
{
- struct mm_struct *mm = gts->ts_mm;
- struct vm_area_struct *vma;
- int pageshift, asid, write, ret;
- unsigned long paddr, gpa, vaddr;
+ int pageshift = 0, asid, write, ret, atomic = !cb;
+ unsigned long gpa = 0, vaddr = 0;
/*
* NOTE: The GRU contains magic hardware that eliminates races between
@@ -317,28 +354,19 @@ static int gru_try_dropin(struct gru_thread_state *gts,
if (atomic_read(&gts->ts_gms->ms_range_active))
goto failactive;
- vma = find_vma(mm, vaddr);
- if (!vma)
+ ret = gru_vtop(gts, vaddr, write, atomic, &gpa, &pageshift);
+ if (ret == -1)
goto failinval;
+ if (ret == -2)
+ goto failupm;
- /*
- * Atomic lookup is faster & usually works even if called in non-atomic
- * context.
- */
- rmb(); /* Must/check ms_range_active before loading PTEs */
- ret = atomic_pte_lookup(vma, vaddr, write, &paddr, &pageshift);
- if (ret) {
- if (!cb)
+ if (!(gts->ts_sizeavail & GRU_SIZEAVAIL(pageshift))) {
+ gts->ts_sizeavail |= GRU_SIZEAVAIL(pageshift);
+ if (atomic || !gru_update_cch(gts, 0)) {
+ gts->ts_force_cch_reload = 1;
goto failupm;
- if (non_atomic_pte_lookup(vma, vaddr, write, &paddr,
- &pageshift))
- goto failinval;
+ }
}
- if (is_gru_paddr(paddr))
- goto failinval;
-
- paddr = paddr & ~((1UL << pageshift) - 1);
- gpa = uv_soc_phys_ram_to_gpa(paddr);
gru_cb_set_istatus_active(cb);
tfh_write_restart(tfh, gpa, GAA_RAM, vaddr, asid, write,
GRU_PAGESIZE(pageshift));
@@ -368,6 +396,7 @@ failupm:
failfmm:
/* FMM state on UPM call */
+ gru_flush_cache(tfh);
STAT(tlb_dropin_fail_fmm);
gru_dbg(grudev, "FAILED fmm tfh: 0x%p, state %d\n", tfh, tfh->state);
return 0;
@@ -448,6 +477,7 @@ irqreturn_t gru_intr(int irq, void *dev_id)
up_read(&gts->ts_mm->mmap_sem);
} else {
tfh_user_polling_mode(tfh);
+ STAT(intr_mm_lock_failed);
}
}
return IRQ_HANDLED;
@@ -497,10 +527,8 @@ int gru_handle_user_call_os(unsigned long cb)
if (!gts)
return -EINVAL;
- if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
- ret = -EINVAL;
+ if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE)
goto exit;
- }
/*
* If force_unload is set, the UPM TLB fault is phony. The task
@@ -508,6 +536,20 @@ int gru_handle_user_call_os(unsigned long cb)
* unload the context. The task will page fault and assign a new
* context.
*/
+ if (gts->ts_tgid_owner == current->tgid && gts->ts_blade >= 0 &&
+ gts->ts_blade != uv_numa_blade_id()) {
+ STAT(call_os_offnode_reference);
+ gts->ts_force_unload = 1;
+ }
+
+ /*
+ * CCH may contain stale data if ts_force_cch_reload is set.
+ */
+ if (gts->ts_gru && gts->ts_force_cch_reload) {
+ gru_update_cch(gts, 0);
+ gts->ts_force_cch_reload = 0;
+ }
+
ret = -EAGAIN;
cbrnum = thread_cbr_number(gts, ucbnum);
if (gts->ts_force_unload) {
@@ -541,11 +583,13 @@ int gru_get_exception_detail(unsigned long arg)
if (!gts)
return -EINVAL;
- if (gts->ts_gru) {
- ucbnum = get_cb_number((void *)excdet.cb);
+ ucbnum = get_cb_number((void *)excdet.cb);
+ if (ucbnum >= gts->ts_cbr_au_count * GRU_CBR_AU_SIZE) {
+ ret = -EINVAL;
+ } else if (gts->ts_gru) {
cbrnum = thread_cbr_number(gts, ucbnum);
cbe = get_cbe_by_index(gts->ts_gru, cbrnum);
- prefetchw(cbe); /* Harmless on hardware, required for emulator */
+ prefetchw(cbe);/* Harmless on hardware, required for emulator */
excdet.opc = cbe->opccpy;
excdet.exopc = cbe->exopccpy;
excdet.ecause = cbe->ecause;
@@ -567,6 +611,31 @@ int gru_get_exception_detail(unsigned long arg)
/*
* User request to unload a context. Content is saved for possible reload.
*/
+static int gru_unload_all_contexts(void)
+{
+ struct gru_thread_state *gts;
+ struct gru_state *gru;
+ int gid, ctxnum;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ foreach_gid(gid) {
+ gru = GID_TO_GRU(gid);
+ spin_lock(&gru->gs_lock);
+ for (ctxnum = 0; ctxnum < GRU_NUM_CCH; ctxnum++) {
+ gts = gru->gs_gts[ctxnum];
+ if (gts && mutex_trylock(&gts->ts_ctxlock)) {
+ spin_unlock(&gru->gs_lock);
+ gru_unload_context(gts, 1);
+ gru_unlock_gts(gts);
+ spin_lock(&gru->gs_lock);
+ }
+ }
+ spin_unlock(&gru->gs_lock);
+ }
+ return 0;
+}
+
int gru_user_unload_context(unsigned long arg)
{
struct gru_thread_state *gts;
@@ -578,6 +647,9 @@ int gru_user_unload_context(unsigned long arg)
gru_dbg(grudev, "gseg 0x%lx\n", req.gseg);
+ if (!req.gseg)
+ return gru_unload_all_contexts();
+
gts = gru_find_lock_gts(req.gseg);
if (!gts)
return -EINVAL;
@@ -609,7 +681,7 @@ int gru_user_flush_tlb(unsigned long arg)
if (!gts)
return -EINVAL;
- gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.vaddr + req.len);
+ gru_flush_tlb_range(gts->ts_gms, req.vaddr, req.len);
gru_unlock_gts(gts);
return 0;
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index c67e4e8bd62..3e6e42d2f01 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -45,7 +45,9 @@
#include <asm/uv/uv_mmrs.h>
struct gru_blade_state *gru_base[GRU_MAX_BLADES] __read_mostly;
-unsigned long gru_start_paddr, gru_end_paddr __read_mostly;
+unsigned long gru_start_paddr __read_mostly;
+unsigned long gru_end_paddr __read_mostly;
+unsigned int gru_max_gids __read_mostly;
struct gru_stats_s gru_stats;
/* Guaranteed user available resources on each node */
@@ -101,7 +103,7 @@ static int gru_file_mmap(struct file *file, struct vm_area_struct *vma)
return -EPERM;
if (vma->vm_start & (GRU_GSEG_PAGESIZE - 1) ||
- vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
+ vma->vm_end & (GRU_GSEG_PAGESIZE - 1))
return -EINVAL;
vma->vm_flags |=
@@ -273,8 +275,11 @@ static void gru_init_chiplet(struct gru_state *gru, unsigned long paddr,
gru->gs_blade_id = bid;
gru->gs_cbr_map = (GRU_CBR_AU == 64) ? ~0 : (1UL << GRU_CBR_AU) - 1;
gru->gs_dsr_map = (1UL << GRU_DSR_AU) - 1;
+ gru->gs_asid_limit = MAX_ASID;
gru_tgh_flush_init(gru);
- gru_dbg(grudev, "bid %d, nid %d, gru %x, vaddr %p (0x%lx)\n",
+ if (gru->gs_gid >= gru_max_gids)
+ gru_max_gids = gru->gs_gid + 1;
+ gru_dbg(grudev, "bid %d, nid %d, gid %d, vaddr %p (0x%lx)\n",
bid, nid, gru->gs_gid, gru->gs_gru_base_vaddr,
gru->gs_gru_base_paddr);
gru_kservices_init(gru);
@@ -295,7 +300,7 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
for_each_online_node(nid) {
bid = uv_node_to_blade_id(nid);
pnode = uv_node_to_pnode(nid);
- if (gru_base[bid])
+ if (bid < 0 || gru_base[bid])
continue;
page = alloc_pages_node(nid, GFP_KERNEL, order);
if (!page)
@@ -308,11 +313,11 @@ static int gru_init_tables(unsigned long gru_base_paddr, void *gru_base_vaddr)
dsrbytes = 0;
cbrs = 0;
for (gru = gru_base[bid]->bs_grus, chip = 0;
- chip < GRU_CHIPLETS_PER_BLADE;
+ chip < GRU_CHIPLETS_PER_BLADE;
chip++, gru++) {
paddr = gru_chiplet_paddr(gru_base_paddr, pnode, chip);
vaddr = gru_chiplet_vaddr(gru_base_vaddr, pnode, chip);
- gru_init_chiplet(gru, paddr, vaddr, bid, nid, chip);
+ gru_init_chiplet(gru, paddr, vaddr, nid, bid, chip);
n = hweight64(gru->gs_cbr_map) * GRU_CBR_AU_SIZE;
cbrs = max(cbrs, n);
n = hweight64(gru->gs_dsr_map) * GRU_DSR_AU_BYTES;
@@ -370,26 +375,26 @@ static int __init gru_init(void)
void *gru_start_vaddr;
if (!is_uv_system())
- return 0;
+ return -ENODEV;
#if defined CONFIG_IA64
gru_start_paddr = 0xd000000000UL; /* ZZZZZZZZZZZZZZZZZZZ fixme */
#else
gru_start_paddr = uv_read_local_mmr(UVH_RH_GAM_GRU_OVERLAY_CONFIG_MMR) &
0x7fffffffffffUL;
-
#endif
gru_start_vaddr = __va(gru_start_paddr);
- gru_end_paddr = gru_start_paddr + MAX_NUMNODES * GRU_SIZE;
+ gru_end_paddr = gru_start_paddr + GRU_MAX_BLADES * GRU_SIZE;
printk(KERN_INFO "GRU space: 0x%lx - 0x%lx\n",
gru_start_paddr, gru_end_paddr);
irq = get_base_irq();
for (chip = 0; chip < GRU_CHIPLETS_PER_BLADE; chip++) {
ret = request_irq(irq + chip, gru_intr, 0, id, NULL);
- /* TODO: fix irq handling on x86. For now ignore failures because
+ /* TODO: fix irq handling on x86. For now ignore failure because
* interrupts are not required & not yet fully supported */
if (ret) {
- printk("!!!WARNING: GRU ignoring request failure!!!\n");
+ printk(KERN_WARNING
+ "!!!WARNING: GRU ignoring request failure!!!\n");
ret = 0;
}
if (ret) {
@@ -435,7 +440,7 @@ exit1:
static void __exit gru_exit(void)
{
- int i, bid;
+ int i, bid, gid;
int order = get_order(sizeof(struct gru_state) *
GRU_CHIPLETS_PER_BLADE);
@@ -445,6 +450,9 @@ static void __exit gru_exit(void)
for (i = 0; i < GRU_CHIPLETS_PER_BLADE; i++)
free_irq(IRQ_GRU + i, NULL);
+ foreach_gid(gid)
+ gru_kservices_exit(GID_TO_GRU(gid));
+
for (bid = 0; bid < GRU_MAX_BLADES; bid++)
free_pages((unsigned long)gru_base[bid], order);
@@ -469,7 +477,11 @@ struct vm_operations_struct gru_vm_ops = {
.fault = gru_fault,
};
+#ifndef MODULE
fs_initcall(gru_init);
+#else
+module_init(gru_init);
+#endif
module_exit(gru_exit);
module_param(gru_options, ulong, 0644);
diff --git a/drivers/misc/sgi-gru/gruhandles.c b/drivers/misc/sgi-gru/gruhandles.c
new file mode 100644
index 00000000000..9b7ccb32869
--- /dev/null
+++ b/drivers/misc/sgi-gru/gruhandles.c
@@ -0,0 +1,183 @@
+/*
+ * GRU KERNEL MCS INSTRUCTIONS
+ *
+ * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include "gru.h"
+#include "grulib.h"
+#include "grutables.h"
+
+/* 10 sec */
+#ifdef CONFIG_IA64
+#include <asm/processor.h>
+#define GRU_OPERATION_TIMEOUT (((cycles_t) local_cpu_data->itc_freq)*10)
+#else
+#include <asm/tsc.h>
+#define GRU_OPERATION_TIMEOUT ((cycles_t) tsc_khz*10*1000)
+#endif
+
+/* Extract the status field from a kernel handle */
+#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
+
+struct mcs_op_statistic mcs_op_statistics[mcsop_last];
+
+static void update_mcs_stats(enum mcs_op op, unsigned long clks)
+{
+ atomic_long_inc(&mcs_op_statistics[op].count);
+ atomic_long_add(clks, &mcs_op_statistics[op].total);
+ if (mcs_op_statistics[op].max < clks)
+ mcs_op_statistics[op].max = clks;
+}
+
+static void start_instruction(void *h)
+{
+ unsigned long *w0 = h;
+
+ wmb(); /* setting CMD bit must be last */
+ *w0 = *w0 | 1;
+ gru_flush_cache(h);
+}
+
+static int wait_instruction_complete(void *h, enum mcs_op opc)
+{
+ int status;
+ cycles_t start_time = get_cycles();
+
+ while (1) {
+ cpu_relax();
+ status = GET_MSEG_HANDLE_STATUS(h);
+ if (status != CCHSTATUS_ACTIVE)
+ break;
+ if (GRU_OPERATION_TIMEOUT < (get_cycles() - start_time))
+ panic("GRU %p is malfunctioning\n", h);
+ }
+ if (gru_options & OPT_STATS)
+ update_mcs_stats(opc, get_cycles() - start_time);
+ return status;
+}
+
+int cch_allocate(struct gru_context_configuration_handle *cch,
+ int asidval, int sizeavail, unsigned long cbrmap,
+ unsigned long dsrmap)
+{
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ cch->asid[i] = (asidval++);
+ cch->sizeavail[i] = sizeavail;
+ }
+ cch->dsr_allocation_map = dsrmap;
+ cch->cbr_allocation_map = cbrmap;
+ cch->opc = CCHOP_ALLOCATE;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_allocate);
+}
+
+int cch_start(struct gru_context_configuration_handle *cch)
+{
+ cch->opc = CCHOP_START;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_start);
+}
+
+int cch_interrupt(struct gru_context_configuration_handle *cch)
+{
+ cch->opc = CCHOP_INTERRUPT;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_interrupt);
+}
+
+int cch_deallocate(struct gru_context_configuration_handle *cch)
+{
+ cch->opc = CCHOP_DEALLOCATE;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_deallocate);
+}
+
+int cch_interrupt_sync(struct gru_context_configuration_handle
+ *cch)
+{
+ cch->opc = CCHOP_INTERRUPT_SYNC;
+ start_instruction(cch);
+ return wait_instruction_complete(cch, cchop_interrupt_sync);
+}
+
+int tgh_invalidate(struct gru_tlb_global_handle *tgh,
+ unsigned long vaddr, unsigned long vaddrmask,
+ int asid, int pagesize, int global, int n,
+ unsigned short ctxbitmap)
+{
+ tgh->vaddr = vaddr;
+ tgh->asid = asid;
+ tgh->pagesize = pagesize;
+ tgh->n = n;
+ tgh->global = global;
+ tgh->vaddrmask = vaddrmask;
+ tgh->ctxbitmap = ctxbitmap;
+ tgh->opc = TGHOP_TLBINV;
+ start_instruction(tgh);
+ return wait_instruction_complete(tgh, tghop_invalidate);
+}
+
+void tfh_write_only(struct gru_tlb_fault_handle *tfh,
+ unsigned long pfn, unsigned long vaddr,
+ int asid, int dirty, int pagesize)
+{
+ tfh->fillasid = asid;
+ tfh->fillvaddr = vaddr;
+ tfh->pfn = pfn;
+ tfh->dirty = dirty;
+ tfh->pagesize = pagesize;
+ tfh->opc = TFHOP_WRITE_ONLY;
+ start_instruction(tfh);
+}
+
+void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
+ unsigned long paddr, int gaa,
+ unsigned long vaddr, int asid, int dirty,
+ int pagesize)
+{
+ tfh->fillasid = asid;
+ tfh->fillvaddr = vaddr;
+ tfh->pfn = paddr >> GRU_PADDR_SHIFT;
+ tfh->gaa = gaa;
+ tfh->dirty = dirty;
+ tfh->pagesize = pagesize;
+ tfh->opc = TFHOP_WRITE_RESTART;
+ start_instruction(tfh);
+}
+
+void tfh_restart(struct gru_tlb_fault_handle *tfh)
+{
+ tfh->opc = TFHOP_RESTART;
+ start_instruction(tfh);
+}
+
+void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
+{
+ tfh->opc = TFHOP_USER_POLLING_MODE;
+ start_instruction(tfh);
+}
+
+void tfh_exception(struct gru_tlb_fault_handle *tfh)
+{
+ tfh->opc = TFHOP_EXCEPTION;
+ start_instruction(tfh);
+}
+
diff --git a/drivers/misc/sgi-gru/gruhandles.h b/drivers/misc/sgi-gru/gruhandles.h
index b63018d60fe..1ed74d7508c 100644
--- a/drivers/misc/sgi-gru/gruhandles.h
+++ b/drivers/misc/sgi-gru/gruhandles.h
@@ -489,170 +489,28 @@ enum gru_cbr_state {
* 64m 26 8
* ...
*/
-#define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2: (sh)) >> 1) - 6)
+#define GRU_PAGESIZE(sh) ((((sh) > 20 ? (sh) + 2 : (sh)) >> 1) - 6)
#define GRU_SIZEAVAIL(sh) (1UL << GRU_PAGESIZE(sh))
/* minimum TLB purge count to ensure a full purge */
#define GRUMAXINVAL 1024UL
-
-/* Extract the status field from a kernel handle */
-#define GET_MSEG_HANDLE_STATUS(h) (((*(unsigned long *)(h)) >> 16) & 3)
-
-static inline void start_instruction(void *h)
-{
- unsigned long *w0 = h;
-
- wmb(); /* setting CMD bit must be last */
- *w0 = *w0 | 1;
- gru_flush_cache(h);
-}
-
-static inline int wait_instruction_complete(void *h)
-{
- int status;
-
- do {
- cpu_relax();
- barrier();
- status = GET_MSEG_HANDLE_STATUS(h);
- } while (status == CCHSTATUS_ACTIVE);
- return status;
-}
-
-#if defined CONFIG_IA64
-static inline void cch_allocate_set_asids(
- struct gru_context_configuration_handle *cch, int asidval)
-{
- int i;
-
- for (i = 0; i <= RGN_HPAGE; i++) { /* assume HPAGE is last region */
- cch->asid[i] = (asidval++);
-#if 0
- /* ZZZ hugepages not supported yet */
- if (i == RGN_HPAGE)
- cch->sizeavail[i] = GRU_SIZEAVAIL(hpage_shift);
- else
-#endif
- cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT);
- }
-}
-#elif defined CONFIG_X86_64
-static inline void cch_allocate_set_asids(
- struct gru_context_configuration_handle *cch, int asidval)
-{
- int i;
-
- for (i = 0; i < 8; i++) {
- cch->asid[i] = asidval++;
- cch->sizeavail[i] = GRU_SIZEAVAIL(PAGE_SHIFT) |
- GRU_SIZEAVAIL(21);
- }
-}
-#endif
-
-static inline int cch_allocate(struct gru_context_configuration_handle *cch,
- int asidval, unsigned long cbrmap,
- unsigned long dsrmap)
-{
- cch_allocate_set_asids(cch, asidval);
- cch->dsr_allocation_map = dsrmap;
- cch->cbr_allocation_map = cbrmap;
- cch->opc = CCHOP_ALLOCATE;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_start(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_START;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_interrupt(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_INTERRUPT;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_deallocate(struct gru_context_configuration_handle *cch)
-{
- cch->opc = CCHOP_DEALLOCATE;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int cch_interrupt_sync(struct gru_context_configuration_handle
- *cch)
-{
- cch->opc = CCHOP_INTERRUPT_SYNC;
- start_instruction(cch);
- return wait_instruction_complete(cch);
-}
-
-static inline int tgh_invalidate(struct gru_tlb_global_handle *tgh,
- unsigned long vaddr, unsigned long vaddrmask,
- int asid, int pagesize, int global, int n,
- unsigned short ctxbitmap)
-{
- tgh->vaddr = vaddr;
- tgh->asid = asid;
- tgh->pagesize = pagesize;
- tgh->n = n;
- tgh->global = global;
- tgh->vaddrmask = vaddrmask;
- tgh->ctxbitmap = ctxbitmap;
- tgh->opc = TGHOP_TLBINV;
- start_instruction(tgh);
- return wait_instruction_complete(tgh);
-}
-
-static inline void tfh_write_only(struct gru_tlb_fault_handle *tfh,
- unsigned long pfn, unsigned long vaddr,
- int asid, int dirty, int pagesize)
-{
- tfh->fillasid = asid;
- tfh->fillvaddr = vaddr;
- tfh->pfn = pfn;
- tfh->dirty = dirty;
- tfh->pagesize = pagesize;
- tfh->opc = TFHOP_WRITE_ONLY;
- start_instruction(tfh);
-}
-
-static inline void tfh_write_restart(struct gru_tlb_fault_handle *tfh,
- unsigned long paddr, int gaa,
- unsigned long vaddr, int asid, int dirty,
- int pagesize)
-{
- tfh->fillasid = asid;
- tfh->fillvaddr = vaddr;
- tfh->pfn = paddr >> GRU_PADDR_SHIFT;
- tfh->gaa = gaa;
- tfh->dirty = dirty;
- tfh->pagesize = pagesize;
- tfh->opc = TFHOP_WRITE_RESTART;
- start_instruction(tfh);
-}
-
-static inline void tfh_restart(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_RESTART;
- start_instruction(tfh);
-}
-
-static inline void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_USER_POLLING_MODE;
- start_instruction(tfh);
-}
-
-static inline void tfh_exception(struct gru_tlb_fault_handle *tfh)
-{
- tfh->opc = TFHOP_EXCEPTION;
- start_instruction(tfh);
-}
+int cch_allocate(struct gru_context_configuration_handle *cch,
+ int asidval, int sizeavail, unsigned long cbrmap, unsigned long dsrmap);
+
+int cch_start(struct gru_context_configuration_handle *cch);
+int cch_interrupt(struct gru_context_configuration_handle *cch);
+int cch_deallocate(struct gru_context_configuration_handle *cch);
+int cch_interrupt_sync(struct gru_context_configuration_handle *cch);
+int tgh_invalidate(struct gru_tlb_global_handle *tgh, unsigned long vaddr,
+ unsigned long vaddrmask, int asid, int pagesize, int global, int n,
+ unsigned short ctxbitmap);
+void tfh_write_only(struct gru_tlb_fault_handle *tfh, unsigned long pfn,
+ unsigned long vaddr, int asid, int dirty, int pagesize);
+void tfh_write_restart(struct gru_tlb_fault_handle *tfh, unsigned long paddr,
+ int gaa, unsigned long vaddr, int asid, int dirty, int pagesize);
+void tfh_restart(struct gru_tlb_fault_handle *tfh);
+void tfh_user_polling_mode(struct gru_tlb_fault_handle *tfh);
+void tfh_exception(struct gru_tlb_fault_handle *tfh);
#endif /* __GRUHANDLES_H__ */
diff --git a/drivers/misc/sgi-gru/grukservices.c b/drivers/misc/sgi-gru/grukservices.c
index 880c55dfb66..d8bd7d84a7c 100644
--- a/drivers/misc/sgi-gru/grukservices.c
+++ b/drivers/misc/sgi-gru/grukservices.c
@@ -52,8 +52,10 @@
*/
/* Blade percpu resources PERMANENTLY reserved for kernel use */
-#define GRU_NUM_KERNEL_CBR 1
+#define GRU_NUM_KERNEL_CBR 1
#define GRU_NUM_KERNEL_DSR_BYTES 256
+#define GRU_NUM_KERNEL_DSR_CL (GRU_NUM_KERNEL_DSR_BYTES / \
+ GRU_CACHE_LINE_BYTES)
#define KERNEL_CTXNUM 15
/* GRU instruction attributes for all instructions */
@@ -94,7 +96,6 @@ struct message_header {
char fill;
};
-#define QLINES(mq) ((mq) + offsetof(struct message_queue, qlines))
#define HSTATUS(mq, h) ((mq) + offsetof(struct message_queue, hstatus[h]))
static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr)
@@ -122,7 +123,7 @@ int gru_get_cb_exception_detail(void *cb,
struct gru_control_block_extended *cbe;
cbe = get_cbe(GRUBASE(cb), get_cb_number(cb));
- prefetchw(cbe); /* Harmless on hardware, required for emulator */
+ prefetchw(cbe); /* Harmless on hardware, required for emulator */
excdet->opc = cbe->opccpy;
excdet->exopc = cbe->exopccpy;
excdet->ecause = cbe->ecause;
@@ -250,7 +251,8 @@ static inline void restore_present2(void *p, int val)
* Create a message queue.
* qlines - message queue size in cache lines. Includes 2-line header.
*/
-int gru_create_message_queue(void *p, unsigned int bytes)
+int gru_create_message_queue(struct gru_message_queue_desc *mqd,
+ void *p, unsigned int bytes, int nasid, int vector, int apicid)
{
struct message_queue *mq = p;
unsigned int qlines;
@@ -265,6 +267,12 @@ int gru_create_message_queue(void *p, unsigned int bytes)
mq->hstatus[0] = 0;
mq->hstatus[1] = 1;
mq->head = gru_mesq_head(2, qlines / 2 + 1);
+ mqd->mq = mq;
+ mqd->mq_gpa = uv_gpa(mq);
+ mqd->qlines = qlines;
+ mqd->interrupt_pnode = UV_NASID_TO_PNODE(nasid);
+ mqd->interrupt_vector = vector;
+ mqd->interrupt_apicid = apicid;
return 0;
}
EXPORT_SYMBOL_GPL(gru_create_message_queue);
@@ -277,8 +285,8 @@ EXPORT_SYMBOL_GPL(gru_create_message_queue);
* -1 - if mesq sent successfully but queue not full
* >0 - unexpected error. MQE_xxx returned
*/
-static int send_noop_message(void *cb,
- unsigned long mq, void *mesg)
+static int send_noop_message(void *cb, struct gru_message_queue_desc *mqd,
+ void *mesg)
{
const struct message_header noop_header = {
.present = MQS_NOOP, .lines = 1};
@@ -289,7 +297,7 @@ static int send_noop_message(void *cb,
STAT(mesq_noop);
save_mhdr = *mhdr;
*mhdr = noop_header;
- gru_mesq(cb, mq, gru_get_tri(mhdr), 1, IMA);
+ gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), 1, IMA);
ret = gru_wait(cb);
if (ret) {
@@ -313,7 +321,7 @@ static int send_noop_message(void *cb,
break;
case CBSS_PUT_NACKED:
STAT(mesq_noop_put_nacked);
- m = mq + (gru_get_amo_value_head(cb) << 6);
+ m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, 1, 1,
IMA);
if (gru_wait(cb) == CBS_IDLE)
@@ -333,30 +341,20 @@ static int send_noop_message(void *cb,
/*
* Handle a gru_mesq full.
*/
-static int send_message_queue_full(void *cb,
- unsigned long mq, void *mesg, int lines)
+static int send_message_queue_full(void *cb, struct gru_message_queue_desc *mqd,
+ void *mesg, int lines)
{
union gru_mesqhead mqh;
unsigned int limit, head;
unsigned long avalue;
- int half, qlines, save;
+ int half, qlines;
/* Determine if switching to first/second half of q */
avalue = gru_get_amo_value(cb);
head = gru_get_amo_value_head(cb);
limit = gru_get_amo_value_limit(cb);
- /*
- * Fetch "qlines" from the queue header. Since the queue may be
- * in memory that can't be accessed using socket addresses, use
- * the GRU to access the data. Use DSR space from the message.
- */
- save = *(int *)mesg;
- gru_vload(cb, QLINES(mq), gru_get_tri(mesg), XTYPE_W, 1, 1, IMA);
- if (gru_wait(cb) != CBS_IDLE)
- goto cberr;
- qlines = *(int *)mesg;
- *(int *)mesg = save;
+ qlines = mqd->qlines;
half = (limit != qlines);
if (half)
@@ -365,7 +363,7 @@ static int send_message_queue_full(void *cb,
mqh = gru_mesq_head(2, qlines / 2 + 1);
/* Try to get lock for switching head pointer */
- gru_gamir(cb, EOP_IR_CLR, HSTATUS(mq, half), XTYPE_DW, IMA);
+ gru_gamir(cb, EOP_IR_CLR, HSTATUS(mqd->mq_gpa, half), XTYPE_DW, IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
if (!gru_get_amo_value(cb)) {
@@ -375,8 +373,8 @@ static int send_message_queue_full(void *cb,
/* Got the lock. Send optional NOP if queue not full, */
if (head != limit) {
- if (send_noop_message(cb, mq, mesg)) {
- gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half),
+ if (send_noop_message(cb, mqd, mesg)) {
+ gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half),
XTYPE_DW, IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
@@ -387,14 +385,16 @@ static int send_message_queue_full(void *cb,
}
/* Then flip queuehead to other half of queue. */
- gru_gamer(cb, EOP_ERR_CSWAP, mq, XTYPE_DW, mqh.val, avalue, IMA);
+ gru_gamer(cb, EOP_ERR_CSWAP, mqd->mq_gpa, XTYPE_DW, mqh.val, avalue,
+ IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
/* If not successfully in swapping queue head, clear the hstatus lock */
if (gru_get_amo_value(cb) != avalue) {
STAT(mesq_qf_switch_head_failed);
- gru_gamir(cb, EOP_IR_INC, HSTATUS(mq, half), XTYPE_DW, IMA);
+ gru_gamir(cb, EOP_IR_INC, HSTATUS(mqd->mq_gpa, half), XTYPE_DW,
+ IMA);
if (gru_wait(cb) != CBS_IDLE)
goto cberr;
}
@@ -404,15 +404,25 @@ cberr:
return MQE_UNEXPECTED_CB_ERR;
}
+/*
+ * Send a cross-partition interrupt to the SSI that contains the target
+ * message queue. Normally, the interrupt is automatically delivered by hardware
+ * but some error conditions require explicit delivery.
+ */
+static void send_message_queue_interrupt(struct gru_message_queue_desc *mqd)
+{
+ if (mqd->interrupt_vector)
+ uv_hub_send_ipi(mqd->interrupt_pnode, mqd->interrupt_apicid,
+ mqd->interrupt_vector);
+}
+
/*
* Handle a gru_mesq failure. Some of these failures are software recoverable
* or retryable.
*/
-static int send_message_failure(void *cb,
- unsigned long mq,
- void *mesg,
- int lines)
+static int send_message_failure(void *cb, struct gru_message_queue_desc *mqd,
+ void *mesg, int lines)
{
int substatus, ret = 0;
unsigned long m;
@@ -429,7 +439,7 @@ static int send_message_failure(void *cb,
break;
case CBSS_QLIMIT_REACHED:
STAT(mesq_send_qlimit_reached);
- ret = send_message_queue_full(cb, mq, mesg, lines);
+ ret = send_message_queue_full(cb, mqd, mesg, lines);
break;
case CBSS_AMO_NACKED:
STAT(mesq_send_amo_nacked);
@@ -437,12 +447,14 @@ static int send_message_failure(void *cb,
break;
case CBSS_PUT_NACKED:
STAT(mesq_send_put_nacked);
- m =mq + (gru_get_amo_value_head(cb) << 6);
+ m = mqd->mq_gpa + (gru_get_amo_value_head(cb) << 6);
gru_vstore(cb, m, gru_get_tri(mesg), XTYPE_CL, lines, 1, IMA);
- if (gru_wait(cb) == CBS_IDLE)
+ if (gru_wait(cb) == CBS_IDLE) {
ret = MQE_OK;
- else
+ send_message_queue_interrupt(mqd);
+ } else {
ret = MQE_UNEXPECTED_CB_ERR;
+ }
break;
default:
BUG();
@@ -452,12 +464,12 @@ static int send_message_failure(void *cb,
/*
* Send a message to a message queue
- * cb GRU control block to use to send message
- * mq message queue
+ * mqd message queue descriptor
* mesg message. ust be vaddr within a GSEG
* bytes message size (<= 2 CL)
*/
-int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
+int gru_send_message_gpa(struct gru_message_queue_desc *mqd, void *mesg,
+ unsigned int bytes)
{
struct message_header *mhdr;
void *cb;
@@ -481,10 +493,10 @@ int gru_send_message_gpa(unsigned long mq, void *mesg, unsigned int bytes)
do {
ret = MQE_OK;
- gru_mesq(cb, mq, gru_get_tri(mhdr), clines, IMA);
+ gru_mesq(cb, mqd->mq_gpa, gru_get_tri(mhdr), clines, IMA);
istatus = gru_wait(cb);
if (istatus != CBS_IDLE)
- ret = send_message_failure(cb, mq, dsr, clines);
+ ret = send_message_failure(cb, mqd, dsr, clines);
} while (ret == MQIE_AGAIN);
gru_free_cpu_resources(cb, dsr);
@@ -497,9 +509,9 @@ EXPORT_SYMBOL_GPL(gru_send_message_gpa);
/*
* Advance the receive pointer for the queue to the next message.
*/
-void gru_free_message(void *rmq, void *mesg)
+void gru_free_message(struct gru_message_queue_desc *mqd, void *mesg)
{
- struct message_queue *mq = rmq;
+ struct message_queue *mq = mqd->mq;
struct message_header *mhdr = mq->next;
void *next, *pnext;
int half = -1;
@@ -529,16 +541,16 @@ EXPORT_SYMBOL_GPL(gru_free_message);
* present. User must call next_message() to move to next message.
* rmq message queue
*/
-void *gru_get_next_message(void *rmq)
+void *gru_get_next_message(struct gru_message_queue_desc *mqd)
{
- struct message_queue *mq = rmq;
+ struct message_queue *mq = mqd->mq;
struct message_header *mhdr = mq->next;
int present = mhdr->present;
/* skip NOOP messages */
STAT(mesq_receive);
while (present == MQS_NOOP) {
- gru_free_message(rmq, mhdr);
+ gru_free_message(mqd, mhdr);
mhdr = mq->next;
present = mhdr->present;
}
@@ -576,7 +588,7 @@ int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
if (gru_get_cpu_resources(GRU_NUM_KERNEL_DSR_BYTES, &cb, &dsr))
return MQE_BUG_NO_RESOURCES;
gru_bcopy(cb, src_gpa, dest_gpa, gru_get_tri(dsr),
- XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_BYTES, IMA);
+ XTYPE_B, bytes, GRU_NUM_KERNEL_DSR_CL, IMA);
ret = gru_wait(cb);
gru_free_cpu_resources(cb, dsr);
return ret;
@@ -611,7 +623,7 @@ static int quicktest(struct gru_state *gru)
if (word0 != word1 || word0 != MAGIC) {
printk
- ("GRU quicktest err: gru %d, found 0x%lx, expected 0x%lx\n",
+ ("GRU quicktest err: gid %d, found 0x%lx, expected 0x%lx\n",
gru->gs_gid, word1, MAGIC);
BUG(); /* ZZZ should not be fatal */
}
@@ -660,15 +672,15 @@ int gru_kservices_init(struct gru_state *gru)
cch->tlb_int_enable = 0;
cch->tfm_done_bit_enable = 0;
cch->unmap_enable = 1;
- err = cch_allocate(cch, 0, cbr_map, dsr_map);
+ err = cch_allocate(cch, 0, 0, cbr_map, dsr_map);
if (err) {
gru_dbg(grudev,
- "Unable to allocate kernel CCH: gru %d, err %d\n",
+ "Unable to allocate kernel CCH: gid %d, err %d\n",
gru->gs_gid, err);
BUG();
}
if (cch_start(cch)) {
- gru_dbg(grudev, "Unable to start kernel CCH: gru %d, err %d\n",
+ gru_dbg(grudev, "Unable to start kernel CCH: gid %d, err %d\n",
gru->gs_gid, err);
BUG();
}
@@ -678,3 +690,22 @@ int gru_kservices_init(struct gru_state *gru)
quicktest(gru);
return 0;
}
+
+void gru_kservices_exit(struct gru_state *gru)
+{
+ struct gru_context_configuration_handle *cch;
+ struct gru_blade_state *bs;
+
+ bs = gru->gs_blade;
+ if (gru != &bs->bs_grus[1])
+ return;
+
+ cch = get_cch(gru->gs_gru_base_vaddr, KERNEL_CTXNUM);
+ lock_cch_handle(cch);
+ if (cch_interrupt_sync(cch))
+ BUG();
+ if (cch_deallocate(cch))
+ BUG();
+ unlock_cch_handle(cch);
+}
+
diff --git a/drivers/misc/sgi-gru/grukservices.h b/drivers/misc/sgi-gru/grukservices.h
index eb17e0a3ac6..747ed315d56 100644
--- a/drivers/misc/sgi-gru/grukservices.h
+++ b/drivers/misc/sgi-gru/grukservices.h
@@ -41,6 +41,15 @@
* - gru_create_message_queue() needs interrupt vector info
*/
+struct gru_message_queue_desc {
+ void *mq; /* message queue vaddress */
+ unsigned long mq_gpa; /* global address of mq */
+ int qlines; /* queue size in CL */
+ int interrupt_vector; /* interrupt vector */
+ int interrupt_pnode; /* pnode for interrupt */
+ int interrupt_apicid; /* lapicid for interrupt */
+};
+
/*
* Initialize a user allocated chunk of memory to be used as
* a message queue. The caller must ensure that the queue is
@@ -51,14 +60,19 @@
* to manage the queue.
*
* Input:
- * p pointer to user allocated memory.
+ * mqd pointer to message queue descriptor
+ * p pointer to user allocated mesq memory.
* bytes size of message queue in bytes
+ * vector interrupt vector (zero if no interrupts)
+ * nasid nasid of blade where interrupt is delivered
+ * apicid apicid of cpu for interrupt
*
* Errors:
* 0 OK
* >0 error
*/
-extern int gru_create_message_queue(void *p, unsigned int bytes);
+extern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
+ void *p, unsigned int bytes, int nasid, int vector, int apicid);
/*
* Send a message to a message queue.
@@ -68,7 +82,7 @@ extern int gru_create_message_queue(void *p, unsigned int bytes);
*
*
* Input:
- * xmq message queue - must be a UV global physical address
+ * mqd pointer to message queue descriptor
* mesg pointer to message. Must be 64-bit aligned
* bytes size of message in bytes
*
@@ -77,8 +91,8 @@ extern int gru_create_message_queue(void *p, unsigned int bytes);
* >0 Send failure - see error codes below
*
*/
-extern int gru_send_message_gpa(unsigned long mq_gpa, void *mesg,
- unsigned int bytes);
+extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
+ void *mesg, unsigned int bytes);
/* Status values for gru_send_message() */
#define MQE_OK 0 /* message sent successfully */
@@ -94,10 +108,11 @@ extern int gru_send_message_gpa(unsigned long mq_gpa, void *mesg,
* API extensions may allow for out-of-order freeing.
*
* Input
- * mq message queue
+ * mqd pointer to message queue descriptor
* mesq message being freed
*/
-extern void gru_free_message(void *mq, void *mesq);
+extern void gru_free_message(struct gru_message_queue_desc *mqd,
+ void *mesq);
/*
* Get next message from message queue. Returns pointer to
@@ -106,13 +121,13 @@ extern void gru_free_message(void *mq, void *mesq);
* in order to move the queue pointers to next message.
*
* Input
- * mq message queue
+ * mqd pointer to message queue descriptor
*
* Output:
* p pointer to message
* NULL no message available
*/
-extern void *gru_get_next_message(void *mq);
+extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
/*
diff --git a/drivers/misc/sgi-gru/grumain.c b/drivers/misc/sgi-gru/grumain.c
index 3d2fc216bae..ec3f7a17d22 100644
--- a/drivers/misc/sgi-gru/grumain.c
+++ b/drivers/misc/sgi-gru/grumain.c
@@ -76,10 +76,9 @@ int gru_cpu_fault_map_id(void)
/* Hit the asid limit. Start over */
static int gru_wrap_asid(struct gru_state *gru)
{
- gru_dbg(grudev, "gru %p\n", gru);
+ gru_dbg(grudev, "gid %d\n", gru->gs_gid);
STAT(asid_wrap);
gru->gs_asid_gen++;
- gru_flush_all_tlb(gru);
return MIN_ASID;
}
@@ -88,19 +87,21 @@ static int gru_reset_asid_limit(struct gru_state *gru, int asid)
{
int i, gid, inuse_asid, limit;
- gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid);
+ gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
STAT(asid_next);
limit = MAX_ASID;
if (asid >= limit)
asid = gru_wrap_asid(gru);
+ gru_flush_all_tlb(gru);
gid = gru->gs_gid;
again:
for (i = 0; i < GRU_NUM_CCH; i++) {
if (!gru->gs_gts[i])
continue;
inuse_asid = gru->gs_gts[i]->ts_gms->ms_asids[gid].mt_asid;
- gru_dbg(grudev, "gru %p, inuse_asid 0x%x, cxtnum %d, gts %p\n",
- gru, inuse_asid, i, gru->gs_gts[i]);
+ gru_dbg(grudev, "gid %d, gts %p, gms %p, inuse 0x%x, cxt %d\n",
+ gru->gs_gid, gru->gs_gts[i], gru->gs_gts[i]->ts_gms,
+ inuse_asid, i);
if (inuse_asid == asid) {
asid += ASID_INC;
if (asid >= limit) {
@@ -120,8 +121,8 @@ again:
}
gru->gs_asid_limit = limit;
gru->gs_asid = asid;
- gru_dbg(grudev, "gru %p, new asid 0x%x, new_limit 0x%x\n", gru, asid,
- limit);
+ gru_dbg(grudev, "gid %d, new asid 0x%x, new_limit 0x%x\n", gru->gs_gid,
+ asid, limit);
return asid;
}
@@ -130,14 +131,12 @@ static int gru_assign_asid(struct gru_state *gru)
{
int asid;
- spin_lock(&gru->gs_asid_lock);
gru->gs_asid += ASID_INC;
asid = gru->gs_asid;
if (asid >= gru->gs_asid_limit)
asid = gru_reset_asid_limit(gru, asid);
- spin_unlock(&gru->gs_asid_lock);
- gru_dbg(grudev, "gru %p, asid 0x%x\n", gru, asid);
+ gru_dbg(grudev, "gid %d, asid 0x%x\n", gru->gs_gid, asid);
return asid;
}
@@ -215,17 +214,20 @@ static int check_gru_resources(struct gru_state *gru, int cbr_au_count,
* TLB manangment requires tracking all GRU chiplets that have loaded a GSEG
* context.
*/
-static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms,
- int ctxnum)
+static int gru_load_mm_tracker(struct gru_state *gru,
+ struct gru_thread_state *gts)
{
+ struct gru_mm_struct *gms = gts->ts_gms;
struct gru_mm_tracker *asids = &gms->ms_asids[gru->gs_gid];
- unsigned short ctxbitmap = (1 << ctxnum);
+ unsigned short ctxbitmap = (1 << gts->ts_ctxnum);
int asid;
spin_lock(&gms->ms_asid_lock);
asid = asids->mt_asid;
- if (asid == 0 || asids->mt_asid_gen != gru->gs_asid_gen) {
+ spin_lock(&gru->gs_asid_lock);
+ if (asid == 0 || (asids->mt_ctxbitmap == 0 && asids->mt_asid_gen !=
+ gru->gs_asid_gen)) {
asid = gru_assign_asid(gru);
asids->mt_asid = asid;
asids->mt_asid_gen = gru->gs_asid_gen;
@@ -233,6 +235,7 @@ static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms,
} else {
STAT(asid_reuse);
}
+ spin_unlock(&gru->gs_asid_lock);
BUG_ON(asids->mt_ctxbitmap & ctxbitmap);
asids->mt_ctxbitmap |= ctxbitmap;
@@ -241,24 +244,28 @@ static int gru_load_mm_tracker(struct gru_state *gru, struct gru_mm_struct *gms,
spin_unlock(&gms->ms_asid_lock);
gru_dbg(grudev,
- "gru %x, gms %p, ctxnum 0x%d, asid 0x%x, asidmap 0x%lx\n",
- gru->gs_gid, gms, ctxnum, asid, gms->ms_asidmap[0]);
+ "gid %d, gts %p, gms %p, ctxnum %d, asid 0x%x, asidmap 0x%lx\n",
+ gru->gs_gid, gts, gms, gts->ts_ctxnum, asid,
+ gms->ms_asidmap[0]);
return asid;
}
static void gru_unload_mm_tracker(struct gru_state *gru,
- struct gru_mm_struct *gms, int ctxnum)
+ struct gru_thread_state *gts)
{
+ struct gru_mm_struct *gms = gts->ts_gms;
struct gru_mm_tracker *asids;
unsigned short ctxbitmap;
asids = &gms->ms_asids[gru->gs_gid];
- ctxbitmap = (1 << ctxnum);
+ ctxbitmap = (1 << gts->ts_ctxnum);
spin_lock(&gms->ms_asid_lock);
+ spin_lock(&gru->gs_asid_lock);
BUG_ON((asids->mt_ctxbitmap & ctxbitmap) != ctxbitmap);
asids->mt_ctxbitmap ^= ctxbitmap;
- gru_dbg(grudev, "gru %x, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
- gru->gs_gid, gms, ctxnum, gms->ms_asidmap[0]);
+ gru_dbg(grudev, "gid %d, gts %p, gms %p, ctxnum 0x%d, asidmap 0x%lx\n",
+ gru->gs_gid, gts, gms, gts->ts_ctxnum, gms->ms_asidmap[0]);
+ spin_unlock(&gru->gs_asid_lock);
spin_unlock(&gms->ms_asid_lock);
}
@@ -319,6 +326,7 @@ static struct gru_thread_state *gru_alloc_gts(struct vm_area_struct *vma,
gts->ts_vma = vma;
gts->ts_tlb_int_select = -1;
gts->ts_gms = gru_register_mmu_notifier();
+ gts->ts_sizeavail = GRU_SIZEAVAIL(PAGE_SHIFT);
if (!gts->ts_gms)
goto err;
@@ -399,7 +407,7 @@ static void gru_free_gru_context(struct gru_thread_state *gts)
struct gru_state *gru;
gru = gts->ts_gru;
- gru_dbg(grudev, "gts %p, gru %p\n", gts, gru);
+ gru_dbg(grudev, "gts %p, gid %d\n", gts, gru->gs_gid);
spin_lock(&gru->gs_lock);
gru->gs_gts[gts->ts_ctxnum] = NULL;
@@ -408,6 +416,7 @@ static void gru_free_gru_context(struct gru_thread_state *gts)
__clear_bit(gts->ts_ctxnum, &gru->gs_context_map);
gts->ts_ctxnum = NULLCTX;
gts->ts_gru = NULL;
+ gts->ts_blade = -1;
spin_unlock(&gru->gs_lock);
gts_drop(gts);
@@ -432,8 +441,8 @@ static inline long gru_copy_handle(void *d, void *s)
return GRU_HANDLE_BYTES;
}
-static void gru_prefetch_context(void *gseg, void *cb, void *cbe, unsigned long cbrmap,
- unsigned long length)
+static void gru_prefetch_context(void *gseg, void *cb, void *cbe,
+ unsigned long cbrmap, unsigned long length)
{
int i, scr;
@@ -500,12 +509,12 @@ void gru_unload_context(struct gru_thread_state *gts, int savestate)
zap_vma_ptes(gts->ts_vma, UGRUADDR(gts), GRU_GSEG_PAGESIZE);
cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
+ gru_dbg(grudev, "gts %p\n", gts);
lock_cch_handle(cch);
if (cch_interrupt_sync(cch))
BUG();
- gru_dbg(grudev, "gts %p\n", gts);
- gru_unload_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum);
+ gru_unload_mm_tracker(gru, gts);
if (savestate)
gru_unload_context_data(gts->ts_gdata, gru->gs_gru_base_vaddr,
ctxnum, gts->ts_cbr_map,
@@ -534,7 +543,7 @@ static void gru_load_context(struct gru_thread_state *gts)
cch = get_cch(gru->gs_gru_base_vaddr, ctxnum);
lock_cch_handle(cch);
- asid = gru_load_mm_tracker(gru, gts->ts_gms, gts->ts_ctxnum);
+ asid = gru_load_mm_tracker(gru, gts);
cch->tfm_fault_bit_enable =
(gts->ts_user_options == GRU_OPT_MISS_FMM_POLL
|| gts->ts_user_options == GRU_OPT_MISS_FMM_INTR);
@@ -544,7 +553,8 @@ static void gru_load_context(struct gru_thread_state *gts)
cch->tlb_int_select = gts->ts_tlb_int_select;
}
cch->tfm_done_bit_enable = 0;
- err = cch_allocate(cch, asid, gts->ts_cbr_map, gts->ts_dsr_map);
+ err = cch_allocate(cch, asid, gts->ts_sizeavail, gts->ts_cbr_map,
+ gts->ts_dsr_map);
if (err) {
gru_dbg(grudev,
"err %d: cch %p, gts %p, cbr 0x%lx, dsr 0x%lx\n",
@@ -565,11 +575,12 @@ static void gru_load_context(struct gru_thread_state *gts)
/*
* Update fields in an active CCH:
* - retarget interrupts on local blade
+ * - update sizeavail mask
* - force a delayed context unload by clearing the CCH asids. This
* forces TLB misses for new GRU instructions. The context is unloaded
* when the next TLB miss occurs.
*/
-static int gru_update_cch(struct gru_thread_state *gts, int int_select)
+int gru_update_cch(struct gru_thread_state *gts, int force_unload)
{
struct gru_context_configuration_handle *cch;
struct gru_state *gru = gts->ts_gru;
@@ -583,9 +594,11 @@ static int gru_update_cch(struct gru_thread_state *gts, int int_select)
goto exit;
if (cch_interrupt(cch))
BUG();
- if (int_select >= 0) {
- gts->ts_tlb_int_select = int_select;
- cch->tlb_int_select = int_select;
+ if (!force_unload) {
+ for (i = 0; i < 8; i++)
+ cch->sizeavail[i] = gts->ts_sizeavail;
+ gts->ts_tlb_int_select = gru_cpu_fault_map_id();
+ cch->tlb_int_select = gru_cpu_fault_map_id();
} else {
for (i = 0; i < 8; i++)
cch->asid[i] = 0;
@@ -617,7 +630,7 @@ static int gru_retarget_intr(struct gru_thread_state *gts)
gru_dbg(grudev, "retarget from %d to %d\n", gts->ts_tlb_int_select,
gru_cpu_fault_map_id());
- return gru_update_cch(gts, gru_cpu_fault_map_id());
+ return gru_update_cch(gts, 0);
}
@@ -688,7 +701,7 @@ static void gru_steal_context(struct gru_thread_state *gts)
STAT(steal_context_failed);
}
gru_dbg(grudev,
- "stole gru %x, ctxnum %d from gts %p. Need cb %d, ds %d;"
+ "stole gid %d, ctxnum %d from gts %p. Need cb %d, ds %d;"
" avail cb %ld, ds %ld\n",
gru->gs_gid, ctxnum, ngts, cbr, dsr, hweight64(gru->gs_cbr_map),
hweight64(gru->gs_dsr_map));
@@ -727,6 +740,7 @@ again:
}
reserve_gru_resources(gru, gts);
gts->ts_gru = gru;
+ gts->ts_blade = gru->gs_blade_id;
gts->ts_ctxnum =
find_first_zero_bit(&gru->gs_context_map, GRU_NUM_CCH);
BUG_ON(gts->ts_ctxnum == GRU_NUM_CCH);
@@ -737,7 +751,7 @@ again:
STAT(assign_context);
gru_dbg(grudev,
- "gseg %p, gts %p, gru %x, ctx %d, cbr %d, dsr %d\n",
+ "gseg %p, gts %p, gid %d, ctx %d, cbr %d, dsr %d\n",
gseg_virtual_address(gts->ts_gru, gts->ts_ctxnum), gts,
gts->ts_gru->gs_gid, gts->ts_ctxnum,
gts->ts_cbr_au_count, gts->ts_dsr_au_count);
@@ -773,8 +787,8 @@ int gru_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
again:
- preempt_disable();
mutex_lock(&gts->ts_ctxlock);
+ preempt_disable();
if (gts->ts_gru) {
if (gts->ts_gru->gs_blade_id != uv_numa_blade_id()) {
STAT(migrated_nopfn_unload);
diff --git a/drivers/misc/sgi-gru/gruprocfs.c b/drivers/misc/sgi-gru/gruprocfs.c
index 73b0ca061bb..ee74821b171 100644
--- a/drivers/misc/sgi-gru/gruprocfs.c
+++ b/drivers/misc/sgi-gru/gruprocfs.c
@@ -62,7 +62,9 @@ static int statistics_show(struct seq_file *s, void *p)
printstat(s, asid_wrap);
printstat(s, asid_reuse);
printstat(s, intr);
+ printstat(s, intr_mm_lock_failed);
printstat(s, call_os);
+ printstat(s, call_os_offnode_reference);
printstat(s, call_os_check_for_bug);
printstat(s, call_os_wait_queue);
printstat(s, user_flush_tlb);
@@ -120,6 +122,30 @@ static ssize_t statistics_write(struct file *file, const char __user *userbuf,
return count;
}
+static int mcs_statistics_show(struct seq_file *s, void *p)
+{
+ int op;
+ unsigned long total, count, max;
+ static char *id[] = {"cch_allocate", "cch_start", "cch_interrupt",
+ "cch_interrupt_sync", "cch_deallocate", "tgh_invalidate"};
+
+ for (op = 0; op < mcsop_last; op++) {
+ count = atomic_long_read(&mcs_op_statistics[op].count);
+ total = atomic_long_read(&mcs_op_statistics[op].total);
+ max = mcs_op_statistics[op].max;
+ seq_printf(s, "%-20s%12ld%12ld%12ld\n", id[op], count,
+ count ? total / count : 0, max);
+ }
+ return 0;
+}
+
+static ssize_t mcs_statistics_write(struct file *file,
+ const char __user *userbuf, size_t count, loff_t *data)
+{
+ memset(mcs_op_statistics, 0, sizeof(mcs_op_statistics));
+ return count;
+}
+
static int options_show(struct seq_file *s, void *p)
{
seq_printf(s, "0x%lx\n", gru_options);
@@ -135,6 +161,7 @@ static ssize_t options_write(struct file *file, const char __user *userbuf,
if (copy_from_user
(buf, userbuf, count < sizeof(buf) ? count : sizeof(buf)))
return -EFAULT;
+ buf[count - 1] = '\0';
if (!strict_strtoul(buf, 10, &val))
gru_options = val;
@@ -199,7 +226,7 @@ static void seq_stop(struct seq_file *file, void *data)
static void *seq_start(struct seq_file *file, loff_t *gid)
{
- if (*gid < GRU_MAX_GRUS)
+ if (*gid < gru_max_gids)
return gid;
return NULL;
}
@@ -207,7 +234,7 @@ static void *seq_start(struct seq_file *file, loff_t *gid)
static void *seq_next(struct seq_file *file, void *data, loff_t *gid)
{
(*gid)++;
- if (*gid < GRU_MAX_GRUS)
+ if (*gid < gru_max_gids)
return gid;
return NULL;
}
@@ -231,6 +258,11 @@ static int statistics_open(struct inode *inode, struct file *file)
return single_open(file, statistics_show, NULL);
}
+static int mcs_statistics_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, mcs_statistics_show, NULL);
+}
+
static int options_open(struct inode *inode, struct file *file)
{
return single_open(file, options_show, NULL);
@@ -255,6 +287,14 @@ static const struct file_operations statistics_fops = {
.release = single_release,
};
+static const struct file_operations mcs_statistics_fops = {
+ .open = mcs_statistics_open,
+ .read = seq_read,
+ .write = mcs_statistics_write,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static const struct file_operations options_fops = {
.open = options_open,
.read = seq_read,
@@ -283,6 +323,7 @@ static struct proc_entry {
struct proc_dir_entry *entry;
} proc_files[] = {
{"statistics", 0644, &statistics_fops},
+ {"mcs_statistics", 0644, &mcs_statistics_fops},
{"debug_options", 0644, &options_fops},
{"cch_status", 0444, &cch_fops},
{"gru_status", 0444, &gru_fops},
diff --git a/drivers/misc/sgi-gru/grutables.h b/drivers/misc/sgi-gru/grutables.h
index a78f70deeb5..bf1eeb7553e 100644
--- a/drivers/misc/sgi-gru/grutables.h
+++ b/drivers/misc/sgi-gru/grutables.h
@@ -153,6 +153,7 @@
extern struct gru_stats_s gru_stats;
extern struct gru_blade_state *gru_base[];
extern unsigned long gru_start_paddr, gru_end_paddr;
+extern unsigned int gru_max_gids;
#define GRU_MAX_BLADES MAX_NUMNODES
#define GRU_MAX_GRUS (GRU_MAX_BLADES * GRU_CHIPLETS_PER_BLADE)
@@ -184,7 +185,9 @@ struct gru_stats_s {
atomic_long_t asid_wrap;
atomic_long_t asid_reuse;
atomic_long_t intr;
+ atomic_long_t intr_mm_lock_failed;
atomic_long_t call_os;
+ atomic_long_t call_os_offnode_reference;
atomic_long_t call_os_check_for_bug;
atomic_long_t call_os_wait_queue;
atomic_long_t user_flush_tlb;
@@ -237,6 +240,17 @@ struct gru_stats_s {
};
+enum mcs_op {cchop_allocate, cchop_start, cchop_interrupt, cchop_interrupt_sync,
+ cchop_deallocate, tghop_invalidate, mcsop_last};
+
+struct mcs_op_statistic {
+ atomic_long_t count;
+ atomic_long_t total;
+ unsigned long max;
+};
+
+extern struct mcs_op_statistic mcs_op_statistics[mcsop_last];
+
#define OPT_DPRINT 1
#define OPT_STATS 2
#define GRU_QUICKLOOK 4
@@ -278,13 +292,12 @@ struct gru_stats_s {
/* Generate a GRU asid value from a GRU base asid & a virtual address. */
#if defined CONFIG_IA64
#define VADDR_HI_BIT 64
-#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
#elif defined CONFIG_X86_64
#define VADDR_HI_BIT 48
-#define GRUREGION(addr) (0) /* ZZZ could do better */
#else
#error "Unsupported architecture"
#endif
+#define GRUREGION(addr) ((addr) >> (VADDR_HI_BIT - 3) & 3)
#define GRUASID(asid, addr) ((asid) + GRUREGION(addr))
/*------------------------------------------------------------------------------
@@ -297,12 +310,12 @@ struct gru_state;
* This structure is pointed to from the mmstruct via the notifier pointer.
* There is one of these per address space.
*/
-struct gru_mm_tracker {
- unsigned int mt_asid_gen; /* ASID wrap count */
- int mt_asid; /* current base ASID for gru */
- unsigned short mt_ctxbitmap; /* bitmap of contexts using
+struct gru_mm_tracker { /* pack to reduce size */
+ unsigned int mt_asid_gen:24; /* ASID wrap count */
+ unsigned int mt_asid:24; /* current base ASID for gru */
+ unsigned short mt_ctxbitmap:16;/* bitmap of contexts using
asid */
-};
+} __attribute__ ((packed));
struct gru_mm_struct {
struct mmu_notifier ms_notifier;
@@ -348,6 +361,7 @@ struct gru_thread_state {
long ts_user_options;/* misc user option flags */
pid_t ts_tgid_owner; /* task that is using the
context - for migration */
+ unsigned short ts_sizeavail; /* Pagesizes in use */
int ts_tsid; /* thread that owns the
structure */
int ts_tlb_int_select;/* target cpu if interrupts
@@ -359,6 +373,9 @@ struct gru_thread_state {
required for contest */
unsigned char ts_cbr_au_count;/* Number of CBR resources
required for contest */
+ char ts_blade; /* If >= 0, migrate context if
+ ref from diferent blade */
+ char ts_force_cch_reload;
char ts_force_unload;/* force context to be unloaded
after migration */
char ts_cbr_idx[GRU_CBR_AU];/* CBR numbers of each
@@ -392,12 +409,12 @@ struct gru_state {
gru segments (64) */
void *gs_gru_base_vaddr; /* Virtual address of
gru segments (64) */
- unsigned char gs_gid; /* unique GRU number */
+ unsigned short gs_gid; /* unique GRU number */
+ unsigned short gs_blade_id; /* blade of GRU */
unsigned char gs_tgh_local_shift; /* used to pick TGH for
local flush */
unsigned char gs_tgh_first_remote; /* starting TGH# for
remote flush */
- unsigned short gs_blade_id; /* blade of GRU */
spinlock_t gs_asid_lock; /* lock used for
assigning asids */
spinlock_t gs_lock; /* lock used for
@@ -492,6 +509,10 @@ struct gru_blade_state {
(i) < GRU_CHIPLETS_PER_BLADE; \
(i)++, (gru)++)
+/* Scan all GRUs */
+#define foreach_gid(gid) \
+ for ((gid) = 0; (gid) < gru_max_gids; (gid)++)
+
/* Scan all active GTSs on a gru. Note: must hold ss_lock to use this macro. */
#define for_each_gts_on_gru(gts, gru, ctxnum) \
for ((ctxnum) = 0; (ctxnum) < GRU_NUM_CCH; (ctxnum)++) \
@@ -578,9 +599,11 @@ extern struct gru_thread_state *gru_find_thread_state(struct vm_area_struct
extern struct gru_thread_state *gru_alloc_thread_state(struct vm_area_struct
*vma, int tsid);
extern void gru_unload_context(struct gru_thread_state *gts, int savestate);
+extern int gru_update_cch(struct gru_thread_state *gts, int force_unload);
extern void gts_drop(struct gru_thread_state *gts);
extern void gru_tgh_flush_init(struct gru_state *gru);
extern int gru_kservices_init(struct gru_state *gru);
+extern void gru_kservices_exit(struct gru_state *gru);
extern irqreturn_t gru_intr(int irq, void *dev_id);
extern int gru_handle_user_call_os(unsigned long address);
extern int gru_user_flush_tlb(unsigned long arg);
diff --git a/drivers/misc/sgi-gru/grutlbpurge.c b/drivers/misc/sgi-gru/grutlbpurge.c
index c84496a7769..1d125091f5e 100644
--- a/drivers/misc/sgi-gru/grutlbpurge.c
+++ b/drivers/misc/sgi-gru/grutlbpurge.c
@@ -187,7 +187,7 @@ void gru_flush_tlb_range(struct gru_mm_struct *gms, unsigned long start,
" FLUSH gruid %d, asid 0x%x, num %ld, cbmap 0x%x\n",
gid, asid, num, asids->mt_ctxbitmap);
tgh = get_lock_tgh_handle(gru);
- tgh_invalidate(tgh, start, 0, asid, grupagesize, 0,
+ tgh_invalidate(tgh, start, ~0, asid, grupagesize, 0,
num - 1, asids->mt_ctxbitmap);
get_unlock_tgh_handle(tgh);
} else {
@@ -210,11 +210,10 @@ void gru_flush_all_tlb(struct gru_state *gru)
{
struct gru_tlb_global_handle *tgh;
- gru_dbg(grudev, "gru %p, gid %d\n", gru, gru->gs_gid);
+ gru_dbg(grudev, "gid %d\n", gru->gs_gid);
tgh = get_lock_tgh_handle(gru);
- tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0);
+ tgh_invalidate(tgh, 0, ~0, 0, 1, 1, GRUMAXINVAL - 1, 0xffff);
get_unlock_tgh_handle(tgh);
- preempt_enable();
}
/*
diff --git a/drivers/misc/sgi-xp/xpc.h b/drivers/misc/sgi-xp/xpc.h
index 275b78896a7..114444cfd49 100644
--- a/drivers/misc/sgi-xp/xpc.h
+++ b/drivers/misc/sgi-xp/xpc.h
@@ -92,7 +92,9 @@ struct xpc_rsvd_page {
u8 pad1[3]; /* align to next u64 in 1st 64-byte cacheline */
union {
unsigned long vars_pa; /* phys address of struct xpc_vars */
- unsigned long activate_mq_gpa; /* gru phy addr of activate_mq */
+ unsigned long activate_gru_mq_desc_gpa; /* phys addr of */
+ /* activate mq's */
+ /* gru mq descriptor */
} sn;
unsigned long ts_jiffies; /* timestamp when rsvd pg was setup by XPC */
u64 pad2[10]; /* align to last u64 in 2nd 64-byte cacheline */
@@ -189,7 +191,9 @@ struct xpc_gru_mq_uv {
int irq; /* irq raised when message is received in mq */
int mmr_blade; /* blade where watchlist was allocated from */
unsigned long mmr_offset; /* offset of irq mmr located on mmr_blade */
+ unsigned long mmr_value; /* value of irq mmr located on mmr_blade */
int watchlist_num; /* number of watchlist allocatd by BIOS */
+ void *gru_mq_desc; /* opaque structure used by the GRU driver */
};
/*
@@ -197,6 +201,7 @@ struct xpc_gru_mq_uv {
* heartbeat, partition active state, and channel state. This is UV only.
*/
struct xpc_activate_mq_msghdr_uv {
+ unsigned int gru_msg_hdr; /* FOR GRU INTERNAL USE ONLY */
short partid; /* sender's partid */
u8 act_state; /* sender's act_state at time msg sent */
u8 type; /* message's type */
@@ -232,7 +237,7 @@ struct xpc_activate_mq_msg_heartbeat_req_uv {
struct xpc_activate_mq_msg_activate_req_uv {
struct xpc_activate_mq_msghdr_uv hdr;
unsigned long rp_gpa;
- unsigned long activate_mq_gpa;
+ unsigned long activate_gru_mq_desc_gpa;
};
struct xpc_activate_mq_msg_deactivate_req_uv {
@@ -263,7 +268,7 @@ struct xpc_activate_mq_msg_chctl_openreply_uv {
short ch_number;
short remote_nentries; /* ??? Is this needed? What is? */
short local_nentries; /* ??? Is this needed? What is? */
- unsigned long local_notify_mq_gpa;
+ unsigned long notify_gru_mq_desc_gpa;
};
/*
@@ -510,8 +515,8 @@ struct xpc_channel_sn2 {
};
struct xpc_channel_uv {
- unsigned long remote_notify_mq_gpa; /* gru phys address of remote */
- /* partition's notify mq */
+ void *cached_notify_gru_mq_desc; /* remote partition's notify mq's */
+ /* gru mq descriptor */
struct xpc_send_msg_slot_uv *send_msg_slots;
void *recv_msg_slots; /* each slot will hold a xpc_notify_mq_msg_uv */
@@ -682,8 +687,12 @@ struct xpc_partition_sn2 {
};
struct xpc_partition_uv {
- unsigned long remote_activate_mq_gpa; /* gru phys address of remote */
- /* partition's activate mq */
+ unsigned long activate_gru_mq_desc_gpa; /* phys addr of parititon's */
+ /* activate mq's gru mq */
+ /* descriptor */
+ void *cached_activate_gru_mq_desc; /* cached copy of partition's */
+ /* activate mq's gru mq descriptor */
+ struct mutex cached_activate_gru_mq_desc_mutex;
spinlock_t flags_lock; /* protect updating of flags */
unsigned int flags; /* general flags */
u8 remote_act_state; /* remote partition's act_state */
@@ -694,8 +703,9 @@ struct xpc_partition_uv {
/* struct xpc_partition_uv flags */
-#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001
-#define XPC_P_ENGAGED_UV 0x00000002
+#define XPC_P_HEARTBEAT_OFFLINE_UV 0x00000001
+#define XPC_P_ENGAGED_UV 0x00000002
+#define XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV 0x00000004
/* struct xpc_partition_uv act_state change requests */
@@ -804,6 +814,7 @@ extern void xpc_activate_kthreads(struct xpc_channel *, int);
extern void xpc_create_kthreads(struct xpc_channel *, int, int);
extern void xpc_disconnect_wait(int);
extern int (*xpc_setup_partitions_sn) (void);
+extern void (*xpc_teardown_partitions_sn) (void);
extern enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *, u64 *,
unsigned long *,
size_t *);
@@ -846,8 +857,8 @@ extern void (*xpc_send_chctl_openrequest) (struct xpc_channel *,
unsigned long *);
extern void (*xpc_send_chctl_openreply) (struct xpc_channel *, unsigned long *);
-extern void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
- unsigned long);
+extern enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *,
+ unsigned long);
extern enum xp_retval (*xpc_send_payload) (struct xpc_channel *, u32, void *,
u16, u8, xpc_notify_func, void *);
diff --git a/drivers/misc/sgi-xp/xpc_channel.c b/drivers/misc/sgi-xp/xpc_channel.c
index 45fd653dbe3..99a2534c38a 100644
--- a/drivers/misc/sgi-xp/xpc_channel.c
+++ b/drivers/misc/sgi-xp/xpc_channel.c
@@ -183,6 +183,7 @@ xpc_process_openclose_chctl_flags(struct xpc_partition *part, int ch_number,
&part->remote_openclose_args[ch_number];
struct xpc_channel *ch = &part->channels[ch_number];
enum xp_retval reason;
+ enum xp_retval ret;
spin_lock_irqsave(&ch->lock, irq_flags);
@@ -399,8 +400,13 @@ again:
DBUG_ON(args->local_nentries == 0);
DBUG_ON(args->remote_nentries == 0);
+ ret = xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
+ if (ret != xpSuccess) {
+ XPC_DISCONNECT_CHANNEL(ch, ret, &irq_flags);
+ spin_unlock_irqrestore(&ch->lock, irq_flags);
+ return;
+ }
ch->flags |= XPC_C_ROPENREPLY;
- xpc_save_remote_msgqueue_pa(ch, args->local_msgqueue_pa);
if (args->local_nentries < ch->remote_nentries) {
dev_dbg(xpc_chan, "XPC_CHCTL_OPENREPLY: new "
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 6576170de96..1ab9fda87fa 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -171,6 +171,7 @@ static struct notifier_block xpc_die_notifier = {
};
int (*xpc_setup_partitions_sn) (void);
+void (*xpc_teardown_partitions_sn) (void);
enum xp_retval (*xpc_get_partition_rsvd_page_pa) (void *buf, u64 *cookie,
unsigned long *rp_pa,
size_t *len);
@@ -217,8 +218,8 @@ void (*xpc_send_chctl_openrequest) (struct xpc_channel *ch,
void (*xpc_send_chctl_openreply) (struct xpc_channel *ch,
unsigned long *irq_flags);
-void (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
- unsigned long msgqueue_pa);
+enum xp_retval (*xpc_save_remote_msgqueue_pa) (struct xpc_channel *ch,
+ unsigned long msgqueue_pa);
enum xp_retval (*xpc_send_payload) (struct xpc_channel *ch, u32 flags,
void *payload, u16 payload_size,
@@ -998,6 +999,7 @@ xpc_setup_partitions(void)
static void
xpc_teardown_partitions(void)
{
+ xpc_teardown_partitions_sn();
kfree(xpc_partitions);
}
diff --git a/drivers/misc/sgi-xp/xpc_sn2.c b/drivers/misc/sgi-xp/xpc_sn2.c
index 2e975762c32..eaaa964942d 100644
--- a/drivers/misc/sgi-xp/xpc_sn2.c
+++ b/drivers/misc/sgi-xp/xpc_sn2.c
@@ -66,6 +66,12 @@ xpc_setup_partitions_sn_sn2(void)
return 0;
}
+static void
+xpc_teardown_partitions_sn_sn2(void)
+{
+ /* nothing needs to be done */
+}
+
/* SH_IPI_ACCESS shub register value on startup */
static u64 xpc_sh1_IPI_access_sn2;
static u64 xpc_sh2_IPI_access0_sn2;
@@ -436,11 +442,12 @@ xpc_send_chctl_local_msgrequest_sn2(struct xpc_channel *ch)
XPC_SEND_LOCAL_NOTIFY_IRQ_SN2(ch, XPC_CHCTL_MSGREQUEST);
}
-static void
+static enum xp_retval
xpc_save_remote_msgqueue_pa_sn2(struct xpc_channel *ch,
unsigned long msgqueue_pa)
{
ch->sn.sn2.remote_msgqueue_pa = msgqueue_pa;
+ return xpSuccess;
}
/*
@@ -1737,20 +1744,20 @@ xpc_clear_remote_msgqueue_flags_sn2(struct xpc_channel *ch)
{
struct xpc_channel_sn2 *ch_sn2 = &ch->sn.sn2;
struct xpc_msg_sn2 *msg;
- s64 put;
+ s64 put, remote_nentries = ch->remote_nentries;
/* flags are zeroed when the buffer is allocated */
- if (ch_sn2->remote_GP.put < ch->remote_nentries)
+ if (ch_sn2->remote_GP.put < remote_nentries)
return;
- put = max(ch_sn2->w_remote_GP.put, ch->remote_nentries);
+ put = max(ch_sn2->w_remote_GP.put, remote_nentries);
do {
msg = (struct xpc_msg_sn2 *)((u64)ch_sn2->remote_msgqueue +
- (put % ch->remote_nentries) *
+ (put % remote_nentries) *
ch->entry_size);
DBUG_ON(!(msg->flags & XPC_M_SN2_READY));
DBUG_ON(!(msg->flags & XPC_M_SN2_DONE));
- DBUG_ON(msg->number != put - ch->remote_nentries);
+ DBUG_ON(msg->number != put - remote_nentries);
msg->flags = 0;
} while (++put < ch_sn2->remote_GP.put);
}
@@ -2315,6 +2322,7 @@ xpc_init_sn2(void)
size_t buf_size;
xpc_setup_partitions_sn = xpc_setup_partitions_sn_sn2;
+ xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_sn2;
xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_sn2;
xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_sn2;
xpc_increment_heartbeat = xpc_increment_heartbeat_sn2;
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c
index 29c0502a96b..f7fff4727ed 100644
--- a/drivers/misc/sgi-xp/xpc_uv.c
+++ b/drivers/misc/sgi-xp/xpc_uv.c
@@ -31,6 +31,21 @@
#include "../sgi-gru/grukservices.h"
#include "xpc.h"
+#if defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
+struct uv_IO_APIC_route_entry {
+ __u64 vector : 8,
+ delivery_mode : 3,
+ dest_mode : 1,
+ delivery_status : 1,
+ polarity : 1,
+ __reserved_1 : 1,
+ trigger : 1,
+ mask : 1,
+ __reserved_2 : 15,
+ dest : 32;
+};
+#endif
+
static atomic64_t xpc_heartbeat_uv;
static DECLARE_BITMAP(xpc_heartbeating_to_mask_uv, XP_MAX_NPARTITIONS_UV);
@@ -56,26 +71,52 @@ xpc_setup_partitions_sn_uv(void)
for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
part_uv = &xpc_partitions[partid].sn.uv;
+ mutex_init(&part_uv->cached_activate_gru_mq_desc_mutex);
spin_lock_init(&part_uv->flags_lock);
part_uv->remote_act_state = XPC_P_AS_INACTIVE;
}
return 0;
}
+static void
+xpc_teardown_partitions_sn_uv(void)
+{
+ short partid;
+ struct xpc_partition_uv *part_uv;
+ unsigned long irq_flags;
+
+ for (partid = 0; partid < XP_MAX_NPARTITIONS_UV; partid++) {
+ part_uv = &xpc_partitions[partid].sn.uv;
+
+ if (part_uv->cached_activate_gru_mq_desc != NULL) {
+ mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
+ spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+ part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+ spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+ kfree(part_uv->cached_activate_gru_mq_desc);
+ part_uv->cached_activate_gru_mq_desc = NULL;
+ mutex_unlock(&part_uv->
+ cached_activate_gru_mq_desc_mutex);
+ }
+ }
+}
+
static int
xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
{
+ int mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
+
#if defined CONFIG_X86_64
mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset);
if (mq->irq < 0) {
dev_err(xpc_part, "uv_setup_irq() returned error=%d\n",
- mq->irq);
+ -mq->irq);
+ return mq->irq;
}
-#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- int mmr_pnode;
- unsigned long mmr_value;
+ mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset);
+#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
if (strcmp(irq_name, XPC_ACTIVATE_IRQ_NAME) == 0)
mq->irq = SGI_XPC_ACTIVATE;
else if (strcmp(irq_name, XPC_NOTIFY_IRQ_NAME) == 0)
@@ -83,10 +124,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name)
else
return -EINVAL;
- mmr_pnode = uv_blade_to_pnode(mq->mmr_blade);
- mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
-
- uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mmr_value);
+ mq->mmr_value = (unsigned long)cpu_physical_id(cpu) << 32 | mq->irq;
+ uv_write_global_mmr64(mmr_pnode, mq->mmr_offset, mq->mmr_value);
#else
#error not a supported configuration
#endif
@@ -127,7 +166,7 @@ xpc_gru_mq_watchlist_alloc_uv(struct xpc_gru_mq_uv *mq)
return ret;
}
#elif defined CONFIG_IA64_GENERIC || defined CONFIG_IA64_SGI_UV
- ret = sn_mq_watchlist_alloc(mq->mmr_blade, uv_gpa(mq->address),
+ ret = sn_mq_watchlist_alloc(mq->mmr_blade, (void *)uv_gpa(mq->address),
mq->order, &mq->mmr_offset);
if (ret < 0) {
dev_err(xpc_part, "sn_mq_watchlist_alloc() failed, ret=%d\n",
@@ -168,12 +207,22 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
int pg_order;
struct page *page;
struct xpc_gru_mq_uv *mq;
+ struct uv_IO_APIC_route_entry *mmr_value;
mq = kmalloc(sizeof(struct xpc_gru_mq_uv), GFP_KERNEL);
if (mq == NULL) {
dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
"a xpc_gru_mq_uv structure\n");
ret = -ENOMEM;
+ goto out_0;
+ }
+
+ mq->gru_mq_desc = kzalloc(sizeof(struct gru_message_queue_desc),
+ GFP_KERNEL);
+ if (mq->gru_mq_desc == NULL) {
+ dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to kmalloc() "
+ "a gru_message_queue_desc structure\n");
+ ret = -ENOMEM;
goto out_1;
}
@@ -194,14 +243,6 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
}
mq->address = page_address(page);
- ret = gru_create_message_queue(mq->address, mq_size);
- if (ret != 0) {
- dev_err(xpc_part, "gru_create_message_queue() returned "
- "error=%d\n", ret);
- ret = -EINVAL;
- goto out_3;
- }
-
/* enable generation of irq when GRU mq operation occurs to this mq */
ret = xpc_gru_mq_watchlist_alloc_uv(mq);
if (ret != 0)
@@ -214,10 +255,20 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name,
ret = request_irq(mq->irq, irq_handler, 0, irq_name, NULL);
if (ret != 0) {
dev_err(xpc_part, "request_irq(irq=%d) returned error=%d\n",
- mq->irq, ret);
+ mq->irq, -ret);
goto out_5;
}
+ mmr_value = (struct uv_IO_APIC_route_entry *)&mq->mmr_value;
+ ret = gru_create_message_queue(mq->gru_mq_desc, mq->address, mq_size,
+ nid, mmr_value->vector, mmr_value->dest);
+ if (ret != 0) {
+ dev_err(xpc_part, "gru_create_message_queue() returned "
+ "error=%d\n", ret);
+ ret = -EINVAL;
+ goto out_6;
+ }
+
/* allow other partitions to access this GRU mq */
xp_ret = xp_expand_memprotect(xp_pa(mq->address), mq_size);
if (xp_ret != xpSuccess) {
@@ -237,8 +288,10 @@ out_4:
out_3:
free_pages((unsigned long)mq->address, pg_order);
out_2:
- kfree(mq);
+ kfree(mq->gru_mq_desc);
out_1:
+ kfree(mq);
+out_0:
return ERR_PTR(ret);
}
@@ -268,13 +321,14 @@ xpc_destroy_gru_mq_uv(struct xpc_gru_mq_uv *mq)
}
static enum xp_retval
-xpc_send_gru_msg(unsigned long mq_gpa, void *msg, size_t msg_size)
+xpc_send_gru_msg(struct gru_message_queue_desc *gru_mq_desc, void *msg,
+ size_t msg_size)
{
enum xp_retval xp_ret;
int ret;
while (1) {
- ret = gru_send_message_gpa(mq_gpa, msg, msg_size);
+ ret = gru_send_message_gpa(gru_mq_desc, msg, msg_size);
if (ret == MQE_OK) {
xp_ret = xpSuccess;
break;
@@ -421,7 +475,15 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
part_uv->act_state_req = XPC_P_ASR_ACTIVATE_UV;
part->remote_rp_pa = msg->rp_gpa; /* !!! _pa is _gpa */
part->remote_rp_ts_jiffies = msg_hdr->rp_ts_jiffies;
- part_uv->remote_activate_mq_gpa = msg->activate_mq_gpa;
+
+ if (msg->activate_gru_mq_desc_gpa !=
+ part_uv->activate_gru_mq_desc_gpa) {
+ spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+ part_uv->flags &= ~XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+ spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+ part_uv->activate_gru_mq_desc_gpa =
+ msg->activate_gru_mq_desc_gpa;
+ }
spin_unlock_irqrestore(&xpc_activate_IRQ_rcvd_lock, irq_flags);
(*wakeup_hb_checker)++;
@@ -498,7 +560,7 @@ xpc_handle_activate_mq_msg_uv(struct xpc_partition *part,
args = &part->remote_openclose_args[msg->ch_number];
args->remote_nentries = msg->remote_nentries;
args->local_nentries = msg->local_nentries;
- args->local_msgqueue_pa = msg->local_notify_mq_gpa;
+ args->local_msgqueue_pa = msg->notify_gru_mq_desc_gpa;
spin_lock_irqsave(&part->chctl_lock, irq_flags);
part->chctl.flags[msg->ch_number] |= XPC_CHCTL_OPENREPLY;
@@ -558,9 +620,10 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
short partid;
struct xpc_partition *part;
int wakeup_hb_checker = 0;
+ int part_referenced;
while (1) {
- msg_hdr = gru_get_next_message(xpc_activate_mq_uv->address);
+ msg_hdr = gru_get_next_message(xpc_activate_mq_uv->gru_mq_desc);
if (msg_hdr == NULL)
break;
@@ -571,14 +634,15 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
partid);
} else {
part = &xpc_partitions[partid];
- if (xpc_part_ref(part)) {
- xpc_handle_activate_mq_msg_uv(part, msg_hdr,
- &wakeup_hb_checker);
+
+ part_referenced = xpc_part_ref(part);
+ xpc_handle_activate_mq_msg_uv(part, msg_hdr,
+ &wakeup_hb_checker);
+ if (part_referenced)
xpc_part_deref(part);
- }
}
- gru_free_message(xpc_activate_mq_uv->address, msg_hdr);
+ gru_free_message(xpc_activate_mq_uv->gru_mq_desc, msg_hdr);
}
if (wakeup_hb_checker)
@@ -588,21 +652,73 @@ xpc_handle_activate_IRQ_uv(int irq, void *dev_id)
}
static enum xp_retval
+xpc_cache_remote_gru_mq_desc_uv(struct gru_message_queue_desc *gru_mq_desc,
+ unsigned long gru_mq_desc_gpa)
+{
+ enum xp_retval ret;
+
+ ret = xp_remote_memcpy(uv_gpa(gru_mq_desc), gru_mq_desc_gpa,
+ sizeof(struct gru_message_queue_desc));
+ if (ret == xpSuccess)
+ gru_mq_desc->mq = NULL;
+
+ return ret;
+}
+
+static enum xp_retval
xpc_send_activate_IRQ_uv(struct xpc_partition *part, void *msg, size_t msg_size,
int msg_type)
{
struct xpc_activate_mq_msghdr_uv *msg_hdr = msg;
+ struct xpc_partition_uv *part_uv = &part->sn.uv;
+ struct gru_message_queue_desc *gru_mq_desc;
+ unsigned long irq_flags;
+ enum xp_retval ret;
DBUG_ON(msg_size > XPC_ACTIVATE_MSG_SIZE_UV);
msg_hdr->type = msg_type;
- msg_hdr->partid = XPC_PARTID(part);
+ msg_hdr->partid = xp_partition_id;
msg_hdr->act_state = part->act_state;
msg_hdr->rp_ts_jiffies = xpc_rsvd_page->ts_jiffies;
+ mutex_lock(&part_uv->cached_activate_gru_mq_desc_mutex);
+again:
+ if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV)) {
+ gru_mq_desc = part_uv->cached_activate_gru_mq_desc;
+ if (gru_mq_desc == NULL) {
+ gru_mq_desc = kmalloc(sizeof(struct
+ gru_message_queue_desc),
+ GFP_KERNEL);
+ if (gru_mq_desc == NULL) {
+ ret = xpNoMemory;
+ goto done;
+ }
+ part_uv->cached_activate_gru_mq_desc = gru_mq_desc;
+ }
+
+ ret = xpc_cache_remote_gru_mq_desc_uv(gru_mq_desc,
+ part_uv->
+ activate_gru_mq_desc_gpa);
+ if (ret != xpSuccess)
+ goto done;
+
+ spin_lock_irqsave(&part_uv->flags_lock, irq_flags);
+ part_uv->flags |= XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV;
+ spin_unlock_irqrestore(&part_uv->flags_lock, irq_flags);
+ }
+
/* ??? Is holding a spin_lock (ch->lock) during this call a bad idea? */
- return xpc_send_gru_msg(part->sn.uv.remote_activate_mq_gpa, msg,
- msg_size);
+ ret = xpc_send_gru_msg(part_uv->cached_activate_gru_mq_desc, msg,
+ msg_size);
+ if (ret != xpSuccess) {
+ smp_rmb(); /* ensure a fresh copy of part_uv->flags */
+ if (!(part_uv->flags & XPC_P_CACHED_ACTIVATE_GRU_MQ_DESC_UV))
+ goto again;
+ }
+done:
+ mutex_unlock(&part_uv->cached_activate_gru_mq_desc_mutex);
+ return ret;
}
static void
@@ -620,7 +736,7 @@ static void
xpc_send_activate_IRQ_ch_uv(struct xpc_channel *ch, unsigned long *irq_flags,
void *msg, size_t msg_size, int msg_type)
{
- struct xpc_partition *part = &xpc_partitions[ch->number];
+ struct xpc_partition *part = &xpc_partitions[ch->partid];
enum xp_retval ret;
ret = xpc_send_activate_IRQ_uv(part, msg, msg_size, msg_type);
@@ -692,7 +808,8 @@ xpc_get_partition_rsvd_page_pa_uv(void *buf, u64 *cookie, unsigned long *rp_pa,
static int
xpc_setup_rsvd_page_sn_uv(struct xpc_rsvd_page *rp)
{
- rp->sn.activate_mq_gpa = uv_gpa(xpc_activate_mq_uv->address);
+ rp->sn.activate_gru_mq_desc_gpa =
+ uv_gpa(xpc_activate_mq_uv->gru_mq_desc);
return 0;
}
@@ -787,7 +904,8 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
part->remote_rp_pa = remote_rp_gpa; /* !!! _pa here is really _gpa */
part->remote_rp_ts_jiffies = remote_rp->ts_jiffies;
- part->sn.uv.remote_activate_mq_gpa = remote_rp->sn.activate_mq_gpa;
+ part->sn.uv.activate_gru_mq_desc_gpa =
+ remote_rp->sn.activate_gru_mq_desc_gpa;
/*
* ??? Is it a good idea to make this conditional on what is
@@ -795,7 +913,8 @@ xpc_request_partition_activation_uv(struct xpc_rsvd_page *remote_rp,
*/
if (part->sn.uv.remote_act_state == XPC_P_AS_INACTIVE) {
msg.rp_gpa = uv_gpa(xpc_rsvd_page);
- msg.activate_mq_gpa = xpc_rsvd_page->sn.activate_mq_gpa;
+ msg.activate_gru_mq_desc_gpa =
+ xpc_rsvd_page->sn.activate_gru_mq_desc_gpa;
xpc_send_activate_IRQ_part_uv(part, &msg, sizeof(msg),
XPC_ACTIVATE_MQ_MSG_ACTIVATE_REQ_UV);
}
@@ -857,7 +976,8 @@ xpc_get_fifo_entry_uv(struct xpc_fifo_head_uv *head)
if (head->first == NULL)
head->last = NULL;
}
- head->n_entries++;
+ head->n_entries--;
+ BUG_ON(head->n_entries < 0);
spin_unlock_irqrestore(&head->lock, irq_flags);
first->next = NULL;
return first;
@@ -876,8 +996,7 @@ xpc_put_fifo_entry_uv(struct xpc_fifo_head_uv *head,
else
head->first = last;
head->last = last;
- head->n_entries--;
- BUG_ON(head->n_entries < 0);
+ head->n_entries++;
spin_unlock_irqrestore(&head->lock, irq_flags);
}
@@ -1037,6 +1156,12 @@ xpc_setup_msg_structures_uv(struct xpc_channel *ch)
DBUG_ON(ch->flags & XPC_C_SETUP);
+ ch_uv->cached_notify_gru_mq_desc = kmalloc(sizeof(struct
+ gru_message_queue_desc),
+ GFP_KERNEL);
+ if (ch_uv->cached_notify_gru_mq_desc == NULL)
+ return xpNoMemory;
+
ret = xpc_allocate_send_msg_slot_uv(ch);
if (ret == xpSuccess) {
@@ -1060,7 +1185,8 @@ xpc_teardown_msg_structures_uv(struct xpc_channel *ch)
DBUG_ON(!spin_is_locked(&ch->lock));
- ch_uv->remote_notify_mq_gpa = 0;
+ kfree(ch_uv->cached_notify_gru_mq_desc);
+ ch_uv->cached_notify_gru_mq_desc = NULL;
if (ch->flags & XPC_C_SETUP) {
xpc_init_fifo_uv(&ch_uv->msg_slot_free_list);
@@ -1111,7 +1237,7 @@ xpc_send_chctl_openreply_uv(struct xpc_channel *ch, unsigned long *irq_flags)
msg.ch_number = ch->number;
msg.local_nentries = ch->local_nentries;
msg.remote_nentries = ch->remote_nentries;
- msg.local_notify_mq_gpa = uv_gpa(xpc_notify_mq_uv);
+ msg.notify_gru_mq_desc_gpa = uv_gpa(xpc_notify_mq_uv->gru_mq_desc);
xpc_send_activate_IRQ_ch_uv(ch, irq_flags, &msg, sizeof(msg),
XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV);
}
@@ -1128,11 +1254,15 @@ xpc_send_chctl_local_msgrequest_uv(struct xpc_partition *part, int ch_number)
xpc_wakeup_channel_mgr(part);
}
-static void
+static enum xp_retval
xpc_save_remote_msgqueue_pa_uv(struct xpc_channel *ch,
- unsigned long msgqueue_pa)
+ unsigned long gru_mq_desc_gpa)
{
- ch->sn.uv.remote_notify_mq_gpa = msgqueue_pa;
+ struct xpc_channel_uv *ch_uv = &ch->sn.uv;
+
+ DBUG_ON(ch_uv->cached_notify_gru_mq_desc == NULL);
+ return xpc_cache_remote_gru_mq_desc_uv(ch_uv->cached_notify_gru_mq_desc,
+ gru_mq_desc_gpa);
}
static void
@@ -1339,7 +1469,8 @@ xpc_handle_notify_IRQ_uv(int irq, void *dev_id)
short partid;
struct xpc_partition *part;
- while ((msg = gru_get_next_message(xpc_notify_mq_uv)) != NULL) {
+ while ((msg = gru_get_next_message(xpc_notify_mq_uv->gru_mq_desc)) !=
+ NULL) {
partid = msg->hdr.partid;
if (partid < 0 || partid >= XP_MAX_NPARTITIONS_UV) {
@@ -1354,7 +1485,7 @@ xpc_handle_notify_IRQ_uv(int irq, void *dev_id)
}
}
- gru_free_message(xpc_notify_mq_uv, msg);
+ gru_free_message(xpc_notify_mq_uv->gru_mq_desc, msg);
}
return IRQ_HANDLED;
@@ -1438,7 +1569,8 @@ xpc_send_payload_uv(struct xpc_channel *ch, u32 flags, void *payload,
msg->hdr.msg_slot_number = msg_slot->msg_slot_number;
memcpy(&msg->payload, payload, payload_size);
- ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg, msg_size);
+ ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
+ msg_size);
if (ret == xpSuccess)
goto out_1;
@@ -1529,7 +1661,7 @@ xpc_received_payload_uv(struct xpc_channel *ch, void *payload)
msg->hdr.partid = xp_partition_id;
msg->hdr.size = 0; /* size of zero indicates this is an ACK */
- ret = xpc_send_gru_msg(ch->sn.uv.remote_notify_mq_gpa, msg,
+ ret = xpc_send_gru_msg(ch->sn.uv.cached_notify_gru_mq_desc, msg,
sizeof(struct xpc_notify_mq_msghdr_uv));
if (ret != xpSuccess)
XPC_DEACTIVATE_PARTITION(&xpc_partitions[ch->partid], ret);
@@ -1541,6 +1673,7 @@ int
xpc_init_uv(void)
{
xpc_setup_partitions_sn = xpc_setup_partitions_sn_uv;
+ xpc_teardown_partitions_sn = xpc_teardown_partitions_sn_uv;
xpc_process_activate_IRQ_rcvd = xpc_process_activate_IRQ_rcvd_uv;
xpc_get_partition_rsvd_page_pa = xpc_get_partition_rsvd_page_pa_uv;
xpc_setup_rsvd_page_sn = xpc_setup_rsvd_page_sn_uv;
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 513eb09a638..fe8041e619e 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -41,6 +41,8 @@
#include "queue.h"
+MODULE_ALIAS("mmc:block");
+
/*
* max 8 partitions per card
*/
diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c
index 78ad48718ab..36a8d53ad2a 100644
--- a/drivers/mmc/card/sdio_uart.c
+++ b/drivers/mmc/card/sdio_uart.c
@@ -30,6 +30,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mutex.h>
+#include <linux/seq_file.h>
#include <linux/serial_reg.h>
#include <linux/circ_buf.h>
#include <linux/gfp.h>
@@ -933,67 +934,64 @@ static int sdio_uart_tiocmset(struct tty_struct *tty, struct file *file,
return result;
}
-static int sdio_uart_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int sdio_uart_proc_show(struct seq_file *m, void *v)
{
- int i, len = 0;
- off_t begin = 0;
+ int i;
- len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+ seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
"", "", "");
- for (i = 0; i < UART_NR && len < PAGE_SIZE - 96; i++) {
+ for (i = 0; i < UART_NR; i++) {
struct sdio_uart_port *port = sdio_uart_port_get(i);
if (port) {
- len += sprintf(page+len, "%d: uart:SDIO", i);
+ seq_printf(m, "%d: uart:SDIO", i);
if(capable(CAP_SYS_ADMIN)) {
- len += sprintf(page + len, " tx:%d rx:%d",
+ seq_printf(m, " tx:%d rx:%d",
port->icount.tx, port->icount.rx);
if (port->icount.frame)
- len += sprintf(page + len, " fe:%d",
+ seq_printf(m, " fe:%d",
port->icount.frame);
if (port->icount.parity)
- len += sprintf(page + len, " pe:%d",
+ seq_printf(m, " pe:%d",
port->icount.parity);
if (port->icount.brk)
- len += sprintf(page + len, " brk:%d",
+ seq_printf(m, " brk:%d",
port->icount.brk);
if (port->icount.overrun)
- len += sprintf(page + len, " oe:%d",
+ seq_printf(m, " oe:%d",
port->icount.overrun);
if (port->icount.cts)
- len += sprintf(page + len, " cts:%d",
+ seq_printf(m, " cts:%d",
port->icount.cts);
if (port->icount.dsr)
- len += sprintf(page + len, " dsr:%d",
+ seq_printf(m, " dsr:%d",
port->icount.dsr);
if (port->icount.rng)
- len += sprintf(page + len, " rng:%d",
+ seq_printf(m, " rng:%d",
port->icount.rng);
if (port->icount.dcd)
- len += sprintf(page + len, " dcd:%d",
+ seq_printf(m, " dcd:%d",
port->icount.dcd);
}
- strcat(page, "\n");
- len++;
sdio_uart_port_put(port);
- }
-
- if (len + begin > off + count)
- goto done;
- if (len + begin < off) {
- begin += len;
- len = 0;
+ seq_putc(m, '\n');
}
}
- *eof = 1;
+ return 0;
+}
-done:
- if (off >= len + begin)
- return 0;
- *start = page + (off - begin);
- return (count < begin + len - off) ? count : (begin + len - off);
+static int sdio_uart_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sdio_uart_proc_show, NULL);
}
+static const struct file_operations sdio_uart_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = sdio_uart_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static const struct tty_operations sdio_uart_ops = {
.open = sdio_uart_open,
.close = sdio_uart_close,
@@ -1007,7 +1005,7 @@ static const struct tty_operations sdio_uart_ops = {
.break_ctl = sdio_uart_break_ctl,
.tiocmget = sdio_uart_tiocmget,
.tiocmset = sdio_uart_tiocmset,
- .read_proc = sdio_uart_read_proc,
+ .proc_fops = &sdio_uart_proc_fops,
};
static struct tty_driver *sdio_uart_tty_driver;
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index f210a8ee686..bdb165f9304 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -84,6 +84,14 @@ mmc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
}
retval = add_uevent_var(env, "MMC_NAME=%s", mmc_card_name(card));
+ if (retval)
+ return retval;
+
+ /*
+ * Request the mmc_block device. Note: that this is a direct request
+ * for the module it carries no information as to what is inserted.
+ */
+ retval = add_uevent_var(env, "MODALIAS=mmc:block");
return retval;
}
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index df6ce4a06cf..fa073ab3fa3 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -21,6 +21,7 @@
#include <linux/leds.h>
#include <linux/scatterlist.h>
#include <linux/log2.h>
+#include <linux/regulator/consumer.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
@@ -297,6 +298,21 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
data->timeout_clks = 0;
}
}
+ /*
+ * Some cards need very high timeouts if driven in SPI mode.
+ * The worst observed timeout was 900ms after writing a
+ * continuous stream of data until the internal logic
+ * overflowed.
+ */
+ if (mmc_host_is_spi(card->host)) {
+ if (data->flags & MMC_DATA_WRITE) {
+ if (data->timeout_ns < 1000000000)
+ data->timeout_ns = 1000000000; /* 1s */
+ } else {
+ if (data->timeout_ns < 100000000)
+ data->timeout_ns = 100000000; /* 100ms */
+ }
+ }
}
EXPORT_SYMBOL(mmc_set_data_timeout);
@@ -523,6 +539,105 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
}
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
+#ifdef CONFIG_REGULATOR
+
+/**
+ * mmc_regulator_get_ocrmask - return mask of supported voltages
+ * @supply: regulator to use
+ *
+ * This returns either a negative errno, or a mask of voltages that
+ * can be provided to MMC/SD/SDIO devices using the specified voltage
+ * regulator. This would normally be called before registering the
+ * MMC host adapter.
+ */
+int mmc_regulator_get_ocrmask(struct regulator *supply)
+{
+ int result = 0;
+ int count;
+ int i;
+
+ count = regulator_count_voltages(supply);
+ if (count < 0)
+ return count;
+
+ for (i = 0; i < count; i++) {
+ int vdd_uV;
+ int vdd_mV;
+
+ vdd_uV = regulator_list_voltage(supply, i);
+ if (vdd_uV <= 0)
+ continue;
+
+ vdd_mV = vdd_uV / 1000;
+ result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_get_ocrmask);
+
+/**
+ * mmc_regulator_set_ocr - set regulator to match host->ios voltage
+ * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
+ * @supply: regulator to use
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * MMC host drivers may use this to enable or disable a regulator using
+ * a particular supply voltage. This would normally be called from the
+ * set_ios() method.
+ */
+int mmc_regulator_set_ocr(struct regulator *supply, unsigned short vdd_bit)
+{
+ int result = 0;
+ int min_uV, max_uV;
+ int enabled;
+
+ enabled = regulator_is_enabled(supply);
+ if (enabled < 0)
+ return enabled;
+
+ if (vdd_bit) {
+ int tmp;
+ int voltage;
+
+ /* REVISIT mmc_vddrange_to_ocrmask() may have set some
+ * bits this regulator doesn't quite support ... don't
+ * be too picky, most cards and regulators are OK with
+ * a 0.1V range goof (it's a small error percentage).
+ */
+ tmp = vdd_bit - ilog2(MMC_VDD_165_195);
+ if (tmp == 0) {
+ min_uV = 1650 * 1000;
+ max_uV = 1950 * 1000;
+ } else {
+ min_uV = 1900 * 1000 + tmp * 100 * 1000;
+ max_uV = min_uV + 100 * 1000;
+ }
+
+ /* avoid needless changes to this voltage; the regulator
+ * might not allow this operation
+ */
+ voltage = regulator_get_voltage(supply);
+ if (voltage < 0)
+ result = voltage;
+ else if (voltage < min_uV || voltage > max_uV)
+ result = regulator_set_voltage(supply, min_uV, max_uV);
+ else
+ result = 0;
+
+ if (result == 0 && !enabled)
+ result = regulator_enable(supply);
+ } else if (enabled) {
+ result = regulator_disable(supply);
+ }
+
+ return result;
+}
+EXPORT_SYMBOL(mmc_regulator_set_ocr);
+
+#endif
+
/*
* Mask off any voltages we don't support and select
* the lowest voltage
@@ -815,6 +930,7 @@ void mmc_stop_host(struct mmc_host *host)
spin_unlock_irqrestore(&host->lock, flags);
#endif
+ cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
mmc_bus_get(host);
@@ -842,6 +958,7 @@ void mmc_stop_host(struct mmc_host *host)
*/
int mmc_suspend_host(struct mmc_host *host, pm_message_t state)
{
+ cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
mmc_bus_get(host);
@@ -875,6 +992,7 @@ int mmc_resume_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
mmc_power_up(host);
+ mmc_select_voltage(host, host->ocr);
BUG_ON(!host->bus_ops->resume);
host->bus_ops->resume(host);
}
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 1237bb4c722..610dbd1fcc8 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -184,6 +184,68 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
NULL, "%08llx\n");
+#define EXT_CSD_STR_LEN 1025
+
+static int mmc_ext_csd_open(struct inode *inode, struct file *filp)
+{
+ struct mmc_card *card = inode->i_private;
+ char *buf;
+ ssize_t n = 0;
+ u8 *ext_csd;
+ int err, i;
+
+ buf = kmalloc(EXT_CSD_STR_LEN + 1, GFP_KERNEL);
+ if (!buf)
+ return -ENOMEM;
+
+ ext_csd = kmalloc(512, GFP_KERNEL);
+ if (!ext_csd) {
+ err = -ENOMEM;
+ goto out_free;
+ }
+
+ mmc_claim_host(card->host);
+ err = mmc_send_ext_csd(card, ext_csd);
+ mmc_release_host(card->host);
+ if (err)
+ goto out_free;
+
+ for (i = 511; i >= 0; i--)
+ n += sprintf(buf + n, "%02x", ext_csd[i]);
+ n += sprintf(buf + n, "\n");
+ BUG_ON(n != EXT_CSD_STR_LEN);
+
+ filp->private_data = buf;
+ kfree(ext_csd);
+ return 0;
+
+out_free:
+ kfree(buf);
+ kfree(ext_csd);
+ return err;
+}
+
+static ssize_t mmc_ext_csd_read(struct file *filp, char __user *ubuf,
+ size_t cnt, loff_t *ppos)
+{
+ char *buf = filp->private_data;
+
+ return simple_read_from_buffer(ubuf, cnt, ppos,
+ buf, EXT_CSD_STR_LEN);
+}
+
+static int mmc_ext_csd_release(struct inode *inode, struct file *file)
+{
+ kfree(file->private_data);
+ return 0;
+}
+
+static struct file_operations mmc_dbg_ext_csd_fops = {
+ .open = mmc_ext_csd_open,
+ .read = mmc_ext_csd_read,
+ .release = mmc_ext_csd_release,
+};
+
void mmc_add_card_debugfs(struct mmc_card *card)
{
struct mmc_host *host = card->host;
@@ -211,6 +273,11 @@ void mmc_add_card_debugfs(struct mmc_card *card)
&mmc_dbg_card_status_fops))
goto err;
+ if (mmc_card_mmc(card))
+ if (!debugfs_create_file("ext_csd", S_IRUSR, root, card,
+ &mmc_dbg_ext_csd_fops))
+ goto err;
+
return;
err:
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c
index 956bd767750..963f2937c5e 100644
--- a/drivers/mmc/core/sdio_cis.c
+++ b/drivers/mmc/core/sdio_cis.c
@@ -223,10 +223,18 @@ static int sdio_read_cis(struct mmc_card *card, struct sdio_func *func)
if (tpl_code == 0xff)
break;
+ /* null entries have no link field or data */
+ if (tpl_code == 0x00)
+ continue;
+
ret = mmc_io_rw_direct(card, 0, 0, ptr++, 0, &tpl_link);
if (ret)
break;
+ /* a size of 0xff also means we're done */
+ if (tpl_link == 0xff)
+ break;
+
this = kmalloc(sizeof(*this) + tpl_link, GFP_KERNEL);
if (!this)
return -ENOMEM;
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index c8fa095a448..4eb7825fd1a 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -76,6 +76,10 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
BUG_ON(!card);
BUG_ON(fn > 7);
+ /* sanity check */
+ if (addr & ~0x1FFFF)
+ return -EINVAL;
+
memset(&cmd, 0, sizeof(struct mmc_command));
cmd.opcode = SD_IO_RW_DIRECT;
@@ -125,6 +129,10 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
WARN_ON(blocks == 0);
WARN_ON(blksz == 0);
+ /* sanity check */
+ if (addr & ~0x1FFFF)
+ return -EINVAL;
+
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 99d4b28d52e..b4cf691f3f6 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -37,6 +37,13 @@ config MMC_SDHCI
If unsure, say N.
+config MMC_SDHCI_IO_ACCESSORS
+ bool
+ depends on MMC_SDHCI
+ help
+ This is silent Kconfig symbol that is selected by the drivers that
+ need to overwrite SDHCI IO memory accessors.
+
config MMC_SDHCI_PCI
tristate "SDHCI support on PCI bus"
depends on MMC_SDHCI && PCI
@@ -65,6 +72,17 @@ config MMC_RICOH_MMC
If unsure, say Y.
+config MMC_SDHCI_OF
+ tristate "SDHCI support on OpenFirmware platforms"
+ depends on MMC_SDHCI && PPC_OF
+ select MMC_SDHCI_IO_ACCESSORS
+ help
+ This selects the OF support for Secure Digital Host Controller
+ Interfaces. So far, only the Freescale eSDHC controller is known
+ to exist on OF platforms.
+
+ If unsure, say N.
+
config MMC_OMAP
tristate "TI OMAP Multimedia Card Interface support"
depends on ARCH_OMAP
@@ -171,13 +189,24 @@ config MMC_TIFM_SD
To compile this driver as a module, choose M here: the
module will be called tifm_sd.
+config MMC_MVSDIO
+ tristate "Marvell MMC/SD/SDIO host driver"
+ depends on PLAT_ORION
+ ---help---
+ This selects the Marvell SDIO host driver.
+ SDIO may currently be found on the Kirkwood 88F6281 and 88F6192
+ SoC controllers.
+
+ To compile this driver as a module, choose M here: the
+ module will be called mvsdio.
+
config MMC_SPI
tristate "MMC/SD/SDIO over SPI"
depends on SPI_MASTER && !HIGHMEM && HAS_DMA
select CRC7
select CRC_ITU_T
help
- Some systems accss MMC/SD/SDIO cards using a SPI controller
+ Some systems access MMC/SD/SDIO cards using a SPI controller
instead of using a "native" MMC/SD/SDIO controller. This has a
disadvantage of being relatively high overhead, but a compensating
advantage of working on many systems without dedicated MMC/SD/SDIO
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index dedec55861d..970a997620e 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
obj-$(CONFIG_MMC_RICOH_MMC) += ricoh_mmc.o
+obj-$(CONFIG_MMC_SDHCI_OF) += sdhci-of.o
obj-$(CONFIG_MMC_WBSD) += wbsd.o
obj-$(CONFIG_MMC_AU1X) += au1xmmc.o
obj-$(CONFIG_MMC_OMAP) += omap.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o
obj-$(CONFIG_MMC_AT91) += at91_mci.o
obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o
obj-$(CONFIG_MMC_TIFM_SD) += tifm_sd.o
+obj-$(CONFIG_MMC_MVSDIO) += mvsdio.o
obj-$(CONFIG_MMC_SPI) += mmc_spi.o
ifeq ($(CONFIG_OF),y)
obj-$(CONFIG_MMC_SPI) += of_mmc_spi.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c
index e94e92001e7..cf6a100bb38 100644
--- a/drivers/mmc/host/atmel-mci.c
+++ b/drivers/mmc/host/atmel-mci.c
@@ -812,7 +812,7 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
slot->sdc_reg |= MCI_SDCBUS_1BIT;
break;
case MMC_BUS_WIDTH_4:
- slot->sdc_reg = MCI_SDCBUS_4BIT;
+ slot->sdc_reg |= MCI_SDCBUS_4BIT;
break;
}
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 87e211df68a..72f8bde4877 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -279,8 +279,11 @@ static int mmc_spi_response_get(struct mmc_spi_host *host,
* so it can always DMA directly into the target buffer.
* It'd probably be better to memcpy() the first chunk and
* avoid extra i/o calls...
+ *
+ * Note we check for more than 8 bytes, because in practice,
+ * some SD cards are slow...
*/
- for (i = 2; i < 9; i++) {
+ for (i = 2; i < 16; i++) {
value = mmc_spi_readbytes(host, 1);
if (value < 0)
goto done;
@@ -609,6 +612,7 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
struct spi_device *spi = host->spi;
int status, i;
struct scratch *scratch = host->data;
+ u32 pattern;
if (host->mmc->use_spi_crc)
scratch->crc_val = cpu_to_be16(
@@ -636,8 +640,27 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
* doesn't necessarily tell whether the write operation succeeded;
* it just says if the transmission was ok and whether *earlier*
* writes succeeded; see the standard.
+ *
+ * In practice, there are (even modern SDHC-)cards which are late
+ * in sending the response, and miss the time frame by a few bits,
+ * so we have to cope with this situation and check the response
+ * bit-by-bit. Arggh!!!
*/
- switch (SPI_MMC_RESPONSE_CODE(scratch->status[0])) {
+ pattern = scratch->status[0] << 24;
+ pattern |= scratch->status[1] << 16;
+ pattern |= scratch->status[2] << 8;
+ pattern |= scratch->status[3];
+
+ /* First 3 bit of pattern are undefined */
+ pattern |= 0xE0000000;
+
+ /* left-adjust to leading 0 bit */
+ while (pattern & 0x80000000)
+ pattern <<= 1;
+ /* right-adjust for pattern matching. Code is in bit 4..0 now. */
+ pattern >>= 27;
+
+ switch (pattern) {
case SPI_RESPONSE_ACCEPTED:
status = 0;
break;
@@ -668,8 +691,9 @@ mmc_spi_writeblock(struct mmc_spi_host *host, struct spi_transfer *t,
/* Return when not busy. If we didn't collect that status yet,
* we'll need some more I/O.
*/
- for (i = 1; i < sizeof(scratch->status); i++) {
- if (scratch->status[i] != 0)
+ for (i = 4; i < sizeof(scratch->status); i++) {
+ /* card is non-busy if the most recent bit is 1 */
+ if (scratch->status[i] & 0x01)
return 0;
}
return mmc_spi_wait_unbusy(host, timeout);
@@ -1204,10 +1228,12 @@ static int mmc_spi_probe(struct spi_device *spi)
/* MMC and SD specs only seem to care that sampling is on the
* rising edge ... meaning SPI modes 0 or 3. So either SPI mode
- * should be legit. We'll use mode 0 since it seems to be a
- * bit less troublesome on some hardware ... unclear why.
+ * should be legit. We'll use mode 0 since the steady state is 0,
+ * which is appropriate for hotplugging, unless the platform data
+ * specify mode 3 (if hardware is not compatible to mode 0).
*/
- spi->mode = SPI_MODE_0;
+ if (spi->mode != SPI_MODE_3)
+ spi->mode = SPI_MODE_0;
spi->bits_per_word = 8;
status = spi_setup(spi);
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c
new file mode 100644
index 00000000000..b5c375d94ab
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.c
@@ -0,0 +1,885 @@
+/*
+ * Marvell MMC/SD/SDIO driver
+ *
+ * Authors: Maen Suleiman, Nicolas Pitre
+ * Copyright (C) 2008-2009 Marvell Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/mbus.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/mmc/host.h>
+
+#include <asm/sizes.h>
+#include <asm/unaligned.h>
+#include <plat/mvsdio.h>
+
+#include "mvsdio.h"
+
+#define DRIVER_NAME "mvsdio"
+
+static int maxfreq = MVSD_CLOCKRATE_MAX;
+static int nodma;
+
+struct mvsd_host {
+ void __iomem *base;
+ struct mmc_request *mrq;
+ spinlock_t lock;
+ unsigned int xfer_mode;
+ unsigned int intr_en;
+ unsigned int ctrl;
+ unsigned int pio_size;
+ void *pio_ptr;
+ unsigned int sg_frags;
+ unsigned int ns_per_clk;
+ unsigned int clock;
+ unsigned int base_clock;
+ struct timer_list timer;
+ struct mmc_host *mmc;
+ struct device *dev;
+ struct resource *res;
+ int irq;
+ int gpio_card_detect;
+ int gpio_write_protect;
+};
+
+#define mvsd_write(offs, val) writel(val, iobase + (offs))
+#define mvsd_read(offs) readl(iobase + (offs))
+
+static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data)
+{
+ void __iomem *iobase = host->base;
+ unsigned int tmout;
+ int tmout_index;
+
+ /* If timeout=0 then maximum timeout index is used. */
+ tmout = DIV_ROUND_UP(data->timeout_ns, host->ns_per_clk);
+ tmout += data->timeout_clks;
+ tmout_index = fls(tmout - 1) - 12;
+ if (tmout_index < 0)
+ tmout_index = 0;
+ if (tmout_index > MVSD_HOST_CTRL_TMOUT_MAX)
+ tmout_index = MVSD_HOST_CTRL_TMOUT_MAX;
+
+ dev_dbg(host->dev, "data %s at 0x%08x: blocks=%d blksz=%d tmout=%u (%d)\n",
+ (data->flags & MMC_DATA_READ) ? "read" : "write",
+ (u32)sg_virt(data->sg), data->blocks, data->blksz,
+ tmout, tmout_index);
+
+ host->ctrl &= ~MVSD_HOST_CTRL_TMOUT_MASK;
+ host->ctrl |= MVSD_HOST_CTRL_TMOUT(tmout_index);
+ mvsd_write(MVSD_HOST_CTRL, host->ctrl);
+ mvsd_write(MVSD_BLK_COUNT, data->blocks);
+ mvsd_write(MVSD_BLK_SIZE, data->blksz);
+
+ if (nodma || (data->blksz | data->sg->offset) & 3) {
+ /*
+ * We cannot do DMA on a buffer which offset or size
+ * is not aligned on a 4-byte boundary.
+ */
+ host->pio_size = data->blocks * data->blksz;
+ host->pio_ptr = sg_virt(data->sg);
+ if (!nodma)
+ printk(KERN_DEBUG "%s: fallback to PIO for data "
+ "at 0x%p size %d\n",
+ mmc_hostname(host->mmc),
+ host->pio_ptr, host->pio_size);
+ return 1;
+ } else {
+ dma_addr_t phys_addr;
+ int dma_dir = (data->flags & MMC_DATA_READ) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE;
+ host->sg_frags = dma_map_sg(mmc_dev(host->mmc), data->sg,
+ data->sg_len, dma_dir);
+ phys_addr = sg_dma_address(data->sg);
+ mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff);
+ mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16);
+ return 0;
+ }
+}
+
+static void mvsd_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 cmdreg = 0, xfer = 0, intr = 0;
+ unsigned long flags;
+
+ BUG_ON(host->mrq != NULL);
+ host->mrq = mrq;
+
+ dev_dbg(host->dev, "cmd %d (hw state 0x%04x)\n",
+ cmd->opcode, mvsd_read(MVSD_HW_STATE));
+
+ cmdreg = MVSD_CMD_INDEX(cmd->opcode);
+
+ if (cmd->flags & MMC_RSP_BUSY)
+ cmdreg |= MVSD_CMD_RSP_48BUSY;
+ else if (cmd->flags & MMC_RSP_136)
+ cmdreg |= MVSD_CMD_RSP_136;
+ else if (cmd->flags & MMC_RSP_PRESENT)
+ cmdreg |= MVSD_CMD_RSP_48;
+ else
+ cmdreg |= MVSD_CMD_RSP_NONE;
+
+ if (cmd->flags & MMC_RSP_CRC)
+ cmdreg |= MVSD_CMD_CHECK_CMDCRC;
+
+ if (cmd->flags & MMC_RSP_OPCODE)
+ cmdreg |= MVSD_CMD_INDX_CHECK;
+
+ if (cmd->flags & MMC_RSP_PRESENT) {
+ cmdreg |= MVSD_UNEXPECTED_RESP;
+ intr |= MVSD_NOR_UNEXP_RSP;
+ }
+
+ if (mrq->data) {
+ struct mmc_data *data = mrq->data;
+ int pio;
+
+ cmdreg |= MVSD_CMD_DATA_PRESENT | MVSD_CMD_CHECK_DATACRC16;
+ xfer |= MVSD_XFER_MODE_HW_WR_DATA_EN;
+ if (data->flags & MMC_DATA_READ)
+ xfer |= MVSD_XFER_MODE_TO_HOST;
+
+ pio = mvsd_setup_data(host, data);
+ if (pio) {
+ xfer |= MVSD_XFER_MODE_PIO;
+ /* PIO section of mvsd_irq has comments on those bits */
+ if (data->flags & MMC_DATA_WRITE)
+ intr |= MVSD_NOR_TX_AVAIL;
+ else if (host->pio_size > 32)
+ intr |= MVSD_NOR_RX_FIFO_8W;
+ else
+ intr |= MVSD_NOR_RX_READY;
+ }
+
+ if (data->stop) {
+ struct mmc_command *stop = data->stop;
+ u32 cmd12reg = 0;
+
+ mvsd_write(MVSD_AUTOCMD12_ARG_LOW, stop->arg & 0xffff);
+ mvsd_write(MVSD_AUTOCMD12_ARG_HI, stop->arg >> 16);
+
+ if (stop->flags & MMC_RSP_BUSY)
+ cmd12reg |= MVSD_AUTOCMD12_BUSY;
+ if (stop->flags & MMC_RSP_OPCODE)
+ cmd12reg |= MVSD_AUTOCMD12_INDX_CHECK;
+ cmd12reg |= MVSD_AUTOCMD12_INDEX(stop->opcode);
+ mvsd_write(MVSD_AUTOCMD12_CMD, cmd12reg);
+
+ xfer |= MVSD_XFER_MODE_AUTO_CMD12;
+ intr |= MVSD_NOR_AUTOCMD12_DONE;
+ } else {
+ intr |= MVSD_NOR_XFER_DONE;
+ }
+ } else {
+ intr |= MVSD_NOR_CMD_DONE;
+ }
+
+ mvsd_write(MVSD_ARG_LOW, cmd->arg & 0xffff);
+ mvsd_write(MVSD_ARG_HI, cmd->arg >> 16);
+
+ spin_lock_irqsave(&host->lock, flags);
+
+ host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+ host->xfer_mode |= xfer;
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+ mvsd_write(MVSD_NOR_INTR_STATUS, ~MVSD_NOR_CARD_INT);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_CMD, cmdreg);
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ host->intr_en |= intr | MVSD_NOR_ERROR;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0xffff);
+
+ mod_timer(&host->timer, jiffies + 5 * HZ);
+
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static u32 mvsd_finish_cmd(struct mvsd_host *host, struct mmc_command *cmd,
+ u32 err_status)
+{
+ void __iomem *iobase = host->base;
+
+ if (cmd->flags & MMC_RSP_136) {
+ unsigned int response[8], i;
+ for (i = 0; i < 8; i++)
+ response[i] = mvsd_read(MVSD_RSP(i));
+ cmd->resp[0] = ((response[0] & 0x03ff) << 22) |
+ ((response[1] & 0xffff) << 6) |
+ ((response[2] & 0xfc00) >> 10);
+ cmd->resp[1] = ((response[2] & 0x03ff) << 22) |
+ ((response[3] & 0xffff) << 6) |
+ ((response[4] & 0xfc00) >> 10);
+ cmd->resp[2] = ((response[4] & 0x03ff) << 22) |
+ ((response[5] & 0xffff) << 6) |
+ ((response[6] & 0xfc00) >> 10);
+ cmd->resp[3] = ((response[6] & 0x03ff) << 22) |
+ ((response[7] & 0x3fff) << 8);
+ } else if (cmd->flags & MMC_RSP_PRESENT) {
+ unsigned int response[3], i;
+ for (i = 0; i < 3; i++)
+ response[i] = mvsd_read(MVSD_RSP(i));
+ cmd->resp[0] = ((response[2] & 0x003f) << (8 - 8)) |
+ ((response[1] & 0xffff) << (14 - 8)) |
+ ((response[0] & 0x03ff) << (30 - 8));
+ cmd->resp[1] = ((response[0] & 0xfc00) >> 10);
+ cmd->resp[2] = 0;
+ cmd->resp[3] = 0;
+ }
+
+ if (err_status & MVSD_ERR_CMD_TIMEOUT) {
+ cmd->error = -ETIMEDOUT;
+ } else if (err_status & (MVSD_ERR_CMD_CRC | MVSD_ERR_CMD_ENDBIT |
+ MVSD_ERR_CMD_INDEX | MVSD_ERR_CMD_STARTBIT)) {
+ cmd->error = -EILSEQ;
+ }
+ err_status &= ~(MVSD_ERR_CMD_TIMEOUT | MVSD_ERR_CMD_CRC |
+ MVSD_ERR_CMD_ENDBIT | MVSD_ERR_CMD_INDEX |
+ MVSD_ERR_CMD_STARTBIT);
+
+ return err_status;
+}
+
+static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data,
+ u32 err_status)
+{
+ void __iomem *iobase = host->base;
+
+ if (host->pio_ptr) {
+ host->pio_ptr = NULL;
+ host->pio_size = 0;
+ } else {
+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags,
+ (data->flags & MMC_DATA_READ) ?
+ DMA_FROM_DEVICE : DMA_TO_DEVICE);
+ }
+
+ if (err_status & MVSD_ERR_DATA_TIMEOUT)
+ data->error = -ETIMEDOUT;
+ else if (err_status & (MVSD_ERR_DATA_CRC | MVSD_ERR_DATA_ENDBIT))
+ data->error = -EILSEQ;
+ else if (err_status & MVSD_ERR_XFER_SIZE)
+ data->error = -EBADE;
+ err_status &= ~(MVSD_ERR_DATA_TIMEOUT | MVSD_ERR_DATA_CRC |
+ MVSD_ERR_DATA_ENDBIT | MVSD_ERR_XFER_SIZE);
+
+ dev_dbg(host->dev, "data done: blocks_left=%d, bytes_left=%d\n",
+ mvsd_read(MVSD_CURR_BLK_LEFT), mvsd_read(MVSD_CURR_BYTE_LEFT));
+ data->bytes_xfered =
+ (data->blocks - mvsd_read(MVSD_CURR_BLK_LEFT)) * data->blksz;
+ /* We can't be sure about the last block when errors are detected */
+ if (data->bytes_xfered && data->error)
+ data->bytes_xfered -= data->blksz;
+
+ /* Handle Auto cmd 12 response */
+ if (data->stop) {
+ unsigned int response[3], i;
+ for (i = 0; i < 3; i++)
+ response[i] = mvsd_read(MVSD_AUTO_RSP(i));
+ data->stop->resp[0] = ((response[2] & 0x003f) << (8 - 8)) |
+ ((response[1] & 0xffff) << (14 - 8)) |
+ ((response[0] & 0x03ff) << (30 - 8));
+ data->stop->resp[1] = ((response[0] & 0xfc00) >> 10);
+ data->stop->resp[2] = 0;
+ data->stop->resp[3] = 0;
+
+ if (err_status & MVSD_ERR_AUTOCMD12) {
+ u32 err_cmd12 = mvsd_read(MVSD_AUTOCMD12_ERR_STATUS);
+ dev_dbg(host->dev, "c12err 0x%04x\n", err_cmd12);
+ if (err_cmd12 & MVSD_AUTOCMD12_ERR_NOTEXE)
+ data->stop->error = -ENOEXEC;
+ else if (err_cmd12 & MVSD_AUTOCMD12_ERR_TIMEOUT)
+ data->stop->error = -ETIMEDOUT;
+ else if (err_cmd12)
+ data->stop->error = -EILSEQ;
+ err_status &= ~MVSD_ERR_AUTOCMD12;
+ }
+ }
+
+ return err_status;
+}
+
+static irqreturn_t mvsd_irq(int irq, void *dev)
+{
+ struct mvsd_host *host = dev;
+ void __iomem *iobase = host->base;
+ u32 intr_status, intr_done_mask;
+ int irq_handled = 0;
+
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n",
+ intr_status, mvsd_read(MVSD_NOR_INTR_EN),
+ mvsd_read(MVSD_HW_STATE));
+
+ spin_lock(&host->lock);
+
+ /* PIO handling, if needed. Messy business... */
+ if (host->pio_size &&
+ (intr_status & host->intr_en &
+ (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) {
+ u16 *p = host->pio_ptr;
+ int s = host->pio_size;
+ while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) {
+ readsw(iobase + MVSD_FIFO, p, 16);
+ p += 16;
+ s -= 32;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ /*
+ * Normally we'd use < 32 here, but the RX_FIFO_8W bit
+ * doesn't appear to assert when there is exactly 32 bytes
+ * (8 words) left to fetch in a transfer.
+ */
+ if (s <= 32) {
+ while (s >= 4 && (intr_status & MVSD_NOR_RX_READY)) {
+ put_unaligned(mvsd_read(MVSD_FIFO), p++);
+ put_unaligned(mvsd_read(MVSD_FIFO), p++);
+ s -= 4;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) {
+ u16 val[2] = {0, 0};
+ val[0] = mvsd_read(MVSD_FIFO);
+ val[1] = mvsd_read(MVSD_FIFO);
+ memcpy(p, &val, s);
+ s = 0;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s == 0) {
+ host->intr_en &=
+ ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ } else if (host->intr_en & MVSD_NOR_RX_FIFO_8W) {
+ host->intr_en &= ~MVSD_NOR_RX_FIFO_8W;
+ host->intr_en |= MVSD_NOR_RX_READY;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ }
+ }
+ dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+ s, intr_status, mvsd_read(MVSD_HW_STATE));
+ host->pio_ptr = p;
+ host->pio_size = s;
+ irq_handled = 1;
+ } else if (host->pio_size &&
+ (intr_status & host->intr_en &
+ (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) {
+ u16 *p = host->pio_ptr;
+ int s = host->pio_size;
+ /*
+ * The TX_FIFO_8W bit is unreliable. When set, bursting
+ * 16 halfwords all at once in the FIFO drops data. Actually
+ * TX_AVAIL does go off after only one word is pushed even if
+ * TX_FIFO_8W remains set.
+ */
+ while (s >= 4 && (intr_status & MVSD_NOR_TX_AVAIL)) {
+ mvsd_write(MVSD_FIFO, get_unaligned(p++));
+ mvsd_write(MVSD_FIFO, get_unaligned(p++));
+ s -= 4;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s < 4) {
+ if (s && (intr_status & MVSD_NOR_TX_AVAIL)) {
+ u16 val[2] = {0, 0};
+ memcpy(&val, p, s);
+ mvsd_write(MVSD_FIFO, val[0]);
+ mvsd_write(MVSD_FIFO, val[1]);
+ s = 0;
+ intr_status = mvsd_read(MVSD_NOR_INTR_STATUS);
+ }
+ if (s == 0) {
+ host->intr_en &=
+ ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ }
+ }
+ dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n",
+ s, intr_status, mvsd_read(MVSD_HW_STATE));
+ host->pio_ptr = p;
+ host->pio_size = s;
+ irq_handled = 1;
+ }
+
+ mvsd_write(MVSD_NOR_INTR_STATUS, intr_status);
+
+ intr_done_mask = MVSD_NOR_CARD_INT | MVSD_NOR_RX_READY |
+ MVSD_NOR_RX_FIFO_8W | MVSD_NOR_TX_FIFO_8W;
+ if (intr_status & host->intr_en & ~intr_done_mask) {
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 err_status = 0;
+
+ del_timer(&host->timer);
+ host->mrq = NULL;
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+
+ spin_unlock(&host->lock);
+
+ if (intr_status & MVSD_NOR_UNEXP_RSP) {
+ cmd->error = -EPROTO;
+ } else if (intr_status & MVSD_NOR_ERROR) {
+ err_status = mvsd_read(MVSD_ERR_INTR_STATUS);
+ dev_dbg(host->dev, "err 0x%04x\n", err_status);
+ }
+
+ err_status = mvsd_finish_cmd(host, cmd, err_status);
+ if (mrq->data)
+ err_status = mvsd_finish_data(host, mrq->data, err_status);
+ if (err_status) {
+ printk(KERN_ERR "%s: unhandled error status %#04x\n",
+ mmc_hostname(host->mmc), err_status);
+ cmd->error = -ENOMSG;
+ }
+
+ mmc_request_done(host->mmc, mrq);
+ irq_handled = 1;
+ } else
+ spin_unlock(&host->lock);
+
+ if (intr_status & MVSD_NOR_CARD_INT) {
+ mmc_signal_sdio_irq(host->mmc);
+ irq_handled = 1;
+ }
+
+ if (irq_handled)
+ return IRQ_HANDLED;
+
+ printk(KERN_ERR "%s: unhandled interrupt status=0x%04x en=0x%04x "
+ "pio=%d\n", mmc_hostname(host->mmc), intr_status,
+ host->intr_en, host->pio_size);
+ return IRQ_NONE;
+}
+
+static void mvsd_timeout_timer(unsigned long data)
+{
+ struct mvsd_host *host = (struct mvsd_host *)data;
+ void __iomem *iobase = host->base;
+ struct mmc_request *mrq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ mrq = host->mrq;
+ if (mrq) {
+ printk(KERN_ERR "%s: Timeout waiting for hardware interrupt.\n",
+ mmc_hostname(host->mmc));
+ printk(KERN_ERR "%s: hw_state=0x%04x, intr_status=0x%04x "
+ "intr_en=0x%04x\n", mmc_hostname(host->mmc),
+ mvsd_read(MVSD_HW_STATE),
+ mvsd_read(MVSD_NOR_INTR_STATUS),
+ mvsd_read(MVSD_NOR_INTR_EN));
+
+ host->mrq = NULL;
+
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+
+ host->xfer_mode &= MVSD_XFER_MODE_INT_CHK_EN;
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+
+ host->intr_en &= MVSD_NOR_CARD_INT;
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+
+ mrq->cmd->error = -ETIMEDOUT;
+ mvsd_finish_cmd(host, mrq->cmd, 0);
+ if (mrq->data) {
+ mrq->data->error = -ETIMEDOUT;
+ mvsd_finish_data(host, mrq->data, 0);
+ }
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ if (mrq)
+ mmc_request_done(host->mmc, mrq);
+}
+
+static irqreturn_t mvsd_card_detect_irq(int irq, void *dev)
+{
+ struct mvsd_host *host = dev;
+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ return IRQ_HANDLED;
+}
+
+static void mvsd_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ if (enable) {
+ host->xfer_mode |= MVSD_XFER_MODE_INT_CHK_EN;
+ host->intr_en |= MVSD_NOR_CARD_INT;
+ } else {
+ host->xfer_mode &= ~MVSD_XFER_MODE_INT_CHK_EN;
+ host->intr_en &= ~MVSD_NOR_CARD_INT;
+ }
+ mvsd_write(MVSD_XFER_MODE, host->xfer_mode);
+ mvsd_write(MVSD_NOR_INTR_EN, host->intr_en);
+ spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static int mvsd_get_ro(struct mmc_host *mmc)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+
+ if (host->gpio_write_protect)
+ return gpio_get_value(host->gpio_write_protect);
+
+ /*
+ * Board doesn't support read only detection; let the mmc core
+ * decide what to do.
+ */
+ return -ENOSYS;
+}
+
+static void mvsd_power_up(struct mvsd_host *host)
+{
+ void __iomem *iobase = host->base;
+ dev_dbg(host->dev, "power up\n");
+ mvsd_write(MVSD_NOR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+ mvsd_write(MVSD_XFER_MODE, 0);
+ mvsd_write(MVSD_NOR_STATUS_EN, 0xffff);
+ mvsd_write(MVSD_ERR_STATUS_EN, 0xffff);
+ mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_power_down(struct mvsd_host *host)
+{
+ void __iomem *iobase = host->base;
+ dev_dbg(host->dev, "power down\n");
+ mvsd_write(MVSD_NOR_INTR_EN, 0);
+ mvsd_write(MVSD_ERR_INTR_EN, 0);
+ mvsd_write(MVSD_SW_RESET, MVSD_SW_RESET_NOW);
+ mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+ mvsd_write(MVSD_NOR_STATUS_EN, 0);
+ mvsd_write(MVSD_ERR_STATUS_EN, 0);
+ mvsd_write(MVSD_NOR_INTR_STATUS, 0xffff);
+ mvsd_write(MVSD_ERR_INTR_STATUS, 0xffff);
+}
+
+static void mvsd_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct mvsd_host *host = mmc_priv(mmc);
+ void __iomem *iobase = host->base;
+ u32 ctrl_reg = 0;
+
+ if (ios->power_mode == MMC_POWER_UP)
+ mvsd_power_up(host);
+
+ if (ios->clock == 0) {
+ mvsd_write(MVSD_XFER_MODE, MVSD_XFER_MODE_STOP_CLK);
+ mvsd_write(MVSD_CLK_DIV, MVSD_BASE_DIV_MAX);
+ host->clock = 0;
+ dev_dbg(host->dev, "clock off\n");
+ } else if (ios->clock != host->clock) {
+ u32 m = DIV_ROUND_UP(host->base_clock, ios->clock) - 1;
+ if (m > MVSD_BASE_DIV_MAX)
+ m = MVSD_BASE_DIV_MAX;
+ mvsd_write(MVSD_CLK_DIV, m);
+ host->clock = ios->clock;
+ host->ns_per_clk = 1000000000 / (host->base_clock / (m+1));
+ dev_dbg(host->dev, "clock=%d (%d), div=0x%04x\n",
+ ios->clock, host->base_clock / (m+1), m);
+ }
+
+ /* default transfer mode */
+ ctrl_reg |= MVSD_HOST_CTRL_BIG_ENDIAN;
+ ctrl_reg &= ~MVSD_HOST_CTRL_LSB_FIRST;
+
+ /* default to maximum timeout */
+ ctrl_reg |= MVSD_HOST_CTRL_TMOUT_MASK;
+ ctrl_reg |= MVSD_HOST_CTRL_TMOUT_EN;
+
+ if (ios->bus_mode == MMC_BUSMODE_PUSHPULL)
+ ctrl_reg |= MVSD_HOST_CTRL_PUSH_PULL_EN;
+
+ if (ios->bus_width == MMC_BUS_WIDTH_4)
+ ctrl_reg |= MVSD_HOST_CTRL_DATA_WIDTH_4_BITS;
+
+ if (ios->timing == MMC_TIMING_MMC_HS ||
+ ios->timing == MMC_TIMING_SD_HS)
+ ctrl_reg |= MVSD_HOST_CTRL_HI_SPEED_EN;
+
+ host->ctrl = ctrl_reg;
+ mvsd_write(MVSD_HOST_CTRL, ctrl_reg);
+ dev_dbg(host->dev, "ctrl 0x%04x: %s %s %s\n", ctrl_reg,
+ (ctrl_reg & MVSD_HOST_CTRL_PUSH_PULL_EN) ?
+ "push-pull" : "open-drain",
+ (ctrl_reg & MVSD_HOST_CTRL_DATA_WIDTH_4_BITS) ?
+ "4bit-width" : "1bit-width",
+ (ctrl_reg & MVSD_HOST_CTRL_HI_SPEED_EN) ?
+ "high-speed" : "");
+
+ if (ios->power_mode == MMC_POWER_OFF)
+ mvsd_power_down(host);
+}
+
+static const struct mmc_host_ops mvsd_ops = {
+ .request = mvsd_request,
+ .get_ro = mvsd_get_ro,
+ .set_ios = mvsd_set_ios,
+ .enable_sdio_irq = mvsd_enable_sdio_irq,
+};
+
+static void __init mv_conf_mbus_windows(struct mvsd_host *host,
+ struct mbus_dram_target_info *dram)
+{
+ void __iomem *iobase = host->base;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ writel(0, iobase + MVSD_WINDOW_CTRL(i));
+ writel(0, iobase + MVSD_WINDOW_BASE(i));
+ }
+
+ for (i = 0; i < dram->num_cs; i++) {
+ struct mbus_dram_window *cs = dram->cs + i;
+ writel(((cs->size - 1) & 0xffff0000) |
+ (cs->mbus_attr << 8) |
+ (dram->mbus_dram_target_id << 4) | 1,
+ iobase + MVSD_WINDOW_CTRL(i));
+ writel(cs->base, iobase + MVSD_WINDOW_BASE(i));
+ }
+}
+
+static int __init mvsd_probe(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = NULL;
+ struct mvsd_host *host = NULL;
+ const struct mvsdio_platform_data *mvsd_data;
+ struct resource *r;
+ int ret, irq;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ mvsd_data = pdev->dev.platform_data;
+ if (!r || irq < 0 || !mvsd_data)
+ return -ENXIO;
+
+ r = request_mem_region(r->start, SZ_1K, DRIVER_NAME);
+ if (!r)
+ return -EBUSY;
+
+ mmc = mmc_alloc_host(sizeof(struct mvsd_host), &pdev->dev);
+ if (!mmc) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ host = mmc_priv(mmc);
+ host->mmc = mmc;
+ host->dev = &pdev->dev;
+ host->res = r;
+ host->base_clock = mvsd_data->clock / 2;
+
+ mmc->ops = &mvsd_ops;
+
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ |
+ MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
+
+ mmc->f_min = DIV_ROUND_UP(host->base_clock, MVSD_BASE_DIV_MAX);
+ mmc->f_max = maxfreq;
+
+ mmc->max_blk_size = 2048;
+ mmc->max_blk_count = 65535;
+
+ mmc->max_hw_segs = 1;
+ mmc->max_phys_segs = 1;
+ mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+
+ spin_lock_init(&host->lock);
+
+ host->base = ioremap(r->start, SZ_4K);
+ if (!host->base) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* (Re-)program MBUS remapping windows if we are asked to. */
+ if (mvsd_data->dram != NULL)
+ mv_conf_mbus_windows(host, mvsd_data->dram);
+
+ mvsd_power_down(host);
+
+ ret = request_irq(irq, mvsd_irq, 0, DRIVER_NAME, host);
+ if (ret) {
+ printk(KERN_ERR "%s: cannot assign irq %d\n", DRIVER_NAME, irq);
+ goto out;
+ } else
+ host->irq = irq;
+
+ if (mvsd_data->gpio_card_detect) {
+ ret = gpio_request(mvsd_data->gpio_card_detect,
+ DRIVER_NAME " cd");
+ if (ret == 0) {
+ gpio_direction_input(mvsd_data->gpio_card_detect);
+ irq = gpio_to_irq(mvsd_data->gpio_card_detect);
+ ret = request_irq(irq, mvsd_card_detect_irq,
+ IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING,
+ DRIVER_NAME " cd", host);
+ if (ret == 0)
+ host->gpio_card_detect =
+ mvsd_data->gpio_card_detect;
+ else
+ gpio_free(mvsd_data->gpio_card_detect);
+ }
+ }
+ if (!host->gpio_card_detect)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
+ if (mvsd_data->gpio_write_protect) {
+ ret = gpio_request(mvsd_data->gpio_write_protect,
+ DRIVER_NAME " wp");
+ if (ret == 0) {
+ gpio_direction_input(mvsd_data->gpio_write_protect);
+ host->gpio_write_protect =
+ mvsd_data->gpio_write_protect;
+ }
+ }
+
+ setup_timer(&host->timer, mvsd_timeout_timer, (unsigned long)host);
+ platform_set_drvdata(pdev, mmc);
+ ret = mmc_add_host(mmc);
+ if (ret)
+ goto out;
+
+ printk(KERN_NOTICE "%s: %s driver initialized, ",
+ mmc_hostname(mmc), DRIVER_NAME);
+ if (host->gpio_card_detect)
+ printk("using GPIO %d for card detection\n",
+ host->gpio_card_detect);
+ else
+ printk("lacking card detect (fall back to polling)\n");
+ return 0;
+
+out:
+ if (host) {
+ if (host->irq)
+ free_irq(host->irq, host);
+ if (host->gpio_card_detect) {
+ free_irq(gpio_to_irq(host->gpio_card_detect), host);
+ gpio_free(host->gpio_card_detect);
+ }
+ if (host->gpio_write_protect)
+ gpio_free(host->gpio_write_protect);
+ if (host->base)
+ iounmap(host->base);
+ }
+ if (r)
+ release_resource(r);
+ if (mmc)
+ mmc_free_host(mmc);
+
+ return ret;
+}
+
+static int __exit mvsd_remove(struct platform_device *pdev)
+{
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+
+ if (mmc) {
+ struct mvsd_host *host = mmc_priv(mmc);
+
+ if (host->gpio_card_detect) {
+ free_irq(gpio_to_irq(host->gpio_card_detect), host);
+ gpio_free(host->gpio_card_detect);
+ }
+ mmc_remove_host(mmc);
+ free_irq(host->irq, host);
+ if (host->gpio_write_protect)
+ gpio_free(host->gpio_write_protect);
+ del_timer_sync(&host->timer);
+ mvsd_power_down(host);
+ iounmap(host->base);
+ release_resource(host->res);
+ mmc_free_host(mmc);
+ }
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int mvsd_suspend(struct platform_device *dev, pm_message_t state,
+ u32 level)
+{
+ struct mmc_host *mmc = platform_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc && level == SUSPEND_DISABLE)
+ ret = mmc_suspend_host(mmc, state);
+
+ return ret;
+}
+
+static int mvsd_resume(struct platform_device *dev, u32 level)
+{
+ struct mmc_host *mmc = platform_dev_get_drvdata(dev);
+ int ret = 0;
+
+ if (mmc && level == RESUME_ENABLE)
+ ret = mmc_resume_host(mmc);
+
+ return ret;
+}
+#else
+#define mvsd_suspend NULL
+#define mvsd_resume NULL
+#endif
+
+static struct platform_driver mvsd_driver = {
+ .remove = __exit_p(mvsd_remove),
+ .suspend = mvsd_suspend,
+ .resume = mvsd_resume,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+};
+
+static int __init mvsd_init(void)
+{
+ return platform_driver_probe(&mvsd_driver, mvsd_probe);
+}
+
+static void __exit mvsd_exit(void)
+{
+ platform_driver_unregister(&mvsd_driver);
+}
+
+module_init(mvsd_init);
+module_exit(mvsd_exit);
+
+/* maximum card clock frequency (default 50MHz) */
+module_param(maxfreq, int, 0);
+
+/* force PIO transfers all the time */
+module_param(nodma, int, 0);
+
+MODULE_AUTHOR("Maen Suleiman, Nicolas Pitre");
+MODULE_DESCRIPTION("Marvell MMC,SD,SDIO Host Controller driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/mvsdio.h b/drivers/mmc/host/mvsdio.h
new file mode 100644
index 00000000000..7d9727b9f5a
--- /dev/null
+++ b/drivers/mmc/host/mvsdio.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2008 Marvell Semiconductors, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __MVSDIO_H
+#define __MVSDIO_H
+
+/*
+ * Clock rates
+ */
+
+#define MVSD_CLOCKRATE_MAX 50000000
+#define MVSD_BASE_DIV_MAX 0x7ff
+
+
+/*
+ * Register offsets
+ */
+
+#define MVSD_SYS_ADDR_LOW 0x000
+#define MVSD_SYS_ADDR_HI 0x004
+#define MVSD_BLK_SIZE 0x008
+#define MVSD_BLK_COUNT 0x00c
+#define MVSD_ARG_LOW 0x010
+#define MVSD_ARG_HI 0x014
+#define MVSD_XFER_MODE 0x018
+#define MVSD_CMD 0x01c
+#define MVSD_RSP(i) (0x020 + ((i)<<2))
+#define MVSD_RSP0 0x020
+#define MVSD_RSP1 0x024
+#define MVSD_RSP2 0x028
+#define MVSD_RSP3 0x02c
+#define MVSD_RSP4 0x030
+#define MVSD_RSP5 0x034
+#define MVSD_RSP6 0x038
+#define MVSD_RSP7 0x03c
+#define MVSD_FIFO 0x040
+#define MVSD_RSP_CRC7 0x044
+#define MVSD_HW_STATE 0x048
+#define MVSD_HOST_CTRL 0x050
+#define MVSD_BLK_GAP_CTRL 0x054
+#define MVSD_CLK_CTRL 0x058
+#define MVSD_SW_RESET 0x05c
+#define MVSD_NOR_INTR_STATUS 0x060
+#define MVSD_ERR_INTR_STATUS 0x064
+#define MVSD_NOR_STATUS_EN 0x068
+#define MVSD_ERR_STATUS_EN 0x06c
+#define MVSD_NOR_INTR_EN 0x070
+#define MVSD_ERR_INTR_EN 0x074
+#define MVSD_AUTOCMD12_ERR_STATUS 0x078
+#define MVSD_CURR_BYTE_LEFT 0x07c
+#define MVSD_CURR_BLK_LEFT 0x080
+#define MVSD_AUTOCMD12_ARG_LOW 0x084
+#define MVSD_AUTOCMD12_ARG_HI 0x088
+#define MVSD_AUTOCMD12_CMD 0x08c
+#define MVSD_AUTO_RSP(i) (0x090 + ((i)<<2))
+#define MVSD_AUTO_RSP0 0x090
+#define MVSD_AUTO_RSP1 0x094
+#define MVSD_AUTO_RSP2 0x098
+#define MVSD_CLK_DIV 0x128
+
+#define MVSD_WINDOW_CTRL(i) (0x108 + ((i) << 3))
+#define MVSD_WINDOW_BASE(i) (0x10c + ((i) << 3))
+
+
+/*
+ * MVSD_CMD
+ */
+
+#define MVSD_CMD_RSP_NONE (0 << 0)
+#define MVSD_CMD_RSP_136 (1 << 0)
+#define MVSD_CMD_RSP_48 (2 << 0)
+#define MVSD_CMD_RSP_48BUSY (3 << 0)
+
+#define MVSD_CMD_CHECK_DATACRC16 (1 << 2)
+#define MVSD_CMD_CHECK_CMDCRC (1 << 3)
+#define MVSD_CMD_INDX_CHECK (1 << 4)
+#define MVSD_CMD_DATA_PRESENT (1 << 5)
+#define MVSD_UNEXPECTED_RESP (1 << 7)
+#define MVSD_CMD_INDEX(x) ((x) << 8)
+
+
+/*
+ * MVSD_AUTOCMD12_CMD
+ */
+
+#define MVSD_AUTOCMD12_BUSY (1 << 0)
+#define MVSD_AUTOCMD12_INDX_CHECK (1 << 1)
+#define MVSD_AUTOCMD12_INDEX(x) ((x) << 8)
+
+/*
+ * MVSD_XFER_MODE
+ */
+
+#define MVSD_XFER_MODE_WR_DATA_START (1 << 0)
+#define MVSD_XFER_MODE_HW_WR_DATA_EN (1 << 1)
+#define MVSD_XFER_MODE_AUTO_CMD12 (1 << 2)
+#define MVSD_XFER_MODE_INT_CHK_EN (1 << 3)
+#define MVSD_XFER_MODE_TO_HOST (1 << 4)
+#define MVSD_XFER_MODE_STOP_CLK (1 << 5)
+#define MVSD_XFER_MODE_PIO (1 << 6)
+
+
+/*
+ * MVSD_HOST_CTRL
+ */
+
+#define MVSD_HOST_CTRL_PUSH_PULL_EN (1 << 0)
+
+#define MVSD_HOST_CTRL_CARD_TYPE_MEM_ONLY (0 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_ONLY (1 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MEM_COMBO (2 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_IO_MMC (3 << 1)
+#define MVSD_HOST_CTRL_CARD_TYPE_MASK (3 << 1)
+
+#define MVSD_HOST_CTRL_BIG_ENDIAN (1 << 3)
+#define MVSD_HOST_CTRL_LSB_FIRST (1 << 4)
+#define MVSD_HOST_CTRL_DATA_WIDTH_4_BITS (1 << 9)
+#define MVSD_HOST_CTRL_HI_SPEED_EN (1 << 10)
+
+#define MVSD_HOST_CTRL_TMOUT_MAX 0xf
+#define MVSD_HOST_CTRL_TMOUT_MASK (0xf << 11)
+#define MVSD_HOST_CTRL_TMOUT(x) ((x) << 11)
+#define MVSD_HOST_CTRL_TMOUT_EN (1 << 15)
+
+
+/*
+ * MVSD_SW_RESET
+ */
+
+#define MVSD_SW_RESET_NOW (1 << 8)
+
+
+/*
+ * Normal interrupt status bits
+ */
+
+#define MVSD_NOR_CMD_DONE (1 << 0)
+#define MVSD_NOR_XFER_DONE (1 << 1)
+#define MVSD_NOR_BLK_GAP_EVT (1 << 2)
+#define MVSD_NOR_DMA_DONE (1 << 3)
+#define MVSD_NOR_TX_AVAIL (1 << 4)
+#define MVSD_NOR_RX_READY (1 << 5)
+#define MVSD_NOR_CARD_INT (1 << 8)
+#define MVSD_NOR_READ_WAIT_ON (1 << 9)
+#define MVSD_NOR_RX_FIFO_8W (1 << 10)
+#define MVSD_NOR_TX_FIFO_8W (1 << 11)
+#define MVSD_NOR_SUSPEND_ON (1 << 12)
+#define MVSD_NOR_AUTOCMD12_DONE (1 << 13)
+#define MVSD_NOR_UNEXP_RSP (1 << 14)
+#define MVSD_NOR_ERROR (1 << 15)
+
+
+/*
+ * Error status bits
+ */
+
+#define MVSD_ERR_CMD_TIMEOUT (1 << 0)
+#define MVSD_ERR_CMD_CRC (1 << 1)
+#define MVSD_ERR_CMD_ENDBIT (1 << 2)
+#define MVSD_ERR_CMD_INDEX (1 << 3)
+#define MVSD_ERR_DATA_TIMEOUT (1 << 4)
+#define MVSD_ERR_DATA_CRC (1 << 5)
+#define MVSD_ERR_DATA_ENDBIT (1 << 6)
+#define MVSD_ERR_AUTOCMD12 (1 << 8)
+#define MVSD_ERR_CMD_STARTBIT (1 << 9)
+#define MVSD_ERR_XFER_SIZE (1 << 10)
+#define MVSD_ERR_RESP_T_BIT (1 << 11)
+#define MVSD_ERR_CRC_ENDBIT (1 << 12)
+#define MVSD_ERR_CRC_STARTBIT (1 << 13)
+#define MVSD_ERR_CRC_STATUS (1 << 14)
+
+
+/*
+ * CMD12 error status bits
+ */
+
+#define MVSD_AUTOCMD12_ERR_NOTEXE (1 << 0)
+#define MVSD_AUTOCMD12_ERR_TIMEOUT (1 << 1)
+#define MVSD_AUTOCMD12_ERR_CRC (1 << 2)
+#define MVSD_AUTOCMD12_ERR_ENDBIT (1 << 3)
+#define MVSD_AUTOCMD12_ERR_INDEX (1 << 4)
+#define MVSD_AUTOCMD12_ERR_RESP_T_BIT (1 << 5)
+#define MVSD_AUTOCMD12_ERR_RESP_STARTBIT (1 << 6)
+
+#endif
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index 3916a5618e2..d183be6f2a5 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -56,6 +56,7 @@
#define SDVS18 (0x5 << 9)
#define SDVS30 (0x6 << 9)
#define SDVS33 (0x7 << 9)
+#define SDVS_MASK 0x00000E00
#define SDVSCLR 0xFFFFF1FF
#define SDVSDET 0x00000400
#define AUTOIDLE 0x1
@@ -76,6 +77,7 @@
#define MSBS (1 << 5)
#define BCE (1 << 1)
#define FOUR_BIT (1 << 1)
+#define DW8 (1 << 5)
#define CC 0x1
#define TC 0x02
#define OD 0x1
@@ -98,10 +100,8 @@
*/
#define OMAP_MMC1_DEVID 0
#define OMAP_MMC2_DEVID 1
+#define OMAP_MMC3_DEVID 2
-#define OMAP_MMC_DATADIR_NONE 0
-#define OMAP_MMC_DATADIR_READ 1
-#define OMAP_MMC_DATADIR_WRITE 2
#define MMC_TIMEOUT_MS 20
#define OMAP_MMC_MASTER_CLOCK 96000000
#define DRIVER_NAME "mmci-omap-hs"
@@ -137,18 +137,18 @@ struct mmc_omap_host {
resource_size_t mapbase;
unsigned int id;
unsigned int dma_len;
- unsigned int dma_dir;
+ unsigned int dma_sg_idx;
unsigned char bus_mode;
- unsigned char datadir;
u32 *buffer;
u32 bytesleft;
int suspended;
int irq;
int carddetect;
int use_dma, dma_ch;
- int initstr;
+ int dma_line_tx, dma_line_rx;
int slot_id;
int dbclk_enabled;
+ int response_busy;
struct omap_mmc_platform_data *pdata;
};
@@ -218,7 +218,7 @@ mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
struct mmc_omap_host *host = mmc_priv(mmc);
struct omap_mmc_slot_data slot = host->pdata->slots[host->slot_id];
- return sprintf(buf, "slot:%s\n", slot.name);
+ return sprintf(buf, "%s\n", slot.name);
}
static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);
@@ -243,10 +243,14 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
OMAP_HSMMC_WRITE(host->base, ISE, INT_EN_MASK);
OMAP_HSMMC_WRITE(host->base, IE, INT_EN_MASK);
+ host->response_busy = 0;
if (cmd->flags & MMC_RSP_PRESENT) {
if (cmd->flags & MMC_RSP_136)
resptype = 1;
- else
+ else if (cmd->flags & MMC_RSP_BUSY) {
+ resptype = 3;
+ host->response_busy = 1;
+ } else
resptype = 2;
}
@@ -275,19 +279,35 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd,
OMAP_HSMMC_WRITE(host->base, CMD, cmdreg);
}
+static int
+mmc_omap_get_dma_dir(struct mmc_omap_host *host, struct mmc_data *data)
+{
+ if (data->flags & MMC_DATA_WRITE)
+ return DMA_TO_DEVICE;
+ else
+ return DMA_FROM_DEVICE;
+}
+
/*
* Notify the transfer complete to MMC core
*/
static void
mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
{
+ if (!data) {
+ struct mmc_request *mrq = host->mrq;
+
+ host->mrq = NULL;
+ mmc_omap_fclk_lazy_disable(host);
+ mmc_request_done(host->mmc, mrq);
+ return;
+ }
+
host->data = NULL;
if (host->use_dma && host->dma_ch != -1)
dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->dma_len,
- host->dma_dir);
-
- host->datadir = OMAP_MMC_DATADIR_NONE;
+ mmc_omap_get_dma_dir(host, data));
if (!data->error)
data->bytes_xfered += data->blocks * (data->blksz);
@@ -322,7 +342,7 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
cmd->resp[0] = OMAP_HSMMC_READ(host->base, RSP10);
}
}
- if (host->data == NULL || cmd->error) {
+ if ((host->data == NULL && !host->response_busy) || cmd->error) {
host->mrq = NULL;
mmc_request_done(host->mmc, cmd->mrq);
}
@@ -331,19 +351,18 @@ mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
/*
* DMA clean up for command errors
*/
-static void mmc_dma_cleanup(struct mmc_omap_host *host)
+static void mmc_dma_cleanup(struct mmc_omap_host *host, int errno)
{
- host->data->error = -ETIMEDOUT;
+ host->data->error = errno;
if (host->use_dma && host->dma_ch != -1) {
dma_unmap_sg(mmc_dev(host->mmc), host->data->sg, host->dma_len,
- host->dma_dir);
+ mmc_omap_get_dma_dir(host, host->data));
omap_free_dma(host->dma_ch);
host->dma_ch = -1;
up(&host->sem);
}
host->data = NULL;
- host->datadir = OMAP_MMC_DATADIR_NONE;
}
/*
@@ -412,7 +431,7 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
struct mmc_data *data;
int end_cmd = 0, end_trans = 0, status;
- if (host->cmd == NULL && host->data == NULL) {
+ if (host->mrq == NULL) {
OMAP_HSMMC_WRITE(host->base, STAT,
OMAP_HSMMC_READ(host->base, STAT));
return IRQ_HANDLED;
@@ -437,18 +456,24 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
}
end_cmd = 1;
}
- if (host->data) {
- mmc_dma_cleanup(host);
+ if (host->data || host->response_busy) {
+ if (host->data)
+ mmc_dma_cleanup(host, -ETIMEDOUT);
+ host->response_busy = 0;
mmc_omap_reset_controller_fsm(host, SRD);
}
}
if ((status & DATA_TIMEOUT) ||
(status & DATA_CRC)) {
- if (host->data) {
- if (status & DATA_TIMEOUT)
- mmc_dma_cleanup(host);
+ if (host->data || host->response_busy) {
+ int err = (status & DATA_TIMEOUT) ?
+ -ETIMEDOUT : -EILSEQ;
+
+ if (host->data)
+ mmc_dma_cleanup(host, err);
else
- host->data->error = -EILSEQ;
+ host->mrq->cmd->error = err;
+ host->response_busy = 0;
mmc_omap_reset_controller_fsm(host, SRD);
end_trans = 1;
}
@@ -473,6 +498,19 @@ static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static void set_sd_bus_power(struct mmc_omap_host *host)
+{
+ unsigned long i;
+
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ for (i = 0; i < loops_per_jiffy; i++) {
+ if (OMAP_HSMMC_READ(host->base, HCTL) & SDBP)
+ break;
+ cpu_relax();
+ }
+}
+
/*
* Switch MMC interface voltage ... only relevant for MMC1.
*
@@ -485,9 +523,6 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
u32 reg_val = 0;
int ret;
- if (host->id != OMAP_MMC1_DEVID)
- return 0;
-
/* Disable the clocks */
clk_disable(host->fclk);
clk_disable(host->iclk);
@@ -532,9 +567,7 @@ static int omap_mmc_switch_opcond(struct mmc_omap_host *host, int vdd)
reg_val |= SDVS30;
OMAP_HSMMC_WRITE(host->base, HCTL, reg_val);
-
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ set_sd_bus_power(host);
return 0;
err:
@@ -551,7 +584,10 @@ static void mmc_omap_detect(struct work_struct *work)
mmc_carddetect_work);
struct omap_mmc_slot_data *slot = &mmc_slot(host);
- host->carddetect = slot->card_detect(slot->card_detect_irq);
+ if (mmc_slot(host).card_detect)
+ host->carddetect = slot->card_detect(slot->card_detect_irq);
+ else
+ host->carddetect = -ENOSYS;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
if (host->carddetect) {
@@ -574,6 +610,48 @@ static irqreturn_t omap_mmc_cd_handler(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static int mmc_omap_get_dma_sync_dev(struct mmc_omap_host *host,
+ struct mmc_data *data)
+{
+ int sync_dev;
+
+ if (data->flags & MMC_DATA_WRITE)
+ sync_dev = host->dma_line_tx;
+ else
+ sync_dev = host->dma_line_rx;
+ return sync_dev;
+}
+
+static void mmc_omap_config_dma_params(struct mmc_omap_host *host,
+ struct mmc_data *data,
+ struct scatterlist *sgl)
+{
+ int blksz, nblk, dma_ch;
+
+ dma_ch = host->dma_ch;
+ if (data->flags & MMC_DATA_WRITE) {
+ omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(sgl), 0, 0);
+ } else {
+ omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
+ (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
+ omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
+ sg_dma_address(sgl), 0, 0);
+ }
+
+ blksz = host->data->blksz;
+ nblk = sg_dma_len(sgl) / blksz;
+
+ omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
+ blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
+ mmc_omap_get_dma_sync_dev(host, data),
+ !(data->flags & MMC_DATA_WRITE));
+
+ omap_start_dma(dma_ch);
+}
+
/*
* DMA call back function
*/
@@ -587,6 +665,14 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
if (host->dma_ch < 0)
return;
+ host->dma_sg_idx++;
+ if (host->dma_sg_idx < host->dma_len) {
+ /* Fire up the next transfer. */
+ mmc_omap_config_dma_params(host, host->data,
+ host->data->sg + host->dma_sg_idx);
+ return;
+ }
+
omap_free_dma(host->dma_ch);
host->dma_ch = -1;
/*
@@ -597,38 +683,28 @@ static void mmc_omap_dma_cb(int lch, u16 ch_status, void *data)
}
/*
- * Configure dma src and destination parameters
- */
-static int mmc_omap_config_dma_param(int sync_dir, struct mmc_omap_host *host,
- struct mmc_data *data)
-{
- if (sync_dir == 0) {
- omap_set_dma_dest_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_CONSTANT,
- (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
- omap_set_dma_src_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_POST_INC,
- sg_dma_address(&data->sg[0]), 0, 0);
- } else {
- omap_set_dma_src_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_CONSTANT,
- (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
- omap_set_dma_dest_params(host->dma_ch, 0,
- OMAP_DMA_AMODE_POST_INC,
- sg_dma_address(&data->sg[0]), 0, 0);
- }
- return 0;
-}
-/*
* Routine to configure and start DMA for the MMC card
*/
static int
mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
{
- int sync_dev, sync_dir = 0;
- int dma_ch = 0, ret = 0, err = 1;
+ int dma_ch = 0, ret = 0, err = 1, i;
struct mmc_data *data = req->data;
+ /* Sanity check: all the SG entries must be aligned by block size. */
+ for (i = 0; i < host->dma_len; i++) {
+ struct scatterlist *sgl;
+
+ sgl = data->sg + i;
+ if (sgl->length % data->blksz)
+ return -EINVAL;
+ }
+ if ((data->blksz % 4) != 0)
+ /* REVISIT: The MMC buffer increments only when MSB is written.
+ * Return error for blksz which is non multiple of four.
+ */
+ return -EINVAL;
+
/*
* If for some reason the DMA transfer is still active,
* we wait for timeout period and free the dma
@@ -647,49 +723,22 @@ mmc_omap_start_dma_transfer(struct mmc_omap_host *host, struct mmc_request *req)
return err;
}
- if (!(data->flags & MMC_DATA_WRITE)) {
- host->dma_dir = DMA_FROM_DEVICE;
- if (host->id == OMAP_MMC1_DEVID)
- sync_dev = OMAP24XX_DMA_MMC1_RX;
- else
- sync_dev = OMAP24XX_DMA_MMC2_RX;
- } else {
- host->dma_dir = DMA_TO_DEVICE;
- if (host->id == OMAP_MMC1_DEVID)
- sync_dev = OMAP24XX_DMA_MMC1_TX;
- else
- sync_dev = OMAP24XX_DMA_MMC2_TX;
- }
-
- ret = omap_request_dma(sync_dev, "MMC/SD", mmc_omap_dma_cb,
- host, &dma_ch);
+ ret = omap_request_dma(mmc_omap_get_dma_sync_dev(host, data), "MMC/SD",
+ mmc_omap_dma_cb,host, &dma_ch);
if (ret != 0) {
- dev_dbg(mmc_dev(host->mmc),
+ dev_err(mmc_dev(host->mmc),
"%s: omap_request_dma() failed with %d\n",
mmc_hostname(host->mmc), ret);
return ret;
}
host->dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
- data->sg_len, host->dma_dir);
+ data->sg_len, mmc_omap_get_dma_dir(host, data));
host->dma_ch = dma_ch;
+ host->dma_sg_idx = 0;
- if (!(data->flags & MMC_DATA_WRITE))
- mmc_omap_config_dma_param(1, host, data);
- else
- mmc_omap_config_dma_param(0, host, data);
-
- if ((data->blksz % 4) == 0)
- omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
- (data->blksz / 4), data->blocks, OMAP_DMA_SYNC_FRAME,
- sync_dev, sync_dir);
- else
- /* REVISIT: The MMC buffer increments only when MSB is written.
- * Return error for blksz which is non multiple of four.
- */
- return -EINVAL;
+ mmc_omap_config_dma_params(host, data, data->sg);
- omap_start_dma(dma_ch);
return 0;
}
@@ -739,7 +788,6 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
host->data = req->data;
if (req->data == NULL) {
- host->datadir = OMAP_MMC_DATADIR_NONE;
OMAP_HSMMC_WRITE(host->base, BLK, 0);
return 0;
}
@@ -748,9 +796,6 @@ mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
| (req->data->blocks << 16));
set_data_timeout(host, req);
- host->datadir = (req->data->flags & MMC_DATA_WRITE) ?
- OMAP_MMC_DATADIR_WRITE : OMAP_MMC_DATADIR_READ;
-
if (host->use_dma) {
ret = mmc_omap_start_dma_transfer(host, req);
if (ret != 0) {
@@ -782,36 +827,29 @@ static void omap_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
u16 dsor = 0;
unsigned long regval;
unsigned long timeout;
+ u32 con;
switch (ios->power_mode) {
case MMC_POWER_OFF:
mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
- /*
- * Reset interface voltage to 3V if it's 1.8V now;
- * only relevant on MMC-1, the others always use 1.8V.
- *
- * REVISIT: If we are able to detect cards after unplugging
- * a 1.8V card, this code should not be needed.
- */
- if (host->id != OMAP_MMC1_DEVID)
- break;
- if (!(OMAP_HSMMC_READ(host->base, HCTL) & SDVSDET)) {
- int vdd = fls(host->mmc->ocr_avail) - 1;
- if (omap_mmc_switch_opcond(host, vdd) != 0)
- host->mmc->ios.vdd = vdd;
- }
break;
case MMC_POWER_UP:
mmc_slot(host).set_power(host->dev, host->slot_id, 1, ios->vdd);
break;
}
+ con = OMAP_HSMMC_READ(host->base, CON);
switch (mmc->ios.bus_width) {
+ case MMC_BUS_WIDTH_8:
+ OMAP_HSMMC_WRITE(host->base, CON, con | DW8);
+ break;
case MMC_BUS_WIDTH_4:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) | FOUR_BIT);
break;
case MMC_BUS_WIDTH_1:
+ OMAP_HSMMC_WRITE(host->base, CON, con & ~DW8);
OMAP_HSMMC_WRITE(host->base, HCTL,
OMAP_HSMMC_READ(host->base, HCTL) & ~FOUR_BIT);
break;
@@ -891,6 +929,33 @@ static int omap_hsmmc_get_ro(struct mmc_host *mmc)
return pdata->slots[0].get_ro(host->dev, 0);
}
+static void omap_hsmmc_init(struct mmc_omap_host *host)
+{
+ u32 hctl, capa, value;
+
+ /* Only MMC1 supports 3.0V */
+ if (host->id == OMAP_MMC1_DEVID) {
+ hctl = SDVS30;
+ capa = VS30 | VS18;
+ } else {
+ hctl = SDVS18;
+ capa = VS18;
+ }
+
+ value = OMAP_HSMMC_READ(host->base, HCTL) & ~SDVS_MASK;
+ OMAP_HSMMC_WRITE(host->base, HCTL, value | hctl);
+
+ value = OMAP_HSMMC_READ(host->base, CAPA);
+ OMAP_HSMMC_WRITE(host->base, CAPA, value | capa);
+
+ /* Set the controller to AUTO IDLE mode */
+ value = OMAP_HSMMC_READ(host->base, SYSCONFIG);
+ OMAP_HSMMC_WRITE(host->base, SYSCONFIG, value | AUTOIDLE);
+
+ /* Set SD bus power bit */
+ set_sd_bus_power(host);
+}
+
static struct mmc_host_ops mmc_omap_ops = {
.request = omap_mmc_request,
.set_ios = omap_mmc_set_ios,
@@ -906,7 +971,6 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
struct mmc_omap_host *host = NULL;
struct resource *res;
int ret = 0, irq;
- u32 hctl, capa;
if (pdata == NULL) {
dev_err(&pdev->dev, "Platform Data is missing\n");
@@ -996,10 +1060,11 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
else
host->dbclk_enabled = 1;
-#ifdef CONFIG_MMC_BLOCK_BOUNCE
- mmc->max_phys_segs = 1;
- mmc->max_hw_segs = 1;
-#endif
+ /* Since we do only SG emulation, we can have as many segs
+ * as we want. */
+ mmc->max_phys_segs = 1024;
+ mmc->max_hw_segs = 1024;
+
mmc->max_blk_size = 512; /* Block Length at max can be 1024 */
mmc->max_blk_count = 0xFFFF; /* No. of Blocks is 16 bits */
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
@@ -1008,31 +1073,31 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
mmc->ocr_avail = mmc_slot(host).ocr_mask;
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
- if (pdata->slots[host->slot_id].wires >= 4)
+ if (pdata->slots[host->slot_id].wires >= 8)
+ mmc->caps |= MMC_CAP_8_BIT_DATA;
+ else if (pdata->slots[host->slot_id].wires >= 4)
mmc->caps |= MMC_CAP_4_BIT_DATA;
- /* Only MMC1 supports 3.0V */
- if (host->id == OMAP_MMC1_DEVID) {
- hctl = SDVS30;
- capa = VS30 | VS18;
- } else {
- hctl = SDVS18;
- capa = VS18;
- }
-
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | hctl);
-
- OMAP_HSMMC_WRITE(host->base, CAPA,
- OMAP_HSMMC_READ(host->base, CAPA) | capa);
-
- /* Set the controller to AUTO IDLE mode */
- OMAP_HSMMC_WRITE(host->base, SYSCONFIG,
- OMAP_HSMMC_READ(host->base, SYSCONFIG) | AUTOIDLE);
+ omap_hsmmc_init(host);
- /* Set SD bus power bit */
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL) | SDBP);
+ /* Select DMA lines */
+ switch (host->id) {
+ case OMAP_MMC1_DEVID:
+ host->dma_line_tx = OMAP24XX_DMA_MMC1_TX;
+ host->dma_line_rx = OMAP24XX_DMA_MMC1_RX;
+ break;
+ case OMAP_MMC2_DEVID:
+ host->dma_line_tx = OMAP24XX_DMA_MMC2_TX;
+ host->dma_line_rx = OMAP24XX_DMA_MMC2_RX;
+ break;
+ case OMAP_MMC3_DEVID:
+ host->dma_line_tx = OMAP34XX_DMA_MMC3_TX;
+ host->dma_line_rx = OMAP34XX_DMA_MMC3_RX;
+ break;
+ default:
+ dev_err(mmc_dev(host->mmc), "Invalid MMC id\n");
+ goto err_irq;
+ }
/* Request IRQ for MMC operations */
ret = request_irq(host->irq, mmc_omap_irq, IRQF_DISABLED,
@@ -1051,7 +1116,7 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
}
/* Request IRQ for card detect */
- if ((mmc_slot(host).card_detect_irq) && (mmc_slot(host).card_detect)) {
+ if ((mmc_slot(host).card_detect_irq)) {
ret = request_irq(mmc_slot(host).card_detect_irq,
omap_mmc_cd_handler,
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING
@@ -1074,8 +1139,8 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
if (ret < 0)
goto err_slot_name;
}
- if (mmc_slot(host).card_detect_irq && mmc_slot(host).card_detect &&
- host->pdata->slots[host->slot_id].get_cover_state) {
+ if (mmc_slot(host).card_detect_irq &&
+ host->pdata->slots[host->slot_id].get_cover_state) {
ret = device_create_file(&mmc->class_dev,
&dev_attr_cover_switch);
if (ret < 0)
@@ -1173,20 +1238,8 @@ static int omap_mmc_suspend(struct platform_device *pdev, pm_message_t state)
" level suspend\n");
}
- if (host->id == OMAP_MMC1_DEVID
- && !(OMAP_HSMMC_READ(host->base, HCTL)
- & SDVSDET)) {
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- & SDVSCLR);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- | SDVS30);
- OMAP_HSMMC_WRITE(host->base, HCTL,
- OMAP_HSMMC_READ(host->base, HCTL)
- | SDBP);
- }
-
+ OMAP_HSMMC_WRITE(host->base, HCTL,
+ OMAP_HSMMC_READ(host->base, HCTL) & ~SDBP);
clk_disable(host->fclk);
clk_disable(host->iclk);
clk_disable(host->dbclk);
@@ -1222,6 +1275,8 @@ static int omap_mmc_resume(struct platform_device *pdev)
dev_dbg(mmc_dev(host->mmc),
"Enabling debounce clk failed\n");
+ omap_hsmmc_init(host);
+
if (host->pdata->resume) {
ret = host->pdata->resume(&pdev->dev, host->slot_id);
if (ret)
diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
new file mode 100644
index 00000000000..3ff4ac3abe8
--- /dev/null
+++ b/drivers/mmc/host/sdhci-of.c
@@ -0,0 +1,309 @@
+/*
+ * OpenFirmware bindings for Secure Digital Host Controller Interface.
+ *
+ * Copyright (c) 2007 Freescale Semiconductor, Inc.
+ * Copyright (c) 2009 MontaVista Software, Inc.
+ *
+ * Authors: Xiaobo Xie <X.Xie@freescale.com>
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/mmc/host.h>
+#include "sdhci.h"
+
+struct sdhci_of_data {
+ unsigned int quirks;
+ struct sdhci_ops ops;
+};
+
+struct sdhci_of_host {
+ unsigned int clock;
+ u16 xfer_mode_shadow;
+};
+
+/*
+ * Ops and quirks for the Freescale eSDHC controller.
+ */
+
+#define ESDHC_DMA_SYSCTL 0x40c
+#define ESDHC_DMA_SNOOP 0x00000040
+
+#define ESDHC_SYSTEM_CONTROL 0x2c
+#define ESDHC_CLOCK_MASK 0x0000fff0
+#define ESDHC_PREDIV_SHIFT 8
+#define ESDHC_DIVIDER_SHIFT 4
+#define ESDHC_CLOCK_PEREN 0x00000004
+#define ESDHC_CLOCK_HCKEN 0x00000002
+#define ESDHC_CLOCK_IPGEN 0x00000001
+
+static u32 esdhc_readl(struct sdhci_host *host, int reg)
+{
+ return in_be32(host->ioaddr + reg);
+}
+
+static u16 esdhc_readw(struct sdhci_host *host, int reg)
+{
+ return in_be16(host->ioaddr + (reg ^ 0x2));
+}
+
+static u8 esdhc_readb(struct sdhci_host *host, int reg)
+{
+ return in_8(host->ioaddr + (reg ^ 0x3));
+}
+
+static void esdhc_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ out_be32(host->ioaddr + reg, val);
+}
+
+static void esdhc_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+ int base = reg & ~0x3;
+ int shift = (reg & 0x2) * 8;
+
+ switch (reg) {
+ case SDHCI_TRANSFER_MODE:
+ /*
+ * Postpone this write, we must do it together with a
+ * command write that is down below.
+ */
+ of_host->xfer_mode_shadow = val;
+ return;
+ case SDHCI_COMMAND:
+ esdhc_writel(host, val << 16 | of_host->xfer_mode_shadow,
+ SDHCI_TRANSFER_MODE);
+ return;
+ case SDHCI_BLOCK_SIZE:
+ /*
+ * Two last DMA bits are reserved, and first one is used for
+ * non-standard blksz of 4096 bytes that we don't support
+ * yet. So clear the DMA boundary bits.
+ */
+ val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
+ /* fall through */
+ }
+ clrsetbits_be32(host->ioaddr + base, 0xffff << shift, val << shift);
+}
+
+static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ int base = reg & ~0x3;
+ int shift = (reg & 0x3) * 8;
+
+ clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
+}
+
+static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+ int div;
+ int pre_div = 2;
+
+ clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+ ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
+
+ if (clock == 0)
+ goto out;
+
+ if (host->max_clk / 16 > clock) {
+ for (; pre_div < 256; pre_div *= 2) {
+ if (host->max_clk / pre_div < clock * 16)
+ break;
+ }
+ }
+
+ for (div = 1; div <= 16; div++) {
+ if (host->max_clk / (div * pre_div) <= clock)
+ break;
+ }
+
+ pre_div >>= 1;
+
+ setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
+ ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
+ div << ESDHC_DIVIDER_SHIFT | pre_div << ESDHC_PREDIV_SHIFT);
+ mdelay(100);
+out:
+ host->clock = clock;
+}
+
+static int esdhc_enable_dma(struct sdhci_host *host)
+{
+ setbits32(host->ioaddr + ESDHC_DMA_SYSCTL, ESDHC_DMA_SNOOP);
+ return 0;
+}
+
+static unsigned int esdhc_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+
+ return of_host->clock;
+}
+
+static unsigned int esdhc_get_timeout_clock(struct sdhci_host *host)
+{
+ struct sdhci_of_host *of_host = sdhci_priv(host);
+
+ return of_host->clock / 1000;
+}
+
+static struct sdhci_of_data sdhci_esdhc = {
+ .quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
+ SDHCI_QUIRK_BROKEN_CARD_DETECTION |
+ SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
+ SDHCI_QUIRK_NO_BUSY_IRQ |
+ SDHCI_QUIRK_NONSTANDARD_CLOCK |
+ SDHCI_QUIRK_PIO_NEEDS_DELAY |
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
+ SDHCI_QUIRK_NO_CARD_NO_RESET,
+ .ops = {
+ .readl = esdhc_readl,
+ .readw = esdhc_readw,
+ .readb = esdhc_readb,
+ .writel = esdhc_writel,
+ .writew = esdhc_writew,
+ .writeb = esdhc_writeb,
+ .set_clock = esdhc_set_clock,
+ .enable_dma = esdhc_enable_dma,
+ .get_max_clock = esdhc_get_max_clock,
+ .get_timeout_clock = esdhc_get_timeout_clock,
+ },
+};
+
+#ifdef CONFIG_PM
+
+static int sdhci_of_suspend(struct of_device *ofdev, pm_message_t state)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ return mmc_suspend_host(host->mmc, state);
+}
+
+static int sdhci_of_resume(struct of_device *ofdev)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ return mmc_resume_host(host->mmc);
+}
+
+#else
+
+#define sdhci_of_suspend NULL
+#define sdhci_of_resume NULL
+
+#endif
+
+static int __devinit sdhci_of_probe(struct of_device *ofdev,
+ const struct of_device_id *match)
+{
+ struct device_node *np = ofdev->node;
+ struct sdhci_of_data *sdhci_of_data = match->data;
+ struct sdhci_host *host;
+ struct sdhci_of_host *of_host;
+ const u32 *clk;
+ int size;
+ int ret;
+
+ if (!of_device_is_available(np))
+ return -ENODEV;
+
+ host = sdhci_alloc_host(&ofdev->dev, sizeof(*of_host));
+ if (!host)
+ return -ENOMEM;
+
+ of_host = sdhci_priv(host);
+ dev_set_drvdata(&ofdev->dev, host);
+
+ host->ioaddr = of_iomap(np, 0);
+ if (!host->ioaddr) {
+ ret = -ENOMEM;
+ goto err_addr_map;
+ }
+
+ host->irq = irq_of_parse_and_map(np, 0);
+ if (!host->irq) {
+ ret = -EINVAL;
+ goto err_no_irq;
+ }
+
+ host->hw_name = dev_name(&ofdev->dev);
+ if (sdhci_of_data) {
+ host->quirks = sdhci_of_data->quirks;
+ host->ops = &sdhci_of_data->ops;
+ }
+
+ clk = of_get_property(np, "clock-frequency", &size);
+ if (clk && size == sizeof(*clk) && *clk)
+ of_host->clock = *clk;
+
+ ret = sdhci_add_host(host);
+ if (ret)
+ goto err_add_host;
+
+ return 0;
+
+err_add_host:
+ irq_dispose_mapping(host->irq);
+err_no_irq:
+ iounmap(host->ioaddr);
+err_addr_map:
+ sdhci_free_host(host);
+ return ret;
+}
+
+static int __devexit sdhci_of_remove(struct of_device *ofdev)
+{
+ struct sdhci_host *host = dev_get_drvdata(&ofdev->dev);
+
+ sdhci_remove_host(host, 0);
+ sdhci_free_host(host);
+ irq_dispose_mapping(host->irq);
+ iounmap(host->ioaddr);
+ return 0;
+}
+
+static const struct of_device_id sdhci_of_match[] = {
+ { .compatible = "fsl,mpc8379-esdhc", .data = &sdhci_esdhc, },
+ { .compatible = "fsl,mpc8536-esdhc", .data = &sdhci_esdhc, },
+ { .compatible = "generic-sdhci", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, sdhci_of_match);
+
+static struct of_platform_driver sdhci_of_driver = {
+ .driver.name = "sdhci-of",
+ .match_table = sdhci_of_match,
+ .probe = sdhci_of_probe,
+ .remove = __devexit_p(sdhci_of_remove),
+ .suspend = sdhci_of_suspend,
+ .resume = sdhci_of_resume,
+};
+
+static int __init sdhci_of_init(void)
+{
+ return of_register_platform_driver(&sdhci_of_driver);
+}
+module_init(sdhci_of_init);
+
+static void __exit sdhci_of_exit(void)
+{
+ of_unregister_platform_driver(&sdhci_of_driver);
+}
+module_exit(sdhci_of_exit);
+
+MODULE_DESCRIPTION("Secure Digital Host Controller Interface OF driver");
+MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
+ "Anton Vorontsov <avorontsov@ru.mvista.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index accb592764e..30d8e3d4e6f 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -48,35 +48,35 @@ static void sdhci_dumpregs(struct sdhci_host *host)
printk(KERN_DEBUG DRIVER_NAME ": ============== REGISTER DUMP ==============\n");
printk(KERN_DEBUG DRIVER_NAME ": Sys addr: 0x%08x | Version: 0x%08x\n",
- readl(host->ioaddr + SDHCI_DMA_ADDRESS),
- readw(host->ioaddr + SDHCI_HOST_VERSION));
+ sdhci_readl(host, SDHCI_DMA_ADDRESS),
+ sdhci_readw(host, SDHCI_HOST_VERSION));
printk(KERN_DEBUG DRIVER_NAME ": Blk size: 0x%08x | Blk cnt: 0x%08x\n",
- readw(host->ioaddr + SDHCI_BLOCK_SIZE),
- readw(host->ioaddr + SDHCI_BLOCK_COUNT));
+ sdhci_readw(host, SDHCI_BLOCK_SIZE),
+ sdhci_readw(host, SDHCI_BLOCK_COUNT));
printk(KERN_DEBUG DRIVER_NAME ": Argument: 0x%08x | Trn mode: 0x%08x\n",
- readl(host->ioaddr + SDHCI_ARGUMENT),
- readw(host->ioaddr + SDHCI_TRANSFER_MODE));
+ sdhci_readl(host, SDHCI_ARGUMENT),
+ sdhci_readw(host, SDHCI_TRANSFER_MODE));
printk(KERN_DEBUG DRIVER_NAME ": Present: 0x%08x | Host ctl: 0x%08x\n",
- readl(host->ioaddr + SDHCI_PRESENT_STATE),
- readb(host->ioaddr + SDHCI_HOST_CONTROL));
+ sdhci_readl(host, SDHCI_PRESENT_STATE),
+ sdhci_readb(host, SDHCI_HOST_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Power: 0x%08x | Blk gap: 0x%08x\n",
- readb(host->ioaddr + SDHCI_POWER_CONTROL),
- readb(host->ioaddr + SDHCI_BLOCK_GAP_CONTROL));
+ sdhci_readb(host, SDHCI_POWER_CONTROL),
+ sdhci_readb(host, SDHCI_BLOCK_GAP_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Wake-up: 0x%08x | Clock: 0x%08x\n",
- readb(host->ioaddr + SDHCI_WAKE_UP_CONTROL),
- readw(host->ioaddr + SDHCI_CLOCK_CONTROL));
+ sdhci_readb(host, SDHCI_WAKE_UP_CONTROL),
+ sdhci_readw(host, SDHCI_CLOCK_CONTROL));
printk(KERN_DEBUG DRIVER_NAME ": Timeout: 0x%08x | Int stat: 0x%08x\n",
- readb(host->ioaddr + SDHCI_TIMEOUT_CONTROL),
- readl(host->ioaddr + SDHCI_INT_STATUS));
+ sdhci_readb(host, SDHCI_TIMEOUT_CONTROL),
+ sdhci_readl(host, SDHCI_INT_STATUS));
printk(KERN_DEBUG DRIVER_NAME ": Int enab: 0x%08x | Sig enab: 0x%08x\n",
- readl(host->ioaddr + SDHCI_INT_ENABLE),
- readl(host->ioaddr + SDHCI_SIGNAL_ENABLE));
+ sdhci_readl(host, SDHCI_INT_ENABLE),
+ sdhci_readl(host, SDHCI_SIGNAL_ENABLE));
printk(KERN_DEBUG DRIVER_NAME ": AC12 err: 0x%08x | Slot int: 0x%08x\n",
- readw(host->ioaddr + SDHCI_ACMD12_ERR),
- readw(host->ioaddr + SDHCI_SLOT_INT_STATUS));
+ sdhci_readw(host, SDHCI_ACMD12_ERR),
+ sdhci_readw(host, SDHCI_SLOT_INT_STATUS));
printk(KERN_DEBUG DRIVER_NAME ": Caps: 0x%08x | Max curr: 0x%08x\n",
- readl(host->ioaddr + SDHCI_CAPABILITIES),
- readl(host->ioaddr + SDHCI_MAX_CURRENT));
+ sdhci_readl(host, SDHCI_CAPABILITIES),
+ sdhci_readl(host, SDHCI_MAX_CURRENT));
printk(KERN_DEBUG DRIVER_NAME ": ===========================================\n");
}
@@ -87,17 +87,65 @@ static void sdhci_dumpregs(struct sdhci_host *host)
* *
\*****************************************************************************/
+static void sdhci_clear_set_irqs(struct sdhci_host *host, u32 clear, u32 set)
+{
+ u32 ier;
+
+ ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+ ier &= ~clear;
+ ier |= set;
+ sdhci_writel(host, ier, SDHCI_INT_ENABLE);
+ sdhci_writel(host, ier, SDHCI_SIGNAL_ENABLE);
+}
+
+static void sdhci_unmask_irqs(struct sdhci_host *host, u32 irqs)
+{
+ sdhci_clear_set_irqs(host, 0, irqs);
+}
+
+static void sdhci_mask_irqs(struct sdhci_host *host, u32 irqs)
+{
+ sdhci_clear_set_irqs(host, irqs, 0);
+}
+
+static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
+{
+ u32 irqs = SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT;
+
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ return;
+
+ if (enable)
+ sdhci_unmask_irqs(host, irqs);
+ else
+ sdhci_mask_irqs(host, irqs);
+}
+
+static void sdhci_enable_card_detection(struct sdhci_host *host)
+{
+ sdhci_set_card_detection(host, true);
+}
+
+static void sdhci_disable_card_detection(struct sdhci_host *host)
+{
+ sdhci_set_card_detection(host, false);
+}
+
static void sdhci_reset(struct sdhci_host *host, u8 mask)
{
unsigned long timeout;
+ u32 uninitialized_var(ier);
if (host->quirks & SDHCI_QUIRK_NO_CARD_NO_RESET) {
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
+ if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
SDHCI_CARD_PRESENT))
return;
}
- writeb(mask, host->ioaddr + SDHCI_SOFTWARE_RESET);
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ ier = sdhci_readl(host, SDHCI_INT_ENABLE);
+
+ sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
if (mask & SDHCI_RESET_ALL)
host->clock = 0;
@@ -106,7 +154,7 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
timeout = 100;
/* hw clears the bit when it's done */
- while (readb(host->ioaddr + SDHCI_SOFTWARE_RESET) & mask) {
+ while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Reset 0x%x never completed.\n",
mmc_hostname(host->mmc), (int)mask);
@@ -116,42 +164,44 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
timeout--;
mdelay(1);
}
+
+ if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
+ sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
}
static void sdhci_init(struct sdhci_host *host)
{
- u32 intmask;
-
sdhci_reset(host, SDHCI_RESET_ALL);
- intmask = SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
+ sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK,
+ SDHCI_INT_BUS_POWER | SDHCI_INT_DATA_END_BIT |
SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_INDEX |
SDHCI_INT_END_BIT | SDHCI_INT_CRC | SDHCI_INT_TIMEOUT |
- SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT |
- SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL |
- SDHCI_INT_DMA_END | SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE |
- SDHCI_INT_ADMA_ERROR;
+ SDHCI_INT_DATA_END | SDHCI_INT_RESPONSE);
+}
- writel(intmask, host->ioaddr + SDHCI_INT_ENABLE);
- writel(intmask, host->ioaddr + SDHCI_SIGNAL_ENABLE);
+static void sdhci_reinit(struct sdhci_host *host)
+{
+ sdhci_init(host);
+ sdhci_enable_card_detection(host);
}
static void sdhci_activate_led(struct sdhci_host *host)
{
u8 ctrl;
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl |= SDHCI_CTRL_LED;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
static void sdhci_deactivate_led(struct sdhci_host *host)
{
u8 ctrl;
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_LED;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
#ifdef SDHCI_USE_LEDS_CLASS
@@ -205,7 +255,7 @@ static void sdhci_read_block_pio(struct sdhci_host *host)
while (len) {
if (chunk == 0) {
- scratch = readl(host->ioaddr + SDHCI_BUFFER);
+ scratch = sdhci_readl(host, SDHCI_BUFFER);
chunk = 4;
}
@@ -257,7 +307,7 @@ static void sdhci_write_block_pio(struct sdhci_host *host)
len--;
if ((chunk == 4) || ((len == 0) && (blksize == 0))) {
- writel(scratch, host->ioaddr + SDHCI_BUFFER);
+ sdhci_writel(host, scratch, SDHCI_BUFFER);
chunk = 0;
scratch = 0;
}
@@ -292,7 +342,10 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
(host->data->blocks == 1))
mask = ~0;
- while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+ while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
+ if (host->quirks & SDHCI_QUIRK_PIO_NEEDS_DELAY)
+ udelay(100);
+
if (host->data->flags & MMC_DATA_READ)
sdhci_read_block_pio(host);
else
@@ -561,6 +614,17 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
return count;
}
+static void sdhci_set_transfer_irqs(struct sdhci_host *host)
+{
+ u32 pio_irqs = SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL;
+ u32 dma_irqs = SDHCI_INT_DMA_END | SDHCI_INT_ADMA_ERROR;
+
+ if (host->flags & SDHCI_REQ_USE_DMA)
+ sdhci_clear_set_irqs(host, pio_irqs, dma_irqs);
+ else
+ sdhci_clear_set_irqs(host, dma_irqs, pio_irqs);
+}
+
static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
{
u8 count;
@@ -581,7 +645,7 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->data_early = 0;
count = sdhci_calc_timeout(host, data);
- writeb(count, host->ioaddr + SDHCI_TIMEOUT_CONTROL);
+ sdhci_writeb(host, count, SDHCI_TIMEOUT_CONTROL);
if (host->flags & SDHCI_USE_DMA)
host->flags |= SDHCI_REQ_USE_DMA;
@@ -661,8 +725,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
WARN_ON(1);
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
- writel(host->adma_addr,
- host->ioaddr + SDHCI_ADMA_ADDRESS);
+ sdhci_writel(host, host->adma_addr,
+ SDHCI_ADMA_ADDRESS);
}
} else {
int sg_cnt;
@@ -681,8 +745,8 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->flags &= ~SDHCI_REQ_USE_DMA;
} else {
WARN_ON(sg_cnt != 1);
- writel(sg_dma_address(data->sg),
- host->ioaddr + SDHCI_DMA_ADDRESS);
+ sdhci_writel(host, sg_dma_address(data->sg),
+ SDHCI_DMA_ADDRESS);
}
}
}
@@ -693,14 +757,14 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
* is ADMA.
*/
if (host->version >= SDHCI_SPEC_200) {
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
ctrl &= ~SDHCI_CTRL_DMA_MASK;
if ((host->flags & SDHCI_REQ_USE_DMA) &&
(host->flags & SDHCI_USE_ADMA))
ctrl |= SDHCI_CTRL_ADMA32;
else
ctrl |= SDHCI_CTRL_SDMA;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
}
if (!(host->flags & SDHCI_REQ_USE_DMA)) {
@@ -709,10 +773,11 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data)
host->blocks = data->blocks;
}
+ sdhci_set_transfer_irqs(host);
+
/* We do not handle DMA boundaries, so set it to max (512 KiB) */
- writew(SDHCI_MAKE_BLKSZ(7, data->blksz),
- host->ioaddr + SDHCI_BLOCK_SIZE);
- writew(data->blocks, host->ioaddr + SDHCI_BLOCK_COUNT);
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, data->blksz), SDHCI_BLOCK_SIZE);
+ sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
}
static void sdhci_set_transfer_mode(struct sdhci_host *host,
@@ -733,7 +798,7 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host,
if (host->flags & SDHCI_REQ_USE_DMA)
mode |= SDHCI_TRNS_DMA;
- writew(mode, host->ioaddr + SDHCI_TRANSFER_MODE);
+ sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
}
static void sdhci_finish_data(struct sdhci_host *host)
@@ -802,7 +867,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if (host->mrq->data && (cmd == host->mrq->data->stop))
mask &= ~SDHCI_DATA_INHIBIT;
- while (readl(host->ioaddr + SDHCI_PRESENT_STATE) & mask) {
+ while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
if (timeout == 0) {
printk(KERN_ERR "%s: Controller never released "
"inhibit bit(s).\n", mmc_hostname(host->mmc));
@@ -821,7 +886,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
sdhci_prepare_data(host, cmd->data);
- writel(cmd->arg, host->ioaddr + SDHCI_ARGUMENT);
+ sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
sdhci_set_transfer_mode(host, cmd->data);
@@ -849,8 +914,7 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
if (cmd->data)
flags |= SDHCI_CMD_DATA;
- writew(SDHCI_MAKE_CMD(cmd->opcode, flags),
- host->ioaddr + SDHCI_COMMAND);
+ sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
}
static void sdhci_finish_command(struct sdhci_host *host)
@@ -863,15 +927,15 @@ static void sdhci_finish_command(struct sdhci_host *host)
if (host->cmd->flags & MMC_RSP_136) {
/* CRC is stripped so we need to do some shifting. */
for (i = 0;i < 4;i++) {
- host->cmd->resp[i] = readl(host->ioaddr +
+ host->cmd->resp[i] = sdhci_readl(host,
SDHCI_RESPONSE + (3-i)*4) << 8;
if (i != 3)
host->cmd->resp[i] |=
- readb(host->ioaddr +
+ sdhci_readb(host,
SDHCI_RESPONSE + (3-i)*4-1);
}
} else {
- host->cmd->resp[0] = readl(host->ioaddr + SDHCI_RESPONSE);
+ host->cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
}
}
@@ -895,7 +959,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
if (clock == host->clock)
return;
- writew(0, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ if (host->ops->set_clock) {
+ host->ops->set_clock(host, clock);
+ if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
+ return;
+ }
+
+ sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
if (clock == 0)
goto out;
@@ -908,11 +978,11 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
clk = div << SDHCI_DIVIDER_SHIFT;
clk |= SDHCI_CLOCK_INT_EN;
- writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
/* Wait max 10 ms */
timeout = 10;
- while (!((clk = readw(host->ioaddr + SDHCI_CLOCK_CONTROL))
+ while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
& SDHCI_CLOCK_INT_STABLE)) {
if (timeout == 0) {
printk(KERN_ERR "%s: Internal clock never "
@@ -925,7 +995,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
}
clk |= SDHCI_CLOCK_CARD_EN;
- writew(clk, host->ioaddr + SDHCI_CLOCK_CONTROL);
+ sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
out:
host->clock = clock;
@@ -939,7 +1009,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
return;
if (power == (unsigned short)-1) {
- writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
goto out;
}
@@ -948,7 +1018,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* a new value. Some controllers don't seem to like this though.
*/
if (!(host->quirks & SDHCI_QUIRK_SINGLE_POWER_WRITE))
- writeb(0, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
pwr = SDHCI_POWER_ON;
@@ -973,10 +1043,9 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
* and set turn on power at the same time, so set the voltage first.
*/
if ((host->quirks & SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER))
- writeb(pwr & ~SDHCI_POWER_ON,
- host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, pwr & ~SDHCI_POWER_ON, SDHCI_POWER_CONTROL);
- writeb(pwr, host->ioaddr + SDHCI_POWER_CONTROL);
+ sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
out:
host->power = power;
@@ -991,6 +1060,7 @@ out:
static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
{
struct sdhci_host *host;
+ bool present;
unsigned long flags;
host = mmc_priv(mmc);
@@ -1005,8 +1075,14 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
host->mrq = mrq;
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)
- || (host->flags & SDHCI_DEVICE_DEAD)) {
+ /* If polling, assume that the card is always present. */
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ present = true;
+ else
+ present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
+ SDHCI_CARD_PRESENT;
+
+ if (!present || host->flags & SDHCI_DEVICE_DEAD) {
host->mrq->cmd->error = -ENOMEDIUM;
tasklet_schedule(&host->finish_tasklet);
} else
@@ -1034,8 +1110,8 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
* Should clear out any weird states.
*/
if (ios->power_mode == MMC_POWER_OFF) {
- writel(0, host->ioaddr + SDHCI_SIGNAL_ENABLE);
- sdhci_init(host);
+ sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
+ sdhci_reinit(host);
}
sdhci_set_clock(host, ios->clock);
@@ -1045,7 +1121,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
sdhci_set_power(host, ios->vdd);
- ctrl = readb(host->ioaddr + SDHCI_HOST_CONTROL);
+ ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if (ios->bus_width == MMC_BUS_WIDTH_4)
ctrl |= SDHCI_CTRL_4BITBUS;
@@ -1057,7 +1133,7 @@ static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
else
ctrl &= ~SDHCI_CTRL_HISPD;
- writeb(ctrl, host->ioaddr + SDHCI_HOST_CONTROL);
+ sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
/*
* Some (ENE) controllers go apeshit on some ios operation,
@@ -1085,10 +1161,12 @@ static int sdhci_get_ro(struct mmc_host *mmc)
if (host->flags & SDHCI_DEVICE_DEAD)
present = 0;
else
- present = readl(host->ioaddr + SDHCI_PRESENT_STATE);
+ present = sdhci_readl(host, SDHCI_PRESENT_STATE);
spin_unlock_irqrestore(&host->lock, flags);
+ if (host->quirks & SDHCI_QUIRK_INVERTED_WRITE_PROTECT)
+ return !!(present & SDHCI_WRITE_PROTECT);
return !(present & SDHCI_WRITE_PROTECT);
}
@@ -1096,7 +1174,6 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
{
struct sdhci_host *host;
unsigned long flags;
- u32 ier;
host = mmc_priv(mmc);
@@ -1105,15 +1182,10 @@ static void sdhci_enable_sdio_irq(struct mmc_host *mmc, int enable)
if (host->flags & SDHCI_DEVICE_DEAD)
goto out;
- ier = readl(host->ioaddr + SDHCI_INT_ENABLE);
-
- ier &= ~SDHCI_INT_CARD_INT;
if (enable)
- ier |= SDHCI_INT_CARD_INT;
-
- writel(ier, host->ioaddr + SDHCI_INT_ENABLE);
- writel(ier, host->ioaddr + SDHCI_SIGNAL_ENABLE);
-
+ sdhci_unmask_irqs(host, SDHCI_INT_CARD_INT);
+ else
+ sdhci_mask_irqs(host, SDHCI_INT_CARD_INT);
out:
mmiowb();
@@ -1142,7 +1214,7 @@ static void sdhci_tasklet_card(unsigned long param)
spin_lock_irqsave(&host->lock, flags);
- if (!(readl(host->ioaddr + SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
+ if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
if (host->mrq) {
printk(KERN_ERR "%s: Card removed during transfer!\n",
mmc_hostname(host->mmc));
@@ -1346,8 +1418,8 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
* we need to at least restart the transfer.
*/
if (intmask & SDHCI_INT_DMA_END)
- writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS),
- host->ioaddr + SDHCI_DMA_ADDRESS);
+ sdhci_writel(host, sdhci_readl(host, SDHCI_DMA_ADDRESS),
+ SDHCI_DMA_ADDRESS);
if (intmask & SDHCI_INT_DATA_END) {
if (host->cmd) {
@@ -1373,7 +1445,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
spin_lock(&host->lock);
- intmask = readl(host->ioaddr + SDHCI_INT_STATUS);
+ intmask = sdhci_readl(host, SDHCI_INT_STATUS);
if (!intmask || intmask == 0xffffffff) {
result = IRQ_NONE;
@@ -1384,22 +1456,22 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
mmc_hostname(host->mmc), intmask);
if (intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE)) {
- writel(intmask & (SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE),
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & (SDHCI_INT_CARD_INSERT |
+ SDHCI_INT_CARD_REMOVE), SDHCI_INT_STATUS);
tasklet_schedule(&host->card_tasklet);
}
intmask &= ~(SDHCI_INT_CARD_INSERT | SDHCI_INT_CARD_REMOVE);
if (intmask & SDHCI_INT_CMD_MASK) {
- writel(intmask & SDHCI_INT_CMD_MASK,
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & SDHCI_INT_CMD_MASK,
+ SDHCI_INT_STATUS);
sdhci_cmd_irq(host, intmask & SDHCI_INT_CMD_MASK);
}
if (intmask & SDHCI_INT_DATA_MASK) {
- writel(intmask & SDHCI_INT_DATA_MASK,
- host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask & SDHCI_INT_DATA_MASK,
+ SDHCI_INT_STATUS);
sdhci_data_irq(host, intmask & SDHCI_INT_DATA_MASK);
}
@@ -1410,7 +1482,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
if (intmask & SDHCI_INT_BUS_POWER) {
printk(KERN_ERR "%s: Card is consuming too much power!\n",
mmc_hostname(host->mmc));
- writel(SDHCI_INT_BUS_POWER, host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, SDHCI_INT_BUS_POWER, SDHCI_INT_STATUS);
}
intmask &= ~SDHCI_INT_BUS_POWER;
@@ -1425,7 +1497,7 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
mmc_hostname(host->mmc), intmask);
sdhci_dumpregs(host);
- writel(intmask, host->ioaddr + SDHCI_INT_STATUS);
+ sdhci_writel(host, intmask, SDHCI_INT_STATUS);
}
result = IRQ_HANDLED;
@@ -1455,6 +1527,8 @@ int sdhci_suspend_host(struct sdhci_host *host, pm_message_t state)
{
int ret;
+ sdhci_disable_card_detection(host);
+
ret = mmc_suspend_host(host->mmc, state);
if (ret)
return ret;
@@ -1487,6 +1561,8 @@ int sdhci_resume_host(struct sdhci_host *host)
if (ret)
return ret;
+ sdhci_enable_card_detection(host);
+
return 0;
}
@@ -1537,7 +1613,7 @@ int sdhci_add_host(struct sdhci_host *host)
sdhci_reset(host, SDHCI_RESET_ALL);
- host->version = readw(host->ioaddr + SDHCI_HOST_VERSION);
+ host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
host->version = (host->version & SDHCI_SPEC_VER_MASK)
>> SDHCI_SPEC_VER_SHIFT;
if (host->version > SDHCI_SPEC_200) {
@@ -1546,7 +1622,7 @@ int sdhci_add_host(struct sdhci_host *host)
host->version);
}
- caps = readl(host->ioaddr + SDHCI_CAPABILITIES);
+ caps = sdhci_readl(host, SDHCI_CAPABILITIES);
if (host->quirks & SDHCI_QUIRK_FORCE_DMA)
host->flags |= SDHCI_USE_DMA;
@@ -1614,19 +1690,27 @@ int sdhci_add_host(struct sdhci_host *host)
host->max_clk =
(caps & SDHCI_CLOCK_BASE_MASK) >> SDHCI_CLOCK_BASE_SHIFT;
+ host->max_clk *= 1000000;
if (host->max_clk == 0) {
- printk(KERN_ERR "%s: Hardware doesn't specify base clock "
- "frequency.\n", mmc_hostname(mmc));
- return -ENODEV;
+ if (!host->ops->get_max_clock) {
+ printk(KERN_ERR
+ "%s: Hardware doesn't specify base clock "
+ "frequency.\n", mmc_hostname(mmc));
+ return -ENODEV;
+ }
+ host->max_clk = host->ops->get_max_clock(host);
}
- host->max_clk *= 1000000;
host->timeout_clk =
(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
if (host->timeout_clk == 0) {
- printk(KERN_ERR "%s: Hardware doesn't specify timeout clock "
- "frequency.\n", mmc_hostname(mmc));
- return -ENODEV;
+ if (!host->ops->get_timeout_clock) {
+ printk(KERN_ERR
+ "%s: Hardware doesn't specify timeout clock "
+ "frequency.\n", mmc_hostname(mmc));
+ return -ENODEV;
+ }
+ host->timeout_clk = host->ops->get_timeout_clock(host);
}
if (caps & SDHCI_TIMEOUT_CLK_UNIT)
host->timeout_clk *= 1000;
@@ -1642,6 +1726,9 @@ int sdhci_add_host(struct sdhci_host *host)
if (caps & SDHCI_CAN_DO_HISPD)
mmc->caps |= MMC_CAP_SD_HIGHSPEED;
+ if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
+ mmc->caps |= MMC_CAP_NEEDS_POLL;
+
mmc->ocr_avail = 0;
if (caps & SDHCI_CAN_VDD_330)
mmc->ocr_avail |= MMC_VDD_32_33|MMC_VDD_33_34;
@@ -1690,13 +1777,19 @@ int sdhci_add_host(struct sdhci_host *host)
* Maximum block size. This varies from controller to controller and
* is specified in the capabilities register.
*/
- mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT;
- if (mmc->max_blk_size >= 3) {
- printk(KERN_WARNING "%s: Invalid maximum block size, "
- "assuming 512 bytes\n", mmc_hostname(mmc));
- mmc->max_blk_size = 512;
- } else
- mmc->max_blk_size = 512 << mmc->max_blk_size;
+ if (host->quirks & SDHCI_QUIRK_FORCE_BLK_SZ_2048) {
+ mmc->max_blk_size = 2;
+ } else {
+ mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >>
+ SDHCI_MAX_BLOCK_SHIFT;
+ if (mmc->max_blk_size >= 3) {
+ printk(KERN_WARNING "%s: Invalid maximum block size, "
+ "assuming 512 bytes\n", mmc_hostname(mmc));
+ mmc->max_blk_size = 0;
+ }
+ }
+
+ mmc->max_blk_size = 512 << mmc->max_blk_size;
/*
* Maximum block count.
@@ -1746,6 +1839,8 @@ int sdhci_add_host(struct sdhci_host *host)
(host->flags & SDHCI_USE_ADMA)?"A":"",
(host->flags & SDHCI_USE_DMA)?"DMA":"PIO");
+ sdhci_enable_card_detection(host);
+
return 0;
#ifdef SDHCI_USE_LEDS_CLASS
@@ -1782,6 +1877,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
spin_unlock_irqrestore(&host->lock, flags);
}
+ sdhci_disable_card_detection(host);
+
mmc_remove_host(host->mmc);
#ifdef SDHCI_USE_LEDS_CLASS
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 43c37c68d07..f20a834f430 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -10,6 +10,9 @@
*/
#include <linux/scatterlist.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/io.h>
/*
* Controller registers
@@ -123,6 +126,7 @@
SDHCI_INT_DATA_AVAIL | SDHCI_INT_SPACE_AVAIL | \
SDHCI_INT_DATA_TIMEOUT | SDHCI_INT_DATA_CRC | \
SDHCI_INT_DATA_END_BIT)
+#define SDHCI_INT_ALL_MASK ((unsigned int)-1)
#define SDHCI_ACMD12_ERR 0x3C
@@ -210,6 +214,18 @@ struct sdhci_host {
#define SDHCI_QUIRK_BROKEN_SMALL_PIO (1<<13)
/* Controller does not provide transfer-complete interrupt when not busy */
#define SDHCI_QUIRK_NO_BUSY_IRQ (1<<14)
+/* Controller has unreliable card detection */
+#define SDHCI_QUIRK_BROKEN_CARD_DETECTION (1<<15)
+/* Controller reports inverted write-protect state */
+#define SDHCI_QUIRK_INVERTED_WRITE_PROTECT (1<<16)
+/* Controller has nonstandard clock management */
+#define SDHCI_QUIRK_NONSTANDARD_CLOCK (1<<17)
+/* Controller does not like fast PIO transfers */
+#define SDHCI_QUIRK_PIO_NEEDS_DELAY (1<<18)
+/* Controller losing signal/interrupt enable states after reset */
+#define SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET (1<<19)
+/* Controller has to be forced to use block size of 2048 bytes */
+#define SDHCI_QUIRK_FORCE_BLK_SZ_2048 (1<<20)
int irq; /* Device IRQ */
void __iomem * ioaddr; /* Mapped address */
@@ -267,9 +283,105 @@ struct sdhci_host {
struct sdhci_ops {
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+ u32 (*readl)(struct sdhci_host *host, int reg);
+ u16 (*readw)(struct sdhci_host *host, int reg);
+ u8 (*readb)(struct sdhci_host *host, int reg);
+ void (*writel)(struct sdhci_host *host, u32 val, int reg);
+ void (*writew)(struct sdhci_host *host, u16 val, int reg);
+ void (*writeb)(struct sdhci_host *host, u8 val, int reg);
+#endif
+
+ void (*set_clock)(struct sdhci_host *host, unsigned int clock);
+
int (*enable_dma)(struct sdhci_host *host);
+ unsigned int (*get_max_clock)(struct sdhci_host *host);
+ unsigned int (*get_timeout_clock)(struct sdhci_host *host);
};
+#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ if (unlikely(host->ops->writel))
+ host->ops->writel(host, val, reg);
+ else
+ writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ if (unlikely(host->ops->writew))
+ host->ops->writew(host, val, reg);
+ else
+ writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ if (unlikely(host->ops->writeb))
+ host->ops->writeb(host, val, reg);
+ else
+ writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readl))
+ return host->ops->readl(host, reg);
+ else
+ return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readw))
+ return host->ops->readw(host, reg);
+ else
+ return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+ if (unlikely(host->ops->readb))
+ return host->ops->readb(host, reg);
+ else
+ return readb(host->ioaddr + reg);
+}
+
+#else
+
+static inline void sdhci_writel(struct sdhci_host *host, u32 val, int reg)
+{
+ writel(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writew(struct sdhci_host *host, u16 val, int reg)
+{
+ writew(val, host->ioaddr + reg);
+}
+
+static inline void sdhci_writeb(struct sdhci_host *host, u8 val, int reg)
+{
+ writeb(val, host->ioaddr + reg);
+}
+
+static inline u32 sdhci_readl(struct sdhci_host *host, int reg)
+{
+ return readl(host->ioaddr + reg);
+}
+
+static inline u16 sdhci_readw(struct sdhci_host *host, int reg)
+{
+ return readw(host->ioaddr + reg);
+}
+
+static inline u8 sdhci_readb(struct sdhci_host *host, int reg)
+{
+ return readb(host->ioaddr + reg);
+}
+
+#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */
extern struct sdhci_host *sdhci_alloc_host(struct device *dev,
size_t priv_size);
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index 6a7a6190483..63fbd5b7d31 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -568,11 +568,11 @@ static int __devinit tmio_mmc_probe(struct platform_device *dev)
host->mmc = mmc;
platform_set_drvdata(dev, mmc);
- host->ctl = ioremap(res_ctl->start, res_ctl->end - res_ctl->start);
+ host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
if (!host->ctl)
goto host_free;
- host->cnf = ioremap(res_cnf->start, res_cnf->end - res_cnf->start);
+ host->cnf = ioremap(res_cnf->start, resource_size(res_cnf));
if (!host->cnf)
goto unmap_ctl;
@@ -650,10 +650,10 @@ static int __devexit tmio_mmc_remove(struct platform_device *dev)
if (mmc) {
struct tmio_mmc_host *host = mmc_priv(mmc);
mmc_remove_host(mmc);
- mmc_free_host(mmc);
free_irq(host->irq, host);
iounmap(host->ctl);
iounmap(host->cnf);
+ mmc_free_host(mmc);
}
return 0;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index ba2b4240a86..9c831ab2ece 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -8,6 +8,9 @@
* published by the Free Software Foundation.
*
*/
+
+#include <linux/highmem.h>
+
#define CNF_CMD 0x04
#define CNF_CTL_BASE 0x10
#define CNF_INT_PIN 0x3d
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
index 4521b1ecce4..82d1e4de475 100644
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -4,7 +4,7 @@
# Core functionality.
obj-$(CONFIG_MTD) += mtd.o
-mtd-y := mtdcore.o mtdsuper.o
+mtd-y := mtdcore.o mtdsuper.o mtdbdi.o
mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o
obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c
index ecf170b55c3..6697a1ec72d 100644
--- a/drivers/mtd/ar7part.c
+++ b/drivers/mtd/ar7part.c
@@ -44,8 +44,6 @@ struct ar7_bin_rec {
unsigned int address;
};
-static struct mtd_partition ar7_parts[AR7_PARTS];
-
static int create_mtd_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long origin)
@@ -57,7 +55,11 @@ static int create_mtd_partitions(struct mtd_info *master,
unsigned int root_offset = ROOT_OFFSET;
int retries = 10;
+ struct mtd_partition *ar7_parts;
+ ar7_parts = kzalloc(sizeof(*ar7_parts) * AR7_PARTS, GFP_KERNEL);
+ if (!ar7_parts)
+ return -ENOMEM;
ar7_parts[0].name = "loader";
ar7_parts[0].offset = 0;
ar7_parts[0].size = master->erasesize;
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c
index f5ab6fa1057..c240454fd11 100644
--- a/drivers/mtd/chips/cfi_cmdset_0001.c
+++ b/drivers/mtd/chips/cfi_cmdset_0001.c
@@ -1236,10 +1236,14 @@ static int inval_cache_and_wait_for_operation(
remove_wait_queue(&chip->wq, &wait);
spin_lock(chip->mutex);
}
- if (chip->erase_suspended || chip->write_suspended) {
- /* Suspend has occured while sleep: reset timeout */
+ if (chip->erase_suspended && chip_state == FL_ERASING) {
+ /* Erase suspend occured while sleep: reset timeout */
timeo = reset_timeo;
chip->erase_suspended = 0;
+ }
+ if (chip->write_suspended && chip_state == FL_WRITING) {
+ /* Write suspend occured while sleep: reset timeout */
+ timeo = reset_timeo;
chip->write_suspended = 0;
}
}
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
index 94bb61e1904..61ea833e090 100644
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -282,6 +282,16 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param)
}
}
+static void fixup_M29W128G_write_buffer(struct mtd_info *mtd, void *param)
+{
+ struct map_info *map = mtd->priv;
+ struct cfi_private *cfi = map->fldrv_priv;
+ if (cfi->cfiq->BufWriteTimeoutTyp) {
+ pr_warning("Don't use write buffer on ST flash M29W128G\n");
+ cfi->cfiq->BufWriteTimeoutTyp = 0;
+ }
+}
+
static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL },
#ifdef AMD_BOOTLOC_BUG
@@ -298,6 +308,7 @@ static struct cfi_fixup cfi_fixup_table[] = {
{ CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, },
{ CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, },
+ { CFI_MFR_ST, 0x227E, fixup_M29W128G_write_buffer, NULL, },
#if !FORCE_WORD_WRITE
{ CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, },
#endif
diff --git a/drivers/mtd/chips/jedec_probe.c b/drivers/mtd/chips/jedec_probe.c
index 2f3f2f719ba..e824b9b9b05 100644
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -159,6 +159,7 @@
#define SST39LF800 0x2781
#define SST39LF160 0x2782
#define SST39VF1601 0x234b
+#define SST39VF3201 0x235b
#define SST39LF512 0x00D4
#define SST39LF010 0x00D5
#define SST39LF020 0x00D6
@@ -1490,6 +1491,21 @@ static const struct amd_flash_info jedec_table[] = {
ERASEINFO(0x1000,256)
}
}, {
+ .mfr_id = MANUFACTURER_SST, /* should be CFI */
+ .dev_id = SST39VF3201,
+ .name = "SST 39VF3201",
+ .devtypes = CFI_DEVICETYPE_X16,
+ .uaddr = MTD_UADDR_0xAAAA_0x5555,
+ .dev_size = SIZE_4MiB,
+ .cmd_set = P_ID_AMD_STD,
+ .nr_regions = 4,
+ .regions = {
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256),
+ ERASEINFO(0x1000,256)
+ }
+ }, {
.mfr_id = MANUFACTURER_SST,
.dev_id = SST36VF3203,
.name = "SST 36VF3203",
diff --git a/drivers/mtd/chips/map_ram.c b/drivers/mtd/chips/map_ram.c
index 072dd8abf33..6bdc50c727e 100644
--- a/drivers/mtd/chips/map_ram.c
+++ b/drivers/mtd/chips/map_ram.c
@@ -21,6 +21,8 @@ static int mapram_write (struct mtd_info *, loff_t, size_t, size_t *, const u_ch
static int mapram_erase (struct mtd_info *, struct erase_info *);
static void mapram_nop (struct mtd_info *);
static struct mtd_info *map_ram_probe(struct map_info *map);
+static unsigned long mapram_unmapped_area(struct mtd_info *, unsigned long,
+ unsigned long, unsigned long);
static struct mtd_chip_driver mapram_chipdrv = {
@@ -64,6 +66,7 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
mtd->type = MTD_RAM;
mtd->size = map->size;
mtd->erase = mapram_erase;
+ mtd->get_unmapped_area = mapram_unmapped_area;
mtd->read = mapram_read;
mtd->write = mapram_write;
mtd->sync = mapram_nop;
@@ -79,6 +82,20 @@ static struct mtd_info *map_ram_probe(struct map_info *map)
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long mapram_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct map_info *map = mtd->priv;
+ return (unsigned long) map->virt + offset;
+}
+
static int mapram_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
diff --git a/drivers/mtd/chips/map_rom.c b/drivers/mtd/chips/map_rom.c
index c76d6e5f47e..076090a67b9 100644
--- a/drivers/mtd/chips/map_rom.c
+++ b/drivers/mtd/chips/map_rom.c
@@ -20,6 +20,8 @@ static int maprom_write (struct mtd_info *, loff_t, size_t, size_t *, const u_ch
static void maprom_nop (struct mtd_info *);
static struct mtd_info *map_rom_probe(struct map_info *map);
static int maprom_erase (struct mtd_info *mtd, struct erase_info *info);
+static unsigned long maprom_unmapped_area(struct mtd_info *, unsigned long,
+ unsigned long, unsigned long);
static struct mtd_chip_driver maprom_chipdrv = {
.probe = map_rom_probe,
@@ -40,6 +42,7 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
mtd->name = map->name;
mtd->type = MTD_ROM;
mtd->size = map->size;
+ mtd->get_unmapped_area = maprom_unmapped_area;
mtd->read = maprom_read;
mtd->write = maprom_write;
mtd->sync = maprom_nop;
@@ -53,6 +56,20 @@ static struct mtd_info *map_rom_probe(struct map_info *map)
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long maprom_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct map_info *map = mtd->priv;
+ return (unsigned long) map->virt + offset;
+}
+
static int maprom_read (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf)
{
struct map_info *map = mtd->priv;
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c
index 50a340388e7..5011fa73f91 100644
--- a/drivers/mtd/cmdlinepart.c
+++ b/drivers/mtd/cmdlinepart.c
@@ -335,7 +335,11 @@ static int parse_cmdline_partitions(struct mtd_info *master,
}
offset += part->parts[i].size;
}
- *pparts = part->parts;
+ *pparts = kmemdup(part->parts,
+ sizeof(*part->parts) * part->num_parts,
+ GFP_KERNEL);
+ if (!*pparts)
+ return -ENOMEM;
return part->num_parts;
}
}
diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c
index 50de839c77a..5bf5f460e13 100644
--- a/drivers/mtd/devices/doc2000.c
+++ b/drivers/mtd/devices/doc2000.c
@@ -10,7 +10,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/sched.h>
diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c
index e32c568c114..0990f780362 100644
--- a/drivers/mtd/devices/doc2001.c
+++ b/drivers/mtd/devices/doc2001.c
@@ -10,7 +10,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c
index d853f891b58..719b2915dc3 100644
--- a/drivers/mtd/devices/doc2001plus.c
+++ b/drivers/mtd/devices/doc2001plus.c
@@ -14,7 +14,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c
index 874e51b110a..a19cda52da5 100644
--- a/drivers/mtd/devices/docecc.c
+++ b/drivers/mtd/devices/docecc.c
@@ -26,7 +26,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 7c3fc766dcf..8185b1f3e5e 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -65,12 +65,6 @@
#define FAST_READ_DUMMY_BYTE 0
#endif
-#ifdef CONFIG_MTD_PARTITIONS
-#define mtd_has_partitions() (1)
-#else
-#define mtd_has_partitions() (0)
-#endif
-
/****************************************************************************/
struct m25p {
@@ -678,6 +672,8 @@ static int __devinit m25p_probe(struct spi_device *spi)
flash->mtd.erasesize = info->sector_size;
}
+ flash->mtd.dev.parent = &spi->dev;
+
dev_info(&spi->dev, "%s (%lld Kbytes)\n", info->name,
(long long)flash->mtd.size >> 10);
@@ -708,12 +704,13 @@ static int __devinit m25p_probe(struct spi_device *spi)
struct mtd_partition *parts = NULL;
int nr_parts = 0;
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- static const char *part_probes[] = { "cmdlinepart", NULL, };
+ if (mtd_has_cmdlinepart()) {
+ static const char *part_probes[]
+ = { "cmdlinepart", NULL, };
- nr_parts = parse_mtd_partitions(&flash->mtd,
- part_probes, &parts, 0);
-#endif
+ nr_parts = parse_mtd_partitions(&flash->mtd,
+ part_probes, &parts, 0);
+ }
if (nr_parts <= 0 && data && data->parts) {
parts = data->parts;
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index 6d9f810565c..62dee54af0a 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -98,12 +98,6 @@ struct dataflash {
struct mtd_info mtd;
};
-#ifdef CONFIG_MTD_PARTITIONS
-#define mtd_has_partitions() (1)
-#else
-#define mtd_has_partitions() (0)
-#endif
-
/* ......................................................................... */
/*
@@ -670,6 +664,8 @@ add_dataflash_otp(struct spi_device *spi, char *name,
device->write = dataflash_write;
device->priv = priv;
+ device->dev.parent = &spi->dev;
+
if (revision >= 'c')
otp_tag = otp_setup(device, revision);
@@ -682,11 +678,13 @@ add_dataflash_otp(struct spi_device *spi, char *name,
struct mtd_partition *parts;
int nr_parts = 0;
-#ifdef CONFIG_MTD_CMDLINE_PARTS
- static const char *part_probes[] = { "cmdlinepart", NULL, };
+ if (mtd_has_cmdlinepart()) {
+ static const char *part_probes[]
+ = { "cmdlinepart", NULL, };
- nr_parts = parse_mtd_partitions(device, part_probes, &parts, 0);
-#endif
+ nr_parts = parse_mtd_partitions(device,
+ part_probes, &parts, 0);
+ }
if (nr_parts <= 0 && pdata && pdata->parts) {
parts = pdata->parts;
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c
index 3aaca88847d..fce5ff7589a 100644
--- a/drivers/mtd/devices/mtdram.c
+++ b/drivers/mtd/devices/mtdram.c
@@ -65,6 +65,19 @@ static void ram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
{
}
+/*
+ * Allow NOMMU mmap() to directly map the device (if not NULL)
+ * - return the address to which the offset maps
+ * - return -ENOSYS to indicate refusal to do the mapping
+ */
+static unsigned long ram_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ return (unsigned long) mtd->priv + offset;
+}
+
static int ram_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
@@ -116,6 +129,7 @@ int mtdram_init_device(struct mtd_info *mtd, void *mapped_address,
mtd->erase = ram_erase;
mtd->point = ram_point;
mtd->unpoint = ram_unpoint;
+ mtd->get_unmapped_area = ram_get_unmapped_area;
mtd->read = ram_read;
mtd->write = ram_write;
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c
index f751dd97c54..32e82aef3e5 100644
--- a/drivers/mtd/inftlmount.c
+++ b/drivers/mtd/inftlmount.c
@@ -28,7 +28,6 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
diff --git a/drivers/mtd/internal.h b/drivers/mtd/internal.h
new file mode 100644
index 00000000000..c658fe7216b
--- /dev/null
+++ b/drivers/mtd/internal.h
@@ -0,0 +1,17 @@
+/* Internal MTD definitions
+ *
+ * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * mtdbdi.c
+ */
+extern struct backing_dev_info mtd_bdi_unmappable;
+extern struct backing_dev_info mtd_bdi_ro_mappable;
+extern struct backing_dev_info mtd_bdi_rw_mappable;
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
index 729f899a5cd..82923bd2d9c 100644
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -529,12 +529,6 @@ config MTD_DMV182
help
Map driver for Dy-4 SVME/DMV-182 board.
-config MTD_SHARP_SL
- tristate "ROM mapped on Sharp SL Series"
- depends on ARCH_PXA
- help
- This enables access to the flash chip on the Sharp SL Series of PDAs.
-
config MTD_INTEL_VR_NOR
tristate "NOR flash on Intel Vermilion Range Expansion Bus CS0"
depends on PCI
@@ -542,6 +536,12 @@ config MTD_INTEL_VR_NOR
Map driver for a NOR flash bank located on the Expansion Bus of the
Intel Vermilion Range chipset.
+config MTD_RBTX4939
+ tristate "Map driver for RBTX4939 board"
+ depends on TOSHIBA_RBTX4939 && MTD_CFI && MTD_COMPLEX_MAPPINGS
+ help
+ Map driver for NOR flash chips on RBTX4939 board.
+
config MTD_PLATRAM
tristate "Map driver for platform device RAM (mtd-ram)"
select MTD_RAM
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
index 26b28a7a90b..2dbc1bec848 100644
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -56,9 +56,9 @@ obj-$(CONFIG_MTD_IXP4XX) += ixp4xx.o
obj-$(CONFIG_MTD_IXP2000) += ixp2000.o
obj-$(CONFIG_MTD_WRSBC8260) += wr_sbc82xx_flash.o
obj-$(CONFIG_MTD_DMV182) += dmv182.o
-obj-$(CONFIG_MTD_SHARP_SL) += sharpsl-flash.o
obj-$(CONFIG_MTD_PLATRAM) += plat-ram.o
obj-$(CONFIG_MTD_OMAP_NOR) += omap_nor.o
obj-$(CONFIG_MTD_INTEL_VR_NOR) += intel_vr_nor.o
obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-async-flash.o
+obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
obj-$(CONFIG_MTD_VMU) += vmu-flash.o
diff --git a/drivers/mtd/maps/omap_nor.c b/drivers/mtd/maps/omap_nor.c
index 7e50e9b1b78..a24478102b1 100644
--- a/drivers/mtd/maps/omap_nor.c
+++ b/drivers/mtd/maps/omap_nor.c
@@ -115,6 +115,8 @@ static int __init omapflash_probe(struct platform_device *pdev)
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &pdev->dev;
+
#ifdef CONFIG_MTD_PARTITIONS
err = parse_mtd_partitions(info->mtd, part_probes, &info->parts, 0);
if (err > 0)
diff --git a/drivers/mtd/maps/physmap.c b/drivers/mtd/maps/physmap.c
index 229718222db..29a90115735 100644
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -147,6 +147,7 @@ static int physmap_flash_probe(struct platform_device *dev)
devices_found++;
}
info->mtd[i]->owner = THIS_MODULE;
+ info->mtd[i]->dev.parent = &dev->dev;
}
if (devices_found == 1) {
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c
index fbf0ca939d7..c83a60fada5 100644
--- a/drivers/mtd/maps/physmap_of.c
+++ b/drivers/mtd/maps/physmap_of.c
@@ -219,6 +219,7 @@ static int __devinit of_flash_probe(struct of_device *dev,
goto err_out;
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &dev->dev;
#ifdef CONFIG_MTD_PARTITIONS
/* First look for RedBoot table or partitions on the command
diff --git a/drivers/mtd/maps/plat-ram.c b/drivers/mtd/maps/plat-ram.c
index e7dd9c8a965..49c9ece7647 100644
--- a/drivers/mtd/maps/plat-ram.c
+++ b/drivers/mtd/maps/plat-ram.c
@@ -224,6 +224,7 @@ static int platram_probe(struct platform_device *pdev)
}
info->mtd->owner = THIS_MODULE;
+ info->mtd->dev.parent = &pdev->dev;
platram_setrw(info, PLATRAM_RW);
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c
index e9026cb1c5b..572d32fdf38 100644
--- a/drivers/mtd/maps/pxa2xx-flash.c
+++ b/drivers/mtd/maps/pxa2xx-flash.c
@@ -117,7 +117,7 @@ static int __init pxa2xx_flash_probe(struct platform_device *pdev)
return 0;
}
-static int __exit pxa2xx_flash_remove(struct platform_device *dev)
+static int __devexit pxa2xx_flash_remove(struct platform_device *dev)
{
struct pxa2xx_flash_info *info = platform_get_drvdata(dev);
diff --git a/drivers/mtd/maps/rbtx4939-flash.c b/drivers/mtd/maps/rbtx4939-flash.c
new file mode 100644
index 00000000000..d39f0adac84
--- /dev/null
+++ b/drivers/mtd/maps/rbtx4939-flash.c
@@ -0,0 +1,208 @@
+/*
+ * rbtx4939-flash (based on physmap.c)
+ *
+ * This is a simplified physmap driver with map_init callback function.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copyright (C) 2009 Atsushi Nemoto <anemo@mba.ocn.ne.jp>
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <asm/txx9/rbtx4939.h>
+
+struct rbtx4939_flash_info {
+ struct mtd_info *mtd;
+ struct map_info map;
+#ifdef CONFIG_MTD_PARTITIONS
+ int nr_parts;
+ struct mtd_partition *parts;
+#endif
+};
+
+static int rbtx4939_flash_remove(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info;
+
+ info = platform_get_drvdata(dev);
+ if (!info)
+ return 0;
+ platform_set_drvdata(dev, NULL);
+
+ if (info->mtd) {
+#ifdef CONFIG_MTD_PARTITIONS
+ struct rbtx4939_flash_data *pdata = dev->dev.platform_data;
+
+ if (info->nr_parts) {
+ del_mtd_partitions(info->mtd);
+ kfree(info->parts);
+ } else if (pdata->nr_parts)
+ del_mtd_partitions(info->mtd);
+ else
+ del_mtd_device(info->mtd);
+#else
+ del_mtd_device(info->mtd);
+#endif
+ map_destroy(info->mtd);
+ }
+ return 0;
+}
+
+static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probe_types[] = { "cmdlinepart", NULL };
+#endif
+
+static int rbtx4939_flash_probe(struct platform_device *dev)
+{
+ struct rbtx4939_flash_data *pdata;
+ struct rbtx4939_flash_info *info;
+ struct resource *res;
+ const char **probe_type;
+ int err = 0;
+ unsigned long size;
+
+ pdata = dev->dev.platform_data;
+ if (!pdata)
+ return -ENODEV;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ info = devm_kzalloc(&dev->dev, sizeof(struct rbtx4939_flash_info),
+ GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ platform_set_drvdata(dev, info);
+
+ size = resource_size(res);
+ pr_notice("rbtx4939 platform flash device: %pR\n", res);
+
+ if (!devm_request_mem_region(&dev->dev, res->start, size,
+ dev_name(&dev->dev)))
+ return -EBUSY;
+
+ info->map.name = dev_name(&dev->dev);
+ info->map.phys = res->start;
+ info->map.size = size;
+ info->map.bankwidth = pdata->width;
+
+ info->map.virt = devm_ioremap(&dev->dev, info->map.phys, size);
+ if (!info->map.virt)
+ return -EBUSY;
+
+ if (pdata->map_init)
+ (*pdata->map_init)(&info->map);
+ else
+ simple_map_init(&info->map);
+
+ probe_type = rom_probe_types;
+ for (; !info->mtd && *probe_type; probe_type++)
+ info->mtd = do_map_probe(*probe_type, &info->map);
+ if (!info->mtd) {
+ dev_err(&dev->dev, "map_probe failed\n");
+ err = -ENXIO;
+ goto err_out;
+ }
+ info->mtd->owner = THIS_MODULE;
+ if (err)
+ goto err_out;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ err = parse_mtd_partitions(info->mtd, part_probe_types,
+ &info->parts, 0);
+ if (err > 0) {
+ add_mtd_partitions(info->mtd, info->parts, err);
+ info->nr_parts = err;
+ return 0;
+ }
+
+ if (pdata->nr_parts) {
+ pr_notice("Using rbtx4939 partition information\n");
+ add_mtd_partitions(info->mtd, pdata->parts, pdata->nr_parts);
+ return 0;
+ }
+#endif
+
+ add_mtd_device(info->mtd);
+ return 0;
+
+err_out:
+ rbtx4939_flash_remove(dev);
+ return err;
+}
+
+#ifdef CONFIG_PM
+static int rbtx4939_flash_suspend(struct platform_device *dev,
+ pm_message_t state)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->suspend)
+ return info->mtd->suspend(info->mtd);
+ return 0;
+}
+
+static int rbtx4939_flash_resume(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->resume)
+ info->mtd->resume(info->mtd);
+ return 0;
+}
+
+static void rbtx4939_flash_shutdown(struct platform_device *dev)
+{
+ struct rbtx4939_flash_info *info = platform_get_drvdata(dev);
+
+ if (info->mtd->suspend && info->mtd->resume)
+ if (info->mtd->suspend(info->mtd) == 0)
+ info->mtd->resume(info->mtd);
+}
+#else
+#define rbtx4939_flash_suspend NULL
+#define rbtx4939_flash_resume NULL
+#define rbtx4939_flash_shutdown NULL
+#endif
+
+static struct platform_driver rbtx4939_flash_driver = {
+ .probe = rbtx4939_flash_probe,
+ .remove = rbtx4939_flash_remove,
+ .suspend = rbtx4939_flash_suspend,
+ .resume = rbtx4939_flash_resume,
+ .shutdown = rbtx4939_flash_shutdown,
+ .driver = {
+ .name = "rbtx4939-flash",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init rbtx4939_flash_init(void)
+{
+ return platform_driver_register(&rbtx4939_flash_driver);
+}
+
+static void __exit rbtx4939_flash_exit(void)
+{
+ platform_driver_unregister(&rbtx4939_flash_driver);
+}
+
+module_init(rbtx4939_flash_init);
+module_exit(rbtx4939_flash_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("RBTX4939 MTD map driver");
+MODULE_ALIAS("platform:rbtx4939-flash");
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c
index 8f57b6f40aa..05e9362dc7f 100644
--- a/drivers/mtd/maps/sa1100-flash.c
+++ b/drivers/mtd/maps/sa1100-flash.c
@@ -351,7 +351,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat)
static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL };
-static int __init sa1100_mtd_probe(struct platform_device *pdev)
+static int __devinit sa1100_mtd_probe(struct platform_device *pdev)
{
struct flash_platform_data *plat = pdev->dev.platform_data;
struct mtd_partition *parts;
diff --git a/drivers/mtd/maps/sharpsl-flash.c b/drivers/mtd/maps/sharpsl-flash.c
deleted file mode 100644
index b392f096c70..00000000000
--- a/drivers/mtd/maps/sharpsl-flash.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * sharpsl-flash.c
- *
- * Copyright (C) 2001 Lineo Japan, Inc.
- * Copyright (C) 2002 SHARP
- *
- * based on rpxlite.c,v 1.15 2001/10/02 15:05:14 dwmw2 Exp
- * Handle mapping of the flash on the RPX Lite and CLLF boards
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/map.h>
-#include <linux/mtd/partitions.h>
-#include <asm/io.h>
-#include <asm/mach-types.h>
-
-#define WINDOW_ADDR 0x00000000
-#define WINDOW_SIZE 0x00800000
-#define BANK_WIDTH 2
-
-static struct mtd_info *mymtd;
-
-struct map_info sharpsl_map = {
- .name = "sharpsl-flash",
- .size = WINDOW_SIZE,
- .bankwidth = BANK_WIDTH,
- .phys = WINDOW_ADDR
-};
-
-static struct mtd_partition sharpsl_partitions[1] = {
- {
- name: "Boot PROM Filesystem",
- }
-};
-
-static int __init init_sharpsl(void)
-{
- struct mtd_partition *parts;
- int nb_parts = 0;
- char *part_type = "static";
-
- printk(KERN_NOTICE "Sharp SL series flash device: %x at %x\n",
- WINDOW_SIZE, WINDOW_ADDR);
- sharpsl_map.virt = ioremap(WINDOW_ADDR, WINDOW_SIZE);
- if (!sharpsl_map.virt) {
- printk("Failed to ioremap\n");
- return -EIO;
- }
-
- simple_map_init(&sharpsl_map);
-
- mymtd = do_map_probe("map_rom", &sharpsl_map);
- if (!mymtd) {
- iounmap(sharpsl_map.virt);
- return -ENXIO;
- }
-
- mymtd->owner = THIS_MODULE;
-
- if (machine_is_corgi() || machine_is_shepherd() || machine_is_husky()
- || machine_is_poodle()) {
- sharpsl_partitions[0].size=0x006d0000;
- sharpsl_partitions[0].offset=0x00120000;
- } else if (machine_is_tosa()) {
- sharpsl_partitions[0].size=0x006a0000;
- sharpsl_partitions[0].offset=0x00160000;
- } else if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi()) {
- sharpsl_partitions[0].size=0x006b0000;
- sharpsl_partitions[0].offset=0x00140000;
- } else {
- map_destroy(mymtd);
- iounmap(sharpsl_map.virt);
- return -ENODEV;
- }
-
- parts = sharpsl_partitions;
- nb_parts = ARRAY_SIZE(sharpsl_partitions);
-
- printk(KERN_NOTICE "Using %s partition definition\n", part_type);
- add_mtd_partitions(mymtd, parts, nb_parts);
-
- return 0;
-}
-
-static void __exit cleanup_sharpsl(void)
-{
- if (mymtd) {
- del_mtd_partitions(mymtd);
- map_destroy(mymtd);
- }
- if (sharpsl_map.virt) {
- iounmap(sharpsl_map.virt);
- sharpsl_map.virt = 0;
- }
-}
-
-module_init(init_sharpsl);
-module_exit(cleanup_sharpsl);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("SHARP (Original: Arnold Christensen <AKC@pel.dk>)");
-MODULE_DESCRIPTION("MTD map driver for SHARP SL series");
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 1409f01406f..a49a9c8f2cb 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -286,6 +286,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
gd->private_data = new;
new->blkcore_priv = gd;
gd->queue = tr->blkcore_priv->rq;
+ gd->driverfs_dev = new->mtd->dev.parent;
if (new->readonly)
set_disk_ro(gd, 1);
@@ -382,11 +383,12 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
tr->blkcore_priv->thread = kthread_run(mtd_blktrans_thread, tr,
"%sd", tr->name);
if (IS_ERR(tr->blkcore_priv->thread)) {
+ int ret = PTR_ERR(tr->blkcore_priv->thread);
blk_cleanup_queue(tr->blkcore_priv->rq);
unregister_blkdev(tr->major, tr->name);
kfree(tr->blkcore_priv);
mutex_unlock(&mtd_table_mutex);
- return PTR_ERR(tr->blkcore_priv->thread);
+ return ret;
}
INIT_LIST_HEAD(&tr->devs);
diff --git a/drivers/mtd/mtdbdi.c b/drivers/mtd/mtdbdi.c
new file mode 100644
index 00000000000..5ca5aed0b22
--- /dev/null
+++ b/drivers/mtd/mtdbdi.c
@@ -0,0 +1,43 @@
+/* MTD backing device capabilities
+ *
+ * Copyright © 2006 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/backing-dev.h>
+#include <linux/mtd/mtd.h>
+#include "internal.h"
+
+/*
+ * backing device capabilities for non-mappable devices (such as NAND flash)
+ * - permits private mappings, copies are taken of the data
+ */
+struct backing_dev_info mtd_bdi_unmappable = {
+ .capabilities = BDI_CAP_MAP_COPY,
+};
+
+/*
+ * backing device capabilities for R/O mappable devices (such as ROM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_ro_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP),
+};
+
+/*
+ * backing device capabilities for writable mappable devices (such as RAM)
+ * - permits private mappings, copies are taken of the data
+ * - permits non-writable shared mappings
+ */
+struct backing_dev_info mtd_bdi_rw_mappable = {
+ .capabilities = (BDI_CAP_MAP_COPY | BDI_CAP_MAP_DIRECT |
+ BDI_CAP_EXEC_MAP | BDI_CAP_READ_MAP |
+ BDI_CAP_WRITE_MAP),
+};
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e9ec59e9a56..763d3f0a1f4 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -13,39 +13,13 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/smp_lock.h>
+#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/compatmac.h>
#include <asm/uaccess.h>
-static struct class *mtd_class;
-
-static void mtd_notify_add(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
-
- device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
- NULL, "mtd%d", mtd->index);
-
- device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
- NULL, "mtd%dro", mtd->index);
-}
-
-static void mtd_notify_remove(struct mtd_info* mtd)
-{
- if (!mtd)
- return;
-
- device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2));
- device_destroy(mtd_class, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1));
-}
-
-static struct mtd_notifier notifier = {
- .add = mtd_notify_add,
- .remove = mtd_notify_remove,
-};
/*
* Data structure to hold the pointer to the mtd device as well
@@ -107,12 +81,15 @@ static int mtd_open(struct inode *inode, struct file *file)
goto out;
}
- if (MTD_ABSENT == mtd->type) {
+ if (mtd->type == MTD_ABSENT) {
put_mtd_device(mtd);
ret = -ENODEV;
goto out;
}
+ if (mtd->backing_dev_info)
+ file->f_mapping->backing_dev_info = mtd->backing_dev_info;
+
/* You can't open it RW if it's not a writeable device */
if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) {
put_mtd_device(mtd);
@@ -781,6 +758,59 @@ static int mtd_ioctl(struct inode *inode, struct file *file,
return ret;
} /* memory_ioctl */
+/*
+ * try to determine where a shared mapping can be made
+ * - only supported for NOMMU at the moment (MMU can't doesn't copy private
+ * mappings)
+ */
+#ifndef CONFIG_MMU
+static unsigned long mtd_get_unmapped_area(struct file *file,
+ unsigned long addr,
+ unsigned long len,
+ unsigned long pgoff,
+ unsigned long flags)
+{
+ struct mtd_file_info *mfi = file->private_data;
+ struct mtd_info *mtd = mfi->mtd;
+
+ if (mtd->get_unmapped_area) {
+ unsigned long offset;
+
+ if (addr != 0)
+ return (unsigned long) -EINVAL;
+
+ if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
+ return (unsigned long) -EINVAL;
+
+ offset = pgoff << PAGE_SHIFT;
+ if (offset > mtd->size - len)
+ return (unsigned long) -EINVAL;
+
+ return mtd->get_unmapped_area(mtd, len, offset, flags);
+ }
+
+ /* can't map directly */
+ return (unsigned long) -ENOSYS;
+}
+#endif
+
+/*
+ * set up a mapping for shared memory segments
+ */
+static int mtd_mmap(struct file *file, struct vm_area_struct *vma)
+{
+#ifdef CONFIG_MMU
+ struct mtd_file_info *mfi = file->private_data;
+ struct mtd_info *mtd = mfi->mtd;
+
+ if (mtd->type == MTD_RAM || mtd->type == MTD_ROM)
+ return 0;
+ return -ENOSYS;
+#else
+ return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
+#endif
+}
+
static const struct file_operations mtd_fops = {
.owner = THIS_MODULE,
.llseek = mtd_lseek,
@@ -789,39 +819,36 @@ static const struct file_operations mtd_fops = {
.ioctl = mtd_ioctl,
.open = mtd_open,
.release = mtd_close,
+ .mmap = mtd_mmap,
+#ifndef CONFIG_MMU
+ .get_unmapped_area = mtd_get_unmapped_area,
+#endif
};
static int __init init_mtdchar(void)
{
- if (register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops)) {
+ int status;
+
+ status = register_chrdev(MTD_CHAR_MAJOR, "mtd", &mtd_fops);
+ if (status < 0) {
printk(KERN_NOTICE "Can't allocate major number %d for Memory Technology Devices.\n",
MTD_CHAR_MAJOR);
- return -EAGAIN;
}
- mtd_class = class_create(THIS_MODULE, "mtd");
-
- if (IS_ERR(mtd_class)) {
- printk(KERN_ERR "Error creating mtd class.\n");
- unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
- return PTR_ERR(mtd_class);
- }
-
- register_mtd_user(&notifier);
- return 0;
+ return status;
}
static void __exit cleanup_mtdchar(void)
{
- unregister_mtd_user(&notifier);
- class_destroy(mtd_class);
unregister_chrdev(MTD_CHAR_MAJOR, "mtd");
}
module_init(init_mtdchar);
module_exit(cleanup_mtdchar);
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_DESCRIPTION("Direct character-device access to MTD devices");
+MODULE_ALIAS_CHARDEV_MAJOR(MTD_CHAR_MAJOR);
diff --git a/drivers/mtd/mtdconcat.c b/drivers/mtd/mtdconcat.c
index 3dbb1b38db6..792b547786b 100644
--- a/drivers/mtd/mtdconcat.c
+++ b/drivers/mtd/mtdconcat.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/types.h>
+#include <linux/backing-dev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/concat.h>
@@ -684,6 +685,40 @@ static int concat_block_markbad(struct mtd_info *mtd, loff_t ofs)
}
/*
+ * try to support NOMMU mmaps on concatenated devices
+ * - we don't support subdev spanning as we can't guarantee it'll work
+ */
+static unsigned long concat_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct mtd_concat *concat = CONCAT(mtd);
+ int i;
+
+ for (i = 0; i < concat->num_subdev; i++) {
+ struct mtd_info *subdev = concat->subdev[i];
+
+ if (offset >= subdev->size) {
+ offset -= subdev->size;
+ continue;
+ }
+
+ /* we've found the subdev over which the mapping will reside */
+ if (offset + len > subdev->size)
+ return (unsigned long) -EINVAL;
+
+ if (subdev->get_unmapped_area)
+ return subdev->get_unmapped_area(subdev, len, offset,
+ flags);
+
+ break;
+ }
+
+ return (unsigned long) -ENOSYS;
+}
+
+/*
* This function constructs a virtual MTD device by concatenating
* num_devs MTD devices. A pointer to the new device object is
* stored to *new_dev upon success. This function does _not_
@@ -740,6 +775,8 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.ecc_stats.badblocks = subdev[0]->ecc_stats.badblocks;
+ concat->mtd.backing_dev_info = subdev[0]->backing_dev_info;
+
concat->subdev[0] = subdev[0];
for (i = 1; i < num_devs; i++) {
@@ -766,6 +803,15 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.flags |=
subdev[i]->flags & MTD_WRITEABLE;
}
+
+ /* only permit direct mapping if the BDIs are all the same
+ * - copy-mapping is still permitted
+ */
+ if (concat->mtd.backing_dev_info !=
+ subdev[i]->backing_dev_info)
+ concat->mtd.backing_dev_info =
+ &default_backing_dev_info;
+
concat->mtd.size += subdev[i]->size;
concat->mtd.ecc_stats.badblocks +=
subdev[i]->ecc_stats.badblocks;
@@ -796,6 +842,7 @@ struct mtd_info *mtd_concat_create(struct mtd_info *subdev[], /* subdevices to c
concat->mtd.unlock = concat_unlock;
concat->mtd.suspend = concat_suspend;
concat->mtd.resume = concat_resume;
+ concat->mtd.get_unmapped_area = concat_get_unmapped_area;
/*
* Combine the erase block size info of the subdevices:
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 76fe0a1e7a5..fdd6ae85939 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -19,9 +19,13 @@
#include <linux/proc_fs.h>
#include <linux/mtd/mtd.h>
+#include "internal.h"
#include "mtdcore.h"
+
+static struct class *mtd_class;
+
/* These are exported solely for the purpose of mtd_blkdevs.c. You
should not use them for _anything_ else */
DEFINE_MUTEX(mtd_table_mutex);
@@ -32,6 +36,160 @@ EXPORT_SYMBOL_GPL(mtd_table);
static LIST_HEAD(mtd_notifiers);
+
+#if defined(CONFIG_MTD_CHAR) || defined(CONFIG_MTD_CHAR_MODULE)
+#define MTD_DEVT(index) MKDEV(MTD_CHAR_MAJOR, (index)*2)
+#else
+#define MTD_DEVT(index) 0
+#endif
+
+/* REVISIT once MTD uses the driver model better, whoever allocates
+ * the mtd_info will probably want to use the release() hook...
+ */
+static void mtd_release(struct device *dev)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ /* remove /dev/mtdXro node if needed */
+ if (MTD_DEVT(mtd->index))
+ device_destroy(mtd_class, MTD_DEVT(mtd->index) + 1);
+}
+
+static ssize_t mtd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+ char *type;
+
+ switch (mtd->type) {
+ case MTD_ABSENT:
+ type = "absent";
+ break;
+ case MTD_RAM:
+ type = "ram";
+ break;
+ case MTD_ROM:
+ type = "rom";
+ break;
+ case MTD_NORFLASH:
+ type = "nor";
+ break;
+ case MTD_NANDFLASH:
+ type = "nand";
+ break;
+ case MTD_DATAFLASH:
+ type = "dataflash";
+ break;
+ case MTD_UBIVOLUME:
+ type = "ubi";
+ break;
+ default:
+ type = "unknown";
+ }
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", type);
+}
+static DEVICE_ATTR(type, S_IRUGO, mtd_type_show, NULL);
+
+static ssize_t mtd_flags_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "0x%lx\n", (unsigned long)mtd->flags);
+
+}
+static DEVICE_ATTR(flags, S_IRUGO, mtd_flags_show, NULL);
+
+static ssize_t mtd_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%llu\n",
+ (unsigned long long)mtd->size);
+
+}
+static DEVICE_ATTR(size, S_IRUGO, mtd_size_show, NULL);
+
+static ssize_t mtd_erasesize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->erasesize);
+
+}
+static DEVICE_ATTR(erasesize, S_IRUGO, mtd_erasesize_show, NULL);
+
+static ssize_t mtd_writesize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->writesize);
+
+}
+static DEVICE_ATTR(writesize, S_IRUGO, mtd_writesize_show, NULL);
+
+static ssize_t mtd_oobsize_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n", (unsigned long)mtd->oobsize);
+
+}
+static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL);
+
+static ssize_t mtd_numeraseregions_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%u\n", mtd->numeraseregions);
+
+}
+static DEVICE_ATTR(numeraseregions, S_IRUGO, mtd_numeraseregions_show,
+ NULL);
+
+static ssize_t mtd_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mtd_info *mtd = dev_to_mtd(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n", mtd->name);
+
+}
+static DEVICE_ATTR(name, S_IRUGO, mtd_name_show, NULL);
+
+static struct attribute *mtd_attrs[] = {
+ &dev_attr_type.attr,
+ &dev_attr_flags.attr,
+ &dev_attr_size.attr,
+ &dev_attr_erasesize.attr,
+ &dev_attr_writesize.attr,
+ &dev_attr_oobsize.attr,
+ &dev_attr_numeraseregions.attr,
+ &dev_attr_name.attr,
+ NULL,
+};
+
+struct attribute_group mtd_group = {
+ .attrs = mtd_attrs,
+};
+
+struct attribute_group *mtd_groups[] = {
+ &mtd_group,
+ NULL,
+};
+
+static struct device_type mtd_devtype = {
+ .name = "mtd",
+ .groups = mtd_groups,
+ .release = mtd_release,
+};
+
/**
* add_mtd_device - register an MTD device
* @mtd: pointer to new MTD device info structure
@@ -40,12 +198,27 @@ static LIST_HEAD(mtd_notifiers);
* notify each currently active MTD 'user' of its arrival. Returns
* zero on success or 1 on failure, which currently will only happen
* if the number of present devices exceeds MAX_MTD_DEVICES (i.e. 16)
+ * or there's a sysfs error.
*/
int add_mtd_device(struct mtd_info *mtd)
{
int i;
+ if (!mtd->backing_dev_info) {
+ switch (mtd->type) {
+ case MTD_RAM:
+ mtd->backing_dev_info = &mtd_bdi_rw_mappable;
+ break;
+ case MTD_ROM:
+ mtd->backing_dev_info = &mtd_bdi_ro_mappable;
+ break;
+ default:
+ mtd->backing_dev_info = &mtd_bdi_unmappable;
+ break;
+ }
+ }
+
BUG_ON(mtd->writesize == 0);
mutex_lock(&mtd_table_mutex);
@@ -80,6 +253,23 @@ int add_mtd_device(struct mtd_info *mtd)
mtd->name);
}
+ /* Caller should have set dev.parent to match the
+ * physical device.
+ */
+ mtd->dev.type = &mtd_devtype;
+ mtd->dev.class = mtd_class;
+ mtd->dev.devt = MTD_DEVT(i);
+ dev_set_name(&mtd->dev, "mtd%d", i);
+ if (device_register(&mtd->dev) != 0) {
+ mtd_table[i] = NULL;
+ break;
+ }
+
+ if (MTD_DEVT(i))
+ device_create(mtd_class, mtd->dev.parent,
+ MTD_DEVT(i) + 1,
+ NULL, "mtd%dro", i);
+
DEBUG(0, "mtd: Giving out device %d to %s\n",i, mtd->name);
/* No need to get a refcount on the module containing
the notifier, since we hold the mtd_table_mutex */
@@ -124,6 +314,8 @@ int del_mtd_device (struct mtd_info *mtd)
} else {
struct mtd_notifier *not;
+ device_unregister(&mtd->dev);
+
/* No need to get a refcount on the module containing
the notifier, since we hold the mtd_table_mutex */
list_for_each_entry(not, &mtd_notifiers, list)
@@ -393,28 +585,38 @@ done:
return ((count < begin+len-off) ? count : begin+len-off);
}
+#endif /* CONFIG_PROC_FS */
+
/*====================================================================*/
/* Init code */
static int __init init_mtd(void)
{
+ mtd_class = class_create(THIS_MODULE, "mtd");
+
+ if (IS_ERR(mtd_class)) {
+ pr_err("Error creating mtd class.\n");
+ return PTR_ERR(mtd_class);
+ }
+#ifdef CONFIG_PROC_FS
if ((proc_mtd = create_proc_entry( "mtd", 0, NULL )))
proc_mtd->read_proc = mtd_read_proc;
+#endif /* CONFIG_PROC_FS */
return 0;
}
static void __exit cleanup_mtd(void)
{
+#ifdef CONFIG_PROC_FS
if (proc_mtd)
remove_proc_entry( "mtd", NULL);
+#endif /* CONFIG_PROC_FS */
+ class_destroy(mtd_class);
}
module_init(init_mtd);
module_exit(cleanup_mtd);
-#endif /* CONFIG_PROC_FS */
-
-
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
MODULE_DESCRIPTION("Core MTD registration and access routines");
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c
index 1a6b3beabe8..1060337c06d 100644
--- a/drivers/mtd/mtdoops.c
+++ b/drivers/mtd/mtdoops.c
@@ -44,6 +44,7 @@ static struct mtdoops_context {
int oops_pages;
int nextpage;
int nextcount;
+ char *name;
void *oops_buf;
@@ -273,6 +274,9 @@ static void mtdoops_notify_add(struct mtd_info *mtd)
{
struct mtdoops_context *cxt = &oops_cxt;
+ if (cxt->name && !strcmp(mtd->name, cxt->name))
+ cxt->mtd_index = mtd->index;
+
if ((mtd->index != cxt->mtd_index) || cxt->mtd_index < 0)
return;
@@ -357,8 +361,10 @@ mtdoops_console_write(struct console *co, const char *s, unsigned int count)
spin_lock_irqsave(&cxt->writecount_lock, flags);
/* Check ready status didn't change whilst waiting for the lock */
- if (!cxt->ready)
+ if (!cxt->ready) {
+ spin_unlock_irqrestore(&cxt->writecount_lock, flags);
return;
+ }
if (cxt->writecount == 0) {
u32 *stamp = cxt->oops_buf;
@@ -383,8 +389,12 @@ static int __init mtdoops_console_setup(struct console *co, char *options)
{
struct mtdoops_context *cxt = co->data;
- if (cxt->mtd_index != -1)
+ if (cxt->mtd_index != -1 || cxt->name)
return -EBUSY;
+ if (options) {
+ cxt->name = kstrdup(options, GFP_KERNEL);
+ return 0;
+ }
if (co->index == -1)
return -EINVAL;
@@ -412,6 +422,7 @@ static int __init mtdoops_console_init(void)
cxt->mtd_index = -1;
cxt->oops_buf = vmalloc(OOPS_PAGE_SIZE);
+ spin_lock_init(&cxt->writecount_lock);
if (!cxt->oops_buf) {
printk(KERN_ERR "Failed to allocate mtdoops buffer workspace\n");
@@ -432,6 +443,7 @@ static void __exit mtdoops_console_exit(void)
unregister_mtd_user(&mtdoops_notifier);
unregister_console(&mtdoops_console);
+ kfree(cxt->name);
vfree(cxt->oops_buf);
}
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 144e6b613a7..29675edb44b 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -48,8 +48,11 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
size_t *retlen, u_char *buf)
{
struct mtd_part *part = PART(mtd);
+ struct mtd_ecc_stats stats;
int res;
+ stats = part->master->ecc_stats;
+
if (from >= mtd->size)
len = 0;
else if (from + len > mtd->size)
@@ -58,9 +61,9 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len,
len, retlen, buf);
if (unlikely(res)) {
if (res == -EUCLEAN)
- mtd->ecc_stats.corrected++;
+ mtd->ecc_stats.corrected += part->master->ecc_stats.corrected - stats.corrected;
if (res == -EBADMSG)
- mtd->ecc_stats.failed++;
+ mtd->ecc_stats.failed += part->master->ecc_stats.failed - stats.failed;
}
return res;
}
@@ -84,6 +87,18 @@ static void part_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
part->master->unpoint(part->master, from + part->offset, len);
}
+static unsigned long part_get_unmapped_area(struct mtd_info *mtd,
+ unsigned long len,
+ unsigned long offset,
+ unsigned long flags)
+{
+ struct mtd_part *part = PART(mtd);
+
+ offset += part->offset;
+ return part->master->get_unmapped_area(part->master, len, offset,
+ flags);
+}
+
static int part_read_oob(struct mtd_info *mtd, loff_t from,
struct mtd_oob_ops *ops)
{
@@ -342,6 +357,12 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave->mtd.name = part->name;
slave->mtd.owner = master->owner;
+ slave->mtd.backing_dev_info = master->backing_dev_info;
+
+ /* NOTE: we don't arrange MTDs as a tree; it'd be error-prone
+ * to have the same data be in two different partitions.
+ */
+ slave->mtd.dev.parent = master->dev.parent;
slave->mtd.read = part_read;
slave->mtd.write = part_write;
@@ -354,6 +375,8 @@ static struct mtd_part *add_one_partition(struct mtd_info *master,
slave->mtd.unpoint = part_unpoint;
}
+ if (master->get_unmapped_area)
+ slave->mtd.get_unmapped_area = part_get_unmapped_area;
if (master->read_oob)
slave->mtd.read_oob = part_read_oob;
if (master->write_oob)
@@ -493,7 +516,9 @@ out_register:
* This function, given a master MTD object and a partition table, creates
* and registers slave MTD objects which are bound to the master according to
* the partition definitions.
- * (Q: should we register the master MTD object as well?)
+ *
+ * We don't register the master, or expect the caller to have done so,
+ * for reasons of data integrity.
*/
int add_mtd_partitions(struct mtd_info *master,
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index 2ff88791ceb..890936d0275 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -334,7 +334,7 @@ config MTD_NAND_ATMEL_ECC_NONE
endchoice
config MTD_NAND_PXA3xx
- bool "Support for NAND flash devices on PXA3xx"
+ tristate "Support for NAND flash devices on PXA3xx"
depends on MTD_NAND && PXA3xx
help
This enables the driver for the NAND flash device found on
@@ -427,4 +427,23 @@ config MTD_NAND_SH_FLCTL
Several Renesas SuperH CPU has FLCTL. This option enables support
for NAND Flash using FLCTL. This driver support SH7723.
+config MTD_NAND_DAVINCI
+ tristate "Support NAND on DaVinci SoC"
+ depends on ARCH_DAVINCI
+ help
+ Enable the driver for NAND flash chips on Texas Instruments
+ DaVinci processors.
+
+config MTD_NAND_TXX9NDFMC
+ tristate "NAND Flash support for TXx9 SoC"
+ depends on SOC_TX4938 || SOC_TX4939
+ help
+ This enables the NAND flash controller on the TXx9 SoCs.
+
+config MTD_NAND_SOCRATES
+ tristate "Support for NAND on Socrates board"
+ depends on MTD_NAND && SOCRATES
+ help
+ Enables support for NAND Flash chips wired onto Socrates board.
+
endif # MTD_NAND
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index b661586afbf..d33860ac42c 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o
obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o
+obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o
obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o
obj-$(CONFIG_MTD_NAND_H1900) += h1910.o
obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o
@@ -36,5 +37,7 @@ obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o
obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o
obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o
obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o
+obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o
+obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o
nand-objs := nand_base.o nand_bbt.o
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c
index 9af2a2cc115..4c2a67ca801 100644
--- a/drivers/mtd/nand/bf5xx_nand.c
+++ b/drivers/mtd/nand/bf5xx_nand.c
@@ -552,7 +552,6 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
{
int ret;
- unsigned short val;
/* Do not use dma */
if (!hardware_ecc)
@@ -560,13 +559,6 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
init_completion(&info->dma_completion);
-#ifdef CONFIG_BF54x
- /* Setup DMAC1 channel mux for NFC which shared with SDH */
- val = bfin_read_DMAC1_PERIMUX();
- val &= 0xFFFE;
- bfin_write_DMAC1_PERIMUX(val);
- SSYNC();
-#endif
/* Request NFC DMA channel */
ret = request_dma(CH_NFC, "BF5XX NFC driver");
if (ret < 0) {
@@ -574,7 +566,13 @@ static int bf5xx_nand_dma_init(struct bf5xx_nand_info *info)
return ret;
}
- set_dma_callback(CH_NFC, (void *) bf5xx_nand_dma_irq, (void *) info);
+#ifdef CONFIG_BF54x
+ /* Setup DMAC1 channel mux for NFC which shared with SDH */
+ bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() & ~1);
+ SSYNC();
+#endif
+
+ set_dma_callback(CH_NFC, bf5xx_nand_dma_irq, info);
/* Turn off the DMA channel first */
disable_dma(CH_NFC);
@@ -632,7 +630,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info)
/*
* Device management interface
*/
-static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
+static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info)
{
struct mtd_info *mtd = &info->mtd;
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c
index 22a6b2e50e9..7c5b257ce8e 100644
--- a/drivers/mtd/nand/cafe_nand.c
+++ b/drivers/mtd/nand/cafe_nand.c
@@ -654,6 +654,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev,
}
cafe = (void *)(&mtd[1]);
+ mtd->dev.parent = &pdev->dev;
mtd->priv = cafe;
mtd->owner = THIS_MODULE;
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c
new file mode 100644
index 00000000000..0119220de7d
--- /dev/null
+++ b/drivers/mtd/nand/davinci_nand.c
@@ -0,0 +1,570 @@
+/*
+ * davinci_nand.c - NAND Flash Driver for DaVinci family chips
+ *
+ * Copyright © 2006 Texas Instruments.
+ *
+ * Port to 2.6.23 Copyright © 2008 by:
+ * Sander Huijsen <Shuijsen@optelecom-nkf.com>
+ * Troy Kisky <troy.kisky@boundarydevices.com>
+ * Dirk Behme <Dirk.Behme@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <mach/nand.h>
+
+#include <asm/mach-types.h>
+
+
+/*
+ * This is a device driver for the NAND flash controller found on the
+ * various DaVinci family chips. It handles up to four SoC chipselects,
+ * and some flavors of secondary chipselect (e.g. based on A12) as used
+ * with multichip packages.
+ *
+ * The 1-bit ECC hardware is supported, but not yet the newer 4-bit ECC
+ * available on chips like the DM355 and OMAP-L137 and needed with the
+ * more error-prone MLC NAND chips.
+ *
+ * This driver assumes EM_WAIT connects all the NAND devices' RDY/nBUSY
+ * outputs in a "wire-AND" configuration, with no per-chip signals.
+ */
+struct davinci_nand_info {
+ struct mtd_info mtd;
+ struct nand_chip chip;
+
+ struct device *dev;
+ struct clk *clk;
+ bool partitioned;
+
+ void __iomem *base;
+ void __iomem *vaddr;
+
+ uint32_t ioaddr;
+ uint32_t current_cs;
+
+ uint32_t mask_chipsel;
+ uint32_t mask_ale;
+ uint32_t mask_cle;
+
+ uint32_t core_chipsel;
+};
+
+static DEFINE_SPINLOCK(davinci_nand_lock);
+
+#define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd)
+
+
+static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info,
+ int offset)
+{
+ return __raw_readl(info->base + offset);
+}
+
+static inline void davinci_nand_writel(struct davinci_nand_info *info,
+ int offset, unsigned long value)
+{
+ __raw_writel(value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Access to hardware control lines: ALE, CLE, secondary chipselect.
+ */
+
+static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+ uint32_t addr = info->current_cs;
+ struct nand_chip *nand = mtd->priv;
+
+ /* Did the control lines change? */
+ if (ctrl & NAND_CTRL_CHANGE) {
+ if ((ctrl & NAND_CTRL_CLE) == NAND_CTRL_CLE)
+ addr |= info->mask_cle;
+ else if ((ctrl & NAND_CTRL_ALE) == NAND_CTRL_ALE)
+ addr |= info->mask_ale;
+
+ nand->IO_ADDR_W = (void __iomem __force *)addr;
+ }
+
+ if (cmd != NAND_CMD_NONE)
+ iowrite8(cmd, nand->IO_ADDR_W);
+}
+
+static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+ uint32_t addr = info->ioaddr;
+
+ /* maybe kick in a second chipselect */
+ if (chip > 0)
+ addr |= info->mask_chipsel;
+ info->current_cs = addr;
+
+ info->chip.IO_ADDR_W = (void __iomem __force *)addr;
+ info->chip.IO_ADDR_R = info->chip.IO_ADDR_W;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * 1-bit hardware ECC ... context maintained for each core chipselect
+ */
+
+static inline uint32_t nand_davinci_readecc_1bit(struct mtd_info *mtd)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+ return davinci_nand_readl(info, NANDF1ECC_OFFSET
+ + 4 * info->core_chipsel);
+}
+
+static void nand_davinci_hwctl_1bit(struct mtd_info *mtd, int mode)
+{
+ struct davinci_nand_info *info;
+ uint32_t nandcfr;
+ unsigned long flags;
+
+ info = to_davinci_nand(mtd);
+
+ /* Reset ECC hardware */
+ nand_davinci_readecc_1bit(mtd);
+
+ spin_lock_irqsave(&davinci_nand_lock, flags);
+
+ /* Restart ECC hardware */
+ nandcfr = davinci_nand_readl(info, NANDFCR_OFFSET);
+ nandcfr |= BIT(8 + info->core_chipsel);
+ davinci_nand_writel(info, NANDFCR_OFFSET, nandcfr);
+
+ spin_unlock_irqrestore(&davinci_nand_lock, flags);
+}
+
+/*
+ * Read hardware ECC value and pack into three bytes
+ */
+static int nand_davinci_calculate_1bit(struct mtd_info *mtd,
+ const u_char *dat, u_char *ecc_code)
+{
+ unsigned int ecc_val = nand_davinci_readecc_1bit(mtd);
+ unsigned int ecc24 = (ecc_val & 0x0fff) | ((ecc_val & 0x0fff0000) >> 4);
+
+ /* invert so that erased block ecc is correct */
+ ecc24 = ~ecc24;
+ ecc_code[0] = (u_char)(ecc24);
+ ecc_code[1] = (u_char)(ecc24 >> 8);
+ ecc_code[2] = (u_char)(ecc24 >> 16);
+
+ return 0;
+}
+
+static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ struct nand_chip *chip = mtd->priv;
+ uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) |
+ (read_ecc[2] << 16);
+ uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) |
+ (calc_ecc[2] << 16);
+ uint32_t diff = eccCalc ^ eccNand;
+
+ if (diff) {
+ if ((((diff >> 12) ^ diff) & 0xfff) == 0xfff) {
+ /* Correctable error */
+ if ((diff >> (12 + 3)) < chip->ecc.size) {
+ dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7);
+ return 1;
+ } else {
+ return -1;
+ }
+ } else if (!(diff & (diff - 1))) {
+ /* Single bit ECC error in the ECC itself,
+ * nothing to fix */
+ return 1;
+ } else {
+ /* Uncorrectable error */
+ return -1;
+ }
+
+ }
+ return 0;
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * NOTE: NAND boot requires ALE == EM_A[1], CLE == EM_A[2], so that's
+ * how these chips are normally wired. This translates to both 8 and 16
+ * bit busses using ALE == BIT(3) in byte addresses, and CLE == BIT(4).
+ *
+ * For now we assume that configuration, or any other one which ignores
+ * the two LSBs for NAND access ... so we can issue 32-bit reads/writes
+ * and have that transparently morphed into multiple NAND operations.
+ */
+static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+ ioread32_rep(chip->IO_ADDR_R, buf, len >> 2);
+ else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+ ioread16_rep(chip->IO_ADDR_R, buf, len >> 1);
+ else
+ ioread8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+static void nand_davinci_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0)
+ iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2);
+ else if ((0x01 & ((unsigned)buf)) == 0 && (0x01 & len) == 0)
+ iowrite16_rep(chip->IO_ADDR_R, buf, len >> 1);
+ else
+ iowrite8_rep(chip->IO_ADDR_R, buf, len);
+}
+
+/*
+ * Check hardware register for wait status. Returns 1 if device is ready,
+ * 0 if it is still busy.
+ */
+static int nand_davinci_dev_ready(struct mtd_info *mtd)
+{
+ struct davinci_nand_info *info = to_davinci_nand(mtd);
+
+ return davinci_nand_readl(info, NANDFSR_OFFSET) & BIT(0);
+}
+
+static void __init nand_dm6446evm_flash_init(struct davinci_nand_info *info)
+{
+ uint32_t regval, a1cr;
+
+ /*
+ * NAND FLASH timings @ PLL1 == 459 MHz
+ * - AEMIF.CLK freq = PLL1/6 = 459/6 = 76.5 MHz
+ * - AEMIF.CLK period = 1/76.5 MHz = 13.1 ns
+ */
+ regval = 0
+ | (0 << 31) /* selectStrobe */
+ | (0 << 30) /* extWait (never with NAND) */
+ | (1 << 26) /* writeSetup 10 ns */
+ | (3 << 20) /* writeStrobe 40 ns */
+ | (1 << 17) /* writeHold 10 ns */
+ | (0 << 13) /* readSetup 10 ns */
+ | (3 << 7) /* readStrobe 60 ns */
+ | (0 << 4) /* readHold 10 ns */
+ | (3 << 2) /* turnAround ?? ns */
+ | (0 << 0) /* asyncSize 8-bit bus */
+ ;
+ a1cr = davinci_nand_readl(info, A1CR_OFFSET);
+ if (a1cr != regval) {
+ dev_dbg(info->dev, "Warning: NAND config: Set A1CR " \
+ "reg to 0x%08x, was 0x%08x, should be done by " \
+ "bootloader.\n", regval, a1cr);
+ davinci_nand_writel(info, A1CR_OFFSET, regval);
+ }
+}
+
+/*----------------------------------------------------------------------*/
+
+static int __init nand_davinci_probe(struct platform_device *pdev)
+{
+ struct davinci_nand_pdata *pdata = pdev->dev.platform_data;
+ struct davinci_nand_info *info;
+ struct resource *res1;
+ struct resource *res2;
+ void __iomem *vaddr;
+ void __iomem *base;
+ int ret;
+ uint32_t val;
+ nand_ecc_modes_t ecc_mode;
+
+ /* which external chipselect will we be managing? */
+ if (pdev->id < 0 || pdev->id > 3)
+ return -ENODEV;
+
+ info = kzalloc(sizeof(*info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "unable to allocate memory\n");
+ ret = -ENOMEM;
+ goto err_nomem;
+ }
+
+ platform_set_drvdata(pdev, info);
+
+ res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res1 || !res2) {
+ dev_err(&pdev->dev, "resource missing\n");
+ ret = -EINVAL;
+ goto err_nomem;
+ }
+
+ vaddr = ioremap(res1->start, res1->end - res1->start);
+ base = ioremap(res2->start, res2->end - res2->start);
+ if (!vaddr || !base) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -EINVAL;
+ goto err_ioremap;
+ }
+
+ info->dev = &pdev->dev;
+ info->base = base;
+ info->vaddr = vaddr;
+
+ info->mtd.priv = &info->chip;
+ info->mtd.name = dev_name(&pdev->dev);
+ info->mtd.owner = THIS_MODULE;
+
+ info->mtd.dev.parent = &pdev->dev;
+
+ info->chip.IO_ADDR_R = vaddr;
+ info->chip.IO_ADDR_W = vaddr;
+ info->chip.chip_delay = 0;
+ info->chip.select_chip = nand_davinci_select_chip;
+
+ /* options such as NAND_USE_FLASH_BBT or 16-bit widths */
+ info->chip.options = pdata ? pdata->options : 0;
+
+ info->ioaddr = (uint32_t __force) vaddr;
+
+ info->current_cs = info->ioaddr;
+ info->core_chipsel = pdev->id;
+ info->mask_chipsel = pdata->mask_chipsel;
+
+ /* use nandboot-capable ALE/CLE masks by default */
+ if (pdata && pdata->mask_ale)
+ info->mask_ale = pdata->mask_cle;
+ else
+ info->mask_ale = MASK_ALE;
+ if (pdata && pdata->mask_cle)
+ info->mask_cle = pdata->mask_cle;
+ else
+ info->mask_cle = MASK_CLE;
+
+ /* Set address of hardware control function */
+ info->chip.cmd_ctrl = nand_davinci_hwcontrol;
+ info->chip.dev_ready = nand_davinci_dev_ready;
+
+ /* Speed up buffer I/O */
+ info->chip.read_buf = nand_davinci_read_buf;
+ info->chip.write_buf = nand_davinci_write_buf;
+
+ /* use board-specific ECC config; else, the best available */
+ if (pdata)
+ ecc_mode = pdata->ecc_mode;
+ else
+ ecc_mode = NAND_ECC_HW;
+
+ switch (ecc_mode) {
+ case NAND_ECC_NONE:
+ case NAND_ECC_SOFT:
+ break;
+ case NAND_ECC_HW:
+ info->chip.ecc.calculate = nand_davinci_calculate_1bit;
+ info->chip.ecc.correct = nand_davinci_correct_1bit;
+ info->chip.ecc.hwctl = nand_davinci_hwctl_1bit;
+ info->chip.ecc.size = 512;
+ info->chip.ecc.bytes = 3;
+ break;
+ case NAND_ECC_HW_SYNDROME:
+ /* FIXME implement */
+ info->chip.ecc.size = 512;
+ info->chip.ecc.bytes = 10;
+
+ dev_warn(&pdev->dev, "4-bit ECC nyet supported\n");
+ /* FALL THROUGH */
+ default:
+ ret = -EINVAL;
+ goto err_ecc;
+ }
+ info->chip.ecc.mode = ecc_mode;
+
+ info->clk = clk_get(&pdev->dev, "AEMIFCLK");
+ if (IS_ERR(info->clk)) {
+ ret = PTR_ERR(info->clk);
+ dev_dbg(&pdev->dev, "unable to get AEMIFCLK, err %d\n", ret);
+ goto err_clk;
+ }
+
+ ret = clk_enable(info->clk);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "unable to enable AEMIFCLK, err %d\n", ret);
+ goto err_clk_enable;
+ }
+
+ /* EMIF timings should normally be set by the boot loader,
+ * especially after boot-from-NAND. The *only* reason to
+ * have this special casing for the DM6446 EVM is to work
+ * with boot-from-NOR ... with CS0 manually re-jumpered
+ * (after startup) so it addresses the NAND flash, not NOR.
+ * Even for dev boards, that's unusually rude...
+ */
+ if (machine_is_davinci_evm())
+ nand_dm6446evm_flash_init(info);
+
+ spin_lock_irq(&davinci_nand_lock);
+
+ /* put CSxNAND into NAND mode */
+ val = davinci_nand_readl(info, NANDFCR_OFFSET);
+ val |= BIT(info->core_chipsel);
+ davinci_nand_writel(info, NANDFCR_OFFSET, val);
+
+ spin_unlock_irq(&davinci_nand_lock);
+
+ /* Scan to find existence of the device(s) */
+ ret = nand_scan(&info->mtd, pdata->mask_chipsel ? 2 : 1);
+ if (ret < 0) {
+ dev_dbg(&pdev->dev, "no NAND chip(s) found\n");
+ goto err_scan;
+ }
+
+ if (mtd_has_partitions()) {
+ struct mtd_partition *mtd_parts = NULL;
+ int mtd_parts_nb = 0;
+
+ if (mtd_has_cmdlinepart()) {
+ static const char *probes[] __initconst =
+ { "cmdlinepart", NULL };
+
+ const char *master_name;
+
+ /* Set info->mtd.name = 0 temporarily */
+ master_name = info->mtd.name;
+ info->mtd.name = (char *)0;
+
+ /* info->mtd.name == 0, means: don't bother checking
+ <mtd-id> */
+ mtd_parts_nb = parse_mtd_partitions(&info->mtd, probes,
+ &mtd_parts, 0);
+
+ /* Restore info->mtd.name */
+ info->mtd.name = master_name;
+ }
+
+ if (mtd_parts_nb <= 0 && pdata) {
+ mtd_parts = pdata->parts;
+ mtd_parts_nb = pdata->nr_parts;
+ }
+
+ /* Register any partitions */
+ if (mtd_parts_nb > 0) {
+ ret = add_mtd_partitions(&info->mtd,
+ mtd_parts, mtd_parts_nb);
+ if (ret == 0)
+ info->partitioned = true;
+ }
+
+ } else if (pdata && pdata->nr_parts) {
+ dev_warn(&pdev->dev, "ignoring %d default partitions on %s\n",
+ pdata->nr_parts, info->mtd.name);
+ }
+
+ /* If there's no partition info, just package the whole chip
+ * as a single MTD device.
+ */
+ if (!info->partitioned)
+ ret = add_mtd_device(&info->mtd) ? -ENODEV : 0;
+
+ if (ret < 0)
+ goto err_scan;
+
+ val = davinci_nand_readl(info, NRCSR_OFFSET);
+ dev_info(&pdev->dev, "controller rev. %d.%d\n",
+ (val >> 8) & 0xff, val & 0xff);
+
+ return 0;
+
+err_scan:
+ clk_disable(info->clk);
+
+err_clk_enable:
+ clk_put(info->clk);
+
+err_ecc:
+err_clk:
+err_ioremap:
+ if (base)
+ iounmap(base);
+ if (vaddr)
+ iounmap(vaddr);
+
+err_nomem:
+ kfree(info);
+ return ret;
+}
+
+static int __exit nand_davinci_remove(struct platform_device *pdev)
+{
+ struct davinci_nand_info *info = platform_get_drvdata(pdev);
+ int status;
+
+ if (mtd_has_partitions() && info->partitioned)
+ status = del_mtd_partitions(&info->mtd);
+ else
+ status = del_mtd_device(&info->mtd);
+
+ iounmap(info->base);
+ iounmap(info->vaddr);
+
+ nand_release(&info->mtd);
+
+ clk_disable(info->clk);
+ clk_put(info->clk);
+
+ kfree(info);
+
+ return 0;
+}
+
+static struct platform_driver nand_davinci_driver = {
+ .remove = __exit_p(nand_davinci_remove),
+ .driver = {
+ .name = "davinci_nand",
+ },
+};
+MODULE_ALIAS("platform:davinci_nand");
+
+static int __init nand_davinci_init(void)
+{
+ return platform_driver_probe(&nand_davinci_driver, nand_davinci_probe);
+}
+module_init(nand_davinci_init);
+
+static void __exit nand_davinci_exit(void)
+{
+ platform_driver_unregister(&nand_davinci_driver);
+}
+module_exit(nand_davinci_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Texas Instruments");
+MODULE_DESCRIPTION("Davinci NAND flash driver");
+
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c
index e4226e02d63..e51c1ed7ac1 100644
--- a/drivers/mtd/nand/diskonchip.c
+++ b/drivers/mtd/nand/diskonchip.c
@@ -1773,4 +1773,4 @@ module_exit(cleanup_nanddoc);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver\n");
+MODULE_DESCRIPTION("M-Systems DiskOnChip 2000, Millennium and Millennium Plus device driver");
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 7815a404a63..d120cd8d726 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -23,6 +23,10 @@
#include <linux/io.h>
#include <asm/fsl_lbc.h>
+#define FSL_UPM_WAIT_RUN_PATTERN 0x1
+#define FSL_UPM_WAIT_WRITE_BYTE 0x2
+#define FSL_UPM_WAIT_WRITE_BUFFER 0x4
+
struct fsl_upm_nand {
struct device *dev;
struct mtd_info mtd;
@@ -36,8 +40,12 @@ struct fsl_upm_nand {
uint8_t upm_addr_offset;
uint8_t upm_cmd_offset;
void __iomem *io_base;
- int rnb_gpio;
+ int rnb_gpio[NAND_MAX_CHIPS];
+ uint32_t mchip_offsets[NAND_MAX_CHIPS];
+ uint32_t mchip_count;
+ uint32_t mchip_number;
int chip_delay;
+ uint32_t wait_flags;
};
#define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd)
@@ -46,7 +54,7 @@ static int fun_chip_ready(struct mtd_info *mtd)
{
struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
- if (gpio_get_value(fun->rnb_gpio))
+ if (gpio_get_value(fun->rnb_gpio[fun->mchip_number]))
return 1;
dev_vdbg(fun->dev, "busy\n");
@@ -55,9 +63,9 @@ static int fun_chip_ready(struct mtd_info *mtd)
static void fun_wait_rnb(struct fsl_upm_nand *fun)
{
- int cnt = 1000000;
+ if (fun->rnb_gpio[fun->mchip_number] >= 0) {
+ int cnt = 1000000;
- if (fun->rnb_gpio >= 0) {
while (--cnt && !fun_chip_ready(&fun->mtd))
cpu_relax();
if (!cnt)
@@ -69,7 +77,9 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun)
static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
+ struct nand_chip *chip = mtd->priv;
struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
+ u32 mar;
if (!(ctrl & fun->last_ctrl)) {
fsl_upm_end_pattern(&fun->upm);
@@ -87,9 +97,28 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
}
- fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd);
+ mar = (cmd << (32 - fun->upm.width)) |
+ fun->mchip_offsets[fun->mchip_number];
+ fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar);
+
+ if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN)
+ fun_wait_rnb(fun);
+}
+
+static void fun_select_chip(struct mtd_info *mtd, int mchip_nr)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd);
- fun_wait_rnb(fun);
+ if (mchip_nr == -1) {
+ chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
+ } else if (mchip_nr >= 0) {
+ fun->mchip_number = mchip_nr;
+ chip->IO_ADDR_R = fun->io_base + fun->mchip_offsets[mchip_nr];
+ chip->IO_ADDR_W = chip->IO_ADDR_R;
+ } else {
+ BUG();
+ }
}
static uint8_t fun_read_byte(struct mtd_info *mtd)
@@ -115,8 +144,11 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
for (i = 0; i < len; i++) {
out_8(fun->chip.IO_ADDR_W, buf[i]);
- fun_wait_rnb(fun);
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE)
+ fun_wait_rnb(fun);
}
+ if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER)
+ fun_wait_rnb(fun);
}
static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
@@ -137,8 +169,10 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
fun->chip.read_buf = fun_read_buf;
fun->chip.write_buf = fun_write_buf;
fun->chip.ecc.mode = NAND_ECC_SOFT;
+ if (fun->mchip_count > 1)
+ fun->chip.select_chip = fun_select_chip;
- if (fun->rnb_gpio >= 0)
+ if (fun->rnb_gpio[0] >= 0)
fun->chip.dev_ready = fun_chip_ready;
fun->mtd.priv = &fun->chip;
@@ -155,7 +189,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun,
goto err;
}
- ret = nand_scan(&fun->mtd, 1);
+ ret = nand_scan(&fun->mtd, fun->mchip_count);
if (ret)
goto err;
@@ -185,8 +219,10 @@ static int __devinit fun_probe(struct of_device *ofdev,
struct fsl_upm_nand *fun;
struct resource io_res;
const uint32_t *prop;
+ int rnb_gpio;
int ret;
int size;
+ int i;
fun = kzalloc(sizeof(*fun), GFP_KERNEL);
if (!fun)
@@ -208,7 +244,7 @@ static int __devinit fun_probe(struct of_device *ofdev,
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM address offset\n");
ret = -EINVAL;
- goto err2;
+ goto err1;
}
fun->upm_addr_offset = *prop;
@@ -216,21 +252,40 @@ static int __devinit fun_probe(struct of_device *ofdev,
if (!prop || size != sizeof(uint32_t)) {
dev_err(&ofdev->dev, "can't get UPM command offset\n");
ret = -EINVAL;
- goto err2;
+ goto err1;
}
fun->upm_cmd_offset = *prop;
- fun->rnb_gpio = of_get_gpio(ofdev->node, 0);
- if (fun->rnb_gpio >= 0) {
- ret = gpio_request(fun->rnb_gpio, dev_name(&ofdev->dev));
- if (ret) {
- dev_err(&ofdev->dev, "can't request RNB gpio\n");
+ prop = of_get_property(ofdev->node,
+ "fsl,upm-addr-line-cs-offsets", &size);
+ if (prop && (size / sizeof(uint32_t)) > 0) {
+ fun->mchip_count = size / sizeof(uint32_t);
+ if (fun->mchip_count >= NAND_MAX_CHIPS) {
+ dev_err(&ofdev->dev, "too much multiple chips\n");
+ goto err1;
+ }
+ for (i = 0; i < fun->mchip_count; i++)
+ fun->mchip_offsets[i] = prop[i];
+ } else {
+ fun->mchip_count = 1;
+ }
+
+ for (i = 0; i < fun->mchip_count; i++) {
+ fun->rnb_gpio[i] = -1;
+ rnb_gpio = of_get_gpio(ofdev->node, i);
+ if (rnb_gpio >= 0) {
+ ret = gpio_request(rnb_gpio, dev_name(&ofdev->dev));
+ if (ret) {
+ dev_err(&ofdev->dev,
+ "can't request RNB gpio #%d\n", i);
+ goto err2;
+ }
+ gpio_direction_input(rnb_gpio);
+ fun->rnb_gpio[i] = rnb_gpio;
+ } else if (rnb_gpio == -EINVAL) {
+ dev_err(&ofdev->dev, "RNB gpio #%d is invalid\n", i);
goto err2;
}
- gpio_direction_input(fun->rnb_gpio);
- } else if (fun->rnb_gpio == -EINVAL) {
- dev_err(&ofdev->dev, "specified RNB gpio is invalid\n");
- goto err2;
}
prop = of_get_property(ofdev->node, "chip-delay", NULL);
@@ -239,8 +294,15 @@ static int __devinit fun_probe(struct of_device *ofdev,
else
fun->chip_delay = 50;
+ prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size);
+ if (prop && size == sizeof(uint32_t))
+ fun->wait_flags = *prop;
+ else
+ fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN |
+ FSL_UPM_WAIT_WRITE_BYTE;
+
fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start,
- io_res.end - io_res.start + 1);
+ io_res.end - io_res.start + 1);
if (!fun->io_base) {
ret = -ENOMEM;
goto err2;
@@ -257,8 +319,11 @@ static int __devinit fun_probe(struct of_device *ofdev,
return 0;
err2:
- if (fun->rnb_gpio >= 0)
- gpio_free(fun->rnb_gpio);
+ for (i = 0; i < fun->mchip_count; i++) {
+ if (fun->rnb_gpio[i] < 0)
+ break;
+ gpio_free(fun->rnb_gpio[i]);
+ }
err1:
kfree(fun);
@@ -268,12 +333,16 @@ err1:
static int __devexit fun_remove(struct of_device *ofdev)
{
struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev);
+ int i;
nand_release(&fun->mtd);
kfree(fun->mtd.name);
- if (fun->rnb_gpio >= 0)
- gpio_free(fun->rnb_gpio);
+ for (i = 0; i < fun->mchip_count; i++) {
+ if (fun->rnb_gpio[i] < 0)
+ break;
+ gpio_free(fun->rnb_gpio[i]);
+ }
kfree(fun);
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index bad048aca89..f3548d04801 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -866,6 +866,7 @@ static int __init mxcnd_probe(struct platform_device *pdev)
mtd = &host->mtd;
mtd->priv = this;
mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &pdev->dev;
/* 50 us command delay time */
this->chip_delay = 5;
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 0c3afccde8a..3d7ed432fa4 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -82,6 +82,20 @@ static struct nand_ecclayout nand_oob_64 = {
.length = 38}}
};
+static struct nand_ecclayout nand_oob_128 = {
+ .eccbytes = 48,
+ .eccpos = {
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127},
+ .oobfree = {
+ {.offset = 2,
+ .length = 78}}
+};
+
static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
int new_state);
@@ -748,6 +762,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip)
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: buffer to store read data
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
uint8_t *buf)
@@ -758,6 +774,47 @@ static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
}
/**
+ * nand_read_page_raw_syndrome - [Intern] read raw page data without ecc
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: buffer to store read data
+ *
+ * We need a special oob layout and handling even when OOB isn't used.
+ */
+static int nand_read_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+ uint8_t *buf)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint8_t *oob = chip->oob_poi;
+ int steps, size;
+
+ for (steps = chip->ecc.steps; steps > 0; steps--) {
+ chip->read_buf(mtd, buf, eccsize);
+ buf += eccsize;
+
+ if (chip->ecc.prepad) {
+ chip->read_buf(mtd, oob, chip->ecc.prepad);
+ oob += chip->ecc.prepad;
+ }
+
+ chip->read_buf(mtd, oob, eccbytes);
+ oob += eccbytes;
+
+ if (chip->ecc.postpad) {
+ chip->read_buf(mtd, oob, chip->ecc.postpad);
+ oob += chip->ecc.postpad;
+ }
+ }
+
+ size = mtd->oobsize - (oob - chip->oob_poi);
+ if (size)
+ chip->read_buf(mtd, oob, size);
+
+ return 0;
+}
+
+/**
* nand_read_page_swecc - [REPLACABLE] software ecc based page read function
* @mtd: mtd info structure
* @chip: nand chip info structure
@@ -1482,6 +1539,8 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from,
* @mtd: mtd info structure
* @chip: nand chip info structure
* @buf: data buffer
+ *
+ * Not for syndrome calculating ecc controllers, which use a special oob layout
*/
static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
const uint8_t *buf)
@@ -1491,6 +1550,44 @@ static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
}
/**
+ * nand_write_page_raw_syndrome - [Intern] raw page write function
+ * @mtd: mtd info structure
+ * @chip: nand chip info structure
+ * @buf: data buffer
+ *
+ * We need a special oob layout and handling even when ECC isn't checked.
+ */
+static void nand_write_page_raw_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
+ const uint8_t *buf)
+{
+ int eccsize = chip->ecc.size;
+ int eccbytes = chip->ecc.bytes;
+ uint8_t *oob = chip->oob_poi;
+ int steps, size;
+
+ for (steps = chip->ecc.steps; steps > 0; steps--) {
+ chip->write_buf(mtd, buf, eccsize);
+ buf += eccsize;
+
+ if (chip->ecc.prepad) {
+ chip->write_buf(mtd, oob, chip->ecc.prepad);
+ oob += chip->ecc.prepad;
+ }
+
+ chip->read_buf(mtd, oob, eccbytes);
+ oob += eccbytes;
+
+ if (chip->ecc.postpad) {
+ chip->write_buf(mtd, oob, chip->ecc.postpad);
+ oob += chip->ecc.postpad;
+ }
+ }
+
+ size = mtd->oobsize - (oob - chip->oob_poi);
+ if (size)
+ chip->write_buf(mtd, oob, size);
+}
+/**
* nand_write_page_swecc - [REPLACABLE] software ecc based page write function
* @mtd: mtd info structure
* @chip: nand chip info structure
@@ -1863,7 +1960,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
}
if (unlikely(ops->ooboffs >= len)) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
"Attempt to start write outside oob\n");
return -EINVAL;
}
@@ -1873,7 +1970,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
ops->ooboffs + ops->ooblen >
((mtd->size >> chip->page_shift) -
(to >> chip->page_shift)) * len)) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_do_write_oob: "
"Attempt write beyond end of device\n");
return -EINVAL;
}
@@ -1929,8 +2026,8 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to,
/* Do not allow writes past end of device */
if (ops->datbuf && (to + ops->len) > mtd->size) {
- DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
- "Attempt read beyond end of device\n");
+ DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
+ "Attempt write beyond end of device\n");
return -EINVAL;
}
@@ -2555,6 +2652,9 @@ int nand_scan_tail(struct mtd_info *mtd)
case 64:
chip->ecc.layout = &nand_oob_64;
break;
+ case 128:
+ chip->ecc.layout = &nand_oob_128;
+ break;
default:
printk(KERN_WARNING "No oob scheme defined for "
"oobsize %d\n", mtd->oobsize);
@@ -2569,10 +2669,6 @@ int nand_scan_tail(struct mtd_info *mtd)
* check ECC mode, default to software if 3byte/512byte hardware ECC is
* selected and we have 256 byte pagesize fallback to software ECC
*/
- if (!chip->ecc.read_page_raw)
- chip->ecc.read_page_raw = nand_read_page_raw;
- if (!chip->ecc.write_page_raw)
- chip->ecc.write_page_raw = nand_write_page_raw;
switch (chip->ecc.mode) {
case NAND_ECC_HW:
@@ -2581,6 +2677,10 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_hwecc;
if (!chip->ecc.write_page)
chip->ecc.write_page = nand_write_page_hwecc;
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw;
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_std;
if (!chip->ecc.write_oob)
@@ -2602,6 +2702,10 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_syndrome;
if (!chip->ecc.write_page)
chip->ecc.write_page = nand_write_page_syndrome;
+ if (!chip->ecc.read_page_raw)
+ chip->ecc.read_page_raw = nand_read_page_raw_syndrome;
+ if (!chip->ecc.write_page_raw)
+ chip->ecc.write_page_raw = nand_write_page_raw_syndrome;
if (!chip->ecc.read_oob)
chip->ecc.read_oob = nand_read_oob_syndrome;
if (!chip->ecc.write_oob)
@@ -2620,6 +2724,8 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_swecc;
chip->ecc.read_subpage = nand_read_subpage;
chip->ecc.write_page = nand_write_page_swecc;
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ chip->ecc.write_page_raw = nand_write_page_raw;
chip->ecc.read_oob = nand_read_oob_std;
chip->ecc.write_oob = nand_write_oob_std;
chip->ecc.size = 256;
@@ -2632,6 +2738,8 @@ int nand_scan_tail(struct mtd_info *mtd)
chip->ecc.read_page = nand_read_page_raw;
chip->ecc.write_page = nand_write_page_raw;
chip->ecc.read_oob = nand_read_oob_std;
+ chip->ecc.read_page_raw = nand_read_page_raw;
+ chip->ecc.write_page_raw = nand_write_page_raw;
chip->ecc.write_oob = nand_write_oob_std;
chip->ecc.size = mtd->writesize;
chip->ecc.bytes = 0;
@@ -2676,6 +2784,7 @@ int nand_scan_tail(struct mtd_info *mtd)
break;
case 4:
case 8:
+ case 16:
mtd->subpage_sft = 2;
break;
}
@@ -2720,14 +2829,14 @@ int nand_scan_tail(struct mtd_info *mtd)
return chip->scan_bbt(mtd);
}
-/* module_text_address() isn't exported, and it's mostly a pointless
+/* is_module_text_address() isn't exported, and it's mostly a pointless
test if this is a module _anyway_ -- they'd have to try _really_ hard
to call us from in-kernel code if the core NAND support is modular. */
#ifdef MODULE
#define caller_is_module() (1)
#else
#define caller_is_module() \
- module_text_address((unsigned long)__builtin_return_address(0))
+ is_module_text_address((unsigned long)__builtin_return_address(0))
#endif
/**
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c
index 75f9f4874ec..86e1d08eee0 100644
--- a/drivers/mtd/nand/plat_nand.c
+++ b/drivers/mtd/nand/plat_nand.c
@@ -30,7 +30,7 @@ struct plat_nand_data {
/*
* Probe for the NAND device.
*/
-static int __init plat_nand_probe(struct platform_device *pdev)
+static int __devinit plat_nand_probe(struct platform_device *pdev)
{
struct platform_nand_data *pdata = pdev->dev.platform_data;
struct plat_nand_data *data;
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 61b69cc4000..30a8ce6d3e6 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -170,7 +170,13 @@ static int use_dma = 1;
module_param(use_dma, bool, 0444);
MODULE_PARM_DESC(use_dma, "enable DMA for data transfering to/from NAND HW");
-#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
+/*
+ * Default NAND flash controller configuration setup by the
+ * bootloader. This configuration is used only when pdata->keep_config is set
+ */
+static struct pxa3xx_nand_timing default_timing;
+static struct pxa3xx_nand_flash default_flash;
+
static struct pxa3xx_nand_cmdset smallpage_cmdset = {
.read1 = 0x0000,
.read2 = 0x0050,
@@ -197,6 +203,7 @@ static struct pxa3xx_nand_cmdset largepage_cmdset = {
.lock_status = 0x007A,
};
+#ifdef CONFIG_MTD_NAND_PXA3xx_BUILTIN
static struct pxa3xx_nand_timing samsung512MbX16_timing = {
.tCH = 10,
.tCS = 0,
@@ -296,9 +303,23 @@ static struct pxa3xx_nand_flash *builtin_flash_types[] = {
#define NDTR1_tWHR(c) (min((c), 15) << 4)
#define NDTR1_tAR(c) (min((c), 15) << 0)
+#define tCH_NDTR0(r) (((r) >> 19) & 0x7)
+#define tCS_NDTR0(r) (((r) >> 16) & 0x7)
+#define tWH_NDTR0(r) (((r) >> 11) & 0x7)
+#define tWP_NDTR0(r) (((r) >> 8) & 0x7)
+#define tRH_NDTR0(r) (((r) >> 3) & 0x7)
+#define tRP_NDTR0(r) (((r) >> 0) & 0x7)
+
+#define tR_NDTR1(r) (((r) >> 16) & 0xffff)
+#define tWHR_NDTR1(r) (((r) >> 4) & 0xf)
+#define tAR_NDTR1(r) (((r) >> 0) & 0xf)
+
/* convert nano-seconds to nand flash controller clock cycles */
#define ns2cycle(ns, clk) (int)(((ns) * (clk / 1000000) / 1000) - 1)
+/* convert nand flash controller clock cycles to nano-seconds */
+#define cycle2ns(c, clk) ((((c) + 1) * 1000000 + clk / 500) / (clk / 1000))
+
static void pxa3xx_nand_set_timing(struct pxa3xx_nand_info *info,
const struct pxa3xx_nand_timing *t)
{
@@ -920,6 +941,82 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info,
return 0;
}
+static void pxa3xx_nand_detect_timing(struct pxa3xx_nand_info *info,
+ struct pxa3xx_nand_timing *t)
+{
+ unsigned long nand_clk = clk_get_rate(info->clk);
+ uint32_t ndtr0 = nand_readl(info, NDTR0CS0);
+ uint32_t ndtr1 = nand_readl(info, NDTR1CS0);
+
+ t->tCH = cycle2ns(tCH_NDTR0(ndtr0), nand_clk);
+ t->tCS = cycle2ns(tCS_NDTR0(ndtr0), nand_clk);
+ t->tWH = cycle2ns(tWH_NDTR0(ndtr0), nand_clk);
+ t->tWP = cycle2ns(tWP_NDTR0(ndtr0), nand_clk);
+ t->tRH = cycle2ns(tRH_NDTR0(ndtr0), nand_clk);
+ t->tRP = cycle2ns(tRP_NDTR0(ndtr0), nand_clk);
+
+ t->tR = cycle2ns(tR_NDTR1(ndtr1), nand_clk);
+ t->tWHR = cycle2ns(tWHR_NDTR1(ndtr1), nand_clk);
+ t->tAR = cycle2ns(tAR_NDTR1(ndtr1), nand_clk);
+}
+
+static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info)
+{
+ uint32_t ndcr = nand_readl(info, NDCR);
+ struct nand_flash_dev *type = NULL;
+ uint32_t id = -1;
+ int i;
+
+ default_flash.page_per_block = ndcr & NDCR_PG_PER_BLK ? 64 : 32;
+ default_flash.page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512;
+ default_flash.flash_width = ndcr & NDCR_DWIDTH_M ? 16 : 8;
+ default_flash.dfc_width = ndcr & NDCR_DWIDTH_C ? 16 : 8;
+
+ if (default_flash.page_size == 2048)
+ default_flash.cmdset = &largepage_cmdset;
+ else
+ default_flash.cmdset = &smallpage_cmdset;
+
+ /* set info fields needed to __readid */
+ info->flash_info = &default_flash;
+ info->read_id_bytes = (default_flash.page_size == 2048) ? 4 : 2;
+ info->reg_ndcr = ndcr;
+
+ if (__readid(info, &id))
+ return -ENODEV;
+
+ /* Lookup the flash id */
+ id = (id >> 8) & 0xff; /* device id is byte 2 */
+ for (i = 0; nand_flash_ids[i].name != NULL; i++) {
+ if (id == nand_flash_ids[i].id) {
+ type = &nand_flash_ids[i];
+ break;
+ }
+ }
+
+ if (!type)
+ return -ENODEV;
+
+ /* fill the missing flash information */
+ i = __ffs(default_flash.page_per_block * default_flash.page_size);
+ default_flash.num_blocks = type->chipsize << (20 - i);
+
+ info->oob_size = (default_flash.page_size == 2048) ? 64 : 16;
+
+ /* calculate addressing information */
+ info->col_addr_cycles = (default_flash.page_size == 2048) ? 2 : 1;
+
+ if (default_flash.num_blocks * default_flash.page_per_block > 65536)
+ info->row_addr_cycles = 3;
+ else
+ info->row_addr_cycles = 2;
+
+ pxa3xx_nand_detect_timing(info, &default_timing);
+ default_flash.timing = &default_timing;
+
+ return 0;
+}
+
static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
const struct pxa3xx_nand_platform_data *pdata)
{
@@ -927,6 +1024,10 @@ static int pxa3xx_nand_detect_flash(struct pxa3xx_nand_info *info,
uint32_t id = -1;
int i;
+ if (pdata->keep_config)
+ if (pxa3xx_nand_detect_config(info) == 0)
+ return 0;
+
for (i = 0; i<pdata->num_flash; ++i) {
f = pdata->flash + i;
@@ -1078,6 +1179,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
this = &info->nand_chip;
mtd->priv = info;
+ mtd->owner = THIS_MODULE;
info->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(info->clk)) {
@@ -1117,14 +1219,14 @@ static int pxa3xx_nand_probe(struct platform_device *pdev)
goto fail_put_clk;
}
- r = request_mem_region(r->start, r->end - r->start + 1, pdev->name);
+ r = request_mem_region(r->start, resource_size(r), pdev->name);
if (r == NULL) {
dev_err(&pdev->dev, "failed to request memory resource\n");
ret = -EBUSY;
goto fail_put_clk;
}
- info->mmio_base = ioremap(r->start, r->end - r->start + 1);
+ info->mmio_base = ioremap(r->start, resource_size(r));
if (info->mmio_base == NULL) {
dev_err(&pdev->dev, "ioremap() failed\n");
ret = -ENODEV;
@@ -1173,7 +1275,7 @@ fail_free_buf:
fail_free_io:
iounmap(info->mmio_base);
fail_free_res:
- release_mem_region(r->start, r->end - r->start + 1);
+ release_mem_region(r->start, resource_size(r));
fail_put_clk:
clk_disable(info->clk);
clk_put(info->clk);
@@ -1186,6 +1288,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
{
struct mtd_info *mtd = platform_get_drvdata(pdev);
struct pxa3xx_nand_info *info = mtd->priv;
+ struct resource *r;
platform_set_drvdata(pdev, NULL);
@@ -1198,6 +1301,14 @@ static int pxa3xx_nand_remove(struct platform_device *pdev)
info->data_buff, info->data_buff_phys);
} else
kfree(info->data_buff);
+
+ iounmap(info->mmio_base);
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(r->start, resource_size(r));
+
+ clk_disable(info->clk);
+ clk_put(info->clk);
+
kfree(mtd);
return 0;
}
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c
index 821acb08ff1..2bc896623e2 100644
--- a/drivers/mtd/nand/sh_flctl.c
+++ b/drivers/mtd/nand/sh_flctl.c
@@ -58,7 +58,7 @@ static struct nand_bbt_descr flctl_4secc_smallpage = {
};
static struct nand_bbt_descr flctl_4secc_largepage = {
- .options = 0,
+ .options = NAND_BBT_SCAN2NDPAGE,
.offs = 58,
.len = 2,
.pattern = scan_ff_pattern,
@@ -149,7 +149,7 @@ static void wait_wfifo_ready(struct sh_flctl *flctl)
printk(KERN_ERR "wait_wfifo_ready(): Timeout occured \n");
}
-static int wait_recfifo_ready(struct sh_flctl *flctl)
+static int wait_recfifo_ready(struct sh_flctl *flctl, int sector_number)
{
uint32_t timeout = LOOP_TIMEOUT_MAX;
int checked[4];
@@ -183,7 +183,12 @@ static int wait_recfifo_ready(struct sh_flctl *flctl)
uint8_t org;
int index;
- index = data >> 16;
+ if (flctl->page_size)
+ index = (512 * sector_number) +
+ (data >> 16);
+ else
+ index = data >> 16;
+
org = flctl->done_buff[index];
flctl->done_buff[index] = org ^ (data & 0xFF);
checked[i] = 1;
@@ -238,14 +243,14 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset)
}
}
-static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff)
+static int read_ecfiforeg(struct sh_flctl *flctl, uint8_t *buff, int sector)
{
int i;
unsigned long *ecc_buf = (unsigned long *)buff;
void *fifo_addr = (void *)FLECFIFO(flctl);
for (i = 0; i < 4; i++) {
- if (wait_recfifo_ready(flctl))
+ if (wait_recfifo_ready(flctl , sector))
return 1;
ecc_buf[i] = readl(fifo_addr);
ecc_buf[i] = be32_to_cpu(ecc_buf[i]);
@@ -384,7 +389,8 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr)
read_fiforeg(flctl, 512, 512 * sector);
ret = read_ecfiforeg(flctl,
- &flctl->done_buff[mtd->writesize + 16 * sector]);
+ &flctl->done_buff[mtd->writesize + 16 * sector],
+ sector);
if (ret)
flctl->hwecc_cant_correct[sector] = 1;
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c
new file mode 100644
index 00000000000..a4519a7bd68
--- /dev/null
+++ b/drivers/mtd/nand/socrates_nand.c
@@ -0,0 +1,325 @@
+/*
+ * drivers/mtd/nand/socrates_nand.c
+ *
+ * Copyright © 2008 Ilya Yanok, Emcraft Systems
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+
+#define FPGA_NAND_CMD_MASK (0x7 << 28)
+#define FPGA_NAND_CMD_COMMAND (0x0 << 28)
+#define FPGA_NAND_CMD_ADDR (0x1 << 28)
+#define FPGA_NAND_CMD_READ (0x2 << 28)
+#define FPGA_NAND_CMD_WRITE (0x3 << 28)
+#define FPGA_NAND_BUSY (0x1 << 15)
+#define FPGA_NAND_ENABLE (0x1 << 31)
+#define FPGA_NAND_DATA_SHIFT 16
+
+struct socrates_nand_host {
+ struct nand_chip nand_chip;
+ struct mtd_info mtd;
+ void __iomem *io_base;
+ struct device *dev;
+};
+
+/**
+ * socrates_nand_write_buf - write buffer to chip
+ * @mtd: MTD device structure
+ * @buf: data buffer
+ * @len: number of bytes to write
+ */
+static void socrates_nand_write_buf(struct mtd_info *mtd,
+ const uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ struct socrates_nand_host *host = this->priv;
+
+ for (i = 0; i < len; i++) {
+ out_be32(host->io_base, FPGA_NAND_ENABLE |
+ FPGA_NAND_CMD_WRITE |
+ (buf[i] << FPGA_NAND_DATA_SHIFT));
+ }
+}
+
+/**
+ * socrates_nand_read_buf - read chip data into buffer
+ * @mtd: MTD device structure
+ * @buf: buffer to store date
+ * @len: number of bytes to read
+ */
+static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ int i;
+ struct nand_chip *this = mtd->priv;
+ struct socrates_nand_host *host = this->priv;
+ uint32_t val;
+
+ val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ;
+
+ out_be32(host->io_base, val);
+ for (i = 0; i < len; i++) {
+ buf[i] = (in_be32(host->io_base) >>
+ FPGA_NAND_DATA_SHIFT) & 0xff;
+ }
+}
+
+/**
+ * socrates_nand_read_byte - read one byte from the chip
+ * @mtd: MTD device structure
+ */
+static uint8_t socrates_nand_read_byte(struct mtd_info *mtd)
+{
+ uint8_t byte;
+ socrates_nand_read_buf(mtd, &byte, sizeof(byte));
+ return byte;
+}
+
+/**
+ * socrates_nand_read_word - read one word from the chip
+ * @mtd: MTD device structure
+ */
+static uint16_t socrates_nand_read_word(struct mtd_info *mtd)
+{
+ uint16_t word;
+ socrates_nand_read_buf(mtd, (uint8_t *)&word, sizeof(word));
+ return word;
+}
+
+/**
+ * socrates_nand_verify_buf - Verify chip data against buffer
+ * @mtd: MTD device structure
+ * @buf: buffer containing the data to compare
+ * @len: number of bytes to compare
+ */
+static int socrates_nand_verify_buf(struct mtd_info *mtd, const u8 *buf,
+ int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++) {
+ if (buf[i] != socrates_nand_read_byte(mtd))
+ return -EFAULT;
+ }
+ return 0;
+}
+
+/*
+ * Hardware specific access to control-lines
+ */
+static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct socrates_nand_host *host = nand_chip->priv;
+ uint32_t val;
+
+ if (cmd == NAND_CMD_NONE)
+ return;
+
+ if (ctrl & NAND_CLE)
+ val = FPGA_NAND_CMD_COMMAND;
+ else
+ val = FPGA_NAND_CMD_ADDR;
+
+ if (ctrl & NAND_NCE)
+ val |= FPGA_NAND_ENABLE;
+
+ val |= (cmd & 0xff) << FPGA_NAND_DATA_SHIFT;
+
+ out_be32(host->io_base, val);
+}
+
+/*
+ * Read the Device Ready pin.
+ */
+static int socrates_nand_device_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *nand_chip = mtd->priv;
+ struct socrates_nand_host *host = nand_chip->priv;
+
+ if (in_be32(host->io_base) & FPGA_NAND_BUSY)
+ return 0; /* busy */
+ return 1;
+}
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probes[] = { "cmdlinepart", NULL };
+#endif
+
+/*
+ * Probe for the NAND device.
+ */
+static int __devinit socrates_nand_probe(struct of_device *ofdev,
+ const struct of_device_id *ofid)
+{
+ struct socrates_nand_host *host;
+ struct mtd_info *mtd;
+ struct nand_chip *nand_chip;
+ int res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *partitions = NULL;
+ int num_partitions = 0;
+#endif
+
+ /* Allocate memory for the device structure (and zero it) */
+ host = kzalloc(sizeof(struct socrates_nand_host), GFP_KERNEL);
+ if (!host) {
+ printk(KERN_ERR
+ "socrates_nand: failed to allocate device structure.\n");
+ return -ENOMEM;
+ }
+
+ host->io_base = of_iomap(ofdev->node, 0);
+ if (host->io_base == NULL) {
+ printk(KERN_ERR "socrates_nand: ioremap failed\n");
+ kfree(host);
+ return -EIO;
+ }
+
+ mtd = &host->mtd;
+ nand_chip = &host->nand_chip;
+ host->dev = &ofdev->dev;
+
+ nand_chip->priv = host; /* link the private data structures */
+ mtd->priv = nand_chip;
+ mtd->name = "socrates_nand";
+ mtd->owner = THIS_MODULE;
+ mtd->dev.parent = &ofdev->dev;
+
+ /*should never be accessed directly */
+ nand_chip->IO_ADDR_R = (void *)0xdeadbeef;
+ nand_chip->IO_ADDR_W = (void *)0xdeadbeef;
+
+ nand_chip->cmd_ctrl = socrates_nand_cmd_ctrl;
+ nand_chip->read_byte = socrates_nand_read_byte;
+ nand_chip->read_word = socrates_nand_read_word;
+ nand_chip->write_buf = socrates_nand_write_buf;
+ nand_chip->read_buf = socrates_nand_read_buf;
+ nand_chip->verify_buf = socrates_nand_verify_buf;
+ nand_chip->dev_ready = socrates_nand_device_ready;
+
+ nand_chip->ecc.mode = NAND_ECC_SOFT; /* enable ECC */
+
+ /* TODO: I have no idea what real delay is. */
+ nand_chip->chip_delay = 20; /* 20us command delay time */
+
+ dev_set_drvdata(&ofdev->dev, host);
+
+ /* first scan to find the device and get the page size */
+ if (nand_scan_ident(mtd, 1)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+ /* second phase scan */
+ if (nand_scan_tail(mtd)) {
+ res = -ENXIO;
+ goto out;
+ }
+
+#ifdef CONFIG_MTD_PARTITIONS
+#ifdef CONFIG_MTD_CMDLINE_PARTS
+ num_partitions = parse_mtd_partitions(mtd, part_probes,
+ &partitions, 0);
+ if (num_partitions < 0) {
+ res = num_partitions;
+ goto release;
+ }
+#endif
+
+#ifdef CONFIG_MTD_OF_PARTS
+ if (num_partitions == 0) {
+ num_partitions = of_mtd_parse_partitions(&ofdev->dev,
+ ofdev->node,
+ &partitions);
+ if (num_partitions < 0) {
+ res = num_partitions;
+ goto release;
+ }
+ }
+#endif
+ if (partitions && (num_partitions > 0))
+ res = add_mtd_partitions(mtd, partitions, num_partitions);
+ else
+#endif
+ res = add_mtd_device(mtd);
+
+ if (!res)
+ return res;
+
+#ifdef CONFIG_MTD_PARTITIONS
+release:
+#endif
+ nand_release(mtd);
+
+out:
+ dev_set_drvdata(&ofdev->dev, NULL);
+ iounmap(host->io_base);
+ kfree(host);
+ return res;
+}
+
+/*
+ * Remove a NAND device.
+ */
+static int __devexit socrates_nand_remove(struct of_device *ofdev)
+{
+ struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev);
+ struct mtd_info *mtd = &host->mtd;
+
+ nand_release(mtd);
+
+ dev_set_drvdata(&ofdev->dev, NULL);
+ iounmap(host->io_base);
+ kfree(host);
+
+ return 0;
+}
+
+static struct of_device_id socrates_nand_match[] =
+{
+ {
+ .compatible = "abb,socrates-nand",
+ },
+ {},
+};
+
+MODULE_DEVICE_TABLE(of, socrates_nand_match);
+
+static struct of_platform_driver socrates_nand_driver = {
+ .name = "socrates_nand",
+ .match_table = socrates_nand_match,
+ .probe = socrates_nand_probe,
+ .remove = __devexit_p(socrates_nand_remove),
+};
+
+static int __init socrates_nand_init(void)
+{
+ return of_register_platform_driver(&socrates_nand_driver);
+}
+
+static void __exit socrates_nand_exit(void)
+{
+ of_unregister_platform_driver(&socrates_nand_driver);
+}
+
+module_init(socrates_nand_init);
+module_exit(socrates_nand_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Ilya Yanok");
+MODULE_DESCRIPTION("NAND driver for Socrates board");
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c
new file mode 100644
index 00000000000..81247926489
--- /dev/null
+++ b/drivers/mtd/nand/txx9ndfmc.c
@@ -0,0 +1,428 @@
+/*
+ * TXx9 NAND flash memory controller driver
+ * Based on RBTX49xx patch from CELF patch archive.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * (C) Copyright TOSHIBA CORPORATION 2004-2007
+ * All Rights Reserved.
+ */
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/nand_ecc.h>
+#include <linux/mtd/partitions.h>
+#include <linux/io.h>
+#include <asm/txx9/ndfmc.h>
+
+/* TXX9 NDFMC Registers */
+#define TXX9_NDFDTR 0x00
+#define TXX9_NDFMCR 0x04
+#define TXX9_NDFSR 0x08
+#define TXX9_NDFISR 0x0c
+#define TXX9_NDFIMR 0x10
+#define TXX9_NDFSPR 0x14
+#define TXX9_NDFRSTR 0x18 /* not TX4939 */
+
+/* NDFMCR : NDFMC Mode Control */
+#define TXX9_NDFMCR_WE 0x80
+#define TXX9_NDFMCR_ECC_ALL 0x60
+#define TXX9_NDFMCR_ECC_RESET 0x60
+#define TXX9_NDFMCR_ECC_READ 0x40
+#define TXX9_NDFMCR_ECC_ON 0x20
+#define TXX9_NDFMCR_ECC_OFF 0x00
+#define TXX9_NDFMCR_CE 0x10
+#define TXX9_NDFMCR_BSPRT 0x04 /* TX4925/TX4926 only */
+#define TXX9_NDFMCR_ALE 0x02
+#define TXX9_NDFMCR_CLE 0x01
+/* TX4939 only */
+#define TXX9_NDFMCR_X16 0x0400
+#define TXX9_NDFMCR_DMAREQ_MASK 0x0300
+#define TXX9_NDFMCR_DMAREQ_NODMA 0x0000
+#define TXX9_NDFMCR_DMAREQ_128 0x0100
+#define TXX9_NDFMCR_DMAREQ_256 0x0200
+#define TXX9_NDFMCR_DMAREQ_512 0x0300
+#define TXX9_NDFMCR_CS_MASK 0x0c
+#define TXX9_NDFMCR_CS(ch) ((ch) << 2)
+
+/* NDFMCR : NDFMC Status */
+#define TXX9_NDFSR_BUSY 0x80
+/* TX4939 only */
+#define TXX9_NDFSR_DMARUN 0x40
+
+/* NDFMCR : NDFMC Reset */
+#define TXX9_NDFRSTR_RST 0x01
+
+struct txx9ndfmc_priv {
+ struct platform_device *dev;
+ struct nand_chip chip;
+ struct mtd_info mtd;
+ int cs;
+ char mtdname[BUS_ID_SIZE + 2];
+};
+
+#define MAX_TXX9NDFMC_DEV 4
+struct txx9ndfmc_drvdata {
+ struct mtd_info *mtds[MAX_TXX9NDFMC_DEV];
+ void __iomem *base;
+ unsigned char hold; /* in gbusclock */
+ unsigned char spw; /* in gbusclock */
+ struct nand_hw_control hw_control;
+#ifdef CONFIG_MTD_PARTITIONS
+ struct mtd_partition *parts[MAX_TXX9NDFMC_DEV];
+#endif
+};
+
+static struct platform_device *mtd_to_platdev(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct txx9ndfmc_priv *txx9_priv = chip->priv;
+ return txx9_priv->dev;
+}
+
+static void __iomem *ndregaddr(struct platform_device *dev, unsigned int reg)
+{
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+ return drvdata->base + (reg << plat->shift);
+}
+
+static u32 txx9ndfmc_read(struct platform_device *dev, unsigned int reg)
+{
+ return __raw_readl(ndregaddr(dev, reg));
+}
+
+static void txx9ndfmc_write(struct platform_device *dev,
+ u32 val, unsigned int reg)
+{
+ __raw_writel(val, ndregaddr(dev, reg));
+}
+
+static uint8_t txx9ndfmc_read_byte(struct mtd_info *mtd)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+
+ return txx9ndfmc_read(dev, TXX9_NDFDTR);
+}
+
+static void txx9ndfmc_write_buf(struct mtd_info *mtd, const uint8_t *buf,
+ int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_WE, TXX9_NDFMCR);
+ while (len--)
+ __raw_writel(*buf++, ndfdtr);
+ txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+ while (len--)
+ *buf++ = __raw_readl(ndfdtr);
+}
+
+static int txx9ndfmc_verify_buf(struct mtd_info *mtd, const uint8_t *buf,
+ int len)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ void __iomem *ndfdtr = ndregaddr(dev, TXX9_NDFDTR);
+
+ while (len--)
+ if (*buf++ != (uint8_t)__raw_readl(ndfdtr))
+ return -EFAULT;
+ return 0;
+}
+
+static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct txx9ndfmc_priv *txx9_priv = chip->priv;
+ struct platform_device *dev = txx9_priv->dev;
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~(TXX9_NDFMCR_CLE | TXX9_NDFMCR_ALE | TXX9_NDFMCR_CE);
+ mcr |= ctrl & NAND_CLE ? TXX9_NDFMCR_CLE : 0;
+ mcr |= ctrl & NAND_ALE ? TXX9_NDFMCR_ALE : 0;
+ /* TXX9_NDFMCR_CE bit is 0:high 1:low */
+ mcr |= ctrl & NAND_NCE ? TXX9_NDFMCR_CE : 0;
+ if (txx9_priv->cs >= 0 && (ctrl & NAND_NCE)) {
+ mcr &= ~TXX9_NDFMCR_CS_MASK;
+ mcr |= TXX9_NDFMCR_CS(txx9_priv->cs);
+ }
+ txx9ndfmc_write(dev, mcr, TXX9_NDFMCR);
+ }
+ if (cmd != NAND_CMD_NONE)
+ txx9ndfmc_write(dev, cmd & 0xff, TXX9_NDFDTR);
+ if (plat->flags & NDFMC_PLAT_FLAG_DUMMYWRITE) {
+ /* dummy write to update external latch */
+ if ((ctrl & NAND_CTRL_CHANGE) && cmd == NAND_CMD_NONE)
+ txx9ndfmc_write(dev, 0, TXX9_NDFDTR);
+ }
+ mmiowb();
+}
+
+static int txx9ndfmc_dev_ready(struct mtd_info *mtd)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+
+ return !(txx9ndfmc_read(dev, TXX9_NDFSR) & TXX9_NDFSR_BUSY);
+}
+
+static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat,
+ uint8_t *ecc_code)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~TXX9_NDFMCR_ECC_ALL;
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_READ, TXX9_NDFMCR);
+ ecc_code[1] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ ecc_code[0] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ ecc_code[2] = txx9ndfmc_read(dev, TXX9_NDFDTR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ return 0;
+}
+
+static void txx9ndfmc_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct platform_device *dev = mtd_to_platdev(mtd);
+ u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR);
+
+ mcr &= ~TXX9_NDFMCR_ECC_ALL;
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_RESET, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_OFF, TXX9_NDFMCR);
+ txx9ndfmc_write(dev, mcr | TXX9_NDFMCR_ECC_ON, TXX9_NDFMCR);
+}
+
+static void txx9ndfmc_initialize(struct platform_device *dev)
+{
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ int tmout = 100;
+
+ if (plat->flags & NDFMC_PLAT_FLAG_NO_RSTR)
+ ; /* no NDFRSTR. Write to NDFSPR resets the NDFMC. */
+ else {
+ /* reset NDFMC */
+ txx9ndfmc_write(dev,
+ txx9ndfmc_read(dev, TXX9_NDFRSTR) |
+ TXX9_NDFRSTR_RST,
+ TXX9_NDFRSTR);
+ while (txx9ndfmc_read(dev, TXX9_NDFRSTR) & TXX9_NDFRSTR_RST) {
+ if (--tmout == 0) {
+ dev_err(&dev->dev, "reset failed.\n");
+ break;
+ }
+ udelay(1);
+ }
+ }
+ /* setup Hold Time, Strobe Pulse Width */
+ txx9ndfmc_write(dev, (drvdata->hold << 4) | drvdata->spw, TXX9_NDFSPR);
+ txx9ndfmc_write(dev,
+ (plat->flags & NDFMC_PLAT_FLAG_USE_BSPRT) ?
+ TXX9_NDFMCR_BSPRT : 0, TXX9_NDFMCR);
+}
+
+#define TXX9NDFMC_NS_TO_CYC(gbusclk, ns) \
+ DIV_ROUND_UP((ns) * DIV_ROUND_UP(gbusclk, 1000), 1000000)
+
+static int __init txx9ndfmc_probe(struct platform_device *dev)
+{
+ struct txx9ndfmc_platform_data *plat = dev->dev.platform_data;
+#ifdef CONFIG_MTD_PARTITIONS
+ static const char *probes[] = { "cmdlinepart", NULL };
+#endif
+ int hold, spw;
+ int i;
+ struct txx9ndfmc_drvdata *drvdata;
+ unsigned long gbusclk = plat->gbus_clock;
+ struct resource *res;
+
+ res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+ drvdata = devm_kzalloc(&dev->dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+ if (!devm_request_mem_region(&dev->dev, res->start,
+ resource_size(res), dev_name(&dev->dev)))
+ return -EBUSY;
+ drvdata->base = devm_ioremap(&dev->dev, res->start,
+ resource_size(res));
+ if (!drvdata->base)
+ return -EBUSY;
+
+ hold = plat->hold ?: 20; /* tDH */
+ spw = plat->spw ?: 90; /* max(tREADID, tWP, tRP) */
+
+ hold = TXX9NDFMC_NS_TO_CYC(gbusclk, hold);
+ spw = TXX9NDFMC_NS_TO_CYC(gbusclk, spw);
+ if (plat->flags & NDFMC_PLAT_FLAG_HOLDADD)
+ hold -= 2; /* actual hold time : (HOLD + 2) BUSCLK */
+ spw -= 1; /* actual wait time : (SPW + 1) BUSCLK */
+ hold = clamp(hold, 1, 15);
+ drvdata->hold = hold;
+ spw = clamp(spw, 1, 15);
+ drvdata->spw = spw;
+ dev_info(&dev->dev, "CLK:%ldMHz HOLD:%d SPW:%d\n",
+ (gbusclk + 500000) / 1000000, hold, spw);
+
+ spin_lock_init(&drvdata->hw_control.lock);
+ init_waitqueue_head(&drvdata->hw_control.wq);
+
+ platform_set_drvdata(dev, drvdata);
+ txx9ndfmc_initialize(dev);
+
+ for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+ struct txx9ndfmc_priv *txx9_priv;
+ struct nand_chip *chip;
+ struct mtd_info *mtd;
+#ifdef CONFIG_MTD_PARTITIONS
+ int nr_parts;
+#endif
+
+ if (!(plat->ch_mask & (1 << i)))
+ continue;
+ txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv),
+ GFP_KERNEL);
+ if (!txx9_priv) {
+ dev_err(&dev->dev, "Unable to allocate "
+ "TXx9 NDFMC MTD device structure.\n");
+ continue;
+ }
+ chip = &txx9_priv->chip;
+ mtd = &txx9_priv->mtd;
+ mtd->owner = THIS_MODULE;
+
+ mtd->priv = chip;
+
+ chip->read_byte = txx9ndfmc_read_byte;
+ chip->read_buf = txx9ndfmc_read_buf;
+ chip->write_buf = txx9ndfmc_write_buf;
+ chip->verify_buf = txx9ndfmc_verify_buf;
+ chip->cmd_ctrl = txx9ndfmc_cmd_ctrl;
+ chip->dev_ready = txx9ndfmc_dev_ready;
+ chip->ecc.calculate = txx9ndfmc_calculate_ecc;
+ chip->ecc.correct = nand_correct_data;
+ chip->ecc.hwctl = txx9ndfmc_enable_hwecc;
+ chip->ecc.mode = NAND_ECC_HW;
+ chip->ecc.size = 256;
+ chip->ecc.bytes = 3;
+ chip->chip_delay = 100;
+ chip->controller = &drvdata->hw_control;
+
+ chip->priv = txx9_priv;
+ txx9_priv->dev = dev;
+
+ if (plat->ch_mask != 1) {
+ txx9_priv->cs = i;
+ sprintf(txx9_priv->mtdname, "%s.%u",
+ dev_name(&dev->dev), i);
+ } else {
+ txx9_priv->cs = -1;
+ strcpy(txx9_priv->mtdname, dev_name(&dev->dev));
+ }
+ if (plat->wide_mask & (1 << i))
+ chip->options |= NAND_BUSWIDTH_16;
+
+ if (nand_scan(mtd, 1)) {
+ kfree(txx9_priv);
+ continue;
+ }
+ mtd->name = txx9_priv->mtdname;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ nr_parts = parse_mtd_partitions(mtd, probes,
+ &drvdata->parts[i], 0);
+ if (nr_parts > 0)
+ add_mtd_partitions(mtd, drvdata->parts[i], nr_parts);
+#endif
+ add_mtd_device(mtd);
+ drvdata->mtds[i] = mtd;
+ }
+
+ return 0;
+}
+
+static int __exit txx9ndfmc_remove(struct platform_device *dev)
+{
+ struct txx9ndfmc_drvdata *drvdata = platform_get_drvdata(dev);
+ int i;
+
+ platform_set_drvdata(dev, NULL);
+ if (!drvdata)
+ return 0;
+ for (i = 0; i < MAX_TXX9NDFMC_DEV; i++) {
+ struct mtd_info *mtd = drvdata->mtds[i];
+ struct nand_chip *chip;
+ struct txx9ndfmc_priv *txx9_priv;
+
+ if (!mtd)
+ continue;
+ chip = mtd->priv;
+ txx9_priv = chip->priv;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ del_mtd_partitions(mtd);
+ kfree(drvdata->parts[i]);
+#endif
+ del_mtd_device(mtd);
+ kfree(txx9_priv);
+ }
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int txx9ndfmc_resume(struct platform_device *dev)
+{
+ if (platform_get_drvdata(dev))
+ txx9ndfmc_initialize(dev);
+ return 0;
+}
+#else
+#define txx9ndfmc_resume NULL
+#endif
+
+static struct platform_driver txx9ndfmc_driver = {
+ .remove = __exit_p(txx9ndfmc_remove),
+ .resume = txx9ndfmc_resume,
+ .driver = {
+ .name = "txx9ndfmc",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init txx9ndfmc_init(void)
+{
+ return platform_driver_probe(&txx9ndfmc_driver, txx9ndfmc_probe);
+}
+
+static void __exit txx9ndfmc_exit(void)
+{
+ platform_driver_unregister(&txx9ndfmc_driver);
+}
+
+module_init(txx9ndfmc_init);
+module_exit(txx9ndfmc_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver");
+MODULE_ALIAS("platform:txx9ndfmc");
diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c
index d1c4546513f..e3f8495a94c 100644
--- a/drivers/mtd/nftlcore.c
+++ b/drivers/mtd/nftlcore.c
@@ -15,11 +15,11 @@
#include <asm/errno.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/hdreg.h>
+#include <linux/blkdev.h>
#include <linux/kmod.h>
#include <linux/mtd/mtd.h>
@@ -818,3 +818,4 @@ module_exit(cleanup_nftl);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>, Fabrice Bellard <fabrice.bellard@netgem.com> et al.");
MODULE_DESCRIPTION("Support code for NAND Flash Translation Layer, used on M-Systems DiskOnChip 2000 and Millennium");
+MODULE_ALIAS_BLOCKDEV_MAJOR(NFTL_MAJOR);
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c
index 9e45b3f39c0..3e164f0c929 100644
--- a/drivers/mtd/ofpart.c
+++ b/drivers/mtd/ofpart.c
@@ -46,6 +46,13 @@ int __devinit of_mtd_parse_partitions(struct device *dev,
const u32 *reg;
int len;
+ /* check if this is a partition node */
+ partname = of_get_property(pp, "name", &len);
+ if (strcmp(partname, "partition") != 0) {
+ nr_parts--;
+ continue;
+ }
+
reg = of_get_property(pp, "reg", &len);
if (!reg || (len != 2 * sizeof(u32))) {
of_node_put(pp);
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c
index 77a4f144615..f2e9de1414d 100644
--- a/drivers/mtd/onenand/omap2.c
+++ b/drivers/mtd/onenand/omap2.c
@@ -294,6 +294,10 @@ static int omap3_onenand_read_bufferram(struct mtd_info *mtd, int area,
if (bram_offset & 3 || (size_t)buf & 3 || count < 384)
goto out_copy;
+ /* panic_write() may be in an interrupt context */
+ if (in_interrupt())
+ goto out_copy;
+
if (buf >= high_memory) {
struct page *p1;
@@ -672,6 +676,8 @@ static int __devinit omap2_onenand_probe(struct platform_device *pdev)
c->mtd.priv = &c->onenand;
c->mtd.owner = THIS_MODULE;
+ c->mtd.dev.parent = &pdev->dev;
+
if (c->dma_channel >= 0) {
struct onenand_chip *this = &c->onenand;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 529af271db1..30d6999e5f9 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1455,7 +1455,8 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
struct mtd_oob_ops *ops)
{
struct onenand_chip *this = mtd->priv;
- int written = 0, column, thislen, subpage;
+ int written = 0, column, thislen = 0, subpage = 0;
+ int prev = 0, prevlen = 0, prev_subpage = 0, first = 1;
int oobwritten = 0, oobcolumn, thisooblen, oobsize;
size_t len = ops->len;
size_t ooblen = ops->ooblen;
@@ -1482,6 +1483,10 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
return -EINVAL;
}
+ /* Check zero length */
+ if (!len)
+ return 0;
+
if (ops->mode == MTD_OOB_AUTO)
oobsize = this->ecclayout->oobavail;
else
@@ -1492,79 +1497,121 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to,
column = to & (mtd->writesize - 1);
/* Loop until all data write */
- while (written < len) {
- u_char *wbuf = (u_char *) buf;
+ while (1) {
+ if (written < len) {
+ u_char *wbuf = (u_char *) buf;
- thislen = min_t(int, mtd->writesize - column, len - written);
- thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
+ thislen = min_t(int, mtd->writesize - column, len - written);
+ thisooblen = min_t(int, oobsize - oobcolumn, ooblen - oobwritten);
- cond_resched();
+ cond_resched();
- this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
- /* Partial page write */
- subpage = thislen < mtd->writesize;
- if (subpage) {
- memset(this->page_buf, 0xff, mtd->writesize);
- memcpy(this->page_buf + column, buf, thislen);
- wbuf = this->page_buf;
- }
+ /* Partial page write */
+ subpage = thislen < mtd->writesize;
+ if (subpage) {
+ memset(this->page_buf, 0xff, mtd->writesize);
+ memcpy(this->page_buf + column, buf, thislen);
+ wbuf = this->page_buf;
+ }
- this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
+ this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
- if (oob) {
- oobbuf = this->oob_buf;
+ if (oob) {
+ oobbuf = this->oob_buf;
- /* We send data to spare ram with oobsize
- * to prevent byte access */
- memset(oobbuf, 0xff, mtd->oobsize);
- if (ops->mode == MTD_OOB_AUTO)
- onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
- else
- memcpy(oobbuf + oobcolumn, oob, thisooblen);
+ /* We send data to spare ram with oobsize
+ * to prevent byte access */
+ memset(oobbuf, 0xff, mtd->oobsize);
+ if (ops->mode == MTD_OOB_AUTO)
+ onenand_fill_auto_oob(mtd, oobbuf, oob, oobcolumn, thisooblen);
+ else
+ memcpy(oobbuf + oobcolumn, oob, thisooblen);
- oobwritten += thisooblen;
- oob += thisooblen;
- oobcolumn = 0;
+ oobwritten += thisooblen;
+ oob += thisooblen;
+ oobcolumn = 0;
+ } else
+ oobbuf = (u_char *) ffchars;
+
+ this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
} else
- oobbuf = (u_char *) ffchars;
+ ONENAND_SET_NEXT_BUFFERRAM(this);
- this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize);
+ /*
+ * 2 PLANE, MLC, and Flex-OneNAND doesn't support
+ * write-while-programe feature.
+ */
+ if (!ONENAND_IS_2PLANE(this) && !first) {
+ ONENAND_SET_PREV_BUFFERRAM(this);
- this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
+ ret = this->wait(mtd, FL_WRITING);
- ret = this->wait(mtd, FL_WRITING);
+ /* In partial page write we don't update bufferram */
+ onenand_update_bufferram(mtd, prev, !ret && !prev_subpage);
+ if (ret) {
+ written -= prevlen;
+ printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
+ break;
+ }
- /* In partial page write we don't update bufferram */
- onenand_update_bufferram(mtd, to, !ret && !subpage);
- if (ONENAND_IS_2PLANE(this)) {
- ONENAND_SET_BUFFERRAM1(this);
- onenand_update_bufferram(mtd, to + this->writesize, !ret && !subpage);
- }
+ if (written == len) {
+ /* Only check verify write turn on */
+ ret = onenand_verify(mtd, buf - len, to - len, len);
+ if (ret)
+ printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+ break;
+ }
- if (ret) {
- printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
- break;
+ ONENAND_SET_NEXT_BUFFERRAM(this);
}
- /* Only check verify write turn on */
- ret = onenand_verify(mtd, buf, to, thislen);
- if (ret) {
- printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
- break;
- }
+ this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
- written += thislen;
+ /*
+ * 2 PLANE, MLC, and Flex-OneNAND wait here
+ */
+ if (ONENAND_IS_2PLANE(this)) {
+ ret = this->wait(mtd, FL_WRITING);
- if (written == len)
- break;
+ /* In partial page write we don't update bufferram */
+ onenand_update_bufferram(mtd, to, !ret && !subpage);
+ if (ret) {
+ printk(KERN_ERR "onenand_write_ops_nolock: write filaed %d\n", ret);
+ break;
+ }
+
+ /* Only check verify write turn on */
+ ret = onenand_verify(mtd, buf, to, thislen);
+ if (ret) {
+ printk(KERN_ERR "onenand_write_ops_nolock: verify failed %d\n", ret);
+ break;
+ }
+
+ written += thislen;
+
+ if (written == len)
+ break;
+
+ } else
+ written += thislen;
column = 0;
+ prev_subpage = subpage;
+ prev = to;
+ prevlen = thislen;
to += thislen;
buf += thislen;
+ first = 0;
}
+ /* In error case, clear all bufferrams */
+ if (written != len)
+ onenand_invalidate_bufferram(mtd, 0, -1);
+
ops->retlen = written;
+ ops->oobretlen = oobwritten;
return ret;
}
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c
index afbc3f8126d..a18e8d2f255 100644
--- a/drivers/mtd/tests/mtd_oobtest.c
+++ b/drivers/mtd/tests/mtd_oobtest.c
@@ -136,7 +136,7 @@ static int write_eraseblock(int ebnum)
ops.ooblen = use_len;
ops.oobretlen = 0;
ops.ooboffs = use_offset;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
err = mtd->write_oob(mtd, addr, &ops);
if (err || ops.oobretlen != use_len) {
@@ -189,7 +189,7 @@ static int verify_eraseblock(int ebnum)
ops.ooblen = use_len;
ops.oobretlen = 0;
ops.ooboffs = use_offset;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != use_len) {
@@ -216,7 +216,7 @@ static int verify_eraseblock(int ebnum)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != mtd->ecclayout->oobavail) {
@@ -281,7 +281,7 @@ static int verify_eraseblock_in_one_go(int ebnum)
ops.ooblen = len;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err || ops.oobretlen != len) {
@@ -522,7 +522,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = 1;
ops.oobretlen = 0;
ops.ooboffs = mtd->ecclayout->oobavail;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to start write past end of OOB\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -542,7 +542,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = 1;
ops.oobretlen = 0;
ops.ooboffs = mtd->ecclayout->oobavail;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to start read past end of OOB\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -566,7 +566,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail + 1;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to write past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -586,7 +586,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail + 1;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to read past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -610,7 +610,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 1;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
printk(PRINT_PREF "attempting to write past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -630,7 +630,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail;
ops.oobretlen = 0;
ops.ooboffs = 1;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
printk(PRINT_PREF "attempting to read past end of device\n");
printk(PRINT_PREF "an error is expected...\n");
@@ -670,7 +670,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = sz;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = writebuf;
err = mtd->write_oob(mtd, addr, &ops);
if (err)
@@ -698,7 +698,7 @@ static int __init mtd_oobtest_init(void)
ops.ooblen = mtd->ecclayout->oobavail * 2;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = readbuf;
err = mtd->read_oob(mtd, addr, &ops);
if (err)
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c
index 645e77fdc63..79fc4530987 100644
--- a/drivers/mtd/tests/mtd_readtest.c
+++ b/drivers/mtd/tests/mtd_readtest.c
@@ -71,7 +71,7 @@ static int read_eraseblock_by_page(int ebnum)
ops.ooblen = mtd->oobsize;
ops.oobretlen = 0;
ops.ooboffs = 0;
- ops.datbuf = 0;
+ ops.datbuf = NULL;
ops.oobbuf = oobbuf;
ret = mtd->read_oob(mtd, addr, &ops);
if (ret || ops.oobretlen != mtd->oobsize) {
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index e63c8fc3df3..f8e0f68f218 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -186,6 +186,16 @@ static loff_t vol_cdev_llseek(struct file *file, loff_t offset, int origin)
return new_offset;
}
+static int vol_cdev_fsync(struct file *file, struct dentry *dentry,
+ int datasync)
+{
+ struct ubi_volume_desc *desc = file->private_data;
+ struct ubi_device *ubi = desc->vol->ubi;
+
+ return ubi_sync(ubi->ubi_num);
+}
+
+
static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count,
loff_t *offp)
{
@@ -1073,6 +1083,7 @@ const struct file_operations ubi_vol_cdev_operations = {
.llseek = vol_cdev_llseek,
.read = vol_cdev_read,
.write = vol_cdev_write,
+ .fsync = vol_cdev_fsync,
.unlocked_ioctl = vol_cdev_ioctl,
.compat_ioctl = vol_cdev_compat_ioctl,
};
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 9c326a50a3e..99610f358c4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3444,25 +3444,12 @@ static void bond_remove_proc_entry(struct bonding *bond)
*/
static void bond_create_proc_dir(void)
{
- int len = strlen(DRV_NAME);
-
- for (bond_proc_dir = init_net.proc_net->subdir; bond_proc_dir;
- bond_proc_dir = bond_proc_dir->next) {
- if ((bond_proc_dir->namelen == len) &&
- !memcmp(bond_proc_dir->name, DRV_NAME, len)) {
- break;
- }
- }
-
if (!bond_proc_dir) {
bond_proc_dir = proc_mkdir(DRV_NAME, init_net.proc_net);
- if (bond_proc_dir) {
- bond_proc_dir->owner = THIS_MODULE;
- } else {
+ if (!bond_proc_dir)
printk(KERN_WARNING DRV_NAME
": Warning: cannot create /proc/net/%s\n",
DRV_NAME);
- }
}
}
@@ -3471,25 +3458,7 @@ static void bond_create_proc_dir(void)
*/
static void bond_destroy_proc_dir(void)
{
- struct proc_dir_entry *de;
-
- if (!bond_proc_dir) {
- return;
- }
-
- /* verify that the /proc dir is empty */
- for (de = bond_proc_dir->subdir; de; de = de->next) {
- /* ignore . and .. */
- if (*(de->name) != '.') {
- break;
- }
- }
-
- if (de) {
- if (bond_proc_dir->owner == THIS_MODULE) {
- bond_proc_dir->owner = NULL;
- }
- } else {
+ if (bond_proc_dir) {
remove_proc_entry(DRV_NAME, init_net.proc_net);
bond_proc_dir = NULL;
}
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 254ec62b5f5..d8350860c0f 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -559,7 +559,7 @@ static void dm9000_show_carrier(board_info_t *db,
static void
dm9000_poll_work(struct work_struct *w)
{
- struct delayed_work *dw = container_of(w, struct delayed_work, work);
+ struct delayed_work *dw = to_delayed_work(w);
board_info_t *db = container_of(dw, board_info_t, phy_poll);
struct net_device *ndev = db->ndev;
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index 2d0a198882a..8bbe7f61799 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -1134,9 +1134,9 @@ static int mpc52xx_fec_of_resume(struct of_device *op)
#endif
static struct of_device_id mpc52xx_fec_match[] = {
- { .type = "network", .compatible = "fsl,mpc5200b-fec", },
- { .type = "network", .compatible = "fsl,mpc5200-fec", },
- { .type = "network", .compatible = "mpc5200-fec", },
+ { .compatible = "fsl,mpc5200b-fec", },
+ { .compatible = "fsl,mpc5200-fec", },
+ { .compatible = "mpc5200-fec", },
{ }
};
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 1243bc8e003..ac0e4b6b6b6 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -1871,13 +1871,6 @@ static int __init vlsi_mod_init(void)
* without procfs - it's not required for the driver to work.
*/
vlsi_proc_root = proc_mkdir(PROC_DIR, NULL);
- if (vlsi_proc_root) {
- /* protect registered procdir against module removal.
- * Because we are in the module init path there's no race
- * window after create_proc_entry (and no barrier needed).
- */
- vlsi_proc_root->owner = THIS_MODULE;
- }
ret = pci_register_driver(&vlsi_irda_driver);
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index c336a1f4251..aa08987f6e8 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -398,7 +398,7 @@ static void meth_rx(struct net_device* dev, unsigned long int_status)
int len = (status & 0xffff) - 4; /* omit CRC */
/* length sanity check */
if (len < 60 || len > 1518) {
- printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2lx.\n",
+ printk(KERN_DEBUG "%s: bogus packet size: %ld, status=%#2Lx.\n",
dev->name, priv->rx_write,
priv->rx_ring[priv->rx_write]->status.raw);
dev->stats.rx_errors++;
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 9f6644a4403..303c23de6ca 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -505,7 +505,7 @@ out:
static void mlx4_en_do_get_stats(struct work_struct *work)
{
- struct delayed_work *delay = container_of(work, struct delayed_work, work);
+ struct delayed_work *delay = to_delayed_work(work);
struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
stats_task);
struct mlx4_en_dev *mdev = priv->mdev;
diff --git a/drivers/net/mlx4/en_rx.c b/drivers/net/mlx4/en_rx.c
index a4130e76499..7e40741fb7d 100644
--- a/drivers/net/mlx4/en_rx.c
+++ b/drivers/net/mlx4/en_rx.c
@@ -298,7 +298,7 @@ static void mlx4_en_free_rx_buf(struct mlx4_en_priv *priv,
void mlx4_en_rx_refill(struct work_struct *work)
{
- struct delayed_work *delay = container_of(work, struct delayed_work, work);
+ struct delayed_work *delay = to_delayed_work(work);
struct mlx4_en_priv *priv = container_of(delay, struct mlx4_en_priv,
refill_task);
struct mlx4_en_dev *mdev = priv->mdev;
diff --git a/drivers/net/mlx4/sense.c b/drivers/net/mlx4/sense.c
index 6d5089ecb5a..f36ae691cab 100644
--- a/drivers/net/mlx4/sense.c
+++ b/drivers/net/mlx4/sense.c
@@ -103,7 +103,7 @@ void mlx4_do_sense_ports(struct mlx4_dev *dev,
static void mlx4_sense_port(struct work_struct *work)
{
- struct delayed_work *delay = container_of(work, struct delayed_work, work);
+ struct delayed_work *delay = to_delayed_work(work);
struct mlx4_sense *sense = container_of(delay, struct mlx4_sense,
sense_poll);
struct mlx4_dev *dev = sense->dev;
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 58b73b08dde..3ff1f425f1b 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -757,8 +757,7 @@ EXPORT_SYMBOL(phy_start);
*/
static void phy_state_machine(struct work_struct *work)
{
- struct delayed_work *dwork =
- container_of(work, struct delayed_work, work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct phy_device *phydev =
container_of(dwork, struct phy_device, state_queue);
int needs_aneg = 0;
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 88dd2e09832..ce7551e17ba 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2299,7 +2299,7 @@ static int sbmac_init(struct platform_device *pldev, long long base)
eaddr = sc->sbm_hwaddr;
/*
- * Read the ethernet address. The firwmare left this programmed
+ * Read the ethernet address. The firmware left this programmed
* for us in the ethernet address register for each mac.
*/
diff --git a/drivers/net/skfp/h/hwmtm.h b/drivers/net/skfp/h/hwmtm.h
index 1a606d4bfe5..e1a7e5f683d 100644
--- a/drivers/net/skfp/h/hwmtm.h
+++ b/drivers/net/skfp/h/hwmtm.h
@@ -145,7 +145,7 @@ struct hw_modul {
int leave_isr ; /* leave fddi_isr immedeately if set */
int isr_flag ; /* set, when HWM is entered from isr */
/*
- * varaibles for the current transmit frame
+ * variables for the current transmit frame
*/
struct s_smt_tx_queue *tx_p ; /* pointer to the transmit queue */
u_long tx_descr ; /* tx descriptor for FORMAC+ */
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 6c44f86ae3f..912308eec86 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -346,38 +346,6 @@ static inline void LPD7_SMC_outsw (unsigned char* a, int r,
#define RPC_LSA_DEFAULT RPC_LED_TX_RX
#define RPC_LSB_DEFAULT RPC_LED_100_10
-#elif defined(CONFIG_SOC_AU1X00)
-
-#include <au1xxx.h>
-
-/* We can only do 16-bit reads and writes in the static memory space. */
-#define SMC_CAN_USE_8BIT 0
-#define SMC_CAN_USE_16BIT 1
-#define SMC_CAN_USE_32BIT 0
-#define SMC_IO_SHIFT 0
-#define SMC_NOWAIT 1
-
-#define SMC_inw(a, r) au_readw((unsigned long)((a) + (r)))
-#define SMC_insw(a, r, p, l) \
- do { \
- unsigned long _a = (unsigned long)((a) + (r)); \
- int _l = (l); \
- u16 *_p = (u16 *)(p); \
- while (_l-- > 0) \
- *_p++ = au_readw(_a); \
- } while(0)
-#define SMC_outw(v, a, r) au_writew(v, (unsigned long)((a) + (r)))
-#define SMC_outsw(a, r, p, l) \
- do { \
- unsigned long _a = (unsigned long)((a) + (r)); \
- int _l = (l); \
- const u16 *_p = (const u16 *)(p); \
- while (_l-- > 0) \
- au_writew(*_p++ , _a); \
- } while(0)
-
-#define SMC_IRQ_FLAGS (0)
-
#elif defined(CONFIG_ARCH_VERSATILE)
#define SMC_CAN_USE_8BIT 1
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1205c2a2265..437683aab32 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -11225,7 +11225,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp)
return tg3_phy_init(tp);
/* Reading the PHY ID register can conflict with ASF
- * firwmare access to the PHY hardware.
+ * firmware access to the PHY hardware.
*/
err = 0;
if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) ||
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 00945f7c1e9..25c9ef6a181 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -69,7 +69,7 @@ MODULE_LICENSE("GPL");
#endif
/*
- * Modules parameters and associated varaibles
+ * Modules parameters and associated variables
*/
static int fst_txq_low = FST_LOW_WATER_MARK;
static int fst_txq_high = FST_HIGH_WATER_MARK;
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 93302c0a36b..f21a6171c69 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -4492,7 +4492,6 @@ static int setup_proc_entry( struct net_device *dev,
goto fail;
apriv->proc_entry->uid = proc_uid;
apriv->proc_entry->gid = proc_gid;
- apriv->proc_entry->owner = THIS_MODULE;
/* Setup the StatsDelta */
entry = proc_create_data("StatsDelta",
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 115b7048750..f4e963ba768 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -2362,7 +2362,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
i * sizeof(struct ipw2100_status));
#ifdef IPW2100_DEBUG_C3
- /* Halt the fimrware so we can get a good image */
+ /* Halt the firmware so we can get a good image */
write_register(priv->net_dev, IPW_REG_RESET_REG,
IPW_AUX_HOST_RESET_REG_STOP_MASTER);
j = 5;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 4a92af1d787..e17a4593e1f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -8844,7 +8844,7 @@ static int ipw_wx_set_mode(struct net_device *dev,
#endif /* CONFIG_IPW2200_MONITOR */
/* Free the existing firmware and reset the fw_loaded
- * flag so ipw_load() will bring in the new firmawre */
+ * flag so ipw_load() will bring in the new firmware */
free_firmware();
priv->ieee->iw_mode = wrqu->mode;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 663dc83be50..3889158b359 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1337,7 +1337,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
- * on the API version read from firware header from here on forward */
+ * on the API version read from firmware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
IWL_ERR(priv, "Driver unable to support your firmware API. "
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index a71b08ca7c7..9d5f97dd7c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2562,7 +2562,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
- * on the API version read from firware header from here on forward */
+ * on the API version read from firmware header from here on forward */
if (api_ver < api_min || api_ver > api_max) {
IWL_ERR(priv, "Driver unable to support your firmware API. "
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 639dd02d3d3..8c3605cdc64 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -1649,7 +1649,7 @@ static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
/**
* @brief This function executes next command in command
- * pending queue. It will put fimware back to PS mode
+ * pending queue. It will put firmware back to PS mode
* if applicable.
*
* @param priv A pointer to struct lbs_private structure
diff --git a/drivers/of/base.c b/drivers/of/base.c
index cd17092b82b..41c5dfd8535 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -446,6 +446,7 @@ struct of_modalias_table {
};
static struct of_modalias_table of_modalias_table[] = {
{ "fsl,mcu-mpc8349emitx", "mcu-mpc8349emitx" },
+ { "mmc-spi-slot", "mmc_spi" },
};
/**
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index c3ea5fa7d05..8574622e36a 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -154,6 +154,10 @@ int sync_start(void)
{
int err;
+ if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+ return -ENOMEM;
+ cpumask_clear(marked_cpus);
+
start_cpu_work();
err = task_handoff_register(&task_free_nb);
@@ -179,6 +183,7 @@ out2:
task_handoff_unregister(&task_free_nb);
out1:
end_sync();
+ free_cpumask_var(marked_cpus);
goto out;
}
@@ -190,6 +195,7 @@ void sync_stop(void)
profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb);
task_handoff_unregister(&task_free_nb);
end_sync();
+ free_cpumask_var(marked_cpus);
}
@@ -565,20 +571,6 @@ void sync_buffer(int cpu)
mutex_unlock(&buffer_mutex);
}
-int __init buffer_sync_init(void)
-{
- if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
- return -ENOMEM;
-
- cpumask_clear(marked_cpus);
- return 0;
-}
-
-void __exit buffer_sync_cleanup(void)
-{
- free_cpumask_var(marked_cpus);
-}
-
/* The function can be used to add a buffer worth of data directly to
* the kernel buffer. The buffer is assumed to be a circular buffer.
* Take the entries from index start and end at index end, wrapping
diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h
index 0ebf5db6267..3110732c183 100644
--- a/drivers/oprofile/buffer_sync.h
+++ b/drivers/oprofile/buffer_sync.h
@@ -19,8 +19,4 @@ void sync_stop(void);
/* sync the given CPU's buffer */
void sync_buffer(int cpu);
-/* initialize/destroy the buffer system. */
-int buffer_sync_init(void);
-void buffer_sync_cleanup(void);
-
#endif /* OPROFILE_BUFFER_SYNC_H */
diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c
index e76d715e434..f0e99d4c066 100644
--- a/drivers/oprofile/cpu_buffer.c
+++ b/drivers/oprofile/cpu_buffer.c
@@ -161,7 +161,7 @@ struct op_sample
{
entry->event = ring_buffer_lock_reserve
(op_ring_buffer_write, sizeof(struct op_sample) +
- size * sizeof(entry->sample->data[0]), &entry->irq_flags);
+ size * sizeof(entry->sample->data[0]));
if (entry->event)
entry->sample = ring_buffer_event_data(entry->event);
else
@@ -178,8 +178,7 @@ struct op_sample
int op_cpu_buffer_write_commit(struct op_entry *entry)
{
- return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event,
- entry->irq_flags);
+ return ring_buffer_unlock_commit(op_ring_buffer_write, entry->event);
}
struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu)
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index ced39f60229..3cffce90f82 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -183,10 +183,6 @@ static int __init oprofile_init(void)
{
int err;
- err = buffer_sync_init();
- if (err)
- return err;
-
err = oprofile_arch_init(&oprofile_ops);
if (err < 0 || timer) {
@@ -195,10 +191,8 @@ static int __init oprofile_init(void)
}
err = oprofilefs_register();
- if (err) {
+ if (err)
oprofile_arch_exit();
- buffer_sync_cleanup();
- }
return err;
}
@@ -208,7 +202,6 @@ static void __exit oprofile_exit(void)
{
oprofilefs_unregister();
oprofile_arch_exit();
- buffer_sync_cleanup();
}
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 7931133526c..9ca21098b14 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -81,7 +81,7 @@ static int __init asp_init_chip(struct parisc_device *dev)
asp.hpa = ASP_INTERRUPT_ADDR;
printk(KERN_INFO "%s version %d at 0x%lx found.\n",
- asp.name, asp.version, dev->hpa.start);
+ asp.name, asp.version, (unsigned long)dev->hpa.start);
/* the IRQ ASP should use */
ret = -EBUSY;
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index cd4dd7ed2c0..5d610cbcfe8 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -406,8 +406,6 @@ resource_found:
}
ioc->avg_search[ioc->avg_idx++] = cr_start;
ioc->avg_idx &= CCIO_SEARCH_SAMPLE - 1;
-#endif
-#ifdef CCIO_COLLECT_STATS
ioc->used_pages += pages_needed;
#endif
/*
@@ -453,10 +451,10 @@ ccio_free_range(struct ioc *ioc, dma_addr_t iova, unsigned long pages_mapped)
unsigned long mask = ~(~0UL >> pages_mapped);
CCIO_FREE_MAPPINGS(ioc, res_idx, mask, 8);
#else
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xff, 8);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffUL, 8);
#endif
} else if(pages_mapped <= 16) {
- CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffff, 16);
+ CCIO_FREE_MAPPINGS(ioc, res_idx, 0xffffUL, 16);
} else if(pages_mapped <= 32) {
CCIO_FREE_MAPPINGS(ioc, res_idx, ~(unsigned int)0, 32);
#ifdef __LP64__
@@ -1028,8 +1026,10 @@ static int ccio_proc_info(struct seq_file *m, void *p)
while (ioc != NULL) {
unsigned int total_pages = ioc->res_size << 3;
+#ifdef CCIO_COLLECT_STATS
unsigned long avg = 0, min, max;
int j;
+#endif
len += seq_printf(m, "%s\n", ioc->name);
@@ -1060,8 +1060,7 @@ static int ccio_proc_info(struct seq_file *m, void *p)
avg /= CCIO_SEARCH_SAMPLE;
len += seq_printf(m, " Bitmap search : %ld/%ld/%ld (min/avg/max CPU Cycles)\n",
min, avg, max);
-#endif
-#ifdef CCIO_COLLECT_STATS
+
len += seq_printf(m, "pci_map_single(): %8ld calls %8ld pages (avg %d/1000)\n",
ioc->msingle_calls, ioc->msingle_pages,
(int)((ioc->msingle_pages * 1000)/ioc->msingle_calls));
@@ -1400,7 +1399,7 @@ ccio_init_resource(struct resource *res, char *name, void __iomem *ioaddr)
result = insert_resource(&iomem_resource, res);
if (result < 0) {
printk(KERN_ERR "%s() failed to claim CCIO bus address space (%08lx,%08lx)\n",
- __func__, res->start, res->end);
+ __func__, (unsigned long)res->start, (unsigned long)res->end);
}
}
@@ -1551,7 +1550,8 @@ static int __init ccio_probe(struct parisc_device *dev)
ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
- printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
+ printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name,
+ (unsigned long)dev->hpa.start);
for (i = 0; i < ioc_count; i++) {
ioc_p = &(*ioc_p)->next;
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index bb5a1c9597c..52ae0b1d470 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -819,7 +819,9 @@ dino_bridge_init(struct dino_device *dino_dev, const char *name)
result = ccio_request_resource(dino_dev->hba.dev, &res[i]);
if (result < 0) {
- printk(KERN_ERR "%s: failed to claim PCI Bus address space %d (0x%lx-0x%lx)!\n", name, i, res[i].start, res[i].end);
+ printk(KERN_ERR "%s: failed to claim PCI Bus address "
+ "space %d (0x%lx-0x%lx)!\n", name, i,
+ (unsigned long)res[i].start, (unsigned long)res[i].end);
return result;
}
}
@@ -899,7 +901,8 @@ static int __init dino_common_init(struct parisc_device *dev,
if (request_resource(&ioport_resource, res) < 0) {
printk(KERN_ERR "%s: request I/O Port region failed "
"0x%lx/%lx (hpa 0x%p)\n",
- name, res->start, res->end, dino_dev->hba.base_addr);
+ name, (unsigned long)res->start, (unsigned long)res->end,
+ dino_dev->hba.base_addr);
return 1;
}
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 7891db50c48..f415fdd9a88 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -314,7 +314,7 @@ static int __init eisa_probe(struct parisc_device *dev)
char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n",
- name, dev->hpa.start);
+ name, (unsigned long)dev->hpa.start);
eisa_dev.hba.dev = dev;
eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/parisc/eisa_enumerator.c b/drivers/parisc/eisa_enumerator.c
index 6d8aae003f6..c709ecc2b7f 100644
--- a/drivers/parisc/eisa_enumerator.c
+++ b/drivers/parisc/eisa_enumerator.c
@@ -98,7 +98,7 @@ static int configure_memory(const unsigned char *buf,
res->start = mem_parent->start + get_24(buf+len+2);
res->end = res->start + get_16(buf+len+5)*1024;
res->flags = IORESOURCE_MEM;
- printk("memory %lx-%lx ", res->start, res->end);
+ printk("memory %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(mem_parent, res);
if (result < 0) {
printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
@@ -188,7 +188,7 @@ static int configure_port(const unsigned char *buf, struct resource *io_parent,
res->start = get_16(buf+len+1);
res->end = get_16(buf+len+1)+(c&HPEE_PORT_SIZE_MASK)+1;
res->flags = IORESOURCE_IO;
- printk("ioports %lx-%lx ", res->start, res->end);
+ printk("ioports %lx-%lx ", (unsigned long)res->start, (unsigned long)res->end);
result = request_resource(io_parent, res);
if (result < 0) {
printk("\n" KERN_ERR "EISA Enumerator: failed to claim EISA Bus address space!\n");
diff --git a/drivers/parisc/iosapic.c b/drivers/parisc/iosapic.c
index 501aaf1f253..73348c4047e 100644
--- a/drivers/parisc/iosapic.c
+++ b/drivers/parisc/iosapic.c
@@ -714,7 +714,7 @@ static void iosapic_set_affinity_irq(unsigned int irq,
if (dest_cpu < 0)
return;
- irq_desc[irq].affinity = cpumask_of_cpu(dest_cpu);
+ cpumask_copy(irq_desc[irq].affinity, cpumask_of(dest_cpu));
vi->txn_addr = txn_affinity_addr(irq, dest_cpu);
spin_lock_irqsave(&iosapic_lock, flags);
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index 454b6532e40..9581d361945 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -3,7 +3,7 @@
*
* (c) Copyright 2000 Red Hat Software
* (c) Copyright 2000 Helge Deller <hdeller@redhat.com>
- * (c) Copyright 2001-2005 Helge Deller <deller@gmx.de>
+ * (c) Copyright 2001-2009 Helge Deller <deller@gmx.de>
* (c) Copyright 2001 Randolph Chung <tausq@debian.org>
*
* This program is free software; you can redistribute it and/or modify
@@ -243,13 +243,11 @@ static int __init led_create_procfs(void)
proc_pdc_root = proc_mkdir("pdc", 0);
if (!proc_pdc_root) return -1;
- proc_pdc_root->owner = THIS_MODULE;
ent = create_proc_entry("led", S_IFREG|S_IRUGO|S_IWUSR, proc_pdc_root);
if (!ent) return -1;
ent->data = (void *)LED_NOLCD; /* LED */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
if (led_type == LED_HASLCD)
{
@@ -258,7 +256,6 @@ static int __init led_create_procfs(void)
ent->data = (void *)LED_HASLCD; /* LCD */
ent->read_proc = led_proc_read;
ent->write_proc = led_proc_write;
- ent->owner = THIS_MODULE;
}
return 0;
@@ -463,9 +460,20 @@ static void led_work_func (struct work_struct *unused)
if (likely(led_lanrxtx)) currentleds |= led_get_net_activity();
if (likely(led_diskio)) currentleds |= led_get_diskio_activity();
- /* blink all LEDs twice a second if we got an Oops (HPMC) */
- if (unlikely(oops_in_progress))
- currentleds = (count_HZ<=(HZ/2)) ? 0 : 0xff;
+ /* blink LEDs if we got an Oops (HPMC) */
+ if (unlikely(oops_in_progress)) {
+ if (boot_cpu_data.cpu_type >= pcxl2) {
+ /* newer machines don't have loadavg. LEDs, so we
+ * let all LEDs blink twice per second instead */
+ currentleds = (count_HZ <= (HZ/2)) ? 0 : 0xff;
+ } else {
+ /* old machines: blink loadavg. LEDs twice per second */
+ if (count_HZ <= (HZ/2))
+ currentleds &= ~(LED4|LED5|LED6|LED7);
+ else
+ currentleds |= (LED4|LED5|LED6|LED7);
+ }
+ }
if (currentleds != lastleds)
{
@@ -511,7 +519,7 @@ static int led_halt(struct notifier_block *nb, unsigned long event, void *buf)
/* Cancel the work item and delete the queue */
if (led_wq) {
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
destroy_workqueue(led_wq);
led_wq = NULL;
}
@@ -630,7 +638,7 @@ int lcd_print( const char *str )
/* temporarily disable the led work task */
if (led_wq)
- cancel_rearming_delayed_workqueue(led_wq, &led_task);
+ cancel_delayed_work_sync(&led_task);
/* copy display string to buffer for procfs */
strlcpy(lcd_text, str, sizeof(lcd_text));
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c
index 032db815b0f..f3492110b1a 100644
--- a/drivers/parport/parport_serial.c
+++ b/drivers/parport/parport_serial.c
@@ -30,6 +30,7 @@ enum parport_pc_pci_cards {
titan_210l,
netmos_9xx5_combo,
netmos_9855,
+ netmos_9855_2p,
avlab_1s1p,
avlab_1s2p,
avlab_2s1p,
@@ -62,7 +63,7 @@ struct parport_pc_pci {
struct parport_pc_pci *card, int failed);
};
-static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *card, int autoirq, int autodma)
+static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, int autoirq, int autodma)
{
/* the rule described below doesn't hold for this device */
if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
@@ -74,9 +75,17 @@ static int __devinit netmos_parallel_init(struct pci_dev *dev, struct parport_pc
* and serial ports. The form is 0x00PS, where <P> is the number of
* parallel ports and <S> is the number of serial ports.
*/
- card->numports = (dev->subsystem_device & 0xf0) >> 4;
- if (card->numports > ARRAY_SIZE(card->addr))
- card->numports = ARRAY_SIZE(card->addr);
+ par->numports = (dev->subsystem_device & 0xf0) >> 4;
+ if (par->numports > ARRAY_SIZE(par->addr))
+ par->numports = ARRAY_SIZE(par->addr);
+ /*
+ * This function is currently only called for cards with up to
+ * one parallel port.
+ * Parallel port BAR is either before or after serial ports BARS;
+ * hence, lo should be either 0 or equal to the number of serial ports.
+ */
+ if (par->addr[0].lo != 0)
+ par->addr[0].lo = dev->subsystem_device & 0xf;
return 0;
}
@@ -84,7 +93,8 @@ static struct parport_pc_pci cards[] __devinitdata = {
/* titan_110l */ { 1, { { 3, -1 }, } },
/* titan_210l */ { 1, { { 3, -1 }, } },
/* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init },
- /* netmos_9855 */ { 1, { { 2, -1 }, }, netmos_parallel_init },
+ /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init },
+ /* netmos_9855_2p */ { 2, { { 0, -1 }, { 2, -1 }, } },
/* avlab_1s1p */ { 1, { { 1, 2}, } },
/* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} },
/* avlab_2s1p */ { 1, { { 2, 3}, } },
@@ -110,6 +120,10 @@ static struct pci_device_id parport_serial_pci_tbl[] = {
{ 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,
+ 0x1000, 0x0020, 0, 0, netmos_9855_2p },
+ { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
+ 0x1000, 0x0022, 0, 0, netmos_9855_2p },
+ { 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,
@@ -192,6 +206,12 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = {
.uart_offset = 8,
},
[netmos_9855] = {
+ .flags = FL_BASE2 | FL_BASE_BARS,
+ .num_ports = 1,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [netmos_9855_2p] = {
.flags = FL_BASE4 | FL_BASE_BARS,
.num_ports = 1,
.base_baud = 115200,
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 2a4501dd251..fdc864f9cf2 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -59,3 +59,13 @@ config HT_IRQ
This allows native hypertransport devices to use interrupts.
If unsure say Y.
+
+config PCI_IOV
+ bool "PCI IOV support"
+ depends on PCI
+ help
+ I/O Virtualization is a PCI feature supported by some devices
+ which allows them to create virtual devices which share their
+ physical resources.
+
+ If unsure, say N.
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 3d07ce24f6a..ba6af162fd3 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -29,6 +29,8 @@ obj-$(CONFIG_DMAR) += dmar.o iova.o intel-iommu.o
obj-$(CONFIG_INTR_REMAP) += dmar.o intr_remapping.o
+obj-$(CONFIG_PCI_IOV) += iov.o
+
#
# Some architectures use the generic PCI setup functions
#
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 52b54f053be..68f91a25259 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -133,7 +133,7 @@ int pci_bus_add_child(struct pci_bus *bus)
*
* Call hotplug for each new devices.
*/
-void pci_bus_add_devices(struct pci_bus *bus)
+void pci_bus_add_devices(const struct pci_bus *bus)
{
struct pci_dev *dev;
struct pci_bus *child;
@@ -184,8 +184,10 @@ void pci_enable_bridges(struct pci_bus *bus)
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->subordinate) {
- retval = pci_enable_device(dev);
- pci_set_master(dev);
+ if (atomic_read(&dev->enable_cnt) == 0) {
+ retval = pci_enable_device(dev);
+ pci_set_master(dev);
+ }
pci_enable_bridges(dev->subordinate);
}
}
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 5f333403c2e..25a00ce4f24 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -31,6 +31,8 @@
#include <linux/iova.h>
#include <linux/intel-iommu.h>
#include <linux/timer.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
#undef PREFIX
#define PREFIX "DMAR:"
@@ -178,6 +180,7 @@ dmar_parse_one_drhd(struct acpi_dmar_header *header)
dmaru->hdr = header;
drhd = (struct acpi_dmar_hardware_unit *)header;
dmaru->reg_base_addr = drhd->address;
+ dmaru->segment = drhd->segment;
dmaru->include_all = drhd->flags & 0x1; /* BIT0: INCLUDE_ALL */
ret = alloc_iommu(dmaru);
@@ -509,6 +512,7 @@ int alloc_iommu(struct dmar_drhd_unit *drhd)
return -ENOMEM;
iommu->seq_id = iommu_allocated++;
+ sprintf (iommu->name, "dmar%d", iommu->seq_id);
iommu->reg = ioremap(drhd->reg_base_addr, VTD_PAGE_SIZE);
if (!iommu->reg) {
@@ -751,14 +755,77 @@ int qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
}
/*
+ * Disable Queued Invalidation interface.
+ */
+void dmar_disable_qi(struct intel_iommu *iommu)
+{
+ unsigned long flags;
+ u32 sts;
+ cycles_t start_time = get_cycles();
+
+ if (!ecap_qis(iommu->ecap))
+ return;
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
+ if (!(sts & DMA_GSTS_QIES))
+ goto end;
+
+ /*
+ * Give a chance to HW to complete the pending invalidation requests.
+ */
+ while ((readl(iommu->reg + DMAR_IQT_REG) !=
+ readl(iommu->reg + DMAR_IQH_REG)) &&
+ (DMAR_OPERATION_TIMEOUT > (get_cycles() - start_time)))
+ cpu_relax();
+
+ iommu->gcmd &= ~DMA_GCMD_QIE;
+
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl,
+ !(sts & DMA_GSTS_QIES), sts);
+end:
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
+/*
+ * Enable queued invalidation.
+ */
+static void __dmar_enable_qi(struct intel_iommu *iommu)
+{
+ u32 cmd, sts;
+ unsigned long flags;
+ struct q_inval *qi = iommu->qi;
+
+ qi->free_head = qi->free_tail = 0;
+ qi->free_cnt = QI_LENGTH;
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ /* write zero to the tail reg */
+ writel(0, iommu->reg + DMAR_IQT_REG);
+
+ dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
+
+ cmd = iommu->gcmd | DMA_GCMD_QIE;
+ iommu->gcmd |= DMA_GCMD_QIE;
+ writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+ /* Make sure hardware complete it */
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
+/*
* Enable Queued Invalidation interface. This is a must to support
* interrupt-remapping. Also used by DMA-remapping, which replaces
* register based IOTLB invalidation.
*/
int dmar_enable_qi(struct intel_iommu *iommu)
{
- u32 cmd, sts;
- unsigned long flags;
struct q_inval *qi;
if (!ecap_qis(iommu->ecap))
@@ -770,20 +837,20 @@ int dmar_enable_qi(struct intel_iommu *iommu)
if (iommu->qi)
return 0;
- iommu->qi = kmalloc(sizeof(*qi), GFP_KERNEL);
+ iommu->qi = kmalloc(sizeof(*qi), GFP_ATOMIC);
if (!iommu->qi)
return -ENOMEM;
qi = iommu->qi;
- qi->desc = (void *)(get_zeroed_page(GFP_KERNEL));
+ qi->desc = (void *)(get_zeroed_page(GFP_ATOMIC));
if (!qi->desc) {
kfree(qi);
iommu->qi = 0;
return -ENOMEM;
}
- qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_KERNEL);
+ qi->desc_status = kmalloc(QI_LENGTH * sizeof(int), GFP_ATOMIC);
if (!qi->desc_status) {
free_page((unsigned long) qi->desc);
kfree(qi);
@@ -796,19 +863,283 @@ int dmar_enable_qi(struct intel_iommu *iommu)
spin_lock_init(&qi->q_lock);
- spin_lock_irqsave(&iommu->register_lock, flags);
- /* write zero to the tail reg */
- writel(0, iommu->reg + DMAR_IQT_REG);
+ __dmar_enable_qi(iommu);
- dmar_writeq(iommu->reg + DMAR_IQA_REG, virt_to_phys(qi->desc));
+ return 0;
+}
- cmd = iommu->gcmd | DMA_GCMD_QIE;
- iommu->gcmd |= DMA_GCMD_QIE;
- writel(cmd, iommu->reg + DMAR_GCMD_REG);
+/* iommu interrupt handling. Most stuff are MSI-like. */
- /* Make sure hardware complete it */
- IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, readl, (sts & DMA_GSTS_QIES), sts);
- spin_unlock_irqrestore(&iommu->register_lock, flags);
+enum faulttype {
+ DMA_REMAP,
+ INTR_REMAP,
+ UNKNOWN,
+};
+
+static const char *dma_remap_fault_reasons[] =
+{
+ "Software",
+ "Present bit in root entry is clear",
+ "Present bit in context entry is clear",
+ "Invalid context entry",
+ "Access beyond MGAW",
+ "PTE Write access is not set",
+ "PTE Read access is not set",
+ "Next page table ptr is invalid",
+ "Root table address invalid",
+ "Context table ptr is invalid",
+ "non-zero reserved fields in RTP",
+ "non-zero reserved fields in CTP",
+ "non-zero reserved fields in PTE",
+};
+
+static const char *intr_remap_fault_reasons[] =
+{
+ "Detected reserved fields in the decoded interrupt-remapped request",
+ "Interrupt index exceeded the interrupt-remapping table size",
+ "Present field in the IRTE entry is clear",
+ "Error accessing interrupt-remapping table pointed by IRTA_REG",
+ "Detected reserved fields in the IRTE entry",
+ "Blocked a compatibility format interrupt request",
+ "Blocked an interrupt request due to source-id verification failure",
+};
+
+#define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1)
+
+const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
+{
+ if (fault_reason >= 0x20 && (fault_reason <= 0x20 +
+ ARRAY_SIZE(intr_remap_fault_reasons))) {
+ *fault_type = INTR_REMAP;
+ return intr_remap_fault_reasons[fault_reason - 0x20];
+ } else if (fault_reason < ARRAY_SIZE(dma_remap_fault_reasons)) {
+ *fault_type = DMA_REMAP;
+ return dma_remap_fault_reasons[fault_reason];
+ } else {
+ *fault_type = UNKNOWN;
+ return "Unknown";
+ }
+}
+
+void dmar_msi_unmask(unsigned int irq)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ /* unmask it */
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(0, iommu->reg + DMAR_FECTL_REG);
+ /* Read a reg to force flush the post write */
+ readl(iommu->reg + DMAR_FECTL_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_mask(unsigned int irq)
+{
+ unsigned long flag;
+ struct intel_iommu *iommu = get_irq_data(irq);
+
+ /* mask it */
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
+ /* Read a reg to force flush the post write */
+ readl(iommu->reg + DMAR_FECTL_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_write(int irq, struct msi_msg *msg)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
+ writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
+ writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+void dmar_msi_read(int irq, struct msi_msg *msg)
+{
+ struct intel_iommu *iommu = get_irq_data(irq);
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
+ msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
+ msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+}
+
+static int dmar_fault_do_one(struct intel_iommu *iommu, int type,
+ u8 fault_reason, u16 source_id, unsigned long long addr)
+{
+ const char *reason;
+ int fault_type;
+
+ reason = dmar_get_fault_reason(fault_reason, &fault_type);
+
+ if (fault_type == INTR_REMAP)
+ printk(KERN_ERR "INTR-REMAP: Request device [[%02x:%02x.%d] "
+ "fault index %llx\n"
+ "INTR-REMAP:[fault reason %02d] %s\n",
+ (source_id >> 8), PCI_SLOT(source_id & 0xFF),
+ PCI_FUNC(source_id & 0xFF), addr >> 48,
+ fault_reason, reason);
+ else
+ printk(KERN_ERR
+ "DMAR:[%s] Request device [%02x:%02x.%d] "
+ "fault addr %llx \n"
+ "DMAR:[fault reason %02d] %s\n",
+ (type ? "DMA Read" : "DMA Write"),
+ (source_id >> 8), PCI_SLOT(source_id & 0xFF),
+ PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
+ return 0;
+}
+
+#define PRIMARY_FAULT_REG_LEN (16)
+irqreturn_t dmar_fault(int irq, void *dev_id)
+{
+ struct intel_iommu *iommu = dev_id;
+ int reg, fault_index;
+ u32 fault_status;
+ unsigned long flag;
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+ if (fault_status)
+ printk(KERN_ERR "DRHD: handling fault status reg %x\n",
+ fault_status);
+
+ /* TBD: ignore advanced fault log currently */
+ if (!(fault_status & DMA_FSTS_PPF))
+ goto clear_rest;
+
+ fault_index = dma_fsts_fault_record_index(fault_status);
+ reg = cap_fault_reg_offset(iommu->cap);
+ while (1) {
+ u8 fault_reason;
+ u16 source_id;
+ u64 guest_addr;
+ int type;
+ u32 data;
+
+ /* highest 32 bits */
+ data = readl(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 12);
+ if (!(data & DMA_FRCD_F))
+ break;
+
+ fault_reason = dma_frcd_fault_reason(data);
+ type = dma_frcd_type(data);
+
+ data = readl(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 8);
+ source_id = dma_frcd_source_id(data);
+
+ guest_addr = dmar_readq(iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN);
+ guest_addr = dma_frcd_page_addr(guest_addr);
+ /* clear the fault */
+ writel(DMA_FRCD_F, iommu->reg + reg +
+ fault_index * PRIMARY_FAULT_REG_LEN + 12);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+
+ dmar_fault_do_one(iommu, type, fault_reason,
+ source_id, guest_addr);
+
+ fault_index++;
+ if (fault_index > cap_num_fault_regs(iommu->cap))
+ fault_index = 0;
+ spin_lock_irqsave(&iommu->register_lock, flag);
+ }
+clear_rest:
+ /* clear all the other faults */
+ fault_status = readl(iommu->reg + DMAR_FSTS_REG);
+ writel(fault_status, iommu->reg + DMAR_FSTS_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ return IRQ_HANDLED;
+}
+
+int dmar_set_interrupt(struct intel_iommu *iommu)
+{
+ int irq, ret;
+
+ /*
+ * Check if the fault interrupt is already initialized.
+ */
+ if (iommu->irq)
+ return 0;
+
+ irq = create_irq();
+ if (!irq) {
+ printk(KERN_ERR "IOMMU: no free vectors\n");
+ return -EINVAL;
+ }
+
+ set_irq_data(irq, iommu);
+ iommu->irq = irq;
+
+ ret = arch_setup_dmar_msi(irq);
+ if (ret) {
+ set_irq_data(irq, NULL);
+ iommu->irq = 0;
+ destroy_irq(irq);
+ return 0;
+ }
+
+ ret = request_irq(irq, dmar_fault, 0, iommu->name, iommu);
+ if (ret)
+ printk(KERN_ERR "IOMMU: can't request irq\n");
+ return ret;
+}
+
+int __init enable_drhd_fault_handling(void)
+{
+ struct dmar_drhd_unit *drhd;
+
+ /*
+ * Enable fault control interrupt.
+ */
+ for_each_drhd_unit(drhd) {
+ int ret;
+ struct intel_iommu *iommu = drhd->iommu;
+ ret = dmar_set_interrupt(iommu);
+
+ if (ret) {
+ printk(KERN_ERR "DRHD %Lx: failed to enable fault, "
+ " interrupt, ret %d\n",
+ (unsigned long long)drhd->reg_base_addr, ret);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Re-enable Queued Invalidation interface.
+ */
+int dmar_reenable_qi(struct intel_iommu *iommu)
+{
+ if (!ecap_qis(iommu->ecap))
+ return -ENOENT;
+
+ if (!iommu->qi)
+ return -ENOENT;
+
+ /*
+ * First disable queued invalidation.
+ */
+ dmar_disable_qi(iommu);
+ /*
+ * Then enable queued invalidation again. Since there is no pending
+ * invalidation requests now, it's safe to re-enable queued
+ * invalidation.
+ */
+ __dmar_enable_qi(iommu);
return 0;
}
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 1c114180106..fbc63d5e459 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -30,9 +30,8 @@
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
+#include <linux/acpi.h>
#include <linux/pci-acpi.h>
-#include <acpi/acpi.h>
-#include <acpi/acpi_bus.h>
#define MY_NAME "acpi_pcihp"
@@ -333,19 +332,14 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus,
{
acpi_status status = AE_NOT_FOUND;
acpi_handle handle, phandle;
- struct pci_bus *pbus = bus;
- struct pci_dev *pdev;
-
- do {
- pdev = pbus->self;
- if (!pdev) {
- handle = acpi_get_pci_rootbridge_handle(
- pci_domain_nr(pbus), pbus->number);
+ struct pci_bus *pbus;
+
+ handle = NULL;
+ for (pbus = bus; pbus; pbus = pbus->parent) {
+ handle = acpi_pci_get_bridge_handle(pbus);
+ if (handle)
break;
- }
- handle = DEVICE_ACPI_HANDLE(&(pdev->dev));
- pbus = pbus->parent;
- } while (!handle);
+ }
/*
* _HPP settings apply to all child buses, until another _HPP is
@@ -378,12 +372,10 @@ EXPORT_SYMBOL_GPL(acpi_get_hp_params_from_firmware);
*
* Attempt to take hotplug control from firmware.
*/
-int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
+int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
{
acpi_status status;
acpi_handle chandle, handle;
- struct pci_dev *pdev = dev;
- struct pci_bus *parent;
struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
@@ -408,33 +400,25 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
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, flags);
+ status = acpi_pci_osc_control_set(handle, flags);
if (ACPI_SUCCESS(status))
goto got_one;
kfree(string.pointer);
string = (struct acpi_buffer){ ACPI_ALLOCATE_BUFFER, NULL };
}
- pdev = dev;
- handle = DEVICE_ACPI_HANDLE(&dev->dev);
- while (!handle) {
+ handle = DEVICE_ACPI_HANDLE(&pdev->dev);
+ if (!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;
+ struct pci_bus *pbus;
+ for (pbus = pdev->bus; pbus; pbus = pbus->parent) {
+ handle = acpi_pci_get_bridge_handle(pbus);
+ if (handle)
+ break;
+ }
}
while (handle) {
@@ -453,13 +437,13 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev, u32 flags)
}
dbg("Cannot get control of hotplug hardware for pci %s\n",
- pci_name(dev));
+ pci_name(pdev));
kfree(string.pointer);
return -ENODEV;
got_one:
- dbg("Gained control for hotplug HW for pci %s (%s)\n", pci_name(dev),
- (char *)string.pointer);
+ dbg("Gained control for hotplug HW for pci %s (%s)\n",
+ pci_name(pdev), (char *)string.pointer);
kfree(string.pointer);
return 0;
}
diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c
index d8649e12729..6151389fd90 100644
--- a/drivers/pci/hotplug/fakephp.c
+++ b/drivers/pci/hotplug/fakephp.c
@@ -1,395 +1,163 @@
-/*
- * Fake PCI Hot Plug Controller Driver
+/* Works like the fakephp driver used to, except a little better.
*
- * Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
- * Copyright (C) 2003 IBM Corp.
- * Copyright (C) 2003 Rolf Eike Beer <eike-kernel@sf-tec.de>
+ * - It's possible to remove devices with subordinate busses.
+ * - New PCI devices that appear via any method, not just a fakephp triggered
+ * rescan, will be noticed.
+ * - Devices that are removed via any method, not just a fakephp triggered
+ * removal, will also be noticed.
*
- * Based on ideas and code from:
- * Vladimir Kondratiev <vladimir.kondratiev@intel.com>
- * Rolf Eike Beer <eike-kernel@sf-tec.de>
+ * Uses nothing from the pci-hotplug subsystem.
*
- * 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.
- *
- * Send feedback to <greg@kroah.com>
*/
-/*
- *
- * This driver will "emulate" removing PCI devices from the system. If
- * the "power" file is written to with "0" then the specified PCI device
- * will be completely removed from the kernel.
- *
- * WARNING, this does NOT turn off the power to the PCI device. This is
- * a "logical" removal, not a physical or electrical removal.
- *
- * Use this module at your own risk, you have been warned!
- *
- * Enabling PCI devices is left as an exercise for the reader...
- *
- */
-#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/pci.h>
-#include <linux/pci_hotplug.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/list.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
#include <linux/init.h>
-#include <linux/string.h>
-#include <linux/slab.h>
-#include <linux/workqueue.h>
+#include <linux/pci.h>
+#include <linux/device.h>
#include "../pci.h"
-#if !defined(MODULE)
- #define MY_NAME "fakephp"
-#else
- #define MY_NAME THIS_MODULE->name
-#endif
-
-#define dbg(format, arg...) \
- do { \
- if (debug) \
- printk(KERN_DEBUG "%s: " format, \
- MY_NAME , ## arg); \
- } while (0)
-#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
-#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
-
-#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
-#define DRIVER_DESC "Fake PCI Hot Plug Controller Driver"
-
-struct dummy_slot {
- struct list_head node;
- struct hotplug_slot *slot;
- struct pci_dev *dev;
- struct work_struct remove_work;
- unsigned long removed;
+struct legacy_slot {
+ struct kobject kobj;
+ struct pci_dev *dev;
+ struct list_head list;
};
-static int debug;
-static int dup_slots;
-static LIST_HEAD(slot_list);
-static struct workqueue_struct *dummyphp_wq;
-
-static void pci_rescan_worker(struct work_struct *work);
-static DECLARE_WORK(pci_rescan_work, pci_rescan_worker);
-
-static int enable_slot (struct hotplug_slot *slot);
-static int disable_slot (struct hotplug_slot *slot);
+static LIST_HEAD(legacy_list);
-static struct hotplug_slot_ops dummy_hotplug_slot_ops = {
- .owner = THIS_MODULE,
- .enable_slot = enable_slot,
- .disable_slot = disable_slot,
-};
-
-static void dummy_release(struct hotplug_slot *slot)
+static ssize_t legacy_show(struct kobject *kobj, struct attribute *attr,
+ char *buf)
{
- struct dummy_slot *dslot = slot->private;
-
- list_del(&dslot->node);
- kfree(dslot->slot->info);
- kfree(dslot->slot);
- pci_dev_put(dslot->dev);
- kfree(dslot);
+ struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
+ strcpy(buf, "1\n");
+ return 2;
}
-#define SLOT_NAME_SIZE 8
-
-static int add_slot(struct pci_dev *dev)
+static void remove_callback(void *data)
{
- struct dummy_slot *dslot;
- struct hotplug_slot *slot;
- char name[SLOT_NAME_SIZE];
- int retval = -ENOMEM;
- static int count = 1;
-
- slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
- if (!slot)
- goto error;
-
- slot->info = kzalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL);
- if (!slot->info)
- goto error_slot;
-
- slot->info->power_status = 1;
- slot->info->max_bus_speed = PCI_SPEED_UNKNOWN;
- slot->info->cur_bus_speed = PCI_SPEED_UNKNOWN;
-
- dslot = kzalloc(sizeof(struct dummy_slot), GFP_KERNEL);
- if (!dslot)
- goto error_info;
-
- if (dup_slots)
- snprintf(name, SLOT_NAME_SIZE, "fake");
- else
- snprintf(name, SLOT_NAME_SIZE, "fake%d", count++);
- dbg("slot->name = %s\n", name);
- slot->ops = &dummy_hotplug_slot_ops;
- slot->release = &dummy_release;
- slot->private = dslot;
-
- retval = pci_hp_register(slot, dev->bus, PCI_SLOT(dev->devfn), name);
- if (retval) {
- err("pci_hp_register failed with error %d\n", retval);
- goto error_dslot;
- }
-
- dbg("slot->name = %s\n", hotplug_slot_name(slot));
- dslot->slot = slot;
- dslot->dev = pci_dev_get(dev);
- list_add (&dslot->node, &slot_list);
- return retval;
-
-error_dslot:
- kfree(dslot);
-error_info:
- kfree(slot->info);
-error_slot:
- kfree(slot);
-error:
- return retval;
+ pci_remove_bus_device((struct pci_dev *)data);
}
-static int __init pci_scan_buses(void)
+static ssize_t legacy_store(struct kobject *kobj, struct attribute *attr,
+ const char *buf, size_t len)
{
- struct pci_dev *dev = NULL;
- int lastslot = 0;
+ struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
+ unsigned long val;
- while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
- if (PCI_FUNC(dev->devfn) > 0 &&
- lastslot == PCI_SLOT(dev->devfn))
- continue;
- lastslot = PCI_SLOT(dev->devfn);
- add_slot(dev);
- }
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
- return 0;
+ if (val)
+ pci_rescan_bus(slot->dev->bus);
+ else
+ sysfs_schedule_callback(&slot->dev->dev.kobj, remove_callback,
+ slot->dev, THIS_MODULE);
+ return len;
}
-static void remove_slot(struct dummy_slot *dslot)
-{
- int retval;
-
- dbg("removing slot %s\n", hotplug_slot_name(dslot->slot));
- retval = pci_hp_deregister(dslot->slot);
- if (retval)
- err("Problem unregistering a slot %s\n",
- hotplug_slot_name(dslot->slot));
-}
+static struct attribute *legacy_attrs[] = {
+ &(struct attribute){ .name = "power", .mode = 0644 },
+ NULL,
+};
-/* called from the single-threaded workqueue handler to remove a slot */
-static void remove_slot_worker(struct work_struct *work)
+static void legacy_release(struct kobject *kobj)
{
- struct dummy_slot *dslot =
- container_of(work, struct dummy_slot, remove_work);
- remove_slot(dslot);
-}
+ struct legacy_slot *slot = container_of(kobj, typeof(*slot), kobj);
-/**
- * pci_rescan_slot - Rescan slot
- * @temp: Device template. Should be set: bus and devfn.
- *
- * Tries hard not to re-enable already existing devices;
- * also handles scanning of subfunctions.
- */
-static int pci_rescan_slot(struct pci_dev *temp)
-{
- struct pci_bus *bus = temp->bus;
- struct pci_dev *dev;
- int func;
- u8 hdr_type;
- int count = 0;
-
- if (!pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type)) {
- temp->hdr_type = hdr_type & 0x7f;
- if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
- pci_dev_put(dev);
- else {
- dev = pci_scan_single_device(bus, temp->devfn);
- if (dev) {
- dbg("New device on %s function %x:%x\n",
- bus->name, temp->devfn >> 3,
- temp->devfn & 7);
- count++;
- }
- }
- /* multifunction device? */
- if (!(hdr_type & 0x80))
- return count;
-
- /* continue scanning for other functions */
- for (func = 1, temp->devfn++; func < 8; func++, temp->devfn++) {
- if (pci_read_config_byte(temp, PCI_HEADER_TYPE, &hdr_type))
- continue;
- temp->hdr_type = hdr_type & 0x7f;
-
- if ((dev = pci_get_slot(bus, temp->devfn)) != NULL)
- pci_dev_put(dev);
- else {
- dev = pci_scan_single_device(bus, temp->devfn);
- if (dev) {
- dbg("New device on %s function %x:%x\n",
- bus->name, temp->devfn >> 3,
- temp->devfn & 7);
- count++;
- }
- }
- }
- }
-
- return count;
+ pci_dev_put(slot->dev);
+ kfree(slot);
}
+static struct kobj_type legacy_ktype = {
+ .sysfs_ops = &(struct sysfs_ops){
+ .store = legacy_store, .show = legacy_show
+ },
+ .release = &legacy_release,
+ .default_attrs = legacy_attrs,
+};
-/**
- * pci_rescan_bus - Rescan PCI bus
- * @bus: the PCI bus to rescan
- *
- * Call pci_rescan_slot for each possible function of the bus.
- */
-static void pci_rescan_bus(const struct pci_bus *bus)
+static int legacy_add_slot(struct pci_dev *pdev)
{
- unsigned int devfn;
- struct pci_dev *dev;
- int retval;
- int found = 0;
- dev = alloc_pci_dev();
- if (!dev)
- return;
+ struct legacy_slot *slot = kzalloc(sizeof(*slot), GFP_KERNEL);
- dev->bus = (struct pci_bus*)bus;
- dev->sysdata = bus->sysdata;
- for (devfn = 0; devfn < 0x100; devfn += 8) {
- dev->devfn = devfn;
- found += pci_rescan_slot(dev);
- }
-
- if (found) {
- pci_bus_assign_resources(bus);
- list_for_each_entry(dev, &bus->devices, bus_list) {
- /* Skip already-added devices */
- if (dev->is_added)
- continue;
- retval = pci_bus_add_device(dev);
- if (retval)
- dev_err(&dev->dev,
- "Error adding device, continuing\n");
- else
- add_slot(dev);
- }
- pci_bus_add_devices(bus);
- }
- kfree(dev);
-}
+ if (!slot)
+ return -ENOMEM;
-/* recursively scan all buses */
-static void pci_rescan_buses(const struct list_head *list)
-{
- const struct list_head *l;
- list_for_each(l,list) {
- const struct pci_bus *b = pci_bus_b(l);
- pci_rescan_bus(b);
- pci_rescan_buses(&b->children);
+ if (kobject_init_and_add(&slot->kobj, &legacy_ktype,
+ &pci_slots_kset->kobj, "%s",
+ dev_name(&pdev->dev))) {
+ dev_warn(&pdev->dev, "Failed to created legacy fake slot\n");
+ return -EINVAL;
}
-}
+ slot->dev = pci_dev_get(pdev);
-/* initiate rescan of all pci buses */
-static inline void pci_rescan(void) {
- pci_rescan_buses(&pci_root_buses);
-}
-
-/* called from the single-threaded workqueue handler to rescan all pci buses */
-static void pci_rescan_worker(struct work_struct *work)
-{
- pci_rescan();
-}
+ list_add(&slot->list, &legacy_list);
-static int enable_slot(struct hotplug_slot *hotplug_slot)
-{
- /* mis-use enable_slot for rescanning of the pci bus */
- cancel_work_sync(&pci_rescan_work);
- queue_work(dummyphp_wq, &pci_rescan_work);
return 0;
}
-static int disable_slot(struct hotplug_slot *slot)
+static int legacy_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
{
- struct dummy_slot *dslot;
- struct pci_dev *dev;
- int func;
-
- if (!slot)
- return -ENODEV;
- dslot = slot->private;
-
- dbg("%s - physical_slot = %s\n", __func__, hotplug_slot_name(slot));
+ struct pci_dev *pdev = to_pci_dev(data);
- for (func = 7; func >= 0; func--) {
- dev = pci_get_slot(dslot->dev->bus, dslot->dev->devfn + func);
- if (!dev)
- continue;
+ if (action == BUS_NOTIFY_ADD_DEVICE) {
+ legacy_add_slot(pdev);
+ } else if (action == BUS_NOTIFY_DEL_DEVICE) {
+ struct legacy_slot *slot;
- if (test_and_set_bit(0, &dslot->removed)) {
- dbg("Slot already scheduled for removal\n");
- pci_dev_put(dev);
- return -ENODEV;
- }
+ list_for_each_entry(slot, &legacy_list, list)
+ if (slot->dev == pdev)
+ goto found;
- /* remove the device from the pci core */
- pci_remove_bus_device(dev);
-
- /* queue work item to blow away this sysfs entry and other
- * parts.
- */
- INIT_WORK(&dslot->remove_work, remove_slot_worker);
- queue_work(dummyphp_wq, &dslot->remove_work);
-
- pci_dev_put(dev);
+ dev_warn(&pdev->dev, "Missing legacy fake slot?");
+ return -ENODEV;
+found:
+ kobject_del(&slot->kobj);
+ list_del(&slot->list);
+ kobject_put(&slot->kobj);
}
+
return 0;
}
-static void cleanup_slots (void)
-{
- struct list_head *tmp;
- struct list_head *next;
- struct dummy_slot *dslot;
-
- destroy_workqueue(dummyphp_wq);
- list_for_each_safe (tmp, next, &slot_list) {
- dslot = list_entry (tmp, struct dummy_slot, node);
- remove_slot(dslot);
- }
-
-}
+static struct notifier_block legacy_notifier = {
+ .notifier_call = legacy_notify
+};
-static int __init dummyphp_init(void)
+static int __init init_legacy(void)
{
- info(DRIVER_DESC "\n");
+ struct pci_dev *pdev = NULL;
- dummyphp_wq = create_singlethread_workqueue(MY_NAME);
- if (!dummyphp_wq)
- return -ENOMEM;
+ /* Add existing devices */
+ while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)))
+ legacy_add_slot(pdev);
- return pci_scan_buses();
+ /* Be alerted of any new ones */
+ bus_register_notifier(&pci_bus_type, &legacy_notifier);
+ return 0;
}
+module_init(init_legacy);
-
-static void __exit dummyphp_exit(void)
+static void __exit remove_legacy(void)
{
- cleanup_slots();
+ struct legacy_slot *slot, *tmp;
+
+ bus_unregister_notifier(&pci_bus_type, &legacy_notifier);
+
+ list_for_each_entry_safe(slot, tmp, &legacy_list, list) {
+ list_del(&slot->list);
+ kobject_del(&slot->kobj);
+ kobject_put(&slot->kobj);
+ }
}
+module_exit(remove_legacy);
-module_init(dummyphp_init);
-module_exit(dummyphp_exit);
-MODULE_AUTHOR(DRIVER_AUTHOR);
-MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Trent Piepho <xyzzy@speakeasy.org>");
+MODULE_DESCRIPTION("Legacy version of the fakephp interface");
MODULE_LICENSE("GPL");
-module_param(debug, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Debugging mode enabled or not");
-module_param(dup_slots, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(dup_slots, "Force duplicate slot names for debugging");
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 39ae37589fd..0a368547e63 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -46,10 +46,10 @@ extern int pciehp_force;
extern struct workqueue_struct *pciehp_wq;
#define dbg(format, arg...) \
- do { \
- if (pciehp_debug) \
- printk("%s: " format, MY_NAME , ## arg); \
- } while (0)
+do { \
+ if (pciehp_debug) \
+ printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \
+} while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
@@ -60,7 +60,7 @@ extern struct workqueue_struct *pciehp_wq;
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (pciehp_debug) \
- dev_printk(, &ctrl->pcie->device, \
+ dev_printk(KERN_DEBUG, &ctrl->pcie->device, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
@@ -108,10 +108,11 @@ struct controller {
u32 slot_cap;
u8 cap_base;
struct timer_list poll_timer;
- int cmd_busy;
+ unsigned int cmd_busy:1;
unsigned int no_cmd_complete:1;
unsigned int link_active_reporting:1;
unsigned int notification_enabled:1;
+ unsigned int power_fault_detected;
};
#define INT_BUTTON_IGNORE 0
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 438d795f9fe..96048010e7d 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -67,37 +67,27 @@ static int __init parse_detect_mode(void)
return PCIEHP_DETECT_DEFAULT;
}
-static struct pcie_port_service_id __initdata port_pci_ids[] = {
- {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_ANY_PORT,
- .service_type = PCIE_PORT_SERVICE_HP,
- .driver_data = 0,
- }, { /* end: all zeroes */ }
-};
-
static int __initdata dup_slot_id;
static int __initdata acpi_slot_detected;
static struct list_head __initdata dummy_slots = LIST_HEAD_INIT(dummy_slots);
/* Dummy driver for dumplicate name detection */
-static int __init dummy_probe(struct pcie_device *dev,
- const struct pcie_port_service_id *id)
+static int __init dummy_probe(struct pcie_device *dev)
{
int pos;
u32 slot_cap;
struct slot *slot, *tmp;
struct pci_dev *pdev = dev->port;
struct pci_bus *pbus = pdev->subordinate;
- if (!(slot = kzalloc(sizeof(*slot), GFP_KERNEL)))
- return -ENOMEM;
/* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */
if (pciehp_get_hp_hw_control_from_firmware(pdev))
return -ENODEV;
if (!(pos = pci_find_capability(pdev, PCI_CAP_ID_EXP)))
return -ENODEV;
pci_read_config_dword(pdev, pos + PCI_EXP_SLTCAP, &slot_cap);
+ slot = kzalloc(sizeof(*slot), GFP_KERNEL);
+ if (!slot)
+ return -ENOMEM;
slot->number = slot_cap >> 19;
list_for_each_entry(tmp, &dummy_slots, slot_list) {
if (tmp->number == slot->number)
@@ -111,7 +101,8 @@ static int __init dummy_probe(struct pcie_device *dev,
static struct pcie_port_service_driver __initdata dummy_driver = {
.name = "pciehp_dummy",
- .id_table = port_pci_ids,
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_HP,
.probe = dummy_probe,
};
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 681e3912b82..fb254b2454d 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -401,7 +401,7 @@ static int get_cur_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe
return 0;
}
-static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_id *id)
+static int pciehp_probe(struct pcie_device *dev)
{
int rc;
struct controller *ctrl;
@@ -475,7 +475,7 @@ static void pciehp_remove (struct pcie_device *dev)
}
#ifdef CONFIG_PM
-static int pciehp_suspend (struct pcie_device *dev, pm_message_t state)
+static int pciehp_suspend (struct pcie_device *dev)
{
dev_info(&dev->device, "%s ENTRY\n", __func__);
return 0;
@@ -503,20 +503,12 @@ static int pciehp_resume (struct pcie_device *dev)
}
return 0;
}
-#endif
-
-static struct pcie_port_service_id port_pci_ids[] = { {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_ANY_PORT,
- .service_type = PCIE_PORT_SERVICE_HP,
- .driver_data = 0,
- }, { /* end: all zeroes */ }
-};
+#endif /* PM */
static struct pcie_port_service_driver hpdriver_portdrv = {
.name = PCIE_MODULE_NAME,
- .id_table = &port_pci_ids[0],
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_HP,
.probe = pciehp_probe,
.remove = pciehp_remove,
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c
index 7a16c6897bb..07bd3215114 100644
--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -548,23 +548,21 @@ static int hpc_power_on_slot(struct slot * slot)
slot_cmd = POWER_ON;
cmd_mask = PCI_EXP_SLTCTL_PCC;
- /* Enable detection that we turned off at slot power-off time */
if (!pciehp_poll_mode) {
- slot_cmd |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
+ /* Enable power fault detection turned off at power off time */
+ slot_cmd |= PCI_EXP_SLTCTL_PFDE;
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
}
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
-
if (retval) {
ctrl_err(ctrl, "Write %x command failed!\n", slot_cmd);
- return -1;
+ return retval;
}
ctrl_dbg(ctrl, "%s: SLOTCTRL %x write cmd %x\n",
__func__, ctrl->cap_base + PCI_EXP_SLTCTL, slot_cmd);
+ ctrl->power_fault_detected = 0;
return retval;
}
@@ -621,18 +619,10 @@ static int hpc_power_off_slot(struct slot * slot)
slot_cmd = POWER_OFF;
cmd_mask = PCI_EXP_SLTCTL_PCC;
- /*
- * If we get MRL or presence detect interrupts now, the isr
- * will notice the sticky power-fault bit too and issue power
- * indicator change commands. This will lead to an endless loop
- * of command completions, since the power-fault bit remains on
- * till the slot is powered on again.
- */
if (!pciehp_poll_mode) {
- slot_cmd &= ~(PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
- cmd_mask |= (PCI_EXP_SLTCTL_PFDE | PCI_EXP_SLTCTL_MRLSCE |
- PCI_EXP_SLTCTL_PDCE);
+ /* Disable power fault detection */
+ slot_cmd &= ~PCI_EXP_SLTCTL_PFDE;
+ cmd_mask |= PCI_EXP_SLTCTL_PFDE;
}
retval = pcie_write_cmd(ctrl, slot_cmd, cmd_mask);
@@ -672,10 +662,11 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
detected &= (PCI_EXP_SLTSTA_ABP | PCI_EXP_SLTSTA_PFD |
PCI_EXP_SLTSTA_MRLSC | PCI_EXP_SLTSTA_PDC |
PCI_EXP_SLTSTA_CC);
+ detected &= ~intr_loc;
intr_loc |= detected;
if (!intr_loc)
return IRQ_NONE;
- if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, detected)) {
+ if (detected && pciehp_writew(ctrl, PCI_EXP_SLTSTA, intr_loc)) {
ctrl_err(ctrl, "%s: Cannot write to SLOTSTATUS\n",
__func__);
return IRQ_NONE;
@@ -709,9 +700,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id)
pciehp_handle_presence_change(p_slot);
/* Check Power Fault Detected */
- if (intr_loc & PCI_EXP_SLTSTA_PFD)
+ if ((intr_loc & PCI_EXP_SLTSTA_PFD) && !ctrl->power_fault_detected) {
+ ctrl->power_fault_detected = 1;
pciehp_handle_power_fault(p_slot);
-
+ }
return IRQ_HANDLED;
}
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index 6aba0b6cf2e..974e924ca96 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -48,10 +48,10 @@ extern int shpchp_debug;
extern struct workqueue_struct *shpchp_wq;
#define dbg(format, arg...) \
- do { \
- if (shpchp_debug) \
- printk("%s: " format, MY_NAME , ## arg); \
- } while (0)
+do { \
+ if (shpchp_debug) \
+ printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); \
+} while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
@@ -62,7 +62,7 @@ extern struct workqueue_struct *shpchp_wq;
#define ctrl_dbg(ctrl, format, arg...) \
do { \
if (shpchp_debug) \
- dev_printk(, &ctrl->pci_dev->dev, \
+ dev_printk(KERN_DEBUG, &ctrl->pci_dev->dev, \
format, ## arg); \
} while (0)
#define ctrl_err(ctrl, format, arg...) \
diff --git a/drivers/pci/hotplug/shpchp_pci.c b/drivers/pci/hotplug/shpchp_pci.c
index 138f161becc..aa315e52529 100644
--- a/drivers/pci/hotplug/shpchp_pci.c
+++ b/drivers/pci/hotplug/shpchp_pci.c
@@ -137,7 +137,7 @@ int __ref shpchp_configure_device(struct slot *p_slot)
busnr))
break;
}
- if (busnr >= end) {
+ if (busnr > end) {
ctrl_err(ctrl,
"No free bus for hot-added bridge\n");
pci_dev_put(dev);
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index f3f686581a9..dcda5212f3b 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -36,6 +36,7 @@
#include <linux/iova.h>
#include <linux/iommu.h>
#include <linux/intel-iommu.h>
+#include <linux/sysdev.h>
#include <asm/cacheflush.h>
#include <asm/iommu.h>
#include "pci.h"
@@ -164,7 +165,8 @@ static inline void context_clear_entry(struct context_entry *context)
* 1: writable
* 2-6: reserved
* 7: super page
- * 8-11: available
+ * 8-10: available
+ * 11: snoop behavior
* 12-63: Host physcial address
*/
struct dma_pte {
@@ -186,6 +188,11 @@ static inline void dma_set_pte_writable(struct dma_pte *pte)
pte->val |= DMA_PTE_WRITE;
}
+static inline void dma_set_pte_snp(struct dma_pte *pte)
+{
+ pte->val |= DMA_PTE_SNP;
+}
+
static inline void dma_set_pte_prot(struct dma_pte *pte, unsigned long prot)
{
pte->val = (pte->val & ~3) | (prot & 3);
@@ -231,6 +238,7 @@ struct dmar_domain {
int flags; /* flags to find out type of domain */
int iommu_coherency;/* indicate coherency of iommu access */
+ int iommu_snooping; /* indicate snooping control feature*/
int iommu_count; /* reference count of iommu */
spinlock_t iommu_lock; /* protect iommu set in domain */
u64 max_addr; /* maximum mapped address */
@@ -240,7 +248,8 @@ struct dmar_domain {
struct device_domain_info {
struct list_head link; /* link to domain siblings */
struct list_head global; /* link to global list */
- u8 bus; /* PCI bus numer */
+ int segment; /* PCI domain */
+ u8 bus; /* PCI bus number */
u8 devfn; /* PCI devfn number */
struct pci_dev *dev; /* it's NULL for PCIE-to-PCI bridge */
struct dmar_domain *domain; /* pointer to domain */
@@ -421,7 +430,6 @@ static struct intel_iommu *domain_get_iommu(struct dmar_domain *domain)
return g_iommus[iommu_id];
}
-/* "Coherency" capability may be different across iommus */
static void domain_update_iommu_coherency(struct dmar_domain *domain)
{
int i;
@@ -438,7 +446,30 @@ static void domain_update_iommu_coherency(struct dmar_domain *domain)
}
}
-static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
+static void domain_update_iommu_snooping(struct dmar_domain *domain)
+{
+ int i;
+
+ domain->iommu_snooping = 1;
+
+ i = find_first_bit(&domain->iommu_bmp, g_num_of_iommus);
+ for (; i < g_num_of_iommus; ) {
+ if (!ecap_sc_support(g_iommus[i]->ecap)) {
+ domain->iommu_snooping = 0;
+ break;
+ }
+ i = find_next_bit(&domain->iommu_bmp, g_num_of_iommus, i+1);
+ }
+}
+
+/* Some capabilities may be different across iommus */
+static void domain_update_iommu_cap(struct dmar_domain *domain)
+{
+ domain_update_iommu_coherency(domain);
+ domain_update_iommu_snooping(domain);
+}
+
+static struct intel_iommu *device_to_iommu(int segment, u8 bus, u8 devfn)
{
struct dmar_drhd_unit *drhd = NULL;
int i;
@@ -446,12 +477,20 @@ static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
for_each_drhd_unit(drhd) {
if (drhd->ignored)
continue;
+ if (segment != drhd->segment)
+ continue;
- for (i = 0; i < drhd->devices_cnt; i++)
+ for (i = 0; i < drhd->devices_cnt; i++) {
if (drhd->devices[i] &&
drhd->devices[i]->bus->number == bus &&
drhd->devices[i]->devfn == devfn)
return drhd->iommu;
+ if (drhd->devices[i] &&
+ drhd->devices[i]->subordinate &&
+ drhd->devices[i]->subordinate->number <= bus &&
+ drhd->devices[i]->subordinate->subordinate >= bus)
+ return drhd->iommu;
+ }
if (drhd->include_all)
return drhd->iommu;
@@ -689,15 +728,17 @@ static void dma_pte_clear_one(struct dmar_domain *domain, u64 addr)
static void dma_pte_clear_range(struct dmar_domain *domain, u64 start, u64 end)
{
int addr_width = agaw_to_width(domain->agaw);
+ int npages;
start &= (((u64)1) << addr_width) - 1;
end &= (((u64)1) << addr_width) - 1;
/* in case it's partial page */
start = PAGE_ALIGN(start);
end &= PAGE_MASK;
+ npages = (end - start) / VTD_PAGE_SIZE;
/* we don't need lock here, nobody else touches the iova range */
- while (start < end) {
+ while (npages--) {
dma_pte_clear_one(domain, start);
start += VTD_PAGE_SIZE;
}
@@ -1004,194 +1045,6 @@ static int iommu_disable_translation(struct intel_iommu *iommu)
return 0;
}
-/* iommu interrupt handling. Most stuff are MSI-like. */
-
-static const char *fault_reason_strings[] =
-{
- "Software",
- "Present bit in root entry is clear",
- "Present bit in context entry is clear",
- "Invalid context entry",
- "Access beyond MGAW",
- "PTE Write access is not set",
- "PTE Read access is not set",
- "Next page table ptr is invalid",
- "Root table address invalid",
- "Context table ptr is invalid",
- "non-zero reserved fields in RTP",
- "non-zero reserved fields in CTP",
- "non-zero reserved fields in PTE",
-};
-#define MAX_FAULT_REASON_IDX (ARRAY_SIZE(fault_reason_strings) - 1)
-
-const char *dmar_get_fault_reason(u8 fault_reason)
-{
- if (fault_reason > MAX_FAULT_REASON_IDX)
- return "Unknown";
- else
- return fault_reason_strings[fault_reason];
-}
-
-void dmar_msi_unmask(unsigned int irq)
-{
- struct intel_iommu *iommu = get_irq_data(irq);
- unsigned long flag;
-
- /* unmask it */
- spin_lock_irqsave(&iommu->register_lock, flag);
- writel(0, iommu->reg + DMAR_FECTL_REG);
- /* Read a reg to force flush the post write */
- readl(iommu->reg + DMAR_FECTL_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_mask(unsigned int irq)
-{
- unsigned long flag;
- struct intel_iommu *iommu = get_irq_data(irq);
-
- /* mask it */
- spin_lock_irqsave(&iommu->register_lock, flag);
- writel(DMA_FECTL_IM, iommu->reg + DMAR_FECTL_REG);
- /* Read a reg to force flush the post write */
- readl(iommu->reg + DMAR_FECTL_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_write(int irq, struct msi_msg *msg)
-{
- struct intel_iommu *iommu = get_irq_data(irq);
- unsigned long flag;
-
- spin_lock_irqsave(&iommu->register_lock, flag);
- writel(msg->data, iommu->reg + DMAR_FEDATA_REG);
- writel(msg->address_lo, iommu->reg + DMAR_FEADDR_REG);
- writel(msg->address_hi, iommu->reg + DMAR_FEUADDR_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-void dmar_msi_read(int irq, struct msi_msg *msg)
-{
- struct intel_iommu *iommu = get_irq_data(irq);
- unsigned long flag;
-
- spin_lock_irqsave(&iommu->register_lock, flag);
- msg->data = readl(iommu->reg + DMAR_FEDATA_REG);
- msg->address_lo = readl(iommu->reg + DMAR_FEADDR_REG);
- msg->address_hi = readl(iommu->reg + DMAR_FEUADDR_REG);
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-}
-
-static int iommu_page_fault_do_one(struct intel_iommu *iommu, int type,
- u8 fault_reason, u16 source_id, unsigned long long addr)
-{
- const char *reason;
-
- reason = dmar_get_fault_reason(fault_reason);
-
- printk(KERN_ERR
- "DMAR:[%s] Request device [%02x:%02x.%d] "
- "fault addr %llx \n"
- "DMAR:[fault reason %02d] %s\n",
- (type ? "DMA Read" : "DMA Write"),
- (source_id >> 8), PCI_SLOT(source_id & 0xFF),
- PCI_FUNC(source_id & 0xFF), addr, fault_reason, reason);
- return 0;
-}
-
-#define PRIMARY_FAULT_REG_LEN (16)
-static irqreturn_t iommu_page_fault(int irq, void *dev_id)
-{
- struct intel_iommu *iommu = dev_id;
- int reg, fault_index;
- u32 fault_status;
- unsigned long flag;
-
- spin_lock_irqsave(&iommu->register_lock, flag);
- fault_status = readl(iommu->reg + DMAR_FSTS_REG);
-
- /* TBD: ignore advanced fault log currently */
- if (!(fault_status & DMA_FSTS_PPF))
- goto clear_overflow;
-
- fault_index = dma_fsts_fault_record_index(fault_status);
- reg = cap_fault_reg_offset(iommu->cap);
- while (1) {
- u8 fault_reason;
- u16 source_id;
- u64 guest_addr;
- int type;
- u32 data;
-
- /* highest 32 bits */
- data = readl(iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN + 12);
- if (!(data & DMA_FRCD_F))
- break;
-
- fault_reason = dma_frcd_fault_reason(data);
- type = dma_frcd_type(data);
-
- data = readl(iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN + 8);
- source_id = dma_frcd_source_id(data);
-
- guest_addr = dmar_readq(iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN);
- guest_addr = dma_frcd_page_addr(guest_addr);
- /* clear the fault */
- writel(DMA_FRCD_F, iommu->reg + reg +
- fault_index * PRIMARY_FAULT_REG_LEN + 12);
-
- spin_unlock_irqrestore(&iommu->register_lock, flag);
-
- iommu_page_fault_do_one(iommu, type, fault_reason,
- source_id, guest_addr);
-
- fault_index++;
- if (fault_index > cap_num_fault_regs(iommu->cap))
- fault_index = 0;
- spin_lock_irqsave(&iommu->register_lock, flag);
- }
-clear_overflow:
- /* clear primary fault overflow */
- fault_status = readl(iommu->reg + DMAR_FSTS_REG);
- if (fault_status & DMA_FSTS_PFO)
- writel(DMA_FSTS_PFO, iommu->reg + DMAR_FSTS_REG);
-
- spin_unlock_irqrestore(&iommu->register_lock, flag);
- return IRQ_HANDLED;
-}
-
-int dmar_set_interrupt(struct intel_iommu *iommu)
-{
- int irq, ret;
-
- irq = create_irq();
- if (!irq) {
- printk(KERN_ERR "IOMMU: no free vectors\n");
- return -EINVAL;
- }
-
- set_irq_data(irq, iommu);
- iommu->irq = irq;
-
- ret = arch_setup_dmar_msi(irq);
- if (ret) {
- set_irq_data(irq, NULL);
- iommu->irq = 0;
- destroy_irq(irq);
- return 0;
- }
-
- /* Force fault register is cleared */
- iommu_page_fault(irq, iommu);
-
- ret = request_irq(irq, iommu_page_fault, 0, iommu->name, iommu);
- if (ret)
- printk(KERN_ERR "IOMMU: can't request irq\n");
- return ret;
-}
static int iommu_init_domains(struct intel_iommu *iommu)
{
@@ -1429,6 +1282,11 @@ static int domain_init(struct dmar_domain *domain, int guest_width)
else
domain->iommu_coherency = 0;
+ if (ecap_sc_support(iommu->ecap))
+ domain->iommu_snooping = 1;
+ else
+ domain->iommu_snooping = 0;
+
domain->iommu_count = 1;
/* always allocate the top pgd */
@@ -1464,7 +1322,7 @@ static void domain_exit(struct dmar_domain *domain)
}
static int domain_context_mapping_one(struct dmar_domain *domain,
- u8 bus, u8 devfn)
+ int segment, u8 bus, u8 devfn)
{
struct context_entry *context;
unsigned long flags;
@@ -1479,7 +1337,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
BUG_ON(!domain->pgd);
- iommu = device_to_iommu(bus, devfn);
+ iommu = device_to_iommu(segment, bus, devfn);
if (!iommu)
return -ENODEV;
@@ -1557,7 +1415,7 @@ static int domain_context_mapping_one(struct dmar_domain *domain,
spin_lock_irqsave(&domain->iommu_lock, flags);
if (!test_and_set_bit(iommu->seq_id, &domain->iommu_bmp)) {
domain->iommu_count++;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
}
spin_unlock_irqrestore(&domain->iommu_lock, flags);
return 0;
@@ -1569,8 +1427,8 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
int ret;
struct pci_dev *tmp, *parent;
- ret = domain_context_mapping_one(domain, pdev->bus->number,
- pdev->devfn);
+ ret = domain_context_mapping_one(domain, pci_domain_nr(pdev->bus),
+ pdev->bus->number, pdev->devfn);
if (ret)
return ret;
@@ -1581,18 +1439,23 @@ domain_context_mapping(struct dmar_domain *domain, struct pci_dev *pdev)
/* Secondary interface's bus number and devfn 0 */
parent = pdev->bus->self;
while (parent != tmp) {
- ret = domain_context_mapping_one(domain, parent->bus->number,
- parent->devfn);
+ ret = domain_context_mapping_one(domain,
+ pci_domain_nr(parent->bus),
+ parent->bus->number,
+ parent->devfn);
if (ret)
return ret;
parent = parent->bus->self;
}
if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
return domain_context_mapping_one(domain,
- tmp->subordinate->number, 0);
+ pci_domain_nr(tmp->subordinate),
+ tmp->subordinate->number, 0);
else /* this is a legacy PCI bridge */
return domain_context_mapping_one(domain,
- tmp->bus->number, tmp->devfn);
+ pci_domain_nr(tmp->bus),
+ tmp->bus->number,
+ tmp->devfn);
}
static int domain_context_mapped(struct pci_dev *pdev)
@@ -1601,12 +1464,12 @@ static int domain_context_mapped(struct pci_dev *pdev)
struct pci_dev *tmp, *parent;
struct intel_iommu *iommu;
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return -ENODEV;
- ret = device_context_mapped(iommu,
- pdev->bus->number, pdev->devfn);
+ ret = device_context_mapped(iommu, pdev->bus->number, pdev->devfn);
if (!ret)
return ret;
/* dependent device mapping */
@@ -1617,17 +1480,17 @@ static int domain_context_mapped(struct pci_dev *pdev)
parent = pdev->bus->self;
while (parent != tmp) {
ret = device_context_mapped(iommu, parent->bus->number,
- parent->devfn);
+ parent->devfn);
if (!ret)
return ret;
parent = parent->bus->self;
}
if (tmp->is_pcie)
- return device_context_mapped(iommu,
- tmp->subordinate->number, 0);
+ return device_context_mapped(iommu, tmp->subordinate->number,
+ 0);
else
- return device_context_mapped(iommu,
- tmp->bus->number, tmp->devfn);
+ return device_context_mapped(iommu, tmp->bus->number,
+ tmp->devfn);
}
static int
@@ -1657,6 +1520,8 @@ domain_page_mapping(struct dmar_domain *domain, dma_addr_t iova,
BUG_ON(dma_pte_addr(pte));
dma_set_pte_addr(pte, start_pfn << VTD_PAGE_SHIFT);
dma_set_pte_prot(pte, prot);
+ if (prot & DMA_PTE_SNP)
+ dma_set_pte_snp(pte);
domain_flush_cache(domain, pte, sizeof(*pte));
start_pfn++;
index++;
@@ -1692,7 +1557,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
info->dev->dev.archdata.iommu = NULL;
spin_unlock_irqrestore(&device_domain_lock, flags);
- iommu = device_to_iommu(info->bus, info->devfn);
+ iommu = device_to_iommu(info->segment, info->bus, info->devfn);
iommu_detach_dev(iommu, info->bus, info->devfn);
free_devinfo_mem(info);
@@ -1727,11 +1592,14 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
struct pci_dev *dev_tmp;
unsigned long flags;
int bus = 0, devfn = 0;
+ int segment;
domain = find_domain(pdev);
if (domain)
return domain;
+ segment = pci_domain_nr(pdev->bus);
+
dev_tmp = pci_find_upstream_pcie_bridge(pdev);
if (dev_tmp) {
if (dev_tmp->is_pcie) {
@@ -1743,7 +1611,8 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
}
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(info, &device_domain_list, global) {
- if (info->bus == bus && info->devfn == devfn) {
+ if (info->segment == segment &&
+ info->bus == bus && info->devfn == devfn) {
found = info->domain;
break;
}
@@ -1781,6 +1650,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
domain_exit(domain);
goto error;
}
+ info->segment = segment;
info->bus = bus;
info->devfn = devfn;
info->dev = NULL;
@@ -1792,7 +1662,8 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw)
found = NULL;
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_entry(tmp, &device_domain_list, global) {
- if (tmp->bus == bus && tmp->devfn == devfn) {
+ if (tmp->segment == segment &&
+ tmp->bus == bus && tmp->devfn == devfn) {
found = tmp->domain;
break;
}
@@ -1812,6 +1683,7 @@ found_domain:
info = alloc_devinfo_mem();
if (!info)
goto error;
+ info->segment = segment;
info->bus = pdev->bus->number;
info->devfn = pdev->devfn;
info->dev = pdev;
@@ -1970,7 +1842,7 @@ static inline void iommu_prepare_isa(void)
ret = iommu_prepare_identity_map(pdev, 0, 16*1024*1024);
if (ret)
- printk("IOMMU: Failed to create 0-64M identity map, "
+ printk(KERN_ERR "IOMMU: Failed to create 0-64M identity map, "
"floppy might not work\n");
}
@@ -1987,7 +1859,7 @@ static int __init init_dmars(void)
struct dmar_rmrr_unit *rmrr;
struct pci_dev *pdev;
struct intel_iommu *iommu;
- int i, ret, unit = 0;
+ int i, ret;
/*
* for each drhd
@@ -2043,11 +1915,40 @@ static int __init init_dmars(void)
}
}
+ /*
+ * Start from the sane iommu hardware state.
+ */
+ for_each_drhd_unit(drhd) {
+ if (drhd->ignored)
+ continue;
+
+ iommu = drhd->iommu;
+
+ /*
+ * If the queued invalidation is already initialized by us
+ * (for example, while enabling interrupt-remapping) then
+ * we got the things already rolling from a sane state.
+ */
+ if (iommu->qi)
+ continue;
+
+ /*
+ * Clear any previous faults.
+ */
+ dmar_fault(-1, iommu);
+ /*
+ * Disable queued invalidation if supported and already enabled
+ * before OS handover.
+ */
+ dmar_disable_qi(iommu);
+ }
+
for_each_drhd_unit(drhd) {
if (drhd->ignored)
continue;
iommu = drhd->iommu;
+
if (dmar_enable_qi(iommu)) {
/*
* Queued Invalidate not enabled, use Register Based
@@ -2067,6 +1968,15 @@ static int __init init_dmars(void)
}
}
+#ifdef CONFIG_INTR_REMAP
+ if (!intr_remapping_enabled) {
+ ret = enable_intr_remapping(0);
+ if (ret)
+ printk(KERN_ERR
+ "IOMMU: enable interrupt remapping failed\n");
+ }
+#endif
+
/*
* For each rmrr
* for each dev attached to rmrr
@@ -2109,7 +2019,6 @@ static int __init init_dmars(void)
if (drhd->ignored)
continue;
iommu = drhd->iommu;
- sprintf (iommu->name, "dmar%d", unit++);
iommu_flush_write_buffer(iommu);
@@ -2279,16 +2188,18 @@ static dma_addr_t __intel_map_single(struct device *hwdev, phys_addr_t paddr,
error:
if (iova)
__free_iova(&domain->iovad, iova);
- printk(KERN_ERR"Device %s request: %lx@%llx dir %d --- failed\n",
+ printk(KERN_ERR"Device %s request: %zx@%llx dir %d --- failed\n",
pci_name(pdev), size, (unsigned long long)paddr, dir);
return 0;
}
-dma_addr_t intel_map_single(struct device *hwdev, phys_addr_t paddr,
- size_t size, int dir)
+static dma_addr_t intel_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
- return __intel_map_single(hwdev, paddr, size, dir,
- to_pci_dev(hwdev)->dma_mask);
+ return __intel_map_single(dev, page_to_phys(page) + offset, size,
+ dir, to_pci_dev(dev)->dma_mask);
}
static void flush_unmaps(void)
@@ -2352,8 +2263,9 @@ static void add_unmap(struct dmar_domain *dom, struct iova *iova)
spin_unlock_irqrestore(&async_umap_flush_lock, flags);
}
-void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
- int dir)
+static void intel_unmap_page(struct device *dev, dma_addr_t dev_addr,
+ size_t size, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
struct pci_dev *pdev = to_pci_dev(dev);
struct dmar_domain *domain;
@@ -2375,7 +2287,7 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
start_addr = iova->pfn_lo << PAGE_SHIFT;
size = aligned_size((u64)dev_addr, size);
- pr_debug("Device %s unmapping: %lx@%llx\n",
+ pr_debug("Device %s unmapping: %zx@%llx\n",
pci_name(pdev), size, (unsigned long long)start_addr);
/* clear the whole page */
@@ -2397,8 +2309,14 @@ void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
}
}
-void *intel_alloc_coherent(struct device *hwdev, size_t size,
- dma_addr_t *dma_handle, gfp_t flags)
+static void intel_unmap_single(struct device *dev, dma_addr_t dev_addr, size_t size,
+ int dir)
+{
+ intel_unmap_page(dev, dev_addr, size, dir, NULL);
+}
+
+static void *intel_alloc_coherent(struct device *hwdev, size_t size,
+ dma_addr_t *dma_handle, gfp_t flags)
{
void *vaddr;
int order;
@@ -2421,8 +2339,8 @@ void *intel_alloc_coherent(struct device *hwdev, size_t size,
return NULL;
}
-void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
- dma_addr_t dma_handle)
+static void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
+ dma_addr_t dma_handle)
{
int order;
@@ -2433,10 +2351,9 @@ void intel_free_coherent(struct device *hwdev, size_t size, void *vaddr,
free_pages((unsigned long)vaddr, order);
}
-#define SG_ENT_VIRT_ADDRESS(sg) (sg_virt((sg)))
-
-void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
- int nelems, int dir)
+static void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
+ int nelems, enum dma_data_direction dir,
+ struct dma_attrs *attrs)
{
int i;
struct pci_dev *pdev = to_pci_dev(hwdev);
@@ -2444,7 +2361,7 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
unsigned long start_addr;
struct iova *iova;
size_t size = 0;
- void *addr;
+ phys_addr_t addr;
struct scatterlist *sg;
struct intel_iommu *iommu;
@@ -2460,7 +2377,7 @@ void intel_unmap_sg(struct device *hwdev, struct scatterlist *sglist,
if (!iova)
return;
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size += aligned_size((u64)addr, sg->length);
}
@@ -2487,16 +2404,16 @@ static int intel_nontranslate_map_sg(struct device *hddev,
for_each_sg(sglist, sg, nelems, i) {
BUG_ON(!sg_page(sg));
- sg->dma_address = virt_to_bus(SG_ENT_VIRT_ADDRESS(sg));
+ sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
sg->dma_length = sg->length;
}
return nelems;
}
-int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
- int dir)
+static int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
- void *addr;
+ phys_addr_t addr;
int i;
struct pci_dev *pdev = to_pci_dev(hwdev);
struct dmar_domain *domain;
@@ -2520,8 +2437,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
iommu = domain_get_iommu(domain);
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
- addr = (void *)virt_to_phys(addr);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size += aligned_size((u64)addr, sg->length);
}
@@ -2544,8 +2460,7 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
start_addr = iova->pfn_lo << PAGE_SHIFT;
offset = 0;
for_each_sg(sglist, sg, nelems, i) {
- addr = SG_ENT_VIRT_ADDRESS(sg);
- addr = (void *)virt_to_phys(addr);
+ addr = page_to_phys(sg_page(sg)) + sg->offset;
size = aligned_size((u64)addr, sg->length);
ret = domain_page_mapping(domain, start_addr + offset,
((u64)addr) & PAGE_MASK,
@@ -2574,13 +2489,19 @@ int intel_map_sg(struct device *hwdev, struct scatterlist *sglist, int nelems,
return nelems;
}
-static struct dma_mapping_ops intel_dma_ops = {
+static int intel_mapping_error(struct device *dev, dma_addr_t dma_addr)
+{
+ return !dma_addr;
+}
+
+struct dma_map_ops intel_dma_ops = {
.alloc_coherent = intel_alloc_coherent,
.free_coherent = intel_free_coherent,
- .map_single = intel_map_single,
- .unmap_single = intel_unmap_single,
.map_sg = intel_map_sg,
.unmap_sg = intel_unmap_sg,
+ .map_page = intel_map_page,
+ .unmap_page = intel_unmap_page,
+ .mapping_error = intel_mapping_error,
};
static inline int iommu_domain_cache_init(void)
@@ -2707,6 +2628,150 @@ static void __init init_no_remapping_devices(void)
}
}
+#ifdef CONFIG_SUSPEND
+static int init_iommu_hw(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+
+ for_each_active_iommu(iommu, drhd)
+ if (iommu->qi)
+ dmar_reenable_qi(iommu);
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu_flush_write_buffer(iommu);
+
+ iommu_set_root_entry(iommu);
+
+ iommu->flush.flush_context(iommu, 0, 0, 0,
+ DMA_CCMD_GLOBAL_INVL, 0);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+ DMA_TLB_GLOBAL_FLUSH, 0);
+ iommu_disable_protect_mem_regions(iommu);
+ iommu_enable_translation(iommu);
+ }
+
+ return 0;
+}
+
+static void iommu_flush_all(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu;
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu->flush.flush_context(iommu, 0, 0, 0,
+ DMA_CCMD_GLOBAL_INVL, 0);
+ iommu->flush.flush_iotlb(iommu, 0, 0, 0,
+ DMA_TLB_GLOBAL_FLUSH, 0);
+ }
+}
+
+static int iommu_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+ unsigned long flag;
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu->iommu_state = kzalloc(sizeof(u32) * MAX_SR_DMAR_REGS,
+ GFP_ATOMIC);
+ if (!iommu->iommu_state)
+ goto nomem;
+ }
+
+ iommu_flush_all();
+
+ for_each_active_iommu(iommu, drhd) {
+ iommu_disable_translation(iommu);
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+
+ iommu->iommu_state[SR_DMAR_FECTL_REG] =
+ readl(iommu->reg + DMAR_FECTL_REG);
+ iommu->iommu_state[SR_DMAR_FEDATA_REG] =
+ readl(iommu->reg + DMAR_FEDATA_REG);
+ iommu->iommu_state[SR_DMAR_FEADDR_REG] =
+ readl(iommu->reg + DMAR_FEADDR_REG);
+ iommu->iommu_state[SR_DMAR_FEUADDR_REG] =
+ readl(iommu->reg + DMAR_FEUADDR_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ }
+ return 0;
+
+nomem:
+ for_each_active_iommu(iommu, drhd)
+ kfree(iommu->iommu_state);
+
+ return -ENOMEM;
+}
+
+static int iommu_resume(struct sys_device *dev)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+ unsigned long flag;
+
+ if (init_iommu_hw()) {
+ WARN(1, "IOMMU setup failed, DMAR can not resume!\n");
+ return -EIO;
+ }
+
+ for_each_active_iommu(iommu, drhd) {
+
+ spin_lock_irqsave(&iommu->register_lock, flag);
+
+ writel(iommu->iommu_state[SR_DMAR_FECTL_REG],
+ iommu->reg + DMAR_FECTL_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEDATA_REG],
+ iommu->reg + DMAR_FEDATA_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEADDR_REG],
+ iommu->reg + DMAR_FEADDR_REG);
+ writel(iommu->iommu_state[SR_DMAR_FEUADDR_REG],
+ iommu->reg + DMAR_FEUADDR_REG);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flag);
+ }
+
+ for_each_active_iommu(iommu, drhd)
+ kfree(iommu->iommu_state);
+
+ return 0;
+}
+
+static struct sysdev_class iommu_sysclass = {
+ .name = "iommu",
+ .resume = iommu_resume,
+ .suspend = iommu_suspend,
+};
+
+static struct sys_device device_iommu = {
+ .cls = &iommu_sysclass,
+};
+
+static int __init init_iommu_sysfs(void)
+{
+ int error;
+
+ error = sysdev_class_register(&iommu_sysclass);
+ if (error)
+ return error;
+
+ error = sysdev_register(&device_iommu);
+ if (error)
+ sysdev_class_unregister(&iommu_sysclass);
+
+ return error;
+}
+
+#else
+static int __init init_iommu_sysfs(void)
+{
+ return 0;
+}
+#endif /* CONFIG_PM */
+
int __init intel_iommu_init(void)
{
int ret = 0;
@@ -2742,6 +2807,7 @@ int __init intel_iommu_init(void)
init_timer(&unmap_timer);
force_iommu = 1;
dma_ops = &intel_dma_ops;
+ init_iommu_sysfs();
register_iommu(&intel_iommu_ops);
@@ -2758,6 +2824,7 @@ static int vm_domain_add_dev_info(struct dmar_domain *domain,
if (!info)
return -ENOMEM;
+ info->segment = pci_domain_nr(pdev->bus);
info->bus = pdev->bus->number;
info->devfn = pdev->devfn;
info->dev = pdev;
@@ -2772,6 +2839,33 @@ static int vm_domain_add_dev_info(struct dmar_domain *domain,
return 0;
}
+static void iommu_detach_dependent_devices(struct intel_iommu *iommu,
+ struct pci_dev *pdev)
+{
+ struct pci_dev *tmp, *parent;
+
+ if (!iommu || !pdev)
+ return;
+
+ /* dependent device detach */
+ tmp = pci_find_upstream_pcie_bridge(pdev);
+ /* Secondary interface's bus number and devfn 0 */
+ if (tmp) {
+ parent = pdev->bus->self;
+ while (parent != tmp) {
+ iommu_detach_dev(iommu, parent->bus->number,
+ parent->devfn);
+ parent = parent->bus->self;
+ }
+ if (tmp->is_pcie) /* this is a PCIE-to-PCI bridge */
+ iommu_detach_dev(iommu,
+ tmp->subordinate->number, 0);
+ else /* this is a legacy PCI bridge */
+ iommu_detach_dev(iommu, tmp->bus->number,
+ tmp->devfn);
+ }
+}
+
static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
struct pci_dev *pdev)
{
@@ -2781,13 +2875,15 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
int found = 0;
struct list_head *entry, *tmp;
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return;
spin_lock_irqsave(&device_domain_lock, flags);
list_for_each_safe(entry, tmp, &domain->devices) {
info = list_entry(entry, struct device_domain_info, link);
+ /* No need to compare PCI domain; it has to be the same */
if (info->bus == pdev->bus->number &&
info->devfn == pdev->devfn) {
list_del(&info->link);
@@ -2797,6 +2893,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
spin_unlock_irqrestore(&device_domain_lock, flags);
iommu_detach_dev(iommu, info->bus, info->devfn);
+ iommu_detach_dependent_devices(iommu, pdev);
free_devinfo_mem(info);
spin_lock_irqsave(&device_domain_lock, flags);
@@ -2811,7 +2908,8 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
* owned by this domain, clear this iommu in iommu_bmp
* update iommu count and coherency
*/
- if (device_to_iommu(info->bus, info->devfn) == iommu)
+ if (iommu == device_to_iommu(info->segment, info->bus,
+ info->devfn))
found = 1;
}
@@ -2820,7 +2918,7 @@ static void vm_domain_remove_one_dev_info(struct dmar_domain *domain,
spin_lock_irqsave(&domain->iommu_lock, tmp_flags);
clear_bit(iommu->seq_id, &domain->iommu_bmp);
domain->iommu_count--;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
spin_unlock_irqrestore(&domain->iommu_lock, tmp_flags);
}
@@ -2844,17 +2942,18 @@ static void vm_domain_remove_all_dev_info(struct dmar_domain *domain)
spin_unlock_irqrestore(&device_domain_lock, flags1);
- iommu = device_to_iommu(info->bus, info->devfn);
+ iommu = device_to_iommu(info->segment, info->bus, info->devfn);
iommu_detach_dev(iommu, info->bus, info->devfn);
+ iommu_detach_dependent_devices(iommu, info->dev);
/* clear this iommu in iommu_bmp, update iommu count
- * and coherency
+ * and capabilities
*/
spin_lock_irqsave(&domain->iommu_lock, flags2);
if (test_and_clear_bit(iommu->seq_id,
&domain->iommu_bmp)) {
domain->iommu_count--;
- domain_update_iommu_coherency(domain);
+ domain_update_iommu_cap(domain);
}
spin_unlock_irqrestore(&domain->iommu_lock, flags2);
@@ -3031,7 +3130,8 @@ static int intel_iommu_attach_device(struct iommu_domain *domain,
}
}
- iommu = device_to_iommu(pdev->bus->number, pdev->devfn);
+ iommu = device_to_iommu(pci_domain_nr(pdev->bus), pdev->bus->number,
+ pdev->devfn);
if (!iommu)
return -ENODEV;
@@ -3077,6 +3177,8 @@ static int intel_iommu_map_range(struct iommu_domain *domain,
prot |= DMA_PTE_READ;
if (iommu_prot & IOMMU_WRITE)
prot |= DMA_PTE_WRITE;
+ if ((iommu_prot & IOMMU_CACHE) && dmar_domain->iommu_snooping)
+ prot |= DMA_PTE_SNP;
max_addr = (iova & VTD_PAGE_MASK) + VTD_PAGE_ALIGN(size);
if (dmar_domain->max_addr < max_addr) {
@@ -3130,6 +3232,17 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
return phys;
}
+static int intel_iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ struct dmar_domain *dmar_domain = domain->priv;
+
+ if (cap == IOMMU_CAP_CACHE_COHERENCY)
+ return dmar_domain->iommu_snooping;
+
+ return 0;
+}
+
static struct iommu_ops intel_iommu_ops = {
.domain_init = intel_iommu_domain_init,
.domain_destroy = intel_iommu_domain_destroy,
@@ -3138,6 +3251,7 @@ static struct iommu_ops intel_iommu_ops = {
.map = intel_iommu_map_range,
.unmap = intel_iommu_unmap_range,
.iova_to_phys = intel_iommu_iova_to_phys,
+ .domain_has_cap = intel_iommu_domain_has_cap,
};
static void __devinit quirk_iommu_rwbf(struct pci_dev *dev)
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index 9d07a05d26f..f5e0ea724a6 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -9,6 +9,7 @@
#include <asm/cpu.h>
#include <linux/intel-iommu.h>
#include "intr_remapping.h"
+#include <acpi/acpi.h>
static struct ioapic_scope ir_ioapic[MAX_IO_APICS];
static int ir_ioapic_num;
@@ -117,21 +118,22 @@ int get_irte(int irq, struct irte *entry)
{
int index;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
if (!entry)
return -1;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
index = irq_iommu->irte_index + irq_iommu->sub_handle;
*entry = *(irq_iommu->iommu->ir_table->base + index);
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return 0;
}
@@ -141,6 +143,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
struct irq_2_iommu *irq_iommu;
u16 index, start_index;
unsigned int mask = 0;
+ unsigned long flags;
int i;
if (!count)
@@ -170,7 +173,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
return -1;
}
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
do {
for (i = index; i < index + count; i++)
if (table->base[i].present)
@@ -182,7 +185,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
index = (index + count) % INTR_REMAP_TABLE_ENTRIES;
if (index == start_index) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
printk(KERN_ERR "can't allocate an IRTE\n");
return -1;
}
@@ -193,7 +196,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
irq_iommu = irq_2_iommu_alloc(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
printk(KERN_ERR "can't allocate irq_2_iommu\n");
return -1;
}
@@ -203,7 +206,7 @@ int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = mask;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return index;
}
@@ -223,30 +226,32 @@ int map_irq_to_irte_handle(int irq, u16 *sub_handle)
{
int index;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
*sub_handle = irq_iommu->sub_handle;
index = irq_iommu->irte_index;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return index;
}
int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
{
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = irq_2_iommu_alloc(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
printk(KERN_ERR "can't allocate irq_2_iommu\n");
return -1;
}
@@ -256,7 +261,7 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
irq_iommu->sub_handle = subhandle;
irq_iommu->irte_mask = 0;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return 0;
}
@@ -264,11 +269,12 @@ int set_irte_irq(int irq, struct intel_iommu *iommu, u16 index, u16 subhandle)
int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
{
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -277,7 +283,7 @@ int clear_irte_irq(int irq, struct intel_iommu *iommu, u16 index)
irq_iommu->sub_handle = 0;
irq_2_iommu(irq)->irte_mask = 0;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return 0;
}
@@ -289,11 +295,12 @@ int modify_irte(int irq, struct irte *irte_modified)
struct irte *irte;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -302,11 +309,11 @@ int modify_irte(int irq, struct irte *irte_modified)
index = irq_iommu->irte_index + irq_iommu->sub_handle;
irte = &iommu->ir_table->base[index];
- set_64bit((unsigned long *)irte, irte_modified->low | (1 << 1));
+ set_64bit((unsigned long *)irte, irte_modified->low);
__iommu_flush_cache(iommu, irte, sizeof(*irte));
rc = qi_flush_iec(iommu, index, 0);
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return rc;
}
@@ -317,11 +324,12 @@ int flush_irte(int irq)
int index;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -330,7 +338,7 @@ int flush_irte(int irq)
index = irq_iommu->irte_index + irq_iommu->sub_handle;
rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return rc;
}
@@ -363,11 +371,12 @@ int free_irte(int irq)
struct irte *irte;
struct intel_iommu *iommu;
struct irq_2_iommu *irq_iommu;
+ unsigned long flags;
- spin_lock(&irq_2_ir_lock);
+ spin_lock_irqsave(&irq_2_ir_lock, flags);
irq_iommu = valid_irq_2_iommu(irq);
if (!irq_iommu) {
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return -1;
}
@@ -378,7 +387,7 @@ int free_irte(int irq)
if (!irq_iommu->sub_handle) {
for (i = 0; i < (1 << irq_iommu->irte_mask); i++)
- set_64bit((unsigned long *)irte, 0);
+ set_64bit((unsigned long *)(irte + i), 0);
rc = qi_flush_iec(iommu, index, irq_iommu->irte_mask);
}
@@ -387,7 +396,7 @@ int free_irte(int irq)
irq_iommu->sub_handle = 0;
irq_iommu->irte_mask = 0;
- spin_unlock(&irq_2_ir_lock);
+ spin_unlock_irqrestore(&irq_2_ir_lock, flags);
return rc;
}
@@ -407,12 +416,27 @@ static void iommu_set_intr_remapping(struct intel_iommu *iommu, int mode)
/* Set interrupt-remapping table pointer */
cmd = iommu->gcmd | DMA_GCMD_SIRTP;
+ iommu->gcmd |= DMA_GCMD_SIRTP;
writel(cmd, iommu->reg + DMAR_GCMD_REG);
IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
readl, (sts & DMA_GSTS_IRTPS), sts);
spin_unlock_irqrestore(&iommu->register_lock, flags);
+ if (mode == 0) {
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ /* enable comaptiblity format interrupt pass through */
+ cmd = iommu->gcmd | DMA_GCMD_CFI;
+ iommu->gcmd |= DMA_GCMD_CFI;
+ writel(cmd, iommu->reg + DMAR_GCMD_REG);
+
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, (sts & DMA_GSTS_CFIS), sts);
+
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+ }
+
/*
* global invalidation of interrupt entry cache before enabling
* interrupt-remapping.
@@ -439,12 +463,12 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
struct page *pages;
ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table),
- GFP_KERNEL);
+ GFP_ATOMIC);
if (!iommu->ir_table)
return -ENOMEM;
- pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
+ pages = alloc_pages(GFP_ATOMIC | __GFP_ZERO, INTR_REMAP_PAGE_ORDER);
if (!pages) {
printk(KERN_ERR "failed to allocate pages of order %d\n",
@@ -459,11 +483,68 @@ static int setup_intr_remapping(struct intel_iommu *iommu, int mode)
return 0;
}
+/*
+ * Disable Interrupt Remapping.
+ */
+static void iommu_disable_intr_remapping(struct intel_iommu *iommu)
+{
+ unsigned long flags;
+ u32 sts;
+
+ if (!ecap_ir_support(iommu->ecap))
+ return;
+
+ /*
+ * global invalidation of interrupt entry cache before disabling
+ * interrupt-remapping.
+ */
+ qi_global_iec(iommu);
+
+ spin_lock_irqsave(&iommu->register_lock, flags);
+
+ sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
+ if (!(sts & DMA_GSTS_IRES))
+ goto end;
+
+ iommu->gcmd &= ~DMA_GCMD_IRE;
+ writel(iommu->gcmd, iommu->reg + DMAR_GCMD_REG);
+
+ IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG,
+ readl, !(sts & DMA_GSTS_IRES), sts);
+
+end:
+ spin_unlock_irqrestore(&iommu->register_lock, flags);
+}
+
int __init enable_intr_remapping(int eim)
{
struct dmar_drhd_unit *drhd;
int setup = 0;
+ for_each_drhd_unit(drhd) {
+ struct intel_iommu *iommu = drhd->iommu;
+
+ /*
+ * If the queued invalidation is already initialized,
+ * shouldn't disable it.
+ */
+ if (iommu->qi)
+ continue;
+
+ /*
+ * Clear previous faults.
+ */
+ dmar_fault(-1, iommu);
+
+ /*
+ * Disable intr remapping and queued invalidation, if already
+ * enabled prior to OS handover.
+ */
+ iommu_disable_intr_remapping(iommu);
+
+ dmar_disable_qi(iommu);
+ }
+
/*
* check for the Interrupt-remapping support
*/
@@ -587,3 +668,54 @@ int __init parse_ioapics_under_ir(void)
return ir_supported;
}
+
+void disable_intr_remapping(void)
+{
+ struct dmar_drhd_unit *drhd;
+ struct intel_iommu *iommu = NULL;
+
+ /*
+ * Disable Interrupt-remapping for all the DRHD's now.
+ */
+ for_each_iommu(iommu, drhd) {
+ if (!ecap_ir_support(iommu->ecap))
+ continue;
+
+ iommu_disable_intr_remapping(iommu);
+ }
+}
+
+int reenable_intr_remapping(int eim)
+{
+ struct dmar_drhd_unit *drhd;
+ int setup = 0;
+ struct intel_iommu *iommu = NULL;
+
+ for_each_iommu(iommu, drhd)
+ if (iommu->qi)
+ dmar_reenable_qi(iommu);
+
+ /*
+ * Setup Interrupt-remapping for all the DRHD's now.
+ */
+ for_each_iommu(iommu, drhd) {
+ if (!ecap_ir_support(iommu->ecap))
+ continue;
+
+ /* Set up interrupt remapping for iommu.*/
+ iommu_set_intr_remapping(iommu, eim);
+ setup = 1;
+ }
+
+ if (!setup)
+ goto error;
+
+ return 0;
+
+error:
+ /*
+ * handle error condition gracefully here!
+ */
+ return -1;
+}
+
diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c
new file mode 100644
index 00000000000..7227efc760d
--- /dev/null
+++ b/drivers/pci/iov.c
@@ -0,0 +1,680 @@
+/*
+ * drivers/pci/iov.c
+ *
+ * Copyright (C) 2009 Intel Corporation, Yu Zhao <yu.zhao@intel.com>
+ *
+ * PCI Express I/O Virtualization (IOV) support.
+ * Single Root IOV 1.0
+ */
+
+#include <linux/pci.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include "pci.h"
+
+#define VIRTFN_ID_LEN 16
+
+static inline u8 virtfn_bus(struct pci_dev *dev, int id)
+{
+ return dev->bus->number + ((dev->devfn + dev->sriov->offset +
+ dev->sriov->stride * id) >> 8);
+}
+
+static inline u8 virtfn_devfn(struct pci_dev *dev, int id)
+{
+ return (dev->devfn + dev->sriov->offset +
+ dev->sriov->stride * id) & 0xff;
+}
+
+static struct pci_bus *virtfn_add_bus(struct pci_bus *bus, int busnr)
+{
+ int rc;
+ struct pci_bus *child;
+
+ if (bus->number == busnr)
+ return bus;
+
+ child = pci_find_bus(pci_domain_nr(bus), busnr);
+ if (child)
+ return child;
+
+ child = pci_add_new_bus(bus, NULL, busnr);
+ if (!child)
+ return NULL;
+
+ child->subordinate = busnr;
+ child->dev.parent = bus->bridge;
+ rc = pci_bus_add_child(child);
+ if (rc) {
+ pci_remove_bus(child);
+ return NULL;
+ }
+
+ return child;
+}
+
+static void virtfn_remove_bus(struct pci_bus *bus, int busnr)
+{
+ struct pci_bus *child;
+
+ if (bus->number == busnr)
+ return;
+
+ child = pci_find_bus(pci_domain_nr(bus), busnr);
+ BUG_ON(!child);
+
+ if (list_empty(&child->devices))
+ pci_remove_bus(child);
+}
+
+static int virtfn_add(struct pci_dev *dev, int id, int reset)
+{
+ int i;
+ int rc;
+ u64 size;
+ char buf[VIRTFN_ID_LEN];
+ struct pci_dev *virtfn;
+ struct resource *res;
+ struct pci_sriov *iov = dev->sriov;
+
+ virtfn = alloc_pci_dev();
+ if (!virtfn)
+ return -ENOMEM;
+
+ mutex_lock(&iov->dev->sriov->lock);
+ virtfn->bus = virtfn_add_bus(dev->bus, virtfn_bus(dev, id));
+ if (!virtfn->bus) {
+ kfree(virtfn);
+ mutex_unlock(&iov->dev->sriov->lock);
+ return -ENOMEM;
+ }
+ virtfn->devfn = virtfn_devfn(dev, id);
+ virtfn->vendor = dev->vendor;
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_DID, &virtfn->device);
+ pci_setup_device(virtfn);
+ virtfn->dev.parent = dev->dev.parent;
+
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ if (!res->parent)
+ continue;
+ virtfn->resource[i].name = pci_name(virtfn);
+ virtfn->resource[i].flags = res->flags;
+ size = resource_size(res);
+ do_div(size, iov->total);
+ virtfn->resource[i].start = res->start + size * id;
+ virtfn->resource[i].end = virtfn->resource[i].start + size - 1;
+ rc = request_resource(res, &virtfn->resource[i]);
+ BUG_ON(rc);
+ }
+
+ if (reset)
+ pci_execute_reset_function(virtfn);
+
+ pci_device_add(virtfn, virtfn->bus);
+ mutex_unlock(&iov->dev->sriov->lock);
+
+ virtfn->physfn = pci_dev_get(dev);
+ virtfn->is_virtfn = 1;
+
+ rc = pci_bus_add_device(virtfn);
+ if (rc)
+ goto failed1;
+ sprintf(buf, "virtfn%u", id);
+ rc = sysfs_create_link(&dev->dev.kobj, &virtfn->dev.kobj, buf);
+ if (rc)
+ goto failed1;
+ rc = sysfs_create_link(&virtfn->dev.kobj, &dev->dev.kobj, "physfn");
+ if (rc)
+ goto failed2;
+
+ kobject_uevent(&virtfn->dev.kobj, KOBJ_CHANGE);
+
+ return 0;
+
+failed2:
+ sysfs_remove_link(&dev->dev.kobj, buf);
+failed1:
+ pci_dev_put(dev);
+ mutex_lock(&iov->dev->sriov->lock);
+ pci_remove_bus_device(virtfn);
+ virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+ mutex_unlock(&iov->dev->sriov->lock);
+
+ return rc;
+}
+
+static void virtfn_remove(struct pci_dev *dev, int id, int reset)
+{
+ char buf[VIRTFN_ID_LEN];
+ struct pci_bus *bus;
+ struct pci_dev *virtfn;
+ struct pci_sriov *iov = dev->sriov;
+
+ bus = pci_find_bus(pci_domain_nr(dev->bus), virtfn_bus(dev, id));
+ if (!bus)
+ return;
+
+ virtfn = pci_get_slot(bus, virtfn_devfn(dev, id));
+ if (!virtfn)
+ return;
+
+ pci_dev_put(virtfn);
+
+ if (reset) {
+ device_release_driver(&virtfn->dev);
+ pci_execute_reset_function(virtfn);
+ }
+
+ sprintf(buf, "virtfn%u", id);
+ sysfs_remove_link(&dev->dev.kobj, buf);
+ sysfs_remove_link(&virtfn->dev.kobj, "physfn");
+
+ mutex_lock(&iov->dev->sriov->lock);
+ pci_remove_bus_device(virtfn);
+ virtfn_remove_bus(dev->bus, virtfn_bus(dev, id));
+ mutex_unlock(&iov->dev->sriov->lock);
+
+ pci_dev_put(dev);
+}
+
+static int sriov_migration(struct pci_dev *dev)
+{
+ u16 status;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (!iov->nr_virtfn)
+ return 0;
+
+ if (!(iov->cap & PCI_SRIOV_CAP_VFM))
+ return 0;
+
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_STATUS, &status);
+ if (!(status & PCI_SRIOV_STATUS_VFM))
+ return 0;
+
+ schedule_work(&iov->mtask);
+
+ return 1;
+}
+
+static void sriov_migration_task(struct work_struct *work)
+{
+ int i;
+ u8 state;
+ u16 status;
+ struct pci_sriov *iov = container_of(work, struct pci_sriov, mtask);
+
+ for (i = iov->initial; i < iov->nr_virtfn; i++) {
+ state = readb(iov->mstate + i);
+ if (state == PCI_SRIOV_VFM_MI) {
+ writeb(PCI_SRIOV_VFM_AV, iov->mstate + i);
+ state = readb(iov->mstate + i);
+ if (state == PCI_SRIOV_VFM_AV)
+ virtfn_add(iov->self, i, 1);
+ } else if (state == PCI_SRIOV_VFM_MO) {
+ virtfn_remove(iov->self, i, 1);
+ writeb(PCI_SRIOV_VFM_UA, iov->mstate + i);
+ state = readb(iov->mstate + i);
+ if (state == PCI_SRIOV_VFM_AV)
+ virtfn_add(iov->self, i, 0);
+ }
+ }
+
+ pci_read_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, &status);
+ status &= ~PCI_SRIOV_STATUS_VFM;
+ pci_write_config_word(iov->self, iov->pos + PCI_SRIOV_STATUS, status);
+}
+
+static int sriov_enable_migration(struct pci_dev *dev, int nr_virtfn)
+{
+ int bir;
+ u32 table;
+ resource_size_t pa;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (nr_virtfn <= iov->initial)
+ return 0;
+
+ pci_read_config_dword(dev, iov->pos + PCI_SRIOV_VFM, &table);
+ bir = PCI_SRIOV_VFM_BIR(table);
+ if (bir > PCI_STD_RESOURCE_END)
+ return -EIO;
+
+ table = PCI_SRIOV_VFM_OFFSET(table);
+ if (table + nr_virtfn > pci_resource_len(dev, bir))
+ return -EIO;
+
+ pa = pci_resource_start(dev, bir) + table;
+ iov->mstate = ioremap(pa, nr_virtfn);
+ if (!iov->mstate)
+ return -ENOMEM;
+
+ INIT_WORK(&iov->mtask, sriov_migration_task);
+
+ iov->ctrl |= PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR;
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+
+ return 0;
+}
+
+static void sriov_disable_migration(struct pci_dev *dev)
+{
+ struct pci_sriov *iov = dev->sriov;
+
+ iov->ctrl &= ~(PCI_SRIOV_CTRL_VFM | PCI_SRIOV_CTRL_INTR);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+
+ cancel_work_sync(&iov->mtask);
+ iounmap(iov->mstate);
+}
+
+static int sriov_enable(struct pci_dev *dev, int nr_virtfn)
+{
+ int rc;
+ int i, j;
+ int nres;
+ u16 offset, stride, initial;
+ struct resource *res;
+ struct pci_dev *pdev;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (!nr_virtfn)
+ return 0;
+
+ if (iov->nr_virtfn)
+ return -EINVAL;
+
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_INITIAL_VF, &initial);
+ if (initial > iov->total ||
+ (!(iov->cap & PCI_SRIOV_CAP_VFM) && (initial != iov->total)))
+ return -EIO;
+
+ if (nr_virtfn < 0 || nr_virtfn > iov->total ||
+ (!(iov->cap & PCI_SRIOV_CAP_VFM) && (nr_virtfn > initial)))
+ return -EINVAL;
+
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, nr_virtfn);
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_OFFSET, &offset);
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_VF_STRIDE, &stride);
+ if (!offset || (nr_virtfn > 1 && !stride))
+ return -EIO;
+
+ nres = 0;
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ if (res->parent)
+ nres++;
+ }
+ if (nres != iov->nres) {
+ dev_err(&dev->dev, "not enough MMIO resources for SR-IOV\n");
+ return -ENOMEM;
+ }
+
+ iov->offset = offset;
+ iov->stride = stride;
+
+ if (virtfn_bus(dev, nr_virtfn - 1) > dev->bus->subordinate) {
+ dev_err(&dev->dev, "SR-IOV: bus number out of range\n");
+ return -ENOMEM;
+ }
+
+ if (iov->link != dev->devfn) {
+ pdev = pci_get_slot(dev->bus, iov->link);
+ if (!pdev)
+ return -ENODEV;
+
+ pci_dev_put(pdev);
+
+ if (!pdev->is_physfn)
+ return -ENODEV;
+
+ rc = sysfs_create_link(&dev->dev.kobj,
+ &pdev->dev.kobj, "dep_link");
+ if (rc)
+ return rc;
+ }
+
+ iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE;
+ pci_block_user_cfg_access(dev);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ msleep(100);
+ pci_unblock_user_cfg_access(dev);
+
+ iov->initial = initial;
+ if (nr_virtfn < initial)
+ initial = nr_virtfn;
+
+ for (i = 0; i < initial; i++) {
+ rc = virtfn_add(dev, i, 0);
+ if (rc)
+ goto failed;
+ }
+
+ if (iov->cap & PCI_SRIOV_CAP_VFM) {
+ rc = sriov_enable_migration(dev, nr_virtfn);
+ if (rc)
+ goto failed;
+ }
+
+ kobject_uevent(&dev->dev.kobj, KOBJ_CHANGE);
+ iov->nr_virtfn = nr_virtfn;
+
+ return 0;
+
+failed:
+ for (j = 0; j < i; j++)
+ virtfn_remove(dev, j, 0);
+
+ iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
+ pci_block_user_cfg_access(dev);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ ssleep(1);
+ pci_unblock_user_cfg_access(dev);
+
+ if (iov->link != dev->devfn)
+ sysfs_remove_link(&dev->dev.kobj, "dep_link");
+
+ return rc;
+}
+
+static void sriov_disable(struct pci_dev *dev)
+{
+ int i;
+ struct pci_sriov *iov = dev->sriov;
+
+ if (!iov->nr_virtfn)
+ return;
+
+ if (iov->cap & PCI_SRIOV_CAP_VFM)
+ sriov_disable_migration(dev);
+
+ for (i = 0; i < iov->nr_virtfn; i++)
+ virtfn_remove(dev, i, 0);
+
+ iov->ctrl &= ~(PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE);
+ pci_block_user_cfg_access(dev);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ ssleep(1);
+ pci_unblock_user_cfg_access(dev);
+
+ if (iov->link != dev->devfn)
+ sysfs_remove_link(&dev->dev.kobj, "dep_link");
+
+ iov->nr_virtfn = 0;
+}
+
+static int sriov_init(struct pci_dev *dev, int pos)
+{
+ int i;
+ int rc;
+ int nres;
+ u32 pgsz;
+ u16 ctrl, total, offset, stride;
+ struct pci_sriov *iov;
+ struct resource *res;
+ struct pci_dev *pdev;
+
+ if (dev->pcie_type != PCI_EXP_TYPE_RC_END &&
+ dev->pcie_type != PCI_EXP_TYPE_ENDPOINT)
+ return -ENODEV;
+
+ pci_read_config_word(dev, pos + PCI_SRIOV_CTRL, &ctrl);
+ if (ctrl & PCI_SRIOV_CTRL_VFE) {
+ pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, 0);
+ ssleep(1);
+ }
+
+ pci_read_config_word(dev, pos + PCI_SRIOV_TOTAL_VF, &total);
+ if (!total)
+ return 0;
+
+ ctrl = 0;
+ list_for_each_entry(pdev, &dev->bus->devices, bus_list)
+ if (pdev->is_physfn)
+ goto found;
+
+ pdev = NULL;
+ if (pci_ari_enabled(dev->bus))
+ ctrl |= PCI_SRIOV_CTRL_ARI;
+
+found:
+ pci_write_config_word(dev, pos + PCI_SRIOV_CTRL, ctrl);
+ pci_write_config_word(dev, pos + PCI_SRIOV_NUM_VF, total);
+ pci_read_config_word(dev, pos + PCI_SRIOV_VF_OFFSET, &offset);
+ pci_read_config_word(dev, pos + PCI_SRIOV_VF_STRIDE, &stride);
+ if (!offset || (total > 1 && !stride))
+ return -EIO;
+
+ pci_read_config_dword(dev, pos + PCI_SRIOV_SUP_PGSIZE, &pgsz);
+ i = PAGE_SHIFT > 12 ? PAGE_SHIFT - 12 : 0;
+ pgsz &= ~((1 << i) - 1);
+ if (!pgsz)
+ return -EIO;
+
+ pgsz &= ~(pgsz - 1);
+ pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz);
+
+ nres = 0;
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ i += __pci_read_base(dev, pci_bar_unknown, res,
+ pos + PCI_SRIOV_BAR + i * 4);
+ if (!res->flags)
+ continue;
+ if (resource_size(res) & (PAGE_SIZE - 1)) {
+ rc = -EIO;
+ goto failed;
+ }
+ res->end = res->start + resource_size(res) * total - 1;
+ nres++;
+ }
+
+ iov = kzalloc(sizeof(*iov), GFP_KERNEL);
+ if (!iov) {
+ rc = -ENOMEM;
+ goto failed;
+ }
+
+ iov->pos = pos;
+ iov->nres = nres;
+ iov->ctrl = ctrl;
+ iov->total = total;
+ iov->offset = offset;
+ iov->stride = stride;
+ iov->pgsz = pgsz;
+ iov->self = dev;
+ pci_read_config_dword(dev, pos + PCI_SRIOV_CAP, &iov->cap);
+ pci_read_config_byte(dev, pos + PCI_SRIOV_FUNC_LINK, &iov->link);
+
+ if (pdev)
+ iov->dev = pci_dev_get(pdev);
+ else {
+ iov->dev = dev;
+ mutex_init(&iov->lock);
+ }
+
+ dev->sriov = iov;
+ dev->is_physfn = 1;
+
+ return 0;
+
+failed:
+ for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) {
+ res = dev->resource + PCI_IOV_RESOURCES + i;
+ res->flags = 0;
+ }
+
+ return rc;
+}
+
+static void sriov_release(struct pci_dev *dev)
+{
+ BUG_ON(dev->sriov->nr_virtfn);
+
+ if (dev == dev->sriov->dev)
+ mutex_destroy(&dev->sriov->lock);
+ else
+ pci_dev_put(dev->sriov->dev);
+
+ kfree(dev->sriov);
+ dev->sriov = NULL;
+}
+
+static void sriov_restore_state(struct pci_dev *dev)
+{
+ int i;
+ u16 ctrl;
+ struct pci_sriov *iov = dev->sriov;
+
+ pci_read_config_word(dev, iov->pos + PCI_SRIOV_CTRL, &ctrl);
+ if (ctrl & PCI_SRIOV_CTRL_VFE)
+ return;
+
+ for (i = PCI_IOV_RESOURCES; i <= PCI_IOV_RESOURCE_END; i++)
+ pci_update_resource(dev, i);
+
+ pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_NUM_VF, iov->nr_virtfn);
+ pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl);
+ if (iov->ctrl & PCI_SRIOV_CTRL_VFE)
+ msleep(100);
+}
+
+/**
+ * pci_iov_init - initialize the IOV capability
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+int pci_iov_init(struct pci_dev *dev)
+{
+ int pos;
+
+ if (!dev->is_pcie)
+ return -ENODEV;
+
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_SRIOV);
+ if (pos)
+ return sriov_init(dev, pos);
+
+ return -ENODEV;
+}
+
+/**
+ * pci_iov_release - release resources used by the IOV capability
+ * @dev: the PCI device
+ */
+void pci_iov_release(struct pci_dev *dev)
+{
+ if (dev->is_physfn)
+ sriov_release(dev);
+}
+
+/**
+ * pci_iov_resource_bar - get position of the SR-IOV BAR
+ * @dev: the PCI device
+ * @resno: the resource number
+ * @type: the BAR type to be filled in
+ *
+ * Returns position of the BAR encapsulated in the SR-IOV capability.
+ */
+int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+ enum pci_bar_type *type)
+{
+ if (resno < PCI_IOV_RESOURCES || resno > PCI_IOV_RESOURCE_END)
+ return 0;
+
+ BUG_ON(!dev->is_physfn);
+
+ *type = pci_bar_unknown;
+
+ return dev->sriov->pos + PCI_SRIOV_BAR +
+ 4 * (resno - PCI_IOV_RESOURCES);
+}
+
+/**
+ * pci_restore_iov_state - restore the state of the IOV capability
+ * @dev: the PCI device
+ */
+void pci_restore_iov_state(struct pci_dev *dev)
+{
+ if (dev->is_physfn)
+ sriov_restore_state(dev);
+}
+
+/**
+ * pci_iov_bus_range - find bus range used by Virtual Function
+ * @bus: the PCI bus
+ *
+ * Returns max number of buses (exclude current one) used by Virtual
+ * Functions.
+ */
+int pci_iov_bus_range(struct pci_bus *bus)
+{
+ int max = 0;
+ u8 busnr;
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ if (!dev->is_physfn)
+ continue;
+ busnr = virtfn_bus(dev, dev->sriov->total - 1);
+ if (busnr > max)
+ max = busnr;
+ }
+
+ return max ? max - bus->number : 0;
+}
+
+/**
+ * pci_enable_sriov - enable the SR-IOV capability
+ * @dev: the PCI device
+ *
+ * Returns 0 on success, or negative on failure.
+ */
+int pci_enable_sriov(struct pci_dev *dev, int nr_virtfn)
+{
+ might_sleep();
+
+ if (!dev->is_physfn)
+ return -ENODEV;
+
+ return sriov_enable(dev, nr_virtfn);
+}
+EXPORT_SYMBOL_GPL(pci_enable_sriov);
+
+/**
+ * pci_disable_sriov - disable the SR-IOV capability
+ * @dev: the PCI device
+ */
+void pci_disable_sriov(struct pci_dev *dev)
+{
+ might_sleep();
+
+ if (!dev->is_physfn)
+ return;
+
+ sriov_disable(dev);
+}
+EXPORT_SYMBOL_GPL(pci_disable_sriov);
+
+/**
+ * pci_sriov_migration - notify SR-IOV core of Virtual Function Migration
+ * @dev: the PCI device
+ *
+ * Returns IRQ_HANDLED if the IRQ is handled, or IRQ_NONE if not.
+ *
+ * Physical Function driver is responsible to register IRQ handler using
+ * VF Migration Interrupt Message Number, and call this function when the
+ * interrupt is generated by the hardware.
+ */
+irqreturn_t pci_sriov_migration(struct pci_dev *dev)
+{
+ if (!dev->is_physfn)
+ return IRQ_NONE;
+
+ return sriov_migration(dev) ? IRQ_HANDLED : IRQ_NONE;
+}
+EXPORT_SYMBOL_GPL(pci_sriov_migration);
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index baba2eb5367..6f2e6295e77 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -27,48 +27,53 @@ static int pci_msi_enable = 1;
/* Arch hooks */
-int __attribute__ ((weak))
-arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+#ifndef arch_msi_check_device
+int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
{
return 0;
}
+#endif
-int __attribute__ ((weak))
-arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry)
-{
- return 0;
-}
-
-int __attribute__ ((weak))
-arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+#ifndef arch_setup_msi_irqs
+int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
+ /*
+ * If an architecture wants to support multiple MSI, it needs to
+ * override arch_setup_msi_irqs()
+ */
+ if (type == PCI_CAP_ID_MSI && nvec > 1)
+ return 1;
+
list_for_each_entry(entry, &dev->msi_list, list) {
ret = arch_setup_msi_irq(dev, entry);
- if (ret)
+ if (ret < 0)
return ret;
+ if (ret > 0)
+ return -ENOSPC;
}
return 0;
}
+#endif
-void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq)
-{
- return;
-}
-
-void __attribute__ ((weak))
-arch_teardown_msi_irqs(struct pci_dev *dev)
+#ifndef arch_teardown_msi_irqs
+void arch_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
list_for_each_entry(entry, &dev->msi_list, list) {
- if (entry->irq != 0)
- arch_teardown_msi_irq(entry->irq);
+ int i, nvec;
+ if (entry->irq == 0)
+ continue;
+ nvec = 1 << entry->msi_attrib.multiple;
+ for (i = 0; i < nvec; i++)
+ arch_teardown_msi_irq(entry->irq + i);
}
}
+#endif
static void __msi_set_enable(struct pci_dev *dev, int pos, int enable)
{
@@ -111,27 +116,14 @@ static inline __attribute_const__ u32 msi_mask(unsigned x)
return (1 << (1 << x)) - 1;
}
-static void msix_flush_writes(struct irq_desc *desc)
+static inline __attribute_const__ u32 msi_capable_mask(u16 control)
{
- struct msi_desc *entry;
+ return msi_mask((control >> 1) & 7);
+}
- entry = get_irq_desc_msi(desc);
- BUG_ON(!entry || !entry->dev);
- switch (entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- /* nothing to do */
- break;
- case PCI_CAP_ID_MSIX:
- {
- int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
- PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
- readl(entry->mask_base + offset);
- break;
- }
- default:
- BUG();
- break;
- }
+static inline __attribute_const__ u32 msi_enabled_mask(u16 control)
+{
+ return msi_mask((control >> 4) & 7);
}
/*
@@ -143,49 +135,71 @@ static void msix_flush_writes(struct irq_desc *desc)
* Returns 1 if it succeeded in masking the interrupt and 0 if the device
* doesn't support MSI masking.
*/
-static int msi_set_mask_bits(struct irq_desc *desc, u32 mask, u32 flag)
+static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
- struct msi_desc *entry;
+ u32 mask_bits = desc->masked;
- entry = get_irq_desc_msi(desc);
- BUG_ON(!entry || !entry->dev);
- switch (entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- if (entry->msi_attrib.maskbit) {
- int pos;
- u32 mask_bits;
-
- pos = (long)entry->mask_base;
- pci_read_config_dword(entry->dev, pos, &mask_bits);
- mask_bits &= ~(mask);
- mask_bits |= flag & mask;
- pci_write_config_dword(entry->dev, pos, mask_bits);
- } else {
- return 0;
- }
- break;
- case PCI_CAP_ID_MSIX:
- {
- int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
- PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
- writel(flag, entry->mask_base + offset);
- readl(entry->mask_base + offset);
- break;
- }
- default:
- BUG();
- break;
+ if (!desc->msi_attrib.maskbit)
+ return;
+
+ mask_bits &= ~mask;
+ mask_bits |= flag;
+ pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
+ desc->masked = mask_bits;
+}
+
+/*
+ * This internal function does not flush PCI writes to the device.
+ * All users must ensure that they read from the device before either
+ * assuming that the device state is up to date, or returning out of this
+ * file. This saves a few milliseconds when initialising devices with lots
+ * of MSI-X interrupts.
+ */
+static void msix_mask_irq(struct msi_desc *desc, u32 flag)
+{
+ u32 mask_bits = desc->masked;
+ unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET;
+ mask_bits &= ~1;
+ mask_bits |= flag;
+ writel(mask_bits, desc->mask_base + offset);
+ desc->masked = mask_bits;
+}
+
+static void msi_set_mask_bit(unsigned irq, u32 flag)
+{
+ struct msi_desc *desc = get_irq_msi(irq);
+
+ if (desc->msi_attrib.is_msix) {
+ msix_mask_irq(desc, flag);
+ readl(desc->mask_base); /* Flush write to device */
+ } else {
+ unsigned offset = irq - desc->dev->irq;
+ msi_mask_irq(desc, 1 << offset, flag << offset);
}
- entry->msi_attrib.masked = !!flag;
- return 1;
+}
+
+void mask_msi_irq(unsigned int irq)
+{
+ msi_set_mask_bit(irq, 1);
+}
+
+void unmask_msi_irq(unsigned int irq)
+{
+ msi_set_mask_bit(irq, 0);
}
void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_desc_msi(desc);
- switch(entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- {
+ if (entry->msi_attrib.is_msix) {
+ void __iomem *base = entry->mask_base +
+ entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+ msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+ msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+ msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
+ } else {
struct pci_dev *dev = entry->dev;
int pos = entry->msi_attrib.pos;
u16 data;
@@ -201,21 +215,6 @@ void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
pci_read_config_word(dev, msi_data_reg(pos, 0), &data);
}
msg->data = data;
- break;
- }
- case PCI_CAP_ID_MSIX:
- {
- void __iomem *base;
- base = entry->mask_base +
- entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
-
- msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
- msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
- msg->data = readl(base + PCI_MSIX_ENTRY_DATA_OFFSET);
- break;
- }
- default:
- BUG();
}
}
@@ -229,11 +228,25 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg)
void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
{
struct msi_desc *entry = get_irq_desc_msi(desc);
- switch (entry->msi_attrib.type) {
- case PCI_CAP_ID_MSI:
- {
+ if (entry->msi_attrib.is_msix) {
+ void __iomem *base;
+ base = entry->mask_base +
+ entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
+
+ writel(msg->address_lo,
+ base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
+ writel(msg->address_hi,
+ base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
+ writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
+ } else {
struct pci_dev *dev = entry->dev;
int pos = entry->msi_attrib.pos;
+ u16 msgctl;
+
+ pci_read_config_word(dev, msi_control_reg(pos), &msgctl);
+ msgctl &= ~PCI_MSI_FLAGS_QSIZE;
+ msgctl |= entry->msi_attrib.multiple << 4;
+ pci_write_config_word(dev, msi_control_reg(pos), msgctl);
pci_write_config_dword(dev, msi_lower_address_reg(pos),
msg->address_lo);
@@ -246,23 +259,6 @@ void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg)
pci_write_config_word(dev, msi_data_reg(pos, 0),
msg->data);
}
- break;
- }
- case PCI_CAP_ID_MSIX:
- {
- void __iomem *base;
- base = entry->mask_base +
- entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;
-
- writel(msg->address_lo,
- base + PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET);
- writel(msg->address_hi,
- base + PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET);
- writel(msg->data, base + PCI_MSIX_ENTRY_DATA_OFFSET);
- break;
- }
- default:
- BUG();
}
entry->msg = *msg;
}
@@ -274,37 +270,18 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg)
write_msi_msg_desc(desc, msg);
}
-void mask_msi_irq(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
-
- msi_set_mask_bits(desc, 1, 1);
- msix_flush_writes(desc);
-}
-
-void unmask_msi_irq(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
-
- msi_set_mask_bits(desc, 1, 0);
- msix_flush_writes(desc);
-}
-
static int msi_free_irqs(struct pci_dev* dev);
-static struct msi_desc* alloc_msi_entry(void)
+static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
{
- struct msi_desc *entry;
-
- entry = kzalloc(sizeof(struct msi_desc), GFP_KERNEL);
- if (!entry)
+ struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+ if (!desc)
return NULL;
- INIT_LIST_HEAD(&entry->list);
- entry->irq = 0;
- entry->dev = NULL;
+ INIT_LIST_HEAD(&desc->list);
+ desc->dev = dev;
- return entry;
+ return desc;
}
static void pci_intx_for_msi(struct pci_dev *dev, int enable)
@@ -328,15 +305,11 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
pci_intx_for_msi(dev, 0);
msi_set_enable(dev, 0);
write_msi_msg(dev->irq, &entry->msg);
- if (entry->msi_attrib.maskbit) {
- struct irq_desc *desc = irq_to_desc(dev->irq);
- msi_set_mask_bits(desc, entry->msi_attrib.maskbits_mask,
- entry->msi_attrib.masked);
- }
pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &control);
+ msi_mask_irq(entry, msi_capable_mask(control), entry->masked);
control &= ~PCI_MSI_FLAGS_QSIZE;
- control |= PCI_MSI_FLAGS_ENABLE;
+ control |= (entry->msi_attrib.multiple << 4) | PCI_MSI_FLAGS_ENABLE;
pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control);
}
@@ -354,9 +327,8 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
msix_set_enable(dev, 0);
list_for_each_entry(entry, &dev->msi_list, list) {
- struct irq_desc *desc = irq_to_desc(entry->irq);
write_msi_msg(entry->irq, &entry->msg);
- msi_set_mask_bits(desc, 1, entry->msi_attrib.masked);
+ msix_mask_irq(entry, entry->masked);
}
BUG_ON(list_empty(&dev->msi_list));
@@ -378,52 +350,48 @@ EXPORT_SYMBOL_GPL(pci_restore_msi_state);
/**
* msi_capability_init - configure device's MSI capability structure
* @dev: pointer to the pci_dev data structure of MSI device function
+ * @nvec: number of interrupts to allocate
*
- * Setup the MSI capability structure of device function with a single
- * MSI irq, regardless of device function is capable of handling
- * multiple messages. A return of zero indicates the successful setup
- * of an entry zero with the new MSI irq or non-zero for otherwise.
- **/
-static int msi_capability_init(struct pci_dev *dev)
+ * Setup the MSI capability structure of the device with the requested
+ * number of interrupts. A return value of zero indicates the successful
+ * setup of an entry with the new MSI irq. A negative return value indicates
+ * an error, and a positive return value indicates the number of interrupts
+ * which could have been allocated.
+ */
+static int msi_capability_init(struct pci_dev *dev, int nvec)
{
struct msi_desc *entry;
int pos, ret;
u16 control;
+ unsigned mask;
msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */
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();
+ entry = alloc_msi_entry(dev);
if (!entry)
return -ENOMEM;
- entry->msi_attrib.type = PCI_CAP_ID_MSI;
+ entry->msi_attrib.is_msix = 0;
entry->msi_attrib.is_64 = is_64bit_address(control);
entry->msi_attrib.entry_nr = 0;
entry->msi_attrib.maskbit = is_mask_bit_support(control);
- entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq; /* Save IOAPIC IRQ */
entry->msi_attrib.pos = pos;
- entry->dev = dev;
- if (entry->msi_attrib.maskbit) {
- unsigned int base, maskbits, temp;
-
- base = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
- entry->mask_base = (void __iomem *)(long)base;
-
- /* All MSIs are unmasked by default, Mask them all */
- pci_read_config_dword(dev, base, &maskbits);
- temp = msi_mask((control & PCI_MSI_FLAGS_QMASK) >> 1);
- maskbits |= temp;
- pci_write_config_dword(dev, base, maskbits);
- entry->msi_attrib.maskbits_mask = temp;
- }
+
+ entry->mask_pos = msi_mask_bits_reg(pos, entry->msi_attrib.is_64);
+ /* All MSIs are unmasked by default, Mask them all */
+ if (entry->msi_attrib.maskbit)
+ pci_read_config_dword(dev, entry->mask_pos, &entry->masked);
+ mask = msi_capable_mask(control);
+ msi_mask_irq(entry, mask, mask);
+
list_add_tail(&entry->list, &dev->msi_list);
/* Configure MSI capability structure */
- ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI);
+ ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
if (ret) {
msi_free_irqs(dev);
return ret;
@@ -476,26 +444,28 @@ static int msix_capability_init(struct pci_dev *dev,
/* MSI-X Table Initialization */
for (i = 0; i < nvec; i++) {
- entry = alloc_msi_entry();
+ entry = alloc_msi_entry(dev);
if (!entry)
break;
j = entries[i].entry;
- entry->msi_attrib.type = PCI_CAP_ID_MSIX;
+ entry->msi_attrib.is_msix = 1;
entry->msi_attrib.is_64 = 1;
entry->msi_attrib.entry_nr = j;
- entry->msi_attrib.maskbit = 1;
- entry->msi_attrib.masked = 1;
entry->msi_attrib.default_irq = dev->irq;
entry->msi_attrib.pos = pos;
- entry->dev = dev;
entry->mask_base = base;
+ entry->masked = readl(base + j * PCI_MSIX_ENTRY_SIZE +
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
+ msix_mask_irq(entry, 1);
list_add_tail(&entry->list, &dev->msi_list);
}
ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
- if (ret) {
+ if (ret < 0) {
+ /* If we had some success report the number of irqs
+ * we succeeded in setting up. */
int avail = 0;
list_for_each_entry(entry, &dev->msi_list, list) {
if (entry->irq != 0) {
@@ -503,14 +473,13 @@ static int msix_capability_init(struct pci_dev *dev,
}
}
- msi_free_irqs(dev);
+ if (avail != 0)
+ ret = avail;
+ }
- /* If we had some success report the number of irqs
- * we succeeded in setting up.
- */
- if (avail == 0)
- avail = ret;
- return avail;
+ if (ret) {
+ msi_free_irqs(dev);
+ return ret;
}
i = 0;
@@ -575,39 +544,54 @@ static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type)
}
/**
- * pci_enable_msi - configure device's MSI capability structure
- * @dev: pointer to the pci_dev data structure of MSI device function
+ * pci_enable_msi_block - configure device's MSI capability structure
+ * @dev: device to configure
+ * @nvec: number of interrupts to configure
*
- * Setup the MSI capability structure of device function with
- * a single MSI irq upon its software driver call to request for
- * MSI mode enabled on its hardware device function. A return of zero
- * indicates the successful setup of an entry zero with the new MSI
- * irq or non-zero for otherwise.
- **/
-int pci_enable_msi(struct pci_dev* dev)
+ * Allocate IRQs for a device with the MSI capability.
+ * This function returns a negative errno if an error occurs. If it
+ * is unable to allocate the number of interrupts requested, it returns
+ * the number of interrupts it might be able to allocate. If it successfully
+ * allocates at least the number of interrupts requested, it returns 0 and
+ * updates the @dev's irq member to the lowest new interrupt number; the
+ * other interrupt numbers allocated to this device are consecutive.
+ */
+int pci_enable_msi_block(struct pci_dev *dev, unsigned int nvec)
{
- int status;
+ int status, pos, maxvec;
+ u16 msgctl;
- status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI);
+ pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
+ if (!pos)
+ return -EINVAL;
+ pci_read_config_word(dev, pos + PCI_MSI_FLAGS, &msgctl);
+ maxvec = 1 << ((msgctl & PCI_MSI_FLAGS_QMASK) >> 1);
+ if (nvec > maxvec)
+ return maxvec;
+
+ status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSI);
if (status)
return status;
WARN_ON(!!dev->msi_enabled);
- /* Check whether driver already requested for MSI-X irqs */
+ /* Check whether driver already requested MSI-X irqs */
if (dev->msix_enabled) {
dev_info(&dev->dev, "can't enable MSI "
"(MSI-X already enabled)\n");
return -EINVAL;
}
- status = msi_capability_init(dev);
+
+ status = msi_capability_init(dev, nvec);
return status;
}
-EXPORT_SYMBOL(pci_enable_msi);
+EXPORT_SYMBOL(pci_enable_msi_block);
-void pci_msi_shutdown(struct pci_dev* dev)
+void pci_msi_shutdown(struct pci_dev *dev)
{
- struct msi_desc *entry;
+ struct msi_desc *desc;
+ u32 mask;
+ u16 ctrl;
if (!pci_msi_enable || !dev || !dev->msi_enabled)
return;
@@ -617,19 +601,15 @@ void pci_msi_shutdown(struct pci_dev* dev)
dev->msi_enabled = 0;
BUG_ON(list_empty(&dev->msi_list));
- entry = list_entry(dev->msi_list.next, struct msi_desc, list);
- /* Return the the pci reset with msi irqs unmasked */
- if (entry->msi_attrib.maskbit) {
- u32 mask = entry->msi_attrib.maskbits_mask;
- struct irq_desc *desc = irq_to_desc(dev->irq);
- msi_set_mask_bits(desc, mask, ~mask);
- }
- if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
- return;
+ desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
+ pci_read_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &ctrl);
+ mask = msi_capable_mask(ctrl);
+ msi_mask_irq(desc, mask, ~mask);
/* Restore dev->irq to its default pin-assertion irq */
- dev->irq = entry->msi_attrib.default_irq;
+ dev->irq = desc->msi_attrib.default_irq;
}
+
void pci_disable_msi(struct pci_dev* dev)
{
struct msi_desc *entry;
@@ -640,7 +620,7 @@ void pci_disable_msi(struct pci_dev* dev)
pci_msi_shutdown(dev);
entry = list_entry(dev->msi_list.next, struct msi_desc, list);
- if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI)
+ if (entry->msi_attrib.is_msix)
return;
msi_free_irqs(dev);
@@ -652,14 +632,18 @@ static int msi_free_irqs(struct pci_dev* dev)
struct msi_desc *entry, *tmp;
list_for_each_entry(entry, &dev->msi_list, list) {
- if (entry->irq)
- BUG_ON(irq_has_action(entry->irq));
+ int i, nvec;
+ if (!entry->irq)
+ continue;
+ nvec = 1 << entry->msi_attrib.multiple;
+ for (i = 0; i < nvec; i++)
+ BUG_ON(irq_has_action(entry->irq + i));
}
arch_teardown_msi_irqs(dev);
list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
- if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) {
+ if (entry->msi_attrib.is_msix) {
writel(1, entry->mask_base + entry->msi_attrib.entry_nr
* PCI_MSIX_ENTRY_SIZE
+ PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET);
@@ -675,6 +659,23 @@ static int msi_free_irqs(struct pci_dev* dev)
}
/**
+ * pci_msix_table_size - return the number of device's MSI-X table entries
+ * @dev: pointer to the pci_dev data structure of MSI-X device function
+ */
+int pci_msix_table_size(struct pci_dev *dev)
+{
+ int pos;
+ u16 control;
+
+ pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
+ if (!pos)
+ return 0;
+
+ pci_read_config_word(dev, msi_control_reg(pos), &control);
+ return multi_msix_capable(control);
+}
+
+/**
* pci_enable_msix - configure device's MSI-X capability structure
* @dev: pointer to the pci_dev data structure of MSI-X device function
* @entries: pointer to an array of MSI-X entries
@@ -691,9 +692,8 @@ static int msi_free_irqs(struct pci_dev* dev)
**/
int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
{
- int status, pos, nr_entries;
+ int status, nr_entries;
int i, j;
- u16 control;
if (!entries)
return -EINVAL;
@@ -702,9 +702,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec)
if (status)
return status;
- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
- pci_read_config_word(dev, msi_control_reg(pos), &control);
- nr_entries = multi_msix_capable(control);
+ nr_entries = pci_msix_table_size(dev);
if (nvec > nr_entries)
return -EINVAL;
diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h
index 3898f523714..71f4df2ef65 100644
--- a/drivers/pci/msi.h
+++ b/drivers/pci/msi.h
@@ -20,14 +20,8 @@
#define msi_mask_bits_reg(base, is64bit) \
( (is64bit == 1) ? base+PCI_MSI_MASK_BIT : base+PCI_MSI_MASK_BIT-4)
#define msi_disable(control) control &= ~PCI_MSI_FLAGS_ENABLE
-#define multi_msi_capable(control) \
- (1 << ((control & PCI_MSI_FLAGS_QMASK) >> 1))
-#define multi_msi_enable(control, num) \
- control |= (((num >> 1) << 4) & PCI_MSI_FLAGS_QSIZE);
#define is_64bit_address(control) (!!(control & PCI_MSI_FLAGS_64BIT))
#define is_mask_bit_support(control) (!!(control & PCI_MSI_FLAGS_MASKBIT))
-#define msi_enable(control, num) multi_msi_enable(control, num); \
- control |= PCI_MSI_FLAGS_ENABLE
#define msix_table_offset_reg(base) (base + 0x04)
#define msix_pba_offset_reg(base) (base + 0x08)
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index deea8a187eb..ea15b053745 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -18,221 +18,6 @@
#include <linux/pci-acpi.h>
#include "pci.h"
-struct acpi_osc_data {
- acpi_handle handle;
- u32 support_set;
- u32 control_set;
- u32 control_query;
- int is_queried;
- struct list_head sibiling;
-};
-static LIST_HEAD(acpi_osc_data_list);
-
-struct acpi_osc_args {
- u32 capbuf[3];
-};
-
-static DEFINE_MUTEX(pci_acpi_lock);
-
-static struct acpi_osc_data *acpi_get_osc_data(acpi_handle handle)
-{
- struct acpi_osc_data *data;
-
- list_for_each_entry(data, &acpi_osc_data_list, sibiling) {
- if (data->handle == handle)
- return data;
- }
- data = kzalloc(sizeof(*data), GFP_KERNEL);
- if (!data)
- return NULL;
- INIT_LIST_HEAD(&data->sibiling);
- data->handle = handle;
- list_add_tail(&data->sibiling, &acpi_osc_data_list);
- return data;
-}
-
-static u8 OSC_UUID[16] = {0x5B, 0x4D, 0xDB, 0x33, 0xF7, 0x1F, 0x1C, 0x40,
- 0x96, 0x57, 0x74, 0x41, 0xC0, 0x3D, 0xD7, 0x66};
-
-static acpi_status acpi_run_osc(acpi_handle handle,
- struct acpi_osc_args *osc_args, u32 *retval)
-{
- acpi_status status;
- struct acpi_object_list input;
- union acpi_object in_params[4];
- struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
- union acpi_object *out_obj;
- u32 errors, flags = osc_args->capbuf[OSC_QUERY_TYPE];
-
- /* Setting up input parameters */
- input.count = 4;
- input.pointer = in_params;
- in_params[0].type = ACPI_TYPE_BUFFER;
- in_params[0].buffer.length = 16;
- in_params[0].buffer.pointer = OSC_UUID;
- in_params[1].type = ACPI_TYPE_INTEGER;
- in_params[1].integer.value = 1;
- in_params[2].type = ACPI_TYPE_INTEGER;
- in_params[2].integer.value = 3;
- in_params[3].type = ACPI_TYPE_BUFFER;
- in_params[3].buffer.length = 12;
- in_params[3].buffer.pointer = (u8 *)osc_args->capbuf;
-
- status = acpi_evaluate_object(handle, "_OSC", &input, &output);
- if (ACPI_FAILURE(status))
- return status;
-
- if (!output.length)
- return AE_NULL_OBJECT;
-
- out_obj = output.pointer;
- if (out_obj->type != ACPI_TYPE_BUFFER) {
- printk(KERN_DEBUG "Evaluate _OSC returns wrong type\n");
- status = AE_TYPE;
- goto out_kfree;
- }
- /* Need to ignore the bit0 in result code */
- errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
- if (errors) {
- if (errors & OSC_REQUEST_ERROR)
- printk(KERN_DEBUG "_OSC request fails\n");
- if (errors & OSC_INVALID_UUID_ERROR)
- printk(KERN_DEBUG "_OSC invalid UUID\n");
- if (errors & OSC_INVALID_REVISION_ERROR)
- printk(KERN_DEBUG "_OSC invalid revision\n");
- if (errors & OSC_CAPABILITIES_MASK_ERROR) {
- if (flags & OSC_QUERY_ENABLE)
- goto out_success;
- printk(KERN_DEBUG "_OSC FW not grant req. control\n");
- status = AE_SUPPORT;
- goto out_kfree;
- }
- status = AE_ERROR;
- goto out_kfree;
- }
-out_success:
- *retval = *((u32 *)(out_obj->buffer.pointer + 8));
- status = AE_OK;
-
-out_kfree:
- kfree(output.pointer);
- return status;
-}
-
-static acpi_status __acpi_query_osc(u32 flags, struct acpi_osc_data *osc_data)
-{
- acpi_status status;
- u32 support_set, result;
- struct acpi_osc_args osc_args;
-
- /* do _OSC query for all possible controls */
- support_set = osc_data->support_set | (flags & OSC_SUPPORT_MASKS);
- osc_args.capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
- osc_args.capbuf[OSC_SUPPORT_TYPE] = support_set;
- osc_args.capbuf[OSC_CONTROL_TYPE] = OSC_CONTROL_MASKS;
-
- status = acpi_run_osc(osc_data->handle, &osc_args, &result);
- if (ACPI_SUCCESS(status)) {
- osc_data->support_set = support_set;
- osc_data->control_query = result;
- osc_data->is_queried = 1;
- }
-
- return status;
-}
-
-/*
- * pci_acpi_osc_support: Invoke _OSC indicating support for the given feature
- * @flags: Bitmask of flags to support
- *
- * See the ACPI spec for the definition of the flags
- */
-int pci_acpi_osc_support(acpi_handle handle, u32 flags)
-{
- acpi_status status;
- acpi_handle tmp;
- struct acpi_osc_data *osc_data;
- int rc = 0;
-
- status = acpi_get_handle(handle, "_OSC", &tmp);
- if (ACPI_FAILURE(status))
- return -ENOTTY;
-
- mutex_lock(&pci_acpi_lock);
- osc_data = acpi_get_osc_data(handle);
- if (!osc_data) {
- printk(KERN_ERR "acpi osc data array is full\n");
- rc = -ENOMEM;
- goto out;
- }
-
- __acpi_query_osc(flags, osc_data);
-out:
- mutex_unlock(&pci_acpi_lock);
- return rc;
-}
-
-/**
- * pci_osc_control_set - commit requested control to Firmware
- * @handle: acpi_handle for the target ACPI object
- * @flags: driver's requested control bits
- *
- * Attempt to take control from Firmware on requested control bits.
- **/
-acpi_status pci_osc_control_set(acpi_handle handle, u32 flags)
-{
- acpi_status status;
- u32 control_req, control_set, result;
- acpi_handle tmp;
- struct acpi_osc_data *osc_data;
- struct acpi_osc_args osc_args;
-
- status = acpi_get_handle(handle, "_OSC", &tmp);
- if (ACPI_FAILURE(status))
- return status;
-
- mutex_lock(&pci_acpi_lock);
- osc_data = acpi_get_osc_data(handle);
- if (!osc_data) {
- printk(KERN_ERR "acpi osc data array is full\n");
- status = AE_ERROR;
- goto out;
- }
-
- control_req = (flags & OSC_CONTROL_MASKS);
- if (!control_req) {
- status = AE_TYPE;
- goto out;
- }
-
- /* No need to evaluate _OSC if the control was already granted. */
- if ((osc_data->control_set & control_req) == control_req)
- goto out;
-
- if (!osc_data->is_queried) {
- status = __acpi_query_osc(osc_data->support_set, osc_data);
- if (ACPI_FAILURE(status))
- goto out;
- }
-
- if ((osc_data->control_query & control_req) != control_req) {
- status = AE_SUPPORT;
- goto out;
- }
-
- control_set = osc_data->control_set | control_req;
- osc_args.capbuf[OSC_QUERY_TYPE] = 0;
- osc_args.capbuf[OSC_SUPPORT_TYPE] = osc_data->support_set;
- osc_args.capbuf[OSC_CONTROL_TYPE] = control_set;
- status = acpi_run_osc(handle, &osc_args, &result);
- if (ACPI_SUCCESS(status))
- osc_data->control_set = result;
-out:
- mutex_unlock(&pci_acpi_lock);
- return status;
-}
-EXPORT_SYMBOL(pci_osc_control_set);
-
/*
* _SxD returns the D-state with the highest power
* (lowest D-state number) supported in the S-state "x".
@@ -386,12 +171,12 @@ static int __init acpi_pci_init(void)
{
int ret;
- if (acpi_gbl_FADT.boot_flags & BAF_MSI_NOT_SUPPORTED) {
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_MSI) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support MSI, so disable it\n");
pci_no_msi();
}
- if (acpi_gbl_FADT.boot_flags & BAF_PCIE_ASPM_CONTROL) {
+ if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n");
pcie_no_aspm();
}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 93eac142358..d76c4c85367 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -99,6 +99,52 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count)
}
static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+/**
+ * store_remove_id - remove a PCI device ID from this driver
+ * @driver: target device driver
+ * @buf: buffer for scanning device ID data
+ * @count: input size
+ *
+ * Removes a dynamic pci device ID to this driver.
+ */
+static ssize_t
+store_remove_id(struct device_driver *driver, const char *buf, size_t count)
+{
+ struct pci_dynid *dynid, *n;
+ struct pci_driver *pdrv = to_pci_driver(driver);
+ __u32 vendor, device, subvendor = PCI_ANY_ID,
+ subdevice = PCI_ANY_ID, class = 0, class_mask = 0;
+ int fields = 0;
+ int retval = -ENODEV;
+
+ fields = sscanf(buf, "%x %x %x %x %x %x",
+ &vendor, &device, &subvendor, &subdevice,
+ &class, &class_mask);
+ if (fields < 2)
+ return -EINVAL;
+
+ spin_lock(&pdrv->dynids.lock);
+ list_for_each_entry_safe(dynid, n, &pdrv->dynids.list, node) {
+ struct pci_device_id *id = &dynid->id;
+ if ((id->vendor == vendor) &&
+ (id->device == device) &&
+ (subvendor == PCI_ANY_ID || id->subvendor == subvendor) &&
+ (subdevice == PCI_ANY_ID || id->subdevice == subdevice) &&
+ !((id->class ^ class) & class_mask)) {
+ list_del(&dynid->node);
+ kfree(dynid);
+ retval = 0;
+ break;
+ }
+ }
+ spin_unlock(&pdrv->dynids.lock);
+
+ if (retval)
+ return retval;
+ return count;
+}
+static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id);
+
static void
pci_free_dynids(struct pci_driver *drv)
{
@@ -125,6 +171,20 @@ static void pci_remove_newid_file(struct pci_driver *drv)
{
driver_remove_file(&drv->driver, &driver_attr_new_id);
}
+
+static int
+pci_create_removeid_file(struct pci_driver *drv)
+{
+ int error = 0;
+ if (drv->probe != NULL)
+ error = driver_create_file(&drv->driver,&driver_attr_remove_id);
+ return error;
+}
+
+static void pci_remove_removeid_file(struct pci_driver *drv)
+{
+ driver_remove_file(&drv->driver, &driver_attr_remove_id);
+}
#else /* !CONFIG_HOTPLUG */
static inline void pci_free_dynids(struct pci_driver *drv) {}
static inline int pci_create_newid_file(struct pci_driver *drv)
@@ -132,6 +192,11 @@ static inline int pci_create_newid_file(struct pci_driver *drv)
return 0;
}
static inline void pci_remove_newid_file(struct pci_driver *drv) {}
+static inline int pci_create_removeid_file(struct pci_driver *drv)
+{
+ return 0;
+}
+static inline void pci_remove_removeid_file(struct pci_driver *drv) {}
#endif
/**
@@ -212,10 +277,9 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
node = dev_to_node(&dev->dev);
if (node >= 0) {
int cpu;
- node_to_cpumask_ptr(nodecpumask, node);
get_online_cpus();
- cpu = cpumask_any_and(nodecpumask, cpu_online_mask);
+ cpu = cpumask_any_and(cpumask_of_node(node), cpu_online_mask);
if (cpu < nr_cpu_ids)
error = work_on_cpu(cpu, local_pci_probe, &ddi);
else
@@ -352,53 +416,60 @@ static int pci_legacy_suspend(struct device *dev, pm_message_t state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- int i = 0;
+
+ pci_dev->state_saved = false;
if (drv && drv->suspend) {
pci_power_t prev = pci_dev->current_state;
+ int error;
- pci_dev->state_saved = false;
-
- i = drv->suspend(pci_dev, state);
- suspend_report_result(drv->suspend, i);
- if (i)
- return i;
-
- if (pci_dev->state_saved)
- goto Fixup;
+ error = drv->suspend(pci_dev, state);
+ suspend_report_result(drv->suspend, error);
+ if (error)
+ return error;
- if (pci_dev->current_state != PCI_D0
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
&& pci_dev->current_state != PCI_UNKNOWN) {
WARN_ONCE(pci_dev->current_state != prev,
"PCI PM: Device state not saved by %pF\n",
drv->suspend);
- goto Fixup;
}
}
- pci_save_state(pci_dev);
- /*
- * This is for compatibility with existing code with legacy PM support.
- */
- pci_pm_set_unknown_state(pci_dev);
-
- Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
- return i;
+ return 0;
}
static int pci_legacy_suspend_late(struct device *dev, pm_message_t state)
{
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
- int i = 0;
if (drv && drv->suspend_late) {
- i = drv->suspend_late(pci_dev, state);
- suspend_report_result(drv->suspend_late, i);
+ pci_power_t prev = pci_dev->current_state;
+ int error;
+
+ error = drv->suspend_late(pci_dev, state);
+ suspend_report_result(drv->suspend_late, error);
+ if (error)
+ return error;
+
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: Device state not saved by %pF\n",
+ drv->suspend_late);
+ return 0;
+ }
}
- return i;
+
+ if (!pci_dev->state_saved)
+ pci_save_state(pci_dev);
+
+ pci_pm_set_unknown_state(pci_dev);
+
+ return 0;
}
static int pci_legacy_resume_early(struct device *dev)
@@ -423,6 +494,23 @@ static int pci_legacy_resume(struct device *dev)
/* Auxiliary functions used by the new power management framework */
+/**
+ * pci_restore_standard_config - restore standard config registers of PCI device
+ * @pci_dev: PCI device to handle
+ */
+static int pci_restore_standard_config(struct pci_dev *pci_dev)
+{
+ pci_update_current_state(pci_dev, PCI_UNKNOWN);
+
+ if (pci_dev->current_state != PCI_D0) {
+ int error = pci_set_power_state(pci_dev, PCI_D0);
+ if (error)
+ return error;
+ }
+
+ return pci_dev->state_saved ? pci_restore_state(pci_dev) : 0;
+}
+
static void pci_pm_default_resume_noirq(struct pci_dev *pci_dev)
{
pci_restore_standard_config(pci_dev);
@@ -443,7 +531,6 @@ static void pci_pm_default_suspend(struct pci_dev *pci_dev)
/* Disable non-bridge devices without PM support */
if (!pci_is_bridge(pci_dev))
pci_disable_enabled_device(pci_dev);
- pci_save_state(pci_dev);
}
static bool pci_has_legacy_pm_support(struct pci_dev *pci_dev)
@@ -493,13 +580,13 @@ static int pci_pm_suspend(struct device *dev)
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_SUSPEND);
+ pci_dev->state_saved = false;
+
if (!pm) {
pci_pm_default_suspend(pci_dev);
goto Fixup;
}
- pci_dev->state_saved = false;
-
if (pm->suspend) {
pci_power_t prev = pci_dev->current_state;
int error;
@@ -509,24 +596,14 @@ static int pci_pm_suspend(struct device *dev)
if (error)
return error;
- if (pci_dev->state_saved)
- goto Fixup;
-
- if (pci_dev->current_state != PCI_D0
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
&& pci_dev->current_state != PCI_UNKNOWN) {
WARN_ONCE(pci_dev->current_state != prev,
"PCI PM: State of device not saved by %pF\n",
pm->suspend);
- goto Fixup;
}
}
- if (!pci_dev->state_saved) {
- pci_save_state(pci_dev);
- if (!pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
- }
-
Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
@@ -536,21 +613,43 @@ static int pci_pm_suspend(struct device *dev)
static int pci_pm_suspend_noirq(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
- struct device_driver *drv = dev->driver;
- int error = 0;
+ struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend_late(dev, PMSG_SUSPEND);
- if (drv && drv->pm && drv->pm->suspend_noirq) {
- error = drv->pm->suspend_noirq(dev);
- suspend_report_result(drv->pm->suspend_noirq, error);
+ if (!pm) {
+ pci_save_state(pci_dev);
+ return 0;
}
- if (!error)
- pci_pm_set_unknown_state(pci_dev);
+ if (pm->suspend_noirq) {
+ pci_power_t prev = pci_dev->current_state;
+ int error;
- return error;
+ error = pm->suspend_noirq(dev);
+ suspend_report_result(pm->suspend_noirq, error);
+ if (error)
+ return error;
+
+ if (!pci_dev->state_saved && pci_dev->current_state != PCI_D0
+ && pci_dev->current_state != PCI_UNKNOWN) {
+ WARN_ONCE(pci_dev->current_state != prev,
+ "PCI PM: State of device not saved by %pF\n",
+ pm->suspend_noirq);
+ return 0;
+ }
+ }
+
+ if (!pci_dev->state_saved) {
+ pci_save_state(pci_dev);
+ if (!pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+ }
+
+ pci_pm_set_unknown_state(pci_dev);
+
+ return 0;
}
static int pci_pm_resume_noirq(struct device *dev)
@@ -617,13 +716,13 @@ static int pci_pm_freeze(struct device *dev)
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_FREEZE);
+ pci_dev->state_saved = false;
+
if (!pm) {
pci_pm_default_suspend(pci_dev);
return 0;
}
- pci_dev->state_saved = false;
-
if (pm->freeze) {
int error;
@@ -633,9 +732,6 @@ static int pci_pm_freeze(struct device *dev)
return error;
}
- if (!pci_dev->state_saved)
- pci_save_state(pci_dev);
-
return 0;
}
@@ -643,20 +739,25 @@ static int pci_pm_freeze_noirq(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct device_driver *drv = dev->driver;
- int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend_late(dev, PMSG_FREEZE);
if (drv && drv->pm && drv->pm->freeze_noirq) {
+ int error;
+
error = drv->pm->freeze_noirq(dev);
suspend_report_result(drv->pm->freeze_noirq, error);
+ if (error)
+ return error;
}
- if (!error)
- pci_pm_set_unknown_state(pci_dev);
+ if (!pci_dev->state_saved)
+ pci_save_state(pci_dev);
- return error;
+ pci_pm_set_unknown_state(pci_dev);
+
+ return 0;
}
static int pci_pm_thaw_noirq(struct device *dev)
@@ -699,46 +800,56 @@ static int pci_pm_poweroff(struct device *dev)
{
struct pci_dev *pci_dev = to_pci_dev(dev);
struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int error = 0;
if (pci_has_legacy_pm_support(pci_dev))
return pci_legacy_suspend(dev, PMSG_HIBERNATE);
+ pci_dev->state_saved = false;
+
if (!pm) {
pci_pm_default_suspend(pci_dev);
goto Fixup;
}
- pci_dev->state_saved = false;
-
if (pm->poweroff) {
+ int error;
+
error = pm->poweroff(dev);
suspend_report_result(pm->poweroff, error);
+ if (error)
+ return error;
}
- if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
- pci_prepare_to_sleep(pci_dev);
-
Fixup:
pci_fixup_device(pci_fixup_suspend, pci_dev);
- return error;
+ return 0;
}
static int pci_pm_poweroff_noirq(struct device *dev)
{
+ struct pci_dev *pci_dev = to_pci_dev(dev);
struct device_driver *drv = dev->driver;
- int error = 0;
if (pci_has_legacy_pm_support(to_pci_dev(dev)))
return pci_legacy_suspend_late(dev, PMSG_HIBERNATE);
- if (drv && drv->pm && drv->pm->poweroff_noirq) {
+ if (!drv || !drv->pm)
+ return 0;
+
+ if (drv->pm->poweroff_noirq) {
+ int error;
+
error = drv->pm->poweroff_noirq(dev);
suspend_report_result(drv->pm->poweroff_noirq, error);
+ if (error)
+ return error;
}
- return error;
+ if (!pci_dev->state_saved && !pci_is_bridge(pci_dev))
+ pci_prepare_to_sleep(pci_dev);
+
+ return 0;
}
static int pci_pm_restore_noirq(struct device *dev)
@@ -852,13 +963,23 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
/* register with core */
error = driver_register(&drv->driver);
if (error)
- return error;
+ goto out;
error = pci_create_newid_file(drv);
if (error)
- driver_unregister(&drv->driver);
+ goto out_newid;
+ error = pci_create_removeid_file(drv);
+ if (error)
+ goto out_removeid;
+out:
return error;
+
+out_removeid:
+ pci_remove_newid_file(drv);
+out_newid:
+ driver_unregister(&drv->driver);
+ goto out;
}
/**
@@ -874,6 +995,7 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner,
void
pci_unregister_driver(struct pci_driver *drv)
{
+ pci_remove_removeid_file(drv);
pci_remove_newid_file(drv);
driver_unregister(&drv->driver);
pci_free_dynids(drv);
@@ -973,6 +1095,7 @@ struct bus_type pci_bus_type = {
.remove = pci_device_remove,
.shutdown = pci_device_shutdown,
.dev_attrs = pci_dev_attrs,
+ .bus_attrs = pci_bus_attrs,
.pm = PCI_PM_OPS_PTR,
};
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index dfc4e0ddf24..e9a8706a640 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -219,6 +219,83 @@ msi_bus_store(struct device *dev, struct device_attribute *attr,
return count;
}
+#ifdef CONFIG_HOTPLUG
+static DEFINE_MUTEX(pci_remove_rescan_mutex);
+static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
+ size_t count)
+{
+ unsigned long val;
+ struct pci_bus *b = NULL;
+
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
+
+ if (val) {
+ mutex_lock(&pci_remove_rescan_mutex);
+ while ((b = pci_find_next_bus(b)) != NULL)
+ pci_rescan_bus(b);
+ mutex_unlock(&pci_remove_rescan_mutex);
+ }
+ return count;
+}
+
+struct bus_attribute pci_bus_attrs[] = {
+ __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, bus_rescan_store),
+ __ATTR_NULL
+};
+
+static ssize_t
+dev_rescan_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long val;
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
+
+ if (val) {
+ mutex_lock(&pci_remove_rescan_mutex);
+ pci_rescan_bus(pdev->bus);
+ mutex_unlock(&pci_remove_rescan_mutex);
+ }
+ return count;
+}
+
+static void remove_callback(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ mutex_lock(&pci_remove_rescan_mutex);
+ pci_remove_bus_device(pdev);
+ mutex_unlock(&pci_remove_rescan_mutex);
+}
+
+static ssize_t
+remove_store(struct device *dev, struct device_attribute *dummy,
+ const char *buf, size_t count)
+{
+ int ret = 0;
+ unsigned long val;
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ if (strict_strtoul(buf, 0, &val) < 0)
+ return -EINVAL;
+
+ if (pci_is_root_bus(pdev->bus))
+ return -EBUSY;
+
+ /* An attribute cannot be unregistered by one of its own methods,
+ * so we have to use this roundabout approach.
+ */
+ if (val)
+ ret = device_schedule_callback(dev, remove_callback);
+ if (ret)
+ count = ret;
+ return count;
+}
+#endif
+
struct device_attribute pci_dev_attrs[] = {
__ATTR_RO(resource),
__ATTR_RO(vendor),
@@ -237,10 +314,25 @@ struct device_attribute pci_dev_attrs[] = {
__ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
broken_parity_status_show,broken_parity_status_store),
__ATTR(msi_bus, 0644, msi_bus_show, msi_bus_store),
+#ifdef CONFIG_HOTPLUG
+ __ATTR(remove, (S_IWUSR|S_IWGRP), NULL, remove_store),
+ __ATTR(rescan, (S_IWUSR|S_IWGRP), NULL, dev_rescan_store),
+#endif
__ATTR_NULL,
};
static ssize_t
+boot_vga_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+
+ return sprintf(buf, "%u\n",
+ !!(pdev->resource[PCI_ROM_RESOURCE].flags &
+ IORESOURCE_ROM_SHADOW));
+}
+struct device_attribute vga_attr = __ATTR_RO(boot_vga);
+
+static ssize_t
pci_read_config(struct kobject *kobj, struct bin_attribute *bin_attr,
char *buf, loff_t off, size_t count)
{
@@ -493,6 +585,19 @@ pci_mmap_legacy_io(struct kobject *kobj, struct bin_attribute *attr,
}
/**
+ * pci_adjust_legacy_attr - adjustment of legacy file attributes
+ * @b: bus to create files under
+ * @mmap_type: I/O port or memory
+ *
+ * Stub implementation. Can be overridden by arch if necessary.
+ */
+void __weak
+pci_adjust_legacy_attr(struct pci_bus *b, enum pci_mmap_state mmap_type)
+{
+ return;
+}
+
+/**
* pci_create_legacy_files - create legacy I/O port and memory files
* @b: bus to create files under
*
@@ -518,6 +623,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_io->read = pci_read_legacy_io;
b->legacy_io->write = pci_write_legacy_io;
b->legacy_io->mmap = pci_mmap_legacy_io;
+ pci_adjust_legacy_attr(b, pci_mmap_io);
error = device_create_bin_file(&b->dev, b->legacy_io);
if (error)
goto legacy_io_err;
@@ -528,6 +634,7 @@ void pci_create_legacy_files(struct pci_bus *b)
b->legacy_mem->size = 1024*1024;
b->legacy_mem->attr.mode = S_IRUSR | S_IWUSR;
b->legacy_mem->mmap = pci_mmap_legacy_mem;
+ pci_adjust_legacy_attr(b, pci_mmap_mem);
error = device_create_bin_file(&b->dev, b->legacy_mem);
if (error)
goto legacy_mem_err;
@@ -719,8 +826,8 @@ static int pci_create_resource_files(struct pci_dev *pdev)
return 0;
}
#else /* !HAVE_PCI_MMAP */
-static inline int pci_create_resource_files(struct pci_dev *dev) { return 0; }
-static inline void pci_remove_resource_files(struct pci_dev *dev) { return; }
+int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
+void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
#endif /* HAVE_PCI_MMAP */
/**
@@ -884,18 +991,27 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev)
pdev->rom_attr = attr;
}
+ if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
+ retval = device_create_file(&pdev->dev, &vga_attr);
+ if (retval)
+ goto err_rom_file;
+ }
+
/* add platform-specific attributes */
retval = pcibios_add_platform_entries(pdev);
if (retval)
- goto err_rom_file;
+ goto err_vga_file;
/* add sysfs entries for various capabilities */
retval = pci_create_capabilities_sysfs(pdev);
if (retval)
- goto err_rom_file;
+ goto err_vga_file;
return 0;
+err_vga_file:
+ if ((pdev->class >> 8) == PCI_CLASS_DISPLAY_VGA)
+ device_remove_file(&pdev->dev, &vga_attr);
err_rom_file:
if (rom_size) {
sysfs_remove_bin_file(&pdev->dev.kobj, pdev->rom_attr);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 6d6120007af..445fb6f7ea3 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -20,6 +20,8 @@
#include <linux/pm_wakeup.h>
#include <linux/interrupt.h>
#include <asm/dma.h> /* isa_dma_bridge_buggy */
+#include <linux/device.h>
+#include <asm/setup.h>
#include "pci.h"
unsigned int pci_pm_d3_delay = PCI_PM_D3_WAIT;
@@ -426,7 +428,6 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* given PCI device
* @dev: PCI device to handle.
* @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
- * @wait: If 'true', wait for the device to change its power state
*
* RETURN VALUE:
* -EINVAL if the requested state is invalid.
@@ -435,12 +436,15 @@ static inline int platform_pci_sleep_wake(struct pci_dev *dev, bool enable)
* 0 if device already is in the requested state.
* 0 if device's power state has been successfully changed.
*/
-static int
-pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
+static int pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state)
{
u16 pmcsr;
bool need_restore = false;
+ /* Check if we're already there */
+ if (dev->current_state == state)
+ return 0;
+
if (!dev->pm_cap)
return -EIO;
@@ -451,10 +455,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
* 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 (dev->current_state == state) {
- /* we're already there */
- return 0;
- } else if (state != PCI_D0 && dev->current_state <= PCI_D3cold
+ if (state != PCI_D0 && dev->current_state <= PCI_D3cold
&& dev->current_state > state) {
dev_err(&dev->dev, "invalid power transition "
"(from state %d to %d)\n", dev->current_state, state);
@@ -481,10 +482,8 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
break;
case PCI_UNKNOWN: /* Boot-up */
if ((pmcsr & PCI_PM_CTRL_STATE_MASK) == PCI_D3hot
- && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET)) {
+ && !(pmcsr & PCI_PM_CTRL_NO_SOFT_RESET))
need_restore = true;
- wait = true;
- }
/* Fall-through: force to D0 */
default:
pmcsr = 0;
@@ -494,9 +493,6 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
/* enter specified state */
pci_write_config_word(dev, dev->pm_cap + PCI_PM_CTRL, pmcsr);
- if (!wait)
- return 0;
-
/* Mandatory power management transition delays */
/* see PCI PM 1.1 5.6.1 table 18 */
if (state == PCI_D3hot || dev->current_state == PCI_D3hot)
@@ -521,7 +517,7 @@ pci_raw_set_power_state(struct pci_dev *dev, pci_power_t state, bool wait)
if (need_restore)
pci_restore_bars(dev);
- if (wait && dev->bus->self)
+ if (dev->bus->self)
pcie_aspm_pm_state_change(dev->bus->self);
return 0;
@@ -546,11 +542,58 @@ void pci_update_current_state(struct pci_dev *dev, pci_power_t state)
}
/**
+ * pci_platform_power_transition - Use platform to change device power state
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ */
+static int pci_platform_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+ int error;
+
+ if (platform_pci_power_manageable(dev)) {
+ error = platform_pci_set_power_state(dev, state);
+ if (!error)
+ pci_update_current_state(dev, state);
+ } else {
+ error = -ENODEV;
+ /* Fall back to PCI_D0 if native PM is not supported */
+ pci_update_current_state(dev, PCI_D0);
+ }
+
+ return error;
+}
+
+/**
+ * __pci_start_power_transition - Start power transition of a PCI device
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ */
+static void __pci_start_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+ if (state == PCI_D0)
+ pci_platform_power_transition(dev, PCI_D0);
+}
+
+/**
+ * __pci_complete_power_transition - Complete power transition of a PCI device
+ * @dev: PCI device to handle.
+ * @state: State to put the device into.
+ *
+ * This function should not be called directly by device drivers.
+ */
+int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state)
+{
+ return state > PCI_D0 ?
+ pci_platform_power_transition(dev, state) : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(__pci_complete_power_transition);
+
+/**
* pci_set_power_state - Set the power state of a PCI device
* @dev: PCI device to handle.
* @state: PCI power state (D0, D1, D2, D3hot) to put the device into.
*
- * Transition a device to a new power state, using the platform formware and/or
+ * Transition a device to a new power state, using the platform firmware and/or
* the device's PCI PM registers.
*
* RETURN VALUE:
@@ -577,30 +620,21 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state)
*/
return 0;
- if (state == PCI_D0 && platform_pci_power_manageable(dev)) {
- /*
- * Allow the platform to change the state, for example via ACPI
- * _PR0, _PS0 and some such, but do not trust it.
- */
- int ret = platform_pci_set_power_state(dev, PCI_D0);
- if (!ret)
- pci_update_current_state(dev, PCI_D0);
- }
+ /* Check if we're already there */
+ if (dev->current_state == state)
+ return 0;
+
+ __pci_start_power_transition(dev, state);
+
/* This device is quirked not to be put into D3, so
don't put it in D3 */
if (state == PCI_D3hot && (dev->dev_flags & PCI_DEV_FLAGS_NO_D3))
return 0;
- error = pci_raw_set_power_state(dev, state, true);
+ error = pci_raw_set_power_state(dev, state);
- if (state > PCI_D0 && platform_pci_power_manageable(dev)) {
- /* Allow the platform to finalize the transition */
- int ret = platform_pci_set_power_state(dev, state);
- if (!ret) {
- pci_update_current_state(dev, state);
- error = 0;
- }
- }
+ if (!__pci_complete_power_transition(dev, state))
+ error = 0;
return error;
}
@@ -645,6 +679,8 @@ pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state)
EXPORT_SYMBOL(pci_choose_state);
+#define PCI_EXP_SAVE_REGS 7
+
static int pci_save_pcie_state(struct pci_dev *dev)
{
int pos, i = 0;
@@ -657,7 +693,7 @@ static int pci_save_pcie_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_EXP);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+ dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
cap = (u16 *)&save_state->data[0];
@@ -666,6 +702,9 @@ static int pci_save_pcie_state(struct pci_dev *dev)
pci_read_config_word(dev, pos + PCI_EXP_LNKCTL, &cap[i++]);
pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
+ pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
+ pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
+ pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
return 0;
}
@@ -686,6 +725,9 @@ static void pci_restore_pcie_state(struct pci_dev *dev)
pci_write_config_word(dev, pos + PCI_EXP_LNKCTL, cap[i++]);
pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
+ pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
+ pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
+ pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
}
@@ -700,7 +742,7 @@ static int pci_save_pcix_state(struct pci_dev *dev)
save_state = pci_find_saved_cap(dev, PCI_CAP_ID_PCIX);
if (!save_state) {
- dev_err(&dev->dev, "buffer not found in %s\n", __FUNCTION__);
+ dev_err(&dev->dev, "buffer not found in %s\n", __func__);
return -ENOMEM;
}
@@ -773,6 +815,7 @@ pci_restore_state(struct pci_dev *dev)
}
pci_restore_pcix_state(dev);
pci_restore_msi_state(dev);
+ pci_restore_iov_state(dev);
return 0;
}
@@ -1231,7 +1274,7 @@ int pci_prepare_to_sleep(struct pci_dev *dev)
if (target_state == PCI_POWER_ERROR)
return -EIO;
- pci_enable_wake(dev, target_state, true);
+ pci_enable_wake(dev, target_state, device_may_wakeup(&dev->dev));
error = pci_set_power_state(dev, target_state);
@@ -1369,7 +1412,8 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
{
int error;
- error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP, 4 * sizeof(u16));
+ error = pci_add_cap_save_buffer(dev, PCI_CAP_ID_EXP,
+ PCI_EXP_SAVE_REGS * sizeof(u16));
if (error)
dev_err(&dev->dev,
"unable to preallocate PCI Express save buffer\n");
@@ -1381,50 +1425,6 @@ void pci_allocate_cap_save_buffers(struct pci_dev *dev)
}
/**
- * pci_restore_standard_config - restore standard config registers of PCI device
- * @dev: PCI device to handle
- *
- * This function assumes that the device's configuration space is accessible.
- * If the device needs to be powered up, the function will wait for it to
- * change the state.
- */
-int pci_restore_standard_config(struct pci_dev *dev)
-{
- pci_power_t prev_state;
- int error;
-
- pci_update_current_state(dev, PCI_D0);
-
- prev_state = dev->current_state;
- if (prev_state == PCI_D0)
- goto Restore;
-
- error = pci_raw_set_power_state(dev, PCI_D0, false);
- if (error)
- return error;
-
- /*
- * This assumes that we won't get a bus in B2 or B3 from the BIOS, but
- * we've made this assumption forever and it appears to be universally
- * satisfied.
- */
- switch(prev_state) {
- case PCI_D3cold:
- case PCI_D3hot:
- mdelay(pci_pm_d3_delay);
- break;
- case PCI_D2:
- udelay(PCI_PM_D2_DELAY);
- break;
- }
-
- pci_update_current_state(dev, PCI_D0);
-
- Restore:
- return dev->state_saved ? pci_restore_state(dev) : 0;
-}
-
-/**
* pci_enable_ari - enable ARI forwarding if hardware support it
* @dev: the PCI device
*/
@@ -1484,7 +1484,7 @@ pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge)
if (!pin)
return -1;
- while (dev->bus->self) {
+ while (dev->bus->parent) {
pin = pci_swizzle_interrupt_pin(dev, pin);
dev = dev->bus->self;
}
@@ -1504,7 +1504,7 @@ u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp)
{
u8 pin = *pinp;
- while (dev->bus->self) {
+ while (dev->bus->parent) {
pin = pci_swizzle_interrupt_pin(dev, pin);
dev = dev->bus->self;
}
@@ -2028,18 +2028,24 @@ static int __pcie_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */
+ pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto transaction_done;
+
msleep(100);
pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND) {
- dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
+ if (!(status & PCI_EXP_DEVSTA_TRPND))
+ goto transaction_done;
+
+ dev_info(&dev->dev, "Busy after 100ms while trying to reset; "
"sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
- if (status & PCI_EXP_DEVSTA_TRPND)
- dev_info(&dev->dev, "Still busy after 1s; "
+ ssleep(1);
+ pci_read_config_word(dev, exppos + PCI_EXP_DEVSTA, &status);
+ if (status & PCI_EXP_DEVSTA_TRPND)
+ dev_info(&dev->dev, "Still busy after 1s; "
"proceeding with reset anyway\n");
- }
+transaction_done:
pci_write_config_word(dev, exppos + PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_BCR_FLR);
mdelay(100);
@@ -2066,18 +2072,24 @@ static int __pci_af_flr(struct pci_dev *dev, int probe)
pci_block_user_cfg_access(dev);
/* Wait for Transaction Pending bit clean */
+ pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+ if (!(status & PCI_AF_STATUS_TP))
+ goto transaction_done;
+
msleep(100);
pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP) {
- dev_info(&dev->dev, "Busy after 100ms while trying to"
- " reset; sleeping for 1 second\n");
- ssleep(1);
- pci_read_config_byte(dev,
- cappos + PCI_AF_STATUS, &status);
- if (status & PCI_AF_STATUS_TP)
- dev_info(&dev->dev, "Still busy after 1s; "
- "proceeding with reset anyway\n");
- }
+ if (!(status & PCI_AF_STATUS_TP))
+ goto transaction_done;
+
+ dev_info(&dev->dev, "Busy after 100ms while trying to"
+ " reset; sleeping for 1 second\n");
+ ssleep(1);
+ pci_read_config_byte(dev, cappos + PCI_AF_STATUS, &status);
+ if (status & PCI_AF_STATUS_TP)
+ dev_info(&dev->dev, "Still busy after 1s; "
+ "proceeding with reset anyway\n");
+
+transaction_done:
pci_write_config_byte(dev, cappos + PCI_AF_CTRL, PCI_AF_CTRL_FLR);
mdelay(100);
@@ -2346,18 +2358,140 @@ int pci_select_bars(struct pci_dev *dev, unsigned long flags)
*/
int pci_resource_bar(struct pci_dev *dev, int resno, enum pci_bar_type *type)
{
+ int reg;
+
if (resno < PCI_ROM_RESOURCE) {
*type = pci_bar_unknown;
return PCI_BASE_ADDRESS_0 + 4 * resno;
} else if (resno == PCI_ROM_RESOURCE) {
*type = pci_bar_mem32;
return dev->rom_base_reg;
+ } else if (resno < PCI_BRIDGE_RESOURCES) {
+ /* device specific resource */
+ reg = pci_iov_resource_bar(dev, resno, type);
+ if (reg)
+ return reg;
}
dev_err(&dev->dev, "BAR: invalid resource #%d\n", resno);
return 0;
}
+#define RESOURCE_ALIGNMENT_PARAM_SIZE COMMAND_LINE_SIZE
+static char resource_alignment_param[RESOURCE_ALIGNMENT_PARAM_SIZE] = {0};
+spinlock_t resource_alignment_lock = SPIN_LOCK_UNLOCKED;
+
+/**
+ * pci_specified_resource_alignment - get resource alignment specified by user.
+ * @dev: the PCI device to get
+ *
+ * RETURNS: Resource alignment if it is specified.
+ * Zero if it is not specified.
+ */
+resource_size_t pci_specified_resource_alignment(struct pci_dev *dev)
+{
+ int seg, bus, slot, func, align_order, count;
+ resource_size_t align = 0;
+ char *p;
+
+ spin_lock(&resource_alignment_lock);
+ p = resource_alignment_param;
+ while (*p) {
+ count = 0;
+ if (sscanf(p, "%d%n", &align_order, &count) == 1 &&
+ p[count] == '@') {
+ p += count + 1;
+ } else {
+ align_order = -1;
+ }
+ if (sscanf(p, "%x:%x:%x.%x%n",
+ &seg, &bus, &slot, &func, &count) != 4) {
+ seg = 0;
+ if (sscanf(p, "%x:%x.%x%n",
+ &bus, &slot, &func, &count) != 3) {
+ /* Invalid format */
+ printk(KERN_ERR "PCI: Can't parse resource_alignment parameter: %s\n",
+ p);
+ break;
+ }
+ }
+ p += count;
+ if (seg == pci_domain_nr(dev->bus) &&
+ bus == dev->bus->number &&
+ slot == PCI_SLOT(dev->devfn) &&
+ func == PCI_FUNC(dev->devfn)) {
+ if (align_order == -1) {
+ align = PAGE_SIZE;
+ } else {
+ align = 1 << align_order;
+ }
+ /* Found */
+ break;
+ }
+ if (*p != ';' && *p != ',') {
+ /* End of param or invalid format */
+ break;
+ }
+ p++;
+ }
+ spin_unlock(&resource_alignment_lock);
+ return align;
+}
+
+/**
+ * pci_is_reassigndev - check if specified PCI is target device to reassign
+ * @dev: the PCI device to check
+ *
+ * RETURNS: non-zero for PCI device is a target device to reassign,
+ * or zero is not.
+ */
+int pci_is_reassigndev(struct pci_dev *dev)
+{
+ return (pci_specified_resource_alignment(dev) != 0);
+}
+
+ssize_t pci_set_resource_alignment_param(const char *buf, size_t count)
+{
+ if (count > RESOURCE_ALIGNMENT_PARAM_SIZE - 1)
+ count = RESOURCE_ALIGNMENT_PARAM_SIZE - 1;
+ spin_lock(&resource_alignment_lock);
+ strncpy(resource_alignment_param, buf, count);
+ resource_alignment_param[count] = '\0';
+ spin_unlock(&resource_alignment_lock);
+ return count;
+}
+
+ssize_t pci_get_resource_alignment_param(char *buf, size_t size)
+{
+ size_t count;
+ spin_lock(&resource_alignment_lock);
+ count = snprintf(buf, size, "%s", resource_alignment_param);
+ spin_unlock(&resource_alignment_lock);
+ return count;
+}
+
+static ssize_t pci_resource_alignment_show(struct bus_type *bus, char *buf)
+{
+ return pci_get_resource_alignment_param(buf, PAGE_SIZE);
+}
+
+static ssize_t pci_resource_alignment_store(struct bus_type *bus,
+ const char *buf, size_t count)
+{
+ return pci_set_resource_alignment_param(buf, count);
+}
+
+BUS_ATTR(resource_alignment, 0644, pci_resource_alignment_show,
+ pci_resource_alignment_store);
+
+static int __init pci_resource_alignment_sysfs_init(void)
+{
+ return bus_create_file(&pci_bus_type,
+ &bus_attr_resource_alignment);
+}
+
+late_initcall(pci_resource_alignment_sysfs_init);
+
static void __devinit pci_no_domains(void)
{
#ifdef CONFIG_PCI_DOMAINS
@@ -2406,6 +2540,9 @@ static int __init pci_setup(char *str)
pci_cardbus_io_size = memparse(str + 9, &str);
} else if (!strncmp(str, "cbmemsize=", 10)) {
pci_cardbus_mem_size = memparse(str + 10, &str);
+ } else if (!strncmp(str, "resource_alignment=", 19)) {
+ pci_set_resource_alignment_param(str + 19,
+ strlen(str + 19));
} else {
printk(KERN_ERR "PCI: Unknown option `%s'\n",
str);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 07c0aa5275e..d03f6b99f29 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -1,6 +1,8 @@
#ifndef DRIVERS_PCI_H
#define DRIVERS_PCI_H
+#include <linux/workqueue.h>
+
#define PCI_CFG_SPACE_SIZE 256
#define PCI_CFG_SPACE_EXP_SIZE 4096
@@ -49,7 +51,6 @@ extern void pci_disable_enabled_device(struct pci_dev *dev);
extern void pci_pm_init(struct pci_dev *dev);
extern void platform_pci_wakeup_init(struct pci_dev *dev);
extern void pci_allocate_cap_save_buffers(struct pci_dev *dev);
-extern int pci_restore_standard_config(struct pci_dev *dev);
static inline bool pci_is_bridge(struct pci_dev *pci_dev)
{
@@ -136,6 +137,12 @@ extern int pcie_mch_quirk;
extern struct device_attribute pci_dev_attrs[];
extern struct device_attribute dev_attr_cpuaffinity;
extern struct device_attribute dev_attr_cpulistaffinity;
+#ifdef CONFIG_HOTPLUG
+extern struct bus_attribute pci_bus_attrs[];
+#else
+#define pci_bus_attrs NULL
+#endif
+
/**
* pci_match_one_device - Tell if a PCI device structure has a matching
@@ -178,6 +185,7 @@ enum pci_bar_type {
pci_bar_mem64, /* A 64-bit memory BAR */
};
+extern int pci_setup_device(struct pci_dev *dev);
extern int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
struct resource *res, unsigned int reg);
extern int pci_resource_bar(struct pci_dev *dev, int resno,
@@ -195,4 +203,60 @@ static inline int pci_ari_enabled(struct pci_bus *bus)
return bus->self && bus->self->ari_enabled;
}
+#ifdef CONFIG_PCI_QUIRKS
+extern int pci_is_reassigndev(struct pci_dev *dev);
+resource_size_t pci_specified_resource_alignment(struct pci_dev *dev);
+extern void pci_disable_bridge_window(struct pci_dev *dev);
+#endif
+
+/* Single Root I/O Virtualization */
+struct pci_sriov {
+ int pos; /* capability position */
+ int nres; /* number of resources */
+ u32 cap; /* SR-IOV Capabilities */
+ u16 ctrl; /* SR-IOV Control */
+ u16 total; /* total VFs associated with the PF */
+ u16 initial; /* initial VFs associated with the PF */
+ u16 nr_virtfn; /* number of VFs available */
+ u16 offset; /* first VF Routing ID offset */
+ u16 stride; /* following VF stride */
+ u32 pgsz; /* page size for BAR alignment */
+ u8 link; /* Function Dependency Link */
+ struct pci_dev *dev; /* lowest numbered PF */
+ struct pci_dev *self; /* this PF */
+ struct mutex lock; /* lock for VF bus */
+ struct work_struct mtask; /* VF Migration task */
+ u8 __iomem *mstate; /* VF Migration State Array */
+};
+
+#ifdef CONFIG_PCI_IOV
+extern int pci_iov_init(struct pci_dev *dev);
+extern void pci_iov_release(struct pci_dev *dev);
+extern int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+ enum pci_bar_type *type);
+extern void pci_restore_iov_state(struct pci_dev *dev);
+extern int pci_iov_bus_range(struct pci_bus *bus);
+#else
+static inline int pci_iov_init(struct pci_dev *dev)
+{
+ return -ENODEV;
+}
+static inline void pci_iov_release(struct pci_dev *dev)
+
+{
+}
+static inline int pci_iov_resource_bar(struct pci_dev *dev, int resno,
+ enum pci_bar_type *type)
+{
+ return 0;
+}
+static inline void pci_restore_iov_state(struct pci_dev *dev)
+{
+}
+static inline int pci_iov_bus_range(struct pci_bus *bus)
+{
+ return 0;
+}
+#endif /* CONFIG_PCI_IOV */
+
#endif /* DRIVERS_PCI_H */
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index e390707661d..32ade5af927 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -38,30 +38,13 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
-static int __devinit aer_probe (struct pcie_device *dev,
- const struct pcie_port_service_id *id );
+static int __devinit aer_probe (struct pcie_device *dev);
static void aer_remove(struct pcie_device *dev);
-static int aer_suspend(struct pcie_device *dev, pm_message_t state)
-{return 0;}
-static int aer_resume(struct pcie_device *dev) {return 0;}
static pci_ers_result_t aer_error_detected(struct pci_dev *dev,
enum pci_channel_state error);
static void aer_error_resume(struct pci_dev *dev);
static pci_ers_result_t aer_root_reset(struct pci_dev *dev);
-/*
- * PCI Express bus's AER Root service driver data structure
- */
-static struct pcie_port_service_id aer_id[] = {
- {
- .vendor = PCI_ANY_ID,
- .device = PCI_ANY_ID,
- .port_type = PCIE_RC_PORT,
- .service_type = PCIE_PORT_SERVICE_AER,
- },
- { /* end: all zeroes */ }
-};
-
static struct pci_error_handlers aer_error_handlers = {
.error_detected = aer_error_detected,
.resume = aer_error_resume,
@@ -69,14 +52,12 @@ static struct pci_error_handlers aer_error_handlers = {
static struct pcie_port_service_driver aerdriver = {
.name = "aer",
- .id_table = &aer_id[0],
+ .port_type = PCIE_ANY_PORT,
+ .service = PCIE_PORT_SERVICE_AER,
.probe = aer_probe,
.remove = aer_remove,
- .suspend = aer_suspend,
- .resume = aer_resume,
-
.err_handler = &aer_error_handlers,
.reset_link = aer_root_reset,
@@ -207,8 +188,7 @@ static void aer_remove(struct pcie_device *dev)
*
* Invoked when PCI Express bus loads AER service driver.
**/
-static int __devinit aer_probe (struct pcie_device *dev,
- const struct pcie_port_service_id *id )
+static int __devinit aer_probe (struct pcie_device *dev)
{
int status;
struct aer_rpc *rpc;
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index ebce26c3704..8edb2f300e8 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -38,7 +38,7 @@ int aer_osc_setup(struct pcie_device *pciedev)
handle = acpi_find_root_bridge_handle(pdev);
if (handle) {
- status = pci_osc_control_set(handle,
+ status = acpi_pci_osc_control_set(handle,
OSC_PCI_EXPRESS_AER_CONTROL |
OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
}
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 38257500738..307452f3003 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -351,21 +351,21 @@ static int find_aer_service_iter(struct device *device, void *data)
{
struct device_driver *driver;
struct pcie_port_service_driver *service_driver;
- struct pcie_device *pcie_dev;
struct find_aer_service_data *result;
result = (struct find_aer_service_data *) data;
if (device->bus == &pcie_port_bus_type) {
- pcie_dev = to_pcie_device(device);
- if (pcie_dev->id.port_type == PCIE_SW_DOWNSTREAM_PORT)
+ struct pcie_port_data *port_data;
+
+ port_data = pci_get_drvdata(to_pcie_device(device)->port);
+ if (port_data->port_type == PCIE_SW_DOWNSTREAM_PORT)
result->is_downstream = 1;
driver = device->driver;
if (driver) {
service_driver = to_service_driver(driver);
- if (service_driver->id_table->service_type ==
- PCIE_PORT_SERVICE_AER) {
+ if (service_driver->service == PCIE_PORT_SERVICE_AER) {
result->aer_driver = service_driver;
return 1;
}
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 2529f3f2ea5..17ad53868f9 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -25,19 +25,21 @@
#define PCIE_CAPABILITIES_REG 0x2
#define PCIE_SLOT_CAPABILITIES_REG 0x14
#define PCIE_PORT_DEVICE_MAXSERVICES 4
+#define PCIE_PORT_MSI_VECTOR_MASK 0x1f
+/*
+ * According to the PCI Express Base Specification 2.0, the indices of the MSI-X
+ * table entires used by port services must not exceed 31
+ */
+#define PCIE_PORT_MAX_MSIX_ENTRIES 32
#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] */
-};
-
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);
#ifdef CONFIG_PM
-extern int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state);
-extern int pcie_port_device_resume(struct pci_dev *dev);
+extern int pcie_port_device_suspend(struct device *dev);
+extern int pcie_port_device_resume(struct device *dev);
#endif
extern void pcie_port_device_remove(struct pci_dev *dev);
extern int __must_check pcie_port_bus_register(void);
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c
index eec89b767f9..ef3a4eeaebb 100644
--- a/drivers/pci/pcie/portdrv_bus.c
+++ b/drivers/pci/pcie/portdrv_bus.c
@@ -26,20 +26,22 @@ EXPORT_SYMBOL_GPL(pcie_port_bus_type);
static int pcie_port_bus_match(struct device *dev, struct device_driver *drv)
{
struct pcie_device *pciedev;
+ struct pcie_port_data *port_data;
struct pcie_port_service_driver *driver;
if (drv->bus != &pcie_port_bus_type || dev->bus != &pcie_port_bus_type)
return 0;
-
+
pciedev = to_pcie_device(dev);
driver = to_service_driver(drv);
- if ( (driver->id_table->vendor != PCI_ANY_ID &&
- driver->id_table->vendor != pciedev->id.vendor) ||
- (driver->id_table->device != PCI_ANY_ID &&
- driver->id_table->device != pciedev->id.device) ||
- (driver->id_table->port_type != PCIE_ANY_PORT &&
- driver->id_table->port_type != pciedev->id.port_type) ||
- driver->id_table->service_type != pciedev->id.service_type )
+
+ if (driver->service != pciedev->service)
+ return 0;
+
+ port_data = pci_get_drvdata(pciedev->port);
+
+ if (driver->port_type != PCIE_ANY_PORT
+ && driver->port_type != port_data->port_type)
return 0;
return 1;
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index 8b3f8c18032..e3998250386 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -15,10 +15,9 @@
#include <linux/slab.h>
#include <linux/pcieport_if.h>
+#include "../pci.h"
#include "portdrv.h"
-extern int pcie_mch_quirk; /* MSI-quirk Indicator */
-
/**
* release_pcie_device - free PCI Express port service device structure
* @dev: Port service device to release
@@ -31,26 +30,150 @@ static void release_pcie_device(struct device *dev)
kfree(to_pcie_device(dev));
}
-static int is_msi_quirked(struct pci_dev *dev)
+/**
+ * pcie_port_msix_add_entry - add entry to given array of MSI-X entries
+ * @entries: Array of MSI-X entries
+ * @new_entry: Index of the entry to add to the array
+ * @nr_entries: Number of entries aleady in the array
+ *
+ * Return value: Position of the added entry in the array
+ */
+static int pcie_port_msix_add_entry(
+ struct msix_entry *entries, int new_entry, int nr_entries)
{
- int port_type, quirk = 0;
+ int j;
+
+ for (j = 0; j < nr_entries; j++)
+ if (entries[j].entry == new_entry)
+ return j;
+
+ entries[j].entry = new_entry;
+ return j;
+}
+
+/**
+ * pcie_port_enable_msix - try to set up MSI-X as interrupt mode for given port
+ * @dev: PCI Express port to handle
+ * @vectors: Array of interrupt vectors to populate
+ * @mask: Bitmask of port capabilities returned by get_port_device_capability()
+ *
+ * Return value: 0 on success, error code on failure
+ */
+static int pcie_port_enable_msix(struct pci_dev *dev, int *vectors, int mask)
+{
+ struct msix_entry *msix_entries;
+ int idx[PCIE_PORT_DEVICE_MAXSERVICES];
+ int nr_entries, status, pos, i, nvec;
u16 reg16;
+ u32 reg32;
- pci_read_config_word(dev,
- pci_find_capability(dev, PCI_CAP_ID_EXP) +
- PCIE_CAPABILITIES_REG, &reg16);
- port_type = (reg16 >> 4) & PORT_TYPE_MASK;
- switch(port_type) {
- case PCIE_RC_PORT:
- if (pcie_mch_quirk == 1)
- quirk = 1;
- break;
- case PCIE_SW_UPSTREAM_PORT:
- case PCIE_SW_DOWNSTREAM_PORT:
- default:
- break;
+ nr_entries = pci_msix_table_size(dev);
+ if (!nr_entries)
+ return -EINVAL;
+ if (nr_entries > PCIE_PORT_MAX_MSIX_ENTRIES)
+ nr_entries = PCIE_PORT_MAX_MSIX_ENTRIES;
+
+ msix_entries = kzalloc(sizeof(*msix_entries) * nr_entries, GFP_KERNEL);
+ if (!msix_entries)
+ return -ENOMEM;
+
+ /*
+ * Allocate as many entries as the port wants, so that we can check
+ * which of them will be useful. Moreover, if nr_entries is correctly
+ * equal to the number of entries this port actually uses, we'll happily
+ * go through without any tricks.
+ */
+ for (i = 0; i < nr_entries; i++)
+ msix_entries[i].entry = i;
+
+ status = pci_enable_msix(dev, msix_entries, nr_entries);
+ if (status)
+ goto Exit;
+
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ idx[i] = -1;
+ status = -EIO;
+ nvec = 0;
+
+ if (mask & (PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP)) {
+ int entry;
+
+ /*
+ * The code below follows the PCI Express Base Specification 2.0
+ * stating in Section 6.1.6 that "PME and Hot-Plug Event
+ * interrupts (when both are implemented) always share the same
+ * MSI or MSI-X vector, as indicated by the Interrupt Message
+ * Number field in the PCI Express Capabilities register", where
+ * according to Section 7.8.2 of the specification "For MSI-X,
+ * the value in this field indicates which MSI-X Table entry is
+ * used to generate the interrupt message."
+ */
+ pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
+ pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);
+ entry = (reg16 >> 9) & PCIE_PORT_MSI_VECTOR_MASK;
+ if (entry >= nr_entries)
+ goto Error;
+
+ i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+ if (i == nvec)
+ nvec++;
+
+ idx[PCIE_PORT_SERVICE_PME_SHIFT] = i;
+ idx[PCIE_PORT_SERVICE_HP_SHIFT] = i;
+ }
+
+ if (mask & PCIE_PORT_SERVICE_AER) {
+ int entry;
+
+ /*
+ * The code below follows Section 7.10.10 of the PCI Express
+ * Base Specification 2.0 stating that bits 31-27 of the Root
+ * Error Status Register contain a value indicating which of the
+ * MSI/MSI-X vectors assigned to the port is going to be used
+ * for AER, where "For MSI-X, the value in this register
+ * indicates which MSI-X Table entry is used to generate the
+ * interrupt message."
+ */
+ pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+ pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &reg32);
+ entry = reg32 >> 27;
+ if (entry >= nr_entries)
+ goto Error;
+
+ i = pcie_port_msix_add_entry(msix_entries, entry, nvec);
+ if (i == nvec)
+ nvec++;
+
+ idx[PCIE_PORT_SERVICE_AER_SHIFT] = i;
}
- return quirk;
+
+ /*
+ * If nvec is equal to the allocated number of entries, we can just use
+ * what we have. Otherwise, the port has some extra entries not for the
+ * services we know and we need to work around that.
+ */
+ if (nvec == nr_entries) {
+ status = 0;
+ } else {
+ /* Drop the temporary MSI-X setup */
+ pci_disable_msix(dev);
+
+ /* Now allocate the MSI-X vectors for real */
+ status = pci_enable_msix(dev, msix_entries, nvec);
+ if (status)
+ goto Exit;
+ }
+
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ vectors[i] = idx[i] >= 0 ? msix_entries[idx[i]].vector : -1;
+
+ Exit:
+ kfree(msix_entries);
+ return status;
+
+ Error:
+ pci_disable_msix(dev);
+ goto Exit;
}
/**
@@ -64,47 +187,32 @@ static int is_msi_quirked(struct pci_dev *dev)
*/
static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask)
{
- int i, pos, nvec, status = -EINVAL;
- int interrupt_mode = PCIE_PORT_INTx_MODE;
+ struct pcie_port_data *port_data = pci_get_drvdata(dev);
+ int irq, interrupt_mode = PCIE_PORT_NO_IRQ;
+ int i;
- /* Set INTx as default */
- for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
- if (mask & (1 << i))
- nvec++;
- vectors[i] = dev->irq;
- }
-
/* Check MSI quirk */
- if (is_msi_quirked(dev))
- return interrupt_mode;
-
- /* Select MSI-X over MSI if supported */
- pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
- if (pos) {
- struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] =
- {{0, 0}, {0, 1}, {0, 2}, {0, 3}};
- status = pci_enable_msix(dev, msix_entries, nvec);
- if (!status) {
- int j = 0;
-
- interrupt_mode = PCIE_PORT_MSIX_MODE;
- for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
- if (mask & (1 << i))
- vectors[i] = msix_entries[j++].vector;
- }
- }
- }
- if (status) {
- pos = pci_find_capability(dev, PCI_CAP_ID_MSI);
- if (pos) {
- status = pci_enable_msi(dev);
- if (!status) {
- interrupt_mode = PCIE_PORT_MSI_MODE;
- for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)
- vectors[i] = dev->irq;
- }
- }
- }
+ if (port_data->port_type == PCIE_RC_PORT && pcie_mch_quirk)
+ goto Fallback;
+
+ /* Try to use MSI-X if supported */
+ if (!pcie_port_enable_msix(dev, vectors, mask))
+ return PCIE_PORT_MSIX_MODE;
+
+ /* We're not going to use MSI-X, so try MSI and fall back to INTx */
+ if (!pci_enable_msi(dev))
+ interrupt_mode = PCIE_PORT_MSI_MODE;
+
+ Fallback:
+ if (interrupt_mode == PCIE_PORT_NO_IRQ && dev->pin)
+ interrupt_mode = PCIE_PORT_INTx_MODE;
+
+ irq = interrupt_mode != PCIE_PORT_NO_IRQ ? dev->irq : -1;
+ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++)
+ vectors[i] = irq;
+
+ vectors[PCIE_PORT_SERVICE_VC_SHIFT] = -1;
+
return interrupt_mode;
}
@@ -132,13 +240,11 @@ static int get_port_device_capability(struct pci_dev *dev)
pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);
if (reg32 & SLOT_HP_CAPABLE_MASK)
services |= PCIE_PORT_SERVICE_HP;
- }
- /* PME Capable - root port capability */
- if (((reg16 >> 4) & PORT_TYPE_MASK) == PCIE_RC_PORT)
- services |= PCIE_PORT_SERVICE_PME;
-
+ }
+ /* AER capable */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR))
services |= PCIE_PORT_SERVICE_AER;
+ /* VC support */
if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
services |= PCIE_PORT_SERVICE_VC;
@@ -152,20 +258,17 @@ static int get_port_device_capability(struct pci_dev *dev)
* @port_type: Type of the port
* @service_type: Type of service to associate with the service device
* @irq: Interrupt vector to associate with the service device
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
*/
static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
- int port_type, int service_type, int irq, int irq_mode)
+ int service_type, int irq)
{
+ struct pcie_port_data *port_data = pci_get_drvdata(parent);
struct device *device;
+ int port_type = port_data->port_type;
dev->port = parent;
- dev->interrupt_mode = irq_mode;
dev->irq = irq;
- dev->id.vendor = parent->vendor;
- dev->id.device = parent->device;
- dev->id.port_type = port_type;
- dev->id.service_type = (1 << service_type);
+ dev->service = service_type;
/* Initialize generic device interface */
device = &dev->device;
@@ -185,10 +288,9 @@ static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev,
* @port_type: Type of the port
* @service_type: Type of service to associate with the service device
* @irq: Interrupt vector to associate with the service device
- * @irq_mode: Interrupt mode of the service (INTx, MSI-X, MSI)
*/
static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
- int port_type, int service_type, int irq, int irq_mode)
+ int service_type, int irq)
{
struct pcie_device *device;
@@ -196,7 +298,7 @@ static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,
if (!device)
return NULL;
- pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);
+ pcie_device_init(parent, device, service_type, irq);
return device;
}
@@ -230,63 +332,90 @@ int pcie_port_device_probe(struct pci_dev *dev)
*/
int pcie_port_device_register(struct pci_dev *dev)
{
- struct pcie_port_device_ext *p_ext;
- int status, type, capabilities, irq_mode, i;
+ struct pcie_port_data *port_data;
+ int status, capabilities, irq_mode, i, nr_serv;
int vectors[PCIE_PORT_DEVICE_MAXSERVICES];
u16 reg16;
- /* Allocate port device extension */
- if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))
+ port_data = kzalloc(sizeof(*port_data), GFP_KERNEL);
+ if (!port_data)
return -ENOMEM;
-
- pci_set_drvdata(dev, p_ext);
+ pci_set_drvdata(dev, port_data);
/* Get port type */
pci_read_config_word(dev,
pci_find_capability(dev, PCI_CAP_ID_EXP) +
PCIE_CAPABILITIES_REG, &reg16);
- type = (reg16 >> 4) & PORT_TYPE_MASK;
+ port_data->port_type = (reg16 >> 4) & PORT_TYPE_MASK;
- /* Now get port services */
capabilities = get_port_device_capability(dev);
+ /* Root ports are capable of generating PME too */
+ if (port_data->port_type == PCIE_RC_PORT)
+ capabilities |= PCIE_PORT_SERVICE_PME;
+
irq_mode = assign_interrupt_mode(dev, vectors, capabilities);
- p_ext->interrupt_mode = irq_mode;
+ if (irq_mode == PCIE_PORT_NO_IRQ) {
+ /*
+ * Don't use service devices that require interrupts if there is
+ * no way to generate them.
+ */
+ if (!(capabilities & PCIE_PORT_SERVICE_VC)) {
+ status = -ENODEV;
+ goto Error;
+ }
+ capabilities = PCIE_PORT_SERVICE_VC;
+ }
+ port_data->port_irq_mode = irq_mode;
+
+ status = pci_enable_device(dev);
+ if (status)
+ goto Error;
+ pci_set_master(dev);
/* Allocate child services if any */
- for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
+ for (i = 0, nr_serv = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {
struct pcie_device *child;
+ int service = 1 << i;
+
+ if (!(capabilities & service))
+ continue;
- if (capabilities & (1 << i)) {
- child = alloc_pcie_device(
- dev, /* parent */
- type, /* port type */
- i, /* service type */
- vectors[i], /* irq */
- irq_mode /* interrupt mode */);
- if (child) {
- status = device_register(&child->device);
- if (status) {
- kfree(child);
- continue;
- }
- get_device(&child->device);
- }
+ child = alloc_pcie_device(dev, service, vectors[i]);
+ if (!child)
+ continue;
+
+ status = device_register(&child->device);
+ if (status) {
+ kfree(child);
+ continue;
}
+
+ get_device(&child->device);
+ nr_serv++;
+ }
+ if (!nr_serv) {
+ pci_disable_device(dev);
+ status = -ENODEV;
+ goto Error;
}
+
return 0;
+
+ Error:
+ kfree(port_data);
+ return status;
}
#ifdef CONFIG_PM
static int suspend_iter(struct device *dev, void *data)
{
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);
+ service_driver->suspend(to_pcie_device(dev));
}
return 0;
}
@@ -294,11 +423,10 @@ static int suspend_iter(struct device *dev, void *data)
/**
* pcie_port_device_suspend - suspend port services associated with a PCIe port
* @dev: PCI Express port to handle
- * @state: Representation of system power management transition in progress
*/
-int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state)
+int pcie_port_device_suspend(struct device *dev)
{
- return device_for_each_child(&dev->dev, &state, suspend_iter);
+ return device_for_each_child(dev, NULL, suspend_iter);
}
static int resume_iter(struct device *dev, void *data)
@@ -318,24 +446,17 @@ static int resume_iter(struct device *dev, void *data)
* pcie_port_device_suspend - resume port services associated with a PCIe port
* @dev: PCI Express port to handle
*/
-int pcie_port_device_resume(struct pci_dev *dev)
+int pcie_port_device_resume(struct device *dev)
{
- return device_for_each_child(&dev->dev, NULL, resume_iter);
+ return device_for_each_child(dev, NULL, resume_iter);
}
-#endif
+#endif /* PM */
static int remove_iter(struct device *dev, void *data)
{
- struct pcie_port_service_driver *service_driver;
-
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));
- }
- *(unsigned long*)data = (unsigned long)dev;
- return 1;
+ put_device(dev);
+ device_unregister(dev);
}
return 0;
}
@@ -349,25 +470,21 @@ static int remove_iter(struct device *dev, void *data)
*/
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;
+ struct pcie_port_data *port_data = pci_get_drvdata(dev);
- 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)
+ device_for_each_child(&dev->dev, NULL, remove_iter);
+ pci_disable_device(dev);
+
+ switch (port_data->port_irq_mode) {
+ case PCIE_PORT_MSIX_MODE:
pci_disable_msix(dev);
- else if (interrupt_mode == PCIE_PORT_MSI_MODE)
+ break;
+ case PCIE_PORT_MSI_MODE:
pci_disable_msi(dev);
+ break;
+ }
+
+ kfree(port_data);
}
/**
@@ -392,7 +509,7 @@ static int pcie_port_probe_service(struct device *dev)
return -ENODEV;
pciedev = to_pcie_device(dev);
- status = driver->probe(pciedev, driver->id_table);
+ status = driver->probe(pciedev);
if (!status) {
dev_printk(KERN_DEBUG, dev, "service driver %s loaded\n",
driver->name);
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 5ea566e20b3..b924e2463f8 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -32,11 +32,6 @@ MODULE_LICENSE("GPL");
/* global data */
static const char device_name[] = "pcieport-driver";
-static int pcie_portdrv_save_config(struct pci_dev *dev)
-{
- return pci_save_state(dev);
-}
-
static int pcie_portdrv_restore_config(struct pci_dev *dev)
{
int retval;
@@ -49,21 +44,21 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev)
}
#ifdef CONFIG_PM
-static int pcie_portdrv_suspend(struct pci_dev *dev, pm_message_t state)
-{
- return pcie_port_device_suspend(dev, state);
+static struct dev_pm_ops pcie_portdrv_pm_ops = {
+ .suspend = pcie_port_device_suspend,
+ .resume = pcie_port_device_resume,
+ .freeze = pcie_port_device_suspend,
+ .thaw = pcie_port_device_resume,
+ .poweroff = pcie_port_device_suspend,
+ .restore = pcie_port_device_resume,
+};
-}
+#define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)
-static int pcie_portdrv_resume(struct pci_dev *dev)
-{
- pci_set_master(dev);
- return pcie_port_device_resume(dev);
-}
-#else
-#define pcie_portdrv_suspend NULL
-#define pcie_portdrv_resume NULL
-#endif
+#else /* !PM */
+
+#define PCIE_PORTDRV_PM_OPS NULL
+#endif /* !PM */
/*
* pcie_portdrv_probe - Probe PCI-Express port devices
@@ -82,20 +77,15 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
if (status)
return status;
- if (pci_enable_device(dev) < 0)
- return -ENODEV;
-
- pci_set_master(dev);
if (!dev->irq && dev->pin) {
dev_warn(&dev->dev, "device [%04x:%04x] has invalid IRQ; "
"check vendor BIOS\n", dev->vendor, dev->device);
}
- if (pcie_port_device_register(dev)) {
- pci_disable_device(dev);
- return -ENOMEM;
- }
+ status = pcie_port_device_register(dev);
+ if (status)
+ return status;
- pcie_portdrv_save_config(dev);
+ pci_save_state(dev);
return 0;
}
@@ -104,7 +94,6 @@ static void pcie_portdrv_remove (struct pci_dev *dev)
{
pcie_port_device_remove(dev);
pci_disable_device(dev);
- kfree(pci_get_drvdata(dev));
}
static int error_detected_iter(struct device *device, void *data)
@@ -278,10 +267,9 @@ static struct pci_driver pcie_portdriver = {
.probe = pcie_portdrv_probe,
.remove = pcie_portdrv_remove,
- .suspend = pcie_portdrv_suspend,
- .resume = pcie_portdrv_resume,
-
.err_handler = &pcie_portdrv_err_handler,
+
+ .driver.pm = PCIE_PORTDRV_PM_OPS,
};
static int __init pcie_portdrv_init(void)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 55ec44a27e8..e2f3dd098cf 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -287,7 +287,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child)
struct resource *res;
int i;
- if (!dev) /* It's a host bus, nothing to read */
+ if (!child->parent) /* It's a host bus, nothing to read */
return;
if (dev->transparent) {
@@ -511,21 +511,21 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max,
/*
* If we already got to this bus through a different bridge,
- * ignore it. This can happen with the i450NX chipset.
+ * don't re-add it. This can happen with the i450NX chipset.
+ *
+ * However, we continue to descend down the hierarchy and
+ * scan remaining child buses.
*/
- if (pci_find_bus(pci_domain_nr(bus), busnr)) {
- dev_info(&dev->dev, "bus %04x:%02x already known\n",
- pci_domain_nr(bus), busnr);
- goto out;
+ child = pci_find_bus(pci_domain_nr(bus), busnr);
+ if (!child) {
+ child = pci_add_new_bus(bus, dev, busnr);
+ if (!child)
+ goto out;
+ child->primary = buses & 0xFF;
+ child->subordinate = (buses >> 16) & 0xFF;
+ child->bridge_ctl = bctl;
}
- child = pci_add_new_bus(bus, dev, busnr);
- if (!child)
- goto out;
- child->primary = buses & 0xFF;
- child->subordinate = (buses >> 16) & 0xFF;
- child->bridge_ctl = bctl;
-
cmax = pci_scan_child_bus(child);
if (cmax > max)
max = cmax;
@@ -674,6 +674,19 @@ static void pci_read_irq(struct pci_dev *dev)
dev->irq = irq;
}
+static void set_pcie_port_type(struct pci_dev *pdev)
+{
+ int pos;
+ u16 reg16;
+
+ pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+ if (!pos)
+ return;
+ pdev->is_pcie = 1;
+ pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
+ pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
+}
+
#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
/**
@@ -683,12 +696,33 @@ static void pci_read_irq(struct pci_dev *dev)
* Initialize the device structure with information about the device's
* vendor,class,memory and IO-space addresses,IRQ lines etc.
* Called at initialisation of the PCI subsystem and by CardBus services.
- * Returns 0 on success and -1 if unknown type of device (not normal, bridge
- * or CardBus).
+ * Returns 0 on success and negative if unknown type of device (not normal,
+ * bridge or CardBus).
*/
-static int pci_setup_device(struct pci_dev * dev)
+int pci_setup_device(struct pci_dev *dev)
{
u32 class;
+ u8 hdr_type;
+ struct pci_slot *slot;
+
+ if (pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type))
+ return -EIO;
+
+ dev->sysdata = dev->bus->sysdata;
+ dev->dev.parent = dev->bus->bridge;
+ dev->dev.bus = &pci_bus_type;
+ dev->hdr_type = hdr_type & 0x7f;
+ dev->multifunction = !!(hdr_type & 0x80);
+ dev->error_state = pci_channel_io_normal;
+ set_pcie_port_type(dev);
+
+ list_for_each_entry(slot, &dev->bus->slots, list)
+ if (PCI_SLOT(dev->devfn) == slot->number)
+ dev->slot = slot;
+
+ /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
+ set this higher, assuming the system even supports it. */
+ dev->dma_mask = 0xffffffff;
dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(dev->bus),
dev->bus->number, PCI_SLOT(dev->devfn),
@@ -703,12 +737,14 @@ static int pci_setup_device(struct pci_dev * dev)
dev_dbg(&dev->dev, "found [%04x:%04x] class %06x header type %02x\n",
dev->vendor, dev->device, class, dev->hdr_type);
+ /* need to have dev->class ready */
+ dev->cfg_size = pci_cfg_space_size(dev);
+
/* "Unknown power state" */
dev->current_state = PCI_UNKNOWN;
/* Early fixups, before probing the BARs */
pci_fixup_device(pci_fixup_early, dev);
- class = dev->class >> 8;
switch (dev->hdr_type) { /* header type */
case PCI_HEADER_TYPE_NORMAL: /* standard header */
@@ -770,7 +806,7 @@ static int pci_setup_device(struct pci_dev * dev)
default: /* unknown header */
dev_err(&dev->dev, "unknown header type %02x, "
"ignoring device\n", dev->hdr_type);
- return -1;
+ return -EIO;
bad:
dev_err(&dev->dev, "ignoring class %02x (doesn't match header "
@@ -785,6 +821,7 @@ static int pci_setup_device(struct pci_dev * dev)
static void pci_release_capabilities(struct pci_dev *dev)
{
pci_vpd_release(dev);
+ pci_iov_release(dev);
}
/**
@@ -803,19 +840,6 @@ static void pci_release_dev(struct device *dev)
kfree(pci_dev);
}
-static void set_pcie_port_type(struct pci_dev *pdev)
-{
- int pos;
- u16 reg16;
-
- pos = pci_find_capability(pdev, PCI_CAP_ID_EXP);
- if (!pos)
- return;
- pdev->is_pcie = 1;
- pci_read_config_word(pdev, pos + PCI_EXP_FLAGS, &reg16);
- pdev->pcie_type = (reg16 & PCI_EXP_FLAGS_TYPE) >> 4;
-}
-
/**
* pci_cfg_space_size - get the configuration space size of the PCI device.
* @dev: PCI device
@@ -847,6 +871,11 @@ int pci_cfg_space_size(struct pci_dev *dev)
{
int pos;
u32 status;
+ u16 class;
+
+ class = dev->class >> 8;
+ if (class == PCI_CLASS_BRIDGE_HOST)
+ return pci_cfg_space_size_ext(dev);
pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
if (!pos) {
@@ -891,9 +920,7 @@ EXPORT_SYMBOL(alloc_pci_dev);
static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
- struct pci_slot *slot;
u32 l;
- u8 hdr_type;
int delay = 1;
if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l))
@@ -920,34 +947,16 @@ static struct pci_dev *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 = alloc_pci_dev();
if (!dev)
return NULL;
dev->bus = bus;
- dev->sysdata = bus->sysdata;
- dev->dev.parent = bus->bridge;
- dev->dev.bus = &pci_bus_type;
dev->devfn = devfn;
- dev->hdr_type = hdr_type & 0x7f;
- dev->multifunction = !!(hdr_type & 0x80);
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
- dev->cfg_size = pci_cfg_space_size(dev);
- dev->error_state = pci_channel_io_normal;
- set_pcie_port_type(dev);
-
- list_for_each_entry(slot, &bus->slots, list)
- if (PCI_SLOT(devfn) == slot->number)
- dev->slot = slot;
- /* Assume 32-bit PCI; let 64-bit PCI cards (which are far rarer)
- set this higher, assuming the system even supports it. */
- dev->dma_mask = 0xffffffff;
- if (pci_setup_device(dev) < 0) {
+ if (pci_setup_device(dev)) {
kfree(dev);
return NULL;
}
@@ -972,6 +981,9 @@ static void pci_init_capabilities(struct pci_dev *dev)
/* Alternative Routing-ID Forwarding */
pci_enable_ari(dev);
+
+ /* Single Root I/O Virtualization */
+ pci_iov_init(dev);
}
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
@@ -1006,6 +1018,12 @@ struct pci_dev *__ref pci_scan_single_device(struct pci_bus *bus, int devfn)
{
struct pci_dev *dev;
+ dev = pci_get_slot(bus, devfn);
+ if (dev) {
+ pci_dev_put(dev);
+ return dev;
+ }
+
dev = pci_scan_device(bus, devfn);
if (!dev)
return NULL;
@@ -1024,35 +1042,27 @@ EXPORT_SYMBOL(pci_scan_single_device);
* Scan a PCI slot on the specified PCI bus for devices, adding
* discovered devices to the @bus->devices list. New devices
* will not have is_added set.
+ *
+ * Returns the number of new devices found.
*/
int pci_scan_slot(struct pci_bus *bus, int devfn)
{
- int func, nr = 0;
- int scan_all_fns;
-
- scan_all_fns = pcibios_scan_all_fns(bus, devfn);
-
- for (func = 0; func < 8; func++, devfn++) {
- struct pci_dev *dev;
-
- dev = pci_scan_single_device(bus, devfn);
- if (dev) {
- nr++;
+ int fn, nr = 0;
+ struct pci_dev *dev;
- /*
- * If this is a single function device,
- * don't scan past the first function.
- */
- if (!dev->multifunction) {
- if (func > 0) {
- dev->multifunction = 1;
- } else {
- break;
- }
+ dev = pci_scan_single_device(bus, devfn);
+ if (dev && !dev->is_added) /* new device? */
+ nr++;
+
+ if ((dev && dev->multifunction) ||
+ (!dev && pcibios_scan_all_fns(bus, devfn))) {
+ for (fn = 1; fn < 8; fn++) {
+ dev = pci_scan_single_device(bus, devfn + fn);
+ if (dev) {
+ if (!dev->is_added)
+ nr++;
+ dev->multifunction = 1;
}
- } else {
- if (func == 0 && !scan_all_fns)
- break;
}
}
@@ -1074,12 +1084,21 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
for (devfn = 0; devfn < 0x100; devfn += 8)
pci_scan_slot(bus, devfn);
+ /* Reserve buses for SR-IOV capability. */
+ max += pci_iov_bus_range(bus);
+
/*
* After performing arch-dependent fixup of the bus, look behind
* all PCI-to-PCI bridges on this bus.
*/
- pr_debug("PCI: Fixups for bus %04x:%02x\n", pci_domain_nr(bus), bus->number);
- pcibios_fixup_bus(bus);
+ if (!bus->is_added) {
+ pr_debug("PCI: Fixups for bus %04x:%02x\n",
+ pci_domain_nr(bus), bus->number);
+ pcibios_fixup_bus(bus);
+ if (pci_is_root_bus(bus))
+ bus->is_added = 1;
+ }
+
for (pass=0; pass < 2; pass++)
list_for_each_entry(dev, &bus->devices, bus_list) {
if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
@@ -1114,7 +1133,7 @@ struct pci_bus * pci_create_bus(struct device *parent,
if (!b)
return NULL;
- dev = kmalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (!dev){
kfree(b);
return NULL;
@@ -1133,7 +1152,6 @@ struct pci_bus * pci_create_bus(struct device *parent,
list_add_tail(&b->node, &pci_root_buses);
up_write(&pci_bus_sem);
- memset(dev, 0, sizeof(*dev));
dev->parent = parent;
dev->release = pci_release_bus_bridge_dev;
dev_set_name(dev, "pci%04x:%02x", pci_domain_nr(b), bus);
@@ -1193,6 +1211,38 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent,
EXPORT_SYMBOL(pci_scan_bus_parented);
#ifdef CONFIG_HOTPLUG
+/**
+ * pci_rescan_bus - scan a PCI bus for devices.
+ * @bus: PCI bus to scan
+ *
+ * Scan a PCI bus and child buses for new devices, adds them,
+ * and enables them.
+ *
+ * Returns the max number of subordinate bus discovered.
+ */
+unsigned int __devinit pci_rescan_bus(struct pci_bus *bus)
+{
+ unsigned int max;
+ struct pci_dev *dev;
+
+ max = pci_scan_child_bus(bus);
+
+ down_read(&pci_bus_sem);
+ list_for_each_entry(dev, &bus->devices, bus_list)
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE ||
+ dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)
+ if (dev->subordinate)
+ pci_bus_size_bridges(dev->subordinate);
+ up_read(&pci_bus_sem);
+
+ pci_bus_assign_resources(bus);
+ pci_enable_bridges(bus);
+ pci_bus_add_devices(bus);
+
+ return max;
+}
+EXPORT_SYMBOL_GPL(pci_rescan_bus);
+
EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bridge);
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index 92b9efe9bca..9b2f0d96900 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -24,6 +24,7 @@
#include <linux/kallsyms.h>
#include <linux/dmi.h>
#include <linux/pci-aspm.h>
+#include <linux/ioport.h>
#include "pci.h"
int isa_dma_bridge_buggy;
@@ -34,6 +35,65 @@ int pcie_mch_quirk;
EXPORT_SYMBOL(pcie_mch_quirk);
#ifdef CONFIG_PCI_QUIRKS
+/*
+ * This quirk function disables the device and releases resources
+ * which is specified by kernel's boot parameter 'pci=resource_alignment='.
+ * It also rounds up size to specified alignment.
+ * Later on, the kernel will assign page-aligned memory resource back
+ * to that device.
+ */
+static void __devinit quirk_resource_alignment(struct pci_dev *dev)
+{
+ int i;
+ struct resource *r;
+ resource_size_t align, size;
+
+ if (!pci_is_reassigndev(dev))
+ return;
+
+ if (dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
+ dev_warn(&dev->dev,
+ "Can't reassign resources to host bridge.\n");
+ return;
+ }
+
+ dev_info(&dev->dev, "Disabling device and release resources.\n");
+ pci_disable_device(dev);
+
+ align = pci_specified_resource_alignment(dev);
+ for (i=0; i < PCI_BRIDGE_RESOURCES; i++) {
+ r = &dev->resource[i];
+ if (!(r->flags & IORESOURCE_MEM))
+ continue;
+ size = resource_size(r);
+ if (size < align) {
+ size = align;
+ dev_info(&dev->dev,
+ "Rounding up size of resource #%d to %#llx.\n",
+ i, (unsigned long long)size);
+ }
+ r->end = size - 1;
+ r->start = 0;
+ }
+ /* Need to disable bridge's resource window,
+ * to enable the kernel to reassign new resource
+ * window later on.
+ */
+ if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE &&
+ (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
+ for (i = PCI_BRIDGE_RESOURCES; i < PCI_NUM_RESOURCES; i++) {
+ r = &dev->resource[i];
+ if (!(r->flags & IORESOURCE_MEM))
+ continue;
+ r->end = resource_size(r) - 1;
+ r->start = 0;
+ }
+ pci_disable_bridge_window(dev);
+ }
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, quirk_resource_alignment);
+
/* The Mellanox Tavor device gives false positive parity errors
* Mark this device with a broken_parity_status, to allow
* PCI scanning code to "skip" this now blacklisted device.
@@ -1126,10 +1186,15 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
* its on-board VGA controller */
asus_hides_smbus = 1;
}
- else if (dev->device == PCI_DEVICE_ID_INTEL_82845G_IG)
+ else if (dev->device == PCI_DEVICE_ID_INTEL_82801DB_2)
switch(dev->subsystem_device) {
case 0x00b8: /* Compaq Evo D510 CMT */
case 0x00b9: /* Compaq Evo D510 SFF */
+ /* Motherboard doesn't have Host bridge
+ * subvendor/subdevice IDs and on-board VGA
+ * controller is disabled if an AGP card is
+ * inserted, therefore checking USB UHCI
+ * Controller #1 */
asus_hides_smbus = 1;
}
else if (dev->device == PCI_DEVICE_ID_INTEL_82815_CGC)
@@ -1154,7 +1219,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, as
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82810_IG3, asus_hides_smbus_hostbridge);
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82845G_IG, asus_hides_smbus_hostbridge);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_2, asus_hides_smbus_hostbridge);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82815_CGC, asus_hides_smbus_hostbridge);
static void asus_hides_smbus_lpc(struct pci_dev *dev)
@@ -1664,9 +1729,13 @@ static void __devinit quirk_netmos(struct pci_dev *dev)
* of parallel ports and <S> is the number of serial ports.
*/
switch (dev->device) {
+ case PCI_DEVICE_ID_NETMOS_9835:
+ /* Well, this rule doesn't hold for the following 9835 device */
+ if (dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
+ dev->subsystem_device == 0x0299)
+ return;
case PCI_DEVICE_ID_NETMOS_9735:
case PCI_DEVICE_ID_NETMOS_9745:
- case PCI_DEVICE_ID_NETMOS_9835:
case PCI_DEVICE_ID_NETMOS_9845:
case PCI_DEVICE_ID_NETMOS_9855:
if ((dev->class >> 8) == PCI_CLASS_COMMUNICATION_SERIAL &&
@@ -2078,6 +2147,92 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA,
PCI_DEVICE_ID_NVIDIA_NVENET_15,
nvenet_msi_disable);
+static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
+{
+ int pos, ttl = 48;
+ int found = 0;
+
+ /* check if there is HT MSI cap or enabled on this device */
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
+ while (pos && ttl--) {
+ u8 flags;
+
+ if (found < 1)
+ found = 1;
+ if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
+ &flags) == 0) {
+ if (flags & HT_MSI_FLAGS_ENABLE) {
+ if (found < 2) {
+ found = 2;
+ break;
+ }
+ }
+ }
+ pos = pci_find_next_ht_capability(dev, pos,
+ HT_CAPTYPE_MSI_MAPPING);
+ }
+
+ return found;
+}
+
+static int __devinit host_bridge_with_leaf(struct pci_dev *host_bridge)
+{
+ struct pci_dev *dev;
+ int pos;
+ int i, dev_no;
+ int found = 0;
+
+ dev_no = host_bridge->devfn >> 3;
+ for (i = dev_no + 1; i < 0x20; i++) {
+ dev = pci_get_slot(host_bridge->bus, PCI_DEVFN(i, 0));
+ if (!dev)
+ continue;
+
+ /* found next host bridge ?*/
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE);
+ if (pos != 0) {
+ pci_dev_put(dev);
+ break;
+ }
+
+ if (ht_check_msi_mapping(dev)) {
+ found = 1;
+ pci_dev_put(dev);
+ break;
+ }
+ pci_dev_put(dev);
+ }
+
+ return found;
+}
+
+#define PCI_HT_CAP_SLAVE_CTRL0 4 /* link control */
+#define PCI_HT_CAP_SLAVE_CTRL1 8 /* link control to */
+
+static int __devinit is_end_of_ht_chain(struct pci_dev *dev)
+{
+ int pos, ctrl_off;
+ int end = 0;
+ u16 flags, ctrl;
+
+ pos = pci_find_ht_capability(dev, HT_CAPTYPE_SLAVE);
+
+ if (!pos)
+ goto out;
+
+ pci_read_config_word(dev, pos + PCI_CAP_FLAGS, &flags);
+
+ ctrl_off = ((flags >> 10) & 1) ?
+ PCI_HT_CAP_SLAVE_CTRL0 : PCI_HT_CAP_SLAVE_CTRL1;
+ pci_read_config_word(dev, pos + ctrl_off, &ctrl);
+
+ if (ctrl & (1 << 6))
+ end = 1;
+
+out:
+ return end;
+}
+
static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
{
struct pci_dev *host_bridge;
@@ -2102,6 +2257,11 @@ static void __devinit nv_ht_enable_msi_mapping(struct pci_dev *dev)
if (!found)
return;
+ /* don't enable end_device/host_bridge with leaf directly here */
+ if (host_bridge == dev && is_end_of_ht_chain(host_bridge) &&
+ host_bridge_with_leaf(host_bridge))
+ goto out;
+
/* root did that ! */
if (msi_ht_cap_enabled(host_bridge))
goto out;
@@ -2132,44 +2292,12 @@ static void __devinit ht_disable_msi_mapping(struct pci_dev *dev)
}
}
-static int __devinit ht_check_msi_mapping(struct pci_dev *dev)
-{
- int pos, ttl = 48;
- int found = 0;
-
- /* check if there is HT MSI cap or enabled on this device */
- pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
- while (pos && ttl--) {
- u8 flags;
-
- if (found < 1)
- found = 1;
- if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
- &flags) == 0) {
- if (flags & HT_MSI_FLAGS_ENABLE) {
- if (found < 2) {
- found = 2;
- break;
- }
- }
- }
- pos = pci_find_next_ht_capability(dev, pos,
- HT_CAPTYPE_MSI_MAPPING);
- }
-
- return found;
-}
-
-static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
+static void __devinit __nv_msi_ht_cap_quirk(struct pci_dev *dev, int all)
{
struct pci_dev *host_bridge;
int pos;
int found;
- /* Enabling HT MSI mapping on this device breaks MCP51 */
- if (dev->device == 0x270)
- return;
-
/* check if there is HT MSI cap or enabled on this device */
found = ht_check_msi_mapping(dev);
@@ -2193,7 +2321,10 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
/* Host bridge is to HT */
if (found == 1) {
/* it is not enabled, try to enable it */
- nv_ht_enable_msi_mapping(dev);
+ if (all)
+ ht_enable_msi_mapping(dev);
+ else
+ nv_ht_enable_msi_mapping(dev);
}
return;
}
@@ -2205,8 +2336,20 @@ static void __devinit nv_msi_ht_cap_quirk(struct pci_dev *dev)
/* Host bridge is not to HT, disable HT MSI mapping on this device */
ht_disable_msi_mapping(dev);
}
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk);
+
+static void __devinit nv_msi_ht_cap_quirk_all(struct pci_dev *dev)
+{
+ return __nv_msi_ht_cap_quirk(dev, 1);
+}
+
+static void __devinit nv_msi_ht_cap_quirk_leaf(struct pci_dev *dev)
+{
+ return __nv_msi_ht_cap_quirk(dev, 0);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, nv_msi_ht_cap_quirk_leaf);
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AL, PCI_ANY_ID, nv_msi_ht_cap_quirk_all);
static void __devinit quirk_msi_intx_disable_bug(struct pci_dev *dev)
{
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 042e0892442..86503c14ce7 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -71,6 +71,9 @@ void pci_remove_bus(struct pci_bus *pci_bus)
down_write(&pci_bus_sem);
list_del(&pci_bus->node);
up_write(&pci_bus_sem);
+ if (!pci_bus->is_added)
+ return;
+
pci_remove_legacy_files(pci_bus);
device_remove_file(&pci_bus->dev, &dev_attr_cpuaffinity);
device_remove_file(&pci_bus->dev, &dev_attr_cpulistaffinity);
@@ -92,6 +95,7 @@ EXPORT_SYMBOL(pci_remove_bus);
*/
void pci_remove_bus_device(struct pci_dev *dev)
{
+ pci_stop_bus_device(dev);
if (dev->subordinate) {
struct pci_bus *b = dev->subordinate;
diff --git a/drivers/pci/search.c b/drivers/pci/search.c
index 5af8bd53814..710d4ea6956 100644
--- a/drivers/pci/search.c
+++ b/drivers/pci/search.c
@@ -29,7 +29,7 @@ pci_find_upstream_pcie_bridge(struct pci_dev *pdev)
if (pdev->is_pcie)
return NULL;
while (1) {
- if (!pdev->bus->self)
+ if (!pdev->bus->parent)
break;
pdev = pdev->bus->self;
/* a p2p bridge */
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 70460894578..334285a8e23 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -27,7 +27,7 @@
#include <linux/slab.h>
-static void pbus_assign_resources_sorted(struct pci_bus *bus)
+static void pbus_assign_resources_sorted(const struct pci_bus *bus)
{
struct pci_dev *dev;
struct resource *res;
@@ -144,6 +144,9 @@ static void pci_setup_bridge(struct pci_bus *bus)
struct pci_bus_region region;
u32 l, bu, lu, io_upper16;
+ if (!pci_is_root_bus(bus) && bus->is_added)
+ return;
+
dev_info(&bridge->dev, "PCI bridge, secondary bus %04x:%02x\n",
pci_domain_nr(bus), bus->number);
@@ -495,7 +498,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
}
EXPORT_SYMBOL(pci_bus_size_bridges);
-void __ref pci_bus_assign_resources(struct pci_bus *bus)
+void __ref pci_bus_assign_resources(const struct pci_bus *bus)
{
struct pci_bus *b;
struct pci_dev *dev;
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
index 32e8d88a461..3039fcb86af 100644
--- a/drivers/pci/setup-res.c
+++ b/drivers/pci/setup-res.c
@@ -120,6 +120,21 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
return err;
}
+#ifdef CONFIG_PCI_QUIRKS
+void pci_disable_bridge_window(struct pci_dev *dev)
+{
+ dev_dbg(&dev->dev, "Disabling bridge window.\n");
+
+ /* MMIO Base/Limit */
+ pci_write_config_dword(dev, PCI_MEMORY_BASE, 0x0000fff0);
+
+ /* Prefetchable MMIO Base/Limit */
+ pci_write_config_dword(dev, PCI_PREF_LIMIT_UPPER32, 0);
+ pci_write_config_dword(dev, PCI_PREF_MEMORY_BASE, 0x0000fff0);
+ pci_write_config_dword(dev, PCI_PREF_BASE_UPPER32, 0xffffffff);
+}
+#endif /* CONFIG_PCI_QUIRKS */
+
int pci_assign_resource(struct pci_dev *dev, int resno)
{
struct pci_bus *bus = dev->bus;
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 5a8ccb4f604..21189447e54 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -1,8 +1,8 @@
/*
* drivers/pci/slot.c
* Copyright (C) 2006 Matthew Wilcox <matthew@wil.cx>
- * Copyright (C) 2006-2008 Hewlett-Packard Development Company, L.P.
- * Alex Chiang <achiang@hp.com>
+ * Copyright (C) 2006-2009 Hewlett-Packard Development Company, L.P.
+ * Alex Chiang <achiang@hp.com>
*/
#include <linux/kobject.h>
@@ -52,8 +52,8 @@ static void pci_slot_release(struct kobject *kobj)
struct pci_dev *dev;
struct pci_slot *slot = to_pci_slot(kobj);
- pr_debug("%s: releasing pci_slot on %x:%d\n", __func__,
- slot->bus->number, slot->number);
+ dev_dbg(&slot->bus->dev, "dev %02x, released physical slot %s\n",
+ slot->number, pci_slot_name(slot));
list_for_each_entry(dev, &slot->bus->devices, bus_list)
if (PCI_SLOT(dev->devfn) == slot->number)
@@ -248,9 +248,8 @@ placeholder:
if (PCI_SLOT(dev->devfn) == slot_nr)
dev->slot = slot;
- /* Don't care if debug printk has a -1 for slot_nr */
- pr_debug("%s: created pci_slot on %04x:%02x:%02x\n",
- __func__, pci_domain_nr(parent), parent->number, slot_nr);
+ dev_dbg(&parent->dev, "dev %02x, created physical slot %s\n",
+ slot_nr, pci_slot_name(slot));
out:
kfree(slot_name);
@@ -299,9 +298,8 @@ EXPORT_SYMBOL_GPL(pci_renumber_slot);
*/
void pci_destroy_slot(struct pci_slot *slot)
{
- pr_debug("%s: dec refcount to %d on %04x:%02x:%02x\n", __func__,
- atomic_read(&slot->kobj.kref.refcount) - 1,
- pci_domain_nr(slot->bus), slot->bus->number, slot->number);
+ dev_dbg(&slot->bus->dev, "dev %02x, dec refcount to %d\n",
+ slot->number, atomic_read(&slot->kobj.kref.refcount) - 1);
down_write(&pci_bus_sem);
kobject_put(&slot->kobj);
diff --git a/drivers/pcmcia/pxa2xx_cm_x255.c b/drivers/pcmcia/pxa2xx_cm_x255.c
index 4ed64d8e95e..5143a760153 100644
--- a/drivers/pcmcia/pxa2xx_cm_x255.c
+++ b/drivers/pcmcia/pxa2xx_cm_x255.c
@@ -63,7 +63,7 @@ static void cmx255_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
int cd = skt->nr ? GPIO_PCMCIA_S1_CD_VALID : GPIO_PCMCIA_S0_CD_VALID;
- int rdy = skt->nr ? GPIO_PCMCIA_S0_RDYINT : GPIO_PCMCIA_S1_RDYINT;
+ int rdy = skt->nr ? GPIO_PCMCIA_S1_RDYINT : GPIO_PCMCIA_S0_RDYINT;
state->detect = !gpio_get_value(cd);
state->ready = !!gpio_get_value(rdy);
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 3608081bc3e..284ebaca6e4 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -67,6 +67,16 @@ config DELL_LAPTOP
This driver adds support for rfkill and backlight control to Dell
laptops.
+config DELL_WMI
+ tristate "Dell WMI extras"
+ depends on ACPI_WMI
+ depends on INPUT
+ ---help---
+ Say Y here if you want to support WMI-based hotkeys on Dell laptops.
+
+ To compile this driver as a module, choose M here: the module will
+ be called dell-wmi.
+
config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras"
depends on ACPI
@@ -165,6 +175,7 @@ config SONY_LAPTOP
depends on ACPI
select BACKLIGHT_CLASS_DEVICE
depends on INPUT
+ depends on RFKILL
---help---
This mini-driver drives the SNC and SPIC devices present in the ACPI
BIOS of the Sony Vaio laptops.
@@ -226,6 +237,30 @@ config THINKPAD_ACPI_DEBUG
If you are not sure, say N here.
+config THINKPAD_ACPI_UNSAFE_LEDS
+ bool "Allow control of important LEDs (unsafe)"
+ depends on THINKPAD_ACPI
+ default n
+ ---help---
+ Overriding LED state on ThinkPads can mask important
+ firmware alerts (like critical battery condition), or misled
+ the user into damaging the hardware (undocking or ejecting
+ the bay while buses are still active), etc.
+
+ LED control on the ThinkPad is write-only (with very few
+ exceptions on very ancient models), which makes it
+ impossible to know beforehand if important information will
+ be lost when one changes LED state.
+
+ Users that know what they are doing can enable this option
+ and the driver will allow control of every LED, including
+ the ones on the dock stations.
+
+ Never enable this option on a distribution kernel.
+
+ Say N here, unless you are building a kernel for your own
+ use, and need to control the important firmware LEDs.
+
config THINKPAD_ACPI_DOCK
bool "Legacy Docking Station Support"
depends on THINKPAD_ACPI
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index e29065120be..e40c7bd1b87 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
+obj-$(CONFIG_DELL_WMI) += dell-wmi.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_HP_WMI) += hp-wmi.o
obj-$(CONFIG_TC1100_WMI) += tc1100-wmi.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index a6a42e8c060..0f6e43bf4fc 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -1,7 +1,7 @@
/*
* Acer WMI Laptop Extras
*
- * Copyright (C) 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
+ * Copyright (C) 2007-2009 Carlos Corbacho <carlos@strangeworlds.co.uk>
*
* Based on acer_acpi:
* Copyright (C) 2005-2007 E.M. Smith
@@ -225,6 +225,25 @@ static struct quirk_entry quirk_fujitsu_amilo_li_1718 = {
.wireless = 2,
};
+/* The Aspire One has a dummy ACPI-WMI interface - disable it */
+static struct dmi_system_id __devinitdata acer_blacklist[] = {
+ {
+ .ident = "Acer Aspire One (SSD)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
+ },
+ },
+ {
+ .ident = "Acer Aspire One (HDD)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "AOA150"),
+ },
+ },
+ {}
+};
+
static struct dmi_system_id acer_quirks[] = {
{
.callback = dmi_matched,
@@ -1117,11 +1136,17 @@ static int __devinit acer_platform_probe(struct platform_device *device)
}
err = acer_rfkill_init(&device->dev);
+ if (err)
+ goto error_rfkill;
return err;
+error_rfkill:
+ if (has_cap(ACER_CAP_BRIGHTNESS))
+ acer_backlight_exit();
error_brightness:
- acer_led_exit();
+ if (has_cap(ACER_CAP_MAILLED))
+ acer_led_exit();
error_mailled:
return err;
}
@@ -1254,6 +1279,12 @@ static int __init acer_wmi_init(void)
printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
+ if (dmi_check_system(acer_blacklist)) {
+ printk(ACER_INFO "Blacklisted hardware detected - "
+ "not loading\n");
+ return -ENODEV;
+ }
+
find_quirks();
/*
diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c
index d63f26e666a..ba1f7497e4b 100644
--- a/drivers/platform/x86/asus_acpi.c
+++ b/drivers/platform/x86/asus_acpi.c
@@ -987,7 +987,6 @@ asus_proc_add(char *name, proc_writefunc *writefunc,
proc->write_proc = writefunc;
proc->read_proc = readfunc;
proc->data = acpi_driver_data(device);
- proc->owner = THIS_MODULE;
proc->uid = asus_uid;
proc->gid = asus_gid;
return 0;
@@ -1020,7 +1019,6 @@ static int asus_hotk_add_fs(struct acpi_device *device)
if (proc) {
proc->read_proc = proc_read_info;
proc->data = acpi_driver_data(device);
- proc->owner = THIS_MODULE;
proc->uid = asus_uid;
proc->gid = asus_gid;
} else {
@@ -1436,7 +1434,6 @@ static int __init asus_acpi_init(void)
printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
return -ENODEV;
}
- asus_proc_dir->owner = THIS_MODULE;
result = acpi_bus_register_driver(&asus_hotk_driver);
if (result < 0) {
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 16e11c2ee19..af9f4302117 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -103,7 +103,7 @@ static void parse_da_table(const struct dmi_header *dm)
da_num_tokens += tokens;
}
-static void find_tokens(const struct dmi_header *dm)
+static void find_tokens(const struct dmi_header *dm, void *dummy)
{
switch (dm->type) {
case 0xd4: /* Indexed IO */
@@ -356,7 +356,7 @@ static int __init dell_init(void)
if (!dmi_check_system(dell_device_table))
return -ENODEV;
- dmi_walk(find_tokens);
+ dmi_walk(find_tokens, NULL);
if (!da_tokens) {
printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n");
diff --git a/drivers/platform/x86/dell-wmi.c b/drivers/platform/x86/dell-wmi.c
new file mode 100644
index 00000000000..2fab9416214
--- /dev/null
+++ b/drivers/platform/x86/dell-wmi.c
@@ -0,0 +1,210 @@
+/*
+ * Dell WMI hotkeys
+ *
+ * Copyright (C) 2008 Red Hat <mjg@redhat.com>
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
+#include <linux/string.h>
+
+MODULE_AUTHOR("Matthew Garrett <mjg@redhat.com>");
+MODULE_DESCRIPTION("Dell laptop WMI hotkeys driver");
+MODULE_LICENSE("GPL");
+
+#define DELL_EVENT_GUID "9DBB5994-A997-11DA-B012-B622A1EF5492"
+
+MODULE_ALIAS("wmi:"DELL_EVENT_GUID);
+
+struct key_entry {
+ char type; /* See KE_* below */
+ u16 code;
+ u16 keycode;
+};
+
+enum { KE_KEY, KE_SW, KE_END };
+
+static struct key_entry dell_wmi_keymap[] = {
+ {KE_KEY, 0xe045, KEY_PROG1},
+ {KE_END, 0}
+};
+
+static struct input_dev *dell_wmi_input_dev;
+
+static struct key_entry *dell_wmi_get_entry_by_scancode(int code)
+{
+ struct key_entry *key;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++)
+ if (code == key->code)
+ return key;
+
+ return NULL;
+}
+
+static struct key_entry *dell_wmi_get_entry_by_keycode(int keycode)
+{
+ struct key_entry *key;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++)
+ if (key->type == KE_KEY && keycode == key->keycode)
+ return key;
+
+ return NULL;
+}
+
+static int dell_wmi_getkeycode(struct input_dev *dev, int scancode,
+ int *keycode)
+{
+ struct key_entry *key = dell_wmi_get_entry_by_scancode(scancode);
+
+ if (key && key->type == KE_KEY) {
+ *keycode = key->keycode;
+ return 0;
+ }
+
+ return -EINVAL;
+}
+
+static int dell_wmi_setkeycode(struct input_dev *dev, int scancode, int keycode)
+{
+ struct key_entry *key;
+ int old_keycode;
+
+ if (keycode < 0 || keycode > KEY_MAX)
+ return -EINVAL;
+
+ key = dell_wmi_get_entry_by_scancode(scancode);
+ if (key && key->type == KE_KEY) {
+ old_keycode = key->keycode;
+ key->keycode = keycode;
+ set_bit(keycode, dev->keybit);
+ if (!dell_wmi_get_entry_by_keycode(old_keycode))
+ clear_bit(old_keycode, dev->keybit);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static void dell_wmi_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ static struct key_entry *key;
+ union acpi_object *obj;
+
+ wmi_get_event_data(value, &response);
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (obj && obj->type == ACPI_TYPE_BUFFER) {
+ int *buffer = (int *)obj->buffer.pointer;
+ key = dell_wmi_get_entry_by_scancode(buffer[1]);
+ if (key) {
+ input_report_key(dell_wmi_input_dev, key->keycode, 1);
+ input_sync(dell_wmi_input_dev);
+ input_report_key(dell_wmi_input_dev, key->keycode, 0);
+ input_sync(dell_wmi_input_dev);
+ } else
+ printk(KERN_INFO "dell-wmi: Unknown key %x pressed\n",
+ buffer[1]);
+ }
+}
+
+static int __init dell_wmi_input_setup(void)
+{
+ struct key_entry *key;
+ int err;
+
+ dell_wmi_input_dev = input_allocate_device();
+
+ if (!dell_wmi_input_dev)
+ return -ENOMEM;
+
+ dell_wmi_input_dev->name = "Dell WMI hotkeys";
+ dell_wmi_input_dev->phys = "wmi/input0";
+ dell_wmi_input_dev->id.bustype = BUS_HOST;
+ dell_wmi_input_dev->getkeycode = dell_wmi_getkeycode;
+ dell_wmi_input_dev->setkeycode = dell_wmi_setkeycode;
+
+ for (key = dell_wmi_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_KEY:
+ set_bit(EV_KEY, dell_wmi_input_dev->evbit);
+ set_bit(key->keycode, dell_wmi_input_dev->keybit);
+ break;
+ case KE_SW:
+ set_bit(EV_SW, dell_wmi_input_dev->evbit);
+ set_bit(key->keycode, dell_wmi_input_dev->swbit);
+ break;
+ }
+ }
+
+ err = input_register_device(dell_wmi_input_dev);
+
+ if (err) {
+ input_free_device(dell_wmi_input_dev);
+ return err;
+ }
+
+ return 0;
+}
+
+static int __init dell_wmi_init(void)
+{
+ int err;
+
+ if (wmi_has_guid(DELL_EVENT_GUID)) {
+ err = dell_wmi_input_setup();
+
+ if (err)
+ return err;
+
+ err = wmi_install_notify_handler(DELL_EVENT_GUID,
+ dell_wmi_notify, NULL);
+ if (err) {
+ input_unregister_device(dell_wmi_input_dev);
+ printk(KERN_ERR "dell-wmi: Unable to register"
+ " notify handler - %d\n", err);
+ return err;
+ }
+
+ } else
+ printk(KERN_WARNING "dell-wmi: No known WMI GUID found\n");
+
+ return 0;
+}
+
+static void __exit dell_wmi_exit(void)
+{
+ if (wmi_has_guid(DELL_EVENT_GUID)) {
+ wmi_remove_notify_handler(DELL_EVENT_GUID);
+ input_unregister_device(dell_wmi_input_dev);
+ }
+}
+
+module_init(dell_wmi_init);
+module_exit(dell_wmi_exit);
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index f41135f2fb2..50d9019de2b 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -53,6 +53,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
static int __init hp_wmi_bios_setup(struct platform_device *device);
static int __exit hp_wmi_bios_remove(struct platform_device *device);
+static int hp_wmi_resume_handler(struct platform_device *device);
struct bios_args {
u32 signature;
@@ -101,6 +102,7 @@ static struct platform_driver hp_wmi_driver = {
},
.probe = hp_wmi_bios_setup,
.remove = hp_wmi_bios_remove,
+ .resume = hp_wmi_resume_handler,
};
static int hp_wmi_perform_query(int query, int write, int value)
@@ -487,6 +489,29 @@ static int __exit hp_wmi_bios_remove(struct platform_device *device)
return 0;
}
+static int hp_wmi_resume_handler(struct platform_device *device)
+{
+ struct key_entry *key;
+
+ /*
+ * Docking state may have changed while suspended, so trigger
+ * an input event for the current state. As this is a switch,
+ * the input layer will only actually pass it on if the state
+ * changed.
+ */
+ for (key = hp_wmi_keymap; key->type != KE_END; key++) {
+ switch (key->type) {
+ case KE_SW:
+ input_report_switch(hp_wmi_input_dev, key->keycode,
+ hp_wmi_dock_state());
+ input_sync(hp_wmi_input_dev);
+ break;
+ }
+ }
+
+ return 0;
+}
+
static int __init hp_wmi_init(void)
{
int err;
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c
index 27b7662955b..29432a50be4 100644
--- a/drivers/platform/x86/intel_menlow.c
+++ b/drivers/platform/x86/intel_menlow.c
@@ -57,8 +57,8 @@ MODULE_LICENSE("GPL");
* In that case max_cstate would be n-1
* GTHS returning '0' would mean that no bandwidth control states are supported
*/
-static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
- unsigned long *max_state)
+static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
+ unsigned long *max_state)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
@@ -83,22 +83,12 @@ static int memory_get_int_max_bandwidth(struct thermal_cooling_device *cdev,
return 0;
}
-static int memory_get_max_bandwidth(struct thermal_cooling_device *cdev,
- char *buf)
-{
- unsigned long value;
- if (memory_get_int_max_bandwidth(cdev, &value))
- return -EINVAL;
-
- return sprintf(buf, "%ld\n", value);
-}
-
static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
- char *buf)
+ unsigned long *value)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
- unsigned long long value;
+ unsigned long long result;
struct acpi_object_list arg_list;
union acpi_object arg;
acpi_status status = AE_OK;
@@ -108,15 +98,16 @@ static int memory_get_cur_bandwidth(struct thermal_cooling_device *cdev,
arg.type = ACPI_TYPE_INTEGER;
arg.integer.value = MEMORY_ARG_CUR_BANDWIDTH;
status = acpi_evaluate_integer(handle, MEMORY_GET_BANDWIDTH,
- &arg_list, &value);
+ &arg_list, &result);
if (ACPI_FAILURE(status))
return -EFAULT;
- return sprintf(buf, "%llu\n", value);
+ *value = result;
+ return 0;
}
static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
- unsigned int state)
+ unsigned long state)
{
struct acpi_device *device = cdev->devdata;
acpi_handle handle = device->handle;
@@ -126,7 +117,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
unsigned long long temp;
unsigned long max_state;
- if (memory_get_int_max_bandwidth(cdev, &max_state))
+ if (memory_get_max_bandwidth(cdev, &max_state))
return -EFAULT;
if (state > max_state)
@@ -142,7 +133,7 @@ static int memory_set_cur_bandwidth(struct thermal_cooling_device *cdev,
&temp);
printk(KERN_INFO
- "Bandwidth value was %d: status is %d\n", state, status);
+ "Bandwidth value was %ld: status is %d\n", state, status);
if (ACPI_FAILURE(status))
return -EFAULT;
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c
index c47a44dcb70..a5ce4bc202e 100644
--- a/drivers/platform/x86/panasonic-laptop.c
+++ b/drivers/platform/x86/panasonic-laptop.c
@@ -184,6 +184,7 @@ static const struct acpi_device_id pcc_device_ids[] = {
{ "MAT0019", 0},
{ "", 0},
};
+MODULE_DEVICE_TABLE(acpi, pcc_device_ids);
static struct acpi_driver acpi_pcc_driver = {
.name = ACPI_PCC_DRIVER_NAME,
@@ -366,7 +367,7 @@ static ssize_t show_numbatt(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_NUM_BATTERIES]);
}
static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
@@ -378,7 +379,7 @@ static ssize_t show_lcdtype(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_LCD_TYPE]);
}
static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
@@ -390,7 +391,7 @@ static ssize_t show_mute(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_MUTE]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_MUTE]);
}
static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
@@ -402,7 +403,7 @@ static ssize_t show_sticky(struct device *dev, struct device_attribute *attr,
if (!acpi_pcc_retrieve_biosdata(pcc, pcc->sinf))
return -EIO;
- return sprintf(buf, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
+ return snprintf(buf, PAGE_SIZE, "%u\n", pcc->sinf[SINF_STICKY_KEY]);
}
static ssize_t set_sticky(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index bc8996c849a..a90ec5cb2f2 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -2,7 +2,7 @@
* ACPI Sony Notebook Control Driver (SNC and SPIC)
*
* Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
- * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
+ * Copyright (C) 2007-2009 Mattia Dongili <malattia@linux.it>
*
* Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
* which are copyrighted by their respective authors.
@@ -46,7 +46,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include <linux/smp_lock.h>
#include <linux/types.h>
#include <linux/backlight.h>
#include <linux/platform_device.h>
@@ -64,6 +63,7 @@
#include <asm/uaccess.h>
#include <linux/sonypi.h>
#include <linux/sony-laptop.h>
+#include <linux/rfkill.h>
#ifdef CONFIG_SONYPI_COMPAT
#include <linux/poll.h>
#include <linux/miscdevice.h>
@@ -123,6 +123,18 @@ MODULE_PARM_DESC(minor,
"default is -1 (automatic)");
#endif
+enum sony_nc_rfkill {
+ SONY_WIFI,
+ SONY_BLUETOOTH,
+ SONY_WWAN,
+ SONY_WIMAX,
+ SONY_RFKILL_MAX,
+};
+
+static struct rfkill *sony_rfkill_devices[SONY_RFKILL_MAX];
+static int sony_rfkill_address[SONY_RFKILL_MAX] = {0x300, 0x500, 0x700, 0x900};
+static void sony_nc_rfkill_update(void);
+
/*********** Input Devices ***********/
#define SONY_LAPTOP_BUF_SIZE 128
@@ -134,6 +146,7 @@ struct sony_laptop_input_s {
spinlock_t fifo_lock;
struct workqueue_struct *wq;
};
+
static struct sony_laptop_input_s sony_laptop_input = {
.users = ATOMIC_INIT(0),
};
@@ -211,6 +224,14 @@ static int sony_laptop_input_index[] = {
48, /* 61 SONYPI_EVENT_WIRELESS_OFF */
49, /* 62 SONYPI_EVENT_ZOOM_IN_PRESSED */
50, /* 63 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ 51, /* 64 SONYPI_EVENT_CD_EJECT_PRESSED */
+ 52, /* 65 SONYPI_EVENT_MODEKEY_PRESSED */
+ 53, /* 66 SONYPI_EVENT_PKEY_P4 */
+ 54, /* 67 SONYPI_EVENT_PKEY_P5 */
+ 55, /* 68 SONYPI_EVENT_SETTINGKEY_PRESSED */
+ 56, /* 69 SONYPI_EVENT_VOLUME_INC_PRESSED */
+ 57, /* 70 SONYPI_EVENT_VOLUME_DEC_PRESSED */
+ -1, /* 71 SONYPI_EVENT_BRIGHTNESS_PRESSED */
};
static int sony_laptop_input_keycode_map[] = {
@@ -264,7 +285,14 @@ static int sony_laptop_input_keycode_map[] = {
KEY_WLAN, /* 47 SONYPI_EVENT_WIRELESS_ON */
KEY_WLAN, /* 48 SONYPI_EVENT_WIRELESS_OFF */
KEY_ZOOMIN, /* 49 SONYPI_EVENT_ZOOM_IN_PRESSED */
- KEY_ZOOMOUT /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ KEY_ZOOMOUT, /* 50 SONYPI_EVENT_ZOOM_OUT_PRESSED */
+ KEY_EJECTCD, /* 51 SONYPI_EVENT_CD_EJECT_PRESSED */
+ KEY_F13, /* 52 SONYPI_EVENT_MODEKEY_PRESSED */
+ KEY_PROG4, /* 53 SONYPI_EVENT_PKEY_P4 */
+ KEY_F14, /* 54 SONYPI_EVENT_PKEY_P5 */
+ KEY_F15, /* 55 SONYPI_EVENT_SETTINGKEY_PRESSED */
+ KEY_VOLUMEUP, /* 56 SONYPI_EVENT_VOLUME_INC_PRESSED */
+ KEY_VOLUMEDOWN, /* 57 SONYPI_EVENT_VOLUME_DEC_PRESSED */
};
/* release buttons after a short delay if pressed */
@@ -369,7 +397,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
sony_laptop_input.wq = create_singlethread_workqueue("sony-laptop");
if (!sony_laptop_input.wq) {
printk(KERN_ERR DRV_PFX
- "Unabe to create workqueue.\n");
+ "Unable to create workqueue.\n");
error = -ENXIO;
goto err_free_kfifo;
}
@@ -689,6 +717,31 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
return -1;
}
+static int sony_find_snc_handle(int handle)
+{
+ int i;
+ int result;
+
+ for (i = 0x20; i < 0x30; i++) {
+ acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
+ if (result == handle)
+ return i-0x20;
+ }
+
+ return -1;
+}
+
+static int sony_call_snc_handle(int handle, int argument, int *result)
+{
+ int offset = sony_find_snc_handle(handle);
+
+ if (offset < 0)
+ return -1;
+
+ return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
+ result);
+}
+
/*
* sony_nc_values input/output validate functions
*/
@@ -809,87 +862,53 @@ struct sony_nc_event {
u8 event;
};
-static struct sony_nc_event *sony_nc_events;
-
-/* Vaio C* --maybe also FE*, N* and AR* ?-- special init sequence
- * for Fn keys
- */
-static int sony_nc_C_enable(const struct dmi_system_id *id)
-{
- int result = 0;
-
- printk(KERN_NOTICE DRV_PFX "detected %s\n", id->ident);
-
- sony_nc_events = id->driver_data;
-
- if (acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x4, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x2, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0x10, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x0, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN03", 0x2, &result) < 0
- || acpi_callsetfunc(sony_nc_acpi_handle, "SN07", 0x101, &result) < 0) {
- printk(KERN_WARNING DRV_PFX "failed to initialize SNC, some "
- "functionalities may be missing\n");
- return 1;
- }
- return 0;
-}
-
-static struct sony_nc_event sony_C_events[] = {
+static struct sony_nc_event sony_100_events[] = {
+ { 0x90, SONYPI_EVENT_PKEY_P1 },
+ { 0x10, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x91, SONYPI_EVENT_PKEY_P2 },
+ { 0x11, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0x81, SONYPI_EVENT_FNKEY_F1 },
{ 0x01, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x82, SONYPI_EVENT_FNKEY_F2 },
+ { 0x02, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x83, SONYPI_EVENT_FNKEY_F3 },
+ { 0x03, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x84, SONYPI_EVENT_FNKEY_F4 },
+ { 0x04, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x85, SONYPI_EVENT_FNKEY_F5 },
{ 0x05, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x86, SONYPI_EVENT_FNKEY_F6 },
{ 0x06, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x87, SONYPI_EVENT_FNKEY_F7 },
{ 0x07, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x89, SONYPI_EVENT_FNKEY_F9 },
+ { 0x09, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x8A, SONYPI_EVENT_FNKEY_F10 },
{ 0x0A, SONYPI_EVENT_FNKEY_RELEASED },
{ 0x8C, SONYPI_EVENT_FNKEY_F12 },
{ 0x0C, SONYPI_EVENT_FNKEY_RELEASED },
+ { 0x9f, SONYPI_EVENT_CD_EJECT_PRESSED },
+ { 0x1f, SONYPI_EVENT_ANYBUTTON_RELEASED },
{ 0, 0 },
};
-/* SNC-only model map */
-static const struct dmi_system_id sony_nc_ids[] = {
- {
- .ident = "Sony Vaio FE Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"),
- },
- },
- {
- .ident = "Sony Vaio FZ Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"),
- },
- },
- {
- .ident = "Sony Vaio C Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-C"),
- },
- },
- {
- .ident = "Sony Vaio N Series",
- .callback = sony_nc_C_enable,
- .driver_data = sony_C_events,
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
- DMI_MATCH(DMI_PRODUCT_NAME, "VGN-N"),
- },
- },
- { }
+static struct sony_nc_event sony_127_events[] = {
+ { 0x81, SONYPI_EVENT_MODEKEY_PRESSED },
+ { 0x01, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x82, SONYPI_EVENT_PKEY_P1 },
+ { 0x02, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x83, SONYPI_EVENT_PKEY_P2 },
+ { 0x03, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x84, SONYPI_EVENT_PKEY_P3 },
+ { 0x04, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x85, SONYPI_EVENT_PKEY_P4 },
+ { 0x05, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x86, SONYPI_EVENT_PKEY_P5 },
+ { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x06, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0x87, SONYPI_EVENT_SETTINGKEY_PRESSED },
+ { 0x07, SONYPI_EVENT_ANYBUTTON_RELEASED },
+ { 0, 0 },
};
/*
@@ -897,38 +916,59 @@ static const struct dmi_system_id sony_nc_ids[] = {
*/
static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
{
- struct sony_nc_event *evmap;
u32 ev = event;
- int result;
- if (ev == 0x92) {
- /* read the key pressed from EC.GECR
- * A call to SN07 with 0x0202 will do it as well respecting
- * the current protocol on different OSes
- *
- * Note: the path for GECR may be
- * \_SB.PCI0.LPCB.EC (C, FE, AR, N and friends)
- * \_SB.PCI0.PIB.EC0 (VGN-FR notifications are sent directly, no GECR)
- *
- * TODO: we may want to do the same for the older GHKE -need
- * dmi list- so this snippet may become one more callback.
- */
- if (acpi_callsetfunc(handle, "SN07", 0x0202, &result) < 0)
- dprintk("sony_acpi_notify, unable to decode event 0x%.2x\n", ev);
- else
- ev = result & 0xFF;
- }
+ if (ev >= 0x90) {
+ /* New-style event */
+ int result;
+ int key_handle = 0;
+ ev -= 0x90;
+
+ if (sony_find_snc_handle(0x100) == ev)
+ key_handle = 0x100;
+ if (sony_find_snc_handle(0x127) == ev)
+ key_handle = 0x127;
+
+ if (key_handle) {
+ struct sony_nc_event *key_event;
+
+ if (sony_call_snc_handle(key_handle, 0x200, &result)) {
+ dprintk("sony_acpi_notify, unable to decode"
+ " event 0x%.2x 0x%.2x\n", key_handle,
+ ev);
+ /* restore the original event */
+ ev = event;
+ } else {
+ ev = result & 0xFF;
+
+ if (key_handle == 0x100)
+ key_event = sony_100_events;
+ else
+ key_event = sony_127_events;
+
+ for (; key_event->data; key_event++) {
+ if (key_event->data == ev) {
+ ev = key_event->event;
+ break;
+ }
+ }
- if (sony_nc_events)
- for (evmap = sony_nc_events; evmap->event; evmap++) {
- if (evmap->data == ev) {
- ev = evmap->event;
- break;
+ if (!key_event->data)
+ printk(KERN_INFO DRV_PFX
+ "Unknown event: 0x%x 0x%x\n",
+ key_handle,
+ ev);
+ else
+ sony_laptop_report_input_event(ev);
}
+ } else if (sony_find_snc_handle(0x124) == ev) {
+ sony_nc_rfkill_update();
+ return;
}
+ } else
+ sony_laptop_report_input_event(ev);
dprintk("sony_acpi_notify, event: 0x%.2x\n", ev);
- sony_laptop_report_input_event(ev);
acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev);
}
@@ -953,9 +993,25 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
/*
* ACPI device
*/
+static int sony_nc_function_setup(struct acpi_device *device)
+{
+ int result;
+
+ /* Enable all events */
+ acpi_callsetfunc(sony_nc_acpi_handle, "SN02", 0xffff, &result);
+
+ /* Setup hotkeys */
+ sony_call_snc_handle(0x0100, 0, &result);
+ sony_call_snc_handle(0x0101, 0, &result);
+ sony_call_snc_handle(0x0102, 0x100, &result);
+
+ return 0;
+}
+
static int sony_nc_resume(struct acpi_device *device)
{
struct sony_nc_value *item;
+ acpi_handle handle;
for (item = sony_nc_values; item->name; item++) {
int ret;
@@ -970,13 +1026,188 @@ static int sony_nc_resume(struct acpi_device *device)
}
}
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+ &handle))) {
+ if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+ dprintk("ECON Method failed\n");
+ }
+
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+ &handle))) {
+ dprintk("Doing SNC setup\n");
+ sony_nc_function_setup(device);
+ }
+
/* set the last requested brightness level */
if (sony_backlight_device &&
!sony_backlight_update_status(sony_backlight_device))
printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
- /* re-initialize models with specific requirements */
- dmi_check_system(sony_nc_ids);
+ return 0;
+}
+
+static void sony_nc_rfkill_cleanup(void)
+{
+ int i;
+
+ for (i = 0; i < SONY_RFKILL_MAX; i++) {
+ if (sony_rfkill_devices[i])
+ rfkill_unregister(sony_rfkill_devices[i]);
+ }
+}
+
+static int sony_nc_rfkill_get(void *data, enum rfkill_state *state)
+{
+ int result;
+ int argument = sony_rfkill_address[(long) data];
+
+ sony_call_snc_handle(0x124, 0x200, &result);
+ if (result & 0x1) {
+ sony_call_snc_handle(0x124, argument, &result);
+ if (result & 0xf)
+ *state = RFKILL_STATE_UNBLOCKED;
+ else
+ *state = RFKILL_STATE_SOFT_BLOCKED;
+ } else {
+ *state = RFKILL_STATE_HARD_BLOCKED;
+ }
+
+ return 0;
+}
+
+static int sony_nc_rfkill_set(void *data, enum rfkill_state state)
+{
+ int result;
+ int argument = sony_rfkill_address[(long) data] + 0x100;
+
+ if (state == RFKILL_STATE_UNBLOCKED)
+ argument |= 0xff0000;
+
+ return sony_call_snc_handle(0x124, argument, &result);
+}
+
+static int sony_nc_setup_wifi_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wifi_rfkill;
+
+ sony_wifi_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WLAN);
+ if (!sony_wifi_rfkill)
+ return -1;
+ sony_wifi_rfkill->name = "sony-wifi";
+ sony_wifi_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wifi_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wifi_rfkill->user_claim_unsupported = 1;
+ sony_wifi_rfkill->data = (void *)SONY_WIFI;
+ err = rfkill_register(sony_wifi_rfkill);
+ if (err)
+ rfkill_free(sony_wifi_rfkill);
+ else
+ sony_rfkill_devices[SONY_WIFI] = sony_wifi_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_bluetooth_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_bluetooth_rfkill;
+
+ sony_bluetooth_rfkill = rfkill_allocate(&device->dev,
+ RFKILL_TYPE_BLUETOOTH);
+ if (!sony_bluetooth_rfkill)
+ return -1;
+ sony_bluetooth_rfkill->name = "sony-bluetooth";
+ sony_bluetooth_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_bluetooth_rfkill->get_state = sony_nc_rfkill_get;
+ sony_bluetooth_rfkill->user_claim_unsupported = 1;
+ sony_bluetooth_rfkill->data = (void *)SONY_BLUETOOTH;
+ err = rfkill_register(sony_bluetooth_rfkill);
+ if (err)
+ rfkill_free(sony_bluetooth_rfkill);
+ else
+ sony_rfkill_devices[SONY_BLUETOOTH] = sony_bluetooth_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_wwan_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wwan_rfkill;
+
+ sony_wwan_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WWAN);
+ if (!sony_wwan_rfkill)
+ return -1;
+ sony_wwan_rfkill->name = "sony-wwan";
+ sony_wwan_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wwan_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wwan_rfkill->user_claim_unsupported = 1;
+ sony_wwan_rfkill->data = (void *)SONY_WWAN;
+ err = rfkill_register(sony_wwan_rfkill);
+ if (err)
+ rfkill_free(sony_wwan_rfkill);
+ else
+ sony_rfkill_devices[SONY_WWAN] = sony_wwan_rfkill;
+ return err;
+}
+
+static int sony_nc_setup_wimax_rfkill(struct acpi_device *device)
+{
+ int err = 0;
+ struct rfkill *sony_wimax_rfkill;
+
+ sony_wimax_rfkill = rfkill_allocate(&device->dev, RFKILL_TYPE_WIMAX);
+ if (!sony_wimax_rfkill)
+ return -1;
+ sony_wimax_rfkill->name = "sony-wimax";
+ sony_wimax_rfkill->toggle_radio = sony_nc_rfkill_set;
+ sony_wimax_rfkill->get_state = sony_nc_rfkill_get;
+ sony_wimax_rfkill->user_claim_unsupported = 1;
+ sony_wimax_rfkill->data = (void *)SONY_WIMAX;
+ err = rfkill_register(sony_wimax_rfkill);
+ if (err)
+ rfkill_free(sony_wimax_rfkill);
+ else
+ sony_rfkill_devices[SONY_WIMAX] = sony_wimax_rfkill;
+ return err;
+}
+
+static void sony_nc_rfkill_update()
+{
+ int i;
+ enum rfkill_state state;
+
+ for (i = 0; i < SONY_RFKILL_MAX; i++) {
+ if (sony_rfkill_devices[i]) {
+ sony_rfkill_devices[i]->
+ get_state(sony_rfkill_devices[i]->data,
+ &state);
+ rfkill_force_state(sony_rfkill_devices[i], state);
+ }
+ }
+}
+
+static int sony_nc_rfkill_setup(struct acpi_device *device)
+{
+ int result, ret;
+
+ if (sony_find_snc_handle(0x124) == -1)
+ return -1;
+
+ ret = sony_call_snc_handle(0x124, 0xb00, &result);
+ if (ret) {
+ printk(KERN_INFO DRV_PFX
+ "Unable to enumerate rfkill devices: %x\n", ret);
+ return ret;
+ }
+
+ if (result & 0x1)
+ sony_nc_setup_wifi_rfkill(device);
+ if (result & 0x2)
+ sony_nc_setup_bluetooth_rfkill(device);
+ if (result & 0x1c)
+ sony_nc_setup_wwan_rfkill(device);
+ if (result & 0x20)
+ sony_nc_setup_wimax_rfkill(device);
return 0;
}
@@ -1024,11 +1255,24 @@ static int sony_nc_add(struct acpi_device *device)
dprintk("_INI Method failed\n");
}
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "ECON",
+ &handle))) {
+ if (acpi_callsetfunc(sony_nc_acpi_handle, "ECON", 1, NULL))
+ dprintk("ECON Method failed\n");
+ }
+
+ if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
+ &handle))) {
+ dprintk("Doing SNC setup\n");
+ sony_nc_function_setup(device);
+ sony_nc_rfkill_setup(device);
+ }
+
/* setup input devices and helper fifo */
result = sony_laptop_setup_input(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to create input devices.\n");
+ "Unable to create input devices.\n");
goto outwalk;
}
@@ -1063,9 +1307,6 @@ static int sony_nc_add(struct acpi_device *device)
}
- /* initialize models with specific requirements */
- dmi_check_system(sony_nc_ids);
-
result = sony_pf_add();
if (result)
goto outbacklight;
@@ -1131,6 +1372,7 @@ static int sony_nc_add(struct acpi_device *device)
sony_laptop_remove_input();
outwalk:
+ sony_nc_rfkill_cleanup();
return result;
}
@@ -1156,6 +1398,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
sony_pf_remove();
sony_laptop_remove_input();
+ sony_nc_rfkill_cleanup();
dprintk(SONY_NC_DRIVER_NAME " removed.\n");
return 0;
@@ -1195,7 +1438,6 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_TYPE1_OFFSET 0x04
#define SONYPI_TYPE2_OFFSET 0x12
#define SONYPI_TYPE3_OFFSET 0x12
-#define SONYPI_TYPE4_OFFSET 0x12
struct sony_pic_ioport {
struct acpi_resource_io io1;
@@ -1328,6 +1570,7 @@ static struct sonypi_event sonypi_pkeyev[] = {
{ 0x01, SONYPI_EVENT_PKEY_P1 },
{ 0x02, SONYPI_EVENT_PKEY_P2 },
{ 0x04, SONYPI_EVENT_PKEY_P3 },
+ { 0x20, SONYPI_EVENT_PKEY_P1 },
{ 0, 0 }
};
@@ -1371,6 +1614,7 @@ static struct sonypi_event sonypi_zoomev[] = {
{ 0x39, SONYPI_EVENT_ZOOM_PRESSED },
{ 0x10, SONYPI_EVENT_ZOOM_IN_PRESSED },
{ 0x20, SONYPI_EVENT_ZOOM_OUT_PRESSED },
+ { 0x04, SONYPI_EVENT_ZOOM_PRESSED },
{ 0, 0 }
};
@@ -1401,6 +1645,19 @@ static struct sonypi_event sonypi_batteryev[] = {
{ 0, 0 }
};
+/* The set of possible volume events */
+static struct sonypi_event sonypi_volumeev[] = {
+ { 0x01, SONYPI_EVENT_VOLUME_INC_PRESSED },
+ { 0x02, SONYPI_EVENT_VOLUME_DEC_PRESSED },
+ { 0, 0 }
+};
+
+/* The set of possible brightness events */
+static struct sonypi_event sonypi_brightnessev[] = {
+ { 0x80, SONYPI_EVENT_BRIGHTNESS_PRESSED },
+ { 0, 0 }
+};
+
static struct sonypi_eventtypes type1_events[] = {
{ 0, 0xffffffff, sonypi_releaseev },
{ 0x70, SONYPI_MEYE_MASK, sonypi_meyeev },
@@ -1438,17 +1695,11 @@ static struct sonypi_eventtypes type3_events[] = {
{ 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
{ 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x31, SONYPI_PKEY_MASK, sonypi_pkeyev },
- { 0 },
-};
-static struct sonypi_eventtypes type4_events[] = {
- { 0, 0xffffffff, sonypi_releaseev },
- { 0x21, SONYPI_FNKEY_MASK, sonypi_fnkeyev },
- { 0x31, SONYPI_WIRELESS_MASK, sonypi_wlessev },
- { 0x31, SONYPI_MEMORYSTICK_MASK, sonypi_memorystickev },
- { 0x41, SONYPI_BATTERY_MASK, sonypi_batteryev },
{ 0x05, SONYPI_PKEY_MASK, sonypi_pkeyev },
{ 0x05, SONYPI_ZOOM_MASK, sonypi_zoomev },
{ 0x05, SONYPI_CAPTURE_MASK, sonypi_captureev },
+ { 0x05, SONYPI_PKEY_MASK, sonypi_volumeev },
+ { 0x05, SONYPI_PKEY_MASK, sonypi_brightnessev },
{ 0 },
};
@@ -1511,11 +1762,11 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v)
/*
* minidrivers for SPIC models
*/
-static int type4_handle_irq(const u8 data_mask, const u8 ev)
+static int type3_handle_irq(const u8 data_mask, const u8 ev)
{
/*
* 0x31 could mean we have to take some extra action and wait for
- * the next irq for some Type4 models, it will generate a new
+ * the next irq for some Type3 models, it will generate a new
* irq and we can read new data from the device:
* - 0x5c and 0x5f requires 0xA0
* - 0x61 requires 0xB3
@@ -1545,16 +1796,10 @@ static struct device_ctrl spic_types[] = {
},
{
.model = SONYPI_DEVICE_TYPE3,
- .handle_irq = NULL,
+ .handle_irq = type3_handle_irq,
.evport_offset = SONYPI_TYPE3_OFFSET,
.event_types = type3_events,
},
- {
- .model = SONYPI_DEVICE_TYPE4,
- .handle_irq = type4_handle_irq,
- .evport_offset = SONYPI_TYPE4_OFFSET,
- .event_types = type4_events,
- },
};
static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
@@ -1578,14 +1823,21 @@ static void sony_pic_detect_device_type(struct sony_pic_dev *dev)
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH7_1, NULL);
if (pcidev) {
- dev->control = &spic_types[3];
+ dev->control = &spic_types[2];
goto out;
}
pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_ICH8_4, NULL);
if (pcidev) {
- dev->control = &spic_types[3];
+ dev->control = &spic_types[2];
+ goto out;
+ }
+
+ pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_ICH9_1, NULL);
+ if (pcidev) {
+ dev->control = &spic_types[2];
goto out;
}
@@ -1598,8 +1850,7 @@ out:
printk(KERN_INFO DRV_PFX "detected Type%d model\n",
dev->control->model == SONYPI_DEVICE_TYPE1 ? 1 :
- dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 :
- dev->control->model == SONYPI_DEVICE_TYPE3 ? 3 : 4);
+ dev->control->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
}
/* camera tests and poweron/poweroff */
@@ -1754,17 +2005,14 @@ int sony_pic_camera_command(int command, u8 value)
EXPORT_SYMBOL(sony_pic_camera_command);
/* gprs/edge modem (SZ460N and SZ210P), thanks to Joshua Wise */
-static void sony_pic_set_wwanpower(u8 state)
+static void __sony_pic_set_wwanpower(u8 state)
{
state = !!state;
- mutex_lock(&spic_dev.lock);
- if (spic_dev.wwan_power == state) {
- mutex_unlock(&spic_dev.lock);
+ if (spic_dev.wwan_power == state)
return;
- }
sony_pic_call2(0xB0, state);
+ sony_pic_call1(0x82);
spic_dev.wwan_power = state;
- mutex_unlock(&spic_dev.lock);
}
static ssize_t sony_pic_wwanpower_store(struct device *dev,
@@ -1776,7 +2024,9 @@ static ssize_t sony_pic_wwanpower_store(struct device *dev,
return -EINVAL;
value = simple_strtoul(buffer, NULL, 10);
- sony_pic_set_wwanpower(value);
+ mutex_lock(&spic_dev.lock);
+ __sony_pic_set_wwanpower(value);
+ mutex_unlock(&spic_dev.lock);
return count;
}
@@ -1929,10 +2179,15 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
static int sonypi_misc_open(struct inode *inode, struct file *file)
{
/* Flush input queue on first open */
- lock_kernel();
+ unsigned long flags;
+
+ spin_lock_irqsave(sonypi_compat.fifo->lock, flags);
+
if (atomic_inc_return(&sonypi_compat.open_count) == 1)
- kfifo_reset(sonypi_compat.fifo);
- unlock_kernel();
+ __kfifo_reset(sonypi_compat.fifo);
+
+ spin_unlock_irqrestore(sonypi_compat.fifo->lock, flags);
+
return 0;
}
@@ -1985,8 +2240,8 @@ static int ec_read16(u8 addr, u16 *value)
return 0;
}
-static int sonypi_misc_ioctl(struct inode *ip, struct file *fp,
- unsigned int cmd, unsigned long arg)
+static long sonypi_misc_ioctl(struct file *fp, unsigned int cmd,
+ unsigned long arg)
{
int ret = 0;
void __user *argp = (void __user *)arg;
@@ -2120,7 +2375,7 @@ static const struct file_operations sonypi_misc_fops = {
.open = sonypi_misc_open,
.release = sonypi_misc_release,
.fasync = sonypi_misc_fasync,
- .ioctl = sonypi_misc_ioctl,
+ .unlocked_ioctl = sonypi_misc_ioctl,
};
static struct miscdevice sonypi_misc_device = {
@@ -2561,7 +2816,7 @@ static int sony_pic_add(struct acpi_device *device)
result = sony_pic_possible_resources(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to read possible resources.\n");
+ "Unable to read possible resources.\n");
goto err_free_resources;
}
@@ -2569,7 +2824,7 @@ static int sony_pic_add(struct acpi_device *device)
result = sony_laptop_setup_input(device);
if (result) {
printk(KERN_ERR DRV_PFX
- "Unabe to create input devices.\n");
+ "Unable to create input devices.\n");
goto err_free_resources;
}
diff --git a/drivers/platform/x86/tc1100-wmi.c b/drivers/platform/x86/tc1100-wmi.c
index b4a4aa9ee48..44166003d4e 100644
--- a/drivers/platform/x86/tc1100-wmi.c
+++ b/drivers/platform/x86/tc1100-wmi.c
@@ -94,9 +94,8 @@ static int get_state(u32 *out, u8 instance)
return -ENODEV;
obj = (union acpi_object *) result.pointer;
- if (obj && obj->type == ACPI_TYPE_BUFFER &&
- obj->buffer.length == sizeof(u32)) {
- tmp = *((u32 *) obj->buffer.pointer);
+ if (obj && obj->type == ACPI_TYPE_INTEGER) {
+ tmp = obj->integer.value;
} else {
tmp = 0;
}
@@ -109,7 +108,7 @@ static int get_state(u32 *out, u8 instance)
*out = (tmp == 3) ? 1 : 0;
return 0;
case TC1100_INSTANCE_JOGDIAL:
- *out = (tmp == 1) ? 1 : 0;
+ *out = (tmp == 1) ? 0 : 1;
return 0;
default:
return -ENODEV;
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index d2433204a40..a40b075743d 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -3,7 +3,7 @@
*
*
* Copyright (C) 2004-2005 Borislav Deianov <borislav@users.sf.net>
- * Copyright (C) 2006-2008 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+ * Copyright (C) 2006-2009 Henrique de Moraes Holschuh <hmh@hmh.eng.br>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,7 +22,7 @@
*/
#define TPACPI_VERSION "0.22"
-#define TPACPI_SYSFS_VERSION 0x020200
+#define TPACPI_SYSFS_VERSION 0x020300
/*
* Changelog:
@@ -54,6 +54,7 @@
#include <linux/string.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
#include <linux/delay.h>
@@ -172,29 +173,26 @@ enum {
TPACPI_RFK_UWB_SW_ID,
};
-/* Debugging */
+/* printk headers */
#define TPACPI_LOG TPACPI_FILE ": "
-#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
-#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
-#define TPACPI_ERR KERN_ERR TPACPI_LOG
-#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
-#define TPACPI_INFO KERN_INFO TPACPI_LOG
-#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
-
+#define TPACPI_EMERG KERN_EMERG TPACPI_LOG
+#define TPACPI_ALERT KERN_ALERT TPACPI_LOG
+#define TPACPI_CRIT KERN_CRIT TPACPI_LOG
+#define TPACPI_ERR KERN_ERR TPACPI_LOG
+#define TPACPI_WARN KERN_WARNING TPACPI_LOG
+#define TPACPI_NOTICE KERN_NOTICE TPACPI_LOG
+#define TPACPI_INFO KERN_INFO TPACPI_LOG
+#define TPACPI_DEBUG KERN_DEBUG TPACPI_LOG
+
+/* Debugging printk groups */
#define TPACPI_DBG_ALL 0xffff
+#define TPACPI_DBG_DISCLOSETASK 0x8000
#define TPACPI_DBG_INIT 0x0001
#define TPACPI_DBG_EXIT 0x0002
-#define dbg_printk(a_dbg_level, format, arg...) \
- do { if (dbg_level & a_dbg_level) \
- printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
- } while (0)
-#ifdef CONFIG_THINKPAD_ACPI_DEBUG
-#define vdbg_printk(a_dbg_level, format, arg...) \
- dbg_printk(a_dbg_level, format, ## arg)
-static const char *str_supported(int is_supported);
-#else
-#define vdbg_printk(a_dbg_level, format, arg...)
-#endif
+#define TPACPI_DBG_RFKILL 0x0004
+#define TPACPI_DBG_HKEY 0x0008
+#define TPACPI_DBG_FAN 0x0010
+#define TPACPI_DBG_BRGHT 0x0020
#define onoff(status, bit) ((status) & (1 << (bit)) ? "on" : "off")
#define enabled(status, bit) ((status) & (1 << (bit)) ? "enabled" : "disabled")
@@ -277,7 +275,6 @@ static struct {
static struct {
u16 hotkey_mask_ff:1;
- u16 bright_cmos_ec_unsync:1;
} tp_warned;
struct thinkpad_id_data {
@@ -326,6 +323,39 @@ static int tpacpi_uwb_emulstate;
#endif
+/*************************************************************************
+ * Debugging helpers
+ */
+
+#define dbg_printk(a_dbg_level, format, arg...) \
+ do { if (dbg_level & (a_dbg_level)) \
+ printk(TPACPI_DEBUG "%s: " format, __func__ , ## arg); \
+ } while (0)
+
+#ifdef CONFIG_THINKPAD_ACPI_DEBUG
+#define vdbg_printk dbg_printk
+static const char *str_supported(int is_supported);
+#else
+#define vdbg_printk(a_dbg_level, format, arg...) \
+ do { } while (0)
+#endif
+
+static void tpacpi_log_usertask(const char * const what)
+{
+ printk(TPACPI_DEBUG "%s: access by process with PID %d\n",
+ what, task_tgid_vnr(current));
+}
+
+#define tpacpi_disclose_usertask(what, format, arg...) \
+ do { \
+ if (unlikely( \
+ (dbg_level & TPACPI_DBG_DISCLOSETASK) && \
+ (tpacpi_lifecycle == TPACPI_LIFE_RUNNING))) { \
+ printk(TPACPI_DEBUG "%s: PID %d: " format, \
+ what, task_tgid_vnr(current), ## arg); \
+ } \
+ } while (0)
+
/****************************************************************************
****************************************************************************
*
@@ -989,10 +1019,13 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
/* try to set the initial state as the default for the rfkill
* type, since we ask the firmware to preserve it across S5 in
* NVRAM */
- rfkill_set_default(rfktype,
+ if (rfkill_set_default(rfktype,
(initial_state == RFKILL_STATE_UNBLOCKED) ?
RFKILL_STATE_UNBLOCKED :
- RFKILL_STATE_SOFT_BLOCKED);
+ RFKILL_STATE_SOFT_BLOCKED) == -EPERM)
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "Default state for %s cannot be changed\n",
+ name);
}
*rfk = rfkill_allocate(&tpacpi_pdev->dev, rfktype);
@@ -1020,6 +1053,21 @@ static int __init tpacpi_new_rfkill(const unsigned int id,
return 0;
}
+static void printk_deprecated_attribute(const char * const what,
+ const char * const details)
+{
+ tpacpi_log_usertask("deprecated sysfs attribute");
+ printk(TPACPI_WARN "WARNING: sysfs attribute %s is deprecated and "
+ "will be removed. %s\n",
+ what, details);
+}
+
+static void printk_deprecated_rfkill_attribute(const char * const what)
+{
+ printk_deprecated_attribute(what,
+ "Please switch to generic rfkill before year 2010");
+}
+
/*************************************************************************
* thinkpad-acpi driver attributes
*/
@@ -1382,7 +1430,6 @@ static enum { /* Reasons for waking up */
static int hotkey_autosleep_ack;
-static int hotkey_orig_status;
static u32 hotkey_orig_mask;
static u32 hotkey_all_mask;
static u32 hotkey_reserved_mask;
@@ -1529,9 +1576,9 @@ static int hotkey_status_get(int *status)
return 0;
}
-static int hotkey_status_set(int status)
+static int hotkey_status_set(bool enable)
{
- if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", status))
+ if (!acpi_evalf(hkey_handle, NULL, "MHKC", "vd", enable ? 1 : 0))
return -EIO;
return 0;
@@ -1847,6 +1894,9 @@ static ssize_t hotkey_enable_show(struct device *dev,
{
int res, status;
+ printk_deprecated_attribute("hotkey_enable",
+ "Hotkey reporting is always enabled");
+
res = hotkey_status_get(&status);
if (res)
return res;
@@ -1859,14 +1909,17 @@ static ssize_t hotkey_enable_store(struct device *dev,
const char *buf, size_t count)
{
unsigned long t;
- int res;
+
+ printk_deprecated_attribute("hotkey_enable",
+ "Hotkeys can be disabled through hotkey_mask");
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
- res = hotkey_status_set(t);
+ if (t == 0)
+ return -EPERM;
- return (res) ? res : count;
+ return count;
}
static struct device_attribute dev_attr_hotkey_enable =
@@ -1910,6 +1963,8 @@ static ssize_t hotkey_mask_store(struct device *dev,
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_mask", "set to 0x%08lx\n", t);
+
return (res) ? res : count;
}
@@ -1922,7 +1977,7 @@ static ssize_t hotkey_bios_enabled_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", hotkey_orig_status);
+ return sprintf(buf, "0\n");
}
static struct device_attribute dev_attr_hotkey_bios_enabled =
@@ -1996,6 +2051,8 @@ static ssize_t hotkey_source_mask_store(struct device *dev,
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_source_mask", "set to 0x%08lx\n", t);
+
return count;
}
@@ -2028,6 +2085,8 @@ static ssize_t hotkey_poll_freq_store(struct device *dev,
hotkey_poll_setup(1);
mutex_unlock(&hotkey_mutex);
+ tpacpi_disclose_usertask("hotkey_poll_freq", "set to %lu\n", t);
+
return count;
}
@@ -2197,11 +2256,11 @@ static void hotkey_exit(void)
kfree(hotkey_keycode_map);
if (tp_features.hotkey) {
- dbg_printk(TPACPI_DBG_EXIT,
+ dbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_HKEY,
"restoring original hot key mask\n");
/* no short-circuit boolean operator below! */
if ((hotkey_mask_set(hotkey_orig_mask) |
- hotkey_status_set(hotkey_orig_status)) != 0)
+ hotkey_status_set(false)) != 0)
printk(TPACPI_ERR
"failed to restore hot key mask "
"to BIOS defaults\n");
@@ -2327,7 +2386,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
int status;
int hkeyv;
- vdbg_printk(TPACPI_DBG_INIT, "initializing hotkey subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "initializing hotkey subdriver\n");
BUG_ON(!tpacpi_inputdev);
BUG_ON(tpacpi_inputdev->open != NULL ||
@@ -2344,7 +2404,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* hotkey not supported on 570 */
tp_features.hotkey = hkey_handle != NULL;
- vdbg_printk(TPACPI_DBG_INIT, "hotkeys are %s\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "hotkeys are %s\n",
str_supported(tp_features.hotkey));
if (!tp_features.hotkey)
@@ -2376,10 +2437,14 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
* T4x, X31, and later
*/
tp_features.hotkey_mask = 1;
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "firmware HKEY interface version: 0x%x\n",
+ hkeyv);
}
}
- vdbg_printk(TPACPI_DBG_INIT, "hotkey masks are %s\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "hotkey masks are %s\n",
str_supported(tp_features.hotkey_mask));
if (tp_features.hotkey_mask) {
@@ -2396,10 +2461,6 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
/* hotkey_source_mask *must* be zero for
* the first hotkey_mask_get */
- res = hotkey_status_get(&hotkey_orig_status);
- if (res)
- goto err_exit;
-
if (tp_features.hotkey_mask) {
res = hotkey_mask_get();
if (res)
@@ -2422,7 +2483,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
hotkey_source_mask = TPACPI_HKEY_NVRAM_GOOD_MASK;
}
- vdbg_printk(TPACPI_DBG_INIT,
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"hotkey source mask 0x%08x, polling freq %d\n",
hotkey_source_mask, hotkey_poll_freq);
#endif
@@ -2476,12 +2537,12 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
}
if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO) {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using Lenovo default hot key map\n");
memcpy(hotkey_keycode_map, &lenovo_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
} else {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
"using IBM default hot key map\n");
memcpy(hotkey_keycode_map, &ibm_keycode_map,
TPACPI_HOTKEY_MAP_SIZE);
@@ -2538,8 +2599,9 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
| (1 << TP_ACPI_HOTKEYSCAN_FNEND);
}
- dbg_printk(TPACPI_DBG_INIT, "enabling hot key handling\n");
- res = hotkey_status_set(1);
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "enabling firmware HKEY event interface...\n");
+ res = hotkey_status_set(true);
if (res) {
hotkey_exit();
return res;
@@ -2552,8 +2614,8 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)
return res;
}
- dbg_printk(TPACPI_DBG_INIT,
- "legacy hot key reporting over procfs %s\n",
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_HKEY,
+ "legacy ibm/hotkey event reporting over procfs %s\n",
(hotkey_report_mode < 2) ?
"enabled" : "disabled");
@@ -2884,9 +2946,17 @@ static int hotkey_read(char *p)
return len;
}
+static void hotkey_enabledisable_warn(void)
+{
+ tpacpi_log_usertask("procfs hotkey enable/disable");
+ WARN(1, TPACPI_WARN
+ "hotkey enable/disable functionality has been "
+ "removed from the driver. Hotkeys are always enabled.\n");
+}
+
static int hotkey_write(char *buf)
{
- int res, status;
+ int res;
u32 mask;
char *cmd;
@@ -2896,17 +2966,16 @@ static int hotkey_write(char *buf)
if (mutex_lock_killable(&hotkey_mutex))
return -ERESTARTSYS;
- status = -1;
mask = hotkey_mask;
res = 0;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- status = 1;
+ hotkey_enabledisable_warn();
} else if (strlencmp(cmd, "disable") == 0) {
- status = 0;
+ hotkey_enabledisable_warn();
+ res = -EPERM;
} else if (strlencmp(cmd, "reset") == 0) {
- status = hotkey_orig_status;
mask = hotkey_orig_mask;
} else if (sscanf(cmd, "0x%x", &mask) == 1) {
/* mask set */
@@ -2917,8 +2986,10 @@ static int hotkey_write(char *buf)
goto errexit;
}
}
- if (status != -1)
- res = hotkey_status_set(status);
+
+ if (!res)
+ tpacpi_disclose_usertask("procfs hotkey",
+ "set mask to 0x%08x\n", mask);
if (!res && mask != hotkey_mask)
res = hotkey_mask_set(mask);
@@ -2971,13 +3042,17 @@ enum {
TP_ACPI_BLTH_SAVE_STATE = 0x05, /* Save state for S4/S5 */
};
+#define TPACPI_RFK_BLUETOOTH_SW_NAME "tpacpi_bluetooth_sw"
+
static struct rfkill *tpacpi_bluetooth_rfkill;
static void bluetooth_suspend(pm_message_t state)
{
/* Try to make sure radio will resume powered off */
- acpi_evalf(NULL, NULL, "\\BLTH", "vd",
- TP_ACPI_BLTH_PWR_OFF_ON_RESUME);
+ if (!acpi_evalf(NULL, NULL, "\\BLTH", "vd",
+ TP_ACPI_BLTH_PWR_OFF_ON_RESUME))
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "bluetooth power down on resume request failed\n");
}
static int bluetooth_get_radiosw(void)
@@ -3015,6 +3090,10 @@ static void bluetooth_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_bluetooth_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int bluetooth_set_radiosw(int radio_on, int update_rfk)
@@ -3030,6 +3109,9 @@ static int bluetooth_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s bluetooth\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_bluetoothemul) {
tpacpi_bluetooth_emulstate = !!radio_on;
@@ -3060,6 +3142,8 @@ static ssize_t bluetooth_enable_show(struct device *dev,
{
int status;
+ printk_deprecated_rfkill_attribute("bluetooth_enable");
+
status = bluetooth_get_radiosw();
if (status < 0)
return status;
@@ -3075,9 +3159,13 @@ static ssize_t bluetooth_enable_store(struct device *dev,
unsigned long t;
int res;
+ printk_deprecated_rfkill_attribute("bluetooth_enable");
+
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("bluetooth_enable", "set to %ld\n", t);
+
res = bluetooth_set_radiosw(t, 1);
return (res) ? res : count;
@@ -3111,6 +3199,8 @@ static int tpacpi_bluetooth_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_bluetooth_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return bluetooth_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3121,6 +3211,9 @@ static void bluetooth_shutdown(void)
TP_ACPI_BLTH_SAVE_STATE))
printk(TPACPI_NOTICE
"failed to save bluetooth state to NVRAM\n");
+ else
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "bluestooth state saved to NVRAM\n");
}
static void bluetooth_exit(void)
@@ -3139,7 +3232,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing bluetooth subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing bluetooth subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
@@ -3148,7 +3242,8 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
tp_features.bluetooth = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GBDC", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "bluetooth is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "bluetooth is %s, status 0x%02x\n",
str_supported(tp_features.bluetooth),
status);
@@ -3163,7 +3258,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
!(status & TP_ACPI_BLUETOOTH_HWPRESENT)) {
/* no bluetooth hardware present in system */
tp_features.bluetooth = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
"bluetooth hardware not installed\n");
}
@@ -3178,7 +3273,7 @@ static int __init bluetooth_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_BLUETOOTH_SW_ID,
&tpacpi_bluetooth_rfkill,
RFKILL_TYPE_BLUETOOTH,
- "tpacpi_bluetooth_sw",
+ TPACPI_RFK_BLUETOOTH_SW_NAME,
true,
tpacpi_bluetooth_rfk_set,
tpacpi_bluetooth_rfk_get);
@@ -3211,19 +3306,27 @@ static int bluetooth_read(char *p)
static int bluetooth_write(char *buf)
{
char *cmd;
+ int state = -1;
if (!tp_features.bluetooth)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- bluetooth_set_radiosw(1, 1);
+ state = 1;
} else if (strlencmp(cmd, "disable") == 0) {
- bluetooth_set_radiosw(0, 1);
+ state = 0;
} else
return -EINVAL;
}
+ if (state != -1) {
+ tpacpi_disclose_usertask("procfs bluetooth",
+ "attempt to %s\n",
+ state ? "enable" : "disable");
+ bluetooth_set_radiosw(state, 1);
+ }
+
return 0;
}
@@ -3248,13 +3351,17 @@ enum {
off / last state */
};
+#define TPACPI_RFK_WWAN_SW_NAME "tpacpi_wwan_sw"
+
static struct rfkill *tpacpi_wan_rfkill;
static void wan_suspend(pm_message_t state)
{
/* Try to make sure radio will resume powered off */
- acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
- TP_ACPI_WGSV_PWR_OFF_ON_RESUME);
+ if (!acpi_evalf(NULL, NULL, "\\WGSV", "qvd",
+ TP_ACPI_WGSV_PWR_OFF_ON_RESUME))
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "WWAN power down on resume request failed\n");
}
static int wan_get_radiosw(void)
@@ -3292,6 +3399,10 @@ static void wan_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_wan_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int wan_set_radiosw(int radio_on, int update_rfk)
@@ -3307,6 +3418,9 @@ static int wan_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s WWAN\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_wwanemul) {
tpacpi_wwan_emulstate = !!radio_on;
@@ -3337,6 +3451,8 @@ static ssize_t wan_enable_show(struct device *dev,
{
int status;
+ printk_deprecated_rfkill_attribute("wwan_enable");
+
status = wan_get_radiosw();
if (status < 0)
return status;
@@ -3352,9 +3468,13 @@ static ssize_t wan_enable_store(struct device *dev,
unsigned long t;
int res;
+ printk_deprecated_rfkill_attribute("wwan_enable");
+
if (parse_strtoul(buf, 1, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("wwan_enable", "set to %ld\n", t);
+
res = wan_set_radiosw(t, 1);
return (res) ? res : count;
@@ -3388,6 +3508,8 @@ static int tpacpi_wan_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_wan_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return wan_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3398,6 +3520,9 @@ static void wan_shutdown(void)
TP_ACPI_WGSV_SAVE_STATE))
printk(TPACPI_NOTICE
"failed to save WWAN state to NVRAM\n");
+ else
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "WWAN state saved to NVRAM\n");
}
static void wan_exit(void)
@@ -3416,14 +3541,16 @@ static int __init wan_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing wan subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing wan subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
tp_features.wan = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GWAN", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "wan is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "wan is %s, status 0x%02x\n",
str_supported(tp_features.wan),
status);
@@ -3438,7 +3565,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
!(status & TP_ACPI_WANCARD_HWPRESENT)) {
/* no wan hardware present in system */
tp_features.wan = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
"wan hardware not installed\n");
}
@@ -3453,7 +3580,7 @@ static int __init wan_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_WWAN_SW_ID,
&tpacpi_wan_rfkill,
RFKILL_TYPE_WWAN,
- "tpacpi_wwan_sw",
+ TPACPI_RFK_WWAN_SW_NAME,
true,
tpacpi_wan_rfk_set,
tpacpi_wan_rfk_get);
@@ -3471,6 +3598,8 @@ static int wan_read(char *p)
int len = 0;
int status = wan_get_radiosw();
+ tpacpi_disclose_usertask("procfs wan", "read");
+
if (!tp_features.wan)
len += sprintf(p + len, "status:\t\tnot supported\n");
else {
@@ -3486,19 +3615,27 @@ static int wan_read(char *p)
static int wan_write(char *buf)
{
char *cmd;
+ int state = -1;
if (!tp_features.wan)
return -ENODEV;
while ((cmd = next_cmd(&buf))) {
if (strlencmp(cmd, "enable") == 0) {
- wan_set_radiosw(1, 1);
+ state = 1;
} else if (strlencmp(cmd, "disable") == 0) {
- wan_set_radiosw(0, 1);
+ state = 0;
} else
return -EINVAL;
}
+ if (state != -1) {
+ tpacpi_disclose_usertask("procfs wan",
+ "attempt to %s\n",
+ state ? "enable" : "disable");
+ wan_set_radiosw(state, 1);
+ }
+
return 0;
}
@@ -3521,6 +3658,8 @@ enum {
TP_ACPI_UWB_RADIOSSW = 0x02, /* UWB radio enabled */
};
+#define TPACPI_RFK_UWB_SW_NAME "tpacpi_uwb_sw"
+
static struct rfkill *tpacpi_uwb_rfkill;
static int uwb_get_radiosw(void)
@@ -3558,6 +3697,10 @@ static void uwb_update_rfk(void)
if (status < 0)
return;
rfkill_force_state(tpacpi_uwb_rfkill, status);
+
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "forced rfkill state to %d\n",
+ status);
}
static int uwb_set_radiosw(int radio_on, int update_rfk)
@@ -3573,6 +3716,9 @@ static int uwb_set_radiosw(int radio_on, int update_rfk)
&& radio_on)
return -EPERM;
+ vdbg_printk(TPACPI_DBG_RFKILL,
+ "will %s UWB\n", radio_on ? "enable" : "disable");
+
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
if (dbg_uwbemul) {
tpacpi_uwb_emulstate = !!radio_on;
@@ -3607,6 +3753,8 @@ static int tpacpi_uwb_rfk_get(void *data, enum rfkill_state *state)
static int tpacpi_uwb_rfk_set(void *data, enum rfkill_state state)
{
+ dbg_printk(TPACPI_DBG_RFKILL,
+ "request to change radio state to %d\n", state);
return uwb_set_radiosw((state == RFKILL_STATE_UNBLOCKED), 0);
}
@@ -3621,14 +3769,16 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
int res;
int status = 0;
- vdbg_printk(TPACPI_DBG_INIT, "initializing uwb subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "initializing uwb subdriver\n");
TPACPI_ACPIHANDLE_INIT(hkey);
tp_features.uwb = hkey_handle &&
acpi_evalf(hkey_handle, &status, "GUWB", "qd");
- vdbg_printk(TPACPI_DBG_INIT, "uwb is %s, status 0x%02x\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_RFKILL,
+ "uwb is %s, status 0x%02x\n",
str_supported(tp_features.uwb),
status);
@@ -3653,7 +3803,7 @@ static int __init uwb_init(struct ibm_init_struct *iibm)
res = tpacpi_new_rfkill(TPACPI_RFK_UWB_SW_ID,
&tpacpi_uwb_rfkill,
RFKILL_TYPE_UWB,
- "tpacpi_uwb_sw",
+ TPACPI_RFK_UWB_SW_NAME,
false,
tpacpi_uwb_rfk_set,
tpacpi_uwb_rfk_get);
@@ -4602,6 +4752,16 @@ static const char * const tpacpi_led_names[TPACPI_LED_NUMLEDS] = {
"tpacpi::unknown_led",
"tpacpi::standby",
};
+#define TPACPI_SAFE_LEDS 0x0081U
+
+static inline bool tpacpi_is_led_restricted(const unsigned int led)
+{
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+ return false;
+#else
+ return (TPACPI_SAFE_LEDS & (1 << led)) == 0;
+#endif
+}
static int led_get_status(const unsigned int led)
{
@@ -4639,16 +4799,20 @@ static int led_set_status(const unsigned int led,
switch (led_supported) {
case TPACPI_LED_570:
/* 570 */
- if (led > 7)
+ if (unlikely(led > 7))
return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
(1 << led), led_sled_arg1[ledstatus]))
rc = -EIO;
break;
case TPACPI_LED_OLD:
/* 600e/x, 770e, 770x, A21e, A2xm/p, T20-22, X20 */
- if (led > 7)
+ if (unlikely(led > 7))
return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
rc = ec_write(TPACPI_LED_EC_HLMS, (1 << led));
if (rc >= 0)
rc = ec_write(TPACPI_LED_EC_HLBL,
@@ -4659,6 +4823,10 @@ static int led_set_status(const unsigned int led,
break;
case TPACPI_LED_NEW:
/* all others */
+ if (unlikely(led >= TPACPI_LED_NUMLEDS))
+ return -EINVAL;
+ if (unlikely(tpacpi_is_led_restricted(led)))
+ return -EPERM;
if (!acpi_evalf(led_handle, NULL, NULL, "vdd",
led, led_led_arg1[ledstatus]))
rc = -EIO;
@@ -4751,6 +4919,30 @@ static void led_exit(void)
kfree(tpacpi_leds);
}
+static int __init tpacpi_init_led(unsigned int led)
+{
+ int rc;
+
+ tpacpi_leds[led].led = led;
+
+ tpacpi_leds[led].led_classdev.brightness_set = &led_sysfs_set;
+ tpacpi_leds[led].led_classdev.blink_set = &led_sysfs_blink_set;
+ if (led_supported == TPACPI_LED_570)
+ tpacpi_leds[led].led_classdev.brightness_get =
+ &led_sysfs_get;
+
+ tpacpi_leds[led].led_classdev.name = tpacpi_led_names[led];
+
+ INIT_WORK(&tpacpi_leds[led].work, led_set_status_worker);
+
+ rc = led_classdev_register(&tpacpi_pdev->dev,
+ &tpacpi_leds[led].led_classdev);
+ if (rc < 0)
+ tpacpi_leds[led].led_classdev.name = NULL;
+
+ return rc;
+}
+
static int __init led_init(struct ibm_init_struct *iibm)
{
unsigned int i;
@@ -4784,27 +4976,21 @@ static int __init led_init(struct ibm_init_struct *iibm)
}
for (i = 0; i < TPACPI_LED_NUMLEDS; i++) {
- tpacpi_leds[i].led = i;
-
- tpacpi_leds[i].led_classdev.brightness_set = &led_sysfs_set;
- tpacpi_leds[i].led_classdev.blink_set = &led_sysfs_blink_set;
- if (led_supported == TPACPI_LED_570)
- tpacpi_leds[i].led_classdev.brightness_get =
- &led_sysfs_get;
-
- tpacpi_leds[i].led_classdev.name = tpacpi_led_names[i];
-
- INIT_WORK(&tpacpi_leds[i].work, led_set_status_worker);
-
- rc = led_classdev_register(&tpacpi_pdev->dev,
- &tpacpi_leds[i].led_classdev);
- if (rc < 0) {
- tpacpi_leds[i].led_classdev.name = NULL;
- led_exit();
- return rc;
+ if (!tpacpi_is_led_restricted(i)) {
+ rc = tpacpi_init_led(i);
+ if (rc < 0) {
+ led_exit();
+ return rc;
+ }
}
}
+#ifdef CONFIG_THINKPAD_ACPI_UNSAFE_LEDS
+ if (led_supported != TPACPI_LED_NONE)
+ printk(TPACPI_NOTICE
+ "warning: userspace override of important "
+ "firmware LEDs is enabled\n");
+#endif
return (led_supported != TPACPI_LED_NONE)? 0 : 1;
}
@@ -5340,6 +5526,20 @@ static struct ibm_struct ecdump_driver_data = {
#define TPACPI_BACKLIGHT_DEV_NAME "thinkpad_screen"
+/*
+ * ThinkPads can read brightness from two places: EC HBRV (0x31), or
+ * CMOS NVRAM byte 0x5E, bits 0-3.
+ *
+ * EC HBRV (0x31) has the following layout
+ * Bit 7: unknown function
+ * Bit 6: unknown function
+ * Bit 5: Z: honour scale changes, NZ: ignore scale changes
+ * Bit 4: must be set to zero to avoid problems
+ * Bit 3-0: backlight brightness level
+ *
+ * brightness_get_raw returns status data in the HBRV layout
+ */
+
enum {
TP_EC_BACKLIGHT = 0x31,
@@ -5349,108 +5549,164 @@ enum {
TP_EC_BACKLIGHT_MAPSW = 0x20,
};
+enum tpacpi_brightness_access_mode {
+ TPACPI_BRGHT_MODE_AUTO = 0, /* Not implemented yet */
+ TPACPI_BRGHT_MODE_EC, /* EC control */
+ TPACPI_BRGHT_MODE_UCMS_STEP, /* UCMS step-based control */
+ TPACPI_BRGHT_MODE_ECNVRAM, /* EC control w/ NVRAM store */
+ TPACPI_BRGHT_MODE_MAX
+};
+
static struct backlight_device *ibm_backlight_device;
-static int brightness_mode;
+
+static enum tpacpi_brightness_access_mode brightness_mode =
+ TPACPI_BRGHT_MODE_MAX;
+
static unsigned int brightness_enable = 2; /* 2 = auto, 0 = no, 1 = yes */
static struct mutex brightness_mutex;
-/*
- * ThinkPads can read brightness from two places: EC 0x31, or
- * CMOS NVRAM byte 0x5E, bits 0-3.
- *
- * EC 0x31 has the following layout
- * Bit 7: unknown function
- * Bit 6: unknown function
- * Bit 5: Z: honour scale changes, NZ: ignore scale changes
- * Bit 4: must be set to zero to avoid problems
- * Bit 3-0: backlight brightness level
- *
- * brightness_get_raw returns status data in the EC 0x31 layout
- */
-static int brightness_get_raw(int *status)
+/* NVRAM brightness access,
+ * call with brightness_mutex held! */
+static unsigned int tpacpi_brightness_nvram_get(void)
{
- u8 lec = 0, lcmos = 0, level = 0;
+ u8 lnvram;
- if (brightness_mode & 1) {
- if (!acpi_ec_read(TP_EC_BACKLIGHT, &lec))
- return -EIO;
- level = lec & TP_EC_BACKLIGHT_LVLMSK;
- };
- if (brightness_mode & 2) {
- lcmos = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
- & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
- >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
- lcmos &= (tp_features.bright_16levels)? 0x0f : 0x07;
- level = lcmos;
- }
-
- if (brightness_mode == 3) {
- *status = lec; /* Prefer EC, CMOS is just a backing store */
- lec &= TP_EC_BACKLIGHT_LVLMSK;
- if (lec == lcmos)
- tp_warned.bright_cmos_ec_unsync = 0;
- else {
- if (!tp_warned.bright_cmos_ec_unsync) {
- printk(TPACPI_ERR
- "CMOS NVRAM (%u) and EC (%u) do not "
- "agree on display brightness level\n",
- (unsigned int) lcmos,
- (unsigned int) lec);
- tp_warned.bright_cmos_ec_unsync = 1;
- }
+ lnvram = (nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS)
+ & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS;
+ lnvram &= (tp_features.bright_16levels) ? 0x0f : 0x07;
+
+ return lnvram;
+}
+
+static void tpacpi_brightness_checkpoint_nvram(void)
+{
+ u8 lec = 0;
+ u8 b_nvram;
+
+ if (brightness_mode != TPACPI_BRGHT_MODE_ECNVRAM)
+ return;
+
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "trying to checkpoint backlight level to NVRAM...\n");
+
+ if (mutex_lock_killable(&brightness_mutex) < 0)
+ return;
+
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+ goto unlock;
+ lec &= TP_EC_BACKLIGHT_LVLMSK;
+ b_nvram = nvram_read_byte(TP_NVRAM_ADDR_BRIGHTNESS);
+
+ if (lec != ((b_nvram & TP_NVRAM_MASK_LEVEL_BRIGHTNESS)
+ >> TP_NVRAM_POS_LEVEL_BRIGHTNESS)) {
+ /* NVRAM needs update */
+ b_nvram &= ~(TP_NVRAM_MASK_LEVEL_BRIGHTNESS <<
+ TP_NVRAM_POS_LEVEL_BRIGHTNESS);
+ b_nvram |= lec;
+ nvram_write_byte(b_nvram, TP_NVRAM_ADDR_BRIGHTNESS);
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "updated NVRAM backlight level to %u (0x%02x)\n",
+ (unsigned int) lec, (unsigned int) b_nvram);
+ } else
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "NVRAM backlight level already is %u (0x%02x)\n",
+ (unsigned int) lec, (unsigned int) b_nvram);
+
+unlock:
+ mutex_unlock(&brightness_mutex);
+}
+
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_get_raw(int *status)
+{
+ u8 lec = 0;
+
+ switch (brightness_mode) {
+ case TPACPI_BRGHT_MODE_UCMS_STEP:
+ *status = tpacpi_brightness_nvram_get();
+ return 0;
+ case TPACPI_BRGHT_MODE_EC:
+ case TPACPI_BRGHT_MODE_ECNVRAM:
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
return -EIO;
- }
- } else {
- *status = level;
+ *status = lec;
+ return 0;
+ default:
+ return -ENXIO;
}
+}
+
+/* call with brightness_mutex held! */
+/* do NOT call with illegal backlight level value */
+static int tpacpi_brightness_set_ec(unsigned int value)
+{
+ u8 lec = 0;
+
+ if (unlikely(!acpi_ec_read(TP_EC_BACKLIGHT, &lec)))
+ return -EIO;
+
+ if (unlikely(!acpi_ec_write(TP_EC_BACKLIGHT,
+ (lec & TP_EC_BACKLIGHT_CMDMSK) |
+ (value & TP_EC_BACKLIGHT_LVLMSK))))
+ return -EIO;
+
+ return 0;
+}
+
+/* call with brightness_mutex held! */
+static int tpacpi_brightness_set_ucmsstep(unsigned int value)
+{
+ int cmos_cmd, inc;
+ unsigned int current_value, i;
+
+ current_value = tpacpi_brightness_nvram_get();
+
+ if (value == current_value)
+ return 0;
+
+ cmos_cmd = (value > current_value) ?
+ TP_CMOS_BRIGHTNESS_UP :
+ TP_CMOS_BRIGHTNESS_DOWN;
+ inc = (value > current_value) ? 1 : -1;
+
+ for (i = current_value; i != value; i += inc)
+ if (issue_thinkpad_cmos_command(cmos_cmd))
+ return -EIO;
return 0;
}
/* May return EINTR which can always be mapped to ERESTARTSYS */
-static int brightness_set(int value)
+static int brightness_set(unsigned int value)
{
- int cmos_cmd, inc, i, res;
- int current_value;
- int command_bits;
+ int res;
if (value > ((tp_features.bright_16levels)? 15 : 7) ||
value < 0)
return -EINVAL;
+ vdbg_printk(TPACPI_DBG_BRGHT,
+ "set backlight level to %d\n", value);
+
res = mutex_lock_killable(&brightness_mutex);
if (res < 0)
return res;
- res = brightness_get_raw(&current_value);
- if (res < 0)
- goto errout;
-
- command_bits = current_value & TP_EC_BACKLIGHT_CMDMSK;
- current_value &= TP_EC_BACKLIGHT_LVLMSK;
-
- cmos_cmd = value > current_value ?
- TP_CMOS_BRIGHTNESS_UP :
- TP_CMOS_BRIGHTNESS_DOWN;
- inc = (value > current_value)? 1 : -1;
-
- res = 0;
- for (i = current_value; i != value; i += inc) {
- if ((brightness_mode & 2) &&
- issue_thinkpad_cmos_command(cmos_cmd)) {
- res = -EIO;
- goto errout;
- }
- if ((brightness_mode & 1) &&
- !acpi_ec_write(TP_EC_BACKLIGHT,
- (i + inc) | command_bits)) {
- res = -EIO;
- goto errout;;
- }
+ switch (brightness_mode) {
+ case TPACPI_BRGHT_MODE_EC:
+ case TPACPI_BRGHT_MODE_ECNVRAM:
+ res = tpacpi_brightness_set_ec(value);
+ break;
+ case TPACPI_BRGHT_MODE_UCMS_STEP:
+ res = tpacpi_brightness_set_ucmsstep(value);
+ break;
+ default:
+ res = -ENXIO;
}
-errout:
mutex_unlock(&brightness_mutex);
return res;
}
@@ -5459,21 +5715,34 @@ errout:
static int brightness_update_status(struct backlight_device *bd)
{
- /* it is the backlight class's job (caller) to handle
- * EINTR and other errors properly */
- return brightness_set(
+ unsigned int level =
(bd->props.fb_blank == FB_BLANK_UNBLANK &&
bd->props.power == FB_BLANK_UNBLANK) ?
- bd->props.brightness : 0);
+ bd->props.brightness : 0;
+
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "backlight: attempt to set level to %d\n",
+ level);
+
+ /* it is the backlight class's job (caller) to handle
+ * EINTR and other errors properly */
+ return brightness_set(level);
}
static int brightness_get(struct backlight_device *bd)
{
int status, res;
- res = brightness_get_raw(&status);
+ res = mutex_lock_killable(&brightness_mutex);
if (res < 0)
- return 0; /* FIXME: teach backlight about error handling */
+ return 0;
+
+ res = tpacpi_brightness_get_raw(&status);
+
+ mutex_unlock(&brightness_mutex);
+
+ if (res < 0)
+ return 0;
return status & TP_EC_BACKLIGHT_LVLMSK;
}
@@ -5523,7 +5792,7 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
}
if (!brightness_enable) {
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
"brightness support disabled by "
"module parameter\n");
return 1;
@@ -5538,20 +5807,38 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
if (b == 16)
tp_features.bright_16levels = 1;
- if (!brightness_mode) {
- if (thinkpad_id.vendor == PCI_VENDOR_ID_LENOVO)
- brightness_mode = 2;
- else
- brightness_mode = 3;
+ /*
+ * Check for module parameter bogosity, note that we
+ * init brightness_mode to TPACPI_BRGHT_MODE_MAX in order to be
+ * able to detect "unspecified"
+ */
+ if (brightness_mode > TPACPI_BRGHT_MODE_MAX)
+ return -EINVAL;
- dbg_printk(TPACPI_DBG_INIT, "selected brightness_mode=%d\n",
- brightness_mode);
- }
+ /* TPACPI_BRGHT_MODE_AUTO not implemented yet, just use default */
+ if (brightness_mode == TPACPI_BRGHT_MODE_AUTO ||
+ brightness_mode == TPACPI_BRGHT_MODE_MAX) {
+ if (thinkpad_id.vendor == PCI_VENDOR_ID_IBM) {
+ /*
+ * IBM models that define HBRV probably have
+ * EC-based backlight level control
+ */
+ if (acpi_evalf(ec_handle, NULL, "HBRV", "qd"))
+ /* T40-T43, R50-R52, R50e, R51e, X31-X41 */
+ brightness_mode = TPACPI_BRGHT_MODE_ECNVRAM;
+ else
+ /* all other IBM ThinkPads */
+ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
+ } else
+ /* All Lenovo ThinkPads */
+ brightness_mode = TPACPI_BRGHT_MODE_UCMS_STEP;
- if (brightness_mode > 3)
- return -EINVAL;
+ dbg_printk(TPACPI_DBG_BRGHT,
+ "selected brightness_mode=%d\n",
+ brightness_mode);
+ }
- if (brightness_get_raw(&b) < 0)
+ if (tpacpi_brightness_get_raw(&b) < 0)
return 1;
if (tp_features.bright_16levels)
@@ -5565,7 +5852,8 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
printk(TPACPI_ERR "Could not register backlight device\n");
return PTR_ERR(ibm_backlight_device);
}
- vdbg_printk(TPACPI_DBG_INIT, "brightness is supported\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_BRGHT,
+ "brightness is supported\n");
ibm_backlight_device->props.max_brightness =
(tp_features.bright_16levels)? 15 : 7;
@@ -5575,13 +5863,25 @@ static int __init brightness_init(struct ibm_init_struct *iibm)
return 0;
}
+static void brightness_suspend(pm_message_t state)
+{
+ tpacpi_brightness_checkpoint_nvram();
+}
+
+static void brightness_shutdown(void)
+{
+ tpacpi_brightness_checkpoint_nvram();
+}
+
static void brightness_exit(void)
{
if (ibm_backlight_device) {
- vdbg_printk(TPACPI_DBG_EXIT,
+ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_BRGHT,
"calling backlight_device_unregister()\n");
backlight_device_unregister(ibm_backlight_device);
}
+
+ tpacpi_brightness_checkpoint_nvram();
}
static int brightness_read(char *p)
@@ -5628,6 +5928,9 @@ static int brightness_write(char *buf)
return -EINVAL;
}
+ tpacpi_disclose_usertask("procfs brightness",
+ "set level to %d\n", level);
+
/*
* Now we know what the final level should be, so we try to set it.
* Doing it this way makes the syscall restartable in case of EINTR
@@ -5641,6 +5944,8 @@ static struct ibm_struct brightness_driver_data = {
.read = brightness_read,
.write = brightness_write,
.exit = brightness_exit,
+ .suspend = brightness_suspend,
+ .shutdown = brightness_shutdown,
};
/*************************************************************************
@@ -5811,7 +6116,7 @@ static struct ibm_struct volume_driver_data = {
* ThinkPads from this same time period (and earlier) probably lack the
* tachometer as well.
*
- * Unfortunately a lot of ThinkPads with new-style ECs but whose firwmare
+ * Unfortunately a lot of ThinkPads with new-style ECs but whose firmware
* was never fixed by IBM to report the EC firmware version string
* probably support the tachometer (like the early X models), so
* detecting it is quite hard. We need more data to know for sure.
@@ -6086,6 +6391,9 @@ static int fan_set_level(int level)
default:
return -ENXIO;
}
+
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0x%02x\n", level);
return 0;
}
@@ -6163,6 +6471,11 @@ static int fan_set_enable(void)
}
mutex_unlock(&fan_mutex);
+
+ if (!rc)
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0x%02x\n",
+ s);
return rc;
}
@@ -6199,6 +6512,9 @@ static int fan_set_disable(void)
rc = -ENXIO;
}
+ if (!rc)
+ vdbg_printk(TPACPI_DBG_FAN,
+ "fan control: set fan control register to 0\n");
mutex_unlock(&fan_mutex);
return rc;
@@ -6327,6 +6643,9 @@ static ssize_t fan_pwm1_enable_store(struct device *dev,
if (parse_strtoul(buf, 2, &t))
return -EINVAL;
+ tpacpi_disclose_usertask("hwmon pwm1_enable",
+ "set fan mode to %lu\n", t);
+
switch (t) {
case 0:
level = TP_EC_FAN_FULLSPEED;
@@ -6392,6 +6711,9 @@ static ssize_t fan_pwm1_store(struct device *dev,
if (parse_strtoul(buf, 255, &s))
return -EINVAL;
+ tpacpi_disclose_usertask("hwmon pwm1",
+ "set fan speed to %lu\n", s);
+
/* scale down from 0-255 to 0-7 */
newlevel = (s >> 5) & 0x07;
@@ -6458,6 +6780,8 @@ static ssize_t fan_fan_watchdog_store(struct device_driver *drv,
fan_watchdog_maxinterval = t;
fan_watchdog_reset();
+ tpacpi_disclose_usertask("fan_watchdog", "set to %lu\n", t);
+
return count;
}
@@ -6479,7 +6803,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
{
int rc;
- vdbg_printk(TPACPI_DBG_INIT, "initializing fan subdriver\n");
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+ "initializing fan subdriver\n");
mutex_init(&fan_mutex);
fan_status_access_mode = TPACPI_FAN_NONE;
@@ -6538,7 +6863,8 @@ static int __init fan_init(struct ibm_init_struct *iibm)
}
}
- vdbg_printk(TPACPI_DBG_INIT, "fan is %s, modes %d, %d\n",
+ vdbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
+ "fan is %s, modes %d, %d\n",
str_supported(fan_status_access_mode != TPACPI_FAN_NONE ||
fan_control_access_mode != TPACPI_FAN_WR_NONE),
fan_status_access_mode, fan_control_access_mode);
@@ -6547,7 +6873,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
if (!fan_control_allowed) {
fan_control_access_mode = TPACPI_FAN_WR_NONE;
fan_control_commands = 0;
- dbg_printk(TPACPI_DBG_INIT,
+ dbg_printk(TPACPI_DBG_INIT | TPACPI_DBG_FAN,
"fan control features disabled by parameter\n");
}
@@ -6576,7 +6902,7 @@ static int __init fan_init(struct ibm_init_struct *iibm)
static void fan_exit(void)
{
- vdbg_printk(TPACPI_DBG_EXIT,
+ vdbg_printk(TPACPI_DBG_EXIT | TPACPI_DBG_FAN,
"cancelling any pending fan watchdog tasks\n");
/* FIXME: can we really do this unconditionally? */
@@ -6757,6 +7083,9 @@ static int fan_write_cmd_level(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "level command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan",
+ "set level to %d\n", level);
return 1;
}
@@ -6770,6 +7099,8 @@ static int fan_write_cmd_enable(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "enable command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan", "enable\n");
return 1;
}
@@ -6783,6 +7114,8 @@ static int fan_write_cmd_disable(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "disable command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan", "disable\n");
return 1;
}
@@ -6801,6 +7134,9 @@ static int fan_write_cmd_speed(const char *cmd, int *rc)
if (*rc == -ENXIO)
printk(TPACPI_ERR "speed command accepted for unsupported "
"access mode %d", fan_control_access_mode);
+ else if (!*rc)
+ tpacpi_disclose_usertask("procfs fan",
+ "set speed to %d\n", speed);
return 1;
}
@@ -6814,8 +7150,12 @@ static int fan_write_cmd_watchdog(const char *cmd, int *rc)
if (interval < 0 || interval > 120)
*rc = -EINVAL;
- else
+ else {
fan_watchdog_maxinterval = interval;
+ tpacpi_disclose_usertask("procfs fan",
+ "set watchdog timer to %d\n",
+ interval);
+ }
return 1;
}
@@ -6992,7 +7332,6 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
ret = -ENODEV;
goto err_out;
}
- entry->owner = THIS_MODULE;
entry->data = ibm;
entry->read_proc = &dispatch_procfs_read;
if (ibm->write)
@@ -7244,10 +7583,10 @@ module_param_named(fan_control, fan_control_allowed, bool, 0);
MODULE_PARM_DESC(fan_control,
"Enables setting fan parameters features when true");
-module_param_named(brightness_mode, brightness_mode, int, 0);
+module_param_named(brightness_mode, brightness_mode, uint, 0);
MODULE_PARM_DESC(brightness_mode,
"Selects brightness control strategy: "
- "0=auto, 1=EC, 2=CMOS, 3=both");
+ "0=auto, 1=EC, 2=UCMS, 3=EC+NVRAM");
module_param(brightness_enable, uint, 0);
MODULE_PARM_DESC(brightness_enable,
@@ -7405,7 +7744,6 @@ static int __init thinkpad_acpi_module_init(void)
thinkpad_acpi_module_exit();
return -ENODEV;
}
- proc_dir->owner = THIS_MODULE;
ret = platform_driver_register(&tpacpi_pdriver);
if (ret) {
@@ -7517,9 +7855,6 @@ static int __init thinkpad_acpi_module_init(void)
return 0;
}
-/* Please remove this in year 2009 */
-MODULE_ALIAS("ibm_acpi");
-
MODULE_ALIAS(TPACPI_DRVR_SHORTNAME);
/*
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
index 40e60fc2e59..9f187265db8 100644
--- a/drivers/platform/x86/toshiba_acpi.c
+++ b/drivers/platform/x86/toshiba_acpi.c
@@ -679,8 +679,6 @@ static acpi_status __init add_device(void)
toshiba_proc_dir,
(read_proc_t *) dispatch_read,
item);
- if (proc)
- proc->owner = THIS_MODULE;
if (proc && item->write_func)
proc->write_proc = (write_proc_t *) dispatch_write;
}
@@ -772,7 +770,6 @@ static int __init toshiba_acpi_init(void)
toshiba_acpi_exit();
return -ENODEV;
} else {
- toshiba_proc_dir->owner = THIS_MODULE;
status = add_device();
if (ACPI_FAILURE(status)) {
toshiba_acpi_exit();
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
index 2834846a185..9a3a682c698 100644
--- a/drivers/pnp/pnpacpi/core.c
+++ b/drivers/pnp/pnpacpi/core.c
@@ -83,7 +83,6 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
acpi_handle handle = dev->data;
struct acpi_buffer buffer;
int ret;
- acpi_status status;
pnp_dbg(&dev->dev, "set resources\n");
ret = pnpacpi_build_resource_template(dev, &buffer);
@@ -94,21 +93,31 @@ static int pnpacpi_set_resources(struct pnp_dev *dev)
kfree(buffer.pointer);
return ret;
}
- status = acpi_set_current_resources(handle, &buffer);
- if (ACPI_FAILURE(status))
+ if (ACPI_FAILURE(acpi_set_current_resources(handle, &buffer)))
ret = -EINVAL;
+ else if (acpi_bus_power_manageable(handle))
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D0);
kfree(buffer.pointer);
return ret;
}
static int pnpacpi_disable_resources(struct pnp_dev *dev)
{
- acpi_status status;
+ acpi_handle handle = dev->data;
+ int ret;
+
+ dev_dbg(&dev->dev, "disable resources\n");
/* acpi_unregister_gsi(pnp_irq(dev, 0)); */
- status = acpi_evaluate_object((acpi_handle) dev->data,
- "_DIS", NULL, NULL);
- return ACPI_FAILURE(status) ? -ENODEV : 0;
+ ret = 0;
+ if (acpi_bus_power_manageable(handle)) {
+ ret = acpi_bus_set_power(handle, ACPI_STATE_D3);
+ if (ret)
+ return ret;
+ }
+ if (ACPI_FAILURE(acpi_evaluate_object(handle, "_DIS", NULL, NULL)))
+ ret = -ENODEV;
+ return ret;
}
#ifdef CONFIG_ACPI_SLEEP
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c
index 996f6483807..cfe86853feb 100644
--- a/drivers/pnp/pnpbios/core.c
+++ b/drivers/pnp/pnpbios/core.c
@@ -94,7 +94,6 @@ struct pnp_dev_node_info node_info;
#ifdef CONFIG_HOTPLUG
-static int unloading = 0;
static struct completion unload_sem;
/*
@@ -158,7 +157,7 @@ static int pnp_dock_thread(void *unused)
int docked = -1, d = 0;
set_freezable();
- while (!unloading) {
+ while (1) {
int status;
/*
@@ -575,8 +574,6 @@ fs_initcall(pnpbios_init);
static int __init pnpbios_thread_init(void)
{
- struct task_struct *task;
-
#if defined(CONFIG_PPC)
if (check_legacy_ioport(PNPBIOS_BASE))
return 0;
@@ -584,10 +581,13 @@ static int __init pnpbios_thread_init(void)
if (pnpbios_disabled)
return 0;
#ifdef CONFIG_HOTPLUG
- init_completion(&unload_sem);
- task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
- if (!IS_ERR(task))
- unloading = 0;
+ {
+ struct task_struct *task;
+ init_completion(&unload_sem);
+ task = kthread_run(pnp_dock_thread, NULL, "kpnpbiosd");
+ if (IS_ERR(task))
+ return PTR_ERR(task);
+ }
#endif
return 0;
}
diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c
index 0c056fcc01c..62bb98124e2 100644
--- a/drivers/power/bq27x00_battery.c
+++ b/drivers/power/bq27x00_battery.c
@@ -83,7 +83,7 @@ static int bq27x00_read(u8 reg, int *rt_value, int b_single,
}
/*
- * Return the battery temperature in Celcius degrees
+ * Return the battery temperature in Celsius degrees
* Or < 0 if something fails.
*/
static int bq27x00_battery_temperature(struct bq27x00_device_info *di)
diff --git a/drivers/power/power_supply_sysfs.c b/drivers/power/power_supply_sysfs.c
index ac01e06817f..da73591017f 100644
--- a/drivers/power/power_supply_sysfs.c
+++ b/drivers/power/power_supply_sysfs.c
@@ -93,6 +93,8 @@ static struct device_attribute power_supply_attrs[] = {
POWER_SUPPLY_ATTR(voltage_avg),
POWER_SUPPLY_ATTR(current_now),
POWER_SUPPLY_ATTR(current_avg),
+ POWER_SUPPLY_ATTR(power_now),
+ POWER_SUPPLY_ATTR(power_avg),
POWER_SUPPLY_ATTR(charge_full_design),
POWER_SUPPLY_ATTR(charge_empty_design),
POWER_SUPPLY_ATTR(charge_full),
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 5324978b73f..235e87fcb49 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -838,7 +838,7 @@ static int ps3av_get_hw_conf(struct ps3av *ps3av)
}
/* set mode using id */
-int ps3av_set_video_mode(u32 id)
+int ps3av_set_video_mode(int id)
{
int size;
u32 option;
@@ -940,7 +940,7 @@ EXPORT_SYMBOL_GPL(ps3av_audio_mute);
static int ps3av_probe(struct ps3_system_bus_device *dev)
{
int res;
- u32 id;
+ int id;
dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
dev_dbg(&dev->core, " timeout=%d\n", timeout);
@@ -962,8 +962,10 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
init_completion(&ps3av->done);
complete(&ps3av->done);
ps3av->wq = create_singlethread_workqueue("ps3avd");
- if (!ps3av->wq)
+ if (!ps3av->wq) {
+ res = -ENOMEM;
goto fail;
+ }
switch (ps3_os_area_get_av_multi_out()) {
case PS3_PARAM_AV_MULTI_OUT_NTSC:
@@ -994,6 +996,12 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
safe_mode = 1;
#endif /* CONFIG_FB */
id = ps3av_auto_videomode(&ps3av->av_hw_conf);
+ if (id < 0) {
+ printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
+ res = -EINVAL;
+ goto fail;
+ }
+
safe_mode = 0;
mutex_lock(&ps3av->mutex);
@@ -1007,7 +1015,7 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
fail:
kfree(ps3av);
ps3av = NULL;
- return -ENOMEM;
+ return res;
}
static int ps3av_remove(struct ps3_system_bus_device *dev)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e7e0cf102d6..e58c0ce65aa 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -29,8 +29,12 @@ config REGULATOR_DEBUG
Say yes here to enable debugging support.
config REGULATOR_FIXED_VOLTAGE
- tristate
+ tristate "Fixed voltage regulator support"
default n
+ help
+ This driver provides support for fixed voltage regulators,
+ useful for systems which use a combination of software
+ managed regulators and simple non-configurable regulators.
config REGULATOR_VIRTUAL_CONSUMER
tristate "Virtual regulator consumer support"
@@ -52,6 +56,13 @@ config REGULATOR_BQ24022
charging select between 100 mA and 500 mA charging current
limit.
+config REGULATOR_TWL4030
+ bool "TI TWL4030/TWL5030/TPS695x0 PMIC"
+ depends on TWL4030_CORE
+ help
+ This driver supports the voltage regulators provided by
+ this family of companion chips.
+
config REGULATOR_WM8350
tristate "Wolfson Microelectroncis WM8350 AudioPlus PMIC"
depends on MFD_WM8350
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 61b30c6ddec..bac133afc06 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
+obj-$(CONFIG_REGULATOR_TWL4030) += twl4030-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
index c175e38a4cd..7ecb820ceeb 100644
--- a/drivers/regulator/bq24022.c
+++ b/drivers/regulator/bq24022.c
@@ -105,7 +105,8 @@ static int __init bq24022_probe(struct platform_device *pdev)
ret = gpio_direction_output(pdata->gpio_iset2, 0);
ret = gpio_direction_output(pdata->gpio_nce, 1);
- bq24022 = regulator_register(&bq24022_desc, &pdev->dev, pdata);
+ bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
+ pdata->init_data, pdata);
if (IS_ERR(bq24022)) {
dev_dbg(&pdev->dev, "couldn't register regulator\n");
ret = PTR_ERR(bq24022);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index f511a406fca..01f7702a805 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -28,33 +28,7 @@
static DEFINE_MUTEX(regulator_list_mutex);
static LIST_HEAD(regulator_list);
static LIST_HEAD(regulator_map_list);
-
-/*
- * struct regulator_dev
- *
- * Voltage / Current regulator class device. One for each regulator.
- */
-struct regulator_dev {
- struct regulator_desc *desc;
- int use_count;
-
- /* lists we belong to */
- struct list_head list; /* list of all regulators */
- struct list_head slist; /* list of supplied regulators */
-
- /* lists we own */
- struct list_head consumer_list; /* consumers we supply */
- struct list_head supply_list; /* regulators we supply */
-
- struct blocking_notifier_head notifier;
- struct mutex mutex; /* consumer lock */
- struct module *owner;
- struct device dev;
- struct regulation_constraints *constraints;
- struct regulator_dev *supply; /* for tree */
-
- void *reg_data; /* regulator_dev data */
-};
+static int has_full_constraints;
/*
* struct regulator_map
@@ -79,7 +53,6 @@ struct regulator {
int uA_load;
int min_uV;
int max_uV;
- int enabled; /* count of client enables */
char *supply_name;
struct device_attribute dev_attr;
struct regulator_dev *rdev;
@@ -312,6 +285,47 @@ static ssize_t regulator_state_show(struct device *dev,
}
static DEVICE_ATTR(state, 0444, regulator_state_show, NULL);
+static ssize_t regulator_status_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ int status;
+ char *label;
+
+ status = rdev->desc->ops->get_status(rdev);
+ if (status < 0)
+ return status;
+
+ switch (status) {
+ case REGULATOR_STATUS_OFF:
+ label = "off";
+ break;
+ case REGULATOR_STATUS_ON:
+ label = "on";
+ break;
+ case REGULATOR_STATUS_ERROR:
+ label = "error";
+ break;
+ case REGULATOR_STATUS_FAST:
+ label = "fast";
+ break;
+ case REGULATOR_STATUS_NORMAL:
+ label = "normal";
+ break;
+ case REGULATOR_STATUS_IDLE:
+ label = "idle";
+ break;
+ case REGULATOR_STATUS_STANDBY:
+ label = "standby";
+ break;
+ default:
+ return -ERANGE;
+ }
+
+ return sprintf(buf, "%s\n", label);
+}
+static DEVICE_ATTR(status, 0444, regulator_status_show, NULL);
+
static ssize_t regulator_min_uA_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -678,6 +692,73 @@ static int set_machine_constraints(struct regulator_dev *rdev,
else
name = "regulator";
+ /* constrain machine-level voltage specs to fit
+ * the actual range supported by this regulator.
+ */
+ if (ops->list_voltage && rdev->desc->n_voltages) {
+ int count = rdev->desc->n_voltages;
+ int i;
+ int min_uV = INT_MAX;
+ int max_uV = INT_MIN;
+ int cmin = constraints->min_uV;
+ int cmax = constraints->max_uV;
+
+ /* it's safe to autoconfigure fixed-voltage supplies */
+ if (count == 1 && !cmin) {
+ cmin = INT_MIN;
+ cmax = INT_MAX;
+ }
+
+ /* voltage constraints are optional */
+ if ((cmin == 0) && (cmax == 0))
+ goto out;
+
+ /* else require explicit machine-level constraints */
+ if (cmin <= 0 || cmax <= 0 || cmax < cmin) {
+ pr_err("%s: %s '%s' voltage constraints\n",
+ __func__, "invalid", name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* initial: [cmin..cmax] valid, [min_uV..max_uV] not */
+ for (i = 0; i < count; i++) {
+ int value;
+
+ value = ops->list_voltage(rdev, i);
+ if (value <= 0)
+ continue;
+
+ /* maybe adjust [min_uV..max_uV] */
+ if (value >= cmin && value < min_uV)
+ min_uV = value;
+ if (value <= cmax && value > max_uV)
+ max_uV = value;
+ }
+
+ /* final: [min_uV..max_uV] valid iff constraints valid */
+ if (max_uV < min_uV) {
+ pr_err("%s: %s '%s' voltage constraints\n",
+ __func__, "unsupportable", name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* use regulator's subset of machine constraints */
+ if (constraints->min_uV < min_uV) {
+ pr_debug("%s: override '%s' %s, %d -> %d\n",
+ __func__, name, "min_uV",
+ constraints->min_uV, min_uV);
+ constraints->min_uV = min_uV;
+ }
+ if (constraints->max_uV > max_uV) {
+ pr_debug("%s: override '%s' %s, %d -> %d\n",
+ __func__, name, "max_uV",
+ constraints->max_uV, max_uV);
+ constraints->max_uV = max_uV;
+ }
+ }
+
rdev->constraints = constraints;
/* do we need to apply the constraint voltage */
@@ -695,10 +776,6 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
- /* are we enabled at boot time by firmware / bootloader */
- if (rdev->constraints->boot_on)
- rdev->use_count = 1;
-
/* do we need to setup our suspend state */
if (constraints->initial_state) {
ret = suspend_prepare(rdev, constraints->initial_state);
@@ -710,11 +787,27 @@ static int set_machine_constraints(struct regulator_dev *rdev,
}
}
- /* if always_on is set then turn the regulator on if it's not
- * already on. */
- if (constraints->always_on && ops->enable &&
- ((ops->is_enabled && !ops->is_enabled(rdev)) ||
- (!ops->is_enabled && !constraints->boot_on))) {
+ if (constraints->initial_mode) {
+ if (!ops->set_mode) {
+ printk(KERN_ERR "%s: no set_mode operation for %s\n",
+ __func__, name);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ ret = ops->set_mode(rdev, constraints->initial_mode);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "%s: failed to set initial mode for %s: %d\n",
+ __func__, name, ret);
+ goto out;
+ }
+ }
+
+ /* If the constraints say the regulator should be on at this point
+ * and we have control then make sure it is enabled.
+ */
+ if ((constraints->always_on || constraints->boot_on) && ops->enable) {
ret = ops->enable(rdev);
if (ret < 0) {
printk(KERN_ERR "%s: failed to enable %s\n",
@@ -817,6 +910,19 @@ static void unset_consumer_device_supply(struct regulator_dev *rdev,
}
}
+static void unset_regulator_supplies(struct regulator_dev *rdev)
+{
+ struct regulator_map *node, *n;
+
+ list_for_each_entry_safe(node, n, &regulator_map_list, list) {
+ if (rdev == node->regulator) {
+ list_del(&node->list);
+ kfree(node);
+ return;
+ }
+ }
+}
+
#define REG_STR_SIZE 32
static struct regulator *create_regulator(struct regulator_dev *rdev,
@@ -898,9 +1004,12 @@ overflow_err:
* @id: Supply name or regulator ID.
*
* Returns a struct regulator corresponding to the regulator producer,
- * or IS_ERR() condition containing errno. Use of supply names
- * configured via regulator_set_device_supply() is strongly
- * encouraged.
+ * or IS_ERR() condition containing errno.
+ *
+ * Use of supply names configured via regulator_set_device_supply() is
+ * strongly encouraged. It is recommended that the supply name used
+ * should match the name used for the supply and/or the relevant
+ * device pins in the datasheet.
*/
struct regulator *regulator_get(struct device *dev, const char *id)
{
@@ -922,8 +1031,6 @@ struct regulator *regulator_get(struct device *dev, const char *id)
goto found;
}
}
- printk(KERN_ERR "regulator: Unable to get requested regulator: %s\n",
- id);
mutex_unlock(&regulator_list_mutex);
return regulator;
@@ -961,10 +1068,6 @@ void regulator_put(struct regulator *regulator)
mutex_lock(&regulator_list_mutex);
rdev = regulator->rdev;
- if (WARN(regulator->enabled, "Releasing supply %s while enabled\n",
- regulator->supply_name))
- _regulator_disable(rdev);
-
/* remove any sysfs entries */
if (regulator->dev) {
sysfs_remove_link(&rdev->dev.kobj, regulator->supply_name);
@@ -1039,12 +1142,7 @@ int regulator_enable(struct regulator *regulator)
int ret = 0;
mutex_lock(&rdev->mutex);
- if (regulator->enabled == 0)
- ret = _regulator_enable(rdev);
- else if (regulator->enabled < 0)
- ret = -EIO;
- if (ret == 0)
- regulator->enabled++;
+ ret = _regulator_enable(rdev);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1055,6 +1153,11 @@ static int _regulator_disable(struct regulator_dev *rdev)
{
int ret = 0;
+ if (WARN(rdev->use_count <= 0,
+ "unbalanced disables for %s\n",
+ rdev->desc->name))
+ return -EIO;
+
/* are we the last user and permitted to disable ? */
if (rdev->use_count == 1 && !rdev->constraints->always_on) {
@@ -1103,16 +1206,7 @@ int regulator_disable(struct regulator *regulator)
int ret = 0;
mutex_lock(&rdev->mutex);
- if (regulator->enabled == 1) {
- ret = _regulator_disable(rdev);
- if (ret == 0)
- regulator->uA_load = 0;
- } else if (WARN(regulator->enabled <= 0,
- "unbalanced disables for supply %s\n",
- regulator->supply_name))
- ret = -EIO;
- if (ret == 0)
- regulator->enabled--;
+ ret = _regulator_disable(rdev);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1159,7 +1253,6 @@ int regulator_force_disable(struct regulator *regulator)
int ret;
mutex_lock(&regulator->rdev->mutex);
- regulator->enabled = 0;
regulator->uA_load = 0;
ret = _regulator_force_disable(regulator->rdev);
mutex_unlock(&regulator->rdev->mutex);
@@ -1204,6 +1297,56 @@ int regulator_is_enabled(struct regulator *regulator)
EXPORT_SYMBOL_GPL(regulator_is_enabled);
/**
+ * regulator_count_voltages - count regulator_list_voltage() selectors
+ * @regulator: regulator source
+ *
+ * Returns number of selectors, or negative errno. Selectors are
+ * numbered starting at zero, and typically correspond to bitfields
+ * in hardware registers.
+ */
+int regulator_count_voltages(struct regulator *regulator)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+
+ return rdev->desc->n_voltages ? : -EINVAL;
+}
+EXPORT_SYMBOL_GPL(regulator_count_voltages);
+
+/**
+ * regulator_list_voltage - enumerate supported voltages
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ * Context: can sleep
+ *
+ * Returns a voltage that can be passed to @regulator_set_voltage(),
+ * zero if this selector code can't be used on this sytem, or a
+ * negative errno.
+ */
+int regulator_list_voltage(struct regulator *regulator, unsigned selector)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+ struct regulator_ops *ops = rdev->desc->ops;
+ int ret;
+
+ if (!ops->list_voltage || selector >= rdev->desc->n_voltages)
+ return -EINVAL;
+
+ mutex_lock(&rdev->mutex);
+ ret = ops->list_voltage(rdev, selector);
+ mutex_unlock(&rdev->mutex);
+
+ if (ret > 0) {
+ if (ret < rdev->constraints->min_uV)
+ ret = 0;
+ else if (ret > rdev->constraints->max_uV)
+ ret = 0;
+ }
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_list_voltage);
+
+/**
* regulator_set_voltage - set regulator output voltage
* @regulator: regulator source
* @min_uV: Minimum required voltage in uV
@@ -1243,6 +1386,7 @@ int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV)
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV);
out:
+ _notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE, NULL);
mutex_unlock(&rdev->mutex);
return ret;
}
@@ -1543,20 +1687,23 @@ int regulator_unregister_notifier(struct regulator *regulator,
}
EXPORT_SYMBOL_GPL(regulator_unregister_notifier);
-/* notify regulator consumers and downstream regulator consumers */
+/* notify regulator consumers and downstream regulator consumers.
+ * Note mutex must be held by caller.
+ */
static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
struct regulator_dev *_rdev;
/* call rdev chain first */
- mutex_lock(&rdev->mutex);
blocking_notifier_call_chain(&rdev->notifier, event, NULL);
- mutex_unlock(&rdev->mutex);
/* now notify regulator we supply */
- list_for_each_entry(_rdev, &rdev->supply_list, slist)
- _notifier_call_chain(_rdev, event, data);
+ list_for_each_entry(_rdev, &rdev->supply_list, slist) {
+ mutex_lock(&_rdev->mutex);
+ _notifier_call_chain(_rdev, event, data);
+ mutex_unlock(&_rdev->mutex);
+ }
}
/**
@@ -1703,6 +1850,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_free);
*
* Called by regulator drivers to notify clients a regulator event has
* occurred. We also notify regulator clients downstream.
+ * Note lock must be held by caller.
*/
int regulator_notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
@@ -1744,6 +1892,11 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
if (status < 0)
return status;
}
+ if (ops->get_status) {
+ status = device_create_file(dev, &dev_attr_status);
+ if (status < 0)
+ return status;
+ }
/* some attributes are type-specific */
if (rdev->desc->type == REGULATOR_CURRENT) {
@@ -1828,17 +1981,18 @@ static int add_regulator_attributes(struct regulator_dev *rdev)
* regulator_register - register regulator
* @regulator_desc: regulator to register
* @dev: struct device for the regulator
+ * @init_data: platform provided init data, passed through by driver
* @driver_data: private regulator data
*
* Called by regulator drivers to register a regulator.
* Returns 0 on success.
*/
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
- struct device *dev, void *driver_data)
+ struct device *dev, struct regulator_init_data *init_data,
+ void *driver_data)
{
static atomic_t regulator_no = ATOMIC_INIT(0);
struct regulator_dev *rdev;
- struct regulator_init_data *init_data = dev->platform_data;
int ret, i;
if (regulator_desc == NULL)
@@ -1945,6 +2099,7 @@ void regulator_unregister(struct regulator_dev *rdev)
return;
mutex_lock(&regulator_list_mutex);
+ unset_regulator_supplies(rdev);
list_del(&rdev->list);
if (rdev->supply)
sysfs_remove_link(&rdev->dev.kobj, "supply");
@@ -1989,6 +2144,23 @@ out:
EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
/**
+ * regulator_has_full_constraints - the system has fully specified constraints
+ *
+ * Calling this function will cause the regulator API to disable all
+ * regulators which have a zero use count and don't have an always_on
+ * constraint in a late_initcall.
+ *
+ * The intention is that this will become the default behaviour in a
+ * future kernel release so users are encouraged to use this facility
+ * now.
+ */
+void regulator_has_full_constraints(void)
+{
+ has_full_constraints = 1;
+}
+EXPORT_SYMBOL_GPL(regulator_has_full_constraints);
+
+/**
* rdev_get_drvdata - get rdev regulator driver data
* @rdev: regulator
*
@@ -2055,3 +2227,77 @@ static int __init regulator_init(void)
/* init early to allow our consumers to complete system booting */
core_initcall(regulator_init);
+
+static int __init regulator_init_complete(void)
+{
+ struct regulator_dev *rdev;
+ struct regulator_ops *ops;
+ struct regulation_constraints *c;
+ int enabled, ret;
+ const char *name;
+
+ mutex_lock(&regulator_list_mutex);
+
+ /* If we have a full configuration then disable any regulators
+ * which are not in use or always_on. This will become the
+ * default behaviour in the future.
+ */
+ list_for_each_entry(rdev, &regulator_list, list) {
+ ops = rdev->desc->ops;
+ c = rdev->constraints;
+
+ if (c->name)
+ name = c->name;
+ else if (rdev->desc->name)
+ name = rdev->desc->name;
+ else
+ name = "regulator";
+
+ if (!ops->disable || c->always_on)
+ continue;
+
+ mutex_lock(&rdev->mutex);
+
+ if (rdev->use_count)
+ goto unlock;
+
+ /* If we can't read the status assume it's on. */
+ if (ops->is_enabled)
+ enabled = ops->is_enabled(rdev);
+ else
+ enabled = 1;
+
+ if (!enabled)
+ goto unlock;
+
+ if (has_full_constraints) {
+ /* We log since this may kill the system if it
+ * goes wrong. */
+ printk(KERN_INFO "%s: disabling %s\n",
+ __func__, name);
+ ret = ops->disable(rdev);
+ if (ret != 0) {
+ printk(KERN_ERR
+ "%s: couldn't disable %s: %d\n",
+ __func__, name, ret);
+ }
+ } else {
+ /* The intention is that in future we will
+ * assume that full constraints are provided
+ * so warn even if we aren't going to do
+ * anything here.
+ */
+ printk(KERN_WARNING
+ "%s: incomplete constraints, leaving %s on\n",
+ __func__, name);
+ }
+
+unlock:
+ mutex_unlock(&rdev->mutex);
+ }
+
+ mutex_unlock(&regulator_list_mutex);
+
+ return 0;
+}
+late_initcall(regulator_init_complete);
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c
index fe77730a7ed..72b15495183 100644
--- a/drivers/regulator/da903x.c
+++ b/drivers/regulator/da903x.c
@@ -471,7 +471,8 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev)
if (ri->desc.id == DA9030_ID_LDO1 || ri->desc.id == DA9030_ID_LDO15)
ri->desc.ops = &da9030_regulator_ldo1_15_ops;
- rdev = regulator_register(&ri->desc, &pdev->dev, ri);
+ rdev = regulator_register(&ri->desc, &pdev->dev,
+ pdev->dev.platform_data, ri);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c
index d31db3e1491..23d554628a7 100644
--- a/drivers/regulator/fixed.c
+++ b/drivers/regulator/fixed.c
@@ -73,7 +73,8 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev)
drvdata->microvolts = config->microvolts;
- drvdata->dev = regulator_register(&drvdata->desc, drvdata);
+ drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev,
+ config->init_data, drvdata);
if (IS_ERR(drvdata->dev)) {
ret = PTR_ERR(drvdata->dev);
goto err_name;
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index 4cc85ec6e12..cd761d85c8f 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -284,7 +284,8 @@ static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
/* Already set by core driver */
pcf = platform_get_drvdata(pdev);
- rdev = regulator_register(&regulators[pdev->id], &pdev->dev, pcf);
+ rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
+ pdev->dev.platform_data, pcf);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
diff --git a/drivers/regulator/twl4030-regulator.c b/drivers/regulator/twl4030-regulator.c
new file mode 100644
index 00000000000..e2032fb60b5
--- /dev/null
+++ b/drivers/regulator/twl4030-regulator.c
@@ -0,0 +1,500 @@
+/*
+ * twl4030-regulator.c -- support regulators in twl4030 family chips
+ *
+ * Copyright (C) 2008 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c/twl4030.h>
+
+
+/*
+ * The TWL4030/TW5030/TPS659x0 family chips include power management, a
+ * USB OTG transceiver, an RTC, ADC, PWM, and lots more. Some versions
+ * include an audio codec, battery charger, and more voltage regulators.
+ * These chips are often used in OMAP-based systems.
+ *
+ * This driver implements software-based resource control for various
+ * voltage regulators. This is usually augmented with state machine
+ * based control.
+ */
+
+struct twlreg_info {
+ /* start of regulator's PM_RECEIVER control register bank */
+ u8 base;
+
+ /* twl4030 resource ID, for resource control state machine */
+ u8 id;
+
+ /* voltage in mV = table[VSEL]; table_len must be a power-of-two */
+ u8 table_len;
+ const u16 *table;
+
+ /* chip constraints on regulator behavior */
+ u16 min_mV;
+
+ /* used by regulator core */
+ struct regulator_desc desc;
+};
+
+
+/* LDO control registers ... offset is from the base of its register bank.
+ * The first three registers of all power resource banks help hardware to
+ * manage the various resource groups.
+ */
+#define VREG_GRP 0
+#define VREG_TYPE 1
+#define VREG_REMAP 2
+#define VREG_DEDICATED 3 /* LDO control */
+
+
+static inline int
+twl4030reg_read(struct twlreg_info *info, unsigned offset)
+{
+ u8 value;
+ int status;
+
+ status = twl4030_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER,
+ &value, info->base + offset);
+ return (status < 0) ? status : value;
+}
+
+static inline int
+twl4030reg_write(struct twlreg_info *info, unsigned offset, u8 value)
+{
+ return twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
+ value, info->base + offset);
+}
+
+/*----------------------------------------------------------------------*/
+
+/* generic power resource operations, which work on all regulators */
+
+static int twl4030reg_grp(struct regulator_dev *rdev)
+{
+ return twl4030reg_read(rdev_get_drvdata(rdev), VREG_GRP);
+}
+
+/*
+ * Enable/disable regulators by joining/leaving the P1 (processor) group.
+ * We assume nobody else is updating the DEV_GRP registers.
+ */
+
+#define P3_GRP BIT(7) /* "peripherals" */
+#define P2_GRP BIT(6) /* secondary processor, modem, etc */
+#define P1_GRP BIT(5) /* CPU/Linux */
+
+static int twl4030reg_is_enabled(struct regulator_dev *rdev)
+{
+ int state = twl4030reg_grp(rdev);
+
+ if (state < 0)
+ return state;
+
+ return (state & P1_GRP) != 0;
+}
+
+static int twl4030reg_enable(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int grp;
+
+ grp = twl4030reg_read(info, VREG_GRP);
+ if (grp < 0)
+ return grp;
+
+ grp |= P1_GRP;
+ return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_disable(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int grp;
+
+ grp = twl4030reg_read(info, VREG_GRP);
+ if (grp < 0)
+ return grp;
+
+ grp &= ~P1_GRP;
+ return twl4030reg_write(info, VREG_GRP, grp);
+}
+
+static int twl4030reg_get_status(struct regulator_dev *rdev)
+{
+ int state = twl4030reg_grp(rdev);
+
+ if (state < 0)
+ return state;
+ state &= 0x0f;
+
+ /* assume state != WARM_RESET; we'd not be running... */
+ if (!state)
+ return REGULATOR_STATUS_OFF;
+ return (state & BIT(3))
+ ? REGULATOR_STATUS_NORMAL
+ : REGULATOR_STATUS_STANDBY;
+}
+
+static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ unsigned message;
+ int status;
+
+ /* We can only set the mode through state machine commands... */
+ switch (mode) {
+ case REGULATOR_MODE_NORMAL:
+ message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_ACTIVE);
+ break;
+ case REGULATOR_MODE_STANDBY:
+ message = MSG_SINGULAR(DEV_GRP_P1, info->id, RES_STATE_SLEEP);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Ensure the resource is associated with some group */
+ status = twl4030reg_grp(rdev);
+ if (status < 0)
+ return status;
+ if (!(status & (P3_GRP | P2_GRP | P1_GRP)))
+ return -EACCES;
+
+ status = twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ message >> 8, 0x15 /* PB_WORD_MSB */ );
+ if (status >= 0)
+ return status;
+
+ return twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
+ message, 0x16 /* PB_WORD_LSB */ );
+}
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Support for adjustable-voltage LDOs uses a four bit (or less) voltage
+ * select field in its control register. We use tables indexed by VSEL
+ * to record voltages in milliVolts. (Accuracy is about three percent.)
+ *
+ * Note that VSEL values for VAUX2 changed in twl5030 and newer silicon;
+ * currently handled by listing two slightly different VAUX2 regulators,
+ * only one of which will be configured.
+ *
+ * VSEL values documented as "TI cannot support these values" are flagged
+ * in these tables as UNSUP() values; we normally won't assign them.
+ *
+ * VAUX3 at 3V is incorrectly listed in some TI manuals as unsupported.
+ * TI are revising the twl5030/tps659x0 specs to support that 3.0V setting.
+ */
+#ifdef CONFIG_TWL4030_ALLOW_UNSUPPORTED
+#define UNSUP_MASK 0x0000
+#else
+#define UNSUP_MASK 0x8000
+#endif
+
+#define UNSUP(x) (UNSUP_MASK | (x))
+#define IS_UNSUP(x) (UNSUP_MASK & (x))
+#define LDO_MV(x) (~UNSUP_MASK & (x))
+
+
+static const u16 VAUX1_VSEL_table[] = {
+ UNSUP(1500), UNSUP(1800), 2500, 2800,
+ 3000, 3000, 3000, 3000,
+};
+static const u16 VAUX2_4030_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1000), UNSUP(1200), 1300,
+ 1500, 1800, UNSUP(1850), 2500,
+ UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VAUX2_VSEL_table[] = {
+ 1700, 1700, 1900, 1300,
+ 1500, 1800, 2000, 2500,
+ 2100, 2800, 2200, 2300,
+ 2400, 2400, 2400, 2400,
+};
+static const u16 VAUX3_VSEL_table[] = {
+ 1500, 1800, 2500, 2800,
+ 3000, 3000, 3000, 3000,
+};
+static const u16 VAUX4_VSEL_table[] = {
+ 700, 1000, 1200, UNSUP(1300),
+ 1500, 1800, UNSUP(1850), 2500,
+ UNSUP(2600), 2800, UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VMMC1_VSEL_table[] = {
+ 1850, 2850, 3000, 3150,
+};
+static const u16 VMMC2_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1000), UNSUP(1200), UNSUP(1300),
+ UNSUP(1500), UNSUP(1800), 1850, UNSUP(2500),
+ 2600, 2800, 2850, 3000,
+ 3150, 3150, 3150, 3150,
+};
+static const u16 VPLL1_VSEL_table[] = {
+ 1000, 1200, 1300, 1800,
+ UNSUP(2800), UNSUP(3000), UNSUP(3000), UNSUP(3000),
+};
+static const u16 VPLL2_VSEL_table[] = {
+ 700, 1000, 1200, 1300,
+ UNSUP(1500), 1800, UNSUP(1850), UNSUP(2500),
+ UNSUP(2600), UNSUP(2800), UNSUP(2850), UNSUP(3000),
+ UNSUP(3150), UNSUP(3150), UNSUP(3150), UNSUP(3150),
+};
+static const u16 VSIM_VSEL_table[] = {
+ UNSUP(1000), UNSUP(1200), UNSUP(1300), 1800,
+ 2800, 3000, 3000, 3000,
+};
+static const u16 VDAC_VSEL_table[] = {
+ 1200, 1300, 1800, 1800,
+};
+
+
+static int twl4030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int mV = info->table[index];
+
+ return IS_UNSUP(mV) ? 0 : (LDO_MV(mV) * 1000);
+}
+
+static int
+twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int vsel;
+
+ for (vsel = 0; vsel < info->table_len; vsel++) {
+ int mV = info->table[vsel];
+ int uV;
+
+ if (IS_UNSUP(mV))
+ continue;
+ uV = LDO_MV(mV) * 1000;
+
+ /* REVISIT for VAUX2, first match may not be best/lowest */
+
+ /* use the first in-range value */
+ if (min_uV <= uV && uV <= max_uV)
+ return twl4030reg_write(info, VREG_DEDICATED, vsel);
+ }
+
+ return -EDOM;
+}
+
+static int twl4030ldo_get_voltage(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+ int vsel = twl4030reg_read(info, VREG_DEDICATED);
+
+ if (vsel < 0)
+ return vsel;
+
+ vsel &= info->table_len - 1;
+ return LDO_MV(info->table[vsel]) * 1000;
+}
+
+static struct regulator_ops twl4030ldo_ops = {
+ .list_voltage = twl4030ldo_list_voltage,
+
+ .set_voltage = twl4030ldo_set_voltage,
+ .get_voltage = twl4030ldo_get_voltage,
+
+ .enable = twl4030reg_enable,
+ .disable = twl4030reg_disable,
+ .is_enabled = twl4030reg_is_enabled,
+
+ .set_mode = twl4030reg_set_mode,
+
+ .get_status = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+/*
+ * Fixed voltage LDOs don't have a VSEL field to update.
+ */
+static int twl4030fixed_list_voltage(struct regulator_dev *rdev, unsigned index)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+ return info->min_mV * 1000;
+}
+
+static int twl4030fixed_get_voltage(struct regulator_dev *rdev)
+{
+ struct twlreg_info *info = rdev_get_drvdata(rdev);
+
+ return info->min_mV * 1000;
+}
+
+static struct regulator_ops twl4030fixed_ops = {
+ .list_voltage = twl4030fixed_list_voltage,
+
+ .get_voltage = twl4030fixed_get_voltage,
+
+ .enable = twl4030reg_enable,
+ .disable = twl4030reg_disable,
+ .is_enabled = twl4030reg_is_enabled,
+
+ .set_mode = twl4030reg_set_mode,
+
+ .get_status = twl4030reg_get_status,
+};
+
+/*----------------------------------------------------------------------*/
+
+#define TWL_ADJUSTABLE_LDO(label, offset, num) { \
+ .base = offset, \
+ .id = num, \
+ .table_len = ARRAY_SIZE(label##_VSEL_table), \
+ .table = label##_VSEL_table, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL4030_REG_##label, \
+ .n_voltages = ARRAY_SIZE(label##_VSEL_table), \
+ .ops = &twl4030ldo_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }, \
+ }
+
+#define TWL_FIXED_LDO(label, offset, mVolts, num) { \
+ .base = offset, \
+ .id = num, \
+ .min_mV = mVolts, \
+ .desc = { \
+ .name = #label, \
+ .id = TWL4030_REG_##label, \
+ .n_voltages = 1, \
+ .ops = &twl4030fixed_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }, \
+ }
+
+/*
+ * We list regulators here if systems need some level of
+ * software control over them after boot.
+ */
+static struct twlreg_info twl4030_regs[] = {
+ TWL_ADJUSTABLE_LDO(VAUX1, 0x17, 1),
+ TWL_ADJUSTABLE_LDO(VAUX2_4030, 0x1b, 2),
+ TWL_ADJUSTABLE_LDO(VAUX2, 0x1b, 2),
+ TWL_ADJUSTABLE_LDO(VAUX3, 0x1f, 3),
+ TWL_ADJUSTABLE_LDO(VAUX4, 0x23, 4),
+ TWL_ADJUSTABLE_LDO(VMMC1, 0x27, 5),
+ TWL_ADJUSTABLE_LDO(VMMC2, 0x2b, 6),
+ /*
+ TWL_ADJUSTABLE_LDO(VPLL1, 0x2f, 7),
+ */
+ TWL_ADJUSTABLE_LDO(VPLL2, 0x33, 8),
+ TWL_ADJUSTABLE_LDO(VSIM, 0x37, 9),
+ TWL_ADJUSTABLE_LDO(VDAC, 0x3b, 10),
+ /*
+ TWL_ADJUSTABLE_LDO(VINTANA1, 0x3f, 11),
+ TWL_ADJUSTABLE_LDO(VINTANA2, 0x43, 12),
+ TWL_ADJUSTABLE_LDO(VINTDIG, 0x47, 13),
+ TWL_SMPS(VIO, 0x4b, 14),
+ TWL_SMPS(VDD1, 0x55, 15),
+ TWL_SMPS(VDD2, 0x63, 16),
+ */
+ TWL_FIXED_LDO(VUSB1V5, 0x71, 1500, 17),
+ TWL_FIXED_LDO(VUSB1V8, 0x74, 1800, 18),
+ TWL_FIXED_LDO(VUSB3V1, 0x77, 3100, 19),
+ /* VUSBCP is managed *only* by the USB subchip */
+};
+
+static int twl4030reg_probe(struct platform_device *pdev)
+{
+ int i;
+ struct twlreg_info *info;
+ struct regulator_init_data *initdata;
+ struct regulation_constraints *c;
+ struct regulator_dev *rdev;
+
+ for (i = 0, info = NULL; i < ARRAY_SIZE(twl4030_regs); i++) {
+ if (twl4030_regs[i].desc.id != pdev->id)
+ continue;
+ info = twl4030_regs + i;
+ break;
+ }
+ if (!info)
+ return -ENODEV;
+
+ initdata = pdev->dev.platform_data;
+ if (!initdata)
+ return -EINVAL;
+
+ /* Constrain board-specific capabilities according to what
+ * this driver and the chip itself can actually do.
+ */
+ c = &initdata->constraints;
+ c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
+ c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
+ | REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS;
+
+ rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "can't register %s, %ld\n",
+ info->desc.name, PTR_ERR(rdev));
+ return PTR_ERR(rdev);
+ }
+ platform_set_drvdata(pdev, rdev);
+
+ /* NOTE: many regulators support short-circuit IRQs (presentable
+ * as REGULATOR_OVER_CURRENT notifications?) configured via:
+ * - SC_CONFIG
+ * - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
+ * - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
+ * - IT_CONFIG
+ */
+
+ return 0;
+}
+
+static int __devexit twl4030reg_remove(struct platform_device *pdev)
+{
+ regulator_unregister(platform_get_drvdata(pdev));
+ return 0;
+}
+
+MODULE_ALIAS("platform:twl4030_reg");
+
+static struct platform_driver twl4030reg_driver = {
+ .probe = twl4030reg_probe,
+ .remove = __devexit_p(twl4030reg_remove),
+ /* NOTE: short name, to work around driver model truncation of
+ * "twl4030_regulator.12" (and friends) to "twl4030_regulator.1".
+ */
+ .driver.name = "twl4030_reg",
+ .driver.owner = THIS_MODULE,
+};
+
+static int __init twl4030reg_init(void)
+{
+ return platform_driver_register(&twl4030reg_driver);
+}
+subsys_initcall(twl4030reg_init);
+
+static void __exit twl4030reg_exit(void)
+{
+ platform_driver_unregister(&twl4030reg_driver);
+}
+module_exit(twl4030reg_exit)
+
+MODULE_DESCRIPTION("TWL4030 regulator driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c
index 5ddb464b1c3..3d08348584e 100644
--- a/drivers/regulator/virtual.c
+++ b/drivers/regulator/virtual.c
@@ -226,13 +226,17 @@ static ssize_t set_mode(struct device *dev, struct device_attribute *attr,
unsigned int mode;
int ret;
- if (strncmp(buf, "fast", strlen("fast")) == 0)
+ /*
+ * sysfs_streq() doesn't need the \n's, but we add them so the strings
+ * will be shared with show_mode(), above.
+ */
+ if (sysfs_streq(buf, "fast\n") == 0)
mode = REGULATOR_MODE_FAST;
- else if (strncmp(buf, "normal", strlen("normal")) == 0)
+ else if (sysfs_streq(buf, "normal\n") == 0)
mode = REGULATOR_MODE_NORMAL;
- else if (strncmp(buf, "idle", strlen("idle")) == 0)
+ else if (sysfs_streq(buf, "idle\n") == 0)
mode = REGULATOR_MODE_IDLE;
- else if (strncmp(buf, "standby", strlen("standby")) == 0)
+ else if (sysfs_streq(buf, "standby\n") == 0)
mode = REGULATOR_MODE_STANDBY;
else {
dev_err(dev, "Configuring invalid mode\n");
@@ -256,7 +260,7 @@ static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA);
static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
-struct device_attribute *attributes[] = {
+static struct device_attribute *attributes[] = {
&dev_attr_min_microvolts,
&dev_attr_max_microvolts,
&dev_attr_min_microamps,
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c
index 5056e23e441..771eca1066b 100644
--- a/drivers/regulator/wm8350-regulator.c
+++ b/drivers/regulator/wm8350-regulator.c
@@ -24,6 +24,9 @@
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
+/* Maximum value possible for VSEL */
+#define WM8350_DCDC_MAX_VSEL 0x66
+
/* Microamps */
static const int isink_cur[] = {
4,
@@ -385,6 +388,14 @@ static int wm8350_dcdc_get_voltage(struct regulator_dev *rdev)
return wm8350_dcdc_val_to_mvolts(val) * 1000;
}
+static int wm8350_dcdc_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector > WM8350_DCDC_MAX_VSEL)
+ return -EINVAL;
+ return wm8350_dcdc_val_to_mvolts(selector) * 1000;
+}
+
static int wm8350_dcdc_set_suspend_voltage(struct regulator_dev *rdev, int uV)
{
struct wm8350 *wm8350 = rdev_get_drvdata(rdev);
@@ -775,6 +786,14 @@ static int wm8350_ldo_get_voltage(struct regulator_dev *rdev)
return wm8350_ldo_val_to_mvolts(val) * 1000;
}
+static int wm8350_ldo_list_voltage(struct regulator_dev *rdev,
+ unsigned selector)
+{
+ if (selector > WM8350_LDO1_VSEL_MASK)
+ return -EINVAL;
+ return wm8350_ldo_val_to_mvolts(selector) * 1000;
+}
+
int wm8350_dcdc_set_slot(struct wm8350 *wm8350, int dcdc, u16 start,
u16 stop, u16 fault)
{
@@ -1031,18 +1050,30 @@ static unsigned int wm8350_dcdc_get_mode(struct regulator_dev *rdev)
int dcdc = rdev_get_id(rdev);
u16 mask, sleep, active, force;
int mode = REGULATOR_MODE_NORMAL;
+ int reg;
- if (dcdc < WM8350_DCDC_1 || dcdc > WM8350_DCDC_6)
- return -EINVAL;
-
- if (dcdc == WM8350_DCDC_2 || dcdc == WM8350_DCDC_5)
+ switch (dcdc) {
+ case WM8350_DCDC_1:
+ reg = WM8350_DCDC1_FORCE_PWM;
+ break;
+ case WM8350_DCDC_3:
+ reg = WM8350_DCDC3_FORCE_PWM;
+ break;
+ case WM8350_DCDC_4:
+ reg = WM8350_DCDC4_FORCE_PWM;
+ break;
+ case WM8350_DCDC_6:
+ reg = WM8350_DCDC6_FORCE_PWM;
+ break;
+ default:
return -EINVAL;
+ }
mask = 1 << (dcdc - WM8350_DCDC_1);
active = wm8350_reg_read(wm8350, WM8350_DCDC_ACTIVE_OPTIONS) & mask;
+ force = wm8350_reg_read(wm8350, reg) & WM8350_DCDC1_FORCE_PWM_ENA;
sleep = wm8350_reg_read(wm8350, WM8350_DCDC_SLEEP_OPTIONS) & mask;
- force = wm8350_reg_read(wm8350, WM8350_DCDC1_FORCE_PWM)
- & WM8350_DCDC1_FORCE_PWM_ENA;
+
dev_dbg(wm8350->dev, "mask %x active %x sleep %x force %x",
mask, active, sleep, force);
@@ -1150,6 +1181,7 @@ static int wm8350_ldo_is_enabled(struct regulator_dev *rdev)
static struct regulator_ops wm8350_dcdc_ops = {
.set_voltage = wm8350_dcdc_set_voltage,
.get_voltage = wm8350_dcdc_get_voltage,
+ .list_voltage = wm8350_dcdc_list_voltage,
.enable = wm8350_dcdc_enable,
.disable = wm8350_dcdc_disable,
.get_mode = wm8350_dcdc_get_mode,
@@ -1173,6 +1205,7 @@ static struct regulator_ops wm8350_dcdc2_5_ops = {
static struct regulator_ops wm8350_ldo_ops = {
.set_voltage = wm8350_ldo_set_voltage,
.get_voltage = wm8350_ldo_get_voltage,
+ .list_voltage = wm8350_ldo_list_voltage,
.enable = wm8350_ldo_enable,
.disable = wm8350_ldo_disable,
.is_enabled = wm8350_ldo_is_enabled,
@@ -1197,6 +1230,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC1,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1213,6 +1247,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC3,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1221,6 +1256,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC4,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1237,6 +1273,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_dcdc_ops,
.irq = WM8350_IRQ_UV_DC6,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_DCDC_MAX_VSEL + 1,
.owner = THIS_MODULE,
},
{
@@ -1245,6 +1282,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO1,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO1_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1253,6 +1291,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO2,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO2_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1261,6 +1300,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO3,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO3_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1269,6 +1309,7 @@ static struct regulator_desc wm8350_reg[NUM_WM8350_REGULATORS] = {
.ops = &wm8350_ldo_ops,
.irq = WM8350_IRQ_UV_LDO4,
.type = REGULATOR_VOLTAGE,
+ .n_voltages = WM8350_LDO4_VSEL_MASK + 1,
.owner = THIS_MODULE,
},
{
@@ -1293,6 +1334,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
{
struct regulator_dev *rdev = (struct regulator_dev *)data;
+ mutex_lock(&rdev->mutex);
if (irq == WM8350_IRQ_CS1 || irq == WM8350_IRQ_CS2)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_REGULATION_OUT,
@@ -1301,6 +1343,7 @@ static void pmic_uv_handler(struct wm8350 *wm8350, int irq, void *data)
regulator_notifier_call_chain(rdev,
REGULATOR_EVENT_UNDER_VOLTAGE,
wm8350);
+ mutex_unlock(&rdev->mutex);
}
static int wm8350_regulator_probe(struct platform_device *pdev)
@@ -1333,9 +1376,9 @@ static int wm8350_regulator_probe(struct platform_device *pdev)
break;
}
-
/* register regulator */
rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev,
+ pdev->dev.platform_data,
dev_get_drvdata(&pdev->dev));
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register %s\n",
diff --git a/drivers/regulator/wm8400-regulator.c b/drivers/regulator/wm8400-regulator.c
index 56e23d44ba5..15742602907 100644
--- a/drivers/regulator/wm8400-regulator.c
+++ b/drivers/regulator/wm8400-regulator.c
@@ -43,6 +43,18 @@ static int wm8400_ldo_disable(struct regulator_dev *dev)
WM8400_LDO1_ENA, 0);
}
+static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ if (selector > WM8400_LDO1_VSEL_MASK)
+ return -EINVAL;
+
+ if (selector < 15)
+ return 900000 + (selector * 50000);
+ else
+ return 1600000 + ((selector - 14) * 100000);
+}
+
static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -51,10 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
val &= WM8400_LDO1_VSEL_MASK;
- if (val < 15)
- return 900000 + (val * 50000);
- else
- return 1600000 + ((val - 14) * 100000);
+ return wm8400_ldo_list_voltage(dev, val);
}
static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
@@ -92,6 +101,7 @@ static struct regulator_ops wm8400_ldo_ops = {
.is_enabled = wm8400_ldo_is_enabled,
.enable = wm8400_ldo_enable,
.disable = wm8400_ldo_disable,
+ .list_voltage = wm8400_ldo_list_voltage,
.get_voltage = wm8400_ldo_get_voltage,
.set_voltage = wm8400_ldo_set_voltage,
};
@@ -124,6 +134,15 @@ static int wm8400_dcdc_disable(struct regulator_dev *dev)
WM8400_DC1_ENA, 0);
}
+static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
+ unsigned selector)
+{
+ if (selector > WM8400_DC1_VSEL_MASK)
+ return -EINVAL;
+
+ return 850000 + (selector * 25000);
+}
+
static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
{
struct wm8400 *wm8400 = rdev_get_drvdata(dev);
@@ -237,6 +256,7 @@ static struct regulator_ops wm8400_dcdc_ops = {
.is_enabled = wm8400_dcdc_is_enabled,
.enable = wm8400_dcdc_enable,
.disable = wm8400_dcdc_disable,
+ .list_voltage = wm8400_dcdc_list_voltage,
.get_voltage = wm8400_dcdc_get_voltage,
.set_voltage = wm8400_dcdc_set_voltage,
.get_mode = wm8400_dcdc_get_mode,
@@ -249,6 +269,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO1",
.id = WM8400_LDO1,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -256,6 +277,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO2",
.id = WM8400_LDO2,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -263,6 +285,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO3",
.id = WM8400_LDO3,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO3_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -270,6 +293,7 @@ static struct regulator_desc regulators[] = {
.name = "LDO4",
.id = WM8400_LDO4,
.ops = &wm8400_ldo_ops,
+ .n_voltages = WM8400_LDO4_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -277,6 +301,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC1",
.id = WM8400_DCDC1,
.ops = &wm8400_dcdc_ops,
+ .n_voltages = WM8400_DC1_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -284,6 +309,7 @@ static struct regulator_desc regulators[] = {
.name = "DCDC2",
.id = WM8400_DCDC2,
.ops = &wm8400_dcdc_ops,
+ .n_voltages = WM8400_DC2_VSEL_MASK + 1,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
@@ -294,7 +320,7 @@ static int __devinit wm8400_regulator_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
rdev = regulator_register(&regulators[pdev->id], &pdev->dev,
- pdev->dev.driver_data);
+ pdev->dev.platform_data, pdev->dev.driver_data);
if (IS_ERR(rdev))
return PTR_ERR(rdev);
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 81450fbd8b1..ffe34a12f44 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -129,13 +129,14 @@ comment "I2C RTC drivers"
if I2C
config RTC_DRV_DS1307
- tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00"
+ tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025"
help
If you say yes here you get support for various compatible RTC
chips (often with battery backup) connected with I2C. This driver
should handle DS1307, DS1337, DS1338, DS1339, DS1340, ST M41T00,
- and probably other chips. In some cases the RTC must already
- have been initialized (by manufacturing or a bootloader).
+ EPSON RX-8025 and probably other chips. In some cases the RTC
+ must already have been initialized (by manufacturing or a
+ bootloader).
The first seven registers on these chips hold an RTC, and other
registers may add features such as NVRAM, a trickle charger for
@@ -224,11 +225,11 @@ config RTC_DRV_PCF8583
will be called rtc-pcf8583.
config RTC_DRV_M41T80
- tristate "ST M41T65/M41T80/81/82/83/84/85/87"
+ tristate "ST M41T62/65/M41T80/81/82/83/84/85/87"
help
If you say Y here you will get support for the ST M41T60
and M41T80 RTC chips series. Currently, the following chips are
- supported: M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
+ supported: M41T62, M41T65, M41T80, M41T81, M41T82, M41T83, M41ST84,
M41ST85, and M41ST87.
This driver can also be built as a module. If so, the module
@@ -440,6 +441,16 @@ config RTC_DRV_DS1742
This driver can also be built as a module. If so, the module
will be called rtc-ds1742.
+config RTC_DRV_EFI
+ tristate "EFI RTC"
+ depends on IA64
+ help
+ If you say yes here you will get support for the EFI
+ Real Time Clock.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-efi.
+
config RTC_DRV_STK17TA8
tristate "Simtek STK17TA8"
depends on RTC_CLASS
@@ -677,22 +688,16 @@ config RTC_DRV_RS5C313
help
If you say yes here you get support for the Ricoh RS5C313 RTC chips.
-config RTC_DRV_PARISC
- tristate "PA-RISC firmware RTC support"
- depends on PARISC
+config RTC_DRV_GENERIC
+ tristate "Generic RTC support"
+ # Please consider writing a new RTC driver instead of using the generic
+ # RTC abstraction
+ depends on PARISC || M68K || PPC
help
- Say Y or M here to enable RTC support on PA-RISC systems using
- firmware calls. If you do not know what you are doing, you should
+ Say Y or M here to enable RTC support on systems using the generic
+ RTC abstraction. If you do not know what you are doing, you should
just say Y.
-config RTC_DRV_PPC
- tristate "PowerPC machine dependent RTC support"
- depends on PPC
- help
- The PowerPC kernel has machine-specific functions for accessing
- the RTC. This exposes that functionality through the generic RTC
- class.
-
config RTC_DRV_PXA
tristate "PXA27x/PXA3xx"
depends on ARCH_PXA
@@ -736,4 +741,13 @@ config RTC_DRV_MV
This driver can also be built as a module. If so, the module
will be called rtc-mv.
+config RTC_DRV_PS3
+ tristate "PS3 RTC"
+ depends on PPC_PS3
+ help
+ If you say yes here you will get support for the RTC on PS3.
+
+ This driver can also be built as a module. If so, the module
+ will be called rtc-ps3.
+
endif # RTC_CLASS
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 0e697aa51ca..6c0639a14f0 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -36,6 +36,7 @@ obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
obj-$(CONFIG_RTC_DRV_DS3234) += rtc-ds3234.o
+obj-$(CONFIG_RTC_DRV_EFI) += rtc-efi.o
obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o
obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o
obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o
@@ -55,8 +56,7 @@ obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PL030) += rtc-pl030.o
obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o
-obj-$(CONFIG_RTC_DRV_PARISC) += rtc-parisc.o
-obj-$(CONFIG_RTC_DRV_PPC) += rtc-ppc.o
+obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o
obj-$(CONFIG_RTC_DRV_PXA) += rtc-pxa.o
obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o
obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o
@@ -76,3 +76,4 @@ obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
+obj-$(CONFIG_RTC_DRV_PS3) += rtc-ps3.o
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c
index 7e5155e88ac..2c4a65302a9 100644
--- a/drivers/rtc/rtc-ds1307.c
+++ b/drivers/rtc/rtc-ds1307.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2005 James Chapman (ds1337 core)
* Copyright (C) 2006 David Brownell
+ * Copyright (C) 2009 Matthias Fuchs (rx8025 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
@@ -31,6 +32,7 @@ enum ds_type {
ds_1339,
ds_1340,
m41t00,
+ rx_8025,
// rs5c372 too? different address...
};
@@ -83,6 +85,12 @@ enum ds_type {
#define DS1339_REG_ALARM1_SECS 0x07
#define DS1339_REG_TRICKLE 0x10
+#define RX8025_REG_CTRL1 0x0e
+# define RX8025_BIT_2412 0x20
+#define RX8025_REG_CTRL2 0x0f
+# define RX8025_BIT_PON 0x10
+# define RX8025_BIT_VDET 0x40
+# define RX8025_BIT_XST 0x20
struct ds1307 {
@@ -94,6 +102,10 @@ struct ds1307 {
struct i2c_client *client;
struct rtc_device *rtc;
struct work_struct work;
+ s32 (*read_block_data)(struct i2c_client *client, u8 command,
+ u8 length, u8 *values);
+ s32 (*write_block_data)(struct i2c_client *client, u8 command,
+ u8 length, const u8 *values);
};
struct chip_desc {
@@ -117,6 +129,8 @@ static const struct chip_desc chips[] = {
[ds_1340] = {
},
[m41t00] = {
+},
+[rx_8025] = {
}, };
static const struct i2c_device_id ds1307_id[] = {
@@ -126,12 +140,86 @@ static const struct i2c_device_id ds1307_id[] = {
{ "ds1339", ds_1339 },
{ "ds1340", ds_1340 },
{ "m41t00", m41t00 },
+ { "rx8025", rx_8025 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ds1307_id);
/*----------------------------------------------------------------------*/
+#define BLOCK_DATA_MAX_TRIES 10
+
+static s32 ds1307_read_block_data_once(struct i2c_client *client, u8 command,
+ u8 length, u8 *values)
+{
+ s32 i, data;
+
+ for (i = 0; i < length; i++) {
+ data = i2c_smbus_read_byte_data(client, command + i);
+ if (data < 0)
+ return data;
+ values[i] = data;
+ }
+ return i;
+}
+
+static s32 ds1307_read_block_data(struct i2c_client *client, u8 command,
+ u8 length, u8 *values)
+{
+ u8 oldvalues[I2C_SMBUS_BLOCK_MAX];
+ s32 ret;
+ int tries = 0;
+
+ dev_dbg(&client->dev, "ds1307_read_block_data (length=%d)\n", length);
+ ret = ds1307_read_block_data_once(client, command, length, values);
+ if (ret < 0)
+ return ret;
+ do {
+ if (++tries > BLOCK_DATA_MAX_TRIES) {
+ dev_err(&client->dev,
+ "ds1307_read_block_data failed\n");
+ return -EIO;
+ }
+ memcpy(oldvalues, values, length);
+ ret = ds1307_read_block_data_once(client, command, length,
+ values);
+ if (ret < 0)
+ return ret;
+ } while (memcmp(oldvalues, values, length));
+ return length;
+}
+
+static s32 ds1307_write_block_data(struct i2c_client *client, u8 command,
+ u8 length, const u8 *values)
+{
+ u8 currvalues[I2C_SMBUS_BLOCK_MAX];
+ int tries = 0;
+
+ dev_dbg(&client->dev, "ds1307_write_block_data (length=%d)\n", length);
+ do {
+ s32 i, ret;
+
+ if (++tries > BLOCK_DATA_MAX_TRIES) {
+ dev_err(&client->dev,
+ "ds1307_write_block_data failed\n");
+ return -EIO;
+ }
+ for (i = 0; i < length; i++) {
+ ret = i2c_smbus_write_byte_data(client, command + i,
+ values[i]);
+ if (ret < 0)
+ return ret;
+ }
+ ret = ds1307_read_block_data_once(client, command, length,
+ currvalues);
+ if (ret < 0)
+ return ret;
+ } while (memcmp(currvalues, values, length));
+ return length;
+}
+
+/*----------------------------------------------------------------------*/
+
/*
* The IRQ logic includes a "real" handler running in IRQ context just
* long enough to schedule this workqueue entry. We need a task context
@@ -202,7 +290,7 @@ static int ds1307_get_time(struct device *dev, struct rtc_time *t)
int tmp;
/* read the RTC date and time registers all at once */
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ tmp = ds1307->read_block_data(ds1307->client,
DS1307_REG_SECS, 7, ds1307->regs);
if (tmp != 7) {
dev_err(dev, "%s error %d\n", "read", tmp);
@@ -279,7 +367,7 @@ static int ds1307_set_time(struct device *dev, struct rtc_time *t)
"write", buf[0], buf[1], buf[2], buf[3],
buf[4], buf[5], buf[6]);
- result = i2c_smbus_write_i2c_block_data(ds1307->client, 0, 7, buf);
+ result = ds1307->write_block_data(ds1307->client, 0, 7, buf);
if (result < 0) {
dev_err(dev, "%s error %d\n", "write", result);
return result;
@@ -297,7 +385,7 @@ static int ds1337_read_alarm(struct device *dev, struct rtc_wkalrm *t)
return -EINVAL;
/* read all ALARM1, ALARM2, and status registers at once */
- ret = i2c_smbus_read_i2c_block_data(client,
+ ret = ds1307->read_block_data(client,
DS1339_REG_ALARM1_SECS, 9, ds1307->regs);
if (ret != 9) {
dev_err(dev, "%s error %d\n", "alarm read", ret);
@@ -356,7 +444,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
t->enabled, t->pending);
/* read current status of both alarms and the chip */
- ret = i2c_smbus_read_i2c_block_data(client,
+ ret = ds1307->read_block_data(client,
DS1339_REG_ALARM1_SECS, 9, buf);
if (ret != 9) {
dev_err(dev, "%s error %d\n", "alarm write", ret);
@@ -391,7 +479,7 @@ static int ds1337_set_alarm(struct device *dev, struct rtc_wkalrm *t)
}
buf[8] = status & ~(DS1337_BIT_A1I | DS1337_BIT_A2I);
- ret = i2c_smbus_write_i2c_block_data(client,
+ ret = ds1307->write_block_data(client,
DS1339_REG_ALARM1_SECS, 9, buf);
if (ret < 0) {
dev_err(dev, "can't set alarm time\n");
@@ -479,7 +567,7 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr,
if (unlikely(!count))
return count;
- result = i2c_smbus_read_i2c_block_data(client, 8 + off, count, buf);
+ result = ds1307->read_block_data(client, 8 + off, count, buf);
if (result < 0)
dev_err(&client->dev, "%s error %d\n", "nvram read", result);
return result;
@@ -490,9 +578,11 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
struct i2c_client *client;
+ struct ds1307 *ds1307;
int result;
client = kobj_to_i2c_client(kobj);
+ ds1307 = i2c_get_clientdata(client);
if (unlikely(off >= NVRAM_SIZE))
return -EFBIG;
@@ -501,7 +591,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr,
if (unlikely(!count))
return count;
- result = i2c_smbus_write_i2c_block_data(client, 8 + off, count, buf);
+ result = ds1307->write_block_data(client, 8 + off, count, buf);
if (result < 0) {
dev_err(&client->dev, "%s error %d\n", "nvram write", result);
return result;
@@ -535,9 +625,8 @@ static int __devinit ds1307_probe(struct i2c_client *client,
int want_irq = false;
unsigned char *buf;
- if (!i2c_check_functionality(adapter,
- I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
- I2C_FUNC_SMBUS_I2C_BLOCK))
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)
+ && !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
return -EIO;
if (!(ds1307 = kzalloc(sizeof(struct ds1307), GFP_KERNEL)))
@@ -547,6 +636,13 @@ static int __devinit ds1307_probe(struct i2c_client *client,
i2c_set_clientdata(client, ds1307);
ds1307->type = id->driver_data;
buf = ds1307->regs;
+ if (i2c_check_functionality(adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
+ ds1307->read_block_data = i2c_smbus_read_i2c_block_data;
+ ds1307->write_block_data = i2c_smbus_write_i2c_block_data;
+ } else {
+ ds1307->read_block_data = ds1307_read_block_data;
+ ds1307->write_block_data = ds1307_write_block_data;
+ }
switch (ds1307->type) {
case ds_1337:
@@ -557,7 +653,7 @@ static int __devinit ds1307_probe(struct i2c_client *client,
want_irq = true;
}
/* get registers that the "rtc" read below won't read... */
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ tmp = ds1307->read_block_data(ds1307->client,
DS1337_REG_CONTROL, 2, buf);
if (tmp != 2) {
pr_debug("read error %d\n", tmp);
@@ -589,13 +685,79 @@ static int __devinit ds1307_probe(struct i2c_client *client,
dev_warn(&client->dev, "SET TIME!\n");
}
break;
+
+ case rx_8025:
+ tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+ if (tmp != 2) {
+ pr_debug("read error %d\n", tmp);
+ err = -EIO;
+ goto exit_free;
+ }
+
+ /* oscillator off? turn it on, so clock can tick. */
+ if (!(ds1307->regs[1] & RX8025_BIT_XST)) {
+ ds1307->regs[1] |= RX8025_BIT_XST;
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL2 << 4 | 0x08,
+ ds1307->regs[1]);
+ dev_warn(&client->dev,
+ "oscillator stop detected - SET TIME!\n");
+ }
+
+ if (ds1307->regs[1] & RX8025_BIT_PON) {
+ ds1307->regs[1] &= ~RX8025_BIT_PON;
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL2 << 4 | 0x08,
+ ds1307->regs[1]);
+ dev_warn(&client->dev, "power-on detected\n");
+ }
+
+ if (ds1307->regs[1] & RX8025_BIT_VDET) {
+ ds1307->regs[1] &= ~RX8025_BIT_VDET;
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL2 << 4 | 0x08,
+ ds1307->regs[1]);
+ dev_warn(&client->dev, "voltage drop detected\n");
+ }
+
+ /* make sure we are running in 24hour mode */
+ if (!(ds1307->regs[0] & RX8025_BIT_2412)) {
+ u8 hour;
+
+ /* switch to 24 hour mode */
+ i2c_smbus_write_byte_data(client,
+ RX8025_REG_CTRL1 << 4 | 0x08,
+ ds1307->regs[0] |
+ RX8025_BIT_2412);
+
+ tmp = i2c_smbus_read_i2c_block_data(ds1307->client,
+ RX8025_REG_CTRL1 << 4 | 0x08, 2, buf);
+ if (tmp != 2) {
+ pr_debug("read error %d\n", tmp);
+ err = -EIO;
+ goto exit_free;
+ }
+
+ /* correct hour */
+ hour = bcd2bin(ds1307->regs[DS1307_REG_HOUR]);
+ if (hour == 12)
+ hour = 0;
+ if (ds1307->regs[DS1307_REG_HOUR] & DS1307_BIT_PM)
+ hour += 12;
+
+ i2c_smbus_write_byte_data(client,
+ DS1307_REG_HOUR << 4 | 0x08,
+ hour);
+ }
+ break;
default:
break;
}
read_rtc:
/* read RTC registers */
- tmp = i2c_smbus_read_i2c_block_data(ds1307->client, 0, 8, buf);
+ tmp = ds1307->read_block_data(ds1307->client, 0, 8, buf);
if (tmp != 8) {
pr_debug("read error %d\n", tmp);
err = -EIO;
@@ -649,6 +811,7 @@ read_rtc:
dev_warn(&client->dev, "SET TIME!\n");
}
break;
+ case rx_8025:
case ds_1337:
case ds_1339:
break;
@@ -662,6 +825,8 @@ read_rtc:
* systems that will run through year 2100.
*/
break;
+ case rx_8025:
+ break;
default:
if (!(tmp & DS1307_BIT_12HR))
break;
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
index a5b0fc09f0c..4d32e328f6c 100644
--- a/drivers/rtc/rtc-ds1374.c
+++ b/drivers/rtc/rtc-ds1374.c
@@ -222,16 +222,16 @@ static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
rtc_tm_to_time(&alarm->time, &new_alarm);
rtc_tm_to_time(&now, &itime);
- new_alarm -= itime;
-
/* This can happen due to races, in addition to dates that are
* truly in the past. To avoid requiring the caller to check for
* races, dates in the past are assumed to be in the recent past
* (i.e. not something that we'd rather the caller know about via
* an error), and the alarm is set to go off as soon as possible.
*/
- if (new_alarm <= 0)
+ if (time_before_eq(new_alarm, itime))
new_alarm = 1;
+ else
+ new_alarm -= itime;
mutex_lock(&ds1374->mutex);
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
new file mode 100644
index 00000000000..550292304b0
--- /dev/null
+++ b/drivers/rtc/rtc-efi.c
@@ -0,0 +1,235 @@
+/*
+ * rtc-efi: RTC Class Driver for EFI-based systems
+ *
+ * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
+ *
+ * Author: dann frazier <dannf@hp.com>
+ * Based on efirtc.c by Stephane Eranian
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/efi.h>
+
+#define EFI_ISDST (EFI_TIME_ADJUST_DAYLIGHT|EFI_TIME_IN_DAYLIGHT)
+/*
+ * EFI Epoch is 1/1/1998
+ */
+#define EFI_RTC_EPOCH 1998
+
+/*
+ * returns day of the year [0-365]
+ */
+static inline int
+compute_yday(efi_time_t *eft)
+{
+ /* efi_time_t.month is in the [1-12] so, we need -1 */
+ return rtc_year_days(eft->day - 1, eft->month - 1, eft->year);
+}
+/*
+ * returns day of the week [0-6] 0=Sunday
+ *
+ * Don't try to provide a year that's before 1998, please !
+ */
+static int
+compute_wday(efi_time_t *eft)
+{
+ int y;
+ int ndays = 0;
+
+ if (eft->year < 1998) {
+ printk(KERN_ERR "efirtc: EFI year < 1998, invalid date\n");
+ return -1;
+ }
+
+ for (y = EFI_RTC_EPOCH; y < eft->year; y++)
+ ndays += 365 + (is_leap_year(y) ? 1 : 0);
+
+ ndays += compute_yday(eft);
+
+ /*
+ * 4=1/1/1998 was a Thursday
+ */
+ return (ndays + 4) % 7;
+}
+
+static void
+convert_to_efi_time(struct rtc_time *wtime, efi_time_t *eft)
+{
+ eft->year = wtime->tm_year + 1900;
+ eft->month = wtime->tm_mon + 1;
+ eft->day = wtime->tm_mday;
+ eft->hour = wtime->tm_hour;
+ eft->minute = wtime->tm_min;
+ eft->second = wtime->tm_sec;
+ eft->nanosecond = 0;
+ eft->daylight = wtime->tm_isdst ? EFI_ISDST : 0;
+ eft->timezone = EFI_UNSPECIFIED_TIMEZONE;
+}
+
+static void
+convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime)
+{
+ memset(wtime, 0, sizeof(*wtime));
+ wtime->tm_sec = eft->second;
+ wtime->tm_min = eft->minute;
+ wtime->tm_hour = eft->hour;
+ wtime->tm_mday = eft->day;
+ wtime->tm_mon = eft->month - 1;
+ wtime->tm_year = eft->year - 1900;
+
+ /* day of the week [0-6], Sunday=0 */
+ wtime->tm_wday = compute_wday(eft);
+
+ /* day in the year [1-365]*/
+ wtime->tm_yday = compute_yday(eft);
+
+
+ switch (eft->daylight & EFI_ISDST) {
+ case EFI_ISDST:
+ wtime->tm_isdst = 1;
+ break;
+ case EFI_TIME_ADJUST_DAYLIGHT:
+ wtime->tm_isdst = 0;
+ break;
+ default:
+ wtime->tm_isdst = -1;
+ }
+}
+
+static int efi_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+ efi_time_t eft;
+ efi_status_t status;
+
+ /*
+ * As of EFI v1.10, this call always returns an unsupported status
+ */
+ status = efi.get_wakeup_time((efi_bool_t *)&wkalrm->enabled,
+ (efi_bool_t *)&wkalrm->pending, &eft);
+
+ if (status != EFI_SUCCESS)
+ return -EINVAL;
+
+ convert_from_efi_time(&eft, &wkalrm->time);
+
+ return rtc_valid_tm(&wkalrm->time);
+}
+
+static int efi_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm)
+{
+ efi_time_t eft;
+ efi_status_t status;
+
+ convert_to_efi_time(&wkalrm->time, &eft);
+
+ /*
+ * XXX Fixme:
+ * As of EFI 0.92 with the firmware I have on my
+ * machine this call does not seem to work quite
+ * right
+ *
+ * As of v1.10, this call always returns an unsupported status
+ */
+ status = efi.set_wakeup_time((efi_bool_t)wkalrm->enabled, &eft);
+
+ printk(KERN_WARNING "write status is %d\n", (int)status);
+
+ return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static int efi_read_time(struct device *dev, struct rtc_time *tm)
+{
+ efi_status_t status;
+ efi_time_t eft;
+ efi_time_cap_t cap;
+
+ status = efi.get_time(&eft, &cap);
+
+ if (status != EFI_SUCCESS) {
+ /* should never happen */
+ printk(KERN_ERR "efitime: can't read time\n");
+ return -EINVAL;
+ }
+
+ convert_from_efi_time(&eft, tm);
+
+ return rtc_valid_tm(tm);
+}
+
+static int efi_set_time(struct device *dev, struct rtc_time *tm)
+{
+ efi_status_t status;
+ efi_time_t eft;
+
+ convert_to_efi_time(tm, &eft);
+
+ status = efi.set_time(&eft);
+
+ return status == EFI_SUCCESS ? 0 : -EINVAL;
+}
+
+static const struct rtc_class_ops efi_rtc_ops = {
+ .read_time = efi_read_time,
+ .set_time = efi_set_time,
+ .read_alarm = efi_read_alarm,
+ .set_alarm = efi_set_alarm,
+};
+
+static int __init efi_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-efi", &dev->dev, &efi_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+
+ return 0;
+}
+
+static int __exit efi_rtc_remove(struct platform_device *dev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(dev);
+
+ rtc_device_unregister(rtc);
+
+ return 0;
+}
+
+static struct platform_driver efi_rtc_driver = {
+ .driver = {
+ .name = "rtc-efi",
+ .owner = THIS_MODULE,
+ },
+ .probe = efi_rtc_probe,
+ .remove = __exit_p(efi_rtc_remove),
+};
+
+static int __init efi_rtc_init(void)
+{
+ return platform_driver_probe(&efi_rtc_driver, efi_rtc_probe);
+}
+
+static void __exit efi_rtc_exit(void)
+{
+ platform_driver_unregister(&efi_rtc_driver);
+}
+
+module_init(efi_rtc_init);
+module_exit(efi_rtc_exit);
+
+MODULE_AUTHOR("dann frazier <dannf@hp.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EFI RTC driver");
diff --git a/drivers/rtc/rtc-generic.c b/drivers/rtc/rtc-generic.c
new file mode 100644
index 00000000000..98322004ad2
--- /dev/null
+++ b/drivers/rtc/rtc-generic.c
@@ -0,0 +1,84 @@
+/* rtc-generic: RTC driver using the generic RTC abstraction
+ *
+ * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/rtc.h>
+
+static int generic_get_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned int ret = get_rtc_time(tm);
+
+ if (ret & RTC_BATT_BAD)
+ return -EOPNOTSUPP;
+
+ return rtc_valid_tm(tm);
+}
+
+static int generic_set_time(struct device *dev, struct rtc_time *tm)
+{
+ if (set_rtc_time(tm) < 0)
+ return -EOPNOTSUPP;
+
+ return 0;
+}
+
+static const struct rtc_class_ops generic_rtc_ops = {
+ .read_time = generic_get_time,
+ .set_time = generic_set_time,
+};
+
+static int __init generic_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-generic", &dev->dev, &generic_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+
+ return 0;
+}
+
+static int __exit generic_rtc_remove(struct platform_device *dev)
+{
+ struct rtc_device *rtc = platform_get_drvdata(dev);
+
+ rtc_device_unregister(rtc);
+
+ return 0;
+}
+
+static struct platform_driver generic_rtc_driver = {
+ .driver = {
+ .name = "rtc-generic",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(generic_rtc_remove),
+};
+
+static int __init generic_rtc_init(void)
+{
+ return platform_driver_probe(&generic_rtc_driver, generic_rtc_probe);
+}
+
+static void __exit generic_rtc_fini(void)
+{
+ platform_driver_unregister(&generic_rtc_driver);
+}
+
+module_init(generic_rtc_init);
+module_exit(generic_rtc_fini);
+
+MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Generic RTC driver");
+MODULE_ALIAS("platform:rtc-generic");
diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c
index dd70bf73ce9..773851f338b 100644
--- a/drivers/rtc/rtc-lib.c
+++ b/drivers/rtc/rtc-lib.c
@@ -26,14 +26,13 @@ static const unsigned short rtc_ydays[2][13] = {
};
#define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
-#define LEAP_YEAR(year) ((!(year % 4) && (year % 100)) || !(year % 400))
/*
* The number of days in the month.
*/
int rtc_month_days(unsigned int month, unsigned int year)
{
- return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1);
+ return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
}
EXPORT_SYMBOL(rtc_month_days);
@@ -42,7 +41,7 @@ EXPORT_SYMBOL(rtc_month_days);
*/
int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
{
- return rtc_ydays[LEAP_YEAR(year)][month] + day-1;
+ return rtc_ydays[is_leap_year(year)][month] + day-1;
}
EXPORT_SYMBOL(rtc_year_days);
@@ -66,7 +65,7 @@ void rtc_time_to_tm(unsigned long time, struct rtc_time *tm)
- LEAPS_THRU_END_OF(1970 - 1);
if (days < 0) {
year -= 1;
- days += 365 + LEAP_YEAR(year);
+ days += 365 + is_leap_year(year);
}
tm->tm_year = year - 1900;
tm->tm_yday = days + 1;
diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c
index 893f7dece23..60fe266f0f4 100644
--- a/drivers/rtc/rtc-m41t80.c
+++ b/drivers/rtc/rtc-m41t80.c
@@ -64,10 +64,12 @@
#define M41T80_FEATURE_BL (1 << 1) /* Battery low indicator */
#define M41T80_FEATURE_SQ (1 << 2) /* Squarewave feature */
#define M41T80_FEATURE_WD (1 << 3) /* Extra watchdog resolution */
+#define M41T80_FEATURE_SQ_ALT (1 << 4) /* RSx bits are in reg 4 */
#define DRV_VERSION "0.05"
static const struct i2c_device_id m41t80_id[] = {
+ { "m41t62", M41T80_FEATURE_SQ | M41T80_FEATURE_SQ_ALT },
{ "m41t65", M41T80_FEATURE_HT | M41T80_FEATURE_WD },
{ "m41t80", M41T80_FEATURE_SQ },
{ "m41t81", M41T80_FEATURE_HT | M41T80_FEATURE_SQ},
@@ -393,12 +395,15 @@ static ssize_t m41t80_sysfs_show_sqwfreq(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
- int val;
+ int val, reg_sqw;
if (!(clientdata->features & M41T80_FEATURE_SQ))
return -EINVAL;
- val = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
+ reg_sqw = M41T80_REG_SQW;
+ if (clientdata->features & M41T80_FEATURE_SQ_ALT)
+ reg_sqw = M41T80_REG_WDAY;
+ val = i2c_smbus_read_byte_data(client, reg_sqw);
if (val < 0)
return -EIO;
val = (val >> 4) & 0xf;
@@ -419,7 +424,7 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
{
struct i2c_client *client = to_i2c_client(dev);
struct m41t80_data *clientdata = i2c_get_clientdata(client);
- int almon, sqw;
+ int almon, sqw, reg_sqw;
int val = simple_strtoul(buf, NULL, 0);
if (!(clientdata->features & M41T80_FEATURE_SQ))
@@ -440,13 +445,16 @@ static ssize_t m41t80_sysfs_set_sqwfreq(struct device *dev,
almon = i2c_smbus_read_byte_data(client, M41T80_REG_ALARM_MON);
if (almon < 0)
return -EIO;
- sqw = i2c_smbus_read_byte_data(client, M41T80_REG_SQW);
+ reg_sqw = M41T80_REG_SQW;
+ if (clientdata->features & M41T80_FEATURE_SQ_ALT)
+ reg_sqw = M41T80_REG_WDAY;
+ sqw = i2c_smbus_read_byte_data(client, reg_sqw);
if (sqw < 0)
return -EIO;
sqw = (sqw & 0x0f) | (val << 4);
if (i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
almon & ~M41T80_ALMON_SQWE) < 0 ||
- i2c_smbus_write_byte_data(client, M41T80_REG_SQW, sqw) < 0)
+ i2c_smbus_write_byte_data(client, reg_sqw, sqw) < 0)
return -EIO;
if (val && i2c_smbus_write_byte_data(client, M41T80_REG_ALARM_MON,
almon | M41T80_ALMON_SQWE) < 0)
diff --git a/drivers/rtc/rtc-parisc.c b/drivers/rtc/rtc-parisc.c
deleted file mode 100644
index c6bfa6fe1a2..00000000000
--- a/drivers/rtc/rtc-parisc.c
+++ /dev/null
@@ -1,112 +0,0 @@
-/* rtc-parisc: RTC for HP PA-RISC firmware
- *
- * Copyright (C) 2008 Kyle McMartin <kyle@mcmartin.ca>
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/time.h>
-#include <linux/platform_device.h>
-
-#include <asm/rtc.h>
-
-/* as simple as can be, and no simpler. */
-struct parisc_rtc {
- struct rtc_device *rtc;
- spinlock_t lock;
-};
-
-static int parisc_get_time(struct device *dev, struct rtc_time *tm)
-{
- struct parisc_rtc *p = dev_get_drvdata(dev);
- unsigned long flags, ret;
-
- spin_lock_irqsave(&p->lock, flags);
- ret = get_rtc_time(tm);
- spin_unlock_irqrestore(&p->lock, flags);
-
- if (ret & RTC_BATT_BAD)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static int parisc_set_time(struct device *dev, struct rtc_time *tm)
-{
- struct parisc_rtc *p = dev_get_drvdata(dev);
- unsigned long flags;
- int ret;
-
- spin_lock_irqsave(&p->lock, flags);
- ret = set_rtc_time(tm);
- spin_unlock_irqrestore(&p->lock, flags);
-
- if (ret < 0)
- return -EOPNOTSUPP;
-
- return 0;
-}
-
-static const struct rtc_class_ops parisc_rtc_ops = {
- .read_time = parisc_get_time,
- .set_time = parisc_set_time,
-};
-
-static int __devinit parisc_rtc_probe(struct platform_device *dev)
-{
- struct parisc_rtc *p;
-
- p = kzalloc(sizeof (*p), GFP_KERNEL);
- if (!p)
- return -ENOMEM;
-
- spin_lock_init(&p->lock);
-
- p->rtc = rtc_device_register("rtc-parisc", &dev->dev, &parisc_rtc_ops,
- THIS_MODULE);
- if (IS_ERR(p->rtc)) {
- int err = PTR_ERR(p->rtc);
- kfree(p);
- return err;
- }
-
- platform_set_drvdata(dev, p);
-
- return 0;
-}
-
-static int __devexit parisc_rtc_remove(struct platform_device *dev)
-{
- struct parisc_rtc *p = platform_get_drvdata(dev);
-
- rtc_device_unregister(p->rtc);
- kfree(p);
-
- return 0;
-}
-
-static struct platform_driver parisc_rtc_driver = {
- .driver = {
- .name = "rtc-parisc",
- .owner = THIS_MODULE,
- },
- .probe = parisc_rtc_probe,
- .remove = __devexit_p(parisc_rtc_remove),
-};
-
-static int __init parisc_rtc_init(void)
-{
- return platform_driver_register(&parisc_rtc_driver);
-}
-
-static void __exit parisc_rtc_fini(void)
-{
- platform_driver_unregister(&parisc_rtc_driver);
-}
-
-module_init(parisc_rtc_init);
-module_exit(parisc_rtc_fini);
-
-MODULE_AUTHOR("Kyle McMartin <kyle@mcmartin.ca>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("HP PA-RISC RTC driver");
diff --git a/drivers/rtc/rtc-ppc.c b/drivers/rtc/rtc-ppc.c
deleted file mode 100644
index c8e97e25ef7..00000000000
--- a/drivers/rtc/rtc-ppc.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * RTC driver for ppc_md RTC functions
- *
- * © 2007 Red Hat, Inc.
- *
- * Author: David Woodhouse <dwmw2@infradead.org>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/rtc.h>
-#include <linux/platform_device.h>
-#include <asm/machdep.h>
-
-static int ppc_rtc_read_time(struct device *dev, struct rtc_time *tm)
-{
- ppc_md.get_rtc_time(tm);
- return 0;
-}
-
-static int ppc_rtc_set_time(struct device *dev, struct rtc_time *tm)
-{
- return ppc_md.set_rtc_time(tm);
-}
-
-static const struct rtc_class_ops ppc_rtc_ops = {
- .set_time = ppc_rtc_set_time,
- .read_time = ppc_rtc_read_time,
-};
-
-static struct rtc_device *rtc;
-static struct platform_device *ppc_rtc_pdev;
-
-static int __init ppc_rtc_init(void)
-{
- if (!ppc_md.get_rtc_time || !ppc_md.set_rtc_time)
- return -ENODEV;
-
- ppc_rtc_pdev = platform_device_register_simple("ppc-rtc", 0, NULL, 0);
- if (IS_ERR(ppc_rtc_pdev))
- return PTR_ERR(ppc_rtc_pdev);
-
- rtc = rtc_device_register("ppc_md", &ppc_rtc_pdev->dev,
- &ppc_rtc_ops, THIS_MODULE);
- if (IS_ERR(rtc)) {
- platform_device_unregister(ppc_rtc_pdev);
- return PTR_ERR(rtc);
- }
-
- return 0;
-}
-
-static void __exit ppc_rtc_exit(void)
-{
- rtc_device_unregister(rtc);
- platform_device_unregister(ppc_rtc_pdev);
-}
-
-module_init(ppc_rtc_init);
-module_exit(ppc_rtc_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>");
-MODULE_DESCRIPTION("Generic RTC class driver for PowerPC");
diff --git a/drivers/rtc/rtc-proc.c b/drivers/rtc/rtc-proc.c
index 0c6257a034f..c086fc30a84 100644
--- a/drivers/rtc/rtc-proc.c
+++ b/drivers/rtc/rtc-proc.c
@@ -105,14 +105,8 @@ static const struct file_operations rtc_proc_fops = {
void rtc_proc_add_device(struct rtc_device *rtc)
{
- if (rtc->id == 0) {
- struct proc_dir_entry *ent;
-
- ent = proc_create_data("driver/rtc", 0, NULL,
- &rtc_proc_fops, rtc);
- if (ent)
- ent->owner = rtc->owner;
- }
+ if (rtc->id == 0)
+ proc_create_data("driver/rtc", 0, NULL, &rtc_proc_fops, rtc);
}
void rtc_proc_del_device(struct rtc_device *rtc)
diff --git a/drivers/rtc/rtc-ps3.c b/drivers/rtc/rtc-ps3.c
new file mode 100644
index 00000000000..968133ce1ee
--- /dev/null
+++ b/drivers/rtc/rtc-ps3.c
@@ -0,0 +1,104 @@
+/*
+ * PS3 RTC Driver
+ *
+ * Copyright 2009 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ * If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+
+#include <asm/lv1call.h>
+#include <asm/ps3.h>
+
+
+static u64 read_rtc(void)
+{
+ int result;
+ u64 rtc_val;
+ u64 tb_val;
+
+ result = lv1_get_rtc(&rtc_val, &tb_val);
+ BUG_ON(result);
+
+ return rtc_val;
+}
+
+static int ps3_get_time(struct device *dev, struct rtc_time *tm)
+{
+ rtc_time_to_tm(read_rtc() + ps3_os_area_get_rtc_diff(), tm);
+ return rtc_valid_tm(tm);
+}
+
+static int ps3_set_time(struct device *dev, struct rtc_time *tm)
+{
+ unsigned long now;
+
+ rtc_tm_to_time(tm, &now);
+ ps3_os_area_set_rtc_diff(now - read_rtc());
+ return 0;
+}
+
+static const struct rtc_class_ops ps3_rtc_ops = {
+ .read_time = ps3_get_time,
+ .set_time = ps3_set_time,
+};
+
+static int __init ps3_rtc_probe(struct platform_device *dev)
+{
+ struct rtc_device *rtc;
+
+ rtc = rtc_device_register("rtc-ps3", &dev->dev, &ps3_rtc_ops,
+ THIS_MODULE);
+ if (IS_ERR(rtc))
+ return PTR_ERR(rtc);
+
+ platform_set_drvdata(dev, rtc);
+ return 0;
+}
+
+static int __exit ps3_rtc_remove(struct platform_device *dev)
+{
+ rtc_device_unregister(platform_get_drvdata(dev));
+ return 0;
+}
+
+static struct platform_driver ps3_rtc_driver = {
+ .driver = {
+ .name = "rtc-ps3",
+ .owner = THIS_MODULE,
+ },
+ .remove = __exit_p(ps3_rtc_remove),
+};
+
+static int __init ps3_rtc_init(void)
+{
+ return platform_driver_probe(&ps3_rtc_driver, ps3_rtc_probe);
+}
+
+static void __exit ps3_rtc_fini(void)
+{
+ platform_driver_unregister(&ps3_rtc_driver);
+}
+
+module_init(ps3_rtc_init);
+module_exit(ps3_rtc_fini);
+
+MODULE_AUTHOR("Sony Corporation");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("ps3 RTC driver");
+MODULE_ALIAS("platform:rtc-ps3");
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index 4898f7fe851..9b1ff12bf94 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -795,10 +795,46 @@ static int __devexit sh_rtc_remove(struct platform_device *pdev)
return 0;
}
+
+static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct sh_rtc *rtc = platform_get_drvdata(pdev);
+
+ set_irq_wake(rtc->periodic_irq, enabled);
+ if (rtc->carry_irq > 0) {
+ set_irq_wake(rtc->carry_irq, enabled);
+ set_irq_wake(rtc->alarm_irq, enabled);
+ }
+
+}
+
+static int sh_rtc_suspend(struct device *dev)
+{
+ if (device_may_wakeup(dev))
+ sh_rtc_set_irq_wake(dev, 1);
+
+ return 0;
+}
+
+static int sh_rtc_resume(struct device *dev)
+{
+ if (device_may_wakeup(dev))
+ sh_rtc_set_irq_wake(dev, 0);
+
+ return 0;
+}
+
+static struct dev_pm_ops sh_rtc_dev_pm_ops = {
+ .suspend = sh_rtc_suspend,
+ .resume = sh_rtc_resume,
+};
+
static struct platform_driver sh_rtc_platform_driver = {
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
+ .pm = &sh_rtc_dev_pm_ops,
},
.probe = sh_rtc_probe,
.remove = __devexit_p(sh_rtc_remove),
diff --git a/drivers/rtc/rtc-v3020.c b/drivers/rtc/rtc-v3020.c
index 14d4f036a76..ad164056feb 100644
--- a/drivers/rtc/rtc-v3020.c
+++ b/drivers/rtc/rtc-v3020.c
@@ -27,17 +27,162 @@
#include <linux/bcd.h>
#include <linux/rtc-v3020.h>
#include <linux/delay.h>
+#include <linux/gpio.h>
-#include <asm/io.h>
+#include <linux/io.h>
#undef DEBUG
+struct v3020;
+
+struct v3020_chip_ops {
+ int (*map_io)(struct v3020 *chip, struct platform_device *pdev,
+ struct v3020_platform_data *pdata);
+ void (*unmap_io)(struct v3020 *chip);
+ unsigned char (*read_bit)(struct v3020 *chip);
+ void (*write_bit)(struct v3020 *chip, unsigned char bit);
+};
+
+#define V3020_CS 0
+#define V3020_WR 1
+#define V3020_RD 2
+#define V3020_IO 3
+
+struct v3020_gpio {
+ const char *name;
+ unsigned int gpio;
+};
+
struct v3020 {
+ /* MMIO access */
void __iomem *ioaddress;
int leftshift;
+
+ /* GPIO access */
+ struct v3020_gpio *gpio;
+
+ struct v3020_chip_ops *ops;
+
struct rtc_device *rtc;
};
+
+static int v3020_mmio_map(struct v3020 *chip, struct platform_device *pdev,
+ struct v3020_platform_data *pdata)
+{
+ if (pdev->num_resources != 1)
+ return -EBUSY;
+
+ if (pdev->resource[0].flags != IORESOURCE_MEM)
+ return -EBUSY;
+
+ chip->leftshift = pdata->leftshift;
+ chip->ioaddress = ioremap(pdev->resource[0].start, 1);
+ if (chip->ioaddress == NULL)
+ return -EBUSY;
+
+ return 0;
+}
+
+static void v3020_mmio_unmap(struct v3020 *chip)
+{
+ iounmap(chip->ioaddress);
+}
+
+static void v3020_mmio_write_bit(struct v3020 *chip, unsigned char bit)
+{
+ writel(bit << chip->leftshift, chip->ioaddress);
+}
+
+static unsigned char v3020_mmio_read_bit(struct v3020 *chip)
+{
+ return readl(chip->ioaddress) & (1 << chip->leftshift);
+}
+
+static struct v3020_chip_ops v3020_mmio_ops = {
+ .map_io = v3020_mmio_map,
+ .unmap_io = v3020_mmio_unmap,
+ .read_bit = v3020_mmio_read_bit,
+ .write_bit = v3020_mmio_write_bit,
+};
+
+static struct v3020_gpio v3020_gpio[] = {
+ { "RTC CS", 0 },
+ { "RTC WR", 0 },
+ { "RTC RD", 0 },
+ { "RTC IO", 0 },
+};
+
+static int v3020_gpio_map(struct v3020 *chip, struct platform_device *pdev,
+ struct v3020_platform_data *pdata)
+{
+ int i, err;
+
+ v3020_gpio[V3020_CS].gpio = pdata->gpio_cs;
+ v3020_gpio[V3020_WR].gpio = pdata->gpio_wr;
+ v3020_gpio[V3020_RD].gpio = pdata->gpio_rd;
+ v3020_gpio[V3020_IO].gpio = pdata->gpio_io;
+
+ for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++) {
+ err = gpio_request(v3020_gpio[i].gpio, v3020_gpio[i].name);
+ if (err)
+ goto err_request;
+
+ gpio_direction_output(v3020_gpio[i].gpio, 1);
+ }
+
+ chip->gpio = v3020_gpio;
+
+ return 0;
+
+err_request:
+ while (--i >= 0)
+ gpio_free(v3020_gpio[i].gpio);
+
+ return err;
+}
+
+static void v3020_gpio_unmap(struct v3020 *chip)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(v3020_gpio); i++)
+ gpio_free(v3020_gpio[i].gpio);
+}
+
+static void v3020_gpio_write_bit(struct v3020 *chip, unsigned char bit)
+{
+ gpio_direction_output(chip->gpio[V3020_IO].gpio, bit);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
+ gpio_set_value(chip->gpio[V3020_WR].gpio, 0);
+ udelay(1);
+ gpio_set_value(chip->gpio[V3020_WR].gpio, 1);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
+}
+
+static unsigned char v3020_gpio_read_bit(struct v3020 *chip)
+{
+ int bit;
+
+ gpio_direction_input(chip->gpio[V3020_IO].gpio);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 0);
+ gpio_set_value(chip->gpio[V3020_RD].gpio, 0);
+ udelay(1);
+ bit = !!gpio_get_value(chip->gpio[V3020_IO].gpio);
+ udelay(1);
+ gpio_set_value(chip->gpio[V3020_RD].gpio, 1);
+ gpio_set_value(chip->gpio[V3020_CS].gpio, 1);
+
+ return bit;
+}
+
+static struct v3020_chip_ops v3020_gpio_ops = {
+ .map_io = v3020_gpio_map,
+ .unmap_io = v3020_gpio_unmap,
+ .read_bit = v3020_gpio_read_bit,
+ .write_bit = v3020_gpio_write_bit,
+};
+
static void v3020_set_reg(struct v3020 *chip, unsigned char address,
unsigned char data)
{
@@ -46,7 +191,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
tmp = address;
for (i = 0; i < 4; i++) {
- writel((tmp & 1) << chip->leftshift, chip->ioaddress);
+ chip->ops->write_bit(chip, (tmp & 1));
tmp >>= 1;
udelay(1);
}
@@ -54,7 +199,7 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
/* Commands dont have data */
if (!V3020_IS_COMMAND(address)) {
for (i = 0; i < 8; i++) {
- writel((data & 1) << chip->leftshift, chip->ioaddress);
+ chip->ops->write_bit(chip, (data & 1));
data >>= 1;
udelay(1);
}
@@ -63,18 +208,18 @@ static void v3020_set_reg(struct v3020 *chip, unsigned char address,
static unsigned char v3020_get_reg(struct v3020 *chip, unsigned char address)
{
- unsigned int data=0;
+ unsigned int data = 0;
int i;
for (i = 0; i < 4; i++) {
- writel((address & 1) << chip->leftshift, chip->ioaddress);
+ chip->ops->write_bit(chip, (address & 1));
address >>= 1;
udelay(1);
}
for (i = 0; i < 8; i++) {
data >>= 1;
- if (readl(chip->ioaddress) & (1 << chip->leftshift))
+ if (chip->ops->read_bit(chip))
data |= 0x80;
udelay(1);
}
@@ -106,16 +251,14 @@ static int v3020_read_time(struct device *dev, struct rtc_time *dt)
tmp = v3020_get_reg(chip, V3020_YEAR);
dt->tm_year = bcd2bin(tmp)+100;
-#ifdef DEBUG
- printk("\n%s : Read RTC values\n",__func__);
- printk("tm_hour: %i\n",dt->tm_hour);
- printk("tm_min : %i\n",dt->tm_min);
- printk("tm_sec : %i\n",dt->tm_sec);
- printk("tm_year: %i\n",dt->tm_year);
- printk("tm_mon : %i\n",dt->tm_mon);
- printk("tm_mday: %i\n",dt->tm_mday);
- printk("tm_wday: %i\n",dt->tm_wday);
-#endif
+ dev_dbg(dev, "\n%s : Read RTC values\n", __func__);
+ dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+ dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+ dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+ dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
+ dev_dbg(dev, "tm_mon : %i\n", dt->tm_mon);
+ dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+ dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
return 0;
}
@@ -125,15 +268,13 @@ static int v3020_set_time(struct device *dev, struct rtc_time *dt)
{
struct v3020 *chip = dev_get_drvdata(dev);
-#ifdef DEBUG
- printk("\n%s : Setting RTC values\n",__func__);
- printk("tm_sec : %i\n",dt->tm_sec);
- printk("tm_min : %i\n",dt->tm_min);
- printk("tm_hour: %i\n",dt->tm_hour);
- printk("tm_mday: %i\n",dt->tm_mday);
- printk("tm_wday: %i\n",dt->tm_wday);
- printk("tm_year: %i\n",dt->tm_year);
-#endif
+ dev_dbg(dev, "\n%s : Setting RTC values\n", __func__);
+ dev_dbg(dev, "tm_sec : %i\n", dt->tm_sec);
+ dev_dbg(dev, "tm_min : %i\n", dt->tm_min);
+ dev_dbg(dev, "tm_hour: %i\n", dt->tm_hour);
+ dev_dbg(dev, "tm_mday: %i\n", dt->tm_mday);
+ dev_dbg(dev, "tm_wday: %i\n", dt->tm_wday);
+ dev_dbg(dev, "tm_year: %i\n", dt->tm_year);
/* Write all the values to ram... */
v3020_set_reg(chip, V3020_SECONDS, bin2bcd(dt->tm_sec));
@@ -168,30 +309,28 @@ static int rtc_probe(struct platform_device *pdev)
int i;
int temp;
- if (pdev->num_resources != 1)
- return -EBUSY;
-
- if (pdev->resource[0].flags != IORESOURCE_MEM)
- return -EBUSY;
-
chip = kzalloc(sizeof *chip, GFP_KERNEL);
if (!chip)
return -ENOMEM;
- chip->leftshift = pdata->leftshift;
- chip->ioaddress = ioremap(pdev->resource[0].start, 1);
- if (chip->ioaddress == NULL)
+ if (pdata->use_gpio)
+ chip->ops = &v3020_gpio_ops;
+ else
+ chip->ops = &v3020_mmio_ops;
+
+ retval = chip->ops->map_io(chip, pdev, pdata);
+ if (retval)
goto err_chip;
/* Make sure the v3020 expects a communication cycle
* by reading 8 times */
for (i = 0; i < 8; i++)
- temp = readl(chip->ioaddress);
+ temp = chip->ops->read_bit(chip);
/* Test chip by doing a write/read sequence
* to the chip ram */
v3020_set_reg(chip, V3020_SECONDS, 0x33);
- if(v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
+ if (v3020_get_reg(chip, V3020_SECONDS) != 0x33) {
retval = -ENODEV;
goto err_io;
}
@@ -200,10 +339,17 @@ static int rtc_probe(struct platform_device *pdev)
* are all disabled */
v3020_set_reg(chip, V3020_STATUS_0, 0x0);
- dev_info(&pdev->dev, "Chip available at physical address 0x%llx,"
- "data connected to D%d\n",
- (unsigned long long)pdev->resource[0].start,
- chip->leftshift);
+ if (pdata->use_gpio)
+ dev_info(&pdev->dev, "Chip available at GPIOs "
+ "%d, %d, %d, %d\n",
+ chip->gpio[V3020_CS].gpio, chip->gpio[V3020_WR].gpio,
+ chip->gpio[V3020_RD].gpio, chip->gpio[V3020_IO].gpio);
+ else
+ dev_info(&pdev->dev, "Chip available at "
+ "physical address 0x%llx,"
+ "data connected to D%d\n",
+ (unsigned long long)pdev->resource[0].start,
+ chip->leftshift);
platform_set_drvdata(pdev, chip);
@@ -218,7 +364,7 @@ static int rtc_probe(struct platform_device *pdev)
return 0;
err_io:
- iounmap(chip->ioaddress);
+ chip->ops->unmap_io(chip);
err_chip:
kfree(chip);
@@ -233,7 +379,7 @@ static int rtc_remove(struct platform_device *dev)
if (rtc)
rtc_device_unregister(rtc);
- iounmap(chip->ioaddress);
+ chip->ops->unmap_io(chip);
kfree(chip);
return 0;
diff --git a/drivers/rtc/rtc-wm8350.c b/drivers/rtc/rtc-wm8350.c
index 5c5e3aa9138..c91edc572eb 100644
--- a/drivers/rtc/rtc-wm8350.c
+++ b/drivers/rtc/rtc-wm8350.c
@@ -122,7 +122,7 @@ static int wm8350_rtc_settime(struct device *dev, struct rtc_time *tm)
do {
rtc_ctrl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL);
schedule_timeout_uninterruptible(msecs_to_jiffies(1));
- } while (retries-- && !(rtc_ctrl & WM8350_RTC_STS));
+ } while (--retries && !(rtc_ctrl & WM8350_RTC_STS));
if (!retries) {
dev_err(dev, "timed out on set confirmation\n");
@@ -236,6 +236,17 @@ static int wm8350_rtc_start_alarm(struct wm8350 *wm8350)
return 0;
}
+static int wm8350_rtc_alarm_irq_enable(struct device *dev,
+ unsigned int enabled)
+{
+ struct wm8350 *wm8350 = dev_get_drvdata(dev);
+
+ if (enabled)
+ return wm8350_rtc_start_alarm(wm8350);
+ else
+ return wm8350_rtc_stop_alarm(wm8350);
+}
+
static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
@@ -291,30 +302,15 @@ static int wm8350_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
return ret;
}
-/*
- * Handle commands from user-space
- */
-static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd,
- unsigned long arg)
+static int wm8350_rtc_update_irq_enable(struct device *dev,
+ unsigned int enabled)
{
struct wm8350 *wm8350 = dev_get_drvdata(dev);
- switch (cmd) {
- case RTC_AIE_OFF:
- return wm8350_rtc_stop_alarm(wm8350);
- case RTC_AIE_ON:
- return wm8350_rtc_start_alarm(wm8350);
-
- case RTC_UIE_OFF:
- wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
- break;
- case RTC_UIE_ON:
+ if (enabled)
wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC);
- break;
-
- default:
- return -ENOIOCTLCMD;
- }
+ else
+ wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
return 0;
}
@@ -345,11 +341,12 @@ static void wm8350_rtc_update_handler(struct wm8350 *wm8350, int irq,
}
static const struct rtc_class_ops wm8350_rtc_ops = {
- .ioctl = wm8350_rtc_ioctl,
.read_time = wm8350_rtc_readtime,
.set_time = wm8350_rtc_settime,
.read_alarm = wm8350_rtc_readalarm,
.set_alarm = wm8350_rtc_setalarm,
+ .alarm_irq_enable = wm8350_rtc_alarm_irq_enable,
+ .update_irq_enable = wm8350_rtc_update_irq_enable,
};
#ifdef CONFIG_PM
@@ -440,7 +437,7 @@ static int wm8350_rtc_probe(struct platform_device *pdev)
do {
timectl = wm8350_reg_read(wm8350,
WM8350_RTC_TIME_CONTROL);
- } while (timectl & WM8350_RTC_STS && retries--);
+ } while (timectl & WM8350_RTC_STS && --retries);
if (retries == 0) {
dev_err(&pdev->dev, "failed to start: timeout\n");
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 2fd64e5a9ab..0570794ccf1 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -2363,6 +2363,7 @@ int dasd_generic_notify(struct ccw_device *cdev, int event)
ret = 0;
switch (event) {
case CIO_GONE:
+ case CIO_BOXED:
case CIO_NO_PATH:
/* First of all call extended error reporting. */
dasd_eer_write(device, NULL, DASD_EER_NOPATH);
diff --git a/drivers/s390/block/dasd_proc.c b/drivers/s390/block/dasd_proc.c
index 2080ba6a69b..654daa3cdfd 100644
--- a/drivers/s390/block/dasd_proc.c
+++ b/drivers/s390/block/dasd_proc.c
@@ -320,7 +320,6 @@ dasd_proc_init(void)
dasd_proc_root_entry = proc_mkdir("dasd", NULL);
if (!dasd_proc_root_entry)
goto out_nodasd;
- dasd_proc_root_entry->owner = THIS_MODULE;
dasd_devices_entry = proc_create("devices",
S_IFREG | S_IRUGO | S_IWUSR,
dasd_proc_root_entry,
@@ -334,7 +333,6 @@ dasd_proc_init(void)
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:
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index c4d2f667a2f..35441fa16be 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -310,8 +310,6 @@ static void ccw_device_remove_orphan_cb(struct work_struct *work)
put_device(&cdev->dev);
}
-static void ccw_device_call_sch_unregister(struct work_struct *work);
-
static void
ccw_device_remove_disconnected(struct ccw_device *cdev)
{
@@ -335,11 +333,10 @@ ccw_device_remove_disconnected(struct ccw_device *cdev)
spin_unlock_irqrestore(cdev->ccwlock, flags);
PREPARE_WORK(&cdev->private->kick_work,
ccw_device_remove_orphan_cb);
+ queue_work(slow_path_wq, &cdev->private->kick_work);
} else
/* Deregister subchannel, which will kill the ccw device. */
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister);
- queue_work(slow_path_wq, &cdev->private->kick_work);
+ ccw_device_schedule_sch_unregister(cdev);
}
/**
@@ -471,7 +468,7 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
int ret;
/* Do device recognition, if needed. */
- if (cdev->id.cu_type == 0) {
+ if (cdev->private->state == DEV_STATE_BOXED) {
ret = ccw_device_recognition(cdev);
if (ret) {
CIO_MSG_EVENT(0, "Couldn't start recognition "
@@ -482,17 +479,21 @@ static int online_store_recog_and_online(struct ccw_device *cdev)
}
wait_event(cdev->private->wait_q,
cdev->private->flags.recog_done);
+ if (cdev->private->state != DEV_STATE_OFFLINE)
+ /* recognition failed */
+ return -EAGAIN;
}
if (cdev->drv && cdev->drv->set_online)
ccw_device_set_online(cdev);
return 0;
}
+
static int online_store_handle_online(struct ccw_device *cdev, int force)
{
int ret;
ret = online_store_recog_and_online(cdev);
- if (ret)
+ if (ret && !force)
return ret;
if (force && cdev->private->state == DEV_STATE_BOXED) {
ret = ccw_device_stlck(cdev);
@@ -500,7 +501,9 @@ static int online_store_handle_online(struct ccw_device *cdev, int force)
return ret;
if (cdev->id.cu_type == 0)
cdev->private->state = DEV_STATE_NOT_OPER;
- online_store_recog_and_online(cdev);
+ ret = online_store_recog_and_online(cdev);
+ if (ret)
+ return ret;
}
return 0;
}
@@ -512,7 +515,11 @@ static ssize_t online_store (struct device *dev, struct device_attribute *attr,
int force, ret;
unsigned long i;
- if (atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
+ if ((cdev->private->state != DEV_STATE_OFFLINE &&
+ cdev->private->state != DEV_STATE_ONLINE &&
+ cdev->private->state != DEV_STATE_BOXED &&
+ cdev->private->state != DEV_STATE_DISCONNECTED) ||
+ atomic_cmpxchg(&cdev->private->onoff, 0, 1) != 0)
return -EAGAIN;
if (cdev->drv && !try_module_get(cdev->drv->owner)) {
@@ -1014,6 +1021,13 @@ static void ccw_device_call_sch_unregister(struct work_struct *work)
put_device(&sch->dev);
}
+void ccw_device_schedule_sch_unregister(struct ccw_device *cdev)
+{
+ PREPARE_WORK(&cdev->private->kick_work,
+ ccw_device_call_sch_unregister);
+ queue_work(slow_path_wq, &cdev->private->kick_work);
+}
+
/*
* subchannel recognition done. Called from the state machine.
*/
@@ -1025,19 +1039,17 @@ io_subchannel_recog_done(struct ccw_device *cdev)
return;
}
switch (cdev->private->state) {
+ case DEV_STATE_BOXED:
+ /* Device did not respond in time. */
case DEV_STATE_NOT_OPER:
cdev->private->flags.recog_done = 1;
/* Remove device found not operational. */
if (!get_device(&cdev->dev))
break;
- PREPARE_WORK(&cdev->private->kick_work,
- ccw_device_call_sch_unregister);
- queue_work(slow_path_wq, &cdev->private->kick_work);
+ ccw_device_schedule_sch_unregister(cdev);
if (atomic_dec_and_test(&ccw_device_init_count))
wake_up(&ccw_device_init_wq);
break;
- case DEV_STATE_BOXED:
- /* Device did not respond in time. */
case DEV_STATE_OFFLINE:
/*
* We can't register the device in interrupt context so
@@ -1551,8 +1563,7 @@ static int purge_fn(struct device *dev, void *data)
goto out;
CIO_MSG_EVENT(3, "ccw: purging 0.%x.%04x\n", priv->dev_id.ssid,
priv->dev_id.devno);
- PREPARE_WORK(&cdev->private->kick_work, ccw_device_call_sch_unregister);
- queue_work(slow_path_wq, &cdev->private->kick_work);
+ ccw_device_schedule_sch_unregister(cdev);
out:
/* Abort loop in case of pending signal. */
diff --git a/drivers/s390/cio/device.h b/drivers/s390/cio/device.h
index 85e01846ca6..f1cbbd94ad4 100644
--- a/drivers/s390/cio/device.h
+++ b/drivers/s390/cio/device.h
@@ -87,6 +87,7 @@ int ccw_device_is_orphan(struct ccw_device *);
int ccw_device_recognition(struct ccw_device *);
int ccw_device_online(struct ccw_device *);
int ccw_device_offline(struct ccw_device *);
+void ccw_device_schedule_sch_unregister(struct ccw_device *);
int ccw_purge_blacklisted(void);
/* Function prototypes for device status and basic sense stuff. */
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index 87b4bfca080..e4604926156 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -256,13 +256,12 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
old_lpm = 0;
if (sch->lpm != old_lpm)
__recover_lost_chpids(sch, old_lpm);
- if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
- if (state == DEV_STATE_NOT_OPER) {
- cdev->private->flags.recog_done = 1;
- cdev->private->state = DEV_STATE_DISCONNECTED;
- return;
- }
- /* Boxed devices don't need extra treatment. */
+ if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID &&
+ (state == DEV_STATE_NOT_OPER || state == DEV_STATE_BOXED)) {
+ cdev->private->flags.recog_done = 1;
+ cdev->private->state = DEV_STATE_DISCONNECTED;
+ wake_up(&cdev->private->wait_q);
+ return;
}
notify = 0;
same_dev = 0; /* Keep the compiler quiet... */
@@ -274,7 +273,7 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
sch->schid.ssid, sch->schid.sch_no);
break;
case DEV_STATE_OFFLINE:
- if (cdev->private->state == DEV_STATE_DISCONNECTED_SENSE_ID) {
+ if (cdev->online) {
same_dev = ccw_device_handle_oper(cdev);
notify = 1;
}
@@ -307,12 +306,17 @@ ccw_device_recog_done(struct ccw_device *cdev, int state)
" subchannel 0.%x.%04x\n",
cdev->private->dev_id.devno,
sch->schid.ssid, sch->schid.sch_no);
+ if (cdev->id.cu_type != 0) { /* device was recognized before */
+ cdev->private->flags.recog_done = 1;
+ cdev->private->state = DEV_STATE_BOXED;
+ wake_up(&cdev->private->wait_q);
+ return;
+ }
break;
}
cdev->private->state = state;
io_subchannel_recog_done(cdev);
- if (state != DEV_STATE_NOT_OPER)
- wake_up(&cdev->private->wait_q);
+ wake_up(&cdev->private->wait_q);
}
/*
@@ -390,10 +394,13 @@ ccw_device_done(struct ccw_device *cdev, int state)
cdev->private->state = state;
-
- if (state == DEV_STATE_BOXED)
+ if (state == DEV_STATE_BOXED) {
CIO_MSG_EVENT(0, "Boxed device %04x on subchannel %04x\n",
cdev->private->dev_id.devno, sch->schid.sch_no);
+ if (cdev->online && !ccw_device_notify(cdev, CIO_BOXED))
+ ccw_device_schedule_sch_unregister(cdev);
+ cdev->private->flags.donotify = 0;
+ }
if (cdev->private->flags.donotify) {
cdev->private->flags.donotify = 0;
diff --git a/drivers/s390/net/qeth_core_offl.c b/drivers/s390/net/qeth_core_offl.c
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/drivers/s390/net/qeth_core_offl.c
+++ /dev/null
diff --git a/drivers/s390/net/qeth_core_offl.h b/drivers/s390/net/qeth_core_offl.h
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/drivers/s390/net/qeth_core_offl.h
+++ /dev/null
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c
index 1fe1e2eda51..cfb0dcb6e3f 100644
--- a/drivers/s390/scsi/zfcp_ccw.c
+++ b/drivers/s390/scsi/zfcp_ccw.c
@@ -176,6 +176,11 @@ static int zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
"ccnoti4", NULL);
break;
+ case CIO_BOXED:
+ dev_warn(&adapter->ccw_device->dev,
+ "The ccw device did not respond in time.\n");
+ zfcp_erp_adapter_shutdown(adapter, 0, "ccnoti5", NULL);
+ break;
}
return 1;
}
diff --git a/drivers/s390/scsi/zfcp_fc.c b/drivers/s390/scsi/zfcp_fc.c
index aab8123c596..e8d032b9dfb 100644
--- a/drivers/s390/scsi/zfcp_fc.c
+++ b/drivers/s390/scsi/zfcp_fc.c
@@ -94,7 +94,7 @@ static int zfcp_wka_port_get(struct zfcp_wka_port *wka_port)
static void zfcp_wka_port_offline(struct work_struct *work)
{
- struct delayed_work *dw = container_of(work, struct delayed_work, work);
+ struct delayed_work *dw = to_delayed_work(work);
struct zfcp_wka_port *wka_port =
container_of(dw, struct zfcp_wka_port, work);
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
index e2f44e6c0bc..8ed2990c826 100644
--- a/drivers/scsi/Kconfig
+++ b/drivers/scsi/Kconfig
@@ -121,10 +121,11 @@ config BLK_DEV_SR
tristate "SCSI CDROM support"
depends on SCSI
---help---
- If you want to use a SCSI or FireWire CD-ROM under Linux,
- say Y and read the SCSI-HOWTO and the CDROM-HOWTO at
- <http://www.tldp.org/docs.html#howto>. Also make sure to say
- Y or M to "ISO 9660 CD-ROM file system support" later.
+ If you want to use a CD or DVD drive attached to your computer
+ by SCSI, FireWire, USB or ATAPI, say Y and read the SCSI-HOWTO
+ and the CDROM-HOWTO at <http://www.tldp.org/docs.html#howto>.
+
+ Make sure to say Y or M to "ISO 9660 CD-ROM file system support".
To compile this driver as a module, choose M here and read
<file:Documentation/scsi/scsi.txt>.
@@ -614,10 +615,16 @@ config LIBFC
---help---
Fibre Channel library module
+config LIBFCOE
+ tristate "LibFCoE module"
+ select LIBFC
+ ---help---
+ Library for Fibre Channel over Ethernet module
+
config FCOE
tristate "FCoE module"
depends on PCI
- select LIBFC
+ select LIBFCOE
---help---
Fibre Channel over Ethernet module
@@ -1380,7 +1387,7 @@ config SCSI_LPFC_DEBUG_FS
bool "Emulex LightPulse Fibre Channel debugfs Support"
depends on SCSI_LPFC && DEBUG_FS
help
- This makes debugging infomation from the lpfc driver
+ This makes debugging information from the lpfc driver
available via the debugfs filesystem.
config SCSI_SIM710
@@ -1388,7 +1395,7 @@ config SCSI_SIM710
depends on (EISA || MCA) && SCSI
select SCSI_SPI_ATTRS
---help---
- This driver for NCR53c710 based SCSI host adapters.
+ This driver is for NCR53c710 based SCSI host adapters.
It currently supports Compaq EISA cards and NCR MCA cards
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index cf792963466..e7c861ac417 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -37,6 +37,7 @@ obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o
obj-$(CONFIG_SCSI_DH) += device_handler/
obj-$(CONFIG_LIBFC) += libfc/
+obj-$(CONFIG_LIBFCOE) += fcoe/
obj-$(CONFIG_FCOE) += fcoe/
obj-$(CONFIG_ISCSI_TCP) += libiscsi.o libiscsi_tcp.o iscsi_tcp.o
obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c
index 37dd47136fb..4b38c4750f7 100644
--- a/drivers/scsi/a2091.c
+++ b/drivers/scsi/a2091.c
@@ -23,6 +23,8 @@
#define DMA(ptr) ((a2091_scsiregs *)((ptr)->base))
#define HDATA(ptr) ((struct WD33C93_hostdata *)((ptr)->hostdata))
+static int a2091_release(struct Scsi_Host *instance);
+
static irqreturn_t a2091_intr (int irq, void *_instance)
{
unsigned long flags;
@@ -144,7 +146,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
}
}
-int __init a2091_detect(struct scsi_host_template *tpnt)
+static int __init a2091_detect(struct scsi_host_template *tpnt)
{
static unsigned char called = 0;
struct Scsi_Host *instance;
@@ -233,7 +235,7 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
-int a2091_release(struct Scsi_Host *instance)
+static int a2091_release(struct Scsi_Host *instance)
{
#ifdef MODULE
DMA(instance)->CNTR = 0;
diff --git a/drivers/scsi/a2091.h b/drivers/scsi/a2091.h
index fe809bc88d7..252528f2672 100644
--- a/drivers/scsi/a2091.h
+++ b/drivers/scsi/a2091.h
@@ -11,9 +11,6 @@
#include <linux/types.h>
-int a2091_detect(struct scsi_host_template *);
-int a2091_release(struct Scsi_Host *);
-
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c
index 8b449d8acac..6970ce82c4a 100644
--- a/drivers/scsi/a3000.c
+++ b/drivers/scsi/a3000.c
@@ -25,6 +25,8 @@
static struct Scsi_Host *a3000_host = NULL;
+static int a3000_release(struct Scsi_Host *instance);
+
static irqreturn_t a3000_intr (int irq, void *dummy)
{
unsigned long flags;
@@ -157,7 +159,7 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
}
}
-int __init a3000_detect(struct scsi_host_template *tpnt)
+static int __init a3000_detect(struct scsi_host_template *tpnt)
{
wd33c93_regs regs;
@@ -232,7 +234,7 @@ static struct scsi_host_template driver_template = {
#include "scsi_module.c"
-int a3000_release(struct Scsi_Host *instance)
+static int a3000_release(struct Scsi_Host *instance)
{
wd33c93_release();
DMA(instance)->CNTR = 0;
diff --git a/drivers/scsi/a3000.h b/drivers/scsi/a3000.h
index 44a4ec7b465..c7afe16fd6e 100644
--- a/drivers/scsi/a3000.h
+++ b/drivers/scsi/a3000.h
@@ -11,9 +11,6 @@
#include <linux/types.h>
-int a3000_detect(struct scsi_host_template *);
-int a3000_release(struct Scsi_Host *);
-
#ifndef CMD_PER_LUN
#define CMD_PER_LUN 2
#endif
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c
index 90d1d0878cb..21964aaebca 100644
--- a/drivers/scsi/aacraid/aachba.c
+++ b/drivers/scsi/aacraid/aachba.c
@@ -143,7 +143,7 @@ static char *aac_get_status_string(u32 status);
*/
static int nondasd = -1;
-static int aac_cache;
+static int aac_cache = 2; /* WCE=0 to avoid performance problems */
static int dacmode = -1;
int aac_msi;
int aac_commit = -1;
@@ -157,7 +157,7 @@ module_param_named(cache, aac_cache, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(cache, "Disable Queue Flush commands:\n"
"\tbit 0 - Disable FUA in WRITE SCSI commands\n"
"\tbit 1 - Disable SYNCHRONIZE_CACHE SCSI command\n"
- "\tbit 2 - Disable only if Battery not protecting Cache");
+ "\tbit 2 - Disable only if Battery is protecting Cache");
module_param(dacmode, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(dacmode, "Control whether dma addressing is using 64 bit DAC."
" 0=off, 1=on");
@@ -217,6 +217,14 @@ int aac_reset_devices;
module_param_named(reset_devices, aac_reset_devices, int, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(reset_devices, "Force an adapter reset at initialization.");
+int aac_wwn = 1;
+module_param_named(wwn, aac_wwn, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(wwn, "Select a WWN type for the arrays:\n"
+ "\t0 - Disable\n"
+ "\t1 - Array Meta Data Signature (default)\n"
+ "\t2 - Adapter Serial Number");
+
+
static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
struct fib *fibptr) {
struct scsi_device *device;
@@ -1206,9 +1214,8 @@ static int aac_scsi_32(struct fib * fib, struct scsi_cmnd * cmd)
static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
{
- if ((sizeof(dma_addr_t) > 4) &&
- (num_physpages > (0xFFFFFFFFULL >> PAGE_SHIFT)) &&
- (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
+ if ((sizeof(dma_addr_t) > 4) && fib->dev->needs_dac &&
+ (fib->dev->adapter_info.options & AAC_OPT_SGMAP_HOST64))
return FAILED;
return aac_scsi_32(fib, cmd);
}
@@ -1371,8 +1378,11 @@ int aac_get_adapter_info(struct aac_dev* dev)
if (dev->nondasd_support && !dev->in_reset)
printk(KERN_INFO "%s%d: Non-DASD support enabled.\n",dev->name, dev->id);
+ if (dma_get_required_mask(&dev->pdev->dev) > DMA_32BIT_MASK)
+ dev->needs_dac = 1;
dev->dac_support = 0;
- if( (sizeof(dma_addr_t) > 4) && (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)){
+ if ((sizeof(dma_addr_t) > 4) && dev->needs_dac &&
+ (dev->adapter_info.options & AAC_OPT_SGMAP_HOST64)) {
if (!dev->in_reset)
printk(KERN_INFO "%s%d: 64bit support enabled.\n",
dev->name, dev->id);
@@ -1382,6 +1392,15 @@ int aac_get_adapter_info(struct aac_dev* dev)
if(dacmode != -1) {
dev->dac_support = (dacmode!=0);
}
+
+ /* avoid problems with AAC_QUIRK_SCSI_32 controllers */
+ if (dev->dac_support && (aac_get_driver_ident(dev->cardtype)->quirks
+ & AAC_QUIRK_SCSI_32)) {
+ dev->nondasd_support = 0;
+ dev->jbod = 0;
+ expose_physicals = 0;
+ }
+
if(dev->dac_support != 0) {
if (!pci_set_dma_mask(dev->pdev, DMA_64BIT_MASK) &&
!pci_set_consistent_dma_mask(dev->pdev, DMA_64BIT_MASK)) {
@@ -2058,7 +2077,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", cid));
memset(&inq_data, 0, sizeof (struct inquiry_data));
- if (scsicmd->cmnd[1] & 0x1) {
+ if ((scsicmd->cmnd[1] & 0x1) && aac_wwn) {
char *arr = (char *)&inq_data;
/* EVPD bit set */
@@ -2081,7 +2100,12 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
arr[1] = scsicmd->cmnd[2];
scsi_sg_copy_from_buffer(scsicmd, &inq_data,
sizeof(inq_data));
- return aac_get_container_serial(scsicmd);
+ if (aac_wwn != 2)
+ return aac_get_container_serial(
+ scsicmd);
+ /* SLES 10 SP1 special */
+ scsicmd->result = DID_OK << 16 |
+ COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
} else {
/* vpd page not implemented */
scsicmd->result = DID_OK << 16 |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index 73916adb8f8..cdbdec9f4fb 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -12,7 +12,7 @@
*----------------------------------------------------------------------------*/
#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 2456
+# define AAC_DRIVER_BUILD 2461
# define AAC_DRIVER_BRANCH "-ms"
#endif
#define MAXIMUM_NUM_CONTAINERS 32
@@ -865,7 +865,11 @@ struct aac_supplement_adapter_info
u8 MfgPcbaSerialNo[12];
u8 MfgWWNName[8];
__le32 SupportedOptions2;
- __le32 ReservedGrowth[1];
+ __le32 StructExpansion;
+ /* StructExpansion == 1 */
+ __le32 FeatureBits3;
+ __le32 SupportedPerformanceModes;
+ __le32 ReservedForFutureGrowth[80];
};
#define AAC_FEATURE_FALCON cpu_to_le32(0x00000010)
#define AAC_FEATURE_JBOD cpu_to_le32(0x08000000)
@@ -1020,6 +1024,7 @@ struct aac_dev
u8 jbod;
u8 cache_protected;
u8 dac_support;
+ u8 needs_dac;
u8 raid_scsi_mode;
u8 comm_interface;
# define AAC_COMM_PRODUCER 0
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 16310443b55..d598eba630d 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -54,6 +54,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
const unsigned long printfbufsiz = 256;
struct aac_init *init;
dma_addr_t phys;
+ unsigned long aac_max_hostphysmempages;
size = fibsize + sizeof(struct aac_init) + commsize + commalign + printfbufsiz;
@@ -90,7 +91,18 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->AdapterFibsPhysicalAddress = cpu_to_le32((u32)phys);
init->AdapterFibsSize = cpu_to_le32(fibsize);
init->AdapterFibAlign = cpu_to_le32(sizeof(struct hw_fib));
- init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
+ /*
+ * number of 4k pages of host physical memory. The aacraid fw needs
+ * this number to be less than 4gb worth of pages. New firmware doesn't
+ * have any issues with the mapping system, but older Firmware did, and
+ * had *troubles* dealing with the math overloading past 32 bits, thus
+ * we must limit this field.
+ */
+ aac_max_hostphysmempages = dma_get_required_mask(&dev->pdev->dev) >> 12;
+ if (aac_max_hostphysmempages < AAC_MAX_HOSTPHYSMEMPAGES)
+ init->HostPhysMemPages = cpu_to_le32(aac_max_hostphysmempages);
+ else
+ init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
init->InitFlags = 0;
if (dev->comm_interface == AAC_COMM_MESSAGE) {
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 36d8aab97ef..c507719c0d4 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -86,7 +86,13 @@ char aac_driver_version[] = AAC_DRIVER_FULL_VERSION;
*
* Note: The last field is used to index into aac_drivers below.
*/
-static struct pci_device_id aac_pci_tbl[] = {
+#ifdef DECLARE_PCI_DEVICE_TABLE
+static DECLARE_PCI_DEVICE_TABLE(aac_pci_tbl) = {
+#elif defined(__devinitconst)
+static const struct pci_device_id aac_pci_tbl[] __devinitconst = {
+#else
+static const struct pci_device_id aac_pci_tbl[] __devinitdata = {
+#endif
{ 0x1028, 0x0001, 0x1028, 0x0001, 0, 0, 0 }, /* PERC 2/Si (Iguana/PERC2Si) */
{ 0x1028, 0x0002, 0x1028, 0x0002, 0, 0, 1 }, /* PERC 3/Di (Opal/PERC3Di) */
{ 0x1028, 0x0003, 0x1028, 0x0003, 0, 0, 2 }, /* PERC 3/Si (SlimFast/PERC3Si */
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 7507d8bc57a..b756041f0b2 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -38,6 +38,7 @@
#include <linux/pci.h>
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include <asm/io.h>
#include <asm/system.h>
@@ -4519,8 +4520,8 @@ static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val)
* and is maintained in little-endian order when written to LRAM.
*/
static void
-AscMemWordCopyPtrToLram(PortAddr iop_base,
- ushort s_addr, uchar *s_buffer, int words)
+AscMemWordCopyPtrToLram(PortAddr iop_base, ushort s_addr,
+ const uchar *s_buffer, int words)
{
int i;
@@ -4642,8 +4643,8 @@ static ushort AscInitLram(ASC_DVC_VAR *asc_dvc)
}
static ASC_DCNT
-AscLoadMicroCode(PortAddr iop_base,
- ushort s_addr, uchar *mcode_buf, ushort mcode_size)
+AscLoadMicroCode(PortAddr iop_base, ushort s_addr,
+ const uchar *mcode_buf, ushort mcode_size)
{
ASC_DCNT chksum;
ushort mcode_word_size;
@@ -4668,1618 +4669,6 @@ AscLoadMicroCode(PortAddr iop_base,
return chksum;
}
-/* Microcode buffer is kept after initialization for error recovery. */
-static uchar _asc_mcode_buf[] = {
- 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF,
- 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04,
- 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40,
- 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2,
- 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98,
- 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00,
- 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62,
- 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8,
- 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23,
- 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04,
- 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88,
- 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00,
- 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88,
- 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00,
- 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6,
- 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6,
- 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01,
- 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8,
- 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23,
- 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01,
- 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01,
- 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33,
- 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01,
- 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3,
- 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6,
- 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23,
- 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0,
- 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00,
- 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01,
- 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84,
- 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61,
- 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC,
- 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01,
- 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46,
- 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29,
- 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88,
- 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02,
- 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82,
- 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95,
- 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02,
- 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02,
- 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23,
- 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC,
- 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01,
- 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01,
- 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02,
- 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02,
- 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E,
- 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01,
- 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35,
- 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82,
- 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8,
- 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39,
- 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6,
- 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6,
- 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88,
- 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42,
- 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01,
- 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98,
- 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6,
- 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33,
- 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83,
- 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33,
- 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05,
- 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83,
- 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00,
- 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03,
- 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6,
- 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42,
- 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95,
- 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42,
- 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95,
- 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32,
- 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84,
- 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23,
- 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04,
- 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95,
- 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4,
- 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63,
- 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6,
- 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84,
- 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84,
- 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63,
- 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03,
- 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2,
- 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00,
- 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00,
- 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04,
- 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04,
- 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00,
- 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98,
- 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20,
- 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE,
- 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62,
- 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23,
- 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3,
- 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC,
- 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95,
- 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05,
- 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85,
- 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01,
- 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01,
- 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6,
- 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01,
- 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01,
- 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05,
- 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00,
- 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63,
- 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85,
- 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63,
- 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05,
- 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00,
- 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85,
- 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85,
- 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0,
- 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05,
- 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23,
- 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87,
- 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00,
- 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23,
- 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33,
- 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60,
- 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05,
- 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00,
- 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA,
- 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33,
- 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63,
- 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23,
- 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67,
- 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63,
- 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06,
- 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B,
- 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6,
- 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06,
- 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E,
- 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63,
- 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03,
- 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33,
- 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E,
- 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20,
- 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B,
- 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88,
- 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6,
- 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88,
- 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07,
- 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84,
- 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00,
- 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04,
- 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04,
- 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00,
- 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01,
- 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01,
- 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01,
- 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04,
- 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01,
- 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1,
- 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05,
- 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23,
- 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07,
- 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01,
- 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04,
- 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63,
- 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0,
- 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04,
- 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43,
- 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01,
- 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98,
- 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04,
- 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95,
- 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88,
- 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08,
- 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63,
- 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09,
- 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32,
- 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36,
- 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32,
- 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40,
- 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73,
- 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73,
- 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01,
- 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77,
- 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23,
- 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84,
-};
-
-static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf);
-static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL;
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc3550_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc,
- 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00,
- 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7,
- 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6,
- 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00,
- 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54,
- 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01,
- 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80,
- 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40,
- 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
- 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
- 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54,
- 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00,
- 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
- 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a,
- 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55,
- 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0,
- 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00,
- 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c,
- 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0,
- 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00,
- 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10,
- 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56,
- 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0,
- 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00,
- 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00,
- 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10,
- 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15,
- 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44,
- 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55,
- 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0,
- 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa,
- 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00,
- 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01,
- 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02,
- 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08,
- 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10,
- 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13,
- 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18,
- 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47,
- 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55,
- 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90,
- 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10,
- 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00,
- 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe,
- 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02,
- 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b,
- 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe,
- 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
- 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02,
- 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02,
- 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02,
- 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02,
- 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18,
- 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe,
- 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10,
- 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d,
- 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd,
- 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
- 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0,
- 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe,
- 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f,
- 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe,
- 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d,
- 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a,
- 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40,
- 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41,
- 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03,
- 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe,
- 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b,
- 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0,
- 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0,
- 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f,
- 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04,
- 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40,
- 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2,
- 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11,
- 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4,
- 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe,
- 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe,
- 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1,
- 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c,
- 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3,
- 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28,
- 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02,
- 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f,
- 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
- 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04,
- 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe,
- 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64,
- 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d,
- 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c,
- 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe,
- 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12,
- 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe,
- 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90,
- 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67,
- 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4,
- 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a,
- 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2,
- 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04,
- 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12,
- 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05,
- 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05,
- 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1,
- 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08,
- 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01,
- 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d,
- 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b,
- 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe,
- 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13,
- 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19,
- 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05,
- 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c,
- 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a,
- 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48,
- 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d,
- 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04,
- 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68,
- 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4,
- 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87,
- 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe,
- 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07,
- 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a,
- 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00,
- 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32,
- 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15,
- 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01,
- 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02,
- 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d,
- 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca,
- 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25,
- 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c,
- 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02,
- 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae,
- 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a,
- 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80,
- 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1,
- 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f,
- 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
- 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52,
- 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe,
- 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a,
- 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18,
- 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58,
- 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe,
- 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90,
- 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35,
- 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0,
- 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80,
- 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0,
- 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10,
- 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61,
- 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c,
- 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe,
- 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe,
- 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10,
- 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe,
- 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe,
- 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
- 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d,
- 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33,
- 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a,
- 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01,
- 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02,
- 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe,
- 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc,
- 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91,
- 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77,
- 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf,
- 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e,
- 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05,
- 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56,
- 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39,
- 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53,
- 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59,
- 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00,
- 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe,
- 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08,
- 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a,
- 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d,
- 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12,
- 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9,
- 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe,
- 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51,
- 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10,
- 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a,
- 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00,
- 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33,
- 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca,
- 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe,
- 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe,
- 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93,
- 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10,
- 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00,
- 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0,
- 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9,
- 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48,
- 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe,
- 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd,
- 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f,
- 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42,
- 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c,
- 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54,
- 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01,
- 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01,
- 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d,
- 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e,
- 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01,
- 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe,
- 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01,
- 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02,
- 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe,
- 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe,
- 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe,
- 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35,
- 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f,
- 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00,
- 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa,
- 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b,
- 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea,
- 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01,
- 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e,
- 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47,
- 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38,
- 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d,
- 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a,
- 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe,
- 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce,
- 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e,
- 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12,
- 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe,
- 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe,
- 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02,
- 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05,
- 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4,
- 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe,
- 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01,
- 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01,
- 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11,
- 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12,
- 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24,
- 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03,
- 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc,
- 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23,
- 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04,
- 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
- 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe,
- 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
- 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d,
- 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01,
- 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01,
- 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
- 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe,
- 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
- 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76,
- 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
- 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe,
- 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
- 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48,
- 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08,
- 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe,
- 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c,
- 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0,
- 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
- 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d,
- 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46,
- 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a,
- 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01,
- 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10,
- 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e,
- 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03,
- 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe,
- 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe,
- 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b,
- 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30,
- 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16,
- 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe,
- 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b,
- 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01,
- 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe,
- 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04,
- 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe,
- 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77,
- 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c,
- 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1,
- 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe,
- 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40,
- 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1,
- 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1,
- 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e,
- 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe,
- 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50,
- 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39,
- 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06,
- 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5,
- 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c,
- 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe,
- 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c,
- 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19,
- 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e,
- 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01,
- 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44,
- 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49,
- 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f,
- 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda,
- 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1,
- 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe,
- 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c,
- 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02,
- 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06,
- 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14,
- 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a,
- 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05,
- 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe,
- 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe,
- 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc,
- 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01,
- 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
- 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13,
- 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56,
- 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b,
- 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58,
- 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c,
- 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00,
- 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27,
- 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08,
- 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01,
- 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f,
- 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14,
- 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe,
- 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2,
- 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78,
- 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83,
- 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c,
- 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00,
- 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28,
- 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4,
- 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90,
- 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4,
- 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe,
- 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c,
- 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba,
- 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe,
- 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23,
- 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe,
- 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26,
- 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26,
- 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08,
- 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08,
- 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89,
- 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44,
- 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e,
- 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe,
- 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd,
- 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03,
- 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01,
- 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88,
- 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3,
- 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03,
- 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10,
- 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17,
- 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde,
- 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01,
- 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f,
- 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10,
- 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58,
- 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90,
- 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe,
- 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6,
- 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17,
- 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe,
- 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10,
- 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00,
- 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71,
- 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f,
- 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14,
- 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02,
- 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc,
- 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe,
- 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe,
- 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63,
- 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14,
- 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17,
- 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71,
- 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c,
- 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42,
- 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0,
- 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13,
- 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f,
- 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12,
- 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c,
- 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17,
- 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f,
- 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68,
- 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73,
- 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e,
- 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42,
- 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01,
- 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18,
- 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2,
- 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b,
- 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05,
- 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe,
- 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12,
- 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe,
- 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10,
- 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26,
- 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93,
- 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14,
- 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9,
- 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6,
- 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */
-static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc38C0800_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4,
- 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19,
- 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00,
- 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0,
- 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0,
- 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0,
- 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc,
- 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00,
- 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13,
- 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc,
- 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54,
- 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01,
- 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12,
- 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80,
- 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00,
- 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01,
- 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d,
- 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0,
- 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01,
- 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44,
- 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa,
- 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01,
- 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11,
- 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54,
- 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0,
- 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc,
- 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00,
- 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03,
- 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13,
- 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17,
- 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44,
- 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55,
- 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0,
- 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00,
- 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00,
- 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01,
- 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08,
- 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f,
- 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12,
- 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14,
- 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18,
- 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40,
- 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10,
- 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00,
- 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe,
- 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06,
- 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d,
- 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe,
- 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12,
- 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02,
- 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02,
- 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02,
- 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02,
- 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14,
- 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe,
- 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10,
- 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59,
- 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd,
- 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe,
- 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0,
- 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe,
- 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10,
- 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe,
- 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43,
- 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54,
- 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b,
- 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10,
- 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe,
- 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02,
- 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe,
- 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7,
- 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe,
- 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10,
- 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02,
- 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13,
- 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78,
- 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9,
- 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27,
- 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe,
- 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a,
- 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d,
- 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19,
- 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c,
- 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda,
- 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28,
- 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02,
- 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d,
- 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e,
- 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04,
- 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe,
- 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b,
- 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62,
- 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52,
- 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe,
- 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe,
- 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe,
- 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00,
- 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6,
- 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36,
- 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf,
- 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08,
- 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c,
- 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28,
- 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe,
- 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff,
- 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48,
- 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05,
- 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05,
- 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab,
- 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02,
- 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2,
- 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39,
- 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2,
- 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36,
- 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb,
- 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18,
- 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe,
- 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe,
- 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62,
- 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01,
- 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02,
- 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2,
- 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01,
- 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12,
- 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2,
- 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb,
- 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07,
- 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05,
- 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b,
- 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01,
- 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38,
- 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01,
- 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01,
- 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe,
- 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b,
- 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d,
- 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0,
- 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01,
- 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe,
- 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14,
- 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12,
- 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe,
- 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b,
- 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe,
- 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88,
- 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c,
- 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d,
- 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe,
- 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b,
- 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe,
- 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90,
- 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d,
- 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08,
- 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e,
- 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe,
- 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06,
- 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9,
- 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12,
- 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e,
- 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a,
- 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09,
- 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7,
- 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18,
- 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58,
- 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe,
- 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5,
- 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18,
- 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe,
- 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76,
- 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5,
- 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15,
- 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10,
- 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a,
- 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe,
- 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08,
- 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f,
- 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18,
- 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49,
- 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18,
- 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a,
- 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09,
- 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b,
- 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00,
- 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a,
- 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d,
- 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b,
- 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63,
- 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe,
- 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe,
- 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a,
- 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29,
- 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8,
- 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40,
- 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef,
- 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40,
- 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05,
- 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe,
- 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05,
- 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19,
- 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32,
- 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe,
- 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c,
- 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7,
- 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41,
- 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe,
- 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed,
- 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe,
- 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6,
- 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe,
- 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe,
- 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42,
- 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd,
- 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb,
- 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0,
- 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea,
- 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05,
- 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27,
- 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34,
- 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20,
- 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6,
- 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00,
- 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33,
- 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24,
- 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c,
- 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe,
- 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28,
- 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66,
- 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09,
- 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b,
- 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10,
- 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82,
- 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96,
- 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f,
- 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08,
- 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05,
- 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c,
- 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d,
- 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10,
- 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10,
- 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41,
- 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70,
- 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe,
- 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0,
- 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02,
- 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45,
- 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75,
- 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01,
- 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09,
- 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe,
- 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d,
- 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe,
- 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe,
- 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41,
- 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06,
- 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe,
- 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00,
- 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01,
- 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe,
- 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13,
- 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01,
- 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01,
- 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12,
- 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12,
- 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24,
- 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03,
- 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc,
- 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21,
- 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05,
- 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13,
- 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe,
- 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4,
- 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f,
- 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01,
- 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01,
- 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90,
- 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe,
- 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80,
- 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79,
- 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58,
- 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe,
- 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c,
- 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52,
- 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc,
- 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe,
- 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22,
- 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
- 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe,
- 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b,
- 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f,
- 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f,
- 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe,
- 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe,
- 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe,
- 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14,
- 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d,
- 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe,
- 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7,
- 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07,
- 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17,
- 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17,
- 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24,
- 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d,
- 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d,
- 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe,
- 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c,
- 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03,
- 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21,
- 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01,
- 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe,
- 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f,
- 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40,
- 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe,
- 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a,
- 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61,
- 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44,
- 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe,
- 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50,
- 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d,
- 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23,
- 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a,
- 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d,
- 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19,
- 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34,
- 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a,
- 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf,
- 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8,
- 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53,
- 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06,
- 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee,
- 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35,
- 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17,
- 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01,
- 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33,
- 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1,
- 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a,
- 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1,
- 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15,
- 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13,
- 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0,
- 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01,
- 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
- 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f,
- 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56,
- 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93,
- 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58,
- 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03,
- 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52,
- 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c,
- 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd,
- 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01,
- 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d,
- 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15,
- 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe,
- 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee,
- 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c,
- 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83,
- 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d,
- 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00,
- 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28,
- 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2,
- 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90,
- 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe,
- 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4,
- 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e,
- 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90,
- 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4,
- 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d,
- 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58,
- 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16,
- 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76,
- 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
- 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1,
- 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01,
- 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8,
- 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01,
- 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27,
- 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d,
- 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06,
- 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e,
- 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8,
- 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11,
- 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e,
- 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80,
- 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01,
- 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75,
- 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24,
- 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4,
- 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04,
- 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03,
- 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe,
- 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30,
- 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79,
- 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35,
- 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75,
- 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7,
- 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c,
- 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe,
- 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe,
- 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7,
- 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23,
- 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe,
- 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d,
- 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13,
- 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7,
- 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04,
- 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39,
- 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04,
- 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2,
- 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32,
- 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09,
- 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
- 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11,
- 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16,
- 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14,
- 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c,
- 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18,
- 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73,
- 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b,
- 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77,
- 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46,
- 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04,
- 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09,
- 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe,
- 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10,
- 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00,
- 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b,
- 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe,
- 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e,
- 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08,
- 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00,
- 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19,
- 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09,
- 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19,
- 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07,
- 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59,
- 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe,
- 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0,
- 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0,
- 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */
-static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */
-
-/* Microcode buffer is kept after initialization for error recovery. */
-static unsigned char _adv_asc38C1600_buf[] = {
- 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0,
- 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13,
- 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff,
- 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0,
- 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00,
- 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4,
- 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e,
- 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0,
- 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01,
- 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc,
- 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12,
- 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea,
- 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12,
- 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4,
- 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01,
- 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c,
- 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00,
- 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01,
- 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10,
- 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48,
- 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7,
- 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12,
- 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c,
- 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0,
- 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00,
- 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00,
- 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10,
- 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16,
- 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc,
- 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7,
- 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00,
- 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c,
- 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c,
- 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46,
- 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6,
- 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8,
- 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00,
- 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01,
- 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01,
- 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d,
- 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10,
- 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13,
- 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10,
- 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff,
- 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00,
- 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00,
- 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08,
- 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13,
- 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00,
- 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe,
- 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c,
- 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe,
- 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d,
- 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05,
- 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1,
- 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90,
- 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8,
- 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60,
- 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52,
- 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07,
- 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02,
- 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7,
- 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f,
- 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe,
- 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c,
- 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d,
- 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe,
- 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01,
- 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09,
- 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec,
- 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde,
- 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51,
- 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57,
- 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41,
- 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03,
- 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30,
- 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0,
- 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40,
- 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0,
- 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f,
- 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05,
- 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28,
- 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01,
- 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe,
- 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32,
- 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe,
- 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0,
- 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b,
- 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05,
- 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf,
- 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a,
- 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77,
- 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42,
- 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29,
- 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00,
- 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01,
- 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25,
- 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13,
- 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e,
- 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe,
- 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10,
- 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe,
- 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43,
- 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f,
- 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f,
- 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe,
- 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f,
- 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46,
- 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04,
- 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c,
- 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0,
- 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06,
- 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda,
- 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe,
- 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f,
- 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe,
- 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01,
- 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba,
- 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2,
- 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0,
- 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe,
- 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27,
- 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f,
- 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42,
- 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13,
- 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13,
- 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06,
- 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68,
- 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66,
- 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13,
- 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe,
- 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00,
- 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17,
- 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01,
- 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15,
- 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae,
- 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a,
- 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01,
- 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95,
- 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6,
- 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e,
- 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe,
- 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21,
- 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05,
- 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84,
- 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00,
- 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe,
- 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29,
- 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14,
- 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe,
- 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76,
- 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13,
- 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00,
- 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00,
- 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe,
- 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c,
- 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32,
- 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c,
- 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08,
- 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c,
- 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe,
- 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe,
- 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21,
- 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a,
- 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40,
- 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20,
- 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe,
- 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e,
- 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e,
- 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b,
- 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12,
- 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b,
- 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04,
- 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90,
- 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6,
- 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e,
- 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90,
- 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2,
- 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34,
- 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe,
- 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b,
- 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a,
- 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a,
- 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41,
- 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07,
- 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d,
- 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76,
- 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe,
- 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe,
- 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe,
- 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b,
- 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0,
- 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07,
- 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5,
- 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe,
- 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74,
- 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78,
- 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05,
- 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06,
- 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21,
- 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe,
- 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42,
- 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57,
- 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b,
- 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03,
- 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01,
- 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c,
- 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64,
- 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97,
- 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06,
- 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7,
- 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58,
- 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24,
- 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe,
- 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a,
- 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe,
- 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb,
- 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e,
- 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26,
- 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e,
- 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c,
- 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef,
- 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe,
- 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51,
- 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe,
- 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18,
- 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe,
- 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92,
- 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2,
- 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe,
- 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe,
- 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94,
- 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3,
- 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12,
- 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e,
- 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5,
- 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32,
- 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0,
- 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41,
- 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99,
- 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8,
- 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01,
- 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81,
- 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13,
- 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b,
- 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe,
- 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00,
- 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85,
- 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe,
- 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f,
- 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e,
- 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2,
- 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe,
- 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01,
- 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d,
- 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe,
- 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c,
- 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0,
- 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19,
- 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19,
- 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19,
- 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75,
- 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d,
- 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c,
- 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01,
- 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e,
- 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0,
- 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56,
- 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01,
- 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe,
- 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe,
- 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe,
- 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47,
- 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12,
- 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe,
- 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b,
- 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe,
- 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe,
- 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec,
- 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b,
- 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02,
- 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3,
- 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10,
- 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e,
- 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02,
- 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13,
- 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc,
- 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe,
- 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe,
- 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06,
- 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83,
- 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80,
- 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe,
- 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c,
- 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe,
- 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4,
- 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09,
- 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01,
- 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01,
- 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e,
- 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe,
- 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64,
- 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe,
- 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01,
- 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40,
- 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03,
- 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07,
- 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00,
- 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10,
- 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe,
- 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13,
- 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe,
- 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe,
- 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0,
- 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10,
- 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47,
- 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01,
- 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42,
- 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01,
- 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01,
- 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89,
- 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85,
- 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec,
- 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e,
- 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01,
- 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee,
- 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d,
- 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23,
- 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09,
- 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42,
- 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a,
- 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43,
- 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80,
- 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34,
- 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e,
- 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10,
- 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49,
- 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
- 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa,
- 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe,
- 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe,
- 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56,
- 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9,
- 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50,
- 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6,
- 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03,
- 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e,
- 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25,
- 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01,
- 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13,
- 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9,
- 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01,
- 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08,
- 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d,
- 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a,
- 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08,
- 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03,
- 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45,
- 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01,
- 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82,
- 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e,
- 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66,
- 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56,
- 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd,
- 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe,
- 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe,
- 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05,
- 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73,
- 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d,
- 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b,
- 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d,
- 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72,
- 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01,
- 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17,
- 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe,
- 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32,
- 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
- 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02,
- 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30,
- 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52,
- 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e,
- 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58,
- 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01,
- 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54,
- 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07,
- 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a,
- 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00,
- 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe,
- 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77,
- 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16,
- 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17,
- 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe,
- 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12,
- 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d,
- 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04,
- 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55,
- 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80,
- 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16,
- 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64,
- 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60,
- 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8,
- 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe,
- 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe,
- 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b,
- 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe,
- 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe,
- 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7,
- 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13,
- 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27,
- 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9,
- 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe,
- 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9,
- 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01,
- 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01,
- 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2,
- 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e,
- 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10,
- 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18,
- 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe,
- 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe,
- 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe,
- 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe,
- 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10,
- 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0,
- 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa,
- 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe,
- 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4,
- 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01,
- 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe,
- 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01,
- 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e,
- 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14,
- 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17,
- 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f,
- 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
- 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1,
- 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01,
- 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f,
- 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89,
- 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe,
- 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17,
- 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c,
- 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e,
- 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f,
- 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13,
- 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09,
- 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18,
- 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01,
- 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa,
- 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe,
- 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01,
- 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80,
- 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18,
- 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c,
- 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d,
- 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3,
- 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe,
- 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01,
- 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe,
- 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07,
- 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c,
- 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9,
- 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83,
- 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1,
- 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe,
- 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b,
- 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04,
- 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04,
- 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a,
- 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6,
- 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c,
- 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe,
- 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee,
- 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83,
- 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a,
- 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45,
- 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe,
- 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13,
- 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1,
- 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13,
- 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a,
- 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48,
- 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f,
- 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01,
- 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24,
- 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d,
- 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30,
- 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80,
- 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38,
- 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31,
- 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba,
- 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44,
- 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09,
- 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89,
- 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90,
- 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b,
- 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10,
- 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe,
- 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1,
- 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1,
- 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c,
- 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa,
- 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d,
- 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8,
- 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe,
- 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e,
- 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99,
- 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08,
- 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e,
- 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84,
- 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80,
- 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04,
- 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06,
- 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f,
- 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b,
- 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e,
- 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00,
-};
-
-static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */
-static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */
-
static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc)
{
PortAddr iop_base;
@@ -6362,6 +4751,10 @@ static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc)
static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/mcode.bin";
+ int err;
+ unsigned long chksum;
ushort warn_code;
PortAddr iop_base;
@@ -6383,12 +4776,29 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
warn_code |= AscInitLram(asc_dvc);
if (asc_dvc->err_code != 0)
return UW_ERR;
- ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum);
- if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf,
- _asc_mcode_size) != _asc_mcode_chksum) {
+
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)chksum);
+ if (AscLoadMicroCode(iop_base, 0, &fw->data[4],
+ fw->size - 4) != chksum) {
asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM;
+ release_firmware(fw);
return warn_code;
}
+ release_firmware(fw);
warn_code |= AscInitMicroCodeVar(asc_dvc);
asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC;
AscEnableInterrupt(iop_base);
@@ -6417,8 +4827,8 @@ static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc)
*
* Returns 0 or an error if the checksum doesn't match
*/
-static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size,
- int memsize, int chksum)
+static int AdvLoadMicrocode(AdvPortAddr iop_base, const unsigned char *buf,
+ int size, int memsize, int chksum)
{
int i, j, end, len = 0;
ADV_DCNT sum;
@@ -6627,6 +5037,8 @@ static int AdvResetSB(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/3550.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -6634,6 +5046,8 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
int word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar tid;
ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */
@@ -6692,9 +5106,24 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
max_cmd[tid]);
}
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf,
- _adv_asc3550_size, ADV_3550_MEMSIZE,
- _adv_asc3550_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_3550_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -7065,6 +5494,8 @@ static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/38C0800.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -7072,6 +5503,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
int word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar byte;
uchar tid;
@@ -7187,9 +5620,24 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
/* We need to reset back to normal mode after LRAM test passes. */
AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf,
- _adv_asc38C0800_size, ADV_38C0800_MEMSIZE,
- _adv_asc38C0800_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_38C0800_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -7544,6 +5992,8 @@ static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc)
*/
static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
{
+ const struct firmware *fw;
+ const char fwname[] = "advansys/38C1600.bin";
AdvPortAddr iop_base;
ushort warn_code;
int begin_addr;
@@ -7551,6 +6001,8 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
ushort code_sum;
long word;
int i;
+ int err;
+ unsigned long chksum;
ushort scsi_cfg1;
uchar byte;
uchar tid;
@@ -7668,9 +6120,24 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc)
/* We need to reset back to normal mode after LRAM test passes. */
AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE);
- asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf,
- _adv_asc38C1600_size, ADV_38C1600_MEMSIZE,
- _adv_asc38C1600_chksum);
+ err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size < 4) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ chksum = (fw->data[3] << 24) | (fw->data[2] << 16) |
+ (fw->data[1] << 8) | fw->data[0];
+ asc_dvc->err_code = AdvLoadMicrocode(iop_base, &fw->data[4],
+ fw->size - 4, ADV_38C1600_MEMSIZE,
+ chksum);
+ release_firmware(fw);
if (asc_dvc->err_code)
return ADV_ERROR;
@@ -14353,3 +12820,7 @@ module_init(advansys_init);
module_exit(advansys_exit);
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("advansys/mcode.bin");
+MODULE_FIRMWARE("advansys/3550.bin");
+MODULE_FIRMWARE("advansys/38C0800.bin");
+MODULE_FIRMWARE("advansys/38C1600.bin");
diff --git a/drivers/scsi/aic7xxx/aic79xx_core.c b/drivers/scsi/aic7xxx/aic79xx_core.c
index bdad54ec088..63b521d615f 100644
--- a/drivers/scsi/aic7xxx/aic79xx_core.c
+++ b/drivers/scsi/aic7xxx/aic79xx_core.c
@@ -1034,7 +1034,7 @@ ahd_intr(struct ahd_softc *ahd)
}
/******************************** Private Inlines *****************************/
-static __inline void
+static inline void
ahd_assert_atn(struct ahd_softc *ahd)
{
ahd_outb(ahd, SCSISIGO, ATNO);
@@ -1069,7 +1069,7 @@ ahd_currently_packetized(struct ahd_softc *ahd)
return (packetized);
}
-static __inline int
+static inline int
ahd_set_active_fifo(struct ahd_softc *ahd)
{
u_int active_fifo;
@@ -1086,7 +1086,7 @@ ahd_set_active_fifo(struct ahd_softc *ahd)
}
}
-static __inline void
+static inline void
ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
{
ahd_busy_tcl(ahd, tcl, SCB_LIST_NULL);
@@ -1096,7 +1096,7 @@ ahd_unbusy_tcl(struct ahd_softc *ahd, u_int tcl)
* Determine whether the sequencer reported a residual
* for this SCB/transaction.
*/
-static __inline void
+static inline void
ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
{
uint32_t sgptr;
@@ -1106,7 +1106,7 @@ ahd_update_residual(struct ahd_softc *ahd, struct scb *scb)
ahd_calc_residual(ahd, scb);
}
-static __inline void
+static inline void
ahd_complete_scb(struct ahd_softc *ahd, struct scb *scb)
{
uint32_t sgptr;
@@ -7987,7 +7987,7 @@ ahd_resume(struct ahd_softc *ahd)
* scbid that should be restored once manipualtion
* of the TCL entry is complete.
*/
-static __inline u_int
+static inline u_int
ahd_index_busy_tcl(struct ahd_softc *ahd, u_int *saved_scbid, u_int tcl)
{
/*
diff --git a/drivers/scsi/aic7xxx/aic79xx_inline.h b/drivers/scsi/aic7xxx/aic79xx_inline.h
index 5f12cf9d99d..09335a3c869 100644
--- a/drivers/scsi/aic7xxx/aic79xx_inline.h
+++ b/drivers/scsi/aic7xxx/aic79xx_inline.h
@@ -46,21 +46,20 @@
#define _AIC79XX_INLINE_H_
/******************************** Debugging ***********************************/
-static __inline char *ahd_name(struct ahd_softc *ahd);
+static inline char *ahd_name(struct ahd_softc *ahd);
-static __inline char *
-ahd_name(struct ahd_softc *ahd)
+static inline char *ahd_name(struct ahd_softc *ahd)
{
return (ahd->name);
}
/************************ Sequencer Execution Control *************************/
-static __inline void ahd_known_modes(struct ahd_softc *ahd,
+static inline void ahd_known_modes(struct ahd_softc *ahd,
ahd_mode src, ahd_mode dst);
-static __inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd,
+static inline ahd_mode_state ahd_build_mode_state(struct ahd_softc *ahd,
ahd_mode src,
ahd_mode dst);
-static __inline void ahd_extract_mode_state(struct ahd_softc *ahd,
+static inline void ahd_extract_mode_state(struct ahd_softc *ahd,
ahd_mode_state state,
ahd_mode *src, ahd_mode *dst);
@@ -73,7 +72,7 @@ int ahd_is_paused(struct ahd_softc *ahd);
void ahd_pause(struct ahd_softc *ahd);
void ahd_unpause(struct ahd_softc *ahd);
-static __inline void
+static inline void
ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
{
ahd->src_mode = src;
@@ -82,13 +81,13 @@ ahd_known_modes(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
ahd->saved_dst_mode = dst;
}
-static __inline ahd_mode_state
+static inline ahd_mode_state
ahd_build_mode_state(struct ahd_softc *ahd, ahd_mode src, ahd_mode dst)
{
return ((src << SRC_MODE_SHIFT) | (dst << DST_MODE_SHIFT));
}
-static __inline void
+static inline void
ahd_extract_mode_state(struct ahd_softc *ahd, ahd_mode_state state,
ahd_mode *src, ahd_mode *dst)
{
@@ -102,13 +101,12 @@ void *ahd_sg_setup(struct ahd_softc *ahd, struct scb *scb,
bus_size_t len, int last);
/************************** Memory mapping routines ***************************/
-static __inline size_t ahd_sg_size(struct ahd_softc *ahd);
+static inline size_t ahd_sg_size(struct ahd_softc *ahd);
void ahd_sync_sglist(struct ahd_softc *ahd,
struct scb *scb, int op);
-static __inline size_t
-ahd_sg_size(struct ahd_softc *ahd)
+static inline size_t ahd_sg_size(struct ahd_softc *ahd)
{
if ((ahd->flags & AHD_64BIT_ADDRESSING) != 0)
return (sizeof(struct ahd_dma64_seg));
@@ -141,11 +139,9 @@ struct scb *
ahd_lookup_scb(struct ahd_softc *ahd, u_int tag);
void ahd_queue_scb(struct ahd_softc *ahd, struct scb *scb);
-static __inline uint8_t *
- ahd_get_sense_buf(struct ahd_softc *ahd,
+static inline uint8_t *ahd_get_sense_buf(struct ahd_softc *ahd,
struct scb *scb);
-static __inline uint32_t
- ahd_get_sense_bufaddr(struct ahd_softc *ahd,
+static inline uint32_t ahd_get_sense_bufaddr(struct ahd_softc *ahd,
struct scb *scb);
#if 0 /* unused */
@@ -158,13 +154,13 @@ do { \
#endif
-static __inline uint8_t *
+static inline uint8_t *
ahd_get_sense_buf(struct ahd_softc *ahd, struct scb *scb)
{
return (scb->sense_data);
}
-static __inline uint32_t
+static inline uint32_t
ahd_get_sense_bufaddr(struct ahd_softc *ahd, struct scb *scb)
{
return (scb->sense_busaddr);
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h
index 8d6612c1992..55c1fe07969 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.h
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.h
@@ -395,19 +395,19 @@ struct info_str {
};
/******************************** Locking *************************************/
-static __inline void
+static inline void
ahd_lockinit(struct ahd_softc *ahd)
{
spin_lock_init(&ahd->platform_data->spin_lock);
}
-static __inline void
+static inline void
ahd_lock(struct ahd_softc *ahd, unsigned long *flags)
{
spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags);
}
-static __inline void
+static inline void
ahd_unlock(struct ahd_softc *ahd, unsigned long *flags)
{
spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags);
@@ -490,29 +490,29 @@ void ahd_pci_write_config(ahd_dev_softc_t pci,
int reg, uint32_t value,
int width);
-static __inline int ahd_get_pci_function(ahd_dev_softc_t);
-static __inline int
+static inline int ahd_get_pci_function(ahd_dev_softc_t);
+static inline int
ahd_get_pci_function(ahd_dev_softc_t pci)
{
return (PCI_FUNC(pci->devfn));
}
-static __inline int ahd_get_pci_slot(ahd_dev_softc_t);
-static __inline int
+static inline int ahd_get_pci_slot(ahd_dev_softc_t);
+static inline int
ahd_get_pci_slot(ahd_dev_softc_t pci)
{
return (PCI_SLOT(pci->devfn));
}
-static __inline int ahd_get_pci_bus(ahd_dev_softc_t);
-static __inline int
+static inline int ahd_get_pci_bus(ahd_dev_softc_t);
+static inline int
ahd_get_pci_bus(ahd_dev_softc_t pci)
{
return (pci->bus->number);
}
-static __inline void ahd_flush_device_writes(struct ahd_softc *);
-static __inline void
+static inline void ahd_flush_device_writes(struct ahd_softc *);
+static inline void
ahd_flush_device_writes(struct ahd_softc *ahd)
{
/* XXX Is this sufficient for all architectures??? */
@@ -524,81 +524,81 @@ int ahd_linux_proc_info(struct Scsi_Host *, char *, char **,
off_t, int, int);
/*********************** Transaction Access Wrappers **************************/
-static __inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahd_set_transaction_status(struct scb *, uint32_t);
-static __inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahd_set_scsi_status(struct scb *, uint32_t);
-static __inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahd_get_transaction_status(struct scb *);
-static __inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahd_get_scsi_status(struct scb *);
-static __inline void ahd_set_transaction_tag(struct scb *, int, u_int);
-static __inline u_long ahd_get_transfer_length(struct scb *);
-static __inline int ahd_get_transfer_dir(struct scb *);
-static __inline void ahd_set_residual(struct scb *, u_long);
-static __inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
-static __inline u_long ahd_get_residual(struct scb *);
-static __inline u_long ahd_get_sense_residual(struct scb *);
-static __inline int ahd_perform_autosense(struct scb *);
-static __inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
+static inline void ahd_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
+static inline void ahd_set_transaction_status(struct scb *, uint32_t);
+static inline void ahd_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
+static inline void ahd_set_scsi_status(struct scb *, uint32_t);
+static inline uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahd_get_transaction_status(struct scb *);
+static inline uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahd_get_scsi_status(struct scb *);
+static inline void ahd_set_transaction_tag(struct scb *, int, u_int);
+static inline u_long ahd_get_transfer_length(struct scb *);
+static inline int ahd_get_transfer_dir(struct scb *);
+static inline void ahd_set_residual(struct scb *, u_long);
+static inline void ahd_set_sense_residual(struct scb *scb, u_long resid);
+static inline u_long ahd_get_residual(struct scb *);
+static inline u_long ahd_get_sense_residual(struct scb *);
+static inline int ahd_perform_autosense(struct scb *);
+static inline uint32_t ahd_get_sense_bufsize(struct ahd_softc *,
struct scb *);
-static __inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
+static inline void ahd_notify_xfer_settings_change(struct ahd_softc *,
struct ahd_devinfo *);
-static __inline void ahd_platform_scb_free(struct ahd_softc *ahd,
+static inline void ahd_platform_scb_free(struct ahd_softc *ahd,
struct scb *scb);
-static __inline void ahd_freeze_scb(struct scb *scb);
+static inline void ahd_freeze_scb(struct scb *scb);
-static __inline
+static inline
void ahd_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~(CAM_STATUS_MASK << 16);
cmd->result |= status << 16;
}
-static __inline
+static inline
void ahd_set_transaction_status(struct scb *scb, uint32_t status)
{
ahd_cmd_set_transaction_status(scb->io_ctx,status);
}
-static __inline
+static inline
void ahd_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~0xFFFF;
cmd->result |= status;
}
-static __inline
+static inline
void ahd_set_scsi_status(struct scb *scb, uint32_t status)
{
ahd_cmd_set_scsi_status(scb->io_ctx, status);
}
-static __inline
+static inline
uint32_t ahd_cmd_get_transaction_status(struct scsi_cmnd *cmd)
{
return ((cmd->result >> 16) & CAM_STATUS_MASK);
}
-static __inline
+static inline
uint32_t ahd_get_transaction_status(struct scb *scb)
{
return (ahd_cmd_get_transaction_status(scb->io_ctx));
}
-static __inline
+static inline
uint32_t ahd_cmd_get_scsi_status(struct scsi_cmnd *cmd)
{
return (cmd->result & 0xFFFF);
}
-static __inline
+static inline
uint32_t ahd_get_scsi_status(struct scb *scb)
{
return (ahd_cmd_get_scsi_status(scb->io_ctx));
}
-static __inline
+static inline
void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
{
/*
@@ -607,43 +607,43 @@ void ahd_set_transaction_tag(struct scb *scb, int enabled, u_int type)
*/
}
-static __inline
+static inline
u_long ahd_get_transfer_length(struct scb *scb)
{
return (scb->platform_data->xfer_len);
}
-static __inline
+static inline
int ahd_get_transfer_dir(struct scb *scb)
{
return (scb->io_ctx->sc_data_direction);
}
-static __inline
+static inline
void ahd_set_residual(struct scb *scb, u_long resid)
{
scsi_set_resid(scb->io_ctx, resid);
}
-static __inline
+static inline
void ahd_set_sense_residual(struct scb *scb, u_long resid)
{
scb->platform_data->sense_resid = resid;
}
-static __inline
+static inline
u_long ahd_get_residual(struct scb *scb)
{
return scsi_get_resid(scb->io_ctx);
}
-static __inline
+static inline
u_long ahd_get_sense_residual(struct scb *scb)
{
return (scb->platform_data->sense_resid);
}
-static __inline
+static inline
int ahd_perform_autosense(struct scb *scb)
{
/*
@@ -654,20 +654,20 @@ int ahd_perform_autosense(struct scb *scb)
return (1);
}
-static __inline uint32_t
+static inline uint32_t
ahd_get_sense_bufsize(struct ahd_softc *ahd, struct scb *scb)
{
return (sizeof(struct scsi_sense_data));
}
-static __inline void
+static inline void
ahd_notify_xfer_settings_change(struct ahd_softc *ahd,
struct ahd_devinfo *devinfo)
{
/* Nothing to do here for linux */
}
-static __inline void
+static inline void
ahd_platform_scb_free(struct ahd_softc *ahd, struct scb *scb)
{
ahd->flags &= ~AHD_RESOURCE_SHORTAGE;
@@ -678,7 +678,7 @@ void ahd_platform_free(struct ahd_softc *ahd);
void ahd_platform_init(struct ahd_softc *ahd);
void ahd_platform_freeze_devq(struct ahd_softc *ahd, struct scb *scb);
-static __inline void
+static inline void
ahd_freeze_scb(struct scb *scb)
{
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
diff --git a/drivers/scsi/aic7xxx/aic79xx_pci.c b/drivers/scsi/aic7xxx/aic79xx_pci.c
index a734d77e880..90a04a37b4f 100644
--- a/drivers/scsi/aic7xxx/aic79xx_pci.c
+++ b/drivers/scsi/aic7xxx/aic79xx_pci.c
@@ -51,7 +51,7 @@
#include "aic79xx_pci.h"
-static __inline uint64_t
+static inline uint64_t
ahd_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
{
uint64_t id;
@@ -377,14 +377,12 @@ ahd_pci_config(struct ahd_softc *ahd, const struct ahd_pci_identity *entry)
error = ahd_init(ahd);
if (error != 0)
return (error);
+ ahd->init_level++;
/*
* Allow interrupts now that we are completely setup.
*/
- error = ahd_pci_map_int(ahd);
- if (!error)
- ahd->init_level++;
- return error;
+ return ahd_pci_map_int(ahd);
}
#ifdef CONFIG_PM
diff --git a/drivers/scsi/aic7xxx/aic7xxx_inline.h b/drivers/scsi/aic7xxx/aic7xxx_inline.h
index 09bf2f4d78d..0b57b783ef4 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_inline.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_inline.h
@@ -55,10 +55,9 @@ void ahc_sync_sglist(struct ahc_softc *ahc,
struct scb *scb, int op);
/******************************** Debugging ***********************************/
-static __inline char *ahc_name(struct ahc_softc *ahc);
+static inline char *ahc_name(struct ahc_softc *ahc);
-static __inline char *
-ahc_name(struct ahc_softc *ahc)
+static inline char *ahc_name(struct ahc_softc *ahc)
{
return (ahc->name);
}
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h
index 3f7238db35e..56f07e527b4 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.h
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h
@@ -230,7 +230,7 @@ int ahc_dmamap_unload(struct ahc_softc *, bus_dma_tag_t, bus_dmamap_t);
#include "aic7xxx.h"
/***************************** Timer Facilities *******************************/
-static __inline void
+static inline void
ahc_scb_timer_reset(struct scb *scb, u_int usec)
{
}
@@ -401,19 +401,19 @@ struct info_str {
/******************************** Locking *************************************/
/* Lock protecting internal data structures */
-static __inline void
+static inline void
ahc_lockinit(struct ahc_softc *ahc)
{
spin_lock_init(&ahc->platform_data->spin_lock);
}
-static __inline void
+static inline void
ahc_lock(struct ahc_softc *ahc, unsigned long *flags)
{
spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags);
}
-static __inline void
+static inline void
ahc_unlock(struct ahc_softc *ahc, unsigned long *flags)
{
spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags);
@@ -493,22 +493,22 @@ void ahc_pci_write_config(ahc_dev_softc_t pci,
int reg, uint32_t value,
int width);
-static __inline int ahc_get_pci_function(ahc_dev_softc_t);
-static __inline int
+static inline int ahc_get_pci_function(ahc_dev_softc_t);
+static inline int
ahc_get_pci_function(ahc_dev_softc_t pci)
{
return (PCI_FUNC(pci->devfn));
}
-static __inline int ahc_get_pci_slot(ahc_dev_softc_t);
-static __inline int
+static inline int ahc_get_pci_slot(ahc_dev_softc_t);
+static inline int
ahc_get_pci_slot(ahc_dev_softc_t pci)
{
return (PCI_SLOT(pci->devfn));
}
-static __inline int ahc_get_pci_bus(ahc_dev_softc_t);
-static __inline int
+static inline int ahc_get_pci_bus(ahc_dev_softc_t);
+static inline int
ahc_get_pci_bus(ahc_dev_softc_t pci)
{
return (pci->bus->number);
@@ -521,8 +521,8 @@ static inline void ahc_linux_pci_exit(void) {
}
#endif
-static __inline void ahc_flush_device_writes(struct ahc_softc *);
-static __inline void
+static inline void ahc_flush_device_writes(struct ahc_softc *);
+static inline void
ahc_flush_device_writes(struct ahc_softc *ahc)
{
/* XXX Is this sufficient for all architectures??? */
@@ -535,81 +535,81 @@ int ahc_linux_proc_info(struct Scsi_Host *, char *, char **,
/*************************** Domain Validation ********************************/
/*********************** Transaction Access Wrappers *************************/
-static __inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahc_set_transaction_status(struct scb *, uint32_t);
-static __inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
-static __inline void ahc_set_scsi_status(struct scb *, uint32_t);
-static __inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahc_get_transaction_status(struct scb *);
-static __inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
-static __inline uint32_t ahc_get_scsi_status(struct scb *);
-static __inline void ahc_set_transaction_tag(struct scb *, int, u_int);
-static __inline u_long ahc_get_transfer_length(struct scb *);
-static __inline int ahc_get_transfer_dir(struct scb *);
-static __inline void ahc_set_residual(struct scb *, u_long);
-static __inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
-static __inline u_long ahc_get_residual(struct scb *);
-static __inline u_long ahc_get_sense_residual(struct scb *);
-static __inline int ahc_perform_autosense(struct scb *);
-static __inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
+static inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t);
+static inline void ahc_set_transaction_status(struct scb *, uint32_t);
+static inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t);
+static inline void ahc_set_scsi_status(struct scb *, uint32_t);
+static inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahc_get_transaction_status(struct scb *);
+static inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd);
+static inline uint32_t ahc_get_scsi_status(struct scb *);
+static inline void ahc_set_transaction_tag(struct scb *, int, u_int);
+static inline u_long ahc_get_transfer_length(struct scb *);
+static inline int ahc_get_transfer_dir(struct scb *);
+static inline void ahc_set_residual(struct scb *, u_long);
+static inline void ahc_set_sense_residual(struct scb *scb, u_long resid);
+static inline u_long ahc_get_residual(struct scb *);
+static inline u_long ahc_get_sense_residual(struct scb *);
+static inline int ahc_perform_autosense(struct scb *);
+static inline uint32_t ahc_get_sense_bufsize(struct ahc_softc *,
struct scb *);
-static __inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
+static inline void ahc_notify_xfer_settings_change(struct ahc_softc *,
struct ahc_devinfo *);
-static __inline void ahc_platform_scb_free(struct ahc_softc *ahc,
+static inline void ahc_platform_scb_free(struct ahc_softc *ahc,
struct scb *scb);
-static __inline void ahc_freeze_scb(struct scb *scb);
+static inline void ahc_freeze_scb(struct scb *scb);
-static __inline
+static inline
void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~(CAM_STATUS_MASK << 16);
cmd->result |= status << 16;
}
-static __inline
+static inline
void ahc_set_transaction_status(struct scb *scb, uint32_t status)
{
ahc_cmd_set_transaction_status(scb->io_ctx,status);
}
-static __inline
+static inline
void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status)
{
cmd->result &= ~0xFFFF;
cmd->result |= status;
}
-static __inline
+static inline
void ahc_set_scsi_status(struct scb *scb, uint32_t status)
{
ahc_cmd_set_scsi_status(scb->io_ctx, status);
}
-static __inline
+static inline
uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd)
{
return ((cmd->result >> 16) & CAM_STATUS_MASK);
}
-static __inline
+static inline
uint32_t ahc_get_transaction_status(struct scb *scb)
{
return (ahc_cmd_get_transaction_status(scb->io_ctx));
}
-static __inline
+static inline
uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd)
{
return (cmd->result & 0xFFFF);
}
-static __inline
+static inline
uint32_t ahc_get_scsi_status(struct scb *scb)
{
return (ahc_cmd_get_scsi_status(scb->io_ctx));
}
-static __inline
+static inline
void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
{
/*
@@ -618,43 +618,43 @@ void ahc_set_transaction_tag(struct scb *scb, int enabled, u_int type)
*/
}
-static __inline
+static inline
u_long ahc_get_transfer_length(struct scb *scb)
{
return (scb->platform_data->xfer_len);
}
-static __inline
+static inline
int ahc_get_transfer_dir(struct scb *scb)
{
return (scb->io_ctx->sc_data_direction);
}
-static __inline
+static inline
void ahc_set_residual(struct scb *scb, u_long resid)
{
scsi_set_resid(scb->io_ctx, resid);
}
-static __inline
+static inline
void ahc_set_sense_residual(struct scb *scb, u_long resid)
{
scb->platform_data->sense_resid = resid;
}
-static __inline
+static inline
u_long ahc_get_residual(struct scb *scb)
{
return scsi_get_resid(scb->io_ctx);
}
-static __inline
+static inline
u_long ahc_get_sense_residual(struct scb *scb)
{
return (scb->platform_data->sense_resid);
}
-static __inline
+static inline
int ahc_perform_autosense(struct scb *scb)
{
/*
@@ -665,20 +665,20 @@ int ahc_perform_autosense(struct scb *scb)
return (1);
}
-static __inline uint32_t
+static inline uint32_t
ahc_get_sense_bufsize(struct ahc_softc *ahc, struct scb *scb)
{
return (sizeof(struct scsi_sense_data));
}
-static __inline void
+static inline void
ahc_notify_xfer_settings_change(struct ahc_softc *ahc,
struct ahc_devinfo *devinfo)
{
/* Nothing to do here for linux */
}
-static __inline void
+static inline void
ahc_platform_scb_free(struct ahc_softc *ahc, struct scb *scb)
{
}
@@ -687,7 +687,7 @@ int ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg);
void ahc_platform_free(struct ahc_softc *ahc);
void ahc_platform_freeze_devq(struct ahc_softc *ahc, struct scb *scb);
-static __inline void
+static inline void
ahc_freeze_scb(struct scb *scb)
{
if ((scb->io_ctx->result & (CAM_DEV_QFRZN << 16)) == 0) {
diff --git a/drivers/scsi/aic7xxx/aic7xxx_pci.c b/drivers/scsi/aic7xxx/aic7xxx_pci.c
index c07cb6eebb0..27014b9de12 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_pci.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_pci.c
@@ -54,7 +54,7 @@
#include "aic7xxx_pci.h"
-static __inline uint64_t
+static inline uint64_t
ahc_compose_id(u_int device, u_int vendor, u_int subdevice, u_int subvendor)
{
uint64_t id;
@@ -960,16 +960,12 @@ ahc_pci_config(struct ahc_softc *ahc, const struct ahc_pci_identity *entry)
error = ahc_init(ahc);
if (error != 0)
return (error);
+ ahc->init_level++;
/*
* Allow interrupts now that we are completely setup.
*/
- error = ahc_pci_map_int(ahc);
- if (error != 0)
- return (error);
-
- ahc->init_level++;
- return (0);
+ return ahc_pci_map_int(ahc);
}
/*
diff --git a/drivers/scsi/aic7xxx/aiclib.h b/drivers/scsi/aic7xxx/aiclib.h
index 3bfbf0fe1ec..f8fd198aafb 100644
--- a/drivers/scsi/aic7xxx/aiclib.h
+++ b/drivers/scsi/aic7xxx/aiclib.h
@@ -133,7 +133,7 @@ struct scsi_sense_data
#define SCSI_STATUS_TASK_ABORTED 0x40
/************************* Large Disk Handling ********************************/
-static __inline int
+static inline int
aic_sector_div(sector_t capacity, int heads, int sectors)
{
/* ugly, ugly sector_div calling convention.. */
@@ -141,7 +141,7 @@ aic_sector_div(sector_t capacity, int heads, int sectors)
return (int)capacity;
}
-static __inline uint32_t
+static inline uint32_t
scsi_4btoul(uint8_t *bytes)
{
uint32_t rv;
diff --git a/drivers/scsi/cxgb3i/Kbuild b/drivers/scsi/cxgb3i/Kbuild
index ee7d6d2f9c3..25a2032bfa2 100644
--- a/drivers/scsi/cxgb3i/Kbuild
+++ b/drivers/scsi/cxgb3i/Kbuild
@@ -1,4 +1,4 @@
EXTRA_CFLAGS += -I$(TOPDIR)/drivers/net/cxgb3
-cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o
-obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i_ddp.o cxgb3i.o
+cxgb3i-y := cxgb3i_init.o cxgb3i_iscsi.o cxgb3i_pdu.o cxgb3i_offload.o cxgb3i_ddp.o
+obj-$(CONFIG_SCSI_CXGB3_ISCSI) += cxgb3i.o
diff --git a/drivers/scsi/cxgb3i/cxgb3i.h b/drivers/scsi/cxgb3i/cxgb3i.h
index a7cf550b9cc..d362860e750 100644
--- a/drivers/scsi/cxgb3i/cxgb3i.h
+++ b/drivers/scsi/cxgb3i/cxgb3i.h
@@ -66,10 +66,12 @@ struct cxgb3i_hba {
* @pdev: pointer to pci dev
* @hba_cnt: # of hbas (the same as # of ports)
* @hba: all the hbas on this adapter
+ * @flags: bit flag for adapter event/status
* @tx_max_size: max. tx packet size supported
* @rx_max_size: max. rx packet size supported
* @tag_format: ddp tag format settings
*/
+#define CXGB3I_ADAPTER_FLAG_RESET 0x1
struct cxgb3i_adapter {
struct list_head list_head;
spinlock_t lock;
@@ -78,6 +80,7 @@ struct cxgb3i_adapter {
unsigned char hba_cnt;
struct cxgb3i_hba *hba[MAX_NPORTS];
+ unsigned int flags;
unsigned int tx_max_size;
unsigned int rx_max_size;
@@ -137,10 +140,9 @@ struct cxgb3i_task_data {
int cxgb3i_iscsi_init(void);
void cxgb3i_iscsi_cleanup(void);
-struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *);
-void cxgb3i_adapter_remove(struct t3cdev *);
-int cxgb3i_adapter_ulp_init(struct cxgb3i_adapter *);
-void cxgb3i_adapter_ulp_cleanup(struct cxgb3i_adapter *);
+struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *);
+void cxgb3i_adapter_open(struct t3cdev *);
+void cxgb3i_adapter_close(struct t3cdev *);
struct cxgb3i_hba *cxgb3i_hba_find_by_netdev(struct net_device *);
struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *,
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.c b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
index 4eb6f5593b3..d06a661c209 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.c
@@ -23,19 +23,6 @@
#include "cxgb3i_ddp.h"
-#define DRV_MODULE_NAME "cxgb3i_ddp"
-#define DRV_MODULE_VERSION "1.0.0"
-#define DRV_MODULE_RELDATE "Dec. 1, 2008"
-
-static char version[] =
- "Chelsio S3xx iSCSI DDP " DRV_MODULE_NAME
- " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
-
-MODULE_AUTHOR("Karen Xie <kxie@chelsio.com>");
-MODULE_DESCRIPTION("cxgb3i ddp pagepod manager");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_MODULE_VERSION);
-
#define ddp_log_error(fmt...) printk(KERN_ERR "cxgb3i_ddp: ERR! " fmt)
#define ddp_log_warn(fmt...) printk(KERN_WARNING "cxgb3i_ddp: WARN! " fmt)
#define ddp_log_info(fmt...) printk(KERN_INFO "cxgb3i_ddp: " fmt)
@@ -66,9 +53,6 @@ static unsigned char ddp_page_order[DDP_PGIDX_MAX] = {0, 1, 2, 4};
static unsigned char ddp_page_shift[DDP_PGIDX_MAX] = {12, 13, 14, 16};
static unsigned char page_idx = DDP_PGIDX_MAX;
-static LIST_HEAD(cxgb3i_ddp_list);
-static DEFINE_RWLOCK(cxgb3i_ddp_rwlock);
-
/*
* functions to program the pagepod in h/w
*/
@@ -113,8 +97,8 @@ static int set_ddp_map(struct cxgb3i_ddp_info *ddp, struct pagepod_hdr *hdr,
return 0;
}
-static int clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int idx,
- unsigned int npods)
+static void clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int tag,
+ unsigned int idx, unsigned int npods)
{
unsigned int pm_addr = (idx << PPOD_SIZE_SHIFT) + ddp->llimit;
int i;
@@ -122,13 +106,17 @@ static int clear_ddp_map(struct cxgb3i_ddp_info *ddp, unsigned int idx,
for (i = 0; i < npods; i++, idx++, pm_addr += PPOD_SIZE) {
struct sk_buff *skb = ddp->gl_skb[idx];
+ if (!skb) {
+ ddp_log_error("ddp tag 0x%x, 0x%x, %d/%u, skb NULL.\n",
+ tag, idx, i, npods);
+ continue;
+ }
ddp->gl_skb[idx] = NULL;
memset((skb->head + sizeof(struct ulp_mem_io)), 0, PPOD_SIZE);
ulp_mem_io_set_hdr(skb, pm_addr);
skb->priority = CPL_PRIORITY_CONTROL;
cxgb3_ofld_send(ddp->tdev, skb);
}
- return 0;
}
static inline int ddp_find_unused_entries(struct cxgb3i_ddp_info *ddp,
@@ -211,7 +199,6 @@ int cxgb3i_ddp_find_page_index(unsigned long pgsz)
ddp_log_debug("ddp page size 0x%lx not supported.\n", pgsz);
return DDP_PGIDX_MAX;
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_find_page_index);
static inline void ddp_gl_unmap(struct pci_dev *pdev,
struct cxgb3i_gather_list *gl)
@@ -334,7 +321,6 @@ error_out:
kfree(gl);
return NULL;
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_make_gl);
/**
* cxgb3i_ddp_release_gl - release a page buffer list
@@ -348,7 +334,6 @@ void cxgb3i_ddp_release_gl(struct cxgb3i_gather_list *gl,
ddp_gl_unmap(pdev, gl);
kfree(gl);
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_release_gl);
/**
* cxgb3i_ddp_tag_reserve - set up ddp for a data transfer
@@ -430,7 +415,6 @@ unmark_entries:
ddp_unmark_entries(ddp, idx, npods);
return err;
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_tag_reserve);
/**
* cxgb3i_ddp_tag_release - release a ddp tag
@@ -453,22 +437,21 @@ void cxgb3i_ddp_tag_release(struct t3cdev *tdev, u32 tag)
struct cxgb3i_gather_list *gl = ddp->gl_map[idx];
unsigned int npods;
- if (!gl) {
- ddp_log_error("release ddp 0x%x, idx 0x%x, gl NULL.\n",
- tag, idx);
+ if (!gl || !gl->nelem) {
+ ddp_log_error("release 0x%x, idx 0x%x, gl 0x%p, %u.\n",
+ tag, idx, gl, gl ? gl->nelem : 0);
return;
}
npods = (gl->nelem + PPOD_PAGES_MAX - 1) >> PPOD_PAGES_SHIFT;
ddp_log_debug("ddp tag 0x%x, release idx 0x%x, npods %u.\n",
tag, idx, npods);
- clear_ddp_map(ddp, idx, npods);
+ clear_ddp_map(ddp, tag, idx, npods);
ddp_unmark_entries(ddp, idx, npods);
cxgb3i_ddp_release_gl(gl, ddp->pdev);
} else
ddp_log_error("ddp tag 0x%x, idx 0x%x > max 0x%x.\n",
tag, idx, ddp->nppods);
}
-EXPORT_SYMBOL_GPL(cxgb3i_ddp_tag_release);
static int setup_conn_pgidx(struct t3cdev *tdev, unsigned int tid, int pg_idx,
int reply)
@@ -509,7 +492,6 @@ int cxgb3i_setup_conn_host_pagesize(struct t3cdev *tdev, unsigned int tid,
{
return setup_conn_pgidx(tdev, tid, page_idx, reply);
}
-EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_host_pagesize);
/**
* cxgb3i_setup_conn_pagesize - setup the conn.'s ddp page size
@@ -526,7 +508,6 @@ int cxgb3i_setup_conn_pagesize(struct t3cdev *tdev, unsigned int tid,
return setup_conn_pgidx(tdev, tid, pgidx, reply);
}
-EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_pagesize);
/**
* cxgb3i_setup_conn_digest - setup conn. digest setting
@@ -562,26 +543,104 @@ int cxgb3i_setup_conn_digest(struct t3cdev *tdev, unsigned int tid,
cxgb3_ofld_send(tdev, skb);
return 0;
}
-EXPORT_SYMBOL_GPL(cxgb3i_setup_conn_digest);
-static int ddp_init(struct t3cdev *tdev)
+
+/**
+ * cxgb3i_adapter_ddp_info - read the adapter's ddp information
+ * @tdev: t3cdev adapter
+ * @tformat: tag format
+ * @txsz: max tx pdu payload size, filled in by this func.
+ * @rxsz: max rx pdu payload size, filled in by this func.
+ * setup the tag format for a given iscsi entity
+ */
+int cxgb3i_adapter_ddp_info(struct t3cdev *tdev,
+ struct cxgb3i_tag_format *tformat,
+ unsigned int *txsz, unsigned int *rxsz)
+{
+ struct cxgb3i_ddp_info *ddp;
+ unsigned char idx_bits;
+
+ if (!tformat)
+ return -EINVAL;
+
+ if (!tdev->ulp_iscsi)
+ return -EINVAL;
+
+ ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
+
+ idx_bits = 32 - tformat->sw_bits;
+ tformat->rsvd_bits = ddp->idx_bits;
+ tformat->rsvd_shift = PPOD_IDX_SHIFT;
+ tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;
+
+ ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
+ tformat->sw_bits, tformat->rsvd_bits,
+ tformat->rsvd_shift, tformat->rsvd_mask);
+
+ *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
+ ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
+ ddp_log_info("max payload size: %u/%u, %u/%u.\n",
+ *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
+ return 0;
+}
+
+/**
+ * cxgb3i_ddp_cleanup - release the cxgb3 adapter's ddp resource
+ * @tdev: t3cdev adapter
+ * release all the resource held by the ddp pagepod manager for a given
+ * adapter if needed
+ */
+void cxgb3i_ddp_cleanup(struct t3cdev *tdev)
+{
+ int i = 0;
+ struct cxgb3i_ddp_info *ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
+
+ ddp_log_info("t3dev 0x%p, release ddp 0x%p.\n", tdev, ddp);
+
+ if (ddp) {
+ tdev->ulp_iscsi = NULL;
+ while (i < ddp->nppods) {
+ struct cxgb3i_gather_list *gl = ddp->gl_map[i];
+ if (gl) {
+ int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
+ >> PPOD_PAGES_SHIFT;
+ ddp_log_info("t3dev 0x%p, ddp %d + %d.\n",
+ tdev, i, npods);
+ kfree(gl);
+ ddp_free_gl_skb(ddp, i, npods);
+ i += npods;
+ } else
+ i++;
+ }
+ cxgb3i_free_big_mem(ddp);
+ }
+}
+
+/**
+ * ddp_init - initialize the cxgb3 adapter's ddp resource
+ * @tdev: t3cdev adapter
+ * initialize the ddp pagepod manager for a given adapter
+ */
+static void ddp_init(struct t3cdev *tdev)
{
struct cxgb3i_ddp_info *ddp;
struct ulp_iscsi_info uinfo;
unsigned int ppmax, bits;
int i, err;
- static int vers_printed;
- if (!vers_printed) {
- printk(KERN_INFO "%s", version);
- vers_printed = 1;
+ if (tdev->ulp_iscsi) {
+ ddp_log_warn("t3dev 0x%p, ddp 0x%p already set up.\n",
+ tdev, tdev->ulp_iscsi);
+ return;
}
err = tdev->ctl(tdev, ULP_ISCSI_GET_PARAMS, &uinfo);
if (err < 0) {
ddp_log_error("%s, failed to get iscsi param err=%d.\n",
tdev->name, err);
- return err;
+ return;
}
ppmax = (uinfo.ulimit - uinfo.llimit + 1) >> PPOD_SIZE_SHIFT;
@@ -598,7 +657,7 @@ static int ddp_init(struct t3cdev *tdev)
if (!ddp) {
ddp_log_warn("%s unable to alloc ddp 0x%d, ddp disabled.\n",
tdev->name, ppmax);
- return 0;
+ return;
}
ddp->gl_map = (struct cxgb3i_gather_list **)(ddp + 1);
ddp->gl_skb = (struct sk_buff **)(((char *)ddp->gl_map) +
@@ -632,142 +691,26 @@ static int ddp_init(struct t3cdev *tdev)
tdev->ulp_iscsi = ddp;
- /* add to the list */
- write_lock(&cxgb3i_ddp_rwlock);
- list_add_tail(&ddp->list, &cxgb3i_ddp_list);
- write_unlock(&cxgb3i_ddp_rwlock);
-
- ddp_log_info("nppods %u (0x%x ~ 0x%x), bits %u, mask 0x%x,0x%x "
- "pkt %u/%u, %u/%u.\n",
- ppmax, ddp->llimit, ddp->ulimit, ddp->idx_bits,
- ddp->idx_mask, ddp->rsvd_tag_mask,
- ddp->max_txsz, uinfo.max_txsz,
+ ddp_log_info("tdev 0x%p, nppods %u, bits %u, mask 0x%x,0x%x pkt %u/%u,"
+ " %u/%u.\n",
+ tdev, ppmax, ddp->idx_bits, ddp->idx_mask,
+ ddp->rsvd_tag_mask, ddp->max_txsz, uinfo.max_txsz,
ddp->max_rxsz, uinfo.max_rxsz);
- return 0;
+ return;
free_ddp_map:
cxgb3i_free_big_mem(ddp);
- return err;
-}
-
-/**
- * cxgb3i_adapter_ddp_init - initialize the adapter's ddp resource
- * @tdev: t3cdev adapter
- * @tformat: tag format
- * @txsz: max tx pdu payload size, filled in by this func.
- * @rxsz: max rx pdu payload size, filled in by this func.
- * initialize the ddp pagepod manager for a given adapter if needed and
- * setup the tag format for a given iscsi entity
- */
-int cxgb3i_adapter_ddp_init(struct t3cdev *tdev,
- struct cxgb3i_tag_format *tformat,
- unsigned int *txsz, unsigned int *rxsz)
-{
- struct cxgb3i_ddp_info *ddp;
- unsigned char idx_bits;
-
- if (!tformat)
- return -EINVAL;
-
- if (!tdev->ulp_iscsi) {
- int err = ddp_init(tdev);
- if (err < 0)
- return err;
- }
- ddp = (struct cxgb3i_ddp_info *)tdev->ulp_iscsi;
-
- idx_bits = 32 - tformat->sw_bits;
- tformat->rsvd_bits = ddp->idx_bits;
- tformat->rsvd_shift = PPOD_IDX_SHIFT;
- tformat->rsvd_mask = (1 << tformat->rsvd_bits) - 1;
-
- ddp_log_info("tag format: sw %u, rsvd %u,%u, mask 0x%x.\n",
- tformat->sw_bits, tformat->rsvd_bits,
- tformat->rsvd_shift, tformat->rsvd_mask);
-
- *txsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- ddp->max_txsz - ISCSI_PDU_NONPAYLOAD_LEN);
- *rxsz = min_t(unsigned int, ULP2_MAX_PDU_PAYLOAD,
- ddp->max_rxsz - ISCSI_PDU_NONPAYLOAD_LEN);
- ddp_log_info("max payload size: %u/%u, %u/%u.\n",
- *txsz, ddp->max_txsz, *rxsz, ddp->max_rxsz);
- return 0;
-}
-EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_init);
-
-static void ddp_release(struct cxgb3i_ddp_info *ddp)
-{
- int i = 0;
- struct t3cdev *tdev = ddp->tdev;
-
- tdev->ulp_iscsi = NULL;
- while (i < ddp->nppods) {
- struct cxgb3i_gather_list *gl = ddp->gl_map[i];
- if (gl) {
- int npods = (gl->nelem + PPOD_PAGES_MAX - 1)
- >> PPOD_PAGES_SHIFT;
-
- kfree(gl);
- ddp_free_gl_skb(ddp, i, npods);
- } else
- i++;
- }
- cxgb3i_free_big_mem(ddp);
-}
-
-/**
- * cxgb3i_adapter_ddp_cleanup - release the adapter's ddp resource
- * @tdev: t3cdev adapter
- * release all the resource held by the ddp pagepod manager for a given
- * adapter if needed
- */
-void cxgb3i_adapter_ddp_cleanup(struct t3cdev *tdev)
-{
- struct cxgb3i_ddp_info *ddp;
-
- /* remove from the list */
- write_lock(&cxgb3i_ddp_rwlock);
- list_for_each_entry(ddp, &cxgb3i_ddp_list, list) {
- if (ddp->tdev == tdev) {
- list_del(&ddp->list);
- break;
- }
- }
- write_unlock(&cxgb3i_ddp_rwlock);
-
- if (ddp)
- ddp_release(ddp);
-}
-EXPORT_SYMBOL_GPL(cxgb3i_adapter_ddp_cleanup);
-
-/**
- * cxgb3i_ddp_init_module - module init entry point
- * initialize any driver wide global data structures
- */
-static int __init cxgb3i_ddp_init_module(void)
-{
- page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
- ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
- PAGE_SIZE, page_idx);
- return 0;
}
/**
- * cxgb3i_ddp_exit_module - module cleanup/exit entry point
- * go through the ddp list and release any resource held.
+ * cxgb3i_ddp_init - initialize ddp functions
*/
-static void __exit cxgb3i_ddp_exit_module(void)
+void cxgb3i_ddp_init(struct t3cdev *tdev)
{
- struct cxgb3i_ddp_info *ddp;
-
- /* release all ddp manager if there is any */
- write_lock(&cxgb3i_ddp_rwlock);
- list_for_each_entry(ddp, &cxgb3i_ddp_list, list) {
- list_del(&ddp->list);
- ddp_release(ddp);
+ if (page_idx == DDP_PGIDX_MAX) {
+ page_idx = cxgb3i_ddp_find_page_index(PAGE_SIZE);
+ ddp_log_info("system PAGE_SIZE %lu, ddp idx %u.\n",
+ PAGE_SIZE, page_idx);
}
- write_unlock(&cxgb3i_ddp_rwlock);
+ ddp_init(tdev);
}
-
-module_init(cxgb3i_ddp_init_module);
-module_exit(cxgb3i_ddp_exit_module);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_ddp.h b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
index 75a63a81e87..0d296de7cf3 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_ddp.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_ddp.h
@@ -301,7 +301,9 @@ int cxgb3i_setup_conn_pagesize(struct t3cdev *, unsigned int tid, int reply,
int cxgb3i_setup_conn_digest(struct t3cdev *, unsigned int tid,
int hcrc, int dcrc, int reply);
int cxgb3i_ddp_find_page_index(unsigned long pgsz);
-int cxgb3i_adapter_ddp_init(struct t3cdev *, struct cxgb3i_tag_format *,
+int cxgb3i_adapter_ddp_info(struct t3cdev *, struct cxgb3i_tag_format *,
unsigned int *txsz, unsigned int *rxsz);
-void cxgb3i_adapter_ddp_cleanup(struct t3cdev *);
+
+void cxgb3i_ddp_init(struct t3cdev *);
+void cxgb3i_ddp_cleanup(struct t3cdev *);
#endif
diff --git a/drivers/scsi/cxgb3i/cxgb3i_init.c b/drivers/scsi/cxgb3i/cxgb3i_init.c
index 1ce9f244e46..042d9bce991 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_init.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_init.c
@@ -12,8 +12,8 @@
#include "cxgb3i.h"
#define DRV_MODULE_NAME "cxgb3i"
-#define DRV_MODULE_VERSION "1.0.1"
-#define DRV_MODULE_RELDATE "Jan. 2009"
+#define DRV_MODULE_VERSION "1.0.2"
+#define DRV_MODULE_RELDATE "Mar. 2009"
static char version[] =
"Chelsio S3xx iSCSI Driver " DRV_MODULE_NAME
@@ -26,6 +26,7 @@ MODULE_VERSION(DRV_MODULE_VERSION);
static void open_s3_dev(struct t3cdev *);
static void close_s3_dev(struct t3cdev *);
+static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error);
static cxgb3_cpl_handler_func cxgb3i_cpl_handlers[NUM_CPL_CMDS];
static struct cxgb3_client t3c_client = {
@@ -33,6 +34,7 @@ static struct cxgb3_client t3c_client = {
.handlers = cxgb3i_cpl_handlers,
.add = open_s3_dev,
.remove = close_s3_dev,
+ .err_handler = s3_err_handler,
};
/**
@@ -48,8 +50,9 @@ static void open_s3_dev(struct t3cdev *t3dev)
vers_printed = 1;
}
+ cxgb3i_ddp_init(t3dev);
cxgb3i_sdev_add(t3dev, &t3c_client);
- cxgb3i_adapter_add(t3dev);
+ cxgb3i_adapter_open(t3dev);
}
/**
@@ -58,8 +61,28 @@ static void open_s3_dev(struct t3cdev *t3dev)
*/
static void close_s3_dev(struct t3cdev *t3dev)
{
- cxgb3i_adapter_remove(t3dev);
+ cxgb3i_adapter_close(t3dev);
cxgb3i_sdev_remove(t3dev);
+ cxgb3i_ddp_cleanup(t3dev);
+}
+
+static void s3_err_handler(struct t3cdev *tdev, u32 status, u32 error)
+{
+ struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(tdev);
+
+ cxgb3i_log_info("snic 0x%p, tdev 0x%p, status 0x%x, err 0x%x.\n",
+ snic, tdev, status, error);
+ if (!snic)
+ return;
+
+ switch (status) {
+ case OFFLOAD_STATUS_DOWN:
+ snic->flags |= CXGB3I_ADAPTER_FLAG_RESET;
+ break;
+ case OFFLOAD_STATUS_UP:
+ snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
+ break;
+ }
}
/**
diff --git a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
index e185dedc4c1..fff8e432764 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_iscsi.c
@@ -53,36 +53,52 @@ static LIST_HEAD(cxgb3i_snic_list);
static DEFINE_RWLOCK(cxgb3i_snic_rwlock);
/**
- * cxgb3i_adapter_add - init a s3 adapter structure and any h/w settings
- * @t3dev: t3cdev adapter
- * return the resulting cxgb3i_adapter struct
+ * cxgb3i_adpater_find_by_tdev - find the cxgb3i_adapter structure via t3cdev
+ * @tdev: t3cdev pointer
*/
-struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *t3dev)
+struct cxgb3i_adapter *cxgb3i_adapter_find_by_tdev(struct t3cdev *tdev)
{
struct cxgb3i_adapter *snic;
- struct adapter *adapter = tdev2adap(t3dev);
- int i;
- snic = kzalloc(sizeof(*snic), GFP_KERNEL);
- if (!snic) {
- cxgb3i_api_debug("cxgb3 %s, OOM.\n", t3dev->name);
- return NULL;
+ read_lock(&cxgb3i_snic_rwlock);
+ list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
+ if (snic->tdev == tdev) {
+ read_unlock(&cxgb3i_snic_rwlock);
+ return snic;
+ }
}
- spin_lock_init(&snic->lock);
+ read_unlock(&cxgb3i_snic_rwlock);
+ return NULL;
+}
+
+static inline int adapter_update(struct cxgb3i_adapter *snic)
+{
+ cxgb3i_log_info("snic 0x%p, t3dev 0x%p, updating.\n",
+ snic, snic->tdev);
+ return cxgb3i_adapter_ddp_info(snic->tdev, &snic->tag_format,
+ &snic->tx_max_size,
+ &snic->rx_max_size);
+}
+
+static int adapter_add(struct cxgb3i_adapter *snic)
+{
+ struct t3cdev *t3dev = snic->tdev;
+ struct adapter *adapter = tdev2adap(t3dev);
+ int i, err;
- snic->tdev = t3dev;
snic->pdev = adapter->pdev;
snic->tag_format.sw_bits = sw_tag_idx_bits + sw_tag_age_bits;
- if (cxgb3i_adapter_ddp_init(t3dev, &snic->tag_format,
+ err = cxgb3i_adapter_ddp_info(t3dev, &snic->tag_format,
&snic->tx_max_size,
- &snic->rx_max_size) < 0)
- goto free_snic;
+ &snic->rx_max_size);
+ if (err < 0)
+ return err;
for_each_port(adapter, i) {
snic->hba[i] = cxgb3i_hba_host_add(snic, adapter->port[i]);
if (!snic->hba[i])
- goto ulp_cleanup;
+ return -EINVAL;
}
snic->hba_cnt = adapter->params.nports;
@@ -91,46 +107,71 @@ struct cxgb3i_adapter *cxgb3i_adapter_add(struct t3cdev *t3dev)
list_add_tail(&snic->list_head, &cxgb3i_snic_list);
write_unlock(&cxgb3i_snic_rwlock);
- return snic;
+ cxgb3i_log_info("t3dev 0x%p open, snic 0x%p, %u scsi hosts added.\n",
+ t3dev, snic, snic->hba_cnt);
+ return 0;
+}
-ulp_cleanup:
- cxgb3i_adapter_ddp_cleanup(t3dev);
-free_snic:
- kfree(snic);
- return NULL;
+/**
+ * cxgb3i_adapter_open - init a s3 adapter structure and any h/w settings
+ * @t3dev: t3cdev adapter
+ */
+void cxgb3i_adapter_open(struct t3cdev *t3dev)
+{
+ struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
+ int err;
+
+ if (snic)
+ err = adapter_update(snic);
+ else {
+ snic = kzalloc(sizeof(*snic), GFP_KERNEL);
+ if (snic) {
+ spin_lock_init(&snic->lock);
+ snic->tdev = t3dev;
+ err = adapter_add(snic);
+ } else
+ err = -ENOMEM;
+ }
+
+ if (err < 0) {
+ cxgb3i_log_info("snic 0x%p, f 0x%x, t3dev 0x%p open, err %d.\n",
+ snic, snic ? snic->flags : 0, t3dev, err);
+ if (snic) {
+ snic->flags &= ~CXGB3I_ADAPTER_FLAG_RESET;
+ cxgb3i_adapter_close(t3dev);
+ }
+ }
}
/**
- * cxgb3i_adapter_remove - release the resources held and cleanup h/w settings
+ * cxgb3i_adapter_close - release the resources held and cleanup h/w settings
* @t3dev: t3cdev adapter
*/
-void cxgb3i_adapter_remove(struct t3cdev *t3dev)
+void cxgb3i_adapter_close(struct t3cdev *t3dev)
{
+ struct cxgb3i_adapter *snic = cxgb3i_adapter_find_by_tdev(t3dev);
int i;
- struct cxgb3i_adapter *snic;
+
+ if (!snic || snic->flags & CXGB3I_ADAPTER_FLAG_RESET) {
+ cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, f 0x%x.\n",
+ t3dev, snic, snic ? snic->flags : 0);
+ return;
+ }
/* remove from the list */
write_lock(&cxgb3i_snic_rwlock);
- list_for_each_entry(snic, &cxgb3i_snic_list, list_head) {
- if (snic->tdev == t3dev) {
- list_del(&snic->list_head);
- break;
- }
- }
+ list_del(&snic->list_head);
write_unlock(&cxgb3i_snic_rwlock);
- if (snic) {
- for (i = 0; i < snic->hba_cnt; i++) {
- if (snic->hba[i]) {
- cxgb3i_hba_host_remove(snic->hba[i]);
- snic->hba[i] = NULL;
- }
+ for (i = 0; i < snic->hba_cnt; i++) {
+ if (snic->hba[i]) {
+ cxgb3i_hba_host_remove(snic->hba[i]);
+ snic->hba[i] = NULL;
}
-
- /* release ddp resources */
- cxgb3i_adapter_ddp_cleanup(snic->tdev);
- kfree(snic);
}
+ cxgb3i_log_info("t3dev 0x%p close, snic 0x%p, %u scsi hosts removed.\n",
+ t3dev, snic, snic->hba_cnt);
+ kfree(snic);
}
/**
@@ -170,7 +211,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
shost = iscsi_host_alloc(&cxgb3i_host_template,
sizeof(struct cxgb3i_hba), 1);
if (!shost) {
- cxgb3i_log_info("iscsi_host_alloc failed.\n");
+ cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_alloc failed.\n",
+ snic, ndev);
return NULL;
}
@@ -188,7 +230,8 @@ struct cxgb3i_hba *cxgb3i_hba_host_add(struct cxgb3i_adapter *snic,
pci_dev_get(snic->pdev);
err = iscsi_host_add(shost, &snic->pdev->dev);
if (err) {
- cxgb3i_log_info("iscsi_host_add failed.\n");
+ cxgb3i_log_info("snic 0x%p, ndev 0x%p, host_add failed.\n",
+ snic, ndev);
goto pci_dev_put;
}
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.c b/drivers/scsi/cxgb3i/cxgb3i_offload.c
index c2e434e54e2..4d8654cdbda 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.c
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.c
@@ -94,29 +94,30 @@ static int c3cn_get_port(struct s3_conn *c3cn, struct cxgb3i_sdev_data *cdata)
if (!cdata)
goto error_out;
- if (c3cn->saddr.sin_port != 0) {
- idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;
- if (idx < 0 || idx >= cxgb3_max_connect)
- return 0;
- if (!test_and_set_bit(idx, cdata->sport_map))
- return -EADDRINUSE;
+ if (c3cn->saddr.sin_port) {
+ cxgb3i_log_error("connect, sin_port NON-ZERO %u.\n",
+ c3cn->saddr.sin_port);
+ return -EADDRINUSE;
}
- /* the sport_map_next may not be accurate but that is okay, sport_map
- should be */
- start = idx = cdata->sport_map_next;
+ spin_lock_bh(&cdata->lock);
+ start = idx = cdata->sport_next;
do {
if (++idx >= cxgb3_max_connect)
idx = 0;
- if (!(test_and_set_bit(idx, cdata->sport_map))) {
+ if (!cdata->sport_conn[idx]) {
c3cn->saddr.sin_port = htons(cxgb3_sport_base + idx);
- cdata->sport_map_next = idx;
+ cdata->sport_next = idx;
+ cdata->sport_conn[idx] = c3cn;
+ spin_unlock_bh(&cdata->lock);
+
c3cn_conn_debug("%s reserve port %u.\n",
cdata->cdev->name,
cxgb3_sport_base + idx);
return 0;
}
} while (idx != start);
+ spin_unlock_bh(&cdata->lock);
error_out:
return -EADDRNOTAVAIL;
@@ -124,15 +125,19 @@ error_out:
static void c3cn_put_port(struct s3_conn *c3cn)
{
- struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
+ if (!c3cn->cdev)
+ return;
if (c3cn->saddr.sin_port) {
+ struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(c3cn->cdev);
int idx = ntohs(c3cn->saddr.sin_port) - cxgb3_sport_base;
c3cn->saddr.sin_port = 0;
if (idx < 0 || idx >= cxgb3_max_connect)
return;
- clear_bit(idx, cdata->sport_map);
+ spin_lock_bh(&cdata->lock);
+ cdata->sport_conn[idx] = NULL;
+ spin_unlock_bh(&cdata->lock);
c3cn_conn_debug("%s, release port %u.\n",
cdata->cdev->name, cxgb3_sport_base + idx);
}
@@ -1305,11 +1310,7 @@ static void c3cn_release_offload_resources(struct s3_conn *c3cn)
struct t3cdev *cdev = c3cn->cdev;
unsigned int tid = c3cn->tid;
- if (!cdev)
- return;
-
c3cn->qset = 0;
-
c3cn_free_cpl_skbs(c3cn);
if (c3cn->wr_avail != c3cn->wr_max) {
@@ -1317,18 +1318,22 @@ static void c3cn_release_offload_resources(struct s3_conn *c3cn)
reset_wr_list(c3cn);
}
- if (c3cn->l2t) {
- l2t_release(L2DATA(cdev), c3cn->l2t);
- c3cn->l2t = NULL;
- }
-
- if (c3cn->state == C3CN_STATE_CONNECTING) /* we have ATID */
- s3_free_atid(cdev, tid);
- else { /* we have TID */
- cxgb3_remove_tid(cdev, (void *)c3cn, tid);
- c3cn_put(c3cn);
+ if (cdev) {
+ if (c3cn->l2t) {
+ l2t_release(L2DATA(cdev), c3cn->l2t);
+ c3cn->l2t = NULL;
+ }
+ if (c3cn->state == C3CN_STATE_CONNECTING)
+ /* we have ATID */
+ s3_free_atid(cdev, tid);
+ else {
+ /* we have TID */
+ cxgb3_remove_tid(cdev, (void *)c3cn, tid);
+ c3cn_put(c3cn);
+ }
}
+ c3cn->dst_cache = NULL;
c3cn->cdev = NULL;
}
@@ -1417,17 +1422,18 @@ static void c3cn_active_close(struct s3_conn *c3cn)
}
/**
- * cxgb3i_c3cn_release - close and release an iscsi tcp connection
+ * cxgb3i_c3cn_release - close and release an iscsi tcp connection and any
+ * resource held
* @c3cn: the iscsi tcp connection
*/
void cxgb3i_c3cn_release(struct s3_conn *c3cn)
{
c3cn_conn_debug("c3cn 0x%p, s %u, f 0x%lx.\n",
c3cn, c3cn->state, c3cn->flags);
- if (likely(c3cn->state != C3CN_STATE_CONNECTING))
- c3cn_active_close(c3cn);
- else
+ if (unlikely(c3cn->state == C3CN_STATE_CONNECTING))
c3cn_set_flag(c3cn, C3CN_ACTIVE_CLOSE_NEEDED);
+ else if (likely(c3cn->state != C3CN_STATE_CLOSED))
+ c3cn_active_close(c3cn);
c3cn_put(c3cn);
}
@@ -1656,7 +1662,6 @@ int cxgb3i_c3cn_connect(struct s3_conn *c3cn, struct sockaddr_in *usin)
c3cn_set_state(c3cn, C3CN_STATE_CLOSED);
ip_rt_put(rt);
c3cn_put_port(c3cn);
- c3cn->daddr.sin_port = 0;
return err;
}
@@ -1776,10 +1781,25 @@ out_err:
static void sdev_data_cleanup(struct cxgb3i_sdev_data *cdata)
{
struct adap_ports *ports = &cdata->ports;
+ struct s3_conn *c3cn;
int i;
+ for (i = 0; i < cxgb3_max_connect; i++) {
+ if (cdata->sport_conn[i]) {
+ c3cn = cdata->sport_conn[i];
+ cdata->sport_conn[i] = NULL;
+
+ spin_lock_bh(&c3cn->lock);
+ c3cn->cdev = NULL;
+ c3cn_set_flag(c3cn, C3CN_OFFLOAD_DOWN);
+ c3cn_closed(c3cn);
+ spin_unlock_bh(&c3cn->lock);
+ }
+ }
+
for (i = 0; i < ports->nports; i++)
NDEV2CDATA(ports->lldevs[i]) = NULL;
+
cxgb3i_free_big_mem(cdata);
}
@@ -1821,21 +1841,27 @@ void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
struct cxgb3i_sdev_data *cdata;
struct ofld_page_info rx_page_info;
unsigned int wr_len;
- int mapsize = DIV_ROUND_UP(cxgb3_max_connect,
- 8 * sizeof(unsigned long));
+ int mapsize = cxgb3_max_connect * sizeof(struct s3_conn *);
int i;
cdata = cxgb3i_alloc_big_mem(sizeof(*cdata) + mapsize, GFP_KERNEL);
- if (!cdata)
+ if (!cdata) {
+ cxgb3i_log_warn("t3dev 0x%p, offload up, OOM %d.\n",
+ cdev, mapsize);
return;
+ }
if (cdev->ctl(cdev, GET_WR_LEN, &wr_len) < 0 ||
cdev->ctl(cdev, GET_PORTS, &cdata->ports) < 0 ||
- cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0)
+ cdev->ctl(cdev, GET_RX_PAGE_INFO, &rx_page_info) < 0) {
+ cxgb3i_log_warn("t3dev 0x%p, offload up, ioctl failed.\n",
+ cdev);
goto free_cdata;
+ }
s3_init_wr_tab(wr_len);
+ spin_lock_init(&cdata->lock);
INIT_LIST_HEAD(&cdata->list);
cdata->cdev = cdev;
cdata->client = client;
@@ -1847,6 +1873,7 @@ void cxgb3i_sdev_add(struct t3cdev *cdev, struct cxgb3_client *client)
list_add_tail(&cdata->list, &cdata_list);
write_unlock(&cdata_rwlock);
+ cxgb3i_log_info("t3dev 0x%p, offload up, added.\n", cdev);
return;
free_cdata:
@@ -1861,6 +1888,8 @@ void cxgb3i_sdev_remove(struct t3cdev *cdev)
{
struct cxgb3i_sdev_data *cdata = CXGB3_SDEV_DATA(cdev);
+ cxgb3i_log_info("t3dev 0x%p, offload down, remove.\n", cdev);
+
write_lock(&cdata_rwlock);
list_del(&cdata->list);
write_unlock(&cdata_rwlock);
diff --git a/drivers/scsi/cxgb3i/cxgb3i_offload.h b/drivers/scsi/cxgb3i/cxgb3i_offload.h
index 275f23f16eb..ebfca960c0a 100644
--- a/drivers/scsi/cxgb3i/cxgb3i_offload.h
+++ b/drivers/scsi/cxgb3i/cxgb3i_offload.h
@@ -16,7 +16,7 @@
#define _CXGB3I_OFFLOAD_H
#include <linux/skbuff.h>
-#include <net/tcp.h>
+#include <linux/in.h>
#include "common.h"
#include "adapter.h"
@@ -135,11 +135,11 @@ enum c3cn_flags {
C3CN_ABORT_RPL_PENDING, /* expecting an abort reply */
C3CN_TX_DATA_SENT, /* already sent a TX_DATA WR */
C3CN_ACTIVE_CLOSE_NEEDED, /* need to be closed */
+ C3CN_OFFLOAD_DOWN /* offload function off */
};
/**
* cxgb3i_sdev_data - Per adapter data.
- *
* Linked off of each Ethernet device port on the adapter.
* Also available via the t3cdev structure since we have pointers to our port
* net_device's there ...
@@ -148,16 +148,17 @@ enum c3cn_flags {
* @cdev: t3cdev adapter
* @client: CPL client pointer
* @ports: array of adapter ports
- * @sport_map_next: next index into the port map
- * @sport_map: source port map
+ * @sport_next: next port
+ * @sport_conn: source port connection
*/
struct cxgb3i_sdev_data {
struct list_head list;
struct t3cdev *cdev;
struct cxgb3_client *client;
struct adap_ports ports;
- unsigned int sport_map_next;
- unsigned long sport_map[0];
+ spinlock_t lock;
+ unsigned int sport_next;
+ struct s3_conn *sport_conn[0];
};
#define NDEV2CDATA(ndev) (*(struct cxgb3i_sdev_data **)&(ndev)->ec_ptr)
#define CXGB3_SDEV_DATA(cdev) NDEV2CDATA((cdev)->lldev)
diff --git a/drivers/scsi/fcoe/Makefile b/drivers/scsi/fcoe/Makefile
index b78da06d7c0..950f27615c7 100644
--- a/drivers/scsi/fcoe/Makefile
+++ b/drivers/scsi/fcoe/Makefile
@@ -1,8 +1,2 @@
-# $Id: Makefile
-
obj-$(CONFIG_FCOE) += fcoe.o
-
-fcoe-y := \
- libfcoe.o \
- fcoe_sw.o \
- fc_transport_fcoe.o
+obj-$(CONFIG_LIBFCOE) += libfcoe.o
diff --git a/drivers/scsi/fcoe/fc_transport_fcoe.c b/drivers/scsi/fcoe/fc_transport_fcoe.c
deleted file mode 100644
index 8862758006c..00000000000
--- a/drivers/scsi/fcoe/fc_transport_fcoe.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#include <linux/pci.h>
-#include <scsi/libfcoe.h>
-#include <scsi/fc_transport_fcoe.h>
-
-/* internal fcoe transport */
-struct fcoe_transport_internal {
- struct fcoe_transport *t;
- struct net_device *netdev;
- struct list_head list;
-};
-
-/* fcoe transports list and its lock */
-static LIST_HEAD(fcoe_transports);
-static DEFINE_MUTEX(fcoe_transports_lock);
-
-/**
- * fcoe_transport_default() - Returns ptr to the default transport fcoe_sw
- */
-struct fcoe_transport *fcoe_transport_default(void)
-{
- return &fcoe_sw_transport;
-}
-
-/**
- * fcoe_transport_to_pcidev() - get the pci dev from a netdev
- * @netdev: the netdev that pci dev will be retrived from
- *
- * Returns: NULL or the corrsponding pci_dev
- */
-struct pci_dev *fcoe_transport_pcidev(const struct net_device *netdev)
-{
- if (!netdev->dev.parent)
- return NULL;
- return to_pci_dev(netdev->dev.parent);
-}
-
-/**
- * fcoe_transport_device_lookup() - Lookup a transport
- * @netdev: the netdev the transport to be attached to
- *
- * This will look for existing offload driver, if not found, it falls back to
- * the default sw hba (fcoe_sw) as its fcoe transport.
- *
- * Returns: 0 for success
- */
-static struct fcoe_transport_internal *
-fcoe_transport_device_lookup(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- struct fcoe_transport_internal *ti;
-
- /* assign the transpor to this device */
- mutex_lock(&t->devlock);
- list_for_each_entry(ti, &t->devlist, list) {
- if (ti->netdev == netdev) {
- mutex_unlock(&t->devlock);
- return ti;
- }
- }
- mutex_unlock(&t->devlock);
- return NULL;
-}
-/**
- * fcoe_transport_device_add() - Assign a transport to a device
- * @netdev: the netdev the transport to be attached to
- *
- * This will look for existing offload driver, if not found, it falls back to
- * the default sw hba (fcoe_sw) as its fcoe transport.
- *
- * Returns: 0 for success
- */
-static int fcoe_transport_device_add(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- struct fcoe_transport_internal *ti;
-
- ti = fcoe_transport_device_lookup(t, netdev);
- if (ti) {
- printk(KERN_DEBUG "fcoe_transport_device_add:"
- "device %s is already added to transport %s\n",
- netdev->name, t->name);
- return -EEXIST;
- }
- /* allocate an internal struct to host the netdev and the list */
- ti = kzalloc(sizeof(*ti), GFP_KERNEL);
- if (!ti)
- return -ENOMEM;
-
- ti->t = t;
- ti->netdev = netdev;
- INIT_LIST_HEAD(&ti->list);
- dev_hold(ti->netdev);
-
- mutex_lock(&t->devlock);
- list_add(&ti->list, &t->devlist);
- mutex_unlock(&t->devlock);
-
- printk(KERN_DEBUG "fcoe_transport_device_add:"
- "device %s added to transport %s\n",
- netdev->name, t->name);
-
- return 0;
-}
-
-/**
- * fcoe_transport_device_remove() - Remove a device from its transport
- * @netdev: the netdev the transport to be attached to
- *
- * This removes the device from the transport so the given transport will
- * not manage this device any more
- *
- * Returns: 0 for success
- */
-static int fcoe_transport_device_remove(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- struct fcoe_transport_internal *ti;
-
- ti = fcoe_transport_device_lookup(t, netdev);
- if (!ti) {
- printk(KERN_DEBUG "fcoe_transport_device_remove:"
- "device %s is not managed by transport %s\n",
- netdev->name, t->name);
- return -ENODEV;
- }
- mutex_lock(&t->devlock);
- list_del(&ti->list);
- mutex_unlock(&t->devlock);
- printk(KERN_DEBUG "fcoe_transport_device_remove:"
- "device %s removed from transport %s\n",
- netdev->name, t->name);
- dev_put(ti->netdev);
- kfree(ti);
- return 0;
-}
-
-/**
- * fcoe_transport_device_remove_all() - Remove all from transport devlist
- *
- * This removes the device from the transport so the given transport will
- * not manage this device any more
- *
- * Returns: 0 for success
- */
-static void fcoe_transport_device_remove_all(struct fcoe_transport *t)
-{
- struct fcoe_transport_internal *ti, *tmp;
-
- mutex_lock(&t->devlock);
- list_for_each_entry_safe(ti, tmp, &t->devlist, list) {
- list_del(&ti->list);
- kfree(ti);
- }
- mutex_unlock(&t->devlock);
-}
-
-/**
- * fcoe_transport_match() - Use the bus device match function to match the hw
- * @t: The fcoe transport to check
- * @netdev: The netdev to match against
- *
- * This function is used to check if the given transport wants to manage the
- * input netdev. if the transports implements the match function, it will be
- * called, o.w. we just compare the pci vendor and device id.
- *
- * Returns: true for match up
- */
-static bool fcoe_transport_match(struct fcoe_transport *t,
- struct net_device *netdev)
-{
- /* match transport by vendor and device id */
- struct pci_dev *pci;
-
- pci = fcoe_transport_pcidev(netdev);
-
- if (pci) {
- printk(KERN_DEBUG "fcoe_transport_match:"
- "%s:%x:%x -- %s:%x:%x\n",
- t->name, t->vendor, t->device,
- netdev->name, pci->vendor, pci->device);
-
- /* if transport supports match */
- if (t->match)
- return t->match(netdev);
-
- /* else just compare the vendor and device id: pci only */
- return (t->vendor == pci->vendor) && (t->device == pci->device);
- }
- return false;
-}
-
-/**
- * fcoe_transport_lookup() - Check if the transport is already registered
- * @t: the transport to be looked up
- *
- * This compares the parent device (pci) vendor and device id
- *
- * Returns: NULL if not found
- *
- * TODO: return default sw transport if no other transport is found
- */
-static struct fcoe_transport *
-fcoe_transport_lookup(struct net_device *netdev)
-{
- struct fcoe_transport *t;
-
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry(t, &fcoe_transports, list) {
- if (fcoe_transport_match(t, netdev)) {
- mutex_unlock(&fcoe_transports_lock);
- return t;
- }
- }
- mutex_unlock(&fcoe_transports_lock);
-
- printk(KERN_DEBUG "fcoe_transport_lookup:"
- "use default transport for %s\n", netdev->name);
- return fcoe_transport_default();
-}
-
-/**
- * fcoe_transport_register() - Adds a fcoe transport to the fcoe transports list
- * @t: ptr to the fcoe transport to be added
- *
- * Returns: 0 for success
- */
-int fcoe_transport_register(struct fcoe_transport *t)
-{
- struct fcoe_transport *tt;
-
- /* TODO - add fcoe_transport specific initialization here */
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry(tt, &fcoe_transports, list) {
- if (tt == t) {
- mutex_unlock(&fcoe_transports_lock);
- return -EEXIST;
- }
- }
- list_add_tail(&t->list, &fcoe_transports);
- mutex_unlock(&fcoe_transports_lock);
-
- printk(KERN_DEBUG "fcoe_transport_register:%s\n", t->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_register);
-
-/**
- * fcoe_transport_unregister() - Remove the tranport fro the fcoe transports list
- * @t: ptr to the fcoe transport to be removed
- *
- * Returns: 0 for success
- */
-int fcoe_transport_unregister(struct fcoe_transport *t)
-{
- struct fcoe_transport *tt, *tmp;
-
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry_safe(tt, tmp, &fcoe_transports, list) {
- if (tt == t) {
- list_del(&t->list);
- mutex_unlock(&fcoe_transports_lock);
- fcoe_transport_device_remove_all(t);
- printk(KERN_DEBUG "fcoe_transport_unregister:%s\n",
- t->name);
- return 0;
- }
- }
- mutex_unlock(&fcoe_transports_lock);
- return -ENODEV;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_unregister);
-
-/**
- * fcoe_load_transport_driver() - Load an offload driver by alias name
- * @netdev: the target net device
- *
- * Requests for an offload driver module as the fcoe transport, if fails, it
- * falls back to use the SW HBA (fcoe_sw) as its transport
- *
- * TODO -
- * 1. supports only PCI device
- * 2. needs fix for VLAn and bonding
- * 3. pure hw fcoe hba may not have netdev
- *
- * Returns: 0 for success
- */
-int fcoe_load_transport_driver(struct net_device *netdev)
-{
- struct pci_dev *pci;
- struct device *dev = netdev->dev.parent;
-
- if (fcoe_transport_lookup(netdev)) {
- /* load default transport */
- printk(KERN_DEBUG "fcoe: already loaded transport for %s\n",
- netdev->name);
- return -EEXIST;
- }
-
- pci = to_pci_dev(dev);
- if (dev->bus != &pci_bus_type) {
- printk(KERN_DEBUG "fcoe: support noly PCI device\n");
- return -ENODEV;
- }
- printk(KERN_DEBUG "fcoe: loading driver fcoe-pci-0x%04x-0x%04x\n",
- pci->vendor, pci->device);
-
- return request_module("fcoe-pci-0x%04x-0x%04x",
- pci->vendor, pci->device);
-
-}
-EXPORT_SYMBOL_GPL(fcoe_load_transport_driver);
-
-/**
- * fcoe_transport_attach() - Load transport to fcoe
- * @netdev: the netdev the transport to be attached to
- *
- * This will look for existing offload driver, if not found, it falls back to
- * the default sw hba (fcoe_sw) as its fcoe transport.
- *
- * Returns: 0 for success
- */
-int fcoe_transport_attach(struct net_device *netdev)
-{
- struct fcoe_transport *t;
-
- /* find the corresponding transport */
- t = fcoe_transport_lookup(netdev);
- if (!t) {
- printk(KERN_DEBUG "fcoe_transport_attach"
- ":no transport for %s:use %s\n",
- netdev->name, t->name);
- return -ENODEV;
- }
- /* add to the transport */
- if (fcoe_transport_device_add(t, netdev)) {
- printk(KERN_DEBUG "fcoe_transport_attach"
- ":failed to add %s to tramsport %s\n",
- netdev->name, t->name);
- return -EIO;
- }
- /* transport create function */
- if (t->create)
- t->create(netdev);
-
- printk(KERN_DEBUG "fcoe_transport_attach:transport %s for %s\n",
- t->name, netdev->name);
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_attach);
-
-/**
- * fcoe_transport_release() - Unload transport from fcoe
- * @netdev: the net device on which fcoe is to be released
- *
- * Returns: 0 for success
- */
-int fcoe_transport_release(struct net_device *netdev)
-{
- struct fcoe_transport *t;
-
- /* find the corresponding transport */
- t = fcoe_transport_lookup(netdev);
- if (!t) {
- printk(KERN_DEBUG "fcoe_transport_release:"
- "no transport for %s:use %s\n",
- netdev->name, t->name);
- return -ENODEV;
- }
- /* remove the device from the transport */
- if (fcoe_transport_device_remove(t, netdev)) {
- printk(KERN_DEBUG "fcoe_transport_release:"
- "failed to add %s to tramsport %s\n",
- netdev->name, t->name);
- return -EIO;
- }
- /* transport destroy function */
- if (t->destroy)
- t->destroy(netdev);
-
- printk(KERN_DEBUG "fcoe_transport_release:"
- "device %s dettached from transport %s\n",
- netdev->name, t->name);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_transport_release);
-
-/**
- * fcoe_transport_init() - Initializes fcoe transport layer
- *
- * This prepares for the fcoe transport layer
- *
- * Returns: none
- */
-int __init fcoe_transport_init(void)
-{
- INIT_LIST_HEAD(&fcoe_transports);
- mutex_init(&fcoe_transports_lock);
- return 0;
-}
-
-/**
- * fcoe_transport_exit() - Cleans up the fcoe transport layer
- *
- * This cleans up the fcoe transport layer. removing any transport on the list,
- * note that the transport destroy func is not called here.
- *
- * Returns: none
- */
-int __exit fcoe_transport_exit(void)
-{
- struct fcoe_transport *t, *tmp;
-
- mutex_lock(&fcoe_transports_lock);
- list_for_each_entry_safe(t, tmp, &fcoe_transports, list) {
- list_del(&t->list);
- mutex_unlock(&fcoe_transports_lock);
- fcoe_transport_device_remove_all(t);
- mutex_lock(&fcoe_transports_lock);
- }
- mutex_unlock(&fcoe_transports_lock);
- return 0;
-}
diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c
new file mode 100644
index 00000000000..94e1e318977
--- /dev/null
+++ b/drivers/scsi/fcoe/fcoe.c
@@ -0,0 +1,1878 @@
+/*
+ * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_ether.h>
+#include <linux/if_vlan.h>
+#include <linux/crc32.h>
+#include <linux/cpu.h>
+#include <linux/fs.h>
+#include <linux/sysfs.h>
+#include <linux/ctype.h>
+#include <scsi/scsi_tcq.h>
+#include <scsi/scsicam.h>
+#include <scsi/scsi_transport.h>
+#include <scsi/scsi_transport_fc.h>
+#include <net/rtnetlink.h>
+
+#include <scsi/fc/fc_encaps.h>
+#include <scsi/fc/fc_fip.h>
+
+#include <scsi/libfc.h>
+#include <scsi/fc_frame.h>
+#include <scsi/libfcoe.h>
+
+#include "fcoe.h"
+
+static int debug_fcoe;
+
+MODULE_AUTHOR("Open-FCoE.org");
+MODULE_DESCRIPTION("FCoE");
+MODULE_LICENSE("GPL v2");
+
+/* fcoe host list */
+LIST_HEAD(fcoe_hostlist);
+DEFINE_RWLOCK(fcoe_hostlist_lock);
+DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
+DEFINE_PER_CPU(struct fcoe_percpu_s, fcoe_percpu);
+
+/* Function Prototyes */
+static int fcoe_reset(struct Scsi_Host *shost);
+static int fcoe_xmit(struct fc_lport *, struct fc_frame *);
+static int fcoe_rcv(struct sk_buff *, struct net_device *,
+ struct packet_type *, struct net_device *);
+static int fcoe_percpu_receive_thread(void *arg);
+static void fcoe_clean_pending_queue(struct fc_lport *lp);
+static void fcoe_percpu_clean(struct fc_lport *lp);
+static int fcoe_link_ok(struct fc_lport *lp);
+
+static struct fc_lport *fcoe_hostlist_lookup(const struct net_device *);
+static int fcoe_hostlist_add(const struct fc_lport *);
+static int fcoe_hostlist_remove(const struct fc_lport *);
+
+static int fcoe_check_wait_queue(struct fc_lport *);
+static int fcoe_device_notification(struct notifier_block *, ulong, void *);
+static void fcoe_dev_setup(void);
+static void fcoe_dev_cleanup(void);
+
+/* notification function from net device */
+static struct notifier_block fcoe_notifier = {
+ .notifier_call = fcoe_device_notification,
+};
+
+static struct scsi_transport_template *scsi_transport_fcoe_sw;
+
+struct fc_function_template fcoe_transport_function = {
+ .show_host_node_name = 1,
+ .show_host_port_name = 1,
+ .show_host_supported_classes = 1,
+ .show_host_supported_fc4s = 1,
+ .show_host_active_fc4s = 1,
+ .show_host_maxframe_size = 1,
+
+ .show_host_port_id = 1,
+ .show_host_supported_speeds = 1,
+ .get_host_speed = fc_get_host_speed,
+ .show_host_speed = 1,
+ .show_host_port_type = 1,
+ .get_host_port_state = fc_get_host_port_state,
+ .show_host_port_state = 1,
+ .show_host_symbolic_name = 1,
+
+ .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
+ .show_rport_maxframe_size = 1,
+ .show_rport_supported_classes = 1,
+
+ .show_host_fabric_name = 1,
+ .show_starget_node_name = 1,
+ .show_starget_port_name = 1,
+ .show_starget_port_id = 1,
+ .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
+ .show_rport_dev_loss_tmo = 1,
+ .get_fc_host_stats = fc_get_host_stats,
+ .issue_fc_host_lip = fcoe_reset,
+
+ .terminate_rport_io = fc_rport_terminate_io,
+};
+
+static struct scsi_host_template fcoe_shost_template = {
+ .module = THIS_MODULE,
+ .name = "FCoE Driver",
+ .proc_name = FCOE_NAME,
+ .queuecommand = fc_queuecommand,
+ .eh_abort_handler = fc_eh_abort,
+ .eh_device_reset_handler = fc_eh_device_reset,
+ .eh_host_reset_handler = fc_eh_host_reset,
+ .slave_alloc = fc_slave_alloc,
+ .change_queue_depth = fc_change_queue_depth,
+ .change_queue_type = fc_change_queue_type,
+ .this_id = -1,
+ .cmd_per_lun = 32,
+ .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
+ .use_clustering = ENABLE_CLUSTERING,
+ .sg_tablesize = SG_ALL,
+ .max_sectors = 0xffff,
+};
+
+/**
+ * fcoe_lport_config() - sets up the fc_lport
+ * @lp: ptr to the fc_lport
+ * @shost: ptr to the parent scsi host
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_lport_config(struct fc_lport *lp)
+{
+ lp->link_up = 0;
+ lp->qfull = 0;
+ lp->max_retry_count = 3;
+ lp->e_d_tov = 2 * 1000; /* FC-FS default */
+ lp->r_a_tov = 2 * 2 * 1000;
+ lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
+ FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
+
+ fc_lport_init_stats(lp);
+
+ /* lport fc_lport related configuration */
+ fc_lport_config(lp);
+
+ /* offload related configuration */
+ lp->crc_offload = 0;
+ lp->seq_offload = 0;
+ lp->lro_enabled = 0;
+ lp->lro_xid = 0;
+ lp->lso_max = 0;
+
+ return 0;
+}
+
+/**
+ * fcoe_netdev_config() - Set up netdev for SW FCoE
+ * @lp : ptr to the fc_lport
+ * @netdev : ptr to the associated netdevice struct
+ *
+ * Must be called after fcoe_lport_config() as it will use lport mutex
+ *
+ * Returns : 0 for success
+ */
+static int fcoe_netdev_config(struct fc_lport *lp, struct net_device *netdev)
+{
+ u32 mfs;
+ u64 wwnn, wwpn;
+ struct fcoe_softc *fc;
+ u8 flogi_maddr[ETH_ALEN];
+
+ /* Setup lport private data to point to fcoe softc */
+ fc = lport_priv(lp);
+ fc->ctlr.lp = lp;
+ fc->real_dev = netdev;
+ fc->phys_dev = netdev;
+
+ /* Require support for get_pauseparam ethtool op. */
+ if (netdev->priv_flags & IFF_802_1Q_VLAN)
+ fc->phys_dev = vlan_dev_real_dev(netdev);
+
+ /* Do not support for bonding device */
+ if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
+ (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
+ (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
+ return -EOPNOTSUPP;
+ }
+
+ /*
+ * Determine max frame size based on underlying device and optional
+ * user-configured limit. If the MFS is too low, fcoe_link_ok()
+ * will return 0, so do this first.
+ */
+ mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
+ sizeof(struct fcoe_crc_eof));
+ if (fc_set_mfs(lp, mfs))
+ return -EINVAL;
+
+ /* offload features support */
+ if (fc->real_dev->features & NETIF_F_SG)
+ lp->sg_supp = 1;
+
+#ifdef NETIF_F_FCOE_CRC
+ if (netdev->features & NETIF_F_FCOE_CRC) {
+ lp->crc_offload = 1;
+ printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
+ netdev->name);
+ }
+#endif
+#ifdef NETIF_F_FSO
+ if (netdev->features & NETIF_F_FSO) {
+ lp->seq_offload = 1;
+ lp->lso_max = netdev->gso_max_size;
+ printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
+ netdev->name, lp->lso_max);
+ }
+#endif
+ if (netdev->fcoe_ddp_xid) {
+ lp->lro_enabled = 1;
+ lp->lro_xid = netdev->fcoe_ddp_xid;
+ printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
+ netdev->name, lp->lro_xid);
+ }
+ skb_queue_head_init(&fc->fcoe_pending_queue);
+ fc->fcoe_pending_queue_active = 0;
+
+ /* setup Source Mac Address */
+ memcpy(fc->ctlr.ctl_src_addr, fc->real_dev->dev_addr,
+ fc->real_dev->addr_len);
+
+ wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
+ fc_set_wwnn(lp, wwnn);
+ /* XXX - 3rd arg needs to be vlan id */
+ wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
+ fc_set_wwpn(lp, wwpn);
+
+ /*
+ * Add FCoE MAC address as second unicast MAC address
+ * or enter promiscuous mode if not capable of listening
+ * for multiple unicast MACs.
+ */
+ rtnl_lock();
+ memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
+ dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
+ rtnl_unlock();
+
+ /*
+ * setup the receive function from ethernet driver
+ * on the ethertype for the given device
+ */
+ fc->fcoe_packet_type.func = fcoe_rcv;
+ fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
+ fc->fcoe_packet_type.dev = fc->real_dev;
+ dev_add_pack(&fc->fcoe_packet_type);
+
+ return 0;
+}
+
+/**
+ * fcoe_shost_config() - Sets up fc_lport->host
+ * @lp : ptr to the fc_lport
+ * @shost : ptr to the associated scsi host
+ * @dev : device associated to scsi host
+ *
+ * Must be called after fcoe_lport_config() and fcoe_netdev_config()
+ *
+ * Returns : 0 for success
+ */
+static int fcoe_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
+ struct device *dev)
+{
+ int rc = 0;
+
+ /* lport scsi host config */
+ lp->host = shost;
+
+ lp->host->max_lun = FCOE_MAX_LUN;
+ lp->host->max_id = FCOE_MAX_FCP_TARGET;
+ lp->host->max_channel = 0;
+ lp->host->transportt = scsi_transport_fcoe_sw;
+
+ /* add the new host to the SCSI-ml */
+ rc = scsi_add_host(lp->host, dev);
+ if (rc) {
+ FC_DBG("fcoe_shost_config:error on scsi_add_host\n");
+ return rc;
+ }
+ sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
+ FCOE_NAME, FCOE_VERSION,
+ fcoe_netdev(lp)->name);
+
+ return 0;
+}
+
+/**
+ * fcoe_em_config() - allocates em for this lport
+ * @lp: the port that em is to allocated for
+ *
+ * Returns : 0 on success
+ */
+static inline int fcoe_em_config(struct fc_lport *lp)
+{
+ BUG_ON(lp->emp);
+
+ lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
+ FCOE_MIN_XID, FCOE_MAX_XID);
+ if (!lp->emp)
+ return -ENOMEM;
+
+ return 0;
+}
+
+/**
+ * fcoe_if_destroy() - FCoE software HBA tear-down function
+ * @netdev: ptr to the associated net_device
+ *
+ * Returns: 0 if link is OK for use by FCoE.
+ */
+static int fcoe_if_destroy(struct net_device *netdev)
+{
+ struct fc_lport *lp = NULL;
+ struct fcoe_softc *fc;
+ u8 flogi_maddr[ETH_ALEN];
+
+ BUG_ON(!netdev);
+
+ printk(KERN_DEBUG "fcoe_if_destroy:interface on %s\n",
+ netdev->name);
+
+ lp = fcoe_hostlist_lookup(netdev);
+ if (!lp)
+ return -ENODEV;
+
+ fc = lport_priv(lp);
+
+ /* Logout of the fabric */
+ fc_fabric_logoff(lp);
+
+ /* Remove the instance from fcoe's list */
+ fcoe_hostlist_remove(lp);
+
+ /* Don't listen for Ethernet packets anymore */
+ dev_remove_pack(&fc->fcoe_packet_type);
+ dev_remove_pack(&fc->fip_packet_type);
+ fcoe_ctlr_destroy(&fc->ctlr);
+
+ /* Cleanup the fc_lport */
+ fc_lport_destroy(lp);
+ fc_fcp_destroy(lp);
+
+ /* Detach from the scsi-ml */
+ fc_remove_host(lp->host);
+ scsi_remove_host(lp->host);
+
+ /* There are no more rports or I/O, free the EM */
+ if (lp->emp)
+ fc_exch_mgr_free(lp->emp);
+
+ /* Delete secondary MAC addresses */
+ rtnl_lock();
+ memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
+ dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
+ if (!is_zero_ether_addr(fc->ctlr.data_src_addr))
+ dev_unicast_delete(fc->real_dev,
+ fc->ctlr.data_src_addr, ETH_ALEN);
+ dev_mc_delete(fc->real_dev, FIP_ALL_ENODE_MACS, ETH_ALEN, 0);
+ rtnl_unlock();
+
+ /* Free the per-CPU revieve threads */
+ fcoe_percpu_clean(lp);
+
+ /* Free existing skbs */
+ fcoe_clean_pending_queue(lp);
+
+ /* Free memory used by statistical counters */
+ fc_lport_free_stats(lp);
+
+ /* Release the net_device and Scsi_Host */
+ dev_put(fc->real_dev);
+ scsi_host_put(lp->host);
+
+ return 0;
+}
+
+/*
+ * fcoe_ddp_setup - calls LLD's ddp_setup through net_device
+ * @lp: the corresponding fc_lport
+ * @xid: the exchange id for this ddp transfer
+ * @sgl: the scatterlist describing this transfer
+ * @sgc: number of sg items
+ *
+ * Returns : 0 no ddp
+ */
+static int fcoe_ddp_setup(struct fc_lport *lp, u16 xid,
+ struct scatterlist *sgl, unsigned int sgc)
+{
+ struct net_device *n = fcoe_netdev(lp);
+
+ if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
+ return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
+
+ return 0;
+}
+
+/*
+ * fcoe_ddp_done - calls LLD's ddp_done through net_device
+ * @lp: the corresponding fc_lport
+ * @xid: the exchange id for this ddp transfer
+ *
+ * Returns : the length of data that have been completed by ddp
+ */
+static int fcoe_ddp_done(struct fc_lport *lp, u16 xid)
+{
+ struct net_device *n = fcoe_netdev(lp);
+
+ if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
+ return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
+ return 0;
+}
+
+static struct libfc_function_template fcoe_libfc_fcn_templ = {
+ .frame_send = fcoe_xmit,
+ .ddp_setup = fcoe_ddp_setup,
+ .ddp_done = fcoe_ddp_done,
+};
+
+/**
+ * fcoe_fip_recv - handle a received FIP frame.
+ * @skb: the receive skb
+ * @dev: associated &net_device
+ * @ptype: the &packet_type structure which was used to register this handler.
+ * @orig_dev: original receive &net_device, in case @dev is a bond.
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_fip_recv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *ptype,
+ struct net_device *orig_dev)
+{
+ struct fcoe_softc *fc;
+
+ fc = container_of(ptype, struct fcoe_softc, fip_packet_type);
+ fcoe_ctlr_recv(&fc->ctlr, skb);
+ return 0;
+}
+
+/**
+ * fcoe_fip_send() - send an Ethernet-encapsulated FIP frame.
+ * @fip: FCoE controller.
+ * @skb: FIP Packet.
+ */
+static void fcoe_fip_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
+{
+ skb->dev = fcoe_from_ctlr(fip)->real_dev;
+ dev_queue_xmit(skb);
+}
+
+/**
+ * fcoe_update_src_mac() - Update Ethernet MAC filters.
+ * @fip: FCoE controller.
+ * @old: Unicast MAC address to delete if the MAC is non-zero.
+ * @new: Unicast MAC address to add.
+ *
+ * Remove any previously-set unicast MAC filter.
+ * Add secondary FCoE MAC address filter for our OUI.
+ */
+static void fcoe_update_src_mac(struct fcoe_ctlr *fip, u8 *old, u8 *new)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_from_ctlr(fip);
+ rtnl_lock();
+ if (!is_zero_ether_addr(old))
+ dev_unicast_delete(fc->real_dev, old, ETH_ALEN);
+ dev_unicast_add(fc->real_dev, new, ETH_ALEN);
+ rtnl_unlock();
+}
+
+/**
+ * fcoe_if_create() - this function creates the fcoe interface
+ * @netdev: pointer the associated netdevice
+ *
+ * Creates fc_lport struct and scsi_host for lport, configures lport
+ * and starts fabric login.
+ *
+ * Returns : 0 on success
+ */
+static int fcoe_if_create(struct net_device *netdev)
+{
+ int rc;
+ struct fc_lport *lp = NULL;
+ struct fcoe_softc *fc;
+ struct Scsi_Host *shost;
+
+ BUG_ON(!netdev);
+
+ printk(KERN_DEBUG "fcoe_if_create:interface on %s\n",
+ netdev->name);
+
+ lp = fcoe_hostlist_lookup(netdev);
+ if (lp)
+ return -EEXIST;
+
+ shost = libfc_host_alloc(&fcoe_shost_template,
+ sizeof(struct fcoe_softc));
+ if (!shost) {
+ FC_DBG("Could not allocate host structure\n");
+ return -ENOMEM;
+ }
+ lp = shost_priv(shost);
+ fc = lport_priv(lp);
+
+ /* configure fc_lport, e.g., em */
+ rc = fcoe_lport_config(lp);
+ if (rc) {
+ FC_DBG("Could not configure lport\n");
+ goto out_host_put;
+ }
+
+ /* configure lport network properties */
+ rc = fcoe_netdev_config(lp, netdev);
+ if (rc) {
+ FC_DBG("Could not configure netdev for lport\n");
+ goto out_host_put;
+ }
+
+ /*
+ * Initialize FIP.
+ */
+ fcoe_ctlr_init(&fc->ctlr);
+ fc->ctlr.send = fcoe_fip_send;
+ fc->ctlr.update_mac = fcoe_update_src_mac;
+
+ fc->fip_packet_type.func = fcoe_fip_recv;
+ fc->fip_packet_type.type = htons(ETH_P_FIP);
+ fc->fip_packet_type.dev = fc->real_dev;
+ dev_add_pack(&fc->fip_packet_type);
+
+ /* configure lport scsi host properties */
+ rc = fcoe_shost_config(lp, shost, &netdev->dev);
+ if (rc) {
+ FC_DBG("Could not configure shost for lport\n");
+ goto out_host_put;
+ }
+
+ /* lport exch manager allocation */
+ rc = fcoe_em_config(lp);
+ if (rc) {
+ FC_DBG("Could not configure em for lport\n");
+ goto out_host_put;
+ }
+
+ /* Initialize the library */
+ rc = fcoe_libfc_config(lp, &fcoe_libfc_fcn_templ);
+ if (rc) {
+ FC_DBG("Could not configure libfc for lport!\n");
+ goto out_lp_destroy;
+ }
+
+ /* add to lports list */
+ fcoe_hostlist_add(lp);
+
+ lp->boot_time = jiffies;
+
+ fc_fabric_login(lp);
+
+ if (!fcoe_link_ok(lp))
+ fcoe_ctlr_link_up(&fc->ctlr);
+
+ dev_hold(netdev);
+
+ return rc;
+
+out_lp_destroy:
+ fc_exch_mgr_free(lp->emp); /* Free the EM */
+out_host_put:
+ scsi_host_put(lp->host);
+ return rc;
+}
+
+/**
+ * fcoe_if_init() - attach to scsi transport
+ *
+ * Returns : 0 on success
+ */
+static int __init fcoe_if_init(void)
+{
+ /* attach to scsi transport */
+ scsi_transport_fcoe_sw =
+ fc_attach_transport(&fcoe_transport_function);
+
+ if (!scsi_transport_fcoe_sw) {
+ printk(KERN_ERR "fcoe_init:fc_attach_transport() failed\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * fcoe_if_exit() - detach from scsi transport
+ *
+ * Returns : 0 on success
+ */
+int __exit fcoe_if_exit(void)
+{
+ fc_release_transport(scsi_transport_fcoe_sw);
+ return 0;
+}
+
+/**
+ * fcoe_percpu_thread_create() - Create a receive thread for an online cpu
+ * @cpu: cpu index for the online cpu
+ */
+static void fcoe_percpu_thread_create(unsigned int cpu)
+{
+ struct fcoe_percpu_s *p;
+ struct task_struct *thread;
+
+ p = &per_cpu(fcoe_percpu, cpu);
+
+ thread = kthread_create(fcoe_percpu_receive_thread,
+ (void *)p, "fcoethread/%d", cpu);
+
+ if (likely(!IS_ERR(p->thread))) {
+ kthread_bind(thread, cpu);
+ wake_up_process(thread);
+
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ p->thread = thread;
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ }
+}
+
+/**
+ * fcoe_percpu_thread_destroy() - removes the rx thread for the given cpu
+ * @cpu: cpu index the rx thread is to be removed
+ *
+ * Destroys a per-CPU Rx thread. Any pending skbs are moved to the
+ * current CPU's Rx thread. If the thread being destroyed is bound to
+ * the CPU processing this context the skbs will be freed.
+ */
+static void fcoe_percpu_thread_destroy(unsigned int cpu)
+{
+ struct fcoe_percpu_s *p;
+ struct task_struct *thread;
+ struct page *crc_eof;
+ struct sk_buff *skb;
+#ifdef CONFIG_SMP
+ struct fcoe_percpu_s *p0;
+ unsigned targ_cpu = smp_processor_id();
+#endif /* CONFIG_SMP */
+
+ printk(KERN_DEBUG "fcoe: Destroying receive thread for CPU %d\n", cpu);
+
+ /* Prevent any new skbs from being queued for this CPU. */
+ p = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ thread = p->thread;
+ p->thread = NULL;
+ crc_eof = p->crc_eof_page;
+ p->crc_eof_page = NULL;
+ p->crc_eof_offset = 0;
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+
+#ifdef CONFIG_SMP
+ /*
+ * Don't bother moving the skb's if this context is running
+ * on the same CPU that is having its thread destroyed. This
+ * can easily happen when the module is removed.
+ */
+ if (cpu != targ_cpu) {
+ p0 = &per_cpu(fcoe_percpu, targ_cpu);
+ spin_lock_bh(&p0->fcoe_rx_list.lock);
+ if (p0->thread) {
+ FC_DBG("Moving frames from CPU %d to CPU %d\n",
+ cpu, targ_cpu);
+
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ __skb_queue_tail(&p0->fcoe_rx_list, skb);
+ spin_unlock_bh(&p0->fcoe_rx_list.lock);
+ } else {
+ /*
+ * The targeted CPU is not initialized and cannot accept
+ * new skbs. Unlock the targeted CPU and drop the skbs
+ * on the CPU that is going offline.
+ */
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ kfree_skb(skb);
+ spin_unlock_bh(&p0->fcoe_rx_list.lock);
+ }
+ } else {
+ /*
+ * This scenario occurs when the module is being removed
+ * and all threads are being destroyed. skbs will continue
+ * to be shifted from the CPU thread that is being removed
+ * to the CPU thread associated with the CPU that is processing
+ * the module removal. Once there is only one CPU Rx thread it
+ * will reach this case and we will drop all skbs and later
+ * stop the thread.
+ */
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ kfree_skb(skb);
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ }
+#else
+ /*
+ * This a non-SMP scenario where the singluar Rx thread is
+ * being removed. Free all skbs and stop the thread.
+ */
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
+ kfree_skb(skb);
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+#endif
+
+ if (thread)
+ kthread_stop(thread);
+
+ if (crc_eof)
+ put_page(crc_eof);
+}
+
+/**
+ * fcoe_cpu_callback() - fcoe cpu hotplug event callback
+ * @nfb: callback data block
+ * @action: event triggering the callback
+ * @hcpu: index for the cpu of this event
+ *
+ * This creates or destroys per cpu data for fcoe
+ *
+ * Returns NOTIFY_OK always.
+ */
+static int fcoe_cpu_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ unsigned cpu = (unsigned long)hcpu;
+
+ switch (action) {
+ case CPU_ONLINE:
+ case CPU_ONLINE_FROZEN:
+ FC_DBG("CPU %x online: Create Rx thread\n", cpu);
+ fcoe_percpu_thread_create(cpu);
+ break;
+ case CPU_DEAD:
+ case CPU_DEAD_FROZEN:
+ FC_DBG("CPU %x offline: Remove Rx thread\n", cpu);
+ fcoe_percpu_thread_destroy(cpu);
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block fcoe_cpu_notifier = {
+ .notifier_call = fcoe_cpu_callback,
+};
+
+/**
+ * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
+ * @skb: the receive skb
+ * @dev: associated net device
+ * @ptype: context
+ * @odldev: last device
+ *
+ * this function will receive the packet and build fc frame and pass it up
+ *
+ * Returns: 0 for success
+ */
+int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *ptype, struct net_device *olddev)
+{
+ struct fc_lport *lp;
+ struct fcoe_rcv_info *fr;
+ struct fcoe_softc *fc;
+ struct fc_frame_header *fh;
+ struct fcoe_percpu_s *fps;
+ unsigned short oxid;
+ unsigned int cpu = 0;
+
+ fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
+ lp = fc->ctlr.lp;
+ if (unlikely(lp == NULL)) {
+ FC_DBG("cannot find hba structure");
+ goto err2;
+ }
+ if (!lp->link_up)
+ goto err2;
+
+ if (unlikely(debug_fcoe)) {
+ FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p "
+ "end:%p sum:%d dev:%s", skb->len, skb->data_len,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->csum,
+ skb->dev ? skb->dev->name : "<NULL>");
+
+ }
+
+ /* check for FCOE packet type */
+ if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
+ FC_DBG("wrong FC type frame");
+ goto err;
+ }
+
+ /*
+ * Check for minimum frame length, and make sure required FCoE
+ * and FC headers are pulled into the linear data area.
+ */
+ if (unlikely((skb->len < FCOE_MIN_FRAME) ||
+ !pskb_may_pull(skb, FCOE_HEADER_LEN)))
+ goto err;
+
+ skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
+ fh = (struct fc_frame_header *) skb_transport_header(skb);
+
+ oxid = ntohs(fh->fh_ox_id);
+
+ fr = fcoe_dev_from_skb(skb);
+ fr->fr_dev = lp;
+ fr->ptype = ptype;
+
+#ifdef CONFIG_SMP
+ /*
+ * The incoming frame exchange id(oxid) is ANDed with num of online
+ * cpu bits to get cpu and then this cpu is used for selecting
+ * a per cpu kernel thread from fcoe_percpu.
+ */
+ cpu = oxid & (num_online_cpus() - 1);
+#endif
+
+ fps = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&fps->fcoe_rx_list.lock);
+ if (unlikely(!fps->thread)) {
+ /*
+ * The targeted CPU is not ready, let's target
+ * the first CPU now. For non-SMP systems this
+ * will check the same CPU twice.
+ */
+ FC_DBG("CPU is online, but no receive thread ready "
+ "for incoming skb- using first online CPU.\n");
+
+ spin_unlock_bh(&fps->fcoe_rx_list.lock);
+ cpu = first_cpu(cpu_online_map);
+ fps = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&fps->fcoe_rx_list.lock);
+ if (!fps->thread) {
+ spin_unlock_bh(&fps->fcoe_rx_list.lock);
+ goto err;
+ }
+ }
+
+ /*
+ * We now have a valid CPU that we're targeting for
+ * this skb. We also have this receive thread locked,
+ * so we're free to queue skbs into it's queue.
+ */
+ __skb_queue_tail(&fps->fcoe_rx_list, skb);
+ if (fps->fcoe_rx_list.qlen == 1)
+ wake_up_process(fps->thread);
+
+ spin_unlock_bh(&fps->fcoe_rx_list.lock);
+
+ return 0;
+err:
+ fc_lport_get_stats(lp)->ErrorFrames++;
+
+err2:
+ kfree_skb(skb);
+ return -1;
+}
+EXPORT_SYMBOL_GPL(fcoe_rcv);
+
+/**
+ * fcoe_start_io() - pass to netdev to start xmit for fcoe
+ * @skb: the skb to be xmitted
+ *
+ * Returns: 0 for success
+ */
+static inline int fcoe_start_io(struct sk_buff *skb)
+{
+ int rc;
+
+ skb_get(skb);
+ rc = dev_queue_xmit(skb);
+ if (rc != 0)
+ return rc;
+ kfree_skb(skb);
+ return 0;
+}
+
+/**
+ * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof
+ * @skb: the skb to be xmitted
+ * @tlen: total len
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
+{
+ struct fcoe_percpu_s *fps;
+ struct page *page;
+
+ fps = &get_cpu_var(fcoe_percpu);
+ page = fps->crc_eof_page;
+ if (!page) {
+ page = alloc_page(GFP_ATOMIC);
+ if (!page) {
+ put_cpu_var(fcoe_percpu);
+ return -ENOMEM;
+ }
+ fps->crc_eof_page = page;
+ fps->crc_eof_offset = 0;
+ }
+
+ get_page(page);
+ skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
+ fps->crc_eof_offset, tlen);
+ skb->len += tlen;
+ skb->data_len += tlen;
+ skb->truesize += tlen;
+ fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
+
+ if (fps->crc_eof_offset >= PAGE_SIZE) {
+ fps->crc_eof_page = NULL;
+ fps->crc_eof_offset = 0;
+ put_page(page);
+ }
+ put_cpu_var(fcoe_percpu);
+ return 0;
+}
+
+/**
+ * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
+ * @fp: the fc_frame containg data to be checksummed
+ *
+ * This uses crc32() to calculate the crc for fc frame
+ * Return : 32 bit crc
+ */
+u32 fcoe_fc_crc(struct fc_frame *fp)
+{
+ struct sk_buff *skb = fp_skb(fp);
+ struct skb_frag_struct *frag;
+ unsigned char *data;
+ unsigned long off, len, clen;
+ u32 crc;
+ unsigned i;
+
+ crc = crc32(~0, skb->data, skb_headlen(skb));
+
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ frag = &skb_shinfo(skb)->frags[i];
+ off = frag->page_offset;
+ len = frag->size;
+ while (len > 0) {
+ clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
+ data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
+ KM_SKB_DATA_SOFTIRQ);
+ crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
+ kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
+ off += clen;
+ len -= clen;
+ }
+ }
+ return crc;
+}
+
+/**
+ * fcoe_xmit() - FCoE frame transmit function
+ * @lp: the associated local port
+ * @fp: the fc_frame to be transmitted
+ *
+ * Return : 0 for success
+ */
+int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
+{
+ int wlen, rc = 0;
+ u32 crc;
+ struct ethhdr *eh;
+ struct fcoe_crc_eof *cp;
+ struct sk_buff *skb;
+ struct fcoe_dev_stats *stats;
+ struct fc_frame_header *fh;
+ unsigned int hlen; /* header length implies the version */
+ unsigned int tlen; /* trailer length */
+ unsigned int elen; /* eth header, may include vlan */
+ struct fcoe_softc *fc;
+ u8 sof, eof;
+ struct fcoe_hdr *hp;
+
+ WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
+
+ fc = lport_priv(lp);
+ fh = fc_frame_header_get(fp);
+ skb = fp_skb(fp);
+ wlen = skb->len / FCOE_WORD_TO_BYTE;
+
+ if (!lp->link_up) {
+ kfree(skb);
+ return 0;
+ }
+
+ if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ) &&
+ fcoe_ctlr_els_send(&fc->ctlr, skb))
+ return 0;
+
+ sof = fr_sof(fp);
+ eof = fr_eof(fp);
+
+ elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ?
+ sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr);
+ hlen = sizeof(struct fcoe_hdr);
+ tlen = sizeof(struct fcoe_crc_eof);
+ wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
+
+ /* crc offload */
+ if (likely(lp->crc_offload)) {
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ skb->csum_start = skb_headroom(skb);
+ skb->csum_offset = skb->len;
+ crc = 0;
+ } else {
+ skb->ip_summed = CHECKSUM_NONE;
+ crc = fcoe_fc_crc(fp);
+ }
+
+ /* copy fc crc and eof to the skb buff */
+ if (skb_is_nonlinear(skb)) {
+ skb_frag_t *frag;
+ if (fcoe_get_paged_crc_eof(skb, tlen)) {
+ kfree_skb(skb);
+ return -ENOMEM;
+ }
+ frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
+ cp = kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ)
+ + frag->page_offset;
+ } else {
+ cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
+ }
+
+ memset(cp, 0, sizeof(*cp));
+ cp->fcoe_eof = eof;
+ cp->fcoe_crc32 = cpu_to_le32(~crc);
+
+ if (skb_is_nonlinear(skb)) {
+ kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
+ cp = NULL;
+ }
+
+ /* adjust skb netowrk/transport offsets to match mac/fcoe/fc */
+ skb_push(skb, elen + hlen);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ skb->mac_len = elen;
+ skb->protocol = htons(ETH_P_FCOE);
+ skb->dev = fc->real_dev;
+
+ /* fill up mac and fcoe headers */
+ eh = eth_hdr(skb);
+ eh->h_proto = htons(ETH_P_FCOE);
+ if (fc->ctlr.map_dest)
+ fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
+ else
+ /* insert GW address */
+ memcpy(eh->h_dest, fc->ctlr.dest_addr, ETH_ALEN);
+
+ if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN))
+ memcpy(eh->h_source, fc->ctlr.ctl_src_addr, ETH_ALEN);
+ else
+ memcpy(eh->h_source, fc->ctlr.data_src_addr, ETH_ALEN);
+
+ hp = (struct fcoe_hdr *)(eh + 1);
+ memset(hp, 0, sizeof(*hp));
+ if (FC_FCOE_VER)
+ FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
+ hp->fcoe_sof = sof;
+
+#ifdef NETIF_F_FSO
+ /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
+ if (lp->seq_offload && fr_max_payload(fp)) {
+ skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
+ skb_shinfo(skb)->gso_size = fr_max_payload(fp);
+ } else {
+ skb_shinfo(skb)->gso_type = 0;
+ skb_shinfo(skb)->gso_size = 0;
+ }
+#endif
+ /* update tx stats: regardless if LLD fails */
+ stats = fc_lport_get_stats(lp);
+ stats->TxFrames++;
+ stats->TxWords += wlen;
+
+ /* send down to lld */
+ fr_dev(fp) = lp;
+ if (fc->fcoe_pending_queue.qlen)
+ rc = fcoe_check_wait_queue(lp);
+
+ if (rc == 0)
+ rc = fcoe_start_io(skb);
+
+ if (rc) {
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ __skb_queue_tail(&fc->fcoe_pending_queue, skb);
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
+ lp->qfull = 1;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_xmit);
+
+/**
+ * fcoe_percpu_receive_thread() - recv thread per cpu
+ * @arg: ptr to the fcoe per cpu struct
+ *
+ * Return: 0 for success
+ */
+int fcoe_percpu_receive_thread(void *arg)
+{
+ struct fcoe_percpu_s *p = arg;
+ u32 fr_len;
+ struct fc_lport *lp;
+ struct fcoe_rcv_info *fr;
+ struct fcoe_dev_stats *stats;
+ struct fc_frame_header *fh;
+ struct sk_buff *skb;
+ struct fcoe_crc_eof crc_eof;
+ struct fc_frame *fp;
+ u8 *mac = NULL;
+ struct fcoe_softc *fc;
+ struct fcoe_hdr *hp;
+
+ set_user_nice(current, -20);
+
+ while (!kthread_should_stop()) {
+
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ schedule();
+ set_current_state(TASK_RUNNING);
+ if (kthread_should_stop())
+ return 0;
+ spin_lock_bh(&p->fcoe_rx_list.lock);
+ }
+ spin_unlock_bh(&p->fcoe_rx_list.lock);
+ fr = fcoe_dev_from_skb(skb);
+ lp = fr->fr_dev;
+ if (unlikely(lp == NULL)) {
+ FC_DBG("invalid HBA Structure");
+ kfree_skb(skb);
+ continue;
+ }
+
+ if (unlikely(debug_fcoe)) {
+ FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
+ "tail:%p end:%p sum:%d dev:%s",
+ skb->len, skb->data_len,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->csum,
+ skb->dev ? skb->dev->name : "<NULL>");
+ }
+
+ /*
+ * Save source MAC address before discarding header.
+ */
+ fc = lport_priv(lp);
+ if (skb_is_nonlinear(skb))
+ skb_linearize(skb); /* not ideal */
+ mac = eth_hdr(skb)->h_source;
+
+ /*
+ * Frame length checks and setting up the header pointers
+ * was done in fcoe_rcv already.
+ */
+ hp = (struct fcoe_hdr *) skb_network_header(skb);
+ fh = (struct fc_frame_header *) skb_transport_header(skb);
+
+ stats = fc_lport_get_stats(lp);
+ if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
+ if (stats->ErrorFrames < 5)
+ printk(KERN_WARNING "FCoE version "
+ "mismatch: The frame has "
+ "version %x, but the "
+ "initiator supports version "
+ "%x\n", FC_FCOE_DECAPS_VER(hp),
+ FC_FCOE_VER);
+ stats->ErrorFrames++;
+ kfree_skb(skb);
+ continue;
+ }
+
+ skb_pull(skb, sizeof(struct fcoe_hdr));
+ fr_len = skb->len - sizeof(struct fcoe_crc_eof);
+
+ stats->RxFrames++;
+ stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
+
+ fp = (struct fc_frame *)skb;
+ fc_frame_init(fp);
+ fr_dev(fp) = lp;
+ fr_sof(fp) = hp->fcoe_sof;
+
+ /* Copy out the CRC and EOF trailer for access */
+ if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
+ kfree_skb(skb);
+ continue;
+ }
+ fr_eof(fp) = crc_eof.fcoe_eof;
+ fr_crc(fp) = crc_eof.fcoe_crc32;
+ if (pskb_trim(skb, fr_len)) {
+ kfree_skb(skb);
+ continue;
+ }
+
+ /*
+ * We only check CRC if no offload is available and if it is
+ * it's solicited data, in which case, the FCP layer would
+ * check it during the copy.
+ */
+ if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
+ fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+ else
+ fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
+
+ fh = fc_frame_header_get(fp);
+ if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
+ fh->fh_type == FC_TYPE_FCP) {
+ fc_exch_recv(lp, lp->emp, fp);
+ continue;
+ }
+ if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
+ if (le32_to_cpu(fr_crc(fp)) !=
+ ~crc32(~0, skb->data, fr_len)) {
+ if (debug_fcoe || stats->InvalidCRCCount < 5)
+ printk(KERN_WARNING "fcoe: dropping "
+ "frame with CRC error\n");
+ stats->InvalidCRCCount++;
+ stats->ErrorFrames++;
+ fc_frame_free(fp);
+ continue;
+ }
+ fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
+ }
+ if (unlikely(fc->ctlr.flogi_oxid != FC_XID_UNKNOWN) &&
+ fcoe_ctlr_recv_flogi(&fc->ctlr, fp, mac)) {
+ fc_frame_free(fp);
+ continue;
+ }
+ fc_exch_recv(lp, lp->emp, fp);
+ }
+ return 0;
+}
+
+/**
+ * fcoe_watchdog() - fcoe timer callback
+ * @vp:
+ *
+ * This checks the pending queue length for fcoe and set lport qfull
+ * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
+ * fcoe_hostlist.
+ *
+ * Returns: 0 for success
+ */
+void fcoe_watchdog(ulong vp)
+{
+ struct fcoe_softc *fc;
+
+ read_lock(&fcoe_hostlist_lock);
+ list_for_each_entry(fc, &fcoe_hostlist, list) {
+ if (fc->ctlr.lp)
+ fcoe_check_wait_queue(fc->ctlr.lp);
+ }
+ read_unlock(&fcoe_hostlist_lock);
+
+ fcoe_timer.expires = jiffies + (1 * HZ);
+ add_timer(&fcoe_timer);
+}
+
+
+/**
+ * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue
+ * @lp: the fc_port for this skb
+ * @skb: the associated skb to be xmitted
+ *
+ * This empties the wait_queue, dequeue the head of the wait_queue queue
+ * and calls fcoe_start_io() for each packet, if all skb have been
+ * transmitted, return qlen or -1 if a error occurs, then restore
+ * wait_queue and try again later.
+ *
+ * The wait_queue is used when the skb transmit fails. skb will go
+ * in the wait_queue which will be emptied by the time function OR
+ * by the next skb transmit.
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_check_wait_queue(struct fc_lport *lp)
+{
+ struct fcoe_softc *fc = lport_priv(lp);
+ struct sk_buff *skb;
+ int rc = -1;
+
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ if (fc->fcoe_pending_queue_active)
+ goto out;
+ fc->fcoe_pending_queue_active = 1;
+
+ while (fc->fcoe_pending_queue.qlen) {
+ /* keep qlen > 0 until fcoe_start_io succeeds */
+ fc->fcoe_pending_queue.qlen++;
+ skb = __skb_dequeue(&fc->fcoe_pending_queue);
+
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ rc = fcoe_start_io(skb);
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+
+ if (rc) {
+ __skb_queue_head(&fc->fcoe_pending_queue, skb);
+ /* undo temporary increment above */
+ fc->fcoe_pending_queue.qlen--;
+ break;
+ }
+ /* undo temporary increment above */
+ fc->fcoe_pending_queue.qlen--;
+ }
+
+ if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
+ lp->qfull = 0;
+ fc->fcoe_pending_queue_active = 0;
+ rc = fc->fcoe_pending_queue.qlen;
+out:
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ return rc;
+}
+
+/**
+ * fcoe_dev_setup() - setup link change notification interface
+ */
+static void fcoe_dev_setup()
+{
+ /*
+ * here setup a interface specific wd time to
+ * monitor the link state
+ */
+ register_netdevice_notifier(&fcoe_notifier);
+}
+
+/**
+ * fcoe_dev_setup() - cleanup link change notification interface
+ */
+static void fcoe_dev_cleanup(void)
+{
+ unregister_netdevice_notifier(&fcoe_notifier);
+}
+
+/**
+ * fcoe_device_notification() - netdev event notification callback
+ * @notifier: context of the notification
+ * @event: type of event
+ * @ptr: fixed array for output parsed ifname
+ *
+ * This function is called by the ethernet driver in case of link change event
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_device_notification(struct notifier_block *notifier,
+ ulong event, void *ptr)
+{
+ struct fc_lport *lp = NULL;
+ struct net_device *real_dev = ptr;
+ struct fcoe_softc *fc;
+ struct fcoe_dev_stats *stats;
+ u32 link_possible = 1;
+ u32 mfs;
+ int rc = NOTIFY_OK;
+
+ read_lock(&fcoe_hostlist_lock);
+ list_for_each_entry(fc, &fcoe_hostlist, list) {
+ if (fc->real_dev == real_dev) {
+ lp = fc->ctlr.lp;
+ break;
+ }
+ }
+ read_unlock(&fcoe_hostlist_lock);
+ if (lp == NULL) {
+ rc = NOTIFY_DONE;
+ goto out;
+ }
+
+ switch (event) {
+ case NETDEV_DOWN:
+ case NETDEV_GOING_DOWN:
+ link_possible = 0;
+ break;
+ case NETDEV_UP:
+ case NETDEV_CHANGE:
+ break;
+ case NETDEV_CHANGEMTU:
+ mfs = fc->real_dev->mtu -
+ (sizeof(struct fcoe_hdr) +
+ sizeof(struct fcoe_crc_eof));
+ if (mfs >= FC_MIN_MAX_FRAME)
+ fc_set_mfs(lp, mfs);
+ break;
+ case NETDEV_REGISTER:
+ break;
+ default:
+ FC_DBG("Unknown event %ld from netdev netlink\n", event);
+ }
+ if (link_possible && !fcoe_link_ok(lp))
+ fcoe_ctlr_link_up(&fc->ctlr);
+ else if (fcoe_ctlr_link_down(&fc->ctlr)) {
+ stats = fc_lport_get_stats(lp);
+ stats->LinkFailureCount++;
+ fcoe_clean_pending_queue(lp);
+ }
+out:
+ return rc;
+}
+
+/**
+ * fcoe_if_to_netdev() - parse a name buffer to get netdev
+ * @ifname: fixed array for output parsed ifname
+ * @buffer: incoming buffer to be copied
+ *
+ * Returns: NULL or ptr to netdeive
+ */
+static struct net_device *fcoe_if_to_netdev(const char *buffer)
+{
+ char *cp;
+ char ifname[IFNAMSIZ + 2];
+
+ if (buffer) {
+ strlcpy(ifname, buffer, IFNAMSIZ);
+ cp = ifname + strlen(ifname);
+ while (--cp >= ifname && *cp == '\n')
+ *cp = '\0';
+ return dev_get_by_name(&init_net, ifname);
+ }
+ return NULL;
+}
+
+/**
+ * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev
+ * @netdev: the target netdev
+ *
+ * Returns: ptr to the struct module, NULL for failure
+ */
+static struct module *
+fcoe_netdev_to_module_owner(const struct net_device *netdev)
+{
+ struct device *dev;
+
+ if (!netdev)
+ return NULL;
+
+ dev = netdev->dev.parent;
+ if (!dev)
+ return NULL;
+
+ if (!dev->driver)
+ return NULL;
+
+ return dev->driver->owner;
+}
+
+/**
+ * fcoe_ethdrv_get() - Hold the Ethernet driver
+ * @netdev: the target netdev
+ *
+ * Holds the Ethernet driver module by try_module_get() for
+ * the corresponding netdev.
+ *
+ * Returns: 0 for succsss
+ */
+static int fcoe_ethdrv_get(const struct net_device *netdev)
+{
+ struct module *owner;
+
+ owner = fcoe_netdev_to_module_owner(netdev);
+ if (owner) {
+ printk(KERN_DEBUG "fcoe:hold driver module %s for %s\n",
+ module_name(owner), netdev->name);
+ return try_module_get(owner);
+ }
+ return -ENODEV;
+}
+
+/**
+ * fcoe_ethdrv_put() - Release the Ethernet driver
+ * @netdev: the target netdev
+ *
+ * Releases the Ethernet driver module by module_put for
+ * the corresponding netdev.
+ *
+ * Returns: 0 for succsss
+ */
+static int fcoe_ethdrv_put(const struct net_device *netdev)
+{
+ struct module *owner;
+
+ owner = fcoe_netdev_to_module_owner(netdev);
+ if (owner) {
+ printk(KERN_DEBUG "fcoe:release driver module %s for %s\n",
+ module_name(owner), netdev->name);
+ module_put(owner);
+ return 0;
+ }
+ return -ENODEV;
+}
+
+/**
+ * fcoe_destroy() - handles the destroy from sysfs
+ * @buffer: expcted to be a eth if name
+ * @kp: associated kernel param
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
+{
+ int rc;
+ struct net_device *netdev;
+
+ netdev = fcoe_if_to_netdev(buffer);
+ if (!netdev) {
+ rc = -ENODEV;
+ goto out_nodev;
+ }
+ /* look for existing lport */
+ if (!fcoe_hostlist_lookup(netdev)) {
+ rc = -ENODEV;
+ goto out_putdev;
+ }
+ rc = fcoe_if_destroy(netdev);
+ if (rc) {
+ printk(KERN_ERR "fcoe: fcoe_if_destroy(%s) failed\n",
+ netdev->name);
+ rc = -EIO;
+ goto out_putdev;
+ }
+ fcoe_ethdrv_put(netdev);
+ rc = 0;
+out_putdev:
+ dev_put(netdev);
+out_nodev:
+ return rc;
+}
+
+/**
+ * fcoe_create() - Handles the create call from sysfs
+ * @buffer: expcted to be a eth if name
+ * @kp: associated kernel param
+ *
+ * Returns: 0 for success
+ */
+static int fcoe_create(const char *buffer, struct kernel_param *kp)
+{
+ int rc;
+ struct net_device *netdev;
+
+ netdev = fcoe_if_to_netdev(buffer);
+ if (!netdev) {
+ rc = -ENODEV;
+ goto out_nodev;
+ }
+ /* look for existing lport */
+ if (fcoe_hostlist_lookup(netdev)) {
+ rc = -EEXIST;
+ goto out_putdev;
+ }
+ fcoe_ethdrv_get(netdev);
+
+ rc = fcoe_if_create(netdev);
+ if (rc) {
+ printk(KERN_ERR "fcoe: fcoe_if_create(%s) failed\n",
+ netdev->name);
+ fcoe_ethdrv_put(netdev);
+ rc = -EIO;
+ goto out_putdev;
+ }
+ rc = 0;
+out_putdev:
+ dev_put(netdev);
+out_nodev:
+ return rc;
+}
+
+module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(create, "string");
+MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
+module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
+__MODULE_PARM_TYPE(destroy, "string");
+MODULE_PARM_DESC(destroy, "Destroy fcoe port");
+
+/**
+ * fcoe_link_ok() - Check if link is ok for the fc_lport
+ * @lp: ptr to the fc_lport
+ *
+ * Any permanently-disqualifying conditions have been previously checked.
+ * This also updates the speed setting, which may change with link for 100/1000.
+ *
+ * This function should probably be checking for PAUSE support at some point
+ * in the future. Currently Per-priority-pause is not determinable using
+ * ethtool, so we shouldn't be restrictive until that problem is resolved.
+ *
+ * Returns: 0 if link is OK for use by FCoE.
+ *
+ */
+int fcoe_link_ok(struct fc_lport *lp)
+{
+ struct fcoe_softc *fc = lport_priv(lp);
+ struct net_device *dev = fc->real_dev;
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ int rc = 0;
+
+ if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
+ dev = fc->phys_dev;
+ if (dev->ethtool_ops->get_settings) {
+ dev->ethtool_ops->get_settings(dev, &ecmd);
+ lp->link_supported_speeds &=
+ ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
+ if (ecmd.supported & (SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full))
+ lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
+ if (ecmd.supported & SUPPORTED_10000baseT_Full)
+ lp->link_supported_speeds |=
+ FC_PORTSPEED_10GBIT;
+ if (ecmd.speed == SPEED_1000)
+ lp->link_speed = FC_PORTSPEED_1GBIT;
+ if (ecmd.speed == SPEED_10000)
+ lp->link_speed = FC_PORTSPEED_10GBIT;
+ }
+ } else
+ rc = -1;
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(fcoe_link_ok);
+
+/**
+ * fcoe_percpu_clean() - Clear the pending skbs for an lport
+ * @lp: the fc_lport
+ */
+void fcoe_percpu_clean(struct fc_lport *lp)
+{
+ struct fcoe_percpu_s *pp;
+ struct fcoe_rcv_info *fr;
+ struct sk_buff_head *list;
+ struct sk_buff *skb, *next;
+ struct sk_buff *head;
+ unsigned int cpu;
+
+ for_each_possible_cpu(cpu) {
+ pp = &per_cpu(fcoe_percpu, cpu);
+ spin_lock_bh(&pp->fcoe_rx_list.lock);
+ list = &pp->fcoe_rx_list;
+ head = list->next;
+ for (skb = head; skb != (struct sk_buff *)list;
+ skb = next) {
+ next = skb->next;
+ fr = fcoe_dev_from_skb(skb);
+ if (fr->fr_dev == lp) {
+ __skb_unlink(skb, list);
+ kfree_skb(skb);
+ }
+ }
+ spin_unlock_bh(&pp->fcoe_rx_list.lock);
+ }
+}
+EXPORT_SYMBOL_GPL(fcoe_percpu_clean);
+
+/**
+ * fcoe_clean_pending_queue() - Dequeue a skb and free it
+ * @lp: the corresponding fc_lport
+ *
+ * Returns: none
+ */
+void fcoe_clean_pending_queue(struct fc_lport *lp)
+{
+ struct fcoe_softc *fc = lport_priv(lp);
+ struct sk_buff *skb;
+
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ kfree_skb(skb);
+ spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ }
+ spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+}
+EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
+
+/**
+ * fcoe_reset() - Resets the fcoe
+ * @shost: shost the reset is from
+ *
+ * Returns: always 0
+ */
+int fcoe_reset(struct Scsi_Host *shost)
+{
+ struct fc_lport *lport = shost_priv(shost);
+ fc_lport_reset(lport);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_reset);
+
+/**
+ * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
+ * @device: this is currently ptr to net_device
+ *
+ * Returns: NULL or the located fcoe_softc
+ */
+static struct fcoe_softc *
+fcoe_hostlist_lookup_softc(const struct net_device *dev)
+{
+ struct fcoe_softc *fc;
+
+ read_lock(&fcoe_hostlist_lock);
+ list_for_each_entry(fc, &fcoe_hostlist, list) {
+ if (fc->real_dev == dev) {
+ read_unlock(&fcoe_hostlist_lock);
+ return fc;
+ }
+ }
+ read_unlock(&fcoe_hostlist_lock);
+ return NULL;
+}
+
+/**
+ * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
+ * @netdev: ptr to net_device
+ *
+ * Returns: 0 for success
+ */
+struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_hostlist_lookup_softc(netdev);
+
+ return (fc) ? fc->ctlr.lp : NULL;
+}
+EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup);
+
+/**
+ * fcoe_hostlist_add() - Add a lport to lports list
+ * @lp: ptr to the fc_lport to badded
+ *
+ * Returns: 0 for success
+ */
+int fcoe_hostlist_add(const struct fc_lport *lp)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
+ if (!fc) {
+ fc = lport_priv(lp);
+ write_lock_bh(&fcoe_hostlist_lock);
+ list_add_tail(&fc->list, &fcoe_hostlist);
+ write_unlock_bh(&fcoe_hostlist_lock);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_hostlist_add);
+
+/**
+ * fcoe_hostlist_remove() - remove a lport from lports list
+ * @lp: ptr to the fc_lport to badded
+ *
+ * Returns: 0 for success
+ */
+int fcoe_hostlist_remove(const struct fc_lport *lp)
+{
+ struct fcoe_softc *fc;
+
+ fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
+ BUG_ON(!fc);
+ write_lock_bh(&fcoe_hostlist_lock);
+ list_del(&fc->list);
+ write_unlock_bh(&fcoe_hostlist_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(fcoe_hostlist_remove);
+
+/**
+ * fcoe_init() - fcoe module loading initialization
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int __init fcoe_init(void)
+{
+ unsigned int cpu;
+ int rc = 0;
+ struct fcoe_percpu_s *p;
+
+ INIT_LIST_HEAD(&fcoe_hostlist);
+ rwlock_init(&fcoe_hostlist_lock);
+
+ for_each_possible_cpu(cpu) {
+ p = &per_cpu(fcoe_percpu, cpu);
+ skb_queue_head_init(&p->fcoe_rx_list);
+ }
+
+ for_each_online_cpu(cpu)
+ fcoe_percpu_thread_create(cpu);
+
+ /* Initialize per CPU interrupt thread */
+ rc = register_hotcpu_notifier(&fcoe_cpu_notifier);
+ if (rc)
+ goto out_free;
+
+ /* Setup link change notification */
+ fcoe_dev_setup();
+
+ setup_timer(&fcoe_timer, fcoe_watchdog, 0);
+
+ mod_timer(&fcoe_timer, jiffies + (10 * HZ));
+
+ fcoe_if_init();
+
+ return 0;
+
+out_free:
+ for_each_online_cpu(cpu) {
+ fcoe_percpu_thread_destroy(cpu);
+ }
+
+ return rc;
+}
+module_init(fcoe_init);
+
+/**
+ * fcoe_exit() - fcoe module unloading cleanup
+ *
+ * Returns 0 on success, negative on failure
+ */
+static void __exit fcoe_exit(void)
+{
+ unsigned int cpu;
+ struct fcoe_softc *fc, *tmp;
+
+ fcoe_dev_cleanup();
+
+ /* Stop the timer */
+ del_timer_sync(&fcoe_timer);
+
+ /* releases the associated fcoe hosts */
+ list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
+ fcoe_if_destroy(fc->real_dev);
+
+ unregister_hotcpu_notifier(&fcoe_cpu_notifier);
+
+ for_each_online_cpu(cpu) {
+ fcoe_percpu_thread_destroy(cpu);
+ }
+
+ /* detach from scsi transport */
+ fcoe_if_exit();
+}
+module_exit(fcoe_exit);
diff --git a/drivers/scsi/fcoe/fcoe.h b/drivers/scsi/fcoe/fcoe.h
new file mode 100644
index 00000000000..917aae88689
--- /dev/null
+++ b/drivers/scsi/fcoe/fcoe.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright(c) 2009 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Maintained at www.Open-FCoE.org
+ */
+
+#ifndef _FCOE_H_
+#define _FCOE_H_
+
+#include <linux/skbuff.h>
+#include <linux/kthread.h>
+
+#define FCOE_MAX_QUEUE_DEPTH 256
+#define FCOE_LOW_QUEUE_DEPTH 32
+
+#define FCOE_WORD_TO_BYTE 4
+
+#define FCOE_VERSION "0.1"
+#define FCOE_NAME "fcoe"
+#define FCOE_VENDOR "Open-FCoE.org"
+
+#define FCOE_MAX_LUN 255
+#define FCOE_MAX_FCP_TARGET 256
+
+#define FCOE_MAX_OUTSTANDING_COMMANDS 1024
+
+#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
+#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
+
+/*
+ * this percpu struct for fcoe
+ */
+struct fcoe_percpu_s {
+ struct task_struct *thread;
+ struct sk_buff_head fcoe_rx_list;
+ struct page *crc_eof_page;
+ int crc_eof_offset;
+};
+
+/*
+ * the fcoe sw transport private data
+ */
+struct fcoe_softc {
+ struct list_head list;
+ struct net_device *real_dev;
+ struct net_device *phys_dev; /* device with ethtool_ops */
+ struct packet_type fcoe_packet_type;
+ struct packet_type fip_packet_type;
+ struct sk_buff_head fcoe_pending_queue;
+ u8 fcoe_pending_queue_active;
+ struct fcoe_ctlr ctlr;
+};
+
+#define fcoe_from_ctlr(fc) container_of(fc, struct fcoe_softc, ctlr)
+
+static inline struct net_device *fcoe_netdev(
+ const struct fc_lport *lp)
+{
+ return ((struct fcoe_softc *)lport_priv(lp))->real_dev;
+}
+
+#endif /* _FCOE_H_ */
diff --git a/drivers/scsi/fcoe/fcoe_sw.c b/drivers/scsi/fcoe/fcoe_sw.c
deleted file mode 100644
index 2bbbe3c0cc7..00000000000
--- a/drivers/scsi/fcoe/fcoe_sw.c
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Maintained at www.Open-FCoE.org
- */
-
-#include <linux/module.h>
-#include <linux/version.h>
-#include <linux/kernel.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/spinlock.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_vlan.h>
-#include <net/rtnetlink.h>
-
-#include <scsi/fc/fc_els.h>
-#include <scsi/fc/fc_encaps.h>
-#include <scsi/fc/fc_fs.h>
-#include <scsi/scsi_transport.h>
-#include <scsi/scsi_transport_fc.h>
-
-#include <scsi/libfc.h>
-#include <scsi/libfcoe.h>
-#include <scsi/fc_transport_fcoe.h>
-
-#define FCOE_SW_VERSION "0.1"
-#define FCOE_SW_NAME "fcoesw"
-#define FCOE_SW_VENDOR "Open-FCoE.org"
-
-#define FCOE_MAX_LUN 255
-#define FCOE_MAX_FCP_TARGET 256
-
-#define FCOE_MAX_OUTSTANDING_COMMANDS 1024
-
-#define FCOE_MIN_XID 0x0001 /* the min xid supported by fcoe_sw */
-#define FCOE_MAX_XID 0x07ef /* the max xid supported by fcoe_sw */
-
-static struct scsi_transport_template *scsi_transport_fcoe_sw;
-
-struct fc_function_template fcoe_sw_transport_function = {
- .show_host_node_name = 1,
- .show_host_port_name = 1,
- .show_host_supported_classes = 1,
- .show_host_supported_fc4s = 1,
- .show_host_active_fc4s = 1,
- .show_host_maxframe_size = 1,
-
- .show_host_port_id = 1,
- .show_host_supported_speeds = 1,
- .get_host_speed = fc_get_host_speed,
- .show_host_speed = 1,
- .show_host_port_type = 1,
- .get_host_port_state = fc_get_host_port_state,
- .show_host_port_state = 1,
- .show_host_symbolic_name = 1,
-
- .dd_fcrport_size = sizeof(struct fc_rport_libfc_priv),
- .show_rport_maxframe_size = 1,
- .show_rport_supported_classes = 1,
-
- .show_host_fabric_name = 1,
- .show_starget_node_name = 1,
- .show_starget_port_name = 1,
- .show_starget_port_id = 1,
- .set_rport_dev_loss_tmo = fc_set_rport_loss_tmo,
- .show_rport_dev_loss_tmo = 1,
- .get_fc_host_stats = fc_get_host_stats,
- .issue_fc_host_lip = fcoe_reset,
-
- .terminate_rport_io = fc_rport_terminate_io,
-};
-
-static struct scsi_host_template fcoe_sw_shost_template = {
- .module = THIS_MODULE,
- .name = "FCoE Driver",
- .proc_name = FCOE_SW_NAME,
- .queuecommand = fc_queuecommand,
- .eh_abort_handler = fc_eh_abort,
- .eh_device_reset_handler = fc_eh_device_reset,
- .eh_host_reset_handler = fc_eh_host_reset,
- .slave_alloc = fc_slave_alloc,
- .change_queue_depth = fc_change_queue_depth,
- .change_queue_type = fc_change_queue_type,
- .this_id = -1,
- .cmd_per_lun = 32,
- .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
- .use_clustering = ENABLE_CLUSTERING,
- .sg_tablesize = SG_ALL,
- .max_sectors = 0xffff,
-};
-
-/**
- * fcoe_sw_lport_config() - sets up the fc_lport
- * @lp: ptr to the fc_lport
- * @shost: ptr to the parent scsi host
- *
- * Returns: 0 for success
- */
-static int fcoe_sw_lport_config(struct fc_lport *lp)
-{
- int i = 0;
-
- lp->link_up = 0;
- lp->qfull = 0;
- lp->max_retry_count = 3;
- lp->e_d_tov = 2 * 1000; /* FC-FS default */
- lp->r_a_tov = 2 * 2 * 1000;
- lp->service_params = (FCP_SPPF_INIT_FCN | FCP_SPPF_RD_XRDY_DIS |
- FCP_SPPF_RETRY | FCP_SPPF_CONF_COMPL);
-
- /*
- * allocate per cpu stats block
- */
- for_each_online_cpu(i)
- lp->dev_stats[i] = kzalloc(sizeof(struct fcoe_dev_stats),
- GFP_KERNEL);
-
- /* lport fc_lport related configuration */
- fc_lport_config(lp);
-
- /* offload related configuration */
- lp->crc_offload = 0;
- lp->seq_offload = 0;
- lp->lro_enabled = 0;
- lp->lro_xid = 0;
- lp->lso_max = 0;
-
- return 0;
-}
-
-/**
- * fcoe_sw_netdev_config() - Set up netdev for SW FCoE
- * @lp : ptr to the fc_lport
- * @netdev : ptr to the associated netdevice struct
- *
- * Must be called after fcoe_sw_lport_config() as it will use lport mutex
- *
- * Returns : 0 for success
- */
-static int fcoe_sw_netdev_config(struct fc_lport *lp, struct net_device *netdev)
-{
- u32 mfs;
- u64 wwnn, wwpn;
- struct fcoe_softc *fc;
- u8 flogi_maddr[ETH_ALEN];
-
- /* Setup lport private data to point to fcoe softc */
- fc = lport_priv(lp);
- fc->lp = lp;
- fc->real_dev = netdev;
- fc->phys_dev = netdev;
-
- /* Require support for get_pauseparam ethtool op. */
- if (netdev->priv_flags & IFF_802_1Q_VLAN)
- fc->phys_dev = vlan_dev_real_dev(netdev);
-
- /* Do not support for bonding device */
- if ((fc->real_dev->priv_flags & IFF_MASTER_ALB) ||
- (fc->real_dev->priv_flags & IFF_SLAVE_INACTIVE) ||
- (fc->real_dev->priv_flags & IFF_MASTER_8023AD)) {
- return -EOPNOTSUPP;
- }
-
- /*
- * Determine max frame size based on underlying device and optional
- * user-configured limit. If the MFS is too low, fcoe_link_ok()
- * will return 0, so do this first.
- */
- mfs = fc->real_dev->mtu - (sizeof(struct fcoe_hdr) +
- sizeof(struct fcoe_crc_eof));
- if (fc_set_mfs(lp, mfs))
- return -EINVAL;
-
- if (!fcoe_link_ok(lp))
- lp->link_up = 1;
-
- /* offload features support */
- if (fc->real_dev->features & NETIF_F_SG)
- lp->sg_supp = 1;
-
-#ifdef NETIF_F_FCOE_CRC
- if (netdev->features & NETIF_F_FCOE_CRC) {
- lp->crc_offload = 1;
- printk(KERN_DEBUG "fcoe:%s supports FCCRC offload\n",
- netdev->name);
- }
-#endif
-#ifdef NETIF_F_FSO
- if (netdev->features & NETIF_F_FSO) {
- lp->seq_offload = 1;
- lp->lso_max = netdev->gso_max_size;
- printk(KERN_DEBUG "fcoe:%s supports LSO for max len 0x%x\n",
- netdev->name, lp->lso_max);
- }
-#endif
- if (netdev->fcoe_ddp_xid) {
- lp->lro_enabled = 1;
- lp->lro_xid = netdev->fcoe_ddp_xid;
- printk(KERN_DEBUG "fcoe:%s supports LRO for max xid 0x%x\n",
- netdev->name, lp->lro_xid);
- }
- skb_queue_head_init(&fc->fcoe_pending_queue);
- fc->fcoe_pending_queue_active = 0;
-
- /* setup Source Mac Address */
- memcpy(fc->ctl_src_addr, fc->real_dev->dev_addr,
- fc->real_dev->addr_len);
-
- wwnn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 1, 0);
- fc_set_wwnn(lp, wwnn);
- /* XXX - 3rd arg needs to be vlan id */
- wwpn = fcoe_wwn_from_mac(fc->real_dev->dev_addr, 2, 0);
- fc_set_wwpn(lp, wwpn);
-
- /*
- * Add FCoE MAC address as second unicast MAC address
- * or enter promiscuous mode if not capable of listening
- * for multiple unicast MACs.
- */
- rtnl_lock();
- memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
- dev_unicast_add(fc->real_dev, flogi_maddr, ETH_ALEN);
- rtnl_unlock();
-
- /*
- * setup the receive function from ethernet driver
- * on the ethertype for the given device
- */
- fc->fcoe_packet_type.func = fcoe_rcv;
- fc->fcoe_packet_type.type = __constant_htons(ETH_P_FCOE);
- fc->fcoe_packet_type.dev = fc->real_dev;
- dev_add_pack(&fc->fcoe_packet_type);
-
- return 0;
-}
-
-/**
- * fcoe_sw_shost_config() - Sets up fc_lport->host
- * @lp : ptr to the fc_lport
- * @shost : ptr to the associated scsi host
- * @dev : device associated to scsi host
- *
- * Must be called after fcoe_sw_lport_config() and fcoe_sw_netdev_config()
- *
- * Returns : 0 for success
- */
-static int fcoe_sw_shost_config(struct fc_lport *lp, struct Scsi_Host *shost,
- struct device *dev)
-{
- int rc = 0;
-
- /* lport scsi host config */
- lp->host = shost;
-
- lp->host->max_lun = FCOE_MAX_LUN;
- lp->host->max_id = FCOE_MAX_FCP_TARGET;
- lp->host->max_channel = 0;
- lp->host->transportt = scsi_transport_fcoe_sw;
-
- /* add the new host to the SCSI-ml */
- rc = scsi_add_host(lp->host, dev);
- if (rc) {
- FC_DBG("fcoe_sw_shost_config:error on scsi_add_host\n");
- return rc;
- }
- sprintf(fc_host_symbolic_name(lp->host), "%s v%s over %s",
- FCOE_SW_NAME, FCOE_SW_VERSION,
- fcoe_netdev(lp)->name);
-
- return 0;
-}
-
-/**
- * fcoe_sw_em_config() - allocates em for this lport
- * @lp: the port that em is to allocated for
- *
- * Returns : 0 on success
- */
-static inline int fcoe_sw_em_config(struct fc_lport *lp)
-{
- BUG_ON(lp->emp);
-
- lp->emp = fc_exch_mgr_alloc(lp, FC_CLASS_3,
- FCOE_MIN_XID, FCOE_MAX_XID);
- if (!lp->emp)
- return -ENOMEM;
-
- return 0;
-}
-
-/**
- * fcoe_sw_destroy() - FCoE software HBA tear-down function
- * @netdev: ptr to the associated net_device
- *
- * Returns: 0 if link is OK for use by FCoE.
- */
-static int fcoe_sw_destroy(struct net_device *netdev)
-{
- int cpu;
- struct fc_lport *lp = NULL;
- struct fcoe_softc *fc;
- u8 flogi_maddr[ETH_ALEN];
-
- BUG_ON(!netdev);
-
- printk(KERN_DEBUG "fcoe_sw_destroy:interface on %s\n",
- netdev->name);
-
- lp = fcoe_hostlist_lookup(netdev);
- if (!lp)
- return -ENODEV;
-
- fc = lport_priv(lp);
-
- /* Logout of the fabric */
- fc_fabric_logoff(lp);
-
- /* Remove the instance from fcoe's list */
- fcoe_hostlist_remove(lp);
-
- /* Don't listen for Ethernet packets anymore */
- dev_remove_pack(&fc->fcoe_packet_type);
-
- /* Cleanup the fc_lport */
- fc_lport_destroy(lp);
- fc_fcp_destroy(lp);
-
- /* Detach from the scsi-ml */
- fc_remove_host(lp->host);
- scsi_remove_host(lp->host);
-
- /* There are no more rports or I/O, free the EM */
- if (lp->emp)
- fc_exch_mgr_free(lp->emp);
-
- /* Delete secondary MAC addresses */
- rtnl_lock();
- memcpy(flogi_maddr, (u8[6]) FC_FCOE_FLOGI_MAC, ETH_ALEN);
- dev_unicast_delete(fc->real_dev, flogi_maddr, ETH_ALEN);
- if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
- dev_unicast_delete(fc->real_dev, fc->data_src_addr, ETH_ALEN);
- rtnl_unlock();
-
- /* Free the per-CPU revieve threads */
- fcoe_percpu_clean(lp);
-
- /* Free existing skbs */
- fcoe_clean_pending_queue(lp);
-
- /* Free memory used by statistical counters */
- for_each_online_cpu(cpu)
- kfree(lp->dev_stats[cpu]);
-
- /* Release the net_device and Scsi_Host */
- dev_put(fc->real_dev);
- scsi_host_put(lp->host);
-
- return 0;
-}
-
-/*
- * fcoe_sw_ddp_setup - calls LLD's ddp_setup through net_device
- * @lp: the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
- * @sgl: the scatterlist describing this transfer
- * @sgc: number of sg items
- *
- * Returns : 0 no ddp
- */
-static int fcoe_sw_ddp_setup(struct fc_lport *lp, u16 xid,
- struct scatterlist *sgl, unsigned int sgc)
-{
- struct net_device *n = fcoe_netdev(lp);
-
- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_setup)
- return n->netdev_ops->ndo_fcoe_ddp_setup(n, xid, sgl, sgc);
-
- return 0;
-}
-
-/*
- * fcoe_sw_ddp_done - calls LLD's ddp_done through net_device
- * @lp: the corresponding fc_lport
- * @xid: the exchange id for this ddp transfer
- *
- * Returns : the length of data that have been completed by ddp
- */
-static int fcoe_sw_ddp_done(struct fc_lport *lp, u16 xid)
-{
- struct net_device *n = fcoe_netdev(lp);
-
- if (n->netdev_ops && n->netdev_ops->ndo_fcoe_ddp_done)
- return n->netdev_ops->ndo_fcoe_ddp_done(n, xid);
- return 0;
-}
-
-static struct libfc_function_template fcoe_sw_libfc_fcn_templ = {
- .frame_send = fcoe_xmit,
- .ddp_setup = fcoe_sw_ddp_setup,
- .ddp_done = fcoe_sw_ddp_done,
-};
-
-/**
- * fcoe_sw_create() - this function creates the fcoe interface
- * @netdev: pointer the associated netdevice
- *
- * Creates fc_lport struct and scsi_host for lport, configures lport
- * and starts fabric login.
- *
- * Returns : 0 on success
- */
-static int fcoe_sw_create(struct net_device *netdev)
-{
- int rc;
- struct fc_lport *lp = NULL;
- struct fcoe_softc *fc;
- struct Scsi_Host *shost;
-
- BUG_ON(!netdev);
-
- printk(KERN_DEBUG "fcoe_sw_create:interface on %s\n",
- netdev->name);
-
- lp = fcoe_hostlist_lookup(netdev);
- if (lp)
- return -EEXIST;
-
- shost = fcoe_host_alloc(&fcoe_sw_shost_template,
- sizeof(struct fcoe_softc));
- if (!shost) {
- FC_DBG("Could not allocate host structure\n");
- return -ENOMEM;
- }
- lp = shost_priv(shost);
- fc = lport_priv(lp);
-
- /* configure fc_lport, e.g., em */
- rc = fcoe_sw_lport_config(lp);
- if (rc) {
- FC_DBG("Could not configure lport\n");
- goto out_host_put;
- }
-
- /* configure lport network properties */
- rc = fcoe_sw_netdev_config(lp, netdev);
- if (rc) {
- FC_DBG("Could not configure netdev for lport\n");
- goto out_host_put;
- }
-
- /* configure lport scsi host properties */
- rc = fcoe_sw_shost_config(lp, shost, &netdev->dev);
- if (rc) {
- FC_DBG("Could not configure shost for lport\n");
- goto out_host_put;
- }
-
- /* lport exch manager allocation */
- rc = fcoe_sw_em_config(lp);
- if (rc) {
- FC_DBG("Could not configure em for lport\n");
- goto out_host_put;
- }
-
- /* Initialize the library */
- rc = fcoe_libfc_config(lp, &fcoe_sw_libfc_fcn_templ);
- if (rc) {
- FC_DBG("Could not configure libfc for lport!\n");
- goto out_lp_destroy;
- }
-
- /* add to lports list */
- fcoe_hostlist_add(lp);
-
- lp->boot_time = jiffies;
-
- fc_fabric_login(lp);
-
- dev_hold(netdev);
-
- return rc;
-
-out_lp_destroy:
- fc_exch_mgr_free(lp->emp); /* Free the EM */
-out_host_put:
- scsi_host_put(lp->host);
- return rc;
-}
-
-/**
- * fcoe_sw_match() - The FCoE SW transport match function
- *
- * Returns : false always
- */
-static bool fcoe_sw_match(struct net_device *netdev)
-{
- /* FIXME - for sw transport, always return false */
- return false;
-}
-
-/* the sw hba fcoe transport */
-struct fcoe_transport fcoe_sw_transport = {
- .name = "fcoesw",
- .create = fcoe_sw_create,
- .destroy = fcoe_sw_destroy,
- .match = fcoe_sw_match,
- .vendor = 0x0,
- .device = 0xffff,
-};
-
-/**
- * fcoe_sw_init() - Registers fcoe_sw_transport
- *
- * Returns : 0 on success
- */
-int __init fcoe_sw_init(void)
-{
- /* attach to scsi transport */
- scsi_transport_fcoe_sw =
- fc_attach_transport(&fcoe_sw_transport_function);
-
- if (!scsi_transport_fcoe_sw) {
- printk(KERN_ERR "fcoe_sw_init:fc_attach_transport() failed\n");
- return -ENODEV;
- }
-
- mutex_init(&fcoe_sw_transport.devlock);
- INIT_LIST_HEAD(&fcoe_sw_transport.devlist);
-
- /* register sw transport */
- fcoe_transport_register(&fcoe_sw_transport);
- return 0;
-}
-
-/**
- * fcoe_sw_exit() - Unregisters fcoe_sw_transport
- *
- * Returns : 0 on success
- */
-int __exit fcoe_sw_exit(void)
-{
- /* dettach the transport */
- fc_release_transport(scsi_transport_fcoe_sw);
- fcoe_transport_unregister(&fcoe_sw_transport);
- return 0;
-}
diff --git a/drivers/scsi/fcoe/libfcoe.c b/drivers/scsi/fcoe/libfcoe.c
index 0d6f5beb7f9..f410f4abb54 100644
--- a/drivers/scsi/fcoe/libfcoe.c
+++ b/drivers/scsi/fcoe/libfcoe.c
@@ -1,5 +1,6 @@
/*
- * Copyright(c) 2007 - 2008 Intel Corporation. All rights reserved.
+ * Copyright (c) 2008-2009 Cisco Systems, Inc. All rights reserved.
+ * Copyright (c) 2009 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -17,1200 +18,1260 @@
* Maintained at www.Open-FCoE.org
*/
+#include <linux/types.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kernel.h>
+#include <linux/list.h>
#include <linux/spinlock.h>
-#include <linux/skbuff.h>
+#include <linux/timer.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
-#include <linux/kthread.h>
-#include <linux/crc32.h>
-#include <linux/cpu.h>
-#include <linux/fs.h>
-#include <linux/sysfs.h>
-#include <linux/ctype.h>
-#include <scsi/scsi_tcq.h>
-#include <scsi/scsicam.h>
-#include <scsi/scsi_transport.h>
-#include <scsi/scsi_transport_fc.h>
+#include <linux/netdevice.h>
+#include <linux/errno.h>
+#include <linux/bitops.h>
#include <net/rtnetlink.h>
+#include <scsi/fc/fc_els.h>
+#include <scsi/fc/fc_fs.h>
+#include <scsi/fc/fc_fip.h>
#include <scsi/fc/fc_encaps.h>
+#include <scsi/fc/fc_fcoe.h>
#include <scsi/libfc.h>
-#include <scsi/fc_frame.h>
#include <scsi/libfcoe.h>
-#include <scsi/fc_transport_fcoe.h>
-
-static int debug_fcoe;
-#define FCOE_MAX_QUEUE_DEPTH 256
-#define FCOE_LOW_QUEUE_DEPTH 32
+MODULE_AUTHOR("Open-FCoE.org");
+MODULE_DESCRIPTION("FIP discovery protocol support for FCoE HBAs");
+MODULE_LICENSE("GPL v2");
-/* destination address mode */
-#define FCOE_GW_ADDR_MODE 0x00
-#define FCOE_FCOUI_ADDR_MODE 0x01
+#define FCOE_CTLR_MIN_FKA 500 /* min keep alive (mS) */
+#define FCOE_CTLR_DEF_FKA FIP_DEF_FKA /* default keep alive (mS) */
-#define FCOE_WORD_TO_BYTE 4
+static void fcoe_ctlr_timeout(unsigned long);
+static void fcoe_ctlr_link_work(struct work_struct *);
+static void fcoe_ctlr_recv_work(struct work_struct *);
-MODULE_AUTHOR("Open-FCoE.org");
-MODULE_DESCRIPTION("FCoE");
-MODULE_LICENSE("GPL");
+static u8 fcoe_all_fcfs[ETH_ALEN] = FIP_ALL_FCF_MACS;
-/* fcoe host list */
-LIST_HEAD(fcoe_hostlist);
-DEFINE_RWLOCK(fcoe_hostlist_lock);
-DEFINE_TIMER(fcoe_timer, NULL, 0, 0);
-struct fcoe_percpu_s *fcoe_percpu[NR_CPUS];
+static u32 fcoe_ctlr_debug; /* 1 for basic, 2 for noisy debug */
+#define FIP_DBG_LVL(level, fmt, args...) \
+ do { \
+ if (fcoe_ctlr_debug >= (level)) \
+ FC_DBG(fmt, ##args); \
+ } while (0)
-/* Function Prototyes */
-static int fcoe_check_wait_queue(struct fc_lport *);
-static void fcoe_recv_flogi(struct fcoe_softc *, struct fc_frame *, u8 *);
-#ifdef CONFIG_HOTPLUG_CPU
-static int fcoe_cpu_callback(struct notifier_block *, ulong, void *);
-#endif /* CONFIG_HOTPLUG_CPU */
-static int fcoe_device_notification(struct notifier_block *, ulong, void *);
-static void fcoe_dev_setup(void);
-static void fcoe_dev_cleanup(void);
+#define FIP_DBG(fmt, args...) FIP_DBG_LVL(1, fmt, ##args)
-/* notification function from net device */
-static struct notifier_block fcoe_notifier = {
- .notifier_call = fcoe_device_notification,
-};
+/*
+ * Return non-zero if FCF fcoe_size has been validated.
+ */
+static inline int fcoe_ctlr_mtu_valid(const struct fcoe_fcf *fcf)
+{
+ return (fcf->flags & FIP_FL_SOL) != 0;
+}
+/*
+ * Return non-zero if the FCF is usable.
+ */
+static inline int fcoe_ctlr_fcf_usable(struct fcoe_fcf *fcf)
+{
+ u16 flags = FIP_FL_SOL | FIP_FL_AVAIL;
-#ifdef CONFIG_HOTPLUG_CPU
-static struct notifier_block fcoe_cpu_notifier = {
- .notifier_call = fcoe_cpu_callback,
-};
+ return (fcf->flags & flags) == flags;
+}
/**
- * fcoe_create_percpu_data() - creates the associated cpu data
- * @cpu: index for the cpu where fcoe cpu data will be created
- *
- * create percpu stats block, from cpu add notifier
- *
- * Returns: none
+ * fcoe_ctlr_init() - Initialize the FCoE Controller instance.
+ * @fip: FCoE controller.
*/
-static void fcoe_create_percpu_data(int cpu)
+void fcoe_ctlr_init(struct fcoe_ctlr *fip)
{
- struct fc_lport *lp;
- struct fcoe_softc *fc;
-
- write_lock_bh(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- lp = fc->lp;
- if (lp->dev_stats[cpu] == NULL)
- lp->dev_stats[cpu] =
- kzalloc(sizeof(struct fcoe_dev_stats),
- GFP_KERNEL);
- }
- write_unlock_bh(&fcoe_hostlist_lock);
+ fip->state = FIP_ST_LINK_WAIT;
+ INIT_LIST_HEAD(&fip->fcfs);
+ spin_lock_init(&fip->lock);
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ setup_timer(&fip->timer, fcoe_ctlr_timeout, (unsigned long)fip);
+ INIT_WORK(&fip->link_work, fcoe_ctlr_link_work);
+ INIT_WORK(&fip->recv_work, fcoe_ctlr_recv_work);
+ skb_queue_head_init(&fip->fip_recv_list);
}
+EXPORT_SYMBOL(fcoe_ctlr_init);
/**
- * fcoe_destroy_percpu_data() - destroys the associated cpu data
- * @cpu: index for the cpu where fcoe cpu data will destroyed
- *
- * destroy percpu stats block called by cpu add/remove notifier
+ * fcoe_ctlr_reset_fcfs() - Reset and free all FCFs for a controller.
+ * @fip: FCoE controller.
*
- * Retuns: none
+ * Called with &fcoe_ctlr lock held.
*/
-static void fcoe_destroy_percpu_data(int cpu)
+static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip)
{
- struct fc_lport *lp;
- struct fcoe_softc *fc;
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf *next;
- write_lock_bh(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- lp = fc->lp;
- kfree(lp->dev_stats[cpu]);
- lp->dev_stats[cpu] = NULL;
+ fip->sel_fcf = NULL;
+ list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
+ list_del(&fcf->list);
+ kfree(fcf);
}
- write_unlock_bh(&fcoe_hostlist_lock);
+ fip->fcf_count = 0;
+ fip->sel_time = 0;
}
/**
- * fcoe_cpu_callback() - fcoe cpu hotplug event callback
- * @nfb: callback data block
- * @action: event triggering the callback
- * @hcpu: index for the cpu of this event
+ * fcoe_ctrl_destroy() - Disable and tear-down the FCoE controller.
+ * @fip: FCoE controller.
+ *
+ * This is called by FCoE drivers before freeing the &fcoe_ctlr.
*
- * this creates or destroys per cpu data for fcoe
+ * The receive handler will have been deleted before this to guarantee
+ * that no more recv_work will be scheduled.
*
- * Returns NOTIFY_OK always.
+ * The timer routine will simply return once we set FIP_ST_DISABLED.
+ * This guarantees that no further timeouts or work will be scheduled.
*/
-static int fcoe_cpu_callback(struct notifier_block *nfb, unsigned long action,
- void *hcpu)
+void fcoe_ctlr_destroy(struct fcoe_ctlr *fip)
{
- unsigned int cpu = (unsigned long)hcpu;
-
- switch (action) {
- case CPU_ONLINE:
- fcoe_create_percpu_data(cpu);
- break;
- case CPU_DEAD:
- fcoe_destroy_percpu_data(cpu);
- break;
- default:
- break;
- }
- return NOTIFY_OK;
+ flush_work(&fip->recv_work);
+ spin_lock_bh(&fip->lock);
+ fip->state = FIP_ST_DISABLED;
+ fcoe_ctlr_reset_fcfs(fip);
+ spin_unlock_bh(&fip->lock);
+ del_timer_sync(&fip->timer);
+ flush_work(&fip->link_work);
}
-#endif /* CONFIG_HOTPLUG_CPU */
+EXPORT_SYMBOL(fcoe_ctlr_destroy);
/**
- * fcoe_rcv() - this is the fcoe receive function called by NET_RX_SOFTIRQ
- * @skb: the receive skb
- * @dev: associated net device
- * @ptype: context
- * @odldev: last device
- *
- * this function will receive the packet and build fc frame and pass it up
+ * fcoe_ctlr_fcoe_size() - Return the maximum FCoE size required for VN_Port.
+ * @fip: FCoE controller.
*
- * Returns: 0 for success
+ * Returns the maximum packet size including the FCoE header and trailer,
+ * but not including any Ethernet or VLAN headers.
*/
-int fcoe_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *ptype, struct net_device *olddev)
+static inline u32 fcoe_ctlr_fcoe_size(struct fcoe_ctlr *fip)
{
- struct fc_lport *lp;
- struct fcoe_rcv_info *fr;
- struct fcoe_softc *fc;
- struct fcoe_dev_stats *stats;
- struct fc_frame_header *fh;
- unsigned short oxid;
- int cpu_idx;
- struct fcoe_percpu_s *fps;
-
- fc = container_of(ptype, struct fcoe_softc, fcoe_packet_type);
- lp = fc->lp;
- if (unlikely(lp == NULL)) {
- FC_DBG("cannot find hba structure");
- goto err2;
- }
-
- if (unlikely(debug_fcoe)) {
- FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p tail:%p "
- "end:%p sum:%d dev:%s", skb->len, skb->data_len,
- skb->head, skb->data, skb_tail_pointer(skb),
- skb_end_pointer(skb), skb->csum,
- skb->dev ? skb->dev->name : "<NULL>");
+ /*
+ * Determine the max FCoE frame size allowed, including
+ * FCoE header and trailer.
+ * Note: lp->mfs is currently the payload size, not the frame size.
+ */
+ return fip->lp->mfs + sizeof(struct fc_frame_header) +
+ sizeof(struct fcoe_hdr) + sizeof(struct fcoe_crc_eof);
+}
- }
+/**
+ * fcoe_ctlr_solicit() - Send a solicitation.
+ * @fip: FCoE controller.
+ * @fcf: Destination FCF. If NULL, a multicast solicitation is sent.
+ */
+static void fcoe_ctlr_solicit(struct fcoe_ctlr *fip, struct fcoe_fcf *fcf)
+{
+ struct sk_buff *skb;
+ struct fip_sol {
+ struct ethhdr eth;
+ struct fip_header fip;
+ struct {
+ struct fip_mac_desc mac;
+ struct fip_wwn_desc wwnn;
+ struct fip_size_desc size;
+ } __attribute__((packed)) desc;
+ } __attribute__((packed)) *sol;
+ u32 fcoe_size;
+
+ skb = dev_alloc_skb(sizeof(*sol));
+ if (!skb)
+ return;
- /* check for FCOE packet type */
- if (unlikely(eth_hdr(skb)->h_proto != htons(ETH_P_FCOE))) {
- FC_DBG("wrong FC type frame");
- goto err;
- }
+ sol = (struct fip_sol *)skb->data;
- /*
- * Check for minimum frame length, and make sure required FCoE
- * and FC headers are pulled into the linear data area.
- */
- if (unlikely((skb->len < FCOE_MIN_FRAME) ||
- !pskb_may_pull(skb, FCOE_HEADER_LEN)))
- goto err;
+ memset(sol, 0, sizeof(*sol));
+ memcpy(sol->eth.h_dest, fcf ? fcf->fcf_mac : fcoe_all_fcfs, ETH_ALEN);
+ memcpy(sol->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
+ sol->eth.h_proto = htons(ETH_P_FIP);
- skb_set_transport_header(skb, sizeof(struct fcoe_hdr));
- fh = (struct fc_frame_header *) skb_transport_header(skb);
+ sol->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
+ sol->fip.fip_op = htons(FIP_OP_DISC);
+ sol->fip.fip_subcode = FIP_SC_SOL;
+ sol->fip.fip_dl_len = htons(sizeof(sol->desc) / FIP_BPW);
+ sol->fip.fip_flags = htons(FIP_FL_FPMA);
- oxid = ntohs(fh->fh_ox_id);
+ sol->desc.mac.fd_desc.fip_dtype = FIP_DT_MAC;
+ sol->desc.mac.fd_desc.fip_dlen = sizeof(sol->desc.mac) / FIP_BPW;
+ memcpy(sol->desc.mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
- fr = fcoe_dev_from_skb(skb);
- fr->fr_dev = lp;
- fr->ptype = ptype;
- cpu_idx = 0;
-#ifdef CONFIG_SMP
- /*
- * The incoming frame exchange id(oxid) is ANDed with num of online
- * cpu bits to get cpu_idx and then this cpu_idx is used for selecting
- * a per cpu kernel thread from fcoe_percpu. In case the cpu is
- * offline or no kernel thread for derived cpu_idx then cpu_idx is
- * initialize to first online cpu index.
- */
- cpu_idx = oxid & (num_online_cpus() - 1);
- if (!fcoe_percpu[cpu_idx] || !cpu_online(cpu_idx))
- cpu_idx = first_cpu(cpu_online_map);
-#endif
- fps = fcoe_percpu[cpu_idx];
+ sol->desc.wwnn.fd_desc.fip_dtype = FIP_DT_NAME;
+ sol->desc.wwnn.fd_desc.fip_dlen = sizeof(sol->desc.wwnn) / FIP_BPW;
+ put_unaligned_be64(fip->lp->wwnn, &sol->desc.wwnn.fd_wwn);
- spin_lock_bh(&fps->fcoe_rx_list.lock);
- __skb_queue_tail(&fps->fcoe_rx_list, skb);
- if (fps->fcoe_rx_list.qlen == 1)
- wake_up_process(fps->thread);
+ fcoe_size = fcoe_ctlr_fcoe_size(fip);
+ sol->desc.size.fd_desc.fip_dtype = FIP_DT_FCOE_SIZE;
+ sol->desc.size.fd_desc.fip_dlen = sizeof(sol->desc.size) / FIP_BPW;
+ sol->desc.size.fd_size = htons(fcoe_size);
- spin_unlock_bh(&fps->fcoe_rx_list.lock);
+ skb_put(skb, sizeof(*sol));
+ skb->protocol = htons(ETH_P_802_3);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
+ fip->send(fip, skb);
- return 0;
-err:
-#ifdef CONFIG_SMP
- stats = lp->dev_stats[smp_processor_id()];
-#else
- stats = lp->dev_stats[0];
-#endif
- if (stats)
- stats->ErrorFrames++;
-
-err2:
- kfree_skb(skb);
- return -1;
+ if (!fcf)
+ fip->sol_time = jiffies;
}
-EXPORT_SYMBOL_GPL(fcoe_rcv);
/**
- * fcoe_start_io() - pass to netdev to start xmit for fcoe
- * @skb: the skb to be xmitted
+ * fcoe_ctlr_link_up() - Start FCoE controller.
+ * @fip: FCoE controller.
*
- * Returns: 0 for success
+ * Called from the LLD when the network link is ready.
*/
-static inline int fcoe_start_io(struct sk_buff *skb)
+void fcoe_ctlr_link_up(struct fcoe_ctlr *fip)
{
- int rc;
-
- skb_get(skb);
- rc = dev_queue_xmit(skb);
- if (rc != 0)
- return rc;
- kfree_skb(skb);
- return 0;
+ spin_lock_bh(&fip->lock);
+ if (fip->state == FIP_ST_NON_FIP || fip->state == FIP_ST_AUTO) {
+ fip->last_link = 1;
+ fip->link = 1;
+ spin_unlock_bh(&fip->lock);
+ fc_linkup(fip->lp);
+ } else if (fip->state == FIP_ST_LINK_WAIT) {
+ fip->state = FIP_ST_AUTO;
+ fip->last_link = 1;
+ fip->link = 1;
+ spin_unlock_bh(&fip->lock);
+ FIP_DBG("%s", "setting AUTO mode.\n");
+ fc_linkup(fip->lp);
+ fcoe_ctlr_solicit(fip, NULL);
+ } else
+ spin_unlock_bh(&fip->lock);
}
+EXPORT_SYMBOL(fcoe_ctlr_link_up);
/**
- * fcoe_get_paged_crc_eof() - in case we need alloc a page for crc_eof
- * @skb: the skb to be xmitted
- * @tlen: total len
+ * fcoe_ctlr_reset() - Reset FIP.
+ * @fip: FCoE controller.
+ * @new_state: FIP state to be entered.
*
- * Returns: 0 for success
+ * Returns non-zero if the link was up and now isn't.
*/
-static int fcoe_get_paged_crc_eof(struct sk_buff *skb, int tlen)
+static int fcoe_ctlr_reset(struct fcoe_ctlr *fip, enum fip_state new_state)
{
- struct fcoe_percpu_s *fps;
- struct page *page;
- int cpu_idx;
-
- cpu_idx = get_cpu();
- fps = fcoe_percpu[cpu_idx];
- page = fps->crc_eof_page;
- if (!page) {
- page = alloc_page(GFP_ATOMIC);
- if (!page) {
- put_cpu();
- return -ENOMEM;
- }
- fps->crc_eof_page = page;
- WARN_ON(fps->crc_eof_offset != 0);
+ struct fc_lport *lp = fip->lp;
+ int link_dropped;
+
+ spin_lock_bh(&fip->lock);
+ fcoe_ctlr_reset_fcfs(fip);
+ del_timer(&fip->timer);
+ fip->state = new_state;
+ fip->ctlr_ka_time = 0;
+ fip->port_ka_time = 0;
+ fip->sol_time = 0;
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ fip->map_dest = 0;
+ fip->last_link = 0;
+ link_dropped = fip->link;
+ fip->link = 0;
+ spin_unlock_bh(&fip->lock);
+
+ if (link_dropped)
+ fc_linkdown(lp);
+
+ if (new_state == FIP_ST_ENABLED) {
+ fcoe_ctlr_solicit(fip, NULL);
+ fc_linkup(lp);
+ link_dropped = 0;
}
-
- get_page(page);
- skb_fill_page_desc(skb, skb_shinfo(skb)->nr_frags, page,
- fps->crc_eof_offset, tlen);
- skb->len += tlen;
- skb->data_len += tlen;
- skb->truesize += tlen;
- fps->crc_eof_offset += sizeof(struct fcoe_crc_eof);
-
- if (fps->crc_eof_offset >= PAGE_SIZE) {
- fps->crc_eof_page = NULL;
- fps->crc_eof_offset = 0;
- put_page(page);
- }
- put_cpu();
- return 0;
+ return link_dropped;
}
/**
- * fcoe_fc_crc() - calculates FC CRC in this fcoe skb
- * @fp: the fc_frame containg data to be checksummed
+ * fcoe_ctlr_link_down() - Stop FCoE controller.
+ * @fip: FCoE controller.
*
- * This uses crc32() to calculate the crc for fc frame
- * Return : 32 bit crc
+ * Returns non-zero if the link was up and now isn't.
+ *
+ * Called from the LLD when the network link is not ready.
+ * There may be multiple calls while the link is down.
*/
-u32 fcoe_fc_crc(struct fc_frame *fp)
+int fcoe_ctlr_link_down(struct fcoe_ctlr *fip)
{
- struct sk_buff *skb = fp_skb(fp);
- struct skb_frag_struct *frag;
- unsigned char *data;
- unsigned long off, len, clen;
- u32 crc;
- unsigned i;
-
- crc = crc32(~0, skb->data, skb_headlen(skb));
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- frag = &skb_shinfo(skb)->frags[i];
- off = frag->page_offset;
- len = frag->size;
- while (len > 0) {
- clen = min(len, PAGE_SIZE - (off & ~PAGE_MASK));
- data = kmap_atomic(frag->page + (off >> PAGE_SHIFT),
- KM_SKB_DATA_SOFTIRQ);
- crc = crc32(crc, data + (off & ~PAGE_MASK), clen);
- kunmap_atomic(data, KM_SKB_DATA_SOFTIRQ);
- off += clen;
- len -= clen;
- }
- }
- return crc;
+ return fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
}
-EXPORT_SYMBOL_GPL(fcoe_fc_crc);
+EXPORT_SYMBOL(fcoe_ctlr_link_down);
/**
- * fcoe_xmit() - FCoE frame transmit function
- * @lp: the associated local port
- * @fp: the fc_frame to be transmitted
+ * fcoe_ctlr_send_keep_alive() - Send a keep-alive to the selected FCF.
+ * @fip: FCoE controller.
+ * @ports: 0 for controller keep-alive, 1 for port keep-alive.
+ * @sa: source MAC address.
*
- * Return : 0 for success
+ * A controller keep-alive is sent every fka_period (typically 8 seconds).
+ * The source MAC is the native MAC address.
+ *
+ * A port keep-alive is sent every 90 seconds while logged in.
+ * The source MAC is the assigned mapped source address.
+ * The destination is the FCF's F-port.
*/
-int fcoe_xmit(struct fc_lport *lp, struct fc_frame *fp)
+static void fcoe_ctlr_send_keep_alive(struct fcoe_ctlr *fip, int ports, u8 *sa)
{
- int wlen, rc = 0;
- u32 crc;
- struct ethhdr *eh;
- struct fcoe_crc_eof *cp;
struct sk_buff *skb;
- struct fcoe_dev_stats *stats;
- struct fc_frame_header *fh;
- unsigned int hlen; /* header length implies the version */
- unsigned int tlen; /* trailer length */
- unsigned int elen; /* eth header, may include vlan */
- int flogi_in_progress = 0;
- struct fcoe_softc *fc;
- u8 sof, eof;
- struct fcoe_hdr *hp;
-
- WARN_ON((fr_len(fp) % sizeof(u32)) != 0);
-
- fc = lport_priv(lp);
- /*
- * if it is a flogi then we need to learn gw-addr
- * and my own fcid
- */
- fh = fc_frame_header_get(fp);
- if (unlikely(fh->fh_r_ctl == FC_RCTL_ELS_REQ)) {
- if (fc_frame_payload_op(fp) == ELS_FLOGI) {
- fc->flogi_oxid = ntohs(fh->fh_ox_id);
- fc->address_mode = FCOE_FCOUI_ADDR_MODE;
- fc->flogi_progress = 1;
- flogi_in_progress = 1;
- } else if (fc->flogi_progress && ntoh24(fh->fh_s_id) != 0) {
- /*
- * Here we must've gotten an SID by accepting an FLOGI
- * from a point-to-point connection. Switch to using
- * the source mac based on the SID. The destination
- * MAC in this case would have been set by receving the
- * FLOGI.
- */
- fc_fcoe_set_mac(fc->data_src_addr, fh->fh_s_id);
- fc->flogi_progress = 0;
- }
- }
-
- skb = fp_skb(fp);
- sof = fr_sof(fp);
- eof = fr_eof(fp);
-
- elen = (fc->real_dev->priv_flags & IFF_802_1Q_VLAN) ?
- sizeof(struct vlan_ethhdr) : sizeof(struct ethhdr);
- hlen = sizeof(struct fcoe_hdr);
- tlen = sizeof(struct fcoe_crc_eof);
- wlen = (skb->len - tlen + sizeof(crc)) / FCOE_WORD_TO_BYTE;
-
- /* crc offload */
- if (likely(lp->crc_offload)) {
- skb->ip_summed = CHECKSUM_PARTIAL;
- skb->csum_start = skb_headroom(skb);
- skb->csum_offset = skb->len;
- crc = 0;
- } else {
- skb->ip_summed = CHECKSUM_NONE;
- crc = fcoe_fc_crc(fp);
- }
+ struct fip_kal {
+ struct ethhdr eth;
+ struct fip_header fip;
+ struct fip_mac_desc mac;
+ } __attribute__((packed)) *kal;
+ struct fip_vn_desc *vn;
+ u32 len;
+ struct fc_lport *lp;
+ struct fcoe_fcf *fcf;
- /* copy fc crc and eof to the skb buff */
- if (skb_is_nonlinear(skb)) {
- skb_frag_t *frag;
- if (fcoe_get_paged_crc_eof(skb, tlen)) {
- kfree_skb(skb);
- return -ENOMEM;
- }
- frag = &skb_shinfo(skb)->frags[skb_shinfo(skb)->nr_frags - 1];
- cp = kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ)
- + frag->page_offset;
- } else {
- cp = (struct fcoe_crc_eof *)skb_put(skb, tlen);
- }
+ fcf = fip->sel_fcf;
+ lp = fip->lp;
+ if (!fcf || !fc_host_port_id(lp->host))
+ return;
- memset(cp, 0, sizeof(*cp));
- cp->fcoe_eof = eof;
- cp->fcoe_crc32 = cpu_to_le32(~crc);
+ len = fcoe_ctlr_fcoe_size(fip) + sizeof(struct ethhdr);
+ BUG_ON(len < sizeof(*kal) + sizeof(*vn));
+ skb = dev_alloc_skb(len);
+ if (!skb)
+ return;
- if (skb_is_nonlinear(skb)) {
- kunmap_atomic(cp, KM_SKB_DATA_SOFTIRQ);
- cp = NULL;
+ kal = (struct fip_kal *)skb->data;
+ memset(kal, 0, len);
+ memcpy(kal->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
+ memcpy(kal->eth.h_source, sa, ETH_ALEN);
+ kal->eth.h_proto = htons(ETH_P_FIP);
+
+ kal->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
+ kal->fip.fip_op = htons(FIP_OP_CTRL);
+ kal->fip.fip_subcode = FIP_SC_KEEP_ALIVE;
+ kal->fip.fip_dl_len = htons((sizeof(kal->mac) +
+ ports * sizeof(*vn)) / FIP_BPW);
+ kal->fip.fip_flags = htons(FIP_FL_FPMA);
+
+ kal->mac.fd_desc.fip_dtype = FIP_DT_MAC;
+ kal->mac.fd_desc.fip_dlen = sizeof(kal->mac) / FIP_BPW;
+ memcpy(kal->mac.fd_mac, fip->ctl_src_addr, ETH_ALEN);
+
+ if (ports) {
+ vn = (struct fip_vn_desc *)(kal + 1);
+ vn->fd_desc.fip_dtype = FIP_DT_VN_ID;
+ vn->fd_desc.fip_dlen = sizeof(*vn) / FIP_BPW;
+ memcpy(vn->fd_mac, fip->data_src_addr, ETH_ALEN);
+ hton24(vn->fd_fc_id, fc_host_port_id(lp->host));
+ put_unaligned_be64(lp->wwpn, &vn->fd_wwpn);
}
- /* adjust skb netowrk/transport offsets to match mac/fcoe/fc */
- skb_push(skb, elen + hlen);
+ skb_put(skb, len);
+ skb->protocol = htons(ETH_P_802_3);
skb_reset_mac_header(skb);
skb_reset_network_header(skb);
- skb->mac_len = elen;
- skb->protocol = htons(ETH_P_FCOE);
- skb->dev = fc->real_dev;
-
- /* fill up mac and fcoe headers */
- eh = eth_hdr(skb);
- eh->h_proto = htons(ETH_P_FCOE);
- if (fc->address_mode == FCOE_FCOUI_ADDR_MODE)
- fc_fcoe_set_mac(eh->h_dest, fh->fh_d_id);
- else
- /* insert GW address */
- memcpy(eh->h_dest, fc->dest_addr, ETH_ALEN);
-
- if (unlikely(flogi_in_progress))
- memcpy(eh->h_source, fc->ctl_src_addr, ETH_ALEN);
- else
- memcpy(eh->h_source, fc->data_src_addr, ETH_ALEN);
-
- hp = (struct fcoe_hdr *)(eh + 1);
- memset(hp, 0, sizeof(*hp));
- if (FC_FCOE_VER)
- FC_FCOE_ENCAPS_VER(hp, FC_FCOE_VER);
- hp->fcoe_sof = sof;
-
-#ifdef NETIF_F_FSO
- /* fcoe lso, mss is in max_payload which is non-zero for FCP data */
- if (lp->seq_offload && fr_max_payload(fp)) {
- skb_shinfo(skb)->gso_type = SKB_GSO_FCOE;
- skb_shinfo(skb)->gso_size = fr_max_payload(fp);
- } else {
- skb_shinfo(skb)->gso_type = 0;
- skb_shinfo(skb)->gso_size = 0;
- }
-#endif
- /* update tx stats: regardless if LLD fails */
- stats = lp->dev_stats[smp_processor_id()];
- if (stats) {
- stats->TxFrames++;
- stats->TxWords += wlen;
- }
-
- /* send down to lld */
- fr_dev(fp) = lp;
- if (fc->fcoe_pending_queue.qlen)
- rc = fcoe_check_wait_queue(lp);
-
- if (rc == 0)
- rc = fcoe_start_io(skb);
-
- if (rc) {
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- __skb_queue_tail(&fc->fcoe_pending_queue, skb);
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- if (fc->fcoe_pending_queue.qlen > FCOE_MAX_QUEUE_DEPTH)
- lp->qfull = 1;
- }
-
- return 0;
+ fip->send(fip, skb);
}
-EXPORT_SYMBOL_GPL(fcoe_xmit);
/**
- * fcoe_percpu_receive_thread() - recv thread per cpu
- * @arg: ptr to the fcoe per cpu struct
+ * fcoe_ctlr_encaps() - Encapsulate an ELS frame for FIP, without sending it.
+ * @fip: FCoE controller.
+ * @dtype: FIP descriptor type for the frame.
+ * @skb: FCoE ELS frame including FC header but no FCoE headers.
+ *
+ * Returns non-zero error code on failure.
+ *
+ * The caller must check that the length is a multiple of 4.
*
- * Return: 0 for success
+ * The @skb must have enough headroom (28 bytes) and tailroom (8 bytes).
+ * Headroom includes the FIP encapsulation description, FIP header, and
+ * Ethernet header. The tailroom is for the FIP MAC descriptor.
*/
-int fcoe_percpu_receive_thread(void *arg)
+static int fcoe_ctlr_encaps(struct fcoe_ctlr *fip,
+ u8 dtype, struct sk_buff *skb)
{
- struct fcoe_percpu_s *p = arg;
- u32 fr_len;
- struct fc_lport *lp;
- struct fcoe_rcv_info *fr;
- struct fcoe_dev_stats *stats;
- struct fc_frame_header *fh;
- struct sk_buff *skb;
- struct fcoe_crc_eof crc_eof;
- struct fc_frame *fp;
- u8 *mac = NULL;
- struct fcoe_softc *fc;
- struct fcoe_hdr *hp;
-
- set_user_nice(current, -20);
-
- while (!kthread_should_stop()) {
-
- spin_lock_bh(&p->fcoe_rx_list.lock);
- while ((skb = __skb_dequeue(&p->fcoe_rx_list)) == NULL) {
- set_current_state(TASK_INTERRUPTIBLE);
- spin_unlock_bh(&p->fcoe_rx_list.lock);
- schedule();
- set_current_state(TASK_RUNNING);
- if (kthread_should_stop())
- return 0;
- spin_lock_bh(&p->fcoe_rx_list.lock);
- }
- spin_unlock_bh(&p->fcoe_rx_list.lock);
- fr = fcoe_dev_from_skb(skb);
- lp = fr->fr_dev;
- if (unlikely(lp == NULL)) {
- FC_DBG("invalid HBA Structure");
- kfree_skb(skb);
- continue;
- }
-
- stats = lp->dev_stats[smp_processor_id()];
-
- if (unlikely(debug_fcoe)) {
- FC_DBG("skb_info: len:%d data_len:%d head:%p data:%p "
- "tail:%p end:%p sum:%d dev:%s",
- skb->len, skb->data_len,
- skb->head, skb->data, skb_tail_pointer(skb),
- skb_end_pointer(skb), skb->csum,
- skb->dev ? skb->dev->name : "<NULL>");
- }
-
- /*
- * Save source MAC address before discarding header.
- */
- fc = lport_priv(lp);
- if (unlikely(fc->flogi_progress))
- mac = eth_hdr(skb)->h_source;
-
- if (skb_is_nonlinear(skb))
- skb_linearize(skb); /* not ideal */
-
- /*
- * Frame length checks and setting up the header pointers
- * was done in fcoe_rcv already.
- */
- hp = (struct fcoe_hdr *) skb_network_header(skb);
- fh = (struct fc_frame_header *) skb_transport_header(skb);
-
- if (unlikely(FC_FCOE_DECAPS_VER(hp) != FC_FCOE_VER)) {
- if (stats) {
- if (stats->ErrorFrames < 5)
- FC_DBG("unknown FCoE version %x",
- FC_FCOE_DECAPS_VER(hp));
- stats->ErrorFrames++;
- }
- kfree_skb(skb);
- continue;
- }
-
- skb_pull(skb, sizeof(struct fcoe_hdr));
- fr_len = skb->len - sizeof(struct fcoe_crc_eof);
-
- if (stats) {
- stats->RxFrames++;
- stats->RxWords += fr_len / FCOE_WORD_TO_BYTE;
- }
-
- fp = (struct fc_frame *)skb;
- fc_frame_init(fp);
- fr_dev(fp) = lp;
- fr_sof(fp) = hp->fcoe_sof;
-
- /* Copy out the CRC and EOF trailer for access */
- if (skb_copy_bits(skb, fr_len, &crc_eof, sizeof(crc_eof))) {
- kfree_skb(skb);
- continue;
- }
- fr_eof(fp) = crc_eof.fcoe_eof;
- fr_crc(fp) = crc_eof.fcoe_crc32;
- if (pskb_trim(skb, fr_len)) {
- kfree_skb(skb);
- continue;
- }
-
- /*
- * We only check CRC if no offload is available and if it is
- * it's solicited data, in which case, the FCP layer would
- * check it during the copy.
- */
- if (lp->crc_offload && skb->ip_summed == CHECKSUM_UNNECESSARY)
- fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
- else
- fr_flags(fp) |= FCPHF_CRC_UNCHECKED;
-
- fh = fc_frame_header_get(fp);
- if (fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA &&
- fh->fh_type == FC_TYPE_FCP) {
- fc_exch_recv(lp, lp->emp, fp);
- continue;
- }
- if (fr_flags(fp) & FCPHF_CRC_UNCHECKED) {
- if (le32_to_cpu(fr_crc(fp)) !=
- ~crc32(~0, skb->data, fr_len)) {
- if (debug_fcoe || stats->InvalidCRCCount < 5)
- printk(KERN_WARNING "fcoe: dropping "
- "frame with CRC error\n");
- stats->InvalidCRCCount++;
- stats->ErrorFrames++;
- fc_frame_free(fp);
- continue;
- }
- fr_flags(fp) &= ~FCPHF_CRC_UNCHECKED;
- }
- /* non flogi and non data exchanges are handled here */
- if (unlikely(fc->flogi_progress))
- fcoe_recv_flogi(fc, fp, mac);
- fc_exch_recv(lp, lp->emp, fp);
- }
+ struct fip_encaps_head {
+ struct ethhdr eth;
+ struct fip_header fip;
+ struct fip_encaps encaps;
+ } __attribute__((packed)) *cap;
+ struct fip_mac_desc *mac;
+ struct fcoe_fcf *fcf;
+ size_t dlen;
+
+ fcf = fip->sel_fcf;
+ if (!fcf)
+ return -ENODEV;
+ dlen = sizeof(struct fip_encaps) + skb->len; /* len before push */
+ cap = (struct fip_encaps_head *)skb_push(skb, sizeof(*cap));
+
+ memset(cap, 0, sizeof(*cap));
+ memcpy(cap->eth.h_dest, fcf->fcf_mac, ETH_ALEN);
+ memcpy(cap->eth.h_source, fip->ctl_src_addr, ETH_ALEN);
+ cap->eth.h_proto = htons(ETH_P_FIP);
+
+ cap->fip.fip_ver = FIP_VER_ENCAPS(FIP_VER);
+ cap->fip.fip_op = htons(FIP_OP_LS);
+ cap->fip.fip_subcode = FIP_SC_REQ;
+ cap->fip.fip_dl_len = htons((dlen + sizeof(*mac)) / FIP_BPW);
+ cap->fip.fip_flags = htons(FIP_FL_FPMA);
+
+ cap->encaps.fd_desc.fip_dtype = dtype;
+ cap->encaps.fd_desc.fip_dlen = dlen / FIP_BPW;
+
+ mac = (struct fip_mac_desc *)skb_put(skb, sizeof(*mac));
+ memset(mac, 0, sizeof(mac));
+ mac->fd_desc.fip_dtype = FIP_DT_MAC;
+ mac->fd_desc.fip_dlen = sizeof(*mac) / FIP_BPW;
+ if (dtype != ELS_FLOGI)
+ memcpy(mac->fd_mac, fip->data_src_addr, ETH_ALEN);
+
+ skb->protocol = htons(ETH_P_802_3);
+ skb_reset_mac_header(skb);
+ skb_reset_network_header(skb);
return 0;
}
/**
- * fcoe_recv_flogi() - flogi receive function
- * @fc: associated fcoe_softc
- * @fp: the recieved frame
- * @sa: the source address of this flogi
+ * fcoe_ctlr_els_send() - Send an ELS frame encapsulated by FIP if appropriate.
+ * @fip: FCoE controller.
+ * @skb: FCoE ELS frame including FC header but no FCoE headers.
*
- * This is responsible to parse the flogi response and sets the corresponding
- * mac address for the initiator, eitehr OUI based or GW based.
+ * Returns a non-zero error code if the frame should not be sent.
+ * Returns zero if the caller should send the frame with FCoE encapsulation.
*
- * Returns: none
+ * The caller must check that the length is a multiple of 4.
+ * The SKB must have enough headroom (28 bytes) and tailroom (8 bytes).
*/
-static void fcoe_recv_flogi(struct fcoe_softc *fc, struct fc_frame *fp, u8 *sa)
+int fcoe_ctlr_els_send(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
struct fc_frame_header *fh;
+ u16 old_xid;
u8 op;
- fh = fc_frame_header_get(fp);
- if (fh->fh_type != FC_TYPE_ELS)
- return;
- op = fc_frame_payload_op(fp);
- if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
- fc->flogi_oxid == ntohs(fh->fh_ox_id)) {
- /*
- * FLOGI accepted.
- * If the src mac addr is FC_OUI-based, then we mark the
- * address_mode flag to use FC_OUI-based Ethernet DA.
- * Otherwise we use the FCoE gateway addr
- */
- if (!compare_ether_addr(sa, (u8[6]) FC_FCOE_FLOGI_MAC)) {
- fc->address_mode = FCOE_FCOUI_ADDR_MODE;
- } else {
- memcpy(fc->dest_addr, sa, ETH_ALEN);
- fc->address_mode = FCOE_GW_ADDR_MODE;
- }
+ if (fip->state == FIP_ST_NON_FIP)
+ return 0;
+ fh = (struct fc_frame_header *)skb->data;
+ op = *(u8 *)(fh + 1);
+
+ switch (op) {
+ case ELS_FLOGI:
+ old_xid = fip->flogi_oxid;
+ fip->flogi_oxid = ntohs(fh->fh_ox_id);
+ if (fip->state == FIP_ST_AUTO) {
+ if (old_xid == FC_XID_UNKNOWN)
+ fip->flogi_count = 0;
+ fip->flogi_count++;
+ if (fip->flogi_count < 3)
+ goto drop;
+ fip->map_dest = 1;
+ return 0;
+ }
+ op = FIP_DT_FLOGI;
+ break;
+ case ELS_FDISC:
+ if (ntoh24(fh->fh_s_id))
+ return 0;
+ op = FIP_DT_FDISC;
+ break;
+ case ELS_LOGO:
+ if (fip->state != FIP_ST_ENABLED)
+ return 0;
+ if (ntoh24(fh->fh_d_id) != FC_FID_FLOGI)
+ return 0;
+ op = FIP_DT_LOGO;
+ break;
+ case ELS_LS_ACC:
+ if (fip->flogi_oxid == FC_XID_UNKNOWN)
+ return 0;
+ if (!ntoh24(fh->fh_s_id))
+ return 0;
+ if (fip->state == FIP_ST_AUTO)
+ return 0;
/*
- * Remove any previously-set unicast MAC filter.
- * Add secondary FCoE MAC address filter for our OUI.
- */
- rtnl_lock();
- if (compare_ether_addr(fc->data_src_addr, (u8[6]) { 0 }))
- dev_unicast_delete(fc->real_dev, fc->data_src_addr,
- ETH_ALEN);
- fc_fcoe_set_mac(fc->data_src_addr, fh->fh_d_id);
- dev_unicast_add(fc->real_dev, fc->data_src_addr, ETH_ALEN);
- rtnl_unlock();
-
- fc->flogi_progress = 0;
- } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
- /*
- * Save source MAC for point-to-point responses.
+ * Here we must've gotten an SID by accepting an FLOGI
+ * from a point-to-point connection. Switch to using
+ * the source mac based on the SID. The destination
+ * MAC in this case would have been set by receving the
+ * FLOGI.
*/
- memcpy(fc->dest_addr, sa, ETH_ALEN);
- fc->address_mode = FCOE_GW_ADDR_MODE;
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ fc_fcoe_set_mac(fip->data_src_addr, fh->fh_s_id);
+ return 0;
+ default:
+ if (fip->state != FIP_ST_ENABLED)
+ goto drop;
+ return 0;
}
+ if (fcoe_ctlr_encaps(fip, op, skb))
+ goto drop;
+ fip->send(fip, skb);
+ return -EINPROGRESS;
+drop:
+ kfree_skb(skb);
+ return -EINVAL;
}
+EXPORT_SYMBOL(fcoe_ctlr_els_send);
-/**
- * fcoe_watchdog() - fcoe timer callback
- * @vp:
+/*
+ * fcoe_ctlr_age_fcfs() - Reset and free all old FCFs for a controller.
+ * @fip: FCoE controller.
*
- * This checks the pending queue length for fcoe and set lport qfull
- * if the FCOE_MAX_QUEUE_DEPTH is reached. This is done for all fc_lport on the
- * fcoe_hostlist.
+ * Called with lock held.
*
- * Returns: 0 for success
+ * An FCF is considered old if we have missed three advertisements.
+ * That is, there have been no valid advertisement from it for three
+ * times its keep-alive period including fuzz.
+ *
+ * In addition, determine the time when an FCF selection can occur.
*/
-void fcoe_watchdog(ulong vp)
+static void fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip)
{
- struct fcoe_softc *fc;
-
- read_lock(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- if (fc->lp)
- fcoe_check_wait_queue(fc->lp);
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf *next;
+ unsigned long sel_time = 0;
+
+ list_for_each_entry_safe(fcf, next, &fip->fcfs, list) {
+ if (time_after(jiffies, fcf->time + fcf->fka_period * 3 +
+ msecs_to_jiffies(FIP_FCF_FUZZ * 3))) {
+ if (fip->sel_fcf == fcf)
+ fip->sel_fcf = NULL;
+ list_del(&fcf->list);
+ WARN_ON(!fip->fcf_count);
+ fip->fcf_count--;
+ kfree(fcf);
+ } else if (fcoe_ctlr_mtu_valid(fcf) &&
+ (!sel_time || time_before(sel_time, fcf->time))) {
+ sel_time = fcf->time;
+ }
+ }
+ if (sel_time) {
+ sel_time += msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+ fip->sel_time = sel_time;
+ if (time_before(sel_time, fip->timer.expires))
+ mod_timer(&fip->timer, sel_time);
+ } else {
+ fip->sel_time = 0;
}
- read_unlock(&fcoe_hostlist_lock);
-
- fcoe_timer.expires = jiffies + (1 * HZ);
- add_timer(&fcoe_timer);
}
-
/**
- * fcoe_check_wait_queue() - put the skb into fcoe pending xmit queue
- * @lp: the fc_port for this skb
- * @skb: the associated skb to be xmitted
+ * fcoe_ctlr_parse_adv() - Decode a FIP advertisement into a new FCF entry.
+ * @skb: received FIP advertisement frame
+ * @fcf: resulting FCF entry.
*
- * This empties the wait_queue, dequeue the head of the wait_queue queue
- * and calls fcoe_start_io() for each packet, if all skb have been
- * transmitted, return qlen or -1 if a error occurs, then restore
- * wait_queue and try again later.
- *
- * The wait_queue is used when the skb transmit fails. skb will go
- * in the wait_queue which will be emptied by the time function OR
- * by the next skb transmit.
- *
- * Returns: 0 for success
+ * Returns zero on a valid parsed advertisement,
+ * otherwise returns non zero value.
*/
-static int fcoe_check_wait_queue(struct fc_lport *lp)
+static int fcoe_ctlr_parse_adv(struct sk_buff *skb, struct fcoe_fcf *fcf)
{
- struct fcoe_softc *fc = lport_priv(lp);
- struct sk_buff *skb;
- int rc = -1;
-
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- if (fc->fcoe_pending_queue_active)
- goto out;
- fc->fcoe_pending_queue_active = 1;
-
- while (fc->fcoe_pending_queue.qlen) {
- /* keep qlen > 0 until fcoe_start_io succeeds */
- fc->fcoe_pending_queue.qlen++;
- skb = __skb_dequeue(&fc->fcoe_pending_queue);
-
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- rc = fcoe_start_io(skb);
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
-
- if (rc) {
- __skb_queue_head(&fc->fcoe_pending_queue, skb);
- /* undo temporary increment above */
- fc->fcoe_pending_queue.qlen--;
+ struct fip_header *fiph;
+ struct fip_desc *desc = NULL;
+ struct fip_wwn_desc *wwn;
+ struct fip_fab_desc *fab;
+ struct fip_fka_desc *fka;
+ unsigned long t;
+ size_t rlen;
+ size_t dlen;
+
+ memset(fcf, 0, sizeof(*fcf));
+ fcf->fka_period = msecs_to_jiffies(FCOE_CTLR_DEF_FKA);
+
+ fiph = (struct fip_header *)skb->data;
+ fcf->flags = ntohs(fiph->fip_flags);
+
+ rlen = ntohs(fiph->fip_dl_len) * 4;
+ if (rlen + sizeof(*fiph) > skb->len)
+ return -EINVAL;
+
+ desc = (struct fip_desc *)(fiph + 1);
+ while (rlen > 0) {
+ dlen = desc->fip_dlen * FIP_BPW;
+ if (dlen < sizeof(*desc) || dlen > rlen)
+ return -EINVAL;
+ switch (desc->fip_dtype) {
+ case FIP_DT_PRI:
+ if (dlen != sizeof(struct fip_pri_desc))
+ goto len_err;
+ fcf->pri = ((struct fip_pri_desc *)desc)->fd_pri;
break;
+ case FIP_DT_MAC:
+ if (dlen != sizeof(struct fip_mac_desc))
+ goto len_err;
+ memcpy(fcf->fcf_mac,
+ ((struct fip_mac_desc *)desc)->fd_mac,
+ ETH_ALEN);
+ if (!is_valid_ether_addr(fcf->fcf_mac)) {
+ FIP_DBG("invalid MAC addr in FIP adv\n");
+ return -EINVAL;
+ }
+ break;
+ case FIP_DT_NAME:
+ if (dlen != sizeof(struct fip_wwn_desc))
+ goto len_err;
+ wwn = (struct fip_wwn_desc *)desc;
+ fcf->switch_name = get_unaligned_be64(&wwn->fd_wwn);
+ break;
+ case FIP_DT_FAB:
+ if (dlen != sizeof(struct fip_fab_desc))
+ goto len_err;
+ fab = (struct fip_fab_desc *)desc;
+ fcf->fabric_name = get_unaligned_be64(&fab->fd_wwn);
+ fcf->vfid = ntohs(fab->fd_vfid);
+ fcf->fc_map = ntoh24(fab->fd_map);
+ break;
+ case FIP_DT_FKA:
+ if (dlen != sizeof(struct fip_fka_desc))
+ goto len_err;
+ fka = (struct fip_fka_desc *)desc;
+ t = ntohl(fka->fd_fka_period);
+ if (t >= FCOE_CTLR_MIN_FKA)
+ fcf->fka_period = msecs_to_jiffies(t);
+ break;
+ case FIP_DT_MAP_OUI:
+ case FIP_DT_FCOE_SIZE:
+ case FIP_DT_FLOGI:
+ case FIP_DT_FDISC:
+ case FIP_DT_LOGO:
+ case FIP_DT_ELP:
+ default:
+ FIP_DBG("unexpected descriptor type %x in FIP adv\n",
+ desc->fip_dtype);
+ /* standard says ignore unknown descriptors >= 128 */
+ if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
+ return -EINVAL;
+ continue;
}
- /* undo temporary increment above */
- fc->fcoe_pending_queue.qlen--;
+ desc = (struct fip_desc *)((char *)desc + dlen);
+ rlen -= dlen;
}
+ if (!fcf->fc_map || (fcf->fc_map & 0x10000))
+ return -EINVAL;
+ if (!fcf->switch_name || !fcf->fabric_name)
+ return -EINVAL;
+ return 0;
- if (fc->fcoe_pending_queue.qlen < FCOE_LOW_QUEUE_DEPTH)
- lp->qfull = 0;
- fc->fcoe_pending_queue_active = 0;
- rc = fc->fcoe_pending_queue.qlen;
-out:
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- return rc;
+len_err:
+ FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+ desc->fip_dtype, dlen);
+ return -EINVAL;
}
/**
- * fcoe_dev_setup() - setup link change notification interface
+ * fcoe_ctlr_recv_adv() - Handle an incoming advertisement.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*/
-static void fcoe_dev_setup()
+static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf new;
+ struct fcoe_fcf *found;
+ unsigned long sol_tov = msecs_to_jiffies(FCOE_CTRL_SOL_TOV);
+ int first = 0;
+ int mtu_valid;
+
+ if (fcoe_ctlr_parse_adv(skb, &new))
+ return;
+
+ spin_lock_bh(&fip->lock);
+ first = list_empty(&fip->fcfs);
+ found = NULL;
+ list_for_each_entry(fcf, &fip->fcfs, list) {
+ if (fcf->switch_name == new.switch_name &&
+ fcf->fabric_name == new.fabric_name &&
+ fcf->fc_map == new.fc_map &&
+ compare_ether_addr(fcf->fcf_mac, new.fcf_mac) == 0) {
+ found = fcf;
+ break;
+ }
+ }
+ if (!found) {
+ if (fip->fcf_count >= FCOE_CTLR_FCF_LIMIT)
+ goto out;
+
+ fcf = kmalloc(sizeof(*fcf), GFP_ATOMIC);
+ if (!fcf)
+ goto out;
+
+ fip->fcf_count++;
+ memcpy(fcf, &new, sizeof(new));
+ list_add(&fcf->list, &fip->fcfs);
+ } else {
+ /*
+ * Flags in advertisements are ignored once the FCF is
+ * selected. Flags in unsolicited advertisements are
+ * ignored after a usable solicited advertisement
+ * has been received.
+ */
+ if (fcf == fip->sel_fcf) {
+ fip->ctlr_ka_time -= fcf->fka_period;
+ fip->ctlr_ka_time += new.fka_period;
+ if (time_before(fip->ctlr_ka_time, fip->timer.expires))
+ mod_timer(&fip->timer, fip->ctlr_ka_time);
+ } else if (!fcoe_ctlr_fcf_usable(fcf))
+ fcf->flags = new.flags;
+ fcf->fka_period = new.fka_period;
+ memcpy(fcf->fcf_mac, new.fcf_mac, ETH_ALEN);
+ }
+ mtu_valid = fcoe_ctlr_mtu_valid(fcf);
+ fcf->time = jiffies;
+ FIP_DBG_LVL(found ? 2 : 1, "%s FCF for fab %llx map %x val %d\n",
+ found ? "old" : "new",
+ fcf->fabric_name, fcf->fc_map, mtu_valid);
+
/*
- * here setup a interface specific wd time to
- * monitor the link state
+ * If this advertisement is not solicited and our max receive size
+ * hasn't been verified, send a solicited advertisement.
*/
- register_netdevice_notifier(&fcoe_notifier);
-}
+ if (!mtu_valid)
+ fcoe_ctlr_solicit(fip, fcf);
-/**
- * fcoe_dev_setup() - cleanup link change notification interface
- */
-static void fcoe_dev_cleanup(void)
-{
- unregister_netdevice_notifier(&fcoe_notifier);
+ /*
+ * If its been a while since we did a solicit, and this is
+ * the first advertisement we've received, do a multicast
+ * solicitation to gather as many advertisements as we can
+ * before selection occurs.
+ */
+ if (first && time_after(jiffies, fip->sol_time + sol_tov))
+ fcoe_ctlr_solicit(fip, NULL);
+
+ /*
+ * If this is the first validated FCF, note the time and
+ * set a timer to trigger selection.
+ */
+ if (mtu_valid && !fip->sel_time && fcoe_ctlr_fcf_usable(fcf)) {
+ fip->sel_time = jiffies +
+ msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+ if (!timer_pending(&fip->timer) ||
+ time_before(fip->sel_time, fip->timer.expires))
+ mod_timer(&fip->timer, fip->sel_time);
+ }
+out:
+ spin_unlock_bh(&fip->lock);
}
/**
- * fcoe_device_notification() - netdev event notification callback
- * @notifier: context of the notification
- * @event: type of event
- * @ptr: fixed array for output parsed ifname
- *
- * This function is called by the ethernet driver in case of link change event
- *
- * Returns: 0 for success
+ * fcoe_ctlr_recv_els() - Handle an incoming FIP-encapsulated ELS frame.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*/
-static int fcoe_device_notification(struct notifier_block *notifier,
- ulong event, void *ptr)
+static void fcoe_ctlr_recv_els(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
- struct fc_lport *lp = NULL;
- struct net_device *real_dev = ptr;
- struct fcoe_softc *fc;
+ struct fc_lport *lp = fip->lp;
+ struct fip_header *fiph;
+ struct fc_frame *fp;
+ struct fc_frame_header *fh = NULL;
+ struct fip_desc *desc;
+ struct fip_encaps *els;
struct fcoe_dev_stats *stats;
- u32 new_link_up;
- u32 mfs;
- int rc = NOTIFY_OK;
-
- read_lock(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- if (fc->real_dev == real_dev) {
- lp = fc->lp;
+ enum fip_desc_type els_dtype = 0;
+ u8 els_op;
+ u8 sub;
+ u8 granted_mac[ETH_ALEN] = { 0 };
+ size_t els_len = 0;
+ size_t rlen;
+ size_t dlen;
+
+ fiph = (struct fip_header *)skb->data;
+ sub = fiph->fip_subcode;
+ if (sub != FIP_SC_REQ && sub != FIP_SC_REP)
+ goto drop;
+
+ rlen = ntohs(fiph->fip_dl_len) * 4;
+ if (rlen + sizeof(*fiph) > skb->len)
+ goto drop;
+
+ desc = (struct fip_desc *)(fiph + 1);
+ while (rlen > 0) {
+ dlen = desc->fip_dlen * FIP_BPW;
+ if (dlen < sizeof(*desc) || dlen > rlen)
+ goto drop;
+ switch (desc->fip_dtype) {
+ case FIP_DT_MAC:
+ if (dlen != sizeof(struct fip_mac_desc))
+ goto len_err;
+ memcpy(granted_mac,
+ ((struct fip_mac_desc *)desc)->fd_mac,
+ ETH_ALEN);
+ if (!is_valid_ether_addr(granted_mac)) {
+ FIP_DBG("invalid MAC addrs in FIP ELS\n");
+ goto drop;
+ }
break;
+ case FIP_DT_FLOGI:
+ case FIP_DT_FDISC:
+ case FIP_DT_LOGO:
+ case FIP_DT_ELP:
+ if (fh)
+ goto drop;
+ if (dlen < sizeof(*els) + sizeof(*fh) + 1)
+ goto len_err;
+ els_len = dlen - sizeof(*els);
+ els = (struct fip_encaps *)desc;
+ fh = (struct fc_frame_header *)(els + 1);
+ els_dtype = desc->fip_dtype;
+ break;
+ default:
+ FIP_DBG("unexpected descriptor type %x "
+ "in FIP adv\n", desc->fip_dtype);
+ /* standard says ignore unknown descriptors >= 128 */
+ if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
+ goto drop;
+ continue;
}
- }
- read_unlock(&fcoe_hostlist_lock);
- if (lp == NULL) {
- rc = NOTIFY_DONE;
- goto out;
+ desc = (struct fip_desc *)((char *)desc + dlen);
+ rlen -= dlen;
}
- new_link_up = lp->link_up;
- switch (event) {
- case NETDEV_DOWN:
- case NETDEV_GOING_DOWN:
- new_link_up = 0;
- break;
- case NETDEV_UP:
- case NETDEV_CHANGE:
- new_link_up = !fcoe_link_ok(lp);
- break;
- case NETDEV_CHANGEMTU:
- mfs = fc->real_dev->mtu -
- (sizeof(struct fcoe_hdr) +
- sizeof(struct fcoe_crc_eof));
- if (mfs >= FC_MIN_MAX_FRAME)
- fc_set_mfs(lp, mfs);
- new_link_up = !fcoe_link_ok(lp);
- break;
- case NETDEV_REGISTER:
- break;
- default:
- FC_DBG("unknown event %ld call", event);
- }
- if (lp->link_up != new_link_up) {
- if (new_link_up)
- fc_linkup(lp);
- else {
- stats = lp->dev_stats[smp_processor_id()];
- if (stats)
- stats->LinkFailureCount++;
- fc_linkdown(lp);
- fcoe_clean_pending_queue(lp);
- }
- }
-out:
- return rc;
-}
+ if (!fh)
+ goto drop;
+ els_op = *(u8 *)(fh + 1);
-/**
- * fcoe_if_to_netdev() - parse a name buffer to get netdev
- * @ifname: fixed array for output parsed ifname
- * @buffer: incoming buffer to be copied
- *
- * Returns: NULL or ptr to netdeive
- */
-static struct net_device *fcoe_if_to_netdev(const char *buffer)
-{
- char *cp;
- char ifname[IFNAMSIZ + 2];
-
- if (buffer) {
- strlcpy(ifname, buffer, IFNAMSIZ);
- cp = ifname + strlen(ifname);
- while (--cp >= ifname && *cp == '\n')
- *cp = '\0';
- return dev_get_by_name(&init_net, ifname);
+ if (els_dtype == FIP_DT_FLOGI && sub == FIP_SC_REP &&
+ fip->flogi_oxid == ntohs(fh->fh_ox_id) &&
+ els_op == ELS_LS_ACC && is_valid_ether_addr(granted_mac)) {
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ fip->update_mac(fip, fip->data_src_addr, granted_mac);
+ memcpy(fip->data_src_addr, granted_mac, ETH_ALEN);
}
- return NULL;
+
+ /*
+ * Convert skb into an fc_frame containing only the ELS.
+ */
+ skb_pull(skb, (u8 *)fh - skb->data);
+ skb_trim(skb, els_len);
+ fp = (struct fc_frame *)skb;
+ fc_frame_init(fp);
+ fr_sof(fp) = FC_SOF_I3;
+ fr_eof(fp) = FC_EOF_T;
+ fr_dev(fp) = lp;
+
+ stats = fc_lport_get_stats(lp);
+ stats->RxFrames++;
+ stats->RxWords += skb->len / FIP_BPW;
+
+ fc_exch_recv(lp, lp->emp, fp);
+ return;
+
+len_err:
+ FIP_DBG("FIP length error in descriptor type %x len %zu\n",
+ desc->fip_dtype, dlen);
+drop:
+ kfree_skb(skb);
}
/**
- * fcoe_netdev_to_module_owner() - finds out the nic drive moddule of the netdev
- * @netdev: the target netdev
+ * fcoe_ctlr_recv_els() - Handle an incoming link reset frame.
+ * @fip: FCoE controller.
+ * @fh: Received FIP header.
*
- * Returns: ptr to the struct module, NULL for failure
+ * There may be multiple VN_Port descriptors.
+ * The overall length has already been checked.
*/
-static struct module *
-fcoe_netdev_to_module_owner(const struct net_device *netdev)
+static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip,
+ struct fip_header *fh)
{
- struct device *dev;
-
- if (!netdev)
- return NULL;
-
- dev = netdev->dev.parent;
- if (!dev)
- return NULL;
+ struct fip_desc *desc;
+ struct fip_mac_desc *mp;
+ struct fip_wwn_desc *wp;
+ struct fip_vn_desc *vp;
+ size_t rlen;
+ size_t dlen;
+ struct fcoe_fcf *fcf = fip->sel_fcf;
+ struct fc_lport *lp = fip->lp;
+ u32 desc_mask;
+
+ FIP_DBG("Clear Virtual Link received\n");
+ if (!fcf)
+ return;
+ if (!fcf || !fc_host_port_id(lp->host))
+ return;
- if (!dev->driver)
- return NULL;
+ /*
+ * mask of required descriptors. Validating each one clears its bit.
+ */
+ desc_mask = BIT(FIP_DT_MAC) | BIT(FIP_DT_NAME) | BIT(FIP_DT_VN_ID);
+
+ rlen = ntohs(fh->fip_dl_len) * FIP_BPW;
+ desc = (struct fip_desc *)(fh + 1);
+ while (rlen >= sizeof(*desc)) {
+ dlen = desc->fip_dlen * FIP_BPW;
+ if (dlen > rlen)
+ return;
+ switch (desc->fip_dtype) {
+ case FIP_DT_MAC:
+ mp = (struct fip_mac_desc *)desc;
+ if (dlen < sizeof(*mp))
+ return;
+ if (compare_ether_addr(mp->fd_mac, fcf->fcf_mac))
+ return;
+ desc_mask &= ~BIT(FIP_DT_MAC);
+ break;
+ case FIP_DT_NAME:
+ wp = (struct fip_wwn_desc *)desc;
+ if (dlen < sizeof(*wp))
+ return;
+ if (get_unaligned_be64(&wp->fd_wwn) != fcf->switch_name)
+ return;
+ desc_mask &= ~BIT(FIP_DT_NAME);
+ break;
+ case FIP_DT_VN_ID:
+ vp = (struct fip_vn_desc *)desc;
+ if (dlen < sizeof(*vp))
+ return;
+ if (compare_ether_addr(vp->fd_mac,
+ fip->data_src_addr) == 0 &&
+ get_unaligned_be64(&vp->fd_wwpn) == lp->wwpn &&
+ ntoh24(vp->fd_fc_id) == fc_host_port_id(lp->host))
+ desc_mask &= ~BIT(FIP_DT_VN_ID);
+ break;
+ default:
+ /* standard says ignore unknown descriptors >= 128 */
+ if (desc->fip_dtype < FIP_DT_VENDOR_BASE)
+ return;
+ break;
+ }
+ desc = (struct fip_desc *)((char *)desc + dlen);
+ rlen -= dlen;
+ }
- return dev->driver->owner;
+ /*
+ * reset only if all required descriptors were present and valid.
+ */
+ if (desc_mask) {
+ FIP_DBG("missing descriptors mask %x\n", desc_mask);
+ } else {
+ FIP_DBG("performing Clear Virtual Link\n");
+ fcoe_ctlr_reset(fip, FIP_ST_ENABLED);
+ }
}
/**
- * fcoe_ethdrv_get() - Hold the Ethernet driver
- * @netdev: the target netdev
+ * fcoe_ctlr_recv() - Receive a FIP frame.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*
- * Holds the Ethernet driver module by try_module_get() for
- * the corresponding netdev.
- *
- * Returns: 0 for succsss
+ * This is called from NET_RX_SOFTIRQ.
*/
-static int fcoe_ethdrv_get(const struct net_device *netdev)
+void fcoe_ctlr_recv(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
- struct module *owner;
-
- owner = fcoe_netdev_to_module_owner(netdev);
- if (owner) {
- printk(KERN_DEBUG "fcoe:hold driver module %s for %s\n",
- module_name(owner), netdev->name);
- return try_module_get(owner);
- }
- return -ENODEV;
+ spin_lock_bh(&fip->fip_recv_list.lock);
+ __skb_queue_tail(&fip->fip_recv_list, skb);
+ spin_unlock_bh(&fip->fip_recv_list.lock);
+ schedule_work(&fip->recv_work);
}
+EXPORT_SYMBOL(fcoe_ctlr_recv);
/**
- * fcoe_ethdrv_put() - Release the Ethernet driver
- * @netdev: the target netdev
+ * fcoe_ctlr_recv_handler() - Receive a FIP frame.
+ * @fip: FCoE controller.
+ * @skb: Received FIP packet.
*
- * Releases the Ethernet driver module by module_put for
- * the corresponding netdev.
- *
- * Returns: 0 for succsss
+ * Returns non-zero if the frame is dropped.
*/
-static int fcoe_ethdrv_put(const struct net_device *netdev)
+static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb)
{
- struct module *owner;
+ struct fip_header *fiph;
+ struct ethhdr *eh;
+ enum fip_state state;
+ u16 op;
+ u8 sub;
+
+ if (skb_linearize(skb))
+ goto drop;
+ if (skb->len < sizeof(*fiph))
+ goto drop;
+ eh = eth_hdr(skb);
+ if (compare_ether_addr(eh->h_dest, fip->ctl_src_addr) &&
+ compare_ether_addr(eh->h_dest, FIP_ALL_ENODE_MACS))
+ goto drop;
+ fiph = (struct fip_header *)skb->data;
+ op = ntohs(fiph->fip_op);
+ sub = fiph->fip_subcode;
+
+ FIP_DBG_LVL(2, "ver %x op %x/%x dl %x fl %x\n",
+ FIP_VER_DECAPS(fiph->fip_ver), op, sub,
+ ntohs(fiph->fip_dl_len), ntohs(fiph->fip_flags));
+
+ if (FIP_VER_DECAPS(fiph->fip_ver) != FIP_VER)
+ goto drop;
+ if (ntohs(fiph->fip_dl_len) * FIP_BPW + sizeof(*fiph) > skb->len)
+ goto drop;
+
+ spin_lock_bh(&fip->lock);
+ state = fip->state;
+ if (state == FIP_ST_AUTO) {
+ fip->map_dest = 0;
+ fip->state = FIP_ST_ENABLED;
+ state = FIP_ST_ENABLED;
+ FIP_DBG("using FIP mode\n");
+ }
+ spin_unlock_bh(&fip->lock);
+ if (state != FIP_ST_ENABLED)
+ goto drop;
- owner = fcoe_netdev_to_module_owner(netdev);
- if (owner) {
- printk(KERN_DEBUG "fcoe:release driver module %s for %s\n",
- module_name(owner), netdev->name);
- module_put(owner);
+ if (op == FIP_OP_LS) {
+ fcoe_ctlr_recv_els(fip, skb); /* consumes skb */
return 0;
}
- return -ENODEV;
+ if (op == FIP_OP_DISC && sub == FIP_SC_ADV)
+ fcoe_ctlr_recv_adv(fip, skb);
+ else if (op == FIP_OP_CTRL && sub == FIP_SC_CLR_VLINK)
+ fcoe_ctlr_recv_clr_vlink(fip, fiph);
+ kfree_skb(skb);
+ return 0;
+drop:
+ kfree_skb(skb);
+ return -1;
}
/**
- * fcoe_destroy() - handles the destroy from sysfs
- * @buffer: expcted to be a eth if name
- * @kp: associated kernel param
+ * fcoe_ctlr_select() - Select the best FCF, if possible.
+ * @fip: FCoE controller.
+ *
+ * If there are conflicting advertisements, no FCF can be chosen.
*
- * Returns: 0 for success
+ * Called with lock held.
*/
-static int fcoe_destroy(const char *buffer, struct kernel_param *kp)
+static void fcoe_ctlr_select(struct fcoe_ctlr *fip)
{
- int rc;
- struct net_device *netdev;
-
- netdev = fcoe_if_to_netdev(buffer);
- if (!netdev) {
- rc = -ENODEV;
- goto out_nodev;
- }
- /* look for existing lport */
- if (!fcoe_hostlist_lookup(netdev)) {
- rc = -ENODEV;
- goto out_putdev;
- }
- /* pass to transport */
- rc = fcoe_transport_release(netdev);
- if (rc) {
- printk(KERN_ERR "fcoe: fcoe_transport_release(%s) failed\n",
- netdev->name);
- rc = -EIO;
- goto out_putdev;
+ struct fcoe_fcf *fcf;
+ struct fcoe_fcf *best = NULL;
+
+ list_for_each_entry(fcf, &fip->fcfs, list) {
+ FIP_DBG("consider FCF for fab %llx VFID %d map %x val %d\n",
+ fcf->fabric_name, fcf->vfid,
+ fcf->fc_map, fcoe_ctlr_mtu_valid(fcf));
+ if (!fcoe_ctlr_fcf_usable(fcf)) {
+ FIP_DBG("FCF for fab %llx map %x %svalid %savailable\n",
+ fcf->fabric_name, fcf->fc_map,
+ (fcf->flags & FIP_FL_SOL) ? "" : "in",
+ (fcf->flags & FIP_FL_AVAIL) ? "" : "un");
+ continue;
+ }
+ if (!best) {
+ best = fcf;
+ continue;
+ }
+ if (fcf->fabric_name != best->fabric_name ||
+ fcf->vfid != best->vfid ||
+ fcf->fc_map != best->fc_map) {
+ FIP_DBG("conflicting fabric, VFID, or FC-MAP\n");
+ return;
+ }
+ if (fcf->pri < best->pri)
+ best = fcf;
}
- fcoe_ethdrv_put(netdev);
- rc = 0;
-out_putdev:
- dev_put(netdev);
-out_nodev:
- return rc;
+ fip->sel_fcf = best;
}
/**
- * fcoe_create() - Handles the create call from sysfs
- * @buffer: expcted to be a eth if name
- * @kp: associated kernel param
+ * fcoe_ctlr_timeout() - FIP timer function.
+ * @arg: &fcoe_ctlr pointer.
*
- * Returns: 0 for success
+ * Ages FCFs. Triggers FCF selection if possible. Sends keep-alives.
*/
-static int fcoe_create(const char *buffer, struct kernel_param *kp)
+static void fcoe_ctlr_timeout(unsigned long arg)
{
- int rc;
- struct net_device *netdev;
-
- netdev = fcoe_if_to_netdev(buffer);
- if (!netdev) {
- rc = -ENODEV;
- goto out_nodev;
+ struct fcoe_ctlr *fip = (struct fcoe_ctlr *)arg;
+ struct fcoe_fcf *sel;
+ struct fcoe_fcf *fcf;
+ unsigned long next_timer = jiffies + msecs_to_jiffies(FIP_VN_KA_PERIOD);
+ DECLARE_MAC_BUF(buf);
+ u8 send_ctlr_ka;
+ u8 send_port_ka;
+
+ spin_lock_bh(&fip->lock);
+ if (fip->state == FIP_ST_DISABLED) {
+ spin_unlock_bh(&fip->lock);
+ return;
}
- /* look for existing lport */
- if (fcoe_hostlist_lookup(netdev)) {
- rc = -EEXIST;
- goto out_putdev;
+
+ fcf = fip->sel_fcf;
+ fcoe_ctlr_age_fcfs(fip);
+
+ sel = fip->sel_fcf;
+ if (!sel && fip->sel_time && time_after_eq(jiffies, fip->sel_time)) {
+ fcoe_ctlr_select(fip);
+ sel = fip->sel_fcf;
+ fip->sel_time = 0;
}
- fcoe_ethdrv_get(netdev);
-
- /* pass to transport */
- rc = fcoe_transport_attach(netdev);
- if (rc) {
- printk(KERN_ERR "fcoe: fcoe_transport_attach(%s) failed\n",
- netdev->name);
- fcoe_ethdrv_put(netdev);
- rc = -EIO;
- goto out_putdev;
+
+ if (sel != fcf) {
+ fcf = sel; /* the old FCF may have been freed */
+ if (sel) {
+ printk(KERN_INFO "host%d: FIP selected "
+ "Fibre-Channel Forwarder MAC %s\n",
+ fip->lp->host->host_no,
+ print_mac(buf, sel->fcf_mac));
+ memcpy(fip->dest_addr, sel->fcf_mac, ETH_ALEN);
+ fip->port_ka_time = jiffies +
+ msecs_to_jiffies(FIP_VN_KA_PERIOD);
+ fip->ctlr_ka_time = jiffies + sel->fka_period;
+ fip->link = 1;
+ } else {
+ printk(KERN_NOTICE "host%d: "
+ "FIP Fibre-Channel Forwarder timed out. "
+ "Starting FCF discovery.\n",
+ fip->lp->host->host_no);
+ fip->link = 0;
+ }
+ schedule_work(&fip->link_work);
}
- rc = 0;
-out_putdev:
- dev_put(netdev);
-out_nodev:
- return rc;
-}
-module_param_call(create, fcoe_create, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(create, "string");
-MODULE_PARM_DESC(create, "Create fcoe port using net device passed in.");
-module_param_call(destroy, fcoe_destroy, NULL, NULL, S_IWUSR);
-__MODULE_PARM_TYPE(destroy, "string");
-MODULE_PARM_DESC(destroy, "Destroy fcoe port");
+ send_ctlr_ka = 0;
+ send_port_ka = 0;
+ if (sel) {
+ if (time_after_eq(jiffies, fip->ctlr_ka_time)) {
+ fip->ctlr_ka_time = jiffies + sel->fka_period;
+ send_ctlr_ka = 1;
+ }
+ if (time_after(next_timer, fip->ctlr_ka_time))
+ next_timer = fip->ctlr_ka_time;
-/**
- * fcoe_link_ok() - Check if link is ok for the fc_lport
- * @lp: ptr to the fc_lport
- *
- * Any permanently-disqualifying conditions have been previously checked.
- * This also updates the speed setting, which may change with link for 100/1000.
- *
- * This function should probably be checking for PAUSE support at some point
- * in the future. Currently Per-priority-pause is not determinable using
- * ethtool, so we shouldn't be restrictive until that problem is resolved.
- *
- * Returns: 0 if link is OK for use by FCoE.
- *
- */
-int fcoe_link_ok(struct fc_lport *lp)
-{
- struct fcoe_softc *fc = lport_priv(lp);
- struct net_device *dev = fc->real_dev;
- struct ethtool_cmd ecmd = { ETHTOOL_GSET };
- int rc = 0;
-
- if ((dev->flags & IFF_UP) && netif_carrier_ok(dev)) {
- dev = fc->phys_dev;
- if (dev->ethtool_ops->get_settings) {
- dev->ethtool_ops->get_settings(dev, &ecmd);
- lp->link_supported_speeds &=
- ~(FC_PORTSPEED_1GBIT | FC_PORTSPEED_10GBIT);
- if (ecmd.supported & (SUPPORTED_1000baseT_Half |
- SUPPORTED_1000baseT_Full))
- lp->link_supported_speeds |= FC_PORTSPEED_1GBIT;
- if (ecmd.supported & SUPPORTED_10000baseT_Full)
- lp->link_supported_speeds |=
- FC_PORTSPEED_10GBIT;
- if (ecmd.speed == SPEED_1000)
- lp->link_speed = FC_PORTSPEED_1GBIT;
- if (ecmd.speed == SPEED_10000)
- lp->link_speed = FC_PORTSPEED_10GBIT;
+ if (time_after_eq(jiffies, fip->port_ka_time)) {
+ fip->port_ka_time += jiffies +
+ msecs_to_jiffies(FIP_VN_KA_PERIOD);
+ send_port_ka = 1;
}
- } else
- rc = -1;
+ if (time_after(next_timer, fip->port_ka_time))
+ next_timer = fip->port_ka_time;
+ mod_timer(&fip->timer, next_timer);
+ } else if (fip->sel_time) {
+ next_timer = fip->sel_time +
+ msecs_to_jiffies(FCOE_CTLR_START_DELAY);
+ mod_timer(&fip->timer, next_timer);
+ }
+ spin_unlock_bh(&fip->lock);
- return rc;
+ if (send_ctlr_ka)
+ fcoe_ctlr_send_keep_alive(fip, 0, fip->ctl_src_addr);
+ if (send_port_ka)
+ fcoe_ctlr_send_keep_alive(fip, 1, fip->data_src_addr);
}
-EXPORT_SYMBOL_GPL(fcoe_link_ok);
/**
- * fcoe_percpu_clean() - Clear the pending skbs for an lport
- * @lp: the fc_lport
+ * fcoe_ctlr_link_work() - worker thread function for link changes.
+ * @work: pointer to link_work member inside &fcoe_ctlr.
+ *
+ * See if the link status has changed and if so, report it.
+ *
+ * This is here because fc_linkup() and fc_linkdown() must not
+ * be called from the timer directly, since they use a mutex.
*/
-void fcoe_percpu_clean(struct fc_lport *lp)
+static void fcoe_ctlr_link_work(struct work_struct *work)
{
- int idx;
- struct fcoe_percpu_s *pp;
- struct fcoe_rcv_info *fr;
- struct sk_buff_head *list;
- struct sk_buff *skb, *next;
- struct sk_buff *head;
-
- for (idx = 0; idx < NR_CPUS; idx++) {
- if (fcoe_percpu[idx]) {
- pp = fcoe_percpu[idx];
- spin_lock_bh(&pp->fcoe_rx_list.lock);
- list = &pp->fcoe_rx_list;
- head = list->next;
- for (skb = head; skb != (struct sk_buff *)list;
- skb = next) {
- next = skb->next;
- fr = fcoe_dev_from_skb(skb);
- if (fr->fr_dev == lp) {
- __skb_unlink(skb, list);
- kfree_skb(skb);
- }
- }
- spin_unlock_bh(&pp->fcoe_rx_list.lock);
- }
+ struct fcoe_ctlr *fip;
+ int link;
+ int last_link;
+
+ fip = container_of(work, struct fcoe_ctlr, link_work);
+ spin_lock_bh(&fip->lock);
+ last_link = fip->last_link;
+ link = fip->link;
+ fip->last_link = link;
+ spin_unlock_bh(&fip->lock);
+
+ if (last_link != link) {
+ if (link)
+ fc_linkup(fip->lp);
+ else
+ fcoe_ctlr_reset(fip, FIP_ST_LINK_WAIT);
}
}
-EXPORT_SYMBOL_GPL(fcoe_percpu_clean);
/**
- * fcoe_clean_pending_queue() - Dequeue a skb and free it
- * @lp: the corresponding fc_lport
- *
- * Returns: none
+ * fcoe_ctlr_recv_work() - Worker thread function for receiving FIP frames.
+ * @recv_work: pointer to recv_work member inside &fcoe_ctlr.
*/
-void fcoe_clean_pending_queue(struct fc_lport *lp)
+static void fcoe_ctlr_recv_work(struct work_struct *recv_work)
{
- struct fcoe_softc *fc = lport_priv(lp);
+ struct fcoe_ctlr *fip;
struct sk_buff *skb;
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
- while ((skb = __skb_dequeue(&fc->fcoe_pending_queue)) != NULL) {
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
- kfree_skb(skb);
- spin_lock_bh(&fc->fcoe_pending_queue.lock);
+ fip = container_of(recv_work, struct fcoe_ctlr, recv_work);
+ spin_lock_bh(&fip->fip_recv_list.lock);
+ while ((skb = __skb_dequeue(&fip->fip_recv_list))) {
+ spin_unlock_bh(&fip->fip_recv_list.lock);
+ fcoe_ctlr_recv_handler(fip, skb);
+ spin_lock_bh(&fip->fip_recv_list.lock);
}
- spin_unlock_bh(&fc->fcoe_pending_queue.lock);
+ spin_unlock_bh(&fip->fip_recv_list.lock);
}
-EXPORT_SYMBOL_GPL(fcoe_clean_pending_queue);
/**
- * libfc_host_alloc() - Allocate a Scsi_Host with room for the fc_lport
- * @sht: ptr to the scsi host templ
- * @priv_size: size of private data after fc_lport
+ * fcoe_ctlr_recv_flogi() - snoop Pre-FIP receipt of FLOGI response or request.
+ * @fip: FCoE controller.
+ * @fp: FC frame.
+ * @sa: Ethernet source MAC address from received FCoE frame.
*
- * Returns: ptr to Scsi_Host
- * TODO: to libfc?
- */
-static inline struct Scsi_Host *
-libfc_host_alloc(struct scsi_host_template *sht, int priv_size)
-{
- return scsi_host_alloc(sht, sizeof(struct fc_lport) + priv_size);
-}
-
-/**
- * fcoe_host_alloc() - Allocate a Scsi_Host with room for the fcoe_softc
- * @sht: ptr to the scsi host templ
- * @priv_size: size of private data after fc_lport
+ * Snoop potential response to FLOGI or even incoming FLOGI.
*
- * Returns: ptr to Scsi_Host
- */
-struct Scsi_Host *fcoe_host_alloc(struct scsi_host_template *sht, int priv_size)
-{
- return libfc_host_alloc(sht, sizeof(struct fcoe_softc) + priv_size);
-}
-EXPORT_SYMBOL_GPL(fcoe_host_alloc);
-
-/**
- * fcoe_reset() - Resets the fcoe
- * @shost: shost the reset is from
+ * The caller has checked that we are waiting for login as indicated
+ * by fip->flogi_oxid != FC_XID_UNKNOWN.
+ *
+ * The caller is responsible for freeing the frame.
*
- * Returns: always 0
+ * Return non-zero if the frame should not be delivered to libfc.
*/
-int fcoe_reset(struct Scsi_Host *shost)
+int fcoe_ctlr_recv_flogi(struct fcoe_ctlr *fip, struct fc_frame *fp, u8 *sa)
{
- struct fc_lport *lport = shost_priv(shost);
- fc_lport_reset(lport);
+ struct fc_frame_header *fh;
+ u8 op;
+ u8 mac[ETH_ALEN];
+
+ fh = fc_frame_header_get(fp);
+ if (fh->fh_type != FC_TYPE_ELS)
+ return 0;
+
+ op = fc_frame_payload_op(fp);
+ if (op == ELS_LS_ACC && fh->fh_r_ctl == FC_RCTL_ELS_REP &&
+ fip->flogi_oxid == ntohs(fh->fh_ox_id)) {
+
+ spin_lock_bh(&fip->lock);
+ if (fip->state != FIP_ST_AUTO && fip->state != FIP_ST_NON_FIP) {
+ spin_unlock_bh(&fip->lock);
+ return -EINVAL;
+ }
+ fip->state = FIP_ST_NON_FIP;
+ FIP_DBG("received FLOGI LS_ACC using non-FIP mode\n");
+
+ /*
+ * FLOGI accepted.
+ * If the src mac addr is FC_OUI-based, then we mark the
+ * address_mode flag to use FC_OUI-based Ethernet DA.
+ * Otherwise we use the FCoE gateway addr
+ */
+ if (!compare_ether_addr(sa, (u8[6])FC_FCOE_FLOGI_MAC)) {
+ fip->map_dest = 1;
+ } else {
+ memcpy(fip->dest_addr, sa, ETH_ALEN);
+ fip->map_dest = 0;
+ }
+ fip->flogi_oxid = FC_XID_UNKNOWN;
+ memcpy(mac, fip->data_src_addr, ETH_ALEN);
+ fc_fcoe_set_mac(fip->data_src_addr, fh->fh_d_id);
+ spin_unlock_bh(&fip->lock);
+
+ fip->update_mac(fip, mac, fip->data_src_addr);
+ } else if (op == ELS_FLOGI && fh->fh_r_ctl == FC_RCTL_ELS_REQ && sa) {
+ /*
+ * Save source MAC for point-to-point responses.
+ */
+ spin_lock_bh(&fip->lock);
+ if (fip->state == FIP_ST_AUTO || fip->state == FIP_ST_NON_FIP) {
+ memcpy(fip->dest_addr, sa, ETH_ALEN);
+ fip->map_dest = 0;
+ if (fip->state == FIP_ST_NON_FIP)
+ FIP_DBG("received FLOGI REQ, "
+ "using non-FIP mode\n");
+ fip->state = FIP_ST_NON_FIP;
+ }
+ spin_unlock_bh(&fip->lock);
+ }
return 0;
}
-EXPORT_SYMBOL_GPL(fcoe_reset);
+EXPORT_SYMBOL(fcoe_ctlr_recv_flogi);
/**
* fcoe_wwn_from_mac() - Converts 48-bit IEEE MAC address to 64-bit FC WWN.
@@ -1254,85 +1315,6 @@ u64 fcoe_wwn_from_mac(unsigned char mac[MAX_ADDR_LEN],
EXPORT_SYMBOL_GPL(fcoe_wwn_from_mac);
/**
- * fcoe_hostlist_lookup_softc() - find the corresponding lport by a given device
- * @device: this is currently ptr to net_device
- *
- * Returns: NULL or the located fcoe_softc
- */
-static struct fcoe_softc *
-fcoe_hostlist_lookup_softc(const struct net_device *dev)
-{
- struct fcoe_softc *fc;
-
- read_lock(&fcoe_hostlist_lock);
- list_for_each_entry(fc, &fcoe_hostlist, list) {
- if (fc->real_dev == dev) {
- read_unlock(&fcoe_hostlist_lock);
- return fc;
- }
- }
- read_unlock(&fcoe_hostlist_lock);
- return NULL;
-}
-
-/**
- * fcoe_hostlist_lookup() - Find the corresponding lport by netdev
- * @netdev: ptr to net_device
- *
- * Returns: 0 for success
- */
-struct fc_lport *fcoe_hostlist_lookup(const struct net_device *netdev)
-{
- struct fcoe_softc *fc;
-
- fc = fcoe_hostlist_lookup_softc(netdev);
-
- return (fc) ? fc->lp : NULL;
-}
-EXPORT_SYMBOL_GPL(fcoe_hostlist_lookup);
-
-/**
- * fcoe_hostlist_add() - Add a lport to lports list
- * @lp: ptr to the fc_lport to badded
- *
- * Returns: 0 for success
- */
-int fcoe_hostlist_add(const struct fc_lport *lp)
-{
- struct fcoe_softc *fc;
-
- fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
- if (!fc) {
- fc = lport_priv(lp);
- write_lock_bh(&fcoe_hostlist_lock);
- list_add_tail(&fc->list, &fcoe_hostlist);
- write_unlock_bh(&fcoe_hostlist_lock);
- }
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_hostlist_add);
-
-/**
- * fcoe_hostlist_remove() - remove a lport from lports list
- * @lp: ptr to the fc_lport to badded
- *
- * Returns: 0 for success
- */
-int fcoe_hostlist_remove(const struct fc_lport *lp)
-{
- struct fcoe_softc *fc;
-
- fc = fcoe_hostlist_lookup_softc(fcoe_netdev(lp));
- BUG_ON(!fc);
- write_lock_bh(&fcoe_hostlist_lock);
- list_del(&fc->list);
- write_unlock_bh(&fcoe_hostlist_lock);
-
- return 0;
-}
-EXPORT_SYMBOL_GPL(fcoe_hostlist_remove);
-
-/**
* fcoe_libfc_config() - sets up libfc related properties for lport
* @lp: ptr to the fc_lport
* @tt: libfc function template
@@ -1354,121 +1336,3 @@ int fcoe_libfc_config(struct fc_lport *lp, struct libfc_function_template *tt)
return 0;
}
EXPORT_SYMBOL_GPL(fcoe_libfc_config);
-
-/**
- * fcoe_init() - fcoe module loading initialization
- *
- * Initialization routine
- * 1. Will create fc transport software structure
- * 2. initialize the link list of port information structure
- *
- * Returns 0 on success, negative on failure
- */
-static int __init fcoe_init(void)
-{
- int cpu;
- struct fcoe_percpu_s *p;
-
-
- INIT_LIST_HEAD(&fcoe_hostlist);
- rwlock_init(&fcoe_hostlist_lock);
-
-#ifdef CONFIG_HOTPLUG_CPU
- register_cpu_notifier(&fcoe_cpu_notifier);
-#endif /* CONFIG_HOTPLUG_CPU */
-
- /*
- * initialize per CPU interrupt thread
- */
- for_each_online_cpu(cpu) {
- p = kzalloc(sizeof(struct fcoe_percpu_s), GFP_KERNEL);
- if (p) {
- p->thread = kthread_create(fcoe_percpu_receive_thread,
- (void *)p,
- "fcoethread/%d", cpu);
-
- /*
- * if there is no error then bind the thread to the cpu
- * initialize the semaphore and skb queue head
- */
- if (likely(!IS_ERR(p->thread))) {
- p->cpu = cpu;
- fcoe_percpu[cpu] = p;
- skb_queue_head_init(&p->fcoe_rx_list);
- kthread_bind(p->thread, cpu);
- wake_up_process(p->thread);
- } else {
- fcoe_percpu[cpu] = NULL;
- kfree(p);
- }
- }
- }
-
- /*
- * setup link change notification
- */
- fcoe_dev_setup();
-
- setup_timer(&fcoe_timer, fcoe_watchdog, 0);
-
- mod_timer(&fcoe_timer, jiffies + (10 * HZ));
-
- /* initiatlize the fcoe transport */
- fcoe_transport_init();
-
- fcoe_sw_init();
-
- return 0;
-}
-module_init(fcoe_init);
-
-/**
- * fcoe_exit() - fcoe module unloading cleanup
- *
- * Returns 0 on success, negative on failure
- */
-static void __exit fcoe_exit(void)
-{
- u32 idx;
- struct fcoe_softc *fc, *tmp;
- struct fcoe_percpu_s *p;
- struct sk_buff *skb;
-
- /*
- * Stop all call back interfaces
- */
-#ifdef CONFIG_HOTPLUG_CPU
- unregister_cpu_notifier(&fcoe_cpu_notifier);
-#endif /* CONFIG_HOTPLUG_CPU */
- fcoe_dev_cleanup();
-
- /*
- * stop timer
- */
- del_timer_sync(&fcoe_timer);
-
- /* releases the associated fcoe transport for each lport */
- list_for_each_entry_safe(fc, tmp, &fcoe_hostlist, list)
- fcoe_transport_release(fc->real_dev);
-
- for (idx = 0; idx < NR_CPUS; idx++) {
- if (fcoe_percpu[idx]) {
- kthread_stop(fcoe_percpu[idx]->thread);
- p = fcoe_percpu[idx];
- spin_lock_bh(&p->fcoe_rx_list.lock);
- while ((skb = __skb_dequeue(&p->fcoe_rx_list)) != NULL)
- kfree_skb(skb);
- spin_unlock_bh(&p->fcoe_rx_list.lock);
- if (fcoe_percpu[idx]->crc_eof_page)
- put_page(fcoe_percpu[idx]->crc_eof_page);
- kfree(fcoe_percpu[idx]);
- }
- }
-
- /* remove sw trasnport */
- fcoe_sw_exit();
-
- /* detach the transport */
- fcoe_transport_exit();
-}
-module_exit(fcoe_exit);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 93d1fbe4ee5..ea4abee7a2a 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -75,7 +75,7 @@ MODULE_PARM_DESC(max_lun, "Maximum allowed LUN. "
module_param_named(max_targets, max_targets, uint, S_IRUGO);
MODULE_PARM_DESC(max_targets, "Maximum allowed targets. "
"[Default=" __stringify(IBMVFC_MAX_TARGETS) "]");
-module_param_named(disc_threads, disc_threads, uint, S_IRUGO | S_IWUSR);
+module_param_named(disc_threads, disc_threads, uint, S_IRUGO);
MODULE_PARM_DESC(disc_threads, "Number of device discovery threads to use. "
"[Default=" __stringify(IBMVFC_MAX_DISC_THREADS) "]");
module_param_named(debug, ibmvfc_debug, uint, S_IRUGO | S_IWUSR);
@@ -640,6 +640,7 @@ static void ibmvfc_release_crq_queue(struct ibmvfc_host *vhost)
ibmvfc_dbg(vhost, "Releasing CRQ\n");
free_irq(vdev->irq, vhost);
+ tasklet_kill(&vhost->tasklet);
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
@@ -2699,6 +2700,25 @@ static struct ibmvfc_crq *ibmvfc_next_crq(struct ibmvfc_host *vhost)
static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
{
struct ibmvfc_host *vhost = (struct ibmvfc_host *)dev_instance;
+ unsigned long flags;
+
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ vio_disable_interrupts(to_vio_dev(vhost->dev));
+ tasklet_schedule(&vhost->tasklet);
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ return IRQ_HANDLED;
+}
+
+/**
+ * ibmvfc_tasklet - Interrupt handler tasklet
+ * @data: ibmvfc host struct
+ *
+ * Returns:
+ * Nothing
+ **/
+static void ibmvfc_tasklet(void *data)
+{
+ struct ibmvfc_host *vhost = data;
struct vio_dev *vdev = to_vio_dev(vhost->dev);
struct ibmvfc_crq *crq;
struct ibmvfc_async_crq *async;
@@ -2706,7 +2726,6 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
int done = 0;
spin_lock_irqsave(vhost->host->host_lock, flags);
- vio_disable_interrupts(to_vio_dev(vhost->dev));
while (!done) {
/* Pull all the valid messages off the CRQ */
while ((crq = ibmvfc_next_crq(vhost)) != NULL) {
@@ -2734,7 +2753,6 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance)
}
spin_unlock_irqrestore(vhost->host->host_lock, flags);
- return IRQ_HANDLED;
}
/**
@@ -3105,6 +3123,7 @@ static void ibmvfc_tgt_adisc_done(struct ibmvfc_event *evt)
vhost->discovery_threads--;
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
+ del_timer(&tgt->timer);
switch (status) {
case IBMVFC_MAD_SUCCESS:
@@ -3161,9 +3180,89 @@ static void ibmvfc_init_passthru(struct ibmvfc_event *evt)
}
/**
+ * ibmvfc_tgt_adisc_cancel_done - Completion handler when cancelling an ADISC
+ * @evt: ibmvfc event struct
+ *
+ * Just cleanup this event struct. Everything else is handled by
+ * the ADISC completion handler. If the ADISC never actually comes
+ * back, we still have the timer running on the ADISC event struct
+ * which will fire and cause the CRQ to get reset.
+ *
+ **/
+static void ibmvfc_tgt_adisc_cancel_done(struct ibmvfc_event *evt)
+{
+ struct ibmvfc_host *vhost = evt->vhost;
+ struct ibmvfc_target *tgt = evt->tgt;
+
+ tgt_dbg(tgt, "ADISC cancel complete\n");
+ vhost->abort_threads--;
+ ibmvfc_free_event(evt);
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
+ wake_up(&vhost->work_wait_q);
+}
+
+/**
+ * ibmvfc_adisc_timeout - Handle an ADISC timeout
+ * @tgt: ibmvfc target struct
+ *
+ * If an ADISC times out, send a cancel. If the cancel times
+ * out, reset the CRQ. When the ADISC comes back as cancelled,
+ * log back into the target.
+ **/
+static void ibmvfc_adisc_timeout(struct ibmvfc_target *tgt)
+{
+ struct ibmvfc_host *vhost = tgt->vhost;
+ struct ibmvfc_event *evt;
+ struct ibmvfc_tmf *tmf;
+ unsigned long flags;
+ int rc;
+
+ tgt_dbg(tgt, "ADISC timeout\n");
+ spin_lock_irqsave(vhost->host->host_lock, flags);
+ if (vhost->abort_threads >= disc_threads ||
+ tgt->action != IBMVFC_TGT_ACTION_INIT_WAIT ||
+ vhost->state != IBMVFC_INITIALIZING ||
+ vhost->action != IBMVFC_HOST_ACTION_QUERY_TGTS) {
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+ return;
+ }
+
+ vhost->abort_threads++;
+ kref_get(&tgt->kref);
+ evt = ibmvfc_get_event(vhost);
+ ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT);
+
+ evt->tgt = tgt;
+ tmf = &evt->iu.tmf;
+ memset(tmf, 0, sizeof(*tmf));
+ tmf->common.version = 1;
+ tmf->common.opcode = IBMVFC_TMF_MAD;
+ tmf->common.length = sizeof(*tmf);
+ tmf->scsi_id = tgt->scsi_id;
+ tmf->cancel_key = tgt->cancel_key;
+
+ rc = ibmvfc_send_event(evt, vhost, default_timeout);
+
+ if (rc) {
+ tgt_err(tgt, "Failed to send cancel event for ADISC. rc=%d\n", rc);
+ vhost->abort_threads--;
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
+ __ibmvfc_reset_host(vhost);
+ } else
+ tgt_dbg(tgt, "Attempting to cancel ADISC\n");
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
+}
+
+/**
* ibmvfc_tgt_adisc - Initiate an ADISC for specified target
* @tgt: ibmvfc target struct
*
+ * When sending an ADISC we end up with two timers running. The
+ * first timer is the timer in the ibmvfc target struct. If this
+ * fires, we send a cancel to the target. The second timer is the
+ * timer on the ibmvfc event for the ADISC, which is longer. If that
+ * fires, it means the ADISC timed out and our attempt to cancel it
+ * also failed, so we need to reset the CRQ.
**/
static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
{
@@ -3184,6 +3283,7 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
mad = &evt->iu.passthru;
mad->iu.flags = IBMVFC_FC_ELS;
mad->iu.scsi_id = tgt->scsi_id;
+ mad->iu.cancel_key = tgt->cancel_key;
mad->fc_iu.payload[0] = IBMVFC_ADISC;
memcpy(&mad->fc_iu.payload[2], &vhost->login_buf->resp.port_name,
@@ -3192,9 +3292,19 @@ static void ibmvfc_tgt_adisc(struct ibmvfc_target *tgt)
sizeof(vhost->login_buf->resp.node_name));
mad->fc_iu.payload[6] = vhost->login_buf->resp.scsi_id & 0x00ffffff;
+ if (timer_pending(&tgt->timer))
+ mod_timer(&tgt->timer, jiffies + (IBMVFC_ADISC_TIMEOUT * HZ));
+ else {
+ tgt->timer.data = (unsigned long) tgt;
+ tgt->timer.expires = jiffies + (IBMVFC_ADISC_TIMEOUT * HZ);
+ tgt->timer.function = (void (*)(unsigned long))ibmvfc_adisc_timeout;
+ add_timer(&tgt->timer);
+ }
+
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
- if (ibmvfc_send_event(evt, vhost, default_timeout)) {
+ if (ibmvfc_send_event(evt, vhost, IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT)) {
vhost->discovery_threads--;
+ del_timer(&tgt->timer);
ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
kref_put(&tgt->kref, ibmvfc_release_tgt);
} else
@@ -3322,6 +3432,8 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id)
tgt->new_scsi_id = scsi_id;
tgt->vhost = vhost;
tgt->need_login = 1;
+ tgt->cancel_key = vhost->task_set++;
+ init_timer(&tgt->timer);
kref_init(&tgt->kref);
ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
spin_lock_irqsave(vhost->host->host_lock, flags);
@@ -3716,6 +3828,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost)
spin_unlock_irqrestore(vhost->host->host_lock, flags);
if (rport)
fc_remote_port_delete(rport);
+ del_timer_sync(&tgt->timer);
kref_put(&tgt->kref, ibmvfc_release_tgt);
return;
}
@@ -3859,6 +3972,8 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
retrc = 0;
+ tasklet_init(&vhost->tasklet, (void *)ibmvfc_tasklet, (unsigned long)vhost);
+
if ((rc = request_irq(vdev->irq, ibmvfc_interrupt, 0, IBMVFC_NAME, vhost))) {
dev_err(dev, "Couldn't register irq 0x%x. rc=%d\n", vdev->irq, rc);
goto req_irq_failed;
@@ -3874,6 +3989,7 @@ static int ibmvfc_init_crq(struct ibmvfc_host *vhost)
return retrc;
req_irq_failed:
+ tasklet_kill(&vhost->tasklet);
do {
rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address);
} while (rc == H_BUSY || H_IS_LONG_BUSY(rc));
@@ -4040,6 +4156,7 @@ static int ibmvfc_probe(struct vio_dev *vdev, const struct vio_device_id *id)
vhost->dev = dev;
vhost->partition_number = -1;
vhost->log_level = log_level;
+ vhost->task_set = 1;
strcpy(vhost->partition_name, "UNKNOWN");
init_waitqueue_head(&vhost->work_wait_q);
init_waitqueue_head(&vhost->init_wait_q);
@@ -4174,6 +4291,7 @@ static struct fc_function_template ibmvfc_transport_functions = {
.show_host_supported_classes = 1,
.show_host_port_type = 1,
.show_host_port_id = 1,
+ .show_host_maxframe_size = 1,
.get_host_port_state = ibmvfc_get_host_port_state,
.show_host_port_state = 1,
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.h b/drivers/scsi/ibmvscsi/ibmvfc.h
index b21e071b986..ca1dcf7a756 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.h
+++ b/drivers/scsi/ibmvscsi/ibmvfc.h
@@ -29,10 +29,14 @@
#include "viosrp.h"
#define IBMVFC_NAME "ibmvfc"
-#define IBMVFC_DRIVER_VERSION "1.0.4"
-#define IBMVFC_DRIVER_DATE "(November 14, 2008)"
+#define IBMVFC_DRIVER_VERSION "1.0.5"
+#define IBMVFC_DRIVER_DATE "(March 19, 2009)"
#define IBMVFC_DEFAULT_TIMEOUT 60
+#define IBMVFC_ADISC_CANCEL_TIMEOUT 45
+#define IBMVFC_ADISC_TIMEOUT 15
+#define IBMVFC_ADISC_PLUS_CANCEL_TIMEOUT \
+ (IBMVFC_ADISC_TIMEOUT + IBMVFC_ADISC_CANCEL_TIMEOUT)
#define IBMVFC_INIT_TIMEOUT 120
#define IBMVFC_MAX_REQUESTS_DEFAULT 100
@@ -53,9 +57,9 @@
* Ensure we have resources for ERP and initialization:
* 1 for ERP
* 1 for initialization
- * 1 for each discovery thread
+ * 2 for each discovery thread
*/
-#define IBMVFC_NUM_INTERNAL_REQ (1 + 1 + disc_threads)
+#define IBMVFC_NUM_INTERNAL_REQ (1 + 1 + (disc_threads * 2))
#define IBMVFC_MAD_SUCCESS 0x00
#define IBMVFC_MAD_NOT_SUPPORTED 0xF1
@@ -585,10 +589,12 @@ struct ibmvfc_target {
enum ibmvfc_target_action action;
int need_login;
int init_retries;
+ u32 cancel_key;
struct ibmvfc_service_parms service_parms;
struct ibmvfc_service_parms service_parms_change;
struct fc_rport_identifiers ids;
void (*job_step) (struct ibmvfc_target *);
+ struct timer_list timer;
struct kref kref;
};
@@ -672,6 +678,7 @@ struct ibmvfc_host {
int task_set;
int init_retries;
int discovery_threads;
+ int abort_threads;
int client_migrated;
int reinit;
int delay_init;
@@ -684,6 +691,7 @@ struct ibmvfc_host {
char partition_name[97];
void (*job_step) (struct ibmvfc_host *);
struct task_struct *work_thread;
+ struct tasklet_struct tasklet;
wait_queue_head_t init_wait_q;
wait_queue_head_t work_wait_q;
};
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index a5725f3b7ce..f555ae99ad4 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -41,7 +41,7 @@
MODULE_AUTHOR("Open-FCoE.org");
MODULE_DESCRIPTION("libfc");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
static int fc_fcp_debug;
@@ -407,10 +407,12 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp)
if (~crc != le32_to_cpu(fr_crc(fp))) {
crc_err:
- stats = lp->dev_stats[smp_processor_id()];
+ stats = fc_lport_get_stats(lp);
stats->ErrorFrames++;
+ /* FIXME - per cpu count, not total count! */
if (stats->InvalidCRCCount++ < 5)
- FC_DBG("CRC error on data frame\n");
+ printk(KERN_WARNING "CRC error on data frame for port (%6x)\n",
+ fc_host_port_id(lp->host));
/*
* Assume the frame is total garbage.
* We may have copied it over the good part
@@ -1752,7 +1754,7 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void (*done)(struct scsi_cmnd *))
/*
* setup the data direction
*/
- stats = lp->dev_stats[smp_processor_id()];
+ stats = fc_lport_get_stats(lp);
if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
fsp->req_flags = FC_SRB_READ;
stats->InputRequests++;
diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
index 7ef44501ecc..b8178ef398d 100644
--- a/drivers/scsi/libfc/fc_lport.c
+++ b/drivers/scsi/libfc/fc_lport.c
@@ -267,10 +267,10 @@ EXPORT_SYMBOL(fc_get_host_speed);
struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
{
- int i;
struct fc_host_statistics *fcoe_stats;
struct fc_lport *lp = shost_priv(shost);
struct timespec v0, v1;
+ unsigned int cpu;
fcoe_stats = &lp->host_stats;
memset(fcoe_stats, 0, sizeof(struct fc_host_statistics));
@@ -279,10 +279,11 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
jiffies_to_timespec(lp->boot_time, &v1);
fcoe_stats->seconds_since_last_reset = (v0.tv_sec - v1.tv_sec);
- for_each_online_cpu(i) {
- struct fcoe_dev_stats *stats = lp->dev_stats[i];
- if (stats == NULL)
- continue;
+ for_each_possible_cpu(cpu) {
+ struct fcoe_dev_stats *stats;
+
+ stats = per_cpu_ptr(lp->dev_stats, cpu);
+
fcoe_stats->tx_frames += stats->TxFrames;
fcoe_stats->tx_words += stats->TxWords;
fcoe_stats->rx_frames += stats->RxFrames;
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index dfaa8adf099..68962835916 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1999,8 +1999,10 @@ iscsi_pool_init(struct iscsi_pool *q, int max, void ***items, int item_size)
q->queue = kfifo_init((void*)q->pool, max * sizeof(void*),
GFP_KERNEL, NULL);
- if (q->queue == ERR_PTR(-ENOMEM))
+ if (IS_ERR(q->queue)) {
+ q->queue = NULL;
goto enomem;
+ }
for (i = 0; i < max; i++) {
q->pool[i] = kzalloc(item_size, GFP_KERNEL);
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index 552f58b655d..2a5f0777148 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -338,20 +338,6 @@ struct osd_request *osd_start_request(struct osd_dev *dev, gfp_t gfp)
}
EXPORT_SYMBOL(osd_start_request);
-/*
- * If osd_finalize_request() was called but the request was not executed through
- * the block layer, then we must release BIOs.
- */
-static void _abort_unexecuted_bios(struct request *rq)
-{
- struct bio *bio;
-
- while ((bio = rq->bio) != NULL) {
- rq->bio = bio->bi_next;
- bio_endio(bio, 0);
- }
-}
-
static void _osd_free_seg(struct osd_request *or __unused,
struct _osd_req_data_segment *seg)
{
@@ -363,9 +349,30 @@ static void _osd_free_seg(struct osd_request *or __unused,
seg->alloc_size = 0;
}
+static void _put_request(struct request *rq , bool is_async)
+{
+ if (is_async) {
+ WARN_ON(rq->bio);
+ __blk_put_request(rq->q, rq);
+ } else {
+ /*
+ * If osd_finalize_request() was called but the request was not
+ * executed through the block layer, then we must release BIOs.
+ * TODO: Keep error code in or->async_error. Need to audit all
+ * code paths.
+ */
+ if (unlikely(rq->bio))
+ blk_end_request(rq, -ENOMEM, blk_rq_bytes(rq));
+ else
+ blk_put_request(rq);
+ }
+}
+
void osd_end_request(struct osd_request *or)
{
struct request *rq = or->request;
+ /* IMPORTANT: make sure this agrees with osd_execute_request_async */
+ bool is_async = (or->request->end_io_data == or);
_osd_free_seg(or, &or->set_attr);
_osd_free_seg(or, &or->enc_get_attr);
@@ -373,12 +380,11 @@ void osd_end_request(struct osd_request *or)
if (rq) {
if (rq->next_rq) {
- _abort_unexecuted_bios(rq->next_rq);
- blk_put_request(rq->next_rq);
+ _put_request(rq->next_rq, is_async);
+ rq->next_rq = NULL;
}
- _abort_unexecuted_bios(rq);
- blk_put_request(rq);
+ _put_request(rq, is_async);
}
_osd_request_free(or);
}
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index f8b1a749958..f644c9571ea 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -345,10 +345,6 @@ static int osd_probe(struct device *dev)
}
dev_set_drvdata(oud->class_member, oud);
- error = sysfs_create_link(&scsi_device->sdev_gendev.kobj,
- &oud->class_member->kobj, osd_symlink);
- if (error)
- OSD_ERR("warning: unable to make symlink\n");
OSD_INFO("osd_probe %s\n", disk->disk_name);
return 0;
@@ -377,8 +373,6 @@ static int osd_remove(struct device *dev)
scsi_device);
}
- sysfs_remove_link(&oud->od.scsi_device->sdev_gendev.kobj, osd_symlink);
-
if (oud->class_member)
device_destroy(osd_sysfs_class,
MKDEV(SCSI_OSD_MAJOR, oud->minor));
diff --git a/drivers/scsi/ql1040_fw.h b/drivers/scsi/ql1040_fw.h
deleted file mode 100644
index aaf9284a8b7..00000000000
--- a/drivers/scsi/ql1040_fw.h
+++ /dev/null
@@ -1,2130 +0,0 @@
-/**************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * Copyright (C) 2004 QLogic Corporation
- * (www.qlogic.com)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- *************************************************************************/
-
-/************************************************************************
- * *
- * --- ISP1040 Initiator/Target Firmware --- *
- * 32 LUN Support *
- * *
- ************************************************************************
- */
-
-/*
- * Firmware Version 7.65.06 (14:38 Jan 07, 2002)
- */
-
-static unsigned char firmware_version[] = {7,65,6};
-
-#define FW_VERSION_STRING "7.65.06"
-
-static unsigned short risc_code_addr01 = 0x1000 ;
-
-static unsigned short risc_code01[] = {
- 0x0078, 0x103a, 0x0000, 0x4158, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x3520, 0x514c, 0x4f47, 0x4943,
- 0x2043, 0x4f52, 0x504f, 0x5241, 0x5449, 0x4f4e, 0x2049, 0x5350,
- 0x3130, 0x3230, 0x2049, 0x2f54, 0x2046, 0x6972, 0x6d77, 0x6172,
- 0x6520, 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x372e, 0x3635,
- 0x2020, 0x2043, 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20,
- 0x3030, 0x2050, 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020,
- 0x3031, 0x2024, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x0048,
- 0x1045, 0x0038, 0x104b, 0x0078, 0x1047, 0x0028, 0x104b, 0x20b9,
- 0x1212, 0x0078, 0x104d, 0x20b9, 0x2222, 0x20c1, 0x0008, 0x2071,
- 0x0010, 0x70c3, 0x0004, 0x20c9, 0x78ff, 0x2089, 0x1186, 0x70c7,
- 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0007, 0x3f00,
- 0x70d6, 0x20c1, 0x0008, 0x2019, 0x0000, 0x2009, 0xfeff, 0x2100,
- 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64, 0x206b, 0x0a0a, 0xaddc,
- 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114, 0xa286, 0xa5a5, 0x0040,
- 0x10bf, 0xa386, 0x000f, 0x0040, 0x1085, 0x2c6a, 0x2a5a, 0x20c1,
- 0x0000, 0x2019, 0x000f, 0x0078, 0x1065, 0x2c6a, 0x2a5a, 0x20c1,
- 0x0008, 0x2009, 0x7fff, 0x2148, 0x2944, 0x204b, 0x0a0a, 0xa9bc,
- 0x3fff, 0x2734, 0x203b, 0x5050, 0x2114, 0xa286, 0x0a0a, 0x0040,
- 0x10a9, 0x284a, 0x263a, 0x20c1, 0x0004, 0x2009, 0x3fff, 0x2134,
- 0x200b, 0x5050, 0x2114, 0xa286, 0x5050, 0x0040, 0x10aa, 0x0078,
- 0x118e, 0x284a, 0x263a, 0x98c0, 0xa188, 0x1000, 0x212c, 0x200b,
- 0xa5a5, 0x2114, 0xa286, 0xa5a5, 0x0040, 0x10bc, 0x250a, 0xa18a,
- 0x1000, 0x98c1, 0x0078, 0x10c1, 0x250a, 0x0078, 0x10c1, 0x2c6a,
- 0x2a5a, 0x2130, 0xa18a, 0x0040, 0x2128, 0xa1a2, 0x5200, 0x8424,
- 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0xa192, 0x7900, 0x2009,
- 0x0000, 0x2001, 0x0031, 0x1078, 0x1d26, 0x2218, 0x2079, 0x5200,
- 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109,
- 0x00c0, 0x10dc, 0x7ef2, 0x8528, 0x7de6, 0x7cea, 0x7bee, 0x7883,
- 0x0000, 0x2031, 0x0030, 0x78cf, 0x0101, 0x780b, 0x0002, 0x780f,
- 0x0002, 0x784f, 0x0003, 0x2069, 0x5240, 0x2001, 0x04fd, 0x2004,
- 0xa082, 0x0005, 0x0048, 0x1104, 0x0038, 0x1100, 0x0078, 0x1108,
- 0x681b, 0x003c, 0x0078, 0x110a, 0x00a8, 0x1108, 0x681b, 0x003c,
- 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa, 0x680f, 0x0008,
- 0x6813, 0x0005, 0x6823, 0x0000, 0x6827, 0x0006, 0x6817, 0x0008,
- 0x682b, 0x0000, 0x681f, 0x0019, 0x2069, 0x5480, 0x2011, 0x0020,
- 0x2009, 0x0010, 0x680b, 0x080c, 0x680f, 0x0019, 0x6803, 0xfd00,
- 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
- 0x8109, 0x00c0, 0x1122, 0x2069, 0x5500, 0x2009, 0x0002, 0x20a9,
- 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bf0, 0xa386, 0xfeff,
- 0x00c0, 0x1148, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x114c,
- 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x0070, 0x1152,
- 0x0078, 0x1139, 0x8109, 0x00c0, 0x1137, 0x1078, 0x22a7, 0x1078,
- 0x493d, 0x1078, 0x19b5, 0x1078, 0x4e33, 0x3200, 0xa085, 0x000d,
- 0x2090, 0x70c3, 0x0000, 0x0090, 0x116c, 0x70c0, 0xa086, 0x0002,
- 0x00c0, 0x116c, 0x1078, 0x1284, 0x1078, 0x1196, 0x78cc, 0xa005,
- 0x00c0, 0x117a, 0x1078, 0x1d4f, 0x0010, 0x1180, 0x0068, 0x1180,
- 0x1078, 0x2186, 0x0010, 0x1180, 0x0068, 0x1180, 0x1078, 0x1ab9,
- 0x00e0, 0x116c, 0x1078, 0x4cba, 0x0078, 0x116c, 0x118e, 0x1190,
- 0x24ac, 0x24ac, 0x49be, 0x49be, 0x24ac, 0x24ac, 0x0078, 0x118e,
- 0x0078, 0x1190, 0x0078, 0x1192, 0x0078, 0x1194, 0x0068, 0x1201,
- 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1201, 0x7814,
- 0xa005, 0x00c0, 0x11a7, 0x0010, 0x1202, 0x0078, 0x1201, 0x2009,
- 0x525b, 0x2104, 0xa005, 0x00c0, 0x1201, 0x2009, 0x5264, 0x200b,
- 0x0000, 0x7914, 0xa186, 0x0042, 0x00c0, 0x11cc, 0x7816, 0x2009,
- 0x5262, 0x2164, 0x200b, 0x0000, 0x6018, 0x70c6, 0x6014, 0x70ca,
- 0x611c, 0xa18c, 0xff00, 0x6020, 0xa084, 0x00ff, 0xa105, 0x70ce,
- 0x1078, 0x199a, 0x0078, 0x11ff, 0x7814, 0xa086, 0x0018, 0x00c0,
- 0x11d3, 0x1078, 0x1678, 0x7817, 0x0000, 0x2009, 0x5262, 0x2104,
- 0xa065, 0x0040, 0x11ef, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17,
- 0x0c7f, 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6007,
- 0x0103, 0x1078, 0x1976, 0x00c0, 0x11fb, 0x1078, 0x199a, 0x2009,
- 0x5262, 0x200b, 0x0000, 0x2009, 0x525c, 0x2104, 0x200b, 0x0000,
- 0xa005, 0x0040, 0x11ff, 0x2001, 0x4005, 0x0078, 0x1286, 0x0078,
- 0x1284, 0x007c, 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000,
- 0x70cf, 0x0000, 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1252, 0x2038,
- 0x0079, 0x1212, 0x1284, 0x12e5, 0x12a9, 0x12fe, 0x130d, 0x1313,
- 0x12a0, 0x1766, 0x1317, 0x1298, 0x12ad, 0x12af, 0x12b1, 0x12b3,
- 0x176b, 0x1298, 0x1329, 0x1365, 0x1690, 0x1760, 0x12b5, 0x15af,
- 0x15cb, 0x15e7, 0x1612, 0x1568, 0x1576, 0x158a, 0x159e, 0x13e9,
- 0x1298, 0x1397, 0x139d, 0x13a2, 0x13a7, 0x13ad, 0x13b2, 0x13b7,
- 0x13bc, 0x13c1, 0x13c5, 0x13da, 0x13e6, 0x1298, 0x1298, 0x1298,
- 0x1298, 0x13f5, 0x13fe, 0x140d, 0x1451, 0x145b, 0x1462, 0x14a8,
- 0x14b7, 0x14c6, 0x14d8, 0x1548, 0x1558, 0x1298, 0x1298, 0x1298,
- 0x1298, 0x155d, 0xa0bc, 0xffa0, 0x00c0, 0x1298, 0x2038, 0xa084,
- 0x001f, 0x0079, 0x125b, 0x17a4, 0x17a7, 0x17b7, 0x1298, 0x1298,
- 0x1931, 0x194e, 0x1298, 0x1298, 0x1298, 0x1952, 0x195a, 0x1298,
- 0x1298, 0x1298, 0x1298, 0x12db, 0x12f4, 0x131f, 0x135b, 0x1686,
- 0x1782, 0x1796, 0x1298, 0x1847, 0x1960, 0x190d, 0x1917, 0x191b,
- 0x1929, 0x1298, 0x1298, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078,
- 0x1286, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068,
- 0x1287, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x00e0,
- 0x128f, 0x00e0, 0x1291, 0x0068, 0x1291, 0x2091, 0x4080, 0x007c,
- 0x70c3, 0x4001, 0x0078, 0x1287, 0x70c3, 0x4006, 0x0078, 0x1287,
- 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
- 0x1284, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x1284, 0x0078,
- 0x1284, 0x0078, 0x1284, 0x0078, 0x1284, 0x2091, 0x8000, 0x70c3,
- 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
- 0x0007, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
- 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051, 0x0470, 0x2061,
- 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091, 0x5000, 0x2091,
- 0x4080, 0x0078, 0x0455, 0x1078, 0x1bc4, 0x00c0, 0x129c, 0x75d8,
- 0x74dc, 0x75da, 0x74de, 0x0078, 0x12e8, 0x2029, 0x0000, 0x2520,
- 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1afe, 0x0040, 0x1284,
- 0x70c3, 0x4002, 0x0078, 0x1284, 0x1078, 0x1bc4, 0x00c0, 0x129c,
- 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1301, 0x2029, 0x0000,
- 0x2520, 0x71d0, 0x73c8, 0x72cc, 0x70c4, 0x1078, 0x1b5e, 0x0040,
- 0x1284, 0x70c3, 0x4002, 0x0078, 0x1284, 0x71c4, 0x70c8, 0x2114,
- 0x200a, 0x0078, 0x1282, 0x71c4, 0x2114, 0x0078, 0x1282, 0x70c7,
- 0x0007, 0x70cb, 0x0041, 0x70cf, 0x0006, 0x0078, 0x1284, 0x1078,
- 0x1bc4, 0x00c0, 0x129c, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
- 0x132c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
- 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x1355, 0xa40a,
- 0x0040, 0x133c, 0x00c8, 0x1346, 0x8001, 0x7892, 0xa084, 0xfc00,
- 0x0040, 0x134a, 0x78cc, 0xa085, 0x0001, 0x78ce, 0x2001, 0x4005,
- 0x0078, 0x1286, 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x7c96, 0x78cc,
- 0xa084, 0xfffc, 0x78ce, 0x0078, 0x1359, 0x78cc, 0xa085, 0x0001,
- 0x78ce, 0x0078, 0x1284, 0x1078, 0x1bc4, 0x00c0, 0x129c, 0x75d8,
- 0x76dc, 0x75da, 0x76de, 0x0078, 0x1368, 0x2029, 0x0000, 0x2530,
- 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6,
- 0xa005, 0x0040, 0x1391, 0xa40a, 0x0040, 0x1378, 0x00c8, 0x1382,
- 0x8001, 0x78ae, 0xa084, 0xfc00, 0x0040, 0x1386, 0x78cc, 0xa085,
- 0x0100, 0x78ce, 0x2001, 0x4005, 0x0078, 0x1286, 0x7ab6, 0x7bba,
- 0x7dbe, 0x7ec2, 0x7cb2, 0x78cc, 0xa084, 0xfcff, 0x78ce, 0x0078,
- 0x1395, 0x78cc, 0xa085, 0x0100, 0x78ce, 0x0078, 0x1284, 0x2009,
- 0x5261, 0x210c, 0x7aec, 0x0078, 0x1282, 0x2009, 0x5241, 0x210c,
- 0x0078, 0x1283, 0x2009, 0x5242, 0x210c, 0x0078, 0x1283, 0x2061,
- 0x5240, 0x610c, 0x6210, 0x0078, 0x1282, 0x2009, 0x5245, 0x210c,
- 0x0078, 0x1283, 0x2009, 0x5246, 0x210c, 0x0078, 0x1283, 0x2009,
- 0x5248, 0x210c, 0x0078, 0x1283, 0x2009, 0x5249, 0x210c, 0x0078,
- 0x1283, 0x7908, 0x7a0c, 0x0078, 0x1282, 0x71c4, 0x8107, 0xa084,
- 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x5480, 0x6a00, 0x6804,
- 0xa084, 0x0008, 0x0040, 0x13d7, 0x6b08, 0x0078, 0x13d8, 0x6b0c,
- 0x0078, 0x1281, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6b1c,
- 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x1281, 0x794c, 0x0078,
- 0x1283, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6908, 0x6a18,
- 0x6b10, 0x2091, 0x8001, 0x0078, 0x1281, 0x71c4, 0xa182, 0x0010,
- 0x00c8, 0x127c, 0x1078, 0x237f, 0x0078, 0x1281, 0x71c4, 0xa182,
- 0x0010, 0x00c8, 0x127c, 0x2011, 0x5241, 0x2204, 0x007e, 0x2112,
- 0x1078, 0x2338, 0x017f, 0x0078, 0x1283, 0x71c4, 0x2019, 0x0100,
- 0x2304, 0xa082, 0x0006, 0x0048, 0x141b, 0x2011, 0x1449, 0x20a9,
- 0x0008, 0x0078, 0x141f, 0x2011, 0x1441, 0x20a9, 0x0008, 0x2204,
- 0xa106, 0x0040, 0x142a, 0x8210, 0x0070, 0x1428, 0x0078, 0x141f,
- 0x0078, 0x127c, 0x2304, 0xa082, 0x0006, 0x0048, 0x1433, 0xa292,
- 0x1449, 0x0078, 0x1435, 0xa292, 0x1441, 0x027e, 0x2011, 0x5242,
- 0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x2344, 0x017f, 0x0078,
- 0x1283, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
- 0x004b, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0004, 0x0001, 0x0002,
- 0x0003, 0x2061, 0x5240, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
- 0x6012, 0x0078, 0x1282, 0x2061, 0x5240, 0x6114, 0x70c4, 0x6016,
- 0x0078, 0x1283, 0x2061, 0x5240, 0x71c4, 0x2011, 0x0004, 0x601f,
- 0x0019, 0x2019, 0x1212, 0xa186, 0x0028, 0x0040, 0x1483, 0x2011,
- 0x0005, 0x601f, 0x0019, 0x2019, 0x1212, 0xa186, 0x0032, 0x0040,
- 0x1483, 0x2011, 0x0006, 0x601f, 0x000c, 0x2019, 0x2222, 0xa186,
- 0x003c, 0x00c0, 0x127c, 0x6018, 0x007e, 0x611a, 0x7800, 0xa084,
- 0x0001, 0x00c0, 0x149e, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
- 0x0048, 0x1496, 0x0038, 0x149a, 0x0078, 0x149e, 0x0028, 0x149a,
- 0x0078, 0x149e, 0x2019, 0x2222, 0x0078, 0x14a0, 0x2019, 0x1212,
- 0x23b8, 0x1078, 0x2355, 0x1078, 0x4e33, 0x017f, 0x0078, 0x1283,
- 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x127c, 0x2011, 0x5248, 0x2204,
- 0x2112, 0x007e, 0x1078, 0x2377, 0x017f, 0x0078, 0x1283, 0x71c4,
- 0xa182, 0x0010, 0x00c8, 0x127c, 0x2011, 0x5249, 0x2204, 0x007e,
- 0x2112, 0x1078, 0x2366, 0x017f, 0x0078, 0x1283, 0x71c4, 0x72c8,
- 0xa184, 0xfffd, 0x00c0, 0x127b, 0xa284, 0xfffd, 0x00c0, 0x127b,
- 0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x1282,
- 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
- 0x5480, 0x2019, 0x0000, 0x72c8, 0xd2bc, 0x0040, 0x14e9, 0xa39d,
- 0x0010, 0xd2b4, 0x0040, 0x14ee, 0xa39d, 0x0008, 0x6800, 0x007e,
- 0xa226, 0x0040, 0x1511, 0x6a02, 0xa484, 0x2000, 0x0040, 0x14fa,
- 0xa39d, 0x0010, 0xa484, 0x1000, 0x0040, 0x1500, 0xa39d, 0x0008,
- 0xa484, 0x4000, 0x0040, 0x1511, 0x810f, 0xa284, 0x4000, 0x0040,
- 0x150d, 0x1078, 0x2399, 0x0078, 0x1511, 0x1078, 0x238b, 0x0078,
- 0x1511, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1540, 0xa2a4, 0x00ff,
- 0x2061, 0x5240, 0x6118, 0xa186, 0x0028, 0x0040, 0x1527, 0xa186,
- 0x0032, 0x0040, 0x152d, 0xa186, 0x003c, 0x0040, 0x1533, 0xa482,
- 0x0064, 0x0048, 0x153d, 0x0078, 0x1537, 0xa482, 0x0050, 0x0048,
- 0x153d, 0x0078, 0x1537, 0xa482, 0x0043, 0x0048, 0x153d, 0x71c4,
- 0x71c6, 0x027f, 0x72ca, 0x0078, 0x127d, 0x6a0a, 0xa39d, 0x000a,
- 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078, 0x1281,
- 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091,
- 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078, 0x1281,
- 0x70c4, 0x794c, 0x784e, 0x0078, 0x1283, 0x71c4, 0x72c8, 0x73cc,
- 0xa182, 0x0010, 0x00c8, 0x127c, 0x1078, 0x23a7, 0x0078, 0x1281,
- 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0002,
- 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x1078,
- 0x19c5, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804,
- 0xa005, 0x0040, 0x1585, 0x1078, 0x226f, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x1282, 0x77c4, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6a08,
- 0xa295, 0x0004, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1599, 0x1078,
- 0x226f, 0x2091, 0x8001, 0x2708, 0x0078, 0x1282, 0x77c4, 0x2041,
- 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
- 0x19d2, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x1282, 0x77c4,
- 0x72c8, 0x73cc, 0x77c6, 0x72ca, 0x73ce, 0x1078, 0x1a52, 0x00c0,
- 0x15c7, 0x6818, 0xa005, 0x0040, 0x15c7, 0x2708, 0x1078, 0x23b7,
- 0x00c0, 0x15c7, 0x7817, 0x0015, 0x2091, 0x8001, 0x007c, 0x2091,
- 0x8001, 0x0078, 0x1284, 0x77c4, 0x77c6, 0x2041, 0x0021, 0x2049,
- 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x19d2, 0x2061,
- 0x5240, 0x606f, 0x0003, 0x6782, 0x6093, 0x000f, 0x6073, 0x0000,
- 0x7817, 0x0016, 0x1078, 0x226f, 0x2091, 0x8001, 0x007c, 0x77c8,
- 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2061,
- 0x5240, 0x606f, 0x0002, 0x6073, 0x0000, 0x6782, 0x6093, 0x000f,
- 0x7817, 0x0017, 0x1078, 0x226f, 0x2091, 0x8001, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0010, 0x2091, 0x8000, 0x1078, 0x19d2,
- 0x70c8, 0x6836, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1606, 0x2091,
- 0x8001, 0x007c, 0x78cc, 0xa084, 0x0003, 0x00c0, 0x1636, 0x2039,
- 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078,
- 0x19c5, 0x2091, 0x8000, 0x6808, 0xa80d, 0x690a, 0x2091, 0x8001,
- 0x8738, 0xa784, 0x001f, 0x00c0, 0x161f, 0xa7bc, 0xff00, 0x873f,
- 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x161f, 0x2091, 0x8000,
- 0x2069, 0x0100, 0x6830, 0xa084, 0x0040, 0x0040, 0x165f, 0x684b,
- 0x0004, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x164c,
- 0x0070, 0x164c, 0x0078, 0x1643, 0x684b, 0x0009, 0x20a9, 0x0014,
- 0x6848, 0xa084, 0x0001, 0x0040, 0x1659, 0x0070, 0x1659, 0x0078,
- 0x1650, 0x20a9, 0x00fa, 0x0070, 0x165f, 0x0078, 0x165b, 0x2079,
- 0x5200, 0x7817, 0x0018, 0x2061, 0x5240, 0x606f, 0x0001, 0x6073,
- 0x0000, 0x6093, 0x000f, 0x78cc, 0xa085, 0x0002, 0x78ce, 0x6808,
- 0xa084, 0xfffd, 0x680a, 0x681b, 0x0048, 0x2091, 0x8001, 0x007c,
- 0x78cc, 0xa084, 0xfffd, 0x78ce, 0xa084, 0x0001, 0x00c0, 0x1682,
- 0x1078, 0x1a9c, 0x71c4, 0x71c6, 0x794a, 0x007c, 0x1078, 0x1bc4,
- 0x00c0, 0x129c, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1693,
- 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
- 0x72ce, 0x2079, 0x5200, 0x2091, 0x8000, 0x1078, 0x1980, 0x2091,
- 0x8001, 0x0040, 0x174a, 0x20a9, 0x0005, 0x20a1, 0x5218, 0x2091,
- 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0020, 0x1078, 0x197b,
- 0x0040, 0x16b6, 0x1078, 0x199a, 0x0078, 0x174a, 0x6004, 0xa084,
- 0xff00, 0x8007, 0x8009, 0x0040, 0x1719, 0x0c7e, 0x2c68, 0x2091,
- 0x8000, 0x1078, 0x1980, 0x2091, 0x8001, 0x0040, 0x16ea, 0x2c00,
- 0x689e, 0x8109, 0x00c0, 0x16be, 0x609f, 0x0000, 0x0c7f, 0x0c7e,
- 0x7218, 0x731c, 0x7420, 0x7524, 0x2c68, 0x689c, 0xa065, 0x0040,
- 0x1718, 0x2009, 0x0020, 0x1078, 0x197b, 0x00c0, 0x1701, 0x6004,
- 0xa084, 0x00ff, 0xa086, 0x0002, 0x00c0, 0x16ea, 0x2d00, 0x6002,
- 0x0078, 0x16d0, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17,
- 0x0c7f, 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6008,
- 0xa085, 0x0200, 0x600a, 0x1078, 0x1976, 0x1078, 0x199a, 0x0078,
- 0x174a, 0x0c7f, 0x0c7e, 0x609c, 0x2060, 0x1078, 0x1a17, 0x0c7f,
- 0x609f, 0x0000, 0x1078, 0x174e, 0x2009, 0x000c, 0x6007, 0x0103,
- 0x601b, 0x0003, 0x1078, 0x1976, 0x1078, 0x199a, 0x0078, 0x174a,
- 0x0c7f, 0x74c4, 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x7817,
- 0x0012, 0x0e7e, 0x2071, 0x5240, 0x706f, 0x0005, 0x7073, 0x0000,
- 0x7376, 0x727a, 0x747e, 0x7082, 0x7087, 0x0000, 0x2c00, 0x708a,
- 0x708f, 0x0000, 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0x0060,
- 0x0040, 0x173c, 0x1078, 0x48d3, 0x0e7f, 0x6596, 0x65a6, 0x669a,
- 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x1078, 0x226f, 0x2091,
- 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, 0x20a9, 0x0005,
- 0x2099, 0x5218, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100,
- 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c,
- 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x1284, 0x71c4, 0x71c6,
- 0x2168, 0x0078, 0x176d, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04,
- 0xa210, 0x8d68, 0x8109, 0x00c0, 0x176f, 0xa285, 0x0000, 0x00c0,
- 0x177d, 0x70c3, 0x4000, 0x0078, 0x177f, 0x70c3, 0x4003, 0x70ca,
- 0x0078, 0x1287, 0x2011, 0x5267, 0x220c, 0x70c4, 0x8003, 0x0048,
- 0x178f, 0x1078, 0x3c51, 0xa184, 0x7fff, 0x0078, 0x1793, 0x1078,
- 0x3c44, 0xa185, 0x8000, 0x2012, 0x0078, 0x1283, 0x71c4, 0x1078,
- 0x3c3b, 0x6100, 0x2001, 0x5267, 0x2004, 0xa084, 0x8000, 0xa10d,
- 0x6204, 0x6308, 0x0078, 0x1281, 0x79e4, 0x0078, 0x1283, 0x71c4,
- 0x71c6, 0x2198, 0x20a1, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x21a0,
- 0x2099, 0x0042, 0x20a9, 0x0004, 0x53a3, 0x0078, 0x1284, 0x70c4,
- 0x2068, 0x2079, 0x5200, 0x2091, 0x8000, 0x1078, 0x1980, 0x2091,
- 0x8001, 0x0040, 0x1843, 0x6007, 0x0001, 0x600b, 0x0000, 0x602b,
- 0x0000, 0x601b, 0x0006, 0x6a10, 0xa28c, 0x000f, 0xa284, 0x00f0,
- 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x6016, 0xa284, 0x0800,
- 0x0040, 0x17de, 0x601b, 0x000a, 0x0078, 0x17e4, 0xa284, 0x1000,
- 0x0040, 0x17e4, 0x601b, 0x000c, 0xa284, 0x0300, 0x0040, 0x17ed,
- 0x602b, 0x0001, 0x8004, 0x8004, 0x8004, 0xa085, 0x0001, 0x601e,
- 0x6023, 0x0000, 0x6027, 0x0000, 0xa284, 0x0400, 0x0040, 0x17fa,
- 0x602b, 0x0000, 0x20a9, 0x0006, 0xac80, 0x000b, 0x20a0, 0xad80,
- 0x0005, 0x2098, 0x53a3, 0xa284, 0x0300, 0x00c0, 0x180f, 0x6046,
- 0x604a, 0x604e, 0x6052, 0x6096, 0x609a, 0x0078, 0x1819, 0x6800,
- 0x6046, 0x6804, 0x604a, 0x6e08, 0x664e, 0x6d0c, 0x6552, 0x6596,
- 0x669a, 0x6014, 0x2091, 0x8000, 0x7817, 0x0042, 0x2c08, 0x2061,
- 0x5240, 0x606f, 0x0005, 0x6073, 0x0000, 0x6077, 0x0000, 0x607b,
- 0x0000, 0x607f, 0x0000, 0x6082, 0x618a, 0xa284, 0x0400, 0x608e,
- 0x2091, 0x8001, 0x0e7e, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007,
- 0x0002, 0x7003, 0x0000, 0x0e7f, 0x2091, 0x8000, 0x1078, 0x226f,
- 0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x1287, 0x0c7e,
- 0x0d7e, 0x0e7e, 0x0f7e, 0x2091, 0x8000, 0x2071, 0x5240, 0x2079,
- 0x0100, 0x2061, 0x0010, 0x70a0, 0xa06d, 0x0040, 0x1903, 0x6a04,
- 0xa294, 0x00ff, 0xa286, 0x0007, 0x0040, 0x1862, 0xa286, 0x000f,
- 0x00c0, 0x1903, 0x691c, 0xa184, 0x00c0, 0x0040, 0x1903, 0xa184,
- 0x0080, 0x00c0, 0x18d3, 0x6824, 0xa084, 0xff00, 0xa085, 0x0019,
- 0x6826, 0x71b0, 0x81ff, 0x0040, 0x1889, 0x0d7e, 0x2069, 0x0020,
- 0x6807, 0x0010, 0x6908, 0x6808, 0xa106, 0x00c0, 0x187a, 0x690c,
- 0x680c, 0xa106, 0x00c0, 0x187f, 0xa184, 0x00ff, 0x00c0, 0x187f,
- 0x0d7f, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x1889, 0x7848, 0xa085,
- 0x000c, 0x784a, 0x71b0, 0x81ff, 0x0040, 0x18ac, 0x70b3, 0x0000,
- 0x0d7e, 0x2069, 0x0020, 0x6807, 0x0018, 0x6804, 0xa084, 0x0008,
- 0x00c0, 0x189d, 0x6807, 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0,
- 0x18a4, 0x6807, 0x0002, 0x0d7f, 0x61c4, 0x62c8, 0x63cc, 0x61c6,
- 0x62ca, 0x63ce, 0x0e7e, 0x2071, 0x5200, 0x7266, 0x736a, 0xae80,
- 0x0019, 0x0e7f, 0x7848, 0xa084, 0x000c, 0x00c0, 0x18ba, 0x1078,
- 0x47e1, 0x78a3, 0x0000, 0x7858, 0xa084, 0xedff, 0x785a, 0x70b4,
- 0xa080, 0x00da, 0x781a, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091,
- 0x8001, 0x0078, 0x1284, 0x6824, 0xa084, 0xff00, 0xa085, 0x0019,
- 0x6826, 0x78b8, 0xa084, 0x801f, 0x00c0, 0x18d9, 0x7848, 0xa085,
- 0x000c, 0x784a, 0x7848, 0xa084, 0x000c, 0x00c0, 0x18e2, 0x71b0,
- 0x81ff, 0x0040, 0x1901, 0x70b3, 0x0000, 0x0d7e, 0x2069, 0x0020,
- 0x6807, 0x0018, 0x6804, 0xa084, 0x0008, 0x00c0, 0x18f2, 0x6807,
- 0x0008, 0x6804, 0xa084, 0x0008, 0x00c0, 0x18f9, 0x6807, 0x0002,
- 0x0d7f, 0x0078, 0x18cb, 0x0f7f, 0x0e7f, 0x0d7f, 0x0c7f, 0x2091,
- 0x8001, 0x2001, 0x4005, 0x0078, 0x1286, 0x7980, 0x71c6, 0x71c4,
- 0xa182, 0x0003, 0x00c8, 0x127c, 0x7982, 0x0078, 0x1284, 0x7980,
- 0x71c6, 0x0078, 0x1284, 0x7974, 0x71c6, 0x71c4, 0x7976, 0x7978,
- 0x71ca, 0x71c8, 0x797a, 0x797c, 0x71ce, 0x71cc, 0x797e, 0x0078,
- 0x1284, 0x7974, 0x71c6, 0x7978, 0x71ca, 0x797c, 0x71ce, 0x0078,
- 0x1284, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x2001, 0x04fd, 0x2004,
- 0xa082, 0x0005, 0x0048, 0x1940, 0x0038, 0x1942, 0x0078, 0x194c,
- 0x00a8, 0x194c, 0xa18c, 0x0001, 0x00c0, 0x194a, 0x20b9, 0x2222,
- 0x0078, 0x194c, 0x20b9, 0x1212, 0x0078, 0x1284, 0x7900, 0x71c6,
- 0x0078, 0x1284, 0x2009, 0x5274, 0x2104, 0x70c6, 0x70c4, 0x200a,
- 0x0078, 0x1284, 0x2009, 0x5274, 0x2104, 0x70c6, 0x0078, 0x1284,
- 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
- 0x5480, 0x6a14, 0xd2b4, 0x0040, 0x1971, 0x2011, 0x0001, 0x0078,
- 0x1973, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x1281, 0xac80, 0x0001,
- 0x1078, 0x1b80, 0x007c, 0xac80, 0x0001, 0x1078, 0x1b20, 0x007c,
- 0x7850, 0xa065, 0x0040, 0x1988, 0x2c04, 0x7852, 0x2063, 0x0000,
- 0x007c, 0x0f7e, 0x2079, 0x5200, 0x7850, 0xa06d, 0x0040, 0x1998,
- 0x2d04, 0x7852, 0x6803, 0x0000, 0x6807, 0x0000, 0x680b, 0x0000,
- 0x0f7f, 0x007c, 0x2091, 0x8000, 0x0f7e, 0x2079, 0x5200, 0x7850,
- 0x2062, 0x2c00, 0xa005, 0x00c0, 0x19a7, 0x1078, 0x248c, 0x7852,
- 0x0f7f, 0x2091, 0x8001, 0x007c, 0x0f7e, 0x2079, 0x5200, 0x7850,
- 0x206a, 0x2d00, 0x7852, 0x0f7f, 0x007c, 0x2011, 0x7900, 0x7a52,
- 0x7bec, 0x8319, 0x0040, 0x19c2, 0xa280, 0x0031, 0x2012, 0x2010,
- 0x0078, 0x19b9, 0x2013, 0x0000, 0x007c, 0xa784, 0x0f00, 0x800b,
- 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8,
- 0x5500, 0x007c, 0x1078, 0x19c5, 0x2900, 0x682a, 0x2a00, 0x682e,
- 0x6808, 0xa084, 0xffef, 0xa80d, 0x690a, 0x2009, 0x5252, 0x210c,
- 0x6804, 0xa005, 0x0040, 0x1a04, 0xa116, 0x00c0, 0x19ef, 0x2060,
- 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x19f2, 0x2009,
- 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1a01, 0x6000, 0x6806,
- 0x1078, 0x1a31, 0x1078, 0x1ccb, 0x6810, 0x8001, 0x6812, 0x00c0,
- 0x19f2, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x1a16,
- 0x2008, 0x609c, 0xa005, 0x0040, 0x1a13, 0x2062, 0x609f, 0x0000,
- 0xa065, 0x0078, 0x1a09, 0x7850, 0x7952, 0x2062, 0x007c, 0xa065,
- 0x0040, 0x1a30, 0x2008, 0x609c, 0xa005, 0x0040, 0x1a25, 0x2062,
- 0x609f, 0x0000, 0xa065, 0x0078, 0x1a1b, 0x0f7e, 0x2079, 0x5200,
- 0x2091, 0x8000, 0x7850, 0x7952, 0x0f7f, 0x2062, 0x2091, 0x8001,
- 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80,
- 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c,
- 0x6022, 0x007c, 0x0e7e, 0x2071, 0x5240, 0x704c, 0xa08c, 0x0200,
- 0x00c0, 0x1a50, 0xa088, 0x5280, 0x2d0a, 0x8000, 0x704e, 0xa006,
- 0x0e7f, 0x007c, 0x1078, 0x19c5, 0x2091, 0x8000, 0x6804, 0x781e,
- 0xa065, 0x0040, 0x1a9b, 0x0078, 0x1a63, 0x2c00, 0x781e, 0x6000,
- 0xa065, 0x0040, 0x1a9b, 0x600c, 0xa306, 0x00c0, 0x1a5d, 0x6010,
- 0xa206, 0x00c0, 0x1a5d, 0x2c28, 0x2001, 0x5252, 0x2004, 0xac06,
- 0x00c0, 0x1a74, 0x0078, 0x1a99, 0x6804, 0xac06, 0x00c0, 0x1a81,
- 0x6000, 0xa065, 0x6806, 0x00c0, 0x1a8b, 0x6803, 0x0000, 0x0078,
- 0x1a8b, 0x6400, 0x781c, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0,
- 0x1a8b, 0x2c00, 0x6802, 0x2560, 0x1078, 0x1a31, 0x601b, 0x0005,
- 0x6023, 0x0020, 0x1078, 0x1ccb, 0x6810, 0x8001, 0x1050, 0x248c,
- 0x6812, 0xa085, 0xffff, 0x007c, 0x2039, 0x0000, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x19d2,
- 0x8738, 0xa784, 0x001f, 0x00c0, 0x1aa6, 0xa7bc, 0xff00, 0x873f,
- 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1aa6, 0x2091, 0x8001,
- 0x007c, 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x00c0, 0x1aca,
- 0x2091, 0x8000, 0x78e0, 0x78e3, 0x0000, 0x2091, 0x8001, 0xa005,
- 0x00c0, 0x1acb, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1ad1, 0x1078,
- 0x248c, 0x0079, 0x1ad3, 0x1ae3, 0x1ae6, 0x1aec, 0x1af0, 0x1ae4,
- 0x1af4, 0x1afa, 0x1ae4, 0x1ae4, 0x1c95, 0x1cb9, 0x1cbd, 0x1ae4,
- 0x1ae4, 0x1ae4, 0x1ae4, 0x007c, 0x1078, 0x248c, 0x1078, 0x1a9c,
- 0x2001, 0x8001, 0x0078, 0x1cc3, 0x2001, 0x8003, 0x0078, 0x1cc3,
- 0x2001, 0x8004, 0x0078, 0x1cc3, 0x1078, 0x1a9c, 0x2001, 0x8006,
- 0x0078, 0x1cc3, 0x2001, 0x8007, 0x0078, 0x1cc3, 0x2030, 0x2138,
- 0xa782, 0x0021, 0x0048, 0x1b06, 0x2009, 0x0020, 0x2600, 0x1078,
- 0x1b20, 0x00c0, 0x1b1f, 0xa7ba, 0x0020, 0x0048, 0x1b1e, 0x0040,
- 0x1b1e, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000,
- 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1b00, 0xa006, 0x007c,
- 0x81ff, 0x0040, 0x1b5b, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084,
- 0x00ff, 0x0040, 0x1b32, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
- 0x00c0, 0x1b2d, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a,
- 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0001, 0x7002, 0x7007,
- 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x1b4f,
- 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1b41, 0x7008,
- 0x800b, 0x00c8, 0x1b41, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
- 0x1b5b, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x2030, 0x2138,
- 0xa782, 0x0021, 0x0048, 0x1b66, 0x2009, 0x0020, 0x2600, 0x1078,
- 0x1b80, 0x00c0, 0x1b7f, 0xa7ba, 0x0020, 0x0048, 0x1b7e, 0x0040,
- 0x1b7e, 0x2708, 0xa6b0, 0x0020, 0xa290, 0x0040, 0xa399, 0x0000,
- 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0078, 0x1b60, 0xa006, 0x007c,
- 0x81ff, 0x0040, 0x1bc1, 0x2098, 0x20a1, 0x0030, 0x700c, 0xa084,
- 0x00ff, 0x0040, 0x1b92, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
- 0x00c0, 0x1b8d, 0x21a8, 0x7017, 0x0000, 0x810b, 0x7112, 0x721a,
- 0x731e, 0x7422, 0x7526, 0x780c, 0xa085, 0x0000, 0x7002, 0x53a6,
- 0x7007, 0x0001, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8,
- 0x1bb0, 0x2009, 0x0022, 0x2104, 0xa084, 0x4000, 0x00c0, 0x1ba2,
- 0x7010, 0xa084, 0xf000, 0x0040, 0x1bb9, 0x7007, 0x0008, 0x0078,
- 0x1bbd, 0x7108, 0x8103, 0x00c8, 0x1ba2, 0x7007, 0x0002, 0xa184,
- 0x01e0, 0x7003, 0x0000, 0x007c, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0004, 0x00c8, 0x1bcd, 0x0078, 0x1bd0, 0xa006, 0x0078, 0x1bd2,
- 0xa085, 0x0001, 0x007c, 0x0e7e, 0x2071, 0x5200, 0x2d08, 0x7058,
- 0x6802, 0xa005, 0x00c0, 0x1bdd, 0x715e, 0x715a, 0x0e7f, 0x007c,
- 0x2c08, 0x7858, 0x6002, 0xa005, 0x00c0, 0x1be7, 0x795e, 0x795a,
- 0x007c, 0x2091, 0x8000, 0x6114, 0x1078, 0x2180, 0x6900, 0xa184,
- 0x0100, 0x00c0, 0x2035, 0xa184, 0x0200, 0x00c0, 0x2031, 0x681c,
- 0xa005, 0x00c0, 0x203d, 0x6003, 0x0000, 0x2c08, 0x785c, 0xa065,
- 0x00c0, 0x1c05, 0x795a, 0x0078, 0x1c06, 0x6102, 0x795e, 0x2091,
- 0x8001, 0x1078, 0x228c, 0x007c, 0x0e7e, 0x2071, 0x5200, 0x7058,
- 0xa06d, 0x0040, 0x1c1a, 0x6800, 0x705a, 0xa005, 0x00c0, 0x1c19,
- 0x705e, 0x8dff, 0x0e7f, 0x007c, 0x0d7e, 0x0c7e, 0x0f7e, 0x2079,
- 0x5200, 0xaf80, 0x0016, 0x2060, 0x6000, 0xa005, 0x0040, 0x1c43,
- 0x2068, 0x6814, 0xa306, 0x00c0, 0x1c33, 0x6828, 0xa084, 0x00ff,
- 0xa406, 0x0040, 0x1c36, 0x2d60, 0x0078, 0x1c24, 0x6800, 0xa005,
- 0x6002, 0x00c0, 0x1c42, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c41,
- 0x2c00, 0x785e, 0x2d00, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
- 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5200, 0xaf80, 0x0016, 0x2060,
- 0x6000, 0xa005, 0x0040, 0x1c6b, 0x2068, 0x6814, 0xa084, 0x00ff,
- 0xa306, 0x0040, 0x1c5e, 0x2d60, 0x0078, 0x1c50, 0x6800, 0xa005,
- 0x6002, 0x00c0, 0x1c6a, 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c69,
- 0x2c00, 0x785e, 0x2d00, 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c,
- 0x0d7e, 0x0c7e, 0x0f7e, 0x2079, 0x5200, 0xaf80, 0x0016, 0x2060,
- 0x6000, 0xa06d, 0x0040, 0x1c90, 0x6814, 0xa306, 0x0040, 0x1c83,
- 0x2d60, 0x0078, 0x1c78, 0x6800, 0xa005, 0x6002, 0x00c0, 0x1c8f,
- 0xaf80, 0x0016, 0xac06, 0x0040, 0x1c8e, 0x2c00, 0x785e, 0x2d00,
- 0x0f7f, 0x0c7f, 0x0d7f, 0xa005, 0x007c, 0x2091, 0x8000, 0x2069,
- 0x5240, 0x6800, 0xa086, 0x0000, 0x0040, 0x1ca3, 0x2091, 0x8001,
- 0x78e3, 0x0009, 0x007c, 0x6880, 0xa0bc, 0xff00, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0010, 0x1078, 0x19d2, 0x8738, 0xa784,
- 0x001f, 0x00c0, 0x1cac, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078,
- 0x1cc3, 0x2001, 0x800c, 0x0078, 0x1cc3, 0x1078, 0x1a9c, 0x2001,
- 0x800d, 0x0078, 0x1cc3, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001,
- 0x2091, 0x4080, 0x007c, 0x6004, 0x2c08, 0x2063, 0x0000, 0x7884,
- 0x8000, 0x7886, 0x7888, 0xa005, 0x798a, 0x0040, 0x1cda, 0x2c02,
- 0x0078, 0x1cdb, 0x798e, 0x007c, 0x6807, 0x0103, 0x0c7e, 0x2061,
- 0x5200, 0x2d08, 0x206b, 0x0000, 0x6084, 0x8000, 0x6086, 0x6088,
- 0xa005, 0x618a, 0x0040, 0x1cef, 0x2d02, 0x0078, 0x1cf0, 0x618e,
- 0x0c7f, 0x007c, 0x1078, 0x1d03, 0x0040, 0x1d02, 0x0c7e, 0x609c,
- 0xa065, 0x0040, 0x1cfd, 0x1078, 0x1a17, 0x0c7f, 0x609f, 0x0000,
- 0x1078, 0x199a, 0x007c, 0x788c, 0xa065, 0x0040, 0x1d15, 0x2091,
- 0x8000, 0x7884, 0x8001, 0x7886, 0x2c04, 0x788e, 0xa005, 0x00c0,
- 0x1d13, 0x788a, 0x8000, 0x2091, 0x8001, 0x007c, 0x20a9, 0x0010,
- 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x1d1f, 0xa200, 0x0070,
- 0x1d23, 0x0078, 0x1d1a, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9,
- 0x0010, 0xa005, 0x0040, 0x1d49, 0xa11a, 0x00c8, 0x1d49, 0x8213,
- 0x818d, 0x0048, 0x1d3a, 0xa11a, 0x00c8, 0x1d3b, 0x0070, 0x1d41,
- 0x0078, 0x1d2f, 0xa11a, 0x2308, 0x8210, 0x0070, 0x1d41, 0x0078,
- 0x1d2f, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
- 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x1d45, 0x7994,
- 0x70d0, 0xa106, 0x0040, 0x1dbd, 0x2091, 0x8000, 0x2071, 0x0020,
- 0x7004, 0xa005, 0x00c0, 0x1dbd, 0x7008, 0x7208, 0xa206, 0x00c0,
- 0x1dbd, 0xa286, 0x0008, 0x00c0, 0x1dbd, 0x2071, 0x0010, 0x1078,
- 0x1980, 0x0040, 0x1dbd, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa184,
- 0xff00, 0x0040, 0x1d8b, 0x2031, 0x0000, 0x810b, 0x86b5, 0x810b,
- 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b, 0x86b5, 0x810b,
- 0x86b5, 0x2100, 0xa210, 0x2600, 0xa319, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0x0078, 0x1d95, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
- 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x2009, 0x0020, 0x1078,
- 0x197b, 0x2091, 0x8001, 0x0040, 0x1db4, 0x1078, 0x199a, 0x78a8,
- 0x8000, 0x78aa, 0xa086, 0x0002, 0x00c0, 0x1dbd, 0x2091, 0x8000,
- 0x78e3, 0x0002, 0x78ab, 0x0000, 0x78cc, 0xa085, 0x0003, 0x78ce,
- 0x2091, 0x8001, 0x0078, 0x1dbd, 0x78ab, 0x0000, 0x1078, 0x2149,
- 0x6004, 0xa084, 0x000f, 0x0079, 0x1dc2, 0x2071, 0x0010, 0x2091,
- 0x8001, 0x007c, 0x1dd2, 0x1df4, 0x1e1a, 0x1dd2, 0x1e37, 0x1de1,
- 0x1fc9, 0x1fe4, 0x1dd2, 0x1dee, 0x1e14, 0x1e7f, 0x1eee, 0x1f57,
- 0x1f69, 0x1fe0, 0x2039, 0x0400, 0x78dc, 0xa705, 0x78de, 0x6008,
- 0xa705, 0x600a, 0x1078, 0x2064, 0x609c, 0x78da, 0x1078, 0x2131,
- 0x007c, 0x78dc, 0xa084, 0x0100, 0x0040, 0x1de8, 0x0078, 0x1dd2,
- 0x601c, 0xa085, 0x0080, 0x601e, 0x0078, 0x1dfb, 0x1078, 0x1bc4,
- 0x00c0, 0x1dd2, 0x1078, 0x2163, 0x78dc, 0xa084, 0x0100, 0x0040,
- 0x1dfb, 0x0078, 0x1dd2, 0x78df, 0x0000, 0x6004, 0x8007, 0xa084,
- 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x1e11, 0x1078,
- 0x2064, 0x0040, 0x1e11, 0x78dc, 0xa085, 0x0100, 0x78de, 0x0078,
- 0x1e13, 0x1078, 0x2088, 0x007c, 0x1078, 0x1bc4, 0x00c0, 0x1dd2,
- 0x1078, 0x215f, 0x78dc, 0xa08c, 0x0e00, 0x00c0, 0x1e23, 0xa084,
- 0x0100, 0x00c0, 0x1e25, 0x0078, 0x1dd2, 0x1078, 0x2064, 0x00c0,
- 0x1e36, 0x6104, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x2021,
- 0xa186, 0x000f, 0x0040, 0x2021, 0x1078, 0x2088, 0x007c, 0x78dc,
- 0xa084, 0x0100, 0x0040, 0x1e3e, 0x0078, 0x1dd2, 0x78df, 0x0000,
- 0x6714, 0x2011, 0x0001, 0x20a9, 0x0001, 0x6018, 0xa084, 0x00ff,
- 0xa005, 0x0040, 0x1e61, 0x2011, 0x0001, 0xa7bc, 0xff00, 0x20a9,
- 0x0020, 0xa08e, 0x0001, 0x0040, 0x1e61, 0x2039, 0x0000, 0x2011,
- 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040, 0x1e61, 0x0078,
- 0x1e7c, 0x1078, 0x19c5, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f,
- 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091,
- 0x8001, 0x0070, 0x1e75, 0x0078, 0x1e63, 0x8211, 0x0040, 0x1e7c,
- 0x20a9, 0x0100, 0x0078, 0x1e63, 0x1078, 0x199a, 0x007c, 0x2001,
- 0x5267, 0x2004, 0xa084, 0x8000, 0x0040, 0x2049, 0x6114, 0x1078,
- 0x2180, 0x6900, 0xa184, 0x0001, 0x0040, 0x1ea0, 0x6028, 0xa084,
- 0x00ff, 0x00c0, 0x2041, 0x6800, 0xa084, 0x0001, 0x0040, 0x2049,
- 0x6803, 0x0000, 0x680b, 0x0000, 0x6807, 0x0000, 0x0078, 0x2051,
- 0x2011, 0x0001, 0x6020, 0xd0f4, 0x0040, 0x1ea8, 0xa295, 0x0002,
- 0xd0c4, 0x0040, 0x1ead, 0xa295, 0x0008, 0xd0cc, 0x0040, 0x1eb2,
- 0xa295, 0x0400, 0x601c, 0xa084, 0x0002, 0x0040, 0x1eb9, 0xa295,
- 0x0004, 0x602c, 0xa08c, 0x00ff, 0xa182, 0x0002, 0x0048, 0x204d,
- 0xa182, 0x001b, 0x00c8, 0x204d, 0x0040, 0x204d, 0x690e, 0x602c,
- 0x8007, 0xa08c, 0x00ff, 0xa182, 0x0002, 0x0048, 0x204d, 0xa182,
- 0x001b, 0x00c8, 0x204d, 0x0040, 0x204d, 0x6912, 0x6030, 0xa005,
- 0x00c0, 0x1edc, 0x2001, 0x001e, 0x8000, 0x6816, 0x6028, 0xa084,
- 0x00ff, 0x0040, 0x2049, 0x6806, 0x6028, 0x8007, 0xa084, 0x00ff,
- 0x0040, 0x2049, 0x680a, 0x6a02, 0x0078, 0x2051, 0x2001, 0x5240,
- 0x2004, 0xa086, 0x0007, 0x00c0, 0x1f53, 0x2001, 0x5267, 0x2004,
- 0xa084, 0x8000, 0x0040, 0x2049, 0x6114, 0x1078, 0x2180, 0x2001,
- 0x5252, 0x2004, 0x2010, 0x82ff, 0x0040, 0x1f0e, 0xa080, 0x0005,
- 0x2004, 0xa084, 0x00ff, 0xa106, 0x00c0, 0x1f53, 0x2091, 0x8000,
- 0x6a04, 0x6b08, 0x6418, 0xa484, 0x0003, 0x0040, 0x1f2d, 0x6128,
- 0xa18c, 0x00ff, 0x8001, 0x00c0, 0x1f23, 0x2100, 0xa210, 0x0048,
- 0x1f53, 0x0078, 0x1f2d, 0x8001, 0x00c0, 0x1f53, 0x2100, 0xa212,
- 0x0048, 0x1f53, 0x82ff, 0x0040, 0x1f53, 0xa484, 0x000c, 0x0040,
- 0x1f47, 0x6128, 0x810f, 0xa18c, 0x00ff, 0xa082, 0x0004, 0x00c0,
- 0x1f3f, 0x2100, 0xa318, 0x0048, 0x1f53, 0x0078, 0x1f47, 0xa082,
- 0x0004, 0x00c0, 0x1f53, 0x2100, 0xa31a, 0x0048, 0x1f53, 0x6030,
- 0xa005, 0x0040, 0x1f4d, 0x8000, 0x6816, 0x6a06, 0x6b0a, 0x2091,
- 0x8001, 0x0078, 0x2051, 0x2091, 0x8001, 0x0078, 0x204d, 0x6114,
- 0x1078, 0x2180, 0x2091, 0x8000, 0x6b08, 0x8318, 0x0048, 0x1f65,
- 0x6b0a, 0x2091, 0x8001, 0x0078, 0x2060, 0x2091, 0x8001, 0x0078,
- 0x204d, 0x6024, 0x8007, 0xa084, 0x00ff, 0x0040, 0x1f87, 0xa086,
- 0x0080, 0x00c0, 0x1fc7, 0x20a9, 0x0008, 0x2069, 0x7610, 0x2091,
- 0x8000, 0x6800, 0xa084, 0xfcff, 0x6802, 0xade8, 0x0008, 0x0070,
- 0x1f83, 0x0078, 0x1f79, 0x2091, 0x8001, 0x0078, 0x2051, 0x6028,
- 0xa015, 0x0040, 0x1fc7, 0x6114, 0x1078, 0x2180, 0x0c7e, 0x0d7e,
- 0xade8, 0x0007, 0x2091, 0x8000, 0x6800, 0xa00d, 0x0040, 0x1fc3,
- 0xa206, 0x0040, 0x1f9e, 0x2168, 0x0078, 0x1f94, 0x2160, 0x6000,
- 0x6802, 0x2c68, 0x1078, 0x19ac, 0x0d7f, 0x6818, 0xa00d, 0x0040,
- 0x1fbb, 0x2060, 0x6200, 0x6a1a, 0x6a1c, 0x6202, 0x681e, 0x1078,
- 0x1989, 0x2da0, 0x2198, 0x20a9, 0x0031, 0x53a3, 0x2d60, 0x1078,
- 0x1ccb, 0x0078, 0x1fbe, 0x6808, 0x8000, 0x680a, 0x2091, 0x8001,
- 0x0c7f, 0x0078, 0x2060, 0x2091, 0x8001, 0x0d7f, 0x0c7f, 0x0078,
- 0x2049, 0x6114, 0x1078, 0x2180, 0x6800, 0xa084, 0x0001, 0x0040,
- 0x2039, 0x2091, 0x8000, 0x6a04, 0x8210, 0x0048, 0x1fdc, 0x6a06,
- 0x2091, 0x8001, 0x0078, 0x2060, 0x2091, 0x8001, 0x0078, 0x204d,
- 0x1078, 0x1bc4, 0x00c0, 0x1dd2, 0x6114, 0x1078, 0x2180, 0x60be,
- 0x60bb, 0x0000, 0x6900, 0xa184, 0x0008, 0x0040, 0x1ff3, 0x6020,
- 0xa085, 0x0100, 0x6022, 0xa184, 0x0001, 0x0040, 0x2049, 0xa184,
- 0x0100, 0x00c0, 0x2035, 0xa184, 0x0200, 0x00c0, 0x2031, 0x681c,
- 0xa005, 0x00c0, 0x203d, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000f,
- 0x00c0, 0x200c, 0x1078, 0x2163, 0x78df, 0x0000, 0x6004, 0x8007,
- 0xa084, 0x00ff, 0x78d2, 0x8001, 0x609f, 0x0000, 0x0040, 0x2021,
- 0x1078, 0x2064, 0x0040, 0x2021, 0x78dc, 0xa085, 0x0100, 0x78de,
- 0x007c, 0x78d7, 0x0000, 0x78db, 0x0000, 0x6024, 0xa084, 0xff00,
- 0x6026, 0x1078, 0x3aac, 0x0040, 0x1d4f, 0x1078, 0x1be9, 0x0078,
- 0x1d4f, 0x2009, 0x0017, 0x0078, 0x2053, 0x2009, 0x000e, 0x0078,
- 0x2053, 0x2009, 0x0007, 0x0078, 0x2053, 0x2009, 0x0035, 0x0078,
- 0x2053, 0x2009, 0x003e, 0x0078, 0x2053, 0x2009, 0x0004, 0x0078,
- 0x2053, 0x2009, 0x0006, 0x0078, 0x2053, 0x2009, 0x0016, 0x0078,
- 0x2053, 0x2009, 0x0001, 0x6024, 0xa084, 0xff00, 0xa105, 0x6026,
- 0x2091, 0x8000, 0x1078, 0x1ccb, 0x2091, 0x8001, 0x0078, 0x1d4f,
- 0x1078, 0x199a, 0x0078, 0x1d4f, 0x78d4, 0xa06d, 0x00c0, 0x206f,
- 0x2c00, 0x78d6, 0x78da, 0x609f, 0x0000, 0x0078, 0x207b, 0x2c00,
- 0x689e, 0x609f, 0x0000, 0x78d6, 0x2d00, 0x6002, 0x78d8, 0xad06,
- 0x00c0, 0x207b, 0x6002, 0x78d0, 0x8001, 0x78d2, 0x00c0, 0x2087,
- 0x78dc, 0xa084, 0xfeff, 0x78de, 0x78d8, 0x2060, 0xa006, 0x007c,
- 0xa02e, 0x2530, 0x611c, 0x61a2, 0xa184, 0xe1ff, 0x601e, 0xa184,
- 0x0060, 0x0040, 0x2097, 0x0e7e, 0x1078, 0x48d3, 0x0e7f, 0x6596,
- 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714,
- 0x1078, 0x19c5, 0x2091, 0x8000, 0x60a0, 0xa084, 0x8000, 0x00c0,
- 0x20be, 0x6808, 0xa084, 0x0001, 0x0040, 0x20be, 0x2091, 0x8001,
- 0x1078, 0x1a31, 0x2091, 0x8000, 0x1078, 0x1ccb, 0x2091, 0x8001,
- 0x78d7, 0x0000, 0x78db, 0x0000, 0x0078, 0x2130, 0x6024, 0xa096,
- 0x0001, 0x00c0, 0x20c5, 0x8000, 0x6026, 0x6a10, 0x6814, 0x2091,
- 0x8001, 0xa202, 0x0048, 0x20d4, 0x0040, 0x20d4, 0x2039, 0x0200,
- 0x1078, 0x2131, 0x0078, 0x2130, 0x2c08, 0x2091, 0x8000, 0x60a0,
- 0xa084, 0x8000, 0x0040, 0x2101, 0x6800, 0xa065, 0x0040, 0x2106,
- 0x6a04, 0x0e7e, 0x2071, 0x5240, 0x7000, 0xa084, 0x0001, 0x0040,
- 0x20fb, 0x7048, 0xa206, 0x00c0, 0x20fb, 0x6b04, 0x231c, 0x2160,
- 0x6302, 0x2300, 0xa005, 0x00c0, 0x20f6, 0x6902, 0x2260, 0x6102,
- 0x0e7f, 0x0078, 0x210d, 0x2160, 0x6202, 0x6906, 0x0e7f, 0x0078,
- 0x210d, 0x6800, 0xa065, 0x0040, 0x2106, 0x6102, 0x6902, 0x00c0,
- 0x210a, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0x60a0, 0xa084,
- 0x8000, 0x0040, 0x2117, 0x6808, 0xa084, 0xfffc, 0x680a, 0x6810,
- 0x8000, 0x6812, 0x2091, 0x8001, 0x6808, 0xa08c, 0x0040, 0x0040,
- 0x2126, 0xa086, 0x0040, 0x680a, 0x1078, 0x1a42, 0x2091, 0x8000,
- 0x1078, 0x226f, 0x2091, 0x8001, 0x78db, 0x0000, 0x78d7, 0x0000,
- 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x1ccb,
- 0x2091, 0x8001, 0x78d8, 0xa065, 0x0040, 0x2144, 0x609c, 0x78da,
- 0x609f, 0x0000, 0x0078, 0x2134, 0x78d7, 0x0000, 0x78db, 0x0000,
- 0x007c, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x2150, 0xa006,
- 0x7896, 0x70d2, 0x7804, 0xa005, 0x0040, 0x215e, 0x8001, 0x7806,
- 0x00c0, 0x215e, 0x0068, 0x215e, 0x2091, 0x4080, 0x007c, 0x2039,
- 0x2177, 0x0078, 0x2165, 0x2039, 0x217d, 0x2704, 0xa005, 0x0040,
- 0x2176, 0xac00, 0x2068, 0x6b08, 0x6c0c, 0x6910, 0x6a14, 0x690a,
- 0x6a0e, 0x6b12, 0x6c16, 0x8738, 0x0078, 0x2165, 0x007c, 0x0003,
- 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000,
- 0x0c7e, 0x1078, 0x3c3b, 0x2c68, 0x0c7f, 0x007c, 0x0010, 0x21f7,
- 0x0068, 0x21f7, 0x2029, 0x0000, 0x78cb, 0x0000, 0x788c, 0xa065,
- 0x0040, 0x21f0, 0x2009, 0x5274, 0x2104, 0xa084, 0x0001, 0x0040,
- 0x21be, 0x6004, 0xa086, 0x0103, 0x00c0, 0x21be, 0x6018, 0xa005,
- 0x00c0, 0x21be, 0x6014, 0xa005, 0x00c0, 0x21be, 0x0d7e, 0x2069,
- 0x0000, 0x6818, 0xa084, 0x0001, 0x00c0, 0x21bd, 0x600c, 0x70c6,
- 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080,
- 0x0d7f, 0x1078, 0x1cf2, 0x0078, 0x21f5, 0x0d7f, 0x1078, 0x21f8,
- 0x0040, 0x21f0, 0x6204, 0xa294, 0x00ff, 0xa296, 0x0003, 0x0040,
- 0x21d0, 0x6204, 0xa296, 0x0110, 0x00c0, 0x21de, 0x78cb, 0x0001,
- 0x6204, 0xa294, 0xff00, 0x8217, 0x8211, 0x0040, 0x21de, 0x85ff,
- 0x00c0, 0x21f0, 0x8210, 0xa202, 0x00c8, 0x21f0, 0x057e, 0x1078,
- 0x2207, 0x057f, 0x0040, 0x21eb, 0x78e0, 0xa086, 0x0003, 0x0040,
- 0x21f0, 0x0078, 0x21de, 0x8528, 0x78c8, 0xa005, 0x0040, 0x218e,
- 0x85ff, 0x0040, 0x21f7, 0x2091, 0x4080, 0x78b0, 0x70d6, 0x007c,
- 0x7bac, 0x79b0, 0x70d4, 0xa102, 0x00c0, 0x2201, 0x2300, 0xa005,
- 0x007c, 0x0048, 0x2205, 0xa302, 0x007c, 0x8002, 0x007c, 0x2001,
- 0x04fd, 0x2004, 0xa082, 0x0005, 0x00c8, 0x2221, 0x2091, 0x8000,
- 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2256, 0x7008, 0x7208,
- 0xa206, 0x00c0, 0x2256, 0xa286, 0x0008, 0x00c0, 0x2256, 0x2071,
- 0x0010, 0x1078, 0x225b, 0x2009, 0x0020, 0x6004, 0xa086, 0x0103,
- 0x00c0, 0x2230, 0x6028, 0xa005, 0x00c0, 0x2230, 0x2009, 0x000c,
- 0x1078, 0x1976, 0x0040, 0x2249, 0x78c4, 0x8000, 0x78c6, 0xa086,
- 0x0002, 0x00c0, 0x2256, 0x2091, 0x8000, 0x78e3, 0x0003, 0x78c7,
- 0x0000, 0x78cc, 0xa085, 0x0300, 0x78ce, 0x2091, 0x8001, 0x0078,
- 0x2256, 0x78c7, 0x0000, 0x1078, 0x1cf2, 0x79ac, 0x78b0, 0x8000,
- 0xa10a, 0x00c8, 0x2254, 0xa006, 0x78b2, 0xa006, 0x2071, 0x0010,
- 0x2091, 0x8001, 0x007c, 0x8107, 0x8004, 0x8004, 0x7ab8, 0x7bb4,
- 0x7cc0, 0x7dbc, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0x007c, 0x2009, 0x525b, 0x2091, 0x8000, 0x200a, 0x0f7e,
- 0x0e7e, 0x2071, 0x5240, 0x7000, 0xa086, 0x0000, 0x00c0, 0x2289,
- 0x2009, 0x5212, 0x2104, 0xa005, 0x00c0, 0x2289, 0x2079, 0x0100,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2289, 0x0018, 0x2289, 0x781b,
- 0x004b, 0x0e7f, 0x0f7f, 0x007c, 0x0f7e, 0x0e7e, 0x2071, 0x5240,
- 0x2091, 0x8000, 0x7000, 0xa086, 0x0000, 0x00c0, 0x22a2, 0x2079,
- 0x0100, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x22a2, 0x0018, 0x22a2,
- 0x781b, 0x004d, 0x2091, 0x8001, 0x0e7f, 0x0f7f, 0x007c, 0x127e,
- 0x2091, 0x2300, 0x2071, 0x5240, 0x2079, 0x0100, 0x784b, 0x000f,
- 0x0098, 0x22b5, 0x7838, 0x0078, 0x22ae, 0x20a9, 0x0040, 0x7800,
- 0xa082, 0x0004, 0x0048, 0x22be, 0x20a9, 0x0060, 0x789b, 0x0000,
- 0x78af, 0x0000, 0x78af, 0x0000, 0x0070, 0x22c8, 0x0078, 0x22c0,
- 0x7800, 0xa082, 0x0004, 0x0048, 0x22d7, 0x70b7, 0x0093, 0x2019,
- 0x4ff0, 0x1078, 0x2313, 0x702f, 0x8001, 0x0078, 0x22e3, 0x70b7,
- 0x0000, 0x2019, 0x4e70, 0x1078, 0x2313, 0x2019, 0x4eaf, 0x1078,
- 0x2313, 0x702f, 0x8000, 0x7003, 0x0000, 0x1078, 0x2420, 0x7004,
- 0xa084, 0x000f, 0x017e, 0x2009, 0x04fd, 0x210c, 0xa18a, 0x0005,
- 0x0048, 0x22f8, 0x0038, 0x22fe, 0xa085, 0x6280, 0x0078, 0x2300,
- 0x0028, 0x22fe, 0xa085, 0x6280, 0x0078, 0x2300, 0xa085, 0x62c0,
- 0x017f, 0x7806, 0x780f, 0xb204, 0x7843, 0x00d8, 0x7853, 0x0080,
- 0x780b, 0x0008, 0x7047, 0x0008, 0x7053, 0x527f, 0x704f, 0x0000,
- 0x127f, 0x2000, 0x007c, 0x137e, 0x147e, 0x157e, 0x047e, 0x20a1,
- 0x012b, 0x2304, 0xa005, 0x789a, 0x0040, 0x2333, 0x8318, 0x2324,
- 0x8318, 0x2398, 0x24a8, 0xa484, 0xff00, 0x0040, 0x232b, 0xa482,
- 0x0100, 0x20a9, 0x0100, 0x2020, 0x53a6, 0xa005, 0x00c0, 0x2322,
- 0x3318, 0x0078, 0x2319, 0x047f, 0x157f, 0x147f, 0x137f, 0x007c,
- 0xa18c, 0x000f, 0x2011, 0x0101, 0x2204, 0xa084, 0xfff0, 0xa105,
- 0x2012, 0x1078, 0x2420, 0x007c, 0x2011, 0x0101, 0x20a9, 0x0009,
- 0x810b, 0x0070, 0x234d, 0x0078, 0x2348, 0xa18c, 0x0e00, 0x2204,
- 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2009, 0x0101, 0x20a9,
- 0x0005, 0x8213, 0x0070, 0x235e, 0x0078, 0x2359, 0xa294, 0x00e0,
- 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x007c, 0x2011, 0x0101,
- 0x20a9, 0x000c, 0x810b, 0x0070, 0x236f, 0x0078, 0x236a, 0xa18c,
- 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0x2011,
- 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x8103,
- 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x62ac,
- 0x63ac, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e,
- 0x2061, 0x0100, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f,
- 0x007c, 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100,
- 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x8103,
- 0x8003, 0xa080, 0x0020, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4,
- 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091,
- 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005, 0x0040, 0x23fe, 0x2061,
- 0x7600, 0x1078, 0x2406, 0x0040, 0x23e8, 0x20a9, 0x0000, 0x2061,
- 0x7500, 0x0c7e, 0x1078, 0x2406, 0x0040, 0x23d6, 0x0c7f, 0x8c60,
- 0x0070, 0x23d4, 0x0078, 0x23c9, 0x0078, 0x23fe, 0x007f, 0xa082,
- 0x7500, 0x2071, 0x5240, 0x7086, 0x7182, 0x2001, 0x0004, 0x706e,
- 0x7093, 0x000f, 0x7073, 0x0000, 0x1078, 0x226a, 0x0078, 0x23fa,
- 0x60c0, 0xa005, 0x00c0, 0x23fe, 0x2071, 0x5240, 0x7182, 0x2c00,
- 0x708a, 0x2001, 0x0006, 0x706e, 0x7093, 0x000f, 0x7073, 0x0000,
- 0x1078, 0x226a, 0x2001, 0x0000, 0x0078, 0x2400, 0x2001, 0x0001,
- 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005,
- 0x0040, 0x241d, 0x2060, 0x600c, 0xa306, 0x00c0, 0x241a, 0x6010,
- 0xa206, 0x00c0, 0x241a, 0x6014, 0xa106, 0x00c0, 0x241a, 0xa006,
- 0x0078, 0x241f, 0x6000, 0x0078, 0x2407, 0xa085, 0x0001, 0x007c,
- 0x2011, 0x5241, 0x220c, 0xa18c, 0x000f, 0x2011, 0x013b, 0x2204,
- 0xa084, 0x0100, 0x0040, 0x2436, 0x2021, 0xff04, 0x2122, 0x810b,
- 0x810b, 0x810b, 0x810b, 0xa18d, 0x0f00, 0x2104, 0x007c, 0x0e7e,
- 0x68e4, 0xa08c, 0x0020, 0x0040, 0x248a, 0xa084, 0x0006, 0x00c0,
- 0x248a, 0x6014, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
- 0xa0f0, 0x5480, 0x7004, 0xa084, 0x000a, 0x00c0, 0x248a, 0x7108,
- 0xa194, 0xff00, 0x0040, 0x248a, 0xa18c, 0x00ff, 0x2001, 0x000c,
- 0xa106, 0x0040, 0x2471, 0x2001, 0x0012, 0xa106, 0x0040, 0x2475,
- 0x2001, 0x0014, 0xa106, 0x0040, 0x2479, 0x2001, 0x0019, 0xa106,
- 0x0040, 0x247d, 0x2001, 0x0032, 0xa106, 0x0040, 0x2481, 0x0078,
- 0x2485, 0x2009, 0x0012, 0x0078, 0x2487, 0x2009, 0x0014, 0x0078,
- 0x2487, 0x2009, 0x0019, 0x0078, 0x2487, 0x2009, 0x0020, 0x0078,
- 0x2487, 0x2009, 0x003f, 0x0078, 0x2487, 0x2011, 0x0000, 0x2100,
- 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x248c, 0x2091, 0x8000,
- 0x2071, 0x0000, 0x007e, 0x7018, 0xa084, 0x0001, 0x00c0, 0x2493,
- 0x007f, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002,
- 0x70db, 0x0741, 0x70df, 0x0006, 0x2071, 0x0000, 0x701b, 0x0001,
- 0x2091, 0x4080, 0x0078, 0x24aa, 0x107e, 0x007e, 0x127e, 0x2091,
- 0x2300, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x77c2, 0x74c6, 0x76ca,
- 0x75ce, 0xa594, 0x003f, 0xa49c, 0x0003, 0xa484, 0x000f, 0x0079,
- 0x24c1, 0x24d3, 0x24d3, 0x24d3, 0x280d, 0x3a09, 0x24d1, 0x2502,
- 0x250c, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1, 0x24d1,
- 0x24d1, 0x1078, 0x248c, 0x8507, 0xa084, 0x001f, 0x0079, 0x24d8,
- 0x2516, 0x280d, 0x29c7, 0x2ac4, 0x2aec, 0x2d8c, 0x3037, 0x309a,
- 0x30fb, 0x3180, 0x3238, 0x32d6, 0x2502, 0x28e9, 0x300c, 0x24f8,
- 0x3dac, 0x3dcc, 0x3f8f, 0x3f9b, 0x4074, 0x24f8, 0x24f8, 0x4149,
- 0x414d, 0x3daa, 0x24f8, 0x3efa, 0x24f8, 0x3c5e, 0x250c, 0x24f8,
- 0x1078, 0x248c, 0x0018, 0x24b1, 0x127f, 0x2091, 0x8001, 0x007f,
- 0x107f, 0x007c, 0x2019, 0x4f49, 0x1078, 0x2313, 0x702f, 0x0001,
- 0x781b, 0x004f, 0x0078, 0x24fa, 0x2019, 0x4eaf, 0x1078, 0x2313,
- 0x702f, 0x8000, 0x781b, 0x00cd, 0x0078, 0x24fa, 0x7242, 0x2009,
- 0x520f, 0x200b, 0x0000, 0xa584, 0x0001, 0x00c0, 0x3c72, 0x0040,
- 0x2533, 0x1078, 0x248c, 0x7003, 0x0000, 0x704b, 0x0000, 0x7043,
- 0x0000, 0x7037, 0x0000, 0x1078, 0x39e0, 0x0018, 0x24b1, 0x2009,
- 0x520f, 0x200b, 0x0000, 0x7068, 0xa005, 0x00c0, 0x25fe, 0x706c,
- 0xa084, 0x0007, 0x0079, 0x253c, 0x2635, 0x2544, 0x2550, 0x256d,
- 0x258f, 0x25dc, 0x25b5, 0x2544, 0x1078, 0x39c8, 0x2009, 0x0048,
- 0x1078, 0x2ed8, 0x00c0, 0x254e, 0x7003, 0x0004, 0x0078, 0x24fa,
- 0x1078, 0x39c8, 0x00c0, 0x256b, 0x7080, 0x8007, 0x7882, 0x789b,
- 0x0010, 0x78ab, 0x000c, 0x789b, 0x0060, 0x78ab, 0x0001, 0x785b,
- 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0, 0x256b, 0x7003,
- 0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0,
- 0x258d, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
- 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
- 0x0002, 0x785b, 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0,
- 0x258d, 0x7003, 0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078,
- 0x39c8, 0x00c0, 0x25b3, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010,
- 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0020, 0x7184,
- 0x79aa, 0x78ab, 0x000d, 0x789b, 0x0060, 0x78ab, 0x0004, 0x785b,
- 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0, 0x25b3, 0x7003,
- 0x0004, 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0,
- 0x25da, 0x7180, 0x8107, 0x7882, 0x789b, 0x0010, 0xa18c, 0x001f,
- 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
- 0x0002, 0x785b, 0x0004, 0x2009, 0x00dd, 0x1078, 0x2ecc, 0x00c0,
- 0x25da, 0x7088, 0x708b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0002,
- 0x7093, 0x000f, 0x0078, 0x24fa, 0x1078, 0x39c8, 0x00c0, 0x24fa,
- 0x7088, 0x2068, 0x6f14, 0x1078, 0x38bd, 0x2c50, 0x1078, 0x3a7a,
- 0x789b, 0x0010, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa,
- 0x6e1c, 0x2041, 0x0001, 0x708c, 0xa084, 0x0400, 0x2001, 0x0004,
- 0x0040, 0x25fc, 0x2001, 0x0006, 0x0078, 0x271d, 0x1078, 0x39c8,
- 0x00c0, 0x24fa, 0x789b, 0x0010, 0x7068, 0x2068, 0x6f14, 0x1078,
- 0x38bd, 0x2c50, 0x1078, 0x3a7a, 0x6008, 0xa085, 0x0010, 0x600a,
- 0x6824, 0xa005, 0x0040, 0x261c, 0xa082, 0x0006, 0x0048, 0x261a,
- 0x0078, 0x261c, 0x6827, 0x0005, 0x6b14, 0xa39c, 0x001f, 0xa39d,
- 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040, 0x262a, 0xa684, 0x0001,
- 0x0040, 0x262c, 0xa39c, 0xffbf, 0x7baa, 0x2031, 0x0020, 0x2041,
- 0x0001, 0x2001, 0x0003, 0x0078, 0x271d, 0x0018, 0x24b1, 0x744c,
- 0xa485, 0x0000, 0x0040, 0x264f, 0xa080, 0x5280, 0x2030, 0x7150,
- 0x8108, 0xa12a, 0x0048, 0x2646, 0x2009, 0x5280, 0x2164, 0x6504,
- 0x85ff, 0x00c0, 0x2660, 0x8421, 0x00c0, 0x2640, 0x7152, 0x7003,
- 0x0000, 0x704b, 0x0000, 0x7040, 0xa005, 0x0040, 0x3c72, 0x0078,
- 0x24fa, 0x764c, 0xa6b0, 0x5280, 0x7150, 0x2600, 0x0078, 0x264b,
- 0x7152, 0x2568, 0x2558, 0x754a, 0x2c50, 0x6034, 0xa085, 0x0000,
- 0x00c0, 0x265d, 0x6708, 0x773a, 0xa784, 0x033f, 0x0040, 0x2696,
- 0xa784, 0x0021, 0x00c0, 0x265d, 0xa784, 0x0002, 0x0040, 0x267f,
- 0xa784, 0x0004, 0x0040, 0x265d, 0xa7bc, 0xfffb, 0x670a, 0xa784,
- 0x0008, 0x00c0, 0x265d, 0xa784, 0x0010, 0x00c0, 0x265d, 0xa784,
- 0x0200, 0x00c0, 0x265d, 0xa784, 0x0100, 0x0040, 0x2696, 0x6018,
- 0xa005, 0x00c0, 0x265d, 0xa7bc, 0xfeff, 0x670a, 0x6823, 0x0000,
- 0x6e1c, 0xa684, 0x000e, 0x6118, 0x0040, 0x26a6, 0x601c, 0xa102,
- 0x0048, 0x26a9, 0x0040, 0x26a9, 0x0078, 0x2659, 0x81ff, 0x00c0,
- 0x2659, 0x68c3, 0x0000, 0xa784, 0x0080, 0x00c0, 0x26b1, 0x700c,
- 0x6022, 0xa7bc, 0xff7f, 0x670a, 0x1078, 0x3a7a, 0x0018, 0x24b1,
- 0x789b, 0x0010, 0xa046, 0x1078, 0x39c8, 0x00c0, 0x24fa, 0x6b14,
- 0xa39c, 0x001f, 0xa39d, 0x00c0, 0x7058, 0xa084, 0x8000, 0x0040,
- 0x26cd, 0xa684, 0x0001, 0x0040, 0x26cf, 0xa39c, 0xffbf, 0xa684,
- 0x0010, 0x0040, 0x26d5, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684,
- 0x000e, 0x00c0, 0x26e0, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x271b,
- 0x7158, 0xa18c, 0x0800, 0x0040, 0x34cb, 0x2011, 0x0020, 0xa684,
- 0x0008, 0x00c0, 0x26f1, 0x8210, 0xa684, 0x0002, 0x00c0, 0x26f1,
- 0x8210, 0x7aaa, 0x8840, 0x1078, 0x39e0, 0x6a14, 0x610c, 0x8108,
- 0xa18c, 0x00ff, 0xa1e0, 0x7500, 0x2c64, 0x8cff, 0x0040, 0x2712,
- 0x6014, 0xa206, 0x00c0, 0x26fc, 0x60b8, 0x8001, 0x60ba, 0x00c0,
- 0x26f7, 0x0c7e, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x0c7f,
- 0x0078, 0x2635, 0x1078, 0x39c8, 0x00c0, 0x24fa, 0x2a60, 0x610e,
- 0x79aa, 0x8840, 0x7132, 0x2001, 0x0001, 0x007e, 0x715c, 0xa184,
- 0x0018, 0x0040, 0x2738, 0xa184, 0x0010, 0x0040, 0x272b, 0x1078,
- 0x36d0, 0x00c0, 0x275b, 0xa184, 0x0008, 0x0040, 0x2738, 0x69a0,
- 0xa184, 0x0600, 0x00c0, 0x2738, 0x1078, 0x35bb, 0x0078, 0x275b,
- 0x69a0, 0xa184, 0x0800, 0x0040, 0x274f, 0x0c7e, 0x027e, 0x2960,
- 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106,
- 0x027f, 0x0c7f, 0x1078, 0x36d0, 0x00c0, 0x275b, 0x69a0, 0xa184,
- 0x0200, 0x0040, 0x2757, 0x1078, 0x360c, 0x0078, 0x275b, 0xa184,
- 0x0400, 0x00c0, 0x2734, 0x69a0, 0xa184, 0x1000, 0x0040, 0x2766,
- 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x238b, 0x007f, 0x7002,
- 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2774, 0xa086, 0x0060,
- 0x00c0, 0x2774, 0xa18d, 0x4000, 0x88ff, 0x0040, 0x2779, 0xa18d,
- 0x0004, 0x795a, 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b,
- 0x0061, 0x6818, 0xa08d, 0x8000, 0xa084, 0x7fff, 0x691a, 0xa68c,
- 0x0080, 0x0040, 0x2798, 0x7097, 0x0000, 0xa08a, 0x000d, 0x0050,
- 0x2796, 0xa08a, 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a,
- 0x78aa, 0x8008, 0x810c, 0x0040, 0x34d1, 0xa18c, 0x00f8, 0x00c0,
- 0x34d1, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
- 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
- 0x157f, 0x6814, 0x8007, 0x7882, 0x6d94, 0x7dd6, 0x7dde, 0x6e98,
- 0x7ed2, 0x7eda, 0x1078, 0x39c8, 0x00c0, 0x27cf, 0x702c, 0x8003,
- 0x0048, 0x27c8, 0x2019, 0x4eaf, 0x1078, 0x2313, 0x702f, 0x8000,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x27cf, 0x0098, 0x27d7, 0x6008,
- 0xa084, 0xffef, 0x600a, 0x1078, 0x39e0, 0x0078, 0x2523, 0x7200,
- 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x27e4, 0x781b, 0x004f,
- 0x1078, 0x39e0, 0x0078, 0x27f5, 0x6ab4, 0xa295, 0x2000, 0x7a5a,
- 0x781b, 0x004f, 0x1078, 0x39e0, 0x7200, 0x2500, 0xa605, 0x0040,
- 0x27f5, 0xa284, 0x0007, 0x1079, 0x2803, 0xad80, 0x0009, 0x7036,
- 0xa284, 0x0007, 0xa086, 0x0001, 0x00c0, 0x24fa, 0x6018, 0x8000,
- 0x601a, 0x0078, 0x24fa, 0x280b, 0x4b4b, 0x4b4b, 0x4b3a, 0x4b4b,
- 0x280b, 0x4b3a, 0x280b, 0x1078, 0x248c, 0x1078, 0x39c8, 0x0f7e,
- 0x2079, 0x5200, 0x78cc, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x2831,
- 0x706c, 0xa086, 0x0001, 0x00c0, 0x2820, 0x706e, 0x0078, 0x28c4,
- 0x706c, 0xa086, 0x0005, 0x00c0, 0x282f, 0x7088, 0x2068, 0x681b,
- 0x0004, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822, 0x706f,
- 0x0000, 0x2011, 0x0004, 0x716c, 0xa186, 0x0001, 0x0040, 0x2852,
- 0xa186, 0x0007, 0x00c0, 0x2842, 0x2009, 0x5238, 0x200b, 0x0005,
- 0x0078, 0x2852, 0x2009, 0x5213, 0x2104, 0x2009, 0x5212, 0x200a,
- 0x2009, 0x5238, 0x200b, 0x0001, 0x706f, 0x0000, 0x7073, 0x0001,
- 0x0078, 0x2854, 0x706f, 0x0000, 0x1078, 0x4887, 0x157e, 0x20a9,
- 0x0010, 0x2039, 0x0000, 0x1078, 0x37b0, 0xa7b8, 0x0100, 0x0070,
- 0x2863, 0x0078, 0x285b, 0x157f, 0x7000, 0x0079, 0x2867, 0x2895,
- 0x287c, 0x287c, 0x286f, 0x2895, 0x2895, 0x2895, 0x2895, 0x2021,
- 0x525a, 0x2404, 0xa005, 0x0040, 0x2895, 0xad06, 0x00c0, 0x287c,
- 0x6800, 0x2022, 0x0078, 0x288c, 0x6820, 0xa084, 0x0001, 0x00c0,
- 0x2888, 0x6f14, 0x1078, 0x38bd, 0x1078, 0x34a2, 0x0078, 0x288c,
- 0x7060, 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000, 0x6820,
- 0xa085, 0x0008, 0x6822, 0x1078, 0x1cdc, 0x2021, 0x7600, 0x1078,
- 0x28d1, 0x2021, 0x525a, 0x1078, 0x28d1, 0x157e, 0x20a9, 0x0000,
- 0x2021, 0x7500, 0x1078, 0x28d1, 0x8420, 0x0070, 0x28a9, 0x0078,
- 0x28a2, 0x2061, 0x5500, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6018,
- 0x6110, 0x81ff, 0x0040, 0x28b8, 0xa102, 0x0050, 0x28b8, 0x6012,
- 0x601b, 0x0000, 0xace0, 0x0010, 0x0070, 0x28c0, 0x0078, 0x28af,
- 0x8421, 0x00c0, 0x28ad, 0x157f, 0x709c, 0xa084, 0x8000, 0x0040,
- 0x28cb, 0x1078, 0x3ace, 0x7003, 0x0000, 0x704b, 0x0000, 0x0078,
- 0x24fa, 0x047e, 0x2404, 0xa005, 0x0040, 0x28e5, 0x2068, 0x6800,
- 0x007e, 0x6a1a, 0x6817, 0x0000, 0x6820, 0xa085, 0x0008, 0x6822,
- 0x1078, 0x1cdc, 0x007f, 0x0078, 0x28d3, 0x047f, 0x2023, 0x0000,
- 0x007c, 0xa282, 0x0003, 0x0050, 0x28ef, 0x1078, 0x248c, 0x2300,
- 0x0079, 0x28f2, 0x28f5, 0x2968, 0x2985, 0xa282, 0x0002, 0x0040,
- 0x28fb, 0x1078, 0x248c, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000,
- 0x0079, 0x2902, 0x290a, 0x290a, 0x290c, 0x2940, 0x34d7, 0x290a,
- 0x2940, 0x290a, 0x1078, 0x248c, 0x7780, 0x1078, 0x37b0, 0x7780,
- 0xa7bc, 0x0f00, 0x1078, 0x38bd, 0x6018, 0xa005, 0x0040, 0x2937,
- 0x2021, 0x7600, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x29a0,
- 0x0040, 0x2937, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7500, 0x047e,
- 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x29a0, 0x047f, 0x0040,
- 0x2936, 0x8420, 0x0070, 0x2936, 0x0078, 0x2927, 0x157f, 0x8738,
- 0xa784, 0x001f, 0x00c0, 0x2912, 0x0078, 0x2523, 0x0078, 0x2523,
- 0x7780, 0x1078, 0x38bd, 0x6018, 0xa005, 0x0040, 0x2966, 0x2021,
- 0x7600, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x29a0, 0x0040,
- 0x2966, 0x157e, 0x20a9, 0x0000, 0x2021, 0x7500, 0x047e, 0x2009,
- 0x0005, 0x2011, 0x0020, 0x1078, 0x29a0, 0x047f, 0x0040, 0x2965,
- 0x8420, 0x0070, 0x2965, 0x0078, 0x2956, 0x157f, 0x0078, 0x2523,
- 0x2200, 0x0079, 0x296b, 0x296e, 0x2970, 0x2970, 0x1078, 0x248c,
- 0x2009, 0x0012, 0x706c, 0xa086, 0x0002, 0x0040, 0x2979, 0x2009,
- 0x000e, 0x6818, 0xa084, 0x8000, 0x0040, 0x297f, 0x691a, 0x706f,
- 0x0000, 0x7073, 0x0001, 0x0078, 0x3956, 0x2200, 0x0079, 0x2988,
- 0x298d, 0x2970, 0x298b, 0x1078, 0x248c, 0x1078, 0x4887, 0x7000,
- 0xa086, 0x0001, 0x00c0, 0x3467, 0x1078, 0x34b8, 0x6008, 0xa084,
- 0xffef, 0x600a, 0x1078, 0x345a, 0x0040, 0x3467, 0x0078, 0x2635,
- 0x2404, 0xa005, 0x0040, 0x29c3, 0x2068, 0x2d04, 0x007e, 0x6814,
- 0xa706, 0x0040, 0x29af, 0x2d20, 0x007f, 0x0078, 0x29a1, 0x007f,
- 0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205, 0x6822, 0x1078,
- 0x1cdc, 0x6010, 0x8001, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x1078, 0x34b8, 0x007c, 0xa085, 0x0001, 0x0078, 0x29c2, 0x2300,
- 0x0079, 0x29ca, 0x29cf, 0x29cd, 0x2a68, 0x1078, 0x248c, 0x78ec,
- 0xa084, 0x0001, 0x00c0, 0x29e3, 0x7000, 0xa086, 0x0004, 0x00c0,
- 0x29db, 0x0078, 0x2a06, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x0078, 0x3467, 0x78e4, 0xa005, 0x00d0, 0x2a06, 0x0018,
- 0x24fa, 0x2008, 0xa084, 0x0030, 0x00c0, 0x29f2, 0x781b, 0x004f,
- 0x0078, 0x24fa, 0x78ec, 0xa084, 0x0003, 0x0040, 0x29ee, 0x2100,
- 0xa084, 0x0007, 0x0079, 0x29fc, 0x2a3f, 0x2a4a, 0x2a30, 0x2a04,
- 0x39bb, 0x39bb, 0x2a04, 0x2a59, 0x1078, 0x248c, 0x7000, 0xa086,
- 0x0004, 0x00c0, 0x2a20, 0x706c, 0xa086, 0x0002, 0x00c0, 0x2a16,
- 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x28e9, 0x706c, 0xa086,
- 0x0006, 0x0040, 0x2a10, 0x706c, 0xa086, 0x0004, 0x0040, 0x2a10,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x2a2a, 0x78ec, 0xa084, 0x0003,
- 0x00c0, 0x2a2c, 0x0078, 0x300c, 0x2001, 0x0003, 0x0078, 0x2da0,
- 0x6818, 0xa084, 0x8000, 0x0040, 0x2a37, 0x681b, 0x001d, 0x1078,
- 0x378f, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x2a46, 0x681b, 0x001d, 0x1078, 0x378f,
- 0x0078, 0x3986, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a51, 0x681b,
- 0x001d, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b, 0x00ca, 0x0078,
- 0x24fa, 0x6818, 0xa084, 0x8000, 0x0040, 0x2a60, 0x681b, 0x001d,
- 0x1078, 0x378f, 0x782b, 0x3008, 0x781b, 0x008f, 0x0078, 0x24fa,
- 0xa584, 0x000f, 0x00c0, 0x2a85, 0x7000, 0x0079, 0x2a6f, 0x2523,
- 0x2a79, 0x2a77, 0x3467, 0x3467, 0x3467, 0x3467, 0x2a77, 0x1078,
- 0x248c, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
- 0x345a, 0x0040, 0x3467, 0x0078, 0x2635, 0x78e4, 0xa005, 0x00d0,
- 0x2a06, 0x0018, 0x2a06, 0x2008, 0xa084, 0x0030, 0x00c0, 0x2a94,
- 0x781b, 0x004f, 0x0078, 0x24fa, 0x78ec, 0xa084, 0x0003, 0x0040,
- 0x2a90, 0x2100, 0xa184, 0x0007, 0x0079, 0x2a9e, 0x2ab0, 0x2ab4,
- 0x2aa8, 0x2aa6, 0x39bb, 0x39bb, 0x2aa6, 0x39b1, 0x1078, 0x248c,
- 0x1078, 0x3797, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa,
- 0x1078, 0x3797, 0x0078, 0x3986, 0x1078, 0x3797, 0x782b, 0x3008,
- 0x781b, 0x00ca, 0x0078, 0x24fa, 0x1078, 0x3797, 0x782b, 0x3008,
- 0x781b, 0x008f, 0x0078, 0x24fa, 0x2300, 0x0079, 0x2ac7, 0x2acc,
- 0x2aca, 0x2ace, 0x1078, 0x248c, 0x0078, 0x3180, 0x681b, 0x0008,
- 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x3180, 0x78ec,
- 0xa084, 0x0003, 0x0040, 0x3180, 0xa184, 0x0007, 0x0079, 0x2ae0,
- 0x2ae8, 0x2ab4, 0x2a30, 0x3956, 0x39bb, 0x39bb, 0x2ae8, 0x39b1,
- 0x1078, 0x396a, 0x0078, 0x24fa, 0xa282, 0x0005, 0x0050, 0x2af2,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x2af5, 0x2af8, 0x2d4d, 0x2d5b,
- 0x2200, 0x0079, 0x2afb, 0x2b15, 0x2b02, 0x2b15, 0x2b00, 0x2d32,
- 0x1078, 0x248c, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082,
- 0x0020, 0x0048, 0x376b, 0xa08a, 0x0004, 0x00c8, 0x376b, 0x0079,
- 0x2b11, 0x376b, 0x376b, 0x376b, 0x3719, 0x789b, 0x0018, 0x79a8,
- 0xa184, 0x0080, 0x0040, 0x2b26, 0x0078, 0x376b, 0x7000, 0xa005,
- 0x00c0, 0x2b1c, 0x2011, 0x0004, 0x0078, 0x32e9, 0xa184, 0x00ff,
- 0xa08a, 0x0010, 0x00c8, 0x376b, 0x0079, 0x2b2e, 0x2b40, 0x2b3e,
- 0x2b58, 0x2b5c, 0x2c17, 0x376b, 0x376b, 0x2c19, 0x376b, 0x376b,
- 0x2d2e, 0x2d2e, 0x376b, 0x376b, 0x376b, 0x2d30, 0x1078, 0x248c,
- 0xa684, 0x1000, 0x0040, 0x2b4d, 0x2001, 0x0500, 0x8000, 0x8000,
- 0x783a, 0x781b, 0x008d, 0x0078, 0x24fa, 0x6818, 0xa084, 0x8000,
- 0x0040, 0x2b56, 0x681b, 0x001d, 0x0078, 0x2b44, 0x0078, 0x3956,
- 0x681b, 0x001d, 0x0078, 0x377b, 0x6920, 0x6922, 0xa684, 0x1800,
- 0x00c0, 0x2b9d, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2ba5, 0x6818,
- 0xa086, 0x0008, 0x00c0, 0x2b6e, 0x681b, 0x0000, 0xa684, 0x0400,
- 0x0040, 0x2c13, 0xa684, 0x0080, 0x0040, 0x2b99, 0x7097, 0x0000,
- 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050, 0x2b99, 0xa08a,
- 0x000c, 0x7196, 0x2001, 0x000c, 0x800c, 0x719a, 0x789b, 0x0061,
- 0x78aa, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000,
- 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
- 0x157f, 0x781b, 0x0058, 0x0078, 0x24fa, 0xa684, 0x1000, 0x0040,
- 0x2ba5, 0x781b, 0x0065, 0x0078, 0x24fa, 0xa684, 0x0060, 0x0040,
- 0x2c0f, 0xa684, 0x0800, 0x0040, 0x2c0f, 0xa684, 0x8000, 0x00c0,
- 0x2bb3, 0x0078, 0x2bcb, 0xa6b4, 0x7fff, 0x7e5a, 0x6eb6, 0x7adc,
- 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x2bbe, 0x8000, 0xa084, 0x003f,
- 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
- 0x2200, 0xa303, 0x68ae, 0xa684, 0x4000, 0x0040, 0x2bd3, 0xa6b4,
- 0xbfff, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x00c0, 0x2be0,
- 0x1078, 0x493d, 0x1078, 0x4b3a, 0x781b, 0x0064, 0x0078, 0x24fa,
- 0xa006, 0x1078, 0x4c41, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200,
- 0xa105, 0x0040, 0x2bef, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa,
- 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0,
- 0x2c01, 0xa6b5, 0x4000, 0x7e5a, 0x6eb6, 0x781b, 0x0064, 0x0078,
- 0x24fa, 0x781b, 0x0064, 0x2200, 0xa115, 0x00c0, 0x2c0b, 0x1078,
- 0x4b4b, 0x0078, 0x24fa, 0x1078, 0x4b96, 0x0078, 0x24fa, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x781b, 0x0058, 0x0078, 0x24fa, 0x1078,
- 0x248c, 0x0078, 0x2c7a, 0x6920, 0xa184, 0x0100, 0x0040, 0x2c31,
- 0xa18c, 0xfeff, 0x6922, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084,
- 0xefff, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078,
- 0x2c69, 0xa184, 0x0200, 0x0040, 0x2c69, 0xa18c, 0xfdff, 0x6922,
- 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0xdfff, 0x6002, 0x6004,
- 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0008,
- 0x0040, 0x2c69, 0x1078, 0x38b9, 0x1078, 0x35bb, 0x88ff, 0x0040,
- 0x2c69, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004,
- 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2c63, 0x782b, 0x3008, 0x781b,
- 0x0056, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
- 0x24fa, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2c72, 0x781b, 0x0058,
- 0x0078, 0x24fa, 0x781b, 0x0065, 0x0078, 0x24fa, 0x0078, 0x3773,
- 0x0078, 0x3773, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x00c0,
- 0x2c88, 0x6820, 0xa084, 0x0100, 0x0040, 0x2c78, 0x2009, 0x0008,
- 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
- 0x2cbf, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x2cb7,
- 0x0048, 0x2c9c, 0x0078, 0x2cb9, 0xa380, 0x0002, 0xa102, 0x00c8,
- 0x2cb7, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0c7e, 0x7054, 0x2060,
- 0x6000, 0xa084, 0xefef, 0x6002, 0x6004, 0xa084, 0xffe5, 0x6006,
- 0x0c7f, 0x7e58, 0xa6b4, 0xfffb, 0x7e5a, 0x0078, 0x2c6a, 0x0078,
- 0x2c1b, 0x24a8, 0x7aa8, 0x00f0, 0x2cb9, 0x0078, 0x2c8a, 0xa284,
- 0x00f0, 0xa086, 0x0020, 0x00c0, 0x2d1f, 0x8318, 0x8318, 0x2300,
- 0xa102, 0x0040, 0x2ccf, 0x0048, 0x2ccf, 0x0078, 0x2d1c, 0xa286,
- 0x0023, 0x0040, 0x2c78, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
- 0xa684, 0xfff1, 0xa085, 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085,
- 0x0010, 0x600a, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008, 0x2c48,
- 0x0c7f, 0xa184, 0x0010, 0x0040, 0x2cf3, 0x1078, 0x38b9, 0x1078,
- 0x36d0, 0x0078, 0x2d02, 0x0c7e, 0x7054, 0x2060, 0x6004, 0x2008,
- 0x2c48, 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2c69, 0x1078, 0x38b9,
- 0x1078, 0x35bb, 0x88ff, 0x0040, 0x2c69, 0x789b, 0x0060, 0x2800,
- 0x78aa, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2d16,
- 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa, 0x782b, 0x3008,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x7aa8, 0x0078, 0x2c8a, 0x8318,
- 0x2300, 0xa102, 0x0040, 0x2d28, 0x0048, 0x2d28, 0x0078, 0x2c8a,
- 0xa284, 0x0080, 0x00c0, 0x377b, 0x0078, 0x3773, 0x0078, 0x377b,
- 0x0078, 0x376b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e,
- 0x0001, 0x0040, 0x2d3d, 0x1078, 0x248c, 0x7aa8, 0xa294, 0x00ff,
- 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x376b, 0x0079,
- 0x2d49, 0x376b, 0x3508, 0x376b, 0x3665, 0xa282, 0x0000, 0x00c0,
- 0x2d53, 0x1078, 0x248c, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0xa282, 0x0003, 0x00c0, 0x2d61, 0x1078,
- 0x248c, 0xa484, 0x8000, 0x00c0, 0x2d84, 0x706c, 0xa005, 0x0040,
- 0x2d6b, 0x1078, 0x248c, 0x6f14, 0x7782, 0xa7bc, 0x0f00, 0x1078,
- 0x38bd, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f,
- 0x00c0, 0x2d6f, 0x1078, 0x3793, 0x706f, 0x0002, 0x2009, 0x5238,
- 0x200b, 0x0009, 0x0078, 0x2d86, 0x1078, 0x379f, 0x782b, 0x3008,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0xa282, 0x0004, 0x0050, 0x2d92,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x2d95, 0x2d98, 0x2e81, 0x2eb4,
- 0xa286, 0x0003, 0x0040, 0x2d9e, 0x1078, 0x248c, 0x2001, 0x0000,
- 0x007e, 0x68c0, 0xa005, 0x0040, 0x2da7, 0x7003, 0x0003, 0x68a0,
- 0xa084, 0x2000, 0x0040, 0x2db0, 0x6008, 0xa085, 0x0002, 0x600a,
- 0x007f, 0x703e, 0x7000, 0xa084, 0x0007, 0x0079, 0x2db7, 0x2523,
- 0x2dc1, 0x2dc1, 0x2fb6, 0x2ff2, 0x2523, 0x2ff2, 0x2dbf, 0x1078,
- 0x248c, 0xa684, 0x1000, 0x00c0, 0x2dc9, 0x1078, 0x4887, 0x0040,
- 0x2e5b, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x2e11, 0xa186, 0x0008,
- 0x00c0, 0x2de0, 0x1078, 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x1078, 0x345a, 0x0040, 0x2e11, 0x1078, 0x4887, 0x0078, 0x2df8,
- 0xa186, 0x0028, 0x00c0, 0x2e11, 0x1078, 0x4887, 0x6008, 0xa084,
- 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2df8, 0x8001, 0x601a,
- 0xa005, 0x0040, 0x2df8, 0x8001, 0xa005, 0x0040, 0x2df8, 0x601e,
- 0x6820, 0xa084, 0x0001, 0x0040, 0x2523, 0x6820, 0xa084, 0xfffe,
- 0x6822, 0x7060, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004,
- 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2e0e, 0x6002, 0x6006, 0x0078,
- 0x2523, 0x017e, 0x1078, 0x2ee5, 0x017f, 0xa684, 0xdf00, 0x681e,
- 0x682b, 0x0000, 0x6f14, 0x81ff, 0x0040, 0x2e5b, 0xa186, 0x0002,
- 0x00c0, 0x2e5b, 0xa684, 0x0800, 0x00c0, 0x2e2e, 0xa684, 0x0060,
- 0x0040, 0x2e2e, 0x78d8, 0x7adc, 0x682e, 0x6a32, 0x6820, 0xa084,
- 0x0800, 0x00c0, 0x2e5b, 0x8717, 0xa294, 0x000f, 0x8213, 0x8213,
- 0x8213, 0xa290, 0x5480, 0xa290, 0x0000, 0x221c, 0xa384, 0x0100,
- 0x00c0, 0x2e44, 0x0078, 0x2e4a, 0x8210, 0x2204, 0xa085, 0x0018,
- 0x2012, 0x8211, 0xa384, 0x0400, 0x0040, 0x2e57, 0x68a0, 0xa084,
- 0x0100, 0x00c0, 0x2e57, 0x1078, 0x2f69, 0x0078, 0x2523, 0x6008,
- 0xa085, 0x0002, 0x600a, 0x6916, 0x6818, 0xa084, 0x8000, 0x0040,
- 0x2e63, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x1078, 0x34a9,
- 0x1078, 0x34b8, 0x00c0, 0x2e70, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x6820, 0xa084, 0x0001, 0x00c0, 0x2e79, 0x1078, 0x34a2, 0x0078,
- 0x2e7d, 0x7060, 0x2060, 0x6800, 0x6002, 0x1078, 0x1cdc, 0x0078,
- 0x2523, 0xa282, 0x0004, 0x0048, 0x2e87, 0x1078, 0x248c, 0x2200,
- 0x0079, 0x2e8a, 0x2e85, 0x2e8e, 0x2e9b, 0x2e8e, 0x7000, 0xa086,
- 0x0005, 0x0040, 0x2e97, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007,
- 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003,
- 0x0040, 0x2eb0, 0xa186, 0x0000, 0x0040, 0x2eb0, 0x0078, 0x376b,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x6820, 0xa085, 0x0004, 0x6822,
- 0x82ff, 0x00c0, 0x2ebf, 0x1078, 0x378f, 0x0078, 0x2ec6, 0x8211,
- 0x0040, 0x2ec4, 0x1078, 0x248c, 0x1078, 0x379f, 0x782b, 0x3008,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x702c, 0x8003, 0x0048, 0x2ed6,
- 0x2019, 0x4eaf, 0x1078, 0x2313, 0x702f, 0x8000, 0x1078, 0x39e0,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2ee2, 0x0018, 0x2ee2, 0x791a,
- 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684, 0x0060, 0x00c0,
- 0x2eef, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2f68, 0xa684,
- 0x0800, 0x00c0, 0x2f11, 0x68b4, 0xa084, 0x4800, 0xa635, 0xa684,
- 0x0800, 0x00c0, 0x2f11, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x703c,
- 0xa005, 0x00c0, 0x2f09, 0x2200, 0xa105, 0x0040, 0x2f10, 0x703f,
- 0x0015, 0x7000, 0xa086, 0x0006, 0x0040, 0x2f10, 0x1078, 0x4887,
- 0x007c, 0xa684, 0x0020, 0x0040, 0x2f33, 0xa684, 0x4000, 0x0040,
- 0x2f1f, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x2f09, 0x68b4,
- 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x2f19, 0x703c,
- 0xa005, 0x00c0, 0x2f2d, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x692e,
- 0x6a32, 0x0078, 0x2f09, 0xa684, 0x4000, 0x0040, 0x2f3d, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x0078, 0x2f09, 0x68b4, 0xa084, 0x4800,
- 0xa635, 0xa684, 0x4000, 0x00c0, 0x2f37, 0x703c, 0xa005, 0x00c0,
- 0x2f4b, 0x703f, 0x0015, 0x79d8, 0x7adc, 0x78d0, 0x80fb, 0x00c8,
- 0x2f52, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e,
- 0x6a32, 0x2100, 0xa205, 0x00c0, 0x2f5f, 0x0078, 0x2f09, 0x7000,
- 0xa086, 0x0006, 0x0040, 0x2f68, 0x1078, 0x4c41, 0x0078, 0x2f09,
- 0x007c, 0x6008, 0xa085, 0x0200, 0x600a, 0xa384, 0x0200, 0x0040,
- 0x2f75, 0x6008, 0xa085, 0x0002, 0x600a, 0x681b, 0x0006, 0x688f,
- 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f,
- 0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b,
- 0x0020, 0x68b3, 0x0000, 0x68af, 0x0000, 0x7000, 0x0079, 0x2f90,
- 0x2523, 0x2f9a, 0x2fa3, 0x2f98, 0x2f98, 0x2f98, 0x2f98, 0x2f98,
- 0x1078, 0x248c, 0x6820, 0xa084, 0x0001, 0x00c0, 0x2fa3, 0x1078,
- 0x34a2, 0x0078, 0x2fa9, 0x7060, 0x2c50, 0x2060, 0x6800, 0x6002,
- 0x2a60, 0x2021, 0x525a, 0x2404, 0xa005, 0x0040, 0x2fb2, 0x2020,
- 0x0078, 0x2fab, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x34a9,
- 0x1078, 0x34b8, 0x6008, 0xa084, 0xfdff, 0x600a, 0x682b, 0x0000,
- 0x789b, 0x000e, 0x6f14, 0x6817, 0x0002, 0x1078, 0x4c89, 0xa684,
- 0x0800, 0x0040, 0x2fcf, 0x691c, 0xa18d, 0x2000, 0x691e, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x2fdf, 0x7868, 0xa08c, 0x00ff, 0x0040,
- 0x2fdd, 0x681b, 0x001e, 0x0078, 0x2fdf, 0x681b, 0x0000, 0x2021,
- 0x525a, 0x2404, 0xad06, 0x0040, 0x2fe6, 0x7460, 0x6800, 0x2022,
- 0x68c3, 0x0000, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x1cdc,
- 0x0078, 0x2523, 0x1078, 0x2ee5, 0x682b, 0x0000, 0x2001, 0x000e,
- 0x6f14, 0x1078, 0x39e6, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xa084,
- 0x8000, 0x0040, 0x3005, 0x703c, 0x681a, 0xa68c, 0xdf00, 0x691e,
- 0x706f, 0x0000, 0x0078, 0x2523, 0x7000, 0xa005, 0x00c0, 0x3012,
- 0x0078, 0x2523, 0xa006, 0x1078, 0x4887, 0x6817, 0x0000, 0x681b,
- 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa085,
- 0x00ff, 0x6822, 0x7000, 0x0079, 0x3025, 0x2523, 0x302f, 0x302f,
- 0x3031, 0x3031, 0x3031, 0x3031, 0x302d, 0x1078, 0x248c, 0x1078,
- 0x34b8, 0x6008, 0xa084, 0xffef, 0x600a, 0x0078, 0x3472, 0x2300,
- 0x0079, 0x303a, 0x303d, 0x303f, 0x3098, 0x1078, 0x248c, 0xa684,
- 0x8000, 0x00c0, 0x307d, 0x7000, 0x0079, 0x3046, 0x2523, 0x3050,
- 0x3050, 0x306c, 0x3050, 0x3079, 0x306c, 0x304e, 0x1078, 0x248c,
- 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0, 0x3068, 0xa6b4, 0xffdf,
- 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a, 0x6eb6, 0x681c, 0xa084,
- 0xffdf, 0x681e, 0x1078, 0x4887, 0x1078, 0x4b4b, 0x0078, 0x3956,
- 0xa684, 0x2000, 0x0040, 0x305a, 0x6818, 0xa084, 0x8000, 0x0040,
- 0x3079, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x3079, 0x681b,
- 0x0007, 0x1078, 0x396a, 0x0078, 0x24fa, 0xa6b4, 0x7fff, 0x7e5a,
- 0x7adc, 0x79d8, 0x78d0, 0x79d2, 0x801b, 0x00c8, 0x3088, 0x8000,
- 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
- 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0065, 0x007c,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x309d, 0x30a0, 0x30a2, 0x30eb,
- 0x1078, 0x248c, 0xa684, 0x8000, 0x00c0, 0x30da, 0x7000, 0x0079,
- 0x30a9, 0x2523, 0x30b3, 0x30b3, 0x30cf, 0x30b3, 0x30d6, 0x30cf,
- 0x30b1, 0x1078, 0x248c, 0xa684, 0x0060, 0xa086, 0x0060, 0x00c0,
- 0x30cb, 0xa6b4, 0xffbf, 0xa6b4, 0xbfff, 0xa6b5, 0x2000, 0x7e5a,
- 0x6eb6, 0x681c, 0xa084, 0xffbf, 0x681e, 0x1078, 0x4887, 0x1078,
- 0x4b4b, 0x0078, 0x3956, 0xa684, 0x2000, 0x0040, 0x30bd, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x30d6, 0x681b, 0x0007, 0x781b, 0x00ca,
- 0x0078, 0x24fa, 0xa6b4, 0x7fff, 0x7e5a, 0x7adc, 0x79d8, 0x6b98,
- 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2,
- 0x781b, 0x0065, 0x007c, 0x6820, 0xa085, 0x0004, 0x6822, 0x1078,
- 0x3921, 0xa6b5, 0x0800, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x2300, 0x0079, 0x30fe, 0x3101, 0x3103,
- 0x3105, 0x1078, 0x248c, 0x0078, 0x377b, 0xa684, 0x0400, 0x00c0,
- 0x312e, 0x79e4, 0xa184, 0x0020, 0x0040, 0x3115, 0x78ec, 0xa084,
- 0x0003, 0x0040, 0x3115, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab,
- 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xa184, 0x0020, 0x0040,
- 0x3126, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x312a, 0x2001, 0x0014,
- 0x0078, 0x2da0, 0xa184, 0x0007, 0x0079, 0x3166, 0x7a90, 0xa294,
- 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3164, 0x789b,
- 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0, 0x3155, 0x7ba8, 0x7ba8,
- 0xa386, 0x0001, 0x00c0, 0x3148, 0x2009, 0xfff7, 0x0078, 0x314e,
- 0xa386, 0x0003, 0x00c0, 0x3155, 0x2009, 0xffef, 0x0c7e, 0x7054,
- 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab,
- 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c,
- 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3956, 0x2a3f, 0x2a4a,
- 0x3170, 0x3178, 0x316e, 0x316e, 0x3956, 0x3956, 0x1078, 0x248c,
- 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3960,
- 0x6920, 0xa18c, 0xfdff, 0xa18c, 0xfeff, 0x6922, 0x0078, 0x3956,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x318a, 0x78ec, 0xa084, 0x0003,
- 0x00c0, 0x31b1, 0x7000, 0xa086, 0x0004, 0x00c0, 0x31a4, 0x706c,
- 0xa086, 0x0002, 0x00c0, 0x319a, 0x2011, 0x0002, 0x2019, 0x0000,
- 0x0078, 0x28e9, 0x706c, 0xa086, 0x0006, 0x0040, 0x3194, 0x706c,
- 0xa086, 0x0004, 0x0040, 0x3194, 0x7000, 0xa086, 0x0000, 0x0040,
- 0x24fa, 0x6818, 0xa085, 0x8000, 0x681a, 0x2001, 0x0014, 0x0078,
- 0x2da0, 0xa184, 0x0007, 0x0079, 0x31b5, 0x3956, 0x3956, 0x31bd,
- 0x3956, 0x39bb, 0x39bb, 0x3956, 0x3956, 0xa684, 0x0080, 0x0040,
- 0x31ec, 0x7194, 0x81ff, 0x0040, 0x31ec, 0xa182, 0x000d, 0x00d0,
- 0x31cd, 0x7097, 0x0000, 0x0078, 0x31d2, 0xa182, 0x000c, 0x7096,
- 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e,
- 0x7098, 0x8114, 0xa210, 0x729a, 0xa080, 0x000b, 0xad00, 0x2098,
- 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f,
- 0x137f, 0x157f, 0x0078, 0x3960, 0xa684, 0x0400, 0x00c0, 0x322d,
- 0x6820, 0xa084, 0x0001, 0x0040, 0x3960, 0xa68c, 0x0060, 0xa684,
- 0x0060, 0x0040, 0x3201, 0xa086, 0x0060, 0x00c0, 0x3201, 0xa18d,
- 0x4000, 0xa18c, 0xfffb, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab,
- 0x0000, 0x789b, 0x0061, 0x6818, 0xa085, 0x8000, 0x681a, 0x78aa,
- 0x8008, 0x810c, 0x0040, 0x34d1, 0xa18c, 0x00f8, 0x00c0, 0x34d1,
- 0x157e, 0x137e, 0x147e, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8000,
- 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f,
- 0x6814, 0x8007, 0x7882, 0x0078, 0x3960, 0x6818, 0xa084, 0x8000,
- 0x0040, 0x3234, 0x681b, 0x0008, 0x781b, 0x00c0, 0x0078, 0x24fa,
- 0x2300, 0x0079, 0x323b, 0x3240, 0x32d4, 0x323e, 0x1078, 0x248c,
- 0x7000, 0xa084, 0x0007, 0x0079, 0x3245, 0x2523, 0x324f, 0x3284,
- 0x325a, 0x324d, 0x2523, 0x324d, 0x324d, 0x1078, 0x248c, 0x681c,
- 0xa084, 0x2000, 0x0040, 0x3268, 0x6008, 0xa085, 0x0002, 0x600a,
- 0x0078, 0x3268, 0x68c0, 0xa005, 0x00c0, 0x3284, 0x6920, 0xa18d,
- 0x0001, 0x6922, 0x68c3, 0x0001, 0x6800, 0x706a, 0x0078, 0x327e,
- 0x6920, 0xa18d, 0x0001, 0x6922, 0x6800, 0x6006, 0xa005, 0x00c0,
- 0x3272, 0x6002, 0x681c, 0xa084, 0x000e, 0x0040, 0x327e, 0x7014,
- 0x68ba, 0x7130, 0xa188, 0x7500, 0x0078, 0x3280, 0x2009, 0x7600,
- 0x2104, 0x6802, 0x2d0a, 0x7162, 0x6eb6, 0xa684, 0x0060, 0x0040,
- 0x32d2, 0xa684, 0x0800, 0x00c0, 0x3298, 0xa684, 0x7fff, 0x68b6,
- 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x4887, 0x0078, 0x32d2,
- 0xa684, 0x0020, 0x0040, 0x32ad, 0x68c0, 0xa005, 0x0040, 0x32a4,
- 0x1078, 0x4c89, 0x0078, 0x32a7, 0xa006, 0x1078, 0x4c41, 0x79d8,
- 0x7adc, 0x69aa, 0x6aa6, 0x0078, 0x32b3, 0x1078, 0x38ca, 0x69aa,
- 0x6aa6, 0x1078, 0x4c41, 0xa684, 0x8000, 0x0040, 0x32d2, 0xa684,
- 0x7fff, 0x68b6, 0x7adc, 0x79d8, 0xa684, 0x0020, 0x00c0, 0x32ca,
- 0x78d0, 0x801b, 0x00c8, 0x32c5, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
- 0xa303, 0x68ae, 0x0078, 0x2523, 0x0078, 0x377b, 0x7037, 0x0000,
- 0xa282, 0x0006, 0x0050, 0x32de, 0x1078, 0x248c, 0x7000, 0xa084,
- 0x0007, 0x10c0, 0x3a8c, 0x2300, 0x0079, 0x32e6, 0x32e9, 0x3312,
- 0x3326, 0x2200, 0x0079, 0x32ec, 0x3310, 0x377b, 0x32f2, 0x3310,
- 0x3342, 0x3384, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068, 0x704a,
- 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070, 0x3302,
- 0x0078, 0x32fb, 0x157f, 0xad80, 0x0009, 0x7036, 0x6817, 0x0000,
- 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x376b,
- 0x1078, 0x248c, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068, 0x704a,
- 0xad80, 0x0009, 0x7036, 0x2200, 0x0079, 0x331e, 0x377b, 0x3324,
- 0x3324, 0x3342, 0x3324, 0x377b, 0x1078, 0x248c, 0x7003, 0x0005,
- 0x2001, 0x7710, 0x2068, 0x704a, 0xad80, 0x0009, 0x7036, 0x2200,
- 0x0079, 0x3332, 0x333a, 0x3338, 0x3338, 0x333a, 0x3338, 0x333a,
- 0x1078, 0x248c, 0x1078, 0x379f, 0x782b, 0x3008, 0x781b, 0x0065,
- 0x0078, 0x24fa, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
- 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x7600, 0x2d04,
- 0x2d08, 0x7162, 0x2068, 0xa005, 0x0040, 0x335d, 0x6814, 0xa206,
- 0x0040, 0x3379, 0x6800, 0x0078, 0x3350, 0x7003, 0x0005, 0x2001,
- 0x7710, 0x2068, 0x704a, 0x7036, 0x157e, 0x20a9, 0x0031, 0x2003,
- 0x0000, 0x8000, 0x0070, 0x336e, 0x0078, 0x3367, 0x157f, 0xad80,
- 0x0009, 0x7036, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827,
- 0x0003, 0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x33d3,
- 0x1078, 0x3797, 0x0078, 0x33d3, 0x7003, 0x0002, 0x7a80, 0xa294,
- 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x79a8,
- 0x79a8, 0xa18c, 0x00ff, 0xa1e8, 0x7500, 0x2d04, 0x2d08, 0x7162,
- 0x2068, 0xa005, 0x0040, 0x33a3, 0x6814, 0xa206, 0x0040, 0x33be,
- 0x6800, 0x0078, 0x3396, 0x7003, 0x0005, 0x2001, 0x7710, 0x2068,
- 0x704a, 0x157e, 0x20a9, 0x0031, 0x2003, 0x0000, 0x8000, 0x0070,
- 0x33b3, 0x0078, 0x33ac, 0x157f, 0xad80, 0x0009, 0x7036, 0x6a16,
- 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a,
- 0x6820, 0xa084, 0x0c00, 0x0040, 0x33d3, 0xa084, 0x0800, 0x0040,
- 0x33cd, 0x1078, 0x379b, 0x0078, 0x33d3, 0x1078, 0x3797, 0x708b,
- 0x0000, 0x0078, 0x33d3, 0x027e, 0x8207, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa080, 0x5480, 0x2060, 0x7056, 0x6000, 0x705a,
- 0x6004, 0x705e, 0xa684, 0x0060, 0x0040, 0x342b, 0x6b98, 0x6c94,
- 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x340d, 0x7bd2, 0x7bda, 0x7cd6,
- 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a, 0xa684, 0x0060, 0xa086, 0x0060,
- 0x0040, 0x342b, 0x68c0, 0xa005, 0x0040, 0x3406, 0x7003, 0x0003,
- 0x682b, 0x0000, 0x1078, 0x4b3a, 0x0078, 0x3408, 0x1078, 0x4b4b,
- 0xa6b5, 0x2000, 0x7e5a, 0x0078, 0x342b, 0x68b0, 0xa31a, 0x2100,
- 0xa423, 0x2400, 0xa305, 0x0040, 0x342b, 0x7bd2, 0x7bda, 0x7cd6,
- 0x7cde, 0x68b0, 0xa6b4, 0xbfff, 0x7e5a, 0x007e, 0x68c0, 0xa005,
- 0x007f, 0x0040, 0x3429, 0x7003, 0x0003, 0x1078, 0x4b3a, 0x0078,
- 0x342b, 0x1078, 0x4b96, 0x077f, 0x1078, 0x38bd, 0x2009, 0x0065,
- 0xa684, 0x0004, 0x0040, 0x344c, 0x78e4, 0xa084, 0x0030, 0x0040,
- 0x3444, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3444, 0x782b, 0x3008,
- 0x2009, 0x0065, 0x0078, 0x344c, 0x0f7e, 0x2079, 0x5200, 0x1078,
- 0x4887, 0x0f7f, 0x0040, 0x2523, 0x791a, 0x2d00, 0x704a, 0x8207,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x5480, 0x2048,
- 0x0078, 0x24fa, 0x6020, 0xa005, 0x0040, 0x3466, 0x8001, 0x6022,
- 0x6008, 0xa085, 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006,
- 0x1078, 0x4887, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040,
- 0x681f, 0x0100, 0x7000, 0xa084, 0x0007, 0x0079, 0x3477, 0x2523,
- 0x3481, 0x3481, 0x349e, 0x3489, 0x3487, 0x3489, 0x347f, 0x1078,
- 0x248c, 0x1078, 0x34a9, 0x1078, 0x34a2, 0x1078, 0x1cdc, 0x0078,
- 0x2523, 0x706c, 0x706f, 0x0000, 0x7093, 0x0000, 0x0079, 0x3490,
- 0x349a, 0x349a, 0x3498, 0x3498, 0x3498, 0x349a, 0x3498, 0x349a,
- 0x0079, 0x2902, 0x706f, 0x0000, 0x0078, 0x2523, 0x681b, 0x0000,
- 0x0078, 0x2fb6, 0x6800, 0xa005, 0x00c0, 0x34a7, 0x6002, 0x6006,
- 0x007c, 0x6010, 0xa005, 0x0040, 0x34b2, 0x8001, 0x00d0, 0x34b2,
- 0x1078, 0x248c, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c,
- 0x6018, 0xa005, 0x0040, 0x34be, 0x8001, 0x601a, 0x007c, 0x1078,
- 0x39e0, 0x681b, 0x0018, 0x0078, 0x34f5, 0x1078, 0x39e0, 0x681b,
- 0x0019, 0x0078, 0x34f5, 0x1078, 0x39e0, 0x681b, 0x001a, 0x0078,
- 0x34f5, 0x1078, 0x39e0, 0x681b, 0x0003, 0x0078, 0x34f5, 0x7780,
- 0x1078, 0x38bd, 0x7184, 0xa18c, 0x00ff, 0xa1e8, 0x7500, 0x2d04,
- 0x2d08, 0x2068, 0xa005, 0x00c0, 0x34e7, 0x0078, 0x2523, 0x6814,
- 0x7280, 0xa206, 0x0040, 0x34ef, 0x6800, 0x0078, 0x34e0, 0x6800,
- 0x200a, 0x681b, 0x0005, 0x708b, 0x0000, 0x1078, 0x34a9, 0x6820,
- 0xa084, 0x0001, 0x00c0, 0x34fe, 0x1078, 0x34a2, 0x1078, 0x34b8,
- 0x681f, 0x0000, 0x6823, 0x0020, 0x1078, 0x1cdc, 0x0078, 0x2523,
- 0xa282, 0x0003, 0x00c0, 0x376b, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8,
- 0xa4a4, 0x00ff, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0100,
- 0x0040, 0x356c, 0xa18c, 0xfeff, 0x6922, 0xa4a4, 0x00ff, 0x0040,
- 0x3556, 0xa482, 0x000c, 0x0048, 0x3529, 0x0040, 0x3529, 0x2021,
- 0x000c, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x3533, 0x1078,
- 0x3627, 0x0078, 0x355f, 0x1078, 0x37e9, 0x0c7e, 0x2960, 0x6004,
- 0xa084, 0xfff5, 0x6006, 0x1078, 0x3652, 0x0c7f, 0x6920, 0xa18d,
- 0x0100, 0x6922, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400,
- 0x00c0, 0x3550, 0x782b, 0x3008, 0x781b, 0x0056, 0x0078, 0x24fa,
- 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x2960,
- 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3652, 0x0c7f, 0x7e58,
- 0xa684, 0x0400, 0x00c0, 0x3568, 0x781b, 0x0058, 0x0078, 0x24fa,
- 0x781b, 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x7054, 0x2060, 0x6100,
- 0xa18c, 0x1000, 0x0040, 0x35ac, 0x6208, 0x8217, 0xa294, 0x00ff,
- 0xa282, 0x000c, 0x0048, 0x3580, 0x0040, 0x3580, 0x2011, 0x000c,
- 0x2400, 0xa202, 0x00c8, 0x3585, 0x2220, 0x6208, 0xa294, 0x00ff,
- 0x7018, 0xa086, 0x0028, 0x00c0, 0x3595, 0xa282, 0x0019, 0x00c8,
- 0x359b, 0x2011, 0x0019, 0x0078, 0x359b, 0xa282, 0x000c, 0x00c8,
- 0x359b, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x35a0, 0x2228,
- 0x1078, 0x37ed, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x35ac,
- 0x1078, 0x3627, 0x0078, 0x35b0, 0x1078, 0x37e9, 0x1078, 0x3652,
- 0x7858, 0xa085, 0x0004, 0x785a, 0x0c7f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x0c7e, 0x2960, 0x6000, 0xd0e4, 0x00c0,
- 0x35d5, 0xd0b4, 0x00c0, 0x35cf, 0x6010, 0xa084, 0x000f, 0x00c0,
- 0x35cf, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011,
- 0x0032, 0x2019, 0x0000, 0x0078, 0x35fc, 0x68a0, 0xa084, 0x0200,
- 0x00c0, 0x35cf, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028,
- 0x00c0, 0x35ea, 0xa282, 0x0019, 0x00c8, 0x35f0, 0x2011, 0x0019,
- 0x0078, 0x35f0, 0xa282, 0x000c, 0x00c8, 0x35f0, 0x2011, 0x000c,
- 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x35fc,
- 0x0040, 0x35fc, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003,
- 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xa085,
- 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0xa18c, 0xfff5,
- 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3617, 0x78ab,
- 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0,
- 0x0005, 0x6820, 0xa085, 0x0100, 0x6822, 0x0c7f, 0x007c, 0x0c7e,
- 0x7154, 0x2160, 0x1078, 0x362e, 0x0c7f, 0x007c, 0x2008, 0xa084,
- 0xfff0, 0xa425, 0x7c86, 0x6018, 0x789a, 0x7cae, 0x6412, 0x78a4,
- 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016, 0x788a,
- 0xa4a4, 0x000f, 0x8427, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa405,
- 0x600e, 0x78ec, 0xd08c, 0x00c0, 0x3651, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3659, 0x0c7f,
- 0x007c, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012,
- 0x7884, 0xa084, 0xfff0, 0x7886, 0x007c, 0xa282, 0x0002, 0x00c0,
- 0x376b, 0x7aa8, 0x6920, 0xa18d, 0x0080, 0x6922, 0xa184, 0x0200,
- 0x0040, 0x36ae, 0xa18c, 0xfdff, 0x6922, 0xa294, 0x00ff, 0xa282,
- 0x0002, 0x00c8, 0x376b, 0x1078, 0x36f9, 0x1078, 0x3652, 0xa980,
- 0x0001, 0x200c, 0x1078, 0x38b9, 0x1078, 0x35bb, 0x88ff, 0x0040,
- 0x36a1, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xa6b5, 0x0004,
- 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x369b, 0x782b, 0x3008, 0x781b,
- 0x0056, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078,
- 0x24fa, 0x7e58, 0xa684, 0x0400, 0x00c0, 0x36aa, 0x781b, 0x0058,
- 0x0078, 0x24fa, 0x781b, 0x0065, 0x0078, 0x24fa, 0xa282, 0x0002,
- 0x00c8, 0x36b6, 0xa284, 0x0001, 0x0040, 0x36c0, 0x7154, 0xa188,
- 0x0000, 0x210c, 0xa18c, 0x2000, 0x00c0, 0x36c0, 0x2011, 0x0000,
- 0x1078, 0x37db, 0x1078, 0x36f9, 0x1078, 0x3652, 0x7858, 0xa085,
- 0x0004, 0x785a, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa,
- 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0,
- 0x36e9, 0xd0bc, 0x00c0, 0x36e7, 0x6014, 0xa084, 0x0040, 0x00c0,
- 0x36e7, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078, 0x36f6, 0x2011,
- 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa,
- 0xa8c0, 0x0004, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f, 0x0c7f,
- 0x007c, 0x0c7e, 0x7054, 0x2060, 0x1078, 0x3700, 0x0c7f, 0x007c,
- 0x82ff, 0x0040, 0x3705, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002,
- 0x789a, 0x78a4, 0xa084, 0xffbf, 0xa205, 0x78a6, 0x788a, 0x6016,
- 0x78ec, 0xd08c, 0x00c0, 0x3718, 0x6004, 0xa084, 0xffef, 0x6006,
- 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x3722, 0x007f,
- 0x0078, 0x3725, 0x007f, 0x0078, 0x3767, 0xa684, 0x0020, 0x0040,
- 0x3767, 0x7888, 0xa084, 0x0040, 0x0040, 0x3767, 0x7bb8, 0xa384,
- 0x003f, 0x831b, 0x00c8, 0x3735, 0x8000, 0xa005, 0x0040, 0x374b,
- 0x831b, 0x00c8, 0x373e, 0x8001, 0x0040, 0x3763, 0xa684, 0x4000,
- 0x0040, 0x374b, 0x78b8, 0x801b, 0x00c8, 0x3747, 0x8000, 0xa084,
- 0x003f, 0x00c0, 0x3763, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc,
- 0x2001, 0x0001, 0xa108, 0x00c8, 0x3757, 0xa291, 0x0000, 0x79d2,
- 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x4c41, 0x781b, 0x0064, 0x1078,
- 0x4ac6, 0x0078, 0x24fa, 0x781b, 0x0064, 0x0078, 0x24fa, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x1078, 0x37a3, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x1078, 0x378f, 0x782b, 0x3008, 0x781b,
- 0x0065, 0x0078, 0x24fa, 0x6827, 0x0002, 0x1078, 0x3797, 0x78e4,
- 0xa084, 0x0030, 0x0040, 0x2523, 0x78ec, 0xa084, 0x0003, 0x0040,
- 0x2523, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa, 0x2001,
- 0x0005, 0x0078, 0x37a5, 0x2001, 0x000c, 0x0078, 0x37a5, 0x2001,
- 0x0006, 0x0078, 0x37a5, 0x2001, 0x000d, 0x0078, 0x37a5, 0x2001,
- 0x0009, 0x0078, 0x37a5, 0x2001, 0x0007, 0x789b, 0x0010, 0x78aa,
- 0x789b, 0x0060, 0x78ab, 0x0001, 0xa6b5, 0x0004, 0x7e5a, 0x007c,
- 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0,
- 0x5480, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040,
- 0x37c9, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008,
- 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040,
- 0x37d9, 0xa184, 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010,
- 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004,
- 0x007c, 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab,
- 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b,
- 0x0060, 0x78ab, 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff,
- 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0,
- 0x2001, 0x5246, 0x2004, 0xa082, 0x0028, 0x0040, 0x3817, 0x2021,
- 0x38a0, 0x2019, 0x0014, 0x20a9, 0x000c, 0x0078, 0x381d, 0x2021,
- 0x38ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404,
- 0xa084, 0xfff0, 0xa106, 0x0040, 0x382c, 0x8420, 0x2300, 0xa210,
- 0x0070, 0x382c, 0x0078, 0x381f, 0x157f, 0x007c, 0x157e, 0x2009,
- 0x5246, 0x210c, 0xa182, 0x0032, 0x0048, 0x3842, 0x0040, 0x3846,
- 0x2009, 0x3892, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032,
- 0x0078, 0x3858, 0xa182, 0x0028, 0x0040, 0x3850, 0x2009, 0x38a0,
- 0x2019, 0x0014, 0x20a9, 0x000c, 0x2011, 0x0064, 0x0078, 0x3858,
- 0x2009, 0x38ac, 0x2019, 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064,
- 0x2200, 0xa502, 0x0040, 0x3868, 0x0048, 0x3868, 0x8108, 0x2300,
- 0xa210, 0x0070, 0x3865, 0x0078, 0x3858, 0x157f, 0xa006, 0x007c,
- 0x157f, 0xa582, 0x0064, 0x00c8, 0x3877, 0x7808, 0xa085, 0x0070,
- 0x780a, 0x7044, 0xa085, 0x0070, 0x7046, 0x0078, 0x3877, 0x78ec,
- 0xa084, 0x0300, 0x0040, 0x387f, 0x2104, 0x0078, 0x3890, 0x2104,
- 0xa09e, 0x1102, 0x00c0, 0x3890, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0005, 0x0048, 0x388f, 0x2001, 0x1201, 0x0078, 0x3890, 0x2104,
- 0xa005, 0x007c, 0x1102, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
- 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
- 0x3202, 0x4202, 0x5202, 0x6202, 0x7202, 0x6605, 0x7605, 0x7805,
- 0x7a05, 0x7c05, 0x7e05, 0x7f05, 0x2202, 0x3202, 0x4202, 0x5202,
- 0x5404, 0x6404, 0x7404, 0x7604, 0x7804, 0x7a04, 0x7c04, 0x7e04,
- 0x7f04, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00, 0x800b,
- 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e0,
- 0x5500, 0x007c, 0x79d8, 0x7adc, 0x78d0, 0x801b, 0x00c8, 0x38d1,
- 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x007c, 0x0f7e,
- 0x2079, 0x0100, 0x2009, 0x5240, 0x2091, 0x8000, 0x2104, 0x0079,
- 0x38e1, 0x3917, 0x38eb, 0x38eb, 0x38eb, 0x38eb, 0x38eb, 0x38eb,
- 0x391b, 0x1078, 0x248c, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
- 0x00c0, 0x38ed, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
- 0x38f4, 0x68b4, 0xa085, 0x4000, 0x68b6, 0x7858, 0xa085, 0x4000,
- 0x785a, 0x7830, 0xa084, 0x0080, 0x00c0, 0x3917, 0x0018, 0x3917,
- 0x681c, 0xa084, 0x0020, 0x00c0, 0x3915, 0x0e7e, 0x2071, 0x5240,
- 0x1078, 0x396a, 0x0e7f, 0x0078, 0x3917, 0x781b, 0x00ca, 0x2091,
- 0x8001, 0x0f7f, 0x007c, 0x70b3, 0x0000, 0x1078, 0x3b44, 0x0078,
- 0x3917, 0x0c7e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xa0e0, 0x5480, 0x6004, 0xa084, 0x000a, 0x00c0, 0x3954,
- 0x6108, 0xa194, 0xff00, 0x0040, 0x3954, 0xa18c, 0x00ff, 0x2001,
- 0x0019, 0xa106, 0x0040, 0x3943, 0x2001, 0x0032, 0xa106, 0x0040,
- 0x3947, 0x0078, 0x394b, 0x2009, 0x0020, 0x0078, 0x394d, 0x2009,
- 0x003f, 0x0078, 0x394d, 0x2011, 0x0000, 0x2100, 0xa205, 0x600a,
- 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c, 0x781b, 0x0065,
- 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0065, 0x0078, 0x24fa,
- 0x781b, 0x0058, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x0056,
- 0x0078, 0x24fa, 0x2009, 0x5220, 0x210c, 0xa186, 0x0000, 0x0040,
- 0x397e, 0xa186, 0x0001, 0x0040, 0x3981, 0x2009, 0x5238, 0x200b,
- 0x000b, 0x706f, 0x0001, 0x781b, 0x0048, 0x007c, 0x781b, 0x00c4,
- 0x007c, 0x2009, 0x5238, 0x200b, 0x000a, 0x007c, 0x2009, 0x5220,
- 0x210c, 0xa186, 0x0000, 0x0040, 0x39a1, 0xa186, 0x0001, 0x0040,
- 0x399b, 0x2009, 0x5238, 0x200b, 0x000b, 0x706f, 0x0001, 0x781b,
- 0x0048, 0x0078, 0x24fa, 0x2009, 0x5238, 0x200b, 0x000a, 0x0078,
- 0x24fa, 0x782b, 0x3008, 0x781b, 0x00c4, 0x0078, 0x24fa, 0x781b,
- 0x00ca, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b, 0x00ca, 0x0078,
- 0x24fa, 0x781b, 0x008f, 0x0078, 0x24fa, 0x782b, 0x3008, 0x781b,
- 0x008f, 0x0078, 0x24fa, 0x6818, 0xa084, 0x8000, 0x0040, 0x39c2,
- 0x681b, 0x001d, 0x706f, 0x0001, 0x781b, 0x0048, 0x0078, 0x24fa,
- 0x007e, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x39de, 0x7808, 0xa084,
- 0xfffc, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084,
- 0x0021, 0x0040, 0x39de, 0x7044, 0x780a, 0xa005, 0x007f, 0x007c,
- 0x7044, 0xa085, 0x0002, 0x7046, 0x780a, 0x007c, 0x007e, 0x7830,
- 0xa084, 0x0040, 0x00c0, 0x39e7, 0x0098, 0x39f2, 0x007f, 0x789a,
- 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
- 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x3a01, 0x0098,
- 0x39ff, 0x007f, 0x789a, 0x78ac, 0x007e, 0x7044, 0x780a, 0x007f,
- 0x007c, 0x78ec, 0xa084, 0x0002, 0x00c0, 0x4871, 0xa784, 0x007d,
- 0x00c0, 0x3a15, 0x2700, 0x1078, 0x248c, 0xa784, 0x0001, 0x00c0,
- 0x300c, 0xa784, 0x0070, 0x0040, 0x3a25, 0x0c7e, 0x2d60, 0x2f68,
- 0x1078, 0x2437, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
- 0x3a32, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2523,
- 0x0078, 0x3956, 0xa784, 0x0004, 0x0040, 0x3a65, 0x78b8, 0xa084,
- 0x4001, 0x0040, 0x3a65, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x2523, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
- 0x3a65, 0x78c0, 0xa085, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00ca,
- 0x0078, 0x24fa, 0x784b, 0x0008, 0x6818, 0xa084, 0x8000, 0x0040,
- 0x3a61, 0x681b, 0x0015, 0xa684, 0x4000, 0x0040, 0x3a61, 0x681b,
- 0x0007, 0x1078, 0x396a, 0x0078, 0x24fa, 0x681b, 0x0003, 0x7858,
- 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000, 0x784b,
- 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2a06, 0x0018, 0x24fa,
- 0x0078, 0x3773, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xa080, 0x5480, 0x2060, 0x2048, 0x7056, 0x6000, 0x705a,
- 0x6004, 0x705e, 0x2a60, 0x007c, 0x0079, 0x3a8e, 0x3a96, 0x3a97,
- 0x3a96, 0x3a99, 0x3a96, 0x3a96, 0x3a96, 0x3a9e, 0x007c, 0x1078,
- 0x34b8, 0x1078, 0x4887, 0x7038, 0x600a, 0x007c, 0x70a0, 0xa005,
- 0x0040, 0x3aab, 0x2068, 0x1078, 0x1bd3, 0x1078, 0x47fe, 0x1078,
- 0x4805, 0x70a3, 0x0000, 0x007c, 0x0e7e, 0x2091, 0x8000, 0x2071,
- 0x5240, 0x7000, 0xa086, 0x0007, 0x00c0, 0x3ac2, 0x6110, 0x70bc,
- 0xa106, 0x00c0, 0x3ac2, 0x0e7f, 0x1078, 0x1be0, 0x1078, 0x3ac8,
- 0xa006, 0x007c, 0x2091, 0x8001, 0x0e7f, 0xa085, 0x0001, 0x007c,
- 0x0f7e, 0x0e7e, 0x2071, 0x5240, 0x0078, 0x2297, 0x785b, 0x0000,
- 0x70af, 0x000e, 0x2009, 0x0100, 0x017e, 0x70a0, 0xa06d, 0x0040,
- 0x3add, 0x70a3, 0x0000, 0x0078, 0x3ae3, 0x70b3, 0x0000, 0x1078,
- 0x1c0c, 0x0040, 0x3ae9, 0x70ac, 0x6826, 0x1078, 0x3bc6, 0x0078,
- 0x3add, 0x017f, 0x157e, 0x0c7e, 0x0d7e, 0x20a9, 0x0008, 0x2061,
- 0x7610, 0x6000, 0xa105, 0x6002, 0x601c, 0xa06d, 0x0040, 0x3b01,
- 0x6800, 0x601e, 0x1078, 0x19ac, 0x6008, 0x8000, 0x600a, 0x0078,
- 0x3af4, 0x6018, 0xa06d, 0x0040, 0x3b0b, 0x6800, 0x601a, 0x1078,
- 0x19ac, 0x0078, 0x3b01, 0xace0, 0x0008, 0x0070, 0x3b11, 0x0078,
- 0x3af1, 0x709c, 0xa084, 0x8000, 0x0040, 0x3b18, 0x1078, 0x3c44,
- 0x0d7f, 0x0c7f, 0x157f, 0x007c, 0x127e, 0x2091, 0x2300, 0x6804,
- 0xa084, 0x000f, 0x0079, 0x3b24, 0x3b34, 0x3b34, 0x3b34, 0x3b34,
- 0x3b34, 0x3b34, 0x3b36, 0x3b3c, 0x3b34, 0x3b34, 0x3b34, 0x3b34,
- 0x3b34, 0x3b3e, 0x3b34, 0x3b36, 0x1078, 0x248c, 0x1078, 0x45d3,
- 0x1078, 0x19ac, 0x0078, 0x3b42, 0x6827, 0x000b, 0x1078, 0x45d3,
- 0x1078, 0x3bc6, 0x127f, 0x007c, 0x127e, 0x2091, 0x2300, 0x0098,
- 0x3b60, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x3b60, 0x0d7e, 0x1078,
- 0x4812, 0x2d00, 0x682e, 0x2009, 0x0004, 0x2001, 0x0000, 0x6827,
- 0x0084, 0x1078, 0x47c7, 0x1078, 0x3bc6, 0x0d7f, 0x0078, 0x3b94,
- 0x7948, 0xa185, 0x4000, 0x784a, 0x0098, 0x3b69, 0x794a, 0x0078,
- 0x3b4e, 0x7828, 0xa086, 0x1834, 0x00c0, 0x3b72, 0xa185, 0x0004,
- 0x0078, 0x3b79, 0x7828, 0xa086, 0x1814, 0x00c0, 0x3b66, 0xa185,
- 0x000c, 0x784a, 0x789b, 0x000e, 0x78ab, 0x0002, 0x7858, 0xa084,
- 0x00ff, 0xa085, 0x0400, 0x785a, 0x70b4, 0xa080, 0x0091, 0x781a,
- 0x6827, 0x0284, 0x682c, 0x6836, 0x6830, 0x683a, 0x2009, 0x0004,
- 0x2001, 0x0000, 0x1078, 0x47c7, 0x127f, 0x007c, 0x0d7e, 0x6b14,
- 0x1078, 0x1c70, 0x0040, 0x3ba3, 0x2068, 0x6827, 0x0002, 0x1078,
- 0x3bc6, 0x0078, 0x3b98, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0x6c28,
- 0xa4a4, 0x00ff, 0x1078, 0x1c1c, 0x0040, 0x3bb3, 0x2068, 0x6827,
- 0x0002, 0x1078, 0x3bc6, 0x0d7f, 0x007c, 0x0d7e, 0x6b14, 0xa39c,
- 0x00ff, 0x1078, 0x1c48, 0x0040, 0x3bc4, 0x2068, 0x6827, 0x0002,
- 0x1078, 0x3bc6, 0x0078, 0x3bb9, 0x0d7f, 0x007c, 0x0c7e, 0x6914,
- 0x1078, 0x3c3b, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0006, 0x0040,
- 0x3be1, 0xa186, 0x000d, 0x0040, 0x3c00, 0xa186, 0x0017, 0x00c0,
- 0x3bdd, 0x1078, 0x19ac, 0x0078, 0x3bdf, 0x1078, 0x1cde, 0x0c7f,
- 0x007c, 0x6004, 0x8001, 0x0048, 0x3bfe, 0x6006, 0x2009, 0x0000,
- 0xa684, 0x0001, 0x00c0, 0x3bee, 0xa18d, 0x8000, 0xa684, 0x0004,
- 0x0040, 0x3bf4, 0xa18d, 0x0002, 0x691e, 0x6823, 0x0000, 0x7104,
- 0x810f, 0x6818, 0xa105, 0x681a, 0x0078, 0x3bdd, 0x1078, 0x248c,
- 0x6018, 0xa005, 0x00c0, 0x3c0f, 0x6008, 0x8001, 0x0048, 0x3c0f,
- 0x600a, 0x601c, 0x6802, 0x2d00, 0x601e, 0x0078, 0x3c25, 0xac88,
- 0x0006, 0x2104, 0xa005, 0x0040, 0x3c18, 0x2008, 0x0078, 0x3c11,
- 0x6802, 0x2d0a, 0x6008, 0x8001, 0x0048, 0x3bdf, 0x600a, 0x6018,
- 0x2068, 0x6800, 0x601a, 0x0078, 0x3c09, 0x157e, 0x137e, 0x147e,
- 0x0c7e, 0x0d7e, 0x1078, 0x1989, 0x00c0, 0x3c30, 0x1078, 0x248c,
- 0x2da0, 0x137f, 0x20a9, 0x0031, 0x53a3, 0x0c7f, 0x147f, 0x137f,
- 0x157f, 0x0078, 0x3bdd, 0xa184, 0x001f, 0x8003, 0x8003, 0x8003,
- 0xa080, 0x7610, 0x2060, 0x007c, 0x2019, 0x5251, 0x2304, 0xa085,
- 0x0001, 0x201a, 0x2019, 0x0102, 0x2304, 0xa085, 0x0001, 0x201a,
- 0x007c, 0x2019, 0x5251, 0x2304, 0xa084, 0xfffe, 0x201a, 0x2019,
- 0x0102, 0x2304, 0xa084, 0xfffe, 0x201a, 0x007c, 0x7990, 0xa18c,
- 0xfff8, 0x7992, 0x70b4, 0xa080, 0x00d8, 0x781a, 0x0078, 0x24fa,
- 0x70a3, 0x0000, 0x7003, 0x0000, 0x7043, 0x0001, 0x7037, 0x0000,
- 0x0018, 0x24b1, 0x1078, 0x1c0c, 0x0040, 0x3c99, 0x2009, 0x520f,
- 0x200b, 0x0000, 0x68bc, 0x2060, 0x6100, 0xa184, 0x0300, 0x0040,
- 0x3c8d, 0x6827, 0x000e, 0xa084, 0x0200, 0x0040, 0x3c89, 0x6827,
- 0x0017, 0x1078, 0x3bc6, 0x0078, 0x3c68, 0x7000, 0xa086, 0x0007,
- 0x00c0, 0x3d0d, 0x2d00, 0x70a2, 0xad80, 0x000f, 0x7036, 0x0078,
- 0x3ca0, 0x7040, 0xa086, 0x0001, 0x0040, 0x2533, 0x0078, 0x24fa,
- 0x2031, 0x0000, 0x691c, 0xa184, 0x0002, 0x0040, 0x3ca9, 0xa6b5,
- 0x0004, 0xa184, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080, 0x3da6,
- 0x2004, 0xa635, 0x6820, 0xa084, 0x0400, 0x0040, 0x3cc1, 0x789b,
- 0x0018, 0x78ab, 0x0003, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5,
- 0x5000, 0x6820, 0xa084, 0x8000, 0x0040, 0x3ccf, 0xa6b5, 0x0400,
- 0x789b, 0x000e, 0x6824, 0x8007, 0x78aa, 0x0078, 0x3cef, 0x681c,
- 0xd0fc, 0x00c0, 0x3cdd, 0xa6b5, 0x0800, 0x6820, 0xd0c4, 0x0040,
- 0x3cef, 0xa6b5, 0x4000, 0x0078, 0x3cef, 0x6820, 0xd0c4, 0x0040,
- 0x3ce5, 0xa6b5, 0x4000, 0x0078, 0x3cef, 0x789b, 0x0018, 0x78ab,
- 0x0002, 0x789b, 0x0081, 0x78ab, 0x0001, 0xa6b5, 0x1000, 0xa684,
- 0x0200, 0x0040, 0x3d09, 0x682c, 0x78d2, 0x6830, 0x78d6, 0xa684,
- 0x0100, 0x0040, 0x3d07, 0x682c, 0xa084, 0x0001, 0x0040, 0x3d07,
- 0x7888, 0xa084, 0x0040, 0x0040, 0x3d07, 0xa6b5, 0x8000, 0x1078,
- 0x47f6, 0x7e5a, 0x6eb6, 0x0078, 0x4835, 0x1078, 0x39c8, 0x00c0,
- 0x3da0, 0x702c, 0x8004, 0x0048, 0x3d1b, 0x2019, 0x4f49, 0x1078,
- 0x2313, 0x702f, 0x0001, 0x2041, 0x0001, 0x2031, 0x1000, 0x789b,
- 0x0018, 0x6814, 0xa084, 0x001f, 0xa085, 0x0080, 0x78aa, 0x691c,
- 0xa184, 0x0002, 0x0040, 0x3d34, 0xa6b5, 0x0004, 0x78ab, 0x0020,
- 0x6828, 0x78aa, 0xa8c0, 0x0002, 0x681c, 0xd0f4, 0x0040, 0x3d3d,
- 0x2c50, 0x1078, 0x3a7a, 0x1078, 0x4702, 0x6820, 0xa084, 0x8000,
- 0x0040, 0x3d4b, 0xa6b5, 0x0400, 0x789b, 0x000e, 0x6824, 0x8007,
- 0x78aa, 0x0078, 0x3d52, 0x681c, 0xa084, 0x8000, 0x00c0, 0x3d52,
- 0xa6b5, 0x0800, 0x6820, 0xa084, 0x0100, 0x0040, 0x3d59, 0xa6b5,
- 0x4000, 0x681c, 0xa084, 0x00c0, 0x8003, 0x8003, 0x8007, 0xa080,
- 0x3da6, 0x2004, 0xa635, 0xa684, 0x0100, 0x0040, 0x3d73, 0x682c,
- 0xa084, 0x0001, 0x0040, 0x3d73, 0x7888, 0xa084, 0x0040, 0x0040,
- 0x3d73, 0xa6b5, 0x8000, 0x789b, 0x007e, 0x7eae, 0x6eb6, 0x6814,
- 0x8007, 0x78aa, 0x7882, 0x2810, 0x7aaa, 0x7830, 0xa084, 0x00c0,
- 0x00c0, 0x3da0, 0x0018, 0x3da0, 0x70b4, 0xa080, 0x00dd, 0x781a,
- 0x1078, 0x39e0, 0xa684, 0x0200, 0x0040, 0x3d94, 0x682c, 0x78d2,
- 0x6830, 0x78d6, 0x1078, 0x47f6, 0x2d00, 0x70a2, 0x704a, 0x6810,
- 0x70be, 0x7003, 0x0007, 0xad80, 0x000f, 0x7036, 0x0078, 0x24fa,
- 0x1078, 0x1bd3, 0x1078, 0x39e0, 0x0078, 0x24fa, 0x0000, 0x0300,
- 0x0200, 0x0000, 0x1078, 0x248c, 0x2300, 0x0079, 0x3daf, 0x3db2,
- 0x3db2, 0x3db4, 0x1078, 0x248c, 0x1078, 0x4805, 0x6924, 0xa184,
- 0x00ff, 0xa086, 0x000a, 0x0040, 0x3dc6, 0xa184, 0xff00, 0xa085,
- 0x000a, 0x6826, 0x1078, 0x1bd3, 0x0078, 0x3c68, 0x2001, 0x000a,
- 0x1078, 0x4797, 0x0078, 0x3c68, 0xa282, 0x0005, 0x0050, 0x3dd2,
- 0x1078, 0x248c, 0x7000, 0xa084, 0x0007, 0x10c0, 0x3a8c, 0x1078,
- 0x1989, 0x00c0, 0x3df4, 0x2069, 0xffff, 0xa684, 0x0004, 0x0040,
- 0x3de5, 0x2001, 0x2800, 0x0078, 0x3de7, 0x2001, 0x0800, 0x71b4,
- 0xa188, 0x0091, 0x789b, 0x000e, 0x8007, 0x78aa, 0x2031, 0x0400,
- 0x7e5a, 0x791a, 0x0078, 0x24fa, 0x6807, 0x0106, 0x680b, 0x0000,
- 0x689f, 0x0000, 0x6827, 0x0000, 0xa386, 0x0002, 0x00c0, 0x3e15,
- 0xa286, 0x0002, 0x00c0, 0x3e15, 0x78a0, 0xa005, 0x00c0, 0x3e15,
- 0xa484, 0x8000, 0x00c0, 0x3e15, 0x78e4, 0xa084, 0x0008, 0x0040,
- 0x3e15, 0xa6b5, 0x0008, 0x2019, 0x0000, 0x1078, 0x4217, 0x2d00,
- 0x70a2, 0x704a, 0x7003, 0x0007, 0x7037, 0x0000, 0x6824, 0xa084,
- 0x0080, 0x0040, 0x3e27, 0x1078, 0x42cd, 0x0078, 0x24fa, 0x2300,
- 0x0079, 0x3e2a, 0x3e2d, 0x3eae, 0x3ec7, 0x2200, 0x0079, 0x3e30,
- 0x3e35, 0x3e45, 0x3e6b, 0x3e77, 0x3e9a, 0x2029, 0x0001, 0xa026,
- 0x2011, 0x0000, 0x1078, 0x43f3, 0x0079, 0x3e3e, 0x3e43, 0x24fa,
- 0x3c68, 0x3e43, 0x3e43, 0x1078, 0x248c, 0x7990, 0xa18c, 0x0007,
- 0x00c0, 0x3e4c, 0x2009, 0x0008, 0x2011, 0x0001, 0xa684, 0x0004,
- 0x0040, 0x3e54, 0x2011, 0x0003, 0x2220, 0xa12a, 0x2011, 0x0001,
- 0x1078, 0x43f3, 0x0079, 0x3e5c, 0x3e61, 0x24fa, 0x3c68, 0x3e69,
- 0x3e63, 0x0078, 0x483b, 0x70ab, 0x3e67, 0x0078, 0x24fa, 0x0078,
- 0x3e61, 0x1078, 0x248c, 0xa684, 0x0010, 0x0040, 0x3e75, 0x1078,
- 0x429c, 0x0040, 0x3e75, 0x0078, 0x24fa, 0x0078, 0x430d, 0x6000,
- 0xa084, 0x0002, 0x0040, 0x3e94, 0x70b4, 0xa080, 0x00cd, 0x781a,
- 0x0d7e, 0x1078, 0x4812, 0x2d00, 0x682e, 0x6827, 0x0000, 0x1078,
- 0x3bc6, 0x0d7f, 0x1078, 0x19ac, 0x7003, 0x0000, 0x7037, 0x0000,
- 0x704b, 0x0000, 0x0078, 0x3c68, 0xa684, 0x0004, 0x00c0, 0x3e9a,
- 0x0078, 0x483b, 0x6000, 0xa084, 0x0004, 0x00c0, 0x3eac, 0x6000,
- 0xa084, 0x0001, 0x0040, 0x3eac, 0x70ab, 0x3eac, 0x2001, 0x0007,
- 0x1078, 0x478f, 0x0078, 0x4841, 0x0078, 0x483b, 0x2200, 0x0079,
- 0x3eb1, 0x3eb6, 0x3eb8, 0x3eb6, 0x3eb6, 0x3eb6, 0x1078, 0x248c,
- 0x70a7, 0x3ebc, 0x0078, 0x4847, 0x78e4, 0xa084, 0x0008, 0x00c0,
- 0x3eb8, 0x1078, 0x4781, 0x70ab, 0x3ec5, 0x0078, 0x483b, 0x2200,
- 0x0079, 0x3eca, 0x3ecf, 0x3ed1, 0x3ed1, 0x3ecf, 0x3ecf, 0x1078,
- 0x248c, 0x78e4, 0xa084, 0x0008, 0x0040, 0x3ee6, 0x70a7, 0x3eda,
- 0x0078, 0x4847, 0x2011, 0x0004, 0x1078, 0x43ed, 0x0079, 0x3ee0,
- 0x3ee6, 0x24fa, 0x3c68, 0x3ee6, 0x3ef0, 0x3ef4, 0x70ab, 0x3eee,
- 0x2001, 0x0003, 0x1078, 0x478f, 0x0078, 0x4841, 0x0078, 0x483b,
- 0x70ab, 0x3ee6, 0x0078, 0x24fa, 0x70ab, 0x3ef8, 0x0078, 0x24fa,
- 0x0078, 0x3eee, 0xa282, 0x0003, 0x0050, 0x3f00, 0x1078, 0x248c,
- 0xa386, 0x0002, 0x00c0, 0x3f19, 0xa286, 0x0002, 0x00c0, 0x3f1f,
- 0x78a0, 0xa005, 0x00c0, 0x3f1f, 0xa484, 0x8000, 0x00c0, 0x3f1f,
- 0x78e4, 0xa084, 0x0008, 0x0040, 0x3f19, 0xa6b5, 0x0008, 0x2019,
- 0x0000, 0xa684, 0x0008, 0x0040, 0x3f1f, 0x1078, 0x4279, 0x6810,
- 0x70be, 0x7003, 0x0007, 0x2300, 0x0079, 0x3f26, 0x3f29, 0x3f56,
- 0x3f5e, 0x2200, 0x0079, 0x3f2c, 0x3f31, 0x3f2f, 0x3f4a, 0x1078,
- 0x248c, 0x7990, 0xa1ac, 0x0007, 0xa026, 0x2011, 0x0001, 0x1078,
- 0x43f3, 0x0079, 0x3f3b, 0x3f40, 0x24fa, 0x3c68, 0x3f48, 0x3f42,
- 0x0078, 0x483b, 0x70ab, 0x3f46, 0x0078, 0x24fa, 0x0078, 0x3f40,
- 0x1078, 0x248c, 0xa684, 0x0010, 0x0040, 0x3f54, 0x1078, 0x429c,
- 0x0040, 0x3f54, 0x0078, 0x24fa, 0x0078, 0x430d, 0x2200, 0x0079,
- 0x3f59, 0x3f5c, 0x3f5c, 0x3f5c, 0x1078, 0x248c, 0x2200, 0x0079,
- 0x3f61, 0x3f64, 0x3f66, 0x3f66, 0x1078, 0x248c, 0x78e4, 0xa084,
- 0x0008, 0x0040, 0x3f7b, 0x70a7, 0x3f6f, 0x0078, 0x4847, 0x2011,
- 0x0004, 0x1078, 0x43ed, 0x0079, 0x3f75, 0x3f7b, 0x24fa, 0x3c68,
- 0x3f7b, 0x3f85, 0x3f89, 0x70ab, 0x3f83, 0x2001, 0x0003, 0x1078,
- 0x478f, 0x0078, 0x4841, 0x0078, 0x483b, 0x70ab, 0x3f7b, 0x0078,
- 0x24fa, 0x70ab, 0x3f8d, 0x0078, 0x24fa, 0x0078, 0x3f83, 0x2300,
- 0x0079, 0x3f92, 0x3f97, 0x3f99, 0x3f95, 0x1078, 0x248c, 0x70a4,
- 0x007a, 0x70a4, 0x007a, 0xa282, 0x0002, 0x0050, 0x3fa1, 0x1078,
- 0x248c, 0xa684, 0x0200, 0x0040, 0x3fab, 0x1078, 0x47fe, 0x1078,
- 0x43d5, 0x1078, 0x4805, 0x2300, 0x0079, 0x3fae, 0x3fb1, 0x3fd9,
- 0x403f, 0xad86, 0xffff, 0x0040, 0x3c68, 0xa286, 0x0001, 0x0040,
- 0x3fbb, 0x1078, 0x248c, 0xa684, 0x0200, 0x0040, 0x3fc3, 0x1078,
- 0x47fe, 0x1078, 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x78b8,
- 0xa084, 0xc001, 0x0040, 0x3fd5, 0x7848, 0xa085, 0x0008, 0x784a,
- 0x7848, 0xa084, 0x0008, 0x00c0, 0x3fd0, 0x7003, 0x0000, 0x0078,
- 0x3c68, 0x2200, 0x0079, 0x3fdc, 0x3fde, 0x400f, 0x70a7, 0x3fe2,
- 0x0078, 0x4847, 0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x3fe8,
- 0x3fef, 0x24fa, 0x3c68, 0x3ff7, 0x3fff, 0x4005, 0x4007, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab,
- 0x4003, 0x0078, 0x24fa, 0x0078, 0x3fef, 0x1078, 0x248c, 0x70ab,
- 0x400b, 0x0078, 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x70a7,
- 0x4013, 0x0078, 0x4847, 0x2011, 0x0012, 0x1078, 0x43ed, 0x0079,
- 0x4019, 0x401f, 0x24fa, 0x3c68, 0x402b, 0x4033, 0x4039, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a, 0x70b4, 0xa080, 0x00aa,
- 0x781a, 0x0078, 0x24fa, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6,
- 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x4037, 0x0078, 0x24fa, 0x0078,
- 0x401f, 0x70ab, 0x403d, 0x0078, 0x24fa, 0x0078, 0x402b, 0xa286,
- 0x0001, 0x0040, 0x4045, 0x1078, 0x248c, 0x70a7, 0x4049, 0x0078,
- 0x4847, 0x2011, 0x0015, 0x1078, 0x43ed, 0x0079, 0x404f, 0x4054,
- 0x24fa, 0x3c68, 0x4062, 0x406e, 0xa6b4, 0x00ff, 0xa6b5, 0x0400,
- 0x6eb6, 0x7e5a, 0x783b, 0x1301, 0x70b4, 0xa080, 0x00b5, 0x781a,
- 0x0078, 0x24fa, 0xa6b4, 0x00ff, 0xa6b5, 0x0400, 0x6eb6, 0x7e5a,
- 0x70b4, 0xa080, 0x00aa, 0x781a, 0x0078, 0x24fa, 0x70ab, 0x4072,
- 0x0078, 0x24fa, 0x0078, 0x4054, 0xa282, 0x0003, 0x0050, 0x407a,
- 0x1078, 0x248c, 0x2300, 0x0079, 0x407d, 0x4080, 0x40b7, 0x4114,
- 0xa286, 0x0001, 0x0040, 0x4086, 0x1078, 0x248c, 0x6804, 0xa084,
- 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4093, 0x1078, 0x3bc6, 0x7003,
- 0x0000, 0x0078, 0x3c68, 0x683b, 0x0000, 0x6837, 0x0000, 0xa684,
- 0x0200, 0x0040, 0x40a1, 0x1078, 0x47fe, 0x1078, 0x43d5, 0x1078,
- 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x78b8, 0xa084, 0xc001,
- 0x0040, 0x40b3, 0x7848, 0xa085, 0x0008, 0x784a, 0x7848, 0xa084,
- 0x0008, 0x00c0, 0x40ae, 0x7003, 0x0000, 0x0078, 0x3c68, 0x2200,
- 0x0079, 0x40ba, 0x40bc, 0x40ef, 0x70a7, 0x40c0, 0x0078, 0x4847,
- 0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x40c6, 0x40cd, 0x24fa,
- 0x3c68, 0x40d5, 0x40dd, 0x40e3, 0x40e5, 0xa6b4, 0x00ff, 0xa6b5,
- 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4, 0x00ff, 0xa6b5,
- 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x40e1, 0x0078,
- 0x24fa, 0x0078, 0x40cd, 0x1078, 0x248c, 0x70ab, 0x40eb, 0x1078,
- 0x4805, 0x0078, 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x70a7,
- 0x40f3, 0x0078, 0x4847, 0x2011, 0x0005, 0x1078, 0x43ed, 0x0079,
- 0x40f9, 0x40fe, 0x24fa, 0x3c68, 0x4106, 0x410e, 0xa6b4, 0x00ff,
- 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4, 0x00ff,
- 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0x70ab, 0x4112,
- 0x0078, 0x24fa, 0x0078, 0x40fe, 0xa286, 0x0001, 0x0040, 0x411a,
- 0x1078, 0x248c, 0x70a7, 0x411e, 0x0078, 0x4847, 0x2011, 0x0006,
- 0x1078, 0x43ed, 0x0079, 0x4124, 0x4129, 0x24fa, 0x3c68, 0x412f,
- 0x4139, 0xa6b5, 0x0800, 0x6eb6, 0x7e5a, 0x0078, 0x4835, 0xa6b4,
- 0x00ff, 0xa6b5, 0x0800, 0x6eb6, 0xa6b5, 0x4000, 0x7e5a, 0x0078,
- 0x4835, 0x70ab, 0x413d, 0x0078, 0x24fa, 0x0078, 0x4129, 0x2300,
- 0x0079, 0x4142, 0x4147, 0x4145, 0x4145, 0x1078, 0x248c, 0x1078,
- 0x248c, 0x2300, 0x71a8, 0xa005, 0x017a, 0x6810, 0x70be, 0xa282,
- 0x0003, 0x0050, 0x4155, 0x1078, 0x248c, 0x2300, 0x0079, 0x4158,
- 0x415b, 0x4169, 0x418b, 0xa684, 0x0200, 0x0040, 0x4163, 0x1078,
- 0x47fe, 0x1078, 0x4805, 0x2001, 0x0001, 0x1078, 0x4797, 0x0078,
- 0x24fa, 0xa296, 0x0002, 0x0040, 0x4172, 0x82ff, 0x0040, 0x4172,
- 0x1078, 0x248c, 0x70a7, 0x4176, 0x0078, 0x4847, 0x2011, 0x0018,
- 0x1078, 0x43ed, 0x0079, 0x417c, 0x4181, 0x24fa, 0x3c68, 0x4183,
- 0x4185, 0x0078, 0x4835, 0x0078, 0x4835, 0x70ab, 0x4189, 0x0078,
- 0x24fa, 0x0078, 0x4181, 0x2200, 0x0079, 0x418e, 0x4190, 0x41a9,
- 0x70a7, 0x4194, 0x0078, 0x4847, 0x2011, 0x0017, 0x1078, 0x43ed,
- 0x0079, 0x419a, 0x419f, 0x24fa, 0x3c68, 0x41a1, 0x41a3, 0x0078,
- 0x4835, 0x0078, 0x4835, 0x70ab, 0x41a7, 0x0078, 0x24fa, 0x0078,
- 0x419f, 0xa484, 0x8000, 0x00c0, 0x4205, 0xa684, 0x0100, 0x0040,
- 0x41b5, 0x1078, 0x47fe, 0x1078, 0x43d5, 0x78d8, 0x78d2, 0x78dc,
- 0x78d6, 0xa6b4, 0xefff, 0x7e5a, 0x70a7, 0x41c0, 0x0078, 0x4847,
- 0x2011, 0x000d, 0x1078, 0x43ed, 0x0079, 0x41c6, 0x41cd, 0x24fa,
- 0x3c68, 0x41cd, 0x41f3, 0x41f9, 0x41fb, 0x78d8, 0x79dc, 0xa105,
- 0x00c0, 0x41df, 0x78b8, 0xa084, 0x001f, 0x00c0, 0x41df, 0x70b3,
- 0x0000, 0x7858, 0xa084, 0xfdff, 0x785a, 0x0078, 0x4835, 0xa684,
- 0x0100, 0x0040, 0x41f1, 0x7848, 0xa085, 0x0008, 0x784a, 0x1078,
- 0x47bc, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x70b3, 0x0000, 0x1078,
- 0x47f6, 0x0078, 0x4835, 0x70ab, 0x41f7, 0x0078, 0x24fa, 0x0078,
- 0x41cd, 0x1078, 0x248c, 0x70ab, 0x4201, 0x1078, 0x4805, 0x0078,
- 0x24fa, 0x1078, 0x484d, 0x0078, 0x24fa, 0x1078, 0x4805, 0x70ab,
- 0x420f, 0x2001, 0x0003, 0x1078, 0x478f, 0x0078, 0x4841, 0x1078,
- 0x47f6, 0x682c, 0x78d2, 0x6830, 0x78d6, 0x0078, 0x4835, 0x70b8,
- 0x6812, 0x70be, 0x8000, 0x70ba, 0x681b, 0x0000, 0xa684, 0x0008,
- 0x0040, 0x423a, 0x157e, 0x137e, 0x147e, 0x7890, 0x8004, 0x8004,
- 0x8004, 0x8004, 0xa084, 0x000f, 0x681a, 0x80ac, 0x789b, 0x0000,
- 0xaf80, 0x002b, 0x2098, 0xad80, 0x000b, 0x20a0, 0x53a5, 0x147f,
- 0x137f, 0x157f, 0xa6c4, 0x0f00, 0xa684, 0x0002, 0x00c0, 0x4249,
- 0x692c, 0x810d, 0x810d, 0x810d, 0xa184, 0x0007, 0x2008, 0x0078,
- 0x425c, 0x789b, 0x0010, 0x79ac, 0xa184, 0x0020, 0x0040, 0x425c,
- 0x017e, 0x2009, 0x0005, 0x2001, 0x3d00, 0x1078, 0x47c7, 0x6824,
- 0xa085, 0x003b, 0x6826, 0x017f, 0xa184, 0x001f, 0xa805, 0x6816,
- 0x1078, 0x3c3b, 0x68be, 0xa684, 0x0004, 0x0040, 0x426d, 0xa18c,
- 0xff00, 0x78a8, 0xa084, 0x00ff, 0xa105, 0x682a, 0xa6b4, 0x00ff,
- 0x6000, 0xa084, 0x0008, 0x0040, 0x4277, 0xa6b5, 0x4000, 0x6eb6,
- 0x007c, 0x157e, 0x137e, 0x147e, 0x6918, 0x7890, 0x8004, 0x8004,
- 0x8004, 0x8004, 0xa084, 0x000f, 0x007e, 0xa100, 0x681a, 0x007f,
- 0x8000, 0x8004, 0x0040, 0x4298, 0x20a8, 0x8104, 0xa080, 0x000b,
- 0xad00, 0x20a0, 0x789b, 0x0000, 0xaf80, 0x002b, 0x2098, 0x53a5,
- 0x147f, 0x137f, 0x157f, 0x007c, 0x682c, 0xa084, 0x0020, 0x00c0,
- 0x42a4, 0x620c, 0x0078, 0x42a5, 0x6210, 0x6b18, 0x2300, 0xa202,
- 0x0040, 0x42c5, 0x2018, 0xa382, 0x000e, 0x0048, 0x42b5, 0x0040,
- 0x42b5, 0x2019, 0x000e, 0x0078, 0x42b9, 0x7858, 0xa084, 0xffef,
- 0x785a, 0x783b, 0x1b01, 0x7893, 0x0000, 0x7ba2, 0x70b4, 0xa080,
- 0x008e, 0x781a, 0xa085, 0x0001, 0x007c, 0x7858, 0xa084, 0xffef,
- 0x785a, 0x7893, 0x0000, 0xa006, 0x007c, 0x6904, 0xa18c, 0x00ff,
- 0xa196, 0x0007, 0x0040, 0x42da, 0xa196, 0x000f, 0x0040, 0x42da,
- 0x6807, 0x0117, 0x6914, 0x1078, 0x3c3b, 0x6100, 0x8104, 0x00c8,
- 0x42f5, 0x601c, 0xa005, 0x0040, 0x42e9, 0x2001, 0x0800, 0x0078,
- 0x42f7, 0x0d7e, 0x6824, 0x007e, 0x1078, 0x4812, 0x007f, 0x6826,
- 0x2d00, 0x682e, 0x1078, 0x3bc6, 0x0d7f, 0x2001, 0x0200, 0x6924,
- 0xa18c, 0x00ff, 0xa10d, 0x6926, 0x8007, 0x789b, 0x000e, 0x78aa,
- 0x6820, 0xa085, 0x8000, 0x6822, 0x2031, 0x0400, 0x6eb6, 0x7e5a,
- 0x71b4, 0xa188, 0x0091, 0x791a, 0x007c, 0xa6c4, 0x0f00, 0xa684,
- 0x0002, 0x00c0, 0x4321, 0x692c, 0x810d, 0x810d, 0x810d, 0xa184,
- 0x0007, 0x2008, 0xa805, 0x6816, 0x1078, 0x3c3b, 0x68be, 0x0078,
- 0x4324, 0x6914, 0x1078, 0x3c3b, 0x6100, 0x8104, 0x00c8, 0x4382,
- 0xa184, 0x0300, 0x0040, 0x4330, 0x6807, 0x0117, 0x0078, 0x434e,
- 0x6004, 0xa005, 0x00c0, 0x4357, 0x6807, 0x0117, 0x601c, 0xa005,
- 0x00c0, 0x4344, 0x0d7e, 0x1078, 0x4812, 0x6827, 0x0034, 0x2d00,
- 0x682e, 0x1078, 0x3bc6, 0x0d7f, 0xa684, 0x0004, 0x0040, 0x434e,
- 0x2031, 0x0400, 0x2001, 0x2800, 0x0078, 0x4352, 0x2031, 0x0400,
- 0x2001, 0x0800, 0x71b4, 0xa188, 0x0091, 0x0078, 0x43b0, 0x6018,
- 0xa005, 0x00c0, 0x4344, 0x601c, 0xa005, 0x00c0, 0x4344, 0x689f,
- 0x0000, 0x6827, 0x003d, 0xa684, 0x0001, 0x0040, 0x43be, 0xd694,
- 0x00c0, 0x437b, 0x6100, 0xd1d4, 0x0040, 0x437b, 0x692c, 0xa18c,
- 0x00ff, 0x0040, 0x43be, 0xa186, 0x0003, 0x0040, 0x43be, 0xa186,
- 0x0012, 0x0040, 0x43be, 0xa6b5, 0x0800, 0x71b4, 0xa188, 0x00ae,
- 0x0078, 0x43b9, 0x6807, 0x0117, 0x2031, 0x0400, 0x692c, 0xa18c,
- 0x00ff, 0xa186, 0x0012, 0x00c0, 0x4393, 0x2001, 0x43cb, 0x2009,
- 0x0001, 0x0078, 0x43a4, 0xa186, 0x0003, 0x00c0, 0x439d, 0x2001,
- 0x43cc, 0x2009, 0x0012, 0x0078, 0x43a4, 0x2001, 0x0200, 0x71b4,
- 0xa188, 0x0091, 0x0078, 0x43b0, 0x1078, 0x47e1, 0x78a3, 0x0000,
- 0x681c, 0xa085, 0x0040, 0x681e, 0x71b4, 0xa188, 0x00da, 0xa006,
- 0x6826, 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000,
- 0x6822, 0x6eb6, 0x7e5a, 0x791a, 0x0078, 0x24fa, 0x6eb6, 0x1078,
- 0x3bc6, 0x6810, 0x70be, 0x7003, 0x0007, 0x70a3, 0x0000, 0x704b,
- 0x0000, 0x0078, 0x24fa, 0x0023, 0x0070, 0x0005, 0x0000, 0x0a00,
- 0x0000, 0x0000, 0x0025, 0x0000, 0x0000, 0x683b, 0x0000, 0x6837,
- 0x0000, 0xa684, 0x0200, 0x0040, 0x43ec, 0x78b8, 0xa08c, 0x001f,
- 0xa084, 0x8000, 0x0040, 0x43e5, 0x8108, 0x78d8, 0xa100, 0x6836,
- 0x78dc, 0xa081, 0x0000, 0x683a, 0x007c, 0x7990, 0x810f, 0xa5ac,
- 0x0007, 0x2021, 0x0000, 0xa480, 0x0010, 0x789a, 0x79a8, 0xa18c,
- 0x00ff, 0xa184, 0x0080, 0x00c0, 0x441b, 0xa182, 0x0020, 0x00c8,
- 0x4439, 0xa182, 0x0012, 0x00c8, 0x4781, 0x2100, 0x1079, 0x4409,
- 0x007c, 0x4781, 0x45eb, 0x4781, 0x4781, 0x4446, 0x4449, 0x4483,
- 0x44b9, 0x44ed, 0x44f0, 0x4781, 0x4781, 0x44a4, 0x4514, 0x454e,
- 0x4781, 0x4781, 0x4574, 0xa184, 0x0020, 0x00c0, 0x45a8, 0xa18c,
- 0x001f, 0x6814, 0xa084, 0x001f, 0xa106, 0x0040, 0x4436, 0x70b4,
- 0xa080, 0x00cd, 0x781a, 0x2001, 0x0014, 0x1078, 0x4797, 0x1078,
- 0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x2001, 0x0000,
- 0x007c, 0xa182, 0x0024, 0x00c8, 0x4781, 0xa184, 0x0003, 0x1079,
- 0x4409, 0x007c, 0x4781, 0x4781, 0x4781, 0x4781, 0x1078, 0x4781,
- 0x007c, 0x2200, 0x0079, 0x444c, 0x4577, 0x4577, 0x4470, 0x4470,
- 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x446e, 0x4470,
- 0x4465, 0x4470, 0x4470, 0x4470, 0x4470, 0x4470, 0x4478, 0x447b,
- 0x4577, 0x447b, 0x4470, 0x4470, 0x4470, 0x0c7e, 0x077e, 0x6f14,
- 0x1078, 0x37b0, 0x077f, 0x0c7f, 0x0078, 0x4470, 0x1078, 0x468e,
- 0x6827, 0x02b3, 0x2009, 0x000b, 0x2001, 0x4800, 0x0078, 0x45ab,
- 0x1078, 0x4773, 0x007c, 0x6827, 0x0093, 0x2009, 0x000b, 0x2001,
- 0x4800, 0x0078, 0x4593, 0x2d58, 0x6804, 0xa084, 0x00ff, 0xa086,
- 0x0006, 0x00c0, 0x448d, 0x6807, 0x0117, 0x6827, 0x0002, 0x1078,
- 0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
- 0x3b96, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6, 0x0d7f, 0x1078,
- 0x3bc6, 0x2001, 0x0002, 0x007c, 0x1078, 0x45d3, 0x2001, 0x0017,
- 0x1078, 0x4797, 0x70a3, 0x0000, 0x2009, 0x5238, 0x200b, 0x0006,
- 0x70af, 0x0017, 0x2009, 0x0200, 0x1078, 0x3ad4, 0x2001, 0x0001,
- 0x007c, 0x2200, 0x0079, 0x44bc, 0x4577, 0x45a8, 0x45a8, 0x45a8,
- 0x44dd, 0x45ba, 0x44e5, 0x45ba, 0x45ba, 0x45bd, 0x45bd, 0x45c2,
- 0x45c2, 0x44d5, 0x44d5, 0x45a8, 0x45a8, 0x45ba, 0x45a8, 0x44e5,
- 0x4577, 0x44e5, 0x44e5, 0x44e5, 0x44e5, 0x6827, 0x0084, 0x2009,
- 0x000b, 0x2001, 0x4300, 0x0078, 0x45cc, 0x6827, 0x000d, 0x2009,
- 0x000b, 0x2001, 0x4300, 0x0078, 0x45ab, 0x6827, 0x0093, 0x2009,
- 0x000b, 0x2001, 0x4300, 0x0078, 0x4593, 0x2001, 0x0000, 0x007c,
- 0x2200, 0x0079, 0x44f3, 0x4577, 0x450c, 0x450c, 0x450c, 0x450c,
- 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba, 0x45ba,
- 0x450c, 0x450c, 0x450c, 0x450c, 0x45ba, 0x450c, 0x450c, 0x45ba,
- 0x45ba, 0x45ba, 0x45ba, 0x4577, 0x6827, 0x0093, 0x2009, 0x000b,
- 0x2001, 0x4300, 0x0078, 0x4593, 0xa684, 0x0004, 0x00c0, 0x4528,
- 0x6804, 0xa084, 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4781, 0x1078,
- 0x45d3, 0x6807, 0x0117, 0x1078, 0x3bc6, 0x2001, 0x0002, 0x007c,
- 0x6000, 0xa084, 0x0004, 0x0040, 0x4781, 0x2d58, 0x6804, 0xa084,
- 0x00ff, 0xa086, 0x0006, 0x00c0, 0x4537, 0x6807, 0x0117, 0x6827,
- 0x0002, 0x1078, 0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e,
- 0x0d7e, 0x1078, 0x3ba5, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6,
- 0x0d7f, 0x1078, 0x3bc6, 0x2001, 0x0002, 0x007c, 0x6000, 0xa084,
- 0x0004, 0x0040, 0x4781, 0x6a04, 0xa294, 0x00ff, 0xa286, 0x0006,
- 0x00c0, 0x455c, 0x6807, 0x0117, 0x6827, 0x0002, 0x2d58, 0x1078,
- 0x4812, 0x6827, 0x0036, 0x6932, 0x2d00, 0x682e, 0x0d7e, 0x1078,
- 0x3bb5, 0x1078, 0x45d3, 0x2b68, 0x1078, 0x3bc6, 0x0d7f, 0x1078,
- 0x3bc6, 0x2001, 0x0002, 0x007c, 0x1078, 0x4781, 0x007c, 0x70b4,
- 0xa080, 0x00cd, 0x781a, 0x2001, 0x0001, 0x1078, 0x4797, 0x1078,
- 0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c, 0x1078, 0x47c7,
- 0x1078, 0x47fe, 0x1078, 0x43d5, 0x1078, 0x42cd, 0x1078, 0x4805,
- 0x2001, 0x0001, 0x007c, 0x1078, 0x47c7, 0x1078, 0x47fe, 0x1078,
- 0x43d5, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x2001, 0x0013, 0x1078,
- 0x4797, 0x1078, 0x4805, 0x7003, 0x0000, 0x2001, 0x0002, 0x007c,
- 0x1078, 0x4781, 0x007c, 0x1078, 0x47c7, 0x1078, 0x47fe, 0x1078,
- 0x43d5, 0x1078, 0x42cd, 0x1078, 0x4805, 0x1078, 0x484d, 0x2001,
- 0x0001, 0x007c, 0x2001, 0x0003, 0x007c, 0x1078, 0x468e, 0x2001,
- 0x0000, 0x007c, 0x0c7e, 0x077e, 0x6f14, 0x1078, 0x37b0, 0x077f,
- 0x0c7f, 0x2001, 0x0000, 0x007c, 0x1078, 0x47c7, 0x1078, 0x4781,
- 0x2001, 0x0006, 0x007c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007,
- 0x0040, 0x45de, 0xa186, 0x000f, 0x00c0, 0x45e2, 0x1078, 0x47fe,
- 0x1078, 0x43d5, 0x70b4, 0xa080, 0x00cd, 0x781a, 0x1078, 0x4805,
- 0x7003, 0x0000, 0x007c, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084,
- 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x4781, 0x1079, 0x45f8, 0x007c,
- 0x4781, 0x45fc, 0x4781, 0x4695, 0xa282, 0x0003, 0x0040, 0x4603,
- 0x1078, 0x4781, 0x007c, 0x7da8, 0xa5ac, 0x00ff, 0x7ca8, 0xa4a4,
- 0x00ff, 0x69b8, 0xa184, 0x0100, 0x0040, 0x4642, 0xa18c, 0xfeff,
- 0x69ba, 0x78a0, 0xa005, 0x00c0, 0x4642, 0xa4a4, 0x00ff, 0x0040,
- 0x4636, 0xa482, 0x000c, 0x0040, 0x461f, 0x00c8, 0x4629, 0x852b,
- 0x852b, 0x1078, 0x382e, 0x0040, 0x4629, 0x1078, 0x3627, 0x0078,
- 0x4638, 0x1078, 0x4760, 0x1078, 0x3652, 0x69b8, 0xa18d, 0x0100,
- 0x69ba, 0xa6b5, 0x1000, 0x7e5a, 0x0078, 0x463b, 0x1078, 0x3652,
- 0xa6b4, 0xefff, 0x7e5a, 0x70b4, 0xa080, 0x0091, 0x781a, 0x2001,
- 0x0001, 0x007c, 0x0c7e, 0x1078, 0x4682, 0x6200, 0xd2e4, 0x0040,
- 0x4673, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048,
- 0x4655, 0x0040, 0x4655, 0x2011, 0x000c, 0x2400, 0xa202, 0x00c8,
- 0x465a, 0x2220, 0x6208, 0xa294, 0x00ff, 0x701c, 0xa202, 0x00c8,
- 0x4662, 0x721c, 0x2200, 0xa502, 0x00c8, 0x4667, 0x2228, 0x1078,
- 0x4764, 0x852b, 0x852b, 0x1078, 0x382e, 0x0040, 0x4673, 0x1078,
- 0x362e, 0x0078, 0x4677, 0x1078, 0x4760, 0x1078, 0x3659, 0xa6b5,
- 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004,
- 0x0c7f, 0x007c, 0x007e, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa0e0, 0x5480, 0x007f, 0x007c, 0x0c7e, 0x1078,
- 0x4682, 0x1078, 0x3659, 0x0c7f, 0x007c, 0xa282, 0x0002, 0x00c0,
- 0x4781, 0x7aa8, 0xa294, 0x00ff, 0x69b8, 0xa184, 0x0200, 0x0040,
- 0x46cc, 0xa18c, 0xfdff, 0x69ba, 0x78a0, 0xa005, 0x00c0, 0x46cc,
- 0xa282, 0x0002, 0x00c8, 0x376b, 0x1078, 0x472a, 0x1078, 0x36f9,
- 0x1078, 0x3652, 0xa684, 0x0100, 0x0040, 0x46c2, 0x682c, 0xa084,
- 0x0001, 0x0040, 0x46c2, 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040,
- 0x46c2, 0xc6fd, 0xa6b5, 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x0091,
- 0x781a, 0x2001, 0x0001, 0x007c, 0x0c7e, 0x1078, 0x4682, 0xa284,
- 0xfffe, 0x0040, 0x46d7, 0x2011, 0x0001, 0x0078, 0x46db, 0xa284,
- 0x0001, 0x0040, 0x46e1, 0x6100, 0xd1ec, 0x00c0, 0x46e1, 0x2011,
- 0x0000, 0x1078, 0x471c, 0x1078, 0x3700, 0x1078, 0x3659, 0xa684,
- 0x0100, 0x0040, 0x46f7, 0x682c, 0xa084, 0x0001, 0x0040, 0x46f7,
- 0xc6fc, 0x7888, 0xa084, 0x0040, 0x0040, 0x46f7, 0xc6fd, 0xa6b5,
- 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004,
- 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6000, 0x2011, 0x0001, 0xa084,
- 0x2000, 0x00c0, 0x470d, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x68b8, 0xa085,
- 0x0200, 0x68ba, 0x0c7f, 0x007c, 0x789b, 0x0018, 0x78ab, 0x0001,
- 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0081, 0x78ab,
- 0x0004, 0x007c, 0x0c7e, 0x7054, 0x2060, 0x6000, 0xa084, 0x1000,
- 0x00c0, 0x4738, 0x2029, 0x0032, 0x2021, 0x0000, 0x0078, 0x4758,
- 0x6508, 0xa5ac, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0, 0x4748,
- 0xa582, 0x0019, 0x00c8, 0x474e, 0x2029, 0x0019, 0x0078, 0x474e,
- 0xa582, 0x000c, 0x00c8, 0x474e, 0x2029, 0x000c, 0x6408, 0x8427,
- 0xa4a4, 0x00ff, 0xa482, 0x000c, 0x0048, 0x4758, 0x2021, 0x000c,
- 0x1078, 0x4764, 0x68b8, 0xa085, 0x0100, 0x68ba, 0x0c7f, 0x007c,
- 0x2021, 0x0000, 0x2029, 0x0032, 0x789b, 0x0018, 0x78ab, 0x0001,
- 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7caa, 0x789b, 0x0081,
- 0x78ab, 0x0005, 0x007c, 0x2001, 0x0003, 0x1078, 0x478f, 0xa6b5,
- 0x1000, 0x7e5a, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0005,
- 0x007c, 0x2001, 0x0007, 0x1078, 0x478f, 0xa6b5, 0x1000, 0x7e5a,
- 0x70b4, 0xa080, 0x00b9, 0x781a, 0x2001, 0x0004, 0x007c, 0x789b,
- 0x0018, 0x78aa, 0x789b, 0x0081, 0x78ab, 0x0001, 0x007c, 0x6904,
- 0xa18c, 0x00ff, 0xa196, 0x0007, 0x0040, 0x47a5, 0xa196, 0x000f,
- 0x0040, 0x47a5, 0x1078, 0x19ac, 0x007c, 0x6924, 0xa194, 0x003f,
- 0x00c0, 0x47ae, 0xa18c, 0xffc0, 0xa105, 0x6826, 0x1078, 0x3bc6,
- 0x691c, 0xa184, 0x0100, 0x0040, 0x47bb, 0x6914, 0x1078, 0x3c3b,
- 0x6204, 0x8210, 0x6206, 0x007c, 0x692c, 0x6834, 0x682e, 0xa112,
- 0x6930, 0x6838, 0x6832, 0xa11b, 0xa200, 0xa301, 0x007c, 0x0c7e,
- 0xade0, 0x0018, 0x6003, 0x0070, 0x6106, 0x600b, 0x0000, 0x600f,
- 0x0a00, 0x6013, 0x0000, 0x6017, 0x0000, 0x8007, 0x601a, 0x601f,
- 0x0000, 0x6023, 0x0000, 0x0c7f, 0x6824, 0xa085, 0x0080, 0x6826,
- 0x007c, 0x157e, 0x137e, 0x147e, 0x2098, 0xaf80, 0x002d, 0x20a0,
- 0x81ac, 0x0040, 0x47ec, 0x53a6, 0xa184, 0x0001, 0x0040, 0x47f2,
- 0x3304, 0x78be, 0x147f, 0x137f, 0x157f, 0x007c, 0x70b0, 0xa005,
- 0x10c0, 0x248c, 0x70b3, 0x8000, 0x0078, 0x4b4b, 0x71b0, 0x81ff,
- 0x0040, 0x4804, 0x1078, 0x4c41, 0x007c, 0x71b0, 0x81ff, 0x0040,
- 0x4811, 0x7848, 0xa085, 0x0008, 0x784a, 0x70b3, 0x0000, 0x1078,
- 0x4887, 0x007c, 0x0c7e, 0x0d7e, 0x1078, 0x1989, 0x00c0, 0x481a,
- 0x1078, 0x248c, 0x0c7f, 0x157e, 0x137e, 0x147e, 0x2da0, 0x2c98,
- 0x20a9, 0x0031, 0x53a3, 0x147f, 0x137f, 0x157f, 0x6807, 0x010d,
- 0x680b, 0x0000, 0x7004, 0x8007, 0x681a, 0x6823, 0x0000, 0x681f,
- 0x0000, 0x689f, 0x0000, 0x0c7f, 0x007c, 0x70b4, 0xa080, 0x0091,
- 0x781a, 0x0078, 0x24fa, 0x70b4, 0xa080, 0x0081, 0x781a, 0x0078,
- 0x24fa, 0x70b4, 0xa080, 0x00b9, 0x781a, 0x0078, 0x24fa, 0x70b4,
- 0xa080, 0x00c3, 0x781a, 0x0078, 0x24fa, 0x6904, 0xa18c, 0x00ff,
- 0xa196, 0x0007, 0x0040, 0x485a, 0xa196, 0x000f, 0x0040, 0x485a,
- 0x6807, 0x0117, 0x6824, 0xa084, 0x00ff, 0xa085, 0x0200, 0x6826,
- 0x8007, 0x789b, 0x000e, 0x78aa, 0x6820, 0xa085, 0x8000, 0x6822,
- 0x2031, 0x0400, 0x6eb6, 0x7e5a, 0x71b4, 0xa188, 0x0091, 0x791a,
- 0x007c, 0x1078, 0x4805, 0x7848, 0xa085, 0x000c, 0x784a, 0x70b4,
- 0xa080, 0x00cd, 0x781a, 0x2009, 0x000b, 0x2001, 0x4400, 0x1078,
- 0x47c7, 0x2001, 0x0013, 0x1078, 0x4797, 0x0078, 0x3c68, 0x127e,
- 0x2091, 0x2200, 0x2049, 0x4887, 0x7000, 0x7204, 0xa205, 0x720c,
- 0xa215, 0x7008, 0xa084, 0xfff7, 0xa205, 0x0040, 0x4899, 0x0078,
- 0x489e, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084,
- 0x0001, 0x00c0, 0x48cc, 0x7108, 0x8103, 0x00c8, 0x48ab, 0x1078,
- 0x49ce, 0x0078, 0x48a3, 0x700c, 0xa08c, 0x00ff, 0x0040, 0x48cc,
- 0x7004, 0x8004, 0x00c8, 0x48c3, 0x7014, 0xa005, 0x00c0, 0x48bf,
- 0x7010, 0xa005, 0x0040, 0x48c3, 0xa102, 0x00c8, 0x48a3, 0x7007,
- 0x0010, 0x0078, 0x48cc, 0x8aff, 0x0040, 0x48cc, 0x1078, 0x4c18,
- 0x00c0, 0x48c6, 0x0040, 0x48a3, 0x1078, 0x4957, 0x7003, 0x0000,
- 0x127f, 0x2000, 0x007c, 0x017e, 0x6104, 0xa18c, 0x00ff, 0xa186,
- 0x0007, 0x0040, 0x48df, 0xa18e, 0x000f, 0x00c0, 0x48e2, 0x6040,
- 0x0078, 0x48e3, 0x6428, 0x017f, 0x84ff, 0x0040, 0x490d, 0x2c70,
- 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x491d, 0x273c, 0x87fb, 0x00c0,
- 0x48fb, 0x0048, 0x48f5, 0x1078, 0x248c, 0x609c, 0xa075, 0x0040,
- 0x490d, 0x0078, 0x48e8, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c,
- 0xa529, 0x8421, 0x0040, 0x490d, 0x8738, 0x2704, 0xa005, 0x00c0,
- 0x48fc, 0x709c, 0xa075, 0x00c0, 0x48e8, 0x007c, 0x0000, 0x0005,
- 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
- 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4912, 0x490f,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4912, 0x0000, 0x491a, 0x4917,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x491a, 0x0000, 0x4915, 0x4915,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4915, 0x0000, 0x491b, 0x491b,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x491b, 0x127e, 0x2091, 0x2200,
- 0x2079, 0x5200, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002,
- 0x7003, 0x0000, 0x2071, 0x0020, 0x7007, 0x000a, 0x7007, 0x0002,
- 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049,
- 0x4957, 0x2019, 0x0000, 0x7004, 0x8004, 0x00c8, 0x49aa, 0x7007,
- 0x0012, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4961, 0xa184, 0x01e0,
- 0x0040, 0x496c, 0x1078, 0x248c, 0x2001, 0x04fd, 0x2004, 0xa082,
- 0x0005, 0x00c8, 0x4977, 0xa184, 0x4000, 0x00c0, 0x4961, 0xa19c,
- 0x300c, 0xa386, 0x2004, 0x0040, 0x4985, 0xa386, 0x0008, 0x0040,
- 0x4990, 0xa386, 0x200c, 0x00c0, 0x4961, 0x7200, 0x8204, 0x0048,
- 0x4990, 0x730c, 0xa384, 0x00ff, 0x0040, 0x4990, 0x1078, 0x248c,
- 0x7007, 0x0012, 0x7000, 0xa084, 0x0001, 0x00c0, 0x49aa, 0x7008,
- 0xa084, 0x01e0, 0x00c0, 0x49aa, 0x7310, 0x7014, 0xa305, 0x0040,
- 0x49aa, 0x710c, 0xa184, 0x0300, 0x00c0, 0x49aa, 0xa184, 0x00ff,
- 0x00c0, 0x4957, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084,
- 0x0008, 0x00c0, 0x49ae, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048,
- 0x49b3, 0x7003, 0x0000, 0x2049, 0x0000, 0x007c, 0x107e, 0x007e,
- 0x127e, 0x157e, 0x2091, 0x2200, 0x7108, 0x1078, 0x49ce, 0x157f,
- 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7204, 0x7500,
- 0x730c, 0xa384, 0x0300, 0x00c0, 0x49f5, 0xa184, 0x01e0, 0x00c0,
- 0x4a19, 0x7108, 0xa184, 0x01e0, 0x00c0, 0x4a19, 0x2001, 0x04fd,
- 0x2004, 0xa082, 0x0005, 0x00c8, 0x49e9, 0xa184, 0x4000, 0x00c0,
- 0x49d9, 0xa184, 0x0007, 0x0079, 0x49ed, 0x49f7, 0x4a09, 0x49f5,
- 0x4a09, 0x49f5, 0x4a55, 0x49f5, 0x4a53, 0x1078, 0x248c, 0x7004,
- 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff, 0x00c0, 0x4a04,
- 0x2049, 0x0000, 0x0078, 0x4a08, 0x1078, 0x4c18, 0x00c0, 0x4a04,
- 0x007c, 0x7004, 0xa084, 0x0010, 0xa085, 0x0002, 0x7006, 0x8aff,
- 0x00c0, 0x4a14, 0x0078, 0x4a18, 0x1078, 0x4c18, 0x00c0, 0x4a14,
- 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0, 0x4a1c, 0x2091, 0x6000,
- 0x00e0, 0x4a20, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008,
- 0x7004, 0xa084, 0x0008, 0x00c0, 0x4a28, 0x7007, 0x0012, 0x7108,
- 0x8103, 0x0048, 0x4a2d, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0,
- 0x4a41, 0x7004, 0xa005, 0x00c0, 0x4a41, 0x700c, 0xa005, 0x0040,
- 0x4a43, 0x0078, 0x4a24, 0x2049, 0x0000, 0x1078, 0x38d7, 0x6818,
- 0xa084, 0x8000, 0x0040, 0x4a4e, 0x681b, 0x0002, 0x007c, 0x1078,
- 0x248c, 0x1078, 0x248c, 0x1078, 0x4ab1, 0x7210, 0x7114, 0x700c,
- 0xa09c, 0x00ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078,
- 0x4ab1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c,
- 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4a78, 0x00c8, 0x4a78,
- 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x4a5f,
- 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4a84,
- 0xa7ba, 0x4917, 0x0078, 0x4a86, 0xa7ba, 0x490f, 0x007f, 0xa73d,
- 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078,
- 0x4957, 0x007c, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4aa5, 0x609c,
- 0xa005, 0x0040, 0x4aae, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080,
- 0x491d, 0x203c, 0x87fb, 0x1040, 0x248c, 0x8a51, 0x0040, 0x4aad,
- 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c, 0x2051, 0x0000,
- 0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x4ac5, 0x6000,
- 0xa064, 0x00c0, 0x4abc, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080,
- 0x492d, 0x203c, 0x87fb, 0x1040, 0x248c, 0x007c, 0x127e, 0x0d7e,
- 0x2091, 0x2200, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90,
- 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084,
- 0x0008, 0x007f, 0x0040, 0x4ae0, 0xa0b8, 0x4917, 0x0078, 0x4ae2,
- 0xa0b8, 0x490f, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff,
- 0xa186, 0x0007, 0x0040, 0x4af0, 0xa18e, 0x000f, 0x00c0, 0x4af9,
- 0x681c, 0xa084, 0x0040, 0x0040, 0x4b00, 0xa6b5, 0x0001, 0x0078,
- 0x4b00, 0x681c, 0xa084, 0x0040, 0x0040, 0x4b00, 0xa6b5, 0x0001,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b02, 0x2400,
- 0xa305, 0x00c0, 0x4b0d, 0x0078, 0x4b33, 0x2c58, 0x2704, 0x6104,
- 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184,
- 0x0008, 0x0040, 0x4b23, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014,
- 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c,
- 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078,
- 0x4a92, 0x0078, 0x4b35, 0x1078, 0x4c18, 0x00c0, 0x4b33, 0x127f,
- 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007,
- 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4b41, 0x7003, 0x0008,
- 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f,
- 0x2049, 0x4b4b, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
- 0x4b54, 0x7e08, 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186,
- 0x0007, 0x0040, 0x4b67, 0xa18e, 0x000f, 0x00c0, 0x4b72, 0x681c,
- 0xa084, 0x0040, 0x0040, 0x4b6e, 0xa6b5, 0x0001, 0x6840, 0x2050,
- 0x0078, 0x4b7b, 0x681c, 0xa084, 0x0020, 0x00c0, 0x4b79, 0xa6b5,
- 0x0001, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8,
- 0x491d, 0x273c, 0x87fb, 0x00c0, 0x4b8f, 0x0048, 0x4b89, 0x1078,
- 0x248c, 0x689c, 0xa065, 0x0040, 0x4b93, 0x0078, 0x4b7c, 0x1078,
- 0x4c18, 0x00c0, 0x4b8f, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e,
- 0x017e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08,
- 0xa6b5, 0x000c, 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040,
- 0x4bad, 0xa18e, 0x000f, 0x00c0, 0x4bb6, 0x681c, 0xa084, 0x0040,
- 0x0040, 0x4bbd, 0xa6b5, 0x0001, 0x0078, 0x4bbd, 0x681c, 0xa084,
- 0x0040, 0x0040, 0x4bbd, 0xa6b5, 0x0001, 0x2049, 0x4b96, 0x017e,
- 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4bcb, 0xa18e,
- 0x000f, 0x00c0, 0x4bce, 0x6840, 0x0078, 0x4bcf, 0x6828, 0x017f,
- 0xa055, 0x0040, 0x4c15, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f,
- 0xa7b8, 0x491d, 0x273c, 0x87fb, 0x00c0, 0x4be9, 0x0048, 0x4be2,
- 0x1078, 0x248c, 0x709c, 0xa075, 0x2060, 0x0040, 0x4c15, 0x0078,
- 0x4bd5, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048,
- 0x4c02, 0x8a51, 0x00c0, 0x4bf6, 0x1078, 0x248c, 0x8738, 0x2704,
- 0xa005, 0x00c0, 0x4bea, 0x709c, 0xa075, 0x2060, 0x0040, 0x4c15,
- 0x0078, 0x4bd5, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908,
- 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4c11, 0x1078,
- 0x248c, 0x2071, 0x0020, 0x0078, 0x4b00, 0x127f, 0x2000, 0x007c,
- 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x0040, 0x4c40, 0x2704,
- 0xac08, 0x2104, 0x701a, 0x8108, 0x2104, 0x701e, 0x8108, 0x2104,
- 0x7012, 0x8108, 0x2104, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040,
- 0x4c37, 0x8108, 0x2104, 0x7022, 0x8108, 0x2104, 0x7026, 0x7602,
- 0x7004, 0xa084, 0x0010, 0xa085, 0x0001, 0x7006, 0x1078, 0x4a92,
- 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x2049, 0x4c41,
- 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003, 0x00c0, 0x4c6b, 0x017e,
- 0x6904, 0xa18c, 0x00ff, 0xa186, 0x0007, 0x0040, 0x4c5b, 0xa18e,
- 0x000f, 0x00c0, 0x4c5e, 0x6840, 0x0078, 0x4c5f, 0x6828, 0x017f,
- 0xa005, 0x0040, 0x4c79, 0x0078, 0x489e, 0x0020, 0x4c6b, 0x1078,
- 0x4a55, 0x0078, 0x4c79, 0x00a0, 0x4c72, 0x7108, 0x1078, 0x49ce,
- 0x0078, 0x4c4a, 0x7007, 0x0010, 0x00a0, 0x4c74, 0x7108, 0x1078,
- 0x49ce, 0x7008, 0xa086, 0x0008, 0x00c0, 0x4c4a, 0x7000, 0xa005,
- 0x00c0, 0x4c4a, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000,
- 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x2091,
- 0x2200, 0x0d7f, 0x2049, 0x4c89, 0xad80, 0x0011, 0x20a0, 0x2099,
- 0x0031, 0x700c, 0xa084, 0x00ff, 0x682a, 0x7007, 0x0008, 0x7007,
- 0x0002, 0x7003, 0x0001, 0x0040, 0x4ca8, 0x8000, 0x80ac, 0x53a5,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4caa, 0x0c7f,
- 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f,
- 0x2000, 0x007c, 0x2091, 0x6000, 0x2091, 0x8000, 0x78cc, 0xa005,
- 0x0040, 0x4cd1, 0x7994, 0x70d0, 0xa106, 0x00c0, 0x4cd1, 0x7804,
- 0xa005, 0x0040, 0x4cd1, 0x7807, 0x0000, 0x0068, 0x4cd1, 0x2091,
- 0x4080, 0x7820, 0x8001, 0x7822, 0x00c0, 0x4d2c, 0x7824, 0x7822,
- 0x2069, 0x5240, 0x6800, 0xa084, 0x0007, 0x0040, 0x4cef, 0xa086,
- 0x0002, 0x0040, 0x4cef, 0x6834, 0xa00d, 0x0040, 0x4cef, 0x2104,
- 0xa005, 0x0040, 0x4cef, 0x8001, 0x200a, 0x0040, 0x4dd4, 0x7848,
- 0xa005, 0x0040, 0x4cfd, 0x8001, 0x784a, 0x00c0, 0x4cfd, 0x2009,
- 0x0102, 0x6844, 0x200a, 0x1078, 0x226f, 0x6890, 0xa005, 0x0040,
- 0x4d09, 0x8001, 0x6892, 0x00c0, 0x4d09, 0x686f, 0x0000, 0x6873,
- 0x0001, 0x2061, 0x5500, 0x20a9, 0x0100, 0x2009, 0x0002, 0x6034,
- 0xa005, 0x0040, 0x4d1f, 0x8001, 0x6036, 0x00c0, 0x4d1f, 0x6010,
- 0xa005, 0x0040, 0x4d1f, 0x017e, 0x1078, 0x226f, 0x017f, 0xace0,
- 0x0010, 0x0070, 0x4d25, 0x0078, 0x4d0f, 0x8109, 0x0040, 0x4d2c,
- 0x20a9, 0x0100, 0x0078, 0x4d0f, 0x1078, 0x4d39, 0x1078, 0x4d5e,
- 0x2009, 0x5251, 0x2104, 0x2009, 0x0102, 0x200a, 0x2091, 0x8001,
- 0x007c, 0x7834, 0x8001, 0x7836, 0x00c0, 0x4d5d, 0x7838, 0x7836,
- 0x2091, 0x8000, 0x7844, 0xa005, 0x00c0, 0x4d48, 0x2001, 0x0101,
- 0x8001, 0x7846, 0xa080, 0x7500, 0x2040, 0x2004, 0xa065, 0x0040,
- 0x4d5d, 0x6024, 0xa005, 0x0040, 0x4d59, 0x8001, 0x6026, 0x0040,
- 0x4d8d, 0x6000, 0x2c40, 0x0078, 0x4d4e, 0x007c, 0x7828, 0x8001,
- 0x782a, 0x00c0, 0x4d8c, 0x782c, 0x782a, 0x7830, 0xa005, 0x00c0,
- 0x4d6b, 0x2001, 0x0200, 0x8001, 0x7832, 0x8003, 0x8003, 0x8003,
- 0x8003, 0xa090, 0x5500, 0xa298, 0x0002, 0x2304, 0xa084, 0x0008,
- 0x0040, 0x4d8c, 0xa290, 0x0009, 0x2204, 0xa005, 0x0040, 0x4d84,
- 0x8001, 0x2012, 0x00c0, 0x4d8c, 0x2304, 0xa084, 0xfff7, 0xa085,
- 0x0080, 0x201a, 0x1078, 0x226f, 0x007c, 0x2069, 0x5240, 0x6800,
- 0xa005, 0x0040, 0x4d97, 0x6848, 0xac06, 0x0040, 0x4dd4, 0x601b,
- 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
- 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f82, 0x1078,
- 0x19c5, 0x6818, 0xa005, 0x0040, 0x4daf, 0x8001, 0x681a, 0x6808,
- 0xa084, 0xffef, 0x680a, 0x6810, 0x8001, 0x00d0, 0x4db9, 0x1078,
- 0x248c, 0x6812, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078,
- 0x1cdc, 0x2069, 0x5240, 0x7944, 0xa184, 0x0100, 0x2001, 0x0006,
- 0x686e, 0x00c0, 0x4dcf, 0x6986, 0x2001, 0x0004, 0x686e, 0x1078,
- 0x226a, 0x2091, 0x8001, 0x007c, 0x2069, 0x0100, 0x2009, 0x5240,
- 0x2104, 0xa084, 0x0007, 0x0040, 0x4e30, 0xa086, 0x0007, 0x00c0,
- 0x4dea, 0x0d7e, 0x2009, 0x5252, 0x216c, 0x1078, 0x3b1c, 0x0d7f,
- 0x0078, 0x4e30, 0x2009, 0x5252, 0x2164, 0x1078, 0x2437, 0x601b,
- 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
- 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830,
- 0xa084, 0x0040, 0x0040, 0x4e24, 0x684b, 0x0004, 0x20a9, 0x0014,
- 0x6848, 0xa084, 0x0004, 0x0040, 0x4e11, 0x0070, 0x4e11, 0x0078,
- 0x4e08, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001,
- 0x0040, 0x4e1e, 0x0070, 0x4e1e, 0x0078, 0x4e15, 0x20a9, 0x00fa,
- 0x0070, 0x4e24, 0x0078, 0x4e20, 0x6808, 0xa084, 0xfffd, 0x680a,
- 0x681b, 0x0048, 0x2009, 0x525b, 0x200b, 0x0007, 0x784c, 0x784a,
- 0x2091, 0x8001, 0x007c, 0x2079, 0x5200, 0x1078, 0x4e5e, 0x1078,
- 0x4e42, 0x1078, 0x4e50, 0x7833, 0x0000, 0x7847, 0x0000, 0x784b,
- 0x0000, 0x007c, 0x2019, 0x0003, 0x2011, 0x5246, 0x2204, 0xa086,
- 0x003c, 0x0040, 0x4e4d, 0x2019, 0x0002, 0x7b2a, 0x7b2e, 0x007c,
- 0x2019, 0x0039, 0x2011, 0x5246, 0x2204, 0xa086, 0x003c, 0x0040,
- 0x4e5b, 0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x3971,
- 0x2011, 0x5246, 0x2204, 0xa086, 0x003c, 0x0040, 0x4e69, 0x2019,
- 0x2626, 0x7b22, 0x7b26, 0x783f, 0x0000, 0x7843, 0x000a, 0x007c,
- 0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014,
- 0x0014, 0x0014, 0x0014, 0x0014, 0x0014, 0x0080, 0x000f, 0x0000,
- 0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b,
- 0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0x0000, 0x006c,
- 0x0002, 0x0014, 0x98cd, 0x009e, 0x0093, 0xa202, 0x8838, 0x3806,
- 0x8839, 0x20c3, 0x0864, 0x9885, 0x28c1, 0x9cae, 0xa203, 0x300c,
- 0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0x9865, 0x28f2,
- 0x9c91, 0x9858, 0x300c, 0x28e1, 0x9c91, 0x2802, 0xa206, 0x64c3,
- 0x282e, 0xa207, 0x64a0, 0x6de0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
- 0x7824, 0x68c1, 0x7864, 0x883e, 0x9879, 0x8576, 0x8677, 0x206b,
- 0x28c1, 0x9cae, 0x2044, 0x2103, 0x20a2, 0x2081, 0x9865, 0xa209,
- 0x2901, 0x988d, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a, 0x883c,
- 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c91, 0x0014, 0xa204,
- 0xa300, 0x3009, 0x19e2, 0xf864, 0x856e, 0x883f, 0x08e6, 0x9891,
- 0xf881, 0x988c, 0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2, 0x80f0,
- 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014, 0x1de2,
- 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008, 0x1dc1,
- 0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008, 0x84a8, 0x11d6,
- 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x8000, 0x2847,
- 0x1011, 0x98c0, 0x8000, 0xa000, 0x2802, 0x1011, 0x98c6, 0x9865,
- 0x283e, 0x1011, 0x98ca, 0xa20b, 0x0017, 0x300c, 0xa300, 0x1de2,
- 0xdb81, 0x0014, 0x0210, 0x98d7, 0x0014, 0x26e0, 0x873a, 0xfb02,
- 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9cb3, 0x0704,
- 0x0000, 0x006c, 0x0002, 0x984f, 0x0014, 0x009e, 0x00a0, 0x0017,
- 0x60ff, 0x300c, 0x8720, 0xa211, 0x9cd0, 0x8772, 0x8837, 0x2101,
- 0x987a, 0x10d2, 0x78e2, 0x9cd3, 0x9859, 0xd984, 0xf0e2, 0xf0a1,
- 0x98cd, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f, 0x9401, 0xb520,
- 0xc802, 0x8820, 0x987a, 0x2301, 0x987a, 0x10d2, 0x78e4, 0x9cd3,
- 0x8821, 0x8820, 0x9859, 0xf123, 0xf142, 0xf101, 0x98c6, 0x10d2,
- 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001, 0x0014, 0x6845,
- 0x0214, 0xa21b, 0x9cd0, 0x2001, 0x98c5, 0x8201, 0x1852, 0xd184,
- 0xd163, 0x8834, 0x8001, 0x988d, 0x3027, 0x84a8, 0x1a56, 0x8833,
- 0x0014, 0xa218, 0x6981, 0x9cbc, 0x6926, 0x6902, 0x1a34, 0x9899,
- 0x1a14, 0x7021, 0x0014, 0xa300, 0x6141, 0x6964, 0x8010, 0x8592,
- 0x8026, 0x84b9, 0x69e4, 0x8023, 0x16e1, 0x8001, 0x10f1, 0x6946,
- 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0x98b5, 0x6969, 0xa214,
- 0x61c2, 0x8002, 0x14e1, 0x8004, 0x16e1, 0x0101, 0x300a, 0x8827,
- 0x0014, 0xa217, 0x9cbc, 0x0014, 0xa300, 0x8181, 0x842a, 0x84a8,
- 0x1ce6, 0x882c, 0x0016, 0xa212, 0x9cd0, 0x10d2, 0x70e4, 0x0004,
- 0x8007, 0x9424, 0xcc1a, 0x9cd3, 0x98c5, 0x8827, 0x300a, 0x0013,
- 0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e, 0xa21d, 0x0014,
- 0x878e, 0x0016, 0xa21c, 0x1035, 0x9891, 0xa210, 0xa000, 0x8010,
- 0x8592, 0x853b, 0xd044, 0x8022, 0x3807, 0x84bb, 0x98ea, 0x8021,
- 0x3807, 0x84b9, 0x300c, 0x817e, 0x872b, 0x8772, 0x9891, 0x0000,
- 0x0020, 0x002b, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0014, 0x0014, 0x9849, 0x0014, 0x0014,
- 0x98e2, 0x98cd, 0x0014, 0x0014, 0x0014, 0x0080, 0x0137, 0x0000,
- 0x0201, 0x0604, 0x0c08, 0x2120, 0x4022, 0xf880, 0x0018, 0x300b,
- 0xa201, 0x0014, 0xa200, 0x0014, 0xa200, 0x0214, 0xa202, 0x8838,
- 0x3806, 0x8839, 0x20c3, 0x0864, 0xa82f, 0x28c1, 0x9cae, 0xa203,
- 0x300c, 0x2846, 0x8161, 0x846a, 0x8300, 0x1856, 0x883a, 0xa804,
- 0x28f2, 0x9c91, 0xa8f4, 0x300c, 0x28e1, 0x9c91, 0x2802, 0xa206,
- 0x64c3, 0x282e, 0xa207, 0x64a0, 0x6de0, 0x67a0, 0x6fc0, 0x1814,
- 0x883b, 0x7824, 0x68c1, 0x7864, 0x883e, 0xa802, 0x8576, 0x8677,
- 0x206b, 0x28c1, 0x9cae, 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8e4,
- 0xa209, 0x2901, 0xa809, 0x0014, 0xa205, 0xa300, 0x1872, 0x879a,
- 0x883c, 0x1fe2, 0xc601, 0xa20a, 0x856e, 0x0704, 0x9c91, 0x0014,
- 0xa204, 0xa300, 0x3009, 0x19e2, 0xf864, 0x856e, 0x883f, 0x08e6,
- 0xa8f7, 0xf881, 0xa8f0, 0xc801, 0x0014, 0xf8c1, 0x0016, 0x85b2,
- 0x80f0, 0x9532, 0xfb02, 0x1de2, 0x0014, 0x8532, 0xf241, 0x0014,
- 0x1de2, 0x84a8, 0xd7a0, 0x1fe6, 0x0014, 0xa208, 0x6043, 0x8008,
- 0x1dc1, 0x0016, 0x8300, 0x8160, 0x842a, 0xf041, 0x3008, 0x84a8,
- 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x8000,
- 0x2847, 0x1011, 0xa8fc, 0x8000, 0xa000, 0x2802, 0x1011, 0xa8fd,
- 0xa89b, 0x283e, 0x1011, 0xa8fd, 0xa20b, 0x0017, 0x300c, 0xa300,
- 0x1de2, 0xdb81, 0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a,
- 0xfb02, 0x19f2, 0x1fe2, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9cb3,
- 0x0704, 0x0017, 0x60ff, 0x300c, 0x8720, 0xa211, 0x9d63, 0x8772,
- 0x8837, 0x2101, 0xa821, 0x10d2, 0x78e2, 0x9d66, 0xa8fc, 0xd984,
- 0xf0e2, 0xf0a1, 0xa86c, 0x0014, 0x8831, 0xd166, 0x8830, 0x800f,
- 0x9401, 0xb520, 0xc802, 0x8820, 0xa80f, 0x2301, 0xa80d, 0x10d2,
- 0x78e4, 0x9d66, 0x8821, 0x8820, 0xa8e6, 0xf123, 0xf142, 0xf101,
- 0xa84f, 0x10d2, 0x70f6, 0x8832, 0x8203, 0x870c, 0xd99e, 0x6001,
- 0x0014, 0x6845, 0x0214, 0xa21b, 0x9d63, 0x2001, 0xa840, 0x8201,
- 0x1852, 0xd184, 0xd163, 0x8834, 0x8001, 0xa801, 0x3027, 0x84a8,
- 0x1a56, 0x8833, 0x0014, 0xa218, 0x6981, 0x9d4f, 0x6926, 0x6902,
- 0x1a34, 0xa801, 0x1a14, 0x7021, 0x0014, 0xa300, 0x6141, 0x6964,
- 0x8010, 0x8592, 0x8026, 0x84b9, 0x69e4, 0x8023, 0x16e1, 0x8001,
- 0x10f1, 0x6946, 0xa213, 0x1462, 0xa213, 0x8000, 0x16e1, 0xa807,
- 0x6969, 0xa214, 0x61c2, 0x8002, 0x14e1, 0x8004, 0x16e1, 0x0101,
- 0x300a, 0x8827, 0x0014, 0xa217, 0x9d4f, 0x0014, 0xa300, 0x8181,
- 0x842a, 0x84a8, 0x1ce6, 0x882c, 0x0016, 0xa212, 0x9d63, 0x10d2,
- 0x70e4, 0x0004, 0x8007, 0x9424, 0xcc1a, 0x9d66, 0xa8f8, 0x8827,
- 0x300a, 0x0013, 0x8000, 0x84a4, 0x0016, 0x11c2, 0x211e, 0x870e,
- 0xa21d, 0x0014, 0x878e, 0x0016, 0xa21c, 0x1035, 0xa8b4, 0xa210,
- 0x3807, 0x300c, 0x817e, 0x872b, 0x8772, 0xa8ad, 0x0000, 0x0d0c
-};
-static unsigned short risc_code_length01 = 0x4158;
diff --git a/drivers/scsi/ql12160_fw.h b/drivers/scsi/ql12160_fw.h
deleted file mode 100644
index d89dac0cc9d..00000000000
--- a/drivers/scsi/ql12160_fw.h
+++ /dev/null
@@ -1,1811 +0,0 @@
-/*****************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP12160 device driver for Linux 2.2.x and 2.4.x
- * Copyright (C) 2002 Qlogic Corporation (www.qlogic.com)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- *****************************************************************************/
-
-/************************************************************************
- * --- ISP12160A Initiator Firmware --- *
- * 32 LUN Support *
- ************************************************************************/
-
-/*
- * Firmware Version 10.04.42 (15:44 Apr 18, 2003)
- */
-
-#ifdef UNIQUE_FW_NAME
-static unsigned char fw12160i_version_str[] = {10,4,42};
-#else
-static unsigned char firmware_version[] = {10,4,42};
-#endif
-
-#ifdef UNIQUE_FW_NAME
-#define fw12160i_VERSION_STRING "10.04.42"
-#else
-#define FW_VERSION_STRING "10.04.42"
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw12160i_addr01 = 0x1000;
-#else
-static unsigned short risc_code_addr01 = 0x1000;
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw12160i_code01[] = {
-#else
-static unsigned short risc_code01[] = {
-#endif
- 0x0804, 0x1041, 0x0000, 0x36c9, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
- 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
- 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
- 0x3132, 0x3136, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
- 0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3034, 0x2020, 0x2043,
- 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
- 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
- 0x2400, 0x20c9, 0x90ff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001,
- 0x01ff, 0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2,
- 0x20c1, 0x0020, 0x2089, 0x1221, 0x2071, 0x0010, 0x70c3, 0x0004,
- 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000a,
- 0x2001, 0x04fd, 0x2004, 0x70d6, 0x2009, 0xfeff, 0x2130, 0x2128,
- 0xa1a2, 0x4700, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
- 0xa192, 0x9100, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1e05,
- 0x2218, 0x2079, 0x4700, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
- 0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2009, 0xff00, 0x3400, 0xa102,
- 0x0218, 0x0110, 0x20a8, 0x42a4, 0x781b, 0x0064, 0x7814, 0xc0cd,
- 0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4740, 0x080c,
- 0x465c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4780,
- 0x2071, 0x0100, 0x080c, 0x465c, 0x7814, 0xc0d4, 0x7816, 0x00de,
- 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802,
- 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002,
- 0x2009, 0x0002, 0x2069, 0x4740, 0x681b, 0x0003, 0x6823, 0x0007,
- 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0006,
- 0x6833, 0x0008, 0x683b, 0x0000, 0x8109, 0x0500, 0x68cf, 0x000a,
- 0x68bf, 0x47c0, 0x2079, 0x4700, 0x68d3, 0x762d, 0x68c3, 0x4cc0,
- 0x68c7, 0x4bc0, 0x68cb, 0x8cc0, 0x68a7, 0x8f44, 0x68ab, 0x8f49,
- 0x68af, 0x8f44, 0x68b3, 0x8f44, 0x68a3, 0x0001, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4780, 0x0870, 0x68cf, 0x000a,
- 0x68bf, 0x49c0, 0x68d3, 0x7839, 0x68c3, 0x6cc0, 0x68c7, 0x4c40,
- 0x68cb, 0x8dd0, 0x68a7, 0x8f49, 0x68ab, 0x8f4e, 0x68af, 0x8f49,
- 0x68b3, 0x8f49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x4bc0, 0x2071,
- 0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120,
- 0x2019, 0x180c, 0x2021, 0x000c, 0x080c, 0x1d75, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x1188, 0x2069, 0x4c40, 0x2071, 0x0100, 0x70ec,
- 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120, 0x2019, 0x180c,
- 0x2021, 0x000c, 0x080c, 0x1d75, 0x00ee, 0x2011, 0x0002, 0x2069,
- 0x4cc0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b,
- 0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, 0x0100, 0x681f,
- 0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
- 0x1f04, 0x1135, 0x8109, 0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc,
- 0x1128, 0x8211, 0x0118, 0x2069, 0x6cc0, 0x08d8, 0x080c, 0x22f6,
- 0x080c, 0x403d, 0x080c, 0x1b8c, 0x080c, 0x4615, 0x2091, 0x2200,
- 0x2079, 0x4700, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4700,
- 0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4740,
- 0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4780, 0x2091, 0x2000,
- 0x2079, 0x4700, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
- 0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118c, 0x70c0, 0xa086,
- 0x0002, 0x1110, 0x080c, 0x13ba, 0x2039, 0x0000, 0x080c, 0x12ab,
- 0x78ac, 0xa005, 0x1180, 0x0e04, 0x119a, 0x786c, 0xa065, 0x0110,
- 0x080c, 0x20a1, 0x080c, 0x1e26, 0x0e04, 0x11af, 0x786c, 0xa065,
- 0x0110, 0x080c, 0x20a1, 0x0e04, 0x11af, 0x2009, 0x4747, 0x2011,
- 0x4787, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c9b, 0x2071,
- 0x4740, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8,
- 0x2079, 0x0200, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, 0x2190,
- 0x080c, 0x274c, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1,
- 0x2079, 0x4700, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c,
- 0x20a1, 0x1d04, 0x11d9, 0x2079, 0x4700, 0x2071, 0x0010, 0x080c,
- 0x4429, 0x2071, 0x4780, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025,
- 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d,
- 0x2190, 0x080c, 0x274c, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079,
- 0x4700, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110,
- 0x080c, 0x20a1, 0x1d04, 0x118e, 0x080c, 0x4429, 0x0804, 0x118e,
- 0x3c00, 0xa084, 0x0007, 0x0002, 0x120c, 0x120c, 0x120e, 0x120e,
- 0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x2575, 0x2091, 0x2400,
- 0x080c, 0x40d5, 0x0005, 0x2091, 0x2200, 0x080c, 0x40d5, 0x0005,
- 0x2091, 0x2200, 0x080c, 0x40d5, 0x2091, 0x2400, 0x080c, 0x40d5,
- 0x0005, 0x1241, 0x1241, 0x1242, 0x1242, 0x124d, 0x124d, 0x124d,
- 0x124d, 0x1256, 0x1256, 0x1261, 0x1261, 0x124d, 0x124d, 0x124d,
- 0x124d, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
- 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
- 0x1270, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c,
- 0x2592, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126,
- 0x080c, 0x1200, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106,
- 0x0126, 0x2091, 0x2600, 0x080c, 0x2592, 0x012e, 0x010e, 0x000e,
- 0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2592,
- 0x2091, 0x2800, 0x080c, 0x2592, 0x012e, 0x010e, 0x000e, 0x000d,
- 0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4700,
- 0x2071, 0x0200, 0x2069, 0x4740, 0x3d00, 0xd08c, 0x0130, 0x70ec,
- 0xa084, 0x1c00, 0x78e2, 0x080c, 0x465c, 0x3d00, 0xd084, 0x0150,
- 0x2069, 0x4780, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6,
- 0x080c, 0x465c, 0x080c, 0x2526, 0x00fe, 0x00ee, 0x00de, 0x012e,
- 0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, 0x0002,
- 0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, 0x70c3,
- 0x4002, 0x0804, 0x13bd, 0x0e04, 0x131e, 0x2061, 0x0000, 0x6018,
- 0xd084, 0x1904, 0x131e, 0x7828, 0xa005, 0x1120, 0x0004, 0x131f,
- 0x0804, 0x131e, 0xd0fc, 0x0130, 0x0006, 0x080c, 0x1b29, 0x000e,
- 0x0150, 0x0028, 0x0006, 0x080c, 0x1b1e, 0x000e, 0x0120, 0x2001,
- 0x4007, 0x0804, 0x13bc, 0x7910, 0xd0fc, 0x1128, 0x2061, 0x4740,
- 0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4780, 0xc19d, 0xc7fd, 0x6060,
- 0xa005, 0x1904, 0x131e, 0x7912, 0x607e, 0x7828, 0xc0fc, 0xa086,
- 0x0018, 0x1120, 0x00c6, 0x080c, 0x1926, 0x00ce, 0x782b, 0x0000,
- 0x6078, 0xa065, 0x01e0, 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce,
- 0x609f, 0x0000, 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087, 0x0103,
- 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
- 0x080c, 0x1b34, 0x000e, 0x7812, 0x1198, 0x080c, 0x1b7f, 0x7810,
- 0xd09c, 0x1118, 0x2061, 0x4740, 0x0020, 0x2061, 0x4780, 0xc09c,
- 0x7812, 0x607b, 0x0000, 0x60d0, 0xd0c4, 0x0130, 0xc0c4, 0x60d2,
- 0x2001, 0x4005, 0x0804, 0x13bc, 0x0804, 0x13ba, 0x0005, 0xa006,
- 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a,
- 0x0040, 0x1a04, 0x136c, 0x0002, 0x13ba, 0x1408, 0x13d6, 0x143c,
- 0x1470, 0x1470, 0x13ce, 0x1a78, 0x147a, 0x13c8, 0x13da, 0x13db,
- 0x13dc, 0x13dd, 0x1a7c, 0x13c8, 0x1487, 0x14db, 0x1941, 0x1a72,
- 0x13de, 0x17c8, 0x17fe, 0x1830, 0x1876, 0x1785, 0x1792, 0x17a5,
- 0x17b7, 0x15bf, 0x13c8, 0x150d, 0x1518, 0x1526, 0x1534, 0x154b,
- 0x1559, 0x155c, 0x156e, 0x157c, 0x1586, 0x15a5, 0x15b1, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x15cc, 0x15dd, 0x15f7, 0x162b, 0x1654,
- 0x1666, 0x1669, 0x1693, 0x16cc, 0x16de, 0x1753, 0x1763, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x1775, 0x2100, 0xa08a, 0x0040, 0x1a04,
- 0x13c8, 0x0002, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x1a9e,
- 0x1aa4, 0x13c8, 0x13c8, 0x13c8, 0x1aa8, 0x1ae8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x1403, 0x146b, 0x1482, 0x14d6, 0x193c, 0x13c8,
- 0x13c8, 0x190b, 0x13c8, 0x1aec, 0x1a90, 0x1a9a, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
- 0x13c8, 0x13c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, 0x73ce,
- 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13bd, 0x2061,
- 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x0005,
- 0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099, 0x0041,
- 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4, 0x70c3,
- 0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091, 0x8000,
- 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020,
- 0x70d3, 0x000a, 0x2001, 0x0004, 0x70d6, 0x2079, 0x0000, 0x781b,
- 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051,
- 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091,
- 0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018,
- 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0,
- 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e,
- 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13ba, 0xa182,
- 0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007,
- 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002,
- 0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13bd, 0x24a8,
- 0x53a5, 0x0c10, 0x0804, 0x13ba, 0x2029, 0x0000, 0x2520, 0x71d0,
- 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000,
- 0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040,
- 0x7007, 0x0006, 0x81ff, 0x0904, 0x13ba, 0xa182, 0x0040, 0x1210,
- 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007,
- 0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, 0x70c3,
- 0x4002, 0x0804, 0x13bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0878,
- 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, 0x72ca,
- 0x0804, 0x13b9, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, 0x002a,
- 0x0804, 0x13ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029,
- 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca,
- 0x73ce, 0x74d2, 0xa005, 0x05e8, 0xa40a, 0x0108, 0x1240, 0x8001,
- 0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, 0x78ae, 0x2001,
- 0x4005, 0x0804, 0x13bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76,
- 0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c,
- 0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000,
- 0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1,
- 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605,
- 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae,
- 0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13ba, 0x75d8, 0x76dc,
- 0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8,
- 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0500,
- 0xa40a, 0x0110, 0x1a04, 0x13bc, 0x8001, 0x7892, 0xa084, 0xfc00,
- 0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0804, 0x13bc,
- 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0118, 0x7a10,
- 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0018,
- 0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13ba, 0x2009, 0x0000, 0x786c,
- 0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, 0x0804, 0x13b8,
- 0x2009, 0x4748, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
- 0x13b9, 0x2011, 0x4788, 0x2214, 0x0804, 0x13b8, 0x2009, 0x4749,
- 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
- 0x4789, 0x2214, 0x0804, 0x13b8, 0x2061, 0x4740, 0x6128, 0x622c,
- 0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1148,
- 0x2061, 0x4780, 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c,
- 0x73de, 0x0804, 0x13b8, 0x2009, 0x474c, 0x210c, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x478c, 0x2214, 0x0804,
- 0x13b8, 0x7918, 0x0804, 0x13b9, 0x2009, 0x0202, 0x210c, 0xa18c,
- 0x0f30, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
- 0x0102, 0x2214, 0xa294, 0x0f30, 0x0804, 0x13b8, 0x2009, 0x474d,
- 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
- 0x478d, 0x2214, 0x0804, 0x13b8, 0x7920, 0x2001, 0x01ff, 0x2004,
- 0xd0fc, 0x1904, 0x13b9, 0x7a24, 0x0804, 0x13b8, 0x2011, 0x4c40,
- 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4bc0, 0x8107, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da,
- 0xd1fc, 0x1118, 0x2021, 0x023b, 0x0010, 0x2021, 0x013b, 0x2424,
- 0xa4a4, 0x1c00, 0x74de, 0x0804, 0x13b7, 0x77c4, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0804,
- 0x13b7, 0x2061, 0x4740, 0x6118, 0x2001, 0x01ff, 0x2004, 0xd0fc,
- 0x1904, 0x13b9, 0x2061, 0x4780, 0x6218, 0x0804, 0x13b8, 0x77c4,
- 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da,
- 0x2091, 0x8001, 0x0804, 0x13b7, 0x71c4, 0x2110, 0xa294, 0x000f,
- 0xa282, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23b4, 0xa384, 0x4000,
- 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x71c4, 0x2100, 0xc0bc,
- 0xa082, 0x0010, 0x1a04, 0x13b3, 0xd1bc, 0x1120, 0x2011, 0x4748,
- 0x2204, 0x0020, 0x2011, 0x4788, 0x2204, 0xc0bd, 0x0006, 0x2100,
- 0xc0bc, 0x2012, 0x080c, 0x2358, 0x001e, 0x0804, 0x13b9, 0x71c4,
- 0x2021, 0x4749, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0030, 0x71c8,
- 0x2021, 0x4789, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1623, 0x20a9,
- 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, 0x1f04, 0x1609, 0x71c4,
- 0x72c8, 0x0804, 0x13b2, 0xa292, 0x1623, 0x0026, 0x2122, 0x001e,
- 0x080c, 0x236a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1110, 0xd3fc,
- 0x09f0, 0x0804, 0x13ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0004,
- 0x0001, 0x0002, 0x0003, 0x2061, 0x4740, 0x6128, 0x622c, 0x8214,
- 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003, 0x8003,
- 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0, 0x0026, 0x0016,
- 0x2061, 0x4780, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
- 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
- 0x001e, 0x002e, 0x0804, 0x13b8, 0x2061, 0x4740, 0x6130, 0x70c4,
- 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2061,
- 0x4780, 0x6230, 0x70c8, 0x6032, 0x0804, 0x13b8, 0x7918, 0x0804,
- 0x13b9, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001, 0x01ff, 0x2004,
- 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2, 0x2019, 0x0000,
- 0x080c, 0x23a6, 0x0036, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118,
- 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa184, 0xf0cf, 0x0128, 0x000e,
- 0x2110, 0x71c4, 0x0804, 0x13b2, 0xc3fd, 0x080c, 0x23a6, 0x2310,
- 0x001e, 0x0804, 0x13b8, 0x71c4, 0xa182, 0x0010, 0x0248, 0x2001,
- 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2,
- 0x2011, 0x474d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112,
- 0x2019, 0x0000, 0x080c, 0x2393, 0x2001, 0x01ff, 0x2004, 0xd0fc,
- 0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa182, 0x0010, 0x0228,
- 0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x2011, 0x478d, 0x2204,
- 0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd, 0x080c, 0x2393,
- 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0x72c8, 0xa184, 0xfffd,
- 0x1904, 0x13b2, 0xa284, 0xfffd, 0x1904, 0x13b2, 0x2100, 0x7920,
- 0x7822, 0x2200, 0x7a24, 0x7826, 0x0804, 0x13b8, 0x2011, 0x4c40,
- 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4bc0, 0x8107, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc, 0x74d8, 0x71c6,
- 0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000, 0x6a02, 0xd2ac,
- 0x1118, 0x2021, 0x0000, 0x0090, 0xa484, 0x00ff, 0xa082, 0x0002,
- 0x1a04, 0x174f, 0x843f, 0xa7bc, 0x00ff, 0x0140, 0xa786, 0x0002,
- 0x1904, 0x174f, 0xa484, 0x00ff, 0x0904, 0x174f, 0x2061, 0x0200,
- 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, 0x0009, 0x2031, 0x0062,
- 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084, 0x00ff, 0x1110,
- 0xa73d, 0x1138, 0x2041, 0x0019, 0xa384, 0x00ff, 0xa082, 0x001a,
- 0x0210, 0xa4a4, 0x00ff, 0x8307, 0xa084, 0x00ff, 0x0188, 0xa842,
- 0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff, 0xa39d, 0x0f00,
- 0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600, 0xa702, 0x1278,
- 0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a, 0x6b0c, 0x73ce,
- 0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804, 0x13ba, 0x2091,
- 0x8001, 0x0804, 0x13b4, 0x77c4, 0x080c, 0x1b9a, 0x2091, 0x8000,
- 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e,
- 0x2708, 0x0804, 0x13b7, 0x70c4, 0x2061, 0x4740, 0x6118, 0x601a,
- 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x70c8, 0x2061,
- 0x4780, 0x6218, 0x601a, 0x0804, 0x13b8, 0x71c4, 0x72c8, 0x73cc,
- 0xa182, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23d8, 0xa384, 0x4000,
- 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x77c4, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708,
- 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6a08,
- 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x22d5,
- 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0110,
- 0x080c, 0x22d5, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4,
- 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000,
- 0x080c, 0x1bb2, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0804, 0x13b8,
- 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc,
- 0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc, 0x73c8, 0x72cc, 0x77c6,
- 0x73ca, 0x72ce, 0x080c, 0x1c2a, 0x11e8, 0x6818, 0xa005, 0x01a0,
- 0x2708, 0x0076, 0x080c, 0x23f7, 0x007e, 0x1170, 0x2001, 0x0015,
- 0xd7fc, 0x1118, 0x2061, 0x4740, 0x0018, 0xc0fd, 0x2061, 0x4780,
- 0x782a, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001, 0x2001, 0x4005,
- 0x0804, 0x13bc, 0x2091, 0x8001, 0x0804, 0x13ba, 0x77c4, 0xd7fc,
- 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc, 0x080c, 0x1b1e,
- 0x0110, 0x0804, 0x13bc, 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005,
- 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1bb2, 0x2009, 0x0016,
- 0xd7fc, 0x1118, 0x2061, 0x4740, 0x0018, 0x2061, 0x4780, 0xc1fd,
- 0x6063, 0x0003, 0x607b, 0x0000, 0x6772, 0x607f, 0x000f, 0x792a,
- 0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22d5, 0x2091, 0x8001, 0x0005,
- 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128, 0x080c, 0x1b29,
- 0x0138, 0x0804, 0x13bc, 0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc,
- 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x1118,
- 0x2061, 0x4740, 0x0018, 0x2061, 0x4780, 0xc1fd, 0x607b, 0x0000,
- 0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a, 0x61d0, 0xc1c4,
- 0x61d2, 0x080c, 0x22d5, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049,
- 0x0005, 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0118,
- 0x60d0, 0xc0fd, 0x60d2, 0x080c, 0x1bb2, 0x70c8, 0x6836, 0x8738,
- 0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005, 0x2019, 0x0000,
- 0x72c8, 0xd284, 0x0128, 0x080c, 0x1b29, 0x0138, 0x0804, 0x13bc,
- 0x080c, 0x1b1e, 0x0110, 0x0804, 0x13bc, 0x72c8, 0x72ca, 0x78ac,
- 0xa084, 0x0003, 0x1518, 0x2039, 0x0000, 0xd284, 0x0108, 0xc7fd,
- 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x080c, 0x1b9a,
- 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x6837, 0x0000,
- 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x1d80, 0xa7bc, 0xff00,
- 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d40, 0x2091, 0x8000,
- 0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, 0x2069, 0x0200, 0x6808,
- 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004,
- 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x18c2, 0x684b,
- 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x18cb,
- 0x20a9, 0x00fa, 0x1f04, 0x18d2, 0x2079, 0x4700, 0x2009, 0x0018,
- 0x72c8, 0xd284, 0x1118, 0x2061, 0x4740, 0x0018, 0x2061, 0x4780,
- 0xc1fd, 0x607b, 0x0000, 0x792a, 0x6063, 0x0001, 0x607f, 0x000f,
- 0x60a3, 0x0000, 0x60a4, 0x60ae, 0x60b2, 0x60d0, 0xd0b4, 0x0160,
- 0xc0b4, 0x60d2, 0x00c6, 0x60b4, 0xa065, 0x6008, 0xc0d4, 0x600a,
- 0x6018, 0x8001, 0x601a, 0x00ce, 0x60d0, 0xa084, 0x7eff, 0x60d2,
- 0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0108, 0x0005, 0x681b, 0x0054,
- 0x2091, 0x8001, 0x0005, 0x73cc, 0x080c, 0x1878, 0x69ec, 0x6a48,
- 0xa185, 0x1800, 0x684a, 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021,
- 0x0004, 0x20a9, 0x09ff, 0x1f04, 0x191b, 0x8421, 0x1dd0, 0x8319,
- 0x1db0, 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118,
- 0x2069, 0x4740, 0x0010, 0x2069, 0x4780, 0x71c4, 0x71c6, 0x6916,
- 0x81ff, 0x1110, 0x68a3, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
- 0x1110, 0x080c, 0x1c7a, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de,
- 0x0010, 0xa02e, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
- 0x72ce, 0x2079, 0x4700, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c,
- 0x1b77, 0x0904, 0x1a5c, 0x20a9, 0x0005, 0x20a1, 0x4714, 0x2091,
- 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1d41,
- 0x0120, 0x080c, 0x1b7f, 0x0804, 0x1a5c, 0x6004, 0xa08c, 0x00ff,
- 0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x2086, 0x000e, 0xa084,
- 0xff00, 0x8007, 0x8009, 0x0904, 0x19f1, 0x00c6, 0x2c68, 0x080c,
- 0x1b77, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000,
- 0x00ce, 0x00c6, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
- 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x19f0, 0x2009,
- 0x0040, 0x080c, 0x1d41, 0x15a0, 0x6004, 0xa084, 0x00ff, 0xa086,
- 0x0002, 0x0150, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1138,
- 0x0016, 0x080c, 0x2083, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce,
- 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce, 0x609f, 0x0000, 0x080c,
- 0x1a60, 0x2009, 0x0018, 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086,
- 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
- 0x080c, 0x1b34, 0x000e, 0x7812, 0x080c, 0x1b7f, 0x0804, 0x1a5c,
- 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bf3, 0x00ce, 0x609f, 0x0000,
- 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003,
- 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
- 0x080c, 0x1b34, 0x000e, 0x7812, 0x080c, 0x1b7f, 0x0804, 0x1a5c,
- 0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1b29, 0x01f0, 0x0018,
- 0x080c, 0x1b1e, 0x01d0, 0x080c, 0x1a60, 0x2009, 0x0018, 0x6087,
- 0x0103, 0x601b, 0x0021, 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff,
- 0x0110, 0xc0c5, 0x7812, 0x080c, 0x1b34, 0x000e, 0x7812, 0x080c,
- 0x1b7f, 0x2001, 0x4007, 0x0804, 0x13bc, 0x6104, 0xa18c, 0x00ff,
- 0xa186, 0x0005, 0x1118, 0x601c, 0xc0bd, 0x601e, 0x74c4, 0x73c8,
- 0x72cc, 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc,
- 0x1118, 0x2071, 0x4740, 0x0018, 0x2071, 0x4780, 0xc1fd, 0x792a,
- 0x7063, 0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, 0x746e,
- 0x7072, 0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, 0x611c,
- 0xa184, 0x0060, 0x0110, 0x080c, 0x3fe9, 0x00ee, 0x6596, 0x65a6,
- 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023,
- 0x0000, 0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x080c,
- 0x22d5, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804, 0x13bd,
- 0x20a9, 0x0005, 0x2099, 0x4714, 0x2091, 0x8000, 0x530a, 0x2091,
- 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9,
- 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0804, 0x13ba,
- 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c, 0xa016,
- 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000, 0x1118,
- 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804, 0x13bd,
- 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x1a04, 0x13b3, 0x7966,
- 0x0804, 0x13ba, 0x7964, 0x71c6, 0x0804, 0x13ba, 0x7900, 0x71c6,
- 0x71c4, 0x7902, 0x0804, 0x13ba, 0x7900, 0x71c6, 0x0804, 0x13ba,
- 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c, 0x0230,
- 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, 0x810c, 0x81ff, 0x1904,
- 0x13b4, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd, 0x7912,
- 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, 0x01c0, 0x8108, 0x2019,
- 0x0041, 0x2011, 0x8f4e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312,
- 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312,
- 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x8f53,
- 0x2112, 0x2011, 0x8f73, 0x2312, 0x7904, 0x7806, 0x0804, 0x13b9,
- 0x7804, 0x70c6, 0x0804, 0x13ba, 0x71c4, 0xd1fc, 0x1118, 0x2011,
- 0x4bc0, 0x0010, 0x2011, 0x4c40, 0x8107, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc, 0x0110,
- 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, 0x0001, 0x6b0c, 0x6800,
- 0x70da, 0x0804, 0x13b7, 0x7814, 0xd0f4, 0x0130, 0x2001, 0x4007,
- 0x70db, 0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001, 0x4007,
- 0x70db, 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7814, 0xd0f4,
- 0x0130, 0x2001, 0x4007, 0x70db, 0x0000, 0xa005, 0x0008, 0xa006,
- 0x0005, 0x7814, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db, 0x0001,
- 0xa005, 0x0008, 0xa006, 0x0005, 0x7112, 0x721a, 0x731e, 0x7810,
- 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c,
- 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2,
- 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f,
- 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107,
- 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, 0x7d10,
- 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc,
- 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, 0x711a, 0x721e, 0x7d10,
- 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, 0x01e0, 0x0005, 0x7848,
- 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, 0x0000, 0x0005, 0x00f6,
- 0x2079, 0x4700, 0x7848, 0x2062, 0x2c00, 0xa005, 0x1110, 0x080c,
- 0x2575, 0x784a, 0x00fe, 0x0005, 0x2011, 0x9100, 0x7a4a, 0x7bc4,
- 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, 0x2010, 0x0cc8, 0x2013,
- 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, 0x1118, 0x2011, 0x4cc0,
- 0x0010, 0x2011, 0x6cc0, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
- 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa268, 0x002e,
- 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808,
- 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128, 0x2009,
- 0x4752, 0x2071, 0x4740, 0x0020, 0x2009, 0x4792, 0x2071, 0x4780,
- 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, 0x1138, 0x2060, 0x6000,
- 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, 0x2009, 0x0000, 0x0016,
- 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, 0x0421, 0x080c, 0x1db2,
- 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x6812, 0x1d88, 0x7910,
- 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060, 0x080c,
- 0x26bf, 0x00ee, 0x0005, 0xa065, 0x0160, 0x2008, 0x609c, 0xa005,
- 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x7848, 0x794a,
- 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c,
- 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a,
- 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071, 0x4740,
- 0x2031, 0x47c0, 0x0020, 0x2071, 0x4780, 0x2031, 0x49c0, 0x704c,
- 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x704e, 0xa006,
- 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x4740, 0x0010,
- 0x2079, 0x4780, 0x080c, 0x1b9a, 0x2091, 0x8000, 0x6804, 0x780a,
- 0xa065, 0x05f0, 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065,
- 0x05b8, 0x6010, 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0, 0x2c28,
- 0x7848, 0xac06, 0x1108, 0x0448, 0x6804, 0xac06, 0x1140, 0x6000,
- 0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048, 0x6400,
- 0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00, 0x6802,
- 0x2560, 0x080c, 0x1c02, 0x601b, 0x0005, 0x6023, 0x0020, 0x00fe,
- 0x080c, 0x1db2, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001,
- 0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005,
- 0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108,
- 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091,
- 0x8000, 0x080c, 0x1bb2, 0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc,
- 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091,
- 0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8f74, 0x210c, 0xa10d,
- 0x0118, 0xa065, 0x0804, 0x20a1, 0x2061, 0x0000, 0x6018, 0xd084,
- 0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, 0x2069,
- 0x4740, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4780, 0xc7fd, 0x2091,
- 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005, 0x1108,
- 0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x2575, 0x0002, 0x1cd7,
- 0x1cda, 0x1ce0, 0x1ce4, 0x1cd8, 0x1ce8, 0x1cd8, 0x1cd8, 0x1cd8,
- 0x1cee, 0x1d18, 0x1d1b, 0x1d20, 0x1d29, 0x1cd8, 0x1cd8, 0x0005,
- 0x080c, 0x2575, 0x080c, 0x1c7a, 0x2001, 0x8001, 0x0804, 0x1d32,
- 0x2001, 0x8003, 0x0804, 0x1d32, 0x2001, 0x8004, 0x0804, 0x1d32,
- 0x080c, 0x1c7a, 0x2001, 0x8006, 0x0804, 0x1d32, 0x2011, 0x800a,
- 0x2091, 0x8000, 0xd7fc, 0x1118, 0x2069, 0x4740, 0x0010, 0x2069,
- 0x4780, 0x2038, 0x6800, 0xa086, 0x0000, 0x0120, 0x6f1e, 0x2091,
- 0x8001, 0x0005, 0x0026, 0x6870, 0xa0bc, 0xff00, 0x2041, 0x0021,
- 0x2049, 0x0004, 0x2051, 0x0010, 0x080c, 0x1bb2, 0x8738, 0xa784,
- 0x001f, 0x1dd0, 0x2091, 0x8001, 0x000e, 0x6970, 0x71c6, 0x00d0,
- 0x2001, 0x800c, 0x00b8, 0x080c, 0x1c7a, 0x2001, 0x800d, 0x0090,
- 0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0, 0x70c6, 0x2001, 0x800e,
- 0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008, 0x78e8, 0x70c6, 0x2001,
- 0x800f, 0x0000, 0x70c2, 0xd7fc, 0x1118, 0x70db, 0x0000, 0x0010,
- 0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080,
- 0x0005, 0xac80, 0x0001, 0x81ff, 0x0518, 0x2099, 0x0030, 0x20a0,
- 0x700c, 0xa084, 0x07ff, 0x0100, 0x7018, 0x0006, 0x701c, 0x0006,
- 0x7020, 0x0006, 0x7024, 0x0006, 0x7112, 0x81ac, 0x721a, 0x731e,
- 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b,
- 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x1110, 0x53a5, 0xa006,
- 0x7003, 0x0000, 0x7007, 0x0004, 0x000e, 0x7026, 0x000e, 0x7022,
- 0x000e, 0x701e, 0x000e, 0x701a, 0x0005, 0x2011, 0x0020, 0x2009,
- 0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201, 0x6803, 0xfd20, 0x6807,
- 0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109,
- 0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520, 0x2029, 0x0001, 0x7814,
- 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019, 0x0c0a, 0x2021, 0x000a,
- 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x0070, 0x70ec, 0xd0e4,
- 0x1128, 0x2019, 0x180c, 0x2021, 0x000c, 0x0030, 0x2019, 0x1809,
- 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a, 0x6c0e, 0x6d1e, 0x6807,
- 0x0038, 0x0005, 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, 0x7868,
- 0xa005, 0x796a, 0x0110, 0x2c02, 0x0008, 0x796e, 0x0005, 0x00c6,
- 0x2061, 0x4700, 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068,
- 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e, 0x00ce, 0x0005,
- 0x2091, 0x8000, 0x2c04, 0x786e, 0xa005, 0x1108, 0x786a, 0x2091,
- 0x8001, 0x609c, 0xa005, 0x0188, 0x00c6, 0x2060, 0x2008, 0x609c,
- 0xa005, 0x0138, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005,
- 0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce, 0x7848, 0x2062, 0x609f,
- 0x0000, 0xac85, 0x0000, 0x1110, 0x080c, 0x2575, 0x784a, 0x0005,
- 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200,
- 0x1f04, 0x1dfc, 0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010,
- 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a,
- 0x1220, 0x1f04, 0x1e0c, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04,
- 0x1e0c, 0x0006, 0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e,
- 0x0005, 0x0006, 0x3200, 0xa085, 0x1000, 0x0cb8, 0x7d74, 0x70d0,
- 0xa506, 0x0904, 0x1eda, 0x7810, 0x2050, 0x080c, 0x1b77, 0x0904,
- 0x1eda, 0xa046, 0x7970, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040,
- 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, 0x8840, 0x2009, 0x0080,
- 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020,
- 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0110, 0x080c,
- 0x1b77, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, 0x2091, 0x8001,
- 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, 0x1120, 0x88ff, 0x0904,
- 0x1ec7, 0x0050, 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001,
- 0x20a0, 0x53a5, 0x0804, 0x1ec7, 0xa046, 0x7218, 0x731c, 0xdac4,
- 0x0110, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3,
- 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0118, 0x7422,
- 0x7526, 0xa006, 0x7007, 0x0004, 0x0904, 0x1ec7, 0x8cff, 0x0110,
- 0x080c, 0x1b7f, 0x00ce, 0x080c, 0x1b7f, 0xa046, 0x7888, 0x8000,
- 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, 0x7b78, 0xdac4, 0x0110,
- 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399,
- 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e, 0xdac4,
- 0x0588, 0x7422, 0x7526, 0x0470, 0x6014, 0xd0fc, 0x1118, 0x2069,
- 0x4740, 0x0010, 0x2069, 0x4780, 0x2091, 0x8000, 0x681f, 0x0002,
- 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, 0x0c70, 0x788b, 0x0000,
- 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0098, 0x00ce,
- 0x788b, 0x0000, 0x080c, 0x205c, 0x6004, 0xa084, 0x000f, 0x0059,
- 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, 0xa084, 0x000f, 0x0019,
- 0x0804, 0x1e26, 0x0005, 0x0002, 0x1eec, 0x1f07, 0x1f20, 0x1eec,
- 0x1f2d, 0x1efd, 0x1eec, 0x1eec, 0x1eec, 0x1f05, 0x1f1e, 0x1eec,
- 0x1eec, 0x1eec, 0x1eec, 0x1eec, 0x2039, 0x0400, 0x78bc, 0xa705,
- 0x78be, 0x6008, 0xa705, 0x600a, 0x080c, 0x1f69, 0x609c, 0x78ba,
- 0x609f, 0x0000, 0x080c, 0x2048, 0x0005, 0x78bc, 0xd0c4, 0x0108,
- 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, 0x080c, 0x2086, 0x78bc,
- 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, 0x6004, 0x8007, 0xa084,
- 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, 0x1f69, 0x0120, 0x78bc,
- 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f84, 0x0005, 0x080c, 0x2083,
- 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, 0x1108, 0x0828, 0x080c,
- 0x1f69, 0x1110, 0x0804, 0x1f84, 0x0005, 0x78bc, 0xd0c4, 0x0110,
- 0x0804, 0x1eec, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001, 0x22a8,
- 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, 0xa7bc, 0xff00, 0x20a9,
- 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, 0x2011, 0x0002,
- 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c0, 0x080c, 0x1b9a,
- 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808,
- 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x1f04,
- 0x1f51, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, 0x080c, 0x1b7f,
- 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x1110,
- 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06, 0x1108,
- 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, 0x78bc, 0xc0c4, 0x78be,
- 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e, 0x2530, 0x7dba,
- 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff,
- 0x601e, 0xa984, 0x0060, 0x0160, 0x080c, 0x3fe9, 0x86ff, 0x1140,
- 0x85ff, 0x1130, 0x2039, 0x0800, 0x080c, 0x2048, 0x0804, 0x2046,
- 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4780, 0xd7fc,
- 0x1110, 0x2071, 0x4740, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f,
- 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0, 0xa168,
- 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c4,
- 0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138, 0xd7fc,
- 0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08, 0xd684,
- 0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1c02, 0x2091,
- 0x8000, 0x080c, 0x1db2, 0x2091, 0x8001, 0x7814, 0xd0c4, 0x0904,
- 0x2046, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x2046, 0xd0fc,
- 0x1110, 0x0804, 0x2046, 0x601b, 0x0021, 0x0804, 0x2046, 0x6024,
- 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814, 0xa202,
- 0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c, 0x78ba,
- 0x609f, 0x0000, 0x080c, 0x2048, 0x0804, 0x2046, 0x2c08, 0xd9fc,
- 0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002,
- 0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304, 0x6002,
- 0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00, 0x2060,
- 0x080c, 0x26bf, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050, 0x6800,
- 0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160, 0x6003,
- 0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a, 0x6810,
- 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4,
- 0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1c13, 0x00ee, 0x0005,
- 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1db2, 0x2091,
- 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f, 0x0000,
- 0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818, 0xd384,
- 0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278, 0xc384,
- 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84, 0x7222,
- 0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876, 0x70d2,
- 0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04, 0x2082,
- 0x2091, 0x4080, 0x0005, 0x2039, 0x2098, 0x0010, 0x2039, 0x209e,
- 0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912,
- 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88, 0x0005,
- 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b,
- 0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x224a, 0x2225, 0x20a9,
- 0x2119, 0x2039, 0x8f74, 0x2734, 0x7d10, 0x00c0, 0x6084, 0xa086,
- 0x0103, 0x1904, 0x2103, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff,
- 0x11d8, 0x0804, 0x2103, 0x8603, 0xa080, 0x8f55, 0x620c, 0x2202,
- 0x8000, 0x6210, 0x2202, 0x080c, 0x1dd0, 0x8630, 0xa68e, 0x000f,
- 0x0904, 0x2184, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602, 0x1220,
- 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04, 0x2184,
- 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8, 0x2011,
- 0x8f55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684, 0x1130,
- 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685, 0x8020,
- 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf,
- 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810, 0xc0ad,
- 0x7812, 0x0804, 0x2184, 0x263a, 0x080c, 0x2250, 0x1904, 0x226c,
- 0x786c, 0xa065, 0x1904, 0x20ae, 0x2091, 0x8000, 0x7810, 0xa084,
- 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804,
- 0x226c, 0x2039, 0x8f74, 0x2734, 0x7d10, 0x00a0, 0x6084, 0xa086,
- 0x0103, 0x1904, 0x216e, 0x6114, 0x6018, 0xa105, 0x0120, 0x86ff,
- 0x11b8, 0x0804, 0x216e, 0xa680, 0x8f55, 0x620c, 0x2202, 0x080c,
- 0x1dd0, 0x8630, 0xa68e, 0x001e, 0x0904, 0x2184, 0x786c, 0xa065,
- 0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005,
- 0xa682, 0x0006, 0x1a04, 0x2184, 0x2091, 0x8000, 0x2069, 0x0000,
- 0x6818, 0xd084, 0x11f8, 0x2011, 0x8f55, 0x2009, 0x8f4e, 0x26a8,
- 0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2150, 0xa685,
- 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084,
- 0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8f75, 0x200a,
- 0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a, 0x080c,
- 0x2250, 0x1904, 0x226c, 0x786c, 0xa065, 0x1904, 0x211e, 0x2091,
- 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812,
- 0x2091, 0x8001, 0x0804, 0x226c, 0x2091, 0x8000, 0x7007, 0x0004,
- 0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302, 0x1150,
- 0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091,
- 0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c,
- 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, 0x8004,
- 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4,
- 0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1,
- 0x0030, 0x7003, 0x0000, 0x2009, 0x8f54, 0x260a, 0x8109, 0x2198,
- 0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6,
- 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a,
- 0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140, 0x810f,
- 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107,
- 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211, 0xd4c4,
- 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8,
- 0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8f54, 0x2634, 0x78a8,
- 0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004, 0xd094,
- 0x1de8, 0x0804, 0x2186, 0x2069, 0x4747, 0x206b, 0x0003, 0x78ac,
- 0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6, 0x2091,
- 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001,
- 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, 0x721e,
- 0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086, 0x0103,
- 0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000, 0x6818,
- 0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020,
- 0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1dd0, 0x0e04, 0x2243,
- 0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c, 0xa065,
- 0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8, 0x00e0,
- 0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a, 0xa086,
- 0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1dd0, 0xa006,
- 0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9, 0x1110,
- 0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091, 0x4080,
- 0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385, 0x0000,
- 0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184, 0xff00,
- 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
- 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0,
- 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028,
- 0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1b34, 0x01d0, 0x78a8,
- 0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118, 0x2069,
- 0x4740, 0x0010, 0x2069, 0x4780, 0x2091, 0x8000, 0x681f, 0x0003,
- 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001,
- 0x0068, 0x78ab, 0x0000, 0x080c, 0x1dd0, 0x7990, 0x7894, 0x8000,
- 0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010,
- 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2009, 0x4758, 0x0010,
- 0x2009, 0x4798, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, 0x4780,
- 0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4740, 0x2079, 0x0200,
- 0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, 0x4745,
- 0x0010, 0x2009, 0x4785, 0x2104, 0xa005, 0x1130, 0x7830, 0xa084,
- 0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, 0x0002,
- 0x2069, 0x4700, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x234b,
- 0x2071, 0x4780, 0x2079, 0x0100, 0x2021, 0x49bf, 0x784b, 0x000f,
- 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3e37, 0x0030,
- 0x20a1, 0x012b, 0x2019, 0x3e37, 0xd184, 0x0110, 0x20a1, 0x022b,
- 0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398,
- 0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, 0x20a9,
- 0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x2329, 0x7003,
- 0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, 0x080c,
- 0x246c, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300, 0x7806,
- 0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, 0x2f08,
- 0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4740, 0x2079,
- 0x0200, 0x2021, 0x47bf, 0x0804, 0x2306, 0x080c, 0x2526, 0x0005,
- 0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201, 0xa18c,
- 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e, 0x080c,
- 0x246c, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011, 0x0201,
- 0x20a9, 0x0009, 0x810b, 0x1f04, 0x2372, 0xa18c, 0x0e00, 0x2204,
- 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002, 0x2009,
- 0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x2383, 0xa294, 0x00e0,
- 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118, 0x2009,
- 0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011,
- 0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x239b, 0xa18c, 0xf000,
- 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011, 0x0102,
- 0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa09c, 0x0f30, 0xa084,
- 0xf0cf, 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc,
- 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020,
- 0x609a, 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100,
- 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080,
- 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005,
- 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc,
- 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020,
- 0x0118, 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed,
- 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091,
- 0x8000, 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2450, 0xd1fc,
- 0x0118, 0x2061, 0x8ed0, 0x0010, 0x2061, 0x8dc0, 0x080c, 0x2458,
- 0x0560, 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8dd0, 0x0010,
- 0x2061, 0x8cc0, 0x00c6, 0x080c, 0x2458, 0x0128, 0x00ce, 0x8c60,
- 0x1f04, 0x2412, 0x04a8, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8dd0,
- 0x2071, 0x4780, 0x0020, 0xa082, 0x8cc0, 0x2071, 0x4740, 0x7076,
- 0x7172, 0x2138, 0x2001, 0x0004, 0x7062, 0x707f, 0x000f, 0x71d0,
- 0xc1c4, 0x71d2, 0x080c, 0x22cb, 0x00c0, 0xd1fc, 0x1118, 0x2071,
- 0x4740, 0x0010, 0x2071, 0x4780, 0x6020, 0xc0dd, 0x6022, 0x7172,
- 0x2138, 0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, 0x000f,
- 0x71d0, 0xc1c4, 0x71d2, 0x080c, 0x22cb, 0x2001, 0x0000, 0x0010,
- 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005,
- 0x2c04, 0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c,
- 0xa206, 0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000,
- 0x0c80, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079,
- 0x4780, 0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4740, 0x2071,
- 0x0200, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e,
- 0x0060, 0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800,
- 0xd0bc, 0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005,
- 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120,
- 0xa084, 0x0006, 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036,
- 0x2018, 0x2071, 0x4c40, 0xd0fc, 0x1110, 0x2071, 0x4bc0, 0x8007,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084,
- 0x000a, 0x1904, 0x2523, 0x7108, 0xa194, 0xff00, 0x0904, 0x2523,
- 0xa18c, 0x00ff, 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085,
- 0x003a, 0x7006, 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a,
- 0xa102, 0x16d0, 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084,
- 0x00ff, 0x701e, 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a,
- 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012,
- 0xa106, 0x0198, 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019,
- 0xa106, 0x0188, 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009,
- 0x000c, 0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0,
- 0x2009, 0x0019, 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f,
- 0x0058, 0x2009, 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009,
- 0x0019, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004,
- 0xa085, 0x000a, 0x7006, 0x2071, 0x4700, 0x7004, 0xd0bc, 0x0158,
- 0xd3fc, 0x1120, 0x73ea, 0x2071, 0x4740, 0x0018, 0x73ee, 0x2071,
- 0x4780, 0x701f, 0x000d, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff,
- 0x2004, 0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005,
- 0x12a0, 0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c,
- 0x810c, 0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004,
- 0x8004, 0xa105, 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x2574,
- 0x255b, 0x2574, 0x255b, 0x254e, 0x2568, 0x254e, 0x7008, 0xa084,
- 0xc3ff, 0xa085, 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085,
- 0x3000, 0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000,
- 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005,
- 0x7008, 0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084,
- 0xc3ff, 0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04, 0x2575, 0x2091,
- 0x8000, 0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e,
- 0x2071, 0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db,
- 0x0a04, 0x70df, 0x002a, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
- 0x4080, 0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a,
- 0x758e, 0x7492, 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138,
- 0xd7bc, 0x1128, 0xa784, 0x007d, 0x1904, 0x3c9c, 0x0871, 0xa49c,
- 0x000f, 0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418,
- 0x8507, 0xa084, 0x000f, 0x0002, 0x2b6c, 0x2c57, 0x2c95, 0x2efb,
- 0x3279, 0x32d0, 0x3376, 0x3405, 0x34d9, 0x35ab, 0x25c7, 0x25c4,
- 0x299e, 0x2a85, 0x324d, 0x25c4, 0x080c, 0x2575, 0x0005, 0xa006,
- 0x0038, 0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042,
- 0x70ce, 0x705c, 0xa005, 0x1904, 0x2718, 0x7060, 0xa084, 0x0007,
- 0x0002, 0x25e1, 0x2652, 0x265a, 0x2663, 0x266c, 0x26fe, 0x2675,
- 0x2652, 0x7830, 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4,
- 0x1904, 0x262f, 0x70a0, 0xa086, 0x0001, 0x09c0, 0x7014, 0xa005,
- 0x19a8, 0x70b0, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080,
- 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
- 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d,
- 0x6e1c, 0x2001, 0x0010, 0x0804, 0x284b, 0x705c, 0xa005, 0x1904,
- 0x25c6, 0x00c6, 0x00d6, 0x70b0, 0xa06d, 0x6800, 0xa065, 0xa055,
- 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804,
- 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa,
- 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0804, 0x284b, 0x080c,
- 0x3c5b, 0x1904, 0x25c6, 0x781b, 0x0068, 0x70b8, 0xa06d, 0x68b4,
- 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808,
- 0xc08d, 0x780a, 0x68bc, 0x703e, 0xc1b4, 0x71d2, 0x70b4, 0xa065,
- 0x68c0, 0x7056, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009,
- 0x7042, 0x0005, 0x080c, 0x3c5b, 0x1120, 0x781b, 0x0054, 0x7003,
- 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011, 0x000c, 0x0419,
- 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011, 0x0006,
- 0x00d1, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1128, 0x2011,
- 0x000d, 0x0089, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c5b, 0x1150,
- 0x2011, 0x0006, 0x0041, 0x7078, 0x707b, 0x0000, 0x2068, 0x704a,
- 0x7003, 0x0004, 0x0005, 0x7170, 0xc1fc, 0x8107, 0x7882, 0x789b,
- 0x0080, 0xa286, 0x000c, 0x1120, 0x7aaa, 0x2001, 0x0001, 0x0098,
- 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, 0x0120,
- 0x7aaa, 0x2001, 0x0002, 0x0038, 0x78ab, 0x0020, 0x7174, 0x79aa,
- 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, 0x785b, 0x0004,
- 0x781b, 0x0113, 0x080c, 0x3c6e, 0x707f, 0x000f, 0x70d0, 0xd0b4,
- 0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x7014,
- 0xa005, 0x1138, 0x70d0, 0xd0b4, 0x0128, 0x70b4, 0xac06, 0x1110,
- 0x0c29, 0x0005, 0x0016, 0x71a0, 0xa186, 0x0001, 0x0528, 0x00d6,
- 0x0026, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0, 0x2068, 0x6800,
- 0xac06, 0x0120, 0x8211, 0x01b0, 0x00c9, 0x0cc8, 0x00c6, 0x2100,
- 0x2011, 0x0001, 0xa212, 0x70b0, 0x2068, 0x6800, 0x2060, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x8211, 0x0110, 0x0041, 0x0cb0, 0x70a3,
- 0x0001, 0x00ce, 0x002e, 0x00de, 0x001e, 0x0005, 0xade8, 0x0005,
- 0x70a8, 0xad06, 0x1110, 0x70a4, 0x2068, 0x0005, 0x080c, 0x3c5b,
- 0x1904, 0x25c6, 0x7078, 0x2068, 0x7770, 0x080c, 0x3b95, 0x2c50,
- 0x080c, 0x3cf6, 0x789b, 0x0080, 0x6814, 0xa084, 0x001f, 0xc0bd,
- 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0804, 0x2850,
- 0x080c, 0x3c5b, 0x1904, 0x25c6, 0x789b, 0x0080, 0x705c, 0x2068,
- 0x6f14, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6, 0x70b4,
- 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a,
- 0x00ce, 0x080c, 0x3b95, 0x2c50, 0x080c, 0x3cf6, 0x6824, 0xa005,
- 0x0130, 0xa082, 0x0006, 0x0208, 0x0010, 0x6827, 0x0005, 0x6814,
- 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001,
- 0x2001, 0x0003, 0x0804, 0x2850, 0xc28d, 0x72d2, 0x72bc, 0xa200,
- 0xa015, 0x7150, 0x8108, 0xa12a, 0x0208, 0x71bc, 0x2164, 0x6504,
- 0x85ff, 0x1170, 0x7152, 0x8421, 0x1da8, 0x70d0, 0xd08c, 0x0128,
- 0x70cc, 0xa005, 0x1110, 0x70cf, 0x000a, 0x0005, 0x2200, 0x0c90,
- 0x70d0, 0xc08c, 0x70d2, 0x70cf, 0x0000, 0x6034, 0xa005, 0x1db0,
- 0x6708, 0xa784, 0x073f, 0x01d0, 0xd7d4, 0x1d80, 0xa784, 0x0021,
- 0x1d68, 0xa784, 0x0002, 0x0130, 0xa784, 0x0004, 0x0d38, 0xa7bc,
- 0xfffb, 0x670a, 0xa784, 0x0218, 0x1d08, 0xa784, 0x0100, 0x0130,
- 0x6018, 0xa005, 0x19d8, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823,
- 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0128, 0x601c, 0xa302,
- 0x0220, 0x0118, 0x0858, 0x83ff, 0x1948, 0x2d58, 0x2c50, 0x7152,
- 0xd7bc, 0x1120, 0x7028, 0x6022, 0x603a, 0x0010, 0xc7bc, 0x670a,
- 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001, 0x6b14,
- 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0110, 0xd684, 0x0110,
- 0xa39c, 0xffbf, 0xd6a4, 0x0110, 0xa39d, 0x0020, 0xa684, 0x000e,
- 0x1904, 0x2802, 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a0, 0xa786,
- 0x0001, 0x1178, 0x70d0, 0xd0b4, 0x1160, 0x7000, 0xa082, 0x0002,
- 0x1240, 0x7830, 0xd0bc, 0x1128, 0x789b, 0x0080, 0x7baa, 0x0804,
- 0x2849, 0x8739, 0x77a2, 0x2750, 0x77ac, 0xa7b0, 0x0005, 0x70a8,
- 0xa606, 0x1108, 0x76a4, 0x76ae, 0x2c3a, 0x8738, 0x2d3a, 0x8738,
- 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc, 0x0150,
- 0x2091, 0x8000, 0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, 0x2091,
- 0x8000, 0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, 0x1904,
- 0x2751, 0x0005, 0xd1dc, 0x0904, 0x37f1, 0x2029, 0x0020, 0xd69c,
- 0x1120, 0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, 0x610c,
- 0x8108, 0xa18c, 0x00ff, 0x70c8, 0xa160, 0x2c64, 0x8cff, 0x0188,
- 0x6014, 0xa706, 0x1dd0, 0x60b8, 0x8001, 0x60ba, 0x1d88, 0x2a60,
- 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x1904, 0x2751,
- 0x0005, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008,
- 0xc0d5, 0x600a, 0x77a0, 0xa786, 0x0001, 0x1904, 0x27d9, 0x70d0,
- 0xd0b4, 0x1904, 0x27d9, 0x7000, 0xa082, 0x0002, 0x1a04, 0x27d9,
- 0x7830, 0xd0bc, 0x1904, 0x27d9, 0x789b, 0x0080, 0x7baa, 0x7daa,
- 0x79aa, 0x2001, 0x0002, 0x0006, 0x6018, 0x8000, 0x601a, 0x0008,
- 0x0006, 0x2960, 0x6104, 0x2a60, 0x080c, 0x3d09, 0x1590, 0xa184,
- 0x0018, 0x0180, 0xa184, 0x0010, 0x0118, 0x080c, 0x399a, 0x1548,
- 0xa184, 0x0008, 0x0138, 0x69a0, 0xa184, 0x0600, 0x1118, 0x080c,
- 0x38b8, 0x00f8, 0x69a0, 0xa184, 0x1e00, 0x0528, 0xa184, 0x0800,
- 0x0178, 0x00c6, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104,
- 0xa18d, 0x0010, 0x6106, 0x00ce, 0x080c, 0x399a, 0x1150, 0x69a0,
- 0xa184, 0x0200, 0x0118, 0x080c, 0x38fd, 0x0018, 0xa184, 0x0400,
- 0x19f0, 0x69a0, 0xa184, 0x1000, 0x0130, 0x6914, 0xa18c, 0xff00,
- 0x810f, 0x080c, 0x23c5, 0x002e, 0xa68c, 0x00e0, 0xa684, 0x0060,
- 0x0128, 0xa086, 0x0060, 0x1110, 0xa18d, 0x4000, 0xa18d, 0x0104,
- 0x69b6, 0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a,
- 0xd6bc, 0x0168, 0xc0fc, 0x7083, 0x0000, 0xa08a, 0x000d, 0x0328,
- 0xa08a, 0x000c, 0x7182, 0x2001, 0x000c, 0x800c, 0x7186, 0x78aa,
- 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0,
- 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898,
- 0x25a0, 0xa286, 0x0020, 0x1508, 0x70d0, 0xc0b5, 0x70d2, 0x2c00,
- 0x70b6, 0x2d00, 0x70ba, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286,
- 0x0002, 0x0904, 0x2921, 0x70a0, 0x8000, 0x70a2, 0x74b0, 0xa498,
- 0x0005, 0x70a8, 0xa306, 0x1108, 0x73a4, 0x73b2, 0xa286, 0x0010,
- 0x0904, 0x25c6, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, 0x19e0,
- 0xa286, 0x0002, 0x1904, 0x2938, 0x080c, 0x3c5b, 0x19a8, 0x6814,
- 0xc0fc, 0x8007, 0x7882, 0x2091, 0x8000, 0x781b, 0x0068, 0x68b4,
- 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091,
- 0x8001, 0x7808, 0xc08d, 0x780a, 0x0126, 0x00d6, 0x00c6, 0x70d0,
- 0xa084, 0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0x2900, 0x7056,
- 0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009,
- 0x7042, 0x7830, 0xd0bc, 0x0140, 0x2091, 0x303d, 0x70d0, 0xa084,
- 0x303d, 0x2091, 0x8000, 0x2090, 0x70a0, 0xa005, 0x1108, 0x0005,
- 0x8421, 0x0de8, 0x724c, 0x70bc, 0xa200, 0xa015, 0x0804, 0x2751,
- 0xa286, 0x0010, 0x1560, 0x080c, 0x3c5b, 0x1904, 0x28cc, 0x6814,
- 0xc0fc, 0x8007, 0x7882, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894,
- 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
- 0x70a0, 0x8000, 0x70a2, 0x74b0, 0xa490, 0x0005, 0x70a8, 0xa206,
- 0x1108, 0x72a4, 0x72b2, 0x2900, 0x7056, 0x68bc, 0x703e, 0x7003,
- 0x0002, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x6bb4,
- 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94,
- 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0068, 0x2900,
- 0x7056, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0170,
- 0x70d0, 0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, 0x0000,
- 0x0010, 0x2009, 0x0001, 0xa284, 0x000f, 0x0033, 0xad80, 0x0009,
- 0x7042, 0x2d00, 0x704a, 0x0005, 0x299c, 0x4208, 0x4208, 0x41f6,
- 0x4208, 0x299c, 0x299c, 0x299c, 0x080c, 0x2575, 0x7808, 0xa084,
- 0xfffd, 0x780a, 0x00f6, 0x2079, 0x4700, 0x78ac, 0x00fe, 0xd084,
- 0x01c0, 0x7160, 0xa186, 0x0001, 0x0904, 0x2a61, 0xa186, 0x0007,
- 0x0170, 0xa186, 0x0005, 0x1158, 0x7078, 0x2068, 0x681b, 0x0004,
- 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7063,
- 0x0000, 0x70a3, 0x0000, 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x26ae,
- 0x0156, 0x2011, 0x0004, 0x7160, 0xa186, 0x0001, 0x0158, 0xa186,
- 0x0007, 0x1118, 0x701f, 0x0005, 0x0010, 0x701f, 0x0001, 0x70d0,
- 0xc0c5, 0x70d2, 0x2001, 0x470a, 0x2004, 0xa084, 0x00ff, 0xa086,
- 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3, 0x0001,
- 0x0066, 0x080c, 0x3f4e, 0x20a9, 0x0010, 0x2039, 0x0000, 0x080c,
- 0x3a8b, 0xa7b8, 0x0100, 0x1f04, 0x29ef, 0x006e, 0x7000, 0x0002,
- 0x2a2c, 0x2a0a, 0x2a0a, 0x2a02, 0x2a2c, 0x2a2c, 0x2a2c, 0x2a00,
- 0x080c, 0x2575, 0x705c, 0xa005, 0x0538, 0xad06, 0x1118, 0x6800,
- 0x705e, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c, 0x3b95,
- 0x6008, 0xc0d4, 0x600a, 0x080c, 0x37c7, 0x0020, 0x7058, 0x2060,
- 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc, 0x0108,
- 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff,
- 0xc09d, 0x6822, 0x080c, 0x1dbf, 0x2011, 0x0004, 0x74c8, 0xa4a0,
- 0x0100, 0x04b1, 0xaea0, 0x0017, 0x0499, 0x20a9, 0x0101, 0x74c8,
- 0x0479, 0x8420, 0x1f04, 0x2a38, 0x70c0, 0x2060, 0x2021, 0x0002,
- 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016, 0x0006,
- 0x2011, 0x4702, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e, 0xa102,
- 0x0338, 0x6012, 0x1128, 0x2011, 0x4704, 0x2204, 0xc0a5, 0x2012,
- 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a42, 0x8421, 0x1d00,
- 0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000, 0x0005,
- 0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, 0x6a1a,
- 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e,
- 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1dbf, 0x000e,
- 0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, 0x0310,
- 0x080c, 0x2575, 0x2300, 0x0002, 0x2a8f, 0x2b0c, 0x2b1a, 0xa282,
- 0x0002, 0x0110, 0x080c, 0x2575, 0x7060, 0x7063, 0x0000, 0x707f,
- 0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2aa6, 0x2aa6,
- 0x2aa8, 0x2ae0, 0x37fb, 0x2aa6, 0x2ae0, 0x2aa6, 0x080c, 0x2575,
- 0x7770, 0x080c, 0x3a8b, 0x7770, 0xa7bc, 0x8f00, 0x080c, 0x3b95,
- 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8dc0, 0x0010,
- 0x2021, 0x8ed0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, 0x2b34,
- 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, 0x8cc0,
- 0x0010, 0x2021, 0x8dd0, 0x0046, 0x2009, 0x0005, 0x2011, 0x0010,
- 0x080c, 0x2b34, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2acb, 0x015e,
- 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x25c9, 0x0804, 0x25c9,
- 0x7770, 0x080c, 0x3b95, 0x6018, 0xa005, 0x0520, 0xd7fc, 0x1118,
- 0x2021, 0x8dc0, 0x0010, 0x2021, 0x8ed0, 0x2009, 0x0005, 0x2011,
- 0x0020, 0x080c, 0x2b34, 0x01b0, 0x0156, 0x20a9, 0x0101, 0xd7fc,
- 0x1118, 0x2021, 0x8cc0, 0x0010, 0x2021, 0x8dd0, 0x0046, 0x2009,
- 0x0005, 0x2011, 0x0020, 0x0481, 0x004e, 0x0118, 0x8420, 0x1f04,
- 0x2afe, 0x015e, 0x0804, 0x25c9, 0x2200, 0x0002, 0x2b11, 0x2b13,
- 0x2b13, 0x080c, 0x2575, 0x7063, 0x0000, 0x70d0, 0xc0c5, 0x70d2,
- 0x0804, 0x25c9, 0x2200, 0x0002, 0x2b21, 0x2b13, 0x2b1f, 0x080c,
- 0x2575, 0x080c, 0x3f4e, 0x7000, 0xa086, 0x0002, 0x1904, 0x3780,
- 0x080c, 0x37e1, 0x6008, 0xa084, 0xfbef, 0x600a, 0x080c, 0x3772,
- 0x0904, 0x3780, 0x0804, 0x25c9, 0x2404, 0xa005, 0x0590, 0x2068,
- 0x2d04, 0x0006, 0x6814, 0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8,
- 0x000e, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4,
- 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff, 0xa205, 0x6822,
- 0x080c, 0x1dbf, 0x2021, 0x4702, 0x241c, 0x8319, 0x2322, 0x6010,
- 0x8001, 0x6012, 0x1128, 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022,
- 0x6008, 0xa084, 0xf9ef, 0x600a, 0x080c, 0x26ca, 0x080c, 0x37e1,
- 0x0005, 0xa085, 0x0001, 0x0ce0, 0x2300, 0x0002, 0x2b73, 0x2b71,
- 0x2bee, 0x080c, 0x2575, 0x78e4, 0xa005, 0x17b0, 0x3208, 0xa18c,
- 0x0800, 0x0118, 0x0104, 0x25c6, 0x0010, 0x0304, 0x25c6, 0x2008,
- 0xa084, 0x0030, 0x1110, 0x0804, 0x324d, 0x78ec, 0xa084, 0x0003,
- 0x0dd0, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
- 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
- 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
- 0x0001, 0x0002, 0x2bd1, 0x2bda, 0x2bc7, 0x2baa, 0x3c4f, 0x3c4f,
- 0x2baa, 0x2be4, 0x080c, 0x2575, 0x7000, 0xa086, 0x0004, 0x1190,
- 0x7060, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000,
- 0x0804, 0x2a85, 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086,
- 0x0004, 0x0d90, 0x79e4, 0x2001, 0x0003, 0x0804, 0x2f3b, 0x6818,
- 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a61, 0x781b, 0x006e,
- 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a61,
- 0x0804, 0x3c2d, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c,
- 0x3a61, 0x781b, 0x00fa, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b,
- 0x001d, 0x080c, 0x3a61, 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f,
- 0x11c0, 0x7000, 0x0002, 0x25c9, 0x2bfb, 0x2bfd, 0x3780, 0x3780,
- 0x3780, 0x2bfb, 0x2bfb, 0x080c, 0x2575, 0x080c, 0x37e1, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x080c, 0x3772, 0x0904, 0x3780, 0x0804,
- 0x25c9, 0x78e4, 0xa005, 0x1b04, 0x2bac, 0x3208, 0xa18c, 0x0800,
- 0x0118, 0x0104, 0x2bac, 0x0010, 0x0304, 0x2bac, 0x2008, 0xa084,
- 0x0030, 0x1118, 0x781b, 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003,
- 0x0dc8, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
- 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
- 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
- 0x0001, 0x0002, 0x2c49, 0x2c4d, 0x2c44, 0x2c42, 0x3c4f, 0x3c4f,
- 0x2c42, 0x3c49, 0x080c, 0x2575, 0x080c, 0x3a67, 0x781b, 0x006e,
- 0x0005, 0x080c, 0x3a67, 0x0804, 0x3c2d, 0x080c, 0x3a67, 0x781b,
- 0x00fa, 0x0005, 0x080c, 0x3a67, 0x781b, 0x00cb, 0x0005, 0x2300,
- 0x0002, 0x2c5e, 0x2c5c, 0x2c60, 0x080c, 0x2575, 0x0804, 0x3405,
- 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0904,
- 0x3405, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3405, 0xa184, 0x0100,
- 0x0d98, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184,
- 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184,
- 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001,
- 0x0001, 0x0002, 0x2c92, 0x2c4d, 0x2bc7, 0x3c0b, 0x3c4f, 0x3c4f,
- 0x3c0b, 0x3c49, 0x080c, 0x3c17, 0x0005, 0xa282, 0x0005, 0x0310,
- 0x080c, 0x2575, 0x7898, 0x2040, 0x2300, 0x0002, 0x2ca1, 0x2ecb,
- 0x2ed5, 0x2200, 0x0002, 0x2cbd, 0x2caa, 0x2cbd, 0x2ca8, 0x2ead,
- 0x080c, 0x2575, 0x789b, 0x0018, 0x78a8, 0x2010, 0xa084, 0x00ff,
- 0xa082, 0x0020, 0x0a04, 0x3a30, 0xa08a, 0x0004, 0x1a04, 0x3a30,
- 0x0002, 0x3a30, 0x3a30, 0x3a30, 0x39e4, 0x789b, 0x0018, 0x79a8,
- 0xa184, 0x0080, 0x0148, 0x0804, 0x3a30, 0x7000, 0xa005, 0x1dd8,
- 0x2011, 0x0004, 0x0804, 0x35b7, 0xa184, 0x00ff, 0xa08a, 0x0010,
- 0x1a04, 0x3a30, 0x0002, 0x2ce5, 0x2ce3, 0x2cf7, 0x2cfb, 0x2da9,
- 0x3a30, 0x3a30, 0x2dab, 0x3a30, 0x3a30, 0x2ea9, 0x2ea9, 0x3a30,
- 0x3a30, 0x3a30, 0x2eab, 0x080c, 0x2575, 0xd6e4, 0x0140, 0x2001,
- 0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00c7, 0x0005, 0x6818,
- 0xd0fc, 0x0118, 0x681b, 0x001d, 0x0c90, 0x0804, 0x3c0b, 0x681b,
- 0x001d, 0x0804, 0x3a5b, 0x6920, 0x6922, 0xa684, 0x1800, 0x1904,
- 0x2d4c, 0x6820, 0xd084, 0x1904, 0x2d54, 0x6818, 0xa086, 0x0008,
- 0x1110, 0x681b, 0x0000, 0xd6d4, 0x0568, 0xd6bc, 0x0558, 0x7083,
- 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0718, 0xa08a,
- 0x000c, 0x7182, 0x2001, 0x000c, 0x800c, 0x7186, 0x789b, 0x0061,
- 0x78aa, 0x0156, 0x0136, 0x0146, 0x0016, 0x3208, 0xa18c, 0x0600,
- 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x001e, 0x789b,
- 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e,
- 0x013e, 0x015e, 0x6038, 0xa005, 0x1150, 0x681c, 0xa084, 0x000e,
- 0x0904, 0x3a5b, 0x080c, 0x3a6d, 0x782b, 0x3008, 0x0010, 0x8001,
- 0x603a, 0x781b, 0x0071, 0x0005, 0xd6e4, 0x0130, 0x781b, 0x0083,
- 0x0005, 0x781b, 0x0083, 0x0005, 0xa684, 0x0060, 0x0dd0, 0xd6dc,
- 0x0dc0, 0xd6fc, 0x01a0, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8,
- 0x78d0, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98,
- 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4,
- 0x0118, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148,
- 0x0006, 0x080c, 0x3f4e, 0x080c, 0x4208, 0x000e, 0x781b, 0x0080,
- 0x0005, 0xa006, 0x080c, 0x42e8, 0x6ab0, 0x69ac, 0x6c98, 0x6b94,
- 0x2200, 0xa105, 0x0120, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa,
- 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130,
- 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, 0x0080, 0x0005, 0x781b, 0x0080,
- 0x2200, 0xa115, 0x1118, 0x080c, 0x4208, 0x0005, 0x080c, 0x4235,
- 0x0005, 0x080c, 0x2575, 0x0804, 0x2e3f, 0x00c6, 0x7054, 0x2060,
- 0x6920, 0xa18c, 0xecff, 0x6922, 0x6000, 0xa084, 0xcfdf, 0x6002,
- 0x080c, 0x3917, 0xa006, 0x2040, 0x2038, 0x080c, 0x39bf, 0x0804,
- 0x2e33, 0x00c6, 0x7054, 0x2060, 0x2c48, 0x7aa8, 0xa294, 0x00ff,
- 0xa286, 0x0004, 0x11d8, 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000,
- 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x391a,
- 0x080c, 0x39bf, 0x0804, 0x2e33, 0xa18c, 0xecff, 0x6922, 0x6104,
- 0xa18c, 0xffdd, 0x6106, 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003,
- 0x01d0, 0x6104, 0xa184, 0x0010, 0x0548, 0x080c, 0x3b91, 0x080c,
- 0x399a, 0x88ff, 0x0518, 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa,
- 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005,
- 0x781b, 0x0082, 0x0005, 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff,
- 0x6922, 0x6000, 0xc0ec, 0x6002, 0x2039, 0x0000, 0x2041, 0x0000,
- 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x39bf, 0xa286, 0x0001,
- 0x0158, 0x6104, 0xa184, 0x0008, 0x01b0, 0x080c, 0x3b91, 0x080c,
- 0x38b8, 0x88ff, 0x1980, 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c,
- 0xfeff, 0x6922, 0x6000, 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006,
- 0x2010, 0x080c, 0x391a, 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b,
- 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x0804, 0x3a57, 0x2808,
- 0x789b, 0x0080, 0x2019, 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286,
- 0x0001, 0x11b8, 0x2300, 0xa102, 0xa086, 0x0001, 0x0904, 0x2dad,
- 0x7ca8, 0xa4a4, 0x00ff, 0xa480, 0x0002, 0xa300, 0x2018, 0xa102,
- 0x0a04, 0x2dc1, 0x0904, 0x2dc1, 0x24a8, 0x7aa8, 0x1f04, 0x2e5d,
- 0x0c18, 0xa284, 0x00f0, 0xa082, 0x0020, 0x06b8, 0x2200, 0xa082,
- 0x0021, 0x1698, 0x7aa8, 0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0,
- 0xa286, 0x0023, 0x0950, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
- 0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a,
- 0x78a0, 0xa005, 0x0904, 0x2e34, 0x20a8, 0x7998, 0x789b, 0x0060,
- 0x78aa, 0x2011, 0x0080, 0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa,
- 0x7a98, 0x1f04, 0x2e8b, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b,
- 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x8318, 0x2100, 0xa302,
- 0x0a04, 0x2e44, 0xa284, 0x0080, 0x1904, 0x3a5b, 0x78a0, 0xa005,
- 0x08c8, 0x0804, 0x3a5b, 0x0804, 0x3a30, 0x7054, 0xa04d, 0x789b,
- 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c,
- 0x2575, 0x7aa8, 0xa294, 0x00ff, 0x784b, 0x0008, 0x78a8, 0xa084,
- 0x00ff, 0xa08a, 0x0005, 0x1a04, 0x3a30, 0x0002, 0x3a30, 0x382f,
- 0x3a30, 0x394a, 0x3d59, 0xa282, 0x0000, 0x1110, 0x080c, 0x2575,
- 0x080c, 0x3a61, 0x781b, 0x0082, 0x0005, 0xa282, 0x0003, 0x1110,
- 0x080c, 0x2575, 0xd4fc, 0x11d0, 0x7060, 0xa005, 0x0110, 0x080c,
- 0x2575, 0x6f14, 0x7772, 0xa7bc, 0x8f00, 0x080c, 0x3b95, 0x6008,
- 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x1db0, 0x080c,
- 0x3a64, 0x7063, 0x0002, 0x701f, 0x0009, 0x0010, 0x080c, 0x3a70,
- 0x781b, 0x0082, 0x0005, 0xa282, 0x0004, 0x0310, 0x080c, 0x2575,
- 0x2300, 0x0002, 0x2f05, 0x309b, 0x30d7, 0xa286, 0x0003, 0x0598,
- 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d0, 0xd1b4, 0x0528, 0xd1bc,
- 0x1518, 0x2001, 0x4701, 0x2004, 0xd0c4, 0x11f0, 0x7868, 0xa084,
- 0x00ff, 0x11d0, 0xa282, 0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300,
- 0x781b, 0x0059, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
- 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
- 0x00de, 0x2001, 0x0000, 0x0058, 0x783b, 0x1300, 0x781b, 0x0057,
- 0x2001, 0x0000, 0x0020, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x7046,
- 0x68a0, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f,
- 0x0002, 0x307c, 0x2f56, 0x2f53, 0x31a7, 0x3232, 0x25c9, 0x2f51,
- 0x2f51, 0x080c, 0x2575, 0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120,
- 0x7044, 0xa086, 0x0014, 0x11e8, 0x080c, 0x3f4e, 0x2009, 0x0000,
- 0x6818, 0xd0fc, 0x0108, 0x7044, 0xa086, 0x0014, 0x0168, 0x6818,
- 0xa086, 0x0008, 0x1904, 0x303e, 0x7858, 0xd09c, 0x0904, 0x303e,
- 0x6820, 0xd0ac, 0x0904, 0x303e, 0x681b, 0x0014, 0x2009, 0x0002,
- 0x04a8, 0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158,
- 0x6008, 0xc0a4, 0x600a, 0x080c, 0x3772, 0x0540, 0x080c, 0x37e1,
- 0x080c, 0x3f4e, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, 0xa005,
- 0x0d78, 0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820,
- 0xd084, 0x0904, 0x25c9, 0xc084, 0x6822, 0x080c, 0x26bf, 0x7058,
- 0x00c6, 0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005,
- 0x2d00, 0x1108, 0x6002, 0x6006, 0x0804, 0x25c9, 0x0016, 0x81ff,
- 0x15f0, 0x7000, 0xa086, 0x0030, 0x05d0, 0x71d0, 0xd1bc, 0x15b8,
- 0xd1b4, 0x11e8, 0x705c, 0xa005, 0x1590, 0x70a0, 0xa086, 0x0001,
- 0x0570, 0x7003, 0x0000, 0x0046, 0x0056, 0x0076, 0x0066, 0x00c6,
- 0x00d6, 0x080c, 0x25f1, 0x00de, 0x00ce, 0x006e, 0x007e, 0x005e,
- 0x004e, 0x71d0, 0xd1b4, 0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c,
- 0x3c5b, 0x11a8, 0x781b, 0x0068, 0x00d6, 0x70b8, 0xa06d, 0x68b4,
- 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4,
- 0x71d2, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x00de, 0x080c,
- 0x30ff, 0x001e, 0x81ff, 0x0904, 0x303e, 0xa684, 0xdf00, 0x681e,
- 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x1904, 0x303f, 0x6818,
- 0xa086, 0x0014, 0x1130, 0x2008, 0xd6e4, 0x0118, 0x7868, 0xa08c,
- 0x00ff, 0x080c, 0x3a7a, 0x080c, 0x26ca, 0x6820, 0xd0dc, 0x1578,
- 0x8717, 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xb284, 0x0600,
- 0x0118, 0xa290, 0x4bc0, 0x0010, 0xa290, 0x4c40, 0xa290, 0x0000,
- 0x221c, 0xd3c4, 0x0170, 0x6820, 0xd0e4, 0x0128, 0xa084, 0xefff,
- 0x6822, 0xc3ac, 0x2312, 0x8210, 0x2204, 0xa085, 0x0038, 0x2012,
- 0x8211, 0xd3d4, 0x0138, 0x68a0, 0xd0c4, 0x1120, 0x080c, 0x3167,
- 0x0804, 0x25c9, 0x6008, 0xc08d, 0x600a, 0x0008, 0x692a, 0x6916,
- 0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e,
- 0x6410, 0x84ff, 0x0168, 0x2009, 0x4702, 0x2104, 0x8001, 0x200a,
- 0x8421, 0x6412, 0x1128, 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022,
- 0x6018, 0xa005, 0x0118, 0x8001, 0x601a, 0x1118, 0x6008, 0xc0a4,
- 0x600a, 0x6820, 0xd084, 0x1130, 0x6800, 0xa005, 0x1108, 0x6002,
- 0x6006, 0x0020, 0x7058, 0x2060, 0x6800, 0x6002, 0x2061, 0x4700,
- 0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a,
- 0x0110, 0x2d02, 0x0008, 0x616e, 0x7200, 0xa286, 0x0030, 0x0158,
- 0xa286, 0x0040, 0x1904, 0x25c9, 0x7003, 0x0002, 0x7048, 0x2068,
- 0x68c4, 0x2060, 0x0005, 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc,
- 0x703e, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80,
- 0x0009, 0x7042, 0x0005, 0xa282, 0x0004, 0x0210, 0x080c, 0x2575,
- 0x2200, 0x0002, 0x30a6, 0x30b5, 0x30c1, 0x30b5, 0xa586, 0x1300,
- 0x0160, 0xa586, 0x8300, 0x1d90, 0x7003, 0x0000, 0x6018, 0x8001,
- 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x7000, 0xa086, 0x0005,
- 0x0128, 0x080c, 0x3a61, 0x781b, 0x0082, 0x0005, 0x781b, 0x0083,
- 0x0005, 0x7890, 0x8007, 0x8001, 0xa084, 0x0007, 0xa080, 0x0018,
- 0x789a, 0x79a8, 0xa18c, 0x00ff, 0xa186, 0x0003, 0x0128, 0xa186,
- 0x0000, 0x0110, 0x0804, 0x3a30, 0x781b, 0x0083, 0x0005, 0x6820,
- 0xc095, 0x6822, 0x82ff, 0x1118, 0x080c, 0x3a61, 0x0030, 0x8211,
- 0x0110, 0x080c, 0x2575, 0x080c, 0x3a70, 0x781b, 0x0082, 0x0005,
- 0x080c, 0x3c6e, 0x7830, 0xa084, 0x00c0, 0x1170, 0x0016, 0x3208,
- 0xa18c, 0x0800, 0x001e, 0x0118, 0x0104, 0x30fc, 0x0010, 0x0304,
- 0x30fc, 0x791a, 0xa006, 0x0005, 0xa085, 0x0001, 0x0005, 0xa684,
- 0x0060, 0x1130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3166,
- 0xd6dc, 0x1198, 0x68b4, 0xd0dc, 0x1180, 0x6998, 0x6a94, 0x692e,
- 0x6a32, 0x7044, 0xa005, 0x1130, 0x2200, 0xa105, 0x0904, 0x3f4e,
- 0x7047, 0x0015, 0x0804, 0x3f4e, 0x0005, 0xd6ac, 0x01f0, 0xd6f4,
- 0x0130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804, 0x3f4e, 0x68b4,
- 0xa084, 0x4000, 0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110,
- 0x7047, 0x0015, 0xd6dc, 0x1128, 0x68b4, 0xd0dc, 0x0110, 0x6ca8,
- 0x6da4, 0x6c2e, 0x6d32, 0x0804, 0x3f4e, 0xd6f4, 0x0130, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x0804, 0x3f4e, 0x68b4, 0xa084, 0x4800,
- 0xa635, 0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015,
- 0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291,
- 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x1110, 0x0804, 0x3f4e,
- 0x7000, 0xa086, 0x0006, 0x0110, 0x0804, 0x3f4e, 0x0005, 0x6946,
- 0x6008, 0xc0cd, 0xd3cc, 0x0108, 0xc08d, 0x600a, 0x6818, 0x683a,
- 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30, 0x692c,
- 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837, 0x0020,
- 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0002, 0x25c9, 0x3196,
- 0x3190, 0x318e, 0x318e, 0x318e, 0x318e, 0x318e, 0x080c, 0x2575,
- 0x6820, 0xd084, 0x1118, 0x080c, 0x37c7, 0x0030, 0x7058, 0x2c50,
- 0x2060, 0x6800, 0x6002, 0x2a60, 0xaea0, 0x0017, 0x2404, 0xa005,
- 0x0110, 0x2020, 0x0cd8, 0x2d22, 0x206b, 0x0000, 0x0005, 0x080c,
- 0x37cd, 0x080c, 0x37e1, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000,
- 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916, 0x2009,
- 0x0000, 0xae86, 0x4740, 0x0110, 0x2009, 0x0001, 0x080c, 0x431f,
- 0xd6dc, 0x01c8, 0x691c, 0xc1ed, 0x691e, 0x6828, 0xa082, 0x000e,
- 0x0290, 0x6848, 0xa084, 0x000f, 0xa086, 0x000b, 0x1160, 0x685c,
- 0xa086, 0x0047, 0x1140, 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1118,
- 0x2700, 0x080c, 0x249e, 0x6818, 0xd0fc, 0x0140, 0x681b, 0x0000,
- 0x7868, 0xa08c, 0x00ff, 0x0110, 0x681b, 0x001e, 0xaea0, 0x0017,
- 0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060,
- 0x6000, 0xd0a4, 0x0580, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051,
- 0x0020, 0x00d6, 0x00f6, 0x0156, 0x0146, 0x2079, 0x4700, 0x080c,
- 0x1bb2, 0x014e, 0x015e, 0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101,
- 0x0026, 0x2204, 0xa06d, 0x0140, 0x6814, 0xa706, 0x0110, 0x6800,
- 0x0cc8, 0x6820, 0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80,
- 0x00de, 0x7063, 0x0003, 0x707b, 0x0000, 0x7772, 0x707f, 0x000f,
- 0x71d0, 0xc1c4, 0x71d2, 0x6818, 0xa086, 0x0002, 0x1138, 0x6817,
- 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e, 0x080c, 0x1dbf,
- 0x0804, 0x25c9, 0x7cd8, 0x7ddc, 0x7fd0, 0x080c, 0x30ff, 0x682b,
- 0x0000, 0x789b, 0x000e, 0x6f14, 0x080c, 0x3c72, 0xa08c, 0x00ff,
- 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00,
- 0x691e, 0x7063, 0x0000, 0x0804, 0x25c9, 0x7000, 0xa005, 0x1110,
- 0x0804, 0x25c9, 0xa006, 0x080c, 0x3f4e, 0x6920, 0xd1ac, 0x1110,
- 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820,
- 0xa084, 0x00ff, 0x6822, 0x7000, 0x0002, 0x25c9, 0x326f, 0x326f,
- 0x3272, 0x3272, 0x3272, 0x326d, 0x326d, 0x080c, 0x2575, 0x6818,
- 0x0804, 0x2f3b, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804,
- 0x3795, 0x2300, 0x0002, 0x327e, 0x3280, 0x32ce, 0x080c, 0x2575,
- 0xd6fc, 0x1904, 0x2d5b, 0x7000, 0xa00d, 0x0002, 0x25c9, 0x3290,
- 0x3290, 0x32ba, 0x3290, 0x32cb, 0x328e, 0x328e, 0x080c, 0x2575,
- 0xa684, 0x0060, 0x0538, 0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4,
- 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002,
- 0x0148, 0x080c, 0x3f4e, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c,
- 0x4235, 0x0010, 0x080c, 0x4208, 0x781b, 0x0083, 0x71d0, 0xd1b4,
- 0x1904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d, 0x0005,
- 0xd6ec, 0x09f0, 0x6818, 0xd0fc, 0x0170, 0xd6f4, 0x1130, 0x681b,
- 0x0015, 0x781b, 0x0083, 0x0804, 0x25c6, 0x681b, 0x0007, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x080c, 0x3c17, 0x0005, 0x080c, 0x2575,
- 0x2300, 0x0002, 0x32d7, 0x32f9, 0x3351, 0x080c, 0x2575, 0x7000,
- 0x0002, 0x32e1, 0x32e3, 0x32ea, 0x32e1, 0x32e1, 0x32e1, 0x32e1,
- 0x32e1, 0x080c, 0x2575, 0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c,
- 0x4235, 0x0010, 0x080c, 0x4208, 0x681c, 0xc0b4, 0x681e, 0x70d0,
- 0xd0b4, 0x1904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d,
- 0x0005, 0xd6fc, 0x1904, 0x3341, 0x7000, 0xa00d, 0x0002, 0x25c9,
- 0x330f, 0x3309, 0x3339, 0x330f, 0x333e, 0x3307, 0x3307, 0x080c,
- 0x2575, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684,
- 0x0060, 0x0538, 0xa086, 0x0060, 0x1510, 0xa6b4, 0xbfbf, 0xc6ed,
- 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0148, 0x080c, 0x3f4e, 0x69ac,
- 0x68b0, 0xa115, 0x0118, 0x080c, 0x4235, 0x0010, 0x080c, 0x4208,
- 0x781b, 0x0083, 0x681c, 0xc0b4, 0x681e, 0x71d0, 0xd1b4, 0x1904,
- 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904, 0x260d, 0x0005, 0xd6ec,
- 0x09f0, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, 0x781b, 0x00fb,
- 0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302,
- 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0083,
- 0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, 0x0083, 0x0804,
- 0x25c6, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x1150,
- 0xa484, 0x0200, 0x0108, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0083,
- 0x0804, 0x25c6, 0x6820, 0xc095, 0x6822, 0x080c, 0x3c02, 0xc6dd,
- 0x080c, 0x3a61, 0x781b, 0x0082, 0x0804, 0x25c6, 0x2300, 0x0002,
- 0x337b, 0x337d, 0x337f, 0x080c, 0x2575, 0x0804, 0x3a5b, 0x7d98,
- 0xd6d4, 0x15a8, 0x79e4, 0xd1ac, 0x0130, 0x78ec, 0xa084, 0x0003,
- 0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
- 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120, 0x78ec, 0xa084,
- 0x0003, 0x1120, 0x2001, 0x0014, 0x0804, 0x2f3b, 0x7884, 0xd0fc,
- 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
- 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
- 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x04c2, 0x7a90,
- 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff, 0x0568, 0x789b,
- 0x0080, 0x7ba8, 0xa384, 0x0001, 0x11d0, 0x7ba8, 0x7ba8, 0xa386,
- 0x0004, 0x1118, 0x2009, 0xffdf, 0x0058, 0xa386, 0x0001, 0x1118,
- 0x2009, 0xfff7, 0x0028, 0xa386, 0x0003, 0x1148, 0x2009, 0xffef,
- 0x00c6, 0x7054, 0x2060, 0x6004, 0xa104, 0x6006, 0x00ce, 0x789b,
- 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b, 0x3009,
- 0x6920, 0xa18c, 0xecff, 0x6922, 0x7d9a, 0x0804, 0x3c0b, 0x2bd1,
- 0x2bda, 0x33f9, 0x33ff, 0x33f7, 0x33f7, 0x3c0b, 0x3c0b, 0x080c,
- 0x2575, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3c11, 0x6920,
- 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3c0b, 0x79e4, 0xa184, 0x0030,
- 0x0120, 0x78ec, 0xa084, 0x0003, 0x1570, 0x7000, 0xa086, 0x0004,
- 0x1190, 0x7060, 0xa086, 0x0002, 0x1130, 0x2011, 0x0002, 0x2019,
- 0x0000, 0x0804, 0x2a85, 0x7060, 0xa086, 0x0006, 0x0db0, 0x7060,
- 0xa086, 0x0004, 0x0d90, 0x7000, 0xa086, 0x0000, 0x0904, 0x25c6,
- 0x6920, 0xa184, 0x0420, 0x0128, 0xc1d4, 0x6922, 0x6818, 0x0804,
- 0x2f3b, 0x6818, 0xa08e, 0x0002, 0x0120, 0xc0fd, 0x681a, 0x2001,
- 0x0014, 0x0804, 0x2f3b, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
- 0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000,
- 0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007,
- 0x0010, 0x2001, 0x0001, 0x0002, 0x3c0b, 0x3c0b, 0x345c, 0x3c0b,
- 0x3c4f, 0x3c4f, 0x3c0b, 0x3c0b, 0xd6bc, 0x0570, 0x7180, 0x81ff,
- 0x0558, 0xa182, 0x000d, 0x1318, 0x7083, 0x0000, 0x0028, 0xa182,
- 0x000c, 0x7082, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa, 0x0156,
- 0x0136, 0x0146, 0x7084, 0x8114, 0xa210, 0x7286, 0xa080, 0x000b,
- 0xad00, 0x2098, 0xb284, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010,
- 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e,
- 0x013e, 0x015e, 0x0804, 0x3c11, 0xd6d4, 0x1904, 0x34cf, 0x6820,
- 0xd084, 0x0904, 0x3c11, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0120,
- 0xa086, 0x0060, 0x1108, 0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b,
- 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a,
- 0x78aa, 0x8008, 0x810c, 0x0904, 0x37f6, 0xa18c, 0x00f8, 0x1904,
- 0x37f6, 0x0156, 0x0136, 0x0146, 0x0016, 0x20a1, 0x012b, 0x3208,
- 0xa18c, 0x0600, 0x0110, 0x20a1, 0x022b, 0x001e, 0x789b, 0x0000,
- 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e,
- 0x015e, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0804, 0x3c11, 0x6818,
- 0xd0fc, 0x0110, 0x681b, 0x0008, 0x080c, 0x3a61, 0x781b, 0x00ed,
- 0x0005, 0x2300, 0x0002, 0x34e0, 0x359d, 0x34de, 0x080c, 0x2575,
- 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x1528, 0x7200, 0xa286, 0x0003,
- 0x0904, 0x2f09, 0x71d0, 0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001,
- 0x4701, 0x2004, 0xd0c4, 0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b,
- 0x0059, 0x70b8, 0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6,
- 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
- 0x00de, 0x0030, 0x7200, 0x0020, 0x783b, 0x1800, 0x781b, 0x0057,
- 0xa284, 0x000f, 0x0002, 0x3588, 0x3545, 0x351d, 0x2f38, 0x351b,
- 0x3588, 0x351b, 0x351b, 0x080c, 0x2575, 0x681c, 0xd0ec, 0x0118,
- 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006,
- 0xa005, 0x1108, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084,
- 0x000e, 0x1120, 0x71c8, 0xa188, 0x0100, 0x0028, 0x7030, 0x68ba,
- 0x713c, 0x70c8, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715a, 0xd6dc,
- 0x1120, 0xc6fc, 0x6eb6, 0x0804, 0x3588, 0x6eb6, 0xa684, 0x0060,
- 0x1120, 0xa684, 0x7fff, 0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684,
- 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898, 0x68aa, 0x080c, 0x3f4e,
- 0x0478, 0xd6ac, 0x0140, 0xa006, 0x080c, 0x3f4e, 0x2408, 0x2510,
- 0x69aa, 0x6aa6, 0x0068, 0x2408, 0x2510, 0x2700, 0x8007, 0xa084,
- 0x007f, 0xa108, 0xa291, 0x0000, 0x69aa, 0x6aa6, 0x080c, 0x3f4e,
- 0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac,
- 0x1138, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000,
- 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
- 0x7000, 0xa086, 0x0030, 0x1904, 0x25c9, 0x7003, 0x0002, 0x70b8,
- 0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00,
- 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0xa586, 0x8800, 0x1148,
- 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
- 0x600a, 0x0804, 0x3a5b, 0x7043, 0x0000, 0xa282, 0x0006, 0x0310,
- 0x080c, 0x2575, 0x2300, 0x0002, 0x35b7, 0x35c8, 0x35d2, 0x2200,
- 0x0002, 0x35bf, 0x3a5b, 0x35c1, 0x35bf, 0x3603, 0x3651, 0x080c,
- 0x2575, 0x7a80, 0xa294, 0x0f00, 0x080c, 0x36a5, 0x0804, 0x3a30,
- 0x00c1, 0x0002, 0x3a5b, 0x35d0, 0x35d0, 0x3603, 0x35d0, 0x3a5b,
- 0x080c, 0x2575, 0x0071, 0x0002, 0x35dc, 0x35da, 0x35da, 0x35dc,
- 0x35da, 0x35dc, 0x080c, 0x2575, 0x080c, 0x3a70, 0x781b, 0x0082,
- 0x0005, 0x7000, 0xa086, 0x0002, 0x1150, 0x080c, 0x37e1, 0x0010,
- 0x080c, 0x3f4e, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000,
- 0xa086, 0x0003, 0x0da8, 0x7003, 0x0005, 0x2001, 0x8ee0, 0xae8e,
- 0x4740, 0x0110, 0x2001, 0x8f12, 0x2068, 0x704a, 0xad80, 0x0009,
- 0x7042, 0x2200, 0x0005, 0x7000, 0xa086, 0x0002, 0x1158, 0x70d0,
- 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x0038, 0x080c,
- 0x3f4e, 0x0020, 0x7000, 0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001,
- 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
- 0xa215, 0x2069, 0x8dc0, 0xb284, 0x0600, 0x1118, 0xc2fd, 0x2069,
- 0x8ed0, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206,
- 0x0120, 0x6800, 0x0cb8, 0x080c, 0x36a5, 0x6eb4, 0x7e5a, 0x6920,
- 0xa184, 0x0c00, 0x0904, 0x36cb, 0x7060, 0xa086, 0x0006, 0x1128,
- 0x7070, 0xa206, 0x1110, 0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad,
- 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a67, 0x0804,
- 0x36cb, 0x7200, 0xa286, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2,
- 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x0030, 0x080c, 0x3f4e, 0x0018,
- 0xa286, 0x0003, 0x0dd0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00,
- 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0xae86, 0x4740,
- 0x0108, 0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8,
- 0xa168, 0x2d04, 0x2d08, 0x715a, 0xa06d, 0x0128, 0x6814, 0xa206,
- 0x0118, 0x6800, 0x0cb8, 0x0409, 0x6eb4, 0x6920, 0xa184, 0x0c00,
- 0x0904, 0x36cb, 0xd0dc, 0x0178, 0x7060, 0xa086, 0x0004, 0x1140,
- 0x7070, 0xa206, 0x1128, 0x7074, 0xa306, 0x1110, 0x7062, 0x707a,
- 0x080c, 0x3a6d, 0x0480, 0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922,
- 0x080c, 0x3a67, 0x707b, 0x0000, 0x0430, 0x7003, 0x0005, 0xb284,
- 0x0600, 0x0118, 0x2001, 0x8ee0, 0x0010, 0x2001, 0x8f12, 0x2068,
- 0x704a, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04,
- 0x36b4, 0x015e, 0xb284, 0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd,
- 0x6a16, 0xad80, 0x0009, 0x7042, 0x68b7, 0x0700, 0x6823, 0x0800,
- 0x6827, 0x0003, 0x0005, 0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x3712,
- 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda,
- 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed,
- 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009,
- 0x0082, 0x2019, 0x0000, 0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c,
- 0x4208, 0x0470, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305,
- 0x01f8, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108,
- 0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0083, 0xd69c, 0x0128, 0x2011,
- 0x0082, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c,
- 0x4235, 0x0070, 0x2019, 0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff,
- 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0110, 0x2009, 0x0082, 0x791a,
- 0x68c0, 0x7056, 0x2d00, 0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001,
- 0x4701, 0x2004, 0xd0c4, 0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc,
- 0x0548, 0x7a80, 0xa294, 0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0,
- 0xa504, 0x1558, 0x70d6, 0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001,
- 0x852c, 0x0218, 0x8633, 0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594,
- 0xff00, 0x0130, 0x2011, 0x0008, 0x852f, 0x0c81, 0x8637, 0x0008,
- 0x0c69, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0170, 0x72da,
- 0x76d6, 0x0058, 0x7a80, 0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0,
- 0x78e0, 0xa534, 0x0da8, 0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x25c6,
- 0x2300, 0xa405, 0x0904, 0x25c6, 0x70a0, 0xa086, 0x0001, 0x1904,
- 0x260d, 0x0005, 0x6020, 0xa005, 0x0150, 0x8001, 0x6022, 0x6008,
- 0xa085, 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x0005,
- 0xa006, 0x080c, 0x3f4e, 0x7000, 0xa086, 0x0002, 0x0120, 0x7060,
- 0xa086, 0x0005, 0x1150, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b,
- 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f,
- 0x0002, 0x25c9, 0x37a6, 0x37a3, 0x37c3, 0x37af, 0x25c9, 0x37a1,
- 0x37a1, 0x080c, 0x2575, 0x0449, 0x0411, 0x0028, 0x0431, 0x7058,
- 0x2060, 0x6800, 0x6002, 0x080c, 0x1dbf, 0x0804, 0x25c9, 0x7060,
- 0x7063, 0x0000, 0x707f, 0x0000, 0x0002, 0x37bf, 0x37bf, 0x37bd,
- 0x37bd, 0x37bd, 0x37bf, 0x37bd, 0x37bf, 0x0804, 0x2a9a, 0x7063,
- 0x0000, 0x0804, 0x25c9, 0x681b, 0x0000, 0x0804, 0x31a7, 0x6800,
- 0xa005, 0x1108, 0x6002, 0x6006, 0x0005, 0x6410, 0x84ff, 0x0168,
- 0x2009, 0x4702, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128,
- 0x2021, 0x4704, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a,
- 0x0005, 0x6018, 0xa005, 0x0110, 0x8001, 0x601a, 0x0005, 0x080c,
- 0x3c6e, 0x681b, 0x0018, 0x0490, 0x080c, 0x3c6e, 0x681b, 0x0019,
- 0x0468, 0x080c, 0x3c6e, 0x681b, 0x001a, 0x0440, 0x080c, 0x3c6e,
- 0x681b, 0x0003, 0x0418, 0x7770, 0x080c, 0x3b95, 0x7174, 0xa18c,
- 0x00ff, 0x3210, 0xa294, 0x0600, 0x0118, 0xa1e8, 0x8cc0, 0x0010,
- 0xa1e8, 0x8dd0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x1118, 0x707a,
- 0x0804, 0x25c9, 0x6814, 0x7270, 0xa206, 0x0110, 0x6800, 0x0c98,
- 0x6800, 0x200a, 0x681b, 0x0005, 0x707b, 0x0000, 0x080c, 0x37cd,
- 0x6820, 0xd084, 0x1110, 0x080c, 0x37c7, 0x080c, 0x37e1, 0x681f,
- 0x0000, 0x6823, 0x0020, 0x080c, 0x1dbf, 0x0804, 0x25c9, 0xa282,
- 0x0003, 0x1904, 0x3a35, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4,
- 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922,
- 0xa6b4, 0x00ff, 0x0530, 0xa682, 0x0018, 0x0218, 0x0110, 0x2031,
- 0x0018, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x2041,
- 0x0000, 0x080c, 0x3aee, 0x0118, 0x080c, 0x391a, 0x00a0, 0x080c,
- 0x3aba, 0x080c, 0x3917, 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695,
- 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082,
- 0x0005, 0x080c, 0x3917, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071,
- 0x0005, 0x781b, 0x0083, 0x0005, 0x00c6, 0x7054, 0x2060, 0x6100,
- 0xd1e4, 0x0598, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x0018,
- 0x0218, 0x0110, 0x2011, 0x0018, 0x2600, 0xa202, 0x1208, 0x2230,
- 0xa686, 0x0010, 0x1108, 0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec,
- 0xd0e4, 0x0130, 0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028,
- 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208,
- 0x2228, 0x080c, 0x3abe, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c,
- 0x3aee, 0x0118, 0x080c, 0x391a, 0x0020, 0x080c, 0x3aba, 0x080c,
- 0x3917, 0x7858, 0xc095, 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005,
- 0x00c6, 0x2960, 0x6000, 0xd0e4, 0x1188, 0xd0b4, 0x1150, 0x6010,
- 0xa084, 0x000f, 0x1130, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce,
- 0x0005, 0x2011, 0x0032, 0x2019, 0x0000, 0x00f0, 0x68a0, 0xd0cc,
- 0x1dc0, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282,
- 0x000b, 0x1218, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210,
- 0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x0018,
- 0x0218, 0x0110, 0x2019, 0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003,
- 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5,
- 0x6822, 0x080c, 0x3a7a, 0x00ce, 0x0005, 0x00c6, 0x2960, 0x6104,
- 0xa18c, 0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0000,
- 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
- 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x00ce, 0x0005, 0xa006,
- 0x2030, 0x2010, 0x00c6, 0x7154, 0x2160, 0x2018, 0x2008, 0xa084,
- 0xffe0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4,
- 0xa084, 0x7770, 0xa18c, 0x000f, 0xa105, 0x2029, 0x4705, 0x252c,
- 0xd5cc, 0x0140, 0xd3a4, 0x0110, 0xa085, 0x0800, 0xd3fc, 0x0110,
- 0xa085, 0x8080, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637,
- 0x8204, 0x8004, 0xa605, 0x600e, 0x6004, 0xa084, 0xffd5, 0x6006,
- 0x00ce, 0x0005, 0xa282, 0x0002, 0x1904, 0x3a3f, 0x7aa8, 0x6920,
- 0xc1bd, 0x6922, 0xd1cc, 0x0568, 0xc1cc, 0x6922, 0xa294, 0x00ff,
- 0xa282, 0x0002, 0x1a04, 0x3a30, 0x080c, 0x39c1, 0x080c, 0x3917,
- 0xa980, 0x0001, 0x200c, 0x080c, 0x3b91, 0x080c, 0x38b8, 0x88ff,
- 0x0178, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
- 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005,
- 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083,
- 0x0005, 0xa282, 0x0002, 0x1218, 0xa284, 0x0001, 0x0140, 0x7154,
- 0xa188, 0x0000, 0x210c, 0xd1ec, 0x1110, 0x2011, 0x0000, 0x080c,
- 0x3aac, 0x0479, 0x080c, 0x3917, 0x7858, 0xc095, 0x785a, 0x781b,
- 0x0082, 0x0005, 0x00c6, 0x0026, 0x2960, 0x6000, 0x2011, 0x0001,
- 0xd0ec, 0x1158, 0xd0bc, 0x1138, 0x6014, 0xd0b4, 0x1120, 0xc1a4,
- 0x6106, 0xa006, 0x0088, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x080c, 0x3a7a,
- 0x6820, 0xa085, 0x0200, 0x6822, 0x002e, 0x00ce, 0x0005, 0x8807,
- 0xa715, 0x00c6, 0x2009, 0x0000, 0x7054, 0x2060, 0x82ff, 0x0110,
- 0x2009, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084,
- 0xff9f, 0xa105, 0xc0ec, 0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4,
- 0x0110, 0xa085, 0x0020, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084,
- 0xffef, 0x6006, 0x00ce, 0x0005, 0x0006, 0x7000, 0xa086, 0x0003,
- 0x0110, 0x000e, 0x0010, 0x000e, 0x0498, 0xd6ac, 0x0588, 0x7888,
- 0xa084, 0x0040, 0x0568, 0x7bb8, 0x8307, 0xa084, 0x007f, 0x1518,
- 0x8207, 0xa084, 0x00ff, 0x0904, 0x3a57, 0xa09a, 0x0004, 0x1a04,
- 0x3a57, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291, 0x0000,
- 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, 0x42e8, 0x781b, 0x0080,
- 0xb284, 0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001,
- 0x080c, 0x419a, 0x0005, 0x080c, 0x2575, 0x781b, 0x0080, 0x0005,
- 0x781b, 0x0083, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031,
- 0x0000, 0xa006, 0x2010, 0x080c, 0x391a, 0x080c, 0x39bf, 0x7e58,
- 0x080c, 0x3a73, 0x781b, 0x0082, 0x0005, 0x0cd1, 0x6820, 0xc0c4,
- 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c, 0x3944, 0x00b0, 0x0c81,
- 0x6820, 0xc0cc, 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c, 0x39de,
- 0x0060, 0x0c31, 0x6820, 0xa084, 0xecff, 0x6822, 0x00c6, 0x7054,
- 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006, 0x00ce, 0x0005, 0x0049,
- 0x781b, 0x0082, 0x0005, 0x6827, 0x0002, 0x0049, 0x781b, 0x0082,
- 0x0005, 0x2001, 0x0005, 0x0088, 0x2001, 0x000c, 0x0070, 0x6820,
- 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040, 0x2001, 0x000d, 0x0028,
- 0x2001, 0x0009, 0x0010, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa,
- 0xc69d, 0x7e5a, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6,
- 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
- 0x601a, 0x00ce, 0x0005, 0x0076, 0x873f, 0xa7bc, 0x000f, 0x873b,
- 0x873b, 0x8703, 0xa0e0, 0x4bc0, 0xae8e, 0x4740, 0x0110, 0xa0e0,
- 0x4c40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x7fe0, 0x78ae,
- 0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6, 0x6016, 0x6004, 0xa085,
- 0x0038, 0x6006, 0x007e, 0x0005, 0x789b, 0x0080, 0x78ab, 0x0001,
- 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
- 0x0004, 0x0800, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0080,
- 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa,
- 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, 0x3a7a, 0x0156, 0x8007,
- 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4,
- 0xa18c, 0xffe0, 0x2021, 0x3b7a, 0x2019, 0x0011, 0x20a9, 0x000e,
- 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0, 0xa106, 0x0128, 0x8420,
- 0x2300, 0xa210, 0x1f04, 0x3ae2, 0x015e, 0x0005, 0x0156, 0x0804,
- 0x3b30, 0x2021, 0x3b88, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582,
- 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033, 0xa582, 0x0033,
- 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0065, 0x2200,
- 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3b07, 0x015e,
- 0x0088, 0x2021, 0x3b7a, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
- 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300, 0xa210, 0x1f04,
- 0x3b19, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064,
- 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x0005,
- 0xa886, 0x0002, 0x01e8, 0x2021, 0x3b66, 0x20a9, 0x000d, 0x2011,
- 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019, 0x0019, 0x2011,
- 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300, 0xa210, 0x1f04,
- 0x3b41, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890,
- 0x2021, 0x3b75, 0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024,
- 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028, 0x0930, 0x8420,
- 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3b19, 0x1021, 0x2202,
- 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610, 0x4612, 0x5812,
- 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021, 0xb002, 0xe204,
- 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
- 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
- 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, 0x7e07,
- 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784, 0x0f00, 0x800b,
- 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xd7fc,
- 0x0118, 0xa0e0, 0x6cc0, 0x0010, 0xa0e0, 0x4cc0, 0x0005, 0x00e6,
- 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0x4780, 0x2071,
- 0x4780, 0x0030, 0x2009, 0x4740, 0x2079, 0x0200, 0x2071, 0x4740,
- 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x3bc8, 0x3bc8,
- 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc8, 0x3bc6, 0x3bc6, 0x080c, 0x2575,
- 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0580, 0x7858,
- 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086, 0x1814,
- 0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b,
- 0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830, 0xd0bc, 0x11b8,
- 0xb284, 0x0800, 0x0118, 0x0104, 0x3bff, 0x0010, 0x0304, 0x3bff,
- 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084, 0x0003, 0x0138,
- 0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b, 0x00fb, 0x00fe,
- 0x00ee, 0x0005, 0x2001, 0x4701, 0x2004, 0xd0ac, 0x1118, 0x6814,
- 0x080c, 0x249e, 0x0005, 0x781b, 0x0083, 0x0005, 0x781b, 0x0082,
- 0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e, 0x0005, 0x2009,
- 0x4719, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186, 0x0001, 0x0150,
- 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x781b,
- 0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009, 0x4719, 0x210c,
- 0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138, 0x701f, 0x000b,
- 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f, 0x000a, 0x0005,
- 0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005, 0x781b, 0x00fa,
- 0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb, 0x0005, 0x6818,
- 0xd0fc, 0x0110, 0x681b, 0x001d, 0x701f, 0x000b, 0x7063, 0x0001,
- 0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, 0x1170, 0x7808,
- 0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084,
- 0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, 0x7808, 0xc08d,
- 0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, 0xb284, 0x0800,
- 0x0118, 0x1104, 0x3c80, 0x0010, 0x1304, 0x3c80, 0x78ac, 0x0005,
- 0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000,
- 0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, 0x0118, 0x1104,
- 0x3c8f, 0x0010, 0x1304, 0x3c92, 0x78ac, 0x0006, 0x7808, 0xa085,
- 0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x324d,
- 0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2490,
- 0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008,
- 0x78ec, 0xa084, 0x0003, 0x0904, 0x324d, 0x0804, 0x3c0b, 0xa784,
- 0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, 0x784b, 0x0008,
- 0x78ec, 0xa084, 0x0003, 0x0904, 0x324d, 0x78e4, 0xa084, 0x0007,
- 0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a,
- 0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, 0x7884, 0xd0fc,
- 0x0128, 0x080c, 0x3a57, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003,
- 0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000,
- 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x2bac, 0xb284,
- 0x0800, 0x0110, 0x0104, 0x25c6, 0x0304, 0x25c6, 0x6b14, 0x8307,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080,
- 0x4c40, 0x0010, 0xa080, 0x4bc0, 0x2060, 0x2048, 0x7056, 0x2a60,
- 0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3d57, 0x68a0,
- 0xd1ac, 0x1120, 0xa084, 0x0e00, 0x0904, 0x3d55, 0x6108, 0x8117,
- 0xa18c, 0x00ff, 0x631c, 0x832f, 0xd0dc, 0x0110, 0xa39d, 0x0001,
- 0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110,
- 0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec,
- 0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182, 0x000b, 0x1248,
- 0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029,
- 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa,
- 0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820,
- 0xa085, 0x1000, 0x6822, 0x080c, 0x3a7a, 0xa085, 0x0001, 0x00ce,
- 0x0005, 0xa282, 0x0006, 0x1904, 0x3a49, 0x7da8, 0x7eac, 0x8637,
- 0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff,
- 0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3dcb,
- 0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x3a23, 0xa6b4,
- 0x00ff, 0x0904, 0x3dc8, 0xa682, 0x0031, 0x1a04, 0x3a23, 0xa582,
- 0x0009, 0x0a04, 0x3a23, 0xa882, 0x0003, 0x1a04, 0x3a23, 0xa886,
- 0x0002, 0x01d0, 0xa886, 0x0000, 0x1904, 0x3a23, 0x2001, 0x000c,
- 0x79ec, 0xd1e4, 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c,
- 0x3a23, 0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000,
- 0xc0ac, 0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x3a23,
- 0x8634, 0xa682, 0x0018, 0x0228, 0x0120, 0x2031, 0x0018, 0x0804,
- 0x3e19, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c,
- 0x3aee, 0x0904, 0x3a23, 0x080c, 0x391a, 0x080c, 0x39bf, 0x7e58,
- 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005,
- 0x080c, 0x3917, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154,
- 0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904, 0x3a23, 0xd1ec, 0x1120,
- 0x2039, 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000,
- 0x2041, 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff,
- 0xa706, 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f,
- 0xa39c, 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705,
- 0xa086, 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000,
- 0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284,
- 0xff00, 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128,
- 0x852b, 0x852b, 0x080c, 0x3aee, 0x0d58, 0x080c, 0x391a, 0x080c,
- 0x39bf, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab,
- 0x0004, 0x7daa, 0x78ab, 0x0000, 0x7eaa, 0x7faa, 0x2800, 0x78aa,
- 0x789b, 0x0060, 0x78ab, 0x0008, 0x6820, 0xc0e5, 0x6822, 0x080c,
- 0x3a7a, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x0020,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9855, 0x984d, 0x0014,
- 0x9911, 0x98ff, 0x0014, 0x0014, 0x0090, 0x00e7, 0x0100, 0x0402,
- 0x2008, 0xf880, 0x0018, 0x0017, 0x840f, 0xd8c1, 0x0014, 0x0016,
- 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, 0x2500,
- 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
- 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, 0x3806,
- 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d18, 0xa201,
- 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a,
- 0xa808, 0x28e2, 0x9cce, 0xa8f3, 0x0864, 0xa83e, 0x300c, 0xa801,
- 0x3008, 0x28e1, 0x9cce, 0x28a2, 0x7163, 0xa831, 0x2021, 0xa818,
- 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4, 0x6c80,
- 0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027, 0x85f2,
- 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa813, 0x883e, 0xa811,
- 0x2882, 0x7162, 0xa814, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0,
- 0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861,
- 0x883e, 0x206a, 0x28c1, 0x9d18, 0x2042, 0x2101, 0xa8ca, 0x2902,
- 0xa20e, 0xa80b, 0xa207, 0x0014, 0xa203, 0x8000, 0x85a4, 0x1872,
- 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x7121, 0x0014,
- 0x0704, 0x3008, 0x9cce, 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009,
- 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861,
- 0xa8eb, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532,
- 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8,
- 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x2849, 0x1011, 0xa8fc,
- 0x3008, 0x8000, 0xa000, 0x2081, 0x2802, 0x1011, 0xa8fc, 0xa889,
- 0x3008, 0x20a1, 0x283c, 0x1011, 0xa8fc, 0xa209, 0x0017, 0x300c,
- 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014,
- 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, 0x18f2, 0x0014, 0xa20b,
- 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d22, 0x0704, 0xa206, 0x6865,
- 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa,
- 0x8160, 0x842a, 0x8180, 0xf021, 0x3008, 0x84a8, 0x11d7, 0x7042,
- 0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x0000, 0x0126, 0x70d0,
- 0xa084, 0x4c00, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
- 0x11a0, 0x720c, 0x82ff, 0x0128, 0x8aff, 0x1178, 0x7200, 0xd284,
- 0x1160, 0x7804, 0xd0cc, 0x0110, 0x080c, 0x435b, 0x7007, 0x0008,
- 0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003,
- 0x7002, 0xc69c, 0xd084, 0x0588, 0x7108, 0xe000, 0x7008, 0xa106,
- 0x1dd8, 0xa184, 0x0003, 0x0904, 0x3fca, 0xa184, 0x01e0, 0x1904,
- 0x3fca, 0xd1f4, 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60,
- 0x2011, 0x0180, 0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20,
- 0x700c, 0xa106, 0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008,
- 0xa106, 0x1dd8, 0xa184, 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4,
- 0x0548, 0x7007, 0x0002, 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130,
- 0x080c, 0x40d6, 0x8aff, 0x0904, 0x3f54, 0x0cb8, 0x700c, 0xa08c,
- 0x07ff, 0x01e8, 0x7004, 0xd084, 0x0178, 0x7014, 0xa005, 0x1148,
- 0x7010, 0x7310, 0xa306, 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102,
- 0x1e20, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x429a,
- 0x1de8, 0x09d8, 0x080c, 0x405c, 0x012e, 0x2000, 0x0005, 0x7204,
- 0x7108, 0xc19c, 0x8103, 0x1218, 0x7007, 0x0002, 0x0cc0, 0xa205,
- 0x1d88, 0x7007, 0x0008, 0x7003, 0x0008, 0x0006, 0x2001, 0x4701,
- 0x2004, 0xd0cc, 0x0110, 0x080c, 0x435b, 0x000e, 0x012e, 0x2000,
- 0x0005, 0x6428, 0x84ff, 0x0508, 0x2c70, 0x7004, 0xa0bc, 0x000f,
- 0xa7b8, 0x401d, 0x273c, 0x87fb, 0x1148, 0x0210, 0x080c, 0x2575,
- 0x609c, 0xa075, 0x0190, 0x0c88, 0x2039, 0x4012, 0x2704, 0xae68,
- 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0138, 0x8738, 0x2704,
- 0xa005, 0x1da8, 0x709c, 0xa075, 0x1d00, 0x0005, 0x0000, 0x0005,
- 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
- 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4012, 0x400f,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4012, 0x0000, 0x401a, 0x4017,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x401a, 0x0000, 0x4015, 0x4015,
- 0x0000, 0x0000, 0x8000, 0x0000, 0x4015, 0x0000, 0x401b, 0x401b,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x401b, 0x2079, 0x4700, 0x2071,
- 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x2009,
- 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
- 0x0000, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1128, 0x8109, 0x0118,
- 0x2071, 0x0020, 0x0c80, 0x0005, 0x7004, 0x8004, 0x1a04, 0x40b2,
- 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c,
- 0x410e, 0x0804, 0x40d2, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108,
- 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x410e,
- 0x0804, 0x40d2, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0190, 0xa386,
- 0x0008, 0x01c0, 0x7004, 0xd084, 0x1148, 0x7108, 0x7008, 0xa106,
- 0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x410e, 0xa386, 0x200c,
- 0x19f0, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, 0x07ff, 0x0110,
- 0x080c, 0x2575, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
- 0x0118, 0x080c, 0x410e, 0x0470, 0x7007, 0x0012, 0x7000, 0xd084,
- 0x1148, 0x7310, 0x7014, 0xa305, 0x0128, 0x710c, 0xa184, 0x07ff,
- 0x1904, 0x405c, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
- 0x0118, 0x080c, 0x410e, 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008,
- 0x7004, 0xd09c, 0x1de8, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184,
- 0x01e0, 0x0118, 0x080c, 0x410e, 0x0028, 0x7007, 0x0012, 0x7108,
- 0x8103, 0x0e88, 0x7003, 0x0008, 0x0005, 0x7108, 0xa184, 0x01e0,
- 0x15a8, 0x7108, 0xa184, 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002,
- 0x40ea, 0x40f8, 0x40e8, 0x40f8, 0x40e8, 0x4148, 0x40e8, 0x4146,
- 0x080c, 0x2575, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
- 0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x429a, 0x1de8, 0x0005,
- 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140,
- 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030,
- 0x8aff, 0x0118, 0x080c, 0x429a, 0x1de8, 0x0005, 0x7007, 0x0012,
- 0x7108, 0x1d04, 0x4111, 0x2091, 0x6000, 0x1d04, 0x4115, 0x2091,
- 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8,
- 0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000,
- 0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108,
- 0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000,
- 0x0010, 0x2001, 0x0001, 0x080c, 0x3ba7, 0x681b, 0x0002, 0x2051,
- 0x0000, 0x0005, 0x080c, 0x2575, 0x080c, 0x2575, 0x080c, 0x4187,
- 0x7210, 0x7114, 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211,
- 0xa189, 0x0000, 0x04a1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200,
- 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238,
- 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60,
- 0x8a07, 0x0006, 0x6004, 0xd09c, 0x0118, 0xa7ba, 0x4017, 0x0010,
- 0xa7ba, 0x400f, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
- 0x6b8e, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110,
- 0x080c, 0x410e, 0x7007, 0x0012, 0x080c, 0x405c, 0x0005, 0x8a50,
- 0x8739, 0x2704, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60,
- 0x6004, 0xa084, 0x000f, 0xa080, 0x402d, 0x203c, 0x87fb, 0x090c,
- 0x2575, 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004,
- 0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057,
- 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008,
- 0x000e, 0x0118, 0xa0b8, 0x4017, 0x0010, 0xa0b8, 0x400f, 0xb284,
- 0x0200, 0x0110, 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c,
- 0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0550, 0x2c58, 0x2704,
- 0x6104, 0xac60, 0x6000, 0xa400, 0x2048, 0xa9cc, 0x0004, 0x0118,
- 0x080c, 0x43a3, 0x0400, 0x701a, 0x6004, 0xa301, 0x701e, 0xd19c,
- 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000,
- 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203,
- 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x42c5, 0x0010,
- 0x080c, 0x429a, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6,
- 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, 0x0004,
- 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000, 0x0005,
- 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
- 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c, 0x681c,
- 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050, 0x2d60,
- 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x401d, 0x273c, 0x87fb, 0x1138,
- 0x0210, 0x080c, 0x2575, 0x689c, 0xa065, 0x0120, 0x0c88, 0x080c,
- 0x429a, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, 0x0016,
- 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, 0xb284,
- 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5, 0x000c,
- 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
- 0x2049, 0x4235, 0x6828, 0xa055, 0x00d6, 0x0904, 0x4296, 0x2d70,
- 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x401d, 0x273c, 0x87fb,
- 0x1140, 0x0210, 0x080c, 0x2575, 0x709c, 0xa075, 0x2060, 0x0570,
- 0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268,
- 0x8a51, 0x1110, 0x080c, 0x2575, 0x8738, 0x2704, 0xa005, 0x1d90,
- 0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420, 0x831a,
- 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b,
- 0x1210, 0x080c, 0x2575, 0xb284, 0x0200, 0x0118, 0x2071, 0x0050,
- 0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x41c3, 0x00de, 0x012e,
- 0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, 0x0110,
- 0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108, 0x0005,
- 0x2704, 0xac78, 0x7800, 0x2f08, 0xd094, 0x1904, 0x43a6, 0x701a,
- 0x7804, 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xd09c,
- 0x0120, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084,
- 0x0010, 0xc085, 0x7006, 0x2079, 0x4700, 0x8a51, 0x01e8, 0x8738,
- 0x2704, 0xa005, 0x1168, 0x609c, 0xa005, 0x01b8, 0x2060, 0x6004,
- 0xa084, 0x000f, 0xa080, 0x401d, 0x203c, 0x87fb, 0x090c, 0x2575,
- 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e, 0x0110, 0xa006, 0x0028,
- 0xa084, 0x0003, 0xa086, 0x0003, 0x0005, 0x2051, 0x0000, 0x0005,
- 0x0126, 0x0006, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090,
- 0x00de, 0x008e, 0x7108, 0xa184, 0x0003, 0x1128, 0x6828, 0xa005,
- 0x0178, 0x0804, 0x3f6d, 0x7108, 0xd1fc, 0x0118, 0x080c, 0x40d6,
- 0x0c88, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0de8, 0x080c, 0x40d6,
- 0x7008, 0xa086, 0x0008, 0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003,
- 0x0000, 0x2049, 0x0000, 0x0006, 0x2001, 0x4701, 0x2004, 0xd0cc,
- 0x0110, 0x080c, 0x435b, 0x000e, 0x012e, 0x2000, 0x0005, 0x0126,
- 0x0146, 0x0136, 0x0156, 0x00c6, 0x00d6, 0x70d0, 0xa084, 0x4c00,
- 0x8004, 0x2090, 0x00de, 0x2049, 0x431f, 0xad80, 0x0011, 0x20a0,
- 0xb284, 0x0200, 0x0118, 0x2099, 0x0032, 0x0010, 0x2099, 0x0031,
- 0x700c, 0xa084, 0x07ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002,
- 0x7003, 0x0001, 0x0118, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084,
- 0x07ff, 0x0130, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0,
- 0x00ce, 0x2049, 0x0000, 0x7003, 0x0000, 0x015e, 0x013e, 0x014e,
- 0x012e, 0x2000, 0x0005, 0x6814, 0xd0fc, 0x0904, 0x439e, 0x7000,
- 0xd084, 0x05e0, 0x7e24, 0xa6b5, 0x0004, 0x7007, 0x0004, 0x7004,
- 0xa084, 0x0004, 0x1de0, 0x7118, 0x0016, 0x711c, 0x0016, 0x7120,
- 0x0016, 0x7124, 0x0016, 0x701b, 0x0000, 0x701f, 0x3fff, 0x7023,
- 0x0000, 0x7027, 0x0000, 0x7013, 0x0004, 0x7017, 0x0000, 0x7602,
- 0x7007, 0x0001, 0x2001, 0xffff, 0x2009, 0x0031, 0x200a, 0x200a,
- 0x7108, 0x7008, 0xa106, 0x1de0, 0xd1fc, 0x0dd0, 0x002e, 0x7226,
- 0x002e, 0x7222, 0x002e, 0x721e, 0x002e, 0x721a, 0x7007, 0x0002,
- 0x7008, 0xa086, 0x0008, 0x0110, 0x0804, 0x410e, 0x7007, 0x0004,
- 0x7003, 0x0000, 0x0005, 0x2049, 0x41c3, 0x0068, 0x7008, 0xa084,
- 0x0003, 0x0110, 0xa006, 0x0005, 0xa006, 0x2020, 0x2018, 0x2c58,
- 0x2160, 0x2049, 0x0000, 0x8b58, 0x6100, 0x2100, 0xa408, 0x711a,
- 0x6004, 0xa301, 0x701e, 0x0006, 0x2b04, 0xa084, 0x0008, 0x0150,
- 0x6010, 0xa081, 0x0000, 0x7022, 0x0006, 0x6014, 0xa081, 0x0000,
- 0x7026, 0x0006, 0xa184, 0x0007, 0x2011, 0x0008, 0xa22a, 0x6208,
- 0x2400, 0xa212, 0x0026, 0x620c, 0x2240, 0x2300, 0xa843, 0x002e,
- 0x88ff, 0x1170, 0x2500, 0xa202, 0x0108, 0x1250, 0x2220, 0x2041,
- 0x0000, 0x2b04, 0xd09c, 0x0110, 0x000e, 0x000e, 0x000e, 0x0450,
- 0x7512, 0x7017, 0x0000, 0x7602, 0xa986, 0x41c3, 0x1118, 0x7007,
- 0x0001, 0x0028, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006, 0x2500,
- 0xa100, 0x701a, 0x2b04, 0xa084, 0x0008, 0x0110, 0x000e, 0x004e,
- 0x001e, 0xa189, 0x0000, 0x711e, 0x2b0c, 0xa18c, 0x0008, 0x0130,
- 0xa4a1, 0x0000, 0x7422, 0xa081, 0x0000, 0x7026, 0x2500, 0xa222,
- 0xa8c3, 0x0000, 0x7412, 0x2820, 0x7416, 0x7602, 0xa986, 0x41c3,
- 0x1118, 0x7007, 0x0001, 0x0028, 0x7004, 0xa084, 0x0010, 0xc085,
- 0x7006, 0x8b59, 0x2b60, 0x2079, 0x4700, 0x080c, 0x42c5, 0xa006,
- 0x0005, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168,
- 0x7974, 0x70d0, 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f,
- 0x0000, 0x0e04, 0x443d, 0x2091, 0x4080, 0x2069, 0x4780, 0xc7fd,
- 0x6800, 0xa084, 0x000f, 0x1198, 0x68d0, 0xd0b4, 0x0180, 0xd0bc,
- 0x1170, 0x00f6, 0x2079, 0x0100, 0xd7fc, 0x1110, 0x2079, 0x0200,
- 0x7830, 0xa084, 0x00c0, 0x1110, 0x080c, 0x22d5, 0x00fe, 0xd7fc,
- 0x0120, 0x2069, 0x4740, 0xc7fc, 0x0c18, 0x7830, 0x8001, 0x7832,
- 0x1904, 0x44c7, 0x7834, 0x7832, 0x2061, 0x6cc0, 0x2069, 0x4780,
- 0xc7fd, 0x68cc, 0xa005, 0x0128, 0x8001, 0x68ce, 0x1110, 0x080c,
- 0x4639, 0x6800, 0xa084, 0x000f, 0x0168, 0xa086, 0x0001, 0x0150,
- 0x6840, 0xa00d, 0x0138, 0x2104, 0xa005, 0x0120, 0x8001, 0x200a,
- 0x0904, 0x45d6, 0x6814, 0xa005, 0x01a8, 0x8001, 0x6816, 0x1190,
- 0x68a3, 0x0001, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x0200, 0x0010,
- 0x2079, 0x0100, 0x080c, 0x3c6e, 0x00fe, 0x6860, 0xa005, 0x0110,
- 0x080c, 0x22d5, 0x687c, 0xa005, 0x0140, 0x8001, 0x687e, 0x1128,
- 0x6863, 0x0000, 0x68d0, 0xc0c5, 0x68d2, 0x68d0, 0xd0fc, 0x01b0,
- 0xc0fc, 0x68d2, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0158, 0x8001,
- 0x6036, 0x68d0, 0xc0fd, 0x68d2, 0x1128, 0x6010, 0xa005, 0x0110,
- 0x080c, 0x22d5, 0xace0, 0x0010, 0x1f04, 0x44ac, 0xd7fc, 0x0138,
- 0x2061, 0x4cc0, 0x2069, 0x4740, 0xc7fc, 0x0804, 0x4469, 0x0459,
- 0x7838, 0x8001, 0x783a, 0x11a0, 0x783c, 0x783a, 0x2061, 0x4cc0,
- 0x2069, 0x4740, 0xc7fc, 0x680c, 0xa005, 0x0110, 0x080c, 0x4543,
- 0xd7fc, 0x1130, 0x2061, 0x6cc0, 0x2069, 0x4780, 0xc7fd, 0x0c98,
- 0x7810, 0xd0cc, 0x0168, 0xd0ac, 0x1120, 0xd0a4, 0x0148, 0xc0ad,
- 0x7812, 0x2091, 0x8001, 0x0e04, 0x44ef, 0x080c, 0x20a1, 0x0005,
- 0x2091, 0x8001, 0x0005, 0x7840, 0x8001, 0x7842, 0x1904, 0x4542,
- 0x7844, 0x7842, 0x2069, 0x4740, 0xc7fc, 0x2079, 0x0200, 0x68d4,
- 0xa005, 0x0138, 0x7de0, 0xa504, 0x1120, 0x68d6, 0x68d0, 0xc0bc,
- 0x68d2, 0x2079, 0x4700, 0x6810, 0xa005, 0x1110, 0x2001, 0x0101,
- 0x8001, 0x6812, 0xd7fc, 0x0118, 0xa080, 0x8dd0, 0x0010, 0xa080,
- 0x8cc0, 0x2040, 0x2004, 0xa065, 0x01e0, 0x6024, 0xa005, 0x01b0,
- 0x8001, 0x6026, 0x1198, 0x6800, 0xa005, 0x0130, 0x6848, 0xac06,
- 0x1118, 0x080c, 0x45d6, 0x0068, 0x6860, 0xa005, 0x0118, 0x6027,
- 0x0001, 0x0020, 0x080c, 0x4584, 0x2804, 0x0c28, 0x6000, 0x2c40,
- 0x0c10, 0xd7fc, 0x1138, 0x2069, 0x4780, 0xc7fd, 0x2079, 0x0100,
- 0x0804, 0x44ff, 0x0005, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008,
- 0xd09c, 0x0558, 0x6024, 0xa005, 0x0118, 0x8001, 0x6026, 0x0418,
- 0x6008, 0xc09c, 0xd084, 0x1110, 0xd0ac, 0x01c0, 0x600a, 0x6004,
- 0xa005, 0x01d8, 0x00d6, 0x00c6, 0x0016, 0x2068, 0x6010, 0x8001,
- 0x6012, 0x080c, 0x37c7, 0x2d00, 0x2c68, 0x2060, 0x080c, 0x1c02,
- 0x080c, 0x1db2, 0x001e, 0x00ce, 0x00de, 0x0038, 0xc0bd, 0x600a,
- 0xa18d, 0x0001, 0x0010, 0xa18d, 0x0100, 0xace0, 0x0010, 0x1f04,
- 0x4547, 0xa184, 0x0001, 0x0130, 0xa18c, 0xfffe, 0x690e, 0x080c,
- 0x22d5, 0x0008, 0x690e, 0x0005, 0x2c00, 0x687a, 0x6714, 0x6f72,
- 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084,
- 0x5f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022,
- 0x6000, 0x2042, 0x2069, 0x4780, 0xd7fc, 0x1110, 0x2069, 0x4740,
- 0x6858, 0xac06, 0x1110, 0x2800, 0x685a, 0x080c, 0x1b9a, 0x6818,
- 0xa005, 0x0110, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810,
- 0x7908, 0x8109, 0x790a, 0x8001, 0x1310, 0x080c, 0x2575, 0x6812,
- 0x1118, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000,
- 0x2c68, 0x080c, 0x1dbf, 0xd7fc, 0x1118, 0x2069, 0x4740, 0x0010,
- 0x2069, 0x4780, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118,
- 0x6976, 0x2001, 0x0004, 0x080c, 0x22cb, 0x0005, 0x00d6, 0x6948,
- 0x2160, 0xd7fc, 0x1118, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100,
- 0x080c, 0x2490, 0x601b, 0x0006, 0x6858, 0xa084, 0x5f00, 0x601e,
- 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000,
- 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4,
- 0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110,
- 0x1f04, 0x45fd, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084,
- 0x0110, 0x1f04, 0x4606, 0x20a9, 0x00fa, 0x1f04, 0x460d, 0x681b,
- 0x0054, 0x00de, 0x6863, 0x0007, 0x0005, 0x2079, 0x4700, 0x00e1,
- 0x0089, 0x00a9, 0x2009, 0x0002, 0x2069, 0x4780, 0x680f, 0x0000,
- 0x6813, 0x0000, 0x6817, 0x0000, 0x8109, 0x0118, 0x2069, 0x4740,
- 0x0ca8, 0x0005, 0x2019, 0x00a3, 0x7b3a, 0x7b3e, 0x0005, 0x2019,
- 0x0033, 0x7b42, 0x7b46, 0x0005, 0x2019, 0x32dd, 0x7b32, 0x7b36,
- 0x0005, 0x6a4c, 0xa285, 0x0000, 0x01f0, 0x6950, 0x6bbc, 0xa300,
- 0x00c6, 0x2164, 0x6304, 0x83ff, 0x1138, 0x8211, 0x0148, 0x8108,
- 0xa11a, 0x0eb8, 0x69bc, 0x0ca8, 0x68cf, 0x000a, 0x00ce, 0x0005,
- 0x694c, 0x6abc, 0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109,
- 0x1dc8, 0x694e, 0x00ce, 0x0005, 0x0016, 0x1d04, 0x465d, 0x2091,
- 0x6000, 0x1d04, 0x4661, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x1118,
- 0xd0d4, 0x0190, 0x00a0, 0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5,
- 0xc0c5, 0x7816, 0xd0d4, 0x1580, 0x0460, 0x7814, 0xc0fd, 0xc0c5,
- 0x7816, 0xd0d4, 0x1548, 0x0428, 0xd0e4, 0x0904, 0x46c4, 0x1d04,
- 0x467f, 0x2091, 0x6000, 0x2009, 0x000c, 0x1d04, 0x4685, 0x2091,
- 0x6000, 0x8109, 0x1dd0, 0x70e4, 0xa084, 0x01ff, 0xa086, 0x01ff,
- 0x1110, 0x70ec, 0x08c0, 0xae8e, 0x0100, 0x0128, 0x7814, 0xc0f4,
- 0xd0fc, 0x1130, 0x0020, 0x7814, 0xc0fc, 0xd0f4, 0x1108, 0xc0c4,
- 0x7816, 0x7804, 0xd08c, 0x0500, 0x00c6, 0x2061, 0x0000, 0x6018,
- 0xd084, 0x11b8, 0xae86, 0x0200, 0x00e6, 0x2071, 0x0010, 0x0120,
- 0x70db, 0x0001, 0x78e4, 0x0018, 0x70db, 0x0000, 0x78e0, 0x70c6,
- 0x70c3, 0x800e, 0x601b, 0x0001, 0x2091, 0x4080, 0x00ee, 0x00ce,
- 0x0018, 0x00ce, 0x681f, 0x000c, 0x001e, 0x70a0, 0x70a2, 0x0005,
- 0x0c26
-};
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw12160i_length01 = 0x36c9;
-#else
-static unsigned short risc_code_length01 = 0x36c9;
-#endif
-
diff --git a/drivers/scsi/ql1280_fw.h b/drivers/scsi/ql1280_fw.h
deleted file mode 100644
index 784f2a04bf2..00000000000
--- a/drivers/scsi/ql1280_fw.h
+++ /dev/null
@@ -1,2048 +0,0 @@
-/*****************************************************************************
- * QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x
- * Copyright (C) 2001 Qlogic Corporation (www.qlogic.com)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- *****************************************************************************/
-
-/************************************************************************
- * --- ISP1240/1080/1280 Initiator Firmware --- *
- * 32 LUN Support *
- ************************************************************************/
-
-
-/*
- * Firmware Version 8.15.11 (10:20 Jan 02, 2002)
- */
-
-#ifdef UNIQUE_FW_NAME
-static unsigned char fw1280ei_version_str[] = {8,15,11};
-#else
-static unsigned char firmware_version[] = {8,15,11};
-#endif
-
-#ifdef UNIQUE_FW_NAME
-#define fw1280ei_VERSION_STRING "8.15.11"
-#else
-#define FW_VERSION_STRING "8.15.11"
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw1280ei_addr01 = 0x1000 ;
-#else
-static unsigned short risc_code_addr01 = 0x1000 ;
-#endif
-
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw1280ei_code01[] = {
-#else
-static unsigned short risc_code01[] = {
-#endif
- 0x0078, 0x1041, 0x0000, 0x3e2e, 0x0000, 0x2043, 0x4f50, 0x5952,
- 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
- 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
- 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
- 0x3132, 0x3430, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
- 0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3135, 0x2020, 0x2043,
- 0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
- 0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
- 0x2400, 0x20c9, 0x98ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
- 0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010,
- 0x2089, 0x1374, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086,
- 0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071,
- 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13f8, 0x0078,
- 0x106d, 0x20c1, 0x0020, 0x2089, 0x131c, 0x2071, 0x0010, 0x70c3,
- 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
- 0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000,
- 0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64,
- 0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114,
- 0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0,
- 0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080,
- 0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128,
- 0xa1a2, 0x4f00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
- 0xa192, 0x9900, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x20c1,
- 0x2218, 0x2079, 0x4f00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
- 0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2009, 0xff00, 0x3400,
- 0xa102, 0x0048, 0x10cf, 0x0040, 0x10cf, 0x20a8, 0x42a4, 0x2001,
- 0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e5, 0x2071, 0x0100,
- 0x0d7e, 0x2069, 0x4f40, 0x1078, 0x4db0, 0x0d7f, 0x7810, 0xc0ed,
- 0x7812, 0x781b, 0x0064, 0x0078, 0x110a, 0x2001, 0x04fc, 0x2004,
- 0xa086, 0x1280, 0x00c0, 0x1105, 0x7814, 0xc0ed, 0xc0d5, 0x7816,
- 0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4f40, 0x1078,
- 0x4db0, 0x2069, 0x4f80, 0x2071, 0x0100, 0x1078, 0x4db0, 0x7814,
- 0xc0d4, 0x7816, 0x0d7f, 0x0078, 0x110a, 0x7814, 0xc0e5, 0x7816,
- 0x781b, 0x003c, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800,
- 0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002,
- 0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4f40, 0x681b, 0x0003,
- 0x6823, 0x0007, 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028,
- 0x6837, 0x0000, 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000,
- 0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4fc0, 0x2079,
- 0x4f00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148,
- 0x68d7, 0x7329, 0x0078, 0x114a, 0x68d7, 0x730d, 0x0078, 0x114a,
- 0x68d7, 0x732d, 0x68c7, 0x54c0, 0x68cb, 0x53c0, 0x68cf, 0x94c0,
- 0x68ab, 0x9744, 0x68af, 0x9749, 0x68b3, 0x9744, 0x68b7, 0x9744,
- 0x68a7, 0x0001, 0x2069, 0x4f80, 0x0078, 0x111e, 0x68d3, 0x000a,
- 0x68c3, 0x51c0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439,
- 0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x74c0, 0x68cb, 0x5440,
- 0x68cf, 0x95d0, 0x68ab, 0x9749, 0x68af, 0x974e, 0x68b3, 0x9749,
- 0x68b7, 0x9749, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2,
- 0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x53c0, 0x2071,
- 0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1195, 0x2019, 0x0c0c, 0x2021,
- 0x000c, 0x1078, 0x2050, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021,
- 0x000a, 0x1078, 0x2050, 0x2069, 0x5440, 0x2071, 0x0100, 0x70ec,
- 0xd0e4, 0x00c0, 0x11ab, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
- 0x2050, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078,
- 0x2050, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c,
- 0x2069, 0x53c0, 0x1078, 0x2050, 0x2069, 0x5440, 0x1078, 0x2050,
- 0x0078, 0x11db, 0x2069, 0x53c0, 0x0e7e, 0x2071, 0x0100, 0x70ec,
- 0xd0e4, 0x00c0, 0x11d4, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
- 0x2050, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a,
- 0x1078, 0x2050, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x54c0, 0x2009,
- 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8,
- 0xa386, 0xfeff, 0x00c0, 0x11f2, 0x6817, 0x0100, 0x681f, 0x0064,
- 0x0078, 0x11f6, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
- 0x00f0, 0x11e3, 0x8109, 0x00c0, 0x11e1, 0x8211, 0x0040, 0x1204,
- 0x2069, 0x74c0, 0x0078, 0x11df, 0x1078, 0x26a2, 0x1078, 0x4712,
- 0x1078, 0x1e1b, 0x1078, 0x4d42, 0x2091, 0x2100, 0x2079, 0x4f00,
- 0x7810, 0xd0ec, 0x0040, 0x1218, 0x2071, 0x0020, 0x0078, 0x121a,
- 0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4f00, 0x2071, 0x0020,
- 0x2091, 0x2300, 0x2079, 0x4f00, 0x7810, 0xd0ec, 0x0040, 0x122c,
- 0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4f40,
- 0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4f80, 0x2091, 0x2000,
- 0x2079, 0x4f00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
- 0x2071, 0x0010, 0x70c3, 0x0000, 0x0090, 0x124d, 0x70c0, 0xa086,
- 0x0002, 0x00c0, 0x124d, 0x1078, 0x15c1, 0x2039, 0x0000, 0x7810,
- 0xd0ec, 0x00c0, 0x12cf, 0x1078, 0x148e, 0x78ac, 0xa005, 0x00c0,
- 0x126b, 0x0068, 0x1261, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078,
- 0x23dc, 0x1078, 0x20e8, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040,
- 0x126b, 0x1078, 0x23dc, 0x0068, 0x1278, 0x2009, 0x4f47, 0x2011,
- 0x4f87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1f51,
- 0x2071, 0x4f40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485,
- 0x0000, 0x0040, 0x129d, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4,
- 0xa28c, 0x303d, 0x2190, 0x1078, 0x2bb1, 0x2091, 0x8000, 0x2091,
- 0x303d, 0x0068, 0x129d, 0x2079, 0x4f00, 0x786c, 0xa065, 0x0040,
- 0x129d, 0x2071, 0x0010, 0x1078, 0x23dc, 0x00e0, 0x12a5, 0x2079,
- 0x4f00, 0x2071, 0x0010, 0x1078, 0x4b16, 0x2071, 0x4f80, 0x70a4,
- 0xa005, 0x0040, 0x12bd, 0x7050, 0xa025, 0x0040, 0x12bd, 0x2079,
- 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078,
- 0x2bb1, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4f00, 0x2071,
- 0x0010, 0x0068, 0x12c9, 0x786c, 0xa065, 0x0040, 0x12c9, 0x1078,
- 0x23dc, 0x00e0, 0x1253, 0x1078, 0x4b16, 0x0078, 0x1253, 0x1078,
- 0x148e, 0x78ac, 0xa005, 0x00c0, 0x12e7, 0x0068, 0x12dd, 0x786c,
- 0xa065, 0x0040, 0x12dd, 0x1078, 0x23dc, 0x1078, 0x20e8, 0x0068,
- 0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x23dc, 0x0068,
- 0x12f1, 0x2009, 0x4f47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078,
- 0x1f51, 0x2071, 0x4f40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450,
- 0xa485, 0x0000, 0x0040, 0x130c, 0x2079, 0x0100, 0x2091, 0x8000,
- 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2bb1, 0x2091, 0x8000,
- 0x2091, 0x303d, 0x2079, 0x4f00, 0x2071, 0x0010, 0x0068, 0x1316,
- 0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x23dc, 0x00e0, 0x12cf,
- 0x1078, 0x4b16, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x133c, 0x133c, 0x133e, 0x133e,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
- 0x134b, 0x134b, 0x134b, 0x134b, 0x0078, 0x133c, 0x007e, 0x107e,
- 0x127e, 0x2091, 0x2400, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
- 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c8,
- 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
- 0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
- 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300,
- 0x1078, 0x29d1, 0x2091, 0x2400, 0x1078, 0x29d1, 0x127f, 0x107f,
- 0x007f, 0x2091, 0x8001, 0x007c, 0x1394, 0x1394, 0x1396, 0x1396,
- 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13ae, 0x13ae, 0x1396, 0x1396,
- 0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13af, 0x13af, 0x13af, 0x13af,
- 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af,
- 0x13af, 0x13af, 0x13af, 0x13af, 0x0078, 0x1394, 0x007e, 0x107e,
- 0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f,
- 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13d5,
- 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e,
- 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069,
- 0x4f40, 0x2079, 0x4f00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078,
- 0x4db0, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c,
- 0x3c00, 0xa084, 0x0007, 0x0079, 0x13cd, 0x13de, 0x13de, 0x13e0,
- 0x13e0, 0x13e5, 0x13e5, 0x13ea, 0x13ea, 0x3c00, 0xa084, 0x0003,
- 0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x29b2,
- 0x2091, 0x2200, 0x1078, 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078,
- 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078, 0x47ec, 0x2091, 0x2200,
- 0x1078, 0x47ec, 0x007c, 0x2091, 0x2100, 0x1078, 0x47ec, 0x007c,
- 0x1418, 0x1418, 0x141a, 0x141a, 0x1427, 0x1427, 0x1427, 0x1427,
- 0x1432, 0x1432, 0x143f, 0x143f, 0x1427, 0x1427, 0x1427, 0x1427,
- 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
- 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
- 0x0078, 0x1418, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078,
- 0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
- 0x107e, 0x127e, 0x1078, 0x13c8, 0x127f, 0x107f, 0x007f, 0x2091,
- 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078,
- 0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
- 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x29d1, 0x2091, 0x2400,
- 0x1078, 0x29d1, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c,
- 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4f00,
- 0x2071, 0x0200, 0x2069, 0x4f40, 0x3d00, 0xd08c, 0x0040, 0x1466,
- 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4db0, 0x3d00, 0xd084,
- 0x0040, 0x1474, 0x2069, 0x4f80, 0x2071, 0x0100, 0x70ec, 0xa084,
- 0x1c00, 0x78e6, 0x1078, 0x4db0, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f,
- 0x107f, 0x007f, 0x007c, 0x7008, 0x800b, 0x00c8, 0x1489, 0x7007,
- 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x148a, 0xd09c, 0x0040, 0x1489,
- 0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15c4, 0x0068, 0x151a,
- 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x151a, 0x7828, 0xa005,
- 0x00c0, 0x149e, 0x0010, 0x151b, 0x0078, 0x151a, 0x7910, 0xd1f4,
- 0x0040, 0x14a4, 0x0078, 0x14b9, 0x7914, 0xd1ec, 0x0040, 0x14bd,
- 0xd0fc, 0x0040, 0x14b3, 0x007e, 0x1078, 0x1dae, 0x007f, 0x0040,
- 0x14bd, 0x0078, 0x14b9, 0x007e, 0x1078, 0x1da1, 0x007f, 0x0040,
- 0x14bd, 0x2001, 0x4007, 0x0078, 0x15c3, 0x7910, 0xd0fc, 0x00c0,
- 0x14c7, 0x2061, 0x4f40, 0xc19c, 0xc7fc, 0x0078, 0x14cb, 0x2061,
- 0x4f80, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x00c0, 0x151a, 0x7912,
- 0x6082, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14db, 0x0c7e,
- 0x1078, 0x1b85, 0x0c7f, 0x782b, 0x0000, 0x607c, 0xa065, 0x0040,
- 0x1500, 0x0c7e, 0x609c, 0x1078, 0x1e90, 0x0c7f, 0x609f, 0x0000,
- 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6087, 0x0103, 0x7810, 0x007e,
- 0x84ff, 0x00c0, 0x14f6, 0x85ff, 0x0040, 0x14f8, 0xc0c5, 0x7812,
- 0x1078, 0x1dbb, 0x007f, 0x7812, 0x00c0, 0x1514, 0x1078, 0x1e0d,
- 0x7810, 0xd09c, 0x00c0, 0x1508, 0x2061, 0x4f40, 0x0078, 0x150c,
- 0x2061, 0x4f80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0dc,
- 0x0040, 0x1518, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078, 0x15c3,
- 0x0078, 0x15c1, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x1523, 0x2001,
- 0x4007, 0x0078, 0x15c3, 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce,
- 0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x1531, 0x0079,
- 0x1538, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15cf, 0x0079, 0x1578,
- 0x15c1, 0x1617, 0x15e0, 0x164f, 0x1687, 0x1687, 0x15d7, 0x1ced,
- 0x1692, 0x15cf, 0x15e4, 0x15e6, 0x15e8, 0x15ea, 0x1cf2, 0x15cf,
- 0x16a0, 0x16fd, 0x1ba5, 0x1ce7, 0x15ec, 0x19ea, 0x1a2c, 0x1a67,
- 0x1ab8, 0x19a5, 0x19b2, 0x19c6, 0x19d9, 0x17eb, 0x15cf, 0x1734,
- 0x1741, 0x174d, 0x1759, 0x176f, 0x177b, 0x177e, 0x178a, 0x1796,
- 0x179e, 0x17d3, 0x17df, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x17f8,
- 0x180a, 0x1826, 0x185c, 0x1884, 0x1894, 0x1897, 0x18c8, 0x18f9,
- 0x190b, 0x1974, 0x1984, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x1994,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x1d17, 0x1d1d, 0x15cf,
- 0x15cf, 0x15cf, 0x1d21, 0x1d66, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x1611, 0x1681, 0x169a, 0x16f7, 0x1b9f, 0x15cf, 0x15cf, 0x1b68,
- 0x15cf, 0x1d6a, 0x1d09, 0x1d13, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf, 0x15cf,
- 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15c3, 0x73ce, 0x72ca,
- 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15c4, 0x2061, 0x0000,
- 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c, 0x70c3,
- 0x4001, 0x0078, 0x15c4, 0x70c3, 0x4006, 0x0078, 0x15c4, 0x2099,
- 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078, 0x15c1,
- 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15c1, 0x0078, 0x15c1,
- 0x0078, 0x15c1, 0x0078, 0x15c1, 0x2091, 0x8000, 0x70c3, 0x0004,
- 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x0008,
- 0x2001, 0x000f, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001, 0x2031,
- 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445, 0x2061,
- 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080, 0x0078,
- 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x161a, 0x2029,
- 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0, 0x2099,
- 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422,
- 0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15c1, 0xa182, 0x0040,
- 0x00c8, 0x1634, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007,
- 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x163b, 0x7007,
- 0x0002, 0xa084, 0x01e0, 0x0040, 0x1649, 0x70c3, 0x4002, 0x0078,
- 0x15c4, 0x24a8, 0x53a5, 0x0078, 0x162b, 0x0078, 0x15c1, 0x2029,
- 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1,
- 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422,
- 0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040, 0x15c1,
- 0xa182, 0x0040, 0x00c8, 0x166e, 0x2120, 0xa006, 0x2008, 0x8403,
- 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040,
- 0x1675, 0xa084, 0x01e0, 0x0040, 0x1663, 0x70c3, 0x4002, 0x0078,
- 0x15c4, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1652, 0x71c4,
- 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x168f, 0x200a, 0x72ca,
- 0x0078, 0x15c0, 0x70c7, 0x0008, 0x70cb, 0x000f, 0x70cf, 0x000b,
- 0x0078, 0x15c1, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16a3,
- 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6,
- 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16f2, 0xa40a, 0x0040,
- 0x16b3, 0x00c8, 0x16bc, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0040,
- 0x16c0, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15c3,
- 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0040,
- 0x16d8, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118,
- 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, 0x16e2,
- 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000,
- 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0040,
- 0x16ec, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae,
- 0x0078, 0x16f5, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15c1, 0x75d8,
- 0x76dc, 0x75da, 0x76de, 0x0078, 0x1700, 0x2029, 0x0000, 0x2530,
- 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6,
- 0xa005, 0x0040, 0x172f, 0xa40a, 0x0040, 0x1710, 0x00c8, 0x1719,
- 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x171d, 0x78ac, 0xc0c5,
- 0x78ae, 0x2001, 0x4005, 0x0078, 0x15c3, 0x7a9a, 0x7b9e, 0x7da2,
- 0x7ea6, 0x2600, 0xa505, 0x0040, 0x1728, 0x7a10, 0xc2c5, 0x7a12,
- 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x1732, 0x78ac,
- 0xc0c5, 0x78ae, 0x0078, 0x15c1, 0x2009, 0x0000, 0x786c, 0xa065,
- 0x0040, 0x173e, 0x8108, 0x6000, 0x0078, 0x1737, 0x7ac4, 0x0078,
- 0x15bf, 0x2009, 0x4f48, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0,
- 0x2011, 0x4f88, 0x2214, 0x0078, 0x15bf, 0x2009, 0x4f49, 0x210c,
- 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f89, 0x2214, 0x0078,
- 0x15bf, 0x2061, 0x4f40, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214,
- 0x7810, 0xd0ec, 0x00c0, 0x176d, 0x2061, 0x4f80, 0x6328, 0x73da,
- 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15bf, 0x2009,
- 0x4f4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f8c,
- 0x2214, 0x0078, 0x15bf, 0x7918, 0x0078, 0x15c0, 0x2009, 0x4f4d,
- 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2011, 0x4f8d, 0x2214,
- 0x0078, 0x15bf, 0x2009, 0x4f4e, 0x210c, 0x7810, 0xd0ec, 0x00c0,
- 0x15c0, 0x2011, 0x4f8e, 0x2214, 0x0078, 0x15bf, 0x7920, 0x7810,
- 0xd0ec, 0x00c0, 0x15c0, 0x7a24, 0x0078, 0x15bf, 0x71c4, 0xd1fc,
- 0x00c0, 0x17a6, 0x2011, 0x53c0, 0x0078, 0x17a8, 0x2011, 0x5440,
- 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x6a00,
- 0x6804, 0xd09c, 0x0040, 0x17b7, 0x6b08, 0x0078, 0x17b8, 0x6b0c,
- 0xd1fc, 0x00c0, 0x17bf, 0x2021, 0x023b, 0x0078, 0x17c1, 0x2021,
- 0x013b, 0x2424, 0x7914, 0xd1e4, 0x0040, 0x17cd, 0xd4c4, 0x00c0,
- 0x17cc, 0xc4d5, 0x0078, 0x17cd, 0xc4dd, 0xa4a4, 0x1c00, 0x74de,
- 0x71c4, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000,
- 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15be, 0x2061,
- 0x4f40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2061, 0x4f80,
- 0x6218, 0x0078, 0x15bf, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000,
- 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15be,
- 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b9,
- 0x1078, 0x27c6, 0xa384, 0x4000, 0x0040, 0x1808, 0xa295, 0x0020,
- 0x0078, 0x15be, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8,
- 0x15b9, 0xd1bc, 0x00c0, 0x1819, 0x2011, 0x4f48, 0x2204, 0x0078,
- 0x181d, 0x2011, 0x4f88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc,
- 0x2012, 0x1078, 0x2723, 0x017f, 0x0078, 0x15c0, 0x71c4, 0x2021,
- 0x4f49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1835, 0x71c8,
- 0x2021, 0x4f89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1854, 0x20a9,
- 0x0008, 0x2204, 0xa106, 0x0040, 0x1844, 0x8210, 0x00f0, 0x1839,
- 0x71c4, 0x72c8, 0x0078, 0x15b8, 0xa292, 0x1854, 0x027e, 0x2122,
- 0x017f, 0x1078, 0x2744, 0x7810, 0xd0ec, 0x00c0, 0x1852, 0xd3fc,
- 0x0040, 0x182f, 0x0078, 0x15c1, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
- 0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4f40, 0x6128, 0x622c,
- 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
- 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1882, 0x027e, 0x017e,
- 0x2061, 0x4f80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
- 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
- 0x017f, 0x027f, 0x0078, 0x15bf, 0x2061, 0x4f40, 0x6130, 0x70c4,
- 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x2061, 0x4f80, 0x6230,
- 0x70c8, 0x6032, 0x0078, 0x15bf, 0x7918, 0x0078, 0x15c0, 0x71c4,
- 0xa184, 0xffcf, 0x0040, 0x18a3, 0x7810, 0xd0ec, 0x00c0, 0x15b9,
- 0x72c8, 0x0078, 0x15b8, 0x2011, 0x4f4d, 0x2204, 0x2112, 0x007e,
- 0x2019, 0x0000, 0x1078, 0x27ab, 0x7810, 0xd0ec, 0x0040, 0x18b3,
- 0x017f, 0x0078, 0x15c0, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x18bc,
- 0x2110, 0x71c4, 0x0078, 0x15b8, 0x2011, 0x4f8d, 0x2204, 0x2112,
- 0x007e, 0xc3fd, 0x1078, 0x27ab, 0x027f, 0x017f, 0x0078, 0x15bf,
- 0x71c4, 0xa182, 0x0010, 0x0048, 0x18d4, 0x7810, 0xd0ec, 0x00c0,
- 0x15b9, 0x72c8, 0x0078, 0x15b8, 0x2011, 0x4f4e, 0x2204, 0x007e,
- 0x2112, 0x2019, 0x0000, 0x1078, 0x2789, 0x7810, 0xd0ec, 0x0040,
- 0x18e4, 0x017f, 0x0078, 0x15c0, 0x71c8, 0xa182, 0x0010, 0x0048,
- 0x18ed, 0x2110, 0x71c4, 0x0078, 0x15b8, 0x2011, 0x4f8e, 0x2204,
- 0x007e, 0x2112, 0xc3fd, 0x1078, 0x2789, 0x027f, 0x017f, 0x0078,
- 0x15bf, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b8, 0xa284,
- 0xfffd, 0x00c0, 0x15b8, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24,
- 0x7826, 0x0078, 0x15bf, 0x71c4, 0xd1fc, 0x00c0, 0x1913, 0x2011,
- 0x53c0, 0x0078, 0x1915, 0x2011, 0x5440, 0x8107, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0xd2bc,
- 0x0040, 0x1924, 0xa39d, 0x0010, 0xd2b4, 0x0040, 0x1929, 0xa39d,
- 0x0008, 0x2091, 0x8000, 0x6800, 0x007e, 0xa226, 0x0040, 0x1948,
- 0x6a02, 0xd4ec, 0x0040, 0x1935, 0xc3a5, 0xd4e4, 0x0040, 0x1939,
- 0xc39d, 0xd4f4, 0x0040, 0x1948, 0x810f, 0xd2f4, 0x0040, 0x1944,
- 0x1078, 0x2808, 0x0078, 0x1948, 0x1078, 0x27e6, 0x0078, 0x1948,
- 0x72cc, 0x6808, 0xa206, 0x0040, 0x196a, 0xa2a4, 0x00ff, 0x7814,
- 0xd0e4, 0x00c0, 0x195b, 0xa482, 0x0028, 0x0048, 0x1967, 0x0040,
- 0x1967, 0x0078, 0x195f, 0xa482, 0x0043, 0x0048, 0x1967, 0x71c4,
- 0x71c6, 0x027f, 0x72ca, 0x2091, 0x8001, 0x0078, 0x15ba, 0x6a0a,
- 0xa39d, 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4,
- 0x2091, 0x8001, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b, 0x2091,
- 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc,
- 0x681e, 0x2708, 0x0078, 0x15be, 0x70c4, 0x2061, 0x4f40, 0x6118,
- 0x601a, 0x7810, 0xd0ec, 0x00c0, 0x15c0, 0x70c8, 0x2061, 0x4f80,
- 0x6218, 0x601a, 0x0078, 0x15bf, 0x71c4, 0x72c8, 0x73cc, 0xa182,
- 0x0010, 0x00c8, 0x15b9, 0x1078, 0x282a, 0xa384, 0x4000, 0x0040,
- 0x19a3, 0xa295, 0x0020, 0x0078, 0x15be, 0x77c4, 0x1078, 0x1e2b,
- 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x15bf, 0x77c4, 0x1078, 0x1e2b, 0x2091, 0x8000, 0x6a08,
- 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x19c1, 0x1078,
- 0x266f, 0x2091, 0x8001, 0x2708, 0x0078, 0x15bf, 0x77c4, 0x1078,
- 0x1e2b, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005,
- 0x0040, 0x19d4, 0x1078, 0x266f, 0x2091, 0x8001, 0x2708, 0x0078,
- 0x15bf, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020,
- 0x2091, 0x8000, 0x1078, 0x1e46, 0x2091, 0x8001, 0x2708, 0x6a08,
- 0x0078, 0x15bf, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19fe, 0xd7fc,
- 0x0040, 0x19f8, 0x1078, 0x1dae, 0x0040, 0x19fe, 0x0078, 0x15c3,
- 0x1078, 0x1da1, 0x0040, 0x19fe, 0x0078, 0x15c3, 0x73c8, 0x72cc,
- 0x77c6, 0x73ca, 0x72ce, 0x1078, 0x1ecd, 0x00c0, 0x1a28, 0x6818,
- 0xa005, 0x0040, 0x1a22, 0x2708, 0x077e, 0x1078, 0x285a, 0x077f,
- 0x00c0, 0x1a22, 0x2001, 0x0015, 0xd7fc, 0x00c0, 0x1a1b, 0x2061,
- 0x4f40, 0x0078, 0x1a1e, 0xc0fd, 0x2061, 0x4f80, 0x782a, 0x2091,
- 0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15c3,
- 0x2091, 0x8001, 0x0078, 0x15c1, 0x77c4, 0x7814, 0xd0e4, 0x00c0,
- 0x1a40, 0xd7fc, 0x0040, 0x1a3a, 0x1078, 0x1dae, 0x0040, 0x1a40,
- 0x0078, 0x15c3, 0x1078, 0x1da1, 0x0040, 0x1a40, 0x0078, 0x15c3,
- 0x77c6, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
- 0x8000, 0x1078, 0x1e46, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a54,
- 0x2061, 0x4f40, 0x0078, 0x1a57, 0x2061, 0x4f80, 0xc1fd, 0x6067,
- 0x0003, 0x607f, 0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4,
- 0xc1dc, 0x61d6, 0x1078, 0x266f, 0x2091, 0x8001, 0x007c, 0x77c8,
- 0x77ca, 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a7e, 0xd7fc,
- 0x0040, 0x1a78, 0x1078, 0x1dae, 0x0040, 0x1a7e, 0x0078, 0x15c3,
- 0x1078, 0x1da1, 0x0040, 0x1a7e, 0x0078, 0x15c3, 0xa7bc, 0xff00,
- 0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a8b, 0x2061,
- 0x4f40, 0x0078, 0x1a8e, 0x2061, 0x4f80, 0xc1fd, 0x607f, 0x0000,
- 0x6067, 0x0002, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc,
- 0x61d6, 0x1078, 0x266f, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049,
- 0x0005, 0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0040,
- 0x1aac, 0x60d4, 0xc0fd, 0x60d6, 0x1078, 0x1e46, 0x70c8, 0x6836,
- 0x8738, 0xa784, 0x001f, 0x00c0, 0x1aac, 0x2091, 0x8001, 0x007c,
- 0x2019, 0x0000, 0x7814, 0xd0e4, 0x00c0, 0x1ace, 0x72c8, 0xd284,
- 0x0040, 0x1ac8, 0x1078, 0x1dae, 0x0040, 0x1ace, 0x0078, 0x15c3,
- 0x1078, 0x1da1, 0x0040, 0x1ace, 0x0078, 0x15c3, 0x72c8, 0x72ca,
- 0x78ac, 0xa084, 0x0003, 0x00c0, 0x1af9, 0x2039, 0x0000, 0xd284,
- 0x0040, 0x1adb, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051,
- 0x0008, 0x1078, 0x1e2b, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d,
- 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ae1,
- 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0,
- 0x1ae1, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1b0b, 0x7810,
- 0xd0ec, 0x0040, 0x1b07, 0x2069, 0x0100, 0x0078, 0x1b0d, 0x2069,
- 0x0200, 0x0078, 0x1b0d, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd,
- 0x680a, 0x6830, 0xd0b4, 0x0040, 0x1b2d, 0x684b, 0x0004, 0x20a9,
- 0x0014, 0x6848, 0xd094, 0x0040, 0x1b1f, 0x00f0, 0x1b19, 0x684b,
- 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0040, 0x1b29, 0x00f0,
- 0x1b23, 0x20a9, 0x00fa, 0x00f0, 0x1b2b, 0x2079, 0x4f00, 0x2009,
- 0x0018, 0x72c8, 0xd284, 0x00c0, 0x1b39, 0x2061, 0x4f40, 0x0078,
- 0x1b3c, 0x2061, 0x4f80, 0xc1fd, 0x607f, 0x0000, 0x792a, 0x6067,
- 0x0001, 0x6083, 0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6,
- 0x60d4, 0xd0b4, 0x0040, 0x1b58, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8,
- 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f,
- 0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x83ff,
- 0x0040, 0x1b63, 0x007c, 0x681b, 0x0047, 0x2091, 0x8001, 0x007c,
- 0x73cc, 0x1078, 0x1aba, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a,
- 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff,
- 0x00f0, 0x1b78, 0x8421, 0x00c0, 0x1b76, 0x8319, 0x00c0, 0x1b74,
- 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b8c,
- 0x2069, 0x4f40, 0x0078, 0x1b8e, 0x2069, 0x4f80, 0x71c4, 0x71c6,
- 0x6916, 0x81ff, 0x00c0, 0x1b96, 0x68a7, 0x0001, 0x78ac, 0xc08c,
- 0x78ae, 0xd084, 0x00c0, 0x1b9e, 0x1078, 0x1f2d, 0x007c, 0x75d8,
- 0x74dc, 0x75da, 0x74de, 0x0078, 0x1ba7, 0xa02e, 0x2520, 0x71c4,
- 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4f00, 0x7dde,
- 0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1e04, 0x0040, 0x1cd1, 0x20a9,
- 0x0005, 0x20a1, 0x4f14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001,
- 0x2009, 0x0040, 0x1078, 0x2018, 0x0040, 0x1bca, 0x1078, 0x1e0d,
- 0x0078, 0x1cd1, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0,
- 0x1bd5, 0x007e, 0x1078, 0x23bf, 0x007f, 0xa084, 0xff00, 0x8007,
- 0x8009, 0x0040, 0x1c61, 0x0c7e, 0x2c68, 0x1078, 0x1e04, 0x0040,
- 0x1c1b, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1bdc, 0x609f, 0x0000,
- 0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
- 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c60, 0x2009,
- 0x0040, 0x1078, 0x2018, 0x00c0, 0x1c3e, 0x6004, 0xa084, 0x00ff,
- 0xa086, 0x0002, 0x00c0, 0x1c1b, 0x6004, 0xa084, 0x00ff, 0xa086,
- 0x000a, 0x00c0, 0x1c17, 0x017e, 0x1078, 0x23bb, 0x017f, 0x2d00,
- 0x6002, 0x0078, 0x1bea, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e90,
- 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6008,
- 0xc0cd, 0x600a, 0x6004, 0x6086, 0x7810, 0x007e, 0x84ff, 0x00c0,
- 0x1c34, 0x85ff, 0x0040, 0x1c36, 0xc0c5, 0x7812, 0x1078, 0x1dbb,
- 0x007f, 0x7812, 0x1078, 0x1e0d, 0x0078, 0x1cd1, 0x0c7f, 0x0c7e,
- 0x609c, 0x1078, 0x1e90, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1cd5,
- 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003, 0x7810, 0x007e,
- 0x84ff, 0x00c0, 0x1c56, 0x85ff, 0x0040, 0x1c58, 0xc0c5, 0x7812,
- 0x1078, 0x1dbb, 0x007f, 0x7812, 0x1078, 0x1e0d, 0x0078, 0x1cd1,
- 0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1c8f, 0x6114, 0xd1fc, 0x0040,
- 0x1c6f, 0x1078, 0x1dae, 0x0040, 0x1c8f, 0x0078, 0x1c73, 0x1078,
- 0x1da1, 0x0040, 0x1c8f, 0x1078, 0x1cd5, 0x2009, 0x0018, 0x6087,
- 0x0103, 0x601b, 0x0021, 0x7810, 0x007e, 0x84ff, 0x00c0, 0x1c83,
- 0x85ff, 0x0040, 0x1c85, 0xc0c5, 0x7812, 0x1078, 0x1dbb, 0x007f,
- 0x7812, 0x1078, 0x1e0d, 0x2001, 0x4007, 0x0078, 0x15c3, 0x74c4,
- 0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012,
- 0xd0fc, 0x00c0, 0x1c9f, 0x2071, 0x4f40, 0x0078, 0x1ca2, 0x2071,
- 0x4f80, 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6,
- 0x736a, 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e,
- 0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1cb9, 0x1078,
- 0x46b6, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000,
- 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x6024, 0xa096, 0x0001,
- 0x00c0, 0x1ccc, 0x8000, 0x6026, 0x1078, 0x266f, 0x2091, 0x8001,
- 0x007c, 0x70c3, 0x4005, 0x0078, 0x15c4, 0x20a9, 0x0005, 0x2099,
- 0x4f14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210,
- 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4,
- 0x70c7, 0x0000, 0x791e, 0x0078, 0x15c1, 0x71c4, 0x71c6, 0x2168,
- 0x0078, 0x1cf4, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210,
- 0x8d68, 0x8109, 0x00c0, 0x1cf6, 0xa285, 0x0000, 0x00c0, 0x1d04,
- 0x70c3, 0x4000, 0x0078, 0x1d06, 0x70c3, 0x4003, 0x70ca, 0x0078,
- 0x15c4, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b9,
- 0x7966, 0x0078, 0x15c1, 0x7964, 0x71c6, 0x0078, 0x15c1, 0x7900,
- 0x71c6, 0x71c4, 0x7902, 0x0078, 0x15c1, 0x7900, 0x71c6, 0x0078,
- 0x15c1, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1d36,
- 0x810c, 0x0048, 0x1d32, 0x8210, 0x810c, 0x810c, 0x0048, 0x1d32,
- 0x8210, 0x810c, 0x81ff, 0x00c0, 0x15ba, 0x8210, 0x7a0e, 0xd28c,
- 0x0040, 0x1d62, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019,
- 0x0003, 0xd284, 0x0040, 0x1d5c, 0x8108, 0x2019, 0x0041, 0x2011,
- 0x974e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043,
- 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047,
- 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9753, 0x2112, 0x2011,
- 0x9773, 0x2312, 0x7904, 0x7806, 0x0078, 0x15c0, 0x7804, 0x70c6,
- 0x0078, 0x15c1, 0x71c4, 0xd1fc, 0x00c0, 0x1d72, 0x2011, 0x53c0,
- 0x0078, 0x1d74, 0x2011, 0x5440, 0x8107, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d83, 0x2011,
- 0x0001, 0x0078, 0x1d85, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da,
- 0x0078, 0x15be, 0x7814, 0xd0f4, 0x0040, 0x1d95, 0x2001, 0x4007,
- 0x70db, 0x0000, 0xa005, 0x0078, 0x1da0, 0xd0fc, 0x0040, 0x1d9f,
- 0x2001, 0x4007, 0x70db, 0x0001, 0xa005, 0x0078, 0x1da0, 0xa006,
- 0x007c, 0x7814, 0xd0f4, 0x0040, 0x1dac, 0x2001, 0x4007, 0x70db,
- 0x0000, 0xa005, 0x0078, 0x1dad, 0xa006, 0x007c, 0x7814, 0xd0fc,
- 0x0040, 0x1db9, 0x2001, 0x4007, 0x70db, 0x0001, 0xa005, 0x0078,
- 0x1dba, 0xa006, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4,
- 0x0040, 0x1dc4, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c,
- 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2,
- 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1de1,
- 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078,
- 0x1de4, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006,
- 0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1df1, 0x7b84, 0xa319, 0x7c80,
- 0xa421, 0x7008, 0xd0fc, 0x0040, 0x1df1, 0x7003, 0x0001, 0x7007,
- 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1e01, 0x7322,
- 0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1e0c,
- 0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4f00,
- 0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1e18, 0x1078, 0x29b2,
- 0x784a, 0x0f7f, 0x007c, 0x2011, 0x9900, 0x7a4a, 0x7bc4, 0x8319,
- 0x0040, 0x1e28, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1e1f,
- 0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1e34,
- 0x2011, 0x54c0, 0x0078, 0x1e36, 0x2011, 0x74c0, 0xa784, 0x0f00,
- 0x800b, 0xa784, 0x001f, 0x0040, 0x1e41, 0x8003, 0x8003, 0x8003,
- 0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1e2b,
- 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d,
- 0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1e5b, 0x2009, 0x4f53, 0x2071,
- 0x4f40, 0x0078, 0x1e5f, 0x2009, 0x4f93, 0x2071, 0x4f80, 0x210c,
- 0x6804, 0xa005, 0x0040, 0x1e6f, 0xa116, 0x00c0, 0x1e6f, 0x2060,
- 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e72, 0x2009,
- 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e87, 0x6000, 0x6806,
- 0x1078, 0x1ea2, 0x1078, 0x2064, 0x6810, 0x7908, 0x8109, 0x790a,
- 0x8001, 0x6812, 0x00c0, 0x1e72, 0x7910, 0xc1a5, 0x7912, 0x017f,
- 0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2b13, 0x0e7f, 0x007c,
- 0xa065, 0x0040, 0x1ea1, 0x2008, 0x609c, 0xa005, 0x0040, 0x1e9e,
- 0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e94, 0x7848, 0x794a,
- 0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9, 0x001c,
- 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828, 0x601a,
- 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1ebd, 0x2071,
- 0x4f40, 0x2031, 0x4fc0, 0x0078, 0x1ec1, 0x2071, 0x4f80, 0x2031,
- 0x51c0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1ecb, 0xa608, 0x2d0a,
- 0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0,
- 0x1ed5, 0x2079, 0x4f40, 0x0078, 0x1ed7, 0x2079, 0x4f80, 0x1078,
- 0x1e2b, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040, 0x1f2b,
- 0x0078, 0x1ee9, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065, 0x0040,
- 0x1f2b, 0x6010, 0xa306, 0x00c0, 0x1ee2, 0x600c, 0xa206, 0x00c0,
- 0x1ee2, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1ef8, 0x0078, 0x1f28,
- 0x6804, 0xac06, 0x00c0, 0x1f06, 0x6000, 0x2060, 0x6806, 0xa005,
- 0x00c0, 0x1f06, 0x6803, 0x0000, 0x0078, 0x1f10, 0x6400, 0x7808,
- 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1f10, 0x2c00, 0x6802,
- 0x2560, 0x0f7f, 0x1078, 0x1ea2, 0x0f7e, 0x601b, 0x0005, 0x6023,
- 0x0020, 0x0f7f, 0x1078, 0x2064, 0x0f7e, 0x7908, 0x8109, 0x790a,
- 0x6810, 0x8001, 0x6812, 0x00c0, 0x1f28, 0x7810, 0xc0a5, 0x7812,
- 0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039,
- 0x0000, 0xd0fc, 0x0040, 0x1f35, 0xc7fd, 0x2041, 0x0021, 0x2049,
- 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1e46, 0x8738,
- 0xa784, 0x001f, 0x00c0, 0x1f3d, 0xa7bc, 0xff00, 0x873f, 0x8738,
- 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1f3d, 0x2091, 0x8001, 0x077f,
- 0x007c, 0x786c, 0x2009, 0x9774, 0x210c, 0xa10d, 0x0040, 0x1f5b,
- 0xa065, 0x0078, 0x23dc, 0x2061, 0x0000, 0x6018, 0xd084, 0x00c0,
- 0x1f7b, 0x7810, 0xd08c, 0x0040, 0x1f6c, 0xc08c, 0x7812, 0xc7fc,
- 0x2069, 0x4f40, 0x0078, 0x1f71, 0xc08d, 0x7812, 0x2069, 0x4f80,
- 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001,
- 0xa005, 0x00c0, 0x1f7c, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1f82,
- 0x1078, 0x29b2, 0x0079, 0x1f84, 0x1f94, 0x1f97, 0x1f9d, 0x1fa1,
- 0x1f95, 0x1fa5, 0x1f95, 0x1f95, 0x1f95, 0x1fab, 0x1fdc, 0x1fe0,
- 0x1fe6, 0x1ffb, 0x1f95, 0x1f95, 0x007c, 0x1078, 0x29b2, 0x1078,
- 0x1f2d, 0x2001, 0x8001, 0x0078, 0x2007, 0x2001, 0x8003, 0x0078,
- 0x2007, 0x2001, 0x8004, 0x0078, 0x2007, 0x1078, 0x1f2d, 0x2001,
- 0x8006, 0x0078, 0x2007, 0x2091, 0x8000, 0x077e, 0xd7fc, 0x00c0,
- 0x1fb7, 0x2069, 0x4f40, 0x2039, 0x0009, 0x0078, 0x1fbb, 0x2069,
- 0x4f80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040, 0x1fc5,
- 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f, 0xa0bc,
- 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010, 0x1078,
- 0x1e46, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1fcf, 0x2091, 0x8001,
- 0x2001, 0x800a, 0x0078, 0x2007, 0x2001, 0x800c, 0x0078, 0x2007,
- 0x1078, 0x1f2d, 0x2001, 0x800d, 0x0078, 0x2007, 0x7814, 0xd0e4,
- 0x00c0, 0x1ff9, 0xd0ec, 0x0040, 0x1ff3, 0xd7fc, 0x0040, 0x1ff3,
- 0x78e4, 0x0078, 0x1ff4, 0x78e0, 0x70c6, 0x2001, 0x800e, 0x0078,
- 0x2007, 0x0078, 0x1f95, 0xd7fc, 0x0040, 0x2001, 0x78ec, 0x0078,
- 0x2002, 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0078, 0x2007, 0x70c2,
- 0xd7fc, 0x00c0, 0x200f, 0x70db, 0x0000, 0x0078, 0x2011, 0x70db,
- 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c,
- 0xac80, 0x0001, 0x81ff, 0x0040, 0x2043, 0x2099, 0x0030, 0x20a0,
- 0x700c, 0xa084, 0x03ff, 0x0040, 0x2025, 0x7018, 0x007e, 0x701c,
- 0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a,
- 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008,
- 0x800b, 0x00c8, 0x2037, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
- 0x2043, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f,
- 0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c,
- 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00,
- 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
- 0x8109, 0x00c0, 0x2054, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063,
- 0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x2071, 0x2c02, 0x0078,
- 0x2072, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4f00, 0x6887, 0x0103,
- 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x2083,
- 0x2d02, 0x0078, 0x2084, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000,
- 0x2c04, 0x786e, 0xa005, 0x00c0, 0x208e, 0x786a, 0x2091, 0x8001,
- 0x609c, 0xa005, 0x0040, 0x20a7, 0x0c7e, 0x2060, 0x2008, 0x609c,
- 0xa005, 0x0040, 0x20a3, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c,
- 0xa005, 0x00c0, 0x209b, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848,
- 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x20b1, 0x1078,
- 0x29b2, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086,
- 0x818e, 0x00c8, 0x20bc, 0xa200, 0x00f0, 0x20b7, 0x8086, 0x818e,
- 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x20e2, 0xa11a,
- 0x00c8, 0x20e2, 0x8213, 0x818d, 0x0048, 0x20d5, 0xa11a, 0x00c8,
- 0x20d6, 0x00f0, 0x20ca, 0x0078, 0x20da, 0xa11a, 0x2308, 0x8210,
- 0x00f0, 0x20ca, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f,
- 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x20de,
- 0x7d74, 0x70d0, 0xa506, 0x0040, 0x21ce, 0x7810, 0x2050, 0x7800,
- 0xd08c, 0x0040, 0x210a, 0xdaec, 0x0040, 0x210a, 0x0e7e, 0x2091,
- 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2107, 0x7008,
- 0x0e7f, 0xa086, 0x0008, 0x0040, 0x210a, 0x0078, 0x21ce, 0x0e7f,
- 0x0078, 0x21ce, 0x1078, 0x1e04, 0x0040, 0x21ce, 0xa046, 0x7970,
- 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x2119, 0x0078,
- 0x2120, 0x72d0, 0xa206, 0x0040, 0x2120, 0x8840, 0x2009, 0x0080,
- 0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020,
- 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x2132,
- 0x1078, 0x1e04, 0x7008, 0xd0fc, 0x0040, 0x2132, 0x7007, 0x0002,
- 0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2169, 0x53a5, 0x8cff,
- 0x00c0, 0x2147, 0x88ff, 0x0040, 0x21b8, 0x0078, 0x2151, 0x2c00,
- 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078,
- 0x21b8, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2159, 0x7420,
- 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab,
- 0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2169, 0x7422, 0x7526,
- 0xa006, 0x7007, 0x0004, 0x0040, 0x21b8, 0x8cff, 0x0040, 0x2172,
- 0x1078, 0x1e0d, 0x0c7f, 0x1078, 0x1e0d, 0xa046, 0x7888, 0x8000,
- 0x788a, 0xa086, 0x0002, 0x0040, 0x2198, 0x7a7c, 0x7b78, 0xdac4,
- 0x0040, 0x2184, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004,
- 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a,
- 0x731e, 0xdac4, 0x0040, 0x21ce, 0x7422, 0x7526, 0x0078, 0x21ce,
- 0x6014, 0xd0fc, 0x00c0, 0x21a0, 0x2069, 0x4f40, 0x0078, 0x21a2,
- 0x2069, 0x4f80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040,
- 0x21ae, 0xa046, 0x788c, 0x2060, 0x0078, 0x2198, 0x788b, 0x0000,
- 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x21ce,
- 0x0c7f, 0x788b, 0x0000, 0x1078, 0x238d, 0x6004, 0xa084, 0x000f,
- 0x1078, 0x21cf, 0x88ff, 0x0040, 0x21cc, 0x788c, 0x2060, 0x6004,
- 0xa084, 0x000f, 0x1078, 0x21cf, 0x0078, 0x20e8, 0x007c, 0x0079,
- 0x21d1, 0x21e1, 0x21ff, 0x221d, 0x21e1, 0x222e, 0x21f2, 0x21e1,
- 0x21e1, 0x21e1, 0x21fd, 0x221b, 0x21e1, 0x21e1, 0x21e1, 0x21e1,
- 0x21e1, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705,
- 0x600a, 0x1078, 0x2271, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078,
- 0x2377, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21f8, 0x0078, 0x21e1,
- 0x601c, 0xc0bd, 0x601e, 0x0078, 0x2205, 0x1078, 0x23bf, 0x78bc,
- 0xd0c4, 0x0040, 0x2205, 0x0078, 0x21e1, 0x78bf, 0x0000, 0x6004,
- 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x2218, 0x1078,
- 0x2271, 0x0040, 0x2218, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x221a,
- 0x0078, 0x2290, 0x007c, 0x1078, 0x23bb, 0x78bc, 0xa08c, 0x0e00,
- 0x00c0, 0x2225, 0xd0c4, 0x00c0, 0x2227, 0x0078, 0x21e1, 0x1078,
- 0x2271, 0x00c0, 0x222d, 0x0078, 0x2290, 0x007c, 0x78bc, 0xd0c4,
- 0x0040, 0x2234, 0x0078, 0x21e1, 0x78bf, 0x0000, 0x6714, 0x2011,
- 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x2254,
- 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x2254,
- 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002,
- 0x0040, 0x2254, 0x0078, 0x226e, 0x1078, 0x1e2b, 0x2d00, 0x2091,
- 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde,
- 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x2257, 0x8211,
- 0x0040, 0x226e, 0x20a9, 0x0100, 0x0078, 0x2257, 0x1078, 0x1e0d,
- 0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0,
- 0x227c, 0x78ba, 0x0078, 0x2284, 0x689e, 0x2d00, 0x6002, 0x78b8,
- 0xad06, 0x00c0, 0x2284, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0,
- 0x228f, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c,
- 0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c,
- 0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040,
- 0x22a3, 0x1078, 0x46b6, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714,
- 0x2071, 0x4f80, 0xd7fc, 0x00c0, 0x22af, 0x2071, 0x4f40, 0xa784,
- 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x22ba, 0x8003, 0x8003,
- 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084,
- 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091,
- 0x8000, 0x7814, 0xd0c4, 0x0040, 0x22df, 0xd0ec, 0x0040, 0x22db,
- 0xd7fc, 0x00c0, 0x22d8, 0xd0f4, 0x00c0, 0x22e6, 0x0078, 0x22df,
- 0xd0fc, 0x00c0, 0x22e6, 0x7810, 0xd0f4, 0x00c0, 0x22e6, 0x6e08,
- 0xd684, 0x0040, 0x2310, 0xd9fc, 0x00c0, 0x2310, 0x2091, 0x8001,
- 0x1078, 0x1ea2, 0x2091, 0x8000, 0x1078, 0x2064, 0x2091, 0x8001,
- 0x7814, 0xd0e4, 0x00c0, 0x2375, 0x7814, 0xd0c4, 0x0040, 0x2375,
- 0xd0ec, 0x0040, 0x2308, 0xd7fc, 0x00c0, 0x2303, 0xd0f4, 0x00c0,
- 0x230c, 0x0078, 0x2375, 0xd0fc, 0x00c0, 0x230c, 0x0078, 0x2375,
- 0x7810, 0xd0f4, 0x0040, 0x2375, 0x601b, 0x0021, 0x0078, 0x2375,
- 0x6024, 0xa096, 0x0001, 0x00c0, 0x2317, 0x8000, 0x6026, 0x6a10,
- 0x6814, 0xa202, 0x0048, 0x232a, 0x0040, 0x232a, 0x2091, 0x8001,
- 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, 0x2377,
- 0x0078, 0x2375, 0x2c08, 0xd9fc, 0x0040, 0x2352, 0x6800, 0xa065,
- 0x0040, 0x2352, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040, 0x2348,
- 0x704c, 0xa206, 0x00c0, 0x2348, 0x6b04, 0x2160, 0x2304, 0x6002,
- 0xa005, 0x00c0, 0x2344, 0x6902, 0x2260, 0x6102, 0x0078, 0x235e,
- 0x2d00, 0x2060, 0x1078, 0x2b13, 0x6e08, 0x2160, 0x6202, 0x6906,
- 0x0078, 0x235e, 0x6800, 0x6902, 0xa065, 0x0040, 0x235a, 0x6102,
- 0x0078, 0x235b, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0xd9fc,
- 0x0040, 0x2365, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08, 0x8528,
- 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040, 0x2375,
- 0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1eb3, 0x0e7f, 0x007c, 0x6008,
- 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x2064, 0x2091, 0x8001,
- 0x78b8, 0xa065, 0x0040, 0x238a, 0x609c, 0x78ba, 0x609f, 0x0000,
- 0x0078, 0x2377, 0x78b6, 0x78ba, 0x007c, 0x7970, 0x7874, 0x2818,
- 0xd384, 0x0040, 0x2397, 0x8000, 0xa112, 0x0048, 0x239c, 0x8000,
- 0xa112, 0x00c8, 0x23ac, 0xc384, 0x7a7c, 0x721a, 0x7a78, 0x721e,
- 0xdac4, 0x0040, 0x23a7, 0x7a84, 0x7222, 0x7a80, 0x7226, 0xa006,
- 0xd384, 0x0040, 0x23ac, 0x8000, 0x7876, 0x70d2, 0x781c, 0xa005,
- 0x0040, 0x23ba, 0x8001, 0x781e, 0x00c0, 0x23ba, 0x0068, 0x23ba,
- 0x2091, 0x4080, 0x007c, 0x2039, 0x23d3, 0x0078, 0x23c1, 0x2039,
- 0x23d9, 0x2704, 0xa005, 0x0040, 0x23d2, 0xac00, 0x2068, 0x6908,
- 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738,
- 0x0078, 0x23c1, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
- 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, 0x780c, 0x0079,
- 0x23e1, 0x25b3, 0x2586, 0x23e5, 0x245e, 0x2039, 0x9774, 0x2734,
- 0x7d10, 0x0078, 0x2405, 0x6084, 0xa086, 0x0103, 0x00c0, 0x2447,
- 0x6114, 0x6018, 0xa105, 0x0040, 0x23fa, 0x86ff, 0x00c0, 0x2416,
- 0x0078, 0x2447, 0x8603, 0xa080, 0x9755, 0x620c, 0x2202, 0x8000,
- 0x6210, 0x2202, 0x1078, 0x2086, 0x8630, 0xa68e, 0x000f, 0x0040,
- 0x24d2, 0x786c, 0xa065, 0x00c0, 0x23eb, 0x7808, 0xa602, 0x00c8,
- 0x2416, 0xd5ac, 0x00c0, 0x2416, 0x263a, 0x007c, 0xa682, 0x0003,
- 0x00c8, 0x24d2, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084,
- 0x00c0, 0x2442, 0x2011, 0x9755, 0x2204, 0x70c6, 0x8210, 0x2204,
- 0x70ca, 0xd684, 0x00c0, 0x2432, 0x8210, 0x2204, 0x70da, 0x8210,
- 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091,
- 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b,
- 0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x24d2, 0x263a,
- 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c, 0xa065, 0x00c0, 0x23eb,
- 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x2459,
- 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x25e0, 0x2039, 0x9774,
- 0x2734, 0x7d10, 0x0078, 0x247a, 0x6084, 0xa086, 0x0103, 0x00c0,
- 0x24bb, 0x6114, 0x6018, 0xa105, 0x0040, 0x2473, 0x86ff, 0x00c0,
- 0x248b, 0x0078, 0x24bb, 0xa680, 0x9755, 0x620c, 0x2202, 0x1078,
- 0x2086, 0x8630, 0xa68e, 0x001e, 0x0040, 0x24d2, 0x786c, 0xa065,
- 0x00c0, 0x2464, 0x7808, 0xa602, 0x00c8, 0x248b, 0xd5ac, 0x00c0,
- 0x248b, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, 0x24d2, 0x2091,
- 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x24b6, 0x2011,
- 0x9755, 0x2009, 0x974e, 0x26a8, 0x211c, 0x2204, 0x201a, 0x8108,
- 0x8210, 0x00f0, 0x249c, 0xa685, 0x8030, 0x70c2, 0x681b, 0x0001,
- 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001,
- 0xa006, 0x2009, 0x9775, 0x200a, 0x203a, 0x007c, 0x7810, 0xc0ad,
- 0x7812, 0x0078, 0x24d2, 0x263a, 0x1078, 0x25bd, 0x00c0, 0x25e0,
- 0x786c, 0xa065, 0x00c0, 0x2464, 0x2091, 0x8000, 0x7810, 0xa084,
- 0xffcf, 0x86ff, 0x0040, 0x24cd, 0xc0ad, 0x7812, 0x2091, 0x8001,
- 0x0078, 0x25e0, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994, 0x70d4,
- 0xa102, 0x0048, 0x24e3, 0x0040, 0x24ed, 0x7b90, 0xa302, 0x00c0,
- 0x24ed, 0x0078, 0x24e6, 0x8002, 0x00c0, 0x24ed, 0x263a, 0x7810,
- 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, 0xff00, 0x0040,
- 0x24fa, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
- 0x0078, 0x24fd, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, 0x721a,
- 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, 0x250d, 0x7aa4,
- 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030, 0x7003,
- 0x0000, 0x2009, 0x9754, 0x260a, 0x8109, 0x2198, 0x2104, 0xd084,
- 0x0040, 0x251b, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, 0x8603,
- 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8,
- 0x252a, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0040, 0x2539,
- 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078,
- 0x253c, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006,
- 0xa211, 0xd4c4, 0x0040, 0x2548, 0x7b84, 0xa319, 0x7c80, 0xa421,
- 0x7008, 0xd0fc, 0x0040, 0x2548, 0xa084, 0x01e0, 0x0040, 0x256d,
- 0x7d10, 0x2031, 0x9754, 0x2634, 0x78a8, 0x8000, 0x78aa, 0xd08c,
- 0x00c0, 0x2562, 0x7007, 0x0006, 0x7004, 0xd094, 0x00c0, 0x255c,
- 0x0078, 0x24d4, 0x2069, 0x4f47, 0x206b, 0x0003, 0x78ac, 0xa085,
- 0x0300, 0x78ae, 0xa006, 0x0078, 0x2576, 0x2030, 0x75d6, 0x2091,
- 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001,
- 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a, 0x721e,
- 0xd5c4, 0x0040, 0x2585, 0x7322, 0x7426, 0x007c, 0x6084, 0xa086,
- 0x0103, 0x00c0, 0x25a9, 0x6114, 0x6018, 0xa105, 0x00c0, 0x25a9,
- 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x25a9, 0x600c, 0x70c6,
- 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091, 0x4080,
- 0x1078, 0x2086, 0x0068, 0x25a8, 0x786c, 0xa065, 0x00c0, 0x2586,
- 0x007c, 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c, 0xa065, 0x00c0,
- 0x2586, 0x0078, 0x25e0, 0x1078, 0x25bd, 0x00c0, 0x25e0, 0x786c,
- 0xa065, 0x00c0, 0x25b3, 0x0078, 0x25e0, 0x6084, 0xa086, 0x0103,
- 0x00c0, 0x25d1, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004, 0x00c0,
- 0x25d1, 0x7804, 0xd0a4, 0x0040, 0x25d1, 0x1078, 0x2086, 0xa006,
- 0x007c, 0x1078, 0x25e6, 0x00c0, 0x25d8, 0xa085, 0x0001, 0x007c,
- 0x1078, 0x25f5, 0x00c0, 0x25de, 0x2041, 0x0001, 0x7d10, 0x007c,
- 0x88ff, 0x0040, 0x25e5, 0x2091, 0x4080, 0x007c, 0x7b90, 0x7994,
- 0x70d4, 0xa102, 0x00c0, 0x25ef, 0xa385, 0x0000, 0x007c, 0x0048,
- 0x25f3, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, 0x0040,
- 0x260d, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005,
- 0x00c0, 0x260a, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x260d,
- 0x0078, 0x265e, 0x0e7f, 0x0078, 0x265e, 0xa184, 0xff00, 0x0040,
- 0x261a, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
- 0x0078, 0x261d, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4,
- 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018,
- 0x6028, 0xa005, 0x0040, 0x262e, 0x2009, 0x0040, 0x1078, 0x1dbb,
- 0x0040, 0x2650, 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, 0x265e,
- 0x6014, 0xd0fc, 0x00c0, 0x2640, 0x2069, 0x4f40, 0x0078, 0x2642,
- 0x2069, 0x4f80, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000,
- 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, 0x265e,
- 0x78ab, 0x0000, 0x1078, 0x2086, 0x7990, 0x7894, 0x8000, 0xa10a,
- 0x00c8, 0x265b, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010,
- 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x266a, 0x2009, 0x4f59,
- 0x0078, 0x266c, 0x2009, 0x4f99, 0x2091, 0x8000, 0x200a, 0x0f7e,
- 0xd7fc, 0x00c0, 0x2683, 0x2009, 0x4f40, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x0040, 0x267f, 0x2079, 0x0100, 0x0078, 0x2687, 0x2079,
- 0x0200, 0x0078, 0x2687, 0x2009, 0x4f80, 0x2079, 0x0100, 0x2104,
- 0xa086, 0x0000, 0x00c0, 0x26a0, 0xd7fc, 0x00c0, 0x2693, 0x2009,
- 0x4f45, 0x0078, 0x2695, 0x2009, 0x4f85, 0x2104, 0xa005, 0x00c0,
- 0x26a0, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x26a0, 0x781b, 0x0045,
- 0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, 0x4f00, 0x6810, 0xd0ec,
- 0x00c0, 0x270f, 0x2071, 0x4f80, 0x2079, 0x0100, 0x2021, 0x51bf,
- 0x784b, 0x000f, 0x2019, 0x44a7, 0xd184, 0x0040, 0x26c3, 0x6810,
- 0xd0ec, 0x0040, 0x26bf, 0x20a1, 0x012b, 0x0078, 0x26c5, 0x20a1,
- 0x022b, 0x0078, 0x26c5, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040,
- 0x26d2, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318,
- 0x0078, 0x26c5, 0x789b, 0x0020, 0x20a9, 0x0010, 0x6814, 0xd0e4,
- 0x0040, 0x26e2, 0x78af, 0x0000, 0x78af, 0x9020, 0x00f0, 0x26da,
- 0x0078, 0x26e8, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0, 0x26e2,
- 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040, 0x26f1,
- 0xc1bd, 0x1078, 0x28e2, 0x017f, 0x7020, 0xa084, 0x000f, 0x007e,
- 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x2701, 0xa085, 0x6340, 0x0078,
- 0x2703, 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843, 0x00d8,
- 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000, 0x8109,
- 0x0040, 0x2722, 0x2071, 0x4f40, 0x6810, 0xd0ec, 0x0040, 0x271c,
- 0x2079, 0x0100, 0x0078, 0x271e, 0x2079, 0x0200, 0x2021, 0x4fbf,
- 0x0078, 0x26b0, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x2737, 0x007e,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2733, 0x2011,
- 0x0101, 0x0078, 0x2739, 0x2011, 0x0201, 0x0078, 0x2739, 0x2011,
- 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012,
- 0x017f, 0x1078, 0x28e2, 0x007c, 0xd3fc, 0x00c0, 0x2757, 0x007e,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2753, 0x2011,
- 0x0101, 0x0078, 0x2759, 0x2011, 0x0201, 0x0078, 0x2759, 0x2011,
- 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, 0x275b, 0xa18c, 0x0e00,
- 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019, 0x0002,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x0040, 0x2773, 0x8319, 0x2009,
- 0x0101, 0x0078, 0x2775, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213,
- 0x00f0, 0x2777, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205,
- 0x200a, 0x8319, 0x0040, 0x2788, 0x2009, 0x0201, 0x0078, 0x2775,
- 0x007c, 0xd3fc, 0x00c0, 0x279c, 0x007e, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x007f, 0x0040, 0x2798, 0x2011, 0x0101, 0x0078, 0x279e,
- 0x2011, 0x0201, 0x0078, 0x279e, 0x2011, 0x0101, 0x20a9, 0x000c,
- 0x810b, 0x00f0, 0x27a0, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff,
- 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x27be, 0x007e, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27ba, 0x2011, 0x0102,
- 0x0078, 0x27c0, 0x2011, 0x0202, 0x0078, 0x27c0, 0x2011, 0x0102,
- 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e, 0xd1bc,
- 0x00c0, 0x27da, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x27d6, 0x2061, 0x0100, 0x0078, 0x27dc, 0x2061, 0x0200,
- 0x0078, 0x27dc, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080,
- 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc,
- 0x00c0, 0x27fa, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x27f6, 0x2061, 0x0100, 0x0078, 0x27fc, 0x2061, 0x0200,
- 0x0078, 0x27fc, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080,
- 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c,
- 0x0c7e, 0xd1bc, 0x00c0, 0x281c, 0x007e, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x007f, 0x0040, 0x2818, 0x2061, 0x0100, 0x0078, 0x281e,
- 0x2061, 0x0200, 0x0078, 0x281e, 0x2061, 0x0100, 0xc1bc, 0x8103,
- 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020, 0x60ae,
- 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x283e, 0x007e, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x283a, 0x2061, 0x0100,
- 0x0078, 0x2840, 0x2061, 0x0200, 0x0078, 0x2840, 0x2061, 0x0100,
- 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c,
- 0x0020, 0x0040, 0x284e, 0xc2ac, 0xa39d, 0x4000, 0xc3fc, 0xd3b4,
- 0x00c0, 0x2853, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018,
- 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818, 0xa005,
- 0x0040, 0x28c0, 0xd1fc, 0x0040, 0x2869, 0x2061, 0x96d0, 0x0078,
- 0x286b, 0x2061, 0x95c0, 0x1078, 0x28c8, 0x0040, 0x28a2, 0x20a9,
- 0x0101, 0xd1fc, 0x0040, 0x2878, 0x2061, 0x95d0, 0x0078, 0x287a,
- 0x2061, 0x94c0, 0x0c7e, 0x1078, 0x28c8, 0x0040, 0x2885, 0x0c7f,
- 0x8c60, 0x00f0, 0x287a, 0x0078, 0x28c0, 0x007f, 0xd1fc, 0x0040,
- 0x288f, 0xa082, 0x95d0, 0x2071, 0x4f80, 0x0078, 0x2893, 0xa082,
- 0x94c0, 0x2071, 0x4f40, 0x707a, 0x7176, 0x2138, 0x2001, 0x0004,
- 0x7066, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x1078, 0x2663,
- 0x0078, 0x28bc, 0xd1fc, 0x00c0, 0x28a9, 0x2071, 0x4f40, 0x0078,
- 0x28ab, 0x2071, 0x4f80, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2138,
- 0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, 0x000f, 0x71d4,
- 0xc1dc, 0x71d6, 0x1078, 0x2663, 0x2001, 0x0000, 0x0078, 0x28c2,
- 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f, 0x007c,
- 0x2c04, 0xa005, 0x0040, 0x28df, 0x2060, 0x6010, 0xa306, 0x00c0,
- 0x28dc, 0x600c, 0xa206, 0x00c0, 0x28dc, 0x6014, 0xa106, 0x00c0,
- 0x28dc, 0xa006, 0x0078, 0x28e1, 0x6000, 0x0078, 0x28c9, 0xa085,
- 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0, 0x28fa,
- 0x2079, 0x4f40, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x28f6, 0x2071, 0x0100, 0x0078, 0x28fe, 0x2071, 0x0200,
- 0x0078, 0x28fe, 0x2079, 0x4f80, 0x2071, 0x0100, 0x7920, 0xa18c,
- 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x2908, 0x017f, 0x0078, 0x2923,
- 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0, 0x2920,
- 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x291c,
- 0xa18d, 0x0f00, 0x0078, 0x2922, 0xa18d, 0x0f00, 0x0078, 0x2922,
- 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e, 0x2001,
- 0x4f01, 0x2004, 0xd0ac, 0x00c0, 0x29a3, 0x68e4, 0xd0ac, 0x0040,
- 0x29a3, 0xa084, 0x0006, 0x00c0, 0x29a3, 0x6014, 0xd0fc, 0x00c0,
- 0x293d, 0x2071, 0x53c0, 0x0078, 0x293f, 0x2071, 0x5440, 0x8007,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084,
- 0x000a, 0x00c0, 0x29a3, 0x7108, 0xa194, 0xff00, 0x0040, 0x29a3,
- 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x2972, 0x2001,
- 0x000c, 0xa106, 0x0040, 0x2976, 0x2001, 0x0012, 0xa106, 0x0040,
- 0x297a, 0x2001, 0x0014, 0xa106, 0x0040, 0x297e, 0x2001, 0x0019,
- 0xa106, 0x0040, 0x2982, 0x2001, 0x0032, 0xa106, 0x0040, 0x2986,
- 0x0078, 0x298a, 0x2009, 0x000c, 0x0078, 0x298c, 0x2009, 0x0012,
- 0x0078, 0x298c, 0x2009, 0x0014, 0x0078, 0x298c, 0x2009, 0x0019,
- 0x0078, 0x298c, 0x2009, 0x0020, 0x0078, 0x298c, 0x2009, 0x003f,
- 0x0078, 0x298c, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x2071,
- 0x4f00, 0x7004, 0xd0bc, 0x0040, 0x29a3, 0x6014, 0xd0fc, 0x00c0,
- 0x299e, 0x70ea, 0x2071, 0x4f40, 0x0078, 0x29a1, 0x70ee, 0x2071,
- 0x4f80, 0x701f, 0x000d, 0x0e7f, 0x007c, 0x2001, 0x4f05, 0x2004,
- 0xd0e4, 0x00c0, 0x29b1, 0x7804, 0xa084, 0xff1f, 0xa085, 0x6340,
- 0x7806, 0x007c, 0x0068, 0x29b2, 0x2091, 0x8000, 0x2071, 0x0000,
- 0x007e, 0x7018, 0xd084, 0x00c0, 0x29b9, 0x007f, 0x2071, 0x0010,
- 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x080f, 0x70df,
- 0x000b, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0078,
- 0x29cf, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, 0x7592,
- 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0040, 0x29e6,
- 0xa784, 0x007d, 0x00c0, 0x441d, 0x1078, 0x29b2, 0xa49c, 0x000f,
- 0xa382, 0x0004, 0x0050, 0x29f1, 0xa3a6, 0x0007, 0x00c0, 0x29b2,
- 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x29f6, 0x3071, 0x3162,
- 0x318d, 0x33ff, 0x37e8, 0x3862, 0x3917, 0x39a8, 0x3a96, 0x3b85,
- 0x2a09, 0x2a06, 0x2e42, 0x2f65, 0x37b9, 0x2a06, 0x1078, 0x29b2,
- 0x007c, 0xa006, 0x0078, 0x2a13, 0x7808, 0xc08d, 0x780a, 0xa006,
- 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, 0x00c0, 0x2b79,
- 0x7064, 0xa084, 0x0007, 0x0079, 0x2a1d, 0x2a25, 0x2a98, 0x2aa1,
- 0x2aac, 0x2ab7, 0x2b5f, 0x2ac2, 0x2a98, 0x7830, 0xd0bc, 0x00c0,
- 0x2a08, 0x71d4, 0xd1bc, 0x00c0, 0x2a08, 0xd1b4, 0x00c0, 0x2a75,
- 0x70a4, 0xa086, 0x0001, 0x0040, 0x2a08, 0x70b4, 0xa06d, 0x6800,
- 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045,
- 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x2a4b,
- 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010,
- 0x0078, 0x2cd3, 0x7060, 0xa005, 0x00c0, 0x2a08, 0x0c7e, 0x0d7e,
- 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c,
- 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886,
- 0x0001, 0x0040, 0x2a6e, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d,
- 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2cd3, 0x1078, 0x43b0, 0x00c0,
- 0x2a08, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894,
- 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
- 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, 0x705a,
- 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c,
- 0x1078, 0x43b0, 0x00c0, 0x2aa0, 0x781b, 0x0047, 0x7003, 0x0004,
- 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2aab, 0x2011, 0x000c, 0x1078,
- 0x2ad2, 0x7003, 0x0004, 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2ab6,
- 0x2011, 0x0006, 0x1078, 0x2ad2, 0x7003, 0x0004, 0x007c, 0x1078,
- 0x43b0, 0x00c0, 0x2ac1, 0x2011, 0x000d, 0x1078, 0x2ad2, 0x7003,
- 0x0004, 0x007c, 0x1078, 0x43b0, 0x00c0, 0x2ad1, 0x2011, 0x0006,
- 0x1078, 0x2ad2, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, 0x7003,
- 0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010,
- 0xa286, 0x000c, 0x00c0, 0x2ae1, 0x7aaa, 0x2001, 0x0001, 0x0078,
- 0x2af6, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d,
- 0x0040, 0x2aef, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2af6, 0x78ab,
- 0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060,
- 0x78aa, 0x785b, 0x0004, 0x781b, 0x0116, 0x1078, 0x43d3, 0x7083,
- 0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2b12, 0xc0b4, 0x70d6, 0x0c7e,
- 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
- 0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, 0x2b21, 0x70d4,
- 0xd0b4, 0x0040, 0x2b22, 0x70b8, 0xac06, 0x00c0, 0x2b22, 0x1078,
- 0x2b01, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, 0x0040, 0x2b54,
- 0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068,
- 0x6800, 0xac06, 0x0040, 0x2b3b, 0x8211, 0x0040, 0x2b52, 0x1078,
- 0x2b56, 0x0078, 0x2b30, 0x0c7e, 0x2100, 0x2011, 0x0001, 0xa212,
- 0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a,
- 0x8211, 0x0040, 0x2b4f, 0x1078, 0x2b56, 0x0078, 0x2b42, 0x70a7,
- 0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8, 0x0005,
- 0x70ac, 0xad06, 0x00c0, 0x2b5e, 0x70a8, 0x2068, 0x007c, 0x1078,
- 0x43b0, 0x00c0, 0x2a08, 0x707c, 0x2068, 0x7774, 0x1078, 0x424e,
- 0x2c50, 0x1078, 0x4492, 0x789b, 0x0010, 0x6814, 0xa084, 0x001f,
- 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0078,
- 0x2cd9, 0x1078, 0x43b0, 0x00c0, 0x2a08, 0x789b, 0x0010, 0x7060,
- 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2b93, 0xc0b4, 0x70d6,
- 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
- 0x8001, 0x601a, 0x0c7f, 0x1078, 0x424e, 0x2c50, 0x1078, 0x4492,
- 0x6824, 0xa005, 0x0040, 0x2ba4, 0xa082, 0x0006, 0x0048, 0x2ba2,
- 0x0078, 0x2ba4, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd,
- 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0078,
- 0x2cd9, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, 0x7154, 0x8108,
- 0xa12a, 0x0048, 0x2bbc, 0x71c0, 0x2164, 0x6504, 0x85ff, 0x00c0,
- 0x2bd3, 0x7156, 0x8421, 0x00c0, 0x2bb7, 0x70d4, 0xd08c, 0x0040,
- 0x2bcf, 0x70d0, 0xa005, 0x00c0, 0x2bcf, 0x70d3, 0x000a, 0x007c,
- 0x2200, 0x0078, 0x2bc1, 0x70d4, 0xc08c, 0x70d6, 0x70d3, 0x0000,
- 0x6034, 0xa005, 0x00c0, 0x2bd0, 0x6708, 0xa784, 0x073f, 0x0040,
- 0x2c02, 0xd7d4, 0x00c0, 0x2bd0, 0xa784, 0x0021, 0x00c0, 0x2bd0,
- 0xa784, 0x0002, 0x0040, 0x2bf3, 0xa784, 0x0004, 0x0040, 0x2bd0,
- 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2bd0, 0xa784,
- 0x0100, 0x0040, 0x2c02, 0x6018, 0xa005, 0x00c0, 0x2bd0, 0xa7bc,
- 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e,
- 0x6318, 0x0040, 0x2c13, 0x601c, 0xa302, 0x0048, 0x2c16, 0x0040,
- 0x2c16, 0x0078, 0x2bd0, 0x83ff, 0x00c0, 0x2bd0, 0x2d58, 0x2c50,
- 0x7156, 0xd7bc, 0x00c0, 0x2c1f, 0x7028, 0x6022, 0x603a, 0xc7bc,
- 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001,
- 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040, 0x2c33,
- 0xd684, 0x0040, 0x2c35, 0xa39c, 0xffbf, 0xd6a4, 0x0040, 0x2c3a,
- 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2c85, 0xc7a5, 0x670a,
- 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c59, 0x70d4,
- 0xd0b4, 0x00c0, 0x2c59, 0x7000, 0xa082, 0x0002, 0x00c8, 0x2c59,
- 0x7830, 0xd0bc, 0x00c0, 0x2c59, 0x789b, 0x0010, 0x7baa, 0x0078,
- 0x2cd1, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, 0x70ac,
- 0xa606, 0x00c0, 0x2c64, 0x76a8, 0x76b2, 0x2c3a, 0x8738, 0x2d3a,
- 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc,
- 0x0040, 0x2c7c, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4, 0xa084,
- 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040, 0x2c84,
- 0x8421, 0x2200, 0x00c0, 0x2bb6, 0x007c, 0xd1dc, 0x0040, 0x3e49,
- 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2c92, 0x8528, 0xd68c, 0x00c0,
- 0x2c92, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff,
- 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2cb1, 0x6014, 0xa706,
- 0x00c0, 0x2c9a, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2c95, 0x2a60,
- 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0, 0x2bb6,
- 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008,
- 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c59, 0x70d4,
- 0xd0b4, 0x00c0, 0x2c59, 0x7000, 0xa082, 0x0002, 0x00c8, 0x2c59,
- 0x7830, 0xd0bc, 0x00c0, 0x2c59, 0x789b, 0x0010, 0x7baa, 0x7daa,
- 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a, 0x0078,
- 0x2cda, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018, 0x0040,
- 0x2cf6, 0xa184, 0x0010, 0x0040, 0x2ce9, 0x1078, 0x405e, 0x00c0,
- 0x2d1b, 0xa184, 0x0008, 0x0040, 0x2cf6, 0x69a0, 0xa184, 0x0600,
- 0x00c0, 0x2cf6, 0x1078, 0x3f3e, 0x0078, 0x2d1b, 0x69a0, 0xa184,
- 0x1e00, 0x0040, 0x2d26, 0xa184, 0x0800, 0x0040, 0x2d0f, 0x0c7e,
- 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010,
- 0x6106, 0x0c7f, 0x1078, 0x405e, 0x00c0, 0x2d1b, 0x69a0, 0xa184,
- 0x0200, 0x0040, 0x2d17, 0x1078, 0x3fa1, 0x0078, 0x2d1b, 0xa184,
- 0x0400, 0x00c0, 0x2cf2, 0x69a0, 0xa184, 0x1000, 0x0040, 0x2d26,
- 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x27e6, 0x027f, 0xa68c,
- 0x00e0, 0xa684, 0x0060, 0x0040, 0x2d33, 0xa086, 0x0060, 0x00c0,
- 0x2d33, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060,
- 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040, 0x2d4e,
- 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2d4c, 0xa08a,
- 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, 0x3518,
- 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b,
- 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0,
- 0xa286, 0x0020, 0x00c0, 0x2d86, 0x70d4, 0xc0b5, 0x70d6, 0x2c00,
- 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286,
- 0x0002, 0x0040, 0x2dbc, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa498,
- 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2d7e, 0x73a8, 0x73b6, 0xa286,
- 0x0010, 0x0040, 0x2a08, 0x0d7f, 0x0c7f, 0x007c, 0x7000, 0xa005,
- 0x00c0, 0x2d64, 0xa286, 0x0002, 0x00c0, 0x2dd6, 0x1078, 0x43b0,
- 0x00c0, 0x2d64, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091, 0x8000,
- 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898,
- 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a, 0x127e,
- 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f, 0x0d7f,
- 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002, 0x2d00,
- 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040, 0x2dc8,
- 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090,
- 0x70a4, 0xa005, 0x00c0, 0x2dcd, 0x007c, 0x8421, 0x0040, 0x2dcc,
- 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2bb6, 0xa286, 0x0010,
- 0x00c0, 0x2e07, 0x1078, 0x43b0, 0x00c0, 0x2d64, 0x6814, 0xc0fc,
- 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6,
- 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x70a4,
- 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, 0x00c0,
- 0x2dfa, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003,
- 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0x6bb4,
- 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94,
- 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b, 0x2900,
- 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0040,
- 0x2e32, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0, 0x2e2c,
- 0x2009, 0x0000, 0x0078, 0x2e2e, 0x2009, 0x0001, 0xa284, 0x000f,
- 0x1079, 0x2e38, 0xad80, 0x0009, 0x7046, 0x2d00, 0x704e, 0x007c,
- 0x2e40, 0x493f, 0x493f, 0x492c, 0x493f, 0x2e40, 0x2e40, 0x2e40,
- 0x1078, 0x29b2, 0x7808, 0xa084, 0xfffd, 0x780a, 0x1078, 0x29a5,
- 0x0f7e, 0x2079, 0x4f00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2e6a,
- 0x7064, 0xa086, 0x0001, 0x00c0, 0x2e58, 0x7066, 0x0078, 0x2f41,
- 0x7064, 0xa086, 0x0005, 0x00c0, 0x2e68, 0x707c, 0x2068, 0x681b,
- 0x0004, 0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822,
- 0x7067, 0x0000, 0x70a7, 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078,
- 0x2b01, 0x157e, 0x2011, 0x0004, 0x7164, 0xa186, 0x0001, 0x0040,
- 0x2e8a, 0xa186, 0x0007, 0x00c0, 0x2e81, 0x701f, 0x0005, 0x0078,
- 0x2e8a, 0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6,
- 0x0078, 0x2e8c, 0x7067, 0x0000, 0x2001, 0x4f0a, 0x2004, 0xa084,
- 0x00ff, 0xa086, 0x0018, 0x0040, 0x2e9c, 0x7018, 0x7016, 0xa005,
- 0x00c0, 0x2e9c, 0x70a7, 0x0001, 0x067e, 0x1078, 0x45d6, 0x20a9,
- 0x0010, 0x2039, 0x0000, 0x1078, 0x4148, 0xa7b8, 0x0100, 0x00f0,
- 0x2ea3, 0x067f, 0x7000, 0x0079, 0x2ead, 0x2ee7, 0x2ec2, 0x2ec2,
- 0x2eb7, 0x2ee7, 0x2ee7, 0x2ee7, 0x2eb5, 0x1078, 0x29b2, 0x7060,
- 0xa005, 0x0040, 0x2ee7, 0xad06, 0x00c0, 0x2ec2, 0x6800, 0x7062,
- 0x0078, 0x2ed4, 0x6820, 0xd084, 0x00c0, 0x2ed0, 0x6f14, 0x1078,
- 0x424e, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3e19, 0x0078, 0x2ed4,
- 0x705c, 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818,
- 0xd0fc, 0x0040, 0x2edc, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000,
- 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x2073, 0xb284,
- 0x0400, 0x0040, 0x2eef, 0x2021, 0x96d0, 0x0078, 0x2ef1, 0x2021,
- 0x95c0, 0x1078, 0x2f46, 0xb284, 0x0400, 0x0040, 0x2efb, 0x2021,
- 0x4f98, 0x0078, 0x2efd, 0x2021, 0x4f58, 0x1078, 0x2f46, 0x20a9,
- 0x0101, 0xb284, 0x0400, 0x0040, 0x2f09, 0x2021, 0x95d0, 0x0078,
- 0x2f0b, 0x2021, 0x94c0, 0x1078, 0x2f46, 0x8420, 0x00f0, 0x2f0b,
- 0xb284, 0x0300, 0x0040, 0x2f18, 0x2061, 0x54c0, 0x0078, 0x2f1a,
- 0x2061, 0x74c0, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff,
- 0x0040, 0x2f37, 0x6018, 0x017e, 0x007e, 0x2011, 0x4f02, 0x220c,
- 0xa102, 0x2012, 0x007f, 0x017f, 0xa102, 0x0050, 0x2f37, 0x6012,
- 0x00c0, 0x2f37, 0x2011, 0x4f04, 0x2204, 0xc0a5, 0x2012, 0x601b,
- 0x0000, 0xace0, 0x0010, 0x00f0, 0x2f1e, 0x8421, 0x00c0, 0x2f1c,
- 0x157f, 0x7003, 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404,
- 0xa005, 0x0040, 0x2f61, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817,
- 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820,
- 0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x2073, 0x007f, 0x0078,
- 0x2f48, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050,
- 0x2f6b, 0x1078, 0x29b2, 0x2300, 0x0079, 0x2f6e, 0x2f71, 0x2ffc,
- 0x3019, 0xa282, 0x0002, 0x0040, 0x2f77, 0x1078, 0x29b2, 0x7064,
- 0x7067, 0x0000, 0x7083, 0x0000, 0x0079, 0x2f7e, 0x2f86, 0x2f86,
- 0x2f88, 0x2fc8, 0x3e55, 0x2f86, 0x2fc8, 0x2f86, 0x1078, 0x29b2,
- 0x7774, 0x1078, 0x4148, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x424e,
- 0x6018, 0xa005, 0x0040, 0x2fbf, 0xd7fc, 0x00c0, 0x2f9b, 0x2021,
- 0x95c0, 0x0078, 0x2f9d, 0x2021, 0x96d0, 0x2009, 0x0005, 0x2011,
- 0x0010, 0x1078, 0x3034, 0x0040, 0x2fbf, 0x157e, 0x20a9, 0x0101,
- 0xd7fc, 0x00c0, 0x2faf, 0x2021, 0x94c0, 0x0078, 0x2fb1, 0x2021,
- 0x95d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x3034,
- 0x047f, 0x0040, 0x2fbe, 0x8420, 0x00f0, 0x2fb1, 0x157f, 0x8738,
- 0xa784, 0x001f, 0x00c0, 0x2f8e, 0x0078, 0x2a0c, 0x0078, 0x2a0c,
- 0x7774, 0x1078, 0x424e, 0x6018, 0xa005, 0x0040, 0x2ffa, 0xd7fc,
- 0x00c0, 0x2fd6, 0x2021, 0x95c0, 0x0078, 0x2fd8, 0x2021, 0x96d0,
- 0x2009, 0x0005, 0x2011, 0x0020, 0x1078, 0x3034, 0x0040, 0x2ffa,
- 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2fea, 0x2021, 0x94c0,
- 0x0078, 0x2fec, 0x2021, 0x95d0, 0x047e, 0x2009, 0x0005, 0x2011,
- 0x0020, 0x1078, 0x3034, 0x047f, 0x0040, 0x2ff9, 0x8420, 0x00f0,
- 0x2fec, 0x157f, 0x0078, 0x2a0c, 0x2200, 0x0079, 0x2fff, 0x3002,
- 0x3004, 0x3004, 0x1078, 0x29b2, 0x2009, 0x0012, 0x7064, 0xa086,
- 0x0002, 0x0040, 0x300d, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040,
- 0x3012, 0x691a, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078,
- 0x435d, 0x2200, 0x0079, 0x301c, 0x3021, 0x3004, 0x301f, 0x1078,
- 0x29b2, 0x1078, 0x45d6, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3dc7,
- 0x1078, 0x3e36, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3db8,
- 0x0040, 0x3dc7, 0x0078, 0x2a0c, 0x2404, 0xa005, 0x0040, 0x306d,
- 0x2068, 0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x3043, 0x2d20,
- 0x007f, 0x0078, 0x3035, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000,
- 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084,
- 0x00ff, 0xa205, 0x6822, 0x1078, 0x2073, 0x2021, 0x4f02, 0x241c,
- 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x00c0, 0x3064, 0x2021,
- 0x4f04, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a,
- 0x1078, 0x2b22, 0x1078, 0x3e36, 0x007c, 0xa085, 0x0001, 0x0078,
- 0x306c, 0x2300, 0x0079, 0x3074, 0x3079, 0x3077, 0x30f9, 0x1078,
- 0x29b2, 0x78e4, 0xa005, 0x00d0, 0x30af, 0x3208, 0x007e, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x308a, 0xa18c, 0x0300,
- 0x0078, 0x308c, 0xa18c, 0x0400, 0x0040, 0x3092, 0x0018, 0x2a08,
- 0x0078, 0x3094, 0x0028, 0x2a08, 0x2008, 0xa084, 0x0030, 0x00c0,
- 0x309b, 0x0078, 0x37b9, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3099,
- 0x2100, 0xa084, 0x0007, 0x0079, 0x30a5, 0x30d9, 0x30e3, 0x30ce,
- 0x30ad, 0x43a5, 0x43a5, 0x30ad, 0x30ee, 0x1078, 0x29b2, 0x7000,
- 0xa086, 0x0004, 0x00c0, 0x30c9, 0x7064, 0xa086, 0x0002, 0x00c0,
- 0x30bf, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2f65, 0x7064,
- 0xa086, 0x0006, 0x0040, 0x30b9, 0x7064, 0xa086, 0x0004, 0x0040,
- 0x30b9, 0x79e4, 0x2001, 0x0003, 0x0078, 0x3443, 0x6818, 0xd0fc,
- 0x0040, 0x30d4, 0x681b, 0x001d, 0x1078, 0x4118, 0x781b, 0x0064,
- 0x007c, 0x6818, 0xd0fc, 0x0040, 0x30df, 0x681b, 0x001d, 0x1078,
- 0x4118, 0x0078, 0x4381, 0x6818, 0xd0fc, 0x0040, 0x30e9, 0x681b,
- 0x001d, 0x1078, 0x4118, 0x781b, 0x00f8, 0x007c, 0x6818, 0xd0fc,
- 0x0040, 0x30f4, 0x681b, 0x001d, 0x1078, 0x4118, 0x781b, 0x00c8,
- 0x007c, 0xa584, 0x000f, 0x00c0, 0x3118, 0x1078, 0x29a5, 0x7000,
- 0x0079, 0x3102, 0x2a0c, 0x310a, 0x310c, 0x3dc7, 0x3dc7, 0x3dc7,
- 0x310a, 0x310a, 0x1078, 0x29b2, 0x1078, 0x3e36, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x1078, 0x3db8, 0x0040, 0x3dc7, 0x0078, 0x2a0c,
- 0x78e4, 0xa005, 0x00d0, 0x30af, 0x3208, 0x007e, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3129, 0xa18c, 0x0300, 0x0078,
- 0x312b, 0xa18c, 0x0400, 0x0040, 0x3131, 0x0018, 0x30af, 0x0078,
- 0x3133, 0x0028, 0x30af, 0x2008, 0xa084, 0x0030, 0x00c0, 0x313b,
- 0x781b, 0x005b, 0x007c, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3138,
- 0x2100, 0xa184, 0x0007, 0x0079, 0x3145, 0x3154, 0x3158, 0x314f,
- 0x314d, 0x43a5, 0x43a5, 0x314d, 0x439f, 0x1078, 0x29b2, 0x1078,
- 0x4120, 0x781b, 0x0064, 0x007c, 0x1078, 0x4120, 0x0078, 0x4381,
- 0x1078, 0x4120, 0x781b, 0x00f8, 0x007c, 0x1078, 0x4120, 0x781b,
- 0x00c8, 0x007c, 0x2300, 0x0079, 0x3165, 0x316a, 0x3168, 0x316c,
- 0x1078, 0x29b2, 0x0078, 0x39a8, 0x681b, 0x0016, 0x78a3, 0x0000,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x39a8, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x39a8, 0xa184, 0x0100, 0x0040, 0x3170, 0xa184, 0x0007,
- 0x0079, 0x3182, 0x318a, 0x3158, 0x30ce, 0x435d, 0x43a5, 0x43a5,
- 0x435d, 0x439f, 0x1078, 0x4369, 0x007c, 0xa282, 0x0005, 0x0050,
- 0x3193, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3196, 0x3199, 0x33c9,
- 0x33d4, 0x2200, 0x0079, 0x319c, 0x31b6, 0x31a3, 0x31b6, 0x31a1,
- 0x33ac, 0x1078, 0x29b2, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
- 0xa082, 0x0020, 0x0048, 0x4107, 0xa08a, 0x0004, 0x00c8, 0x4107,
- 0x0079, 0x31b2, 0x4107, 0x4107, 0x4107, 0x40b1, 0x789b, 0x0018,
- 0x79a8, 0xa184, 0x0080, 0x0040, 0x31c7, 0x0078, 0x4107, 0x7000,
- 0xa005, 0x00c0, 0x31bd, 0x2011, 0x0004, 0x0078, 0x3b93, 0xa184,
- 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x4107, 0x0079, 0x31cf, 0x31e1,
- 0x31df, 0x31f6, 0x31fa, 0x32cd, 0x4107, 0x4107, 0x32cf, 0x4107,
- 0x4107, 0x33a8, 0x33a8, 0x4107, 0x4107, 0x4107, 0x33aa, 0x1078,
- 0x29b2, 0xd6e4, 0x0040, 0x31ec, 0x2001, 0x0300, 0x8000, 0x8000,
- 0x783a, 0x781b, 0x00c3, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x31f4,
- 0x681b, 0x001d, 0x0078, 0x31e4, 0x0078, 0x435d, 0x681b, 0x001d,
- 0x0078, 0x4111, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x325f,
- 0x6820, 0xd084, 0x00c0, 0x3265, 0x6818, 0xa086, 0x0008, 0x00c0,
- 0x320b, 0x681b, 0x0000, 0xd6d4, 0x0040, 0x32ca, 0xd6bc, 0x0040,
- 0x324b, 0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d,
- 0x0050, 0x324b, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c,
- 0x718a, 0x789b, 0x0061, 0x78aa, 0x157e, 0x137e, 0x147e, 0x017e,
- 0x3208, 0xa18c, 0x0300, 0x0040, 0x323d, 0x007e, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3239, 0x20a1, 0x012b, 0x0078,
- 0x323f, 0x20a1, 0x022b, 0x0078, 0x323f, 0x20a1, 0x012b, 0x017f,
- 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6,
- 0x147f, 0x137f, 0x157f, 0x6038, 0xa005, 0x00c0, 0x325a, 0x681c,
- 0xa084, 0x000e, 0x0040, 0x4111, 0x1078, 0x4127, 0x782b, 0x3008,
- 0x0078, 0x325c, 0x8001, 0x603a, 0x781b, 0x0067, 0x007c, 0xd6e4,
- 0x0040, 0x3265, 0x781b, 0x0079, 0x007c, 0xa684, 0x0060, 0x0040,
- 0x32c7, 0xd6dc, 0x0040, 0x32c7, 0xd6fc, 0x00c0, 0x3271, 0x0078,
- 0x3288, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x801b,
- 0x00c8, 0x327b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
- 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
- 0xd6f4, 0x0040, 0x328e, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086,
- 0x0003, 0x00c0, 0x329c, 0x007e, 0x1078, 0x45d6, 0x1078, 0x493f,
- 0x007f, 0x781b, 0x0076, 0x007c, 0xa006, 0x1078, 0x4a44, 0x6ab0,
- 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x32ab, 0x2200,
- 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6,
- 0x7bde, 0x2300, 0xa405, 0x00c0, 0x32bb, 0xc6f5, 0x7e5a, 0x6eb6,
- 0x781b, 0x0076, 0x007c, 0x781b, 0x0076, 0x2200, 0xa115, 0x00c0,
- 0x32c4, 0x1078, 0x493f, 0x007c, 0x1078, 0x4977, 0x007c, 0x781b,
- 0x0079, 0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x29b2, 0x0078,
- 0x331b, 0x6920, 0xd1c4, 0x0040, 0x32e4, 0xc1c4, 0x6922, 0x0c7e,
- 0x7058, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x0c7f, 0x0078, 0x330f, 0xd1cc, 0x0040, 0x330f, 0xc1cc,
- 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004,
- 0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x330f,
- 0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x330f, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
- 0x330c, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58,
- 0xd6d4, 0x00c0, 0x3316, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
- 0x007c, 0x0078, 0x410c, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007,
- 0x00c0, 0x3329, 0x6820, 0xa084, 0x0100, 0x0040, 0x3319, 0x2009,
- 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001,
- 0x00c0, 0x3345, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040,
- 0x333d, 0x0048, 0x333d, 0x0078, 0x333f, 0x0078, 0x32d1, 0x24a8,
- 0x7aa8, 0x00f0, 0x333f, 0x0078, 0x332b, 0xa284, 0x00f0, 0xa086,
- 0x0020, 0x00c0, 0x3399, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040,
- 0x3355, 0x0048, 0x3355, 0x0078, 0x3396, 0xa286, 0x0023, 0x0040,
- 0x3319, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1,
- 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058,
- 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x3376,
- 0x1078, 0x424a, 0x1078, 0x405e, 0x0078, 0x3384, 0x0c7e, 0x7058,
- 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x330f,
- 0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x330f, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3393,
- 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7aa8, 0x0078,
- 0x332b, 0x8318, 0x2300, 0xa102, 0x0040, 0x33a2, 0x0048, 0x33a2,
- 0x0078, 0x332b, 0xa284, 0x0080, 0x00c0, 0x4111, 0x0078, 0x410c,
- 0x0078, 0x4111, 0x0078, 0x4107, 0x7058, 0xa04d, 0x789b, 0x0018,
- 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, 0x33b9, 0x1078,
- 0x29b2, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a,
- 0x0004, 0x00c8, 0x4107, 0x0079, 0x33c5, 0x4107, 0x3e8f, 0x4107,
- 0x4006, 0xa282, 0x0000, 0x00c0, 0x33cf, 0x1078, 0x29b2, 0x1078,
- 0x4118, 0x781b, 0x0078, 0x007c, 0xa282, 0x0003, 0x00c0, 0x33da,
- 0x1078, 0x29b2, 0xd4fc, 0x00c0, 0x33fa, 0x7064, 0xa005, 0x0040,
- 0x33e3, 0x1078, 0x29b2, 0x6f14, 0x7776, 0xa7bc, 0x8f00, 0x1078,
- 0x424e, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f,
- 0x00c0, 0x33e7, 0x1078, 0x411c, 0x7067, 0x0002, 0x701f, 0x0009,
- 0x0078, 0x33fc, 0x1078, 0x412b, 0x781b, 0x0078, 0x007c, 0xa282,
- 0x0004, 0x0050, 0x3405, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3408,
- 0x340b, 0x35cb, 0x360e, 0xa286, 0x0003, 0x0040, 0x3443, 0x7200,
- 0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, 0x343b, 0xd1b4,
- 0x0040, 0x343b, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x343b, 0xa282,
- 0x0002, 0x00c8, 0x343b, 0x0d7e, 0x783b, 0x8300, 0x781b, 0x004c,
- 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898,
- 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x2001,
- 0x0000, 0x0078, 0x3447, 0x783b, 0x1300, 0x781b, 0x004a, 0x2001,
- 0x0000, 0x0078, 0x3447, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a,
- 0x68a0, 0xd0ec, 0x0040, 0x344f, 0x6008, 0xc08d, 0x600a, 0xa284,
- 0x000f, 0x0079, 0x3453, 0x35ab, 0x3460, 0x345d, 0x3711, 0x379d,
- 0x2a0c, 0x345b, 0x345b, 0x1078, 0x29b2, 0x6008, 0xc0d4, 0x600a,
- 0xd6e4, 0x0040, 0x3468, 0x7048, 0xa086, 0x0014, 0x00c0, 0x3488,
- 0x1078, 0x45d6, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0040, 0x3471,
- 0x7048, 0xa086, 0x0014, 0x0040, 0x3482, 0x6818, 0xa086, 0x0008,
- 0x00c0, 0x3563, 0x7858, 0xd09c, 0x0040, 0x3563, 0x6820, 0xd0ac,
- 0x0040, 0x3563, 0x681b, 0x0014, 0x2009, 0x0002, 0x0078, 0x34c7,
- 0x7868, 0xa08c, 0x00ff, 0x0040, 0x34c7, 0xa186, 0x0008, 0x00c0,
- 0x349e, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3db8, 0x0040, 0x34c7,
- 0x1078, 0x3e36, 0x1078, 0x45d6, 0x0078, 0x34af, 0xa186, 0x0028,
- 0x00c0, 0x34c7, 0x6018, 0xa005, 0x0040, 0x3491, 0x8001, 0x0040,
- 0x3491, 0x8001, 0x0040, 0x3491, 0x601e, 0x0078, 0x3491, 0x6820,
- 0xd084, 0x0040, 0x2a0c, 0xc084, 0x6822, 0x1078, 0x2b13, 0x705c,
- 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005,
- 0x2d00, 0x00c0, 0x34c4, 0x6002, 0x6006, 0x0078, 0x2a0c, 0x017e,
- 0x81ff, 0x00c0, 0x3511, 0x7000, 0xa086, 0x0030, 0x0040, 0x3511,
- 0x71d4, 0xd1bc, 0x00c0, 0x3511, 0xd1b4, 0x00c0, 0x34f8, 0x7060,
- 0xa005, 0x00c0, 0x3511, 0x70a4, 0xa086, 0x0001, 0x0040, 0x3511,
- 0x7003, 0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e,
- 0x1078, 0x2a35, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f,
- 0x71d4, 0xd1b4, 0x00c0, 0x3511, 0x7003, 0x0040, 0x0078, 0x3511,
- 0x1078, 0x43b0, 0x00c0, 0x3511, 0x781b, 0x005b, 0x0d7e, 0x70bc,
- 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
- 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a,
- 0x0d7f, 0x1078, 0x3648, 0x017f, 0x81ff, 0x0040, 0x3563, 0xa684,
- 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0,
- 0x3564, 0x6818, 0xa086, 0x0014, 0x00c0, 0x352d, 0x2008, 0xd6e4,
- 0x0040, 0x352d, 0x7868, 0xa08c, 0x00ff, 0x1078, 0x2b01, 0x1078,
- 0x2b22, 0x6820, 0xd0dc, 0x00c0, 0x3564, 0x8717, 0xa294, 0x000f,
- 0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x3543, 0xa290,
- 0x53c0, 0x0078, 0x3545, 0xa290, 0x5440, 0xa290, 0x0000, 0x221c,
- 0xd3c4, 0x00c0, 0x354d, 0x0078, 0x3553, 0x8210, 0x2204, 0xa085,
- 0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x355e, 0x68a0, 0xd0c4,
- 0x00c0, 0x355e, 0x1078, 0x36c2, 0x0078, 0x2a0c, 0x6008, 0xc08d,
- 0x600a, 0x0078, 0x3564, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040,
- 0x356b, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff,
- 0x0040, 0x3580, 0x2009, 0x4f02, 0x2104, 0x8001, 0x200a, 0x8421,
- 0x6412, 0x00c0, 0x3580, 0x2021, 0x4f04, 0x2404, 0xc0a5, 0x2022,
- 0x6018, 0xa005, 0x0040, 0x3588, 0x8001, 0x601a, 0x00c0, 0x358b,
- 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x3597, 0x6800,
- 0xa005, 0x00c0, 0x3594, 0x6002, 0x6006, 0x0078, 0x359b, 0x705c,
- 0x2060, 0x6800, 0x6002, 0x2061, 0x4f00, 0x6887, 0x0103, 0x2d08,
- 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x35aa, 0x2d02,
- 0x0078, 0x35ab, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x35bb,
- 0xa286, 0x0040, 0x00c0, 0x2a0c, 0x7003, 0x0002, 0x704c, 0x2068,
- 0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc,
- 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80,
- 0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x35d1, 0x1078,
- 0x29b2, 0x2200, 0x0079, 0x35d4, 0x35d8, 0x35e9, 0x35f6, 0x35e9,
- 0xa586, 0x1300, 0x0040, 0x35e9, 0xa586, 0x8300, 0x00c0, 0x35cf,
- 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
- 0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x35f3, 0x1078, 0x4118,
- 0x781b, 0x0078, 0x007c, 0x781b, 0x0079, 0x007c, 0x7890, 0x8007,
- 0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
- 0x00ff, 0xa186, 0x0003, 0x0040, 0x360b, 0xa186, 0x0000, 0x0040,
- 0x360b, 0x0078, 0x4107, 0x781b, 0x0079, 0x007c, 0x6820, 0xc095,
- 0x6822, 0x82ff, 0x00c0, 0x3618, 0x1078, 0x4118, 0x0078, 0x361f,
- 0x8211, 0x0040, 0x361d, 0x1078, 0x29b2, 0x1078, 0x412b, 0x781b,
- 0x0078, 0x007c, 0x1078, 0x43d3, 0x7830, 0xa084, 0x00c0, 0x00c0,
- 0x3645, 0x017e, 0x3208, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec,
- 0x007f, 0x0040, 0x3637, 0xa18c, 0x0300, 0x0078, 0x3639, 0xa18c,
- 0x0400, 0x017f, 0x0040, 0x3640, 0x0018, 0x3645, 0x0078, 0x3642,
- 0x0028, 0x3645, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
- 0xa684, 0x0060, 0x00c0, 0x3652, 0x682f, 0x0000, 0x6833, 0x0000,
- 0x0078, 0x36c1, 0xd6dc, 0x00c0, 0x366a, 0x68b4, 0xd0dc, 0x00c0,
- 0x366a, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0,
- 0x3667, 0x2200, 0xa105, 0x0040, 0x45d6, 0x704b, 0x0015, 0x0078,
- 0x45d6, 0x007c, 0xd6ac, 0x0040, 0x3690, 0xd6f4, 0x0040, 0x3676,
- 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x45d6, 0x68b4, 0xa084,
- 0x4000, 0xa635, 0xd6f4, 0x00c0, 0x3670, 0x7048, 0xa005, 0x00c0,
- 0x3683, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x368c, 0x68b4, 0xd0dc,
- 0x0040, 0x368c, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x45d6,
- 0xd6f4, 0x0040, 0x3699, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
- 0x45d6, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x3693,
- 0x7048, 0xa005, 0x00c0, 0x36a6, 0x704b, 0x0015, 0x2408, 0x2510,
- 0x2700, 0x80fb, 0x00c8, 0x36ad, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x36ba,
- 0x0078, 0x45d6, 0x7000, 0xa086, 0x0006, 0x0040, 0x36c1, 0x0078,
- 0x45d6, 0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x36c9,
- 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000,
- 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003,
- 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020,
- 0x7000, 0x0079, 0x36e3, 0x2a0c, 0x36f5, 0x36ed, 0x36eb, 0x36eb,
- 0x36eb, 0x36eb, 0x36eb, 0x1078, 0x29b2, 0x6820, 0xd084, 0x00c0,
- 0x36f5, 0x1078, 0x3e19, 0x0078, 0x36fb, 0x705c, 0x2c50, 0x2060,
- 0x6800, 0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3704,
- 0x2021, 0x4f58, 0x0078, 0x3706, 0x2021, 0x4f98, 0x2404, 0xa005,
- 0x0040, 0x370d, 0x2020, 0x0078, 0x3706, 0x2d22, 0x206b, 0x0000,
- 0x007c, 0x1078, 0x3e20, 0x1078, 0x3e36, 0x6008, 0xc0cc, 0x600a,
- 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944,
- 0x6916, 0x3208, 0xa18c, 0x0300, 0x0040, 0x372a, 0x2009, 0x0000,
- 0x0078, 0x372c, 0x2009, 0x0001, 0x1078, 0x4a81, 0xd6dc, 0x0040,
- 0x3734, 0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0040, 0x3743,
- 0x7868, 0xa08c, 0x00ff, 0x0040, 0x3741, 0x681b, 0x001e, 0x0078,
- 0x3743, 0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x374b, 0x2021,
- 0x4f98, 0x0078, 0x374d, 0x2021, 0x4f58, 0x6800, 0x2022, 0x6a3c,
- 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0040,
- 0x378d, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x0d7e,
- 0x0f7e, 0x157e, 0x147e, 0x2079, 0x4f00, 0x1078, 0x1e46, 0x147f,
- 0x157f, 0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, 0x027e, 0x2204,
- 0xa06d, 0x0040, 0x377d, 0x6814, 0xa706, 0x0040, 0x377a, 0x6800,
- 0x0078, 0x3770, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210, 0x8109,
- 0x00c0, 0x376e, 0x0d7f, 0x7067, 0x0003, 0x707f, 0x0000, 0x7776,
- 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, 0xa086, 0x0002,
- 0x00c0, 0x3799, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec,
- 0x681e, 0x1078, 0x2073, 0x0078, 0x2a0c, 0x7cd8, 0x7ddc, 0x7fd0,
- 0x1078, 0x3648, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078,
- 0x43d7, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x37b2,
- 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078,
- 0x2a0c, 0x7000, 0xa005, 0x00c0, 0x37bf, 0x0078, 0x2a0c, 0xa006,
- 0x1078, 0x45d6, 0x6920, 0xd1ac, 0x00c0, 0x37c8, 0x681b, 0x0014,
- 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff,
- 0x6822, 0x7000, 0x0079, 0x37d4, 0x2a0c, 0x37de, 0x37de, 0x37e1,
- 0x37e1, 0x37e1, 0x37dc, 0x37dc, 0x1078, 0x29b2, 0x6818, 0x0078,
- 0x3443, 0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0078, 0x3dde,
- 0x2300, 0x0079, 0x37eb, 0x37ee, 0x37f0, 0x3860, 0x1078, 0x29b2,
- 0xd6fc, 0x00c0, 0x3847, 0x7000, 0xa00d, 0x0079, 0x37f7, 0x2a0c,
- 0x3801, 0x3801, 0x3831, 0x3801, 0x3844, 0x37ff, 0x37ff, 0x1078,
- 0x29b2, 0xa684, 0x0060, 0x0040, 0x3831, 0xa086, 0x0060, 0x00c0,
- 0x382e, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac,
- 0x681e, 0xa186, 0x0002, 0x0040, 0x3820, 0x1078, 0x45d6, 0x69ac,
- 0x68b0, 0xa115, 0x0040, 0x3820, 0x1078, 0x4977, 0x0078, 0x3822,
- 0x1078, 0x493f, 0x781b, 0x0079, 0x71d4, 0xd1b4, 0x00c0, 0x2a08,
- 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c, 0xd6ec, 0x0040,
- 0x380b, 0x6818, 0xd0fc, 0x0040, 0x3844, 0xd6f4, 0x00c0, 0x383e,
- 0x681b, 0x0015, 0x781b, 0x0079, 0x0078, 0x2a08, 0x681b, 0x0007,
- 0x682f, 0x0000, 0x6833, 0x0000, 0x1078, 0x4369, 0x007c, 0xc6fc,
- 0x7e5a, 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x3850, 0x8000,
- 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
- 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0079, 0x007c,
- 0x1078, 0x29b2, 0x2300, 0x0079, 0x3865, 0x386a, 0x388f, 0x38ef,
- 0x1078, 0x29b2, 0x7000, 0x0079, 0x386d, 0x3875, 0x3877, 0x3880,
- 0x3875, 0x3875, 0x3875, 0x3875, 0x3875, 0x1078, 0x29b2, 0x69ac,
- 0x68b0, 0xa115, 0x0040, 0x3880, 0x1078, 0x4977, 0x0078, 0x3882,
- 0x1078, 0x493f, 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0,
- 0x2a08, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c, 0xd6fc,
- 0x00c0, 0x38df, 0x7000, 0xa00d, 0x0079, 0x3896, 0x2a0c, 0x38a6,
- 0x38a0, 0x38d6, 0x38a6, 0x38dc, 0x389e, 0x389e, 0x1078, 0x29b2,
- 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060,
- 0x0040, 0x38d6, 0xa086, 0x0060, 0x00c0, 0x38d3, 0xa6b4, 0xbfbf,
- 0xc6ed, 0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x38c2, 0x1078,
- 0x45d6, 0x69ac, 0x68b0, 0xa115, 0x0040, 0x38c2, 0x1078, 0x4977,
- 0x0078, 0x38c4, 0x1078, 0x493f, 0x781b, 0x0079, 0x681c, 0xc0b4,
- 0x681e, 0x71d4, 0xd1b4, 0x00c0, 0x2a08, 0x70a4, 0xa086, 0x0001,
- 0x00c0, 0x2a52, 0x007c, 0xd6ec, 0x0040, 0x38b0, 0x6818, 0xd0fc,
- 0x0040, 0x38dc, 0x681b, 0x0007, 0x781b, 0x00f9, 0x007c, 0xc6fc,
- 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
- 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0079, 0x007c, 0xd6dc,
- 0x0040, 0x38f8, 0x782b, 0x3009, 0x781b, 0x0079, 0x0078, 0x2a08,
- 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x390b,
- 0xa484, 0x0200, 0x0040, 0x3905, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b,
- 0x0079, 0x0078, 0x2a08, 0x6820, 0xc095, 0x6822, 0x1078, 0x42e2,
- 0xc6dd, 0x1078, 0x4118, 0x781b, 0x0078, 0x0078, 0x2a08, 0x2300,
- 0x0079, 0x391a, 0x391d, 0x391f, 0x3921, 0x1078, 0x29b2, 0x0078,
- 0x4111, 0xd6d4, 0x00c0, 0x395c, 0x79e4, 0xd1ac, 0x0040, 0x392f,
- 0x78ec, 0xa084, 0x0003, 0x0040, 0x392f, 0x782b, 0x3009, 0x789b,
- 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xd1ac,
- 0x0040, 0x393f, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x3958, 0x2001,
- 0x4f04, 0x2004, 0xd0e4, 0x00c0, 0x3954, 0x6820, 0xd0c4, 0x0040,
- 0x3954, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008,
- 0xa084, 0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x3443,
- 0xa184, 0x0007, 0x0079, 0x3992, 0x7a90, 0xa294, 0x0007, 0x789b,
- 0x0060, 0x79a8, 0x81ff, 0x0040, 0x3990, 0x789b, 0x0010, 0x7ba8,
- 0xa384, 0x0001, 0x00c0, 0x3983, 0x7ba8, 0x7ba8, 0xa386, 0x0001,
- 0x00c0, 0x3976, 0x2009, 0xfff7, 0x0078, 0x397c, 0xa386, 0x0003,
- 0x00c0, 0x3983, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004,
- 0xa104, 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684,
- 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922,
- 0x0078, 0x435d, 0x30d9, 0x30e3, 0x399c, 0x39a2, 0x399a, 0x399a,
- 0x435d, 0x435d, 0x1078, 0x29b2, 0x6920, 0xa18c, 0xfcff, 0x6922,
- 0x0078, 0x4363, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x435d,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x39b2, 0x78ec, 0xa084, 0x0003,
- 0x00c0, 0x39e6, 0x7000, 0xa086, 0x0004, 0x00c0, 0x39cc, 0x7064,
- 0xa086, 0x0002, 0x00c0, 0x39c2, 0x2011, 0x0002, 0x2019, 0x0000,
- 0x0078, 0x2f65, 0x7064, 0xa086, 0x0006, 0x0040, 0x39bc, 0x7064,
- 0xa086, 0x0004, 0x0040, 0x39bc, 0x7000, 0xa086, 0x0000, 0x0040,
- 0x2a08, 0x6920, 0xa184, 0x0420, 0x0040, 0x39db, 0xc1d4, 0x6922,
- 0x6818, 0x0078, 0x3443, 0x6818, 0xa08e, 0x0002, 0x0040, 0x39e4,
- 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078, 0x3443, 0xa184, 0x0007,
- 0x0079, 0x39ea, 0x435d, 0x435d, 0x39f2, 0x435d, 0x43a5, 0x43a5,
- 0x435d, 0x435d, 0xd6bc, 0x0040, 0x3a34, 0x7184, 0x81ff, 0x0040,
- 0x3a34, 0xa182, 0x000d, 0x00d0, 0x3a01, 0x7087, 0x0000, 0x0078,
- 0x3a06, 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061,
- 0x79aa, 0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a,
- 0xa080, 0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x3a28,
- 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x3a24,
- 0x20a1, 0x012b, 0x0078, 0x3a2a, 0x20a1, 0x022b, 0x0078, 0x3a2a,
- 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f,
- 0x137f, 0x157f, 0x0078, 0x4363, 0xd6d4, 0x00c0, 0x3a88, 0x6820,
- 0xd084, 0x0040, 0x4363, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040,
- 0x3a46, 0xa086, 0x0060, 0x00c0, 0x3a46, 0xc1f5, 0xc194, 0x795a,
- 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818,
- 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3e4f, 0xa18c,
- 0x00f8, 0x00c0, 0x3e4f, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208,
- 0xa18c, 0x0300, 0x0040, 0x3a74, 0x007e, 0x2001, 0x4f04, 0x2004,
- 0xd0ec, 0x007f, 0x0040, 0x3a70, 0x20a1, 0x012b, 0x0078, 0x3a76,
- 0x20a1, 0x022b, 0x0078, 0x3a76, 0x20a1, 0x012b, 0x017f, 0x789b,
- 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f,
- 0x137f, 0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x4363,
- 0x6818, 0xd0fc, 0x0040, 0x3a8e, 0x681b, 0x0008, 0x6820, 0xc0ad,
- 0x6822, 0x1078, 0x4120, 0x781b, 0x00ea, 0x007c, 0x2300, 0x0079,
- 0x3a99, 0x3a9e, 0x3b76, 0x3a9c, 0x1078, 0x29b2, 0x7cd8, 0x7ddc,
- 0x7fd0, 0x82ff, 0x00c0, 0x3ac7, 0x7200, 0xa286, 0x0003, 0x0040,
- 0x3410, 0x71d4, 0xd1bc, 0x00c0, 0x3aca, 0xd1b4, 0x0040, 0x3aca,
- 0x0d7e, 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4,
- 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
- 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x3ace, 0x7200,
- 0x0078, 0x3ace, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f,
- 0x0079, 0x3ad2, 0x3b61, 0x3b10, 0x3adc, 0x343f, 0x3ada, 0x3b61,
- 0x3ada, 0x3ada, 0x1078, 0x29b2, 0x681c, 0xd0ec, 0x0040, 0x3ae3,
- 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006,
- 0xa005, 0x00c0, 0x3aec, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c,
- 0xa084, 0x000e, 0x00c0, 0x3b00, 0xb284, 0x0300, 0x0040, 0x3afc,
- 0x2009, 0x95c0, 0x0078, 0x3b05, 0x2009, 0x96d0, 0x0078, 0x3b05,
- 0x7030, 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a,
- 0x715e, 0xd6dc, 0x00c0, 0x3b10, 0xc6fc, 0x6eb6, 0x0078, 0x3b61,
- 0x6eb6, 0xa684, 0x0060, 0x00c0, 0x3b1a, 0xa684, 0x7fff, 0x68b6,
- 0x0078, 0x3b61, 0xd6dc, 0x00c0, 0x3b28, 0xa684, 0x7fff, 0x68b6,
- 0x6894, 0x68a6, 0x6898, 0x68aa, 0x1078, 0x45d6, 0x0078, 0x3b61,
- 0xd6ac, 0x0040, 0x3b34, 0xa006, 0x1078, 0x45d6, 0x2408, 0x2510,
- 0x69aa, 0x6aa6, 0x0078, 0x3b44, 0x2408, 0x2510, 0x2700, 0x801b,
- 0x00c8, 0x3b3b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
- 0x69aa, 0x6aa6, 0x1078, 0x45d6, 0xd6fc, 0x0040, 0x3b61, 0xa684,
- 0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3b59, 0x2700,
- 0x801b, 0x00c8, 0x3b54, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
- 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303,
- 0x68ae, 0x7000, 0xa086, 0x0030, 0x00c0, 0x2a0c, 0x7003, 0x0002,
- 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a,
- 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800,
- 0x00c0, 0x3b83, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x0078, 0x4111, 0x7047, 0x0000, 0xa282,
- 0x0006, 0x0050, 0x3b8d, 0x1078, 0x29b2, 0x2300, 0x0079, 0x3b90,
- 0x3b93, 0x3ba5, 0x3bb1, 0x2200, 0x0079, 0x3b96, 0x3b9c, 0x4111,
- 0x3b9e, 0x3b9c, 0x3beb, 0x3c40, 0x1078, 0x29b2, 0x7a80, 0xa294,
- 0x0f00, 0x1078, 0x3cca, 0x0078, 0x4107, 0x1078, 0x3bc2, 0x0079,
- 0x3ba9, 0x4111, 0x3baf, 0x3baf, 0x3beb, 0x3baf, 0x4111, 0x1078,
- 0x29b2, 0x1078, 0x3bc2, 0x0079, 0x3bb5, 0x3bbd, 0x3bbb, 0x3bbb,
- 0x3bbd, 0x3bbb, 0x3bbd, 0x1078, 0x29b2, 0x1078, 0x412b, 0x781b,
- 0x0078, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bd3, 0x1078,
- 0x3e36, 0x0078, 0x3bcd, 0x1078, 0x45d6, 0x6008, 0xa084, 0xfbef,
- 0x600a, 0x0078, 0x3bd8, 0x7000, 0xa086, 0x0003, 0x0040, 0x3bcb,
- 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3be2, 0x2001, 0x96e0,
- 0x0078, 0x3be4, 0x2001, 0x9712, 0x2068, 0x704e, 0xad80, 0x0009,
- 0x7046, 0x2200, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bfd,
- 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078,
- 0x3c02, 0x1078, 0x45d6, 0x0078, 0x3c02, 0x7000, 0xa086, 0x0003,
- 0x0040, 0x3bf9, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b,
- 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x95c0, 0xb284,
- 0x0300, 0x00c0, 0x3c16, 0xc2fd, 0x2069, 0x96d0, 0x2d04, 0x2d08,
- 0x715e, 0xa06d, 0x0040, 0x3c23, 0x6814, 0xa206, 0x0040, 0x3c25,
- 0x6800, 0x0078, 0x3c17, 0x1078, 0x3cca, 0x6eb4, 0x7e5a, 0x6920,
- 0xa184, 0x0c00, 0x0040, 0x3cf4, 0x7064, 0xa086, 0x0006, 0x00c0,
- 0x3c37, 0x7074, 0xa206, 0x00c0, 0x3c37, 0x7066, 0x707e, 0x681b,
- 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4120, 0x0078, 0x3cf4,
- 0x7200, 0xa286, 0x0002, 0x00c0, 0x3c52, 0x70d4, 0xc0b5, 0x70d6,
- 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3c56, 0x1078, 0x45d6,
- 0x0078, 0x3c56, 0xa286, 0x0003, 0x0040, 0x3c4e, 0x7003, 0x0001,
- 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f,
- 0xa215, 0xb284, 0x0300, 0x00c0, 0x3c66, 0xc2fd, 0x79a8, 0x79a8,
- 0xa18c, 0x00ff, 0x2118, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e,
- 0xa06d, 0x0040, 0x3c7a, 0x6814, 0xa206, 0x0040, 0x3ca3, 0x6800,
- 0x0078, 0x3c6e, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c84,
- 0x2001, 0x96e0, 0x0078, 0x3c86, 0x2001, 0x9712, 0x2068, 0x704e,
- 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c8b,
- 0x157f, 0xb284, 0x0300, 0x0040, 0x3c98, 0xc2fc, 0x0078, 0x3c99,
- 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823,
- 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0040,
- 0x3cf4, 0xd0dc, 0x0040, 0x3cbf, 0x7064, 0xa086, 0x0004, 0x00c0,
- 0x3cbb, 0x7074, 0xa206, 0x00c0, 0x3cbb, 0x7078, 0xa306, 0x00c0,
- 0x3cbb, 0x7066, 0x707e, 0x1078, 0x4127, 0x0078, 0x3cf4, 0x681b,
- 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x4120, 0x707f, 0x0000,
- 0x0078, 0x3cf4, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3cd4,
- 0x2001, 0x96e0, 0x0078, 0x3cd6, 0x2001, 0x9712, 0x2068, 0x704e,
- 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3cdb,
- 0x157f, 0xb284, 0x0300, 0x0040, 0x3ce8, 0xc2fc, 0x0078, 0x3ce9,
- 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823,
- 0x0800, 0x6827, 0x0003, 0x007c, 0xc6ec, 0xa6ac, 0x0060, 0x0040,
- 0x3d46, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3d21,
- 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3d4b,
- 0xd6f4, 0x00c0, 0x3d0c, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009,
- 0x0079, 0xd69c, 0x0040, 0x3d19, 0x2009, 0x0078, 0x2019, 0x0000,
- 0x2320, 0x791a, 0xd6ec, 0x0040, 0x3d56, 0x1078, 0x493f, 0x0078,
- 0x3d56, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040,
- 0x3d4d, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0,
- 0x3d32, 0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0079, 0xd69c, 0x0040,
- 0x3d3e, 0x2011, 0x0078, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec,
- 0x0040, 0x3d56, 0x1078, 0x4977, 0x0078, 0x3d56, 0x2019, 0x0000,
- 0x2320, 0x0078, 0x3d4d, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079,
- 0xd69c, 0x0040, 0x3d55, 0x2009, 0x0078, 0x791a, 0x68c0, 0x705a,
- 0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, 0x2001, 0x4f01, 0x2004,
- 0xd0c4, 0x00c0, 0x3dab, 0x70d8, 0xa02d, 0x0040, 0x3d84, 0xd1bc,
- 0x0040, 0x3d9e, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040,
- 0x3d75, 0x78e0, 0xa504, 0x00c0, 0x3dab, 0x70da, 0xc1bc, 0x71d6,
- 0x0078, 0x3dab, 0x2031, 0x0001, 0x852c, 0x0048, 0x3d83, 0x8633,
- 0x8210, 0x0078, 0x3d7c, 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040,
- 0x3d91, 0x2011, 0x0008, 0x852f, 0x1078, 0x3d7a, 0x8637, 0x0078,
- 0x3d93, 0x1078, 0x3d7a, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206,
- 0x0040, 0x3dab, 0x72de, 0x76da, 0x0078, 0x3dab, 0x7a80, 0xa294,
- 0x0f00, 0x70dc, 0xa236, 0x0040, 0x3d9b, 0x78e0, 0xa534, 0x0040,
- 0x3d9b, 0xc1bd, 0x71d6, 0xd1b4, 0x00c0, 0x2a08, 0x2300, 0xa405,
- 0x0040, 0x2a08, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a52, 0x007c,
- 0x6020, 0xa005, 0x0040, 0x3dc6, 0x8001, 0x6022, 0x6008, 0xa085,
- 0x0008, 0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x007c, 0xa006,
- 0x1078, 0x45d6, 0x7000, 0xa086, 0x0002, 0x0040, 0x3dd4, 0x7064,
- 0xa086, 0x0005, 0x00c0, 0x3dde, 0x682b, 0x0000, 0x6817, 0x0000,
- 0x681b, 0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084,
- 0x000f, 0x0079, 0x3de3, 0x2a0c, 0x3df3, 0x3ded, 0x3e15, 0x3dfd,
- 0x2a0c, 0x3deb, 0x3deb, 0x1078, 0x29b2, 0x1078, 0x3e20, 0x1078,
- 0x3e19, 0x0078, 0x3df9, 0x1078, 0x3e20, 0x705c, 0x2060, 0x6800,
- 0x6002, 0x1078, 0x2073, 0x0078, 0x2a0c, 0x7064, 0x7067, 0x0000,
- 0x7083, 0x0000, 0x0079, 0x3e04, 0x3e11, 0x3e11, 0x3e0c, 0x3e0c,
- 0x3e0c, 0x3e11, 0x3e0c, 0x3e11, 0x77d4, 0xc7dd, 0x77d6, 0x0079,
- 0x2f7e, 0x7067, 0x0000, 0x0078, 0x2a0c, 0x681b, 0x0000, 0x0078,
- 0x3711, 0x6800, 0xa005, 0x00c0, 0x3e1e, 0x6002, 0x6006, 0x007c,
- 0x6410, 0x84ff, 0x0040, 0x3e32, 0x2009, 0x4f02, 0x2104, 0x8001,
- 0x200a, 0x8421, 0x6412, 0x00c0, 0x3e32, 0x2021, 0x4f04, 0x2404,
- 0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005,
- 0x0040, 0x3e3c, 0x8001, 0x601a, 0x007c, 0x1078, 0x43d3, 0x681b,
- 0x0018, 0x0078, 0x3e7d, 0x1078, 0x43d3, 0x681b, 0x0019, 0x0078,
- 0x3e7d, 0x1078, 0x43d3, 0x681b, 0x001a, 0x0078, 0x3e7d, 0x1078,
- 0x43d3, 0x681b, 0x0003, 0x0078, 0x3e7d, 0x7774, 0x1078, 0x424e,
- 0x7178, 0xa18c, 0x00ff, 0x3210, 0xa294, 0x0300, 0x0040, 0x3e64,
- 0xa1e8, 0x94c0, 0x0078, 0x3e66, 0xa1e8, 0x95d0, 0x2d04, 0x2d08,
- 0x2068, 0xa005, 0x00c0, 0x3e6f, 0x707e, 0x0078, 0x2a0c, 0x6814,
- 0x7274, 0xa206, 0x0040, 0x3e77, 0x6800, 0x0078, 0x3e67, 0x6800,
- 0x200a, 0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3e20, 0x6820,
- 0xd084, 0x00c0, 0x3e85, 0x1078, 0x3e19, 0x1078, 0x3e36, 0x681f,
- 0x0000, 0x6823, 0x0020, 0x1078, 0x2073, 0x0078, 0x2a0c, 0xa282,
- 0x0003, 0x00c0, 0x4107, 0x7da8, 0xa5ac, 0x00ff, 0x7e5a, 0x7ea8,
- 0xa6b4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3eea,
- 0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0040, 0x3ed7, 0xa682, 0x000c,
- 0x0048, 0x3eae, 0x0040, 0x3eae, 0x2031, 0x000c, 0x2500, 0xa086,
- 0x000a, 0x0040, 0x3eb5, 0x852b, 0x852b, 0x1078, 0x41e0, 0x0040,
- 0x3ebd, 0x1078, 0x3fbc, 0x0078, 0x3ee0, 0x1078, 0x419b, 0x0c7e,
- 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3ff2, 0x0c7f,
- 0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
- 0x3ed4, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x0c7e,
- 0x2960, 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3ff2, 0x0c7f,
- 0x7e58, 0xd6d4, 0x00c0, 0x3ee7, 0x781b, 0x0067, 0x007c, 0x781b,
- 0x0079, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040,
- 0x3f33, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048,
- 0x3efd, 0x0040, 0x3efd, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8,
- 0x3f02, 0x2230, 0x6208, 0xa294, 0x00ff, 0x2001, 0x4f05, 0x2004,
- 0xd0e4, 0x00c0, 0x3f17, 0x78ec, 0xd0e4, 0x0040, 0x3f17, 0xa282,
- 0x000a, 0x00c8, 0x3f1d, 0x2011, 0x000a, 0x0078, 0x3f1d, 0xa282,
- 0x000c, 0x00c8, 0x3f1d, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8,
- 0x3f22, 0x2228, 0x1078, 0x419f, 0x2500, 0xa086, 0x000a, 0x0040,
- 0x3f2b, 0x852b, 0x852b, 0x1078, 0x41e0, 0x0040, 0x3f33, 0x1078,
- 0x3fbc, 0x0078, 0x3f37, 0x1078, 0x419b, 0x1078, 0x3ff2, 0x7858,
- 0xc095, 0x785a, 0x0c7f, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960,
- 0x6000, 0xd0e4, 0x00c0, 0x3f58, 0xd0b4, 0x00c0, 0x3f52, 0x6010,
- 0xa084, 0x000f, 0x00c0, 0x3f52, 0x6104, 0xa18c, 0xfff5, 0x6106,
- 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3f83,
- 0x68a0, 0xd0cc, 0x00c0, 0x3f52, 0x6208, 0xa294, 0x00ff, 0x2001,
- 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x3f71, 0x78ec, 0xd0e4, 0x0040,
- 0x3f71, 0xa282, 0x000b, 0x00c8, 0x3f71, 0x2011, 0x000a, 0x0078,
- 0x3f77, 0xa282, 0x000c, 0x00c8, 0x3f77, 0x2011, 0x000c, 0x6308,
- 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x3f83, 0x0040,
- 0x3f83, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
- 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822,
- 0x70d4, 0xd0b4, 0x0040, 0x3f9f, 0xc0b4, 0x70d6, 0x70b8, 0xa065,
- 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f,
- 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011,
- 0x0032, 0x2019, 0x0000, 0x0078, 0x3fad, 0x78ab, 0x0001, 0x78ab,
- 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820,
- 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7158, 0x2160, 0x2018,
- 0xa08c, 0x0020, 0x0040, 0x3fc5, 0xc0ac, 0x2008, 0xa084, 0xfff0,
- 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084,
- 0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4, 0xa39c, 0x0020, 0x0040,
- 0x3fdb, 0xa085, 0x4000, 0xc0fc, 0xd0b4, 0x00c0, 0x3fe0, 0xc0fd,
- 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004,
- 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006,
- 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6018, 0x789a, 0x78a4,
- 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886,
- 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, 0x007c, 0xa282, 0x0002,
- 0x00c0, 0x4107, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040,
- 0x4041, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8,
- 0x4107, 0x1078, 0x4094, 0x1078, 0x3ff2, 0xa980, 0x0001, 0x200c,
- 0x1078, 0x424a, 0x1078, 0x3f3e, 0x88ff, 0x0040, 0x4037, 0x789b,
- 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
- 0x4034, 0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58,
- 0xd6d4, 0x00c0, 0x403e, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
- 0x007c, 0xa282, 0x0002, 0x00c8, 0x4049, 0xa284, 0x0001, 0x0040,
- 0x4052, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x00c0, 0x4052,
- 0x2011, 0x0000, 0x1078, 0x417c, 0x1078, 0x4094, 0x1078, 0x3ff2,
- 0x7858, 0xc095, 0x785a, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x027e,
- 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0, 0x4075, 0xd0bc,
- 0x00c0, 0x4073, 0x6014, 0xd0b4, 0x00c0, 0x4073, 0xc1a4, 0x6106,
- 0xa006, 0x0078, 0x4091, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
- 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4,
- 0x0040, 0x408d, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200,
- 0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff,
- 0x0040, 0x409c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a,
- 0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x40a9,
- 0xc0fd, 0x78a6, 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f,
- 0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x40ba, 0x007f,
- 0x0078, 0x40bd, 0x007f, 0x0078, 0x4104, 0xd6ac, 0x0040, 0x4104,
- 0x7888, 0xa084, 0x0040, 0x0040, 0x4104, 0x7bb8, 0xa384, 0x003f,
- 0x831b, 0x00c8, 0x40cc, 0x8000, 0xa005, 0x0040, 0x40e1, 0x831b,
- 0x00c8, 0x40d5, 0x8001, 0x0040, 0x4101, 0xd6f4, 0x0040, 0x40e1,
- 0x78b8, 0x801b, 0x00c8, 0x40dd, 0x8000, 0xa084, 0x003f, 0x00c0,
- 0x4101, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108,
- 0x00c8, 0x40ec, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade,
- 0x1078, 0x4a44, 0x781b, 0x0076, 0xb284, 0x0300, 0x0040, 0x40fc,
- 0x2001, 0x0000, 0x0078, 0x40fe, 0x2001, 0x0001, 0x1078, 0x48ce,
- 0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0079, 0x007c, 0x1078,
- 0x412f, 0x781b, 0x0078, 0x007c, 0x1078, 0x4118, 0x781b, 0x0078,
- 0x007c, 0x6827, 0x0002, 0x1078, 0x4120, 0x781b, 0x0078, 0x007c,
- 0x2001, 0x0005, 0x0078, 0x4131, 0x2001, 0x000c, 0x0078, 0x4131,
- 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x4131, 0x2001,
- 0x000d, 0x0078, 0x4131, 0x2001, 0x0009, 0x0078, 0x4131, 0x2001,
- 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d4, 0xd0b4,
- 0x0040, 0x4147, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008,
- 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c,
- 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0x017e,
- 0xb28c, 0x0300, 0x0040, 0x4158, 0xa0e0, 0x53c0, 0x0078, 0x415a,
- 0xa0e0, 0x5440, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
- 0x000f, 0x0040, 0x416a, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
- 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040,
- 0x0040, 0x417a, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, 0x6004,
- 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001,
- 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
- 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x419a, 0xc0b4, 0x70d6, 0x0c7e,
- 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
- 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b,
- 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
- 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x70d4, 0xd0b4, 0x0040,
- 0x41be, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084,
- 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x157e,
- 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a,
- 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x4233, 0x2019, 0x0011, 0x20a9,
- 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040,
- 0x41de, 0x8420, 0x2300, 0xa210, 0x00f0, 0x41d3, 0x157f, 0x007c,
- 0x157e, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x4211, 0x2021,
- 0x4241, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, 0x0040,
- 0x4227, 0x0048, 0x4227, 0x8420, 0x95a9, 0x2011, 0x0032, 0xa582,
- 0x0032, 0x0040, 0x4227, 0x0048, 0x4227, 0x8420, 0x95a9, 0x2019,
- 0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x4227, 0x0048,
- 0x4227, 0x8420, 0x2300, 0xa210, 0x00f0, 0x4203, 0x157f, 0x0078,
- 0x4225, 0x2021, 0x4233, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
- 0x0032, 0x2200, 0xa502, 0x0040, 0x4227, 0x0048, 0x4227, 0x8420,
- 0x2300, 0xa210, 0x00f0, 0x4219, 0x157f, 0xa006, 0x007c, 0x157f,
- 0xa582, 0x0064, 0x00c8, 0x4230, 0x7808, 0xa085, 0x0070, 0x780a,
- 0x2404, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403,
- 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07,
- 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07,
- 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00,
- 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
- 0xd7fc, 0x0040, 0x425f, 0xa0e0, 0x74c0, 0x0078, 0x4261, 0xa0e0,
- 0x54c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x426f, 0x2079,
- 0x0100, 0x2009, 0x4f80, 0x2071, 0x4f80, 0x0078, 0x427f, 0x2009,
- 0x4f40, 0x2071, 0x4f40, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x0040,
- 0x427d, 0x2079, 0x0100, 0x0078, 0x427f, 0x2079, 0x0200, 0x2091,
- 0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x4286, 0x4290, 0x4290,
- 0x4290, 0x4290, 0x4290, 0x4290, 0x428e, 0x428e, 0x1078, 0x29b2,
- 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x42df,
- 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086,
- 0x1814, 0x00c0, 0x42df, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
- 0x00c0, 0x42a5, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
- 0x42ac, 0x7830, 0xd0bc, 0x00c0, 0x42df, 0x007e, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x007f, 0x0040, 0x42c1, 0xb284, 0x0300, 0x0078,
- 0x42c3, 0xb284, 0x0400, 0x0040, 0x42c9, 0x0018, 0x42df, 0x0078,
- 0x42cb, 0x0028, 0x42df, 0x79e4, 0xa184, 0x0030, 0x0040, 0x42df,
- 0x78ec, 0xa084, 0x0003, 0x0040, 0x42df, 0x681c, 0xd0ac, 0x00c0,
- 0x42dd, 0x1078, 0x4369, 0x0078, 0x42df, 0x781b, 0x00f9, 0x0f7f,
- 0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4f01, 0x2004, 0xd0ac, 0x00c0,
- 0x435b, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
- 0xb28c, 0x0300, 0x0040, 0x42f8, 0xa0e0, 0x53c0, 0x0078, 0x42fa,
- 0xa0e0, 0x5440, 0x6004, 0xa084, 0x000a, 0x00c0, 0x435b, 0x6108,
- 0xa194, 0xff00, 0x0040, 0x435b, 0xa18c, 0x00ff, 0x2001, 0x000a,
- 0xa106, 0x0040, 0x4326, 0x2001, 0x000c, 0xa106, 0x0040, 0x432a,
- 0x2001, 0x0012, 0xa106, 0x0040, 0x432e, 0x2001, 0x0014, 0xa106,
- 0x0040, 0x4332, 0x2001, 0x0019, 0xa106, 0x0040, 0x4336, 0x2001,
- 0x0032, 0xa106, 0x0040, 0x433a, 0x0078, 0x433e, 0x2009, 0x000c,
- 0x0078, 0x4340, 0x2009, 0x0012, 0x0078, 0x4340, 0x2009, 0x0014,
- 0x0078, 0x4340, 0x2009, 0x0019, 0x0078, 0x4340, 0x2009, 0x0020,
- 0x0078, 0x4340, 0x2009, 0x003f, 0x0078, 0x4340, 0x2011, 0x0000,
- 0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x2061,
- 0x4f00, 0x6004, 0xd0bc, 0x0040, 0x435b, 0x6814, 0xd0fc, 0x00c0,
- 0x4356, 0x60ea, 0x2061, 0x4f40, 0x0078, 0x4359, 0x60ee, 0x2061,
- 0x4f80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0079, 0x007c,
- 0x781b, 0x0078, 0x007c, 0x781b, 0x0067, 0x007c, 0x781b, 0x0064,
- 0x007c, 0x2009, 0x4f19, 0x210c, 0xa186, 0x0000, 0x0040, 0x437b,
- 0xa186, 0x0001, 0x0040, 0x437e, 0x701f, 0x000b, 0x7067, 0x0001,
- 0x781b, 0x0047, 0x007c, 0x781b, 0x00f0, 0x007c, 0x701f, 0x000a,
- 0x007c, 0x2009, 0x4f19, 0x210c, 0xa186, 0x0000, 0x0040, 0x4396,
- 0xa186, 0x0001, 0x0040, 0x4393, 0x701f, 0x000b, 0x7067, 0x0001,
- 0x781b, 0x0047, 0x007c, 0x701f, 0x000a, 0x007c, 0x781b, 0x00ef,
- 0x007c, 0x781b, 0x00f9, 0x007c, 0x781b, 0x00f8, 0x007c, 0x781b,
- 0x00c9, 0x007c, 0x781b, 0x00c8, 0x007c, 0x6818, 0xd0fc, 0x0040,
- 0x43ab, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c,
- 0x7830, 0xa084, 0x00c0, 0x00c0, 0x43d2, 0x7808, 0xc08c, 0x780a,
- 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x00c0,
- 0x43cf, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x00c0, 0x43cd, 0x7804,
- 0xa084, 0xff1f, 0xa085, 0x00e0, 0x7806, 0xa006, 0x007c, 0x7808,
- 0xc08d, 0x780a, 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830,
- 0xa084, 0x0040, 0x00c0, 0x43d7, 0x2001, 0x4f04, 0x2004, 0xd0ec,
- 0x0040, 0x43e6, 0xb284, 0x0300, 0x0078, 0x43e8, 0xb284, 0x0400,
- 0x0040, 0x43ee, 0x0098, 0x43f2, 0x0078, 0x43f0, 0x00a8, 0x43f2,
- 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
- 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x4415, 0x007e,
- 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x440b, 0xb284,
- 0x0300, 0x0078, 0x440d, 0xb284, 0x0400, 0x0040, 0x4413, 0x0098,
- 0x440f, 0x0078, 0x4415, 0x00a8, 0x4413, 0x78ac, 0x007e, 0x7808,
- 0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0,
- 0x37b9, 0xa784, 0x0070, 0x0040, 0x442d, 0x0c7e, 0x2d60, 0x2f68,
- 0x1078, 0x2926, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
- 0x443a, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x37b9,
- 0x0078, 0x435d, 0xa784, 0x0004, 0x0040, 0x4469, 0x78b8, 0xa084,
- 0x4001, 0x0040, 0x4469, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x37b9, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
- 0x4469, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f9,
- 0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0040, 0x4466, 0x681b,
- 0x0015, 0xd6f4, 0x0040, 0x4466, 0x681b, 0x0007, 0x1078, 0x4369,
- 0x007c, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f,
- 0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x30af, 0x007e, 0x2001, 0x4f04, 0x2004, 0xd0ec, 0x007f,
- 0x0040, 0x4486, 0xb284, 0x0300, 0x0078, 0x4488, 0xb284, 0x0400,
- 0x0040, 0x448e, 0x0018, 0x2a08, 0x0078, 0x4490, 0x0028, 0x2a08,
- 0x0078, 0x410c, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
- 0x8003, 0xd3fc, 0x0040, 0x44a0, 0xa080, 0x5440, 0x0078, 0x44a2,
- 0xa080, 0x53c0, 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
- 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014,
- 0x9914, 0x98fd, 0x0014, 0x0014, 0x0080, 0x00ff, 0x0100, 0x0402,
- 0x2008, 0xf880, 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014,
- 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
- 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
- 0x0010, 0xa200, 0x3806, 0x7102, 0x805f, 0x9481, 0x8839, 0x20c4,
- 0x0864, 0xa856, 0x3008, 0x28c1, 0x9d1b, 0xa201, 0x300c, 0x2847,
- 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2,
- 0x9ccb, 0xa8f3, 0x0864, 0xa844, 0x300c, 0xa801, 0x3008, 0x28e1,
- 0x9ccb, 0x2021, 0xa81d, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0,
- 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, 0x883d, 0x7942, 0x8020,
- 0xa4a1, 0x882b, 0x1814, 0x883b, 0x80df, 0x94a1, 0x7027, 0x85f2,
- 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa816, 0x883e, 0xa814,
- 0x2001, 0xa812, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x7942,
- 0x8020, 0xa4a1, 0x1814, 0x80df, 0x94a1, 0x883b, 0x7023, 0x8576,
- 0x8677, 0xa802, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d1b, 0x2044,
- 0x2103, 0x20a2, 0x2081, 0xa8c3, 0xa207, 0x0904, 0xa20e, 0xa809,
- 0xa203, 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601,
- 0xa208, 0x856e, 0x866f, 0x7161, 0x0014, 0x0704, 0x3008, 0x9ccb,
- 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844,
- 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014,
- 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014,
- 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014,
- 0x3008, 0x8000, 0x284a, 0x1011, 0xa8fc, 0x3008, 0x9d33, 0x8000,
- 0xa000, 0x2802, 0x1011, 0xa8fd, 0x9d39, 0xa8bd, 0x3008, 0x9d33,
- 0x283b, 0x1011, 0xa8fd, 0xa209, 0x7102, 0x805f, 0x9481, 0x0017,
- 0x300c, 0xa209, 0x8000, 0x85a4, 0x1de2, 0xa209, 0xdac1, 0x0014,
- 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0,
- 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d25,
- 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016,
- 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021,
- 0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822,
- 0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944,
- 0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4,
- 0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
- 0x00c0, 0x4602, 0x720c, 0x82ff, 0x0040, 0x45ed, 0x8aff, 0x00c0,
- 0x4602, 0x7200, 0xd284, 0x00c0, 0x4602, 0x7804, 0xd0cc, 0x0040,
- 0x45f3, 0x1078, 0x4acc, 0x7023, 0x0000, 0x7027, 0x0000, 0x7000,
- 0xd084, 0x0040, 0x45fd, 0x7007, 0x0004, 0x7003, 0x0008, 0x127f,
- 0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084,
- 0x0040, 0x465b, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x460a,
- 0xa184, 0x0003, 0x0040, 0x468c, 0xa184, 0x01e0, 0x00c0, 0x468c,
- 0xd1f4, 0x00c0, 0x460a, 0xa184, 0x3000, 0xa086, 0x1000, 0x0040,
- 0x460a, 0x2001, 0x4f05, 0x2004, 0xd0e4, 0x0040, 0x4637, 0x2011,
- 0x0180, 0x710c, 0x8211, 0x0040, 0x4645, 0x7008, 0xd0f4, 0x00c0,
- 0x460a, 0x700c, 0xa106, 0x0040, 0x462a, 0x0078, 0x4627, 0x2011,
- 0x0180, 0x710c, 0x8211, 0x0040, 0x4645, 0x7008, 0xd0f4, 0x00c0,
- 0x460a, 0x700c, 0xa106, 0x0040, 0x463a, 0x7007, 0x0012, 0x7108,
- 0x0005, 0x7008, 0xa106, 0x00c0, 0x4647, 0xa184, 0x0003, 0x0040,
- 0x468c, 0xd194, 0x0040, 0x4647, 0xd1f4, 0x0040, 0x468c, 0x7007,
- 0x0002, 0x0078, 0x460a, 0x7108, 0xd1fc, 0x0040, 0x4666, 0x1078,
- 0x47ed, 0x8aff, 0x0040, 0x45dc, 0x0078, 0x465b, 0x700c, 0xa08c,
- 0x03ff, 0x0040, 0x4691, 0x7004, 0xd084, 0x0040, 0x4683, 0x7014,
- 0xa005, 0x00c0, 0x467f, 0x7010, 0x7310, 0xa306, 0x00c0, 0x4673,
- 0x2300, 0xa005, 0x0040, 0x4683, 0xa102, 0x00c8, 0x465b, 0x7007,
- 0x0010, 0x0078, 0x468c, 0x8aff, 0x0040, 0x4691, 0x1078, 0x49f2,
- 0x00c0, 0x4686, 0x0040, 0x465b, 0x1078, 0x4738, 0x127f, 0x2000,
- 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x46a0, 0x7007,
- 0x0002, 0x0078, 0x4691, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c,
- 0xa205, 0x00c0, 0x468c, 0x7023, 0x0000, 0x7027, 0x0000, 0x7003,
- 0x0008, 0x007e, 0x2001, 0x4f01, 0x2004, 0xd0cc, 0x0040, 0x46b2,
- 0x1078, 0x4acc, 0x007f, 0x127f, 0x2000, 0x007c, 0x6428, 0x84ff,
- 0x0040, 0x46e2, 0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x46f2,
- 0x273c, 0x87fb, 0x00c0, 0x46d0, 0x0048, 0x46c8, 0x1078, 0x29b2,
- 0x609c, 0xa075, 0x0040, 0x46e2, 0x0078, 0x46bb, 0x2039, 0x46e7,
- 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0040,
- 0x46e2, 0x8738, 0x2704, 0xa005, 0x00c0, 0x46d1, 0x709c, 0xa075,
- 0x00c0, 0x46bb, 0x007c, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011,
- 0x0015, 0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015,
- 0x001b, 0x0000, 0x0000, 0x46e7, 0x46e4, 0x0000, 0x0000, 0x8000,
- 0x0000, 0x46e7, 0x0000, 0x46ef, 0x46ec, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x46ef, 0x0000, 0x46ea, 0x46ea, 0x0000, 0x0000, 0x8000,
- 0x0000, 0x46ea, 0x0000, 0x46f0, 0x46f0, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x46f0, 0x2079, 0x4f00, 0x2071, 0x0010, 0x7007, 0x000a,
- 0x7007, 0x0002, 0x7003, 0x0001, 0x7810, 0xd0ec, 0x0040, 0x4726,
- 0x2009, 0x0001, 0x2071, 0x0020, 0x0078, 0x472a, 0x2009, 0x0002,
- 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000,
- 0x8109, 0x0040, 0x4737, 0x2071, 0x0020, 0x0078, 0x472a, 0x007c,
- 0x7004, 0x8004, 0x00c8, 0x47c1, 0x7108, 0x7008, 0xa106, 0x00c0,
- 0x473c, 0xa184, 0x01e0, 0x0040, 0x4749, 0x1078, 0x4830, 0x0078,
- 0x47e9, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106,
- 0x00c0, 0x474d, 0xa184, 0x01e0, 0x0040, 0x475a, 0x1078, 0x4830,
- 0x0078, 0x47e9, 0x7810, 0xd0ec, 0x0040, 0x4774, 0x2001, 0x04fd,
- 0x2004, 0xa086, 0x0003, 0x00c0, 0x4778, 0xa184, 0x4000, 0x0040,
- 0x477c, 0xa382, 0x0003, 0x00c8, 0x477c, 0xa184, 0x0004, 0x0040,
- 0x474d, 0x8318, 0x0078, 0x474d, 0x7814, 0xd0ec, 0x00c0, 0x477c,
- 0xa184, 0x4000, 0x00c0, 0x474d, 0xa19c, 0x300c, 0xa386, 0x2004,
- 0x0040, 0x4799, 0xa386, 0x0008, 0x0040, 0x47a4, 0x7004, 0xd084,
- 0x00c0, 0x4795, 0x7108, 0x7008, 0xa106, 0x00c0, 0x478a, 0xa184,
- 0x0003, 0x0040, 0x4795, 0x0078, 0x4830, 0xa386, 0x200c, 0x00c0,
- 0x474d, 0x7200, 0x8204, 0x0048, 0x47a4, 0x730c, 0xa384, 0x03ff,
- 0x0040, 0x47a4, 0x1078, 0x29b2, 0x7108, 0x7008, 0xa106, 0x00c0,
- 0x47a4, 0xa184, 0x01e0, 0x0040, 0x47b1, 0x1078, 0x4830, 0x0078,
- 0x47e9, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x47c1, 0x7310,
- 0x7014, 0xa305, 0x0040, 0x47c1, 0x710c, 0xa184, 0x03ff, 0x00c0,
- 0x4738, 0x7108, 0x7008, 0xa106, 0x00c0, 0x47c1, 0xa184, 0x01e0,
- 0x0040, 0x47ce, 0x1078, 0x4830, 0x0078, 0x47e9, 0x7007, 0x0012,
- 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x47d2, 0x7108, 0x7008,
- 0xa106, 0x00c0, 0x47d6, 0xa184, 0x01e0, 0x0040, 0x47e3, 0x1078,
- 0x4830, 0x0078, 0x47e9, 0x7007, 0x0012, 0x7108, 0x8103, 0x0048,
- 0x47d6, 0x7003, 0x0008, 0x007c, 0x7108, 0xa184, 0x01e0, 0x00c0,
- 0x4830, 0x7108, 0xa184, 0x01e0, 0x00c0, 0x4830, 0xa184, 0x0007,
- 0x0079, 0x47fa, 0x4804, 0x4814, 0x4802, 0x4814, 0x4802, 0x4872,
- 0x4802, 0x4870, 0x1078, 0x29b2, 0x7004, 0xa084, 0x0010, 0xc08d,
- 0x7006, 0x8aff, 0x00c0, 0x480f, 0x2049, 0x0000, 0x007c, 0x1078,
- 0x49f2, 0x00c0, 0x480f, 0x007c, 0x7004, 0xa084, 0x0010, 0xc08d,
- 0x7006, 0x7004, 0xd084, 0x00c0, 0x4828, 0x7108, 0x7008, 0xa106,
- 0x00c0, 0x481d, 0xa184, 0x0003, 0x0040, 0x4828, 0x0078, 0x4830,
- 0x8aff, 0x0040, 0x482f, 0x1078, 0x49f2, 0x00c0, 0x482b, 0x007c,
- 0x7007, 0x0012, 0x7108, 0x00e0, 0x4833, 0x2091, 0x6000, 0x00e0,
- 0x4837, 0x2091, 0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004,
- 0xd09c, 0x00c0, 0x483f, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0,
- 0x4843, 0x7003, 0x0000, 0x7000, 0xa005, 0x00c0, 0x4857, 0x7004,
- 0xa005, 0x00c0, 0x4857, 0x700c, 0xa005, 0x0040, 0x4859, 0x0078,
- 0x483b, 0x2049, 0x0000, 0xb284, 0x0100, 0x0040, 0x4863, 0x2001,
- 0x0000, 0x0078, 0x4865, 0x2001, 0x0001, 0x1078, 0x4262, 0x681b,
- 0x0002, 0x2051, 0x0000, 0x007c, 0x1078, 0x29b2, 0x1078, 0x29b2,
- 0x1078, 0x48b9, 0x7210, 0x7114, 0x700c, 0xa09c, 0x03ff, 0x2800,
- 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x48b9, 0x2704, 0x2c58,
- 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b, 0x2400,
- 0xa305, 0x0040, 0x4895, 0x00c8, 0x4895, 0x8412, 0x8210, 0x830a,
- 0xa189, 0x0000, 0x2b60, 0x0078, 0x487c, 0x2b60, 0x8a07, 0x007e,
- 0x6004, 0xd09c, 0x0040, 0x48a0, 0xa7ba, 0x46ec, 0x0078, 0x48a2,
- 0xa7ba, 0x46e4, 0x007f, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
- 0x6b8e, 0x7108, 0x7008, 0xa106, 0x00c0, 0x48a9, 0xa184, 0x01e0,
- 0x0040, 0x48b4, 0x1078, 0x4830, 0x7007, 0x0012, 0x1078, 0x4738,
- 0x007c, 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x48cd, 0x6000,
- 0xa064, 0x00c0, 0x48c4, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080,
- 0x4702, 0x203c, 0x87fb, 0x1040, 0x29b2, 0x007c, 0x127e, 0x0d7e,
- 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060,
- 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff,
- 0x007e, 0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x48eb, 0xa0b8,
- 0x46ec, 0x0078, 0x48ed, 0xa0b8, 0x46e4, 0xb284, 0x0100, 0x0040,
- 0x48f4, 0x7e20, 0x0078, 0x48f5, 0x7e24, 0xa6b5, 0x000c, 0x681c,
- 0xd0b4, 0x0040, 0x48fc, 0xc685, 0x2400, 0xa305, 0x0040, 0x4925,
- 0x2c58, 0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004,
- 0xa301, 0x701e, 0xd19c, 0x0040, 0x4915, 0x6010, 0xa081, 0x0000,
- 0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202,
- 0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001,
- 0x2b60, 0x1078, 0x4a1c, 0x0078, 0x4927, 0x1078, 0x49f2, 0x00c0,
- 0x4925, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084,
- 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094,
- 0x00c0, 0x4936, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e,
- 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f,
- 0x0d7f, 0x7e20, 0xb284, 0x0100, 0x00c0, 0x494f, 0x7e24, 0xa6b5,
- 0x000c, 0x681c, 0xd0ac, 0x00c0, 0x495a, 0xc685, 0x7003, 0x0000,
- 0x7007, 0x0004, 0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f,
- 0xa7b8, 0x46f2, 0x273c, 0x87fb, 0x00c0, 0x4970, 0x0048, 0x496a,
- 0x1078, 0x29b2, 0x689c, 0xa065, 0x0040, 0x4974, 0x0078, 0x495d,
- 0x1078, 0x49f2, 0x00c0, 0x4970, 0x127f, 0x2000, 0x007c, 0x127e,
- 0x007e, 0x017e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e,
- 0x2090, 0x007f, 0x7e20, 0xb284, 0x0100, 0x00c0, 0x4988, 0x7e24,
- 0x0d7f, 0x037f, 0x047f, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040,
- 0x4996, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004, 0x2049, 0x4977,
- 0x6828, 0xa055, 0x0d7e, 0x0040, 0x49ee, 0x2d70, 0x2e60, 0x7004,
- 0xa0bc, 0x000f, 0xa7b8, 0x46f2, 0x273c, 0x87fb, 0x00c0, 0x49b3,
- 0x0048, 0x49ac, 0x1078, 0x29b2, 0x709c, 0xa075, 0x2060, 0x0040,
- 0x49ee, 0x0078, 0x499f, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c,
- 0xa31b, 0x0048, 0x49cc, 0x8a51, 0x00c0, 0x49c0, 0x1078, 0x29b2,
- 0x8738, 0x2704, 0xa005, 0x00c0, 0x49b4, 0x709c, 0xa075, 0x2060,
- 0x0040, 0x49ee, 0x0078, 0x499f, 0x8422, 0x8420, 0x831a, 0xa399,
- 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8,
- 0x49db, 0x1078, 0x29b2, 0xb284, 0x0100, 0x0040, 0x49e9, 0x2001,
- 0x4f04, 0x2004, 0xd0ec, 0x00c0, 0x49e9, 0x2071, 0x0050, 0x0078,
- 0x49eb, 0x2071, 0x0020, 0x0d7f, 0x0078, 0x48fc, 0x0d7f, 0x127f,
- 0x2000, 0x007c, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040,
- 0x49fb, 0xa006, 0x007c, 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0,
- 0x4a02, 0x007c, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e,
- 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xd09c, 0x0040, 0x4a14,
- 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010,
- 0xc085, 0x7006, 0x2079, 0x4f00, 0x8738, 0x8a51, 0x0040, 0x4a40,
- 0x2704, 0xa005, 0x00c0, 0x4a32, 0x609c, 0xa005, 0x0040, 0x4a41,
- 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x46f2, 0x203c, 0x87fb,
- 0x1040, 0x29b2, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040,
- 0x4a3c, 0xa006, 0x0078, 0x4a41, 0xa084, 0x0003, 0xa086, 0x0003,
- 0x007c, 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4,
- 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184,
- 0x0003, 0x00c0, 0x4a59, 0x6828, 0xa005, 0x0040, 0x4a69, 0x0078,
- 0x4602, 0x7108, 0xd1fc, 0x0040, 0x4a61, 0x1078, 0x47ed, 0x0078,
- 0x4a4e, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4a63, 0x1078,
- 0x47ed, 0x7008, 0xa086, 0x0008, 0x00c0, 0x4a4e, 0x7000, 0xa005,
- 0x00c0, 0x4a4e, 0x7003, 0x0000, 0x2049, 0x0000, 0x007e, 0x7804,
- 0xd0cc, 0x0040, 0x4a7d, 0x1078, 0x4acc, 0x007f, 0x127f, 0x2000,
- 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4,
- 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x4a81, 0xad80,
- 0x0011, 0x20a0, 0xb284, 0x0100, 0x0040, 0x4aa4, 0x2001, 0x4f04,
- 0x2004, 0xd0ec, 0x0040, 0x4aa0, 0x2099, 0x0031, 0x0078, 0x4aa6,
- 0x2099, 0x0032, 0x0078, 0x4aa6, 0x2099, 0x0031, 0x700c, 0xa084,
- 0x03ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001,
- 0x0040, 0x4ab5, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff,
- 0x0040, 0x4ac1, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0,
- 0x4abc, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f,
- 0x147f, 0x127f, 0x2000, 0x007c, 0x6814, 0xd0fc, 0x0040, 0x4b11,
- 0x7000, 0xd084, 0x0040, 0x4b11, 0x7e24, 0xa6b5, 0x0004, 0x7007,
- 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4ad9, 0x7118, 0x017e,
- 0x711c, 0x017e, 0x7120, 0x017e, 0x7124, 0x017e, 0xa00e, 0x711a,
- 0x701f, 0x3fff, 0x7122, 0x7126, 0x7013, 0x0004, 0x7116, 0x7602,
- 0x7007, 0x0001, 0x2001, 0xffff, 0x2009, 0x0031, 0x200a, 0x200a,
- 0x7108, 0x7008, 0xa106, 0x00c0, 0x4af8, 0xd1fc, 0x0040, 0x4af8,
- 0x027f, 0x7226, 0x027f, 0x7222, 0x027f, 0x721e, 0x027f, 0x721a,
- 0x7007, 0x0002, 0x7008, 0xa086, 0x0008, 0x0040, 0x4b11, 0x0078,
- 0x4830, 0x7007, 0x0004, 0x7003, 0x0000, 0x007c, 0x2091, 0x8000,
- 0x2091, 0x6000, 0x78ac, 0xa005, 0x00c0, 0x4b2d, 0x7974, 0x70d0,
- 0xa106, 0x00c0, 0x4b2d, 0x781c, 0xa005, 0x0040, 0x4b2d, 0x781f,
- 0x0000, 0x0068, 0x4b2d, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832,
- 0x00c0, 0x4bb5, 0x7834, 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x4bae,
- 0x2061, 0x74c0, 0x2069, 0x4f80, 0xc7fd, 0x68d0, 0xa005, 0x0040,
- 0x4b47, 0x8001, 0x68d2, 0x00c0, 0x4b47, 0x1078, 0x4d83, 0x6800,
- 0xa084, 0x000f, 0x0040, 0x4b5c, 0xa086, 0x0001, 0x0040, 0x4b5c,
- 0x6844, 0xa00d, 0x0040, 0x4b5c, 0x2104, 0xa005, 0x0040, 0x4b5c,
- 0x8001, 0x200a, 0x0040, 0x4cf6, 0x6814, 0xa005, 0x0040, 0x4b81,
- 0x8001, 0x6816, 0x00c0, 0x4b81, 0x68a7, 0x0001, 0x0f7e, 0xd7fc,
- 0x00c0, 0x4b76, 0x7810, 0xd0ec, 0x0040, 0x4b72, 0x2079, 0x0100,
- 0x0078, 0x4b78, 0x2079, 0x0200, 0x0078, 0x4b78, 0x2079, 0x0100,
- 0x1078, 0x43d3, 0x0f7f, 0x6864, 0xa005, 0x0040, 0x4b81, 0x1078,
- 0x266f, 0x6880, 0xa005, 0x0040, 0x4b8e, 0x8001, 0x6882, 0x00c0,
- 0x4b8e, 0x6867, 0x0000, 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc,
- 0x0040, 0x4bab, 0xc0fc, 0x68d6, 0x20a9, 0x0200, 0x6034, 0xa005,
- 0x0040, 0x4ba7, 0x8001, 0x6036, 0x68d4, 0xc0fd, 0x68d6, 0x00c0,
- 0x4ba7, 0x6010, 0xa005, 0x0040, 0x4ba7, 0x1078, 0x266f, 0xace0,
- 0x0010, 0x00f0, 0x4b96, 0xd7fc, 0x0040, 0x4bb5, 0x2061, 0x54c0,
- 0x2069, 0x4f40, 0xc7fc, 0x0078, 0x4b3d, 0x1078, 0x4bf1, 0x7838,
- 0x8001, 0x783a, 0x00c0, 0x4bd7, 0x783c, 0x783a, 0x2061, 0x54c0,
- 0x2069, 0x4f40, 0xc7fc, 0x680c, 0xa005, 0x0040, 0x4bc9, 0x1078,
- 0x4c5b, 0xd7fc, 0x00c0, 0x4bd7, 0x7810, 0xd0ec, 0x00c0, 0x4bd7,
- 0x2061, 0x74c0, 0x2069, 0x4f80, 0xc7fd, 0x0078, 0x4bc3, 0x7814,
- 0xd0e4, 0x00c0, 0x4bdb, 0x7810, 0xd0cc, 0x0040, 0x4bee, 0xd0ac,
- 0x00c0, 0x4be7, 0xd0a4, 0x0040, 0x4bee, 0xc0ad, 0x7812, 0x2091,
- 0x8001, 0x0068, 0x4bed, 0x1078, 0x23dc, 0x007c, 0x2091, 0x8001,
- 0x007c, 0x7840, 0x8001, 0x7842, 0x00c0, 0x4c5a, 0x7844, 0x7842,
- 0x2069, 0x4f40, 0xc7fc, 0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040,
- 0x4c03, 0x2079, 0x0100, 0x68d8, 0xa005, 0x0040, 0x4c0f, 0x7de0,
- 0xa504, 0x00c0, 0x4c0f, 0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079,
- 0x4f00, 0x6810, 0xa005, 0x00c0, 0x4c17, 0x2001, 0x0101, 0x8001,
- 0x6812, 0xd7fc, 0x0040, 0x4c20, 0xa080, 0x95d0, 0x0078, 0x4c22,
- 0xa080, 0x94c0, 0x2040, 0x2004, 0xa065, 0x0040, 0x4c4c, 0x6024,
- 0xa005, 0x0040, 0x4c48, 0x8001, 0x6026, 0x00c0, 0x4c48, 0x6800,
- 0xa005, 0x0040, 0x4c3b, 0x684c, 0xac06, 0x00c0, 0x4c3b, 0x1078,
- 0x4cf6, 0x0078, 0x4c4c, 0x6864, 0xa005, 0x0040, 0x4c43, 0x6027,
- 0x0001, 0x0078, 0x4c48, 0x1078, 0x4ca9, 0x2804, 0x0078, 0x4c24,
- 0x6000, 0x2c40, 0x0078, 0x4c24, 0xd7fc, 0x00c0, 0x4c5a, 0x7810,
- 0xd0ec, 0x00c0, 0x4c5a, 0x2069, 0x4f80, 0xc7fd, 0x2079, 0x0100,
- 0x0078, 0x4c03, 0x007c, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008,
- 0xd09c, 0x0040, 0x4c95, 0x6024, 0xa005, 0x0040, 0x4c6b, 0x8001,
- 0x6026, 0x0078, 0x4c93, 0x6008, 0xc09c, 0xd084, 0x00c0, 0x4c73,
- 0xd0ac, 0x0040, 0x4c8d, 0x600a, 0x6004, 0xa005, 0x0040, 0x4c95,
- 0x0d7e, 0x0c7e, 0x017e, 0x2068, 0x6010, 0x8001, 0x6012, 0x1078,
- 0x3e19, 0x2d00, 0x2c68, 0x2060, 0x1078, 0x1ea2, 0x1078, 0x2064,
- 0x017f, 0x0c7f, 0x0d7f, 0x0078, 0x4c95, 0xc0bd, 0x600a, 0xa18d,
- 0x0001, 0x0078, 0x4c95, 0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0,
- 0x4c5f, 0xa184, 0x0001, 0x0040, 0x4ca4, 0xa18c, 0xfffe, 0x690e,
- 0x1078, 0x266f, 0x0078, 0x4ca5, 0x690e, 0x007c, 0x00c0, 0x4ca5,
- 0x786c, 0x2c00, 0x687e, 0x6714, 0x6f76, 0x6017, 0x0000, 0x602b,
- 0x0000, 0x601b, 0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020,
- 0xa084, 0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x1078,
- 0x1e2b, 0x6818, 0xa005, 0x0040, 0x4cc7, 0x8001, 0x681a, 0x6808,
- 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0,
- 0x4cd3, 0x1078, 0x29b2, 0x6812, 0x00c0, 0x4cd9, 0x7910, 0xc1a5,
- 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x2073,
- 0xd7fc, 0x00c0, 0x4ce7, 0x2069, 0x4f40, 0x0078, 0x4ce9, 0x2069,
- 0x4f80, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4cf3,
- 0x697a, 0x2001, 0x0004, 0x1078, 0x2663, 0x007c, 0x0d7e, 0x694c,
- 0x2160, 0xd7fc, 0x00c0, 0x4d08, 0x7810, 0xd0ec, 0x0040, 0x4d04,
- 0x2069, 0x0100, 0x0078, 0x4d0a, 0x2069, 0x0200, 0x0078, 0x4d0a,
- 0x2069, 0x0100, 0x1078, 0x2926, 0x601b, 0x0006, 0x6858, 0xa084,
- 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022,
- 0x602f, 0x0000, 0x6033, 0x0000, 0x6808, 0xa084, 0xfffd, 0x680a,
- 0x6830, 0xd0b4, 0x0040, 0x4d3c, 0x684b, 0x0004, 0x20a9, 0x0014,
- 0x6848, 0xd094, 0x0040, 0x4d2e, 0x00f0, 0x4d28, 0x684b, 0x0009,
- 0x20a9, 0x0014, 0x6848, 0xd084, 0x0040, 0x4d38, 0x00f0, 0x4d32,
- 0x20a9, 0x00fa, 0x00f0, 0x4d3a, 0x681b, 0x0047, 0x0d7f, 0x6867,
- 0x0007, 0x007c, 0x2079, 0x4f00, 0x1078, 0x4d76, 0x1078, 0x4d5c,
- 0x1078, 0x4d69, 0x2009, 0x0002, 0x2069, 0x4f80, 0x680f, 0x0000,
- 0x6813, 0x0000, 0x6817, 0x0000, 0x8109, 0x0040, 0x4d5b, 0x2069,
- 0x4f40, 0x0078, 0x4d4e, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x4d64,
- 0x2019, 0x00cc, 0x0078, 0x4d66, 0x2019, 0x007b, 0x7b3a, 0x7b3e,
- 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4d71, 0x2019, 0x0040, 0x0078,
- 0x4d73, 0x2019, 0x0026, 0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4,
- 0x00c0, 0x4d7e, 0x2019, 0x3f94, 0x0078, 0x4d80, 0x2019, 0x2624,
- 0x7b32, 0x7b36, 0x007c, 0x6a50, 0xa285, 0x0000, 0x0040, 0x4daf,
- 0x6954, 0x6bc0, 0xa300, 0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0,
- 0x4d9b, 0x8211, 0x0040, 0x4d9f, 0x8108, 0xa11a, 0x0048, 0x4d8c,
- 0x69c0, 0x0078, 0x4d8c, 0x68d3, 0x000a, 0x0c7f, 0x007c, 0x6950,
- 0x6ac0, 0x2264, 0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5,
- 0x600a, 0x8210, 0x8109, 0x00c0, 0x4da1, 0x6952, 0x0c7f, 0x007c,
- 0x00e0, 0x4db0, 0x2091, 0x6000, 0x00e0, 0x4db4, 0x2091, 0x6000,
- 0x70ec, 0xd0dc, 0x00c0, 0x4dc1, 0xd0d4, 0x0040, 0x4dea, 0x0078,
- 0x4ded, 0x2008, 0x7810, 0xd0ec, 0x0040, 0x4dd4, 0xd1c4, 0x00c0,
- 0x4e0e, 0x7814, 0xc0c5, 0x7816, 0x7810, 0xc0f5, 0x7812, 0xd0ec,
- 0x0040, 0x4e0a, 0x0078, 0x4e06, 0xae8e, 0x0100, 0x0040, 0x4de1,
- 0x7814, 0xc0f5, 0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4e0a, 0x0078,
- 0x4e06, 0x7814, 0xc0fd, 0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4e0a,
- 0x0078, 0x4e06, 0xd0e4, 0x0040, 0x4e0c, 0x00e0, 0x4ded, 0x2091,
- 0x6000, 0x2009, 0x000c, 0x00e0, 0x4df3, 0x2091, 0x6000, 0x8109,
- 0x00c0, 0x4df3, 0x70e4, 0xa084, 0x01ff, 0xa086, 0x01ff, 0x00c0,
- 0x4e04, 0x70ec, 0x0078, 0x4dc1, 0x1078, 0x4e0f, 0x7804, 0xd08c,
- 0x0040, 0x4e0c, 0x681f, 0x000c, 0x70a0, 0x70a2, 0x007c, 0x7910,
- 0xd1ec, 0x0040, 0x4e19, 0x7814, 0xc0c4, 0xc1f4, 0x7912, 0x0078,
- 0x4e2b, 0xae8e, 0x0100, 0x0040, 0x4e25, 0x7814, 0xc0f4, 0xd0fc,
- 0x00c0, 0x4e2b, 0xc0c4, 0x0078, 0x4e2b, 0x7814, 0xc0fc, 0xd0f4,
- 0x00c0, 0x4e2b, 0xc0c4, 0x7816, 0x007c, 0x14e3
-};
-#ifdef UNIQUE_FW_NAME
-static unsigned short fw1280ei_length01 = 0x3e2e;
-#else
-static unsigned short risc_code_length01 = 0x3e2e;
-#endif
-
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index df09820e891..351b56ced92 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -348,6 +348,7 @@
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/dma-mapping.h>
+#include <linux/firmware.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -384,11 +385,7 @@
#define MEMORY_MAPPED_IO 1
#endif
-#define UNIQUE_FW_NAME
#include "qla1280.h"
-#include "ql12160_fw.h" /* ISP RISC codes */
-#include "ql1280_fw.h"
-#include "ql1040_fw.h"
#ifndef BITS_PER_LONG
#error "BITS_PER_LONG not defined!"
@@ -541,10 +538,7 @@ __setup("qla1280=", qla1280_setup);
struct qla_boards {
unsigned char name[9]; /* Board ID String */
int numPorts; /* Number of SCSI ports */
- unsigned short *fwcode; /* pointer to FW array */
- unsigned short *fwlen; /* number of words in array */
- unsigned short *fwstart; /* start address for F/W */
- unsigned char *fwver; /* Ptr to F/W version array */
+ char *fwname; /* firmware name */
};
/* NOTE: the last argument in each entry is used to index ql1280_board_tbl */
@@ -567,19 +561,13 @@ MODULE_DEVICE_TABLE(pci, qla1280_pci_tbl);
static struct qla_boards ql1280_board_tbl[] = {
/* Name , Number of ports, FW details */
- {"QLA12160", 2, &fw12160i_code01[0], &fw12160i_length01,
- &fw12160i_addr01, &fw12160i_version_str[0]},
- {"QLA1040", 1, &risc_code01[0], &risc_code_length01,
- &risc_code_addr01, &firmware_version[0]},
- {"QLA1080", 1, &fw1280ei_code01[0], &fw1280ei_length01,
- &fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA1240", 2, &fw1280ei_code01[0], &fw1280ei_length01,
- &fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA1280", 2, &fw1280ei_code01[0], &fw1280ei_length01,
- &fw1280ei_addr01, &fw1280ei_version_str[0]},
- {"QLA10160", 1, &fw12160i_code01[0], &fw12160i_length01,
- &fw12160i_addr01, &fw12160i_version_str[0]},
- {" ", 0}
+ {"QLA12160", 2, "qlogic/12160.bin"},
+ {"QLA1040", 1, "qlogic/1040.bin"},
+ {"QLA1080", 1, "qlogic/1280.bin"},
+ {"QLA1240", 2, "qlogic/1280.bin"},
+ {"QLA1280", 2, "qlogic/1280.bin"},
+ {"QLA10160", 1, "qlogic/12160.bin"},
+ {" ", 0, " "},
};
static int qla1280_verbose = 1;
@@ -704,7 +692,7 @@ qla1280_info(struct Scsi_Host *host)
sprintf (bp,
"QLogic %s PCI to SCSI Host Adapter\n"
" Firmware version: %2d.%02d.%02d, Driver version %s",
- &bdp->name[0], bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
+ &bdp->name[0], ha->fwver1, ha->fwver2, ha->fwver3,
QLA1280_VERSION);
return bp;
}
@@ -1648,36 +1636,60 @@ qla1280_chip_diag(struct scsi_qla_host *ha)
static int
qla1280_load_firmware_pio(struct scsi_qla_host *ha)
{
- uint16_t risc_address, *risc_code_address, risc_code_size;
+ const struct firmware *fw;
+ const __le16 *fw_data;
+ uint16_t risc_address, risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT], i;
int err;
+ err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
+ &ha->pdev->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ ql1280_board_tbl[ha->devnum].fwname, err);
+ return err;
+ }
+ if ((fw->size % 2) || (fw->size < 6)) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, ql1280_board_tbl[ha->devnum].fwname);
+ err = -EINVAL;
+ goto out;
+ }
+ ha->fwver1 = fw->data[0];
+ ha->fwver2 = fw->data[1];
+ ha->fwver3 = fw->data[2];
+ fw_data = (const __le16 *)&fw->data[0];
+ ha->fwstart = __le16_to_cpu(fw_data[2]);
+
/* Load RISC code. */
- risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
- risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
- risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
+ risc_address = ha->fwstart;
+ fw_data = (const __le16 *)&fw->data[4];
+ risc_code_size = (fw->size - 6) / 2;
for (i = 0; i < risc_code_size; i++) {
mb[0] = MBC_WRITE_RAM_WORD;
mb[1] = risc_address + i;
- mb[2] = risc_code_address[i];
+ mb[2] = __le16_to_cpu(fw_data[i]);
err = qla1280_mailbox_command(ha, BIT_0 | BIT_1 | BIT_2, mb);
if (err) {
printk(KERN_ERR "scsi(%li): Failed to load firmware\n",
ha->host_no);
- return err;
+ goto out;
}
}
-
- return 0;
+out:
+ release_firmware(fw);
+ return err;
}
#define DUMP_IT_BACK 0 /* for debug of RISC loading */
static int
qla1280_load_firmware_dma(struct scsi_qla_host *ha)
{
- uint16_t risc_address, *risc_code_address, risc_code_size;
+ const struct firmware *fw;
+ const __le16 *fw_data;
+ uint16_t risc_address, risc_code_size;
uint16_t mb[MAILBOX_REGISTER_COUNT], cnt;
int err = 0, num, i;
#if DUMP_IT_BACK
@@ -1689,10 +1701,29 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
return -ENOMEM;
#endif
+ err = request_firmware(&fw, ql1280_board_tbl[ha->devnum].fwname,
+ &ha->pdev->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ ql1280_board_tbl[ha->devnum].fwname, err);
+ return err;
+ }
+ if ((fw->size % 2) || (fw->size < 6)) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, ql1280_board_tbl[ha->devnum].fwname);
+ err = -EINVAL;
+ goto out;
+ }
+ ha->fwver1 = fw->data[0];
+ ha->fwver2 = fw->data[1];
+ ha->fwver3 = fw->data[2];
+ fw_data = (const __le16 *)&fw->data[0];
+ ha->fwstart = __le16_to_cpu(fw_data[2]);
+
/* Load RISC code. */
- risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
- risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
- risc_code_size = *ql1280_board_tbl[ha->devnum].fwlen;
+ risc_address = ha->fwstart;
+ fw_data = (const __le16 *)&fw->data[4];
+ risc_code_size = (fw->size - 6) / 2;
dprintk(1, "%s: DMA RISC code (%i) words\n",
__func__, risc_code_size);
@@ -1708,10 +1739,9 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
dprintk(2, "qla1280_setup_chip: loading risc @ =(0x%p),"
"%d,%d(0x%x)\n",
- risc_code_address, cnt, num, risc_address);
+ fw_data, cnt, num, risc_address);
for(i = 0; i < cnt; i++)
- ((__le16 *)ha->request_ring)[i] =
- cpu_to_le16(risc_code_address[i]);
+ ((__le16 *)ha->request_ring)[i] = fw_data[i];
mb[0] = MBC_LOAD_RAM;
mb[1] = risc_address;
@@ -1763,7 +1793,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
#endif
risc_address += cnt;
risc_code_size = risc_code_size - cnt;
- risc_code_address = risc_code_address + cnt;
+ fw_data = fw_data + cnt;
num++;
}
@@ -1771,6 +1801,7 @@ qla1280_load_firmware_dma(struct scsi_qla_host *ha)
#if DUMP_IT_BACK
pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
#endif
+ release_firmware(fw);
return err;
}
@@ -1786,7 +1817,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
/* Verify checksum of loaded RISC code. */
mb[0] = MBC_VERIFY_CHECKSUM;
/* mb[1] = ql12_risc_code_addr01; */
- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+ mb[1] = ha->fwstart;
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, mb);
if (err) {
printk(KERN_ERR "scsi(%li): RISC checksum failed.\n", ha->host_no);
@@ -1796,7 +1827,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha)
/* Start firmware execution. */
dprintk(1, "%s: start firmware running.\n", __func__);
mb[0] = MBC_EXECUTE_FIRMWARE;
- mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+ mb[1] = ha->fwstart;
err = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
if (err) {
printk(KERN_ERR "scsi(%li): Failed to start firmware\n",
@@ -4450,6 +4481,9 @@ module_exit(qla1280_exit);
MODULE_AUTHOR("Qlogic & Jes Sorensen");
MODULE_DESCRIPTION("Qlogic ISP SCSI (qla1x80/qla1x160) driver");
MODULE_LICENSE("GPL");
+MODULE_FIRMWARE("qlogic/1040.bin");
+MODULE_FIRMWARE("qlogic/1280.bin");
+MODULE_FIRMWARE("qlogic/12160.bin");
MODULE_VERSION(QLA1280_VERSION);
/*
diff --git a/drivers/scsi/qla1280.h b/drivers/scsi/qla1280.h
index ff2c363ead2..d7c44b8d2b4 100644
--- a/drivers/scsi/qla1280.h
+++ b/drivers/scsi/qla1280.h
@@ -1069,6 +1069,12 @@ struct scsi_qla_host {
struct nvram nvram;
int nvram_valid;
+
+ /* Firmware Info */
+ unsigned short fwstart; /* start address for F/W */
+ unsigned char fwver1; /* F/W version first char */
+ unsigned char fwver2; /* F/W version second char */
+ unsigned char fwver3; /* F/W version third char */
};
#endif /* _QLA1280_H */
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index ee9d4015243..b09993a0657 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -96,7 +96,9 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN))
return 0;
- /* Read NVRAM data from cache. */
+ if (IS_NOCACHE_VPD_TYPE(ha))
+ ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_nvram << 2,
+ ha->nvram_size);
return memory_read_from_buffer(buf, count, &off, ha->nvram,
ha->nvram_size);
}
@@ -111,7 +113,8 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
struct qla_hw_data *ha = vha->hw;
uint16_t cnt;
- if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size)
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->nvram_size ||
+ !ha->isp_ops->write_nvram)
return 0;
/* Checksum NVRAM. */
@@ -137,12 +140,21 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj,
*iter = chksum;
}
+ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "HBA not online, failing NVRAM update.\n");
+ return -EAGAIN;
+ }
+
/* Write NVRAM. */
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->nvram_base, count);
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->nvram, ha->nvram_base,
count);
+ /* NVRAM settings take effect immediately. */
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+ qla2x00_wait_for_chip_reset(vha);
return (count);
}
@@ -330,6 +342,12 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj,
if (ha->optrom_state != QLA_SWRITING)
break;
+ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "HBA not online, failing flash update.\n");
+ return -EAGAIN;
+ }
+
DEBUG2(qla_printk(KERN_INFO, ha,
"Writing flash region -- 0x%x/0x%x.\n",
ha->optrom_region_start, ha->optrom_region_size));
@@ -364,7 +382,9 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj,
if (!capable(CAP_SYS_ADMIN))
return 0;
- /* Read NVRAM data from cache. */
+ if (IS_NOCACHE_VPD_TYPE(ha))
+ ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
+ ha->vpd_size);
return memory_read_from_buffer(buf, count, &off, ha->vpd, ha->vpd_size);
}
@@ -376,14 +396,35 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj,
struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
struct device, kobj)));
struct qla_hw_data *ha = vha->hw;
+ uint8_t *tmp_data;
- if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size)
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count != ha->vpd_size ||
+ !ha->isp_ops->write_nvram)
return 0;
+ if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "HBA not online, failing VPD update.\n");
+ return -EAGAIN;
+ }
+
/* Write NVRAM. */
ha->isp_ops->write_nvram(vha, (uint8_t *)buf, ha->vpd_base, count);
ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd, ha->vpd_base, count);
+ /* Update flash version information for 4Gb & above. */
+ if (!IS_FWI2_CAPABLE(ha))
+ goto done;
+
+ tmp_data = vmalloc(256);
+ if (!tmp_data) {
+ qla_printk(KERN_WARNING, ha,
+ "Unable to allocate memory for VPD information update.\n");
+ goto done;
+ }
+ ha->isp_ops->get_flash_version(vha, tmp_data);
+ vfree(tmp_data);
+done:
return count;
}
@@ -458,6 +499,199 @@ static struct bin_attribute sysfs_sfp_attr = {
.read = qla2x00_sysfs_read_sfp,
};
+static ssize_t
+qla2x00_sysfs_write_reset(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+ int type;
+
+ if (off != 0)
+ return 0;
+
+ type = simple_strtol(buf, NULL, 10);
+ switch (type) {
+ case 0x2025c:
+ qla_printk(KERN_INFO, ha,
+ "Issuing ISP reset on (%ld).\n", vha->host_no);
+
+ scsi_block_requests(vha->host);
+ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ qla2xxx_wake_dpc(vha);
+ qla2x00_wait_for_chip_reset(vha);
+ scsi_unblock_requests(vha->host);
+ break;
+ case 0x2025d:
+ if (!IS_QLA81XX(ha))
+ break;
+
+ qla_printk(KERN_INFO, ha,
+ "Issuing MPI reset on (%ld).\n", vha->host_no);
+
+ /* Make sure FC side is not in reset */
+ qla2x00_wait_for_hba_online(vha);
+
+ /* Issue MPI reset */
+ scsi_block_requests(vha->host);
+ if (qla81xx_restart_mpi_firmware(vha) != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, ha,
+ "MPI reset failed on (%ld).\n", vha->host_no);
+ scsi_unblock_requests(vha->host);
+ break;
+ }
+ return count;
+}
+
+static struct bin_attribute sysfs_reset_attr = {
+ .attr = {
+ .name = "reset",
+ .mode = S_IWUSR,
+ },
+ .size = 0,
+ .write = qla2x00_sysfs_write_reset,
+};
+
+static ssize_t
+qla2x00_sysfs_write_edc(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t dev, adr, opt, len;
+ int rval;
+
+ ha->edc_data_len = 0;
+
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
+ return 0;
+
+ if (!ha->edc_data) {
+ ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->edc_data_dma);
+ if (!ha->edc_data) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to allocate memory for EDC write.\n"));
+ return 0;
+ }
+ }
+
+ dev = le16_to_cpup((void *)&buf[0]);
+ adr = le16_to_cpup((void *)&buf[2]);
+ opt = le16_to_cpup((void *)&buf[4]);
+ len = le16_to_cpup((void *)&buf[6]);
+
+ if (!(opt & BIT_0))
+ if (len == 0 || len > DMA_POOL_SIZE || len > count - 8)
+ return -EINVAL;
+
+ memcpy(ha->edc_data, &buf[8], len);
+
+ rval = qla2x00_write_edc(vha, dev, adr, ha->edc_data_dma,
+ ha->edc_data, len, opt);
+ if (rval != QLA_SUCCESS) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to write EDC (%x) %02x:%02x:%04x:%02x:%02x.\n",
+ rval, dev, adr, opt, len, *buf));
+ return 0;
+ }
+
+ return count;
+}
+
+static struct bin_attribute sysfs_edc_attr = {
+ .attr = {
+ .name = "edc",
+ .mode = S_IWUSR,
+ },
+ .size = 0,
+ .write = qla2x00_sysfs_write_edc,
+};
+
+static ssize_t
+qla2x00_sysfs_write_edc_status(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+ uint16_t dev, adr, opt, len;
+ int rval;
+
+ ha->edc_data_len = 0;
+
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count < 8)
+ return 0;
+
+ if (!ha->edc_data) {
+ ha->edc_data = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->edc_data_dma);
+ if (!ha->edc_data) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to allocate memory for EDC status.\n"));
+ return 0;
+ }
+ }
+
+ dev = le16_to_cpup((void *)&buf[0]);
+ adr = le16_to_cpup((void *)&buf[2]);
+ opt = le16_to_cpup((void *)&buf[4]);
+ len = le16_to_cpup((void *)&buf[6]);
+
+ if (!(opt & BIT_0))
+ if (len == 0 || len > DMA_POOL_SIZE)
+ return -EINVAL;
+
+ memset(ha->edc_data, 0, len);
+ rval = qla2x00_read_edc(vha, dev, adr, ha->edc_data_dma,
+ ha->edc_data, len, opt);
+ if (rval != QLA_SUCCESS) {
+ DEBUG2(qla_printk(KERN_INFO, ha,
+ "Unable to write EDC status (%x) %02x:%02x:%04x:%02x.\n",
+ rval, dev, adr, opt, len));
+ return 0;
+ }
+
+ ha->edc_data_len = len;
+
+ return count;
+}
+
+static ssize_t
+qla2x00_sysfs_read_edc_status(struct kobject *kobj,
+ struct bin_attribute *bin_attr,
+ char *buf, loff_t off, size_t count)
+{
+ struct scsi_qla_host *vha = shost_priv(dev_to_shost(container_of(kobj,
+ struct device, kobj)));
+ struct qla_hw_data *ha = vha->hw;
+
+ if (!capable(CAP_SYS_ADMIN) || off != 0 || count == 0)
+ return 0;
+
+ if (!ha->edc_data || ha->edc_data_len == 0 || ha->edc_data_len > count)
+ return -EINVAL;
+
+ memcpy(buf, ha->edc_data, ha->edc_data_len);
+
+ return ha->edc_data_len;
+}
+
+static struct bin_attribute sysfs_edc_status_attr = {
+ .attr = {
+ .name = "edc_status",
+ .mode = S_IRUSR | S_IWUSR,
+ },
+ .size = 0,
+ .write = qla2x00_sysfs_write_edc_status,
+ .read = qla2x00_sysfs_read_edc_status,
+};
+
static struct sysfs_entry {
char *name;
struct bin_attribute *attr;
@@ -469,6 +703,9 @@ static struct sysfs_entry {
{ "optrom_ctl", &sysfs_optrom_ctl_attr, },
{ "vpd", &sysfs_vpd_attr, 1 },
{ "sfp", &sysfs_sfp_attr, 1 },
+ { "reset", &sysfs_reset_attr, },
+ { "edc", &sysfs_edc_attr, 2 },
+ { "edc_status", &sysfs_edc_status_attr, 2 },
{ NULL },
};
@@ -482,6 +719,8 @@ qla2x00_alloc_sysfs_attr(scsi_qla_host_t *vha)
for (iter = bin_file_entries; iter->name; iter++) {
if (iter->is4GBp_only && !IS_FWI2_CAPABLE(vha->hw))
continue;
+ if (iter->is4GBp_only == 2 && !IS_QLA25XX(vha->hw))
+ continue;
ret = sysfs_create_bin_file(&host->shost_gendev.kobj,
iter->attr);
@@ -502,6 +741,8 @@ qla2x00_free_sysfs_attr(scsi_qla_host_t *vha)
for (iter = bin_file_entries; iter->name; iter++) {
if (iter->is4GBp_only && !IS_FWI2_CAPABLE(ha))
continue;
+ if (iter->is4GBp_only == 2 && !IS_QLA25XX(ha))
+ continue;
sysfs_remove_bin_file(&host->shost_gendev.kobj,
iter->attr);
@@ -818,9 +1059,33 @@ qla2x00_mpi_version_show(struct device *dev, struct device_attribute *attr,
if (!IS_QLA81XX(ha))
return snprintf(buf, PAGE_SIZE, "\n");
- return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x (%x)\n",
+ return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d (%x)\n",
ha->mpi_version[0], ha->mpi_version[1], ha->mpi_version[2],
- ha->mpi_version[3], ha->mpi_capabilities);
+ ha->mpi_capabilities);
+}
+
+static ssize_t
+qla2x00_phy_version_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ struct qla_hw_data *ha = vha->hw;
+
+ if (!IS_QLA81XX(ha))
+ return snprintf(buf, PAGE_SIZE, "\n");
+
+ return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d\n",
+ ha->phy_version[0], ha->phy_version[1], ha->phy_version[2]);
+}
+
+static ssize_t
+qla2x00_flash_block_size_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
+ struct qla_hw_data *ha = vha->hw;
+
+ return snprintf(buf, PAGE_SIZE, "0x%x\n", ha->fdt_block_size);
}
static DEVICE_ATTR(driver_version, S_IRUGO, qla2x00_drvr_version_show, NULL);
@@ -848,6 +1113,9 @@ static DEVICE_ATTR(optrom_fw_version, S_IRUGO, qla2x00_optrom_fw_version_show,
static DEVICE_ATTR(total_isp_aborts, S_IRUGO, qla2x00_total_isp_aborts_show,
NULL);
static DEVICE_ATTR(mpi_version, S_IRUGO, qla2x00_mpi_version_show, NULL);
+static DEVICE_ATTR(phy_version, S_IRUGO, qla2x00_phy_version_show, NULL);
+static DEVICE_ATTR(flash_block_size, S_IRUGO, qla2x00_flash_block_size_show,
+ NULL);
struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_driver_version,
@@ -868,6 +1136,8 @@ struct device_attribute *qla2x00_host_attrs[] = {
&dev_attr_optrom_fw_version,
&dev_attr_total_isp_aborts,
&dev_attr_mpi_version,
+ &dev_attr_phy_version,
+ &dev_attr_flash_block_size,
NULL,
};
@@ -1012,7 +1282,10 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
if (!fcport)
return;
- qla2x00_abort_fcport_cmds(fcport);
+ if (unlikely(pci_channel_offline(fcport->vha->hw->pdev)))
+ qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
+ else
+ qla2x00_abort_fcport_cmds(fcport);
/*
* Transport has effectively 'deleted' the rport, clear
@@ -1032,16 +1305,18 @@ qla2x00_terminate_rport_io(struct fc_rport *rport)
if (!fcport)
return;
+ if (unlikely(pci_channel_offline(fcport->vha->hw->pdev))) {
+ qla2x00_abort_all_cmds(fcport->vha, DID_NO_CONNECT << 16);
+ return;
+ }
/*
* At this point all fcport's software-states are cleared. Perform any
* final cleanup of firmware resources (PCBs and XCBs).
*/
- if (fcport->loop_id != FC_NO_LOOP_ID) {
+ if (fcport->loop_id != FC_NO_LOOP_ID)
fcport->vha->hw->isp_ops->fabric_logout(fcport->vha,
fcport->loop_id, fcport->d_id.b.domain,
fcport->d_id.b.area, fcport->d_id.b.al_pa);
- fcport->loop_id = FC_NO_LOOP_ID;
- }
qla2x00_abort_fcport_cmds(fcport);
}
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index e0c5bb54b25..714ee67567e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -176,8 +176,7 @@
/* ISP request and response entry counts (37-65535) */
#define REQUEST_ENTRY_CNT_2100 128 /* Number of request entries. */
#define REQUEST_ENTRY_CNT_2200 2048 /* Number of request entries. */
-#define REQUEST_ENTRY_CNT_2XXX_EXT_MEM 4096 /* Number of request entries. */
-#define REQUEST_ENTRY_CNT_24XX 4096 /* Number of request entries. */
+#define REQUEST_ENTRY_CNT_24XX 2048 /* Number of request entries. */
#define RESPONSE_ENTRY_CNT_2100 64 /* Number of response entries.*/
#define RESPONSE_ENTRY_CNT_2300 512 /* Number of response entries.*/
@@ -201,20 +200,7 @@ typedef struct srb {
/*
* SRB flag definitions
*/
-#define SRB_TIMEOUT BIT_0 /* Command timed out */
-#define SRB_DMA_VALID BIT_1 /* Command sent to ISP */
-#define SRB_WATCHDOG BIT_2 /* Command on watchdog list */
-#define SRB_ABORT_PENDING BIT_3 /* Command abort sent to device */
-
-#define SRB_ABORTED BIT_4 /* Command aborted command already */
-#define SRB_RETRY BIT_5 /* Command needs retrying */
-#define SRB_GOT_SENSE BIT_6 /* Command has sense data */
-#define SRB_FAILOVER BIT_7 /* Command in failover state */
-
-#define SRB_BUSY BIT_8 /* Command is in busy retry state */
-#define SRB_FO_CANCEL BIT_9 /* Command don't need to do failover */
-#define SRB_IOCTL BIT_10 /* IOCTL command. */
-#define SRB_TAPE BIT_11 /* FCP2 (Tape) command. */
+#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */
/*
* ISP I/O Register Set structure definitions.
@@ -372,10 +358,10 @@ struct device_reg_2xxx {
};
struct device_reg_25xxmq {
- volatile uint32_t req_q_in;
- volatile uint32_t req_q_out;
- volatile uint32_t rsp_q_in;
- volatile uint32_t rsp_q_out;
+ uint32_t req_q_in;
+ uint32_t req_q_out;
+ uint32_t rsp_q_in;
+ uint32_t rsp_q_out;
};
typedef union {
@@ -620,6 +606,7 @@ typedef struct {
#define MBC_GET_TIMEOUT_PARAMS 0x22 /* Get FW timeouts. */
#define MBC_TRACE_CONTROL 0x27 /* Trace control command. */
#define MBC_GEN_SYSTEM_ERROR 0x2a /* Generate System Error. */
+#define MBC_WRITE_SFP 0x30 /* Write SFP Data. */
#define MBC_READ_SFP 0x31 /* Read SFP Data. */
#define MBC_SET_TIMEOUT_PARAMS 0x32 /* Set FW timeouts. */
#define MBC_MID_INITIALIZE_FIRMWARE 0x48 /* MID Initialize firmware. */
@@ -1570,39 +1557,13 @@ typedef struct fc_port {
#define FCS_DEVICE_DEAD 2
#define FCS_DEVICE_LOST 3
#define FCS_ONLINE 4
-#define FCS_NOT_SUPPORTED 5
-#define FCS_FAILOVER 6
-#define FCS_FAILOVER_FAILED 7
/*
* FC port flags.
*/
#define FCF_FABRIC_DEVICE BIT_0
#define FCF_LOGIN_NEEDED BIT_1
-#define FCF_FO_MASKED BIT_2
-#define FCF_FAILOVER_NEEDED BIT_3
-#define FCF_RESET_NEEDED BIT_4
-#define FCF_PERSISTENT_BOUND BIT_5
-#define FCF_TAPE_PRESENT BIT_6
-#define FCF_FARP_DONE BIT_7
-#define FCF_FARP_FAILED BIT_8
-#define FCF_FARP_REPLY_NEEDED BIT_9
-#define FCF_AUTH_REQ BIT_10
-#define FCF_SEND_AUTH_REQ BIT_11
-#define FCF_RECEIVE_AUTH_REQ BIT_12
-#define FCF_AUTH_SUCCESS BIT_13
-#define FCF_RLC_SUPPORT BIT_14
-#define FCF_CONFIG BIT_15 /* Needed? */
-#define FCF_RESCAN_NEEDED BIT_16
-#define FCF_XP_DEVICE BIT_17
-#define FCF_MSA_DEVICE BIT_18
-#define FCF_EVA_DEVICE BIT_19
-#define FCF_MSA_PORT_ACTIVE BIT_20
-#define FCF_FAILBACK_DISABLE BIT_21
-#define FCF_FAILOVER_DISABLE BIT_22
-#define FCF_DSXXX_DEVICE BIT_23
-#define FCF_AA_EVA_DEVICE BIT_24
-#define FCF_AA_MSA_DEVICE BIT_25
+#define FCF_TAPE_PRESENT BIT_2
/* No loop ID flag. */
#define FC_NO_LOOP_ID 0x1000
@@ -2102,9 +2063,6 @@ struct isp_operations {
int (*get_flash_version) (struct scsi_qla_host *, void *);
int (*start_scsi) (srb_t *);
- void (*wrt_req_reg) (struct qla_hw_data *, uint16_t, uint16_t);
- void (*wrt_rsp_reg) (struct qla_hw_data *, uint16_t, uint16_t);
- uint16_t (*rd_req_reg) (struct qla_hw_data *, uint16_t);
};
/* MSI-X Support *************************************************************/
@@ -2200,6 +2158,8 @@ struct rsp_que {
dma_addr_t dma;
response_t *ring;
response_t *ring_ptr;
+ uint32_t __iomem *rsp_q_in; /* FWI2-capable only. */
+ uint32_t __iomem *rsp_q_out;
uint16_t ring_index;
uint16_t out_ptr;
uint16_t length;
@@ -2217,6 +2177,8 @@ struct req_que {
dma_addr_t dma;
request_t *ring;
request_t *ring_ptr;
+ uint32_t __iomem *req_q_in; /* FWI2-capable only. */
+ uint32_t __iomem *req_q_out;
uint16_t ring_index;
uint16_t in_ptr;
uint16_t cnt;
@@ -2256,10 +2218,10 @@ struct qla_hw_data {
uint32_t msix_enabled :1;
uint32_t disable_serdes :1;
uint32_t gpsc_supported :1;
- uint32_t vsan_enabled :1;
uint32_t npiv_supported :1;
uint32_t fce_enabled :1;
- uint32_t hw_event_marker_found:1;
+ uint32_t fac_supported :1;
+ uint32_t chip_reset_done :1;
} flags;
/* This spinlock is used to protect "io transactions", you must
@@ -2277,7 +2239,7 @@ struct qla_hw_data {
#define MIN_IOBASE_LEN 0x100
/* Multi queue data structs */
- device_reg_t *mqiobase;
+ device_reg_t __iomem *mqiobase;
uint16_t msix_count;
uint8_t mqenable;
struct req_que **req_q_map;
@@ -2300,7 +2262,6 @@ struct qla_hw_data {
uint16_t max_loop_id;
uint16_t fb_rev;
- uint16_t max_public_loop_ids;
uint16_t min_external_loopid; /* First external loop Id */
#define PORT_SPEED_UNKNOWN 0xFFFF
@@ -2381,6 +2342,8 @@ struct qla_hw_data {
IS_QLA25XX(ha) || IS_QLA81XX(ha))
#define IS_NOPOLLING_TYPE(ha) ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && \
(ha)->flags.msix_enabled)
+#define IS_FAC_REQUIRED(ha) (IS_QLA81XX(ha))
+#define IS_NOCACHE_VPD_TYPE(ha) (IS_QLA81XX(ha))
#define IS_IIDMA_CAPABLE(ha) ((ha)->device_type & DT_IIDMA)
#define IS_FWI2_CAPABLE(ha) ((ha)->device_type & DT_FWI2)
@@ -2425,6 +2388,10 @@ struct qla_hw_data {
void *sfp_data;
dma_addr_t sfp_data_dma;
+ uint8_t *edc_data;
+ dma_addr_t edc_data_dma;
+ uint16_t edc_data_len;
+
struct task_struct *dpc_thread;
uint8_t dpc_active; /* DPC routine is active */
@@ -2439,6 +2406,8 @@ struct qla_hw_data {
dma_addr_t init_cb_dma;
init_cb_t *init_cb;
int init_cb_size;
+ dma_addr_t ex_init_cb_dma;
+ struct ex_init_cb_81xx *ex_init_cb;
/* These are used by mailbox operations. */
volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
@@ -2453,15 +2422,6 @@ struct qla_hw_data {
struct completion mbx_cmd_comp; /* Serialize mbx access */
struct completion mbx_intr_comp; /* Used for completion notification */
- uint32_t mbx_flags;
-#define MBX_IN_PROGRESS BIT_0
-#define MBX_BUSY BIT_1 /* Got the Access */
-#define MBX_SLEEPING_ON_SEM BIT_2
-#define MBX_POLLING_FOR_COMP BIT_3
-#define MBX_COMPLETED BIT_4
-#define MBX_TIMEDOUT BIT_5
-#define MBX_ACCESS_TIMEDOUT BIT_6
-
/* Basic firmware related information. */
uint16_t fw_major_version;
uint16_t fw_minor_version;
@@ -2473,13 +2433,15 @@ struct qla_hw_data {
#define RISC_START_ADDRESS_2100 0x1000
#define RISC_START_ADDRESS_2300 0x800
#define RISC_START_ADDRESS_2400 0x100000
+ uint16_t fw_xcb_count;
uint16_t fw_options[16]; /* slots: 1,2,3,10,11 */
uint8_t fw_seriallink_options[4];
uint16_t fw_seriallink_options24[4];
- uint8_t mpi_version[4];
+ uint8_t mpi_version[3];
uint32_t mpi_capabilities;
+ uint8_t phy_version[3];
/* Firmware dump information. */
struct qla2xxx_fw_dump *fw_dump;
@@ -2545,6 +2507,8 @@ struct qla_hw_data {
uint32_t flt_region_boot;
uint32_t flt_region_fw;
uint32_t flt_region_vpd_nvram;
+ uint32_t flt_region_vpd;
+ uint32_t flt_region_nvram;
uint32_t flt_region_npiv_conf;
/* Needed for BEACON */
@@ -2613,36 +2577,19 @@ typedef struct scsi_qla_host {
#define LOOP_RESYNC_ACTIVE 5
#define LOCAL_LOOP_UPDATE 6 /* Perform a local loop update. */
#define RSCN_UPDATE 7 /* Perform an RSCN update. */
-#define MAILBOX_RETRY 8
-#define ISP_RESET_NEEDED 9 /* Initiate a ISP reset. */
-#define FAILOVER_EVENT_NEEDED 10
-#define FAILOVER_EVENT 11
-#define FAILOVER_NEEDED 12
-#define SCSI_RESTART_NEEDED 13 /* Processes SCSI retry queue. */
-#define PORT_RESTART_NEEDED 14 /* Processes Retry queue. */
-#define RESTART_QUEUES_NEEDED 15 /* Restarts the Lun queue. */
-#define ABORT_QUEUES_NEEDED 16
-#define RELOGIN_NEEDED 17
-#define LOGIN_RETRY_NEEDED 18 /* Initiate required fabric logins. */
-#define REGISTER_FC4_NEEDED 19 /* SNS FC4 registration required. */
-#define ISP_ABORT_RETRY 20 /* ISP aborted. */
-#define FCPORT_RESCAN_NEEDED 21 /* IO descriptor processing needed */
-#define IODESC_PROCESS_NEEDED 22 /* IO descriptor processing needed */
-#define IOCTL_ERROR_RECOVERY 23
-#define LOOP_RESET_NEEDED 24
-#define BEACON_BLINK_NEEDED 25
-#define REGISTER_FDMI_NEEDED 26
-#define FCPORT_UPDATE_NEEDED 27
-#define VP_DPC_NEEDED 28 /* wake up for VP dpc handling */
-#define UNLOADING 29
-#define NPIV_CONFIG_NEEDED 30
+#define RELOGIN_NEEDED 8
+#define REGISTER_FC4_NEEDED 9 /* SNS FC4 registration required. */
+#define ISP_ABORT_RETRY 10 /* ISP aborted. */
+#define BEACON_BLINK_NEEDED 11
+#define REGISTER_FDMI_NEEDED 12
+#define FCPORT_UPDATE_NEEDED 13
+#define VP_DPC_NEEDED 14 /* wake up for VP dpc handling */
+#define UNLOADING 15
+#define NPIV_CONFIG_NEEDED 16
uint32_t device_flags;
-#define DFLG_LOCAL_DEVICES BIT_0
-#define DFLG_RETRY_LOCAL_DEVICES BIT_1
-#define DFLG_FABRIC_DEVICES BIT_2
-#define SWITCH_FOUND BIT_3
-#define DFLG_NO_CABLE BIT_4
+#define SWITCH_FOUND BIT_0
+#define DFLG_NO_CABLE BIT_1
srb_t *status_srb; /* Status continuation entry. */
@@ -2755,10 +2702,5 @@ typedef struct scsi_qla_host {
#include "qla_inline.h"
#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr)
-#define CMD_COMPL_STATUS(Cmnd) ((Cmnd)->SCp.this_residual)
-#define CMD_RESID_LEN(Cmnd) ((Cmnd)->SCp.buffers_residual)
-#define CMD_SCSI_STATUS(Cmnd) ((Cmnd)->SCp.Status)
-#define CMD_ACTUAL_SNSLEN(Cmnd) ((Cmnd)->SCp.Message)
-#define CMD_ENTRY_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in)
#endif
diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c
index c66036da7d2..3a9a6ca4226 100644
--- a/drivers/scsi/qla2xxx/qla_dfs.c
+++ b/drivers/scsi/qla2xxx/qla_dfs.c
@@ -71,7 +71,7 @@ qla2x00_dfs_fce_open(struct inode *inode, struct file *file)
mutex_unlock(&ha->fce_mutex);
out:
- return single_open(file, qla2x00_dfs_fce_show, ha);
+ return single_open(file, qla2x00_dfs_fce_show, vha);
}
static int
@@ -145,7 +145,7 @@ create_dir:
atomic_inc(&qla2x00_dfs_root_count);
create_nodes:
- ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, ha,
+ ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha,
&dfs_fce_ops);
if (!ha->dfs_fce) {
qla_printk(KERN_NOTICE, ha,
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
index ffff4255408..96ccb9642ba 100644
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1403,6 +1403,21 @@ struct access_chip_rsp_84xx {
#define MBA_IDC_TIME_EXT 0x8102
#define MBC_IDC_ACK 0x101
+#define MBC_RESTART_MPI_FW 0x3d
+#define MBC_FLASH_ACCESS_CTRL 0x3e /* Control flash access. */
+
+/* Flash access control option field bit definitions */
+#define FAC_OPT_FORCE_SEMAPHORE BIT_15
+#define FAC_OPT_REQUESTOR_ID BIT_14
+#define FAC_OPT_CMD_SUBCODE 0xff
+
+/* Flash access control command subcodes */
+#define FAC_OPT_CMD_WRITE_PROTECT 0x00
+#define FAC_OPT_CMD_WRITE_ENABLE 0x01
+#define FAC_OPT_CMD_ERASE_SECTOR 0x02
+#define FAC_OPT_CMD_LOCK_SEMAPHORE 0x03
+#define FAC_OPT_CMD_UNLOCK_SEMAPHORE 0x04
+#define FAC_OPT_CMD_GET_SECTOR_SIZE 0x05
struct nvram_81xx {
/* NVRAM header. */
@@ -1440,7 +1455,17 @@ struct nvram_81xx {
uint16_t reserved_6[24];
/* Offset 128. */
- uint16_t reserved_7[64];
+ uint16_t ex_version;
+ uint8_t prio_fcf_matching_flags;
+ uint8_t reserved_6_1[3];
+ uint16_t pri_fcf_vlan_id;
+ uint8_t pri_fcf_fabric_name[8];
+ uint16_t reserved_6_2[7];
+ uint8_t spma_mac_addr[6];
+ uint16_t reserved_6_3[14];
+
+ /* Offset 192. */
+ uint16_t reserved_7[32];
/*
* BIT 0 = Enable spinup delay
@@ -1664,6 +1689,17 @@ struct mid_init_cb_81xx {
struct mid_conf_entry_24xx entries[MAX_MULTI_ID_FABRIC];
};
+struct ex_init_cb_81xx {
+ uint16_t ex_version;
+ uint8_t prio_fcf_matching_flags;
+ uint8_t reserved_1[3];
+ uint16_t pri_fcf_vlan_id;
+ uint8_t pri_fcf_fabric_name[8];
+ uint16_t reserved_2[7];
+ uint8_t spma_mac_addr[6];
+ uint16_t reserved_3[14];
+};
+
#define FARX_ACCESS_FLASH_CONF_81XX 0x7FFD0000
#define FARX_ACCESS_FLASH_DATA_81XX 0x7F800000
@@ -1672,6 +1708,10 @@ struct mid_init_cb_81xx {
#define FA_RISC_CODE_ADDR_81 0xA0000
#define FA_FW_AREA_ADDR_81 0xC0000
#define FA_VPD_NVRAM_ADDR_81 0xD0000
+#define FA_VPD0_ADDR_81 0xD0000
+#define FA_VPD1_ADDR_81 0xD0400
+#define FA_NVRAM0_ADDR_81 0xD0080
+#define FA_NVRAM1_ADDR_81 0xD0480
#define FA_FEATURE_ADDR_81 0xD4000
#define FA_FLASH_DESCR_ADDR_81 0xD8000
#define FA_FLASH_LAYOUT_ADDR_81 0xD8400
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 6de283f8f11..528913f6bed 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -73,6 +73,7 @@ extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
fc_host_event_code, u32);
extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
+extern int qla81xx_restart_mpi_firmware(scsi_qla_host_t *);
extern void qla2x00_abort_fcport_cmds(fc_port_t *);
extern struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *,
@@ -82,7 +83,7 @@ extern void qla2x00_relogin(struct scsi_qla_host *);
/*
* Global Functions in qla_mid.c source file.
*/
-extern struct scsi_host_template qla24xx_driver_template;
+extern struct scsi_host_template qla2xxx_driver_template;
extern struct scsi_transport_template *qla2xxx_transport_vport_template;
extern void qla2x00_timer(scsi_qla_host_t *);
extern void qla2x00_start_timer(scsi_qla_host_t *, void *, unsigned long);
@@ -110,6 +111,7 @@ extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
extern int qla2x00_wait_for_hba_online(scsi_qla_host_t *);
+extern int qla2x00_wait_for_chip_reset(scsi_qla_host_t *);
extern void qla2xxx_wake_dpc(struct scsi_qla_host *);
extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
@@ -144,8 +146,8 @@ extern int
qla2x00_execute_fw(scsi_qla_host_t *, uint32_t);
extern void
-qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *,
- uint16_t *, uint16_t *, uint16_t *, uint32_t *, uint8_t *, uint32_t *);
+qla2x00_get_fw_version(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *,
+ uint16_t *, uint32_t *, uint8_t *, uint32_t *, uint8_t *);
extern int
qla2x00_get_fw_options(scsi_qla_host_t *, uint16_t *);
@@ -263,12 +265,29 @@ extern int
qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
extern int
+qla2x00_read_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
+ uint8_t *, uint16_t, uint16_t);
+
+extern int
+qla2x00_write_edc(scsi_qla_host_t *, uint16_t, uint16_t, dma_addr_t,
+ uint8_t *, uint16_t, uint16_t);
+
+extern int
qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
extern int qla81xx_idc_ack(scsi_qla_host_t *, uint16_t *);
+extern int
+qla81xx_fac_get_sector_size(scsi_qla_host_t *, uint32_t *);
+
+extern int
+qla81xx_fac_do_write_enable(scsi_qla_host_t *, int);
+
+extern int
+qla81xx_fac_erase_sector(scsi_qla_host_t *, uint32_t, uint32_t);
+
/*
* Global Function Prototypes in qla_isr.c source file.
*/
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 87f9abc7146..bd7dd84c064 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -20,7 +20,6 @@
* QLogic ISP2x00 Hardware Support Function Prototypes.
*/
static int qla2x00_isp_firmware(scsi_qla_host_t *);
-static void qla2x00_resize_request_q(scsi_qla_host_t *);
static int qla2x00_setup_chip(scsi_qla_host_t *);
static int qla2x00_init_rings(scsi_qla_host_t *);
static int qla2x00_fw_ready(scsi_qla_host_t *);
@@ -61,8 +60,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
int rval;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
+
/* Clear adapter flags. */
vha->flags.online = 0;
+ ha->flags.chip_reset_done = 0;
vha->flags.reset_active = 0;
atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME);
atomic_set(&vha->loop_state, LOOP_DOWN);
@@ -70,7 +71,6 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
vha->dpc_flags = 0;
vha->flags.management_server_logged_in = 0;
vha->marker_needed = 0;
- ha->mbx_flags = 0;
ha->isp_abort_cnt = 0;
ha->beacon_blink_led = 0;
set_bit(REGISTER_FDMI_NEEDED, &vha->dpc_flags);
@@ -131,6 +131,7 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
}
}
rval = qla2x00_init_rings(vha);
+ ha->flags.chip_reset_done = 1;
return (rval);
}
@@ -512,7 +513,6 @@ qla2x00_reset_chip(scsi_qla_host_t *vha)
static inline void
qla24xx_reset_risc(scsi_qla_host_t *vha)
{
- int hw_evt = 0;
unsigned long flags = 0;
struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
@@ -542,8 +542,6 @@ qla24xx_reset_risc(scsi_qla_host_t *vha)
d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
barrier();
}
- if (cnt == 0)
- hw_evt = 1;
/* Wait for soft-reset to complete. */
d2 = RD_REG_DWORD(&reg->ctrl_status);
@@ -816,7 +814,7 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
qla_printk(KERN_INFO, ha, "Allocated (%d KB) for FCE...\n",
FCE_SIZE / 1024);
- fce_size = sizeof(struct qla2xxx_fce_chain) + EFT_SIZE;
+ fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
ha->flags.fce_enabled = 1;
ha->fce_dma = tc_dma;
ha->fce = tc;
@@ -894,62 +892,6 @@ cont_alloc:
}
/**
- * qla2x00_resize_request_q() - Resize request queue given available ISP memory.
- * @ha: HA context
- *
- * Returns 0 on success.
- */
-static void
-qla2x00_resize_request_q(scsi_qla_host_t *vha)
-{
- int rval;
- uint16_t fw_iocb_cnt = 0;
- uint16_t request_q_length = REQUEST_ENTRY_CNT_2XXX_EXT_MEM;
- dma_addr_t request_dma;
- request_t *request_ring;
- struct qla_hw_data *ha = vha->hw;
- struct req_que *req = ha->req_q_map[0];
-
- /* Valid only on recent ISPs. */
- if (IS_QLA2100(ha) || IS_QLA2200(ha))
- return;
-
- /* Retrieve IOCB counts available to the firmware. */
- rval = qla2x00_get_resource_cnts(vha, NULL, NULL, NULL, &fw_iocb_cnt,
- &ha->max_npiv_vports);
- if (rval)
- return;
- /* No point in continuing if current settings are sufficient. */
- if (fw_iocb_cnt < 1024)
- return;
- if (req->length >= request_q_length)
- return;
-
- /* Attempt to claim larger area for request queue. */
- request_ring = dma_alloc_coherent(&ha->pdev->dev,
- (request_q_length + 1) * sizeof(request_t), &request_dma,
- GFP_KERNEL);
- if (request_ring == NULL)
- return;
-
- /* Resize successful, report extensions. */
- qla_printk(KERN_INFO, ha, "Extended memory detected (%d KB)...\n",
- (ha->fw_memory_size + 1) / 1024);
- qla_printk(KERN_INFO, ha, "Resizing request queue depth "
- "(%d -> %d)...\n", req->length, request_q_length);
-
- /* Clear old allocations. */
- dma_free_coherent(&ha->pdev->dev,
- (req->length + 1) * sizeof(request_t), req->ring,
- req->dma);
-
- /* Begin using larger queue. */
- req->length = request_q_length;
- req->ring = request_ring;
- req->dma = request_dma;
-}
-
-/**
* qla2x00_setup_chip() - Load and start RISC firmware.
* @ha: HA context
*
@@ -963,6 +905,7 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
struct qla_hw_data *ha = vha->hw;
struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
unsigned long flags;
+ uint16_t fw_major_version;
if (!IS_FWI2_CAPABLE(ha) && !IS_QLA2100(ha) && !IS_QLA2200(ha)) {
/* Disable SRAM, Instruction RAM and GP RAM parity. */
@@ -986,13 +929,15 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
rval = qla2x00_execute_fw(vha, srisc_address);
/* Retrieve firmware information. */
- if (rval == QLA_SUCCESS && ha->fw_major_version == 0) {
+ if (rval == QLA_SUCCESS) {
+ fw_major_version = ha->fw_major_version;
qla2x00_get_fw_version(vha,
&ha->fw_major_version,
&ha->fw_minor_version,
&ha->fw_subminor_version,
&ha->fw_attributes, &ha->fw_memory_size,
- ha->mpi_version, &ha->mpi_capabilities);
+ ha->mpi_version, &ha->mpi_capabilities,
+ ha->phy_version);
ha->flags.npiv_supported = 0;
if (IS_QLA2XXX_MIDTYPE(ha) &&
(ha->fw_attributes & BIT_2)) {
@@ -1003,9 +948,11 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
ha->max_npiv_vports =
MIN_MULTI_ID_FABRIC - 1;
}
- qla2x00_resize_request_q(vha);
+ qla2x00_get_resource_cnts(vha, NULL,
+ &ha->fw_xcb_count, NULL, NULL,
+ &ha->max_npiv_vports);
- if (ql2xallocfwdump)
+ if (!fw_major_version && ql2xallocfwdump)
qla2x00_alloc_fw_dump(vha);
}
} else {
@@ -1028,6 +975,21 @@ qla2x00_setup_chip(scsi_qla_host_t *vha)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
}
+ if (rval == QLA_SUCCESS && IS_FAC_REQUIRED(ha)) {
+ uint32_t size;
+
+ rval = qla81xx_fac_get_sector_size(vha, &size);
+ if (rval == QLA_SUCCESS) {
+ ha->flags.fac_supported = 1;
+ ha->fdt_block_size = size << 2;
+ } else {
+ qla_printk(KERN_ERR, ha,
+ "Unsupported FAC firmware (%d.%02d.%02d).\n",
+ ha->fw_major_version, ha->fw_minor_version,
+ ha->fw_subminor_version);
+ }
+ }
+
if (rval) {
DEBUG2_3(printk("scsi(%ld): Setup chip **** FAILED ****.\n",
vha->host_no));
@@ -1314,8 +1276,11 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
mid_init_cb->count = cpu_to_le16(ha->max_npiv_vports);
}
-
- mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
+ if (IS_FWI2_CAPABLE(ha)) {
+ mid_init_cb->options = __constant_cpu_to_le16(BIT_1);
+ mid_init_cb->init_cb.execution_throttle =
+ cpu_to_le16(ha->fw_xcb_count);
+ }
rval = qla2x00_init_firmware(vha, ha->init_cb_size);
if (rval) {
@@ -1989,7 +1954,6 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags)
fcport->port_type = FCT_UNKNOWN;
fcport->loop_id = FC_NO_LOOP_ID;
atomic_set(&fcport->state, FCS_UNCONFIGURED);
- fcport->flags = FCF_RLC_SUPPORT;
fcport->supported_classes = FC_COS_UNSPECIFIED;
return fcport;
@@ -2171,7 +2135,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
vha->host_no, fcport->loop_id));
atomic_set(&fcport->state, FCS_DEVICE_LOST);
- fcport->flags &= ~FCF_FARP_DONE;
}
}
@@ -2228,8 +2191,7 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
WWN_SIZE))
continue;
- fcport->flags &= ~(FCF_FABRIC_DEVICE |
- FCF_PERSISTENT_BOUND);
+ fcport->flags &= ~FCF_FABRIC_DEVICE;
fcport->loop_id = new_fcport->loop_id;
fcport->port_type = new_fcport->port_type;
fcport->d_id.b24 = new_fcport->d_id.b24;
@@ -2242,7 +2204,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
if (!found) {
/* New device, add to fcports list. */
- new_fcport->flags &= ~FCF_PERSISTENT_BOUND;
if (vha->vp_idx) {
new_fcport->vha = vha;
new_fcport->vp_idx = vha->vp_idx;
@@ -2275,11 +2236,6 @@ cleanup_allocation:
"rval=%x\n", vha->host_no, rval));
}
- if (found_devs) {
- vha->device_flags |= DFLG_LOCAL_DEVICES;
- vha->device_flags &= ~DFLG_RETRY_LOCAL_DEVICES;
- }
-
return (rval);
}
@@ -2765,7 +2721,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
fcport->loop_id = FC_NO_LOOP_ID;
fcport->flags |= (FCF_FABRIC_DEVICE |
FCF_LOGIN_NEEDED);
- fcport->flags &= ~FCF_PERSISTENT_BOUND;
break;
}
@@ -2808,9 +2763,6 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha,
kfree(swl);
kfree(new_fcport);
- if (!list_empty(new_fcports))
- vha->device_flags |= DFLG_FABRIC_DEVICES;
-
return (rval);
}
@@ -2993,7 +2945,6 @@ qla2x00_device_resync(scsi_qla_host_t *vha)
0, 0);
}
}
- fcport->flags &= ~FCF_FARP_DONE;
}
}
return (rval);
@@ -3302,6 +3253,7 @@ qla2x00_abort_isp(scsi_qla_host_t *vha)
if (vha->flags.online) {
vha->flags.online = 0;
+ ha->flags.chip_reset_done = 0;
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
ha->qla_stats.total_isp_aborts++;
@@ -3451,6 +3403,7 @@ qla2x00_restart_isp(scsi_qla_host_t *vha)
if (!status && !(status = qla2x00_init_rings(vha))) {
clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags);
+ ha->flags.chip_reset_done = 1;
/* Initialize the queues in use */
qla25xx_init_queues(ha);
@@ -4338,23 +4291,17 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
/* Determine NVRAM starting address. */
ha->nvram_size = sizeof(struct nvram_81xx);
- ha->nvram_base = FA_NVRAM_FUNC0_ADDR;
ha->vpd_size = FA_NVRAM_VPD_SIZE;
- ha->vpd_base = FA_NVRAM_VPD0_ADDR;
- if (PCI_FUNC(ha->pdev->devfn) & 1) {
- ha->nvram_base = FA_NVRAM_FUNC1_ADDR;
- ha->vpd_base = FA_NVRAM_VPD1_ADDR;
- }
/* Get VPD data into cache */
ha->vpd = ha->nvram + VPD_OFFSET;
- ha->isp_ops->read_nvram(vha, (uint8_t *)ha->vpd,
- ha->nvram_base - FA_NVRAM_FUNC0_ADDR, FA_NVRAM_VPD_SIZE * 4);
+ ha->isp_ops->read_optrom(vha, ha->vpd, ha->flt_region_vpd << 2,
+ ha->vpd_size);
/* Get NVRAM data into cache and calculate checksum. */
- dptr = (uint32_t *)nv;
- ha->isp_ops->read_nvram(vha, (uint8_t *)dptr, ha->nvram_base,
+ ha->isp_ops->read_optrom(vha, ha->nvram, ha->flt_region_nvram << 2,
ha->nvram_size);
+ dptr = (uint32_t *)nv;
for (cnt = 0, chksum = 0; cnt < ha->nvram_size >> 2; cnt++)
chksum += le32_to_cpu(*dptr++);
@@ -4452,6 +4399,9 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
icb->enode_mac[5] = 0x06 + PCI_FUNC(ha->pdev->devfn);
}
+ /* Use extended-initialization control block. */
+ memcpy(ha->ex_init_cb, &nv->ex_version, sizeof(*ha->ex_init_cb));
+
/*
* Setup driver NVRAM options.
*/
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 2258152b1f4..a8abbb95730 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -776,7 +776,7 @@ qla24xx_start_scsi(srb_t *sp)
req_cnt = qla24xx_calc_iocbs(tot_dsds);
if (req->cnt < (req_cnt + 2)) {
- cnt = ha->isp_ops->rd_req_reg(ha, req->id);
+ cnt = RD_REG_DWORD_RELAXED(req->req_q_out);
if (req->ring_index < cnt)
req->cnt = cnt - req->ring_index;
@@ -836,7 +836,8 @@ qla24xx_start_scsi(srb_t *sp)
sp->flags |= SRB_DMA_VALID;
/* Set chip new ring index. */
- ha->isp_ops->wrt_req_reg(ha, req->id, req->ring_index);
+ WRT_REG_DWORD(req->req_q_in, req->ring_index);
+ RD_REG_DWORD_RELAXED(&ha->iobase->isp24.hccr);
/* Manage unprocessed RIO/ZIO commands in response queue. */
if (vha->flags.process_response_queue &&
@@ -854,35 +855,3 @@ queuing_error:
return QLA_FUNCTION_FAILED;
}
-
-uint16_t
-qla24xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
-{
- device_reg_t __iomem *reg = (void *) ha->iobase;
- return RD_REG_DWORD_RELAXED(&reg->isp24.req_q_out);
-}
-
-uint16_t
-qla25xx_rd_req_reg(struct qla_hw_data *ha, uint16_t id)
-{
- device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
- return RD_REG_DWORD_RELAXED(&reg->isp25mq.req_q_out);
-}
-
-void
-qla24xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->iobase;
- WRT_REG_DWORD(&reg->isp24.req_q_in, index);
- RD_REG_DWORD_RELAXED(&reg->isp24.req_q_in);
-}
-
-void
-qla25xx_wrt_req_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
- struct device_reg_2xxx __iomem *ioreg = &ha->iobase->isp;
- WRT_REG_DWORD(&reg->isp25mq.req_q_in, index);
- RD_REG_DWORD(&ioreg->hccr); /* PCI posting */
-}
-
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index f250e5b7897..d04981848e5 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -852,9 +852,6 @@ qla2x00_process_completed_request(struct scsi_qla_host *vha,
/* Free outstanding command slot. */
req->outstanding_cmds[index] = NULL;
- CMD_COMPL_STATUS(sp->cmd) = 0L;
- CMD_SCSI_STATUS(sp->cmd) = 0L;
-
/* Save ISP completion status */
sp->cmd->result = DID_OK << 16;
@@ -955,7 +952,6 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
if (sense_len >= SCSI_SENSE_BUFFERSIZE)
sense_len = SCSI_SENSE_BUFFERSIZE;
- CMD_ACTUAL_SNSLEN(cp) = sense_len;
sp->request_sense_length = sense_len;
sp->request_sense_ptr = cp->sense_buffer;
if (sp->request_sense_length > 32)
@@ -973,8 +969,7 @@ qla2x00_handle_sense(srb_t *sp, uint8_t *sense_data, uint32_t sense_len)
cp->device->channel, cp->device->id, cp->device->lun, cp,
cp->serial_number));
if (sense_len)
- DEBUG5(qla2x00_dump_buffer(cp->sense_buffer,
- CMD_ACTUAL_SNSLEN(cp)));
+ DEBUG5(qla2x00_dump_buffer(cp->sense_buffer, sense_len));
}
/**
@@ -1043,9 +1038,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
}
lscsi_status = scsi_status & STATUS_MASK;
- CMD_ENTRY_STATUS(cp) = sts->entry_status;
- CMD_COMPL_STATUS(cp) = comp_status;
- CMD_SCSI_STATUS(cp) = scsi_status;
fcport = sp->fcport;
@@ -1104,7 +1096,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
if (scsi_status & (SS_RESIDUAL_UNDER | SS_RESIDUAL_OVER)) {
resid = resid_len;
scsi_set_resid(cp, resid);
- CMD_RESID_LEN(cp) = resid;
if (!lscsi_status &&
((unsigned)(scsi_bufflen(cp) - resid) <
@@ -1160,7 +1151,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
if (scsi_status & SS_RESIDUAL_UNDER) {
scsi_set_resid(cp, resid);
- CMD_RESID_LEN(cp) = resid;
} else {
DEBUG2(printk(KERN_INFO
"scsi(%ld:%d:%d) UNDERRUN status detected "
@@ -1499,7 +1489,6 @@ qla24xx_mbx_completion(scsi_qla_host_t *vha, uint16_t mb0)
void
qla24xx_process_response_queue(struct rsp_que *rsp)
{
- struct qla_hw_data *ha = rsp->hw;
struct sts_entry_24xx *pkt;
struct scsi_qla_host *vha;
@@ -1553,7 +1542,7 @@ qla24xx_process_response_queue(struct rsp_que *rsp)
}
/* Adjust ring index */
- ha->isp_ops->wrt_rsp_reg(ha, rsp->id, rsp->ring_index);
+ WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
}
static void
@@ -2029,7 +2018,7 @@ skip_msix:
skip_msi:
ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler,
- IRQF_DISABLED|IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
+ IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp);
if (ret) {
qla_printk(KERN_WARNING, ha,
"Failed to reserve interrupt %d already in use.\n",
@@ -2117,18 +2106,3 @@ int qla25xx_request_irq(struct rsp_que *rsp)
msix->rsp = rsp;
return ret;
}
-
-void
-qla25xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->mqiobase + QLA_QUE_PAGE * id;
- WRT_REG_DWORD(&reg->isp25mq.rsp_q_out, index);
-}
-
-void
-qla24xx_wrt_rsp_reg(struct qla_hw_data *ha, uint16_t id, uint16_t index)
-{
- device_reg_t __iomem *reg = (void *) ha->iobase;
- WRT_REG_DWORD(&reg->isp24.rsp_q_out, index);
-}
-
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 4aab7acf752..e67c1660bf4 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -45,6 +45,9 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
struct qla_hw_data *ha = vha->hw;
scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+ if (ha->pdev->error_state > pci_channel_io_frozen)
+ return QLA_FUNCTION_TIMEOUT;
+
reg = ha->iobase;
io_lock_on = base_vha->flags.init_done;
@@ -408,7 +411,7 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
void
qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
uint16_t *subminor, uint16_t *attributes, uint32_t *memory, uint8_t *mpi,
- uint32_t *mpi_caps)
+ uint32_t *mpi_caps, uint8_t *phy)
{
int rval;
mbx_cmd_t mc;
@@ -420,7 +423,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
mcp->out_mb = MBX_0;
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
if (IS_QLA81XX(vha->hw))
- mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10;
+ mcp->in_mb |= MBX_13|MBX_12|MBX_11|MBX_10|MBX_9|MBX_8;
mcp->flags = 0;
mcp->tov = MBX_TOV_SECONDS;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -435,11 +438,13 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha, uint16_t *major, uint16_t *minor,
else
*memory = (mcp->mb[5] << 16) | mcp->mb[4];
if (IS_QLA81XX(vha->hw)) {
- mpi[0] = mcp->mb[10] >> 8;
- mpi[1] = mcp->mb[10] & 0xff;
- mpi[2] = mcp->mb[11] >> 8;
- mpi[3] = mcp->mb[11] & 0xff;
+ mpi[0] = mcp->mb[10] & 0xff;
+ mpi[1] = mcp->mb[11] >> 8;
+ mpi[2] = mcp->mb[11] & 0xff;
*mpi_caps = (mcp->mb[12] << 16) | mcp->mb[13];
+ phy[0] = mcp->mb[8] & 0xff;
+ phy[1] = mcp->mb[9] >> 8;
+ phy[2] = mcp->mb[9] & 0xff;
}
if (rval != QLA_SUCCESS) {
@@ -1043,14 +1048,22 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
else
mcp->mb[0] = MBC_INITIALIZE_FIRMWARE;
+ mcp->mb[1] = 0;
mcp->mb[2] = MSW(ha->init_cb_dma);
mcp->mb[3] = LSW(ha->init_cb_dma);
- mcp->mb[4] = 0;
- mcp->mb[5] = 0;
mcp->mb[6] = MSW(MSD(ha->init_cb_dma));
mcp->mb[7] = LSW(MSD(ha->init_cb_dma));
- mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
- mcp->in_mb = MBX_5|MBX_4|MBX_0;
+ mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ if (IS_QLA81XX(ha) && ha->ex_init_cb->ex_version) {
+ mcp->mb[1] = BIT_0;
+ mcp->mb[10] = MSW(ha->ex_init_cb_dma);
+ mcp->mb[11] = LSW(ha->ex_init_cb_dma);
+ mcp->mb[12] = MSW(MSD(ha->ex_init_cb_dma));
+ mcp->mb[13] = LSW(MSD(ha->ex_init_cb_dma));
+ mcp->mb[14] = sizeof(*ha->ex_init_cb);
+ mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10;
+ }
+ mcp->in_mb = MBX_0;
mcp->buf_size = size;
mcp->flags = MBX_DMA_OUT;
mcp->tov = MBX_TOV_SECONDS;
@@ -1187,10 +1200,6 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt)
fcport->d_id.b.al_pa = pd->port_id[2];
fcport->d_id.b.rsvd_1 = 0;
- /* Check for device require authentication. */
- pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) :
- (fcport->flags &= ~FCF_AUTH_REQ);
-
/* If not target must be initiator or unknown type. */
if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
fcport->port_type = FCT_INITIATOR;
@@ -3218,3 +3227,204 @@ qla81xx_idc_ack(scsi_qla_host_t *vha, uint16_t *mb)
return rval;
}
+
+int
+qla81xx_fac_get_sector_size(scsi_qla_host_t *vha, uint32_t *sector_size)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ if (!IS_QLA81XX(vha->hw))
+ return QLA_FUNCTION_FAILED;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
+ mcp->mb[1] = FAC_OPT_CMD_GET_SECTOR_SIZE;
+ mcp->out_mb = MBX_1|MBX_0;
+ mcp->in_mb = MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
+ __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ *sector_size = mcp->mb[1];
+ }
+
+ return rval;
+}
+
+int
+qla81xx_fac_do_write_enable(scsi_qla_host_t *vha, int enable)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ if (!IS_QLA81XX(vha->hw))
+ return QLA_FUNCTION_FAILED;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
+ mcp->mb[1] = enable ? FAC_OPT_CMD_WRITE_ENABLE :
+ FAC_OPT_CMD_WRITE_PROTECT;
+ mcp->out_mb = MBX_1|MBX_0;
+ mcp->in_mb = MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n",
+ __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla81xx_fac_erase_sector(scsi_qla_host_t *vha, uint32_t start, uint32_t finish)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ if (!IS_QLA81XX(vha->hw))
+ return QLA_FUNCTION_FAILED;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_FLASH_ACCESS_CTRL;
+ mcp->mb[1] = FAC_OPT_CMD_ERASE_SECTOR;
+ mcp->mb[2] = LSW(start);
+ mcp->mb[3] = MSW(start);
+ mcp->mb[4] = LSW(finish);
+ mcp->mb[5] = MSW(finish);
+ mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_2|MBX_1|MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x "
+ "mb[2]=%x.\n", __func__, vha->host_no, rval, mcp->mb[0],
+ mcp->mb[1], mcp->mb[2]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla81xx_restart_mpi_firmware(scsi_qla_host_t *vha)
+{
+ int rval = 0;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_RESTART_MPI_FW;
+ mcp->out_mb = MBX_0;
+ mcp->in_mb = MBX_0|MBX_1;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=0x%x mb[1]=0x%x.\n",
+ __func__, vha->host_no, rval, mcp->mb[0], mcp->mb[1]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla2x00_read_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
+ dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ mcp->mb[0] = MBC_READ_SFP;
+ mcp->mb[1] = dev;
+ mcp->mb[2] = MSW(sfp_dma);
+ mcp->mb[3] = LSW(sfp_dma);
+ mcp->mb[6] = MSW(MSD(sfp_dma));
+ mcp->mb[7] = LSW(MSD(sfp_dma));
+ mcp->mb[8] = len;
+ mcp->mb[9] = adr;
+ mcp->mb[10] = opt;
+ mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (opt & BIT_0)
+ if (sfp)
+ *sfp = mcp->mb[8];
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+ }
+
+ return rval;
+}
+
+int
+qla2x00_write_edc(scsi_qla_host_t *vha, uint16_t dev, uint16_t adr,
+ dma_addr_t sfp_dma, uint8_t *sfp, uint16_t len, uint16_t opt)
+{
+ int rval;
+ mbx_cmd_t mc;
+ mbx_cmd_t *mcp = &mc;
+
+ DEBUG11(printk("%s(%ld): entered.\n", __func__, vha->host_no));
+
+ if (opt & BIT_0)
+ if (sfp)
+ len = *sfp;
+
+ mcp->mb[0] = MBC_WRITE_SFP;
+ mcp->mb[1] = dev;
+ mcp->mb[2] = MSW(sfp_dma);
+ mcp->mb[3] = LSW(sfp_dma);
+ mcp->mb[6] = MSW(MSD(sfp_dma));
+ mcp->mb[7] = LSW(MSD(sfp_dma));
+ mcp->mb[8] = len;
+ mcp->mb[9] = adr;
+ mcp->mb[10] = opt;
+ mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
+ mcp->in_mb = MBX_0;
+ mcp->tov = MBX_TOV_SECONDS;
+ mcp->flags = 0;
+ rval = qla2x00_mailbox_command(vha, mcp);
+
+ if (rval != QLA_SUCCESS) {
+ DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__,
+ vha->host_no, rval, mcp->mb[0]));
+ } else {
+ DEBUG11(printk("%s(%ld): done.\n", __func__, vha->host_no));
+ }
+
+ return rval;
+}
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
index 785c61279e6..51716c7e300 100644
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -359,7 +359,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport)
scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost);
struct qla_hw_data *ha = base_vha->hw;
scsi_qla_host_t *vha;
- struct scsi_host_template *sht = &qla24xx_driver_template;
+ struct scsi_host_template *sht = &qla2xxx_driver_template;
struct Scsi_Host *host;
vha = qla2x00_create_host(sht, ha);
@@ -584,6 +584,7 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
struct req_que *req = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
uint16_t que_id = 0;
+ device_reg_t __iomem *reg;
req = kzalloc(sizeof(struct req_que), GFP_KERNEL);
if (req == NULL) {
@@ -631,6 +632,9 @@ qla25xx_create_req_que(struct qla_hw_data *ha, uint16_t options,
req->ring_index = 0;
req->cnt = req->length;
req->id = que_id;
+ reg = ISP_QUE_REG(ha, que_id);
+ req->req_q_in = &reg->isp25mq.req_q_in;
+ req->req_q_out = &reg->isp25mq.req_q_out;
req->max_q_depth = ha->req_q_map[0]->max_q_depth;
mutex_unlock(&ha->vport_lock);
@@ -658,7 +662,8 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
int ret = 0;
struct rsp_que *rsp = NULL;
struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
- uint16_t que_id = 0;;
+ uint16_t que_id = 0;
+ device_reg_t __iomem *reg;
rsp = kzalloc(sizeof(struct rsp_que), GFP_KERNEL);
if (rsp == NULL) {
@@ -706,6 +711,9 @@ qla25xx_create_rsp_que(struct qla_hw_data *ha, uint16_t options,
rsp->ring_ptr = rsp->ring;
rsp->ring_index = 0;
rsp->id = que_id;
+ reg = ISP_QUE_REG(ha, que_id);
+ rsp->rsp_q_in = &reg->isp25mq.rsp_q_in;
+ rsp->rsp_q_out = &reg->isp25mq.rsp_q_out;
mutex_unlock(&ha->vport_lock);
ret = qla25xx_request_irq(rsp);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 3ddfa889e94..efe29924e05 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -104,9 +104,7 @@ static int qla2xxx_slave_alloc(struct scsi_device *);
static int qla2xxx_scan_finished(struct Scsi_Host *, unsigned long time);
static void qla2xxx_scan_start(struct Scsi_Host *);
static void qla2xxx_slave_destroy(struct scsi_device *);
-static int qla2x00_queuecommand(struct scsi_cmnd *cmd,
- void (*fn)(struct scsi_cmnd *));
-static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
+static int qla2xxx_queuecommand(struct scsi_cmnd *cmd,
void (*fn)(struct scsi_cmnd *));
static int qla2xxx_eh_abort(struct scsi_cmnd *);
static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
@@ -117,42 +115,10 @@ static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
static int qla2x00_change_queue_depth(struct scsi_device *, int);
static int qla2x00_change_queue_type(struct scsi_device *, int);
-static struct scsi_host_template qla2x00_driver_template = {
+struct scsi_host_template qla2xxx_driver_template = {
.module = THIS_MODULE,
.name = QLA2XXX_DRIVER_NAME,
- .queuecommand = qla2x00_queuecommand,
-
- .eh_abort_handler = qla2xxx_eh_abort,
- .eh_device_reset_handler = qla2xxx_eh_device_reset,
- .eh_target_reset_handler = qla2xxx_eh_target_reset,
- .eh_bus_reset_handler = qla2xxx_eh_bus_reset,
- .eh_host_reset_handler = qla2xxx_eh_host_reset,
-
- .slave_configure = qla2xxx_slave_configure,
-
- .slave_alloc = qla2xxx_slave_alloc,
- .slave_destroy = qla2xxx_slave_destroy,
- .scan_finished = qla2xxx_scan_finished,
- .scan_start = qla2xxx_scan_start,
- .change_queue_depth = qla2x00_change_queue_depth,
- .change_queue_type = qla2x00_change_queue_type,
- .this_id = -1,
- .cmd_per_lun = 3,
- .use_clustering = ENABLE_CLUSTERING,
- .sg_tablesize = SG_ALL,
-
- /*
- * The RISC allows for each command to transfer (2^32-1) bytes of data,
- * which equates to 0x800000 sectors.
- */
- .max_sectors = 0xFFFF,
- .shost_attrs = qla2x00_host_attrs,
-};
-
-struct scsi_host_template qla24xx_driver_template = {
- .module = THIS_MODULE,
- .name = QLA2XXX_DRIVER_NAME,
- .queuecommand = qla24xx_queuecommand,
+ .queuecommand = qla2xxx_queuecommand,
.eh_abort_handler = qla2xxx_eh_abort,
.eh_device_reset_handler = qla2xxx_eh_device_reset,
@@ -430,73 +396,7 @@ qla2x00_get_new_sp(scsi_qla_host_t *vha, fc_port_t *fcport,
}
static int
-qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
-{
- scsi_qla_host_t *vha = shost_priv(cmd->device->host);
- fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
- struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
- struct qla_hw_data *ha = vha->hw;
- srb_t *sp;
- int rval;
-
- if (unlikely(pci_channel_offline(ha->pdev))) {
- cmd->result = DID_REQUEUE << 16;
- goto qc_fail_command;
- }
-
- rval = fc_remote_port_chkready(rport);
- if (rval) {
- cmd->result = rval;
- goto qc_fail_command;
- }
-
- /* Close window on fcport/rport state-transitioning. */
- if (fcport->drport)
- goto qc_target_busy;
-
- if (atomic_read(&fcport->state) != FCS_ONLINE) {
- if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
- atomic_read(&vha->loop_state) == LOOP_DEAD) {
- cmd->result = DID_NO_CONNECT << 16;
- goto qc_fail_command;
- }
- goto qc_target_busy;
- }
-
- spin_unlock_irq(vha->host->host_lock);
-
- sp = qla2x00_get_new_sp(vha, fcport, cmd, done);
- if (!sp)
- goto qc_host_busy_lock;
-
- rval = ha->isp_ops->start_scsi(sp);
- if (rval != QLA_SUCCESS)
- goto qc_host_busy_free_sp;
-
- spin_lock_irq(vha->host->host_lock);
-
- return 0;
-
-qc_host_busy_free_sp:
- qla2x00_sp_free_dma(sp);
- mempool_free(sp, ha->srb_mempool);
-
-qc_host_busy_lock:
- spin_lock_irq(vha->host->host_lock);
- return SCSI_MLQUEUE_HOST_BUSY;
-
-qc_target_busy:
- return SCSI_MLQUEUE_TARGET_BUSY;
-
-qc_fail_command:
- done(cmd);
-
- return 0;
-}
-
-
-static int
-qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
+qla2xxx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
@@ -507,7 +407,10 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
int rval;
if (unlikely(pci_channel_offline(ha->pdev))) {
- cmd->result = DID_REQUEUE << 16;
+ if (ha->pdev->error_state == pci_channel_io_frozen)
+ cmd->result = DID_REQUEUE << 16;
+ else
+ cmd->result = DID_NO_CONNECT << 16;
goto qc24_fail_command;
}
@@ -635,6 +538,34 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *vha)
return (return_status);
}
+int
+qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha)
+{
+ int return_status;
+ unsigned long wait_reset;
+ struct qla_hw_data *ha = vha->hw;
+ scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
+
+ wait_reset = jiffies + (MAX_LOOP_TIMEOUT * HZ);
+ while (((test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) ||
+ test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
+ test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
+ ha->dpc_active) && time_before(jiffies, wait_reset)) {
+
+ msleep(1000);
+
+ if (!test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
+ ha->flags.chip_reset_done)
+ break;
+ }
+ if (ha->flags.chip_reset_done)
+ return_status = QLA_SUCCESS;
+ else
+ return_status = QLA_FUNCTION_FAILED;
+
+ return return_status;
+}
+
/*
* qla2x00_wait_for_loop_ready
* Wait for MAX_LOOP_TIMEOUT(5 min) value for loop
@@ -1163,7 +1094,7 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
continue;
for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
sp = req->outstanding_cmds[cnt];
- if (sp && sp->fcport->vha == vha) {
+ if (sp) {
req->outstanding_cmds[cnt] = NULL;
sp->cmd->result = res;
qla2x00_sp_compl(ha, sp);
@@ -1351,9 +1282,6 @@ static struct isp_operations qla2100_isp_ops = {
.write_optrom = qla2x00_write_optrom_data,
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
- .wrt_req_reg = NULL,
- .wrt_rsp_reg = NULL,
- .rd_req_reg = NULL,
};
static struct isp_operations qla2300_isp_ops = {
@@ -1389,9 +1317,6 @@ static struct isp_operations qla2300_isp_ops = {
.write_optrom = qla2x00_write_optrom_data,
.get_flash_version = qla2x00_get_flash_version,
.start_scsi = qla2x00_start_scsi,
- .wrt_req_reg = NULL,
- .wrt_rsp_reg = NULL,
- .rd_req_reg = NULL,
};
static struct isp_operations qla24xx_isp_ops = {
@@ -1427,9 +1352,6 @@ static struct isp_operations qla24xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
- .wrt_req_reg = qla24xx_wrt_req_reg,
- .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
- .rd_req_reg = qla24xx_rd_req_reg,
};
static struct isp_operations qla25xx_isp_ops = {
@@ -1465,9 +1387,6 @@ static struct isp_operations qla25xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
- .wrt_req_reg = qla24xx_wrt_req_reg,
- .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
- .rd_req_reg = qla24xx_rd_req_reg,
};
static struct isp_operations qla81xx_isp_ops = {
@@ -1493,8 +1412,8 @@ static struct isp_operations qla81xx_isp_ops = {
.build_iocbs = NULL,
.prep_ms_iocb = qla24xx_prep_ms_iocb,
.prep_ms_fdmi_iocb = qla24xx_prep_ms_fdmi_iocb,
- .read_nvram = qla25xx_read_nvram_data,
- .write_nvram = qla25xx_write_nvram_data,
+ .read_nvram = NULL,
+ .write_nvram = NULL,
.fw_dump = qla81xx_fw_dump,
.beacon_on = qla24xx_beacon_on,
.beacon_off = qla24xx_beacon_off,
@@ -1503,9 +1422,6 @@ static struct isp_operations qla81xx_isp_ops = {
.write_optrom = qla24xx_write_optrom_data,
.get_flash_version = qla24xx_get_flash_version,
.start_scsi = qla24xx_start_scsi,
- .wrt_req_reg = qla24xx_wrt_req_reg,
- .wrt_rsp_reg = qla24xx_wrt_rsp_reg,
- .rd_req_reg = qla24xx_rd_req_reg,
};
static inline void
@@ -1727,7 +1643,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
struct rsp_que *rsp = NULL;
bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
- sht = &qla2x00_driver_template;
+ sht = &qla2xxx_driver_template;
if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
@@ -1736,7 +1652,6 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532 ||
pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8001) {
bars = pci_select_bars(pdev, IORESOURCE_MEM);
- sht = &qla24xx_driver_template;
mem_only = 1;
}
@@ -1927,10 +1842,16 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->rsp_q_map[0] = rsp;
ha->req_q_map[0] = req;
+ /* FWI2-capable only. */
+ req->req_q_in = &ha->iobase->isp24.req_q_in;
+ req->req_q_out = &ha->iobase->isp24.req_q_out;
+ rsp->rsp_q_in = &ha->iobase->isp24.rsp_q_in;
+ rsp->rsp_q_out = &ha->iobase->isp24.rsp_q_out;
if (ha->mqenable) {
- ha->isp_ops->wrt_req_reg = qla25xx_wrt_req_reg;
- ha->isp_ops->wrt_rsp_reg = qla25xx_wrt_rsp_reg;
- ha->isp_ops->rd_req_reg = qla25xx_rd_req_reg;
+ req->req_q_in = &ha->mqiobase->isp25mq.req_q_in;
+ req->req_q_out = &ha->mqiobase->isp25mq.req_q_out;
+ rsp->rsp_q_in = &ha->mqiobase->isp25mq.rsp_q_in;
+ rsp->rsp_q_out = &ha->mqiobase->isp25mq.rsp_q_out;
}
if (qla2x00_initialize_adapter(base_vha)) {
@@ -2000,6 +1921,16 @@ probe_init_failed:
ha->max_queues = 0;
probe_failed:
+ if (base_vha->timer_active)
+ qla2x00_stop_timer(base_vha);
+ base_vha->flags.online = 0;
+ if (ha->dpc_thread) {
+ struct task_struct *t = ha->dpc_thread;
+
+ ha->dpc_thread = NULL;
+ kthread_stop(t);
+ }
+
qla2x00_free_device(base_vha);
scsi_host_put(base_vha->host);
@@ -2033,10 +1964,30 @@ qla2x00_remove_one(struct pci_dev *pdev)
set_bit(UNLOADING, &base_vha->dpc_flags);
+ qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
+
qla2x00_dfs_remove(base_vha);
qla84xx_put_chip(base_vha);
+ /* Disable timer */
+ if (base_vha->timer_active)
+ qla2x00_stop_timer(base_vha);
+
+ base_vha->flags.online = 0;
+
+ /* Kill the kernel thread for this host */
+ if (ha->dpc_thread) {
+ struct task_struct *t = ha->dpc_thread;
+
+ /*
+ * qla2xxx_wake_dpc checks for ->dpc_thread
+ * so we need to zero it out.
+ */
+ ha->dpc_thread = NULL;
+ kthread_stop(t);
+ }
+
qla2x00_free_sysfs_attr(base_vha);
fc_remove_host(base_vha->host);
@@ -2065,25 +2016,6 @@ static void
qla2x00_free_device(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
- qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16);
-
- /* Disable timer */
- if (vha->timer_active)
- qla2x00_stop_timer(vha);
-
- vha->flags.online = 0;
-
- /* Kill the kernel thread for this host */
- if (ha->dpc_thread) {
- struct task_struct *t = ha->dpc_thread;
-
- /*
- * qla2xxx_wake_dpc checks for ->dpc_thread
- * so we need to zero it out.
- */
- ha->dpc_thread = NULL;
- kthread_stop(t);
- }
if (ha->flags.fce_enabled)
qla2x00_disable_fce_trace(vha, NULL, NULL);
@@ -2313,9 +2245,19 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
} else
ha->npiv_info = NULL;
+ /* Get consistent memory allocated for EX-INIT-CB. */
+ if (IS_QLA81XX(ha)) {
+ ha->ex_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL,
+ &ha->ex_init_cb_dma);
+ if (!ha->ex_init_cb)
+ goto fail_ex_init_cb;
+ }
+
INIT_LIST_HEAD(&ha->vp_list);
return 1;
+fail_ex_init_cb:
+ kfree(ha->npiv_info);
fail_npiv_info:
dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
sizeof(response_t), (*rsp)->ring, (*rsp)->dma);
@@ -2398,18 +2340,22 @@ qla2x00_mem_free(struct qla_hw_data *ha)
if (ha->sfp_data)
dma_pool_free(ha->s_dma_pool, ha->sfp_data, ha->sfp_data_dma);
+ if (ha->edc_data)
+ dma_pool_free(ha->s_dma_pool, ha->edc_data, ha->edc_data_dma);
+
if (ha->ms_iocb)
dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma);
+ if (ha->ex_init_cb)
+ dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
+
if (ha->s_dma_pool)
dma_pool_destroy(ha->s_dma_pool);
-
if (ha->gid_list)
dma_free_coherent(&ha->pdev->dev, GID_LIST_SIZE, ha->gid_list,
ha->gid_list_dma);
-
if (ha->init_cb)
dma_free_coherent(&ha->pdev->dev, ha->init_cb_size,
ha->init_cb, ha->init_cb_dma);
@@ -2428,6 +2374,8 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->ms_iocb_dma = 0;
ha->init_cb = NULL;
ha->init_cb_dma = 0;
+ ha->ex_init_cb = NULL;
+ ha->ex_init_cb_dma = 0;
ha->s_dma_pool = NULL;
@@ -2914,19 +2862,11 @@ qla2x00_timer(scsi_qla_host_t *vha)
spin_unlock_irqrestore(&ha->hardware_lock,
cpu_flags);
}
- set_bit(ABORT_QUEUES_NEEDED, &vha->dpc_flags);
start_dpc++;
}
/* if the loop has been down for 4 minutes, reinit adapter */
if (atomic_dec_and_test(&vha->loop_down_timer) != 0) {
- DEBUG(printk("scsi(%ld): Loop down exceed 4 mins - "
- "restarting queues.\n",
- vha->host_no));
-
- set_bit(RESTART_QUEUES_NEEDED, &vha->dpc_flags);
- start_dpc++;
-
if (!(vha->device_flags & DFLG_NO_CABLE) &&
!vha->vp_idx) {
DEBUG(printk("scsi(%ld): Loop down - "
@@ -3053,6 +2993,8 @@ qla2x00_release_firmware(void)
static pci_ers_result_t
qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
{
+ scsi_qla_host_t *base_vha = pci_get_drvdata(pdev);
+
switch (state) {
case pci_channel_io_normal:
return PCI_ERS_RESULT_CAN_RECOVER;
@@ -3060,7 +3002,7 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
pci_disable_device(pdev);
return PCI_ERS_RESULT_NEED_RESET;
case pci_channel_io_perm_failure:
- qla2x00_remove_one(pdev);
+ qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
return PCI_ERS_RESULT_DISCONNECT;
}
return PCI_ERS_RESULT_NEED_RESET;
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
index 284827926ef..152ecfc26cd 100644
--- a/drivers/scsi/qla2xxx/qla_sup.c
+++ b/drivers/scsi/qla2xxx/qla_sup.c
@@ -612,8 +612,8 @@ qla2xxx_find_flt_start(scsi_qla_host_t *vha, uint32_t *start)
/* Good data. Use specified location. */
loc = locations[1];
- *start = le16_to_cpu(fltl->start_hi) << 16 |
- le16_to_cpu(fltl->start_lo);
+ *start = (le16_to_cpu(fltl->start_hi) << 16 |
+ le16_to_cpu(fltl->start_lo)) >> 2;
end:
DEBUG2(qla_printk(KERN_DEBUG, ha, "FLTL[%s] = 0x%x.\n", loc, *start));
return QLA_SUCCESS;
@@ -629,6 +629,14 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
{ FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR, FA_BOOT_CODE_ADDR_81 };
const uint32_t def_vpd_nvram[] =
{ FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR, FA_VPD_NVRAM_ADDR_81 };
+ const uint32_t def_vpd0[] =
+ { 0, 0, FA_VPD0_ADDR_81 };
+ const uint32_t def_vpd1[] =
+ { 0, 0, FA_VPD1_ADDR_81 };
+ const uint32_t def_nvram0[] =
+ { 0, 0, FA_NVRAM0_ADDR_81 };
+ const uint32_t def_nvram1[] =
+ { 0, 0, FA_NVRAM1_ADDR_81 };
const uint32_t def_fdt[] =
{ FA_FLASH_DESCR_ADDR_24, FA_FLASH_DESCR_ADDR,
FA_FLASH_DESCR_ADDR_81 };
@@ -693,6 +701,20 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr)
break;
case FLT_REG_VPD_0:
ha->flt_region_vpd_nvram = start;
+ if (!(PCI_FUNC(ha->pdev->devfn) & 1))
+ ha->flt_region_vpd = start;
+ break;
+ case FLT_REG_VPD_1:
+ if (PCI_FUNC(ha->pdev->devfn) & 1)
+ ha->flt_region_vpd = start;
+ break;
+ case FLT_REG_NVRAM_0:
+ if (!(PCI_FUNC(ha->pdev->devfn) & 1))
+ ha->flt_region_nvram = start;
+ break;
+ case FLT_REG_NVRAM_1:
+ if (PCI_FUNC(ha->pdev->devfn) & 1)
+ ha->flt_region_nvram = start;
break;
case FLT_REG_FDT:
ha->flt_region_fdt = start;
@@ -722,13 +744,18 @@ no_flash_data:
ha->flt_region_fw = def_fw[def];
ha->flt_region_boot = def_boot[def];
ha->flt_region_vpd_nvram = def_vpd_nvram[def];
+ ha->flt_region_vpd = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+ def_vpd0[def]: def_vpd1[def];
+ ha->flt_region_nvram = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
+ def_nvram0[def]: def_nvram1[def];
ha->flt_region_fdt = def_fdt[def];
ha->flt_region_npiv_conf = !(PCI_FUNC(ha->pdev->devfn) & 1) ?
def_npiv_conf0[def]: def_npiv_conf1[def];
done:
DEBUG2(qla_printk(KERN_DEBUG, ha, "FLT[%s]: boot=0x%x fw=0x%x "
- "vpd_nvram=0x%x fdt=0x%x flt=0x%x npiv=0x%x.\n", loc,
- ha->flt_region_boot, ha->flt_region_fw, ha->flt_region_vpd_nvram,
+ "vpd_nvram=0x%x vpd=0x%x nvram=0x%x fdt=0x%x flt=0x%x "
+ "npiv=0x%x.\n", loc, ha->flt_region_boot, ha->flt_region_fw,
+ ha->flt_region_vpd_nvram, ha->flt_region_vpd, ha->flt_region_nvram,
ha->flt_region_fdt, ha->flt_region_flt, ha->flt_region_npiv_conf));
}
@@ -931,31 +958,41 @@ done:
ha->npiv_info = NULL;
}
-static void
-qla24xx_unprotect_flash(struct qla_hw_data *ha)
+static int
+qla24xx_unprotect_flash(scsi_qla_host_t *vha)
{
+ struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+ if (ha->flags.fac_supported)
+ return qla81xx_fac_do_write_enable(vha, 1);
+
/* Enable flash write. */
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) | CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
if (!ha->fdt_wrt_disable)
- return;
+ goto done;
/* Disable flash write-protection, first clear SR protection bit */
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
/* Then write zero again to clear remaining SR bits.*/
qla24xx_write_flash_dword(ha, flash_conf_addr(ha, 0x101), 0);
+done:
+ return QLA_SUCCESS;
}
-static void
-qla24xx_protect_flash(struct qla_hw_data *ha)
+static int
+qla24xx_protect_flash(scsi_qla_host_t *vha)
{
uint32_t cnt;
+ struct qla_hw_data *ha = vha->hw;
struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
+ if (ha->flags.fac_supported)
+ return qla81xx_fac_do_write_enable(vha, 0);
+
if (!ha->fdt_wrt_disable)
goto skip_wrt_protect;
@@ -973,6 +1010,26 @@ skip_wrt_protect:
WRT_REG_DWORD(&reg->ctrl_status,
RD_REG_DWORD(&reg->ctrl_status) & ~CSRX_FLASH_ENABLE);
RD_REG_DWORD(&reg->ctrl_status); /* PCI Posting. */
+
+ return QLA_SUCCESS;
+}
+
+static int
+qla24xx_erase_sector(scsi_qla_host_t *vha, uint32_t fdata)
+{
+ struct qla_hw_data *ha = vha->hw;
+ uint32_t start, finish;
+
+ if (ha->flags.fac_supported) {
+ start = fdata >> 2;
+ finish = start + (ha->fdt_block_size >> 2) - 1;
+ return qla81xx_fac_erase_sector(vha, flash_data_addr(ha,
+ start), flash_data_addr(ha, finish));
+ }
+
+ return qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd,
+ (fdata & 0xff00) | ((fdata << 16) & 0xff0000) |
+ ((fdata >> 16) & 0xff));
}
static int
@@ -987,8 +1044,6 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
void *optrom = NULL;
struct qla_hw_data *ha = vha->hw;
- ret = QLA_SUCCESS;
-
/* Prepare burst-capable write on supported ISPs. */
if ((IS_QLA25XX(ha) || IS_QLA81XX(ha)) && !(faddr & 0xfff) &&
dwords > OPTROM_BURST_DWORDS) {
@@ -1004,7 +1059,12 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
rest_addr = (ha->fdt_block_size >> 2) - 1;
sec_mask = ~rest_addr;
- qla24xx_unprotect_flash(ha);
+ ret = qla24xx_unprotect_flash(vha);
+ if (ret != QLA_SUCCESS) {
+ qla_printk(KERN_WARNING, ha,
+ "Unable to unprotect flash for update.\n");
+ goto done;
+ }
for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
fdata = (faddr & sec_mask) << 2;
@@ -1017,9 +1077,7 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
ha->fdt_unprotect_sec_cmd,
(fdata & 0xff00) | ((fdata << 16) &
0xff0000) | ((fdata >> 16) & 0xff));
- ret = qla24xx_write_flash_dword(ha, ha->fdt_erase_cmd,
- (fdata & 0xff00) |((fdata << 16) &
- 0xff0000) | ((fdata >> 16) & 0xff));
+ ret = qla24xx_erase_sector(vha, fdata);
if (ret != QLA_SUCCESS) {
DEBUG9(qla_printk("Unable to erase sector: "
"address=%x.\n", faddr));
@@ -1073,8 +1131,11 @@ qla24xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr,
0xff0000) | ((fdata >> 16) & 0xff));
}
- qla24xx_protect_flash(ha);
-
+ ret = qla24xx_protect_flash(vha);
+ if (ret != QLA_SUCCESS)
+ qla_printk(KERN_WARNING, ha,
+ "Unable to protect flash after update.\n");
+done:
if (optrom)
dma_free_coherent(&ha->pdev->dev,
OPTROM_BURST_SIZE, optrom, optrom_dma);
@@ -1915,7 +1976,7 @@ qla2x00_resume_hba(struct scsi_qla_host *vha)
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
- qla2x00_wait_for_hba_online(vha);
+ qla2x00_wait_for_chip_reset(vha);
scsi_unblock_requests(vha->host);
}
@@ -2206,11 +2267,7 @@ qla24xx_write_optrom_data(struct scsi_qla_host *vha, uint8_t *buf,
rval = qla24xx_write_flash_data(vha, (uint32_t *)buf, offset >> 2,
length >> 2);
- /* Resume HBA -- RISC reset needed. */
clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags);
- set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
- qla2xxx_wake_dpc(vha);
- qla2x00_wait_for_hba_online(vha);
scsi_unblock_requests(vha->host);
return rval;
@@ -2518,7 +2575,7 @@ qla24xx_get_flash_version(scsi_qla_host_t *vha, void *mbuf)
dcode = mbuf;
/* Begin with first PCI expansion ROM header. */
- pcihdr = ha->flt_region_boot;
+ pcihdr = ha->flt_region_boot << 2;
last_image = 1;
do {
/* Verify PCI expansion ROM header. */
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index a772eab2f0e..19d1afc3a34 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,9 +7,9 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.00-k4"
+#define QLA2XXX_VERSION "8.03.01-k1"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
-#define QLA_DRIVER_PATCH_VER 0
+#define QLA_DRIVER_PATCH_VER 1
#define QLA_DRIVER_BETA_VER 0
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index 69d6ad862b6..fa34b92850a 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -28,6 +28,7 @@
#include <linux/dma-mapping.h>
#include <linux/of.h>
#include <linux/of_device.h>
+#include <linux/firmware.h>
#include <asm/byteorder.h>
@@ -53,8 +54,6 @@
#define DEFAULT_LOOP_COUNT 10000
-#include "qlogicpti_asm.c"
-
static struct qlogicpti *qptichain = NULL;
static DEFINE_SPINLOCK(qptichain_lock);
@@ -465,16 +464,32 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host)
static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
{
+ const struct firmware *fw;
+ const char fwname[] = "qlogic/isp1000.bin";
+ const __le16 *fw_data;
struct Scsi_Host *host = qpti->qhost;
unsigned short csum = 0;
unsigned short param[6];
- unsigned short *risc_code, risc_code_addr, risc_code_length;
+ unsigned short risc_code_addr, risc_code_length;
+ int err;
unsigned long flags;
int i, timeout;
- risc_code = &sbus_risc_code01[0];
+ err = request_firmware(&fw, fwname, &qpti->op->dev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fwname, err);
+ return err;
+ }
+ if (fw->size % 2) {
+ printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+ fw->size, fwname);
+ err = -EINVAL;
+ goto outfirm;
+ }
+ fw_data = (const __le16 *)&fw->data[0];
risc_code_addr = 0x1000; /* all f/w modules load at 0x1000 */
- risc_code_length = sbus_risc_code_length01;
+ risc_code_length = fw->size / 2;
spin_lock_irqsave(host->host_lock, flags);
@@ -482,12 +497,12 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
* afterwards via the mailbox commands.
*/
for (i = 0; i < risc_code_length; i++)
- csum += risc_code[i];
+ csum += __le16_to_cpu(fw_data[i]);
if (csum) {
- spin_unlock_irqrestore(host->host_lock, flags);
printk(KERN_EMERG "qlogicpti%d: Aieee, firmware checksum failed!",
qpti->qpti_id);
- return 1;
+ err = 1;
+ goto out;
}
sbus_writew(SBUS_CTRL_RESET, qpti->qregs + SBUS_CTRL);
sbus_writew((DMA_CTRL_CCLEAR | DMA_CTRL_CIRQ), qpti->qregs + CMD_DMA_CTRL);
@@ -496,9 +511,9 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
while (--timeout && (sbus_readw(qpti->qregs + SBUS_CTRL) & SBUS_CTRL_RESET))
udelay(20);
if (!timeout) {
- spin_unlock_irqrestore(host->host_lock, flags);
printk(KERN_EMERG "qlogicpti%d: Cannot reset the ISP.", qpti->qpti_id);
- return 1;
+ err = 1;
+ goto out;
}
sbus_writew(HCCTRL_RESET, qpti->qregs + HCCTRL);
@@ -536,21 +551,21 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
if (qlogicpti_mbox_command(qpti, param, 1)) {
printk(KERN_EMERG "qlogicpti%d: Cannot stop firmware for reload.\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
/* Load it up.. */
for (i = 0; i < risc_code_length; i++) {
param[0] = MBOX_WRITE_RAM_WORD;
param[1] = risc_code_addr + i;
- param[2] = risc_code[i];
+ param[2] = __le16_to_cpu(fw_data[i]);
if (qlogicpti_mbox_command(qpti, param, 1) ||
param[0] != MBOX_COMMAND_COMPLETE) {
printk("qlogicpti%d: Firmware dload failed, I'm bolixed!\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
}
@@ -569,8 +584,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: New firmware csum failure!\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
/* Start using newly downloaded firmware. */
@@ -583,8 +598,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: AboutFirmware cmd fails.\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
/* Snag the major and minor revisions from the result. */
@@ -599,8 +614,8 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
(param[0] != MBOX_COMMAND_COMPLETE)) {
printk(KERN_EMERG "qlogicpti%d: could not set clock rate.\n",
qpti->qpti_id);
- spin_unlock_irqrestore(host->host_lock, flags);
- return 1;
+ err = 1;
+ goto out;
}
if (qpti->is_pti != 0) {
@@ -616,8 +631,11 @@ static int __devinit qlogicpti_load_firmware(struct qlogicpti *qpti)
qlogicpti_mbox_command(qpti, param, 1);
}
+out:
spin_unlock_irqrestore(host->host_lock, flags);
- return 0;
+outfirm:
+ release_firmware(fw);
+ return err;
}
static int qlogicpti_verify_tmon(struct qlogicpti *qpti)
@@ -1458,6 +1476,7 @@ MODULE_DESCRIPTION("QlogicISP SBUS driver");
MODULE_AUTHOR("David S. Miller (davem@davemloft.net)");
MODULE_LICENSE("GPL");
MODULE_VERSION("2.1");
+MODULE_FIRMWARE("qlogic/isp1000.bin");
module_init(qpti_init);
module_exit(qpti_exit);
diff --git a/drivers/scsi/qlogicpti_asm.c b/drivers/scsi/qlogicpti_asm.c
deleted file mode 100644
index 19aa84f4601..00000000000
--- a/drivers/scsi/qlogicpti_asm.c
+++ /dev/null
@@ -1,1160 +0,0 @@
-/* Version 1.31.00 ISP1000 Initiator RISC firmware */
-unsigned short sbus_risc_code01[] __devinitdata = {
- 0x0078, 0x1030, 0x0000, 0x2419, 0x0000, 0x12ff, 0x2043, 0x4f50,
- 0x5952, 0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932,
- 0x2c31, 0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749,
- 0x4320, 0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049,
- 0x5350, 0x3130, 0x3030, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520,
- 0x2056, 0x6572, 0x7369, 0x6f6e, 0x2030, 0x312e, 0x3331, 0x2020,
- 0x20b9, 0x1212, 0x20c1, 0x0008, 0x2071, 0x0010, 0x70c3, 0x0004,
- 0x20c9, 0x3fff, 0x2089, 0x10c8, 0x70c7, 0x4953, 0x70cb, 0x5020,
- 0x70cf, 0x2020, 0x70d3, 0x0001, 0x3f00, 0x70d6, 0x2031, 0x0030,
- 0x2079, 0x3500, 0x7863, 0x0000, 0x2fa0, 0x2009, 0x0327, 0x2011,
- 0x0000, 0x20a9, 0x0040, 0x42a4, 0x8109, 0x00c0, 0x1051, 0x789b,
- 0x0101, 0x780b, 0x0002, 0x780f, 0x0002, 0x784f, 0x0bb8, 0x2069,
- 0x3540, 0x00a8, 0x106a, 0x681b, 0x003c, 0x2009, 0x1313, 0x21b8,
- 0x0078, 0x106c, 0x681b, 0x0028, 0x6807, 0x0007, 0x680b, 0x00fa,
- 0x680f, 0x0008, 0x6813, 0x0005, 0x681f, 0x0000, 0x6823, 0x0006,
- 0x6817, 0x0008, 0x6827, 0x0000, 0x2069, 0x3600, 0x2011, 0x0020,
- 0x2009, 0x0010, 0x680b, 0x0c19, 0x680f, 0x0019, 0x6803, 0xdd00,
- 0x6807, 0x001a, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004,
- 0x8109, 0x00c0, 0x1082, 0x2069, 0x3680, 0x20a9, 0x0080, 0x6837,
- 0x0000, 0x680b, 0x0040, 0x6817, 0x0100, 0x681f, 0x0064, 0xade8,
- 0x0010, 0x0070, 0x10a5, 0x0078, 0x1097, 0x1078, 0x1a38, 0x1078,
- 0x2f3a, 0x1078, 0x1681, 0x1078, 0x33ba, 0x3200, 0xa085, 0x000d,
- 0x2090, 0x70c3, 0x0000, 0x0090, 0x10bc, 0x70c0, 0xa086, 0x0002,
- 0x00c0, 0x10bc, 0x1078, 0x11ba, 0x1078, 0x10ec, 0x1078, 0x1817,
- 0x1078, 0x19a8, 0x1078, 0x327d, 0x1078, 0x177d, 0x0078, 0x10bc,
- 0x10d0, 0x10d2, 0x1bc3, 0x1bc3, 0x2f98, 0x2f98, 0x1bc3, 0x1bc3,
- 0x0078, 0x10d0, 0x0078, 0x10d2, 0x0078, 0x10d4, 0x0078, 0x10d6,
- 0x7008, 0x800c, 0x00c8, 0x10e7, 0x7007, 0x0002, 0xa08c, 0x000c,
- 0x00c0, 0x10e8, 0x8004, 0x8004, 0x00c8, 0x10e7, 0x087a, 0x097a,
- 0x70c3, 0x4002, 0x0078, 0x11bd, 0x7814, 0xa005, 0x00c0, 0x10f4,
- 0x0010, 0x1130, 0x0078, 0x112f, 0x2009, 0x3568, 0x2104, 0xa005,
- 0x00c0, 0x112f, 0x7814, 0xa086, 0x0001, 0x00c0, 0x1101, 0x1078,
- 0x1536, 0x7817, 0x0000, 0x2009, 0x356f, 0x2104, 0xa065, 0x0040,
- 0x111d, 0x2009, 0x356a, 0x211c, 0x8108, 0x2114, 0x8108, 0x2104,
- 0xa210, 0xa399, 0x0000, 0x2009, 0x001c, 0x6083, 0x0103, 0x1078,
- 0x1611, 0x00c0, 0x1129, 0x1078, 0x1678, 0x2009, 0x356f, 0x200b,
- 0x0000, 0x2009, 0x3569, 0x2104, 0x200b, 0x0000, 0xa005, 0x0040,
- 0x112d, 0x2001, 0x4005, 0x0078, 0x11bc, 0x0078, 0x11ba, 0x007c,
- 0x2061, 0x0000, 0x6018, 0xa084, 0x0001, 0x0040, 0x1138, 0x007c,
- 0x70c3, 0x0000, 0x70c7, 0x0000, 0x70cb, 0x0000, 0x70cf, 0x0000,
- 0x70c0, 0xa0bc, 0xffc0, 0x00c0, 0x1188, 0x2038, 0x0079, 0x1148,
- 0x11ba, 0x1205, 0x11d3, 0x1205, 0x1256, 0x1256, 0x11ca, 0x1590,
- 0x1261, 0x11c6, 0x11d7, 0x11d9, 0x11db, 0x11dd, 0x1595, 0x11c6,
- 0x1267, 0x1283, 0x1544, 0x158a, 0x11df, 0x146b, 0x148d, 0x14a7,
- 0x14d0, 0x1424, 0x1432, 0x1446, 0x145a, 0x12ef, 0x11c6, 0x129f,
- 0x12a6, 0x12ab, 0x12b0, 0x12b6, 0x12bb, 0x12c0, 0x12c5, 0x12ca,
- 0x12ce, 0x12e3, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x12fb,
- 0x1304, 0x1313, 0x1339, 0x1343, 0x134a, 0x1370, 0x137f, 0x138e,
- 0x13a0, 0x1409, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x1419,
- 0xa0bc, 0xffa0, 0x00c0, 0x11c6, 0x2038, 0xa084, 0x001f, 0x0079,
- 0x1191, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6,
- 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6,
- 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6, 0x11c6,
- 0x11c6, 0x11c6, 0x11c6, 0x15ed, 0x15f7, 0x15fb, 0x1609, 0x11c6,
- 0x11c6, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x11bc, 0x73ce,
- 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x2061, 0x0000, 0x601b,
- 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c, 0x70c3, 0x4001,
- 0x0078, 0x11bd, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005,
- 0x53a3, 0x0078, 0x11ba, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078,
- 0x11ba, 0x0078, 0x11ba, 0x0078, 0x11ba, 0x0078, 0x11ba, 0x2091,
- 0x8000, 0x70c3, 0x0000, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf,
- 0x2020, 0x70d3, 0x0001, 0x3f00, 0x70d6, 0x2079, 0x0000, 0x781b,
- 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x0457, 0x2051,
- 0x0470, 0x2061, 0x0472, 0x20b9, 0xffff, 0x20c1, 0x0000, 0x2091,
- 0x5000, 0x2091, 0x4080, 0x0078, 0x0455, 0x71d0, 0x72c8, 0x73cc,
- 0x70c4, 0x20a0, 0x2098, 0x2031, 0x0030, 0x81ff, 0x0040, 0x11ba,
- 0x7007, 0x0004, 0x731a, 0x721e, 0x2051, 0x0012, 0x2049, 0x1234,
- 0x2041, 0x11ba, 0x7003, 0x0002, 0xa786, 0x0001, 0x00c0, 0x1226,
- 0x2049, 0x1242, 0x2041, 0x124e, 0x7003, 0x0003, 0x7017, 0x0000,
- 0x810b, 0x7112, 0x00c8, 0x122e, 0x7017, 0x0001, 0x7007, 0x0001,
- 0xa786, 0x0001, 0x0040, 0x1242, 0x700c, 0xa084, 0x007f, 0x8004,
- 0x2009, 0x0020, 0xa102, 0x0942, 0x094a, 0x20a8, 0x26a0, 0x53a6,
- 0x0078, 0x10d8, 0x700c, 0xa084, 0x007f, 0x0040, 0x1242, 0x80ac,
- 0x0048, 0x1242, 0x2698, 0x53a5, 0x0078, 0x10d8, 0x700c, 0xa084,
- 0x007f, 0x80ac, 0x2698, 0x53a5, 0x0078, 0x11ba, 0x71c4, 0x70c8,
- 0x2114, 0xa79e, 0x0004, 0x00c0, 0x125e, 0x200a, 0x72ca, 0x0078,
- 0x11b9, 0x70c7, 0x0001, 0x70cb, 0x001f, 0x0078, 0x11ba, 0x70c4,
- 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005,
- 0x0040, 0x127d, 0x8001, 0x7872, 0x7a7a, 0x7b7e, 0x7c76, 0x7898,
- 0xa084, 0xfffc, 0x789a, 0x0078, 0x1281, 0x7898, 0xa085, 0x0001,
- 0x789a, 0x0078, 0x11ba, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6,
- 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0040, 0x1299, 0x8001, 0x7886,
- 0x7a8e, 0x7b92, 0x7c8a, 0x7898, 0xa084, 0xfcff, 0x789a, 0x0078,
- 0x129d, 0x7898, 0xa085, 0x0100, 0x789a, 0x0078, 0x11ba, 0x2009,
- 0x3559, 0x210c, 0x2011, 0x0410, 0x0078, 0x11b8, 0x2009, 0x3541,
- 0x210c, 0x0078, 0x11b9, 0x2009, 0x3542, 0x210c, 0x0078, 0x11b9,
- 0x2061, 0x3540, 0x610c, 0x6210, 0x0078, 0x11b8, 0x2009, 0x3545,
- 0x210c, 0x0078, 0x11b9, 0x2009, 0x3546, 0x210c, 0x0078, 0x11b9,
- 0x2009, 0x3547, 0x210c, 0x0078, 0x11b9, 0x2009, 0x3548, 0x210c,
- 0x0078, 0x11b9, 0x7908, 0x7a0c, 0x0078, 0x11b8, 0x71c4, 0x8107,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8, 0x3600, 0x6a00,
- 0x6804, 0xa084, 0x0008, 0x0040, 0x12e0, 0x6b08, 0x0078, 0x12e1,
- 0x6b0c, 0x0078, 0x11b7, 0x77c4, 0x1078, 0x1692, 0x2091, 0x8000,
- 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x11b7, 0x77c4,
- 0x1078, 0x1692, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10, 0x2091,
- 0x8001, 0x0078, 0x11b7, 0x71c4, 0xa182, 0x0010, 0x00c8, 0x11b2,
- 0x1078, 0x1abc, 0x0078, 0x11b7, 0x71c4, 0xa182, 0x0010, 0x00c8,
- 0x11b2, 0x2011, 0x3541, 0x2204, 0x007e, 0x2112, 0x1078, 0x1a75,
- 0x017f, 0x0078, 0x11b9, 0x71c4, 0x2011, 0x1331, 0x20a9, 0x0008,
- 0x2204, 0xa106, 0x0040, 0x1323, 0x8210, 0x0070, 0x1321, 0x0078,
- 0x1318, 0x0078, 0x11b2, 0xa292, 0x1331, 0x027e, 0x2011, 0x3542,
- 0x2204, 0x2112, 0x017f, 0x007e, 0x1078, 0x1a81, 0x017f, 0x0078,
- 0x11b9, 0x03e8, 0x00fa, 0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032,
- 0x004b, 0x2061, 0x3540, 0x610c, 0x6210, 0x70c4, 0x600e, 0x70c8,
- 0x6012, 0x0078, 0x11b8, 0x2061, 0x3540, 0x6114, 0x70c4, 0x6016,
- 0x0078, 0x11b9, 0x71c4, 0x2011, 0x0004, 0x2019, 0x1212, 0xa186,
- 0x0028, 0x0040, 0x1363, 0x2011, 0x0005, 0x2019, 0x1212, 0xa186,
- 0x0032, 0x0040, 0x1363, 0x2011, 0x0006, 0x2019, 0x1313, 0xa186,
- 0x003c, 0x00c0, 0x11b2, 0x2061, 0x3540, 0x6018, 0x007e, 0x611a,
- 0x23b8, 0x1078, 0x1a92, 0x1078, 0x33ba, 0x017f, 0x0078, 0x11b9,
- 0x71c4, 0xa184, 0xffcf, 0x00c0, 0x11b2, 0x2011, 0x3547, 0x2204,
- 0x2112, 0x007e, 0x1078, 0x1ab4, 0x017f, 0x0078, 0x11b9, 0x71c4,
- 0xa182, 0x0010, 0x00c8, 0x11b2, 0x2011, 0x3548, 0x2204, 0x007e,
- 0x2112, 0x1078, 0x1aa3, 0x017f, 0x0078, 0x11b9, 0x71c4, 0x72c8,
- 0xa184, 0xfffd, 0x00c0, 0x11b1, 0xa284, 0xfffd, 0x00c0, 0x11b1,
- 0x2100, 0x7908, 0x780a, 0x2200, 0x7a0c, 0x780e, 0x0078, 0x11b8,
- 0x71c4, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa0e8,
- 0x3600, 0x2019, 0x0000, 0x72c8, 0x6800, 0x007e, 0xa226, 0x0040,
- 0x13cf, 0x6a02, 0xa484, 0x2000, 0x0040, 0x13b8, 0xa39d, 0x0010,
- 0xa484, 0x1000, 0x0040, 0x13be, 0xa39d, 0x0008, 0xa484, 0x4000,
- 0x0040, 0x13cf, 0x810f, 0xa284, 0x4000, 0x0040, 0x13cb, 0x1078,
- 0x1ad6, 0x0078, 0x13cf, 0x1078, 0x1ac8, 0x0078, 0x13cf, 0x72cc,
- 0x82ff, 0x0040, 0x1401, 0x6808, 0xa206, 0x0040, 0x1401, 0xa2a4,
- 0x00ff, 0x2061, 0x3540, 0x6118, 0xa186, 0x0028, 0x0040, 0x13e8,
- 0xa186, 0x0032, 0x0040, 0x13ee, 0xa186, 0x003c, 0x0040, 0x13f4,
- 0xa482, 0x0064, 0x0048, 0x13fe, 0x0078, 0x13f8, 0xa482, 0x0050,
- 0x0048, 0x13fe, 0x0078, 0x13f8, 0xa482, 0x0043, 0x0048, 0x13fe,
- 0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x11b3, 0x6a0a, 0xa39d,
- 0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078,
- 0x11b7, 0x77c4, 0x1078, 0x1692, 0x2091, 0x8000, 0x6a14, 0x6b1c,
- 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078,
- 0x11b7, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x11b2,
- 0x1078, 0x1ae4, 0x0078, 0x11b7, 0x77c4, 0x1078, 0x1692, 0x2091,
- 0x8000, 0x6a08, 0xa295, 0x0002, 0x6a0a, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x11b8, 0x77c4, 0x1078, 0x1692, 0x2091, 0x8000, 0x6a08,
- 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1441, 0x1078,
- 0x1a19, 0x2091, 0x8001, 0x2708, 0x0078, 0x11b8, 0x77c4, 0x1078,
- 0x1692, 0x2091, 0x8000, 0x6a08, 0xa295, 0x0004, 0x6a0a, 0x6804,
- 0xa005, 0x0040, 0x1455, 0x1078, 0x1a19, 0x2091, 0x8001, 0x2708,
- 0x0078, 0x11b8, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051,
- 0x0020, 0x2091, 0x8000, 0x1078, 0x169f, 0x2091, 0x8001, 0x2708,
- 0x6a08, 0x0078, 0x11b8, 0x77c4, 0x72c8, 0x73cc, 0x77c6, 0x72ca,
- 0x73ce, 0x1078, 0x1718, 0x00c0, 0x1489, 0x6818, 0xa005, 0x0040,
- 0x1483, 0x2708, 0x1078, 0x1af4, 0x00c0, 0x1483, 0x7817, 0xffff,
- 0x2091, 0x8001, 0x007c, 0x2091, 0x8001, 0x2001, 0x4005, 0x0078,
- 0x11bc, 0x2091, 0x8001, 0x0078, 0x11ba, 0x77c4, 0x77c6, 0x2041,
- 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
- 0x169f, 0x2061, 0x3540, 0x60a3, 0x0003, 0x67b6, 0x60a7, 0x0000,
- 0x7817, 0xffff, 0x2091, 0x8001, 0x1078, 0x1a19, 0x007c, 0x77c8,
- 0x77ca, 0x77c4, 0x77c6, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2061,
- 0x3540, 0x60a3, 0x0002, 0x60a7, 0x0000, 0x67b6, 0x7817, 0xffff,
- 0x1078, 0x1a19, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0004,
- 0x2051, 0x0010, 0x2091, 0x8000, 0x1078, 0x169f, 0x70c8, 0x6836,
- 0x8738, 0xa784, 0x0007, 0x00c0, 0x14c4, 0x2091, 0x8001, 0x007c,
- 0x7898, 0xa084, 0x0003, 0x00c0, 0x14f4, 0x2039, 0x0000, 0x2041,
- 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078, 0x1692, 0x2091,
- 0x8000, 0x6808, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784,
- 0x0007, 0x00c0, 0x14dd, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f,
- 0xa784, 0x0f00, 0x00c0, 0x14dd, 0x2091, 0x8000, 0x2069, 0x0100,
- 0x6830, 0xa084, 0x0040, 0x0040, 0x151d, 0x684b, 0x0004, 0x20a9,
- 0x0014, 0x6848, 0xa084, 0x0004, 0x0040, 0x150a, 0x0070, 0x150a,
- 0x0078, 0x1501, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084,
- 0x0001, 0x0040, 0x1517, 0x0070, 0x1517, 0x0078, 0x150e, 0x20a9,
- 0x00fa, 0x0070, 0x151d, 0x0078, 0x1519, 0x2079, 0x3500, 0x7817,
- 0x0001, 0x2061, 0x3540, 0x60a3, 0x0001, 0x60a7, 0x0000, 0x60c3,
- 0x000f, 0x7898, 0xa085, 0x0002, 0x789a, 0x6808, 0xa084, 0xfffd,
- 0x680a, 0x681b, 0x0046, 0x2091, 0x8001, 0x007c, 0x7898, 0xa084,
- 0xfffd, 0x789a, 0xa084, 0x0001, 0x00c0, 0x1540, 0x1078, 0x1760,
- 0x71c4, 0x71c6, 0x794a, 0x007c, 0x74c4, 0x73c8, 0x72cc, 0x74c6,
- 0x73ca, 0x72ce, 0x2079, 0x3500, 0x2009, 0x0040, 0x1078, 0x166f,
- 0x0040, 0x1586, 0x1078, 0x163f, 0x0040, 0x155a, 0x1078, 0x1678,
- 0x0078, 0x1586, 0x6010, 0x2091, 0x8001, 0x7817, 0xffff, 0x2009,
- 0x3568, 0x200b, 0x0005, 0x8108, 0x200b, 0x0000, 0x8108, 0x230a,
- 0x8108, 0x220a, 0x8108, 0x240a, 0x8108, 0x200a, 0x8108, 0x200b,
- 0x0000, 0x8108, 0x2c0a, 0xa02e, 0x2530, 0x0e7e, 0x1078, 0x2f13,
- 0x0e7f, 0x6592, 0x65a2, 0x6696, 0x66a6, 0x60ab, 0x0000, 0x60af,
- 0x0000, 0x2091, 0x8001, 0x1078, 0x1a19, 0x007c, 0x70c3, 0x4005,
- 0x0078, 0x11bd, 0x71c4, 0x70c7, 0x0000, 0x7906, 0x0078, 0x11ba,
- 0x71c4, 0x71c6, 0x2168, 0x0078, 0x1597, 0x2069, 0x1000, 0x690c,
- 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1599, 0xa285,
- 0x0000, 0x00c0, 0x15a7, 0x70c3, 0x4000, 0x0078, 0x15a9, 0x70c3,
- 0x4003, 0x70ca, 0x0078, 0x11bd, 0x71c4, 0x72c8, 0x73cc, 0x2100,
- 0xa184, 0xfffc, 0x00c0, 0x11c6, 0x2100, 0x0079, 0x15b7, 0x15ce,
- 0x15e3, 0x15e5, 0x15e7, 0x70c3, 0x4003, 0x71ce, 0x72d2, 0x73d6,
- 0x0078, 0x15ca, 0x70c3, 0x4000, 0x70cf, 0x0000, 0x70d3, 0x0000,
- 0x70d7, 0x0000, 0x77c6, 0x71ca, 0x0078, 0x11ba, 0x2031, 0x15e9,
- 0x2624, 0x8630, 0x2412, 0x2204, 0xa446, 0x00c0, 0x15bb, 0xa484,
- 0xffff, 0x00c0, 0x15d0, 0x2031, 0x15e9, 0x8210, 0x8319, 0xa384,
- 0xffff, 0x00c0, 0x15d0, 0x0078, 0x15c2, 0x0078, 0x15c2, 0x0078,
- 0x15c2, 0x5555, 0xaaaa, 0xffff, 0x0000, 0x7960, 0x71c6, 0x71c4,
- 0xa182, 0x0003, 0x00c8, 0x11b2, 0x7962, 0x0078, 0x11ba, 0x7960,
- 0x71c6, 0x0078, 0x11ba, 0x7954, 0x71c6, 0x71c4, 0x7956, 0x7958,
- 0x71ca, 0x71c8, 0x795a, 0x795c, 0x71ce, 0x71cc, 0x795e, 0x0078,
- 0x11ba, 0x7954, 0x71c6, 0x7958, 0x71ca, 0x795c, 0x71ce, 0x0078,
- 0x11ba, 0x700c, 0xa084, 0x007f, 0x0040, 0x161d, 0x7007, 0x0004,
- 0x7004, 0xa084, 0x0004, 0x00c0, 0x1618, 0x7017, 0x0000, 0x7112,
- 0x721a, 0x731e, 0x8108, 0x810c, 0x81a9, 0x8c98, 0x20a1, 0x0030,
- 0x6080, 0x20a2, 0x53a6, 0x780c, 0xa085, 0x0000, 0x7002, 0x7007,
- 0x0001, 0x7108, 0x8104, 0x00c8, 0x1631, 0x7007, 0x0002, 0xa184,
- 0x000c, 0x710c, 0xa184, 0x0300, 0x7003, 0x0000, 0x007c, 0x700c,
- 0xa084, 0x007f, 0x0040, 0x164b, 0x7007, 0x0004, 0x7004, 0xa084,
- 0x0004, 0x00c0, 0x1646, 0x7017, 0x0000, 0x7112, 0x721a, 0x731e,
- 0x2099, 0x0030, 0x8108, 0x81ac, 0x780c, 0xa085, 0x0001, 0x7002,
- 0x7007, 0x0001, 0x7008, 0x800c, 0x00c8, 0x165a, 0x7007, 0x0002,
- 0xa08c, 0x000c, 0x00c0, 0x166c, 0x710c, 0xa184, 0x0300, 0x00c0,
- 0x166c, 0x2ca0, 0x53a5, 0xa006, 0x7003, 0x0000, 0x007c, 0x7850,
- 0xa065, 0x0040, 0x1677, 0x2c04, 0x7852, 0x2063, 0x0000, 0x007c,
- 0x0f7e, 0x2079, 0x3500, 0x7850, 0x2062, 0x2c00, 0x7852, 0x0f7f,
- 0x007c, 0x2011, 0x4000, 0x7a52, 0x2019, 0x0410, 0x8319, 0x0040,
- 0x168f, 0xa280, 0x002f, 0x2012, 0x2010, 0x0078, 0x1686, 0x2013,
- 0x0000, 0x007c, 0xa784, 0x0f00, 0x800c, 0xa784, 0x0007, 0x8003,
- 0x8003, 0x8003, 0x8003, 0xa105, 0xa0e8, 0x3680, 0x007c, 0x1078,
- 0x1692, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xffef,
- 0xa80d, 0x690a, 0x2009, 0x354f, 0x210c, 0x6804, 0xa005, 0x0040,
- 0x16bc, 0xa116, 0x00c0, 0x16bc, 0x2060, 0x6000, 0x6806, 0x017e,
- 0x200b, 0x0000, 0x0078, 0x16bf, 0x2009, 0x0000, 0x017e, 0x6804,
- 0xa065, 0x0040, 0x16ce, 0x6000, 0x6806, 0x1078, 0x16df, 0x1078,
- 0x17cb, 0x6810, 0x8001, 0x6812, 0x00c0, 0x16bf, 0x017f, 0x6902,
- 0x6906, 0x007c, 0xa065, 0x0040, 0x16de, 0x6098, 0x609b, 0x0000,
- 0x2008, 0x1078, 0x1678, 0x2100, 0x0078, 0x16d2, 0x007c, 0x6003,
- 0x0103, 0x20a9, 0x001c, 0xac80, 0x0004, 0x20a0, 0x2001, 0x0000,
- 0x40a4, 0x6828, 0x6016, 0x682c, 0x601e, 0x007c, 0x0e7e, 0x2071,
- 0x3540, 0x7040, 0xa08c, 0x0080, 0x00c0, 0x16fc, 0xa088, 0x3580,
- 0x2d0a, 0x8000, 0x7042, 0xa006, 0x0e7f, 0x007c, 0x0e7e, 0x2071,
- 0x3540, 0x2009, 0x3580, 0x7240, 0x8221, 0x8211, 0x0048, 0x1716,
- 0x2104, 0x8108, 0xad06, 0x00c0, 0x1705, 0x8119, 0x211e, 0x8108,
- 0x8318, 0x8211, 0x00c8, 0x170e, 0x7442, 0xa006, 0x0e7f, 0x007c,
- 0x1078, 0x1692, 0x2091, 0x8000, 0x6804, 0x781e, 0xa065, 0x0040,
- 0x175f, 0x0078, 0x1729, 0x2c00, 0x781e, 0x6000, 0xa065, 0x0040,
- 0x175f, 0x600c, 0xa306, 0x00c0, 0x1723, 0x6008, 0xa206, 0x00c0,
- 0x1723, 0x2c28, 0x2001, 0x354f, 0x2004, 0xac06, 0x0040, 0x175f,
- 0x6804, 0xac06, 0x00c0, 0x1746, 0x6000, 0x2060, 0x6806, 0xa005,
- 0x00c0, 0x1746, 0x6803, 0x0000, 0x0078, 0x1750, 0x6400, 0x781c,
- 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1750, 0x2c00, 0x6802,
- 0x2560, 0x1078, 0x16df, 0x6017, 0x0005, 0x601f, 0x0020, 0x1078,
- 0x17cb, 0x6810, 0x8001, 0x6812, 0x2001, 0xffff, 0xa005, 0x007c,
- 0x2039, 0x0000, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
- 0x2091, 0x8000, 0x1078, 0x169f, 0x8738, 0xa784, 0x0007, 0x00c0,
- 0x176a, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00,
- 0x00c0, 0x176a, 0x2091, 0x8001, 0x007c, 0x2061, 0x0000, 0x6018,
- 0xa084, 0x0001, 0x00c0, 0x178a, 0x78ac, 0x78af, 0x0000, 0xa005,
- 0x00c0, 0x178b, 0x007c, 0xa08c, 0xfff0, 0x0040, 0x1791, 0x1078,
- 0x1ba5, 0x0079, 0x1793, 0x17a3, 0x17a5, 0x17ab, 0x17af, 0x17a3,
- 0x17b3, 0x17a3, 0x17a3, 0x17a3, 0x17a3, 0x17b9, 0x17bd, 0x17a3,
- 0x17a3, 0x17a3, 0x17a3, 0x1078, 0x1ba5, 0x1078, 0x1760, 0x2001,
- 0x8001, 0x0078, 0x17c3, 0x2001, 0x8003, 0x0078, 0x17c3, 0x2001,
- 0x8004, 0x0078, 0x17c3, 0x1078, 0x1760, 0x2001, 0x8006, 0x0078,
- 0x17c3, 0x2001, 0x800c, 0x0078, 0x17c3, 0x1078, 0x1760, 0x2001,
- 0x800d, 0x0078, 0x17c3, 0x70c2, 0x2061, 0x0000, 0x601b, 0x0001,
- 0x2091, 0x4080, 0x007c, 0x2c04, 0x6082, 0x2c08, 0x2063, 0x0000,
- 0x7864, 0x8000, 0x7866, 0x7868, 0xa005, 0x796a, 0x0040, 0x17db,
- 0x2c02, 0x0078, 0x17dc, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x3500,
- 0x6883, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6064, 0x8000, 0x6066,
- 0x6068, 0xa005, 0x616a, 0x0040, 0x17f0, 0x2d02, 0x0078, 0x17f1,
- 0x616e, 0x0c7f, 0x007c, 0x1078, 0x1804, 0x0040, 0x1803, 0x0c7e,
- 0x6098, 0xa065, 0x0040, 0x17fe, 0x1078, 0x16d2, 0x0c7f, 0x609b,
- 0x0000, 0x1078, 0x1678, 0x007c, 0x786c, 0xa065, 0x0040, 0x1816,
- 0x2091, 0x8000, 0x7864, 0x8001, 0x7866, 0x2c04, 0x786e, 0xa005,
- 0x00c0, 0x1814, 0x786a, 0x8000, 0x2091, 0x8001, 0x007c, 0x7898,
- 0xa005, 0x00c0, 0x1865, 0x7974, 0x70d0, 0x0005, 0x0005, 0x72d0,
- 0xa206, 0x00c0, 0x181c, 0x2200, 0xa106, 0x00c0, 0x1833, 0x7804,
- 0xa005, 0x0040, 0x1865, 0x7807, 0x0000, 0x0068, 0x1865, 0x2091,
- 0x4080, 0x0078, 0x1865, 0x1078, 0x166f, 0x0040, 0x1865, 0x7a7c,
- 0x7b78, 0x8107, 0x8004, 0x8004, 0xa210, 0xa399, 0x0000, 0x2009,
- 0x0040, 0x1078, 0x163f, 0x0040, 0x185c, 0x1078, 0x1678, 0x7880,
- 0x8000, 0x7882, 0xa086, 0x0002, 0x00c0, 0x1865, 0x2091, 0x8000,
- 0x78af, 0x0002, 0x7883, 0x0000, 0x7898, 0xa085, 0x0003, 0x789a,
- 0x2091, 0x8001, 0x0078, 0x1865, 0x7883, 0x0000, 0x1078, 0x1992,
- 0x6000, 0xa084, 0x0007, 0x0079, 0x1866, 0x007c, 0x186e, 0x187d,
- 0x189d, 0x186e, 0x18af, 0x186e, 0x186e, 0x186e, 0x2039, 0x0400,
- 0x78a8, 0xa705, 0x78aa, 0x6004, 0xa705, 0x6006, 0x1078, 0x18ed,
- 0x6018, 0x78a6, 0x1078, 0x197a, 0x007c, 0x78a8, 0xa084, 0x0100,
- 0x0040, 0x1884, 0x0078, 0x186e, 0x78ab, 0x0000, 0x6000, 0x8007,
- 0xa084, 0x00ff, 0x789e, 0x8001, 0x609b, 0x0000, 0x0040, 0x189a,
- 0x1078, 0x18ed, 0x0040, 0x189a, 0x78a8, 0xa085, 0x0100, 0x78aa,
- 0x0078, 0x189c, 0x1078, 0x1911, 0x007c, 0x78a8, 0xa08c, 0x0e00,
- 0x00c0, 0x18a6, 0xa084, 0x0100, 0x00c0, 0x18a8, 0x0078, 0x186e,
- 0x1078, 0x18ed, 0x00c0, 0x18ae, 0x1078, 0x1911, 0x007c, 0x78a8,
- 0xa084, 0x0100, 0x0040, 0x18b6, 0x0078, 0x186e, 0x78ab, 0x0000,
- 0x6710, 0x20a9, 0x0001, 0x6014, 0xa084, 0x00ff, 0xa005, 0x0040,
- 0x18d3, 0xa7bc, 0xff00, 0x20a9, 0x0008, 0xa08e, 0x0001, 0x0040,
- 0x18d3, 0x2039, 0x0000, 0x20a9, 0x0080, 0xa08e, 0x0002, 0x0040,
- 0x18d3, 0x0078, 0x18ea, 0x1078, 0x1692, 0x2d00, 0x2091, 0x8000,
- 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a,
- 0x2d00, 0xa080, 0x0010, 0x2068, 0x2091, 0x8001, 0x0070, 0x18ea,
- 0x0078, 0x18d6, 0x1078, 0x1678, 0x007c, 0x78a0, 0xa06d, 0x00c0,
- 0x18f8, 0x2c00, 0x78a2, 0x78a6, 0x609b, 0x0000, 0x0078, 0x1904,
- 0x2c00, 0x689a, 0x609b, 0x0000, 0x78a2, 0x2d00, 0x6002, 0x78a4,
- 0xad06, 0x00c0, 0x1904, 0x6002, 0x789c, 0x8001, 0x789e, 0x00c0,
- 0x1910, 0x78a8, 0xa084, 0x0000, 0x78aa, 0x78a4, 0x2060, 0xa006,
- 0x007c, 0xa02e, 0x2530, 0x6118, 0xa184, 0x0060, 0x619e, 0x0040,
- 0x191d, 0x0e7e, 0x1078, 0x2f13, 0x0e7f, 0x6592, 0x65a2, 0x6696,
- 0x66a6, 0x60ab, 0x0000, 0x60af, 0x0000, 0x6710, 0x1078, 0x1692,
- 0x2091, 0x8000, 0x6808, 0xa084, 0x0001, 0x0040, 0x193f, 0x2091,
- 0x8001, 0x1078, 0x16df, 0x2091, 0x8000, 0x1078, 0x17cb, 0x2091,
- 0x8001, 0x78a3, 0x0000, 0x78a7, 0x0000, 0x0078, 0x1979, 0x6020,
- 0xa096, 0x0001, 0x00c0, 0x1946, 0x8000, 0x6022, 0x6a10, 0x6814,
- 0x2091, 0x8001, 0xa202, 0x0048, 0x1955, 0x0040, 0x1955, 0x2039,
- 0x0200, 0x1078, 0x197a, 0x0078, 0x1979, 0x2c08, 0x2091, 0x8000,
- 0x6800, 0xa065, 0x0040, 0x195d, 0x6102, 0x6902, 0x00c0, 0x1961,
- 0x6906, 0x2160, 0x6003, 0x0000, 0x6810, 0x8000, 0x6812, 0x2091,
- 0x8001, 0x6808, 0xa08c, 0x0040, 0x0040, 0x1973, 0xa086, 0x0040,
- 0x680a, 0x1078, 0x16ee, 0x1078, 0x1a19, 0x78a7, 0x0000, 0x78a3,
- 0x0000, 0x007c, 0x6004, 0xa705, 0x6006, 0x2091, 0x8000, 0x1078,
- 0x17cb, 0x2091, 0x8001, 0x78a4, 0xa065, 0x0040, 0x198d, 0x6098,
- 0x78a6, 0x609b, 0x0000, 0x0078, 0x197d, 0x78a3, 0x0000, 0x78a7,
- 0x0000, 0x007c, 0x7970, 0x7874, 0x8000, 0xa10a, 0x00c8, 0x1999,
- 0xa006, 0x7876, 0x70d2, 0x7804, 0xa005, 0x0040, 0x19a7, 0x8001,
- 0x7806, 0x00c0, 0x19a7, 0x0068, 0x19a7, 0x2091, 0x4080, 0x007c,
- 0x0068, 0x19c2, 0x2029, 0x0000, 0x786c, 0xa065, 0x0040, 0x19bd,
- 0x1078, 0x19c3, 0x0040, 0x19bd, 0x057e, 0x1078, 0x19d9, 0x057f,
- 0x00c0, 0x19bd, 0x8528, 0x0078, 0x19ac, 0x85ff, 0x0040, 0x19c2,
- 0x2091, 0x4080, 0x007c, 0x7b84, 0x7988, 0x72d4, 0x0005, 0x0005,
- 0x70d4, 0xa206, 0x00c0, 0x19c5, 0x2200, 0xa102, 0x00c0, 0x19d3,
- 0x2300, 0xa005, 0x007c, 0x0048, 0x19d7, 0xa302, 0x007c, 0x8002,
- 0x007c, 0x1078, 0x1a0b, 0x2009, 0x001c, 0x6024, 0xa005, 0x0040,
- 0x19e3, 0x2009, 0x0040, 0x1078, 0x1611, 0x0040, 0x19fc, 0x7894,
- 0x8000, 0x7896, 0xa086, 0x0002, 0x00c0, 0x1a0a, 0x2091, 0x8000,
- 0x78af, 0x0003, 0x7897, 0x0000, 0x7898, 0xa085, 0x0300, 0x789a,
- 0x2091, 0x8001, 0x0078, 0x1a0a, 0x7897, 0x0000, 0x1078, 0x17f3,
- 0x7984, 0x7888, 0x8000, 0xa10a, 0x00c8, 0x1a07, 0xa006, 0x788a,
- 0x70d6, 0xa006, 0x007c, 0x8107, 0x8004, 0x8004, 0x7a90, 0x7b8c,
- 0xa210, 0xa399, 0x0000, 0x007c, 0x2009, 0x3568, 0x2091, 0x8000,
- 0x200a, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3540, 0x2091, 0x8000,
- 0x2104, 0xa086, 0x0000, 0x00c0, 0x1a34, 0x2009, 0x3512, 0x2104,
- 0xa005, 0x00c0, 0x1a34, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x1a34,
- 0x0018, 0x1a34, 0x781b, 0x0044, 0x2091, 0x8001, 0x0f7f, 0x007c,
- 0x127e, 0x2091, 0x2300, 0x2071, 0x3540, 0x2079, 0x0100, 0x2019,
- 0x2dd8, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040, 0x1a50, 0x789a,
- 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, 0x0078, 0x1a43,
- 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x0220,
- 0x0070, 0x1a5c, 0x0078, 0x1a54, 0x7003, 0x0000, 0x1078, 0x1b5b,
- 0x7004, 0xa084, 0x000f, 0xa085, 0x6280, 0x7806, 0x780f, 0x9200,
- 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x0038, 0x7047, 0x357f,
- 0x7043, 0x0000, 0x127f, 0x2000, 0x007c, 0xa18c, 0x000f, 0x2011,
- 0x0101, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x1078, 0x1b5b,
- 0x007c, 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x0070, 0x1a8a,
- 0x0078, 0x1a85, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105,
- 0x2012, 0x007c, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x0070,
- 0x1a9b, 0x0078, 0x1a96, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f,
- 0xa205, 0x200a, 0x007c, 0x2011, 0x0101, 0x20a9, 0x000c, 0x810b,
- 0x0070, 0x1aac, 0x0078, 0x1aa7, 0xa18c, 0xf000, 0x2204, 0xa084,
- 0x0fff, 0xa105, 0x2012, 0x007c, 0x2011, 0x0102, 0x2204, 0xa084,
- 0xffcf, 0xa105, 0x2012, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020,
- 0x0c7e, 0x2061, 0x0100, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c,
- 0x8103, 0x8003, 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a,
- 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003,
- 0xa080, 0x0022, 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0xa085,
- 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x8103, 0x8003, 0xa080, 0x0020,
- 0x0c7e, 0x2061, 0x0100, 0x609a, 0x60a4, 0x62ae, 0x2010, 0x60a4,
- 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e,
- 0x6818, 0xa005, 0x0040, 0x1b39, 0x2061, 0x3f80, 0x1078, 0x1b41,
- 0x0040, 0x1b27, 0x20a9, 0x0000, 0x2061, 0x3e80, 0x0c7e, 0x1078,
- 0x1b41, 0x0040, 0x1b13, 0x0c7f, 0x8c60, 0x0070, 0x1b11, 0x0078,
- 0x1b06, 0x0078, 0x1b39, 0x007f, 0xa082, 0x3e80, 0x2071, 0x3540,
- 0x70ba, 0x601c, 0xa085, 0x0800, 0x601e, 0x71b6, 0x60a7, 0x0000,
- 0x2001, 0x0004, 0x70a2, 0x1078, 0x1a14, 0x0078, 0x1b35, 0x2071,
- 0x3540, 0x601c, 0xa085, 0x0800, 0x601e, 0x71b6, 0x60a7, 0x0000,
- 0x2001, 0x0006, 0x70a2, 0x1078, 0x1a14, 0x2001, 0x0000, 0x0078,
- 0x1b3b, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f,
- 0x007c, 0x2c04, 0xa005, 0x0040, 0x1b58, 0x2060, 0x600c, 0xa306,
- 0x00c0, 0x1b55, 0x6008, 0xa206, 0x00c0, 0x1b55, 0x6010, 0xa106,
- 0x00c0, 0x1b55, 0xa006, 0x0078, 0x1b5a, 0x6000, 0x0078, 0x1b42,
- 0xa085, 0x0001, 0x007c, 0x2011, 0x3541, 0x220c, 0xa18c, 0x000f,
- 0x2011, 0x013b, 0x2204, 0xa084, 0x0100, 0x0040, 0x1b6a, 0x2021,
- 0xff80, 0x2122, 0x007c, 0x0e7e, 0x68e4, 0xa08c, 0x0020, 0x0040,
- 0x1ba3, 0xa084, 0x0006, 0x00c0, 0x1ba3, 0x6010, 0x8007, 0xa084,
- 0x000f, 0x8003, 0x8003, 0x8003, 0xa0f0, 0x3600, 0x7004, 0xa084,
- 0x000a, 0x00c0, 0x1ba3, 0x7108, 0xa194, 0xff00, 0x0040, 0x1ba3,
- 0xa18c, 0x00ff, 0x2001, 0x0019, 0xa106, 0x0040, 0x1b96, 0x2001,
- 0x0032, 0xa106, 0x0040, 0x1b9a, 0x0078, 0x1b9e, 0x2009, 0x0020,
- 0x0078, 0x1ba0, 0x2009, 0x003f, 0x0078, 0x1ba0, 0x2011, 0x0000,
- 0x2100, 0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x1ba5, 0x007e,
- 0x2071, 0x0000, 0x7018, 0xa084, 0x0001, 0x00c0, 0x1baa, 0x007f,
- 0x2e08, 0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002,
- 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x007f, 0x2070,
- 0x007f, 0x0078, 0x1bc1, 0x107e, 0x007e, 0x127e, 0x2091, 0x2300,
- 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0xa594, 0x003f, 0xa484, 0x4000,
- 0x0040, 0x1bd8, 0xa784, 0x007c, 0x00c0, 0x2d9c, 0x1078, 0x1ba5,
- 0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x1be0, 0x1078, 0x1ba5,
- 0x8507, 0xa084, 0x000f, 0x0079, 0x1be5, 0x1fea, 0x209a, 0x20c0,
- 0x22e6, 0x256b, 0x25b3, 0x25ea, 0x2665, 0x26bf, 0x2744, 0x1c0b,
- 0x1bf5, 0x1e53, 0x1f1d, 0x254a, 0x1bf5, 0x1078, 0x1ba5, 0x0018,
- 0x1bc8, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c, 0x7003,
- 0x0000, 0x703f, 0x0000, 0x7030, 0xa005, 0x0040, 0x1c09, 0x7033,
- 0x0000, 0x0018, 0x1bc8, 0x705c, 0xa005, 0x00c0, 0x1cb6, 0x70a0,
- 0xa084, 0x0007, 0x0079, 0x1c14, 0x1cd6, 0x1c1c, 0x1c2a, 0x1c4b,
- 0x1c71, 0x1c9d, 0x1c9b, 0x1c1c, 0x7808, 0xa084, 0xfffd, 0x780a,
- 0x2009, 0x0046, 0x1078, 0x2412, 0x00c0, 0x1c28, 0x7003, 0x0004,
- 0x0078, 0x1bf7, 0x1078, 0x2d5e, 0x00c0, 0x1c49, 0x70b4, 0x8007,
- 0x789b, 0x007e, 0x78aa, 0x789b, 0x0010, 0x78ab, 0x000c, 0x789b,
- 0x0060, 0x78ab, 0x0001, 0x785b, 0x0004, 0x2009, 0x00f7, 0x1078,
- 0x2410, 0x00c0, 0x1c49, 0x7003, 0x0004, 0x70c3, 0x000f, 0x7033,
- 0x3570, 0x0078, 0x1bf7, 0x1078, 0x2d5e, 0x00c0, 0x1c6f, 0x71b4,
- 0x8107, 0x789b, 0x007e, 0x78aa, 0x789b, 0x0010, 0xa18c, 0x0007,
- 0xa18d, 0x00c0, 0x79aa, 0x78ab, 0x0006, 0x789b, 0x0060, 0x78ab,
- 0x0002, 0x785b, 0x0004, 0x2009, 0x00f7, 0x1078, 0x2410, 0x00c0,
- 0x1c6f, 0x7003, 0x0004, 0x70c3, 0x000f, 0x7033, 0x3570, 0x0078,
- 0x1bf7, 0x1078, 0x2d5e, 0x00c0, 0x1c99, 0x71b4, 0x8107, 0x789b,
- 0x007e, 0x78aa, 0x789b, 0x0010, 0xa18c, 0x0007, 0xa18d, 0x00c0,
- 0x79aa, 0x78ab, 0x0020, 0x71b8, 0x79aa, 0x78ab, 0x000d, 0x789b,
- 0x0060, 0x78ab, 0x0004, 0x785b, 0x0004, 0x2009, 0x00f7, 0x1078,
- 0x2410, 0x00c0, 0x1c99, 0x7003, 0x0004, 0x70c3, 0x000f, 0x7033,
- 0x3570, 0x0078, 0x1bf7, 0x0078, 0x1c4b, 0x1078, 0x2d5e, 0x00c0,
- 0x1bf7, 0x70bc, 0x2068, 0x789b, 0x0010, 0x6f10, 0x1078, 0x2ca1,
- 0x2c50, 0x6810, 0xa084, 0x0007, 0xa085, 0x0080, 0x78aa, 0x6e18,
- 0x2041, 0x0001, 0x2001, 0x0004, 0x0078, 0x1dde, 0x1078, 0x2d5e,
- 0x00c0, 0x1bf7, 0x789b, 0x0010, 0x705c, 0x2068, 0x6f10, 0x1078,
- 0x2ca1, 0x2c50, 0x6008, 0xa085, 0x0010, 0x600a, 0x6810, 0xa084,
- 0x0007, 0xa085, 0x0080, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001,
- 0x1078, 0x2dc5, 0x2001, 0x0003, 0x0078, 0x1dc9, 0x0018, 0x1bc8,
- 0x7440, 0xa485, 0x0000, 0x0040, 0x1cf0, 0xa080, 0x3580, 0x2030,
- 0x7144, 0x8108, 0xa12a, 0x0048, 0x1ce7, 0x2009, 0x3580, 0x2164,
- 0x6504, 0x85ff, 0x00c0, 0x1cfd, 0x8421, 0x00c0, 0x1ce1, 0x7146,
- 0x7003, 0x0000, 0x703f, 0x0000, 0x0078, 0x1bf7, 0x7640, 0xa6b0,
- 0x3580, 0x7144, 0x2600, 0x0078, 0x1cec, 0x7146, 0x2568, 0x2558,
- 0x753e, 0x2c50, 0x6034, 0xa085, 0x0000, 0x00c0, 0x1cfa, 0x6708,
- 0x7736, 0xa784, 0x013f, 0x0040, 0x1d2f, 0xa784, 0x0021, 0x00c0,
- 0x1cfa, 0xa784, 0x0002, 0x0040, 0x1d1c, 0xa784, 0x0004, 0x0040,
- 0x1cfa, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0008, 0x00c0, 0x1cfa,
- 0xa784, 0x0010, 0x00c0, 0x1cfa, 0xa784, 0x0100, 0x0040, 0x1d2f,
- 0x6018, 0xa005, 0x00c0, 0x1cfa, 0xa7bc, 0xfeff, 0x670a, 0x681f,
- 0x0000, 0x6e18, 0xa684, 0x000e, 0x6118, 0x0040, 0x1d3f, 0x601c,
- 0xa102, 0x0048, 0x1d42, 0x0040, 0x1d42, 0x0078, 0x1cf6, 0x81ff,
- 0x00c0, 0x1cf6, 0xa784, 0x0080, 0x00c0, 0x1d48, 0x700c, 0x6022,
- 0xa7bc, 0xff7f, 0x670a, 0x6b10, 0x8307, 0xa084, 0x000f, 0x8003,
- 0x8003, 0x8003, 0xa080, 0x3600, 0x2060, 0x2048, 0x704a, 0x6000,
- 0x704e, 0x6004, 0x7052, 0x2a60, 0x0018, 0x1bc8, 0x789b, 0x0010,
- 0xa046, 0x1078, 0x2d5e, 0x00c0, 0x1bf7, 0x6b10, 0xa39c, 0x0007,
- 0xa39d, 0x00c0, 0x704c, 0xa084, 0x8000, 0x0040, 0x1d73, 0xa684,
- 0x0001, 0x0040, 0x1d75, 0xa39c, 0xffbf, 0xa684, 0x0010, 0x0040,
- 0x1d7b, 0xa39d, 0x0020, 0x7baa, 0x8840, 0xa684, 0x000e, 0x00c0,
- 0x1d86, 0xa7bd, 0x0010, 0x670a, 0x0078, 0x1dc7, 0x714c, 0xa18c,
- 0x0800, 0x0040, 0x2902, 0x2011, 0x0021, 0x8004, 0x8004, 0x0048,
- 0x1d9d, 0x2011, 0x0022, 0x8004, 0x0048, 0x1d9d, 0x2011, 0x0020,
- 0x8004, 0x0048, 0x1d9d, 0x0040, 0x1dc7, 0x7aaa, 0x8840, 0x1078,
- 0x2d77, 0x6a10, 0x610c, 0x8108, 0xa18c, 0x00ff, 0xa1e0, 0x3e80,
- 0x2c64, 0x8cff, 0x0040, 0x1dbe, 0x6010, 0xa206, 0x00c0, 0x1da8,
- 0x60b4, 0x8001, 0x60b6, 0x00c0, 0x1da3, 0x0c7e, 0x2a60, 0x6008,
- 0xa085, 0x0100, 0x600a, 0x0c7f, 0x0078, 0x1cd6, 0x1078, 0x2d5e,
- 0x00c0, 0x1bf7, 0x2a60, 0x610e, 0x79aa, 0x8840, 0x712e, 0x2001,
- 0x0001, 0x007e, 0x7150, 0xa184, 0x0018, 0x0040, 0x1ddd, 0xa184,
- 0x0010, 0x0040, 0x1dd7, 0x1078, 0x2acc, 0x00c0, 0x1ddd, 0xa184,
- 0x0008, 0x0040, 0x1ddd, 0x1078, 0x29e6, 0x007f, 0x7002, 0xa68c,
- 0x0060, 0x88ff, 0x0040, 0x1de6, 0xa18d, 0x0004, 0x795a, 0x69b2,
- 0x789b, 0x0060, 0x2800, 0x78aa, 0x789b, 0x0061, 0x6814, 0xa085,
- 0x8000, 0x6816, 0x78aa, 0x157e, 0x137e, 0x147e, 0x20a1, 0x012c,
- 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000a, 0x2098, 0x53a6,
- 0x147f, 0x137f, 0x157f, 0x6810, 0x8007, 0x789b, 0x007e, 0x78aa,
- 0x6d90, 0x7dd6, 0x7dde, 0x6e94, 0x7ed2, 0x7eda, 0x7830, 0xa084,
- 0x00c0, 0x00c0, 0x1e15, 0x0098, 0x1e1d, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x1078, 0x2d77, 0x0078, 0x1bff, 0x7200, 0xa284, 0x0007,
- 0xa086, 0x0001, 0x00c0, 0x1e2a, 0x781b, 0x0049, 0x1078, 0x2d77,
- 0x0078, 0x1e3b, 0x6ab0, 0xa295, 0x2000, 0x7a5a, 0x781b, 0x0049,
- 0x1078, 0x2d77, 0x7200, 0x2500, 0xa605, 0x0040, 0x1e3b, 0xa284,
- 0x0007, 0x1079, 0x1e49, 0xad80, 0x0008, 0x7032, 0xa284, 0x0007,
- 0xa086, 0x0001, 0x00c0, 0x1e47, 0x6018, 0x8000, 0x601a, 0x0078,
- 0x1bf7, 0x1e51, 0x30f0, 0x30f0, 0x30df, 0x30f0, 0x1e51, 0x1e51,
- 0x1e51, 0x1078, 0x1ba5, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e,
- 0x2079, 0x3500, 0x7898, 0x0f7f, 0xa084, 0x0001, 0x0040, 0x1e79,
- 0x70a0, 0xa086, 0x0001, 0x00c0, 0x1e68, 0x70a2, 0x0078, 0x1f01,
- 0x70a0, 0xa086, 0x0005, 0x00c0, 0x1e77, 0x70bc, 0x2068, 0x6817,
- 0x0004, 0x6813, 0x0000, 0x681c, 0xa085, 0x0008, 0x681e, 0x70a3,
- 0x0000, 0x157e, 0x2011, 0x0004, 0x71a0, 0xa186, 0x0001, 0x0040,
- 0x1e9b, 0xa186, 0x0007, 0x00c0, 0x1e8b, 0x2009, 0x352b, 0x200b,
- 0x0005, 0x0078, 0x1e9b, 0x2009, 0x3513, 0x2104, 0x2009, 0x3512,
- 0x200a, 0x2009, 0x352b, 0x200b, 0x0001, 0x70a3, 0x0000, 0x70a7,
- 0x0001, 0x0078, 0x1e9d, 0x70a3, 0x0000, 0x1078, 0x2ec7, 0x20a9,
- 0x0010, 0x2039, 0x0000, 0x1078, 0x2ba6, 0xa7b8, 0x0100, 0x0070,
- 0x1eab, 0x0078, 0x1ea3, 0x7000, 0x2020, 0x0079, 0x1eaf, 0x1edd,
- 0x1ec6, 0x1ec6, 0x1eb9, 0x1edd, 0x1edd, 0x1eb7, 0x1eb7, 0x1078,
- 0x1ba5, 0x2021, 0x3557, 0x2404, 0xa005, 0x0040, 0x1ec6, 0xad06,
- 0x00c0, 0x1ec6, 0x6800, 0x2022, 0x0078, 0x1ed6, 0x681c, 0xa084,
- 0x0001, 0x00c0, 0x1ed2, 0x6f10, 0x1078, 0x2ca1, 0x1078, 0x28d9,
- 0x0078, 0x1ed6, 0x7054, 0x2060, 0x6800, 0x6002, 0x6a16, 0x681c,
- 0xa085, 0x0008, 0x681e, 0x1078, 0x17dd, 0x2021, 0x3f80, 0x1078,
- 0x1f07, 0x2021, 0x3557, 0x1078, 0x1f07, 0x20a9, 0x0000, 0x2021,
- 0x3e80, 0x1078, 0x1f07, 0x8420, 0x0070, 0x1ef0, 0x0078, 0x1ee9,
- 0x20a9, 0x0080, 0x2061, 0x3680, 0x6018, 0x6110, 0xa102, 0x6012,
- 0x601b, 0x0000, 0xace0, 0x0010, 0x0070, 0x1f00, 0x0078, 0x1ef4,
- 0x157f, 0x7003, 0x0000, 0x703f, 0x0000, 0x0078, 0x1bf7, 0x047e,
- 0x2404, 0xa005, 0x0040, 0x1f19, 0x2068, 0x6800, 0x007e, 0x6a16,
- 0x681c, 0xa085, 0x0008, 0x681e, 0x1078, 0x17dd, 0x007f, 0x0078,
- 0x1f09, 0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050,
- 0x1f23, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x1f26, 0x1f29, 0x1f9c,
- 0x1faa, 0xa282, 0x0002, 0x0040, 0x1f2f, 0x1078, 0x1ba5, 0x70a0,
- 0x70a3, 0x0000, 0x70c3, 0x0000, 0x0079, 0x1f36, 0x1f3e, 0x1f3e,
- 0x1f40, 0x1f74, 0x2908, 0x1f3e, 0x1f74, 0x1f3e, 0x1078, 0x1ba5,
- 0x77b4, 0x1078, 0x2ba6, 0x77b4, 0xa7bc, 0x0f00, 0x1078, 0x2ca1,
- 0x6018, 0xa005, 0x0040, 0x1f6b, 0x2021, 0x3f80, 0x2009, 0x0004,
- 0x2011, 0x0010, 0x1078, 0x1fc5, 0x0040, 0x1f6b, 0x157e, 0x20a9,
- 0x0000, 0x2021, 0x3e80, 0x047e, 0x2009, 0x0004, 0x2011, 0x0010,
- 0x1078, 0x1fc5, 0x047f, 0x0040, 0x1f6a, 0x8420, 0x0070, 0x1f6a,
- 0x0078, 0x1f5b, 0x157f, 0x8738, 0xa784, 0x0007, 0x00c0, 0x1f46,
- 0x0078, 0x1bff, 0x0078, 0x1bff, 0x77b4, 0x1078, 0x2ca1, 0x6018,
- 0xa005, 0x0040, 0x1f9a, 0x2021, 0x3f80, 0x2009, 0x0005, 0x2011,
- 0x0020, 0x1078, 0x1fc5, 0x0040, 0x1f9a, 0x157e, 0x20a9, 0x0000,
- 0x2021, 0x3e80, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078,
- 0x1fc5, 0x047f, 0x0040, 0x1f99, 0x8420, 0x0070, 0x1f99, 0x0078,
- 0x1f8a, 0x157f, 0x0078, 0x1bff, 0x2200, 0x0079, 0x1f9f, 0x1fa2,
- 0x1fa4, 0x1fa4, 0x1078, 0x1ba5, 0x70a3, 0x0000, 0x70a7, 0x0001,
- 0x0078, 0x1bf7, 0x2200, 0x0079, 0x1fad, 0x1fb2, 0x1fa4, 0x1fb0,
- 0x1078, 0x1ba5, 0x1078, 0x241f, 0x7000, 0xa086, 0x0001, 0x00c0,
- 0x28af, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef, 0x600a, 0x1078,
- 0x28a2, 0x0040, 0x28af, 0x0078, 0x1cd6, 0x2404, 0xa005, 0x0040,
- 0x1fe6, 0x2068, 0x2d04, 0x007e, 0x6810, 0xa706, 0x0040, 0x1fd4,
- 0x2d20, 0x007f, 0x0078, 0x1fc6, 0x007f, 0x2022, 0x6916, 0x681c,
- 0xa205, 0x681e, 0x1078, 0x17dd, 0x6010, 0x8001, 0x6012, 0x6008,
- 0xa084, 0xffef, 0x600a, 0x1078, 0x28ef, 0x007c, 0xa085, 0x0001,
- 0x0078, 0x1fe5, 0x2300, 0x0079, 0x1fed, 0x1ff2, 0x1ff0, 0x2035,
- 0x1078, 0x1ba5, 0x78e4, 0xa005, 0x00d0, 0x2015, 0x0018, 0x2015,
- 0x2008, 0xa084, 0x0030, 0x00c0, 0x2001, 0x781b, 0x0049, 0x0078,
- 0x1bf7, 0x78ec, 0xa084, 0x0003, 0x0040, 0x1ffd, 0x2100, 0xa084,
- 0x0007, 0x0079, 0x200b, 0x2023, 0x2029, 0x201d, 0x2013, 0x2d58,
- 0x2d58, 0x2013, 0x202f, 0x1078, 0x1ba5, 0x7000, 0xa005, 0x0040,
- 0x1bff, 0x2001, 0x0003, 0x0078, 0x22fa, 0x1078, 0x2b89, 0x781b,
- 0x0055, 0x0078, 0x1bf7, 0x1078, 0x2b89, 0x781b, 0x00dc, 0x0078,
- 0x1bf7, 0x1078, 0x2b89, 0x781b, 0x00e3, 0x0078, 0x1bf7, 0x1078,
- 0x2b89, 0x781b, 0x009d, 0x0078, 0x1bf7, 0xa584, 0x000f, 0x00c0,
- 0x205f, 0x1078, 0x241f, 0x7000, 0x0079, 0x203e, 0x2046, 0x2053,
- 0x2046, 0x28af, 0x2048, 0x28af, 0x2046, 0x2046, 0x1078, 0x1ba5,
- 0x71a0, 0x70a3, 0x0000, 0xa186, 0x0004, 0x00c0, 0x2051, 0x0078,
- 0x2908, 0x0078, 0x28af, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x1078, 0x28a2, 0x0040, 0x28af, 0x0078, 0x1cd6, 0x78e4,
- 0xa005, 0x00d0, 0x2015, 0x0018, 0x2015, 0x2008, 0xa084, 0x0030,
- 0x00c0, 0x206e, 0x781b, 0x0049, 0x0078, 0x1bf7, 0x78ec, 0xa084,
- 0x0003, 0x0040, 0x206a, 0x2100, 0xa184, 0x0007, 0x0079, 0x2078,
- 0x2088, 0x208e, 0x2082, 0x2080, 0x2d58, 0x2d58, 0x2080, 0x2d50,
- 0x1078, 0x1ba5, 0x1078, 0x2b91, 0x781b, 0x0055, 0x0078, 0x1bf7,
- 0x1078, 0x2b91, 0x781b, 0x00dc, 0x0078, 0x1bf7, 0x1078, 0x2b91,
- 0x781b, 0x00e3, 0x0078, 0x1bf7, 0x1078, 0x2b91, 0x781b, 0x009d,
- 0x0078, 0x1bf7, 0x2300, 0x0079, 0x209d, 0x20a2, 0x20a0, 0x20a4,
- 0x1078, 0x1ba5, 0x0078, 0x2665, 0x6817, 0x0008, 0x78a3, 0x0000,
- 0x79e4, 0xa184, 0x0030, 0x0040, 0x2665, 0x78ec, 0xa084, 0x0003,
- 0x0040, 0x2665, 0xa184, 0x0007, 0x0079, 0x20b6, 0x2023, 0x2029,
- 0x201d, 0x2d30, 0x2d58, 0x2d58, 0x20be, 0x2d50, 0x1078, 0x1ba5,
- 0xa282, 0x0005, 0x0050, 0x20c6, 0x1078, 0x1ba5, 0x2300, 0x0079,
- 0x20c9, 0x20cc, 0x22ce, 0x22da, 0x2200, 0x0079, 0x20cf, 0x20d4,
- 0x20d6, 0x20e9, 0x20d4, 0x22b3, 0x1078, 0x1ba5, 0x789b, 0x0018,
- 0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x2b6a, 0xa08a,
- 0x0004, 0x00c8, 0x2b6a, 0x0079, 0x20e5, 0x2b6a, 0x2b6a, 0x2b6a,
- 0x2b0c, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x20fe,
- 0xa184, 0x0018, 0x0040, 0x20fa, 0x0078, 0x2b6a, 0x7000, 0xa005,
- 0x00c0, 0x20f4, 0x2011, 0x0003, 0x0078, 0x2752, 0xa184, 0x00ff,
- 0xa08a, 0x0010, 0x00c8, 0x2b6a, 0x0079, 0x2106, 0x2118, 0x2116,
- 0x212e, 0x2130, 0x21c2, 0x2b6a, 0x2b6a, 0x21c4, 0x2b6a, 0x2b6a,
- 0x22af, 0x22af, 0x2b6a, 0x2b6a, 0x2b6a, 0x22b1, 0x1078, 0x1ba5,
- 0xa684, 0x1000, 0x0040, 0x2125, 0x2001, 0x0300, 0x8000, 0x8000,
- 0x783a, 0x781b, 0x009a, 0x0078, 0x1bf7, 0x6814, 0xa084, 0x8000,
- 0x0040, 0x212c, 0x6817, 0x0003, 0x0078, 0x2d30, 0x1078, 0x1ba5,
- 0x691c, 0x691e, 0xa684, 0x1800, 0x00c0, 0x214a, 0x681c, 0xa084,
- 0x0001, 0x00c0, 0x2152, 0x6814, 0xa086, 0x0008, 0x00c0, 0x2142,
- 0x6817, 0x0000, 0xa684, 0x0400, 0x0040, 0x21be, 0x781b, 0x0058,
- 0x0078, 0x1bf7, 0xa684, 0x1000, 0x0040, 0x2152, 0x781b, 0x0058,
- 0x0078, 0x1bf7, 0xa684, 0x0060, 0x0040, 0x21ba, 0xa684, 0x0800,
- 0x0040, 0x21ba, 0xa684, 0x8000, 0x00c0, 0x2160, 0x0078, 0x217a,
- 0xa6b4, 0x7fff, 0x7e5a, 0x6eb2, 0x789b, 0x0074, 0x7aac, 0x79ac,
- 0x78ac, 0x801b, 0x00c8, 0x216d, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x6b94, 0x2100, 0xa302, 0x68ae, 0x6b90, 0x2200,
- 0xa303, 0x68aa, 0xa684, 0x4000, 0x0040, 0x2182, 0xa6b4, 0xbfff,
- 0x7e5a, 0x6eb2, 0x7000, 0xa086, 0x0003, 0x00c0, 0x218f, 0x1078,
- 0x2f3a, 0x1078, 0x30df, 0x781b, 0x0067, 0x0078, 0x1bf7, 0xa006,
- 0x1078, 0x3194, 0x6aac, 0x69a8, 0x6c94, 0x6b90, 0x2200, 0xa105,
- 0x0040, 0x219e, 0x2200, 0xa422, 0x2100, 0xa31b, 0x7cd2, 0x7bd6,
- 0x2300, 0xa405, 0x00c0, 0x21ac, 0xa6b5, 0x4000, 0x7e5a, 0x6eb2,
- 0x781b, 0x0067, 0x0078, 0x1bf7, 0x781b, 0x0067, 0x2200, 0xa115,
- 0x00c0, 0x21b6, 0x1078, 0x30f0, 0x0078, 0x1bf7, 0x1078, 0x311d,
- 0x0078, 0x1bf7, 0x781b, 0x006a, 0x0078, 0x1bf7, 0x781b, 0x0058,
- 0x0078, 0x1bf7, 0x1078, 0x1ba5, 0x0078, 0x2221, 0x691c, 0xa184,
- 0x0100, 0x0040, 0x21dc, 0xa18c, 0xfeff, 0x691e, 0x0c7e, 0x7048,
- 0x2060, 0x6000, 0xa084, 0xefff, 0x6002, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x0c7f, 0x0078, 0x2210, 0xa184, 0x0200, 0x0040, 0x2210,
- 0xa18c, 0xfdff, 0x691e, 0x0c7e, 0x7048, 0x2060, 0x6000, 0xa084,
- 0xdfff, 0x6002, 0x6004, 0xa084, 0xffef, 0x6006, 0x2008, 0x2c48,
- 0x0c7f, 0xa184, 0x0008, 0x0040, 0x2210, 0x1078, 0x2c9d, 0x1078,
- 0x29e6, 0x88ff, 0x0040, 0x2210, 0x789b, 0x0060, 0x2800, 0x78aa,
- 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x220c,
- 0x781b, 0x0055, 0x0078, 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x7e58, 0xa684, 0x0400, 0x00c0, 0x2219, 0x781b, 0x0058, 0x0078,
- 0x1bf7, 0x781b, 0x006a, 0x0078, 0x1bf7, 0x0078, 0x2b70, 0x0078,
- 0x2b70, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x0040, 0x221f,
- 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
- 0x2244, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x223c,
- 0x0048, 0x223c, 0x0078, 0x223e, 0x0078, 0x21c6, 0x24a8, 0x7aa8,
- 0x00f0, 0x223e, 0x0078, 0x222a, 0xa284, 0x00f0, 0xa086, 0x0020,
- 0x00c0, 0x22a0, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040, 0x2254,
- 0x0048, 0x2254, 0x0078, 0x229d, 0xa286, 0x0023, 0x0040, 0x221f,
- 0x6818, 0xa084, 0xfff1, 0x681a, 0x7e58, 0xa684, 0xfff1, 0xa085,
- 0x0010, 0x2030, 0x7e5a, 0x6008, 0xa085, 0x0010, 0x600a, 0x0c7e,
- 0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184, 0x0010,
- 0x0040, 0x2278, 0x1078, 0x2c9d, 0x1078, 0x2acc, 0x0078, 0x2287,
- 0x0c7e, 0x7048, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xa184,
- 0x0008, 0x0040, 0x2210, 0x1078, 0x2c9d, 0x1078, 0x29e6, 0x88ff,
- 0x0040, 0x2210, 0x789b, 0x0060, 0x2800, 0x78aa, 0xa6b5, 0x0004,
- 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2299, 0x781b, 0x0055, 0x0078,
- 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x7aa8, 0x0078, 0x222a,
- 0x8318, 0x2300, 0xa102, 0x0040, 0x22a9, 0x0048, 0x22a9, 0x0078,
- 0x222a, 0xa284, 0x0080, 0x00c0, 0x2b76, 0x0078, 0x2b70, 0x0078,
- 0x2b76, 0x0078, 0x2b6a, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff,
- 0xa08e, 0x0001, 0x0040, 0x22be, 0x1078, 0x1ba5, 0x7aa8, 0xa294,
- 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004, 0x00c8, 0x2b6a,
- 0x0079, 0x22ca, 0x2b6a, 0x2939, 0x2b6a, 0x2a67, 0xa282, 0x0000,
- 0x00c0, 0x22d4, 0x1078, 0x1ba5, 0x1078, 0x2b89, 0x781b, 0x0069,
- 0x0078, 0x1bf7, 0xa282, 0x0003, 0x00c0, 0x22e0, 0x1078, 0x1ba5,
- 0x1078, 0x2b99, 0x781b, 0x0069, 0x0078, 0x1bf7, 0xa282, 0x0004,
- 0x0050, 0x22ec, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x22ef, 0x22f2,
- 0x23c9, 0x23fa, 0xa286, 0x0003, 0x0040, 0x22f8, 0x1078, 0x1ba5,
- 0x2001, 0x0000, 0x703a, 0x7000, 0xa084, 0x0007, 0x0079, 0x2300,
- 0x2308, 0x230a, 0x230a, 0x2508, 0x2530, 0x24d2, 0x2308, 0x2308,
- 0x1078, 0x1ba5, 0xa684, 0x1000, 0x00c0, 0x2312, 0x1078, 0x2ec7,
- 0x0040, 0x23a3, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x235a, 0xa186,
- 0x0008, 0x00c0, 0x2329, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x1078, 0x28a2, 0x0040, 0x235a, 0x1078, 0x2ec7, 0x0078,
- 0x2341, 0xa186, 0x0028, 0x00c0, 0x235a, 0x1078, 0x2ec7, 0x6008,
- 0xa084, 0xffef, 0x600a, 0x6018, 0xa005, 0x0040, 0x2341, 0x8001,
- 0x601a, 0xa005, 0x0040, 0x2341, 0x8001, 0xa005, 0x0040, 0x2341,
- 0x601e, 0x681c, 0xa084, 0x0001, 0x0040, 0x1bff, 0x681c, 0xa084,
- 0xfffe, 0x681e, 0x7054, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f,
- 0x6004, 0x6802, 0xa005, 0x2d00, 0x00c0, 0x2357, 0x6002, 0x6006,
- 0x0078, 0x1bff, 0x017e, 0x1078, 0x241f, 0x017f, 0xa684, 0xdf00,
- 0x681a, 0x6827, 0x0000, 0x6f10, 0x81ff, 0x0040, 0x23a3, 0xa186,
- 0x0002, 0x00c0, 0x239b, 0xa684, 0x0800, 0x00c0, 0x2377, 0xa684,
- 0x0060, 0x0040, 0x2377, 0x78d8, 0x7adc, 0x682e, 0x6a2a, 0x8717,
- 0xa294, 0x000f, 0x8213, 0x8213, 0x8213, 0xa290, 0x3600, 0xa290,
- 0x0000, 0x221c, 0xa384, 0x0100, 0x00c0, 0x2388, 0x0078, 0x238e,
- 0x8210, 0x2204, 0xa085, 0x0018, 0x2012, 0x8211, 0xa384, 0x0400,
- 0x0040, 0x239b, 0x689c, 0xa084, 0x0100, 0x00c0, 0x239b, 0x1078,
- 0x2491, 0x0078, 0x1bff, 0xa186, 0x0018, 0x0040, 0x23a3, 0xa186,
- 0x0014, 0x0040, 0x1bff, 0x6912, 0x6814, 0xa084, 0x8000, 0x0040,
- 0x23ab, 0x7038, 0x6816, 0xa68c, 0xdf00, 0x691a, 0x1078, 0x28e0,
- 0x1078, 0x28ef, 0x00c0, 0x23b8, 0x6008, 0xa084, 0xffef, 0x600a,
- 0x681c, 0xa084, 0x0001, 0x00c0, 0x23c1, 0x1078, 0x28d9, 0x0078,
- 0x23c5, 0x7054, 0x2060, 0x6800, 0x6002, 0x1078, 0x17dd, 0x0078,
- 0x1bff, 0xa282, 0x0004, 0x0048, 0x23cf, 0x1078, 0x1ba5, 0x2200,
- 0x0079, 0x23d2, 0x23d6, 0x23d8, 0x23e5, 0x23d8, 0x1078, 0x1ba5,
- 0x7000, 0xa086, 0x0005, 0x0040, 0x23e1, 0x1078, 0x2b89, 0x781b,
- 0x0069, 0x781b, 0x006a, 0x0078, 0x1bf7, 0x7890, 0x8007, 0x8001,
- 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
- 0xa186, 0x0003, 0x0040, 0x23f6, 0x0078, 0x2b6a, 0x781b, 0x006a,
- 0x0078, 0x1bf7, 0x681c, 0xa085, 0x0004, 0x681e, 0x82ff, 0x00c0,
- 0x2405, 0x1078, 0x2b89, 0x0078, 0x240c, 0x8211, 0x0040, 0x240a,
- 0x1078, 0x1ba5, 0x1078, 0x2b99, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x1078, 0x2d77, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x241c, 0x0018,
- 0x241c, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684,
- 0x0060, 0x00c0, 0x2429, 0x682f, 0x0000, 0x682b, 0x0000, 0x0078,
- 0x2490, 0xa684, 0x0800, 0x00c0, 0x2438, 0x68b0, 0xa084, 0x4800,
- 0xa635, 0xa684, 0x0800, 0x00c0, 0x2438, 0x1078, 0x2ec7, 0x007c,
- 0xa684, 0x0020, 0x0040, 0x2462, 0x78d0, 0x8003, 0x00c8, 0x2446,
- 0xa006, 0x1078, 0x3194, 0x78d4, 0x1078, 0x31f9, 0xa684, 0x4000,
- 0x0040, 0x2450, 0x682f, 0x0000, 0x682b, 0x0000, 0x0078, 0x2435,
- 0x68b0, 0xa084, 0x4800, 0xa635, 0xa684, 0x4000, 0x00c0, 0x244a,
- 0x7038, 0xa005, 0x00c0, 0x245c, 0x79d8, 0x7adc, 0x692e, 0x6a2a,
- 0x0078, 0x2435, 0xa684, 0x4000, 0x0040, 0x246c, 0x682f, 0x0000,
- 0x682b, 0x0000, 0x0078, 0x2435, 0x68b0, 0xa084, 0x4800, 0xa635,
- 0xa684, 0x4000, 0x00c0, 0x2466, 0x7038, 0xa005, 0x00c0, 0x247a,
- 0x703b, 0x0007, 0x79d8, 0x7adc, 0x78d0, 0x80f3, 0x00c8, 0x2481,
- 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a2a,
- 0x2100, 0xa205, 0x00c0, 0x248e, 0x0078, 0x2435, 0x1078, 0x3194,
- 0x007c, 0xa384, 0x0200, 0x0040, 0x2499, 0x6008, 0xa085, 0x0002,
- 0x600a, 0x6817, 0x0006, 0x6a28, 0x692c, 0x6a3a, 0x693e, 0x682b,
- 0x0300, 0x682f, 0x0000, 0x6833, 0x2000, 0x6893, 0x0000, 0x6897,
- 0x0020, 0x7000, 0x0079, 0x24ac, 0x24b4, 0x24b6, 0x24bf, 0x24b4,
- 0x24b4, 0x24b4, 0x24b4, 0x24b4, 0x1078, 0x1ba5, 0x681c, 0xa084,
- 0x0001, 0x00c0, 0x24bf, 0x1078, 0x28d9, 0x0078, 0x24c5, 0x7054,
- 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60, 0x2021, 0x3557, 0x2404,
- 0xa005, 0x0040, 0x24ce, 0x2020, 0x0078, 0x24c7, 0x2d22, 0x206b,
- 0x0000, 0x007c, 0x77b4, 0x1078, 0x2ba6, 0xa7bc, 0x0f00, 0x1078,
- 0x2ca1, 0x6018, 0xa005, 0x0040, 0x2501, 0x0d7e, 0x2001, 0x3f90,
- 0x2068, 0x0d7f, 0x2021, 0x3f80, 0x2009, 0x0004, 0x2011, 0x0010,
- 0x1078, 0x1fc5, 0x0040, 0x2501, 0x157e, 0x20a9, 0x0000, 0x2021,
- 0x3e80, 0x047e, 0x2009, 0x0004, 0x2011, 0x0010, 0x1078, 0x1fc5,
- 0x047f, 0x0040, 0x2500, 0x8420, 0x0070, 0x2500, 0x0078, 0x24f1,
- 0x157f, 0x8738, 0xa784, 0x0007, 0x00c0, 0x24d7, 0x0078, 0x1bff,
- 0x1078, 0x28e0, 0x1078, 0x28ef, 0x6827, 0x0000, 0x789b, 0x000e,
- 0x6f10, 0x6813, 0x0002, 0x1078, 0x31ca, 0xa684, 0x0800, 0x0040,
- 0x251d, 0x6918, 0xa18d, 0x2000, 0x691a, 0x6814, 0xa084, 0x8000,
- 0x0040, 0x2524, 0x6817, 0x0000, 0x2021, 0x3557, 0x6800, 0x2022,
- 0x6a38, 0x693c, 0x6a2a, 0x692e, 0x1078, 0x17dd, 0x0078, 0x1bff,
- 0x1078, 0x241f, 0x6827, 0x0000, 0x789b, 0x000e, 0x6f10, 0x1078,
- 0x2d7c, 0xa08c, 0x00ff, 0x6912, 0x6814, 0xa084, 0x8000, 0x0040,
- 0x2543, 0x7038, 0x6816, 0xa68c, 0xdf00, 0x691a, 0x70a3, 0x0000,
- 0x0078, 0x1bff, 0xa006, 0x1078, 0x2ec7, 0x6813, 0x0000, 0x6817,
- 0x0001, 0xa68c, 0xdf00, 0x691a, 0x6827, 0x0000, 0x7000, 0x0079,
- 0x2559, 0x2561, 0x2563, 0x2563, 0x2565, 0x2565, 0x2565, 0x2561,
- 0x2561, 0x1078, 0x1ba5, 0x1078, 0x28ef, 0x6008, 0xa084, 0xffef,
- 0x600a, 0x0078, 0x28ba, 0x2300, 0x0079, 0x256e, 0x2571, 0x2573,
- 0x25b1, 0x1078, 0x1ba5, 0x7000, 0x0079, 0x2576, 0x257e, 0x2580,
- 0x2580, 0x258b, 0x2580, 0x2592, 0x257e, 0x257e, 0x1078, 0x1ba5,
- 0xa684, 0x2000, 0x00c0, 0x258b, 0xa6b5, 0x2000, 0x7e5a, 0x1078,
- 0x30f0, 0x0078, 0x2d30, 0x6814, 0xa084, 0x8000, 0x0040, 0x2592,
- 0x6817, 0x0007, 0x2009, 0x3518, 0x210c, 0xa186, 0x0000, 0x0040,
- 0x25a7, 0xa186, 0x0001, 0x0040, 0x25ab, 0x2009, 0x352b, 0x200b,
- 0x000b, 0x70a3, 0x0001, 0x781b, 0x0046, 0x0078, 0x1bf7, 0x781b,
- 0x00dd, 0x0078, 0x1bf7, 0x2009, 0x352b, 0x200b, 0x000a, 0x0078,
- 0x1bf7, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x25b6, 0x25b9, 0x25bb,
- 0x25de, 0x1078, 0x1ba5, 0x7000, 0x0079, 0x25be, 0x25c6, 0x25c8,
- 0x25c8, 0x25d3, 0x25c8, 0x25da, 0x25c6, 0x25c6, 0x1078, 0x1ba5,
- 0xa684, 0x2000, 0x00c0, 0x25d3, 0xa6b5, 0x2000, 0x7e5a, 0x1078,
- 0x30f0, 0x0078, 0x2d30, 0x6814, 0xa084, 0x8000, 0x0040, 0x25da,
- 0x6817, 0x0007, 0x781b, 0x00e4, 0x0078, 0x1bf7, 0x681c, 0xa085,
- 0x0004, 0x681e, 0xa6b5, 0x0800, 0x1078, 0x2b89, 0x781b, 0x0069,
- 0x0078, 0x1bf7, 0x2300, 0x0079, 0x25ed, 0x25f0, 0x25f2, 0x25f4,
- 0x1078, 0x1ba5, 0x1078, 0x1ba5, 0xa684, 0x0400, 0x00c0, 0x2613,
- 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
- 0x785a, 0x79e4, 0xa184, 0x0020, 0x0040, 0x260b, 0x78ec, 0xa084,
- 0x0003, 0x00c0, 0x260f, 0x2001, 0x0014, 0x0078, 0x22fa, 0xa184,
- 0x0007, 0x0079, 0x264b, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060,
- 0x79a8, 0x81ff, 0x0040, 0x2649, 0x789b, 0x0010, 0x7ba8, 0xa384,
- 0x0001, 0x00c0, 0x263a, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0,
- 0x262d, 0x2009, 0xfff7, 0x0078, 0x2633, 0xa386, 0x0003, 0x00c0,
- 0x263a, 0x2009, 0xffef, 0x0c7e, 0x7048, 0x2060, 0x6004, 0xa104,
- 0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
- 0x785a, 0x782b, 0x3009, 0x691c, 0xa18c, 0xfdff, 0xa18c, 0xfeff,
- 0x691e, 0x0078, 0x2d30, 0x2023, 0x2029, 0x2655, 0x265d, 0x2653,
- 0x2653, 0x2653, 0x2d30, 0x1078, 0x1ba5, 0x691c, 0xa18c, 0xfdff,
- 0xa18c, 0xfeff, 0x691e, 0x0078, 0x2d38, 0x691c, 0xa18c, 0xfdff,
- 0xa18c, 0xfeff, 0x691e, 0x0078, 0x2d30, 0x79e4, 0xa184, 0x0030,
- 0x0040, 0x266f, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x2677, 0x6814,
- 0xa085, 0x8000, 0x6816, 0x2001, 0x0014, 0x0078, 0x22fa, 0xa184,
- 0x0007, 0x0079, 0x267b, 0x2d30, 0x2d30, 0x2683, 0x2d30, 0x2d58,
- 0x2d58, 0x2d30, 0x2d30, 0xa684, 0x0400, 0x00c0, 0x26b4, 0x681c,
- 0xa084, 0x0001, 0x0040, 0x2d38, 0xa68c, 0x2060, 0xa18c, 0xfffb,
- 0x795a, 0x69b2, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061,
- 0x6814, 0xa085, 0x8000, 0x6816, 0x78aa, 0x157e, 0x137e, 0x147e,
- 0x20a1, 0x012c, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000a,
- 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6810, 0x8007, 0x789b,
- 0x007e, 0x78aa, 0x0078, 0x2d38, 0x6814, 0xa084, 0x8000, 0x0040,
- 0x26bb, 0x6817, 0x0008, 0x781b, 0x00d8, 0x0078, 0x1bf7, 0x2300,
- 0x0079, 0x26c2, 0x26c7, 0x2742, 0x26c5, 0x1078, 0x1ba5, 0x7000,
- 0xa084, 0x0007, 0x0079, 0x26cc, 0x26d4, 0x26d6, 0x26f2, 0x26d4,
- 0x26d4, 0x24d2, 0x26d4, 0x26d4, 0x1078, 0x1ba5, 0x691c, 0xa18d,
- 0x0001, 0x691e, 0x6800, 0x6006, 0xa005, 0x00c0, 0x26e0, 0x6002,
- 0x6818, 0xa084, 0x000e, 0x0040, 0x26ec, 0x7014, 0x68b6, 0x712c,
- 0xa188, 0x3e80, 0x0078, 0x26ee, 0x2009, 0x3f80, 0x2104, 0x6802,
- 0x2d0a, 0x7156, 0x6eb2, 0xa684, 0x0060, 0x0040, 0x2740, 0xa684,
- 0x0800, 0x00c0, 0x2704, 0xa684, 0x7fff, 0x68b2, 0x6890, 0x6894,
- 0x1078, 0x2ec7, 0x0078, 0x2740, 0xa684, 0x0020, 0x0040, 0x2716,
- 0xa006, 0x1078, 0x3194, 0x78d0, 0x8003, 0x00c8, 0x2712, 0x78d4,
- 0x1078, 0x31f9, 0x79d8, 0x7adc, 0x0078, 0x271a, 0x1078, 0x2cae,
- 0x1078, 0x3194, 0xa684, 0x8000, 0x0040, 0x2740, 0xa684, 0x7fff,
- 0x68b2, 0x789b, 0x0074, 0x1078, 0x2d7c, 0x2010, 0x1078, 0x2d7c,
- 0x2008, 0xa684, 0x0020, 0x00c0, 0x2738, 0x1078, 0x2d7c, 0x801b,
- 0x00c8, 0x2733, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
- 0x6b94, 0x2100, 0xa302, 0x68ae, 0x6b90, 0x2200, 0xa303, 0x68aa,
- 0x0078, 0x1bff, 0x0078, 0x2b76, 0x7033, 0x0000, 0xa282, 0x0005,
- 0x0050, 0x274c, 0x1078, 0x1ba5, 0x2300, 0x0079, 0x274f, 0x2752,
- 0x275c, 0x277f, 0x2200, 0x0079, 0x2755, 0x275a, 0x2b76, 0x275a,
- 0x27a8, 0x27f9, 0x1078, 0x1ba5, 0x7000, 0xa086, 0x0001, 0x00c0,
- 0x2769, 0x1078, 0x28ef, 0x1078, 0x2ec7, 0x7034, 0x600a, 0x0078,
- 0x276e, 0x7000, 0xa086, 0x0003, 0x0040, 0x2763, 0x7003, 0x0005,
- 0x2001, 0x3f90, 0x2068, 0x703e, 0x7032, 0x2200, 0x0079, 0x2778,
- 0x2b76, 0x277d, 0x27a8, 0x277d, 0x2b76, 0x1078, 0x1ba5, 0x7000,
- 0xa086, 0x0001, 0x00c0, 0x278c, 0x1078, 0x28ef, 0x1078, 0x2ec7,
- 0x7034, 0x600a, 0x0078, 0x2791, 0x7000, 0xa086, 0x0003, 0x0040,
- 0x2786, 0x7003, 0x0005, 0x2001, 0x3f90, 0x2068, 0x703e, 0x7032,
- 0x2200, 0x0079, 0x279b, 0x27a2, 0x27a0, 0x27a2, 0x27a0, 0x27a2,
- 0x1078, 0x1ba5, 0x1078, 0x2b99, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x7000, 0xa086, 0x0001, 0x00c0, 0x27b5, 0x1078, 0x28ef, 0x1078,
- 0x2ec7, 0x7034, 0x600a, 0x0078, 0x27ba, 0x7000, 0xa086, 0x0003,
- 0x0040, 0x27af, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00, 0x789b,
- 0x0018, 0x7ca8, 0xa484, 0x0007, 0xa215, 0x2069, 0x3f80, 0x2d04,
- 0x2d08, 0x7156, 0x2068, 0xa005, 0x0040, 0x27d5, 0x6810, 0xa206,
- 0x0040, 0x27ee, 0x6800, 0x0078, 0x27c8, 0x7003, 0x0005, 0x2001,
- 0x3f90, 0x2068, 0x703e, 0x7032, 0x157e, 0x20a9, 0x002f, 0x2003,
- 0x0000, 0x8000, 0x0070, 0x27e6, 0x0078, 0x27df, 0x157f, 0x6a12,
- 0x68b3, 0x0700, 0x681f, 0x0800, 0x6823, 0x0003, 0x6eb0, 0x7e5a,
- 0x681c, 0xa084, 0x0c00, 0x0040, 0x284f, 0x1078, 0x2b91, 0x0078,
- 0x284f, 0x7000, 0xa086, 0x0001, 0x00c0, 0x2806, 0x1078, 0x28ef,
- 0x1078, 0x2ec7, 0x7034, 0x600a, 0x0078, 0x280b, 0x7000, 0xa086,
- 0x0003, 0x0040, 0x2800, 0x7003, 0x0002, 0x7a80, 0xa294, 0x0f00,
- 0x789b, 0x0018, 0x7ca8, 0xa484, 0x0007, 0xa215, 0x79a8, 0x79a8,
- 0xa18c, 0x00ff, 0xa1e8, 0x3e80, 0x2d04, 0x2d08, 0x7156, 0x2068,
- 0xa005, 0x0040, 0x282a, 0x6810, 0xa206, 0x0040, 0x2843, 0x6800,
- 0x0078, 0x281d, 0x7003, 0x0005, 0x2001, 0x3f90, 0x2068, 0x703e,
- 0x7032, 0x157e, 0x20a9, 0x002f, 0x2003, 0x0000, 0x8000, 0x0070,
- 0x283b, 0x0078, 0x2834, 0x157f, 0x6a12, 0x68b3, 0x0700, 0x681f,
- 0x0800, 0x6823, 0x0003, 0x6eb0, 0x7e5a, 0x681c, 0xa084, 0x0c00,
- 0x0040, 0x284f, 0x1078, 0x2b8d, 0x7e58, 0x0078, 0x284f, 0x027e,
- 0x8207, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3600,
- 0x2060, 0x704a, 0x6000, 0x704e, 0x6004, 0x7052, 0xa684, 0x0060,
- 0x0040, 0x2886, 0x6b94, 0x6c90, 0x69a8, 0x68ac, 0xa105, 0x00c0,
- 0x2874, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0x7e5a,
- 0x1078, 0x30f0, 0x0078, 0x2886, 0x68ac, 0xa31a, 0x2100, 0xa423,
- 0x2400, 0xa305, 0x0040, 0x2886, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde,
- 0x68ac, 0xa6b4, 0xbfff, 0x7e5a, 0x1078, 0x311d, 0x077f, 0x1078,
- 0x2ca1, 0x2009, 0x006a, 0xa684, 0x0008, 0x0040, 0x2891, 0x2009,
- 0x0069, 0xa6b5, 0x2000, 0x7e5a, 0x791a, 0x2d00, 0x703e, 0x8207,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3600, 0x2048,
- 0x0078, 0x1bf7, 0x6020, 0xa005, 0x0040, 0x28ae, 0x8001, 0x6022,
- 0x6008, 0xa085, 0x0008, 0x600a, 0x7010, 0x6026, 0x007c, 0xa006,
- 0x1078, 0x2ec7, 0x6813, 0x0000, 0x6817, 0x0001, 0x681f, 0x0040,
- 0x681b, 0x0100, 0x7000, 0xa084, 0x0007, 0x0079, 0x28bf, 0x28c7,
- 0x28c9, 0x28c9, 0x28d5, 0x28d1, 0x28c7, 0x28c7, 0x28c7, 0x1078,
- 0x1ba5, 0x1078, 0x28e0, 0x1078, 0x28d9, 0x1078, 0x17dd, 0x0078,
- 0x1bff, 0x70a3, 0x0000, 0x0078, 0x1bff, 0x6817, 0x0000, 0x0078,
- 0x2508, 0x6800, 0xa005, 0x00c0, 0x28de, 0x6002, 0x6006, 0x007c,
- 0x6010, 0xa005, 0x0040, 0x28e9, 0x8001, 0x00d0, 0x28e9, 0x1078,
- 0x1ba5, 0x6012, 0x6008, 0xa084, 0xffef, 0x600a, 0x007c, 0x6018,
- 0xa005, 0x0040, 0x28f5, 0x8001, 0x601a, 0x007c, 0x1078, 0x2d77,
- 0x6817, 0x0018, 0x0078, 0x2926, 0x1078, 0x2d77, 0x6817, 0x0019,
- 0x0078, 0x2926, 0x1078, 0x2d77, 0x6817, 0x001a, 0x0078, 0x2926,
- 0x77b4, 0x1078, 0x2ca1, 0x71b8, 0xa18c, 0x00ff, 0xa1e8, 0x3e80,
- 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x2918, 0x0078, 0x1bff,
- 0x6810, 0x72b4, 0xa206, 0x0040, 0x2920, 0x6800, 0x0078, 0x2911,
- 0x6800, 0x200a, 0x6817, 0x0005, 0x70bf, 0x0000, 0x1078, 0x28e0,
- 0x681c, 0xa084, 0x0001, 0x00c0, 0x292f, 0x1078, 0x28d9, 0x1078,
- 0x28ef, 0x681b, 0x0000, 0x681f, 0x0020, 0x1078, 0x17dd, 0x0078,
- 0x1bff, 0xa282, 0x0003, 0x00c0, 0x2b6a, 0x7da8, 0xa5ac, 0x00ff,
- 0x7ea8, 0xa6b4, 0x00ff, 0x691c, 0xa18d, 0x0080, 0x691e, 0xa184,
- 0x0100, 0x0040, 0x2999, 0xa18c, 0xfeff, 0x691e, 0xa6b4, 0x00ff,
- 0x0040, 0x2983, 0xa682, 0x000f, 0x0048, 0x295a, 0x0040, 0x295a,
- 0x2031, 0x000f, 0x852b, 0x852b, 0x1078, 0x2c24, 0x0040, 0x2964,
- 0x1078, 0x2a33, 0x0078, 0x298c, 0x1078, 0x2bdf, 0x0c7e, 0x2960,
- 0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x2a57, 0x0c7f, 0x691c,
- 0xa18d, 0x0100, 0x691e, 0x7e58, 0xa6b5, 0x0004, 0x7e5a, 0xa684,
- 0x0400, 0x00c0, 0x297f, 0x781b, 0x0055, 0x0078, 0x1bf7, 0x781b,
- 0x0069, 0x0078, 0x1bf7, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5,
- 0x6006, 0x1078, 0x2a57, 0x0c7f, 0x7e58, 0xa684, 0x0400, 0x00c0,
- 0x2995, 0x781b, 0x0058, 0x0078, 0x1bf7, 0x781b, 0x006a, 0x0078,
- 0x1bf7, 0x0c7e, 0x7048, 0x2060, 0x6100, 0xa18c, 0x1000, 0x0040,
- 0x29d9, 0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000f, 0x0048,
- 0x29ad, 0x0040, 0x29ad, 0x2011, 0x000f, 0x2600, 0xa202, 0x00c8,
- 0x29b2, 0x2230, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028,
- 0x00c0, 0x29c2, 0xa282, 0x0019, 0x00c8, 0x29c8, 0x2011, 0x0019,
- 0x0078, 0x29c8, 0xa282, 0x000c, 0x00c8, 0x29c8, 0x2011, 0x000c,
- 0x2200, 0xa502, 0x00c8, 0x29cd, 0x2228, 0x1078, 0x2be3, 0x852b,
- 0x852b, 0x1078, 0x2c24, 0x0040, 0x29d9, 0x1078, 0x2a33, 0x0078,
- 0x29dd, 0x1078, 0x2bdf, 0x1078, 0x2a57, 0x7858, 0xa085, 0x0004,
- 0x785a, 0x0c7f, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x0c7e, 0x2960,
- 0x6000, 0xa084, 0x1000, 0x00c0, 0x2a01, 0x6010, 0xa084, 0x000f,
- 0x00c0, 0x29fb, 0xa18c, 0x0002, 0x00c0, 0x29fb, 0xa18c, 0xfff5,
- 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078,
- 0x2a23, 0x6208, 0xa294, 0x00ff, 0x7018, 0xa086, 0x0028, 0x00c0,
- 0x2a11, 0xa282, 0x0019, 0x00c8, 0x2a17, 0x2011, 0x0019, 0x0078,
- 0x2a17, 0xa282, 0x000c, 0x00c8, 0x2a17, 0x2011, 0x000c, 0x6308,
- 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000f, 0x0048, 0x2a23, 0x0040,
- 0x2a23, 0x2019, 0x000f, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
- 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x681c, 0xa085, 0x0100,
- 0x681e, 0x0c7f, 0x007c, 0x0c7e, 0x7148, 0x2160, 0x2008, 0xa084,
- 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4,
- 0xa084, 0xfff8, 0xa18c, 0x0007, 0xa105, 0x78a6, 0x6016, 0x788a,
- 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605,
- 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e,
- 0x7048, 0x2060, 0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6,
- 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886, 0x0c7f, 0x007c, 0xa282,
- 0x0002, 0x00c0, 0x2b6a, 0x7aa8, 0x691c, 0xa18d, 0x0080, 0x691e,
- 0xa184, 0x0200, 0x0040, 0x2aac, 0xa18c, 0xfdff, 0x691e, 0xa294,
- 0x00ff, 0xa282, 0x0002, 0x00c8, 0x2b6a, 0x1078, 0x2af3, 0x1078,
- 0x2a57, 0xa980, 0x0001, 0x200c, 0x1078, 0x2c9d, 0x1078, 0x29e6,
- 0x88ff, 0x0040, 0x2a9f, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58,
- 0xa6b5, 0x0004, 0x7e5a, 0xa684, 0x0400, 0x00c0, 0x2a9b, 0x781b,
- 0x0055, 0x0078, 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x7e58,
- 0xa684, 0x0400, 0x00c0, 0x2aa8, 0x781b, 0x0058, 0x0078, 0x1bf7,
- 0x781b, 0x006a, 0x0078, 0x1bf7, 0xa282, 0x0002, 0x00c8, 0x2ab4,
- 0xa284, 0x0001, 0x0040, 0x2abe, 0x7148, 0xa188, 0x0000, 0x210c,
- 0xa18c, 0x2000, 0x00c0, 0x2abe, 0x2011, 0x0000, 0x1078, 0x2bd1,
- 0x1078, 0x2af3, 0x1078, 0x2a57, 0x7858, 0xa085, 0x0004, 0x785a,
- 0x781b, 0x0069, 0x0078, 0x1bf7, 0x0c7e, 0x027e, 0x2960, 0x6000,
- 0x2011, 0x0001, 0xa084, 0x2000, 0x00c0, 0x2ae3, 0x6014, 0xa084,
- 0x0040, 0x00c0, 0x2ae1, 0xa18c, 0xffef, 0x6106, 0xa006, 0x0078,
- 0x2af0, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
- 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x681c, 0xa085, 0x0200, 0x681e,
- 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7048, 0x2060, 0x82ff, 0x0040,
- 0x2afb, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4,
- 0xa084, 0xffbf, 0xa205, 0x78a6, 0x6016, 0x788a, 0x6004, 0xa084,
- 0xffef, 0x6006, 0x0c7f, 0x007c, 0x007e, 0x7000, 0xa086, 0x0003,
- 0x0040, 0x2b15, 0x007f, 0x0078, 0x2b18, 0x007f, 0x0078, 0x2b66,
- 0xa684, 0x0020, 0x0040, 0x2b66, 0x7888, 0xa084, 0x0040, 0x0040,
- 0x2b66, 0x78a8, 0x8001, 0x0040, 0x2b25, 0x7bb8, 0xa384, 0x003f,
- 0x831b, 0x00c8, 0x2b2c, 0x8000, 0xa005, 0x0040, 0x2b4d, 0x831b,
- 0x00c8, 0x2b35, 0x8001, 0x0040, 0x2b62, 0xa006, 0x1078, 0x3194,
- 0x78b4, 0x1078, 0x31f9, 0x0078, 0x2b66, 0xa684, 0x4000, 0x0040,
- 0x2b4d, 0x78b8, 0x801b, 0x00c8, 0x2b46, 0x8000, 0xa084, 0x003f,
- 0x00c0, 0x2b62, 0xa6b4, 0xbfff, 0x7e5a, 0x79d8, 0x7adc, 0x2001,
- 0x0001, 0xa108, 0x00c8, 0x2b56, 0xa291, 0x0000, 0x79d2, 0x79da,
- 0x7ad6, 0x7ade, 0x1078, 0x3194, 0x781b, 0x0067, 0x1078, 0x305e,
- 0x0078, 0x1bf7, 0x781b, 0x0067, 0x0078, 0x1bf7, 0x781b, 0x006a,
- 0x0078, 0x1bf7, 0x1078, 0x2b9d, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x1078, 0x2b89, 0x781b, 0x0069, 0x0078, 0x1bf7, 0x6823, 0x0002,
- 0x1078, 0x2b91, 0x691c, 0xa18d, 0x0020, 0x691e, 0x6814, 0xa084,
- 0x8000, 0x0040, 0x2b85, 0x6817, 0x0005, 0x781b, 0x0069, 0x0078,
- 0x1bf7, 0x2001, 0x0005, 0x0078, 0x2b9f, 0x2001, 0x000c, 0x0078,
- 0x2b9f, 0x2001, 0x0006, 0x0078, 0x2b9f, 0x2001, 0x000d, 0x0078,
- 0x2b9f, 0x2001, 0x0009, 0x0078, 0x2b9f, 0x2001, 0x0007, 0x789b,
- 0x007f, 0x78aa, 0xa6b5, 0x0008, 0x7e5a, 0x007c, 0x077e, 0x873f,
- 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, 0x3600, 0xa7b8,
- 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, 0x2bbf, 0xa184,
- 0xfff0, 0x78a6, 0x6012, 0x6004, 0xa085, 0x0008, 0x6006, 0x8738,
- 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040, 0x0040, 0x2bcf, 0xa184,
- 0xffbf, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0010, 0x6006, 0x077f,
- 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
- 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004, 0x007c, 0x2031,
- 0x0000, 0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab,
- 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab,
- 0x0005, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003,
- 0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2001, 0x3546,
- 0x2004, 0xa082, 0x0028, 0x0040, 0x2c0d, 0x2021, 0x2c84, 0x2019,
- 0x0014, 0x20a9, 0x000c, 0x0078, 0x2c13, 0x2021, 0x2c90, 0x2019,
- 0x0019, 0x20a9, 0x000d, 0x2011, 0x0064, 0x2404, 0xa084, 0xfff0,
- 0xa106, 0x0040, 0x2c22, 0x8420, 0x2300, 0xa210, 0x0070, 0x2c22,
- 0x0078, 0x2c15, 0x157f, 0x007c, 0x157e, 0x2011, 0x3546, 0x2214,
- 0xa282, 0x0032, 0x0048, 0x2c38, 0x0040, 0x2c3c, 0x2021, 0x2c76,
- 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x0078, 0x2c4c,
- 0xa282, 0x0028, 0x0040, 0x2c44, 0x2021, 0x2c84, 0x2019, 0x0014,
- 0x20a9, 0x000c, 0x0078, 0x2c4a, 0x2021, 0x2c90, 0x2019, 0x0019,
- 0x20a9, 0x000d, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x2c5c,
- 0x0048, 0x2c5c, 0x8420, 0x2300, 0xa210, 0x0070, 0x2c59, 0x0078,
- 0x2c4c, 0x157f, 0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8,
- 0x2c65, 0x7808, 0xa085, 0x0070, 0x780a, 0x78ec, 0xa084, 0x0300,
- 0x0040, 0x2c73, 0x2404, 0xa09e, 0x1201, 0x00c0, 0x2c73, 0x2001,
- 0x2101, 0x0078, 0x2c74, 0x2404, 0xa005, 0x007c, 0x1201, 0x3002,
- 0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806,
- 0x7a06, 0x0a07, 0x0c07, 0x0e07, 0x3202, 0x4202, 0x5202, 0x6202,
- 0x7202, 0x6605, 0x7605, 0x7805, 0x7a05, 0x7c05, 0x7e05, 0x7f05,
- 0x2202, 0x3202, 0x4202, 0x5202, 0x5404, 0x6404, 0x7404, 0x7604,
- 0x7804, 0x7a04, 0x7c04, 0x7e04, 0x7f04, 0x789b, 0x0010, 0xa046,
- 0x007c, 0xa784, 0x0f00, 0x800c, 0xa784, 0x0007, 0x8003, 0x8003,
- 0x8003, 0x8003, 0xa105, 0xa0e0, 0x3680, 0x007c, 0x79d8, 0x7adc,
- 0x78d0, 0x801b, 0x00c8, 0x2cb5, 0x8000, 0xa084, 0x003f, 0xa108,
- 0xa291, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x0100, 0x2009, 0x3540,
- 0x2091, 0x8000, 0x2104, 0x0079, 0x2cc5, 0x2cf7, 0x2ccf, 0x2ccf,
- 0x2ccf, 0x2ccf, 0x2ccf, 0x2ccd, 0x2ccd, 0x1078, 0x1ba5, 0x784b,
- 0x0004, 0x7848, 0xa084, 0x0004, 0x00c0, 0x2cd1, 0x784b, 0x0008,
- 0x7848, 0xa084, 0x0008, 0x00c0, 0x2cd8, 0x68b0, 0xa085, 0x4000,
- 0x68b2, 0x7858, 0xa085, 0x4000, 0x785a, 0x7830, 0xa084, 0x0080,
- 0x00c0, 0x2cf7, 0x0018, 0x2cf7, 0x6818, 0xa084, 0x0020, 0x00c0,
- 0x2cf5, 0x781b, 0x00dd, 0x0078, 0x2cf7, 0x781b, 0x00e4, 0x2091,
- 0x8001, 0x0f7f, 0x007c, 0x0c7e, 0x6810, 0x8007, 0xa084, 0x000f,
- 0x8003, 0x8003, 0x8003, 0xa0e0, 0x3600, 0x6004, 0xa084, 0x000a,
- 0x00c0, 0x2d2e, 0x6108, 0xa194, 0xff00, 0x0040, 0x2d2e, 0xa18c,
- 0x00ff, 0x2001, 0x0019, 0xa106, 0x0040, 0x2d1d, 0x2001, 0x0032,
- 0xa106, 0x0040, 0x2d21, 0x0078, 0x2d25, 0x2009, 0x0020, 0x0078,
- 0x2d27, 0x2009, 0x003f, 0x0078, 0x2d27, 0x2011, 0x0000, 0x2100,
- 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f, 0x007c,
- 0x781b, 0x006a, 0x0078, 0x1bf7, 0x781b, 0x0069, 0x0078, 0x1bf7,
- 0x781b, 0x0058, 0x0078, 0x1bf7, 0x781b, 0x0055, 0x0078, 0x1bf7,
- 0x781b, 0x00dd, 0x0078, 0x1bf7, 0x781b, 0x00dc, 0x0078, 0x1bf7,
- 0x781b, 0x00e4, 0x0078, 0x1bf7, 0x781b, 0x00e3, 0x0078, 0x1bf7,
- 0x781b, 0x009e, 0x0078, 0x1bf7, 0x781b, 0x009d, 0x0078, 0x1bf7,
- 0x70a3, 0x0001, 0x781b, 0x0046, 0x0078, 0x1bf7, 0x007e, 0x7830,
- 0xa084, 0x00c0, 0x00c0, 0x2d75, 0x7808, 0xa084, 0xfffd, 0x780a,
- 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040,
- 0x2d75, 0x7808, 0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0x7808,
- 0xa085, 0x0002, 0x780a, 0x007c, 0x7830, 0xa084, 0x0040, 0x00c0,
- 0x2d7c, 0x0098, 0x2d85, 0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd,
- 0x780a, 0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021,
- 0x0040, 0x2d94, 0x0098, 0x2d92, 0x78ac, 0x007e, 0x7808, 0xa085,
- 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0070, 0x0040, 0x2da8,
- 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x1b6b, 0x2d78, 0x2c68, 0x0c7f,
- 0x6817, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681a, 0x682f, 0x0000,
- 0x682b, 0x0000, 0x784b, 0x0008, 0x78e4, 0xa005, 0x00d0, 0x2015,
- 0xa084, 0x0020, 0x0040, 0x2015, 0x78ec, 0xa084, 0x0003, 0x0040,
- 0x2015, 0x0018, 0x2015, 0x0078, 0x2b70, 0x0c7e, 0x6810, 0x8007,
- 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa080, 0x3600, 0x2060,
- 0x2048, 0x704a, 0x6000, 0x704e, 0x6004, 0x7052, 0x0c7f, 0x007c,
- 0x0020, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020,
- 0x0000, 0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9847, 0x0014,
- 0x0014, 0x98f5, 0x98e7, 0x0014, 0x0014, 0x0080, 0x00bf, 0x0100,
- 0x0402, 0x2008, 0xf880, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014,
- 0xa200, 0x8838, 0x817e, 0x842a, 0x84a0, 0x3806, 0x8839, 0x28c2,
- 0x9cc3, 0xa805, 0x0864, 0xa83b, 0x3008, 0x28c1, 0x9cc3, 0xa201,
- 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a,
- 0xa808, 0x28e2, 0x9ca0, 0xa8f3, 0x0864, 0xa829, 0x300c, 0xa801,
- 0x3008, 0x28e1, 0x9ca0, 0x280d, 0xa204, 0x64c0, 0x67a0, 0x6fc0,
- 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa80f, 0x786e, 0x883e,
- 0xa80c, 0x282b, 0xa205, 0x64a0, 0x67a0, 0x6fc0, 0x1814, 0x883b,
- 0x7023, 0x8576, 0x8677, 0xa801, 0x883e, 0x2069, 0x28c1, 0x9cc3,
- 0x2044, 0x2103, 0x20a2, 0x2081, 0xa8dc, 0xa207, 0x0014, 0xa203,
- 0x8000, 0x84a8, 0x85a4, 0x1872, 0x849a, 0x883c, 0x1fe2, 0xf601,
- 0xa208, 0x856e, 0x866f, 0x0704, 0x3008, 0x9ca0, 0x0014, 0xa202,
- 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf848, 0x8174, 0x86eb,
- 0x85eb, 0x872e, 0x87a9, 0x883f, 0x08e6, 0xa8f1, 0xf861, 0xa8e8,
- 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2,
- 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0,
- 0x1fe6, 0x0014, 0xa206, 0x6865, 0x817f, 0x842a, 0x1dc1, 0x8823,
- 0x0016, 0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a,
- 0xf021, 0x3008, 0x84a8, 0x1dc6, 0x20d7, 0x8822, 0x0016, 0x8000,
- 0x2848, 0x1011, 0xa8fc, 0x3008, 0x8000, 0xa000, 0x2802, 0x1011,
- 0xa8fd, 0xa887, 0x3008, 0x283d, 0x1011, 0xa8fd, 0xa209, 0x0017,
- 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0x26e0, 0x873a,
- 0xfaa2, 0x19f2, 0x1fe2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x817e,
- 0x842a, 0x84a0, 0x3806, 0x0210, 0x9ccd, 0x0704, 0x0000, 0x127e,
- 0x2091, 0x2200, 0x2049, 0x2ec7, 0x7000, 0x7204, 0xa205, 0x720c,
- 0xa215, 0x7008, 0xa084, 0xfffd, 0xa205, 0x0040, 0x2ed9, 0x0078,
- 0x2ede, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c, 0x7000, 0xa084,
- 0x0001, 0x00c0, 0x2f0c, 0x7108, 0x8104, 0x00c8, 0x2eeb, 0x1078,
- 0x2fa8, 0x0078, 0x2ee3, 0x700c, 0xa08c, 0x007f, 0x0040, 0x2f0c,
- 0x7004, 0x8004, 0x00c8, 0x2f03, 0x7014, 0xa005, 0x00c0, 0x2eff,
- 0x7010, 0xa005, 0x0040, 0x2f03, 0xa102, 0x00c8, 0x2ee3, 0x7007,
- 0x0010, 0x0078, 0x2f0c, 0x8aff, 0x0040, 0x2f0c, 0x1078, 0x316b,
- 0x00c0, 0x2f06, 0x0040, 0x2ee3, 0x1078, 0x2f56, 0x7003, 0x0000,
- 0x127f, 0x2000, 0x007c, 0x6424, 0x84ff, 0x0040, 0x2f30, 0x2c70,
- 0x2039, 0x2f35, 0x2704, 0xae68, 0x680c, 0xa630, 0x6808, 0xa529,
- 0x8421, 0x0040, 0x2f30, 0x8738, 0x2704, 0xa005, 0x00c0, 0x2f1b,
- 0x7098, 0xa075, 0x0040, 0x2f30, 0x2039, 0x2f32, 0x0078, 0x2f1a,
- 0x007c, 0x0000, 0x0004, 0x0008, 0x000c, 0x0010, 0x0014, 0x0018,
- 0x001c, 0x0000, 0x127e, 0x2091, 0x2200, 0x2079, 0x3500, 0x2071,
- 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2071,
- 0x0020, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2049,
- 0x0000, 0x78b3, 0x0000, 0x127f, 0x2000, 0x007c, 0x2049, 0x2f56,
- 0x7004, 0x8004, 0x00c8, 0x2f82, 0x7007, 0x0012, 0x7108, 0x7008,
- 0xa106, 0x00c0, 0x2f5e, 0xa184, 0x0030, 0x0040, 0x2f6b, 0xa086,
- 0x0030, 0x00c0, 0x2f5e, 0x7000, 0xa084, 0x0001, 0x00c0, 0x2f82,
- 0x7008, 0xa084, 0x000c, 0x00c0, 0x2f80, 0x710c, 0xa184, 0x0300,
- 0x00c0, 0x2f80, 0xa184, 0x007f, 0x00c0, 0x2f56, 0x0078, 0x2f82,
- 0x6817, 0x0003, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xa084,
- 0x0008, 0x00c0, 0x2f86, 0x7007, 0x0012, 0x7108, 0x8104, 0x0048,
- 0x2f8b, 0x78b3, 0x0000, 0x7003, 0x0000, 0x2049, 0x0000, 0x007c,
- 0x107e, 0x007e, 0x127e, 0x157e, 0x2091, 0x2200, 0x7108, 0x1078,
- 0x2fa8, 0x157f, 0x127f, 0x2091, 0x8001, 0x007f, 0x107f, 0x007c,
- 0x7204, 0x2118, 0x7108, 0x700c, 0xa084, 0x0300, 0x00c0, 0x2fea,
- 0xa184, 0x000c, 0x00c0, 0x2fea, 0x8213, 0x8213, 0x8213, 0x8213,
- 0xa284, 0x0100, 0xa10d, 0x810b, 0x810b, 0x810f, 0xa184, 0x0007,
- 0x0079, 0x2fc2, 0x2fcc, 0x2fdc, 0x2fea, 0x2fdc, 0x2ffe, 0x2ffe,
- 0x2fea, 0x2ffc, 0x1078, 0x1ba5, 0x7007, 0x0002, 0x8aff, 0x00c0,
- 0x2fd5, 0x2049, 0x0000, 0x0078, 0x2fd9, 0x1078, 0x316b, 0x00c0,
- 0x2fd5, 0x78b3, 0x0000, 0x007c, 0x7007, 0x0002, 0x8aff, 0x00c0,
- 0x2fe3, 0x0078, 0x2fe7, 0x1078, 0x316b, 0x00c0, 0x2fe3, 0x78b3,
- 0x0000, 0x007c, 0x7007, 0x0002, 0x1078, 0x2f56, 0x1078, 0x2cbb,
- 0x6814, 0xa084, 0x8000, 0x0040, 0x2ff7, 0x6817, 0x0002, 0x007c,
- 0x1078, 0x1ba5, 0x1078, 0x1ba5, 0x1078, 0x3050, 0x7210, 0x7114,
- 0x700c, 0xa09c, 0x007f, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000,
- 0x78b0, 0xa005, 0x0040, 0x3010, 0x78b3, 0x0000, 0x0078, 0x3033,
- 0x1078, 0x3050, 0x2704, 0x2c58, 0xac60, 0x630c, 0x2200, 0xa322,
- 0x6308, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x3029, 0x00c8,
- 0x3029, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078,
- 0x3010, 0x2b60, 0x8a07, 0xa7ba, 0x2f32, 0xa73d, 0x2c00, 0x6882,
- 0x6f86, 0x6c8e, 0x6b8a, 0x7007, 0x0012, 0x1078, 0x2f56, 0x007c,
- 0x8738, 0x2704, 0xa005, 0x00c0, 0x3044, 0x6098, 0xa005, 0x0040,
- 0x304d, 0x2060, 0x2039, 0x2f32, 0x8a51, 0x0040, 0x304c, 0x7008,
- 0xa084, 0x00c0, 0xa086, 0x00c0, 0x007c, 0x2051, 0x0000, 0x007c,
- 0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x305d, 0x2039, 0x2f38,
- 0x6000, 0xa064, 0x00c0, 0x305d, 0x2d60, 0x007c, 0x127e, 0x0d7e,
- 0x2091, 0x2200, 0x0d7f, 0x6880, 0x2060, 0x6884, 0x6b88, 0x6c8c,
- 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0xa0b8, 0x2f32, 0x7e08,
- 0xa6b5, 0x000c, 0x6818, 0xa084, 0x0040, 0x0040, 0x3079, 0xa6b5,
- 0x0001, 0x0f7e, 0x2079, 0x0100, 0x7858, 0x0f7f, 0xa084, 0x0040,
- 0x0040, 0x3088, 0xa684, 0x0001, 0x00c0, 0x3088, 0xa6b5, 0x0001,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x308a, 0x7000,
- 0xa005, 0x0040, 0x3095, 0x1078, 0x1ba5, 0x2400, 0xa305, 0x00c0,
- 0x309b, 0x0078, 0x30d8, 0x2c58, 0x2704, 0xac60, 0x6004, 0xa400,
- 0x007e, 0x701a, 0x6000, 0xa301, 0x701e, 0x2009, 0x04fd, 0x2104,
- 0xa086, 0x04fd, 0x007f, 0x00c0, 0x30c8, 0xa084, 0x0001, 0x0040,
- 0x30c8, 0xa684, 0x0001, 0x00c0, 0x30c8, 0x7013, 0x0001, 0x7017,
- 0x0000, 0x7602, 0x7007, 0x0001, 0x78b3, 0x0001, 0xa4a0, 0x0001,
- 0xa399, 0x0000, 0x6004, 0xa400, 0x701a, 0x6000, 0xa301, 0x701e,
- 0x620c, 0x2400, 0xa202, 0x7012, 0x6208, 0x2300, 0xa203, 0x7016,
- 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078, 0x3038, 0x0078, 0x30da,
- 0x1078, 0x316b, 0x00c0, 0x30d8, 0x127f, 0x2000, 0x007c, 0x127e,
- 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xa084,
- 0x0004, 0x00c0, 0x30e6, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c,
- 0x127e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049, 0x30f0, 0x7007,
- 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x30f9, 0x7000, 0xa005,
- 0x0040, 0x3104, 0x1078, 0x1ba5, 0x7e08, 0xa6b5, 0x000c, 0x6818,
- 0xa084, 0x0040, 0x0040, 0x310e, 0xa6b5, 0x0001, 0x6824, 0xa005,
- 0x0040, 0x311a, 0x2050, 0x2039, 0x2f35, 0x2d60, 0x1078, 0x316b,
- 0x00c0, 0x3116, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
- 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x037f, 0x047f, 0x7e08, 0xa6b5,
- 0x000c, 0x6818, 0xa084, 0x0040, 0x0040, 0x3130, 0xa6b5, 0x0001,
- 0x2049, 0x311d, 0x6824, 0xa055, 0x0040, 0x3168, 0x2d70, 0x2e60,
- 0x2039, 0x2f35, 0x2704, 0xae68, 0x680c, 0xa422, 0x6808, 0xa31b,
- 0x0048, 0x3155, 0x8a51, 0x00c0, 0x3147, 0x1078, 0x1ba5, 0x8738,
- 0x2704, 0xa005, 0x00c0, 0x313b, 0x7098, 0xa075, 0x2060, 0x0040,
- 0x3168, 0x2039, 0x2f32, 0x0078, 0x313a, 0x8422, 0x8420, 0x831a,
- 0xa399, 0x0000, 0x690c, 0x2400, 0xa122, 0x6908, 0x2300, 0xa11b,
- 0x00c8, 0x3164, 0x1078, 0x1ba5, 0x2071, 0x0020, 0x0078, 0x3088,
- 0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x00c0, 0xa086, 0x00c0,
- 0x0040, 0x3193, 0x2704, 0xac08, 0x2104, 0x701e, 0x8108, 0x2104,
- 0x701a, 0x8108, 0x2104, 0x7016, 0x8108, 0x2104, 0x7012, 0x0f7e,
- 0x2079, 0x0100, 0x7858, 0x0f7f, 0xa084, 0x0040, 0x0040, 0x318e,
- 0xa684, 0x0001, 0x00c0, 0x318e, 0xa6b5, 0x0001, 0x7602, 0x7007,
- 0x0001, 0x1078, 0x3038, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091,
- 0x2200, 0x2049, 0x3194, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x00c0,
- 0x00c0, 0x31aa, 0x6824, 0xa005, 0x0040, 0x31ba, 0x0078, 0x2ede,
- 0x0078, 0x31ba, 0x7108, 0x8104, 0x00c8, 0x31b2, 0x1078, 0x2fa8,
- 0x0078, 0x319d, 0x7007, 0x0010, 0x7108, 0x8104, 0x00c8, 0x31b4,
- 0x1078, 0x2fa8, 0x7008, 0xa086, 0x0002, 0x00c0, 0x319d, 0x7000,
- 0xa005, 0x00c0, 0x319d, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f,
- 0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0d7e, 0x2091,
- 0x2200, 0x0d7f, 0x2049, 0x31ca, 0xad80, 0x0010, 0x20a0, 0x2099,
- 0x0031, 0x700c, 0xa084, 0x007f, 0x6826, 0x7007, 0x0008, 0x7007,
- 0x0002, 0x7003, 0x0001, 0x0040, 0x31e8, 0x8000, 0x80ac, 0x53a5,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x31ea, 0x2049,
- 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f, 0x127f, 0x2000,
- 0x007c, 0x127e, 0x007e, 0x0d7e, 0x2091, 0x2200, 0x0d7f, 0x2049,
- 0x31f9, 0x6880, 0x2060, 0x6884, 0x6b88, 0x6c8c, 0x8057, 0xaad4,
- 0x00ff, 0xa084, 0x00ff, 0xa0b8, 0x2f32, 0x7e08, 0xa6b5, 0x0004,
- 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x3212, 0x2c58,
- 0x2704, 0xac60, 0x6004, 0xa400, 0x701a, 0x6000, 0xa301, 0x701e,
- 0x7013, 0x0001, 0x7017, 0x0000, 0x7602, 0x7007, 0x0001, 0x007f,
- 0x8007, 0x2009, 0x0031, 0x200a, 0x00a0, 0x322c, 0x7108, 0x7007,
- 0x0002, 0x810c, 0x00c8, 0x322c, 0x810c, 0x0048, 0x3239, 0x0078,
- 0x2fea, 0xa4a0, 0x0001, 0xa399, 0x0000, 0x6b8a, 0x6c8e, 0x7007,
- 0x0004, 0x2049, 0x0000, 0x7003, 0x0000, 0x127f, 0x2000, 0x007c,
- 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e, 0x00c8, 0x3251,
- 0xa200, 0x00f0, 0x324c, 0x8086, 0x818e, 0x007c, 0x157e, 0x20a9,
- 0x0010, 0xa005, 0x0040, 0x3277, 0xa11a, 0x00c8, 0x3277, 0x8213,
- 0x818d, 0x0048, 0x326a, 0xa11a, 0x00c8, 0x326b, 0x00f0, 0x325f,
- 0x0078, 0x326f, 0xa11a, 0x2308, 0x8210, 0x00f0, 0x325f, 0x007e,
- 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f, 0x007c, 0x007e,
- 0x3200, 0xa085, 0x0800, 0x0078, 0x3273, 0x00e0, 0x32bf, 0x2091,
- 0x6000, 0x7820, 0x8001, 0x7822, 0x00c0, 0x32b9, 0x7824, 0x7822,
- 0x2091, 0x8000, 0x2069, 0x3540, 0x6800, 0xa084, 0x0007, 0x0040,
- 0x32a1, 0xa086, 0x0002, 0x0040, 0x32a1, 0x6830, 0xa00d, 0x0040,
- 0x32a1, 0x2104, 0xa005, 0x0040, 0x32a1, 0x8001, 0x200a, 0x0040,
- 0x336f, 0x2061, 0x3680, 0x20a9, 0x0080, 0x6034, 0xa005, 0x0040,
- 0x32b3, 0x8001, 0x6036, 0x00c0, 0x32b3, 0x6010, 0xa005, 0x0040,
- 0x32b3, 0x1078, 0x1a19, 0xace0, 0x0010, 0x0070, 0x32b9, 0x0078,
- 0x32a5, 0x1078, 0x32d4, 0x1078, 0x32c2, 0x1078, 0x32f9, 0x2091,
- 0x8001, 0x007c, 0x783c, 0x8001, 0x783e, 0x00c0, 0x32d3, 0x7840,
- 0x783e, 0x7848, 0xa005, 0x0040, 0x32d3, 0x8001, 0x784a, 0x00c0,
- 0x32d3, 0x1078, 0x1a19, 0x007c, 0x7834, 0x8001, 0x7836, 0x00c0,
- 0x32f8, 0x7838, 0x7836, 0x2091, 0x8000, 0x7844, 0xa005, 0x00c0,
- 0x32e3, 0x2001, 0x0101, 0x8001, 0x7846, 0xa080, 0x3e80, 0x2040,
- 0x2004, 0xa065, 0x0040, 0x32f8, 0x6020, 0xa005, 0x0040, 0x32f4,
- 0x8001, 0x6022, 0x0040, 0x3328, 0x6000, 0x2c40, 0x0078, 0x32e9,
- 0x007c, 0x7828, 0x8001, 0x782a, 0x00c0, 0x3327, 0x782c, 0x782a,
- 0x7830, 0xa005, 0x00c0, 0x3306, 0x2001, 0x0080, 0x8001, 0x7832,
- 0x8003, 0x8003, 0x8003, 0x8003, 0xa090, 0x3680, 0xa298, 0x0002,
- 0x2304, 0xa084, 0x0008, 0x0040, 0x3327, 0xa290, 0x0009, 0x2204,
- 0xa005, 0x0040, 0x331f, 0x8001, 0x2012, 0x00c0, 0x3327, 0x2304,
- 0xa084, 0xfff7, 0xa085, 0x0080, 0x201a, 0x1078, 0x1a19, 0x007c,
- 0x2069, 0x3540, 0x6800, 0xa005, 0x0040, 0x3332, 0x683c, 0xac06,
- 0x0040, 0x336f, 0x6017, 0x0006, 0x60b0, 0xa084, 0x3f00, 0x601a,
- 0x601c, 0xa084, 0x00ff, 0xa085, 0x0060, 0x601e, 0x6000, 0x2042,
- 0x6710, 0x6fb6, 0x1078, 0x1692, 0x6818, 0xa005, 0x0040, 0x334a,
- 0x8001, 0x681a, 0x6808, 0xa084, 0xffef, 0x680a, 0x6810, 0x8001,
- 0x00d0, 0x3354, 0x1078, 0x1ba5, 0x6812, 0x602f, 0x0000, 0x602b,
- 0x0000, 0x2c68, 0x1078, 0x17dd, 0x2069, 0x3540, 0x2001, 0x0006,
- 0x68a2, 0x7944, 0xa184, 0x0100, 0x00c0, 0x336a, 0x69ba, 0x2001,
- 0x0004, 0x68a2, 0x1078, 0x1a14, 0x2091, 0x8001, 0x007c, 0x2009,
- 0x354f, 0x2164, 0x2069, 0x0100, 0x1078, 0x1b6b, 0x6017, 0x0006,
- 0x6858, 0xa084, 0x3f00, 0x601a, 0x601c, 0xa084, 0x00ff, 0xa085,
- 0x0048, 0x601e, 0x602f, 0x0000, 0x602b, 0x0000, 0x6830, 0xa084,
- 0x0040, 0x0040, 0x33ab, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
- 0xa084, 0x0004, 0x0040, 0x3398, 0x0070, 0x3398, 0x0078, 0x338f,
- 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xa084, 0x0001, 0x0040,
- 0x33a5, 0x0070, 0x33a5, 0x0078, 0x339c, 0x20a9, 0x00fa, 0x0070,
- 0x33ab, 0x0078, 0x33a7, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b,
- 0x0046, 0x2009, 0x3568, 0x200b, 0x0007, 0x784c, 0x784a, 0x2091,
- 0x8001, 0x007c, 0x2079, 0x3500, 0x1078, 0x3403, 0x1078, 0x33cb,
- 0x1078, 0x33e0, 0x1078, 0x33f5, 0x7833, 0x0000, 0x7847, 0x0000,
- 0x784b, 0x0000, 0x007c, 0x2019, 0x000a, 0x2011, 0x3546, 0x2204,
- 0xa086, 0x0032, 0x0040, 0x33dd, 0x2019, 0x000c, 0x2204, 0xa086,
- 0x003c, 0x0040, 0x33dd, 0x2019, 0x0008, 0x7b2a, 0x7b2e, 0x007c,
- 0x2019, 0x0030, 0x2011, 0x3546, 0x2204, 0xa086, 0x0032, 0x0040,
- 0x33f2, 0x2019, 0x0039, 0x2204, 0xa086, 0x003c, 0x0040, 0x33f2,
- 0x2019, 0x0027, 0x7b36, 0x7b3a, 0x007c, 0x2019, 0x000d, 0x2011,
- 0x3546, 0x2204, 0xa086, 0x003c, 0x0040, 0x3400, 0x2019, 0x000a,
- 0x7b3e, 0x7b42, 0x007c, 0x2019, 0x2faf, 0x2011, 0x3546, 0x2204,
- 0xa086, 0x0032, 0x0040, 0x3415, 0x2019, 0x3971, 0x2204, 0xa086,
- 0x003c, 0x0040, 0x3415, 0x2019, 0x2626, 0x7b22, 0x7b26, 0x007c,
- 0x92a7
-};
-unsigned short __devinitdata sbus_risc_code_length01 = 0x2419;
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index a2ef03243a2..166417a6afb 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -169,12 +169,10 @@ scsi_pool_alloc_command(struct scsi_host_cmd_pool *pool, gfp_t gfp_mask)
{
struct scsi_cmnd *cmd;
- cmd = kmem_cache_alloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
+ cmd = kmem_cache_zalloc(pool->cmd_slab, gfp_mask | pool->gfp_mask);
if (!cmd)
return NULL;
- memset(cmd, 0, sizeof(*cmd));
-
cmd->sense_buffer = kmem_cache_alloc(pool->sense_slab,
gfp_mask | pool->gfp_mask);
if (!cmd->sense_buffer) {
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index 099b5455bbc..b1348136964 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -596,8 +596,6 @@ int __init scsi_init_devinfo(void)
error = -ENOMEM;
goto out;
}
-
- p->owner = THIS_MODULE;
#endif /* CONFIG_SCSI_PROC_FS */
out:
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 4b13e36d3aa..d1cb64ad1a3 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -791,7 +791,22 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
"%d bytes done.\n",
req->nr_sectors, good_bytes));
- /* A number of bytes were successfully read. If there
+ /*
+ * Recovered errors need reporting, but they're always treated
+ * as success, so fiddle the result code here. For BLOCK_PC
+ * we already took a copy of the original into rq->errors which
+ * is what gets returned to the user
+ */
+ if (sense_valid && sshdr.sense_key == RECOVERED_ERROR) {
+ if (!(req->cmd_flags & REQ_QUIET))
+ scsi_print_sense("", cmd);
+ result = 0;
+ /* BLOCK_PC may have set error */
+ error = 0;
+ }
+
+ /*
+ * A number of bytes were successfully read. If there
* are leftovers and there is some kind of error
* (result != 0), retry the rest.
*/
diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
index 82f7b2dd08a..77fbddb507f 100644
--- a/drivers/scsi/scsi_proc.c
+++ b/drivers/scsi/scsi_proc.c
@@ -115,8 +115,6 @@ void scsi_proc_hostdir_add(struct scsi_host_template *sht)
if (!sht->proc_dir)
printk(KERN_ERR "%s: proc_mkdir failed for %s\n",
__func__, sht->proc_name);
- else
- sht->proc_dir->owner = sht->module;
}
mutex_unlock(&global_host_template_mutex);
}
@@ -163,7 +161,6 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
}
p->write_proc = proc_scsi_write_proc;
- p->owner = sht->module;
}
/**
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index aeab5d9dff2..3fcb64b91c4 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1051,12 +1051,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
good_bytes = sd_completed_bytes(SCpnt);
break;
case RECOVERED_ERROR:
- /* Inform the user, but make sure that it's not treated
- * as a hard error.
- */
- scsi_print_sense("sd", SCpnt);
- SCpnt->result = 0;
- memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
good_bytes = scsi_bufflen(SCpnt);
break;
case NO_SENSE:
diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c
index c9146d751cb..4f618f48735 100644
--- a/drivers/scsi/ses.c
+++ b/drivers/scsi/ses.c
@@ -264,6 +264,7 @@ struct ses_host_edev {
struct enclosure_device *edev;
};
+#if 0
int ses_match_host(struct enclosure_device *edev, void *data)
{
struct ses_host_edev *sed = data;
@@ -280,6 +281,7 @@ int ses_match_host(struct enclosure_device *edev, void *data)
sed->edev = edev;
return 1;
}
+#endif /* 0 */
static void ses_process_descriptor(struct enclosure_component *ecomp,
unsigned char *desc)
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ffc87851f2e..82312df9b0b 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1312,8 +1312,10 @@ static void sg_rq_end_io(struct request *rq, int uptodate)
wake_up_interruptible(&sfp->read_wait);
kill_fasync(&sfp->async_qp, SIGPOLL, POLL_IN);
kref_put(&sfp->f_ref, sg_remove_sfp);
- } else
- execute_in_process_context(sg_rq_end_io_usercontext, &srp->ew);
+ } else {
+ INIT_WORK(&srp->ew.work, sg_rq_end_io_usercontext);
+ schedule_work(&srp->ew.work);
+ }
}
static struct file_operations sg_fops = {
@@ -1656,10 +1658,30 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
md->null_mapped = hp->dxferp ? 0 : 1;
}
- if (iov_count)
- res = blk_rq_map_user_iov(q, rq, md, hp->dxferp, iov_count,
- hp->dxfer_len, GFP_ATOMIC);
- else
+ if (iov_count) {
+ int len, size = sizeof(struct sg_iovec) * iov_count;
+ struct iovec *iov;
+
+ iov = kmalloc(size, GFP_ATOMIC);
+ if (!iov)
+ return -ENOMEM;
+
+ if (copy_from_user(iov, hp->dxferp, size)) {
+ kfree(iov);
+ return -EFAULT;
+ }
+
+ len = iov_length(iov, iov_count);
+ if (hp->dxfer_len < len) {
+ iov_count = iov_shorten(iov, iov_count, hp->dxfer_len);
+ len = hp->dxfer_len;
+ }
+
+ res = blk_rq_map_user_iov(q, rq, md, (struct sg_iovec *)iov,
+ iov_count,
+ len, GFP_ATOMIC);
+ kfree(iov);
+ } else
res = blk_rq_map_user(q, rq, md, hp->dxferp,
hp->dxfer_len, GFP_ATOMIC);
@@ -2079,7 +2101,8 @@ static void sg_remove_sfp(struct kref *kref)
write_unlock_irqrestore(&sg_index_lock, iflags);
wake_up_interruptible(&sdp->o_excl_wait);
- execute_in_process_context(sg_remove_sfp_usercontext, &sfp->ew);
+ INIT_WORK(&sfp->ew.work, sg_remove_sfp_usercontext);
+ schedule_work(&sfp->ew.work);
}
static int
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index e7fa3caead7..0e1a0f2d2ad 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -309,15 +309,6 @@ static int sr_done(struct scsi_cmnd *SCpnt)
break;
case RECOVERED_ERROR:
-
- /*
- * An error occured, but it recovered. Inform the
- * user, but make sure that it's not treated as a
- * hard error.
- */
- scsi_print_sense("sr", SCpnt);
- SCpnt->result = 0;
- SCpnt->sense_buffer[0] = 0x0;
good_bytes = this_count;
break;
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 47b614e8580..df7f96caa1c 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -36,11 +36,11 @@
#include <scsi/scsi_eh.h>
#define DRV_NAME "stex"
-#define ST_DRIVER_VERSION "4.6.0000.1"
-#define ST_VER_MAJOR 4
-#define ST_VER_MINOR 6
-#define ST_OEM 0
-#define ST_BUILD_VER 1
+#define ST_DRIVER_VERSION "4.6.0000.3"
+#define ST_VER_MAJOR 4
+#define ST_VER_MINOR 6
+#define ST_OEM 0
+#define ST_BUILD_VER 3
enum {
/* MU register offset */
@@ -55,6 +55,13 @@ enum {
OIS = 0x30, /* MU_OUTBOUND_INTERRUPT_STATUS */
OIM = 0x3c, /* MU_OUTBOUND_INTERRUPT_MASK */
+ YH2I_INT = 0x20,
+ YINT_EN = 0x34,
+ YI2H_INT = 0x9c,
+ YI2H_INT_C = 0xa0,
+ YH2I_REQ = 0xc0,
+ YH2I_REQ_HI = 0xc4,
+
/* MU register value */
MU_INBOUND_DOORBELL_HANDSHAKE = 1,
MU_INBOUND_DOORBELL_REQHEADCHANGED = 2,
@@ -95,20 +102,14 @@ enum {
TASK_ATTRIBUTE_ORDERED = 0x2,
TASK_ATTRIBUTE_ACA = 0x4,
- /* request count, etc. */
- MU_MAX_REQUEST = 32,
+ SS_STS_NORMAL = 0x80000000,
+ SS_STS_DONE = 0x40000000,
+ SS_STS_HANDSHAKE = 0x20000000,
- /* one message wasted, use MU_MAX_REQUEST+1
- to handle MU_MAX_REQUEST messages */
- MU_REQ_COUNT = (MU_MAX_REQUEST + 1),
- MU_STATUS_COUNT = (MU_MAX_REQUEST + 1),
+ SS_HEAD_HANDSHAKE = 0x80,
STEX_CDB_LENGTH = 16,
- REQ_VARIABLE_LEN = 1024,
STATUS_VAR_LEN = 128,
- ST_CAN_QUEUE = MU_MAX_REQUEST,
- ST_CMD_PER_LUN = MU_MAX_REQUEST,
- ST_MAX_SG = 32,
/* sg flags */
SG_CF_EOT = 0x80, /* end of table */
@@ -120,9 +121,9 @@ enum {
st_shasta = 0,
st_vsc = 1,
- st_vsc1 = 2,
- st_yosemite = 3,
- st_seq = 4,
+ st_yosemite = 2,
+ st_seq = 3,
+ st_yel = 4,
PASSTHRU_REQ_TYPE = 0x00000001,
PASSTHRU_REQ_NO_WAKEUP = 0x00000100,
@@ -160,26 +161,36 @@ struct st_sgitem {
u8 ctrl; /* SG_CF_xxx */
u8 reserved[3];
__le32 count;
+ __le64 addr;
+};
+
+struct st_ss_sgitem {
__le32 addr;
__le32 addr_hi;
+ __le32 count;
};
struct st_sgtable {
__le16 sg_count;
__le16 max_sg_count;
__le32 sz_in_byte;
- struct st_sgitem table[ST_MAX_SG];
+};
+
+struct st_msg_header {
+ __le64 handle;
+ u8 flag;
+ u8 channel;
+ __le16 timeout;
+ u32 reserved;
};
struct handshake_frame {
- __le32 rb_phy; /* request payload queue physical address */
- __le32 rb_phy_hi;
+ __le64 rb_phy; /* request payload queue physical address */
__le16 req_sz; /* size of each request payload */
__le16 req_cnt; /* count of reqs the buffer can hold */
__le16 status_sz; /* size of each status payload */
__le16 status_cnt; /* count of status the buffer can hold */
- __le32 hosttime; /* seconds from Jan 1, 1970 (GMT) */
- __le32 hosttime_hi;
+ __le64 hosttime; /* seconds from Jan 1, 1970 (GMT) */
u8 partner_type; /* who sends this frame */
u8 reserved0[7];
__le32 partner_ver_major;
@@ -188,7 +199,8 @@ struct handshake_frame {
__le32 partner_ver_build;
__le32 extra_offset; /* NEW */
__le32 extra_size; /* NEW */
- u32 reserved1[2];
+ __le32 scratch_size;
+ u32 reserved1;
};
struct req_msg {
@@ -200,7 +212,7 @@ struct req_msg {
u8 data_dir;
u8 payload_sz; /* payload size in 4-byte, not used */
u8 cdb[STEX_CDB_LENGTH];
- u8 variable[REQ_VARIABLE_LEN];
+ u32 variable[0];
};
struct status_msg {
@@ -256,12 +268,6 @@ struct st_drvver {
u32 reserved[3];
};
-#define MU_REQ_BUFFER_SIZE (MU_REQ_COUNT * sizeof(struct req_msg))
-#define MU_STATUS_BUFFER_SIZE (MU_STATUS_COUNT * sizeof(struct status_msg))
-#define MU_BUFFER_SIZE (MU_REQ_BUFFER_SIZE + MU_STATUS_BUFFER_SIZE)
-#define STEX_EXTRA_SIZE sizeof(struct st_frame)
-#define STEX_BUFFER_SIZE (MU_BUFFER_SIZE + STEX_EXTRA_SIZE)
-
struct st_ccb {
struct req_msg *req;
struct scsi_cmnd *cmd;
@@ -273,6 +279,7 @@ struct st_ccb {
u32 req_type;
u8 srb_status;
u8 scsi_status;
+ u8 reserved[2];
};
struct st_hba {
@@ -284,6 +291,10 @@ struct st_hba {
struct Scsi_Host *host;
struct pci_dev *pdev;
+ struct req_msg * (*alloc_rq) (struct st_hba *);
+ int (*map_sg)(struct st_hba *, struct req_msg *, struct st_ccb *);
+ void (*send) (struct st_hba *, struct req_msg *, u16);
+
u32 req_head;
u32 req_tail;
u32 status_head;
@@ -291,16 +302,36 @@ struct st_hba {
struct status_msg *status_buffer;
void *copy_buffer; /* temp buffer for driver-handled commands */
- struct st_ccb ccb[MU_MAX_REQUEST];
+ struct st_ccb *ccb;
struct st_ccb *wait_ccb;
- wait_queue_head_t waitq;
+ __le32 *scratch;
unsigned int mu_status;
+ unsigned int cardtype;
+ int msi_enabled;
int out_req_cnt;
+ u32 extra_offset;
+ u16 rq_count;
+ u16 rq_size;
+ u16 sts_count;
+};
- unsigned int cardtype;
+struct st_card_info {
+ struct req_msg * (*alloc_rq) (struct st_hba *);
+ int (*map_sg)(struct st_hba *, struct req_msg *, struct st_ccb *);
+ void (*send) (struct st_hba *, struct req_msg *, u16);
+ unsigned int max_id;
+ unsigned int max_lun;
+ unsigned int max_channel;
+ u16 rq_count;
+ u16 rq_size;
+ u16 sts_count;
};
+static int msi;
+module_param(msi, int, 0);
+MODULE_PARM_DESC(msi, "Enable Message Signaled Interrupts(0=off, 1=on)");
+
static const char console_inq_page[] =
{
0x03,0x00,0x03,0x03,0xFA,0x00,0x00,0x30,
@@ -318,22 +349,20 @@ MODULE_DESCRIPTION("Promise Technology SuperTrak EX Controllers");
MODULE_LICENSE("GPL");
MODULE_VERSION(ST_DRIVER_VERSION);
-static void stex_gettime(__le32 *time)
+static void stex_gettime(__le64 *time)
{
struct timeval tv;
do_gettimeofday(&tv);
- *time = cpu_to_le32(tv.tv_sec & 0xffffffff);
- *(time + 1) = cpu_to_le32((tv.tv_sec >> 16) >> 16);
+ *time = cpu_to_le64(tv.tv_sec);
}
static struct status_msg *stex_get_status(struct st_hba *hba)
{
- struct status_msg *status =
- hba->status_buffer + hba->status_tail;
+ struct status_msg *status = hba->status_buffer + hba->status_tail;
++hba->status_tail;
- hba->status_tail %= MU_STATUS_COUNT;
+ hba->status_tail %= hba->sts_count+1;
return status;
}
@@ -351,47 +380,83 @@ static void stex_invalid_field(struct scsi_cmnd *cmd,
static struct req_msg *stex_alloc_req(struct st_hba *hba)
{
- struct req_msg *req = ((struct req_msg *)hba->dma_mem) +
- hba->req_head;
+ struct req_msg *req = hba->dma_mem + hba->req_head * hba->rq_size;
++hba->req_head;
- hba->req_head %= MU_REQ_COUNT;
+ hba->req_head %= hba->rq_count+1;
return req;
}
+static struct req_msg *stex_ss_alloc_req(struct st_hba *hba)
+{
+ return (struct req_msg *)(hba->dma_mem +
+ hba->req_head * hba->rq_size + sizeof(struct st_msg_header));
+}
+
static int stex_map_sg(struct st_hba *hba,
struct req_msg *req, struct st_ccb *ccb)
{
struct scsi_cmnd *cmd;
struct scatterlist *sg;
struct st_sgtable *dst;
+ struct st_sgitem *table;
int i, nseg;
cmd = ccb->cmd;
- dst = (struct st_sgtable *)req->variable;
- dst->max_sg_count = cpu_to_le16(ST_MAX_SG);
- dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
+ nseg = scsi_dma_map(cmd);
+ BUG_ON(nseg < 0);
+ if (nseg) {
+ dst = (struct st_sgtable *)req->variable;
+
+ ccb->sg_count = nseg;
+ dst->sg_count = cpu_to_le16((u16)nseg);
+ dst->max_sg_count = cpu_to_le16(hba->host->sg_tablesize);
+ dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
+
+ table = (struct st_sgitem *)(dst + 1);
+ scsi_for_each_sg(cmd, sg, nseg, i) {
+ table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
+ table[i].addr = cpu_to_le64(sg_dma_address(sg));
+ table[i].ctrl = SG_CF_64B | SG_CF_HOST;
+ }
+ table[--i].ctrl |= SG_CF_EOT;
+ }
+
+ return nseg;
+}
+
+static int stex_ss_map_sg(struct st_hba *hba,
+ struct req_msg *req, struct st_ccb *ccb)
+{
+ struct scsi_cmnd *cmd;
+ struct scatterlist *sg;
+ struct st_sgtable *dst;
+ struct st_ss_sgitem *table;
+ int i, nseg;
+ cmd = ccb->cmd;
nseg = scsi_dma_map(cmd);
- if (nseg < 0)
- return -EIO;
+ BUG_ON(nseg < 0);
if (nseg) {
+ dst = (struct st_sgtable *)req->variable;
+
ccb->sg_count = nseg;
dst->sg_count = cpu_to_le16((u16)nseg);
+ dst->max_sg_count = cpu_to_le16(hba->host->sg_tablesize);
+ dst->sz_in_byte = cpu_to_le32(scsi_bufflen(cmd));
+ table = (struct st_ss_sgitem *)(dst + 1);
scsi_for_each_sg(cmd, sg, nseg, i) {
- dst->table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
- dst->table[i].addr =
+ table[i].count = cpu_to_le32((u32)sg_dma_len(sg));
+ table[i].addr =
cpu_to_le32(sg_dma_address(sg) & 0xffffffff);
- dst->table[i].addr_hi =
+ table[i].addr_hi =
cpu_to_le32((sg_dma_address(sg) >> 16) >> 16);
- dst->table[i].ctrl = SG_CF_64B | SG_CF_HOST;
}
- dst->table[--i].ctrl |= SG_CF_EOT;
}
- return 0;
+ return nseg;
}
static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
@@ -400,7 +465,7 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
size_t count = sizeof(struct st_frame);
p = hba->copy_buffer;
- count = scsi_sg_copy_to_buffer(ccb->cmd, p, count);
+ scsi_sg_copy_to_buffer(ccb->cmd, p, count);
memset(p->base, 0, sizeof(u32)*6);
*(unsigned long *)(p->base) = pci_resource_start(hba->pdev, 0);
p->rom_addr = 0;
@@ -418,15 +483,13 @@ static void stex_controller_info(struct st_hba *hba, struct st_ccb *ccb)
p->subid =
hba->pdev->subsystem_vendor << 16 | hba->pdev->subsystem_device;
- count = scsi_sg_copy_from_buffer(ccb->cmd, p, count);
+ scsi_sg_copy_from_buffer(ccb->cmd, p, count);
}
static void
stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
{
req->tag = cpu_to_le16(tag);
- req->task_attr = TASK_ATTRIBUTE_SIMPLE;
- req->task_manage = 0; /* not supported yet */
hba->ccb[tag].req = req;
hba->out_req_cnt++;
@@ -436,13 +499,44 @@ stex_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
readl(hba->mmio_base + IDBL); /* flush */
}
+static void
+stex_ss_send_cmd(struct st_hba *hba, struct req_msg *req, u16 tag)
+{
+ struct scsi_cmnd *cmd;
+ struct st_msg_header *msg_h;
+ dma_addr_t addr;
+
+ req->tag = cpu_to_le16(tag);
+
+ hba->ccb[tag].req = req;
+ hba->out_req_cnt++;
+
+ cmd = hba->ccb[tag].cmd;
+ msg_h = (struct st_msg_header *)req - 1;
+ if (likely(cmd)) {
+ msg_h->channel = (u8)cmd->device->channel;
+ msg_h->timeout = cpu_to_le16(cmd->request->timeout/HZ);
+ }
+ addr = hba->dma_handle + hba->req_head * hba->rq_size;
+ addr += (hba->ccb[tag].sg_count+4)/11;
+ msg_h->handle = cpu_to_le64(addr);
+
+ ++hba->req_head;
+ hba->req_head %= hba->rq_count+1;
+
+ writel((addr >> 16) >> 16, hba->mmio_base + YH2I_REQ_HI);
+ readl(hba->mmio_base + YH2I_REQ_HI); /* flush */
+ writel(addr, hba->mmio_base + YH2I_REQ);
+ readl(hba->mmio_base + YH2I_REQ); /* flush */
+}
+
static int
stex_slave_alloc(struct scsi_device *sdev)
{
/* Cheat: usually extracted from Inquiry data */
sdev->tagged_supported = 1;
- scsi_activate_tcq(sdev, ST_CMD_PER_LUN);
+ scsi_activate_tcq(sdev, sdev->host->can_queue);
return 0;
}
@@ -469,7 +563,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
{
struct st_hba *hba;
struct Scsi_Host *host;
- unsigned int id,lun;
+ unsigned int id, lun;
struct req_msg *req;
u16 tag;
@@ -516,7 +610,8 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
case INQUIRY:
if (id != host->max_id - 1)
break;
- if (lun == 0 && (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
+ if (!lun && !cmd->device->channel &&
+ (cmd->cmnd[1] & INQUIRY_EVPD) == 0) {
scsi_sg_copy_from_buffer(cmd, (void *)console_inq_page,
sizeof(console_inq_page));
cmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8;
@@ -554,7 +649,7 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
if (unlikely(tag >= host->can_queue))
return SCSI_MLQUEUE_HOST_BUSY;
- req = stex_alloc_req(hba);
+ req = hba->alloc_rq(hba);
req->lun = lun;
req->target = id;
@@ -572,12 +667,13 @@ stex_queuecommand(struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
hba->ccb[tag].cmd = cmd;
hba->ccb[tag].sense_bufflen = SCSI_SENSE_BUFFERSIZE;
hba->ccb[tag].sense_buffer = cmd->sense_buffer;
- hba->ccb[tag].req_type = 0;
- if (cmd->sc_data_direction != DMA_NONE)
- stex_map_sg(hba, req, &hba->ccb[tag]);
+ if (!hba->map_sg(hba, req, &hba->ccb[tag])) {
+ hba->ccb[tag].sg_count = 0;
+ memset(&req->variable[0], 0, 8);
+ }
- stex_send_cmd(hba, req, tag);
+ hba->send(hba, req, tag);
return 0;
}
@@ -586,7 +682,7 @@ static void stex_scsi_done(struct st_ccb *ccb)
struct scsi_cmnd *cmd = ccb->cmd;
int result;
- if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) {
+ if (ccb->srb_status == SRB_STATUS_SUCCESS || ccb->srb_status == 0) {
result = ccb->scsi_status;
switch (ccb->scsi_status) {
case SAM_STAT_GOOD:
@@ -626,8 +722,6 @@ static void stex_scsi_done(struct st_ccb *ccb)
static void stex_copy_data(struct st_ccb *ccb,
struct status_msg *resp, unsigned int variable)
{
- size_t count = variable;
-
if (resp->scsi_status != SAM_STAT_GOOD) {
if (ccb->sense_buffer != NULL)
memcpy(ccb->sense_buffer, resp->variable,
@@ -637,17 +731,16 @@ static void stex_copy_data(struct st_ccb *ccb,
if (ccb->cmd == NULL)
return;
- count = scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, count);
+ scsi_sg_copy_from_buffer(ccb->cmd, resp->variable, variable);
}
-static void stex_ys_commands(struct st_hba *hba,
+static void stex_check_cmd(struct st_hba *hba,
struct st_ccb *ccb, struct status_msg *resp)
{
if (ccb->cmd->cmnd[0] == MGT_CMD &&
- resp->scsi_status != SAM_STAT_CHECK_CONDITION) {
+ resp->scsi_status != SAM_STAT_CHECK_CONDITION)
scsi_set_resid(ccb->cmd, scsi_bufflen(ccb->cmd) -
le32_to_cpu(*(__le32 *)&resp->variable[0]));
- }
}
static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
@@ -658,12 +751,12 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
unsigned int size;
u16 tag;
- if (!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED))
+ if (unlikely(!(doorbell & MU_OUTBOUND_DOORBELL_STATUSHEADCHANGED)))
return;
/* status payloads */
hba->status_head = readl(base + OMR1);
- if (unlikely(hba->status_head >= MU_STATUS_COUNT)) {
+ if (unlikely(hba->status_head > hba->sts_count)) {
printk(KERN_WARNING DRV_NAME "(%s): invalid status head\n",
pci_name(hba->pdev));
return;
@@ -693,13 +786,13 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
continue;
}
+ hba->out_req_cnt--;
ccb = &hba->ccb[tag];
- if (hba->wait_ccb == ccb)
+ if (unlikely(hba->wait_ccb == ccb))
hba->wait_ccb = NULL;
if (unlikely(ccb->req == NULL)) {
printk(KERN_WARNING DRV_NAME
"(%s): lagging req\n", pci_name(hba->pdev));
- hba->out_req_cnt--;
continue;
}
@@ -720,7 +813,7 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
if (likely(ccb->cmd != NULL)) {
if (hba->cardtype == st_yosemite)
- stex_ys_commands(hba, ccb, resp);
+ stex_check_cmd(hba, ccb, resp);
if (unlikely(ccb->cmd->cmnd[0] == PASSTHRU_CMD &&
ccb->cmd->cmnd[1] == PASSTHRU_GET_ADAPTER))
@@ -728,17 +821,8 @@ static void stex_mu_intr(struct st_hba *hba, u32 doorbell)
scsi_dma_unmap(ccb->cmd);
stex_scsi_done(ccb);
- hba->out_req_cnt--;
- } else if (ccb->req_type & PASSTHRU_REQ_TYPE) {
- hba->out_req_cnt--;
- if (ccb->req_type & PASSTHRU_REQ_NO_WAKEUP) {
- ccb->req_type = 0;
- continue;
- }
+ } else
ccb->req_type = 0;
- if (waitqueue_active(&hba->waitq))
- wake_up(&hba->waitq);
- }
}
update_status:
@@ -771,7 +855,103 @@ static irqreturn_t stex_intr(int irq, void *__hba)
return IRQ_RETVAL(handled);
}
-static int stex_handshake(struct st_hba *hba)
+static void stex_ss_mu_intr(struct st_hba *hba)
+{
+ struct status_msg *resp;
+ struct st_ccb *ccb;
+ __le32 *scratch;
+ unsigned int size;
+ int count = 0;
+ u32 value;
+ u16 tag;
+
+ if (unlikely(hba->out_req_cnt <= 0 ||
+ hba->mu_status == MU_STATE_RESETTING))
+ return;
+
+ while (count < hba->sts_count) {
+ scratch = hba->scratch + hba->status_tail;
+ value = le32_to_cpu(*scratch);
+ if (unlikely(!(value & SS_STS_NORMAL)))
+ return;
+
+ resp = hba->status_buffer + hba->status_tail;
+ *scratch = 0;
+ ++count;
+ ++hba->status_tail;
+ hba->status_tail %= hba->sts_count+1;
+
+ tag = (u16)value;
+ if (unlikely(tag >= hba->host->can_queue)) {
+ printk(KERN_WARNING DRV_NAME
+ "(%s): invalid tag\n", pci_name(hba->pdev));
+ continue;
+ }
+
+ hba->out_req_cnt--;
+ ccb = &hba->ccb[tag];
+ if (unlikely(hba->wait_ccb == ccb))
+ hba->wait_ccb = NULL;
+ if (unlikely(ccb->req == NULL)) {
+ printk(KERN_WARNING DRV_NAME
+ "(%s): lagging req\n", pci_name(hba->pdev));
+ continue;
+ }
+
+ ccb->req = NULL;
+ if (likely(value & SS_STS_DONE)) { /* normal case */
+ ccb->srb_status = SRB_STATUS_SUCCESS;
+ ccb->scsi_status = SAM_STAT_GOOD;
+ } else {
+ ccb->srb_status = resp->srb_status;
+ ccb->scsi_status = resp->scsi_status;
+ size = resp->payload_sz * sizeof(u32);
+ if (unlikely(size < sizeof(*resp) - STATUS_VAR_LEN ||
+ size > sizeof(*resp))) {
+ printk(KERN_WARNING DRV_NAME
+ "(%s): bad status size\n",
+ pci_name(hba->pdev));
+ } else {
+ size -= sizeof(*resp) - STATUS_VAR_LEN;
+ if (size)
+ stex_copy_data(ccb, resp, size);
+ }
+ if (likely(ccb->cmd != NULL))
+ stex_check_cmd(hba, ccb, resp);
+ }
+
+ if (likely(ccb->cmd != NULL)) {
+ scsi_dma_unmap(ccb->cmd);
+ stex_scsi_done(ccb);
+ } else
+ ccb->req_type = 0;
+ }
+}
+
+static irqreturn_t stex_ss_intr(int irq, void *__hba)
+{
+ struct st_hba *hba = __hba;
+ void __iomem *base = hba->mmio_base;
+ u32 data;
+ unsigned long flags;
+ int handled = 0;
+
+ spin_lock_irqsave(hba->host->host_lock, flags);
+
+ data = readl(base + YI2H_INT);
+ if (data && data != 0xffffffff) {
+ /* clear the interrupt */
+ writel(data, base + YI2H_INT_C);
+ stex_ss_mu_intr(hba);
+ handled = 1;
+ }
+
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+
+ return IRQ_RETVAL(handled);
+}
+
+static int stex_common_handshake(struct st_hba *hba)
{
void __iomem *base = hba->mmio_base;
struct handshake_frame *h;
@@ -800,26 +980,27 @@ static int stex_handshake(struct st_hba *hba)
data = readl(base + OMR1);
if ((data & 0xffff0000) == MU_HANDSHAKE_SIGNATURE_HALF) {
data &= 0x0000ffff;
- if (hba->host->can_queue > data)
+ if (hba->host->can_queue > data) {
hba->host->can_queue = data;
+ hba->host->cmd_per_lun = data;
+ }
}
- h = (struct handshake_frame *)(hba->dma_mem + MU_REQ_BUFFER_SIZE);
- h->rb_phy = cpu_to_le32(hba->dma_handle);
- h->rb_phy_hi = cpu_to_le32((hba->dma_handle >> 16) >> 16);
- h->req_sz = cpu_to_le16(sizeof(struct req_msg));
- h->req_cnt = cpu_to_le16(MU_REQ_COUNT);
+ h = (struct handshake_frame *)hba->status_buffer;
+ h->rb_phy = cpu_to_le64(hba->dma_handle);
+ h->req_sz = cpu_to_le16(hba->rq_size);
+ h->req_cnt = cpu_to_le16(hba->rq_count+1);
h->status_sz = cpu_to_le16(sizeof(struct status_msg));
- h->status_cnt = cpu_to_le16(MU_STATUS_COUNT);
+ h->status_cnt = cpu_to_le16(hba->sts_count+1);
stex_gettime(&h->hosttime);
h->partner_type = HMU_PARTNER_TYPE;
- if (hba->dma_size > STEX_BUFFER_SIZE) {
- h->extra_offset = cpu_to_le32(STEX_BUFFER_SIZE);
+ if (hba->extra_offset) {
+ h->extra_offset = cpu_to_le32(hba->extra_offset);
h->extra_size = cpu_to_le32(ST_ADDITIONAL_MEM);
} else
h->extra_offset = h->extra_size = 0;
- status_phys = hba->dma_handle + MU_REQ_BUFFER_SIZE;
+ status_phys = hba->dma_handle + (hba->rq_count+1) * hba->rq_size;
writel(status_phys, base + IMR0);
readl(base + IMR0);
writel((status_phys >> 16) >> 16, base + IMR1);
@@ -851,10 +1032,79 @@ static int stex_handshake(struct st_hba *hba)
readl(base + IMR1);
writel(0, base + OMR1);
readl(base + OMR1); /* flush */
- hba->mu_status = MU_STATE_STARTED;
return 0;
}
+static int stex_ss_handshake(struct st_hba *hba)
+{
+ void __iomem *base = hba->mmio_base;
+ struct st_msg_header *msg_h;
+ struct handshake_frame *h;
+ __le32 *scratch = hba->scratch;
+ u32 data;
+ unsigned long before;
+ int ret = 0;
+
+ h = (struct handshake_frame *)(hba->alloc_rq(hba));
+ msg_h = (struct st_msg_header *)h - 1;
+ msg_h->handle = cpu_to_le64(hba->dma_handle);
+ msg_h->flag = SS_HEAD_HANDSHAKE;
+
+ h->rb_phy = cpu_to_le64(hba->dma_handle);
+ h->req_sz = cpu_to_le16(hba->rq_size);
+ h->req_cnt = cpu_to_le16(hba->rq_count+1);
+ h->status_sz = cpu_to_le16(sizeof(struct status_msg));
+ h->status_cnt = cpu_to_le16(hba->sts_count+1);
+ stex_gettime(&h->hosttime);
+ h->partner_type = HMU_PARTNER_TYPE;
+ h->extra_offset = h->extra_size = 0;
+ h->scratch_size = cpu_to_le32((hba->sts_count+1)*sizeof(u32));
+
+ data = readl(base + YINT_EN);
+ data &= ~4;
+ writel(data, base + YINT_EN);
+ writel((hba->dma_handle >> 16) >> 16, base + YH2I_REQ_HI);
+ writel(hba->dma_handle, base + YH2I_REQ);
+
+ scratch = hba->scratch;
+ before = jiffies;
+ while (!(le32_to_cpu(*scratch) & SS_STS_HANDSHAKE)) {
+ if (time_after(jiffies, before + MU_MAX_DELAY * HZ)) {
+ printk(KERN_ERR DRV_NAME
+ "(%s): no signature after handshake frame\n",
+ pci_name(hba->pdev));
+ ret = -1;
+ break;
+ }
+ rmb();
+ msleep(1);
+ }
+
+ *scratch = 0;
+ msg_h->flag = 0;
+ return ret;
+}
+
+static int stex_handshake(struct st_hba *hba)
+{
+ int err;
+ unsigned long flags;
+
+ err = (hba->cardtype == st_yel) ?
+ stex_ss_handshake(hba) : stex_common_handshake(hba);
+ if (err == 0) {
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ hba->req_head = 0;
+ hba->req_tail = 0;
+ hba->status_head = 0;
+ hba->status_tail = 0;
+ hba->out_req_cnt = 0;
+ hba->mu_status = MU_STATE_STARTED;
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
+ }
+ return err;
+}
+
static int stex_abort(struct scsi_cmnd *cmd)
{
struct Scsi_Host *host = cmd->device->host;
@@ -883,15 +1133,23 @@ static int stex_abort(struct scsi_cmnd *cmd)
goto out;
}
- data = readl(base + ODBL);
- if (data == 0 || data == 0xffffffff)
- goto fail_out;
+ if (hba->cardtype == st_yel) {
+ data = readl(base + YI2H_INT);
+ if (data == 0 || data == 0xffffffff)
+ goto fail_out;
- writel(data, base + ODBL);
- readl(base + ODBL); /* flush */
+ writel(data, base + YI2H_INT_C);
+ stex_ss_mu_intr(hba);
+ } else {
+ data = readl(base + ODBL);
+ if (data == 0 || data == 0xffffffff)
+ goto fail_out;
- stex_mu_intr(hba, data);
+ writel(data, base + ODBL);
+ readl(base + ODBL); /* flush */
+ stex_mu_intr(hba, data);
+ }
if (hba->wait_ccb == NULL) {
printk(KERN_WARNING DRV_NAME
"(%s): lost interrupt\n", pci_name(hba->pdev));
@@ -950,8 +1208,8 @@ static void stex_hard_reset(struct st_hba *hba)
static int stex_reset(struct scsi_cmnd *cmd)
{
struct st_hba *hba;
- unsigned long flags;
- unsigned long before;
+ void __iomem *base;
+ unsigned long flags, before;
hba = (struct st_hba *) &cmd->device->host->hostdata[0];
@@ -971,13 +1229,6 @@ static int stex_reset(struct scsi_cmnd *cmd)
pci_name(hba->pdev));
return FAILED;
}
- spin_lock_irqsave(hba->host->host_lock, flags);
- hba->req_head = 0;
- hba->req_tail = 0;
- hba->status_head = 0;
- hba->status_tail = 0;
- hba->out_req_cnt = 0;
- spin_unlock_irqrestore(hba->host->host_lock, flags);
return SUCCESS;
}
@@ -994,7 +1245,23 @@ static int stex_reset(struct scsi_cmnd *cmd)
msleep(1);
}
+ base = hba->mmio_base;
+ writel(0, base + IMR0);
+ readl(base + IMR0);
+ writel(0, base + OMR0);
+ readl(base + OMR0);
+ writel(0, base + IMR1);
+ readl(base + IMR1);
+ writel(0, base + OMR1);
+ readl(base + OMR1); /* flush */
+ spin_lock_irqsave(hba->host->host_lock, flags);
+ hba->req_head = 0;
+ hba->req_tail = 0;
+ hba->status_head = 0;
+ hba->status_tail = 0;
+ hba->out_req_cnt = 0;
hba->mu_status = MU_STATE_STARTED;
+ spin_unlock_irqrestore(hba->host->host_lock, flags);
return SUCCESS;
}
@@ -1028,10 +1295,100 @@ static struct scsi_host_template driver_template = {
.slave_destroy = stex_slave_destroy,
.eh_abort_handler = stex_abort,
.eh_host_reset_handler = stex_reset,
- .can_queue = ST_CAN_QUEUE,
.this_id = -1,
- .sg_tablesize = ST_MAX_SG,
- .cmd_per_lun = ST_CMD_PER_LUN,
+};
+
+static struct pci_device_id stex_pci_tbl[] = {
+ /* st_shasta */
+ { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */
+ { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX12350 */
+ { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX4350 */
+ { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ st_shasta }, /* SuperTrak EX24350 */
+
+ /* st_vsc */
+ { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
+
+ /* st_yosemite */
+ { 0x105a, 0x8650, 0x105a, PCI_ANY_ID, 0, 0, st_yosemite },
+
+ /* st_seq */
+ { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
+
+ /* st_yel */
+ { 0x105a, 0x8650, 0x1033, PCI_ANY_ID, 0, 0, st_yel },
+ { 0x105a, 0x8760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yel },
+ { } /* terminate list */
+};
+
+static struct st_card_info stex_card_info[] = {
+ /* st_shasta */
+ {
+ .max_id = 17,
+ .max_lun = 8,
+ .max_channel = 0,
+ .rq_count = 32,
+ .rq_size = 1048,
+ .sts_count = 32,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_vsc */
+ {
+ .max_id = 129,
+ .max_lun = 1,
+ .max_channel = 0,
+ .rq_count = 32,
+ .rq_size = 1048,
+ .sts_count = 32,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_yosemite */
+ {
+ .max_id = 2,
+ .max_lun = 256,
+ .max_channel = 0,
+ .rq_count = 256,
+ .rq_size = 1048,
+ .sts_count = 256,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_seq */
+ {
+ .max_id = 129,
+ .max_lun = 1,
+ .max_channel = 0,
+ .rq_count = 32,
+ .rq_size = 1048,
+ .sts_count = 32,
+ .alloc_rq = stex_alloc_req,
+ .map_sg = stex_map_sg,
+ .send = stex_send_cmd,
+ },
+
+ /* st_yel */
+ {
+ .max_id = 129,
+ .max_lun = 256,
+ .max_channel = 3,
+ .rq_count = 801,
+ .rq_size = 512,
+ .sts_count = 801,
+ .alloc_rq = stex_ss_alloc_req,
+ .map_sg = stex_ss_map_sg,
+ .send = stex_ss_send_cmd,
+ },
};
static int stex_set_dma_mask(struct pci_dev * pdev)
@@ -1047,11 +1404,48 @@ static int stex_set_dma_mask(struct pci_dev * pdev)
return ret;
}
+static int stex_request_irq(struct st_hba *hba)
+{
+ struct pci_dev *pdev = hba->pdev;
+ int status;
+
+ if (msi) {
+ status = pci_enable_msi(pdev);
+ if (status != 0)
+ printk(KERN_ERR DRV_NAME
+ "(%s): error %d setting up MSI\n",
+ pci_name(pdev), status);
+ else
+ hba->msi_enabled = 1;
+ } else
+ hba->msi_enabled = 0;
+
+ status = request_irq(pdev->irq, hba->cardtype == st_yel ?
+ stex_ss_intr : stex_intr, IRQF_SHARED, DRV_NAME, hba);
+
+ if (status != 0) {
+ if (hba->msi_enabled)
+ pci_disable_msi(pdev);
+ }
+ return status;
+}
+
+static void stex_free_irq(struct st_hba *hba)
+{
+ struct pci_dev *pdev = hba->pdev;
+
+ free_irq(pdev->irq, hba);
+ if (hba->msi_enabled)
+ pci_disable_msi(pdev);
+}
+
static int __devinit
stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
struct st_hba *hba;
struct Scsi_Host *host;
+ const struct st_card_info *ci = NULL;
+ u32 sts_offset, cp_offset, scratch_offset;
int err;
err = pci_enable_device(pdev);
@@ -1095,10 +1489,17 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
}
hba->cardtype = (unsigned int) id->driver_data;
- if (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))
- hba->cardtype = st_vsc1;
- hba->dma_size = (hba->cardtype == st_vsc1 || hba->cardtype == st_seq) ?
- (STEX_BUFFER_SIZE + ST_ADDITIONAL_MEM) : (STEX_BUFFER_SIZE);
+ ci = &stex_card_info[hba->cardtype];
+ sts_offset = scratch_offset = (ci->rq_count+1) * ci->rq_size;
+ if (hba->cardtype == st_yel)
+ sts_offset += (ci->sts_count+1) * sizeof(u32);
+ cp_offset = sts_offset + (ci->sts_count+1) * sizeof(struct status_msg);
+ hba->dma_size = cp_offset + sizeof(struct st_frame);
+ if (hba->cardtype == st_seq ||
+ (hba->cardtype == st_vsc && (pdev->subsystem_device & 1))) {
+ hba->extra_offset = hba->dma_size;
+ hba->dma_size += ST_ADDITIONAL_MEM;
+ }
hba->dma_mem = dma_alloc_coherent(&pdev->dev,
hba->dma_size, &hba->dma_handle, GFP_KERNEL);
if (!hba->dma_mem) {
@@ -1108,35 +1509,46 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
goto out_iounmap;
}
- hba->status_buffer =
- (struct status_msg *)(hba->dma_mem + MU_REQ_BUFFER_SIZE);
- hba->copy_buffer = hba->dma_mem + MU_BUFFER_SIZE;
+ hba->ccb = kcalloc(ci->rq_count, sizeof(struct st_ccb), GFP_KERNEL);
+ if (!hba->ccb) {
+ err = -ENOMEM;
+ printk(KERN_ERR DRV_NAME "(%s): ccb alloc failed\n",
+ pci_name(pdev));
+ goto out_pci_free;
+ }
+
+ if (hba->cardtype == st_yel)
+ hba->scratch = (__le32 *)(hba->dma_mem + scratch_offset);
+ hba->status_buffer = (struct status_msg *)(hba->dma_mem + sts_offset);
+ hba->copy_buffer = hba->dma_mem + cp_offset;
+ hba->rq_count = ci->rq_count;
+ hba->rq_size = ci->rq_size;
+ hba->sts_count = ci->sts_count;
+ hba->alloc_rq = ci->alloc_rq;
+ hba->map_sg = ci->map_sg;
+ hba->send = ci->send;
hba->mu_status = MU_STATE_STARTING;
- if (hba->cardtype == st_shasta) {
- host->max_lun = 8;
- host->max_id = 16 + 1;
- } else if (hba->cardtype == st_yosemite) {
- host->max_lun = 256;
- host->max_id = 1 + 1;
- } else {
- /* st_vsc , st_vsc1 and st_seq */
- host->max_lun = 1;
- host->max_id = 128 + 1;
- }
- host->max_channel = 0;
+ if (hba->cardtype == st_yel)
+ host->sg_tablesize = 38;
+ else
+ host->sg_tablesize = 32;
+ host->can_queue = ci->rq_count;
+ host->cmd_per_lun = ci->rq_count;
+ host->max_id = ci->max_id;
+ host->max_lun = ci->max_lun;
+ host->max_channel = ci->max_channel;
host->unique_id = host->host_no;
host->max_cmd_len = STEX_CDB_LENGTH;
hba->host = host;
hba->pdev = pdev;
- init_waitqueue_head(&hba->waitq);
- err = request_irq(pdev->irq, stex_intr, IRQF_SHARED, DRV_NAME, hba);
+ err = stex_request_irq(hba);
if (err) {
printk(KERN_ERR DRV_NAME "(%s): request irq failed\n",
pci_name(pdev));
- goto out_pci_free;
+ goto out_ccb_free;
}
err = stex_handshake(hba);
@@ -1164,7 +1576,9 @@ stex_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return 0;
out_free_irq:
- free_irq(pdev->irq, hba);
+ stex_free_irq(hba);
+out_ccb_free:
+ kfree(hba->ccb);
out_pci_free:
dma_free_coherent(&pdev->dev, hba->dma_size,
hba->dma_mem, hba->dma_handle);
@@ -1183,15 +1597,20 @@ out_disable:
static void stex_hba_stop(struct st_hba *hba)
{
struct req_msg *req;
+ struct st_msg_header *msg_h;
unsigned long flags;
unsigned long before;
u16 tag = 0;
spin_lock_irqsave(hba->host->host_lock, flags);
- req = stex_alloc_req(hba);
- memset(req->cdb, 0, STEX_CDB_LENGTH);
+ req = hba->alloc_rq(hba);
+ if (hba->cardtype == st_yel) {
+ msg_h = (struct st_msg_header *)req - 1;
+ memset(msg_h, 0, hba->rq_size);
+ } else
+ memset(req, 0, hba->rq_size);
- if (hba->cardtype == st_yosemite) {
+ if (hba->cardtype == st_yosemite || hba->cardtype == st_yel) {
req->cdb[0] = MGT_CMD;
req->cdb[1] = MGT_CMD_SIGNATURE;
req->cdb[2] = CTLR_CONFIG_CMD;
@@ -1206,27 +1625,31 @@ static void stex_hba_stop(struct st_hba *hba)
hba->ccb[tag].sg_count = 0;
hba->ccb[tag].sense_bufflen = 0;
hba->ccb[tag].sense_buffer = NULL;
- hba->ccb[tag].req_type |= PASSTHRU_REQ_TYPE;
+ hba->ccb[tag].req_type = PASSTHRU_REQ_TYPE;
- stex_send_cmd(hba, req, tag);
+ hba->send(hba, req, tag);
spin_unlock_irqrestore(hba->host->host_lock, flags);
before = jiffies;
while (hba->ccb[tag].req_type & PASSTHRU_REQ_TYPE) {
- if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ))
+ if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) {
+ hba->ccb[tag].req_type = 0;
return;
- msleep(10);
+ }
+ msleep(1);
}
}
static void stex_hba_free(struct st_hba *hba)
{
- free_irq(hba->pdev->irq, hba);
+ stex_free_irq(hba);
iounmap(hba->mmio_base);
pci_release_regions(hba->pdev);
+ kfree(hba->ccb);
+
dma_free_coherent(&hba->pdev->dev, hba->dma_size,
hba->dma_mem, hba->dma_handle);
}
@@ -1255,27 +1678,6 @@ static void stex_shutdown(struct pci_dev *pdev)
stex_hba_stop(hba);
}
-static struct pci_device_id stex_pci_tbl[] = {
- /* st_shasta */
- { 0x105a, 0x8350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX8350/8300/16350/16300 */
- { 0x105a, 0xc350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX12350 */
- { 0x105a, 0x4302, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX4350 */
- { 0x105a, 0xe350, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
- st_shasta }, /* SuperTrak EX24350 */
-
- /* st_vsc */
- { 0x105a, 0x7250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_vsc },
-
- /* st_yosemite */
- { 0x105a, 0x8650, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_yosemite },
-
- /* st_seq */
- { 0x105a, 0x3360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, st_seq },
- { } /* terminate list */
-};
MODULE_DEVICE_TABLE(pci, stex_pci_tbl);
static struct pci_driver stex_pci_driver = {
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.h b/drivers/scsi/sym53c8xx_2/sym_glue.h
index 567fbe0b4f0..b80bf709f10 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.h
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.h
@@ -234,7 +234,7 @@ static inline struct sym_hcb * sym_get_hcb(struct Scsi_Host *host)
/*
* Set the status field of a CAM CCB.
*/
-static __inline void
+static inline void
sym_set_cam_status(struct scsi_cmnd *cmd, int status)
{
cmd->result &= ~(0xff << 16);
@@ -244,7 +244,7 @@ sym_set_cam_status(struct scsi_cmnd *cmd, int status)
/*
* Get the status field of a CAM CCB.
*/
-static __inline int
+static inline int
sym_get_cam_status(struct scsi_cmnd *cmd)
{
return host_byte(cmd->result);
@@ -253,7 +253,7 @@ sym_get_cam_status(struct scsi_cmnd *cmd)
/*
* Build CAM result for a successful IO and for a failed IO.
*/
-static __inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
+static inline void sym_set_cam_result_ok(struct sym_ccb *cp, struct scsi_cmnd *cmd, int resid)
{
scsi_set_resid(cmd, resid);
cmd->result = (((DID_OK) << 16) + ((cp->ssss_status) & 0x7f));
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.c b/drivers/scsi/sym53c8xx_2/sym_hipd.c
index ccea7db59f4..ffa70d1ed18 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.c
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.c
@@ -602,7 +602,7 @@ sym_getsync(struct sym_hcb *np, u_char dt, u_char sfac, u_char *divp, u_char *fa
/*
* Set initial io register bits from burst code.
*/
-static __inline void sym_init_burst(struct sym_hcb *np, u_char bc)
+static inline void sym_init_burst(struct sym_hcb *np, u_char bc)
{
np->rv_ctest4 &= ~0x80;
np->rv_dmode &= ~(0x3 << 6);
diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h
index 61d28fcfffb..1588c90518d 100644
--- a/drivers/scsi/sym53c8xx_2/sym_hipd.h
+++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h
@@ -1096,7 +1096,7 @@ do { \
#elif SYM_CONF_DMA_ADDRESSING_MODE == 2
#define DMA_DAC_MASK DMA_64BIT_MASK
int sym_lookup_dmap(struct sym_hcb *np, u32 h, int s);
-static __inline void
+static inline void
sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len)
{
u32 h = (badd>>32);
@@ -1201,7 +1201,7 @@ dma_addr_t __vtobus(m_pool_ident_t dev_dmat, void *m);
#define sym_m_pool_match(mp_id1, mp_id2) (mp_id1 == mp_id2)
-static __inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
+static inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
{
void *vaddr = NULL;
dma_addr_t baddr = 0;
@@ -1215,7 +1215,7 @@ static __inline void *sym_m_get_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
return vaddr;
}
-static __inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
+static inline void sym_m_free_dma_mem_cluster(m_pool_p mp, m_vtob_p vbp)
{
dma_free_coherent(mp->dev_dmat, SYM_MEM_CLUSTER_SIZE, vbp->vaddr,
vbp->baddr);
diff --git a/drivers/scsi/sym53c8xx_2/sym_malloc.c b/drivers/scsi/sym53c8xx_2/sym_malloc.c
index 92bf9b14a7a..883cac10daf 100644
--- a/drivers/scsi/sym53c8xx_2/sym_malloc.c
+++ b/drivers/scsi/sym53c8xx_2/sym_malloc.c
@@ -262,7 +262,7 @@ static void ___free_dma_mem_cluster(m_pool_p mp, void *m)
#endif
/* Fetch the memory pool for a given pool id (i.e. DMA constraints) */
-static __inline m_pool_p ___get_dma_pool(m_pool_ident_t dev_dmat)
+static inline m_pool_p ___get_dma_pool(m_pool_ident_t dev_dmat)
{
m_pool_p mp;
for (mp = mp0.next;
diff --git a/drivers/scsi/sym53c8xx_2/sym_misc.h b/drivers/scsi/sym53c8xx_2/sym_misc.h
index 430537183c1..96c15145902 100644
--- a/drivers/scsi/sym53c8xx_2/sym_misc.h
+++ b/drivers/scsi/sym53c8xx_2/sym_misc.h
@@ -52,17 +52,17 @@ typedef struct sym_quehead {
(ptr)->flink = (ptr); (ptr)->blink = (ptr); \
} while (0)
-static __inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
+static inline struct sym_quehead *sym_que_first(struct sym_quehead *head)
{
return (head->flink == head) ? 0 : head->flink;
}
-static __inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
+static inline struct sym_quehead *sym_que_last(struct sym_quehead *head)
{
return (head->blink == head) ? 0 : head->blink;
}
-static __inline void __sym_que_add(struct sym_quehead * new,
+static inline void __sym_que_add(struct sym_quehead * new,
struct sym_quehead * blink,
struct sym_quehead * flink)
{
@@ -72,19 +72,19 @@ static __inline void __sym_que_add(struct sym_quehead * new,
blink->flink = new;
}
-static __inline void __sym_que_del(struct sym_quehead * blink,
+static inline void __sym_que_del(struct sym_quehead * blink,
struct sym_quehead * flink)
{
flink->blink = blink;
blink->flink = flink;
}
-static __inline int sym_que_empty(struct sym_quehead *head)
+static inline int sym_que_empty(struct sym_quehead *head)
{
return head->flink == head;
}
-static __inline void sym_que_splice(struct sym_quehead *list,
+static inline void sym_que_splice(struct sym_quehead *list,
struct sym_quehead *head)
{
struct sym_quehead *first = list->flink;
@@ -101,7 +101,7 @@ static __inline void sym_que_splice(struct sym_quehead *list,
}
}
-static __inline void sym_que_move(struct sym_quehead *orig,
+static inline void sym_que_move(struct sym_quehead *orig,
struct sym_quehead *dest)
{
struct sym_quehead *first, *last;
@@ -129,7 +129,7 @@ static __inline void sym_que_move(struct sym_quehead *orig,
#define sym_insque_head(new, head) __sym_que_add(new, head, (head)->flink)
-static __inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
+static inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
{
struct sym_quehead *elem = head->flink;
@@ -142,7 +142,7 @@ static __inline struct sym_quehead *sym_remque_head(struct sym_quehead *head)
#define sym_insque_tail(new, head) __sym_que_add(new, (head)->blink, head)
-static __inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
+static inline struct sym_quehead *sym_remque_tail(struct sym_quehead *head)
{
struct sym_quehead *elem = head->blink;
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 533f82025ad..7ddff3f5508 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -306,6 +306,63 @@ static void __devexit pci_plx9050_exit(struct pci_dev *dev)
}
}
+#define NI8420_INT_ENABLE_REG 0x38
+#define NI8420_INT_ENABLE_BIT 0x2000
+
+static void __devexit pci_ni8420_exit(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return;
+
+ /* Disable the CPU Interrupt */
+ writel(readl(p + NI8420_INT_ENABLE_REG) & ~(NI8420_INT_ENABLE_BIT),
+ p + NI8420_INT_ENABLE_REG);
+ iounmap(p);
+}
+
+
+/* MITE registers */
+#define MITE_IOWBSR1 0xc4
+#define MITE_IOWCR1 0xf4
+#define MITE_LCIMR1 0x08
+#define MITE_LCIMR2 0x10
+
+#define MITE_LCIMR2_CLR_CPU_IE (1 << 30)
+
+static void __devexit pci_ni8430_exit(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return;
+
+ /* Disable the CPU Interrupt */
+ writel(MITE_LCIMR2_CLR_CPU_IE, p + MITE_LCIMR2);
+ iounmap(p);
+}
+
/* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
static int
sbs_setup(struct serial_private *priv, const struct pciserial_board *board,
@@ -597,6 +654,108 @@ static int pci_xircom_init(struct pci_dev *dev)
return 0;
}
+static int pci_ni8420_init(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return 0;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return -ENOMEM;
+
+ /* Enable CPU Interrupt */
+ writel(readl(p + NI8420_INT_ENABLE_REG) | NI8420_INT_ENABLE_BIT,
+ p + NI8420_INT_ENABLE_REG);
+
+ iounmap(p);
+ return 0;
+}
+
+#define MITE_IOWBSR1_WSIZE 0xa
+#define MITE_IOWBSR1_WIN_OFFSET 0x800
+#define MITE_IOWBSR1_WENAB (1 << 7)
+#define MITE_LCIMR1_IO_IE_0 (1 << 24)
+#define MITE_LCIMR2_SET_CPU_IE (1 << 31)
+#define MITE_IOWCR1_RAMSEL_MASK 0xfffffffe
+
+static int pci_ni8430_init(struct pci_dev *dev)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ u32 device_window;
+ unsigned int bar = 0;
+
+ if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
+ moan_device("no memory in bar", dev);
+ return 0;
+ }
+
+ base = pci_resource_start(dev, bar);
+ len = pci_resource_len(dev, bar);
+ p = ioremap_nocache(base, len);
+ if (p == NULL)
+ return -ENOMEM;
+
+ /* Set device window address and size in BAR0 */
+ device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00)
+ | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE;
+ writel(device_window, p + MITE_IOWBSR1);
+
+ /* Set window access to go to RAMSEL IO address space */
+ writel((readl(p + MITE_IOWCR1) & MITE_IOWCR1_RAMSEL_MASK),
+ p + MITE_IOWCR1);
+
+ /* Enable IO Bus Interrupt 0 */
+ writel(MITE_LCIMR1_IO_IE_0, p + MITE_LCIMR1);
+
+ /* Enable CPU Interrupt */
+ writel(MITE_LCIMR2_SET_CPU_IE, p + MITE_LCIMR2);
+
+ iounmap(p);
+ return 0;
+}
+
+/* UART Port Control Register */
+#define NI8430_PORTCON 0x0f
+#define NI8430_PORTCON_TXVR_ENABLE (1 << 3)
+
+static int
+pci_ni8430_setup(struct serial_private *priv,
+ const struct pciserial_board *board,
+ struct uart_port *port, int idx)
+{
+ void __iomem *p;
+ unsigned long base, len;
+ unsigned int bar, offset = board->first_offset;
+
+ if (idx >= board->num_ports)
+ return 1;
+
+ bar = FL_GET_BASE(board->flags);
+ offset += idx * board->uart_offset;
+
+ base = pci_resource_start(priv->dev, bar);
+ len = pci_resource_len(priv->dev, bar);
+ p = ioremap_nocache(base, len);
+
+ /* enable the transciever */
+ writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE,
+ p + offset + NI8430_PORTCON);
+
+ iounmap(p);
+
+ return setup_port(priv, port, bar, offset, board->reg_shift);
+}
+
+
static int pci_netmos_init(struct pci_dev *dev)
{
/* subdevice 0x00PS means <P> parallel, <S> serial */
@@ -913,6 +1072,126 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
.exit = __devexit_p(pci_ite887x_exit),
},
/*
+ * National Instruments
+ */
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI23216,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2328,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2324I,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PCI2322I,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_23216,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2328,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8420_2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8422_2324,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_DEVICE_ID_NI_PXI8422_2322,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8420_init,
+ .setup = pci_default_setup,
+ .exit = __devexit_p(pci_ni8420_exit),
+ },
+ {
+ .vendor = PCI_VENDOR_ID_NI,
+ .device = PCI_ANY_ID,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ .init = pci_ni8430_init,
+ .setup = pci_ni8430_setup,
+ .exit = __devexit_p(pci_ni8430_exit),
+ },
+ /*
* Panacom
*/
{
@@ -1216,6 +1495,7 @@ enum pci_board_num_t {
pbn_b1_2_115200,
pbn_b1_4_115200,
pbn_b1_8_115200,
+ pbn_b1_16_115200,
pbn_b1_1_921600,
pbn_b1_2_921600,
@@ -1225,6 +1505,9 @@ enum pci_board_num_t {
pbn_b1_2_1250000,
pbn_b1_bt_1_115200,
+ pbn_b1_bt_2_115200,
+ pbn_b1_bt_4_115200,
+
pbn_b1_bt_2_921600,
pbn_b1_1_1382400,
@@ -1280,6 +1563,10 @@ enum pci_board_num_t {
pbn_exar_XR17C154,
pbn_exar_XR17C158,
pbn_pasemi_1682M,
+ pbn_ni8430_2,
+ pbn_ni8430_4,
+ pbn_ni8430_8,
+ pbn_ni8430_16,
};
/*
@@ -1487,6 +1774,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 115200,
.uart_offset = 8,
},
+ [pbn_b1_16_115200] = {
+ .flags = FL_BASE1,
+ .num_ports = 16,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
[pbn_b1_1_921600] = {
.flags = FL_BASE1,
@@ -1525,6 +1818,18 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.base_baud = 115200,
.uart_offset = 8,
},
+ [pbn_b1_bt_2_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 2,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
+ [pbn_b1_bt_4_115200] = {
+ .flags = FL_BASE1|FL_BASE_BARS,
+ .num_ports = 4,
+ .base_baud = 115200,
+ .uart_offset = 8,
+ },
[pbn_b1_bt_2_921600] = {
.flags = FL_BASE1|FL_BASE_BARS,
@@ -1850,6 +2155,37 @@ static struct pciserial_board pci_boards[] __devinitdata = {
.num_ports = 1,
.base_baud = 8333333,
},
+ /*
+ * National Instruments 843x
+ */
+ [pbn_ni8430_16] = {
+ .flags = FL_BASE0,
+ .num_ports = 16,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_8] = {
+ .flags = FL_BASE0,
+ .num_ports = 8,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_4] = {
+ .flags = FL_BASE0,
+ .num_ports = 4,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
+ [pbn_ni8430_2] = {
+ .flags = FL_BASE0,
+ .num_ports = 2,
+ .base_baud = 3686400,
+ .uart_offset = 0x10,
+ .first_offset = 0x800,
+ },
};
static const struct pci_device_id softmodem_blacklist[] = {
@@ -3052,6 +3388,82 @@ static struct pci_device_id serial_pci_tbl[] = {
pbn_pasemi_1682M },
/*
+ * National Instruments
+ */
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_16_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2324I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI2322I,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_16_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_8_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8420_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_4_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8422_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_b1_bt_2_115200 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_8 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_2328,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_8 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8430_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8430_23216,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_16 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2322,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_2 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PXI8432_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+ { PCI_VENDOR_ID_NI, PCI_DEVICE_ID_NI_PCI8432_2324,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ pbn_ni8430_4 },
+
+ /*
* ADDI-DATA GmbH communication cards <info@addi-data.com>
*/
{ PCI_VENDOR_ID_ADDIDATA,
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index bbcfc26a3b6..d71dfe39894 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -333,6 +333,10 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "WACF006", 0 },
{ "WACF007", 0 },
{ "WACF008", 0 },
+ { "WACF009", 0 },
+ { "WACF00A", 0 },
+ { "WACF00B", 0 },
+ { "WACF00C", 0 },
/* Compaq touchscreen */
{ "FPI2002", 0 },
/* Fujitsu Stylistic touchscreens */
@@ -346,8 +350,9 @@ static const struct pnp_device_id pnp_dev_table[] = {
{ "FUJ02B8", 0 },
{ "FUJ02B9", 0 },
{ "FUJ02BC", 0 },
- /* Fujitsu Wacom Tablet PC devices */
+ /* Fujitsu Wacom Tablet PC device */
{ "FUJ02E5", 0 },
+ /* Fujitsu P-series tablet PC device */
{ "FUJ02E6", 0 },
/*
* LG C1 EXPRESS DUAL (C1-PB11A3) touch screen (actually a FUJ02E6 in
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 9be11b0963f..07c03b9eb12 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -770,7 +770,7 @@ config UART1_RTS_PIN
config SERIAL_BFIN_UART2
bool "Enable UART2"
- depends on SERIAL_BFIN && (BF54x)
+ depends on SERIAL_BFIN && (BF54x || BF538 || BF539)
help
Enable UART2
@@ -1374,7 +1374,7 @@ config SERIAL_BFIN_SPORT
depends on BLACKFIN && EXPERIMENTAL
select SERIAL_CORE
help
- Enble support SPORT emulate UART on Blackfin series.
+ Enable SPORT emulate UART on Blackfin series.
To compile this driver as a module, choose M here: the
module will be called bfin_sport_uart.
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index 8f58f7ff0dd..b3497d7e535 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -1020,7 +1020,8 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
/* Get current mode register */
mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL
- | ATMEL_US_NBSTOP | ATMEL_US_PAR);
+ | ATMEL_US_NBSTOP | ATMEL_US_PAR
+ | ATMEL_US_USMODE);
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
quot = uart_get_divisor(port, baud);
@@ -1065,6 +1066,12 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
} else
mode |= ATMEL_US_PAR_NONE;
+ /* hardware handshake (RTS/CTS) */
+ if (termios->c_cflag & CRTSCTS)
+ mode |= ATMEL_US_USMODE_HWHS;
+ else
+ mode |= ATMEL_US_USMODE_NORMAL;
+
spin_lock_irqsave(&port->lock, flags);
port->read_status_mask = ATMEL_US_OVRE;
diff --git a/drivers/serial/bfin_5xx.c b/drivers/serial/bfin_5xx.c
index 318d69dce8e..f9b5a72e261 100644
--- a/drivers/serial/bfin_5xx.c
+++ b/drivers/serial/bfin_5xx.c
@@ -174,10 +174,10 @@ static void bfin_serial_rx_chars(struct bfin_serial_port *uart)
return;
}
- if (!uart->port.info || !uart->port.info->tty)
+ if (!uart->port.info || !uart->port.info->port.tty)
return;
#endif
- tty = uart->port.info->tty;
+ tty = uart->port.info->port.tty;
if (ANOMALY_05000363) {
/* The BF533 (and BF561) family of processors have a nice anomaly
@@ -401,9 +401,11 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
else
flg = TTY_NORMAL;
- for (i = uart->rx_dma_buf.tail; i != uart->rx_dma_buf.head; i++) {
+ for (i = uart->rx_dma_buf.tail; ; i++) {
if (i >= UART_XMIT_SIZE)
i = 0;
+ if (i == uart->rx_dma_buf.head)
+ break;
if (!uart_handle_sysrq_char(&uart->port, uart->rx_dma_buf.buf[i]))
uart_insert_char(&uart->port, status, OE,
uart->rx_dma_buf.buf[i], flg);
@@ -415,7 +417,8 @@ static void bfin_serial_dma_rx_chars(struct bfin_serial_port *uart)
void bfin_serial_rx_dma_timeout(struct bfin_serial_port *uart)
{
- int x_pos, pos, flags;
+ int x_pos, pos;
+ unsigned long flags;
spin_lock_irqsave(&uart->port.lock, flags);
@@ -757,7 +760,7 @@ bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios,
}
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
- quot = uart_get_divisor(port, baud);
+ quot = uart_get_divisor(port, baud) - ANOMALY_05000230;
spin_lock_irqsave(&uart->port.lock, flags);
UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15);
@@ -1088,7 +1091,7 @@ static void
bfin_serial_console_write(struct console *co, const char *s, unsigned int count)
{
struct bfin_serial_port *uart = &bfin_serial_ports[co->index];
- int flags = 0;
+ unsigned long flags;
spin_lock_irqsave(&uart->port.lock, flags);
uart_console_write(&uart->port, s, count, bfin_serial_console_putchar);
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c
index bde4b4b0b80..5c6ef51da27 100644
--- a/drivers/serial/cpm_uart/cpm_uart_core.c
+++ b/drivers/serial/cpm_uart/cpm_uart_core.c
@@ -406,6 +406,18 @@ static int cpm_uart_startup(struct uart_port *port)
pr_debug("CPM uart[%d]:startup\n", port->line);
+ /* If the port is not the console, make sure rx is disabled. */
+ if (!(pinfo->flags & FLAG_CONSOLE)) {
+ /* Disable UART rx */
+ if (IS_SMC(pinfo)) {
+ clrbits16(&pinfo->smcp->smc_smcmr, SMCMR_REN);
+ clrbits8(&pinfo->smcp->smc_smcm, SMCM_RX);
+ } else {
+ clrbits32(&pinfo->sccp->scc_gsmrl, SCC_GSMRL_ENR);
+ clrbits16(&pinfo->sccp->scc_sccm, UART_SCCM_RX);
+ }
+ cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
+ }
/* Install interrupt handler. */
retval = request_irq(port->irq, cpm_uart_int, 0, "cpm_uart", port);
if (retval)
@@ -420,8 +432,6 @@ static int cpm_uart_startup(struct uart_port *port)
setbits32(&pinfo->sccp->scc_gsmrl, (SCC_GSMRL_ENR | SCC_GSMRL_ENT));
}
- if (!(pinfo->flags & FLAG_CONSOLE))
- cpm_line_cr_cmd(pinfo, CPM_CR_INIT_TRX);
return 0;
}
diff --git a/drivers/serial/icom.c b/drivers/serial/icom.c
index 2b7531d9f6a..6579e2be1dd 100644
--- a/drivers/serial/icom.c
+++ b/drivers/serial/icom.c
@@ -1098,7 +1098,6 @@ static void icom_set_termios(struct uart_port *port,
{
int baud;
unsigned cflag, iflag;
- int bits;
char new_config2;
char new_config3 = 0;
char tmp_byte;
@@ -1119,34 +1118,27 @@ static void icom_set_termios(struct uart_port *port,
switch (cflag & CSIZE) {
case CS5: /* 5 bits/char */
new_config2 |= ICOM_ACFG_5BPC;
- bits = 7;
break;
case CS6: /* 6 bits/char */
new_config2 |= ICOM_ACFG_6BPC;
- bits = 8;
break;
case CS7: /* 7 bits/char */
new_config2 |= ICOM_ACFG_7BPC;
- bits = 9;
break;
case CS8: /* 8 bits/char */
new_config2 |= ICOM_ACFG_8BPC;
- bits = 10;
break;
default:
- bits = 10;
break;
}
if (cflag & CSTOPB) {
/* 2 stop bits */
new_config2 |= ICOM_ACFG_2STOP_BIT;
- bits++;
}
if (cflag & PARENB) {
/* parity bit enabled */
new_config2 |= ICOM_ACFG_PARITY_ENAB;
trace(ICOM_PORT, "PARENB", 0);
- bits++;
}
if (cflag & PARODD) {
/* odd parity */
@@ -1322,7 +1314,6 @@ static struct uart_driver icom_uart_driver = {
static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
{
u32 subsystem_id = icom_adapter->subsystem_id;
- int retval = 0;
int i;
struct icom_port *icom_port;
@@ -1368,7 +1359,7 @@ static int __devinit icom_init_ports(struct icom_adapter *icom_adapter)
}
}
- return retval;
+ return 0;
}
static void icom_port_active(struct icom_port *icom_port, struct icom_adapter *icom_adapter, int port_num)
@@ -1391,7 +1382,6 @@ static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
{
struct icom_port *icom_port;
int port_num;
- int retval;
for (port_num = 0; port_num < icom_adapter->numb_ports; port_num++) {
@@ -1405,7 +1395,7 @@ static int __devinit icom_load_ports(struct icom_adapter *icom_adapter)
icom_port->adapter = icom_adapter;
/* get port memory */
- if ((retval = get_port_memory(icom_port)) != 0) {
+ if (get_port_memory(icom_port) != 0) {
dev_err(&icom_port->adapter->pci_dev->dev,
"Memory allocation for port FAILED\n");
}
diff --git a/drivers/serial/jsm/jsm_driver.c b/drivers/serial/jsm/jsm_driver.c
index ac79cbe4c2c..d2d32a19862 100644
--- a/drivers/serial/jsm/jsm_driver.c
+++ b/drivers/serial/jsm/jsm_driver.c
@@ -52,12 +52,11 @@ int jsm_debug;
module_param(jsm_debug, int, 0);
MODULE_PARM_DESC(jsm_debug, "Driver debugging level");
-static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc = 0;
struct jsm_board *brd;
static int adapter_count = 0;
- int retval;
rc = pci_enable_device(pdev);
if (rc) {
@@ -134,7 +133,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = jsm_tty_init(brd);
if (rc < 0) {
dev_err(&pdev->dev, "Can't init tty devices (%d)\n", rc);
- retval = -ENXIO;
+ rc = -ENXIO;
goto out_free_irq;
}
@@ -142,7 +141,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc < 0) {
/* XXX: leaking all resources from jsm_tty_init here! */
dev_err(&pdev->dev, "Can't init uart port (%d)\n", rc);
- retval = -ENXIO;
+ rc = -ENXIO;
goto out_free_irq;
}
@@ -161,7 +160,7 @@ static int jsm_probe_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* XXX: leaking all resources from jsm_tty_init and
jsm_uart_port_init here! */
dev_err(&pdev->dev, "memory allocation for flipbuf failed\n");
- retval = -ENOMEM;
+ rc = -ENOMEM;
goto out_free_irq;
}
diff --git a/drivers/serial/jsm/jsm_tty.c b/drivers/serial/jsm/jsm_tty.c
index 324c74d2f66..330696309f7 100644
--- a/drivers/serial/jsm/jsm_tty.c
+++ b/drivers/serial/jsm/jsm_tty.c
@@ -367,7 +367,7 @@ static struct uart_ops jsm_ops = {
* Init the tty subsystem. Called once per board after board has been
* downloaded and init'ed.
*/
-int jsm_tty_init(struct jsm_board *brd)
+int __devinit jsm_tty_init(struct jsm_board *brd)
{
int i;
void __iomem *vaddr;
@@ -431,7 +431,7 @@ int jsm_tty_init(struct jsm_board *brd)
return 0;
}
-int jsm_uart_port_init(struct jsm_board *brd)
+int __devinit jsm_uart_port_init(struct jsm_board *brd)
{
int i;
struct jsm_channel *ch;
diff --git a/drivers/serial/mcf.c b/drivers/serial/mcf.c
index 56841fe5f48..0eefb07beba 100644
--- a/drivers/serial/mcf.c
+++ b/drivers/serial/mcf.c
@@ -513,7 +513,7 @@ static int __init mcf_console_setup(struct console *co, char *options)
int parity = 'n';
int flow = 'n';
- if ((co->index >= 0) && (co->index <= MCF_MAXPORTS))
+ if ((co->index < 0) || (co->index >= MCF_MAXPORTS))
co->index = 0;
port = &mcf_ports[co->index].port;
if (port->membase == 0)
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 0c3a2ab1612..7f72f8ceaa6 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -50,8 +50,8 @@
/* OF Platform device Usage :
*
* This driver is only used for PSCs configured in uart mode. The device
- * tree will have a node for each PSC in uart mode w/ device_type = "serial"
- * and "mpc52xx-psc-uart" in the compatible string
+ * tree will have a node for each PSC with "mpc52xx-psc-uart" in the compatible
+ * list.
*
* By default, PSC devices are enumerated in the order they are found. However
* a particular PSC number can be forces by adding 'device_no = <port#>'
@@ -522,7 +522,7 @@ mpc52xx_uart_startup(struct uart_port *port)
/* Request IRQ */
ret = request_irq(port->irq, mpc52xx_uart_int,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM | IRQF_SHARED,
+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
"mpc52xx_psc_uart", port);
if (ret)
return ret;
@@ -1212,30 +1212,18 @@ mpc52xx_uart_of_resume(struct of_device *op)
#endif
static void
-mpc52xx_uart_of_assign(struct device_node *np, int idx)
+mpc52xx_uart_of_assign(struct device_node *np)
{
- int free_idx = -1;
int i;
- /* Find the first free node */
+ /* Find the first free PSC number */
for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
if (mpc52xx_uart_nodes[i] == NULL) {
- free_idx = i;
- break;
+ of_node_get(np);
+ mpc52xx_uart_nodes[i] = np;
+ return;
}
}
-
- if ((idx < 0) || (idx >= MPC52xx_PSC_MAXNUM))
- idx = free_idx;
-
- if (idx < 0)
- return; /* No free slot; abort */
-
- of_node_get(np);
- /* If the slot is already occupied, then swap slots */
- if (mpc52xx_uart_nodes[idx] && (free_idx != -1))
- mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx];
- mpc52xx_uart_nodes[idx] = np;
}
static void
@@ -1243,23 +1231,17 @@ mpc52xx_uart_of_enumerate(void)
{
static int enum_done;
struct device_node *np;
- const unsigned int *devno;
const struct of_device_id *match;
int i;
if (enum_done)
return;
- for_each_node_by_type(np, "serial") {
+ /* Assign index to each PSC in device tree */
+ for_each_matching_node(np, mpc52xx_uart_of_match) {
match = of_match_node(mpc52xx_uart_of_match, np);
- if (!match)
- continue;
-
psc_ops = match->data;
-
- /* Is a particular device number requested? */
- devno = of_get_property(np, "port-number", NULL);
- mpc52xx_uart_of_assign(np, devno ? *devno : -1);
+ mpc52xx_uart_of_assign(np);
}
enum_done = 1;
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index 42f4e66fcca..b0bb29d804a 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -27,6 +27,8 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/console.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
#include <linux/serial_core.h>
#include <linux/smp_lock.h>
#include <linux/device.h>
@@ -1682,20 +1684,20 @@ static const char *uart_type(struct uart_port *port)
#ifdef CONFIG_PROC_FS
-static int uart_line_info(char *buf, struct uart_driver *drv, int i)
+static void uart_line_info(struct seq_file *m, struct uart_driver *drv, int i)
{
struct uart_state *state = drv->state + i;
int pm_state;
struct uart_port *port = state->port;
char stat_buf[32];
unsigned int status;
- int mmio, ret;
+ int mmio;
if (!port)
- return 0;
+ return;
mmio = port->iotype >= UPIO_MEM;
- ret = sprintf(buf, "%d: uart:%s %s%08llX irq:%d",
+ seq_printf(m, "%d: uart:%s %s%08llX irq:%d",
port->line, uart_type(port),
mmio ? "mmio:0x" : "port:",
mmio ? (unsigned long long)port->mapbase
@@ -1703,8 +1705,8 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
port->irq);
if (port->type == PORT_UNKNOWN) {
- strcat(buf, "\n");
- return ret + 1;
+ seq_putc(m, '\n');
+ return;
}
if (capable(CAP_SYS_ADMIN)) {
@@ -1719,19 +1721,19 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
uart_change_pm(state, pm_state);
mutex_unlock(&state->mutex);
- ret += sprintf(buf + ret, " tx:%d rx:%d",
+ seq_printf(m, " tx:%d rx:%d",
port->icount.tx, port->icount.rx);
if (port->icount.frame)
- ret += sprintf(buf + ret, " fe:%d",
+ seq_printf(m, " fe:%d",
port->icount.frame);
if (port->icount.parity)
- ret += sprintf(buf + ret, " pe:%d",
+ seq_printf(m, " pe:%d",
port->icount.parity);
if (port->icount.brk)
- ret += sprintf(buf + ret, " brk:%d",
+ seq_printf(m, " brk:%d",
port->icount.brk);
if (port->icount.overrun)
- ret += sprintf(buf + ret, " oe:%d",
+ seq_printf(m, " oe:%d",
port->icount.overrun);
#define INFOBIT(bit, str) \
@@ -1753,45 +1755,39 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i)
STATBIT(TIOCM_RNG, "|RI");
if (stat_buf[0])
stat_buf[0] = ' ';
- strcat(stat_buf, "\n");
- ret += sprintf(buf + ret, stat_buf);
- } else {
- strcat(buf, "\n");
- ret++;
+ seq_puts(m, stat_buf);
}
+ seq_putc(m, '\n');
#undef STATBIT
#undef INFOBIT
- return ret;
}
-static int uart_read_proc(char *page, char **start, off_t off,
- int count, int *eof, void *data)
+static int uart_proc_show(struct seq_file *m, void *v)
{
- struct tty_driver *ttydrv = data;
+ struct tty_driver *ttydrv = m->private;
struct uart_driver *drv = ttydrv->driver_state;
- int i, len = 0, l;
- off_t begin = 0;
+ int i;
- len += sprintf(page, "serinfo:1.0 driver%s%s revision:%s\n",
+ seq_printf(m, "serinfo:1.0 driver%s%s revision:%s\n",
"", "", "");
- for (i = 0; i < drv->nr && len < PAGE_SIZE - 96; i++) {
- l = uart_line_info(page + len, drv, i);
- len += l;
- if (len + begin > off + count)
- goto done;
- if (len + begin < off) {
- begin += len;
- len = 0;
- }
- }
- *eof = 1;
- done:
- if (off >= len + begin)
- return 0;
- *start = page + (off - begin);
- return (count < begin + len - off) ? count : (begin + len - off);
+ for (i = 0; i < drv->nr; i++)
+ uart_line_info(m, drv, i);
+ return 0;
}
+
+static int uart_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, uart_proc_show, PDE(inode)->data);
+}
+
+static const struct file_operations uart_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = uart_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
#endif
#if defined(CONFIG_SERIAL_CORE_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
@@ -2299,7 +2295,7 @@ static const struct tty_operations uart_ops = {
.break_ctl = uart_break_ctl,
.wait_until_sent= uart_wait_until_sent,
#ifdef CONFIG_PROC_FS
- .read_proc = uart_read_proc,
+ .proc_fops = &uart_proc_fops,
#endif
.tiocmget = uart_tiocmget,
.tiocmset = uart_tiocmset,
diff --git a/drivers/serial/ucc_uart.c b/drivers/serial/ucc_uart.c
index 315a9333ca3..7de66c06b05 100644
--- a/drivers/serial/ucc_uart.c
+++ b/drivers/serial/ucc_uart.c
@@ -1274,6 +1274,7 @@ static int ucc_uart_probe(struct of_device *ofdev,
if (!iprop) {
iprop = of_get_property(np, "device-id", NULL);
if (!iprop) {
+ kfree(qe_port);
dev_err(&ofdev->dev, "UCC is unspecified in "
"device tree\n");
return -EINVAL;
diff --git a/drivers/sh/intc.c b/drivers/sh/intc.c
index 2269fbcaa18..7fb9b5c4669 100644
--- a/drivers/sh/intc.c
+++ b/drivers/sh/intc.c
@@ -22,6 +22,8 @@
#include <linux/interrupt.h>
#include <linux/bootmem.h>
#include <linux/sh_intc.h>
+#include <linux/sysdev.h>
+#include <linux/list.h>
#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \
((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \
@@ -40,6 +42,8 @@ struct intc_handle_int {
};
struct intc_desc_int {
+ struct list_head list;
+ struct sys_device sysdev;
unsigned long *reg;
#ifdef CONFIG_SMP
unsigned long *smp;
@@ -52,6 +56,8 @@ struct intc_desc_int {
struct irq_chip chip;
};
+static LIST_HEAD(intc_list);
+
#ifdef CONFIG_SMP
#define IS_SMP(x) x.smp
#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c))
@@ -232,6 +238,11 @@ static void intc_disable(unsigned int irq)
}
}
+static int intc_set_wake(unsigned int irq, unsigned int on)
+{
+ return 0; /* allow wakeup, but setup hardware in intc_suspend() */
+}
+
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
static void intc_mask_ack(unsigned int irq)
{
@@ -664,6 +675,9 @@ void __init register_intc_controller(struct intc_desc *desc)
d = alloc_bootmem(sizeof(*d));
+ INIT_LIST_HEAD(&d->list);
+ list_add(&d->list, &intc_list);
+
d->nr_reg = desc->mask_regs ? desc->nr_mask_regs * 2 : 0;
d->nr_reg += desc->prio_regs ? desc->nr_prio_regs * 2 : 0;
d->nr_reg += desc->sense_regs ? desc->nr_sense_regs : 0;
@@ -707,7 +721,11 @@ void __init register_intc_controller(struct intc_desc *desc)
d->chip.mask = intc_disable;
d->chip.unmask = intc_enable;
d->chip.mask_ack = intc_disable;
+ d->chip.enable = intc_enable;
+ d->chip.disable = intc_disable;
+ d->chip.shutdown = intc_disable;
d->chip.set_type = intc_set_sense;
+ d->chip.set_wake = intc_set_wake;
#if defined(CONFIG_CPU_SH3) || defined(CONFIG_CPU_SH4A)
if (desc->ack_regs) {
@@ -758,3 +776,53 @@ void __init register_intc_controller(struct intc_desc *desc)
intc_register_irq(desc, d, vect->enum_id, evt2irq(vect->vect));
}
}
+
+static int intc_suspend(struct sys_device *dev, pm_message_t state)
+{
+ struct intc_desc_int *d;
+ struct irq_desc *desc;
+ int irq;
+
+ /* get intc controller associated with this sysdev */
+ d = container_of(dev, struct intc_desc_int, sysdev);
+
+ /* enable wakeup irqs belonging to this intc controller */
+ for_each_irq_desc(irq, desc) {
+ if ((desc->status & IRQ_WAKEUP) && (desc->chip == &d->chip))
+ intc_enable(irq);
+ }
+
+ return 0;
+}
+
+static struct sysdev_class intc_sysdev_class = {
+ .name = "intc",
+ .suspend = intc_suspend,
+};
+
+/* register this intc as sysdev to allow suspend/resume */
+static int __init register_intc_sysdevs(void)
+{
+ struct intc_desc_int *d;
+ int error;
+ int id = 0;
+
+ error = sysdev_class_register(&intc_sysdev_class);
+ if (!error) {
+ list_for_each_entry(d, &intc_list, list) {
+ d->sysdev.id = id;
+ d->sysdev.cls = &intc_sysdev_class;
+ error = sysdev_register(&d->sysdev);
+ if (error)
+ break;
+ id++;
+ }
+ }
+
+ if (error)
+ pr_warning("intc: sysdev registration error\n");
+
+ return error;
+}
+
+device_initcall(register_intc_sysdevs);
diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c
index cab1ab7cfb7..93c20e135ee 100644
--- a/drivers/sh/maple/maple.c
+++ b/drivers/sh/maple/maple.c
@@ -776,7 +776,7 @@ static struct maple_driver maple_unsupported_device = {
.bus = &maple_bus_type,
},
};
-/**
+/*
* maple_bus_type - core maple bus structure
*/
struct bus_type maple_bus_type = {
diff --git a/drivers/spi/spi_gpio.c b/drivers/spi/spi_gpio.c
index d2866c293de..26bd03e6185 100644
--- a/drivers/spi/spi_gpio.c
+++ b/drivers/spi/spi_gpio.c
@@ -178,8 +178,10 @@ static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
if (is_active)
setsck(spi, spi->mode & SPI_CPOL);
- /* SPI is normally active-low */
- gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
+ if (cs != SPI_GPIO_NO_CHIPSELECT) {
+ /* SPI is normally active-low */
+ gpio_set_value(cs, (spi->mode & SPI_CS_HIGH) ? is_active : !is_active);
+ }
}
static int spi_gpio_setup(struct spi_device *spi)
@@ -191,15 +193,17 @@ static int spi_gpio_setup(struct spi_device *spi)
return -EINVAL;
if (!spi->controller_state) {
- status = gpio_request(cs, dev_name(&spi->dev));
- if (status)
- return status;
- status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
+ if (cs != SPI_GPIO_NO_CHIPSELECT) {
+ status = gpio_request(cs, dev_name(&spi->dev));
+ if (status)
+ return status;
+ status = gpio_direction_output(cs, spi->mode & SPI_CS_HIGH);
+ }
}
if (!status)
status = spi_bitbang_setup(spi);
if (status) {
- if (!spi->controller_state)
+ if (!spi->controller_state && cs != SPI_GPIO_NO_CHIPSELECT)
gpio_free(cs);
}
return status;
@@ -209,7 +213,8 @@ static void spi_gpio_cleanup(struct spi_device *spi)
{
unsigned long cs = (unsigned long) spi->controller_data;
- gpio_free(cs);
+ if (cs != SPI_GPIO_NO_CHIPSELECT)
+ gpio_free(cs);
spi_bitbang_cleanup(spi);
}
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 44a2b46ccb7..f4573a96af2 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -14,6 +14,8 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
@@ -23,7 +25,13 @@
#include <linux/spi/spi_bitbang.h>
#include <linux/platform_device.h>
#include <linux/fsl_devices.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>
+#include <linux/of_spi.h>
+#include <sysdev/fsl_soc.h>
#include <asm/irq.h>
#include <asm/io.h>
@@ -79,7 +87,7 @@ struct mpc83xx_spi {
u32(*get_tx) (struct mpc83xx_spi *);
unsigned int count;
- int irq;
+ unsigned int irq;
unsigned nsecs; /* (clock cycle time)/2 */
@@ -89,9 +97,6 @@ struct mpc83xx_spi {
bool qe_mode;
- void (*activate_cs) (u8 cs, u8 polarity);
- void (*deactivate_cs) (u8 cs, u8 polarity);
-
u8 busy;
struct workqueue_struct *workqueue;
@@ -123,6 +128,7 @@ static inline u32 mpc83xx_spi_read_reg(__be32 __iomem * reg)
}
#define MPC83XX_SPI_RX_BUF(type) \
+static \
void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
{ \
type * rx = mpc83xx_spi->rx; \
@@ -131,6 +137,7 @@ void mpc83xx_spi_rx_buf_##type(u32 data, struct mpc83xx_spi *mpc83xx_spi) \
}
#define MPC83XX_SPI_TX_BUF(type) \
+static \
u32 mpc83xx_spi_tx_buf_##type(struct mpc83xx_spi *mpc83xx_spi) \
{ \
u32 data; \
@@ -151,15 +158,14 @@ 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;
+ struct mpc83xx_spi *mpc83xx_spi = spi_master_get_devdata(spi->master);
+ struct fsl_spi_platform_data *pdata = spi->dev.parent->platform_data;
+ bool pol = spi->mode & SPI_CS_HIGH;
struct spi_mpc83xx_cs *cs = spi->controller_state;
- 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 (pdata->cs_control)
+ pdata->cs_control(spi, !pol);
}
if (value == BITBANG_CS_ACTIVE) {
@@ -172,7 +178,7 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
if (cs->hw_mode != regval) {
unsigned long flags;
- void *tmp_ptr = &mpc83xx_spi->base->mode;
+ __be32 __iomem *mode = &mpc83xx_spi->base->mode;
regval = cs->hw_mode;
/* Turn off IRQs locally to minimize time that
@@ -180,12 +186,12 @@ static void mpc83xx_spi_chipselect(struct spi_device *spi, int value)
*/
local_irq_save(flags);
/* Turn off SPI unit prior changing mode */
- mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
- mpc83xx_spi_write_reg(tmp_ptr, regval);
+ mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+ mpc83xx_spi_write_reg(mode, regval);
local_irq_restore(flags);
}
- if (mpc83xx_spi->activate_cs)
- mpc83xx_spi->activate_cs(spi->chip_select, pol);
+ if (pdata->cs_control)
+ pdata->cs_control(spi, pol);
}
}
@@ -284,7 +290,7 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
regval = mpc83xx_spi_read_reg(&mpc83xx_spi->base->mode);
if (cs->hw_mode != regval) {
unsigned long flags;
- void *tmp_ptr = &mpc83xx_spi->base->mode;
+ __be32 __iomem *mode = &mpc83xx_spi->base->mode;
regval = cs->hw_mode;
/* Turn off IRQs locally to minimize time
@@ -292,8 +298,8 @@ int mpc83xx_spi_setup_transfer(struct spi_device *spi, struct spi_transfer *t)
*/
local_irq_save(flags);
/* Turn off SPI unit prior changing mode */
- mpc83xx_spi_write_reg(tmp_ptr, regval & ~SPMODE_ENABLE);
- mpc83xx_spi_write_reg(tmp_ptr, regval);
+ mpc83xx_spi_write_reg(mode, regval & ~SPMODE_ENABLE);
+ mpc83xx_spi_write_reg(mode, regval);
local_irq_restore(flags);
}
return 0;
@@ -483,7 +489,7 @@ static int mpc83xx_spi_setup(struct spi_device *spi)
return 0;
}
-irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
+static irqreturn_t mpc83xx_spi_irq(s32 irq, void *context_data)
{
struct mpc83xx_spi *mpc83xx_spi = context_data;
u32 event;
@@ -545,43 +551,28 @@ static void mpc83xx_spi_cleanup(struct spi_device *spi)
kfree(spi->controller_state);
}
-static int __init mpc83xx_spi_probe(struct platform_device *dev)
+static struct spi_master * __devinit
+mpc83xx_spi_probe(struct device *dev, struct resource *mem, unsigned int irq)
{
+ struct fsl_spi_platform_data *pdata = dev->platform_data;
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));
-
+ master = spi_alloc_master(dev, sizeof(struct mpc83xx_spi));
if (master == NULL) {
ret = -ENOMEM;
goto err;
}
- platform_set_drvdata(dev, master);
- pdata = dev->dev.platform_data;
+ dev_set_drvdata(dev, master);
- if (pdata == NULL) {
- ret = -ENODEV;
- goto free_master;
- }
-
- r = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (r == NULL) {
- ret = -ENODEV;
- goto free_master;
- }
master->setup = mpc83xx_spi_setup;
master->transfer = mpc83xx_spi_transfer;
master->cleanup = mpc83xx_spi_cleanup;
mpc83xx_spi = spi_master_get_devdata(master);
- mpc83xx_spi->activate_cs = pdata->activate_cs;
- mpc83xx_spi->deactivate_cs = pdata->deactivate_cs;
mpc83xx_spi->qe_mode = pdata->qe_mode;
mpc83xx_spi->get_rx = mpc83xx_spi_rx_buf_u8;
mpc83xx_spi->get_tx = mpc83xx_spi_tx_buf_u8;
@@ -596,18 +587,13 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
init_completion(&mpc83xx_spi->done);
- mpc83xx_spi->base = ioremap(r->start, r->end - r->start + 1);
+ mpc83xx_spi->base = ioremap(mem->start, mem->end - mem->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;
- }
+ mpc83xx_spi->irq = irq;
/* Register for SPI Interrupt */
ret = request_irq(mpc83xx_spi->irq, mpc83xx_spi_irq,
@@ -649,9 +635,9 @@ static int __init mpc83xx_spi_probe(struct platform_device *dev)
printk(KERN_INFO
"%s: MPC83xx SPI Controller driver at 0x%p (irq = %d)\n",
- dev_name(&dev->dev), mpc83xx_spi->base, mpc83xx_spi->irq);
+ dev_name(dev), mpc83xx_spi->base, mpc83xx_spi->irq);
- return ret;
+ return master;
unreg_master:
destroy_workqueue(mpc83xx_spi->workqueue);
@@ -661,18 +647,16 @@ unmap_io:
iounmap(mpc83xx_spi->base);
put_master:
spi_master_put(master);
-free_master:
- kfree(master);
err:
- return ret;
+ return ERR_PTR(ret);
}
-static int __exit mpc83xx_spi_remove(struct platform_device *dev)
+static int __devexit mpc83xx_spi_remove(struct device *dev)
{
struct mpc83xx_spi *mpc83xx_spi;
struct spi_master *master;
- master = platform_get_drvdata(dev);
+ master = dev_get_drvdata(dev);
mpc83xx_spi = spi_master_get_devdata(master);
flush_workqueue(mpc83xx_spi->workqueue);
@@ -685,23 +669,293 @@ static int __exit mpc83xx_spi_remove(struct platform_device *dev)
return 0;
}
+struct mpc83xx_spi_probe_info {
+ struct fsl_spi_platform_data pdata;
+ int *gpios;
+ bool *alow_flags;
+};
+
+static struct mpc83xx_spi_probe_info *
+to_of_pinfo(struct fsl_spi_platform_data *pdata)
+{
+ return container_of(pdata, struct mpc83xx_spi_probe_info, pdata);
+}
+
+static void mpc83xx_spi_cs_control(struct spi_device *spi, bool on)
+{
+ struct device *dev = spi->dev.parent;
+ struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(dev->platform_data);
+ u16 cs = spi->chip_select;
+ int gpio = pinfo->gpios[cs];
+ bool alow = pinfo->alow_flags[cs];
+
+ gpio_set_value(gpio, on ^ alow);
+}
+
+static int of_mpc83xx_spi_get_chipselects(struct device *dev)
+{
+ struct device_node *np = dev_archdata_get_node(&dev->archdata);
+ struct fsl_spi_platform_data *pdata = dev->platform_data;
+ struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+ unsigned int ngpios;
+ int i = 0;
+ int ret;
+
+ ngpios = of_gpio_count(np);
+ if (!ngpios) {
+ /*
+ * SPI w/o chip-select line. One SPI device is still permitted
+ * though.
+ */
+ pdata->max_chipselect = 1;
+ return 0;
+ }
+
+ pinfo->gpios = kmalloc(ngpios * sizeof(pinfo->gpios), GFP_KERNEL);
+ if (!pinfo->gpios)
+ return -ENOMEM;
+ memset(pinfo->gpios, -1, ngpios * sizeof(pinfo->gpios));
+
+ pinfo->alow_flags = kzalloc(ngpios * sizeof(pinfo->alow_flags),
+ GFP_KERNEL);
+ if (!pinfo->alow_flags) {
+ ret = -ENOMEM;
+ goto err_alloc_flags;
+ }
+
+ for (; i < ngpios; i++) {
+ int gpio;
+ enum of_gpio_flags flags;
+
+ gpio = of_get_gpio_flags(np, i, &flags);
+ if (!gpio_is_valid(gpio)) {
+ dev_err(dev, "invalid gpio #%d: %d\n", i, gpio);
+ goto err_loop;
+ }
+
+ ret = gpio_request(gpio, dev_name(dev));
+ if (ret) {
+ dev_err(dev, "can't request gpio #%d: %d\n", i, ret);
+ goto err_loop;
+ }
+
+ pinfo->gpios[i] = gpio;
+ pinfo->alow_flags[i] = flags & OF_GPIO_ACTIVE_LOW;
+
+ ret = gpio_direction_output(pinfo->gpios[i],
+ pinfo->alow_flags[i]);
+ if (ret) {
+ dev_err(dev, "can't set output direction for gpio "
+ "#%d: %d\n", i, ret);
+ goto err_loop;
+ }
+ }
+
+ pdata->max_chipselect = ngpios;
+ pdata->cs_control = mpc83xx_spi_cs_control;
+
+ return 0;
+
+err_loop:
+ while (i >= 0) {
+ if (gpio_is_valid(pinfo->gpios[i]))
+ gpio_free(pinfo->gpios[i]);
+ i--;
+ }
+
+ kfree(pinfo->alow_flags);
+ pinfo->alow_flags = NULL;
+err_alloc_flags:
+ kfree(pinfo->gpios);
+ pinfo->gpios = NULL;
+ return ret;
+}
+
+static int of_mpc83xx_spi_free_chipselects(struct device *dev)
+{
+ struct fsl_spi_platform_data *pdata = dev->platform_data;
+ struct mpc83xx_spi_probe_info *pinfo = to_of_pinfo(pdata);
+ int i;
+
+ if (!pinfo->gpios)
+ return 0;
+
+ for (i = 0; i < pdata->max_chipselect; i++) {
+ if (gpio_is_valid(pinfo->gpios[i]))
+ gpio_free(pinfo->gpios[i]);
+ }
+
+ kfree(pinfo->gpios);
+ kfree(pinfo->alow_flags);
+ return 0;
+}
+
+static int __devinit of_mpc83xx_spi_probe(struct of_device *ofdev,
+ const struct of_device_id *ofid)
+{
+ struct device *dev = &ofdev->dev;
+ struct device_node *np = ofdev->node;
+ struct mpc83xx_spi_probe_info *pinfo;
+ struct fsl_spi_platform_data *pdata;
+ struct spi_master *master;
+ struct resource mem;
+ struct resource irq;
+ const void *prop;
+ int ret = -ENOMEM;
+
+ pinfo = kzalloc(sizeof(*pinfo), GFP_KERNEL);
+ if (!pinfo)
+ return -ENOMEM;
+
+ pdata = &pinfo->pdata;
+ dev->platform_data = pdata;
+
+ /* Allocate bus num dynamically. */
+ pdata->bus_num = -1;
+
+ /* SPI controller is either clocked from QE or SoC clock. */
+ pdata->sysclk = get_brgfreq();
+ if (pdata->sysclk == -1) {
+ pdata->sysclk = fsl_get_sys_freq();
+ if (pdata->sysclk == -1) {
+ ret = -ENODEV;
+ goto err_clk;
+ }
+ }
+
+ prop = of_get_property(np, "mode", NULL);
+ if (prop && !strcmp(prop, "cpu-qe"))
+ pdata->qe_mode = 1;
+
+ ret = of_mpc83xx_spi_get_chipselects(dev);
+ if (ret)
+ goto err;
+
+ ret = of_address_to_resource(np, 0, &mem);
+ if (ret)
+ goto err;
+
+ ret = of_irq_to_resource(np, 0, &irq);
+ if (!ret) {
+ ret = -EINVAL;
+ goto err;
+ }
+
+ master = mpc83xx_spi_probe(dev, &mem, irq.start);
+ if (IS_ERR(master)) {
+ ret = PTR_ERR(master);
+ goto err;
+ }
+
+ of_register_spi_devices(master, np);
+
+ return 0;
+
+err:
+ of_mpc83xx_spi_free_chipselects(dev);
+err_clk:
+ kfree(pinfo);
+ return ret;
+}
+
+static int __devexit of_mpc83xx_spi_remove(struct of_device *ofdev)
+{
+ int ret;
+
+ ret = mpc83xx_spi_remove(&ofdev->dev);
+ if (ret)
+ return ret;
+ of_mpc83xx_spi_free_chipselects(&ofdev->dev);
+ return 0;
+}
+
+static const struct of_device_id of_mpc83xx_spi_match[] = {
+ { .compatible = "fsl,spi" },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_mpc83xx_spi_match);
+
+static struct of_platform_driver of_mpc83xx_spi_driver = {
+ .name = "mpc83xx_spi",
+ .match_table = of_mpc83xx_spi_match,
+ .probe = of_mpc83xx_spi_probe,
+ .remove = __devexit_p(of_mpc83xx_spi_remove),
+};
+
+#ifdef CONFIG_MPC832x_RDB
+/*
+ * XXX XXX XXX
+ * This is "legacy" platform driver, was used by the MPC8323E-RDB boards
+ * only. The driver should go away soon, since newer MPC8323E-RDB's device
+ * tree can work with OpenFirmware driver. But for now we support old trees
+ * as well.
+ */
+static int __devinit plat_mpc83xx_spi_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ unsigned int irq;
+ struct spi_master *master;
+
+ if (!pdev->dev.platform_data)
+ return -EINVAL;
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem)
+ return -EINVAL;
+
+ irq = platform_get_irq(pdev, 0);
+ if (!irq)
+ return -EINVAL;
+
+ master = mpc83xx_spi_probe(&pdev->dev, mem, irq);
+ if (IS_ERR(master))
+ return PTR_ERR(master);
+ return 0;
+}
+
+static int __devexit plat_mpc83xx_spi_remove(struct platform_device *pdev)
+{
+ return mpc83xx_spi_remove(&pdev->dev);
+}
+
MODULE_ALIAS("platform:mpc83xx_spi");
static struct platform_driver mpc83xx_spi_driver = {
- .remove = __exit_p(mpc83xx_spi_remove),
+ .probe = plat_mpc83xx_spi_probe,
+ .remove = __exit_p(plat_mpc83xx_spi_remove),
.driver = {
.name = "mpc83xx_spi",
.owner = THIS_MODULE,
},
};
+static bool legacy_driver_failed;
+
+static void __init legacy_driver_register(void)
+{
+ legacy_driver_failed = platform_driver_register(&mpc83xx_spi_driver);
+}
+
+static void __exit legacy_driver_unregister(void)
+{
+ if (legacy_driver_failed)
+ return;
+ platform_driver_unregister(&mpc83xx_spi_driver);
+}
+#else
+static void __init legacy_driver_register(void) {}
+static void __exit legacy_driver_unregister(void) {}
+#endif /* CONFIG_MPC832x_RDB */
+
static int __init mpc83xx_spi_init(void)
{
- return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe);
+ legacy_driver_register();
+ return of_register_platform_driver(&of_mpc83xx_spi_driver);
}
static void __exit mpc83xx_spi_exit(void)
{
- platform_driver_unregister(&mpc83xx_spi_driver);
+ of_unregister_platform_driver(&of_mpc83xx_spi_driver);
+ legacy_driver_unregister();
}
module_init(mpc83xx_spi_init);
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index fe7e5f35e5d..494d3f756e2 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -354,7 +354,7 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev,
if (xspi->regs == NULL) {
rc = -ENOMEM;
dev_warn(&ofdev->dev, "ioremap failure\n");
- goto put_master;
+ goto release_mem;
}
xspi->irq = r_irq->start;
@@ -365,7 +365,7 @@ static int __init xilinx_spi_of_probe(struct of_device *ofdev,
prop = of_get_property(ofdev->node, "xlnx,num-ss-bits", &len);
if (!prop || len < sizeof(*prop)) {
dev_warn(&ofdev->dev, "no 'xlnx,num-ss-bits' property\n");
- goto put_master;
+ goto unmap_io;
}
master->num_chipselect = *prop;
@@ -397,6 +397,8 @@ free_irq:
free_irq(xspi->irq, xspi);
unmap_io:
iounmap(xspi->regs);
+release_mem:
+ release_mem_region(r_mem->start, resource_size(r_mem));
put_master:
spi_master_put(master);
return rc;
@@ -406,6 +408,7 @@ static int __devexit xilinx_spi_remove(struct of_device *ofdev)
{
struct xilinx_spi *xspi;
struct spi_master *master;
+ struct resource r_mem;
master = platform_get_drvdata(ofdev);
xspi = spi_master_get_devdata(master);
@@ -413,6 +416,8 @@ static int __devexit xilinx_spi_remove(struct of_device *ofdev)
spi_bitbang_stop(&xspi->bitbang);
free_irq(xspi->irq, xspi);
iounmap(xspi->regs);
+ if (!of_address_to_resource(ofdev->node, 0, &r_mem))
+ release_mem_region(r_mem.start, resource_size(&r_mem));
dev_set_drvdata(&ofdev->dev, 0);
spi_master_put(xspi->bitbang.master);
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 211af86a6c5..0dcf9ca0b0a 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -4,7 +4,7 @@ menuconfig STAGING
---help---
This option allows you to select a number of drivers that are
not of the "normal" Linux kernel quality level. These drivers
- are placed here in order to get a wider audience for use of
+ are placed here in order to get a wider audience to make use of
them. Please note that these drivers are under heavy
development, may or may not work, and may contain userspace
interfaces that most likely will be changed in the near
@@ -12,7 +12,7 @@ menuconfig STAGING
Using any of these drivers will taint your kernel which might
affect support options from both the community, and various
- commercial support orginizations.
+ commercial support organizations.
If you wish to work on these drivers, to help improve them, or
to report problems you have with them, please see the
@@ -73,6 +73,8 @@ source "drivers/staging/rt2860/Kconfig"
source "drivers/staging/rt2870/Kconfig"
+source "drivers/staging/rt3070/Kconfig"
+
source "drivers/staging/comedi/Kconfig"
source "drivers/staging/asus_oled/Kconfig"
@@ -93,5 +95,25 @@ source "drivers/staging/epl/Kconfig"
source "drivers/staging/android/Kconfig"
+source "drivers/staging/dst/Kconfig"
+
+source "drivers/staging/pohmelfs/Kconfig"
+
+source "drivers/staging/stlc45xx/Kconfig"
+
+source "drivers/staging/uc2322/Kconfig"
+
+source "drivers/staging/b3dfg/Kconfig"
+
+source "drivers/staging/phison/Kconfig"
+
+source "drivers/staging/p9auth/Kconfig"
+
+source "drivers/staging/heci/Kconfig"
+
+source "drivers/staging/line6/Kconfig"
+
+source "drivers/staging/serqt_usb/Kconfig"
+
endif # !STAGING_EXCLUDE_BUILD
endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 47a56f5ffab..47dfd5b4288 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_AGNX) += agnx/
obj-$(CONFIG_OTUS) += otus/
obj-$(CONFIG_RT2860) += rt2860/
obj-$(CONFIG_RT2870) += rt2870/
+obj-$(CONFIG_RT3070) += rt3070/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/
@@ -29,3 +30,13 @@ obj-$(CONFIG_INPUT_MIMIO) += mimio/
obj-$(CONFIG_TRANZPORT) += frontier/
obj-$(CONFIG_EPL) += epl/
obj-$(CONFIG_ANDROID) += android/
+obj-$(CONFIG_DST) += dst/
+obj-$(CONFIG_POHMELFS) += pohmelfs/
+obj-$(CONFIG_STLC45XX) += stlc45xx/
+obj-$(CONFIG_USB_SERIAL_ATEN2011) += uc2322/
+obj-$(CONFIG_B3DFG) += b3dfg/
+obj-$(CONFIG_IDE_PHISON) += phison/
+obj-$(CONFIG_PLAN9AUTH) += p9auth/
+obj-$(CONFIG_HECI) += heci/
+obj-$(CONFIG_LINE6_USB) += line6/
+obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb/
diff --git a/drivers/staging/agnx/agnx.h b/drivers/staging/agnx/agnx.h
index 20f36da6247..3963d2597a1 100644
--- a/drivers/staging/agnx/agnx.h
+++ b/drivers/staging/agnx/agnx.h
@@ -41,16 +41,16 @@ static const struct ieee80211_rate agnx_rates_80211g[] = {
/* { .bitrate = 20, .hw_value = 2, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
/* { .bitrate = 55, .hw_value = 3, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
/* { .bitrate = 110, .hw_value = 4, .flags = IEEE80211_RATE_SHORT_PREAMBLE }, */
- { .bitrate = 10, .hw_value = 1, },
- { .bitrate = 20, .hw_value = 2, },
- { .bitrate = 55, .hw_value = 3, },
- { .bitrate = 110, .hw_value = 4,},
+ { .bitrate = 10, .hw_value = 1, },
+ { .bitrate = 20, .hw_value = 2, },
+ { .bitrate = 55, .hw_value = 3, },
+ { .bitrate = 110, .hw_value = 4,},
{ .bitrate = 60, .hw_value = 0xB, },
{ .bitrate = 90, .hw_value = 0xF, },
{ .bitrate = 120, .hw_value = 0xA },
{ .bitrate = 180, .hw_value = 0xE, },
-// { .bitrate = 240, .hw_value = 0xd, },
+/* { .bitrate = 240, .hw_value = 0xd, }, */
{ .bitrate = 360, .hw_value = 0xD, },
{ .bitrate = 480, .hw_value = 0x8, },
{ .bitrate = 540, .hw_value = 0xC, },
@@ -110,10 +110,10 @@ struct agnx_priv {
/* Need volatile? */
u32 irq_status;
- struct delayed_work periodic_work; /* Periodic tasks like recalibrate*/
+ struct delayed_work periodic_work; /* Periodic tasks like recalibrate */
struct ieee80211_low_level_stats stats;
-// unsigned int phymode;
+ /* unsigned int phymode; */
int mode;
int channel;
u8 bssid[ETH_ALEN];
diff --git a/drivers/staging/agnx/debug.h b/drivers/staging/agnx/debug.h
index e3e25dda0ba..761d99c2d3f 100644
--- a/drivers/staging/agnx/debug.h
+++ b/drivers/staging/agnx/debug.h
@@ -23,7 +23,7 @@ static inline void agnx_bug(char *reason)
static inline void agnx_print_desc(struct agnx_desc *desc)
{
- u32 reg = be32_to_cpu(desc->frag);
+ u32 reg = be32_to_cpu(desc->frag);
PRINTK_BITS(DESC, PACKET_LEN);
@@ -291,7 +291,7 @@ static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
PRINTK_LE32(STA, sta->phy_stats_high);
PRINTK_LE32(STA, sta->phy_stats_low);
-// for (i = 0; i < 8; i++)
+ /* for (i = 0; i < 8; i++) */
agnx_print_sta_traffic(sta->traffic + 0);
PRINTK_LE16(STA, sta->traffic_class0_frag_success);
@@ -311,10 +311,10 @@ static inline void agnx_print_sta(struct agnx_priv *priv, unsigned int sta_idx)
static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
{
u16 fctl;
- int hdrlen;
+ int hdrlen;
DECLARE_MAC_BUF(mac);
- fctl = le16_to_cpu(hdr->frame_control);
+ fctl = le16_to_cpu(hdr->frame_control);
switch (fctl & IEEE80211_FCTL_FTYPE) {
case IEEE80211_FTYPE_DATA:
printk(PFX "%s DATA ", tag);
@@ -324,7 +324,7 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
break;
case IEEE80211_FTYPE_MGMT:
printk(PFX "%s MGMT ", tag);
- switch(fctl & IEEE80211_FCTL_STYPE) {
+ switch (fctl & IEEE80211_FCTL_STYPE) {
case IEEE80211_STYPE_ASSOC_REQ:
printk("SubType: ASSOC_REQ ");
break;
@@ -369,7 +369,7 @@ static inline void dump_ieee80211_hdr(struct ieee80211_hdr *hdr, char *tag)
printk(PFX "%s Packet type: Unknow\n", tag);
}
- hdrlen = ieee80211_hdrlen(fctl);
+ hdrlen = ieee80211_hdrlen(fctl);
if (hdrlen >= 4)
printk("FC=0x%04x DUR=0x%04x",
@@ -389,29 +389,28 @@ static inline void dump_txm_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0x1e8; i += 4) {
+ for (i = 0; i <= 0x1e8; i += 4)
printk(KERN_DEBUG PFX "TXM: %x---> 0x%.8x\n", i, ioread32(ctl + i));
- }
}
static inline void dump_rxm_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0x108; i += 4)
+ for (i = 0; i <= 0x108; i += 4)
printk(KERN_DEBUG PFX "RXM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2000 + i));
}
static inline void dump_bm_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0x90; i += 4)
+ for (i = 0; i <= 0x90; i += 4)
printk(KERN_DEBUG PFX "BM: %x---> 0x%.8x\n", i, ioread32(ctl + 0x2c00 + i));
}
static inline void dump_cir_registers(struct agnx_priv *priv)
{
void __iomem *ctl = priv->ctl;
int i;
- for (i = 0; i <=0xb8; i += 4)
+ for (i = 0; i <= 0xb8; i += 4)
printk(KERN_DEBUG PFX "CIR: %x---> 0x%.8x\n", i, ioread32(ctl + 0x3000 + i));
}
diff --git a/drivers/staging/agnx/pci.c b/drivers/staging/agnx/pci.c
index 854630cb527..4ff4c160142 100644
--- a/drivers/staging/agnx/pci.c
+++ b/drivers/staging/agnx/pci.c
@@ -39,34 +39,34 @@ static inline void agnx_interrupt_ack(struct agnx_priv *priv, u32 *reason)
void __iomem *ctl = priv->ctl;
u32 reg;
- if ( *reason & AGNX_STAT_RX ) {
+ if (*reason & AGNX_STAT_RX) {
/* Mark complete RX */
reg = ioread32(ctl + AGNX_CIR_RXCTL);
reg |= 0x4;
iowrite32(reg, ctl + AGNX_CIR_RXCTL);
/* disable Rx interrupt */
}
- if ( *reason & AGNX_STAT_TX ) {
+ if (*reason & AGNX_STAT_TX) {
reg = ioread32(ctl + AGNX_CIR_TXDCTL);
if (reg & 0x4) {
iowrite32(reg, ctl + AGNX_CIR_TXDCTL);
*reason |= AGNX_STAT_TXD;
}
- reg = ioread32(ctl + AGNX_CIR_TXMCTL);
+ reg = ioread32(ctl + AGNX_CIR_TXMCTL);
if (reg & 0x4) {
iowrite32(reg, ctl + AGNX_CIR_TXMCTL);
*reason |= AGNX_STAT_TXM;
}
}
- if ( *reason & AGNX_STAT_X ) {
-/* reg = ioread32(ctl + AGNX_INT_STAT); */
-/* iowrite32(reg, ctl + AGNX_INT_STAT); */
-/* /\* FIXME reinit interrupt mask *\/ */
-/* reg = 0xc390bf9 & ~IRQ_TX_BEACON; */
-/* reg &= ~IRQ_TX_DISABLE; */
-/* iowrite32(reg, ctl + AGNX_INT_MASK); */
-/* iowrite32(0x800, ctl + AGNX_CIR_BLKCTL); */
- }
+/* if (*reason & AGNX_STAT_X) {
+ reg = ioread32(ctl + AGNX_INT_STAT);
+ iowrite32(reg, ctl + AGNX_INT_STAT);
+ /* FIXME reinit interrupt mask *\/
+ reg = 0xc390bf9 & ~IRQ_TX_BEACON;
+ reg &= ~IRQ_TX_DISABLE;
+ iowrite32(reg, ctl + AGNX_INT_MASK);
+ iowrite32(0x800, ctl + AGNX_CIR_BLKCTL);
+ } */
} /* agnx_interrupt_ack */
static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
@@ -79,7 +79,7 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
spin_lock(&priv->lock);
-// printk(KERN_ERR PFX "Get a interrupt %s\n", __func__);
+/* printk(KERN_ERR PFX "Get a interrupt %s\n", __func__); */
if (priv->init_status != AGNX_START)
goto out;
@@ -92,7 +92,7 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
ret = IRQ_HANDLED;
priv->irq_status = ioread32(ctl + AGNX_INT_STAT);
-// printk(PFX "Interrupt reason is 0x%x\n", irq_reason);
+/* printk(PFX "Interrupt reason is 0x%x\n", irq_reason); */
/* Make sure the txm and txd flags don't conflict with other unknown
interrupt flag, maybe is not necessary */
irq_reason &= 0xF;
@@ -101,13 +101,13 @@ static irqreturn_t agnx_interrupt_handler(int irq, void *dev_id)
/* TODO Make sure the card finished initialized */
agnx_interrupt_ack(priv, &irq_reason);
- if ( irq_reason & AGNX_STAT_RX )
+ if (irq_reason & AGNX_STAT_RX)
handle_rx_irq(priv);
- if ( irq_reason & AGNX_STAT_TXD )
+ if (irq_reason & AGNX_STAT_TXD)
handle_txd_irq(priv);
- if ( irq_reason & AGNX_STAT_TXM )
+ if (irq_reason & AGNX_STAT_TXM)
handle_txm_irq(priv);
- if ( irq_reason & AGNX_STAT_X )
+ if (irq_reason & AGNX_STAT_X)
handle_other_irq(priv);
enable_rx_interrupt(priv);
@@ -171,7 +171,7 @@ static int agnx_alloc_rings(struct agnx_priv *priv)
len = priv->rx.size + priv->txm.size + priv->txd.size;
-// priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL);
+/* priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_KERNEL); */
priv->rx.info = kzalloc(sizeof(struct agnx_info) * len, GFP_ATOMIC);
if (!priv->rx.info)
return -ENOMEM;
@@ -210,28 +210,27 @@ static void rings_free(struct agnx_priv *priv)
#if 0
static void agnx_periodic_work_handler(struct work_struct *work)
{
- struct agnx_priv *priv = container_of(work, struct agnx_priv,
- periodic_work.work);
-// unsigned long flags;
+ struct agnx_priv *priv = container_of(work, struct agnx_priv, periodic_work.work);
+/* unsigned long flags; */
unsigned long delay;
/* fixme: using mutex?? */
-// spin_lock_irqsave(&priv->lock, flags);
+/* spin_lock_irqsave(&priv->lock, flags); */
/* TODO Recalibrate*/
-// calibrate_oscillator(priv);
-// antenna_calibrate(priv);
-// agnx_send_packet(priv, 997);
+/* calibrate_oscillator(priv); */
+/* antenna_calibrate(priv); */
+/* agnx_send_packet(priv, 997); /
/* FIXME */
/* if (debug == 3) */
/* delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY); */
/* else */
delay = msecs_to_jiffies(AGNX_PERIODIC_DELAY);
-// delay = round_jiffies(HZ * 15);
+/* delay = round_jiffies(HZ * 15); */
queue_delayed_work(priv->hw->workqueue, &priv->periodic_work, delay);
-// spin_unlock_irqrestore(&priv->lock, flags);
+/* spin_unlock_irqrestore(&priv->lock, flags); */
}
#endif
@@ -255,12 +254,12 @@ static int agnx_start(struct ieee80211_hw *dev)
goto out;
}
-// mdelay(500);
+/* mdelay(500); */
might_sleep();
agnx_hw_init(priv);
-// mdelay(500);
+/* mdelay(500); */
might_sleep();
priv->init_status = AGNX_START;
@@ -280,16 +279,16 @@ static void agnx_stop(struct ieee80211_hw *dev)
/* make sure hardware will not generate irq */
agnx_hw_reset(priv);
free_irq(priv->pdev->irq, dev);
- flush_workqueue(priv->hw->workqueue);
-// cancel_delayed_work_sync(&priv->periodic_work);
+ flush_workqueue(priv->hw->workqueue);
+/* cancel_delayed_work_sync(&priv->periodic_work); */
unfill_rings(priv);
rings_free(priv);
}
-static int agnx_config(struct ieee80211_hw *dev,
- struct ieee80211_conf *conf)
+static int agnx_config(struct ieee80211_hw *dev, u32 changed)
{
struct agnx_priv *priv = dev->priv;
+ struct ieee80211_conf *conf = &dev->conf;
int channel = ieee80211_frequency_to_channel(conf->channel->center_freq);
AGNX_TRACE;
@@ -315,7 +314,6 @@ static int agnx_config_interface(struct ieee80211_hw *dev,
spin_lock(&priv->lock);
if (memcmp(conf->bssid, priv->bssid, ETH_ALEN)) {
-// u32 reghi, reglo;
agnx_set_bssid(priv, conf->bssid);
memcpy(priv->bssid, conf->bssid, ETH_ALEN);
hash_write(priv, conf->bssid, BSSID_STAID);
@@ -425,7 +423,7 @@ static struct ieee80211_ops agnx_ops = {
.remove_interface = agnx_remove_interface,
.config = agnx_config,
.config_interface = agnx_config_interface,
- .configure_filter = agnx_configure_filter,
+ .configure_filter = agnx_configure_filter,
.get_stats = agnx_get_stats,
.get_tx_stats = agnx_get_tx_stats,
.get_tsf = agnx_get_tsft
@@ -434,11 +432,12 @@ static struct ieee80211_ops agnx_ops = {
static void __devexit agnx_pci_remove(struct pci_dev *pdev)
{
struct ieee80211_hw *dev = pci_get_drvdata(pdev);
- struct agnx_priv *priv = dev->priv;
+ struct agnx_priv *priv;
AGNX_TRACE;
if (!dev)
return;
+ priv = dev->priv;
ieee80211_unregister_hw(dev);
pci_iounmap(pdev, priv->ctl);
pci_iounmap(pdev, priv->data);
@@ -504,7 +503,7 @@ static int __devinit agnx_pci_probe(struct pci_dev *pdev,
/* Map mem #1 and #2 */
priv->ctl = pci_iomap(pdev, 0, mem_len0);
-// printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl);
+/* printk(KERN_DEBUG PFX"MEM1 mapped address is 0x%p\n", priv->ctl); */
if (!priv->ctl) {
printk(KERN_ERR PFX "Can't map device memory\n");
goto err_free_dev;
diff --git a/drivers/staging/agnx/phy.c b/drivers/staging/agnx/phy.c
index da8f10c0838..2be63312b72 100644
--- a/drivers/staging/agnx/phy.c
+++ b/drivers/staging/agnx/phy.c
@@ -114,7 +114,7 @@ static void mac_address_set(struct agnx_priv *priv)
/* FIXME */
reg = (mac_addr[0] << 24) | (mac_addr[1] << 16) | mac_addr[2] << 8 | mac_addr[3];
iowrite32(reg, ctl + AGNX_RXM_MACHI);
- reg = (mac_addr[4] << 8) | mac_addr[5];
+ reg = (mac_addr[4] << 8) | mac_addr[5];
iowrite32(reg, ctl + AGNX_RXM_MACLO);
}
@@ -127,7 +127,7 @@ static void receiver_bssid_set(struct agnx_priv *priv, u8 *bssid)
/* FIXME */
reg = bssid[0] << 24 | (bssid[1] << 16) | (bssid[2] << 8) | bssid[3];
iowrite32(reg, ctl + AGNX_RXM_BSSIDHI);
- reg = (bssid[4] << 8) | bssid[5];
+ reg = (bssid[4] << 8) | bssid[5];
iowrite32(reg, ctl + AGNX_RXM_BSSIDLO);
/* Enable the receiver */
@@ -401,9 +401,9 @@ static void rx_management_init(struct agnx_priv *priv)
agnx_write32(ctl, 0x2074, 0x1f171710);
agnx_write32(ctl, 0x2078, 0x10100d0d);
agnx_write32(ctl, 0x207c, 0x11111010);
- }
- else
+ } else {
agnx_write32(ctl, AGNX_RXM_DELAY11, 0x0);
+ }
agnx_write32(ctl, AGNX_RXM_REQRATE, 0x8195e00);
}
@@ -476,7 +476,7 @@ static void gain_ctlcnt_init(struct agnx_priv *priv)
/* It seemed if we set other bit to 1 the bit 0 will
be auto change to 0 */
agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x2 | 0x1);
-// agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1);
+/* agnx_write32(ctl, AGNX_BM_TXTOPEER, 0x1); */
} /* gain_ctlcnt_init */
@@ -490,7 +490,7 @@ static void phy_init(struct agnx_priv *priv)
/* Load InitialGainTable */
gain_table_init(priv);
- agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
+ agnx_write32(ctl, AGNX_CIR_ADDRWIN, 0x2000000);
/* Clear the following offsets in Memory Range #2: */
memset_io(data + 0x5040, 0, 0xa * 4);
@@ -586,7 +586,7 @@ static void phy_init(struct agnx_priv *priv)
agnx_write32(ctl, AGNX_GCR_SIFST11B, 0x28);
agnx_write32(ctl, AGNX_GCR_CWDETEC, 0x0);
agnx_write32(ctl, AGNX_GCR_0X38, 0x1e);
-// agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);
+/* agnx_write32(ctl, AGNX_GCR_BOACT, 0x26);*/
agnx_write32(ctl, AGNX_GCR_DISCOVMOD, 0x3);
agnx_write32(ctl, AGNX_GCR_THCAP11A, 0x32);
@@ -810,10 +810,10 @@ static void card_interface_init(struct agnx_priv *priv)
}
print_hex_dump_bytes(PFX "EEPROM: ", DUMP_PREFIX_NONE, eeprom,
ARRAY_SIZE(eeprom));
- } while(0);
+ } while (0);
spi_rc_write(ctl, RF_CHIP0, 0x26);
- reg = agnx_read32(ctl, AGNX_SPI_RLSW);
+ reg = agnx_read32(ctl, AGNX_SPI_RLSW);
/* Initialize the system interface */
system_itf_init(priv);
@@ -874,19 +874,19 @@ static void card_interface_init(struct agnx_priv *priv)
/* FIXME Enable the request */
/* Check packet length */
/* Set maximum packet length */
-/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
-/* enable_receiver(priv); */
+/* agnx_write32(ctl, AGNX_RXM_REQRATE, 0x88195e00); */
+/* enable_receiver(priv); */
/* Set the Receiver BSSID */
receiver_bssid_set(priv, bssid);
/* FIXME Set to managed mode */
set_managed_mode(priv);
-// set_promiscuous_mode(priv);
-/* set_scan_mode(priv); */
-/* set_learn_mode(priv); */
-// set_promis_and_managed(priv);
-// set_adhoc_mode(priv);
+/* set_promiscuous_mode(priv); */
+/* set_scan_mode(priv); */
+/* set_learn_mode(priv); */
+/* set_promis_and_managed(priv); */
+/* set_adhoc_mode(priv); */
/* Set the recieve request rate */
/* Check packet length */
diff --git a/drivers/staging/agnx/rf.c b/drivers/staging/agnx/rf.c
index 8294b6e2eb9..42e457a1844 100644
--- a/drivers/staging/agnx/rf.c
+++ b/drivers/staging/agnx/rf.c
@@ -109,12 +109,12 @@ void rf_chips_init(struct agnx_priv *priv)
}
/* Set SPI clock speed to 200NS */
- reg = agnx_read32(ctl, AGNX_SPI_CFG);
- reg &= ~0xF;
- reg |= 0x3;
- agnx_write32(ctl, AGNX_SPI_CFG, reg);
+ reg = agnx_read32(ctl, AGNX_SPI_CFG);
+ reg &= ~0xF;
+ reg |= 0x3;
+ agnx_write32(ctl, AGNX_SPI_CFG, reg);
- /* Set SPI clock speed to 50NS */
+ /* Set SPI clock speed to 50NS */
reg = agnx_read32(ctl, AGNX_SPI_CFG);
reg &= ~0xF;
reg |= 0x1;
@@ -256,7 +256,7 @@ static void antenna_init(struct agnx_priv *priv, int num_antenna)
agnx_write32(ctl, AGNX_GCR_THD0BTFEST, 70);
agnx_write32(ctl, AGNX_GCR_SIGHTH, 100);
agnx_write32(ctl, AGNX_GCR_SIGLTH, 48);
-// agnx_write32(ctl, AGNX_GCR_SIGLTH, 16);
+/* agnx_write32(ctl, AGNX_GCR_SIGLTH, 16); */
break;
default:
printk(KERN_WARNING PFX "Unknow antenna number\n");
@@ -275,8 +275,8 @@ static void chain_update(struct agnx_priv *priv, u32 chain)
if (reg == 0x4)
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1, reg|0x1000);
else if (reg != 0x0)
- spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
- else {
+ spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
+ else {
if (chain == 3 || chain == 6) {
spi_rf_write(ctl, RF_CHIP0|RF_CHIP1|RF_CHIP2, reg|0x1000);
agnx_write32(ctl, AGNX_GCR_RXOVERIDE, 0x0);
@@ -634,8 +634,7 @@ static void chain_calibrate(struct agnx_priv *priv, struct chains *chains,
}
} /* chain_calibrate */
-
-static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
+static inline void get_calibrete_value(struct agnx_priv *priv, struct chains *chains,
unsigned int num)
{
void __iomem *ctl = priv->ctl;
@@ -652,7 +651,7 @@ static void inline get_calibrete_value(struct agnx_priv *priv, struct chains *ch
}
if (num == 0 || num == 1 || num == 2) {
- if ( 0 == chains[num].cali)
+ if (0 == chains[num].cali)
chains[num].cali = 0xff;
else
chains[num].cali--;
@@ -669,7 +668,7 @@ static inline void calibra_delay(struct agnx_priv *priv)
unsigned int i = 100;
wmb();
- while (i--) {
+ while (--i) {
reg = (ioread32(ctl + AGNX_ACI_STATUS));
if (reg == 0x4000)
break;
diff --git a/drivers/staging/agnx/sta.c b/drivers/staging/agnx/sta.c
index d3ac675e45b..5b2d54a587c 100644
--- a/drivers/staging/agnx/sta.c
+++ b/drivers/staging/agnx/sta.c
@@ -18,7 +18,7 @@ void hash_read(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
}
@@ -40,7 +40,7 @@ void hash_write(struct agnx_priv *priv, u8 *mac_addr, u8 sta_id)
iowrite32(reghi, ctl + AGNX_RXM_HASH_CMD_HIGH);
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
if (!(reglo & 0x80000000))
printk(KERN_WARNING PFX "Update hash table failed\n");
}
@@ -59,7 +59,7 @@ void hash_delete(struct agnx_priv *priv, u32 reghi, u32 reglo, u8 sta_id)
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
printk(PFX "RX hash cmd are : %.8x%.8x\n", reghi, reglo);
}
@@ -69,15 +69,14 @@ void hash_dump(struct agnx_priv *priv, u8 sta_id)
void __iomem *ctl = priv->ctl;
u32 reghi, reglo;
- reglo = 0x0; /* dump command */
- reglo|= 0x40000000; /* status bit */
+ reglo = 0x40000000; /* status bit */
iowrite32(reglo, ctl + AGNX_RXM_HASH_CMD_LOW);
iowrite32(sta_id << 16, ctl + AGNX_RXM_HASH_DUMP_DATA);
udelay(80);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_HIGH);
- reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
+ reglo = ioread32(ctl + AGNX_RXM_HASH_CMD_LOW);
printk(PFX "hash cmd are : %.8x%.8x\n", reghi, reglo);
reghi = ioread32(ctl + AGNX_RXM_HASH_CMD_FLAG);
printk(PFX "hash flag is : %.8x\n", reghi);
@@ -91,7 +90,7 @@ void hash_dump(struct agnx_priv *priv, u8 sta_id)
void get_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int sta_idx)
{
void __iomem *ctl = priv->ctl;
- memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
+ memcpy_fromio(power, ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
sizeof(*power));
}
@@ -100,7 +99,7 @@ set_sta_power(struct agnx_priv *priv, struct agnx_sta_power *power, unsigned int
{
void __iomem *ctl = priv->ctl;
/* FIXME 2. Write Template to offset + station number */
- memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
+ memcpy_toio(ctl + AGNX_TXM_STAPOWTEMP + sizeof(*power) * sta_idx,
power, sizeof(*power));
}
@@ -135,7 +134,7 @@ inline void set_sta(struct agnx_priv *priv, struct agnx_sta *sta, unsigned int s
{
void __iomem *data = priv->data;
- memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
+ memcpy_toio(data + AGNX_PDUPOOL + sizeof(*sta) * sta_idx,
sta, sizeof(*sta));
}
@@ -165,7 +164,7 @@ static void sta_tx_workqueue_init(struct agnx_priv *priv, unsigned int sta_idx)
reg = agnx_set_bits(WORK_QUEUE_VALID, WORK_QUEUE_VALID_SHIFT, 1);
reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 1);
-// reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0);
+/* reg |= agnx_set_bits(WORK_QUEUE_ACK_TYPE, WORK_QUEUE_ACK_TYPE_SHIFT, 0); */
tx_wq.reg2 |= cpu_to_le32(reg);
/* Suppose all 8 traffic class are used */
@@ -181,7 +180,7 @@ static void sta_traffic_init(struct agnx_sta_traffic *traffic)
reg = agnx_set_bits(NEW_PACKET, NEW_PACKET_SHIFT, 1);
reg |= agnx_set_bits(TRAFFIC_VALID, TRAFFIC_VALID_SHIFT, 1);
-// reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1);
+/* reg |= agnx_set_bits(TRAFFIC_ACK_TYPE, TRAFFIC_ACK_TYPE_SHIFT, 1); */
traffic->reg0 = cpu_to_le32(reg);
/* 3. setting RX Sequence Number to 4095 */
diff --git a/drivers/staging/agnx/sta.h b/drivers/staging/agnx/sta.h
index 58d0b12900d..94e2cf1f973 100644
--- a/drivers/staging/agnx/sta.h
+++ b/drivers/staging/agnx/sta.h
@@ -16,7 +16,7 @@ struct agnx_hash_cmd {
#define PASS 0x00000001
#define PASS_SHIFT 1
__be32 cmdlo;
-}__attribute__((__packed__));
+} __attribute__((__packed__));
/*
diff --git a/drivers/staging/agnx/table.c b/drivers/staging/agnx/table.c
index c60048487b5..b52fef9db0e 100644
--- a/drivers/staging/agnx/table.c
+++ b/drivers/staging/agnx/table.c
@@ -80,7 +80,7 @@ void routing_table_init(struct agnx_priv *priv)
disable_receiver(priv);
- for ( type = 0; type < 0x3; type++ ) {
+ for (type = 0; type < 0x3; type++) {
for (subtype = 0; subtype < 0x10; subtype++) {
/* 1. Set Routing table to R/W and to Return status on Read */
reg = (type << ROUTAB_TYPE_SHIFT) |
@@ -89,7 +89,7 @@ void routing_table_init(struct agnx_priv *priv)
if (type == ROUTAB_TYPE_DATA) {
/* NULL goes to RFP */
if (subtype == ROUTAB_SUBTYPE_NULL)
-// reg |= ROUTAB_ROUTE_RFP;
+/* reg |= ROUTAB_ROUTE_RFP; */
reg |= ROUTAB_ROUTE_CPU;
/* QOS NULL goes to CPU */
else if (subtype == ROUTAB_SUBTYPE_QOSNULL)
@@ -104,7 +104,7 @@ void routing_table_init(struct agnx_priv *priv)
(subtype == ROUTAB_SUBTYPE_QOSDATAPOLL) ||
(subtype == ROUTAB_SUBTYPE_QOSDATAACKPOLL))
reg |= ROUTAB_ROUTE_ENCRY;
-// reg |= ROUTAB_ROUTE_CPU;
+/* reg |= ROUTAB_ROUTE_CPU; */
/*Drop NULL and QOS NULL ack, poll and poll ack*/
else if ((subtype == ROUTAB_SUBTYPE_NULLACK) ||
(subtype == ROUTAB_SUBTYPE_QOSNULLACK) ||
@@ -112,11 +112,11 @@ void routing_table_init(struct agnx_priv *priv)
(subtype == ROUTAB_SUBTYPE_QOSNULLPOLL) ||
(subtype == ROUTAB_SUBTYPE_NULLPOLLACK) ||
(subtype == ROUTAB_SUBTYPE_QOSNULLPOLLACK))
-// reg |= ROUTAB_ROUTE_DROP;
+/* reg |= ROUTAB_ROUTE_DROP; */
reg |= ROUTAB_ROUTE_CPU;
- }
- else
+ } else {
reg |= (ROUTAB_ROUTE_CPU);
+ }
iowrite32(reg, ctl + AGNX_RXM_ROUTAB);
/* Check to verify that the status bit cleared */
routing_table_delay();
diff --git a/drivers/staging/agnx/xmit.c b/drivers/staging/agnx/xmit.c
index 7f01528b8a4..0e034081f3a 100644
--- a/drivers/staging/agnx/xmit.c
+++ b/drivers/staging/agnx/xmit.c
@@ -17,8 +17,8 @@
#include "debug.h"
#include "phy.h"
-unsigned int rx_frame_cnt = 0;
-//unsigned int local_tx_sent_cnt = 0;
+unsigned int rx_frame_cnt;
+/* unsigned int local_tx_sent_cnt = 0; */
static inline void disable_rx_engine(struct agnx_priv *priv)
{
@@ -242,15 +242,15 @@ static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
memset(stat, 0, sizeof(*stat));
/* RSSI */
rssi = (u8 *)&hdr->phy_stats_lo;
-// stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3;
+/* stat->ssi = (rssi[0] + rssi[1] + rssi[2]) / 3; */
/* Noise */
noise = ioread32(ctl + AGNX_GCR_NOISE0);
noise += ioread32(ctl + AGNX_GCR_NOISE1);
noise += ioread32(ctl + AGNX_GCR_NOISE2);
stat->noise = noise / 3;
/* Signal quality */
- //snr = stat->ssi - stat->noise;
- if (snr >=0 && snr < 40)
+/* snr = stat->ssi - stat->noise; */
+ if (snr >= 0 && snr < 40)
stat->signal = 5 * snr / 2;
else if (snr >= 40)
stat->signal = 100;
@@ -269,10 +269,9 @@ static void get_rx_stats(struct agnx_priv *priv, struct agnx_hdr *hdr,
stat->band = IEEE80211_BAND_2GHZ;
stat->freq = agnx_channels[priv->channel - 1].center_freq;
-// stat->antenna = 3;
-// stat->mactime = be32_to_cpu(hdr->time_stamp);
-// stat->channel = priv->channel;
-
+/* stat->antenna = 3;
+ stat->mactime = be32_to_cpu(hdr->time_stamp);
+ stat->channel = priv->channel; */
}
static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
@@ -296,7 +295,7 @@ static inline void combine_hdr_frag(struct ieee80211_hdr *ieeehdr,
static inline int agnx_packet_check(struct agnx_priv *priv, struct agnx_hdr *agnxhdr,
unsigned packet_len)
{
- if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1){
+ if (agnx_get_bits(CRC_FAIL, CRC_FAIL_SHIFT, be32_to_cpu(agnxhdr->reg1)) == 1) {
printk(PFX "RX: CRC check fail\n");
goto drop;
}
@@ -320,7 +319,7 @@ void handle_rx_irq(struct agnx_priv *priv)
{
struct ieee80211_rx_status status;
unsigned int len;
-// AGNX_TRACE;
+/* AGNX_TRACE; */
do {
struct agnx_desc *desc;
@@ -341,54 +340,54 @@ void handle_rx_irq(struct agnx_priv *priv)
len = (frag & PACKET_LEN) >> PACKET_LEN_SHIFT;
if (agnx_packet_check(priv, hdr, len) == -1) {
- rx_desc_reusing(priv, i);
+ rx_desc_reusing(priv, i);
continue;
}
skb_put(skb, len);
do {
- u16 fctl;
+ u16 fctl;
fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)->frame_control);
- if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)// && !(fctl & IEEE80211_STYPE_BEACON))
+ if ((fctl & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_BEACON)/* && !(fctl & IEEE80211_STYPE_BEACON)) */
dump_ieee80211_hdr((struct ieee80211_hdr *)hdr->mac_hdr, "RX");
} while (0);
if (hdr->_11b0 && !hdr->_11g0) {
-/* int j; */
-/* u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr) */
-/* ->frame_control); */
-/* if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) { */
-/* agnx_print_rx_hdr(hdr); */
-// agnx_print_sta(priv, BSSID_STAID);
-/* for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
-/* } */
+/* int j;
+ u16 fctl = le16_to_cpu(((struct ieee80211_hdr *)hdr->mac_hdr)
+ ->frame_control);
+ if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) {
+ agnx_print_rx_hdr(hdr);
+ agnx_print_sta(priv, BSSID_STAID);
+ for (j = 0; j < 8; j++)
+ agnx_print_sta_tx_wq(priv, BSSID_STAID, j);
+ } */
get_rx_stats(priv, hdr, &status);
skb_pull(skb, sizeof(*hdr));
combine_hdr_frag((struct ieee80211_hdr *)hdr->mac_hdr, skb);
} else if (!hdr->_11b0 && hdr->_11g0) {
-// int j;
+/* int j; */
agnx_print_rx_hdr(hdr);
agnx_print_sta(priv, BSSID_STAID);
-// for (j = 0; j < 8; j++)
+/* for (j = 0; j < 8; j++) */
agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
print_hex_dump_bytes("agnx: RX_PACKET: ", DUMP_PREFIX_NONE,
skb->data, skb->len + 8);
-// if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0)
+/* if (agnx_plcp_get_bitrate_ofdm(&hdr->_11g0) == 0) */
get_rx_stats(priv, hdr, &status);
skb_pull(skb, sizeof(*hdr));
combine_hdr_frag((struct ieee80211_hdr *)
((void *)&hdr->mac_hdr), skb);
-// dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G");
+/* dump_ieee80211_hdr((struct ieee80211_hdr *)skb->data, "RX G"); */
} else
agnx_bug("Unknown packets type");
ieee80211_rx_irqsafe(priv->hw, skb, &status);
rx_desc_reinit(priv, i);
- } while ( priv->rx.idx++ );
+ } while (priv->rx.idx++);
} /* handle_rx_irq */
static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
@@ -415,40 +414,40 @@ static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
pci_unmap_single(priv->pdev, info->mapping, info->dma_len, PCI_DMA_TODEVICE);
do {
-// int j;
+/* int j; */
size_t len;
len = info->skb->len - sizeof(struct agnx_hdr) + info->hdr_len;
- // if (len == 614) {
-// agnx_print_desc(desc);
+/* if (len == 614) { */
+/* agnx_print_desc(desc); */
if (info->type == PACKET) {
-// agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data);
-/* agnx_print_sta_power(priv, LOCAL_STAID); */
-/* agnx_print_sta(priv, LOCAL_STAID); */
-/* // for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
-// agnx_print_sta_power(priv, BSSID_STAID);
-// agnx_print_sta(priv, BSSID_STAID);
-// for (j = 0; j < 8; j++)
-// agnx_print_sta_tx_wq(priv, BSSID_STAID, 0);
+/* agnx_print_tx_hdr((struct agnx_hdr *)info->skb->data); */
+/* agnx_print_sta_power(priv, LOCAL_STAID); */
+/* agnx_print_sta(priv, LOCAL_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, 0); */
+/* agnx_print_sta_power(priv, BSSID_STAID); */
+/* agnx_print_sta(priv, BSSID_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, BSSID_STAID, 0); */
}
-// }
+/* } */
} while (0);
if (info->type == PACKET) {
-// dump_txm_registers(priv);
-// dump_rxm_registers(priv);
-// dump_bm_registers(priv);
-// dump_cir_registers(priv);
+/* dump_txm_registers(priv);
+ dump_rxm_registers(priv);
+ dump_bm_registers(priv);
+ dump_cir_registers(priv); */
}
if (info->type == PACKET) {
-// struct ieee80211_hdr *hdr;
+/* struct ieee80211_hdr *hdr; */
struct ieee80211_tx_info *txi = IEEE80211_SKB_CB(info->skb);
skb_pull(info->skb, sizeof(struct agnx_hdr));
memcpy(skb_push(info->skb, info->hdr_len), &info->hdr, info->hdr_len);
-// dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE");
+/* dump_ieee80211_hdr((struct ieee80211_hdr *)info->skb->data, "TX_HANDLE"); */
/* print_hex_dump_bytes("agnx: TX_HANDLE: ", DUMP_PREFIX_NONE, */
/* info->skb->data, info->skb->len); */
@@ -462,7 +461,7 @@ static inline void handle_tx_irq(struct agnx_priv *priv, struct agnx_ring *ring)
/* ieee80211_tx_status_irqsafe(priv->hw, info->skb, &(info->tx_status)); */
/* } else */
/* dev_kfree_skb_irq(info->skb); */
- }
+ }
memset(desc, 0, sizeof(*desc));
memset(info, 0, sizeof(*info));
}
@@ -485,7 +484,7 @@ void handle_txd_irq(struct agnx_priv *priv)
void handle_other_irq(struct agnx_priv *priv)
{
-// void __iomem *ctl = priv->ctl;
+/* void __iomem *ctl = priv->ctl; */
u32 status = priv->irq_status;
void __iomem *ctl = priv->ctl;
u32 reg;
@@ -526,11 +525,11 @@ void handle_other_irq(struct agnx_priv *priv)
iowrite32(reg, ctl + AGNX_INT_MASK);
iowrite32(IRQ_RX_FRAME, ctl + AGNX_INT_STAT);
printk(PFX "IRQ: RX Frame\n");
- rx_frame_cnt++;
+ rx_frame_cnt++;
}
if (status & IRQ_ERR_INT) {
iowrite32(IRQ_ERR_INT, ctl + AGNX_INT_STAT);
-// agnx_hw_reset(priv);
+/* agnx_hw_reset(priv); */
printk(PFX "IRQ: Error Interrupt\n");
}
if (status & IRQ_TX_QUE_FULL)
@@ -558,14 +557,14 @@ void handle_other_irq(struct agnx_priv *priv)
static inline void route_flag_set(struct agnx_hdr *txhdr)
{
-// u32 reg = 0;
+/* u32 reg = 0; */
/* FIXME */
-/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
-/* txhdr->reg5 = cpu_to_be32(reg); */
- txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
-// txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18));
-// txhdr->reg5 = cpu_to_be32(0x7 << 0x0);
+/* reg = (0x7 << ROUTE_COMPRESSION_SHIFT) & ROUTE_COMPRESSION; */
+/* txhdr->reg5 = cpu_to_be32(reg); */
+ txhdr->reg5 = (0xa << 0x0) | (0x7 << 0x18);
+/* txhdr->reg5 = cpu_to_be32((0xa << 0x0) | (0x7 << 0x18)); */
+/* txhdr->reg5 = cpu_to_be32(0x7 << 0x0); */
}
/* Return 0 if no match */
@@ -579,12 +578,29 @@ static inline unsigned int get_power_level(unsigned int rate, unsigned int anten
case 55:
case 60:
case 90:
- case 120: power_level = 22; break;
- case 180: power_level = 19; break;
- case 240: power_level = 18; break;
- case 360: power_level = 16; break;
- case 480: power_level = 15; break;
- case 540: power_level = 14; break;
+ case 120:
+ power_level = 22;
+ break;
+
+ case 180:
+ power_level = 19;
+ break;
+
+ case 240:
+ power_level = 18;
+ break;
+
+ case 360:
+ power_level = 16;
+ break;
+
+ case 480:
+ power_level = 15;
+ break;
+
+ case 540:
+ power_level = 14;
+ break;
default:
agnx_bug("Error rate setting\n");
}
@@ -604,30 +620,30 @@ static inline void fill_agnx_hdr(struct agnx_priv *priv, struct agnx_info *tx_in
memset(txhdr, 0, sizeof(*txhdr));
-// reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID);
+/* reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, LOCAL_STAID); */
reg = agnx_set_bits(STATION_ID, STATION_ID_SHIFT, BSSID_STAID);
reg |= agnx_set_bits(WORKQUEUE_ID, WORKQUEUE_ID_SHIFT, 0);
txhdr->reg4 = cpu_to_be32(reg);
/* Set the Hardware Sequence Number to 1? */
reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 0);
-// reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1);
+/* reg = agnx_set_bits(SEQUENCE_NUMBER, SEQUENCE_NUMBER_SHIFT, 1); */
reg |= agnx_set_bits(MAC_HDR_LEN, MAC_HDR_LEN_SHIFT, tx_info->hdr_len);
txhdr->reg1 = cpu_to_be32(reg);
/* Set the agnx_hdr's MAC header */
memcpy(txhdr->mac_hdr, &tx_info->hdr, tx_info->hdr_len);
reg = agnx_set_bits(ACK, ACK_SHIFT, 1);
-// reg = agnx_set_bits(ACK, ACK_SHIFT, 0);
+/* reg = agnx_set_bits(ACK, ACK_SHIFT, 0); */
reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 0);
-// reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1);
+/* reg |= agnx_set_bits(MULTICAST, MULTICAST_SHIFT, 1); */
reg |= agnx_set_bits(RELAY, RELAY_SHIFT, 0);
reg |= agnx_set_bits(TM, TM_SHIFT, 0);
txhdr->reg0 = cpu_to_be32(reg);
/* Set the long and short retry limits */
- txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
- txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
+ txhdr->tx.short_retry_limit = tx_info->txi->control.rates[0].count;
+ txhdr->tx.long_retry_limit = tx_info->txi->control.rates[0].count;
/* FIXME */
len = tx_info->skb->len - sizeof(*txhdr) + tx_info->hdr_len + FCS_LEN;
@@ -652,23 +668,23 @@ static void txm_power_set(struct agnx_priv *priv,
if (txi->control.rates[0].idx < 0) {
/* For B mode Short Preamble */
reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_SHORT);
-// control->tx_rate = -control->tx_rate;
+/* control->tx_rate = -control->tx_rate; */
} else
reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211G);
-// reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG);
+/* reg = agnx_set_bits(PHY_MODE, PHY_MODE_SHIFT, AGNX_MODE_80211B_LONG); */
reg |= agnx_set_bits(SIGNAL, SIGNAL_SHIFT, 0xB);
reg |= agnx_set_bits(RATE, RATE_SHIFT, 0xB);
-// reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15);
+/* reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 15); */
reg |= agnx_set_bits(POWER_LEVEL, POWER_LEVEL_SHIFT, 20);
/* if rate < 11M set it to 0 */
reg |= agnx_set_bits(NUM_TRANSMITTERS, NUM_TRANSMITTERS_SHIFT, 1);
-// reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1);
-// reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1);
+/* reg |= agnx_set_bits(EDCF, EDCF_SHIFT, 1); */
+/* reg |= agnx_set_bits(TIFS, TIFS_SHIFT, 1); */
power.reg = reg;
-// power.reg = cpu_to_le32(reg);
+/* power.reg = cpu_to_le32(reg); */
-// set_sta_power(priv, &power, LOCAL_STAID);
+/* set_sta_power(priv, &power, LOCAL_STAID); */
set_sta_power(priv, &power, BSSID_STAID);
}
@@ -759,24 +775,24 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
txm_power_set(priv, txi);
-/* do { */
-/* int j; */
-/* size_t len; */
-/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
-/* // if (len == 614) { */
-/* agnx_print_desc(hdr_desc); */
-/* agnx_print_desc(frag_desc); */
-/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
-/* agnx_print_sta_power(priv, LOCAL_STAID); */
-/* agnx_print_sta(priv, LOCAL_STAID); */
-/* for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
-/* agnx_print_sta_power(priv, BSSID_STAID); */
-/* agnx_print_sta(priv, BSSID_STAID); */
-/* for (j = 0; j < 8; j++) */
-/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
-/* // } */
-/* } while (0); */
+/* do { */
+/* int j; */
+/* size_t len; */
+/* len = skb->len - hdr_info->dma_len + hdr_info->hdr_len; */
+/* if (len == 614) { */
+/* agnx_print_desc(hdr_desc); */
+/* agnx_print_desc(frag_desc); */
+/* agnx_print_tx_hdr((struct agnx_hdr *)skb->data); */
+/* agnx_print_sta_power(priv, LOCAL_STAID); */
+/* agnx_print_sta(priv, LOCAL_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, LOCAL_STAID, j); */
+/* agnx_print_sta_power(priv, BSSID_STAID); */
+/* agnx_print_sta(priv, BSSID_STAID); */
+/* for (j = 0; j < 8; j++) */
+/* agnx_print_sta_tx_wq(priv, BSSID_STAID, j); */
+/* } */
+/* } while (0); */
spin_unlock_irqrestore(&priv->lock, flags);
@@ -787,7 +803,7 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
reg = (ioread32(priv->ctl + AGNX_CIR_TXMCTL));
reg |= 0x8;
iowrite32((reg), priv->ctl + AGNX_CIR_TXMCTL);
- }while (0);
+ } while (0);
/* Trigger TXD */
do {
@@ -795,7 +811,7 @@ static int __agnx_tx(struct agnx_priv *priv, struct sk_buff *skb,
reg = (ioread32(priv->ctl + AGNX_CIR_TXDCTL));
reg |= 0x8;
iowrite32((reg), priv->ctl + AGNX_CIR_TXDCTL);
- }while (0);
+ } while (0);
return 0;
}
@@ -807,12 +823,12 @@ int _agnx_tx(struct agnx_priv *priv, struct sk_buff *skb)
if (tx_packet_check(skb))
return 0;
-/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
-/* skb->data, skb->len); */
+/* print_hex_dump_bytes("agnx: TX_PACKET: ", DUMP_PREFIX_NONE, */
+/* skb->data, skb->len); */
- fctl = le16_to_cpu(*((__le16 *)skb->data));
+ fctl = le16_to_cpu(*((__le16 *)skb->data));
- if ( (fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA )
+ if ((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)
return __agnx_tx(priv, skb, &priv->txd);
else
return __agnx_tx(priv, skb, &priv->txm);
diff --git a/drivers/staging/altpciechdma/altpciechdma.c b/drivers/staging/altpciechdma/altpciechdma.c
index f516140ca97..3e41e086148 100644
--- a/drivers/staging/altpciechdma/altpciechdma.c
+++ b/drivers/staging/altpciechdma/altpciechdma.c
@@ -46,7 +46,6 @@
#include <linux/cdev.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
-#include <linux/delay.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>
@@ -313,15 +312,16 @@ static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
continue;
/* do not map BARs with address 0 */
if (!bar_start || !bar_end) {
- printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
+ printk(KERN_DEBUG "BAR #%d is not present?!\n", i);
rc = -1;
goto fail;
}
bar_length = bar_end - bar_start + 1;
/* BAR length is less than driver requires? */
if (bar_length < bar_min_len[i]) {
- printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
- "requires at least %lu bytes\n", i, bar_length, bar_min_len[i]);
+ printk(KERN_DEBUG "BAR #%d length = %lu bytes but driver "
+ "requires at least %lu bytes\n",
+ i, bar_length, bar_min_len[i]);
rc = -1;
goto fail;
}
@@ -333,8 +333,8 @@ static int __devinit map_bars(struct ape_dev *ape, struct pci_dev *dev)
rc = -1;
goto fail;
}
- printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
- ape->bar[i], bar_min_len[i], bar_length);
+ printk(KERN_DEBUG "BAR[%d] mapped at 0x%p with length %lu(/%lu).\n", i,
+ ape->bar[i], bar_min_len[i], bar_length);
}
/* succesfully mapped all required BAR regions */
rc = 0;
@@ -427,11 +427,13 @@ static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first,
dma_addr_t next = sg_dma_address(&sgl[i + 1]);
/* length of this entry i */
len = sg_dma_len(&sgl[i]);
- printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
+ printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
+ (unsigned long long)addr, len);
/* entry i + 1 is non-contiguous with entry i? */
if (next != addr + len) {
/* TODO create entry here (we could overwrite i) */
- printk(KERN_DEBUG "%4d: cont_addr=0x%08x cont_len=0x%08x\n", j, cont_addr, cont_len);
+ printk(KERN_DEBUG "%4d: cont_addr=0x%Lx cont_len=0x%08x\n", j,
+ (unsigned long long)cont_addr, cont_len);
/* set descriptor for contiguous transfer */
ape_chdma_desc_set(&desc[j], cont_addr, ep_addr, cont_len);
/* next end point memory address */
@@ -447,8 +449,10 @@ static int ape_sg_to_chdma_table(struct scatterlist *sgl, int nents, int first,
addr = next;
}
/* TODO create entry here (we could overwrite i) */
- printk(KERN_DEBUG "%04d: addr=0x%08x length=0x%08x\n", i, addr, len);
- printk(KERN_DEBUG "%4d: cont_addr=0x%08x length=0x%08x\n", j, cont_addr, cont_len);
+ printk(KERN_DEBUG "%04d: addr=0x%Lx length=0x%08x\n", i,
+ (unsigned long long)addr, len);
+ printk(KERN_DEBUG "%4d: cont_addr=0x%Lx length=0x%08x\n", j,
+ (unsigned long long)cont_addr, cont_len);
j++;
return j;
}
@@ -467,15 +471,14 @@ static inline int compare(u32 *p, u32 *q, int len)
} else {
fail++;
/* show the first few miscompares */
- if (fail < 10) {
- printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
- /* but stop after a while */
- } else if (fail == 10) {
- printk(KERN_DEBUG "---more errors follow! not printed---\n");
- } else {
+ if (fail < 10)
+ printk(KERN_DEBUG "[%p] = 0x%08x != [%p] = 0x%08x ?!\n", p, *p, q, *q);
+ /* but stop after a while */
+ else if (fail == 10)
+ printk(KERN_DEBUG "---more errors follow! not printed---\n");
+ else
/* stop compare after this many errors */
- break;
- }
+ break;
}
p++;
q++;
@@ -528,7 +531,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
printk(KERN_DEBUG "ape->table_virt = 0x%p.\n", ape->table_virt);
if (!write_header || !read_header || !ape->table_virt)
- goto fail;
+ goto fail;
/* allocate and map coherently-cached memory for a DMA-able buffer */
/* @see Documentation/PCI/PCI-DMA-mapping.txt, near line 318 */
@@ -565,9 +568,8 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
/* read 8192 bytes from RC buffer to EP address 4096 */
ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus, 4096, 2 * PAGE_SIZE);
#if 1
- for (i = 0; i < 255; i++) {
+ for (i = 0; i < 255; i++)
ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus, 4096, 2 * PAGE_SIZE);
- }
/* index of last descriptor */
n = i - 1;
#endif
@@ -647,7 +649,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
printk(KERN_DEBUG "EPLAST = %u, n = %d\n", eplast, n);
if (eplast == n) {
printk(KERN_DEBUG "DONE\n");
- /* print IRQ count before the transfer */
+ /* print IRQ count before the transfer */
printk(KERN_DEBUG "#IRQs during transfer: %d\n", ape->irq_count - irq_count);
break;
}
@@ -661,9 +663,9 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
n = 0;
ape_chdma_desc_set(&ape->table_virt->desc[n], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
#if 1
- for (i = 0; i < 255; i++) {
+ for (i = 0; i < 255; i++)
ape_chdma_desc_set(&ape->table_virt->desc[i], buffer_bus + 8192, 4096, 2 * PAGE_SIZE);
- }
+
/* index of last descriptor */
n = i - 1;
#endif
@@ -691,7 +693,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
w = (u32)(n + 1);
/* enable updates of eplast for each descriptor completion */
w |= (u32)(1UL << 18)/*global EPLAST_EN*/;
-#if 0 // test variable, make a module option later
+#if 0 /* test variable, make a module option later */
/* enable MSI for each descriptor completion */
if (ape->msi_enabled)
w |= (1UL << 17)/*global MSI*/;
@@ -715,7 +717,7 @@ static int __devinit dma_test(struct ape_dev *ape, struct pci_dev *dev)
/** memory write barrier */
wmb();
/** dummy read to flush posted writes */
- //(void)ioread32();
+ /* (void) ioread32(); */
printk(KERN_DEBUG "POLL FOR WRITE:\n");
/* poll for completion, 1000 times 1 millisecond */
@@ -844,7 +846,7 @@ static int __devinit probe(struct pci_dev *dev, const struct pci_device_id *id)
}
ape->got_regions = 1;
-#if 1 // @todo For now, disable 64-bit, because I do not understand the implications (DAC!)
+#if 1 /* @todo For now, disable 64-bit, because I do not understand the implications (DAC!) */
/* query for DMA transfer */
/* @see Documentation/PCI/PCI-DMA-mapping.txt */
if (!pci_set_dma_mask(dev, DMA_64BIT_MASK)) {
@@ -947,7 +949,8 @@ static void __devexit remove(struct pci_dev *dev)
struct ape_dev *ape;
printk(KERN_DEBUG "remove(0x%p)\n", dev);
if ((dev == 0) || (dev->dev.driver_data == 0)) {
- printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n", dev, dev->dev.driver_data);
+ printk(KERN_DEBUG "remove(dev = 0x%p) dev->dev.driver_data = 0x%p\n",
+ dev, (dev? dev->dev.driver_data: NULL));
return;
}
ape = (struct ape_dev *)dev->dev.driver_data;
@@ -1048,10 +1051,9 @@ static ssize_t sg_write(struct file *file, const char __user *buf, size_t count,
printk(KERN_DEBUG DRV_NAME "_write(buf=0x%p, count=%lld, pos=%llu)\n",
buf, (s64)count, (u64)*pos);
/* TODO transfer boundaries at PAGE_SIZE granularity */
- while (remaining > 0)
- {
+ while (remaining > 0) {
/* limit DMA transfer size */
- transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN)? remaining:
+ transfer_len = (remaining < APE_CHDMA_MAX_TRANSFER_LEN) ? remaining :
APE_CHDMA_MAX_TRANSFER_LEN;
/* get all user space buffer pages and create a scattergather list */
sgm_map_user_pages(ape->sgm, transfer_addr, transfer_len, 0/*read from userspace*/);
@@ -1085,12 +1087,12 @@ static ssize_t sg_write(struct file *file, const char __user *buf, size_t count,
/*
* character device file operations
*/
-static struct file_operations sg_fops = {
- .owner = THIS_MODULE,
- .open = sg_open,
- .release = sg_close,
- .read = sg_read,
- .write = sg_write,
+static const struct file_operations sg_fops = {
+ .owner = THIS_MODULE,
+ .open = sg_open,
+ .release = sg_close,
+ .read = sg_read,
+ .write = sg_write,
};
/* sg_init() - Initialize character device
@@ -1158,12 +1160,12 @@ static struct pci_driver pci_driver = {
*/
static int __init alterapciechdma_init(void)
{
- int rc = 0;
+ int rc = 0;
printk(KERN_DEBUG DRV_NAME " init(), built at " __DATE__ " " __TIME__ "\n");
/* register this driver with the PCI bus driver */
rc = pci_register_driver(&pci_driver);
if (rc < 0)
- return rc;
+ return rc;
return 0;
}
diff --git a/drivers/staging/android/binder.c b/drivers/staging/android/binder.c
index 758131cad08..79e90fed27d 100644
--- a/drivers/staging/android/binder.c
+++ b/drivers/staging/android/binder.c
@@ -2649,14 +2649,22 @@ static void binder_vma_open(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+ printk(KERN_INFO
+ "binder: %d open vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ proc->pid, vma->vm_start, vma->vm_end,
+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+ (unsigned long)pgprot_val(vma->vm_page_prot));
dump_stack();
}
static void binder_vma_close(struct vm_area_struct *vma)
{
struct binder_proc *proc = vma->vm_private_data;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+ printk(KERN_INFO
+ "binder: %d close vm area %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ proc->pid, vma->vm_start, vma->vm_end,
+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+ (unsigned long)pgprot_val(vma->vm_page_prot));
proc->vma = NULL;
}
@@ -2677,7 +2685,11 @@ static int binder_mmap(struct file *filp, struct vm_area_struct *vma)
vma->vm_end = vma->vm_start + SZ_4M;
if (binder_debug_mask & BINDER_DEBUG_OPEN_CLOSE)
- printk(KERN_INFO "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n", proc->pid, vma->vm_start, vma->vm_end, (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags, pgprot_val(vma->vm_page_prot));
+ printk(KERN_INFO
+ "binder_mmap: %d %lx-%lx (%ld K) vma %lx pagep %lx\n",
+ proc->pid, vma->vm_start, vma->vm_end,
+ (vma->vm_end - vma->vm_start) / SZ_1K, vma->vm_flags,
+ (unsigned long)pgprot_val(vma->vm_page_prot));
if (vma->vm_flags & FORBIDDEN_MMAP_FLAGS) {
ret = -EPERM;
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index 643ac5ce381..3375c1cce2b 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -225,7 +225,7 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
buffer_size - sizeof(struct ram_console_buffer);
if (ram_console_buffer_size > buffer_size) {
- pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n",
+ pr_err("ram_console: buffer %p, invalid size %zu, datasize %zu\n",
buffer, buffer_size, ram_console_buffer_size);
return 0;
}
@@ -235,8 +235,8 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
if (ram_console_buffer_size > buffer_size) {
- pr_err("ram_console: buffer %p, invalid size %d, "
- "non-ecc datasize %d\n",
+ pr_err("ram_console: buffer %p, invalid size %zu, "
+ "non-ecc datasize %zu\n",
buffer, buffer_size, ram_console_buffer_size);
return 0;
}
@@ -322,7 +322,7 @@ static int ram_console_driver_probe(struct platform_device *pdev)
}
buffer_size = res->end - res->start + 1;
start = res->start;
- printk(KERN_INFO "ram_console: got buffer at %x, size %x\n",
+ printk(KERN_INFO "ram_console: got buffer at %zx, size %zx\n",
start, buffer_size);
buffer = ioremap(res->start, buffer_size);
if (buffer == NULL) {
diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c
index 666a186e212..04dde4b8281 100644
--- a/drivers/staging/asus_oled/asus_oled.c
+++ b/drivers/staging/asus_oled/asus_oled.c
@@ -56,10 +56,10 @@ MODULE_AUTHOR("Jakub Schmidtke, sjakub@gmail.com");
MODULE_DESCRIPTION("Asus OLED Driver v" ASUS_OLED_VERSION);
MODULE_LICENSE("GPL");
-static struct class *oled_class = 0;
-static int oled_num = 0;
+static struct class *oled_class;
+static int oled_num;
-static uint start_off = 0;
+static uint start_off;
module_param(start_off, uint, 0644);
@@ -80,20 +80,20 @@ struct oled_dev_desc_str {
};
/* table of devices that work with this driver */
-static struct usb_device_id id_table [] = {
+static struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0b05, 0x1726) }, // Asus G1/G2 (and variants)
{ USB_DEVICE(0x0b05, 0x175b) }, // Asus G50V (and possibly others - G70? G71?)
{ },
};
/* parameters of specific devices */
-static struct oled_dev_desc_str oled_dev_desc_table [] = {
+static struct oled_dev_desc_str oled_dev_desc_table[] = {
{ 0x0b05, 0x1726, 128, PACK_MODE_G1, "G1/G2" },
{ 0x0b05, 0x175b, 256, PACK_MODE_G50, "G50" },
{ },
};
-MODULE_DEVICE_TABLE (usb, id_table);
+MODULE_DEVICE_TABLE(usb, id_table);
#define SETUP_PACKET_HEADER(packet, val1, val2, val3, val4, val5, val6, val7) \
do { \
@@ -107,7 +107,7 @@ MODULE_DEVICE_TABLE (usb, id_table);
packet->header.value6 = val5; \
packet->header.value7 = val6; \
packet->header.value8 = val7; \
- } while(0);
+ } while (0);
struct asus_oled_header {
uint8_t magic1;
@@ -160,10 +160,12 @@ static void enable_oled(struct asus_oled_dev *odev, uint8_t enabl)
SETUP_PACKET_HEADER(packet, 0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00);
- if (enabl) packet->bitmap[0] = 0xaf;
- else packet->bitmap[0] = 0xae;
+ if (enabl)
+ packet->bitmap[0] = 0xaf;
+ else
+ packet->bitmap[0] = 0xae;
- for (a=0; a<1; a++) {
+ for (a = 0; a < 1; a++) {
retval = usb_bulk_msg(odev->udev,
usb_sndbulkpipe(odev->udev, 2),
packet,
@@ -252,7 +254,7 @@ static void send_packets(struct usb_device *udev, struct asus_oled_packet *packe
}
}
-static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6){
+static void send_packet(struct usb_device *udev, struct asus_oled_packet *packet, size_t offset, size_t len, char *buf, uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4, uint8_t b5, uint8_t b6) {
int retval;
int act_len;
@@ -294,7 +296,7 @@ static void send_data(struct asus_oled_dev *odev)
return;
}
- if (odev->pack_mode==PACK_MODE_G1){
+ if (odev->pack_mode == PACK_MODE_G1) {
// When sending roll-mode data the display updated only first packet.
// I have no idea why, but when static picture is send just before
// rolling picture - everything works fine.
@@ -308,7 +310,7 @@ static void send_data(struct asus_oled_dev *odev)
send_packets(odev->udev, packet, odev->buf, odev->pic_mode, packet_num);
}
else
- if (odev->pack_mode==PACK_MODE_G50){
+ if (odev->pack_mode == PACK_MODE_G50) {
send_packets_g50(odev->udev, packet, odev->buf);
}
@@ -326,7 +328,7 @@ static int append_values(struct asus_oled_dev *odev, uint8_t val, size_t count)
x += odev->x_shift;
y += odev->y_shift;
- switch(odev->pack_mode)
+ switch (odev->pack_mode)
{
case PACK_MODE_G1:
// i = (x/128)*640 + 127 - x + (y/8)*128;
@@ -377,30 +379,32 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
{
size_t offs = 0, max_offs;
- if (count < 1) return 0;
+ if (count < 1)
+ return 0;
- if (tolower(buf[0]) == 'b'){
+ if (tolower(buf[0]) == 'b') {
// binary mode, set the entire memory
size_t i;
odev->buf_size = (odev->dev_width * ASUS_OLED_DISP_HEIGHT) / 8;
- if (odev->buf) kfree(odev->buf);
+ if (odev->buf)
+ kfree(odev->buf);
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
memset(odev->buf, 0xff, odev->buf_size);
- for (i=1; i < count && i<=32*32; i++){
+ for (i = 1; i < count && i <= 32 * 32; i++) {
odev->buf[i-1] = buf[i];
odev->buf_offs = i-1;
}
- odev->width=odev->dev_width / 8;
- odev->height=ASUS_OLED_DISP_HEIGHT;
- odev->x_shift=0;
- odev->y_shift=0;
- odev->last_val=0;
+ odev->width = odev->dev_width / 8;
+ odev->height = ASUS_OLED_DISP_HEIGHT;
+ odev->x_shift = 0;
+ odev->y_shift = 0;
+ odev->last_val = 0;
send_data(odev);
@@ -416,7 +420,7 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
goto error_header;
}
- switch(tolower(buf[1])) {
+ switch (tolower(buf[1])) {
case ASUS_OLED_STATIC:
case ASUS_OLED_ROLL:
case ASUS_OLED_FLASH:
@@ -432,27 +436,36 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
if (buf[i] >= '0' && buf[i] <= '9') {
w = 10*w + (buf[i] - '0');
- if (w > ASUS_OLED_MAX_WIDTH) goto error_width;
+ if (w > ASUS_OLED_MAX_WIDTH)
+ goto error_width;
}
- else if (tolower(buf[i]) == 'x') break;
- else goto error_width;
+ else if (tolower(buf[i]) == 'x')
+ break;
+ else
+ goto error_width;
}
for (++i; i < count; ++i) {
if (buf[i] >= '0' && buf[i] <= '9') {
h = 10*h + (buf[i] - '0');
- if (h > ASUS_OLED_DISP_HEIGHT) goto error_height;
+ if (h > ASUS_OLED_DISP_HEIGHT)
+ goto error_height;
}
- else if (tolower(buf[i]) == '>') break;
- else goto error_height;
+ else if (tolower(buf[i]) == '>')
+ break;
+ else
+ goto error_height;
}
- if (w < 1 || w > ASUS_OLED_MAX_WIDTH) goto error_width;
+ if (w < 1 || w > ASUS_OLED_MAX_WIDTH)
+ goto error_width;
- if (h < 1 || h > ASUS_OLED_DISP_HEIGHT) goto error_height;
+ if (h < 1 || h > ASUS_OLED_DISP_HEIGHT)
+ goto error_height;
- if (i >= count || buf[i] != '>') goto error_header;
+ if (i >= count || buf[i] != '>')
+ goto error_header;
offs = i+1;
@@ -468,7 +481,8 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
odev->buf_size = w_mem * h_mem / 8;
- if (odev->buf) kfree(odev->buf);
+ if (odev->buf)
+ kfree(odev->buf);
odev->buf = kmalloc(odev->buf_size, GFP_KERNEL);
if (odev->buf == NULL) {
@@ -505,23 +519,30 @@ static ssize_t odev_set_picture(struct asus_oled_dev *odev, const char *buf, siz
int ret;
if (buf[offs] == '1' || buf[offs] == '#') {
- if ( (ret = append_values(odev, 1, 1)) < 0) return ret;
+ ret = append_values(odev, 1, 1);
+ if (ret < 0)
+ return ret;
}
else if (buf[offs] == '0' || buf[offs] == ' ') {
- if ( (ret = append_values(odev, 0, 1)) < 0) return ret;
+ ret = append_values(odev, 0, 1);
+ if (ret < 0)
+ return ret;
}
else if (buf[offs] == '\n') {
// New line detected. Lets assume, that all characters till the end of the
// line were equal to the last character in this line.
if (odev->buf_offs % odev->width != 0)
- if ( (ret = append_values(odev, odev->last_val,
- odev->width - (odev->buf_offs % odev->width))) < 0) return ret;
+ ret = append_values(odev, odev->last_val,
+ odev->width - (odev->buf_offs % odev->width));
+ if (ret < 0)
+ return ret;
}
offs++;
}
- if (odev->buf_offs >= max_offs) send_data(odev);
+ if (odev->buf_offs >= max_offs)
+ send_data(odev);
return count;
@@ -566,9 +587,9 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
uint16_t dev_width = 0;
oled_pack_mode_t pack_mode = PACK_MODE_LAST;
const struct oled_dev_desc_str * dev_desc = oled_dev_desc_table;
- const char *desc = 0;
+ const char *desc = NULL;
- if (id == 0) {
+ if (!id) {
// Even possible? Just to make sure...
dev_err(&interface->dev, "No usb_device_id provided!\n");
return -ENODEV;
@@ -586,7 +607,7 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
}
}
- if ( !desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
+ if (!desc || dev_width < 1 || pack_mode == PACK_MODE_LAST) {
dev_err(&interface->dev, "Missing or incomplete device description!\n");
return -ENODEV;
}
@@ -611,20 +632,20 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
odev->last_val = 0;
odev->buf = NULL;
odev->enabled = 1;
- odev->dev = 0;
+ odev->dev = NULL;
- usb_set_intfdata (interface, odev);
+ usb_set_intfdata(interface, odev);
- if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled)))) {
+ retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
+ if (retval)
goto err_files;
- }
- if ((retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture)))) {
+ retval = device_create_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
+ if (retval)
goto err_files;
- }
- odev->dev = device_create(oled_class, &interface->dev, MKDEV(0,0),
- NULL,"oled_%d", ++oled_num);
+ odev->dev = device_create(oled_class, &interface->dev, MKDEV(0, 0),
+ NULL, "oled_%d", ++oled_num);
if (IS_ERR(odev->dev)) {
retval = PTR_ERR(odev->dev);
@@ -633,13 +654,13 @@ static int asus_oled_probe(struct usb_interface *interface, const struct usb_dev
dev_set_drvdata(odev->dev, odev);
- if ( (retval = device_create_file(odev->dev, &dev_attr_enabled))) {
+ retval = device_create_file(odev->dev, &dev_attr_enabled);
+ if (retval)
goto err_class_enabled;
- }
- if ( (retval = device_create_file(odev->dev, &dev_attr_picture))) {
+ retval = device_create_file(odev->dev, &dev_attr_picture);
+ if (retval)
goto err_class_picture;
- }
dev_info(&interface->dev, "Attached Asus OLED device: %s [width %u, pack_mode %d]\n", desc, odev->dev_width, odev->pack_mode);
@@ -659,7 +680,7 @@ err_files:
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
- usb_set_intfdata (interface, NULL);
+ usb_set_intfdata(interface, NULL);
usb_put_dev(odev->udev);
kfree(odev);
@@ -670,19 +691,20 @@ static void asus_oled_disconnect(struct usb_interface *interface)
{
struct asus_oled_dev *odev;
- odev = usb_get_intfdata (interface);
- usb_set_intfdata (interface, NULL);
+ odev = usb_get_intfdata(interface);
+ usb_set_intfdata(interface, NULL);
device_remove_file(odev->dev, &dev_attr_picture);
device_remove_file(odev->dev, &dev_attr_enabled);
device_unregister(odev->dev);
- device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(picture));
- device_remove_file(&interface->dev, & ASUS_OLED_DEVICE_ATTR(enabled));
+ device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(picture));
+ device_remove_file(&interface->dev, &ASUS_OLED_DEVICE_ATTR(enabled));
usb_put_dev(odev->udev);
- if (odev->buf) kfree(odev->buf);
+ if (odev->buf)
+ kfree(odev->buf);
kfree(odev);
@@ -713,7 +735,8 @@ static int __init asus_oled_init(void)
return PTR_ERR(oled_class);
}
- if ((retval = class_create_file(oled_class, &class_attr_version))) {
+ retval = class_create_file(oled_class, &class_attr_version);
+ if (retval) {
err("Error creating class version file");
goto error;
}
@@ -740,6 +763,6 @@ static void __exit asus_oled_exit(void)
usb_deregister(&oled_driver);
}
-module_init (asus_oled_init);
-module_exit (asus_oled_exit);
+module_init(asus_oled_init);
+module_exit(asus_oled_exit);
diff --git a/drivers/staging/at76_usb/TODO b/drivers/staging/at76_usb/TODO
index 6911ca71a41..0c7ed21c3b9 100644
--- a/drivers/staging/at76_usb/TODO
+++ b/drivers/staging/at76_usb/TODO
@@ -1,2 +1,7 @@
-rewrite the driver to use the proper in-kernel wireless stack
-instead of using its own.
+Fix the mac80211 port of at76_usb (the proper in-kernel wireless
+stack) and get it included to the mainline. Patches available here:
+
+http://git.kernel.org/?p=linux/kernel/git/linville/wireless-legacy.git;a=shortlog;h=at76
+
+Contact Kalle Valo <kalle.valo@iki.fi> and linux-wireless list
+<linux-wireless@vger.kernel.org> for more information.
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
index c8e4d31c7df..6f6e36a3bd9 100644
--- a/drivers/staging/at76_usb/at76_usb.c
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -36,7 +36,7 @@
#include <net/ieee80211_radiotap.h>
#include <linux/firmware.h>
#include <linux/leds.h>
-#include <net/ieee80211.h>
+#include <linux/ieee80211.h>
#include "at76_usb.h"
@@ -1727,12 +1727,12 @@ static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
/* write TLV data elements */
- ie->id = MFIE_TYPE_SSID;
+ ie->id = WLAN_EID_SSID;
ie->len = bss->ssid_len;
memcpy(ie->data, bss->ssid, bss->ssid_len);
next_ie(&ie);
- ie->id = MFIE_TYPE_RATES;
+ ie->id = WLAN_EID_SUPP_RATES;
ie->len = sizeof(hw_rates);
memcpy(ie->data, hw_rates, sizeof(hw_rates));
next_ie(&ie); /* ie points behind the supp_rates field */
@@ -4397,7 +4397,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
switch (ie->id) {
- case MFIE_TYPE_SSID:
+ case WLAN_EID_SSID:
if (have_ssid)
break;
@@ -4420,7 +4420,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
have_ssid = 1;
break;
- case MFIE_TYPE_RATES:
+ case WLAN_EID_SUPP_RATES:
if (have_rates)
break;
@@ -4433,7 +4433,7 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
hex2str(ie->data, ie->len));
break;
- case MFIE_TYPE_DS_SET:
+ case WLAN_EID_DS_PARAMS:
if (have_channel)
break;
@@ -4443,9 +4443,9 @@ static void at76_rx_mgmt_beacon(struct at76_priv *priv,
priv->netdev->name, match->channel);
break;
- case MFIE_TYPE_CF_SET:
- case MFIE_TYPE_TIM:
- case MFIE_TYPE_IBSS_SET:
+ case WLAN_EID_CF_PARAMS:
+ case WLAN_EID_TIM:
+ case WLAN_EID_IBSS_PARAMS:
default:
at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
priv->netdev->name, ie->id, ie->len,
@@ -5370,8 +5370,7 @@ static void at76_delete_device(struct at76_priv *priv)
at76_dbg(DBG_PROC_ENTRY, "%s: unlinked urbs", __func__);
- if (priv->rx_skb)
- kfree_skb(priv->rx_skb);
+ kfree_skb(priv->rx_skb);
at76_free_bss_list(priv);
del_timer_sync(&priv->bss_list_timer);
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
index b20be9da1fa..6d60c6e23a0 100644
--- a/drivers/staging/at76_usb/at76_usb.h
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -22,6 +22,93 @@
#ifndef _AT76_USB_H
#define _AT76_USB_H
+/*
+ * ieee80211 definitions copied from net/ieee80211.h
+ */
+
+#define WEP_KEY_LEN 13
+#define WEP_KEYS 4
+
+#define IEEE80211_DATA_LEN 2304
+/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
+ 6.2.1.1.2.
+
+ The figure in section 7.1.2 suggests a body size of up to 2312
+ bytes is allowed, which is a bit confusing, I suspect this
+ represents the 2304 bytes of real data, plus a possible 8 bytes of
+ WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
+
+#define IEEE80211_1ADDR_LEN 10
+#define IEEE80211_2ADDR_LEN 16
+#define IEEE80211_3ADDR_LEN 24
+#define IEEE80211_4ADDR_LEN 30
+#define IEEE80211_FCS_LEN 4
+#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
+#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
+
+#define MIN_FRAG_THRESHOLD 256U
+#define MAX_FRAG_THRESHOLD 2346U
+
+struct ieee80211_info_element {
+ u8 id;
+ u8 len;
+ u8 data[0];
+} __attribute__ ((packed));
+
+struct ieee80211_hdr_3addr {
+ __le16 frame_ctl;
+ __le16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ __le16 seq_ctl;
+ u8 payload[0];
+} __attribute__ ((packed));
+
+struct ieee80211_auth {
+ struct ieee80211_hdr_3addr header;
+ __le16 algorithm;
+ __le16 transaction;
+ __le16 status;
+ /* challenge */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_assoc_request {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 listen_interval;
+ /* SSID, supported rates, RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_probe_response {
+ struct ieee80211_hdr_3addr header;
+ __le32 time_stamp[2];
+ __le16 beacon_interval;
+ __le16 capability;
+ /* SSID, supported rates, FH params, DS params,
+ * CF params, IBSS params, TIM (if beacon), RSN */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+/* Alias beacon for probe_response */
+#define ieee80211_beacon ieee80211_probe_response
+
+struct ieee80211_assoc_response {
+ struct ieee80211_hdr_3addr header;
+ __le16 capability;
+ __le16 status;
+ __le16 aid;
+ /* supported rates */
+ struct ieee80211_info_element info_element[0];
+} __attribute__ ((packed));
+
+struct ieee80211_disassoc {
+ struct ieee80211_hdr_3addr header;
+ __le16 reason;
+} __attribute__ ((packed));
+
/* Board types */
enum board_type {
BOARD_503_ISL3861 = 1,
diff --git a/drivers/staging/b3dfg/Kconfig b/drivers/staging/b3dfg/Kconfig
new file mode 100644
index 00000000000..524231047de
--- /dev/null
+++ b/drivers/staging/b3dfg/Kconfig
@@ -0,0 +1,9 @@
+config B3DFG
+ tristate "Brontes 3d Frame Framegrabber"
+ default n
+ ---help---
+ This driver provides support for the Brontes 3d Framegrabber
+ PCI card.
+
+ To compile this driver as a module, choose M here. The module
+ will be called b3dfg.
diff --git a/drivers/staging/b3dfg/Makefile b/drivers/staging/b3dfg/Makefile
new file mode 100644
index 00000000000..91f439ffc17
--- /dev/null
+++ b/drivers/staging/b3dfg/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_B3DFG) += b3dfg.o
diff --git a/drivers/staging/b3dfg/TODO b/drivers/staging/b3dfg/TODO
new file mode 100644
index 00000000000..f5a9298b9ac
--- /dev/null
+++ b/drivers/staging/b3dfg/TODO
@@ -0,0 +1,4 @@
+
+ - queue/wait buffer presents filltime results for each frame?
+ - counting of dropped frames
+ - review endianness
diff --git a/drivers/staging/b3dfg/b3dfg.c b/drivers/staging/b3dfg/b3dfg.c
new file mode 100644
index 00000000000..0348072b3ab
--- /dev/null
+++ b/drivers/staging/b3dfg/b3dfg.c
@@ -0,0 +1,1119 @@
+ /*
+ * Brontes PCI frame grabber driver
+ *
+ * Copyright (C) 2008 3M Company
+ * Contact: Justin Bronder <jsbronder@brontes3d.com>
+ * Original Authors: Daniel Drake <ddrake@brontes3d.com>
+ * Duane Griffin <duaneg@dghda.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/device.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/ioctl.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/types.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/poll.h>
+#include <linux/wait.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <linux/uaccess.h>
+
+static unsigned int b3dfg_nbuf = 2;
+
+module_param_named(buffer_count, b3dfg_nbuf, uint, 0444);
+
+MODULE_PARM_DESC(buffer_count, "Number of buffers (min 2, default 2)\n");
+
+MODULE_AUTHOR("Daniel Drake <ddrake@brontes3d.com>");
+MODULE_DESCRIPTION("Brontes frame grabber driver");
+MODULE_LICENSE("GPL");
+
+#define DRIVER_NAME "b3dfg"
+#define B3DFG_MAX_DEVS 4
+#define B3DFG_FRAMES_PER_BUFFER 3
+
+#define B3DFG_BAR_REGS 0
+#define B3DFG_REGS_LENGTH 0x10000
+
+#define B3DFG_IOC_MAGIC 0xb3 /* dfg :-) */
+#define B3DFG_IOCGFRMSZ _IOR(B3DFG_IOC_MAGIC, 1, int)
+#define B3DFG_IOCTNUMBUFS _IO(B3DFG_IOC_MAGIC, 2)
+#define B3DFG_IOCTTRANS _IO(B3DFG_IOC_MAGIC, 3)
+#define B3DFG_IOCTQUEUEBUF _IO(B3DFG_IOC_MAGIC, 4)
+#define B3DFG_IOCTPOLLBUF _IOWR(B3DFG_IOC_MAGIC, 5, struct b3dfg_poll)
+#define B3DFG_IOCTWAITBUF _IOWR(B3DFG_IOC_MAGIC, 6, struct b3dfg_wait)
+#define B3DFG_IOCGWANDSTAT _IOR(B3DFG_IOC_MAGIC, 7, int)
+
+enum {
+ /* number of 4kb pages per frame */
+ B3D_REG_FRM_SIZE = 0x0,
+
+ /* bit 0: set to enable interrupts
+ * bit 1: set to enable cable status change interrupts */
+ B3D_REG_HW_CTRL = 0x4,
+
+ /* bit 0-1 - 1-based ID of next pending frame transfer (0 = none)
+ * bit 2 indicates the previous DMA transfer has completed
+ * bit 3 indicates wand cable status change
+ * bit 8:15 - counter of number of discarded triplets */
+ B3D_REG_DMA_STS = 0x8,
+
+ /* bit 0: wand status (1 = present, 0 = disconnected) */
+ B3D_REG_WAND_STS = 0xc,
+
+ /* bus address for DMA transfers. lower 2 bits must be zero because DMA
+ * works with 32 bit word size. */
+ B3D_REG_EC220_DMA_ADDR = 0x8000,
+
+ /* bit 20:0 - number of 32 bit words to be transferred
+ * bit 21:31 - reserved */
+ B3D_REG_EC220_TRF_SIZE = 0x8004,
+
+ /* bit 0 - error bit
+ * bit 1 - interrupt bit (set to generate interrupt at end of transfer)
+ * bit 2 - start bit (set to start transfer)
+ * bit 3 - direction (0 = DMA_TO_DEVICE, 1 = DMA_FROM_DEVICE
+ * bit 4:31 - reserved */
+ B3D_REG_EC220_DMA_STS = 0x8008,
+};
+
+enum b3dfg_buffer_state {
+ B3DFG_BUFFER_POLLED = 0,
+ B3DFG_BUFFER_PENDING,
+ B3DFG_BUFFER_POPULATED,
+};
+
+struct b3dfg_buffer {
+ unsigned char *frame[B3DFG_FRAMES_PER_BUFFER];
+ struct list_head list;
+ u8 state;
+};
+
+struct b3dfg_dev {
+
+ /* no protection needed: all finalized at initialization time */
+ struct pci_dev *pdev;
+ struct cdev chardev;
+ struct device *dev;
+ void __iomem *regs;
+ unsigned int frame_size;
+
+ /*
+ * Protects buffer state, including buffer_queue, triplet_ready,
+ * cur_dma_frame_idx & cur_dma_frame_addr.
+ */
+ spinlock_t buffer_lock;
+ struct b3dfg_buffer *buffers;
+ struct list_head buffer_queue;
+
+ /* Last frame in triplet transferred (-1 if none). */
+ int cur_dma_frame_idx;
+
+ /* Current frame's address for DMA. */
+ dma_addr_t cur_dma_frame_addr;
+
+ /*
+ * Protects cstate_tstamp.
+ * Nests inside buffer_lock.
+ */
+ spinlock_t cstate_lock;
+ unsigned long cstate_tstamp;
+
+ /*
+ * Protects triplets_dropped.
+ * Nests inside buffers_lock.
+ */
+ spinlock_t triplets_dropped_lock;
+ unsigned int triplets_dropped;
+
+ wait_queue_head_t buffer_waitqueue;
+
+ unsigned int transmission_enabled:1;
+ unsigned int triplet_ready:1;
+};
+
+static u8 b3dfg_devices[B3DFG_MAX_DEVS];
+
+static struct class *b3dfg_class;
+static dev_t b3dfg_devt;
+
+static const struct pci_device_id b3dfg_ids[] __devinitdata = {
+ { PCI_DEVICE(0x0b3d, 0x0001) },
+ { },
+};
+
+MODULE_DEVICE_TABLE(pci, b3dfg_ids);
+
+/***** user-visible types *****/
+
+struct b3dfg_poll {
+ int buffer_idx;
+ unsigned int triplets_dropped;
+};
+
+struct b3dfg_wait {
+ int buffer_idx;
+ unsigned int timeout;
+ unsigned int triplets_dropped;
+};
+
+/**** register I/O ****/
+
+static u32 b3dfg_read32(struct b3dfg_dev *fgdev, u16 reg)
+{
+ return ioread32(fgdev->regs + reg);
+}
+
+static void b3dfg_write32(struct b3dfg_dev *fgdev, u16 reg, u32 value)
+{
+ iowrite32(value, fgdev->regs + reg);
+}
+
+/**** buffer management ****/
+
+/*
+ * Program EC220 for transfer of a specific frame.
+ * Called with buffer_lock held.
+ */
+static int setup_frame_transfer(struct b3dfg_dev *fgdev,
+ struct b3dfg_buffer *buf, int frame)
+{
+ unsigned char *frm_addr;
+ dma_addr_t frm_addr_dma;
+ unsigned int frm_size = fgdev->frame_size;
+
+ frm_addr = buf->frame[frame];
+ frm_addr_dma = pci_map_single(fgdev->pdev, frm_addr,
+ frm_size, PCI_DMA_FROMDEVICE);
+ if (pci_dma_mapping_error(fgdev->pdev, frm_addr_dma))
+ return -ENOMEM;
+
+ fgdev->cur_dma_frame_addr = frm_addr_dma;
+ fgdev->cur_dma_frame_idx = frame;
+
+ b3dfg_write32(fgdev, B3D_REG_EC220_DMA_ADDR,
+ cpu_to_le32(frm_addr_dma));
+ b3dfg_write32(fgdev, B3D_REG_EC220_TRF_SIZE,
+ cpu_to_le32(frm_size >> 2));
+ b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0xf);
+
+ return 0;
+}
+
+/* Caller should hold buffer lock */
+static void dequeue_all_buffers(struct b3dfg_dev *fgdev)
+{
+ int i;
+ for (i = 0; i < b3dfg_nbuf; i++) {
+ struct b3dfg_buffer *buf = &fgdev->buffers[i];
+ buf->state = B3DFG_BUFFER_POLLED;
+ list_del_init(&buf->list);
+ }
+}
+
+/* queue a buffer to receive data */
+static int queue_buffer(struct b3dfg_dev *fgdev, int bufidx)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ struct b3dfg_buffer *buf;
+ unsigned long flags;
+ int r = 0;
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ if (bufidx < 0 || bufidx >= b3dfg_nbuf) {
+ dev_dbg(dev, "Invalid buffer index, %d\n", bufidx);
+ r = -ENOENT;
+ goto out;
+ }
+ buf = &fgdev->buffers[bufidx];
+
+ if (unlikely(buf->state == B3DFG_BUFFER_PENDING)) {
+ dev_dbg(dev, "buffer %d is already queued\n", bufidx);
+ r = -EINVAL;
+ goto out;
+ }
+
+ buf->state = B3DFG_BUFFER_PENDING;
+ list_add_tail(&buf->list, &fgdev->buffer_queue);
+
+ if (fgdev->transmission_enabled && fgdev->triplet_ready) {
+ dev_dbg(dev, "triplet is ready, pushing immediately\n");
+ fgdev->triplet_ready = 0;
+ r = setup_frame_transfer(fgdev, buf, 0);
+ if (r)
+ dev_err(dev, "unable to map DMA buffer\n");
+ }
+
+out:
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+ return r;
+}
+
+/* non-blocking buffer poll. returns 1 if data is present in the buffer,
+ * 0 otherwise */
+static int poll_buffer(struct b3dfg_dev *fgdev, void __user *arg)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ struct b3dfg_poll p;
+ struct b3dfg_buffer *buf;
+ unsigned long flags;
+ int r = 1;
+ int arg_out = 0;
+
+ if (copy_from_user(&p, arg, sizeof(p)))
+ return -EFAULT;
+
+ if (unlikely(!fgdev->transmission_enabled)) {
+ dev_dbg(dev, "cannot poll, transmission disabled\n");
+ return -EINVAL;
+ }
+
+ if (p.buffer_idx < 0 || p.buffer_idx >= b3dfg_nbuf)
+ return -ENOENT;
+
+ buf = &fgdev->buffers[p.buffer_idx];
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ if (likely(buf->state == B3DFG_BUFFER_POPULATED)) {
+ arg_out = 1;
+ buf->state = B3DFG_BUFFER_POLLED;
+
+ /* IRQs already disabled by spin_lock_irqsave above. */
+ spin_lock(&fgdev->triplets_dropped_lock);
+ p.triplets_dropped = fgdev->triplets_dropped;
+ fgdev->triplets_dropped = 0;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+ } else {
+ r = 0;
+ }
+
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ if (arg_out && copy_to_user(arg, &p, sizeof(p)))
+ r = -EFAULT;
+
+ return r;
+}
+
+static unsigned long get_cstate_change(struct b3dfg_dev *fgdev)
+{
+ unsigned long flags, when;
+
+ spin_lock_irqsave(&fgdev->cstate_lock, flags);
+ when = fgdev->cstate_tstamp;
+ spin_unlock_irqrestore(&fgdev->cstate_lock, flags);
+ return when;
+}
+
+static int is_event_ready(struct b3dfg_dev *fgdev, struct b3dfg_buffer *buf,
+ unsigned long when)
+{
+ int result;
+ unsigned long flags;
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ spin_lock(&fgdev->cstate_lock);
+ result = (!fgdev->transmission_enabled ||
+ buf->state == B3DFG_BUFFER_POPULATED ||
+ when != fgdev->cstate_tstamp);
+ spin_unlock(&fgdev->cstate_lock);
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ return result;
+}
+
+/* sleep until a specific buffer becomes populated */
+static int wait_buffer(struct b3dfg_dev *fgdev, void __user *arg)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ struct b3dfg_wait w;
+ struct b3dfg_buffer *buf;
+ unsigned long flags, when;
+ int r;
+
+ if (copy_from_user(&w, arg, sizeof(w)))
+ return -EFAULT;
+
+ if (!fgdev->transmission_enabled) {
+ dev_dbg(dev, "cannot wait, transmission disabled\n");
+ return -EINVAL;
+ }
+
+ if (w.buffer_idx < 0 || w.buffer_idx >= b3dfg_nbuf)
+ return -ENOENT;
+
+ buf = &fgdev->buffers[w.buffer_idx];
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ if (buf->state == B3DFG_BUFFER_POPULATED) {
+ r = w.timeout;
+ goto out_triplets_dropped;
+ }
+
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ when = get_cstate_change(fgdev);
+ if (w.timeout > 0) {
+ r = wait_event_interruptible_timeout(fgdev->buffer_waitqueue,
+ is_event_ready(fgdev, buf, when),
+ (w.timeout * HZ) / 1000);
+
+ if (unlikely(r < 0))
+ goto out;
+
+ w.timeout = r * 1000 / HZ;
+ } else {
+ r = wait_event_interruptible(fgdev->buffer_waitqueue,
+ is_event_ready(fgdev, buf, when));
+
+ if (unlikely(r)) {
+ r = -ERESTARTSYS;
+ goto out;
+ }
+ }
+
+ /* TODO: Inform the user via field(s) in w? */
+ if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev)) {
+ r = -EINVAL;
+ goto out;
+ }
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ if (buf->state != B3DFG_BUFFER_POPULATED) {
+ r = -ETIMEDOUT;
+ goto out_unlock;
+ }
+
+ buf->state = B3DFG_BUFFER_POLLED;
+
+out_triplets_dropped:
+
+ /* IRQs already disabled by spin_lock_irqsave above. */
+ spin_lock(&fgdev->triplets_dropped_lock);
+ w.triplets_dropped = fgdev->triplets_dropped;
+ fgdev->triplets_dropped = 0;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+
+out_unlock:
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+ if (copy_to_user(arg, &w, sizeof(w)))
+ r = -EFAULT;
+out:
+ return r;
+}
+
+/* mmap page fault handler */
+static int b3dfg_vma_fault(struct vm_area_struct *vma,
+ struct vm_fault *vmf)
+{
+ struct b3dfg_dev *fgdev = vma->vm_file->private_data;
+ unsigned long off = vmf->pgoff << PAGE_SHIFT;
+ unsigned int frame_size = fgdev->frame_size;
+ unsigned int buf_size = frame_size * B3DFG_FRAMES_PER_BUFFER;
+ unsigned char *addr;
+
+ /* determine which buffer the offset lies within */
+ unsigned int buf_idx = off / buf_size;
+ /* and the offset into the buffer */
+ unsigned int buf_off = off % buf_size;
+
+ /* determine which frame inside the buffer the offset lies in */
+ unsigned int frm_idx = buf_off / frame_size;
+ /* and the offset into the frame */
+ unsigned int frm_off = buf_off % frame_size;
+
+ if (unlikely(buf_idx >= b3dfg_nbuf))
+ return VM_FAULT_SIGBUS;
+
+ addr = fgdev->buffers[buf_idx].frame[frm_idx] + frm_off;
+ vm_insert_pfn(vma, (unsigned long)vmf->virtual_address,
+ virt_to_phys(addr) >> PAGE_SHIFT);
+
+ return VM_FAULT_NOPAGE;
+}
+
+static struct vm_operations_struct b3dfg_vm_ops = {
+ .fault = b3dfg_vma_fault,
+};
+
+static int get_wand_status(struct b3dfg_dev *fgdev, int __user *arg)
+{
+ u32 wndstat = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
+ dev_dbg(&fgdev->pdev->dev, "wand status %x\n", wndstat);
+ return __put_user(wndstat & 0x1, arg);
+}
+
+static int enable_transmission(struct b3dfg_dev *fgdev)
+{
+ u16 command;
+ unsigned long flags;
+ struct device *dev = &fgdev->pdev->dev;
+
+ dev_dbg(dev, "enable transmission\n");
+
+ /* check the cable is plugged in. */
+ if (!b3dfg_read32(fgdev, B3D_REG_WAND_STS)) {
+ dev_dbg(dev, "cannot start transmission without wand\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Check we're a bus master.
+ * TODO: I think we can remove this having added the pci_set_master call
+ */
+ pci_read_config_word(fgdev->pdev, PCI_COMMAND, &command);
+ if (!(command & PCI_COMMAND_MASTER)) {
+ dev_err(dev, "not a bus master, force-enabling\n");
+ pci_write_config_word(fgdev->pdev, PCI_COMMAND,
+ command | PCI_COMMAND_MASTER);
+ }
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+
+ /* Handle racing enable_transmission calls. */
+ if (fgdev->transmission_enabled) {
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+ goto out;
+ }
+
+ spin_lock(&fgdev->triplets_dropped_lock);
+ fgdev->triplets_dropped = 0;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+
+ fgdev->triplet_ready = 0;
+ fgdev->cur_dma_frame_idx = -1;
+ fgdev->transmission_enabled = 1;
+
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ /* Enable DMA and cable status interrupts. */
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0x03);
+
+out:
+ return 0;
+}
+
+static void disable_transmission(struct b3dfg_dev *fgdev)
+{
+ struct device *dev = &fgdev->pdev->dev;
+ unsigned long flags;
+ u32 tmp;
+
+ dev_dbg(dev, "disable transmission\n");
+
+ /* guarantee that no more interrupts will be serviced */
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ fgdev->transmission_enabled = 0;
+
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+ /* FIXME: temporary debugging only. if the board stops transmitting,
+ * hitting ctrl+c and seeing this message is useful for determining
+ * the state of the board. */
+ tmp = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
+ dev_dbg(dev, "DMA_STS reads %x after TX stopped\n", tmp);
+
+ dequeue_all_buffers(fgdev);
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ wake_up_interruptible(&fgdev->buffer_waitqueue);
+}
+
+static int set_transmission(struct b3dfg_dev *fgdev, int enabled)
+{
+ int res = 0;
+
+ if (enabled && !fgdev->transmission_enabled)
+ res = enable_transmission(fgdev);
+ else if (!enabled && fgdev->transmission_enabled)
+ disable_transmission(fgdev);
+
+ return res;
+}
+
+/* Called in interrupt context. */
+static void handle_cstate_unplug(struct b3dfg_dev *fgdev)
+{
+ /* Disable all interrupts. */
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+ /* Stop transmission. */
+ spin_lock(&fgdev->buffer_lock);
+ fgdev->transmission_enabled = 0;
+
+ fgdev->cur_dma_frame_idx = -1;
+ fgdev->triplet_ready = 0;
+ if (fgdev->cur_dma_frame_addr) {
+ pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
+ fgdev->frame_size, PCI_DMA_FROMDEVICE);
+ fgdev->cur_dma_frame_addr = 0;
+ }
+ dequeue_all_buffers(fgdev);
+ spin_unlock(&fgdev->buffer_lock);
+}
+
+/* Called in interrupt context. */
+static void handle_cstate_change(struct b3dfg_dev *fgdev)
+{
+ u32 cstate = b3dfg_read32(fgdev, B3D_REG_WAND_STS);
+ unsigned long when;
+ struct device *dev = &fgdev->pdev->dev;
+
+ dev_dbg(dev, "cable state change: %u\n", cstate);
+
+ /*
+ * When the wand is unplugged we reset our state. The hardware will
+ * have done the same internally.
+ *
+ * Note we should never see a cable *plugged* event, as interrupts
+ * should only be enabled when transmitting, which requires the cable
+ * to be plugged. If we do see one it probably means the cable has been
+ * unplugged and re-plugged very rapidly. Possibly because it has a
+ * broken wire and is momentarily losing contact.
+ *
+ * TODO: At the moment if you plug in the cable then enable transmission
+ * the hardware will raise a couple of spurious interrupts, so
+ * just ignore them for now.
+ *
+ * Once the hardware is fixed we should complain and treat it as an
+ * unplug. Or at least track how frequently it is happening and do
+ * so if too many come in.
+ */
+ if (cstate) {
+ dev_warn(dev, "ignoring unexpected plug event\n");
+ return;
+ }
+ handle_cstate_unplug(fgdev);
+
+ /*
+ * Record cable state change timestamp & wake anyone waiting
+ * on a cable state change. Be paranoid about ensuring events
+ * are not missed if we somehow get two interrupts in a jiffy.
+ */
+ spin_lock(&fgdev->cstate_lock);
+ when = jiffies_64;
+ if (when <= fgdev->cstate_tstamp)
+ when = fgdev->cstate_tstamp + 1;
+ fgdev->cstate_tstamp = when;
+ wake_up_interruptible(&fgdev->buffer_waitqueue);
+ spin_unlock(&fgdev->cstate_lock);
+}
+
+/* Called with buffer_lock held. */
+static void transfer_complete(struct b3dfg_dev *fgdev)
+{
+ struct b3dfg_buffer *buf;
+ struct device *dev = &fgdev->pdev->dev;
+
+ pci_unmap_single(fgdev->pdev, fgdev->cur_dma_frame_addr,
+ fgdev->frame_size, PCI_DMA_FROMDEVICE);
+ fgdev->cur_dma_frame_addr = 0;
+
+ buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
+ if (buf) {
+ dev_dbg(dev, "handle frame completion\n");
+ if (fgdev->cur_dma_frame_idx == B3DFG_FRAMES_PER_BUFFER - 1) {
+
+ /* last frame of that triplet completed */
+ dev_dbg(dev, "triplet completed\n");
+ buf->state = B3DFG_BUFFER_POPULATED;
+ list_del_init(&buf->list);
+ wake_up_interruptible(&fgdev->buffer_waitqueue);
+ }
+ } else {
+ dev_err(dev, "got frame but no buffer!\n");
+ }
+}
+
+/*
+ * Called with buffer_lock held.
+ *
+ * Note that idx is the (1-based) *next* frame to be transferred, while
+ * cur_dma_frame_idx is the (0-based) *last* frame to have been transferred (or
+ * -1 if none). Thus there should be a difference of 2 between them.
+ */
+static bool setup_next_frame_transfer(struct b3dfg_dev *fgdev, int idx)
+{
+ struct b3dfg_buffer *buf;
+ struct device *dev = &fgdev->pdev->dev;
+ bool need_ack = 1;
+
+ dev_dbg(dev, "program DMA transfer for next frame: %d\n", idx);
+
+ buf = list_entry(fgdev->buffer_queue.next, struct b3dfg_buffer, list);
+ if (buf) {
+ if (idx == fgdev->cur_dma_frame_idx + 2) {
+ if (setup_frame_transfer(fgdev, buf, idx - 1))
+ dev_err(dev, "unable to map DMA buffer\n");
+ need_ack = 0;
+ } else {
+ dev_err(dev, "frame mismatch, got %d, expected %d\n",
+ idx, fgdev->cur_dma_frame_idx + 2);
+
+ /* FIXME: handle dropped triplets here */
+ }
+ } else {
+ dev_err(dev, "cannot setup DMA, no buffer\n");
+ }
+
+ return need_ack;
+}
+
+static irqreturn_t b3dfg_intr(int irq, void *dev_id)
+{
+ struct b3dfg_dev *fgdev = dev_id;
+ struct device *dev = &fgdev->pdev->dev;
+ u32 sts;
+ u8 dropped;
+ bool need_ack = 1;
+ irqreturn_t res = IRQ_HANDLED;
+
+ sts = b3dfg_read32(fgdev, B3D_REG_DMA_STS);
+ if (unlikely(sts == 0)) {
+ dev_warn(dev, "ignore interrupt, DMA status is 0\n");
+ res = IRQ_NONE;
+ goto out;
+ }
+
+ if (unlikely(!fgdev->transmission_enabled)) {
+ dev_warn(dev, "ignore interrupt, TX disabled\n");
+ res = IRQ_HANDLED;
+ goto out;
+ }
+
+ /* Handle dropped frames, as reported by the hardware. */
+ dropped = (sts >> 8) & 0xff;
+ dev_dbg(dev, "intr: DMA_STS=%08x (drop=%d comp=%d next=%d)\n",
+ sts, dropped, !!(sts & 0x4), sts & 0x3);
+ if (unlikely(dropped > 0)) {
+ spin_lock(&fgdev->triplets_dropped_lock);
+ fgdev->triplets_dropped += dropped;
+ spin_unlock(&fgdev->triplets_dropped_lock);
+ }
+
+ /* Handle a cable state change (i.e. the wand being unplugged). */
+ if (sts & 0x08) {
+ handle_cstate_change(fgdev);
+ goto out;
+ }
+
+ spin_lock(&fgdev->buffer_lock);
+ if (unlikely(list_empty(&fgdev->buffer_queue))) {
+
+ /* FIXME need more sanity checking here */
+ dev_info(dev, "buffer not ready for next transfer\n");
+ fgdev->triplet_ready = 1;
+ goto out_unlock;
+ }
+
+ /* Has a frame transfer been completed? */
+ if (sts & 0x4) {
+ u32 dma_status = b3dfg_read32(fgdev, B3D_REG_EC220_DMA_STS);
+
+ /* Check for DMA errors reported by the hardware. */
+ if (unlikely(dma_status & 0x1)) {
+ dev_err(dev, "EC220 error: %08x\n", dma_status);
+
+ /* FIXME flesh out error handling */
+ goto out_unlock;
+ }
+
+ /* Sanity check, we should have a frame index at this point. */
+ if (unlikely(fgdev->cur_dma_frame_idx == -1)) {
+ dev_err(dev, "completed but no last idx?\n");
+
+ /* FIXME flesh out error handling */
+ goto out_unlock;
+ }
+
+ transfer_complete(fgdev);
+ }
+
+ /* Is there another frame transfer pending? */
+ if (sts & 0x3)
+ need_ack = setup_next_frame_transfer(fgdev, sts & 0x3);
+ else
+ fgdev->cur_dma_frame_idx = -1;
+
+out_unlock:
+ spin_unlock(&fgdev->buffer_lock);
+out:
+ if (need_ack) {
+ dev_dbg(dev, "acknowledging interrupt\n");
+ b3dfg_write32(fgdev, B3D_REG_EC220_DMA_STS, 0x0b);
+ }
+ return res;
+}
+
+static int b3dfg_open(struct inode *inode, struct file *filp)
+{
+ struct b3dfg_dev *fgdev =
+ container_of(inode->i_cdev, struct b3dfg_dev, chardev);
+
+ dev_dbg(&fgdev->pdev->dev, "open\n");
+ filp->private_data = fgdev;
+ return 0;
+}
+
+static int b3dfg_release(struct inode *inode, struct file *filp)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+ dev_dbg(&fgdev->pdev->dev, "release\n");
+ disable_transmission(fgdev);
+ return 0;
+}
+
+static long b3dfg_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+
+ switch (cmd) {
+ case B3DFG_IOCGFRMSZ:
+ return __put_user(fgdev->frame_size, (int __user *) arg);
+ case B3DFG_IOCGWANDSTAT:
+ return get_wand_status(fgdev, (int __user *) arg);
+ case B3DFG_IOCTTRANS:
+ return set_transmission(fgdev, (int) arg);
+ case B3DFG_IOCTQUEUEBUF:
+ return queue_buffer(fgdev, (int) arg);
+ case B3DFG_IOCTPOLLBUF:
+ return poll_buffer(fgdev, (void __user *) arg);
+ case B3DFG_IOCTWAITBUF:
+ return wait_buffer(fgdev, (void __user *) arg);
+ default:
+ dev_dbg(&fgdev->pdev->dev, "unrecognised ioctl %x\n", cmd);
+ return -EINVAL;
+ }
+}
+
+static unsigned int b3dfg_poll(struct file *filp, poll_table *poll_table)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+ unsigned long flags, when;
+ int i;
+ int r = 0;
+
+ when = get_cstate_change(fgdev);
+ poll_wait(filp, &fgdev->buffer_waitqueue, poll_table);
+
+ spin_lock_irqsave(&fgdev->buffer_lock, flags);
+ for (i = 0; i < b3dfg_nbuf; i++) {
+ if (fgdev->buffers[i].state == B3DFG_BUFFER_POPULATED) {
+ r = POLLIN | POLLRDNORM;
+ break;
+ }
+ }
+ spin_unlock_irqrestore(&fgdev->buffer_lock, flags);
+
+ /* TODO: Confirm this is how we want to communicate the change. */
+ if (!fgdev->transmission_enabled || when != get_cstate_change(fgdev))
+ r = POLLERR;
+
+ return r;
+}
+
+static int b3dfg_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+ struct b3dfg_dev *fgdev = filp->private_data;
+ unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
+ unsigned long vsize = vma->vm_end - vma->vm_start;
+ unsigned long bufdatalen = b3dfg_nbuf * fgdev->frame_size * 3;
+ unsigned long psize = bufdatalen - offset;
+ int r = 0;
+
+ if (vsize <= psize) {
+ vma->vm_flags |= VM_IO | VM_RESERVED | VM_CAN_NONLINEAR |
+ VM_PFNMAP;
+ vma->vm_ops = &b3dfg_vm_ops;
+ } else {
+ r = -EINVAL;
+ }
+
+ return r;
+}
+
+static struct file_operations b3dfg_fops = {
+ .owner = THIS_MODULE,
+ .open = b3dfg_open,
+ .release = b3dfg_release,
+ .unlocked_ioctl = b3dfg_ioctl,
+ .poll = b3dfg_poll,
+ .mmap = b3dfg_mmap,
+};
+
+static void free_all_frame_buffers(struct b3dfg_dev *fgdev)
+{
+ int i, j;
+ for (i = 0; i < b3dfg_nbuf; i++)
+ for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++)
+ kfree(fgdev->buffers[i].frame[j]);
+ kfree(fgdev->buffers);
+}
+
+/* initialize device and any data structures. called before any interrupts
+ * are enabled. */
+static int b3dfg_init_dev(struct b3dfg_dev *fgdev)
+{
+ int i, j;
+ u32 frm_size = b3dfg_read32(fgdev, B3D_REG_FRM_SIZE);
+
+ /* Disable interrupts. In abnormal circumstances (e.g. after a crash)
+ * the board may still be transmitting from the previous session. If we
+ * ensure that interrupts are disabled before we later enable them, we
+ * are sure to capture a triplet from the start, rather than starting
+ * from frame 2 or 3. Disabling interrupts causes the FG to throw away
+ * all buffered data and stop buffering more until interrupts are
+ * enabled again.
+ */
+ b3dfg_write32(fgdev, B3D_REG_HW_CTRL, 0);
+
+ fgdev->frame_size = frm_size * 4096;
+ fgdev->buffers = kzalloc(sizeof(struct b3dfg_buffer) * b3dfg_nbuf,
+ GFP_KERNEL);
+ if (!fgdev->buffers)
+ goto err_no_buf;
+ for (i = 0; i < b3dfg_nbuf; i++) {
+ struct b3dfg_buffer *buf = &fgdev->buffers[i];
+ for (j = 0; j < B3DFG_FRAMES_PER_BUFFER; j++) {
+ buf->frame[j] = kmalloc(fgdev->frame_size, GFP_KERNEL);
+ if (!buf->frame[j])
+ goto err_no_mem;
+ }
+ INIT_LIST_HEAD(&buf->list);
+ }
+
+ INIT_LIST_HEAD(&fgdev->buffer_queue);
+ init_waitqueue_head(&fgdev->buffer_waitqueue);
+ spin_lock_init(&fgdev->buffer_lock);
+ spin_lock_init(&fgdev->cstate_lock);
+ spin_lock_init(&fgdev->triplets_dropped_lock);
+ return 0;
+
+err_no_mem:
+ free_all_frame_buffers(fgdev);
+err_no_buf:
+ return -ENOMEM;
+}
+
+/* find next free minor number, returns -1 if none are availabile */
+static int get_free_minor(void)
+{
+ int i;
+ for (i = 0; i < B3DFG_MAX_DEVS; i++) {
+ if (b3dfg_devices[i] == 0)
+ return i;
+ }
+ return -1;
+}
+
+static int __devinit b3dfg_probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct b3dfg_dev *fgdev = kzalloc(sizeof(*fgdev), GFP_KERNEL);
+ int r = 0;
+ int minor = get_free_minor();
+ dev_t devno = MKDEV(MAJOR(b3dfg_devt), minor);
+ unsigned long res_len;
+ resource_size_t res_base;
+
+ if (fgdev == NULL)
+ return -ENOMEM;
+
+ if (minor < 0) {
+ dev_err(&pdev->dev, "too many devices found!\n");
+ r = -EIO;
+ goto err_free;
+ }
+
+ b3dfg_devices[minor] = 1;
+ dev_info(&pdev->dev, "probe device with IRQ %d\n", pdev->irq);
+
+ cdev_init(&fgdev->chardev, &b3dfg_fops);
+ fgdev->chardev.owner = THIS_MODULE;
+
+ r = cdev_add(&fgdev->chardev, devno, 1);
+ if (r) {
+ dev_err(&pdev->dev, "cannot add char device\n");
+ goto err_release_minor;
+ }
+
+ fgdev->dev = device_create(
+ b3dfg_class,
+ &pdev->dev,
+ devno,
+ dev_get_drvdata(&pdev->dev),
+ DRIVER_NAME "%d", minor);
+
+ if (IS_ERR(fgdev->dev)) {
+ dev_err(&pdev->dev, "cannot create device\n");
+ r = PTR_ERR(fgdev->dev);
+ goto err_del_cdev;
+ }
+
+ r = pci_enable_device(pdev);
+ if (r) {
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ goto err_dev_unreg;
+ }
+
+ res_len = pci_resource_len(pdev, B3DFG_BAR_REGS);
+ if (res_len != B3DFG_REGS_LENGTH) {
+ dev_err(&pdev->dev, "invalid register resource size\n");
+ r = -EIO;
+ goto err_disable;
+ }
+
+ if (pci_resource_flags(pdev, B3DFG_BAR_REGS)
+ != (IORESOURCE_MEM | IORESOURCE_SIZEALIGN)) {
+ dev_err(&pdev->dev, "invalid resource flags\n");
+ r = -EIO;
+ goto err_disable;
+ }
+ r = pci_request_regions(pdev, DRIVER_NAME);
+ if (r) {
+ dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+ goto err_disable;
+ }
+
+ pci_set_master(pdev);
+
+ r = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
+ if (r) {
+ dev_err(&pdev->dev, "no usable DMA configuration\n");
+ goto err_free_res;
+ }
+
+ res_base = pci_resource_start(pdev, B3DFG_BAR_REGS);
+ fgdev->regs = ioremap_nocache(res_base, res_len);
+ if (!fgdev->regs) {
+ dev_err(&pdev->dev, "regs ioremap failed\n");
+ r = -EIO;
+ goto err_free_res;
+ }
+
+ fgdev->pdev = pdev;
+ pci_set_drvdata(pdev, fgdev);
+ r = b3dfg_init_dev(fgdev);
+ if (r < 0) {
+ dev_err(&pdev->dev, "failed to initalize device\n");
+ goto err_unmap;
+ }
+
+ r = request_irq(pdev->irq, b3dfg_intr, IRQF_SHARED, DRIVER_NAME, fgdev);
+ if (r) {
+ dev_err(&pdev->dev, "couldn't request irq %d\n", pdev->irq);
+ goto err_free_bufs;
+ }
+
+ return 0;
+
+err_free_bufs:
+ free_all_frame_buffers(fgdev);
+err_unmap:
+ iounmap(fgdev->regs);
+err_free_res:
+ pci_release_regions(pdev);
+err_disable:
+ pci_disable_device(pdev);
+err_dev_unreg:
+ device_destroy(b3dfg_class, devno);
+err_del_cdev:
+ cdev_del(&fgdev->chardev);
+err_release_minor:
+ b3dfg_devices[minor] = 0;
+err_free:
+ kfree(fgdev);
+ return r;
+}
+
+static void __devexit b3dfg_remove(struct pci_dev *pdev)
+{
+ struct b3dfg_dev *fgdev = pci_get_drvdata(pdev);
+ unsigned int minor = MINOR(fgdev->chardev.dev);
+
+ dev_dbg(&pdev->dev, "remove\n");
+
+ free_irq(pdev->irq, fgdev);
+ iounmap(fgdev->regs);
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+ device_destroy(b3dfg_class, MKDEV(MAJOR(b3dfg_devt), minor));
+ cdev_del(&fgdev->chardev);
+ free_all_frame_buffers(fgdev);
+ kfree(fgdev);
+ b3dfg_devices[minor] = 0;
+}
+
+static struct pci_driver b3dfg_driver = {
+ .name = DRIVER_NAME,
+ .id_table = b3dfg_ids,
+ .probe = b3dfg_probe,
+ .remove = __devexit_p(b3dfg_remove),
+};
+
+static int __init b3dfg_module_init(void)
+{
+ int r;
+
+ if (b3dfg_nbuf < 2) {
+ printk(KERN_ERR DRIVER_NAME
+ ": buffer_count is out of range (must be >= 2)");
+ return -EINVAL;
+ }
+
+ printk(KERN_INFO DRIVER_NAME ": loaded\n");
+
+ b3dfg_class = class_create(THIS_MODULE, DRIVER_NAME);
+ if (IS_ERR(b3dfg_class))
+ return PTR_ERR(b3dfg_class);
+
+ r = alloc_chrdev_region(&b3dfg_devt, 0, B3DFG_MAX_DEVS, DRIVER_NAME);
+ if (r)
+ goto err1;
+
+ r = pci_register_driver(&b3dfg_driver);
+ if (r)
+ goto err2;
+
+ return r;
+
+err2:
+ unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
+err1:
+ class_destroy(b3dfg_class);
+ return r;
+}
+
+static void __exit b3dfg_module_exit(void)
+{
+ printk(KERN_INFO DRIVER_NAME ": unloaded\n");
+ pci_unregister_driver(&b3dfg_driver);
+ unregister_chrdev_region(b3dfg_devt, B3DFG_MAX_DEVS);
+ class_destroy(b3dfg_class);
+}
+
+module_init(b3dfg_module_init);
+module_exit(b3dfg_module_exit);
diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig
index b47ca1e7e38..2d819d278b0 100644
--- a/drivers/staging/comedi/Kconfig
+++ b/drivers/staging/comedi/Kconfig
@@ -1,11 +1,18 @@
config COMEDI
- tristate "Data Acquision support (comedi)"
+ tristate "Data acquisition support (comedi)"
default N
depends on m
---help---
- Enable support a wide range of data acquision devices
+ Enable support a wide range of data acquisition devices
for Linux.
+config COMEDI_DEBUG
+ bool "Comedi debugging"
+ depends on COMEDI != n
+ help
+ This is an option for use by developers; most people should
+ say N here. This enables comedi core and driver debugging.
+
config COMEDI_RT
tristate "Comedi Real-time support"
depends on COMEDI && RT
@@ -20,6 +27,13 @@ config COMEDI_PCI_DRIVERS
---help---
Enable lots of comedi PCI drivers to be built
+config COMEDI_PCMCIA_DRIVERS
+ tristate "Comedi PCMCIA drivers"
+ depends on COMEDI && PCMCIAI
+ default N
+ ---help---
+ Enable lots of comedi PCMCIA drivers to be built
+
config COMEDI_USB_DRIVERS
tristate "Comedi USB drivers"
depends on COMEDI && USB
diff --git a/drivers/staging/comedi/comedi.h b/drivers/staging/comedi/comedi.h
index 36d2e1b01e7..e6b5f16edb0 100644
--- a/drivers/staging/comedi/comedi.h
+++ b/drivers/staging/comedi/comedi.h
@@ -57,9 +57,6 @@ extern "C" {
/* max length of device and driver names */
#define COMEDI_NAMELEN 20
- typedef unsigned int lsampl_t;
- typedef unsigned short sampl_t;
-
/* packs and unpacks a channel/range number */
#define CR_PACK(chan, rng, aref) ((((aref)&0x3)<<24) | (((rng)&0xff)<<16) | (chan))
@@ -261,10 +258,11 @@ enum configuration_ids {
INSN_CONFIG_GET_CLOCK_SRC = 2004, /* Get master clock source */
INSN_CONFIG_SET_OTHER_SRC = 2005, /* Set other source */
/* INSN_CONFIG_GET_OTHER_SRC = 2006,*/ /* Get other source */
- INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE, /* Get size in bytes of
- subdevice's on-board fifos
- used during streaming
- input/output */
+ INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE = 2006, /* Get size in bytes of
+ subdevice's on-board
+ fifos used during
+ streaming
+ input/output */
INSN_CONFIG_SET_COUNTER_MODE = 4097,
INSN_CONFIG_8254_SET_MODE = INSN_CONFIG_SET_COUNTER_MODE, /* deprecated */
INSN_CONFIG_8254_READ_STATUS = 4098,
@@ -293,45 +291,32 @@ enum comedi_support_level {
/* ioctls */
#define CIO 'd'
-#define COMEDI_DEVCONFIG _IOW(CIO, 0, comedi_devconfig)
-#define COMEDI_DEVINFO _IOR(CIO, 1, comedi_devinfo)
-#define COMEDI_SUBDINFO _IOR(CIO, 2, comedi_subdinfo)
-#define COMEDI_CHANINFO _IOR(CIO, 3, comedi_chaninfo)
+#define COMEDI_DEVCONFIG _IOW(CIO, 0, struct comedi_devconfig)
+#define COMEDI_DEVINFO _IOR(CIO, 1, struct comedi_devinfo)
+#define COMEDI_SUBDINFO _IOR(CIO, 2, struct comedi_subdinfo)
+#define COMEDI_CHANINFO _IOR(CIO, 3, struct comedi_chaninfo)
#define COMEDI_TRIG _IOWR(CIO, 4, comedi_trig)
#define COMEDI_LOCK _IO(CIO, 5)
#define COMEDI_UNLOCK _IO(CIO, 6)
#define COMEDI_CANCEL _IO(CIO, 7)
-#define COMEDI_RANGEINFO _IOR(CIO, 8, comedi_rangeinfo)
-#define COMEDI_CMD _IOR(CIO, 9, comedi_cmd)
-#define COMEDI_CMDTEST _IOR(CIO, 10, comedi_cmd)
-#define COMEDI_INSNLIST _IOR(CIO, 11, comedi_insnlist)
-#define COMEDI_INSN _IOR(CIO, 12, comedi_insn)
-#define COMEDI_BUFCONFIG _IOR(CIO, 13, comedi_bufconfig)
-#define COMEDI_BUFINFO _IOWR(CIO, 14, comedi_bufinfo)
+#define COMEDI_RANGEINFO _IOR(CIO, 8, struct comedi_rangeinfo)
+#define COMEDI_CMD _IOR(CIO, 9, struct comedi_cmd)
+#define COMEDI_CMDTEST _IOR(CIO, 10, struct comedi_cmd)
+#define COMEDI_INSNLIST _IOR(CIO, 11, struct comedi_insnlist)
+#define COMEDI_INSN _IOR(CIO, 12, struct comedi_insn)
+#define COMEDI_BUFCONFIG _IOR(CIO, 13, struct comedi_bufconfig)
+#define COMEDI_BUFINFO _IOWR(CIO, 14, struct comedi_bufinfo)
#define COMEDI_POLL _IO(CIO, 15)
/* structures */
-typedef struct comedi_trig_struct comedi_trig;
-typedef struct comedi_cmd_struct comedi_cmd;
-typedef struct comedi_insn_struct comedi_insn;
-typedef struct comedi_insnlist_struct comedi_insnlist;
-typedef struct comedi_chaninfo_struct comedi_chaninfo;
-typedef struct comedi_subdinfo_struct comedi_subdinfo;
-typedef struct comedi_devinfo_struct comedi_devinfo;
-typedef struct comedi_devconfig_struct comedi_devconfig;
-typedef struct comedi_rangeinfo_struct comedi_rangeinfo;
-typedef struct comedi_krange_struct comedi_krange;
-typedef struct comedi_bufconfig_struct comedi_bufconfig;
-typedef struct comedi_bufinfo_struct comedi_bufinfo;
-
-struct comedi_trig_struct {
+struct comedi_trig {
unsigned int subdev; /* subdevice */
unsigned int mode; /* mode */
unsigned int flags;
unsigned int n_chan; /* number of channels */
unsigned int *chanlist; /* channel/range list */
- sampl_t *data; /* data list, size depends on subd flags */
+ short *data; /* data list, size depends on subd flags */
unsigned int n; /* number of scans */
unsigned int trigsrc;
unsigned int trigvar;
@@ -340,21 +325,21 @@ struct comedi_trig_struct {
unsigned int unused[3];
};
-struct comedi_insn_struct {
+struct comedi_insn {
unsigned int insn;
unsigned int n;
- lsampl_t *data;
+ unsigned int *data;
unsigned int subdev;
unsigned int chanspec;
unsigned int unused[3];
};
-struct comedi_insnlist_struct {
+struct comedi_insnlist {
unsigned int n_insns;
- comedi_insn *insns;
+ struct comedi_insn *insns;
};
-struct comedi_cmd_struct {
+struct comedi_cmd {
unsigned int subdev;
unsigned int flags;
@@ -376,37 +361,37 @@ struct comedi_cmd_struct {
unsigned int *chanlist; /* channel/range list */
unsigned int chanlist_len;
- sampl_t *data; /* data list, size depends on subd flags */
+ short *data; /* data list, size depends on subd flags */
unsigned int data_len;
};
-struct comedi_chaninfo_struct {
+struct comedi_chaninfo {
unsigned int subdev;
- lsampl_t *maxdata_list;
+ unsigned int *maxdata_list;
unsigned int *flaglist;
unsigned int *rangelist;
unsigned int unused[4];
};
-struct comedi_rangeinfo_struct {
+struct comedi_rangeinfo {
unsigned int range_type;
void *range_ptr;
};
-struct comedi_krange_struct {
+struct comedi_krange {
int min; /* fixed point, multiply by 1e-6 */
int max; /* fixed point, multiply by 1e-6 */
unsigned int flags;
};
-struct comedi_subdinfo_struct {
+struct comedi_subdinfo {
unsigned int type;
unsigned int n_chan;
unsigned int subd_flags;
unsigned int timer_type;
unsigned int len_chanlist;
- lsampl_t maxdata;
+ unsigned int maxdata;
unsigned int flags; /* channel flags */
unsigned int range_type; /* lookup in kernel */
unsigned int settling_time_0;
@@ -414,7 +399,7 @@ struct comedi_subdinfo_struct {
unsigned int unused[8];
};
-struct comedi_devinfo_struct {
+struct comedi_devinfo {
unsigned int version_code;
unsigned int n_subdevs;
char driver_name[COMEDI_NAMELEN];
@@ -424,12 +409,12 @@ struct comedi_devinfo_struct {
int unused[30];
};
-struct comedi_devconfig_struct {
+struct comedi_devconfig {
char board_name[COMEDI_NAMELEN];
int options[COMEDI_NDEVCONFOPTS];
};
-struct comedi_bufconfig_struct {
+struct comedi_bufconfig {
unsigned int subdevice;
unsigned int flags;
@@ -439,7 +424,7 @@ struct comedi_bufconfig_struct {
unsigned int unused[4];
};
-struct comedi_bufinfo_struct {
+struct comedi_bufinfo {
unsigned int subdevice;
unsigned int bytes_read;
diff --git a/drivers/staging/comedi/comedi_compat32.c b/drivers/staging/comedi/comedi_compat32.c
index 7d0116bcb9f..1b9c2a7c824 100644
--- a/drivers/staging/comedi/comedi_compat32.c
+++ b/drivers/staging/comedi/comedi_compat32.c
@@ -37,31 +37,31 @@
#include <linux/ioctl32.h> /* for (un)register_ioctl32_conversion */
#endif
-#define COMEDI32_CHANINFO _IOR(CIO,3,comedi32_chaninfo)
-#define COMEDI32_RANGEINFO _IOR(CIO,8,comedi32_rangeinfo)
+#define COMEDI32_CHANINFO _IOR(CIO, 3, struct comedi32_chaninfo_struct)
+#define COMEDI32_RANGEINFO _IOR(CIO, 8, struct comedi32_rangeinfo_struct)
/* N.B. COMEDI32_CMD and COMEDI_CMD ought to use _IOWR, not _IOR.
* It's too late to change it now, but it only affects the command number. */
-#define COMEDI32_CMD _IOR(CIO,9,comedi32_cmd)
+#define COMEDI32_CMD _IOR(CIO, 9, struct comedi32_cmd_struct)
/* N.B. COMEDI32_CMDTEST and COMEDI_CMDTEST ought to use _IOWR, not _IOR.
* It's too late to change it now, but it only affects the command number. */
-#define COMEDI32_CMDTEST _IOR(CIO,10,comedi32_cmd)
-#define COMEDI32_INSNLIST _IOR(CIO,11,comedi32_insnlist)
-#define COMEDI32_INSN _IOR(CIO,12,comedi32_insn)
+#define COMEDI32_CMDTEST _IOR(CIO, 10, struct comedi32_cmd_struct)
+#define COMEDI32_INSNLIST _IOR(CIO, 11, struct comedi32_insnlist_struct)
+#define COMEDI32_INSN _IOR(CIO, 12, struct comedi32_insn_struct)
-typedef struct comedi32_chaninfo_struct {
+struct comedi32_chaninfo_struct {
unsigned int subdev;
- compat_uptr_t maxdata_list; /* 32-bit 'lsampl_t *' */
+ compat_uptr_t maxdata_list; /* 32-bit 'unsigned int *' */
compat_uptr_t flaglist; /* 32-bit 'unsigned int *' */
compat_uptr_t rangelist; /* 32-bit 'unsigned int *' */
unsigned int unused[4];
-} comedi32_chaninfo;
+};
-typedef struct comedi32_rangeinfo_struct {
+struct comedi32_rangeinfo_struct {
unsigned int range_type;
compat_uptr_t range_ptr; /* 32-bit 'void *' */
-} comedi32_rangeinfo;
+};
-typedef struct comedi32_cmd_struct {
+struct comedi32_cmd_struct {
unsigned int subdev;
unsigned int flags;
unsigned int start_src;
@@ -76,37 +76,36 @@ typedef struct comedi32_cmd_struct {
unsigned int stop_arg;
compat_uptr_t chanlist; /* 32-bit 'unsigned int *' */
unsigned int chanlist_len;
- compat_uptr_t data; /* 32-bit 'sampl_t *' */
+ compat_uptr_t data; /* 32-bit 'short *' */
unsigned int data_len;
-} comedi32_cmd;
+};
-typedef struct comedi32_insn_struct {
+struct comedi32_insn_struct {
unsigned int insn;
unsigned int n;
- compat_uptr_t data; /* 32-bit 'lsampl_t *' */
+ compat_uptr_t data; /* 32-bit 'unsigned int *' */
unsigned int subdev;
unsigned int chanspec;
unsigned int unused[3];
-} comedi32_insn;
+};
-typedef struct comedi32_insnlist_struct {
+struct comedi32_insnlist_struct {
unsigned int n_insns;
- compat_uptr_t insns; /* 32-bit 'comedi_insn *' */
-} comedi32_insnlist;
+ compat_uptr_t insns; /* 32-bit 'struct comedi_insn *' */
+};
/* Handle translated ioctl. */
static int translated_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
- if (!file->f_op) {
+ if (!file->f_op)
return -ENOTTY;
- }
+
#ifdef HAVE_UNLOCKED_IOCTL
if (file->f_op->unlocked_ioctl) {
int rc = (int)(*file->f_op->unlocked_ioctl)(file, cmd, arg);
- if (rc == -ENOIOCTLCMD) {
+ if (rc == -ENOIOCTLCMD)
rc = -ENOTTY;
- }
return rc;
}
#endif
@@ -124,8 +123,8 @@ static int translated_ioctl(struct file *file, unsigned int cmd,
/* Handle 32-bit COMEDI_CHANINFO ioctl. */
static int compat_chaninfo(struct file *file, unsigned long arg)
{
- comedi_chaninfo __user *chaninfo;
- comedi32_chaninfo __user *chaninfo32;
+ struct comedi_chaninfo __user *chaninfo;
+ struct comedi32_chaninfo_struct __user *chaninfo32;
int err;
union {
unsigned int uint;
@@ -150,9 +149,8 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
err |= __put_user(compat_ptr(temp.uptr), &chaninfo->flaglist);
err |= __get_user(temp.uptr, &chaninfo32->rangelist);
err |= __put_user(compat_ptr(temp.uptr), &chaninfo->rangelist);
- if (err) {
+ if (err)
return -EFAULT;
- }
return translated_ioctl(file, COMEDI_CHANINFO, (unsigned long)chaninfo);
}
@@ -160,8 +158,8 @@ static int compat_chaninfo(struct file *file, unsigned long arg)
/* Handle 32-bit COMEDI_RANGEINFO ioctl. */
static int compat_rangeinfo(struct file *file, unsigned long arg)
{
- comedi_rangeinfo __user *rangeinfo;
- comedi32_rangeinfo __user *rangeinfo32;
+ struct comedi_rangeinfo __user *rangeinfo;
+ struct comedi32_rangeinfo_struct __user *rangeinfo32;
int err;
union {
unsigned int uint;
@@ -182,17 +180,16 @@ static int compat_rangeinfo(struct file *file, unsigned long arg)
err |= __put_user(temp.uint, &rangeinfo->range_type);
err |= __get_user(temp.uptr, &rangeinfo32->range_ptr);
err |= __put_user(compat_ptr(temp.uptr), &rangeinfo->range_ptr);
- if (err) {
+ if (err)
return -EFAULT;
- }
return translated_ioctl(file, COMEDI_RANGEINFO,
(unsigned long)rangeinfo);
}
/* Copy 32-bit cmd structure to native cmd structure. */
-static int get_compat_cmd(comedi_cmd __user *cmd,
- comedi32_cmd __user *cmd32)
+static int get_compat_cmd(struct comedi_cmd __user *cmd,
+ struct comedi32_cmd_struct __user *cmd32)
{
int err;
union {
@@ -242,7 +239,7 @@ static int get_compat_cmd(comedi_cmd __user *cmd,
}
/* Copy native cmd structure to 32-bit cmd structure. */
-static int put_compat_cmd(comedi32_cmd __user *cmd32, comedi_cmd __user *cmd)
+static int put_compat_cmd(struct comedi32_cmd_struct __user *cmd32, struct comedi_cmd __user *cmd)
{
int err;
unsigned int temp;
@@ -292,17 +289,16 @@ static int put_compat_cmd(comedi32_cmd __user *cmd32, comedi_cmd __user *cmd)
/* Handle 32-bit COMEDI_CMD ioctl. */
static int compat_cmd(struct file *file, unsigned long arg)
{
- comedi_cmd __user *cmd;
- comedi32_cmd __user *cmd32;
+ struct comedi_cmd __user *cmd;
+ struct comedi32_cmd_struct __user *cmd32;
int rc;
cmd32 = compat_ptr(arg);
cmd = compat_alloc_user_space(sizeof(*cmd));
rc = get_compat_cmd(cmd, cmd32);
- if (rc) {
+ if (rc)
return rc;
- }
return translated_ioctl(file, COMEDI_CMD, (unsigned long)cmd);
}
@@ -310,33 +306,31 @@ static int compat_cmd(struct file *file, unsigned long arg)
/* Handle 32-bit COMEDI_CMDTEST ioctl. */
static int compat_cmdtest(struct file *file, unsigned long arg)
{
- comedi_cmd __user *cmd;
- comedi32_cmd __user *cmd32;
+ struct comedi_cmd __user *cmd;
+ struct comedi32_cmd_struct __user *cmd32;
int rc, err;
cmd32 = compat_ptr(arg);
cmd = compat_alloc_user_space(sizeof(*cmd));
rc = get_compat_cmd(cmd, cmd32);
- if (rc) {
+ if (rc)
return rc;
- }
rc = translated_ioctl(file, COMEDI_CMDTEST, (unsigned long)cmd);
- if (rc < 0) {
+ if (rc < 0)
return rc;
- }
err = put_compat_cmd(cmd32, cmd);
- if (err) {
+ if (err)
rc = err;
- }
+
return rc;
}
/* Copy 32-bit insn structure to native insn structure. */
-static int get_compat_insn(comedi_insn __user *insn,
- comedi32_insn __user *insn32)
+static int get_compat_insn(struct comedi_insn __user *insn,
+ struct comedi32_insn_struct __user *insn32)
{
int err;
union {
@@ -347,9 +341,9 @@ static int get_compat_insn(comedi_insn __user *insn,
/* Copy insn structure. Ignore the unused members. */
err = 0;
if (!access_ok(VERIFY_READ, insn32, sizeof(*insn32))
- || !access_ok(VERIFY_WRITE, insn, sizeof(*insn))) {
+ || !access_ok(VERIFY_WRITE, insn, sizeof(*insn)))
return -EFAULT;
- }
+
err |= __get_user(temp.uint, &insn32->insn);
err |= __put_user(temp.uint, &insn->insn);
err |= __get_user(temp.uint, &insn32->n);
@@ -367,11 +361,11 @@ static int get_compat_insn(comedi_insn __user *insn,
static int compat_insnlist(struct file *file, unsigned long arg)
{
struct combined_insnlist {
- comedi_insnlist insnlist;
- comedi_insn insn[1];
+ struct comedi_insnlist insnlist;
+ struct comedi_insn insn[1];
} __user *s;
- comedi32_insnlist __user *insnlist32;
- comedi32_insn __user *insn32;
+ struct comedi32_insnlist_struct __user *insnlist32;
+ struct comedi32_insn_struct __user *insn32;
compat_uptr_t uptr;
unsigned int n_insns, n;
int err, rc;
@@ -386,9 +380,8 @@ static int compat_insnlist(struct file *file, unsigned long arg)
err |= __get_user(n_insns, &insnlist32->n_insns);
err |= __get_user(uptr, &insnlist32->insns);
insn32 = compat_ptr(uptr);
- if (err) {
+ if (err)
return -EFAULT;
- }
/* Allocate user memory to copy insnlist and insns into. */
s = compat_alloc_user_space(offsetof(struct combined_insnlist,
@@ -400,16 +393,14 @@ static int compat_insnlist(struct file *file, unsigned long arg)
}
err |= __put_user(n_insns, &s->insnlist.n_insns);
err |= __put_user(&s->insn[0], &s->insnlist.insns);
- if (err) {
+ if (err)
return -EFAULT;
- }
/* Copy insn structures. */
for (n = 0; n < n_insns; n++) {
rc = get_compat_insn(&s->insn[n], &insn32[n]);
- if (rc) {
+ if (rc)
return rc;
- }
}
return translated_ioctl(file, COMEDI_INSNLIST,
@@ -419,17 +410,16 @@ static int compat_insnlist(struct file *file, unsigned long arg)
/* Handle 32-bit COMEDI_INSN ioctl. */
static int compat_insn(struct file *file, unsigned long arg)
{
- comedi_insn __user *insn;
- comedi32_insn __user *insn32;
+ struct comedi_insn __user *insn;
+ struct comedi32_insn_struct __user *insn32;
int rc;
insn32 = compat_ptr(arg);
insn = compat_alloc_user_space(sizeof(*insn));
rc = get_compat_insn(insn, insn32);
- if (rc) {
+ if (rc)
return rc;
- }
return translated_ioctl(file, COMEDI_INSN, (unsigned long)insn);
}
@@ -512,14 +502,14 @@ static int mapped_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg,
int rc;
/* Make sure we are dealing with a Comedi device. */
- if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR) {
+ if (imajor(file->f_dentry->d_inode) != COMEDI_MAJOR)
return -ENOTTY;
- }
+
rc = raw_ioctl(file, cmd, arg);
/* Do not return -ENOIOCTLCMD. */
- if (rc == -ENOIOCTLCMD) {
+ if (rc == -ENOIOCTLCMD)
rc = -ENOTTY;
- }
+
return rc;
}
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 018c964396d..19dce2ebfc1 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -59,33 +59,39 @@ int comedi_debug;
module_param(comedi_debug, int, 0644);
#endif
+int comedi_autoconfig = 1;
+module_param(comedi_autoconfig, bool, 0444);
+
+int comedi_num_legacy_minors = 0;
+module_param(comedi_num_legacy_minors, int, 0444);
+
static DEFINE_SPINLOCK(comedi_file_info_table_lock);
static struct comedi_device_file_info
*comedi_file_info_table[COMEDI_NUM_MINORS];
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg);
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg);
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg);
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg);
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
struct file *file);
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
void *file);
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg);
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg);
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file);
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file);
-static int do_poll_ioctl(comedi_device *dev, unsigned int subd, void *file);
-
-extern void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s);
-static int do_cancel(comedi_device *dev, comedi_subdevice *s);
+static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg);
+static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg);
+static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file);
+static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file);
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file);
+
+extern void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s);
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
static int comedi_fasync(int fd, struct file *file, int on);
-static int is_device_busy(comedi_device *dev);
+static int is_device_busy(struct comedi_device *dev);
#ifdef HAVE_UNLOCKED_IOCTL
static long comedi_unlocked_ioctl(struct file *file, unsigned int cmd,
@@ -98,9 +104,13 @@ static int comedi_ioctl(struct inode *inode, struct file *file,
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev;
int rc;
+ if (dev_file_info == NULL || dev_file_info->device == NULL)
+ return -ENODEV;
+ dev = dev_file_info->device;
+
mutex_lock(&dev->mutex);
/* Device config is special, because it must work on
@@ -182,9 +192,9 @@ done:
writes:
none
*/
-static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
+static int do_devconfig_ioctl(struct comedi_device *dev, struct comedi_devconfig *arg)
{
- comedi_devconfig it;
+ struct comedi_devconfig it;
int ret;
unsigned char *aux_data = NULL;
int aux_len;
@@ -203,7 +213,7 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
return 0;
}
- if (copy_from_user(&it, arg, sizeof(comedi_devconfig)))
+ if (copy_from_user(&it, arg, sizeof(struct comedi_devconfig)))
return -EFAULT;
it.board_name[COMEDI_NAMELEN - 1] = 0;
@@ -262,14 +272,14 @@ static int do_devconfig_ioctl(comedi_device *dev, comedi_devconfig *arg)
modified bufconfig at arg
*/
-static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
+static int do_bufconfig_ioctl(struct comedi_device *dev, void *arg)
{
- comedi_bufconfig bc;
- comedi_async *async;
- comedi_subdevice *s;
+ struct comedi_bufconfig bc;
+ struct comedi_async *async;
+ struct comedi_subdevice *s;
int ret = 0;
- if (copy_from_user(&bc, arg, sizeof(comedi_bufconfig)))
+ if (copy_from_user(&bc, arg, sizeof(struct comedi_bufconfig)))
return -EFAULT;
if (bc.subdevice >= dev->n_subdevices || bc.subdevice < 0)
@@ -330,7 +340,7 @@ static int do_bufconfig_ioctl(comedi_device *dev, void *arg)
bc.maximum_size = async->max_bufsize;
copyback:
- if (copy_to_user(arg, &bc, sizeof(comedi_bufconfig)))
+ if (copy_to_user(arg, &bc, sizeof(struct comedi_bufconfig)))
return -EFAULT;
return 0;
@@ -350,16 +360,16 @@ copyback:
devinfo structure
*/
-static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
+static int do_devinfo_ioctl(struct comedi_device *dev, struct comedi_devinfo *arg,
struct file *file)
{
- comedi_devinfo devinfo;
+ struct comedi_devinfo devinfo;
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_subdevice *read_subdev =
+ struct comedi_subdevice *read_subdev =
comedi_get_read_subdevice(dev_file_info);
- comedi_subdevice *write_subdev =
+ struct comedi_subdevice *write_subdev =
comedi_get_write_subdevice(dev_file_info);
memset(&devinfo, 0, sizeof(devinfo));
@@ -380,7 +390,7 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
else
devinfo.write_subdevice = -1;
- if (copy_to_user(arg, &devinfo, sizeof(comedi_devinfo)))
+ if (copy_to_user(arg, &devinfo, sizeof(struct comedi_devinfo)))
return -EFAULT;
return 0;
@@ -400,14 +410,14 @@ static int do_devinfo_ioctl(comedi_device *dev, comedi_devinfo *arg,
array of subdevice info structures at arg
*/
-static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
+static int do_subdinfo_ioctl(struct comedi_device *dev, struct comedi_subdinfo *arg,
void *file)
{
int ret, i;
- comedi_subdinfo *tmp, *us;
- comedi_subdevice *s;
+ struct comedi_subdinfo *tmp, *us;
+ struct comedi_subdevice *s;
- tmp = kcalloc(dev->n_subdevices, sizeof(comedi_subdinfo), GFP_KERNEL);
+ tmp = kcalloc(dev->n_subdevices, sizeof(struct comedi_subdinfo), GFP_KERNEL);
if (!tmp)
return -ENOMEM;
@@ -459,7 +469,7 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
}
ret = copy_to_user(arg, tmp,
- dev->n_subdevices * sizeof(comedi_subdinfo));
+ dev->n_subdevices * sizeof(struct comedi_subdinfo));
kfree(tmp);
@@ -480,12 +490,12 @@ static int do_subdinfo_ioctl(comedi_device *dev, comedi_subdinfo *arg,
arrays at elements of chaninfo structure
*/
-static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
+static int do_chaninfo_ioctl(struct comedi_device *dev, struct comedi_chaninfo *arg)
{
- comedi_subdevice *s;
- comedi_chaninfo it;
+ struct comedi_subdevice *s;
+ struct comedi_chaninfo it;
- if (copy_from_user(&it, arg, sizeof(comedi_chaninfo)))
+ if (copy_from_user(&it, arg, sizeof(struct comedi_chaninfo)))
return -EFAULT;
if (it.subdev >= dev->n_subdevices)
@@ -496,7 +506,7 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
if (s->maxdata || !s->maxdata_list)
return -EINVAL;
if (copy_to_user(it.maxdata_list, s->maxdata_list,
- s->n_chan * sizeof(lsampl_t)))
+ s->n_chan * sizeof(unsigned int)))
return -EFAULT;
}
@@ -544,13 +554,13 @@ static int do_chaninfo_ioctl(comedi_device *dev, comedi_chaninfo *arg)
modified bufinfo at arg
*/
-static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
+static int do_bufinfo_ioctl(struct comedi_device *dev, void *arg)
{
- comedi_bufinfo bi;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_bufinfo bi;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
- if (copy_from_user(&bi, arg, sizeof(comedi_bufinfo)))
+ if (copy_from_user(&bi, arg, sizeof(struct comedi_bufinfo)))
return -EFAULT;
if (bi.subdevice >= dev->n_subdevices || bi.subdevice < 0)
@@ -591,13 +601,13 @@ static int do_bufinfo_ioctl(comedi_device *dev, void *arg)
bi.buf_read_ptr = async->buf_read_ptr;
copyback:
- if (copy_to_user(arg, &bi, sizeof(comedi_bufinfo)))
+ if (copy_to_user(arg, &bi, sizeof(struct comedi_bufinfo)))
return -EFAULT;
return 0;
}
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
void *file);
/*
* COMEDI_INSNLIST
@@ -616,25 +626,25 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
*/
/* arbitrary limits */
#define MAX_SAMPLES 256
-static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insnlist_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_insnlist insnlist;
- comedi_insn *insns = NULL;
- lsampl_t *data = NULL;
+ struct comedi_insnlist insnlist;
+ struct comedi_insn *insns = NULL;
+ unsigned int *data = NULL;
int i = 0;
int ret = 0;
- if (copy_from_user(&insnlist, arg, sizeof(comedi_insnlist)))
+ if (copy_from_user(&insnlist, arg, sizeof(struct comedi_insnlist)))
return -EFAULT;
- data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+ data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
if (!data) {
DPRINTK("kmalloc failed\n");
ret = -ENOMEM;
goto error;
}
- insns = kmalloc(sizeof(comedi_insn) * insnlist.n_insns, GFP_KERNEL);
+ insns = kmalloc(sizeof(struct comedi_insn) * insnlist.n_insns, GFP_KERNEL);
if (!insns) {
DPRINTK("kmalloc failed\n");
ret = -ENOMEM;
@@ -642,7 +652,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
}
if (copy_from_user(insns, insnlist.insns,
- sizeof(comedi_insn) * insnlist.n_insns)) {
+ sizeof(struct comedi_insn) * insnlist.n_insns)) {
DPRINTK("copy_from_user failed\n");
ret = -EFAULT;
goto error;
@@ -656,7 +666,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
}
if (insns[i].insn & INSN_MASK_WRITE) {
if (copy_from_user(data, insns[i].data,
- insns[i].n * sizeof(lsampl_t))) {
+ insns[i].n * sizeof(unsigned int))) {
DPRINTK("copy_from_user failed\n");
ret = -EFAULT;
goto error;
@@ -667,7 +677,7 @@ static int do_insnlist_ioctl(comedi_device *dev, void *arg, void *file)
goto error;
if (insns[i].insn & INSN_MASK_READ) {
if (copy_to_user(insns[i].data, data,
- insns[i].n * sizeof(lsampl_t))) {
+ insns[i].n * sizeof(unsigned int))) {
DPRINTK("copy_to_user failed\n");
ret = -EFAULT;
goto error;
@@ -686,7 +696,7 @@ error:
return i;
}
-static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
+static int check_insn_config_length(struct comedi_insn *insn, unsigned int *data)
{
if (insn->n < 1)
return -EINVAL;
@@ -747,10 +757,10 @@ static int check_insn_config_length(comedi_insn *insn, lsampl_t *data)
return -EINVAL;
}
-static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
+static int parse_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data,
void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int ret = 0;
int i;
@@ -815,7 +825,7 @@ static int parse_insn(comedi_device *dev, comedi_insn *insn, lsampl_t *data,
}
} else {
/* a subdevice instruction */
- lsampl_t maxdata;
+ unsigned int maxdata;
if (insn->subdev >= dev->n_subdevices) {
DPRINTK("subdevice %d out of range\n", insn->subdev);
@@ -901,25 +911,25 @@ out:
* pointer to insn
*
* reads:
- * comedi_insn struct at arg
+ * struct comedi_insn struct at arg
* data (for writes)
*
* writes:
* data (for reads)
*/
-static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_insn_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_insn insn;
- lsampl_t *data = NULL;
+ struct comedi_insn insn;
+ unsigned int *data = NULL;
int ret = 0;
- data = kmalloc(sizeof(lsampl_t) * MAX_SAMPLES, GFP_KERNEL);
+ data = kmalloc(sizeof(unsigned int) * MAX_SAMPLES, GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto error;
}
- if (copy_from_user(&insn, arg, sizeof(comedi_insn))) {
+ if (copy_from_user(&insn, arg, sizeof(struct comedi_insn))) {
ret = -EFAULT;
goto error;
}
@@ -928,7 +938,7 @@ static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
if (insn.n > MAX_SAMPLES)
insn.n = MAX_SAMPLES;
if (insn.insn & INSN_MASK_WRITE) {
- if (copy_from_user(data, insn.data, insn.n * sizeof(lsampl_t))) {
+ if (copy_from_user(data, insn.data, insn.n * sizeof(unsigned int))) {
ret = -EFAULT;
goto error;
}
@@ -937,7 +947,7 @@ static int do_insn_ioctl(comedi_device *dev, void *arg, void *file)
if (ret < 0)
goto error;
if (insn.insn & INSN_MASK_READ) {
- if (copy_to_user(insn.data, data, insn.n * sizeof(lsampl_t))) {
+ if (copy_to_user(insn.data, data, insn.n * sizeof(unsigned int))) {
ret = -EFAULT;
goto error;
}
@@ -965,15 +975,15 @@ error:
modified cmd structure at arg
*/
-static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmd_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_cmd user_cmd;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_cmd user_cmd;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
int ret = 0;
unsigned int *chanlist_saver = NULL;
- if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+ if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
DPRINTK("bad cmd address\n");
return -EFAULT;
}
@@ -1062,7 +1072,7 @@ static int do_cmd_ioctl(comedi_device *dev, void *arg, void *file)
/* restore chanlist pointer before copying back */
user_cmd.chanlist = chanlist_saver;
user_cmd.data = NULL;
- if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
+ if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
DPRINTK("fault writing cmd\n");
ret = -EFAULT;
goto cleanup;
@@ -1119,15 +1129,15 @@ cleanup:
modified cmd structure at arg
*/
-static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
+static int do_cmdtest_ioctl(struct comedi_device *dev, void *arg, void *file)
{
- comedi_cmd user_cmd;
- comedi_subdevice *s;
+ struct comedi_cmd user_cmd;
+ struct comedi_subdevice *s;
int ret = 0;
unsigned int *chanlist = NULL;
unsigned int *chanlist_saver = NULL;
- if (copy_from_user(&user_cmd, arg, sizeof(comedi_cmd))) {
+ if (copy_from_user(&user_cmd, arg, sizeof(struct comedi_cmd))) {
DPRINTK("bad cmd address\n");
return -EFAULT;
}
@@ -1191,7 +1201,7 @@ static int do_cmdtest_ioctl(comedi_device *dev, void *arg, void *file)
/* restore chanlist pointer before copying back */
user_cmd.chanlist = chanlist_saver;
- if (copy_to_user(arg, &user_cmd, sizeof(comedi_cmd))) {
+ if (copy_to_user(arg, &user_cmd, sizeof(struct comedi_cmd))) {
DPRINTK("bad cmd address\n");
ret = -EFAULT;
goto cleanup;
@@ -1217,11 +1227,11 @@ cleanup:
*/
-static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_lock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
int ret = 0;
unsigned long flags;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1261,9 +1271,9 @@ static int do_lock_ioctl(comedi_device *dev, unsigned int arg, void *file)
This function isn't protected by the semaphore, since
we already own the lock.
*/
-static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_unlock_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1301,9 +1311,9 @@ static int do_unlock_ioctl(comedi_device *dev, unsigned int arg, void *file)
nothing
*/
-static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_cancel_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1337,9 +1347,9 @@ static int do_cancel_ioctl(comedi_device *dev, unsigned int arg, void *file)
nothing
*/
-static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
+static int do_poll_ioctl(struct comedi_device *dev, unsigned int arg, void *file)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (arg >= dev->n_subdevices)
return -EINVAL;
@@ -1360,7 +1370,7 @@ static int do_poll_ioctl(comedi_device *dev, unsigned int arg, void *file)
return -EINVAL;
}
-static int do_cancel(comedi_device *dev, comedi_subdevice *s)
+static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
int ret = 0;
@@ -1374,8 +1384,8 @@ static int do_cancel(comedi_device *dev, comedi_subdevice *s)
void comedi_unmap(struct vm_area_struct *area)
{
- comedi_async *async;
- comedi_device *dev;
+ struct comedi_async *async;
+ struct comedi_device *dev;
async = area->vm_private_data;
dev = async->subdevice->device;
@@ -1394,14 +1404,14 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
- comedi_async *async = NULL;
+ struct comedi_device *dev = dev_file_info->device;
+ struct comedi_async *async = NULL;
unsigned long start = vma->vm_start;
unsigned long size;
int n_pages;
int i;
int retval;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
mutex_lock(&dev->mutex);
if (!dev->attached) {
@@ -1470,9 +1480,9 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
- comedi_subdevice *read_subdev;
- comedi_subdevice *write_subdev;
+ struct comedi_device *dev = dev_file_info->device;
+ struct comedi_subdevice *read_subdev;
+ struct comedi_subdevice *write_subdev;
mutex_lock(&dev->mutex);
if (!dev->attached) {
@@ -1513,14 +1523,14 @@ static unsigned int comedi_poll(struct file *file, poll_table *wait)
static ssize_t comedi_write(struct file *file, const char *buf, size_t nbytes,
loff_t *offset)
{
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
int n, m, count = 0, retval = 0;
DECLARE_WAITQUEUE(wait, current);
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info->device;
if (!dev->attached) {
DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1615,14 +1625,14 @@ done:
static ssize_t comedi_read(struct file *file, char *buf, size_t nbytes,
loff_t *offset)
{
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
int n, m, count = 0, retval = 0;
DECLARE_WAITQUEUE(wait, current);
const unsigned minor = iminor(file->f_dentry->d_inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info->device;
if (!dev->attached) {
DPRINTK("no driver configured on comedi%i\n", dev->minor);
@@ -1723,9 +1733,9 @@ done:
/*
This function restores a subdevice to an idle state.
*/
-void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
+void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_async *async = s->async;
+ struct comedi_async *async = s->async;
comedi_set_subdevice_runflags(s, SRF_RUNNING, 0);
#ifdef CONFIG_COMEDI_RT
@@ -1747,11 +1757,11 @@ void do_become_nonbusy(comedi_device *dev, comedi_subdevice *s)
static int comedi_open(struct inode *inode, struct file *file)
{
- char mod[32];
const unsigned minor = iminor(inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info ? dev_file_info->device : NULL;
+
if (dev == NULL) {
DPRINTK("invalid minor number\n");
return -ENODEV;
@@ -1783,10 +1793,9 @@ static int comedi_open(struct inode *inode, struct file *file)
dev->in_request_module = 1;
- sprintf(mod, "char-major-%i-%i", COMEDI_MAJOR, dev->minor);
#ifdef CONFIG_KMOD
mutex_unlock(&dev->mutex);
- request_module(mod);
+ request_module("char-major-%i-%i", COMEDI_MAJOR, dev->minor);
mutex_lock(&dev->mutex);
#endif
@@ -1823,8 +1832,8 @@ static int comedi_close(struct inode *inode, struct file *file)
const unsigned minor = iminor(inode);
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
- comedi_subdevice *s = NULL;
+ struct comedi_device *dev = dev_file_info->device;
+ struct comedi_subdevice *s = NULL;
int i;
mutex_lock(&dev->mutex);
@@ -1862,7 +1871,7 @@ static int comedi_fasync(int fd, struct file *file, int on)
struct comedi_device_file_info *dev_file_info =
comedi_get_device_file_info(minor);
- comedi_device *dev = dev_file_info->device;
+ struct comedi_device *dev = dev_file_info->device;
return fasync_helper(fd, file, on, &dev->async_queue);
}
@@ -1893,7 +1902,7 @@ static void comedi_cleanup_legacy_minors(void)
{
unsigned i;
- for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++)
+ for (i = 0; i < comedi_num_legacy_minors; i++)
comedi_free_board_minor(i);
}
@@ -1905,6 +1914,22 @@ static int __init comedi_init(void)
printk(KERN_INFO "comedi: version " COMEDI_RELEASE
" - http://www.comedi.org\n");
+ if (comedi_num_legacy_minors < 0 ||
+ comedi_num_legacy_minors > COMEDI_NUM_BOARD_MINORS) {
+ printk(KERN_ERR "comedi: error: invalid value for module "
+ "parameter \"comedi_num_legacy_minors\". Valid values "
+ "are 0 through %i.\n", COMEDI_NUM_BOARD_MINORS);
+ return -EINVAL;
+ }
+
+ /*
+ * comedi is unusable if both comedi_autoconfig and
+ * comedi_num_legacy_minors are zero, so we might as well adjust the
+ * defaults in that case
+ */
+ if (comedi_autoconfig == 0 && comedi_num_legacy_minors == 0)
+ comedi_num_legacy_minors = 16;
+
memset(comedi_file_info_table, 0,
sizeof(struct comedi_device_file_info *) * COMEDI_NUM_MINORS);
@@ -1933,7 +1958,7 @@ static int __init comedi_init(void)
comedi_proc_init();
/* create devices files for legacy/manual use */
- for (i = 0; i < COMEDI_NUM_LEGACY_MINORS; i++) {
+ for (i = 0; i < comedi_num_legacy_minors; i++) {
int minor;
minor = comedi_alloc_board_minor(NULL);
if (minor < 0) {
@@ -1975,15 +2000,15 @@ static void __exit comedi_cleanup(void)
module_init(comedi_init);
module_exit(comedi_cleanup);
-void comedi_error(const comedi_device *dev, const char *s)
+void comedi_error(const struct comedi_device *dev, const char *s)
{
rt_printk("comedi%d: %s: %s\n", dev->minor, dev->driver->driver_name,
s);
}
-void comedi_event(comedi_device *dev, comedi_subdevice *s)
+void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_async *async = s->async;
+ struct comedi_async *async = s->async;
unsigned runflags = 0;
unsigned runflags_mask = 0;
@@ -2042,7 +2067,7 @@ void comedi_event(comedi_device *dev, comedi_subdevice *s)
s->async->events = 0;
}
-void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
+void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
unsigned bits)
{
unsigned long flags;
@@ -2053,7 +2078,7 @@ void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
comedi_spin_unlock_irqrestore(&s->spin_lock, flags);
}
-unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
+unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s)
{
unsigned long flags;
unsigned runflags;
@@ -2064,9 +2089,9 @@ unsigned comedi_get_subdevice_runflags(comedi_subdevice *s)
return runflags;
}
-static int is_device_busy(comedi_device *dev)
+static int is_device_busy(struct comedi_device *dev)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int i;
if (!dev->attached)
@@ -2083,15 +2108,15 @@ static int is_device_busy(comedi_device *dev)
return 0;
}
-void comedi_device_init(comedi_device *dev)
+void comedi_device_init(struct comedi_device *dev)
{
- memset(dev, 0, sizeof(comedi_device));
+ memset(dev, 0, sizeof(struct comedi_device));
spin_lock_init(&dev->spinlock);
mutex_init(&dev->mutex);
dev->minor = -1;
}
-void comedi_device_cleanup(comedi_device *dev)
+void comedi_device_cleanup(struct comedi_device *dev)
{
if (dev == NULL)
return;
@@ -2105,13 +2130,13 @@ int comedi_alloc_board_minor(struct device *hardware_device)
{
unsigned long flags;
struct comedi_device_file_info *info;
- device_create_result_type *csdev;
+ struct device *csdev;
unsigned i;
info = kzalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
if (info == NULL)
return -ENOMEM;
- info->device = kzalloc(sizeof(comedi_device), GFP_KERNEL);
+ info->device = kzalloc(sizeof(struct comedi_device), GFP_KERNEL);
if (info->device == NULL) {
kfree(info);
return -ENOMEM;
@@ -2155,7 +2180,7 @@ void comedi_free_board_minor(unsigned minor)
comedi_spin_unlock_irqrestore(&comedi_file_info_table_lock, flags);
if (info) {
- comedi_device *dev = info->device;
+ struct comedi_device *dev = info->device;
if (dev) {
if (dev->class_dev) {
device_destroy(comedi_class,
@@ -2168,11 +2193,11 @@ void comedi_free_board_minor(unsigned minor)
}
}
-int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
+int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s)
{
unsigned long flags;
struct comedi_device_file_info *info;
- device_create_result_type *csdev;
+ struct device *csdev;
unsigned i;
info = kmalloc(sizeof(struct comedi_device_file_info), GFP_KERNEL);
@@ -2182,7 +2207,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
info->read_subdevice = s;
info->write_subdevice = s;
comedi_spin_lock_irqsave(&comedi_file_info_table_lock, flags);
- for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_BOARD_MINORS; ++i) {
+ for (i = COMEDI_FIRST_SUBDEVICE_MINOR; i < COMEDI_NUM_MINORS; ++i) {
if (comedi_file_info_table[i] == NULL) {
comedi_file_info_table[i] = info;
break;
@@ -2206,7 +2231,7 @@ int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s)
return i;
}
-void comedi_free_subdevice_minor(comedi_subdevice *s)
+void comedi_free_subdevice_minor(struct comedi_subdevice *s)
{
unsigned long flags;
struct comedi_device_file_info *info;
diff --git a/drivers/staging/comedi/comedi_fops.h b/drivers/staging/comedi/comedi_fops.h
index 63f8df558e8..cb503c88c7f 100644
--- a/drivers/staging/comedi/comedi_fops.h
+++ b/drivers/staging/comedi/comedi_fops.h
@@ -4,5 +4,6 @@
extern struct class *comedi_class;
extern const struct file_operations comedi_fops;
+extern int comedi_autoconfig;
#endif /* _COMEDI_FOPS_H */
diff --git a/drivers/staging/comedi/comedi_ksyms.c b/drivers/staging/comedi/comedi_ksyms.c
index 90d57282efb..6e6fb979ef5 100644
--- a/drivers/staging/comedi/comedi_ksyms.c
+++ b/drivers/staging/comedi/comedi_ksyms.c
@@ -31,12 +31,12 @@
/* for drivers */
EXPORT_SYMBOL(comedi_driver_register);
EXPORT_SYMBOL(comedi_driver_unregister);
-//EXPORT_SYMBOL(comedi_bufcheck);
-//EXPORT_SYMBOL(comedi_done);
-//EXPORT_SYMBOL(comedi_error_done);
+/* EXPORT_SYMBOL(comedi_bufcheck); */
+/* EXPORT_SYMBOL(comedi_done); */
+/* EXPORT_SYMBOL(comedi_error_done); */
EXPORT_SYMBOL(comedi_error);
-//EXPORT_SYMBOL(comedi_eobuf);
-//EXPORT_SYMBOL(comedi_eos);
+/* EXPORT_SYMBOL(comedi_eobuf); */
+/* EXPORT_SYMBOL(comedi_eos); */
EXPORT_SYMBOL(comedi_event);
EXPORT_SYMBOL(comedi_get_subdevice_runflags);
EXPORT_SYMBOL(comedi_set_subdevice_runflags);
@@ -60,6 +60,8 @@ EXPORT_SYMBOL_GPL(comedi_alloc_board_minor);
EXPORT_SYMBOL_GPL(comedi_free_board_minor);
EXPORT_SYMBOL_GPL(comedi_pci_auto_config);
EXPORT_SYMBOL_GPL(comedi_pci_auto_unconfig);
+EXPORT_SYMBOL_GPL(comedi_usb_auto_config);
+EXPORT_SYMBOL_GPL(comedi_usb_auto_unconfig);
/* for kcomedilib */
EXPORT_SYMBOL(check_chanlist);
diff --git a/drivers/staging/comedi/comedi_rt.h b/drivers/staging/comedi/comedi_rt.h
index 61852bf5adc..169ca963312 100644
--- a/drivers/staging/comedi/comedi_rt.h
+++ b/drivers/staging/comedi/comedi_rt.h
@@ -28,7 +28,6 @@
#error comedi_rt.h should only be included by comedidev.h
#endif
-#include <linux/version.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/errno.h>
@@ -59,12 +58,12 @@
int comedi_request_irq(unsigned int irq, irqreturn_t(*handler) (int,
void *PT_REGS_ARG), unsigned long flags, const char *device,
- comedi_device *dev_id);
-void comedi_free_irq(unsigned int irq, comedi_device *dev_id);
+ struct comedi_device *dev_id);
+void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id);
void comedi_rt_init(void);
void comedi_rt_cleanup(void);
-int comedi_switch_to_rt(comedi_device *dev);
-void comedi_switch_to_non_rt(comedi_device *dev);
+int comedi_switch_to_rt(struct comedi_device *dev);
+void comedi_switch_to_non_rt(struct comedi_device *dev);
void comedi_rt_pend_wakeup(wait_queue_head_t *q);
extern int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1,
void *arg2);
diff --git a/drivers/staging/comedi/comedidev.h b/drivers/staging/comedi/comedidev.h
index 3735355d3c5..ea319360ae6 100644
--- a/drivers/staging/comedi/comedidev.h
+++ b/drivers/staging/comedi/comedidev.h
@@ -26,7 +26,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/version.h>
#include <linux/kdev_t.h>
#include <linux/slab.h>
#include <linux/errno.h>
@@ -36,7 +35,6 @@
#include <linux/mm.h>
#include <linux/init.h>
#include <linux/vmalloc.h>
-#include <linux/mm.h>
#include "interrupt.h"
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
@@ -55,9 +53,9 @@
#define COMEDI_INITCLEANUP_NOMODULE(x) \
static int __init x ## _init_module(void) \
- {return comedi_driver_register(&(x));} \
+ {return comedi_driver_register(&(x)); } \
static void __exit x ## _cleanup_module(void) \
- {comedi_driver_unregister(&(x));} \
+ {comedi_driver_unregister(&(x)); } \
module_init(x ## _init_module); \
module_exit(x ## _cleanup_module); \
@@ -120,23 +118,14 @@
#define PCI_VENDOR_ID_MEILHAUS 0x1402
#define COMEDI_NUM_MINORS 0x100
-#define COMEDI_NUM_LEGACY_MINORS 0x10
#define COMEDI_NUM_BOARD_MINORS 0x30
#define COMEDI_FIRST_SUBDEVICE_MINOR COMEDI_NUM_BOARD_MINORS
-typedef struct comedi_device_struct comedi_device;
-typedef struct comedi_subdevice_struct comedi_subdevice;
-typedef struct comedi_async_struct comedi_async;
-typedef struct comedi_driver_struct comedi_driver;
-typedef struct comedi_lrange_struct comedi_lrange;
-
-typedef struct device device_create_result_type;
-
#define COMEDI_DEVICE_CREATE(cs, parent, devt, drvdata, device, fmt...) \
device_create(cs, ((parent) ? (parent) : (device)), devt, drvdata, fmt)
-struct comedi_subdevice_struct {
- comedi_device *device;
+struct comedi_subdevice {
+ struct comedi_device *device;
int type;
int n_chan;
volatile int subdev_flags;
@@ -144,7 +133,7 @@ struct comedi_subdevice_struct {
void *private;
- comedi_async *async;
+ struct comedi_async *async;
void *lock;
void *busy;
@@ -153,46 +142,46 @@ struct comedi_subdevice_struct {
int io_bits;
- lsampl_t maxdata; /* if maxdata==0, use list */
- const lsampl_t *maxdata_list; /* list is channel specific */
+ unsigned int maxdata; /* if maxdata==0, use list */
+ const unsigned int *maxdata_list; /* list is channel specific */
unsigned int flags;
const unsigned int *flaglist;
unsigned int settling_time_0;
- const comedi_lrange *range_table;
- const comedi_lrange *const *range_table_list;
+ const struct comedi_lrange *range_table;
+ const struct comedi_lrange *const *range_table_list;
unsigned int *chanlist; /* driver-owned chanlist (not used) */
- int (*insn_read) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
- int (*insn_write) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
- int (*insn_bits) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
- int (*insn_config) (comedi_device *, comedi_subdevice *, comedi_insn *,
- lsampl_t *);
-
- int (*do_cmd) (comedi_device *, comedi_subdevice *);
- int (*do_cmdtest) (comedi_device *, comedi_subdevice *, comedi_cmd *);
- int (*poll) (comedi_device *, comedi_subdevice *);
- int (*cancel) (comedi_device *, comedi_subdevice *);
- /* int (*do_lock)(comedi_device *,comedi_subdevice *); */
- /* int (*do_unlock)(comedi_device *,comedi_subdevice *); */
+ int (*insn_read) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insn_write) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insn_bits) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insn_config) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+
+ int (*do_cmd) (struct comedi_device *, struct comedi_subdevice *);
+ int (*do_cmdtest) (struct comedi_device *, struct comedi_subdevice *, struct comedi_cmd *);
+ int (*poll) (struct comedi_device *, struct comedi_subdevice *);
+ int (*cancel) (struct comedi_device *, struct comedi_subdevice *);
+ /* int (*do_lock)(struct comedi_device *,struct comedi_subdevice *); */
+ /* int (*do_unlock)(struct comedi_device *,struct comedi_subdevice *); */
/* called when the buffer changes */
- int (*buf_change) (comedi_device *dev, comedi_subdevice *s,
+ int (*buf_change) (struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long new_size);
- void (*munge) (comedi_device *dev, comedi_subdevice *s, void *data,
+ void (*munge) (struct comedi_device *dev, struct comedi_subdevice *s, void *data,
unsigned int num_bytes, unsigned int start_chan_index);
enum dma_data_direction async_dma_dir;
unsigned int state;
- device_create_result_type *class_dev;
+ struct device *class_dev;
int minor;
};
@@ -201,8 +190,8 @@ struct comedi_buf_page {
dma_addr_t dma_addr;
};
-struct comedi_async_struct {
- comedi_subdevice *subdevice;
+struct comedi_async {
+ struct comedi_subdevice *subdevice;
void *prealloc_buf; /* pre-allocated buffer */
unsigned int prealloc_bufsz; /* buffer size, in bytes */
@@ -232,7 +221,7 @@ struct comedi_async_struct {
unsigned int events; /* events that have occurred */
- comedi_cmd cmd;
+ struct comedi_cmd cmd;
wait_queue_head_t wait_head;
@@ -241,17 +230,17 @@ struct comedi_async_struct {
int (*cb_func) (unsigned int flags, void *);
void *cb_arg;
- int (*inttrig) (comedi_device *dev, comedi_subdevice *s,
+ int (*inttrig) (struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int x);
};
-struct comedi_driver_struct {
- struct comedi_driver_struct *next;
+struct comedi_driver {
+ struct comedi_driver *next;
const char *driver_name;
struct module *module;
- int (*attach) (comedi_device *, comedi_devconfig *);
- int (*detach) (comedi_device *);
+ int (*attach) (struct comedi_device *, struct comedi_devconfig *);
+ int (*detach) (struct comedi_device *);
/* number of elements in board_name and board_id arrays */
unsigned int num_names;
@@ -260,12 +249,12 @@ struct comedi_driver_struct {
int offset;
};
-struct comedi_device_struct {
+struct comedi_device {
int use_count;
- comedi_driver *driver;
+ struct comedi_driver *driver;
void *private;
- device_create_result_type *class_dev;
+ struct device *class_dev;
int minor;
/* hw_dev is passed to dma_alloc_coherent when allocating async buffers
* for subdevices that have async_dma_dir set to something other than
@@ -281,25 +270,25 @@ struct comedi_device_struct {
int in_request_module;
int n_subdevices;
- comedi_subdevice *subdevices;
+ struct comedi_subdevice *subdevices;
/* dumb */
unsigned long iobase;
unsigned int irq;
- comedi_subdevice *read_subdev;
- comedi_subdevice *write_subdev;
+ struct comedi_subdevice *read_subdev;
+ struct comedi_subdevice *write_subdev;
struct fasync_struct *async_queue;
- void (*open) (comedi_device *dev);
- void (*close) (comedi_device *dev);
+ void (*open) (struct comedi_device *dev);
+ void (*close) (struct comedi_device *dev);
};
struct comedi_device_file_info {
- comedi_device *device;
- comedi_subdevice *read_subdevice;
- comedi_subdevice *write_subdevice;
+ struct comedi_device *device;
+ struct comedi_subdevice *read_subdevice;
+ struct comedi_subdevice *write_subdevice;
};
#ifdef CONFIG_COMEDI_DEBUG
@@ -312,8 +301,8 @@ static const int comedi_debug;
* function prototypes
*/
-void comedi_event(comedi_device *dev, comedi_subdevice *s);
-void comedi_error(const comedi_device *dev, const char *s);
+void comedi_event(struct comedi_device *dev, struct comedi_subdevice *s);
+void comedi_error(const struct comedi_device *dev, const char *s);
/* we can expand the number of bits used to encode devices/subdevices into
the minor number soon, after more distros support > 8 bit minor numbers
@@ -327,7 +316,7 @@ static const unsigned COMEDI_SUBDEVICE_MINOR_OFFSET = 1;
struct comedi_device_file_info *comedi_get_device_file_info(unsigned minor);
-static inline comedi_subdevice *comedi_get_read_subdevice(
+static inline struct comedi_subdevice *comedi_get_read_subdevice(
const struct comedi_device_file_info *info)
{
if (info->read_subdevice)
@@ -337,7 +326,7 @@ static inline comedi_subdevice *comedi_get_read_subdevice(
return info->device->read_subdev;
}
-static inline comedi_subdevice *comedi_get_write_subdevice(
+static inline struct comedi_subdevice *comedi_get_write_subdevice(
const struct comedi_device_file_info *info)
{
if (info->write_subdevice)
@@ -347,17 +336,17 @@ static inline comedi_subdevice *comedi_get_write_subdevice(
return info->device->write_subdev;
}
-void comedi_device_detach(comedi_device *dev);
-int comedi_device_attach(comedi_device *dev, comedi_devconfig *it);
-int comedi_driver_register(comedi_driver *);
-int comedi_driver_unregister(comedi_driver *);
+void comedi_device_detach(struct comedi_device *dev);
+int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+int comedi_driver_register(struct comedi_driver *);
+int comedi_driver_unregister(struct comedi_driver *);
void init_polling(void);
void cleanup_polling(void);
-void start_polling(comedi_device *);
-void stop_polling(comedi_device *);
+void start_polling(struct comedi_device *);
+void stop_polling(struct comedi_device *);
-int comedi_buf_alloc(comedi_device *dev, comedi_subdevice *s, unsigned long
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned long
new_size);
#ifdef CONFIG_PROC_FS
@@ -386,13 +375,13 @@ enum subdevice_runflags {
various internal comedi functions
*/
-int do_rangeinfo_ioctl(comedi_device *dev, comedi_rangeinfo *arg);
-int check_chanlist(comedi_subdevice *s, int n, unsigned int *chanlist);
-void comedi_set_subdevice_runflags(comedi_subdevice *s, unsigned mask,
+int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg);
+int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist);
+void comedi_set_subdevice_runflags(struct comedi_subdevice *s, unsigned mask,
unsigned bits);
-unsigned comedi_get_subdevice_runflags(comedi_subdevice *s);
-int insn_inval(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
+unsigned comedi_get_subdevice_runflags(struct comedi_subdevice *s);
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
/* range stuff */
@@ -403,12 +392,12 @@ int insn_inval(comedi_device *dev, comedi_subdevice *s,
#define BIP_RANGE(a) {-(a)*1e6, (a)*1e6, 0}
#define UNI_RANGE(a) {0, (a)*1e6, 0}
-extern const comedi_lrange range_bipolar10;
-extern const comedi_lrange range_bipolar5;
-extern const comedi_lrange range_bipolar2_5;
-extern const comedi_lrange range_unipolar10;
-extern const comedi_lrange range_unipolar5;
-extern const comedi_lrange range_unknown;
+extern const struct comedi_lrange range_bipolar10;
+extern const struct comedi_lrange range_bipolar5;
+extern const struct comedi_lrange range_bipolar2_5;
+extern const struct comedi_lrange range_unipolar10;
+extern const struct comedi_lrange range_unipolar5;
+extern const struct comedi_lrange range_unknown;
#define range_digital range_unipolar5
@@ -418,21 +407,21 @@ extern const comedi_lrange range_unknown;
#define GCC_ZERO_LENGTH_ARRAY 0
#endif
-struct comedi_lrange_struct {
+struct comedi_lrange {
int length;
- comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
+ struct comedi_krange range[GCC_ZERO_LENGTH_ARRAY];
};
/* some silly little inline functions */
-static inline int alloc_subdevices(comedi_device *dev,
+static inline int alloc_subdevices(struct comedi_device *dev,
unsigned int num_subdevices)
{
unsigned i;
dev->n_subdevices = num_subdevices;
dev->subdevices =
- kcalloc(num_subdevices, sizeof(comedi_subdevice), GFP_KERNEL);
+ kcalloc(num_subdevices, sizeof(struct comedi_subdevice), GFP_KERNEL);
if (!dev->subdevices)
return -ENOMEM;
for (i = 0; i < num_subdevices; ++i) {
@@ -444,7 +433,7 @@ static inline int alloc_subdevices(comedi_device *dev,
return 0;
}
-static inline int alloc_private(comedi_device *dev, int size)
+static inline int alloc_private(struct comedi_device *dev, int size)
{
dev->private = kzalloc(size, GFP_KERNEL);
if (!dev->private)
@@ -452,17 +441,17 @@ static inline int alloc_private(comedi_device *dev, int size)
return 0;
}
-static inline unsigned int bytes_per_sample(const comedi_subdevice *subd)
+static inline unsigned int bytes_per_sample(const struct comedi_subdevice *subd)
{
if (subd->subdev_flags & SDF_LSAMPL)
- return sizeof(lsampl_t);
+ return sizeof(unsigned int);
else
- return sizeof(sampl_t);
+ return sizeof(short);
}
/* must be used in attach to set dev->hw_dev if you wish to dma directly
into comedi's buffer */
-static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
+static inline void comedi_set_hw_dev(struct comedi_device *dev, struct device *hw_dev)
{
if (dev->hw_dev)
put_device(dev->hw_dev);
@@ -474,31 +463,31 @@ static inline void comedi_set_hw_dev(comedi_device *dev, struct device *hw_dev)
}
}
-int comedi_buf_put(comedi_async *async, sampl_t x);
-int comedi_buf_get(comedi_async *async, sampl_t *x);
+int comedi_buf_put(struct comedi_async *async, short x);
+int comedi_buf_get(struct comedi_async *async, short *x);
-unsigned int comedi_buf_write_n_available(comedi_async *async);
-unsigned int comedi_buf_write_alloc(comedi_async *async, unsigned int nbytes);
-unsigned int comedi_buf_write_alloc_strict(comedi_async *async,
+unsigned int comedi_buf_write_n_available(struct comedi_async *async);
+unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes);
+unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
unsigned int nbytes);
-unsigned comedi_buf_write_free(comedi_async *async, unsigned int nbytes);
-unsigned comedi_buf_read_alloc(comedi_async *async, unsigned nbytes);
-unsigned comedi_buf_read_free(comedi_async *async, unsigned int nbytes);
-unsigned int comedi_buf_read_n_available(comedi_async *async);
-void comedi_buf_memcpy_to(comedi_async *async, unsigned int offset,
+unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes);
+unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes);
+unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes);
+unsigned int comedi_buf_read_n_available(struct comedi_async *async);
+void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
const void *source, unsigned int num_bytes);
-void comedi_buf_memcpy_from(comedi_async *async, unsigned int offset,
+void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
void *destination, unsigned int num_bytes);
-static inline unsigned comedi_buf_write_n_allocated(comedi_async *async)
+static inline unsigned comedi_buf_write_n_allocated(struct comedi_async *async)
{
return async->buf_write_alloc_count - async->buf_write_count;
}
-static inline unsigned comedi_buf_read_n_allocated(comedi_async *async)
+static inline unsigned comedi_buf_read_n_allocated(struct comedi_async *async)
{
return async->buf_read_alloc_count - async->buf_read_count;
}
-void comedi_reset_async_buf(comedi_async *async);
+void comedi_reset_async_buf(struct comedi_async *async);
static inline void *comedi_aux_data(int options[], int n)
{
@@ -527,10 +516,13 @@ static inline void *comedi_aux_data(int options[], int n)
int comedi_alloc_board_minor(struct device *hardware_device);
void comedi_free_board_minor(unsigned minor);
-int comedi_alloc_subdevice_minor(comedi_device *dev, comedi_subdevice *s);
-void comedi_free_subdevice_minor(comedi_subdevice *s);
+int comedi_alloc_subdevice_minor(struct comedi_device *dev, struct comedi_subdevice *s);
+void comedi_free_subdevice_minor(struct comedi_subdevice *s);
int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name);
void comedi_pci_auto_unconfig(struct pci_dev *pcidev);
+struct usb_device; /* forward declaration */
+int comedi_usb_auto_config(struct usb_device *usbdev, const char *board_name);
+void comedi_usb_auto_unconfig(struct usb_device *usbdev);
#include "comedi_rt.h"
diff --git a/drivers/staging/comedi/comedilib.h b/drivers/staging/comedi/comedilib.h
index fc5fc015726..c2729312d57 100644
--- a/drivers/staging/comedi/comedilib.h
+++ b/drivers/staging/comedi/comedilib.h
@@ -36,18 +36,16 @@
#ifndef KCOMEDILIB_DEPRECATED
-typedef void comedi_t;
-
/* these functions may not be called at real-time priority */
-comedi_t *comedi_open(const char *path);
-int comedi_close(comedi_t *dev);
+void *comedi_open(const char *path);
+int comedi_close(void *dev);
/* these functions may be called at any priority, but may fail at
real-time priority */
-int comedi_lock(comedi_t *dev, unsigned int subdev);
-int comedi_unlock(comedi_t *dev, unsigned int subdev);
+int comedi_lock(void *dev, unsigned int subdev);
+int comedi_unlock(void *dev, unsigned int subdev);
/* these functions may be called at any priority, but you must hold
the lock for the subdevice */
@@ -56,68 +54,68 @@ int comedi_loglevel(int loglevel);
void comedi_perror(const char *s);
char *comedi_strerror(int errnum);
int comedi_errno(void);
-int comedi_fileno(comedi_t *dev);
+int comedi_fileno(void *dev);
-int comedi_cancel(comedi_t *dev, unsigned int subdev);
-int comedi_register_callback(comedi_t *dev, unsigned int subdev,
+int comedi_cancel(void *dev, unsigned int subdev);
+int comedi_register_callback(void *dev, unsigned int subdev,
unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
-int comedi_command(comedi_t *dev, comedi_cmd *cmd);
-int comedi_command_test(comedi_t *dev, comedi_cmd *cmd);
-int comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
-int __comedi_trigger(comedi_t *dev, unsigned int subdev, comedi_trig *it);
-int comedi_data_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t data);
-int comedi_data_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t *data);
-int comedi_data_read_hint(comedi_t *dev, unsigned int subdev,
+int comedi_command(void *dev, struct comedi_cmd *cmd);
+int comedi_command_test(void *dev, struct comedi_cmd *cmd);
+int comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
+int __comedi_trigger(void *dev, unsigned int subdev, struct comedi_trig *it);
+int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int data);
+int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int *data);
+int comedi_data_read_hint(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref);
-int comedi_data_read_delayed(comedi_t *dev, unsigned int subdev,
+int comedi_data_read_delayed(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref,
- lsampl_t *data, unsigned int nano_sec);
-int comedi_dio_config(comedi_t *dev, unsigned int subdev, unsigned int chan,
+ unsigned int *data, unsigned int nano_sec);
+int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
unsigned int io);
-int comedi_dio_read(comedi_t *dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
unsigned int *val);
-int comedi_dio_write(comedi_t *dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
unsigned int val);
-int comedi_dio_bitfield(comedi_t *dev, unsigned int subdev, unsigned int mask,
+int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
unsigned int *bits);
-int comedi_get_n_subdevices(comedi_t *dev);
-int comedi_get_version_code(comedi_t *dev);
-const char *comedi_get_driver_name(comedi_t *dev);
-const char *comedi_get_board_name(comedi_t *dev);
-int comedi_get_subdevice_type(comedi_t *dev, unsigned int subdevice);
-int comedi_find_subdevice_by_type(comedi_t *dev, int type, unsigned int subd);
-int comedi_get_n_channels(comedi_t *dev, unsigned int subdevice);
-lsampl_t comedi_get_maxdata(comedi_t *dev, unsigned int subdevice, unsigned
+int comedi_get_n_subdevices(void *dev);
+int comedi_get_version_code(void *dev);
+const char *comedi_get_driver_name(void *dev);
+const char *comedi_get_board_name(void *dev);
+int comedi_get_subdevice_type(void *dev, unsigned int subdevice);
+int comedi_find_subdevice_by_type(void *dev, int type, unsigned int subd);
+int comedi_get_n_channels(void *dev, unsigned int subdevice);
+unsigned int comedi_get_maxdata(void *dev, unsigned int subdevice, unsigned
int chan);
-int comedi_get_n_ranges(comedi_t *dev, unsigned int subdevice, unsigned int
+int comedi_get_n_ranges(void *dev, unsigned int subdevice, unsigned int
chan);
-int comedi_do_insn(comedi_t *dev, comedi_insn *insn);
-int comedi_poll(comedi_t *dev, unsigned int subdev);
+int comedi_do_insn(void *dev, struct comedi_insn *insn);
+int comedi_poll(void *dev, unsigned int subdev);
/* DEPRECATED functions */
-int comedi_get_rangetype(comedi_t *dev, unsigned int subdevice,
+int comedi_get_rangetype(void *dev, unsigned int subdevice,
unsigned int chan);
/* ALPHA functions */
-unsigned int comedi_get_subdevice_flags(comedi_t *dev, unsigned int subdevice);
-int comedi_get_len_chanlist(comedi_t *dev, unsigned int subdevice);
-int comedi_get_krange(comedi_t *dev, unsigned int subdevice, unsigned int
- chan, unsigned int range, comedi_krange *krange);
-unsigned int comedi_get_buf_head_pos(comedi_t *dev, unsigned int subdevice);
-int comedi_set_user_int_count(comedi_t *dev, unsigned int subdevice,
+unsigned int comedi_get_subdevice_flags(void *dev, unsigned int subdevice);
+int comedi_get_len_chanlist(void *dev, unsigned int subdevice);
+int comedi_get_krange(void *dev, unsigned int subdevice, unsigned int
+ chan, unsigned int range, struct comedi_krange *krange);
+unsigned int comedi_get_buf_head_pos(void *dev, unsigned int subdevice);
+int comedi_set_user_int_count(void *dev, unsigned int subdevice,
unsigned int buf_user_count);
-int comedi_map(comedi_t *dev, unsigned int subdev, void *ptr);
-int comedi_unmap(comedi_t *dev, unsigned int subdev);
-int comedi_get_buffer_size(comedi_t *dev, unsigned int subdev);
-int comedi_mark_buffer_read(comedi_t *dev, unsigned int subdevice,
+int comedi_map(void *dev, unsigned int subdev, void *ptr);
+int comedi_unmap(void *dev, unsigned int subdev);
+int comedi_get_buffer_size(void *dev, unsigned int subdev);
+int comedi_mark_buffer_read(void *dev, unsigned int subdevice,
unsigned int num_bytes);
-int comedi_mark_buffer_written(comedi_t *d, unsigned int subdevice,
+int comedi_mark_buffer_written(void *d, unsigned int subdevice,
unsigned int num_bytes);
-int comedi_get_buffer_contents(comedi_t *dev, unsigned int subdevice);
-int comedi_get_buffer_offset(comedi_t *dev, unsigned int subdevice);
+int comedi_get_buffer_contents(void *dev, unsigned int subdevice);
+int comedi_get_buffer_offset(void *dev, unsigned int subdevice);
#else
@@ -139,14 +137,14 @@ int comedi_cancel(unsigned int minor, unsigned int subdev);
int comedi_register_callback(unsigned int minor, unsigned int subdev,
unsigned int mask, int (*cb) (unsigned int, void *), void *arg);
-int comedi_command(unsigned int minor, comedi_cmd *cmd);
-int comedi_command_test(unsigned int minor, comedi_cmd *cmd);
-int comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
-int __comedi_trigger(unsigned int minor, unsigned int subdev, comedi_trig *it);
+int comedi_command(unsigned int minor, struct comedi_cmd *cmd);
+int comedi_command_test(unsigned int minor, struct comedi_cmd *cmd);
+int comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
+int __comedi_trigger(unsigned int minor, unsigned int subdev, struct comedi_trig *it);
int comedi_data_write(unsigned int dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t data);
+ unsigned int range, unsigned int aref, unsigned int data);
int comedi_data_read(unsigned int dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t *data);
+ unsigned int range, unsigned int aref, unsigned int *data);
int comedi_dio_config(unsigned int dev, unsigned int subdev, unsigned int chan,
unsigned int io);
int comedi_dio_read(unsigned int dev, unsigned int subdev, unsigned int chan,
@@ -163,11 +161,11 @@ int comedi_get_subdevice_type(unsigned int minor, unsigned int subdevice);
int comedi_find_subdevice_by_type(unsigned int minor, int type,
unsigned int subd);
int comedi_get_n_channels(unsigned int minor, unsigned int subdevice);
-lsampl_t comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
+unsigned int comedi_get_maxdata(unsigned int minor, unsigned int subdevice, unsigned
int chan);
int comedi_get_n_ranges(unsigned int minor, unsigned int subdevice, unsigned int
chan);
-int comedi_do_insn(unsigned int minor, comedi_insn *insn);
+int comedi_do_insn(unsigned int minor, struct comedi_insn *insn);
int comedi_poll(unsigned int minor, unsigned int subdev);
/* DEPRECATED functions */
@@ -179,7 +177,7 @@ unsigned int comedi_get_subdevice_flags(unsigned int minor, unsigned int
subdevice);
int comedi_get_len_chanlist(unsigned int minor, unsigned int subdevice);
int comedi_get_krange(unsigned int minor, unsigned int subdevice, unsigned int
- chan, unsigned int range, comedi_krange *krange);
+ chan, unsigned int range, struct comedi_krange *krange);
unsigned int comedi_get_buf_head_pos(unsigned int minor, unsigned int
subdevice);
int comedi_set_user_int_count(unsigned int minor, unsigned int subdevice,
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c
index 36a93b95e3f..6e13e450dc7 100644
--- a/drivers/staging/comedi/drivers.c
+++ b/drivers/staging/comedi/drivers.c
@@ -28,6 +28,7 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/pci.h>
+#include <linux/usb.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -46,26 +47,26 @@
#include <asm/io.h>
#include <asm/system.h>
-static int postconfig(comedi_device * dev);
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static void *comedi_recognize(comedi_driver * driv, const char *name);
-static void comedi_report_boards(comedi_driver * driv);
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s);
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+static int postconfig(struct comedi_device *dev);
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static void *comedi_recognize(struct comedi_driver * driv, const char *name);
+static void comedi_report_boards(struct comedi_driver *driv);
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s);
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long new_size);
-comedi_driver *comedi_drivers;
+struct comedi_driver *comedi_drivers;
int comedi_modprobe(int minor)
{
return -EINVAL;
}
-static void cleanup_device(comedi_device * dev)
+static void cleanup_device(struct comedi_device *dev)
{
int i;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
if (dev->subdevices) {
for (i = 0; i < dev->n_subdevices; i++) {
@@ -80,10 +81,8 @@ static void cleanup_device(comedi_device * dev)
dev->subdevices = NULL;
dev->n_subdevices = 0;
}
- if (dev->private) {
- kfree(dev->private);
- dev->private = NULL;
- }
+ kfree(dev->private);
+ dev->private = NULL;
dev->driver = 0;
dev->board_name = NULL;
dev->board_ptr = NULL;
@@ -96,7 +95,7 @@ static void cleanup_device(comedi_device * dev)
comedi_set_hw_dev(dev, NULL);
}
-static void __comedi_device_detach(comedi_device * dev)
+static void __comedi_device_detach(struct comedi_device *dev)
{
dev->attached = 0;
if (dev->driver) {
@@ -107,16 +106,16 @@ static void __comedi_device_detach(comedi_device * dev)
cleanup_device(dev);
}
-void comedi_device_detach(comedi_device * dev)
+void comedi_device_detach(struct comedi_device *dev)
{
if (!dev->attached)
return;
__comedi_device_detach(dev);
}
-int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
+int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_driver *driv;
+ struct comedi_driver *driv;
int ret;
if (dev->attached)
@@ -139,7 +138,7 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
continue;
}
}
- //initialize dev->driver here so comedi_error() can be called from attach
+ /* initialize dev->driver here so comedi_error() can be called from attach */
dev->driver = driv;
ret = driv->attach(dev, it);
if (ret < 0) {
@@ -150,8 +149,8 @@ int comedi_device_attach(comedi_device * dev, comedi_devconfig * it)
goto attached;
}
- // recognize has failed if we get here
- // report valid board names before returning error
+ /* recognize has failed if we get here */
+ /* report valid board names before returning error */
for (driv = comedi_drivers; driv; driv = driv->next) {
if (!try_module_get(driv->module)) {
printk("comedi: failed to increment module count\n");
@@ -181,7 +180,7 @@ attached:
return 0;
}
-int comedi_driver_register(comedi_driver * driver)
+int comedi_driver_register(struct comedi_driver *driver)
{
driver->next = comedi_drivers;
comedi_drivers = driver;
@@ -189,15 +188,15 @@ int comedi_driver_register(comedi_driver * driver)
return 0;
}
-int comedi_driver_unregister(comedi_driver * driver)
+int comedi_driver_unregister(struct comedi_driver *driver)
{
- comedi_driver *prev;
+ struct comedi_driver *prev;
int i;
/* check for devices using this driver */
for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
- comedi_device *dev;
+ struct comedi_device *dev;
if(dev_file_info == NULL) continue;
dev = dev_file_info->device;
@@ -225,11 +224,11 @@ int comedi_driver_unregister(comedi_driver * driver)
return -EINVAL;
}
-static int postconfig(comedi_device * dev)
+static int postconfig(struct comedi_device *dev)
{
int i;
- comedi_subdevice *s;
- comedi_async *async = NULL;
+ struct comedi_subdevice *s;
+ struct comedi_async *async = NULL;
int ret;
for (i = 0; i < dev->n_subdevices; i++) {
@@ -246,7 +245,7 @@ static int postconfig(comedi_device * dev)
SDF_CMD_WRITE)) == 0);
BUG_ON(!s->do_cmdtest);
- async = kzalloc(sizeof(comedi_async), GFP_KERNEL);
+ async = kzalloc(sizeof(struct comedi_async), GFP_KERNEL);
if (async == NULL) {
printk("failed to allocate async struct\n");
return -ENOMEM;
@@ -298,8 +297,8 @@ static int postconfig(comedi_device * dev)
return 0;
}
-// generic recognize function for drivers that register their supported board names
-void *comedi_recognize(comedi_driver * driv, const char *name)
+/* generic recognize function for drivers that register their supported board names */
+void *comedi_recognize(struct comedi_driver * driv, const char *name)
{
unsigned i;
const char *const *name_ptr = driv->board_name;
@@ -314,7 +313,7 @@ void *comedi_recognize(comedi_driver * driv, const char *name)
return NULL;
}
-void comedi_report_boards(comedi_driver * driv)
+void comedi_report_boards(struct comedi_driver *driv)
{
unsigned int i;
const char *const *name_ptr;
@@ -332,28 +331,28 @@ void comedi_report_boards(comedi_driver * driv)
printk(" %s\n", driv->driver_name);
}
-static int poll_invalid(comedi_device * dev, comedi_subdevice * s)
+static int poll_invalid(struct comedi_device *dev, struct comedi_subdevice *s)
{
return -EINVAL;
}
-int insn_inval(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+int insn_inval(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return -EINVAL;
}
-static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int insn_rw_emulate_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
- comedi_insn new_insn;
+ struct comedi_insn new_insn;
int ret;
static const unsigned channels_per_bitfield = 32;
unsigned chan = CR_CHAN(insn->chanspec);
const unsigned base_bitfield_channel =
(chan < channels_per_bitfield) ? 0 : chan;
- lsampl_t new_data[2];
+ unsigned int new_data[2];
memset(new_data, 0, sizeof(new_data));
memset(&new_insn, 0, sizeof(new_insn));
new_insn.insn = INSN_BITS;
@@ -380,7 +379,7 @@ static int insn_rw_emulate_bits(comedi_device * dev, comedi_subdevice * s,
return 1;
}
-static inline unsigned long uvirt_to_kva(pgd_t * pgd, unsigned long adr)
+static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
{
unsigned long ret = 0UL;
pmd_t *pmd;
@@ -413,10 +412,10 @@ static inline unsigned long kvirt_to_kva(unsigned long adr)
return kva;
}
-int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
+int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned long new_size)
{
- comedi_async *async = s->async;
+ struct comedi_async *async = s->async;
/* Round up new_size to multiple of PAGE_SIZE */
new_size = (new_size + PAGE_SIZE - 1) & PAGE_MASK;
@@ -425,7 +424,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
if (async->prealloc_buf && async->prealloc_bufsz == new_size) {
return 0;
}
- // deallocate old buffer
+ /* deallocate old buffer */
if (async->prealloc_buf) {
vunmap(async->prealloc_buf);
async->prealloc_buf = NULL;
@@ -454,7 +453,7 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
async->buf_page_list = NULL;
async->n_buf_pages = 0;
}
- // allocate new buffer
+ /* allocate new buffer */
if (new_size) {
unsigned i = 0;
unsigned n_pages = new_size >> PAGE_SHIFT;
@@ -537,16 +536,15 @@ int comedi_buf_alloc(comedi_device * dev, comedi_subdevice * s,
/* munging is applied to data by core as it passes between user
* and kernel space */
-unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
+unsigned int comedi_buf_munge(struct comedi_async *async, unsigned int num_bytes)
{
- comedi_subdevice *s = async->subdevice;
+ struct comedi_subdevice *s = async->subdevice;
unsigned int count = 0;
const unsigned num_sample_bytes = bytes_per_sample(s);
if (s->munge == NULL || (async->cmd.flags & CMDF_RAWDATA)) {
async->munge_count += num_bytes;
- if ((int)(async->munge_count - async->buf_write_count) > 0)
- BUG();
+ BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
return num_bytes;
}
/* don't munge partial samples */
@@ -567,7 +565,7 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
s->munge(s->device, s, async->prealloc_buf + async->munge_ptr,
block_size, async->munge_chan);
- smp_wmb(); //barrier insures data is munged in buffer before munge_count is incremented
+ smp_wmb(); /* barrier insures data is munged in buffer before munge_count is incremented */
async->munge_chan += block_size / num_sample_bytes;
async->munge_chan %= async->cmd.chanlist_len;
@@ -576,12 +574,11 @@ unsigned int comedi_buf_munge(comedi_async * async, unsigned int num_bytes)
async->munge_ptr %= async->prealloc_bufsz;
count += block_size;
}
- if ((int)(async->munge_count - async->buf_write_count) > 0)
- BUG();
+ BUG_ON((int)(async->munge_count - async->buf_write_count) > 0);
return count;
}
-unsigned int comedi_buf_write_n_available(comedi_async * async)
+unsigned int comedi_buf_write_n_available(struct comedi_async *async)
{
unsigned int free_end;
unsigned int nbytes;
@@ -601,7 +598,7 @@ unsigned int comedi_buf_write_n_available(comedi_async * async)
}
/* allocates chunk for the writer from free buffer space */
-unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
+unsigned int comedi_buf_write_alloc(struct comedi_async *async, unsigned int nbytes)
{
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
@@ -616,7 +613,7 @@ unsigned int comedi_buf_write_alloc(comedi_async * async, unsigned int nbytes)
}
/* allocates nothing unless it can completely fulfill the request */
-unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
+unsigned int comedi_buf_write_alloc_strict(struct comedi_async *async,
unsigned int nbytes)
{
unsigned int free_end = async->buf_read_count + async->prealloc_bufsz;
@@ -632,7 +629,7 @@ unsigned int comedi_buf_write_alloc_strict(comedi_async * async,
}
/* transfers a chunk from writer to filled buffer space */
-unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes)
{
if ((int)(async->buf_write_count + nbytes -
async->buf_write_alloc_count) > 0) {
@@ -650,7 +647,7 @@ unsigned comedi_buf_write_free(comedi_async * async, unsigned int nbytes)
}
/* allocates a chunk for the reader from filled (and munged) buffer space */
-unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
+unsigned comedi_buf_read_alloc(struct comedi_async *async, unsigned nbytes)
{
if ((int)(async->buf_read_alloc_count + nbytes - async->munge_count) >
0) {
@@ -664,9 +661,9 @@ unsigned comedi_buf_read_alloc(comedi_async * async, unsigned nbytes)
}
/* transfers control of a chunk from reader to free buffer space */
-unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
+unsigned comedi_buf_read_free(struct comedi_async *async, unsigned int nbytes)
{
- // barrier insures data has been read out of buffer before read count is incremented
+ /* barrier insures data has been read out of buffer before read count is incremented */
smp_mb();
if ((int)(async->buf_read_count + nbytes -
async->buf_read_alloc_count) > 0) {
@@ -680,7 +677,7 @@ unsigned comedi_buf_read_free(comedi_async * async, unsigned int nbytes)
return nbytes;
}
-void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_to(struct comedi_async *async, unsigned int offset,
const void *data, unsigned int num_bytes)
{
unsigned int write_ptr = async->buf_write_ptr + offset;
@@ -705,7 +702,7 @@ void comedi_buf_memcpy_to(comedi_async * async, unsigned int offset,
}
}
-void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
+void comedi_buf_memcpy_from(struct comedi_async *async, unsigned int offset,
void *dest, unsigned int nbytes)
{
void *src;
@@ -731,7 +728,7 @@ void comedi_buf_memcpy_from(comedi_async * async, unsigned int offset,
}
}
-unsigned int comedi_buf_read_n_available(comedi_async * async)
+unsigned int comedi_buf_read_n_available(struct comedi_async *async)
{
unsigned num_bytes;
@@ -746,32 +743,32 @@ unsigned int comedi_buf_read_n_available(comedi_async * async)
return num_bytes;
}
-int comedi_buf_get(comedi_async * async, sampl_t * x)
+int comedi_buf_get(struct comedi_async *async, short *x)
{
unsigned int n = comedi_buf_read_n_available(async);
- if (n < sizeof(sampl_t))
+ if (n < sizeof(short))
return 0;
- comedi_buf_read_alloc(async, sizeof(sampl_t));
- *x = *(sampl_t *) (async->prealloc_buf + async->buf_read_ptr);
- comedi_buf_read_free(async, sizeof(sampl_t));
+ comedi_buf_read_alloc(async, sizeof(short));
+ *x = *(short *) (async->prealloc_buf + async->buf_read_ptr);
+ comedi_buf_read_free(async, sizeof(short));
return 1;
}
-int comedi_buf_put(comedi_async * async, sampl_t x)
+int comedi_buf_put(struct comedi_async *async, short x)
{
- unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(sampl_t));
+ unsigned int n = comedi_buf_write_alloc_strict(async, sizeof(short));
- if (n < sizeof(sampl_t)) {
+ if (n < sizeof(short)) {
async->events |= COMEDI_CB_ERROR;
return 0;
}
- *(sampl_t *) (async->prealloc_buf + async->buf_write_ptr) = x;
- comedi_buf_write_free(async, sizeof(sampl_t));
+ *(short *) (async->prealloc_buf + async->buf_write_ptr) = x;
+ comedi_buf_write_free(async, sizeof(short));
return 1;
}
-void comedi_reset_async_buf(comedi_async * async)
+void comedi_reset_async_buf(struct comedi_async *async)
{
async->buf_write_alloc_count = 0;
async->buf_write_count = 0;
@@ -792,14 +789,27 @@ void comedi_reset_async_buf(comedi_async * async)
int comedi_auto_config(struct device *hardware_device, const char *board_name, const int *options, unsigned num_options)
{
- comedi_devconfig it;
+ struct comedi_devconfig it;
int minor;
struct comedi_device_file_info *dev_file_info;
int retval;
+ unsigned *private_data = NULL;
+
+ if (!comedi_autoconfig) {
+ dev_set_drvdata(hardware_device, NULL);
+ return 0;
+ }
minor = comedi_alloc_board_minor(hardware_device);
if(minor < 0) return minor;
- dev_set_drvdata(hardware_device, (void*)(unsigned long)minor);
+
+ private_data = kmalloc(sizeof(unsigned), GFP_KERNEL);
+ if (private_data == NULL) {
+ retval = -ENOMEM;
+ goto cleanup;
+ }
+ *private_data = minor;
+ dev_set_drvdata(hardware_device, private_data);
dev_file_info = comedi_get_device_file_info(minor);
@@ -812,8 +822,11 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
mutex_lock(&dev_file_info->device->mutex);
retval = comedi_device_attach(dev_file_info->device, &it);
mutex_unlock(&dev_file_info->device->mutex);
+
+cleanup:
if(retval < 0)
{
+ kfree(private_data);
comedi_free_board_minor(minor);
}
return retval;
@@ -821,20 +834,23 @@ int comedi_auto_config(struct device *hardware_device, const char *board_name, c
void comedi_auto_unconfig(struct device *hardware_device)
{
- unsigned long minor = (unsigned long)dev_get_drvdata(hardware_device);
+ unsigned *minor = (unsigned *)dev_get_drvdata(hardware_device);
+ if(minor == NULL) return;
- BUG_ON(minor >= COMEDI_NUM_BOARD_MINORS);
+ BUG_ON(*minor >= COMEDI_NUM_BOARD_MINORS);
- comedi_free_board_minor(minor);
+ comedi_free_board_minor(*minor);
+ dev_set_drvdata(hardware_device, NULL);
+ kfree(minor);
}
int comedi_pci_auto_config(struct pci_dev *pcidev, const char *board_name)
{
int options[2];
- // pci bus
+ /* pci bus */
options[0] = pcidev->bus->number;
- // pci slot
+ /* pci slot */
options[1] = PCI_SLOT(pcidev->devfn);
return comedi_auto_config(&pcidev->dev, board_name, options, sizeof(options) / sizeof(options[0]));
@@ -844,3 +860,16 @@ void comedi_pci_auto_unconfig(struct pci_dev *pcidev)
{
comedi_auto_unconfig(&pcidev->dev);
}
+
+int comedi_usb_auto_config(struct usb_device *usbdev,
+ const char *board_name)
+{
+ BUG_ON(usbdev == NULL);
+ return comedi_auto_config(&usbdev->dev, board_name, NULL, 0);
+}
+
+void comedi_usb_auto_unconfig(struct usb_device *usbdev)
+{
+ BUG_ON(usbdev == NULL);
+ comedi_auto_unconfig(&usbdev->dev);
+}
diff --git a/drivers/staging/comedi/drivers/8253.h b/drivers/staging/comedi/drivers/8253.h
new file mode 100644
index 00000000000..08a11a5a16e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8253.h
@@ -0,0 +1,420 @@
+/*
+ comedi/drivers/8253.h
+ Header file for 8253
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _8253_H
+#define _8253_H
+
+#ifndef CMDTEST
+#include "../comedi.h"
+#else
+#include "../comedi.h"
+#endif
+
+#define i8253_cascade_ns_to_timer i8253_cascade_ns_to_timer_2div
+
+static inline void i8253_cascade_ns_to_timer_2div_old(int i8253_osc_base,
+ unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+ int round_mode)
+{
+ int divider;
+ int div1, div2;
+ int div1_glb, div2_glb, ns_glb;
+ int div1_lub, div2_lub, ns_lub;
+ int ns;
+
+ divider = (*nanosec + i8253_osc_base / 2) / i8253_osc_base;
+
+ /* find 2 integers 1<={x,y}<=65536 such that x*y is
+ close to divider */
+
+ div1_lub = div2_lub = 0;
+ div1_glb = div2_glb = 0;
+
+ ns_glb = 0;
+ ns_lub = 0xffffffff;
+
+ div2 = 0x10000;
+ for (div1 = divider / 65536 + 1; div1 < div2; div1++) {
+ div2 = divider / div1;
+
+ ns = i8253_osc_base * div1 * div2;
+ if (ns <= *nanosec && ns > ns_glb) {
+ ns_glb = ns;
+ div1_glb = div1;
+ div2_glb = div2;
+ }
+
+ div2++;
+ if (div2 <= 65536) {
+ ns = i8253_osc_base * div1 * div2;
+ if (ns > *nanosec && ns < ns_lub) {
+ ns_lub = ns;
+ div1_lub = div1;
+ div2_lub = div2;
+ }
+ }
+ }
+
+ *nanosec = div1_lub * div2_lub * i8253_osc_base;
+ *d1 = div1_lub & 0xffff;
+ *d2 = div2_lub & 0xffff;
+ return;
+}
+
+static inline void i8253_cascade_ns_to_timer_power(int i8253_osc_base,
+ unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+ int round_mode)
+{
+ int div1, div2;
+ int base;
+
+ for (div1 = 2; div1 <= (1 << 16); div1 <<= 1) {
+ base = i8253_osc_base * div1;
+ round_mode &= TRIG_ROUND_MASK;
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ div2 = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ div2 = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ div2 = (*nanosec + base - 1) / base;
+ break;
+ }
+ if (div2 < 2)
+ div2 = 2;
+ if (div2 <= 65536) {
+ *nanosec = div2 * base;
+ *d1 = div1 & 0xffff;
+ *d2 = div2 & 0xffff;
+ return;
+ }
+ }
+
+ /* shouldn't get here */
+ div1 = 0x10000;
+ div2 = 0x10000;
+ *nanosec = div1 * div2 * i8253_osc_base;
+ *d1 = div1 & 0xffff;
+ *d2 = div2 & 0xffff;
+}
+
+static inline void i8253_cascade_ns_to_timer_2div(int i8253_osc_base,
+ unsigned int *d1, unsigned int *d2, unsigned int *nanosec,
+ int round_mode)
+{
+ unsigned int divider;
+ unsigned int div1, div2;
+ unsigned int div1_glb, div2_glb, ns_glb;
+ unsigned int div1_lub, div2_lub, ns_lub;
+ unsigned int ns;
+ unsigned int start;
+ unsigned int ns_low, ns_high;
+ static const unsigned int max_count = 0x10000;
+ /* exit early if everything is already correct (this can save time
+ * since this function may be called repeatedly during command tests
+ * and execution) */
+ div1 = *d1 ? *d1 : max_count;
+ div2 = *d2 ? *d2 : max_count;
+ divider = div1 * div2;
+ if (div1 * div2 * i8253_osc_base == *nanosec &&
+ div1 > 1 && div1 <= max_count &&
+ div2 > 1 && div2 <= max_count &&
+ /* check for overflow */
+ divider > div1 && divider > div2 &&
+ divider * i8253_osc_base > divider &&
+ divider * i8253_osc_base > i8253_osc_base) {
+ return;
+ }
+
+ divider = *nanosec / i8253_osc_base;
+
+ div1_lub = div2_lub = 0;
+ div1_glb = div2_glb = 0;
+
+ ns_glb = 0;
+ ns_lub = 0xffffffff;
+
+ div2 = max_count;
+ start = divider / div2;
+ if (start < 2)
+ start = 2;
+ for (div1 = start; div1 <= divider / div1 + 1 && div1 <= max_count;
+ div1++) {
+ for (div2 = divider / div1;
+ div1 * div2 <= divider + div1 + 1 && div2 <= max_count;
+ div2++) {
+ ns = i8253_osc_base * div1 * div2;
+ if (ns <= *nanosec && ns > ns_glb) {
+ ns_glb = ns;
+ div1_glb = div1;
+ div2_glb = div2;
+ }
+ if (ns >= *nanosec && ns < ns_lub) {
+ ns_lub = ns;
+ div1_lub = div1;
+ div2_lub = div2;
+ }
+ }
+ }
+
+ round_mode &= TRIG_ROUND_MASK;
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ ns_high = div1_lub * div2_lub * i8253_osc_base;
+ ns_low = div1_glb * div2_glb * i8253_osc_base;
+ if (ns_high - *nanosec < *nanosec - ns_low) {
+ div1 = div1_lub;
+ div2 = div2_lub;
+ } else {
+ div1 = div1_glb;
+ div2 = div2_glb;
+ }
+ break;
+ case TRIG_ROUND_UP:
+ div1 = div1_lub;
+ div2 = div2_lub;
+ break;
+ case TRIG_ROUND_DOWN:
+ div1 = div1_glb;
+ div2 = div2_glb;
+ break;
+ }
+
+ *nanosec = div1 * div2 * i8253_osc_base;
+ *d1 = div1 & 0xffff; // masking is done since counter maps zero to 0x10000
+ *d2 = div2 & 0xffff;
+ return;
+}
+
+#ifndef CMDTEST
+/* i8254_load programs 8254 counter chip. It should also work for the 8253.
+ * base_address is the lowest io address for the chip (the address of counter 0).
+ * counter_number is the counter you want to load (0,1 or 2)
+ * count is the number to load into the counter.
+ *
+ * You probably want to use mode 2.
+ *
+ * Use i8254_mm_load() if you board uses memory-mapped io, it is
+ * the same as i8254_load() except it uses writeb() instead of outb().
+ *
+ * Neither i8254_load() or i8254_read() do their loading/reading
+ * atomically. The 16 bit read/writes are performed with two successive
+ * 8 bit read/writes. So if two parts of your driver do a load/read on
+ * the same counter, it may be necessary to protect these functions
+ * with a spinlock.
+ *
+ * FMH
+ */
+
+#define i8254_control_reg 3
+
+static inline int i8254_load(unsigned long base_address, unsigned int regshift,
+ unsigned int counter_number, unsigned int count, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (count > 0xffff)
+ return -1;
+ if (mode > 5)
+ return -1;
+ if ((mode == 2 || mode == 3) && count == 1)
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= (mode << 1); // set counter mode
+ outb(byte, base_address + (i8254_control_reg << regshift));
+ byte = count & 0xff; // lsb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+
+ return 0;
+}
+
+static inline int i8254_mm_load(void *base_address, unsigned int regshift,
+ unsigned int counter_number, unsigned int count, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (count > 0xffff)
+ return -1;
+ if (mode > 5)
+ return -1;
+ if ((mode == 2 || mode == 3) && count == 1)
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= (mode << 1); // set counter mode
+ writeb(byte, base_address + (i8254_control_reg << regshift));
+ byte = count & 0xff; // lsb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+
+ return 0;
+}
+
+/* Returns 16 bit counter value, should work for 8253 also.*/
+static inline int i8254_read(unsigned long base_address, unsigned int regshift,
+ unsigned int counter_number)
+{
+ unsigned int byte;
+ int ret;
+
+ if (counter_number > 2)
+ return -1;
+
+ // latch counter
+ byte = counter_number << 6;
+ outb(byte, base_address + (i8254_control_reg << regshift));
+
+ // read lsb
+ ret = inb(base_address + (counter_number << regshift));
+ // read msb
+ ret += inb(base_address + (counter_number << regshift)) << 8;
+
+ return ret;
+}
+
+static inline int i8254_mm_read(void *base_address, unsigned int regshift,
+ unsigned int counter_number)
+{
+ unsigned int byte;
+ int ret;
+
+ if (counter_number > 2)
+ return -1;
+
+ // latch counter
+ byte = counter_number << 6;
+ writeb(byte, base_address + (i8254_control_reg << regshift));
+
+ // read lsb
+ ret = readb(base_address + (counter_number << regshift));
+ // read msb
+ ret += readb(base_address + (counter_number << regshift)) << 8;
+
+ return ret;
+}
+
+/* Loads 16 bit initial counter value, should work for 8253 also. */
+static inline void i8254_write(unsigned long base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int count)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return;
+
+ byte = count & 0xff; // lsb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ outb(byte, base_address + (counter_number << regshift));
+}
+
+static inline void i8254_mm_write(void *base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int count)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return;
+
+ byte = count & 0xff; // lsb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+ byte = (count >> 8) & 0xff; // msb of counter value
+ writeb(byte, base_address + (counter_number << regshift));
+}
+
+/* Set counter mode, should work for 8253 also.
+ * Note: the 'mode' value is different to that for i8254_load() and comes
+ * from the INSN_CONFIG_8254_SET_MODE command:
+ * I8254_MODE0, I8254_MODE1, ..., I8254_MODE5
+ * OR'ed with:
+ * I8254_BCD, I8254_BINARY
+ */
+static inline int i8254_set_mode(unsigned long base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (mode > (I8254_MODE5 | I8254_BINARY))
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= mode; // set counter mode and BCD|binary
+ outb(byte, base_address + (i8254_control_reg << regshift));
+
+ return 0;
+}
+
+static inline int i8254_mm_set_mode(void *base_address,
+ unsigned int regshift, unsigned int counter_number, unsigned int mode)
+{
+ unsigned int byte;
+
+ if (counter_number > 2)
+ return -1;
+ if (mode > (I8254_MODE5 | I8254_BINARY))
+ return -1;
+
+ byte = counter_number << 6;
+ byte |= 0x30; // load low then high byte
+ byte |= mode; // set counter mode and BCD|binary
+ writeb(byte, base_address + (i8254_control_reg << regshift));
+
+ return 0;
+}
+
+static inline int i8254_status(unsigned long base_address,
+ unsigned int regshift, unsigned int counter_number)
+{
+ outb(0xE0 | (2 << counter_number),
+ base_address + (i8254_control_reg << regshift));
+ return inb(base_address + (counter_number << regshift));
+}
+
+static inline int i8254_mm_status(void *base_address,
+ unsigned int regshift, unsigned int counter_number)
+{
+ writeb(0xE0 | (2 << counter_number),
+ base_address + (i8254_control_reg << regshift));
+ return readb(base_address + (counter_number << regshift));
+}
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/8255.c b/drivers/staging/comedi/drivers/8255.c
new file mode 100644
index 00000000000..0369c7c84ac
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8255.c
@@ -0,0 +1,442 @@
+/*
+ comedi/drivers/8255.c
+ Driver for 8255
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: 8255
+Description: generic 8255 support
+Devices: [standard] 8255 (8255)
+Author: ds
+Status: works
+Updated: Fri, 7 Jun 2002 12:56:45 -0700
+
+The classic in digital I/O. The 8255 appears in Comedi as a single
+digital I/O subdevice with 24 channels. The channel 0 corresponds
+to the 8255's port A, bit 0; channel 23 corresponds to port C, bit
+7. Direction configuration is done in blocks, with channels 0-7,
+8-15, 16-19, and 20-23 making up the 4 blocks. The only 8255 mode
+supported is mode 0.
+
+You should enable compilation this driver if you plan to use a board
+that has an 8255 chip. For multifunction boards, the main driver will
+configure the 8255 subdevice automatically.
+
+This driver also works independently with ISA and PCI cards that
+directly map the 8255 registers to I/O ports, including cards with
+multiple 8255 chips. To configure the driver for such a card, the
+option list should be a list of the I/O port bases for each of the
+8255 chips. For example,
+
+ comedi_config /dev/comedi0 8255 0x200,0x204,0x208,0x20c
+
+Note that most PCI 8255 boards do NOT work with this driver, and
+need a separate driver as a wrapper. For those that do work, the
+I/O port base address can be found in the output of 'lspci -v'.
+
+*/
+
+/*
+ This file contains an exported subdevice for driving an 8255.
+
+ To use this subdevice as part of another driver, you need to
+ set up the subdevice in the attach function of the driver by
+ calling:
+
+ subdev_8255_init(device, subdevice, callback_function, arg)
+
+ device and subdevice are pointers to the device and subdevice
+ structures. callback_function will be called to provide the
+ low-level input/output to the device, i.e., actual register
+ access. callback_function will be called with the value of arg
+ as the last parameter. If the 8255 device is mapped as 4
+ consecutive I/O ports, you can use NULL for callback_function
+ and the I/O port base for arg, and an internal function will
+ handle the register access.
+
+ In addition, if the main driver handles interrupts, you can
+ enable commands on the subdevice by calling subdev_8255_init_irq()
+ instead. Then, when you get an interrupt that is likely to be
+ from the 8255, you should call subdev_8255_interrupt(), which
+ will copy the latched value to a Comedi buffer.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define _8255_SIZE 4
+
+#define _8255_DATA 0
+#define _8255_CR 3
+
+#define CR_C_LO_IO 0x01
+#define CR_B_IO 0x02
+#define CR_B_MODE 0x04
+#define CR_C_HI_IO 0x08
+#define CR_A_IO 0x10
+#define CR_A_MODE(a) ((a)<<5)
+#define CR_CW 0x80
+
+struct subdev_8255_struct {
+ unsigned long cb_arg;
+ int (*cb_func) (int, int, int, unsigned long);
+ int have_irq;
+};
+
+#define CALLBACK_ARG (((struct subdev_8255_struct *)s->private)->cb_arg)
+#define CALLBACK_FUNC (((struct subdev_8255_struct *)s->private)->cb_func)
+#define subdevpriv ((struct subdev_8255_struct *)s->private)
+
+static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it);
+static int dev_8255_detach(struct comedi_device *dev);
+static struct comedi_driver driver_8255 = {
+ driver_name:"8255",
+ module:THIS_MODULE,
+ attach:dev_8255_attach,
+ detach:dev_8255_detach,
+};
+
+COMEDI_INITCLEANUP(driver_8255);
+
+static void do_config(struct comedi_device *dev, struct comedi_subdevice * s);
+
+void subdev_8255_interrupt(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ short d;
+
+ d = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
+ d |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
+
+ comedi_buf_put(s->async, d);
+ s->async->events |= COMEDI_CB_EOS;
+
+ comedi_event(dev, s);
+}
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+ unsigned long iobase = arg;
+
+ if (dir) {
+ outb(data, iobase + port);
+ return 0;
+ } else {
+ return inb(iobase + port);
+ }
+}
+
+static int subdev_8255_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ if (data[0] & 0xff)
+ CALLBACK_FUNC(1, _8255_DATA, s->state & 0xff,
+ CALLBACK_ARG);
+ if (data[0] & 0xff00)
+ CALLBACK_FUNC(1, _8255_DATA + 1, (s->state >> 8) & 0xff,
+ CALLBACK_ARG);
+ if (data[0] & 0xff0000)
+ CALLBACK_FUNC(1, _8255_DATA + 2,
+ (s->state >> 16) & 0xff, CALLBACK_ARG);
+ }
+
+ data[1] = CALLBACK_FUNC(0, _8255_DATA, 0, CALLBACK_ARG);
+ data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 1, 0, CALLBACK_ARG) << 8);
+ data[1] |= (CALLBACK_FUNC(0, _8255_DATA + 2, 0, CALLBACK_ARG) << 16);
+
+ return 2;
+}
+
+static int subdev_8255_insn_config(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+ unsigned int bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x0000ff) {
+ bits = 0x0000ff;
+ } else if (mask & 0x00ff00) {
+ bits = 0x00ff00;
+ } else if (mask & 0x0f0000) {
+ bits = 0x0f0000;
+ } else {
+ bits = 0xf00000;
+ }
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ do_config(dev, s);
+
+ return 1;
+}
+
+static void do_config(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ int config;
+
+ config = CR_CW;
+ /* 1 in io_bits indicates output, 1 in config indicates input */
+ if (!(s->io_bits & 0x0000ff))
+ config |= CR_A_IO;
+ if (!(s->io_bits & 0x00ff00))
+ config |= CR_B_IO;
+ if (!(s->io_bits & 0x0f0000))
+ config |= CR_C_LO_IO;
+ if (!(s->io_bits & 0xf00000))
+ config |= CR_C_HI_IO;
+ CALLBACK_FUNC(1, _8255_CR, config, CALLBACK_ARG);
+}
+
+static int subdev_8255_cmdtest(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1 */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2 */
+
+ if (err)
+ return 2;
+
+ /* step 3 */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4 */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int subdev_8255_cmd(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+static int subdev_8255_cancel(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+int subdev_8255_init(struct comedi_device *dev, struct comedi_subdevice * s, int (*cb) (int,
+ int, int, unsigned long), unsigned long arg)
+{
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 24;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+
+ s->private = kmalloc(sizeof(struct subdev_8255_struct), GFP_KERNEL);
+ if (!s->private)
+ return -ENOMEM;
+
+ CALLBACK_ARG = arg;
+ if (cb == NULL) {
+ CALLBACK_FUNC = subdev_8255_cb;
+ } else {
+ CALLBACK_FUNC = cb;
+ }
+ s->insn_bits = subdev_8255_insn;
+ s->insn_config = subdev_8255_insn_config;
+
+ s->state = 0;
+ s->io_bits = 0;
+ do_config(dev, s);
+
+ return 0;
+}
+
+int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg)
+{
+ int ret;
+
+ ret = subdev_8255_init(dev, s, cb, arg);
+ if (ret < 0)
+ return ret;
+
+ s->do_cmdtest = subdev_8255_cmdtest;
+ s->do_cmd = subdev_8255_cmd;
+ s->cancel = subdev_8255_cancel;
+
+ subdevpriv->have_irq = 1;
+
+ return 0;
+}
+
+void subdev_8255_cleanup(struct comedi_device *dev, struct comedi_subdevice * s)
+{
+ if (s->private) {
+ if (subdevpriv->have_irq) {
+ }
+
+ kfree(s->private);
+ }
+}
+
+/*
+
+ Start of the 8255 standalone device
+
+ */
+
+static int dev_8255_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ int i;
+
+ printk("comedi%d: 8255:", dev->minor);
+
+ dev->board_name = "8255";
+
+ for (i = 0; i < COMEDI_NDEVCONFOPTS; i++) {
+ iobase = it->options[i];
+ if (!iobase)
+ break;
+ }
+ if (i == 0) {
+ printk(" no devices specified\n");
+ return -EINVAL;
+ }
+
+ if ((ret = alloc_subdevices(dev, i)) < 0)
+ return ret;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ iobase = it->options[i];
+
+ printk(" 0x%04lx", iobase);
+ if (!request_region(iobase, _8255_SIZE, "8255")) {
+ printk(" (I/O port conflict)");
+
+ dev->subdevices[i].type = COMEDI_SUBD_UNUSED;
+ } else {
+ subdev_8255_init(dev, dev->subdevices + i, NULL,
+ iobase);
+ }
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int dev_8255_detach(struct comedi_device *dev)
+{
+ int i;
+ unsigned long iobase;
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: 8255: remove\n", dev->minor);
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ s = dev->subdevices + i;
+ if (s->type != COMEDI_SUBD_UNUSED) {
+ iobase = CALLBACK_ARG;
+ release_region(iobase, _8255_SIZE);
+ }
+ subdev_8255_cleanup(dev, s);
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(subdev_8255_init);
+EXPORT_SYMBOL(subdev_8255_init_irq);
+EXPORT_SYMBOL(subdev_8255_cleanup);
+EXPORT_SYMBOL(subdev_8255_interrupt);
diff --git a/drivers/staging/comedi/drivers/8255.h b/drivers/staging/comedi/drivers/8255.h
new file mode 100644
index 00000000000..979311b9927
--- /dev/null
+++ b/drivers/staging/comedi/drivers/8255.h
@@ -0,0 +1,57 @@
+/*
+ module/8255.h
+ Header file for 8255
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _8255_H
+#define _8255_H
+
+#include "../comedidev.h"
+
+#if defined(CONFIG_COMEDI_8255) || defined(CONFIG_COMEDI_8255_MODULE)
+
+int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg);
+int subdev_8255_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg);
+void subdev_8255_cleanup(struct comedi_device * dev, struct comedi_subdevice * s);
+void subdev_8255_interrupt(struct comedi_device * dev, struct comedi_subdevice * s);
+
+#else
+
+static inline int subdev_8255_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *x, unsigned long y)
+{
+ printk("8255 support not configured -- disabling subdevice\n");
+
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
+}
+
+static inline void subdev_8255_cleanup(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+}
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile
index eb7a615e085..12d6e4312f3 100644
--- a/drivers/staging/comedi/drivers/Makefile
+++ b/drivers/staging/comedi/drivers/Makefile
@@ -8,12 +8,121 @@ obj-$(CONFIG_COMEDI) += comedi_test.o
obj-$(CONFIG_COMEDI) += comedi_parport.o
# Comedi PCI drivers
-obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mite.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += 8255.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += acl7225b.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_035.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1032.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1500.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1516.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_1564.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_16xx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2016.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2032.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_2200.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3001.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3120.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3501.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += addi_apci_3xxx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci6208.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7296.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci7432.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci8164.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9111.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adl_pci9118.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adq12b.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1710.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci1723.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += adv_pci_dio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_aio12_8.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += aio_iiro_16.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_dio200.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc236.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pc263.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci224.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += amplc_pci230.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += c6xdigio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas64.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidas.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidda.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcidio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdas.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += cb_pcimdda.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_bond.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_parport.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += comedi_test.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += contec_pci_dio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += daqboard2000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das08.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16m1.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das16.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das1800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das6402.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += das800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dmm32at.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2801.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2811.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2814.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2815.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt2817.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt282x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += dt3000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += fl512.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += gsc_hpdi.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += icp_multi.o
-obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me_daq.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ii_pci20kc.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += jr3_pci.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ke_counter.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me4000.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += me_daq.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mite.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += mpc624.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += multiq3.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_6527.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_65xx.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_660x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_670x.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_a2150.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_at_ao.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio16d.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_atmio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_labpc.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcidio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_pcimio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tiocmd.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ni_tio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl711.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl724.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl725.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl726.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl730.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl812.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl816.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcl818.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3724.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcm3730.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmad.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmda12.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmmio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += pcmuio.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += poc.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rtd520.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti800.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += rti802.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s526.o
obj-$(CONFIG_COMEDI_PCI_DRIVERS) += s626.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += serial2002.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += skel.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += ssv_dnp.o
+obj-$(CONFIG_COMEDI_PCI_DRIVERS) += unioxx5.o
+
+# Comedi PCMCIA drivers
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += cb_das16_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += das08_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_700.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_daq_dio24.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_labpc_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += ni_mio_cs.o
+obj-$(CONFIG_COMEDI_PCMCIA_DRIVERS) += quatech_daqp_cs.o
# Comedi USB drivers
obj-$(CONFIG_COMEDI_USB_DRIVERS) += usbdux.o
diff --git a/drivers/staging/comedi/drivers/acl7225b.c b/drivers/staging/comedi/drivers/acl7225b.c
new file mode 100644
index 00000000000..b21320f0959
--- /dev/null
+++ b/drivers/staging/comedi/drivers/acl7225b.c
@@ -0,0 +1,149 @@
+/*
+ * comedi/drivers/acl7225b.c
+ * Driver for Adlink NuDAQ ACL-7225b and clones
+ * José Luis Sánchez
+ */
+/*
+Driver: acl7225b
+Description: Adlink NuDAQ ACL-7225b & compatibles
+Author: José Luis Sánchez (jsanchezv@teleline.es)
+Status: testing
+Devices: [Adlink] ACL-7225b (acl7225b), [ICP] P16R16DIO (p16r16dio)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define ACL7225_SIZE 8 /* Requires 8 ioports, but only 4 are used */
+#define P16R16DIO_SIZE 4
+#define ACL7225_RIO_LO 0 /* Relays input/output low byte (R0-R7) */
+#define ACL7225_RIO_HI 1 /* Relays input/output high byte (R8-R15) */
+#define ACL7225_DI_LO 2 /* Digital input low byte (DI0-DI7) */
+#define ACL7225_DI_HI 3 /* Digital input high byte (DI8-DI15) */
+
+static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it);
+static int acl7225b_detach(struct comedi_device *dev);
+
+struct boardtype {
+ const char *name; // driver name
+ int io_range; // len of I/O space
+};
+
+static const struct boardtype boardtypes[] = {
+ {"acl7225b", ACL7225_SIZE,},
+ {"p16r16dio", P16R16DIO_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+#define this_board ((const struct boardtype *)dev->board_ptr)
+
+static struct comedi_driver driver_acl7225b = {
+ driver_name:"acl7225b",
+ module:THIS_MODULE,
+ attach:acl7225b_attach,
+ detach:acl7225b_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct boardtype),
+};
+
+COMEDI_INITCLEANUP(driver_acl7225b);
+
+static int acl7225b_do_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ }
+ if (data[0] & 0x00ff)
+ outb(s->state & 0xff, dev->iobase + (unsigned long)s->private);
+ if (data[0] & 0xff00)
+ outb((s->state >> 8),
+ dev->iobase + (unsigned long)s->private + 1);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int acl7225b_di_insn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + (unsigned long)s->private) |
+ (inb(dev->iobase + (unsigned long)s->private + 1) << 8);
+
+ return 2;
+}
+
+static int acl7225b_attach(struct comedi_device *dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int iobase, iorange;
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ printk("comedi%d: acl7225b: board=%s 0x%04x ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "acl7225b")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->board_name = this_board->name;
+ dev->iobase = iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* Relays outputs */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_do_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_RIO_LO;
+
+ s = dev->subdevices + 1;
+ /* Relays status */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_RIO_LO;
+
+ s = dev->subdevices + 2;
+ /* Isolated digital inputs */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = acl7225b_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)ACL7225_DI_LO;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int acl7225b_detach(struct comedi_device *dev)
+{
+ printk("comedi%d: acl7225b: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
new file mode 100644
index 00000000000..c96aee09e1b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.c
@@ -0,0 +1,1047 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+/*
+ | Description : APCI-1710 82X54 timer module |
+*/
+
+#include "APCI1710_82x54.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitTimer |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| BYTE_ b_TimerMode, |
+| ULONG_ ul_ReloadValue, |
+| BYTE_ b_InputClockSelection, |
+| BYTE_ b_InputClockLevel, |
+| BYTE_ b_OutputLevel, |
+| BYTE_ b_HardwareGateLevel)
+INT i_InsnConfig_InitTimer(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data)
+|
++----------------------------------------------------------------------------+
+| Task : Configure the Timer (b_TimerNbr) operating mode |
+| (b_TimerMode) from selected module (b_ModulNbr). |
+| You must calling this function be for you call any |
+| other function witch access of the timer. |
+| |
+| |
+| Timer mode description table |
+| |
+|+--------+-----------------------------+--------------+--------------------+|
+||Selected+ Mode description +u_ReloadValue | Hardware gate input||
+|| mode | | description | action ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 0 is typically used | | ||
+|| |for event counting. After | | ||
+|| |the initialisation, OUT | | ||
+|| |is initially low, and | | ||
+|| 0 |will remain low until the |Start counting| Hardware gate ||
+|| |counter reaches zero. | value | ||
+|| |OUT then goes high and | | ||
+|| |remains high until a new | | ||
+|| |count is written. See | | ||
+|| |"i_APCI1710_WriteTimerValue" | | ||
+|| |function. | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 1 is similar to mode 0 | | ||
+|| |except for the gate input | | ||
+|| 1 |action. The gate input is not|Start counting| Hardware trigger ||
+|| |used for enabled or disabled | value | ||
+|| |the timer. | | ||
+|| |The gate input is used for | | ||
+|| |triggered the timer. | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |This mode functions like a | | ||
+|| |divide-by-ul_ReloadValue | | ||
+|| |counter. It is typically used| | ||
+|| |to generate a real time clock| | ||
+|| |interrupt. OUT will initially| | ||
+|| 2 |be high after the | Division | Hardware gate ||
+|| |initialisation. When the | factor | ||
+|| |initial count has decremented| | ||
+|| |to 1, OUT goes low for one | | ||
+|| |CLK pule. OUT then goes high | | ||
+|| |again, the counter reloads | | ||
+|| |the initial count | | ||
+|| |(ul_ReloadValue) and the | | ||
+|| |process is repeated. | | ||
+|| |This action can generated a | | ||
+|| |interrupt. See function | | ||
+|| |"i_APCI1710_SetBoardInt- | | ||
+|| |RoutineX" | | ||
+|| |and "i_APCI1710_EnableTimer" | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 3 is typically used for | | ||
+|| |baud rate generation. This | | ||
+|| |mode is similar to mode 2 | | ||
+|| |except for the duty cycle of | | ||
+|| 3 |OUT. OUT will initially be | Division | Hardware gate ||
+|| |high after the initialisation| factor | ||
+|| |When half the initial count | | ||
+|| |(ul_ReloadValue) has expired,| | ||
+|| |OUT goes low for the | | ||
+|| |remainder of the count. The | | ||
+|| |mode is periodic; the | | ||
+|| |sequence above is repeated | | ||
+|| |indefinitely. | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |OUT will be initially high | | ||
+|| |after the initialisation. | | ||
+|| |When the initial count | | ||
+|| 4 |expires OUT will go low for |Start counting| Hardware gate ||
+|| |one CLK pulse and then go | value | ||
+|| |high again. | | ||
+|| |The counting sequences is | | ||
+|| |triggered by writing a new | | ||
+|| |value. See | | ||
+|| |"i_APCI1710_WriteTimerValue" | | ||
+|| |function. If a new count is | | ||
+|| |written during counting, | | ||
+|| |it will be loaded on the | | ||
+|| |next CLK pulse | | ||
+|+--------+-----------------------------+--------------+--------------------+|
+|| |Mode 5 is similar to mode 4 | | ||
+|| |except for the gate input | | ||
+|| |action. The gate input is not| | ||
+|| 5 |used for enabled or disabled |Start counting| Hardware trigger ||
+|| |the timer. The gate input is | value | ||
+|| |used for triggered the timer.| | ||
+|+--------+-----------------------------+--------------+--------------------+|
+| |
+| |
+| |
+| Input clock selection table |
+| |
+| +--------------------------------+------------------------------------+ |
+| | b_InputClockSelection | Description | |
+| | parameter | | |
+| +--------------------------------+------------------------------------+ |
+| | APCI1710_PCI_BUS_CLOCK | For the timer input clock, the PCI | |
+| | | bus clock / 4 is used. This PCI bus| |
+| | | clock can be 30MHz or 33MHz. For | |
+| | | Timer 0 only this selection are | |
+| | | available. | |
+| +--------------------------------+------------------------------------+ |
+| | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the| |
+| | | possibility to inject a input clock| |
+| | | for Timer 1 or Timer 2. The source | |
+| | | from this clock can eat the output | |
+| | | clock from Timer 0 or any other | |
+| | | clock source. | |
+| +--------------------------------+------------------------------------+ |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to |
+| configure (0 to 2) |
+| BYTE_ b_TimerMode : Timer mode selection |
+| (0 to 5) |
+| 0: Interrupt on terminal|
+| count |
+| 1: Hardware |
+| retriggerable one- |
+| shot |
+| 2: Rate generator |
+| 3: Square wave mode |
+| 4: Software triggered |
+| strobe |
+| 5: Hardware triggered |
+| strobe |
+| See timer mode |
+| description table. |
+| ULONG_ ul_ReloadValue : Start counting value |
+| or division factor |
+| See timer mode |
+| description table. |
+| BYTE_ b_InputClockSelection : Selection from input |
+| timer clock. |
+| See input clock |
+| selection table. |
+| BYTE_ b_InputClockLevel : Selection from input |
+| clock level. |
+| 0 : Low active |
+| (Input inverted) |
+| 1 : High active |
+| BYTE_ b_OutputLevel, : Selection from output |
+| clock level. |
+| 0 : Low active |
+| 1 : High active |
+| (Output inverted) |
+| BYTE_ b_HardwareGateLevel : Selection from |
+| hardware gate level. |
+| 0 : Low active |
+| (Input inverted) |
+| 1 : High active |
+| If you will not used |
+| the hardware gate set |
+| this value to 0.
+|b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_TimerMode = (BYTE) data[0];
+ ul_ReloadValue = (ULONG) data[1];
+ b_InputClockSelection =(BYTE) data[2];
+ b_InputClockLevel =(BYTE) data[3];
+ b_OutputLevel =(BYTE) data[4];
+ b_HardwareGateLevel =(BYTE) data[5];
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer mode selection is wrong |
+| -6: Input timer clock selection is wrong |
+| -7: Selection from input clock level is wrong |
+| -8: Selection from output clock level is wrong |
+| -9: Selection from hardware gate level is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr;
+ BYTE b_TimerNbr;
+ BYTE b_TimerMode;
+ ULONG ul_ReloadValue;
+ BYTE b_InputClockSelection;
+ BYTE b_InputClockLevel;
+ BYTE b_OutputLevel;
+ BYTE b_HardwareGateLevel;
+
+ //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ DWORD dw_Test = 0;
+ //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_TimerMode = (BYTE) data[0];
+ ul_ReloadValue = (ULONG) data[1];
+ b_InputClockSelection = (BYTE) data[2];
+ b_InputClockLevel = (BYTE) data[3];
+ b_OutputLevel = (BYTE) data[4];
+ b_HardwareGateLevel = (BYTE) data[5];
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+
+ if (b_TimerNbr <= 2) {
+ /* Test the timer mode */
+ if (b_TimerMode <= 5) {
+ //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ /* Test te imput clock selection */
+ /*
+ if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) ||
+ ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1))))
+ */
+
+ if (((b_TimerNbr == 0) &&
+ (b_InputClockSelection == APCI1710_PCI_BUS_CLOCK)) ||
+ ((b_TimerNbr == 0) &&
+ (b_InputClockSelection == APCI1710_10MHZ)) ||
+ ((b_TimerNbr != 0) &&
+ ((b_InputClockSelection == APCI1710_PCI_BUS_CLOCK) ||
+ (b_InputClockSelection == APCI1710_FRONT_CONNECTOR_INPUT) ||
+ (b_InputClockSelection == APCI1710_10MHZ)))) {
+ //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ if (((b_InputClockSelection == APCI1710_10MHZ) &&
+ ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) ||
+ (b_InputClockSelection != APCI1710_10MHZ)) {
+ //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz
+ /* Test the input clock level selection */
+
+ if ((b_InputClockLevel == 0) ||
+ (b_InputClockLevel == 1)) {
+ /* Test the output clock level selection */
+ if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) {
+ /* Test the hardware gate level selection */
+ if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) {
+ //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ /* Test if version > 1.1 and clock selection = 10MHz */
+ if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) {
+ /* Test if 40MHz quartz on board */
+ dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)));
+
+ dw_Test = (dw_Test >> 16) & 1;
+ } else {
+ dw_Test = 1;
+ }
+
+ /* Test if detection OK */
+ if (dw_Test == 1) {
+ //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ /* Initialisation OK */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1;
+
+ /* Save the input clock selection */
+ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection;
+
+ /* Save the input clock level */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1;
+
+ /* Save the output level */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1;
+
+ /* Save the gate level */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel;
+
+ /* Set the configuration word and disable the timer */
+ //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ /*
+ devpriv->s_ModuleInfo [b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo [b_TimerNbr].
+ dw_ConfigurationWord = (DWORD) (((b_HardwareGateLevel << 0) & 0x1) |
+ ((b_InputClockLevel << 1) & 0x2) |
+ (((~b_OutputLevel & 1) << 2) & 0x4) |
+ ((b_InputClockSelection << 4) & 0x10));
+ */
+ /* Test if 10MHz selected */
+ if (b_InputClockSelection == APCI1710_10MHZ) {
+ b_InputClockSelection = 2;
+ }
+
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (DWORD)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30));
+ //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Initialise the 82X54 Timer */
+ outl((DWORD) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Write the reload value */
+ outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ } // if (dw_Test == 1)
+ else {
+ /* Input timer clock selection is wrong */
+ i_ReturnValue = -6;
+ } // if (dw_Test == 1)
+ //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz
+ } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
+ else {
+ /* Selection from hardware gate level is wrong */
+ DPRINTK("Selection from hardware gate level is wrong\n");
+ i_ReturnValue = -9;
+ } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1))
+ } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
+ else {
+ /* Selection from output clock level is wrong */
+ DPRINTK("Selection from output clock level is wrong\n");
+ i_ReturnValue = -8;
+ } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1))
+ } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
+ else {
+ /* Selection from input clock level is wrong */
+ DPRINTK("Selection from input clock level is wrong\n");
+ i_ReturnValue = -7;
+ } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1))
+ } else {
+ /* Input timer clock selection is wrong */
+ DPRINTK("Input timer clock selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /* Input timer clock selection is wrong */
+ DPRINTK("Input timer clock selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
+ else {
+ /* Timer mode selection is wrong */
+ DPRINTK("Timer mode selection is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5))
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableTimer |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| BYTE_ b_InterruptEnable)
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Enable OR Disable the Timer (b_TimerNbr) from selected module |
+| (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitTimer" function be for you call this |
+| function. If you enable the timer interrupt, the timer |
+| generate a interrupt after the timer value reach |
+| the zero. See function "i_APCI1710_SetBoardIntRoutineX"|
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to enable |
+| (0 to 2) |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| timer interrupt. |
+| APCI1710_ENABLE : |
+| Enable the timer interrupt |
+| APCI1710_DISABLE : |
+| Disable the timer interrupt|
+i_ReturnValue=insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_ActionType = (BYTE) data[0]; // enable disable
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
+| -6: Interrupt parameter is wrong |
+| -7: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device * dev,
+ struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_DummyRead;
+ BYTE b_ModulNbr;
+ BYTE b_TimerNbr;
+ BYTE b_ActionType;
+ BYTE b_InterruptEnable;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec);
+ b_ActionType = (BYTE) data[0]; // enable disable
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+
+ switch (b_ActionType) {
+ case APCI1710_ENABLE:
+ b_InterruptEnable = (BYTE) data[1];
+ /* Test the interrupt selection */
+ if ((b_InterruptEnable == APCI1710_ENABLE) ||
+ (b_InterruptEnable == APCI1710_DISABLE)) {
+ if (b_InterruptEnable == APCI1710_ENABLE) {
+
+ dw_DummyRead = inl(devpriv->s_BoardInfos.ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Enable the interrupt */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord | 0x8;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ } // if (b_InterruptEnable == APCI1710_ENABLE)
+ else {
+ /* Disable the interrupt */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Save the interrupt flag */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
+ } // if (b_InterruptEnable == APCI1710_ENABLE)
+
+ /* Test if error occur */
+ if (i_ReturnValue >= 0) {
+ /* Save the interrupt flag */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr);
+
+ /* Enable the timer */
+ outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ }
+ } else {
+ /* Interrupt parameter is wrong */
+ DPRINTK("\n");
+ i_ReturnValue = -6;
+ }
+ break;
+ case APCI1710_DISABLE:
+ /* Test the interrupt flag */
+ if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) {
+ /* Disable the interrupt */
+
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr]. dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ /* Save the interrupt flag */
+ devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr));
+ }
+
+ /* Disable the timer */
+ outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ break;
+ } // Switch end
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK ("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadAllTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PULONG_ pul_TimerValueArray)
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the all timer values from selected timer |
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_TimerValueArray : Timer value array. |
+| Element 0 contain the timer 0 value. |
+| Element 1 contain the timer 1 value. |
+| Element 2 contain the timer 2 value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a TIMER module |
+| -4: Timer 0 not initialised see function |
+| "i_APCI1710_InitTimer" |
+| -5: Timer 1 not initialised see function |
+| "i_APCI1710_InitTimer" |
+| -6: Timer 2 not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr, b_ReadType;
+ PULONG pul_TimerValueArray;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ReadType = CR_CHAN(insn->chanspec);
+ pul_TimerValueArray = (PULONG) data;
+ i_ReturnValue = insn->n;
+
+ switch (b_ReadType) {
+ case APCI1710_TIMER_READINTERRUPT:
+
+ data[0] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /* Increment the read FIFO */
+ devpriv->s_InterruptParameters.ui_Read = (devpriv->s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ break;
+
+ case APCI1710_TIMER_READALLTIMER:
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test if timer 0 iniutialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) {
+ /* Test if timer 1 iniutialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) {
+ /* Test if timer 2 iniutialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) {
+ /* Latch all counter */
+ outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ /* Read the timer 0 value */
+ pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr));
+
+ /* Read the timer 1 value */
+ pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+
+ /* Read the timer 2 value */
+ pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr));
+ } else {
+ /* Timer 2 not initialised see function */
+ DPRINTK("Timer 2 not initialised see function\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /* Timer 1 not initialised see function */
+ DPRINTK("Timer 1 not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer 0 not initialised see function */
+ DPRINTK("Timer 0 not initialised see function\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ } // End of Switch
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read write functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_BitsType;
+ INT i_ReturnValue = 0;
+ b_BitsType = data[0];
+
+ printk("\n82X54");
+
+ switch (b_BitsType) {
+ case APCI1710_TIMER_READVALUE:
+ i_ReturnValue = i_APCI1710_ReadTimerValue(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (PULONG) & data[0]);
+ break;
+
+ case APCI1710_TIMER_GETOUTPUTLEVEL:
+ i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (PBYTE) &data[0]);
+ break;
+
+ case APCI1710_TIMER_GETPROGRESSSTATUS:
+ i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (PBYTE)&data[0]);
+ break;
+
+ case APCI1710_TIMER_WRITEVALUE:
+ i_ReturnValue = i_APCI1710_WriteTimerValue(dev,
+ (BYTE)CR_AREF(insn->chanspec),
+ (BYTE)CR_CHAN(insn->chanspec),
+ (ULONG)data[1]);
+
+ break;
+
+ default:
+ printk("Bits Config Parameter Wrong\n");
+ i_ReturnValue = -1;
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| PULONG_ pul_TimerValue) |
++----------------------------------------------------------------------------+
+| Task : Return the timer value from selected digital timer |
+| (b_TimerNbr) from selected timer module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to read |
+| (0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_TimerValue : Timer value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadTimerValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PULONG pul_TimerValue)
+{
+ INT i_ReturnValue = 0;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_82X54ModuleInfo.
+ s_82X54TimerInfo[b_TimerNbr].
+ b_82X54Init == 1) {
+ /* Latch the timer value */
+ outl((2 << b_TimerNbr) | 0xD0,
+ devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (64 * b_ModulNbr));
+
+ /* Read the counter value */
+ *pul_TimerValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + (b_TimerNbr * 4) +
+ (64 * b_ModulNbr));
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_GetTimerOutputLevel |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | BYTE_ b_TimerNbr, |
+ | PBYTE_ pb_OutputLevel) |
+ +----------------------------------------------------------------------------+
+ | Task : Return the output signal level (pb_OutputLevel) from |
+ | selected digital timer (b_TimerNbr) from selected timer|
+ | module (b_ModulNbr). |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+ | APCI-1710 |
+ | BYTE_ b_ModulNbr : Selected module number |
+ | (0 to 3) |
+ | BYTE_ b_TimerNbr : Timer number to test |
+ | (0 to 2) |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : PBYTE_ pb_OutputLevel : Output signal level |
+ | 0 : The output is low |
+ | 1 : The output is high |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: Module selection wrong |
+ | -3: Timer selection wrong |
+ | -4: The module is not a TIMER module |
+ | -5: Timer not initialised see function |
+ | "i_APCI1710_InitTimer" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_GetTimerOutputLevel(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_OutputLevel)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_TimerStatus;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+ /* Latch the timer value */
+ outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ /* Read the timer status */
+ dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ *pb_OutputLevel = (BYTE) (((dw_TimerStatus >> 7) & 1) ^ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel);
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetTimerProgressStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| PBYTE_ pb_TimerStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the progress status (pb_TimerStatus) from |
+| selected digital timer (b_TimerNbr) from selected timer|
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to test |
+| (0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimerStatus : Output signal level |
+| 0 : Timer not in progress |
+| 1 : Timer in progress |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_TimerStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_TimerStatus;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+ /* Latch the timer value */
+ outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ /* Read the timer status */
+ dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+
+ *pb_TimerStatus = (BYTE) ((dw_TimerStatus) >> 8) & 1;
+ printk("ProgressStatus : %d", *pb_TimerStatus);
+ } else {
+ /* Timer not initialised see function */
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+
+ i_ReturnValue = -2;
+ }
+
+ return i_ReturnValue;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_WriteTimerValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TimerNbr, |
+| ULONG_ ul_WriteValue) |
++----------------------------------------------------------------------------+
+| Task : Write the value (ul_WriteValue) into the selected timer|
+| (b_TimerNbr) from selected timer module (b_ModulNbr). |
+| The action in depend of the time mode selection. |
+| See timer mode description table. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board |
+| APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_TimerNbr : Timer number to write |
+| (0 to 2) |
+| ULONG_ ul_WriteValue : Value to write |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: Timer selection wrong |
+| -4: The module is not a TIMER module |
+| -5: Timer not initialised see function |
+| "i_APCI1710_InitTimer" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_WriteTimerValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ ULONG ul_WriteValue)
+{
+ INT i_ReturnValue = 0;
+
+ /* Test the module number */
+ if (b_ModulNbr < 4) {
+ /* Test if 82X54 timer */
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+ /* Test the timer number */
+ if (b_TimerNbr <= 2) {
+ /* Test if timer initialised */
+ if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) {
+ /* Write the value */
+ outl(ul_WriteValue, devpriv->s_BoardInfos.ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr));
+ } else {
+ /* Timer not initialised see function */
+ DPRINTK("Timer not initialised see function\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /* Timer selection wrong */
+ DPRINTK("Timer selection wrong\n");
+ i_ReturnValue = -3;
+ } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2))
+ } else {
+ /* The module is not a TIMER module */
+ DPRINTK("The module is not a TIMER module\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /* Module number error */
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return i_ReturnValue;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
new file mode 100644
index 00000000000..4797c0b77a4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_82x54.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_PCI_BUS_CLOCK 0
+#define APCI1710_FRONT_CONNECTOR_INPUT 1
+#define APCI1710_TIMER_READVALUE 0
+#define APCI1710_TIMER_GETOUTPUTLEVEL 1
+#define APCI1710_TIMER_GETPROGRESSSTATUS 2
+#define APCI1710_TIMER_WRITEVALUE 3
+
+#define APCI1710_TIMER_READINTERRUPT 1
+#define APCI1710_TIMER_READALLTIMER 2
+
+/* BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
+#ifndef APCI1710_10MHZ
+#define APCI1710_10MHZ 10
+#endif
+/* END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz */
+
+/*
+ * 82X54 TIMER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableTimer(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * 82X54 READ FUNCTION
+ */
+INT i_APCI1710_InsnReadAllTimerValue(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * 82X54 READ & WRITE FUNCTION
+ */
+INT i_APCI1710_ReadTimerValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PULONG pul_TimerValue);
+
+INT i_APCI1710_GetTimerOutputLevel(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_OutputLevel);
+
+INT i_APCI1710_GetTimerProgressStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ PBYTE pb_TimerStatus);
+
+/*
+ * 82X54 WRITE FUNCTION
+ */
+INT i_APCI1710_WriteTimerValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_TimerNbr,
+ ULONG ul_WriteValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
new file mode 100644
index 00000000000..1a54d3b2c69
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.c
@@ -0,0 +1,2032 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : CHRONO.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 chronometer module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 29/06/98 | S. Weber | Digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | | | |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "APCI1710_Chrono.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitChrono |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ChronoMode, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_TimingInterval, |
+| PULONG_ pul_RealTimingInterval)
+
++----------------------------------------------------------------------------+
+| Task : Configure the chronometer operating mode (b_ChronoMode)|
+| from selected module (b_ModulNbr). |
+| The ul_TimingInterval and ul_TimingUnit determine the |
+| timing base for the measurement. |
+| The pul_RealTimingInterval return the real timing |
+| value. You must calling this function be for you call |
+| any other function witch access of the chronometer. |
+| |
+| Witch this functionality from the APCI-1710 you have |
+| the possibility to measure the timing witch two event. |
+| |
+| The mode 0 and 1 is appropriate for period measurement.|
+| The mode 2 and 3 is appropriate for frequent |
+| measurement. |
+| The mode 4 to 7 is appropriate for measuring the timing|
+| between two event. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr CR_AREF(insn->chanspec) : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ChronoMode data[0] : Chronometer action mode |
+| (0 to 7). |
+| BYTE_ b_PCIInputClock data[1] : Selection from PCI bus clock|
+| - APCI1710_30MHZ : |
+| The PC have a PCI bus |
+| clock from 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC have a PCI bus |
+| clock from 33 MHz |
+| - APCI1710_40MHZ |
+| The APCI-1710 have a |
+| integrated 40Mhz |
+| quartz. |
+| BYTE_ b_TimingUnit data[2] : Base timing unity (0 to 4) |
+| 0 : ns |
+| 1 : µs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_TimingInterval : data[3] Base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |
+| value.
+| data[0]
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer mode selection is wrong |
+| -5: The selected PCI input clock is wrong |
+| -6: Timing unity selection is wrong |
+| -7: Base timing selection is wrong |
+| -8: You can not used the 40MHz clock selection wich |
+| this board |
+| -9: You can not used the 40MHz clock selection wich |
+| this CHRONOS version |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitChrono(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_TimerValue = 0;
+ ULONG ul_TimingInterval = 0;
+ ULONG ul_RealTimingInterval = 0;
+ double d_RealTimingInterval = 0;
+ DWORD dw_ModeArray[8] =
+ { 0x01, 0x05, 0x00, 0x04, 0x02, 0x0E, 0x0A, 0x06 };
+ BYTE b_ModulNbr, b_ChronoMode, b_PCIInputClock, b_TimingUnit;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ChronoMode = (BYTE) data[0];
+ b_PCIInputClock = (BYTE) data[1];
+ b_TimingUnit = (BYTE) data[2];
+ ul_TimingInterval = (ULONG) data[3];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /*****************************/
+ /* Test the chronometer mode */
+ /*****************************/
+
+ if (b_ChronoMode <= 7) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ)) {
+ /*************************/
+ /* Test the timing unity */
+ /*************************/
+
+ if (b_TimingUnit <= 4) {
+ /**********************************/
+ /* Test the base timing selection */
+ /**********************************/
+
+ if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 66) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165576UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143165UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 143UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 60) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150240UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130150UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 130UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 2UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 50) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374182UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107374UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 107UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 1UL))) {
+ /**************************/
+ /* Test the board version */
+ /**************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+ /************************/
+ /* Test the TOR version */
+ /************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+ fpu_begin
+ ();
+
+ /****************************************/
+ /* Calculate the timer 0 division fator */
+ /****************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.001 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.001 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.001 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (0.001
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.001 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (1.0 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (1.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (
+ (double)
+ 1.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (1.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ *
+ (1000
+ *
+ b_PCIInputClock);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (1000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1000.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (1000.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (1000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (1000000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1000000.0
+ *
+ (double)
+ b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (1000000.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (ul_TimingInterval
+ *
+ 60)
+ *
+ (1000000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_TimingInterval * 60.0) * (1000000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (1000000.0
+ *
+ (double)
+ b_PCIInputClock))
+ /
+ 60;
+ d_RealTimingInterval
+ =
+ (
+ (double)
+ ul_TimerValue
+ /
+ (0.001 * (double)b_PCIInputClock)) / 60.0;
+
+ if ((double)(((double)ul_TimerValue / (1000000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 0.99392);
+ }
+
+ break;
+ }
+
+ fpu_end();
+
+ /****************************/
+ /* Save the PCI input clock */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_PCIInputClock
+ =
+ b_PCIInputClock;
+
+ /*************************/
+ /* Save the timing unity */
+ /*************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /************************/
+ /* Save the base timing */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ d_TimingInterval
+ =
+ d_RealTimingInterval;
+
+ /****************************/
+ /* Set the chronometer mode */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg
+ =
+ dw_ModeArray
+ [b_ChronoMode];
+
+ /***********************/
+ /* Test if 40 MHz used */
+ /***********************/
+
+ if (b_PCIInputClock == APCI1710_40MHZ) {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg
+ |
+ 0x80;
+ }
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].s_ChronoModuleInfo.dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 16 + (64 * b_ModulNbr));
+
+ /***********************/
+ /* Write timer 0 value */
+ /***********************/
+
+ outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
+
+ /*********************/
+ /* Chronometer init. */
+ /*********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_ChronoInit
+ =
+ 1;
+ } else {
+ /***********************************************/
+ /* TOR version error for 40MHz clock selection */
+ /***********************************************/
+
+ DPRINTK("TOR version error for 40MHz clock selection\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /**************************************************************/
+ /* You can not used the 40MHz clock selection wich this board */
+ /**************************************************************/
+
+ DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**********************************/
+ /* Base timing selection is wrong */
+ /**********************************/
+
+ DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /***********************************/
+ /* Timing unity selection is wrong */
+ /***********************************/
+
+ DPRINTK("Timing unity selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ } // if (b_ChronoMode >= 0 && b_ChronoMode <= 7)
+ else {
+ /***************************************/
+ /* Chronometer mode selection is wrong */
+ /***************************************/
+
+ DPRINTK("Chronometer mode selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_ChronoMode >= 0 && b_ChronoMode <= 7)
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+ data[0] = ul_RealTimingInterval;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableChrono |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_CycleMode, |
+| BYTE_ b_InterruptEnable)
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Enable the chronometer from selected module |
+| (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitChrono" function be for you call this |
+| function. |
+| If you enable the chronometer interrupt, the |
+| chronometer generate a interrupt after the stop signal.|
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter from this manual. |
+| The b_CycleMode parameter determine if you will |
+| measured a single or more cycle.
+
+| Disable the chronometer from selected module |
+| (b_ModulNbr). If you disable the chronometer after a |
+| start signal occur and you restart the chronometer |
+| witch the " i_APCI1710_EnableChrono" function, if no |
+| stop signal occur this start signal is ignored.
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr CR_AREF(chanspec) : Selected module number (0 to 3) |
+ data[0] ENABle/Disable chrono
+| BYTE_ b_CycleMode : Selected the chronometer |
+| data[1] acquisition mode |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| data[2] chronometer interrupt. |
+| APCI1710_ENABLE: |
+| Enable the chronometer |
+| interrupt |
+| APCI1710_DISABLE: |
+| Disable the chronometer |
+| interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
+| -5: Chronometer acquisition mode cycle is wrong |
+| -6: Interrupt parameter is wrong |
+| -7: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX"
+ -8: data[0] wrong input |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr, b_CycleMode, b_InterruptEnable, b_Action;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_Action = (BYTE) data[0];
+ b_CycleMode = (BYTE) data[1];
+ b_InterruptEnable = (BYTE) data[2];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+
+ switch (b_Action) {
+
+ case APCI1710_ENABLE:
+
+ /*********************************/
+ /* Test the cycle mode parameter */
+ /*********************************/
+
+ if ((b_CycleMode == APCI1710_SINGLE)
+ || (b_CycleMode ==
+ APCI1710_CONTINUOUS)) {
+ /***************************/
+ /* Test the interrupt flag */
+ /***************************/
+
+ if ((b_InterruptEnable ==
+ APCI1710_ENABLE)
+ || (b_InterruptEnable ==
+ APCI1710_DISABLE))
+ {
+
+ /***************************/
+ /* Save the interrupt flag */
+ /***************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_InterruptMask
+ =
+ b_InterruptEnable;
+
+ /***********************/
+ /* Save the cycle mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode =
+ b_CycleMode;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg &
+ 0x8F) | ((1 &
+ b_InterruptEnable)
+ << 5) | ((1 &
+ b_CycleMode)
+ << 6) | 0x10;
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if (b_InterruptEnable ==
+ APCI1710_ENABLE)
+ {
+ /****************************/
+ /* Clear the interrupt flag */
+ /****************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 32 +
+ (64 * b_ModulNbr));
+ devpriv->tsk_Current = current; // Save the current process task structure
+ }
+
+ /***********************************/
+ /* Enable or disable the interrupt */
+ /* Enable the chronometer */
+ /***********************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 16 +
+ (64 * b_ModulNbr));
+
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 36 +
+ (64 * b_ModulNbr));
+
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ else {
+ /***********************************************/
+ /* Chronometer acquisition mode cycle is wrong */
+ /***********************************************/
+
+ DPRINTK("Chronometer acquisition mode cycle is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ break;
+
+ case APCI1710_DISABLE:
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_InterruptMask = 0;
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ dw_ConfigReg & 0x2F;
+
+ /***************************/
+ /* Disable the interrupt */
+ /* Disable the chronometer */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.dw_ConfigReg,
+ devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode ==
+ APCI1710_CONTINUOUS) {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 36 +
+ (64 * b_ModulNbr));
+ }
+ break;
+
+ default:
+ DPRINTK("Inputs wrong! Enable or Disable chrono\n");
+ i_ReturnValue = -8;
+ } // switch ENABLE/DISABLE
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnReadChrono(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read functions for Timer |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadChrono(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_ReadType;
+ INT i_ReturnValue = insn->n;
+
+ b_ReadType = CR_CHAN(insn->chanspec);
+
+ switch (b_ReadType) {
+ case APCI1710_CHRONO_PROGRESS_STATUS:
+ i_ReturnValue = i_APCI1710_GetChronoProgressStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_CHRONO_READVALUE:
+ i_ReturnValue = i_APCI1710_ReadChronoValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (UINT) insn->unused[0],
+ (PBYTE) & data[0], (PULONG) & data[1]);
+ break;
+
+ case APCI1710_CHRONO_CONVERTVALUE:
+ i_ReturnValue = i_APCI1710_ConvertChronoValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (ULONG) insn->unused[0],
+ (PULONG) & data[0],
+ (PBYTE) & data[1],
+ (PBYTE) & data[2],
+ (PUINT) & data[3],
+ (PUINT) & data[4], (PUINT) & data[5]);
+ break;
+
+ case APCI1710_CHRONO_READINTERRUPT:
+ printk("In Chrono Read Interrupt\n");
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+ break;
+
+ default:
+ printk("ReadType Parameter wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetChronoProgressStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_ChronoStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the chronometer status (pb_ChronoStatus) from |
+| selected chronometer module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
+| status. |
+| 0 : Measurement not started.|
+| No start signal occur. |
+| 1 : Measurement started. |
+| A start signal occur. |
+| 2 : Measurement stopped. |
+| A stop signal occur. |
+| The measurement is |
+| terminate. |
+| 3: A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetChronoProgressStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_ChronoStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (64 * b_ModulNbr));
+
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 8) == 8) {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_ChronoStatus = 3;
+ } // if ((dw_Status & 8) == 8)
+ else {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) == 2) {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_ChronoStatus = 2;
+ } // if ((dw_Status & 2) == 2)
+ else {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1) {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_ChronoStatus = 1;
+ } // if ((dw_Status & 1) == 1)
+ else {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_ChronoStatus = 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadChronoValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| UINT_ ui_TimeOut, |
+| PBYTE_ pb_ChronoStatus, |
+| PULONG_ pul_ChronoValue) |
++----------------------------------------------------------------------------+
+| Task : Return the chronometer status (pb_ChronoStatus) and the|
+| timing value (pul_ChronoValue) after a stop signal |
+| occur from selected chronometer module (b_ModulNbr). |
+| This function are only avaible if you have disabled |
+| the interrupt functionality. See function |
+| "i_APCI1710_EnableChrono" and the Interrupt mask |
+| description chapter. |
+| You can test the chronometer status witch the |
+| "i_APCI1710_GetChronoProgressStatus" function. |
+| |
+| The returned value from pul_ChronoValue parameter is |
+| not real measured timing. |
+| You must used the "i_APCI1710_ConvertChronoValue" |
+| function or make this operation for calculate the |
+| timing: |
+| |
+| Timing = pul_ChronoValue * pul_RealTimingInterval. |
+| |
+| pul_RealTimingInterval is the returned parameter from |
+| "i_APCI1710_InitChrono" function and the time unity is |
+| the b_TimingUnit from "i_APCI1710_InitChrono" function|
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pb_ChronoStatus : Return the chronometer |
+| status. |
+| 0 : Measurement not started.|
+| No start signal occur. |
+| 1 : Measurement started. |
+| A start signal occur. |
+| 2 : Measurement stopped. |
+| A stop signal occur. |
+| The measurement is |
+| terminate. |
+| 3: A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitChrono" |
+| PULONG pul_ChronoValue : Chronometer timing value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
+| -5: Timeout parameter is wrong (0 to 65535) |
+| -6: Interrupt routine installed. You can not read |
+| directly the chronometer measured timing. |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadChronoValue(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ UINT ui_TimeOut, PBYTE pb_ChronoStatus, PULONG pul_ChronoValue)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_TimeOut = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+ /*****************************/
+ /* Test the timout parameter */
+ /*****************************/
+
+ if ((ui_TimeOut >= 0)
+ && (ui_TimeOut <= 65535UL)) {
+
+ for (;;) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModulNbr));
+
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 8) == 8) {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_ChronoStatus = 3;
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode ==
+ APCI1710_CONTINUOUS)
+ {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
+ }
+
+ break;
+ } // if ((dw_Status & 8) == 8)
+ else {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) ==
+ 2) {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_ChronoStatus
+ = 2;
+
+ /***************************/
+ /* Test if continnous mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_ChronoModuleInfo.
+ b_CycleMode
+ ==
+ APCI1710_CONTINUOUS)
+ {
+ /*************************/
+ /* Clear status register */
+ /*************************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 36 + (64 * b_ModulNbr));
+ }
+ break;
+ } // if ((dw_Status & 2) == 2)
+ else {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1) {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_ChronoStatus
+ =
+ 1;
+ } // if ((dw_Status & 1) == 1)
+ else {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_ChronoStatus
+ =
+ 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+
+ if (dw_TimeOut == ui_TimeOut) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ break;
+ } else {
+ /*************************/
+ /* Increment the timeout */
+ /*************************/
+
+ dw_TimeOut =
+ dw_TimeOut + 1;
+ mdelay(1000);
+
+ }
+ } // for (;;)
+
+ /*****************************/
+ /* Test if stop signal occur */
+ /*****************************/
+
+ if (*pb_ChronoStatus == 2) {
+ /**********************************/
+ /* Read the measured timing value */
+ /**********************************/
+
+ *pul_ChronoValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (64 * b_ModulNbr));
+
+ if (*pul_ChronoValue != 0) {
+ *pul_ChronoValue =
+ *pul_ChronoValue
+ - 1;
+ }
+ } else {
+ /*************************/
+ /* Test if timeout occur */
+ /*************************/
+
+ if ((*pb_ChronoStatus != 3)
+ && (dw_TimeOut ==
+ ui_TimeOut)
+ && (ui_TimeOut != 0)) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ *pb_ChronoStatus = 4;
+ }
+ }
+
+ } else {
+ /******************************/
+ /* Timeout parameter is wrong */
+ /******************************/
+ DPRINTK("Timeout parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ConvertChronoValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| ULONG_ ul_ChronoValue, |
+| PULONG_ pul_Hour, |
+| PBYTE_ pb_Minute, |
+| PBYTE_ pb_Second, |
+| PUINT_ pui_MilliSecond, |
+| PUINT_ pui_MicroSecond, |
+| PUINT_ pui_NanoSecond) |
++----------------------------------------------------------------------------+
+| Task : Convert the chronometer measured timing |
+| (ul_ChronoValue) in to h, mn, s, ms, µs, ns. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| ULONG_ ul_ChronoValue : Measured chronometer timing |
+| value. |
+| See"i_APCI1710_ReadChronoValue"|
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_Hour : Chronometer timing hour |
+| PBYTE_ pb_Minute : Chronometer timing minute |
+| PBYTE_ pb_Second : Chronometer timing second |
+| PUINT_ pui_MilliSecond : Chronometer timing mini |
+| second |
+| PUINT_ pui_MicroSecond : Chronometer timing micro |
+| second |
+| PUINT_ pui_NanoSecond : Chronometer timing nano |
+| second |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ConvertChronoValue(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ ULONG ul_ChronoValue,
+ PULONG pul_Hour,
+ PBYTE pb_Minute,
+ PBYTE pb_Second,
+ PUINT pui_MilliSecond, PUINT pui_MicroSecond, PUINT pui_NanoSecond)
+{
+ INT i_ReturnValue = 0;
+ double d_Hour;
+ double d_Minute;
+ double d_Second;
+ double d_MilliSecond;
+ double d_MicroSecond;
+ double d_NanoSecond;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+ fpu_begin();
+
+ d_Hour = (double)ul_ChronoValue *(double)
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.d_TimingInterval;
+
+ switch (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_TimingUnit) {
+ case 0:
+ d_Hour = d_Hour / (double)1000.0;
+
+ case 1:
+ d_Hour = d_Hour / (double)1000.0;
+
+ case 2:
+ d_Hour = d_Hour / (double)1000.0;
+
+ case 3:
+ d_Hour = d_Hour / (double)60.0;
+
+ case 4:
+ /**********************/
+ /* Calculate the hour */
+ /**********************/
+
+ d_Hour = d_Hour / (double)60.0;
+ *pul_Hour = (ULONG) d_Hour;
+
+ /************************/
+ /* Calculate the minute */
+ /************************/
+
+ d_Minute = d_Hour - *pul_Hour;
+ d_Minute = d_Minute * 60;
+ *pb_Minute = (BYTE) d_Minute;
+
+ /************************/
+ /* Calculate the second */
+ /************************/
+
+ d_Second = d_Minute - *pb_Minute;
+ d_Second = d_Second * 60;
+ *pb_Second = (BYTE) d_Second;
+
+ /*****************************/
+ /* Calculate the mini second */
+ /*****************************/
+
+ d_MilliSecond = d_Second - *pb_Second;
+ d_MilliSecond = d_MilliSecond * 1000;
+ *pui_MilliSecond = (UINT) d_MilliSecond;
+
+ /******************************/
+ /* Calculate the micro second */
+ /******************************/
+
+ d_MicroSecond =
+ d_MilliSecond -
+ *pui_MilliSecond;
+ d_MicroSecond = d_MicroSecond * 1000;
+ *pui_MicroSecond = (UINT) d_MicroSecond;
+
+ /******************************/
+ /* Calculate the micro second */
+ /******************************/
+
+ d_NanoSecond =
+ d_MicroSecond -
+ *pui_MicroSecond;
+ d_NanoSecond = d_NanoSecond * 1000;
+ *pui_NanoSecond = (UINT) d_NanoSecond;
+ break;
+ }
+
+ fpu_end();
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Sets the output witch has been passed with the |
+| parameter b_Channel. Setting an output means setting an|
+| output high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel : Selection from digital output |
+| CR_CHAN() channel (0 to 2) |
+| 0 : Channel H |
+| 1 : Channel A |
+| 2 : Channel B |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: The selected digital output is wrong |
+| -5: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetChronoChlOff |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_OutputChannel) |
++----------------------------------------------------------------------------+
+| Task : Resets the output witch has been passed with the |
+| parameter b_Channel. Resetting an output means setting |
+| an output low. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710
+ data[0] : Chl ON, Chl OFF , Chl Read , Port Read
+
+| BYTE_ b_ModulNbr CR_AREF : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel CR_CHAN : Selection from digital output |
+| channel (0 to 2) |
+| 0 : Channel H |
+| 1 : Channel A |
+| 2 : Channel B |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: The selected digital output is wrong |
+| -5: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadChronoChlValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_InputChannel, |
+| PBYTE_ pb_ChannelStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the status from selected digital input |
+| (b_InputChannel) from selected chronometer |
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| BYTE_ b_InputChannel : Selection from digital input |
+| channel (0 to 2) |
+| CR_CHAN() 0 : Channel E |
+| 1 : Channel F |
+| 2 : Channel G |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel status.|
+| data[0] 0 : Channel is not active |
+| 1 : Channel is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: The selected digital input is wrong |
+| -5: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadChronoPortValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_PortValue) |
++----------------------------------------------------------------------------+
+| Task : Return the status from digital inputs port from |
+| selected (b_ModulNbr) chronometer module. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_PortValue : Digital inputs port status.
+| data[0]
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a Chronometer module |
+| -4: Chronometer not initialised see function |
+| "i_APCI1710_InitChrono" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr, b_OutputChannel, b_InputChannel, b_IOType;
+ DWORD dw_Status;
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_PortValue;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ i_ReturnValue = insn->n;
+ b_IOType = (BYTE) data[0];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+ /***********************************/
+ /* Test if chronometer initialised */
+ /***********************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_ChronoModuleInfo.b_ChronoInit == 1) {
+ /***********************************/
+ /* Test the digital output channel */
+ /***********************************/
+ switch (b_IOType) {
+
+ case APCI1710_CHRONO_SET_CHANNELOFF:
+
+ b_OutputChannel =
+ (BYTE) CR_CHAN(insn->chanspec);
+ if (b_OutputChannel <= 2) {
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (b_OutputChannel * 4) +
+ (64 * b_ModulNbr));
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+ else {
+ /****************************************/
+ /* The selected digital output is wrong */
+ /****************************************/
+
+ DPRINTK("The selected digital output is wrong\n");
+ i_ReturnValue = -4;
+
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+
+ break;
+
+ case APCI1710_CHRONO_SET_CHANNELON:
+
+ b_OutputChannel =
+ (BYTE) CR_CHAN(insn->chanspec);
+ if (b_OutputChannel <= 2) {
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (b_OutputChannel * 4) +
+ (64 * b_ModulNbr));
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+ else {
+ /****************************************/
+ /* The selected digital output is wrong */
+ /****************************************/
+
+ DPRINTK("The selected digital output is wrong\n");
+ i_ReturnValue = -4;
+
+ } // if ((b_OutputChannel >= 0) && (b_OutputChannel <= 2))
+
+ break;
+
+ case APCI1710_CHRONO_READ_CHANNEL:
+ /**********************************/
+ /* Test the digital input channel */
+ /**********************************/
+ pb_ChannelStatus = (PBYTE) & data[0];
+ b_InputChannel =
+ (BYTE) CR_CHAN(insn->chanspec);
+
+ if (b_InputChannel <= 2) {
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 12 +
+ (64 * b_ModulNbr));
+
+ *pb_ChannelStatus =
+ (BYTE) (((dw_Status >>
+ b_InputChannel)
+ & 1) ^ 1);
+ } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
+ else {
+ /***************************************/
+ /* The selected digital input is wrong */
+ /***************************************/
+
+ DPRINTK("The selected digital input is wrong\n");
+ i_ReturnValue = -4;
+ } // if ((b_InputChannel >= 0) && (b_InputChannel <= 2))
+
+ break;
+
+ case APCI1710_CHRONO_READ_PORT:
+
+ pb_PortValue = (PBYTE) & data[0];
+
+ dw_Status =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (64 * b_ModulNbr));
+
+ *pb_PortValue =
+ (BYTE) ((dw_Status & 0x7) ^ 7);
+ break;
+ }
+ } else {
+ /*******************************/
+ /* Chronometer not initialised */
+ /*******************************/
+
+ DPRINTK("Chronometer not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a Chronometer module */
+ /******************************************/
+
+ DPRINTK("The module is not a Chronometer module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
new file mode 100644
index 00000000000..26b50cefee5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Chrono.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_CHRONO_PROGRESS_STATUS 0
+#define APCI1710_CHRONO_READVALUE 1
+#define APCI1710_CHRONO_CONVERTVALUE 2
+#define APCI1710_CHRONO_READINTERRUPT 3
+
+#define APCI1710_CHRONO_SET_CHANNELON 0
+#define APCI1710_CHRONO_SET_CHANNELOFF 1
+#define APCI1710_CHRONO_READ_CHANNEL 2
+#define APCI1710_CHRONO_READ_PORT 3
+
+/*
+ * CHRONOMETER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitChrono(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableChrono(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
+ * CHRONOMETER READ FUNCTION
+ */
+INT i_APCI1710_InsnReadChrono(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_GetChronoProgressStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_ChronoStatus);
+
+INT i_APCI1710_ReadChronoValue(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ UINT ui_TimeOut, PBYTE pb_ChronoStatus,
+ PULONG pul_ChronoValue);
+
+INT i_APCI1710_ConvertChronoValue(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ ULONG ul_ChronoValue,
+ PULONG pul_Hour,
+ PBYTE pb_Minute,
+ PBYTE pb_Second,
+ PUINT pui_MilliSecond, PUINT pui_MicroSecond,
+ PUINT pui_NanoSecond);
+
+/*
+ * CHRONOMETER DIGITAL INPUT OUTPUT FUNCTION
+ */
+INT i_APCI1710_InsnBitsChronoDigitalIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
new file mode 100644
index 00000000000..8be27aedaaf
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.c
@@ -0,0 +1,1020 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : DIG_IO.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 digital I/O module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 16/06/98 | S. Weber | Digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | | | |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "APCI1710_Dig_io.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
++----------------------------------------------------------------------------+
+| Task : Configure the digital I/O operating mode from selected |
+| module (b_ModulNbr). You must calling this function be|
+| for you call any other function witch access of digital|
+| I/O. |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| BYTE_ b_ModulNbr data[0]: Module number to |
+| configure (0 to 3) |
+| BYTE_ b_ChannelAMode data[1] : Channel A mode selection |
+| 0 : Channel used for digital |
+| input |
+| 1 : Channel used for digital |
+| output |
+| BYTE_ b_ChannelBMode data[2] : Channel B mode selection |
+| 0 : Channel used for digital |
+| input |
+| 1 : Channel used for digital |
+| output |
+ data[0] memory on/off
+Activates and deactivates the digital output memory.
+ After having |
+| called up this function with memory on,the output you have previously|
+| activated with the function are not reset
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: Bi-directional channel A configuration error |
+| -5: Bi-directional channel B configuration error |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_ModulNbr, b_ChannelAMode, b_ChannelBMode;
+ BYTE b_MemoryOnOff, b_ConfigType;
+ INT i_ReturnValue = 0;
+ DWORD dw_WriteConfig = 0;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_ConfigType = (BYTE) data[0]; // Memory or Init
+ b_ChannelAMode = (BYTE) data[1];
+ b_ChannelBMode = (BYTE) data[2];
+ b_MemoryOnOff = (BYTE) data[1]; // if memory operation
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr >= 4) {
+ DPRINTK("Module Number invalid\n");
+ i_ReturnValue = -2;
+ return i_ReturnValue;
+ }
+ switch (b_ConfigType) {
+ case APCI1710_DIGIO_MEMORYONOFF:
+
+ if (b_MemoryOnOff) // If Memory ON
+ {
+ /****************************/
+ /* Set the output memory on */
+ /****************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_OutputMemoryEnabled = 1;
+
+ /***************************/
+ /* Clear the output memory */
+ /***************************/
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.dw_OutputMemory = 0;
+ } else // If memory off
+ {
+ /*****************************/
+ /* Set the output memory off */
+ /*****************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_OutputMemoryEnabled = 0;
+ }
+ break;
+
+ case APCI1710_DIGIO_INIT:
+
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+
+ /***************************************************/
+ /* Test the bi-directional channel A configuration */
+ /***************************************************/
+
+ if ((b_ChannelAMode == 0) || (b_ChannelAMode == 1)) {
+ /***************************************************/
+ /* Test the bi-directional channel B configuration */
+ /***************************************************/
+
+ if ((b_ChannelBMode == 0)
+ || (b_ChannelBMode == 1)) {
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit =
+ 1;
+
+ /********************************/
+ /* Save channel A configuration */
+ /********************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode = b_ChannelAMode;
+
+ /********************************/
+ /* Save channel B configuration */
+ /********************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode = b_ChannelBMode;
+
+ /*****************************************/
+ /* Set the channel A and B configuration */
+ /*****************************************/
+
+ dw_WriteConfig =
+ (DWORD) (b_ChannelAMode |
+ (b_ChannelBMode * 2));
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(dw_WriteConfig,
+ devpriv->s_BoardInfos.
+ ui_Address + 4 +
+ (64 * b_ModulNbr));
+
+ } else {
+ /************************************************/
+ /* Bi-directional channel B configuration error */
+ /************************************************/
+ DPRINTK("Bi-directional channel B configuration error\n");
+ i_ReturnValue = -5;
+ }
+
+ } else {
+ /************************************************/
+ /* Bi-directional channel A configuration error */
+ /************************************************/
+ DPRINTK("Bi-directional channel A configuration error\n");
+ i_ReturnValue = -4;
+
+ }
+
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+ DPRINTK("The module is not a digital I/O module\n");
+ i_ReturnValue = -3;
+ }
+ } // end of Switch
+ printk("Return Value %d\n", i_ReturnValue);
+ return i_ReturnValue;
+}
+
+/*
++----------------------------------------------------------------------------+
+| INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+
+|INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,comedi_subdevice
+*s, struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task : Read the status from selected digital I/O digital input|
+| (b_InputChannel) |
++----------------------------------------------------------------------------|
+
+
+|
+| BYTE_ b_ModulNbr CR_AREF(chanspec) : Selected module number |
+| (0 to 3) |
+| BYTE_ b_InputChannel CR_CHAN(chanspec) : Selection from digital |
+| input ( 0 to 6) |
+| 0 : Channel C |
+| 1 : Channel D |
+| 2 : Channel E |
+| 3 : Channel F |
+| 4 : Channel G |
+| 5 : Channel A |
+| 6 : Channel B
+
+
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Digital input channel |
+| status |
+| 0 : Channle is not active|
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: The selected digital I/O digital input is wrong |
+| -5: Digital I/O not initialised |
+| -6: The digital channel A is used for output |
+| -7: The digital channel B is used for output |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_ i_APCI1710_ReadDigitalIOChlValue (BYTE_ b_BoardHandle,
+// BYTE_ b_ModulNbr,
+// BYTE_ b_InputChannel,
+//
+// PBYTE_ pb_ChannelStatus)
+INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr, b_InputChannel;
+ PBYTE pb_ChannelStatus;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
+ data[0] = 0;
+ pb_ChannelStatus = (PBYTE) & data[0];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /******************************************/
+ /* Test the digital imnput channel number */
+ /******************************************/
+
+ if (b_InputChannel <= 6) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /**********************************/
+ /* Test if channel A or channel B */
+ /**********************************/
+
+ if (b_InputChannel > 4) {
+ /*********************/
+ /* Test if channel A */
+ /*********************/
+
+ if (b_InputChannel == 5) {
+ /***************************/
+ /* Test the channel A mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode
+ != 0) {
+ /********************************************/
+ /* The digital channel A is used for output */
+ /********************************************/
+
+ i_ReturnValue =
+ -6;
+ }
+ } // if (b_InputChannel == 5)
+ else {
+ /***************************/
+ /* Test the channel B mode */
+ /***************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode
+ != 0) {
+ /********************************************/
+ /* The digital channel B is used for output */
+ /********************************************/
+
+ i_ReturnValue =
+ -7;
+ }
+ } // if (b_InputChannel == 5)
+ } // if (b_InputChannel > 4)
+
+ /***********************/
+ /* Test if error occur */
+ /***********************/
+
+ if (i_ReturnValue >= 0) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ //INPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // &dw_StatusReg);
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+
+ *pb_ChannelStatus =
+ (BYTE) ((dw_StatusReg ^
+ 0x1C) >>
+ b_InputChannel) & 1;
+
+ } // if (i_ReturnValue == 0)
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+ DPRINTK("Digital I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /********************************/
+ /* Selected digital input error */
+ /********************************/
+ DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+ DPRINTK("The module is not a digital I/O module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnWriteDigitalIOChlOnOff(comedi_device
+|*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task : Sets or resets the output witch has been passed with the |
+| parameter b_Channel. Setting an output means setting |
+| an ouput high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr (aref ) : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel (CR_CHAN) : Selection from digital output |
+| channel (0 to 2) |
+| 0 : Channel H |
+| 1 : Channel A |
+| 2 : Channel B |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: The selected digital output is wrong |
+| -5: digital I/O not initialised see function |
+| " i_APCI1710_InitDigitalIO" |
+| -6: The digital channel A is used for input |
+| -7: The digital channel B is used for input
+ -8: Digital Output Memory OFF. |
+| Use previously the function |
+| "i_APCI1710_SetDigitalIOMemoryOn". |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_ i_APCI1710_SetDigitalIOChlOn (BYTE_ b_BoardHandle,
+// BYTE_ b_ModulNbr,
+// BYTE_ b_OutputChannel)
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_WriteValue = 0;
+ BYTE b_ModulNbr, b_OutputChannel;
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_OutputChannel = CR_CHAN(insn->chanspec);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /******************************************/
+ /* Test the digital output channel number */
+ /******************************************/
+
+ switch (b_OutputChannel) {
+ /*************/
+ /* Channel H */
+ /*************/
+
+ case 0:
+ break;
+
+ /*************/
+ /* Channel A */
+ /*************/
+
+ case 1:
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode != 1) {
+ /*******************************************/
+ /* The digital channel A is used for input */
+ /*******************************************/
+
+ i_ReturnValue = -6;
+ }
+ break;
+
+ /*************/
+ /* Channel B */
+ /*************/
+
+ case 2:
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode != 1) {
+ /*******************************************/
+ /* The digital channel B is used for input */
+ /*******************************************/
+
+ i_ReturnValue = -7;
+ }
+ break;
+
+ default:
+ /****************************************/
+ /* The selected digital output is wrong */
+ /****************************************/
+
+ i_ReturnValue = -4;
+ break;
+ }
+
+ /***********************/
+ /* Test if error occur */
+ /***********************/
+
+ if (i_ReturnValue >= 0) {
+
+ /*********************************/
+ /* Test if set channel ON */
+ /*********************************/
+ if (data[0]) {
+ /*********************************/
+ /* Test if output memory enabled */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled ==
+ 1) {
+ dw_WriteValue =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ | (1 <<
+ b_OutputChannel);
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ = dw_WriteValue;
+ } else {
+ dw_WriteValue =
+ 1 <<
+ b_OutputChannel;
+ }
+ } // set channel off
+ else {
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled ==
+ 1) {
+ dw_WriteValue =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ & (0xFFFFFFFFUL
+ -
+ (1 << b_OutputChannel));
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ = dw_WriteValue;
+ } else {
+ /*****************************/
+ /* Digital Output Memory OFF */
+ /*****************************/
+ // +Use previously the function "i_APCI1710_SetDigitalIOMemoryOn"
+ i_ReturnValue = -8;
+ }
+
+ }
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ //OUTPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // dw_WriteValue);
+ outl(dw_WriteValue,
+ devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+ }
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+
+|INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,comedi_subdevice
+ *s, struct comedi_insn *insn,unsigned int *data)
++----------------------------------------------------------------------------+
+| Task : write:
+ Sets or resets one or several outputs from port. |
+| Setting an output means setting an output high. |
+| If you have switched OFF the digital output memory |
+| (OFF), all the other output are set to "0".
+
+| read:
+ Read the status from digital input port |
+| from selected digital I/O module (b_ModulNbr)
++----------------------------------------------------------------------------+
+| Input Parameters :
+ BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr CR_AREF(aref) : Selected module number (0 to 3)|
+| BYTE_ b_PortValue CR_CHAN(chanspec) : Output Value ( 0 To 7 )
+| data[0] read or write port
+ data[1] if write then indicate ON or OFF
+
+ if read : data[1] will return port status.
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
+
+ INPUT :
+
+ 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: Digital I/O not initialised
+
+ OUTPUT: 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a digital I/O module |
+| -4: Output value wrong |
+| -5: digital I/O not initialised see function |
+| " i_APCI1710_InitDigitalIO" |
+| -6: The digital channel A is used for input |
+| -7: The digital channel B is used for input
+ -8: Digital Output Memory OFF. |
+| Use previously the function |
+| "i_APCI1710_SetDigitalIOMemoryOn". |
++----------------------------------------------------------------------------+
+*/
+
+//_INT_ i_APCI1710_SetDigitalIOPortOn (BYTE_ b_BoardHandle,
+// BYTE_ b_ModulNbr,
+// BYTE_ b_PortValue)
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_WriteValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr, b_PortValue;
+ BYTE b_PortOperation, b_PortOnOFF;
+
+ PBYTE pb_PortValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_PortOperation = (BYTE) data[0]; // Input or output
+ b_PortOnOFF = (BYTE) data[1]; // if output then On or Off
+ b_PortValue = (BYTE) data[2]; // if out put then Value
+ i_ReturnValue = insn->n;
+ pb_PortValue = (PBYTE) & data[0];
+// if input then read value
+
+ switch (b_PortOperation) {
+ case APCI1710_INPUT:
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ //INPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // &dw_StatusReg);
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+ *pb_PortValue =
+ (BYTE) (dw_StatusReg ^ 0x1C);
+
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ i_ReturnValue = -2;
+ }
+
+ break;
+
+ case APCI1710_OUTPUT:
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if digital I/O counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_DIGITAL_IO) {
+ /**********************************************/
+ /* Test if the digital I/O module initialised */
+ /**********************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_DigitalIOInfo.b_DigitalInit == 1) {
+ /***********************/
+ /* Test the port value */
+ /***********************/
+
+ if (b_PortValue <= 7) {
+ /***********************************/
+ /* Test the digital output channel */
+ /***********************************/
+
+ /**************************/
+ /* Test if channel A used */
+ /**************************/
+
+ if ((b_PortValue & 2) == 2) {
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelAMode
+ != 1) {
+ /*******************************************/
+ /* The digital channel A is used for input */
+ /*******************************************/
+
+ i_ReturnValue =
+ -6;
+ }
+ } // if ((b_PortValue & 2) == 2)
+
+ /**************************/
+ /* Test if channel B used */
+ /**************************/
+
+ if ((b_PortValue & 4) == 4) {
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_ChannelBMode
+ != 1) {
+ /*******************************************/
+ /* The digital channel B is used for input */
+ /*******************************************/
+
+ i_ReturnValue =
+ -7;
+ }
+ } // if ((b_PortValue & 4) == 4)
+
+ /***********************/
+ /* Test if error occur */
+ /***********************/
+
+ if (i_ReturnValue >= 0) {
+
+ //if(data[1])
+ //{
+ switch (b_PortOnOFF) {
+ /*********************************/
+ /* Test if set Port ON */
+ /*********************************/
+
+ case APCI1710_ON:
+
+ /*********************************/
+ /* Test if output memory enabled */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled
+ == 1) {
+ dw_WriteValue
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ |
+ b_PortValue;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ =
+ dw_WriteValue;
+ } else {
+ dw_WriteValue
+ =
+ b_PortValue;
+ }
+ break;
+
+ // If Set PORT OFF
+ case APCI1710_OFF:
+
+ /*********************************/
+ /* Test if output memory enabled */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ b_OutputMemoryEnabled
+ == 1) {
+ dw_WriteValue
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ &
+ (0xFFFFFFFFUL
+ -
+ b_PortValue);
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_DigitalIOInfo.
+ dw_OutputMemory
+ =
+ dw_WriteValue;
+ } else {
+ /*****************************/
+ /* Digital Output Memory OFF */
+ /*****************************/
+
+ i_ReturnValue
+ =
+ -8;
+ }
+ } // switch
+
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ // OUTPDW (ps_APCI1710Variable->
+ // s_Board [b_BoardHandle].
+ // s_BoardInfos.
+ // ui_Address + (64 * b_ModulNbr),
+ // dw_WriteValue);
+ outl(dw_WriteValue,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ }
+ } else {
+ /**********************/
+ /* Output value wrong */
+ /**********************/
+
+ i_ReturnValue = -4;
+ }
+ } else {
+ /*******************************/
+ /* Digital I/O not initialised */
+ /*******************************/
+
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************/
+ /* The module is not a digital I/O module */
+ /******************************************/
+
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ i_ReturnValue = -2;
+ }
+ break;
+
+ default:
+ i_ReturnValue = -9;
+ DPRINTK("NO INPUT/OUTPUT specified\n");
+ } //switch INPUT / OUTPUT
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
new file mode 100644
index 00000000000..5ef157a55ca
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Dig_io.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_ON 1 /* Digital Output ON or OFF */
+#define APCI1710_OFF 0
+
+#define APCI1710_INPUT 0 /* Digital I/O */
+#define APCI1710_OUTPUT 1
+
+#define APCI1710_DIGIO_MEMORYONOFF 0x10
+#define APCI1710_DIGIO_INIT 0x11
+
+/*
+ * DIGITAL I/O INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * INPUT OUTPUT FUNCTIONS
+ */
+INT i_APCI1710_InsnReadDigitalIOChlValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteDigitalIOChlOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsDigitalIOPortOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
new file mode 100644
index 00000000000..1062f2fdec3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.c
@@ -0,0 +1,5363 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : INC_CPT.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 incremental counter module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | 29/06/01 | Guinot C. | - 1100/0231 -> 0701/0232 |
+ | | | See i_APCI1710_DisableFrequencyMeasurement |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_INCCPT.h"
+
+/*
++----------------------------------------------------------------------------+
+| INT i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data)
+
++----------------------------------------------------------------------------+
+| Task : Configuration function for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : *data
++----------------------------------------------------------------------------+
+| Return Value : |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_ConfigType;
+ INT i_ReturnValue = 0;
+ ui_ConfigType = CR_CHAN(insn->chanspec);
+
+ printk("\nINC_CPT");
+
+ devpriv->tsk_Current = current; // Save the current process task structure
+ switch (ui_ConfigType) {
+ case APCI1710_INCCPT_INITCOUNTER:
+ i_ReturnValue = i_APCI1710_InitCounter(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1],
+ (BYTE) data[2], (BYTE) data[3], (BYTE) data[4]);
+ break;
+
+ case APCI1710_INCCPT_COUNTERAUTOTEST:
+ i_ReturnValue = i_APCI1710_CounterAutoTest(dev,
+ (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_INITINDEX:
+ i_ReturnValue = i_APCI1710_InitIndex(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1], (BYTE) data[2], (BYTE) data[3]);
+ break;
+
+ case APCI1710_INCCPT_INITREFERENCE:
+ i_ReturnValue = i_APCI1710_InitReference(dev,
+ CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_INITEXTERNALSTROBE:
+ i_ReturnValue = i_APCI1710_InitExternalStrobe(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0], (BYTE) data[1]);
+ break;
+
+ case APCI1710_INCCPT_INITCOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_InitCompareLogic(dev,
+ CR_AREF(insn->chanspec), (UINT) data[0]);
+ break;
+
+ case APCI1710_INCCPT_INITFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_InitFrequencyMeasurement(dev,
+ CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1], (ULONG) data[2], (PULONG) & data[0]);
+ break;
+
+ default:
+ printk("Insn Config : Config Parameter Wrong\n");
+
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_CounterRange, |
+| BYTE_ b_FirstCounterModus, |
+| BYTE_ b_FirstCounterOption, |
+| BYTE_ b_SecondCounterModus, |
+| BYTE_ b_SecondCounterOption) |
++----------------------------------------------------------------------------+
+| Task : Configure the counter operating mode from selected |
+| module (b_ModulNbr). You must calling this function be |
+| for you call any other function witch access of |
+| counters. |
+| |
+| Counter range |
+| ------------- |
+| +------------------------------------+-----------------------------------+ |
+| | Parameter Passed value | Description | |
+| |------------------------------------+-----------------------------------| |
+| |b_ModulNbr APCI1710_16BIT_COUNTER | The module is configured for | |
+| | | two 16-bit counter. | |
+| | | - b_FirstCounterModus and | |
+| | | b_FirstCounterOption | |
+| | | configure the first 16 bit | |
+| | | counter. | |
+| | | - b_SecondCounterModus and | |
+| | | b_SecondCounterOption | |
+| | | configure the second 16 bit | |
+| | | counter. | |
+| |------------------------------------+-----------------------------------| |
+| |b_ModulNbr APCI1710_32BIT_COUNTER | The module is configured for one | |
+| | | 32-bit counter. | |
+| | | - b_FirstCounterModus and | |
+| | | b_FirstCounterOption | |
+| | | configure the 32 bit counter. | |
+| | | - b_SecondCounterModus and | |
+| | | b_SecondCounterOption | |
+| | | are not used and have no | |
+| | | importance. | |
+| +------------------------------------+-----------------------------------+ |
+| |
+| Counter operating mode |
+| ---------------------- |
+| |
+| +--------------------+-------------------------+-------------------------+ |
+| | Parameter | Passed value | Description | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_QUADRUPLE_MODE | In the quadruple mode, | |
+| | or | | the edge analysis | |
+| |b_SecondCounterModus| | circuit generates a | |
+| | | | counting pulse from | |
+| | | | each edge of 2 signals | |
+| | | | which are phase shifted | |
+| | | | in relation to each | |
+| | | | other. | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_DOUBLE_MODE | Functions in the same | |
+| | or | | way as the quadruple | |
+| |b_SecondCounterModus| | mode, except that only | |
+| | | | two of the four edges | |
+| | | | are analysed per | |
+| | | | period | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_SIMPLE_MODE | Functions in the same | |
+| | or | | way as the quadruple | |
+| |b_SecondCounterModus| | mode, except that only | |
+| | | | one of the four edges | |
+| | | | is analysed per | |
+| | | | period. | |
+| |--------------------+-------------------------+-------------------------| |
+| |b_FirstCounterModus | APCI1710_DIRECT_MODE | In the direct mode the | |
+| | or | | both edge analysis | |
+| |b_SecondCounterModus| | circuits are inactive. | |
+| | | | The inputs A, B in the | |
+| | | | 32-bit mode or A, B and | |
+| | | | C, D in the 16-bit mode | |
+| | | | represent, each, one | |
+| | | | clock pulse gate circuit| |
+| | | | There by frequency and | |
+| | | | pulse duration | |
+| | | | measurements can be | |
+| | | | performed. | |
+| +--------------------+-------------------------+-------------------------+ |
+| |
+| |
+| IMPORTANT! |
+| If you have configured the module for two 16-bit counter, a mixed |
+| mode with a counter in quadruple/double/single mode |
+| and the other counter in direct mode is not possible! |
+| |
+| |
+| Counter operating option for quadruple/double/simple mode |
+| --------------------------------------------------------- |
+| |
+| +----------------------+-------------------------+------------------------+|
+| | Parameter | Passed value | Description ||
+| |----------------------+-------------------------+------------------------||
+| |b_FirstCounterOption | APCI1710_HYSTERESIS_ON | In both edge analysis ||
+| | or | | circuits is available ||
+| |b_SecondCounterOption | | one hysteresis circuit.||
+| | | | It suppresses each ||
+| | | | time the first counting||
+| | | | pulse after a change ||
+| | | | of rotation. ||
+| |----------------------+-------------------------+------------------------||
+| |b_FirstCounterOption | APCI1710_HYSTERESIS_OFF | The first counting ||
+| | or | | pulse is not suppress ||
+| |b_SecondCounterOption | | after a change of ||
+| | | | rotation. ||
+| +----------------------+-------------------------+------------------------+|
+| |
+| |
+| IMPORTANT! |
+| This option are only avaible if you have selected the direct mode. |
+| |
+| |
+| Counter operating option for direct mode |
+| ---------------------------------------- |
+| |
+| +----------------------+--------------------+----------------------------+ |
+| | Parameter | Passed value | Description | |
+| |----------------------+--------------------+----------------------------| |
+| |b_FirstCounterOption | APCI1710_INCREMENT | The counter increment for | |
+| | or | | each counting pulse | |
+| |b_SecondCounterOption | | | |
+| |----------------------+--------------------+----------------------------| |
+| |b_FirstCounterOption | APCI1710_DECREMENT | The counter decrement for | |
+| | or | | each counting pulse | |
+| |b_SecondCounterOption | | | |
+| +----------------------+--------------------+----------------------------+ |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_CounterRange : Selection form counter |
+| range. |
+| BYTE_ b_FirstCounterModus : First counter operating |
+| mode. |
+| BYTE_ b_FirstCounterOption : First counter option. |
+| BYTE_ b_SecondCounterModus : Second counter operating |
+| mode. |
+| BYTE_ b_SecondCounterOption : Second counter option. |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module is not a counter module |
+| -3: The selected counter range is wrong. |
+| -4: The selected first counter operating mode is wrong. |
+| -5: The selected first counter operating option is wrong|
+| -6: The selected second counter operating mode is wrong.|
+| -7: The selected second counter operating option is |
+| wrong. |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitCounter(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_CounterRange,
+ BYTE b_FirstCounterModus,
+ BYTE b_FirstCounterOption,
+ BYTE b_SecondCounterModus, BYTE b_SecondCounterOption)
+{
+ INT i_ReturnValue = 0;
+
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ /**************************/
+ /* Test the counter range */
+ /**************************/
+
+ if (b_CounterRange == APCI1710_16BIT_COUNTER
+ || b_CounterRange == APCI1710_32BIT_COUNTER) {
+ /********************************/
+ /* Test the first counter modus */
+ /********************************/
+
+ if (b_FirstCounterModus == APCI1710_QUADRUPLE_MODE ||
+ b_FirstCounterModus == APCI1710_DOUBLE_MODE ||
+ b_FirstCounterModus == APCI1710_SIMPLE_MODE ||
+ b_FirstCounterModus == APCI1710_DIRECT_MODE) {
+ /*********************************/
+ /* Test the first counter option */
+ /*********************************/
+
+ if ((b_FirstCounterModus == APCI1710_DIRECT_MODE
+ && (b_FirstCounterOption ==
+ APCI1710_INCREMENT
+ || b_FirstCounterOption
+ == APCI1710_DECREMENT))
+ || (b_FirstCounterModus !=
+ APCI1710_DIRECT_MODE
+ && (b_FirstCounterOption ==
+ APCI1710_HYSTERESIS_ON
+ || b_FirstCounterOption
+ ==
+ APCI1710_HYSTERESIS_OFF)))
+ {
+ /**************************/
+ /* Test if 16-bit counter */
+ /**************************/
+
+ if (b_CounterRange ==
+ APCI1710_16BIT_COUNTER) {
+ /*********************************/
+ /* Test the second counter modus */
+ /*********************************/
+
+ if ((b_FirstCounterModus !=
+ APCI1710_DIRECT_MODE
+ &&
+ (b_SecondCounterModus
+ ==
+ APCI1710_QUADRUPLE_MODE
+ ||
+ b_SecondCounterModus
+ ==
+ APCI1710_DOUBLE_MODE
+ ||
+ b_SecondCounterModus
+ ==
+ APCI1710_SIMPLE_MODE))
+ || (b_FirstCounterModus
+ ==
+ APCI1710_DIRECT_MODE
+ &&
+ b_SecondCounterModus
+ ==
+ APCI1710_DIRECT_MODE))
+ {
+ /**********************************/
+ /* Test the second counter option */
+ /**********************************/
+
+ if ((b_SecondCounterModus == APCI1710_DIRECT_MODE && (b_SecondCounterOption == APCI1710_INCREMENT || b_SecondCounterOption == APCI1710_DECREMENT)) || (b_SecondCounterModus != APCI1710_DIRECT_MODE && (b_SecondCounterOption == APCI1710_HYSTERESIS_ON || b_SecondCounterOption == APCI1710_HYSTERESIS_OFF))) {
+ i_ReturnValue =
+ 0;
+ } else {
+ /*********************************************************/
+ /* The selected second counter operating option is wrong */
+ /*********************************************************/
+
+ DPRINTK("The selected second counter operating option is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ } else {
+ /*******************************************************/
+ /* The selected second counter operating mode is wrong */
+ /*******************************************************/
+
+ DPRINTK("The selected second counter operating mode is wrong\n");
+ i_ReturnValue = -6;
+ }
+ }
+ } else {
+ /********************************************************/
+ /* The selected first counter operating option is wrong */
+ /********************************************************/
+
+ DPRINTK("The selected first counter operating option is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /******************************************************/
+ /* The selected first counter operating mode is wrong */
+ /******************************************************/
+ DPRINTK("The selected first counter operating mode is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /***************************************/
+ /* The selected counter range is wrong */
+ /***************************************/
+
+ DPRINTK("The selected counter range is wrong\n");
+ i_ReturnValue = -3;
+ }
+
+ /*************************/
+ /* Test if a error occur */
+ /*************************/
+
+ if (i_ReturnValue == 0) {
+ /**************************/
+ /* Test if 16-Bit counter */
+ /**************************/
+
+ if (b_CounterRange == APCI1710_32BIT_COUNTER) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 = b_CounterRange |
+ b_FirstCounterModus |
+ b_FirstCounterOption;
+ } else {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 = b_CounterRange |
+ (b_FirstCounterModus & 0x5) |
+ (b_FirstCounterOption & 0x20) |
+ (b_SecondCounterModus & 0xA) |
+ (b_SecondCounterOption & 0x40);
+
+ /***********************/
+ /* Test if direct mode */
+ /***********************/
+
+ if (b_FirstCounterModus == APCI1710_DIRECT_MODE) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 |
+ APCI1710_DIRECT_MODE;
+ }
+ }
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CounterInit = 1;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_CounterAutoTest |
+| (BYTE_ b_BoardHandle, |
+| PBYTE_ pb_TestStatus) |
++----------------------------------------------------------------------------+
+| Task : A test mode is intended for testing the component and |
+| the connected periphery. All the 8-bit counter chains |
+| are operated internally as down counters. |
+| Independently from the external signals, |
+| all the four 8-bit counter chains are decremented in |
+| parallel by each negative clock pulse edge of CLKX. |
+| |
+| Counter auto test conclusion |
+| ---------------------------- |
+| +-----------------+-----------------------------+ |
+| | pb_TestStatus | Error description | |
+| | mask | | |
+| |-----------------+-----------------------------| |
+| | 0000 | No error detected | |
+| |-----------------|-----------------------------| |
+| | 0001 | Error detected of counter 0 | |
+| |-----------------|-----------------------------| |
+| | 0010 | Error detected of counter 1 | |
+| |-----------------|-----------------------------| |
+| | 0100 | Error detected of counter 2 | |
+| |-----------------|-----------------------------| |
+| | 1000 | Error detected of counter 3 | |
+| +-----------------+-----------------------------+ |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 | |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TestStatus : Auto test conclusion. See table|
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_CounterAutoTest(struct comedi_device * dev, PBYTE pb_TestStatus)
+{
+ BYTE b_ModulCpt = 0;
+ INT i_ReturnValue = 0;
+ DWORD dw_LathchValue;
+
+ *pb_TestStatus = 0;
+
+ /********************************/
+ /* Test if counter module found */
+ /********************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[0] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[1] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[2] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[3] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ for (b_ModulCpt = 0; b_ModulCpt < 4; b_ModulCpt++) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulCpt] &
+ 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ /******************/
+ /* Start the test */
+ /******************/
+
+ outl(3, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulCpt));
+
+ /*********************/
+ /* Tatch the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulCpt));
+
+ /************************/
+ /* Read the latch value */
+ /************************/
+
+ dw_LathchValue = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulCpt));
+
+ if ((dw_LathchValue & 0xFF) !=
+ ((dw_LathchValue >> 8) & 0xFF)
+ && (dw_LathchValue & 0xFF) !=
+ ((dw_LathchValue >> 16) & 0xFF)
+ && (dw_LathchValue & 0xFF) !=
+ ((dw_LathchValue >> 24) & 0xFF)) {
+ *pb_TestStatus =
+ *pb_TestStatus | (1 <<
+ b_ModulCpt);
+ }
+
+ /*****************/
+ /* Stop the test */
+ /*****************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulCpt));
+ }
+ }
+ } else {
+ /***************************/
+ /* No counter module found */
+ /***************************/
+
+ DPRINTK("No counter module found\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitIndex (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ReferenceAction, |
+| BYTE_ b_IndexOperation, |
+| BYTE_ b_AutoMode, |
+| BYTE_ b_InterruptEnable) |
++----------------------------------------------------------------------------+
+| Task : Initialise the index corresponding to the selected |
+| module (b_ModulNbr). If a INDEX flag occur, you have |
+| the possibility to clear the 32-Bit counter or to latch|
+| the current 32-Bit value in to the first latch |
+| register. The b_IndexOperation parameter give the |
+| possibility to choice the INDEX action. |
+| If you have enabled the automatic mode, each INDEX |
+| action is cleared automatically, else you must read |
+| the index status ("i_APCI1710_ReadIndexStatus") |
+| after each INDEX action. |
+| |
+| |
+| Index action |
+| ------------ |
+| |
+| +------------------------+------------------------------------+ |
+| | b_IndexOperation | Operation | |
+| |------------------------+------------------------------------| |
+| |APCI1710_LATCH_COUNTER | After a index signal, the counter | |
+| | | value (32-Bit) is latched in to | |
+| | | the first latch register | |
+| |------------------------|------------------------------------| |
+| |APCI1710_CLEAR_COUNTER | After a index signal, the counter | |
+| | | value is cleared (32-Bit) | |
+| +------------------------+------------------------------------+ |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ReferenceAction : Determine if the reference |
+| must set or no for the |
+| acceptance from index |
+| APCI1710_ENABLE : |
+| Reference must be set for |
+| accepted the index |
+| APCI1710_DISABLE : |
+| Reference have not |
+| importance |
+| BYTE_ b_IndexOperation : Index operating mode. |
+| See table. |
+| BYTE_ b_AutoMode : Enable or disable the |
+| automatic index reset. |
+| APCI1710_ENABLE : |
+| Enable the automatic mode |
+| APCI1710_DISABLE : |
+| Disable the automatic mode |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| interrupt. |
+| APCI1710_ENABLE : |
+| Enable the interrupt |
+| APCI1710_DISABLE : |
+| Disable the interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4 The reference action parameter is wrong |
+| -5: The index operating mode parameter is wrong |
+| -6: The auto mode parameter is wrong |
+| -7: Interrupt parameter is wrong |
+| -8: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitIndex(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_ReferenceAction,
+ BYTE b_IndexOperation, BYTE b_AutoMode, BYTE b_InterruptEnable)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************/
+ /* Test the reference parameter */
+ /********************************/
+
+ if (b_ReferenceAction == APCI1710_ENABLE ||
+ b_ReferenceAction == APCI1710_DISABLE) {
+ /****************************/
+ /* Test the index parameter */
+ /****************************/
+
+ if (b_IndexOperation ==
+ APCI1710_HIGH_EDGE_LATCH_COUNTER
+ || b_IndexOperation ==
+ APCI1710_LOW_EDGE_LATCH_COUNTER
+ || b_IndexOperation ==
+ APCI1710_HIGH_EDGE_CLEAR_COUNTER
+ || b_IndexOperation ==
+ APCI1710_LOW_EDGE_CLEAR_COUNTER
+ || b_IndexOperation ==
+ APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER
+ || b_IndexOperation ==
+ APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ {
+ /********************************/
+ /* Test the auto mode parameter */
+ /********************************/
+
+ if (b_AutoMode == APCI1710_ENABLE ||
+ b_AutoMode == APCI1710_DISABLE)
+ {
+ /***************************/
+ /* Test the interrupt mode */
+ /***************************/
+
+ if (b_InterruptEnable ==
+ APCI1710_ENABLE
+ || b_InterruptEnable ==
+ APCI1710_DISABLE) {
+
+ /************************************/
+ /* Makte the configuration commando */
+ /************************************/
+
+ if (b_ReferenceAction ==
+ APCI1710_ENABLE)
+ {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ |
+ APCI1710_ENABLE_INDEX_ACTION;
+ } else {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ &
+ APCI1710_DISABLE_INDEX_ACTION;
+ }
+
+ /****************************************/
+ /* Test if low level latch or/and clear */
+ /****************************************/
+
+ if (b_IndexOperation ==
+ APCI1710_LOW_EDGE_LATCH_COUNTER
+ ||
+ b_IndexOperation
+ ==
+ APCI1710_LOW_EDGE_CLEAR_COUNTER
+ ||
+ b_IndexOperation
+ ==
+ APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ {
+ /*************************************/
+ /* Set the index level to low (DQ26) */
+ /*************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_SET_LOW_INDEX_LEVEL;
+ } else {
+ /**************************************/
+ /* Set the index level to high (DQ26) */
+ /**************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_SET_HIGH_INDEX_LEVEL;
+ }
+
+ /***********************************/
+ /* Test if latch and clear counter */
+ /***********************************/
+
+ if (b_IndexOperation ==
+ APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER
+ ||
+ b_IndexOperation
+ ==
+ APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ {
+ /***************************************/
+ /* Set the latch and clear flag (DQ27) */
+ /***************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_ENABLE_LATCH_AND_CLEAR;
+ } // if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+ else {
+ /*****************************************/
+ /* Clear the latch and clear flag (DQ27) */
+ /*****************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_DISABLE_LATCH_AND_CLEAR;
+
+ /*************************/
+ /* Test if latch counter */
+ /*************************/
+
+ if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_COUNTER) {
+ /*********************************/
+ /* Enable the latch from counter */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ |
+ APCI1710_INDEX_LATCH_COUNTER;
+ } else {
+ /*********************************/
+ /* Enable the clear from counter */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ &
+ (~APCI1710_INDEX_LATCH_COUNTER);
+ }
+ } // // if (b_IndexOperation == APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER || b_IndexOperation == APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER)
+
+ if (b_AutoMode ==
+ APCI1710_DISABLE)
+ {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ |
+ APCI1710_INDEX_AUTO_MODE;
+ } else {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2
+ &
+ (~APCI1710_INDEX_AUTO_MODE);
+ }
+
+ if (b_InterruptEnable ==
+ APCI1710_ENABLE)
+ {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ |
+ APCI1710_ENABLE_INDEX_INT;
+ } else {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ &
+ APCI1710_DISABLE_INDEX_INT;
+ }
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_IndexInit = 1;
+
+ } else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } else {
+ /************************************/
+ /* The auto mode parameter is wrong */
+ /************************************/
+
+ DPRINTK("The auto mode parameter is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /***********************************************/
+ /* The index operating mode parameter is wrong */
+ /***********************************************/
+
+ DPRINTK("The index operating mode parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************************/
+ /* The reference action parameter is wrong */
+ /*******************************************/
+
+ DPRINTK("The reference action parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitReference |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ReferenceLevel) |
++----------------------------------------------------------------------------+
+| Task : Initialise the reference corresponding to the selected |
+| module (b_ModulNbr). |
+| |
+| Reference level |
+| --------------- |
+| +--------------------+-------------------------+ |
+| | b_ReferenceLevel | Operation | |
+| +--------------------+-------------------------+ |
+| | APCI1710_LOW | Reference occur if "0" | |
+| |--------------------|-------------------------| |
+| | APCI1710_HIGH | Reference occur if "1" | |
+| +--------------------+-------------------------+ |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ReferenceLevel : Reference level. |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number parameter is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Reference level parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitReference(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_ReferenceLevel)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /**************************************/
+ /* Test the reference level parameter */
+ /**************************************/
+
+ if (b_ReferenceLevel == 0 || b_ReferenceLevel == 1) {
+ if (b_ReferenceLevel == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 |
+ APCI1710_REFERENCE_HIGH;
+ } else {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 &
+ APCI1710_REFERENCE_LOW;
+ }
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_ReferenceInit = 1;
+ } else {
+ /**************************************/
+ /* Reference level parameter is wrong */
+ /**************************************/
+
+ DPRINTK("Reference level parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitExternalStrobe |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_ExternalStrobe, |
+| BYTE_ b_ExternalStrobeLevel) |
++----------------------------------------------------------------------------+
+| Task : Initialises the external strobe level corresponding to |
+| the selected module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_ExternalStrobe : External strobe selection |
+| 0 : External strobe A |
+| 1 : External strobe B |
+| BYTE_ b_ExternalStrobeLevel : External strobe level |
+| APCI1710_LOW : |
+| External latch occurs if "0" |
+| APCI1710_HIGH : |
+| External latch occurs if "1" |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised. |
+| See function "i_APCI1710_InitCounter" |
+| -4: External strobe selection is wrong |
+| -5: External strobe level parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitExternalStrobe(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_ExternalStrobe, BYTE b_ExternalStrobeLevel)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /**************************************/
+ /* Test the external strobe selection */
+ /**************************************/
+
+ if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1) {
+ /******************/
+ /* Test the level */
+ /******************/
+
+ if ((b_ExternalStrobeLevel == APCI1710_HIGH) ||
+ ((b_ExternalStrobeLevel == APCI1710_LOW
+ && (devpriv->
+ s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3135))) {
+ /*****************/
+ /* Set the level */
+ /*****************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 = (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 & (0xFF -
+ (0x10 << b_ExternalStrobe))) | ((b_ExternalStrobeLevel ^ 1) << (4 + b_ExternalStrobe));
+ } else {
+ /********************************************/
+ /* External strobe level parameter is wrong */
+ /********************************************/
+
+ DPRINTK("External strobe level parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } // if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)
+ else {
+ /**************************************/
+ /* External strobe selection is wrong */
+ /**************************************/
+
+ DPRINTK("External strobe selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_ExternalStrobe == 0 || b_ExternalStrobe == 1)
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_InitCompareLogic |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | UINT_ ui_CompareValue) |
+ +----------------------------------------------------------------------------+
+ | Task : Set the 32-Bit compare value. At that moment that the |
+ | incremental counter arrive to the compare value |
+ | (ui_CompareValue) a interrupt is generated. |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Module number to configure |
+ | (0 to 3) |
+ | UINT_ ui_CompareValue : 32-Bit compare value |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: No counter module found |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_InitCompareLogic(struct comedi_device * dev,
+ BYTE b_ModulNbr, UINT ui_CompareValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+ outl(ui_CompareValue, devpriv->s_BoardInfos.
+ ui_Address + 28 + (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CompareLogicInit = 1;
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitFrequencyMeasurement |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_TimingUnity, |
+| ULONG_ ul_TimingInterval, |
+| PULONG_ pul_RealTimingInterval) |
++----------------------------------------------------------------------------+
+| Task : Sets the time for the frequency measurement. |
+| Configures the selected TOR incremental counter of the |
+| selected module (b_ModulNbr). The ul_TimingInterval and|
+| ul_TimingUnity determine the time base for the |
+| measurement. The pul_RealTimingInterval returns the |
+| real time value. You must call up this function before |
+| you call up any other function which gives access to |
+| the frequency measurement. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
+| BYTE_ b_PCIInputClock : Selection of the PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC has a PCI bus clock |
+| of 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC has a PCI bus clock |
+| of 33 MHz |
+| BYTE_ b_TimingUnity : Base time unit (0 to 2) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| ULONG_ ul_TimingInterval: Base time value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base time value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected PCI input clock is wrong |
+| -5: Timing unity selection is wrong |
+| -6: Base timing selection is wrong |
+| -7: 40MHz quartz not on board |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitFrequencyMeasurement(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PCIInputClock,
+ BYTE b_TimingUnity,
+ ULONG ul_TimingInterval, PULONG pul_RealTimingInterval)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_TimerValue = 0;
+ double d_RealTimingInterval;
+ DWORD dw_Status = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ)) {
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if (b_TimingUnity <= 2) {
+ /**********************************/
+ /* Test the base timing selection */
+ /**********************************/
+
+ if (((b_PCIInputClock == APCI1710_30MHZ)
+ && (b_TimingUnity == 0)
+ && (ul_TimingInterval >=
+ 266)
+ && (ul_TimingInterval <=
+ 8738133UL))
+ || ((b_PCIInputClock ==
+ APCI1710_30MHZ)
+ && (b_TimingUnity == 1)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 8738UL))
+ || ((b_PCIInputClock ==
+ APCI1710_30MHZ)
+ && (b_TimingUnity == 2)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 8UL))
+ || ((b_PCIInputClock ==
+ APCI1710_33MHZ)
+ && (b_TimingUnity == 0)
+ && (ul_TimingInterval >=
+ 242)
+ && (ul_TimingInterval <=
+ 7943757UL))
+ || ((b_PCIInputClock ==
+ APCI1710_33MHZ)
+ && (b_TimingUnity == 1)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 7943UL))
+ || ((b_PCIInputClock ==
+ APCI1710_33MHZ)
+ && (b_TimingUnity == 2)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 7UL))
+ || ((b_PCIInputClock ==
+ APCI1710_40MHZ)
+ && (b_TimingUnity == 0)
+ && (ul_TimingInterval >=
+ 200)
+ && (ul_TimingInterval <=
+ 6553500UL))
+ || ((b_PCIInputClock ==
+ APCI1710_40MHZ)
+ && (b_TimingUnity == 1)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 6553UL))
+ || ((b_PCIInputClock ==
+ APCI1710_40MHZ)
+ && (b_TimingUnity == 2)
+ && (ul_TimingInterval >=
+ 1)
+ && (ul_TimingInterval <=
+ 6UL))) {
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock ==
+ APCI1710_40MHZ) {
+ /******************************/
+ /* Test if firmware >= Rev1.5 */
+ /******************************/
+
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3135) {
+ /*********************************/
+ /* Test if 40MHz quartz on board */
+ /*********************************/
+
+ /*INPDW (ps_APCI1710Variable->
+ s_Board [b_BoardHandle].
+ s_BoardInfos.
+ ui_Address + 36 + (64 * b_ModulNbr), &dw_Status); */
+ dw_Status =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 36 +
+ (64 * b_ModulNbr));
+
+ /******************************/
+ /* Test the quartz flag (DQ0) */
+ /******************************/
+
+ if ((dw_Status & 1) != 1) {
+ /*****************************/
+ /* 40MHz quartz not on board */
+ /*****************************/
+
+ DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue
+ =
+ -7;
+ }
+ } else {
+ /*****************************/
+ /* 40MHz quartz not on board */
+ /*****************************/
+ DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue =
+ -7;
+ }
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /***************************/
+ /* Test if not error occur */
+ /***************************/
+
+ if (i_ReturnValue == 0) {
+ /****************************/
+ /* Test the INC_CPT version */
+ /****************************/
+
+ if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131) {
+
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock == APCI1710_40MHZ) {
+ /*********************************/
+ /* Enable the 40MHz quarz (DQ30) */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_ENABLE_40MHZ_FREQUENCY;
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+ else {
+ /**********************************/
+ /* Disable the 40MHz quarz (DQ30) */
+ /**********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_DISABLE_40MHZ_FREQUENCY;
+
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /********************************/
+ /* Calculate the division fator */
+ /********************************/
+
+ fpu_begin();
+ switch (b_TimingUnity) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.00025 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.00025 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.00025 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.00025 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+ *pul_RealTimingInterval
+ =
+ *pul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.25 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.25 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.25 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.25 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+ *pul_RealTimingInterval
+ =
+ *pul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ *
+ (250.0
+ *
+ b_PCIInputClock);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (250.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (250.0 * (double)b_PCIInputClock)) >= (double)((double)*pul_RealTimingInterval + 0.5)) {
+ *pul_RealTimingInterval
+ =
+ *pul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ break;
+ }
+
+ fpu_end();
+ /*************************/
+ /* Write the timer value */
+ /*************************/
+
+ outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + 32 + (64 * b_ModulNbr));
+
+ /*******************************/
+ /* Set the initialisation flag */
+ /*******************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementInit
+ = 1;
+ } else {
+ /***************************/
+ /* Counter not initialised */
+ /***************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue =
+ -3;
+ }
+ } // if (i_ReturnValue == 0)
+ } else {
+ /**********************************/
+ /* Base timing selection is wrong */
+ /**********************************/
+
+ DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /***********************************/
+ /* Timing unity selection is wrong */
+ /***********************************/
+
+ DPRINTK("Timing unity selection is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+ //INSN BITS
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set & Clear Functions for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_BitsType;
+ INT i_ReturnValue = 0;
+ ui_BitsType = CR_CHAN(insn->chanspec);
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ switch (ui_BitsType) {
+ case APCI1710_INCCPT_CLEARCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_ClearCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_CLEARALLCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_ClearAllCounterValue(dev);
+ break;
+
+ case APCI1710_INCCPT_SETINPUTFILTER:
+ i_ReturnValue = i_APCI1710_SetInputFilter(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0], (BYTE) data[1]);
+ break;
+
+ case APCI1710_INCCPT_LATCHCOUNTER:
+ i_ReturnValue = i_APCI1710_LatchCounter(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE:
+ i_ReturnValue = i_APCI1710_SetIndexAndReferenceSource(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_SETDIGITALCHLON:
+ i_ReturnValue = i_APCI1710_SetDigitalChlOn(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_SETDIGITALCHLOFF:
+ i_ReturnValue = i_APCI1710_SetDigitalChlOff(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ default:
+ printk("Bits Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ClearCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Clear the counter value from selected module |
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number parameter is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ClearCounterValue(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************/
+ /* Clear the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ClearAllCounterValue |
+| (BYTE_ b_BoardHandle) |
++----------------------------------------------------------------------------+
+| Task : Clear all counter value. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ClearAllCounterValue(struct comedi_device * dev)
+{
+ BYTE b_ModulCpt = 0;
+ INT i_ReturnValue = 0;
+
+ /********************************/
+ /* Test if counter module found */
+ /********************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[0] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[1] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[2] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER
+ || (devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[3] & 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ for (b_ModulCpt = 0; b_ModulCpt < 4; b_ModulCpt++) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulCpt] &
+ 0xFFFF0000UL) ==
+ APCI1710_INCREMENTAL_COUNTER) {
+ /*********************/
+ /* Clear the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulCpt));
+ }
+ }
+ } else {
+ /***************************/
+ /* No counter module found */
+ /***************************/
+
+ DPRINTK("No counter module found\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetInputFilter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_Module, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_Filter) |
++----------------------------------------------------------------------------+
+| Task : Disable or enable the software filter from selected |
+| module (b_ModulNbr). b_Filter determine the filter time|
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
+| BYTE_ b_PCIInputClock : Selection of the PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC has a PCI bus clock |
+| of 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC has a PCI bus clock |
+| of 33 MHz |
+| - APCI1710_40MHZ : |
+| The APCI1710 has a 40MHz |
+| quartz |
+| BYTE_ b_Filter : Filter selection |
+| |
+| 30 MHz |
+| ------ |
+| 0: Software filter not used |
+| 1: Filter from 266ns (3.750000MHz) |
+| 2: Filter from 400ns (2.500000MHz) |
+| 3: Filter from 533ns (1.876170MHz) |
+| 4: Filter from 666ns (1.501501MHz) |
+| 5: Filter from 800ns (1.250000MHz) |
+| 6: Filter from 933ns (1.071800MHz) |
+| 7: Filter from 1066ns (0.938080MHz) |
+| 8: Filter from 1200ns (0.833333MHz) |
+| 9: Filter from 1333ns (0.750000MHz) |
+| 10: Filter from 1466ns (0.682100MHz) |
+| 11: Filter from 1600ns (0.625000MHz) |
+| 12: Filter from 1733ns (0.577777MHz) |
+| 13: Filter from 1866ns (0.535900MHz) |
+| 14: Filter from 2000ns (0.500000MHz) |
+| 15: Filter from 2133ns (0.468800MHz) |
+| |
+| 33 MHz |
+| ------ |
+| 0: Software filter not used |
+| 1: Filter from 242ns (4.125000MHz) |
+| 2: Filter from 363ns (2.754820MHz) |
+| 3: Filter from 484ns (2.066115MHz) |
+| 4: Filter from 605ns (1.652892MHz) |
+| 5: Filter from 726ns (1.357741MHz) |
+| 6: Filter from 847ns (1.180637MHz) |
+| 7: Filter from 968ns (1.033055MHz) |
+| 8: Filter from 1089ns (0.918273MHz) |
+| 9: Filter from 1210ns (0.826446MHz) |
+| 10: Filter from 1331ns (0.751314MHz) |
+| 11: Filter from 1452ns (0.688705MHz) |
+| 12: Filter from 1573ns (0.635727MHz) |
+| 13: Filter from 1694ns (0.590318MHz) |
+| 14: Filter from 1815ns (0.550964MHz) |
+| 15: Filter from 1936ns (0.516528MHz) |
+| |
+| 40 MHz |
+| ------ |
+| 0: Software filter not used |
+| 1: Filter from 200ns (5.000000MHz) |
+| 2: Filter from 300ns (3.333333MHz) |
+| 3: Filter from 400ns (2.500000MHz) |
+| 4: Filter from 500ns (2.000000MHz) |
+| 5: Filter from 600ns (1.666666MHz) |
+| 6: Filter from 700ns (1.428500MHz) |
+| 7: Filter from 800ns (1.250000MHz) |
+| 8: Filter from 900ns (1.111111MHz) |
+| 9: Filter from 1000ns (1.000000MHz) |
+| 10: Filter from 1100ns (0.909090MHz) |
+| 11: Filter from 1200ns (0.833333MHz) |
+| 12: Filter from 1300ns (0.769200MHz) |
+| 13: Filter from 1400ns (0.714200MHz) |
+| 14: Filter from 1500ns (0.666666MHz) |
+| 15: Filter from 1600ns (0.625000MHz) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: The module is not a counter module |
+| -4: The selected PCI input clock is wrong |
+| -5: The selected filter value is wrong |
+| -6: 40MHz quartz not on board |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetInputFilter(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_PCIInputClock, BYTE b_Filter)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+ /******************************/
+ /* Test if firmware >= Rev1.5 */
+ /******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF) >= 0x3135) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ)) {
+ /*************************/
+ /* Test the filter value */
+ /*************************/
+
+ if (b_Filter < 16) {
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock ==
+ APCI1710_40MHZ) {
+ /*********************************/
+ /* Test if 40MHz quartz on board */
+ /*********************************/
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 36 +
+ (64 * b_ModulNbr));
+
+ /******************************/
+ /* Test the quartz flag (DQ0) */
+ /******************************/
+
+ if ((dw_Status & 1) !=
+ 1) {
+ /*****************************/
+ /* 40MHz quartz not on board */
+ /*****************************/
+
+ DPRINTK("40MHz quartz not on board\n");
+ i_ReturnValue =
+ -6;
+ }
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /***************************/
+ /* Test if error not occur */
+ /***************************/
+
+ if (i_ReturnValue == 0) {
+ /**********************/
+ /* Test if 40MHz used */
+ /**********************/
+
+ if (b_PCIInputClock ==
+ APCI1710_40MHZ)
+ {
+ /*********************************/
+ /* Enable the 40MHz quarz (DQ31) */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ |
+ APCI1710_ENABLE_40MHZ_FILTER;
+
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+ else {
+ /**********************************/
+ /* Disable the 40MHz quarz (DQ31) */
+ /**********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ &
+ APCI1710_DISABLE_40MHZ_FILTER;
+
+ } // if (b_PCIInputClock == APCI1710_40MHZ)
+
+ /************************/
+ /* Set the filter value */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3
+ & 0x1F) |
+ ((b_Filter &
+ 0x7) <<
+ 5);
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4
+ & 0xFE) |
+ ((b_Filter &
+ 0x8) >>
+ 3);
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+ } // if (i_ReturnValue == 0)
+ } // if (b_Filter < 16)
+ else {
+ /**************************************/
+ /* The selected filter value is wrong */
+ /**************************************/
+
+ DPRINTK("The selected filter value is wrong\n");
+ i_ReturnValue = -5;
+ } // if (b_Filter < 16)
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))
+ else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = 4;
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ) || (b_PCIInputClock == APCI1710_40MHZ))
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_LatchCounter (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_LatchReg) |
++----------------------------------------------------------------------------+
+| Task : Latch the courant value from selected module |
+| (b_ModulNbr) in to the selected latch register |
+| (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_LatchReg : Selected latch register |
+| 0 : for the first latch register |
+| 1 : for the second latch register |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected latch register parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_LatchCounter(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test the latch register parameter */
+ /*************************************/
+
+ if (b_LatchReg < 2) {
+ /*********************/
+ /* Tatch the counter */
+ /*********************/
+
+ outl(1 << (b_LatchReg * 4),
+ devpriv->s_BoardInfos.ui_Address +
+ (64 * b_ModulNbr));
+ } else {
+ /**************************************************/
+ /* The selected latch register parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetIndexAndReferenceSource |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SourceSelection) |
++----------------------------------------------------------------------------+
+| Task : Determine the hardware source for the index and the |
+| reference logic. Per default the index logic is |
+| connected to the difference input C and the reference |
+| logic is connected to the 24V input E |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_SourceSelection : APCI1710_SOURCE_0 : |
+| The index logic is connected |
+| to the difference input C and|
+| the reference logic is |
+| connected to the 24V input E.|
+| This is the default |
+| configuration. |
+| APCI1710_SOURCE_1 : |
+| The reference logic is |
+| connected to the difference |
+| input C and the index logic |
+| is connected to the 24V |
+| input E |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: The module is not a counter module. |
+| -4: The source selection is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetIndexAndReferenceSource(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_SourceSelection)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if incremental counter */
+ /*******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+ /******************************/
+ /* Test if firmware >= Rev1.5 */
+ /******************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF) >= 0x3135) {
+ /*****************************/
+ /* Test the source selection */
+ /*****************************/
+
+ if (b_SourceSelection == APCI1710_SOURCE_0 ||
+ b_SourceSelection == APCI1710_SOURCE_1)
+ {
+ /******************************************/
+ /* Test if invert the index and reference */
+ /******************************************/
+
+ if (b_SourceSelection ==
+ APCI1710_SOURCE_1) {
+ /********************************************/
+ /* Invert index and reference source (DQ25) */
+ /********************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 |
+ APCI1710_INVERT_INDEX_RFERENCE;
+ } else {
+ /****************************************/
+ /* Set the default configuration (DQ25) */
+ /****************************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister4 &
+ APCI1710_DEFAULT_INDEX_RFERENCE;
+ }
+ } // if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)
+ else {
+ /*********************************/
+ /* The source selection is wrong */
+ /*********************************/
+
+ DPRINTK("The source selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_SourceSelection == APCI1710_SOURCE_0 ||b_SourceSelection == APCI1710_SOURCE_1)
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a counter module */
+ /**************************************/
+
+ DPRINTK("The module is not a counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***************************************/
+ /* The selected module number is wrong */
+ /***************************************/
+
+ DPRINTK("The selected module number is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetDigitalChlOn |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Sets the digital output H Setting an output means |
+| setting an ouput high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetDigitalChlOn(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.b_ModeRegister3 | 0x10;
+
+ /*********************/
+ /* Set the output On */
+ /*********************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetDigitalChlOff |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Resets the digital output H. Resetting an output means |
+| setting an ouput low. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Number of the module to be |
+| configured (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The selected module number is wrong |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetDigitalChlOff(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.b_ModeRegister3 & 0xEF;
+
+ /**********************/
+ /* Set the output Off */
+ /**********************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+ // INSN WRITE
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Enable Disable functions for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_InsnWriteINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_WriteType;
+ INT i_ReturnValue = 0;
+
+ ui_WriteType = CR_CHAN(insn->chanspec);
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ switch (ui_WriteType) {
+ case APCI1710_INCCPT_ENABLELATCHINTERRUPT:
+ i_ReturnValue = i_APCI1710_EnableLatchInterrupt(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_DISABLELATCHINTERRUPT:
+ i_ReturnValue = i_APCI1710_DisableLatchInterrupt(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_WRITE16BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Write16BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0], (UINT) data[1]);
+ break;
+
+ case APCI1710_INCCPT_WRITE32BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Write32BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec), (ULONG) data[0]);
+
+ break;
+
+ case APCI1710_INCCPT_ENABLEINDEX:
+ i_APCI1710_EnableIndex(dev, (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_DISABLEINDEX:
+ i_ReturnValue = i_APCI1710_DisableIndex(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_ENABLECOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_EnableCompareLogic(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_DISABLECOMPARELOGIC:
+ i_ReturnValue = i_APCI1710_DisableCompareLogic(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ case APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_EnableFrequencyMeasurement(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_DisableFrequencyMeasurement(dev,
+ (BYTE) CR_AREF(insn->chanspec));
+ break;
+
+ default:
+ printk("Write Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableLatchInterrupt |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Enable the latch interrupt from selected module |
+| (b_ModulNbr). Each software or hardware latch occur a |
+| interrupt. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Interrupt routine not installed see function |
+| "i_APCI1710_SetBoardIntRoutine" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableLatchInterrupt(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+ /********************/
+ /* Enable interrupt */
+ /********************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 | APCI1710_ENABLE_LATCH_INT;
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4, devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableLatchInterrupt |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Disable the latch interrupt from selected module |
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Interrupt routine not installed see function |
+| "i_APCI1710_SetBoardIntRoutine" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableLatchInterrupt(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4 &
+ ((APCI1710_DISABLE_LATCH_INT << 8) | 0xFF),
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ mdelay(1000);
+
+ /*********************/
+ /* Disable interrupt */
+ /*********************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 & APCI1710_DISABLE_LATCH_INT;
+
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Write16BitCounterValue |
+| (BYTE_ b_BoardHandle |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedCounter, |
+| UINT_ ui_WriteValue) |
++----------------------------------------------------------------------------+
+| Task : Write a 16-Bit value (ui_WriteValue) in to the selected|
+| 16-Bit counter (b_SelectedCounter) from selected module|
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_SelectedCounter : Selected 16-Bit counter |
+| (0 or 1) |
+| UINT_ ui_WriteValue : 16-Bit write value |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected 16-Bit counter parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Write16BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter, UINT ui_WriteValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /******************************/
+ /* Test the counter selection */
+ /******************************/
+
+ if (b_SelectedCounter < 2) {
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ outl((ULONG) ((ULONG) (ui_WriteValue) << (16 *
+ b_SelectedCounter)),
+ devpriv->s_BoardInfos.ui_Address + 8 +
+ (b_SelectedCounter * 4) +
+ (64 * b_ModulNbr));
+ } else {
+ /**************************************************/
+ /* The selected 16-Bit counter parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Write32BitCounterValue |
+| (BYTE_ b_BoardHandle |
+| BYTE_ b_ModulNbr, |
+| ULONG_ ul_WriteValue) |
++----------------------------------------------------------------------------+
+| Task : Write a 32-Bit value (ui_WriteValue) in to the selected|
+| module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| ULONG_ ul_WriteValue : 32-Bit write value |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Write32BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, ULONG ul_WriteValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ outl(ul_WriteValue, devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableIndex (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Enable the INDEX actions |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Index not initialised see function |
+| "i_APCI1710_InitIndex" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableIndex(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_InterruptLatchReg;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*****************************/
+ /* Test if index initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 | APCI1710_ENABLE_INDEX;
+
+ ul_InterruptLatchReg =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ 24 + (64 * b_ModulNbr));
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*************************************************************/
+ /* Index not initialised see function "i_APCI1710_InitIndex" */
+ /*************************************************************/
+
+ DPRINTK("Index not initialised \n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableIndex (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Disable the INDEX actions |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Index not initialised see function |
+| "i_APCI1710_InitIndex" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableIndex(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*****************************/
+ /* Test if index initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 &
+ APCI1710_DISABLE_INDEX;
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*************************************************************/
+ /* Index not initialised see function "i_APCI1710_InitIndex" */
+ /*************************************************************/
+
+ DPRINTK("Index not initialised \n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableCompareLogic |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Enable the 32-Bit compare logic. At that moment that |
+| the incremental counter arrive to the compare value a |
+| interrupt is generated. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : -
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Compare logic not initialised. |
+| See function "i_APCI1710_InitCompareLogic" |
+| -5: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnableCompareLogic(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test if compare logic initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CompareLogicInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 |
+ APCI1710_ENABLE_COMPARE_INT;
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*********************************/
+ /* Compare logic not initialised */
+ /*********************************/
+
+ DPRINTK("Compare logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableCompareLogic |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Task : Disable the 32-Bit compare logic.
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : -
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Compare logic not initialised. |
+| See function "i_APCI1710_InitCompareLogic" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisableCompareLogic(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test if compare logic initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_CompareLogicInit == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_DISABLE_COMPARE_INT;
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ } else {
+ /*********************************/
+ /* Compare logic not initialised */
+ /*********************************/
+
+ DPRINTK("Compare logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_EnableFrequencyMeasurement |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | BYTE_ b_InterruptEnable) |
+ +----------------------------------------------------------------------------+
+ | Task : Enables the frequency measurement function |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Number of the module to be |
+ | configured (0 to 3) |
+ | BYTE_ b_InterruptEnable: Enable or disable the |
+ | interrupt. |
+ | APCI1710_ENABLE: |
+ | Enable the interrupt |
+ | APCI1710_DISABLE: |
+ | Disable the interrupt |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : - |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: The selected module number is wrong |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ | -4: Frequency measurement logic not initialised. |
+ | See function "i_APCI1710_InitFrequencyMeasurement" |
+ | -5: Interrupt parameter is wrong |
+ | -6: Interrupt function not initialised. |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_EnableFrequencyMeasurement(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_InterruptEnable)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************************/
+ /* Test if frequency mesurement initialised */
+ /********************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_FrequencyMeasurementInit == 1) {
+ /***************************/
+ /* Test the interrupt mode */
+ /***************************/
+
+ if ((b_InterruptEnable == APCI1710_DISABLE) ||
+ (b_InterruptEnable == APCI1710_ENABLE))
+ {
+
+ /************************************/
+ /* Enable the frequency measurement */
+ /************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 |
+ APCI1710_ENABLE_FREQUENCY;
+
+ /*********************************************/
+ /* Disable or enable the frequency interrupt */
+ /*********************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_DISABLE_FREQUENCY_INT)
+ | (b_InterruptEnable << 3);
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementEnable =
+ 1;
+ } else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /***********************************************/
+ /* Frequency measurement logic not initialised */
+ /***********************************************/
+
+ DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_DisableFrequencyMeasurement |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr) |
+ +----------------------------------------------------------------------------+
+ | Task : Disables the frequency measurement function |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Number of the module to be |
+ | configured (0 to 3) |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : - |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: The selected module number is wrong |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ | -4: Frequency measurement logic not initialised. |
+ | See function "i_APCI1710_InitFrequencyMeasurement" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_DisableFrequencyMeasurement(struct comedi_device * dev, BYTE b_ModulNbr)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************************/
+ /* Test if frequency mesurement initialised */
+ /********************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_FrequencyMeasurementInit == 1) {
+ /*************************************/
+ /* Disable the frequency measurement */
+ /*************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_DISABLE_FREQUENCY
+ // Begin CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared
+ & APCI1710_DISABLE_FREQUENCY_INT;
+ // End CG 29/06/01 CG 1100/0231 -> 0701/0232 Frequence measure IRQ must be cleared
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+
+ /*************************************/
+ /* Disable the frequency measurement */
+ /*************************************/
+
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementEnable = 0;
+ } else {
+ /***********************************************/
+ /* Frequency measurement logic not initialised */
+ /***********************************************/
+
+ DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*########################################################################### */
+
+ // INSN READ
+
+/*########################################################################### */
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev,struct comedi_subdevice *s,
+struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read and Get functions for INC_CPT |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1710_InsnReadINCCPT(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_ReadType;
+ INT i_ReturnValue = 0;
+
+ ui_ReadType = CR_CHAN(insn->chanspec);
+
+ devpriv->tsk_Current = current; // Save the current process task structure
+ switch (ui_ReadType) {
+ case APCI1710_INCCPT_READLATCHREGISTERSTATUS:
+ i_ReturnValue = i_APCI1710_ReadLatchRegisterStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_RANGE(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_READLATCHREGISTERVALUE:
+ i_ReturnValue = i_APCI1710_ReadLatchRegisterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_RANGE(insn->chanspec), (PULONG) & data[0]);
+ printk("Latch Register Value %d\n", data[0]);
+ break;
+
+ case APCI1710_INCCPT_READ16BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Read16BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) CR_RANGE(insn->chanspec), (PUINT) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_READ32BITCOUNTERVALUE:
+ i_ReturnValue = i_APCI1710_Read32BitCounterValue(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PULONG) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETINDEXSTATUS:
+ i_ReturnValue = i_APCI1710_GetIndexStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETREFERENCESTATUS:
+ i_ReturnValue = i_APCI1710_GetReferenceStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETUASSTATUS:
+ i_ReturnValue = i_APCI1710_GetUASStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GETCBSTATUS:
+ i_ReturnValue = i_APCI1710_GetCBStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_GET16BITCBSTATUS:
+ i_ReturnValue = i_APCI1710_Get16BitCBStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (PBYTE) & data[0], (PBYTE) & data[1]);
+ break;
+
+ case APCI1710_INCCPT_GETUDSTATUS:
+ i_ReturnValue = i_APCI1710_GetUDStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+
+ break;
+
+ case APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS:
+ i_ReturnValue = i_APCI1710_GetInterruptUDLatchedStatus(dev,
+ (BYTE) CR_AREF(insn->chanspec), (PBYTE) & data[0]);
+ break;
+
+ case APCI1710_INCCPT_READFREQUENCYMEASUREMENT:
+ i_ReturnValue = i_APCI1710_ReadFrequencyMeasurement(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (PBYTE) & data[0],
+ (PBYTE) & data[1], (PULONG) & data[2]);
+ break;
+
+ case APCI1710_INCCPT_READINTERRUPT:
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ break;
+
+ default:
+ printk("ReadType Parameter wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadLatchRegisterStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_LatchReg, |
+| PBYTE_ pb_LatchStatus) |
++----------------------------------------------------------------------------+
+| Task : Read the latch register status from selected module |
+| (b_ModulNbr) and selected latch register (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_LatchReg : Selected latch register |
+| 0 : for the first latch register |
+| 1 : for the second latch register |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_LatchStatus : Latch register status. |
+| 0 : No latch occur |
+| 1 : A software latch occur |
+| 2 : A hardware latch occur |
+| 3 : A software and hardware |
+| latch occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected latch register parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadLatchRegisterStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg, PBYTE pb_LatchStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_LatchReg;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test the latch register parameter */
+ /*************************************/
+
+ if (b_LatchReg < 2) {
+ dw_LatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ *pb_LatchStatus =
+ (BYTE) ((dw_LatchReg >> (b_LatchReg *
+ 4)) & 0x3);
+ } else {
+ /**************************************************/
+ /* The selected latch register parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadLatchRegisterValue |
+| (BYTE_ b_BoardHandle,|
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_LatchReg, |
+| PULONG_ pul_LatchValue) |
++----------------------------------------------------------------------------+
+| Task : Read the latch register value from selected module |
+| (b_ModulNbr) and selected latch register (b_LatchReg). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_LatchReg : Selected latch register |
+| 0 : for the first latch register |
+| 1 : for the second latch register |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_LatchValue : Latch register value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected latch register parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_ReadLatchRegisterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg, PULONG pul_LatchValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************************/
+ /* Test the latch register parameter */
+ /*************************************/
+
+ if (b_LatchReg < 2) {
+ *pul_LatchValue = inl(devpriv->s_BoardInfos.
+ ui_Address + ((b_LatchReg + 1) * 4) +
+ (64 * b_ModulNbr));
+
+ } else {
+ /**************************************************/
+ /* The selected latch register parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected latch register parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Read16BitCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedCounter, |
+| PUINT_ pui_CounterValue) |
++----------------------------------------------------------------------------+
+| Task : Latch the selected 16-Bit counter (b_SelectedCounter) |
+| from selected module (b_ModulNbr) in to the first |
+| latch register and return the latched value. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| BYTE_ b_SelectedCounter : Selected 16-Bit counter |
+| (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : PUINT_ pui_CounterValue : 16-Bit counter value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: The selected 16-Bit counter parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Read16BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter, PUINT pui_CounterValue)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_LathchValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /******************************/
+ /* Test the counter selection */
+ /******************************/
+
+ if (b_SelectedCounter < 2) {
+ /*********************/
+ /* Latch the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ /************************/
+ /* Read the latch value */
+ /************************/
+
+ dw_LathchValue = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulNbr));
+
+ *pui_CounterValue =
+ (UINT) ((dw_LathchValue >> (16 *
+ b_SelectedCounter)) &
+ 0xFFFFU);
+ } else {
+ /**************************************************/
+ /* The selected 16-Bit counter parameter is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected 16-Bit counter parameter is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Read32BitCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PULONG_ pul_CounterValue) |
++----------------------------------------------------------------------------+
+| Task : Latch the 32-Bit counter from selected module |
+| (b_ModulNbr) in to the first latch register and return |
+| the latched value. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_CounterValue : 32-Bit counter value |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Read32BitCounterValue(struct comedi_device * dev,
+ BYTE b_ModulNbr, PULONG pul_CounterValue)
+{
+ INT i_ReturnValue = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************/
+ /* Tatch the counter */
+ /*********************/
+
+ outl(1, devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ /************************/
+ /* Read the latch value */
+ /************************/
+
+ *pul_CounterValue = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (64 * b_ModulNbr));
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetIndexStatus (BYTE_ b_BoardHandle,|
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_IndexStatus)|
++----------------------------------------------------------------------------+
+| Task : Return the index status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_IndexStatus : 0 : No INDEX occur |
+| 1 : A INDEX occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Index not initialised see function |
+| "i_APCI1710_InitIndex" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetIndexStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_IndexStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*****************************/
+ /* Test if index initialised */
+ /*****************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_IndexInit) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModulNbr));
+
+ *pb_IndexStatus = (BYTE) (dw_StatusReg & 1);
+ } else {
+ /*************************************************************/
+ /* Index not initialised see function "i_APCI1710_InitIndex" */
+ /*************************************************************/
+
+ DPRINTK("Index not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetReferenceStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_ReferenceStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the reference status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ReferenceStatus : 0 : No REFERENCE occur |
+| 1 : A REFERENCE occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Reference not initialised see function |
+| "i_APCI1710_InitReference" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetReferenceStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_ReferenceStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************************/
+ /* Test if reference initialised */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_ReferenceInit) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModulNbr));
+
+ *pb_ReferenceStatus =
+ (BYTE) (~dw_StatusReg & 1);
+ } else {
+ /*********************************************************************/
+ /* Reference not initialised see function "i_APCI1710_InitReference" */
+ /*********************************************************************/
+
+ DPRINTK("Reference not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetUASStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_UASStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the error signal (UAS) status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UASStatus : 0 : UAS is low "0" |
+| 1 : UAS is high "1" |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetUASStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_UASStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModulNbr));
+
+ *pb_UASStatus = (BYTE) ((dw_StatusReg >> 1) & 1);
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetCBStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_CBStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the counter overflow status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_CBStatus : 0 : Counter no overflow |
+| 1 : Counter overflow |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetCBStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModulNbr));
+
+ *pb_CBStatus = (BYTE) (dw_StatusReg & 1);
+
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Get16BitCBStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_CBStatusCounter0, |
+| PBYTE_ pb_CBStatusCounter1) |
++----------------------------------------------------------------------------+
+| Task : Returns the counter overflow (counter initialised to |
+| 2*16-bit) status from selected incremental counter |
+| module |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_CBStatusCounter0 : 0 : No overflow occur for |
+| the first 16-bit |
+| counter |
+| 1 : Overflow occur for the|
+| first 16-bit counter |
+| PBYTE_ pb_CBStatusCounter1 : 0 : No overflow occur for |
+| the second 16-bit |
+| counter |
+| 1 : Overflow occur for the|
+| second 16-bit counter |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Counter not initialised to 2*16-bit mode. |
+| See function "i_APCI1710_InitCounter" |
+| -5: Firmware revision error |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_Get16BitCBStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0, PBYTE pb_CBStatusCounter1)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*************************/
+ /* Test if 2*16-Bit mode */
+ /*************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 & 0x10) == 0x10) {
+ /*****************************/
+ /* Test the Firmware version */
+ /*****************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] & 0xFFFF) >=
+ 0x3136) {
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ *pb_CBStatusCounter1 =
+ (BYTE) ((dw_StatusReg >> 0) &
+ 1);
+ *pb_CBStatusCounter0 =
+ (BYTE) ((dw_StatusReg >> 1) &
+ 1);
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)
+ else {
+ /****************************/
+ /* Firmware revision error */
+ /****************************/
+
+ i_ReturnValue = -5;
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_BoardInfos.dw_MolduleConfiguration [b_ModulNbr] & 0xFFFF) >= 0x3136)
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)
+ else {
+ /********************************************/
+ /* Counter not initialised to 2*16-bit mode */
+ /* "i_APCI1710_InitCounter" */
+ /********************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -4;
+ } // if ((ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & 0x10) == 0x10)
+ } // if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)
+ else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ } // if (ps_APCI1710Variable->s_Board [b_BoardHandle].s_ModuleInfo [b_ModulNbr].s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1)
+ } // if (b_ModulNbr < 4)
+ else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ } // if (b_ModulNbr < 4)
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetUDStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_UDStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the counter progress status |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UDStatus : 0 : Counter progress in the |
+| selected mode down |
+| 1 : Counter progress in the |
+| selected mode up |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetUDStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModulNbr));
+
+ *pb_UDStatus = (BYTE) ((dw_StatusReg >> 2) & 1);
+
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetInterruptUDLatchedStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| PBYTE_ pb_UDStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the counter progress latched status after a |
+| index interrupt occur. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_UDStatus : 0 : Counter progress in the |
+| selected mode down |
+| 1 : Counter progress in the |
+| selected mode up |
+| 2 : No index interrupt occur |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: No counter module found |
+| -3: Counter not initialised see function |
+| "i_APCI1710_InitCounter" |
+| -4: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device * dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /*********************************/
+ /* Test if index interrupt occur */
+ /*********************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_IndexInterruptOccur == 1) {
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_IndexInterruptOccur = 0;
+
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModulNbr));
+
+ *pb_UDStatus = (BYTE) ((dw_StatusReg >> 1) & 1);
+ } else {
+ /****************************/
+ /* No index interrupt occur */
+ /****************************/
+
+ *pb_UDStatus = 2;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : _INT_ i_APCI1710_ReadFrequencyMeasurement |
+ | (BYTE_ b_BoardHandle, |
+ | BYTE_ b_ModulNbr, |
+ | PBYTE_ pb_Status, |
+ | PULONG_ pul_ReadValue) |
+ +----------------------------------------------------------------------------+
+ | Task : Returns the status (pb_Status) and the number of |
+ | increments in the set time. |
+ | See function " i_APCI1710_InitFrequencyMeasurement " |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+ | BYTE_ b_ModulNbr : Number of the module to be |
+ | configured (0 to 3) |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : PBYTE_ pb_Status : Returns the frequency |
+ | measurement status |
+ | 0 : Counting cycle not |
+ | started. |
+ | 1 : Counting cycle started. |
+ | 2 : Counting cycle stopped. |
+ | The measurement cycle is |
+ | completed. |
+ | PBYTE_ pb_UDStatus : 0 : Counter progress in the |
+ | selected mode down |
+ | 1 : Counter progress in the |
+ | selected mode up |
+ | PULONG_ pul_ReadValue : Return the number of |
+ | increments in the defined |
+ | time base. |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0: No error |
+ | -1: The handle parameter of the board is wrong |
+ | -2: The selected module number is wrong |
+ | -3: Counter not initialised see function |
+ | "i_APCI1710_InitCounter" |
+ | -4: Frequency measurement logic not initialised. |
+ | See function "i_APCI1710_InitFrequencyMeasurement" |
+ +----------------------------------------------------------------------------+
+ */
+
+INT i_APCI1710_ReadFrequencyMeasurement(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ PBYTE pb_Status, PBYTE pb_UDStatus, PULONG pul_ReadValue)
+{
+ INT i_ReturnValue = 0;
+ UINT ui_16BitValue;
+ DWORD dw_StatusReg;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.s_InitFlag.b_CounterInit == 1) {
+ /********************************************/
+ /* Test if frequency mesurement initialised */
+ /********************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.b_FrequencyMeasurementInit == 1) {
+ /******************/
+ /* Test if enable */
+ /******************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SiemensCounterInfo.
+ s_InitFlag.
+ b_FrequencyMeasurementEnable == 1) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 32 +
+ (64 * b_ModulNbr));
+
+ /**************************/
+ /* Test if frequency stop */
+ /**************************/
+
+ if (dw_StatusReg & 1) {
+ *pb_Status = 2;
+ *pb_UDStatus =
+ (BYTE) ((dw_StatusReg >>
+ 1) & 3);
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_ReadValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 28 +
+ (64 * b_ModulNbr));
+
+ if (*pb_UDStatus == 0) {
+ /*************************/
+ /* Test the counter mode */
+ /*************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModulNbr].s_SiemensCounterInfo.s_ModeRegister.s_ByteModeRegister.b_ModeRegister1 & APCI1710_16BIT_COUNTER) == APCI1710_16BIT_COUNTER) {
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFFU) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ *
+ pul_ReadValue
+ &
+ 0xFFFFU;
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFF0000UL)
+ |
+ (0xFFFFU
+ -
+ ui_16BitValue);
+ }
+
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFF0000UL) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ (
+ (*pul_ReadValue
+ >>
+ 16)
+ &
+ 0xFFFFU);
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFFUL)
+ |
+ (
+ (0xFFFFU - ui_16BitValue) << 16);
+ }
+ } else {
+ if (*pul_ReadValue != 0) {
+ *pul_ReadValue
+ =
+ 0xFFFFFFFFUL
+ -
+ *pul_ReadValue;
+ }
+ }
+ } else {
+ if (*pb_UDStatus == 1) {
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFF0000UL) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ (
+ (*pul_ReadValue
+ >>
+ 16)
+ &
+ 0xFFFFU);
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFFUL)
+ |
+ (
+ (0xFFFFU - ui_16BitValue) << 16);
+ }
+ } else {
+ if (*pb_UDStatus
+ == 2) {
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((*pul_ReadValue & 0xFFFFU) != 0) {
+ ui_16BitValue
+ =
+ (UINT)
+ *
+ pul_ReadValue
+ &
+ 0xFFFFU;
+ *pul_ReadValue
+ =
+ (*pul_ReadValue
+ &
+ 0xFFFF0000UL)
+ |
+ (0xFFFFU
+ -
+ ui_16BitValue);
+ }
+ }
+ }
+ }
+ } else {
+ *pb_Status = 1;
+ *pb_UDStatus = 0;
+ }
+ } else {
+ *pb_Status = 0;
+ *pb_UDStatus = 0;
+ }
+ } else {
+ /***********************************************/
+ /* Frequency measurement logic not initialised */
+ /***********************************************/
+
+ DPRINTK("Frequency measurement logic not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /****************************************/
+ /* Counter not initialised see function */
+ /* "i_APCI1710_InitCounter" */
+ /****************************************/
+
+ DPRINTK("Counter not initialised\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*************************************************/
+ /* The selected module number parameter is wrong */
+ /*************************************************/
+
+ DPRINTK("The selected module number parameter is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
new file mode 100644
index 00000000000..5153cf68665
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_INCCPT.h
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_16BIT_COUNTER 0x10
+#define APCI1710_32BIT_COUNTER 0x0
+#define APCI1710_QUADRUPLE_MODE 0x0
+#define APCI1710_DOUBLE_MODE 0x3
+#define APCI1710_SIMPLE_MODE 0xF
+#define APCI1710_DIRECT_MODE 0x80
+#define APCI1710_HYSTERESIS_ON 0x60
+#define APCI1710_HYSTERESIS_OFF 0x0
+#define APCI1710_INCREMENT 0x60
+#define APCI1710_DECREMENT 0x0
+#define APCI1710_LATCH_COUNTER 0x1
+#define APCI1710_CLEAR_COUNTER 0x0
+#define APCI1710_LOW 0x0
+#define APCI1710_HIGH 0x1
+
+/*********************/
+/* Version 0600-0229 */
+/*********************/
+#define APCI1710_HIGH_EDGE_CLEAR_COUNTER 0x0
+#define APCI1710_HIGH_EDGE_LATCH_COUNTER 0x1
+#define APCI1710_LOW_EDGE_CLEAR_COUNTER 0x2
+#define APCI1710_LOW_EDGE_LATCH_COUNTER 0x3
+#define APCI1710_HIGH_EDGE_LATCH_AND_CLEAR_COUNTER 0x4
+#define APCI1710_LOW_EDGE_LATCH_AND_CLEAR_COUNTER 0x5
+#define APCI1710_SOURCE_0 0x0
+#define APCI1710_SOURCE_1 0x1
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_ENABLE_LATCH_INT 0x80
+#define APCI1710_DISABLE_LATCH_INT (~APCI1710_ENABLE_LATCH_INT)
+
+#define APCI1710_INDEX_LATCH_COUNTER 0x10
+#define APCI1710_INDEX_AUTO_MODE 0x8
+#define APCI1710_ENABLE_INDEX 0x4
+#define APCI1710_DISABLE_INDEX (~APCI1710_ENABLE_INDEX)
+#define APCI1710_ENABLE_LATCH_AND_CLEAR 0x8
+#define APCI1710_DISABLE_LATCH_AND_CLEAR (~APCI1710_ENABLE_LATCH_AND_CLEAR)
+#define APCI1710_SET_LOW_INDEX_LEVEL 0x4
+#define APCI1710_SET_HIGH_INDEX_LEVEL (~APCI1710_SET_LOW_INDEX_LEVEL)
+#define APCI1710_INVERT_INDEX_RFERENCE 0x2
+#define APCI1710_DEFAULT_INDEX_RFERENCE (~APCI1710_INVERT_INDEX_RFERENCE)
+
+#define APCI1710_ENABLE_INDEX_INT 0x1
+#define APCI1710_DISABLE_INDEX_INT (~APCI1710_ENABLE_INDEX_INT)
+
+#define APCI1710_ENABLE_FREQUENCY 0x4
+#define APCI1710_DISABLE_FREQUENCY (~APCI1710_ENABLE_FREQUENCY)
+
+#define APCI1710_ENABLE_FREQUENCY_INT 0x8
+#define APCI1710_DISABLE_FREQUENCY_INT (~APCI1710_ENABLE_FREQUENCY_INT)
+
+#define APCI1710_ENABLE_40MHZ_FREQUENCY 0x40
+#define APCI1710_DISABLE_40MHZ_FREQUENCY (~APCI1710_ENABLE_40MHZ_FREQUENCY)
+
+#define APCI1710_ENABLE_40MHZ_FILTER 0x80
+#define APCI1710_DISABLE_40MHZ_FILTER (~APCI1710_ENABLE_40MHZ_FILTER)
+
+#define APCI1710_ENABLE_COMPARE_INT 0x2
+#define APCI1710_DISABLE_COMPARE_INT (~APCI1710_ENABLE_COMPARE_INT)
+
+#define APCI1710_ENABLE_INDEX_ACTION 0x20
+#define APCI1710_DISABLE_INDEX_ACTION (~APCI1710_ENABLE_INDEX_ACTION)
+#define APCI1710_REFERENCE_HIGH 0x40
+#define APCI1710_REFERENCE_LOW (~APCI1710_REFERENCE_HIGH)
+
+#define APCI1710_TOR_GATE_LOW 0x40
+#define APCI1710_TOR_GATE_HIGH (~APCI1710_TOR_GATE_LOW)
+
+/* INSN CONFIG */
+#define APCI1710_INCCPT_INITCOUNTER 100
+#define APCI1710_INCCPT_COUNTERAUTOTEST 101
+#define APCI1710_INCCPT_INITINDEX 102
+#define APCI1710_INCCPT_INITREFERENCE 103
+#define APCI1710_INCCPT_INITEXTERNALSTROBE 104
+#define APCI1710_INCCPT_INITCOMPARELOGIC 105
+#define APCI1710_INCCPT_INITFREQUENCYMEASUREMENT 106
+
+/* INSN READ */
+#define APCI1710_INCCPT_READLATCHREGISTERSTATUS 200
+#define APCI1710_INCCPT_READLATCHREGISTERVALUE 201
+#define APCI1710_INCCPT_READ16BITCOUNTERVALUE 202
+#define APCI1710_INCCPT_READ32BITCOUNTERVALUE 203
+#define APCI1710_INCCPT_GETINDEXSTATUS 204
+#define APCI1710_INCCPT_GETREFERENCESTATUS 205
+#define APCI1710_INCCPT_GETUASSTATUS 206
+#define APCI1710_INCCPT_GETCBSTATUS 207
+#define APCI1710_INCCPT_GET16BITCBSTATUS 208
+#define APCI1710_INCCPT_GETUDSTATUS 209
+#define APCI1710_INCCPT_GETINTERRUPTUDLATCHEDSTATUS 210
+#define APCI1710_INCCPT_READFREQUENCYMEASUREMENT 211
+#define APCI1710_INCCPT_READINTERRUPT 212
+
+/* INSN BITS */
+#define APCI1710_INCCPT_CLEARCOUNTERVALUE 300
+#define APCI1710_INCCPT_CLEARALLCOUNTERVALUE 301
+#define APCI1710_INCCPT_SETINPUTFILTER 302
+#define APCI1710_INCCPT_LATCHCOUNTER 303
+#define APCI1710_INCCPT_SETINDEXANDREFERENCESOURCE 304
+#define APCI1710_INCCPT_SETDIGITALCHLON 305
+#define APCI1710_INCCPT_SETDIGITALCHLOFF 306
+
+/* INSN WRITE */
+#define APCI1710_INCCPT_ENABLELATCHINTERRUPT 400
+#define APCI1710_INCCPT_DISABLELATCHINTERRUPT 401
+#define APCI1710_INCCPT_WRITE16BITCOUNTERVALUE 402
+#define APCI1710_INCCPT_WRITE32BITCOUNTERVALUE 403
+#define APCI1710_INCCPT_ENABLEINDEX 404
+#define APCI1710_INCCPT_DISABLEINDEX 405
+#define APCI1710_INCCPT_ENABLECOMPARELOGIC 406
+#define APCI1710_INCCPT_DISABLECOMPARELOGIC 407
+#define APCI1710_INCCPT_ENABLEFREQUENCYMEASUREMENT 408
+#define APCI1710_INCCPT_DISABLEFREQUENCYMEASUREMENT 409
+
+/************ Main Functions *************/
+INT i_APCI1710_InsnConfigINCCPT(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnBitsINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnWriteINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn *insn, unsigned int * data);
+
+INT i_APCI1710_InsnReadINCCPT(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn *insn, unsigned int * data);
+
+/*********** Supplementary Functions********/
+
+/* INSN CONFIG */
+INT i_APCI1710_InitCounter(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_CounterRange,
+ BYTE b_FirstCounterModus,
+ BYTE b_FirstCounterOption,
+ BYTE b_SecondCounterModus,
+ BYTE b_SecondCounterOption);
+
+INT i_APCI1710_CounterAutoTest(struct comedi_device *dev, PBYTE pb_TestStatus);
+
+INT i_APCI1710_InitIndex(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_ReferenceAction,
+ BYTE b_IndexOperation, BYTE b_AutoMode,
+ BYTE b_InterruptEnable);
+
+INT i_APCI1710_InitReference(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_ReferenceLevel);
+
+INT i_APCI1710_InitExternalStrobe(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_ExternalStrobe,
+ BYTE b_ExternalStrobeLevel);
+
+INT i_APCI1710_InitCompareLogic(struct comedi_device *dev,
+ BYTE b_ModulNbr, UINT ui_CompareValue);
+
+INT i_APCI1710_InitFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PCIInputClock,
+ BYTE b_TimingUnity,
+ ULONG ul_TimingInterval,
+ PULONG pul_RealTimingInterval);
+
+/* INSN BITS */
+INT i_APCI1710_ClearCounterValue(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_ClearAllCounterValue(struct comedi_device *dev);
+
+INT i_APCI1710_SetInputFilter(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_PCIInputClock,
+ BYTE b_Filter);
+
+INT i_APCI1710_LatchCounter(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg);
+
+INT i_APCI1710_SetIndexAndReferenceSource(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_SourceSelection);
+
+INT i_APCI1710_SetDigitalChlOn(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_SetDigitalChlOff(struct comedi_device *dev, BYTE b_ModulNbr);
+
+/* INSN WRITE */
+INT i_APCI1710_EnableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableLatchInterrupt(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_Write16BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter,
+ UINT ui_WriteValue);
+
+INT i_APCI1710_Write32BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, ULONG ul_WriteValue);
+
+INT i_APCI1710_EnableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableIndex(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_EnableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_DisableCompareLogic(struct comedi_device *dev, BYTE b_ModulNbr);
+
+INT i_APCI1710_EnableFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_InterruptEnable);
+
+INT i_APCI1710_DisableFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr);
+
+/* INSN READ */
+INT i_APCI1710_ReadLatchRegisterStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg,
+ PBYTE pb_LatchStatus);
+
+INT i_APCI1710_ReadLatchRegisterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_LatchReg,
+ PULONG pul_LatchValue);
+
+INT i_APCI1710_Read16BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, BYTE b_SelectedCounter,
+ PUINT pui_CounterValue);
+
+INT i_APCI1710_Read32BitCounterValue(struct comedi_device *dev,
+ BYTE b_ModulNbr, PULONG pul_CounterValue);
+
+INT i_APCI1710_GetIndexStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_IndexStatus);
+
+INT i_APCI1710_GetReferenceStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_ReferenceStatus);
+
+INT i_APCI1710_GetUASStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_UASStatus);
+
+INT i_APCI1710_GetCBStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatus);
+
+INT i_APCI1710_Get16BitCBStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_CBStatusCounter0,
+ PBYTE pb_CBStatusCounter1);
+
+INT i_APCI1710_GetUDStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus);
+
+INT i_APCI1710_GetInterruptUDLatchedStatus(struct comedi_device *dev,
+ BYTE b_ModulNbr, PBYTE pb_UDStatus);
+
+INT i_APCI1710_ReadFrequencyMeasurement(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ PBYTE pb_Status, PBYTE pb_UDStatus,
+ PULONG pul_ReadValue);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
new file mode 100644
index 00000000000..3ac6a264ef5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.c
@@ -0,0 +1,861 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : Inp_CPT.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 pulse encoder module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Inp_cpt.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitPulseEncoder |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| BYTE_ b_InputLevelSelection, |
+| BYTE_ b_TriggerOutputAction, |
+| ULONG_ ul_StartValue) |
++----------------------------------------------------------------------------+
+| Task : Configure the pulse encoder operating mode selected via|
+| b_ModulNbr and b_PulseEncoderNbr. The pulse encoder |
+| after each pulse decrement the counter value from 1. |
+| |
+| You must calling this function be for you call any |
+| other function witch access of pulse encoders. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3) |
+| BYTE_ b_InputLevelSelection : Input level selection |
+| (0 or 1) |
+| 0 : Set pulse encoder|
+| count the the low|
+| level pulse. |
+| 1 : Set pulse encoder|
+| count the the |
+| high level pulse.|
+| BYTE_ b_TriggerOutputAction : Digital TRIGGER output |
+| action |
+| 0 : No action |
+| 1 : Set the trigger |
+| output to "1" |
+| (high) after the |
+| passage from 1 to|
+| 0 from pulse |
+| encoder. |
+| 2 : Set the trigger |
+| output to "0" |
+| (low) after the |
+| passage from 1 to|
+| 0 from pulse |
+| encoder |
+| ULONG_ ul_StartValue : Pulse encoder start value|
+| (1 to 4294967295)
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_PulseEncoderNbr =(BYTE) data[0];
+ b_InputLevelSelection =(BYTE) data[1];
+ b_TriggerOutputAction =(BYTE) data[2];
+ ul_StartValue =(ULONG) data[3];
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module is not a pulse encoder module |
+| -3: Pulse encoder selection is wrong |
+| -4: Input level selection is wrong |
+| -5: Digital TRIGGER output action selection is wrong |
+| -6: Pulse encoder start value is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_IntRegister;
+
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ BYTE b_InputLevelSelection;
+ BYTE b_TriggerOutputAction;
+ ULONG ul_StartValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_PulseEncoderNbr = (BYTE) data[0];
+ b_InputLevelSelection = (BYTE) data[1];
+ b_TriggerOutputAction = (BYTE) data[2];
+ ul_StartValue = (ULONG) data[3];
+
+ i_ReturnValue = insn->n;
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /*************************/
+ /* Test if pulse encoder */
+ /*************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ APCI1710_PULSE_ENCODER) ==
+ APCI1710_PULSE_ENCODER) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /************************/
+ /* Test the input level */
+ /************************/
+
+ if ((b_InputLevelSelection == 0)
+ || (b_InputLevelSelection == 1)) {
+ /*******************************************/
+ /* Test the ouput TRIGGER action selection */
+ /*******************************************/
+
+ if ((b_TriggerOutputAction <= 2)
+ || (b_PulseEncoderNbr > 0)) {
+ if (ul_StartValue > 1) {
+
+ dw_IntRegister =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+
+ /***********************/
+ /* Set the start value */
+ /***********************/
+
+ outl(ul_StartValue,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (b_PulseEncoderNbr
+ * 4) +
+ (64 * b_ModulNbr));
+
+ /***********************/
+ /* Set the input level */
+ /***********************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister &
+ (0xFFFFFFFFUL -
+ (1UL << (8 + b_PulseEncoderNbr)))) | ((1UL & (~b_InputLevelSelection)) << (8 + b_PulseEncoderNbr));
+
+ /*******************************/
+ /* Test if output trigger used */
+ /*******************************/
+
+ if ((b_TriggerOutputAction > 0) && (b_PulseEncoderNbr > 1)) {
+ /****************************/
+ /* Enable the output action */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ | (1UL
+ << (4 + b_PulseEncoderNbr));
+
+ /*********************************/
+ /* Set the output TRIGGER action */
+ /*********************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << (12 + b_PulseEncoderNbr)))) | ((1UL & (b_TriggerOutputAction - 1)) << (12 + b_PulseEncoderNbr));
+ } else {
+ /*****************************/
+ /* Disable the output action */
+ /*****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << (4 + b_PulseEncoderNbr)));
+ }
+
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ 20 +
+ (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo
+ [b_PulseEncoderNbr].
+ b_PulseEncoderInit
+ = 1;
+ } else {
+ /**************************************/
+ /* Pulse encoder start value is wrong */
+ /**************************************/
+
+ DPRINTK("Pulse encoder start value is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /****************************************************/
+ /* Digital TRIGGER output action selection is wrong */
+ /****************************************************/
+
+ DPRINTK("Digital TRIGGER output action selection is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /**********************************/
+ /* Input level selection is wrong */
+ /**********************************/
+
+ DPRINTK("Input level selection is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /********************************************/
+ /* The module is not a pulse encoder module */
+ /********************************************/
+
+ DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;
+ }
+ } else {
+ /********************************************/
+ /* The module is not a pulse encoder module */
+ /********************************************/
+
+ DPRINTK("The module is not a pulse encoder module\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnablePulseEncoder |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| BYTE_ b_CycleSelection, |
+| BYTE_ b_InterruptHandling) |
++----------------------------------------------------------------------------+
+| Task : Enableor disable the selected pulse encoder (b_PulseEncoderNbr) |
+| from selected module (b_ModulNbr). Each input pulse |
+| decrement the pulse encoder counter value from 1. |
+| If you enabled the interrupt (b_InterruptHandling), a |
+| interrupt is generated when the pulse encoder has run |
+| down. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3) |
+| BYTE_ b_CycleSelection : APCI1710_CONTINUOUS: |
+| Each time the |
+| counting value is set|
+| on "0", the pulse |
+| encoder load the |
+| start value after |
+| the next pulse. |
+| APCI1710_SINGLE: |
+| If the counter is set|
+| on "0", the pulse |
+| encoder is stopped. |
+| BYTE_ b_InterruptHandling : Interrupts can be |
+| generated, when the pulse|
+| encoder has run down. |
+| With this parameter the |
+| user decides if |
+| interrupts are used or |
+| not. |
+| APCI1710_ENABLE: |
+| Interrupts are enabled |
+| APCI1710_DISABLE: |
+| Interrupts are disabled
+
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_Action =(BYTE) data[0];
+ b_PulseEncoderNbr =(BYTE) data[1];
+ b_CycleSelection =(BYTE) data[2];
+ b_InterruptHandling =(BYTE) data[3];|
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection is wrong |
+| -3: Pulse encoder selection is wrong |
+| -4: Pulse encoder not initialised. |
+| See function "i_APCI1710_InitPulseEncoder" |
+| -5: Cycle selection mode is wrong |
+| -6: Interrupt handling mode is wrong |
+| -7: Interrupt routine not installed. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ BYTE b_CycleSelection;
+ BYTE b_InterruptHandling;
+ BYTE b_Action;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Action = (BYTE) data[0];
+ b_PulseEncoderNbr = (BYTE) data[1];
+ b_CycleSelection = (BYTE) data[2];
+ b_InterruptHandling = (BYTE) data[3];
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo[b_PulseEncoderNbr].
+ b_PulseEncoderInit == 1) {
+ switch (b_Action) {
+
+ case APCI1710_ENABLE:
+ /****************************/
+ /* Test the cycle selection */
+ /****************************/
+
+ if (b_CycleSelection ==
+ APCI1710_CONTINUOUS
+ || b_CycleSelection ==
+ APCI1710_SINGLE) {
+ /*******************************/
+ /* Test the interrupt handling */
+ /*******************************/
+
+ if (b_InterruptHandling ==
+ APCI1710_ENABLE
+ || b_InterruptHandling
+ == APCI1710_DISABLE) {
+ /******************************/
+ /* Test if interrupt not used */
+ /******************************/
+
+ if (b_InterruptHandling
+ ==
+ APCI1710_DISABLE)
+ {
+ /*************************/
+ /* Disable the interrupt */
+ /*************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1UL << b_PulseEncoderNbr));
+ } else {
+
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister
+ | (1UL
+ <<
+ b_PulseEncoderNbr);
+ devpriv->tsk_Current = current; // Save the current process task structure
+
+ }
+
+ if (i_ReturnValue >= 0) {
+ /***********************************/
+ /* Enable or disable the interrupt */
+ /***********************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_SetRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 20 +
+ (64 * b_ModulNbr));
+
+ /****************************/
+ /* Enable the pulse encoder */
+ /****************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ | (1UL
+ <<
+ b_PulseEncoderNbr);
+
+ /**********************/
+ /* Set the cycle mode */
+ /**********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ =
+ (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister
+ &
+ (0xFFFFFFFFUL
+ -
+ (1 << (b_PulseEncoderNbr + 4)))) | ((b_CycleSelection & 1UL) << (4 + b_PulseEncoderNbr));
+
+ /****************************/
+ /* Enable the pulse encoder */
+ /****************************/
+
+ outl(devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 16 +
+ (64 * b_ModulNbr));
+ }
+ } else {
+ /************************************/
+ /* Interrupt handling mode is wrong */
+ /************************************/
+
+ DPRINTK("Interrupt handling mode is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /*********************************/
+ /* Cycle selection mode is wrong */
+ /*********************************/
+
+ DPRINTK("Cycle selection mode is wrong\n");
+ i_ReturnValue = -5;
+ }
+ break;
+
+ case APCI1710_DISABLE:
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister &
+ (0xFFFFFFFFUL -
+ (1UL << b_PulseEncoderNbr));
+
+ /*****************************/
+ /* Disable the pulse encoder */
+ /*****************************/
+
+ outl(devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_ControlRegister,
+ devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ break;
+ } // switch End
+
+ } else {
+ /*********************************/
+ /* Pulse encoder not initialised */
+ /*********************************/
+
+ DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Module selection is wrong */
+ /*****************************/
+
+ DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadPulseEncoderStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PulseEncoderNbr, |
+| PBYTE_ pb_Status) |
++----------------------------------------------------------------------------+
+| Task APCI1710_PULSEENCODER_READ : Reads the pulse encoder status
+ and valuefrom selected pulse |
+| encoder (b_PulseEncoderNbr) from selected module |
+| (b_ModulNbr). |
++----------------------------------------------------------------------------+
+ BYTE b_Type; data[0]
+ APCI1710_PULSEENCODER_WRITE
+ Writes a 32-bit value (ul_WriteValue) into the selected|
+| pulse encoder (b_PulseEncoderNbr) from selected module |
+| (b_ModulNbr). This operation set the new start pulse |
+| encoder value.
+ APCI1710_PULSEENCODER_READ
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| CRAREF() BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| data[1] BYTE_ b_PulseEncoderNbr : Pulse encoder selection |
+| (0 to 3)
+ APCI1710_PULSEENCODER_WRITE
+ data[2] ULONG_ ul_WriteValue : 32-bit value to be |
+| written |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_Status : Pulse encoder status. |
+| 0 : No overflow occur|
+| 1 : Overflow occur
+ PULONG_ pul_ReadValue : Pulse encoder value | |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection is wrong |
+| -3: Pulse encoder selection is wrong |
+| -4: Pulse encoder not initialised. |
+| See function "i_APCI1710_InitPulseEncoder" |
++----------------------------------------------------------------------------+
+*/
+
+/*_INT_ i_APCI1710_ReadPulseEncoderStatus (BYTE_ b_BoardHandle,
+ BYTE_ b_ModulNbr,
+ BYTE_ b_PulseEncoderNbr,
+
+ PBYTE_ pb_Status)
+ */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusRegister;
+ BYTE b_ModulNbr;
+ BYTE b_PulseEncoderNbr;
+ PBYTE pb_Status;
+ BYTE b_Type;
+ PULONG pul_ReadValue;
+ ULONG ul_WriteValue;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Type = (BYTE) data[0];
+ b_PulseEncoderNbr = (BYTE) data[1];
+ pb_Status = (PBYTE) & data[0];
+ pul_ReadValue = (PULONG) & data[1];
+
+ /***********************************/
+ /* Test the selected module number */
+ /***********************************/
+
+ if (b_ModulNbr <= 3) {
+ /******************************************/
+ /* Test the selected pulse encoder number */
+ /******************************************/
+
+ if (b_PulseEncoderNbr <= 3) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo[b_PulseEncoderNbr].
+ b_PulseEncoderInit == 1) {
+
+ switch (b_Type) {
+ case APCI1710_PULSEENCODER_READ:
+ /****************************/
+ /* Read the status register */
+ /****************************/
+
+ dw_StatusRegister =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (64 * b_ModulNbr));
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister |
+ dw_StatusRegister;
+
+ *pb_Status =
+ (BYTE) (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister >> (1 +
+ b_PulseEncoderNbr)) & 1;
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PulseEncoderModuleInfo.
+ dw_StatusRegister &
+ (0xFFFFFFFFUL - (1 << (1 +
+ b_PulseEncoderNbr)));
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_ReadValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address +
+ (4 * b_PulseEncoderNbr) +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_PULSEENCODER_WRITE:
+ ul_WriteValue = (ULONG) data[2];
+ /*******************/
+ /* Write the value */
+ /*******************/
+
+ outl(ul_WriteValue,
+ devpriv->s_BoardInfos.
+ ui_Address +
+ (4 * b_PulseEncoderNbr) +
+ (64 * b_ModulNbr));
+
+ } //end of switch
+ } else {
+ /*********************************/
+ /* Pulse encoder not initialised */
+ /*********************************/
+
+ DPRINTK("Pulse encoder not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* Pulse encoder selection is wrong */
+ /************************************/
+
+ DPRINTK("Pulse encoder selection is wrong\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Module selection is wrong */
+ /*****************************/
+
+ DPRINTK("Module selection is wrong\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /***************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
new file mode 100644
index 00000000000..28252873e86
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Inp_cpt.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_PULSEENCODER_READ 0
+#define APCI1710_PULSEENCODER_WRITE 1
+
+INT i_APCI1710_InsnConfigInitPulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisablePulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
+ * READ PULSE ENCODER FUNCTIONS
+ */
+INT i_APCI1710_InsnReadInterruptPulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
+ * WRITE PULSE ENCODER FUNCTIONS
+ */
+INT i_APCI1710_InsnBitsReadWritePulseEncoder(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
new file mode 100644
index 00000000000..5ddd092a656
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.c
@@ -0,0 +1,3588 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : PWM.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 Wulse wide modulation module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +-----------------------------------------------------------------------+
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Pwm.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Pwm Init and Get Pwm Initialisation |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigPWM(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_ConfigType;
+ INT i_ReturnValue = 0;
+ b_ConfigType = CR_CHAN(insn->chanspec);
+
+ switch (b_ConfigType) {
+ case APCI1710_PWM_INIT:
+ i_ReturnValue = i_APCI1710_InitPWM(dev, (BYTE) CR_AREF(insn->chanspec), // b_ModulNbr
+ (BYTE) data[0], //b_PWM
+ (BYTE) data[1], // b_ClockSelection
+ (BYTE) data[2], // b_TimingUnit
+ (ULONG) data[3], //ul_LowTiming
+ (ULONG) data[4], //ul_HighTiming
+ (PULONG) & data[0], //pul_RealLowTiming
+ (PULONG) & data[1] //pul_RealHighTiming
+ );
+ break;
+
+ case APCI1710_PWM_GETINITDATA:
+ i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (BYTE) CR_AREF(insn->chanspec), // b_ModulNbr
+ (BYTE) data[0], //b_PWM
+ (PBYTE) & data[0], //pb_TimingUnit
+ (PULONG) & data[1], //pul_LowTiming
+ (PULONG) & data[2], //pul_HighTiming
+ (PBYTE) & data[3], // pb_StartLevel
+ (PBYTE) & data[4], // pb_StopMode
+ (PBYTE) & data[5], // pb_StopLevel
+ (PBYTE) & data[6], // pb_ExternGate
+ (PBYTE) & data[7], // pb_InterruptEnable
+ (PBYTE) & data[8] // pb_Enable
+ );
+ break;
+
+ default:
+ printk(" Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitPWM |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_ClockSelection, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_LowTiming, |
+| ULONG_ ul_HighTiming, |
+| PULONG_ pul_RealLowTiming, |
+| PULONG_ pul_RealHighTiming) |
++----------------------------------------------------------------------------+
+| Task : Configure the selected PWM (b_PWM) from selected module|
+| (b_ModulNbr). The ul_LowTiming, ul_HighTiming and |
+| ul_TimingUnit determine the low/high timing base for |
+| the period. pul_RealLowTiming, pul_RealHighTiming |
+| return the real timing value. |
+| You must calling this function be for you call any |
+| other function witch access of the PWM. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure|
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1). |
+| BYTE_ b_ClockSelection : Selection from PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC have a 30 MHz |
+| PCI bus clock |
+| - APCI1710_33MHZ : |
+| The PC have a 33 MHz |
+| PCI bus clock |
+| - APCI1710_40MHZ |
+| The APCI-1710 have a |
+| integrated 40Mhz |
+| quartz. |
+| BYTE_ b_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_LowTiming : Low base timing value. |
+| ULONG_ ul_HighTiming : High base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealLowTiming : Real low base timing |
+| value. |
+| PULONG_ pul_RealHighTiming : Real high base timing |
+| value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: The selected input clock is wrong |
+| -6: Timing Unit selection is wrong |
+| -7: Low base timing selection is wrong |
+| -8: High base timing selection is wrong |
+| -9: You can not used the 40MHz clock selection with |
+| this board |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InitPWM(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_ClockSelection,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming,
+ PULONG pul_RealLowTiming, PULONG pul_RealHighTiming)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_LowTimerValue = 0;
+ ULONG ul_HighTimerValue = 0;
+ DWORD dw_Command;
+ double d_RealLowTiming = 0;
+ double d_RealHighTiming = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /******************/
+ /* Test the clock */
+ /******************/
+
+ if ((b_ClockSelection == APCI1710_30MHZ) ||
+ (b_ClockSelection == APCI1710_33MHZ) ||
+ (b_ClockSelection == APCI1710_40MHZ)) {
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if (b_TimingUnit <= 4) {
+ /*********************************/
+ /* Test the low timing selection */
+ /*********************************/
+
+ if (((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 266)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230650UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 9UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 242)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691043UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 520UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 8UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 200)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496729UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 7UL))) {
+ /**********************************/
+ /* Test the High timing selection */
+ /**********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
+ /**************************/
+ /* Test the board version */
+ /**************************/
+
+ if (((b_ClockSelection == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_ClockSelection != APCI1710_40MHZ)) {
+
+ /************************************/
+ /* Calculate the low division fator */
+ /************************************/
+
+ fpu_begin
+ ();
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ ul_LowTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (ul_LowTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealLowTiming
+ =
+ (
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealLowTiming + 0.5)) {
+ *pul_RealLowTiming
+ =
+ *pul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ /*************************************/
+ /* Calculate the high division fator */
+ /*************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ ul_HighTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (ul_HighTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ *pul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealHighTiming
+ =
+ (
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealHighTiming + 0.5)) {
+ *pul_RealHighTiming
+ =
+ *pul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ fpu_end();
+ /****************************/
+ /* Save the clock selection */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ b_ClockSelection
+ =
+ b_ClockSelection;
+
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /****************************/
+ /* Save the low base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_LowTiming
+ =
+ d_RealLowTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealLowTiming
+ =
+ *pul_RealLowTiming;
+
+ /****************************/
+ /* Save the high base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_HighTiming
+ =
+ d_RealHighTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealHighTiming
+ =
+ *pul_RealHighTiming;
+
+ /************************/
+ /* Write the low timing */
+ /************************/
+
+ outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Write the high timing */
+ /*************************/
+
+ outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ dw_Command
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 8
+ +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command
+ =
+ dw_Command
+ &
+ 0x7F;
+
+ if (b_ClockSelection == APCI1710_40MHZ) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x80;
+ }
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************/
+ /* PWM init. */
+ /*************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_PWMInit
+ =
+ 1;
+ } else {
+ /***************************************************/
+ /* You can not used the 40MHz clock selection with */
+ /* this board */
+ /***************************************************/
+ DPRINTK("You can not used the 40MHz clock selection with this board\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /***************************************/
+ /* High base timing selection is wrong */
+ /***************************************/
+ DPRINTK("High base timing selection is wrong\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**************************************/
+ /* Low base timing selection is wrong */
+ /**************************************/
+ DPRINTK("Low base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+ else {
+ /*******************************/
+ /* The selected clock is wrong */
+ /*******************************/
+ DPRINTK("The selected clock is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ))
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetPWMInitialisation |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| PBYTE_ pb_TimingUnit, |
+| PULONG_ pul_LowTiming, |
+| PULONG_ pul_HighTiming, |
+| PBYTE_ pb_StartLevel, |
+| PBYTE_ pb_StopMode, |
+| PBYTE_ pb_StopLevel, |
+| PBYTE_ pb_ExternGate, |
+| PBYTE_ pb_InterruptEnable, |
+| PBYTE_ pb_Enable) |
++----------------------------------------------------------------------------+
+| Task : Return the PWM (b_PWM) initialisation from selected |
+| module (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitPWM" function be for you call this |
+| function. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| PULONG_ pul_LowTiming : Low base timing value. |
+| PULONG_ pul_HighTiming : High base timing value. |
+| PBYTE_ pb_StartLevel : Start period level |
+| selection |
+| 0 : The period start |
+| with a low level |
+| 1 : The period start |
+| with a high level|
+| PBYTE_ pb_StopMode : Stop mode selection |
+| 0 : The PWM is stopped |
+| directly after the |
+| "i_APCI1710_DisablePWM"|
+| function and break the|
+| last period |
+| 1 : After the |
+| "i_APCI1710_DisablePWM"|
+| function the PWM is |
+| stopped at the end |
+| from last period cycle|
+| PBYTE_ pb_StopLevel : Stop PWM level selection |
+| 0 : The output signal |
+| keep the level after|
+| the |
+| "i_APCI1710_DisablePWM"|
+| function |
+| 1 : The output signal is|
+| set to low after the|
+| "i_APCI1710_DisablePWM"|
+| function |
+| 2 : The output signal is|
+| set to high after |
+| the |
+| "i_APCI1710_DisablePWM"|
+| function |
+| PBYTE_ pb_ExternGate : Extern gate action |
+| selection |
+| 0 : Extern gate signal |
+| not used. |
+| 1 : Extern gate signal |
+| used. |
+| PBYTE_ pb_InterruptEnable : Enable or disable the PWM |
+| interrupt. |
+| - APCI1710_ENABLE : |
+| Enable the PWM interrupt|
+| A interrupt occur after |
+| each period |
+| - APCI1710_DISABLE : |
+| Disable the PWM |
+| interrupt |
+| PBYTE_ pb_Enable : Indicate if the PWM is |
+| enabled or no |
+| 0 : PWM not enabled |
+| 1 : PWM enabled |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_GetPWMInitialisation(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ PBYTE pb_TimingUnit,
+ PULONG pul_LowTiming,
+ PULONG pul_HighTiming,
+ PBYTE pb_StartLevel,
+ PBYTE pb_StopMode,
+ PBYTE pb_StopLevel,
+ PBYTE pb_ExternGate, PBYTE pb_InterruptEnable, PBYTE pb_Enable)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /***********************/
+ /* Read the low timing */
+ /***********************/
+
+ *pul_LowTiming =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 0 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ /************************/
+ /* Read the high timing */
+ /************************/
+
+ *pul_HighTiming =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 4 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ *pb_StartLevel =
+ (BYTE) ((dw_Command >> 5) & 1);
+ *pb_StopMode =
+ (BYTE) ((dw_Command >> 0) & 1);
+ *pb_StopLevel =
+ (BYTE) ((dw_Command >> 1) & 1);
+ *pb_ExternGate =
+ (BYTE) ((dw_Command >> 4) & 1);
+ *pb_InterruptEnable =
+ (BYTE) ((dw_Command >> 3) & 1);
+
+ if (*pb_StopLevel) {
+ *pb_StopLevel =
+ *pb_StopLevel +
+ (BYTE) ((dw_Command >>
+ 2) & 1);
+ }
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ *pb_Enable =
+ (BYTE) ((dw_Command >> 0) & 1);
+
+ *pb_TimingUnit = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo[b_PWM].b_TimingUnit;
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name :INT i_APCI1710_InsnWritePWM(struct comedi_device *dev,
+struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Pwm Enable Disable and Set New Timing |
++----------------------------------------------------------------------------+
+| Input Parameters :
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWritePWM(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_WriteType;
+ INT i_ReturnValue = 0;
+ b_WriteType = CR_CHAN(insn->chanspec);
+
+ switch (b_WriteType) {
+ case APCI1710_PWM_ENABLE:
+ i_ReturnValue = i_APCI1710_EnablePWM(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1],
+ (BYTE) data[2],
+ (BYTE) data[3], (BYTE) data[4], (BYTE) data[5]);
+ break;
+
+ case APCI1710_PWM_DISABLE:
+ i_ReturnValue = i_APCI1710_DisablePWM(dev,
+ (BYTE) CR_AREF(insn->chanspec), (BYTE) data[0]);
+ break;
+
+ case APCI1710_PWM_NEWTIMING:
+ i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
+ (BYTE) CR_AREF(insn->chanspec),
+ (BYTE) data[0],
+ (BYTE) data[1], (ULONG) data[2], (ULONG) data[3]);
+ break;
+
+ default:
+ printk("Write Config Parameter Wrong\n");
+ }
+
+ if (i_ReturnValue >= 0)
+ i_ReturnValue = insn->n;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnablePWM |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_StartLevel, |
+| BYTE_ b_StopMode, |
+| BYTE_ b_StopLevel, |
+| BYTE_ b_ExternGate, |
+| BYTE_ b_InterruptEnable) |
++----------------------------------------------------------------------------+
+| Task : Enable the selected PWM (b_PWM) from selected module |
+| (b_ModulNbr). You must calling the "i_APCI1710_InitPWM"|
+| function be for you call this function. |
+| If you enable the PWM interrupt, the PWM generate a |
+| interrupt after each period. |
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number |
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
+| BYTE_ b_StartLevel : Start period level selection |
+| 0 : The period start with a |
+| low level |
+| 1 : The period start with a |
+| high level |
+| BYTE_ b_StopMode : Stop mode selection |
+| 0 : The PWM is stopped |
+| directly after the |
+| "i_APCI1710_DisablePWM" |
+| function and break the |
+| last period |
+| 1 : After the |
+| "i_APCI1710_DisablePWM" |
+| function the PWM is |
+| stopped at the end from|
+| last period cycle. |
+| BYTE_ b_StopLevel : Stop PWM level selection |
+| 0 : The output signal keep |
+| the level after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| 1 : The output signal is set|
+| to low after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| 2 : The output signal is set|
+| to high after the |
+| "i_APCI1710_DisablePWM" |
+| function |
+| BYTE_ b_ExternGate : Extern gate action selection |
+| 0 : Extern gate signal not |
+| used. |
+| 1 : Extern gate signal used.|
+| BYTE_ b_InterruptEnable : Enable or disable the PWM |
+| interrupt. |
+| - APCI1710_ENABLE : |
+| Enable the PWM interrupt |
+| A interrupt occur after |
+| each period |
+| - APCI1710_DISABLE : |
+| Disable the PWM interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM start level selection is wrong |
+| -7: PWM stop mode selection is wrong |
+| -8: PWM stop level selection is wrong |
+| -9: Extern gate signal selection is wrong |
+| -10: Interrupt parameter is wrong |
+| -11: Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_EnablePWM(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_StartLevel,
+ BYTE b_StopMode,
+ BYTE b_StopLevel, BYTE b_ExternGate, BYTE b_InterruptEnable)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+
+ devpriv->tsk_Current = current; // Save the current process task structure
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /**********************************/
+ /* Test the start level selection */
+ /**********************************/
+
+ if (b_StartLevel <= 1) {
+ /**********************/
+ /* Test the stop mode */
+ /**********************/
+
+ if (b_StopMode <= 1) {
+ /***********************/
+ /* Test the stop level */
+ /***********************/
+
+ if (b_StopLevel <= 2) {
+ /*****************************/
+ /* Test the extern gate mode */
+ /*****************************/
+
+ if (b_ExternGate
+ <= 1) {
+ /*****************************/
+ /* Test the interrupt action */
+ /*****************************/
+
+ if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) {
+ /******************************************/
+ /* Test if interrupt function initialised */
+ /******************************************/
+
+ /********************/
+ /* Read the command */
+ /********************/
+
+ dw_Command
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 8
+ +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command
+ =
+ dw_Command
+ &
+ 0x80;
+
+ /********************/
+ /* Make the command */
+ /********************/
+
+ dw_Command
+ =
+ dw_Command
+ |
+ b_StopMode
+ |
+ (b_InterruptEnable
+ <<
+ 3)
+ |
+ (b_ExternGate
+ <<
+ 4)
+ |
+ (b_StartLevel
+ <<
+ 5);
+
+ if (b_StopLevel & 3) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 2;
+
+ if (b_StopLevel & 2) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 4;
+ }
+ }
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_InterruptEnable
+ =
+ b_InterruptEnable;
+
+ /*******************/
+ /* Set the command */
+ /*******************/
+
+ outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /******************/
+ /* Enable the PWM */
+ /******************/
+ outl(1, devpriv->s_BoardInfos.ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
+ } // if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+ else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue
+ =
+ -10;
+ } // if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE)
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ else {
+ /*****************************************/
+ /* Extern gate signal selection is wrong */
+ /*****************************************/
+ DPRINTK("Extern gate signal selection is wrong\n");
+ i_ReturnValue
+ =
+ -9;
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ } // if (b_StopLevel >= 0 && b_StopLevel <= 2)
+ else {
+ /*************************************/
+ /* PWM stop level selection is wrong */
+ /*************************************/
+ DPRINTK("PWM stop level selection is wrong\n");
+ i_ReturnValue =
+ -8;
+ } // if (b_StopLevel >= 0 && b_StopLevel <= 2)
+ } // if (b_StopMode >= 0 && b_StopMode <= 1)
+ else {
+ /************************************/
+ /* PWM stop mode selection is wrong */
+ /************************************/
+ DPRINTK("PWM stop mode selection is wrong\n");
+ i_ReturnValue = -7;
+ } // if (b_StopMode >= 0 && b_StopMode <= 1)
+ } // if (b_StartLevel >= 0 && b_StartLevel <= 1)
+ else {
+ /**************************************/
+ /* PWM start level selection is wrong */
+ /**************************************/
+ DPRINTK("PWM start level selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if (b_StartLevel >= 0 && b_StartLevel <= 1)
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisablePWM (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM) |
++----------------------------------------------------------------------------+
+| Task : Disable the selected PWM (b_PWM) from selected module |
+| (b_ModulNbr). The output signal level depend of the |
+| initialisation by the "i_APCI1710_EnablePWM". |
+| See the b_StartLevel, b_StopMode and b_StopLevel |
+| parameters from this function. |
++----------------------------------------------------------------------------+
+| Input Parameters :BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM not enabled see function |
+| "i_APCI1710_EnablePWM" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_DisablePWM(struct comedi_device * dev, BYTE b_ModulNbr, BYTE b_PWM)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /***********************/
+ /* Test if PWM enabled */
+ /***********************/
+
+ if (dw_Status & 0x1) {
+ /*******************/
+ /* Disable the PWM */
+ /*******************/
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (20 * b_PWM) +
+ (64 * b_ModulNbr));
+ } // if (dw_Status & 0x1)
+ else {
+ /*******************/
+ /* PWM not enabled */
+ /*******************/
+ DPRINTK("PWM not enabled\n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK(" PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetNewPWMTiming |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| BYTE_ b_ClockSelection, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_LowTiming, |
+| ULONG_ ul_HighTiming) |
++----------------------------------------------------------------------------+
+| Task : Set a new timing. The ul_LowTiming, ul_HighTiming and |
+| ul_TimingUnit determine the low/high timing base for |
+| the period. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Module number to configure|
+| (0 to 3) |
+| BYTE_ b_PWM : Selected PWM (0 or 1). |
+| BYTE_ b_TimingUnit : Base timing Unit (0 to 4) |
+| 0 : ns |
+| 1 : æs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| ULONG_ ul_LowTiming : Low base timing value. |
+| ULONG_ ul_HighTiming : High base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised |
+| -6: Timing Unit selection is wrong |
+| -7: Low base timing selection is wrong |
+| -8: High base timing selection is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_SetNewPWMTiming(struct comedi_device * dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM, BYTE b_TimingUnit, ULONG ul_LowTiming, ULONG ul_HighTiming)
+{
+ BYTE b_ClockSelection;
+ INT i_ReturnValue = 0;
+ ULONG ul_LowTimerValue = 0;
+ ULONG ul_HighTimerValue = 0;
+ ULONG ul_RealLowTiming = 0;
+ ULONG ul_RealHighTiming = 0;
+ DWORD dw_Status;
+ DWORD dw_Command;
+ double d_RealLowTiming = 0;
+ double d_RealHighTiming = 0;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ b_ClockSelection = devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_PWMModuleInfo.
+ b_ClockSelection;
+
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if (b_TimingUnit <= 4) {
+ /*********************************/
+ /* Test the low timing selection */
+ /*********************************/
+
+ if (((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 266)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230650UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571230UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 571UL))
+ || ((b_ClockSelection ==
+ APCI1710_30MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 9UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 242)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691043UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 519691UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 520UL))
+ || ((b_ClockSelection ==
+ APCI1710_33MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <= 8UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 0)
+ && (ul_LowTiming
+ >= 200)
+ && (ul_LowTiming
+ <=
+ 0xFFFFFFFFUL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 1)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496729UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 2)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429496UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 3)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 429UL))
+ || ((b_ClockSelection ==
+ APCI1710_40MHZ)
+ && (b_TimingUnit
+ == 4)
+ && (ul_LowTiming
+ >= 1)
+ && (ul_LowTiming
+ <=
+ 7UL))) {
+ /**********************************/
+ /* Test the High timing selection */
+ /**********************************/
+
+ if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
+ /************************************/
+ /* Calculate the low division fator */
+ /************************************/
+
+ fpu_begin();
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ ul_LowTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (ul_LowTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealLowTiming
+ =
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (ul_LowTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealLowTiming
+ =
+ (ULONG)
+ (ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealLowTiming
+ =
+ (
+ (double)
+ ul_LowTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealLowTiming + 0.5)) {
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming
+ +
+ 1;
+ }
+
+ ul_LowTiming
+ =
+ ul_LowTiming
+ -
+ 1;
+ ul_LowTimerValue
+ =
+ ul_LowTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_LowTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_LowTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ /*************************************/
+ /* Calculate the high division fator */
+ /*************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.00025 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.00025 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (0.25 * b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (0.25 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ ul_HighTiming
+ *
+ (250.0
+ *
+ b_ClockSelection);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250.0 * (double)b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (ul_HighTiming
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection));
+ d_RealHighTiming
+ =
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection);
+
+ if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (ul_HighTiming
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_ClockSelection));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealHighTiming
+ =
+ (ULONG)
+ (ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60;
+ d_RealHighTiming
+ =
+ (
+ (double)
+ ul_HighTimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_ClockSelection))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealHighTiming + 0.5)) {
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming
+ +
+ 1;
+ }
+
+ ul_HighTiming
+ =
+ ul_HighTiming
+ -
+ 1;
+ ul_HighTimerValue
+ =
+ ul_HighTimerValue
+ -
+ 2;
+
+ if (b_ClockSelection != APCI1710_40MHZ) {
+ ul_HighTimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_HighTimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ fpu_end();
+
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /****************************/
+ /* Save the low base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_LowTiming
+ =
+ d_RealLowTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealLowTiming
+ =
+ ul_RealLowTiming;
+
+ /****************************/
+ /* Save the high base timing */
+ /****************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ d_HighTiming
+ =
+ d_RealHighTiming;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_PWMModuleInfo.
+ s_PWMInfo
+ [b_PWM].
+ ul_RealHighTiming
+ =
+ ul_RealHighTiming;
+
+ /************************/
+ /* Write the low timing */
+ /************************/
+
+ outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /*************************/
+ /* Write the high timing */
+ /*************************/
+
+ outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ dw_Command =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 8 +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+
+ dw_Command =
+ dw_Command
+ & 0x7F;
+
+ if (b_ClockSelection == APCI1710_40MHZ) {
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x80;
+ }
+
+ /***************************/
+ /* Set the clock selection */
+ /***************************/
+
+ outl(dw_Command,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 8 +
+ (20 * b_PWM) + (64 * b_ModulNbr));
+ } else {
+ /***************************************/
+ /* High base timing selection is wrong */
+ /***************************************/
+ DPRINTK("High base timing selection is wrong\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**************************************/
+ /* Low base timing selection is wrong */
+ /**************************************/
+ DPRINTK("Low base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetPWMStatus |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PWM, |
+| PBYTE_ pb_PWMOutputStatus, |
+| PBYTE_ pb_ExternGateStatus) |
++----------------------------------------------------------------------------+
+| Task : Return the status from selected PWM (b_PWM) from |
+| selected module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_PWM : Selected PWM (0 or 1) |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)
+ b_ModulNbr =(BYTE) CR_AREF(insn->chanspec);
+ b_PWM =(BYTE) data[0];
+
+ |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_PWMOutputStatus : Return the PWM output |
+| level status. |
+| 0 : The PWM output level|
+| is low. |
+| 1 : The PWM output level|
+| is high. |
+| PBYTE_ pb_ExternGateStatus : Return the extern gate |
+| level status. |
+| 0 : The extern gate is |
+| low. |
+| 1 : The extern gate is |
+| high.
+ pb_PWMOutputStatus =(PBYTE) data[0];
+ pb_ExternGateStatus =(PBYTE) data[1]; |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a PWM module |
+| -4: PWM selection is wrong |
+| -5: PWM not initialised see function |
+| "i_APCI1710_InitPWM" |
+| -6: PWM not enabled see function "i_APCI1710_EnablePWM"|
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadGetPWMStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+
+ BYTE b_ModulNbr;
+ BYTE b_PWM;
+ PBYTE pb_PWMOutputStatus;
+ PBYTE pb_ExternGateStatus;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_PWM = (BYTE) CR_CHAN(insn->chanspec);
+ pb_PWMOutputStatus = (PBYTE) & data[0];
+ pb_ExternGateStatus = (PBYTE) & data[1];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***************/
+ /* Test if PWM */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ /**************************/
+ /* Test the PWM selection */
+ /**************************/
+
+ if (b_PWM <= 1) {
+ /***************************/
+ /* Test if PWM initialised */
+ /***************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (20 * b_PWM) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /***********************/
+ /* Test if PWM enabled */
+ /***********************/
+
+ if (dw_Status & 0x1) {
+ *pb_PWMOutputStatus =
+ (BYTE) ((dw_Status >> 7)
+ & 1);
+ *pb_ExternGateStatus =
+ (BYTE) ((dw_Status >> 6)
+ & 1);
+ } // if (dw_Status & 0x1)
+ else {
+ /*******************/
+ /* PWM not enabled */
+ /*******************/
+
+ DPRINTK("PWM not enabled \n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } // if (dw_Status & 0x10)
+ else {
+ /***********************/
+ /* PWM not initialised */
+ /***********************/
+
+ DPRINTK("PWM not initialised\n");
+ i_ReturnValue = -5;
+ } // if (dw_Status & 0x10)
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ else {
+ /******************************/
+ /* Tor PWM selection is wrong */
+ /******************************/
+
+ DPRINTK("Tor PWM selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_PWM >= 0 && b_PWM <= 1)
+ } else {
+ /**********************************/
+ /* The module is not a PWM module */
+ /**********************************/
+
+ DPRINTK("The module is not a PWM module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
new file mode 100644
index 00000000000..c1b7f4ca47c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Pwm.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_PWM_INIT 0
+#define APCI1710_PWM_GETINITDATA 1
+
+#define APCI1710_PWM_DISABLE 0
+#define APCI1710_PWM_ENABLE 1
+#define APCI1710_PWM_NEWTIMING 2
+
+INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InitPWM(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_ClockSelection,
+ BYTE b_TimingUnit,
+ ULONG ul_LowTiming,
+ ULONG ul_HighTiming,
+ PULONG pul_RealLowTiming, PULONG pul_RealHighTiming);
+
+INT i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ PBYTE pb_TimingUnit,
+ PULONG pul_LowTiming,
+ PULONG pul_HighTiming,
+ PBYTE pb_StartLevel,
+ PBYTE pb_StopMode,
+ PBYTE pb_StopLevel,
+ PBYTE pb_ExternGate,
+ PBYTE pb_InterruptEnable, PBYTE pb_Enable);
+
+INT i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_EnablePWM(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM,
+ BYTE b_StartLevel,
+ BYTE b_StopMode,
+ BYTE b_StopLevel, BYTE b_ExternGate,
+ BYTE b_InterruptEnable);
+
+INT i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
+ BYTE b_ModulNbr,
+ BYTE b_PWM, BYTE b_TimingUnit,
+ ULONG ul_LowTiming, ULONG ul_HighTiming);
+
+INT i_APCI1710_DisablePWM(struct comedi_device *dev, BYTE b_ModulNbr, BYTE b_PWM);
+
+INT i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
new file mode 100644
index 00000000000..bb6e1622e37
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.c
@@ -0,0 +1,848 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : SSI.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 SSI counter module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 13/05/98 | S. Weber | SSI digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 22/03/00 | C.Guinot | 0100/0226 -> 0200/0227 |
+ | | | Änderung in InitSSI Funktion |
+ | | | b_SSIProfile >= 2 anstatt b_SSIProfile > 2 |
+ | | | |
+ +-----------------------------------------------------------------------+
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Ssi.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitSSI |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SSIProfile, |
+| BYTE_ b_PositionTurnLength, |
+| BYTE_ b_TurnCptLength, |
+| BYTE_ b_PCIInputClock, |
+| ULONG_ ul_SSIOutputClock, |
+| BYTE_ b_SSICountingMode) |
++----------------------------------------------------------------------------+
+| Task : Configure the SSI operating mode from selected module |
+| (b_ModulNbr). You must calling this function be for you|
+| call any other function witch access of SSI. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_SSIProfile : Selection from SSI |
+| profile length (2 to 32).|
+| BYTE_ b_PositionTurnLength : Selection from SSI |
+| position data length |
+| (1 to 31). |
+| BYTE_ b_TurnCptLength : Selection from SSI turn |
+| counter data length |
+| (1 to 31). |
+| BYTE b_PCIInputClock : Selection from PCI bus |
+| clock |
+| - APCI1710_30MHZ : |
+| The PC have a PCI bus |
+| clock from 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC have a PCI bus |
+| clock from 33 MHz |
+| ULONG_ ul_SSIOutputClock : Selection from SSI output|
+| clock. |
+| From 229 to 5 000 000 Hz|
+| for 30 MHz selection. |
+| From 252 to 5 000 000 Hz|
+| for 33 MHz selection. |
+| BYTE b_SSICountingMode : SSI counting mode |
+| selection |
+| - APCI1710_BINARY_MODE : |
+| Binary counting mode. |
+| - APCI1710_GRAY_MODE : |
+| Gray counting mode.
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SSIProfile = (BYTE) data[0];
+ b_PositionTurnLength= (BYTE) data[1];
+ b_TurnCptLength = (BYTE) data[2];
+ b_PCIInputClock = (BYTE) data[3];
+ ul_SSIOutputClock = (ULONG) data[4];
+ b_SSICountingMode = (BYTE) data[5]; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a SSI module |
+| -4: The selected SSI profile length is wrong |
+| -5: The selected SSI position data length is wrong |
+| -6: The selected SSI turn counter data length is wrong |
+| -7: The selected PCI input clock is wrong |
+| -8: The selected SSI output clock is wrong |
+| -9: The selected SSI counting mode parameter is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitSSI(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ UINT ui_TimerValue;
+ BYTE b_ModulNbr, b_SSIProfile, b_PositionTurnLength, b_TurnCptLength,
+ b_PCIInputClock, b_SSICountingMode;
+ ULONG ul_SSIOutputClock;
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SSIProfile = (BYTE) data[0];
+ b_PositionTurnLength = (BYTE) data[1];
+ b_TurnCptLength = (BYTE) data[2];
+ b_PCIInputClock = (BYTE) data[3];
+ ul_SSIOutputClock = (ULONG) data[4];
+ b_SSICountingMode = (BYTE) data[5];
+
+ i_ReturnValue = insn->n;
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if SSI counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+ /*******************************/
+ /* Test the SSI profile length */
+ /*******************************/
+
+ // CG 22/03/00 b_SSIProfile >= 2 anstatt b_SSIProfile > 2
+ if (b_SSIProfile >= 2 && b_SSIProfile < 33) {
+ /*************************************/
+ /* Test the SSI position data length */
+ /*************************************/
+
+ if (b_PositionTurnLength > 0
+ && b_PositionTurnLength < 32) {
+ /*****************************************/
+ /* Test the SSI turn counter data length */
+ /*****************************************/
+
+ if (b_TurnCptLength > 0
+ && b_TurnCptLength < 32) {
+ /***************************/
+ /* Test the profile length */
+ /***************************/
+
+ if ((b_TurnCptLength +
+ b_PositionTurnLength)
+ <= b_SSIProfile) {
+ /****************************/
+ /* Test the PCI input clock */
+ /****************************/
+
+ if (b_PCIInputClock ==
+ APCI1710_30MHZ
+ ||
+ b_PCIInputClock
+ ==
+ APCI1710_33MHZ)
+ {
+ /*************************/
+ /* Test the output clock */
+ /*************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ && (ul_SSIOutputClock > 228 && ul_SSIOutputClock <= 5000000UL)) || (b_PCIInputClock == APCI1710_33MHZ && (ul_SSIOutputClock > 251 && ul_SSIOutputClock <= 5000000UL))) {
+ if (b_SSICountingMode == APCI1710_BINARY_MODE || b_SSICountingMode == APCI1710_GRAY_MODE) {
+ /**********************/
+ /* Save configuration */
+ /**********************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile
+ =
+ b_SSIProfile;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength
+ =
+ b_PositionTurnLength;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_TurnCptLength
+ =
+ b_TurnCptLength;
+
+ /*********************************/
+ /* Initialise the profile length */
+ /*********************************/
+
+ if (b_SSICountingMode == APCI1710_BINARY_MODE) {
+
+ outl(b_SSIProfile + 1, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+ } else {
+
+ outl(b_SSIProfile, devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr));
+ }
+
+ /******************************/
+ /* Calculate the output clock */
+ /******************************/
+
+ ui_TimerValue
+ =
+ (UINT)
+ (
+ ((ULONG) (b_PCIInputClock) * 500000UL) / ul_SSIOutputClock);
+
+ /************************/
+ /* Initialise the timer */
+ /************************/
+
+ outl(ui_TimerValue, devpriv->s_BoardInfos.ui_Address + (64 * b_ModulNbr));
+
+ /********************************/
+ /* Initialise the counting mode */
+ /********************************/
+
+ outl(7 * b_SSICountingMode, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr));
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIInit
+ =
+ 1;
+ } else {
+ /*****************************************************/
+ /* The selected SSI counting mode parameter is wrong */
+ /*****************************************************/
+
+ DPRINTK("The selected SSI counting mode parameter is wrong\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /******************************************/
+ /* The selected SSI output clock is wrong */
+ /******************************************/
+
+ DPRINTK("The selected SSI output clock is wrong\n");
+ i_ReturnValue
+ =
+ -8;
+ }
+ } else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ } else {
+ /********************************************/
+ /* The selected SSI profile length is wrong */
+ /********************************************/
+
+ DPRINTK("The selected SSI profile length is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /******************************************************/
+ /* The selected SSI turn counter data length is wrong */
+ /******************************************************/
+
+ DPRINTK("The selected SSI turn counter data length is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /**************************************************/
+ /* The selected SSI position data length is wrong */
+ /**************************************************/
+
+ DPRINTK("The selected SSI position data length is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /********************************************/
+ /* The selected SSI profile length is wrong */
+ /********************************************/
+
+ DPRINTK("The selected SSI profile length is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /**********************************/
+ /* The module is not a SSI module */
+ /**********************************/
+
+ DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_Read1SSIValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedSSI, |
+| PULONG_ pul_Position, |
+| PULONG_ pul_TurnCpt)
+ INT i_APCI1710_ReadSSIValue(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task :
+
+
+ Read the selected SSI counter (b_SelectedSSI) from |
+| selected module (b_ModulNbr).
+ or Read all SSI counter (b_SelectedSSI) from |
+| selected module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_SelectedSSI : Selection from SSI |
+| counter (0 to 2)
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec); (in case of single ssi)
+ b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
+|
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_Position : SSI position in the turn |
+| PULONG_ pul_TurnCpt : Number of turns
+
+pul_Position = (PULONG) &data[0];
+ pul_TurnCpt = (PULONG) &data[1]; |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a SSI module |
+| -4: SSI not initialised see function |
+| "i_APCI1710_InitSSI" |
+| -5: The selected SSI is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadSSIValue(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_Cpt;
+ BYTE b_Length;
+ BYTE b_Schift;
+ BYTE b_SSICpt;
+ DWORD dw_And;
+ DWORD dw_And1;
+ DWORD dw_And2;
+ DWORD dw_StatusReg;
+ DWORD dw_CounterValue;
+ BYTE b_ModulNbr;
+ BYTE b_SelectedSSI;
+ BYTE b_ReadType;
+ PULONG pul_Position;
+ PULONG pul_TurnCpt;
+ PULONG pul_Position1;
+ PULONG pul_TurnCpt1;
+
+ i_ReturnValue = insn->n;
+ pul_Position1 = (PULONG) & data[0];
+// For Read1
+ pul_TurnCpt1 = (PULONG) & data[1];
+// For Read all
+ pul_Position = (PULONG) & data[0]; //0-2
+ pul_TurnCpt = (PULONG) & data[3]; //3-5
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_SelectedSSI = (BYTE) CR_CHAN(insn->chanspec);
+ b_ReadType = (BYTE) CR_RANGE(insn->chanspec);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if SSI counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+ /***************************/
+ /* Test if SSI initialised */
+ /***************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_SSICounterInfo.b_SSIInit == 1) {
+
+ switch (b_ReadType) {
+
+ case APCI1710_SSI_READ1VALUE:
+ /****************************************/
+ /* Test the selected SSI counter number */
+ /****************************************/
+
+ if (b_SelectedSSI < 3) {
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModulNbr));
+
+ do {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ }
+ while ((dw_StatusReg & 0x1) !=
+ 0);
+
+ /******************************/
+ /* Read the SSI counter value */
+ /******************************/
+
+ dw_CounterValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (b_SelectedSSI * 4) +
+ (64 * b_ModulNbr));
+
+ b_Length =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile / 2;
+
+ if ((b_Length * 2) !=
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile) {
+ b_Length++;
+ }
+
+ b_Schift =
+ b_Length -
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength;
+
+ *pul_Position1 =
+ dw_CounterValue >>
+ b_Schift;
+
+ dw_And = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength;
+ b_Cpt++) {
+ dw_And = dw_And * 2;
+ }
+
+ *pul_Position1 =
+ *pul_Position1 &
+ ((dw_And) - 1);
+
+ *pul_TurnCpt1 =
+ dw_CounterValue >>
+ b_Length;
+
+ dw_And = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_TurnCptLength;
+ b_Cpt++) {
+ dw_And = dw_And * 2;
+ }
+
+ *pul_TurnCpt1 =
+ *pul_TurnCpt1 &
+ ((dw_And) - 1);
+ } else {
+ /*****************************/
+ /* The selected SSI is wrong */
+ /*****************************/
+
+ DPRINTK("The selected SSI is wrong\n");
+ i_ReturnValue = -5;
+ }
+ break;
+
+ case APCI1710_SSI_READALLVALUE:
+ dw_And1 = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength; b_Cpt++) {
+ dw_And1 = dw_And1 * 2;
+ }
+
+ dw_And2 = 1;
+
+ for (b_Cpt = 0;
+ b_Cpt <
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_SSICounterInfo.
+ b_TurnCptLength; b_Cpt++) {
+ dw_And2 = dw_And2 * 2;
+ }
+
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModulNbr));
+
+ do {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ }
+ while ((dw_StatusReg & 0x1) != 0);
+
+ for (b_SSICpt = 0; b_SSICpt < 3;
+ b_SSICpt++) {
+ /******************************/
+ /* Read the SSI counter value */
+ /******************************/
+
+ dw_CounterValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (b_SSICpt * 4) +
+ (64 * b_ModulNbr));
+
+ b_Length =
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile / 2;
+
+ if ((b_Length * 2) !=
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_SSIProfile) {
+ b_Length++;
+ }
+
+ b_Schift =
+ b_Length -
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_SSICounterInfo.
+ b_PositionTurnLength;
+
+ pul_Position[b_SSICpt] =
+ dw_CounterValue >>
+ b_Schift;
+ pul_Position[b_SSICpt] =
+ pul_Position[b_SSICpt] &
+ ((dw_And1) - 1);
+
+ pul_TurnCpt[b_SSICpt] =
+ dw_CounterValue >>
+ b_Length;
+ pul_TurnCpt[b_SSICpt] =
+ pul_TurnCpt[b_SSICpt] &
+ ((dw_And2) - 1);
+ }
+ break;
+
+ default:
+ printk("Read Type Inputs Wrong\n");
+
+ } // switch ending
+
+ } else {
+ /***********************/
+ /* SSI not initialised */
+ /***********************/
+
+ DPRINTK("SSI not initialised\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /**********************************/
+ /* The module is not a SSI module */
+ /**********************************/
+
+ DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;
+
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadSSI1DigitalInput |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_InputChannel, |
+| PBYTE_ pb_ChannelStatus) |
++----------------------------------------------------------------------------+
+| Task :
+ (0) Set the digital output from selected SSI moule |
+| (b_ModuleNbr) ON
+ (1) Set the digital output from selected SSI moule |
+| (b_ModuleNbr) OFF
+ (2)Read the status from selected SSI digital input |
+| (b_InputChannel)
+ (3)Read the status from all SSI digital inputs from |
+| selected SSI module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr CR_AREF : Module number to |
+| configure (0 to 3) |
+| BYTE_ b_InputChannel CR_CHAN : Selection from digital |
+| data[0] which IOTYPE input ( 0 to 2) |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_ChannelStatus : Digital input channel |
+| data[0] status |
+| 0 : Channle is not active|
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a SSI module |
+| -4: The selected SSI digital input is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr;
+ BYTE b_InputChannel;
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_InputStatus;
+ BYTE b_IOType;
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_IOType = (BYTE) data[0];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if SSI counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_SSI_COUNTER) {
+ switch (b_IOType) {
+ case APCI1710_SSI_SET_CHANNELON:
+ /*****************************/
+ /* Set the digital output ON */
+ /*****************************/
+
+ outl(1, devpriv->s_BoardInfos.ui_Address + 16 +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_SSI_SET_CHANNELOFF:
+ /******************************/
+ /* Set the digital output OFF */
+ /******************************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 16 +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_SSI_READ_1CHANNEL:
+ /******************************************/
+ /* Test the digital imnput channel number */
+ /******************************************/
+
+ b_InputChannel = (BYTE) CR_CHAN(insn->chanspec);
+ pb_ChannelStatus = (PBYTE) & data[0];
+
+ if (b_InputChannel <= 2) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+ *pb_ChannelStatus =
+ (BYTE) (((~dw_StatusReg) >> (4 +
+ b_InputChannel))
+ & 1);
+ } else {
+ /********************************/
+ /* Selected digital input error */
+ /********************************/
+
+ DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ case APCI1710_SSI_READ_ALLCHANNEL:
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+ pb_InputStatus = (PBYTE) & data[0];
+
+ dw_StatusReg =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ (64 * b_ModulNbr));
+ *pb_InputStatus =
+ (BYTE) (((~dw_StatusReg) >> 4) & 7);
+ break;
+
+ default:
+ printk("IO type wrong\n");
+
+ } //switch end
+ } else {
+ /**********************************/
+ /* The module is not a SSI module */
+ /**********************************/
+
+ DPRINTK("The module is not a SSI module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
new file mode 100644
index 00000000000..88daad1a391
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ssi.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_BINARY_MODE 0x1
+#define APCI1710_GRAY_MODE 0x0
+
+#define APCI1710_SSI_READ1VALUE 1
+#define APCI1710_SSI_READALLVALUE 2
+
+#define APCI1710_SSI_SET_CHANNELON 0
+#define APCI1710_SSI_SET_CHANNELOFF 1
+#define APCI1710_SSI_READ_1CHANNEL 2
+#define APCI1710_SSI_READ_ALLCHANNEL 3
+
+/*
+ * SSI INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitSSI(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnReadSSIValue(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnBitsSSIDigitalIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
new file mode 100644
index 00000000000..90316e10a3b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c
@@ -0,0 +1,2049 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : TOR.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 tor counter module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 27/01/99 | S. Weber | 40 MHz implementation |
+ +-----------------------------------------------------------------------+
+ | 28/04/00 | S. Weber | Simple,double and quadruple mode implementation|
+ | | | Extern clock implementation |
+ +-----------------------------------------------------------------------+
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Tor.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitTorCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| BYTE_ b_PCIInputClock, |
+| BYTE_ b_TimingUnit, |
+| ULONG_ ul_TimingInterval, |
+| PULONG_ pul_RealTimingInterval) |
++----------------------------------------------------------------------------+
+| Task : Configure the selected tor counter (b_TorCounter) |
+| from selected module (b_ModulNbr). |
+| The ul_TimingInterval and ul_TimingUnit determine the |
+| timing base for the measurement. |
+| The pul_RealTimingInterval return the real timing |
+| value. You must calling this function be for you call |
+| any other function witch access of the tor counter. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+|
+ CR_AREF BYTE_ b_ModulNbr : Module number to configure |
+| (0 to 3) |
+| data[0] BYTE_ b_TorCounter : Tor counter selection |
+| (0 or 1). |
+| data[1] BYTE_ b_PCIInputClock : Selection from PCI bus clock|
+| - APCI1710_30MHZ : |
+| The PC have a PCI bus |
+| clock from 30 MHz |
+| - APCI1710_33MHZ : |
+| The PC have a PCI bus |
+| clock from 33 MHz |
+| - APCI1710_40MHZ |
+| The APCI-1710 have a |
+| integrated 40Mhz |
+| quartz. |
+| - APCI1710_GATE_INPUT |
+| Used the gate input for |
+| the base clock. If you |
+| have selected this option,|
+| than it is not possibl to |
+| used the gate input for |
+| enabled the acquisition |
+| data[2] BYTE_ b_TimingUnit : Base timing unit (0 to 4) |
+| 0 : ns |
+| 1 : µs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| data[3] ULONG_ ul_TimingInterval : Base timing value. |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_RealTimingInterval : Real base timing |
+| data[0] value. |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: The selected PCI input clock is wrong |
+| -6: Timing unit selection is wrong |
+| -7: Base timing selection is wrong |
+| -8: You can not used the 40MHz clock selection wich |
+| this board |
+| -9: You can not used the 40MHz clock selection wich |
+| this TOR version |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTorCounter(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ ULONG ul_TimerValue = 0;
+ DWORD dw_Command;
+ double d_RealTimingInterval = 0;
+ BYTE b_ModulNbr;
+ BYTE b_TorCounter;
+ BYTE b_PCIInputClock;
+ BYTE b_TimingUnit;
+ ULONG ul_TimingInterval;
+ ULONG ul_RealTimingInterval = 0;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+
+ b_TorCounter = (BYTE) data[0];
+ b_PCIInputClock = (BYTE) data[1];
+ b_TimingUnit = (BYTE) data[2];
+ ul_TimingInterval = (ULONG) data[3];
+ printk("INPUT clock %d\n", b_PCIInputClock);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+ /**************************/
+ /* Test the PCI bus clock */
+ /**************************/
+
+ if ((b_PCIInputClock == APCI1710_30MHZ) ||
+ (b_PCIInputClock == APCI1710_33MHZ) ||
+ (b_PCIInputClock == APCI1710_40MHZ) ||
+ (b_PCIInputClock ==
+ APCI1710_GATE_INPUT)) {
+ /************************/
+ /* Test the timing unit */
+ /************************/
+
+ if ((b_TimingUnit <= 4)
+ || (b_PCIInputClock ==
+ APCI1710_GATE_INPUT)) {
+ /**********************************/
+ /* Test the base timing selection */
+ /**********************************/
+
+ if (((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 133) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230650UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571230UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 571UL)) || ((b_PCIInputClock == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 9UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 121) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691043UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 519691UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 520UL)) || ((b_PCIInputClock == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 8UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_TimingInterval >= 100) && (ul_TimingInterval <= 0xFFFFFFFFUL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496729UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429496UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 429UL)) || ((b_PCIInputClock == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_TimingInterval >= 1) && (ul_TimingInterval <= 7UL)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && (ul_TimingInterval >= 2))) {
+ /**************************/
+ /* Test the board version */
+ /**************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_PCIInputClock != APCI1710_40MHZ)) {
+ /************************/
+ /* Test the TOR version */
+ /************************/
+
+ if (((b_PCIInputClock == APCI1710_40MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3131)) || ((b_PCIInputClock == APCI1710_GATE_INPUT) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3132)) || (b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ)) {
+ /*********************************/
+ /* Test if not extern clock used */
+ /*********************************/
+
+ if (b_PCIInputClock != APCI1710_GATE_INPUT) {
+ fpu_begin
+ ();
+ /****************************************/
+ /* Calculate the timer 0 division fator */
+ /****************************************/
+
+ switch (b_TimingUnit) {
+ /******/
+ /* ns */
+ /******/
+
+ case 0:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.00025 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.00025 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.00025 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (0.00025
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.00025 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* æs */
+ /******/
+
+ case 1:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (0.25 * b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (0.25 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (0.25 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (
+ (double)
+ 0.25
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (0.25 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* ms */
+ /******/
+
+ case 2:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ *
+ (250.0
+ *
+ b_PCIInputClock);
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (250.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250.0 * (double)b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (250.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (250.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /*****/
+ /* s */
+ /*****/
+
+ case 3:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (ul_TimingInterval
+ *
+ (250000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)ul_TimingInterval * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock));
+ d_RealTimingInterval
+ =
+ (double)
+ ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock);
+
+ if ((double)((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+
+ /******/
+ /* mn */
+ /******/
+
+ case 4:
+
+ /******************/
+ /* Timer 0 factor */
+ /******************/
+
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (ul_TimingInterval
+ *
+ 60)
+ *
+ (250000.0
+ *
+ b_PCIInputClock));
+
+ /*******************/
+ /* Round the value */
+ /*******************/
+
+ if ((double)((double)(ul_TimingInterval * 60.0) * (250000.0 * (double)b_PCIInputClock)) >= ((double)((double)ul_TimerValue + 0.5))) {
+ ul_TimerValue
+ =
+ ul_TimerValue
+ +
+ 1;
+ }
+
+ /*****************************/
+ /* Calculate the real timing */
+ /*****************************/
+
+ ul_RealTimingInterval
+ =
+ (ULONG)
+ (ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock))
+ /
+ 60;
+ d_RealTimingInterval
+ =
+ (
+ (double)
+ ul_TimerValue
+ /
+ (250000.0
+ *
+ (double)
+ b_PCIInputClock))
+ /
+ 60.0;
+
+ if ((double)(((double)ul_TimerValue / (250000.0 * (double)b_PCIInputClock)) / 60.0) >= (double)((double)ul_RealTimingInterval + 0.5)) {
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval
+ +
+ 1;
+ }
+
+ ul_TimingInterval
+ =
+ ul_TimingInterval
+ -
+ 1;
+ ul_TimerValue
+ =
+ ul_TimerValue
+ -
+ 2;
+
+ if (b_PCIInputClock != APCI1710_40MHZ) {
+ ul_TimerValue
+ =
+ (ULONG)
+ (
+ (double)
+ (ul_TimerValue)
+ *
+ 1.007752288);
+ }
+
+ break;
+ }
+
+ fpu_end();
+ } // if (b_PCIInputClock != APCI1710_GATE_INPUT)
+ else {
+ /*************************************************************/
+ /* 2 Clock used for the overflow and the reload from counter */
+ /*************************************************************/
+
+ ul_TimerValue
+ =
+ ul_TimingInterval
+ -
+ 2;
+ } // if (b_PCIInputClock != APCI1710_GATE_INPUT)
+
+ /****************************/
+ /* Save the PCI input clock */
+ /****************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ b_PCIInputClock
+ =
+ b_PCIInputClock;
+
+ /************************/
+ /* Save the timing unit */
+ /************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_TimingUnit
+ =
+ b_TimingUnit;
+
+ /************************/
+ /* Save the base timing */
+ /************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ d_TimingInterval
+ =
+ d_RealTimingInterval;
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ ul_RealTimingInterval
+ =
+ ul_RealTimingInterval;
+
+ /*******************/
+ /* Get the command */
+ /*******************/
+
+ dw_Command
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 4
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ dw_Command
+ =
+ (dw_Command
+ >>
+ 4)
+ &
+ 0xF;
+
+ /******************/
+ /* Test if 40 MHz */
+ /******************/
+
+ if (b_PCIInputClock == APCI1710_40MHZ) {
+ /****************************/
+ /* Set the 40 MHz selection */
+ /****************************/
+
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x10;
+ }
+
+ /*****************************/
+ /* Test if extern clock used */
+ /*****************************/
+
+ if (b_PCIInputClock == APCI1710_GATE_INPUT) {
+ /****************************/
+ /* Set the 40 MHz selection */
+ /****************************/
+
+ dw_Command
+ =
+ dw_Command
+ |
+ 0x20;
+ }
+
+ /*************************/
+ /* Write the new command */
+ /*************************/
+
+ outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /*******************/
+ /* Disable the tor */
+ /*******************/
+
+ outl(0, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+ /*************************/
+ /* Set the timer 1 value */
+ /*************************/
+
+ outl(ul_TimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /*********************/
+ /* Tor counter init. */
+ /*********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_TorCounterInit
+ =
+ 1;
+ } else {
+ /***********************************************/
+ /* TOR version error for 40MHz clock selection */
+ /***********************************************/
+
+ DPRINTK("TOR version error for 40MHz clock selection\n");
+ i_ReturnValue
+ =
+ -9;
+ }
+ } else {
+ /**************************************************************/
+ /* You can not used the 40MHz clock selection wich this board */
+ /**************************************************************/
+
+ DPRINTK("You can not used the 40MHz clock selection wich this board\n");
+ i_ReturnValue =
+ -8;
+ }
+ } else {
+ /**********************************/
+ /* Base timing selection is wrong */
+ /**********************************/
+
+ DPRINTK("Base timing selection is wrong\n");
+ i_ReturnValue = -7;
+ }
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ else {
+ /**********************************/
+ /* Timing unit selection is wrong */
+ /**********************************/
+
+ DPRINTK("Timing unit selection is wrong\n");
+ i_ReturnValue = -6;
+ } // if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4))
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ else {
+ /*****************************************/
+ /* The selected PCI input clock is wrong */
+ /*****************************************/
+
+ DPRINTK("The selected PCI input clock is wrong\n");
+ i_ReturnValue = -5;
+ } // if ((b_PCIInputClock == APCI1710_30MHZ) || (b_PCIInputClock == APCI1710_33MHZ))
+ } // if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)
+ else {
+ /**********************************/
+ /* Tor Counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor Counter selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounterMode >= 0 && b_TorCounterMode <= 7)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+ data[0] = (UINT) ul_RealTimingInterval;
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_EnableTorCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| BYTE_ b_InputMode, |
+| BYTE_ b_ExternGate, |
+| BYTE_ b_CycleMode, |
+| BYTE_ b_InterruptEnable) |
++----------------------------------------------------------------------------+
+| Task : Enable the tor counter (b_TorCounter) from selected |
+| module (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitTorCounter" function be for you call |
+| this function. |
+| If you enable the tor counter interrupt, the |
+| tor counter generate a interrupt after the timing cycle|
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter from this manual. |
+| The b_CycleMode parameter determine if you will |
+| measured a single or more cycle. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1). |
+| BYTE_ b_InputMode : Input signal level selection |
+| 0 : Tor count each low level |
+| 1 : Tor count each high level|
+| BYTE_ b_ExternGate : Extern gate action selection |
+| 0 : Extern gate signal not |
+| used |
+| 1 : Extern gate signal used. |
+| If you selected the |
+| single mode, each high |
+| level signal start the |
+| counter. |
+| If you selected the |
+| continuous mode, the |
+| first high level signal |
+| start the tor counter |
+| |
+| APCI1710_TOR_QUADRUPLE _MODE : |
+| In the quadruple mode, the edge|
+| analysis circuit generates a |
+| counting pulse from each edge |
+| of 2 signals which are phase |
+| shifted in relation to each |
+| other. |
+| The gate input is used for the |
+| signal B |
+| |
+| APCI1710_TOR_DOUBLE_MODE: |
+| Functions in the same way as |
+| the quadruple mode, except that|
+| only two of the four edges are |
+| analysed per period. |
+| The gate input is used for the |
+| signal B |
+| |
+| APCI1710_TOR_SIMPLE_MODE: |
+| Functions in the same way as |
+| the quadruple mode, except that|
+| only one of the four edges is |
+| analysed per period. |
+| The gate input is used for the |
+| signal B |
+| |
+| BYTE_ b_CycleMode : Selected the tor counter |
+| acquisition mode |
+| BYTE_ b_InterruptEnable : Enable or disable the |
+| tor counter interrupt. |
+| APCI1710_ENABLE: |
+| Enable the tor counter |
+| interrupt |
+| APCI1710_DISABLE: |
+| Disable the tor counter |
+| interrupt |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
+| -6: Tor input signal selection is wrong |
+| -7: Extern gate signal mode is wrong |
+| -8: Tor counter acquisition mode cycle is wrong |
+| -9: Interrupt parameter is wrong |
+| -10:Interrupt function not initialised. |
+| See function "i_APCI1710_SetBoardIntRoutineX" |
++----------------------------------------------------------------------------+
+*/
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_DisableTorCounter |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter) |
++----------------------------------------------------------------------------+
+| Task : Disable the tor counter (b_TorCounter) from selected |
+| module (b_ModulNbr). If you disable the tor counter |
+| after a start cycle occur and you restart the tor |
+| counter witch the " i_APCI1710_EnableTorCounter" |
+| function, the status register is cleared |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1). |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
+| -6: Tor counter not enabled see function |
+| "i_APCI1710_EnableTorCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_DummyRead;
+ DWORD dw_ConfigReg;
+ BYTE b_ModulNbr, b_Action;
+ BYTE b_TorCounter;
+ BYTE b_InputMode;
+ BYTE b_ExternGate;
+ BYTE b_CycleMode;
+ BYTE b_InterruptEnable;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_Action = (BYTE) data[0]; // enable or disable
+ b_TorCounter = (BYTE) data[1];
+ b_InputMode = (BYTE) data[2];
+ b_ExternGate = (BYTE) data[3];
+ b_CycleMode = (BYTE) data[4];
+ b_InterruptEnable = (BYTE) data[5];
+ i_ReturnValue = insn->n;;
+ devpriv->tsk_Current = current; // Save the current process task structure
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+ switch (b_Action) // Enable or Disable
+ {
+ case APCI1710_ENABLE:
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ /******************************/
+ /* Test the input signal mode */
+ /******************************/
+
+ if (b_InputMode == 0 ||
+ b_InputMode == 1 ||
+ b_InputMode ==
+ APCI1710_TOR_SIMPLE_MODE
+ || b_InputMode ==
+ APCI1710_TOR_DOUBLE_MODE
+ || b_InputMode ==
+ APCI1710_TOR_QUADRUPLE_MODE)
+ {
+ /************************************/
+ /* Test the extern gate signal mode */
+ /************************************/
+
+ if (b_ExternGate == 0
+ || b_ExternGate
+ == 1
+ || b_InputMode >
+ 1) {
+ /*********************************/
+ /* Test the cycle mode parameter */
+ /*********************************/
+
+ if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS)) {
+ /***************************/
+ /* Test the interrupt flag */
+ /***************************/
+
+ if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE)) {
+
+ /***************************/
+ /* Save the interrupt mode */
+ /***************************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_InterruptEnable
+ =
+ b_InterruptEnable;
+
+ /*******************/
+ /* Get the command */
+ /*******************/
+
+ dw_ConfigReg
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 4
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ dw_ConfigReg
+ =
+ (dw_ConfigReg
+ >>
+ 4)
+ &
+ 0x30;
+
+ /********************************/
+ /* Test if not direct mode used */
+ /********************************/
+
+ if (b_InputMode > 1) {
+ /*******************************/
+ /* Extern gate can not be used */
+ /*******************************/
+
+ b_ExternGate
+ =
+ 0;
+
+ /*******************************************/
+ /* Enable the extern gate for the Signal B */
+ /*******************************************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ 0x40;
+
+ /***********************/
+ /* Test if simple mode */
+ /***********************/
+
+ if (b_InputMode == APCI1710_TOR_SIMPLE_MODE) {
+ /**************************/
+ /* Enable the sinple mode */
+ /**************************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ 0x780;
+
+ } // if (b_InputMode == APCI1710_TOR_SIMPLE_MODE)
+
+ /***********************/
+ /* Test if double mode */
+ /***********************/
+
+ if (b_InputMode == APCI1710_TOR_DOUBLE_MODE) {
+ /**************************/
+ /* Enable the double mode */
+ /**************************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ 0x180;
+
+ } // if (b_InputMode == APCI1710_TOR_DOUBLE_MODE)
+
+ b_InputMode
+ =
+ 0;
+ } // if (b_InputMode > 1)
+
+ /*******************/
+ /* Set the command */
+ /*******************/
+
+ dw_ConfigReg
+ =
+ dw_ConfigReg
+ |
+ b_CycleMode
+ |
+ (b_InterruptEnable
+ *
+ 2)
+ |
+ (b_InputMode
+ *
+ 4)
+ |
+ (b_ExternGate
+ *
+ 8);
+
+ /*****************************/
+ /* Clear the status register */
+ /*****************************/
+
+ dw_DummyRead
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 0
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /***************************************/
+ /* Clear the interrupt status register */
+ /***************************************/
+
+ dw_DummyRead
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 12
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /********************/
+ /* Set the commando */
+ /********************/
+
+ outl(dw_ConfigReg, devpriv->s_BoardInfos.ui_Address + 4 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ /****************/
+ /* Set the gate */
+ /****************/
+
+ outl(1, devpriv->s_BoardInfos.ui_Address + 8 + (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ else {
+ /********************************/
+ /* Interrupt parameter is wrong */
+ /********************************/
+
+ DPRINTK("Interrupt parameter is wrong\n");
+ i_ReturnValue
+ =
+ -9;
+ } // if ((b_InterruptEnable == APCI1710_ENABLE) || (b_InterruptEnable == APCI1710_DISABLE))
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ else {
+ /***********************************************/
+ /* Tor counter acquisition mode cycle is wrong */
+ /***********************************************/
+
+ DPRINTK("Tor counter acquisition mode cycle is wrong\n");
+ i_ReturnValue
+ =
+ -8;
+ } // if ((b_CycleMode == APCI1710_SINGLE) || (b_CycleMode == APCI1710_CONTINUOUS))
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ else {
+ /***********************************/
+ /* Extern gate input mode is wrong */
+ /***********************************/
+
+ DPRINTK("Extern gate input mode is wrong\n");
+ i_ReturnValue =
+ -7;
+ } // if (b_ExternGate >= 0 && b_ExternGate <= 1)
+ } // if (b_InputMode >= 0 && b_InputMode <= 1)
+ else {
+ /***************************************/
+ /* Tor input signal selection is wrong */
+ /***************************************/
+
+ DPRINTK("Tor input signal selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ }
+ break;
+
+ case APCI1710_DISABLE:
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (dw_Status & 0x10) {
+ /***************************/
+ /* Test if counter enabled */
+ /***************************/
+
+ if (dw_Status & 0x1) {
+ /****************************/
+ /* Clear the interrupt mode */
+ /****************************/
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo
+ [b_TorCounter].
+ b_InterruptEnable
+ =
+ APCI1710_DISABLE;
+
+ /******************/
+ /* Clear the gate */
+ /******************/
+
+ outl(0, devpriv->
+ s_BoardInfos.
+ ui_Address + 8 +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+ } // if (dw_Status & 0x1)
+ else {
+ /***************************/
+ /* Tor counter not enabled */
+ /***************************/
+
+ DPRINTK("Tor counter not enabled \n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } // if (dw_Status & 0x10)
+ else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ } // // if (dw_Status & 0x10)
+
+ } // switch
+ } // if (b_TorCounter <= 1)
+ else {
+ /**********************************/
+ /* Tor counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor counter selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounter <= 1)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module \n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error \n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_GetTorCounterInitialisation |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| PBYTE_ pb_TimingUnit, |
+| PULONG_ pul_TimingInterval, |
+| PBYTE_ pb_InputMode, |
+| PBYTE_ pb_ExternGate, |
+| PBYTE_ pb_CycleMode, |
+| PBYTE_ pb_Enable, |
+| PBYTE_ pb_InterruptEnable)|
++----------------------------------------------------------------------------+
+| Task : Enable the tor counter (b_TorCounter) from selected |
+| module (b_ModulNbr). You must calling the |
+| "i_APCI1710_InitTorCounter" function be for you call |
+| this function. |
+| If you enable the tor counter interrupt, the |
+| tor counter generate a interrupt after the timing cycle|
+| See function "i_APCI1710_SetBoardIntRoutineX" and the |
+| Interrupt mask description chapter from this manual. |
+| The b_CycleMode parameter determine if you will |
+| measured a single or more cycle. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1)
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_TorCounter = CR_CHAN(insn->chanspec);
+. |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TimingUnit : Base timing unit (0 to 4) |
+| 0 : ns |
+| 1 : µs |
+| 2 : ms |
+| 3 : s |
+| 4 : mn |
+| PULONG_ pul_TimingInterval : Base timing value. |
+| PBYTE_ pb_InputMode : Input signal level |
+| selection |
+| 0 : Tor count each low level |
+| 1 : Tor count each high level|
+| PBYTE_ pb_ExternGate : Extern gate action |
+| selection |
+| 0 : Extern gate signal not |
+| used |
+| 1 : Extern gate signal used|
+| PBYTE_ pb_CycleMode : Tor counter acquisition |
+| mode |
+| PBYTE_ pb_Enable : Indicate if the tor counter|
+| is enabled or no |
+| 0 : Tor counter disabled |
+| 1 : Tor counter enabled |
+| PBYTE_ pb_InterruptEnable : Enable or disable the |
+| tor counter interrupt. |
+| APCI1710_ENABLE: |
+| Enable the tor counter |
+| interrupt |
+| APCI1710_DISABLE: |
+| Disable the tor counter |
+| interrupt
+ pb_TimingUnit = (PBYTE) &data[0];
+ pul_TimingInterval = (PULONG) &data[1];
+ pb_InputMode = (PBYTE) &data[2];
+ pb_ExternGate = (PBYTE) &data[3];
+ pb_CycleMode = (PBYTE) &data[4];
+ pb_Enable = (PBYTE) &data[5];
+ pb_InterruptEnable = (PBYTE) &data[6];
+ |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ BYTE b_ModulNbr;
+ BYTE b_TorCounter;
+ PBYTE pb_TimingUnit;
+ PULONG pul_TimingInterval;
+ PBYTE pb_InputMode;
+ PBYTE pb_ExternGate;
+ PBYTE pb_CycleMode;
+ PBYTE pb_Enable;
+ PBYTE pb_InterruptEnable;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_TorCounter = CR_CHAN(insn->chanspec);
+
+ pb_TimingUnit = (PBYTE) & data[0];
+ pul_TimingInterval = (PULONG) & data[1];
+ pb_InputMode = (PBYTE) & data[2];
+ pb_ExternGate = (PBYTE) & data[3];
+ pb_CycleMode = (PBYTE) & data[4];
+ pb_Enable = (PBYTE) & data[5];
+ pb_InterruptEnable = (PBYTE) & data[6];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ if (dw_Status & 0x10) {
+ *pb_Enable = dw_Status & 1;
+
+ /********************/
+ /* Get the commando */
+ /********************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 4 +
+ (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ *pb_CycleMode =
+ (BYTE) ((dw_Status >> 4) & 1);
+ *pb_InterruptEnable =
+ (BYTE) ((dw_Status >> 5) & 1);
+
+ /******************************************************/
+ /* Test if extern gate used for clock or for signal B */
+ /******************************************************/
+
+ if (dw_Status & 0x600) {
+ /*****************************************/
+ /* Test if extern gate used for signal B */
+ /*****************************************/
+
+ if (dw_Status & 0x400) {
+ /***********************/
+ /* Test if simple mode */
+ /***********************/
+
+ if ((dw_Status & 0x7800)
+ == 0x7800) {
+ *pb_InputMode =
+ APCI1710_TOR_SIMPLE_MODE;
+ }
+
+ /***********************/
+ /* Test if double mode */
+ /***********************/
+
+ if ((dw_Status & 0x7800)
+ == 0x1800) {
+ *pb_InputMode =
+ APCI1710_TOR_DOUBLE_MODE;
+ }
+
+ /**************************/
+ /* Test if quadruple mode */
+ /**************************/
+
+ if ((dw_Status & 0x7800)
+ == 0x0000) {
+ *pb_InputMode =
+ APCI1710_TOR_QUADRUPLE_MODE;
+ }
+ } // if (dw_Status & 0x400)
+ else {
+ *pb_InputMode = 1;
+ } // // if (dw_Status & 0x400)
+
+ /************************/
+ /* Extern gate not used */
+ /************************/
+
+ *pb_ExternGate = 0;
+ } // if (dw_Status & 0x600)
+ else {
+ *pb_InputMode =
+ (BYTE) ((dw_Status >> 6)
+ & 1);
+ *pb_ExternGate =
+ (BYTE) ((dw_Status >> 7)
+ & 1);
+ } // if (dw_Status & 0x600)
+
+ *pb_TimingUnit =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo[b_TorCounter].
+ b_TimingUnit;
+
+ *pul_TimingInterval =
+ devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo[b_TorCounter].
+ ul_RealTimingInterval;
+ } else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ }
+
+ } // if (b_TorCounter <= 1)
+ else {
+ /**********************************/
+ /* Tor counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor counter selection is wrong \n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounter <= 1)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadTorCounterValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_TorCounter, |
+| UINT_ ui_TimeOut, |
+| PBYTE_ pb_TorCounterStatus, |
+| PULONG_ pul_TorCounterValue) |
++----------------------------------------------------------------------------+
+| Task case APCI1710_TOR_GETPROGRESSSTATUS: Return the tor counter
+(b_TorCounter) status (pb_TorCounterStatus) from selected tor counter |
+| module (b_ModulNbr).
+
+ case APCI1710_TOR_GETCOUNTERVALUE :
+ Return the tor counter (b_TorCounter) status |
+| (pb_TorCounterStatus) and the timing value |
+| (pul_TorCounterValue) after a conting cycle stop |
+| from selected tor counter module (b_ModulNbr). |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3) |
+| BYTE_ b_TorCounter : Tor counter selection (0 or 1).
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+ b_TorCounter = (BYTE) data[1];
+ ui_TimeOut = (UINT) data[2]; |
++----------------------------------------------------------------------------+
+| Output Parameters : PBYTE_ pb_TorCounterStatus : Return the tor counter |
+| status. |
+| 0 : Conting cycle not started|
+| Software gate not set. |
+| 1 : Conting cycle started. |
+| Software gate set. |
+| 2 : Conting cycle stopped. |
+| The conting cycle is |
+| terminate. |
+| 3 : A overflow occur. You |
+| must change the base |
+| timing witch the |
+| function |
+| "i_APCI1710_InitTorCounter"|
+| 4 : Timeeout occur |
+| PULONG pul_TorCounterValue : Tor counter value.
+ pb_TorCounterStatus=(PBYTE) &data[0];
+ pul_TorCounterValue=(PULONG) &data[1]; |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: Module selection wrong |
+| -3: The module is not a tor counter module |
+| -4: Tor counter selection is wrong |
+| -5: Tor counter not initialised see function |
+| "i_APCI1710_InitTorCounter" |
+| -6: Tor counter not enabled see function |
+| "i_APCI1710_EnableTorCounter" |
+| -7: Timeout parameter is wrong (0 to 65535) |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_Status;
+ DWORD dw_TimeOut = 0;
+
+ BYTE b_ModulNbr;
+ BYTE b_TorCounter;
+ BYTE b_ReadType;
+ UINT ui_TimeOut;
+ PBYTE pb_TorCounterStatus;
+ PULONG pul_TorCounterValue;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+ b_TorCounter = (BYTE) data[1];
+ ui_TimeOut = (UINT) data[2];
+ pb_TorCounterStatus = (PBYTE) & data[0];
+ pul_TorCounterValue = (PULONG) & data[1];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ReadType == APCI1710_TOR_READINTERRUPT) {
+
+ data[0] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].b_OldModuleMask;
+ data[1] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldInterruptMask;
+ data[2] = devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
+
+ /**************************/
+ /* Increment the read FIFO */
+ /***************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Read = (devpriv->
+ s_InterruptParameters.
+ ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
+
+ return insn->n;
+ }
+
+ if (b_ModulNbr < 4) {
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ /**********************************/
+ /* Test the tor counter selection */
+ /**********************************/
+
+ if (b_TorCounter <= 1) {
+ /***********************************/
+ /* Test if tor counter initialised */
+ /***********************************/
+
+ dw_Status = inl(devpriv->s_BoardInfos.
+ ui_Address + 8 + (16 * b_TorCounter) +
+ (64 * b_ModulNbr));
+
+ /*******************************/
+ /* Test if counter initialised */
+ /*******************************/
+
+ if (dw_Status & 0x10) {
+ /***************************/
+ /* Test if counter enabled */
+ /***************************/
+
+ if (dw_Status & 0x1) {
+
+ switch (b_ReadType) {
+
+ case APCI1710_TOR_GETPROGRESSSTATUS:
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_Status =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 4 +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ dw_Status =
+ dw_Status & 0xF;
+
+ /*****************/
+ /* Test if start */
+ /*****************/
+
+ if (dw_Status & 1) {
+ if (dw_Status &
+ 2) {
+ if (dw_Status & 4) {
+ /************************/
+ /* Tor counter owerflow */
+ /************************/
+
+ *pb_TorCounterStatus
+ =
+ 3;
+ } else {
+ /***********************/
+ /* Tor counter started */
+ /***********************/
+
+ *pb_TorCounterStatus
+ =
+ 2;
+ }
+ } else {
+ /***********************/
+ /* Tor counter started */
+ /***********************/
+
+ *pb_TorCounterStatus
+ =
+ 1;
+ }
+ } else {
+ /***************************/
+ /* Tor counter not started */
+ /***************************/
+
+ *pb_TorCounterStatus
+ = 0;
+ }
+ break;
+
+ case APCI1710_TOR_GETCOUNTERVALUE:
+
+ /*****************************/
+ /* Test the timout parameter */
+ /*****************************/
+
+ if ((ui_TimeOut >= 0)
+ && (ui_TimeOut
+ <=
+ 65535UL))
+ {
+ for (;;) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ dw_Status
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 4
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+ /********************/
+ /* Test if overflow */
+ /********************/
+
+ if ((dw_Status & 4) == 4) {
+ /******************/
+ /* Overflow occur */
+ /******************/
+
+ *pb_TorCounterStatus
+ =
+ 3;
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_TorCounterValue
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 0
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+ break;
+ } // if ((dw_Status & 4) == 4)
+ else {
+ /*******************************/
+ /* Test if measurement stopped */
+ /*******************************/
+
+ if ((dw_Status & 2) == 2) {
+ /***********************/
+ /* A stop signal occur */
+ /***********************/
+
+ *pb_TorCounterStatus
+ =
+ 2;
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ *pul_TorCounterValue
+ =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ 0
+ +
+ (16 * b_TorCounter) + (64 * b_ModulNbr));
+
+ break;
+ } // if ((dw_Status & 2) == 2)
+ else {
+ /*******************************/
+ /* Test if measurement started */
+ /*******************************/
+
+ if ((dw_Status & 1) == 1) {
+ /************************/
+ /* A start signal occur */
+ /************************/
+
+ *pb_TorCounterStatus
+ =
+ 1;
+ } // if ((dw_Status & 1) == 1)
+ else {
+ /***************************/
+ /* Measurement not started */
+ /***************************/
+
+ *pb_TorCounterStatus
+ =
+ 0;
+ } // if ((dw_Status & 1) == 1)
+ } // if ((dw_Status & 2) == 2)
+ } // if ((dw_Status & 8) == 8)
+
+ if (dw_TimeOut == ui_TimeOut) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ break;
+ } else {
+ /*************************/
+ /* Increment the timeout */
+ /*************************/
+
+ dw_TimeOut
+ =
+ dw_TimeOut
+ +
+ 1;
+
+ mdelay(1000);
+ }
+ } // for (;;)
+
+ /*************************/
+ /* Test if timeout occur */
+ /*************************/
+
+ if ((*pb_TorCounterStatus != 3) && (dw_TimeOut == ui_TimeOut) && (ui_TimeOut != 0)) {
+ /*****************/
+ /* Timeout occur */
+ /*****************/
+
+ *pb_TorCounterStatus
+ =
+ 4;
+ }
+ } else {
+ /******************************/
+ /* Timeout parameter is wrong */
+ /******************************/
+
+ DPRINTK("Timeout parameter is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ break;
+
+ default:
+ printk("Inputs wrong\n");
+ } // switch end
+ } // if (dw_Status & 0x1)
+ else {
+ /***************************/
+ /* Tor counter not enabled */
+ /***************************/
+
+ DPRINTK("Tor counter not enabled\n");
+ i_ReturnValue = -6;
+ } // if (dw_Status & 0x1)
+ } else {
+ /*******************************/
+ /* Tor counter not initialised */
+ /*******************************/
+
+ DPRINTK("Tor counter not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } // if (b_TorCounter <= 1)
+ else {
+ /**********************************/
+ /* Tor counter selection is wrong */
+ /**********************************/
+
+ DPRINTK("Tor counter selection is wrong\n");
+ i_ReturnValue = -4;
+ } // if (b_TorCounter <= 1)
+ } else {
+ /******************************************/
+ /* The module is not a tor counter module */
+ /******************************************/
+
+ DPRINTK("The module is not a tor counter module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
new file mode 100644
index 00000000000..c245d16207b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_30MHZ 30
+#define APCI1710_33MHZ 33
+#define APCI1710_40MHZ 40
+
+#define APCI1710_GATE_INPUT 10
+
+#define APCI1710_TOR_SIMPLE_MODE 2
+#define APCI1710_TOR_DOUBLE_MODE 3
+#define APCI1710_TOR_QUADRUPLE_MODE 4
+
+#define APCI1710_SINGLE 0
+#define APCI1710_CONTINUOUS 1
+
+#define APCI1710_TOR_GETPROGRESSSTATUS 0
+#define APCI1710_TOR_GETCOUNTERVALUE 1
+#define APCI1710_TOR_READINTERRUPT 2
+
+/*
+ * TOR_COUNTER INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTorCounter(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+INT i_APCI1710_InsnReadGetTorCounterInitialisation(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+/*
+ * TOR_COUNTER READ FUNCTION
+ */
+INT i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
new file mode 100644
index 00000000000..68b1d26bae1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.c
@@ -0,0 +1,1038 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1710 | Compiler : gcc |
+ | Module name : TTL.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-1710 TTL I/O module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 13/05/98 | S. Weber | TTL digital input / output implementation |
+ |----------|-----------|------------------------------------------------|
+ | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
+ | | | available |
+ +-----------------------------------------------------------------------+
+ | | | |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "APCI1710_Ttl.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_InitTTLIODirection |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_PortAMode, |
+| BYTE_ b_PortBMode, |
+| BYTE_ b_PortCMode, |
+| BYTE_ b_PortDMode) |
++----------------------------------------------------------------------------+
+| Task APCI1710_TTL_INIT (using defaults) : Configure the TTL I/O operating mode from selected |
+| module (b_ModulNbr). You must calling this function be|
+| for you call any other function witch access of TTL. |
+ APCI1710_TTL_INITDIRECTION(user inputs for direction)
+
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3)
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_InitType = (BYTE) data[0];
+ b_PortAMode = (BYTE) data[1];
+ b_PortBMode = (BYTE) data[2];
+ b_PortCMode = (BYTE) data[3];
+ b_PortDMode = (BYTE) data[4];|
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL module |
+| -4: Function not available for this version |
+| -5: Port A mode selection is wrong |
+| -6: Port B mode selection is wrong |
+| -7: Port C mode selection is wrong |
+| -8: Port D mode selection is wrong |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnConfigInitTTLIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ BYTE b_ModulNbr;
+ BYTE b_InitType;
+ BYTE b_PortAMode;
+ BYTE b_PortBMode;
+ BYTE b_PortCMode;
+ BYTE b_PortDMode;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ b_InitType = (BYTE) data[0];
+ i_ReturnValue = insn->n;
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ switch (b_InitType) {
+ case APCI1710_TTL_INIT:
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit = 1;
+
+ /***************************/
+ /* Set TTL port A to input */
+ /***************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[0] = 0;
+
+ /***************************/
+ /* Set TTL port B to input */
+ /***************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[1] = 0;
+
+ /***************************/
+ /* Set TTL port C to input */
+ /***************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[2] = 0;
+
+ /****************************/
+ /* Set TTL port D to output */
+ /****************************/
+
+ devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_PortConfiguration[3] = 1;
+
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(0x8,
+ devpriv->s_BoardInfos.ui_Address + 20 +
+ (64 * b_ModulNbr));
+ break;
+
+ case APCI1710_TTL_INITDIRECTION:
+
+ b_PortAMode = (BYTE) data[1];
+ b_PortBMode = (BYTE) data[2];
+ b_PortCMode = (BYTE) data[3];
+ b_PortDMode = (BYTE) data[4];
+
+ /********************/
+ /* Test the version */
+ /********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] & 0xFFFF) >=
+ 0x3230) {
+ /************************/
+ /* Test the port A mode */
+ /************************/
+
+ if ((b_PortAMode == 0)
+ || (b_PortAMode == 1)) {
+ /************************/
+ /* Test the port B mode */
+ /************************/
+
+ if ((b_PortBMode == 0)
+ || (b_PortBMode == 1)) {
+ /************************/
+ /* Test the port C mode */
+ /************************/
+
+ if ((b_PortCMode == 0)
+ || (b_PortCMode
+ == 1)) {
+ /************************/
+ /* Test the port D mode */
+ /************************/
+
+ if ((b_PortDMode == 0) || (b_PortDMode == 1)) {
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_TTLInit
+ =
+ 1;
+
+ /***********************/
+ /* Set TTL port A mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [0]
+ =
+ b_PortAMode;
+
+ /***********************/
+ /* Set TTL port B mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [1]
+ =
+ b_PortBMode;
+
+ /***********************/
+ /* Set TTL port C mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [2]
+ =
+ b_PortCMode;
+
+ /***********************/
+ /* Set TTL port D mode */
+ /***********************/
+
+ devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [3]
+ =
+ b_PortDMode;
+
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl((b_PortAMode << 0) | (b_PortBMode << 1) | (b_PortCMode << 2) | (b_PortDMode << 3), devpriv->s_BoardInfos.ui_Address + 20 + (64 * b_ModulNbr));
+ } else {
+ /**********************************/
+ /* Port D mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port D mode selection is wrong\n");
+ i_ReturnValue
+ =
+ -8;
+ }
+ } else {
+ /**********************************/
+ /* Port C mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port C mode selection is wrong\n");
+ i_ReturnValue =
+ -7;
+ }
+ } else {
+ /**********************************/
+ /* Port B mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port B mode selection is wrong\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /**********************************/
+ /* Port A mode selection is wrong */
+ /**********************************/
+
+ DPRINTK("Port A mode selection is wrong\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************************/
+ /* Function not available for this version */
+ /*******************************************/
+
+ DPRINTK("Function not available for this version\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ DPRINTK("\n");
+ default:
+ printk("Bad Config Type\n");
+ } // switch end
+ } else {
+ /**********************************/
+ /* The module is not a TTL module */
+ /**********************************/
+
+ DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_ReadTTLIOChannelValue |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_SelectedPort, |
+| BYTE_ b_InputChannel, |
+| PBYTE_ pb_ChannelStatus) |
++----------------------------------------------------------------------------+
+| Task : Read the status from selected TTL digital input |
+| (b_InputChannel)
++----------------------------------------------------------------------------+
+| Task : Read the status from digital input port |
+| (b_SelectedPort) from selected TTL module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 7) |
+| BYTE_ b_SelectedPort, : Selection from TTL I/O |
+| port (0 to 2) |
+| 0 : Port A selection |
+| 1 : Port B selection |
+| 2 : Port C selection |
+| 3 : Port D selection |
+| BYTE_ b_InputChannel : Selection from digital |
+| input ( 0 to 2)
+APCI1710_TTL_READCHANNEL
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SelectedPort= CR_RANGE(insn->chanspec);
+ b_InputChannel= CR_CHAN(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+
+ APCI1710_TTL_READPORT|
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SelectedPort= CR_RANGE(insn->chanspec);
+ b_ReadType = (BYTE) data[0];
+
++----------------------------------------------------------------------------+
+| Output Parameters : data[0]
+
+ PBYTE_ pb_ChannelStatus : Digital input channel |
+| status |
+| 0 : Channle is not active|
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL module |
+| -4: The selected TTL input port is wrong |
+| -5: The selected TTL digital input is wrong |
+| -6: TTL I/O not initialised |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnBitsReadTTLIO(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr;
+ BYTE b_SelectedPort;
+ BYTE b_InputChannel;
+ BYTE b_ReadType;
+ PBYTE pb_ChannelStatus;
+ PBYTE pb_PortValue;
+
+ i_ReturnValue = insn->n;
+ b_ReadType = (BYTE) data[0];
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_SelectedPort = CR_RANGE(insn->chanspec);
+ b_InputChannel = CR_CHAN(insn->chanspec);
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ switch (b_ReadType) {
+
+ case APCI1710_TTL_READCHANNEL:
+ pb_ChannelStatus = (PBYTE) & data[0];
+ /********************************/
+ /* Test the TTL I/O port number */
+ /********************************/
+
+ if (((b_SelectedPort <= 2)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) ==
+ 0x3130))
+ || ((b_SelectedPort <= 3)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3230))) {
+ /******************************************/
+ /* Test the digital imnput channel number */
+ /******************************************/
+
+ if (((b_InputChannel <= 7)
+ && (b_SelectedPort < 3))
+ || ((b_InputChannel <= 1)
+ && (b_SelectedPort ==
+ 3))) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit ==
+ 1) {
+ /***********************************/
+ /* Test if TTL port used for input */
+ /***********************************/
+
+ if (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) == 0x3130) || (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ (64 * b_ModulNbr));
+
+ *pb_ChannelStatus
+ =
+ (BYTE) (
+ (dw_StatusReg
+ >>
+ (8 * b_SelectedPort)) >> b_InputChannel) & 1;
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue =
+ -4;
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -6;
+ }
+ } else {
+ /********************************/
+ /* Selected digital input error */
+ /********************************/
+
+ DPRINTK("Selected digital input error\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ case APCI1710_TTL_READPORT:
+ pb_PortValue = (PBYTE) & data[0];
+ /********************************/
+ /* Test the TTL I/O port number */
+ /********************************/
+
+ if (((b_SelectedPort <= 2)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) ==
+ 0x3130))
+ || ((b_SelectedPort <= 3)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3230))) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit == 1) {
+ /***********************************/
+ /* Test if TTL port used for input */
+ /***********************************/
+
+ if (((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr]
+ &
+ 0xFFFF)
+ == 0x3130)
+ || (((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF) >= 0x3230) && (devpriv->s_ModuleInfo[b_ModulNbr].s_TTLIOInfo.b_PortConfiguration[b_SelectedPort] == 0))) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+
+ *pb_PortValue =
+ (BYTE) (
+ (dw_StatusReg >>
+ (8 * b_SelectedPort)) & 0xFF);
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /*******************************/
+ /* Selected TTL I/O port error */
+ /*******************************/
+
+ DPRINTK("Selected TTL I/O port error\n");
+ i_ReturnValue = -4;
+ }
+ break;
+
+ default:
+ printk("Bad ReadType\n");
+
+ } //End Switch
+ } else {
+ /**********************************/
+ /* The module is not a TTL module */
+ /**********************************/
+
+ DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI1710_InsnReadTTLIOAllPortValue(comedi_device
+*dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from all digital input ports |
+| (port A, port B and port C) from selected TTL |
+| module (b_ModulNbr) |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710|
+| BYTE_ b_ModulNbr : Module number to |
+| configure (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : PULONG_ pul_PortValue : Digital TTL inputs port |
+| status |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL module |
+| -4: TTL I/O not initialised |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg;
+ BYTE b_ModulNbr;
+ PULONG pul_PortValue;
+
+ b_ModulNbr = (BYTE) CR_AREF(insn->chanspec);
+ i_ReturnValue = insn->n;
+ pul_PortValue = (PULONG) & data[0];
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit == 1) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ dw_StatusReg = inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModulNbr));
+
+ /**********************/
+ /* Test if TTL Rev1.0 */
+ /**********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] & 0xFFFF) ==
+ 0x3130) {
+ *pul_PortValue =
+ dw_StatusReg & 0xFFFFFFUL;
+ } else {
+ /**************************************/
+ /* Test if port A not used for output */
+ /**************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[0] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0x3FFFF00UL;
+ }
+
+ /**************************************/
+ /* Test if port B not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[1] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0x3FF00FFUL;
+ }
+
+ /**************************************/
+ /* Test if port C not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[2] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0x300FFFFUL;
+ }
+
+ /**************************************/
+ /* Test if port D not used for output */
+ /**************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration[3] == 1) {
+ *pul_PortValue =
+ dw_StatusReg &
+ 0xFFFFFFUL;
+ }
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /**********************************/
+ /* The module is not a TTL module */
+ /**********************************/
+ DPRINTK("The module is not a TTL module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : _INT_ i_APCI1710_SetTTLIOChlOn |
+| (BYTE_ b_BoardHandle, |
+| BYTE_ b_ModulNbr, |
+| BYTE_ b_OutputChannel)
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Sets or resets the output witch has been passed with the |
+| parameter b_Channel. Setting an output means setting |
+| an ouput high. |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE_ b_BoardHandle : Handle of board APCI-1710 |
+| BYTE_ b_ModulNbr : Selected module number (0 to 3)|
+| BYTE_ b_OutputChannel : Selection from digital output |
+| channel (0 or 1) |
+| 0 : PD0 |
+| 1 : PD1 |
+| 2 to 9 : PA |
+| 10 to 17: PB |
+| 18 to 25: PC |
+
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_OutputChannel= CR_CHAN(insn->chanspec);
+ ui_State = data[0]; // ON or OFF
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -1: The handle parameter of the board is wrong |
+| -2: The module parameter is wrong |
+| -3: The module is not a TTL I/O module |
+| -4: The selected digital output is wrong |
+| -5: TTL I/O not initialised see function |
+| " i_APCI1710_InitTTLIO"
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = 0;
+ DWORD dw_StatusReg = 0;
+ BYTE b_ModulNbr;
+ BYTE b_OutputChannel;
+ UINT ui_State;
+
+ i_ReturnValue = insn->n;
+ b_ModulNbr = CR_AREF(insn->chanspec);
+ b_OutputChannel = CR_CHAN(insn->chanspec);
+ ui_State = data[0]; // ON or OFF
+
+ /**************************/
+ /* Test the module number */
+ /**************************/
+
+ if (b_ModulNbr < 4) {
+ /**************************/
+ /* Test if TTL I/O module */
+ /**************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModulNbr] &
+ 0xFFFF0000UL) == APCI1710_TTL_IO) {
+ /******************************************/
+ /* Test if the TTL I/O module initialised */
+ /******************************************/
+
+ if (devpriv->s_ModuleInfo[b_ModulNbr].
+ s_TTLIOInfo.b_TTLInit == 1) {
+ /***********************************/
+ /* Test the TTL I/O channel number */
+ /***********************************/
+
+ if (((b_OutputChannel <= 1)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) ==
+ 0x3130))
+ || ((b_OutputChannel <= 25)
+ && ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration
+ [b_ModulNbr] &
+ 0xFFFF) >=
+ 0x3230))) {
+ /****************************************************/
+ /* Test if the selected channel is a output channel */
+ /****************************************************/
+
+ if (((b_OutputChannel <= 1)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [3] == 1))
+ || ((b_OutputChannel >= 2)
+ && (b_OutputChannel <=
+ 9)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [0] == 1))
+ || ((b_OutputChannel >= 10)
+ && (b_OutputChannel <=
+ 17)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [1] == 1))
+ || ((b_OutputChannel >= 18)
+ && (b_OutputChannel <=
+ 25)
+ && (devpriv->
+ s_ModuleInfo
+ [b_ModulNbr].
+ s_TTLIOInfo.
+ b_PortConfiguration
+ [2] == 1))) {
+ /************************/
+ /* Test if PD0 selected */
+ /************************/
+
+ if (b_OutputChannel == 0) {
+
+ outl(ui_State,
+ devpriv->
+ s_BoardInfos.
+ ui_Address +
+ (64 * b_ModulNbr));
+ } else {
+ /************************/
+ /* Test if PD1 selected */
+ /************************/
+
+ if (b_OutputChannel ==
+ 1) {
+
+ outl(ui_State,
+ devpriv->
+ s_BoardInfos.
+ ui_Address
+ + 4 +
+ (64 * b_ModulNbr));
+ } else {
+ b_OutputChannel
+ =
+ b_OutputChannel
+ - 2;
+
+ /********************/
+ /* Read all channel */
+ /********************/
+
+ dw_StatusReg =
+ inl
+ (devpriv->
+ s_BoardInfos.
+ ui_Address
+ +
+ (64 * b_ModulNbr));
+ if (ui_State) // ON
+ {
+ dw_StatusReg
+ =
+ (dw_StatusReg
+ >>
+ ((b_OutputChannel / 8) * 8)) & 0xFF;
+ dw_StatusReg
+ =
+ dw_StatusReg
+ |
+ (1
+ <<
+ (b_OutputChannel
+ %
+ 8));
+ } else // Off
+ {
+ dw_StatusReg
+ =
+ (dw_StatusReg
+ >>
+ ((b_OutputChannel / 8) * 8)) & 0xFF;
+ dw_StatusReg
+ =
+ dw_StatusReg
+ &
+ (0xFF
+ -
+ (1 << (b_OutputChannel % 8)));
+
+ }
+
+ /****************************/
+ /* Set the new output value */
+ /****************************/
+
+ outl(dw_StatusReg, devpriv->s_BoardInfos.ui_Address + 8 + ((b_OutputChannel / 8) * 4) + (64 * b_ModulNbr));
+ }
+ }
+ } else {
+ /************************************/
+ /* The selected TTL output is wrong */
+ /************************************/
+
+ DPRINTK(" The selected TTL output is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /************************************/
+ /* The selected TTL output is wrong */
+ /************************************/
+
+ DPRINTK("The selected TTL output is wrong\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /***************************/
+ /* TTL I/O not initialised */
+ /***************************/
+
+ DPRINTK("TTL I/O not initialised\n");
+ i_ReturnValue = -5;
+ }
+ } else {
+ /**************************************/
+ /* The module is not a TTL I/O module */
+ /**************************************/
+
+ DPRINTK("The module is not a TTL I/O module\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /***********************/
+ /* Module number error */
+ /***********************/
+
+ DPRINTK("Module number error\n");
+ i_ReturnValue = -2;
+ }
+
+ return (i_ReturnValue);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
new file mode 100644
index 00000000000..00915ddf921
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Ttl.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define APCI1710_TTL_INIT 0
+#define APCI1710_TTL_INITDIRECTION 1
+
+#define APCI1710_TTL_READCHANNEL 0
+#define APCI1710_TTL_READPORT 1
+
+/*
+ * TTL INISIALISATION FUNCTION
+ */
+INT i_APCI1710_InsnConfigInitTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * TTL INPUT FUNCTION
+ */
+INT i_APCI1710_InsnBitsReadTTLIO(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1710_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
+ * TTL OUTPUT FUNCTIONS
+ */
+INT i_APCI1710_InsnWriteSetTTLIOChlOnOff(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
new file mode 100644
index 00000000000..b0907ec1466
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.c
@@ -0,0 +1,203 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : ADDI HEADER READ WRITER | Compiler : Visual C++ |
+ | Module name : S5920.cpp | Version : 6.0 |
+ +-------------------------------+---------------------------------------+
+ | Author : E. LIBS Date : 02/05/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : DLL with the S5920 PCI Controller functions |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 28/08/02 | LIBS Eric | Add return codes each time a function of the |
+ | | | Addi Library is called |
+ +-----------------------------------------------------------------------+
+ | 31/07/03 | KRAUTH J. | Changes for the MSX-Box |
+ +-----------------------------------------------------------------------+
+*/
+
+#include "addi_amcc_S5920.h"
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : INT i_AddiHeaderRW_ReadEeprom |*/
+/*| (INT i_NbOfWordsToRead, |*/
+/*| DWORD dw_PCIBoardEepromAddress, |*/
+/*| WORD w_EepromStartAddress, |*/
+/*| PWORD pw_DataRead) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read word from the 5920 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : INT i_NbOfWordsToRead : Nbr. of word to read |*/
+/*| DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
+/*| WORD w_EepromStartAddress : Eeprom strat address |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : PWORD pw_DataRead : Read data |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+ DWORD dw_PCIBoardEepromAddress,
+ WORD w_EepromStartAddress, PWORD pw_DataRead)
+{
+ DWORD dw_eeprom_busy = 0;
+ INT i_Counter = 0;
+ INT i_WordCounter;
+ INT i;
+ BYTE pb_ReadByte[1];
+ BYTE b_ReadLowByte = 0;
+ BYTE b_ReadHighByte = 0;
+ BYTE b_SelectedAddressLow = 0;
+ BYTE b_SelectedAddressHigh = 0;
+ WORD w_ReadWord = 0;
+
+ for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
+ i_WordCounter++) {
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ for (i_Counter = 0; i_Counter < 2; i_Counter++) {
+ b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; //Read the low 8 bit part
+ b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; //Read the high 8 bit part
+
+ //Select the load low address mode
+ outb(NVCMD_LOAD_LOW,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the low address
+ outb(b_SelectedAddressLow,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the load high address mode
+ outb(NVCMD_LOAD_HIGH,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the high address
+ outb(b_SelectedAddressHigh,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the READ mode
+ outb(NVCMD_BEGIN_READ,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Read data into the EEPROM
+ *pb_ReadByte =
+ inb(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR + 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the upper address part
+ if (i_Counter == 0) {
+ b_ReadLowByte = pb_ReadByte[0];
+ } else {
+ b_ReadHighByte = pb_ReadByte[0];
+ }
+
+ //Sleep
+ for (i = 0; i < 10000; i++) ;
+
+ }
+ w_ReadWord =
+ (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
+ 256));
+
+ pw_DataRead[i_WordCounter] = w_ReadWord;
+
+ w_EepromStartAddress += 2; // to read the next word
+
+ } // for (...) i_NbOfWordsToRead
+ return (0);
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h
new file mode 100644
index 00000000000..9ae56bc3ada
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_S5920.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define AMCC_OP_REG_MCSR 0x3c
+#define EEPROM_BUSY 0x80000000
+#define NVCMD_LOAD_LOW (0x4 << 5) /* nvRam load low command */
+#define NVCMD_LOAD_HIGH (0x5 << 5) /* nvRam load high command */
+#define NVCMD_BEGIN_READ (0x7 << 5) /* nvRam begin read command */
+#define NVCMD_BEGIN_WRITE (0x6 << 5) /* EEPROM begin write command */
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+ DWORD dw_PCIBoardEepromAddress,
+ WORD w_EepromStartAddress, PWORD pw_DataRead);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
new file mode 100644
index 00000000000..b50774cdcf7
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_amcc_s5933.h
@@ -0,0 +1,476 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/* Header file for AMCC s 5933 */
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include "../../comedidev.h"
+
+#include "../comedi_pci.h"
+
+#ifdef PCI_SUPPORT_VER1
+#error No support for 2.1.55 and older
+#endif
+
+/* written on base0 */
+#define FIFO_ADVANCE_ON_BYTE_2 0x20000000
+
+/* added for step 6 dma written on base2 */
+#define AMWEN_ENABLE 0x02
+
+#define A2P_FIFO_WRITE_ENABLE 0x01
+
+/* for transfer count enable bit */
+#define AGCSTS_TC_ENABLE 0x10000000
+
+/*
+ * ADDON RELATED ADDITIONS
+ */
+/* Constant */
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
+#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
+#define APCI3120_AMWEN_ENABLE 0x02
+#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
+#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
+#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
+#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
+#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
+#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
+
+/* ADD_ON ::: this needed since apci supports 16 bit interface to add on */
+#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
+#define APCI3120_ADD_ON_AGCSTS_HIGH (APCI3120_ADD_ON_AGCSTS_LOW + 2)
+#define APCI3120_ADD_ON_MWAR_LOW 0x24
+#define APCI3120_ADD_ON_MWAR_HIGH (APCI3120_ADD_ON_MWAR_LOW + 2)
+#define APCI3120_ADD_ON_MWTC_LOW 0x058
+#define APCI3120_ADD_ON_MWTC_HIGH (APCI3120_ADD_ON_MWTC_LOW + 2)
+
+/* AMCC */
+#define APCI3120_AMCC_OP_MCSR 0x3C
+#define APCI3120_AMCC_OP_REG_INTCSR 0x38
+
+/*
+ * AMCC Operation Register Offsets - PCI
+ */
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+/* INT source */
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2)
+/* FIFO ctrl */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3)
+#define AMCC_OP_REG_MCSR 0x3c
+/* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2)
+/* Command in byte 3 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3)
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof(u32))
+
+/*
+ * AMCC Operation Registers Size - PCI
+ */
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/*
+ * AMCC Operation Register Offsets - Add-on
+ */
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/*
+ * AMCC - Add-on General Control/Status Register
+ */
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/*
+ * AMCC - Add-on Interrupt Control/Status Register
+ */
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct {
+ struct pcilst_struct *next;
+ int used;
+ struct pci_dev *pcidev;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned char pci_bus;
+ unsigned char pci_slot;
+ unsigned char pci_func;
+ resource_size_t io_addr[5];
+ unsigned int irq;
+};
+
+/* ptr to root list of all amcc devices */
+struct pcilst_struct *amcc_devices;
+
+static const int i_ADDIDATADeviceID[] = { 0x15B8, 0x10E8 };
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short
+ device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ int i_Master);
+
+int pci_card_alloc(struct pcilst_struct *amcc, int master);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, resource_size_t * io_addr,
+ unsigned int *irq);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+ struct pci_dev *pcidev;
+ struct pcilst_struct *amcc, *last;
+ int i;
+ int i_Count = 0;
+ amcc_devices = NULL;
+ last = NULL;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ for (i_Count = 0; i_Count < 2; i_Count++) {
+ pci_vendor = i_ADDIDATADeviceID[i_Count];
+ if (pcidev->vendor == pci_vendor) {
+ amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+ memset(amcc, 0, sizeof(*amcc));
+
+ amcc->pcidev = pcidev;
+ if (last)
+ last->next = amcc;
+ else
+ amcc_devices = amcc;
+ last = amcc;
+
+ amcc->vendor = pcidev->vendor;
+ amcc->device = pcidev->device;
+ amcc->pci_bus = pcidev->bus->number;
+ amcc->pci_slot = PCI_SLOT(pcidev->devfn);
+ amcc->pci_func = PCI_FUNC(pcidev->devfn);
+ /* Note: resources may be invalid if PCI device
+ * not enabled, but they are corrected in
+ * pci_card_alloc. */
+ for (i = 0; i < 5; i++)
+ amcc->io_addr[i] =
+ pci_resource_start(pcidev, i);
+ amcc->irq = pcidev->irq;
+
+ }
+ }
+ }
+
+ if (display)
+ v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ kfree(amcc);
+ }
+
+ amcc_devices = NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short device_id)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((!amcc->used) && (amcc->device == device_id)
+ && (amcc->vendor == vendor_id))
+ return amcc;
+
+ }
+
+ return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card)
+{
+ struct pcilst_struct *amcc, *next;
+
+ *card = NULL;
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
+ && (amcc->pci_bus == pci_bus)
+ && (amcc->pci_slot == pci_slot)) {
+ if (!(amcc->used)) {
+ *card = amcc;
+ return 0; /* ok, card is found */
+ } else {
+ rt_printk(" - \nCard on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return 2; /* card exist but is used */
+ }
+ }
+ }
+
+ /* no card found */
+ return 1;
+}
+
+/****************************************************************************/
+/* mark card as used */
+int pci_card_alloc(struct pcilst_struct *amcc, int master)
+{
+ int i;
+
+ if (!amcc)
+ return -1;
+
+ if (amcc->used)
+ return 1;
+ if (comedi_pci_enable(amcc->pcidev, "addi_amcc_s5933"))
+ return -1;
+ /* Resources will be accurate now. */
+ for (i = 0; i < 5; i++)
+ amcc->io_addr[i] = pci_resource_start(amcc->pcidev, i);
+ if (master)
+ pci_set_master(amcc->pcidev);
+ amcc->used = 1;
+
+ return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+ if (!amcc)
+ return -1;
+
+ if (!amcc->used)
+ return 1;
+ amcc->used = 0;
+ comedi_pci_disable(amcc->pcidev);
+ return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+ struct pcilst_struct *amcc, *next;
+
+ printk(KERN_DEBUG "List of pci cards\n");
+ printk(KERN_DEBUG "bus:slot:func vendor device io_amcc io_daq irq used\n");
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ printk
+ ("%2d %2d %2d 0x%4x 0x%4x 0x%8llx 0x%8llx %2u %2d\n",
+ amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
+ amcc->vendor, amcc->device,
+ (unsigned long long)amcc->io_addr[0],
+ (unsigned long long)amcc->io_addr[2], amcc->irq,
+ amcc->used);
+
+ }
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, resource_size_t * io_addr,
+ unsigned int *irq)
+{
+ int i;
+
+ if (!amcc)
+ return -1;
+ *pci_bus = amcc->pci_bus;
+ *pci_slot = amcc->pci_slot;
+ *pci_func = amcc->pci_func;
+ for (i = 0; i < 5; i++)
+ io_addr[i] = amcc->io_addr[i];
+ *irq = amcc->irq;
+ return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ int i_Master)
+{
+ struct pcilst_struct *card;
+
+ if ((pci_bus < 1) & (pci_slot < 1)) {
+ /* use autodetection */
+ card = ptr_find_free_pci_card_by_device(vendor_id, device_id);
+ if (card == NULL) {
+ rt_printk(" - Unused card not found in system!\n");
+ return NULL;
+ }
+ } else {
+ switch (i_find_free_pci_card_by_position(vendor_id, device_id,
+ pci_bus, pci_slot,
+ &card)) {
+ case 1:
+ rt_printk(" - Card not found on requested position b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ case 2:
+ rt_printk(" - Card on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ }
+ }
+
+ if (pci_card_alloc(card, i_Master) != 0) {
+ rt_printk(" - Can't allocate card!\n");
+ return NULL;
+
+ }
+
+ return card;
+}
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c
new file mode 100644
index 00000000000..618c69b6838
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c
@@ -0,0 +1,3062 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_common.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Author : | Date : |
+ +-----------------------------------------------------------------------+
+ | Description : ADDI COMMON Main Module |
+ +-----------------------------------------------------------------------+
+ | CONFIG OPTIONS |
+ | option[0] - PCI bus number - if bus number and slot number are 0, |
+ | then driver search for first unused card |
+ | option[1] - PCI slot number |
+ | |
+ | option[2] = 0 - DMA ENABLE |
+ | = 1 - DMA DISABLE |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include "../../comedidev.h"
+#include <asm/io.h>
+#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
+#include <asm/i387.h>
+#endif
+#include "../comedi_fc.h"
+
+#include "addi_common.h"
+#include "addi_amcc_s5933.h"
+
+//Update-0.7.57->0.7.68MODULE_AUTHOR("ADDI-DATA GmbH <info@addi-data.com>");
+//Update-0.7.57->0.7.68MODULE_DESCRIPTION("Comedi ADDI-DATA module");
+//Update-0.7.57->0.7.68MODULE_LICENSE("GPL");
+
+#define devpriv ((addi_private *)dev->private)
+#define this_board ((boardtype *)dev->board_ptr)
+
+#if defined(CONFIG_APCI_1710) || defined(CONFIG_APCI_3200) || defined(CONFIG_APCI_3300)
+//BYTE b_SaveFPUReg [94];
+
+void fpu_begin(void)
+{
+ //asm ("fstenv b_SaveFPUReg");
+ kernel_fpu_begin();
+}
+
+void fpu_end(void)
+{
+ // asm ("frstor b_SaveFPUReg");
+ kernel_fpu_end();
+}
+#endif
+
+#include "addi_eeprom.c"
+#if (defined (CONFIG_APCI_3120) || defined (CONFIG_APCI_3001))
+#include "hwdrv_apci3120.c"
+#endif
+#ifdef CONFIG_APCI_1032
+#include "hwdrv_apci1032.c"
+#endif
+#ifdef CONFIG_APCI_1516
+#include "hwdrv_apci1516.c"
+#endif
+#ifdef CONFIG_APCI_2016
+#include "hwdrv_apci2016.c"
+#endif
+#ifdef CONFIG_APCI_2032
+#include "hwdrv_apci2032.c"
+#endif
+#ifdef CONFIG_APCI_2200
+#include "hwdrv_apci2200.c"
+#endif
+#ifdef CONFIG_APCI_1564
+#include "hwdrv_apci1564.c"
+#endif
+#ifdef CONFIG_APCI_1500
+#include "hwdrv_apci1500.c"
+#endif
+#ifdef CONFIG_APCI_3501
+#include "hwdrv_apci3501.c"
+#endif
+#ifdef CONFIG_APCI_035
+#include "hwdrv_apci035.c"
+#endif
+#if (defined (CONFIG_APCI_3200) || defined (CONFIG_APCI_3300))
+#include "hwdrv_apci3200.c"
+#endif
+#ifdef CONFIG_APCI_1710
+#include "hwdrv_APCI1710.c"
+#endif
+#ifdef CONFIG_APCI_16XX
+#include "hwdrv_apci16xx.c"
+#endif
+#ifdef CONFIG_APCI_3XXX
+#include "hwdrv_apci3xxx.c"
+#endif
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+static DEFINE_PCI_DEVICE_TABLE(addi_apci_tbl) = {
+#ifdef CONFIG_APCI_3120
+ {APCI3120_BOARD_VENDOR_ID, 0x818D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1032
+ {APCI1032_BOARD_VENDOR_ID, 0x1003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1516
+ {APCI1516_BOARD_VENDOR_ID, 0x1001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2016
+ {APCI2016_BOARD_VENDOR_ID, 0x1002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2032
+ {APCI2032_BOARD_VENDOR_ID, 0x1004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_2200
+ {APCI2200_BOARD_VENDOR_ID, 0x1005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1564
+ {APCI1564_BOARD_VENDOR_ID, 0x1006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1500
+ {APCI1500_BOARD_VENDOR_ID, 0x80fc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3001
+ {APCI3120_BOARD_VENDOR_ID, 0x828D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3501
+ {APCI3501_BOARD_VENDOR_ID, 0x3001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_035
+ {APCI035_BOARD_VENDOR_ID, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3200
+ {APCI3200_BOARD_VENDOR_ID, 0x3000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3300
+ {APCI3200_BOARD_VENDOR_ID, 0x3007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_1710
+ {APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_16XX
+ {0x15B8, 0x1009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x100A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+#ifdef CONFIG_APCI_3XXX
+ {0x15B8, 0x3010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x300F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x300E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3015, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3016, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3017, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3018, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x301F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x300B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3002, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0x15B8, 0x3024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+#endif
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, addi_apci_tbl);
+
+static const boardtype boardtypes[] = {
+#ifdef CONFIG_APCI_3120
+ {"apci3120",
+ APCI3120_BOARD_VENDOR_ID,
+ 0x818D,
+ AMCC_OP_REG_SIZE,
+ APCI3120_ADDRESS_RANGE,
+ 8,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 16,
+ 8,
+ 16,
+ 8,
+ 0xffff,
+ 0x3fff,
+ &range_apci3120_ai,
+ &range_apci3120_ao,
+ 4,
+ 4,
+ 0x0f,
+ 0,
+ NULL,
+ 1,
+ 1,
+ 1,
+ 10000,
+ 100000,
+ v_APCI3120_Interrupt,
+ i_APCI3120_Reset,
+ i_APCI3120_InsnConfigAnalogInput,
+ i_APCI3120_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ i_APCI3120_CommandTestAnalogInput,
+ i_APCI3120_CommandAnalogInput,
+ i_APCI3120_StopCyclicAcquisition,
+ NULL,
+ i_APCI3120_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3120_InsnReadDigitalInput,
+ NULL,
+ i_APCI3120_InsnBitsDigitalInput,
+ i_APCI3120_InsnConfigDigitalOutput,
+ i_APCI3120_InsnWriteDigitalOutput,
+ i_APCI3120_InsnBitsDigitalOutput,
+ NULL,
+ i_APCI3120_InsnConfigTimer,
+ i_APCI3120_InsnWriteTimer,
+ i_APCI3120_InsnReadTimer,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1032
+ {"apci1032",
+ APCI1032_BOARD_VENDOR_ID,
+ 0x1003,
+ 4,
+ APCI1032_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 32,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ v_APCI1032_Interrupt,
+ i_APCI1032_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1032_ConfigDigitalInput,
+ i_APCI1032_Read1DigitalInput,
+ NULL,
+ i_APCI1032_ReadMoreDigitalInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1516
+ {"apci1516",
+ APCI1516_BOARD_VENDOR_ID,
+ 0x1001,
+ 128,
+ APCI1516_ADDRESS_RANGE,
+ 32,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 8,
+ 8,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI1516_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1516_Read1DigitalInput,
+ NULL,
+ i_APCI1516_ReadMoreDigitalInput,
+ i_APCI1516_ConfigDigitalOutput,
+ i_APCI1516_WriteDigitalOutput,
+ i_APCI1516_ReadDigitalOutput,
+ NULL,
+ i_APCI1516_ConfigWatchdog,
+ i_APCI1516_StartStopWriteWatchdog,
+ i_APCI1516_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_2016
+ {"apci2016",
+ APCI2016_BOARD_VENDOR_ID,
+ 0x1002,
+ 128,
+ APCI2016_ADDRESS_RANGE,
+ 32,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 16,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI2016_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2016_ConfigDigitalOutput,
+ i_APCI2016_WriteDigitalOutput,
+ i_APCI2016_BitsDigitalOutput,
+ NULL,
+ i_APCI2016_ConfigWatchdog,
+ i_APCI2016_StartStopWriteWatchdog,
+ i_APCI2016_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_2032
+ {"apci2032",
+ APCI2032_BOARD_VENDOR_ID,
+ 0x1004,
+ 4,
+ APCI2032_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 32,
+ 0xffffffff,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI2032_Interrupt,
+ i_APCI2032_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2032_ConfigDigitalOutput,
+ i_APCI2032_WriteDigitalOutput,
+ i_APCI2032_ReadDigitalOutput,
+ i_APCI2032_ReadInterruptStatus,
+ i_APCI2032_ConfigWatchdog,
+ i_APCI2032_StartStopWriteWatchdog,
+ i_APCI2032_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_2200
+ {"apci2200",
+ APCI2200_BOARD_VENDOR_ID,
+ 0x1005,
+ 4,
+ APCI2200_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 8,
+ 16,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI2200_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI2200_Read1DigitalInput,
+ NULL,
+ i_APCI2200_ReadMoreDigitalInput,
+ i_APCI2200_ConfigDigitalOutput,
+ i_APCI2200_WriteDigitalOutput,
+ i_APCI2200_ReadDigitalOutput,
+ NULL,
+ i_APCI2200_ConfigWatchdog,
+ i_APCI2200_StartStopWriteWatchdog,
+ i_APCI2200_ReadWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1564
+ {"apci1564",
+ APCI1564_BOARD_VENDOR_ID,
+ 0x1006,
+ 128,
+ APCI1564_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_93C76,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 32,
+ 32,
+ 0xffffffff,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI1564_Interrupt,
+ i_APCI1564_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1564_ConfigDigitalInput,
+ i_APCI1564_Read1DigitalInput,
+ NULL,
+ i_APCI1564_ReadMoreDigitalInput,
+ i_APCI1564_ConfigDigitalOutput,
+ i_APCI1564_WriteDigitalOutput,
+ i_APCI1564_ReadDigitalOutput,
+ i_APCI1564_ReadInterruptStatus,
+ i_APCI1564_ConfigTimerCounterWatchdog,
+ i_APCI1564_StartStopWriteTimerCounterWatchdog,
+ i_APCI1564_ReadTimerCounterWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1500
+ {"apci1500",
+ APCI1500_BOARD_VENDOR_ID,
+ 0x80fc,
+ 128,
+ APCI1500_ADDRESS_RANGE,
+ 4,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 16,
+ 16,
+ 0xffff,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI1500_Interrupt,
+ i_APCI1500_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI1500_ConfigDigitalInputEvent,
+ i_APCI1500_Initialisation,
+ i_APCI1500_StartStopInputEvent,
+ i_APCI1500_ReadMoreDigitalInput,
+ i_APCI1500_ConfigDigitalOutputErrorInterrupt,
+ i_APCI1500_WriteDigitalOutput,
+ i_APCI1500_ConfigureInterrupt,
+ NULL,
+ i_APCI1500_ConfigCounterTimerWatchdog,
+ i_APCI1500_StartStopTriggerTimerCounterWatchdog,
+ i_APCI1500_ReadInterruptMask,
+ i_APCI1500_ReadCounterTimerWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3001
+ {"apci3001",
+ APCI3120_BOARD_VENDOR_ID,
+ 0x828D,
+ AMCC_OP_REG_SIZE,
+ APCI3120_ADDRESS_RANGE,
+ 8,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 16,
+ 8,
+ 16,
+ 0,
+ 0xfff,
+ 0,
+ &range_apci3120_ai,
+ NULL,
+ 4,
+ 4,
+ 0x0f,
+ 0,
+ NULL,
+ 1,
+ 1,
+ 1,
+ 10000,
+ 100000,
+ v_APCI3120_Interrupt,
+ i_APCI3120_Reset,
+ i_APCI3120_InsnConfigAnalogInput,
+ i_APCI3120_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ i_APCI3120_CommandTestAnalogInput,
+ i_APCI3120_CommandAnalogInput,
+ i_APCI3120_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3120_InsnReadDigitalInput,
+ NULL,
+ i_APCI3120_InsnBitsDigitalInput,
+ i_APCI3120_InsnConfigDigitalOutput,
+ i_APCI3120_InsnWriteDigitalOutput,
+ i_APCI3120_InsnBitsDigitalOutput,
+ NULL,
+ i_APCI3120_InsnConfigTimer,
+ i_APCI3120_InsnWriteTimer,
+ i_APCI3120_InsnReadTimer,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3501
+ {"apci3501",
+ APCI3501_BOARD_VENDOR_ID,
+ 0x3001,
+ 64,
+ APCI3501_ADDRESS_RANGE,
+ 0,
+ 0,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5933,
+ 0,
+ 0,
+ 0,
+ 8,
+ 0,
+ 16383,
+ NULL,
+ &range_apci3501_ao,
+ 2,
+ 2,
+ 0x3,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 0,
+ 0,
+ v_APCI3501_Interrupt,
+ i_APCI3501_Reset,
+ NULL, NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3501_ConfigAnalogOutput,
+ i_APCI3501_WriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3501_ReadDigitalInput,
+ i_APCI3501_ConfigDigitalOutput,
+ i_APCI3501_WriteDigitalOutput,
+ i_APCI3501_ReadDigitalOutput,
+ NULL,
+ i_APCI3501_ConfigTimerCounterWatchdog,
+ i_APCI3501_StartStopWriteTimerCounterWatchdog,
+ i_APCI3501_ReadTimerCounterWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_035
+ {"apci035",
+ APCI035_BOARD_VENDOR_ID,
+ 0x0300,
+ 127,
+ APCI035_ADDRESS_RANGE,
+ 0,
+ 0,
+ 1,
+ ADDIDATA_S5920,
+ 16,
+ 8,
+ 16,
+ 0,
+ 0xff,
+ 0,
+ &range_apci035_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 1,
+ 0,
+ 10000,
+ 100000,
+ v_APCI035_Interrupt,
+ i_APCI035_Reset,
+ i_APCI035_ConfigAnalogInput,
+ i_APCI035_ReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI035_ConfigTimerWatchdog,
+ i_APCI035_StartStopWriteTimerWatchdog,
+ i_APCI035_ReadTimerWatchdog,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3200
+ {"apci3200",
+ APCI3200_BOARD_VENDOR_ID,
+ 0x3000,
+ 128,
+ 256,
+ 4,
+ 4,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 16,
+ 8,
+ 16,
+ 0,
+ 0x3ffff,
+ 0,
+ &range_apci3200_ai,
+ NULL,
+ 4,
+ 4,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 10000,
+ 100000,
+ v_APCI3200_Interrupt,
+ i_APCI3200_Reset,
+ i_APCI3200_ConfigAnalogInput,
+ i_APCI3200_ReadAnalogInput,
+ i_APCI3200_InsnWriteReleaseAnalogInput,
+ i_APCI3200_InsnBits_AnalogInput_Test,
+ i_APCI3200_CommandTestAnalogInput,
+ i_APCI3200_CommandAnalogInput,
+ i_APCI3200_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3200_ReadDigitalInput,
+ i_APCI3200_ConfigDigitalOutput,
+ i_APCI3200_WriteDigitalOutput,
+ i_APCI3200_ReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_3300
+ //Begin JK 20.10.2004: APCI-3300 integration
+ {"apci3300",
+ APCI3200_BOARD_VENDOR_ID,
+ 0x3007,
+ 128,
+ 256,
+ 4,
+ 4,
+ ADDIDATA_EEPROM,
+ ADDIDATA_S5920,
+ 0,
+ 8,
+ 8,
+ 0,
+ 0x3ffff,
+ 0,
+ &range_apci3300_ai,
+ NULL,
+ 4,
+ 4,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 10000,
+ 100000,
+ v_APCI3200_Interrupt,
+ i_APCI3200_Reset,
+ i_APCI3200_ConfigAnalogInput,
+ i_APCI3200_ReadAnalogInput,
+ i_APCI3200_InsnWriteReleaseAnalogInput,
+ i_APCI3200_InsnBits_AnalogInput_Test,
+ i_APCI3200_CommandTestAnalogInput,
+ i_APCI3200_CommandAnalogInput,
+ i_APCI3200_StopCyclicAcquisition,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3200_ReadDigitalInput,
+ i_APCI3200_ConfigDigitalOutput,
+ i_APCI3200_WriteDigitalOutput,
+ i_APCI3200_ReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_1710
+ {"apci1710", APCI1710_BOARD_VENDOR_ID, APCI1710_BOARD_DEVICE_ID,
+ 128,
+ 8,
+ 256,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ v_APCI1710_Interrupt,
+ i_APCI1710_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+#endif
+#ifdef CONFIG_APCI_16XX
+ {"apci1648",
+ 0x15B8,
+ 0x1009,
+ 128,
+ 0,
+ 0,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 48,
+ &range_apci16xx_ttl,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI16XX_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI16XX_InsnConfigInitTTLIO,
+ i_APCI16XX_InsnBitsReadTTLIO,
+ i_APCI16XX_InsnReadTTLIOAllPortValue,
+ i_APCI16XX_InsnBitsWriteTTLIO},
+
+ {"apci1696",
+ 0x15B8,
+ 0x100A,
+ 128,
+ 0,
+ 0,
+ 0,
+ ADDIDATA_NO_EEPROM,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 96,
+ &range_apci16xx_ttl,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ NULL,
+ i_APCI16XX_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI16XX_InsnConfigInitTTLIO,
+ i_APCI16XX_InsnBitsReadTTLIO,
+ i_APCI16XX_InsnReadTTLIOAllPortValue,
+ i_APCI16XX_InsnBitsWriteTTLIO},
+#endif
+#ifdef CONFIG_APCI_3XXX
+ {"apci3000-16",
+ 0x15B8,
+ 0x3010,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3000-8",
+ 0x15B8,
+ 0x300F,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3000-4",
+ 0x15B8,
+ 0x300E,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3006-16",
+ 0x15B8,
+ 0x3013,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3006-8",
+ 0x15B8,
+ 0x3014,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3006-4",
+ 0x15B8,
+ 0x3015,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3010-16",
+ 0x15B8,
+ 0x3016,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3010-8",
+ 0x15B8,
+ 0x3017,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3010-4",
+ 0x15B8,
+ 0x3018,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 4095,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3016-16",
+ 0x15B8,
+ 0x3019,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3016-8",
+ 0x15B8,
+ 0x301A,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3016-4",
+ 0x15B8,
+ 0x301B,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 4,
+ 2,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3100-16-4",
+ 0x15B8,
+ 0x301C,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3100-8-4",
+ 0x15B8,
+ 0x301D,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3106-16-4",
+ 0x15B8,
+ 0x301E,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3106-8-4",
+ 0x15B8,
+ 0x301F,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 10000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3110-16-4",
+ 0x15B8,
+ 0x3020,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3110-8-4",
+ 0x15B8,
+ 0x3021,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 4095,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3116-16-4",
+ 0x15B8,
+ 0x3022,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 16,
+ 8,
+ 16,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3116-8-4",
+ 0x15B8,
+ 0x3023,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 8,
+ 4,
+ 8,
+ 4,
+ 65535,
+ 4095,
+ &range_apci3XXX_ai,
+ &range_apci3XXX_ao,
+ 4,
+ 4,
+ 1,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+
+ {"apci3003",
+ 0x15B8,
+ 0x300B,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 4,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 7,
+ 2500,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3002-16",
+ 0x15B8,
+ 0x3002,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 16,
+ 16,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3002-8",
+ 0x15B8,
+ 0x3003,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 8,
+ 8,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3002-4",
+ 0x15B8,
+ 0x3004,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 4,
+ 4,
+ 0,
+ 65535,
+ 0,
+ &range_apci3XXX_ai,
+ NULL,
+ 4,
+ 4,
+ 1,
+ 0,
+ NULL,
+ 0,
+ 0,
+ 6,
+ 5000,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ i_APCI3XXX_InsnConfigAnalogInput,
+ i_APCI3XXX_InsnReadAnalogInput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnReadDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnBitsDigitalInput,
+ NULL,
+ i_APCI3XXX_InsnWriteDigitalOutput,
+ i_APCI3XXX_InsnBitsDigitalOutput,
+ i_APCI3XXX_InsnReadDigitalOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL},
+
+ {"apci3500",
+ 0x15B8,
+ 0x3024,
+ 256,
+ 256,
+ 256,
+ 256,
+ ADDIDATA_NO_EEPROM,
+ ADDIDATA_9054,
+ 0,
+ 0,
+ 0,
+ 4,
+ 0,
+ 4095,
+ NULL,
+ &range_apci3XXX_ao,
+ 0,
+ 0,
+ 0,
+ 24,
+ &range_apci3XXX_ttl,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ v_APCI3XXX_Interrupt,
+ i_APCI3XXX_Reset,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnWriteAnalogOutput,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ i_APCI3XXX_InsnConfigInitTTLIO,
+ i_APCI3XXX_InsnBitsTTLIO,
+ i_APCI3XXX_InsnReadTTLIO,
+ i_APCI3XXX_InsnWriteTTLIO},
+#endif
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
+
+struct comedi_driver driver_addi = {
+ driver_name:"addi_common",
+ module:THIS_MODULE,
+ attach:i_ADDI_Attach,
+ detach:i_ADDI_Detach,
+ num_names:n_boardtypes,
+ board_name:&boardtypes[0].pc_DriverName,
+ offset:sizeof(boardtype),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_addi, addi_apci_tbl);
+
+/*
++----------------------------------------------------------------------------+
+| Function name :static int i_ADDI_Attach(struct comedi_device *dev, |
+| struct comedi_devconfig *it) |
+| |
++----------------------------------------------------------------------------+
+| Task :Detects the card. |
+| Configure the driver for a particular board. |
+| This function does all the initializations and memory |
+| allocation of data structures for the driver. |
++----------------------------------------------------------------------------+
+| Input Parameters :struct comedi_device *dev |
+| struct comedi_devconfig *it |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, pages, i, n_subdevices;
+ DWORD dw_Dummy;
+ resource_size_t io_addr[5];
+ unsigned int irq;
+ resource_size_t iobase_a, iobase_main, iobase_addon, iobase_reserved;
+ struct pcilst_struct *card = NULL;
+ unsigned char pci_bus, pci_slot, pci_func;
+ int i_Dma = 0;
+ static char c_Identifier[150];
+
+ sprintf(c_Identifier, "Addi-Data GmbH Comedi %s",
+ this_board->pc_DriverName);
+
+ if ((ret = alloc_private(dev, sizeof(addi_private))) < 0) {
+ return -ENOMEM;
+ }
+
+ if (!pci_list_builded) {
+ v_pci_card_list_init(this_board->i_VendorId, 1); //1 for displaying the list..
+ pci_list_builded = 1;
+ }
+ //rt_printk("comedi%d: addi_common: board=%s",dev->minor,this_board->pc_DriverName);
+
+ if ((this_board->i_Dma) && (it->options[2] == 0)) {
+ i_Dma = 1;
+ }
+
+ if ((card = ptr_select_and_alloc_pci_card(this_board->i_VendorId,
+ this_board->i_DeviceId,
+ it->options[0],
+ it->options[1], i_Dma)) == NULL) {
+ return -EIO;
+ }
+ devpriv->allocated = 1;
+
+ if ((i_pci_card_data(card, &pci_bus, &pci_slot, &pci_func, &io_addr[0],
+ &irq)) < 0) {
+ i_pci_card_free(card);
+ printk(" - Can't get AMCC data!\n");
+ return -EIO;
+ }
+
+ iobase_a = io_addr[0];
+ iobase_main = io_addr[1];
+ iobase_addon = io_addr[2];
+ iobase_reserved = io_addr[3];
+ printk("\nBus %d: Slot %d: Funct%d\nBase0: 0x%8llx\nBase1: 0x%8llx\nBase2: 0x%8llx\nBase3: 0x%8llx\n", pci_bus, pci_slot, pci_func, (unsigned long long)io_addr[0], (unsigned long long)io_addr[1], (unsigned long long)io_addr[2], (unsigned long long)io_addr[3]);
+
+ if ((this_board->pc_EepromChip == NULL)
+ || (strcmp(this_board->pc_EepromChip, ADDIDATA_9054) != 0)) {
+ /************************************/
+ /* Test if more that 1 address used */
+ /************************************/
+
+ if (this_board->i_IorangeBase1 != 0) {
+ dev->iobase = (unsigned long)iobase_main; // DAQ base address...
+ } else {
+ dev->iobase = (unsigned long)iobase_a; // DAQ base address...
+ }
+
+ dev->board_name = this_board->pc_DriverName;
+ devpriv->amcc = card;
+ devpriv->iobase = (INT) dev->iobase;
+ devpriv->i_IobaseAmcc = (INT) iobase_a; //AMCC base address...
+ devpriv->i_IobaseAddon = (INT) iobase_addon; //ADD ON base address....
+ devpriv->i_IobaseReserved = (INT) iobase_reserved;
+ devpriv->ps_BoardInfo = this_board;
+ } else {
+ dev->board_name = this_board->pc_DriverName;
+ dev->iobase = (unsigned long)io_addr[2];
+ devpriv->amcc = card;
+ devpriv->iobase = (INT) io_addr[2];
+ devpriv->ps_BoardInfo = this_board;
+ devpriv->i_IobaseReserved = (INT) io_addr[3];
+ printk("\nioremap begin");
+ devpriv->dw_AiBase =
+ (ULONG_PTR) ioremap(io_addr[3],
+ this_board->i_IorangeBase3);
+ printk("\nioremap end");
+ }
+
+ //##
+
+ if (irq > 0) {
+ if (comedi_request_irq(irq, v_ADDI_Interrupt, IRQF_SHARED,
+ c_Identifier, dev) < 0) {
+ printk(", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk("\nirq=%u", irq);
+ }
+ } else {
+ rt_printk(", IRQ disabled");
+ }
+
+ printk("\nOption %d %d %d\n", it->options[0], it->options[1],
+ it->options[2]);
+ dev->irq = irq;
+
+ // Read eepeom and fill boardtype Structure
+
+ if (this_board->i_PCIEeprom) {
+ printk("\nPCI Eeprom used");
+ if (!(strcmp(this_board->pc_EepromChip, "S5920"))) {
+ // Set 3 wait stait
+ if (!(strcmp(this_board->pc_DriverName, "apci035"))) {
+ outl(0x80808082, devpriv->i_IobaseAmcc + 0x60);
+ } else {
+ outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+ }
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+ printk("\nEnable the interrupt for the controler");
+ }
+ printk("\nRead Eeprom");
+ i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip,
+ dev);
+ } else {
+ printk("\nPCI Eeprom unused");
+ }
+
+ if (it->options[2] > 0) {
+ devpriv->us_UseDma = ADDI_DISABLE;
+ } else {
+ devpriv->us_UseDma = ADDI_ENABLE;
+ }
+
+ if (this_board->i_Dma) {
+ printk("\nDMA used");
+ if (devpriv->us_UseDma == ADDI_ENABLE) {
+ // alloc DMA buffers
+ devpriv->b_DmaDoubleBuffer = 0;
+ for (i = 0; i < 2; i++) {
+ for (pages = 4; pages >= 0; pages--) {
+ if ((devpriv->ul_DmaBufferVirtual[i] =
+ (void *)
+ __get_free_pages
+ (GFP_KERNEL, pages))) {
+ break;
+ }
+ }
+ if (devpriv->ul_DmaBufferVirtual[i]) {
+ devpriv->ui_DmaBufferPages[i] = pages;
+ devpriv->ui_DmaBufferSize[i] =
+ PAGE_SIZE * pages;
+ devpriv->ui_DmaBufferSamples[i] =
+ devpriv->
+ ui_DmaBufferSize[i] >> 1;
+ devpriv->ul_DmaBufferHw[i] =
+ virt_to_bus((void *)devpriv->
+ ul_DmaBufferVirtual[i]);
+ }
+ }
+ if (!devpriv->ul_DmaBufferVirtual[0]) {
+ rt_printk
+ (", Can't allocate DMA buffer, DMA disabled!");
+ devpriv->us_UseDma = ADDI_DISABLE;
+ }
+
+ if (devpriv->ul_DmaBufferVirtual[1]) {
+ devpriv->b_DmaDoubleBuffer = 1;
+ }
+ }
+
+ if ((devpriv->us_UseDma == ADDI_ENABLE)) {
+ rt_printk("\nDMA ENABLED\n");
+ } else {
+ printk("\nDMA DISABLED\n");
+ }
+ }
+
+ if (!strcmp(this_board->pc_DriverName, "apci1710")) {
+#ifdef CONFIG_APCI_1710
+ i_ADDI_AttachPCI1710(dev);
+
+ // save base address
+ devpriv->s_BoardInfos.ui_Address = io_addr[2];
+#endif
+ } else {
+ //Update-0.7.57->0.7.68dev->n_subdevices = 7;
+ n_subdevices = 7;
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ // Allocate and Initialise AI Subdevice Structures
+ s = dev->subdevices + 0;
+ if ((this_board->i_NbrAiChannel)
+ || (this_board->i_NbrAiChannelDiff)) {
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_RT | SDF_COMMON | SDF_GROUND
+ | SDF_DIFF;
+ if (this_board->i_NbrAiChannel) {
+ s->n_chan = this_board->i_NbrAiChannel;
+ devpriv->b_SingelDiff = 0;
+ } else {
+ s->n_chan = this_board->i_NbrAiChannelDiff;
+ devpriv->b_SingelDiff = 1;
+ }
+ s->maxdata = this_board->i_AiMaxdata;
+ s->len_chanlist = this_board->i_AiChannelList;
+ s->range_table = this_board->pr_AiRangelist;
+
+ /* Set the initialisation flag */
+ devpriv->b_AiInitialisation = 1;
+
+ s->insn_config =
+ this_board->i_hwdrv_InsnConfigAnalogInput;
+ s->insn_read = this_board->i_hwdrv_InsnReadAnalogInput;
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteAnalogInput;
+ s->insn_bits = this_board->i_hwdrv_InsnBitsAnalogInput;
+ s->do_cmdtest =
+ this_board->i_hwdrv_CommandTestAnalogInput;
+ s->do_cmd = this_board->i_hwdrv_CommandAnalogInput;
+ s->cancel = this_board->i_hwdrv_CancelAnalogInput;
+
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise AO Subdevice Structures
+ s = dev->subdevices + 1;
+ if (this_board->i_NbrAoChannel) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_GROUND | SDF_COMMON |
+ SDF_RT;
+ s->n_chan = this_board->i_NbrAoChannel;
+ s->maxdata = this_board->i_AoMaxdata;
+ s->len_chanlist = this_board->i_NbrAoChannel;
+ s->range_table = this_board->pr_AoRangelist;
+ s->insn_config =
+ this_board->i_hwdrv_InsnConfigAnalogOutput;
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteAnalogOutput;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ // Allocate and Initialise DI Subdevice Structures
+ s = dev->subdevices + 2;
+ if (this_board->i_NbrDiChannel) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrDiChannel;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->i_NbrDiChannel;
+ s->range_table = &range_digital;
+ s->io_bits = 0; /* all bits input */
+ s->insn_config =
+ this_board->i_hwdrv_InsnConfigDigitalInput;
+ s->insn_read = this_board->i_hwdrv_InsnReadDigitalInput;
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteDigitalInput;
+ s->insn_bits = this_board->i_hwdrv_InsnBitsDigitalInput;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ // Allocate and Initialise DO Subdevice Structures
+ s = dev->subdevices + 3;
+ if (this_board->i_NbrDoChannel) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITEABLE | SDF_RT |
+ SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrDoChannel;
+ s->maxdata = this_board->i_DoMaxdata;
+ s->len_chanlist = this_board->i_NbrDoChannel;
+ s->range_table = &range_digital;
+ s->io_bits = 0xf; /* all bits output */
+
+ s->insn_config = this_board->i_hwdrv_InsnConfigDigitalOutput; //for digital output memory..
+ s->insn_write =
+ this_board->i_hwdrv_InsnWriteDigitalOutput;
+ s->insn_bits =
+ this_board->i_hwdrv_InsnBitsDigitalOutput;
+ s->insn_read =
+ this_board->i_hwdrv_InsnReadDigitalOutput;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise Timer Subdevice Structures
+ s = dev->subdevices + 4;
+ if (this_board->i_Timer) {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_RT | SDF_GROUND |
+ SDF_COMMON;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ s->len_chanlist = 1;
+ s->range_table = &range_digital;
+
+ s->insn_write = this_board->i_hwdrv_InsnWriteTimer;
+ s->insn_read = this_board->i_hwdrv_InsnReadTimer;
+ s->insn_config = this_board->i_hwdrv_InsnConfigTimer;
+ s->insn_bits = this_board->i_hwdrv_InsnBitsTimer;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // Allocate and Initialise TTL
+ s = dev->subdevices + 5;
+ if (this_board->i_NbrTTLChannel) {
+ s->type = COMEDI_SUBD_TTLIO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT |
+ SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->i_NbrTTLChannel;
+ s->maxdata = 1;
+ s->io_bits = 0; /* all bits input */
+ s->len_chanlist = this_board->i_NbrTTLChannel;
+ s->range_table = &range_digital;
+ s->insn_config = this_board->i_hwdr_ConfigInitTTLIO;
+ s->insn_bits = this_board->i_hwdr_ReadTTLIOBits;
+ s->insn_read = this_board->i_hwdr_ReadTTLIOAllPortValue;
+ s->insn_write = this_board->i_hwdr_WriteTTLIOChlOnOff;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* EEPROM */
+ s = dev->subdevices + 6;
+ if (this_board->i_PCIEeprom) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 256;
+ s->maxdata = 0xffff;
+ s->insn_read = i_ADDIDATA_InsnReadEeprom;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ }
+
+ printk("\ni_ADDI_Attach end\n");
+ i_ADDI_Reset(dev);
+ devpriv->b_ValidDriver = 1;
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : static int i_ADDI_Detach(struct comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Deallocates resources of the addi_common driver |
+| Free the DMA buffers, unregister irq. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Detach(struct comedi_device * dev)
+{
+
+ if (dev->private) {
+ if (devpriv->b_ValidDriver) {
+ i_ADDI_Reset(dev);
+ }
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if ((devpriv->ps_BoardInfo->pc_EepromChip == NULL)
+ || (strcmp(devpriv->ps_BoardInfo->pc_EepromChip,
+ ADDIDATA_9054) != 0)) {
+ if (devpriv->allocated) {
+ i_pci_card_free(devpriv->amcc);
+ }
+
+ if (devpriv->ul_DmaBufferVirtual[0]) {
+ free_pages((unsigned long)devpriv->
+ ul_DmaBufferVirtual[0],
+ devpriv->ui_DmaBufferPages[0]);
+ }
+
+ if (devpriv->ul_DmaBufferVirtual[1]) {
+ free_pages((unsigned long)devpriv->
+ ul_DmaBufferVirtual[1],
+ devpriv->ui_DmaBufferPages[1]);
+ }
+ } else {
+ iounmap((void *)devpriv->dw_AiBase);
+
+ if (devpriv->allocated) {
+ i_pci_card_free(devpriv->amcc);
+ }
+ }
+
+ if (pci_list_builded) {
+ //v_pci_card_list_cleanup(PCI_VENDOR_ID_AMCC);
+ v_pci_card_list_cleanup(this_board->i_VendorId);
+ pci_list_builded = 0;
+ }
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : static int i_ADDI_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task : Disables all interrupts, Resets digital output to low, |
+| Set all analog output to low |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDI_Reset(struct comedi_device * dev)
+{
+
+ this_board->i_hwdrv_Reset(dev);
+ return 0;
+}
+
+// Interrupt function
+/*
++----------------------------------------------------------------------------+
+| Function name : |
+|static void v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG) |
+| |
++----------------------------------------------------------------------------+
+| Task : Registerd interrupt routine |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ this_board->v_hwdrv_Interrupt(irq, d);
+ return IRQ_RETVAL(1);
+}
+
+// EEPROM Read Function
+/*
++----------------------------------------------------------------------------+
+| Function name : |
+|INT i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data)
+| |
++----------------------------------------------------------------------------+
+| Task : Read 256 words from EEPROM |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters :(struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ WORD w_Data;
+ WORD w_Address;
+ w_Address = CR_CHAN(insn->chanspec); // address to be read as 0,1,2,3...255
+
+ w_Data = w_EepromReadWord(devpriv->i_IobaseAmcc,
+ this_board->pc_EepromChip, 0x100 + (2 * w_Address));
+ data[0] = w_Data;
+ //multiplied by 2 bcozinput will be like 0,1,2...255
+ return insn->n;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.h b/drivers/staging/comedi/drivers/addi-data/addi_common.h
new file mode 100644
index 00000000000..19df5c1444a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_common.h
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <linux/io.h>
+#include <linux/kmod.h>
+#include <linux/uaccess.h>
+#include "../../comedidev.h"
+#include "addi_amcc_s5933.h"
+
+#define ERROR -1
+#define SUCCESS 1
+
+/* variable type definition */
+typedef unsigned char BYTE, *PBYTE;
+typedef short SHORT, *PSHORT;
+typedef unsigned short USHORT, *PUSHORT;
+typedef unsigned short WORD, *PWORD;
+typedef int INT, *PINT;;
+typedef unsigned int UINT, *PUINT;
+typedef int LONG, *PLONG; /* 32-bit */
+typedef unsigned int ULONG, *PULONG; /* 32-bit */
+typedef unsigned int DWORD, *PDWORD; /* 32-bit */
+typedef unsigned long ULONG_PTR;
+
+typedef const struct comedi_lrange *PCRANGE;
+
+#define LOBYTE(W) (BYTE)((W) & 0xFF)
+#define HIBYTE(W) (BYTE)(((W) >> 8) & 0xFF)
+#define MAKEWORD(H, L) (USHORT)((L) | ((H) << 8))
+#define LOWORD(W) (USHORT)((W) & 0xFFFF)
+#define HIWORD(W) (USHORT)(((W) >> 16) & 0xFFFF)
+#define MAKEDWORD(H, L) (UINT)((L) | ((H) << 16))
+
+#define ADDI_ENABLE 1
+#define ADDI_DISABLE 0
+#define APCI1710_SAVE_INTERRUPT 1
+
+#define ADDIDATA_EEPROM 1
+#define ADDIDATA_NO_EEPROM 0
+#define ADDIDATA_93C76 "93C76"
+#define ADDIDATA_S5920 "S5920"
+#define ADDIDATA_S5933 "S5933"
+#define ADDIDATA_9054 "9054"
+
+/* ADDIDATA Enable Disable */
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+/* Structures */
+
+/* structure for the boardtype */
+typedef struct {
+ const char *pc_DriverName; // driver name
+ INT i_VendorId; //PCI vendor a device ID of card
+ INT i_DeviceId;
+ INT i_IorangeBase0;
+ INT i_IorangeBase1;
+ INT i_IorangeBase2; // base 2 range
+ INT i_IorangeBase3; // base 3 range
+ INT i_PCIEeprom; // eeprom present or not
+ char *pc_EepromChip; // type of chip
+ INT i_NbrAiChannel; // num of A/D chans
+ INT i_NbrAiChannelDiff; // num of A/D chans in diff mode
+ INT i_AiChannelList; // len of chanlist
+ INT i_NbrAoChannel; // num of D/A chans
+ INT i_AiMaxdata; // resolution of A/D
+ INT i_AoMaxdata; // resolution of D/A
+ PCRANGE pr_AiRangelist; // rangelist for A/D
+ PCRANGE pr_AoRangelist; // rangelist for D/A
+
+ INT i_NbrDiChannel; // Number of DI channels
+ INT i_NbrDoChannel; // Number of DO channels
+ INT i_DoMaxdata; // data to set all chanels high
+
+ INT i_NbrTTLChannel; // Number of TTL channels
+ PCRANGE pr_TTLRangelist; // rangelist for TTL
+
+ INT i_Dma; // dma present or not
+ INT i_Timer; // timer subdevice present or not
+ BYTE b_AvailableConvertUnit;
+ UINT ui_MinAcquisitiontimeNs; // Minimum Acquisition in Nano secs
+ UINT ui_MinDelaytimeNs; // Minimum Delay in Nano secs
+
+ /* interrupt and reset */
+ void (*v_hwdrv_Interrupt)(int irq, void *d);
+ int (*i_hwdrv_Reset)(struct comedi_device *dev);
+
+ /* Subdevice functions */
+
+ /* ANALOG INPUT */
+ int (*i_hwdrv_InsnConfigAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_CommandTestAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+ int (*i_hwdrv_CommandAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s);
+ int (*i_hwdrv_CancelAnalogInput)(struct comedi_device *dev,
+ struct comedi_subdevice *s);
+
+ /* Analog Output */
+ int (*i_hwdrv_InsnConfigAnalogOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteAnalogOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsAnalogOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+ /* Digital Input */
+ int (*i_hwdrv_InsnConfigDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsDigitalInput) (struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+ /* Digital Output */
+ int (*i_hwdrv_InsnConfigDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnWriteDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnBitsDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadDigitalOutput)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+ /* TIMER */
+ int (*i_hwdrv_InsnConfigTimer)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+ int (*i_hwdrv_InsnWriteTimer)(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdrv_InsnReadTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+ int (*i_hwdrv_InsnBitsTimer)(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+ /* TTL IO */
+ int (*i_hwdr_ConfigInitTTLIO)(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdr_ReadTTLIOBits)(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+ int (*i_hwdr_ReadTTLIOAllPortValue)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+ int (*i_hwdr_WriteTTLIOChlOnOff)(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+} boardtype;
+
+//MODULE INFO STRUCTURE
+
+typedef union {
+ /* Incremental counter infos */
+ struct {
+ union {
+ struct {
+ BYTE b_ModeRegister1;
+ BYTE b_ModeRegister2;
+ BYTE b_ModeRegister3;
+ BYTE b_ModeRegister4;
+ } s_ByteModeRegister;
+ DWORD dw_ModeRegister1_2_3_4;
+ } s_ModeRegister;
+
+ struct {
+ unsigned int b_IndexInit:1;
+ unsigned int b_CounterInit:1;
+ unsigned int b_ReferenceInit:1;
+ unsigned int b_IndexInterruptOccur:1;
+ unsigned int b_CompareLogicInit:1;
+ unsigned int b_FrequencyMeasurementInit:1;
+ unsigned int b_FrequencyMeasurementEnable:1;
+ } s_InitFlag;
+
+ } s_SiemensCounterInfo;
+
+ /* SSI infos */
+ struct {
+ BYTE b_SSIProfile;
+ BYTE b_PositionTurnLength;
+ BYTE b_TurnCptLength;
+ BYTE b_SSIInit;
+ } s_SSICounterInfo;
+
+ /* TTL I/O infos */
+ struct {
+ BYTE b_TTLInit;
+ BYTE b_PortConfiguration[4];
+ } s_TTLIOInfo;
+
+ /* Digital I/O infos */
+ struct {
+ BYTE b_DigitalInit;
+ BYTE b_ChannelAMode;
+ BYTE b_ChannelBMode;
+ BYTE b_OutputMemoryEnabled;
+ DWORD dw_OutputMemory;
+ } s_DigitalIOInfo;
+
+ /*********************/
+ /* 82X54 timer infos */
+ /*********************/
+
+ struct {
+ struct {
+ BYTE b_82X54Init;
+ BYTE b_InputClockSelection;
+ BYTE b_InputClockLevel;
+ BYTE b_OutputLevel;
+ BYTE b_HardwareGateLevel;
+ DWORD dw_ConfigurationWord;
+ } s_82X54TimerInfo[3];
+ BYTE b_InterruptMask;
+ } s_82X54ModuleInfo;
+
+ /*********************/
+ /* Chronometer infos */
+ /*********************/
+
+ struct {
+ BYTE b_ChronoInit;
+ BYTE b_InterruptMask;
+ BYTE b_PCIInputClock;
+ BYTE b_TimingUnit;
+ BYTE b_CycleMode;
+ double d_TimingInterval;
+ DWORD dw_ConfigReg;
+ } s_ChronoModuleInfo;
+
+ /***********************/
+ /* Pulse encoder infos */
+ /***********************/
+
+ struct {
+ struct {
+ BYTE b_PulseEncoderInit;
+ } s_PulseEncoderInfo[4];
+ DWORD dw_SetRegister;
+ DWORD dw_ControlRegister;
+ DWORD dw_StatusRegister;
+ } s_PulseEncoderModuleInfo;
+
+ /* Tor conter infos */
+ struct {
+ struct {
+ BYTE b_TorCounterInit;
+ BYTE b_TimingUnit;
+ BYTE b_InterruptEnable;
+ double d_TimingInterval;
+ ULONG ul_RealTimingInterval;
+ } s_TorCounterInfo[2];
+ BYTE b_PCIInputClock;
+ } s_TorCounterModuleInfo;
+
+ /* PWM infos */
+ struct {
+ struct {
+ BYTE b_PWMInit;
+ BYTE b_TimingUnit;
+ BYTE b_InterruptEnable;
+ double d_LowTiming;
+ double d_HighTiming;
+ ULONG ul_RealLowTiming;
+ ULONG ul_RealHighTiming;
+ } s_PWMInfo[2];
+ BYTE b_ClockSelection;
+ } s_PWMModuleInfo;
+
+ /* ETM infos */
+ struct {
+ struct {
+ BYTE b_ETMEnable;
+ BYTE b_ETMInterrupt;
+ } s_ETMInfo[2];
+ BYTE b_ETMInit;
+ BYTE b_TimingUnit;
+ BYTE b_ClockSelection;
+ double d_TimingInterval;
+ ULONG ul_Timing;
+ } s_ETMModuleInfo;
+
+ /* CDA infos */
+ struct {
+ BYTE b_CDAEnable;
+ BYTE b_CDAInterrupt;
+ BYTE b_CDAInit;
+ BYTE b_FctSelection;
+ BYTE b_CDAReadFIFOOverflow;
+ } s_CDAModuleInfo;
+
+} str_ModuleInfo;
+
+/* Private structure for the addi_apci3120 driver */
+typedef struct {
+
+ INT iobase;
+ INT i_IobaseAmcc; // base+size for AMCC chip
+ INT i_IobaseAddon; //addon base address
+ INT i_IobaseReserved;
+ ULONG_PTR dw_AiBase;
+ struct pcilst_struct *amcc; // ptr too AMCC data
+ BYTE allocated; // we have blocked card
+ BYTE b_ValidDriver; // driver is ok
+ BYTE b_AiContinuous; // we do unlimited AI
+ BYTE b_AiInitialisation;
+ UINT ui_AiActualScan; //how many scans we finished
+ UINT ui_AiBufferPtr; // data buffer ptr in samples
+ UINT ui_AiNbrofChannels; // how many channels is measured
+ UINT ui_AiScanLength; // Length of actual scanlist
+ UINT ui_AiActualScanPosition; // position in actual scan
+ PUINT pui_AiChannelList; // actual chanlist
+ UINT ui_AiChannelList[32]; // actual chanlist
+ BYTE b_AiChannelConfiguration[32]; // actual chanlist
+ UINT ui_AiReadData[32];
+ DWORD dw_AiInitialised;
+ UINT ui_AiTimer0; //Timer Constant for Timer0
+ UINT ui_AiTimer1; //Timer constant for Timer1
+ UINT ui_AiFlags;
+ UINT ui_AiDataLength;
+ short *AiData; // Pointer to sample data
+ UINT ui_AiNbrofScans; // number of scans to do
+ USHORT us_UseDma; // To use Dma or not
+ BYTE b_DmaDoubleBuffer; // we can use double buffering
+ UINT ui_DmaActualBuffer; // which buffer is used now
+ //*UPDATE-0.7.57->0.7.68
+ //ULONG ul_DmaBufferVirtual[2];// pointers to begin of DMA buffer
+ short *ul_DmaBufferVirtual[2]; // pointers to begin of DMA buffer
+ ULONG ul_DmaBufferHw[2]; // hw address of DMA buff
+ UINT ui_DmaBufferSize[2]; // size of dma buffer in bytes
+ UINT ui_DmaBufferUsesize[2]; // which size we may now used for transfer
+ UINT ui_DmaBufferSamples[2]; // size in samples
+ UINT ui_DmaBufferPages[2]; // number of pages in buffer
+ BYTE b_DigitalOutputRegister; // Digital Output Register
+ BYTE b_OutputMemoryStatus;
+ BYTE b_AnalogInputChannelNbr; // Analog input channel Nbr
+ BYTE b_AnalogOutputChannelNbr; // Analog input Output Nbr
+ BYTE b_TimerSelectMode; // Contain data written at iobase + 0C
+ BYTE b_ModeSelectRegister; // Contain data written at iobase + 0E
+ USHORT us_OutputRegister; // Contain data written at iobase + 0
+ BYTE b_InterruptState;
+ BYTE b_TimerInit; // Specify if InitTimerWatchdog was load
+ BYTE b_TimerStarted; // Specify if timer 2 is running or not
+ BYTE b_Timer2Mode; // Specify the timer 2 mode
+ BYTE b_Timer2Interrupt; //Timer2 interrupt enable or disable
+ BYTE b_AiCyclicAcquisition; // indicate cyclic acquisition
+ BYTE b_InterruptMode; // eoc eos or dma
+ BYTE b_EocEosInterrupt; // Enable disable eoc eos interrupt
+ UINT ui_EocEosConversionTime;
+ BYTE b_EocEosConversionTimeBase;
+ BYTE b_SingelDiff;
+ BYTE b_ExttrigEnable; /* To enable or disable external trigger */
+
+ /* Pointer to the current process */
+ struct task_struct *tsk_Current;
+ boardtype *ps_BoardInfo;
+
+ /* Hardware board infos for 1710 */
+ struct {
+ UINT ui_Address; /* Board address */
+ UINT ui_FlashAddress;
+ BYTE b_InterruptNbr; /* Board interrupt number */
+ BYTE b_SlotNumber; /* PCI slot number */
+ BYTE b_BoardVersion;
+ DWORD dw_MolduleConfiguration[4]; /* Module config */
+ } s_BoardInfos;
+
+ /* Interrupt infos */
+ struct {
+ ULONG ul_InterruptOccur; /* 0 : No interrupt occur */
+ /* > 0 : Interrupt occur */
+ UINT ui_Read; /* Read FIFO */
+ UINT ui_Write; /* Write FIFO */
+ struct {
+ BYTE b_OldModuleMask;
+ ULONG ul_OldInterruptMask; /* Interrupt mask */
+ ULONG ul_OldCounterLatchValue; /* Interrupt counter value */
+ } s_FIFOInterruptParameters[APCI1710_SAVE_INTERRUPT];
+ } s_InterruptParameters;
+
+ str_ModuleInfo s_ModuleInfo[4];
+ ULONG ul_TTLPortConfiguration[10];
+
+} addi_private;
+
+static unsigned short pci_list_builded; /* set to 1 when list of card is known */
+
+/* Function declarations */
+static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int i_ADDI_Detach(struct comedi_device *dev);
+static int i_ADDI_Reset(struct comedi_device *dev);
+
+static irqreturn_t v_ADDI_Interrupt(int irq, void *d PT_REGS_ARG);
+static int i_ADDIDATA_InsnReadEeprom(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
new file mode 100644
index 00000000000..a8a1bb2e8fa
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/addi_eeprom.c
@@ -0,0 +1,1158 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : ADDI DATA | Compiler : GCC |
+ | Modulname : addi_eeprom.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description : ADDI EEPROM Module |
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#define NVCMD_BEGIN_READ (0x7 << 5 ) // nvRam begin read command
+#define NVCMD_LOAD_LOW (0x4 << 5 ) // nvRam load low command
+#define NVCMD_LOAD_HIGH (0x5 << 5 ) // nvRam load high command
+#define EE76_CMD_LEN 13 // bits in instructions
+#define EE_READ 0x0180 // 01 1000 0000 read instruction
+
+#define WORD unsigned short
+#define PWORD unsigned short *
+#define PDWORD unsigned int *
+
+#ifndef DWORD
+#define DWORD unsigned int
+#endif
+
+#define EEPROM_DIGITALINPUT 0
+#define EEPROM_DIGITALOUTPUT 1
+#define EEPROM_ANALOGINPUT 2
+#define EEPROM_ANALOGOUTPUT 3
+#define EEPROM_TIMER 4
+#define EEPROM_WATCHDOG 5
+#define EEPROM_TIMER_WATCHDOG_COUNTER 10
+
+struct str_Functionality {
+ BYTE b_Type;
+ WORD w_Address;
+};
+
+typedef struct {
+ WORD w_HeaderSize;
+ BYTE b_Nfunctions;
+ struct str_Functionality s_Functions[7];
+} str_MainHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+ BYTE b_Interruptible;
+ WORD w_NinterruptLogic;
+} str_DigitalInputHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+} str_DigitalOutputHeader;
+
+// used for timer as well as watchdog
+
+typedef struct {
+ WORD w_HeaderSize;
+ BYTE b_Resolution;
+ BYTE b_Mode; // in case of Watchdog it is functionality
+ WORD w_MinTiming;
+ BYTE b_TimeBase;
+} str_TimerDetails;
+typedef struct {
+
+ WORD w_Ntimer;
+ str_TimerDetails s_TimerDetails[4]; // supports 4 timers
+} str_TimerMainHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+ BYTE b_Resolution;
+} str_AnalogOutputHeader;
+
+typedef struct {
+ WORD w_Nchannel;
+ WORD w_MinConvertTiming;
+ WORD w_MinDelayTiming;
+ BYTE b_HasDma;
+ BYTE b_Resolution;
+} str_AnalogInputHeader;
+
+ /*****************************************/
+ /* Read Header Functions */
+ /*****************************************/
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, struct comedi_device *dev);
+
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalInputHeader * s_Header);
+
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalOutputHeader * s_Header);
+
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_TimerMainHeader * s_Header);
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogOutputHeader * s_Header);
+
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogInputHeader * s_Header);
+
+ /******************************************/
+ /* Eeprom Specific Functions */
+ /******************************************/
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
+ WORD w_EepromStartAddress);
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+void v_EepromClock76(DWORD dw_Address, DWORD dw_RegisterValue);
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress);
+void v_EepromSendCommand76(DWORD dw_Address, DWORD dw_EepromCommand,
+ BYTE b_DataLengthInBits);
+void v_EepromCs76Read(DWORD dw_Address, WORD w_offset, PWORD pw_Value);
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : WORD w_EepromReadWord |
+| (WORD w_PCIBoardEepromAddress, |
+| char * pc_PCIChipInformation, |
+| WORD w_EepromStartAddress) |
++----------------------------------------------------------------------------+
+| Task : Read from eepromn a word |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| WORD w_EepromStartAddress : Selected eeprom address |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : Read word value from eeprom |
++----------------------------------------------------------------------------+
+*/
+
+WORD w_EepromReadWord(WORD w_PCIBoardEepromAddress, char *pc_PCIChipInformation,
+ WORD w_EepromStartAddress)
+{
+
+ BYTE b_Counter = 0;
+
+ BYTE b_ReadByte = 0;
+
+ BYTE b_ReadLowByte = 0;
+
+ BYTE b_ReadHighByte = 0;
+
+ BYTE b_SelectedAddressLow = 0;
+
+ BYTE b_SelectedAddressHigh = 0;
+
+ WORD w_ReadWord = 0;
+
+ /**************************/
+
+ /* Test the PCI chip type */
+
+ /**************************/
+
+ if ((!strcmp(pc_PCIChipInformation, "S5920")) ||
+ (!strcmp(pc_PCIChipInformation, "S5933")))
+ {
+
+ for (b_Counter = 0; b_Counter < 2; b_Counter++)
+ {
+
+ b_SelectedAddressLow = (w_EepromStartAddress + b_Counter) % 256; //Read the low 8 bit part
+
+ b_SelectedAddressHigh = (w_EepromStartAddress + b_Counter) / 256; //Read the high 8 bit part
+
+ /************************************/
+
+ /* Select the load low address mode */
+
+ /************************************/
+
+ outb(NVCMD_LOAD_LOW, w_PCIBoardEepromAddress + 0x3F);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /************************/
+
+ /* Load the low address */
+
+ /************************/
+
+ outb(b_SelectedAddressLow,
+ w_PCIBoardEepromAddress + 0x3E);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*************************************/
+
+ /* Select the load high address mode */
+
+ /*************************************/
+
+ outb(NVCMD_LOAD_HIGH, w_PCIBoardEepromAddress + 0x3F);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*************************/
+
+ /* Load the high address */
+
+ /*************************/
+
+ outb(b_SelectedAddressHigh,
+ w_PCIBoardEepromAddress + 0x3E);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /************************/
+
+ /* Select the READ mode */
+
+ /************************/
+
+ outb(NVCMD_BEGIN_READ, w_PCIBoardEepromAddress + 0x3F);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*****************************/
+
+ /* Read data into the EEPROM */
+
+ /*****************************/
+
+ b_ReadByte = inb(w_PCIBoardEepromAddress + 0x3E);
+
+ /****************/
+
+ /* Wait on busy */
+
+ /****************/
+
+ v_EepromWaitBusy(w_PCIBoardEepromAddress);
+
+ /*********************************/
+
+ /* Select the upper address part */
+
+ /*********************************/
+
+ if (b_Counter == 0)
+ {
+
+ b_ReadLowByte = b_ReadByte;
+
+ } // if(b_Counter==0)
+
+ else
+ {
+
+ b_ReadHighByte = b_ReadByte;
+
+ } // if(b_Counter==0)
+
+ } // for (b_Counter=0; b_Counter<2; b_Counter++)
+
+ w_ReadWord = (b_ReadLowByte | (((WORD) b_ReadHighByte) * 256));
+
+ } // end of if ((!strcmp(pc_PCIChipInformation, "S5920")) || (!strcmp(pc_PCIChipInformation, "S5933")))
+
+ if (!strcmp(pc_PCIChipInformation, "93C76"))
+ {
+
+ /*************************************/
+
+ /* Read 16 bit from the EEPROM 93C76 */
+
+ /*************************************/
+
+ v_EepromCs76Read(w_PCIBoardEepromAddress, w_EepromStartAddress,
+ &w_ReadWord);
+
+ }
+
+ return (w_ReadWord);
+
+}
+
+/*
+
++----------------------------------------------------------------------------+
+
+| Function Name : void v_EepromWaitBusy |
+
+| (WORD w_PCIBoardEepromAddress) |
+
++----------------------------------------------------------------------------+
+
+| Task : Wait the busy flag from PCI controller |
+
++----------------------------------------------------------------------------+
+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom base address |
+
++----------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++----------------------------------------------------------------------------+
+
+| Return Value : - |
+
++----------------------------------------------------------------------------+
+
+*/
+
+void v_EepromWaitBusy(WORD w_PCIBoardEepromAddress)
+{
+
+ BYTE b_EepromBusy = 0;
+
+ do
+ {
+
+ /*************/
+
+ /* IMPORTANT */
+
+ /*************/
+
+ /************************************************************************/
+
+ /* An error has been written in the AMCC 5933 book at the page B-13 */
+
+ /* Ex: if you read a byte and look for the busy statusEEPROM=0x80 and */
+
+ /* the operator register is AMCC_OP_REG_MCSR+3 */
+
+ /* WORD read EEPROM=0x8000 andAMCC_OP_REG_MCSR+2 */
+
+ /* DWORD read EEPROM=0x80000000 and AMCC_OP_REG_MCSR */
+
+ /************************************************************************/
+
+ b_EepromBusy = inb(w_PCIBoardEepromAddress + 0x3F);
+ b_EepromBusy = b_EepromBusy & 0x80;
+
+ }
+ while (b_EepromBusy == 0x80);
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function Name : void v_EepromClock76(DWORD dw_Address, |
+
+| DWORD dw_RegisterValue) |
+
++---------------------------------------------------------------------------------+
+
+| Task : This function sends the clocking sequence to the EEPROM. |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |
+
+| DWORD dw_RegisterValue : PCI eeprom register value to write.|
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++---------------------------------------------------------------------------------+
+
+| Return Value : - |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromClock76(DWORD dw_Address, DWORD dw_RegisterValue)
+{
+
+ /************************/
+
+ /* Set EEPROM clock Low */
+
+ /************************/
+
+ outl(dw_RegisterValue & 0x6, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /*************************/
+
+ /* Set EEPROM clock High */
+
+ /*************************/
+
+ outl(dw_RegisterValue | 0x1, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function Name : void v_EepromSendCommand76(DWORD dw_Address, |
+
+| DWORD dw_EepromCommand, |
+
+| BYTE b_DataLengthInBits) |
+
++---------------------------------------------------------------------------------+
+
+| Task : This function sends a Command to the EEPROM 93C76. |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |
+
+| DWORD dw_EepromCommand : PCI eeprom command to write. |
+
+| BYTE b_DataLengthInBits : PCI eeprom command data length. |
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++---------------------------------------------------------------------------------+
+
+| Return Value : - |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromSendCommand76(DWORD dw_Address, DWORD dw_EepromCommand,
+ BYTE b_DataLengthInBits)
+{
+
+ char c_BitPos = 0;
+
+ DWORD dw_RegisterValue = 0;
+
+ /*****************************/
+
+ /* Enable EEPROM Chip Select */
+
+ /*****************************/
+
+ dw_RegisterValue = 0x2;
+
+ /********************************************************************/
+
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+
+ /********************************************************************/
+
+ outl(dw_RegisterValue, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /*******************************************/
+
+ /* Send EEPROM command - one bit at a time */
+
+ /*******************************************/
+
+ for (c_BitPos = (b_DataLengthInBits - 1); c_BitPos >= 0; c_BitPos--)
+ {
+
+ /**********************************/
+
+ /* Check if current bit is 0 or 1 */
+
+ /**********************************/
+
+ if (dw_EepromCommand & (1 << c_BitPos))
+ {
+
+ /***********/
+
+ /* Write 1 */
+
+ /***********/
+
+ dw_RegisterValue = dw_RegisterValue | 0x4;
+
+ }
+
+ else
+ {
+
+ /***********/
+
+ /* Write 0 */
+
+ /***********/
+
+ dw_RegisterValue = dw_RegisterValue & 0x3;
+
+ }
+
+ /*********************/
+
+ /* Write the command */
+
+ /*********************/
+
+ outl(dw_RegisterValue, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /****************************/
+
+ /* Trigger the EEPROM clock */
+
+ /****************************/
+
+ v_EepromClock76(dw_Address, dw_RegisterValue);
+
+ }
+
+}
+
+/*
+
++---------------------------------------------------------------------------------+
+
+| Function Name : void v_EepromCs76Read(DWORD dw_Address, |
+
+| WORD w_offset, |
+
+| PWORD pw_Value) |
+
++---------------------------------------------------------------------------------+
+
+| Task : This function read a value from the EEPROM 93C76. |
+
++---------------------------------------------------------------------------------+
+
+| Input Parameters : DWORD dw_Address : PCI eeprom base address |
+
+| WORD w_offset : Offset of the adress to read |
+
+| PWORD pw_Value : PCI eeprom 16 bit read value. |
+
++---------------------------------------------------------------------------------+
+
+| Output Parameters : - |
+
++---------------------------------------------------------------------------------+
+
+| Return Value : - |
+
++---------------------------------------------------------------------------------+
+
+*/
+
+void v_EepromCs76Read(DWORD dw_Address, WORD w_offset, PWORD pw_Value)
+{
+
+ char c_BitPos = 0;
+
+ DWORD dw_RegisterValue = 0;
+
+ DWORD dw_RegisterValueRead = 0;
+
+ /*************************************************/
+
+ /* Send EEPROM read command and offset to EEPROM */
+
+ /*************************************************/
+
+ v_EepromSendCommand76(dw_Address, (EE_READ << 4) | (w_offset / 2),
+ EE76_CMD_LEN);
+
+ /*******************************/
+
+ /* Get the last register value */
+
+ /*******************************/
+
+ dw_RegisterValue = (((w_offset / 2) & 0x1) << 2) | 0x2;
+
+ /*****************************/
+
+ /* Set the 16-bit value of 0 */
+
+ /*****************************/
+
+ *pw_Value = 0;
+
+ /************************/
+
+ /* Get the 16-bit value */
+
+ /************************/
+
+ for (c_BitPos = 0; c_BitPos < 16; c_BitPos++)
+ {
+
+ /****************************/
+
+ /* Trigger the EEPROM clock */
+
+ /****************************/
+
+ v_EepromClock76(dw_Address, dw_RegisterValue);
+
+ /**********************/
+
+ /* Get the result bit */
+
+ /**********************/
+
+ dw_RegisterValueRead = inl(dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+ /***************************************/
+
+ /* Get bit value and shift into result */
+
+ /***************************************/
+
+ if (dw_RegisterValueRead & 0x8)
+ {
+
+ /**********/
+
+ /* Read 1 */
+
+ /**********/
+
+ *pw_Value = (*pw_Value << 1) | 0x1;
+
+ }
+
+ else
+ {
+
+ /**********/
+
+ /* Read 0 */
+
+ /**********/
+
+ *pw_Value = (*pw_Value << 1);
+
+ }
+
+ }
+
+ /*************************/
+
+ /* Clear all EEPROM bits */
+
+ /*************************/
+
+ dw_RegisterValue = 0x0;
+
+ /********************************************************************/
+
+ /* Toggle EEPROM's Chip select to get it out of Shift Register Mode */
+
+ /********************************************************************/
+
+ outl(dw_RegisterValue, dw_Address);
+
+ /***************/
+
+ /* Wait 0.1 ms */
+
+ /***************/
+
+ udelay(100);
+
+}
+
+ /******************************************/
+ /* EEPROM HEADER READ FUNCTIONS */
+ /******************************************/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress, |
+| char * pc_PCIChipInformation,struct comedi_device *dev) |
++----------------------------------------------------------------------------+
+| Task : Read from eeprom Main Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| struct comedi_device *dev : comedi device structure |
+| pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_EepromReadMainHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, struct comedi_device *dev)
+{
+ WORD w_Temp, i, w_Count = 0;
+ UINT ui_Temp;
+ str_MainHeader s_MainHeader;
+ str_DigitalInputHeader s_DigitalInputHeader;
+ str_DigitalOutputHeader s_DigitalOutputHeader;
+ //str_TimerMainHeader s_TimerMainHeader,s_WatchdogMainHeader;
+ str_AnalogOutputHeader s_AnalogOutputHeader;
+ str_AnalogInputHeader s_AnalogInputHeader;
+
+ // Read size
+ s_MainHeader.w_HeaderSize =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + 8);
+
+ // Read nbr of functionality
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + 10);
+ s_MainHeader.b_Nfunctions = (BYTE) w_Temp & 0x00FF;
+
+ // Read functionality details
+ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+ // Read Type
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + 12 + w_Count);
+ s_MainHeader.s_Functions[i].b_Type = (BYTE) w_Temp & 0x3F;
+ w_Count = w_Count + 2;
+ //Read Address
+ s_MainHeader.s_Functions[i].w_Address =
+ w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + 12 + w_Count);
+ w_Count = w_Count + 2;
+ }
+
+ // Display main header info
+ for (i = 0; i < s_MainHeader.b_Nfunctions; i++) {
+
+ switch (s_MainHeader.s_Functions[i].b_Type) {
+ case EEPROM_DIGITALINPUT:
+ i_EepromReadDigitalInputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_DigitalInputHeader);
+ this_board->i_NbrDiChannel =
+ s_DigitalInputHeader.w_Nchannel;
+ break;
+
+ case EEPROM_DIGITALOUTPUT:
+ i_EepromReadDigitalOutputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_DigitalOutputHeader);
+ this_board->i_NbrDoChannel =
+ s_DigitalOutputHeader.w_Nchannel;
+ ui_Temp = 0xffffffff;
+ this_board->i_DoMaxdata =
+ ui_Temp >> (32 - this_board->i_NbrDoChannel);
+ break;
+
+ case EEPROM_ANALOGINPUT:
+ i_EepromReadAnlogInputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_AnalogInputHeader);
+ if (!(strcmp(this_board->pc_DriverName, "apci3200")))
+ this_board->i_NbrAiChannel =
+ s_AnalogInputHeader.w_Nchannel * 4;
+ else
+ this_board->i_NbrAiChannel =
+ s_AnalogInputHeader.w_Nchannel;
+ this_board->i_Dma = s_AnalogInputHeader.b_HasDma;
+ this_board->ui_MinAcquisitiontimeNs =
+ (UINT) s_AnalogInputHeader.w_MinConvertTiming *
+ 1000;
+ this_board->ui_MinDelaytimeNs =
+ (UINT) s_AnalogInputHeader.w_MinDelayTiming *
+ 1000;
+ ui_Temp = 0xffff;
+ this_board->i_AiMaxdata =
+ ui_Temp >> (16 -
+ s_AnalogInputHeader.b_Resolution);
+ break;
+
+ case EEPROM_ANALOGOUTPUT:
+ i_EepromReadAnlogOutputHeader(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ s_MainHeader.s_Functions[i].w_Address,
+ &s_AnalogOutputHeader);
+ this_board->i_NbrAoChannel =
+ s_AnalogOutputHeader.w_Nchannel;
+ ui_Temp = 0xffff;
+ this_board->i_AoMaxdata =
+ ui_Temp >> (16 -
+ s_AnalogOutputHeader.b_Resolution);
+ break;
+
+ case EEPROM_TIMER:
+ this_board->i_Timer = 1; //Timer subdevice present
+ break;
+
+ case EEPROM_WATCHDOG:
+ this_board->i_Timer = 1; //Timer subdevice present
+ break;
+
+ case EEPROM_TIMER_WATCHDOG_COUNTER:
+ this_board->i_Timer = 1; //Timer subdevice present
+ }
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadDigitalInputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_DigitalInputHeader *s_Header) |
+| |
++----------------------------------------------------------------------------+
+| Task : Read Digital Input Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_DigitalInputHeader *s_Header: Digita Input Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalInputHeader * s_Header)
+{
+ WORD w_Temp;
+
+ // read nbr of channels
+ s_Header->w_Nchannel =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 6);
+
+ // interruptible or not
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 8);
+ s_Header->b_Interruptible = (BYTE) (w_Temp >> 7) & 0x01;
+
+// How many interruptible logic
+ s_Header->w_NinterruptLogic =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 10);
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadDigitalOutputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_DigitalOutputHeader *s_Header) |
+| |
++----------------------------------------------------------------------------+
+| Task : Read Digital Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_DigitalOutputHeader *s_Header: Digital Output Header|
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadDigitalOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_DigitalOutputHeader * s_Header)
+{
+// Read Nbr channels
+ s_Header->w_Nchannel =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 6);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress, |
+| char *pc_PCIChipInformation,WORD w_Address, |
+| str_TimerMainHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Timer or Watchdog Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_TimerMainHeader *s_Header: Timer Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+INT i_EepromReadTimerHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_TimerMainHeader * s_Header)
+{
+
+ WORD i, w_Size = 0, w_Temp;
+
+//Read No of Timer
+ s_Header->w_Ntimer =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 6);
+//Read header size
+
+ for (i = 0; i < s_Header->w_Ntimer; i++) {
+ s_Header->s_TimerDetails[i].w_HeaderSize =
+ w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ 0x100 + w_Address + 8 + w_Size + 0);
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ 0x100 + w_Address + 8 + w_Size + 2);
+
+ //Read Resolution
+ s_Header->s_TimerDetails[i].b_Resolution =
+ (BYTE) (w_Temp >> 10) & 0x3F;
+
+ //Read Mode
+ s_Header->s_TimerDetails[i].b_Mode =
+ (BYTE) (w_Temp >> 4) & 0x3F;
+
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation,
+ 0x100 + w_Address + 8 + w_Size + 4);
+
+ //Read MinTiming
+ s_Header->s_TimerDetails[i].w_MinTiming = (w_Temp >> 6) & 0x3FF;
+
+ //Read Timebase
+ s_Header->s_TimerDetails[i].b_TimeBase = (BYTE) (w_Temp) & 0x3F;
+ w_Size += s_Header->s_TimerDetails[i].w_HeaderSize;
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadAnlogOutputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_AnalogOutputHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Nalog Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_AnalogOutputHeader *s_Header:Anlog Output Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+INT i_EepromReadAnlogOutputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogOutputHeader * s_Header)
+{
+ WORD w_Temp;
+ // No of channels for 1st hard component
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 10);
+ s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
+ // Resolution for 1st hard component
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 16);
+ s_Header->b_Resolution = (BYTE) (w_Temp >> 8) & 0xFF;
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_EepromReadAnlogInputHeader(WORD |
+| w_PCIBoardEepromAddress,char *pc_PCIChipInformation, |
+| WORD w_Address,str_AnalogInputHeader *s_Header) |
++----------------------------------------------------------------------------+
+| Task : Read Nalog Output Header |
++----------------------------------------------------------------------------+
+| Input Parameters : WORD w_PCIBoardEepromAddress : PCI eeprom address |
+| |
+| char *pc_PCIChipInformation : PCI Chip Type. |
+| |
+| str_AnalogInputHeader *s_Header:Anlog Input Header |
+| Pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
++----------------------------------------------------------------------------+
+*/
+
+// Reads only for ONE hardware component
+INT i_EepromReadAnlogInputHeader(WORD w_PCIBoardEepromAddress,
+ char *pc_PCIChipInformation, WORD w_Address,
+ str_AnalogInputHeader * s_Header)
+{
+ WORD w_Temp, w_Offset;
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 10);
+ s_Header->w_Nchannel = (w_Temp >> 4) & 0x03FF;
+ s_Header->w_MinConvertTiming =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 16);
+ s_Header->w_MinDelayTiming =
+ w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation,
+ 0x100 + w_Address + 30);
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + 20);
+ s_Header->b_HasDma = (w_Temp >> 13) & 0x01; // whether dma present or not
+
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress, pc_PCIChipInformation, 0x100 + w_Address + 72); // reading Y
+ w_Temp = w_Temp & 0x00FF;
+ if (w_Temp) //Y>0
+ {
+ w_Offset = 74 + (2 * w_Temp) + (10 * (1 + (w_Temp / 16))); // offset of first analog input single header
+ w_Offset = w_Offset + 2; // resolution
+ } else //Y=0
+ {
+ w_Offset = 74;
+ w_Offset = w_Offset + 2; // resolution
+ }
+
+// read Resolution
+ w_Temp = w_EepromReadWord(w_PCIBoardEepromAddress,
+ pc_PCIChipInformation, 0x100 + w_Address + w_Offset);
+ s_Header->b_Resolution = w_Temp & 0x001F; // last 5 bits
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
new file mode 100644
index 00000000000..617dc087dcb
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/amcc_s5933_58.h
@@ -0,0 +1,457 @@
+/*
+ Modified by umesh on 16th may 2001
+ Modified by sarath on 22nd may 2001
+*/
+
+/*
+ comedi/drivers/amcc_s5933_v_58.h
+
+ Stuff for AMCC S5933 PCI Controller
+
+ Author: Michal Dobes <majkl@tesnet.cz>
+
+ Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
+ made by Andrea Cisternino <acister@pcape1.pi.infn.it>
+ and as result of espionage from MITE code made by David A. Schleef.
+ Thanks to AMCC for their on-line documentation and bus master DMA
+ example.
+*/
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+#include <linux/pci.h>
+#include "../../comedidev.h"
+
+#ifdef PCI_SUPPORT_VER1
+#error Sorry, no support for 2.1.55 and older! :-((((
+#endif
+
+/***********Added by sarath for compatibility with APCI3120
+
+*************************/
+
+#define FIFO_ADVANCE_ON_BYTE_2 0x20000000 // written on base0
+
+#define AMWEN_ENABLE 0x02 // added for step 6 dma written on base2
+#define A2P_FIFO_WRITE_ENABLE 0x01
+
+#define AGCSTS_TC_ENABLE 0x10000000 // Added for transfer count enable bit
+
+// ADDON RELATED ADDITIONS
+// Constant
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_LOW 0x00
+#define APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH 0x1200
+#define APCI3120_A2P_FIFO_MANAGEMENT 0x04000400L
+#define APCI3120_AMWEN_ENABLE 0x02
+#define APCI3120_A2P_FIFO_WRITE_ENABLE 0x01
+#define APCI3120_FIFO_ADVANCE_ON_BYTE_2 0x20000000L
+#define APCI3120_ENABLE_WRITE_TC_INT 0x00004000L
+#define APCI3120_CLEAR_WRITE_TC_INT 0x00040000L
+#define APCI3120_DISABLE_AMWEN_AND_A2P_FIFO_WRITE 0x0
+#define APCI3120_DISABLE_BUS_MASTER_ADD_ON 0x0
+#define APCI3120_DISABLE_BUS_MASTER_PCI 0x0
+
+ // ADD_ON ::: this needed since apci supports 16 bit interface to add on
+#define APCI3120_ADD_ON_AGCSTS_LOW 0x3C
+#define APCI3120_ADD_ON_AGCSTS_HIGH APCI3120_ADD_ON_AGCSTS_LOW + 2
+#define APCI3120_ADD_ON_MWAR_LOW 0x24
+#define APCI3120_ADD_ON_MWAR_HIGH APCI3120_ADD_ON_MWAR_LOW + 2
+#define APCI3120_ADD_ON_MWTC_LOW 0x058
+#define APCI3120_ADD_ON_MWTC_HIGH APCI3120_ADD_ON_MWTC_LOW + 2
+
+// AMCC
+#define APCI3120_AMCC_OP_MCSR 0x3C
+#define APCI3120_AMCC_OP_REG_INTCSR 0x38
+
+/*******from here all upward definitions are added by sarath */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
+#define AMCC_OP_REG_MCSR 0x3c
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register */
+/****************************************************************************/
+
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+/****************************************************************************/
+
+struct pcilst_struct {
+ struct pcilst_struct *next;
+ int used;
+ struct pci_dev *pcidev;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned int master;
+ unsigned char pci_bus;
+ unsigned char pci_slot;
+ unsigned char pci_func;
+ unsigned int io_addr[5];
+ unsigned int irq;
+};
+
+struct pcilst_struct *amcc_devices; // ptr to root list of all amcc devices
+
+/****************************************************************************/
+
+void v_pci_card_list_init(unsigned short pci_vendor, char display);
+void v_pci_card_list_cleanup(unsigned short pci_vendor);
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short
+ device_id);
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card);
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot);
+
+int i_pci_card_alloc(struct pcilst_struct *amcc);
+int i_pci_card_free(struct pcilst_struct *amcc);
+void v_pci_card_list_display(void);
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, unsigned short *io_addr,
+ unsigned short *irq, unsigned short *master);
+
+/****************************************************************************/
+
+/* build list of amcc cards in this system */
+void v_pci_card_list_init(unsigned short pci_vendor, char display)
+{
+ struct pci_dev *pcidev;
+ struct pcilst_struct *amcc, *last;
+ int i;
+
+ amcc_devices = NULL;
+ last = NULL;
+
+ pci_for_each_dev(pcidev) {
+ if (pcidev->vendor == pci_vendor) {
+ amcc = kmalloc(sizeof(*amcc), GFP_KERNEL);
+ memset(amcc, 0, sizeof(*amcc));
+
+ amcc->pcidev = pcidev;
+ if (last) {
+ last->next = amcc;
+ } else {
+ amcc_devices = amcc;
+ }
+ last = amcc;
+
+ amcc->vendor = pcidev->vendor;
+ amcc->device = pcidev->device;
+#if 0
+ amcc->master = pcidev->master; // how get this information under 2.4 kernels?
+#endif
+ amcc->pci_bus = pcidev->bus->number;
+ amcc->pci_slot = PCI_SLOT(pcidev->devfn);
+ amcc->pci_func = PCI_FUNC(pcidev->devfn);
+ for (i = 0; i < 5; i++)
+ amcc->io_addr[i] =
+ pcidev->resource[i].start & ~3UL;
+ amcc->irq = pcidev->irq;
+ }
+ }
+
+ if (display)
+ v_pci_card_list_display();
+}
+
+/****************************************************************************/
+/* free up list of amcc cards in this system */
+void v_pci_card_list_cleanup(unsigned short pci_vendor)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ kfree(amcc);
+ }
+
+ amcc_devices = NULL;
+}
+
+/****************************************************************************/
+/* find first unused card with this device_id */
+struct pcilst_struct *ptr_find_free_pci_card_by_device(unsigned short vendor_id,
+ unsigned short device_id)
+{
+ struct pcilst_struct *amcc, *next;
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((!amcc->used) && (amcc->device == device_id)
+ && (amcc->vendor == vendor_id))
+ return amcc;
+
+ }
+
+ return NULL;
+}
+
+/****************************************************************************/
+/* find card on requested position */
+int i_find_free_pci_card_by_position(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot,
+ struct pcilst_struct **card)
+{
+ struct pcilst_struct *amcc, *next;
+
+ *card = NULL;
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ if ((amcc->vendor == vendor_id) && (amcc->device == device_id)
+ && (amcc->pci_bus == pci_bus)
+ && (amcc->pci_slot == pci_slot)) {
+ if (!(amcc->used)) {
+ *card = amcc;
+ return 0; // ok, card is found
+ } else {
+ rt_printk
+ (" - \nCard on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return 2; // card exist but is used
+ }
+ }
+ }
+
+ return 1; // no card found
+}
+
+/****************************************************************************/
+/* mark card as used */
+int i_pci_card_alloc(struct pcilst_struct *amcc)
+{
+ if (!amcc)
+ return -1;
+
+ if (amcc->used)
+ return 1;
+ amcc->used = 1;
+ return 0;
+}
+
+/****************************************************************************/
+/* mark card as free */
+int i_pci_card_free(struct pcilst_struct *amcc)
+{
+ if (!amcc)
+ return -1;
+
+ if (!amcc->used)
+ return 1;
+ amcc->used = 0;
+ return 0;
+}
+
+/****************************************************************************/
+/* display list of found cards */
+void v_pci_card_list_display(void)
+{
+ struct pcilst_struct *amcc, *next;
+
+ printk("List of pci cards\n");
+ printk("bus:slot:func vendor device master io_amcc io_daq irq used\n");
+
+ for (amcc = amcc_devices; amcc; amcc = next) {
+ next = amcc->next;
+ printk
+ ("%2d %2d %2d 0x%4x 0x%4x %3s 0x%4x 0x%4x %2d %2d\n",
+ amcc->pci_bus, amcc->pci_slot, amcc->pci_func,
+ amcc->vendor, amcc->device, amcc->master ? "yes" : "no",
+ amcc->io_addr[0], amcc->io_addr[2], amcc->irq, amcc->used);
+
+ }
+}
+
+/****************************************************************************/
+/* return all card information for driver */
+int i_pci_card_data(struct pcilst_struct *amcc,
+ unsigned char *pci_bus, unsigned char *pci_slot,
+ unsigned char *pci_func, unsigned short *io_addr,
+ unsigned short *irq, unsigned short *master)
+{
+ int i;
+
+ if (!amcc)
+ return -1;
+ *pci_bus = amcc->pci_bus;
+ *pci_slot = amcc->pci_slot;
+ *pci_func = amcc->pci_func;
+ for (i = 0; i < 5; i++)
+ io_addr[i] = amcc->io_addr[i];
+ *irq = amcc->irq;
+ *master = amcc->master;
+ return 0;
+}
+
+/****************************************************************************/
+/* select and alloc card */
+struct pcilst_struct *ptr_select_and_alloc_pci_card(unsigned short vendor_id,
+ unsigned short device_id,
+ unsigned short pci_bus,
+ unsigned short pci_slot)
+{
+ struct pcilst_struct *card;
+
+ if ((pci_bus < 1) & (pci_slot < 1)) { // use autodetection
+ if ((card = ptr_find_free_pci_card_by_device(vendor_id,
+ device_id)) ==
+ NULL) {
+ rt_printk(" - Unused card not found in system!\n");
+ return NULL;
+ }
+ } else {
+ switch (i_find_free_pci_card_by_position(vendor_id, device_id,
+ pci_bus, pci_slot,
+ &card)) {
+ case 1:
+ rt_printk
+ (" - Card not found on requested position b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ case 2:
+ rt_printk
+ (" - Card on requested position is used b:s %d:%d!\n",
+ pci_bus, pci_slot);
+ return NULL;
+ }
+ }
+
+ if (i_pci_card_alloc(card) != 0) {
+ rt_printk(" - Can't allocate card!\n");
+ return NULL;
+ }
+
+ return card;
+}
+
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
new file mode 100644
index 00000000000..3f8929c0907
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c
@@ -0,0 +1,1265 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1710 | Compiler : GCC |
+ | Module name : hwdrv_apci1710.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1710 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+#include "hwdrv_APCI1710.h"
+#include "APCI1710_Inp_cpt.c"
+
+#include "APCI1710_Ssi.c"
+#include "APCI1710_Tor.c"
+#include "APCI1710_Ttl.c"
+#include "APCI1710_Dig_io.c"
+#include "APCI1710_82x54.c"
+#include "APCI1710_Chrono.c"
+#include "APCI1710_Pwm.c"
+#include "APCI1710_INCCPT.c"
+
+void i_ADDI_AttachPCI1710(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+ int ret = 0;
+ int n_subdevices = 9;
+
+ //Update-0.7.57->0.7.68dev->n_subdevices = 9;
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return;
+
+ // Allocate and Initialise Timer Subdevice Structures
+ s = dev->subdevices + 0;
+
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 3;
+ s->maxdata = 0;
+ s->len_chanlist = 3;
+ s->range_table = &range_digital;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisableTimer;
+ s->insn_read = i_APCI1710_InsnReadAllTimerValue;
+ s->insn_config = i_APCI1710_InsnConfigInitTimer;
+ s->insn_bits = i_APCI1710_InsnBitsTimer;
+
+ // Allocate and Initialise DIO Subdevice Structures
+ s = dev->subdevices + 1;
+
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 7;
+ s->maxdata = 1;
+ s->len_chanlist = 7;
+ s->range_table = &range_digital;
+ s->insn_config = i_APCI1710_InsnConfigDigitalIO;
+ s->insn_read = i_APCI1710_InsnReadDigitalIOChlValue;
+ s->insn_bits = i_APCI1710_InsnBitsDigitalIOPortOnOff;
+ s->insn_write = i_APCI1710_InsnWriteDigitalIOChlOnOff;
+
+ // Allocate and Initialise Chrono Subdevice Structures
+ s = dev->subdevices + 2;
+
+ s->type = COMEDI_SUBD_CHRONO;
+ s->subdev_flags = SDF_WRITEABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 0;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisableChrono;
+ s->insn_read = i_APCI1710_InsnReadChrono;
+ s->insn_config = i_APCI1710_InsnConfigInitChrono;
+ s->insn_bits = i_APCI1710_InsnBitsChronoDigitalIO;
+
+ // Allocate and Initialise PWM Subdevice Structures
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_PWM;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 3;
+ s->maxdata = 1;
+ s->len_chanlist = 3;
+ s->range_table = &range_digital;
+ s->io_bits = 0; //all bits input
+ s->insn_config = i_APCI1710_InsnConfigPWM;
+ s->insn_read = i_APCI1710_InsnReadGetPWMStatus;
+ s->insn_write = i_APCI1710_InsnWritePWM;
+ s->insn_bits = i_APCI1710_InsnBitsReadPWMInterrupt;
+
+ // Allocate and Initialise TTLIO Subdevice Structures
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_TTLIO;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_apci1710_ttl; // to pass arguments in range
+ s->insn_config = i_APCI1710_InsnConfigInitTTLIO;
+ s->insn_bits = i_APCI1710_InsnBitsReadTTLIO;
+ s->insn_write = i_APCI1710_InsnWriteSetTTLIOChlOnOff;
+ s->insn_read = i_APCI1710_InsnReadTTLIOAllPortValue;
+
+ // Allocate and Initialise TOR Subdevice Structures
+ s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_TOR;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+ s->io_bits = 0; //all bits input
+ s->insn_config = i_APCI1710_InsnConfigInitTorCounter;
+ s->insn_read = i_APCI1710_InsnReadGetTorCounterInitialisation;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisableTorCounter;
+ s->insn_bits = i_APCI1710_InsnBitsGetTorCounterProgressStatusAndValue;
+
+ // Allocate and Initialise SSI Subdevice Structures
+ s = dev->subdevices + 6;
+ s->type = COMEDI_SUBD_SSI;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_apci1710_ssi;
+ s->insn_config = i_APCI1710_InsnConfigInitSSI;
+ s->insn_read = i_APCI1710_InsnReadSSIValue;
+ s->insn_bits = i_APCI1710_InsnBitsSSIDigitalIO;
+
+ // Allocate and Initialise PULSEENCODER Subdevice Structures
+ s = dev->subdevices + 7;
+ s->type = COMEDI_SUBD_PULSEENCODER;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->insn_config = i_APCI1710_InsnConfigInitPulseEncoder;
+ s->insn_write = i_APCI1710_InsnWriteEnableDisablePulseEncoder;
+ s->insn_bits = i_APCI1710_InsnBitsReadWritePulseEncoder;
+ s->insn_read = i_APCI1710_InsnReadInterruptPulseEncoder;
+
+ // Allocate and Initialise INCREMENTALCOUNTER Subdevice Structures
+ s = dev->subdevices + 8;
+ s->type = COMEDI_SUBD_INCREMENTALCOUNTER;
+ s->subdev_flags =
+ SDF_WRITEABLE | SDF_READABLE | SDF_RT | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 500;
+ s->maxdata = 1;
+ s->len_chanlist = 500;
+ s->range_table = &range_apci1710_inccpt;
+ s->insn_config = i_APCI1710_InsnConfigINCCPT;
+ s->insn_write = i_APCI1710_InsnWriteINCCPT;
+ s->insn_read = i_APCI1710_InsnReadINCCPT;
+ s->insn_bits = i_APCI1710_InsnBitsINCCPT;
+}
+
+int i_APCI1710_Reset(struct comedi_device * dev);
+void v_APCI1710_Interrupt(int irq, void *d);
+//for 1710
+
+int i_APCI1710_Reset(struct comedi_device * dev)
+{
+ int ret;
+ DWORD dw_Dummy;
+
+ /*********************************/
+ /* Read all module configuration */
+ /*********************************/
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 60);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[0] = ret;
+
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 124);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[1] = ret;
+
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 188);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[2] = ret;
+
+ ret = inl(devpriv->s_BoardInfos.ui_Address + 252);
+ devpriv->s_BoardInfos.dw_MolduleConfiguration[3] = ret;
+
+ // outl(0x80808082,devpriv->s_BoardInfos.ui_Address+0x60);
+ outl(0x83838383, devpriv->s_BoardInfos.ui_Address + 0x60);
+
+ devpriv->s_BoardInfos.b_BoardVersion = 1;
+
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->s_BoardInfos.ui_Address + 0x38);
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function's Name : __void__ v_APCI1710_InterruptFunction |
+| (BYTE b_Interrupt, __CPPARGS) |
++----------------------------------------------------------------------------+
+| Task : APCI-1710 interrupt function |
++----------------------------------------------------------------------------+
+| Input Parameters : BYTE b_Interrupt : Interrupt number |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 : OK |
+| -1 : Error |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI1710_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ BYTE b_ModuleCpt = 0;
+ BYTE b_InterruptFlag = 0;
+ BYTE b_PWMCpt = 0;
+ BYTE b_TorCounterCpt = 0;
+ BYTE b_PulseIncoderCpt = 0;
+ UINT ui_16BitValue;
+ ULONG ul_InterruptLatchReg = 0;
+ ULONG ul_LatchRegisterValue = 0;
+ ULONG ul_82X54InterruptStatus;
+ ULONG ul_StatusRegister;
+
+ str_ModuleInfo *ps_ModuleInfo;
+
+ printk("APCI1710 Interrupt\n");
+ for (b_ModuleCpt = 0; b_ModuleCpt < 4; b_ModuleCpt++, ps_ModuleInfo++) {
+
+ /**************************/
+ /* 1199/0225 to 0100/0226 */
+ /**************************/
+ ps_ModuleInfo = &devpriv->s_ModuleInfo[b_ModuleCpt];
+
+ /***********************/
+ /* Test if 82X54 timer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_82X54_TIMER) {
+
+ //printk("TIMER Interrupt Occurred\n");
+ ul_82X54InterruptStatus = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if ((ul_82X54InterruptStatus & ps_ModuleInfo->
+ s_82X54ModuleInfo.
+ b_InterruptMask) != 0) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ (ul_82X54InterruptStatus &
+ ps_ModuleInfo->s_82X54ModuleInfo.
+ b_InterruptMask) << 4;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].ul_OldCounterLatchValue = 0;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ } // if ((ul_82X54InterruptStatus & 0x7) != 0)
+ } // 82X54 timer
+
+ /***************************/
+ /* Test if increm. counter */
+ /***************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_INCREMENTAL_COUNTER) {
+
+ ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + (64 * b_ModuleCpt));
+
+ /*********************/
+ /* Test if interrupt */
+ /*********************/
+
+ if ((ul_InterruptLatchReg & 0x22) && (ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 & 0x80)) {
+ /************************************/
+ /* Test if strobe latch I interrupt */
+ /************************************/
+
+ if (ul_InterruptLatchReg & 2) {
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 4 +
+ (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 1UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+
+ /*************************************/
+ /* Test if strobe latch II interrupt */
+ /*************************************/
+
+ if (ul_InterruptLatchReg & 0x20) {
+
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 8 +
+ (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 2UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+
+ ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 24 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if index interrupt */
+ /***************************/
+
+ if (ul_InterruptLatchReg & 0x8) {
+ ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_InitFlag.b_IndexInterruptOccur = 1;
+
+ if (ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister2 &
+ APCI1710_INDEX_AUTO_MODE) {
+
+ outl(ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ dw_ModeRegister1_2_3_4,
+ devpriv->s_BoardInfos.
+ ui_Address + 20 +
+ (64 * b_ModuleCpt));
+ }
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if ((ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_ENABLE_INDEX_INT) ==
+ APCI1710_ENABLE_INDEX_INT) {
+ devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 4UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+
+ /*****************************/
+ /* Test if compare interrupt */
+ /*****************************/
+
+ if (ul_InterruptLatchReg & 0x10) {
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if ((ps_ModuleInfo->
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister3 &
+ APCI1710_ENABLE_COMPARE_INT) ==
+ APCI1710_ENABLE_COMPARE_INT) {
+ devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 8UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+
+ /*******************************************/
+ /* Test if frequency measurement interrupt */
+ /*******************************************/
+
+ if (ul_InterruptLatchReg & 0x20) {
+ /*******************/
+ /* Read the status */
+ /*******************/
+
+ ul_StatusRegister = inl(devpriv->s_BoardInfos.
+ ui_Address + 32 + (64 * b_ModuleCpt));
+
+ /******************/
+ /* Read the value */
+ /******************/
+
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ 28 + (64 * b_ModuleCpt));
+
+ switch ((ul_StatusRegister >> 1) & 3) {
+ case 0:
+ /*************************/
+ /* Test the counter mode */
+ /*************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModuleCpt].
+ s_SiemensCounterInfo.
+ s_ModeRegister.
+ s_ByteModeRegister.
+ b_ModeRegister1 &
+ APCI1710_16BIT_COUNTER)
+ == APCI1710_16BIT_COUNTER) {
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue &
+ 0xFFFFU) != 0) {
+ ui_16BitValue =
+ (UINT)
+ ul_LatchRegisterValue
+ & 0xFFFFU;
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue
+ & 0xFFFF0000UL)
+ | (0xFFFFU -
+ ui_16BitValue);
+ }
+
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue &
+ 0xFFFF0000UL) !=
+ 0) {
+ ui_16BitValue =
+ (UINT) (
+ (ul_LatchRegisterValue
+ >> 16) &
+ 0xFFFFU);
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue
+ & 0xFFFFUL) |
+ ((0xFFFFU -
+ ui_16BitValue)
+ << 16);
+ }
+ } else {
+ if (ul_LatchRegisterValue != 0) {
+ ul_LatchRegisterValue =
+ 0xFFFFFFFFUL -
+ ul_LatchRegisterValue;
+ }
+ }
+ break;
+
+ case 1:
+ /****************************************/
+ /* Test if 16-bit counter 2 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue &
+ 0xFFFF0000UL) != 0) {
+ ui_16BitValue =
+ (UINT) (
+ (ul_LatchRegisterValue
+ >> 16) &
+ 0xFFFFU);
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue &
+ 0xFFFFUL) | ((0xFFFFU -
+ ui_16BitValue)
+ << 16);
+ }
+ break;
+
+ case 2:
+ /****************************************/
+ /* Test if 16-bit counter 1 pulse occur */
+ /****************************************/
+
+ if ((ul_LatchRegisterValue & 0xFFFFU) !=
+ 0) {
+ ui_16BitValue =
+ (UINT)
+ ul_LatchRegisterValue &
+ 0xFFFFU;
+ ul_LatchRegisterValue =
+ (ul_LatchRegisterValue &
+ 0xFFFF0000UL) | (0xFFFFU
+ - ui_16BitValue);
+ }
+ break;
+ }
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask = 0x10000UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask = 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters[devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write + 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ }
+ } // Incremental counter
+
+ /***************/
+ /* Test if CDA */
+ /***************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_CDA) {
+ /******************************************/
+ /* Test if CDA enable and functionality 0 */
+ /******************************************/
+
+ if ((devpriv->s_ModuleInfo[b_ModuleCpt].
+ s_CDAModuleInfo.
+ b_CDAEnable == APCI1710_ENABLE)
+ && (devpriv->s_ModuleInfo[b_ModuleCpt].
+ s_CDAModuleInfo.b_FctSelection == 0)) {
+ /****************************/
+ /* Get the interrupt status */
+ /****************************/
+
+ ul_StatusRegister = inl(devpriv->s_BoardInfos.
+ ui_Address + 16 + (64 * b_ModuleCpt));
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 1) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 0x80000UL;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue = 0;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ } // if (ul_StatusRegister & 1)
+
+ }
+ } // CDA
+
+ /***********************/
+ /* Test if PWM counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_PWM) {
+ for (b_PWMCpt = 0; b_PWMCpt < 2; b_PWMCpt++) {
+ /*************************************/
+ /* Test if PWM interrupt initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModuleCpt].
+ s_PWMModuleInfo.
+ s_PWMInfo[b_PWMCpt].
+ b_InterruptEnable == APCI1710_ENABLE) {
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+ ul_StatusRegister =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 16 +
+ (20 * b_PWMCpt) +
+ (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 0x1) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ 0x4000UL << b_PWMCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) %
+ APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,
+ devpriv->tsk_Current,
+ 0);
+
+ } // if (ul_StatusRegister & 0x1)
+ } // if (APCI1710_ENABLE)
+ } // for (b_PWMCpt == 0; b_PWMCpt < 0; b_PWMCpt ++)
+ } // PWM counter
+
+ /***********************/
+ /* Test if tor counter */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_TOR_COUNTER) {
+ for (b_TorCounterCpt = 0; b_TorCounterCpt < 2;
+ b_TorCounterCpt++) {
+ /*************************************/
+ /* Test if tor interrupt initialised */
+ /*************************************/
+
+ if (devpriv->
+ s_ModuleInfo[b_ModuleCpt].
+ s_TorCounterModuleInfo.
+ s_TorCounterInfo[b_TorCounterCpt].
+ b_InterruptEnable == APCI1710_ENABLE) {
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+ ul_StatusRegister =
+ inl(devpriv->s_BoardInfos.
+ ui_Address + 12 +
+ (16 * b_TorCounterCpt) +
+ (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (ul_StatusRegister & 0x1) {
+ /******************************/
+ /* Read the tor counter value */
+ /******************************/
+
+ ul_LatchRegisterValue =
+ inl(devpriv->
+ s_BoardInfos.
+ ui_Address + 0 +
+ (16 * b_TorCounterCpt) +
+ (64 * b_ModuleCpt));
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ 0x1000UL <<
+ b_TorCounterCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue
+ = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) %
+ APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,
+ devpriv->tsk_Current,
+ 0);
+ } // if (ul_StatusRegister & 0x1)
+ } // if (APCI1710_ENABLE)
+ } // for (b_TorCounterCpt == 0; b_TorCounterCpt < 0; b_TorCounterCpt ++)
+ } // Tor counter
+
+ /***********************/
+ /* Test if chronometer */
+ /***********************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_CHRONOMETER) {
+
+ //printk("APCI1710 Chrono Interrupt\n");
+ /*****************************/
+ /* Read the interrupt status */
+ /*****************************/
+
+ ul_InterruptLatchReg = inl(devpriv->s_BoardInfos.
+ ui_Address + 12 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if ((ul_InterruptLatchReg & 0x8) == 0x8) {
+ /****************************/
+ /* Clear the interrupt flag */
+ /****************************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 32 + (64 * b_ModuleCpt));
+
+ /***************************/
+ /* Test if continuous mode */
+ /***************************/
+
+ if (ps_ModuleInfo->
+ s_ChronoModuleInfo.
+ b_CycleMode == APCI1710_ENABLE) {
+ /********************/
+ /* Clear the status */
+ /********************/
+
+ outl(0, devpriv->s_BoardInfos.
+ ui_Address + 36 +
+ (64 * b_ModuleCpt));
+ }
+
+ /*************************/
+ /* Read the timing value */
+ /*************************/
+
+ ul_LatchRegisterValue =
+ inl(devpriv->s_BoardInfos.ui_Address +
+ 4 + (64 * b_ModuleCpt));
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if (ps_ModuleInfo->
+ s_ChronoModuleInfo.b_InterruptMask) {
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].ul_OldInterruptMask =
+ 0x80;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue =
+ ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) % APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+ } // Chronometer
+
+ /*************************/
+ /* Test if pulse encoder */
+ /*************************/
+
+ if ((devpriv->s_BoardInfos.
+ dw_MolduleConfiguration[b_ModuleCpt] &
+ 0xFFFF0000UL) == APCI1710_PULSE_ENCODER) {
+ /****************************/
+ /* Read the status register */
+ /****************************/
+
+ ul_StatusRegister = inl(devpriv->s_BoardInfos.
+ ui_Address + 20 + (64 * b_ModuleCpt));
+
+ if (ul_StatusRegister & 0xF) {
+ for (b_PulseIncoderCpt = 0;
+ b_PulseIncoderCpt < 4;
+ b_PulseIncoderCpt++) {
+ /*************************************/
+ /* Test if pulse encoder initialised */
+ /*************************************/
+
+ if ((ps_ModuleInfo->
+ s_PulseEncoderModuleInfo.
+ s_PulseEncoderInfo
+ [b_PulseIncoderCpt].
+ b_PulseEncoderInit == 1)
+ && (((ps_ModuleInfo->s_PulseEncoderModuleInfo.dw_SetRegister >> b_PulseIncoderCpt) & 1) == 1) && (((ul_StatusRegister >> (b_PulseIncoderCpt)) & 1) == 1)) {
+ devpriv->s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldInterruptMask =
+ 0x100UL <<
+ b_PulseIncoderCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ b_OldModuleMask =
+ 1 << b_ModuleCpt;
+
+ devpriv->
+ s_InterruptParameters.
+ s_FIFOInterruptParameters
+ [devpriv->
+ s_InterruptParameters.
+ ui_Write].
+ ul_OldCounterLatchValue
+ = ul_LatchRegisterValue;
+
+ devpriv->
+ s_InterruptParameters.
+ ul_InterruptOccur++;
+
+ /****************************/
+ /* 0899/0224 to 1199/0225 */
+ /****************************/
+ /* Increment the write FIFO */
+ /****************************/
+
+ devpriv->
+ s_InterruptParameters.
+ ui_Write = (devpriv->
+ s_InterruptParameters.
+ ui_Write +
+ 1) %
+ APCI1710_SAVE_INTERRUPT;
+
+ b_InterruptFlag = 1;
+
+ /**********************/
+ /* Call user function */
+ /**********************/
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO,
+ devpriv->tsk_Current,
+ 0);
+
+ }
+ }
+ }
+ } //pulse encoder
+
+ }
+ return;
+
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
new file mode 100644
index 00000000000..998cbba8afe
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#define COMEDI_SUBD_PWM 12 /* Pulse width Measurement */
+#define COMEDI_SUBD_SSI 13 /* Synchronous serial interface */
+#define COMEDI_SUBD_TOR 14 /* Tor counter */
+#define COMEDI_SUBD_CHRONO 15 /* Chrono meter */
+#define COMEDI_SUBD_PULSEENCODER 16 /* Pulse Encoder INP CPT */
+#define COMEDI_SUBD_INCREMENTALCOUNTER 17 /* Incremental Counter */
+
+#define APCI1710_BOARD_NAME "apci1710"
+#define APCI1710_BOARD_VENDOR_ID 0x10E8
+#define APCI1710_BOARD_DEVICE_ID 0x818F
+#define APCI1710_ADDRESS_RANGE 256
+#define APCI1710_CONFIG_ADDRESS_RANGE 8
+#define APCI1710_INCREMENTAL_COUNTER 0x53430000UL
+#define APCI1710_SSI_COUNTER 0x53490000UL
+#define APCI1710_TTL_IO 0x544C0000UL
+#define APCI1710_DIGITAL_IO 0x44490000UL
+#define APCI1710_82X54_TIMER 0x49430000UL
+#define APCI1710_CHRONOMETER 0x43480000UL
+#define APCI1710_PULSE_ENCODER 0x495A0000UL
+#define APCI1710_TOR_COUNTER 0x544F0000UL
+#define APCI1710_PWM 0x50570000UL
+#define APCI1710_ETM 0x45540000UL
+#define APCI1710_CDA 0x43440000UL
+#define APCI1710_DISABLE 0
+#define APCI1710_ENABLE 1
+#define APCI1710_SYNCHRONOUS_MODE 1
+#define APCI1710_ASYNCHRONOUS_MODE 0
+
+//MODULE INFO STRUCTURE
+
+static const struct comedi_lrange range_apci1710_ttl = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci1710_ssi = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci1710_inccpt = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1)
+ }
+};
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
new file mode 100644
index 00000000000..e4527926c2d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.c
@@ -0,0 +1,600 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-035 | Compiler : GCC |
+ | Module name : hwdrv_apci035.c | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-035 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci035.h"
+INT i_WatchdogNbr = 0;
+INT i_Temp = 0;
+INT i_Flag = 1;
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_ConfigTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Watchdog |
+ data[1] : Watchdog number
+| data[2] : Time base Unit |
+| data[3] : Reload Value |
+ data[4] : External Trigger |
+ 1:Enable
+ 0:Disable
+ data[5] :External Trigger Level
+ 00 Trigger Disabled
+ 01 Trigger Enabled (Low level)
+ 10 Trigger Enabled (High Level)
+ 11 Trigger Enabled (High/Low level)
+ data[6] : External Gate |
+ 1:Enable
+ 0:Disable
+ data[7] : External Gate level
+ 00 Gate Disabled
+ 01 Gate Enabled (Low level)
+ 10 Gate Enabled (High Level)
+ data[8] :Warning Relay
+ 1: ENABLE
+ 0: DISABLE
+ data[9] :Warning Delay available
+ data[10] :Warning Relay Time unit
+ data[11] :Warning Relay Time Reload value
+ data[12] :Reset Relay
+ 1 : ENABLE
+ 0 : DISABLE
+ data[13] :Interrupt
+ 1 : ENABLE
+ 0 : DISABLE
+
+|
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ConfigTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Status = 0;
+ UINT ui_Command = 0;
+ UINT ui_Mode = 0;
+ i_Temp = 0;
+ devpriv->tsk_Current = current;
+ devpriv->b_TimerSelectMode = data[0];
+ i_WatchdogNbr = data[1];
+ if (data[0] == 0) {
+ ui_Mode = 2;
+ } else {
+ ui_Mode = 0;
+ }
+//ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ ui_Command = 0;
+//ui_Command = ui_Command & 0xFFFFF9FEUL;
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/************************/
+/* Set the reload value */
+/************************/
+ outl(data[3], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 4);
+/*********************/
+/* Set the time unit */
+/*********************/
+ outl(data[2], devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 8);
+ if (data[0] == ADDIDATA_TIMER) {
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Enable the timer mode */
+ /* - Set the timer mode */
+ /******************************/
+
+ ui_Command =
+ (ui_Command & 0xFFF719E2UL) | ui_Mode << 13UL | 0x10UL;
+
+ } //if (data[0] == ADDIDATA_TIMER)
+ else {
+ if (data[0] == ADDIDATA_WATCHDOG) {
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Disable the timer mode */
+ /******************************/
+
+ ui_Command = ui_Command & 0xFFF819E2UL;
+
+ } else {
+ printk("\n The parameter for Timer/watchdog selection is in error\n");
+ return -EINVAL;
+ }
+ }
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/********************************/
+/* Disable the hardware trigger */
+/********************************/
+ ui_Command = ui_Command & 0xFFFFF89FUL;
+ if (data[4] == ADDIDATA_ENABLE) {
+ /**********************************/
+ /* Set the hardware trigger level */
+ /**********************************/
+ ui_Command = ui_Command | (data[5] << 5);
+ }
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*****************************/
+/* Disable the hardware gate */
+/*****************************/
+ ui_Command = ui_Command & 0xFFFFF87FUL;
+ if (data[6] == ADDIDATA_ENABLE) {
+/*******************************/
+/* Set the hardware gate level */
+/*******************************/
+ ui_Command = ui_Command | (data[7] << 7);
+ }
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*******************************/
+/* Disable the hardware output */
+/*******************************/
+ ui_Command = ui_Command & 0xFFFFF9FBUL;
+/*********************************/
+/* Set the hardware output level */
+/*********************************/
+ ui_Command = ui_Command | (data[8] << 2);
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ if (data[9] == ADDIDATA_ENABLE) {
+ /************************/
+ /* Set the reload value */
+ /************************/
+ outl(data[11],
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 24);
+ /**********************/
+ /* Set the time unite */
+ /**********************/
+ outl(data[10],
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 28);
+ }
+
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /*******************************/
+ /* Disable the hardware output */
+ /*******************************/
+ ui_Command = ui_Command & 0xFFFFF9F7UL;
+ /*********************************/
+ /* Set the hardware output level */
+ /*********************************/
+ ui_Command = ui_Command | (data[12] << 3);
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /*************************************/
+ /** Enable the watchdog interrupt **/
+ /*************************************/
+ ui_Command = 0;
+ ui_Command = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+/*******************************/
+/* Set the interrupt selection */
+/*******************************/
+ ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
+
+ ui_Command = (ui_Command & 0xFFFFF9FDUL) | (data[13] << 1);
+ outl(ui_Command, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_StartStopWriteTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 - Stop Selected Timer/Watchdog |
+| 1 - Start Selected Timer/Watchdog |
+| 2 - Trigger Selected Timer/Watchdog |
+| 3 - Stop All Timer/Watchdog |
+| 4 - Start All Timer/Watchdog |
+| 5 - Trigger All Timer/Watchdog |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Command = 0;
+ INT i_Count = 0;
+ if (data[0] == 1) {
+ ui_Command =
+ inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /**********************/
+ /* Start the hardware */
+ /**********************/
+ ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x1UL;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ } // if (data[0]==1)
+ if (data[0] == 2) {
+ ui_Command =
+ inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ /***************************/
+ /* Set the trigger command */
+ /***************************/
+ ui_Command = (ui_Command & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ }
+
+ if (data[0] == 0) //Stop The Watchdog
+ {
+ //Stop The Watchdog
+ ui_Command = 0;
+ //ui_Command = inl(devpriv->iobase+((i_WatchdogNbr-1)*32)+12);
+ //ui_Command = ui_Command & 0xFFFFF9FEUL;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 12);
+ } // if (data[1]==0)
+ if (data[0] == 3) //stop all Watchdogs
+ {
+ ui_Command = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ ui_Command = 0x2UL;
+ } else {
+ ui_Command = 0x10UL;
+ }
+ i_WatchdogNbr = i_Count;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+ 0);
+ }
+
+ }
+ if (data[0] == 4) //start all Watchdogs
+ {
+ ui_Command = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ ui_Command = 0x1UL;
+ } else {
+ ui_Command = 0x8UL;
+ }
+ i_WatchdogNbr = i_Count;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+ 0);
+ }
+ }
+ if (data[0] == 5) //trigger all Watchdogs
+ {
+ ui_Command = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ ui_Command = 0x4UL;
+ } else {
+ ui_Command = 0x20UL;
+ }
+
+ i_WatchdogNbr = i_Count;
+ outl(ui_Command,
+ devpriv->iobase + ((i_WatchdogNbr - 1) * 32) +
+ 0);
+ }
+ i_Temp = 1;
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_ReadTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : software trigger status
+ data[1] : hardware trigger status
+| data[2] : Software clear status
+ data[3] : Overflow status
+ data[4] : Timer actual value
+
+
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ReadTimerWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Status = 0; // Status register
+ i_WatchdogNbr = insn->unused[0];
+ /******************/
+ /* Get the status */
+ /******************/
+ ui_Status = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 16);
+ /***********************************/
+ /* Get the software trigger status */
+ /***********************************/
+ data[0] = ((ui_Status >> 1) & 1);
+ /***********************************/
+ /* Get the hardware trigger status */
+ /***********************************/
+ data[1] = ((ui_Status >> 2) & 1);
+ /*********************************/
+ /* Get the software clear status */
+ /*********************************/
+ data[2] = ((ui_Status >> 3) & 1);
+ /***************************/
+ /* Get the overflow status */
+ /***************************/
+ data[3] = ((ui_Status >> 0) & 1);
+ if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ data[4] = inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0);
+
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI035_ConfigAnalogInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Analog Input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| data[0] : Warning delay value
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->tsk_Current = current;
+ outl(0x200 | 0, devpriv->iobase + 128 + 0x4);
+ outl(0, devpriv->iobase + 128 + 0);
+/********************************/
+/* Initialise the warning value */
+/********************************/
+ outl(0x300 | 0, devpriv->iobase + 128 + 0x4);
+ outl((data[0] << 8), devpriv->iobase + 128 + 0);
+ outl(0x200000UL, devpriv->iobase + 128 + 12);
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_ReadAnalogInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
+| data[0] : Digital Value Of Input |
+| |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_CommandRegister = 0;
+/******************/
+/* Set the start */
+/******************/
+ ui_CommandRegister = 0x80000;
+ /******************************/
+ /* Write the command register */
+ /******************************/
+ outl(ui_CommandRegister, devpriv->iobase + 128 + 8);
+
+/***************************************/
+/* Read the digital value of the input */
+/***************************************/
+ data[0] = inl(devpriv->iobase + 128 + 28);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI035_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI035_Reset(struct comedi_device * dev)
+{
+ INT i_Count = 0;
+ for (i_Count = 1; i_Count <= 4; i_Count++) {
+ i_WatchdogNbr = i_Count;
+ outl(0x0, devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 0); //stop all timers
+ }
+ outl(0x0, devpriv->iobase + 128 + 12); //Disable the warning delay
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI035_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt processing Routine |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI035_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ UINT ui_StatusRegister1 = 0;
+ UINT ui_StatusRegister2 = 0;
+ UINT ui_ReadCommand = 0;
+ UINT ui_ChannelNumber = 0;
+ UINT ui_DigitalTemperature = 0;
+ if (i_Temp == 1) {
+ i_WatchdogNbr = i_Flag;
+ i_Flag = i_Flag + 1;
+ }
+ /**************************************/
+ /* Read the interrupt status register of temperature Warning */
+ /**************************************/
+ ui_StatusRegister1 = inl(devpriv->iobase + 128 + 16);
+ /**************************************/
+ /* Read the interrupt status register for Watchdog/timer */
+ /**************************************/
+
+ ui_StatusRegister2 =
+ inl(devpriv->iobase + ((i_WatchdogNbr - 1) * 32) + 20);
+
+ if ((((ui_StatusRegister1) & 0x8) == 0x8)) //Test if warning relay interrupt
+ {
+ /**********************************/
+ /* Disable the temperature warning */
+ /**********************************/
+ ui_ReadCommand = inl(devpriv->iobase + 128 + 12);
+ ui_ReadCommand = ui_ReadCommand & 0xFFDF0000UL;
+ outl(ui_ReadCommand, devpriv->iobase + 128 + 12);
+ /***************************/
+ /* Read the channel number */
+ /***************************/
+ ui_ChannelNumber = inl(devpriv->iobase + 128 + 60);
+ /**************************************/
+ /* Read the digital temperature value */
+ /**************************************/
+ ui_DigitalTemperature = inl(devpriv->iobase + 128 + 60);
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+ else {
+ if ((ui_StatusRegister2 & 0x1) == 0x1) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ }
+ } //else if (((ui_StatusRegister1 & 0x8) == 0x8))
+
+ return;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
new file mode 100644
index 00000000000..80d7c0d39aa
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci035.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/* Card Specific information */
+#define APCI035_BOARD_VENDOR_ID 0x15B8
+#define APCI035_ADDRESS_RANGE 255
+
+INT i_TW_Number;
+struct {
+ INT i_Gain;
+ INT i_Polarity;
+ INT i_OffsetRange;
+ INT i_Coupling;
+ INT i_SingleDiff;
+ INT i_AutoCalibration;
+ UINT ui_ReloadValue;
+ UINT ui_TimeUnitReloadVal;
+ INT i_Interrupt;
+ INT i_ModuleSelection;
+} Config_Parameters_Main;
+
+/* ANALOG INPUT RANGE */
+struct comedi_lrange range_apci035_ai = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+/* Timer / Watchdog Related Defines */
+#define APCI035_TCW_SYNC_ENABLEDISABLE 0
+#define APCI035_TCW_RELOAD_VALUE 4
+#define APCI035_TCW_TIMEBASE 8
+#define APCI035_TCW_PROG 12
+#define APCI035_TCW_TRIG_STATUS 16
+#define APCI035_TCW_IRQ 20
+#define APCI035_TCW_WARN_TIMEVAL 24
+#define APCI035_TCW_WARN_TIMEBASE 28
+
+#define ADDIDATA_TIMER 0
+/* #define ADDIDATA_WATCHDOG 1 */
+
+#define APCI035_TW1 0
+#define APCI035_TW2 32
+#define APCI035_TW3 64
+#define APCI035_TW4 96
+
+#define APCI035_AI_OFFSET 0
+#define APCI035_TEMP 128
+#define APCI035_ALR_SEQ 4
+#define APCI035_START_STOP_INDEX 8
+#define APCI035_ALR_START_STOP 12
+#define APCI035_ALR_IRQ 16
+#define APCI035_EOS 20
+#define APCI035_CHAN_NO 24
+#define APCI035_CHAN_VAL 28
+#define APCI035_CONV_TIME_TIME_BASE 36
+#define APCI035_RELOAD_CONV_TIME_VAL 32
+#define APCI035_DELAY_TIME_TIME_BASE 44
+#define APCI035_RELOAD_DELAY_TIME_VAL 40
+#define ENABLE_EXT_TRIG 1
+#define ENABLE_EXT_GATE 2
+#define ENABLE_EXT_TRIG_GATE 3
+
+#define ANALOG_INPUT 0
+#define TEMPERATURE 1
+#define RESISTANCE 2
+
+#define ADDIDATA_GREATER_THAN_TEST 0
+#define ADDIDATA_LESS_THAN_TEST 1
+
+#define APCI035_MAXVOLT 2.5
+
+#define ADDIDATA_UNIPOLAR 1
+#define ADDIDATA_BIPOLAR 2
+
+/* ADDIDATA Enable Disable */
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+/* Hardware Layer functions for Apci035 */
+
+/* TIMER */
+/* timer value is passed as u seconds */
+INT i_APCI035_ConfigTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_StartStopWriteTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_ReadTimerWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/* Temperature Related Defines (Analog Input Subdevice) */
+
+INT i_APCI035_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI035_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/* Interrupt */
+static void v_APCI035_Interrupt(int irq, void *d);
+
+/* Reset functions */
+INT i_APCI035_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
new file mode 100644
index 00000000000..32796ceb946
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.c
@@ -0,0 +1,285 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1032 | Compiler : GCC |
+ | Module name : hwdrv_apci1032.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1032 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci1032.h"
+#include <linux/delay.h>
+//Global variables
+UINT ui_InterruptStatus = 0;
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_ConfigDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures the digital input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Enable Digital Input Interrupt |
+| 0 Disable Digital Input Interrupt |
+| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
+| : 1 ADDIDATA Interrupt AND LOGIC |
+| data[2] : Interrupt mask for the mode 1 |
+| data[3] : Interrupt mask for the mode 2 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ConfigDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue;
+
+ ULONG ul_Command1 = 0;
+ ULONG ul_Command2 = 0;
+ devpriv->tsk_Current = current;
+
+ /*******************************/
+ /* Set the digital input logic */
+ /*******************************/
+ if (data[0] == ADDIDATA_ENABLE) {
+ ul_Command1 = ul_Command1 | data[2];
+ ul_Command2 = ul_Command2 | data[3];
+ outl(ul_Command1,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(ul_Command2,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ if (data[1] == ADDIDATA_OR) {
+ outl(0x4, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ ui_TmpValue =
+ inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ } //if (data[1] == ADDIDATA_OR)
+ else {
+ outl(0x6, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ } //else if(data[1] == ADDIDATA_OR)
+ } // if( data[0] == ADDIDATA_ENABLE)
+ else {
+ ul_Command1 = ul_Command1 & 0xFFFF0000;
+ ul_Command2 = ul_Command2 & 0xFFFF0000;
+ outl(ul_Command1,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(ul_Command2,
+ devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ } //else if ( data[0] == ADDIDATA_ENABLE)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1032_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 31) {
+ ui_TmpValue = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=31)
+ else {
+ //comedi_error(dev," \n chan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=31)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+ if (data[1] == 0) {
+ *data = (UINT) inl(devpriv->iobase + APCI1032_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 8:
+ ui_Mask = 255;
+ *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+ break;
+ case 16:
+ ui_Mask = 65535;
+ *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
+ break;
+ case 31:
+ break;
+ default:
+ //comedi_error(dev," \nchan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_NoOfChannels)
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ *data = ui_InterruptStatus;
+ } //if(data[1]==1)
+ } //else if(data[1]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1032_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1032_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+
+ UINT ui_Temp;
+ //disable the interrupt
+ ui_Temp = inl(devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ outl(ui_Temp & APCI1032_DIGITAL_IP_INTERRUPT_DISABLE,
+ devpriv->iobase + APCI1032_DIGITAL_IP_IRQ);
+ ui_InterruptStatus =
+ inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS);
+ ui_InterruptStatus = ui_InterruptStatus & 0X0000FFFF;
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ outl(ui_Temp, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //enable the interrupt
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1032_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1032_Reset(struct comedi_device * dev)
+{
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_IRQ); //disable the interrupts
+ inl(devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_STATUS); //Reset the interrupt status register
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE1); //Disable the and/or interrupt
+ outl(0x0, devpriv->iobase + APCI1032_DIGITAL_IP_INTERRUPT_MODE2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
new file mode 100644
index 00000000000..659ef85088c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1032.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/********* Definitions for APCI-1032 card *****/
+
+#define APCI1032_BOARD_VENDOR_ID 0x15B8
+#define APCI1032_ADDRESS_RANGE 20
+//DIGITAL INPUT DEFINE
+
+#define APCI1032_DIGITAL_IP 0
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE1 4
+#define APCI1032_DIGITAL_IP_INTERRUPT_MODE2 8
+#define APCI1032_DIGITAL_IP_IRQ 16
+
+//Digital Input IRQ Function Selection
+#define ADDIDATA_OR 0
+#define ADDIDATA_AND 1
+
+//Digital Input Interrupt Status
+#define APCI1032_DIGITAL_IP_INTERRUPT_STATUS 12
+
+//Digital Input Interrupt Enable Disable.
+#define APCI1032_DIGITAL_IP_INTERRUPT_ENABLE 0x4
+#define APCI1032_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// Hardware Layer functions for Apci1032
+
+//DI
+// for di read
+
+INT i_APCI1032_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1032_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+INT i_APCI1032_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+static void v_APCI1032_Interrupt(int irq, void *d);
+//Reset
+INT i_APCI1032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
new file mode 100644
index 00000000000..2d6adcff41e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c
@@ -0,0 +1,3045 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1500 | Compiler : GCC |
+ | Module name : hwdrv_apci1500.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1500 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+#include "hwdrv_apci1500.h"
+
+int i_TimerCounter1Init = 0;
+int i_TimerCounter2Init = 0;
+int i_WatchdogCounter3Init = 0;
+int i_Event1Status = 0, i_Event2Status = 0;
+int i_TimerCounterWatchdogInterrupt = 0;
+int i_Logic = 0, i_CounterLogic = 0;
+int i_InterruptMask = 0;
+int i_InputChannel = 0;
+int i_TimerCounter1Enabled = 0, i_TimerCounter2Enabled =
+ 0, i_WatchdogCounter3Enabled = 0;
+
+/*
+ +----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigDigitalInputEvent |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : An event can be generated for each port. |
+| The first event is related to the first 8 channels |
+| (port 1) and the second to the following 6 channels |
+| (port 2). An interrupt is generated when one or both |
+| events have occurred |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] :Number of the input port on |
+| which the event will take place |
+| (1 or 2)
+ data[1] : The event logic for port 1 has |
+| three possibilities |
+| :0 APCI1500_AND :This logic |
+| links |
+| the inputs |
+| with an AND |
+| logic. |
+| 1 APCI1500_OR :This logic |
+| links |
+| the inputs |
+| with a |
+| OR logic. |
+| 2 APCI1500_OR_PRIORITY |
+| :This logic |
+| links |
+| the inputs |
+| with a |
+| priority |
+| OR logic. |
+| Input 1 |
+| has the |
+| highest |
+| priority |
+| level and |
+| input 8 |
+| the smallest|
+| For the second port the user has|
+| 1 possibility: |
+| APCI1500_OR :This logic |
+| links |
+| the inputs |
+| with a |
+| polarity |
+| OR logic |
+| data[2] : These 8-character word for port1|
+| and 6-character word for port 2 |
+| give the mask of the event. |
+| Each place gives the state |
+| of the input channels and can |
+| have one of these six characters|
+| |
+| 0 : This input must be on 0 |
+| 1 : This input must be on 1 |
+| 2 : This input reacts to |
+| a falling edge |
+| 3 : This input reacts to a |
+| rising edge |
+| 4 : This input reacts to both edges |
+|
+| 5 : This input is not |
+| used for event |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ConfigDigitalInputEvent(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_PatternPolarity = 0, i_PatternTransition = 0, i_PatternMask = 0;
+ int i_MaxChannel = 0, i_Count = 0, i_EventMask = 0;
+ int i_PatternTransitionCount = 0, i_RegValue;
+ int i;
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Disables the main interrupt on the board */
+ /**********************************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ if (data[0] == 1) {
+ i_MaxChannel = 8;
+ } // if (data[0] == 1)
+ else {
+ if (data[0] == 2) {
+ i_MaxChannel = 6;
+ } // if(data[0]==2)
+ else {
+ printk("\nThe specified port event does not exist\n");
+ return -EINVAL;
+ } //else if(data[0]==2)
+ } //else if (data[0] == 1)
+ switch (data[1]) {
+ case 0:
+ data[1] = APCI1500_AND;
+ break;
+ case 1:
+ data[1] = APCI1500_OR;
+ break;
+ case 2:
+ data[1] = APCI1500_OR_PRIORITY;
+ break;
+ default:
+ printk("\nThe specified interrupt logic does not exist\n");
+ return -EINVAL;
+ } //switch(data[1]);
+
+ i_Logic = data[1];
+ for (i_Count = i_MaxChannel, i = 0; i_Count > 0; i_Count--, i++) {
+ i_EventMask = data[2 + i];
+ switch (i_EventMask) {
+ case 0:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ break;
+ case 1:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ i_PatternPolarity =
+ i_PatternPolarity | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 2:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ i_PatternTransition =
+ i_PatternTransition | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 3:
+ i_PatternMask =
+ i_PatternMask | (1 << (i_MaxChannel - i_Count));
+ i_PatternPolarity =
+ i_PatternPolarity | (1 << (i_MaxChannel -
+ i_Count));
+ i_PatternTransition =
+ i_PatternTransition | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 4:
+ i_PatternTransition =
+ i_PatternTransition | (1 << (i_MaxChannel -
+ i_Count));
+ break;
+ case 5:
+ break;
+ default:
+ printk("\nThe option indicated in the event mask does not exist\n");
+ return -EINVAL;
+ } // switch(i_EventMask)
+ } //for (i_Count = i_MaxChannel; i_Count >0;i_Count --)
+
+ if (data[0] == 1) {
+ /****************************/
+ /* Test the interrupt logic */
+ /****************************/
+
+ if (data[1] == APCI1500_AND ||
+ data[1] == APCI1500_OR ||
+ data[1] == APCI1500_OR_PRIORITY) {
+ /**************************************/
+ /* Tests if a transition was declared */
+ /* for a OR PRIORITY logic */
+ /**************************************/
+
+ if (data[1] == APCI1500_OR_PRIORITY
+ && i_PatternTransition != 0) {
+ /********************************************/
+ /* Transition error on an OR PRIORITY logic */
+ /********************************************/
+ printk("\nTransition error on an OR PRIORITY logic\n");
+ return -EINVAL;
+ } // if (data[1]== APCI1500_OR_PRIORITY && i_PatternTransition != 0)
+
+ /*************************************/
+ /* Tests if more than one transition */
+ /* was declared for an AND logic */
+ /*************************************/
+
+ if (data[1] == APCI1500_AND) {
+ for (i_Count = 0; i_Count < 8; i_Count++) {
+ i_PatternTransitionCount =
+ i_PatternTransitionCount +
+ ((i_PatternTransition >>
+ i_Count) & 0x1);
+
+ } //for (i_Count = 0; i_Count < 8; i_Count++)
+
+ if (i_PatternTransitionCount > 1) {
+ /****************************************/
+ /* Transition error on an AND logic */
+ /****************************************/
+ printk("\n Transition error on an AND logic\n");
+ return -EINVAL;
+ } // if (i_PatternTransitionCount > 1)
+ } // if (data[1]== APCI1500_AND)
+
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the polarity register of port 1 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_POLARITY,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternPolarity,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the pattern mask register of */
+ /* port 1 */
+ /*********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_MASK,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternMask,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /********************************************/
+ /* Selects the pattern transition register */
+ /* of port 1 */
+ /********************************************/
+ outb(APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternTransition,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 1 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 1 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Port A new mode */
+ /**********************/
+
+ i_RegValue = (i_RegValue & 0xF9) | data[1] | 0x9;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_Event1Status = 1;
+
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } // if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+ else {
+ printk("\nThe choice for interrupt logic does not exist\n");
+ return -EINVAL;
+ } // else }// if(data[1]==APCI1500_AND||data[1]==APCI1500_OR||data[1]==APCI1500_OR_PRIORITY)
+ } // if (data[0]== 1)
+
+ /************************************/
+ /* Test if event setting for port 2 */
+ /************************************/
+
+ if (data[0] == 2) {
+ /************************/
+ /* Test the event logic */
+ /************************/
+
+ if (data[1] == APCI1500_OR) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the mode specification mask */
+ /* register of port B */
+ /****************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port B */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = i_RegValue & 0xF9;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************************/
+ /* Selects error channels 1 and 2 */
+ /**********************************/
+
+ i_PatternMask = (i_PatternMask | 0xC0);
+ i_PatternPolarity = (i_PatternPolarity | 0xC0);
+ i_PatternTransition = (i_PatternTransition | 0xC0);
+
+ /**********************************************/
+ /* Selects the polarity register of port 2 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternPolarity,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the pattern transition register */
+ /* of port 2 */
+ /**********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternTransition,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Selects the pattern Mask register */
+ /* of port 2 */
+ /**********************************************/
+
+ outb(APCI1500_RW_PORT_B_PATTERN_MASK,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_PatternMask,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 2 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************/
+ /* Selects the mode specification mask */
+ /* register of port 2 */
+ /******************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = (i_RegValue & 0xF9) | 4;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_Event2Status = 1;
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } // if (data[1] == APCI1500_OR)
+ else {
+ printk("\nThe choice for interrupt logic does not exist\n");
+ return -EINVAL;
+ } //elseif (data[1] == APCI1500_OR)
+ } //if(data[0]==2)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_StartStopInputEvent |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Allows or disallows a port event |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
+ data[0] :0 Start input event
+ 1 Stop input event
+ data[1] :No of port (1 or 2)
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopInputEvent(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i_Event1InterruptStatus = 0, i_Event2InterruptStatus =
+ 0, i_RegValue;
+ switch (data[0]) {
+ case START:
+ /*************************/
+ /* Tests the port number */
+ /*************************/
+
+ if (data[1] == 1 || data[1] == 2) {
+ /***************************/
+ /* Test if port 1 selected */
+ /***************************/
+
+ if (data[1] == 1) {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if (i_Event1Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 1 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Allows the pattern interrupt */
+ /*************************************/
+ outb(0xC0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event1InterruptStatus = 1;
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } // if(i_Event1Status==1)
+ else {
+ printk("\nEvent 1 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event1Status==1)
+ } //if (data[1]==1)
+ if (data[1] == 2) {
+
+ if (i_Event2Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 2 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Allows the pattern interrupt */
+ /*************************************/
+ outb(0xC0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event2InterruptStatus = 1;
+ } // if(i_Event2Status==1)
+ else {
+ printk("\nEvent 2 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event2Status==1)
+ } // if(data[1]==2)
+ } // if (data[1] == 1 || data[0] == 2)
+ else {
+ printk("\nThe port parameter is in error\n");
+ return -EINVAL;
+ } //else if (data[1] == 1 || data[0] == 2)
+
+ break;
+
+ case STOP:
+ /*************************/
+ /* Tests the port number */
+ /*************************/
+
+ if (data[1] == 1 || data[1] == 2) {
+ /***************************/
+ /* Test if port 1 selected */
+ /***************************/
+
+ if (data[1] == 1) {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if (i_Event1Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port A */
+ /******************/
+ outb(0xF0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 1 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Inhibits the pattern interrupt */
+ /*************************************/
+ outb(0xE0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port A */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event1InterruptStatus = 0;
+ } // if(i_Event1Status==1)
+ else {
+ printk("\nEvent 1 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event1Status==1)
+ } //if (data[1]==1)
+ if (data[1] == 2) {
+ /*****************************/
+ /* Test if event initialised */
+ /*****************************/
+ if (i_Event2Status == 1) {
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************/
+ /* Disable Port B */
+ /******************/
+ outb(0x74,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the command and status register of */
+ /* port 2 */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************/
+ /* Inhibits the pattern interrupt */
+ /*************************************/
+ outb(0xE0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************************/
+ /* Selects the APCI1500_RW_MASTER_CONFIGURATION_CONTROL register */
+ /*****************************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************/
+ /* Enable Port B */
+ /*****************/
+ outb(0xF4,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_Event2InterruptStatus = 0;
+ } // if(i_Event2Status==1)
+ else {
+ printk("\nEvent 2 not initialised\n");
+ return -EINVAL;
+ } //else if(i_Event2Status==1)
+ } //if(data[1]==2)
+
+ } // if (data[1] == 1 || data[1] == 2)
+ else {
+ printk("\nThe port parameter is in error\n");
+ return -EINVAL;
+ } //else if (data[1] == 1 || data[1] == 2)
+ break;
+ default:
+ printk("\nThe option of START/STOP logic does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_Initialisation |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1500_Initialisation(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i_DummyRead = 0;
+ /******************/
+ /* Software reset */
+ /******************/
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the master configuration control register */
+ /*****************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data path polarity register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port A means 1 */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data direction register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port A: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port A */
+ outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data path polarity register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* A high level of port B means 1 */
+ outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port B: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port B */
+ outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the data path polarity register of port C */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port C means 1 */
+ outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port C */
+ outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs except channel 1 */
+ outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the special IO register of port C */
+ outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes it */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 1 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 1 */
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of timer 1 */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 2 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 2 */
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates Timer 2 interrupt management: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 3 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of Timer 3 */
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates interrupt management of timer 3: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes all interrupts */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer
+ data[0] : 0 Read a single channel
+ 1 read a port value
+ data[1] : port value
++----------------------------------------------------------------------------+
+| Output Parameters : -- data[0] :The read status value
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_PortValue = data[1];
+ UINT ui_Mask = 0;
+ UINT ui_Channel;
+ UINT ui_TmpValue = 0;
+ ui_Channel = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case 0:
+ if (ui_Channel >= 0 && ui_Channel <= 15) {
+ ui_TmpValue =
+ (UINT) inw(devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_IP);
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=15)
+ else {
+ printk("\nThe channel specification are in error\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=15)
+ break;
+ case 1:
+
+ *data = (UINT) inw(devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_IP);
+ switch (ui_Channel) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 8:
+ ui_Mask = 255;
+ *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+ break;
+ case 15:
+ break;
+
+ default:
+ printk("\nSpecified channel cannot be read \n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_Channel)
+ break;
+ default:
+ printk("\nThe specified functionality does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigDigitalOutputErrorInterrupt
+ (struct comedi_device *dev,struct comedi_subdevice *s struct comedi_insn
+ *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures the digital output memory and the digital
+ output error interrupt |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+ data[1] :1 Enable the voltage error interrupt
+| :0 Disable the voltage error interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->b_OutputMemoryStatus = data[0];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ static UINT ui_Temp = 0;
+ UINT ui_Temp1;
+
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ if (!devpriv->b_OutputMemoryStatus) {
+ ui_Temp = 0;
+
+ } //if(!devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0],
+ devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 15:
+ data[0] = data[0] | ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->i_IobaseAddon +
+ APCI1500_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ ui_Temp = data[0];
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigCounterTimerWatchdog(comedi_device
+ *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status data[0] : 2 APCI1500_1_8_KHZ
+| 1 APCI1500_3_6_KHZ |
+| 0 APCI1500_115_KHZ
+ data[1] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+ data[2] : 0 Counter
+ 1 Timer/Watchdog
+ data[3] : This parameter has |
+| two meanings. |
+| - If the counter/timer |
+| is used as a counter |
+| the limit value of |
+| the counter is given |
+| |
+| - If the counter/timer |
+| is used as a timer, |
+| the divider factor |
+| for the output is |
+| given.
+ data[4] : 0 APCI1500_CONTINUOUS
+ 1 APCI1500_SINGLE
+ data[5] : 0 Software Trigger
+ 1 Hardware Trigger
+
+ data[6] :0 Software gate
+ 1 Hardware gate
+ data[7] :0 Interrupt Disable
+ 1 Interrupt Enable
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_TimerCounterMode, i_MasterConfiguration;
+
+ devpriv->tsk_Current = current;
+
+//Selection of the input clock
+ if (data[0] == 0 || data[0] == 1 || data[0] == 2) {
+ outw(data[0], devpriv->i_IobaseAddon + APCI1500_CLK_SELECT);
+ } // if(data[0]==0||data[0]==1||data[0]==2)
+ else {
+ if (data[0] != 3) {
+ printk("\nThe option for input clock selection does not exist\n");
+ return -EINVAL;
+ } // if(data[0]!=3)
+ } //elseif(data[0]==0||data[0]==1||data[0]==2)
+ //Select the counter/timer
+ switch (data[1]) {
+ case COUNTER1:
+ //selecting counter or timer
+ switch (data[2]) {
+ case 0:
+ data[2] = APCI1500_COUNTER;
+ break;
+ case 1:
+ data[2] = APCI1500_TIMER;
+ break;
+ default:
+ printk("\nThis choice is not a timer nor a counter\n");
+ return -EINVAL;
+ } // switch(data[2])
+
+ //Selecting single or continuous mode
+ switch (data[4]) {
+ case 0:
+ data[4] = APCI1500_CONTINUOUS;
+ break;
+ case 1:
+ data[4] = APCI1500_SINGLE;
+ break;
+ default:
+ printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ } // switch(data[4])
+
+ i_TimerCounterMode = data[2] | data[4] | 7;
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3] >= 0) && (data[3] <= 65535)) {
+ if (data[7] == APCI1500_ENABLE
+ || data[7] == APCI1500_DISABLE) {
+
+ /************************************************/
+ /* Selects the mode register of timer/counter 1 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 1 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 1 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3] = data[3] >> 8;
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables timer/counter 1 and triggers timer/counter 1 */
+ /********************************************************/
+
+ i_MasterConfiguration =
+ i_MasterConfiguration | 0x40;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 1 */
+ /****************************************/
+
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Disable timer/counter 1 */
+ /***************************/
+
+ outb(0x0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 1 */
+ /****************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Trigger timer/counter 1 */
+ /***************************/
+ outb(0x2,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ } //elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ } // if ((data[3]>= 0) && (data[3] <= 65535))
+ else {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ } //else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt = data[7];
+ i_TimerCounter1Init = 1;
+ break;
+
+ case COUNTER2: //selecting counter or timer
+ switch (data[2]) {
+ case 0:
+ data[2] = APCI1500_COUNTER;
+ break;
+ case 1:
+ data[2] = APCI1500_TIMER;
+ break;
+ default:
+ printk("\nThis choice is not a timer nor a counter\n");
+ return -EINVAL;
+ } // switch(data[2])
+
+ //Selecting single or continuous mode
+ switch (data[4]) {
+ case 0:
+ data[4] = APCI1500_CONTINUOUS;
+ break;
+ case 1:
+ data[4] = APCI1500_SINGLE;
+ break;
+ default:
+ printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ } // switch(data[4])
+
+ //Selecting software or hardware trigger
+ switch (data[5]) {
+ case 0:
+ data[5] = APCI1500_SOFTWARE_TRIGGER;
+ break;
+ case 1:
+ data[5] = APCI1500_HARDWARE_TRIGGER;
+ break;
+ default:
+ printk("\nThis choice for software or hardware trigger does not exist\n");
+ return -EINVAL;
+ } // switch(data[5])
+
+ //Selecting software or hardware gate
+ switch (data[6]) {
+ case 0:
+ data[6] = APCI1500_SOFTWARE_GATE;
+ break;
+ case 1:
+ data[6] = APCI1500_HARDWARE_GATE;
+ break;
+ default:
+ printk("\nThis choice for software or hardware gate does not exist\n");
+ return -EINVAL;
+ } // switch(data[6])
+
+ i_TimerCounterMode = data[2] | data[4] | data[5] | data[6] | 7;
+
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3] >= 0) && (data[3] <= 65535)) {
+ if (data[7] == APCI1500_ENABLE
+ || data[7] == APCI1500_DISABLE) {
+
+ /************************************************/
+ /* Selects the mode register of timer/counter 2 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 2 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of timer/counter 2 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3] = data[3] >> 8;
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables timer/counter 2 and triggers timer/counter 2 */
+ /********************************************************/
+
+ i_MasterConfiguration =
+ i_MasterConfiguration | 0x20;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 2 */
+ /****************************************/
+
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Disable timer/counter 2 */
+ /***************************/
+
+ outb(0x0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /****************************************/
+ /* Selects the commands register of */
+ /* timer/counter 2 */
+ /****************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Trigger timer/counter 1 */
+ /***************************/
+ outb(0x2,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ } //elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ } // if ((data[3]>= 0) && (data[3] <= 65535))
+ else {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ } //else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt = data[7];
+ i_TimerCounter2Init = 1;
+ break;
+
+ case COUNTER3: //selecting counter or watchdog
+ switch (data[2]) {
+ case 0:
+ data[2] = APCI1500_COUNTER;
+ break;
+ case 1:
+ data[2] = APCI1500_WATCHDOG;
+ break;
+ default:
+ printk("\nThis choice is not a watchdog nor a counter\n");
+ return -EINVAL;
+ } // switch(data[2])
+
+ //Selecting single or continuous mode
+ switch (data[4]) {
+ case 0:
+ data[4] = APCI1500_CONTINUOUS;
+ break;
+ case 1:
+ data[4] = APCI1500_SINGLE;
+ break;
+ default:
+ printk("\nThis option for single/continuous mode does not exist\n");
+ return -EINVAL;
+ } // switch(data[4])
+
+ //Selecting software or hardware gate
+ switch (data[6]) {
+ case 0:
+ data[6] = APCI1500_SOFTWARE_GATE;
+ break;
+ case 1:
+ data[6] = APCI1500_HARDWARE_GATE;
+ break;
+ default:
+ printk("\nThis choice for software or hardware gate does not exist\n");
+ return -EINVAL;
+ } // switch(data[6])
+
+ /*****************************/
+ /* Test if used for watchdog */
+ /*****************************/
+
+ if (data[2] == APCI1500_WATCHDOG) {
+ /*****************************/
+ /* - Enables the output line */
+ /* - Enables retrigger */
+ /* - Pulses output */
+ /*****************************/
+ i_TimerCounterMode = data[2] | data[4] | 0x54;
+ } //if (data[2] == APCI1500_WATCHDOG)
+ else {
+ i_TimerCounterMode = data[2] | data[4] | data[6] | 7;
+ } //elseif (data[2] == APCI1500_WATCHDOG)
+ /*************************/
+ /* Test the reload value */
+ /*************************/
+
+ if ((data[3] >= 0) && (data[3] <= 65535)) {
+ if (data[7] == APCI1500_ENABLE
+ || data[7] == APCI1500_DISABLE) {
+
+ /************************************************/
+ /* Selects the mode register of watchdog/counter 3 */
+ /************************************************/
+ outb(APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************/
+ /* Writes the new mode */
+ /***********************/
+ outb(i_TimerCounterMode,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of watchdog/counter 3 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************/
+ /* Writes the low value */
+ /*************************/
+
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /****************************************************/
+ /* Selects the constant register of watchdog/counter 3 */
+ /****************************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**************************/
+ /* Writes the high value */
+ /**************************/
+
+ data[3] = data[3] >> 8;
+ outb(data[3],
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /**********************/
+ /* Reads the register */
+ /**********************/
+
+ i_MasterConfiguration =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************************************/
+ /* Enables watchdog/counter 3 and triggers watchdog/counter 3 */
+ /********************************************************/
+
+ i_MasterConfiguration =
+ i_MasterConfiguration | 0x10;
+
+ /*********************************************/
+ /* Selects the master configuration register */
+ /*********************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************************/
+ /* Writes the new configuration */
+ /********************************/
+ outb(i_MasterConfiguration,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /********************/
+ /* Test if COUNTER */
+ /********************/
+ if (data[2] == APCI1500_COUNTER) {
+
+ /*************************************/
+ /* Selects the command register of */
+ /* watchdog/counter 3 */
+ /*************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Disable the watchdog/counter 3 and starts it */
+ /*************************************************/
+ outb(0x0,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************************/
+ /* Selects the command register of */
+ /* watchdog/counter 3 */
+ /*************************************/
+
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Trigger the watchdog/counter 3 and starts it */
+ /*************************************************/
+ outb(0x2,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } //elseif(data[2]==APCI1500_COUNTER)
+
+ } //if(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ else {
+ printk("\nError in selection of interrupt enable or disable\n");
+ return -EINVAL;
+ } //elseif(data[7]== APCI1500_ENABLE ||data[7]== APCI1500_DISABLE)
+ } // if ((data[3]>= 0) && (data[3] <= 65535))
+ else {
+ printk("\nError in selection of reload value\n");
+ return -EINVAL;
+ } //else if ((data[3]>= 0) && (data[3] <= 65535))
+ i_TimerCounterWatchdogInterrupt = data[7];
+ i_WatchdogCounter3Init = 1;
+ break;
+
+ default:
+ printk("\nThe specified counter\timer option does not exist\n");
+ } //switch(data[1])
+ i_CounterLogic = data[2];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_StartStopTriggerTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Start / Stop or trigger the timer counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
+ data[0] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+ data[1] : 0 start
+ 1 stop
+ 2 Trigger
+ data[2] : 0 Counter
+ 1 Timer/Watchdog
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_CommandAndStatusValue;
+
+ switch (data[0]) {
+ case COUNTER1:
+ switch (data[1]) {
+ case START:
+ if (i_TimerCounter1Init == 1) {
+ if (i_TimerCounterWatchdogInterrupt == 1) {
+ i_CommandAndStatusValue = 0xC4; //Enable the interrupt
+ } // if(i_TimerCounterWatchdogInterrupt==1)
+ else {
+ i_CommandAndStatusValue = 0xE4; //disable the interrupt
+ } //elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts timer/counter 1 */
+ /**************************/
+ i_TimerCounter1Enabled = 1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter1Init==1)
+ else {
+ printk("\nCounter/Timer1 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP:
+
+ /**************************/
+ /* Stop timer/counter 1 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_TimerCounter1Enabled = 0;
+ break;
+
+ case TRIGGER:
+ if (i_TimerCounter1Init == 1) {
+ if (i_TimerCounter1Enabled == 1) {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ } //if( i_TimerCounter1Enabled==1)
+ else {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ } //elseif(i_TimerCounter1Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter1Init==1)
+ else {
+ printk("\nCounter/Timer1 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ default:
+ printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ } //switch(data[1])
+ break;
+
+ case COUNTER2:
+ switch (data[1]) {
+ case START:
+ if (i_TimerCounter2Init == 1) {
+ if (i_TimerCounterWatchdogInterrupt == 1) {
+ i_CommandAndStatusValue = 0xC4; //Enable the interrupt
+ } // if(i_TimerCounterWatchdogInterrupt==1)
+ else {
+ i_CommandAndStatusValue = 0xE4; //disable the interrupt
+ } //elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts timer/counter 2 */
+ /**************************/
+ i_TimerCounter2Enabled = 1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter2Init==1)
+ else {
+ printk("\nCounter/Timer2 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP:
+
+ /**************************/
+ /* Stop timer/counter 2 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_TimerCounter2Enabled = 0;
+ break;
+ case TRIGGER:
+ if (i_TimerCounter2Init == 1) {
+ if (i_TimerCounter2Enabled == 1) {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ } //if( i_TimerCounter2Enabled==1)
+ else {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ } //elseif(i_TimerCounter2Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter2Init==1)
+ else {
+ printk("\nCounter/Timer2 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ } //switch(data[1])
+ break;
+ case COUNTER3:
+ switch (data[1]) {
+ case START:
+ if (i_WatchdogCounter3Init == 1) {
+
+ if (i_TimerCounterWatchdogInterrupt == 1) {
+ i_CommandAndStatusValue = 0xC4; //Enable the interrupt
+ } // if(i_TimerCounterWatchdogInterrupt==1)
+ else {
+ i_CommandAndStatusValue = 0xE4; //disable the interrupt
+ } //elseif(i_TimerCounterWatchdogInterrupt==1)
+ /**************************/
+ /* Starts Watchdog/counter 3 */
+ /**************************/
+ i_WatchdogCounter3Enabled = 1;
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ } // if( i_WatchdogCounter3init==1)
+ else {
+ printk("\nWatchdog/Counter3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+
+ case STOP:
+
+ /**************************/
+ /* Stop Watchdog/counter 3 */
+ /**************************/
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x00,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_WatchdogCounter3Enabled = 0;
+ break;
+
+ case TRIGGER:
+ switch (data[2]) {
+ case 0: //triggering counter 3
+ if (i_WatchdogCounter3Init == 1) {
+ if (i_WatchdogCounter3Enabled == 1) {
+ /************************/
+ /* Set Trigger and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0x6;
+ } //if( i_WatchdogCounter3Enabled==1)
+ else {
+ /***************/
+ /* Set Trigger */
+ /***************/
+
+ i_CommandAndStatusValue = 0x2;
+ } //elseif(i_WatchdogCounter3Enabled==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_WatchdogCounter3Init==1)
+ else {
+ printk("\nCounter3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ case 1:
+ //triggering Watchdog 3
+ if (i_WatchdogCounter3Init == 1) {
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x6,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_WatchdogCounter3Init==1)
+ else {
+ printk("\nWatchdog 3 not configured\n");
+ return -EINVAL;
+ }
+ break;
+ default:
+ printk("\nWrong choice of watchdog/counter3\n");
+ return -EINVAL;
+ } //switch(data[2])
+ break;
+ default:
+ printk("\nThe specified option for start/stop/trigger does not exist\n");
+ return -EINVAL;
+ } //switch(data[1])
+ break;
+ default:
+ printk("\nThe specified choice for counter/watchdog/timer does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadCounterTimerWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
+ data[0] : 0 Counter1/Timer1
+ 1 Counter2/Timer2
+ 2 Counter3/Watchdog
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i_CommandAndStatusValue;
+ switch (data[0]) {
+ case COUNTER1:
+ //Read counter/timer1
+ if (i_TimerCounter1Init == 1) {
+ if (i_TimerCounter1Enabled == 1) {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ } //if( i_TimerCounter1Init==1)
+ else {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ } //elseif(i_TimerCounter1Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR1_VALUE_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] = data[0] << 8;
+ data[0] = data[0] & 0xff00;
+ outb(APCI1500_R_CPT_TMR1_VALUE_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ data[0] | inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter1Init==1)
+ else {
+ printk("\nTimer/Counter1 not configured\n");
+ return -EINVAL;
+ } //elseif( i_TimerCounter1Init==1)
+ break;
+ case COUNTER2:
+ //Read counter/timer2
+ if (i_TimerCounter2Init == 1) {
+ if (i_TimerCounter2Enabled == 1) {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ } //if( i_TimerCounter2Init==1)
+ else {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ } //elseif(i_TimerCounter2Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR2_VALUE_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] = data[0] << 8;
+ data[0] = data[0] & 0xff00;
+ outb(APCI1500_R_CPT_TMR2_VALUE_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ data[0] | inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_TimerCounter2Init==1)
+ else {
+ printk("\nTimer/Counter2 not configured\n");
+ return -EINVAL;
+ } //elseif( i_TimerCounter2Init==1)
+ break;
+ case COUNTER3:
+ //Read counter/watchdog2
+ if (i_WatchdogCounter3Init == 1) {
+ if (i_WatchdogCounter3Enabled == 1) {
+ /************************/
+ /* Set RCC and gate */
+ /************************/
+
+ i_CommandAndStatusValue = 0xC;
+ } //if( i_TimerCounter2Init==1)
+ else {
+ /***************/
+ /* Set RCC */
+ /***************/
+
+ i_CommandAndStatusValue = 0x8;
+ } //elseif(i_WatchdogCounter3Init==1)
+
+ /********************************************/
+ /* Selects the commands and status register */
+ /********************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_CommandAndStatusValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************/
+ /* Selects the counter register (high) */
+ /***************************************/
+ outb(APCI1500_R_CPT_TMR3_VALUE_HIGH,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] = data[0] << 8;
+ data[0] = data[0] & 0xff00;
+ outb(APCI1500_R_CPT_TMR3_VALUE_LOW,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ data[0] =
+ data[0] | inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ } //if( i_WatchdogCounter3Init==1)
+ else {
+ printk("\nWatchdogCounter3 not configured\n");
+ return -EINVAL;
+ } //elseif( i_WatchdogCounter3Init==1)
+ break;
+ default:
+ printk("\nThe choice of timer/counter/watchdog does not exist\n");
+ return -EINVAL;
+ } //switch(data[0])
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ReadInterruptMask |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read the interrupt mask |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- data[0]:The interrupt mask value data[1]:Channel no
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ReadInterruptMask(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = i_InterruptMask;
+ data[1] = i_InputChannel;
+ i_InterruptMask = 0;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_ConfigureInterrupt |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Configures the interrupt registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer |
+
+
++----------------------------------------------------------------------------+
+| Output Parameters : --
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1500_ConfigureInterrupt(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Status;
+ int i_RegValue;
+ int i_Constant;
+ devpriv->tsk_Current = current;
+ outl(0x0, devpriv->i_IobaseAmcc + 0x38);
+ if (data[0] == 1) {
+ i_Constant = 0xC0;
+ } //if(data[0]==1)
+ else {
+ if (data[0] == 0) {
+ i_Constant = 0x00;
+ } //if{data[0]==0)
+ else {
+ printk("\nThe parameter passed to driver is in error for enabling the voltage interrupt\n");
+ return -EINVAL;
+ } //else if(data[0]==0)
+ } //elseif(data[0]==1)
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*********************************************/
+ /* Writes the new configuration (APCI1500_OR) */
+ /*********************************************/
+ i_RegValue = (i_RegValue & 0xF9) | APCI1500_OR;
+
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************/
+ /* Authorises the interrupt on the board */
+ /*****************************************/
+ outb(0xC0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***************************************************/
+ /* Selects the pattern polarity register of port B */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the pattern transition register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************************/
+ /* Selects the pattern mask register of port B */
+ /***********************************************/
+ outb(APCI1500_RW_PORT_B_PATTERN_MASK,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(i_Constant, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port A */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port B */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 1 */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 2 */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 3 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 3 */
+ /***********************************/
+
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************/
+ /* Enables the PCI interrupt */
+ /*****************************/
+ outl(0x3000, devpriv->i_IobaseAmcc + 0x38);
+ ui_Status = inl(devpriv->i_IobaseAmcc + 0x10);
+ ui_Status = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(0x23000, devpriv->i_IobaseAmcc + 0x38);
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1500_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1500_Interrupt(int irq, void *d)
+{
+
+ struct comedi_device *dev = d;
+ UINT ui_InterruptStatus = 0;
+ int i_RegValue = 0;
+ i_InterruptMask = 0;
+
+ /***********************************/
+ /* Read the board interrupt status */
+ /***********************************/
+ ui_InterruptStatus = inl(devpriv->i_IobaseAmcc + 0x38);
+
+ /***************************************/
+ /* Test if board generated a interrupt */
+ /***************************************/
+ if ((ui_InterruptStatus & 0x800000) == 0x800000) {
+ /************************/
+ /* Disable all Interrupt */
+ /************************/
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ //outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Disables the main interrupt on the board */
+ /**********************************************/
+ //outb(0x00,devpriv->iobase+APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port A */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 1;
+ if (i_Logic == APCI1500_OR_PRIORITY) {
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ /***************************************************/
+ /* Selects the interrupt vector register of port A */
+ /***************************************************/
+ outb(APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+
+ i_InputChannel = 1 + (i_RegValue >> 1);
+
+ } // if(i_Logic==APCI1500_OR_PRIORITY)
+ else {
+ i_InputChannel = 0;
+ } //elseif(i_Logic==APCI1500_OR_PRIORITY)
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of port B */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ printk("\n\n\n");
+ /****************/
+ /* Reads port B */
+ /****************/
+ i_RegValue =
+ inb((UINT) devpriv->iobase +
+ APCI1500_Z8536_PORT_B);
+
+ i_RegValue = i_RegValue & 0xC0;
+ /**************************************/
+ /* Tests if this is an external error */
+ /**************************************/
+
+ if (i_RegValue) {
+ //Disable the interrupt
+ /*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outl(0x0, devpriv->i_IobaseAmcc + 0x38);
+
+ if (i_RegValue & 0x80) {
+ i_InterruptMask =
+ i_InterruptMask | 0x40;
+ } //if (i_RegValue & 0x80)
+
+ if (i_RegValue & 0x40) {
+ i_InterruptMask =
+ i_InterruptMask | 0x80;
+ } //if (i_RegValue & 0x40)
+ } // if (i_RegValue)
+ else {
+ i_InterruptMask = i_InterruptMask | 2;
+ } // if (i_RegValue)
+ } //if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 1 */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 4;
+ } // if ((i_RegValue & 0x60) == 0x60)
+ /*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 2 */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ i_InterruptMask = i_InterruptMask | 8;
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ /*****************************************************/
+ /* Selects the command and status register of timer 3 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_RegValue =
+ inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ if ((i_RegValue & 0x60) == 0x60) {
+ /*****************************************************/
+ /* Selects the command and status register of timer 3 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ /***********************************/
+ /* Deletes the interrupt of timer 3 */
+ /***********************************/
+ i_RegValue = (i_RegValue & 0x0F) | 0x20;
+ outb(i_RegValue,
+ devpriv->iobase +
+ APCI1500_Z8536_CONTROL_REGISTER);
+ if (i_CounterLogic == APCI1500_COUNTER) {
+ i_InterruptMask = i_InterruptMask | 0x10;
+ } //if(i_CounterLogic==APCI1500_COUNTER)
+ else {
+ i_InterruptMask = i_InterruptMask | 0x20;
+ }
+ } // if ((i_RegValue & 0x60) == 0x60)
+
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ /***********************/
+ /* Enable all Interrupts */
+ /***********************/
+
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /**********************************************/
+ /* Authorizes the main interrupt on the board */
+ /**********************************************/
+ outb(0xD0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ } // if ((ui_InterruptStatus & 0x800000) == 0x800000)
+ else {
+ printk("\nInterrupt from unknown source\n");
+
+ } //else if ((ui_InterruptStatus & 0x800000) == 0x800000)
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1500_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1500_Reset(struct comedi_device * dev)
+{
+ int i_DummyRead = 0;
+ i_TimerCounter1Init = 0;
+ i_TimerCounter2Init = 0;
+ i_WatchdogCounter3Init = 0;
+ i_Event1Status = 0;
+ i_Event2Status = 0;
+ i_TimerCounterWatchdogInterrupt = 0;
+ i_Logic = 0;
+ i_CounterLogic = 0;
+ i_InterruptMask = 0;
+ i_InputChannel = 0;;
+ i_TimerCounter1Enabled = 0;
+ i_TimerCounter2Enabled = 0;
+ i_WatchdogCounter3Enabled = 0;
+
+ /******************/
+ /* Software reset */
+ /******************/
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ i_DummyRead = inb(devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(1, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the master configuration control register */
+ /*****************************************************/
+ outb(APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0xF4, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data path polarity register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port A means 1 */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /* Selects the data direction register of port A */
+ outb(APCI1500_RW_PORT_A_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port A */
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port A: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port A */
+ outb(APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the mode specification register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ outb(0x10, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data path polarity register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* A high level of port B means 1 */
+ outb(0x7F, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port B */
+ outb(APCI1500_RW_PORT_B_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs */
+ outb(0xFF, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of port B */
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of port B: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the handshake specification register of port B */
+ outb(APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes the register */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+
+ /*****************************************************/
+ /* Selects the data path polarity register of port C */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* High level of port C means 1 */
+ outb(0x9, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the data direction register of port C */
+ outb(APCI1500_RW_PORT_C_DATA_DIRECTION,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* All bits used as inputs except channel 1 */
+ outb(0x0E, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the special IO register of port C */
+ outb(APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes it */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 1 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 1 */
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates the interrupt management of timer 1 */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 2 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of timer 2 */
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates Timer 2 interrupt management: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /******************************************************/
+ /* Selects the command and status register of timer 3 */
+ /******************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes IP and IUS */
+ outb(0x20, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Selects the command and status register of Timer 3 */
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deactivates interrupt management of timer 3: */
+ outb(0xE0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /* Deletes all interrupts */
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ //reset all the digital outputs
+ outw(0x0, devpriv->i_IobaseAddon + APCI1500_DIGITAL_OP);
+/*******************************/
+/* Disable the board interrupt */
+/*******************************/
+ /*************************************************/
+ /* Selects the master interrupt control register */
+ /*************************************************/
+ outb(APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ /*****************************************************/
+ /* Selects the command and status register of port A */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of port B */
+ /*****************************************************/
+ outb(APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of timer 1 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+ /* Selects the command and status register of timer 2 */
+ /*****************************************************/
+ outb(APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/*****************************************************/
+/* Selects the command and status register of timer 3*/
+/*****************************************************/
+ outb(APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+/****************************/
+/* Deactivates all interrupts */
+/******************************/
+ outb(0x00, devpriv->iobase + APCI1500_Z8536_CONTROL_REGISTER);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
new file mode 100644
index 00000000000..5d960b40a6a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/********* Definitions for APCI-1500 card *****/
+
+// Card Specific information
+#define APCI1500_BOARD_VENDOR_ID 0x10e8
+#define APCI1500_ADDRESS_RANGE 4
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI1500_DIGITAL_OP 2
+#define APCI1500_DIGITAL_IP 0
+#define APCI1500_AND 2
+#define APCI1500_OR 4
+#define APCI1500_OR_PRIORITY 6
+#define APCI1500_CLK_SELECT 0
+#define COUNTER1 0
+#define COUNTER2 1
+#define COUNTER3 2
+#define APCI1500_COUNTER 0x20
+#define APCI1500_TIMER 0
+#define APCI1500_WATCHDOG 0
+#define APCI1500_SINGLE 0
+#define APCI1500_CONTINUOUS 0x80
+#define APCI1500_DISABLE 0
+#define APCI1500_ENABLE 1
+#define APCI1500_SOFTWARE_TRIGGER 0x4
+#define APCI1500_HARDWARE_TRIGGER 0x10
+#define APCI1500_SOFTWARE_GATE 0
+#define APCI1500_HARDWARE_GATE 0x8
+#define START 0
+#define STOP 1
+#define TRIGGER 2
+
+/*
+ * Zillog I/O enumeration
+ */
+enum {
+ APCI1500_Z8536_PORT_C,
+ APCI1500_Z8536_PORT_B,
+ APCI1500_Z8536_PORT_A,
+ APCI1500_Z8536_CONTROL_REGISTER
+};
+
+/*
+ * Z8536 CIO Internal Address
+ */
+enum {
+ APCI1500_RW_MASTER_INTERRUPT_CONTROL,
+ APCI1500_RW_MASTER_CONFIGURATION_CONTROL,
+ APCI1500_RW_PORT_A_INTERRUPT_CONTROL,
+ APCI1500_RW_PORT_B_INTERRUPT_CONTROL,
+ APCI1500_RW_TIMER_COUNTER_INTERRUPT_VECTOR,
+ APCI1500_RW_PORT_C_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_C_DATA_DIRECTION,
+ APCI1500_RW_PORT_C_SPECIAL_IO_CONTROL,
+
+ APCI1500_RW_PORT_A_COMMAND_AND_STATUS,
+ APCI1500_RW_PORT_B_COMMAND_AND_STATUS,
+ APCI1500_RW_CPT_TMR1_CMD_STATUS,
+ APCI1500_RW_CPT_TMR2_CMD_STATUS,
+ APCI1500_RW_CPT_TMR3_CMD_STATUS,
+ APCI1500_RW_PORT_A_DATA,
+ APCI1500_RW_PORT_B_DATA,
+ APCI1500_RW_PORT_C_DATA,
+
+ APCI1500_R_CPT_TMR1_VALUE_HIGH,
+ APCI1500_R_CPT_TMR1_VALUE_LOW,
+ APCI1500_R_CPT_TMR2_VALUE_HIGH,
+ APCI1500_R_CPT_TMR2_VALUE_LOW,
+ APCI1500_R_CPT_TMR3_VALUE_HIGH,
+ APCI1500_R_CPT_TMR3_VALUE_LOW,
+ APCI1500_RW_CPT_TMR1_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR1_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR2_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR2_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR3_TIME_CST_HIGH,
+ APCI1500_RW_CPT_TMR3_TIME_CST_LOW,
+ APCI1500_RW_CPT_TMR1_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR2_MODE_SPECIFICATION,
+ APCI1500_RW_CPT_TMR3_MODE_SPECIFICATION,
+ APCI1500_R_CURRENT_VECTOR,
+
+ APCI1500_RW_PORT_A_SPECIFICATION,
+ APCI1500_RW_PORT_A_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_A_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_A_DATA_DIRECTION,
+ APCI1500_RW_PORT_A_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_A_PATTERN_POLARITY,
+ APCI1500_RW_PORT_A_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_A_PATTERN_MASK,
+
+ APCI1500_RW_PORT_B_SPECIFICATION,
+ APCI1500_RW_PORT_B_HANDSHAKE_SPECIFICATION,
+ APCI1500_RW_PORT_B_DATA_PCITCH_POLARITY,
+ APCI1500_RW_PORT_B_DATA_DIRECTION,
+ APCI1500_RW_PORT_B_SPECIAL_IO_CONTROL,
+ APCI1500_RW_PORT_B_PATTERN_POLARITY,
+ APCI1500_RW_PORT_B_PATTERN_TRANSITION,
+ APCI1500_RW_PORT_B_PATTERN_MASK
+};
+
+ /*----------DIGITAL INPUT----------------*/
+static int i_APCI1500_Initialisation(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int i_APCI1500_ConfigDigitalInputEvent(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+
+static int i_APCI1500_StartStopInputEvent(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int i_APCI1500_ReadMoreDigitalInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*---------- DIGITAL OUTPUT------------*/
+static int i_APCI1500_ConfigDigitalOutputErrorInterrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_WriteDigitalOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*----------TIMER----------------*/
+static int i_APCI1500_ConfigCounterTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_StartStopTriggerTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_ReadCounterTimerWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+static int i_APCI1500_ReadInterruptMask(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*----------INTERRUPT HANDLER------*/
+static void v_APCI1500_Interrupt(int irq, void *d);
+static int i_APCI1500_ConfigureInterrupt(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+/*----------RESET---------------*/
+static int i_APCI1500_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
new file mode 100644
index 00000000000..5ae9a93844e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c
@@ -0,0 +1,542 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1516 | Compiler : GCC |
+ | Module name : hwdrv_apci1516.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1516 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci1516.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1516_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 7) {
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=7)
+ else {
+ //comedi_error(dev," \n chan spec wrong\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=7)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+
+ *data = (UINT) inw(devpriv->iobase + APCI1516_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 7:
+ break;
+
+ default:
+ printk("\nWrong parameters\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_NoOfChannels)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ConfigDigitalOutput (struct comedi_device *dev,
+ struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI1516_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->b_OutputMemoryStatus = data[0];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ printk("EL311003 : @=%x\n", devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inw(devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0], devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n", data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 7:
+ data[0] = data[0] | ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n", data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n", data[0],
+ devpriv->iobase + APCI1516_DIGITAL_OP);
+
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xff) & ui_Temp;
+ break;
+
+ case 7:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase +
+ APCI1516_DIGITAL_OP);
+
+ printk("EL311003 : d=%d @=%x\n",
+ data[0],
+ devpriv->iobase +
+ APCI1516_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Temp;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ ui_Temp = data[0];
+ *data = inw(devpriv->iobase + APCI1516_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if(ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 7:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if(ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif(ui_Temp==1)
+ } //elseif(ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ConfigWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outw(0x0,
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_RELOAD_VALUE);
+ data[1] = data[1] >> 16;
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_RELOAD_VALUE + 2);
+ } //if(data[0]==0)
+ else {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ } //elseif(data[0]==0)
+
+ return insn->n;
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI1516_StartStopWriteWatchdog |
+ | (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
+ +----------------------------------------------------------------------------+
+ | Task : Start / Stop The Watchdog |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+ | unsigned int *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+ */
+
+int i_APCI1516_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outw(0x0001,
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2: //Software trigger
+ outw(0x0201,
+ devpriv->i_IobaseAddon +
+ APCI1516_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1516_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = inw(devpriv->i_IobaseAddon + APCI1516_WATCHDOG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1516_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1516_Reset(struct comedi_device * dev)
+{
+ outw(0x0, devpriv->iobase + APCI1516_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_ENABLEDISABLE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI1516_WATCHDOG_RELOAD_VALUE + 2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
new file mode 100644
index 00000000000..398baa04a16
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/********* Definitions for APCI-1516 card *****/
+
+// Card Specific information
+#define APCI1516_BOARD_VENDOR_ID 0x15B8
+#define APCI1516_ADDRESS_RANGE 8
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI1516_DIGITAL_OP 4
+#define APCI1516_DIGITAL_OP_RW 4
+#define APCI1516_DIGITAL_IP 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG 2
+#define APCI1516_DIGITAL_OP_WATCHDOG 0
+#define APCI1516_WATCHDOG_ENABLEDISABLE 12
+#define APCI1516_WATCHDOG_RELOAD_VALUE 4
+#define APCI1516_WATCHDOG_STATUS 16
+
+// Hardware Layer functions for Apci1516
+
+//Digital Input
+INT i_APCI1516_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//Digital Output
+int i_APCI1516_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1516_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+int i_APCI1516_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1516_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1516_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//reset
+INT i_APCI1516_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
new file mode 100644
index 00000000000..a6b504c3d39
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.c
@@ -0,0 +1,1105 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-1564 | Compiler : GCC |
+ | Module name : hwdrv_apci1564.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-1564 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include <linux/delay.h>
+#include "hwdrv_apci1564.h"
+
+//Global variables
+UINT ui_InterruptStatus_1564 = 0;
+UINT ui_InterruptData, ui_Type;
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures the digital input Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Enable Digital Input Interrupt |
+| 0 Disable Digital Input Interrupt |
+| data[1] : 0 ADDIDATA Interrupt OR LOGIC |
+| : 1 ADDIDATA Interrupt AND LOGIC |
+| data[2] : Interrupt mask for the mode 1 |
+| data[3] : Interrupt mask for the mode 2 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->tsk_Current = current;
+ /*******************************/
+ /* Set the digital input logic */
+ /*******************************/
+ if (data[0] == ADDIDATA_ENABLE) {
+ data[2] = data[2] << 4;
+ data[3] = data[3] << 4;
+ outl(data[2],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(data[3],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ if (data[1] == ADDIDATA_OR) {
+ outl(0x4,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ } // if (data[1] == ADDIDATA_OR)
+ else {
+ outl(0x6,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ } // else if (data[1] == ADDIDATA_OR)
+ } // if (data[0] == ADDIDATA_ENABLE)
+ else {
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE1);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ } // else if (data[0] == ADDIDATA_ENABLE)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_Channel : Channel number to read |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 31) {
+ ui_TmpValue =
+ (UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } // if (ui_Channel >= 0 && ui_Channel <=31)
+ else {
+ comedi_error(dev, "Not a valid channel number !!! \n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if (ui_Channel >= 0 && ui_Channel <=31)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To be Read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+ if (data[1] == 0) {
+ *data = (UINT) inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 8:
+ ui_Mask = 255;
+ *data = (*data >> (8 * ui_PortValue)) & ui_Mask;
+ break;
+ case 16:
+ ui_Mask = 65535;
+ *data = (*data >> (16 * ui_PortValue)) & ui_Mask;
+ break;
+ case 31:
+ break;
+ default:
+ comedi_error(dev, "Not a valid Channel number !!!\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch (ui_NoOfChannels)
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ *data = ui_InterruptStatus_1564;
+ } // if (data[1]==1)
+ } // else if (data[1]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command = 0;
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } // if ((data[0]!=0) && (data[0]!=1))
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } // else if (data[0])
+ if (data[1] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x1;
+ } // if (data[1] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFE;
+ } // else if (data[1] == ADDIDATA_ENABLE)
+ if (data[2] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x2;
+ } // if (data[2] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFD;
+ } // else if (data[2] == ADDIDATA_ENABLE)
+ outl(ul_Command,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT);
+ ui_InterruptData =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT);
+ devpriv->tsk_Current = current;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } // else if (devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+ case 16:
+ data[0] =
+ (data[0] << (16 *
+ data[2])) | ui_Temp;
+ break;
+ case 31:
+ data[0] = data[0] | ui_Temp;
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } // switch (ui_NoOfChannels)
+ outl(data[0],
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0],
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 16:
+ data[0] = ~data[0] & 0xffff;
+ ui_Temp1 = 65535;
+ ui_Temp1 =
+ ui_Temp1 << 16 *
+ data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (16 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+ case 31:
+ break;
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+ outl(data[0],
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ } // if (data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (data[1]==0)
+ } // if (data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // else if (data[3]==1)
+ } // else if (data[3]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 16:
+ *data = (*data >> (16 * data[1])) & 65535;
+ break;
+
+ case 31:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch(ui_NoOfChannels)
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // else if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ConfigTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Counter |
+| 2 Configure As Watchdog |
+| data[1] : 1 Enable Interrupt |
+| 0 Disable Interrupt |
+| data[2] : Time Unit |
+| data[3] : Reload Value |
+| data[4] : Timer Mode |
+| data[5] : Timer Counter Watchdog Number|
+ data[6] : Counter Direction
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ devpriv->tsk_Current = current;
+ if (data[0] == ADDIDATA_WATCHDOG) {
+ devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+
+ //Disable the watchdog
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_PROG);
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_RELOAD_VALUE);
+ } // if (data[0]==ADDIDATA_WATCHDOG)
+ else if (data[0] == ADDIDATA_TIMER) {
+ //First Stop The Timer
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //Stop The Timer
+
+ devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+ if (data[1] == 1) {
+ outl(0x02, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_IRQ);
+ outl(0x0,
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_IRQ);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_IRQ);
+ } // if (data[1]==1)
+ else {
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //disable Timer interrupt
+ } // else if (data[1]==1)
+
+ // Loading Timebase
+
+ outl(data[2],
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_RELOAD_VALUE);
+
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 =
+ (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+ outl(ul_Command1, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG); //mode 2
+ } // else if (data[0]==ADDIDATA_TIMER)
+ else if (data[0] == ADDIDATA_COUNTER) {
+ devpriv->b_TimerSelectMode = ADDIDATA_COUNTER;
+ devpriv->b_ModeSelectRegister = data[5];
+
+ //First Stop The Counter
+ ul_Command1 =
+ inl(devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1, devpriv->iobase + ((data[5] - 1) * 0x20) + APCI1564_TCW_PROG); //Stop The Timer
+
+ /************************/
+ /* Set the reload value */
+ /************************/
+ outl(data[3],
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_RELOAD_VALUE);
+
+ /******************************/
+ /* Set the mode : */
+ /* - Disable the hardware */
+ /* - Disable the counter mode */
+ /* - Disable the warning */
+ /* - Disable the reset */
+ /* - Disable the timer mode */
+ /* - Enable the counter mode */
+ /******************************/
+ ul_Command1 =
+ (ul_Command1 & 0xFFFC19E2UL) | 0x80000UL |
+ (ULONG) ((ULONG) data[4] << 16UL);
+ outl(ul_Command1,
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+
+ // Enable or Disable Interrupt
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FD) | (data[1] << 1);
+ outl(ul_Command1,
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+
+ /*****************************/
+ /* Set the Up/Down selection */
+ /*****************************/
+ ul_Command1 = (ul_Command1 & 0xFFFBF9FFUL) | (data[6] << 18);
+ outl(ul_Command1,
+ devpriv->iobase + ((data[5] - 1) * 0x20) +
+ APCI1564_TCW_PROG);
+ } // else if (data[0]==ADDIDATA_COUNTER)
+ else {
+ printk(" Invalid subdevice.");
+ } // else if (data[0]==ADDIDATA_WATCHDOG)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_StartStopWriteTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : 1 Start |
+| 0 Stop |
+| 2 Trigger |
+| Clear (Only Counter) |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ switch (data[1]) {
+ case 0: //stop the watchdog
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG + APCI1564_TCW_PROG); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outl(0x0001,
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_PROG);
+ break;
+ case 2: //Software trigger
+ outl(0x0201,
+ devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_PROG);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch (data[1])
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ if (data[1] == 1) {
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+
+ //Enable the Timer
+ outl(ul_Command1,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ } // if (data[1]==1)
+ else if (data[1] == 0) {
+ //Stop The Timer
+
+ ul_Command1 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ } // else if(data[1]==0)
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ ul_Command1 =
+ inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) + APCI1564_TCW_PROG);
+ if (data[1] == 1) {
+ //Start the Counter subdevice
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+ } // if (data[1] == 1)
+ else if (data[1] == 0) {
+ // Stops the Counter subdevice
+ ul_Command1 = 0;
+
+ } // else if (data[1] == 0)
+ else if (data[1] == 2) {
+ // Clears the Counter subdevice
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x400;
+ } // else if (data[1] == 3)
+ outl(ul_Command1,
+ devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) + APCI1564_TCW_PROG);
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ // Stores the status of the Watchdog
+ data[0] =
+ inl(devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_TRIG_STATUS) & 0x1;
+ data[1] =
+ inl(devpriv->i_IobaseAmcc +
+ APCI1564_DIGITAL_OP_WATCHDOG);
+ } // if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+ else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ // Stores the status of the Timer
+ data[0] =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_TRIG_STATUS) & 0x1;
+
+ // Stores the Actual value of the Timer
+ data[1] = inl(devpriv->i_IobaseAmcc + APCI1564_TIMER);
+ } // else if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ else if (devpriv->b_TimerSelectMode == ADDIDATA_COUNTER) {
+ // Read the Counter Actual Value.
+ data[0] =
+ inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) +
+ APCI1564_TCW_SYNC_ENABLEDISABLE);
+ ul_Command1 =
+ inl(devpriv->iobase + ((devpriv->b_ModeSelectRegister -
+ 1) * 0x20) + APCI1564_TCW_TRIG_STATUS);
+
+ /***********************************/
+ /* Get the software trigger status */
+ /***********************************/
+ data[1] = (BYTE) ((ul_Command1 >> 1) & 1);
+
+ /***********************************/
+ /* Get the hardware trigger status */
+ /***********************************/
+ data[2] = (BYTE) ((ul_Command1 >> 2) & 1);
+
+ /*********************************/
+ /* Get the software clear status */
+ /*********************************/
+ data[3] = (BYTE) ((ul_Command1 >> 3) & 1);
+
+ /***************************/
+ /* Get the overflow status */
+ /***************************/
+ data[4] = (BYTE) ((ul_Command1 >> 0) & 1);
+ } // else if (devpriv->b_TimerSelectMode==ADDIDATA_COUNTER)
+ else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
+ && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)
+ && (devpriv->b_TimerSelectMode != ADDIDATA_COUNTER)) {
+ printk("\n Invalid Subdevice !!!\n");
+ } // else if ((devpriv->b_TimerSelectMode!=ADDIDATA_TIMER) && (devpriv->b_TimerSelectMode!=ADDIDATA_WATCHDOG)&& (devpriv->b_TimerSelectMode!=ADDIDATA_COUNTER))
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_ReadInterruptStatus |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task :Reads the interrupt status register |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI1564_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ *data = ui_Type;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI1564_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt handler for the interruptible digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+static void v_APCI1564_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ UINT ui_DO, ui_DI;
+ UINT ui_Timer;
+ UINT ui_C1, ui_C2, ui_C3, ui_C4;
+ ULONG ul_Command2 = 0;
+ ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ) & 0x01;
+ ui_DO = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_IRQ) & 0x01;
+ ui_Timer =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_IRQ) & 0x01;
+ ui_C1 = inl(devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_IRQ) & 0x1;
+ ui_C2 = inl(devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_IRQ) & 0x1;
+ ui_C3 = inl(devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_IRQ) & 0x1;
+ ui_C4 = inl(devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_IRQ) & 0x1;
+ if (ui_DI == 0 && ui_DO == 0 && ui_Timer == 0 && ui_C1 == 0
+ && ui_C2 == 0 && ui_C3 == 0 && ui_C4 == 0) {
+ printk("\nInterrupt from unknown source\n");
+ } // if(ui_DI==0 && ui_DO==0 && ui_Timer==0 && ui_C1==0 && ui_C2==0 && ui_C3==0 && ui_C4==0)
+
+ if (ui_DI == 1) {
+ ui_DI = inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_IRQ);
+ ui_InterruptStatus_1564 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP +
+ APCI1564_DIGITAL_IP_INTERRUPT_STATUS);
+ ui_InterruptStatus_1564 = ui_InterruptStatus_1564 & 0X000FFFF0;
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ outl(ui_DI, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP + APCI1564_DIGITAL_IP_IRQ); //enable the interrupt
+ return;
+ }
+
+ if (ui_DO == 1) {
+ // Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+ ui_Type =
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
+ //Disable the Interrupt
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP +
+ APCI1564_DIGITAL_OP_INTERRUPT);
+
+ //Sends signal to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ } // if (ui_DO)
+
+ if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_TIMER)) {
+ // Disable Timer Interrupt
+ ul_Command2 =
+ inl(devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Timer Interrupt
+
+ outl(ul_Command2,
+ devpriv->i_IobaseAmcc + APCI1564_TIMER +
+ APCI1564_TCW_PROG);
+ } // if ((ui_Timer == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_TIMER))
+
+ if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER1 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C1 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER))
+
+ if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER2 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C2 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+ if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER3 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C3 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+
+ if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode = ADDIDATA_COUNTER)) {
+ // Disable Counter Interrupt
+ ul_Command2 =
+ inl(devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_PROG);
+ outl(0x0,
+ devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_PROG);
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+
+ // Enable Counter Interrupt
+ outl(ul_Command2,
+ devpriv->iobase + APCI1564_COUNTER4 +
+ APCI1564_TCW_PROG);
+ } // if ((ui_C4 == 1) && (devpriv->b_TimerSelectMode =ADDIDATA_COUNTER))
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI1564_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI1564_Reset(struct comedi_device * dev)
+{
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_IRQ); //disable the interrupts
+ inl(devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_STATUS); //Reset the interrupt status register
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE1); //Disable the and/or interrupt
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_IP_INTERRUPT_MODE2);
+ devpriv->b_DigitalOutputRegister = 0;
+ ui_Type = 0;
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP); //Resets the output channels
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_INTERRUPT); //Disables the interrupt.
+ outl(0x0,
+ devpriv->i_IobaseAmcc + APCI1564_DIGITAL_OP_WATCHDOG +
+ APCI1564_TCW_RELOAD_VALUE);
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER);
+ outl(0x0, devpriv->i_IobaseAmcc + APCI1564_TIMER + APCI1564_TCW_PROG);
+
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER1 + APCI1564_TCW_PROG);
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER2 + APCI1564_TCW_PROG);
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER3 + APCI1564_TCW_PROG);
+ outl(0x0, devpriv->iobase + APCI1564_COUNTER4 + APCI1564_TCW_PROG);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
new file mode 100644
index 00000000000..f0c461ca539
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1564.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/********* Definitions for APCI-1564 card *****/
+
+#define APCI1564_BOARD_VENDOR_ID 0x15B8
+#define APCI1564_ADDRESS_RANGE 128
+
+//DIGITAL INPUT-OUTPUT DEFINE
+// Input defines
+#define APCI1564_DIGITAL_IP 0x04
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE1 4
+#define APCI1564_DIGITAL_IP_INTERRUPT_MODE2 8
+#define APCI1564_DIGITAL_IP_IRQ 16
+
+// Output defines
+#define APCI1564_DIGITAL_OP 0x18
+#define APCI1564_DIGITAL_OP_RW 0
+#define APCI1564_DIGITAL_OP_INTERRUPT 4
+#define APCI1564_DIGITAL_OP_IRQ 12
+
+//Digital Input IRQ Function Selection
+#define ADDIDATA_OR 0
+#define ADDIDATA_AND 1
+
+//Digital Input Interrupt Status
+#define APCI1564_DIGITAL_IP_INTERRUPT_STATUS 12
+
+//Digital Output Interrupt Status
+#define APCI1564_DIGITAL_OP_INTERRUPT_STATUS 8
+
+//Digital Input Interrupt Enable Disable.
+#define APCI1564_DIGITAL_IP_INTERRUPT_ENABLE 0x4
+#define APCI1564_DIGITAL_IP_INTERRUPT_DISABLE 0xFFFFFFFB
+
+//Digital Output Interrupt Enable Disable.
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
+#define APCI1564_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
+#define APCI1564_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_TIMER 0
+#define ADDIDATA_COUNTER 1
+#define ADDIDATA_WATCHDOG 2
+#define APCI1564_DIGITAL_OP_WATCHDOG 0x28
+#define APCI1564_TIMER 0x48
+#define APCI1564_COUNTER1 0x0
+#define APCI1564_COUNTER2 0x20
+#define APCI1564_COUNTER3 0x40
+#define APCI1564_COUNTER4 0x60
+#define APCI1564_TCW_SYNC_ENABLEDISABLE 0
+#define APCI1564_TCW_RELOAD_VALUE 4
+#define APCI1564_TCW_TIMEBASE 8
+#define APCI1564_TCW_PROG 12
+#define APCI1564_TCW_TRIG_STATUS 16
+#define APCI1564_TCW_IRQ 20
+#define APCI1564_TCW_WARN_TIMEVAL 24
+#define APCI1564_TCW_WARN_TIMEBASE 28
+
+// Hardware Layer functions for Apci1564
+
+//DI
+// for di read
+INT i_APCI1564_ConfigDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DO
+int i_APCI1564_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI1564_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1564_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI1564_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI1564_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI1564_ReadTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// INTERRUPT
+static void v_APCI1564_Interrupt(int irq, void *d);
+
+// RESET
+INT i_APCI1564_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
new file mode 100644
index 00000000000..906d635da6b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.c
@@ -0,0 +1,780 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : API APCI1648 | Compiler : gcc |
+ | Module name : TTL.C | Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: S. Weber | Date : 25/05/2005 |
+ +-----------------------------------------------------------------------+
+ | Description : APCI-16XX TTL I/O module |
+ | |
+ | |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ |25.05.2005| S.Weber | Creation |
+ | | | |
+ +-----------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "hwdrv_apci16xx.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnConfigInitTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task APCI16XX_TTL_INIT (using defaults) : |
+| Configure the TTL I/O operating mode from all ports |
+| You must calling this function be |
+| for you call any other function witch access of TTL. |
+| APCI16XX_TTL_INITDIRECTION(user inputs for direction) |
++----------------------------------------------------------------------------+
+| Input Parameters : b_InitType = (BYTE) data[0]; |
+| b_Port0Mode = (BYTE) data[1]; |
+| b_Port1Mode = (BYTE) data[2]; |
+| b_Port2Mode = (BYTE) data[3]; |
+| b_Port3Mode = (BYTE) data[4]; |
+| ........ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -1: Port 0 mode selection is wrong |
+| -2: Port 1 mode selection is wrong |
+| -3: Port 2 mode selection is wrong |
+| -4: Port 3 mode selection is wrong |
+| -X: Port X-1 mode selection is wrong |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+ BYTE b_Cpt = 0;
+ BYTE b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_INIT) ||
+ (b_Command == APCI16XX_TTL_INITDIRECTION) ||
+ (b_Command == APCI16XX_TTL_OUTPUTMEMORY)) {
+ /***************************************/
+ /* Test the initialisation buffer size */
+ /***************************************/
+
+ if ((b_Command == APCI16XX_TTL_INITDIRECTION)
+ && ((BYTE) (insn->n - 1) != b_NumberOfPort)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ if ((b_Command == APCI16XX_TTL_OUTPUTMEMORY)
+ && ((BYTE) (insn->n) != 2)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ /**************************************************************************/
+ /* Test if no error occur and APCI16XX_TTL_INITDIRECTION command selected */
+ /**************************************************************************/
+
+ if ((i_ReturnValue >= 0) && (b_Command == APCI16XX_TTL_INITDIRECTION)) {
+ memset(devpriv->ul_TTLPortConfiguration, 0,
+ sizeof(devpriv->ul_TTLPortConfiguration));
+
+ /*************************************/
+ /* Test the port direction selection */
+ /*************************************/
+
+ for (b_Cpt = 1;
+ (b_Cpt <= b_NumberOfPort) && (i_ReturnValue >= 0);
+ b_Cpt++) {
+ /**********************/
+ /* Test the direction */
+ /**********************/
+
+ if ((data[b_Cpt] != 0) && (data[b_Cpt] != 0xFF)) {
+ /************************/
+ /* Port direction error */
+ /************************/
+
+ printk("\nPort %d direction selection error",
+ (INT) b_Cpt);
+ i_ReturnValue = -(INT) b_Cpt;
+ }
+
+ /**************************/
+ /* Save the configuration */
+ /**************************/
+
+ devpriv->ul_TTLPortConfiguration[(b_Cpt - 1) / 4] =
+ devpriv->ul_TTLPortConfiguration[(b_Cpt -
+ 1) / 4] | (data[b_Cpt] << (8 * ((b_Cpt -
+ 1) % 4)));
+ }
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /***********************************/
+ /* Test if TTL port initilaisation */
+ /***********************************/
+
+ if ((b_Command == APCI16XX_TTL_INIT)
+ || (b_Command == APCI16XX_TTL_INITDIRECTION)) {
+ /******************************/
+ /* Set all port configuration */
+ /******************************/
+
+ for (b_Cpt = 0; b_Cpt <= b_NumberOfPort; b_Cpt++) {
+ if ((b_Cpt % 4) == 0) {
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(devpriv->
+ ul_TTLPortConfiguration[b_Cpt /
+ 4],
+ devpriv->iobase + 32 + b_Cpt);
+ }
+ }
+ }
+ }
+
+ /************************************************/
+ /* Test if output memory initialisation command */
+ /************************************************/
+
+ if (b_Command == APCI16XX_TTL_OUTPUTMEMORY) {
+ if (data[1]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ }
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnBitsReadTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from selected TTL digital input |
+| (b_InputChannel) |
++----------------------------------------------------------------------------+
+| Task : Read the status from digital input port |
+| (b_SelectedPort) |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| APCI16XX_TTL_READCHANNEL |
+| b_SelectedPort= CR_RANGE(insn->chanspec); |
+| b_InputChannel= CR_CHAN(insn->chanspec); |
+| b_ReadType = (BYTE) data[0]; |
+| |
+| APCI16XX_TTL_READPORT |
+| b_SelectedPort= CR_RANGE(insn->chanspec); |
+| b_ReadType = (BYTE) data[0]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] 0 : Channle is not active |
+| 1 : Channle is active |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -100 : Config command error |
+| -101 : Data size error |
+| -102 : The selected TTL input port is wrong |
+| -103 : The selected TTL digital input is wrong |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+ BYTE b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+ BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
+ BYTE b_InputChannel = CR_CHAN(insn->chanspec);
+ BYTE *pb_Status;
+ DWORD dw_Status;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_READCHANNEL)
+ || (b_Command == APCI16XX_TTL_READPORT)) {
+ /**************************/
+ /* Test the selected port */
+ /**************************/
+
+ if (b_SelectedPort < b_NumberOfPort) {
+ /**********************/
+ /* Test if input port */
+ /**********************/
+
+ if (((devpriv->ul_TTLPortConfiguration
+ [b_SelectedPort /
+ 4] >> (8 *
+ (b_SelectedPort
+ %
+ 4))) &
+ 0xFF) == 0) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if ((b_Command ==
+ APCI16XX_TTL_READCHANNEL)
+ && (b_InputChannel > 7)) {
+ /*******************************************/
+ /* The selected TTL digital input is wrong */
+ /*******************************************/
+
+ printk("\nChannel selection error");
+ i_ReturnValue = -103;
+ }
+ } else {
+ /****************************************/
+ /* The selected TTL input port is wrong */
+ /****************************************/
+
+ printk("\nPort selection error");
+ i_ReturnValue = -102;
+ }
+ } else {
+ /****************************************/
+ /* The selected TTL input port is wrong */
+ /****************************************/
+
+ printk("\nPort selection error");
+ i_ReturnValue = -102;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ pb_Status = (PBYTE) & data[0];
+
+ /*******************************/
+ /* Get the digital inpu status */
+ /*******************************/
+
+ dw_Status =
+ inl(devpriv->iobase + 8 + ((b_SelectedPort / 4) * 4));
+ dw_Status = (dw_Status >> (8 * (b_SelectedPort % 4))) & 0xFF;
+
+ /***********************/
+ /* Save the port value */
+ /***********************/
+
+ *pb_Status = (BYTE) dw_Status;
+
+ /***************************************/
+ /* Test if read channel status command */
+ /***************************************/
+
+ if (b_Command == APCI16XX_TTL_READCHANNEL) {
+ *pb_Status = (*pb_Status >> b_InputChannel) & 1;
+ }
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnReadTTLIOAllPortValue |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from all digital input ports |
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Port 0 to 3 data |
+| data[1] : Port 4 to 7 data |
+| .... |
++----------------------------------------------------------------------------+
+| Return Value : 0: No error |
+| -100 : Read command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Command = (BYTE) CR_AREF(insn->chanspec);
+ INT i_ReturnValue = insn->n;
+ BYTE b_Cpt = 0;
+ BYTE b_NumberOfPort = 0;
+ unsigned int *pls_ReadData = data;
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_READ_ALL_INPUTS)
+ || (b_Command == APCI16XX_TTL_READ_ALL_OUTPUTS)) {
+ /**********************************/
+ /* Get the number of 32-Bit ports */
+ /**********************************/
+
+ b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 32);
+ if ((b_NumberOfPort * 32) <
+ devpriv->ps_BoardInfo->i_NbrTTLChannel) {
+ b_NumberOfPort = b_NumberOfPort + 1;
+ }
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= b_NumberOfPort) {
+ if (b_Command == APCI16XX_TTL_READ_ALL_INPUTS) {
+ /**************************/
+ /* Read all digital input */
+ /**************************/
+
+ for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
+ /************************/
+ /* Read the 32-Bit port */
+ /************************/
+
+ pls_ReadData[b_Cpt] =
+ inl(devpriv->iobase + 8 +
+ (b_Cpt * 4));
+
+ /**************************************/
+ /* Mask all channels used als outputs */
+ /**************************************/
+
+ pls_ReadData[b_Cpt] =
+ pls_ReadData[b_Cpt] &
+ (~devpriv->
+ ul_TTLPortConfiguration[b_Cpt]);
+ }
+ } else {
+ /****************************/
+ /* Read all digital outputs */
+ /****************************/
+
+ for (b_Cpt = 0; b_Cpt < b_NumberOfPort; b_Cpt++) {
+ /************************/
+ /* Read the 32-Bit port */
+ /************************/
+
+ pls_ReadData[b_Cpt] =
+ inl(devpriv->iobase + 20 +
+ (b_Cpt * 4));
+
+ /**************************************/
+ /* Mask all channels used als outputs */
+ /**************************************/
+
+ pls_ReadData[b_Cpt] =
+ pls_ReadData[b_Cpt] & devpriv->
+ ul_TTLPortConfiguration[b_Cpt];
+ }
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /*****************/
+ /* Command error */
+ /*****************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI16XX_InsnBitsWriteTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set the state from selected TTL digital output |
+| (b_OutputChannel) |
++----------------------------------------------------------------------------+
+| Task : Set the state from digital output port |
+| (b_SelectedPort) |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| APCI16XX_TTL_WRITECHANNEL_ON | APCI16XX_TTL_WRITECHANNEL_OFF |
+| b_SelectedPort = CR_RANGE(insn->chanspec); |
+| b_OutputChannel= CR_CHAN(insn->chanspec); |
+| b_Command = (BYTE) data[0]; |
+| |
+| APCI16XX_TTL_WRITEPORT_ON | APCI16XX_TTL_WRITEPORT_OFF |
+| b_SelectedPort = CR_RANGE(insn->chanspec); |
+| b_Command = (BYTE) data[0]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : TTL output port 0 to 3 data |
+| data[1] : TTL output port 4 to 7 data |
+| .... |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -100 : Command error |
+| -101 : Data size error |
+| -102 : The selected TTL output port is wrong |
+| -103 : The selected TTL digital output is wrong |
+| -104 : Output memory disabled |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+ BYTE b_NumberOfPort =
+ (BYTE) (devpriv->ps_BoardInfo->i_NbrTTLChannel / 8);
+ BYTE b_SelectedPort = CR_RANGE(insn->chanspec);
+ BYTE b_OutputChannel = CR_CHAN(insn->chanspec);
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if ((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) ||
+ (b_Command == APCI16XX_TTL_WRITEPORT_ON) ||
+ (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) ||
+ (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) {
+ /**************************/
+ /* Test the selected port */
+ /**************************/
+
+ if (b_SelectedPort < b_NumberOfPort) {
+ /***********************/
+ /* Test if output port */
+ /***********************/
+
+ if (((devpriv->ul_TTLPortConfiguration
+ [b_SelectedPort /
+ 4] >> (8 *
+ (b_SelectedPort
+ %
+ 4))) &
+ 0xFF) == 0xFF) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (((b_Command == APCI16XX_TTL_WRITECHANNEL_ON) || (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF)) && (b_OutputChannel > 7)) {
+ /********************************************/
+ /* The selected TTL digital output is wrong */
+ /********************************************/
+
+ printk("\nChannel selection error");
+ i_ReturnValue = -103;
+ }
+
+ if (((b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE)) {
+ /********************************************/
+ /* The selected TTL digital output is wrong */
+ /********************************************/
+
+ printk("\nOutput memory disabled");
+ i_ReturnValue = -104;
+ }
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (((b_Command == APCI16XX_TTL_WRITEPORT_ON) || (b_Command == APCI16XX_TTL_WRITEPORT_OFF)) && (insn->n < 2)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /*****************************************/
+ /* The selected TTL output port is wrong */
+ /*****************************************/
+
+ printk("\nPort selection error %lX",
+ (unsigned long)devpriv->
+ ul_TTLPortConfiguration[0]);
+ i_ReturnValue = -102;
+ }
+ } else {
+ /****************************************/
+ /* The selected TTL output port is wrong */
+ /****************************************/
+
+ printk("\nPort selection error %d %d",
+ b_SelectedPort, b_NumberOfPort);
+ i_ReturnValue = -102;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("\nCommand selection error");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("\nBuffer size error");
+ i_ReturnValue = -101;
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /********************************/
+ /* Get the digital output state */
+ /********************************/
+
+ dw_Status =
+ inl(devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
+
+ /**********************************/
+ /* Test if output memory not used */
+ /**********************************/
+
+ if (devpriv->b_OutputMemoryStatus == ADDIDATA_DISABLE) {
+ /*********************************/
+ /* Clear the selected port value */
+ /*********************************/
+
+ dw_Status =
+ dw_Status & (0xFFFFFFFFUL -
+ (0xFFUL << (8 * (b_SelectedPort % 4))));
+ }
+
+ /******************************/
+ /* Test if setting channel ON */
+ /******************************/
+
+ if (b_Command == APCI16XX_TTL_WRITECHANNEL_ON) {
+ dw_Status =
+ dw_Status | (1UL << ((8 * (b_SelectedPort %
+ 4)) + b_OutputChannel));
+ }
+
+ /***************************/
+ /* Test if setting port ON */
+ /***************************/
+
+ if (b_Command == APCI16XX_TTL_WRITEPORT_ON) {
+ dw_Status =
+ dw_Status | ((data[1] & 0xFF) << (8 *
+ (b_SelectedPort % 4)));
+ }
+
+ /*******************************/
+ /* Test if setting channel OFF */
+ /*******************************/
+
+ if (b_Command == APCI16XX_TTL_WRITECHANNEL_OFF) {
+ dw_Status =
+ dw_Status & (0xFFFFFFFFUL -
+ (1UL << ((8 * (b_SelectedPort % 4)) +
+ b_OutputChannel)));
+ }
+
+ /****************************/
+ /* Test if setting port OFF */
+ /****************************/
+
+ if (b_Command == APCI16XX_TTL_WRITEPORT_OFF) {
+ dw_Status =
+ dw_Status & (0xFFFFFFFFUL -
+ ((data[1] & 0xFF) << (8 * (b_SelectedPort %
+ 4))));
+ }
+
+ outl(dw_Status,
+ devpriv->iobase + 20 + ((b_SelectedPort / 4) * 4));
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : - |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_Reset(struct comedi_device * dev)
+{
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
new file mode 100644
index 00000000000..5bf91e13a03
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci16xx.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+#ifndef ADDIDATA_ENABLE
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+#endif
+
+#define APCI16XX_TTL_INIT 0
+#define APCI16XX_TTL_INITDIRECTION 1
+#define APCI16XX_TTL_OUTPUTMEMORY 2
+
+#define APCI16XX_TTL_READCHANNEL 0
+#define APCI16XX_TTL_READPORT 1
+
+#define APCI16XX_TTL_WRITECHANNEL_ON 0
+#define APCI16XX_TTL_WRITECHANNEL_OFF 1
+#define APCI16XX_TTL_WRITEPORT_ON 2
+#define APCI16XX_TTL_WRITEPORT_OFF 3
+
+#define APCI16XX_TTL_READ_ALL_INPUTS 0
+#define APCI16XX_TTL_READ_ALL_OUTPUTS 1
+
+#ifdef __KERNEL__
+
+static const struct comedi_lrange range_apci16xx_ttl = { 12,
+ {BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1)}
+};
+
+/*
++----------------------------------------------------------------------------+
+| TTL INISIALISATION FUNCTION |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnConfigInitTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+
+/*
++----------------------------------------------------------------------------+
+| TTL INPUT FUNCTION |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsReadTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+
+int i_APCI16XX_InsnReadTTLIOAllPortValue(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+/*
++----------------------------------------------------------------------------+
+| TTL OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI16XX_InsnBitsWriteTTLIO(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+
+int i_APCI16XX_Reset(struct comedi_device *dev);
+#endif
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
new file mode 100644
index 00000000000..31f55da39ea
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.c
@@ -0,0 +1,460 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-2016 | Compiler : GCC |
+ | Module name : hwdrv_apci2016.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2016 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci2016.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 1 Digital Memory On |
+| 0 Digital Memory Off |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } // if ((data[0]!=0) && (data[0]!=1))
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0]
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } // else if (data[0]
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_NoOfChannel;
+ UINT ui_Temp, ui_Temp1;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+ comedi_error(dev,
+ "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+ return -EINVAL;
+ } // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inw(devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } // else if (devpriv->b_OutputMemoryStatus )
+ if ((data[1] != 0) && (data[1] != 1)) {
+ comedi_error(dev,
+ "Invalid Data[1] value !!!, Data[1] should be 0 or 1\n");
+ return -EINVAL;
+ } // if ((data[1]!=0) && (data[1]!=1))
+
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0], devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+ case 15:
+ data[0] = data[0] | ui_Temp;
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+ outw(data[0],
+ devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } // else if (data[1]==1)
+ } // else if (data[1]==0)
+ } // if (data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->iobase + APCI2016_DIGITAL_OP);
+ } // if (data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 15:
+ break;
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+ outw(data[0],
+ devpriv->iobase +
+ APCI2016_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_BitsDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_BitsDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ if ((ui_NoOfChannel < 0) || (ui_NoOfChannel > 15)) {
+ comedi_error(dev,
+ "Invalid Channel Numbers !!!, Channel Numbers must be between 0 and 15\n");
+ return -EINVAL;
+ } // if ((ui_NoOfChannel<0) || (ui_NoOfChannel>15))
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Invalid Data[0] value !!!, Data[0] should be 0 or 1\n");
+ return -EINVAL;
+ } // if ((data[0]!=0) && (data[0]!=1))
+ ui_Temp = data[0];
+ *data = inw(devpriv->iobase + APCI2016_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannel)
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_ConfigWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure |
+| struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outw(0x0,
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_RELOAD_VALUE);
+ data[1] = data[1] >> 16;
+ outw(data[1],
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_RELOAD_VALUE + 2);
+ } else {
+ printk("\nThe input parameters are wrong\n");
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_StartStopWriteWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure |
+| struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2016_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outw(0x0001,
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2: //Software trigger
+ outw(0x0201,
+ devpriv->i_IobaseAddon +
+ APCI2016_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch(data[0])
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure |
+| struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2016_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ udelay(5);
+ data[0] = inw(devpriv->i_IobaseAddon + APCI2016_WATCHDOG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2016_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2016_Reset(struct comedi_device * dev)
+{
+ outw(0x0, devpriv->iobase + APCI2016_DIGITAL_OP); // Resets the digital output channels
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_ENABLEDISABLE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE);
+ outw(0x0, devpriv->i_IobaseAddon + APCI2016_WATCHDOG_RELOAD_VALUE + 2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
new file mode 100644
index 00000000000..9261aacd25f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2016.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+/********* Definitions for APCI-2016 card *****/
+
+#define APCI2016_BOARD_VENDOR_ID 0x15B8
+#define APCI2016_ADDRESS_RANGE 8
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2016_DIGITAL_OP 0x04
+#define APCI2016_DIGITAL_OP_RW 4
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG 2
+#define APCI2016_DIGITAL_OP_WATCHDOG 0
+#define APCI2016_WATCHDOG_ENABLEDISABLE 12
+#define APCI2016_WATCHDOG_RELOAD_VALUE 4
+#define APCI2016_WATCHDOG_STATUS 16
+
+// Hardware Layer functions for Apci2016
+
+//DO
+int i_APCI2016_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_BitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+
+int i_APCI2016_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+int i_APCI2016_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+// void v_APCI2016_Interrupt(int irq, void *d) ;
+
+ //void v_APCI2016_Interrupt(int irq, void *d);
+// RESET
+INT i_APCI2016_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
new file mode 100644
index 00000000000..1347bc388f3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.c
@@ -0,0 +1,579 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-2032 | Compiler : GCC |
+ | Module name : hwdrv_apci2032.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2032 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+
+#include "hwdrv_apci2032.h"
+UINT ui_InterruptData, ui_Type;
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2032_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command = 0;
+ devpriv->tsk_Current = current;
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } //if ( (data[0]!=0) && (data[0]!=1) )
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } //else if (data[0])
+
+ if (data[1] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x1;
+ } //if (data[1] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFE;
+ } //elseif (data[1] == ADDIDATA_ENABLE)
+ if (data[2] == ADDIDATA_ENABLE) {
+ ul_Command = ul_Command | 0x2;
+ } //if (data[2] == ADDIDATA_ENABLE)
+ else {
+ ul_Command = ul_Command & 0xFFFFFFFD;
+ } //elseif (data[2] == ADDIDATA_ENABLE)
+ outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
+ ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To Write |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 16:
+ data[0] =
+ (data[0] << (16 *
+ data[2])) | ui_Temp;
+ break;
+ case 31:
+ data[0] = data[0] | ui_Temp;
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0],
+ devpriv->iobase + APCI2032_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0],
+ devpriv->iobase + APCI2032_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 16:
+ data[0] = ~data[0] & 0xffff;
+ ui_Temp1 = 65535;
+ ui_Temp1 =
+ ui_Temp1 << 16 *
+ data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (16 *
+ data
+ [2])) ^
+ 0xffffffff) & ui_Temp;
+ break;
+
+ case 31:
+ break;
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0],
+ devpriv->iobase +
+ APCI2032_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2032_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 16:
+ *data = (*data >> (16 * data[1])) & 65535;
+ break;
+
+ case 31:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif (ui_Temp==1)
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI2032_ConfigWatchdog(comedi_device
+ *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)|
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2032_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outl(0x0,
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_PROG);
+ //Loading the Reload value
+ outl(data[1],
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_RELOAD_VALUE);
+ } else {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ }
+
+ return insn->n;
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI2032_StartStopWriteWatchdog |
+ | (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
+ +----------------------------------------------------------------------------+
+ | Task : Start / Stop The Watchdog |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+ | unsigned int *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+ */
+
+int i_APCI2032_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outl(0x0001,
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_PROG);
+ break;
+ case 2: //Software trigger
+ outl(0x0201,
+ devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_PROG);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ data[0] =
+ inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG +
+ APCI2032_TCW_TRIG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : void v_APCI2032_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+void v_APCI2032_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ unsigned int ui_DO;
+
+ ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; //Check if VCC OR CC interrupt has occured.
+
+ if (ui_DO == 0) {
+ printk("\nInterrupt from unKnown source\n");
+ } // if(ui_DO==0)
+ if (ui_DO) {
+ // Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt.
+ ui_Type =
+ inl(devpriv->iobase +
+ APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3;
+ outl(0x0,
+ devpriv->iobase + APCI2032_DIGITAL_OP +
+ APCI2032_DIGITAL_OP_INTERRUPT);
+ if (ui_Type == 1) {
+ //Sends signal to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ } // if (ui_Type==1)
+ else {
+ if (ui_Type == 2) {
+ // Sends signal to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ } //if (ui_Type==2)
+ } //else if (ui_Type==1)
+ } //if(ui_DO)
+
+ return;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_ReadInterruptStatus |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task :Reads the interrupt status register |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_ReadInterruptStatus(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ *data = ui_Type;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2032_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2032_Reset(struct comedi_device * dev)
+{
+ devpriv->b_DigitalOutputRegister = 0;
+ ui_Type = 0;
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); //Resets the output channels
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); //Disables the interrupt.
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog
+ outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); //reload=0
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
new file mode 100644
index 00000000000..55002e0288b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2032.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/********* Definitions for APCI-2032 card *****/
+
+// Card Specific information
+#define APCI2032_BOARD_VENDOR_ID 0x15B8
+#define APCI2032_ADDRESS_RANGE 63
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2032_DIGITAL_OP 0
+#define APCI2032_DIGITAL_OP_RW 0
+#define APCI2032_DIGITAL_OP_INTERRUPT 4
+#define APCI2032_DIGITAL_OP_IRQ 12
+
+//Digital Output Interrupt Status
+#define APCI2032_DIGITAL_OP_INTERRUPT_STATUS 8
+
+//Digital Output Interrupt Enable Disable.
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_ENABLE 0x1
+#define APCI2032_DIGITAL_OP_VCC_INTERRUPT_DISABLE 0xFFFFFFFE
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_ENABLE 0x2
+#define APCI2032_DIGITAL_OP_CC_INTERRUPT_DISABLE 0xFFFFFFFD
+
+//ADDIDATA Enable Disable
+
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define ADDIDATA_WATCHDOG 2
+#define APCI2032_DIGITAL_OP_WATCHDOG 16
+#define APCI2032_TCW_RELOAD_VALUE 4
+#define APCI2032_TCW_TIMEBASE 8
+#define APCI2032_TCW_PROG 12
+#define APCI2032_TCW_TRIG_STATUS 16
+#define APCI2032_TCW_IRQ 20
+
+// Hardware Layer functions for Apci2032
+
+//DO
+int i_APCI2032_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2032_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2032_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_ReadInterruptStatus(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI2032_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2032_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// Interrupt functions.....
+
+void v_APCI2032_Interrupt(int irq, void *d);
+
+//Reset functions
+int i_APCI2032_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
new file mode 100644
index 00000000000..947e18ef3ab
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.c
@@ -0,0 +1,549 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-2200 | Compiler : GCC |
+ | Module name : hwdrv_apci2200.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-2200 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci2200.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Read1DigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the digital input |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI2200_Read1DigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue = 0;
+ UINT ui_Channel;
+ ui_Channel = CR_CHAN(insn->chanspec);
+ if (ui_Channel >= 0 && ui_Channel <= 7) {
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
+ *data = (ui_TmpValue >> ui_Channel) & 0x1;
+ } //if(ui_Channel >= 0 && ui_Channel <=7)
+ else {
+ printk("\nThe specified channel does not exist\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //else if(ui_Channel >= 0 && ui_Channel <=7)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadMoreDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Return the status of the Requested digital inputs |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_PortValue = data[0];
+ UINT ui_Mask = 0;
+ UINT ui_NoOfChannels;
+
+ ui_NoOfChannels = CR_CHAN(insn->chanspec);
+
+ *data = (UINT) inw(devpriv->iobase + APCI2200_DIGITAL_IP);
+ switch (ui_NoOfChannels) {
+ case 2:
+ ui_Mask = 3;
+ *data = (*data >> (2 * ui_PortValue)) & ui_Mask;
+ break;
+ case 4:
+ ui_Mask = 15;
+ *data = (*data >> (4 * ui_PortValue)) & ui_Mask;
+ break;
+ case 7:
+ break;
+
+ default:
+ printk("\nWrong parameters\n");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } //switch(ui_NoOfChannels)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ConfigDigitalOutput (struct comedi_device *dev,
+ struct comedi_subdevice *s struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| data[0] :1:Memory on |
+| 0:Memory off |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI2200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->b_OutputMemoryStatus = data[0];
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes port value To the selected port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outw(data[0], devpriv->iobase + APCI2200_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 4:
+ data[0] =
+ (data[0] << (4 *
+ data[2])) | ui_Temp;
+ break;
+
+ case 8:
+ data[0] =
+ (data[0] << (8 *
+ data[2])) | ui_Temp;
+ break;
+ case 15:
+ data[0] = data[0] | ui_Temp;
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase + APCI2200_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xffff;
+ data[0] = data[0] & ui_Temp;
+ outw(data[0],
+ devpriv->iobase + APCI2200_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+
+ case 4:
+ data[0] = ~data[0] & 0xf;
+ ui_Temp1 = 15;
+ ui_Temp1 =
+ ui_Temp1 << 4 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (4 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+
+ case 8:
+ data[0] = ~data[0] & 0xff;
+ ui_Temp1 = 255;
+ ui_Temp1 =
+ ui_Temp1 << 8 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (8 *
+ data
+ [2])) ^
+ 0xffff) & ui_Temp;
+ break;
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+
+ outw(data[0],
+ devpriv->iobase +
+ APCI2200_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return (insn->n);;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Temp;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ ui_Temp = data[0];
+ *data = inw(devpriv->iobase + APCI2200_DIGITAL_OP);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if(ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 4:
+ *data = (*data >> (4 * data[1])) & 15;
+ break;
+
+ case 8:
+ *data = (*data >> (8 * data[1])) & 255;
+ break;
+
+ case 15:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if(ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif(ui_Temp==1)
+ } //elseif(ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ConfigWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Configures The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ConfigWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0] == 0) {
+ //Disable the watchdog
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ //Loading the Reload value
+ outw(data[1],
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE);
+ data[1] = data[1] >> 16;
+ outw(data[1],
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE + 2);
+ } //if(data[0]==0)
+ else {
+ printk("\nThe input parameters are wrong\n");
+ return -EINVAL;
+ } //elseif(data[0]==0)
+
+ return insn->n;
+}
+
+ /*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI2200_StartStopWriteWatchdog |
+ | (struct comedi_device *dev,struct comedi_subdevice *s,
+ struct comedi_insn *insn,unsigned int *data); |
+ +----------------------------------------------------------------------------+
+ | Task : Start / Stop The Watchdog |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+ | unsigned int *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+ */
+
+int i_APCI2200_StartStopWriteWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case 0: //stop the watchdog
+ outw(0x0, devpriv->iobase + APCI2200_WATCHDOG + APCI2200_WATCHDOG_ENABLEDISABLE); //disable the watchdog
+ break;
+ case 1: //start the watchdog
+ outw(0x0001,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ break;
+ case 2: //Software trigger
+ outw(0x0201,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ break;
+ default:
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } // switch(data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_ReadWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,
+ unsigned int *data); |
++----------------------------------------------------------------------------+
+| Task : Read The Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s, :pointer to subdevice structure
+ struct comedi_insn *insn :pointer to insn structure |
+| unsigned int *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI2200_ReadWatchdog(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] =
+ inw(devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI2200_Reset(struct comedi_device *dev) | |
++----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI2200_Reset(struct comedi_device * dev)
+{
+ outw(0x0, devpriv->iobase + APCI2200_DIGITAL_OP); //RESETS THE DIGITAL OUTPUTS
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_ENABLEDISABLE);
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE);
+ outw(0x0,
+ devpriv->iobase + APCI2200_WATCHDOG +
+ APCI2200_WATCHDOG_RELOAD_VALUE + 2);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
new file mode 100644
index 00000000000..0a115b4c44c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci2200.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+/********* Definitions for APCI-2200 card *****/
+
+// Card Specific information
+#define APCI2200_BOARD_VENDOR_ID 0x15b8
+#define APCI2200_ADDRESS_RANGE 64
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI2200_DIGITAL_OP 4
+#define APCI2200_DIGITAL_IP 0
+
+// TIMER COUNTER WATCHDOG DEFINES
+
+#define APCI2200_WATCHDOG 0x08
+#define APCI2200_WATCHDOG_ENABLEDISABLE 12
+#define APCI2200_WATCHDOG_RELOAD_VALUE 4
+#define APCI2200_WATCHDOG_STATUS 16
+
+// Hardware Layer functions for Apci2200
+
+//Digital Input
+INT i_APCI2200_ReadMoreDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_Read1DigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//Digital Output
+int i_APCI2200_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI2200_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+int i_APCI2200_ConfigWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2200_StartStopWriteWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI2200_ReadWatchdog(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//reset
+INT i_APCI2200_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
new file mode 100644
index 00000000000..68eb8dfd513
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
@@ -0,0 +1,2697 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : APCI-3120 | Compiler : GCC |
+ | Module name : hwdrv_apci3120.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-----------------------------------------------------------------------+
+ | Description :APCI3120 Module. Hardware abstraction Layer for APCI3120|
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#include "hwdrv_apci3120.h"
+static UINT ui_Temp = 0;
+
+// FUNCTION DEFINITIONS
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev,|
+| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Calls card specific function |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT i;
+
+ if ((data[0] != APCI3120_EOC_MODE) && (data[0] != APCI3120_EOS_MODE))
+ return -1;
+
+ // Check for Conversion time to be added ??
+ devpriv->ui_EocEosConversionTime = data[2];
+
+ if (data[0] == APCI3120_EOS_MODE) {
+
+ //Test the number of the channel
+ for (i = 0; i < data[3]; i++) {
+
+ if (CR_CHAN(data[4 + i]) >= this_board->i_NbrAiChannel) {
+ printk("bad channel list\n");
+ return -2;
+ }
+ }
+
+ devpriv->b_InterruptMode = APCI3120_EOS_MODE;
+
+ if (data[1]) {
+ devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+ } else
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ // Copy channel list and Range List to devpriv
+
+ devpriv->ui_AiNbrofChannels = data[3];
+ for (i = 0; i < devpriv->ui_AiNbrofChannels; i++) {
+ devpriv->ui_AiChannelList[i] = data[4 + i];
+ }
+
+ } else // EOC
+ {
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ if (data[1]) {
+ devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+ } else {
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ }
+ }
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : card specific function |
+| Reads analog input in synchronous mode |
+| EOC and EOS is selected as per configured |
+| if no conversion time is set uses default conversion |
+| time 10 microsec. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ USHORT us_ConvertTiming, us_TmpValue, i;
+ BYTE b_Tmp;
+
+ // fix convertion time to 10 us
+ if (!devpriv->ui_EocEosConversionTime) {
+ printk("No timer0 Value using 10 us\n");
+ us_ConvertTiming = 10;
+ } else
+ us_ConvertTiming = (USHORT) (devpriv->ui_EocEosConversionTime / 1000); // nano to useconds
+
+ // this_board->i_hwdrv_InsnReadAnalogInput(dev,us_ConvertTiming,insn->n,&insn->chanspec,data,insn->unused[0]);
+
+ // Clear software registers
+ devpriv->b_TimerSelectMode = 0;
+ devpriv->b_ModeSelectRegister = 0;
+ devpriv->us_OutputRegister = 0;
+// devpriv->b_DigitalOutputRegister=0;
+
+ if (insn->unused[0] == 222) // second insn read
+ {
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ui_AiReadData[i];
+ }
+
+ } else {
+ devpriv->tsk_Current = current; // Save the current process task structure
+ //Testing if board have the new Quartz and calculate the time value
+ //to set in the timer
+
+ us_TmpValue =
+ (USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ us_ConvertTiming = (us_ConvertTiming * 2) - 2;
+ } else {
+ us_ConvertTiming =
+ ((us_ConvertTiming * 12926) / 10000) - 1;
+ }
+
+ us_TmpValue = (USHORT) devpriv->b_InterruptMode;
+
+ switch (us_TmpValue) {
+
+ case APCI3120_EOC_MODE:
+
+ // Testing the interrupt flag and set the EOC bit
+ // Clears the FIFO
+ inw(devpriv->iobase + APCI3120_RESET_FIFO);
+
+ // Initialize the sequence array
+
+ //if (!i_APCI3120_SetupChannelList(dev,s,1,chanlist,0)) return -EINVAL;
+
+ if (!i_APCI3120_SetupChannelList(dev, s, 1,
+ &insn->chanspec, 0))
+ return -EINVAL;
+
+ //Initialize Timer 0 mode 4
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) |
+ APCI3120_TIMER_0_MODE_4;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ // Reset the scan bit and Disables the EOS, DMA, EOC interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_SCAN;
+
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+
+ //Disables the EOS,DMA and enables the EOC interrupt
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_EOS_INT) |
+ APCI3120_ENABLE_EOC_INT;
+ inw(devpriv->iobase);
+
+ } else {
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+ }
+
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // Sets gate 0
+ devpriv->us_OutputRegister =
+ (devpriv->
+ us_OutputRegister & APCI3120_CLEAR_PA_PR) |
+ APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ // Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(us_ConvertTiming,
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ us_TmpValue =
+ (USHORT) inw(dev->iobase + APCI3120_RD_STATUS);
+
+ if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) {
+
+ do {
+ // Waiting for the end of conversion
+ us_TmpValue =
+ inw(devpriv->iobase +
+ APCI3120_RD_STATUS);
+ } while ((us_TmpValue & APCI3120_EOC) ==
+ APCI3120_EOC);
+
+ //Read the result in FIFO and put it in insn data pointer
+ us_TmpValue = inw(devpriv->iobase + 0);
+ *data = us_TmpValue;
+
+ inw(devpriv->iobase + APCI3120_RESET_FIFO);
+ }
+
+ break;
+
+ case APCI3120_EOS_MODE:
+
+ inw(devpriv->iobase);
+ // Clears the FIFO
+ inw(devpriv->iobase + APCI3120_RESET_FIFO);
+ // clear PA PR and disable timer 0
+
+ devpriv->us_OutputRegister =
+ (devpriv->
+ us_OutputRegister & APCI3120_CLEAR_PA_PR) |
+ APCI3120_DISABLE_TIMER0;
+
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ if (!i_APCI3120_SetupChannelList(dev, s,
+ devpriv->ui_AiNbrofChannels,
+ devpriv->ui_AiChannelList, 0))
+ return -EINVAL;
+
+ //Initialize Timer 0 mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) |
+ APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(us_ConvertTiming,
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Set the scan bit
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister | APCI3120_ENABLE_SCAN;
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ //If Interrupt function is loaded
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+ //Disables the EOC,DMA and enables the EOS interrupt
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_EOC_INT) |
+ APCI3120_ENABLE_EOS_INT;
+ inw(devpriv->iobase);
+
+ } else
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER;
+
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //Sets gate 0
+
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ //Start conversion
+ outw(0, devpriv->iobase + APCI3120_START_CONVERSION);
+
+ //Waiting of end of convertion if interrupt is not installed
+ if (devpriv->b_EocEosInterrupt == APCI3120_DISABLE) {
+ //Waiting the end of convertion
+ do {
+ us_TmpValue =
+ inw(devpriv->iobase +
+ APCI3120_RD_STATUS);
+ }
+ while ((us_TmpValue & APCI3120_EOS) !=
+ APCI3120_EOS);
+
+ for (i = 0; i < devpriv->ui_AiNbrofChannels;
+ i++) {
+ //Read the result in FIFO and write them in shared memory
+ us_TmpValue = inw(devpriv->iobase);
+ data[i] = (UINT) us_TmpValue;
+ }
+
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE; // Restore defaults.
+ }
+ break;
+
+ default:
+ printk("inputs wrong\n");
+
+ }
+ devpriv->ui_EocEosConversionTime = 0; // re initializing the variable;
+ }
+
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev,|
+| struct comedi_subdevice *s)|
+| |
++----------------------------------------------------------------------------+
+| Task : Stops Cyclic acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ // Disable A2P Fifo write and AMWEN signal
+ outw(0, devpriv->i_IobaseAddon + 4);
+
+ //Disable Bus Master ADD ON
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(0, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(0, devpriv->i_IobaseAddon + 2);
+
+ //Disable BUS Master PCI
+ outl(0, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+
+ //outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR)&(~AINT_WRITE_COMPL), devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR); // stop amcc irqs
+ //outl(inl(devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR)&(~EN_A2P_TRANSFERS), devpriv->i_IobaseAmcc+AMCC_OP_REG_MCSR); // stop DMA
+
+ //Disable ext trigger
+ i_APCI3120_ExttrigDisable(dev);
+
+ devpriv->us_OutputRegister = 0;
+ //stop counters
+ outw(devpriv->
+ us_OutputRegister & APCI3120_DISABLE_TIMER0 &
+ APCI3120_DISABLE_TIMER1, dev->iobase + APCI3120_WR_ADDRESS);
+
+ outw(APCI3120_DISABLE_ALL_TIMER, dev->iobase + APCI3120_WR_ADDRESS);
+
+ //DISABLE_ALL_INTERRUPT
+ outb(APCI3120_DISABLE_ALL_INTERRUPT,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+ //Flush FIFO
+ inb(dev->iobase + APCI3120_RESET_FIFO);
+ inw(dev->iobase + APCI3120_RD_STATUS);
+ devpriv->ui_AiActualScan = 0;
+ devpriv->ui_AiActualScanPosition = 0;
+ s->async->cur_chan = 0;
+ devpriv->ui_AiBufferPtr = 0;
+ devpriv->b_AiContinuous = 0;
+ devpriv->ui_DmaActualBuffer = 0;
+
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ i_APCI3120_Reset(dev);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev|
+| ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
+| |
++----------------------------------------------------------------------------+
+| Task : Test validity for a command for cyclic anlog input |
+| acquisition |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_cmd *cmd |
++----------------------------------------------------------------------------+
+| Return Value :0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CommandTestAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp; // divisor1,divisor2;
+
+ // step 1: make sure trigger sources are trivially valid
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ //step 2: make sure trigger sources are unique and mutually compatible
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+
+ if (cmd->convert_src != TRIG_TIMER)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err)
+ return 2;
+
+ // step 3: make sure arguments are trivially compatible
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) // Test Delay timing
+ {
+ if (cmd->scan_begin_arg < this_board->ui_MinDelaytimeNs) {
+ cmd->scan_begin_arg = this_board->ui_MinDelaytimeNs;
+ err++;
+ }
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) // Test Acquisition timing
+ {
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if ((cmd->convert_arg)
+ && (cmd->convert_arg <
+ this_board->ui_MinAcquisitiontimeNs)) {
+ cmd->convert_arg =
+ this_board->ui_MinAcquisitiontimeNs;
+ err++;
+ }
+ } else {
+ if (cmd->convert_arg <
+ this_board->ui_MinAcquisitiontimeNs) {
+ cmd->convert_arg =
+ this_board->ui_MinAcquisitiontimeNs;
+ err++;
+
+ }
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > this_board->i_AiChannelList) {
+ cmd->chanlist_len = this_board->i_AiChannelList;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { // TRIG_NONE
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ // step 4: fix up any arguments
+
+ if (cmd->convert_src == TRIG_TIMER) {
+
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, |
+| struct comedi_subdevice *s) |
+| |
++----------------------------------------------------------------------------+
+| Task : Does asynchronous acquisition |
+| Determines the mode 1 or 2. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CommandAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ //loading private structure with cmd structure inputs
+ devpriv->ui_AiFlags = cmd->flags;
+ devpriv->ui_AiNbrofChannels = cmd->chanlist_len;
+ devpriv->ui_AiScanLength = cmd->scan_end_arg;
+ devpriv->pui_AiChannelList = cmd->chanlist;
+
+ //UPDATE-0.7.57->0.7.68devpriv->AiData=s->async->data;
+ devpriv->AiData = s->async->prealloc_buf;
+ //UPDATE-0.7.57->0.7.68devpriv->ui_AiDataLength=s->async->data_len;
+ devpriv->ui_AiDataLength = s->async->prealloc_bufsz;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ui_AiNbrofScans = cmd->stop_arg;
+ } else {
+ devpriv->ui_AiNbrofScans = 0;
+ }
+
+ devpriv->ui_AiTimer0 = 0; // variables changed to timer0,timer1
+ devpriv->ui_AiTimer1 = 0;
+ if ((devpriv->ui_AiNbrofScans == 0) || (devpriv->ui_AiNbrofScans == -1))
+ devpriv->b_AiContinuous = 1; // user want neverending analog acquisition
+ // stopped using cancel
+
+ if (cmd->start_src == TRIG_EXT)
+ devpriv->b_ExttrigEnable = APCI3120_ENABLE;
+ else
+ devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ // mode 1 or 3
+ if (cmd->convert_src == TRIG_TIMER) {
+ // mode 1
+
+ devpriv->ui_AiTimer0 = cmd->convert_arg; // timer constant in nano seconds
+ //return this_board->i_hwdrv_CommandAnalogInput(1,dev,s);
+ return i_APCI3120_CyclicAnalogInput(1, dev, s);
+ }
+
+ }
+ if ((cmd->scan_begin_src == TRIG_TIMER)
+ && (cmd->convert_src == TRIG_TIMER)) {
+ // mode 2
+ devpriv->ui_AiTimer1 = cmd->scan_begin_arg;
+ devpriv->ui_AiTimer0 = cmd->convert_arg; // variable changed timer2 to timer0
+ //return this_board->i_hwdrv_CommandAnalogInput(2,dev,s);
+ return i_APCI3120_CyclicAnalogInput(2, dev, s);
+ }
+ return -1;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_CyclicAnalogInput(int mode, |
+| struct comedi_device * dev,struct comedi_subdevice * s) |
++----------------------------------------------------------------------------+
+| Task : This is used for analog input cyclic acquisition |
+| Performs the command operations. |
+| If DMA is configured does DMA initialization |
+| otherwise does the acquisition with EOS interrupt. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ BYTE b_Tmp;
+ UINT ui_Tmp, ui_DelayTiming = 0, ui_TimerValue1 = 0, dmalen0 =
+ 0, dmalen1 = 0, ui_TimerValue2 =
+ 0, ui_TimerValue0, ui_ConvertTiming;
+ USHORT us_TmpValue;
+
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //devpriv->b_AiCyclicAcquisition=APCI3120_ENABLE;
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /*******************/
+ /* Resets the FIFO */
+ /*******************/
+ inb(dev->iobase + APCI3120_RESET_FIFO);
+
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //inw(dev->iobase+APCI3120_RD_STATUS);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /***************************/
+ /* Acquisition initialized */
+ /***************************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ devpriv->b_AiCyclicAcquisition = APCI3120_ENABLE;
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ // clear software registers
+ devpriv->b_TimerSelectMode = 0;
+ devpriv->us_OutputRegister = 0;
+ devpriv->b_ModeSelectRegister = 0;
+ //devpriv->b_DigitalOutputRegister=0;
+
+ //COMMENT JK 07.05.04: Followings calls are in i_APCI3120_StartAnalogInputAcquisition
+
+ /****************************/
+ /* Clear Timer Write TC INT */
+ /****************************/
+ outl(APCI3120_CLEAR_WRITE_TC_INT,
+ devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_REG_INTCSR);
+
+ /************************************/
+ /* Clears the timer status register */
+ /************************************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //inw(dev->iobase+APCI3120_TIMER_STATUS_REGISTER);
+ inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /**************************/
+ /* Disables All Timer */
+ /* Sets PR and PA to 0 */
+ /**************************/
+ devpriv->us_OutputRegister = devpriv->us_OutputRegister &
+ APCI3120_DISABLE_TIMER0 &
+ APCI3120_DISABLE_TIMER1 & APCI3120_CLEAR_PA_PR;
+
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+ /*******************/
+ /* Resets the FIFO */
+ /*******************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ inb(devpriv->iobase + APCI3120_RESET_FIFO);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ devpriv->ui_AiActualScan = 0;
+ devpriv->ui_AiActualScanPosition = 0;
+ s->async->cur_chan = 0;
+ devpriv->ui_AiBufferPtr = 0;
+ devpriv->ui_DmaActualBuffer = 0;
+
+ // value for timer2 minus -2 has to be done .....dunno y??
+ ui_TimerValue2 = devpriv->ui_AiNbrofScans - 2;
+ ui_ConvertTiming = devpriv->ui_AiTimer0;
+
+ if (mode == 2)
+ ui_DelayTiming = devpriv->ui_AiTimer1;
+
+ /**********************************/
+ /* Initializes the sequence array */
+ /**********************************/
+ if (!i_APCI3120_SetupChannelList(dev, s, devpriv->ui_AiNbrofChannels,
+ devpriv->pui_AiChannelList, 0))
+ return -EINVAL;
+
+ us_TmpValue = (USHORT) inw(dev->iobase + APCI3120_RD_STATUS);
+/*** EL241003 : add this section in comment because floats must not be used
+ if((us_TmpValue & 0x00B0)==0x00B0)
+ {
+ f_ConvertValue=(((float)ui_ConvertTiming * 0.002) - 2);
+ ui_TimerValue0=(UINT)f_ConvertValue;
+ if (mode==2)
+ {
+ f_DelayValue = (((float)ui_DelayTiming * 0.00002) - 2);
+ ui_TimerValue1 = (UINT) f_DelayValue;
+ }
+ }
+ else
+ {
+ f_ConvertValue=(((float)ui_ConvertTiming * 0.0012926) - 1);
+ ui_TimerValue0=(UINT)f_ConvertValue;
+ if (mode == 2)
+ {
+ f_DelayValue = (((float)ui_DelayTiming * 0.000012926) - 1);
+ ui_TimerValue1 = (UINT) f_DelayValue;
+ }
+ }
+***********************************************************************************************/
+/*** EL241003 Begin : add this section to replace floats calculation by integer calculations **/
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ ui_TimerValue0 = ui_ConvertTiming * 2 - 2000;
+ ui_TimerValue0 = ui_TimerValue0 / 1000;
+
+ if (mode == 2) {
+ ui_DelayTiming = ui_DelayTiming / 1000;
+ ui_TimerValue1 = ui_DelayTiming * 2 - 200;
+ ui_TimerValue1 = ui_TimerValue1 / 100;
+ }
+ } else {
+ ui_ConvertTiming = ui_ConvertTiming / 1000;
+ ui_TimerValue0 = ui_ConvertTiming * 12926 - 10000;
+ ui_TimerValue0 = ui_TimerValue0 / 10000;
+
+ if (mode == 2) {
+ ui_DelayTiming = ui_DelayTiming / 1000;
+ ui_TimerValue1 = ui_DelayTiming * 12926 - 1;
+ ui_TimerValue1 = ui_TimerValue1 / 1000000;
+ }
+ }
+/*** EL241003 End ******************************************************************************/
+
+ if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+ i_APCI3120_ExttrigEnable(dev); // activate EXT trigger
+ }
+ switch (mode) {
+ case 1:
+ // init timer0 in mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ //Set the convertion time
+ outw(((USHORT) ui_TimerValue0),
+ dev->iobase + APCI3120_TIMER_VALUE);
+ break;
+
+ case 2:
+ // init timer1 in mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xF3) | APCI3120_TIMER_1_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 1
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_1_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ //Set the convertion time
+ outw(((USHORT) ui_TimerValue1),
+ dev->iobase + APCI3120_TIMER_VALUE);
+
+ // init timer0 in mode 2
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0xFC) | APCI3120_TIMER_0_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Select Timer 0
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_0_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+
+ //Set the convertion time
+ outw(((USHORT) ui_TimerValue0),
+ dev->iobase + APCI3120_TIMER_VALUE);
+ break;
+
+ }
+ // ##########common for all modes#################
+
+ /***********************/
+ /* Clears the SCAN bit */
+ /***********************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister | APCI3120_DISABLE_SCAN;
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &
+ APCI3120_DISABLE_SCAN;
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // If DMA is disabled
+ if (devpriv->us_UseDma == APCI3120_DISABLE) {
+ // disable EOC and enable EOS
+ devpriv->b_InterruptMode = APCI3120_EOS_MODE;
+ devpriv->b_EocEosInterrupt = APCI3120_ENABLE;
+
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT) |
+ APCI3120_ENABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ if (!devpriv->b_AiContinuous) {
+ // configure Timer2 For counting EOS
+ //Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister & APCI3120_DISABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+
+ // DISABLE TIMER INTERRUPT
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_INT & 0xEF;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ //(1) Init timer 2 in mode 0 and write timer value
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0x0F) |
+ APCI3120_TIMER_2_MODE_0;
+ outb(devpriv->b_TimerSelectMode,
+ dev->iobase + APCI3120_TIMER_CRT1);
+
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_TimerValue2),
+ dev->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, dev->iobase + APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_TimerValue2),
+ dev->iobase + APCI3120_TIMER_VALUE);
+
+ //(2) Reset FC_TIMER BIT Clearing timer status register
+ inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ // enable timer counter and disable watch dog
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_TIMER_COUNTER) &
+ APCI3120_DISABLE_WATCHDOG;
+ // select EOS clock input for timer 2
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_TIMER2_SELECT_EOS;
+ // Enable timer2 interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_TIMER_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+ devpriv->b_Timer2Mode = APCI3120_COUNTER;
+ devpriv->b_Timer2Interrupt = APCI3120_ENABLE;
+ }
+ } else {
+ // If DMA Enabled
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //inw(dev->iobase+0);// reset EOC bit
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+ devpriv->b_InterruptMode = APCI3120_DMA_MODE;
+
+ /************************************/
+ /* Disables the EOC, EOS interrupt */
+ /************************************/
+ devpriv->b_ModeSelectRegister = devpriv->b_ModeSelectRegister &
+ APCI3120_DISABLE_EOC_INT & APCI3120_DISABLE_EOS_INT;
+
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ dmalen0 = devpriv->ui_DmaBufferSize[0];
+ dmalen1 = devpriv->ui_DmaBufferSize[1];
+
+ if (!devpriv->b_AiContinuous) {
+
+ if (dmalen0 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2)) { // must we fill full first buffer?
+ dmalen0 =
+ devpriv->ui_AiNbrofScans *
+ devpriv->ui_AiScanLength * 2;
+ } else if (dmalen1 > (devpriv->ui_AiNbrofScans * devpriv->ui_AiScanLength * 2 - dmalen0)) // and must we fill full second buffer when first is once filled?
+ dmalen1 =
+ devpriv->ui_AiNbrofScans *
+ devpriv->ui_AiScanLength * 2 - dmalen0;
+ }
+
+ if (devpriv->ui_AiFlags & TRIG_WAKE_EOS) {
+ // don't we want wake up every scan?
+ if (dmalen0 > (devpriv->ui_AiScanLength * 2)) {
+ dmalen0 = devpriv->ui_AiScanLength * 2;
+ if (devpriv->ui_AiScanLength & 1)
+ dmalen0 += 2;
+ }
+ if (dmalen1 > (devpriv->ui_AiScanLength * 2)) {
+ dmalen1 = devpriv->ui_AiScanLength * 2;
+ if (devpriv->ui_AiScanLength & 1)
+ dmalen1 -= 2;
+ if (dmalen1 < 4)
+ dmalen1 = 4;
+ }
+ } else { // isn't output buff smaller that our DMA buff?
+ if (dmalen0 > (devpriv->ui_AiDataLength)) {
+ dmalen0 = devpriv->ui_AiDataLength;
+ }
+ if (dmalen1 > (devpriv->ui_AiDataLength)) {
+ dmalen1 = devpriv->ui_AiDataLength;
+ }
+ }
+ devpriv->ui_DmaBufferUsesize[0] = dmalen0;
+ devpriv->ui_DmaBufferUsesize[1] = dmalen1;
+
+ //Initialize DMA
+
+ // Set Transfer count enable bit and A2P_fifo reset bit in AGCSTS register
+ //1
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAmcc + AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ /*********************/
+ /* ENABLE BUS MASTER */
+ /*********************/
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH,
+ devpriv->i_IobaseAddon + 2);
+
+ // TO VERIFIED
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ outw(0x1000, devpriv->i_IobaseAddon + 2);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ //2 No change
+ // A2P FIFO MANAGEMENT
+ // A2P fifo reset & transfer control enable
+ /***********************/
+ /* A2P FIFO MANAGEMENT */
+ /***********************/
+ outl(APCI3120_A2P_FIFO_MANAGEMENT, devpriv->i_IobaseAmcc +
+ APCI3120_AMCC_OP_MCSR);
+
+ //3
+ //beginning address of dma buf
+ //The 32 bit address of dma buffer is converted into two 16 bit addresses
+ // Can done by using _attach and put into into an array
+ // array used may be for differnet pages
+
+ // DMA Start Adress Low
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ul_DmaBufferHw[0] & 0xFFFF),
+ devpriv->i_IobaseAddon + 2);
+
+ /*************************/
+ /* DMA Start Adress High */
+ /*************************/
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ul_DmaBufferHw[0] / 65536),
+ devpriv->i_IobaseAddon + 2);
+
+ //4
+ // amount of bytes to be transfered set transfer count
+ // used ADDON MWTC register
+ //commented testing outl(devpriv->ui_DmaBufferUsesize[0], devpriv->i_IobaseAddon+AMCC_OP_REG_AMWTC);
+
+ /**************************/
+ /* Nbr of acquisition LOW */
+ /**************************/
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ui_DmaBufferUsesize[0] & 0xFFFF),
+ devpriv->i_IobaseAddon + 2);
+
+ /***************************/
+ /* Nbr of acquisition HIGH */
+ /***************************/
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw((devpriv->ui_DmaBufferUsesize[0] / 65536),
+ devpriv->i_IobaseAddon + 2);
+
+ //5
+ // To configure A2P FIFO
+ // testing outl( FIFO_ADVANCE_ON_BYTE_2,devpriv->i_IobaseAmcc+AMCC_OP_REG_INTCSR);
+
+ /******************/
+ /* A2P FIFO RESET */
+ /******************/
+ // TO VERIFY
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ outl(0x04000000UL, devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ //6
+ //ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ //outw(3,devpriv->i_IobaseAddon + 4);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ //7
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ /***************************************************/
+ /* A2P FIFO CONFIGURATE, END OF DMA INTERRUPT INIT */
+ /***************************************************/
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ /******************************************/
+ /* ENABLE A2P FIFO WRITE AND ENABLE AMWEN */
+ /******************************************/
+ outw(3, devpriv->i_IobaseAddon + 4);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+
+ /******************/
+ /* A2P FIFO RESET */
+ /******************/
+ //BEGIN JK 07.05.04: Comparison between WIN32 and Linux driver
+ outl(0x04000000UL,
+ devpriv->i_IobaseAmcc + APCI3120_AMCC_OP_MCSR);
+ //END JK 07.05.04: Comparison between WIN32 and Linux driver
+ }
+
+ if ((devpriv->us_UseDma == APCI3120_DISABLE)
+ && !devpriv->b_AiContinuous) {
+ // set gate 2 to start conversion
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ }
+
+ switch (mode) {
+ case 1:
+ // set gate 0 to start conversion
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ break;
+ case 2:
+ // set gate 0 and gate 1
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER1;
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister | APCI3120_ENABLE_TIMER0;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ break;
+
+ }
+
+ return 0;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| INTERNAL FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_Reset(struct comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Hardware reset function |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_Reset(struct comedi_device * dev)
+{
+ unsigned int i;
+ unsigned short us_TmpValue;
+
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ devpriv->ui_EocEosConversionTime = 0; // set eoc eos conv time to 0
+ devpriv->b_OutputMemoryStatus = 0;
+
+ // variables used in timer subdevice
+ devpriv->b_Timer2Mode = 0;
+ devpriv->b_Timer2Interrupt = 0;
+ devpriv->b_ExttrigEnable = 0; // Disable ext trigger
+
+ /* Disable all interrupts, watchdog for the anolog output */
+ devpriv->b_ModeSelectRegister = 0;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // Disables all counters, ext trigger and clears PA, PR
+ devpriv->us_OutputRegister = 0;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+ //Code to set the all anolog o/p channel to 0v
+ //8191 is decimal value for zero(0 v)volt in bipolar mode(default)
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_1, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 1
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_2, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 2
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_3, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 3
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_4, dev->iobase + APCI3120_ANALOG_OUTPUT_1); //channel 4
+
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_5, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 5
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_6, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 6
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_7, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 7
+ outw(8191 | APCI3120_ANALOG_OP_CHANNEL_8, dev->iobase + APCI3120_ANALOG_OUTPUT_2); //channel 8
+
+ // Reset digital output to L0W
+
+//ES05 outb(0x0,dev->iobase+APCI3120_DIGITAL_OUTPUT);
+ udelay(10);
+
+ inw(dev->iobase + 0); //make a dummy read
+ inb(dev->iobase + APCI3120_RESET_FIFO); // flush FIFO
+ inw(dev->iobase + APCI3120_RD_STATUS); // flush A/D status register
+
+ //code to reset the RAM sequence
+ for (i = 0; i < 16; i++) {
+ us_TmpValue = i << 8; //select the location
+ outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+ }
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_SetupChannelList(struct comedi_device * dev, |
+| struct comedi_subdevice * s, int n_chan,unsigned int *chanlist|
+| ,char check) |
+| |
++----------------------------------------------------------------------------+
+| Task :This function will first check channel list is ok or not|
+|and then initialize the sequence RAM with the polarity, Gain,Channel number |
+|If the last argument of function "check"is 1 then it only checks the channel|
+|list is ok or not. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device * dev |
+| struct comedi_subdevice * s |
+| int n_chan |
+ unsigned int *chanlist
+ char check
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_SetupChannelList(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, char check)
+{
+ unsigned int i; //, differencial=0, bipolar=0;
+ unsigned int gain;
+ unsigned short us_TmpValue;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ if (!check)
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+ // All is ok, so we can setup channel/range list
+ if (check)
+ return 1;
+
+ //Code to set the PA and PR...Here it set PA to 0..
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister & APCI3120_CLEAR_PA_PR;
+ devpriv->us_OutputRegister = ((n_chan - 1) & 0xf) << 8;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+
+ for (i = 0; i < n_chan; i++) {
+ // store range list to card
+ us_TmpValue = CR_CHAN(chanlist[i]); // get channel number;
+
+ if (CR_RANGE(chanlist[i]) < APCI3120_BIPOLAR_RANGES) {
+ us_TmpValue &= ((~APCI3120_UNIPOLAR) & 0xff); // set bipolar
+ } else {
+ us_TmpValue |= APCI3120_UNIPOLAR; // enable unipolar......
+ }
+
+ gain = CR_RANGE(chanlist[i]); // get gain number
+ us_TmpValue |= ((gain & 0x03) << 4); //<<4 for G0 and G1 bit in RAM
+ us_TmpValue |= i << 8; //To select the RAM LOCATION....
+ outw(us_TmpValue, dev->iobase + APCI3120_SEQ_RAM_ADDRESS);
+
+ printk("\n Gain = %i",
+ (((unsigned char)CR_RANGE(chanlist[i]) & 0x03) << 2));
+ printk("\n Channel = %i", CR_CHAN(chanlist[i]));
+ printk("\n Polarity = %i", us_TmpValue & APCI3120_UNIPOLAR);
+ }
+ return 1; // we can serve this with scan logic
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_ExttrigEnable(struct comedi_device * dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Enable the external trigger |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device * dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigEnable(struct comedi_device * dev)
+{
+
+ devpriv->us_OutputRegister |= APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_ExttrigDisable(struct comedi_device * dev) |
+| |
++----------------------------------------------------------------------------+
+| Task : Disables the external trigger |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device * dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_ExttrigDisable(struct comedi_device * dev)
+{
+ devpriv->us_OutputRegister &= ~APCI3120_ENABLE_EXT_TRIGGER;
+ outw(devpriv->us_OutputRegister, dev->iobase + APCI3120_WR_ADDRESS);
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| INTERRUPT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3120_Interrupt(int irq, void *d) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task :Interrupt handler for APCI3120 |
+| When interrupt occurs this gets called. |
+| First it finds which interrupt has been generated and |
+| handles corresponding interrupt |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq |
+| void *d |
+| |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3120_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ USHORT int_daq;
+
+ unsigned int int_amcc, ui_Check, i;
+ USHORT us_TmpValue;
+ BYTE b_DummyRead;
+
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ ui_Check = 1;
+
+ int_daq = inw(dev->iobase + APCI3120_RD_STATUS) & 0xf000; // get IRQ reasons
+ int_amcc = inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); // get AMCC INT register
+
+ if ((!int_daq) && (!(int_amcc & ANY_S593X_INT))) {
+ comedi_error(dev, "IRQ from unknow source");
+ return;
+ }
+
+ outl(int_amcc | 0x00ff0000, devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR); // shutdown IRQ reasons in AMCC
+
+ int_daq = (int_daq >> 12) & 0xF;
+
+ if (devpriv->b_ExttrigEnable == APCI3120_ENABLE) {
+ //Disable ext trigger
+ i_APCI3120_ExttrigDisable(dev);
+ devpriv->b_ExttrigEnable = APCI3120_DISABLE;
+ }
+ //clear the timer 2 interrupt
+ inb(devpriv->i_IobaseAmcc + APCI3120_TIMER_STATUS_REGISTER);
+
+ if (int_amcc & MASTER_ABORT_INT)
+ comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ if (int_amcc & TARGET_ABORT_INT)
+ comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+
+ // Ckeck if EOC interrupt
+ if (((int_daq & 0x8) == 0)
+ && (devpriv->b_InterruptMode == APCI3120_EOC_MODE)) {
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) {
+
+ // Read the AI Value
+
+ devpriv->ui_AiReadData[0] =
+ (UINT) inw(devpriv->iobase + 0);
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } else {
+ //Disable EOC Interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ }
+ }
+
+ // Check If EOS interrupt
+ if ((int_daq & 0x2) && (devpriv->b_InterruptMode == APCI3120_EOS_MODE)) {
+
+ if (devpriv->b_EocEosInterrupt == APCI3120_ENABLE) // enable this in without DMA ???
+ {
+
+ if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+ ui_Check = 0;
+ i_APCI3120_InterruptHandleEos(dev);
+ devpriv->ui_AiActualScan++;
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase +
+ APCI3120_WRITE_MODE_SELECT);
+ } else {
+ ui_Check = 0;
+ for (i = 0; i < devpriv->ui_AiNbrofChannels;
+ i++) {
+ us_TmpValue = inw(devpriv->iobase + 0);
+ devpriv->ui_AiReadData[i] =
+ (UINT) us_TmpValue;
+ }
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE;
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+
+ }
+
+ } else {
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+ devpriv->b_EocEosInterrupt = APCI3120_DISABLE; //Default settings
+ devpriv->b_InterruptMode = APCI3120_EOC_MODE;
+ }
+
+ }
+ //Timer2 interrupt
+ if (int_daq & 0x1) {
+
+ switch (devpriv->b_Timer2Mode) {
+ case APCI3120_COUNTER:
+
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // stop timer 2
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister & APCI3120_DISABLE_ALL_TIMER;
+ outw(devpriv->us_OutputRegister,
+ dev->iobase + APCI3120_WR_ADDRESS);
+
+ //stop timer 0 and timer 1
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+
+ //UPDATE-0.7.57->0.7.68comedi_done(dev,s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+
+ break;
+
+ case APCI3120_TIMER:
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ break;
+
+ case APCI3120_WATCHDOG:
+
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ break;
+
+ default:
+
+ // disable Timer Interrupt
+
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_INT;
+
+ outb(devpriv->b_ModeSelectRegister,
+ dev->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ }
+
+ b_DummyRead = inb(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+
+ }
+
+ if ((int_daq & 0x4) && (devpriv->b_InterruptMode == APCI3120_DMA_MODE)) {
+ if (devpriv->b_AiCyclicAcquisition == APCI3120_ENABLE) {
+
+ /****************************/
+ /* Clear Timer Write TC INT */
+ /****************************/
+
+ outl(APCI3120_CLEAR_WRITE_TC_INT,
+ devpriv->i_IobaseAmcc +
+ APCI3120_AMCC_OP_REG_INTCSR);
+
+ /************************************/
+ /* Clears the timer status register */
+ /************************************/
+ inw(dev->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ v_APCI3120_InterruptDma(irq, d); // do some data transfer
+ } else {
+ /* Stops the Timer */
+ outw(devpriv->
+ us_OutputRegister & APCI3120_DISABLE_TIMER0 &
+ APCI3120_DISABLE_TIMER1,
+ dev->iobase + APCI3120_WR_ADDRESS);
+ }
+
+ }
+
+ return;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InterruptHandleEos(struct comedi_device *dev) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : This function handles EOS interrupt. |
+| This function copies the acquired data(from FIFO) |
+| to Comedi buffer. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| |
+| |
++----------------------------------------------------------------------------+
+| Return Value : 0 |
+| |
++----------------------------------------------------------------------------+
+*/
+
+/*
+ * int i_APCI3120_InterruptHandleEos(struct comedi_device *dev)
+{
+ int n_chan,i;
+ short *data;
+ struct comedi_subdevice *s=dev->subdevices+0;
+ struct comedi_async *async = s->async;
+ data=async->data+async->buf_int_ptr;
+ n_chan=devpriv->ui_AiNbrofChannels;
+
+ for(i=0;i<n_chan;i++)
+ {
+ data[i]=inw(dev->iobase+0);
+ }
+ async->buf_int_count+=n_chan*sizeof(short);
+ async->buf_int_ptr+=n_chan*sizeof(short);
+ comedi_eos(dev,s);
+ if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over
+ {
+*//* buffer rollover */
+/* s->async->buf_int_ptr=0;
+ comedi_eobuf(dev,s);
+ }
+ return 0;
+}*/
+int i_APCI3120_InterruptHandleEos(struct comedi_device * dev)
+{
+ int n_chan, i;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int err = 1;
+
+ n_chan = devpriv->ui_AiNbrofChannels;
+
+ s->async->events = 0;
+
+ for (i = 0; i < n_chan; i++)
+ err &= comedi_buf_put(s->async, inw(dev->iobase + 0));
+
+ s->async->events |= COMEDI_CB_EOS;
+
+ if (err == 0)
+ s->async->events |= COMEDI_CB_OVERFLOW;
+
+ comedi_event(dev, s);
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3120_InterruptDma(int irq, void *d) |
+| |
++----------------------------------------------------------------------------+
+| Task : This is a handler for the DMA interrupt |
+| This function copies the data to Comedi Buffer. |
+| For continuous DMA it reinitializes the DMA operation. |
+| For single mode DMA it stop the acquisition. |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq, void *d |
+| |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3120_InterruptDma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ unsigned int next_dma_buf, samplesinbuf;
+ unsigned long low_word, high_word, var;
+
+ UINT ui_Tmp;
+ samplesinbuf =
+ devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer] -
+ inl(devpriv->i_IobaseAmcc + AMCC_OP_REG_MWTC);
+
+ if (samplesinbuf <
+ devpriv->ui_DmaBufferUsesize[devpriv->ui_DmaActualBuffer]) {
+ comedi_error(dev, "Interrupted DMA transfer!");
+ }
+ if (samplesinbuf & 1) {
+ comedi_error(dev, "Odd count of bytes in DMA ring!");
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+
+ return;
+ }
+ samplesinbuf = samplesinbuf >> 1; // number of received samples
+ if (devpriv->b_DmaDoubleBuffer) {
+ // switch DMA buffers if is used double buffering
+ next_dma_buf = 1 - devpriv->ui_DmaActualBuffer;
+
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); // 0x1000 is out putted in windows driver
+
+ var = devpriv->ul_DmaBufferHw[next_dma_buf];
+ low_word = var & 0xffff;
+ var = devpriv->ul_DmaBufferHw[next_dma_buf];
+ high_word = var / 65536;
+
+ /* DMA Start Adress Low */
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+
+ /* DMA Start Adress High */
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ low_word = var & 0xffff;
+ var = devpriv->ui_DmaBufferUsesize[next_dma_buf];
+ high_word = var / 65536;
+
+ /* Nbr of acquisition LOW */
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+
+ /* Nbr of acquisition HIGH */
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ // To configure A2P FIFO
+ // ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ outw(3, devpriv->i_IobaseAddon + 4);
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+
+ }
+/*UPDATE-0.7.57->0.7.68
+ ptr=(short *)devpriv->ul_DmaBufferVirtual[devpriv->ui_DmaActualBuffer];
+
+
+ // if there is not enough space left in the buffer to copy all data contained in the DMABufferVirtual
+ if(s->async->buf_int_ptr+samplesinbuf*sizeof(short)>=devpriv->ui_AiDataLength)
+ {
+ m=(devpriv->ui_AiDataLength-s->async->buf_int_ptr)/sizeof(short);
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,m);
+ s->async->buf_int_count+=m*sizeof(short);
+ ptr+=m*sizeof(short);
+ samplesinbuf-=m;
+ s->async->buf_int_ptr=0;
+ comedi_eobuf(dev,s);
+ }
+
+ if (samplesinbuf)
+ {
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev,s,(void *)ptr,((void *)(devpriv->AiData))+s->async->buf_int_ptr,samplesinbuf);
+
+ s->async->buf_int_count+=samplesinbuf*sizeof(short);
+ s->async->buf_int_ptr+=samplesinbuf*sizeof(short);
+ if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS))
+ {
+ comedi_bufcheck(dev,s);
+ }
+ }
+ if (!devpriv->b_AiContinuous)
+ if ( devpriv->ui_AiActualScan>=devpriv->ui_AiNbrofScans )
+ {
+ // all data sampled
+ i_APCI3120_StopCyclicAcquisition(dev,s);
+ devpriv->b_AiCyclicAcquisition=APCI3120_DISABLE;
+ //DPRINTK("\n Single DMA completed..\n");
+ comedi_done(dev,s);
+ return;
+ }
+*/
+ if (samplesinbuf) {
+ v_APCI3120_InterruptDmaMoveBlock16bit(dev, s,
+ devpriv->ul_DmaBufferVirtual[devpriv->
+ ui_DmaActualBuffer], samplesinbuf);
+
+ if (!(devpriv->ui_AiFlags & TRIG_WAKE_EOS)) {
+ s->async->events |= COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ }
+ }
+ if (!devpriv->b_AiContinuous)
+ if (devpriv->ui_AiActualScan >= devpriv->ui_AiNbrofScans) {
+ // all data sampled
+ i_APCI3120_StopCyclicAcquisition(dev, s);
+ devpriv->b_AiCyclicAcquisition = APCI3120_DISABLE;
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+
+ if (devpriv->b_DmaDoubleBuffer) { // switch dma buffers
+ devpriv->ui_DmaActualBuffer = 1 - devpriv->ui_DmaActualBuffer;
+ } else {
+ // restart DMA if is not used double buffering
+ //ADDED REINITIALISE THE DMA
+ ui_Tmp = AGCSTS_TC_ENABLE | AGCSTS_RESET_A2P_FIFO;
+ outl(ui_Tmp, devpriv->i_IobaseAddon + AMCC_OP_REG_AGCSTS);
+
+ // changed since 16 bit interface for add on
+ outw(APCI3120_ADD_ON_AGCSTS_LOW, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_LOW,
+ devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_AGCSTS_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(APCI3120_ENABLE_TRANSFER_ADD_ON_HIGH, devpriv->i_IobaseAddon + 2); //
+ // A2P FIFO MANAGEMENT
+ // A2P fifo reset & transfer control enable
+ outl(APCI3120_A2P_FIFO_MANAGEMENT,
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_MCSR);
+
+ var = devpriv->ul_DmaBufferHw[0];
+ low_word = var & 0xffff;
+ var = devpriv->ul_DmaBufferHw[0];
+ high_word = var / 65536;
+ outw(APCI3120_ADD_ON_MWAR_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_MWAR_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ var = devpriv->ui_DmaBufferUsesize[0];
+ low_word = var & 0xffff; //changed
+ var = devpriv->ui_DmaBufferUsesize[0];
+ high_word = var / 65536;
+ outw(APCI3120_ADD_ON_MWTC_LOW, devpriv->i_IobaseAddon + 0);
+ outw(low_word, devpriv->i_IobaseAddon + 2);
+ outw(APCI3120_ADD_ON_MWTC_HIGH, devpriv->i_IobaseAddon + 0);
+ outw(high_word, devpriv->i_IobaseAddon + 2);
+
+ // To configure A2P FIFO
+ //ENABLE A2P FIFO WRITE AND ENABLE AMWEN
+ // AMWEN_ENABLE | A2P_FIFO_WRITE_ENABLE (0x01|0x02)=0x03
+ outw(3, devpriv->i_IobaseAddon + 4);
+ //initialise end of dma interrupt AINT_WRITE_COMPL = ENABLE_WRITE_TC_INT(ADDI)
+ outl((APCI3120_FIFO_ADVANCE_ON_BYTE_2 |
+ APCI3120_ENABLE_WRITE_TC_INT),
+ devpriv->i_IobaseAmcc + AMCC_OP_REG_INTCSR);
+ }
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :void v_APCI3120_InterruptDmaMoveBlock16bit(comedi_device|
+|*dev,struct comedi_subdevice *s,short *dma,short *data,int n) |
+| |
++----------------------------------------------------------------------------+
+| Task : This function copies the data from DMA buffer to the |
+| Comedi buffer |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| short *dma |
+| short *data,int n |
++----------------------------------------------------------------------------+
+| Return Value : void |
+| |
++----------------------------------------------------------------------------+
+*/
+
+/*void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n)
+{
+ int i,j,m;
+
+ j=s->async->cur_chan;
+ m=devpriv->ui_AiActualScanPosition;
+ for(i=0;i<n;i++)
+ {
+ *data=*dma;
+ data++; dma++;
+ j++;
+ if(j>=devpriv->ui_AiNbrofChannels)
+ {
+ m+=j;
+ j=0;
+ if(m>=devpriv->ui_AiScanLength)
+ {
+ m=0;
+ devpriv->ui_AiActualScan++;
+ if (devpriv->ui_AiFlags & TRIG_WAKE_EOS)
+;//UPDATE-0.7.57->0.7.68 comedi_eos(dev,s);
+ }
+ }
+ }
+ devpriv->ui_AiActualScanPosition=m;
+ s->async->cur_chan=j;
+
+}
+*/
+void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device * dev,
+ struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+ devpriv->ui_AiActualScan +=
+ (s->async->cur_chan + num_samples) / devpriv->ui_AiScanLength;
+ s->async->cur_chan += num_samples;
+ s->async->cur_chan %= devpriv->ui_AiScanLength;
+
+ cfc_write_array_to_buffer(s, dma_buffer, num_samples * sizeof(short));
+}
+
+/*
++----------------------------------------------------------------------------+
+| TIMER SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task :Configure Timer 2 |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+| |
+| data[0]= TIMER configure as timer |
+| = WATCHDOG configure as watchdog |
+| data[1] = Timer constant |
+| data[2] = Timer2 interrupt (1)enable or(0) disable |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Timervalue2;
+ USHORT us_TmpValue;
+ BYTE b_Tmp;
+
+ if (!data[1])
+ comedi_error(dev, "config:No timer constant !");
+
+ devpriv->b_Timer2Interrupt = (BYTE) data[2]; // save info whether to enable or disable interrupt
+
+ ui_Timervalue2 = data[1] / 1000; // convert nano seconds to u seconds
+
+ //this_board->i_hwdrv_InsnConfigTimer(dev, ui_Timervalue2,(BYTE)data[0]);
+ us_TmpValue = (USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ // and calculate the time value to set in the timer
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 50;
+ } else {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 70;
+ }
+
+ //Reset gate 2 of Timer 2 to disable it (Set Bit D14 to 0)
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER2;
+ outw(devpriv->us_OutputRegister, devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ // Disable TIMER Interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT & 0xEF;
+
+ // Disable Eoc and Eos Interrupts
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_EOC_INT &
+ APCI3120_DISABLE_EOS_INT;
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+ if (data[0] == APCI3120_TIMER) //initialize timer
+ {
+
+ //devpriv->b_ModeSelectRegister=devpriv->b_ModeSelectRegister| APCI3120_ENABLE_TIMER_INT ;
+ //outb(devpriv->b_ModeSelectRegister,devpriv->iobase+APCI3120_WRITE_MODE_SELECT);
+
+ //Set the Timer 2 in mode 2(Timer)
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_2;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Configure the timer 2 for writing the LOW WORD of timer is Delay value
+ //You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+ //you can set the digital output and configure the timer 2,and if you don't make this, digital output
+ //are erase (Set to 0)
+
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+ outw(HIWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+ // timer2 in Timer mode enabled
+ devpriv->b_Timer2Mode = APCI3120_TIMER;
+
+ } else // Initialize Watch dog
+ {
+
+ //Set the Timer 2 in mode 5(Watchdog)
+
+ devpriv->b_TimerSelectMode =
+ (devpriv->
+ b_TimerSelectMode & 0x0F) | APCI3120_TIMER_2_MODE_5;
+ outb(devpriv->b_TimerSelectMode,
+ devpriv->iobase + APCI3120_TIMER_CRT1);
+
+ //Configure the timer 2 for writing the LOW WORD of timer is Delay value
+ //You must make a b_tmp variable with DigitalOutPutRegister because at Address_1+APCI3120_TIMER_CRT0
+ //you can set the digital output and configure the timer 2,and if you don't make this, digital output
+ //are erase (Set to 0)
+
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+ outw(LOWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ outw(HIWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+ //watchdog enabled
+ devpriv->b_Timer2Mode = APCI3120_WATCHDOG;
+
+ }
+
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, |
+| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : To start and stop the timer |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+| |
+| data[0] = 1 (start) |
+| data[0] = 0 (stop ) |
+| data[0] = 2 (write new value) |
+| data[1]= new value |
+| |
+| devpriv->b_Timer2Mode = 0 DISABLE |
+| 1 Timer |
+| 2 Watch dog |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ui_Timervalue2 = 0;
+ USHORT us_TmpValue;
+ BYTE b_Tmp;
+
+ if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
+ && (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
+ comedi_error(dev, "\nwrite:timer2 not configured ");
+ return -EINVAL;
+ }
+
+ if (data[0] == 2) // write new value
+ {
+ if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
+ comedi_error(dev,
+ "write :timer2 not configured in TIMER MODE");
+ return -EINVAL;
+ }
+
+ if (data[1])
+ ui_Timervalue2 = data[1];
+ else
+ ui_Timervalue2 = 0;
+ }
+
+ //this_board->i_hwdrv_InsnWriteTimer(dev,data[0],ui_Timervalue2);
+
+ switch (data[0]) {
+ case APCI3120_START:
+
+ // Reset FC_TIMER BIT
+ inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) //start timer
+ {
+ //Enable Timer
+ devpriv->b_ModeSelectRegister =
+ devpriv->b_ModeSelectRegister & 0x0B;
+ } else //start watch dog
+ {
+ //Enable WatchDog
+ devpriv->b_ModeSelectRegister =
+ (devpriv->
+ b_ModeSelectRegister & 0x0B) |
+ APCI3120_ENABLE_WATCHDOG;
+ }
+
+ //enable disable interrupt
+ if ((devpriv->b_Timer2Interrupt) == APCI3120_ENABLE) {
+
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister |
+ APCI3120_ENABLE_TIMER_INT;
+ // save the task structure to pass info to user
+ devpriv->tsk_Current = current;
+ } else {
+
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_INT;
+ }
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) //start timer
+ {
+ //For Timer mode is Gate2 must be activated **timer started
+ devpriv->us_OutputRegister =
+ devpriv->
+ us_OutputRegister | APCI3120_ENABLE_TIMER2;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+ }
+
+ break;
+
+ case APCI3120_STOP:
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) {
+ //Disable timer
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_TIMER_COUNTER;
+ } else {
+ //Disable WatchDog
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister &
+ APCI3120_DISABLE_WATCHDOG;
+ }
+ // Disable timer interrupt
+ devpriv->b_ModeSelectRegister =
+ devpriv->
+ b_ModeSelectRegister & APCI3120_DISABLE_TIMER_INT;
+
+ // Write above states to register
+ outb(devpriv->b_ModeSelectRegister,
+ devpriv->iobase + APCI3120_WRITE_MODE_SELECT);
+
+ // Reset Gate 2
+ devpriv->us_OutputRegister =
+ devpriv->us_OutputRegister & APCI3120_DISABLE_TIMER_INT;
+ outw(devpriv->us_OutputRegister,
+ devpriv->iobase + APCI3120_WR_ADDRESS);
+
+ // Reset FC_TIMER BIT
+ inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+
+ // Disable timer
+ //devpriv->b_Timer2Mode=APCI3120_DISABLE;
+
+ break;
+
+ case 2: //write new value to Timer
+ if (devpriv->b_Timer2Mode != APCI3120_TIMER) {
+ comedi_error(dev,
+ "write :timer2 not configured in TIMER MODE");
+ return -EINVAL;
+ }
+ // ui_Timervalue2=data[1]; // passed as argument
+ us_TmpValue =
+ (USHORT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ //EL250804: Testing if board APCI3120 have the new Quartz or if it is an APCI3001
+ // and calculate the time value to set in the timer
+ if ((us_TmpValue & 0x00B0) == 0x00B0
+ || !strcmp(this_board->pc_DriverName, "apci3001")) {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 50;
+ } else {
+ //Calculate the time value to set in the timer
+ ui_Timervalue2 = ui_Timervalue2 / 70;
+ }
+ //Writing LOW WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ outw(LOWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Writing HIGH WORD
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ outw(HIWORD(ui_Timervalue2),
+ devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ break;
+ default:
+ return -EINVAL; // Not a valid input
+ }
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : int i_APCI3120_InsnReadTimer(struct comedi_device *dev, |
+| struct comedi_subdevice *s,struct comedi_insn *insn, unsigned int *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : read the Timer value |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+| |
++----------------------------------------------------------------------------+
+| Return Value : |
+| for Timer: data[0]= Timer constant |
+| |
+| for watchdog: data[0]=0 (still running) |
+| data[0]=1 (run down) |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnReadTimer(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Tmp;
+ USHORT us_TmpValue, us_TmpValue_2, us_StatusValue;
+
+ if ((devpriv->b_Timer2Mode != APCI3120_WATCHDOG)
+ && (devpriv->b_Timer2Mode != APCI3120_TIMER)) {
+ comedi_error(dev, "\nread:timer2 not configured ");
+ }
+
+ //this_board->i_hwdrv_InsnReadTimer(dev,data);
+ if (devpriv->b_Timer2Mode == APCI3120_TIMER) {
+
+ //Read the LOW WORD of Timer 2 register
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_LOW_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ us_TmpValue = inw(devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ //Read the HIGH WORD of Timer 2 register
+ b_Tmp = ((devpriv->
+ b_DigitalOutputRegister) & 0xF0) |
+ APCI3120_SELECT_TIMER_2_HIGH_WORD;
+ outb(b_Tmp, devpriv->iobase + APCI3120_TIMER_CRT0);
+
+ us_TmpValue_2 = inw(devpriv->iobase + APCI3120_TIMER_VALUE);
+
+ // combining both words
+ data[0] = (UINT) ((us_TmpValue) | ((us_TmpValue_2) << 16));
+
+ } else // Read watch dog status
+ {
+
+ us_StatusValue = inw(devpriv->iobase + APCI3120_RD_STATUS);
+ us_StatusValue =
+ ((us_StatusValue & APCI3120_FC_TIMER) >> 12) & 1;
+ if (us_StatusValue == 1) {
+ // RESET FC_TIMER BIT
+ inb(devpriv->iobase + APCI3120_TIMER_STATUS_REGISTER);
+ }
+ data[0] = us_StatusValue; // when data[0] = 1 then the watch dog has rundown
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, |
+| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
+| |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the specified Digital input channel|
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ UINT ui_Chan, ui_TmpValue;
+
+ ui_Chan = CR_CHAN(insn->chanspec); // channel specified
+
+ //this_board->i_hwdrv_InsnReadDigitalInput(dev,ui_Chan,data);
+ if (ui_Chan >= 0 && ui_Chan <= 3) {
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+
+ // since only 1 channel reqd to bring it to last bit it is rotated
+ // 8 +(chan - 1) times then ANDed with 1 for last bit.
+ *data = (ui_TmpValue >> (ui_Chan + 8)) & 1;
+ //return 0;
+ } else {
+ // comedi_error(dev," chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ }
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, |
+|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the Digital input Port i.e.4channels|
+| value is returned in data[0] |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3120_InsnBitsDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_TmpValue;
+ ui_TmpValue = (UINT) inw(devpriv->iobase + APCI3120_RD_STATUS);
+ /***** state of 4 channels in the 11, 10, 9, 8 bits of status reg
+ rotated right 8 times to bring them to last four bits
+ ANDed with oxf for value.
+ *****/
+
+ *data = (ui_TmpValue >> 8) & 0xf;
+ //this_board->i_hwdrv_InsnBitsDigitalInput(dev,data);
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device |
+| *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task :Configure the output memory ON or OFF |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters :struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ }
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = APCI3120_ENABLE;
+
+ } else {
+ devpriv->b_OutputMemoryStatus = APCI3120_DISABLE;
+ devpriv->b_DigitalOutputRegister = 0;
+ }
+ if (!devpriv->b_OutputMemoryStatus) {
+ ui_Temp = 0;
+
+ } //if(!devpriv->b_OutputMemoryStatus )
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, |
+| struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : write diatal output port |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+ data[0] Value to be written
+ data[1] :1 Set digital o/p ON
+ data[1] 2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ if ((data[0] > this_board->i_DoMaxdata) || (data[0] < 0)) {
+
+ comedi_error(dev, "Data is not valid !!! \n");
+ return -EINVAL;
+ }
+
+ switch (data[1]) {
+ case 1:
+ data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
+ break;
+
+ case 2:
+ data[0] = data[0];
+ break;
+ default:
+ printk("\nThe parameter passed is in error \n");
+ return -EINVAL;
+ } // switch(data[1])
+ outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+
+ devpriv->b_DigitalOutputRegister = data[0] & 0xF0;
+
+ return insn->n;
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Write digiatl output |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
+ data[0] Value to be written
+ data[1] :1 Set digital o/p ON
+ data[1] 2 Set digital o/p OFF with memory ON
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+
+ UINT ui_Temp1;
+
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ }
+ if ((ui_NoOfChannel > (this_board->i_NbrDoChannel - 1))
+ || (ui_NoOfChannel < 0)) {
+ comedi_error(dev,
+ "This board doesn't have specified channel !!! \n");
+ return -EINVAL;
+ }
+
+ switch (data[1]) {
+ case 1:
+ data[0] = (data[0] << ui_NoOfChannel);
+//ES05 data[0]=(data[0]<<4)|ui_Temp;
+ data[0] = (data[0] << 4) | devpriv->b_DigitalOutputRegister;
+ break;
+
+ case 2:
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp1 = ui_Temp1 << 4;
+//ES05 ui_Temp=ui_Temp|ui_Temp1;
+ devpriv->b_DigitalOutputRegister =
+ devpriv->b_DigitalOutputRegister | ui_Temp1;
+
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
+ data[0] = data[0] << 4;
+//ES05 data[0]=data[0]& ui_Temp;
+ data[0] = data[0] & devpriv->b_DigitalOutputRegister;
+ break;
+ default:
+ printk("\nThe parameter passed is in error \n");
+ return -EINVAL;
+ } // switch(data[1])
+ outb(data[0], devpriv->iobase + APCI3120_DIGITAL_OUTPUT);
+
+//ES05 ui_Temp=data[0] & 0xf0;
+ devpriv->b_DigitalOutputRegister = data[0] & 0xf0;
+ return (insn->n);
+
+}
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,|
+|struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data) |
+| |
++----------------------------------------------------------------------------+
+| Task : Write analog output |
+| |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
+| struct comedi_subdevice *s |
+| struct comedi_insn *insn |
+| unsigned int *data |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data)
+{
+ UINT ui_Range, ui_Channel;
+ USHORT us_TmpValue;
+
+ ui_Range = CR_RANGE(insn->chanspec);
+ ui_Channel = CR_CHAN(insn->chanspec);
+
+ //this_board->i_hwdrv_InsnWriteAnalogOutput(dev, ui_Range, ui_Channel,data[0]);
+ if (ui_Range) // if 1 then unipolar
+ {
+
+ if (data[0] != 0)
+ data[0] =
+ ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
+ 13) | (data[0] + 8191));
+ else
+ data[0] =
+ ((((ui_Channel & 0x03) << 14) & 0xC000) | (1 <<
+ 13) | 8192);
+
+ } else // if 0 then bipolar
+ {
+ data[0] =
+ ((((ui_Channel & 0x03) << 14) & 0xC000) | (0 << 13) |
+ data[0]);
+
+ }
+
+ //out put n values at the given channel.
+ // rt_printk("\nwaiting for DA_READY BIT");
+ do //Waiting of DA_READY BIT
+ {
+ us_TmpValue =
+ ((USHORT) inw(devpriv->iobase +
+ APCI3120_RD_STATUS)) & 0x0001;
+ } while (us_TmpValue != 0x0001);
+
+ if (ui_Channel <= 3)
+ // for channel 0-3 out at the register 1 (wrDac1-8)
+ // data[i] typecasted to ushort since word write is to be done
+ outw((USHORT) data[0],
+ devpriv->iobase + APCI3120_ANALOG_OUTPUT_1);
+ else
+ // for channel 4-7 out at the register 2 (wrDac5-8)
+ //data[i] typecasted to ushort since word write is to be done
+ outw((USHORT) data[0],
+ devpriv->iobase + APCI3120_ANALOG_OUTPUT_2);
+
+ return insn->n;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
new file mode 100644
index 00000000000..59d5d87a845
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.h
@@ -0,0 +1,241 @@
+
+// hwdrv_apci3120.h
+
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+// comedi related defines
+
+//ANALOG INPUT RANGE
+static const struct comedi_lrange range_apci3120_ai = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+// ANALOG OUTPUT RANGE
+static const struct comedi_lrange range_apci3120_ao = { 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
+
+#define APCI3120_BIPOLAR_RANGES 4 // used for test on mixture of BIP/UNI ranges
+
+#define APCI3120_BOARD_VENDOR_ID 0x10E8
+#define APCI3120_ADDRESS_RANGE 16
+
+#define APCI3120_DISABLE 0
+#define APCI3120_ENABLE 1
+
+#define APCI3120_START 1
+#define APCI3120_STOP 0
+
+#define APCI3120_EOC_MODE 1
+#define APCI3120_EOS_MODE 2
+#define APCI3120_DMA_MODE 3
+
+//DIGITAL INPUT-OUTPUT DEFINE
+
+#define APCI3120_DIGITAL_OUTPUT 0x0D
+#define APCI3120_RD_STATUS 0x02
+#define APCI3120_RD_FIFO 0x00
+
+// digital output insn_write ON /OFF selection
+#define APCI3120_SET4DIGITALOUTPUTON 1
+#define APCI3120_SET4DIGITALOUTPUTOFF 0
+
+// analog output SELECT BIT
+#define APCI3120_ANALOG_OP_CHANNEL_1 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_2 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_3 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_4 0xC000
+#define APCI3120_ANALOG_OP_CHANNEL_5 0x0000
+#define APCI3120_ANALOG_OP_CHANNEL_6 0x4000
+#define APCI3120_ANALOG_OP_CHANNEL_7 0x8000
+#define APCI3120_ANALOG_OP_CHANNEL_8 0xC000
+
+// Enable external trigger bit in nWrAddress
+#define APCI3120_ENABLE_EXT_TRIGGER 0x8000
+
+//ANALOG OUTPUT AND INPUT DEFINE
+#define APCI3120_UNIPOLAR 0x80 //$$ RAM sequence polarity BIT
+#define APCI3120_BIPOLAR 0x00 //$$ RAM sequence polarity BIT
+#define APCI3120_ANALOG_OUTPUT_1 0x08 // (ADDRESS )
+#define APCI3120_ANALOG_OUTPUT_2 0x0A // (ADDRESS )
+#define APCI3120_1_GAIN 0x00 //$$ RAM sequence Gain Bits for gain 1
+#define APCI3120_2_GAIN 0x10 //$$ RAM sequence Gain Bits for gain 2
+#define APCI3120_5_GAIN 0x20 //$$ RAM sequence Gain Bits for gain 5
+#define APCI3120_10_GAIN 0x30 //$$ RAM sequence Gain Bits for gain 10
+#define APCI3120_SEQ_RAM_ADDRESS 0x06 //$$ EARLIER NAMED APCI3120_FIFO_ADDRESS
+#define APCI3120_RESET_FIFO 0x0C //(ADDRESS)
+#define APCI3120_TIMER_0_MODE_2 0x01 //$$ Bits for timer mode
+#define APCI3120_TIMER_0_MODE_4 0x2
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_ENABLE_TIMER0 0x1000 //$$Gatebit 0 in nWrAddress
+#define APCI3120_CLEAR_PR 0xF0FF
+#define APCI3120_CLEAR_PA 0xFFF0
+#define APCI3120_CLEAR_PA_PR (APCI3120_CLEAR_PR & APCI3120_CLEAR_PA)
+
+// nWrMode_Select
+#define APCI3120_ENABLE_SCAN 0x8 //$$ bit in nWrMode_Select
+#define APCI3120_DISABLE_SCAN (~APCI3120_ENABLE_SCAN)
+#define APCI3120_ENABLE_EOS_INT 0x2 //$$ bit in nWrMode_Select
+
+#define APCI3120_DISABLE_EOS_INT (~APCI3120_ENABLE_EOS_INT)
+#define APCI3120_ENABLE_EOC_INT 0x1
+#define APCI3120_DISABLE_EOC_INT (~APCI3120_ENABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT_WITHOUT_TIMER (APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+#define APCI3120_DISABLE_ALL_INTERRUPT (APCI3120_DISABLE_TIMER_INT & APCI3120_DISABLE_EOS_INT & APCI3120_DISABLE_EOC_INT)
+
+//status register bits
+#define APCI3120_EOC 0x8000
+#define APCI3120_EOS 0x2000
+
+// software trigger dummy register
+#define APCI3120_START_CONVERSION 0x02 //(ADDRESS)
+
+//TIMER DEFINE
+#define APCI3120_QUARTZ_A 70
+#define APCI3120_QUARTZ_B 50
+#define APCI3120_TIMER 1
+#define APCI3120_WATCHDOG 2
+#define APCI3120_TIMER_DISABLE 0
+#define APCI3120_TIMER_ENABLE 1
+#define APCI3120_ENABLE_TIMER2 0x4000 //$$ gatebit 2 in nWrAddress
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+#define APCI3120_ENABLE_TIMER_INT 0x04 //$$ ENAIRQ_FC_Bit in nWrModeSelect
+#define APCI3120_DISABLE_TIMER_INT (~APCI3120_ENABLE_TIMER_INT)
+#define APCI3120_WRITE_MODE_SELECT 0x0E // (ADDRESS)
+#define APCI3120_SELECT_TIMER_0_WORD 0x00
+#define APCI3120_SELECT_TIMER_1_WORD 0x01
+#define APCI3120_TIMER_1_MODE_2 0x4
+
+//$$ BIT FOR MODE IN nCsTimerCtr1
+#define APCI3120_TIMER_2_MODE_0 0x0
+#define APCI3120_TIMER_2_MODE_2 0x10
+#define APCI3120_TIMER_2_MODE_5 0x30
+
+//$$ BIT FOR MODE IN nCsTimerCtr0
+#define APCI3120_SELECT_TIMER_2_LOW_WORD 0x02
+#define APCI3120_SELECT_TIMER_2_HIGH_WORD 0x03
+
+#define APCI3120_TIMER_CRT0 0x0D //(ADDRESS for cCsTimerCtr0)
+#define APCI3120_TIMER_CRT1 0x0C //(ADDRESS for cCsTimerCtr1)
+
+#define APCI3120_TIMER_VALUE 0x04 //ADDRESS for nCsTimerWert
+#define APCI3120_TIMER_STATUS_REGISTER 0x0D //ADDRESS for delete timer 2 interrupt
+#define APCI3120_RD_STATUS 0x02 //ADDRESS
+#define APCI3120_WR_ADDRESS 0x00 //ADDRESS
+#define APCI3120_ENABLE_WATCHDOG 0x20 //$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_WATCHDOG (~APCI3120_ENABLE_WATCHDOG)
+#define APCI3120_ENABLE_TIMER_COUNTER 0x10 //$$BIT in nWrMode_Select
+#define APCI3120_DISABLE_TIMER_COUNTER (~APCI3120_ENABLE_TIMER_COUNTER)
+#define APCI3120_FC_TIMER 0x1000 //bit in status register
+#define APCI3120_ENABLE_TIMER0 0x1000
+#define APCI3120_ENABLE_TIMER1 0x2000
+#define APCI3120_ENABLE_TIMER2 0x4000
+#define APCI3120_DISABLE_TIMER0 (~APCI3120_ENABLE_TIMER0)
+#define APCI3120_DISABLE_TIMER1 (~APCI3120_ENABLE_TIMER1)
+#define APCI3120_DISABLE_TIMER2 (~APCI3120_ENABLE_TIMER2)
+
+#define APCI3120_TIMER2_SELECT_EOS 0xC0 // ADDED on 20-6
+#define APCI3120_COUNTER 3 // on 20-6
+#define APCI3120_DISABLE_ALL_TIMER ( APCI3120_DISABLE_TIMER0 & APCI3120_DISABLE_TIMER1 & APCI3120_DISABLE_TIMER2 ) // on 20-6
+
+#define MAX_ANALOGINPUT_CHANNELS 32
+
+typedef struct {
+ BYTE b_Type; /* EOC or EOS */
+ BYTE b_InterruptFlag; /* Interrupt use or not */
+ UINT ui_ConvertTiming; /* Selection of the convertion time */
+ BYTE b_NbrOfChannel; /* Number of channel to read */
+ UINT ui_ChannelList[MAX_ANALOGINPUT_CHANNELS]; /* Number of the channel to be read */
+ UINT ui_RangeList[MAX_ANALOGINPUT_CHANNELS]; /* Gain of each channel */
+
+} str_AnalogReadInformation;
+
+// Function Declaration For APCI-3120
+
+// Internal functions
+int i_APCI3120_SetupChannelList(struct comedi_device *dev, struct comedi_subdevice *s,
+ int n_chan, unsigned int *chanlist, char check);
+int i_APCI3120_ExttrigEnable(struct comedi_device *dev);
+int i_APCI3120_ExttrigDisable(struct comedi_device *dev);
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
+int i_APCI3120_Reset(struct comedi_device *dev);
+int i_APCI3120_CyclicAnalogInput(int mode, struct comedi_device *dev,
+ struct comedi_subdevice *s);
+// Interrupt functions
+void v_APCI3120_Interrupt(int irq, void *d);
+//UPDATE-0.7.57->0.7.68 void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,struct comedi_subdevice *s,short *dma,short *data,int n);
+void v_APCI3120_InterruptDmaMoveBlock16bit(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ short *dma_buffer,
+ unsigned int num_samples);
+int i_APCI3120_InterruptHandleEos(struct comedi_device *dev);
+void v_APCI3120_InterruptDma(int irq, void *d);
+
+// TIMER
+
+int i_APCI3120_InsnConfigTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnWriteTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadTimer(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DI
+// for di read
+
+int i_APCI3120_InsnBitsDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DO
+//int i_APCI3120_WriteDigitalOutput(struct comedi_device *dev, BYTE data);
+int i_APCI3120_InsnConfigDigitalOutput(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI3120_InsnBitsDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnWriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//AO
+//int i_APCI3120_Write1AnalogValue(struct comedi_device *dev,UINT ui_Range,UINT ui_Channel,UINT data );
+int i_APCI3120_InsnWriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//AI HArdware layer
+
+int i_APCI3120_InsnConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_InsnReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3120_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+int i_APCI3120_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+//int i_APCI3120_CancelAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+int i_APCI3120_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
new file mode 100644
index 00000000000..1ff66bee548
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
@@ -0,0 +1,3642 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-3200 | Compiler : GCC |
+ | Module name : hwdrv_apci3200.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-3200 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | 02.07.04 | J. Krauth | Modification from the driver in order to |
+ | | | correct some errors when using several boards. |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+ | 26.10.04 | J. Krauth | - Update for COMEDI 0.7.68 |
+ | | | - Read eeprom value |
+ | | | - Append APCI-3300 |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
+ +----------------------------------------------------------------------------+
+ | Included files |
+ +----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3200.h"
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+#include "addi_amcc_S5920.h"
+//#define PRINT_INFO
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+//BEGIN JK 06.07.04: Management of sevrals boards
+/*
+ INT i_CJCAvailable=1;
+ INT i_CJCPolarity=0;
+ INT i_CJCGain=2;//changed from 0 to 2
+ INT i_InterruptFlag=0;
+ INT i_ADDIDATAPolarity;
+ INT i_ADDIDATAGain;
+ INT i_AutoCalibration=0; //: auto calibration
+ INT i_ADDIDATAConversionTime;
+ INT i_ADDIDATAConversionTimeUnit;
+ INT i_ADDIDATAType;
+ INT i_ChannelNo;
+ INT i_ChannelCount=0;
+ INT i_ScanType;
+ INT i_FirstChannel;
+ INT i_LastChannel;
+ INT i_Sum=0;
+ INT i_Offset;
+ UINT ui_Channel_num=0;
+ static int i_Count=0;
+ INT i_Initialised=0;
+ UINT ui_InterruptChannelValue[96]; //Buffer
+*/
+str_BoardInfos s_BoardInfos[100]; // 100 will be the max number of boards to be used
+//END JK 06.07.04: Management of sevrals boards
+
+//Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : INT i_AddiHeaderRW_ReadEeprom |*/
+/*| (INT i_NbOfWordsToRead, |*/
+/*| DWORD dw_PCIBoardEepromAddress, |*/
+/*| WORD w_EepromStartAddress, |*/
+/*| PWORD pw_DataRead) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read word from the 5920 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : INT i_NbOfWordsToRead : Nbr. of word to read |*/
+/*| DWORD dw_PCIBoardEepromAddress : Address of the eeprom |*/
+/*| WORD w_EepromStartAddress : Eeprom strat address |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : PWORD pw_DataRead : Read data |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+INT i_AddiHeaderRW_ReadEeprom(INT i_NbOfWordsToRead,
+ DWORD dw_PCIBoardEepromAddress,
+ WORD w_EepromStartAddress, PWORD pw_DataRead)
+{
+ DWORD dw_eeprom_busy = 0;
+ INT i_Counter = 0;
+ INT i_WordCounter;
+ INT i;
+ BYTE pb_ReadByte[1];
+ BYTE b_ReadLowByte = 0;
+ BYTE b_ReadHighByte = 0;
+ BYTE b_SelectedAddressLow = 0;
+ BYTE b_SelectedAddressHigh = 0;
+ WORD w_ReadWord = 0;
+
+ for (i_WordCounter = 0; i_WordCounter < i_NbOfWordsToRead;
+ i_WordCounter++) {
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ for (i_Counter = 0; i_Counter < 2; i_Counter++) {
+ b_SelectedAddressLow = (w_EepromStartAddress + i_Counter) % 256; //Read the low 8 bit part
+ b_SelectedAddressHigh = (w_EepromStartAddress + i_Counter) / 256; //Read the high 8 bit part
+
+ //Select the load low address mode
+ outb(NVCMD_LOAD_LOW,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the low address
+ outb(b_SelectedAddressLow,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the load high address mode
+ outb(NVCMD_LOAD_HIGH,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Load the high address
+ outb(b_SelectedAddressHigh,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the READ mode
+ outb(NVCMD_BEGIN_READ,
+ dw_PCIBoardEepromAddress + AMCC_OP_REG_MCSR +
+ 3);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Read data into the EEPROM
+ *pb_ReadByte =
+ inb(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR + 2);
+
+ //Wait on busy
+ do {
+ dw_eeprom_busy =
+ inl(dw_PCIBoardEepromAddress +
+ AMCC_OP_REG_MCSR);
+ dw_eeprom_busy = dw_eeprom_busy & EEPROM_BUSY;
+ }
+ while (dw_eeprom_busy == EEPROM_BUSY);
+
+ //Select the upper address part
+ if (i_Counter == 0) {
+ b_ReadLowByte = pb_ReadByte[0];
+ } else {
+ b_ReadHighByte = pb_ReadByte[0];
+ }
+
+ //Sleep
+ for (i = 0; i < 10000; i++) ;
+
+ }
+ w_ReadWord =
+ (b_ReadLowByte | (((unsigned short)b_ReadHighByte) *
+ 256));
+
+ pw_DataRead[i_WordCounter] = w_ReadWord;
+
+ w_EepromStartAddress += 2; // to read the next word
+
+ } // for (...) i_NbOfWordsToRead
+ return (0);
+}
+
+/*+----------------------------------------------------------------------------+*/
+/*| Function Name : void v_GetAPCI3200EepromCalibrationValue (void) |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Task : Read calibration value from the APCI-3200 eeprom. |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Input Parameters : - |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Output Parameters : - |*/
+/*+----------------------------------------------------------------------------+*/
+/*| Return Value : - |*/
+/*+----------------------------------------------------------------------------+*/
+
+void v_GetAPCI3200EepromCalibrationValue(DWORD dw_PCIBoardEepromAddress,
+ str_BoardInfos * BoardInformations)
+{
+ WORD w_AnalogInputMainHeaderAddress;
+ WORD w_AnalogInputComponentAddress;
+ WORD w_NumberOfModuls = 0;
+ WORD w_CurrentSources[2];
+ WORD w_ModulCounter = 0;
+ WORD w_FirstHeaderSize = 0;
+ WORD w_NumberOfInputs = 0;
+ WORD w_CJCFlag = 0;
+ WORD w_NumberOfGainValue = 0;
+ WORD w_SingleHeaderAddress = 0;
+ WORD w_SingleHeaderSize = 0;
+ WORD w_Input = 0;
+ WORD w_GainFactorAddress = 0;
+ WORD w_GainFactorValue[2];
+ WORD w_GainIndex = 0;
+ WORD w_GainValue = 0;
+
+ /*****************************************/
+ /** Get the Analog input header address **/
+ /*****************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, 0x116, //w_EepromStartAddress: Analog input header address
+ &w_AnalogInputMainHeaderAddress);
+
+ /*******************************************/
+ /** Compute the real analog input address **/
+ /*******************************************/
+ w_AnalogInputMainHeaderAddress = w_AnalogInputMainHeaderAddress + 0x100;
+
+ /******************************/
+ /** Get the number of moduls **/
+ /******************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputMainHeaderAddress + 0x02, //w_EepromStartAddress: Number of conponment
+ &w_NumberOfModuls);
+
+ for (w_ModulCounter = 0; w_ModulCounter < w_NumberOfModuls;
+ w_ModulCounter++) {
+ /***********************************/
+ /** Compute the component address **/
+ /***********************************/
+ w_AnalogInputComponentAddress =
+ w_AnalogInputMainHeaderAddress +
+ (w_FirstHeaderSize * w_ModulCounter) + 0x04;
+
+ /****************************/
+ /** Read first header size **/
+ /****************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress, // Address of the first header
+ &w_FirstHeaderSize);
+
+ w_FirstHeaderSize = w_FirstHeaderSize >> 4;
+
+ /***************************/
+ /** Read number of inputs **/
+ /***************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x06, // Number of inputs for the first modul
+ &w_NumberOfInputs);
+
+ w_NumberOfInputs = w_NumberOfInputs >> 4;
+
+ /***********************/
+ /** Read the CJC flag **/
+ /***********************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x08, // CJC flag
+ &w_CJCFlag);
+
+ w_CJCFlag = (w_CJCFlag >> 3) & 0x1; // Get only the CJC flag
+
+ /*******************************/
+ /** Read number of gain value **/
+ /*******************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 0x44, // Number of gain value
+ &w_NumberOfGainValue);
+
+ w_NumberOfGainValue = w_NumberOfGainValue & 0xFF;
+
+ /***********************************/
+ /** Compute single header address **/
+ /***********************************/
+ w_SingleHeaderAddress =
+ w_AnalogInputComponentAddress + 0x46 +
+ (((w_NumberOfGainValue / 16) + 1) * 2) +
+ (6 * w_NumberOfGainValue) +
+ (4 * (((w_NumberOfGainValue / 16) + 1) * 2));
+
+ /********************************************/
+ /** Read current sources value for input 1 **/
+ /********************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_SingleHeaderAddress, //w_EepromStartAddress: Single header address
+ &w_SingleHeaderSize);
+
+ w_SingleHeaderSize = w_SingleHeaderSize >> 4;
+
+ /*************************************/
+ /** Read gain factor for the module **/
+ /*************************************/
+ w_GainFactorAddress = w_AnalogInputComponentAddress;
+
+ for (w_GainIndex = 0; w_GainIndex < w_NumberOfGainValue;
+ w_GainIndex++) {
+ /************************************/
+ /** Read gain value for the module **/
+ /************************************/
+ i_AddiHeaderRW_ReadEeprom(1, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + (2 * (1 + (w_NumberOfGainValue / 16))) + (0x02 * w_GainIndex), // Gain value
+ &w_GainValue);
+
+ BoardInformations->s_Module[w_ModulCounter].
+ w_GainValue[w_GainIndex] = w_GainValue;
+
+# ifdef PRINT_INFO
+ printk("\n Gain value = %d",
+ BoardInformations->s_Module[w_ModulCounter].
+ w_GainValue[w_GainIndex]);
+# endif
+
+ /*************************************/
+ /** Read gain factor for the module **/
+ /*************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress, w_AnalogInputComponentAddress + 70 + ((2 * w_NumberOfGainValue) + (2 * (1 + (w_NumberOfGainValue / 16)))) + (0x04 * w_GainIndex), // Gain factor
+ w_GainFactorValue);
+
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_GainFactor[w_GainIndex] =
+ (w_GainFactorValue[1] << 16) +
+ w_GainFactorValue[0];
+
+# ifdef PRINT_INFO
+ printk("\n w_GainFactorValue [%d] = %lu", w_GainIndex,
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_GainFactor[w_GainIndex]);
+# endif
+ }
+
+ /***************************************************************/
+ /** Read current source value for each channels of the module **/
+ /***************************************************************/
+ for (w_Input = 0; w_Input < w_NumberOfInputs; w_Input++) {
+ /********************************************/
+ /** Read current sources value for input 1 **/
+ /********************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress,
+ (w_Input * w_SingleHeaderSize) +
+ w_SingleHeaderAddress + 0x0C, w_CurrentSources);
+
+ /************************************/
+ /** Save the current sources value **/
+ /************************************/
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSource[w_Input] =
+ (w_CurrentSources[0] +
+ ((w_CurrentSources[1] & 0xFFF) << 16));
+
+# ifdef PRINT_INFO
+ printk("\n Current sources [%d] = %lu", w_Input,
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSource[w_Input]);
+# endif
+ }
+
+ /***************************************/
+ /** Read the CJC current source value **/
+ /***************************************/
+ i_AddiHeaderRW_ReadEeprom(2, //i_NbOfWordsToRead
+ dw_PCIBoardEepromAddress,
+ (w_Input * w_SingleHeaderSize) + w_SingleHeaderAddress +
+ 0x0C, w_CurrentSources);
+
+ /************************************/
+ /** Save the current sources value **/
+ /************************************/
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSourceCJC =
+ (w_CurrentSources[0] +
+ ((w_CurrentSources[1] & 0xFFF) << 16));
+
+# ifdef PRINT_INFO
+ printk("\n Current sources CJC = %lu",
+ BoardInformations->s_Module[w_ModulCounter].
+ ul_CurrentSourceCJC);
+# endif
+ }
+}
+
+INT i_APCI3200_GetChannelCalibrationValue(struct comedi_device * dev,
+ unsigned int ui_Channel_num, unsigned int * CJCCurrentSource,
+ unsigned int * ChannelCurrentSource, unsigned int * ChannelGainFactor)
+{
+ int i_DiffChannel = 0;
+ int i_Module = 0;
+
+#ifdef PRINT_INFO
+ printk("\n Channel = %u", ui_Channel_num);
+#endif
+
+ //Test if single or differential mode
+ if (s_BoardInfos[dev->minor].i_ConnectionType == 1) {
+ //if diff
+
+ if ((ui_Channel_num >= 0) && (ui_Channel_num <= 1))
+ i_DiffChannel = ui_Channel_num, i_Module = 0;
+ else if ((ui_Channel_num >= 2) && (ui_Channel_num <= 3))
+ i_DiffChannel = ui_Channel_num - 2, i_Module = 1;
+ else if ((ui_Channel_num >= 4) && (ui_Channel_num <= 5))
+ i_DiffChannel = ui_Channel_num - 4, i_Module = 2;
+ else if ((ui_Channel_num >= 6) && (ui_Channel_num <= 7))
+ i_DiffChannel = ui_Channel_num - 6, i_Module = 3;
+
+ } else {
+ // if single
+ if ((ui_Channel_num == 0) || (ui_Channel_num == 1))
+ i_DiffChannel = 0, i_Module = 0;
+ else if ((ui_Channel_num == 2) || (ui_Channel_num == 3))
+ i_DiffChannel = 1, i_Module = 0;
+ else if ((ui_Channel_num == 4) || (ui_Channel_num == 5))
+ i_DiffChannel = 0, i_Module = 1;
+ else if ((ui_Channel_num == 6) || (ui_Channel_num == 7))
+ i_DiffChannel = 1, i_Module = 1;
+ else if ((ui_Channel_num == 8) || (ui_Channel_num == 9))
+ i_DiffChannel = 0, i_Module = 2;
+ else if ((ui_Channel_num == 10) || (ui_Channel_num == 11))
+ i_DiffChannel = 1, i_Module = 2;
+ else if ((ui_Channel_num == 12) || (ui_Channel_num == 13))
+ i_DiffChannel = 0, i_Module = 3;
+ else if ((ui_Channel_num == 14) || (ui_Channel_num == 15))
+ i_DiffChannel = 1, i_Module = 3;
+ }
+
+ //Test if thermocouple or RTD mode
+ *CJCCurrentSource =
+ s_BoardInfos[dev->minor].s_Module[i_Module].ul_CurrentSourceCJC;
+#ifdef PRINT_INFO
+ printk("\n CJCCurrentSource = %lu", *CJCCurrentSource);
+#endif
+
+ *ChannelCurrentSource =
+ s_BoardInfos[dev->minor].s_Module[i_Module].
+ ul_CurrentSource[i_DiffChannel];
+#ifdef PRINT_INFO
+ printk("\n ChannelCurrentSource = %lu", *ChannelCurrentSource);
+#endif
+ // }
+ // }
+
+ //Channle gain factor
+ *ChannelGainFactor =
+ s_BoardInfos[dev->minor].s_Module[i_Module].
+ ul_GainFactor[s_BoardInfos[dev->minor].i_ADDIDATAGain];
+#ifdef PRINT_INFO
+ printk("\n ChannelGainFactor = %lu", *ChannelGainFactor);
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ return (0);
+}
+
+//End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadDigitalInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel or port |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read for Port
+ Channel Numberfor single channel
+ | UINT data[0] : 0: Read single channel
+ 1: Read port value
+ data[1] Port number
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- data[0] :Read status value
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp = 0;
+ UINT ui_NoOfChannel = 0;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseReserved);
+
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ if (data[1] < 0 || data[1] > 1) {
+ printk("\nThe port number is in error\n");
+ return -EINVAL;
+ } //if(data[1] < 0 || data[1] >1)
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ *data = (*data >> (2 * data[1])) & 0x3;
+ break;
+ case 3:
+ *data = (*data & 15);
+ break;
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+
+ } //switch(ui_NoOfChannels)
+ } //if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif (ui_Temp==1)
+ }
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ConfigDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Configures The Digital Output Subdevice. |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | data[0] :1 Memory enable
+ 0 Memory Disable
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } //if ( (data[0]!=0) && (data[0]!=1) )
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } //else if (data[0])
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_WriteDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : writes To the digital Output Subdevice |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ | data[0] :Value to output
+ data[1] : 0 o/p single channel
+ 1 o/p port
+ data[2] : port no
+ data[3] :0 set the digital o/p on
+ 1 set the digital o/p off
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp = 0, ui_Temp1 = 0;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inl(devpriv->i_IobaseAddon);
+
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0], devpriv->i_IobaseAddon);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] =
+ (data[0] << (2 *
+ data[2])) | ui_Temp;
+ break;
+ case 3:
+ data[0] = (data[0] | ui_Temp);
+ break;
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0], devpriv->i_IobaseAddon);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] = (data[0] << ui_NoOfChannel) ^ 0xf;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0], devpriv->i_IobaseAddon);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ switch (ui_NoOfChannel) {
+
+ case 2:
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 =
+ ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data
+ [2])) ^
+ 0xf) & ui_Temp;
+
+ break;
+ case 3:
+ break;
+
+ default:
+ comedi_error(dev,
+ " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ } //switch(ui_NoOfChannels)
+
+ outl(data[0], devpriv->i_IobaseAddon);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadDigitalOutput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel or port |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ data[0] :0 read single channel
+ 1 read port value
+ data[1] port no
+
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->i_IobaseAddon);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ if (data[1] < 0 || data[1] > 1) {
+ printk("\nThe port selection is in error\n");
+ return -EINVAL;
+ } //if(data[1] <0 ||data[1] >1)
+ switch (ui_NoOfChannel) {
+ case 2:
+ *data = (*data >> (2 * data[1])) & 3;
+ break;
+
+ case 3:
+ break;
+
+ default:
+ comedi_error(dev, " chan spec wrong");
+ return -EINVAL; // "sorry channel spec wrong "
+ break;
+ } // switch(ui_NoOfChannels)
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // else if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : INT i_APCI3200_ConfigAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Configures The Analog Input Subdevice |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ | |
+ | data[0]
+ | 0:Normal AI |
+ | 1:RTD |
+ | 2:THERMOCOUPLE |
+ | data[1] : Gain To Use |
+ | |
+ | data[2] : Polarity
+ | 0:Bipolar |
+ | 1:Unipolar |
+ | |
+ | data[3] : Offset Range
+ | |
+ | data[4] : Coupling
+ | 0:DC Coupling |
+ | 1:AC Coupling |
+ | |
+ | data[5] :Differential/Single
+ | 0:Single |
+ | 1:Differential |
+ | |
+ | data[6] :TimerReloadValue
+ | |
+ | data[7] :ConvertingTimeUnit
+ | |
+ | data[8] :0 Analog voltage measurement
+ 1 Resistance measurement
+ 2 Temperature measurement
+ | data[9] :Interrupt
+ | 0:Disable
+ | 1:Enable
+ data[10] :Type of Thermocouple
+ | data[11] : 0: single channel
+ Module Number
+ |
+ | data[12]
+ | 0:Single Read
+ | 1:Read more channel
+ 2:Single scan
+ | 3:Continous Scan
+ data[13] :Number of channels to read
+ | data[14] :RTD connection type
+ :0:RTD not used
+ 1:RTD 2 wire connection
+ 2:RTD 3 wire connection
+ 3:RTD 4 wire connection
+ | |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ConfigAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ UINT ul_Config = 0, ul_Temp = 0;
+ UINT ui_ChannelNo = 0;
+ UINT ui_Dummy = 0;
+ INT i_err = 0;
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+#ifdef PRINT_INFO
+ INT i = 0, i2 = 0;
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ // Initialize the structure
+ if (s_BoardInfos[dev->minor].b_StructInitialized != 1) {
+ s_BoardInfos[dev->minor].i_CJCAvailable = 1;
+ s_BoardInfos[dev->minor].i_CJCPolarity = 0;
+ s_BoardInfos[dev->minor].i_CJCGain = 2; //changed from 0 to 2
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_AutoCalibration = 0; //: auto calibration
+ s_BoardInfos[dev->minor].i_ChannelCount = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].ui_Channel_num = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 1;
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].i_ConnectionType = 0;
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ memset(s_BoardInfos[dev->minor].s_Module, 0,
+ sizeof(s_BoardInfos[dev->minor].s_Module[MAX_MODULE]));
+
+ v_GetAPCI3200EepromCalibrationValue(devpriv->i_IobaseAmcc,
+ &s_BoardInfos[dev->minor]);
+
+#ifdef PRINT_INFO
+ for (i = 0; i < MAX_MODULE; i++) {
+ printk("\n s_Module[%i].ul_CurrentSourceCJC = %lu", i,
+ s_BoardInfos[dev->minor].s_Module[i].
+ ul_CurrentSourceCJC);
+
+ for (i2 = 0; i2 < 5; i2++) {
+ printk("\n s_Module[%i].ul_CurrentSource [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_CurrentSource[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].ul_GainFactor [%i] = %lu", i, i2, s_BoardInfos[dev->minor].s_Module[i].ul_GainFactor[i2]);
+ }
+
+ for (i2 = 0; i2 < 8; i2++) {
+ printk("\n s_Module[%i].w_GainValue [%i] = %u",
+ i, i2,
+ s_BoardInfos[dev->minor].s_Module[i].
+ w_GainValue[i2]);
+ }
+ }
+#endif
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+
+ if (data[0] != 0 && data[0] != 1 && data[0] != 2) {
+ printk("\nThe selection of acquisition type is in error\n");
+ i_err++;
+ } //if(data[0]!=0 && data[0]!=1 && data[0]!=2)
+ if (data[0] == 1) {
+ if (data[14] != 0 && data[14] != 1 && data[14] != 2
+ && data[14] != 4) {
+ printk("\n Error in selection of RTD connection type\n");
+ i_err++;
+ } //if(data[14]!=0 && data[14]!=1 && data[14]!=2 && data[14]!=4)
+ } //if(data[0]==1 )
+ if (data[1] < 0 || data[1] > 7) {
+ printk("\nThe selection of gain is in error\n");
+ i_err++;
+ } // if(data[1]<0 || data[1]>7)
+ if (data[2] != 0 && data[2] != 1) {
+ printk("\nThe selection of polarity is in error\n");
+ i_err++;
+ } //if(data[2]!=0 && data[2]!=1)
+ if (data[3] != 0) {
+ printk("\nThe selection of offset range is in error\n");
+ i_err++;
+ } // if(data[3]!=0)
+ if (data[4] != 0 && data[4] != 1) {
+ printk("\nThe selection of coupling is in error\n");
+ i_err++;
+ } //if(data[4]!=0 && data[4]!=1)
+ if (data[5] != 0 && data[5] != 1) {
+ printk("\nThe selection of single/differential mode is in error\n");
+ i_err++;
+ } //if(data[5]!=0 && data[5]!=1)
+ if (data[8] != 0 && data[8] != 1 && data[2] != 2) {
+ printk("\nError in selection of functionality\n");
+ } //if(data[8]!=0 && data[8]!=1 && data[2]!=2)
+ if (data[12] == 0 || data[12] == 1) {
+ if (data[6] != 20 && data[6] != 40 && data[6] != 80
+ && data[6] != 160) {
+ printk("\nThe selection of conversion time reload value is in error\n");
+ i_err++;
+ } // if (data[6]!=20 && data[6]!=40 && data[6]!=80 && data[6]!=160 )
+ if (data[7] != 2) {
+ printk("\nThe selection of conversion time unit is in error\n");
+ i_err++;
+ } // if(data[7]!=2)
+ }
+ if (data[9] != 0 && data[9] != 1) {
+ printk("\nThe selection of interrupt enable is in error\n");
+ i_err++;
+ } //if(data[9]!=0 && data[9]!=1)
+ if (data[11] < 0 || data[11] > 4) {
+ printk("\nThe selection of module is in error\n");
+ i_err++;
+ } //if(data[11] <0 || data[11]>1)
+ if (data[12] < 0 || data[12] > 3) {
+ printk("\nThe selection of singlechannel/scan selection is in error\n");
+ i_err++;
+ } //if(data[12] < 0 || data[12]> 3)
+ if (data[13] < 0 || data[13] > 16) {
+ printk("\nThe selection of number of channels is in error\n");
+ i_err++;
+ } // if(data[13] <0 ||data[13] >15)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ /*
+ i_ChannelCount=data[13];
+ i_ScanType=data[12];
+ i_ADDIDATAPolarity = data[2];
+ i_ADDIDATAGain=data[1];
+ i_ADDIDATAConversionTime=data[6];
+ i_ADDIDATAConversionTimeUnit=data[7];
+ i_ADDIDATAType=data[0];
+ */
+
+ // Save acquisition configuration for the actual board
+ s_BoardInfos[dev->minor].i_ChannelCount = data[13];
+ s_BoardInfos[dev->minor].i_ScanType = data[12];
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity = data[2];
+ s_BoardInfos[dev->minor].i_ADDIDATAGain = data[1];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTime = data[6];
+ s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit = data[7];
+ s_BoardInfos[dev->minor].i_ADDIDATAType = data[0];
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ s_BoardInfos[dev->minor].i_ConnectionType = data[5];
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //END JK 06.07.04: Management of sevrals boards
+
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ memset(s_BoardInfos[dev->minor].ui_ScanValueArray, 0, (7 + 12) * sizeof(unsigned int)); // 7 is the maximal number of channels
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //BEGIN JK 02.07.04 : This while can't be do, it block the process when using severals boards
+ //while(i_InterruptFlag==1)
+ while (s_BoardInfos[dev->minor].i_InterruptFlag == 1) {
+#ifndef MSXBOX
+ udelay(1);
+#else
+ // In the case where the driver is compiled for the MSX-Box
+ // we used a printk to have a little delay because udelay
+ // seems to be broken under the MSX-Box.
+ // This solution hat to be studied.
+ printk("");
+#endif
+ }
+ //END JK 02.07.04 : This while can't be do, it block the process when using severals boards
+
+ ui_ChannelNo = CR_CHAN(insn->chanspec); // get the channel
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=ui_ChannelNo;
+ //ui_Channel_num =ui_ChannelNo;
+
+ s_BoardInfos[dev->minor].i_ChannelNo = ui_ChannelNo;
+ s_BoardInfos[dev->minor].ui_Channel_num = ui_ChannelNo;
+
+ //END JK 06.07.04: Management of sevrals boards
+
+ if (data[5] == 0) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 15) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>15)
+ } //if(data[5]==0)
+ else {
+ if (data[14] == 2) {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 3) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>3)
+ } //if(data[14]==2)
+ else {
+ if (ui_ChannelNo < 0 || ui_ChannelNo > 7) {
+ printk("\nThe Selection of the channel is in error\n");
+ i_err++;
+ } // if(ui_ChannelNo<0 || ui_ChannelNo>7)
+ } //elseif(data[14]==2)
+ } //elseif(data[5]==0)
+ if (data[12] == 0 || data[12] == 1) {
+ switch (data[5]) {
+ case 0:
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=0 && ui_ChannelNo <=3)
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 7) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=4 && ui_ChannelNo <=7)
+ if (ui_ChannelNo >= 8 && ui_ChannelNo <= 11) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=8 && ui_ChannelNo <=11)
+ if (ui_ChannelNo >= 12 && ui_ChannelNo <= 15) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=12 && ui_ChannelNo <=15)
+ break;
+ case 1:
+ if (data[14] == 2) {
+ if (ui_ChannelNo == 0) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==0 )
+ if (ui_ChannelNo == 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ } // if(ui_ChannelNo ==1)
+ if (ui_ChannelNo == 2) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==2 )
+ if (ui_ChannelNo == 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo ==3)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=0;
+ s_BoardInfos[dev->minor].i_ChannelNo = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = 0;
+ break;
+ } //if(data[14]==2)
+ if (ui_ChannelNo >= 0 && ui_ChannelNo <= 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(ui_ChannelNo >=0 && ui_ChannelNo <=1)
+ if (ui_ChannelNo >= 2 && ui_ChannelNo <= 3) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-2;
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 2;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 2;
+ } //if(ui_ChannelNo >=2 && ui_ChannelNo <=3)
+ if (ui_ChannelNo >= 4 && ui_ChannelNo <= 5) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-4;
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 4;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 4;
+ } //if(ui_ChannelNo >=4 && ui_ChannelNo <=5)
+ if (ui_ChannelNo >= 6 && ui_ChannelNo <= 7) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_ChannelNo=i_ChannelNo-6;
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_ChannelNo =
+ s_BoardInfos[dev->minor].i_ChannelNo -
+ 6;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ ui_ChannelNo = ui_ChannelNo - 6;
+ } //if(ui_ChannelNo >=6 && ui_ChannelNo <=7)
+ break;
+
+ default:
+ printk("\n This selection of polarity does not exist\n");
+ i_err++;
+ } //switch(data[2])
+ } //if(data[12]==0 || data[12]==1)
+ else {
+ switch (data[11]) {
+ case 1:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=0;
+ s_BoardInfos[dev->minor].i_Offset = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 2:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=64;
+ s_BoardInfos[dev->minor].i_Offset = 64;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 3:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=128;
+ s_BoardInfos[dev->minor].i_Offset = 128;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ case 4:
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Offset=192;
+ s_BoardInfos[dev->minor].i_Offset = 192;
+ //END JK 06.07.04: Management of sevrals boards
+ break;
+ default:
+ printk("\nError in module selection\n");
+ i_err++;
+ } // switch(data[11])
+ } // elseif(data[12]==0 || data[12]==1)
+ if (i_err) {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ }
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Count=0;
+ //i_Sum=0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(i_ScanType!=1)
+
+ ul_Config =
+ data[1] | (data[2] << 6) | (data[5] << 7) | (data[3] << 8) |
+ (data[4] << 9);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(0 | ui_ChannelNo , devpriv->iobase+i_Offset + 0x4);
+ outl(0 | ui_ChannelNo,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+ /**************************/
+ /* Reset the configuration */
+ /**************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(0 , devpriv->iobase+i_Offset + 0x0);
+ outl(0, devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl(ul_Config , devpriv->iobase+i_Offset + 0x0);
+ outl(ul_Config,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x0);
+ //END JK 06.07.04: Management of sevrals boards
+
+ /***************************/
+ /*Reset the calibration bit */
+ /***************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ul_Temp = inl(devpriv->iobase+i_Offset + 12);
+ ul_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //outl((ul_Temp & 0xFFF9FFFF) , devpriv->iobase+.i_Offset + 12);
+ outl((ul_Temp & 0xFFF9FFFF),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ //END JK 06.07.04: Management of sevrals boards
+
+ if (data[9] == 1) {
+ devpriv->tsk_Current = current;
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_InterruptFlag=1;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 1;
+ //END JK 06.07.04: Management of sevrals boards
+ } // if(data[9]==1)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //else if(data[9]==1)
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Initialised=1;
+ s_BoardInfos[dev->minor].i_Initialised = 1;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].i_ScanType == 1)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //i_Sum=i_Sum+1;
+ s_BoardInfos[dev->minor].i_Sum =
+ s_BoardInfos[dev->minor].i_Sum + 1;
+ //END JK 06.07.04: Management of sevrals boards
+
+ insn->unused[0] = 0;
+ i_APCI3200_ReadAnalogInput(dev, s, insn, &ui_Dummy);
+ }
+
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital Value Of Input |
+ | data[1] : Calibration Offset Value |
+ | data[2] : Calibration Gain Value
+ | data[3] : CJC value
+ | data[4] : CJC offset value
+ | data[5] : CJC gain value
+ | Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ | data[6] : CJC current source from eeprom
+ | data[7] : Channel current source from eeprom
+ | data[8] : Channle gain factor from eeprom
+ | End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_ReadAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_DummyValue = 0;
+ int i_ConvertCJCCalibration;
+ int i = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_Initialised==0)
+ if (s_BoardInfos[dev->minor].i_Initialised == 0)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(i_Initialised==0);
+
+#ifdef PRINT_INFO
+ printk("\n insn->unused[0] = %i", insn->unused[0]);
+#endif
+
+ switch (insn->unused[0]) {
+ case 0:
+
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+0]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 0] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+
+ //Begin JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 6],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 7],
+ &s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->minor].
+ i_Count + 8]);
+
+#ifdef PRINT_INFO
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+6] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 6]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+7] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 7]);
+
+ printk("\n s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count+8] = %lu", s_BoardInfos[dev->minor].ui_InterruptChannelValue[s_BoardInfos[dev->minor].i_Count + 8]);
+#endif
+
+ //End JK 25.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_ReadCJCValue(dev, &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 3]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 3]=0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 3] = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //elseif((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE) && (i_CJCAvailable==1))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+ if ((s_BoardInfos[dev->minor].i_AutoCalibration == FALSE)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_APCI3200_ReadCalibrationOffsetValue(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 1]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 1] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count + 2]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos[dev->
+ minor].i_Count + 2] = ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if (( i_AutoCalibration == FALSE) && (i_InterruptFlag == FALSE))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE)&& (i_CJCAvailable==1))
+ if ((s_BoardInfos[dev->minor].i_ADDIDATAType == 2)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == FALSE)
+ && (s_BoardInfos[dev->minor].i_CJCAvailable == 1))
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC */
+ /**********************************************************/
+ /**********************************/
+ /*Test if the polarity is the same */
+ /**********************************/
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (s_BoardInfos[dev->minor].i_CJCPolarity !=
+ s_BoardInfos[dev->minor].i_ADDIDATAPolarity)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_ConvertCJCCalibration = 1;
+ } //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_CJCGain==i_ADDIDATAGain)
+ if (s_BoardInfos[dev->minor].i_CJCGain ==
+ s_BoardInfos[dev->minor].i_ADDIDATAGain)
+ //END JK 06.07.04: Management of sevrals boards
+ {
+ i_ConvertCJCCalibration = 0;
+ } //if(i_CJCGain==i_ADDIDATAGain)
+ else {
+ i_ConvertCJCCalibration = 1;
+ } //elseif(i_CJCGain==i_ADDIDATAGain)
+ } //elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (i_ConvertCJCCalibration == 1) {
+ i_APCI3200_ReadCJCCalOffset(dev,
+ &ui_DummyValue);
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+4]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] =
+ ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+
+ i_APCI3200_ReadCJCCalGain(dev, &ui_DummyValue);
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+5]=ui_DummyValue;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] =
+ ui_DummyValue;
+ //END JK 06.07.04: Management of sevrals boards
+ } //if(i_ConvertCJCCalibration==1)
+ else {
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_InterruptChannelValue[i_Count+4]=0;
+ //ui_InterruptChannelValue[i_Count+5]=0;
+
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 4] = 0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[s_BoardInfos
+ [dev->minor].i_Count + 5] = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ } //elseif(i_ConvertCJCCalibration==1)
+ } //if((i_ADDIDATAType==2) && (i_InterruptFlag == FALSE))
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].i_ScanType != 1) {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ } //if(i_ScanType!=1)
+ else {
+ //i_Count=i_Count +6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count +6;
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //else if(i_ScanType!=1)
+
+ //if((i_ScanType==1) &&(i_InterruptFlag==1))
+ if ((s_BoardInfos[dev->minor].i_ScanType == 1)
+ && (s_BoardInfos[dev->minor].i_InterruptFlag == 1)) {
+ //i_Count=i_Count-6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count-6;
+ s_BoardInfos[dev->minor].i_Count =
+ s_BoardInfos[dev->minor].i_Count - 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+ //if(i_ScanType==0)
+ if (s_BoardInfos[dev->minor].i_ScanType == 0) {
+ /*
+ data[0]= ui_InterruptChannelValue[0];
+ data[1]= ui_InterruptChannelValue[1];
+ data[2]= ui_InterruptChannelValue[2];
+ data[3]= ui_InterruptChannelValue[3];
+ data[4]= ui_InterruptChannelValue[4];
+ data[5]= ui_InterruptChannelValue[5];
+ */
+#ifdef PRINT_INFO
+ printk("\n data[0]= s_BoardInfos [dev->minor].ui_InterruptChannelValue[0];");
+#endif
+ data[0] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[0];
+ data[1] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[1];
+ data[2] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[2];
+ data[3] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[3];
+ data[4] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[4];
+ data[5] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[5];
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //printk("\n 0 - i_APCI3200_GetChannelCalibrationValue data [6] = %lu, data [7] = %lu, data [8] = %lu", data [6], data [7], data [8]);
+ i_APCI3200_GetChannelCalibrationValue(dev,
+ s_BoardInfos[dev->minor].ui_Channel_num,
+ &data[6], &data[7], &data[8]);
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ }
+ break;
+ case 1:
+
+ for (i = 0; i < insn->n; i++) {
+ //data[i]=ui_InterruptChannelValue[i];
+ data[i] =
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue[i];
+ }
+
+ //i_Count=0;
+ //i_Sum=0;
+ //if(i_ScanType==1)
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ if (s_BoardInfos[dev->minor].i_ScanType == 1) {
+ //i_Initialised=0;
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ //END JK 06.07.04: Management of sevrals boards
+ }
+ break;
+ default:
+ printk("\nThe parameters passed are in error\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //switch(insn->unused[0])
+
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_Read1AnalogInputChannel |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannel : Channel No to read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital Value read |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+INT i_APCI3200_Read1AnalogInputChannel(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ UINT ui_ChannelNo = 0;
+ UINT ui_CommandRegister = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //ui_ChannelNo=i_ChannelNo;
+ ui_ChannelNo = s_BoardInfos[dev->minor].i_ChannelNo;
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: Bad channel value is used when using differential mode
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ outl(0 | s_BoardInfos[dev->minor].i_ChannelNo,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: Bad channel value is used when using differential mode
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /**************************************************************************/
+ /* Set the start end stop index to the selected channel and set the start */
+ /**************************************************************************/
+
+ ui_CommandRegister = ui_ChannelNo | (ui_ChannelNo << 8) | 0x80000;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /******************************/
+ /* Write the command register */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*************************/
+ /*Read the EOC Status bit */
+ /*************************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /***************************************/
+ /* Read the digital value of the input */
+ /***************************************/
+
+ //data[0] = inl (devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ //END JK 06.07.04: Management of sevrals boards
+
+ } // if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCalibrationOffsetValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read calibration offset value of the selected channel|
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Calibration offset Value |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device * dev, UINT * data)
+{
+ UINT ui_Temp = 0, ui_EOC = 0;
+ UINT ui_CommandRegister = 0;
+
+ //BEGIN JK 06.07.04: Management of sevrals boards
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: This seems not necessary !
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: This seems not necessary !
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /*****************************/
+ /*Read the calibration offset */
+ /*****************************/
+ //ui_Temp = inl(devpriv->iobase+i_Offset + 12);
+ ui_Temp = inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*********************************/
+ /*Configure the Offset Conversion */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Temp | 0x00020000), devpriv->iobase+i_Offset + 12);
+ outl((ui_Temp | 0x00020000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister, devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl (devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset */
+ /**************************************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset+ 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCalibrationGainValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read calibration gain value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Calibration gain Value Of Input |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCalibrationGainValue(struct comedi_device * dev, UINT * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ /*********************************/
+ /* Write the channel to configure */
+ /*********************************/
+ //Begin JK 20.10.2004: This seems not necessary !
+ //outl(0 | ui_Channel_num , devpriv->iobase+i_Offset + 0x4);
+ //outl(0 | s_BoardInfos [dev->minor].ui_Channel_num , devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 0x4);
+ //End JK 20.10.2004: This seems not necessary !
+
+ /***************************/
+ /*Read the calibration gain */
+ /***************************/
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /*******************************/
+ /*Configure the Gain Conversion */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00040000 , devpriv->iobase+i_Offset + 12);
+ outl(0x00040000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+
+ ui_CommandRegister = 0;
+
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ } //if (i_InterruptFlag == ADDIDATA_ENABLE)
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+
+ do {
+
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /************************************************/
+ /*Read the digital value of the calibration Gain */
+ /************************************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC value of the selected channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC Value |
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_ReadCJCValue(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+
+ /******************************/
+ /*Set the converting time unit */
+ /******************************/
+
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl( 0x00000400 , devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************************/
+ /*Initialise dw_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ }
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister , devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*****************************/
+ /*Test if interrupt is enable */
+ /*****************************/
+
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+
+ } while (ui_EOC != 1);
+
+ /***********************************/
+ /*Read the digital value of the CJC */
+ /***********************************/
+
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCCalOffset |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC calibration offset value of the selected channel
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC calibration offset Value
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalOffset(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+ /*******************************************/
+ /*Read calibration offset value for the CJC */
+ /*******************************************/
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00000400 , devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*********************************/
+ /*Configure the Offset Conversion */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00020000, devpriv->iobase+i_Offset + 12);
+ outl(0x00020000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /*******************************/
+ /*Initialise ui_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+
+ }
+
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister,devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+
+ /**************************************************/
+ /*Read the digital value of the calibration Offset */
+ /**************************************************/
+ //data[0] = inl(devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_ReadCJCGainValue |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Read CJC calibration gain value
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | UINT ui_NoOfChannels : No Of Channels To read |
+ | UINT *data : Data Pointer to read status |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : CJC calibration gain value
+ |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_ReadCJCCalGain(struct comedi_device * dev, unsigned int * data)
+{
+ UINT ui_EOC = 0;
+ INT ui_CommandRegister = 0;
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTimeUnit , devpriv->iobase+i_Offset + 36);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTimeUnit,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /**************************/
+ /* Set the convert timing */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(i_ADDIDATAConversionTime , devpriv->iobase+i_Offset + 32);
+ outl(s_BoardInfos[dev->minor].i_ADDIDATAConversionTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+ /******************************/
+ /*Configure the CJC Conversion */
+ /******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00000400,devpriv->iobase+i_Offset + 4);
+ outl(0x00000400,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************************/
+ /*Configure the Gain Conversion */
+ /*******************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(0x00040000,devpriv->iobase+i_Offset + 12);
+ outl(0x00040000,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+
+ /*******************************/
+ /*Initialise dw_CommandRegister */
+ /*******************************/
+ ui_CommandRegister = 0;
+ /*********************************/
+ /*Test if the interrupt is enable */
+ /*********************************/
+ //if (i_InterruptFlag == ADDIDATA_ENABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_ENABLE) {
+ /**********************/
+ /*Enable the interrupt */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00100000;
+ }
+ /**********************/
+ /*Start the conversion */
+ /**********************/
+ ui_CommandRegister = ui_CommandRegister | 0x00080000;
+ /***************************/
+ /*Write the command regiter */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_CommandRegister ,devpriv->iobase+i_Offset + 8);
+ outl(ui_CommandRegister,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == ADDIDATA_DISABLE) {
+ do {
+ /*******************/
+ /*Read the EOC flag */
+ /*******************/
+ //ui_EOC = inl(devpriv->iobase+i_Offset + 20) & 1;
+ ui_EOC = inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 20) & 1;
+ } while (ui_EOC != 1);
+ /************************************************/
+ /*Read the digital value of the calibration Gain */
+ /************************************************/
+ //data[0] = inl (devpriv->iobase+i_Offset + 28);
+ data[0] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ } //if (i_InterruptFlag == ADDIDATA_DISABLE)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_InsnBits_AnalogInput_Test |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Tests the Selected Anlog Input Channel |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer contains |
+ | configuration parameters as below |
+ |
+ |
+ | data[0] : 0 TestAnalogInputShortCircuit
+ | 1 TestAnalogInputConnection |
+
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ | data[0] : Digital value obtained |
+ | data[1] : calibration offset |
+ | data[2] : calibration gain |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Configuration = 0;
+ INT i_Temp; //,i_TimeUnit;
+ //if(i_Initialised==0)
+
+ if (s_BoardInfos[dev->minor].i_Initialised == 0) {
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(i_Initialised==0);
+ if (data[0] != 0 && data[0] != 1) {
+ printk("\nError in selection of functionality\n");
+ i_APCI3200_Reset(dev);
+ return -EINVAL;
+ } //if(data[0]!=0 && data[0]!=1)
+
+ if (data[0] == 1) //Perform Short Circuit TEST
+ {
+ /**************************/
+ /*Set the short-cicuit bit */
+ /**************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset + 12) >> 19) & 1) !=
+ 1) ;
+ //outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00001000 | s_BoardInfos[dev->minor].i_ChannelNo),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 4);
+ /*************************/
+ /*Set the time unit to ns */
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1; */
+ //i_Temp= i_InterruptFlag ;
+ i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+ //i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+ //if(i_AutoCalibration == FALSE)
+ if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl((0x00001000 |i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00001000 | s_BoardInfos[dev->minor].
+ i_ChannelNo),
+ devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 4);
+ data++;
+ i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+ data++;
+ i_APCI3200_ReadCalibrationGainValue(dev, data);
+ }
+ } else {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset + 12) >> 19) & 1) !=
+ 1) ;
+ //outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00000800 | s_BoardInfos[dev->minor].i_ChannelNo),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 4);
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 0);
+ ui_Configuration =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 0);
+ /*************************/
+ /*Set the time unit to ns */
+ /*************************/
+ /* i_TimeUnit= i_ADDIDATAConversionTimeUnit;
+ i_ADDIDATAConversionTimeUnit= 1; */
+ //i_Temp= i_InterruptFlag ;
+ i_Temp = s_BoardInfos[dev->minor].i_InterruptFlag;
+ //i_InterruptFlag = ADDIDATA_DISABLE;
+ s_BoardInfos[dev->minor].i_InterruptFlag = ADDIDATA_DISABLE;
+ i_APCI3200_Read1AnalogInputChannel(dev, s, insn, data);
+ //if(i_AutoCalibration == FALSE)
+ if (s_BoardInfos[dev->minor].i_AutoCalibration == FALSE) {
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].
+ i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((0x00000800|i_ChannelNo) , devpriv->iobase+i_Offset + 4);
+ outl((0x00000800 | s_BoardInfos[dev->minor].
+ i_ChannelNo),
+ devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 4);
+ data++;
+ i_APCI3200_ReadCalibrationOffsetValue(dev, data);
+ data++;
+ i_APCI3200_ReadCalibrationGainValue(dev, data);
+ }
+ }
+ //i_InterruptFlag=i_Temp ;
+ s_BoardInfos[dev->minor].i_InterruptFlag = i_Temp;
+ //printk("\ni_InterruptFlag=%d\n",i_InterruptFlag);
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_InsnWriteReleaseAnalogInput |
+ | (struct comedi_device *dev,struct comedi_subdevice *s, |
+ | struct comedi_insn *insn,unsigned int *data) |
+ +----------------------------------------------------------------------------+
+ | Task : Resets the channels |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev : Driver handle |
+ | struct comedi_subdevice *s : Subdevice Pointer |
+ | struct comedi_insn *insn : Insn Structure Pointer |
+ | unsigned int *data : Data Pointer
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ i_APCI3200_Reset(dev);
+ return insn->n;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev|
+ | ,struct comedi_subdevice *s,struct comedi_cmd *cmd) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Test validity for a command for cyclic anlog input |
+ | acquisition |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | struct comedi_cmd *cmd |
+ | |
+ |
+ | |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value :0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandTestAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+
+ int err = 0;
+ int tmp; // divisor1,divisor2;
+ UINT ui_ConvertTime = 0;
+ UINT ui_ConvertTimeBase = 0;
+ UINT ui_DelayTime = 0;
+ UINT ui_DelayTimeBase = 0;
+ INT i_Triggermode = 0;
+ INT i_TriggerEdge = 0;
+ INT i_NbrOfChannel = 0;
+ INT i_Cpt = 0;
+ double d_ConversionTimeForAllChannels = 0.0;
+ double d_SCANTimeNewUnit = 0.0;
+ // step 1: make sure trigger sources are trivially valid
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+ //if(i_InterruptFlag==0)
+ if (s_BoardInfos[dev->minor].i_InterruptFlag == 0) {
+ err++;
+ // printk("\nThe interrupt should be enabled\n");
+ }
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 1;
+ }
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ err++;
+ }
+ if (cmd->start_src == TRIG_EXT) {
+ i_TriggerEdge = cmd->start_arg & 0xFFFF;
+ i_Triggermode = cmd->start_arg >> 16;
+ if (i_TriggerEdge < 1 || i_TriggerEdge > 3) {
+ err++;
+ printk("\nThe trigger edge selection is in error\n");
+ }
+ if (i_Triggermode != 2) {
+ err++;
+ printk("\nThe trigger mode selection is in error\n");
+ }
+ }
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+
+ if (cmd->convert_src != TRIG_TIMER)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 2;
+ }
+ //i_FirstChannel=cmd->chanlist[0];
+ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+ //i_LastChannel=cmd->chanlist[1];
+ s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+ ui_ConvertTimeBase = cmd->convert_arg >> 16;
+ if (ui_ConvertTime != 20 && ui_ConvertTime != 40
+ && ui_ConvertTime != 80 && ui_ConvertTime != 160)
+ {
+ printk("\nThe selection of conversion time reload value is in error\n");
+ err++;
+ } // if (ui_ConvertTime!=20 && ui_ConvertTime!=40 && ui_ConvertTime!=80 && ui_ConvertTime!=160 )
+ if (ui_ConvertTimeBase != 2) {
+ printk("\nThe selection of conversion time unit is in error\n");
+ err++;
+ } //if(ui_ConvertTimeBase!=2)
+ } else {
+ ui_ConvertTime = 0;
+ ui_ConvertTimeBase = 0;
+ }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ ui_DelayTime = 0;
+ ui_DelayTimeBase = 0;
+ } //if(cmd->scan_begin_src==TRIG_FOLLOW)
+ else {
+ ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+ ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+ if (ui_DelayTimeBase != 2 && ui_DelayTimeBase != 3) {
+ err++;
+ printk("\nThe Delay time base selection is in error\n");
+ }
+ if (ui_DelayTime < 1 && ui_DelayTime > 1023) {
+ err++;
+ printk("\nThe Delay time value is in error\n");
+ }
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 3;
+ }
+ fpu_begin();
+ d_SCANTimeNewUnit = (double)ui_DelayTime;
+ //i_NbrOfChannel= i_LastChannel-i_FirstChannel + 4;
+ i_NbrOfChannel =
+ s_BoardInfos[dev->minor].i_LastChannel -
+ s_BoardInfos[dev->minor].i_FirstChannel + 4;
+ /**********************************************************/
+ /*calculate the total conversion time for all the channels */
+ /**********************************************************/
+ d_ConversionTimeForAllChannels =
+ (double)((double)ui_ConvertTime /
+ (double)i_NbrOfChannel);
+
+ /*******************************/
+ /*Convert the frequence in time */
+ /*******************************/
+ d_ConversionTimeForAllChannels =
+ (double)1.0 / d_ConversionTimeForAllChannels;
+ ui_ConvertTimeBase = 3;
+ /***********************************/
+ /*Test if the time unit is the same */
+ /***********************************/
+
+ if (ui_DelayTimeBase <= ui_ConvertTimeBase) {
+
+ for (i_Cpt = 0;
+ i_Cpt < (ui_ConvertTimeBase - ui_DelayTimeBase);
+ i_Cpt++) {
+
+ d_ConversionTimeForAllChannels =
+ d_ConversionTimeForAllChannels * 1000;
+ d_ConversionTimeForAllChannels =
+ d_ConversionTimeForAllChannels + 1;
+ }
+ } else {
+ for (i_Cpt = 0;
+ i_Cpt < (ui_DelayTimeBase - ui_ConvertTimeBase);
+ i_Cpt++) {
+ d_SCANTimeNewUnit = d_SCANTimeNewUnit * 1000;
+
+ }
+ }
+
+ if (d_ConversionTimeForAllChannels >= d_SCANTimeNewUnit) {
+
+ printk("\nSCAN Delay value cannot be used\n");
+ /*********************************/
+ /*SCAN Delay value cannot be used */
+ /*********************************/
+ err++;
+ }
+ fpu_end();
+ } //else if(cmd->scan_begin_src==TRIG_FOLLOW)
+
+ if (err) {
+ i_APCI3200_Reset(dev);
+ return 4;
+ }
+
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev,|
+ | struct comedi_subdevice *s)|
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Stop the acquisition |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value :0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_StopCyclicAcquisition(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ UINT ui_Configuration = 0;
+ //i_InterruptFlag=0;
+ //i_Initialised=0;
+ //i_Count=0;
+ //i_Sum=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+
+ /*******************/
+ /*Read the register */
+ /*******************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ /*****************************/
+ /*Reset the START and IRQ bit */
+ /*****************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration & 0xFFE7FFFF),devpriv->iobase+i_Offset + 8);
+ outl((ui_Configuration & 0xFFE7FFFF),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name : int i_APCI3200_CommandAnalogInput(struct comedi_device *dev, |
+ | struct comedi_subdevice *s) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : Does asynchronous acquisition |
+ | Determines the mode 1 or 2. |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | struct comedi_subdevice *s |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_CommandAnalogInput(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ UINT ui_Configuration = 0;
+ //INT i_CurrentSource = 0;
+ UINT ui_Trigger = 0;
+ UINT ui_TriggerEdge = 0;
+ UINT ui_Triggermode = 0;
+ UINT ui_ScanMode = 0;
+ UINT ui_ConvertTime = 0;
+ UINT ui_ConvertTimeBase = 0;
+ UINT ui_DelayTime = 0;
+ UINT ui_DelayTimeBase = 0;
+ UINT ui_DelayMode = 0;
+ //i_FirstChannel=cmd->chanlist[0];
+ //i_LastChannel=cmd->chanlist[1];
+ s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
+ s_BoardInfos[dev->minor].i_LastChannel = cmd->chanlist[1];
+ if (cmd->start_src == TRIG_EXT) {
+ ui_Trigger = 1;
+ ui_TriggerEdge = cmd->start_arg & 0xFFFF;
+ ui_Triggermode = cmd->start_arg >> 16;
+ } //if(cmd->start_src==TRIG_EXT)
+ else {
+ ui_Trigger = 0;
+ } //elseif(cmd->start_src==TRIG_EXT)
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ ui_ScanMode = 0;
+ } // if (cmd->stop_src==TRIG_COUNT)
+ else {
+ ui_ScanMode = 2;
+ } //else if (cmd->stop_src==TRIG_COUNT)
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ ui_DelayTime = 0;
+ ui_DelayTimeBase = 0;
+ ui_DelayMode = 0;
+ } //if(cmd->scan_begin_src==TRIG_FOLLOW)
+ else {
+ ui_DelayTime = cmd->scan_begin_arg & 0xFFFF;
+ ui_DelayTimeBase = cmd->scan_begin_arg >> 16;
+ ui_DelayMode = 1;
+ } //else if(cmd->scan_begin_src==TRIG_FOLLOW)
+ // printk("\nui_DelayTime=%u\n",ui_DelayTime);
+ // printk("\nui_DelayTimeBase=%u\n",ui_DelayTimeBase);
+ if (cmd->convert_src == TRIG_TIMER) {
+ ui_ConvertTime = cmd->convert_arg & 0xFFFF;
+ ui_ConvertTimeBase = cmd->convert_arg >> 16;
+ } else {
+ ui_ConvertTime = 0;
+ ui_ConvertTimeBase = 0;
+ }
+
+ // if(i_ADDIDATAType ==1 || ((i_ADDIDATAType==2)))
+ // {
+ /**************************************************/
+ /*Read the old configuration of the current source */
+ /**************************************************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 12);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ /***********************************************/
+ /*Write the configuration of the current source */
+ /***********************************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration & 0xFFC00000 ), devpriv->iobase+i_Offset +12);
+ outl((ui_Configuration & 0xFFC00000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 12);
+ // }
+ ui_Configuration = 0;
+ // printk("\nfirstchannel=%u\n",i_FirstChannel);
+ // printk("\nlastchannel=%u\n",i_LastChannel);
+ // printk("\nui_Trigger=%u\n",ui_Trigger);
+ // printk("\nui_TriggerEdge=%u\n",ui_TriggerEdge);
+ // printk("\nui_Triggermode=%u\n",ui_Triggermode);
+ // printk("\nui_DelayMode=%u\n",ui_DelayMode);
+ // printk("\nui_ScanMode=%u\n",ui_ScanMode);
+
+ //ui_Configuration = i_FirstChannel |(i_LastChannel << 8)| 0x00100000 |
+ ui_Configuration =
+ s_BoardInfos[dev->minor].i_FirstChannel | (s_BoardInfos[dev->
+ minor].
+ i_LastChannel << 8) | 0x00100000 | (ui_Trigger << 24) |
+ (ui_TriggerEdge << 25) | (ui_Triggermode << 27) | (ui_DelayMode
+ << 18) | (ui_ScanMode << 16);
+
+ /*************************/
+ /*Write the Configuration */
+ /*************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl( ui_Configuration, devpriv->iobase+i_Offset + 0x8);
+ outl(ui_Configuration,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 0x8);
+ /***********************/
+ /*Write the Delay Value */
+ /***********************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_DelayTime,devpriv->iobase+i_Offset + 40);
+ outl(ui_DelayTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 40);
+ /***************************/
+ /*Write the Delay time base */
+ /***************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_DelayTimeBase,devpriv->iobase+i_Offset + 44);
+ outl(ui_DelayTimeBase,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 44);
+ /*********************************/
+ /*Write the conversion time value */
+ /*********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_ConvertTime,devpriv->iobase+i_Offset + 32);
+ outl(ui_ConvertTime,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 32);
+
+ /********************************/
+ /*Write the conversion time base */
+ /********************************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl(ui_ConvertTimeBase,devpriv->iobase+i_Offset + 36);
+ outl(ui_ConvertTimeBase,
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 36);
+ /*******************/
+ /*Read the register */
+ /*******************/
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 4);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /******************/
+ /*Set the SCAN bit */
+ /******************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+
+ //outl(((ui_Configuration & 0x1E0FF) | 0x00002000),devpriv->iobase+i_Offset + 4);
+ outl(((ui_Configuration & 0x1E0FF) | 0x00002000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 4);
+ /*******************/
+ /*Read the register */
+ /*******************/
+ ui_Configuration = 0;
+ //ui_Configuration = inl(devpriv->iobase+i_Offset + 8);
+ ui_Configuration =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+
+ /*******************/
+ /*Set the START bit */
+ /*******************/
+ //while (((inl(devpriv->iobase+i_Offset+12)>>19) & 1) != 1);
+ while (((inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset +
+ 12) >> 19) & 1) != 1) ;
+ //outl((ui_Configuration | 0x00080000),devpriv->iobase+i_Offset + 8);
+ outl((ui_Configuration | 0x00080000),
+ devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 8);
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : int i_APCI3200_Reset(struct comedi_device *dev) |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task :Resets the registers of the card |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+
+int i_APCI3200_Reset(struct comedi_device * dev)
+{
+ INT i_Temp;
+ DWORD dw_Dummy;
+ //i_InterruptFlag=0;
+ //i_Initialised==0;
+ //i_Count=0;
+ //i_Sum=0;
+
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ s_BoardInfos[dev->minor].i_Initialised = 0;
+ s_BoardInfos[dev->minor].i_Count = 0;
+ s_BoardInfos[dev->minor].i_Sum = 0;
+ s_BoardInfos[dev->minor].b_StructInitialized = 0;
+
+ outl(0x83838383, devpriv->i_IobaseAmcc + 0x60);
+
+ // Enable the interrupt for the controler
+ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38);
+ outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38);
+ outl(0, devpriv->i_IobaseAddon); //Resets the output
+ /***************/
+ /*Empty the buffer */
+ /**************/
+ for (i_Temp = 0; i_Temp <= 95; i_Temp++) {
+ //ui_InterruptChannelValue[i_Temp]=0;
+ s_BoardInfos[dev->minor].ui_InterruptChannelValue[i_Temp] = 0;
+ } //for(i_Temp=0;i_Temp<=95;i_Temp++)
+ /*****************************/
+ /*Reset the START and IRQ bit */
+ /*****************************/
+ for (i_Temp = 0; i_Temp <= 192;) {
+ while (((inl(devpriv->iobase + i_Temp + 12) >> 19) & 1) != 1) ;
+ outl(0, devpriv->iobase + i_Temp + 8);
+ i_Temp = i_Temp + 64;
+ } //for(i_Temp=0;i_Temp<=192;i_Temp+64)
+ return 0;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function Name : static void v_APCI3200_Interrupt |
+ | (int irq , void *d) |
+ +----------------------------------------------------------------------------+
+ | Task : Interrupt processing Routine |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : int irq : irq number |
+ | void *d : void pointer |
+ +----------------------------------------------------------------------------+
+ | Output Parameters : -- |
+ +----------------------------------------------------------------------------+
+ | Return Value : TRUE : No error occur |
+ | : FALSE : Error occur. Return the error |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+void v_APCI3200_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ UINT ui_StatusRegister = 0;
+ UINT ui_ChannelNumber = 0;
+ INT i_CalibrationFlag = 0;
+ INT i_CJCFlag = 0;
+ UINT ui_DummyValue = 0;
+ UINT ui_DigitalTemperature = 0;
+ UINT ui_DigitalInput = 0;
+ int i_ConvertCJCCalibration;
+
+ //BEGIN JK TEST
+ int i_ReturnValue = 0;
+ //END JK TEST
+
+ //printk ("\n i_ScanType = %i i_ADDIDATAType = %i", s_BoardInfos [dev->minor].i_ScanType, s_BoardInfos [dev->minor].i_ADDIDATAType);
+
+ //switch(i_ScanType)
+ switch (s_BoardInfos[dev->minor].i_ScanType) {
+ case 0:
+ case 1:
+ //switch(i_ADDIDATAType)
+ switch (s_BoardInfos[dev->minor].i_ADDIDATAType) {
+ case 0:
+ case 1:
+
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 16);
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+ //i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+ i_CalibrationFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 12) & 0x00060000) >>
+ 17);
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+
+ /*************************************/
+ /*Read the digital analog input value */
+ /*************************************/
+ //ui_DigitalInput = inl(devpriv->iobase+i_Offset + 28);
+ ui_DigitalInput =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ /***********************************************/
+ /* Test if the value read is the channel value */
+ /***********************************************/
+ if (i_CalibrationFlag == 0) {
+ //ui_InterruptChannelValue[i_Count + 0] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 0] = ui_DigitalInput;
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ /*
+ printk("\n 1 - i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos %i", ui_ChannelNumber);
+ i_APCI3200_GetChannelCalibrationValue (dev, s_BoardInfos [dev->minor].ui_Channel_num,
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 6],
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 7],
+ &s_BoardInfos [dev->minor].ui_InterruptChannelValue[s_BoardInfos [dev->minor].i_Count + 8]);
+ */
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ /******************************************************/
+ /*Start the conversion of the calibration offset value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationOffsetValue
+ (dev, &ui_DummyValue);
+ } //if (i_CalibrationFlag == 0)
+ /**********************************************************/
+ /* Test if the value read is the calibration offset value */
+ /**********************************************************/
+
+ if (i_CalibrationFlag == 1) {
+
+ /******************/
+ /* Save the value */
+ /******************/
+
+ //ui_InterruptChannelValue[i_Count + 1] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 1] = ui_DigitalInput;
+
+ /******************************************************/
+ /* Start the conversion of the calibration gain value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+ } //if (i_CalibrationFlag == 1)
+ /******************************************************/
+ /*Test if the value read is the calibration gain value */
+ /******************************************************/
+
+ if (i_CalibrationFlag == 2) {
+
+ /****************/
+ /*Save the value */
+ /****************/
+ //ui_InterruptChannelValue[i_Count + 2] = ui_DigitalInput;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 2] = ui_DigitalInput;
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType == 1) {
+
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].
+ i_InterruptFlag = 0;
+ //i_Count=i_Count + 6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+ s_BoardInfos[dev->minor].
+ i_Count =
+ s_BoardInfos[dev->
+ minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //if(i_ScanType==1)
+ else {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].
+ i_Count = 0;
+ } //elseif(i_ScanType==1)
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType != 1) {
+ i_ReturnValue = send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if(i_ScanType!=1)
+ else {
+ //if(i_ChannelCount==i_Sum)
+ if (s_BoardInfos[dev->minor].
+ i_ChannelCount ==
+ s_BoardInfos[dev->
+ minor].i_Sum) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ }
+ } //if(i_ScanType!=1)
+ } //if (i_CalibrationFlag == 2)
+ } // if ((ui_StatusRegister & 0x2) == 0x2)
+
+ break;
+
+ case 2:
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 16);
+ /*************************/
+ /*Test if interrupt occur */
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+
+ //i_CJCFlag = ((inl(devpriv->iobase+i_Offset + 4) & 0x00000400) >> 10);
+ i_CJCFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 4) & 0x00000400) >> 10);
+
+ //i_CalibrationFlag = ((inl(devpriv->iobase+i_Offset + 12) & 0x00060000) >> 17);
+ i_CalibrationFlag =
+ ((inl(devpriv->iobase +
+ s_BoardInfos[dev->
+ minor].
+ i_Offset +
+ 12) & 0x00060000) >>
+ 17);
+
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+ ui_ChannelNumber =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 24);
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].ui_Channel_num =
+ ui_ChannelNumber;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ /************************************/
+ /*Read the digital temperature value */
+ /************************************/
+ //ui_DigitalTemperature = inl(devpriv->iobase+i_Offset + 28);
+ ui_DigitalTemperature =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+
+ /*********************************************/
+ /*Test if the value read is the channel value */
+ /*********************************************/
+
+ if ((i_CalibrationFlag == 0)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 0]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 0] =
+ ui_DigitalTemperature;
+
+ /*********************************/
+ /*Start the conversion of the CJC */
+ /*********************************/
+ i_APCI3200_ReadCJCValue(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 0) && (i_CJCFlag == 0))
+
+ /*****************************************/
+ /*Test if the value read is the CJC value */
+ /*****************************************/
+
+ if ((i_CJCFlag == 1)
+ && (i_CalibrationFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 3]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 3] =
+ ui_DigitalTemperature;
+
+ /******************************************************/
+ /*Start the conversion of the calibration offset value */
+ /******************************************************/
+ i_APCI3200_ReadCalibrationOffsetValue
+ (dev, &ui_DummyValue);
+ } // if ((i_CJCFlag == 1) && (i_CalibrationFlag == 0))
+
+ /********************************************************/
+ /*Test if the value read is the calibration offset value */
+ /********************************************************/
+
+ if ((i_CalibrationFlag == 1)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 1]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 1] =
+ ui_DigitalTemperature;
+
+ /****************************************************/
+ /*Start the conversion of the calibration gain value */
+ /****************************************************/
+ i_APCI3200_ReadCalibrationGainValue(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 1) && (i_CJCFlag == 0))
+
+ /******************************************************/
+ /*Test if the value read is the calibration gain value */
+ /******************************************************/
+
+ if ((i_CalibrationFlag == 2)
+ && (i_CJCFlag == 0)) {
+ //ui_InterruptChannelValue[i_Count + 2]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 2] =
+ ui_DigitalTemperature;
+
+ /**********************************************************/
+ /*Test if the Calibration channel must be read for the CJC */
+ /**********************************************************/
+
+ /*Test if the polarity is the same */
+ /**********************************/
+ //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (s_BoardInfos[dev->minor].
+ i_CJCPolarity !=
+ s_BoardInfos[dev->minor].
+ i_ADDIDATAPolarity) {
+ i_ConvertCJCCalibration = 1;
+ } //if(i_CJCPolarity!=i_ADDIDATAPolarity)
+ else {
+ //if(i_CJCGain==i_ADDIDATAGain)
+ if (s_BoardInfos[dev->minor].
+ i_CJCGain ==
+ s_BoardInfos[dev->
+ minor].
+ i_ADDIDATAGain) {
+ i_ConvertCJCCalibration
+ = 0;
+ } //if(i_CJCGain==i_ADDIDATAGain)
+ else {
+ i_ConvertCJCCalibration
+ = 1;
+ } //elseif(i_CJCGain==i_ADDIDATAGain)
+ } //elseif(i_CJCPolarity!=i_ADDIDATAPolarity)
+ if (i_ConvertCJCCalibration == 1) {
+ /****************************************************************/
+ /*Start the conversion of the calibration gain value for the CJC */
+ /****************************************************************/
+ i_APCI3200_ReadCJCCalOffset(dev,
+ &ui_DummyValue);
+
+ } //if(i_ConvertCJCCalibration==1)
+ else {
+ //ui_InterruptChannelValue[i_Count + 4]=0;
+ //ui_InterruptChannelValue[i_Count + 5]=0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->
+ minor].i_Count +
+ 4] = 0;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->
+ minor].i_Count +
+ 5] = 0;
+ } //elseif(i_ConvertCJCCalibration==1)
+ } //else if ((i_CalibrationFlag == 2) && (i_CJCFlag == 0))
+
+ /********************************************************************/
+ /*Test if the value read is the calibration offset value for the CJC */
+ /********************************************************************/
+
+ if ((i_CalibrationFlag == 1)
+ && (i_CJCFlag == 1)) {
+ //ui_InterruptChannelValue[i_Count + 4]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 4] =
+ ui_DigitalTemperature;
+
+ /****************************************************************/
+ /*Start the conversion of the calibration gain value for the CJC */
+ /****************************************************************/
+ i_APCI3200_ReadCJCCalGain(dev,
+ &ui_DummyValue);
+
+ } //if ((i_CalibrationFlag == 1) && (i_CJCFlag == 1))
+
+ /******************************************************************/
+ /*Test if the value read is the calibration gain value for the CJC */
+ /******************************************************************/
+
+ if ((i_CalibrationFlag == 2)
+ && (i_CJCFlag == 1)) {
+ //ui_InterruptChannelValue[i_Count + 5]=ui_DigitalTemperature;
+ s_BoardInfos[dev->minor].
+ ui_InterruptChannelValue
+ [s_BoardInfos[dev->minor].
+ i_Count + 5] =
+ ui_DigitalTemperature;
+
+ //if(i_ScanType==1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType == 1) {
+
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].
+ i_InterruptFlag = 0;
+ //i_Count=i_Count + 6;
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ //s_BoardInfos [dev->minor].i_Count=s_BoardInfos [dev->minor].i_Count + 6;
+ s_BoardInfos[dev->minor].
+ i_Count =
+ s_BoardInfos[dev->
+ minor].i_Count + 9;
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ } //if(i_ScanType==1)
+ else {
+ //i_Count=0;
+ s_BoardInfos[dev->minor].
+ i_Count = 0;
+ } //elseif(i_ScanType==1)
+
+ //if(i_ScanType!=1)
+ if (s_BoardInfos[dev->minor].
+ i_ScanType != 1) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+ } //if(i_ScanType!=1)
+ else {
+ //if(i_ChannelCount==i_Sum)
+ if (s_BoardInfos[dev->minor].
+ i_ChannelCount ==
+ s_BoardInfos[dev->
+ minor].i_Sum) {
+ send_sig(SIGIO, devpriv->tsk_Current, 0); // send signal to the sample
+
+ } //if(i_ChannelCount==i_Sum)
+ } //else if(i_ScanType!=1)
+ } //if ((i_CalibrationFlag == 2) && (i_CJCFlag == 1))
+
+ } //else if ((ui_StatusRegister & 0x2) == 0x2)
+ break;
+ } //switch(i_ADDIDATAType)
+ break;
+ case 2:
+ case 3:
+ i_APCI3200_InterruptHandleEos(dev);
+ break;
+ } //switch(i_ScanType)
+ return;
+}
+
+/*
+ +----------------------------------------------------------------------------+
+ | Function name :int i_APCI3200_InterruptHandleEos(struct comedi_device *dev) |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Task : . |
+ | This function copies the acquired data(from FIFO) |
+ | to Comedi buffer. |
+ | |
+ +----------------------------------------------------------------------------+
+ | Input Parameters : struct comedi_device *dev |
+ | |
+ | |
+ +----------------------------------------------------------------------------+
+ | Return Value : 0 |
+ | |
+ +----------------------------------------------------------------------------+
+*/
+int i_APCI3200_InterruptHandleEos(struct comedi_device * dev)
+{
+ UINT ui_StatusRegister = 0;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //comedi_async *async = s->async;
+ //UINT *data;
+ //data=async->data+async->buf_int_ptr;//new samples added from here onwards
+ int n = 0, i = 0;
+ //END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ /************************************/
+ /*Read the interrupt status register */
+ /************************************/
+ //ui_StatusRegister = inl(devpriv->iobase+i_Offset + 16);
+ ui_StatusRegister =
+ inl(devpriv->iobase + s_BoardInfos[dev->minor].i_Offset + 16);
+
+ /*************************/
+ /*Test if interrupt occur */
+ /*************************/
+
+ if ((ui_StatusRegister & 0x2) == 0x2) {
+ /*************************/
+ /*Read the channel number */
+ /*************************/
+ //ui_ChannelNumber = inl(devpriv->iobase+i_Offset + 24);
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //This value is not used
+ //ui_ChannelNumber = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 24);
+ s->async->events = 0;
+ //END JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ /*************************************/
+ /*Read the digital Analog Input value */
+ /*************************************/
+
+ //data[i_Count] = inl(devpriv->iobase+i_Offset + 28);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //data[s_BoardInfos [dev->minor].i_Count] = inl(devpriv->iobase+s_BoardInfos [dev->minor].i_Offset + 28);
+ s_BoardInfos[dev->minor].ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count] =
+ inl(devpriv->iobase +
+ s_BoardInfos[dev->minor].i_Offset + 28);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //if((i_Count == (i_LastChannel-i_FirstChannel+3)))
+ if ((s_BoardInfos[dev->minor].i_Count ==
+ (s_BoardInfos[dev->minor].i_LastChannel -
+ s_BoardInfos[dev->minor].
+ i_FirstChannel + 3))) {
+
+ //Begin JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ s_BoardInfos[dev->minor].i_Count++;
+
+ for (i = s_BoardInfos[dev->minor].i_FirstChannel;
+ i <= s_BoardInfos[dev->minor].i_LastChannel;
+ i++) {
+ i_APCI3200_GetChannelCalibrationValue(dev, i,
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3)],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 1],
+ &s_BoardInfos[dev->minor].
+ ui_ScanValueArray[s_BoardInfos[dev->
+ minor].i_Count + ((i -
+ s_BoardInfos
+ [dev->minor].
+ i_FirstChannel)
+ * 3) + 2]);
+ }
+
+ //End JK 22.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+ //i_Count=-1;
+
+ s_BoardInfos[dev->minor].i_Count = -1;
+
+ //async->buf_int_count+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_count+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_ptr+=(i_LastChannel-i_FirstChannel+4)*sizeof(UINT);
+ //Begin JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //async->buf_int_ptr+=(s_BoardInfos [dev->minor].i_LastChannel-s_BoardInfos [dev->minor].i_FirstChannel+4)*sizeof(UINT);
+ //comedi_eos(dev,s);
+
+ // Set the event type (Comedi Buffer End Of Scan)
+ s->async->events |= COMEDI_CB_EOS;
+
+ // Test if enougth memory is available and allocate it for 7 values
+ //n = comedi_buf_write_alloc(s->async, 7*sizeof(unsigned int));
+ n = comedi_buf_write_alloc(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ // If not enougth memory available, event is set to Comedi Buffer Errror
+ if (n > ((7 + 12) * sizeof(unsigned int))) {
+ printk("\ncomedi_buf_write_alloc n = %i", n);
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ // Write all 7 scan values in the comedi buffer
+ comedi_buf_memcpy_to(s->async, 0,
+ (unsigned int *) s_BoardInfos[dev->minor].
+ ui_ScanValueArray, (7 + 12) * sizeof(unsigned int));
+
+ // Update comedi buffer pinters indexes
+ comedi_buf_write_free(s->async,
+ (7 + 12) * sizeof(unsigned int));
+
+ // Send events
+ comedi_event(dev, s);
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //BEGIN JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ //
+ //if (s->async->buf_int_ptr>=s->async->data_len) // for buffer rool over
+ // {
+ // /* buffer rollover */
+ // s->async->buf_int_ptr=0;
+ // comedi_eobuf(dev,s);
+ // }
+ //End JK 18.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ }
+ //i_Count++;
+ s_BoardInfos[dev->minor].i_Count++;
+ }
+ //i_InterruptFlag=0;
+ s_BoardInfos[dev->minor].i_InterruptFlag = 0;
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
new file mode 100644
index 00000000000..a6f57f55e79
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+// Card Specific information
+#define APCI3200_BOARD_VENDOR_ID 0x15B8
+//#define APCI3200_ADDRESS_RANGE 264
+
+int MODULE_NO;
+struct {
+ INT i_Gain;
+ INT i_Polarity;
+ INT i_OffsetRange;
+ INT i_Coupling;
+ INT i_SingleDiff;
+ INT i_AutoCalibration;
+ UINT ui_ReloadValue;
+ UINT ui_TimeUnitReloadVal;
+ INT i_Interrupt;
+ INT i_ModuleSelection;
+} Config_Parameters_Module1, Config_Parameters_Module2,
+ Config_Parameters_Module3, Config_Parameters_Module4;
+
+//ANALOG INPUT RANGE
+static const struct comedi_lrange range_apci3200_ai = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+static const struct comedi_lrange range_apci3300_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)
+ }
+};
+
+//Analog Input related Defines
+#define APCI3200_AI_OFFSET_GAIN 0
+#define APCI3200_AI_SC_TEST 4
+#define APCI3200_AI_IRQ 8
+#define APCI3200_AI_AUTOCAL 12
+#define APCI3200_RELOAD_CONV_TIME_VAL 32
+#define APCI3200_CONV_TIME_TIME_BASE 36
+#define APCI3200_RELOAD_DELAY_TIME_VAL 40
+#define APCI3200_DELAY_TIME_TIME_BASE 44
+#define APCI3200_AI_MODULE1 0
+#define APCI3200_AI_MODULE2 64
+#define APCI3200_AI_MODULE3 128
+#define APCI3200_AI_MODULE4 192
+#define TRUE 1
+#define FALSE 0
+#define APCI3200_AI_EOSIRQ 16
+#define APCI3200_AI_EOS 20
+#define APCI3200_AI_CHAN_ID 24
+#define APCI3200_AI_CHAN_VAL 28
+#define ANALOG_INPUT 0
+#define TEMPERATURE 1
+#define RESISTANCE 2
+
+#define ENABLE_EXT_TRIG 1
+#define ENABLE_EXT_GATE 2
+#define ENABLE_EXT_TRIG_GATE 3
+
+#define APCI3200_MAXVOLT 2.5
+#define ADDIDATA_GREATER_THAN_TEST 0
+#define ADDIDATA_LESS_THAN_TEST 1
+
+#define ADDIDATA_UNIPOLAR 1
+#define ADDIDATA_BIPOLAR 2
+
+//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+#define MAX_MODULE 4
+//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+typedef struct {
+ ULONG ul_NumberOfValue;
+ ULONG *pul_ResistanceValue;
+ ULONG *pul_TemperatureValue;
+} str_ADDIDATA_RTDStruct, *pstr_ADDIDATA_RTDStruct;
+
+//BEGIN JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+typedef struct {
+ // Begin JK 05/08/2003 change for Linux
+ unsigned long ul_CurrentSourceCJC;
+ unsigned long ul_CurrentSource[5];
+ // End JK 05/08/2003 change for Linux
+
+ // Begin CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
+ unsigned long ul_GainFactor[8]; // Gain Factor
+ unsigned int w_GainValue[10];
+ // End CG 15/02/02 Rev 1.0 -> Rev 1.1 : Add Header Type 1
+} str_Module;
+//END JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+
+//BEGIN JK 06.07.04: Management of sevrals boards
+typedef struct {
+ INT i_CJCAvailable;
+ INT i_CJCPolarity;
+ INT i_CJCGain;
+ INT i_InterruptFlag;
+ INT i_ADDIDATAPolarity;
+ INT i_ADDIDATAGain;
+ INT i_AutoCalibration;
+ INT i_ADDIDATAConversionTime;
+ INT i_ADDIDATAConversionTimeUnit;
+ INT i_ADDIDATAType;
+ INT i_ChannelNo;
+ INT i_ChannelCount;
+ INT i_ScanType;
+ INT i_FirstChannel;
+ INT i_LastChannel;
+ INT i_Sum;
+ INT i_Offset;
+ UINT ui_Channel_num;
+ INT i_Count;
+ INT i_Initialised;
+ //UINT ui_InterruptChannelValue[96]; //Buffer
+ UINT ui_InterruptChannelValue[144]; //Buffer
+ BYTE b_StructInitialized;
+ //Begin JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+ unsigned int ui_ScanValueArray[7 + 12]; // 7 is the maximal number of channels
+ //End JK 19.10.2004: APCI-3200 Driver update 0.7.57 -> 0.7.68
+
+ //Begin JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+ INT i_ConnectionType;
+ INT i_NbrOfModule;
+ str_Module s_Module[MAX_MODULE];
+ //End JK 21.10.2004: APCI-3200 / APCI-3300 Reading of EEPROM values
+} str_BoardInfos;
+//END JK 06.07.04: Management of sevrals boards
+
+// Hardware Layer functions for Apci3200
+
+//AI
+
+INT i_APCI3200_ConfigAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_ReadAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_InsnWriteReleaseAnalogInput(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_InsnBits_AnalogInput_Test(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3200_StopCyclicAcquisition(struct comedi_device *dev, struct comedi_subdevice *s);
+INT i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
+INT i_APCI3200_CommandTestAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+INT i_APCI3200_CommandAnalogInput(struct comedi_device *dev, struct comedi_subdevice *s);
+INT i_APCI3200_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+//Interrupt
+void v_APCI3200_Interrupt(int irq, void *d);
+int i_APCI3200_InterruptHandleEos(struct comedi_device *dev);
+//Reset functions
+INT i_APCI3200_Reset(struct comedi_device *dev);
+
+int i_APCI3200_ReadCJCCalOffset(struct comedi_device *dev, unsigned int *data);
+int i_APCI3200_ReadCJCValue(struct comedi_device *dev, unsigned int *data);
+int i_APCI3200_ReadCalibrationGainValue(struct comedi_device *dev, UINT *data);
+int i_APCI3200_ReadCalibrationOffsetValue(struct comedi_device *dev, UINT *data);
+int i_APCI3200_Read1AnalogInputChannel(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI3200_ReadCJCCalGain(struct comedi_device *dev, unsigned int *data);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
new file mode 100644
index 00000000000..20391a91da0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c
@@ -0,0 +1,742 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*.
+
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-------------------------------+---------------------------------------+
+ | Project : APCI-3501 | Compiler : GCC |
+ | Module name : hwdrv_apci3501.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: Eric Stolz | Date : 02/12/2002 |
+ +-------------------------------+---------------------------------------+
+ | Description : Hardware Layer Acces For APCI-3501 |
+ +-----------------------------------------------------------------------+
+ | UPDATES |
+ +----------+-----------+------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Included files |
++----------------------------------------------------------------------------+
+*/
+#include "hwdrv_apci3501.h"
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadDigitalInput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+INT i_APCI3501_ReadDigitalInput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->iobase + APCI3501_DIGITAL_IP);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } //if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+
+ *data = *data & 0x3;
+ } //if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } //elseif (ui_Temp==1)
+ } //elseif (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Digital Output Subdevice. |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[1] : 1 Enable VCC Interrupt |
+| 0 Disable VCC Interrupt |
+| data[2] : 1 Enable CC Interrupt |
+| 0 Disable CC Interrupt |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3501_ConfigDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ if ((data[0] != 0) && (data[0] != 1)) {
+ comedi_error(dev,
+ "Not a valid Data !!! ,Data should be 1 or 0\n");
+ return -EINVAL;
+ } //if ( (data[0]!=0) && (data[0]!=1) )
+ if (data[0]) {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE;
+ } // if (data[0])
+ else {
+ devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE;
+ } //else if (data[0])
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_WriteDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : writes To the digital Output Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp, ui_Temp1;
+ UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel
+ if (devpriv->b_OutputMemoryStatus) {
+ ui_Temp = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
+ } //if(devpriv->b_OutputMemoryStatus )
+ else {
+ ui_Temp = 0;
+ } //if(devpriv->b_OutputMemoryStatus )
+ if (data[3] == 0) {
+ if (data[1] == 0) {
+ data[0] = (data[0] << ui_NoOfChannel) | ui_Temp;
+ outl(data[0], devpriv->iobase + APCI3501_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ data[0] = (data[0] << (2 * data[2])) | ui_Temp;
+ outl(data[0],
+ devpriv->iobase + APCI3501_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==0)
+ else {
+ if (data[3] == 1) {
+ if (data[1] == 0) {
+ data[0] = ~data[0] & 0x1;
+ ui_Temp1 = 1;
+ ui_Temp1 = ui_Temp1 << ui_NoOfChannel;
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ (data[0] << ui_NoOfChannel) ^
+ 0xffffffff;
+ data[0] = data[0] & ui_Temp;
+ outl(data[0],
+ devpriv->iobase + APCI3501_DIGITAL_OP);
+ } //if(data[1]==0)
+ else {
+ if (data[1] == 1) {
+ data[0] = ~data[0] & 0x3;
+ ui_Temp1 = 3;
+ ui_Temp1 = ui_Temp1 << 2 * data[2];
+ ui_Temp = ui_Temp | ui_Temp1;
+ data[0] =
+ ((data[0] << (2 *
+ data[2])) ^
+ 0xffffffff) & ui_Temp;
+ outl(data[0],
+ devpriv->iobase +
+ APCI3501_DIGITAL_OP);
+ } // if(data[1]==1)
+ else {
+ printk("\nSpecified channel not supported\n");
+ } //else if(data[1]==1)
+ } //elseif(data[1]==0)
+ } //if(data[3]==1);
+ else {
+ printk("\nSpecified functionality does not exist\n");
+ return -EINVAL;
+ } //if else data[3]==1)
+ } //if else data[3]==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadDigitalOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read value of the selected channel or port |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT ui_NoOfChannels : No Of Channels To read |
+| UINT *data : Data Pointer to read status |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ReadDigitalOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ UINT ui_Temp;
+ UINT ui_NoOfChannel;
+
+ ui_NoOfChannel = CR_CHAN(insn->chanspec);
+ ui_Temp = data[0];
+ *data = inl(devpriv->iobase + APCI3501_DIGITAL_OP);
+ if (ui_Temp == 0) {
+ *data = (*data >> ui_NoOfChannel) & 0x1;
+ } // if (ui_Temp==0)
+ else {
+ if (ui_Temp == 1) {
+ *data = *data & 0x3;
+
+ } // if (ui_Temp==1)
+ else {
+ printk("\nSpecified channel not supported \n");
+ } // else if (ui_Temp==1)
+ } // else if (ui_Temp==0)
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigAnalogOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Analog Output Subdevice |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : Voltage Mode |
+| 0:Mode 0 |
+| 1:Mode 1 |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ outl(data[0],
+ devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_VOLT_MODE);
+
+ if (data[0]) {
+ devpriv->b_InterruptMode = MODE1;
+ } else {
+ devpriv->b_InterruptMode = MODE0;
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_WriteAnalogOutput |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Writes To the Selected Anlog Output Channel |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| struct comedi_subdevice *s : Subdevice Pointer |
+| struct comedi_insn *insn : Insn Structure Pointer |
+| unsigned int *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_WriteAnalogOutput(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;;
+
+ ul_Channel_no = CR_CHAN(insn->chanspec);
+
+ if (devpriv->b_InterruptMode == MODE1) {
+ ul_Polarity = 0x80000000;
+ if ((*data < 0) || (*data > 16384)) {
+ printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+ }
+
+ } // end if(devpriv->b_InterruptMode==MODE1)
+ else {
+ ul_Polarity = 0;
+ if ((*data < 0) || (*data > 8192)) {
+ printk("\nIn WriteAnalogOutput :: Not Valid Data\n");
+ }
+
+ } // end else
+
+ if ((ul_Channel_no < 0) || (ul_Channel_no > 7)) {
+ printk("\nIn WriteAnalogOutput :: Not Valid Channel\n");
+ } // end if((ul_Channel_no<0)||(ul_Channel_no>7))
+
+ ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+
+ while (ul_DAC_Ready == 0) {
+ ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+ ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
+ }
+
+ if (ul_DAC_Ready) {
+// Output the Value on the output channels.
+ ul_Command1 =
+ (ULONG) ((ULONG) (ul_Channel_no & 0xFF) |
+ (ULONG) ((*data << 0x8) & 0x7FFFFF00L) |
+ (ULONG) (ul_Polarity));
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_PROG);
+ }
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ConfigTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Configures The Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Configure As Timer |
+| 1 Configure As Counter |
+| 2 Configure As Watchdog |
+| data[1] : 1 Enable Interrupt |
+| 0 Disable Interrupt |
+| data[2] : Time Unit |
+| data[3] : Reload Value |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ devpriv->tsk_Current = current;
+ if (data[0] == ADDIDATA_WATCHDOG) {
+
+ devpriv->b_TimerSelectMode = ADDIDATA_WATCHDOG;
+ //Disable the watchdog
+ outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Wa
+
+ if (data[1] == 1) {
+ //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x02,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else {
+ outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
+ }
+
+ //Loading the Timebase value
+ outl(data[2],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_RELOAD_VALUE);
+ //Set the mode
+ ul_Command1 = inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG) | 0xFFF819E0UL; //e2->e0
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } //end if(data[0]==ADDIDATA_WATCHDOG)
+
+ else if (data[0] == ADDIDATA_TIMER) {
+ //First Stop The Timer
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //Stop The Timer
+ devpriv->b_TimerSelectMode = ADDIDATA_TIMER;
+ if (data[1] == 1) {
+ //Enable TIMER int & DISABLE ALL THE OTHER int SOURCES
+ outl(0x02,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else {
+ outl(0x0, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //disable Timer interrupt
+ }
+
+ // Loading Timebase
+ outl(data[2],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TIMEBASE);
+
+ //Loading the Reload value
+ outl(data[3],
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_RELOAD_VALUE);
+
+ // printk ("\nTimer Address :: %x\n", (devpriv->iobase+APCI3501_WATCHDOG));
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 =
+ (ul_Command1 & 0xFFF719E2UL) | 2UL << 13UL | 0x10UL;
+ outl(ul_Command1, devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG); //mode 2
+
+ } //end if(data[0]==ADDIDATA_TIMER)
+
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_StartStopWriteTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Start / Stop The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : 1 Start |
+| 0 Stop | 2 Trigger |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ ULONG ul_Command1 = 0;
+ int i_Temp;
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+
+ if (data[1] == 1) {
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+ //Enable the Watchdog
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ }
+
+ else if (data[1] == 0) //Stop The Watchdog
+ {
+ //Stop The Watchdog
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(0x0,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else if (data[1] == 2) {
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } //if(data[1]==2)
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+ if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ if (data[1] == 1) {
+
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x1UL;
+ //Enable the Timer
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ } else if (data[1] == 0) {
+ //Stop The Timer
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = ul_Command1 & 0xFFFFF9FEUL;
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ }
+
+ else if (data[1] == 2) {
+ //Trigger the Timer
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FFUL) | 0x200UL;
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_PROG);
+ }
+
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+ i_Temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_ReadTimerCounterWatchdog |
+| (struct comedi_device *dev,struct comedi_subdevice *s, |
+| struct comedi_insn *insn,unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read The Selected Timer , Counter or Watchdog |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev : Driver handle |
+| UINT *data : Data Pointer contains |
+| configuration parameters as below |
+| |
+| data[0] : 0 Timer |
+| 1 Counter |
+| 2 Watchdog | | data[1] : Timer Counter Watchdog Number |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ if (devpriv->b_TimerSelectMode == ADDIDATA_WATCHDOG) {
+ data[0] =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_WATCHDOG)
+
+ else if (devpriv->b_TimerSelectMode == ADDIDATA_TIMER) {
+ data[0] =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ data[1] = inl(devpriv->iobase + APCI3501_WATCHDOG);
+ } // end if (devpriv->b_TimerSelectMode==ADDIDATA_TIMER)
+
+ else if ((devpriv->b_TimerSelectMode != ADDIDATA_TIMER)
+ && (devpriv->b_TimerSelectMode != ADDIDATA_WATCHDOG)) {
+ printk("\nIn ReadTimerCounterWatchdog :: Invalid Subdevice \n");
+ }
+ return insn->n;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3501_Reset(struct comedi_device *dev) |
+| |
++----------------------------------------------------------------------------+
+| Task :Resets the registers of the card |
++----------------------------------------------------------------------------+
+| Input Parameters : |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : |
+| |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3501_Reset(struct comedi_device * dev)
+{
+ int i_Count = 0, i_temp = 0;
+ ULONG ul_Command1 = 0, ul_Polarity, ul_DAC_Ready = 0;
+ outl(0x0, devpriv->iobase + APCI3501_DIGITAL_OP);
+ outl(1, devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_VOLT_MODE);
+
+ ul_Polarity = 0x80000000;
+
+ for (i_Count = 0; i_Count <= 7; i_Count++) {
+ ul_DAC_Ready = inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+
+ while (ul_DAC_Ready == 0) {
+ ul_DAC_Ready =
+ inl(devpriv->iobase + APCI3501_ANALOG_OUTPUT);
+ ul_DAC_Ready = (ul_DAC_Ready >> 8) & 1;
+ }
+
+ if (ul_DAC_Ready) {
+ // Output the Value on the output channels.
+ ul_Command1 =
+ (ULONG) ((ULONG) (i_Count & 0xFF) |
+ (ULONG) ((i_temp << 0x8) & 0x7FFFFF00L) |
+ (ULONG) (ul_Polarity));
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_ANALOG_OUTPUT +
+ APCI3501_AO_PROG);
+ }
+ }
+
+ return 0;
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : static void v_APCI3501_Interrupt |
+| (int irq , void *d) |
++----------------------------------------------------------------------------+
+| Task : Interrupt processing Routine |
++----------------------------------------------------------------------------+
+| Input Parameters : int irq : irq number |
+| void *d : void pointer |
++----------------------------------------------------------------------------+
+| Output Parameters : -- |
++----------------------------------------------------------------------------+
+| Return Value : TRUE : No error occur |
+| : FALSE : Error occur. Return the error |
+| |
++----------------------------------------------------------------------------+
+*/
+void v_APCI3501_Interrupt(int irq, void *d)
+{
+ int i_temp;
+ struct comedi_device *dev = d;
+ unsigned int ui_Timer_AOWatchdog;
+ unsigned long ul_Command1;
+ // Disable Interrupt
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+
+ ul_Command1 = (ul_Command1 & 0xFFFFF9FDul);
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+
+ ui_Timer_AOWatchdog =
+ inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_IRQ) & 0x1;
+
+ if ((!ui_Timer_AOWatchdog)) {
+ comedi_error(dev, "IRQ from unknow source");
+ return;
+ }
+
+ // Enable Interrupt
+ //Send a signal to from kernel to user space
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ ul_Command1 =
+ inl(devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+ ul_Command1 = ((ul_Command1 & 0xFFFFF9FDul) | 1 << 1);
+ outl(ul_Command1,
+ devpriv->iobase + APCI3501_WATCHDOG + APCI3501_TCW_PROG);
+ i_temp = inl(devpriv->iobase + APCI3501_WATCHDOG +
+ APCI3501_TCW_TRIG_STATUS) & 0x1;
+ return;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
new file mode 100644
index 00000000000..51e7b66544a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+// Card Specific information
+#define APCI3501_BOARD_VENDOR_ID 0x15B8
+#define APCI3501_ADDRESS_RANGE 255
+
+#define APCI3501_DIGITAL_IP 0x50
+#define APCI3501_DIGITAL_OP 0x40
+#define APCI3501_ANALOG_OUTPUT 0x00
+
+//Analog Output related Defines
+#define APCI3501_AO_VOLT_MODE 0
+#define APCI3501_AO_PROG 4
+#define APCI3501_AO_TRIG_SCS 8
+#define UNIPOLAR 0
+#define BIPOLAR 1
+#define MODE0 0
+#define MODE1 1
+// ANALOG OUTPUT RANGE
+struct comedi_lrange range_apci3501_ao = { 2, {
+ BIP_RANGE(10),
+ UNI_RANGE(10)
+ }
+};
+
+//Watchdog Related Defines
+
+#define APCI3501_WATCHDOG 0x20
+#define APCI3501_TCW_SYNC_ENABLEDISABLE 0
+#define APCI3501_TCW_RELOAD_VALUE 4
+#define APCI3501_TCW_TIMEBASE 8
+#define APCI3501_TCW_PROG 12
+#define APCI3501_TCW_TRIG_STATUS 16
+#define APCI3501_TCW_IRQ 20
+#define APCI3501_TCW_WARN_TIMEVAL 24
+#define APCI3501_TCW_WARN_TIMEBASE 28
+#define ADDIDATA_TIMER 0
+#define ADDIDATA_WATCHDOG 2
+
+// Hardware Layer functions for Apci3501
+
+//AO
+INT i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DI
+// for di read
+//INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+
+INT i_APCI3501_ReadDigitalInput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+//DO
+int i_APCI3501_ConfigDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+INT i_APCI3501_ReadDigitalOutput(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+
+// TIMER
+// timer value is passed as u seconds
+INT i_APCI3501_ConfigTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+int i_APCI3501_StartStopWriteTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn,
+ unsigned int *data);
+int i_APCI3501_ReadTimerCounterWatchdog(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+//Interrupt
+void v_APCI3501_Interrupt(int irq, void *d);
+
+//Reset functions
+int i_APCI3501_Reset(struct comedi_device *dev);
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
new file mode 100644
index 00000000000..b7268e4da64
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.c
@@ -0,0 +1,1691 @@
+/**
+@verbatim
+
+Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+
+ ADDI-DATA GmbH
+ Dieselstrasse 3
+ D-77833 Ottersweier
+ Tel: +19(0)7223/9493-0
+ Fax: +49(0)7223/9493-92
+ http://www.addi-data-com
+ info@addi-data.com
+
+This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+You shoud also find the complete GPL in the COPYING file accompanying this source code.
+
+@endverbatim
+*/
+/*
+ +-----------------------------------------------------------------------+
+ | (C) ADDI-DATA GmbH Dieselstrasse 3 D-77833 Ottersweier |
+ +-----------------------------------------------------------------------+
+ | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
+ | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+ +-----------------------------------------------------------------------+
+ | Project : APCI-3XXX | Compiler : GCC |
+ | Module name : hwdrv_apci3xxx.c| Version : 2.96 |
+ +-------------------------------+---------------------------------------+
+ | Project manager: S. Weber | Date : 15/09/2005 |
+ +-----------------------------------------------------------------------+
+ | Description :APCI3XXX Module. Hardware abstraction Layer for APCI3XXX|
+ +-----------------------------------------------------------------------+
+ | UPDATE'S |
+ +-----------------------------------------------------------------------+
+ | Date | Author | Description of updates |
+ +----------+-----------+------------------------------------------------+
+ | | | |
+ | | | |
+ +----------+-----------+------------------------------------------------+
+*/
+
+#include "hwdrv_apci3xxx.h"
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_TestConversionStarted |
+| (struct comedi_device *dev) |
++----------------------------------------------------------------------------+
+| Task Test if any conversion started |
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 : Conversion not started |
+| 1 : Conversion started |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_TestConversionStarted(struct comedi_device * dev)
+{
+ if ((readl((void *)(devpriv->dw_AiBase + 8)) & 0x80000UL) == 0x80000UL) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_AnalogInputConfigOperatingMode |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Converting mode and convert time selection |
++----------------------------------------------------------------------------+
+| Input Parameters : b_SingleDiff = (BYTE) data[1]; |
+| b_TimeBase = (BYTE) data[2]; (0: ns, 1:micros 2:ms)|
+| dw_ReloadValue = (DWORD) data[3]; |
+| ........ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0 : No error |
+| -1 : Single/Diff selection error |
+| -2 : Convert time base unity selection error |
+| -3 : Convert time value selection error |
+| -10: Any conversion started |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_AnalogInputConfigOperatingMode(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_TimeBase = 0;
+ BYTE b_SingleDiff = 0;
+ DWORD dw_ReloadValue = 0;
+ DWORD dw_TestReloadValue = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n == 4) {
+ /****************************/
+ /* Get the Singel/Diff flag */
+ /****************************/
+
+ b_SingleDiff = (BYTE) data[1];
+
+ /****************************/
+ /* Get the time base unitiy */
+ /****************************/
+
+ b_TimeBase = (BYTE) data[2];
+
+ /*************************************/
+ /* Get the convert time reload value */
+ /*************************************/
+
+ dw_ReloadValue = (DWORD) data[3];
+
+ /**********************/
+ /* Test the time base */
+ /**********************/
+
+ if ((devpriv->ps_BoardInfo->
+ b_AvailableConvertUnit & (1 << b_TimeBase)) !=
+ 0) {
+ /*******************************/
+ /* Test the convert time value */
+ /*******************************/
+
+ if ((dw_ReloadValue >= 0) && (dw_ReloadValue <= 65535)) {
+ dw_TestReloadValue = dw_ReloadValue;
+
+ if (b_TimeBase == 1) {
+ dw_TestReloadValue =
+ dw_TestReloadValue * 1000UL;
+ }
+ if (b_TimeBase == 2) {
+ dw_TestReloadValue =
+ dw_TestReloadValue * 1000000UL;
+ }
+
+ /*******************************/
+ /* Test the convert time value */
+ /*******************************/
+
+ if (dw_TestReloadValue >=
+ devpriv->ps_BoardInfo->
+ ui_MinAcquisitiontimeNs) {
+ if ((b_SingleDiff == APCI3XXX_SINGLE)
+ || (b_SingleDiff ==
+ APCI3XXX_DIFF)) {
+ if (((b_SingleDiff == APCI3XXX_SINGLE) && (devpriv->ps_BoardInfo->i_NbrAiChannel == 0)) || ((b_SingleDiff == APCI3XXX_DIFF) && (devpriv->ps_BoardInfo->i_NbrAiChannelDiff == 0))) {
+ /*******************************/
+ /* Single/Diff selection error */
+ /*******************************/
+
+ printk("Single/Diff selection error\n");
+ i_ReturnValue = -1;
+ } else {
+ /**********************************/
+ /* Test if conversion not started */
+ /**********************************/
+
+ if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
+ devpriv->
+ ui_EocEosConversionTime
+ =
+ (UINT)
+ dw_ReloadValue;
+ devpriv->
+ b_EocEosConversionTimeBase
+ =
+ b_TimeBase;
+ devpriv->
+ b_SingelDiff
+ =
+ b_SingleDiff;
+ devpriv->
+ b_AiInitialisation
+ = 1;
+
+ /*******************************/
+ /* Set the convert timing unit */
+ /*******************************/
+
+ writel((DWORD)
+ b_TimeBase,
+ (void *)
+ (devpriv->
+ dw_AiBase
+ +
+ 36));
+
+ /**************************/
+ /* Set the convert timing */
+ /*************************/
+
+ writel(dw_ReloadValue, (void *)(devpriv->dw_AiBase + 32));
+ } else {
+ /**************************/
+ /* Any conversion started */
+ /**************************/
+
+ printk("Any conversion started\n");
+ i_ReturnValue =
+ -10;
+ }
+ }
+ } else {
+ /*******************************/
+ /* Single/Diff selection error */
+ /*******************************/
+
+ printk("Single/Diff selection error\n");
+ i_ReturnValue = -1;
+ }
+ } else {
+ /************************/
+ /* Time selection error */
+ /************************/
+
+ printk("Convert time value selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /************************/
+ /* Time selection error */
+ /************************/
+
+ printk("Convert time value selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*****************************/
+ /* Time base selection error */
+ /*****************************/
+
+ printk("Convert time base unity selection error\n");
+ i_ReturnValue = -2;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnConfigAnalogInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Converting mode and convert time selection |
++----------------------------------------------------------------------------+
+| Input Parameters : b_ConvertMode = (BYTE) data[0]; |
+| b_TimeBase = (BYTE) data[1]; (0: ns, 1:micros 2:ms)|
+| dw_ReloadValue = (DWORD) data[2]; |
+| ........ |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnConfigAnalogInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ switch ((BYTE) data[0]) {
+ case APCI3XXX_CONFIGURATION:
+ i_ReturnValue =
+ i_APCI3XXX_AnalogInputConfigOperatingMode(dev,
+ s, insn, data);
+ break;
+
+ default:
+ i_ReturnValue = -100;
+ printk("Config command error %d\n", data[0]);
+ break;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnReadAnalogInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Read 1 analog input |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
+| b_Channel = CR_CHAN(insn->chanspec); |
+| dw_NbrOfAcquisition = insn->n; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -3 : Channel selection error |
+| -4 : Configuration selelection error |
+| -10: Any conversion started |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadAnalogInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Configuration = (BYTE) CR_RANGE(insn->chanspec);
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ DWORD dw_Temp = 0;
+ DWORD dw_Configuration = 0;
+ DWORD dw_AcquisitionCpt = 0;
+ BYTE b_Interrupt = 0;
+
+ /*************************************/
+ /* Test if operating mode configured */
+ /*************************************/
+
+ if (devpriv->b_AiInitialisation) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (((b_Channel < devpriv->ps_BoardInfo->i_NbrAiChannel)
+ && (devpriv->b_SingelDiff == APCI3XXX_SINGLE))
+ || ((b_Channel < devpriv->ps_BoardInfo->
+ i_NbrAiChannelDiff)
+ && (devpriv->b_SingelDiff == APCI3XXX_DIFF))) {
+ /**********************************/
+ /* Test the channel configuration */
+ /**********************************/
+
+ if (b_Configuration > 7) {
+ /***************************/
+ /* Channel not initialised */
+ /***************************/
+
+ i_ReturnValue = -4;
+ printk("Channel %d range %d selection error\n",
+ b_Channel, b_Configuration);
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n", b_Channel);
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if ((b_Interrupt != 0) || ((b_Interrupt == 0)
+ && (insn->n >= 1))) {
+ /**********************************/
+ /* Test if conversion not started */
+ /**********************************/
+
+ if (i_APCI3XXX_TestConversionStarted(dev) == 0) {
+ /******************/
+ /* Clear the FIFO */
+ /******************/
+
+ writel(0x10000UL,
+ (void *)(devpriv->dw_AiBase +
+ 12));
+
+ /*******************************/
+ /* Get and save the delay mode */
+ /*******************************/
+
+ dw_Temp =
+ readl((void *)(devpriv->
+ dw_AiBase + 4));
+ dw_Temp = dw_Temp & 0xFFFFFEF0UL;
+
+ /***********************************/
+ /* Channel configuration selection */
+ /***********************************/
+
+ writel(dw_Temp,
+ (void *)(devpriv->dw_AiBase +
+ 4));
+
+ /**************************/
+ /* Make the configuration */
+ /**************************/
+
+ dw_Configuration =
+ (b_Configuration & 3) |
+ ((DWORD) (b_Configuration >> 2)
+ << 6) | ((DWORD) devpriv->
+ b_SingelDiff << 7);
+
+ /***************************/
+ /* Write the configuration */
+ /***************************/
+
+ writel(dw_Configuration,
+ (void *)(devpriv->dw_AiBase +
+ 0));
+
+ /*********************/
+ /* Channel selection */
+ /*********************/
+
+ writel(dw_Temp | 0x100UL,
+ (void *)(devpriv->dw_AiBase +
+ 4));
+ writel((DWORD) b_Channel,
+ (void *)(devpriv->dw_AiBase +
+ 0));
+
+ /***********************/
+ /* Restaure delay mode */
+ /***********************/
+
+ writel(dw_Temp,
+ (void *)(devpriv->dw_AiBase +
+ 4));
+
+ /***********************************/
+ /* Set the number of sequence to 1 */
+ /***********************************/
+
+ writel(1,
+ (void *)(devpriv->dw_AiBase +
+ 48));
+
+ /***************************/
+ /* Save the interrupt flag */
+ /***************************/
+
+ devpriv->b_EocEosInterrupt =
+ b_Interrupt;
+
+ /*******************************/
+ /* Save the number of channels */
+ /*******************************/
+
+ devpriv->ui_AiNbrofChannels = 1;
+
+ /******************************/
+ /* Test if interrupt not used */
+ /******************************/
+
+ if (b_Interrupt == 0) {
+ for (dw_AcquisitionCpt = 0;
+ dw_AcquisitionCpt <
+ insn->n;
+ dw_AcquisitionCpt++) {
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ writel(0x80000UL,
+ (void *)
+ (devpriv->
+ dw_AiBase
+ + 8));
+
+ /****************/
+ /* Wait the EOS */
+ /****************/
+
+ do {
+ dw_Temp =
+ readl(
+ (void *)
+ (devpriv->
+ dw_AiBase
+ +
+ 20));
+ dw_Temp =
+ dw_Temp
+ & 1;
+ }
+ while (dw_Temp != 1);
+
+ /*************************/
+ /* Read the analog value */
+ /*************************/
+
+ data[dw_AcquisitionCpt]
+ =
+ (unsigned int)
+ readl((void
+ *)
+ (devpriv->
+ dw_AiBase
+ + 28));
+ }
+ } else {
+ /************************/
+ /* Start the conversion */
+ /************************/
+
+ writel(0x180000UL,
+ (void *)(devpriv->
+ dw_AiBase + 8));
+ }
+ } else {
+ /**************************/
+ /* Any conversion started */
+ /**************************/
+
+ printk("Any conversion started\n");
+ i_ReturnValue = -10;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Operating mode not configured\n");
+ i_ReturnValue = -1;
+ }
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name : void v_APCI3XXX_Interrupt (int irq, |
+| void *d) |
++----------------------------------------------------------------------------+
+| Task :Interrupt handler for APCI3XXX |
+| When interrupt occurs this gets called. |
+| First it finds which interrupt has been generated and |
+| handles corresponding interrupt |
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : - |
++----------------------------------------------------------------------------+
+*/
+
+void v_APCI3XXX_Interrupt(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ BYTE b_CopyCpt = 0;
+ DWORD dw_Status = 0;
+
+ /***************************/
+ /* Test if interrupt occur */
+ /***************************/
+
+ if (((dw_Status = readl((void *)(devpriv->dw_AiBase + 16))) & 0x2UL) ==
+ 0x2UL) {
+ /***********************/
+ /* Reset the interrupt */
+ /***********************/
+
+ writel(dw_Status, (void *)(devpriv->dw_AiBase + 16));
+
+ /*****************************/
+ /* Test if interrupt enabled */
+ /*****************************/
+
+ if (devpriv->b_EocEosInterrupt == 1) {
+ /********************************/
+ /* Read all analog inputs value */
+ /********************************/
+
+ for (b_CopyCpt = 0;
+ b_CopyCpt < devpriv->ui_AiNbrofChannels;
+ b_CopyCpt++) {
+ devpriv->ui_AiReadData[b_CopyCpt] =
+ (UINT) readl((void *)(devpriv->
+ dw_AiBase + 28));
+ }
+
+ /**************************/
+ /* Set the interrupt flag */
+ /**************************/
+
+ devpriv->b_EocEosInterrupt = 2;
+
+ /**********************************************/
+ /* Send a signal to from kernel to user space */
+ /**********************************************/
+
+ send_sig(SIGIO, devpriv->tsk_Current, 0);
+ }
+ }
+}
+
+/*
++----------------------------------------------------------------------------+
+| ANALOG OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnWriteAnalogOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task Read 1 analog input |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Range = CR_RANGE(insn->chanspec); |
+| b_Channel = CR_CHAN(insn->chanspec); |
+| data[0] = analog value; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -3 : Channel selection error |
+| -4 : Configuration selelection error |
+| .... |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteAnalogOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Range = (BYTE) CR_RANGE(insn->chanspec);
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ DWORD dw_Status = 0;
+ INT i_ReturnValue = insn->n;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel < devpriv->ps_BoardInfo->i_NbrAoChannel) {
+ /**********************************/
+ /* Test the channel configuration */
+ /**********************************/
+
+ if (b_Range < 2) {
+ /***************************/
+ /* Set the range selection */
+ /***************************/
+
+ writel(b_Range,
+ (void *)(devpriv->dw_AiBase + 96));
+
+ /**************************************************/
+ /* Write the analog value to the selected channel */
+ /**************************************************/
+
+ writel((data[0] << 8) | b_Channel,
+ (void *)(devpriv->dw_AiBase + 100));
+
+ /****************************/
+ /* Wait the end of transfer */
+ /****************************/
+
+ do {
+ dw_Status =
+ readl((void *)(devpriv->
+ dw_AiBase + 96));
+ }
+ while ((dw_Status & 0x100) != 0x100);
+ } else {
+ /***************************/
+ /* Channel not initialised */
+ /***************************/
+
+ i_ReturnValue = -4;
+ printk("Channel %d range %d selection error\n",
+ b_Channel, b_Range);
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n", b_Channel);
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| TTL FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnConfigInitTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task You must calling this function be |
+| for you call any other function witch access of TTL. |
+| APCI3XXX_TTL_INIT_DIRECTION_PORT2(user inputs for direction)|
++----------------------------------------------------------------------------+
+| Input Parameters : b_InitType = (BYTE) data[0]; |
+| b_Port2Mode = (BYTE) data[1]; |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| -1: Port 2 mode selection is wrong |
+| .... |
+| -100 : Config command error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnConfigInitTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Command = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /*******************/
+ /* Get the command */
+ /* **************** */
+
+ b_Command = (BYTE) data[0];
+
+ /********************/
+ /* Test the command */
+ /********************/
+
+ if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
+ /***************************************/
+ /* Test the initialisation buffer size */
+ /***************************************/
+
+ if ((b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)
+ && (insn->n != 2)) {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("Command selection error\n");
+ i_ReturnValue = -100;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ /*********************************************************************************/
+ /* Test if no error occur and APCI3XXX_TTL_INIT_DIRECTION_PORT2 command selected */
+ /*********************************************************************************/
+
+ if ((i_ReturnValue >= 0)
+ && (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2)) {
+ /**********************/
+ /* Test the direction */
+ /**********************/
+
+ if ((data[1] == 0) || (data[1] == 0xFF)) {
+ /**************************/
+ /* Save the configuration */
+ /**************************/
+
+ devpriv->ul_TTLPortConfiguration[0] =
+ devpriv->ul_TTLPortConfiguration[0] | data[1];
+ } else {
+ /************************/
+ /* Port direction error */
+ /************************/
+
+ printk("Port 2 direction selection error\n");
+ i_ReturnValue = -1;
+ }
+ }
+
+ /**************************/
+ /* Test if no error occur */
+ /**************************/
+
+ if (i_ReturnValue >= 0) {
+ /***********************************/
+ /* Test if TTL port initilaisation */
+ /***********************************/
+
+ if (b_Command == APCI3XXX_TTL_INIT_DIRECTION_PORT2) {
+ /*************************/
+ /* Set the configuration */
+ /*************************/
+
+ outl(data[1], devpriv->iobase + 224);
+ }
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| TTL INPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnBitsTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Write the selected output mask and read the status from|
+| all TTL channles |
++----------------------------------------------------------------------------+
+| Input Parameters : dw_ChannelMask = data [0]; |
+| dw_BitMask = data [1]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[1] : All TTL channles states |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -4 : Channel mask error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnBitsTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_ChannelCpt = 0;
+ DWORD dw_ChannelMask = 0;
+ DWORD dw_BitMask = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 2) {
+ /*******************************/
+ /* Get the channe and bit mask */
+ /*******************************/
+
+ dw_ChannelMask = data[0];
+ dw_BitMask = data[1];
+
+ /*************************/
+ /* Test the channel mask */
+ /*************************/
+
+ if (((dw_ChannelMask & 0XFF00FF00) == 0) &&
+ (((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0xFF)
+ || (((devpriv->ul_TTLPortConfiguration[0] &
+ 0xFF) == 0)
+ && ((dw_ChannelMask & 0XFF0000) ==
+ 0)))) {
+ /*********************************/
+ /* Test if set/reset any channel */
+ /*********************************/
+
+ if (dw_ChannelMask) {
+ /****************************************/
+ /* Test if set/rest any port 0 channels */
+ /****************************************/
+
+ if (dw_ChannelMask & 0xFF) {
+ /*******************************************/
+ /* Read port 0 (first digital output port) */
+ /*******************************************/
+
+ dw_Status = inl(devpriv->iobase + 80);
+
+ for (b_ChannelCpt = 0; b_ChannelCpt < 8;
+ b_ChannelCpt++) {
+ if ((dw_ChannelMask >>
+ b_ChannelCpt) &
+ 1) {
+ dw_Status =
+ (dw_Status &
+ (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+ }
+ }
+
+ outl(dw_Status, devpriv->iobase + 80);
+ }
+
+ /****************************************/
+ /* Test if set/rest any port 2 channels */
+ /****************************************/
+
+ if (dw_ChannelMask & 0xFF0000) {
+ dw_BitMask = dw_BitMask >> 16;
+ dw_ChannelMask = dw_ChannelMask >> 16;
+
+ /********************************************/
+ /* Read port 2 (second digital output port) */
+ /********************************************/
+
+ dw_Status = inl(devpriv->iobase + 112);
+
+ for (b_ChannelCpt = 0; b_ChannelCpt < 8;
+ b_ChannelCpt++) {
+ if ((dw_ChannelMask >>
+ b_ChannelCpt) &
+ 1) {
+ dw_Status =
+ (dw_Status &
+ (0xFF - (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+ }
+ }
+
+ outl(dw_Status, devpriv->iobase + 112);
+ }
+ }
+
+ /*******************************************/
+ /* Read port 0 (first digital output port) */
+ /*******************************************/
+
+ data[1] = inl(devpriv->iobase + 80);
+
+ /******************************************/
+ /* Read port 1 (first digital input port) */
+ /******************************************/
+
+ data[1] = data[1] | (inl(devpriv->iobase + 64) << 8);
+
+ /************************/
+ /* Test if port 2 input */
+ /************************/
+
+ if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF) == 0) {
+ data[1] =
+ data[1] | (inl(devpriv->iobase +
+ 96) << 16);
+ } else {
+ data[1] =
+ data[1] | (inl(devpriv->iobase +
+ 112) << 16);
+ }
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("Channel mask error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnReadTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the status from selected channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Selected TTL channel state |
++----------------------------------------------------------------------------+
+| Return Value : 0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ INT i_ReturnValue = insn->n;
+ unsigned int *pls_ReadData = data;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***********************/
+ /* Test if read port 0 */
+ /***********************/
+
+ if (b_Channel < 8) {
+ /*******************************************/
+ /* Read port 0 (first digital output port) */
+ /*******************************************/
+
+ pls_ReadData[0] = inl(devpriv->iobase + 80);
+ pls_ReadData[0] = (pls_ReadData[0] >> b_Channel) & 1;
+ } else {
+ /***********************/
+ /* Test if read port 1 */
+ /***********************/
+
+ if ((b_Channel > 7) && (b_Channel < 16)) {
+ /******************************************/
+ /* Read port 1 (first digital input port) */
+ /******************************************/
+
+ pls_ReadData[0] = inl(devpriv->iobase + 64);
+ pls_ReadData[0] =
+ (pls_ReadData[0] >> (b_Channel -
+ 8)) & 1;
+ } else {
+ /***********************/
+ /* Test if read port 2 */
+ /***********************/
+
+ if ((b_Channel > 15) && (b_Channel < 24)) {
+ /************************/
+ /* Test if port 2 input */
+ /************************/
+
+ if ((devpriv->ul_TTLPortConfiguration[0]
+ & 0xFF) == 0) {
+ pls_ReadData[0] =
+ inl(devpriv->iobase +
+ 96);
+ pls_ReadData[0] =
+ (pls_ReadData[0] >>
+ (b_Channel - 16)) & 1;
+ } else {
+ pls_ReadData[0] =
+ inl(devpriv->iobase +
+ 112);
+ pls_ReadData[0] =
+ (pls_ReadData[0] >>
+ (b_Channel - 16)) & 1;
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n",
+ b_Channel);
+ }
+ }
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| TTL OUTPUT FUNCTIONS |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : INT i_APCI3XXX_InsnWriteTTLIO |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set the state from TTL output channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
+| b_State = data [0] |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : 0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteTTLIO(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ BYTE b_State = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ b_State = (BYTE) data[0];
+
+ /***********************/
+ /* Test if read port 0 */
+ /***********************/
+
+ if (b_Channel < 8) {
+ /*****************************************************************************/
+ /* Read port 0 (first digital output port) and set/reset the selcted channel */
+ /*****************************************************************************/
+
+ dw_Status = inl(devpriv->iobase + 80);
+ dw_Status =
+ (dw_Status & (0xFF -
+ (1 << b_Channel))) | ((b_State & 1) <<
+ b_Channel);
+ outl(dw_Status, devpriv->iobase + 80);
+ } else {
+ /***********************/
+ /* Test if read port 2 */
+ /***********************/
+
+ if ((b_Channel > 15) && (b_Channel < 24)) {
+ /*************************/
+ /* Test if port 2 output */
+ /*************************/
+
+ if ((devpriv->ul_TTLPortConfiguration[0] & 0xFF)
+ == 0xFF) {
+ /*****************************************************************************/
+ /* Read port 2 (first digital output port) and set/reset the selcted channel */
+ /*****************************************************************************/
+
+ dw_Status = inl(devpriv->iobase + 112);
+ dw_Status =
+ (dw_Status & (0xFF -
+ (1 << (b_Channel -
+ 16)))) |
+ ((b_State & 1) << (b_Channel -
+ 16));
+ outl(dw_Status, devpriv->iobase + 112);
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n",
+ b_Channel);
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ i_ReturnValue = -3;
+ printk("Channel %d selection error\n",
+ b_Channel);
+ }
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL INPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnReadDigitalInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the specified Digital input channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) (0 to 3) |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Channel value |
++----------------------------------------------------------------------------+
+| Return Value : 0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadDigitalInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = (BYTE) CR_CHAN(insn->chanspec);
+ DWORD dw_Temp = 0;
+
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel <= devpriv->ps_BoardInfo->i_NbrDiChannel) {
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ dw_Temp = inl(devpriv->iobase + 32);
+ *data = (dw_Temp >> b_Channel) & 1;
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Channel selection error\n");
+ i_ReturnValue = -3;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnBitsDigitalInput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Reads the value of the Digital input Port i.e.4channels|
++----------------------------------------------------------------------------+
+| Input Parameters : - |
++----------------------------------------------------------------------------+
+| Output Parameters : data[0] : Port value |
++----------------------------------------------------------------------------+
+| Return Value :>0: No error |
+| .... |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3XXX_InsnBitsDigitalInput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ DWORD dw_Temp = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ dw_Temp = inl(devpriv->iobase + 32);
+ *data = dw_Temp & 0xf;
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| DIGITAL OUTPUT SUBDEVICE |
++----------------------------------------------------------------------------+
+
+*/
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnBitsDigitalOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Write the selected output mask and read the status from|
+| all digital output channles |
++----------------------------------------------------------------------------+
+| Input Parameters : dw_ChannelMask = data [0]; |
+| dw_BitMask = data [1]; |
++----------------------------------------------------------------------------+
+| Output Parameters : data[1] : All digital output channles states |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -4 : Channel mask error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+int i_APCI3XXX_InsnBitsDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_ChannelCpt = 0;
+ DWORD dw_ChannelMask = 0;
+ DWORD dw_BitMask = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 2) {
+ /*******************************/
+ /* Get the channe and bit mask */
+ /*******************************/
+
+ dw_ChannelMask = data[0];
+ dw_BitMask = data[1];
+
+ /*************************/
+ /* Test the channel mask */
+ /*************************/
+
+ if ((dw_ChannelMask & 0XFFFFFFF0) == 0) {
+ /*********************************/
+ /* Test if set/reset any channel */
+ /*********************************/
+
+ if (dw_ChannelMask & 0xF) {
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ dw_Status = inl(devpriv->iobase + 48);
+
+ for (b_ChannelCpt = 0; b_ChannelCpt < 4;
+ b_ChannelCpt++) {
+ if ((dw_ChannelMask >> b_ChannelCpt) &
+ 1) {
+ dw_Status =
+ (dw_Status & (0xF -
+ (1 << b_ChannelCpt))) | (dw_BitMask & (1 << b_ChannelCpt));
+ }
+ }
+
+ outl(dw_Status, devpriv->iobase + 48);
+ }
+
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ data[1] = inl(devpriv->iobase + 48);
+ } else {
+ /************************/
+ /* Config command error */
+ /************************/
+
+ printk("Channel mask error\n");
+ i_ReturnValue = -4;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnWriteDigitalOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Set the state from digital output channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
+| b_State = data [0] |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnWriteDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = CR_CHAN(insn->chanspec);
+ BYTE b_State = 0;
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+ /*******************/
+ /* Get the command */
+ /*******************/
+
+ b_State = (BYTE) data[0];
+
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ dw_Status = inl(devpriv->iobase + 48);
+
+ dw_Status =
+ (dw_Status & (0xF -
+ (1 << b_Channel))) | ((b_State & 1) <<
+ b_Channel);
+ outl(dw_Status, devpriv->iobase + 48);
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Channel selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function name :int i_APCI3XXX_InsnReadDigitalOutput |
+| (struct comedi_device *dev, |
+| struct comedi_subdevice *s, |
+| struct comedi_insn *insn, |
+| unsigned int *data) |
++----------------------------------------------------------------------------+
+| Task : Read the state from digital output channel |
++----------------------------------------------------------------------------+
+| Input Parameters : b_Channel = CR_CHAN(insn->chanspec) |
++----------------------------------------------------------------------------+
+| Output Parameters : b_State = data [0] |
++----------------------------------------------------------------------------+
+| Return Value : >0 : No error |
+| -3 : Channel selection error |
+| -101 : Data size error |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_InsnReadDigitalOutput(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ INT i_ReturnValue = insn->n;
+ BYTE b_Channel = CR_CHAN(insn->chanspec);
+ DWORD dw_Status = 0;
+
+ /************************/
+ /* Test the buffer size */
+ /************************/
+
+ if (insn->n >= 1) {
+ /***************************/
+ /* Test the channel number */
+ /***************************/
+
+ if (b_Channel < devpriv->ps_BoardInfo->i_NbrDoChannel) {
+ /********************************/
+ /* Read the digital output port */
+ /********************************/
+
+ dw_Status = inl(devpriv->iobase + 48);
+
+ dw_Status = (dw_Status >> b_Channel) & 1;
+ *data = dw_Status;
+ } else {
+ /***************************/
+ /* Channel selection error */
+ /***************************/
+
+ printk("Channel selection error\n");
+ i_ReturnValue = -3;
+ }
+ } else {
+ /*******************/
+ /* Data size error */
+ /*******************/
+
+ printk("Buffer size error\n");
+ i_ReturnValue = -101;
+ }
+
+ return (i_ReturnValue);
+}
+
+/*
++----------------------------------------------------------------------------+
+| Function Name : int i_APCI3XXX_Reset(struct comedi_device *dev) | +----------------------------------------------------------------------------+
+| Task :resets all the registers |
++----------------------------------------------------------------------------+
+| Input Parameters : struct comedi_device *dev |
++----------------------------------------------------------------------------+
+| Output Parameters : - |
++----------------------------------------------------------------------------+
+| Return Value : - |
++----------------------------------------------------------------------------+
+*/
+
+int i_APCI3XXX_Reset(struct comedi_device * dev)
+{
+ unsigned char b_Cpt = 0;
+
+ /*************************/
+ /* Disable the interrupt */
+ /*************************/
+
+ disable_irq(dev->irq);
+
+ /****************************/
+ /* Reset the interrupt flag */
+ /****************************/
+
+ devpriv->b_EocEosInterrupt = 0;
+
+ /***************************/
+ /* Clear the start command */
+ /***************************/
+
+ writel(0, (void *)(devpriv->dw_AiBase + 8));
+
+ /*****************************/
+ /* Reset the interrupt flags */
+ /*****************************/
+
+ writel(readl((void *)(devpriv->dw_AiBase + 16)),
+ (void *)(devpriv->dw_AiBase + 16));
+
+ /*****************/
+ /* clear the EOS */
+ /*****************/
+
+ readl((void *)(devpriv->dw_AiBase + 20));
+
+ /******************/
+ /* Clear the FIFO */
+ /******************/
+
+ for (b_Cpt = 0; b_Cpt < 16; b_Cpt++) {
+ readl((void *)(devpriv->dw_AiBase + 28));
+ }
+
+ /************************/
+ /* Enable the interrupt */
+ /************************/
+
+ enable_irq(dev->irq);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
new file mode 100644
index 00000000000..788d7c1cf5c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3xxx.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
+ *
+ * ADDI-DATA GmbH
+ * Dieselstrasse 3
+ * D-77833 Ottersweier
+ * Tel: +19(0)7223/9493-0
+ * Fax: +49(0)7223/9493-92
+ * http://www.addi-data-com
+ * info@addi-data.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#ifndef COMEDI_SUBD_TTLIO
+#define COMEDI_SUBD_TTLIO 11 /* Digital Input Output But TTL */
+#endif
+
+#ifndef ADDIDATA_ENABLE
+#define ADDIDATA_ENABLE 1
+#define ADDIDATA_DISABLE 0
+#endif
+
+#define APCI3XXX_SINGLE 0
+#define APCI3XXX_DIFF 1
+#define APCI3XXX_CONFIGURATION 0
+
+#define APCI3XXX_TTL_INIT_DIRECTION_PORT2 0
+
+#ifdef __KERNEL__
+
+static const struct comedi_lrange range_apci3XXX_ai = { 8, {BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1)}
+};
+
+static const struct comedi_lrange range_apci3XXX_ttl = { 12, {BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1),
+ BIP_RANGE(1)}
+};
+
+static const struct comedi_lrange range_apci3XXX_ao = { 2, {BIP_RANGE(10),
+ UNI_RANGE(10)}
+};
+#endif
diff --git a/drivers/staging/comedi/drivers/addi_apci_035.c b/drivers/staging/comedi/drivers/addi_apci_035.c
new file mode 100644
index 00000000000..bac018202fe
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_035.c
@@ -0,0 +1,5 @@
+#define CONFIG_APCI_035 1
+
+#define ADDIDATA_WATCHDOG 2 // Or shold it be something else
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1032.c b/drivers/staging/comedi/drivers/addi_apci_1032.c
new file mode 100644
index 00000000000..fa2056e8aa0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1032.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1032 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1500.c b/drivers/staging/comedi/drivers/addi_apci_1500.c
new file mode 100644
index 00000000000..7a5cae599ef
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1500.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1500 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1516.c b/drivers/staging/comedi/drivers/addi_apci_1516.c
new file mode 100644
index 00000000000..8d414844009
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1516.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1516 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1564.c b/drivers/staging/comedi/drivers/addi_apci_1564.c
new file mode 100644
index 00000000000..0351cdde102
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1564.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1564 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_16xx.c b/drivers/staging/comedi/drivers/addi_apci_16xx.c
new file mode 100644
index 00000000000..50679904129
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_16xx.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_16XX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_1710.c b/drivers/staging/comedi/drivers/addi_apci_1710.c
new file mode 100644
index 00000000000..c433445913d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_1710.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_1710 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2016.c b/drivers/staging/comedi/drivers/addi_apci_2016.c
new file mode 100644
index 00000000000..271c47c8cad
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2016.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2016 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2032.c b/drivers/staging/comedi/drivers/addi_apci_2032.c
new file mode 100644
index 00000000000..5108ea2a392
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2032.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2032 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_2200.c b/drivers/staging/comedi/drivers/addi_apci_2200.c
new file mode 100644
index 00000000000..e439f835cf4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_2200.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_2200 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3001.c b/drivers/staging/comedi/drivers/addi_apci_3001.c
new file mode 100644
index 00000000000..df97c305828
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3001.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3001 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3120.c b/drivers/staging/comedi/drivers/addi_apci_3120.c
new file mode 100644
index 00000000000..9183125ddde
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3120.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3120 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3200.c b/drivers/staging/comedi/drivers/addi_apci_3200.c
new file mode 100644
index 00000000000..f25a70b3290
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3200.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3200 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3300.c b/drivers/staging/comedi/drivers/addi_apci_3300.c
new file mode 100644
index 00000000000..1ee4778ad45
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3300.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3300 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3501.c b/drivers/staging/comedi/drivers/addi_apci_3501.c
new file mode 100644
index 00000000000..1049e20237e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3501.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3501 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_3xxx.c b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
new file mode 100644
index 00000000000..fb9deb7083b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_3xxx.c
@@ -0,0 +1,3 @@
+#define CONFIG_APCI_3XXX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/addi_apci_all.c b/drivers/staging/comedi/drivers/addi_apci_all.c
new file mode 100644
index 00000000000..aeb1b2688f3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/addi_apci_all.c
@@ -0,0 +1,18 @@
+#define CONFIG_APCI_035 1
+#define CONFIG_APCI_1032 1
+#define CONFIG_APCI_1500 1
+#define CONFIG_APCI_1516 1
+#define CONFIG_APCI_1564 1
+#define CONFIG_APCI_16XX 1
+#define CONFIG_APCI_1710 1
+#define CONFIG_APCI_2016 1
+#define CONFIG_APCI_2032 1
+#define CONFIG_APCI_2200 1
+#define CONFIG_APCI_3001 1
+#define CONFIG_APCI_3120 1
+#define CONFIG_APCI_3200 1
+#define CONFIG_APCI_3300 1
+#define CONFIG_APCI_3501 1
+#define CONFIG_APCI_3XXX 1
+
+#include "addi-data/addi_common.c"
diff --git a/drivers/staging/comedi/drivers/adl_pci6208.c b/drivers/staging/comedi/drivers/adl_pci6208.c
new file mode 100644
index 00000000000..f710f551820
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci6208.c
@@ -0,0 +1,391 @@
+/*
+ comedi/drivers/adl_pci6208.c
+
+ Hardware driver for ADLink 6208 series cards:
+ card | voltage output | current output
+ -------------+-------------------+---------------
+ PCI-6208V | 8 channels | -
+ PCI-6216V | 16 channels | -
+ PCI-6208A | 8 channels | 8 channels
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: adl_pci6208
+Description: ADLink PCI-6208A
+Devices: [ADLink] PCI-6208A (adl_pci6208)
+Author: nsyeow <nsyeow@pd.jaring.my>
+Updated: Fri, 30 Jan 2004 14:44:27 +0800
+Status: untested
+
+Configuration Options:
+ none
+
+References:
+ - ni_660x.c
+ - adl_pci9111.c copied the entire pci setup section
+ - adl_pci9118.c
+*/
+/*
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver. The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+#include "../comedidev.h"
+#include "comedi_pci.h"
+
+#define PCI6208_DRIVER_NAME "adl_pci6208"
+
+/* Board descriptions */
+struct pci6208_board {
+ const char *name;
+ unsigned short dev_id; /* `lspci` will show you this */
+ int ao_chans;
+ //int ao_bits;
+};
+
+static const struct pci6208_board pci6208_boards[] = {
+ /*{
+ name : "pci6208v",
+ dev_id : 0x6208, //not sure
+ ao_chans: 8
+ //, ao_bits : 16
+ },
+ {
+ name : "pci6216v",
+ dev_id : 0x6208, //not sure
+ ao_chans: 16
+ //, ao_bits : 16
+ }, */
+ {
+ name: "pci6208a",
+ dev_id: 0x6208,
+ ao_chans:8
+ //, ao_bits : 16
+ }
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(pci6208_pci_table) = {
+ //{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ //{ PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ {PCI_VENDOR_ID_ADLINK, 0x6208, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci6208_pci_table);
+
+/* Will be initialized in pci6208_find device(). */
+#define thisboard ((const struct pci6208_board *)dev->board_ptr)
+
+struct pci6208_private {
+ int data;
+ struct pci_dev *pci_dev; /* for a PCI device */
+ unsigned int ao_readback[2]; /* Used for AO readback */
+};
+
+#define devpriv ((struct pci6208_private *)dev->private)
+
+static int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci6208_detach(struct comedi_device * dev);
+
+#define pci6208_board_nbr \
+ (sizeof(pci6208_boards) / sizeof(struct pci6208_board))
+
+static struct comedi_driver driver_pci6208 = {
+ driver_name:PCI6208_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pci6208_attach,
+ detach:pci6208_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pci6208, pci6208_pci_table);
+
+static int pci6208_find_device(struct comedi_device * dev, int bus, int slot);
+static int
+pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
+ int dev_minor);
+
+/*read/write functions*/
+static int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data);
+//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci6208_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int retval;
+ unsigned long io_base;
+
+ printk("comedi%d: pci6208: ", dev->minor);
+
+ retval = alloc_private(dev, sizeof(struct pci6208_private));
+ if (retval < 0)
+ return retval;
+
+ retval = pci6208_find_device(dev, it->options[0], it->options[1]);
+ if (retval < 0)
+ return retval;
+
+ retval = pci6208_pci_setup(devpriv->pci_dev, &io_base, dev->minor);
+ if (retval < 0)
+ return retval;
+
+ dev->iobase = io_base;
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE; //anything else to add here??
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = 0xffff; //16-bit DAC
+ s->range_table = &range_bipolar10; //this needs to be checked.
+ s->insn_write = pci6208_ao_winsn;
+ s->insn_read = pci6208_ao_rinsn;
+
+ //s=dev->subdevices+1;
+ /* digital i/o subdevice */
+ //s->type=COMEDI_SUBD_DIO;
+ //s->subdev_flags=SDF_READABLE|SDF_WRITABLE;
+ //s->n_chan=16;
+ //s->maxdata=1;
+ //s->range_table=&range_digital;
+ //s->insn_bits = pci6208_dio_insn_bits;
+ //s->insn_config = pci6208_dio_insn_config;
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci6208_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci6208: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+static int pci6208_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i = 0, Data_Read;
+ unsigned short chan = CR_CHAN(insn->chanspec);
+ unsigned long invert = 1 << (16 - 1);
+ unsigned long out_value;
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ out_value = data[i] ^ invert;
+ /* a typical programming sequence */
+ do {
+ Data_Read = (inw(dev->iobase) & 1);
+ } while (Data_Read);
+ outw(out_value, dev->iobase + (0x02 * chan));
+ devpriv->ao_readback[chan] = out_value;
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int pci6208_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+//static int pci6208_dio_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data)
+//{
+// if(insn->n!=2)return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+// if(data[0]){
+// s->state &= ~data[0];
+// s->state |= data[0]&data[1];
+ /* Write out the new digital output lines */
+ //outw(s->state,dev->iobase + SKEL_DIO);
+// }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ //data[1]=inw(dev->iobase + SKEL_DIO);
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ //data[1]=s->state;
+
+// return 2;
+//}
+
+//static int pci6208_dio_insn_config(struct comedi_device *dev,struct comedi_subdevice *s,
+// struct comedi_insn *insn,unsigned int *data)
+//{
+// int chan=CR_CHAN(insn->chanspec);
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+// if(data[0]==COMEDI_OUTPUT){
+// s->io_bits |= 1<<chan;
+// }else{
+// s->io_bits &= ~(1<<chan);
+// }
+ //outw(s->io_bits,dev->iobase + SKEL_DIO_CONFIG);
+
+// return 1;
+//}
+
+static int pci6208_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct pci_dev *pci_dev;
+ int i;
+
+ for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+ if (pci_dev->vendor == PCI_VENDOR_ID_ADLINK) {
+ for (i = 0; i < pci6208_board_nbr; i++) {
+ if (pci6208_boards[i].dev_id == pci_dev->device) {
+ // was a particular bus/slot requested?
+ if ((bus != 0) || (slot != 0)) {
+ // are we on the wrong bus/slot?
+ if (pci_dev->bus->number
+ != bus ||
+ PCI_SLOT(pci_dev->devfn)
+ != slot) {
+ continue;
+ }
+ }
+ dev->board_ptr = pci6208_boards + i;
+ goto found;
+ }
+ }
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+
+ found:
+ printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
+ dev->minor,
+ pci6208_boards[i].name,
+ pci_dev->bus->number,
+ PCI_SLOT(pci_dev->devfn),
+ PCI_FUNC(pci_dev->devfn), pci_dev->irq);
+
+ // TODO: Warn about non-tested boards.
+ //switch(board->device_id)
+ //{
+ //};
+
+ devpriv->pci_dev = pci_dev;
+
+ return 0;
+}
+
+static int
+pci6208_pci_setup(struct pci_dev *pci_dev, unsigned long *io_base_ptr,
+ int dev_minor)
+{
+ unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
+
+ // Enable PCI device and request regions
+ if (comedi_pci_enable(pci_dev, PCI6208_DRIVER_NAME) < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev_minor);
+ return -EIO;
+ }
+ // Read local configuration register base address [PCI_BASE_ADDRESS #1].
+ lcr_io_base = pci_resource_start(pci_dev, 1);
+ lcr_io_range = pci_resource_len(pci_dev, 1);
+
+ printk("comedi%d: local config registers at address 0x%4lx [0x%4lx]\n",
+ dev_minor, lcr_io_base, lcr_io_range);
+
+ // Read PCI6208 register base address [PCI_BASE_ADDRESS #2].
+ io_base = pci_resource_start(pci_dev, 2);
+ io_range = pci_resource_end(pci_dev, 2) - io_base + 1;
+
+ printk("comedi%d: 6208 registers at address 0x%4lx [0x%4lx]\n",
+ dev_minor, io_base, io_range);
+
+ *io_base_ptr = io_base;
+ //devpriv->io_range = io_range;
+ //devpriv->is_valid=0;
+ //devpriv->lcr_io_base=lcr_io_base;
+ //devpriv->lcr_io_range=lcr_io_range;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/adl_pci7296.c b/drivers/staging/comedi/drivers/adl_pci7296.c
new file mode 100644
index 00000000000..bd0f9ab226e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci7296.c
@@ -0,0 +1,174 @@
+/*
+ comedi/drivers/adl_pci7296.c
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: adl_pci7296
+Description: Driver for the Adlink PCI-7296 96 ch. digital io board
+Devices: [ADLink] PCI-7296 (adl_pci7296)
+Author: Jon Grierson <jd@renko.co.uk>
+Updated: Mon, 14 Apr 2008 15:05:56 +0100
+Status: testing
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/kernel.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+// #include "8253.h"
+
+#define PORT1A 0
+#define PORT2A 4
+#define PORT3A 8
+#define PORT4A 12
+
+#define PCI_DEVICE_ID_PCI7296 0x7296
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci7296_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7296, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci7296_pci_table);
+
+struct adl_pci7296_private {
+ int data;
+ struct pci_dev *pci_dev;
+};
+
+
+#define devpriv ((struct adl_pci7296_private *)dev->private)
+
+static int adl_pci7296_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci7296_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci7296 = {
+ driver_name:"adl_pci7296",
+ module:THIS_MODULE,
+ attach:adl_pci7296_attach,
+ detach:adl_pci7296_detach,
+};
+
+static int adl_pci7296_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+ int bus, slot;
+ int ret;
+
+ printk("comedi: attempt to attach...\n");
+ printk("comedi%d: adl_pci7432\n", dev->minor);
+
+ dev->board_name = "pci7432";
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if (alloc_private(dev, sizeof(struct adl_pci7296_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+ pcidev->device == PCI_DEVICE_ID_PCI7296) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (pcidev->bus->number != bus
+ || PCI_SLOT(pcidev->devfn) != slot) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "adl_pci7296") < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+
+ dev->iobase = pci_resource_start(pcidev, 2);
+ printk("comedi: base addr %4lx\n", dev->iobase);
+
+ // four 8255 digital io subdevices
+ s = dev->subdevices + 0;
+ subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase));
+
+ s = dev->subdevices + 1;
+ ret = subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase + PORT2A));
+ if (ret < 0)
+ return ret;
+
+ s = dev->subdevices + 2;
+ ret = subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase + PORT3A));
+ if (ret < 0)
+ return ret;
+
+ s = dev->subdevices + 3;
+ ret = subdev_8255_init(dev, s, NULL,
+ (unsigned long)(dev->iobase + PORT4A));
+ if (ret < 0)
+ return ret;
+
+ printk("attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+}
+
+static int adl_pci7296_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci7432: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ // detach four 8255 digital io subdevices
+ if (dev->subdevices) {
+ subdev_8255_cleanup(dev, dev->subdevices + 0);
+ subdev_8255_cleanup(dev, dev->subdevices + 1);
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+ }
+
+ return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci7296, adl_pci7296_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci7432.c b/drivers/staging/comedi/drivers/adl_pci7432.c
new file mode 100644
index 00000000000..a8f1715608d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci7432.c
@@ -0,0 +1,202 @@
+/*
+ comedi/drivers/adl_pci7432.c
+
+ Hardware comedi driver fot PCI7432 Adlink card
+ Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: adl_pci7432
+Description: Driver for the Adlink PCI-7432 64 ch. isolated digital io board
+Devices: [ADLink] PCI-7432 (adl_pci7432)
+Author: Michel Lachaine <mike@mikelachaine.ca>
+Status: experimental
+Updated: Mon, 14 Apr 2008 15:08:14 +0100
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/kernel.h>
+#include "comedi_pci.h"
+
+#define PCI7432_DI 0x00
+#define PCI7432_DO 0x00
+
+#define PCI_DEVICE_ID_PCI7432 0x7432
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci7432_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI7432, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci7432_pci_table);
+
+struct adl_pci7432_private {
+ int data;
+ struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct adl_pci7432_private *)dev->private)
+
+static int adl_pci7432_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci7432_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci7432 = {
+ driver_name:"adl_pci7432",
+ module:THIS_MODULE,
+ attach:adl_pci7432_attach,
+ detach:adl_pci7432_detach,
+};
+
+/* Digital IO */
+
+static int adl_pci7432_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci7432_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/* */
+
+static int adl_pci7432_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+ int bus, slot;
+
+ printk("comedi: attempt to attach...\n");
+ printk("comedi%d: adl_pci7432\n", dev->minor);
+
+ dev->board_name = "pci7432";
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if (alloc_private(dev, sizeof(struct adl_pci7432_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+ pcidev->device == PCI_DEVICE_ID_PCI7432) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (pcidev->bus->number != bus
+ || PCI_SLOT(pcidev->devfn) != slot) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "adl_pci7432") < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+ dev->iobase = pci_resource_start(pcidev, 2);
+ printk("comedi: base addr %4lx\n", dev->iobase);
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ s->io_bits = 0x00000000;
+ s->range_table = &range_digital;
+ s->insn_bits = adl_pci7432_di_insn_bits;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags =
+ SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ s->io_bits = 0xffffffff;
+ s->range_table = &range_digital;
+ s->insn_bits = adl_pci7432_do_insn_bits;
+
+ printk("comedi: attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+}
+
+static int adl_pci7432_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci7432: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+static int adl_pci7432_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ printk("comedi: pci7432_do_insn_bits called\n");
+ printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ printk("comedi: out: %8x on iobase %4lx\n", s->state,
+ dev->iobase + PCI7432_DO);
+ outl(s->state & 0xffffffff, dev->iobase + PCI7432_DO);
+ }
+ return 2;
+}
+
+static int adl_pci7432_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ printk("comedi: pci7432_di_insn_bits called\n");
+ printk("comedi: data0: %8x data1: %8x\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inl(dev->iobase + PCI7432_DI) & 0xffffffff;
+ printk("comedi: data1 %8x\n", data[1]);
+
+ return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci7432, adl_pci7432_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci8164.c b/drivers/staging/comedi/drivers/adl_pci8164.c
new file mode 100644
index 00000000000..adf90be7998
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci8164.c
@@ -0,0 +1,512 @@
+/*
+ comedi/drivers/adl_pci8164.c
+
+ Hardware comedi driver fot PCI-8164 Adlink card
+ Copyright (C) 2004 Michel Lachine <mike@mikelachaine.ca>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: adl_pci8164
+Description: Driver for the Adlink PCI-8164 4 Axes Motion Control board
+Devices: [ADLink] PCI-8164 (adl_pci8164)
+Author: Michel Lachaine <mike@mikelachaine.ca>
+Status: experimental
+Updated: Mon, 14 Apr 2008 15:10:32 +0100
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include "comedi_fc.h"
+#include "comedi_pci.h"
+#include "8253.h"
+
+#define PCI8164_AXIS_X 0x00
+#define PCI8164_AXIS_Y 0x08
+#define PCI8164_AXIS_Z 0x10
+#define PCI8164_AXIS_U 0x18
+
+#define PCI8164_MSTS 0x00
+#define PCI8164_SSTS 0x02
+#define PCI8164_BUF0 0x04
+#define PCI8164_BUF1 0x06
+
+#define PCI8164_CMD 0x00
+#define PCI8164_OTP 0x02
+
+#define PCI_DEVICE_ID_PCI8164 0x8164
+
+static DEFINE_PCI_DEVICE_TABLE(adl_pci8164_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI_DEVICE_ID_PCI8164, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, adl_pci8164_pci_table);
+
+struct adl_pci8164_private {
+ int data;
+ struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct adl_pci8164_private *)dev->private)
+
+static int adl_pci8164_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int adl_pci8164_detach(struct comedi_device * dev);
+static struct comedi_driver driver_adl_pci8164 = {
+ driver_name:"adl_pci8164",
+ module:THIS_MODULE,
+ attach:adl_pci8164_attach,
+ detach:adl_pci8164_detach,
+};
+
+static int adl_pci8164_insn_read_msts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_ssts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_buf0(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_read_buf1(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_cmd(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_otp(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_buf0(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_insn_write_buf1(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int adl_pci8164_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+ int bus, slot;
+
+ printk("comedi: attempt to attach...\n");
+ printk("comedi%d: adl_pci8164\n", dev->minor);
+
+ dev->board_name = "pci8164";
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if (alloc_private(dev, sizeof(struct adl_pci8164_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_ADLINK &&
+ pcidev->device == PCI_DEVICE_ID_PCI8164) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (pcidev->bus->number != bus
+ || PCI_SLOT(pcidev->devfn) != slot) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "adl_pci8164") < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+ dev->iobase = pci_resource_start(pcidev, 2);
+ printk("comedi: base addr %4lx\n", dev->iobase);
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_msts;
+ s->insn_write = adl_pci8164_insn_write_cmd;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_ssts;
+ s->insn_write = adl_pci8164_insn_write_otp;
+
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_buf0;
+ s->insn_write = adl_pci8164_insn_write_buf0;
+
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_PROC;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 4;
+ //s->range_table = &range_axis;
+ s->insn_read = adl_pci8164_insn_read_buf1;
+ s->insn_write = adl_pci8164_insn_write_buf1;
+
+ printk("comedi: attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, bus, slot);
+ return -EIO;
+}
+
+static int adl_pci8164_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci8164: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+static int adl_pci8164_insn_read_msts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_MSTS);
+ printk("comedi: pci8164 MSTS read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_read_ssts(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_SSTS);
+ printk("comedi: pci8164 SSTS read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_read_buf0(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF0);
+ printk("comedi: pci8164 BUF0 read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_read_buf1(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ data[0] = inw(dev->iobase + axis_reg + PCI8164_BUF1);
+ printk("comedi: pci8164 BUF1 read -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_cmd(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_CMD);
+ printk("comedi: pci8164 CMD write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_otp(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_OTP);
+ printk("comedi: pci8164 OTP write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_buf0(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_BUF0);
+ printk("comedi: pci8164 BUF0 write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+static int adl_pci8164_insn_write_buf1(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int axis, axis_reg;
+
+ char *axisname;
+
+ axis = CR_CHAN(insn->chanspec);
+
+ switch (axis) {
+ case 0:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ break;
+ case 1:
+ axis_reg = PCI8164_AXIS_Y;
+ axisname = "Y";
+ break;
+ case 2:
+ axis_reg = PCI8164_AXIS_Z;
+ axisname = "Z";
+ break;
+ case 3:
+ axis_reg = PCI8164_AXIS_U;
+ axisname = "U";
+ break;
+ default:
+ axis_reg = PCI8164_AXIS_X;
+ axisname = "X";
+ }
+
+ outw(data[0], dev->iobase + axis_reg + PCI8164_BUF1);
+ printk("comedi: pci8164 BUF1 write -> %04X:%04X on axis %s\n", data[0],
+ data[1], axisname);
+
+ return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_adl_pci8164, adl_pci8164_pci_table);
diff --git a/drivers/staging/comedi/drivers/adl_pci9111.c b/drivers/staging/comedi/drivers/adl_pci9111.c
new file mode 100644
index 00000000000..b4a61c560c5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci9111.c
@@ -0,0 +1,1391 @@
+/*
+
+ comedi/drivers/adl_pci9111.c
+
+ Hardware driver for PCI9111 ADLink cards:
+
+ PCI-9111HR
+
+ Copyright (C) 2002-2005 Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+Driver: adl_pci9111
+Description: Adlink PCI-9111HR
+Author: Emmanuel Pacaud <emmanuel.pacaud@univ-poitiers.fr>
+Devices: [ADLink] PCI-9111HR (adl_pci9111)
+Status: experimental
+
+Supports:
+
+ - ai_insn read
+ - ao_insn read/write
+ - di_insn read
+ - do_insn read/write
+ - ai_do_cmd mode with the following sources:
+
+ - start_src TRIG_NOW
+ - scan_begin_src TRIG_FOLLOW TRIG_TIMER TRIG_EXT
+ - convert_src TRIG_TIMER TRIG_EXT
+ - scan_end_src TRIG_COUNT
+ - stop_src TRIG_COUNT TRIG_NONE
+
+ The scanned channels must be consecutive and start from 0. They must
+ all have the same range and aref.
+
+Configuration options:
+
+ [0] - PCI bus number (optional)
+ [1] - PCI slot number (optional)
+
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+
+*/
+
+/*
+CHANGELOG:
+
+ 2005/02/17 Extend AI streaming capabilities. Now, scan_begin_arg can be
+ a multiple of chanlist_len*convert_arg.
+ 2002/02/19 Fixed the two's complement conversion in pci9111_(hr_)ai_get_data.
+ 2002/02/18 Added external trigger support for analog input.
+
+TODO:
+
+ - Really test implemented functionality.
+ - Add support for the PCI-9111DG with a probe routine to identify the card type
+ (perhaps with the help of the channel number readback of the A/D Data register).
+ - Add external multiplexer support.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+#define PCI9111_DRIVER_NAME "adl_pci9111"
+#define PCI9111_HR_DEVICE_ID 0x9111
+
+/* TODO: Add other pci9111 board id */
+
+#define PCI9111_IO_RANGE 0x0100
+
+#define PCI9111_FIFO_HALF_SIZE 512
+
+#define PCI9111_AI_CHANNEL_NBR 16
+
+#define PCI9111_AI_RESOLUTION 12
+#define PCI9111_AI_RESOLUTION_MASK 0x0FFF
+#define PCI9111_AI_RESOLUTION_2_CMP_BIT 0x0800
+
+#define PCI9111_HR_AI_RESOLUTION 16
+#define PCI9111_HR_AI_RESOLUTION_MASK 0xFFFF
+#define PCI9111_HR_AI_RESOLUTION_2_CMP_BIT 0x8000
+
+#define PCI9111_AI_ACQUISITION_PERIOD_MIN_NS 10000
+#define PCI9111_AO_CHANNEL_NBR 1
+#define PCI9111_AO_RESOLUTION 12
+#define PCI9111_AO_RESOLUTION_MASK 0x0FFF
+#define PCI9111_DI_CHANNEL_NBR 16
+#define PCI9111_DO_CHANNEL_NBR 16
+#define PCI9111_DO_MASK 0xFFFF
+
+#define PCI9111_RANGE_SETTING_DELAY 10
+#define PCI9111_AI_INSTANT_READ_UDELAY_US 2
+#define PCI9111_AI_INSTANT_READ_TIMEOUT 100
+
+#define PCI9111_8254_CLOCK_PERIOD_NS 500
+
+#define PCI9111_8254_COUNTER_0 0x00
+#define PCI9111_8254_COUNTER_1 0x40
+#define PCI9111_8254_COUNTER_2 0x80
+#define PCI9111_8254_COUNTER_LATCH 0x00
+#define PCI9111_8254_READ_LOAD_LSB_ONLY 0x10
+#define PCI9111_8254_READ_LOAD_MSB_ONLY 0x20
+#define PCI9111_8254_READ_LOAD_LSB_MSB 0x30
+#define PCI9111_8254_MODE_0 0x00
+#define PCI9111_8254_MODE_1 0x02
+#define PCI9111_8254_MODE_2 0x04
+#define PCI9111_8254_MODE_3 0x06
+#define PCI9111_8254_MODE_4 0x08
+#define PCI9111_8254_MODE_5 0x0A
+#define PCI9111_8254_BINARY_COUNTER 0x00
+#define PCI9111_8254_BCD_COUNTER 0x01
+
+/* IO address map */
+
+#define PCI9111_REGISTER_AD_FIFO_VALUE 0x00 /* AD Data stored in FIFO */
+#define PCI9111_REGISTER_DA_OUTPUT 0x00
+#define PCI9111_REGISTER_DIGITAL_IO 0x02
+#define PCI9111_REGISTER_EXTENDED_IO_PORTS 0x04
+#define PCI9111_REGISTER_AD_CHANNEL_CONTROL 0x06 /* Channel selection */
+#define PCI9111_REGISTER_AD_CHANNEL_READBACK 0x06
+#define PCI9111_REGISTER_INPUT_SIGNAL_RANGE 0x08
+#define PCI9111_REGISTER_RANGE_STATUS_READBACK 0x08
+#define PCI9111_REGISTER_TRIGGER_MODE_CONTROL 0x0A
+#define PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK 0x0A
+#define PCI9111_REGISTER_SOFTWARE_TRIGGER 0x0E
+#define PCI9111_REGISTER_INTERRUPT_CONTROL 0x0C
+#define PCI9111_REGISTER_8254_COUNTER_0 0x40
+#define PCI9111_REGISTER_8254_COUNTER_1 0x42
+#define PCI9111_REGISTER_8254_COUNTER_2 0X44
+#define PCI9111_REGISTER_8254_CONTROL 0x46
+#define PCI9111_REGISTER_INTERRUPT_CLEAR 0x48
+
+#define PCI9111_TRIGGER_MASK 0x0F
+#define PCI9111_PTRG_OFF (0 << 3)
+#define PCI9111_PTRG_ON (1 << 3)
+#define PCI9111_EITS_EXTERNAL (1 << 2)
+#define PCI9111_EITS_INTERNAL (0 << 2)
+#define PCI9111_TPST_SOFTWARE_TRIGGER (0 << 1)
+#define PCI9111_TPST_TIMER_PACER (1 << 1)
+#define PCI9111_ASCAN_ON (1 << 0)
+#define PCI9111_ASCAN_OFF (0 << 0)
+
+#define PCI9111_ISC0_SET_IRQ_ON_ENDING_OF_AD_CONVERSION (0 << 0)
+#define PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL (1 << 0)
+#define PCI9111_ISC1_SET_IRQ_ON_TIMER_TICK (0 << 1)
+#define PCI9111_ISC1_SET_IRQ_ON_EXT_TRG (1 << 1)
+#define PCI9111_FFEN_SET_FIFO_ENABLE (0 << 2)
+#define PCI9111_FFEN_SET_FIFO_DISABLE (1 << 2)
+
+#define PCI9111_CHANNEL_MASK 0x0F
+
+#define PCI9111_RANGE_MASK 0x07
+#define PCI9111_FIFO_EMPTY_MASK 0x10
+#define PCI9111_FIFO_HALF_FULL_MASK 0x20
+#define PCI9111_FIFO_FULL_MASK 0x40
+#define PCI9111_AD_BUSY_MASK 0x80
+
+#define PCI9111_IO_BASE dev->iobase
+
+/*
+ * Define inlined function
+ */
+
+#define pci9111_trigger_and_autoscan_get() \
+ (inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK)&0x0F)
+
+#define pci9111_trigger_and_autoscan_set(flags) \
+ outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_TRIGGER_MODE_CONTROL)
+
+#define pci9111_interrupt_and_fifo_get() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_MODE_INTERRUPT_READBACK) >> 4) &0x03)
+
+#define pci9111_interrupt_and_fifo_set(flags) \
+ outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+
+#define pci9111_interrupt_clear() \
+ outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CLEAR)
+
+#define pci9111_software_trigger() \
+ outb(0,PCI9111_IO_BASE+PCI9111_REGISTER_SOFTWARE_TRIGGER)
+
+#define pci9111_fifo_reset() \
+ outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+ outb(PCI9111_FFEN_SET_FIFO_DISABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL); \
+ outb(PCI9111_FFEN_SET_FIFO_ENABLE,PCI9111_IO_BASE+PCI9111_REGISTER_INTERRUPT_CONTROL)
+
+#define pci9111_is_fifo_full() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_FULL_MASK)==0)
+
+#define pci9111_is_fifo_half_full() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_HALF_FULL_MASK)==0)
+
+#define pci9111_is_fifo_empty() \
+ ((inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)& \
+ PCI9111_FIFO_EMPTY_MASK)==0)
+
+#define pci9111_ai_channel_set(channel) \
+ outb((channel)&PCI9111_CHANNEL_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_CONTROL)
+
+#define pci9111_ai_channel_get() \
+ inb(PCI9111_IO_BASE+PCI9111_REGISTER_AD_CHANNEL_READBACK)&PCI9111_CHANNEL_MASK
+
+#define pci9111_ai_range_set(range) \
+ outb((range)&PCI9111_RANGE_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_INPUT_SIGNAL_RANGE)
+
+#define pci9111_ai_range_get() \
+ inb(PCI9111_IO_BASE+PCI9111_REGISTER_RANGE_STATUS_READBACK)&PCI9111_RANGE_MASK
+
+#define pci9111_ai_get_data() \
+ ((inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE)>>4)&PCI9111_AI_RESOLUTION_MASK) \
+ ^ PCI9111_AI_RESOLUTION_2_CMP_BIT
+
+#define pci9111_hr_ai_get_data() \
+ (inw(PCI9111_IO_BASE+PCI9111_REGISTER_AD_FIFO_VALUE) & PCI9111_HR_AI_RESOLUTION_MASK) \
+ ^ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT
+
+#define pci9111_ao_set_data(data) \
+ outw(data&PCI9111_AO_RESOLUTION_MASK,PCI9111_IO_BASE+PCI9111_REGISTER_DA_OUTPUT)
+
+#define pci9111_di_get_bits() \
+ inw(PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+
+#define pci9111_do_set_bits(bits) \
+ outw(bits,PCI9111_IO_BASE+PCI9111_REGISTER_DIGITAL_IO)
+
+#define pci9111_8254_control_set(flags) \
+ outb(flags,PCI9111_IO_BASE+PCI9111_REGISTER_8254_CONTROL)
+
+#define pci9111_8254_counter_0_set(data) \
+ outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0); \
+ outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_0)
+
+#define pci9111_8254_counter_1_set(data) \
+ outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1); \
+ outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_1)
+
+#define pci9111_8254_counter_2_set(data) \
+ outb(data & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2); \
+ outb( (data >> 8) & 0xFF, PCI9111_IO_BASE+PCI9111_REGISTER_8254_COUNTER_2)
+
+/* Function prototypes */
+
+static int pci9111_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci9111_detach(struct comedi_device * dev);
+static void pci9111_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int start_chan_index);
+
+static const struct comedi_lrange pci9111_hr_ai_range = {
+ 5,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625)
+ }
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci9111_pci_table) = {
+ {PCI_VENDOR_ID_ADLINK, PCI9111_HR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0,
+ 0, 0},
+ /* { PCI_VENDOR_ID_ADLINK, PCI9111_HG_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, */
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci9111_pci_table);
+
+/* */
+/* Board specification structure */
+/* */
+
+struct pci9111_board {
+ const char *name; /* driver name */
+ int device_id;
+ int ai_channel_nbr; /* num of A/D chans */
+ int ao_channel_nbr; /* num of D/A chans */
+ int ai_resolution; /* resolution of A/D */
+ int ai_resolution_mask;
+ int ao_resolution; /* resolution of D/A */
+ int ao_resolution_mask;
+ const struct comedi_lrange *ai_range_list; /* rangelist for A/D */
+ const struct comedi_lrange *ao_range_list; /* rangelist for D/A */
+ unsigned int ai_acquisition_period_min_ns;
+};
+
+static const struct pci9111_board pci9111_boards[] = {
+ {
+ name: "pci9111_hr",
+ device_id:PCI9111_HR_DEVICE_ID,
+ ai_channel_nbr:PCI9111_AI_CHANNEL_NBR,
+ ao_channel_nbr:PCI9111_AO_CHANNEL_NBR,
+ ai_resolution:PCI9111_HR_AI_RESOLUTION,
+ ai_resolution_mask:PCI9111_HR_AI_RESOLUTION_MASK,
+ ao_resolution:PCI9111_AO_RESOLUTION,
+ ao_resolution_mask:PCI9111_AO_RESOLUTION_MASK,
+ ai_range_list:&pci9111_hr_ai_range,
+ ao_range_list:&range_bipolar10,
+ ai_acquisition_period_min_ns:PCI9111_AI_ACQUISITION_PERIOD_MIN_NS}
+};
+
+#define pci9111_board_nbr \
+ (sizeof(pci9111_boards)/sizeof(struct pci9111_board))
+
+static struct comedi_driver pci9111_driver = {
+ driver_name:PCI9111_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pci9111_attach,
+ detach:pci9111_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(pci9111_driver, pci9111_pci_table);
+
+/* Private data structure */
+
+struct pci9111_private_data {
+ struct pci_dev *pci_device;
+ unsigned long io_range; /* PCI6503 io range */
+
+ unsigned long lcr_io_base; /* Local configuration register base address */
+ unsigned long lcr_io_range;
+
+ int stop_counter;
+ int stop_is_none;
+
+ unsigned int scan_delay;
+ unsigned int chanlist_len;
+ unsigned int chunk_counter;
+ unsigned int chunk_num_samples;
+
+ int ao_readback; /* Last written analog output data */
+
+ int timer_divisor_1; /* Divisor values for the 8254 timer pacer */
+ int timer_divisor_2;
+
+ int is_valid; /* Is device valid */
+
+ short ai_bounce_buffer[2 * PCI9111_FIFO_HALF_SIZE];
+};
+
+#define dev_private ((struct pci9111_private_data *)dev->private)
+
+/* ------------------------------------------------------------------ */
+/* PLX9050 SECTION */
+/* ------------------------------------------------------------------ */
+
+#define PLX9050_REGISTER_INTERRUPT_CONTROL 0x4c
+
+#define PLX9050_LINTI1_ENABLE (1 << 0)
+#define PLX9050_LINTI1_ACTIVE_HIGH (1 << 1)
+#define PLX9050_LINTI1_STATUS (1 << 2)
+#define PLX9050_LINTI2_ENABLE (1 << 3)
+#define PLX9050_LINTI2_ACTIVE_HIGH (1 << 4)
+#define PLX9050_LINTI2_STATUS (1 << 5)
+#define PLX9050_PCI_INTERRUPT_ENABLE (1 << 6)
+#define PLX9050_SOFTWARE_INTERRUPT (1 << 7)
+
+static void plx9050_interrupt_control(unsigned long io_base,
+ bool LINTi1_enable,
+ bool LINTi1_active_high,
+ bool LINTi2_enable, bool LINTi2_active_high, bool interrupt_enable)
+{
+ int flags = 0;
+
+ if (LINTi1_enable)
+ flags |= PLX9050_LINTI1_ENABLE;
+ if (LINTi1_active_high)
+ flags |= PLX9050_LINTI1_ACTIVE_HIGH;
+ if (LINTi2_enable)
+ flags |= PLX9050_LINTI2_ENABLE;
+ if (LINTi2_active_high)
+ flags |= PLX9050_LINTI2_ACTIVE_HIGH;
+
+ if (interrupt_enable)
+ flags |= PLX9050_PCI_INTERRUPT_ENABLE;
+
+ outb(flags, io_base + PLX9050_REGISTER_INTERRUPT_CONTROL);
+}
+
+/* ------------------------------------------------------------------ */
+/* MISCELLANEOUS SECTION */
+/* ------------------------------------------------------------------ */
+
+/* 8254 timer */
+
+static void pci9111_timer_set(struct comedi_device * dev)
+{
+ pci9111_8254_control_set(PCI9111_8254_COUNTER_0 |
+ PCI9111_8254_READ_LOAD_LSB_MSB |
+ PCI9111_8254_MODE_0 | PCI9111_8254_BINARY_COUNTER);
+
+ pci9111_8254_control_set(PCI9111_8254_COUNTER_1 |
+ PCI9111_8254_READ_LOAD_LSB_MSB |
+ PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
+
+ pci9111_8254_control_set(PCI9111_8254_COUNTER_2 |
+ PCI9111_8254_READ_LOAD_LSB_MSB |
+ PCI9111_8254_MODE_2 | PCI9111_8254_BINARY_COUNTER);
+
+ comedi_udelay(1);
+
+ pci9111_8254_counter_2_set(dev_private->timer_divisor_2);
+ pci9111_8254_counter_1_set(dev_private->timer_divisor_1);
+}
+
+enum pci9111_trigger_sources {
+ software,
+ timer_pacer,
+ external
+};
+
+static void pci9111_trigger_source_set(struct comedi_device * dev,
+ enum pci9111_trigger_sources source)
+{
+ int flags;
+
+ flags = pci9111_trigger_and_autoscan_get() & 0x09;
+
+ switch (source) {
+ case software:
+ flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_SOFTWARE_TRIGGER;
+ break;
+
+ case timer_pacer:
+ flags |= PCI9111_EITS_INTERNAL | PCI9111_TPST_TIMER_PACER;
+ break;
+
+ case external:
+ flags |= PCI9111_EITS_EXTERNAL;
+ break;
+ }
+
+ pci9111_trigger_and_autoscan_set(flags);
+}
+
+static void pci9111_pretrigger_set(struct comedi_device * dev, bool pretrigger)
+{
+ int flags;
+
+ flags = pci9111_trigger_and_autoscan_get() & 0x07;
+
+ if (pretrigger)
+ flags |= PCI9111_PTRG_ON;
+
+ pci9111_trigger_and_autoscan_set(flags);
+}
+
+static void pci9111_autoscan_set(struct comedi_device * dev, bool autoscan)
+{
+ int flags;
+
+ flags = pci9111_trigger_and_autoscan_get() & 0x0e;
+
+ if (autoscan)
+ flags |= PCI9111_ASCAN_ON;
+
+ pci9111_trigger_and_autoscan_set(flags);
+}
+
+enum pci9111_ISC0_sources {
+ irq_on_eoc,
+ irq_on_fifo_half_full
+};
+
+enum pci9111_ISC1_sources {
+ irq_on_timer_tick,
+ irq_on_external_trigger
+};
+
+static void pci9111_interrupt_source_set(struct comedi_device * dev,
+ enum pci9111_ISC0_sources irq_0_source, enum pci9111_ISC1_sources irq_1_source)
+{
+ int flags;
+
+ flags = pci9111_interrupt_and_fifo_get() & 0x04;
+
+ if (irq_0_source == irq_on_fifo_half_full)
+ flags |= PCI9111_ISC0_SET_IRQ_ON_FIFO_HALF_FULL;
+
+ if (irq_1_source == irq_on_external_trigger)
+ flags |= PCI9111_ISC1_SET_IRQ_ON_EXT_TRG;
+
+ pci9111_interrupt_and_fifo_set(flags);
+}
+
+/* ------------------------------------------------------------------ */
+/* HARDWARE TRIGGERED ANALOG INPUT SECTION */
+/* ------------------------------------------------------------------ */
+
+/* Cancel analog input autoscan */
+
+#undef AI_DO_CMD_DEBUG
+
+static int pci9111_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* Disable interrupts */
+
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
+ true, false);
+
+ pci9111_trigger_source_set(dev, software);
+
+ pci9111_autoscan_set(dev, false);
+
+ pci9111_fifo_reset();
+
+#ifdef AI_DO_CMD_DEBUG
+ printk(PCI9111_DRIVER_NAME ": ai_cancel\n");
+#endif
+
+ return 0;
+}
+
+/* Test analog input command */
+
+#define pci9111_check_trigger_src(src,flags) \
+ tmp = src; \
+ src &= flags; \
+ if (!src || tmp != src) error++
+
+static int
+pci9111_ai_do_cmd_test(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int tmp;
+ int error = 0;
+ int range, reference;
+ int i;
+ struct pci9111_board *board = (struct pci9111_board *) dev->board_ptr;
+
+ /* Step 1 : check if trigger are trivialy valid */
+
+ pci9111_check_trigger_src(cmd->start_src, TRIG_NOW);
+ pci9111_check_trigger_src(cmd->scan_begin_src,
+ TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT);
+ pci9111_check_trigger_src(cmd->convert_src, TRIG_TIMER | TRIG_EXT);
+ pci9111_check_trigger_src(cmd->scan_end_src, TRIG_COUNT);
+ pci9111_check_trigger_src(cmd->stop_src, TRIG_COUNT | TRIG_NONE);
+
+ if (error)
+ return 1;
+
+ /* step 2 : make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW)
+ error++;
+
+ if ((cmd->scan_begin_src != TRIG_TIMER) &&
+ (cmd->scan_begin_src != TRIG_FOLLOW) &&
+ (cmd->scan_begin_src != TRIG_EXT))
+ error++;
+
+ if ((cmd->convert_src != TRIG_TIMER) && (cmd->convert_src != TRIG_EXT)) {
+ error++;
+ }
+ if ((cmd->convert_src == TRIG_TIMER) &&
+ !((cmd->scan_begin_src == TRIG_TIMER) ||
+ (cmd->scan_begin_src == TRIG_FOLLOW))) {
+ error++;
+ }
+ if ((cmd->convert_src == TRIG_EXT) &&
+ !((cmd->scan_begin_src == TRIG_EXT) ||
+ (cmd->scan_begin_src == TRIG_FOLLOW))) {
+ error++;
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT)
+ error++;
+ if ((cmd->stop_src != TRIG_COUNT) && (cmd->stop_src != TRIG_NONE))
+ error++;
+
+ if (error)
+ return 2;
+
+ /* Step 3 : make sure arguments are trivialy compatible */
+
+ if (cmd->chanlist_len < 1) {
+ cmd->chanlist_len = 1;
+ error++;
+ }
+
+ if (cmd->chanlist_len > board->ai_channel_nbr) {
+ cmd->chanlist_len = board->ai_channel_nbr;
+ error++;
+ }
+
+ if ((cmd->start_src == TRIG_NOW) && (cmd->start_arg != 0)) {
+ cmd->start_arg = 0;
+ error++;
+ }
+
+ if ((cmd->convert_src == TRIG_TIMER) &&
+ (cmd->convert_arg < board->ai_acquisition_period_min_ns)) {
+ cmd->convert_arg = board->ai_acquisition_period_min_ns;
+ error++;
+ }
+ if ((cmd->convert_src == TRIG_EXT) && (cmd->convert_arg != 0)) {
+ cmd->convert_arg = 0;
+ error++;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_TIMER) &&
+ (cmd->scan_begin_arg < board->ai_acquisition_period_min_ns)) {
+ cmd->scan_begin_arg = board->ai_acquisition_period_min_ns;
+ error++;
+ }
+ if ((cmd->scan_begin_src == TRIG_FOLLOW) && (cmd->scan_begin_arg != 0)) {
+ cmd->scan_begin_arg = 0;
+ error++;
+ }
+ if ((cmd->scan_begin_src == TRIG_EXT) && (cmd->scan_begin_arg != 0)) {
+ cmd->scan_begin_arg = 0;
+ error++;
+ }
+
+ if ((cmd->scan_end_src == TRIG_COUNT) &&
+ (cmd->scan_end_arg != cmd->chanlist_len)) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ error++;
+ }
+
+ if ((cmd->stop_src == TRIG_COUNT) && (cmd->stop_arg < 1)) {
+ cmd->stop_arg = 1;
+ error++;
+ }
+ if ((cmd->stop_src == TRIG_NONE) && (cmd->stop_arg != 0)) {
+ cmd->stop_arg = 0;
+ error++;
+ }
+
+ if (error)
+ return 3;
+
+ /* Step 4 : fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
+ &(dev_private->timer_divisor_1),
+ &(dev_private->timer_divisor_2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ error++;
+ }
+ /* There's only one timer on this card, so the scan_begin timer must */
+ /* be a multiple of chanlist_len*convert_arg */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+
+ unsigned int scan_begin_min;
+ unsigned int scan_begin_arg;
+ unsigned int scan_factor;
+
+ scan_begin_min = cmd->chanlist_len * cmd->convert_arg;
+
+ if (cmd->scan_begin_arg != scan_begin_min) {
+ if (scan_begin_min < cmd->scan_begin_arg) {
+ scan_factor =
+ cmd->scan_begin_arg / scan_begin_min;
+ scan_begin_arg = scan_factor * scan_begin_min;
+ if (cmd->scan_begin_arg != scan_begin_arg) {
+ cmd->scan_begin_arg = scan_begin_arg;
+ error++;
+ }
+ } else {
+ cmd->scan_begin_arg = scan_begin_min;
+ error++;
+ }
+ }
+ }
+
+ if (error)
+ return 4;
+
+ /* Step 5 : check channel list */
+
+ if (cmd->chanlist) {
+
+ range = CR_RANGE(cmd->chanlist[0]);
+ reference = CR_AREF(cmd->chanlist[0]);
+
+ if (cmd->chanlist_len > 1) {
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != i) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive "
+ "channels,counting upwards from 0\n");
+ error++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != range) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ error++;
+ }
+ if (CR_AREF(cmd->chanlist[i]) != reference) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same reference\n");
+ error++;
+ }
+ }
+ } else {
+ if ((CR_CHAN(cmd->chanlist[0]) >
+ (board->ai_channel_nbr - 1))
+ || (CR_CHAN(cmd->chanlist[0]) < 0)) {
+ comedi_error(dev,
+ "channel number is out of limits\n");
+ error++;
+ }
+ }
+ }
+
+ if (error)
+ return 5;
+
+ return 0;
+
+}
+
+/* Analog input command */
+
+static int pci9111_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * subdevice)
+{
+ struct comedi_cmd *async_cmd = &subdevice->async->cmd;
+
+ if (!dev->irq) {
+ comedi_error(dev,
+ "no irq assigned for PCI9111, cannot do hardware conversion");
+ return -1;
+ }
+ /* Set channel scan limit */
+ /* PCI9111 allows only scanning from channel 0 to channel n */
+ /* TODO: handle the case of an external multiplexer */
+
+ if (async_cmd->chanlist_len > 1) {
+ pci9111_ai_channel_set((async_cmd->chanlist_len) - 1);
+ pci9111_autoscan_set(dev, true);
+ } else {
+ pci9111_ai_channel_set(CR_CHAN(async_cmd->chanlist[0]));
+ pci9111_autoscan_set(dev, false);
+ }
+
+ /* Set gain */
+ /* This is the same gain on every channel */
+
+ pci9111_ai_range_set(CR_RANGE(async_cmd->chanlist[0]));
+
+ /* Set counter */
+
+ switch (async_cmd->stop_src) {
+ case TRIG_COUNT:
+ dev_private->stop_counter =
+ async_cmd->stop_arg * async_cmd->chanlist_len;
+ dev_private->stop_is_none = 0;
+ break;
+
+ case TRIG_NONE:
+ dev_private->stop_counter = 0;
+ dev_private->stop_is_none = 1;
+ break;
+
+ default:
+ comedi_error(dev, "Invalid stop trigger");
+ return -1;
+ }
+
+ /* Set timer pacer */
+
+ dev_private->scan_delay = 0;
+ switch (async_cmd->convert_src) {
+ case TRIG_TIMER:
+ i8253_cascade_ns_to_timer_2div(PCI9111_8254_CLOCK_PERIOD_NS,
+ &(dev_private->timer_divisor_1),
+ &(dev_private->timer_divisor_2),
+ &(async_cmd->convert_arg),
+ async_cmd->flags & TRIG_ROUND_MASK);
+#ifdef AI_DO_CMD_DEBUG
+ printk(PCI9111_DRIVER_NAME ": divisors = %d, %d\n",
+ dev_private->timer_divisor_1,
+ dev_private->timer_divisor_2);
+#endif
+
+ pci9111_trigger_source_set(dev, software);
+ pci9111_timer_set(dev);
+ pci9111_fifo_reset();
+ pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
+ irq_on_timer_tick);
+ pci9111_trigger_source_set(dev, timer_pacer);
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
+ false, true, true);
+
+ dev_private->scan_delay =
+ (async_cmd->scan_begin_arg / (async_cmd->convert_arg *
+ async_cmd->chanlist_len)) - 1;
+
+ break;
+
+ case TRIG_EXT:
+
+ pci9111_trigger_source_set(dev, external);
+ pci9111_fifo_reset();
+ pci9111_interrupt_source_set(dev, irq_on_fifo_half_full,
+ irq_on_timer_tick);
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
+ false, true, true);
+
+ break;
+
+ default:
+ comedi_error(dev, "Invalid convert trigger");
+ return -1;
+ }
+
+ dev_private->stop_counter *= (1 + dev_private->scan_delay);
+ dev_private->chanlist_len = async_cmd->chanlist_len;
+ dev_private->chunk_counter = 0;
+ dev_private->chunk_num_samples =
+ dev_private->chanlist_len * (1 + dev_private->scan_delay);
+
+#ifdef AI_DO_CMD_DEBUG
+ printk(PCI9111_DRIVER_NAME ": start interruptions!\n");
+ printk(PCI9111_DRIVER_NAME ": trigger source = %2x\n",
+ pci9111_trigger_and_autoscan_get());
+ printk(PCI9111_DRIVER_NAME ": irq source = %2x\n",
+ pci9111_interrupt_and_fifo_get());
+ printk(PCI9111_DRIVER_NAME ": ai_do_cmd\n");
+ printk(PCI9111_DRIVER_NAME ": stop counter = %d\n",
+ dev_private->stop_counter);
+ printk(PCI9111_DRIVER_NAME ": scan delay = %d\n",
+ dev_private->scan_delay);
+ printk(PCI9111_DRIVER_NAME ": chanlist_len = %d\n",
+ dev_private->chanlist_len);
+ printk(PCI9111_DRIVER_NAME ": chunk num samples = %d\n",
+ dev_private->chunk_num_samples);
+#endif
+
+ return 0;
+}
+
+static void pci9111_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int start_chan_index)
+{
+ unsigned int i, num_samples = num_bytes / sizeof(short);
+ short *array = data;
+ int resolution =
+ ((struct pci9111_board *) dev->board_ptr)->ai_resolution;
+
+ for (i = 0; i < num_samples; i++) {
+ if (resolution == PCI9111_HR_AI_RESOLUTION)
+ array[i] =
+ (array[i] & PCI9111_HR_AI_RESOLUTION_MASK) ^
+ PCI9111_HR_AI_RESOLUTION_2_CMP_BIT;
+ else
+ array[i] =
+ ((array[i] >> 4) & PCI9111_AI_RESOLUTION_MASK) ^
+ PCI9111_AI_RESOLUTION_2_CMP_BIT;
+ }
+}
+
+/* ------------------------------------------------------------------ */
+/* INTERRUPT SECTION */
+/* ------------------------------------------------------------------ */
+
+#undef INTERRUPT_DEBUG
+
+static irqreturn_t pci9111_interrupt(int irq, void *p_device PT_REGS_ARG)
+{
+ struct comedi_device *dev = p_device;
+ struct comedi_subdevice *subdevice = dev->read_subdev;
+ struct comedi_async *async;
+ unsigned long irq_flags;
+ unsigned char intcsr;
+
+ if (!dev->attached) {
+ /* Ignore interrupt before device fully attached. */
+ /* Might not even have allocated subdevices yet! */
+ return IRQ_NONE;
+ }
+
+ async = subdevice->async;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+
+ /* Check if we are source of interrupt */
+ intcsr = inb(dev_private->lcr_io_base +
+ PLX9050_REGISTER_INTERRUPT_CONTROL);
+ if (!(((intcsr & PLX9050_PCI_INTERRUPT_ENABLE) != 0)
+ && (((intcsr & (PLX9050_LINTI1_ENABLE |
+ PLX9050_LINTI1_STATUS))
+ ==
+ (PLX9050_LINTI1_ENABLE |
+ PLX9050_LINTI1_STATUS))
+ || ((intcsr & (PLX9050_LINTI2_ENABLE |
+ PLX9050_LINTI2_STATUS))
+ ==
+ (PLX9050_LINTI2_ENABLE |
+ PLX9050_LINTI2_STATUS))))) {
+ /* Not the source of the interrupt. */
+ /* (N.B. not using PLX9050_SOFTWARE_INTERRUPT) */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ return IRQ_NONE;
+ }
+
+ if ((intcsr & (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) ==
+ (PLX9050_LINTI1_ENABLE | PLX9050_LINTI1_STATUS)) {
+ /* Interrupt comes from fifo_half-full signal */
+
+ if (pci9111_is_fifo_full()) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock,
+ irq_flags);
+ comedi_error(dev, PCI9111_DRIVER_NAME " fifo overflow");
+ pci9111_interrupt_clear();
+ pci9111_ai_cancel(dev, subdevice);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, subdevice);
+
+ return IRQ_HANDLED;
+ }
+
+ if (pci9111_is_fifo_half_full()) {
+ unsigned int num_samples;
+ unsigned int bytes_written = 0;
+
+#ifdef INTERRUPT_DEBUG
+ printk(PCI9111_DRIVER_NAME ": fifo is half full\n");
+#endif
+
+ num_samples =
+ PCI9111_FIFO_HALF_SIZE >
+ dev_private->stop_counter
+ && !dev_private->stop_is_none ? dev_private->
+ stop_counter : PCI9111_FIFO_HALF_SIZE;
+ insw(PCI9111_IO_BASE + PCI9111_REGISTER_AD_FIFO_VALUE,
+ dev_private->ai_bounce_buffer, num_samples);
+
+ if (dev_private->scan_delay < 1) {
+ bytes_written =
+ cfc_write_array_to_buffer(subdevice,
+ dev_private->ai_bounce_buffer,
+ num_samples * sizeof(short));
+ } else {
+ int position = 0;
+ int to_read;
+
+ while (position < num_samples) {
+ if (dev_private->chunk_counter <
+ dev_private->chanlist_len) {
+ to_read =
+ dev_private->
+ chanlist_len -
+ dev_private->
+ chunk_counter;
+
+ if (to_read >
+ num_samples - position)
+ to_read =
+ num_samples -
+ position;
+
+ bytes_written +=
+ cfc_write_array_to_buffer
+ (subdevice,
+ dev_private->
+ ai_bounce_buffer +
+ position,
+ to_read *
+ sizeof(short));
+ } else {
+ to_read =
+ dev_private->
+ chunk_num_samples -
+ dev_private->
+ chunk_counter;
+ if (to_read >
+ num_samples - position)
+ to_read =
+ num_samples -
+ position;
+
+ bytes_written +=
+ sizeof(short) *
+ to_read;
+ }
+
+ position += to_read;
+ dev_private->chunk_counter += to_read;
+
+ if (dev_private->chunk_counter >=
+ dev_private->chunk_num_samples)
+ dev_private->chunk_counter = 0;
+ }
+ }
+
+ dev_private->stop_counter -=
+ bytes_written / sizeof(short);
+ }
+ }
+
+ if ((dev_private->stop_counter == 0) && (!dev_private->stop_is_none)) {
+ async->events |= COMEDI_CB_EOA;
+ pci9111_ai_cancel(dev, subdevice);
+ }
+
+ /* Very important, otherwise another interrupt request will be inserted
+ * and will cause driver hangs on processing interrupt event. */
+
+ pci9111_interrupt_clear();
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ comedi_event(dev, subdevice);
+
+ return IRQ_HANDLED;
+}
+
+/* ------------------------------------------------------------------ */
+/* INSTANT ANALOG INPUT OUTPUT SECTION */
+/* ------------------------------------------------------------------ */
+
+/* analog instant input */
+
+#undef AI_INSN_DEBUG
+
+static int pci9111_ai_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+ int resolution =
+ ((struct pci9111_board *) dev->board_ptr)->ai_resolution;
+
+ int timeout, i;
+
+#ifdef AI_INSN_DEBUG
+ printk(PCI9111_DRIVER_NAME ": ai_insn set c/r/n = %2x/%2x/%2x\n",
+ CR_CHAN((&insn->chanspec)[0]),
+ CR_RANGE((&insn->chanspec)[0]), insn->n);
+#endif
+
+ pci9111_ai_channel_set(CR_CHAN((&insn->chanspec)[0]));
+
+ if ((pci9111_ai_range_get()) != CR_RANGE((&insn->chanspec)[0])) {
+ pci9111_ai_range_set(CR_RANGE((&insn->chanspec)[0]));
+ }
+
+ pci9111_fifo_reset();
+
+ for (i = 0; i < insn->n; i++) {
+ pci9111_software_trigger();
+
+ timeout = PCI9111_AI_INSTANT_READ_TIMEOUT;
+
+ while (timeout--) {
+ if (!pci9111_is_fifo_empty())
+ goto conversion_done;
+ }
+
+ comedi_error(dev, "A/D read timeout");
+ data[i] = 0;
+ pci9111_fifo_reset();
+ return -ETIME;
+
+ conversion_done:
+
+ if (resolution == PCI9111_HR_AI_RESOLUTION) {
+ data[i] = pci9111_hr_ai_get_data();
+ } else {
+ data[i] = pci9111_ai_get_data();
+ }
+ }
+
+#ifdef AI_INSN_DEBUG
+ printk(PCI9111_DRIVER_NAME ": ai_insn get c/r/t = %2x/%2x/%2x\n",
+ pci9111_ai_channel_get(),
+ pci9111_ai_range_get(), pci9111_trigger_and_autoscan_get());
+#endif
+
+ return i;
+}
+
+/* Analog instant output */
+
+static int
+pci9111_ao_insn_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ pci9111_ao_set_data(data[i]);
+ dev_private->ao_readback = data[i];
+ }
+
+ return i;
+}
+
+/* Analog output readback */
+
+static int pci9111_ao_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = dev_private->ao_readback & PCI9111_AO_RESOLUTION_MASK;
+ }
+
+ return i;
+}
+
+/* ------------------------------------------------------------------ */
+/* DIGITAL INPUT OUTPUT SECTION */
+/* ------------------------------------------------------------------ */
+
+/* Digital inputs */
+
+static int pci9111_di_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = pci9111_di_get_bits();
+ data[1] = bits;
+
+ return 2;
+}
+
+/* Digital outputs */
+
+static int pci9111_do_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * subdevice, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ /* Only set bits that have been masked */
+ /* data[0] = mask */
+ /* data[1] = bit state */
+
+ data[0] &= PCI9111_DO_MASK;
+
+ bits = subdevice->state;
+ bits &= ~data[0];
+ bits |= data[0] & data[1];
+ subdevice->state = bits;
+
+ pci9111_do_set_bits(bits);
+
+ data[1] = bits;
+
+ return 2;
+}
+
+/* ------------------------------------------------------------------ */
+/* INITIALISATION SECTION */
+/* ------------------------------------------------------------------ */
+
+/* Reset device */
+
+static int pci9111_reset(struct comedi_device * dev)
+{
+ /* Set trigger source to software */
+
+ plx9050_interrupt_control(dev_private->lcr_io_base, true, true, true,
+ true, false);
+
+ pci9111_trigger_source_set(dev, software);
+ pci9111_pretrigger_set(dev, false);
+ pci9111_autoscan_set(dev, false);
+
+ /* Reset 8254 chip */
+
+ dev_private->timer_divisor_1 = 0;
+ dev_private->timer_divisor_2 = 0;
+
+ pci9111_timer_set(dev);
+
+ return 0;
+}
+
+/* Attach */
+/* - Register PCI device */
+/* - Declare device driver capability */
+
+static int pci9111_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *subdevice;
+ unsigned long io_base, io_range, lcr_io_base, lcr_io_range;
+ struct pci_dev *pci_device;
+ int error, i;
+ const struct pci9111_board *board;
+
+ if (alloc_private(dev, sizeof(struct pci9111_private_data)) < 0) {
+ return -ENOMEM;
+ }
+ /* Probe the device to determine what device in the series it is. */
+
+ printk("comedi%d: " PCI9111_DRIVER_NAME " driver\n", dev->minor);
+
+ for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_device != NULL;
+ pci_device =
+ pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+ if (pci_device->vendor == PCI_VENDOR_ID_ADLINK) {
+ for (i = 0; i < pci9111_board_nbr; i++) {
+ if (pci9111_boards[i].device_id ==
+ pci_device->device) {
+ /* was a particular bus/slot requested? */
+ if ((it->options[0] != 0)
+ || (it->options[1] != 0)) {
+ /* are we on the wrong bus/slot? */
+ if (pci_device->bus->number !=
+ it->options[0]
+ || PCI_SLOT(pci_device->
+ devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+
+ dev->board_ptr = pci9111_boards + i;
+ board = (struct pci9111_board *) dev->
+ board_ptr;
+ dev_private->pci_device = pci_device;
+ goto found;
+ }
+ }
+ }
+ }
+
+ printk("comedi%d: no supported board found! (req. bus/slot : %d/%d)\n",
+ dev->minor, it->options[0], it->options[1]);
+ return -EIO;
+
+ found:
+
+ printk("comedi%d: found %s (b:s:f=%d:%d:%d) , irq=%d\n",
+ dev->minor,
+ pci9111_boards[i].name,
+ pci_device->bus->number,
+ PCI_SLOT(pci_device->devfn),
+ PCI_FUNC(pci_device->devfn), pci_device->irq);
+
+ /* TODO: Warn about non-tested boards. */
+
+ switch (board->device_id) {
+ };
+
+ /* Read local configuration register base address [PCI_BASE_ADDRESS #1]. */
+
+ lcr_io_base = pci_resource_start(pci_device, 1);
+ lcr_io_range = pci_resource_len(pci_device, 1);
+
+ printk("comedi%d: local configuration registers at address 0x%4lx [0x%4lx]\n", dev->minor, lcr_io_base, lcr_io_range);
+
+ /* Enable PCI device and request regions */
+ if (comedi_pci_enable(pci_device, PCI9111_DRIVER_NAME) < 0) {
+ printk("comedi%d: Failed to enable PCI device and request regions\n", dev->minor);
+ return -EIO;
+ }
+ /* Read PCI6308 register base address [PCI_BASE_ADDRESS #2]. */
+
+ io_base = pci_resource_start(pci_device, 2);
+ io_range = pci_resource_len(pci_device, 2);
+
+ printk("comedi%d: 6503 registers at address 0x%4lx [0x%4lx]\n",
+ dev->minor, io_base, io_range);
+
+ dev->iobase = io_base;
+ dev->board_name = board->name;
+ dev_private->io_range = io_range;
+ dev_private->is_valid = 0;
+ dev_private->lcr_io_base = lcr_io_base;
+ dev_private->lcr_io_range = lcr_io_range;
+
+ pci9111_reset(dev);
+
+ /* Irq setup */
+
+ dev->irq = 0;
+ if (pci_device->irq > 0) {
+ if (comedi_request_irq(pci_device->irq,
+ pci9111_interrupt,
+ IRQF_SHARED, PCI9111_DRIVER_NAME, dev) != 0) {
+ printk("comedi%d: unable to allocate irq %u\n",
+ dev->minor, pci_device->irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = pci_device->irq;
+
+ /* TODO: Add external multiplexer setup (according to option[2]). */
+
+ if ((error = alloc_subdevices(dev, 4)) < 0)
+ return error;
+
+ subdevice = dev->subdevices + 0;
+ dev->read_subdev = subdevice;
+
+ subdevice->type = COMEDI_SUBD_AI;
+ subdevice->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_CMD_READ;
+
+ /* TODO: Add external multiplexer data */
+ /* if (devpriv->usemux) { subdevice->n_chan = devpriv->usemux; } */
+ /* else { subdevice->n_chan = this_board->n_aichan; } */
+
+ subdevice->n_chan = board->ai_channel_nbr;
+ subdevice->maxdata = board->ai_resolution_mask;
+ subdevice->len_chanlist = board->ai_channel_nbr;
+ subdevice->range_table = board->ai_range_list;
+ subdevice->cancel = pci9111_ai_cancel;
+ subdevice->insn_read = pci9111_ai_insn_read;
+ subdevice->do_cmdtest = pci9111_ai_do_cmd_test;
+ subdevice->do_cmd = pci9111_ai_do_cmd;
+ subdevice->munge = pci9111_ai_munge;
+
+ subdevice = dev->subdevices + 1;
+ subdevice->type = COMEDI_SUBD_AO;
+ subdevice->subdev_flags = SDF_WRITABLE | SDF_COMMON;
+ subdevice->n_chan = board->ao_channel_nbr;
+ subdevice->maxdata = board->ao_resolution_mask;
+ subdevice->len_chanlist = board->ao_channel_nbr;
+ subdevice->range_table = board->ao_range_list;
+ subdevice->insn_write = pci9111_ao_insn_write;
+ subdevice->insn_read = pci9111_ao_insn_read;
+
+ subdevice = dev->subdevices + 2;
+ subdevice->type = COMEDI_SUBD_DI;
+ subdevice->subdev_flags = SDF_READABLE;
+ subdevice->n_chan = PCI9111_DI_CHANNEL_NBR;
+ subdevice->maxdata = 1;
+ subdevice->range_table = &range_digital;
+ subdevice->insn_bits = pci9111_di_insn_bits;
+
+ subdevice = dev->subdevices + 3;
+ subdevice->type = COMEDI_SUBD_DO;
+ subdevice->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ subdevice->n_chan = PCI9111_DO_CHANNEL_NBR;
+ subdevice->maxdata = 1;
+ subdevice->range_table = &range_digital;
+ subdevice->insn_bits = pci9111_do_insn_bits;
+
+ dev_private->is_valid = 1;
+
+ return 0;
+}
+
+/* Detach */
+
+static int pci9111_detach(struct comedi_device * dev)
+{
+ /* Reset device */
+
+ if (dev->private != 0) {
+ if (dev_private->is_valid)
+ pci9111_reset(dev);
+
+ }
+ /* Release previously allocated irq */
+
+ if (dev->irq != 0) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if (dev_private != 0 && dev_private->pci_device != 0) {
+ if (dev->iobase) {
+ comedi_pci_disable(dev_private->pci_device);
+ }
+ pci_dev_put(dev_private->pci_device);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/adl_pci9118.c b/drivers/staging/comedi/drivers/adl_pci9118.c
new file mode 100644
index 00000000000..278cf30cc4a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adl_pci9118.c
@@ -0,0 +1,2100 @@
+/*
+ * comedi/drivers/adl_pci9118.c
+ *
+ * hardware driver for ADLink cards:
+ * card: PCI-9118DG, PCI-9118HG, PCI-9118HR
+ * driver: pci9118dg, pci9118hg, pci9118hr
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+*/
+/*
+Driver: adl_pci9118
+Description: Adlink PCI-9118DG, PCI-9118HG, PCI-9118HR
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [ADLink] PCI-9118DG (pci9118dg), PCI-9118HG (pci9118hg),
+ PCI-9118HR (pci9118hr)
+Status: works
+
+This driver supports AI, AO, DI and DO subdevices.
+AI subdevice supports cmd and insn interface,
+other subdevices support only insn interface.
+For AI:
+- If cmd->scan_begin_src=TRIG_EXT then trigger input is TGIN (pin 46).
+- If cmd->convert_src=TRIG_EXT then trigger input is EXTTRG (pin 44).
+- If cmd->start_src/stop_src=TRIG_EXT then trigger input is TGIN (pin 46).
+- It is not neccessary to have cmd.scan_end_arg=cmd.chanlist_len but
+ cmd.scan_end_arg modulo cmd.chanlist_len must by 0.
+- If return value of cmdtest is 5 then you've bad channel list
+ (it isn't possible mixture S.E. and DIFF inputs or bipolar and unipolar
+ ranges).
+
+There are some hardware limitations:
+a) You cann't use mixture of unipolar/bipoar ranges or differencial/single
+ ended inputs.
+b) DMA transfers must have the length aligned to two samples (32 bit),
+ so there is some problems if cmd->chanlist_len is odd. This driver tries
+ bypass this with adding one sample to the end of the every scan and discard
+ it on output but this cann't be used if cmd->scan_begin_src=TRIG_FOLLOW
+ and is used flag TRIG_WAKE_EOS, then driver switch to interrupt driven mode
+ with interrupt after every sample.
+c) If isn't used DMA then you can use only mode where
+ cmd->scan_begin_src=TRIG_FOLLOW.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, then first available PCI
+ card will be used.
+ [2] - 0= standard 8 DIFF/16 SE channels configuration
+ n= external multiplexer connected, 1<=n<=256
+ [3] - 0=autoselect DMA or EOC interrupts operation
+ 1=disable DMA mode
+ 3=disable DMA and INT, only insn interface will work
+ [4] - sample&hold signal - card can generate signal for external S&H board
+ 0=use SSHO (pin 45) signal is generated in onboard hardware S&H logic
+ 0!=use ADCHN7 (pin 23) signal is generated from driver, number
+ say how long delay is requested in ns and sign polarity of the hold
+ (in this case external multiplexor can serve only 128 channels)
+ [5] - 0=stop measure on all hardware errors
+ 2|=ignore ADOR - A/D Overrun status
+ 8|=ignore Bover - A/D Burst Mode Overrun status
+ 256|=ignore nFull - A/D FIFO Full status
+
+*/
+#include "../comedidev.h"
+#include "../pci_ids.h"
+
+#include <linux/delay.h>
+
+#include "amcc_s5933.h"
+#include "8253.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+/* paranoid checks are broken */
+#undef PCI9118_PARANOIDCHECK /* if defined, then is used code which control correct channel number on every 12 bit sample */
+
+#undef PCI9118_EXTDEBUG /* if defined then driver prints a lot of messages */
+
+#undef DPRINTK
+#ifdef PCI9118_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#define IORANGE_9118 64 /* I hope */
+#define PCI9118_CHANLEN 255 /* len of chanlist, some source say 256, but reality looks like 255 :-( */
+
+#define PCI9118_CNT0 0x00 /* R/W: 8254 couter 0 */
+#define PCI9118_CNT1 0x04 /* R/W: 8254 couter 0 */
+#define PCI9118_CNT2 0x08 /* R/W: 8254 couter 0 */
+#define PCI9118_CNTCTRL 0x0c /* W: 8254 counter control */
+#define PCI9118_AD_DATA 0x10 /* R: A/D data */
+#define PCI9118_DA1 0x10 /* W: D/A registers */
+#define PCI9118_DA2 0x14
+#define PCI9118_ADSTAT 0x18 /* R: A/D status register */
+#define PCI9118_ADCNTRL 0x18 /* W: A/D control register */
+#define PCI9118_DI 0x1c /* R: digi input register */
+#define PCI9118_DO 0x1c /* W: digi output register */
+#define PCI9118_SOFTTRG 0x20 /* W: soft trigger for A/D */
+#define PCI9118_GAIN 0x24 /* W: A/D gain/channel register */
+#define PCI9118_BURST 0x28 /* W: A/D burst number register */
+#define PCI9118_SCANMOD 0x2c /* W: A/D auto scan mode */
+#define PCI9118_ADFUNC 0x30 /* W: A/D function register */
+#define PCI9118_DELFIFO 0x34 /* W: A/D data FIFO reset */
+#define PCI9118_INTSRC 0x38 /* R: interrupt reason register */
+#define PCI9118_INTCTRL 0x38 /* W: interrupt control register */
+
+// bits from A/D control register (PCI9118_ADCNTRL)
+#define AdControl_UniP 0x80 /* 1=bipolar, 0=unipolar */
+#define AdControl_Diff 0x40 /* 1=differential, 0= single end inputs */
+#define AdControl_SoftG 0x20 /* 1=8254 counter works, 0=counter stops */
+#define AdControl_ExtG 0x10 /* 1=8254 countrol controlled by TGIN(pin 46), 0=controled by SoftG */
+#define AdControl_ExtM 0x08 /* 1=external hardware trigger (pin 44), 0=internal trigger */
+#define AdControl_TmrTr 0x04 /* 1=8254 is iternal trigger source, 0=software trigger is source (register PCI9118_SOFTTRG) */
+#define AdControl_Int 0x02 /* 1=enable INT, 0=disable */
+#define AdControl_Dma 0x01 /* 1=enable DMA, 0=disable */
+
+// bits from A/D function register (PCI9118_ADFUNC)
+#define AdFunction_PDTrg 0x80 /* 1=positive, 0=negative digital trigger (only positive is correct) */
+#define AdFunction_PETrg 0x40 /* 1=positive, 0=negative external trigger (only positive is correct) */
+#define AdFunction_BSSH 0x20 /* 1=with sample&hold, 0=without */
+#define AdFunction_BM 0x10 /* 1=burst mode, 0=normal mode */
+#define AdFunction_BS 0x08 /* 1=burst mode start, 0=burst mode stop */
+#define AdFunction_PM 0x04 /* 1=post trigger mode, 0=not post trigger */
+#define AdFunction_AM 0x02 /* 1=about trigger mode, 0=not about trigger */
+#define AdFunction_Start 0x01 /* 1=trigger start, 0=trigger stop */
+
+// bits from A/D status register (PCI9118_ADSTAT)
+#define AdStatus_nFull 0x100 /* 0=FIFO full (fatal), 1=not full */
+#define AdStatus_nHfull 0x080 /* 0=FIFO half full, 1=FIFO not half full */
+#define AdStatus_nEpty 0x040 /* 0=FIFO empty, 1=FIFO not empty */
+#define AdStatus_Acmp 0x020 /* */
+#define AdStatus_DTH 0x010 /* 1=external digital trigger */
+#define AdStatus_Bover 0x008 /* 1=burst mode overrun (fatal) */
+#define AdStatus_ADOS 0x004 /* 1=A/D over speed (warning) */
+#define AdStatus_ADOR 0x002 /* 1=A/D overrun (fatal) */
+#define AdStatus_ADrdy 0x001 /* 1=A/D already ready, 0=not ready */
+
+// bits for interrupt reason and control (PCI9118_INTSRC, PCI9118_INTCTRL)
+// 1=interrupt occur, enable source, 0=interrupt not occur, disable source
+#define Int_Timer 0x08 /* timer interrupt */
+#define Int_About 0x04 /* about trigger complete */
+#define Int_Hfull 0x02 /* A/D FIFO hlaf full */
+#define Int_DTrg 0x01 /* external digital trigger */
+
+#define START_AI_EXT 0x01 /* start measure on external trigger */
+#define STOP_AI_EXT 0x02 /* stop measure on external trigger */
+#define START_AI_INT 0x04 /* start measure on internal trigger */
+#define STOP_AI_INT 0x08 /* stop measure on internal trigger */
+
+#define EXTTRG_AI 0 /* ext trg is used by AI */
+
+static const struct comedi_lrange range_pci9118dg_hr = { 8, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+static const struct comedi_lrange range_pci9118hg = { 8, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+};
+
+#define PCI9118_BIPOLAR_RANGES 4 /* used for test on mixture of BIP/UNI ranges */
+
+static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci9118_detach(struct comedi_device * dev);
+
+struct boardtype {
+ const char *name; // board name
+ int vendor_id; // PCI vendor a device ID of card
+ int device_id;
+ int iorange_amcc; // iorange for own S5933 region
+ int iorange_9118; // pass thru card region size
+ int n_aichan; // num of A/D chans
+ int n_aichand; // num of A/D chans in diff mode
+ int mux_aichan; // num of A/D chans with external multiplexor
+ int n_aichanlist; // len of chanlist
+ int n_aochan; // num of D/A chans
+ int ai_maxdata; // resolution of A/D
+ int ao_maxdata; // resolution of D/A
+ const struct comedi_lrange *rangelist_ai; // rangelist for A/D
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+ unsigned int ai_ns_min; // max sample speed of card v ns
+ unsigned int ai_pacer_min; // minimal pacer value (c1*c2 or c1 in burst)
+ int half_fifo_size; // size of FIFO/2
+
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci9118_pci_table) = {
+ {PCI_VENDOR_ID_AMCC, 0x80d9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci9118_pci_table);
+
+static const struct boardtype boardtypes[] = {
+ {"pci9118dg", PCI_VENDOR_ID_AMCC, 0x80d9,
+ AMCC_OP_REG_SIZE, IORANGE_9118,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
+ &range_pci9118dg_hr, &range_bipolar10,
+ 3000, 12, 512},
+ {"pci9118hg", PCI_VENDOR_ID_AMCC, 0x80d9,
+ AMCC_OP_REG_SIZE, IORANGE_9118,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0x0fff, 0x0fff,
+ &range_pci9118hg, &range_bipolar10,
+ 3000, 12, 512},
+ {"pci9118hr", PCI_VENDOR_ID_AMCC, 0x80d9,
+ AMCC_OP_REG_SIZE, IORANGE_9118,
+ 16, 8, 256, PCI9118_CHANLEN, 2, 0xffff, 0x0fff,
+ &range_pci9118dg_hr, &range_bipolar10,
+ 10000, 40, 512},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+
+static struct comedi_driver driver_pci9118 = {
+ driver_name:"adl_pci9118",
+ module:THIS_MODULE,
+ attach:pci9118_attach,
+ detach:pci9118_detach,
+ num_names:n_boardtypes,
+ board_name:&boardtypes[0].name,
+ offset:sizeof(struct boardtype),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pci9118, pci9118_pci_table);
+
+struct pci9118_private {
+ unsigned long iobase_a; // base+size for AMCC chip
+ unsigned int master; // master capable
+ struct pci_dev *pcidev; // ptr to actual pcidev
+ unsigned int usemux; // we want to use external multiplexor!
+#ifdef PCI9118_PARANOIDCHECK
+ unsigned short chanlist[PCI9118_CHANLEN + 1]; // list of scaned channel
+ unsigned char chanlistlen; // number of scanlist
+#endif
+ unsigned char AdControlReg; // A/D control register
+ unsigned char IntControlReg; // Interrupt control register
+ unsigned char AdFunctionReg; // A/D function register
+ char valid; // driver is ok
+ char ai_neverending; // we do unlimited AI
+ unsigned int i8254_osc_base; // frequence of onboard oscilator
+ unsigned int ai_do; // what do AI? 0=nothing, 1 to 4 mode
+ unsigned int ai_act_scan; // how many scans we finished
+ unsigned int ai_buf_ptr; // data buffer ptr in samples
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int ai_n_scanlen; // len of actual scanlist
+ unsigned int ai_n_realscanlen; // what we must transfer for one outgoing scan include front/back adds
+ unsigned int ai_act_dmapos; // position in actual real stream
+ unsigned int ai_add_front; // how many channels we must add before scan to satisfy S&H?
+ unsigned int ai_add_back; // how many channels we must add before scan to satisfy DMA?
+ unsigned int *ai_chanlist; // actaul chanlist
+ unsigned int ai_timer1;
+ unsigned int ai_timer2;
+ unsigned int ai_flags;
+ char ai12_startstop; // measure can start/stop on external trigger
+ unsigned int ai_divisor1, ai_divisor2; // divisors for start of measure on external start
+ unsigned int ai_data_len;
+ short *ai_data;
+ short ao_data[2]; // data output buffer
+ unsigned int ai_scans; // number of scans to do
+ char dma_doublebuf; // we can use double buffring
+ unsigned int dma_actbuf; // which buffer is used now
+ short *dmabuf_virt[2]; // pointers to begin of DMA buffer
+ unsigned long dmabuf_hw[2]; // hw address of DMA buff
+ unsigned int dmabuf_size[2]; // size of dma buffer in bytes
+ unsigned int dmabuf_use_size[2]; // which size we may now used for transfer
+ unsigned int dmabuf_used_size[2]; // which size was trully used
+ unsigned int dmabuf_panic_size[2];
+ unsigned int dmabuf_samples[2]; // size in samples
+ int dmabuf_pages[2]; // number of pages in buffer
+ unsigned char cnt0_users; // bit field of 8254 CNT0 users (0-unused, 1-AO, 2-DI, 3-DO)
+ unsigned char exttrg_users; // bit field of external trigger users (0-AI, 1-AO, 2-DI, 3-DO)
+ unsigned int cnt0_divisor; // actual CNT0 divisor
+ void (*int_ai_func) (struct comedi_device *, struct comedi_subdevice *, unsigned short, unsigned int, unsigned short); // ptr to actual interrupt AI function
+ unsigned char ai16bits; // =1 16 bit card
+ unsigned char usedma; // =1 use DMA transfer and not INT
+ unsigned char useeoshandle; // =1 change WAKE_EOS DMA transfer to fit on every second
+ unsigned char usessh; // =1 turn on S&H support
+ int softsshdelay; // >0 use software S&H, numer is requested delay in ns
+ unsigned char softsshsample; // polarity of S&H signal in sample state
+ unsigned char softsshhold; // polarity of S&H signal in hold state
+ unsigned int ai_maskerr; // which warning was printed
+ unsigned int ai_maskharderr; // on which error bits stops
+ unsigned int ai_inttrig_start; // TRIG_INT for start
+};
+
+#define devpriv ((struct pci9118_private *)dev->private)
+#define this_board ((struct boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int frontadd, int backadd);
+static int setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
+ int usedma, char eoshandle);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+static int pci9118_reset(struct comedi_device * dev);
+static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source);
+static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source);
+static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci9118_calc_divisors(char mode, struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int *tim1, unsigned int *tim2,
+ unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
+ char usessh, unsigned int chnsshfront);
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_read_ai(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ int n, timeout;
+
+ devpriv->AdControlReg = AdControl_Int & 0xff;
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+
+ if (!setup_channel_list(dev, s, 1, &insn->chanspec, 0, 0, 0, 0, 0))
+ return -EINVAL;
+
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+
+ for (n = 0; n < insn->n; n++) {
+ outw(0, dev->iobase + PCI9118_SOFTTRG); /* start conversion */
+ comedi_udelay(2);
+ timeout = 100;
+ while (timeout--) {
+ if (inl(dev->iobase + PCI9118_ADSTAT) & AdStatus_ADrdy)
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+
+ comedi_error(dev, "A/D insn timeout");
+ data[n] = 0;
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ return -ETIME;
+
+ conv_finish:
+ if (devpriv->ai16bits) {
+ data[n] =
+ (inl(dev->iobase +
+ PCI9118_AD_DATA) & 0xffff) ^ 0x8000;
+ } else {
+ data[n] =
+ (inw(dev->iobase +
+ PCI9118_AD_DATA) >> 4) & 0xfff;
+ }
+ }
+
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ return n;
+
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chanreg, ch;
+
+ ch = CR_CHAN(insn->chanspec);
+ if (ch) {
+ chanreg = PCI9118_DA2;
+ } else {
+ chanreg = PCI9118_DA1;
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ outl(data[n], dev->iobase + chanreg);
+ devpriv->ao_data[ch] = data[n];
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (n = 0; n < insn->n; n++)
+ data[n] = devpriv->ao_data[chan];
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = inl(dev->iobase + PCI9118_DI) & 0xf;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outl(s->state & 0x0f, dev->iobase + PCI9118_DO);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_mode4_switch(struct comedi_device * dev)
+{
+ devpriv->AdFunctionReg =
+ AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+ outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 1) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ outl((devpriv->dmabuf_hw[1 - devpriv->dma_actbuf] >> 9) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ devpriv->AdFunctionReg |= AdFunction_Start;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+}
+
+static unsigned int defragment_dma_buffer(struct comedi_device * dev,
+ struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+ unsigned int i = 0, j = 0;
+ unsigned int start_pos = devpriv->ai_add_front,
+ stop_pos = devpriv->ai_add_front + devpriv->ai_n_chan;
+ unsigned int raw_scanlen = devpriv->ai_add_front + devpriv->ai_n_chan +
+ devpriv->ai_add_back;
+
+ for (i = 0; i < num_samples; i++) {
+ if (devpriv->ai_act_dmapos >= start_pos &&
+ devpriv->ai_act_dmapos < stop_pos) {
+ dma_buffer[j++] = dma_buffer[i];
+ }
+ devpriv->ai_act_dmapos++;
+ devpriv->ai_act_dmapos %= raw_scanlen;
+ }
+
+ return j;
+}
+
+/*
+==============================================================================
+*/
+static unsigned int move_block_from_dma(struct comedi_device * dev,
+ struct comedi_subdevice * s, short * dma_buffer, unsigned int num_samples)
+{
+ unsigned int num_bytes;
+
+ num_samples = defragment_dma_buffer(dev, s, dma_buffer, num_samples);
+ devpriv->ai_act_scan +=
+ (s->async->cur_chan + num_samples) / devpriv->ai_n_scanlen;
+ s->async->cur_chan += num_samples;
+ s->async->cur_chan %= devpriv->ai_n_scanlen;
+ num_bytes =
+ cfc_write_array_to_buffer(s, dma_buffer,
+ num_samples * sizeof(short));
+ if (num_bytes < num_samples * sizeof(short))
+ return -1;
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static char pci9118_decode_error_status(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned char m)
+{
+ if (m & 0x100) {
+ comedi_error(dev, "A/D FIFO Full status (Fatal Error!)");
+ devpriv->ai_maskerr &= ~0x100L;
+ }
+ if (m & 0x008) {
+ comedi_error(dev,
+ "A/D Burst Mode Overrun Status (Fatal Error!)");
+ devpriv->ai_maskerr &= ~0x008L;
+ }
+ if (m & 0x004) {
+ comedi_error(dev, "A/D Over Speed Status (Warning!)");
+ devpriv->ai_maskerr &= ~0x004L;
+ }
+ if (m & 0x002) {
+ comedi_error(dev, "A/D Overrun Status (Fatal Error!)");
+ devpriv->ai_maskerr &= ~0x002L;
+ }
+ if (m & devpriv->ai_maskharderr) {
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return 1;
+ }
+
+ return 0;
+}
+
+static void pci9118_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int start_chan_index)
+{
+ unsigned int i, num_samples = num_bytes / sizeof(short);
+ short *array = data;
+
+ for (i = 0; i < num_samples; i++) {
+ if (devpriv->usedma)
+ array[i] = be16_to_cpu(array[i]);
+ if (devpriv->ai16bits) {
+ array[i] ^= 0x8000;
+ } else {
+ array[i] = (array[i] >> 4) & 0x0fff;
+ }
+ }
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_onesample(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned short int_adstat, unsigned int int_amcc,
+ unsigned short int_daq)
+{
+ register short sampl;
+
+ s->async->events = 0;
+
+ if (int_adstat & devpriv->ai_maskerr)
+ if (pci9118_decode_error_status(dev, s, int_adstat))
+ return;
+
+ sampl = inw(dev->iobase + PCI9118_AD_DATA);
+
+#ifdef PCI9118_PARANOIDCHECK
+ if (devpriv->ai16bits == 0) {
+ if ((sampl & 0x000f) != devpriv->chanlist[s->async->cur_chan]) { // data dropout!
+ rt_printk
+ ("comedi: A/D SAMPL - data dropout: received channel %d, expected %d!\n",
+ sampl & 0x000f,
+ devpriv->chanlist[s->async->cur_chan]);
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return;
+ }
+ }
+#endif
+ cfc_write_to_buffer(s, sampl);
+ s->async->cur_chan++;
+ if (s->async->cur_chan >= devpriv->ai_n_scanlen) { /* one scan done */
+ s->async->cur_chan %= devpriv->ai_n_scanlen;
+ devpriv->ai_act_scan++;
+ if (!(devpriv->ai_neverending))
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pci9118_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ if (s->async->events)
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci9118_ai_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned short int_adstat, unsigned int int_amcc,
+ unsigned short int_daq)
+{
+ unsigned int next_dma_buf, samplesinbuf, sampls, m;
+
+ if (int_amcc & MASTER_ABORT_INT) {
+ comedi_error(dev, "AMCC IRQ - MASTER DMA ABORT!");
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return;
+ }
+
+ if (int_amcc & TARGET_ABORT_INT) {
+ comedi_error(dev, "AMCC IRQ - TARGET DMA ABORT!");
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ pci9118_ai_cancel(dev, s);
+ comedi_event(dev, s);
+ return;
+ }
+
+ if (int_adstat & devpriv->ai_maskerr)
+// if (int_adstat & 0x106)
+ if (pci9118_decode_error_status(dev, s, int_adstat))
+ return;
+
+ samplesinbuf = devpriv->dmabuf_use_size[devpriv->dma_actbuf] >> 1; // number of received real samples
+// DPRINTK("dma_actbuf=%d\n",devpriv->dma_actbuf);
+
+ if (devpriv->dma_doublebuf) { // switch DMA buffers if is used double buffering
+ next_dma_buf = 1 - devpriv->dma_actbuf;
+ outl(devpriv->dmabuf_hw[next_dma_buf],
+ devpriv->iobase_a + AMCC_OP_REG_MWAR);
+ outl(devpriv->dmabuf_use_size[next_dma_buf],
+ devpriv->iobase_a + AMCC_OP_REG_MWTC);
+ devpriv->dmabuf_used_size[next_dma_buf] =
+ devpriv->dmabuf_use_size[next_dma_buf];
+ if (devpriv->ai_do == 4)
+ interrupt_pci9118_ai_mode4_switch(dev);
+ }
+
+ if (samplesinbuf) {
+ m = devpriv->ai_data_len >> 1; // how many samples is to end of buffer
+// DPRINTK("samps=%d m=%d %d %d\n",samplesinbuf,m,s->async->buf_int_count,s->async->buf_int_ptr);
+ sampls = m;
+ move_block_from_dma(dev, s,
+ devpriv->dmabuf_virt[devpriv->dma_actbuf],
+ samplesinbuf);
+ m = m - sampls; // m= how many samples was transfered
+ }
+// DPRINTK("YYY\n");
+
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pci9118_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+
+ if (devpriv->dma_doublebuf) { // switch dma buffers
+ devpriv->dma_actbuf = 1 - devpriv->dma_actbuf;
+ } else { // restart DMA if is not used double buffering
+ outl(devpriv->dmabuf_hw[0],
+ devpriv->iobase_a + AMCC_OP_REG_MWAR);
+ outl(devpriv->dmabuf_use_size[0],
+ devpriv->iobase_a + AMCC_OP_REG_MWTC);
+ if (devpriv->ai_do == 4)
+ interrupt_pci9118_ai_mode4_switch(dev);
+ }
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pci9118(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned int int_daq = 0, int_amcc, int_adstat;
+
+ if (!dev->attached)
+ return IRQ_NONE; // not fully initialized
+
+ int_daq = inl(dev->iobase + PCI9118_INTSRC) & 0xf; // get IRQ reasons from card
+ int_amcc = inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR); // get INT register from AMCC chip
+
+// DPRINTK("INT daq=0x%01x amcc=0x%08x MWAR=0x%08x MWTC=0x%08x ADSTAT=0x%02x ai_do=%d\n", int_daq, int_amcc, inl(devpriv->iobase_a+AMCC_OP_REG_MWAR), inl(devpriv->iobase_a+AMCC_OP_REG_MWTC), inw(dev->iobase+PCI9118_ADSTAT)&0x1ff,devpriv->ai_do);
+
+ if ((!int_daq) && (!(int_amcc & ANY_S593X_INT)))
+ return IRQ_NONE; // interrupt from other source
+
+ outl(int_amcc | 0x00ff0000, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // shutdown IRQ reasons in AMCC
+
+ int_adstat = inw(dev->iobase + PCI9118_ADSTAT) & 0x1ff; // get STATUS register
+
+ if (devpriv->ai_do) {
+ if (devpriv->ai12_startstop)
+ if ((int_adstat & AdStatus_DTH) && (int_daq & Int_DTrg)) { // start stop of measure
+ if (devpriv->ai12_startstop & START_AI_EXT) {
+ devpriv->ai12_startstop &=
+ ~START_AI_EXT;
+ if (!(devpriv->ai12_startstop &
+ STOP_AI_EXT))
+ pci9118_exttrg_del(dev, EXTTRG_AI); // deactivate EXT trigger
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1, devpriv->ai_divisor2); // start pacer
+ outl(devpriv->AdControlReg,
+ dev->iobase + PCI9118_ADCNTRL);
+ } else {
+ if (devpriv->
+ ai12_startstop & STOP_AI_EXT) {
+ devpriv->ai12_startstop &=
+ ~STOP_AI_EXT;
+ pci9118_exttrg_del(dev, EXTTRG_AI); // deactivate EXT trigger
+ devpriv->ai_neverending = 0; //well, on next interrupt from DMA/EOC measure will stop
+ }
+ }
+ }
+
+ (devpriv->int_ai_func) (dev, dev->subdevices + 0, int_adstat,
+ int_amcc, int_daq);
+
+ }
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != devpriv->ai_inttrig_start)
+ return -EINVAL;
+
+ devpriv->ai12_startstop &= ~START_AI_INT;
+ s->async->inttrig = NULL;
+
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ if (devpriv->ai_do != 3) {
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+ devpriv->ai_divisor2);
+ devpriv->AdControlReg |= AdControl_SoftG;
+ }
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT | TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ if (devpriv->master) {
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT | TRIG_FOLLOW;
+ } else {
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ }
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ if (devpriv->master) {
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT | TRIG_NOW;
+ } else {
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ }
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE | TRIG_EXT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW &&
+ cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_INT &&
+ cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE &&
+ cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_INT && cmd->stop_src != TRIG_EXT) {
+ cmd->stop_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->start_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->start_src == TRIG_INT && cmd->scan_begin_src == TRIG_INT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if ((cmd->scan_begin_src & (TRIG_TIMER | TRIG_EXT)) &&
+ (!(cmd->convert_src & (TRIG_TIMER | TRIG_NOW)))) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_FOLLOW) &&
+ (!(cmd->convert_src & (TRIG_TIMER | TRIG_EXT)))) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_EXT && cmd->scan_begin_src == TRIG_EXT) {
+ cmd->stop_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_src & (TRIG_NOW | TRIG_EXT))
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src & (TRIG_FOLLOW | TRIG_EXT))
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_TIMER) &&
+ (cmd->convert_src == TRIG_TIMER) && (cmd->scan_end_arg == 1)) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ cmd->convert_arg = cmd->scan_begin_arg;
+ cmd->scan_begin_arg = 0;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER)
+ if (cmd->scan_begin_arg < this_board->ai_ns_min) {
+ cmd->scan_begin_arg = this_board->ai_ns_min;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_EXT)
+ if (cmd->scan_begin_arg) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ if (cmd->scan_end_arg > 65535) {
+ cmd->scan_end_arg = 65535;
+ err++;
+ }
+ }
+
+ if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW))
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_EXT)
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+
+ if (cmd->chanlist_len > this_board->n_aichanlist) {
+ cmd->chanlist_len = this_board->n_aichanlist;
+ err++;
+ }
+
+ if (cmd->scan_end_arg < cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if ((cmd->scan_end_arg % cmd->chanlist_len)) {
+ cmd->scan_end_arg =
+ cmd->chanlist_len * (cmd->scan_end_arg /
+ cmd->chanlist_len);
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+// rt_printk("S1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+// rt_printk("S2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ if (cmd->scan_begin_arg < this_board->ai_ns_min)
+ cmd->scan_begin_arg = this_board->ai_ns_min;
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (cmd->convert_src & (TRIG_TIMER | TRIG_NOW)) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+// rt_printk("s1 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER
+ && cmd->convert_src == TRIG_NOW) {
+ if (cmd->convert_arg == 0) {
+ if (cmd->scan_begin_arg <
+ this_board->ai_ns_min *
+ (cmd->scan_end_arg + 2)) {
+ cmd->scan_begin_arg =
+ this_board->ai_ns_min *
+ (cmd->scan_end_arg + 2);
+// rt_printk("s2 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ err++;
+ }
+ } else {
+ if (cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg *
+ cmd->chanlist_len;
+// rt_printk("s3 timer1=%u timer2=%u\n",cmd->scan_begin_arg,cmd->convert_arg);
+ err++;
+ }
+ }
+ }
+ }
+
+ if (err)
+ return 4;
+
+ if (cmd->chanlist)
+ if (!check_channel_list(dev, s, cmd->chanlist_len,
+ cmd->chanlist, 0, 0))
+ return 5; // incorrect channels list
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int Compute_and_setup_dma(struct comedi_device * dev)
+{
+ unsigned int dmalen0, dmalen1, i;
+
+ DPRINTK("adl_pci9118 EDBG: BGN: Compute_and_setup_dma()\n");
+ dmalen0 = devpriv->dmabuf_size[0];
+ dmalen1 = devpriv->dmabuf_size[1];
+ DPRINTK("1 dmalen0=%d dmalen1=%d ai_data_len=%d\n", dmalen0, dmalen1,
+ devpriv->ai_data_len);
+ // isn't output buff smaller that our DMA buff?
+ if (dmalen0 > (devpriv->ai_data_len)) {
+ dmalen0 = devpriv->ai_data_len & ~3L; // allign to 32bit down
+ }
+ if (dmalen1 > (devpriv->ai_data_len)) {
+ dmalen1 = devpriv->ai_data_len & ~3L; // allign to 32bit down
+ }
+ DPRINTK("2 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+
+ // we want wake up every scan?
+ if (devpriv->ai_flags & TRIG_WAKE_EOS) {
+ if (dmalen0 < (devpriv->ai_n_realscanlen << 1)) {
+ // uff, too short DMA buffer, disable EOS support!
+ devpriv->ai_flags &= (~TRIG_WAKE_EOS);
+ rt_printk
+ ("comedi%d: WAR: DMA0 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
+ dev->minor, dmalen0,
+ devpriv->ai_n_realscanlen << 1);
+ } else {
+ // short first DMA buffer to one scan
+ dmalen0 = devpriv->ai_n_realscanlen << 1;
+ DPRINTK("21 dmalen0=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen0, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
+ if (devpriv->useeoshandle)
+ dmalen0 += 2;
+ if (dmalen0 < 4) {
+ rt_printk
+ ("comedi%d: ERR: DMA0 buf len bug? (%d<4)\n",
+ dev->minor, dmalen0);
+ dmalen0 = 4;
+ }
+ }
+ }
+ if (devpriv->ai_flags & TRIG_WAKE_EOS) {
+ if (dmalen1 < (devpriv->ai_n_realscanlen << 1)) {
+ // uff, too short DMA buffer, disable EOS support!
+ devpriv->ai_flags &= (~TRIG_WAKE_EOS);
+ rt_printk
+ ("comedi%d: WAR: DMA1 buf too short, cann't support TRIG_WAKE_EOS (%d<%d)\n",
+ dev->minor, dmalen1,
+ devpriv->ai_n_realscanlen << 1);
+ } else {
+ // short second DMA buffer to one scan
+ dmalen1 = devpriv->ai_n_realscanlen << 1;
+ DPRINTK("22 dmalen1=%d ai_n_realscanlen=%d useeoshandle=%d\n", dmalen1, devpriv->ai_n_realscanlen, devpriv->useeoshandle);
+ if (devpriv->useeoshandle)
+ dmalen1 -= 2;
+ if (dmalen1 < 4) {
+ rt_printk
+ ("comedi%d: ERR: DMA1 buf len bug? (%d<4)\n",
+ dev->minor, dmalen1);
+ dmalen1 = 4;
+ }
+ }
+ }
+
+ DPRINTK("3 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+ // transfer without TRIG_WAKE_EOS
+ if (!(devpriv->ai_flags & TRIG_WAKE_EOS)) {
+ // if it's possible then allign DMA buffers to length of scan
+ i = dmalen0;
+ dmalen0 =
+ (dmalen0 / (devpriv->ai_n_realscanlen << 1)) *
+ (devpriv->ai_n_realscanlen << 1);
+ dmalen0 &= ~3L;
+ if (!dmalen0)
+ dmalen0 = i; // uff. very long scan?
+ i = dmalen1;
+ dmalen1 =
+ (dmalen1 / (devpriv->ai_n_realscanlen << 1)) *
+ (devpriv->ai_n_realscanlen << 1);
+ dmalen1 &= ~3L;
+ if (!dmalen1)
+ dmalen1 = i; // uff. very long scan?
+ // if measure isn't neverending then test, if it whole fits into one or two DMA buffers
+ if (!devpriv->ai_neverending) {
+ // fits whole measure into one DMA buffer?
+ if (dmalen0 >
+ ((devpriv->ai_n_realscanlen << 1) *
+ devpriv->ai_scans)) {
+ DPRINTK("3.0 ai_n_realscanlen=%d ai_scans=%d \n", devpriv->ai_n_realscanlen, devpriv->ai_scans);
+ dmalen0 =
+ (devpriv->ai_n_realscanlen << 1) *
+ devpriv->ai_scans;
+ DPRINTK("3.1 dmalen0=%d dmalen1=%d \n", dmalen0,
+ dmalen1);
+ dmalen0 &= ~3L;
+ } else { // fits whole measure into two DMA buffer?
+ if (dmalen1 >
+ ((devpriv->ai_n_realscanlen << 1) *
+ devpriv->ai_scans - dmalen0))
+ dmalen1 =
+ (devpriv->
+ ai_n_realscanlen << 1) *
+ devpriv->ai_scans - dmalen0;
+ DPRINTK("3.2 dmalen0=%d dmalen1=%d \n", dmalen0,
+ dmalen1);
+ dmalen1 &= ~3L;
+ }
+ }
+ }
+
+ DPRINTK("4 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+
+ // these DMA buffer size we'll be used
+ devpriv->dma_actbuf = 0;
+ devpriv->dmabuf_use_size[0] = dmalen0;
+ devpriv->dmabuf_use_size[1] = dmalen1;
+
+ DPRINTK("5 dmalen0=%d dmalen1=%d \n", dmalen0, dmalen1);
+#if 0
+ if (devpriv->ai_n_scanlen < this_board->half_fifo_size) {
+ devpriv->dmabuf_panic_size[0] =
+ (this_board->half_fifo_size / devpriv->ai_n_scanlen +
+ 1) * devpriv->ai_n_scanlen * sizeof(short);
+ devpriv->dmabuf_panic_size[1] =
+ (this_board->half_fifo_size / devpriv->ai_n_scanlen +
+ 1) * devpriv->ai_n_scanlen * sizeof(short);
+ } else {
+ devpriv->dmabuf_panic_size[0] =
+ (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[0];
+ devpriv->dmabuf_panic_size[1] =
+ (devpriv->ai_n_scanlen << 1) % devpriv->dmabuf_size[1];
+ }
+#endif
+
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); // stop DMA
+ outl(devpriv->dmabuf_hw[0], devpriv->iobase_a + AMCC_OP_REG_MWAR);
+ outl(devpriv->dmabuf_use_size[0], devpriv->iobase_a + AMCC_OP_REG_MWTC);
+ // init DMA transfer
+ outl(0x00000000 | AINT_WRITE_COMPL,
+ devpriv->iobase_a + AMCC_OP_REG_INTCSR);
+// outl(0x02000000|AINT_WRITE_COMPL, devpriv->iobase_a+AMCC_OP_REG_INTCSR);
+
+ outl(inl(devpriv->iobase_a +
+ AMCC_OP_REG_MCSR) | RESET_A2P_FLAGS | A2P_HI_PRIORITY |
+ EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_MCSR);
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | EN_A2P_TRANSFERS, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow bus mastering
+
+ DPRINTK("adl_pci9118 EDBG: END: Compute_and_setup_dma()\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_docmd_sampl(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_sampl(%d,) [%d]\n",
+ dev->minor, devpriv->ai_do);
+ switch (devpriv->ai_do) {
+ case 1:
+ devpriv->AdControlReg |= AdControl_TmrTr;
+ break;
+ case 2:
+ comedi_error(dev, "pci9118_ai_docmd_sampl() mode 2 bug!\n");
+ return -EIO;
+ case 3:
+ devpriv->AdControlReg |= AdControl_ExtM;
+ break;
+ case 4:
+ comedi_error(dev, "pci9118_ai_docmd_sampl() mode 4 bug!\n");
+ return -EIO;
+ default:
+ comedi_error(dev,
+ "pci9118_ai_docmd_sampl() mode number bug!\n");
+ return -EIO;
+ };
+
+ devpriv->int_ai_func = interrupt_pci9118_ai_onesample; //transfer function
+
+ if (devpriv->ai12_startstop)
+ pci9118_exttrg_add(dev, EXTTRG_AI); // activate EXT trigger
+
+ if ((devpriv->ai_do == 1) || (devpriv->ai_do == 2))
+ devpriv->IntControlReg |= Int_Timer;
+
+ devpriv->AdControlReg |= AdControl_Int;
+
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow INT in AMCC
+
+ if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ if (devpriv->ai_do != 3) {
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+ devpriv->ai_divisor2);
+ devpriv->AdControlReg |= AdControl_SoftG;
+ }
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ }
+
+ DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_docmd_sampl()\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_docmd_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma(%d,) [%d,%d]\n",
+ dev->minor, devpriv->ai_do, devpriv->usedma);
+ Compute_and_setup_dma(dev);
+
+ switch (devpriv->ai_do) {
+ case 1:
+ devpriv->AdControlReg |=
+ ((AdControl_TmrTr | AdControl_Dma) & 0xff);
+ break;
+ case 2:
+ devpriv->AdControlReg |=
+ ((AdControl_TmrTr | AdControl_Dma) & 0xff);
+ devpriv->AdFunctionReg =
+ AdFunction_PDTrg | AdFunction_PETrg | AdFunction_BM |
+ AdFunction_BS;
+ if (devpriv->usessh && (!devpriv->softsshdelay))
+ devpriv->AdFunctionReg |= AdFunction_BSSH;
+ outl(devpriv->ai_n_realscanlen, dev->iobase + PCI9118_BURST);
+ break;
+ case 3:
+ devpriv->AdControlReg |=
+ ((AdControl_ExtM | AdControl_Dma) & 0xff);
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ break;
+ case 4:
+ devpriv->AdControlReg |=
+ ((AdControl_TmrTr | AdControl_Dma) & 0xff);
+ devpriv->AdFunctionReg =
+ AdFunction_PDTrg | AdFunction_PETrg | AdFunction_AM;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+ outl((devpriv->dmabuf_hw[0] >> 1) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ outl((devpriv->dmabuf_hw[0] >> 9) & 0xff,
+ dev->iobase + PCI9118_CNT0);
+ devpriv->AdFunctionReg |= AdFunction_Start;
+ break;
+ default:
+ comedi_error(dev, "pci9118_ai_docmd_dma() mode number bug!\n");
+ return -EIO;
+ };
+
+ if (devpriv->ai12_startstop) {
+ pci9118_exttrg_add(dev, EXTTRG_AI); // activate EXT trigger
+ }
+
+ devpriv->int_ai_func = interrupt_pci9118_ai_dma; //transfer function
+
+ outl(0x02000000 | AINT_WRITE_COMPL,
+ devpriv->iobase_a + AMCC_OP_REG_INTCSR);
+
+ if (!(devpriv->ai12_startstop & (START_AI_EXT | START_AI_INT))) {
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ if (devpriv->ai_do != 3) {
+ start_pacer(dev, devpriv->ai_do, devpriv->ai_divisor1,
+ devpriv->ai_divisor2);
+ devpriv->AdControlReg |= AdControl_SoftG;
+ }
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+ }
+
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_docmd_dma()\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int addchans = 0;
+ int ret = 0;
+
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_ai_cmd(%d,)\n", dev->minor);
+ devpriv->ai12_startstop = 0;
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ devpriv->ai_n_scanlen = cmd->scan_end_arg;
+ devpriv->ai_chanlist = cmd->chanlist;
+ devpriv->ai_data = s->async->prealloc_buf;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_timer1 = 0;
+ devpriv->ai_timer2 = 0;
+ devpriv->ai_add_front = 0;
+ devpriv->ai_add_back = 0;
+ devpriv->ai_maskerr = 0x10e;
+
+ // prepare for start/stop conditions
+ if (cmd->start_src == TRIG_EXT)
+ devpriv->ai12_startstop |= START_AI_EXT;
+ if (cmd->stop_src == TRIG_EXT) {
+ devpriv->ai_neverending = 1;
+ devpriv->ai12_startstop |= STOP_AI_EXT;
+ }
+ if (cmd->start_src == TRIG_INT) {
+ devpriv->ai12_startstop |= START_AI_INT;
+ devpriv->ai_inttrig_start = cmd->start_arg;
+ s->async->inttrig = pci9118_ai_inttrig;
+ }
+#if 0
+ if (cmd->stop_src == TRIG_INT) {
+ devpriv->ai_neverending = 1;
+ devpriv->ai12_startstop |= STOP_AI_INT;
+ }
+#endif
+ if (cmd->stop_src == TRIG_NONE)
+ devpriv->ai_neverending = 1;
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ devpriv->ai_neverending = 0;
+ } else {
+ devpriv->ai_scans = 0;
+ }
+
+ // use sample&hold signal?
+ if (cmd->convert_src == TRIG_NOW) {
+ devpriv->usessh = 1;
+ } // yes
+ else {
+ devpriv->usessh = 0;
+ } // no
+
+ DPRINTK("1 neverending=%d scans=%u usessh=%d ai_startstop=0x%2x\n",
+ devpriv->ai_neverending, devpriv->ai_scans, devpriv->usessh,
+ devpriv->ai12_startstop);
+
+ // use additional sample at end of every scan to satisty DMA 32 bit transfer?
+ devpriv->ai_add_front = 0;
+ devpriv->ai_add_back = 0;
+ devpriv->useeoshandle = 0;
+ if (devpriv->master) {
+ devpriv->usedma = 1;
+ if ((cmd->flags & TRIG_WAKE_EOS) &&
+ (devpriv->ai_n_scanlen == 1)) {
+ if (cmd->convert_src == TRIG_NOW) {
+ devpriv->ai_add_back = 1;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ devpriv->usedma = 0; // use INT transfer if scanlist have only one channel
+ }
+ }
+ if ((cmd->flags & TRIG_WAKE_EOS) &&
+ (devpriv->ai_n_scanlen & 1) &&
+ (devpriv->ai_n_scanlen > 1)) {
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ //vpriv->useeoshandle=1; // change DMA transfer block to fit EOS on every second call
+ devpriv->usedma = 0; // XXX maybe can be corrected to use 16 bit DMA
+ } else { // well, we must insert one sample to end of EOS to meet 32 bit transfer
+ devpriv->ai_add_back = 1;
+ }
+ }
+ } else { // interrupt transfer don't need any correction
+ devpriv->usedma = 0;
+ }
+
+ // we need software S&H signal? It add two samples before every scan as minimum
+ if (devpriv->usessh && devpriv->softsshdelay) {
+ devpriv->ai_add_front = 2;
+ if ((devpriv->usedma == 1) && (devpriv->ai_add_back == 1)) { // move it to front
+ devpriv->ai_add_front++;
+ devpriv->ai_add_back = 0;
+ }
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ addchans = devpriv->softsshdelay / cmd->convert_arg;
+ if (devpriv->softsshdelay % cmd->convert_arg)
+ addchans++;
+ if (addchans > (devpriv->ai_add_front - 1)) { // uff, still short :-(
+ devpriv->ai_add_front = addchans + 1;
+ if (devpriv->usedma == 1)
+ if ((devpriv->ai_add_front +
+ devpriv->ai_n_chan +
+ devpriv->ai_add_back) & 1)
+ devpriv->ai_add_front++; // round up to 32 bit
+ }
+ } // well, we now know what must be all added
+
+ devpriv->ai_n_realscanlen = // what we must take from card in real to have ai_n_scanlen on output?
+ (devpriv->ai_add_front + devpriv->ai_n_chan +
+ devpriv->ai_add_back) * (devpriv->ai_n_scanlen /
+ devpriv->ai_n_chan);
+
+ DPRINTK("2 usedma=%d realscan=%d af=%u n_chan=%d ab=%d n_scanlen=%d\n",
+ devpriv->usedma,
+ devpriv->ai_n_realscanlen, devpriv->ai_add_front,
+ devpriv->ai_n_chan, devpriv->ai_add_back,
+ devpriv->ai_n_scanlen);
+
+ // check and setup channel list
+ if (!check_channel_list(dev, s, devpriv->ai_n_chan,
+ devpriv->ai_chanlist, devpriv->ai_add_front,
+ devpriv->ai_add_back))
+ return -EINVAL;
+ if (!setup_channel_list(dev, s, devpriv->ai_n_chan,
+ devpriv->ai_chanlist, 0, devpriv->ai_add_front,
+ devpriv->ai_add_back, devpriv->usedma,
+ devpriv->useeoshandle))
+ return -EINVAL;
+
+ // compute timers settings
+ // simplest way, fr=4Mhz/(tim1*tim2), channel manipulation without timers effect
+ if (((cmd->scan_begin_src == TRIG_FOLLOW) || (cmd->scan_begin_src == TRIG_EXT) || (cmd->scan_begin_src == TRIG_INT)) && (cmd->convert_src == TRIG_TIMER)) { // both timer is used for one time
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ devpriv->ai_do = 4;
+ } else {
+ devpriv->ai_do = 1;
+ }
+ pci9118_calc_divisors(devpriv->ai_do, dev, s,
+ &cmd->scan_begin_arg, &cmd->convert_arg,
+ devpriv->ai_flags, devpriv->ai_n_realscanlen,
+ &devpriv->ai_divisor1, &devpriv->ai_divisor2,
+ devpriv->usessh, devpriv->ai_add_front);
+ devpriv->ai_timer2 = cmd->convert_arg;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_TIMER) && ((cmd->convert_src == TRIG_TIMER) || (cmd->convert_src == TRIG_NOW))) { // double timed action
+ if (!devpriv->usedma) {
+ comedi_error(dev,
+ "cmd->scan_begin_src=TRIG_TIMER works only with bus mastering!");
+ return -EIO;
+ }
+
+ devpriv->ai_do = 2;
+ pci9118_calc_divisors(devpriv->ai_do, dev, s,
+ &cmd->scan_begin_arg, &cmd->convert_arg,
+ devpriv->ai_flags, devpriv->ai_n_realscanlen,
+ &devpriv->ai_divisor1, &devpriv->ai_divisor2,
+ devpriv->usessh, devpriv->ai_add_front);
+ devpriv->ai_timer1 = cmd->scan_begin_arg;
+ devpriv->ai_timer2 = cmd->convert_arg;
+ }
+
+ if ((cmd->scan_begin_src == TRIG_FOLLOW)
+ && (cmd->convert_src == TRIG_EXT)) {
+ devpriv->ai_do = 3;
+ }
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ devpriv->AdControlReg = 0; // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable DMA
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL);
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg; // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC);
+ comedi_udelay(1);
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ inl(dev->iobase + PCI9118_ADSTAT); // flush A/D and INT status register
+ inl(dev->iobase + PCI9118_INTSRC);
+
+ devpriv->ai_act_scan = 0;
+ devpriv->ai_act_dmapos = 0;
+ s->async->cur_chan = 0;
+ devpriv->ai_buf_ptr = 0;
+
+ if (devpriv->usedma) {
+ ret = pci9118_ai_docmd_dma(dev, s);
+ } else {
+ ret = pci9118_ai_docmd_sampl(dev, s);
+ }
+
+ DPRINTK("adl_pci9118 EDBG: END: pci9118_ai_cmd()\n");
+ return ret;
+}
+
+/*
+==============================================================================
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int frontadd, int backadd)
+{
+ unsigned int i, differencial = 0, bipolar = 0;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+ if ((frontadd + n_chan + backadd) > s->len_chanlist) {
+ rt_printk
+ ("comedi%d: range/channel list is too long for actual configuration (%d>%d)!",
+ dev->minor, n_chan,
+ s->len_chanlist - frontadd - backadd);
+ return 0;
+ }
+
+ if (CR_AREF(chanlist[0]) == AREF_DIFF)
+ differencial = 1; // all input must be diff
+ if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
+ bipolar = 1; // all input must be bipolar
+ if (n_chan > 1)
+ for (i = 1; i < n_chan; i++) { // check S.E/diff
+ if ((CR_AREF(chanlist[i]) == AREF_DIFF) !=
+ (differencial)) {
+ comedi_error(dev,
+ "Differencial and single ended inputs cann't be mixtured!");
+ return 0;
+ }
+ if ((CR_RANGE(chanlist[i]) < PCI9118_BIPOLAR_RANGES) !=
+ (bipolar)) {
+ comedi_error(dev,
+ "Bipolar and unipolar ranges cann't be mixtured!");
+ return 0;
+ }
+ if ((!devpriv->usemux) & (differencial) &
+ (CR_CHAN(chanlist[i]) >=
+ this_board->n_aichand)) {
+ comedi_error(dev,
+ "If AREF_DIFF is used then is available only first 8 channels!");
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n_chan, unsigned int *chanlist, int rot, int frontadd, int backadd,
+ int usedma, char useeos)
+{
+ unsigned int i, differencial = 0, bipolar = 0;
+ unsigned int scanquad, gain, ssh = 0x00;
+
+ DPRINTK("adl_pci9118 EDBG: BGN: setup_channel_list(%d,.,%d,.,%d,%d,%d,%d)\n", dev->minor, n_chan, rot, frontadd, backadd, usedma);
+
+ if (usedma == 1) {
+ rot = 8;
+ usedma = 0;
+ }
+
+ if (CR_AREF(chanlist[0]) == AREF_DIFF)
+ differencial = 1; // all input must be diff
+ if (CR_RANGE(chanlist[0]) < PCI9118_BIPOLAR_RANGES)
+ bipolar = 1; // all input must be bipolar
+
+ // All is ok, so we can setup channel/range list
+
+ if (!bipolar) {
+ devpriv->AdControlReg |= AdControl_UniP; // set unibipolar
+ } else {
+ devpriv->AdControlReg &= ((~AdControl_UniP) & 0xff); // enable bipolar
+ }
+
+ if (differencial) {
+ devpriv->AdControlReg |= AdControl_Diff; // enable diff inputs
+ } else {
+ devpriv->AdControlReg &= ((~AdControl_Diff) & 0xff); // set single ended inputs
+ }
+
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // setup mode
+
+ outl(2, dev->iobase + PCI9118_SCANMOD); // gods know why this sequence!
+ outl(0, dev->iobase + PCI9118_SCANMOD);
+ outl(1, dev->iobase + PCI9118_SCANMOD);
+
+#ifdef PCI9118_PARANOIDCHECK
+ devpriv->chanlistlen = n_chan;
+ for (i = 0; i < (PCI9118_CHANLEN + 1); i++)
+ devpriv->chanlist[i] = 0x55aa;
+#endif
+
+ if (frontadd) { // insert channels for S&H
+ ssh = devpriv->softsshsample;
+ DPRINTK("FA: %04x: ", ssh);
+ for (i = 0; i < frontadd; i++) { // store range list to card
+ scanquad = CR_CHAN(chanlist[0]); // get channel number;
+ gain = CR_RANGE(chanlist[0]); // get gain number
+ scanquad |= ((gain & 0x03) << 8);
+ outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+ DPRINTK("%02x ", scanquad | ssh);
+ ssh = devpriv->softsshhold;
+ }
+ DPRINTK("\n ");
+ }
+
+ DPRINTK("SL: ", ssh);
+ for (i = 0; i < n_chan; i++) { // store range list to card
+ scanquad = CR_CHAN(chanlist[i]); // get channel number;
+#ifdef PCI9118_PARANOIDCHECK
+ devpriv->chanlist[i ^ usedma] = (scanquad & 0xf) << rot;
+#endif
+ gain = CR_RANGE(chanlist[i]); // get gain number
+ scanquad |= ((gain & 0x03) << 8);
+ outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+ DPRINTK("%02x ", scanquad | ssh);
+ }
+ DPRINTK("\n ");
+
+ if (backadd) { // insert channels for fit onto 32bit DMA
+ DPRINTK("BA: %04x: ", ssh);
+ for (i = 0; i < backadd; i++) { // store range list to card
+ scanquad = CR_CHAN(chanlist[0]); // get channel number;
+ gain = CR_RANGE(chanlist[0]); // get gain number
+ scanquad |= ((gain & 0x03) << 8);
+ outl(scanquad | ssh, dev->iobase + PCI9118_GAIN);
+ DPRINTK("%02x ", scanquad | ssh);
+ }
+ DPRINTK("\n ");
+ }
+#ifdef PCI9118_PARANOIDCHECK
+ devpriv->chanlist[n_chan ^ usedma] = devpriv->chanlist[0 ^ usedma]; // for 32bit oerations
+ if (useeos) {
+ for (i = 1; i < n_chan; i++) { // store range list to card
+ devpriv->chanlist[(n_chan + i) ^ usedma] =
+ (CR_CHAN(chanlist[i]) & 0xf) << rot;
+ }
+ devpriv->chanlist[(2 * n_chan) ^ usedma] = devpriv->chanlist[0 ^ usedma]; // for 32bit oerations
+ useeos = 2;
+ } else {
+ useeos = 1;
+ }
+#ifdef PCI9118_EXTDEBUG
+ DPRINTK("CHL: ");
+ for (i = 0; i <= (useeos * n_chan); i++) {
+ DPRINTK("%04x ", devpriv->chanlist[i]);
+ }
+ DPRINTK("\n ");
+#endif
+#endif
+ outl(0, dev->iobase + PCI9118_SCANMOD); // close scan queue
+// comedi_udelay(100); // important delay, or first sample will be cripled
+
+ DPRINTK("adl_pci9118 EDBG: END: setup_channel_list()\n");
+ return 1; // we can serve this with scan logic
+}
+
+/*
+==============================================================================
+ calculate 8254 divisors if they are used for dual timing
+*/
+static void pci9118_calc_divisors(char mode, struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int *tim1, unsigned int *tim2,
+ unsigned int flags, int chans, unsigned int *div1, unsigned int *div2,
+ char usessh, unsigned int chnsshfront)
+{
+ DPRINTK("adl_pci9118 EDBG: BGN: pci9118_calc_divisors(%d,%d,.,%u,%u,%u,%d,.,.,,%u,%u)\n", mode, dev->minor, *tim1, *tim2, flags, chans, usessh, chnsshfront);
+ switch (mode) {
+ case 1:
+ case 4:
+ if (*tim2 < this_board->ai_ns_min)
+ *tim2 = this_board->ai_ns_min;
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, div1, div2,
+ tim2, flags & TRIG_ROUND_NEAREST);
+ DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u\n",
+ devpriv->i8254_osc_base, *div1, *div2, *tim1);
+ break;
+ case 2:
+ if (*tim2 < this_board->ai_ns_min)
+ *tim2 = this_board->ai_ns_min;
+ DPRINTK("1 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *div1 = *tim2 / devpriv->i8254_osc_base; // convert timer (burst)
+ DPRINTK("2 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ if (*div1 < this_board->ai_pacer_min)
+ *div1 = this_board->ai_pacer_min;
+ DPRINTK("3 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *div2 = *tim1 / devpriv->i8254_osc_base; // scan timer
+ DPRINTK("4 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *div2 = *div2 / *div1; // major timer is c1*c2
+ DPRINTK("5 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ if (*div2 < chans)
+ *div2 = chans;
+ DPRINTK("6 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+
+ *tim2 = *div1 * devpriv->i8254_osc_base; // real convert timer
+
+ if (usessh & (chnsshfront == 0)) // use BSSH signal
+ if (*div2 < (chans + 2))
+ *div2 = chans + 2;
+
+ DPRINTK("7 div1=%u div2=%u timer1=%u timer2=%u\n", *div1, *div2,
+ *tim1, *tim2);
+ *tim1 = *div1 * *div2 * devpriv->i8254_osc_base;
+ DPRINTK("OSC base=%u div1=%u div2=%u timer1=%u timer2=%u\n",
+ devpriv->i8254_osc_base, *div1, *div2, *tim1, *tim2);
+ break;
+ }
+ DPRINTK("adl_pci9118 EDBG: END: pci9118_calc_divisors(%u,%u)\n",
+ *div1, *div2);
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ outl(0x74, dev->iobase + PCI9118_CNTCTRL);
+ outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
+// outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+ comedi_udelay(1);
+
+ if ((mode == 1) || (mode == 2) || (mode == 4)) {
+ outl(divisor2 & 0xff, dev->iobase + PCI9118_CNT2);
+ outl((divisor2 >> 8) & 0xff, dev->iobase + PCI9118_CNT2);
+ outl(divisor1 & 0xff, dev->iobase + PCI9118_CNT1);
+ outl((divisor1 >> 8) & 0xff, dev->iobase + PCI9118_CNT1);
+ }
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_exttrg_add(struct comedi_device * dev, unsigned char source)
+{
+ if (source > 3)
+ return -1; // incorrect source
+ devpriv->exttrg_users |= (1 << source);
+ devpriv->IntControlReg |= Int_DTrg;
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow INT in AMCC
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_exttrg_del(struct comedi_device * dev, unsigned char source)
+{
+ if (source > 3)
+ return -1; // incorrect source
+ devpriv->exttrg_users &= ~(1 << source);
+ if (!devpriv->exttrg_users) { // shutdown ext trg intterrupts
+ devpriv->IntControlReg &= ~Int_DTrg;
+ if (!devpriv->IntControlReg) // all IRQ disabled
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) & (~0x00001f00), devpriv->iobase_a + AMCC_OP_REG_INTCSR); // disable int in AMCC
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL);
+ }
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (devpriv->usedma)
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_MCSR) & (~EN_A2P_TRANSFERS), devpriv->iobase_a + AMCC_OP_REG_MCSR); // stop DMA
+ pci9118_exttrg_del(dev, EXTTRG_AI);
+ start_pacer(dev, 0, 0, 0); // stop 8254 counters
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+ devpriv->AdControlReg = 0x00;
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+ outl(0, dev->iobase + PCI9118_BURST);
+ outl(1, dev->iobase + PCI9118_SCANMOD);
+ outl(2, dev->iobase + PCI9118_SCANMOD); // reset scan queue
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+
+ devpriv->ai_do = 0;
+ devpriv->usedma = 0;
+
+ devpriv->ai_act_scan = 0;
+ devpriv->ai_act_dmapos = 0;
+ s->async->cur_chan = 0;
+ s->async->inttrig = NULL;
+ devpriv->ai_buf_ptr = 0;
+ devpriv->ai_neverending = 0;
+ devpriv->dma_actbuf = 0;
+
+ if (!devpriv->IntControlReg)
+ outl(inl(devpriv->iobase_a + AMCC_OP_REG_INTCSR) | 0x1f00, devpriv->iobase_a + AMCC_OP_REG_INTCSR); // allow INT in AMCC
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_reset(struct comedi_device * dev)
+{
+ devpriv->IntControlReg = 0;
+ devpriv->exttrg_users = 0;
+ inl(dev->iobase + PCI9118_INTCTRL);
+ outl(devpriv->IntControlReg, dev->iobase + PCI9118_INTCTRL); // disable interrupts source
+ outl(0x30, dev->iobase + PCI9118_CNTCTRL);
+// outl(0xb4, dev->iobase + PCI9118_CNTCTRL);
+ start_pacer(dev, 0, 0, 0); // stop 8254 counters
+ devpriv->AdControlReg = 0;
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+ outl(0, dev->iobase + PCI9118_BURST);
+ outl(1, dev->iobase + PCI9118_SCANMOD);
+ outl(2, dev->iobase + PCI9118_SCANMOD); // reset scan queue
+ devpriv->AdFunctionReg = AdFunction_PDTrg | AdFunction_PETrg;
+ outl(devpriv->AdFunctionReg, dev->iobase + PCI9118_ADFUNC); // positive triggers, no S&H, no burst, burst stop, no post trigger, no about trigger, trigger stop
+
+ devpriv->ao_data[0] = 2047;
+ devpriv->ao_data[1] = 2047;
+ outl(devpriv->ao_data[0], dev->iobase + PCI9118_DA1); // reset A/D outs to 0V
+ outl(devpriv->ao_data[1], dev->iobase + PCI9118_DA2);
+ outl(0, dev->iobase + PCI9118_DO); // reset digi outs to L
+ comedi_udelay(10);
+ inl(dev->iobase + PCI9118_AD_DATA);
+ outl(0, dev->iobase + PCI9118_DELFIFO); // flush FIFO
+ outl(0, dev->iobase + PCI9118_INTSRC); // remove INT requests
+ inl(dev->iobase + PCI9118_ADSTAT); // flush A/D status register
+ inl(dev->iobase + PCI9118_INTSRC); // flush INT requests
+ devpriv->AdControlReg = 0;
+ outl(devpriv->AdControlReg, dev->iobase + PCI9118_ADCNTRL); // bipolar, S.E., use 8254, stop 8354, internal trigger, soft trigger, disable INT and DMA
+
+ devpriv->cnt0_users = 0;
+ devpriv->exttrg_users = 0;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, pages, i;
+ unsigned short master;
+ unsigned int irq;
+ unsigned long iobase_a, iobase_9;
+ struct pci_dev *pcidev;
+ int opt_bus, opt_slot;
+ const char *errstr;
+ unsigned char pci_bus, pci_slot, pci_func;
+ u16 u16w;
+
+ rt_printk("comedi%d: adl_pci9118: board=%s", dev->minor,
+ this_board->name);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+ if (it->options[3] & 1) {
+ master = 0; // user don't want use bus master
+ } else {
+ master = 1;
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct pci9118_private))) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ /* Look for matching PCI device */
+ errstr = "not found!";
+ pcidev = NULL;
+ while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_AMCC,
+ this_board->device_id, pcidev))) {
+ /* Found matching vendor/device. */
+ if (opt_bus || opt_slot) {
+ /* Check bus/slot. */
+ if (opt_bus != pcidev->bus->number
+ || opt_slot != PCI_SLOT(pcidev->devfn))
+ continue; /* no match */
+ }
+ /*
+ * Look for device that isn't in use.
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, "adl_pci9118")) {
+ errstr = "failed to enable PCI device and request regions!";
+ continue;
+ }
+ break;
+ }
+
+ if (!pcidev) {
+ if (opt_bus || opt_slot) {
+ rt_printk(" - Card at b:s %d:%d %s\n",
+ opt_bus, opt_slot, errstr);
+ } else {
+ rt_printk(" - Card %s\n", errstr);
+ }
+ return -EIO;
+ }
+
+ if (master) {
+ pci_set_master(pcidev);
+ }
+
+ pci_bus = pcidev->bus->number;
+ pci_slot = PCI_SLOT(pcidev->devfn);
+ pci_func = PCI_FUNC(pcidev->devfn);
+ irq = pcidev->irq;
+ iobase_a = pci_resource_start(pcidev, 0);
+ iobase_9 = pci_resource_start(pcidev, 2);
+
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx, 0x%4lx", pci_bus, pci_slot,
+ pci_func, iobase_9, iobase_a);
+
+ dev->iobase = iobase_9;
+ dev->board_name = this_board->name;
+
+ devpriv->pcidev = pcidev;
+ devpriv->iobase_a = iobase_a;
+
+ pci9118_reset(dev);
+
+ if (it->options[3] & 2)
+ irq = 0; // user don't want use IRQ
+ if (irq > 0) {
+ if (comedi_request_irq(irq, interrupt_pci9118, IRQF_SHARED,
+ "ADLink PCI-9118", dev)) {
+ rt_printk(", unable to allocate IRQ %d, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ } else {
+ rt_printk(", IRQ disabled");
+ }
+
+ dev->irq = irq;
+
+ if (master) { // alloc DMA buffers
+ devpriv->dma_doublebuf = 0;
+ for (i = 0; i < 2; i++) {
+ for (pages = 4; pages >= 0; pages--)
+ if ((devpriv->dmabuf_virt[i] = (short *)
+ __get_free_pages(GFP_KERNEL,
+ pages)))
+ break;
+ if (devpriv->dmabuf_virt[i]) {
+ devpriv->dmabuf_pages[i] = pages;
+ devpriv->dmabuf_size[i] = PAGE_SIZE * pages;
+ devpriv->dmabuf_samples[i] =
+ devpriv->dmabuf_size[i] >> 1;
+ devpriv->dmabuf_hw[i] =
+ virt_to_bus((void *)devpriv->
+ dmabuf_virt[i]);
+ }
+ }
+ if (!devpriv->dmabuf_virt[0]) {
+ rt_printk(", Can't allocate DMA buffer, DMA disabled!");
+ master = 0;
+ }
+
+ if (devpriv->dmabuf_virt[1])
+ devpriv->dma_doublebuf = 1;
+
+ }
+
+ if ((devpriv->master = master)) {
+ rt_printk(", bus master");
+ } else {
+ rt_printk(", no bus master");
+ }
+
+ devpriv->usemux = 0;
+ if (it->options[2] > 0) {
+ devpriv->usemux = it->options[2];
+ if (devpriv->usemux > 256)
+ devpriv->usemux = 256; // max 256 channels!
+ if (it->options[4] > 0)
+ if (devpriv->usemux > 128) {
+ devpriv->usemux = 128; // max 128 channels with softare S&H!
+ }
+ rt_printk(", ext. mux %d channels", devpriv->usemux);
+ }
+
+ devpriv->softsshdelay = it->options[4];
+ if (devpriv->softsshdelay < 0) { // select sample&hold signal polarity
+ devpriv->softsshdelay = -devpriv->softsshdelay;
+ devpriv->softsshsample = 0x80;
+ devpriv->softsshhold = 0x00;
+ } else {
+ devpriv->softsshsample = 0x00;
+ devpriv->softsshhold = 0x80;
+ }
+
+ rt_printk(".\n");
+
+ pci_read_config_word(devpriv->pcidev, PCI_COMMAND, &u16w);
+ pci_write_config_word(devpriv->pcidev, PCI_COMMAND, u16w | 64); // Enable parity check for parity error
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
+ if (devpriv->usemux) {
+ s->n_chan = devpriv->usemux;
+ } else {
+ s->n_chan = this_board->n_aichan;
+ }
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = this_board->n_aichanlist;
+ s->range_table = this_board->rangelist_ai;
+ s->cancel = pci9118_ai_cancel;
+ s->insn_read = pci9118_insn_read_ai;
+ if (dev->irq) {
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pci9118_ai_cmdtest;
+ s->do_cmd = pci9118_ai_cmd;
+ s->munge = pci9118_ai_munge;
+ }
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->rangelist_ao;
+ s->insn_write = pci9118_insn_write_ao;
+ s->insn_read = pci9118_insn_read_ao;
+
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->io_bits = 0; /* all bits input */
+ s->insn_bits = pci9118_insn_bits_di;
+
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->len_chanlist = 4;
+ s->range_table = &range_digital;
+ s->io_bits = 0xf; /* all bits output */
+ s->insn_bits = pci9118_insn_bits_do;
+
+ devpriv->valid = 1;
+ devpriv->i8254_osc_base = 250; // 250ns=4MHz
+ devpriv->ai_maskharderr = 0x10a; // default measure crash condition
+ if (it->options[5]) // disable some requested
+ devpriv->ai_maskharderr &= ~it->options[5];
+
+ switch (this_board->ai_maxdata) {
+ case 0xffff:
+ devpriv->ai16bits = 1;
+ break;
+ default:
+ devpriv->ai16bits = 0;
+ break;
+ }
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci9118_detach(struct comedi_device * dev)
+{
+ if (dev->private) {
+ if (devpriv->valid)
+ pci9118_reset(dev);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ if (devpriv->dmabuf_virt[0])
+ free_pages((unsigned long)devpriv->dmabuf_virt[0],
+ devpriv->dmabuf_pages[0]);
+ if (devpriv->dmabuf_virt[1])
+ free_pages((unsigned long)devpriv->dmabuf_virt[1],
+ devpriv->dmabuf_pages[1]);
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/adq12b.c b/drivers/staging/comedi/drivers/adq12b.c
new file mode 100644
index 00000000000..92f62854d6d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adq12b.c
@@ -0,0 +1,394 @@
+/*
+ comedi/drivers/adq12b.c
+ driver for MicroAxial ADQ12-B data acquisition and control card
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: adq12b
+Description: driver for MicroAxial ADQ12-B data acquisition and control card
+Devices: [MicroAxial] ADQ12-B (adq12b)
+Author: jeremy theler <thelerg@ib.cnea.gov.ar>
+Updated: Thu, 21 Feb 2008 02:56:27 -0300
+Status: works
+
+Driver for the acquisition card ADQ12-B (without any add-on).
+
+ - Analog input is subdevice 0 (16 channels single-ended or 8 differential)
+ - Digital input is subdevice 1 (5 channels)
+ - Digital output is subdevice 1 (8 channels)
+ - The PACER is not supported in this version
+
+If you do not specify any options, they will default to
+
+ # comedi_config /dev/comedi0 adq12b 0x300,0,0
+
+ option 1: I/O base address. The following table is provided as a help
+ of the hardware jumpers.
+
+ address jumper JADR
+ 0x300 1 (factory default)
+ 0x320 2
+ 0x340 3
+ 0x360 4
+ 0x380 5
+ 0x3A0 6
+
+ option 2: unipolar/bipolar ADC selection: 0 -> bipolar, 1 -> unipolar
+
+ selection comedi_config option JUB
+ bipolar 0 2-3 (factory default)
+ unipolar 1 1-2
+
+ option 3: single-ended/differential AI selection: 0 -> SE, 1 -> differential
+
+ selection comedi_config option JCHA JCHB
+ single-ended 0 1-2 1-2 (factory default)
+ differential 1 2-3 2-3
+
+
+ written by jeremy theler <thelerg@ib.cnea.gov.ar>
+
+ instituto balseiro
+ comision nacional de energia atomica
+ universidad nacional de cuyo
+ argentina
+
+ 21-feb-2008
+ + changed supported devices string (missused the [] and ())
+
+ 13-oct-2007
+ + first try
+
+
+*/
+
+#include "../comedidev.h"
+
+// address scheme (page 2.17 of the manual)
+#define ADQ12B_SIZE 16
+
+#define ADQ12B_CTREG 0x00
+#define ADQ12B_STINR 0x00
+#define ADQ12B_OUTBR 0x04
+#define ADQ12B_ADLOW 0x08
+#define ADQ12B_ADHIG 0x09
+#define ADQ12B_CONT0 0x0c
+#define ADQ12B_CONT1 0x0d
+#define ADQ12B_CONT2 0x0e
+#define ADQ12B_COWORD 0x0f
+
+// mask of the bit at STINR to check end of conversion
+#define ADQ12B_EOC 0x20
+
+#define TIMEOUT 20
+
+// available ranges through the PGA gains
+static const struct comedi_lrange range_adq12b_ai_bipolar = { 4, {
+ BIP_RANGE( 5 ),
+ BIP_RANGE( 2 ),
+ BIP_RANGE( 1 ),
+ BIP_RANGE( 0.5 )
+}};
+
+static const struct comedi_lrange range_adq12b_ai_unipolar = { 4, {
+ UNI_RANGE( 5 ),
+ UNI_RANGE( 2 ),
+ UNI_RANGE( 1 ),
+ UNI_RANGE( 0.5 )
+}};
+
+
+
+struct adq12b_board {
+ const char *name;
+ int ai_se_chans;
+ int ai_diff_chans;
+ int ai_bits;
+ int di_chans;
+ int do_chans;
+};
+
+static const struct adq12b_board adq12b_boards[] = {
+ {
+ name: "adq12b",
+ ai_se_chans: 16,
+ ai_diff_chans: 8,
+ ai_bits: 12,
+ di_chans: 5,
+ do_chans: 8
+ }
+// potentially, more adq-based deviced will be added
+/*,
+ name: "adq12b",
+ ai_chans: 16, // this is just for reference, hardcoded again later
+ ai_bits: 12,
+ di_chans: 8,
+ do_chans: 5
+ }*/
+};
+
+#define thisboard ((const struct adq12b_board *)dev->board_ptr)
+
+struct adq12b_private {
+ int unipolar; /* option 2 of comedi_config (1 is iobase) */
+ int differential; /* option 3 of comedi_config */
+ int last_channel;
+ int last_range;
+ unsigned int digital_state;
+};
+
+#define devpriv ((struct adq12b_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int adq12b_attach(struct comedi_device *dev,struct comedi_devconfig *it);
+static int adq12b_detach(struct comedi_device *dev);
+static struct comedi_driver driver_adq12b={
+ driver_name: "adq12b",
+ module: THIS_MODULE,
+ attach: adq12b_attach,
+ detach: adq12b_detach,
+ board_name: &adq12b_boards[0].name,
+ offset: sizeof(struct adq12b_board),
+ num_names: sizeof(adq12b_boards) / sizeof(struct adq12b_board),
+};
+
+static int adq12b_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+static int adq12b_di_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data);
+static int adq12b_do_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int adq12b_attach(struct comedi_device *dev,struct comedi_devconfig *it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ int unipolar, differential;
+
+ iobase = it->options[0];
+ unipolar = it->options[1];
+ differential = it->options[2];
+
+ printk("comedi%d: adq12b called with options base=0x%03lx, %s and %s\n",dev->minor, iobase, (unipolar==1)?"unipolar":"bipolar", (differential==1)?"differential":"single-ended");
+
+ /* if no address was specified, try the default 0x300 */
+ if (iobase == 0) {
+ printk("comedi%d: adq12b warning: I/O base address not specified. Trying the default 0x300.\n", dev->minor);
+ iobase = 0x300;
+ }
+
+ printk("comedi%d: adq12b: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, ADQ12B_SIZE, "adq12b")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if(alloc_private(dev, sizeof(struct adq12b_private)) < 0)
+ return -ENOMEM;
+
+/* fill in devpriv structure */
+ devpriv->unipolar = unipolar;
+ devpriv->differential = differential;
+ devpriv->digital_state = 0;
+/* initialize channel and range to -1 so we make sure we always write
+ at least once to the CTREG in the instruction */
+ devpriv->last_channel = -1;
+ devpriv->last_range = -1;
+
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if(alloc_subdevices(dev, 3)<0)
+ return -ENOMEM;
+
+ s = dev->subdevices+0;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ if (differential) {
+ s->subdev_flags = SDF_READABLE|SDF_GROUND|SDF_DIFF;
+ s->n_chan = thisboard->ai_diff_chans;
+ } else {
+ s->subdev_flags = SDF_READABLE|SDF_GROUND;
+ s->n_chan = thisboard->ai_se_chans;
+ }
+
+ if (unipolar) {
+ s->range_table = &range_adq12b_ai_unipolar;
+ } else {
+ s->range_table = &range_adq12b_ai_bipolar;
+ }
+
+ s->maxdata = (1 << thisboard->ai_bits)-1;
+
+
+ s->len_chanlist = 4; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = adq12b_ai_rinsn;
+
+
+ s = dev->subdevices+1;
+ /* digital input subdevice */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan=thisboard->di_chans;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_di_insn_bits;
+
+ s = dev->subdevices+2;
+ /* digital output subdevice */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->do_chans;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = adq12b_do_insn_bits;
+
+
+ printk("attached\n");
+
+ return 0;
+}
+
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int adq12b_detach(struct comedi_device *dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, ADQ12B_SIZE);
+
+ kfree(devpriv);
+
+ printk("comedi%d: adq12b: removed\n",dev->minor);
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+
+static int adq12b_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data)
+{
+ int n, i;
+ int range, channel;
+ unsigned char hi, lo, status;
+
+ /* change channel and range only if it is different from the previous */
+ range = CR_RANGE(insn->chanspec);
+ channel = CR_CHAN(insn->chanspec);
+ if (channel != devpriv->last_channel || range != devpriv->last_range) {
+ outb((range << 4) | channel, dev->iobase + ADQ12B_CTREG);
+ comedi_udelay(50); /* wait for the mux to settle */
+ }
+
+ /* trigger conversion */
+ status = inb(dev->iobase + ADQ12B_ADLOW);
+
+ /* convert n samples */
+ for(n=0; n < insn->n; n++){
+
+ /* wait for end of convertion */
+ i = 0;
+ do {
+// comedi_udelay(1);
+ status = inb(dev->iobase + ADQ12B_STINR);
+ status = status & ADQ12B_EOC;
+ } while (status == 0 && ++i < TIMEOUT);
+// } while (++i < 10);
+
+ /* read data */
+ hi = inb(dev->iobase + ADQ12B_ADHIG);
+ lo = inb(dev->iobase + ADQ12B_ADLOW);
+
+ //rt_printk("debug: chan=%d range=%d status=%d hi=%d lo=%d\n", channel, range, status, hi, lo);
+ data[n] = (hi << 8) | lo;
+
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+
+static int adq12b_di_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)
+{
+
+ /* only bits 0-4 have information about digital inputs */
+ data[1] = (inb(dev->iobase+ADQ12B_STINR) & (0x1f));
+
+ return 2;
+}
+
+
+static int adq12b_do_insn_bits(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_insn *insn,unsigned int *data)
+{
+ int channel;
+
+ for (channel = 0; channel < 8; channel++)
+ if (((data[0]>>channel) & 0x01) != 0)
+ outb((((data[1]>>channel)&0x01)<<3) | channel, dev->iobase + ADQ12B_OUTBR);
+
+ /* store information to retrieve when asked for reading */
+ if (data[0]) {
+ devpriv->digital_state &= ~data[0];
+ devpriv->digital_state |= (data[0]&data[1]);
+ }
+
+ data[1] = devpriv->digital_state;
+
+ return 2;
+}
+
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_adq12b);
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c
new file mode 100644
index 00000000000..29eac743c8e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1710.c
@@ -0,0 +1,1568 @@
+/*
+ * comedi/drivers/adv_pci1710.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * Thanks to ZhenGang Shang <ZhenGang.Shang@Advantech.com.cn>
+ * for testing and informations.
+ *
+ * hardware driver for Advantech cards:
+ * card: PCI-1710, PCI-1710HG, PCI-1711, PCI-1713, PCI-1720, PCI-1731
+ * driver: pci1710, pci1710hg, pci1711, pci1713, pci1720, pci1731
+ *
+ * Options:
+ * [0] - PCI bus number - if bus number and slot number are 0,
+ * then driver search for first unused card
+ * [1] - PCI slot number
+ *
+*/
+/*
+Driver: adv_pci1710
+Description: Advantech PCI-1710, PCI-1710HG, PCI-1711, PCI-1713,
+ Advantech PCI-1720, PCI-1731
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCI-1710 (adv_pci1710), PCI-1710HG (pci1710hg),
+ PCI-1711 (adv_pci1710), PCI-1713, PCI-1720,
+ PCI-1731
+Status: works
+
+This driver supports AI, AO, DI and DO subdevices.
+AI subdevice supports cmd and insn interface,
+other subdevices support only insn interface.
+
+The PCI-1710 and PCI-1710HG have the same PCI device ID, so the
+driver cannot distinguish between them, as would be normal for a
+PCI driver.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8253.h"
+#include "amcc_s5933.h"
+
+#define PCI171x_PARANOIDCHECK /* if defined, then is used code which control correct channel number on every 12 bit sample */
+
+#undef PCI171X_EXTDEBUG
+
+#define DRV_NAME "adv_pci1710"
+
+#undef DPRINTK
+#ifdef PCI171X_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+// hardware types of the cards
+#define TYPE_PCI171X 0
+#define TYPE_PCI1713 2
+#define TYPE_PCI1720 3
+
+#define IORANGE_171x 32
+#define IORANGE_1720 16
+
+#define PCI171x_AD_DATA 0 /* R: A/D data */
+#define PCI171x_SOFTTRG 0 /* W: soft trigger for A/D */
+#define PCI171x_RANGE 2 /* W: A/D gain/range register */
+#define PCI171x_MUX 4 /* W: A/D multiplexor control */
+#define PCI171x_STATUS 6 /* R: status register */
+#define PCI171x_CONTROL 6 /* W: control register */
+#define PCI171x_CLRINT 8 /* W: clear interrupts request */
+#define PCI171x_CLRFIFO 9 /* W: clear FIFO */
+#define PCI171x_DA1 10 /* W: D/A register */
+#define PCI171x_DA2 12 /* W: D/A register */
+#define PCI171x_DAREF 14 /* W: D/A reference control */
+#define PCI171x_DI 16 /* R: digi inputs */
+#define PCI171x_DO 16 /* R: digi inputs */
+#define PCI171x_CNT0 24 /* R/W: 8254 couter 0 */
+#define PCI171x_CNT1 26 /* R/W: 8254 couter 1 */
+#define PCI171x_CNT2 28 /* R/W: 8254 couter 2 */
+#define PCI171x_CNTCTRL 30 /* W: 8254 counter control */
+
+// upper bits from status register (PCI171x_STATUS) (lower is same woth control reg)
+#define Status_FE 0x0100 /* 1=FIFO is empty */
+#define Status_FH 0x0200 /* 1=FIFO is half full */
+#define Status_FF 0x0400 /* 1=FIFO is full, fatal error */
+#define Status_IRQ 0x0800 /* 1=IRQ occured */
+// bits from control register (PCI171x_CONTROL)
+#define Control_CNT0 0x0040 /* 1=CNT0 have external source, 0=have internal 100kHz source */
+#define Control_ONEFH 0x0020 /* 1=IRQ on FIFO is half full, 0=every sample */
+#define Control_IRQEN 0x0010 /* 1=enable IRQ */
+#define Control_GATE 0x0008 /* 1=enable external trigger GATE (8254?) */
+#define Control_EXT 0x0004 /* 1=external trigger source */
+#define Control_PACER 0x0002 /* 1=enable internal 8254 trigger source */
+#define Control_SW 0x0001 /* 1=enable software trigger source */
+// bits from counter control register (PCI171x_CNTCTRL)
+#define Counter_BCD 0x0001 /* 0 = binary counter, 1 = BCD counter */
+#define Counter_M0 0x0002 /* M0-M2 select modes 0-5 */
+#define Counter_M1 0x0004 /* 000 = mode 0, 010 = mode 2 ... */
+#define Counter_M2 0x0008
+#define Counter_RW0 0x0010 /* RW0/RW1 select read/write mode */
+#define Counter_RW1 0x0020
+#define Counter_SC0 0x0040 /* Select Counter. Only 00 or 11 may */
+#define Counter_SC1 0x0080 /* be used, 00 for CNT0, 11 for read-back command */
+
+#define PCI1720_DA0 0 /* W: D/A register 0 */
+#define PCI1720_DA1 2 /* W: D/A register 1 */
+#define PCI1720_DA2 4 /* W: D/A register 2 */
+#define PCI1720_DA3 6 /* W: D/A register 3 */
+#define PCI1720_RANGE 8 /* R/W: D/A range register */
+#define PCI1720_SYNCOUT 9 /* W: D/A synchronized output register */
+#define PCI1720_SYNCONT 15 /* R/W: D/A synchronized control */
+
+// D/A synchronized control (PCI1720_SYNCONT)
+#define Syncont_SC0 1 /* set synchronous output mode */
+
+static const struct comedi_lrange range_pci1710_3 = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+static const char range_codes_pci1710_3[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x10, 0x11, 0x12, 0x13 };
+
+static const struct comedi_lrange range_pci1710hg = { 12, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+};
+
+static const char range_codes_pci1710hg[] =
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x10, 0x11, 0x12,
+ 0x13 };
+
+static const struct comedi_lrange range_pci17x1 = { 5, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625)
+ }
+};
+
+static const char range_codes_pci17x1[] = { 0x00, 0x01, 0x02, 0x03, 0x04 };
+
+static const struct comedi_lrange range_pci1720 = { 4, {
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(10)
+ }
+};
+
+static const struct comedi_lrange range_pci171x_da = { 2, {
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+static int pci1710_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci1710_detach(struct comedi_device * dev);
+
+struct boardtype {
+ const char *name; // board name
+ int device_id;
+ int iorange; // I/O range len
+ char have_irq; // 1=card support IRQ
+ char cardtype; // 0=1710& co. 2=1713, ...
+ int n_aichan; // num of A/D chans
+ int n_aichand; // num of A/D chans in diff mode
+ int n_aochan; // num of D/A chans
+ int n_dichan; // num of DI chans
+ int n_dochan; // num of DO chans
+ int n_counter; // num of counters
+ int ai_maxdata; // resolution of A/D
+ int ao_maxdata; // resolution of D/A
+ const struct comedi_lrange *rangelist_ai; // rangelist for A/D
+ const char *rangecode_ai; // range codes for programming
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+ unsigned int ai_ns_min; // max sample speed of card v ns
+ unsigned int fifo_half_size; // size of FIFO/2
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci1710_pci_table) = {
+ {PCI_VENDOR_ID_ADVANTECH, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1711, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1731, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci1710_pci_table);
+
+static const struct boardtype boardtypes[] = {
+ {"pci1710", 0x1710,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
+ &range_pci1710_3, range_codes_pci1710_3,
+ &range_pci171x_da,
+ 10000, 2048},
+ {"pci1710hg", 0x1710,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 8, 2, 16, 16, 1, 0x0fff, 0x0fff,
+ &range_pci1710hg, range_codes_pci1710hg,
+ &range_pci171x_da,
+ 10000, 2048},
+ {"pci1711", 0x1711,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 0, 2, 16, 16, 1, 0x0fff, 0x0fff,
+ &range_pci17x1, range_codes_pci17x1, &range_pci171x_da,
+ 10000, 512},
+ {"pci1713", 0x1713,
+ IORANGE_171x, 1, TYPE_PCI1713,
+ 32, 16, 0, 0, 0, 0, 0x0fff, 0x0000,
+ &range_pci1710_3, range_codes_pci1710_3, NULL,
+ 10000, 2048},
+ {"pci1720", 0x1720,
+ IORANGE_1720, 0, TYPE_PCI1720,
+ 0, 0, 4, 0, 0, 0, 0x0000, 0x0fff,
+ NULL, NULL, &range_pci1720,
+ 0, 0},
+ {"pci1731", 0x1731,
+ IORANGE_171x, 1, TYPE_PCI171X,
+ 16, 0, 0, 16, 16, 0, 0x0fff, 0x0000,
+ &range_pci17x1, range_codes_pci17x1, NULL,
+ 10000, 512},
+ // dummy entry corresponding to driver name
+ {.name = DRV_NAME},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
+
+static struct comedi_driver driver_pci1710 = {
+ .driver_name = DRV_NAME,
+ .module = THIS_MODULE,
+ .attach = pci1710_attach,
+ .detach = pci1710_detach,
+ .num_names = n_boardtypes,
+ .board_name = &boardtypes[0].name,
+ .offset = sizeof(struct boardtype),
+};
+
+struct pci1710_private {
+ struct pci_dev *pcidev; // ptr to PCI device
+ char valid; // card is usable
+ char neverending_ai; // we do unlimited AI
+ unsigned int CntrlReg; // Control register
+ unsigned int i8254_osc_base; // frequence of onboard oscilator
+ unsigned int ai_do; // what do AI? 0=nothing, 1 to 4 mode
+ unsigned int ai_act_scan; // how many scans we finished
+ unsigned int ai_act_chan; // actual position in actual scan
+ unsigned int ai_buf_ptr; // data buffer ptr in samples
+ unsigned char ai_eos; // 1=EOS wake up
+ unsigned char ai_et;
+ unsigned int ai_et_CntrlReg;
+ unsigned int ai_et_MuxVal;
+ unsigned int ai_et_div1, ai_et_div2;
+ unsigned int act_chanlist[32]; // list of scaned channel
+ unsigned char act_chanlist_len; // len of scanlist
+ unsigned char act_chanlist_pos; // actual position in MUX list
+ unsigned char da_ranges; // copy of D/A outpit range register
+ unsigned int ai_scans; // len of scanlist
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int *ai_chanlist; // actaul chanlist
+ unsigned int ai_flags; // flaglist
+ unsigned int ai_data_len; // len of data buffer
+ short *ai_data; // data buffer
+ unsigned int ai_timer1; // timers
+ unsigned int ai_timer2;
+ short ao_data[4]; // data output buffer
+ unsigned int cnt0_write_wait; // after a write, wait for update of the internal state
+};
+
+#define devpriv ((struct pci1710_private *)dev->private)
+#define this_board ((const struct boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan);
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+static int pci1710_reset(struct comedi_device * dev);
+static int pci171x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static const unsigned int muxonechan[] = { 0x0000, 0x0101, 0x0202, 0x0303, 0x0404, 0x0505, 0x0606, 0x0707, // used for gain list programming
+ 0x0808, 0x0909, 0x0a0a, 0x0b0b, 0x0c0c, 0x0d0d, 0x0e0e, 0x0f0f,
+ 0x1010, 0x1111, 0x1212, 0x1313, 0x1414, 0x1515, 0x1616, 0x1717,
+ 0x1818, 0x1919, 0x1a1a, 0x1b1b, 0x1c1c, 0x1d1d, 0x1e1e, 0x1f1f
+};
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_read_ai(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, timeout;
+#ifdef PCI171x_PARANOIDCHECK
+ unsigned int idata;
+#endif
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_insn_read_ai(...)\n");
+ devpriv->CntrlReg &= Control_CNT0;
+ devpriv->CntrlReg |= Control_SW; // set software trigger
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+
+ setup_channel_list(dev, s, &insn->chanspec, 1, 1);
+
+ DPRINTK("adv_pci1710 A ST=%4x IO=%x\n",
+ inw(dev->iobase + PCI171x_STATUS),
+ dev->iobase + PCI171x_STATUS);
+ for (n = 0; n < insn->n; n++) {
+ outw(0, dev->iobase + PCI171x_SOFTTRG); /* start conversion */
+ DPRINTK("adv_pci1710 B n=%d ST=%4x\n", n,
+ inw(dev->iobase + PCI171x_STATUS));
+ //comedi_udelay(1);
+ DPRINTK("adv_pci1710 C n=%d ST=%4x\n", n,
+ inw(dev->iobase + PCI171x_STATUS));
+ timeout = 100;
+ while (timeout--) {
+ if (!(inw(dev->iobase + PCI171x_STATUS) & Status_FE))
+ goto conv_finish;
+ if (!(timeout % 10))
+ DPRINTK("adv_pci1710 D n=%d tm=%d ST=%4x\n", n,
+ timeout,
+ inw(dev->iobase + PCI171x_STATUS));
+ }
+ comedi_error(dev, "A/D insn timeout");
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+ data[n] = 0;
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
+ return -ETIME;
+
+ conv_finish:
+#ifdef PCI171x_PARANOIDCHECK
+ idata = inw(dev->iobase + PCI171x_AD_DATA);
+ if (this_board->cardtype != TYPE_PCI1713)
+ if ((idata & 0xf000) != devpriv->act_chanlist[0]) {
+ comedi_error(dev, "A/D insn data droput!");
+ return -ETIME;
+ }
+ data[n] = idata & 0x0fff;
+#else
+ data[n] = inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff;
+#endif
+
+ }
+
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_insn_read_ai(...) n=%d\n", n);
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan, range, ofs;
+
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ if (chan) {
+ devpriv->da_ranges &= 0xfb;
+ devpriv->da_ranges |= (range << 2);
+ outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+ ofs = PCI171x_DA2;
+ } else {
+ devpriv->da_ranges &= 0xfe;
+ devpriv->da_ranges |= range;
+ outw(devpriv->da_ranges, dev->iobase + PCI171x_DAREF);
+ ofs = PCI171x_DA1;
+ }
+
+ for (n = 0; n < insn->n; n++)
+ outw(data[n], dev->iobase + ofs);
+
+ devpriv->ao_data[chan] = data[n];
+
+ return n;
+
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (n = 0; n < insn->n; n++)
+ data[n] = devpriv->ao_data[chan];
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = inw(dev->iobase + PCI171x_DI);
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outw(s->state, dev->iobase + PCI171x_DO);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int msb, lsb, ccntrl;
+ int i;
+
+ ccntrl = 0xD2; /* count only */
+ for (i = 0; i < insn->n; i++) {
+ outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+
+ lsb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+ msb = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+
+ data[0] = lsb | (msb << 8);
+ }
+
+ return insn->n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ uint msb, lsb, ccntrl, status;
+
+ lsb = data[0] & 0x00FF;
+ msb = (data[0] & 0xFF00) >> 8;
+
+ /* write lsb, then msb */
+ outw(lsb, dev->iobase + PCI171x_CNT0);
+ outw(msb, dev->iobase + PCI171x_CNT0);
+
+ if (devpriv->cnt0_write_wait) {
+ /* wait for the new count to be loaded */
+ ccntrl = 0xE2;
+ do {
+ outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+ status = inw(dev->iobase + PCI171x_CNT0) & 0xFF;
+ } while (status & 0x40);
+ }
+
+ return insn->n;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_insn_counter_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef unused
+ /* This doesn't work like a normal Comedi counter config */
+ uint ccntrl = 0;
+
+ devpriv->cnt0_write_wait = data[0] & 0x20;
+
+ /* internal or external clock? */
+ if (!(data[0] & 0x10)) { /* internal */
+ devpriv->CntrlReg &= ~Control_CNT0;
+ } else {
+ devpriv->CntrlReg |= Control_CNT0;
+ }
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+
+ if (data[0] & 0x01)
+ ccntrl |= Counter_M0;
+ if (data[0] & 0x02)
+ ccntrl |= Counter_M1;
+ if (data[0] & 0x04)
+ ccntrl |= Counter_M2;
+ if (data[0] & 0x08)
+ ccntrl |= Counter_BCD;
+ ccntrl |= Counter_RW0; /* set read/write mode */
+ ccntrl |= Counter_RW1;
+ outw(ccntrl, dev->iobase + PCI171x_CNTCTRL);
+#endif
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci1720_insn_write_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, rangereg, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ rangereg = devpriv->da_ranges & (~(0x03 << (chan << 1)));
+ rangereg |= (CR_RANGE(insn->chanspec) << (chan << 1));
+ if (rangereg != devpriv->da_ranges) {
+ outb(rangereg, dev->iobase + PCI1720_RANGE);
+ devpriv->da_ranges = rangereg;
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ outw(data[n], dev->iobase + PCI1720_DA0 + (chan << 1));
+ outb(0, dev->iobase + PCI1720_SYNCOUT); // update outputs
+ }
+
+ devpriv->ao_data[chan] = data[n];
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci1710_every_sample(void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int m;
+#ifdef PCI171x_PARANOIDCHECK
+ short sampl;
+#endif
+
+ DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_every_sample(...)\n");
+ m = inw(dev->iobase + PCI171x_STATUS);
+ if (m & Status_FE) {
+ rt_printk("comedi%d: A/D FIFO empty (%4x)\n", dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+ if (m & Status_FF) {
+ rt_printk
+ ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
+ dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
+
+ DPRINTK("FOR ");
+ for (; !(inw(dev->iobase + PCI171x_STATUS) & Status_FE);) {
+#ifdef PCI171x_PARANOIDCHECK
+ sampl = inw(dev->iobase + PCI171x_AD_DATA);
+ DPRINTK("%04x:", sampl);
+ if (this_board->cardtype != TYPE_PCI1713)
+ if ((sampl & 0xf000) !=
+ devpriv->act_chanlist[s->async->cur_chan]) {
+ rt_printk
+ ("comedi: A/D data dropout: received data from channel %d, expected %d!\n",
+ (sampl & 0xf000) >> 12,
+ (devpriv->act_chanlist[s->async->
+ cur_chan] & 0xf000) >>
+ 12);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+ DPRINTK("%8d %2d %8d~", s->async->buf_int_ptr,
+ s->async->cur_chan, s->async->buf_int_count);
+ comedi_buf_put(s->async, sampl & 0x0fff);
+#else
+ comedi_buf_put(s->async,
+ inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
+#endif
+ ++s->async->cur_chan;
+
+ if (s->async->cur_chan >= devpriv->ai_n_chan) {
+ s->async->cur_chan = 0;
+ }
+
+ if (s->async->cur_chan == 0) { // one scan done
+ devpriv->ai_act_scan++;
+ DPRINTK("adv_pci1710 EDBG: EOS1 bic %d bip %d buc %d bup %d\n", s->async->buf_int_count, s->async->buf_int_ptr, s->async->buf_user_count, s->async->buf_user_ptr);
+ DPRINTK("adv_pci1710 EDBG: EOS2\n");
+ if ((!devpriv->neverending_ai) && (devpriv->ai_act_scan >= devpriv->ai_scans)) { // all data sampled
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ }
+ }
+
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
+ DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_every_sample(...)\n");
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static int move_block_from_fifo(struct comedi_device * dev, struct comedi_subdevice * s,
+ int n, int turn)
+{
+ int i, j;
+#ifdef PCI171x_PARANOIDCHECK
+ int sampl;
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: move_block_from_fifo(...,%d,%d)\n", n,
+ turn);
+ j = s->async->cur_chan;
+ for (i = 0; i < n; i++) {
+#ifdef PCI171x_PARANOIDCHECK
+ sampl = inw(dev->iobase + PCI171x_AD_DATA);
+ if (this_board->cardtype != TYPE_PCI1713)
+ if ((sampl & 0xf000) != devpriv->act_chanlist[j]) {
+ rt_printk
+ ("comedi%d: A/D FIFO data dropout: received data from channel %d, expected %d! (%d/%d/%d/%d/%d/%4x)\n",
+ dev->minor, (sampl & 0xf000) >> 12,
+ (devpriv->
+ act_chanlist[j] & 0xf000) >> 12,
+ i, j, devpriv->ai_act_scan, n, turn,
+ sampl);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return 1;
+ }
+ comedi_buf_put(s->async, sampl & 0x0fff);
+#else
+ comedi_buf_put(s->async,
+ inw(dev->iobase + PCI171x_AD_DATA) & 0x0fff);
+#endif
+ j++;
+ if (j >= devpriv->ai_n_chan) {
+ j = 0;
+ devpriv->ai_act_scan++;
+ }
+ }
+ DPRINTK("adv_pci1710 EDBG: END: move_block_from_fifo(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static void interrupt_pci1710_half_fifo(void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int m, samplesinbuf;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: interrupt_pci1710_half_fifo(...)\n");
+ m = inw(dev->iobase + PCI171x_STATUS);
+ if (!(m & Status_FH)) {
+ rt_printk("comedi%d: A/D FIFO not half full! (%4x)\n",
+ dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+ if (m & Status_FF) {
+ rt_printk
+ ("comedi%d: A/D FIFO Full status (Fatal Error!) (%4x)\n",
+ dev->minor, m);
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return;
+ }
+
+ samplesinbuf = this_board->fifo_half_size;
+ if (samplesinbuf * sizeof(short) >= devpriv->ai_data_len) {
+ m = devpriv->ai_data_len / sizeof(short);
+ if (move_block_from_fifo(dev, s, m, 0))
+ return;
+ samplesinbuf -= m;
+ }
+
+ if (samplesinbuf) {
+ if (move_block_from_fifo(dev, s, samplesinbuf, 1))
+ return;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pci171x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear our INT request
+ DPRINTK("adv_pci1710 EDBG: END: interrupt_pci1710_half_fifo(...)\n");
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_service_pci1710(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: interrupt_service_pci1710(%d,...)\n",
+ irq);
+ if (!dev->attached) // is device attached?
+ return IRQ_NONE; // no, exit
+
+ if (!(inw(dev->iobase + PCI171x_STATUS) & Status_IRQ)) // is this interrupt from our board?
+ return IRQ_NONE; // no, exit
+
+ DPRINTK("adv_pci1710 EDBG: interrupt_service_pci1710() ST: %4x\n",
+ inw(dev->iobase + PCI171x_STATUS));
+
+ if (devpriv->ai_et) { // Switch from initial TRIG_EXT to TRIG_xxx.
+ devpriv->ai_et = 0;
+ devpriv->CntrlReg &= Control_CNT0;
+ devpriv->CntrlReg |= Control_SW; // set software trigger
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ devpriv->CntrlReg = devpriv->ai_et_CntrlReg;
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+ outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX);
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ // start pacer
+ start_pacer(dev, 1, devpriv->ai_et_div1, devpriv->ai_et_div2);
+ return IRQ_HANDLED;
+ }
+ if (devpriv->ai_eos) { // We use FIFO half full INT or not?
+ interrupt_pci1710_every_sample(d);
+ } else {
+ interrupt_pci1710_half_fifo(d);
+ }
+ DPRINTK("adv_pci1710 EDBG: END: interrupt_service_pci1710(...)\n");
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_docmd_and_mode(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ unsigned int divisor1, divisor2;
+ unsigned int seglen;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_docmd_and_mode(%d,...)\n",
+ mode);
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan);
+ if (seglen < 1)
+ return -EINVAL;
+ setup_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan, seglen);
+
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+
+ devpriv->ai_do = mode;
+
+ devpriv->ai_act_scan = 0;
+ s->async->cur_chan = 0;
+ devpriv->ai_buf_ptr = 0;
+ devpriv->neverending_ai = 0;
+
+ devpriv->CntrlReg &= Control_CNT0;
+ if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan? devpriv->ai_eos=1;
+ devpriv->ai_eos = 1;
+ } else {
+ devpriv->CntrlReg |= Control_ONEFH;
+ devpriv->ai_eos = 0;
+ }
+
+ if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1)) {
+ devpriv->neverending_ai = 1;
+ } //well, user want neverending
+ else {
+ devpriv->neverending_ai = 0;
+ }
+ switch (mode) {
+ case 1:
+ case 2:
+ if (devpriv->ai_timer1 < this_board->ai_ns_min)
+ devpriv->ai_timer1 = this_board->ai_ns_min;
+ devpriv->CntrlReg |= Control_PACER | Control_IRQEN;
+ if (mode == 2) {
+ devpriv->ai_et_CntrlReg = devpriv->CntrlReg;
+ devpriv->CntrlReg &=
+ ~(Control_PACER | Control_ONEFH | Control_GATE);
+ devpriv->CntrlReg |= Control_EXT;
+ devpriv->ai_et = 1;
+ } else {
+ devpriv->ai_et = 0;
+ }
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &devpriv->ai_timer1,
+ devpriv->ai_flags & TRIG_ROUND_MASK);
+ DPRINTK("adv_pci1710 EDBG: OSC base=%u div1=%u div2=%u timer=%u\n", devpriv->i8254_osc_base, divisor1, divisor2, devpriv->ai_timer1);
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ if (mode != 2) {
+ // start pacer
+ start_pacer(dev, mode, divisor1, divisor2);
+ } else {
+ devpriv->ai_et_div1 = divisor1;
+ devpriv->ai_et_div2 = divisor2;
+ }
+ break;
+ case 3:
+ devpriv->CntrlReg |= Control_EXT | Control_IRQEN;
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL);
+ break;
+ }
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_docmd_and_mode(...)\n");
+ return 0;
+}
+
+#ifdef PCI171X_EXTDEBUG
+/*
+==============================================================================
+*/
+static void pci171x_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+ rt_printk("adv_pci1710 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+ cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+ rt_printk("adv_pci1710 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+ cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+ rt_printk("adv_pci1710 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+ cmd->scan_end_src);
+ rt_printk("adv_pci1710 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n",
+ e, cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+#endif
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...)\n");
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(-1, cmd);
+#endif
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(1, cmd);
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=1\n", err);
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(2, cmd);
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=2\n", err);
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+ } else { /* TRIG_FOLLOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > this_board->n_aichan) {
+ cmd->chanlist_len = this_board->n_aichan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+#ifdef PCI171X_EXTDEBUG
+ pci171x_cmdtest_out(3, cmd);
+#endif
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=3\n", err);
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(devpriv->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) err=%d ret=4\n", err);
+ return 4;
+ }
+
+ /* step 5: complain about special chanlist considerations */
+
+ if (cmd->chanlist) {
+ if (!check_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return 5; // incorrect channels list
+ }
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmdtest(...) ret=0\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cmd(...)\n");
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ devpriv->ai_chanlist = cmd->chanlist;
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_data = s->async->prealloc_buf;
+ devpriv->ai_timer1 = 0;
+ devpriv->ai_timer2 = 0;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ } else {
+ devpriv->ai_scans = 0;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) { // mode 1, 2, 3
+ if (cmd->convert_src == TRIG_TIMER) { // mode 1 and 2
+ devpriv->ai_timer1 = cmd->convert_arg;
+ return pci171x_ai_docmd_and_mode(cmd->start_src ==
+ TRIG_EXT ? 2 : 1, dev, s);
+ }
+ if (cmd->convert_src == TRIG_EXT) { // mode 3
+ return pci171x_ai_docmd_and_mode(3, dev, s);
+ }
+ }
+
+ return -1;
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic.
+ This works for all cards.
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan)
+{
+ unsigned int chansegment[32];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ DPRINTK("adv_pci1710 EDBG: check_channel_list(...,%d)\n", n_chan);
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+
+ if (n_chan > 1) {
+ chansegment[0] = chanlist[0]; // first channel is everytime ok
+ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) { // build part of chanlist
+ // rt_printk("%d. %d %d\n",i,CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i]));
+ if (chanlist[0] == chanlist[i])
+ break; // we detect loop, this must by finish
+ if (CR_CHAN(chanlist[i]) & 1) // odd channel cann't by differencial
+ if (CR_AREF(chanlist[i]) == AREF_DIFF) {
+ comedi_error(dev,
+ "Odd channel can't be differential input!\n");
+ return 0;
+ }
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+ if (CR_AREF(chansegment[i - 1]) == AREF_DIFF)
+ nowmustbechan = (nowmustbechan + 1) % s->n_chan;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) { // channel list isn't continous :-(
+ rt_printk
+ ("channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+ i, CR_CHAN(chanlist[i]), nowmustbechan,
+ CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ chansegment[i] = chanlist[i]; // well, this is next correct channel in list
+ }
+
+ for (i = 0, segpos = 0; i < n_chan; i++) { // check whole chanlist
+ //rt_printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(chanlist[i]),CR_RANGE(chanlist[i]));
+ if (chanlist[i] != chansegment[i % seglen]) {
+ rt_printk
+ ("bad channel, reference or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; // chan/gain list is strange
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+ return seglen;
+}
+
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen)
+{
+ unsigned int i, range, chanprog;
+
+ DPRINTK("adv_pci1710 EDBG: setup_channel_list(...,%d,%d)\n", n_chan,
+ seglen);
+ devpriv->act_chanlist_len = seglen;
+ devpriv->act_chanlist_pos = 0;
+
+ DPRINTK("SegLen: %d\n", seglen);
+ for (i = 0; i < seglen; i++) { // store range list to card
+ chanprog = muxonechan[CR_CHAN(chanlist[i])];
+ outw(chanprog, dev->iobase + PCI171x_MUX); /* select channel */
+ range = this_board->rangecode_ai[CR_RANGE(chanlist[i])];
+ if (CR_AREF(chanlist[i]) == AREF_DIFF)
+ range |= 0x0020;
+ outw(range, dev->iobase + PCI171x_RANGE); /* select gain */
+#ifdef PCI171x_PARANOIDCHECK
+ devpriv->act_chanlist[i] =
+ (CR_CHAN(chanlist[i]) << 12) & 0xf000;
+#endif
+ DPRINTK("GS: %2d. [%4x]=%4x %4x\n", i, chanprog, range,
+ devpriv->act_chanlist[i]);
+ }
+
+ devpriv->ai_et_MuxVal =
+ CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8);
+ outw(devpriv->ai_et_MuxVal, dev->iobase + PCI171x_MUX); /* select channel interval to scan */
+ DPRINTK("MUX: %4x L%4x.H%4x\n",
+ CR_CHAN(chanlist[0]) | (CR_CHAN(chanlist[seglen - 1]) << 8),
+ CR_CHAN(chanlist[0]), CR_CHAN(chanlist[seglen - 1]));
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode,
+ divisor1, divisor2);
+ outw(0xb4, dev->iobase + PCI171x_CNTCTRL);
+ outw(0x74, dev->iobase + PCI171x_CNTCTRL);
+
+ if (mode == 1) {
+ outw(divisor2 & 0xff, dev->iobase + PCI171x_CNT2);
+ outw((divisor2 >> 8) & 0xff, dev->iobase + PCI171x_CNT2);
+ outw(divisor1 & 0xff, dev->iobase + PCI171x_CNT1);
+ outw((divisor1 >> 8) & 0xff, dev->iobase + PCI171x_CNT1);
+ }
+ DPRINTK("adv_pci1710 EDBG: END: start_pacer(...)\n");
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_ai_cancel(...)\n");
+
+ switch (this_board->cardtype) {
+ default:
+ devpriv->CntrlReg &= Control_CNT0;
+ devpriv->CntrlReg |= Control_SW;
+
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); // reset any operations
+ start_pacer(dev, -1, 0, 0);
+ outb(0, dev->iobase + PCI171x_CLRFIFO);
+ outb(0, dev->iobase + PCI171x_CLRINT);
+ break;
+ }
+
+ devpriv->ai_do = 0;
+ devpriv->ai_act_scan = 0;
+ s->async->cur_chan = 0;
+ devpriv->ai_buf_ptr = 0;
+ devpriv->neverending_ai = 0;
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_ai_cancel(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci171x_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci171x_reset(...)\n");
+ outw(0x30, dev->iobase + PCI171x_CNTCTRL);
+ devpriv->CntrlReg = Control_SW | Control_CNT0; // Software trigger, CNT0=external
+ outw(devpriv->CntrlReg, dev->iobase + PCI171x_CONTROL); // reset any operations
+ outb(0, dev->iobase + PCI171x_CLRFIFO); // clear FIFO
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear INT request
+ start_pacer(dev, -1, 0, 0); // stop 8254
+ devpriv->da_ranges = 0;
+ if (this_board->n_aochan) {
+ outb(devpriv->da_ranges, dev->iobase + PCI171x_DAREF); // set DACs to 0..5V
+ outw(0, dev->iobase + PCI171x_DA1); // set DA outputs to 0V
+ devpriv->ao_data[0] = 0x0000;
+ if (this_board->n_aochan > 1) {
+ outw(0, dev->iobase + PCI171x_DA2);
+ devpriv->ao_data[1] = 0x0000;
+ }
+ }
+ outw(0, dev->iobase + PCI171x_DO); // digital outputs to 0
+ outb(0, dev->iobase + PCI171x_CLRFIFO); // clear FIFO
+ outb(0, dev->iobase + PCI171x_CLRINT); // clear INT request
+
+ DPRINTK("adv_pci1710 EDBG: END: pci171x_reset(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1720_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci1720_reset(...)\n");
+ outb(Syncont_SC0, dev->iobase + PCI1720_SYNCONT); // set synchronous output mode
+ devpriv->da_ranges = 0xAA;
+ outb(devpriv->da_ranges, dev->iobase + PCI1720_RANGE); // set all ranges to +/-5V
+ outw(0x0800, dev->iobase + PCI1720_DA0); // set outputs to 0V
+ outw(0x0800, dev->iobase + PCI1720_DA1);
+ outw(0x0800, dev->iobase + PCI1720_DA2);
+ outw(0x0800, dev->iobase + PCI1720_DA3);
+ outb(0, dev->iobase + PCI1720_SYNCOUT); // update outputs
+ devpriv->ao_data[0] = 0x0800;
+ devpriv->ao_data[1] = 0x0800;
+ devpriv->ao_data[2] = 0x0800;
+ devpriv->ao_data[3] = 0x0800;
+ DPRINTK("adv_pci1710 EDBG: END: pci1720_reset(...)\n");
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci1710 EDBG: BGN: pci1710_reset(...)\n");
+ switch (this_board->cardtype) {
+ case TYPE_PCI1720:
+ return pci1720_reset(dev);
+ default:
+ return pci171x_reset(dev);
+ }
+ DPRINTK("adv_pci1710 EDBG: END: pci1710_reset(...)\n");
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, subdev, n_subdevices;
+ unsigned int irq;
+ unsigned long iobase;
+ struct pci_dev *pcidev;
+ int opt_bus, opt_slot;
+ const char *errstr;
+ unsigned char pci_bus, pci_slot, pci_func;
+ int i;
+ int board_index;
+
+ rt_printk("comedi%d: adv_pci1710: ", dev->minor);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+
+ if ((ret = alloc_private(dev, sizeof(struct pci1710_private))) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ /* Look for matching PCI device */
+ errstr = "not found!";
+ pcidev = NULL;
+ board_index = this_board - boardtypes;
+ while (NULL != (pcidev = pci_get_device(PCI_VENDOR_ID_ADVANTECH,
+ PCI_ANY_ID, pcidev))) {
+ if(strcmp(this_board->name, DRV_NAME) == 0)
+ {
+ for(i = 0; i < n_boardtypes; ++i)
+ {
+ if(pcidev->device == boardtypes[i].device_id)
+ {
+ board_index = i;
+ break;
+ }
+ }
+ if(i == n_boardtypes) continue;
+ }else
+ {
+ if(pcidev->device != boardtypes[board_index].device_id) continue;
+ }
+
+ /* Found matching vendor/device. */
+ if (opt_bus || opt_slot) {
+ /* Check bus/slot. */
+ if (opt_bus != pcidev->bus->number
+ || opt_slot != PCI_SLOT(pcidev->devfn))
+ continue; /* no match */
+ }
+ /*
+ * Look for device that isn't in use.
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, DRV_NAME)) {
+ errstr = "failed to enable PCI device and request regions!";
+ continue;
+ }
+ // fixup board_ptr in case we were using the dummy entry with the driver name
+ dev->board_ptr = &boardtypes[board_index];
+ break;
+ }
+
+ if (!pcidev) {
+ if (opt_bus || opt_slot) {
+ rt_printk(" - Card at b:s %d:%d %s\n",
+ opt_bus, opt_slot, errstr);
+ } else {
+ rt_printk(" - Card %s\n", errstr);
+ }
+ return -EIO;
+ }
+
+ pci_bus = pcidev->bus->number;
+ pci_slot = PCI_SLOT(pcidev->devfn);
+ pci_func = PCI_FUNC(pcidev->devfn);
+ irq = pcidev->irq;
+ iobase = pci_resource_start(pcidev, 2);
+
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx", pci_bus, pci_slot, pci_func,
+ iobase);
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+ devpriv->pcidev = pcidev;
+
+ n_subdevices = 0;
+ if (this_board->n_aichan)
+ n_subdevices++;
+ if (this_board->n_aochan)
+ n_subdevices++;
+ if (this_board->n_dichan)
+ n_subdevices++;
+ if (this_board->n_dochan)
+ n_subdevices++;
+ if (this_board->n_counter)
+ n_subdevices++;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return ret;
+ }
+
+ pci1710_reset(dev);
+
+ if (this_board->have_irq) {
+ if (irq) {
+ if (comedi_request_irq(irq, interrupt_service_pci1710,
+ IRQF_SHARED, "Advantech PCI-1710",
+ dev)) {
+ rt_printk
+ (", unable to allocate IRQ %d, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ } else {
+ rt_printk(", IRQ disabled");
+ }
+ } else {
+ irq = 0;
+ }
+
+ dev->irq = irq;
+
+ printk(".\n");
+
+ subdev = 0;
+
+ if (this_board->n_aichan) {
+ s = dev->subdevices + subdev;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_COMMON | SDF_GROUND;
+ if (this_board->n_aichand)
+ s->subdev_flags |= SDF_DIFF;
+ s->n_chan = this_board->n_aichan;
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = this_board->n_aichan;
+ s->range_table = this_board->rangelist_ai;
+ s->cancel = pci171x_ai_cancel;
+ s->insn_read = pci171x_insn_read_ai;
+ if (irq) {
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pci171x_ai_cmdtest;
+ s->do_cmd = pci171x_ai_cmd;
+ }
+ devpriv->i8254_osc_base = 100; // 100ns=10MHz
+ subdev++;
+ }
+
+ if (this_board->n_aochan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->rangelist_ao;
+ switch (this_board->cardtype) {
+ case TYPE_PCI1720:
+ s->insn_write = pci1720_insn_write_ao;
+ break;
+ default:
+ s->insn_write = pci171x_insn_write_ao;
+ break;
+ }
+ s->insn_read = pci171x_insn_read_ao;
+ subdev++;
+ }
+
+ if (this_board->n_dichan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ s->io_bits = 0; /* all bits input */
+ s->insn_bits = pci171x_insn_bits_di;
+ subdev++;
+ }
+
+ if (this_board->n_dochan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ s->io_bits = (1 << this_board->n_dochan) - 1; /* all bits output */
+ s->state = 0;
+ s->insn_bits = pci171x_insn_bits_do;
+ subdev++;
+ }
+
+ if (this_board->n_counter) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = this_board->n_counter;
+ s->len_chanlist = this_board->n_counter;
+ s->maxdata = 0xffff;
+ s->range_table = &range_unknown;
+ s->insn_read = pci171x_insn_counter_read;
+ s->insn_write = pci171x_insn_counter_write;
+ s->insn_config = pci171x_insn_counter_config;
+ subdev++;
+ }
+
+ devpriv->valid = 1;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1710_detach(struct comedi_device * dev)
+{
+
+ if (dev->private) {
+ if (devpriv->valid)
+ pci1710_reset(dev);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+COMEDI_PCI_INITCLEANUP(driver_pci1710, pci1710_pci_table);
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c
new file mode 100644
index 00000000000..81f7ee18c15
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci1723.c
@@ -0,0 +1,465 @@
+/*******************************************************************************
+ comedi/drivers/pci1723.c
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*******************************************************************************/
+/*
+Driver: adv_pci1723
+Description: Advantech PCI-1723
+Author: yonggang <rsmgnu@gmail.com>, Ian Abbott <abbotti@mev.co.uk>
+Devices: [Advantech] PCI-1723 (adv_pci1723)
+Updated: Mon, 14 Apr 2008 15:12:56 +0100
+Status: works
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+Subdevice 0 is 8-channel AO, 16-bit, range +/- 10 V.
+
+Subdevice 1 is 16-channel DIO. The channels are configurable as input or
+output in 2 groups (0 to 7, 8 to 15). Configuring any channel implicitly
+configures all channels in the same group.
+
+TODO:
+
+1. Add the two milliamp ranges to the AO subdevice (0 to 20 mA, 4 to 20 mA).
+2. Read the initial ranges and values of the AO subdevice at start-up instead
+ of reinitializing them.
+3. Implement calibration.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define ADVANTECH_VENDOR 0x13fe /* Advantech PCI vendor ID */
+
+// hardware types of the cards
+#define TYPE_PCI1723 0
+
+#define IORANGE_1723 0x2A
+
+/* all the registers for the pci1723 board */
+#define PCI1723_DA(N) ((N)<<1) /* W: D/A register N (0 to 7) */
+
+#define PCI1723_SYN_SET 0x12 /*synchronized set register */
+#define PCI1723_ALL_CHNNELE_SYN_STROBE 0x12 /*synchronized status register */
+
+#define PCI1723_RANGE_CALIBRATION_MODE 0x14 /* range and calibration mode */
+#define PCI1723_RANGE_CALIBRATION_STATUS 0x14 /* range and calibration status */
+
+#define PCI1723_CONTROL_CMD_CALIBRATION_FUN 0x16 /* SADC control command for calibration function */
+#define PCI1723_STATUS_CMD_CALIBRATION_FUN 0x16 /* SADC control status for calibration function */
+
+#define PCI1723_CALIBRATION_PARA_STROBE 0x18 /* Calibration parameter strobe */
+
+#define PCI1723_DIGITAL_IO_PORT_SET 0x1A /* Digital I/O port setting */
+#define PCI1723_DIGITAL_IO_PORT_MODE 0x1A /* Digital I/O port mode */
+
+#define PCI1723_WRITE_DIGITAL_OUTPUT_CMD 0x1C /* Write digital output command */
+#define PCI1723_READ_DIGITAL_INPUT_DATA 0x1C /* Read digital input data */
+
+#define PCI1723_WRITE_CAL_CMD 0x1E /* Write calibration command */
+#define PCI1723_READ_CAL_STATUS 0x1E /* Read calibration status */
+
+#define PCI1723_SYN_STROBE 0x20 /* Synchronized strobe */
+
+#define PCI1723_RESET_ALL_CHN_STROBE 0x22 /* Reset all D/A channels strobe */
+
+#define PCI1723_RESET_CAL_CONTROL_STROBE 0x24 /* Reset the calibration controller strobe */
+
+#define PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE 0x26 /* Change D/A channels output type strobe */
+
+#define PCI1723_SELECT_CALIBRATION 0x28 /* Select the calibration Ref_V */
+
+//static unsigned short pci_list_builded=0; /*=1 list of card is know */
+
+static const struct comedi_lrange range_pci1723 = { 1, {
+ BIP_RANGE(10)
+ }
+};
+
+/*
+ * Board descriptions for pci1723 boards.
+ */
+struct pci1723_board {
+ const char *name;
+ int vendor_id; // PCI vendor a device ID of card
+ int device_id;
+ int iorange;
+ char cardtype;
+ int n_aochan; // num of D/A chans
+ int n_diochan; // num of DIO chans
+ int ao_maxdata; // resolution of D/A
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+};
+
+static const struct pci1723_board boardtypes[] = {
+ {
+ name: "pci1723",
+ vendor_id:ADVANTECH_VENDOR,
+ device_id:0x1723,
+ iorange: IORANGE_1723,
+ cardtype:TYPE_PCI1723,
+ n_aochan:8,
+ n_diochan:16,
+ ao_maxdata:0xffff,
+ rangelist_ao:&range_pci1723,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(pci1723_pci_table) = {
+ {PCI_VENDOR_ID_ADVANTECH, 0x1723, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci1723_pci_table);
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci1723_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci1723_detach(struct comedi_device * dev);
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pci1723_board))
+
+static struct comedi_driver driver_pci1723 = {
+ driver_name:"adv_pci1723",
+ module:THIS_MODULE,
+ attach:pci1723_attach,
+ detach:pci1723_detach,
+};
+
+/* this structure is for data unique to this hardware driver. */
+struct pci1723_private {
+ int valid; //card is usable;
+
+ struct pci_dev *pcidev;
+ unsigned char da_range[8]; // D/A output range for each channel
+
+ short ao_data[8]; // data output buffer
+};
+
+/*the following macro to make it easy to
+* access the private structure.
+*/
+#define devpriv ((struct pci1723_private *)dev->private)
+
+#define this_board boardtypes
+
+/*
+ * the pci1723 card reset;
+ */
+static int pci1723_reset(struct comedi_device * dev)
+{
+ int i;
+ DPRINTK("adv_pci1723 EDBG: BGN: pci1723_reset(...)\n");
+
+ outw(0x01, dev->iobase + PCI1723_SYN_SET); // set synchronous output mode
+
+ for (i = 0; i < 8; i++) {
+ // set all outputs to 0V
+ devpriv->ao_data[i] = 0x8000;
+ outw(devpriv->ao_data[i], dev->iobase + PCI1723_DA(i));
+ // set all ranges to +/- 10V
+ devpriv->da_range[i] = 0;
+ outw(((devpriv->da_range[i] << 4) | i),
+ PCI1723_RANGE_CALIBRATION_MODE);
+ }
+
+ outw(0, dev->iobase + PCI1723_CHANGE_CHA_OUTPUT_TYPE_STROBE); // update ranges
+ outw(0, dev->iobase + PCI1723_SYN_STROBE); // update outputs
+
+ // set asynchronous output mode
+ outw(0, dev->iobase + PCI1723_SYN_SET);
+
+ DPRINTK("adv_pci1723 EDBG: END: pci1723_reset(...)\n");
+ return 0;
+}
+
+static int pci1723_insn_read_ao(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ DPRINTK(" adv_PCI1723 DEBUG: pci1723_insn_read_ao() ----- \n");
+ for (n = 0; n < insn->n; n++)
+ data[n] = devpriv->ao_data[chan];
+
+ return n;
+}
+
+/*
+ analog data output;
+*/
+static int pci1723_ao_write_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, chan;
+ chan = CR_CHAN(insn->chanspec);
+
+ DPRINTK("PCI1723: the pci1723_ao_write_winsn() ------\n");
+
+ for (n = 0; n < insn->n; n++) {
+
+ devpriv->ao_data[chan] = data[n];
+ outw(data[n], dev->iobase + PCI1723_DA(chan));
+ }
+
+ return n;
+}
+
+/*
+ digital i/o config/query
+*/
+static int pci1723_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+ unsigned int bits;
+ unsigned short dio_mode;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x00FF) {
+ bits = 0x00FF;
+ } else {
+ bits = 0xFF00;
+ }
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ default:
+ return -EINVAL;
+ }
+
+ // update hardware DIO mode
+ dio_mode = 0x0000; // low byte output, high byte output
+ if ((s->io_bits & 0x00FF) == 0)
+ dio_mode |= 0x0001; // low byte input
+ if ((s->io_bits & 0xFF00) == 0)
+ dio_mode |= 0x0002; // high byte input
+ outw(dio_mode, dev->iobase + PCI1723_DIGITAL_IO_PORT_SET);
+ return 1;
+}
+
+/*
+ digital i/o bits read/write
+*/
+static int pci1723_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outw(s->state, dev->iobase + PCI1723_WRITE_DIGITAL_OUTPUT_CMD);
+ }
+ data[1] = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+ return 2;
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a pci1723 board.
+ */
+static int pci1723_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, subdev, n_subdevices;
+ struct pci_dev *pcidev;
+ unsigned int iobase;
+ unsigned char pci_bus, pci_slot, pci_func;
+ int opt_bus, opt_slot;
+ const char *errstr;
+
+ rt_printk("comedi%d: adv_pci1723: board=%s", dev->minor,
+ this_board->name);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+
+ if ((ret = alloc_private(dev, sizeof(struct pci1723_private))) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return -ENOMEM;
+ }
+
+ /* Look for matching PCI device */
+ errstr = "not found!";
+ pcidev = NULL;
+ while (NULL != (pcidev =
+ pci_get_device(PCI_VENDOR_ID_ADVANTECH,
+ this_board->device_id, pcidev))) {
+ /* Found matching vendor/device. */
+ if (opt_bus || opt_slot) {
+ /* Check bus/slot. */
+ if (opt_bus != pcidev->bus->number
+ || opt_slot != PCI_SLOT(pcidev->devfn))
+ continue; /* no match */
+ }
+ /*
+ * Look for device that isn't in use.
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, "adv_pci1723")) {
+ errstr = "failed to enable PCI device and request regions!";
+ continue;
+ }
+ break;
+ }
+
+ if (!pcidev) {
+ if (opt_bus || opt_slot) {
+ rt_printk(" - Card at b:s %d:%d %s\n",
+ opt_bus, opt_slot, errstr);
+ } else {
+ rt_printk(" - Card %s\n", errstr);
+ }
+ return -EIO;
+ }
+
+ pci_bus = pcidev->bus->number;
+ pci_slot = PCI_SLOT(pcidev->devfn);
+ pci_func = PCI_FUNC(pcidev->devfn);
+ iobase = pci_resource_start(pcidev, 2);
+
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4x", pci_bus, pci_slot, pci_func,
+ iobase);
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+ devpriv->pcidev = pcidev;
+
+ n_subdevices = 0;
+
+ if (this_board->n_aochan)
+ n_subdevices++;
+ if (this_board->n_diochan)
+ n_subdevices++;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ rt_printk(" - Allocation failed!\n");
+ return ret;
+ }
+
+ pci1723_reset(dev);
+ subdev = 0;
+ if (this_board->n_aochan) {
+ s = dev->subdevices + subdev;
+ dev->write_subdev = s;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->rangelist_ao;
+
+ s->insn_write = pci1723_ao_write_winsn;
+ s->insn_read = pci1723_insn_read_ao;
+
+ // read DIO config
+ switch (inw(dev->iobase + PCI1723_DIGITAL_IO_PORT_MODE) & 0x03) {
+ case 0x00: // low byte output, high byte output
+ s->io_bits = 0xFFFF;
+ break;
+ case 0x01: // low byte input, high byte output
+ s->io_bits = 0xFF00;
+ break;
+ case 0x02: // low byte output, high byte input
+ s->io_bits = 0x00FF;
+ break;
+ case 0x03: // low byte input, high byte input
+ s->io_bits = 0x0000;
+ break;
+ }
+ // read DIO port state
+ s->state = inw(dev->iobase + PCI1723_READ_DIGITAL_INPUT_DATA);
+
+ subdev++;
+ }
+
+ if (this_board->n_diochan) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = this_board->n_diochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_diochan;
+ s->range_table = &range_digital;
+ s->insn_config = pci1723_dio_insn_config;
+ s->insn_bits = pci1723_dio_insn_bits;
+ subdev++;
+ }
+
+ devpriv->valid = 1;
+
+ pci1723_reset(dev);
+
+ return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci1723_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci1723: remove\n", dev->minor);
+
+ if (dev->private) {
+ if (devpriv->valid)
+ pci1723_reset(dev);
+
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_pci1723, pci1723_pci_table);
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c
new file mode 100644
index 00000000000..2604425c3a0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/adv_pci_dio.c
@@ -0,0 +1,1077 @@
+/*
+ * comedi/drivers/adv_pci_dio.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * Hardware driver for Advantech PCI DIO cards.
+*/
+/*
+Driver: adv_pci_dio
+Description: Advantech PCI-1730, PCI-1733, PCI-1734, PCI-1736UP,
+ PCI-1750, PCI-1751, PCI-1752, PCI-1753/E, PCI-1754,
+ PCI-1756, PCI-1762
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCI-1730 (adv_pci_dio), PCI-1733,
+ PCI-1734, PCI-1736UP, PCI-1750,
+ PCI-1751, PCI-1752, PCI-1753,
+ PCI-1753+PCI-1753E, PCI-1754, PCI-1756,
+ PCI-1760, PCI-1762
+Status: untested
+Updated: Mon, 14 Apr 2008 10:43:08 +0100
+
+This driver supports now only insn interface for DI/DO/DIO.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#undef PCI_DIO_EXTDEBUG /* if defined, enable extensive debug logging */
+
+#undef DPRINTK
+#ifdef PCI_DIO_EXTDEBUG
+#define DPRINTK(fmt, args...) rt_printk(fmt, ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+/* hardware types of the cards */
+enum hw_cards_id {
+ TYPE_PCI1730, TYPE_PCI1733, TYPE_PCI1734, TYPE_PCI1736,
+ TYPE_PCI1750,
+ TYPE_PCI1751,
+ TYPE_PCI1752,
+ TYPE_PCI1753, TYPE_PCI1753E,
+ TYPE_PCI1754, TYPE_PCI1756,
+ TYPE_PCI1760,
+ TYPE_PCI1762
+};
+
+/* which I/O instructions to use */
+enum hw_io_access {
+ IO_8b, IO_16b
+};
+
+#define MAX_DI_SUBDEVS 2 /* max number of DI subdevices per card */
+#define MAX_DO_SUBDEVS 2 /* max number of DO subdevices per card */
+#define MAX_DIO_SUBDEVG 2 /* max number of DIO subdevices group per card */
+
+#define SIZE_8255 4 /* 8255 IO space length */
+
+#define PCIDIO_MAINREG 2 /* main I/O region for all Advantech cards? */
+
+/* Register offset definitions */
+/* Advantech PCI-1730/3/4 */
+#define PCI1730_IDI 0 /* R: Isolated digital input 0-15 */
+#define PCI1730_IDO 0 /* W: Isolated digital output 0-15 */
+#define PCI1730_DI 2 /* R: Digital input 0-15 */
+#define PCI1730_DO 2 /* W: Digital output 0-15 */
+#define PCI1733_IDI 0 /* R: Isolated digital input 0-31 */
+#define PCI1730_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
+#define PCI1730_3_INT_RF 0x0c /* R/W: set falling/raising edge for interrupts */
+#define PCI1730_3_INT_CLR 0x10 /* R/W: clear interrupts */
+#define PCI1734_IDO 0 /* W: Isolated digital output 0-31 */
+#define PCI173x_BOARDID 4 /* R: Board I/D switch for 1730/3/4 */
+
+/* Advantech PCI-1736UP */
+#define PCI1736_IDI 0 /* R: Isolated digital input 0-15 */
+#define PCI1736_IDO 0 /* W: Isolated digital output 0-15 */
+#define PCI1736_3_INT_EN 0x08 /* R/W: enable/disable interrupts */
+#define PCI1736_3_INT_RF 0x0c /* R/W: set falling/raising edge for interrupts */
+#define PCI1736_3_INT_CLR 0x10 /* R/W: clear interrupts */
+#define PCI1736_BOARDID 4 /* R: Board I/D switch for 1736UP */
+#define PCI1736_MAINREG 0 /* Normal register (2) doesn't work */
+
+/* Advantech PCI-1750 */
+#define PCI1750_IDI 0 /* R: Isolated digital input 0-15 */
+#define PCI1750_IDO 0 /* W: Isolated digital output 0-15 */
+#define PCI1750_ICR 32 /* W: Interrupt control register */
+#define PCI1750_ISR 32 /* R: Interrupt status register */
+
+/* Advantech PCI-1751/3/3E */
+#define PCI1751_DIO 0 /* R/W: begin of 8255 registers block */
+#define PCI1751_ICR 32 /* W: Interrupt control register */
+#define PCI1751_ISR 32 /* R: Interrupt status register */
+#define PCI1753_DIO 0 /* R/W: begin of 8255 registers block */
+#define PCI1753_ICR0 16 /* R/W: Interrupt control register group 0 */
+#define PCI1753_ICR1 17 /* R/W: Interrupt control register group 1 */
+#define PCI1753_ICR2 18 /* R/W: Interrupt control register group 2 */
+#define PCI1753_ICR3 19 /* R/W: Interrupt control register group 3 */
+#define PCI1753E_DIO 32 /* R/W: begin of 8255 registers block */
+#define PCI1753E_ICR0 48 /* R/W: Interrupt control register group 0 */
+#define PCI1753E_ICR1 49 /* R/W: Interrupt control register group 1 */
+#define PCI1753E_ICR2 50 /* R/W: Interrupt control register group 2 */
+#define PCI1753E_ICR3 51 /* R/W: Interrupt control register group 3 */
+
+/* Advantech PCI-1752/4/6 */
+#define PCI1752_IDO 0 /* R/W: Digital output 0-31 */
+#define PCI1752_IDO2 4 /* R/W: Digital output 32-63 */
+#define PCI1754_IDI 0 /* R: Digital input 0-31 */
+#define PCI1754_IDI2 4 /* R: Digital input 32-64 */
+#define PCI1756_IDI 0 /* R: Digital input 0-31 */
+#define PCI1756_IDO 4 /* R/W: Digital output 0-31 */
+#define PCI1754_6_ICR0 0x08 /* R/W: Interrupt control register group 0 */
+#define PCI1754_6_ICR1 0x0a /* R/W: Interrupt control register group 1 */
+#define PCI1754_ICR2 0x0c /* R/W: Interrupt control register group 2 */
+#define PCI1754_ICR3 0x0e /* R/W: Interrupt control register group 3 */
+#define PCI1752_6_CFC 0x12 /* R/W: set/read channel freeze function */
+#define PCI175x_BOARDID 0x10 /* R: Board I/D switch for 1752/4/6 */
+
+/* Advantech PCI-1762 registers */
+#define PCI1762_RO 0 /* R/W: Relays status/output */
+#define PCI1762_IDI 2 /* R: Isolated input status */
+#define PCI1762_BOARDID 4 /* R: Board I/D switch */
+#define PCI1762_ICR 6 /* W: Interrupt control register */
+#define PCI1762_ISR 6 /* R: Interrupt status register */
+
+/* Advantech PCI-1760 registers */
+#define OMB0 0x0c /* W: Mailbox outgoing registers */
+#define OMB1 0x0d
+#define OMB2 0x0e
+#define OMB3 0x0f
+#define IMB0 0x1c /* R: Mailbox incoming registers */
+#define IMB1 0x1d
+#define IMB2 0x1e
+#define IMB3 0x1f
+#define INTCSR0 0x38 /* R/W: Interrupt control registers */
+#define INTCSR1 0x39
+#define INTCSR2 0x3a
+#define INTCSR3 0x3b
+
+/* PCI-1760 mailbox commands */
+#define CMD_ClearIMB2 0x00 /* Clear IMB2 status and return actaul DI status in IMB3 */
+#define CMD_SetRelaysOutput 0x01 /* Set relay output from OMB0 */
+#define CMD_GetRelaysStatus 0x02 /* Get relay status to IMB0 */
+#define CMD_ReadCurrentStatus 0x07 /* Read the current status of the register in OMB0, result in IMB0 */
+#define CMD_ReadFirmwareVersion 0x0e /* Read the firmware ver., result in IMB1.IMB0 */
+#define CMD_ReadHardwareVersion 0x0f /* Read the hardware ver., result in IMB1.IMB0 */
+#define CMD_EnableIDIFilters 0x20 /* Enable IDI filters based on bits in OMB0 */
+#define CMD_EnableIDIPatternMatch 0x21 /* Enable IDI pattern match based on bits in OMB0 */
+#define CMD_SetIDIPatternMatch 0x22 /* Enable IDI pattern match based on bits in OMB0 */
+#define CMD_EnableIDICounters 0x28 /* Enable IDI counters based on bits in OMB0 */
+#define CMD_ResetIDICounters 0x29 /* Reset IDI counters based on bits in OMB0 to its reset values */
+#define CMD_OverflowIDICounters 0x2a /* Enable IDI counters overflow interrupts based on bits in OMB0 */
+#define CMD_MatchIntIDICounters 0x2b /* Enable IDI counters match value interrupts based on bits in OMB0 */
+#define CMD_EdgeIDICounters 0x2c /* Set IDI up counters count edge (bit=0 - rising, =1 - falling) */
+#define CMD_GetIDICntCurValue 0x2f /* Read IDI{OMB0} up counter current value */
+#define CMD_SetIDI0CntResetValue 0x40 /* Set IDI0 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntResetValue 0x41 /* Set IDI1 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntResetValue 0x42 /* Set IDI2 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntResetValue 0x43 /* Set IDI3 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntResetValue 0x44 /* Set IDI4 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntResetValue 0x45 /* Set IDI5 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntResetValue 0x46 /* Set IDI6 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntResetValue 0x47 /* Set IDI7 Counter Reset Value 256*OMB1+OMB0 */
+#define CMD_SetIDI0CntMatchValue 0x48 /* Set IDI0 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI1CntMatchValue 0x49 /* Set IDI1 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI2CntMatchValue 0x4a /* Set IDI2 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI3CntMatchValue 0x4b /* Set IDI3 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI4CntMatchValue 0x4c /* Set IDI4 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI5CntMatchValue 0x4d /* Set IDI5 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI6CntMatchValue 0x4e /* Set IDI6 Counter Match Value 256*OMB1+OMB0 */
+#define CMD_SetIDI7CntMatchValue 0x4f /* Set IDI7 Counter Match Value 256*OMB1+OMB0 */
+
+#define OMBCMD_RETRY 0x03 /* 3 times try request before error */
+
+static int pci_dio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci_dio_detach(struct comedi_device * dev);
+
+struct diosubd_data {
+ int chans; /* num of chans */
+ int addr; /* PCI address ofset */
+ int regs; /* number of registers to read or 8255 subdevices */
+ unsigned int specflags; /* addon subdevice flags */
+};
+
+struct dio_boardtype {
+ const char *name; /* board name */
+ int vendor_id; /* vendor/device PCI ID */
+ int device_id;
+ int main_pci_region; /* main I/O PCI region */
+ enum hw_cards_id cardtype;
+ struct diosubd_data sdi[MAX_DI_SUBDEVS]; /* DI chans */
+ struct diosubd_data sdo[MAX_DO_SUBDEVS]; /* DO chans */
+ struct diosubd_data sdio[MAX_DIO_SUBDEVG]; /* DIO 8255 chans */
+ struct diosubd_data boardid; /* card supports board ID switch */
+ enum hw_io_access io_access;
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci_dio_pci_table) = {
+ {PCI_VENDOR_ID_ADVANTECH, 0x1730, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1733, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1734, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1754, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1756, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_ADVANTECH, 0x1762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci_dio_pci_table);
+
+static const struct dio_boardtype boardtypes[] = {
+ {"pci1730", PCI_VENDOR_ID_ADVANTECH, 0x1730, PCIDIO_MAINREG,
+ TYPE_PCI1730,
+ {{16, PCI1730_DI, 2, 0}, {16, PCI1730_IDI, 2, 0}},
+ {{16, PCI1730_DO, 2, 0}, {16, PCI1730_IDO, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+ IO_8b,
+ },
+ {"pci1733", PCI_VENDOR_ID_ADVANTECH, 0x1733, PCIDIO_MAINREG,
+ TYPE_PCI1733,
+ {{0, 0, 0, 0}, {32, PCI1733_IDI, 4, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+ IO_8b},
+ {"pci1734", PCI_VENDOR_ID_ADVANTECH, 0x1734, PCIDIO_MAINREG,
+ TYPE_PCI1734,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {32, PCI1734_IDO, 4, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI173x_BOARDID, 1, SDF_INTERNAL},
+ IO_8b},
+ {"pci1736", PCI_VENDOR_ID_ADVANTECH, 0x1736, PCI1736_MAINREG,
+ TYPE_PCI1736,
+ {{0, 0, 0, 0}, {16, PCI1736_IDI, 2, 0}},
+ {{0, 0, 0, 0}, {16, PCI1736_IDO, 2, 0}},
+ {{ 0, 0, 0, 0}, { 0, 0, 0, 0}},
+ { 4, PCI1736_BOARDID, 1, SDF_INTERNAL},
+ IO_8b,
+ },
+ {"pci1750", PCI_VENDOR_ID_ADVANTECH, 0x1750, PCIDIO_MAINREG,
+ TYPE_PCI1750,
+ {{0, 0, 0, 0}, {16, PCI1750_IDI, 2, 0}},
+ {{0, 0, 0, 0}, {16, PCI1750_IDO, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1751", PCI_VENDOR_ID_ADVANTECH, 0x1751, PCIDIO_MAINREG,
+ TYPE_PCI1751,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{48, PCI1751_DIO, 2, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1752", PCI_VENDOR_ID_ADVANTECH, 0x1752, PCIDIO_MAINREG,
+ TYPE_PCI1752,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{32, PCI1752_IDO, 2, 0}, {32, PCI1752_IDO2, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+ IO_16b},
+ {"pci1753", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
+ TYPE_PCI1753,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{96, PCI1753_DIO, 4, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1753e", PCI_VENDOR_ID_ADVANTECH, 0x1753, PCIDIO_MAINREG,
+ TYPE_PCI1753E,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{96, PCI1753_DIO, 4, 0}, {96, PCI1753E_DIO, 4, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1754", PCI_VENDOR_ID_ADVANTECH, 0x1754, PCIDIO_MAINREG,
+ TYPE_PCI1754,
+ {{32, PCI1754_IDI, 2, 0}, {32, PCI1754_IDI2, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+ IO_16b},
+ {"pci1756", PCI_VENDOR_ID_ADVANTECH, 0x1756, PCIDIO_MAINREG,
+ TYPE_PCI1756,
+ {{0, 0, 0, 0}, {32, PCI1756_IDI, 2, 0}},
+ {{0, 0, 0, 0}, {32, PCI1756_IDO, 2, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI175x_BOARDID, 1, SDF_INTERNAL},
+ IO_16b},
+ {"pci1760", PCI_VENDOR_ID_ADVANTECH, 0x1760, 0,
+ TYPE_PCI1760,
+ {{0, 0, 0, 0}, {0, 0, 0, 0}}, /* This card have own setup work */
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {0, 0, 0, 0},
+ IO_8b},
+ {"pci1762", PCI_VENDOR_ID_ADVANTECH, 0x1762, PCIDIO_MAINREG,
+ TYPE_PCI1762,
+ {{0, 0, 0, 0}, {16, PCI1762_IDI, 1, 0}},
+ {{0, 0, 0, 0}, {16, PCI1762_RO, 1, 0}},
+ {{0, 0, 0, 0}, {0, 0, 0, 0}},
+ {4, PCI1762_BOARDID, 1, SDF_INTERNAL},
+ IO_16b}
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct dio_boardtype))
+
+static struct comedi_driver driver_pci_dio = {
+ driver_name:"adv_pci_dio",
+ module:THIS_MODULE,
+ attach:pci_dio_attach,
+ detach:pci_dio_detach
+};
+
+struct pci_dio_private {
+ struct pci_dio_private *prev; /* previous private struct */
+ struct pci_dio_private *next; /* next private struct */
+ struct pci_dev *pcidev; /* pointer to board's pci_dev */
+ char valid; /* card is usable */
+ char GlobalIrqEnabled; /* 1= any IRQ source is enabled */
+ /* PCI-1760 specific data */
+ unsigned char IDICntEnable; /* counter's counting enable status */
+ unsigned char IDICntOverEnable; /* counter's overflow interrupts enable status */
+ unsigned char IDICntMatchEnable; /* counter's match interrupts enable status */
+ unsigned char IDICntEdge; /* counter's count edge value (bit=0 - rising, =1 - falling) */
+ unsigned short CntResValue[8]; /* counters' reset value */
+ unsigned short CntMatchValue[8]; /* counters' match interrupt value */
+ unsigned char IDIFiltersEn; /* IDI's digital filters enable status */
+ unsigned char IDIPatMatchEn; /* IDI's pattern match enable status */
+ unsigned char IDIPatMatchValue; /* IDI's pattern match value */
+ unsigned short IDIFiltrLow[8]; /* IDI's filter value low signal */
+ unsigned short IDIFiltrHigh[8]; /* IDI's filter value high signal */
+};
+
+static struct pci_dio_private *pci_priv = NULL; /* list of allocated cards */
+
+#define devpriv ((struct pci_dio_private *)dev->private)
+#define this_board ((const struct dio_boardtype *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_di_b(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ data[1] = 0;
+ for (i = 0; i < d->regs; i++) {
+ data[1] |= inb(dev->iobase + d->addr + i) << (8 * i);
+ }
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_di_w(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ data[1] = 0;
+ for (i = 0; i < d->regs; i++)
+ data[1] |= inw(dev->iobase + d->addr + 2 * i) << (16 * i);
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_do_b(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ for (i = 0; i < d->regs; i++)
+ outb((s->state >> (8 * i)) & 0xff,
+ dev->iobase + d->addr + i);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_insn_bits_do_w(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const struct diosubd_data *d = (const struct diosubd_data *)s->private;
+ int i;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ for (i = 0; i < d->regs; i++)
+ outw((s->state >> (16 * i)) & 0xffff,
+ dev->iobase + d->addr + 2 * i);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_unchecked_mbxrequest(struct comedi_device * dev,
+ unsigned char *omb, unsigned char *imb, int repeats)
+{
+ int cnt, tout, ok = 0;
+
+ for (cnt = 0; cnt < repeats; cnt++) {
+ outb(omb[0], dev->iobase + OMB0);
+ outb(omb[1], dev->iobase + OMB1);
+ outb(omb[2], dev->iobase + OMB2);
+ outb(omb[3], dev->iobase + OMB3);
+ for (tout = 0; tout < 251; tout++) {
+ if ((imb[2] = inb(dev->iobase + IMB2)) == omb[2]) {
+ imb[0] = inb(dev->iobase + IMB0);
+ imb[1] = inb(dev->iobase + IMB1);
+ imb[3] = inb(dev->iobase + IMB3);
+ ok = 1;
+ break;
+ }
+ comedi_udelay(1);
+ }
+ if (ok)
+ return 0;
+ }
+
+ comedi_error(dev, "PCI-1760 mailbox request timeout!");
+ return -ETIME;
+}
+
+static int pci1760_clear_imb2(struct comedi_device * dev)
+{
+ unsigned char omb[4] = { 0x0, 0x0, CMD_ClearIMB2, 0x0 };
+ unsigned char imb[4];
+ /* check if imb2 is already clear */
+ if (inb(dev->iobase + IMB2) == CMD_ClearIMB2)
+ return 0;
+ return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
+}
+
+static int pci1760_mbxrequest(struct comedi_device * dev,
+ unsigned char *omb, unsigned char *imb)
+{
+ if (omb[2] == CMD_ClearIMB2) {
+ comedi_error(dev,
+ "bug! this function should not be used for CMD_ClearIMB2 command");
+ return -EINVAL;
+ }
+ if (inb(dev->iobase + IMB2) == omb[2]) {
+ int retval;
+ retval = pci1760_clear_imb2(dev);
+ if (retval < 0)
+ return retval;
+ }
+ return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY);
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_bits_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = inb(dev->iobase + IMB3);
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_bits_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int ret;
+ unsigned char omb[4] = {
+ 0x00,
+ 0x00,
+ CMD_SetRelaysOutput,
+ 0x00
+ };
+ unsigned char imb[4];
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ omb[0] = s->state;
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_cnt_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int ret, n;
+ unsigned char omb[4] = {
+ CR_CHAN(insn->chanspec) & 0x07,
+ 0x00,
+ CMD_GetIDICntCurValue,
+ 0x00
+ };
+ unsigned char imb[4];
+
+ for (n = 0; n < insn->n; n++) {
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ data[n] = (imb[1] << 8) + imb[0];
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_insn_cnt_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int ret;
+ unsigned char chan = CR_CHAN(insn->chanspec) & 0x07;
+ unsigned char bitmask = 1 << chan;
+ unsigned char omb[4] = {
+ data[0] & 0xff,
+ (data[0] >> 8) & 0xff,
+ CMD_SetIDI0CntResetValue + chan,
+ 0x00
+ };
+ unsigned char imb[4];
+
+ if (devpriv->CntResValue[chan] != (data[0] & 0xffff)) { /* Set reset value if different */
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ devpriv->CntResValue[chan] = data[0] & 0xffff;
+ }
+
+ omb[0] = bitmask; /* reset counter to it reset value */
+ omb[2] = CMD_ResetIDICounters;
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+
+ if (!(bitmask & devpriv->IDICntEnable)) { /* start counter if it don't run */
+ omb[0] = bitmask;
+ omb[2] = CMD_EnableIDICounters;
+ if (!(ret = pci1760_mbxrequest(dev, omb, imb)))
+ return ret;
+ devpriv->IDICntEnable |= bitmask;
+ }
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_reset(struct comedi_device * dev)
+{
+ int i;
+ unsigned char omb[4] = { 0x00, 0x00, 0x00, 0x00 };
+ unsigned char imb[4];
+
+ outb(0, dev->iobase + INTCSR0); /* disable IRQ */
+ outb(0, dev->iobase + INTCSR1);
+ outb(0, dev->iobase + INTCSR2);
+ outb(0, dev->iobase + INTCSR3);
+ devpriv->GlobalIrqEnabled = 0;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_SetRelaysOutput; /* reset relay outputs */
+ pci1760_mbxrequest(dev, omb, imb);
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EnableIDICounters; /* disable IDI up counters */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntEnable = 0;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_OverflowIDICounters; /* disable counters overflow interrupts */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntOverEnable = 0;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_MatchIntIDICounters; /* disable counters match value interrupts */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntMatchEnable = 0;
+
+ omb[0] = 0x00;
+ omb[1] = 0x80;
+ for (i = 0; i < 8; i++) { /* set IDI up counters match value */
+ omb[2] = CMD_SetIDI0CntMatchValue + i;
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->CntMatchValue[i] = 0x8000;
+ }
+
+ omb[0] = 0x00;
+ omb[1] = 0x00;
+ for (i = 0; i < 8; i++) { /* set IDI up counters reset value */
+ omb[2] = CMD_SetIDI0CntResetValue + i;
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->CntResValue[i] = 0x0000;
+ }
+
+ omb[0] = 0xff;
+ omb[2] = CMD_ResetIDICounters; /* reset IDI up counters to reset values */
+ pci1760_mbxrequest(dev, omb, imb);
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EdgeIDICounters; /* set IDI up counters count edge */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDICntEdge = 0x00;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EnableIDIFilters; /* disable all digital in filters */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDIFiltersEn = 0x00;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_EnableIDIPatternMatch; /* disable pattern matching */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDIPatMatchEn = 0x00;
+
+ omb[0] = 0x00;
+ omb[2] = CMD_SetIDIPatternMatch; /* set pattern match value */
+ pci1760_mbxrequest(dev, omb, imb);
+ devpriv->IDIPatMatchValue = 0x00;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_reset(struct comedi_device * dev)
+{
+ DPRINTK("adv_pci_dio EDBG: BGN: pci171x_reset(...)\n");
+
+ switch (this_board->cardtype) {
+ case TYPE_PCI1730:
+ outb(0, dev->iobase + PCI1730_DO); /* clear outputs */
+ outb(0, dev->iobase + PCI1730_DO + 1);
+ outb(0, dev->iobase + PCI1730_IDO);
+ outb(0, dev->iobase + PCI1730_IDO + 1);
+ /* NO break there! */
+ case TYPE_PCI1733:
+ outb(0, dev->iobase + PCI1730_3_INT_EN); /* disable interrupts */
+ outb(0x0f, dev->iobase + PCI1730_3_INT_CLR); /* clear interrupts */
+ outb(0, dev->iobase + PCI1730_3_INT_RF); /* set rising edge trigger */
+ break;
+ case TYPE_PCI1734:
+ outb(0, dev->iobase + PCI1734_IDO); /* clear outputs */
+ outb(0, dev->iobase + PCI1734_IDO + 1);
+ outb(0, dev->iobase + PCI1734_IDO + 2);
+ outb(0, dev->iobase + PCI1734_IDO + 3);
+ break;
+
+ case TYPE_PCI1736:
+ outb(0, dev->iobase+PCI1736_IDO);
+ outb(0, dev->iobase+PCI1736_IDO+1);
+ outb(0, dev->iobase+PCI1736_3_INT_EN); /* disable interrupts */
+ outb(0x0f, dev->iobase+PCI1736_3_INT_CLR);/* clear interrupts */
+ outb(0, dev->iobase+PCI1736_3_INT_RF); /* set rising edge trigger */
+ break;
+
+ case TYPE_PCI1750:
+ case TYPE_PCI1751:
+ outb(0x88, dev->iobase + PCI1750_ICR); /* disable & clear interrupts */
+ break;
+ case TYPE_PCI1752:
+ outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze function */
+ outw(0, dev->iobase + PCI1752_IDO); /* clear outputs */
+ outw(0, dev->iobase + PCI1752_IDO + 2);
+ outw(0, dev->iobase + PCI1752_IDO2);
+ outw(0, dev->iobase + PCI1752_IDO2 + 2);
+ break;
+ case TYPE_PCI1753E:
+ outb(0x88, dev->iobase + PCI1753E_ICR0); /* disable & clear interrupts */
+ outb(0x80, dev->iobase + PCI1753E_ICR1);
+ outb(0x80, dev->iobase + PCI1753E_ICR2);
+ outb(0x80, dev->iobase + PCI1753E_ICR3);
+ /* NO break there! */
+ case TYPE_PCI1753:
+ outb(0x88, dev->iobase + PCI1753_ICR0); /* disable & clear interrupts */
+ outb(0x80, dev->iobase + PCI1753_ICR1);
+ outb(0x80, dev->iobase + PCI1753_ICR2);
+ outb(0x80, dev->iobase + PCI1753_ICR3);
+ break;
+ case TYPE_PCI1754:
+ outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear interrupts */
+ outw(0x08, dev->iobase + PCI1754_6_ICR1);
+ outw(0x08, dev->iobase + PCI1754_ICR2);
+ outw(0x08, dev->iobase + PCI1754_ICR3);
+ break;
+ case TYPE_PCI1756:
+ outw(0, dev->iobase + PCI1752_6_CFC); /* disable channel freeze function */
+ outw(0x08, dev->iobase + PCI1754_6_ICR0); /* disable and clear interrupts */
+ outw(0x08, dev->iobase + PCI1754_6_ICR1);
+ outw(0, dev->iobase + PCI1756_IDO); /* clear outputs */
+ outw(0, dev->iobase + PCI1756_IDO + 2);
+ break;
+ case TYPE_PCI1760:
+ pci1760_reset(dev);
+ break;
+ case TYPE_PCI1762:
+ outw(0x0101, dev->iobase + PCI1762_ICR); /* disable & clear interrupts */
+ break;
+ }
+
+ DPRINTK("adv_pci_dio EDBG: END: pci171x_reset(...)\n");
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci1760_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int subdev = 0;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+ s->insn_bits = pci1760_insn_bits_di;
+ subdev++;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+ s->state = 0;
+ s->insn_bits = pci1760_insn_bits_do;
+ subdev++;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_WRITABLE | SDF_LSAMPL;
+ s->n_chan = 2;
+ s->maxdata = 0xffffffff;
+ s->len_chanlist = 2;
+/* s->insn_config=pci1760_insn_pwm_cfg; */
+ subdev++;
+
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 0xffff;
+ s->len_chanlist = 8;
+ s->insn_read = pci1760_insn_cnt_read;
+ s->insn_write = pci1760_insn_cnt_write;
+/* s->insn_config=pci1760_insn_cnt_cfg; */
+ subdev++;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_add_di(struct comedi_device * dev, struct comedi_subdevice * s,
+ const struct diosubd_data * d, int subdev)
+{
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_COMMON | d->specflags;
+ if (d->chans > 16)
+ s->subdev_flags |= SDF_LSAMPL;
+ s->n_chan = d->chans;
+ s->maxdata = 1;
+ s->len_chanlist = d->chans;
+ s->range_table = &range_digital;
+ switch (this_board->io_access) {
+ case IO_8b:
+ s->insn_bits = pci_dio_insn_bits_di_b;
+ break;
+ case IO_16b:
+ s->insn_bits = pci_dio_insn_bits_di_w;
+ break;
+ }
+ s->private = (void *)d;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_add_do(struct comedi_device * dev, struct comedi_subdevice * s,
+ const struct diosubd_data * d, int subdev)
+{
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_COMMON;
+ if (d->chans > 16)
+ s->subdev_flags |= SDF_LSAMPL;
+ s->n_chan = d->chans;
+ s->maxdata = 1;
+ s->len_chanlist = d->chans;
+ s->range_table = &range_digital;
+ s->state = 0;
+ switch (this_board->io_access) {
+ case IO_8b:
+ s->insn_bits = pci_dio_insn_bits_do_b;
+ break;
+ case IO_16b:
+ s->insn_bits = pci_dio_insn_bits_do_w;
+ break;
+ }
+ s->private = (void *)d;
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int CheckAndAllocCard(struct comedi_device * dev, struct comedi_devconfig * it,
+ struct pci_dev *pcidev)
+{
+ struct pci_dio_private *pr, *prev;
+
+ for (pr = pci_priv, prev = NULL; pr != NULL; prev = pr, pr = pr->next) {
+ if (pr->pcidev == pcidev) {
+ return 0; /* this card is used, look for another */
+ }
+ }
+
+ if (prev) {
+ devpriv->prev = prev;
+ prev->next = devpriv;
+ } else {
+ pci_priv = devpriv;
+ }
+
+ devpriv->pcidev = pcidev;
+
+ return 1;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret, subdev, n_subdevices, i, j;
+ unsigned long iobase;
+ struct pci_dev *pcidev;
+
+ rt_printk("comedi%d: adv_pci_dio: ", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct pci_dio_private))) < 0) {
+ rt_printk(", Error: Cann't allocate private memory!\n");
+ return -ENOMEM;
+ }
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ /* loop through cards supported by this driver */
+ for (i = 0; i < n_boardtypes; ++i) {
+ if (boardtypes[i].vendor_id != pcidev->vendor)
+ continue;
+ if (boardtypes[i].device_id != pcidev->device)
+ continue;
+ /* was a particular bus/slot requested? */
+ if (it->options[0] || it->options[1]) {
+ /* are we on the wrong bus/slot? */
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ ret = CheckAndAllocCard(dev, it, pcidev);
+ if (ret != 1) continue;
+ dev->board_ptr = boardtypes + i;
+ break;
+ }
+ if (dev->board_ptr)
+ break;
+ }
+
+ if (!dev->board_ptr) {
+ rt_printk
+ (", Error: Requested type of the card was not found!\n");
+ return -EIO;
+ }
+
+ if (comedi_pci_enable(pcidev, driver_pci_dio.driver_name)) {
+ rt_printk
+ (", Error: Can't enable PCI device and request regions!\n");
+ return -EIO;
+ }
+ iobase = pci_resource_start(pcidev, this_board->main_pci_region);
+ rt_printk(", b:s:f=%d:%d:%d, io=0x%4lx",
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn),
+ PCI_FUNC(pcidev->devfn), iobase);
+
+ dev->iobase = iobase;
+ dev->board_name = this_board->name;
+
+ if (this_board->cardtype == TYPE_PCI1760) {
+ n_subdevices = 4; /* 8 IDI, 8 IDO, 2 PWM, 8 CNT */
+ } else {
+ n_subdevices = 0;
+ for (i = 0; i < MAX_DI_SUBDEVS; i++)
+ if (this_board->sdi[i].chans)
+ n_subdevices++;
+ for (i = 0; i < MAX_DO_SUBDEVS; i++)
+ if (this_board->sdo[i].chans)
+ n_subdevices++;
+ for (i = 0; i < MAX_DIO_SUBDEVG; i++)
+ n_subdevices += this_board->sdio[i].regs;
+ if (this_board->boardid.chans)
+ n_subdevices++;
+ }
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ rt_printk(", Error: Cann't allocate subdevice memory!\n");
+ return ret;
+ }
+
+ rt_printk(".\n");
+
+ subdev = 0;
+
+ for (i = 0; i < MAX_DI_SUBDEVS; i++)
+ if (this_board->sdi[i].chans) {
+ s = dev->subdevices + subdev;
+ pci_dio_add_di(dev, s, &this_board->sdi[i], subdev);
+ subdev++;
+ }
+
+ for (i = 0; i < MAX_DO_SUBDEVS; i++)
+ if (this_board->sdo[i].chans) {
+ s = dev->subdevices + subdev;
+ pci_dio_add_do(dev, s, &this_board->sdo[i], subdev);
+ subdev++;
+ }
+
+ for (i = 0; i < MAX_DIO_SUBDEVG; i++)
+ for (j = 0; j < this_board->sdio[i].regs; j++) {
+ s = dev->subdevices + subdev;
+ subdev_8255_init(dev, s, NULL,
+ dev->iobase + this_board->sdio[i].addr +
+ SIZE_8255 * j);
+ subdev++;
+ }
+
+ if (this_board->boardid.chans) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ pci_dio_add_di(dev, s, &this_board->boardid, subdev);
+ subdev++;
+ }
+
+ if (this_board->cardtype == TYPE_PCI1760)
+ pci1760_attach(dev, it);
+
+ devpriv->valid = 1;
+
+ pci_dio_reset(dev);
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pci_dio_detach(struct comedi_device * dev)
+{
+ int i, j;
+ struct comedi_subdevice *s;
+ int subdev;
+
+ if (dev->private) {
+ if (devpriv->valid) {
+ pci_dio_reset(dev);
+ }
+
+ /* This shows the silliness of using this kind of
+ * scheme for numbering subdevices. Don't do it. --ds */
+ subdev = 0;
+ for (i = 0; i < MAX_DI_SUBDEVS; i++) {
+ if (this_board->sdi[i].chans) {
+ subdev++;
+ }
+ }
+ for (i = 0; i < MAX_DO_SUBDEVS; i++) {
+ if (this_board->sdo[i].chans) {
+ subdev++;
+ }
+ }
+ for (i = 0; i < MAX_DIO_SUBDEVG; i++) {
+ for (j = 0; j < this_board->sdio[i].regs; j++) {
+ s = dev->subdevices + subdev;
+ subdev_8255_cleanup(dev, s);
+ subdev++;
+ }
+ }
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ s = dev->subdevices + i;
+ s->private = NULL;
+ }
+
+ if (devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+
+ if (devpriv->prev) {
+ devpriv->prev->next = devpriv->next;
+ } else {
+ pci_priv = devpriv->next;
+ }
+ if (devpriv->next) {
+ devpriv->next->prev = devpriv->prev;
+ }
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+COMEDI_PCI_INITCLEANUP(driver_pci_dio, pci_dio_pci_table);
+/*
+==============================================================================
+*/
diff --git a/drivers/staging/comedi/drivers/aio_aio12_8.c b/drivers/staging/comedi/drivers/aio_aio12_8.c
new file mode 100644
index 00000000000..b97b4d82611
--- /dev/null
+++ b/drivers/staging/comedi/drivers/aio_aio12_8.c
@@ -0,0 +1,226 @@
+/*
+
+ comedi/drivers/aio_aio12_8.c
+
+ Driver for Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+ Copyright (C) 2006 C&C Technologies, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+
+Driver: aio_aio12_8
+Description: Acces I/O Products PC-104 AIO12-8 Analog I/O Board
+Author: Pablo Mejia <pablo.mejia@cctechnol.com>
+Devices:
+ [Acces I/O] PC-104 AIO12-8
+Status: experimental
+
+Configuration Options:
+ [0] - I/O port base address
+
+Notes:
+
+ Only synchronous operations are supported.
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+#include "8255.h"
+
+#define AIO12_8_STATUS 0x00
+#define AIO12_8_INTERRUPT 0x01
+#define AIO12_8_ADC 0x02
+#define AIO12_8_DAC_0 0x04
+#define AIO12_8_DAC_1 0x06
+#define AIO12_8_DAC_2 0x08
+#define AIO12_8_DAC_3 0x0A
+#define AIO12_8_COUNTER_0 0x0C
+#define AIO12_8_COUNTER_1 0x0D
+#define AIO12_8_COUNTER_2 0x0E
+#define AIO12_8_COUNTER_CONTROL 0x0F
+#define AIO12_8_DIO_0 0x10
+#define AIO12_8_DIO_1 0x11
+#define AIO12_8_DIO_2 0x12
+#define AIO12_8_DIO_STATUS 0x13
+#define AIO12_8_DIO_CONTROL 0x14
+#define AIO12_8_ADC_TRIGGER_CONTROL 0x15
+#define AIO12_8_TRIGGER 0x16
+#define AIO12_8_POWER 0x17
+
+#define STATUS_ADC_EOC 0x80
+
+#define ADC_MODE_NORMAL 0x00
+#define ADC_MODE_INTERNAL_CLOCK 0x40
+#define ADC_MODE_STANDBY 0x80
+#define ADC_MODE_POWERDOWN 0xC0
+
+#define DAC_ENABLE 0x18
+
+struct aio12_8_boardtype {
+ const char *name;
+};
+
+static const struct aio12_8_boardtype board_types[] = {
+ {
+ name: "aio_aio12_8"},
+};
+
+#define thisboard ((const struct aio12_8_boardtype *) dev->board_ptr)
+
+struct aio12_8_private {
+ unsigned int ao_readback[4];
+};
+
+#define devpriv ((struct aio12_8_private *) dev->private)
+
+static int aio_aio12_8_ai_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned char control =
+ ADC_MODE_NORMAL |
+ (CR_RANGE(insn->chanspec) << 3) | CR_CHAN(insn->chanspec);
+
+ //read status to clear EOC latch
+ inb(dev->iobase + AIO12_8_STATUS);
+
+ for (n = 0; n < insn->n; n++) {
+ int timeout = 5;
+
+ // Setup and start conversion
+ outb(control, dev->iobase + AIO12_8_ADC);
+
+ // Wait for conversion to complete
+ while (timeout &&
+ !(inb(dev->iobase + AIO12_8_STATUS) & STATUS_ADC_EOC)) {
+ timeout--;
+ printk("timeout %d\n", timeout);
+ comedi_udelay(1);
+ }
+ if (timeout == 0) {
+ comedi_error(dev, "ADC timeout");
+ return -EIO;
+ }
+
+ data[n] = inw(dev->iobase + AIO12_8_ADC) & 0x0FFF;
+ }
+ return n;
+}
+
+static int aio_aio12_8_ao_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int val = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = val;
+ return insn->n;
+}
+
+static int aio_aio12_8_ao_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned long port = dev->iobase + AIO12_8_DAC_0 + (2 * chan);
+
+ //enable DACs
+ outb(0x01, dev->iobase + DAC_ENABLE);
+
+ for (i = 0; i < insn->n; i++) {
+ outb(data[i] & 0xFF, port); // LSB
+ outb((data[i] >> 8) & 0x0F, port + 1); // MSB
+ devpriv->ao_readback[chan] = data[i];
+ }
+ return insn->n;
+}
+
+static const struct comedi_lrange range_aio_aio12_8 = {
+ 4,
+ {
+ UNI_RANGE(5),
+ BIP_RANGE(5),
+ UNI_RANGE(10),
+ BIP_RANGE(10),
+ }
+};
+
+static int aio_aio12_8_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int iobase;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ if (!request_region(iobase, 24, "aio_aio12_8")) {
+ printk("I/O port conflict");
+ return -EIO;
+ }
+
+ dev->board_name = thisboard->name;
+
+ dev->iobase = iobase;
+
+ if (alloc_private(dev, sizeof(struct aio12_8_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = &dev->subdevices[0];
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+ s->n_chan = 8;
+ s->maxdata = (1 << 12) - 1;
+ s->range_table = &range_aio_aio12_8;
+ s->insn_read = aio_aio12_8_ai_read;
+
+ s = &dev->subdevices[1];
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_DIFF;
+ s->n_chan = 4;
+ s->maxdata = (1 << 12) - 1;
+ s->range_table = &range_aio_aio12_8;
+ s->insn_read = aio_aio12_8_ao_read;
+ s->insn_write = aio_aio12_8_ao_write;
+
+ s = &dev->subdevices[2];
+ subdev_8255_init(dev, s, NULL, dev->iobase + AIO12_8_DIO_0);
+
+ return 0;
+}
+
+static int aio_aio12_8_detach(struct comedi_device * dev)
+{
+ subdev_8255_cleanup(dev, &dev->subdevices[2]);
+ if (dev->iobase)
+ release_region(dev->iobase, 24);
+ return 0;
+}
+
+static struct comedi_driver driver_aio_aio12_8 = {
+ driver_name:"aio_aio12_8",
+ module:THIS_MODULE,
+ attach:aio_aio12_8_attach,
+ detach:aio_aio12_8_detach,
+ board_name:&board_types[0].name,
+ num_names:1,
+ offset:sizeof(struct aio12_8_boardtype),
+};
+
+COMEDI_INITCLEANUP(driver_aio_aio12_8);
diff --git a/drivers/staging/comedi/drivers/aio_iiro_16.c b/drivers/staging/comedi/drivers/aio_iiro_16.c
new file mode 100644
index 00000000000..9160fdf0ca3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/aio_iiro_16.c
@@ -0,0 +1,177 @@
+/*
+
+ comedi/drivers/aio_iiro_16.c
+
+ Driver for Acces I/O Products PC-104 AIO-IIRO-16 Digital I/O board
+ Copyright (C) 2006 C&C Technologies, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+
+Driver: aio_iiro_16
+Description: Acces I/O Products PC-104 IIRO16 Relay And Isolated Input Board
+Author: Zachary Ware <zach.ware@cctechnol.com>
+Devices:
+ [Acces I/O] PC-104 AIO12-8
+Status: experimental
+
+Configuration Options:
+ [0] - I/O port base address
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define AIO_IIRO_16_SIZE 0x08
+#define AIO_IIRO_16_RELAY_0_7 0x00
+#define AIO_IIRO_16_INPUT_0_7 0x01
+#define AIO_IIRO_16_IRQ 0x02
+#define AIO_IIRO_16_RELAY_8_15 0x04
+#define AIO_IIRO_16_INPUT_8_15 0x05
+
+struct aio_iiro_16_board {
+ const char *name;
+ int do_;
+ int di;
+};
+
+static const struct aio_iiro_16_board aio_iiro_16_boards[] = {
+ {
+ name: "aio_iiro_16",
+ di: 16,
+ do_: 16},
+};
+
+#define thisboard ((const struct aio_iiro_16_board *) dev->board_ptr)
+
+struct aio_iiro_16_private {
+ int data;
+ struct pci_dev *pci_dev;
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct aio_iiro_16_private *) dev->private)
+
+static int aio_iiro_16_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static int aio_iiro_16_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_aio_iiro_16 = {
+ driver_name:"aio_iiro_16",
+ module:THIS_MODULE,
+ attach:aio_iiro_16_attach,
+ detach:aio_iiro_16_detach,
+ board_name:&aio_iiro_16_boards[0].name,
+ offset:sizeof(struct aio_iiro_16_board),
+ num_names:sizeof(aio_iiro_16_boards) / sizeof(struct aio_iiro_16_board),
+};
+
+static int aio_iiro_16_dio_insn_bits_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int aio_iiro_16_dio_insn_bits_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int aio_iiro_16_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int iobase;
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: aio_iiro_16: ", dev->minor);
+
+ dev->board_name = thisboard->name;
+
+ iobase = it->options[0];
+
+ if (!request_region(iobase, AIO_IIRO_16_SIZE, dev->board_name)) {
+ printk("I/O port conflict");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ if (alloc_private(dev, sizeof(struct aio_iiro_16_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = aio_iiro_16_dio_insn_bits_write;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = aio_iiro_16_dio_insn_bits_read;
+
+ printk("attached\n");
+
+ return 1;
+}
+
+static int aio_iiro_16_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: aio_iiro_16: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, AIO_IIRO_16_SIZE);
+
+ return 0;
+}
+
+static int aio_iiro_16_dio_insn_bits_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outb(s->state & 0xff, dev->iobase + AIO_IIRO_16_RELAY_0_7);
+ outb((s->state >> 8) & 0xff,
+ dev->iobase + AIO_IIRO_16_RELAY_8_15);
+ }
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int aio_iiro_16_dio_insn_bits_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = 0;
+ data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_0_7);
+ data[1] |= inb(dev->iobase + AIO_IIRO_16_INPUT_8_15) << 8;
+
+ return 2;
+}
+
+COMEDI_INITCLEANUP(driver_aio_iiro_16);
diff --git a/drivers/staging/comedi/drivers/am9513.h b/drivers/staging/comedi/drivers/am9513.h
new file mode 100644
index 00000000000..f533cf1658c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/am9513.h
@@ -0,0 +1,79 @@
+/*
+ module/am9513.h
+ value added preprocessor definitions for Am9513 timer chip
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _AM9513_H_
+#define _AM9513_H_
+
+#if 0
+
+/*
+ * Before including this file, the following need to be defined:
+ */
+#define Am9513_8BITBUS xxx
+/* or */
+#define Am9513_16BITBUS xxx
+
+#define Am9513_output_control(a) xxx
+#define Am9513_input_status() xxx
+#define Am9513_output_data(a) xxx
+#define Am9513_input_data() xxx
+
+#endif
+
+/*
+ *
+ */
+
+#ifdef Am9513_8BITBUS
+
+#define Am9513_write_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ Am9513_output_data(val>>8); \
+ Am9513_output_data(val&0xff); \
+ }while(0)
+
+#define Am9513_read_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ val=Am9513_input_data()<<8; \
+ val|=Am9513_input_data(); \
+ }while(0)
+
+#else /* Am9513_16BITBUS */
+
+#define Am9513_write_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ Am9513_output_data(val); \
+ }while(0)
+
+#define Am9513_read_register(reg,val) \
+ do{ \
+ Am9513_output_control(reg); \
+ val=Am9513_input_data(); \
+ }while(0)
+
+#endif
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amcc_s5933.h b/drivers/staging/comedi/drivers/amcc_s5933.h
new file mode 100644
index 00000000000..aceffce7ef3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amcc_s5933.h
@@ -0,0 +1,172 @@
+/*
+ comedi/drivers/amcc_s5933.h
+
+ Stuff for AMCC S5933 PCI Controller
+
+ Author: Michal Dobes <dobes@tesnet.cz>
+
+ Inspirated from general-purpose AMCC S5933 PCI Matchmaker driver
+ made by Andrea Cisternino <acister@pcape1.pi.infn.it>
+ and as result of espionage from MITE code made by David A. Schleef.
+ Thanks to AMCC for their on-line documentation and bus master DMA
+ example.
+*/
+
+#ifndef _AMCC_S5933_H_
+#define _AMCC_S5933_H_
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_OMB1 0x00
+#define AMCC_OP_REG_OMB2 0x04
+#define AMCC_OP_REG_OMB3 0x08
+#define AMCC_OP_REG_OMB4 0x0c
+#define AMCC_OP_REG_IMB1 0x10
+#define AMCC_OP_REG_IMB2 0x14
+#define AMCC_OP_REG_IMB3 0x18
+#define AMCC_OP_REG_IMB4 0x1c
+#define AMCC_OP_REG_FIFO 0x20
+#define AMCC_OP_REG_MWAR 0x24
+#define AMCC_OP_REG_MWTC 0x28
+#define AMCC_OP_REG_MRAR 0x2c
+#define AMCC_OP_REG_MRTC 0x30
+#define AMCC_OP_REG_MBEF 0x34
+#define AMCC_OP_REG_INTCSR 0x38
+#define AMCC_OP_REG_INTCSR_SRC (AMCC_OP_REG_INTCSR + 2) /* INT source */
+#define AMCC_OP_REG_INTCSR_FEC (AMCC_OP_REG_INTCSR + 3) /* FIFO ctrl */
+#define AMCC_OP_REG_MCSR 0x3c
+#define AMCC_OP_REG_MCSR_NVDATA (AMCC_OP_REG_MCSR + 2) /* Data in byte 2 */
+#define AMCC_OP_REG_MCSR_NVCMD (AMCC_OP_REG_MCSR + 3) /* Command in byte 3 */
+
+#define AMCC_FIFO_DEPTH_DWORD 8
+#define AMCC_FIFO_DEPTH_BYTES (8 * sizeof (u32))
+
+/****************************************************************************/
+/* AMCC - PCI Interrupt Control/Status Register */
+/****************************************************************************/
+#define INTCSR_OUTBOX_BYTE(x) ((x) & 0x3)
+#define INTCSR_OUTBOX_SELECT(x) (((x) & 0x3) << 2)
+#define INTCSR_OUTBOX_EMPTY_INT 0x10 // enable outbox empty interrupt
+#define INTCSR_INBOX_BYTE(x) (((x) & 0x3) << 8)
+#define INTCSR_INBOX_SELECT(x) (((x) & 0x3) << 10)
+#define INTCSR_INBOX_FULL_INT 0x1000 // enable inbox full interrupt
+#define INTCSR_INBOX_INTR_STATUS 0x20000 // read, or write clear inbox full interrupt
+#define INTCSR_INTR_ASSERTED 0x800000 // read only, interrupt asserted
+
+/****************************************************************************/
+/* AMCC - PCI non-volatile ram command register (byte 3 of master control/status register) */
+/****************************************************************************/
+#define MCSR_NV_LOAD_LOW_ADDR 0x0
+#define MCSR_NV_LOAD_HIGH_ADDR 0x20
+#define MCSR_NV_WRITE 0x40
+#define MCSR_NV_READ 0x60
+#define MCSR_NV_MASK 0x60
+#define MCSR_NV_ENABLE 0x80
+#define MCSR_NV_BUSY MCSR_NV_ENABLE
+
+/****************************************************************************/
+/* AMCC Operation Registers Size - PCI */
+/****************************************************************************/
+
+#define AMCC_OP_REG_SIZE 64 /* in bytes */
+
+/****************************************************************************/
+/* AMCC Operation Register Offsets - Add-on */
+/****************************************************************************/
+
+#define AMCC_OP_REG_AIMB1 0x00
+#define AMCC_OP_REG_AIMB2 0x04
+#define AMCC_OP_REG_AIMB3 0x08
+#define AMCC_OP_REG_AIMB4 0x0c
+#define AMCC_OP_REG_AOMB1 0x10
+#define AMCC_OP_REG_AOMB2 0x14
+#define AMCC_OP_REG_AOMB3 0x18
+#define AMCC_OP_REG_AOMB4 0x1c
+#define AMCC_OP_REG_AFIFO 0x20
+#define AMCC_OP_REG_AMWAR 0x24
+#define AMCC_OP_REG_APTA 0x28
+#define AMCC_OP_REG_APTD 0x2c
+#define AMCC_OP_REG_AMRAR 0x30
+#define AMCC_OP_REG_AMBEF 0x34
+#define AMCC_OP_REG_AINT 0x38
+#define AMCC_OP_REG_AGCSTS 0x3c
+#define AMCC_OP_REG_AMWTC 0x58
+#define AMCC_OP_REG_AMRTC 0x5c
+
+/****************************************************************************/
+/* AMCC - Add-on General Control/Status Register */
+/****************************************************************************/
+
+#define AGCSTS_CONTROL_MASK 0xfffff000
+#define AGCSTS_NV_ACC_MASK 0xe0000000
+#define AGCSTS_RESET_MASK 0x0e000000
+#define AGCSTS_NV_DA_MASK 0x00ff0000
+#define AGCSTS_BIST_MASK 0x0000f000
+#define AGCSTS_STATUS_MASK 0x000000ff
+#define AGCSTS_TCZERO_MASK 0x000000c0
+#define AGCSTS_FIFO_ST_MASK 0x0000003f
+
+#define AGCSTS_RESET_MBFLAGS 0x08000000
+#define AGCSTS_RESET_P2A_FIFO 0x04000000
+#define AGCSTS_RESET_A2P_FIFO 0x02000000
+#define AGCSTS_RESET_FIFOS (AGCSTS_RESET_A2P_FIFO | AGCSTS_RESET_P2A_FIFO)
+
+#define AGCSTS_A2P_TCOUNT 0x00000080
+#define AGCSTS_P2A_TCOUNT 0x00000040
+
+#define AGCSTS_FS_P2A_EMPTY 0x00000020
+#define AGCSTS_FS_P2A_HALF 0x00000010
+#define AGCSTS_FS_P2A_FULL 0x00000008
+
+#define AGCSTS_FS_A2P_EMPTY 0x00000004
+#define AGCSTS_FS_A2P_HALF 0x00000002
+#define AGCSTS_FS_A2P_FULL 0x00000001
+
+/****************************************************************************/
+/* AMCC - Add-on Interrupt Control/Status Register */
+/****************************************************************************/
+
+#define AINT_INT_MASK 0x00ff0000
+#define AINT_SEL_MASK 0x0000ffff
+#define AINT_IS_ENSEL_MASK 0x00001f1f
+
+#define AINT_INT_ASSERTED 0x00800000
+#define AINT_BM_ERROR 0x00200000
+#define AINT_BIST_INT 0x00100000
+
+#define AINT_RT_COMPLETE 0x00080000
+#define AINT_WT_COMPLETE 0x00040000
+
+#define AINT_OUT_MB_INT 0x00020000
+#define AINT_IN_MB_INT 0x00010000
+
+#define AINT_READ_COMPL 0x00008000
+#define AINT_WRITE_COMPL 0x00004000
+
+#define AINT_OMB_ENABLE 0x00001000
+#define AINT_OMB_SELECT 0x00000c00
+#define AINT_OMB_BYTE 0x00000300
+
+#define AINT_IMB_ENABLE 0x00000010
+#define AINT_IMB_SELECT 0x0000000c
+#define AINT_IMB_BYTE 0x00000003
+
+// these are bits from various different registers, needs cleanup XXX
+/* Enable Bus Mastering */
+#define EN_A2P_TRANSFERS 0x00000400
+/* FIFO Flag Reset */
+#define RESET_A2P_FLAGS 0x04000000L
+/* FIFO Relative Priority */
+#define A2P_HI_PRIORITY 0x00000100L
+/* Identify Interrupt Sources */
+#define ANY_S593X_INT 0x00800000L
+#define READ_TC_INT 0x00080000L
+#define WRITE_TC_INT 0x00040000L
+#define IN_MB_INT 0x00020000L
+#define MASTER_ABORT_INT 0x00100000L
+#define TARGET_ABORT_INT 0x00200000L
+#define BUS_MASTER_INT 0x00200000L
+
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_dio200.c b/drivers/staging/comedi/drivers/amplc_dio200.c
new file mode 100644
index 00000000000..8555e272a86
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_dio200.c
@@ -0,0 +1,1483 @@
+/*
+ comedi/drivers/amplc_dio200.c
+ Driver for Amplicon PC272E and PCI272 DIO boards.
+ (Support for other boards in Amplicon 200 series may be added at
+ a later date, e.g. PCI215.)
+
+ Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_dio200
+Description: Amplicon 200 Series Digital I/O
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC212E (pc212e), PC214E (pc214e), PC215E (pc215e),
+ PCI215 (pci215 or amplc_dio200), PC218E (pc218e), PC272E (pc272e),
+ PCI272 (pci272 or amplc_dio200)
+Updated: Wed, 22 Oct 2008 13:36:02 +0100
+Status: works
+
+Configuration options - PC212E, PC214E, PC215E, PC218E, PC272E:
+ [0] - I/O port base address
+ [1] - IRQ (optional, but commands won't work without it)
+
+Configuration options - PCI215, PCI272:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will
+ be used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+SUBDEVICES
+
+ PC218E PC212E PC215E/PCI215
+ ------------- ------------- -------------
+ Subdevices 7 6 5
+ 0 CTR-X1 PPI-X PPI-X
+ 1 CTR-X2 CTR-Y1 PPI-Y
+ 2 CTR-Y1 CTR-Y2 CTR-Z1
+ 3 CTR-Y2 CTR-Z1 CTR-Z2
+ 4 CTR-Z1 CTR-Z2 INTERRUPT
+ 5 CTR-Z2 INTERRUPT
+ 6 INTERRUPT
+
+ PC214E PC272E/PCI272
+ ------------- -------------
+ Subdevices 4 4
+ 0 PPI-X PPI-X
+ 1 PPI-Y PPI-Y
+ 2 CTR-Z1* PPI-Z
+ 3 INTERRUPT* INTERRUPT
+
+Each PPI is a 8255 chip providing 24 DIO channels. The DIO channels
+are configurable as inputs or outputs in four groups:
+
+ Port A - channels 0 to 7
+ Port B - channels 8 to 15
+ Port CL - channels 16 to 19
+ Port CH - channels 20 to 23
+
+Only mode 0 of the 8255 chips is supported.
+
+Each CTR is a 8254 chip providing 3 16-bit counter channels. Each
+channel is configured individually with INSN_CONFIG instructions. The
+specific type of configuration instruction is specified in data[0].
+Some configuration instructions expect an additional parameter in
+data[1]; others return a value in data[1]. The following configuration
+instructions are supported:
+
+ INSN_CONFIG_SET_COUNTER_MODE. Sets the counter channel's mode and
+ BCD/binary setting specified in data[1].
+
+ INSN_CONFIG_8254_READ_STATUS. Reads the status register value for the
+ counter channel into data[1].
+
+ INSN_CONFIG_SET_CLOCK_SRC. Sets the counter channel's clock source as
+ specified in data[1] (this is a hardware-specific value). Not
+ supported on PC214E. For the other boards, valid clock sources are
+ 0 to 7 as follows:
+
+ 0. CLK n, the counter channel's dedicated CLK input from the SK1
+ connector. (N.B. for other values, the counter channel's CLKn
+ pin on the SK1 connector is an output!)
+ 1. Internal 10 MHz clock.
+ 2. Internal 1 MHz clock.
+ 3. Internal 100 kHz clock.
+ 4. Internal 10 kHz clock.
+ 5. Internal 1 kHz clock.
+ 6. OUT n-1, the output of counter channel n-1 (see note 1 below).
+ 7. Ext Clock, the counter chip's dedicated Ext Clock input from
+ the SK1 connector. This pin is shared by all three counter
+ channels on the chip.
+
+ INSN_CONFIG_GET_CLOCK_SRC. Returns the counter channel's current
+ clock source in data[1]. For internal clock sources, data[2] is set
+ to the period in ns.
+
+ INSN_CONFIG_SET_GATE_SRC. Sets the counter channel's gate source as
+ specified in data[2] (this is a hardware-specific value). Not
+ supported on PC214E. For the other boards, valid gate sources are 0
+ to 7 as follows:
+
+ 0. VCC (internal +5V d.c.), i.e. gate permanently enabled.
+ 1. GND (internal 0V d.c.), i.e. gate permanently disabled.
+ 2. GAT n, the counter channel's dedicated GAT input from the SK1
+ connector. (N.B. for other values, the counter channel's GATn
+ pin on the SK1 connector is an output!)
+ 3. /OUT n-2, the inverted output of counter channel n-2 (see note
+ 2 below).
+ 4. Reserved.
+ 5. Reserved.
+ 6. Reserved.
+ 7. Reserved.
+
+ INSN_CONFIG_GET_GATE_SRC. Returns the counter channel's current gate
+ source in data[2].
+
+Clock and gate interconnection notes:
+
+ 1. Clock source OUT n-1 is the output of the preceding channel on the
+ same counter subdevice if n > 0, or the output of channel 2 on the
+ preceding counter subdevice (see note 3) if n = 0.
+
+ 2. Gate source /OUT n-2 is the inverted output of channel 0 on the
+ same counter subdevice if n = 2, or the inverted output of channel n+1
+ on the preceding counter subdevice (see note 3) if n < 2.
+
+ 3. The counter subdevices are connected in a ring, so the highest
+ counter subdevice precedes the lowest.
+
+The 'INTERRUPT' subdevice pretends to be a digital input subdevice. The
+digital inputs come from the interrupt status register. The number of
+channels matches the number of interrupt sources. The PC214E does not
+have an interrupt status register; see notes on 'INTERRUPT SOURCES'
+below.
+
+INTERRUPT SOURCES
+
+ PC218E PC212E PC215E/PCI215
+ ------------- ------------- -------------
+ Sources 6 6 6
+ 0 CTR-X1-OUT PPI-X-C0 PPI-X-C0
+ 1 CTR-X2-OUT PPI-X-C3 PPI-X-C3
+ 2 CTR-Y1-OUT CTR-Y1-OUT PPI-Y-C0
+ 3 CTR-Y2-OUT CTR-Y2-OUT PPI-Y-C3
+ 4 CTR-Z1-OUT CTR-Z1-OUT CTR-Z1-OUT
+ 5 CTR-Z2-OUT CTR-Z2-OUT CTR-Z2-OUT
+
+ PC214E PC272E/PCI272
+ ------------- -------------
+ Sources 1 6
+ 0 JUMPER-J5 PPI-X-C0
+ 1 PPI-X-C3
+ 2 PPI-Y-C0
+ 3 PPI-Y-C3
+ 4 PPI-Z-C0
+ 5 PPI-Z-C3
+
+When an interrupt source is enabled in the interrupt source enable
+register, a rising edge on the source signal latches the corresponding
+bit to 1 in the interrupt status register.
+
+When the interrupt status register value as a whole (actually, just the
+6 least significant bits) goes from zero to non-zero, the board will
+generate an interrupt. For level-triggered hardware interrupts (PCI
+card), the interrupt will remain asserted until the interrupt status
+register is cleared to zero. For edge-triggered hardware interrupts
+(ISA card), no further interrupts will occur until the interrupt status
+register is cleared to zero. To clear a bit to zero in the interrupt
+status register, the corresponding interrupt source must be disabled
+in the interrupt source enable register (there is no separate interrupt
+clear register).
+
+The PC214E does not have an interrupt source enable register or an
+interrupt status register; its 'INTERRUPT' subdevice has a single
+channel and its interrupt source is selected by the position of jumper
+J5.
+
+COMMANDS
+
+The driver supports a read streaming acquisition command on the
+'INTERRUPT' subdevice. The channel list selects the interrupt sources
+to be enabled. All channels will be sampled together (convert_src ==
+TRIG_NOW). The scan begins a short time after the hardware interrupt
+occurs, subject to interrupt latencies (scan_begin_src == TRIG_EXT,
+scan_begin_arg == 0). The value read from the interrupt status register
+is packed into a short value, one bit per requested channel, in the
+order they appear in the channel list.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+#include "8253.h"
+
+#define DIO200_DRIVER_NAME "amplc_dio200"
+
+/* PCI IDs */
+/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
+#define PCI_DEVICE_ID_AMPLICON_PCI272 0x000a
+#define PCI_DEVICE_ID_AMPLICON_PCI215 0x000b
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* 200 series registers */
+#define DIO200_IO_SIZE 0x20
+#define DIO200_XCLK_SCE 0x18 /* Group X clock selection register */
+#define DIO200_YCLK_SCE 0x19 /* Group Y clock selection register */
+#define DIO200_ZCLK_SCE 0x1a /* Group Z clock selection register */
+#define DIO200_XGAT_SCE 0x1b /* Group X gate selection register */
+#define DIO200_YGAT_SCE 0x1c /* Group Y gate selection register */
+#define DIO200_ZGAT_SCE 0x1d /* Group Z gate selection register */
+#define DIO200_INT_SCE 0x1e /* Interrupt enable/status register */
+
+/*
+ * Macros for constructing value for DIO_200_?CLK_SCE and
+ * DIO_200_?GAT_SCE registers:
+ *
+ * 'which' is: 0 for CTR-X1, CTR-Y1, CTR-Z1; 1 for CTR-X2, CTR-Y2 or CTR-Z2.
+ * 'chan' is the channel: 0, 1 or 2.
+ * 'source' is the signal source: 0 to 7.
+ */
+#define CLK_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
+#define GAT_SCE(which, chan, source) (((which) << 5) | ((chan) << 3) | (source))
+
+/*
+ * Periods of the internal clock sources in nanoseconds.
+ */
+static const unsigned clock_period[8] = {
+ 0, /* dedicated clock input/output pin */
+ 100, /* 10 MHz */
+ 1000, /* 1 MHz */
+ 10000, /* 100 kHz */
+ 100000, /* 10 kHz */
+ 1000000, /* 1 kHz */
+ 0, /* OUT N-1 */
+ 0 /* group clock input pin */
+};
+
+/*
+ * Board descriptions.
+ */
+
+enum dio200_bustype { isa_bustype, pci_bustype };
+
+enum dio200_model {
+ pc212e_model,
+ pc214e_model,
+ pc215e_model, pci215_model,
+ pc218e_model,
+ pc272e_model, pci272_model,
+ anypci_model
+};
+
+enum dio200_layout {
+ pc212_layout,
+ pc214_layout,
+ pc215_layout,
+ pc218_layout,
+ pc272_layout
+};
+
+struct dio200_board {
+ const char *name;
+ unsigned short devid;
+ enum dio200_bustype bustype;
+ enum dio200_model model;
+ enum dio200_layout layout;
+};
+
+static const struct dio200_board dio200_boards[] = {
+ {
+ name: "pc212e",
+ bustype: isa_bustype,
+ model: pc212e_model,
+ layout: pc212_layout,
+ },
+ {
+ name: "pc214e",
+ bustype: isa_bustype,
+ model: pc214e_model,
+ layout: pc214_layout,
+ },
+ {
+ name: "pc215e",
+ bustype: isa_bustype,
+ model: pc215e_model,
+ layout: pc215_layout,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci215",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI215,
+ bustype: pci_bustype,
+ model: pci215_model,
+ layout: pc215_layout,
+ },
+#endif
+ {
+ name: "pc218e",
+ bustype: isa_bustype,
+ model: pc218e_model,
+ layout: pc218_layout,
+ },
+ {
+ name: "pc272e",
+ bustype: isa_bustype,
+ model: pc272e_model,
+ layout: pc272_layout,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci272",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI272,
+ bustype: pci_bustype,
+ model: pci272_model,
+ layout: pc272_layout,
+ },
+#endif
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: DIO200_DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ bustype: pci_bustype,
+ model: anypci_model, /* wildcard */
+ },
+#endif
+};
+
+/*
+ * Layout descriptions - some ISA and PCI board descriptions share the same
+ * layout.
+ */
+
+enum dio200_sdtype { sd_none, sd_intr, sd_8255, sd_8254 };
+
+#define DIO200_MAX_SUBDEVS 7
+#define DIO200_MAX_ISNS 6
+
+struct dio200_layout_struct {
+ unsigned short n_subdevs; /* number of subdevices */
+ unsigned char sdtype[DIO200_MAX_SUBDEVS]; /* enum dio200_sdtype */
+ unsigned char sdinfo[DIO200_MAX_SUBDEVS]; /* depends on sdtype */
+ char has_int_sce; /* has interrupt enable/status register */
+ char has_clk_gat_sce; /* has clock/gate selection registers */
+};
+
+static const struct dio200_layout_struct dio200_layouts[] = {
+ [pc212_layout] = {
+ n_subdevs:6,
+ sdtype: {sd_8255, sd_8254, sd_8254, sd_8254,
+ sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x0C, 0x10, 0x14,
+ 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:1,
+ },
+ [pc214_layout] = {
+ n_subdevs:4,
+ sdtype: {sd_8255, sd_8255, sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x10, 0x01},
+ has_int_sce:0,
+ has_clk_gat_sce:0,
+ },
+ [pc215_layout] = {
+ n_subdevs:5,
+ sdtype: {sd_8255, sd_8255, sd_8254,
+ sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x10, 0x14, 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:1,
+ },
+ [pc218_layout] = {
+ n_subdevs:7,
+ sdtype: {sd_8254, sd_8254, sd_8255, sd_8254,
+ sd_8254,
+ sd_intr},
+ sdinfo: {0x00, 0x04, 0x08, 0x0C, 0x10,
+ 0x14,
+ 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:1,
+ },
+ [pc272_layout] = {
+ n_subdevs:4,
+ sdtype: {sd_8255, sd_8255, sd_8255,
+ sd_intr},
+ sdinfo: {0x00, 0x08, 0x10, 0x3F},
+ has_int_sce:1,
+ has_clk_gat_sce:0,
+ },
+};
+
+/*
+ * PCI driver table.
+ */
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(dio200_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI215,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI272,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, dio200_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dio200_board *)dev->board_ptr)
+#define thislayout (&dio200_layouts[((struct dio200_board *)dev->board_ptr)->layout])
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct dio200_private {
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev; /* PCI device */
+#endif
+ int intr_sd;
+};
+
+#define devpriv ((struct dio200_private *)dev->private)
+
+struct dio200_subdev_8254 {
+ unsigned long iobase; /* Counter base address */
+ unsigned long clk_sce_iobase; /* CLK_SCE base address */
+ unsigned long gat_sce_iobase; /* GAT_SCE base address */
+ int which; /* Bit 5 of CLK_SCE or GAT_SCE */
+ int has_clk_gat_sce;
+ unsigned clock_src[3]; /* Current clock sources */
+ unsigned gate_src[3]; /* Current gate sources */
+};
+
+struct dio200_subdev_intr {
+ unsigned long iobase;
+ spinlock_t spinlock;
+ int active;
+ int has_int_sce;
+ unsigned int valid_isns;
+ unsigned int enabled_isns;
+ unsigned int stopcount;
+ int continuous;
+};
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int dio200_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio200_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_dio200 = {
+ driver_name:DIO200_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:dio200_attach,
+ detach:dio200_detach,
+ board_name:&dio200_boards[0].name,
+ offset:sizeof(struct dio200_board),
+ num_names:sizeof(dio200_boards) / sizeof(struct dio200_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_dio200, dio200_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_dio200);
+#endif
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+dio200_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+ PCI_ANY_ID, pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == anypci_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(dio200_boards); i++) {
+ if (dio200_boards[i].bustype != pci_bustype)
+ continue;
+ if (pci_dev->device == dio200_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &dio200_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(dio200_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (pci_dev->device != thisboard->devid)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR
+ "comedi%d: error! no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+#endif
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int
+dio200_request_region(unsigned minor, unsigned long from, unsigned long extent)
+{
+ if (!from || !request_region(from, extent, DIO200_DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+ minor, from, extent);
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * 'insn_bits' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ if (subpriv->has_int_sce) {
+ /* Just read the interrupt status register. */
+ data[1] = inb(subpriv->iobase) & subpriv->valid_isns;
+ } else {
+ /* No interrupt status register. */
+ data[0] = 0;
+ }
+
+ return 2;
+}
+
+/*
+ * Called to stop acquisition for an 'INTERRUPT' subdevice.
+ */
+static void dio200_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ subpriv->active = 0;
+ subpriv->enabled_isns = 0;
+ if (subpriv->has_int_sce) {
+ outb(0, subpriv->iobase);
+ }
+}
+
+/*
+ * Called to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int dio200_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int n;
+ unsigned isn_bits;
+ struct dio200_subdev_intr *subpriv = s->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int retval = 0;
+
+ if (!subpriv->continuous && subpriv->stopcount == 0) {
+ /* An empty acquisition! */
+ s->async->events |= COMEDI_CB_EOA;
+ subpriv->active = 0;
+ retval = 1;
+ } else {
+ /* Determine interrupt sources to enable. */
+ isn_bits = 0;
+ if (cmd->chanlist) {
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ isn_bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+ }
+ }
+ isn_bits &= subpriv->valid_isns;
+ /* Enable interrupt sources. */
+ subpriv->enabled_isns = isn_bits;
+ if (subpriv->has_int_sce) {
+ outb(isn_bits, subpriv->iobase);
+ }
+ }
+
+ return retval;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ struct dio200_subdev_intr *subpriv;
+ unsigned long flags;
+ int event = 0;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ subpriv = s->private;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ s->async->inttrig = 0;
+ if (subpriv->active) {
+ event = dio200_start_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 1;
+}
+
+/*
+ * This is called from the interrupt service routine to handle a read
+ * scan on an 'INTERRUPT' subdevice.
+ */
+static int dio200_handle_read_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned triggered;
+ unsigned intstat;
+ unsigned cur_enabled;
+ unsigned int oldevents;
+ unsigned long flags;
+
+ triggered = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ oldevents = s->async->events;
+ if (subpriv->has_int_sce) {
+ /*
+ * Collect interrupt sources that have triggered and disable
+ * them temporarily. Loop around until no extra interrupt
+ * sources have triggered, at which point, the valid part of
+ * the interrupt status register will read zero, clearing the
+ * cause of the interrupt.
+ *
+ * Mask off interrupt sources already seen to avoid infinite
+ * loop in case of misconfiguration.
+ */
+ cur_enabled = subpriv->enabled_isns;
+ while ((intstat = (inb(subpriv->iobase) & subpriv->valid_isns
+ & ~triggered)) != 0) {
+ triggered |= intstat;
+ cur_enabled &= ~triggered;
+ outb(cur_enabled, subpriv->iobase);
+ }
+ } else {
+ /*
+ * No interrupt status register. Assume the single interrupt
+ * source has triggered.
+ */
+ triggered = subpriv->enabled_isns;
+ }
+
+ if (triggered) {
+ /*
+ * Some interrupt sources have triggered and have been
+ * temporarily disabled to clear the cause of the interrupt.
+ *
+ * Reenable them NOW to minimize the time they are disabled.
+ */
+ cur_enabled = subpriv->enabled_isns;
+ if (subpriv->has_int_sce) {
+ outb(cur_enabled, subpriv->iobase);
+ }
+
+ if (subpriv->active) {
+ /*
+ * The command is still active.
+ *
+ * Ignore interrupt sources that the command isn't
+ * interested in (just in case there's a race
+ * condition).
+ */
+ if (triggered & subpriv->enabled_isns) {
+ /* Collect scan data. */
+ short val;
+ unsigned int n, ch, len;
+
+ val = 0;
+ len = s->async->cmd.chanlist_len;
+ for (n = 0; n < len; n++) {
+ ch = CR_CHAN(s->async->cmd.chanlist[n]);
+ if (triggered & (1U << ch)) {
+ val |= (1U << n);
+ }
+ }
+ /* Write the scan to the buffer. */
+ if (comedi_buf_put(s->async, val)) {
+ s->async->events |= (COMEDI_CB_BLOCK |
+ COMEDI_CB_EOS);
+ } else {
+ /* Error! Stop acquisition. */
+ dio200_stop_intr(dev, s);
+ s->async->events |= COMEDI_CB_ERROR
+ | COMEDI_CB_OVERFLOW;
+ comedi_error(dev, "buffer overflow");
+ }
+
+ /* Check for end of acquisition. */
+ if (!subpriv->continuous) {
+ /* stop_src == TRIG_COUNT */
+ if (subpriv->stopcount > 0) {
+ subpriv->stopcount--;
+ if (subpriv->stopcount == 0) {
+ s->async->events |=
+ COMEDI_CB_EOA;
+ dio200_stop_intr(dev,
+ s);
+ }
+ }
+ }
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (oldevents != s->async->events) {
+ comedi_event(dev, s);
+ }
+
+ return (triggered != 0);
+}
+
+/*
+ * 'cancel' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ if (subpriv->active) {
+ dio200_stop_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= (TRIG_NOW | TRIG_INT);
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_src == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* any count allowed */
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ /* if (err) return 4; */
+
+ return 0;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int dio200_subdev_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ struct dio200_subdev_intr *subpriv = s->private;
+ unsigned long flags;
+ int event = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->spinlock, flags);
+ subpriv->active = 1;
+
+ /* Set up end of acquisition. */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ subpriv->continuous = 0;
+ subpriv->stopcount = cmd->stop_arg;
+ break;
+ default:
+ /* TRIG_NONE */
+ subpriv->continuous = 1;
+ subpriv->stopcount = 0;
+ break;
+ }
+
+ /* Set up start of acquisition. */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ s->async->inttrig = dio200_inttrig_start_intr;
+ break;
+ default:
+ /* TRIG_NOW */
+ event = dio200_start_intr(dev, s);
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 0;
+}
+
+/*
+ * This function initializes an 'INTERRUPT' subdevice.
+ */
+static int
+dio200_subdev_intr_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long iobase, unsigned valid_isns, int has_int_sce)
+{
+ struct dio200_subdev_intr *subpriv;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return -ENOMEM;
+ }
+ subpriv->iobase = iobase;
+ subpriv->has_int_sce = has_int_sce;
+ subpriv->valid_isns = valid_isns;
+ spin_lock_init(&subpriv->spinlock);
+
+ if (has_int_sce) {
+ outb(0, subpriv->iobase); /* Disable interrupt sources. */
+ }
+
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ if (has_int_sce) {
+ s->n_chan = DIO200_MAX_ISNS;
+ s->len_chanlist = DIO200_MAX_ISNS;
+ } else {
+ /* No interrupt source register. Support single channel. */
+ s->n_chan = 1;
+ s->len_chanlist = 1;
+ }
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = dio200_subdev_intr_insn_bits;
+ s->do_cmdtest = dio200_subdev_intr_cmdtest;
+ s->do_cmd = dio200_subdev_intr_cmd;
+ s->cancel = dio200_subdev_intr_cancel;
+
+ return 0;
+}
+
+/*
+ * This function cleans up an 'INTERRUPT' subdevice.
+ */
+static void
+dio200_subdev_intr_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ if (subpriv) {
+ kfree(subpriv);
+ }
+}
+
+/*
+ * Interrupt service routine.
+ */
+static irqreturn_t dio200_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ int handled;
+
+ if (!dev->attached) {
+ return IRQ_NONE;
+ }
+
+ if (devpriv->intr_sd >= 0) {
+ handled = dio200_handle_read_intr(dev,
+ dev->subdevices + devpriv->intr_sd);
+ } else {
+ handled = 0;
+ }
+
+ return IRQ_RETVAL(handled);
+}
+
+/*
+ * Handle 'insn_read' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int chan = CR_CHAN(insn->chanspec);
+
+ data[0] = i8254_read(subpriv->iobase, 0, chan);
+
+ return 1;
+}
+
+/*
+ * Handle 'insn_write' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int chan = CR_CHAN(insn->chanspec);
+
+ i8254_write(subpriv->iobase, 0, chan, data[0]);
+
+ return 1;
+}
+
+/*
+ * Set gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_set_gate_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+ unsigned int gate_src)
+{
+ unsigned char byte;
+
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+ if (gate_src > 7)
+ return -1;
+
+ subpriv->gate_src[counter_number] = gate_src;
+ byte = GAT_SCE(subpriv->which, counter_number, gate_src);
+ outb(byte, subpriv->gat_sce_iobase);
+
+ return 0;
+}
+
+/*
+ * Get gate source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_get_gate_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number)
+{
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+
+ return subpriv->gate_src[counter_number];
+}
+
+/*
+ * Set clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_set_clock_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+ unsigned int clock_src)
+{
+ unsigned char byte;
+
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+ if (clock_src > 7)
+ return -1;
+
+ subpriv->clock_src[counter_number] = clock_src;
+ byte = CLK_SCE(subpriv->which, counter_number, clock_src);
+ outb(byte, subpriv->clk_sce_iobase);
+
+ return 0;
+}
+
+/*
+ * Get clock source for an '8254' counter subdevice channel.
+ */
+static int
+dio200_get_clock_src(struct dio200_subdev_8254 * subpriv, unsigned int counter_number,
+ unsigned int * period_ns)
+{
+ unsigned clock_src;
+
+ if (!subpriv->has_clk_gat_sce)
+ return -1;
+ if (counter_number > 2)
+ return -1;
+
+ clock_src = subpriv->clock_src[counter_number];
+ *period_ns = clock_period[clock_src];
+ return clock_src;
+}
+
+/*
+ * Handle 'insn_config' for an '8254' counter subdevice.
+ */
+static int
+dio200_subdev_8254_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct dio200_subdev_8254 *subpriv = s->private;
+ int ret;
+ int chan = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case INSN_CONFIG_SET_COUNTER_MODE:
+ ret = i8254_set_mode(subpriv->iobase, 0, chan, data[1]);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+ case INSN_CONFIG_8254_READ_STATUS:
+ data[1] = i8254_status(subpriv->iobase, 0, chan);
+ break;
+ case INSN_CONFIG_SET_GATE_SRC:
+ ret = dio200_set_gate_src(subpriv, chan, data[2]);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+ case INSN_CONFIG_GET_GATE_SRC:
+ ret = dio200_get_gate_src(subpriv, chan);
+ if (ret < 0)
+ return -EINVAL;
+ data[2] = ret;
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ ret = dio200_set_clock_src(subpriv, chan, data[1]);
+ if (ret < 0)
+ return -EINVAL;
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ ret = dio200_get_clock_src(subpriv, chan, &data[2]);
+ if (ret < 0)
+ return -EINVAL;
+ data[1] = ret;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return insn->n;
+}
+
+/*
+ * This function initializes an '8254' counter subdevice.
+ *
+ * Note: iobase is the base address of the board, not the subdevice;
+ * offset is the offset to the 8254 chip.
+ */
+static int
+dio200_subdev_8254_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long iobase, unsigned offset, int has_clk_gat_sce)
+{
+ struct dio200_subdev_8254 *subpriv;
+ unsigned int chan;
+
+ subpriv = kzalloc(sizeof(*subpriv), GFP_KERNEL);
+ if (!subpriv) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return -ENOMEM;
+ }
+
+ s->private = subpriv;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 0xFFFF;
+ s->insn_read = dio200_subdev_8254_read;
+ s->insn_write = dio200_subdev_8254_write;
+ s->insn_config = dio200_subdev_8254_config;
+
+ subpriv->iobase = offset + iobase;
+ subpriv->has_clk_gat_sce = has_clk_gat_sce;
+ if (has_clk_gat_sce) {
+ /* Derive CLK_SCE and GAT_SCE register offsets from
+ * 8254 offset. */
+ subpriv->clk_sce_iobase =
+ DIO200_XCLK_SCE + (offset >> 3) + iobase;
+ subpriv->gat_sce_iobase =
+ DIO200_XGAT_SCE + (offset >> 3) + iobase;
+ subpriv->which = (offset >> 2) & 1;
+ }
+
+ /* Initialize channels. */
+ for (chan = 0; chan < 3; chan++) {
+ i8254_set_mode(subpriv->iobase, 0, chan,
+ I8254_MODE0 | I8254_BINARY);
+ if (subpriv->has_clk_gat_sce) {
+ /* Gate source 0 is VCC (logic 1). */
+ dio200_set_gate_src(subpriv, chan, 0);
+ /* Clock source 0 is the dedicated clock input. */
+ dio200_set_clock_src(subpriv, chan, 0);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function cleans up an '8254' counter subdevice.
+ */
+static void
+dio200_subdev_8254_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct dio200_subdev_intr *subpriv = s->private;
+
+ if (subpriv) {
+ kfree(subpriv);
+ }
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int dio200_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev = NULL;
+ int bus = 0, slot = 0;
+#endif
+ const struct dio200_layout_struct *layout;
+ int share_irq = 0;
+ int sdx;
+ unsigned n;
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+ DIO200_DRIVER_NAME);
+
+ if ((ret = alloc_private(dev, sizeof(struct dio200_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ /* Process options. */
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ irq = it->options[1];
+ share_irq = 0;
+ break;
+#ifdef CONFIG_COMEDI_PCI
+ case pci_bustype:
+ bus = it->options[0];
+ slot = it->options[1];
+ share_irq = 1;
+
+ if ((ret = dio200_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+ break;
+#endif
+ default:
+ printk(KERN_ERR
+ "comedi%d: %s: BUG! cannot determine board type!\n",
+ dev->minor, DIO200_DRIVER_NAME);
+ return -EINVAL;
+ break;
+ }
+
+ devpriv->intr_sd = -1;
+
+ /* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+ if (pci_dev) {
+ ret = comedi_pci_enable(pci_dev, DIO200_DRIVER_NAME);
+ if (ret < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device and request regions!\n",
+ dev->minor);
+ return ret;
+ }
+ iobase = pci_resource_start(pci_dev, 2);
+ irq = pci_dev->irq;
+ } else
+#endif
+ {
+ ret = dio200_request_region(dev->minor, iobase, DIO200_IO_SIZE);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ dev->iobase = iobase;
+
+ layout = thislayout;
+ if ((ret = alloc_subdevices(dev, layout->n_subdevs)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ for (n = 0; n < dev->n_subdevices; n++) {
+ s = &dev->subdevices[n];
+ switch (layout->sdtype[n]) {
+ case sd_8254:
+ /* counter subdevice (8254) */
+ ret = dio200_subdev_8254_init(dev, s, iobase,
+ layout->sdinfo[n], layout->has_clk_gat_sce);
+ if (ret < 0) {
+ return ret;
+ }
+ break;
+ case sd_8255:
+ /* digital i/o subdevice (8255) */
+ ret = subdev_8255_init(dev, s, 0,
+ iobase + layout->sdinfo[n]);
+ if (ret < 0) {
+ return ret;
+ }
+ break;
+ case sd_intr:
+ /* 'INTERRUPT' subdevice */
+ if (irq) {
+ ret = dio200_subdev_intr_init(dev, s,
+ iobase + DIO200_INT_SCE,
+ layout->sdinfo[n], layout->has_int_sce);
+ if (ret < 0) {
+ return ret;
+ }
+ devpriv->intr_sd = n;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ break;
+ default:
+ s->type = COMEDI_SUBD_UNUSED;
+ break;
+ }
+ }
+
+ sdx = devpriv->intr_sd;
+ if (sdx >= 0 && sdx < dev->n_subdevices) {
+ dev->read_subdev = &dev->subdevices[sdx];
+ }
+
+ dev->board_name = thisboard->name;
+
+ if (irq) {
+ unsigned long flags = share_irq ? IRQF_SHARED : 0;
+
+ if (comedi_request_irq(irq, dio200_interrupt, flags,
+ DIO200_DRIVER_NAME, dev) >= 0) {
+ dev->irq = irq;
+ } else {
+ printk(KERN_WARNING
+ "comedi%d: warning! irq %u unavailable!\n",
+ dev->minor, irq);
+ }
+ }
+
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ if (thisboard->bustype == isa_bustype) {
+ printk("(base %#lx) ", iobase);
+ } else {
+#ifdef CONFIG_COMEDI_PCI
+ printk("(pci %s) ", pci_name(pci_dev));
+#endif
+ }
+ if (irq) {
+ printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+ } else {
+ printk("(no irq) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int dio200_detach(struct comedi_device * dev)
+{
+ const struct dio200_layout_struct *layout;
+ unsigned n;
+
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+ DIO200_DRIVER_NAME);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->subdevices) {
+ layout = thislayout;
+ for (n = 0; n < dev->n_subdevices; n++) {
+ struct comedi_subdevice *s = &dev->subdevices[n];
+ switch (layout->sdtype[n]) {
+ case sd_8254:
+ dio200_subdev_8254_cleanup(dev, s);
+ break;
+ case sd_8255:
+ subdev_8255_cleanup(dev, s);
+ break;
+ case sd_intr:
+ dio200_subdev_intr_cleanup(dev, s);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ if (devpriv) {
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ } else
+#endif
+ {
+ if (dev->iobase) {
+ release_region(dev->iobase, DIO200_IO_SIZE);
+ }
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pc236.c b/drivers/staging/comedi/drivers/amplc_pc236.c
new file mode 100644
index 00000000000..2027c75feac
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc236.c
@@ -0,0 +1,654 @@
+/*
+ comedi/drivers/amplc_pc236.c
+ Driver for Amplicon PC36AT and PCI236 DIO boards.
+
+ Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_pc236
+Description: Amplicon PC36AT, PCI236
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC36AT (pc36at), PCI236 (pci236 or amplc_pc236)
+Updated: Wed, 22 Oct 2008 13:40:03 +0100
+Status: works
+
+Configuration options - PC36AT:
+ [0] - I/O port base address
+ [1] - IRQ (optional)
+
+Configuration options - PCI236:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will be
+ used.
+
+The PC36AT ISA board and PCI236 PCI board have a single 8255 appearing
+as subdevice 0.
+
+Subdevice 1 pretends to be a digital input device, but it always returns
+0 when read. However, if you run a command with scan_begin_src=TRIG_EXT,
+a rising edge on port C bit 7 acts as an external trigger, which can be
+used to wake up tasks. This is like the comedi_parport device, but the
+only way to physically disable the interrupt on the PC36AT is to remove
+the IRQ jumper. If no interrupt is connected, then subdevice 1 is
+unused.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+#include "plx9052.h"
+
+#define PC236_DRIVER_NAME "amplc_pc236"
+
+/* PCI236 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_AMPLICON_PCI236 0x0009
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* PC36AT / PCI236 registers */
+
+#define PC236_IO_SIZE 4
+#define PC236_LCR_IO_SIZE 128
+
+/*
+ * INTCSR values for PCI236.
+ */
+/* Disable interrupt, also clear any interrupt there */
+#define PCI236_INTR_DISABLE ( PLX9052_INTCSR_LI1ENAB_DISABLED \
+ | PLX9052_INTCSR_LI1POL_HIGH \
+ | PLX9052_INTCSR_LI2POL_HIGH \
+ | PLX9052_INTCSR_PCIENAB_DISABLED \
+ | PLX9052_INTCSR_LI1SEL_EDGE \
+ | PLX9052_INTCSR_LI1CLRINT_ASSERTED )
+/* Enable interrupt, also clear any interrupt there. */
+#define PCI236_INTR_ENABLE ( PLX9052_INTCSR_LI1ENAB_ENABLED \
+ | PLX9052_INTCSR_LI1POL_HIGH \
+ | PLX9052_INTCSR_LI2POL_HIGH \
+ | PLX9052_INTCSR_PCIENAB_ENABLED \
+ | PLX9052_INTCSR_LI1SEL_EDGE \
+ | PLX9052_INTCSR_LI1CLRINT_ASSERTED )
+
+/*
+ * Board descriptions for Amplicon PC36AT and PCI236.
+ */
+
+enum pc236_bustype { isa_bustype, pci_bustype };
+enum pc236_model { pc36at_model, pci236_model, anypci_model };
+
+struct pc236_board {
+ const char *name;
+ const char *fancy_name;
+ unsigned short devid;
+ enum pc236_bustype bustype;
+ enum pc236_model model;
+};
+static const struct pc236_board pc236_boards[] = {
+ {
+ name: "pc36at",
+ fancy_name:"PC36AT",
+ bustype: isa_bustype,
+ model: pc36at_model,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci236",
+ fancy_name:"PCI236",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI236,
+ bustype: pci_bustype,
+ model: pci236_model,
+ },
+#endif
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: PC236_DRIVER_NAME,
+ fancy_name:PC236_DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ bustype: pci_bustype,
+ model: anypci_model, /* wildcard */
+ },
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(pc236_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI236, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pc236_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pc236_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pc236_private {
+#ifdef CONFIG_COMEDI_PCI
+ /* PCI device */
+ struct pci_dev *pci_dev;
+ unsigned long lcr_iobase; /* PLX PCI9052 config registers in PCIBAR1 */
+#endif
+ int enable_irq;
+};
+
+#define devpriv ((struct pc236_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pc236_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pc236_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pc236 = {
+ driver_name:PC236_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pc236_attach,
+ detach:pc236_detach,
+ board_name:&pc236_boards[0].name,
+ offset:sizeof(struct pc236_board),
+ num_names:sizeof(pc236_boards) / sizeof(struct pc236_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_pc236, pc236_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc236);
+#endif
+
+static int pc236_request_region(unsigned minor, unsigned long from,
+ unsigned long extent);
+static void pc236_intr_disable(struct comedi_device * dev);
+static void pc236_intr_enable(struct comedi_device * dev);
+static int pc236_intr_check(struct comedi_device * dev);
+static int pc236_intr_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pc236_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pc236_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pc236_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t pc236_interrupt(int irq, void *d PT_REGS_ARG);
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc236_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+ PCI_ANY_ID, pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == anypci_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pc236_boards); i++) {
+ if (pc236_boards[i].bustype != pci_bustype)
+ continue;
+ if (pci_dev->device == pc236_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &pc236_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(pc236_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (pci_dev->device != thisboard->devid)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR
+ "comedi%d: error! no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pc236_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev = NULL;
+ int bus = 0, slot = 0;
+#endif
+ int share_irq = 0;
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+ PC236_DRIVER_NAME);
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if ((ret = alloc_private(dev, sizeof(struct pc236_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+ /* Process options. */
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ irq = it->options[1];
+ share_irq = 0;
+ break;
+#ifdef CONFIG_COMEDI_PCI
+ case pci_bustype:
+ bus = it->options[0];
+ slot = it->options[1];
+ share_irq = 1;
+
+ if ((ret = pc236_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+ break;
+#endif /* CONFIG_COMEDI_PCI */
+ default:
+ printk(KERN_ERR
+ "comedi%d: %s: BUG! cannot determine board type!\n",
+ dev->minor, PC236_DRIVER_NAME);
+ return -EINVAL;
+ break;
+ }
+
+/*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+ /* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+ if (pci_dev) {
+ if ((ret = comedi_pci_enable(pci_dev, PC236_DRIVER_NAME)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device and request regions!\n",
+ dev->minor);
+ return ret;
+ }
+ devpriv->lcr_iobase = pci_resource_start(pci_dev, 1);
+ iobase = pci_resource_start(pci_dev, 2);
+ irq = pci_dev->irq;
+ } else
+#endif
+ {
+ ret = pc236_request_region(dev->minor, iobase, PC236_IO_SIZE);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ dev->iobase = iobase;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if ((ret = alloc_subdevices(dev, 2)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ s = dev->subdevices + 0;
+ /* digital i/o subdevice (8255) */
+ if ((ret = subdev_8255_init(dev, s, NULL, iobase)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+ s = dev->subdevices + 1;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_UNUSED;
+ pc236_intr_disable(dev);
+ if (irq) {
+ unsigned long flags = share_irq ? IRQF_SHARED : 0;
+
+ if (comedi_request_irq(irq, pc236_interrupt, flags,
+ PC236_DRIVER_NAME, dev) >= 0) {
+ dev->irq = irq;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = pc236_intr_insn;
+ s->do_cmdtest = pc236_intr_cmdtest;
+ s->do_cmd = pc236_intr_cmd;
+ s->cancel = pc236_intr_cancel;
+ }
+ }
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ if (thisboard->bustype == isa_bustype) {
+ printk("(base %#lx) ", iobase);
+ } else {
+#ifdef CONFIG_COMEDI_PCI
+ printk("(pci %s) ", pci_name(pci_dev));
+#endif
+ }
+ if (irq) {
+ printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+ } else {
+ printk("(no irq) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pc236_detach(struct comedi_device * dev)
+{
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+ PC236_DRIVER_NAME);
+ if (devpriv) {
+ pc236_intr_disable(dev);
+ }
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->subdevices) {
+ subdev_8255_cleanup(dev, dev->subdevices + 0);
+ }
+ if (devpriv) {
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ } else
+#endif
+ {
+ if (dev->iobase) {
+ release_region(dev->iobase, PC236_IO_SIZE);
+ }
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+ return 0;
+}
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int pc236_request_region(unsigned minor, unsigned long from,
+ unsigned long extent)
+{
+ if (!from || !request_region(from, extent, PC236_DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+ minor, from, extent);
+ return -EIO;
+ }
+ return 0;
+}
+
+/*
+ * This function is called to mark the interrupt as disabled (no command
+ * configured on subdevice 1) and to physically disable the interrupt
+ * (not possible on the PC36AT, except by removing the IRQ jumper!).
+ */
+static void pc236_intr_disable(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->enable_irq = 0;
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->lcr_iobase)
+ outl(PCI236_INTR_DISABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
+#endif
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called to mark the interrupt as enabled (a command
+ * configured on subdevice 1) and to physically enable the interrupt
+ * (not possible on the PC36AT, except by (re)connecting the IRQ jumper!).
+ */
+static void pc236_intr_enable(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->enable_irq = 1;
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->lcr_iobase)
+ outl(PCI236_INTR_ENABLE, devpriv->lcr_iobase + PLX9052_INTCSR);
+#endif
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+/*
+ * This function is called when an interrupt occurs to check whether
+ * the interrupt has been marked as enabled and was generated by the
+ * board. If so, the function prepares the hardware for the next
+ * interrupt.
+ * Returns 0 if the interrupt should be ignored.
+ */
+static int pc236_intr_check(struct comedi_device * dev)
+{
+ int retval = 0;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (devpriv->enable_irq) {
+ retval = 1;
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->lcr_iobase) {
+ if ((inl(devpriv->lcr_iobase + PLX9052_INTCSR)
+ & PLX9052_INTCSR_LI1STAT_MASK)
+ == PLX9052_INTCSR_LI1STAT_INACTIVE) {
+ retval = 0;
+ } else {
+ /* Clear interrupt and keep it enabled. */
+ outl(PCI236_INTR_ENABLE,
+ devpriv->lcr_iobase + PLX9052_INTCSR);
+ }
+ }
+#endif
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return retval;
+}
+
+/*
+ * Input from subdevice 1.
+ * Copied from the comedi_parport driver.
+ */
+static int pc236_intr_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[1] = 0;
+ return 2;
+}
+
+/*
+ * Subdevice 1 command test.
+ * Copied from the comedi_parport driver.
+ */
+static int pc236_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1 */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: ignored */
+
+ if (err)
+ return 2;
+
+ /* step 3: */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: ignored */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/*
+ * Subdevice 1 command.
+ */
+static int pc236_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pc236_intr_enable(dev);
+
+ return 0;
+}
+
+/*
+ * Subdevice 1 cancel command.
+ */
+static int pc236_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pc236_intr_disable(dev);
+
+ return 0;
+}
+
+/*
+ * Interrupt service routine.
+ * Based on the comedi_parport driver.
+ */
+static irqreturn_t pc236_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 1;
+ int handled;
+
+ handled = pc236_intr_check(dev);
+ if (dev->attached && handled) {
+ comedi_buf_put(s->async, 0);
+ s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ }
+ return IRQ_RETVAL(handled);
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pc263.c b/drivers/staging/comedi/drivers/amplc_pc263.c
new file mode 100644
index 00000000000..97ac4157ada
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pc263.c
@@ -0,0 +1,431 @@
+/*
+ comedi/drivers/amplc_pc263.c
+ Driver for Amplicon PC263 and PCI263 relay boards.
+
+ Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_pc263
+Description: Amplicon PC263, PCI263
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PC263 (pc263), PCI263 (pci263 or amplc_pc263)
+Updated: Wed, 22 Oct 2008 14:10:53 +0100
+Status: works
+
+Configuration options - PC263:
+ [0] - I/O port base address
+
+Configuration options - PCI263:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will be
+ used.
+
+Each board appears as one subdevice, with 16 digital outputs, each
+connected to a reed-relay. Relay contacts are closed when output is 1.
+The state of the outputs can be read.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define PC263_DRIVER_NAME "amplc_pc263"
+
+/* PCI263 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_AMPLICON_PCI263 0x000c
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/* PC263 / PCI263 registers */
+#define PC263_IO_SIZE 2
+
+/*
+ * Board descriptions for Amplicon PC263 / PCI263.
+ */
+
+enum pc263_bustype { isa_bustype, pci_bustype };
+enum pc263_model { pc263_model, pci263_model, anypci_model };
+
+struct pc263_board {
+ const char *name;
+ const char *fancy_name;
+ unsigned short devid;
+ enum pc263_bustype bustype;
+ enum pc263_model model;
+};
+static const struct pc263_board pc263_boards[] = {
+ {
+ name: "pc263",
+ fancy_name:"PC263",
+ bustype: isa_bustype,
+ model: pc263_model,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci263",
+ fancy_name:"PCI263",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI263,
+ bustype: pci_bustype,
+ model: pci263_model,
+ },
+#endif
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: PC263_DRIVER_NAME,
+ fancy_name:PC263_DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ bustype: pci_bustype,
+ model: anypci_model, /* wildcard */
+ },
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(pc263_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI263, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pc263_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pc263_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+#ifdef CONFIG_COMEDI_PCI
+struct pc263_private {
+ /* PCI device. */
+ struct pci_dev *pci_dev;
+};
+
+#define devpriv ((struct pc263_private *)dev->private)
+#endif /* CONFIG_COMEDI_PCI */
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pc263_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pc263_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pc263 = {
+ driver_name:PC263_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pc263_attach,
+ detach:pc263_detach,
+ board_name:&pc263_boards[0].name,
+ offset:sizeof(struct pc263_board),
+ num_names:sizeof(pc263_boards) / sizeof(struct pc263_board),
+};
+
+static int pc263_request_region(unsigned minor, unsigned long from,
+ unsigned long extent);
+static int pc263_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pc263_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+#ifdef CONFIG_COMEDI_PCI
+static int
+pc263_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON,
+ PCI_ANY_ID, pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == anypci_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pc263_boards); i++) {
+ if (pc263_boards[i].bustype != pci_bustype)
+ continue;
+ if (pci_dev->device == pc263_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &pc263_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(pc263_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (pci_dev->device != thisboard->devid)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR
+ "comedi%d: error! no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pc263_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+#ifdef CONFIG_COMEDI_PCI
+ struct pci_dev *pci_dev = NULL;
+ int bus = 0, slot = 0;
+#endif
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor,
+ PC263_DRIVER_NAME);
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+#ifdef CONFIG_COMEDI_PCI
+ if ((ret = alloc_private(dev, sizeof(struct pc263_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+#endif
+ /* Process options. */
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ break;
+#ifdef CONFIG_COMEDI_PCI
+ case pci_bustype:
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if ((ret = pc263_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+ break;
+#endif /* CONFIG_COMEDI_PCI */
+ default:
+ printk(KERN_ERR
+ "comedi%d: %s: BUG! cannot determine board type!\n",
+ dev->minor, PC263_DRIVER_NAME);
+ return -EINVAL;
+ break;
+ }
+
+/*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+ /* Enable device and reserve I/O spaces. */
+#ifdef CONFIG_COMEDI_PCI
+ if (pci_dev) {
+ if ((ret = comedi_pci_enable(pci_dev, PC263_DRIVER_NAME)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device and request regions!\n",
+ dev->minor);
+ return ret;
+ }
+ iobase = pci_resource_start(pci_dev, 2);
+ } else
+#endif
+ {
+ ret = pc263_request_region(dev->minor, iobase, PC263_IO_SIZE);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+ dev->iobase = iobase;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if ((ret = alloc_subdevices(dev, 1)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ s = dev->subdevices + 0;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_RT;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = pc263_dio_insn_bits;
+ s->insn_config = pc263_dio_insn_config;
+ /* all outputs */
+ s->io_bits = 0xffff;
+ /* read initial relay state */
+ s->state = inb(dev->iobase);
+ s->state = s->state | (inb(dev->iobase) << 8);
+
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ if (thisboard->bustype == isa_bustype) {
+ printk("(base %#lx) ", iobase);
+ } else {
+#ifdef CONFIG_COMEDI_PCI
+ printk("(pci %s) ", pci_name(pci_dev));
+#endif
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pc263_detach(struct comedi_device * dev)
+{
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor,
+ PC263_DRIVER_NAME);
+
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv)
+#endif
+ {
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ } else
+#endif
+ {
+ if (dev->iobase) {
+ release_region(dev->iobase, PC263_IO_SIZE);
+ }
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+ return 0;
+}
+
+/*
+ * This function checks and requests an I/O region, reporting an error
+ * if there is a conflict.
+ */
+static int pc263_request_region(unsigned minor, unsigned long from,
+ unsigned long extent)
+{
+ if (!from || !request_region(from, extent, PC263_DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict (%#lx,%lu)!\n",
+ minor, from, extent);
+ return -EIO;
+ }
+ return 0;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pc263_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ outb(s->state & 0xFF, dev->iobase);
+ outb(s->state >> 8, dev->iobase + 1);
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pc263_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 1)
+ return -EINVAL;
+ return 1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_amplc_pc263, pc263_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_amplc_pc263);
+#endif
diff --git a/drivers/staging/comedi/drivers/amplc_pci224.c b/drivers/staging/comedi/drivers/amplc_pci224.c
new file mode 100644
index 00000000000..770b9664893
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci224.c
@@ -0,0 +1,1545 @@
+/*
+ comedi/drivers/amplc_pci224.c
+ Driver for Amplicon PCI224 and PCI234 AO boards.
+
+ Copyright (C) 2005 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: amplc_pci224
+Description: Amplicon PCI224, PCI234
+Author: Ian Abbott <abbotti@mev.co.uk>
+Devices: [Amplicon] PCI224 (amplc_pci224 or pci224),
+ PCI234 (amplc_pci224 or pci234)
+Updated: Wed, 22 Oct 2008 12:25:08 +0100
+Status: works, but see caveats
+
+Supports:
+
+ - ao_insn read/write
+ - ao_do_cmd mode with the following sources:
+
+ - start_src TRIG_INT TRIG_EXT
+ - scan_begin_src TRIG_TIMER TRIG_EXT
+ - convert_src TRIG_NOW
+ - scan_end_src TRIG_COUNT
+ - stop_src TRIG_COUNT TRIG_EXT TRIG_NONE
+
+ The channel list must contain at least one channel with no repeated
+ channels. The scan end count must equal the number of channels in
+ the channel list.
+
+ There is only one external trigger source so only one of start_src,
+ scan_begin_src or stop_src may use TRIG_EXT.
+
+Configuration options - PCI224:
+ [0] - PCI bus of device (optional).
+ [1] - PCI slot of device (optional).
+ If bus/slot is not specified, the first available PCI device
+ will be used.
+ [2] - Select available ranges according to jumper LK1. All channels
+ are set to the same range:
+ 0=Jumper position 1-2 (factory default), 4 software-selectable
+ internal voltage references, giving 4 bipolar and 4 unipolar
+ ranges:
+ [-10V,+10V], [-5V,+5V], [-2.5V,+2.5V], [-1.25V,+1.25V],
+ [0,+10V], [0,+5V], [0,+2.5V], [0,1.25V].
+ 1=Jumper position 2-3, 1 external voltage reference, giving
+ 1 bipolar and 1 unipolar range:
+ [-Vext,+Vext], [0,+Vext].
+
+Configuration options - PCI234:
+ [0] - PCI bus of device (optional).
+ [1] - PCI slot of device (optional).
+ If bus/slot is not specified, the first available PCI device
+ will be used.
+ [2] - Select internal or external voltage reference according to
+ jumper LK1. This affects all channels:
+ 0=Jumper position 1-2 (factory default), Vref=5V internal.
+ 1=Jumper position 2-3, Vref=Vext external.
+ [3] - Select channel 0 range according to jumper LK2:
+ 0=Jumper position 2-3 (factory default), range [-2*Vref,+2*Vref]
+ (10V bipolar when options[2]=0).
+ 1=Jumper position 1-2, range [-Vref,+Vref]
+ (5V bipolar when options[2]=0).
+ [4] - Select channel 1 range according to jumper LK3: cf. options[3].
+ [5] - Select channel 2 range according to jumper LK4: cf. options[3].
+ [6] - Select channel 3 range according to jumper LK5: cf. options[3].
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+Caveats:
+
+ 1) All channels on the PCI224 share the same range. Any change to the
+ range as a result of insn_write or a streaming command will affect
+ the output voltages of all channels, including those not specified
+ by the instruction or command.
+
+ 2) For the analog output command, the first scan may be triggered
+ falsely at the start of acquisition. This occurs when the DAC scan
+ trigger source is switched from 'none' to 'timer' (scan_begin_src =
+ TRIG_TIMER) or 'external' (scan_begin_src == TRIG_EXT) at the start
+ of acquisition and the trigger source is at logic level 1 at the
+ time of the switch. This is very likely for TRIG_TIMER. For
+ TRIG_EXT, it depends on the state of the external line and whether
+ the CR_INVERT flag has been set. The remaining scans are triggered
+ correctly.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "comedi_fc.h"
+#include "8253.h"
+
+#define DRIVER_NAME "amplc_pci224"
+
+/*
+ * PCI IDs.
+ */
+/* #define PCI_VENDOR_ID_AMPLICON 0x14dc */
+#define PCI_DEVICE_ID_AMPLICON_PCI224 0x0007
+#define PCI_DEVICE_ID_AMPLICON_PCI234 0x0008
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+/*
+ * PCI224/234 i/o space 1 (PCIBAR2) registers.
+ */
+#define PCI224_IO1_SIZE 0x20 /* Size of i/o space 1 (8-bit registers) */
+#define PCI224_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
+#define PCI224_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
+#define PCI224_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
+#define PCI224_Z2_CTC 0x17 /* 82C54 counter/timer control word */
+#define PCI224_ZCLK_SCE 0x1A /* Group Z Clock Configuration Register */
+#define PCI224_ZGAT_SCE 0x1D /* Group Z Gate Configuration Register */
+#define PCI224_INT_SCE 0x1E /* ISR Interrupt source mask register */
+ /* /Interrupt status */
+
+/*
+ * PCI224/234 i/o space 2 (PCIBAR3) 16-bit registers.
+ */
+#define PCI224_IO2_SIZE 0x10 /* Size of i/o space 2 (16-bit registers). */
+#define PCI224_DACDATA 0x00 /* (w-o) DAC FIFO data. */
+#define PCI224_SOFTTRIG 0x00 /* (r-o) DAC software scan trigger. */
+#define PCI224_DACCON 0x02 /* (r/w) DAC status/configuration. */
+#define PCI224_FIFOSIZ 0x04 /* (w-o) FIFO size for wraparound mode. */
+#define PCI224_DACCEN 0x06 /* (w-o) DAC channel enable register. */
+
+/*
+ * DACCON values.
+ */
+/* (r/w) Scan trigger. */
+#define PCI224_DACCON_TRIG_MASK (7 << 0)
+#define PCI224_DACCON_TRIG_NONE (0 << 0) /* none */
+#define PCI224_DACCON_TRIG_SW (1 << 0) /* software trig */
+#define PCI224_DACCON_TRIG_EXTP (2 << 0) /* ext +ve edge */
+#define PCI224_DACCON_TRIG_EXTN (3 << 0) /* ext -ve edge */
+#define PCI224_DACCON_TRIG_Z2CT0 (4 << 0) /* Z2 CT0 out */
+#define PCI224_DACCON_TRIG_Z2CT1 (5 << 0) /* Z2 CT1 out */
+#define PCI224_DACCON_TRIG_Z2CT2 (6 << 0) /* Z2 CT2 out */
+/* (r/w) Polarity (PCI224 only, PCI234 always bipolar!). */
+#define PCI224_DACCON_POLAR_MASK (1 << 3)
+#define PCI224_DACCON_POLAR_UNI (0 << 3) /* range [0,Vref] */
+#define PCI224_DACCON_POLAR_BI (1 << 3) /* range [-Vref,Vref] */
+/* (r/w) Internal Vref (PCI224 only, when LK1 in position 1-2). */
+#define PCI224_DACCON_VREF_MASK (3 << 4)
+#define PCI224_DACCON_VREF_1_25 (0 << 4) /* Vref = 1.25V */
+#define PCI224_DACCON_VREF_2_5 (1 << 4) /* Vref = 2.5V */
+#define PCI224_DACCON_VREF_5 (2 << 4) /* Vref = 5V */
+#define PCI224_DACCON_VREF_10 (3 << 4) /* Vref = 10V */
+/* (r/w) Wraparound mode enable (to play back stored waveform). */
+#define PCI224_DACCON_FIFOWRAP (1 << 7)
+/* (r/w) FIFO enable. It MUST be set! */
+#define PCI224_DACCON_FIFOENAB (1 << 8)
+/* (r/w) FIFO interrupt trigger level (most values are not very useful). */
+#define PCI224_DACCON_FIFOINTR_MASK (7 << 9)
+#define PCI224_DACCON_FIFOINTR_EMPTY (0 << 9) /* when empty */
+#define PCI224_DACCON_FIFOINTR_NEMPTY (1 << 9) /* when not empty */
+#define PCI224_DACCON_FIFOINTR_NHALF (2 << 9) /* when not half full */
+#define PCI224_DACCON_FIFOINTR_HALF (3 << 9) /* when half full */
+#define PCI224_DACCON_FIFOINTR_NFULL (4 << 9) /* when not full */
+#define PCI224_DACCON_FIFOINTR_FULL (5 << 9) /* when full */
+/* (r-o) FIFO fill level. */
+#define PCI224_DACCON_FIFOFL_MASK (7 << 12)
+#define PCI224_DACCON_FIFOFL_EMPTY (1 << 12) /* 0 */
+#define PCI224_DACCON_FIFOFL_ONETOHALF (0 << 12) /* [1,2048] */
+#define PCI224_DACCON_FIFOFL_HALFTOFULL (4 << 12) /* [2049,4095] */
+#define PCI224_DACCON_FIFOFL_FULL (6 << 12) /* 4096 */
+/* (r-o) DAC busy flag. */
+#define PCI224_DACCON_BUSY (1 << 15)
+/* (w-o) FIFO reset. */
+#define PCI224_DACCON_FIFORESET (1 << 12)
+/* (w-o) Global reset (not sure what it does). */
+#define PCI224_DACCON_GLOBALRESET (1 << 13)
+
+/*
+ * DAC FIFO size.
+ */
+#define PCI224_FIFO_SIZE 4096
+
+/*
+ * DAC FIFO guaranteed minimum room available, depending on reported fill level.
+ * The maximum room available depends on the reported fill level and how much
+ * has been written!
+ */
+#define PCI224_FIFO_ROOM_EMPTY PCI224_FIFO_SIZE
+#define PCI224_FIFO_ROOM_ONETOHALF (PCI224_FIFO_SIZE / 2)
+#define PCI224_FIFO_ROOM_HALFTOFULL 1
+#define PCI224_FIFO_ROOM_FULL 0
+
+/*
+ * Counter/timer clock input configuration sources.
+ */
+#define CLK_CLK 0 /* reserved (channel-specific clock) */
+#define CLK_10MHZ 1 /* internal 10 MHz clock */
+#define CLK_1MHZ 2 /* internal 1 MHz clock */
+#define CLK_100KHZ 3 /* internal 100 kHz clock */
+#define CLK_10KHZ 4 /* internal 10 kHz clock */
+#define CLK_1KHZ 5 /* internal 1 kHz clock */
+#define CLK_OUTNM1 6 /* output of channel-1 modulo total */
+#define CLK_EXT 7 /* external clock */
+/* Macro to construct clock input configuration register value. */
+#define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+/* Timebases in ns. */
+#define TIMEBASE_10MHZ 100
+#define TIMEBASE_1MHZ 1000
+#define TIMEBASE_100KHZ 10000
+#define TIMEBASE_10KHZ 100000
+#define TIMEBASE_1KHZ 1000000
+
+/*
+ * Counter/timer gate input configuration sources.
+ */
+#define GAT_VCC 0 /* VCC (i.e. enabled) */
+#define GAT_GND 1 /* GND (i.e. disabled) */
+#define GAT_EXT 2 /* reserved (external gate input) */
+#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
+/* Macro to construct gate input configuration register value. */
+#define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+
+/*
+ * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI224 and PCI234:
+ *
+ * Channel's Channel's
+ * clock input gate input
+ * Channel CLK_OUTNM1 GAT_NOUTNM2
+ * ------- ---------- -----------
+ * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
+ * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
+ * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
+ */
+
+/*
+ * Interrupt enable/status bits
+ */
+#define PCI224_INTR_EXT 0x01 /* rising edge on external input */
+#define PCI224_INTR_DAC 0x04 /* DAC (FIFO) interrupt */
+#define PCI224_INTR_Z2CT1 0x20 /* rising edge on Z2-CT1 output */
+
+#define PCI224_INTR_EDGE_BITS (PCI224_INTR_EXT | PCI224_INTR_Z2CT1)
+#define PCI224_INTR_LEVEL_BITS PCI224_INTR_DACFIFO
+
+/*
+ * Handy macros.
+ */
+
+/* Combine old and new bits. */
+#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
+
+/* A generic null function pointer value. */
+#define NULLFUNC 0
+
+/* Current CPU. XXX should this be hard_smp_processor_id()? */
+#define THISCPU smp_processor_id()
+
+/* State bits for use with atomic bit operations. */
+#define AO_CMD_STARTED 0
+
+/*
+ * Range tables.
+ */
+
+/* The software selectable internal ranges for PCI224 (option[2] == 0). */
+static const struct comedi_lrange range_pci224_internal = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+
+static const unsigned short hwrange_pci224_internal[8] = {
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_10,
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_5,
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_2_5,
+ PCI224_DACCON_POLAR_BI | PCI224_DACCON_VREF_1_25,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_10,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_5,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_2_5,
+ PCI224_DACCON_POLAR_UNI | PCI224_DACCON_VREF_1_25,
+};
+
+/* The software selectable external ranges for PCI224 (option[2] == 1). */
+static const struct comedi_lrange range_pci224_external = {
+ 2,
+ {
+ RANGE_ext(-1, 1), /* bipolar [-Vref,+Vref] */
+ RANGE_ext(0, 1), /* unipolar [0,+Vref] */
+ }
+};
+
+static const unsigned short hwrange_pci224_external[2] = {
+ PCI224_DACCON_POLAR_BI,
+ PCI224_DACCON_POLAR_UNI,
+};
+
+/* The hardware selectable Vref*2 external range for PCI234
+ * (option[2] == 1, option[3+n] == 0). */
+static const struct comedi_lrange range_pci234_ext2 = {
+ 1,
+ {
+ RANGE_ext(-2, 2),
+ }
+};
+
+/* The hardware selectable Vref external range for PCI234
+ * (option[2] == 1, option[3+n] == 1). */
+static const struct comedi_lrange range_pci234_ext = {
+ 1,
+ {
+ RANGE_ext(-1, 1),
+ }
+};
+
+/* This serves for all the PCI234 ranges. */
+static const unsigned short hwrange_pci234[1] = {
+ PCI224_DACCON_POLAR_BI, /* bipolar - hardware ignores it! */
+};
+
+/*
+ * Board descriptions.
+ */
+
+enum pci224_model { any_model, pci224_model, pci234_model };
+
+struct pci224_board {
+ const char *name;
+ unsigned short devid;
+ enum pci224_model model;
+ unsigned int ao_chans;
+ unsigned int ao_bits;
+};
+
+static const struct pci224_board pci224_boards[] = {
+ {
+ name: "pci224",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI224,
+ model: pci224_model,
+ ao_chans:16,
+ ao_bits: 12,
+ },
+ {
+ name: "pci234",
+ devid: PCI_DEVICE_ID_AMPLICON_PCI234,
+ model: pci234_model,
+ ao_chans:4,
+ ao_bits: 16,
+ },
+ {
+ name: DRIVER_NAME,
+ devid: PCI_DEVICE_ID_INVALID,
+ model: any_model, /* wildcard */
+ },
+};
+
+/*
+ * PCI driver table.
+ */
+
+static DEFINE_PCI_DEVICE_TABLE(pci224_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI224,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_AMPLICON_PCI234,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci224_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((struct pci224_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pci224_private {
+ struct pci_dev *pci_dev; /* PCI device */
+ const unsigned short *hwrange;
+ unsigned long iobase1;
+ unsigned long state;
+ spinlock_t ao_spinlock;
+ unsigned int *ao_readback;
+ short *ao_scan_vals;
+ unsigned char *ao_scan_order;
+ int intr_cpuid;
+ short intr_running;
+ unsigned short daccon;
+ unsigned int cached_div1;
+ unsigned int cached_div2;
+ unsigned int ao_stop_count;
+ short ao_stop_continuous;
+ unsigned short ao_enab; /* max 16 channels so 'short' will do */
+ unsigned char intsce;
+};
+
+#define devpriv ((struct pci224_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci224_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci224_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pci224 = {
+ driver_name:DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:pci224_attach,
+ detach:pci224_detach,
+ board_name:&pci224_boards[0].name,
+ offset:sizeof(struct pci224_board),
+ num_names:sizeof(pci224_boards) / sizeof(struct pci224_board),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_amplc_pci224, pci224_pci_table);
+
+/*
+ * Called from the 'insn_write' function to perform a single write.
+ */
+static void
+pci224_ao_set_data(struct comedi_device * dev, int chan, int range, unsigned int data)
+{
+ unsigned short mangled;
+
+ /* Store unmangled data for readback. */
+ devpriv->ao_readback[chan] = data;
+ /* Enable the channel. */
+ outw(1 << chan, dev->iobase + PCI224_DACCEN);
+ /* Set range and reset FIFO. */
+ devpriv->daccon = COMBINE(devpriv->daccon, devpriv->hwrange[range],
+ (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK));
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+ /*
+ * Mangle the data. The hardware expects:
+ * - bipolar: 16-bit 2's complement
+ * - unipolar: 16-bit unsigned
+ */
+ mangled = (unsigned short)data << (16 - thisboard->ao_bits);
+ if ((devpriv->daccon & PCI224_DACCON_POLAR_MASK) ==
+ PCI224_DACCON_POLAR_BI) {
+ mangled ^= 0x8000;
+ }
+ /* Write mangled data to the FIFO. */
+ outw(mangled, dev->iobase + PCI224_DACDATA);
+ /* Trigger the conversion. */
+ inw(dev->iobase + PCI224_SOFTTRIG);
+}
+
+/*
+ * 'insn_write' function for AO subdevice.
+ */
+static int
+pci224_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan, range;
+
+ /* Unpack channel and range. */
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ pci224_ao_set_data(dev, chan, range, data[i]);
+ }
+ return i;
+}
+
+/*
+ * 'insn_read' function for AO subdevice.
+ *
+ * N.B. The value read will not be valid if the DAC channel has
+ * never been written successfully since the device was attached
+ * or since the channel has been used by an AO streaming write
+ * command.
+ */
+static int
+pci224_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*
+ * Just a wrapper for the inline function 'i8253_cascade_ns_to_timer'.
+ */
+static void
+pci224_cascade_ns_to_timer(int osc_base, unsigned int *d1, unsigned int *d2,
+ unsigned int *nanosec, int round_mode)
+{
+ i8253_cascade_ns_to_timer(osc_base, d1, d2, nanosec, round_mode);
+}
+
+/*
+ * Kills a command running on the AO subdevice.
+ */
+static void pci224_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ if (!test_and_clear_bit(AO_CMD_STARTED, &devpriv->state)) {
+ return;
+ }
+
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ /* Kill the interrupts. */
+ devpriv->intsce = 0;
+ outb(0, devpriv->iobase1 + PCI224_INT_SCE);
+ /*
+ * Interrupt routine may or may not be running. We may or may not
+ * have been called from the interrupt routine (directly or
+ * indirectly via a comedi_events() callback routine). It's highly
+ * unlikely that we've been called from some other interrupt routine
+ * but who knows what strange things coders get up to!
+ *
+ * If the interrupt routine is currently running, wait for it to
+ * finish, unless we appear to have been called via the interrupt
+ * routine.
+ */
+ while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ /* Reconfigure DAC for insn_write usage. */
+ outw(0, dev->iobase + PCI224_DACCEN); /* Disable channels. */
+ devpriv->daccon = COMBINE(devpriv->daccon,
+ PCI224_DACCON_TRIG_SW | PCI224_DACCON_FIFOINTR_EMPTY,
+ PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK);
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+}
+
+/*
+ * Handles start of acquisition for the AO subdevice.
+ */
+static void pci224_ao_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+
+ set_bit(AO_CMD_STARTED, &devpriv->state);
+ if (!devpriv->ao_stop_continuous && devpriv->ao_stop_count == 0) {
+ /* An empty acquisition! */
+ pci224_ao_stop(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ } else {
+ /* Enable interrupts. */
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ if (cmd->stop_src == TRIG_EXT) {
+ devpriv->intsce = PCI224_INTR_EXT | PCI224_INTR_DAC;
+ } else {
+ devpriv->intsce = PCI224_INTR_DAC;
+ }
+ outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ }
+}
+
+/*
+ * Handles interrupts from the DAC FIFO.
+ */
+static void pci224_ao_handle_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int num_scans;
+ unsigned int room;
+ unsigned short dacstat;
+ unsigned int i, n;
+ unsigned int bytes_per_scan;
+
+ if (cmd->chanlist_len) {
+ bytes_per_scan = cmd->chanlist_len * sizeof(short);
+ } else {
+ /* Shouldn't get here! */
+ bytes_per_scan = sizeof(short);
+ }
+ /* Determine number of scans available in buffer. */
+ num_scans = comedi_buf_read_n_available(s->async) / bytes_per_scan;
+ if (!devpriv->ao_stop_continuous) {
+ /* Fixed number of scans. */
+ if (num_scans > devpriv->ao_stop_count) {
+ num_scans = devpriv->ao_stop_count;
+ }
+ }
+
+ /* Determine how much room is in the FIFO (in samples). */
+ dacstat = inw(dev->iobase + PCI224_DACCON);
+ switch (dacstat & PCI224_DACCON_FIFOFL_MASK) {
+ case PCI224_DACCON_FIFOFL_EMPTY:
+ room = PCI224_FIFO_ROOM_EMPTY;
+ if (!devpriv->ao_stop_continuous
+ && devpriv->ao_stop_count == 0) {
+ /* FIFO empty at end of counted acquisition. */
+ pci224_ao_stop(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ break;
+ case PCI224_DACCON_FIFOFL_ONETOHALF:
+ room = PCI224_FIFO_ROOM_ONETOHALF;
+ break;
+ case PCI224_DACCON_FIFOFL_HALFTOFULL:
+ room = PCI224_FIFO_ROOM_HALFTOFULL;
+ break;
+ default:
+ room = PCI224_FIFO_ROOM_FULL;
+ break;
+ }
+ if (room >= PCI224_FIFO_ROOM_ONETOHALF) {
+ /* FIFO is less than half-full. */
+ if (num_scans == 0) {
+ /* Nothing left to put in the FIFO. */
+ pci224_ao_stop(dev, s);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ rt_printk(KERN_ERR "comedi%d: "
+ "AO buffer underrun\n", dev->minor);
+ }
+ }
+ /* Determine how many new scans can be put in the FIFO. */
+ if (cmd->chanlist_len) {
+ room /= cmd->chanlist_len;
+ }
+ /* Determine how many scans to process. */
+ if (num_scans > room) {
+ num_scans = room;
+ }
+ /* Process scans. */
+ for (n = 0; n < num_scans; n++) {
+ cfc_read_array_from_buffer(s, &devpriv->ao_scan_vals[0],
+ bytes_per_scan);
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ outw(devpriv->ao_scan_vals[devpriv->
+ ao_scan_order[i]],
+ dev->iobase + PCI224_DACDATA);
+ }
+ }
+ if (!devpriv->ao_stop_continuous) {
+ devpriv->ao_stop_count -= num_scans;
+ if (devpriv->ao_stop_count == 0) {
+ /*
+ * Change FIFO interrupt trigger level to wait
+ * until FIFO is empty.
+ */
+ devpriv->daccon = COMBINE(devpriv->daccon,
+ PCI224_DACCON_FIFOINTR_EMPTY,
+ PCI224_DACCON_FIFOINTR_MASK);
+ outw(devpriv->daccon,
+ dev->iobase + PCI224_DACCON);
+ }
+ }
+ if ((devpriv->daccon & PCI224_DACCON_TRIG_MASK) ==
+ PCI224_DACCON_TRIG_NONE) {
+ unsigned short trig;
+
+ /*
+ * This is the initial DAC FIFO interrupt at the
+ * start of the acquisition. The DAC's scan trigger
+ * has been set to 'none' up until now.
+ *
+ * Now that data has been written to the FIFO, the
+ * DAC's scan trigger source can be set to the
+ * correct value.
+ *
+ * BUG: The first scan will be triggered immediately
+ * if the scan trigger source is at logic level 1.
+ */
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ trig = PCI224_DACCON_TRIG_Z2CT0;
+ } else {
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg & CR_INVERT) {
+ trig = PCI224_DACCON_TRIG_EXTN;
+ } else {
+ trig = PCI224_DACCON_TRIG_EXTP;
+ }
+ }
+ devpriv->daccon = COMBINE(devpriv->daccon, trig,
+ PCI224_DACCON_TRIG_MASK);
+ outw(devpriv->daccon, dev->iobase + PCI224_DACCON);
+ }
+ if (s->async->events) {
+ comedi_event(dev, s);
+ }
+}
+
+/*
+ * Internal trigger function to start acquisition on AO subdevice.
+ */
+static int
+pci224_ao_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULLFUNC;
+ pci224_ao_start(dev, s);
+
+ return 1;
+}
+
+#define MAX_SCAN_PERIOD 0xFFFFFFFFU
+#define MIN_SCAN_PERIOD 2500
+#define CONVERT_PERIOD 625
+
+/*
+ * 'do_cmdtest' function for AO subdevice.
+ */
+static int
+pci224_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* Step 1: make sure trigger sources are trivially valid. */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT | TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* Step 2: make sure trigger sources are unique and mutually
+ * compatible. */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ /* There's only one external trigger signal (which makes these
+ * tests easier). Only one thing can use it. */
+ tmp = 0;
+ if (cmd->start_src & TRIG_EXT)
+ tmp++;
+ if (cmd->scan_begin_src & TRIG_EXT)
+ tmp++;
+ if (cmd->stop_src & TRIG_EXT)
+ tmp++;
+ if (tmp > 1)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* Step 3: make sure arguments are trivially compatible. */
+
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ break;
+ case TRIG_EXT:
+ /* Force to external trigger 0. */
+ if ((cmd->start_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->start_arg = COMBINE(cmd->start_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flag allowed is CR_EDGE, which is ignored. */
+ if ((cmd->start_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ cmd->start_arg = COMBINE(cmd->start_arg, 0,
+ CR_FLAGS_MASK & ~CR_EDGE);
+ err++;
+ }
+ break;
+ }
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ if (cmd->scan_begin_arg > MAX_SCAN_PERIOD) {
+ cmd->scan_begin_arg = MAX_SCAN_PERIOD;
+ err++;
+ }
+ tmp = cmd->chanlist_len * CONVERT_PERIOD;
+ if (tmp < MIN_SCAN_PERIOD) {
+ tmp = MIN_SCAN_PERIOD;
+ }
+ if (cmd->scan_begin_arg < tmp) {
+ cmd->scan_begin_arg = tmp;
+ err++;
+ }
+ break;
+ case TRIG_EXT:
+ /* Force to external trigger 0. */
+ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* Only allow flags CR_EDGE and CR_INVERT. Ignore CR_EDGE. */
+ if ((cmd->scan_begin_arg & CR_FLAGS_MASK &
+ ~(CR_EDGE | CR_INVERT)) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+ err++;
+ }
+ break;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_arg == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* Any count allowed. */
+ break;
+ case TRIG_EXT:
+ /* Force to external trigger 0. */
+ if ((cmd->stop_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flag allowed is CR_EDGE, which is ignored. */
+ if ((cmd->stop_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ cmd->stop_arg = COMBINE(cmd->stop_arg, 0,
+ CR_FLAGS_MASK & ~CR_EDGE);
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* Step 4: fix up any arguments. */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int div1, div2, round;
+ int round_mode = cmd->flags & TRIG_ROUND_MASK;
+
+ tmp = cmd->scan_begin_arg;
+ /* Check whether to use a single timer. */
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ round = TIMEBASE_10MHZ / 2;
+ break;
+ case TRIG_ROUND_DOWN:
+ round = 0;
+ break;
+ case TRIG_ROUND_UP:
+ round = TIMEBASE_10MHZ - 1;
+ break;
+ }
+ /* Be careful to avoid overflow! */
+ div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
+ div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
+ TIMEBASE_10MHZ;
+ if (div2 <= 0x10000) {
+ /* A single timer will suffice. */
+ if (div2 < 2)
+ div2 = 2;
+ cmd->scan_begin_arg = div2 * TIMEBASE_10MHZ;
+ if (cmd->scan_begin_arg < div2 ||
+ cmd->scan_begin_arg < TIMEBASE_10MHZ) {
+ /* Overflow! */
+ cmd->scan_begin_arg = MAX_SCAN_PERIOD;
+ }
+ } else {
+ /* Use two timers. */
+ div1 = devpriv->cached_div1;
+ div2 = devpriv->cached_div2;
+ pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+ &cmd->scan_begin_arg, round_mode);
+ devpriv->cached_div1 = div1;
+ devpriv->cached_div2 = div2;
+ }
+ if (tmp != cmd->scan_begin_arg) {
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ /* Step 5: check channel list. */
+
+ if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+ unsigned int range;
+ enum { range_err = 1, dupchan_err = 2, };
+ unsigned errors;
+ unsigned int n;
+ unsigned int ch;
+
+ /*
+ * Check all channels have the same range index. Don't care
+ * about analogue reference, as we can't configure it.
+ *
+ * Check the list has no duplicate channels.
+ */
+ range = CR_RANGE(cmd->chanlist[0]);
+ errors = 0;
+ tmp = 0;
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ ch = CR_CHAN(cmd->chanlist[n]);
+ if (tmp & (1U << ch)) {
+ errors |= dupchan_err;
+ }
+ tmp |= (1U << ch);
+ if (CR_RANGE(cmd->chanlist[n]) != range) {
+ errors |= range_err;
+ }
+ }
+ if (errors) {
+ if (errors & dupchan_err) {
+ DPRINTK("comedi%d: " DRIVER_NAME
+ ": ao_cmdtest: "
+ "entries in chanlist must contain no "
+ "duplicate channels\n", dev->minor);
+ }
+ if (errors & range_err) {
+ DPRINTK("comedi%d: " DRIVER_NAME
+ ": ao_cmdtest: "
+ "entries in chanlist must all have "
+ "the same range index\n", dev->minor);
+ }
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+/*
+ * 'do_cmd' function for AO subdevice.
+ */
+static int pci224_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int range;
+ unsigned int i, j;
+ unsigned int ch;
+ unsigned int rank;
+ unsigned long flags;
+
+ /* Cannot handle null/empty chanlist. */
+ if (cmd->chanlist == NULL || cmd->chanlist_len == 0) {
+ return -EINVAL;
+ }
+
+ /* Determine which channels are enabled and their load order. */
+ devpriv->ao_enab = 0;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ ch = CR_CHAN(cmd->chanlist[i]);
+ devpriv->ao_enab |= 1U << ch;
+ rank = 0;
+ for (j = 0; j < cmd->chanlist_len; j++) {
+ if (CR_CHAN(cmd->chanlist[j]) < ch) {
+ rank++;
+ }
+ }
+ devpriv->ao_scan_order[rank] = i;
+ }
+
+ /* Set enabled channels. */
+ outw(devpriv->ao_enab, dev->iobase + PCI224_DACCEN);
+
+ /* Determine range and polarity. All channels the same. */
+ range = CR_RANGE(cmd->chanlist[0]);
+
+ /*
+ * Set DAC range and polarity.
+ * Set DAC scan trigger source to 'none'.
+ * Set DAC FIFO interrupt trigger level to 'not half full'.
+ * Reset DAC FIFO.
+ *
+ * N.B. DAC FIFO interrupts are currently disabled.
+ */
+ devpriv->daccon = COMBINE(devpriv->daccon,
+ (devpriv->hwrange[range] | PCI224_DACCON_TRIG_NONE |
+ PCI224_DACCON_FIFOINTR_NHALF),
+ (PCI224_DACCON_POLAR_MASK | PCI224_DACCON_VREF_MASK |
+ PCI224_DACCON_TRIG_MASK | PCI224_DACCON_FIFOINTR_MASK));
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int div1, div2, round;
+ unsigned int ns = cmd->scan_begin_arg;
+ int round_mode = cmd->flags & TRIG_ROUND_MASK;
+
+ /* Check whether to use a single timer. */
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ round = TIMEBASE_10MHZ / 2;
+ break;
+ case TRIG_ROUND_DOWN:
+ round = 0;
+ break;
+ case TRIG_ROUND_UP:
+ round = TIMEBASE_10MHZ - 1;
+ break;
+ }
+ /* Be careful to avoid overflow! */
+ div2 = cmd->scan_begin_arg / TIMEBASE_10MHZ;
+ div2 += (round + cmd->scan_begin_arg % TIMEBASE_10MHZ) /
+ TIMEBASE_10MHZ;
+ if (div2 <= 0x10000) {
+ /* A single timer will suffice. */
+ if (div2 < 2)
+ div2 = 2;
+ div2 &= 0xffff;
+ div1 = 1; /* Flag that single timer to be used. */
+ } else {
+ /* Use two timers. */
+ div1 = devpriv->cached_div1;
+ div2 = devpriv->cached_div2;
+ pci224_cascade_ns_to_timer(TIMEBASE_10MHZ, &div1, &div2,
+ &ns, round_mode);
+ }
+
+ /*
+ * The output of timer Z2-0 will be used as the scan trigger
+ * source.
+ */
+ /* Make sure Z2-0 is gated on. */
+ outb(GAT_CONFIG(0, GAT_VCC),
+ devpriv->iobase1 + PCI224_ZGAT_SCE);
+ if (div1 == 1) {
+ /* Not cascading. Z2-0 needs 10 MHz clock. */
+ outb(CLK_CONFIG(0, CLK_10MHZ),
+ devpriv->iobase1 + PCI224_ZCLK_SCE);
+ } else {
+ /* Cascading with Z2-2. */
+ /* Make sure Z2-2 is gated on. */
+ outb(GAT_CONFIG(2, GAT_VCC),
+ devpriv->iobase1 + PCI224_ZGAT_SCE);
+ /* Z2-2 needs 10 MHz clock. */
+ outb(CLK_CONFIG(2, CLK_10MHZ),
+ devpriv->iobase1 + PCI224_ZCLK_SCE);
+ /* Load Z2-2 mode (2) and counter (div1). */
+ i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0,
+ 2, div1, 2);
+ /* Z2-0 is clocked from Z2-2's output. */
+ outb(CLK_CONFIG(0, CLK_OUTNM1),
+ devpriv->iobase1 + PCI224_ZCLK_SCE);
+ }
+ /* Load Z2-0 mode (2) and counter (div2). */
+ i8254_load(devpriv->iobase1 + PCI224_Z2_CT0, 0, 0, div2, 2);
+ }
+
+ /*
+ * Sort out end of acquisition.
+ */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* Fixed number of scans. */
+ devpriv->ao_stop_continuous = 0;
+ devpriv->ao_stop_count = cmd->stop_arg;
+ break;
+ default:
+ /* Continuous scans. */
+ devpriv->ao_stop_continuous = 1;
+ devpriv->ao_stop_count = 0;
+ break;
+ }
+
+ /*
+ * Sort out start of acquisition.
+ */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ s->async->inttrig = &pci224_ao_inttrig_start;
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ break;
+ case TRIG_EXT:
+ /* Enable external interrupt trigger to start acquisition. */
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ devpriv->intsce |= PCI224_INTR_EXT;
+ outb(devpriv->intsce, devpriv->iobase1 + PCI224_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * 'cancel' function for AO subdevice.
+ */
+static int pci224_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pci224_ao_stop(dev, s);
+ return 0;
+}
+
+/*
+ * 'munge' data for AO command.
+ */
+static void
+pci224_ao_munge(struct comedi_device * dev, struct comedi_subdevice * s, void *data,
+ unsigned int num_bytes, unsigned int chan_index)
+{
+ struct comedi_async *async = s->async;
+ short *array = data;
+ unsigned int length = num_bytes / sizeof(*array);
+ unsigned int offset;
+ unsigned int shift;
+ unsigned int i;
+
+ /* The hardware expects 16-bit numbers. */
+ shift = 16 - thisboard->ao_bits;
+ /* Channels will be all bipolar or all unipolar. */
+ if ((devpriv->hwrange[CR_RANGE(async->cmd.chanlist[0])] &
+ PCI224_DACCON_POLAR_MASK) == PCI224_DACCON_POLAR_UNI) {
+ /* Unipolar */
+ offset = 0;
+ } else {
+ /* Bipolar */
+ offset = 32768;
+ }
+ /* Munge the data. */
+ for (i = 0; i < length; i++) {
+ array[i] = (array[i] << shift) - offset;
+ }
+}
+
+/*
+ * Interrupt handler.
+ */
+static irqreturn_t pci224_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = &dev->subdevices[0];
+ struct comedi_cmd *cmd;
+ unsigned char intstat, valid_intstat;
+ unsigned char curenab;
+ int retval = 0;
+ unsigned long flags;
+
+ intstat = inb(devpriv->iobase1 + PCI224_INT_SCE) & 0x3F;
+ if (intstat) {
+ retval = 1;
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ valid_intstat = devpriv->intsce & intstat;
+ /* Temporarily disable interrupt sources. */
+ curenab = devpriv->intsce & ~intstat;
+ outb(curenab, devpriv->iobase1 + PCI224_INT_SCE);
+ devpriv->intr_running = 1;
+ devpriv->intr_cpuid = THISCPU;
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ if (valid_intstat != 0) {
+ cmd = &s->async->cmd;
+ if (valid_intstat & PCI224_INTR_EXT) {
+ devpriv->intsce &= ~PCI224_INTR_EXT;
+ if (cmd->start_src == TRIG_EXT) {
+ pci224_ao_start(dev, s);
+ } else if (cmd->stop_src == TRIG_EXT) {
+ pci224_ao_stop(dev, s);
+ }
+ }
+ if (valid_intstat & PCI224_INTR_DAC) {
+ pci224_ao_handle_fifo(dev, s);
+ }
+ }
+ /* Reenable interrupt sources. */
+ comedi_spin_lock_irqsave(&devpriv->ao_spinlock, flags);
+ if (curenab != devpriv->intsce) {
+ outb(devpriv->intsce,
+ devpriv->iobase1 + PCI224_INT_SCE);
+ }
+ devpriv->intr_running = 0;
+ comedi_spin_unlock_irqrestore(&devpriv->ao_spinlock, flags);
+ }
+ return IRQ_RETVAL(retval);
+}
+
+/*
+ * This function looks for a PCI device matching the requested board name,
+ * bus and slot.
+ */
+static int
+pci224_find_pci(struct comedi_device * dev, int bus, int slot,
+ struct pci_dev **pci_dev_p)
+{
+ struct pci_dev *pci_dev = NULL;
+
+ *pci_dev_p = NULL;
+
+ /* Look for matching PCI device. */
+ for (pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_VENDOR_ID_AMPLICON, PCI_ANY_ID,
+ pci_dev)) {
+ /* If bus/slot specified, check them. */
+ if (bus || slot) {
+ if (bus != pci_dev->bus->number
+ || slot != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (thisboard->model == any_model) {
+ /* Match any supported model. */
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(pci224_boards); i++) {
+ if (pci_dev->device == pci224_boards[i].devid) {
+ /* Change board_ptr to matched board. */
+ dev->board_ptr = &pci224_boards[i];
+ break;
+ }
+ }
+ if (i == ARRAY_SIZE(pci224_boards))
+ continue;
+ } else {
+ /* Match specific model name. */
+ if (thisboard->devid != pci_dev->device)
+ continue;
+ }
+
+ /* Found a match. */
+ *pci_dev_p = pci_dev;
+ return 0;
+ }
+ /* No match found. */
+ if (bus || slot) {
+ printk(KERN_ERR "comedi%d: error! "
+ "no %s found at pci %02x:%02x!\n",
+ dev->minor, thisboard->name, bus, slot);
+ } else {
+ printk(KERN_ERR "comedi%d: error! no %s found!\n",
+ dev->minor, thisboard->name);
+ }
+ return -EIO;
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci224_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pci_dev;
+ unsigned int irq;
+ int bus = 0, slot = 0;
+ unsigned n;
+ int ret;
+
+ printk(KERN_DEBUG "comedi%d: %s: attach\n", dev->minor, DRIVER_NAME);
+
+ bus = it->options[0];
+ slot = it->options[1];
+ if ((ret = alloc_private(dev, sizeof(struct pci224_private))) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+ if ((ret = pci224_find_pci(dev, bus, slot, &pci_dev)) < 0)
+ return ret;
+ devpriv->pci_dev = pci_dev;
+
+ if ((ret = comedi_pci_enable(pci_dev, DRIVER_NAME)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: error! cannot enable PCI device "
+ "and request regions!\n", dev->minor);
+ return ret;
+ }
+ spin_lock_init(&devpriv->ao_spinlock);
+
+ devpriv->iobase1 = pci_resource_start(pci_dev, 2);
+ dev->iobase = pci_resource_start(pci_dev, 3);
+ irq = pci_dev->irq;
+
+ /* Allocate readback buffer for AO channels. */
+ devpriv->ao_readback = kmalloc(sizeof(devpriv->ao_readback[0]) *
+ thisboard->ao_chans, GFP_KERNEL);
+ if (!devpriv->ao_readback) {
+ return -ENOMEM;
+ }
+
+ /* Allocate buffer to hold values for AO channel scan. */
+ devpriv->ao_scan_vals = kmalloc(sizeof(devpriv->ao_scan_vals[0]) *
+ thisboard->ao_chans, GFP_KERNEL);
+ if (!devpriv->ao_scan_vals) {
+ return -ENOMEM;
+ }
+
+ /* Allocate buffer to hold AO channel scan order. */
+ devpriv->ao_scan_order = kmalloc(sizeof(devpriv->ao_scan_order[0]) *
+ thisboard->ao_chans, GFP_KERNEL);
+ if (!devpriv->ao_scan_order) {
+ return -ENOMEM;
+ }
+
+ /* Disable interrupt sources. */
+ devpriv->intsce = 0;
+ outb(0, devpriv->iobase1 + PCI224_INT_SCE);
+
+ /* Initialize the DAC hardware. */
+ outw(PCI224_DACCON_GLOBALRESET, dev->iobase + PCI224_DACCON);
+ outw(0, dev->iobase + PCI224_DACCEN);
+ outw(0, dev->iobase + PCI224_FIFOSIZ);
+ devpriv->daccon = (PCI224_DACCON_TRIG_SW | PCI224_DACCON_POLAR_BI |
+ PCI224_DACCON_FIFOENAB | PCI224_DACCON_FIFOINTR_EMPTY);
+ outw(devpriv->daccon | PCI224_DACCON_FIFORESET,
+ dev->iobase + PCI224_DACCON);
+
+ /* Allocate subdevices. There is only one! */
+ if ((ret = alloc_subdevices(dev, 1)) < 0) {
+ printk(KERN_ERR "comedi%d: error! out of memory!\n",
+ dev->minor);
+ return ret;
+ }
+
+ s = dev->subdevices + 0;
+ /* Analog output subdevice. */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->insn_write = &pci224_ao_insn_write;
+ s->insn_read = &pci224_ao_insn_read;
+ s->len_chanlist = s->n_chan;
+
+ dev->write_subdev = s;
+ s->do_cmd = &pci224_ao_cmd;
+ s->do_cmdtest = &pci224_ao_cmdtest;
+ s->cancel = &pci224_ao_cancel;
+ s->munge = &pci224_ao_munge;
+
+ /* Sort out channel range options. */
+ if (thisboard->model == pci234_model) {
+ /* PCI234 range options. */
+ const struct comedi_lrange **range_table_list;
+
+ s->range_table_list = range_table_list =
+ kmalloc(sizeof(struct comedi_lrange *) * s->n_chan,
+ GFP_KERNEL);
+ if (!s->range_table_list) {
+ return -ENOMEM;
+ }
+ for (n = 2; n < 3 + s->n_chan; n++) {
+ if (it->options[n] < 0 || it->options[n] > 1) {
+ printk(KERN_WARNING "comedi%d: %s: warning! "
+ "bad options[%u]=%d\n",
+ dev->minor, DRIVER_NAME, n,
+ it->options[n]);
+ }
+ }
+ for (n = 0; n < s->n_chan; n++) {
+ if (n < COMEDI_NDEVCONFOPTS - 3 &&
+ it->options[3 + n] == 1) {
+ if (it->options[2] == 1) {
+ range_table_list[n] = &range_pci234_ext;
+ } else {
+ range_table_list[n] = &range_bipolar5;
+ }
+ } else {
+ if (it->options[2] == 1) {
+ range_table_list[n] =
+ &range_pci234_ext2;
+ } else {
+ range_table_list[n] = &range_bipolar10;
+ }
+ }
+ }
+ devpriv->hwrange = hwrange_pci234;
+ } else {
+ /* PCI224 range options. */
+ if (it->options[2] == 1) {
+ s->range_table = &range_pci224_external;
+ devpriv->hwrange = hwrange_pci224_external;
+ } else {
+ if (it->options[2] != 0) {
+ printk(KERN_WARNING "comedi%d: %s: warning! "
+ "bad options[2]=%d\n",
+ dev->minor, DRIVER_NAME,
+ it->options[2]);
+ }
+ s->range_table = &range_pci224_internal;
+ devpriv->hwrange = hwrange_pci224_internal;
+ }
+ }
+
+ dev->board_name = thisboard->name;
+
+ if (irq) {
+ ret = comedi_request_irq(irq, pci224_interrupt, IRQF_SHARED,
+ DRIVER_NAME, dev);
+ if (ret < 0) {
+ printk(KERN_ERR "comedi%d: error! "
+ "unable to allocate irq %u\n", dev->minor, irq);
+ return ret;
+ } else {
+ dev->irq = irq;
+ }
+ }
+
+ printk(KERN_INFO "comedi%d: %s ", dev->minor, dev->board_name);
+ printk("(pci %s) ", pci_name(pci_dev));
+ if (irq) {
+ printk("(irq %u%s) ", irq, (dev->irq ? "" : " UNAVAILABLE"));
+ } else {
+ printk("(no irq) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci224_detach(struct comedi_device * dev)
+{
+ printk(KERN_DEBUG "comedi%d: %s: detach\n", dev->minor, DRIVER_NAME);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->subdevices) {
+ struct comedi_subdevice *s;
+
+ s = dev->subdevices + 0;
+ /* AO subdevice */
+ if (s->range_table_list) {
+ kfree(s->range_table_list);
+ }
+ }
+ if (devpriv) {
+ if (devpriv->ao_readback) {
+ kfree(devpriv->ao_readback);
+ }
+ if (devpriv->ao_scan_vals) {
+ kfree(devpriv->ao_scan_vals);
+ }
+ if (devpriv->ao_scan_order) {
+ kfree(devpriv->ao_scan_order);
+ }
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ if (dev->board_name) {
+ printk(KERN_INFO "comedi%d: %s removed\n",
+ dev->minor, dev->board_name);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c
new file mode 100644
index 00000000000..0c9e5737e10
--- /dev/null
+++ b/drivers/staging/comedi/drivers/amplc_pci230.c
@@ -0,0 +1,2977 @@
+ /*
+ comedi/drivers/amplc_pci230.c
+ Driver for Amplicon PCI230 and PCI260 Multifunction I/O boards.
+
+ Copyright (C) 2001 Allan Willcox <allanwillcox@ozemail.com.au>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+Driver: amplc_pci230
+Description: Amplicon PCI230, PCI260 Multifunction I/O boards
+Author: Allan Willcox <allanwillcox@ozemail.com.au>,
+ Steve D Sharples <steve.sharples@nottingham.ac.uk>,
+ Ian Abbott <abbotti@mev.co.uk>
+Updated: Wed, 22 Oct 2008 12:34:49 +0100
+Devices: [Amplicon] PCI230 (pci230 or amplc_pci230),
+ PCI230+ (pci230+ or amplc_pci230),
+ PCI260 (pci260 or amplc_pci230), PCI260+ (pci260+ or amplc_pci230)
+Status: works
+
+Configuration options:
+ [0] - PCI bus of device (optional).
+ [1] - PCI slot of device (optional).
+ If bus/slot is not specified, the first available PCI device
+ will be used.
+
+Configuring a "amplc_pci230" will match any supported card and it will
+choose the best match, picking the "+" models if possible. Configuring
+a "pci230" will match a PCI230 or PCI230+ card and it will be treated as
+a PCI230. Configuring a "pci260" will match a PCI260 or PCI260+ card
+and it will be treated as a PCI260. Configuring a "pci230+" will match
+a PCI230+ card. Configuring a "pci260+" will match a PCI260+ card.
+
+Subdevices:
+
+ PCI230(+) PCI260(+)
+ --------- ---------
+ Subdevices 3 1
+ 0 AI AI
+ 1 AO
+ 2 DIO
+
+AI Subdevice:
+
+ The AI subdevice has 16 single-ended channels or 8 differential
+ channels.
+
+ The PCI230 and PCI260 cards have 12-bit resolution. The PCI230+ and
+ PCI260+ cards have 16-bit resolution.
+
+ For differential mode, use inputs 2N and 2N+1 for channel N (e.g. use
+ inputs 14 and 15 for channel 7). If the card is physically a PCI230
+ or PCI260 then it actually uses a "pseudo-differential" mode where the
+ inputs are sampled a few microseconds apart. The PCI230+ and PCI260+
+ use true differential sampling. Another difference is that if the
+ card is physically a PCI230 or PCI260, the inverting input is 2N,
+ whereas for a PCI230+ or PCI260+ the inverting input is 2N+1. So if a
+ PCI230 is physically replaced by a PCI230+ (or a PCI260 with a
+ PCI260+) and differential mode is used, the differential inputs need
+ to be physically swapped on the connector.
+
+ The following input ranges are supported:
+
+ 0 => [-10, +10] V
+ 1 => [-5, +5] V
+ 2 => [-2.5, +2.5] V
+ 3 => [-1.25, +1.25] V
+ 4 => [0, 10] V
+ 5 => [0, 5] V
+ 6 => [0, 2.5] V
+
+AI Commands:
+
+ +=========+==============+===========+============+==========+
+ |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ +=========+==============+===========+============+==========+
+ |TRIG_NOW | TRIG_FOLLOW |TRIG_TIMER | TRIG_COUNT |TRIG_NONE |
+ |TRIG_INT | |TRIG_EXT(3)| |TRIG_COUNT|
+ | | |TRIG_INT | | |
+ | |--------------|-----------| | |
+ | | TRIG_TIMER(1)|TRIG_TIMER | | |
+ | | TRIG_EXT(2) | | | |
+ | | TRIG_INT | | | |
+ +---------+--------------+-----------+------------+----------+
+
+ Note 1: If AI command and AO command are used simultaneously, only
+ one may have scan_begin_src == TRIG_TIMER.
+
+ Note 2: For PCI230 and PCI230+, scan_begin_src == TRIG_EXT uses
+ DIO channel 16 (pin 49) which will need to be configured as
+ a digital input. For PCI260+, the EXTTRIG/EXTCONVCLK input
+ (pin 17) is used instead. For PCI230, scan_begin_src ==
+ TRIG_EXT is not supported. The trigger is a rising edge
+ on the input.
+
+ Note 3: For convert_src == TRIG_EXT, the EXTTRIG/EXTCONVCLK input
+ (pin 25 on PCI230(+), pin 17 on PCI260(+)) is used. The
+ convert_arg value is interpreted as follows:
+
+ convert_arg == (CR_EDGE | 0) => rising edge
+ convert_arg == (CR_EDGE | CR_INVERT | 0) => falling edge
+ convert_arg == 0 => falling edge (backwards compatibility)
+ convert_arg == 1 => rising edge (backwards compatibility)
+
+ All entries in the channel list must use the same analogue reference.
+ If the analogue reference is not AREF_DIFF (not differential) each
+ pair of channel numbers (0 and 1, 2 and 3, etc.) must use the same
+ input range. The input ranges used in the sequence must be all
+ bipolar (ranges 0 to 3) or all unipolar (ranges 4 to 6). The channel
+ sequence must consist of 1 or more identical subsequences. Within the
+ subsequence, channels must be in ascending order with no repeated
+ channels. For example, the following sequences are valid: 0 1 2 3
+ (single valid subsequence), 0 2 3 5 0 2 3 5 (repeated valid
+ subsequence), 1 1 1 1 (repeated valid subsequence). The following
+ sequences are invalid: 0 3 2 1 (invalid subsequence), 0 2 3 5 0 2 3
+ (incompletely repeated subsequence). Some versions of the PCI230+ and
+ PCI260+ have a bug that requires a subsequence longer than one entry
+ long to include channel 0.
+
+AO Subdevice:
+
+ The AO subdevice has 2 channels with 12-bit resolution.
+
+ The following output ranges are supported:
+
+ 0 => [0, 10] V
+ 1 => [-10, +10] V
+
+AO Commands:
+
+ +=========+==============+===========+============+==========+
+ |start_src|scan_begin_src|convert_src|scan_end_src| stop_src |
+ +=========+==============+===========+============+==========+
+ |TRIG_INT | TRIG_TIMER(1)| TRIG_NOW | TRIG_COUNT |TRIG_NONE |
+ | | TRIG_EXT(2) | | |TRIG_COUNT|
+ | | TRIG_INT | | | |
+ +---------+--------------+-----------+------------+----------+
+
+ Note 1: If AI command and AO command are used simultaneously, only
+ one may have scan_begin_src == TRIG_TIMER.
+
+ Note 2: scan_begin_src == TRIG_EXT is only supported if the card is
+ configured as a PCI230+ and is only supported on later
+ versions of the card. As a card configured as a PCI230+ is
+ not guaranteed to support external triggering, please consider
+ this support to be a bonus. It uses the EXTTRIG/ EXTCONVCLK
+ input (PCI230+ pin 25). Triggering will be on the rising edge
+ unless the CR_INVERT flag is set in scan_begin_arg.
+
+ The channels in the channel sequence must be in ascending order with
+ no repeats. All entries in the channel sequence must use the same
+ output range.
+
+DIO Subdevice:
+
+ The DIO subdevice is a 8255 chip providing 24 DIO channels. The DIO
+ channels are configurable as inputs or outputs in four groups:
+
+ Port A - channels 0 to 7
+ Port B - channels 8 to 15
+ Port CL - channels 16 to 19
+ Port CH - channels 20 to 23
+
+ Only mode 0 of the 8255 chip is supported.
+
+ Bit 0 of port C (DIO channel 16) is also used as an external scan
+ trigger input for AI commands on PCI230 and PCI230+, so would need to
+ be configured as an input to use it for that purpose.
+*/
+/*
+Extra triggered scan functionality, interrupt bug-fix added by Steve Sharples.
+Support for PCI230+/260+, more triggered scan functionality, and workarounds
+for (or detection of) various hardware problems added by Ian Abbott.
+*/
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8253.h"
+#include "8255.h"
+
+/* PCI230 PCI configuration register information */
+#define PCI_VENDOR_ID_AMPLICON 0x14dc
+#define PCI_DEVICE_ID_PCI230 0x0000
+#define PCI_DEVICE_ID_PCI260 0x0006
+#define PCI_DEVICE_ID_INVALID 0xffff
+
+#define PCI230_IO1_SIZE 32 /* Size of I/O space 1 */
+#define PCI230_IO2_SIZE 16 /* Size of I/O space 2 */
+
+/* PCI230 i/o space 1 registers. */
+#define PCI230_PPI_X_BASE 0x00 /* User PPI (82C55) base */
+#define PCI230_PPI_X_A 0x00 /* User PPI (82C55) port A */
+#define PCI230_PPI_X_B 0x01 /* User PPI (82C55) port B */
+#define PCI230_PPI_X_C 0x02 /* User PPI (82C55) port C */
+#define PCI230_PPI_X_CMD 0x03 /* User PPI (82C55) control word */
+#define PCI230_Z2_CT_BASE 0x14 /* 82C54 counter/timer base */
+#define PCI230_Z2_CT0 0x14 /* 82C54 counter/timer 0 */
+#define PCI230_Z2_CT1 0x15 /* 82C54 counter/timer 1 */
+#define PCI230_Z2_CT2 0x16 /* 82C54 counter/timer 2 */
+#define PCI230_Z2_CTC 0x17 /* 82C54 counter/timer control word */
+#define PCI230_ZCLK_SCE 0x1A /* Group Z Clock Configuration */
+#define PCI230_ZGAT_SCE 0x1D /* Group Z Gate Configuration */
+#define PCI230_INT_SCE 0x1E /* Interrupt source mask (w) */
+#define PCI230_INT_STAT 0x1E /* Interrupt status (r) */
+
+/* PCI230 i/o space 2 registers. */
+#define PCI230_DACCON 0x00 /* DAC control */
+#define PCI230_DACOUT1 0x02 /* DAC channel 0 (w) */
+#define PCI230_DACOUT2 0x04 /* DAC channel 1 (w) (not FIFO mode) */
+#define PCI230_ADCDATA 0x08 /* ADC data (r) */
+#define PCI230_ADCSWTRIG 0x08 /* ADC software trigger (w) */
+#define PCI230_ADCCON 0x0A /* ADC control */
+#define PCI230_ADCEN 0x0C /* ADC channel enable bits */
+#define PCI230_ADCG 0x0E /* ADC gain control bits */
+/* PCI230+ i/o space 2 additional registers. */
+#define PCI230P_ADCTRIG 0x10 /* ADC start acquisition trigger */
+#define PCI230P_ADCTH 0x12 /* ADC analog trigger threshold */
+#define PCI230P_ADCFFTH 0x14 /* ADC FIFO interrupt threshold */
+#define PCI230P_ADCFFLEV 0x16 /* ADC FIFO level (r) */
+#define PCI230P_ADCPTSC 0x18 /* ADC pre-trigger sample count (r) */
+#define PCI230P_ADCHYST 0x1A /* ADC analog trigger hysteresys */
+#define PCI230P_EXTFUNC 0x1C /* Extended functions */
+#define PCI230P_HWVER 0x1E /* Hardware version (r) */
+/* PCI230+ hardware version 2 onwards. */
+#define PCI230P2_DACDATA 0x02 /* DAC data (FIFO mode) (w) */
+#define PCI230P2_DACSWTRIG 0x02 /* DAC soft trigger (FIFO mode) (r) */
+#define PCI230P2_DACEN 0x06 /* DAC channel enable (FIFO mode) */
+
+/* Convertor related constants. */
+#define PCI230_DAC_SETTLE 5 /* Analogue output settling time in µs */
+ /* (DAC itself is 1µs nominally). */
+#define PCI230_ADC_SETTLE 1 /* Analogue input settling time in µs */
+ /* (ADC itself is 1.6µs nominally but we poll
+ * anyway). */
+#define PCI230_MUX_SETTLE 10 /* ADC MUX settling time in µS */
+ /* - 10µs for se, 20µs de. */
+
+/* DACCON read-write values. */
+#define PCI230_DAC_OR_UNI (0<<0) /* Output range unipolar */
+#define PCI230_DAC_OR_BIP (1<<0) /* Output range bipolar */
+#define PCI230_DAC_OR_MASK (1<<0)
+/* The following applies only if DAC FIFO support is enabled in the EXTFUNC
+ * register (and only for PCI230+ hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_EN (1<<8) /* FIFO enable */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_TRIG_NONE (0<<2) /* No trigger */
+#define PCI230P2_DAC_TRIG_SW (1<<2) /* Software trigger trigger */
+#define PCI230P2_DAC_TRIG_EXTP (2<<2) /* EXTTRIG +ve edge trigger */
+#define PCI230P2_DAC_TRIG_EXTN (3<<2) /* EXTTRIG -ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT0 (4<<2) /* CT0-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT1 (5<<2) /* CT1-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_Z2CT2 (6<<2) /* CT2-OUT +ve edge trigger */
+#define PCI230P2_DAC_TRIG_MASK (7<<2)
+#define PCI230P2_DAC_FIFO_WRAP (1<<7) /* FIFO wraparound mode */
+#define PCI230P2_DAC_INT_FIFO_EMPTY (0<<9) /* FIFO interrupt empty */
+#define PCI230P2_DAC_INT_FIFO_NEMPTY (1<<9)
+#define PCI230P2_DAC_INT_FIFO_NHALF (2<<9) /* FIFO intr not half full */
+#define PCI230P2_DAC_INT_FIFO_HALF (3<<9)
+#define PCI230P2_DAC_INT_FIFO_NFULL (4<<9) /* FIFO interrupt not full */
+#define PCI230P2_DAC_INT_FIFO_FULL (5<<9)
+#define PCI230P2_DAC_INT_FIFO_MASK (7<<9)
+
+/* DACCON read-only values. */
+#define PCI230_DAC_BUSY (1<<1) /* DAC busy. */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_UNDERRUN_LATCHED (1<<5) /* Underrun error */
+#define PCI230P2_DAC_FIFO_EMPTY (1<<13) /* FIFO empty */
+#define PCI230P2_DAC_FIFO_FULL (1<<14) /* FIFO full */
+#define PCI230P2_DAC_FIFO_HALF (1<<15) /* FIFO half full */
+
+/* DACCON write-only, transient values. */
+/* The following apply only if the DAC FIFO is enabled (and only for PCI230+
+ * hardware version 2 onwards). */
+#define PCI230P2_DAC_FIFO_UNDERRUN_CLEAR (1<<5) /* Clear underrun */
+#define PCI230P2_DAC_FIFO_RESET (1<<12) /* FIFO reset */
+
+/* PCI230+ hardware version 2 DAC FIFO levels. */
+#define PCI230P2_DAC_FIFOLEVEL_HALF 512
+#define PCI230P2_DAC_FIFOLEVEL_FULL 1024
+/* Free space in DAC FIFO. */
+#define PCI230P2_DAC_FIFOROOM_EMPTY PCI230P2_DAC_FIFOLEVEL_FULL
+#define PCI230P2_DAC_FIFOROOM_ONETOHALF \
+ (PCI230P2_DAC_FIFOLEVEL_FULL - PCI230P2_DAC_FIFOLEVEL_HALF)
+#define PCI230P2_DAC_FIFOROOM_HALFTOFULL 1
+#define PCI230P2_DAC_FIFOROOM_FULL 0
+
+/* ADCCON read/write values. */
+#define PCI230_ADC_TRIG_NONE (0<<0) /* No trigger */
+#define PCI230_ADC_TRIG_SW (1<<0) /* Software trigger trigger */
+#define PCI230_ADC_TRIG_EXTP (2<<0) /* EXTTRIG +ve edge trigger */
+#define PCI230_ADC_TRIG_EXTN (3<<0) /* EXTTRIG -ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT0 (4<<0) /* CT0-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT1 (5<<0) /* CT1-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_Z2CT2 (6<<0) /* CT2-OUT +ve edge trigger */
+#define PCI230_ADC_TRIG_MASK (7<<0)
+#define PCI230_ADC_IR_UNI (0<<3) /* Input range unipolar */
+#define PCI230_ADC_IR_BIP (1<<3) /* Input range bipolar */
+#define PCI230_ADC_IR_MASK (1<<3)
+#define PCI230_ADC_IM_SE (0<<4) /* Input mode single ended */
+#define PCI230_ADC_IM_DIF (1<<4) /* Input mode differential */
+#define PCI230_ADC_IM_MASK (1<<4)
+#define PCI230_ADC_FIFO_EN (1<<8) /* FIFO enable */
+#define PCI230_ADC_INT_FIFO_EMPTY (0<<9)
+#define PCI230_ADC_INT_FIFO_NEMPTY (1<<9) /* FIFO interrupt not empty */
+#define PCI230_ADC_INT_FIFO_NHALF (2<<9)
+#define PCI230_ADC_INT_FIFO_HALF (3<<9) /* FIFO interrupt half full */
+#define PCI230_ADC_INT_FIFO_NFULL (4<<9)
+#define PCI230_ADC_INT_FIFO_FULL (5<<9) /* FIFO interrupt full */
+#define PCI230P_ADC_INT_FIFO_THRESH (7<<9) /* FIFO interrupt threshold */
+#define PCI230_ADC_INT_FIFO_MASK (7<<9)
+
+/* ADCCON write-only, transient values. */
+#define PCI230_ADC_FIFO_RESET (1<<12) /* FIFO reset */
+#define PCI230_ADC_GLOB_RESET (1<<13) /* Global reset */
+
+/* ADCCON read-only values. */
+#define PCI230_ADC_BUSY (1<<15) /* ADC busy */
+#define PCI230_ADC_FIFO_EMPTY (1<<12) /* FIFO empty */
+#define PCI230_ADC_FIFO_FULL (1<<13) /* FIFO full */
+#define PCI230_ADC_FIFO_HALF (1<<14) /* FIFO half full */
+#define PCI230_ADC_FIFO_FULL_LATCHED (1<<5) /* Indicates overrun occurred */
+
+/* PCI230 ADC FIFO levels. */
+#define PCI230_ADC_FIFOLEVEL_HALFFULL 2049 /* Value for FIFO half full */
+#define PCI230_ADC_FIFOLEVEL_FULL 4096 /* FIFO size */
+
+/* Value to write to ADCSWTRIG to trigger ADC conversion in software trigger
+ * mode. Can be anything. */
+#define PCI230_ADC_CONV 0xffff
+
+/* PCI230+ EXTFUNC values. */
+#define PCI230P_EXTFUNC_GAT_EXTTRIG (1<<0)
+ /* Route EXTTRIG pin to external gate inputs. */
+/* PCI230+ hardware version 2 values. */
+#define PCI230P2_EXTFUNC_DACFIFO (1<<1)
+ /* Allow DAC FIFO to be enabled. */
+
+/*
+ * Counter/timer clock input configuration sources.
+ */
+#define CLK_CLK 0 /* reserved (channel-specific clock) */
+#define CLK_10MHZ 1 /* internal 10 MHz clock */
+#define CLK_1MHZ 2 /* internal 1 MHz clock */
+#define CLK_100KHZ 3 /* internal 100 kHz clock */
+#define CLK_10KHZ 4 /* internal 10 kHz clock */
+#define CLK_1KHZ 5 /* internal 1 kHz clock */
+#define CLK_OUTNM1 6 /* output of channel-1 modulo total */
+#define CLK_EXT 7 /* external clock */
+/* Macro to construct clock input configuration register value. */
+#define CLK_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+/* Timebases in ns. */
+#define TIMEBASE_10MHZ 100
+#define TIMEBASE_1MHZ 1000
+#define TIMEBASE_100KHZ 10000
+#define TIMEBASE_10KHZ 100000
+#define TIMEBASE_1KHZ 1000000
+
+/*
+ * Counter/timer gate input configuration sources.
+ */
+#define GAT_VCC 0 /* VCC (i.e. enabled) */
+#define GAT_GND 1 /* GND (i.e. disabled) */
+#define GAT_EXT 2 /* external gate input (PPCn on PCI230) */
+#define GAT_NOUTNM2 3 /* inverted output of channel-2 modulo total */
+/* Macro to construct gate input configuration register value. */
+#define GAT_CONFIG(chan, src) ((((chan) & 3) << 3) | ((src) & 7))
+
+/*
+ * Summary of CLK_OUTNM1 and GAT_NOUTNM2 connections for PCI230 and PCI260:
+ *
+ * Channel's Channel's
+ * clock input gate input
+ * Channel CLK_OUTNM1 GAT_NOUTNM2
+ * ------- ---------- -----------
+ * Z2-CT0 Z2-CT2-OUT /Z2-CT1-OUT
+ * Z2-CT1 Z2-CT0-OUT /Z2-CT2-OUT
+ * Z2-CT2 Z2-CT1-OUT /Z2-CT0-OUT
+ */
+
+/* Interrupt enables/status register values. */
+#define PCI230_INT_DISABLE 0
+#define PCI230_INT_PPI_C0 (1<<0)
+#define PCI230_INT_PPI_C3 (1<<1)
+#define PCI230_INT_ADC (1<<2)
+#define PCI230_INT_ZCLK_CT1 (1<<5)
+/* For PCI230+ hardware version 2 when DAC FIFO enabled. */
+#define PCI230P2_INT_DAC (1<<4)
+
+#define PCI230_TEST_BIT(val, n) ((val>>n)&1)
+ /* Assumes bits numbered with zero offset, ie. 0-15 */
+
+/* (Potentially) shared resources and their owners */
+enum {
+ RES_Z2CT0, /* Z2-CT0 */
+ RES_Z2CT1, /* Z2-CT1 */
+ RES_Z2CT2, /* Z2-CT2 */
+ NUM_RESOURCES /* Number of (potentially) shared resources. */
+};
+
+enum {
+ OWNER_NONE, /* Not owned */
+ OWNER_AICMD, /* Owned by AI command */
+ OWNER_AOCMD /* Owned by AO command */
+};
+
+/*
+ * Handy macros.
+ */
+
+/* Combine old and new bits. */
+#define COMBINE(old, new, mask) (((old) & ~(mask)) | ((new) & (mask)))
+
+/* A generic null function pointer value. */
+#define NULLFUNC 0
+
+/* Current CPU. XXX should this be hard_smp_processor_id()? */
+#define THISCPU smp_processor_id()
+
+/* State flags for atomic bit operations */
+#define AI_CMD_STARTED 0
+#define AO_CMD_STARTED 1
+
+/*
+ * Board descriptions for the two boards supported.
+ */
+
+struct pci230_board {
+ const char *name;
+ unsigned short id;
+ int ai_chans;
+ int ai_bits;
+ int ao_chans;
+ int ao_bits;
+ int have_dio;
+ unsigned int min_hwver; /* Minimum hardware version supported. */
+};
+static const struct pci230_board pci230_boards[] = {
+ {
+ name: "pci230+",
+ id: PCI_DEVICE_ID_PCI230,
+ ai_chans:16,
+ ai_bits: 16,
+ ao_chans:2,
+ ao_bits: 12,
+ have_dio:1,
+ min_hwver:1,
+ },
+ {
+ name: "pci260+",
+ id: PCI_DEVICE_ID_PCI260,
+ ai_chans:16,
+ ai_bits: 16,
+ ao_chans:0,
+ ao_bits: 0,
+ have_dio:0,
+ min_hwver:1,
+ },
+ {
+ name: "pci230",
+ id: PCI_DEVICE_ID_PCI230,
+ ai_chans:16,
+ ai_bits: 12,
+ ao_chans:2,
+ ao_bits: 12,
+ have_dio:1,
+ },
+ {
+ name: "pci260",
+ id: PCI_DEVICE_ID_PCI260,
+ ai_chans:16,
+ ai_bits: 12,
+ ao_chans:0,
+ ao_bits: 0,
+ have_dio:0,
+ },
+ {
+ name: "amplc_pci230", /* Wildcard matches any above */
+ id: PCI_DEVICE_ID_INVALID,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(pci230_pci_table) = {
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI230, PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, 0},
+ {PCI_VENDOR_ID_AMPLICON, PCI_DEVICE_ID_PCI260, PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci230_pci_table);
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define n_pci230_boards (sizeof(pci230_boards)/sizeof(pci230_boards[0]))
+#define thisboard ((const struct pci230_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pci230_private {
+ struct pci_dev *pci_dev;
+ spinlock_t isr_spinlock; /* Interrupt spin lock */
+ spinlock_t res_spinlock; /* Shared resources spin lock */
+ spinlock_t ai_stop_spinlock; /* Spin lock for stopping AI command */
+ spinlock_t ao_stop_spinlock; /* Spin lock for stopping AO command */
+ unsigned long state; /* State flags */
+ unsigned long iobase1; /* PCI230's I/O space 1 */
+ unsigned int ao_readback[2]; /* Used for AO readback */
+ unsigned int ai_scan_count; /* Number of analogue input scans
+ * remaining. */
+ unsigned int ai_scan_pos; /* Current position within analogue
+ * input scan */
+ unsigned int ao_scan_count; /* Number of analogue output scans
+ * remaining. */
+ int intr_cpuid; /* ID of CPU running interrupt routine. */
+ unsigned short hwver; /* Hardware version (for '+' models). */
+ unsigned short adccon; /* ADCCON register value. */
+ unsigned short daccon; /* DACCON register value. */
+ unsigned short adcfifothresh; /* ADC FIFO programmable interrupt
+ * level threshold (PCI230+/260+). */
+ unsigned short adcg; /* ADCG register value. */
+ unsigned char int_en; /* Interrupt enables bits. */
+ unsigned char ai_continuous; /* Flag set when cmd->stop_src ==
+ * TRIG_NONE - user chooses to stop
+ * continuous conversion by
+ * cancelation. */
+ unsigned char ao_continuous; /* Flag set when cmd->stop_src ==
+ * TRIG_NONE - user chooses to stop
+ * continuous conversion by
+ * cancelation. */
+ unsigned char ai_bipolar; /* Set if bipolar input range so we
+ * know to mangle it. */
+ unsigned char ao_bipolar; /* Set if bipolar output range so we
+ * know to mangle it. */
+ unsigned char ier; /* Copy of interrupt enables/status register. */
+ unsigned char intr_running; /* Flag set in interrupt routine. */
+ unsigned char res_owner[NUM_RESOURCES]; /* Shared resource owners. */
+};
+
+#define devpriv ((struct pci230_private *)dev->private)
+
+/* PCI230 clock source periods in ns */
+static const unsigned int pci230_timebase[8] = {
+ [CLK_10MHZ] = TIMEBASE_10MHZ,
+ [CLK_1MHZ] = TIMEBASE_1MHZ,
+ [CLK_100KHZ] = TIMEBASE_100KHZ,
+ [CLK_10KHZ] = TIMEBASE_10KHZ,
+ [CLK_1KHZ] = TIMEBASE_1KHZ,
+};
+
+/* PCI230 analogue input range table */
+static const struct comedi_lrange pci230_ai_range = { 7, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5)
+ }
+};
+
+/* PCI230 analogue gain bits for each input range. */
+static const unsigned char pci230_ai_gain[7] = { 0, 1, 2, 3, 1, 2, 3 };
+
+/* PCI230 adccon bipolar flag for each analogue input range. */
+static const unsigned char pci230_ai_bipolar[7] = { 1, 1, 1, 1, 0, 0, 0 };
+
+/* PCI230 analogue output range table */
+static const struct comedi_lrange pci230_ao_range = { 2, {
+ UNI_RANGE(10),
+ BIP_RANGE(10)
+ }
+};
+
+/* PCI230 daccon bipolar flag for each analogue output range. */
+static const unsigned char pci230_ao_bipolar[2] = { 0, 1 };
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pci230_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci230_detach(struct comedi_device * dev);
+static struct comedi_driver driver_amplc_pci230 = {
+ driver_name:"amplc_pci230",
+ module:THIS_MODULE,
+ attach:pci230_attach,
+ detach:pci230_detach,
+ board_name:&pci230_boards[0].name,
+ offset:sizeof(pci230_boards[0]),
+ num_names:sizeof(pci230_boards) / sizeof(pci230_boards[0]),
+};
+
+COMEDI_PCI_INITCLEANUP(driver_amplc_pci230, pci230_pci_table);
+
+static int pci230_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci230_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci230_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void pci230_ct_setup_ns_mode(struct comedi_device * dev, unsigned int ct,
+ unsigned int mode, uint64_t ns, unsigned int round);
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round);
+static void pci230_cancel_ct(struct comedi_device * dev, unsigned int ct);
+static irqreturn_t pci230_interrupt(int irq, void *d PT_REGS_ARG);
+static int pci230_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pci230_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_handle_ao_nofifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_handle_ao_fifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pci230_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci230_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_ai_stop(struct comedi_device * dev, struct comedi_subdevice * s);
+static void pci230_handle_ai(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static short pci230_ai_read(struct comedi_device * dev)
+{
+ /* Read sample. */
+ short data = (short) inw(dev->iobase + PCI230_ADCDATA);
+
+ /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+ * four bits reserved for expansion). */
+ /* PCI230+ is 16 bit AI. */
+ data = data >> (16 - thisboard->ai_bits);
+
+ /* If a bipolar range was specified, mangle it (twos
+ * complement->straight binary). */
+ if (devpriv->ai_bipolar) {
+ data ^= 1 << (thisboard->ai_bits - 1);
+ }
+ return data;
+}
+
+static inline unsigned short pci230_ao_mangle_datum(struct comedi_device * dev,
+ short datum)
+{
+ /* If a bipolar range was specified, mangle it (straight binary->twos
+ * complement). */
+ if (devpriv->ao_bipolar) {
+ datum ^= 1 << (thisboard->ao_bits - 1);
+ }
+
+ /* PCI230 is 12 bit - stored in upper bits of 16 bit register (lower
+ * four bits reserved for expansion). */
+ /* PCI230+ is also 12 bit AO. */
+ datum <<= (16 - thisboard->ao_bits);
+ return (unsigned short)datum;
+}
+
+static inline void pci230_ao_write_nofifo(struct comedi_device * dev, short datum,
+ unsigned int chan)
+{
+ /* Store unmangled datum to be read back later. */
+ devpriv->ao_readback[chan] = datum;
+
+ /* Write mangled datum to appropriate DACOUT register. */
+ outw(pci230_ao_mangle_datum(dev, datum), dev->iobase + (((chan) == 0)
+ ? PCI230_DACOUT1 : PCI230_DACOUT2));
+}
+
+static inline void pci230_ao_write_fifo(struct comedi_device * dev, short datum,
+ unsigned int chan)
+{
+ /* Store unmangled datum to be read back later. */
+ devpriv->ao_readback[chan] = datum;
+
+ /* Write mangled datum to appropriate DACDATA register. */
+ outw(pci230_ao_mangle_datum(dev, datum),
+ dev->iobase + PCI230P2_DACDATA);
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pci230_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase1, iobase2;
+ /* PCI230's I/O spaces 1 and 2 respectively. */
+ struct pci_dev *pci_dev;
+ int i = 0, irq_hdl, rc;
+
+ printk("comedi%d: amplc_pci230: attach %s %d,%d\n", dev->minor,
+ thisboard->name, it->options[0], it->options[1]);
+
+ /* Allocate the private structure area using alloc_private().
+ * Macro defined in comedidev.h - memsets struct fields to 0. */
+ if ((alloc_private(dev, sizeof(struct pci230_private))) < 0) {
+ return -ENOMEM;
+ }
+ spin_lock_init(&devpriv->isr_spinlock);
+ spin_lock_init(&devpriv->res_spinlock);
+ spin_lock_init(&devpriv->ai_stop_spinlock);
+ spin_lock_init(&devpriv->ao_stop_spinlock);
+ /* Find card */
+ for (pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_dev != NULL;
+ pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) {
+ if (it->options[0] || it->options[1]) {
+ /* Match against bus/slot options. */
+ if (it->options[0] != pci_dev->bus->number ||
+ it->options[1] != PCI_SLOT(pci_dev->devfn))
+ continue;
+ }
+ if (pci_dev->vendor != PCI_VENDOR_ID_AMPLICON)
+ continue;
+ if (thisboard->id == PCI_DEVICE_ID_INVALID) {
+ /* The name was specified as "amplc_pci230" which is
+ * used to match any supported device. Replace the
+ * current dev->board_ptr with one that matches the
+ * PCI device ID. */
+ for (i = 0; i < n_pci230_boards; i++) {
+ if (pci_dev->device == pci230_boards[i].id) {
+ if (pci230_boards[i].min_hwver > 0) {
+ /* Check for a '+' model.
+ * First check length of
+ * registers. */
+ if (pci_resource_len(pci_dev, 3)
+ < 32) {
+ /* Not a '+' model. */
+ continue;
+ }
+ /* TODO: temporarily enable the
+ * PCI device and read the
+ * hardware version register.
+ * For now assume it's okay. */
+ }
+ /* Change board_ptr to matched board */
+ dev->board_ptr = &pci230_boards[i];
+ break;
+ }
+ }
+ if (i < n_pci230_boards)
+ break;
+ } else {
+ /* The name was specified as a specific device name.
+ * The current dev->board_ptr is correct. Check
+ * whether it matches the PCI device ID. */
+ if (thisboard->id == pci_dev->device) {
+ /* Check minimum hardware version. */
+ if (thisboard->min_hwver > 0) {
+ /* Looking for a '+' model. First
+ * check length of registers. */
+ if (pci_resource_len(pci_dev, 3) < 32) {
+ /* Not a '+' model. */
+ continue;
+ }
+ /* TODO: temporarily enable the PCI
+ * device and read the hardware version
+ * register. For now, assume it's
+ * okay. */
+ break;
+ } else {
+ break;
+ }
+ }
+ }
+ }
+ if (!pci_dev) {
+ printk("comedi%d: No %s card found\n", dev->minor,
+ thisboard->name);
+ return -EIO;
+ }
+ devpriv->pci_dev = pci_dev;
+
+ /*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+ /* Enable PCI device and reserve I/O spaces. */
+ if (comedi_pci_enable(pci_dev, "amplc_pci230") < 0) {
+ printk("comedi%d: failed to enable PCI device "
+ "and request regions\n", dev->minor);
+ return -EIO;
+ }
+
+ /* Read base addresses of the PCI230's two I/O regions from PCI
+ * configuration register. */
+ iobase1 = pci_resource_start(pci_dev, 2);
+ iobase2 = pci_resource_start(pci_dev, 3);
+
+ printk("comedi%d: %s I/O region 1 0x%04lx I/O region 2 0x%04lx\n",
+ dev->minor, dev->board_name, iobase1, iobase2);
+
+ devpriv->iobase1 = iobase1;
+ dev->iobase = iobase2;
+
+ /* Read bits of DACCON register - only the output range. */
+ devpriv->daccon = inw(dev->iobase + PCI230_DACCON) & PCI230_DAC_OR_MASK;
+
+ /* Read hardware version register and set extended function register
+ * if they exist. */
+ if (pci_resource_len(pci_dev, 3) >= 32) {
+ unsigned short extfunc = 0;
+
+ devpriv->hwver = inw(dev->iobase + PCI230P_HWVER);
+ if (devpriv->hwver < thisboard->min_hwver) {
+ printk("comedi%d: %s - bad hardware version "
+ "- got %u, need %u\n", dev->minor,
+ dev->board_name, devpriv->hwver,
+ thisboard->min_hwver);
+ return -EIO;
+ }
+ if (devpriv->hwver > 0) {
+ if (!thisboard->have_dio) {
+ /* No DIO ports. Route counters' external gates
+ * to the EXTTRIG signal (PCI260+ pin 17).
+ * (Otherwise, they would be routed to DIO
+ * inputs PC0, PC1 and PC2 which don't exist
+ * on PCI260[+].) */
+ extfunc |= PCI230P_EXTFUNC_GAT_EXTTRIG;
+ }
+ if ((thisboard->ao_chans > 0)
+ && (devpriv->hwver >= 2)) {
+ /* Enable DAC FIFO functionality. */
+ extfunc |= PCI230P2_EXTFUNC_DACFIFO;
+ }
+ }
+ outw(extfunc, dev->iobase + PCI230P_EXTFUNC);
+ if ((extfunc & PCI230P2_EXTFUNC_DACFIFO) != 0) {
+ /* Temporarily enable DAC FIFO, reset it and disable
+ * FIFO wraparound. */
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_EN
+ | PCI230P2_DAC_FIFO_RESET,
+ dev->iobase + PCI230_DACCON);
+ /* Clear DAC FIFO channel enable register. */
+ outw(0, dev->iobase + PCI230P2_DACEN);
+ /* Disable DAC FIFO. */
+ outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
+ }
+ }
+
+ /* Disable board's interrupts. */
+ outb(0, devpriv->iobase1 + PCI230_INT_SCE);
+
+ /* Set ADC to a reasonable state. */
+ devpriv->adcg = 0;
+ devpriv->adccon = PCI230_ADC_TRIG_NONE | PCI230_ADC_IM_SE
+ | PCI230_ADC_IR_BIP;
+ outw(1 << 0, dev->iobase + PCI230_ADCEN);
+ outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+ outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
+ dev->iobase + PCI230_ADCCON);
+
+ /* Register the interrupt handler. */
+ irq_hdl = comedi_request_irq(devpriv->pci_dev->irq, pci230_interrupt,
+ IRQF_SHARED, "amplc_pci230", dev);
+ if (irq_hdl < 0) {
+ printk("comedi%d: unable to register irq, "
+ "commands will not be available %d\n", dev->minor,
+ devpriv->pci_dev->irq);
+ } else {
+ dev->irq = devpriv->pci_dev->irq;
+ printk("comedi%d: registered irq %u\n", dev->minor,
+ devpriv->pci_dev->irq);
+ }
+
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND;
+ s->n_chan = thisboard->ai_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &pci230_ai_range;
+ s->insn_read = &pci230_ai_rinsn;
+ s->len_chanlist = 256; /* but there are restrictions. */
+ /* Only register commands if the interrupt handler is installed. */
+ if (irq_hdl == 0) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmd = &pci230_ai_cmd;
+ s->do_cmdtest = &pci230_ai_cmdtest;
+ s->cancel = pci230_ai_cancel;
+ }
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ if (thisboard->ao_chans > 0) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = thisboard->ao_chans;;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = &pci230_ao_range;
+ s->insn_write = &pci230_ao_winsn;
+ s->insn_read = &pci230_ao_rinsn;
+ s->len_chanlist = thisboard->ao_chans;
+ /* Only register commands if the interrupt handler is
+ * installed. */
+ if (irq_hdl == 0) {
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->do_cmd = &pci230_ao_cmd;
+ s->do_cmdtest = &pci230_ao_cmdtest;
+ s->cancel = pci230_ao_cancel;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+ rc = subdev_8255_init(dev, s, NULL,
+ (devpriv->iobase1 + PCI230_PPI_X_BASE));
+ if (rc < 0)
+ return rc;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("comedi%d: attached\n", dev->minor);
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pci230_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: amplc_pci230: remove\n", dev->minor);
+
+ if (dev->subdevices && thisboard->have_dio)
+ /* Clean up dio subdevice. */
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+
+ return 0;
+}
+
+static int get_resources(struct comedi_device * dev, unsigned int res_mask,
+ unsigned char owner)
+{
+ int ok;
+ unsigned int i;
+ unsigned int b;
+ unsigned int claimed;
+ unsigned long irqflags;
+
+ ok = 1;
+ claimed = 0;
+ comedi_spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
+ for (b = 1, i = 0; (i < NUM_RESOURCES)
+ && (res_mask != 0); b <<= 1, i++) {
+ if ((res_mask & b) != 0) {
+ res_mask &= ~b;
+ if (devpriv->res_owner[i] == OWNER_NONE) {
+ devpriv->res_owner[i] = owner;
+ claimed |= b;
+ } else if (devpriv->res_owner[i] != owner) {
+ for (b = 1, i = 0; claimed != 0; b <<= 1, i++) {
+ if ((claimed & b) != 0) {
+ devpriv->res_owner[i]
+ = OWNER_NONE;
+ claimed &= ~b;
+ }
+ }
+ ok = 0;
+ break;
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
+ return ok;
+}
+
+static inline int get_one_resource(struct comedi_device * dev, unsigned int resource,
+ unsigned char owner)
+{
+ return get_resources(dev, (1U << resource), owner);
+}
+
+static void put_resources(struct comedi_device * dev, unsigned int res_mask,
+ unsigned char owner)
+{
+ unsigned int i;
+ unsigned int b;
+ unsigned long irqflags;
+
+ comedi_spin_lock_irqsave(&devpriv->res_spinlock, irqflags);
+ for (b = 1, i = 0; (i < NUM_RESOURCES)
+ && (res_mask != 0); b <<= 1, i++) {
+ if ((res_mask & b) != 0) {
+ res_mask &= ~b;
+ if (devpriv->res_owner[i] == owner) {
+ devpriv->res_owner[i] = OWNER_NONE;
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->res_spinlock, irqflags);
+}
+
+static inline void put_one_resource(struct comedi_device * dev, unsigned int resource,
+ unsigned char owner)
+{
+ put_resources(dev, (1U << resource), owner);
+}
+
+static inline void put_all_resources(struct comedi_device * dev, unsigned char owner)
+{
+ put_resources(dev, (1U << NUM_RESOURCES) - 1, owner);
+}
+
+/*
+ * COMEDI_SUBD_AI instruction;
+ */
+static int pci230_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int n, i;
+ unsigned int chan, range, aref;
+ unsigned int gainshift;
+ unsigned int status;
+ unsigned short adccon, adcen;
+
+ /* Unpack channel and range. */
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ aref = CR_AREF(insn->chanspec);
+ if (aref == AREF_DIFF) {
+ /* Differential. */
+ if (chan >= s->n_chan / 2) {
+ DPRINTK("comedi%d: amplc_pci230: ai_rinsn: "
+ "differential channel number out of range "
+ "0 to %u\n", dev->minor, (s->n_chan / 2) - 1);
+ return -EINVAL;
+ }
+ }
+
+ /* Use Z2-CT2 as a conversion trigger instead of the built-in
+ * software trigger, as otherwise triggering of differential channels
+ * doesn't work properly for some versions of PCI230/260. Also set
+ * FIFO mode because the ADC busy bit only works for software triggers.
+ */
+ adccon = PCI230_ADC_TRIG_Z2CT2 | PCI230_ADC_FIFO_EN;
+ /* Set Z2-CT2 output low to avoid any false triggers. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE0);
+ devpriv->ai_bipolar = pci230_ai_bipolar[range];
+ if (aref == AREF_DIFF) {
+ /* Differential. */
+ gainshift = chan * 2;
+ if (devpriv->hwver == 0) {
+ /* Original PCI230/260 expects both inputs of the
+ * differential channel to be enabled. */
+ adcen = 3 << gainshift;
+ } else {
+ /* PCI230+/260+ expects only one input of the
+ * differential channel to be enabled. */
+ adcen = 1 << gainshift;
+ }
+ adccon |= PCI230_ADC_IM_DIF;
+ } else {
+ /* Single ended. */
+ adcen = 1 << chan;
+ gainshift = chan & ~1;
+ adccon |= PCI230_ADC_IM_SE;
+ }
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
+ | (pci230_ai_gain[range] << gainshift);
+ if (devpriv->ai_bipolar) {
+ adccon |= PCI230_ADC_IR_BIP;
+ } else {
+ adccon |= PCI230_ADC_IR_UNI;
+ }
+
+ /* Enable only this channel in the scan list - otherwise by default
+ * we'll get one sample from each channel. */
+ outw(adcen, dev->iobase + PCI230_ADCEN);
+
+ /* Set gain for channel. */
+ outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+
+ /* Specify uni/bip, se/diff, conversion source, and reset FIFO. */
+ devpriv->adccon = adccon;
+ outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+ /* Convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* Trigger conversion by toggling Z2-CT2 output (finish with
+ * output high). */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE0);
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE1);
+
+#define TIMEOUT 100
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ status = inw(dev->iobase + PCI230_ADCCON);
+ if (!(status & PCI230_ADC_FIFO_EMPTY))
+ break;
+ comedi_udelay(1);
+ }
+ if (i == TIMEOUT) {
+ /* rt_printk() should be used instead of printk()
+ * whenever the code can be called from real-time. */
+ rt_printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ data[n] = pci230_ai_read(dev);
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+/*
+ * COMEDI_SUBD_AO instructions;
+ */
+static int pci230_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan, range;
+
+ /* Unpack channel and range. */
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ /* Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale */
+ devpriv->ao_bipolar = pci230_ao_bipolar[range];
+ outw(range, dev->iobase + PCI230_DACCON);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* Write value to DAC and store it. */
+ pci230_ao_write_nofifo(dev, data[i], chan);
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int pci230_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int pci230_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* Step 1: make sure trigger sources are trivially valid.
+ * "invalid source" returned by comedilib to user mode process
+ * if this fails. */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ if ((thisboard->min_hwver > 0) && (devpriv->hwver >= 2)) {
+ /*
+ * For PCI230+ hardware version 2 onwards, allow external
+ * trigger from EXTTRIG/EXTCONVCLK input (PCI230+ pin 25).
+ *
+ * FIXME: The permitted scan_begin_src values shouldn't depend
+ * on devpriv->hwver (the detected card's actual hardware
+ * version). They should only depend on thisboard->min_hwver
+ * (the static capabilities of the configured card). To fix
+ * it, a new card model, e.g. "pci230+2" would have to be
+ * defined with min_hwver set to 2. It doesn't seem worth it
+ * for this alone. At the moment, please consider
+ * scan_begin_src==TRIG_EXT support to be a bonus rather than a
+ * guarantee!
+ */
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
+ } else {
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_INT;
+ }
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* Step 2: make sure trigger sources are unique and mutually compatible
+ * "source conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* Step 3: make sure arguments are trivially compatible.
+ * "invalid argument" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED_AO 8000 /* 8000 ns => 125 kHz */
+#define MIN_SPEED_AO 4294967295u /* 4294967295ns = 4.29s */
+ /*- Comedi limit due to unsigned int cmd. Driver limit
+ * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
+ * clock) = 65.536s */
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ if (cmd->scan_begin_arg < MAX_SPEED_AO) {
+ cmd->scan_begin_arg = MAX_SPEED_AO;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED_AO) {
+ cmd->scan_begin_arg = MIN_SPEED_AO;
+ err++;
+ }
+ break;
+ case TRIG_EXT:
+ /* External trigger - for PCI230+ hardware version 2 onwards. */
+ /* Trigger number must be 0. */
+ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flags allowed are CR_EDGE and CR_INVERT. The
+ * CR_EDGE flag is ignored. */
+ if ((cmd->scan_begin_arg
+ & (CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT))) !=
+ 0) {
+ cmd->scan_begin_arg =
+ COMBINE(cmd->scan_begin_arg, 0,
+ CR_FLAGS_MASK & ~(CR_EDGE | CR_INVERT));
+ err++;
+ }
+ break;
+ default:
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ break;
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* Step 4: fix up any arguments.
+ * "argument conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ /* Step 5: check channel list if it exists. */
+
+ if (cmd->chanlist && cmd->chanlist_len > 0) {
+ enum {
+ seq_err = (1 << 0),
+ range_err = (1 << 1)
+ };
+ unsigned int errors;
+ unsigned int n;
+ unsigned int chan, prev_chan;
+ unsigned int range, first_range;
+
+ prev_chan = CR_CHAN(cmd->chanlist[0]);
+ first_range = CR_RANGE(cmd->chanlist[0]);
+ errors = 0;
+ for (n = 1; n < cmd->chanlist_len; n++) {
+ chan = CR_CHAN(cmd->chanlist[n]);
+ range = CR_RANGE(cmd->chanlist[n]);
+ /* Channel numbers must strictly increase. */
+ if (chan < prev_chan) {
+ errors |= seq_err;
+ }
+ /* Ranges must be the same. */
+ if (range != first_range) {
+ errors |= range_err;
+ }
+ prev_chan = chan;
+ }
+ if (errors != 0) {
+ err++;
+ if ((errors & seq_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
+ "channel numbers must increase\n",
+ dev->minor);
+ }
+ if ((errors & range_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ao_cmdtest: "
+ "channels must have the same range\n",
+ dev->minor);
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int pci230_ao_inttrig_scan_begin(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int trig_num)
+{
+ unsigned long irqflags;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
+ if (test_bit(AO_CMD_STARTED, &devpriv->state)) {
+ /* Perform scan. */
+ if (devpriv->hwver < 2) {
+ /* Not using DAC FIFO. */
+ comedi_spin_unlock_irqrestore(&devpriv->
+ ao_stop_spinlock, irqflags);
+ pci230_handle_ao_nofifo(dev, s);
+ comedi_event(dev, s);
+ } else {
+ /* Using DAC FIFO. */
+ /* Read DACSWTRIG register to trigger conversion. */
+ inw(dev->iobase + PCI230P2_DACSWTRIG);
+ comedi_spin_unlock_irqrestore(&devpriv->
+ ao_stop_spinlock, irqflags);
+ }
+ /* Delay. Should driver be responsible for this? */
+ /* XXX TODO: See if DAC busy bit can be used. */
+ comedi_udelay(8);
+ }
+
+ return 1;
+}
+
+static void pci230_ao_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned long irqflags;
+
+ set_bit(AO_CMD_STARTED, &devpriv->state);
+ if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
+ /* An empty acquisition! */
+ async->events |= COMEDI_CB_EOA;
+ pci230_ao_stop(dev, s);
+ comedi_event(dev, s);
+ } else {
+ if (devpriv->hwver >= 2) {
+ /* Using DAC FIFO. */
+ unsigned short scantrig;
+ int run;
+
+ /* Preload FIFO data. */
+ run = pci230_handle_ao_fifo(dev, s);
+ comedi_event(dev, s);
+ if (!run) {
+ /* Stopped. */
+ return;
+ }
+ /* Set scan trigger source. */
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ scantrig = PCI230P2_DAC_TRIG_Z2CT1;
+ break;
+ case TRIG_EXT:
+ /* Trigger on EXTTRIG/EXTCONVCLK pin. */
+ if ((cmd->scan_begin_arg & CR_INVERT) == 0) {
+ /* +ve edge */
+ scantrig = PCI230P2_DAC_TRIG_EXTP;
+ } else {
+ /* -ve edge */
+ scantrig = PCI230P2_DAC_TRIG_EXTN;
+ }
+ break;
+ case TRIG_INT:
+ scantrig = PCI230P2_DAC_TRIG_SW;
+ break;
+ default:
+ /* Shouldn't get here. */
+ scantrig = PCI230P2_DAC_TRIG_NONE;
+ break;
+ }
+ devpriv->daccon = (devpriv->daccon
+ & ~PCI230P2_DAC_TRIG_MASK) | scantrig;
+ outw(devpriv->daccon, dev->iobase + PCI230_DACCON);
+
+ }
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ if (devpriv->hwver < 2) {
+ /* Not using DAC FIFO. */
+ /* Enable CT1 timer interrupt. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock,
+ irqflags);
+ devpriv->int_en |= PCI230_INT_ZCLK_CT1;
+ devpriv->ier |= PCI230_INT_ZCLK_CT1;
+ outb(devpriv->ier,
+ devpriv->iobase1 + PCI230_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->
+ isr_spinlock, irqflags);
+ }
+ /* Set CT1 gate high to start counting. */
+ outb(GAT_CONFIG(1, GAT_VCC),
+ devpriv->iobase1 + PCI230_ZGAT_SCE);
+ break;
+ case TRIG_INT:
+ async->inttrig = pci230_ao_inttrig_scan_begin;
+ break;
+ }
+ if (devpriv->hwver >= 2) {
+ /* Using DAC FIFO. Enable DAC FIFO interrupt. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock,
+ irqflags);
+ devpriv->int_en |= PCI230P2_INT_DAC;
+ devpriv->ier |= PCI230P2_INT_DAC;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock,
+ irqflags);
+ }
+ }
+}
+
+static int pci230_ao_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ if (trig_num != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULLFUNC;
+ pci230_ao_start(dev, s);
+
+ return 1;
+}
+
+static int pci230_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned short daccon;
+ unsigned int range;
+
+ /* Get the command. */
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Claim Z2-CT1. */
+ if (!get_one_resource(dev, RES_Z2CT1, OWNER_AOCMD)) {
+ return -EBUSY;
+ }
+ }
+
+ /* Get number of scans required. */
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ao_scan_count = cmd->stop_arg;
+ devpriv->ao_continuous = 0;
+ } else {
+ /* TRIG_NONE, user calls cancel. */
+ devpriv->ao_scan_count = 0;
+ devpriv->ao_continuous = 1;
+ }
+
+ /* Set range - see analogue output range table; 0 => unipolar 10V,
+ * 1 => bipolar +/-10V range scale */
+ range = CR_RANGE(cmd->chanlist[0]);
+ devpriv->ao_bipolar = pci230_ao_bipolar[range];
+ daccon = devpriv->ao_bipolar ? PCI230_DAC_OR_BIP : PCI230_DAC_OR_UNI;
+ /* Use DAC FIFO for hardware version 2 onwards. */
+ if (devpriv->hwver >= 2) {
+ unsigned short dacen;
+ unsigned int i;
+
+ dacen = 0;
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ dacen |= 1 << CR_CHAN(cmd->chanlist[i]);
+ }
+ /* Set channel scan list. */
+ outw(dacen, dev->iobase + PCI230P2_DACEN);
+ /*
+ * Enable DAC FIFO.
+ * Set DAC scan source to 'none'.
+ * Set DAC FIFO interrupt trigger level to 'not half full'.
+ * Reset DAC FIFO and clear underrun.
+ *
+ * N.B. DAC FIFO interrupts are currently disabled.
+ */
+ daccon |= PCI230P2_DAC_FIFO_EN | PCI230P2_DAC_FIFO_RESET
+ | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR
+ | PCI230P2_DAC_TRIG_NONE | PCI230P2_DAC_INT_FIFO_NHALF;
+ }
+
+ /* Set DACCON. */
+ outw(daccon, dev->iobase + PCI230_DACCON);
+ /* Preserve most of DACCON apart from write-only, transient bits. */
+ devpriv->daccon = daccon
+ & ~(PCI230P2_DAC_FIFO_RESET | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR);
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Set the counter timer 1 to the specified scan frequency. */
+ /* cmd->scan_begin_arg is sampling period in ns */
+ /* gate it off for now. */
+ outb(GAT_CONFIG(1, GAT_GND),
+ devpriv->iobase1 + PCI230_ZGAT_SCE);
+ pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
+ cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ }
+
+ /* N.B. cmd->start_src == TRIG_INT */
+ s->async->inttrig = pci230_ao_inttrig_start;
+
+ return 0;
+}
+
+static int pci230_ai_check_scan_period(struct comedi_cmd * cmd)
+{
+ unsigned int min_scan_period, chanlist_len;
+ int err = 0;
+
+ chanlist_len = cmd->chanlist_len;
+ if (cmd->chanlist_len == 0) {
+ chanlist_len = 1;
+ }
+ min_scan_period = chanlist_len * cmd->convert_arg;
+ if ((min_scan_period < chanlist_len)
+ || (min_scan_period < cmd->convert_arg)) {
+ /* Arithmetic overflow. */
+ min_scan_period = UINT_MAX;
+ err++;
+ }
+ if (cmd->scan_begin_arg < min_scan_period) {
+ cmd->scan_begin_arg = min_scan_period;
+ err++;
+ }
+
+ return !err;
+}
+
+static int pci230_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4,5 or 0, depending on which tests
+ * the command passes. */
+
+ /* Step 1: make sure trigger sources are trivially valid.
+ * "invalid source" returned by comedilib to user mode process
+ * if this fails. */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ /* Unfortunately, we cannot trigger a scan off an external source
+ * on the PCI260 board, since it uses the PPIC0 (DIO) input, which
+ * isn't present on the PCI260. For PCI260+ we can use the
+ * EXTTRIG/EXTCONVCLK input on pin 17 instead. */
+ if ((thisboard->have_dio) || (thisboard->min_hwver > 0)) {
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT
+ | TRIG_EXT;
+ } else {
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_INT;
+ }
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_INT | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* Step 2: make sure trigger sources are unique and mutually compatible
+ * "source conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ /* If scan_begin_src is not TRIG_FOLLOW, then a monostable will be
+ * set up to generate a fixed number of timed conversion pulses. */
+ if ((cmd->scan_begin_src != TRIG_FOLLOW)
+ && (cmd->convert_src != TRIG_TIMER))
+ err++;
+
+ if (err)
+ return 2;
+
+ /* Step 3: make sure arguments are trivially compatible.
+ * "invalid argument" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED_AI_SE 3200 /* PCI230 SE: 3200 ns => 312.5 kHz */
+#define MAX_SPEED_AI_DIFF 8000 /* PCI230 DIFF: 8000 ns => 125 kHz */
+#define MAX_SPEED_AI_PLUS 4000 /* PCI230+: 4000 ns => 250 kHz */
+#define MIN_SPEED_AI 4294967295u /* 4294967295ns = 4.29s */
+ /*- Comedi limit due to unsigned int cmd. Driver limit
+ * = 2^16 (16bit * counter) * 1000000ns (1kHz onboard
+ * clock) = 65.536s */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ unsigned int max_speed_ai;
+
+ if (devpriv->hwver == 0) {
+ /* PCI230 or PCI260. Max speed depends whether
+ * single-ended or pseudo-differential. */
+ if (cmd->chanlist && (cmd->chanlist_len > 0)) {
+ /* Peek analogue reference of first channel. */
+ if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
+ max_speed_ai = MAX_SPEED_AI_DIFF;
+ } else {
+ max_speed_ai = MAX_SPEED_AI_SE;
+ }
+ } else {
+ /* No channel list. Assume single-ended. */
+ max_speed_ai = MAX_SPEED_AI_SE;
+ }
+ } else {
+ /* PCI230+ or PCI260+. */
+ max_speed_ai = MAX_SPEED_AI_PLUS;
+ }
+
+ if (cmd->convert_arg < max_speed_ai) {
+ cmd->convert_arg = max_speed_ai;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED_AI) {
+ cmd->convert_arg = MIN_SPEED_AI;
+ err++;
+ }
+ } else if (cmd->convert_src == TRIG_EXT) {
+ /*
+ * external trigger
+ *
+ * convert_arg == (CR_EDGE | 0)
+ * => trigger on +ve edge.
+ * convert_arg == (CR_EDGE | CR_INVERT | 0)
+ * => trigger on -ve edge.
+ */
+ if ((cmd->convert_arg & CR_FLAGS_MASK) != 0) {
+ /* Trigger number must be 0. */
+ if ((cmd->convert_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->convert_arg = COMBINE(cmd->convert_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flags allowed are CR_INVERT and CR_EDGE.
+ * CR_EDGE is required. */
+ if ((cmd->convert_arg & (CR_FLAGS_MASK & ~CR_INVERT))
+ != CR_EDGE) {
+ /* Set CR_EDGE, preserve CR_INVERT. */
+ cmd->convert_arg =
+ COMBINE(cmd->start_arg, (CR_EDGE | 0),
+ CR_FLAGS_MASK & ~CR_INVERT);
+ err++;
+ }
+ } else {
+ /* Backwards compatibility with previous versions. */
+ /* convert_arg == 0 => trigger on -ve edge. */
+ /* convert_arg == 1 => trigger on +ve edge. */
+ if (cmd->convert_arg > 1) {
+ /* Default to trigger on +ve edge. */
+ cmd->convert_arg = 1;
+ err++;
+ }
+ }
+ } else {
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ /* external "trigger" to begin each scan
+ * scan_begin_arg==0 => use PPC0 input -> gate of CT0 -> gate
+ * of CT2 (sample convert trigger is CT2) */
+ if ((cmd->scan_begin_arg & ~CR_FLAGS_MASK) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ ~CR_FLAGS_MASK);
+ err++;
+ }
+ /* The only flag allowed is CR_EDGE, which is ignored. */
+ if ((cmd->scan_begin_arg & CR_FLAGS_MASK & ~CR_EDGE) != 0) {
+ cmd->scan_begin_arg = COMBINE(cmd->scan_begin_arg, 0,
+ CR_FLAGS_MASK & ~CR_EDGE);
+ err++;
+ }
+ } else if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* N.B. cmd->convert_arg is also TRIG_TIMER */
+ if (!pci230_ai_check_scan_period(cmd)) {
+ err++;
+ }
+ } else {
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* Step 4: fix up any arguments.
+ * "argument conflict" returned by comedilib to user mode process
+ * if this fails. */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ pci230_ns_to_single_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* N.B. cmd->convert_arg is also TRIG_TIMER */
+ tmp = cmd->scan_begin_arg;
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (!pci230_ai_check_scan_period(cmd)) {
+ /* Was below minimum required. Round up. */
+ pci230_ns_to_single_timer(&cmd->scan_begin_arg,
+ TRIG_ROUND_UP);
+ pci230_ai_check_scan_period(cmd);
+ }
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ /* Step 5: check channel list if it exists. */
+
+ if (cmd->chanlist && cmd->chanlist_len > 0) {
+ enum {
+ seq_err = 1 << 0,
+ rangepair_err = 1 << 1,
+ polarity_err = 1 << 2,
+ aref_err = 1 << 3,
+ diffchan_err = 1 << 4,
+ buggy_chan0_err = 1 << 5
+ };
+ unsigned int errors;
+ unsigned int chan, prev_chan;
+ unsigned int range, prev_range;
+ unsigned int polarity, prev_polarity;
+ unsigned int aref, prev_aref;
+ unsigned int subseq_len;
+ unsigned int n;
+
+ subseq_len = 0;
+ errors = 0;
+ prev_chan = prev_aref = prev_range = prev_polarity = 0;
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ chan = CR_CHAN(cmd->chanlist[n]);
+ range = CR_RANGE(cmd->chanlist[n]);
+ aref = CR_AREF(cmd->chanlist[n]);
+ polarity = pci230_ai_bipolar[range];
+ /* Only the first half of the channels are available if
+ * differential. (These are remapped in software. In
+ * hardware, only the even channels are available.) */
+ if ((aref == AREF_DIFF)
+ && (chan >= (s->n_chan / 2))) {
+ errors |= diffchan_err;
+ }
+ if (n > 0) {
+ /* Channel numbers must strictly increase or
+ * subsequence must repeat exactly. */
+ if ((chan <= prev_chan)
+ && (subseq_len == 0)) {
+ subseq_len = n;
+ }
+ if ((subseq_len > 0)
+ && (cmd->chanlist[n] !=
+ cmd->chanlist[n %
+ subseq_len])) {
+ errors |= seq_err;
+ }
+ /* Channels must have same AREF. */
+ if (aref != prev_aref) {
+ errors |= aref_err;
+ }
+ /* Channel ranges must have same polarity. */
+ if (polarity != prev_polarity) {
+ errors |= polarity_err;
+ }
+ /* Single-ended channel pairs must have same
+ * range. */
+ if ((aref != AREF_DIFF)
+ && (((chan ^ prev_chan) & ~1) == 0)
+ && (range != prev_range)) {
+ errors |= rangepair_err;
+ }
+ }
+ prev_chan = chan;
+ prev_range = range;
+ prev_aref = aref;
+ prev_polarity = polarity;
+ }
+ if (subseq_len == 0) {
+ /* Subsequence is whole sequence. */
+ subseq_len = n;
+ }
+ /* If channel list is a repeating subsequence, need a whole
+ * number of repeats. */
+ if ((n % subseq_len) != 0) {
+ errors |= seq_err;
+ }
+ if ((devpriv->hwver > 0) && (devpriv->hwver < 4)) {
+ /*
+ * Buggy PCI230+ or PCI260+ requires channel 0 to be
+ * (first) in the sequence if the sequence contains
+ * more than one channel. Hardware versions 1 and 2
+ * have the bug. There is no hardware version 3.
+ *
+ * Actually, there are two firmwares that report
+ * themselves as hardware version 1 (the boards
+ * have different ADC chips with slightly different
+ * timing requirements, which was supposed to be
+ * invisible to software). The first one doesn't
+ * seem to have the bug, but the second one
+ * does, and we can't tell them apart!
+ */
+ if ((subseq_len > 1)
+ && (CR_CHAN(cmd->chanlist[0]) != 0)) {
+ errors |= buggy_chan0_err;
+ }
+ }
+ if (errors != 0) {
+ err++;
+ if ((errors & seq_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "channel numbers must increase or "
+ "sequence must repeat exactly\n",
+ dev->minor);
+ }
+ if ((errors & rangepair_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "single-ended channel pairs must "
+ "have the same range\n", dev->minor);
+ }
+ if ((errors & polarity_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "channel sequence ranges must be all "
+ "bipolar or all unipolar\n",
+ dev->minor);
+ }
+ if ((errors & aref_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "channel sequence analogue references "
+ "must be all the same (single-ended "
+ "or differential)\n", dev->minor);
+ }
+ if ((errors & diffchan_err) != 0) {
+ DPRINTK("comedi%d: amplc_pci230: ai_cmdtest: "
+ "differential channel number out of "
+ "range 0 to %u\n", dev->minor,
+ (s->n_chan / 2) - 1);
+ }
+ if ((errors & buggy_chan0_err) != 0) {
+ /* Use printk instead of DPRINTK here. */
+ printk("comedi: comedi%d: amplc_pci230: "
+ "ai_cmdtest: Buggy PCI230+/260+ "
+ "h/w version %u requires first channel "
+ "of multi-channel sequence to be 0 "
+ "(corrected in h/w version 4)\n",
+ dev->minor, devpriv->hwver);
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static void pci230_ai_update_fifo_trigger_level(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int scanlen = cmd->scan_end_arg;
+ unsigned int wake;
+ unsigned short triglev;
+ unsigned short adccon;
+
+ if ((cmd->flags & TRIG_WAKE_EOS) != 0) {
+ /* Wake at end of scan. */
+ wake = scanlen - devpriv->ai_scan_pos;
+ } else {
+ if (devpriv->ai_continuous
+ || (devpriv->ai_scan_count
+ >= PCI230_ADC_FIFOLEVEL_HALFFULL)
+ || (scanlen >= PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+ wake = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else {
+ wake = (devpriv->ai_scan_count * scanlen)
+ - devpriv->ai_scan_pos;
+ }
+ }
+ if (wake >= PCI230_ADC_FIFOLEVEL_HALFFULL) {
+ triglev = PCI230_ADC_INT_FIFO_HALF;
+ } else {
+ if ((wake > 1) && (devpriv->hwver > 0)) {
+ /* PCI230+/260+ programmable FIFO interrupt level. */
+ if (devpriv->adcfifothresh != wake) {
+ devpriv->adcfifothresh = wake;
+ outw(wake, dev->iobase + PCI230P_ADCFFTH);
+ }
+ triglev = PCI230P_ADC_INT_FIFO_THRESH;
+ } else {
+ triglev = PCI230_ADC_INT_FIFO_NEMPTY;
+ }
+ }
+ adccon = (devpriv->adccon & ~PCI230_ADC_INT_FIFO_MASK) | triglev;
+ if (adccon != devpriv->adccon) {
+ devpriv->adccon = adccon;
+ outw(adccon, dev->iobase + PCI230_ADCCON);
+ }
+}
+
+static int pci230_ai_inttrig_convert(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ unsigned long irqflags;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+ if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
+ unsigned int delayus;
+
+ /* Trigger conversion by toggling Z2-CT2 output. Finish
+ * with output high. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE0);
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2,
+ I8254_MODE1);
+ /* Delay. Should driver be responsible for this? An
+ * alternative would be to wait until conversion is complete,
+ * but we can't tell when it's complete because the ADC busy
+ * bit has a different meaning when FIFO enabled (and when
+ * FIFO not enabled, it only works for software triggers). */
+ if (((devpriv->adccon & PCI230_ADC_IM_MASK)
+ == PCI230_ADC_IM_DIF)
+ && (devpriv->hwver == 0)) {
+ /* PCI230/260 in differential mode */
+ delayus = 8;
+ } else {
+ /* single-ended or PCI230+/260+ */
+ delayus = 4;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
+ irqflags);
+ comedi_udelay(delayus);
+ } else {
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock,
+ irqflags);
+ }
+
+ return 1;
+}
+
+static int pci230_ai_inttrig_scan_begin(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int trig_num)
+{
+ unsigned long irqflags;
+ unsigned char zgat;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+ if (test_bit(AI_CMD_STARTED, &devpriv->state)) {
+ /* Trigger scan by waggling CT0 gate source. */
+ zgat = GAT_CONFIG(0, GAT_GND);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
+
+ return 1;
+}
+
+static void pci230_ai_start(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long irqflags;
+ unsigned short conv;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ set_bit(AI_CMD_STARTED, &devpriv->state);
+ if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+ /* An empty acquisition! */
+ async->events |= COMEDI_CB_EOA;
+ pci230_ai_stop(dev, s);
+ comedi_event(dev, s);
+ } else {
+ /* Enable ADC FIFO trigger level interrupt. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ devpriv->int_en |= PCI230_INT_ADC;
+ devpriv->ier |= PCI230_INT_ADC;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ /* Update conversion trigger source which is currently set
+ * to CT2 output, which is currently stuck high. */
+ switch (cmd->convert_src) {
+ default:
+ conv = PCI230_ADC_TRIG_NONE;
+ break;
+ case TRIG_TIMER:
+ /* Using CT2 output. */
+ conv = PCI230_ADC_TRIG_Z2CT2;
+ break;
+ case TRIG_EXT:
+ if ((cmd->convert_arg & CR_EDGE) != 0) {
+ if ((cmd->convert_arg & CR_INVERT) == 0) {
+ /* Trigger on +ve edge. */
+ conv = PCI230_ADC_TRIG_EXTP;
+ } else {
+ /* Trigger on -ve edge. */
+ conv = PCI230_ADC_TRIG_EXTN;
+ }
+ } else {
+ /* Backwards compatibility. */
+ if (cmd->convert_arg != 0) {
+ /* Trigger on +ve edge. */
+ conv = PCI230_ADC_TRIG_EXTP;
+ } else {
+ /* Trigger on -ve edge. */
+ conv = PCI230_ADC_TRIG_EXTN;
+ }
+ }
+ break;
+ case TRIG_INT:
+ /* Use CT2 output for software trigger due to problems
+ * in differential mode on PCI230/260. */
+ conv = PCI230_ADC_TRIG_Z2CT2;
+ break;
+ }
+ devpriv->adccon = (devpriv->adccon & ~PCI230_ADC_TRIG_MASK)
+ | conv;
+ outw(devpriv->adccon, dev->iobase + PCI230_ADCCON);
+ if (cmd->convert_src == TRIG_INT) {
+ async->inttrig = pci230_ai_inttrig_convert;
+ }
+ /* Update FIFO interrupt trigger level, which is currently
+ * set to "full". */
+ pci230_ai_update_fifo_trigger_level(dev, s);
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* Update timer gates. */
+ unsigned char zgat;
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Conversion timer CT2 needs to be gated by
+ * inverted output of monostable CT2. */
+ zgat = GAT_CONFIG(2, GAT_NOUTNM2);
+ } else {
+ /* Conversion timer CT2 needs to be gated on
+ * continuously. */
+ zgat = GAT_CONFIG(2, GAT_VCC);
+ }
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Set monostable CT0 trigger source. */
+ switch (cmd->scan_begin_src) {
+ default:
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ break;
+ case TRIG_EXT:
+ /*
+ * For CT0 on PCI230, the external
+ * trigger (gate) signal comes from
+ * PPC0, which is channel 16 of the DIO
+ * subdevice. The application needs to
+ * configure this as an input in order
+ * to use it as an external scan
+ * trigger.
+ */
+ zgat = GAT_CONFIG(0, GAT_EXT);
+ break;
+ case TRIG_TIMER:
+ /*
+ * Monostable CT0 triggered by rising
+ * edge on inverted output of CT1
+ * (falling edge on CT1).
+ */
+ zgat = GAT_CONFIG(0, GAT_NOUTNM2);
+ break;
+ case TRIG_INT:
+ /*
+ * Monostable CT0 is triggered by
+ * inttrig function waggling the CT0
+ * gate source.
+ */
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ break;
+ }
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ /* Scan period timer CT1 needs to be
+ * gated on to start counting. */
+ zgat = GAT_CONFIG(1, GAT_VCC);
+ outb(zgat, devpriv->iobase1
+ + PCI230_ZGAT_SCE);
+ break;
+ case TRIG_INT:
+ async->inttrig =
+ pci230_ai_inttrig_scan_begin;
+ break;
+ }
+ }
+ } else if (cmd->convert_src != TRIG_INT) {
+ /* No longer need Z2-CT2. */
+ put_one_resource(dev, RES_Z2CT2, OWNER_AICMD);
+ }
+ }
+}
+
+static int pci230_ai_inttrig_start(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ if (trig_num != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULLFUNC;
+ pci230_ai_start(dev, s);
+
+ return 1;
+}
+
+static int pci230_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int i, chan, range, diff;
+ unsigned int res_mask;
+ unsigned short adccon, adcen;
+ unsigned char zgat;
+
+ /* Get the command. */
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ /*
+ * Determine which shared resources are needed.
+ */
+ res_mask = 0;
+ /* Need Z2-CT2 to supply a conversion trigger source at a high
+ * logic level, even if not doing timed conversions. */
+ res_mask |= (1U << RES_Z2CT2);
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Using Z2-CT0 monostable to gate Z2-CT2 conversion timer */
+ res_mask |= (1U << RES_Z2CT0);
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Using Z2-CT1 for scan frequency */
+ res_mask |= (1U << RES_Z2CT1);
+ }
+ }
+ /* Claim resources. */
+ if (!get_resources(dev, res_mask, OWNER_AICMD)) {
+ return -EBUSY;
+ }
+
+ /* Get number of scans required. */
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scan_count = cmd->stop_arg;
+ devpriv->ai_continuous = 0;
+ } else {
+ /* TRIG_NONE, user calls cancel. */
+ devpriv->ai_scan_count = 0;
+ devpriv->ai_continuous = 1;
+ }
+ devpriv->ai_scan_pos = 0; /* Position within scan. */
+
+ /* Steps;
+ * - Set channel scan list.
+ * - Set channel gains.
+ * - Enable and reset FIFO, specify uni/bip, se/diff, and set
+ * start conversion source to point to something at a high logic
+ * level (we use the output of counter/timer 2 for this purpose.
+ * - PAUSE to allow things to settle down.
+ * - Reset the FIFO again because it needs resetting twice and there
+ * may have been a false conversion trigger on some versions of
+ * PCI230/260 due to the start conversion source being set to a
+ * high logic level.
+ * - Enable ADC FIFO level interrupt.
+ * - Set actual conversion trigger source and FIFO interrupt trigger
+ * level.
+ * - If convert_src is TRIG_TIMER, set up the timers.
+ */
+
+ adccon = PCI230_ADC_FIFO_EN;
+ adcen = 0;
+
+ if (CR_AREF(cmd->chanlist[0]) == AREF_DIFF) {
+ /* Differential - all channels must be differential. */
+ diff = 1;
+ adccon |= PCI230_ADC_IM_DIF;
+ } else {
+ /* Single ended - all channels must be single-ended. */
+ diff = 0;
+ adccon |= PCI230_ADC_IM_SE;
+ }
+
+ range = CR_RANGE(cmd->chanlist[0]);
+ devpriv->ai_bipolar = pci230_ai_bipolar[range];
+ if (devpriv->ai_bipolar) {
+ adccon |= PCI230_ADC_IR_BIP;
+ } else {
+ adccon |= PCI230_ADC_IR_UNI;
+ }
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int gainshift;
+
+ chan = CR_CHAN(cmd->chanlist[i]);
+ range = CR_RANGE(cmd->chanlist[i]);
+ if (diff) {
+ gainshift = 2 * chan;
+ if (devpriv->hwver == 0) {
+ /* Original PCI230/260 expects both inputs of
+ * the differential channel to be enabled. */
+ adcen |= 3 << gainshift;
+ } else {
+ /* PCI230+/260+ expects only one input of the
+ * differential channel to be enabled. */
+ adcen |= 1 << gainshift;
+ }
+ } else {
+ gainshift = (chan & ~1);
+ adcen |= 1 << chan;
+ }
+ devpriv->adcg = (devpriv->adcg & ~(3 << gainshift))
+ | (pci230_ai_gain[range] << gainshift);
+ }
+
+ /* Set channel scan list. */
+ outw(adcen, dev->iobase + PCI230_ADCEN);
+
+ /* Set channel gains. */
+ outw(devpriv->adcg, dev->iobase + PCI230_ADCG);
+
+ /* Set counter/timer 2 output high for use as the initial start
+ * conversion source. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, 2, I8254_MODE1);
+
+ /* Temporarily use CT2 output as conversion trigger source and
+ * temporarily set FIFO interrupt trigger level to 'full'. */
+ adccon |= PCI230_ADC_INT_FIFO_FULL | PCI230_ADC_TRIG_Z2CT2;
+
+ /* Enable and reset FIFO, specify FIFO trigger level full, specify
+ * uni/bip, se/diff, and temporarily set the start conversion source
+ * to CT2 output. Note that CT2 output is currently high, and this
+ * will produce a false conversion trigger on some versions of the
+ * PCI230/260, but that will be dealt with later. */
+ devpriv->adccon = adccon;
+ outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+ /* Delay */
+ /* Failure to include this will result in the first few channels'-worth
+ * of data being corrupt, normally manifesting itself by large negative
+ * voltages. It seems the board needs time to settle between the first
+ * FIFO reset (above) and the second FIFO reset (below). Setting the
+ * channel gains and scan list _before_ the first FIFO reset also
+ * helps, though only slightly. */
+ comedi_udelay(25);
+
+ /* Reset FIFO again. */
+ outw(adccon | PCI230_ADC_FIFO_RESET, dev->iobase + PCI230_ADCCON);
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* Set up CT2 as conversion timer, but gate it off for now.
+ * Note, counter/timer output 2 can be monitored on the
+ * connector: PCI230 pin 21, PCI260 pin 18. */
+ zgat = GAT_CONFIG(2, GAT_GND);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ /* Set counter/timer 2 to the specified conversion period. */
+ pci230_ct_setup_ns_mode(dev, 2, I8254_MODE3, cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /*
+ * Set up monostable on CT0 output for scan timing. A
+ * rising edge on the trigger (gate) input of CT0 will
+ * trigger the monostable, causing its output to go low
+ * for the configured period. The period depends on
+ * the conversion period and the number of conversions
+ * in the scan.
+ *
+ * Set the trigger high before setting up the
+ * monostable to stop it triggering. The trigger
+ * source will be changed later.
+ */
+ zgat = GAT_CONFIG(0, GAT_VCC);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ pci230_ct_setup_ns_mode(dev, 0, I8254_MODE1,
+ ((uint64_t) cmd->convert_arg
+ * cmd->scan_end_arg), TRIG_ROUND_UP);
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /*
+ * Monostable on CT0 will be triggered by
+ * output of CT1 at configured scan frequency.
+ *
+ * Set up CT1 but gate it off for now.
+ */
+ zgat = GAT_CONFIG(1, GAT_GND);
+ outb(zgat, devpriv->iobase1 + PCI230_ZGAT_SCE);
+ pci230_ct_setup_ns_mode(dev, 1, I8254_MODE3,
+ cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ }
+ }
+ }
+
+ if (cmd->start_src == TRIG_INT) {
+ s->async->inttrig = pci230_ai_inttrig_start;
+ } else {
+ /* TRIG_NOW */
+ pci230_ai_start(dev, s);
+ }
+
+ return 0;
+}
+
+static unsigned int divide_ns(uint64_t ns, unsigned int timebase,
+ unsigned int round_mode)
+{
+ uint64_t div;
+ unsigned int rem;
+
+ div = ns;
+ rem = do_div(div, timebase);
+ round_mode &= TRIG_ROUND_MASK;
+ switch (round_mode) {
+ default:
+ case TRIG_ROUND_NEAREST:
+ div += (rem + (timebase / 2)) / timebase;
+ break;
+ case TRIG_ROUND_DOWN:
+ break;
+ case TRIG_ROUND_UP:
+ div += (rem + timebase - 1) / timebase;
+ break;
+ }
+ return div > UINT_MAX ? UINT_MAX : (unsigned int)div;
+}
+
+/* Given desired period in ns, returns the required internal clock source
+ * and gets the initial count. */
+static unsigned int pci230_choose_clk_count(uint64_t ns, unsigned int *count,
+ unsigned int round_mode)
+{
+ unsigned int clk_src, cnt;
+
+ for (clk_src = CLK_10MHZ;; clk_src++) {
+ cnt = divide_ns(ns, pci230_timebase[clk_src], round_mode);
+ if ((cnt <= 65536) || (clk_src == CLK_1KHZ)) {
+ break;
+ }
+ }
+ *count = cnt;
+ return clk_src;
+}
+
+static void pci230_ns_to_single_timer(unsigned int *ns, unsigned int round)
+{
+ unsigned int count;
+ unsigned int clk_src;
+
+ clk_src = pci230_choose_clk_count(*ns, &count, round);
+ *ns = count * pci230_timebase[clk_src];
+ return;
+}
+
+static void pci230_ct_setup_ns_mode(struct comedi_device * dev, unsigned int ct,
+ unsigned int mode, uint64_t ns, unsigned int round)
+{
+ unsigned int clk_src;
+ unsigned int count;
+
+ /* Set mode. */
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, mode);
+ /* Determine clock source and count. */
+ clk_src = pci230_choose_clk_count(ns, &count, round);
+ /* Program clock source. */
+ outb(CLK_CONFIG(ct, clk_src), devpriv->iobase1 + PCI230_ZCLK_SCE);
+ /* Set initial count. */
+ if (count >= 65536) {
+ count = 0;
+ }
+ i8254_write(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct, count);
+}
+
+static void pci230_cancel_ct(struct comedi_device * dev, unsigned int ct)
+{
+ i8254_set_mode(devpriv->iobase1 + PCI230_Z2_CT_BASE, 0, ct,
+ I8254_MODE1);
+ /* Counter ct, 8254 mode 1, initial count not written. */
+}
+
+/* Interrupt handler */
+static irqreturn_t pci230_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ unsigned char status_int, valid_status_int;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
+ unsigned long irqflags;
+
+ /* Read interrupt status/enable register. */
+ status_int = inb(devpriv->iobase1 + PCI230_INT_STAT);
+
+ if (status_int == PCI230_INT_DISABLE) {
+ return IRQ_NONE;
+ }
+
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ valid_status_int = devpriv->int_en & status_int;
+ /* Disable triggered interrupts.
+ * (Only those interrupts that need re-enabling, are, later in the
+ * handler). */
+ devpriv->ier = devpriv->int_en & ~status_int;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ devpriv->intr_running = 1;
+ devpriv->intr_cpuid = THISCPU;
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ /*
+ * Check the source of interrupt and handle it.
+ * The PCI230 can cope with concurrent ADC, DAC, PPI C0 and C3
+ * interrupts. However, at present (Comedi-0.7.60) does not allow
+ * concurrent execution of commands, instructions or a mixture of the
+ * two.
+ */
+
+ if ((valid_status_int & PCI230_INT_ZCLK_CT1) != 0) {
+ s = dev->write_subdev;
+ pci230_handle_ao_nofifo(dev, s);
+ comedi_event(dev, s);
+ }
+
+ if ((valid_status_int & PCI230P2_INT_DAC) != 0) {
+ s = dev->write_subdev;
+ pci230_handle_ao_fifo(dev, s);
+ comedi_event(dev, s);
+ }
+
+ if ((valid_status_int & PCI230_INT_ADC) != 0) {
+ s = dev->read_subdev;
+ pci230_handle_ai(dev, s);
+ comedi_event(dev, s);
+ }
+
+ /* Reenable interrupts. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ if (devpriv->ier != devpriv->int_en) {
+ devpriv->ier = devpriv->int_en;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ }
+ devpriv->intr_running = 0;
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ return IRQ_HANDLED;
+}
+
+static void pci230_handle_ao_nofifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ short data;
+ int i, ret;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ if (!devpriv->ao_continuous && (devpriv->ao_scan_count == 0)) {
+ return;
+ }
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ /* Read sample from Comedi's circular buffer. */
+ ret = comedi_buf_get(s->async, &data);
+ if (ret == 0) {
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ pci230_ao_stop(dev, s);
+ comedi_error(dev, "AO buffer underrun");
+ return;
+ }
+ /* Write value to DAC. */
+ pci230_ao_write_nofifo(dev, data, CR_CHAN(cmd->chanlist[i]));
+ }
+
+ async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS;
+ if (!devpriv->ao_continuous) {
+ devpriv->ao_scan_count--;
+ if (devpriv->ao_scan_count == 0) {
+ /* End of acquisition. */
+ async->events |= COMEDI_CB_EOA;
+ pci230_ao_stop(dev, s);
+ }
+ }
+}
+
+/* Loads DAC FIFO (if using it) from buffer. */
+/* Returns 0 if AO finished due to completion or error, 1 if still going. */
+static int pci230_handle_ao_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int num_scans;
+ unsigned int room;
+ unsigned short dacstat;
+ unsigned int i, n;
+ unsigned int bytes_per_scan;
+ unsigned int events = 0;
+ int running;
+
+ /* Get DAC FIFO status. */
+ dacstat = inw(dev->iobase + PCI230_DACCON);
+
+ /* Determine number of scans available in buffer. */
+ bytes_per_scan = cmd->chanlist_len * sizeof(short);
+ num_scans = comedi_buf_read_n_available(async) / bytes_per_scan;
+ if (!devpriv->ao_continuous) {
+ /* Fixed number of scans. */
+ if (num_scans > devpriv->ao_scan_count) {
+ num_scans = devpriv->ao_scan_count;
+ }
+ if (devpriv->ao_scan_count == 0) {
+ /* End of acquisition. */
+ events |= COMEDI_CB_EOA;
+ }
+ }
+ if (events == 0) {
+ /* Check for FIFO underrun. */
+ if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
+ comedi_error(dev, "AO FIFO underrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ }
+ /* Check for buffer underrun if FIFO less than half full
+ * (otherwise there will be loads of "DAC FIFO not half full"
+ * interrupts). */
+ if ((num_scans == 0)
+ && ((dacstat & PCI230P2_DAC_FIFO_HALF) == 0)) {
+ comedi_error(dev, "AO buffer underrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ }
+ }
+ if (events == 0) {
+ /* Determine how much room is in the FIFO (in samples). */
+ if ((dacstat & PCI230P2_DAC_FIFO_FULL) != 0) {
+ room = PCI230P2_DAC_FIFOROOM_FULL;
+ } else if ((dacstat & PCI230P2_DAC_FIFO_HALF) != 0) {
+ room = PCI230P2_DAC_FIFOROOM_HALFTOFULL;
+ } else if ((dacstat & PCI230P2_DAC_FIFO_EMPTY) != 0) {
+ room = PCI230P2_DAC_FIFOROOM_EMPTY;
+ } else {
+ room = PCI230P2_DAC_FIFOROOM_ONETOHALF;
+ }
+ /* Convert room to number of scans that can be added. */
+ room /= cmd->chanlist_len;
+ /* Determine number of scans to process. */
+ if (num_scans > room) {
+ num_scans = room;
+ }
+ /* Process scans. */
+ for (n = 0; n < num_scans; n++) {
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ short datum;
+
+ comedi_buf_get(async, &datum);
+ pci230_ao_write_fifo(dev, datum,
+ CR_CHAN(cmd->chanlist[i]));
+ }
+ }
+ events |= COMEDI_CB_EOS | COMEDI_CB_BLOCK;
+ if (!devpriv->ao_continuous) {
+ devpriv->ao_scan_count -= num_scans;
+ if (devpriv->ao_scan_count == 0) {
+ /* All data for the command has been written
+ * to FIFO. Set FIFO interrupt trigger level
+ * to 'empty'. */
+ devpriv->daccon = (devpriv->daccon
+ & ~PCI230P2_DAC_INT_FIFO_MASK)
+ | PCI230P2_DAC_INT_FIFO_EMPTY;
+ outw(devpriv->daccon,
+ dev->iobase + PCI230_DACCON);
+ }
+ }
+ /* Check if FIFO underrun occurred while writing to FIFO. */
+ dacstat = inw(dev->iobase + PCI230_DACCON);
+ if ((dacstat & PCI230P2_DAC_FIFO_UNDERRUN_LATCHED) != 0) {
+ comedi_error(dev, "AO FIFO underrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ }
+ }
+ if ((events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
+ != 0) {
+ /* Stopping AO due to completion or error. */
+ pci230_ao_stop(dev, s);
+ running = 0;
+ } else {
+ running = 1;
+ }
+ async->events |= events;
+ return running;
+}
+
+static void pci230_handle_ai(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int events = 0;
+ unsigned int status_fifo;
+ unsigned int i;
+ unsigned int todo;
+ unsigned int fifoamount;
+ struct comedi_async *async = s->async;
+ unsigned int scanlen = async->cmd.scan_end_arg;
+
+ /* Determine number of samples to read. */
+ if (devpriv->ai_continuous) {
+ todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else if (devpriv->ai_scan_count == 0) {
+ todo = 0;
+ } else if ((devpriv->ai_scan_count > PCI230_ADC_FIFOLEVEL_HALFFULL)
+ || (scanlen > PCI230_ADC_FIFOLEVEL_HALFFULL)) {
+ todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else {
+ todo = (devpriv->ai_scan_count * scanlen)
+ - devpriv->ai_scan_pos;
+ if (todo > PCI230_ADC_FIFOLEVEL_HALFFULL) {
+ todo = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ }
+ }
+
+ if (todo == 0) {
+ return;
+ }
+
+ fifoamount = 0;
+ for (i = 0; i < todo; i++) {
+ if (fifoamount == 0) {
+ /* Read FIFO state. */
+ status_fifo = inw(dev->iobase + PCI230_ADCCON);
+
+ if ((status_fifo & PCI230_ADC_FIFO_FULL_LATCHED) != 0) {
+ /* Report error otherwise FIFO overruns will go
+ * unnoticed by the caller. */
+ comedi_error(dev, "AI FIFO overrun");
+ events |= COMEDI_CB_OVERFLOW | COMEDI_CB_ERROR;
+ break;
+ } else if ((status_fifo & PCI230_ADC_FIFO_EMPTY) != 0) {
+ /* FIFO empty. */
+ break;
+ } else if ((status_fifo & PCI230_ADC_FIFO_HALF) != 0) {
+ /* FIFO half full. */
+ fifoamount = PCI230_ADC_FIFOLEVEL_HALFFULL;
+ } else {
+ /* FIFO not empty. */
+ if (devpriv->hwver > 0) {
+ /* Read PCI230+/260+ ADC FIFO level. */
+ fifoamount = inw(dev->iobase
+ + PCI230P_ADCFFLEV);
+ if (fifoamount == 0) {
+ /* Shouldn't happen. */
+ break;
+ }
+ } else {
+ fifoamount = 1;
+ }
+ }
+ }
+
+ /* Read sample and store in Comedi's circular buffer. */
+ if (comedi_buf_put(async, pci230_ai_read(dev)) == 0) {
+ events |= COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW;
+ comedi_error(dev, "AI buffer overflow");
+ break;
+ }
+ fifoamount--;
+ devpriv->ai_scan_pos++;
+ if (devpriv->ai_scan_pos == scanlen) {
+ /* End of scan. */
+ devpriv->ai_scan_pos = 0;
+ devpriv->ai_scan_count--;
+ async->events |= COMEDI_CB_EOS;
+ }
+ }
+
+ if (!devpriv->ai_continuous && (devpriv->ai_scan_count == 0)) {
+ /* End of acquisition. */
+ events |= COMEDI_CB_EOA;
+ } else {
+ /* More samples required, tell Comedi to block. */
+ events |= COMEDI_CB_BLOCK;
+ }
+ async->events |= events;
+
+ if ((async->events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+ COMEDI_CB_OVERFLOW)) != 0) {
+ /* disable hardware conversions */
+ pci230_ai_stop(dev, s);
+ } else {
+ /* update FIFO interrupt trigger level */
+ pci230_ai_update_fifo_trigger_level(dev, s);
+ }
+}
+
+static void pci230_ao_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long irqflags;
+ unsigned char intsrc;
+ int started;
+ struct comedi_cmd *cmd;
+
+ comedi_spin_lock_irqsave(&devpriv->ao_stop_spinlock, irqflags);
+ started = test_and_clear_bit(AO_CMD_STARTED, &devpriv->state);
+ comedi_spin_unlock_irqrestore(&devpriv->ao_stop_spinlock, irqflags);
+ if (!started) {
+ return;
+ }
+
+ cmd = &s->async->cmd;
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* Stop scan rate generator. */
+ pci230_cancel_ct(dev, 1);
+ }
+
+ /* Determine interrupt source. */
+ if (devpriv->hwver < 2) {
+ /* Not using DAC FIFO. Using CT1 interrupt. */
+ intsrc = PCI230_INT_ZCLK_CT1;
+ } else {
+ /* Using DAC FIFO interrupt. */
+ intsrc = PCI230P2_INT_DAC;
+ }
+ /* Disable interrupt and wait for interrupt routine to finish running
+ * unless we are called from the interrupt routine. */
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ devpriv->int_en &= ~intsrc;
+ while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ }
+ if (devpriv->ier != devpriv->int_en) {
+ devpriv->ier = devpriv->int_en;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ if (devpriv->hwver >= 2) {
+ /* Using DAC FIFO. Reset FIFO, clear underrun error,
+ * disable FIFO. */
+ devpriv->daccon &= PCI230_DAC_OR_MASK;
+ outw(devpriv->daccon | PCI230P2_DAC_FIFO_RESET
+ | PCI230P2_DAC_FIFO_UNDERRUN_CLEAR,
+ dev->iobase + PCI230_DACCON);
+ }
+
+ /* Release resources. */
+ put_all_resources(dev, OWNER_AOCMD);
+}
+
+static int pci230_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pci230_ao_stop(dev, s);
+ return 0;
+}
+
+static void pci230_ai_stop(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long irqflags;
+ struct comedi_cmd *cmd;
+ int started;
+
+ comedi_spin_lock_irqsave(&devpriv->ai_stop_spinlock, irqflags);
+ started = test_and_clear_bit(AI_CMD_STARTED, &devpriv->state);
+ comedi_spin_unlock_irqrestore(&devpriv->ai_stop_spinlock, irqflags);
+ if (!started) {
+ return;
+ }
+
+ cmd = &s->async->cmd;
+ if (cmd->convert_src == TRIG_TIMER) {
+ /* Stop conversion rate generator. */
+ pci230_cancel_ct(dev, 2);
+ }
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ /* Stop scan period monostable. */
+ pci230_cancel_ct(dev, 0);
+ }
+
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ /* Disable ADC interrupt and wait for interrupt routine to finish
+ * running unless we are called from the interrupt routine. */
+ devpriv->int_en &= ~PCI230_INT_ADC;
+ while (devpriv->intr_running && devpriv->intr_cpuid != THISCPU) {
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+ comedi_spin_lock_irqsave(&devpriv->isr_spinlock, irqflags);
+ }
+ if (devpriv->ier != devpriv->int_en) {
+ devpriv->ier = devpriv->int_en;
+ outb(devpriv->ier, devpriv->iobase1 + PCI230_INT_SCE);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->isr_spinlock, irqflags);
+
+ /* Reset FIFO, disable FIFO and set start conversion source to none.
+ * Keep se/diff and bip/uni settings */
+ devpriv->adccon = (devpriv->adccon & (PCI230_ADC_IR_MASK
+ | PCI230_ADC_IM_MASK)) | PCI230_ADC_TRIG_NONE;
+ outw(devpriv->adccon | PCI230_ADC_FIFO_RESET,
+ dev->iobase + PCI230_ADCCON);
+
+ /* Release resources. */
+ put_all_resources(dev, OWNER_AICMD);
+}
+
+static int pci230_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ pci230_ai_stop(dev, s);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/c6xdigio.c b/drivers/staging/comedi/drivers/c6xdigio.c
new file mode 100644
index 00000000000..2efffb14610
--- /dev/null
+++ b/drivers/staging/comedi/drivers/c6xdigio.c
@@ -0,0 +1,517 @@
+/*
+ comedi/drivers/c6xdigio.c
+
+ Hardware driver for Mechatronic Systems Inc. C6x_DIGIO DSP daughter card.
+ (http://robot0.ge.uiuc.edu/~spong/mecha/)
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Dan Block
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: c6xdigio
+Description: Mechatronic Systems Inc. C6x_DIGIO DSP daughter card
+Author: Dan Block
+Status: unknown
+Devices: [Mechatronic Systems Inc.] C6x_DIGIO DSP daughter card (c6xdigio)
+Updated: Sun Nov 20 20:18:34 EST 2005
+
+This driver will not work with a 2.4 kernel.
+http://robot0.ge.uiuc.edu/~spong/mecha/
+
+*/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+#include <linux/timer.h>
+#include <asm/io.h>
+#include <linux/pnp.h>
+
+#include "../comedidev.h"
+
+static u8 ReadByteFromHwPort(unsigned long addr)
+{
+ u8 result = inb(addr);
+ return result;
+}
+
+static void WriteByteToHwPort(unsigned long addr, u8 val)
+{
+ outb_p(val, addr);
+}
+
+#define C6XDIGIO_SIZE 3
+
+/*
+ * port offsets
+ */
+#define C6XDIGIO_PARALLEL_DATA 0
+#define C6XDIGIO_PARALLEL_STATUS 1
+#define C6XDIGIO_PARALLEL_CONTROL 2
+struct pwmbitstype {
+ unsigned sb0:2;
+ unsigned sb1:2;
+ unsigned sb2:2;
+ unsigned sb3:2;
+ unsigned sb4:2;
+};
+union pwmcmdtype {
+ unsigned cmd; // assuming here that int is 32bit
+ struct pwmbitstype bits;
+};
+struct encbitstype {
+ unsigned sb0:3;
+ unsigned sb1:3;
+ unsigned sb2:3;
+ unsigned sb3:3;
+ unsigned sb4:3;
+ unsigned sb5:3;
+ unsigned sb6:3;
+ unsigned sb7:3;
+};
+union encvaluetype {
+ unsigned value;
+ struct encbitstype bits;
+};
+
+#define C6XDIGIO_TIME_OUT 20
+
+static int c6xdigio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int c6xdigio_detach(struct comedi_device * dev);
+struct comedi_driver driver_c6xdigio = {
+ driver_name:"c6xdigio",
+ module:THIS_MODULE,
+ attach:c6xdigio_attach,
+ detach:c6xdigio_detach,
+};
+
+static void C6X_pwmInit(unsigned long baseAddr)
+{
+ int timeout = 0;
+
+//printk("Inside C6X_pwmInit\n");
+
+ WriteByteToHwPort(baseAddr, 0x70);
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x74);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x70);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+
+}
+
+static void C6X_pwmOutput(unsigned long baseAddr, unsigned channel, int value)
+{
+ unsigned ppcmd;
+ union pwmcmdtype pwm;
+ int timeout = 0;
+ unsigned tmp;
+
+ //printk("Inside C6X_pwmOutput\n");
+
+ pwm.cmd = value;
+ if (pwm.cmd > 498)
+ pwm.cmd = 498;
+ if (pwm.cmd < 2)
+ pwm.cmd = 2;
+
+ if (channel == 0) {
+ ppcmd = 0x28;
+ } else { // if channel == 1
+ ppcmd = 0x30;
+ } /* endif */
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb0);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb1 + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb2);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb3 + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, ppcmd + pwm.bits.sb4);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+}
+
+static int C6X_encInput(unsigned long baseAddr, unsigned channel)
+{
+ unsigned ppcmd;
+ union encvaluetype enc;
+ int timeout = 0;
+ int tmp;
+
+ //printk("Inside C6X_encInput\n");
+
+ enc.value = 0;
+ if (channel == 0) {
+ ppcmd = 0x48;
+ } else {
+ ppcmd = 0x50;
+ }
+ WriteByteToHwPort(baseAddr, ppcmd);
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ enc.bits.sb0 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb1 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb2 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb3 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb4 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb5 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb6 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd + 0x4);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+ enc.bits.sb7 = ((ReadByteFromHwPort(baseAddr + 1) >> 3) & 0x7);
+ WriteByteToHwPort(baseAddr, ppcmd);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x0) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ while (((tmp & 0x80) == 0x80) && (timeout < C6XDIGIO_TIME_OUT)) {
+ tmp = ReadByteFromHwPort(baseAddr + 1);
+ timeout++;
+ }
+
+ return (enc.value ^ 0x800000);
+}
+
+static void C6X_encResetAll(unsigned long baseAddr)
+{
+ unsigned timeout = 0;
+
+//printk("Inside C6X_encResetAll\n");
+
+ WriteByteToHwPort(baseAddr, 0x68);
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+ WriteByteToHwPort(baseAddr, 0x6C);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+ WriteByteToHwPort(baseAddr, 0x68);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x0)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+ WriteByteToHwPort(baseAddr, 0x0);
+ timeout = 0;
+ while (((ReadByteFromHwPort(baseAddr + 1) & 0x80) == 0x80)
+ && (timeout < C6XDIGIO_TIME_OUT)) {
+ timeout++;
+ }
+}
+
+static int c6xdigio_pwmo_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ printk("c6xdigio_pwmo_insn_read %x\n", insn->n);
+ return insn->n;
+}
+
+static int c6xdigio_pwmo_insn_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ // printk("c6xdigio_pwmo_insn_write %x\n", insn->n);
+ for (i = 0; i < insn->n; i++) {
+ C6X_pwmOutput(dev->iobase, chan, data[i]);
+ /* devpriv->ao_readback[chan] = data[i]; */
+ }
+ return i;
+}
+
+//static int c6xdigio_ei_init_insn_read(struct comedi_device *dev,
+// struct comedi_subdevice *s,
+// struct comedi_insn *insn,
+// unsigned int *data)
+//{
+// printk("c6xdigio_ei_init_insn_read %x\n", insn->n);
+// return insn->n;
+//}
+
+//static int c6xdigio_ei_init_insn_write(struct comedi_device *dev,
+// struct comedi_subdevice *s,
+// struct comedi_insn *insn,
+// unsigned int *data)
+//{
+// int i;
+// int chan = CR_CHAN(insn->chanspec);
+//
+// C6X_encResetAll( dev->iobase );
+//
+// return insn->n;
+//}
+
+static int c6xdigio_ei_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ // printk("c6xdigio_ei__insn_read %x\n", insn->n);
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = (C6X_encInput(dev->iobase, chan) & 0xffffff);
+ }
+
+ return n;
+}
+
+static void board_init(struct comedi_device * dev)
+{
+
+ //printk("Inside board_init\n");
+
+ C6X_pwmInit(dev->iobase);
+ C6X_encResetAll(dev->iobase);
+
+}
+
+//static void board_halt(struct comedi_device *dev) {
+// C6X_pwmInit(dev->iobase);
+//}
+
+/*
+ options[0] - I/O port
+ options[1] - irq
+ options[2] - number of encoder chips installed
+ */
+
+static const struct pnp_device_id c6xdigio_pnp_tbl[] = {
+ /* Standard LPT Printer Port */
+ {.id = "PNP0400",.driver_data = 0},
+ /* ECP Printer Port */
+ {.id = "PNP0401",.driver_data = 0},
+ {}
+};
+
+static struct pnp_driver c6xdigio_pnp_driver = {
+ .name = "c6xdigio",
+ .id_table = c6xdigio_pnp_tbl,
+};
+
+static int c6xdigio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ unsigned long iobase;
+ unsigned int irq;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ printk("comedi%d: c6xdigio: 0x%04lx\n", dev->minor, iobase);
+ if (!request_region(iobase, C6XDIGIO_SIZE, "c6xdigio")) {
+ printk("comedi%d: I/O port conflict\n", dev->minor);
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "c6xdigio";
+
+ result = alloc_subdevices(dev, 2); // 3 with encoder_init write
+ if (result < 0)
+ return result;
+
+ // Make sure that PnP ports gets activated
+ pnp_register_driver(&c6xdigio_pnp_driver);
+
+ irq = it->options[1];
+ if (irq > 0) {
+ printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
+ } else if (irq == 0) {
+ printk("comedi%d: no irq\n", dev->minor);
+ }
+
+ s = dev->subdevices + 0;
+ /* pwm output subdevice */
+ s->type = COMEDI_SUBD_AO; // Not sure what to put here
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 2;
+ /* s->trig[0] = c6xdigio_pwmo; */
+ s->insn_read = c6xdigio_pwmo_insn_read;
+ s->insn_write = c6xdigio_pwmo_insn_write;
+ s->maxdata = 500;
+ s->range_table = &range_bipolar10; // A suitable lie
+
+ s = dev->subdevices + 1;
+ /* encoder (counter) subdevice */
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = 2;
+ /* s->trig[0] = c6xdigio_ei; */
+ s->insn_read = c6xdigio_ei_insn_read;
+ s->maxdata = 0xffffff;
+ s->range_table = &range_unknown;
+
+ // s = dev->subdevices + 2;
+ // /* pwm output subdevice */
+ // s->type = COMEDI_SUBD_COUNTER; // Not sure what to put here
+ // s->subdev_flags = SDF_WRITEABLE;
+ // s->n_chan = 1;
+ // /* s->trig[0] = c6xdigio_ei_init; */
+ // s->insn_read = c6xdigio_ei_init_insn_read;
+ // s->insn_write = c6xdigio_ei_init_insn_write;
+ // s->maxdata = 0xFFFF; // Really just a don't care
+ // s->range_table = &range_unknown; // Not sure what to put here
+
+ // I will call this init anyway but more than likely the DSP board will not be connect
+ // when device driver is loaded.
+ board_init(dev);
+
+ return 0;
+}
+
+static int c6xdigio_detach(struct comedi_device * dev)
+{
+// board_halt(dev); // may not need this
+
+ printk("comedi%d: c6xdigio: remove\n", dev->minor);
+
+ if (dev->iobase) {
+ release_region(dev->iobase, C6XDIGIO_SIZE);
+ }
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ } // Not using IRQ so I am not sure if I need this
+ pnp_unregister_driver(&c6xdigio_pnp_driver);
+
+ return 0;
+}
+
+COMEDI_INITCLEANUP(driver_c6xdigio);
diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c
new file mode 100644
index 00000000000..0bfe4c954eb
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_das16_cs.c
@@ -0,0 +1,976 @@
+/*
+ comedi/drivers/das16cs.c
+ Driver for Computer Boards PC-CARD DAS16/16.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000, 2001, 2002 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_das16_cs
+Description: Computer Boards PC-CARD DAS16/16
+Devices: [ComputerBoards] PC-CARD DAS16/16 (cb_das16_cs), PC-CARD DAS16/16-AO
+Author: ds
+Updated: Mon, 04 Nov 2002 20:04:21 -0800
+Status: experimental
+
+
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#include "8253.h"
+
+#define DAS16CS_SIZE 18
+
+#define DAS16CS_ADC_DATA 0
+#define DAS16CS_DIO_MUX 2
+#define DAS16CS_MISC1 4
+#define DAS16CS_MISC2 6
+#define DAS16CS_CTR0 8
+#define DAS16CS_CTR1 10
+#define DAS16CS_CTR2 12
+#define DAS16CS_CTR_CONTROL 14
+#define DAS16CS_DIO 16
+
+struct das16cs_board {
+ const char *name;
+ int device_id;
+ int n_ao_chans;
+};
+static const struct das16cs_board das16cs_boards[] = {
+ {
+ device_id:0x0000,/* unknown */
+ name: "PC-CARD DAS16/16",
+ n_ao_chans:0,
+ },
+ {
+ device_id:0x0039,
+ name: "PC-CARD DAS16/16-AO",
+ n_ao_chans:2,
+ },
+ {
+ device_id:0x4009,
+ name: "PCM-DAS16s/16",
+ n_ao_chans:0,
+ },
+};
+
+#define n_boards (sizeof(das16cs_boards)/sizeof(das16cs_boards[0]))
+#define thisboard ((const struct das16cs_board *)dev->board_ptr)
+
+struct das16cs_private {
+ struct pcmcia_device *link;
+
+ unsigned int ao_readback[2];
+ unsigned short status1;
+ unsigned short status2;
+};
+#define devpriv ((struct das16cs_private *)dev->private)
+
+static int das16cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16cs_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16cs = {
+ driver_name:"cb_das16_cs",
+ module:THIS_MODULE,
+ attach:das16cs_attach,
+ detach:das16cs_detach,
+};
+
+static struct pcmcia_device *cur_dev = NULL;
+
+static const struct comedi_lrange das16cs_ai_range = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ }
+};
+
+static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG);
+static int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int get_prodid(struct comedi_device * dev, struct pcmcia_device *link)
+{
+ tuple_t tuple;
+ u_short buf[128];
+ int prodid = 0;
+
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.DesiredTuple = CISTPL_MANFID;
+ tuple.Attributes = TUPLE_RETURN_COMMON;
+ if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+ (pcmcia_get_tuple_data(link, &tuple) == 0)) {
+ prodid = le16_to_cpu(buf[1]);
+ }
+
+ return prodid;
+}
+
+static const struct das16cs_board *das16cs_probe(struct comedi_device * dev,
+ struct pcmcia_device *link)
+{
+ int id;
+ int i;
+
+ id = get_prodid(dev, link);
+
+ for (i = 0; i < n_boards; i++) {
+ if (das16cs_boards[i].device_id == id) {
+ return das16cs_boards + i;
+ }
+ }
+
+ printk("unknown board!\n");
+
+ return NULL;
+}
+
+static int das16cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pcmcia_device *link;
+ struct comedi_subdevice *s;
+ int ret;
+ int i;
+
+ printk("comedi%d: cb_das16_cs: ", dev->minor);
+
+ link = cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+
+ dev->iobase = link->io.BasePort1;
+ printk("I/O base=0x%04lx ", dev->iobase);
+
+ printk("fingerprint:\n");
+ for (i = 0; i < 48; i += 2) {
+ printk("%04x ", inw(dev->iobase + i));
+ }
+ printk("\n");
+
+ ret = comedi_request_irq(link->irq.AssignedIRQ, das16cs_interrupt,
+ IRQF_SHARED, "cb_das16_cs", dev);
+ if (ret < 0) {
+ return ret;
+ }
+ dev->irq = link->irq.AssignedIRQ;
+ printk("irq=%u ", dev->irq);
+
+ dev->board_ptr = das16cs_probe(dev, link);
+ if (!dev->board_ptr)
+ return -EIO;
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct das16cs_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = 16;
+ s->maxdata = 0xffff;
+ s->range_table = &das16cs_ai_range;
+ s->len_chanlist = 16;
+ s->insn_read = das16cs_ai_rinsn;
+ s->do_cmd = das16cs_ai_cmd;
+ s->do_cmdtest = das16cs_ai_cmdtest;
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ if (thisboard->n_ao_chans) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->n_ao_chans;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar10;
+ s->insn_write = &das16cs_ao_winsn;
+ s->insn_read = &das16cs_ao_rinsn;
+ }
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (1) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das16cs_dio_insn_bits;
+ s->insn_config = das16cs_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ /* timer subdevice */
+ if (0) {
+ s->type = COMEDI_SUBD_TIMER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->range_table = &range_unknown;
+ s->insn_read = das16cs_timer_insn_read;
+ s->insn_config = das16cs_timer_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+static int das16cs_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das16cs: remove\n", dev->minor);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ return 0;
+}
+
+static irqreturn_t das16cs_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ //struct comedi_device *dev = d;
+ return IRQ_HANDLED;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int das16cs_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int to;
+ int aref;
+ int range;
+ int chan;
+ static int range_bits[] = { 0x800, 0x000, 0x100, 0x200 };
+
+ chan = CR_CHAN(insn->chanspec);
+ aref = CR_AREF(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ outw(chan, dev->iobase + 2);
+
+ devpriv->status1 &= ~0xf320;
+ devpriv->status1 |= (aref == AREF_DIFF) ? 0 : 0x0020;
+ outw(devpriv->status1, dev->iobase + 4);
+
+ devpriv->status2 &= ~0xff00;
+ devpriv->status2 |= range_bits[range];
+ outw(devpriv->status2, dev->iobase + 6);
+
+ for (i = 0; i < insn->n; i++) {
+ outw(0, dev->iobase);
+
+#define TIMEOUT 1000
+ for (to = 0; to < TIMEOUT; to++) {
+ if (inw(dev->iobase + 4) & 0x0080)
+ break;
+ }
+ if (to == TIMEOUT) {
+ printk("cb_das16_cs: ai timeout\n");
+ return -ETIME;
+ }
+ data[i] = (unsigned short)inw(dev->iobase + 0);
+ }
+
+ return i;
+}
+
+static int das16cs_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ return -EINVAL;
+}
+
+static int das16cs_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* in nanoseconds */
+#define MIN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED) {
+ cmd->scan_begin_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED) {
+ cmd->convert_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int div1, div2;
+
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer(100, &div1, &div2,
+ &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ unsigned int div1, div2;
+
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(100, &div1, &div2,
+ &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int das16cs_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short status1;
+ unsigned short d;
+ int bit;
+
+ for (i = 0; i < insn->n; i++) {
+ devpriv->ao_readback[chan] = data[i];
+ d = data[i];
+
+ outw(devpriv->status1, dev->iobase + 4);
+ comedi_udelay(1);
+
+ status1 = devpriv->status1 & ~0xf;
+ if (chan)
+ status1 |= 0x0001;
+ else
+ status1 |= 0x0008;
+
+/* printk("0x%04x\n",status1);*/
+ outw(status1, dev->iobase + 4);
+ comedi_udelay(1);
+
+ for (bit = 15; bit >= 0; bit--) {
+ int b = (d >> bit) & 0x1;
+ b <<= 1;
+/* printk("0x%04x\n",status1 | b | 0x0000);*/
+ outw(status1 | b | 0x0000, dev->iobase + 4);
+ comedi_udelay(1);
+/* printk("0x%04x\n",status1 | b | 0x0004);*/
+ outw(status1 | b | 0x0004, dev->iobase + 4);
+ comedi_udelay(1);
+ }
+/* make high both DAC0CS and DAC1CS to load
+ new data and update analog output*/
+ outw(status1 | 0x9, dev->iobase + 4);
+ }
+
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int das16cs_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int das16cs_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+
+ outw(s->state, dev->iobase + 16);
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ data[1] = inw(dev->iobase + 16);
+
+ return 2;
+}
+
+static int das16cs_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int bits;
+
+ if (chan < 4)
+ bits = 0x0f;
+ else
+ bits = 0xf0;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ devpriv->status2 &= ~0x00c0;
+ devpriv->status2 |= (s->io_bits & 0xf0) ? 0x0080 : 0;
+ devpriv->status2 |= (s->io_bits & 0x0f) ? 0x0040 : 0;
+
+ outw(devpriv->status2, dev->iobase + 6);
+
+ return insn->n;
+}
+
+static int das16cs_timer_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return -EINVAL;
+}
+
+static int das16cs_timer_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return -EINVAL;
+}
+
+/* PCMCIA stuff */
+
+/*======================================================================
+
+ The following pcmcia code for the pcm-das08 is adapted from the
+ dummy_cs.c driver of the Linux PCMCIA Card Services package.
+
+ The initial developer of the original code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+======================================================================*/
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE)
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version =
+ "cb_das16_cs.c pcmcia code (David Schleef), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link);
+static void das16cs_pcmcia_release(struct pcmcia_device *link);
+static int das16cs_pcmcia_suspend(struct pcmcia_device *p_dev);
+static int das16cs_pcmcia_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int das16cs_pcmcia_attach(struct pcmcia_device *);
+static void das16cs_pcmcia_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static dev_info_t dev_info = "cb_das16_cs";
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+};
+
+/*======================================================================
+
+ das16cs_pcmcia_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int das16cs_pcmcia_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+
+ DEBUG(0, "das16cs_pcmcia_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Initialize the pcmcia_device structure */
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ cur_dev = link;
+
+ das16cs_pcmcia_config(link);
+
+ return 0;
+} /* das16cs_pcmcia_attach */
+
+static void das16cs_pcmcia_detach(struct pcmcia_device *link)
+{
+ DEBUG(0, "das16cs_pcmcia_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((struct local_info_t *) link->priv)->stop = 1;
+ das16cs_pcmcia_release(link);
+ }
+ /* This points to the parent struct local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+} /* das16cs_pcmcia_detach */
+
+static void das16cs_pcmcia_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_fn, last_ret;
+ u_char buf[64];
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ DEBUG(0, "das16cs_pcmcia_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = GetTupleData;
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = ParseTuple;
+ if ((last_ret = pcmcia_parse_tuple(link, &tuple, &parse)) != 0)
+ goto cs_failed;
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple))
+ goto next_entry;
+ if (pcmcia_parse_tuple(link, &tuple, &parse))
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+*/
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io))
+ goto next_entry;
+ }
+
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ last_fn = GetNextTuple;
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ }
+
+ /*
+ Allocate an interrupt line. Note that this does not assign a
+ handler to the interrupt, unless the 'Handler' member of the
+ irq structure is initialized.
+ */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ last_fn = RequestIRQ;
+ if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
+ goto cs_failed;
+ }
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ last_fn = RequestConfiguration;
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
+ goto cs_failed;
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "cb_das16_cs");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %u", link->irq.AssignedIRQ);
+ if (link->io.NumPorts1)
+ printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+ link->io.BasePort1 + link->io.NumPorts1 - 1);
+ if (link->io.NumPorts2)
+ printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+ link->io.BasePort2 + link->io.NumPorts2 - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ cs_error(link, last_fn, last_ret);
+ das16cs_pcmcia_release(link);
+} /* das16cs_pcmcia_config */
+
+static void das16cs_pcmcia_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "das16cs_pcmcia_release(0x%p)\n", link);
+ pcmcia_disable_device(link);
+} /* das16cs_pcmcia_release */
+
+static int das16cs_pcmcia_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+
+ return 0;
+} /* das16cs_pcmcia_suspend */
+
+static int das16cs_pcmcia_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* das16cs_pcmcia_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id das16cs_id_table[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x0039),
+ PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4009),
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, das16cs_id_table);
+
+struct pcmcia_driver das16cs_driver = {
+ .probe = das16cs_pcmcia_attach,
+ .remove = das16cs_pcmcia_detach,
+ .suspend = das16cs_pcmcia_suspend,
+ .resume = das16cs_pcmcia_resume,
+ .id_table = das16cs_id_table,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_das16cs_pcmcia_cs(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&das16cs_driver);
+ return 0;
+}
+
+static void __exit exit_das16cs_pcmcia_cs(void)
+{
+ DEBUG(0, "das16cs_pcmcia_cs: unloading\n");
+ pcmcia_unregister_driver(&das16cs_driver);
+}
+
+int __init init_module(void)
+{
+ int ret;
+
+ ret = init_das16cs_pcmcia_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_das16cs);
+}
+
+void __exit cleanup_module(void)
+{
+ exit_das16cs_pcmcia_cs();
+ comedi_driver_unregister(&driver_das16cs);
+}
+
+#else
+COMEDI_INITCLEANUP(driver_das16cs);
+#endif //CONFIG_PCMCIA
diff --git a/drivers/staging/comedi/drivers/cb_pcidas.c b/drivers/staging/comedi/drivers/cb_pcidas.c
new file mode 100644
index 00000000000..fcc55165136
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidas.c
@@ -0,0 +1,1831 @@
+/*
+ comedi/drivers/cb_pcidas.c
+
+ Developed by Ivan Martinez and Frank Mori Hess, with valuable help from
+ David Schleef and the rest of the Comedi developers comunity.
+
+ Copyright (C) 2001-2003 Ivan Martinez <imr@oersted.dtu.dk>
+ Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: cb_pcidas
+Description: MeasurementComputing PCI-DAS series with the AMCC S5933 PCI controller
+Author: Ivan Martinez <imr@oersted.dtu.dk>,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: 2003-3-11
+Devices: [Measurement Computing] PCI-DAS1602/16 (cb_pcidas),
+ PCI-DAS1602/16jr, PCI-DAS1602/12, PCI-DAS1200, PCI-DAS1200jr,
+ PCI-DAS1000, PCI-DAS1001, PCI_DAS1002
+
+Status:
+ There are many reports of the driver being used with most of the
+ supported cards. Despite no detailed log is maintained, it can
+ be said that the driver is quite tested and stable.
+
+ The boards may be autocalibrated using the comedi_calibrate
+ utility.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+For commands, the scanned channels must be consecutive
+(i.e. 4-5-6-7, 2-3-4,...), and must all have the same
+range and aref.
+*/
+/*
+
+TODO:
+
+analog triggering on 1602 series
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "amcc_s5933.h"
+#include "comedi_pci.h"
+#include "comedi_fc.h"
+
+#undef CB_PCIDAS_DEBUG // disable debugging code
+//#define CB_PCIDAS_DEBUG // enable debugging code
+
+// PCI vendor number of ComputerBoards/MeasurementComputing
+#define PCI_VENDOR_ID_CB 0x1307
+#define TIMER_BASE 100 // 10MHz master clock
+#define AI_BUFFER_SIZE 1024 // maximum fifo size of any supported board
+#define AO_BUFFER_SIZE 1024 // maximum fifo size of any supported board
+#define NUM_CHANNELS_8800 8
+#define NUM_CHANNELS_7376 1
+#define NUM_CHANNELS_8402 2
+#define NUM_CHANNELS_DAC08 1
+
+/* PCI-DAS base addresses */
+
+// indices of base address regions
+#define S5933_BADRINDEX 0
+#define CONT_STAT_BADRINDEX 1
+#define ADC_FIFO_BADRINDEX 2
+#define PACER_BADRINDEX 3
+#define AO_BADRINDEX 4
+// sizes of io regions
+#define CONT_STAT_SIZE 10
+#define ADC_FIFO_SIZE 4
+#define PACER_SIZE 12
+#define AO_SIZE 4
+
+/* Control/Status registers */
+#define INT_ADCFIFO 0 // INTERRUPT / ADC FIFO register
+#define INT_EOS 0x1 // interrupt end of scan
+#define INT_FHF 0x2 // interrupt fifo half full
+#define INT_FNE 0x3 // interrupt fifo not empty
+#define INT_MASK 0x3 // mask of interrupt select bits
+#define INTE 0x4 // interrupt enable
+#define DAHFIE 0x8 // dac half full interrupt enable
+#define EOAIE 0x10 // end of aquisition interrupt enable
+#define DAHFI 0x20 // dac half full read status / write interrupt clear
+#define EOAI 0x40 // read end of acq. interrupt status / write clear
+#define INT 0x80 // read interrupt status / write clear
+#define EOBI 0x200 // read end of burst interrupt status
+#define ADHFI 0x400 // read half-full interrupt status
+#define ADNEI 0x800 // read fifo not empty interrupt latch status
+#define ADNE 0x1000 // read, fifo not empty (realtime, not latched) status
+#define DAEMIE 0x1000 // write, dac empty interrupt enable
+#define LADFUL 0x2000 // read fifo overflow / write clear
+#define DAEMI 0x4000 // dac fifo empty interrupt status / write clear
+
+#define ADCMUX_CONT 2 // ADC CHANNEL MUX AND CONTROL register
+#define BEGIN_SCAN(x) ((x) & 0xf)
+#define END_SCAN(x) (((x) & 0xf) << 4)
+#define GAIN_BITS(x) (((x) & 0x3) << 8)
+#define UNIP 0x800 // Analog front-end unipolar for range
+#define SE 0x400 // Inputs in single-ended mode
+#define PACER_MASK 0x3000 // pacer source bits
+#define PACER_INT 0x1000 // internal pacer
+#define PACER_EXT_FALL 0x2000 // external falling edge
+#define PACER_EXT_RISE 0x3000 // external rising edge
+#define EOC 0x4000 // adc not busy
+
+#define TRIG_CONTSTAT 4 // TRIGGER CONTROL/STATUS register
+#define SW_TRIGGER 0x1 // software start trigger
+#define EXT_TRIGGER 0x2 // external start trigger
+#define ANALOG_TRIGGER 0x3 // external analog trigger
+#define TRIGGER_MASK 0x3 // mask of bits that determine start trigger
+#define TGEN 0x10 // enable external start trigger
+#define BURSTE 0x20 // burst mode enable
+#define XTRCL 0x80 // clear external trigger
+
+#define CALIBRATION_REG 6 // CALIBRATION register
+#define SELECT_8800_BIT 0x100 // select 8800 caldac
+#define SELECT_TRIMPOT_BIT 0x200 // select ad7376 trim pot
+#define SELECT_DAC08_BIT 0x400 // select dac08 caldac
+#define CAL_SRC_BITS(x) (((x) & 0x7) << 11)
+#define CAL_EN_BIT 0x4000 // read calibration source instead of analog input channel 0
+#define SERIAL_DATA_IN_BIT 0x8000 // serial data stream going to 8800 and 7376
+
+#define DAC_CSR 0x8 // dac control and status register
+enum dac_csr_bits {
+ DACEN = 0x2, // dac enable
+ DAC_MODE_UPDATE_BOTH = 0x80, // update both dacs when dac0 is written
+};
+static inline unsigned int DAC_RANGE(unsigned int channel, unsigned int range)
+{
+ return (range & 0x3) << (8 + 2 * (channel & 0x1));
+}
+static inline unsigned int DAC_RANGE_MASK(unsigned int channel)
+{
+ return 0x3 << (8 + 2 * (channel & 0x1));
+};
+
+// bits for 1602 series only
+enum dac_csr_bits_1602 {
+ DAC_EMPTY = 0x1, // dac fifo empty, read, write clear
+ DAC_START = 0x4, // start/arm dac fifo operations
+ DAC_PACER_MASK = 0x18, // bits that set dac pacer source
+ DAC_PACER_INT = 0x8, // dac internal pacing
+ DAC_PACER_EXT_FALL = 0x10, // dac external pacing, falling edge
+ DAC_PACER_EXT_RISE = 0x18, // dac external pacing, rising edge
+};
+static inline unsigned int DAC_CHAN_EN(unsigned int channel)
+{
+ return 1 << (5 + (channel & 0x1)); // enable channel 0 or 1
+};
+
+/* analog input fifo */
+#define ADCDATA 0 // ADC DATA register
+#define ADCFIFOCLR 2 // ADC FIFO CLEAR
+
+// pacer, counter, dio registers
+#define ADC8254 0
+#define DIO_8255 4
+#define DAC8254 8
+
+// analog output registers for 100x, 1200 series
+static inline unsigned int DAC_DATA_REG(unsigned int channel)
+{
+ return 2 * (channel & 0x1);
+}
+
+/* analog output registers for 1602 series*/
+#define DACDATA 0 // DAC DATA register
+#define DACFIFOCLR 2 // DAC FIFO CLEAR
+
+// bit in hexadecimal representation of range index that indicates unipolar input range
+#define IS_UNIPOLAR 0x4
+// analog input ranges for most boards
+static const struct comedi_lrange cb_pcidas_ranges = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+// pci-das1001 input ranges
+static const struct comedi_lrange cb_pcidas_alt_ranges = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+};
+
+// analog output ranges
+static const struct comedi_lrange cb_pcidas_ao_ranges = {
+ 4,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+enum trimpot_model {
+ AD7376,
+ AD8402,
+};
+
+struct cb_pcidas_board {
+ const char *name;
+ unsigned short device_id;
+ int ai_se_chans; // Inputs in single-ended mode
+ int ai_diff_chans; // Inputs in differential mode
+ int ai_bits; // analog input resolution
+ int ai_speed; // fastest conversion period in ns
+ int ao_nchan; // number of analog out channels
+ int has_ao_fifo; // analog output has fifo
+ int ao_scan_speed; // analog output speed for 1602 series (for a scan, not conversion)
+ int fifo_size; // number of samples fifo can hold
+ const struct comedi_lrange *ranges;
+ enum trimpot_model trimpot;
+ unsigned has_dac08:1;
+};
+
+static const struct cb_pcidas_board cb_pcidas_boards[] = {
+ {
+ name: "pci-das1602/16",
+ device_id:0x1,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ has_ao_fifo:1,
+ ao_scan_speed:10000,
+ fifo_size:512,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD8402,
+ has_dac08:1,
+ },
+ {
+ name: "pci-das1200",
+ device_id:0xF,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:3200,
+ ao_nchan:2,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1602/12",
+ device_id:0x10,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:3200,
+ ao_nchan:2,
+ has_ao_fifo:1,
+ ao_scan_speed:4000,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1200/jr",
+ device_id:0x19,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:3200,
+ ao_nchan:0,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1602/16/jr",
+ device_id:0x1C,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:0,
+ has_ao_fifo:0,
+ fifo_size:512,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD8402,
+ has_dac08:1,
+ },
+ {
+ name: "pci-das1000",
+ device_id:0x4C,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:4000,
+ ao_nchan:0,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1001",
+ device_id:0x1a,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:6800,
+ ao_nchan:2,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_alt_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+ {
+ name: "pci-das1002",
+ device_id:0x1b,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 12,
+ ai_speed:6800,
+ ao_nchan:2,
+ has_ao_fifo:0,
+ fifo_size:1024,
+ ranges: &cb_pcidas_ranges,
+ trimpot: AD7376,
+ has_dac08:0,
+ },
+};
+
+// Number of boards in cb_pcidas_boards
+#define N_BOARDS (sizeof(cb_pcidas_boards) / sizeof(struct cb_pcidas_board))
+
+static DEFINE_PCI_DEVICE_TABLE(cb_pcidas_pci_table) = {
+ {PCI_VENDOR_ID_CB, 0x0001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x000f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0010, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0019, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x001c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x004c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x001a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x001b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcidas_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcidas_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct cb_pcidas_private {
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+ // base addresses
+ unsigned long s5933_config;
+ unsigned long control_status;
+ unsigned long adc_fifo;
+ unsigned long pacer_counter_dio;
+ unsigned long ao_registers;
+ // divisors of master clock for analog input pacing
+ unsigned int divisor1;
+ unsigned int divisor2;
+ volatile unsigned int count; // number of analog input samples remaining
+ volatile unsigned int adc_fifo_bits; // bits to write to interupt/adcfifo register
+ volatile unsigned int s5933_intcsr_bits; // bits to write to amcc s5933 interrupt control/status register
+ volatile unsigned int ao_control_bits; // bits to write to ao control and status register
+ short ai_buffer[AI_BUFFER_SIZE];
+ short ao_buffer[AO_BUFFER_SIZE];
+ // divisors of master clock for analog output pacing
+ unsigned int ao_divisor1;
+ unsigned int ao_divisor2;
+ volatile unsigned int ao_count; // number of analog output samples remaining
+ int ao_value[2]; // remember what the analog outputs are set to, to allow readback
+ unsigned int caldac_value[NUM_CHANNELS_8800]; // for readback of caldac
+ unsigned int trimpot_value[NUM_CHANNELS_8402]; // for readback of trimpot
+ unsigned int dac08_value;
+ unsigned int calibration_source;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcidas_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int cb_pcidas_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcidas_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidas = {
+ driver_name:"cb_pcidas",
+ module:THIS_MODULE,
+ attach:cb_pcidas_attach,
+ detach:cb_pcidas_detach,
+};
+
+static int cb_pcidas_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *subdev,
+ unsigned int trig_num);
+static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG);
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status);
+static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int cb_pcidas_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
+ int round_flags);
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcidas_trimpot_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dac08_write(struct comedi_device * dev, unsigned int value);
+static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value);
+static int trimpot_7376_write(struct comedi_device * dev, uint8_t value);
+static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
+ uint8_t value);
+static int nvram_read(struct comedi_device * dev, unsigned int address,
+ uint8_t * data);
+
+static inline unsigned int cal_enable_bits(struct comedi_device * dev)
+{
+ return CAL_EN_BIT | CAL_SRC_BITS(devpriv->calibration_source);
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int cb_pcidas_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pcidev;
+ int index;
+ int i;
+
+ printk("comedi%d: cb_pcidas: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct cb_pcidas_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+ printk("\n");
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_CB)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < N_BOARDS; index++) {
+ if (cb_pcidas_boards[index].device_id != pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = cb_pcidas_boards + index;
+ goto found;
+ }
+ }
+
+ printk("No supported ComputerBoards/MeasurementComputing card found on "
+ "requested position\n");
+ return -EIO;
+
+ found:
+
+ printk("Found %s on bus %i, slot %i\n", cb_pcidas_boards[index].name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ /*
+ * Enable PCI device and reserve I/O ports.
+ */
+ if (comedi_pci_enable(pcidev, "cb_pcidas")) {
+ printk(" Failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ /*
+ * Initialize devpriv->control_status and devpriv->adc_fifo to point to
+ * their base address.
+ */
+ devpriv->s5933_config =
+ pci_resource_start(devpriv->pci_dev, S5933_BADRINDEX);
+ devpriv->control_status =
+ pci_resource_start(devpriv->pci_dev, CONT_STAT_BADRINDEX);
+ devpriv->adc_fifo =
+ pci_resource_start(devpriv->pci_dev, ADC_FIFO_BADRINDEX);
+ devpriv->pacer_counter_dio =
+ pci_resource_start(devpriv->pci_dev, PACER_BADRINDEX);
+ if (thisboard->ao_nchan) {
+ devpriv->ao_registers =
+ pci_resource_start(devpriv->pci_dev, AO_BADRINDEX);
+ }
+ // disable and clear interrupts on amcc s5933
+ outl(INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+ // get irq
+ if (comedi_request_irq(devpriv->pci_dev->irq, cb_pcidas_interrupt,
+ IRQF_SHARED, "cb_pcidas", dev)) {
+ printk(" unable to allocate irq %d\n", devpriv->pci_dev->irq);
+ return -EINVAL;
+ }
+ dev->irq = devpriv->pci_dev->irq;
+
+ //Initialize dev->board_name
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.
+ */
+ if (alloc_subdevices(dev, 7) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ /* WARNING: Number of inputs in differential mode is ignored */
+ s->n_chan = thisboard->ai_se_chans;
+ s->len_chanlist = thisboard->ai_se_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = thisboard->ranges;
+ s->insn_read = cb_pcidas_ai_rinsn;
+ s->insn_config = ai_config_insn;
+ s->do_cmd = cb_pcidas_ai_cmd;
+ s->do_cmdtest = cb_pcidas_ai_cmdtest;
+ s->cancel = cb_pcidas_cancel;
+
+ /* analog output subdevice */
+ s = dev->subdevices + 1;
+ if (thisboard->ao_nchan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = thisboard->ao_nchan;
+ // analog out resolution is the same as analog input resolution, so use ai_bits
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &cb_pcidas_ao_ranges;
+ s->insn_read = cb_pcidas_ao_readback_insn;
+ if (thisboard->has_ao_fifo) {
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->insn_write = cb_pcidas_ao_fifo_winsn;
+ s->do_cmdtest = cb_pcidas_ao_cmdtest;
+ s->do_cmd = cb_pcidas_ao_cmd;
+ s->cancel = cb_pcidas_ao_cancel;
+ } else {
+ s->insn_write = cb_pcidas_ao_nofifo_winsn;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* 8255 */
+ s = dev->subdevices + 2;
+ subdev_8255_init(dev, s, NULL, devpriv->pacer_counter_dio + DIO_8255);
+
+ // serial EEPROM,
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 256;
+ s->maxdata = 0xff;
+ s->insn_read = eeprom_read_insn;
+
+ // 8800 caldac
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = NUM_CHANNELS_8800;
+ s->maxdata = 0xff;
+ s->insn_read = caldac_read_insn;
+ s->insn_write = caldac_write_insn;
+ for (i = 0; i < s->n_chan; i++)
+ caldac_8800_write(dev, i, s->maxdata / 2);
+
+ // trim potentiometer
+ s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ if (thisboard->trimpot == AD7376) {
+ s->n_chan = NUM_CHANNELS_7376;
+ s->maxdata = 0x7f;
+ } else {
+ s->n_chan = NUM_CHANNELS_8402;
+ s->maxdata = 0xff;
+ }
+ s->insn_read = trimpot_read_insn;
+ s->insn_write = trimpot_write_insn;
+ for (i = 0; i < s->n_chan; i++)
+ cb_pcidas_trimpot_write(dev, i, s->maxdata / 2);
+
+ // dac08 caldac
+ s = dev->subdevices + 6;
+ if (thisboard->has_dac08) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = NUM_CHANNELS_DAC08;
+ s->insn_read = dac08_read_insn;
+ s->insn_write = dac08_write_insn;
+ s->maxdata = 0xff;
+ dac08_write(dev, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // make sure mailbox 4 is empty
+ inl(devpriv->s5933_config + AMCC_OP_REG_IMB4);
+ /* Set bits to enable incoming mailbox interrupts on amcc s5933. */
+ devpriv->s5933_intcsr_bits =
+ INTCSR_INBOX_BYTE(3) | INTCSR_INBOX_SELECT(3) |
+ INTCSR_INBOX_FULL_INT;
+ // clear and enable interrupt on amcc s5933
+ outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+ return 1;
+}
+
+/*
+ * cb_pcidas_detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcidas_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: cb_pcidas: remove\n", dev->minor);
+
+ if (devpriv) {
+ if (devpriv->s5933_config) {
+ // disable and clear interrupts on amcc s5933
+ outl(INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("detaching, incsr is 0x%x\n",
+ inl(devpriv->s5933_config +
+ AMCC_OP_REG_INTCSR));
+#endif
+ }
+ }
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ if (devpriv && devpriv->pci_dev) {
+ if (devpriv->s5933_config) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int cb_pcidas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int bits;
+ static const int timeout = 10000;
+ int channel;
+ // enable calibration input if appropriate
+ if (insn->chanspec & CR_ALT_SOURCE) {
+ outw(cal_enable_bits(dev),
+ devpriv->control_status + CALIBRATION_REG);
+ channel = 0;
+ } else {
+ outw(0, devpriv->control_status + CALIBRATION_REG);
+ channel = CR_CHAN(insn->chanspec);
+ }
+ // set mux limits and gain
+ bits = BEGIN_SCAN(channel) |
+ END_SCAN(channel) | GAIN_BITS(CR_RANGE(insn->chanspec));
+ // set unipolar/bipolar
+ if (CR_RANGE(insn->chanspec) & IS_UNIPOLAR)
+ bits |= UNIP;
+ // set singleended/differential
+ if (CR_AREF(insn->chanspec) != AREF_DIFF)
+ bits |= SE;
+ outw(bits, devpriv->control_status + ADCMUX_CONT);
+
+ /* clear fifo */
+ outw(0, devpriv->adc_fifo + ADCFIFOCLR);
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outw(0, devpriv->adc_fifo + ADCDATA);
+
+ /* wait for conversion to end */
+ /* return -ETIMEDOUT if there is a timeout */
+ for (i = 0; i < timeout; i++) {
+ if (inw(devpriv->control_status + ADCMUX_CONT) & EOC)
+ break;
+ }
+ if (i == timeout)
+ return -ETIMEDOUT;
+
+ /* read data */
+ data[n] = inw(devpriv->adc_fifo + ADCDATA);
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
+{
+ static const int num_calibration_sources = 8;
+ unsigned int source = data[1];
+
+ if (source >= num_calibration_sources) {
+ printk("invalid calibration source: %i\n", source);
+ return -EINVAL;
+ }
+
+ devpriv->calibration_source = source;
+
+ return 2;
+}
+
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int id = data[0];
+
+ switch (id) {
+ case INSN_CONFIG_ALT_SOURCE:
+ return ai_config_calibration_source(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return -EINVAL;
+}
+
+// analog output insn for pcidas-1000 and 1200 series
+static int cb_pcidas_ao_nofifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel;
+ unsigned long flags;
+
+ // set channel and range
+ channel = CR_CHAN(insn->chanspec);
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->ao_control_bits &=
+ ~DAC_MODE_UPDATE_BOTH & ~DAC_RANGE_MASK(channel);
+ devpriv->ao_control_bits |=
+ DACEN | DAC_RANGE(channel, CR_RANGE(insn->chanspec));
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // remember value for readback
+ devpriv->ao_value[channel] = data[0];
+ // send data
+ outw(data[0], devpriv->ao_registers + DAC_DATA_REG(channel));
+
+ return 1;
+}
+
+// analog output insn for pcidas-1602 series
+static int cb_pcidas_ao_fifo_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel;
+ unsigned long flags;
+
+ // clear dac fifo
+ outw(0, devpriv->ao_registers + DACFIFOCLR);
+
+ // set channel and range
+ channel = CR_CHAN(insn->chanspec);
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->ao_control_bits &=
+ ~DAC_CHAN_EN(0) & ~DAC_CHAN_EN(1) & ~DAC_RANGE_MASK(channel) &
+ ~DAC_PACER_MASK;
+ devpriv->ao_control_bits |=
+ DACEN | DAC_RANGE(channel,
+ CR_RANGE(insn->chanspec)) | DAC_CHAN_EN(channel) | DAC_START;
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // remember value for readback
+ devpriv->ao_value[channel] = data[0];
+ // send data
+ outw(data[0], devpriv->ao_registers + DACDATA);
+
+ return 1;
+}
+
+// analog output readback insn
+// XXX loses track of analog output value back after an analog ouput command is executed
+static int cb_pcidas_ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ uint8_t nvram_data;
+ int retval;
+
+ retval = nvram_read(dev, CR_CHAN(insn->chanspec), &nvram_data);
+ if (retval < 0)
+ return retval;
+
+ data[0] = nvram_data;
+
+ return 1;
+}
+
+static int caldac_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const unsigned int channel = CR_CHAN(insn->chanspec);
+
+ return caldac_8800_write(dev, channel, data[0]);
+}
+
+static int caldac_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->caldac_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+/* 1602/16 pregain offset */
+static int dac08_write(struct comedi_device * dev, unsigned int value)
+{
+ if (devpriv->dac08_value == value)
+ return 1;
+
+ devpriv->dac08_value = value;
+
+ outw(cal_enable_bits(dev) | (value & 0xff),
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(1);
+ outw(cal_enable_bits(dev) | SELECT_DAC08_BIT | (value & 0xff),
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(1);
+ outw(cal_enable_bits(dev) | (value & 0xff),
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(1);
+
+ return 1;
+}
+
+static int dac08_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return dac08_write(dev, data[0]);
+}
+
+static int dac08_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->dac08_value;
+
+ return 1;
+}
+
+static int cb_pcidas_trimpot_write(struct comedi_device * dev,
+ unsigned int channel, unsigned int value)
+{
+ if (devpriv->trimpot_value[channel] == value)
+ return 1;
+
+ devpriv->trimpot_value[channel] = value;
+ switch (thisboard->trimpot) {
+ case AD7376:
+ trimpot_7376_write(dev, value);
+ break;
+ case AD8402:
+ trimpot_8402_write(dev, channel, value);
+ break;
+ default:
+ comedi_error(dev, "driver bug?");
+ return -1;
+ break;
+ }
+
+ return 1;
+}
+
+static int trimpot_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ return cb_pcidas_trimpot_write(dev, channel, data[0]);
+}
+
+static int trimpot_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ data[0] = devpriv->trimpot_value[channel];
+
+ return 1;
+}
+
+static int cb_pcidas_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int i, gain, start_chan;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_NOW | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ // make sure trigger sources are compatible with each other
+ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->start_src == TRIG_EXT &&
+ (cmd->convert_src == TRIG_EXT
+ || cmd->scan_begin_src == TRIG_EXT))
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg <
+ thisboard->ai_speed * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ thisboard->ai_speed * cmd->chanlist_len;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ start_chan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (start_chan + i) % s->n_chan) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int cb_pcidas_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int bits;
+ unsigned long flags;
+
+ // make sure CAL_EN_BIT is disabled
+ outw(0, devpriv->control_status + CALIBRATION_REG);
+ // initialize before settings pacer source and count values
+ outw(0, devpriv->control_status + TRIG_CONTSTAT);
+ // clear fifo
+ outw(0, devpriv->adc_fifo + ADCFIFOCLR);
+
+ // set mux limits, gain and pacer source
+ bits = BEGIN_SCAN(CR_CHAN(cmd->chanlist[0])) |
+ END_SCAN(CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1])) |
+ GAIN_BITS(CR_RANGE(cmd->chanlist[0]));
+ // set unipolar/bipolar
+ if (CR_RANGE(cmd->chanlist[0]) & IS_UNIPOLAR)
+ bits |= UNIP;
+ // set singleended/differential
+ if (CR_AREF(cmd->chanlist[0]) != AREF_DIFF)
+ bits |= SE;
+ // set pacer source
+ if (cmd->convert_src == TRIG_EXT || cmd->scan_begin_src == TRIG_EXT)
+ bits |= PACER_EXT_RISE;
+ else
+ bits |= PACER_INT;
+ outw(bits, devpriv->control_status + ADCMUX_CONT);
+
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: sent 0x%x to adcmux control\n", bits);
+#endif
+
+ // load counters
+ if (cmd->convert_src == TRIG_TIMER)
+ cb_pcidas_load_counters(dev, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ else if (cmd->scan_begin_src == TRIG_TIMER)
+ cb_pcidas_load_counters(dev, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+
+ // set number of conversions
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->count = cmd->chanlist_len * cmd->stop_arg;
+ }
+ // enable interrupts
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->adc_fifo_bits |= INTE;
+ devpriv->adc_fifo_bits &= ~INT_MASK;
+ if (cmd->flags & TRIG_WAKE_EOS) {
+ if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
+ devpriv->adc_fifo_bits |= INT_EOS; // interrupt end of burst
+ else
+ devpriv->adc_fifo_bits |= INT_FNE; // interrupt fifo not empty
+ } else {
+ devpriv->adc_fifo_bits |= INT_FHF; //interrupt fifo half full
+ }
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+#endif
+ // enable (and clear) interrupts
+ outw(devpriv->adc_fifo_bits | EOAI | INT | LADFUL,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // set start trigger and burst mode
+ bits = 0;
+ if (cmd->start_src == TRIG_NOW)
+ bits |= SW_TRIGGER;
+ else if (cmd->start_src == TRIG_EXT)
+ bits |= EXT_TRIGGER | TGEN | XTRCL;
+ else {
+ comedi_error(dev, "bug!");
+ return -1;
+ }
+ if (cmd->convert_src == TRIG_NOW && cmd->chanlist_len > 1)
+ bits |= BURSTE;
+ outw(bits, devpriv->control_status + TRIG_CONTSTAT);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: sent 0x%x to trig control\n", bits);
+#endif
+
+ return 0;
+}
+
+static int cb_pcidas_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < thisboard->ao_scan_speed) {
+ cmd->scan_begin_arg = thisboard->ao_scan_speed;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
+ &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist && cmd->chanlist_len > 1) {
+ if (CR_CHAN(cmd->chanlist[0]) != 0 ||
+ CR_CHAN(cmd->chanlist[1]) != 1) {
+ comedi_error(dev,
+ "channels must be ordered channel 0, channel 1 in chanlist\n");
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int cb_pcidas_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int i;
+ unsigned long flags;
+
+ // set channel limits, gain
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ // enable channel
+ devpriv->ao_control_bits |=
+ DAC_CHAN_EN(CR_CHAN(cmd->chanlist[i]));
+ // set range
+ devpriv->ao_control_bits |= DAC_RANGE(CR_CHAN(cmd->chanlist[i]),
+ CR_RANGE(cmd->chanlist[i]));
+ }
+
+ // disable analog out before settings pacer source and count values
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // clear fifo
+ outw(0, devpriv->ao_registers + DACFIFOCLR);
+
+ // load counters
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->ao_divisor1), &(devpriv->ao_divisor2),
+ &(cmd->scan_begin_arg), cmd->flags);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 1,
+ devpriv->ao_divisor1, 2);
+ i8254_load(devpriv->pacer_counter_dio + DAC8254, 0, 2,
+ devpriv->ao_divisor2, 2);
+ }
+ // set number of conversions
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ao_count = cmd->chanlist_len * cmd->stop_arg;
+ }
+ // set pacer source
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->ao_control_bits |= DAC_PACER_INT;
+ break;
+ case TRIG_EXT:
+ devpriv->ao_control_bits |= DAC_PACER_EXT_RISE;
+ break;
+ default:
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ comedi_error(dev, "error setting dac pacer source");
+ return -1;
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ async->inttrig = cb_pcidas_ao_inttrig;
+
+ return 0;
+}
+
+static int cb_pcidas_ao_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ unsigned int trig_num)
+{
+ unsigned int num_bytes, num_points = thisboard->fifo_size;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ // load up fifo
+ if (cmd->stop_src == TRIG_COUNT && devpriv->ao_count < num_points)
+ num_points = devpriv->ao_count;
+
+ num_bytes = cfc_read_array_from_buffer(s, devpriv->ao_buffer,
+ num_points * sizeof(short));
+ num_points = num_bytes / sizeof(short);
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ao_count -= num_points;
+ }
+ // write data to board's fifo
+ outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer, num_bytes);
+
+ // enable dac half-full and empty interrupts
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->adc_fifo_bits |= DAEMIE | DAHFIE;
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: adc_fifo_bits are 0x%x\n", devpriv->adc_fifo_bits);
+#endif
+ // enable and clear interrupts
+ outw(devpriv->adc_fifo_bits | DAEMI | DAHFI,
+ devpriv->control_status + INT_ADCFIFO);
+
+ // start dac
+ devpriv->ao_control_bits |= DAC_START | DACEN | DAC_EMPTY;
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("comedi: sent 0x%x to dac control\n",
+ devpriv->ao_control_bits);
+#endif
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ async->inttrig = NULL;
+
+ return 0;
+}
+
+static irqreturn_t cb_pcidas_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ int status, s5933_status;
+ int half_fifo = thisboard->fifo_size / 2;
+ unsigned int num_samples, i;
+ static const int timeout = 10000;
+ unsigned long flags;
+
+ if (dev->attached == 0) {
+ return IRQ_NONE;
+ }
+
+ async = s->async;
+ async->events = 0;
+
+ s5933_status = inl(devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+#ifdef CB_PCIDAS_DEBUG
+ rt_printk("intcsr 0x%x\n", s5933_status);
+ rt_printk("mbef 0x%x\n", inl(devpriv->s5933_config + AMCC_OP_REG_MBEF));
+#endif
+
+ if ((INTCSR_INTR_ASSERTED & s5933_status) == 0)
+ return IRQ_NONE;
+
+ // make sure mailbox 4 is empty
+ inl_p(devpriv->s5933_config + AMCC_OP_REG_IMB4);
+ // clear interrupt on amcc s5933
+ outl(devpriv->s5933_intcsr_bits | INTCSR_INBOX_INTR_STATUS,
+ devpriv->s5933_config + AMCC_OP_REG_INTCSR);
+
+ status = inw(devpriv->control_status + INT_ADCFIFO);
+#ifdef CB_PCIDAS_DEBUG
+ if ((status & (INT | EOAI | LADFUL | DAHFI | DAEMI)) == 0) {
+ comedi_error(dev, "spurious interrupt");
+ }
+#endif
+
+ // check for analog output interrupt
+ if (status & (DAHFI | DAEMI)) {
+ handle_ao_interrupt(dev, status);
+ }
+ // check for analog input interrupts
+ // if fifo half-full
+ if (status & ADHFI) {
+ // read data
+ num_samples = half_fifo;
+ if (async->cmd.stop_src == TRIG_COUNT &&
+ num_samples > devpriv->count) {
+ num_samples = devpriv->count;
+ }
+ insw(devpriv->adc_fifo + ADCDATA, devpriv->ai_buffer,
+ num_samples);
+ cfc_write_array_to_buffer(s, devpriv->ai_buffer,
+ num_samples * sizeof(short));
+ devpriv->count -= num_samples;
+ if (async->cmd.stop_src == TRIG_COUNT && devpriv->count == 0) {
+ async->events |= COMEDI_CB_EOA;
+ cb_pcidas_cancel(dev, s);
+ }
+ // clear half-full interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | INT,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ // else if fifo not empty
+ } else if (status & (ADNEI | EOBI)) {
+ for (i = 0; i < timeout; i++) {
+ // break if fifo is empty
+ if ((ADNE & inw(devpriv->control_status +
+ INT_ADCFIFO)) == 0)
+ break;
+ cfc_write_to_buffer(s, inw(devpriv->adc_fifo));
+ if (async->cmd.stop_src == TRIG_COUNT && --devpriv->count == 0) { /* end of acquisition */
+ cb_pcidas_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+ // clear not-empty interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | INT,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ } else if (status & EOAI) {
+ comedi_error(dev,
+ "bug! encountered end of aquisition interrupt?");
+ // clear EOA interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | EOAI,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ }
+ //check for fifo overflow
+ if (status & LADFUL) {
+ comedi_error(dev, "fifo overflow");
+ // clear overflow interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | LADFUL,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ cb_pcidas_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+
+ comedi_event(dev, s);
+
+ return IRQ_HANDLED;
+}
+
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned int status)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int half_fifo = thisboard->fifo_size / 2;
+ unsigned int num_points;
+ unsigned int flags;
+
+ async->events = 0;
+
+ if (status & DAEMI) {
+ // clear dac empty interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | DAEMI,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ if (inw(devpriv->ao_registers + DAC_CSR) & DAC_EMPTY) {
+ if (cmd->stop_src == TRIG_NONE ||
+ (cmd->stop_src == TRIG_COUNT
+ && devpriv->ao_count)) {
+ comedi_error(dev, "dac fifo underflow");
+ cb_pcidas_ao_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR;
+ }
+ async->events |= COMEDI_CB_EOA;
+ }
+ } else if (status & DAHFI) {
+ unsigned int num_bytes;
+
+ // figure out how many points we are writing to fifo
+ num_points = half_fifo;
+ if (cmd->stop_src == TRIG_COUNT &&
+ devpriv->ao_count < num_points)
+ num_points = devpriv->ao_count;
+ num_bytes =
+ cfc_read_array_from_buffer(s, devpriv->ao_buffer,
+ num_points * sizeof(short));
+ num_points = num_bytes / sizeof(short);
+
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ devpriv->ao_count -= num_points;
+ }
+ // write data to board's fifo
+ outsw(devpriv->ao_registers + DACDATA, devpriv->ao_buffer,
+ num_points);
+ // clear half-full interrupt latch
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ outw(devpriv->adc_fifo_bits | DAHFI,
+ devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ }
+
+ comedi_event(dev, s);
+}
+
+/* cancel analog input command */
+static int cb_pcidas_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ // disable interrupts
+ devpriv->adc_fifo_bits &= ~INTE & ~EOAIE;
+ outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // disable start trigger source and burst mode
+ outw(0, devpriv->control_status + TRIG_CONTSTAT);
+ // software pacer source
+ outw(0, devpriv->control_status + ADCMUX_CONT);
+
+ return 0;
+}
+
+/* cancel analog output command */
+static int cb_pcidas_ao_cancel(struct comedi_device *dev,
+ struct comedi_subdevice *s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ // disable interrupts
+ devpriv->adc_fifo_bits &= ~DAHFIE & ~DAEMIE;
+ outw(devpriv->adc_fifo_bits, devpriv->control_status + INT_ADCFIFO);
+
+ // disable output
+ devpriv->ao_control_bits &= ~DACEN & ~DAC_PACER_MASK;
+ outw(devpriv->ao_control_bits, devpriv->control_status + DAC_CSR);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return 0;
+}
+
+static void cb_pcidas_load_counters(struct comedi_device * dev, unsigned int *ns,
+ int rounding_flags)
+{
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), ns, rounding_flags & TRIG_ROUND_MASK);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 1,
+ devpriv->divisor1, 2);
+ i8254_load(devpriv->pacer_counter_dio + ADC8254, 0, 2,
+ devpriv->divisor2, 2);
+}
+
+static void write_calibration_bitstream(struct comedi_device * dev,
+ unsigned int register_bits, unsigned int bitstream,
+ unsigned int bitstream_length)
+{
+ static const int write_delay = 1;
+ unsigned int bit;
+
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ if (bitstream & bit)
+ register_bits |= SERIAL_DATA_IN_BIT;
+ else
+ register_bits &= ~SERIAL_DATA_IN_BIT;
+ comedi_udelay(write_delay);
+ outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+ }
+}
+
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value)
+{
+ static const int num_caldac_channels = 8;
+ static const int bitstream_length = 11;
+ unsigned int bitstream = ((address & 0x7) << 8) | value;
+ static const int caldac_8800_comedi_udelay = 1;
+
+ if (address >= num_caldac_channels) {
+ comedi_error(dev, "illegal caldac channel");
+ return -1;
+ }
+
+ if (value == devpriv->caldac_value[address])
+ return 1;
+
+ devpriv->caldac_value[address] = value;
+
+ write_calibration_bitstream(dev, cal_enable_bits(dev), bitstream,
+ bitstream_length);
+
+ comedi_udelay(caldac_8800_comedi_udelay);
+ outw(cal_enable_bits(dev) | SELECT_8800_BIT,
+ devpriv->control_status + CALIBRATION_REG);
+ comedi_udelay(caldac_8800_comedi_udelay);
+ outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+ return 1;
+}
+
+static int trimpot_7376_write(struct comedi_device * dev, uint8_t value)
+{
+ static const int bitstream_length = 7;
+ unsigned int bitstream = value & 0x7f;
+ unsigned int register_bits;
+ static const int ad7376_comedi_udelay = 1;
+
+ register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
+ comedi_udelay(ad7376_comedi_udelay);
+ outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+
+ write_calibration_bitstream(dev, register_bits, bitstream,
+ bitstream_length);
+
+ comedi_udelay(ad7376_comedi_udelay);
+ outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+ return 0;
+}
+
+/* For 1602/16 only
+ * ch 0 : adc gain
+ * ch 1 : adc postgain offset */
+static int trimpot_8402_write(struct comedi_device * dev, unsigned int channel,
+ uint8_t value)
+{
+ static const int bitstream_length = 10;
+ unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
+ unsigned int register_bits;
+ static const int ad8402_comedi_udelay = 1;
+
+ register_bits = cal_enable_bits(dev) | SELECT_TRIMPOT_BIT;
+ comedi_udelay(ad8402_comedi_udelay);
+ outw(register_bits, devpriv->control_status + CALIBRATION_REG);
+
+ write_calibration_bitstream(dev, register_bits, bitstream,
+ bitstream_length);
+
+ comedi_udelay(ad8402_comedi_udelay);
+ outw(cal_enable_bits(dev), devpriv->control_status + CALIBRATION_REG);
+
+ return 0;
+}
+
+static int wait_for_nvram_ready(unsigned long s5933_base_addr)
+{
+ static const int timeout = 1000;
+ unsigned int i;
+
+ for (i = 0; i < timeout; i++) {
+ if ((inb(s5933_base_addr +
+ AMCC_OP_REG_MCSR_NVCMD) & MCSR_NV_BUSY)
+ == 0)
+ return 0;
+ comedi_udelay(1);
+ }
+ return -1;
+}
+
+static int nvram_read(struct comedi_device * dev, unsigned int address, uint8_t * data)
+{
+ unsigned long iobase = devpriv->s5933_config;
+
+ if (wait_for_nvram_ready(iobase) < 0)
+ return -ETIMEDOUT;
+
+ outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_LOW_ADDR,
+ iobase + AMCC_OP_REG_MCSR_NVCMD);
+ outb(address & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+ outb(MCSR_NV_ENABLE | MCSR_NV_LOAD_HIGH_ADDR,
+ iobase + AMCC_OP_REG_MCSR_NVCMD);
+ outb((address >> 8) & 0xff, iobase + AMCC_OP_REG_MCSR_NVDATA);
+ outb(MCSR_NV_ENABLE | MCSR_NV_READ, iobase + AMCC_OP_REG_MCSR_NVCMD);
+
+ if (wait_for_nvram_ready(iobase) < 0)
+ return -ETIMEDOUT;
+
+ *data = inb(iobase + AMCC_OP_REG_MCSR_NVDATA);
+
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, cb_pcidas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidas64.c b/drivers/staging/comedi/drivers/cb_pcidas64.c
new file mode 100644
index 00000000000..1a580bd2247
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidas64.c
@@ -0,0 +1,4222 @@
+/*
+ comedi/drivers/cb_pcidas64.c
+ This is a driver for the ComputerBoards/MeasurementComputing PCI-DAS
+ 64xx, 60xx, and 4020 cards.
+
+ Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2001, 2002 Frank Mori Hess
+
+ Thanks also go to the following people:
+
+ Steve Rosenbluth, for providing the source code for
+ his pci-das6402 driver, and source code for working QNX pci-6402
+ drivers by Greg Laird and Mariusz Bogacz. None of the code was
+ used directly here, but it was useful as an additional source of
+ documentation on how to program the boards.
+
+ John Sims, for much testing and feedback on pcidas-4020 support.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************/
+
+/*
+
+Driver: cb_pcidas64
+Description: MeasurementComputing PCI-DAS64xx, 60XX, and 4020 series with the PLX 9080 PCI controller
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: works
+Updated: 2002-10-09
+Devices: [Measurement Computing] PCI-DAS6402/16 (cb_pcidas64),
+ PCI-DAS6402/12, PCI-DAS64/M1/16, PCI-DAS64/M2/16,
+ PCI-DAS64/M3/16, PCI-DAS6402/16/JR, PCI-DAS64/M1/16/JR,
+ PCI-DAS64/M2/16/JR, PCI-DAS64/M3/16/JR, PCI-DAS64/M1/14,
+ PCI-DAS64/M2/14, PCI-DAS64/M3/14, PCI-DAS6013, PCI-DAS6014,
+ PCI-DAS6023, PCI-DAS6025, PCI-DAS6030,
+ PCI-DAS6031, PCI-DAS6032, PCI-DAS6033, PCI-DAS6034,
+ PCI-DAS6035, PCI-DAS6036, PCI-DAS6040, PCI-DAS6052,
+ PCI-DAS6070, PCI-DAS6071, PCI-DAS4020/12
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+
+These boards may be autocalibrated with the comedi_calibrate utility.
+
+To select the bnc trigger input on the 4020 (instead of the dio input),
+specify a nonzero channel in the chanspec. If you wish to use an external
+master clock on the 4020, you may do so by setting the scan_begin_src
+to TRIG_OTHER, and using an INSN_CONFIG_TIMER_1 configuration insn
+to configure the divisor to use for the external clock.
+
+Some devices are not identified because the PCI device IDs are not yet
+known. If you have such a board, please file a bug report at
+https://bugs.comedi.org.
+
+*/
+
+/*
+
+TODO:
+ make it return error if user attempts an ai command that uses the
+ external queue, and an ao command simultaneously
+ user counter subdevice
+ there are a number of boards this driver will support when they are
+ fully released, but does not yet since the pci device id numbers
+ are not yet available.
+ support prescaled 100khz clock for slow pacing (not available on 6000 series?)
+ make ao fifo size adjustable like ai fifo
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <asm/system.h>
+
+#include "comedi_pci.h"
+#include "8253.h"
+#include "8255.h"
+#include "plx9080.h"
+#include "comedi_fc.h"
+
+#undef PCIDAS64_DEBUG // disable debugging code
+//#define PCIDAS64_DEBUG // enable debugging code
+
+#ifdef PCIDAS64_DEBUG
+#define DEBUG_PRINT(format, args...) rt_printk(format , ## args )
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define TIMER_BASE 25 // 40MHz master clock
+#define PRESCALED_TIMER_BASE 10000 // 100kHz 'prescaled' clock for slow aquisition, maybe I'll support this someday
+#define DMA_BUFFER_SIZE 0x1000
+
+/* maximum value that can be loaded into board's 24-bit counters*/
+static const int max_counter_value = 0xffffff;
+
+/* PCI-DAS64xxx base addresses */
+
+// indices of base address regions
+enum base_address_regions {
+ PLX9080_BADDRINDEX = 0,
+ MAIN_BADDRINDEX = 2,
+ DIO_COUNTER_BADDRINDEX = 3,
+};
+
+// priv(dev)->main_iobase registers
+enum write_only_registers {
+ INTR_ENABLE_REG = 0x0, // interrupt enable register
+ HW_CONFIG_REG = 0x2, // hardware config register
+ DAQ_SYNC_REG = 0xc,
+ DAQ_ATRIG_LOW_4020_REG = 0xc,
+ ADC_CONTROL0_REG = 0x10, // adc control register 0
+ ADC_CONTROL1_REG = 0x12, // adc control register 1
+ CALIBRATION_REG = 0x14,
+ ADC_SAMPLE_INTERVAL_LOWER_REG = 0x16, // lower 16 bits of adc sample interval counter
+ ADC_SAMPLE_INTERVAL_UPPER_REG = 0x18, // upper 8 bits of adc sample interval counter
+ ADC_DELAY_INTERVAL_LOWER_REG = 0x1a, // lower 16 bits of delay interval counter
+ ADC_DELAY_INTERVAL_UPPER_REG = 0x1c, // upper 8 bits of delay interval counter
+ ADC_COUNT_LOWER_REG = 0x1e, // lower 16 bits of hardware conversion/scan counter
+ ADC_COUNT_UPPER_REG = 0x20, // upper 8 bits of hardware conversion/scan counter
+ ADC_START_REG = 0x22, // software trigger to start aquisition
+ ADC_CONVERT_REG = 0x24, // initiates single conversion
+ ADC_QUEUE_CLEAR_REG = 0x26, // clears adc queue
+ ADC_QUEUE_LOAD_REG = 0x28, // loads adc queue
+ ADC_BUFFER_CLEAR_REG = 0x2a,
+ ADC_QUEUE_HIGH_REG = 0x2c, // high channel for internal queue, use adc_chan_bits() inline above
+ DAC_CONTROL0_REG = 0x50, // dac control register 0
+ DAC_CONTROL1_REG = 0x52, // dac control register 0
+ DAC_SAMPLE_INTERVAL_LOWER_REG = 0x54, // lower 16 bits of dac sample interval counter
+ DAC_SAMPLE_INTERVAL_UPPER_REG = 0x56, // upper 8 bits of dac sample interval counter
+ DAC_SELECT_REG = 0x60,
+ DAC_START_REG = 0x64,
+ DAC_BUFFER_CLEAR_REG = 0x66, // clear dac buffer
+};
+static inline unsigned int dac_convert_reg(unsigned int channel)
+{
+ return 0x70 + (2 * (channel & 0x1));
+}
+static inline unsigned int dac_lsb_4020_reg(unsigned int channel)
+{
+ return 0x70 + (4 * (channel & 0x1));
+}
+static inline unsigned int dac_msb_4020_reg(unsigned int channel)
+{
+ return 0x72 + (4 * (channel & 0x1));
+}
+
+enum read_only_registers {
+ HW_STATUS_REG = 0x0, // hardware status register, reading this apparently clears pending interrupts as well
+ PIPE1_READ_REG = 0x4,
+ ADC_READ_PNTR_REG = 0x8,
+ LOWER_XFER_REG = 0x10,
+ ADC_WRITE_PNTR_REG = 0xc,
+ PREPOST_REG = 0x14,
+};
+
+enum read_write_registers {
+ I8255_4020_REG = 0x48, // 8255 offset, for 4020 only
+ ADC_QUEUE_FIFO_REG = 0x100, // external channel/gain queue, uses same bits as ADC_QUEUE_LOAD_REG
+ ADC_FIFO_REG = 0x200, /* adc data fifo */
+ DAC_FIFO_REG = 0x300, /* dac data fifo, has weird interactions with external channel queue */
+};
+
+// priv(dev)->dio_counter_iobase registers
+enum dio_counter_registers {
+ DIO_8255_OFFSET = 0x0,
+ DO_REG = 0x20,
+ DI_REG = 0x28,
+ DIO_DIRECTION_60XX_REG = 0x40,
+ DIO_DATA_60XX_REG = 0x48,
+};
+
+// bit definitions for write-only registers
+
+enum intr_enable_contents {
+ ADC_INTR_SRC_MASK = 0x3, // bits that set adc interrupt source
+ ADC_INTR_QFULL_BITS = 0x0, // interrupt fifo quater full
+ ADC_INTR_EOC_BITS = 0x1, // interrupt end of conversion
+ ADC_INTR_EOSCAN_BITS = 0x2, // interrupt end of scan
+ ADC_INTR_EOSEQ_BITS = 0x3, // interrupt end of sequence (probably wont use this it's pretty fancy)
+ EN_ADC_INTR_SRC_BIT = 0x4, // enable adc interrupt source
+ EN_ADC_DONE_INTR_BIT = 0x8, // enable adc aquisition done interrupt
+ DAC_INTR_SRC_MASK = 0x30,
+ DAC_INTR_QEMPTY_BITS = 0x0,
+ DAC_INTR_HIGH_CHAN_BITS = 0x10,
+ EN_DAC_INTR_SRC_BIT = 0x40, // enable dac interrupt source
+ EN_DAC_DONE_INTR_BIT = 0x80,
+ EN_ADC_ACTIVE_INTR_BIT = 0x200, // enable adc active interrupt
+ EN_ADC_STOP_INTR_BIT = 0x400, // enable adc stop trigger interrupt
+ EN_DAC_ACTIVE_INTR_BIT = 0x800, // enable dac active interrupt
+ EN_DAC_UNDERRUN_BIT = 0x4000, // enable dac underrun status bit
+ EN_ADC_OVERRUN_BIT = 0x8000, // enable adc overrun status bit
+};
+
+enum hw_config_contents {
+ MASTER_CLOCK_4020_MASK = 0x3, // bits that specify master clock source for 4020
+ INTERNAL_CLOCK_4020_BITS = 0x1, // use 40 MHz internal master clock for 4020
+ BNC_CLOCK_4020_BITS = 0x2, // use BNC input for master clock
+ EXT_CLOCK_4020_BITS = 0x3, // use dio input for master clock
+ EXT_QUEUE_BIT = 0x200, // use external channel/gain queue (more versatile than internal queue)
+ SLOW_DAC_BIT = 0x400, // use 225 nanosec strobe when loading dac instead of 50 nanosec
+ HW_CONFIG_DUMMY_BITS = 0x2000, // bit with unknown function yet given as default value in pci-das64 manual
+ DMA_CH_SELECT_BIT = 0x8000, // bit selects channels 1/0 for analog input/output, otherwise 0/1
+ FIFO_SIZE_REG = 0x4, // allows adjustment of fifo sizes
+ DAC_FIFO_SIZE_MASK = 0xff00, // bits that set dac fifo size
+ DAC_FIFO_BITS = 0xf800, /* 8k sample ao fifo */
+};
+#define DAC_FIFO_SIZE 0x2000
+
+enum daq_atrig_low_4020_contents {
+ EXT_AGATE_BNC_BIT = 0x8000, // use trig/ext clk bnc input for analog gate signal
+ EXT_STOP_TRIG_BNC_BIT = 0x4000, // use trig/ext clk bnc input for external stop trigger signal
+ EXT_START_TRIG_BNC_BIT = 0x2000, // use trig/ext clk bnc input for external start trigger signal
+};
+static inline uint16_t analog_trig_low_threshold_bits(uint16_t threshold)
+{
+ return threshold & 0xfff;
+}
+
+enum adc_control0_contents {
+ ADC_GATE_SRC_MASK = 0x3, // bits that select gate
+ ADC_SOFT_GATE_BITS = 0x1, // software gate
+ ADC_EXT_GATE_BITS = 0x2, // external digital gate
+ ADC_ANALOG_GATE_BITS = 0x3, // analog level gate
+ ADC_GATE_LEVEL_BIT = 0x4, // level-sensitive gate (for digital)
+ ADC_GATE_POLARITY_BIT = 0x8, // gate active low
+ ADC_START_TRIG_SOFT_BITS = 0x10,
+ ADC_START_TRIG_EXT_BITS = 0x20,
+ ADC_START_TRIG_ANALOG_BITS = 0x30,
+ ADC_START_TRIG_MASK = 0x30,
+ ADC_START_TRIG_FALLING_BIT = 0x40, // trig 1 uses falling edge
+ ADC_EXT_CONV_FALLING_BIT = 0x800, // external pacing uses falling edge
+ ADC_SAMPLE_COUNTER_EN_BIT = 0x1000, // enable hardware scan counter
+ ADC_DMA_DISABLE_BIT = 0x4000, // disables dma
+ ADC_ENABLE_BIT = 0x8000, // master adc enable
+};
+
+enum adc_control1_contents {
+ ADC_QUEUE_CONFIG_BIT = 0x1, // should be set for boards with > 16 channels
+ CONVERT_POLARITY_BIT = 0x10,
+ EOC_POLARITY_BIT = 0x20,
+ ADC_SW_GATE_BIT = 0x40, // software gate of adc
+ ADC_DITHER_BIT = 0x200, // turn on extra noise for dithering
+ RETRIGGER_BIT = 0x800,
+ ADC_LO_CHANNEL_4020_MASK = 0x300,
+ ADC_HI_CHANNEL_4020_MASK = 0xc00,
+ TWO_CHANNEL_4020_BITS = 0x1000, // two channel mode for 4020
+ FOUR_CHANNEL_4020_BITS = 0x2000, // four channel mode for 4020
+ CHANNEL_MODE_4020_MASK = 0x3000,
+ ADC_MODE_MASK = 0xf000,
+};
+static inline uint16_t adc_lo_chan_4020_bits(unsigned int channel)
+{
+ return (channel & 0x3) << 8;
+};
+static inline uint16_t adc_hi_chan_4020_bits(unsigned int channel)
+{
+ return (channel & 0x3) << 10;
+};
+static inline uint16_t adc_mode_bits(unsigned int mode)
+{
+ return (mode & 0xf) << 12;
+};
+
+enum calibration_contents {
+ SELECT_8800_BIT = 0x1,
+ SELECT_8402_64XX_BIT = 0x2,
+ SELECT_1590_60XX_BIT = 0x2,
+ CAL_EN_64XX_BIT = 0x40, // calibration enable for 64xx series
+ SERIAL_DATA_IN_BIT = 0x80,
+ SERIAL_CLOCK_BIT = 0x100,
+ CAL_EN_60XX_BIT = 0x200, // calibration enable for 60xx series
+ CAL_GAIN_BIT = 0x800,
+};
+/* calibration sources for 6025 are:
+ * 0 : ground
+ * 1 : 10V
+ * 2 : 5V
+ * 3 : 0.5V
+ * 4 : 0.05V
+ * 5 : ground
+ * 6 : dac channel 0
+ * 7 : dac channel 1
+ */
+static inline uint16_t adc_src_bits(unsigned int source)
+{
+ return (source & 0xf) << 3;
+};
+
+static inline uint16_t adc_convert_chan_4020_bits(unsigned int channel)
+{
+ return (channel & 0x3) << 8;
+};
+
+enum adc_queue_load_contents {
+ UNIP_BIT = 0x800, // unipolar/bipolar bit
+ ADC_SE_DIFF_BIT = 0x1000, // single-ended/ differential bit
+ ADC_COMMON_BIT = 0x2000, // non-referenced single-ended (common-mode input)
+ QUEUE_EOSEQ_BIT = 0x4000, // queue end of sequence
+ QUEUE_EOSCAN_BIT = 0x8000, // queue end of scan
+};
+static inline uint16_t adc_chan_bits(unsigned int channel)
+{
+ return channel & 0x3f;
+};
+
+enum dac_control0_contents {
+ DAC_ENABLE_BIT = 0x8000, // dac controller enable bit
+ DAC_CYCLIC_STOP_BIT = 0x4000,
+ DAC_WAVEFORM_MODE_BIT = 0x100,
+ DAC_EXT_UPDATE_FALLING_BIT = 0x80,
+ DAC_EXT_UPDATE_ENABLE_BIT = 0x40,
+ WAVEFORM_TRIG_MASK = 0x30,
+ WAVEFORM_TRIG_DISABLED_BITS = 0x0,
+ WAVEFORM_TRIG_SOFT_BITS = 0x10,
+ WAVEFORM_TRIG_EXT_BITS = 0x20,
+ WAVEFORM_TRIG_ADC1_BITS = 0x30,
+ WAVEFORM_TRIG_FALLING_BIT = 0x8,
+ WAVEFORM_GATE_LEVEL_BIT = 0x4,
+ WAVEFORM_GATE_ENABLE_BIT = 0x2,
+ WAVEFORM_GATE_SELECT_BIT = 0x1,
+};
+
+enum dac_control1_contents {
+ DAC_WRITE_POLARITY_BIT = 0x800, /* board-dependent setting */
+ DAC1_EXT_REF_BIT = 0x200,
+ DAC0_EXT_REF_BIT = 0x100,
+ DAC_OUTPUT_ENABLE_BIT = 0x80, // dac output enable bit
+ DAC_UPDATE_POLARITY_BIT = 0x40, /* board-dependent setting */
+ DAC_SW_GATE_BIT = 0x20,
+ DAC1_UNIPOLAR_BIT = 0x8,
+ DAC0_UNIPOLAR_BIT = 0x2,
+};
+
+// bit definitions for read-only registers
+enum hw_status_contents {
+ DAC_UNDERRUN_BIT = 0x1,
+ ADC_OVERRUN_BIT = 0x2,
+ DAC_ACTIVE_BIT = 0x4,
+ ADC_ACTIVE_BIT = 0x8,
+ DAC_INTR_PENDING_BIT = 0x10,
+ ADC_INTR_PENDING_BIT = 0x20,
+ DAC_DONE_BIT = 0x40,
+ ADC_DONE_BIT = 0x80,
+ EXT_INTR_PENDING_BIT = 0x100,
+ ADC_STOP_BIT = 0x200,
+};
+static inline uint16_t pipe_full_bits(uint16_t hw_status_bits)
+{
+ return (hw_status_bits >> 10) & 0x3;
+};
+
+static inline unsigned int dma_chain_flag_bits(uint16_t prepost_bits)
+{
+ return (prepost_bits >> 6) & 0x3;
+}
+static inline unsigned int adc_upper_read_ptr_code(uint16_t prepost_bits)
+{
+ return (prepost_bits >> 12) & 0x3;
+}
+static inline unsigned int adc_upper_write_ptr_code(uint16_t prepost_bits)
+{
+ return (prepost_bits >> 14) & 0x3;
+}
+
+// I2C addresses for 4020
+enum i2c_addresses {
+ RANGE_CAL_I2C_ADDR = 0x20,
+ CALDAC0_I2C_ADDR = 0xc,
+ CALDAC1_I2C_ADDR = 0xd,
+};
+
+enum range_cal_i2c_contents {
+ ADC_SRC_4020_MASK = 0x70, // bits that set what source the adc converter measures
+ BNC_TRIG_THRESHOLD_0V_BIT = 0x80, // make bnc trig/ext clock threshold 0V instead of 2.5V
+};
+static inline uint8_t adc_src_4020_bits(unsigned int source)
+{
+ return (source << 4) & ADC_SRC_4020_MASK;
+};
+static inline uint8_t attenuate_bit(unsigned int channel)
+{
+ // attenuate channel (+-5V input range)
+ return 1 << (channel & 0x3);
+};
+
+// analog input ranges for 64xx boards
+static const struct comedi_lrange ai_ranges_64xx = {
+ 8,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+
+/* analog input ranges for 60xx boards */
+static const struct comedi_lrange ai_ranges_60xx = {
+ 4,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ }
+};
+
+/* analog input ranges for 6030, etc boards */
+static const struct comedi_lrange ai_ranges_6030 = {
+ 14,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.2),
+ BIP_RANGE(0.1),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+/* analog input ranges for 6052, etc boards */
+static const struct comedi_lrange ai_ranges_6052 = {
+ 15,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.25),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+// analog input ranges for 4020 board
+static const struct comedi_lrange ai_ranges_4020 = {
+ 2,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(1),
+ }
+};
+
+// analog output ranges
+static const struct comedi_lrange ao_ranges_64xx = {
+ 4,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+static const int ao_range_code_64xx[] = {
+ 0x0,
+ 0x1,
+ 0x2,
+ 0x3,
+};
+
+static const struct comedi_lrange ao_ranges_60xx = {
+ 1,
+ {
+ BIP_RANGE(10),
+ }
+};
+static const int ao_range_code_60xx[] = {
+ 0x0,
+};
+
+static const struct comedi_lrange ao_ranges_6030 = {
+ 2,
+ {
+ BIP_RANGE(10),
+ UNI_RANGE(10),
+ }
+};
+static const int ao_range_code_6030[] = {
+ 0x0,
+ 0x2,
+};
+
+static const struct comedi_lrange ao_ranges_4020 = {
+ 2,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ }
+};
+static const int ao_range_code_4020[] = {
+ 0x1,
+ 0x0,
+};
+
+enum register_layout {
+ LAYOUT_60XX,
+ LAYOUT_64XX,
+ LAYOUT_4020,
+};
+
+struct hw_fifo_info {
+ unsigned int num_segments;
+ unsigned int max_segment_length;
+ unsigned int sample_packing_ratio;
+ uint16_t fifo_size_reg_mask;
+};
+
+struct pcidas64_board {
+ const char *name;
+ int device_id; // pci device id
+ int ai_se_chans; // number of ai inputs in single-ended mode
+ int ai_bits; // analog input resolution
+ int ai_speed; // fastest conversion period in ns
+ const struct comedi_lrange *ai_range_table;
+ int ao_nchan; // number of analog out channels
+ int ao_bits; // analog output resolution
+ int ao_scan_speed; // analog output speed (for a scan, not conversion)
+ const struct comedi_lrange *ao_range_table;
+ const int *ao_range_code;
+ const struct hw_fifo_info *const ai_fifo;
+ enum register_layout layout; // different board families have slightly different registers
+ unsigned has_8255:1;
+};
+
+static const struct hw_fifo_info ai_fifo_4020 = {
+ num_segments:2,
+ max_segment_length:0x8000,
+ sample_packing_ratio:2,
+ fifo_size_reg_mask:0x7f,
+};
+
+static const struct hw_fifo_info ai_fifo_64xx = {
+ num_segments:4,
+ max_segment_length:0x800,
+ sample_packing_ratio:1,
+ fifo_size_reg_mask:0x3f,
+};
+
+static const struct hw_fifo_info ai_fifo_60xx = {
+ num_segments:4,
+ max_segment_length:0x800,
+ sample_packing_ratio:1,
+ fifo_size_reg_mask:0x7f,
+};
+
+/* maximum number of dma transfers we will chain together into a ring
+ * (and the maximum number of dma buffers we maintain) */
+#define MAX_AI_DMA_RING_COUNT (0x80000 / DMA_BUFFER_SIZE)
+#define MIN_AI_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
+#define AO_DMA_RING_COUNT (0x10000 / DMA_BUFFER_SIZE)
+static inline unsigned int ai_dma_ring_count(struct pcidas64_board * board)
+{
+ if (board->layout == LAYOUT_4020)
+ return MAX_AI_DMA_RING_COUNT;
+ else
+ return MIN_AI_DMA_RING_COUNT;
+}
+
+static const int bytes_in_sample = 2;
+
+static const struct pcidas64_board pcidas64_boards[] = {
+ {
+ name: "pci-das6402/16",
+ device_id:0x1d,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das6402/12", // XXX check
+ device_id:0x1e,
+ ai_se_chans:64,
+ ai_bits: 12,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m1/16",
+ device_id:0x35,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:1000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m2/16",
+ device_id:0x36,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:500,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m3/16",
+ device_id:0x37,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:333,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ao_range_table:&ao_ranges_64xx,
+ ao_range_code:ao_range_code_64xx,
+ ai_fifo: &ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ .name = "pci-das6013",
+ .device_id = 0x78,
+ .ai_se_chans = 16,
+ .ai_bits = 16,
+ .ai_speed = 5000,
+ .ao_nchan = 0,
+ .ao_bits = 16,
+ .layout = LAYOUT_60XX,
+ .ai_range_table = &ai_ranges_60xx,
+ .ao_range_table = &ao_ranges_60xx,
+ .ao_range_code = ao_range_code_60xx,
+ .ai_fifo = &ai_fifo_60xx,
+ .has_8255 = 0,
+ },
+ {
+ name: "pci-das6014",
+ device_id:0x79,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6023",
+ device_id:0x5d,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:5000,
+ ao_nchan:0,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das6025",
+ device_id:0x5e,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das6030",
+ device_id:0x5f,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6031",
+ device_id:0x60,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:10000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6032",
+ device_id:0x61,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:0,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6033",
+ device_id:0x62,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:10000,
+ ao_nchan:0,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6034",
+ device_id:0x63,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:0,
+ ao_scan_speed:0,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6035",
+ device_id:0x64,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6036",
+ device_id:0x6f,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:100000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_60xx,
+ ao_range_table:&ao_ranges_60xx,
+ ao_range_code:ao_range_code_60xx,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6040",
+ device_id:0x65,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:2000,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:1000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6052",
+ device_id:0x66,
+ ai_se_chans:16,
+ ai_bits: 16,
+ ai_speed:3333,
+ ao_nchan:2,
+ ao_bits: 16,
+ ao_scan_speed:3333,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6070",
+ device_id:0x67,
+ ai_se_chans:16,
+ ai_bits: 12,
+ ai_speed:800,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:1000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das6071",
+ device_id:0x68,
+ ai_se_chans:64,
+ ai_bits: 12,
+ ai_speed:800,
+ ao_nchan:2,
+ ao_bits: 12,
+ ao_scan_speed:1000,
+ layout: LAYOUT_60XX,
+ ai_range_table:&ai_ranges_6052,
+ ao_range_table:&ao_ranges_6030,
+ ao_range_code:ao_range_code_6030,
+ ai_fifo: &ai_fifo_60xx,
+ has_8255:0,
+ },
+ {
+ name: "pci-das4020/12",
+ device_id:0x52,
+ ai_se_chans:4,
+ ai_bits: 12,
+ ai_speed:50,
+ ao_bits: 12,
+ ao_nchan:2,
+ ao_scan_speed:0, // no hardware pacing on ao
+ layout: LAYOUT_4020,
+ ai_range_table:&ai_ranges_4020,
+ ao_range_table:&ao_ranges_4020,
+ ao_range_code:ao_range_code_4020,
+ ai_fifo: &ai_fifo_4020,
+ has_8255:1,
+ },
+#if 0
+ {
+ name: "pci-das6402/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:5000,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m1/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:1000,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m2/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:500,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m3/16/jr",
+ device_id:0 // XXX,
+ ai_se_chans:64,
+ ai_bits: 16,
+ ai_speed:333,
+ ao_nchan:0,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m1/14",
+ device_id:0, // XXX
+ ai_se_chans:64,
+ ai_bits: 14,
+ ai_speed:1000,
+ ao_nchan:2,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m2/14",
+ device_id:0, // XXX
+ ai_se_chans:64,
+ ai_bits: 14,
+ ai_speed:500,
+ ao_nchan:2,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+ {
+ name: "pci-das64/m3/14",
+ device_id:0, // XXX
+ ai_se_chans:64,
+ ai_bits: 14,
+ ai_speed:333,
+ ao_nchan:2,
+ ao_scan_speed:10000,
+ layout: LAYOUT_64XX,
+ ai_range_table:&ai_ranges_64xx,
+ ai_fifo: ai_fifo_64xx,
+ has_8255:1,
+ },
+#endif
+};
+
+// Number of boards in cb_pcidas_boards
+static inline unsigned int num_boards(void)
+{
+ return sizeof(pcidas64_boards) / sizeof(struct pcidas64_board);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(pcidas64_pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x001d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x001e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0035, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0036, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0037, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x005d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x005e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x005f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0061, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0062, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0063, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0066, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0067, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x006f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0078, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0079, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pcidas64_pci_table);
+
+static inline struct pcidas64_board *board(const struct comedi_device * dev)
+{
+ return (struct pcidas64_board *) dev->board_ptr;
+}
+
+static inline unsigned short se_diff_bit_6xxx(struct comedi_device * dev,
+ int use_differential)
+{
+ if ((board(dev)->layout == LAYOUT_64XX && !use_differential) ||
+ (board(dev)->layout == LAYOUT_60XX && use_differential))
+ return ADC_SE_DIFF_BIT;
+ else
+ return 0;
+};
+
+struct ext_clock_info {
+ unsigned int divisor; // master clock divisor to use for scans with external master clock
+ unsigned int chanspec; // chanspec for master clock input when used as scan begin src
+};
+
+/* this structure is for data unique to this hardware driver. */
+struct pcidas64_private {
+
+ struct pci_dev *hw_dev; // pointer to board's pci_dev struct
+ // base addresses (physical)
+ resource_size_t plx9080_phys_iobase;
+ resource_size_t main_phys_iobase;
+ resource_size_t dio_counter_phys_iobase;
+ // base addresses (ioremapped)
+ void *plx9080_iobase;
+ void *main_iobase;
+ void *dio_counter_iobase;
+ // local address (used by dma controller)
+ uint32_t local0_iobase;
+ uint32_t local1_iobase;
+ volatile unsigned int ai_count; // number of analog input samples remaining
+ uint16_t *ai_buffer[MAX_AI_DMA_RING_COUNT]; // dma buffers for analog input
+ dma_addr_t ai_buffer_bus_addr[MAX_AI_DMA_RING_COUNT]; // physical addresses of ai dma buffers
+ struct plx_dma_desc *ai_dma_desc; // array of ai dma descriptors read by plx9080, allocated to get proper alignment
+ dma_addr_t ai_dma_desc_bus_addr; // physical address of ai dma descriptor array
+ volatile unsigned int ai_dma_index; // index of the ai dma descriptor/buffer that is currently being used
+ uint16_t *ao_buffer[AO_DMA_RING_COUNT]; // dma buffers for analog output
+ dma_addr_t ao_buffer_bus_addr[AO_DMA_RING_COUNT]; // physical addresses of ao dma buffers
+ struct plx_dma_desc *ao_dma_desc;
+ dma_addr_t ao_dma_desc_bus_addr;
+ volatile unsigned int ao_dma_index; // keeps track of buffer where the next ao sample should go
+ volatile unsigned long ao_count; // number of analog output samples remaining
+ volatile unsigned int ao_value[2]; // remember what the analog outputs are set to, to allow readback
+ unsigned int hw_revision; // stc chip hardware revision number
+ volatile unsigned int intr_enable_bits; // last bits sent to INTR_ENABLE_REG register
+ volatile uint16_t adc_control1_bits; // last bits sent to ADC_CONTROL1_REG register
+ volatile uint16_t fifo_size_bits; // last bits sent to FIFO_SIZE_REG register
+ volatile uint16_t hw_config_bits; // last bits sent to HW_CONFIG_REG register
+ volatile uint16_t dac_control1_bits;
+ volatile uint32_t plx_control_bits; // last bits written to plx9080 control register
+ volatile uint32_t plx_intcsr_bits; // last bits written to plx interrupt control and status register
+ volatile int calibration_source; // index of calibration source readable through ai ch0
+ volatile uint8_t i2c_cal_range_bits; // bits written to i2c calibration/range register
+ volatile unsigned int ext_trig_falling; // configure digital triggers to trigger on falling edge
+ // states of various devices stored to enable read-back
+ unsigned int ad8402_state[2];
+ unsigned int caldac_state[8];
+ volatile short ai_cmd_running;
+ unsigned int ai_fifo_segment_length;
+ struct ext_clock_info ext_clock;
+ short ao_bounce_buffer[DAC_FIFO_SIZE];
+};
+
+
+/* inline function that makes it easier to
+ * access the private structure.
+ */
+static inline struct pcidas64_private *priv(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+/*
+ * The comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidas = {
+ driver_name:"cb_pcidas64",
+ module:THIS_MODULE,
+ attach:attach,
+ detach:detach,
+};
+
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ unsigned int trig_num);
+static int ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG);
+static int ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dio_callback(int dir, int port, int data, unsigned long arg);
+static int dio_callback_4020(int dir, int port, int data, unsigned long arg);
+static int di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dio_60xx_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dio_60xx_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ad8402_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void ad8402_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+static int ad8402_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void check_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd);
+static unsigned int get_divisor(unsigned int ns, unsigned int flags);
+static void i2c_write(struct comedi_device * dev, unsigned int address,
+ const uint8_t * data, unsigned int length);
+static void caldac_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value);
+//static int dac_1590_write(struct comedi_device *dev, unsigned int dac_a, unsigned int dac_b);
+static int caldac_i2c_write(struct comedi_device * dev, unsigned int caldac_channel,
+ unsigned int value);
+static void abort_dma(struct comedi_device * dev, unsigned int channel);
+static void disable_plx_interrupts(struct comedi_device * dev);
+static int set_ai_fifo_size(struct comedi_device * dev, unsigned int num_samples);
+static unsigned int ai_fifo_size(struct comedi_device * dev);
+static int set_ai_fifo_segment_length(struct comedi_device * dev,
+ unsigned int num_entries);
+static void disable_ai_pacing(struct comedi_device * dev);
+static void disable_ai_interrupts(struct comedi_device * dev);
+static void enable_ai_interrupts(struct comedi_device * dev, const struct comedi_cmd * cmd);
+static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags);
+static void load_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd);
+
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidas, pcidas64_pci_table);
+
+static unsigned int ai_range_bits_6xxx(const struct comedi_device * dev,
+ unsigned int range_index)
+{
+ const struct comedi_krange *range =
+ &board(dev)->ai_range_table->range[range_index];
+ unsigned int bits = 0;
+
+ switch (range->max) {
+ case 10000000:
+ bits = 0x000;
+ break;
+ case 5000000:
+ bits = 0x100;
+ break;
+ case 2000000:
+ case 2500000:
+ bits = 0x200;
+ break;
+ case 1000000:
+ case 1250000:
+ bits = 0x300;
+ break;
+ case 500000:
+ bits = 0x400;
+ break;
+ case 200000:
+ case 250000:
+ bits = 0x500;
+ break;
+ case 100000:
+ bits = 0x600;
+ break;
+ case 50000:
+ bits = 0x700;
+ break;
+ default:
+ comedi_error(dev, "bug! in ai_range_bits_6xxx");
+ break;
+ }
+ if (range->min == 0)
+ bits += 0x900;
+ return bits;
+}
+
+static unsigned int hw_revision(const struct comedi_device * dev,
+ uint16_t hw_status_bits)
+{
+ if (board(dev)->layout == LAYOUT_4020)
+ return (hw_status_bits >> 13) & 0x7;
+
+ return (hw_status_bits >> 12) & 0xf;
+}
+
+static void set_dac_range_bits(struct comedi_device * dev, volatile uint16_t * bits,
+ unsigned int channel, unsigned int range)
+{
+ unsigned int code = board(dev)->ao_range_code[range];
+
+ if (channel > 1)
+ comedi_error(dev, "bug! bad channel?");
+ if (code & ~0x3)
+ comedi_error(dev, "bug! bad range code?");
+
+ *bits &= ~(0x3 << (2 * channel));
+ *bits |= code << (2 * channel);
+};
+
+static inline int ao_cmd_is_supported(const struct pcidas64_board * board)
+{
+ return board->ao_nchan && board->layout != LAYOUT_4020;
+}
+
+// initialize plx9080 chip
+static void init_plx9080(struct comedi_device * dev)
+{
+ uint32_t bits;
+ void *plx_iobase = priv(dev)->plx9080_iobase;
+
+ priv(dev)->plx_control_bits =
+ readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG);
+
+ // plx9080 dump
+ DEBUG_PRINT(" plx interrupt status 0x%x\n",
+ readl(plx_iobase + PLX_INTRCS_REG));
+ DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
+ DEBUG_PRINT(" plx control reg 0x%x\n", priv(dev)->plx_control_bits);
+ DEBUG_PRINT(" plx mode/arbitration reg 0x%x\n",
+ readl(plx_iobase + PLX_MARB_REG));
+ DEBUG_PRINT(" plx region0 reg 0x%x\n",
+ readl(plx_iobase + PLX_REGION0_REG));
+ DEBUG_PRINT(" plx region1 reg 0x%x\n",
+ readl(plx_iobase + PLX_REGION1_REG));
+
+ DEBUG_PRINT(" plx revision 0x%x\n",
+ readl(plx_iobase + PLX_REVISION_REG));
+ DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA1_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
+ DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
+ DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
+ readb(plx_iobase + PLX_DMA0_CS_REG));
+ DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+ DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
+
+#ifdef __BIG_ENDIAN
+ bits = BIGEND_DMA0 | BIGEND_DMA1;
+#else
+ bits = 0;
+#endif
+ writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+
+ disable_plx_interrupts(dev);
+
+ abort_dma(dev, 0);
+ abort_dma(dev, 1);
+
+ // configure dma0 mode
+ bits = 0;
+ // enable ready input, not sure if this is necessary
+ bits |= PLX_DMA_EN_READYIN_BIT;
+ // enable bterm, not sure if this is necessary
+ bits |= PLX_EN_BTERM_BIT;
+ // enable dma chaining
+ bits |= PLX_EN_CHAIN_BIT;
+ // enable interrupt on dma done (probably don't need this, since chain never finishes)
+ bits |= PLX_EN_DMA_DONE_INTR_BIT;
+ // don't increment local address during transfers (we are transferring from a fixed fifo register)
+ bits |= PLX_LOCAL_ADDR_CONST_BIT;
+ // route dma interrupt to pci bus
+ bits |= PLX_DMA_INTR_PCI_BIT;
+ // enable demand mode
+ bits |= PLX_DEMAND_MODE_BIT;
+ // enable local burst mode
+ bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
+ // 4020 uses 32 bit dma
+ if (board(dev)->layout == LAYOUT_4020) {
+ bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
+ } else { // localspace0 bus is 16 bits wide
+ bits |= PLX_LOCAL_BUS_16_WIDE_BITS;
+ }
+ writel(bits, plx_iobase + PLX_DMA1_MODE_REG);
+ if (ao_cmd_is_supported(board(dev)))
+ writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
+
+ // enable interrupts on plx 9080
+ priv(dev)->plx_intcsr_bits |=
+ ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
+ ICS_DMA0_E | ICS_DMA1_E;
+ writel(priv(dev)->plx_intcsr_bits,
+ priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+/* Allocate and initialize the subdevice structures.
+ */
+static int setup_subdevices(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+ void *dio_8255_iobase;
+ int i;
+
+ if (alloc_subdevices(dev, 10) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DITHER | SDF_CMD_READ;
+ if (board(dev)->layout == LAYOUT_60XX)
+ s->subdev_flags |= SDF_COMMON | SDF_DIFF;
+ else if (board(dev)->layout == LAYOUT_64XX)
+ s->subdev_flags |= SDF_DIFF;
+ /* XXX Number of inputs in differential mode is ignored */
+ s->n_chan = board(dev)->ai_se_chans;
+ s->len_chanlist = 0x2000;
+ s->maxdata = (1 << board(dev)->ai_bits) - 1;
+ s->range_table = board(dev)->ai_range_table;
+ s->insn_read = ai_rinsn;
+ s->insn_config = ai_config_insn;
+ s->do_cmd = ai_cmd;
+ s->do_cmdtest = ai_cmdtest;
+ s->cancel = ai_cancel;
+ if (board(dev)->layout == LAYOUT_4020) {
+ unsigned int i;
+ uint8_t data;
+ // set adc to read from inputs (not internal calibration sources)
+ priv(dev)->i2c_cal_range_bits = adc_src_4020_bits(4);
+ // set channels to +-5 volt input ranges
+ for (i = 0; i < s->n_chan; i++)
+ priv(dev)->i2c_cal_range_bits |= attenuate_bit(i);
+ data = priv(dev)->i2c_cal_range_bits;
+ i2c_write(dev, RANGE_CAL_I2C_ADDR, &data, sizeof(data));
+ }
+
+ /* analog output subdevice */
+ s = dev->subdevices + 1;
+ if (board(dev)->ao_nchan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_GROUND |
+ SDF_CMD_WRITE;
+ s->n_chan = board(dev)->ao_nchan;
+ s->maxdata = (1 << board(dev)->ao_bits) - 1;
+ s->range_table = board(dev)->ao_range_table;
+ s->insn_read = ao_readback_insn;
+ s->insn_write = ao_winsn;
+ if (ao_cmd_is_supported(board(dev))) {
+ dev->write_subdev = s;
+ s->do_cmdtest = ao_cmdtest;
+ s->do_cmd = ao_cmd;
+ s->len_chanlist = board(dev)->ao_nchan;
+ s->cancel = ao_cancel;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ // digital input
+ s = dev->subdevices + 2;
+ if (board(dev)->layout == LAYOUT_64XX) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = di_rbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // digital output
+ if (board(dev)->layout == LAYOUT_64XX) {
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = do_wbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* 8255 */
+ s = dev->subdevices + 4;
+ if (board(dev)->has_8255) {
+ if (board(dev)->layout == LAYOUT_4020) {
+ dio_8255_iobase =
+ priv(dev)->main_iobase + I8255_4020_REG;
+ subdev_8255_init(dev, s, dio_callback_4020,
+ (unsigned long)dio_8255_iobase);
+ } else {
+ dio_8255_iobase =
+ priv(dev)->dio_counter_iobase + DIO_8255_OFFSET;
+ subdev_8255_init(dev, s, dio_callback,
+ (unsigned long)dio_8255_iobase);
+ }
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // 8 channel dio for 60xx
+ s = dev->subdevices + 5;
+ if (board(dev)->layout == LAYOUT_60XX) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = dio_60xx_config_insn;
+ s->insn_bits = dio_60xx_wbits;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // caldac
+ s = dev->subdevices + 6;
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 8;
+ if (board(dev)->layout == LAYOUT_4020)
+ s->maxdata = 0xfff;
+ else
+ s->maxdata = 0xff;
+ s->insn_read = calib_read_insn;
+ s->insn_write = calib_write_insn;
+ for (i = 0; i < s->n_chan; i++)
+ caldac_write(dev, i, s->maxdata / 2);
+
+ // 2 channel ad8402 potentiometer
+ s = dev->subdevices + 7;
+ if (board(dev)->layout == LAYOUT_64XX) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 2;
+ s->insn_read = ad8402_read_insn;
+ s->insn_write = ad8402_write_insn;
+ s->maxdata = 0xff;
+ for (i = 0; i < s->n_chan; i++)
+ ad8402_write(dev, i, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ //serial EEPROM, if present
+ s = dev->subdevices + 8;
+ if (readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG) & CTL_EECHK) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->n_chan = 128;
+ s->maxdata = 0xffff;
+ s->insn_read = eeprom_read_insn;
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ // user counter subd XXX
+ s = dev->subdevices + 9;
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
+}
+
+static void disable_plx_interrupts(struct comedi_device * dev)
+{
+ priv(dev)->plx_intcsr_bits = 0;
+ writel(priv(dev)->plx_intcsr_bits,
+ priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+static void init_stc_registers(struct comedi_device * dev)
+{
+ uint16_t bits;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ // bit should be set for 6025, although docs say boards with <= 16 chans should be cleared XXX
+ if (1)
+ priv(dev)->adc_control1_bits |= ADC_QUEUE_CONFIG_BIT;
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+
+ // 6402/16 manual says this register must be initialized to 0xff?
+ writew(0xff, priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+
+ bits = SLOW_DAC_BIT | DMA_CH_SELECT_BIT;
+ if (board(dev)->layout == LAYOUT_4020)
+ bits |= INTERNAL_CLOCK_4020_BITS;
+ priv(dev)->hw_config_bits |= bits;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+
+ writew(0, priv(dev)->main_iobase + DAQ_SYNC_REG);
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // set fifos to maximum size
+ priv(dev)->fifo_size_bits |= DAC_FIFO_BITS;
+ set_ai_fifo_segment_length(dev,
+ board(dev)->ai_fifo->max_segment_length);
+
+ priv(dev)->dac_control1_bits = DAC_OUTPUT_ENABLE_BIT;
+ priv(dev)->intr_enable_bits = /* EN_DAC_INTR_SRC_BIT | DAC_INTR_QEMPTY_BITS | */
+ EN_DAC_DONE_INTR_BIT | EN_DAC_UNDERRUN_BIT;
+ writew(priv(dev)->intr_enable_bits,
+ priv(dev)->main_iobase + INTR_ENABLE_REG);
+
+ disable_ai_pacing(dev);
+};
+
+int alloc_and_init_dma_members(struct comedi_device * dev)
+{
+ int i;
+
+ // alocate pci dma buffers
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+ priv(dev)->ai_buffer[i] =
+ pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
+ &priv(dev)->ai_buffer_bus_addr[i]);
+ if (priv(dev)->ai_buffer[i] == NULL) {
+ return -ENOMEM;
+ }
+ }
+ for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+ if (ao_cmd_is_supported(board(dev))) {
+ priv(dev)->ao_buffer[i] =
+ pci_alloc_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ &priv(dev)->ao_buffer_bus_addr[i]);
+ if (priv(dev)->ao_buffer[i] == NULL) {
+ return -ENOMEM;
+ }
+ }
+ }
+ // allocate dma descriptors
+ priv(dev)->ai_dma_desc =
+ pci_alloc_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) * ai_dma_ring_count(board(dev)),
+ &priv(dev)->ai_dma_desc_bus_addr);
+ if (priv(dev)->ai_dma_desc == NULL) {
+ return -ENOMEM;
+ }
+ DEBUG_PRINT("ai dma descriptors start at bus addr 0x%x\n",
+ priv(dev)->ai_dma_desc_bus_addr);
+ if (ao_cmd_is_supported(board(dev))) {
+ priv(dev)->ao_dma_desc =
+ pci_alloc_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) * AO_DMA_RING_COUNT,
+ &priv(dev)->ao_dma_desc_bus_addr);
+ if (priv(dev)->ao_dma_desc == NULL) {
+ return -ENOMEM;
+ }
+ DEBUG_PRINT("ao dma descriptors start at bus addr 0x%x\n",
+ priv(dev)->ao_dma_desc_bus_addr);
+ }
+ // initialize dma descriptors
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+ priv(dev)->ai_dma_desc[i].pci_start_addr =
+ cpu_to_le32(priv(dev)->ai_buffer_bus_addr[i]);
+ if (board(dev)->layout == LAYOUT_4020)
+ priv(dev)->ai_dma_desc[i].local_start_addr =
+ cpu_to_le32(priv(dev)->local1_iobase +
+ ADC_FIFO_REG);
+ else
+ priv(dev)->ai_dma_desc[i].local_start_addr =
+ cpu_to_le32(priv(dev)->local0_iobase +
+ ADC_FIFO_REG);
+ priv(dev)->ai_dma_desc[i].transfer_size = cpu_to_le32(0);
+ priv(dev)->ai_dma_desc[i].next =
+ cpu_to_le32((priv(dev)->ai_dma_desc_bus_addr + ((i +
+ 1) %
+ ai_dma_ring_count(board(dev))) *
+ sizeof(priv(dev)->
+ ai_dma_desc[0])) | PLX_DESC_IN_PCI_BIT |
+ PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI);
+ }
+ if (ao_cmd_is_supported(board(dev))) {
+ for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+ priv(dev)->ao_dma_desc[i].pci_start_addr =
+ cpu_to_le32(priv(dev)->ao_buffer_bus_addr[i]);
+ priv(dev)->ao_dma_desc[i].local_start_addr =
+ cpu_to_le32(priv(dev)->local0_iobase +
+ DAC_FIFO_REG);
+ priv(dev)->ao_dma_desc[i].transfer_size =
+ cpu_to_le32(0);
+ priv(dev)->ao_dma_desc[i].next =
+ cpu_to_le32((priv(dev)->ao_dma_desc_bus_addr +
+ ((i + 1) % (AO_DMA_RING_COUNT)) *
+ sizeof(priv(dev)->
+ ao_dma_desc[0])) |
+ PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
+ }
+ }
+ return 0;
+}
+
+static inline void warn_external_queue(struct comedi_device * dev)
+{
+ comedi_error(dev,
+ "AO command and AI external channel queue cannot be used simultaneously.");
+ comedi_error(dev,
+ "Use internal AI channel queue (channels must be consecutive and use same range/aref)");
+}
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int attach(struct comedi_device *dev, struct comedi_devconfig *it)
+{
+ struct pci_dev *pcidev;
+ int index;
+ uint32_t local_range, local_decode;
+ int retval;
+
+ printk("comedi%d: cb_pcidas64\n", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct pcidas64_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < num_boards(); index++) {
+ if (pcidas64_boards[index].device_id != pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ priv(dev)->hw_dev = pcidev;
+ dev->board_ptr = pcidas64_boards + index;
+ break;
+ }
+ if (dev->board_ptr)
+ break;
+ }
+
+ if (dev->board_ptr == NULL) {
+ printk("No supported ComputerBoards/MeasurementComputing card found\n");
+ return -EIO;
+ }
+
+ printk("Found %s on bus %i, slot %i\n", board(dev)->name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ if (comedi_pci_enable(pcidev, driver_cb_pcidas.driver_name)) {
+ printk(KERN_WARNING
+ " failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ pci_set_master(pcidev);
+
+ //Initialize dev->board_name
+ dev->board_name = board(dev)->name;
+
+ priv(dev)->plx9080_phys_iobase =
+ pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+ priv(dev)->main_phys_iobase =
+ pci_resource_start(pcidev, MAIN_BADDRINDEX);
+ priv(dev)->dio_counter_phys_iobase =
+ pci_resource_start(pcidev, DIO_COUNTER_BADDRINDEX);
+
+ // remap, won't work with 2.0 kernels but who cares
+ priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
+ pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+ priv(dev)->main_iobase = ioremap(priv(dev)->main_phys_iobase,
+ pci_resource_len(pcidev, MAIN_BADDRINDEX));
+ priv(dev)->dio_counter_iobase =
+ ioremap(priv(dev)->dio_counter_phys_iobase,
+ pci_resource_len(pcidev, DIO_COUNTER_BADDRINDEX));
+
+ if (!priv(dev)->plx9080_iobase || !priv(dev)->main_iobase
+ || !priv(dev)->dio_counter_iobase) {
+ printk(" failed to remap io memory\n");
+ return -ENOMEM;
+ }
+
+ DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
+ DEBUG_PRINT(" main remapped to 0x%p\n", priv(dev)->main_iobase);
+ DEBUG_PRINT(" diocounter remapped to 0x%p\n",
+ priv(dev)->dio_counter_iobase);
+
+ // figure out what local addresses are
+ local_range =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS0RNG_REG) & LRNG_MEM_MASK;
+ local_decode =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS0MAP_REG) & local_range & LMAP_MEM_MASK;
+ priv(dev)->local0_iobase =
+ ((uint32_t) priv(dev)->
+ main_phys_iobase & ~local_range) | local_decode;
+ local_range =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS1RNG_REG) & LRNG_MEM_MASK;
+ local_decode =
+ readl(priv(dev)->plx9080_iobase +
+ PLX_LAS1MAP_REG) & local_range & LMAP_MEM_MASK;
+ priv(dev)->local1_iobase =
+ ((uint32_t) priv(dev)->
+ dio_counter_phys_iobase & ~local_range) | local_decode;
+
+ DEBUG_PRINT(" local 0 io addr 0x%x\n", priv(dev)->local0_iobase);
+ DEBUG_PRINT(" local 1 io addr 0x%x\n", priv(dev)->local1_iobase);
+
+ retval = alloc_and_init_dma_members(dev);
+ if (retval < 0)
+ return retval;
+
+ priv(dev)->hw_revision =
+ hw_revision(dev, readw(priv(dev)->main_iobase + HW_STATUS_REG));
+ printk(" stc hardware revision %i\n", priv(dev)->hw_revision);
+ init_plx9080(dev);
+ init_stc_registers(dev);
+ // get irq
+ if (comedi_request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+ "cb_pcidas64", dev)) {
+ printk(" unable to allocate irq %u\n", pcidev->irq);
+ return -EINVAL;
+ }
+ dev->irq = pcidev->irq;
+ printk(" irq %u\n", dev->irq);
+
+ retval = setup_subdevices(dev);
+ if (retval < 0) {
+ return retval;
+ }
+
+ return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int detach(struct comedi_device * dev)
+{
+ unsigned int i;
+
+ printk("comedi%d: cb_pcidas: remove\n", dev->minor);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (priv(dev)) {
+ if (priv(dev)->hw_dev) {
+ if (priv(dev)->plx9080_iobase) {
+ disable_plx_interrupts(dev);
+ iounmap((void *)priv(dev)->plx9080_iobase);
+ }
+ if (priv(dev)->main_iobase)
+ iounmap((void *)priv(dev)->main_iobase);
+ if (priv(dev)->dio_counter_iobase)
+ iounmap((void *)priv(dev)->dio_counter_iobase);
+ // free pci dma buffers
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++) {
+ if (priv(dev)->ai_buffer[i])
+ pci_free_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ priv(dev)->ai_buffer[i],
+ priv(dev)->
+ ai_buffer_bus_addr[i]);
+ }
+ for (i = 0; i < AO_DMA_RING_COUNT; i++) {
+ if (priv(dev)->ao_buffer[i])
+ pci_free_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ priv(dev)->ao_buffer[i],
+ priv(dev)->
+ ao_buffer_bus_addr[i]);
+ }
+ // free dma descriptors
+ if (priv(dev)->ai_dma_desc)
+ pci_free_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) *
+ ai_dma_ring_count(board(dev)),
+ priv(dev)->ai_dma_desc,
+ priv(dev)->ai_dma_desc_bus_addr);
+ if (priv(dev)->ao_dma_desc)
+ pci_free_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) *
+ AO_DMA_RING_COUNT,
+ priv(dev)->ao_dma_desc,
+ priv(dev)->ao_dma_desc_bus_addr);
+ if (priv(dev)->main_phys_iobase) {
+ comedi_pci_disable(priv(dev)->hw_dev);
+ }
+ pci_dev_put(priv(dev)->hw_dev);
+ }
+ }
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+ return 0;
+}
+
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits = 0, n, i;
+ unsigned int channel, range, aref;
+ unsigned long flags;
+ static const int timeout = 100;
+
+ DEBUG_PRINT("chanspec 0x%x\n", insn->chanspec);
+ channel = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ aref = CR_AREF(insn->chanspec);
+
+ // disable card's analog input interrupt sources and pacing
+ // 4020 generates dac done interrupts even though they are disabled
+ disable_ai_pacing(dev);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (insn->chanspec & CR_ALT_FILTER)
+ priv(dev)->adc_control1_bits |= ADC_DITHER_BIT;
+ else
+ priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if (board(dev)->layout != LAYOUT_4020) {
+ // use internal queue
+ priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+
+ // ALT_SOURCE is internal calibration reference
+ if (insn->chanspec & CR_ALT_SOURCE) {
+ unsigned int cal_en_bit;
+
+ DEBUG_PRINT("reading calibration source\n");
+ if (board(dev)->layout == LAYOUT_60XX)
+ cal_en_bit = CAL_EN_60XX_BIT;
+ else
+ cal_en_bit = CAL_EN_64XX_BIT;
+ // select internal reference source to connect to channel 0
+ writew(cal_en_bit | adc_src_bits(priv(dev)->
+ calibration_source),
+ priv(dev)->main_iobase + CALIBRATION_REG);
+ } else {
+ // make sure internal calibration source is turned off
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ }
+ // load internal queue
+ bits = 0;
+ // set gain
+ bits |= ai_range_bits_6xxx(dev, CR_RANGE(insn->chanspec));
+ // set single-ended / differential
+ bits |= se_diff_bit_6xxx(dev, aref == AREF_DIFF);
+ if (aref == AREF_COMMON)
+ bits |= ADC_COMMON_BIT;
+ bits |= adc_chan_bits(channel);
+ // set stop channel
+ writew(adc_chan_bits(channel),
+ priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+ // set start channel, and rest of settings
+ writew(bits, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ } else {
+ uint8_t old_cal_range_bits = priv(dev)->i2c_cal_range_bits;
+
+ priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+ if (insn->chanspec & CR_ALT_SOURCE) {
+ DEBUG_PRINT("reading calibration source\n");
+ priv(dev)->i2c_cal_range_bits |=
+ adc_src_4020_bits(priv(dev)->
+ calibration_source);
+ } else { //select BNC inputs
+ priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+ }
+ // select range
+ if (range == 0)
+ priv(dev)->i2c_cal_range_bits |= attenuate_bit(channel);
+ else
+ priv(dev)->i2c_cal_range_bits &=
+ ~attenuate_bit(channel);
+ // update calibration/range i2c register only if necessary, as it is very slow
+ if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
+ uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+ i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
+ sizeof(i2c_data));
+ }
+
+ /* 4020 manual asks that sample interval register to be set before writing to convert register.
+ * Using somewhat arbitrary setting of 4 master clock ticks = 0.1 usec */
+ writew(0,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+ writew(2,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+ }
+
+ for (n = 0; n < insn->n; n++) {
+
+ // clear adc buffer (inside loop for 4020 sake)
+ writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+
+ /* trigger conversion, bits sent only matter for 4020 */
+ writew(adc_convert_chan_4020_bits(CR_CHAN(insn->chanspec)),
+ priv(dev)->main_iobase + ADC_CONVERT_REG);
+
+ // wait for data
+ for (i = 0; i < timeout; i++) {
+ bits = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+ DEBUG_PRINT(" pipe bits 0x%x\n", pipe_full_bits(bits));
+ if (board(dev)->layout == LAYOUT_4020) {
+ if (readw(priv(dev)->main_iobase +
+ ADC_WRITE_PNTR_REG))
+ break;
+ } else {
+ if (pipe_full_bits(bits))
+ break;
+ }
+ comedi_udelay(1);
+ }
+ DEBUG_PRINT(" looped %i times waiting for data\n", i);
+ if (i == timeout) {
+ comedi_error(dev, " analog input read insn timed out");
+ rt_printk(" status 0x%x\n", bits);
+ return -ETIME;
+ }
+ if (board(dev)->layout == LAYOUT_4020)
+ data[n] =
+ readl(priv(dev)->dio_counter_iobase +
+ ADC_FIFO_REG) & 0xffff;
+ else
+ data[n] =
+ readw(priv(dev)->main_iobase + PIPE1_READ_REG);
+ }
+
+ return n;
+}
+
+static int ai_config_calibration_source(struct comedi_device * dev, unsigned int * data)
+{
+ unsigned int source = data[1];
+ int num_calibration_sources;
+
+ if (board(dev)->layout == LAYOUT_60XX)
+ num_calibration_sources = 16;
+ else
+ num_calibration_sources = 8;
+ if (source >= num_calibration_sources) {
+ printk("invalid calibration source: %i\n", source);
+ return -EINVAL;
+ }
+
+ DEBUG_PRINT("setting calibration source to %i\n", source);
+ priv(dev)->calibration_source = source;
+
+ return 2;
+}
+
+static int ai_config_block_size(struct comedi_device * dev, unsigned int * data)
+{
+ int fifo_size;
+ const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+ unsigned int block_size, requested_block_size;
+ int retval;
+
+ requested_block_size = data[1];
+
+ if (requested_block_size) {
+ fifo_size =
+ requested_block_size * fifo->num_segments /
+ bytes_in_sample;
+
+ retval = set_ai_fifo_size(dev, fifo_size);
+ if (retval < 0)
+ return retval;
+
+ }
+
+ block_size = ai_fifo_size(dev) / fifo->num_segments * bytes_in_sample;
+
+ data[1] = block_size;
+
+ return 2;
+}
+
+static int ai_config_master_clock_4020(struct comedi_device * dev, unsigned int * data)
+{
+ unsigned int divisor = data[4];
+ int retval = 0;
+
+ if (divisor < 2) {
+ divisor = 2;
+ retval = -EAGAIN;
+ }
+
+ switch (data[1]) {
+ case COMEDI_EV_SCAN_BEGIN:
+ priv(dev)->ext_clock.divisor = divisor;
+ priv(dev)->ext_clock.chanspec = data[2];
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ data[4] = divisor;
+
+ return retval ? retval : 5;
+}
+
+// XXX could add support for 60xx series
+static int ai_config_master_clock(struct comedi_device * dev, unsigned int * data)
+{
+
+ switch (board(dev)->layout) {
+ case LAYOUT_4020:
+ return ai_config_master_clock_4020(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ai_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int id = data[0];
+
+ switch (id) {
+ case INSN_CONFIG_ALT_SOURCE:
+ return ai_config_calibration_source(dev, data);
+ break;
+ case INSN_CONFIG_BLOCK_SIZE:
+ return ai_config_block_size(dev, data);
+ break;
+ case INSN_CONFIG_TIMER_1:
+ return ai_config_master_clock(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return -EINVAL;
+}
+
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ unsigned int tmp_arg, tmp_arg2;
+ int i;
+ int aref;
+ unsigned int triggers;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ triggers = TRIG_TIMER;
+ if (board(dev)->layout == LAYOUT_4020)
+ triggers |= TRIG_OTHER;
+ else
+ triggers |= TRIG_FOLLOW;
+ cmd->scan_begin_src &= triggers;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ triggers = TRIG_TIMER;
+ if (board(dev)->layout == LAYOUT_4020)
+ triggers |= TRIG_NOW;
+ else
+ triggers |= TRIG_EXT;
+ cmd->convert_src &= triggers;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_OTHER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ // compatibility check
+ if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (board(dev)->layout == LAYOUT_4020) {
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ } else {
+ if (cmd->convert_arg < board(dev)->ai_speed) {
+ cmd->convert_arg = board(dev)->ai_speed;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ // if scans are timed faster than conversion rate allows
+ if (cmd->convert_arg * cmd->chanlist_len >
+ cmd->scan_begin_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg *
+ cmd->chanlist_len;
+ err++;
+ }
+ }
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_EXT:
+ break;
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp_arg = cmd->convert_arg;
+ tmp_arg2 = cmd->scan_begin_arg;
+ check_adc_timing(dev, cmd);
+ if (tmp_arg != cmd->convert_arg)
+ err++;
+ if (tmp_arg2 != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // make sure user is doesn't change analog reference mid chanlist
+ if (cmd->chanlist) {
+ aref = CR_AREF(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (aref != CR_AREF(cmd->chanlist[i])) {
+ comedi_error(dev,
+ "all elements in chanlist must use the same analog reference");
+ err++;
+ break;
+ }
+ }
+ // check 4020 chanlist
+ if (board(dev)->layout == LAYOUT_4020) {
+ unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ first_channel + i) {
+ comedi_error(dev,
+ "chanlist must use consecutive channels");
+ err++;
+ break;
+ }
+ }
+ if (cmd->chanlist_len == 3) {
+ comedi_error(dev,
+ "chanlist cannot be 3 channels long, use 1, 2, or 4 channels");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int use_hw_sample_counter(struct comedi_cmd * cmd)
+{
+// disable for now until I work out a race
+ return 0;
+
+ if (cmd->stop_src == TRIG_COUNT && cmd->stop_arg <= max_counter_value)
+ return 1;
+ else
+ return 0;
+}
+
+static void setup_sample_counters(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ if (cmd->stop_src == TRIG_COUNT) {
+ // set software count
+ priv(dev)->ai_count = cmd->stop_arg * cmd->chanlist_len;
+ }
+ // load hardware conversion counter
+ if (use_hw_sample_counter(cmd)) {
+ writew(cmd->stop_arg & 0xffff,
+ priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+ writew((cmd->stop_arg >> 16) & 0xff,
+ priv(dev)->main_iobase + ADC_COUNT_UPPER_REG);
+ } else {
+ writew(1, priv(dev)->main_iobase + ADC_COUNT_LOWER_REG);
+ }
+}
+
+static inline unsigned int dma_transfer_size(struct comedi_device * dev)
+{
+ unsigned int num_samples;
+
+ num_samples =
+ priv(dev)->ai_fifo_segment_length *
+ board(dev)->ai_fifo->sample_packing_ratio;
+ if (num_samples > DMA_BUFFER_SIZE / sizeof(uint16_t))
+ num_samples = DMA_BUFFER_SIZE / sizeof(uint16_t);
+
+ return num_samples;
+}
+
+static void disable_ai_pacing(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ disable_ai_interrupts(dev);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ priv(dev)->adc_control1_bits &= ~ADC_SW_GATE_BIT;
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ /* disable pacing, triggering, etc */
+ writew(ADC_DMA_DISABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT,
+ priv(dev)->main_iobase + ADC_CONTROL0_REG);
+}
+
+static void disable_ai_interrupts(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ priv(dev)->intr_enable_bits &=
+ ~EN_ADC_INTR_SRC_BIT & ~EN_ADC_DONE_INTR_BIT &
+ ~EN_ADC_ACTIVE_INTR_BIT & ~EN_ADC_STOP_INTR_BIT &
+ ~EN_ADC_OVERRUN_BIT & ~ADC_INTR_SRC_MASK;
+ writew(priv(dev)->intr_enable_bits,
+ priv(dev)->main_iobase + INTR_ENABLE_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
+}
+
+static void enable_ai_interrupts(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ uint32_t bits;
+ unsigned long flags;
+
+ bits = EN_ADC_OVERRUN_BIT | EN_ADC_DONE_INTR_BIT |
+ EN_ADC_ACTIVE_INTR_BIT | EN_ADC_STOP_INTR_BIT;
+ // Use pio transfer and interrupt on end of conversion if TRIG_WAKE_EOS flag is set.
+ if (cmd->flags & TRIG_WAKE_EOS) {
+ // 4020 doesn't support pio transfers except for fifo dregs
+ if (board(dev)->layout != LAYOUT_4020)
+ bits |= ADC_INTR_EOSCAN_BITS | EN_ADC_INTR_SRC_BIT;
+ }
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ priv(dev)->intr_enable_bits |= bits;
+ writew(priv(dev)->intr_enable_bits,
+ priv(dev)->main_iobase + INTR_ENABLE_REG);
+ DEBUG_PRINT("intr enable bits 0x%x\n", priv(dev)->intr_enable_bits);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static uint32_t ai_convert_counter_6xxx(const struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ // supposed to load counter with desired divisor minus 3
+ return cmd->convert_arg / TIMER_BASE - 3;
+}
+
+static uint32_t ai_scan_counter_6xxx(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ uint32_t count;
+ // figure out how long we need to delay at end of scan
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ count = (cmd->scan_begin_arg -
+ (cmd->convert_arg * (cmd->chanlist_len - 1)))
+ / TIMER_BASE;
+ break;
+ case TRIG_FOLLOW:
+ count = cmd->convert_arg / TIMER_BASE;
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return count - 3;
+}
+
+static uint32_t ai_convert_counter_4020(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ unsigned int divisor;
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ divisor = cmd->scan_begin_arg / TIMER_BASE;
+ break;
+ case TRIG_OTHER:
+ divisor = priv(dev)->ext_clock.divisor;
+ break;
+ default: // should never happen
+ comedi_error(dev, "bug! failed to set ai pacing!");
+ divisor = 1000;
+ break;
+ }
+
+ // supposed to load counter with desired divisor minus 2 for 4020
+ return divisor - 2;
+}
+
+static void select_master_clock_4020(struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ // select internal/external master clock
+ priv(dev)->hw_config_bits &= ~MASTER_CLOCK_4020_MASK;
+ if (cmd->scan_begin_src == TRIG_OTHER) {
+ int chanspec = priv(dev)->ext_clock.chanspec;
+
+ if (CR_CHAN(chanspec))
+ priv(dev)->hw_config_bits |= BNC_CLOCK_4020_BITS;
+ else
+ priv(dev)->hw_config_bits |= EXT_CLOCK_4020_BITS;
+ } else {
+ priv(dev)->hw_config_bits |= INTERNAL_CLOCK_4020_BITS;
+ }
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+}
+
+static void select_master_clock(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ switch (board(dev)->layout) {
+ case LAYOUT_4020:
+ select_master_clock_4020(dev, cmd);
+ break;
+ default:
+ break;
+ }
+}
+
+static inline void dma_start_sync(struct comedi_device * dev, unsigned int channel)
+{
+ unsigned long flags;
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (channel)
+ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
+ PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ else
+ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT |
+ PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static void set_ai_pacing(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ uint32_t convert_counter = 0, scan_counter = 0;
+
+ check_adc_timing(dev, cmd);
+
+ select_master_clock(dev, cmd);
+
+ if (board(dev)->layout == LAYOUT_4020) {
+ convert_counter = ai_convert_counter_4020(dev, cmd);
+ } else {
+ convert_counter = ai_convert_counter_6xxx(dev, cmd);
+ scan_counter = ai_scan_counter_6xxx(dev, cmd);
+ }
+
+ // load lower 16 bits of convert interval
+ writew(convert_counter & 0xffff,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_LOWER_REG);
+ DEBUG_PRINT("convert counter 0x%x\n", convert_counter);
+ // load upper 8 bits of convert interval
+ writew((convert_counter >> 16) & 0xff,
+ priv(dev)->main_iobase + ADC_SAMPLE_INTERVAL_UPPER_REG);
+ // load lower 16 bits of scan delay
+ writew(scan_counter & 0xffff,
+ priv(dev)->main_iobase + ADC_DELAY_INTERVAL_LOWER_REG);
+ // load upper 8 bits of scan delay
+ writew((scan_counter >> 16) & 0xff,
+ priv(dev)->main_iobase + ADC_DELAY_INTERVAL_UPPER_REG);
+ DEBUG_PRINT("scan counter 0x%x\n", scan_counter);
+}
+
+static int use_internal_queue_6xxx(const struct comedi_cmd * cmd)
+{
+ int i;
+ for (i = 0; i + 1 < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i + 1]) !=
+ CR_CHAN(cmd->chanlist[i]) + 1)
+ return 0;
+ if (CR_RANGE(cmd->chanlist[i + 1]) !=
+ CR_RANGE(cmd->chanlist[i]))
+ return 0;
+ if (CR_AREF(cmd->chanlist[i + 1]) != CR_AREF(cmd->chanlist[i]))
+ return 0;
+ }
+ return 1;
+}
+
+static int setup_channel_queue(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned short bits;
+ int i;
+
+ if (board(dev)->layout != LAYOUT_4020) {
+ if (use_internal_queue_6xxx(cmd)) {
+ priv(dev)->hw_config_bits &= ~EXT_QUEUE_BIT;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+ bits = 0;
+ // set channel
+ bits |= adc_chan_bits(CR_CHAN(cmd->chanlist[0]));
+ // set gain
+ bits |= ai_range_bits_6xxx(dev,
+ CR_RANGE(cmd->chanlist[0]));
+ // set single-ended / differential
+ bits |= se_diff_bit_6xxx(dev,
+ CR_AREF(cmd->chanlist[0]) == AREF_DIFF);
+ if (CR_AREF(cmd->chanlist[0]) == AREF_COMMON)
+ bits |= ADC_COMMON_BIT;
+ // set stop channel
+ writew(adc_chan_bits(CR_CHAN(cmd->chanlist[cmd->
+ chanlist_len - 1])),
+ priv(dev)->main_iobase + ADC_QUEUE_HIGH_REG);
+ // set start channel, and rest of settings
+ writew(bits,
+ priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ } else {
+ // use external queue
+ if (dev->write_subdev && dev->write_subdev->busy) {
+ warn_external_queue(dev);
+ return -EBUSY;
+ }
+ priv(dev)->hw_config_bits |= EXT_QUEUE_BIT;
+ writew(priv(dev)->hw_config_bits,
+ priv(dev)->main_iobase + HW_CONFIG_REG);
+ // clear DAC buffer to prevent weird interactions
+ writew(0,
+ priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+ // clear queue pointer
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ // load external queue
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ bits = 0;
+ // set channel
+ bits |= adc_chan_bits(CR_CHAN(cmd->
+ chanlist[i]));
+ // set gain
+ bits |= ai_range_bits_6xxx(dev,
+ CR_RANGE(cmd->chanlist[i]));
+ // set single-ended / differential
+ bits |= se_diff_bit_6xxx(dev,
+ CR_AREF(cmd->chanlist[i]) == AREF_DIFF);
+ if (CR_AREF(cmd->chanlist[i]) == AREF_COMMON)
+ bits |= ADC_COMMON_BIT;
+ // mark end of queue
+ if (i == cmd->chanlist_len - 1)
+ bits |= QUEUE_EOSCAN_BIT |
+ QUEUE_EOSEQ_BIT;
+ writew(bits,
+ priv(dev)->main_iobase +
+ ADC_QUEUE_FIFO_REG);
+ DEBUG_PRINT
+ ("wrote 0x%x to external channel queue\n",
+ bits);
+ }
+ /* doing a queue clear is not specified in board docs,
+ * but required for reliable operation */
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ // prime queue holding register
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_LOAD_REG);
+ }
+ } else {
+ unsigned short old_cal_range_bits =
+ priv(dev)->i2c_cal_range_bits;
+
+ priv(dev)->i2c_cal_range_bits &= ~ADC_SRC_4020_MASK;
+ //select BNC inputs
+ priv(dev)->i2c_cal_range_bits |= adc_src_4020_bits(4);
+ // select ranges
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ unsigned int channel = CR_CHAN(cmd->chanlist[i]);
+ unsigned int range = CR_RANGE(cmd->chanlist[i]);
+
+ if (range == 0)
+ priv(dev)->i2c_cal_range_bits |=
+ attenuate_bit(channel);
+ else
+ priv(dev)->i2c_cal_range_bits &=
+ ~attenuate_bit(channel);
+ }
+ // update calibration/range i2c register only if necessary, as it is very slow
+ if (old_cal_range_bits != priv(dev)->i2c_cal_range_bits) {
+ uint8_t i2c_data = priv(dev)->i2c_cal_range_bits;
+ i2c_write(dev, RANGE_CAL_I2C_ADDR, &i2c_data,
+ sizeof(i2c_data));
+ }
+ }
+ return 0;
+}
+
+static inline void load_first_dma_descriptor(struct comedi_device * dev,
+ unsigned int dma_channel, unsigned int descriptor_bits)
+{
+ /* The transfer size, pci address, and local address registers
+ * are supposedly unused during chained dma,
+ * but I have found that left over values from last operation
+ * occasionally cause problems with transfer of first dma
+ * block. Initializing them to zero seems to fix the problem. */
+ if (dma_channel) {
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA1_TRANSFER_SIZE_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG);
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA1_LOCAL_ADDRESS_REG);
+ writel(descriptor_bits,
+ priv(dev)->plx9080_iobase + PLX_DMA1_DESCRIPTOR_REG);
+ } else {
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ writel(0,
+ priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+ writel(descriptor_bits,
+ priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+ }
+}
+
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ uint32_t bits;
+ unsigned int i;
+ unsigned long flags;
+ int retval;
+
+ disable_ai_pacing(dev);
+ abort_dma(dev, 1);
+
+ retval = setup_channel_queue(dev, cmd);
+ if (retval < 0)
+ return retval;
+
+ // make sure internal calibration source is turned off
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+
+ set_ai_pacing(dev, cmd);
+
+ setup_sample_counters(dev, cmd);
+
+ enable_ai_interrupts(dev, cmd);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ /* set mode, allow conversions through software gate */
+ priv(dev)->adc_control1_bits |= ADC_SW_GATE_BIT;
+ priv(dev)->adc_control1_bits &= ~ADC_DITHER_BIT;
+ if (board(dev)->layout != LAYOUT_4020) {
+ priv(dev)->adc_control1_bits &= ~ADC_MODE_MASK;
+ if (cmd->convert_src == TRIG_EXT)
+ priv(dev)->adc_control1_bits |= adc_mode_bits(13); // good old mode 13
+ else
+ priv(dev)->adc_control1_bits |= adc_mode_bits(8); // mode 8. What else could you need?
+ } else {
+ priv(dev)->adc_control1_bits &= ~CHANNEL_MODE_4020_MASK;
+ if (cmd->chanlist_len == 4)
+ priv(dev)->adc_control1_bits |= FOUR_CHANNEL_4020_BITS;
+ else if (cmd->chanlist_len == 2)
+ priv(dev)->adc_control1_bits |= TWO_CHANNEL_4020_BITS;
+ priv(dev)->adc_control1_bits &= ~ADC_LO_CHANNEL_4020_MASK;
+ priv(dev)->adc_control1_bits |=
+ adc_lo_chan_4020_bits(CR_CHAN(cmd->chanlist[0]));
+ priv(dev)->adc_control1_bits &= ~ADC_HI_CHANNEL_4020_MASK;
+ priv(dev)->adc_control1_bits |=
+ adc_hi_chan_4020_bits(CR_CHAN(cmd->chanlist[cmd->
+ chanlist_len - 1]));
+ }
+ writew(priv(dev)->adc_control1_bits,
+ priv(dev)->main_iobase + ADC_CONTROL1_REG);
+ DEBUG_PRINT("control1 bits 0x%x\n", priv(dev)->adc_control1_bits);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // clear adc buffer
+ writew(0, priv(dev)->main_iobase + ADC_BUFFER_CLEAR_REG);
+
+ if ((cmd->flags & TRIG_WAKE_EOS) == 0 ||
+ board(dev)->layout == LAYOUT_4020) {
+ priv(dev)->ai_dma_index = 0;
+
+ // set dma transfer size
+ for (i = 0; i < ai_dma_ring_count(board(dev)); i++)
+ priv(dev)->ai_dma_desc[i].transfer_size =
+ cpu_to_le32(dma_transfer_size(dev) *
+ sizeof(uint16_t));
+
+ // give location of first dma descriptor
+ load_first_dma_descriptor(dev, 1,
+ priv(dev)->
+ ai_dma_desc_bus_addr | PLX_DESC_IN_PCI_BIT |
+ PLX_INTR_TERM_COUNT | PLX_XFER_LOCAL_TO_PCI);
+
+ dma_start_sync(dev, 1);
+ }
+
+ if (board(dev)->layout == LAYOUT_4020) {
+ /* set source for external triggers */
+ bits = 0;
+ if (cmd->start_src == TRIG_EXT && CR_CHAN(cmd->start_arg))
+ bits |= EXT_START_TRIG_BNC_BIT;
+ if (cmd->stop_src == TRIG_EXT && CR_CHAN(cmd->stop_arg))
+ bits |= EXT_STOP_TRIG_BNC_BIT;
+ writew(bits, priv(dev)->main_iobase + DAQ_ATRIG_LOW_4020_REG);
+ }
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ /* enable pacing, triggering, etc */
+ bits = ADC_ENABLE_BIT | ADC_SOFT_GATE_BITS | ADC_GATE_LEVEL_BIT;
+ if (cmd->flags & TRIG_WAKE_EOS)
+ bits |= ADC_DMA_DISABLE_BIT;
+ // set start trigger
+ if (cmd->start_src == TRIG_EXT) {
+ bits |= ADC_START_TRIG_EXT_BITS;
+ if (cmd->start_arg & CR_INVERT)
+ bits |= ADC_START_TRIG_FALLING_BIT;
+ } else if (cmd->start_src == TRIG_NOW)
+ bits |= ADC_START_TRIG_SOFT_BITS;
+ if (use_hw_sample_counter(cmd))
+ bits |= ADC_SAMPLE_COUNTER_EN_BIT;
+ writew(bits, priv(dev)->main_iobase + ADC_CONTROL0_REG);
+ DEBUG_PRINT("control0 bits 0x%x\n", bits);
+
+ priv(dev)->ai_cmd_running = 1;
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // start aquisition
+ if (cmd->start_src == TRIG_NOW) {
+ writew(0, priv(dev)->main_iobase + ADC_START_REG);
+ DEBUG_PRINT("soft trig\n");
+ }
+
+ return 0;
+}
+
+// read num_samples from 16 bit wide ai fifo
+static void pio_drain_ai_fifo_16(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int i;
+ uint16_t prepost_bits;
+ int read_segment, read_index, write_segment, write_index;
+ int num_samples;
+
+ do {
+ // get least significant 15 bits
+ read_index =
+ readw(priv(dev)->main_iobase +
+ ADC_READ_PNTR_REG) & 0x7fff;
+ write_index =
+ readw(priv(dev)->main_iobase +
+ ADC_WRITE_PNTR_REG) & 0x7fff;
+ /* Get most significant bits (grey code). Different boards use different code
+ * so use a scheme that doesn't depend on encoding. This read must
+ * occur after reading least significant 15 bits to avoid race
+ * with fifo switching to next segment. */
+ prepost_bits = readw(priv(dev)->main_iobase + PREPOST_REG);
+
+ /* if read and write pointers are not on the same fifo segment, read to the
+ * end of the read segment */
+ read_segment = adc_upper_read_ptr_code(prepost_bits);
+ write_segment = adc_upper_write_ptr_code(prepost_bits);
+
+ DEBUG_PRINT(" rd seg %i, wrt seg %i, rd idx %i, wrt idx %i\n",
+ read_segment, write_segment, read_index, write_index);
+
+ if (read_segment != write_segment)
+ num_samples =
+ priv(dev)->ai_fifo_segment_length - read_index;
+ else
+ num_samples = write_index - read_index;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (priv(dev)->ai_count == 0)
+ break;
+ if (num_samples > priv(dev)->ai_count) {
+ num_samples = priv(dev)->ai_count;
+ }
+ priv(dev)->ai_count -= num_samples;
+ }
+
+ if (num_samples < 0) {
+ rt_printk(" cb_pcidas64: bug! num_samples < 0\n");
+ break;
+ }
+
+ DEBUG_PRINT(" read %i samples from fifo\n", num_samples);
+
+ for (i = 0; i < num_samples; i++) {
+ cfc_write_to_buffer(s,
+ readw(priv(dev)->main_iobase + ADC_FIFO_REG));
+ }
+
+ } while (read_segment != write_segment);
+}
+
+/* Read from 32 bit wide ai fifo of 4020 - deal with insane grey coding of pointers.
+ * The pci-4020 hardware only supports
+ * dma transfers (it only supports the use of pio for draining the last remaining
+ * points from the fifo when a data aquisition operation has completed).
+ */
+static void pio_drain_ai_fifo_32(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int i;
+ unsigned int max_transfer = 100000;
+ uint32_t fifo_data;
+ int write_code =
+ readw(priv(dev)->main_iobase + ADC_WRITE_PNTR_REG) & 0x7fff;
+ int read_code =
+ readw(priv(dev)->main_iobase + ADC_READ_PNTR_REG) & 0x7fff;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (max_transfer > priv(dev)->ai_count) {
+ max_transfer = priv(dev)->ai_count;
+ }
+ }
+ for (i = 0; read_code != write_code && i < max_transfer;) {
+ fifo_data = readl(priv(dev)->dio_counter_iobase + ADC_FIFO_REG);
+ cfc_write_to_buffer(s, fifo_data & 0xffff);
+ i++;
+ if (i < max_transfer) {
+ cfc_write_to_buffer(s, (fifo_data >> 16) & 0xffff);
+ i++;
+ }
+ read_code =
+ readw(priv(dev)->main_iobase +
+ ADC_READ_PNTR_REG) & 0x7fff;
+ }
+ priv(dev)->ai_count -= i;
+}
+
+// empty fifo
+static void pio_drain_ai_fifo(struct comedi_device * dev)
+{
+ if (board(dev)->layout == LAYOUT_4020) {
+ pio_drain_ai_fifo_32(dev);
+ } else
+ pio_drain_ai_fifo_16(dev);
+}
+
+static void drain_dma_buffers(struct comedi_device * dev, unsigned int channel)
+{
+ struct comedi_async *async = dev->read_subdev->async;
+ uint32_t next_transfer_addr;
+ int j;
+ int num_samples = 0;
+ void *pci_addr_reg;
+
+ if (channel)
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+ else
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+
+ // loop until we have read all the full buffers
+ for (j = 0, next_transfer_addr = readl(pci_addr_reg);
+ (next_transfer_addr <
+ priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index]
+ || next_transfer_addr >=
+ priv(dev)->ai_buffer_bus_addr[priv(dev)->ai_dma_index] +
+ DMA_BUFFER_SIZE) && j < ai_dma_ring_count(board(dev));
+ j++) {
+ // transfer data from dma buffer to comedi buffer
+ num_samples = dma_transfer_size(dev);
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ if (num_samples > priv(dev)->ai_count)
+ num_samples = priv(dev)->ai_count;
+ priv(dev)->ai_count -= num_samples;
+ }
+ cfc_write_array_to_buffer(dev->read_subdev,
+ priv(dev)->ai_buffer[priv(dev)->ai_dma_index],
+ num_samples * sizeof(uint16_t));
+ priv(dev)->ai_dma_index =
+ (priv(dev)->ai_dma_index +
+ 1) % ai_dma_ring_count(board(dev));
+
+ DEBUG_PRINT("next buffer addr 0x%lx\n",
+ (unsigned long)priv(dev)->ai_buffer_bus_addr[priv(dev)->
+ ai_dma_index]);
+ DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
+ }
+ /* XXX check for dma ring buffer overrun (use end-of-chain bit to mark last
+ * unused buffer) */
+}
+
+void handle_ai_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned int plx_status)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ uint8_t dma1_status;
+ unsigned long flags;
+
+ // check for fifo overrun
+ if (status & ADC_OVERRUN_BIT) {
+ comedi_error(dev, "fifo overrun");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ if (plx_status & ICS_DMA1_A) { // dma chan 1 interrupt
+ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
+
+ if (dma1_status & PLX_DMA_EN_BIT) {
+ drain_dma_buffers(dev, 1);
+ }
+ DEBUG_PRINT(" cleared dma ch1 interrupt\n");
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if (status & ADC_DONE_BIT)
+ DEBUG_PRINT("adc done interrupt\n");
+
+ // drain fifo with pio
+ if ((status & ADC_DONE_BIT) ||
+ ((cmd->flags & TRIG_WAKE_EOS) &&
+ (status & ADC_INTR_PENDING_BIT) &&
+ (board(dev)->layout != LAYOUT_4020))) {
+ DEBUG_PRINT("pio fifo drain\n");
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (priv(dev)->ai_cmd_running) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ pio_drain_ai_fifo(dev);
+ } else
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ }
+ // if we are have all the data, then quit
+ if ((cmd->stop_src == TRIG_COUNT && priv(dev)->ai_count <= 0) ||
+ (cmd->stop_src == TRIG_EXT && (status & ADC_STOP_BIT))) {
+ async->events |= COMEDI_CB_EOA;
+ }
+
+ cfc_handle_events(dev, s);
+}
+
+static inline unsigned int prev_ao_dma_index(struct comedi_device * dev)
+{
+ unsigned int buffer_index;
+
+ if (priv(dev)->ao_dma_index == 0)
+ buffer_index = AO_DMA_RING_COUNT - 1;
+ else
+ buffer_index = priv(dev)->ao_dma_index - 1;
+ return buffer_index;
+}
+
+static int last_ao_dma_load_completed(struct comedi_device * dev)
+{
+ unsigned int buffer_index;
+ unsigned int transfer_address;
+ unsigned short dma_status;
+
+ buffer_index = prev_ao_dma_index(dev);
+ dma_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ if ((dma_status & PLX_DMA_DONE_BIT) == 0)
+ return 0;
+
+ transfer_address =
+ readl(priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ if (transfer_address != priv(dev)->ao_buffer_bus_addr[buffer_index])
+ return 0;
+
+ return 1;
+}
+
+static int ao_stopped_by_error(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ if (cmd->stop_src == TRIG_NONE)
+ return 1;
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (priv(dev)->ao_count)
+ return 1;
+ if (last_ao_dma_load_completed(dev) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static inline int ao_dma_needs_restart(struct comedi_device * dev,
+ unsigned short dma_status)
+{
+ if ((dma_status & PLX_DMA_DONE_BIT) == 0 ||
+ (dma_status & PLX_DMA_EN_BIT) == 0)
+ return 0;
+ if (last_ao_dma_load_completed(dev))
+ return 0;
+
+ return 1;
+}
+
+static void restart_ao_dma(struct comedi_device * dev)
+{
+ unsigned int dma_desc_bits;
+
+ dma_desc_bits =
+ readl(priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+ dma_desc_bits &= ~PLX_END_OF_CHAIN_BIT;
+ DEBUG_PRINT("restarting ao dma, descriptor reg 0x%x\n", dma_desc_bits);
+ load_first_dma_descriptor(dev, 0, dma_desc_bits);
+
+ dma_start_sync(dev, 0);
+}
+
+static void handle_ao_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned int plx_status)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ uint8_t dma0_status;
+ unsigned long flags;
+
+ /* board might not support ao, in which case write_subdev is NULL */
+ if (s == NULL)
+ return;
+ async = s->async;
+ cmd = &async->cmd;
+
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ if (plx_status & ICS_DMA0_A) { // dma chan 0 interrupt
+ if ((dma0_status & PLX_DMA_EN_BIT)
+ && !(dma0_status & PLX_DMA_DONE_BIT))
+ writeb(PLX_DMA_EN_BIT | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ else
+ writeb(PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
+ if (dma0_status & PLX_DMA_EN_BIT) {
+ load_ao_dma(dev, cmd);
+ /* try to recover from dma end-of-chain event */
+ if (ao_dma_needs_restart(dev, dma0_status))
+ restart_ao_dma(dev);
+ }
+ DEBUG_PRINT(" cleared dma ch0 interrupt\n");
+ } else
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if ((status & DAC_DONE_BIT)) {
+ async->events |= COMEDI_CB_EOA;
+ if (ao_stopped_by_error(dev, cmd))
+ async->events |= COMEDI_CB_ERROR;
+ DEBUG_PRINT("plx dma0 desc reg 0x%x\n",
+ readl(priv(dev)->plx9080_iobase +
+ PLX_DMA0_DESCRIPTOR_REG));
+ DEBUG_PRINT("plx dma0 address reg 0x%x\n",
+ readl(priv(dev)->plx9080_iobase +
+ PLX_DMA0_PCI_ADDRESS_REG));
+ }
+ cfc_handle_events(dev, s);
+}
+
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned short status;
+ uint32_t plx_status;
+ uint32_t plx_bits;
+
+ plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ status = readw(priv(dev)->main_iobase + HW_STATUS_REG);
+
+ DEBUG_PRINT("cb_pcidas64: hw status 0x%x ", status);
+ DEBUG_PRINT("plx status 0x%x\n", plx_status);
+
+ /* an interrupt before all the postconfig stuff gets done could
+ * cause a NULL dereference if we continue through the
+ * interrupt handler */
+ if (dev->attached == 0) {
+ DEBUG_PRINT("cb_pcidas64: premature interrupt, ignoring",
+ status);
+ return IRQ_HANDLED;
+ }
+ handle_ai_interrupt(dev, status, plx_status);
+ handle_ao_interrupt(dev, status, plx_status);
+
+ // clear possible plx9080 interrupt sources
+ if (plx_status & ICS_LDIA) { // clear local doorbell interrupt
+ plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
+ }
+
+ DEBUG_PRINT("exiting handler\n");
+
+ return IRQ_HANDLED;
+}
+
+void abort_dma(struct comedi_device * dev, unsigned int channel)
+{
+ unsigned long flags;
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static int ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ if (priv(dev)->ai_cmd_running == 0) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+ priv(dev)->ai_cmd_running = 0;
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ disable_ai_pacing(dev);
+
+ abort_dma(dev, 1);
+
+ DEBUG_PRINT("ai canceled\n");
+ return 0;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int range = CR_RANGE(insn->chanspec);
+
+ // do some initializing
+ writew(0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+
+ // set range
+ set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, chan, range);
+ writew(priv(dev)->dac_control1_bits,
+ priv(dev)->main_iobase + DAC_CONTROL1_REG);
+
+ // write to channel
+ if (board(dev)->layout == LAYOUT_4020) {
+ writew(data[0] & 0xff,
+ priv(dev)->main_iobase + dac_lsb_4020_reg(chan));
+ writew((data[0] >> 8) & 0xf,
+ priv(dev)->main_iobase + dac_msb_4020_reg(chan));
+ } else {
+ writew(data[0], priv(dev)->main_iobase + dac_convert_reg(chan));
+ }
+
+ // remember output value
+ priv(dev)->ao_value[chan] = data[0];
+
+ return 1;
+}
+
+static int ao_readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = priv(dev)->ao_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static void set_dac_control0_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int bits = DAC_ENABLE_BIT | WAVEFORM_GATE_LEVEL_BIT |
+ WAVEFORM_GATE_ENABLE_BIT | WAVEFORM_GATE_SELECT_BIT;
+
+ if (cmd->start_src == TRIG_EXT) {
+ bits |= WAVEFORM_TRIG_EXT_BITS;
+ if (cmd->start_arg & CR_INVERT)
+ bits |= WAVEFORM_TRIG_FALLING_BIT;
+ } else {
+ bits |= WAVEFORM_TRIG_SOFT_BITS;
+ }
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ bits |= DAC_EXT_UPDATE_ENABLE_BIT;
+ if (cmd->scan_begin_arg & CR_INVERT)
+ bits |= DAC_EXT_UPDATE_FALLING_BIT;
+ }
+ writew(bits, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+}
+
+static void set_dac_control1_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ int i;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ int channel, range;
+
+ channel = CR_CHAN(cmd->chanlist[i]);
+ range = CR_RANGE(cmd->chanlist[i]);
+ set_dac_range_bits(dev, &priv(dev)->dac_control1_bits, channel,
+ range);
+ }
+ priv(dev)->dac_control1_bits |= DAC_SW_GATE_BIT;
+ writew(priv(dev)->dac_control1_bits,
+ priv(dev)->main_iobase + DAC_CONTROL1_REG);
+}
+
+static void set_dac_select_reg(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ uint16_t bits;
+ unsigned int first_channel, last_channel;
+
+ first_channel = CR_CHAN(cmd->chanlist[0]);
+ last_channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+ if (last_channel < first_channel)
+ comedi_error(dev, "bug! last ao channel < first ao channel");
+
+ bits = (first_channel & 0x7) | (last_channel & 0x7) << 3;
+
+ writew(bits, priv(dev)->main_iobase + DAC_SELECT_REG);
+}
+
+static void set_dac_interval_regs(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int divisor;
+
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return;
+
+ divisor = get_ao_divisor(cmd->scan_begin_arg, cmd->flags);
+ if (divisor > max_counter_value) {
+ comedi_error(dev, "bug! ao divisor too big");
+ divisor = max_counter_value;
+ }
+ writew(divisor & 0xffff,
+ priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_LOWER_REG);
+ writew((divisor >> 16) & 0xff,
+ priv(dev)->main_iobase + DAC_SAMPLE_INTERVAL_UPPER_REG);
+}
+
+static unsigned int load_ao_dma_buffer(struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ unsigned int num_bytes, buffer_index, prev_buffer_index;
+ unsigned int next_bits;
+
+ buffer_index = priv(dev)->ao_dma_index;
+ prev_buffer_index = prev_ao_dma_index(dev);
+
+ DEBUG_PRINT("attempting to load ao buffer %i (0x%x)\n", buffer_index,
+ priv(dev)->ao_buffer_bus_addr[buffer_index]);
+
+ num_bytes = comedi_buf_read_n_available(dev->write_subdev->async);
+ if (num_bytes > DMA_BUFFER_SIZE)
+ num_bytes = DMA_BUFFER_SIZE;
+ if (cmd->stop_src == TRIG_COUNT && num_bytes > priv(dev)->ao_count)
+ num_bytes = priv(dev)->ao_count;
+ num_bytes -= num_bytes % bytes_in_sample;
+
+ if (num_bytes == 0)
+ return 0;
+
+ DEBUG_PRINT("loading %i bytes\n", num_bytes);
+
+ num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
+ priv(dev)->ao_buffer[buffer_index], num_bytes);
+ priv(dev)->ao_dma_desc[buffer_index].transfer_size =
+ cpu_to_le32(num_bytes);
+ /* set end of chain bit so we catch underruns */
+ next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[buffer_index].next);
+ next_bits |= PLX_END_OF_CHAIN_BIT;
+ priv(dev)->ao_dma_desc[buffer_index].next = cpu_to_le32(next_bits);
+ /* clear end of chain bit on previous buffer now that we have set it
+ * for the last buffer */
+ next_bits = le32_to_cpu(priv(dev)->ao_dma_desc[prev_buffer_index].next);
+ next_bits &= ~PLX_END_OF_CHAIN_BIT;
+ priv(dev)->ao_dma_desc[prev_buffer_index].next = cpu_to_le32(next_bits);
+
+ priv(dev)->ao_dma_index = (buffer_index + 1) % AO_DMA_RING_COUNT;
+ priv(dev)->ao_count -= num_bytes;
+
+ return num_bytes;
+}
+
+static void load_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int num_bytes;
+ unsigned int next_transfer_addr;
+ void *pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+ unsigned int buffer_index;
+
+ do {
+ buffer_index = priv(dev)->ao_dma_index;
+ /* don't overwrite data that hasn't been transferred yet */
+ next_transfer_addr = readl(pci_addr_reg);
+ if (next_transfer_addr >=
+ priv(dev)->ao_buffer_bus_addr[buffer_index]
+ && next_transfer_addr <
+ priv(dev)->ao_buffer_bus_addr[buffer_index] +
+ DMA_BUFFER_SIZE)
+ return;
+ num_bytes = load_ao_dma_buffer(dev, cmd);
+ } while (num_bytes >= DMA_BUFFER_SIZE);
+}
+
+static int prep_ao_dma(struct comedi_device * dev, const struct comedi_cmd * cmd)
+{
+ unsigned int num_bytes;
+ int i;
+
+ /* clear queue pointer too, since external queue has
+ * weird interactions with ao fifo */
+ writew(0, priv(dev)->main_iobase + ADC_QUEUE_CLEAR_REG);
+ writew(0, priv(dev)->main_iobase + DAC_BUFFER_CLEAR_REG);
+
+ num_bytes = (DAC_FIFO_SIZE / 2) * bytes_in_sample;
+ if (cmd->stop_src == TRIG_COUNT &&
+ num_bytes / bytes_in_sample > priv(dev)->ao_count)
+ num_bytes = priv(dev)->ao_count * bytes_in_sample;
+ num_bytes = cfc_read_array_from_buffer(dev->write_subdev,
+ priv(dev)->ao_bounce_buffer, num_bytes);
+ for (i = 0; i < num_bytes / bytes_in_sample; i++) {
+ writew(priv(dev)->ao_bounce_buffer[i],
+ priv(dev)->main_iobase + DAC_FIFO_REG);
+ }
+ priv(dev)->ao_count -= num_bytes / bytes_in_sample;
+ if (cmd->stop_src == TRIG_COUNT && priv(dev)->ao_count == 0)
+ return 0;
+ num_bytes = load_ao_dma_buffer(dev, cmd);
+ if (num_bytes == 0)
+ return -1;
+ if (num_bytes >= DMA_BUFFER_SIZE) ;
+ load_ao_dma(dev, cmd);
+
+ dma_start_sync(dev, 0);
+
+ return 0;
+}
+
+static inline int external_ai_queue_in_use(struct comedi_device * dev)
+{
+ if (dev->read_subdev->busy)
+ return 0;
+ if (board(dev)->layout == LAYOUT_4020)
+ return 0;
+ else if (use_internal_queue_6xxx(&dev->read_subdev->async->cmd))
+ return 0;
+ return 1;
+}
+
+static int ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (external_ai_queue_in_use(dev)) {
+ warn_external_queue(dev);
+ return -EBUSY;
+ }
+ /* disable analog output system during setup */
+ writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+
+ priv(dev)->ao_dma_index = 0;
+ priv(dev)->ao_count = cmd->stop_arg * cmd->chanlist_len;
+
+ set_dac_select_reg(dev, cmd);
+ set_dac_interval_regs(dev, cmd);
+ load_first_dma_descriptor(dev, 0, priv(dev)->ao_dma_desc_bus_addr |
+ PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT);
+
+ set_dac_control1_reg(dev, cmd);
+ s->async->inttrig = ao_inttrig;
+
+ return 0;
+}
+
+static int ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int retval;
+
+ if (trig_num != 0)
+ return -EINVAL;
+
+ retval = prep_ao_dma(dev, cmd);
+ if (retval < 0)
+ return -EPIPE;
+
+ set_dac_control0_reg(dev, cmd);
+
+ if (cmd->start_src == TRIG_INT)
+ writew(0, priv(dev)->main_iobase + DAC_START_REG);
+
+ s->async->inttrig = NULL;
+
+ return 0;
+}
+
+static int ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ unsigned int tmp_arg;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+
+ // compatibility check
+ if (cmd->convert_src == TRIG_EXT && cmd->scan_begin_src == TRIG_TIMER)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < board(dev)->ao_scan_speed) {
+ cmd->scan_begin_arg = board(dev)->ao_scan_speed;
+ err++;
+ }
+ if (get_ao_divisor(cmd->scan_begin_arg,
+ cmd->flags) > max_counter_value) {
+ cmd->scan_begin_arg =
+ (max_counter_value + 2) * TIMER_BASE;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp_arg = cmd->scan_begin_arg;
+ cmd->scan_begin_arg =
+ get_divisor(cmd->scan_begin_arg,
+ cmd->flags) * TIMER_BASE;
+ if (tmp_arg != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ if (cmd->chanlist) {
+ unsigned int first_channel = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != first_channel + i) {
+ comedi_error(dev,
+ "chanlist must use consecutive channels");
+ err++;
+ break;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writew(0x0, priv(dev)->main_iobase + DAC_CONTROL0_REG);
+ abort_dma(dev, 0);
+ return 0;
+}
+
+static int dio_callback(int dir, int port, int data, unsigned long iobase)
+{
+ if (dir) {
+ writeb(data, (void *)(iobase + port));
+ DEBUG_PRINT("wrote 0x%x to port %i\n", data, port);
+ return 0;
+ } else {
+ return readb((void *)(iobase + port));
+ }
+}
+
+static int dio_callback_4020(int dir, int port, int data, unsigned long iobase)
+{
+ if (dir) {
+ writew(data, (void *)(iobase + 2 * port));
+ return 0;
+ } else {
+ return readw((void *)(iobase + 2 * port));
+ }
+}
+
+static int di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = readb(priv(dev)->dio_counter_iobase + DI_REG);
+ bits &= 0xf;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] &= 0xf;
+ // zero bits we are going to change
+ s->state &= ~data[0];
+ // set new bits
+ s->state |= data[0] & data[1];
+
+ writeb(s->state, priv(dev)->dio_counter_iobase + DO_REG);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int dio_60xx_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return 2;
+ default:
+ return -EINVAL;
+ }
+
+ writeb(s->io_bits,
+ priv(dev)->dio_counter_iobase + DIO_DIRECTION_60XX_REG);
+
+ return 1;
+}
+
+static int dio_60xx_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ writeb(s->state,
+ priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+ }
+
+ data[1] = readb(priv(dev)->dio_counter_iobase + DIO_DATA_60XX_REG);
+
+ return 2;
+}
+
+static void caldac_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value)
+{
+ priv(dev)->caldac_state[channel] = value;
+
+ switch (board(dev)->layout) {
+ case LAYOUT_60XX:
+ case LAYOUT_64XX:
+ caldac_8800_write(dev, channel, value);
+ break;
+ case LAYOUT_4020:
+ caldac_i2c_write(dev, channel, value);
+ break;
+ default:
+ break;
+ }
+}
+
+static int calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+
+ /* return immediately if setting hasn't changed, since
+ * programming these things is slow */
+ if (priv(dev)->caldac_state[channel] == data[0])
+ return 1;
+
+ caldac_write(dev, channel, data[0]);
+
+ return 1;
+}
+
+static int calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ data[0] = priv(dev)->caldac_state[channel];
+
+ return 1;
+}
+
+static void ad8402_write(struct comedi_device * dev, unsigned int channel,
+ unsigned int value)
+{
+ static const int bitstream_length = 10;
+ unsigned int bit, register_bits;
+ unsigned int bitstream = ((channel & 0x3) << 8) | (value & 0xff);
+ static const int ad8402_comedi_udelay = 1;
+
+ priv(dev)->ad8402_state[channel] = value;
+
+ register_bits = SELECT_8402_64XX_BIT;
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ if (bitstream & bit)
+ register_bits |= SERIAL_DATA_IN_BIT;
+ else
+ register_bits &= ~SERIAL_DATA_IN_BIT;
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(register_bits | SERIAL_CLOCK_BIT,
+ priv(dev)->main_iobase + CALIBRATION_REG);
+ }
+
+ comedi_udelay(ad8402_comedi_udelay);
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+}
+
+/* for pci-das6402/16, channel 0 is analog input gain and channel 1 is offset */
+static int ad8402_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+
+ /* return immediately if setting hasn't changed, since
+ * programming these things is slow */
+ if (priv(dev)->ad8402_state[channel] == data[0])
+ return 1;
+
+ priv(dev)->ad8402_state[channel] = data[0];
+
+ ad8402_write(dev, channel, data[0]);
+
+ return 1;
+}
+
+static int ad8402_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int channel = CR_CHAN(insn->chanspec);
+
+ data[0] = priv(dev)->ad8402_state[channel];
+
+ return 1;
+}
+
+static uint16_t read_eeprom(struct comedi_device * dev, uint8_t address)
+{
+ static const int bitstream_length = 11;
+ static const int read_command = 0x6;
+ unsigned int bitstream = (read_command << 8) | address;
+ unsigned int bit;
+ void *const plx_control_addr =
+ priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+ uint16_t value;
+ static const int value_length = 16;
+ static const int eeprom_comedi_udelay = 1;
+
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CLK & ~CTL_EE_CS;
+ // make sure we don't send anything to the i2c bus on 4020
+ priv(dev)->plx_control_bits |= CTL_USERO;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ // activate serial eeprom
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits |= CTL_EE_CS;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+
+ // write read command and desired memory address
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ // set bit to be written
+ comedi_udelay(eeprom_comedi_udelay);
+ if (bitstream & bit)
+ priv(dev)->plx_control_bits |= CTL_EE_W;
+ else
+ priv(dev)->plx_control_bits &= ~CTL_EE_W;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ // clock in bit
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits |= CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ }
+ // read back value from eeprom memory location
+ value = 0;
+ for (bit = 1 << (value_length - 1); bit; bit >>= 1) {
+ // clock out bit
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits |= CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CLK;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(eeprom_comedi_udelay);
+ if (readl(plx_control_addr) & CTL_EE_R)
+ value |= bit;
+ }
+
+ // deactivate eeprom serial input
+ comedi_udelay(eeprom_comedi_udelay);
+ priv(dev)->plx_control_bits &= ~CTL_EE_CS;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+
+ return value;
+}
+
+static int eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = read_eeprom(dev, CR_CHAN(insn->chanspec));
+
+ return 1;
+}
+
+/* utility function that rounds desired timing to an achievable time, and
+ * sets cmd members appropriately.
+ * adc paces conversions from master clock by dividing by (x + 3) where x is 24 bit number
+ */
+static void check_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd)
+{
+ unsigned int convert_divisor = 0, scan_divisor;
+ static const int min_convert_divisor = 3;
+ static const int max_convert_divisor =
+ max_counter_value + min_convert_divisor;
+ static const int min_scan_divisor_4020 = 2;
+ unsigned long long max_scan_divisor, min_scan_divisor;
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (board(dev)->layout == LAYOUT_4020) {
+ cmd->convert_arg = 0;
+ } else {
+ convert_divisor =
+ get_divisor(cmd->convert_arg, cmd->flags);
+ if (convert_divisor > max_convert_divisor)
+ convert_divisor = max_convert_divisor;
+ if (convert_divisor < min_convert_divisor)
+ convert_divisor = min_convert_divisor;
+ cmd->convert_arg = convert_divisor * TIMER_BASE;
+ }
+ } else if (cmd->convert_src == TRIG_NOW)
+ cmd->convert_arg = 0;
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ scan_divisor = get_divisor(cmd->scan_begin_arg, cmd->flags);
+ if (cmd->convert_src == TRIG_TIMER) {
+ // XXX check for integer overflows
+ min_scan_divisor = convert_divisor * cmd->chanlist_len;
+ max_scan_divisor =
+ (convert_divisor * cmd->chanlist_len - 1) +
+ max_counter_value;
+ } else {
+ min_scan_divisor = min_scan_divisor_4020;
+ max_scan_divisor = max_counter_value + min_scan_divisor;
+ }
+ if (scan_divisor > max_scan_divisor)
+ scan_divisor = max_scan_divisor;
+ if (scan_divisor < min_scan_divisor)
+ scan_divisor = min_scan_divisor;
+ cmd->scan_begin_arg = scan_divisor * TIMER_BASE;
+ }
+
+ return;
+}
+
+/* Gets nearest achievable timing given master clock speed, does not
+ * take into account possible minimum/maximum divisor values. Used
+ * by other timing checking functions. */
+static unsigned int get_divisor(unsigned int ns, unsigned int flags)
+{
+ unsigned int divisor;
+
+ switch (flags & TRIG_ROUND_MASK) {
+ case TRIG_ROUND_UP:
+ divisor = (ns + TIMER_BASE - 1) / TIMER_BASE;
+ break;
+ case TRIG_ROUND_DOWN:
+ divisor = ns / TIMER_BASE;
+ break;
+ case TRIG_ROUND_NEAREST:
+ default:
+ divisor = (ns + TIMER_BASE / 2) / TIMER_BASE;
+ break;
+ }
+ return divisor;
+}
+
+static unsigned int get_ao_divisor(unsigned int ns, unsigned int flags)
+{
+ return get_divisor(ns, flags) - 2;
+}
+
+// adjusts the size of hardware fifo (which determines block size for dma xfers)
+static int set_ai_fifo_size(struct comedi_device * dev, unsigned int num_samples)
+{
+ unsigned int num_fifo_entries;
+ int retval;
+ const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+
+ num_fifo_entries = num_samples / fifo->sample_packing_ratio;
+
+ retval = set_ai_fifo_segment_length(dev,
+ num_fifo_entries / fifo->num_segments);
+ if (retval < 0)
+ return retval;
+
+ num_samples = retval * fifo->num_segments * fifo->sample_packing_ratio;
+
+ DEBUG_PRINT("set hardware fifo size to %i\n", num_samples);
+
+ return num_samples;
+}
+
+// query length of fifo
+static unsigned int ai_fifo_size(struct comedi_device * dev)
+{
+ return priv(dev)->ai_fifo_segment_length *
+ board(dev)->ai_fifo->num_segments *
+ board(dev)->ai_fifo->sample_packing_ratio;
+}
+
+static int set_ai_fifo_segment_length(struct comedi_device * dev,
+ unsigned int num_entries)
+{
+ static const int increment_size = 0x100;
+ const struct hw_fifo_info *const fifo = board(dev)->ai_fifo;
+ unsigned int num_increments;
+ uint16_t bits;
+
+ if (num_entries < increment_size)
+ num_entries = increment_size;
+ if (num_entries > fifo->max_segment_length)
+ num_entries = fifo->max_segment_length;
+
+ // 1 == 256 entries, 2 == 512 entries, etc
+ num_increments = (num_entries + increment_size / 2) / increment_size;
+
+ bits = (~(num_increments - 1)) & fifo->fifo_size_reg_mask;
+ priv(dev)->fifo_size_bits &= ~fifo->fifo_size_reg_mask;
+ priv(dev)->fifo_size_bits |= bits;
+ writew(priv(dev)->fifo_size_bits,
+ priv(dev)->main_iobase + FIFO_SIZE_REG);
+
+ priv(dev)->ai_fifo_segment_length = num_increments * increment_size;
+
+ DEBUG_PRINT("set hardware fifo segment length to %i\n",
+ priv(dev)->ai_fifo_segment_length);
+
+ return priv(dev)->ai_fifo_segment_length;
+}
+
+/* pci-6025 8800 caldac:
+ * address 0 == dac channel 0 offset
+ * address 1 == dac channel 0 gain
+ * address 2 == dac channel 1 offset
+ * address 3 == dac channel 1 gain
+ * address 4 == fine adc offset
+ * address 5 == coarse adc offset
+ * address 6 == coarse adc gain
+ * address 7 == fine adc gain
+ */
+/* pci-6402/16 uses all 8 channels for dac:
+ * address 0 == dac channel 0 fine gain
+ * address 1 == dac channel 0 coarse gain
+ * address 2 == dac channel 0 coarse offset
+ * address 3 == dac channel 1 coarse offset
+ * address 4 == dac channel 1 fine gain
+ * address 5 == dac channel 1 coarse gain
+ * address 6 == dac channel 0 fine offset
+ * address 7 == dac channel 1 fine offset
+*/
+
+static int caldac_8800_write(struct comedi_device * dev, unsigned int address,
+ uint8_t value)
+{
+ static const int num_caldac_channels = 8;
+ static const int bitstream_length = 11;
+ unsigned int bitstream = ((address & 0x7) << 8) | value;
+ unsigned int bit, register_bits;
+ static const int caldac_8800_udelay = 1;
+
+ if (address >= num_caldac_channels) {
+ comedi_error(dev, "illegal caldac channel");
+ return -1;
+ }
+ for (bit = 1 << (bitstream_length - 1); bit; bit >>= 1) {
+ register_bits = 0;
+ if (bitstream & bit)
+ register_bits |= SERIAL_DATA_IN_BIT;
+ comedi_udelay(caldac_8800_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ register_bits |= SERIAL_CLOCK_BIT;
+ comedi_udelay(caldac_8800_udelay);
+ writew(register_bits, priv(dev)->main_iobase + CALIBRATION_REG);
+ }
+ comedi_udelay(caldac_8800_udelay);
+ writew(SELECT_8800_BIT, priv(dev)->main_iobase + CALIBRATION_REG);
+ comedi_udelay(caldac_8800_udelay);
+ writew(0, priv(dev)->main_iobase + CALIBRATION_REG);
+ comedi_udelay(caldac_8800_udelay);
+ return 0;
+}
+
+// 4020 caldacs
+static int caldac_i2c_write(struct comedi_device * dev, unsigned int caldac_channel,
+ unsigned int value)
+{
+ uint8_t serial_bytes[3];
+ uint8_t i2c_addr;
+ enum pointer_bits {
+ // manual has gain and offset bits switched
+ OFFSET_0_2 = 0x1,
+ GAIN_0_2 = 0x2,
+ OFFSET_1_3 = 0x4,
+ GAIN_1_3 = 0x8,
+ };
+ enum data_bits {
+ NOT_CLEAR_REGISTERS = 0x20,
+ };
+
+ switch (caldac_channel) {
+ case 0: // chan 0 offset
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = OFFSET_0_2;
+ break;
+ case 1: // chan 1 offset
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = OFFSET_1_3;
+ break;
+ case 2: // chan 2 offset
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = OFFSET_0_2;
+ break;
+ case 3: // chan 3 offset
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = OFFSET_1_3;
+ break;
+ case 4: // chan 0 gain
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = GAIN_0_2;
+ break;
+ case 5: // chan 1 gain
+ i2c_addr = CALDAC0_I2C_ADDR;
+ serial_bytes[0] = GAIN_1_3;
+ break;
+ case 6: // chan 2 gain
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = GAIN_0_2;
+ break;
+ case 7: // chan 3 gain
+ i2c_addr = CALDAC1_I2C_ADDR;
+ serial_bytes[0] = GAIN_1_3;
+ break;
+ default:
+ comedi_error(dev, "invalid caldac channel\n");
+ return -1;
+ break;
+ }
+ serial_bytes[1] = NOT_CLEAR_REGISTERS | ((value >> 8) & 0xf);
+ serial_bytes[2] = value & 0xff;
+ i2c_write(dev, i2c_addr, serial_bytes, 3);
+ return 0;
+}
+
+// Their i2c requires a huge delay on setting clock or data high for some reason
+static const int i2c_high_comedi_udelay = 1000;
+static const int i2c_low_comedi_udelay = 10;
+
+// set i2c data line high or low
+static void i2c_set_sda(struct comedi_device * dev, int state)
+{
+ static const int data_bit = CTL_EE_W;
+ void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+
+ if (state) {
+ // set data line high
+ priv(dev)->plx_control_bits &= ~data_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_high_comedi_udelay);
+ } else // set data line low
+ {
+ priv(dev)->plx_control_bits |= data_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_low_comedi_udelay);
+ }
+}
+
+// set i2c clock line high or low
+static void i2c_set_scl(struct comedi_device * dev, int state)
+{
+ static const int clock_bit = CTL_USERO;
+ void *plx_control_addr = priv(dev)->plx9080_iobase + PLX_CONTROL_REG;
+
+ if (state) {
+ // set clock line high
+ priv(dev)->plx_control_bits &= ~clock_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_high_comedi_udelay);
+ } else // set clock line low
+ {
+ priv(dev)->plx_control_bits |= clock_bit;
+ writel(priv(dev)->plx_control_bits, plx_control_addr);
+ comedi_udelay(i2c_low_comedi_udelay);
+ }
+}
+
+static void i2c_write_byte(struct comedi_device * dev, uint8_t byte)
+{
+ uint8_t bit;
+ unsigned int num_bits = 8;
+
+ DEBUG_PRINT("writing to i2c byte 0x%x\n", byte);
+
+ for (bit = 1 << (num_bits - 1); bit; bit >>= 1) {
+ i2c_set_scl(dev, 0);
+ if ((byte & bit))
+ i2c_set_sda(dev, 1);
+ else
+ i2c_set_sda(dev, 0);
+ i2c_set_scl(dev, 1);
+ }
+}
+
+// we can't really read the lines, so fake it
+static int i2c_read_ack(struct comedi_device * dev)
+{
+ i2c_set_scl(dev, 0);
+ i2c_set_sda(dev, 1);
+ i2c_set_scl(dev, 1);
+
+ return 0; // return fake acknowledge bit
+}
+
+// send start bit
+static void i2c_start(struct comedi_device * dev)
+{
+ i2c_set_scl(dev, 1);
+ i2c_set_sda(dev, 1);
+ i2c_set_sda(dev, 0);
+}
+
+// send stop bit
+static void i2c_stop(struct comedi_device * dev)
+{
+ i2c_set_scl(dev, 0);
+ i2c_set_sda(dev, 0);
+ i2c_set_scl(dev, 1);
+ i2c_set_sda(dev, 1);
+}
+
+static void i2c_write(struct comedi_device * dev, unsigned int address,
+ const uint8_t * data, unsigned int length)
+{
+ unsigned int i;
+ uint8_t bitstream;
+ static const int read_bit = 0x1;
+
+//XXX need mutex to prevent simultaneous attempts to access eeprom and i2c bus
+
+ // make sure we dont send anything to eeprom
+ priv(dev)->plx_control_bits &= ~CTL_EE_CS;
+
+ i2c_stop(dev);
+ i2c_start(dev);
+
+ // send address and write bit
+ bitstream = (address << 1) & ~read_bit;
+ i2c_write_byte(dev, bitstream);
+
+ // get acknowledge
+ if (i2c_read_ack(dev) != 0) {
+ comedi_error(dev, "i2c write failed: no acknowledge");
+ i2c_stop(dev);
+ return;
+ }
+ // write data bytes
+ for (i = 0; i < length; i++) {
+ i2c_write_byte(dev, data[i]);
+ if (i2c_read_ack(dev) != 0) {
+ comedi_error(dev, "i2c write failed: no acknowledge");
+ i2c_stop(dev);
+ return;
+ }
+ }
+ i2c_stop(dev);
+}
diff --git a/drivers/staging/comedi/drivers/cb_pcidda.c b/drivers/staging/comedi/drivers/cb_pcidda.c
new file mode 100644
index 00000000000..ed0a5eb3dd9
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidda.c
@@ -0,0 +1,841 @@
+/*
+ comedi/drivers/cb_pcidda.c
+ This intends to be a driver for the ComputerBoards / MeasurementComputing
+ PCI-DDA series.
+
+ Copyright (C) 2001 Ivan Martinez <ivanmr@altavista.com>
+ Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcidda
+Description: MeasurementComputing PCI-DDA series
+Author: Ivan Martinez <ivanmr@altavista.com>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: Supports 08/16, 04/16, 02/16, 08/12, 04/12, and 02/12
+Devices: [Measurement Computing] PCI-DDA08/12 (cb_pcidda), PCI-DDA04/12,
+ PCI-DDA02/12, PCI-DDA08/16, PCI-DDA04/16, PCI-DDA02/16
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI
+ device will be used.
+
+Only simple analog output writing is supported.
+
+So far it has only been tested with:
+ - PCI-DDA08/12
+Please report success/failure with other different cards to
+<comedi@comedi.org>.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#define PCI_VENDOR_ID_CB 0x1307 // PCI vendor number of ComputerBoards
+#define N_BOARDS 10 // Number of boards in cb_pcidda_boards
+#define EEPROM_SIZE 128 // number of entries in eeprom
+#define MAX_AO_CHANNELS 8 // maximum number of ao channels for supported boards
+
+/* PCI-DDA base addresses */
+#define DIGITALIO_BADRINDEX 2
+ // DIGITAL I/O is pci_dev->resource[2]
+#define DIGITALIO_SIZE 8
+ // DIGITAL I/O uses 8 I/O port addresses
+#define DAC_BADRINDEX 3
+ // DAC is pci_dev->resource[3]
+
+/* Digital I/O registers */
+#define PORT1A 0 // PORT 1A DATA
+
+#define PORT1B 1 // PORT 1B DATA
+
+#define PORT1C 2 // PORT 1C DATA
+
+#define CONTROL1 3 // CONTROL REGISTER 1
+
+#define PORT2A 4 // PORT 2A DATA
+
+#define PORT2B 5 // PORT 2B DATA
+
+#define PORT2C 6 // PORT 2C DATA
+
+#define CONTROL2 7 // CONTROL REGISTER 2
+
+/* DAC registers */
+#define DACONTROL 0 // D/A CONTROL REGISTER
+#define SU 0000001 // Simultaneous update enabled
+#define NOSU 0000000 // Simultaneous update disabled
+#define ENABLEDAC 0000002 // Enable specified DAC
+#define DISABLEDAC 0000000 // Disable specified DAC
+#define RANGE2V5 0000000 // 2.5V
+#define RANGE5V 0000200 // 5V
+#define RANGE10V 0000300 // 10V
+#define UNIP 0000400 // Unipolar outputs
+#define BIP 0000000 // Bipolar outputs
+
+#define DACALIBRATION1 4 // D/A CALIBRATION REGISTER 1
+//write bits
+#define SERIAL_IN_BIT 0x1 // serial data input for eeprom, caldacs, reference dac
+#define CAL_CHANNEL_MASK (0x7 << 1)
+#define CAL_CHANNEL_BITS(channel) (((channel) << 1) & CAL_CHANNEL_MASK)
+//read bits
+#define CAL_COUNTER_MASK 0x1f
+#define CAL_COUNTER_OVERFLOW_BIT 0x20 // calibration counter overflow status bit
+#define AO_BELOW_REF_BIT 0x40 // analog output is less than reference dac voltage
+#define SERIAL_OUT_BIT 0x80 // serial data out, for reading from eeprom
+
+#define DACALIBRATION2 6 // D/A CALIBRATION REGISTER 2
+#define SELECT_EEPROM_BIT 0x1 // send serial data in to eeprom
+#define DESELECT_REF_DAC_BIT 0x2 // don't send serial data to MAX542 reference dac
+#define DESELECT_CALDAC_BIT(n) (0x4 << (n)) // don't send serial data to caldac n
+#define DUMMY_BIT 0x40 // manual says to set this bit with no explanation
+
+#define DADATA 8 // FIRST D/A DATA REGISTER (0)
+
+static const struct comedi_lrange cb_pcidda_ranges = {
+ 6,
+ {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ }
+};
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct cb_pcidda_board {
+ const char *name;
+ char status; // Driver status:
+ // 0 - tested
+ // 1 - manual read, not tested
+ // 2 - manual not read
+ unsigned short device_id;
+ int ao_chans;
+ int ao_bits;
+ const struct comedi_lrange *ranges;
+};
+static const struct cb_pcidda_board cb_pcidda_boards[] = {
+ {
+ name: "pci-dda02/12",
+ status: 1,
+ device_id:0x20,
+ ao_chans:2,
+ ao_bits: 12,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda04/12",
+ status: 1,
+ device_id:0x21,
+ ao_chans:4,
+ ao_bits: 12,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda08/12",
+ status: 0,
+ device_id:0x22,
+ ao_chans:8,
+ ao_bits: 12,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda02/16",
+ status: 2,
+ device_id:0x23,
+ ao_chans:2,
+ ao_bits: 16,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda04/16",
+ status: 2,
+ device_id:0x24,
+ ao_chans:4,
+ ao_bits: 16,
+ ranges: &cb_pcidda_ranges,
+ },
+ {
+ name: "pci-dda08/16",
+ status: 0,
+ device_id:0x25,
+ ao_chans:8,
+ ao_bits: 16,
+ ranges: &cb_pcidda_ranges,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(cb_pcidda_pci_table) = {
+ {PCI_VENDOR_ID_CB, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0021, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcidda_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcidda_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct cb_pcidda_private {
+ int data;
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ unsigned long digitalio;
+ unsigned long dac;
+ //unsigned long control_status;
+ //unsigned long adc_fifo;
+ unsigned int dac_cal1_bits; // bits last written to da calibration register 1
+ unsigned int ao_range[MAX_AO_CHANNELS]; // current range settings for output channels
+ u16 eeprom_data[EEPROM_SIZE]; // software copy of board's eeprom
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcidda_private *)dev->private)
+
+static int cb_pcidda_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcidda_detach(struct comedi_device * dev);
+//static int cb_pcidda_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data);
+static int cb_pcidda_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+//static int cb_pcidda_ai_cmd(struct comedi_device *dev,struct comedi_subdevice *s);
+//static int cb_pcidda_ai_cmdtest(struct comedi_device *dev,struct comedi_subdevice *s, struct comedi_cmd *cmd);
+//static int cb_pcidda_ns_to_timer(unsigned int *ns,int round);
+static unsigned int cb_pcidda_serial_in(struct comedi_device * dev);
+static void cb_pcidda_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int num_bits);
+static unsigned int cb_pcidda_read_eeprom(struct comedi_device * dev,
+ unsigned int address);
+static void cb_pcidda_calibrate(struct comedi_device * dev, unsigned int channel,
+ unsigned int range);
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static struct comedi_driver driver_cb_pcidda = {
+ driver_name:"cb_pcidda",
+ module:THIS_MODULE,
+ attach:cb_pcidda_attach,
+ detach:cb_pcidda_detach,
+};
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board.
+ */
+static int cb_pcidda_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pcidev;
+ int index;
+
+ printk("comedi%d: cb_pcidda: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct cb_pcidda_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+ printk("\n");
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ if (pcidev->vendor == PCI_VENDOR_ID_CB) {
+ if (it->options[0] || it->options[1]) {
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ for (index = 0; index < N_BOARDS; index++) {
+ if (cb_pcidda_boards[index].device_id ==
+ pcidev->device) {
+ goto found;
+ }
+ }
+ }
+ }
+ if (!pcidev) {
+ printk("Not a ComputerBoards/MeasurementComputing card on requested position\n");
+ return -EIO;
+ }
+ found:
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = cb_pcidda_boards + index;
+ // "thisboard" macro can be used from here.
+ printk("Found %s at requested position\n", thisboard->name);
+
+ /*
+ * Enable PCI device and request regions.
+ */
+ if (comedi_pci_enable(pcidev, thisboard->name)) {
+ printk("cb_pcidda: failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+
+/*
+ * Allocate the I/O ports.
+ */
+ devpriv->digitalio =
+ pci_resource_start(devpriv->pci_dev, DIGITALIO_BADRINDEX);
+ devpriv->dac = pci_resource_start(devpriv->pci_dev, DAC_BADRINDEX);
+
+/*
+ * Warn about the status of the driver.
+ */
+ if (thisboard->status == 2)
+ printk("WARNING: DRIVER FOR THIS BOARD NOT CHECKED WITH MANUAL. " "WORKS ASSUMING FULL COMPATIBILITY WITH PCI-DDA08/12. " "PLEASE REPORT USAGE TO <ivanmr@altavista.com>.\n");
+
+/*
+ * Initialize dev->board_name.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = thisboard->ranges;
+ s->insn_write = cb_pcidda_ao_winsn;
+// s->subdev_flags |= SDF_CMD_READ;
+// s->do_cmd = cb_pcidda_ai_cmd;
+// s->do_cmdtest = cb_pcidda_ai_cmdtest;
+
+ // two 8255 digital io subdevices
+ s = dev->subdevices + 1;
+ subdev_8255_init(dev, s, NULL, devpriv->digitalio);
+ s = dev->subdevices + 2;
+ subdev_8255_init(dev, s, NULL, devpriv->digitalio + PORT2A);
+
+ printk(" eeprom:");
+ for (index = 0; index < EEPROM_SIZE; index++) {
+ devpriv->eeprom_data[index] = cb_pcidda_read_eeprom(dev, index);
+ printk(" %i:0x%x ", index, devpriv->eeprom_data[index]);
+ }
+ printk("\n");
+
+ // set calibrations dacs
+ for (index = 0; index < thisboard->ao_chans; index++)
+ cb_pcidda_calibrate(dev, index, devpriv->ao_range[index]);
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcidda_detach(struct comedi_device * dev)
+{
+/*
+ * Deallocate the I/O ports.
+ */
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->dac) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ // cleanup 8255
+ if (dev->subdevices) {
+ subdev_8255_cleanup(dev, dev->subdevices + 1);
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ }
+
+ printk("comedi%d: cb_pcidda: remove\n", dev->minor);
+
+ return 0;
+}
+
+/*
+ * I will program this later... ;-)
+ */
+#if 0
+static int cb_pcidda_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ printk("cb_pcidda_ai_cmd\n");
+ printk("subdev: %d\n", cmd->subdev);
+ printk("flags: %d\n", cmd->flags);
+ printk("start_src: %d\n", cmd->start_src);
+ printk("start_arg: %d\n", cmd->start_arg);
+ printk("scan_begin_src: %d\n", cmd->scan_begin_src);
+ printk("convert_src: %d\n", cmd->convert_src);
+ printk("convert_arg: %d\n", cmd->convert_arg);
+ printk("scan_end_src: %d\n", cmd->scan_end_src);
+ printk("scan_end_arg: %d\n", cmd->scan_end_arg);
+ printk("stop_src: %d\n", cmd->stop_src);
+ printk("stop_arg: %d\n", cmd->stop_arg);
+ printk("chanlist_len: %d\n", cmd->chanlist_len);
+}
+#endif
+
+#if 0
+static int cb_pcidda_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER
+ && cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* in nanoseconds */
+#define MIN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED) {
+ cmd->scan_begin_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED) {
+ cmd->convert_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ cb_pcidda_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ cb_pcidda_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+#endif
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers. It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device. Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+#if 0
+static int cb_pcidda_ns_to_timer(unsigned int *ns, int round)
+{
+ /* trivial timer */
+ return *ns;
+}
+#endif
+
+static int cb_pcidda_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int command;
+ unsigned int channel, range;
+
+ channel = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ // adjust calibration dacs if range has changed
+ if (range != devpriv->ao_range[channel])
+ cb_pcidda_calibrate(dev, channel, range);
+
+ /* output channel configuration */
+ command = NOSU | ENABLEDAC;
+
+ /* output channel range */
+ switch (range) {
+ case 0:
+ command |= BIP | RANGE10V;
+ break;
+ case 1:
+ command |= BIP | RANGE5V;
+ break;
+ case 2:
+ command |= BIP | RANGE2V5;
+ break;
+ case 3:
+ command |= UNIP | RANGE10V;
+ break;
+ case 4:
+ command |= UNIP | RANGE5V;
+ break;
+ case 5:
+ command |= UNIP | RANGE2V5;
+ break;
+ };
+
+ /* output channel specification */
+ command |= channel << 2;
+ outw(command, devpriv->dac + DACONTROL);
+
+ /* write data */
+ outw(data[0], devpriv->dac + DADATA + channel * 2);
+
+ /* return the number of samples read/written */
+ return 1;
+}
+
+// lowlevel read from eeprom
+static unsigned int cb_pcidda_serial_in(struct comedi_device * dev)
+{
+ unsigned int value = 0;
+ int i;
+ const int value_width = 16; // number of bits wide values are
+
+ for (i = 1; i <= value_width; i++) {
+ // read bits most significant bit first
+ if (inw_p(devpriv->dac + DACALIBRATION1) & SERIAL_OUT_BIT) {
+ value |= 1 << (value_width - i);
+ }
+ }
+
+ return value;
+}
+
+// lowlevel write to eeprom/dac
+static void cb_pcidda_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int num_bits)
+{
+ int i;
+
+ for (i = 1; i <= num_bits; i++) {
+ // send bits most significant bit first
+ if (value & (1 << (num_bits - i)))
+ devpriv->dac_cal1_bits |= SERIAL_IN_BIT;
+ else
+ devpriv->dac_cal1_bits &= ~SERIAL_IN_BIT;
+ outw_p(devpriv->dac_cal1_bits, devpriv->dac + DACALIBRATION1);
+ }
+}
+
+// reads a 16 bit value from board's eeprom
+static unsigned int cb_pcidda_read_eeprom(struct comedi_device * dev,
+ unsigned int address)
+{
+ unsigned int i;
+ unsigned int cal2_bits;
+ unsigned int value;
+ const int max_num_caldacs = 4; // one caldac for every two dac channels
+ const int read_instruction = 0x6; // bits to send to tell eeprom we want to read
+ const int instruction_length = 3;
+ const int address_length = 8;
+
+ // send serial output stream to eeprom
+ cal2_bits = SELECT_EEPROM_BIT | DESELECT_REF_DAC_BIT | DUMMY_BIT;
+ // deactivate caldacs (one caldac for every two channels)
+ for (i = 0; i < max_num_caldacs; i++) {
+ cal2_bits |= DESELECT_CALDAC_BIT(i);
+ }
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+
+ // tell eeprom we want to read
+ cb_pcidda_serial_out(dev, read_instruction, instruction_length);
+ // send address we want to read from
+ cb_pcidda_serial_out(dev, address, address_length);
+
+ value = cb_pcidda_serial_in(dev);
+
+ // deactivate eeprom
+ cal2_bits &= ~SELECT_EEPROM_BIT;
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+
+ return value;
+}
+
+// writes to 8 bit calibration dacs
+static void cb_pcidda_write_caldac(struct comedi_device * dev, unsigned int caldac,
+ unsigned int channel, unsigned int value)
+{
+ unsigned int cal2_bits;
+ unsigned int i;
+ const int num_channel_bits = 3; // caldacs use 3 bit channel specification
+ const int num_caldac_bits = 8; // 8 bit calibration dacs
+ const int max_num_caldacs = 4; // one caldac for every two dac channels
+
+ /* write 3 bit channel */
+ cb_pcidda_serial_out(dev, channel, num_channel_bits);
+ // write 8 bit caldac value
+ cb_pcidda_serial_out(dev, value, num_caldac_bits);
+
+ // latch stream into appropriate caldac
+ // deselect reference dac
+ cal2_bits = DESELECT_REF_DAC_BIT | DUMMY_BIT;
+ // deactivate caldacs (one caldac for every two channels)
+ for (i = 0; i < max_num_caldacs; i++) {
+ cal2_bits |= DESELECT_CALDAC_BIT(i);
+ }
+ // activate the caldac we want
+ cal2_bits &= ~DESELECT_CALDAC_BIT(caldac);
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+ // deactivate caldac
+ cal2_bits |= DESELECT_CALDAC_BIT(caldac);
+ outw_p(cal2_bits, devpriv->dac + DACALIBRATION2);
+}
+
+// returns caldac that calibrates given analog out channel
+static unsigned int caldac_number(unsigned int channel)
+{
+ return channel / 2;
+}
+
+// returns caldac channel that provides fine gain for given ao channel
+static unsigned int fine_gain_channel(unsigned int ao_channel)
+{
+ return 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides coarse gain for given ao channel
+static unsigned int coarse_gain_channel(unsigned int ao_channel)
+{
+ return 1 + 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides coarse offset for given ao channel
+static unsigned int coarse_offset_channel(unsigned int ao_channel)
+{
+ return 2 + 4 * (ao_channel % 2);
+}
+
+// returns caldac channel that provides fine offset for given ao channel
+static unsigned int fine_offset_channel(unsigned int ao_channel)
+{
+ return 3 + 4 * (ao_channel % 2);
+}
+
+// returns eeprom address that provides offset for given ao channel and range
+static unsigned int offset_eeprom_address(unsigned int ao_channel,
+ unsigned int range)
+{
+ return 0x7 + 2 * range + 12 * ao_channel;
+}
+
+// returns eeprom address that provides gain calibration for given ao channel and range
+static unsigned int gain_eeprom_address(unsigned int ao_channel,
+ unsigned int range)
+{
+ return 0x8 + 2 * range + 12 * ao_channel;
+}
+
+// returns upper byte of eeprom entry, which gives the coarse adjustment values
+static unsigned int eeprom_coarse_byte(unsigned int word)
+{
+ return (word >> 8) & 0xff;
+}
+
+// returns lower byte of eeprom entry, which gives the fine adjustment values
+static unsigned int eeprom_fine_byte(unsigned int word)
+{
+ return word & 0xff;
+}
+
+// set caldacs to eeprom values for given channel and range
+static void cb_pcidda_calibrate(struct comedi_device * dev, unsigned int channel,
+ unsigned int range)
+{
+ unsigned int coarse_offset, fine_offset, coarse_gain, fine_gain;
+
+ // remember range so we can tell when we need to readjust calibration
+ devpriv->ao_range[channel] = range;
+
+ // get values from eeprom data
+ coarse_offset =
+ eeprom_coarse_byte(devpriv->
+ eeprom_data[offset_eeprom_address(channel, range)]);
+ fine_offset =
+ eeprom_fine_byte(devpriv->
+ eeprom_data[offset_eeprom_address(channel, range)]);
+ coarse_gain =
+ eeprom_coarse_byte(devpriv->
+ eeprom_data[gain_eeprom_address(channel, range)]);
+ fine_gain =
+ eeprom_fine_byte(devpriv->
+ eeprom_data[gain_eeprom_address(channel, range)]);
+
+ // set caldacs
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ coarse_offset_channel(channel), coarse_offset);
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ fine_offset_channel(channel), fine_offset);
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ coarse_gain_channel(channel), coarse_gain);
+ cb_pcidda_write_caldac(dev, caldac_number(channel),
+ fine_gain_channel(channel), fine_gain);
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidda, cb_pcidda_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcidio.c b/drivers/staging/comedi/drivers/cb_pcidio.c
new file mode 100644
index 00000000000..71a4b1482e3
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcidio.c
@@ -0,0 +1,294 @@
+/*
+ comedi/drivers/cb_pcidio.c
+ A Comedi driver for PCI-DIO24H & PCI-DIO48H of ComputerBoards (currently MeasurementComputing)
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcidio
+Description: ComputerBoards' DIO boards with PCI interface
+Devices: [Measurement Computing] PCI-DIO24 (cb_pcidio), PCI-DIO24H, PCI-DIO48H
+Author: Yoshiya Matsuzaka
+Updated: Mon, 29 Oct 2007 15:40:47 +0000
+Status: experimental
+
+This driver has been modified from skel.c of comedi-0.7.70.
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first available PCI device will
+ be used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+*/
+
+/*------------------------------ HEADER FILES ---------------------------------*/
+#include "../comedidev.h"
+#include "comedi_pci.h"
+#include "8255.h"
+
+/*-------------------------- MACROS and DATATYPES -----------------------------*/
+#define PCI_VENDOR_ID_CB 0x1307
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcidio_board {
+ const char *name; // anme of the board
+ int n_8255; // number of 8255 chips on board
+
+ // indices of base address regions
+ int pcicontroler_badrindex;
+ int dioregs_badrindex;
+};
+
+static const struct pcidio_board pcidio_boards[] = {
+ {
+ name: "pci-dio24",
+ n_8255: 1,
+ pcicontroler_badrindex:1,
+ dioregs_badrindex:2,
+ },
+ {
+ name: "pci-dio24h",
+ n_8255: 1,
+ pcicontroler_badrindex:1,
+ dioregs_badrindex:2,
+ },
+ {
+ name: "pci-dio48h",
+ n_8255: 2,
+ pcicontroler_badrindex:0,
+ dioregs_badrindex:1,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+static DEFINE_PCI_DEVICE_TABLE(pcidio_pci_table) = {
+ {PCI_VENDOR_ID_CB, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x0014, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_CB, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pcidio_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcidio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pcidio_private {
+ int data; // curently unused
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ /* used for DO readback, curently unused */
+ unsigned int do_readback[4]; /* up to 4 unsigned int suffice to hold 96 bits for PCI-DIO96 */
+
+ unsigned long dio_reg_base; // address of port A of the first 8255 chip on board
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcidio_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcidio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcidio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcidio = {
+ driver_name:"cb_pcidio",
+ module:THIS_MODULE,
+ attach:pcidio_attach,
+ detach:pcidio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcidio_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+// The following fields should NOT be initialized if you are dealing with PCI devices
+// board_name: pcidio_boards,
+// offset: sizeof(struct pcidio_board),
+// num_names: sizeof(pcidio_boards) / sizeof(struct pcidio_board),
+};
+
+/*------------------------------- FUNCTIONS -----------------------------------*/
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev = NULL;
+ int index;
+ int i;
+
+ printk("comedi%d: cb_pcidio: \n", dev->minor);
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcidio_private)) < 0)
+ return -ENOMEM;
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_CB)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0;
+ index < sizeof pcidio_boards / sizeof(struct pcidio_board);
+ index++) {
+ if (pcidio_pci_table[index].device != pcidev->device)
+ continue;
+
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ dev->board_ptr = pcidio_boards + index;
+ goto found;
+ }
+ }
+
+ printk("No supported ComputerBoards/MeasurementComputing card found on "
+ "requested position\n");
+ return -EIO;
+
+ found:
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+ devpriv->pci_dev = pcidev;
+ printk("Found %s on bus %i, slot %i\n", thisboard->name,
+ devpriv->pci_dev->bus->number,
+ PCI_SLOT(devpriv->pci_dev->devfn));
+ if (comedi_pci_enable(pcidev, thisboard->name)) {
+ printk("cb_pcidio: failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ devpriv->dio_reg_base
+ =
+ pci_resource_start(devpriv->pci_dev,
+ pcidio_boards[index].dioregs_badrindex);
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, thisboard->n_8255) < 0)
+ return -ENOMEM;
+
+ for (i = 0; i < thisboard->n_8255; i++) {
+ subdev_8255_init(dev, dev->subdevices + i,
+ NULL, devpriv->dio_reg_base + i * 4);
+ printk(" subdev %d: base = 0x%lx\n", i,
+ devpriv->dio_reg_base + i * 4);
+ }
+
+ printk("attached\n");
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcidio_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: cb_pcidio: remove\n", dev->minor);
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->dio_reg_base) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ if (dev->subdevices) {
+ int i;
+ for (i = 0; i < thisboard->n_8255; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+ }
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcidio, pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdas.c b/drivers/staging/comedi/drivers/cb_pcimdas.c
new file mode 100644
index 00000000000..af705fa092c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcimdas.c
@@ -0,0 +1,484 @@
+/*
+ comedi/drivers/cb_pcimdas.c
+ Comedi driver for Computer Boards PCIM-DAS1602/16
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcimdas
+Description: Measurement Computing PCI Migration series boards
+Devices: [ComputerBoards] PCIM-DAS1602/16 (cb_pcimdas)
+Author: Richard Bytheway
+Updated: Wed, 13 Nov 2002 12:34:56 +0000
+Status: experimental
+
+Written to support the PCIM-DAS1602/16 on a 2.4 series kernel.
+
+Configuration Options:
+ [0] - PCI bus number
+ [1] - PCI slot number
+
+Developed from cb_pcidas and skel by Richard Bytheway (mocelet@sucs.org).
+Only supports DIO, AO and simple AI in it's present form.
+No interrupts, multi channel or FIFO AI, although the card looks like it could support this.
+See http://www.measurementcomputing.com/PDFManuals/pcim-das1602_16.pdf for more details.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "plx9052.h"
+#include "8255.h"
+
+//#define CBPCIMDAS_DEBUG
+#undef CBPCIMDAS_DEBUG
+
+/* Registers for the PCIM-DAS1602/16 */
+
+// sizes of io regions (bytes)
+#define BADR0_SIZE 2 //??
+#define BADR1_SIZE 4
+#define BADR2_SIZE 6
+#define BADR3_SIZE 16
+#define BADR4_SIZE 4
+
+//DAC Offsets
+#define ADC_TRIG 0
+#define DAC0_OFFSET 2
+#define DAC1_OFFSET 4
+
+//AI and Counter Constants
+#define MUX_LIMITS 0
+#define MAIN_CONN_DIO 1
+#define ADC_STAT 2
+#define ADC_CONV_STAT 3
+#define ADC_INT 4
+#define ADC_PACER 5
+#define BURST_MODE 6
+#define PROG_GAIN 7
+#define CLK8254_1_DATA 8
+#define CLK8254_2_DATA 9
+#define CLK8254_3_DATA 10
+#define CLK8254_CONTROL 11
+#define USER_COUNTER 12
+#define RESID_COUNT_H 13
+#define RESID_COUNT_L 14
+
+/* Board description */
+struct cb_pcimdas_board {
+ const char *name;
+ unsigned short device_id;
+ int ai_se_chans; // Inputs in single-ended mode
+ int ai_diff_chans; // Inputs in differential mode
+ int ai_bits; // analog input resolution
+ int ai_speed; // fastest conversion period in ns
+ int ao_nchan; // number of analog out channels
+ int ao_bits; // analogue output resolution
+ int has_ao_fifo; // analog output has fifo
+ int ao_scan_speed; // analog output speed for 1602 series (for a scan, not conversion)
+ int fifo_size; // number of samples fifo can hold
+ int dio_bits; // number of dio bits
+ int has_dio; // has DIO
+ const struct comedi_lrange *ranges;
+};
+
+static const struct cb_pcimdas_board cb_pcimdas_boards[] = {
+ {
+ name: "PCIM-DAS1602/16",
+ device_id:0x56,
+ ai_se_chans:16,
+ ai_diff_chans:8,
+ ai_bits: 16,
+ ai_speed:10000, //??
+ ao_nchan:2,
+ ao_bits: 12,
+ has_ao_fifo:0, //??
+ ao_scan_speed:10000,
+ //??
+ fifo_size:1024,
+ dio_bits:24,
+ has_dio: 1,
+// ranges: &cb_pcimdas_ranges,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+static DEFINE_PCI_DEVICE_TABLE(cb_pcimdas_pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, 0x0056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cb_pcimdas_pci_table);
+
+#define N_BOARDS 1 // Max number of boards supported
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct cb_pcimdas_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct cb_pcimdas_private {
+ int data;
+
+ // would be useful for a PCI device
+ struct pci_dev *pci_dev;
+
+ //base addresses
+ unsigned long BADR0;
+ unsigned long BADR1;
+ unsigned long BADR2;
+ unsigned long BADR3;
+ unsigned long BADR4;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[2];
+
+ // Used for DIO
+ unsigned short int port_a; // copy of BADR4+0
+ unsigned short int port_b; // copy of BADR4+1
+ unsigned short int port_c; // copy of BADR4+2
+ unsigned short int dio_mode; // copy of BADR4+3
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct cb_pcimdas_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int cb_pcimdas_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cb_pcimdas_detach(struct comedi_device * dev);
+static struct comedi_driver driver_cb_pcimdas = {
+ driver_name:"cb_pcimdas",
+ module:THIS_MODULE,
+ attach:cb_pcimdas_attach,
+ detach:cb_pcimdas_detach,
+};
+
+static int cb_pcimdas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcimdas_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int cb_pcimdas_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int cb_pcimdas_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ struct pci_dev *pcidev;
+ int index;
+ //int i;
+
+ printk("comedi%d: cb_pcimdas: ", dev->minor);
+
+/*
+ * Allocate the private structure area.
+ */
+ if (alloc_private(dev, sizeof(struct cb_pcimdas_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Probe the device to determine what device in the series it is.
+ */
+ printk("\n");
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < N_BOARDS; index++) {
+ if (cb_pcimdas_boards[index].device_id !=
+ pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = cb_pcimdas_boards + index;
+ goto found;
+ }
+ }
+
+ printk("No supported ComputerBoards/MeasurementComputing card found on "
+ "requested position\n");
+ return -EIO;
+
+ found:
+
+ printk("Found %s on bus %i, slot %i\n", cb_pcimdas_boards[index].name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ // Warn about non-tested features
+ switch (thisboard->device_id) {
+ case 0x56:
+ break;
+ default:
+ printk("THIS CARD IS UNSUPPORTED.\n"
+ "PLEASE REPORT USAGE TO <mocelet@sucs.org>\n");
+ };
+
+ if (comedi_pci_enable(pcidev, "cb_pcimdas")) {
+ printk(" Failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+
+ devpriv->BADR0 = pci_resource_start(devpriv->pci_dev, 0);
+ devpriv->BADR1 = pci_resource_start(devpriv->pci_dev, 1);
+ devpriv->BADR2 = pci_resource_start(devpriv->pci_dev, 2);
+ devpriv->BADR3 = pci_resource_start(devpriv->pci_dev, 3);
+ devpriv->BADR4 = pci_resource_start(devpriv->pci_dev, 4);
+
+#ifdef CBPCIMDAS_DEBUG
+ printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
+ printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
+ printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
+ printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
+ printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
+#endif
+
+// Dont support IRQ yet
+// // get irq
+// if(comedi_request_irq(devpriv->pci_dev->irq, cb_pcimdas_interrupt, IRQF_SHARED, "cb_pcimdas", dev ))
+// {
+// printk(" unable to allocate irq %u\n", devpriv->pci_dev->irq);
+// return -EINVAL;
+// }
+// dev->irq = devpriv->pci_dev->irq;
+
+ //Initialize dev->board_name
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ //dev->read_subdev=s;
+ // analog input subdevice
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = thisboard->ai_se_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &range_unknown;
+ s->len_chanlist = 1; // This is the maximum chanlist length that
+ // the board can handle
+ s->insn_read = cb_pcimdas_ai_rinsn;
+
+ s = dev->subdevices + 1;
+ // analog output subdevice
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_nchan;
+ s->maxdata = 1 << thisboard->ao_bits;
+ s->range_table = &range_unknown; //ranges are hardware settable, but not software readable.
+ s->insn_write = &cb_pcimdas_ao_winsn;
+ s->insn_read = &cb_pcimdas_ao_rinsn;
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->has_dio) {
+ subdev_8255_init(dev, s, NULL, devpriv->BADR4);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int cb_pcimdas_detach(struct comedi_device * dev)
+{
+#ifdef CBPCIMDAS_DEBUG
+ if (devpriv) {
+ printk("devpriv->BADR0 = 0x%lx\n", devpriv->BADR0);
+ printk("devpriv->BADR1 = 0x%lx\n", devpriv->BADR1);
+ printk("devpriv->BADR2 = 0x%lx\n", devpriv->BADR2);
+ printk("devpriv->BADR3 = 0x%lx\n", devpriv->BADR3);
+ printk("devpriv->BADR4 = 0x%lx\n", devpriv->BADR4);
+ }
+#endif
+ printk("comedi%d: cb_pcimdas: remove\n", dev->minor);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->BADR0) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int cb_pcimdas_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int d;
+ unsigned int busy;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short chanlims;
+ int maxchans;
+
+ // only support sw initiated reads from a single channel
+
+ //check channel number
+ if ((inb(devpriv->BADR3 + 2) & 0x20) == 0) //differential mode
+ maxchans = thisboard->ai_diff_chans;
+ else
+ maxchans = thisboard->ai_se_chans;
+
+ if (chan > (maxchans - 1))
+ return -ETIMEDOUT; //*** Wrong error code. Fixme.
+
+ //configure for sw initiated read
+ d = inb(devpriv->BADR3 + 5);
+ if ((d & 0x03) > 0) { //only reset if needed.
+ d = d & 0xfd;
+ outb(d, devpriv->BADR3 + 5);
+ }
+ outb(0x01, devpriv->BADR3 + 6); //set bursting off, conversions on
+ outb(0x00, devpriv->BADR3 + 7); //set range to 10V. UP/BP is controlled by a switch on the board
+
+ // write channel limits to multiplexer, set Low (bits 0-3) and High (bits 4-7) channels to chan.
+ chanlims = chan | (chan << 4);
+ outb(chanlims, devpriv->BADR3 + 0);
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outw(0, devpriv->BADR2 + 0);
+
+#define TIMEOUT 1000 //typically takes 5 loops on a lightly loaded Pentium 100MHz,
+ //this is likely to be 100 loops on a 2GHz machine, so set 1000 as the limit.
+
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ busy = inb(devpriv->BADR3 + 2) & 0x80;
+ if (!busy)
+ break;
+ }
+ if (i == TIMEOUT) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+ /* read data */
+ d = inw(devpriv->BADR2 + 0);
+
+ /* mangle the data as necessary */
+ //d ^= 1<<(thisboard->ai_bits-1); // 16 bit data from ADC, so no mangle needed.
+
+ data[n] = d;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int cb_pcimdas_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ switch (chan) {
+ case 0:
+ outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC0_OFFSET);
+ break;
+ case 1:
+ outw(data[i] & 0x0FFF, devpriv->BADR2 + DAC1_OFFSET);
+ break;
+ default:
+ return -1;
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int cb_pcimdas_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_PCI_INITCLEANUP(driver_cb_pcimdas, cb_pcimdas_pci_table);
diff --git a/drivers/staging/comedi/drivers/cb_pcimdda.c b/drivers/staging/comedi/drivers/cb_pcimdda.c
new file mode 100644
index 00000000000..e4c5b460fbd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/cb_pcimdda.c
@@ -0,0 +1,474 @@
+/*
+ comedi/drivers/cb_pcimdda.c
+ Computer Boards PCIM-DDA06-16 Comedi driver
+ Author: Calin Culianu <calin@ajvar.org>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: cb_pcimdda
+Description: Measurement Computing PCIM-DDA06-16
+Devices: [Measurement Computing] PCIM-DDA06-16 (cb_pcimdda)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Mon, 14 Apr 2008 15:15:51 +0100
+Status: works
+
+All features of the PCIM-DDA06-16 board are supported. This board
+has 6 16-bit AO channels, and the usual 8255 DIO setup. (24 channels,
+configurable in banks of 8 and 4, etc.). This board does not support commands.
+
+The board has a peculiar way of specifying AO gain/range settings -- You have
+1 jumper bank on the card, which either makes all 6 AO channels either
+5 Volt unipolar, 5V bipolar, 10 Volt unipolar or 10V bipolar.
+
+Since there is absolutely _no_ way to tell in software how this jumper is set
+(well, at least according to the rather thin spec. from Measurement Computing
+ that comes with the board), the driver assumes the jumper is at its factory
+default setting of +/-5V.
+
+Also of note is the fact that this board features another jumper, whose
+state is also completely invisible to software. It toggles two possible AO
+output modes on the board:
+
+ - Update Mode: Writing to an AO channel instantaneously updates the actual
+ signal output by the DAC on the board (this is the factory default).
+ - Simultaneous XFER Mode: Writing to an AO channel has no effect until
+ you read from any one of the AO channels. This is useful for loading
+ all 6 AO values, and then reading from any one of the AO channels on the
+ device to instantly update all 6 AO values in unison. Useful for some
+ control apps, I would assume? If your jumper is in this setting, then you
+ need to issue your comedi_data_write()s to load all the values you want,
+ then issue one comedi_data_read() on any channel on the AO subdevice
+ to initiate the simultaneous XFER.
+
+Configuration Options:
+ [0] PCI bus (optional)
+ [1] PCI slot (optional)
+ [2] analog output range jumper setting
+ 0 == +/- 5 V
+ 1 == +/- 10 V
+*/
+
+/*
+ This is a driver for the Computer Boards PCIM-DDA06-16 Analog Output
+ card. This board has a unique register layout and as such probably
+ deserves its own driver file.
+
+ It is theoretically possible to integrate this board into the cb_pcidda
+ file, but since that isn't my code, I didn't want to significantly
+ modify that file to support this board (I thought it impolite to do so).
+
+ At any rate, if you feel ambitious, please feel free to take
+ the code out of this file and combine it with a more unified driver
+ file.
+
+ I would like to thank Timothy Curry <Timothy.Curry@rdec.redstone.army.mil>
+ for lending me a board so that I could write this driver.
+
+ -Calin Culianu <calin@ajvar.org>
+ */
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#include "8255.h"
+
+/* device ids of the cards we support -- currently only 1 card supported */
+#define PCI_ID_PCIM_DDA06_16 0x0053
+
+/*
+ * This is straight from skel.c -- I did this in case this source file
+ * will someday support more than 1 board...
+ */
+struct board_struct {
+ const char *name;
+ unsigned short device_id;
+ int ao_chans;
+ int ao_bits;
+ int dio_chans;
+ int dio_method;
+ int dio_offset; /* how many bytes into the BADR are the DIO ports */
+ int regs_badrindex; /* IO Region for the control, analog output,
+ and DIO registers */
+ int reg_sz; /* number of bytes of registers in io region */
+};
+
+enum DIO_METHODS {
+ DIO_NONE = 0,
+ DIO_8255,
+ DIO_INTERNAL /* unimplemented */
+};
+
+static const struct board_struct boards[] = {
+ {
+ name: "cb_pcimdda06-16",
+ device_id:PCI_ID_PCIM_DDA06_16,
+ ao_chans:6,
+ ao_bits: 16,
+ dio_chans:24,
+ dio_method:DIO_8255,
+ dio_offset:12,
+ regs_badrindex:3,
+ reg_sz: 16,
+ }
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct board_struct *)dev->board_ptr)
+
+/* Number of boards in boards[] */
+#define N_BOARDS (sizeof(boards) / sizeof(struct board_struct))
+#define REG_SZ (thisboard->reg_sz)
+#define REGS_BADRINDEX (thisboard->regs_badrindex)
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+static DEFINE_PCI_DEVICE_TABLE(pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, PCI_ID_PCIM_DDA06_16, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, pci_table);
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct board_private_struct {
+ unsigned long registers; /* set by probe */
+ unsigned long dio_registers;
+ char attached_to_8255; /* boolean */
+ char attached_successfully; /* boolean */
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+#define MAX_AO_READBACK_CHANNELS 6
+ /* Used for AO readback */
+ unsigned int ao_readback[MAX_AO_READBACK_CHANNELS];
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct board_private_struct *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int detach(struct comedi_device * dev);
+static struct comedi_driver cb_pcimdda_driver = {
+ driver_name:"cb_pcimdda",
+ module:THIS_MODULE,
+ attach:attach,
+ detach:detach,
+};
+
+MODULE_AUTHOR("Calin A. Culianu <calin@rtlab.org>");
+MODULE_DESCRIPTION("Comedi low-level driver for the Computerboards PCIM-DDA "
+ "series. Currently only supports PCIM-DDA06-16 (which "
+ "also happens to be the only board in this series. :) ) ");
+MODULE_LICENSE("GPL");
+COMEDI_PCI_INITCLEANUP_NOMODULE(cb_pcimdda_driver, pci_table);
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*---------------------------------------------------------------------------
+ HELPER FUNCTION DECLARATIONS
+-----------------------------------------------------------------------------*/
+
+/* returns a maxdata value for a given n_bits */
+static inline unsigned int figure_out_maxdata(int bits)
+{
+ return (((unsigned int) 1 << bits) - 1);
+}
+
+/*
+ * Probes for a supported device.
+ *
+ * Prerequisite: private be allocated already inside dev
+ *
+ * If the device is found, it returns 0 and has the following side effects:
+ *
+ * o assigns a struct pci_dev * to dev->private->pci_dev
+ * o assigns a struct board * to dev->board_ptr
+ * o sets dev->private->registers
+ * o sets dev->private->dio_registers
+ *
+ * Otherwise, returns a -errno on error
+ */
+static int probe(struct comedi_device * dev, const struct comedi_devconfig * it);
+
+/*---------------------------------------------------------------------------
+ FUNCTION DEFINITIONS
+-----------------------------------------------------------------------------*/
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int err;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ * if this function fails (returns negative) then the private area is
+ * kfree'd by comedi
+ */
+ if (alloc_private(dev, sizeof(struct board_private_struct)) < 0)
+ return -ENOMEM;
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+ if ((err = probe(dev, it)))
+ return err;
+
+/* Output some info */
+ printk("comedi%d: %s: ", dev->minor, thisboard->name);
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = figure_out_maxdata(thisboard->ao_bits);
+ /* this is hard-coded here */
+ if (it->options[2]) {
+ s->range_table = &range_bipolar10;
+ } else {
+ s->range_table = &range_bipolar5;
+ }
+ s->insn_write = &ao_winsn;
+ s->insn_read = &ao_rinsn;
+
+ s = dev->subdevices + 1;
+ /* digital i/o subdevice */
+ if (thisboard->dio_chans) {
+ switch (thisboard->dio_method) {
+ case DIO_8255:
+ /* this is a straight 8255, so register us with the 8255 driver */
+ subdev_8255_init(dev, s, NULL, devpriv->dio_registers);
+ devpriv->attached_to_8255 = 1;
+ break;
+ case DIO_INTERNAL:
+ default:
+ printk("DIO_INTERNAL not implemented yet!\n");
+ return -ENXIO;
+ break;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ devpriv->attached_successfully = 1;
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int detach(struct comedi_device * dev)
+{
+ if (devpriv) {
+
+ if (dev->subdevices && devpriv->attached_to_8255) {
+ /* de-register us from the 8255 driver */
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+ devpriv->attached_to_8255 = 0;
+ }
+
+ if (devpriv->pci_dev) {
+ if (devpriv->registers) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ if (devpriv->attached_successfully && thisboard)
+ printk("comedi%d: %s: detached\n", dev->minor,
+ thisboard->name);
+
+ }
+
+ return 0;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned long offset = devpriv->registers + chan * 2;
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* first, load the low byte */
+ outb((char)(data[i] & 0x00ff), offset);
+ /* next, write the high byte -- only after this is written is
+ the channel voltage updated in the DAC, unless
+ we're in simultaneous xfer mode (jumper on card)
+ then a rinsn is necessary to actually update the DAC --
+ see ao_rinsn() below... */
+ outb((char)(data[i] >> 8 & 0x00ff), offset + 1);
+
+ /* for testing only.. the actual rinsn SHOULD do an inw!
+ (see the stuff about simultaneous XFER mode on this board) */
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+
+ Usually this means copying a value stored in devpriv->ao_readback.
+ However, since this board has this jumper setting called "Simultaneous
+ Xfer mode" (off by default), we will support it. Simultaneaous xfer
+ mode is accomplished by loading ALL the values you want for AO in all the
+ channels, then READing off one of the AO registers to initiate the
+ instantaneous simultaneous update of all DAC outputs, which makes
+ all AO channels update simultaneously. This is useful for some control
+ applications, I would imagine.
+*/
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ inw(devpriv->registers + chan * 2);
+ /* should I set data[i] to the result of the actual read on the register
+ or the cached unsigned int in devpriv->ao_readback[]? */
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*---------------------------------------------------------------------------
+ HELPER FUNCTION DEFINITIONS
+-----------------------------------------------------------------------------*/
+
+/*
+ * Probes for a supported device.
+ *
+ * Prerequisite: private be allocated already inside dev
+ *
+ * If the device is found, it returns 0 and has the following side effects:
+ *
+ * o assigns a struct pci_dev * to dev->private->pci_dev
+ * o assigns a struct board * to dev->board_ptr
+ * o sets dev->private->registers
+ * o sets dev->private->dio_registers
+ *
+ * Otherwise, returns a -errno on error
+ */
+static int probe(struct comedi_device * dev, const struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ int index;
+ unsigned long registers;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+ // is it not a computer boards card?
+ if (pcidev->vendor != PCI_VENDOR_ID_COMPUTERBOARDS)
+ continue;
+ // loop through cards supported by this driver
+ for (index = 0; index < N_BOARDS; index++) {
+ if (boards[index].device_id != pcidev->device)
+ continue;
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+ /* found ! */
+
+ devpriv->pci_dev = pcidev;
+ dev->board_ptr = boards + index;
+ if (comedi_pci_enable(pcidev, thisboard->name)) {
+ printk("cb_pcimdda: Failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ registers =
+ pci_resource_start(devpriv->pci_dev,
+ REGS_BADRINDEX);
+ devpriv->registers = registers;
+ devpriv->dio_registers
+ = devpriv->registers + thisboard->dio_offset;
+ return 0;
+ }
+ }
+
+ printk("cb_pcimdda: No supported ComputerBoards/MeasurementComputing "
+ "card found at the requested position\n");
+ return -ENODEV;
+}
diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c
index 9e5496f4f1a..1ee489864d3 100644
--- a/drivers/staging/comedi/drivers/comedi_bond.c
+++ b/drivers/staging/comedi/drivers/comedi_bond.c
@@ -59,7 +59,7 @@ Configuration Options:
* Devices: a full list of the boards that attempt to be supported by
* the driver. Format is "(manufacturer) board name [comedi name]",
* where comedi_name is the name that is used to configure the board.
- * See the comment near board_name: in the comedi_driver structure
+ * See the comment near board_name: in the struct comedi_driver structure
* below. If (manufacturer) or [comedi name] is missing, the previous
* value is used.
* Author: you
@@ -142,7 +142,7 @@ static const struct BondingBoard bondingBoards[] = {
#define thisboard ((const struct BondingBoard *)dev->board_ptr)
struct BondedDevice {
- comedi_t *dev;
+ void *dev;
unsigned minor;
unsigned subdev;
unsigned subdev_type;
@@ -154,7 +154,7 @@ struct BondedDevice {
/* this structure is for data unique to this hardware driver. If
several hardware drivers keep similar information in this structure,
- feel free to suggest moving the variable to the comedi_device struct. */
+ feel free to suggest moving the variable to the struct comedi_device struct. */
struct Private {
# define MAX_BOARD_NAME 256
char name[MAX_BOARD_NAME];
@@ -171,21 +171,21 @@ struct Private {
#define devpriv ((struct Private *)dev->private)
/*
- * The comedi_driver structure tells the Comedi core module
+ * The struct comedi_driver structure tells the Comedi core module
* which functions to call to configure/deconfigure (attach/detach)
* the board, and also about the kernel module that contains
* the device code.
*/
-static int bonding_attach(comedi_device *dev, comedi_devconfig *it);
-static int bonding_detach(comedi_device *dev);
+static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int bonding_detach(struct comedi_device *dev);
/** Build Private array of all devices.. */
-static int doDevConfig(comedi_device *dev, comedi_devconfig *it);
-static void doDevUnconfig(comedi_device *dev);
+static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it);
+static void doDevUnconfig(struct comedi_device *dev);
/* Ugly implementation of realloc that always copies memory around -- I'm lazy,
* what can I say? I like to do wasteful memcopies.. :) */
static void *Realloc(const void *ptr, size_t len, size_t old_len);
-static comedi_driver driver_bonding = {
+static struct comedi_driver driver_bonding = {
.driver_name = MODULE_NAME,
.module = THIS_MODULE,
.attach = bonding_attach,
@@ -213,10 +213,10 @@ static comedi_driver driver_bonding = {
.num_names = sizeof(bondingBoards) / sizeof(struct BondingBoard),
};
-static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
-static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
+static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
/*
* Attach is called by the Comedi core to configure the driver
@@ -224,9 +224,9 @@ static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
* in the driver structure, dev->board_ptr contains that
* address.
*/
-static int bonding_attach(comedi_device *dev, comedi_devconfig *it)
+static int bonding_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
LOG_MSG("comedi%d\n", dev->minor);
@@ -281,7 +281,7 @@ static int bonding_attach(comedi_device *dev, comedi_devconfig *it)
* allocated by _attach(). dev->private and dev->subdevices are
* deallocated automatically by the core.
*/
-static int bonding_detach(comedi_device *dev)
+static int bonding_detach(struct comedi_device *dev)
{
LOG_MSG("comedi%d: remove\n", dev->minor);
doDevUnconfig(dev);
@@ -293,10 +293,10 @@ static int bonding_detach(comedi_device *dev)
* useful to applications if you implement the insn_bits interface.
* This allows packed reading/writing of the DIO channels. The
* comedi core can convert between insn_bits and insn_read/write */
-static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int bonding_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
-#define LSAMPL_BITS (sizeof(lsampl_t)*8)
+#define LSAMPL_BITS (sizeof(unsigned int)*8)
unsigned nchans = LSAMPL_BITS, num_done = 0, i;
if (insn->n != 2)
return -EINVAL;
@@ -312,12 +312,12 @@ static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
to this subdevice.. need to shift them to zero position of
course. */
/* Bits corresponding to this subdev. */
- lsampl_t subdevMask = ((1 << bdev->nchans) - 1);
- lsampl_t writeMask, dataBits;
+ unsigned int subdevMask = ((1 << bdev->nchans) - 1);
+ unsigned int writeMask, dataBits;
/* Argh, we have >= LSAMPL_BITS chans.. take all bits */
if (bdev->nchans >= LSAMPL_BITS)
- subdevMask = (lsampl_t) (-1);
+ subdevMask = (unsigned int) (-1);
writeMask = (data[0] >> num_done) & subdevMask;
dataBits = (data[1] >> num_done) & subdevMask;
@@ -340,8 +340,8 @@ static int bonding_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
return insn->n;
}
-static int bonding_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int bonding_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec), ret, io_bits = s->io_bits;
unsigned int io;
@@ -394,10 +394,10 @@ static void *Realloc(const void *oldmem, size_t newlen, size_t oldlen)
return newmem;
}
-static int doDevConfig(comedi_device *dev, comedi_devconfig *it)
+static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it)
{
int i;
- comedi_t *devs_opened[COMEDI_NUM_BOARD_MINORS];
+ void *devs_opened[COMEDI_NUM_BOARD_MINORS];
memset(devs_opened, 0, sizeof(devs_opened));
devpriv->name[0] = 0;;
@@ -406,7 +406,7 @@ static int doDevConfig(comedi_device *dev, comedi_devconfig *it)
for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) {
char file[] = "/dev/comediXXXXXX";
int minor = it->options[i];
- comedi_t *d;
+ void *d;
int sdev = -1, nchans, tmp;
struct BondedDevice *bdev = NULL;
@@ -497,7 +497,7 @@ static int doDevConfig(comedi_device *dev, comedi_devconfig *it)
return 1;
}
-static void doDevUnconfig(comedi_device *dev)
+static void doDevUnconfig(struct comedi_device *dev)
{
unsigned long devs_closed = 0;
diff --git a/drivers/staging/comedi/drivers/comedi_fc.c b/drivers/staging/comedi/drivers/comedi_fc.c
index cd74dbe5417..9fa4cdc84d4 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.c
+++ b/drivers/staging/comedi/drivers/comedi_fc.c
@@ -28,10 +28,10 @@
#include "comedi_fc.h"
-static void increment_scan_progress(comedi_subdevice *subd,
+static void increment_scan_progress(struct comedi_subdevice *subd,
unsigned int num_bytes)
{
- comedi_async *async = subd->async;
+ struct comedi_async *async = subd->async;
unsigned int scan_length = cfc_bytes_per_scan(subd);
async->scan_progress += num_bytes;
@@ -42,10 +42,10 @@ static void increment_scan_progress(comedi_subdevice *subd,
}
/* Writes an array of data points to comedi's buffer */
-unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd, void *data,
+unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd, void *data,
unsigned int num_bytes)
{
- comedi_async *async = subd->async;
+ struct comedi_async *async = subd->async;
unsigned int retval;
if (num_bytes == 0)
@@ -67,10 +67,10 @@ unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd, void *data,
}
EXPORT_SYMBOL(cfc_write_array_to_buffer);
-unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd, void *data,
+unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd, void *data,
unsigned int num_bytes)
{
- comedi_async *async = subd->async;
+ struct comedi_async *async = subd->async;
if (num_bytes == 0)
return 0;
@@ -85,7 +85,7 @@ unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd, void *data,
}
EXPORT_SYMBOL(cfc_read_array_from_buffer);
-unsigned int cfc_handle_events(comedi_device *dev, comedi_subdevice *subd)
+unsigned int cfc_handle_events(struct comedi_device *dev, struct comedi_subdevice *subd)
{
unsigned int events = subd->async->events;
diff --git a/drivers/staging/comedi/drivers/comedi_fc.h b/drivers/staging/comedi/drivers/comedi_fc.h
index 6952fe20f27..494ae3f2aff 100644
--- a/drivers/staging/comedi/drivers/comedi_fc.h
+++ b/drivers/staging/comedi/drivers/comedi_fc.h
@@ -30,30 +30,30 @@
#include "../comedidev.h"
/* Writes an array of data points to comedi's buffer */
-extern unsigned int cfc_write_array_to_buffer(comedi_subdevice *subd,
+extern unsigned int cfc_write_array_to_buffer(struct comedi_subdevice *subd,
void *data,
unsigned int num_bytes);
-static inline unsigned int cfc_write_to_buffer(comedi_subdevice *subd,
- sampl_t data)
+static inline unsigned int cfc_write_to_buffer(struct comedi_subdevice *subd,
+ short data)
{
return cfc_write_array_to_buffer(subd, &data, sizeof(data));
};
-static inline unsigned int cfc_write_long_to_buffer(comedi_subdevice *subd,
- lsampl_t data)
+static inline unsigned int cfc_write_long_to_buffer(struct comedi_subdevice *subd,
+ unsigned int data)
{
return cfc_write_array_to_buffer(subd, &data, sizeof(data));
};
-extern unsigned int cfc_read_array_from_buffer(comedi_subdevice *subd,
+extern unsigned int cfc_read_array_from_buffer(struct comedi_subdevice *subd,
void *data,
unsigned int num_bytes);
-extern unsigned int cfc_handle_events(comedi_device *dev,
- comedi_subdevice *subd);
+extern unsigned int cfc_handle_events(struct comedi_device *dev,
+ struct comedi_subdevice *subd);
-static inline unsigned int cfc_bytes_per_scan(comedi_subdevice *subd)
+static inline unsigned int cfc_bytes_per_scan(struct comedi_subdevice *subd)
{
int num_samples;
int bits_per_sample;
diff --git a/drivers/staging/comedi/drivers/comedi_parport.c b/drivers/staging/comedi/drivers/comedi_parport.c
index ba838fffa29..a23339155ff 100644
--- a/drivers/staging/comedi/drivers/comedi_parport.c
+++ b/drivers/staging/comedi/drivers/comedi_parport.c
@@ -90,9 +90,9 @@ pin, which can be used to wake up tasks.
#define PARPORT_B 1
#define PARPORT_C 2
-static int parport_attach(comedi_device *dev, comedi_devconfig *it);
-static int parport_detach(comedi_device *dev);
-static comedi_driver driver_parport = {
+static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int parport_detach(struct comedi_device *dev);
+static struct comedi_driver driver_parport = {
.driver_name = "comedi_parport",
.module = THIS_MODULE,
.attach = parport_attach,
@@ -108,8 +108,8 @@ struct parport_private {
};
#define devpriv ((struct parport_private *)(dev->private))
-static int parport_insn_a(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_a(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (data[0]) {
devpriv->a_data &= ~data[0];
@@ -123,8 +123,8 @@ static int parport_insn_a(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_insn_config_a(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_config_a(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (data[0]) {
s->io_bits = 0xff;
@@ -138,8 +138,8 @@ static int parport_insn_config_a(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int parport_insn_b(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_b(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (data[0]) {
/* should writes be ignored? */
@@ -151,8 +151,8 @@ static int parport_insn_b(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_insn_c(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_insn_c(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
data[0] &= 0x0f;
if (data[0]) {
@@ -167,8 +167,8 @@ static int parport_insn_c(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_intr_insn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int parport_intr_insn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
if (insn->n < 1)
return -EINVAL;
@@ -177,8 +177,8 @@ static int parport_intr_insn(comedi_device *dev, comedi_subdevice *s,
return 2;
}
-static int parport_intr_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int parport_intr_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -252,7 +252,7 @@ static int parport_intr_cmdtest(comedi_device *dev, comedi_subdevice *s,
return 0;
}
-static int parport_intr_cmd(comedi_device *dev, comedi_subdevice *s)
+static int parport_intr_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
devpriv->c_data |= 0x10;
outb(devpriv->c_data, dev->iobase + PARPORT_C);
@@ -262,7 +262,7 @@ static int parport_intr_cmd(comedi_device *dev, comedi_subdevice *s)
return 0;
}
-static int parport_intr_cancel(comedi_device *dev, comedi_subdevice *s)
+static int parport_intr_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
printk(KERN_DEBUG "parport_intr_cancel()\n");
@@ -276,8 +276,8 @@ static int parport_intr_cancel(comedi_device *dev, comedi_subdevice *s)
static irqreturn_t parport_interrupt(int irq, void *d PT_REGS_ARG)
{
- comedi_device *dev = d;
- comedi_subdevice *s = dev->subdevices + 3;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 3;
if (!devpriv->enable_irq) {
printk(KERN_ERR "comedi_parport: bogus irq, ignored\n");
@@ -291,12 +291,12 @@ static irqreturn_t parport_interrupt(int irq, void *d PT_REGS_ARG)
return IRQ_HANDLED;
}
-static int parport_attach(comedi_device *dev, comedi_devconfig *it)
+static int parport_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
unsigned int irq;
unsigned long iobase;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
iobase = it->options[0];
printk(KERN_INFO "comedi%d: parport: 0x%04lx ", dev->minor, iobase);
@@ -376,7 +376,7 @@ static int parport_attach(comedi_device *dev, comedi_devconfig *it)
return 1;
}
-static int parport_detach(comedi_device *dev)
+static int parport_detach(struct comedi_device *dev)
{
printk("comedi%d: parport: remove\n", dev->minor);
diff --git a/drivers/staging/comedi/drivers/comedi_rt_timer.c b/drivers/staging/comedi/drivers/comedi_rt_timer.c
new file mode 100644
index 00000000000..f40c8cffd4b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/comedi_rt_timer.c
@@ -0,0 +1,728 @@
+/*
+ comedi/drivers/comedi_rt_timer.c
+ virtual driver for using RTL timing sources
+
+ Authors: David A. Schleef, Frank M. Hess
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+**************************************************************************
+*/
+/*
+Driver: comedi_rt_timer
+Description: Command emulator using real-time tasks
+Author: ds, fmhess
+Devices:
+Status: works
+
+This driver requires RTAI or RTLinux to work correctly. It doesn't
+actually drive hardware directly, but calls other drivers and uses
+a real-time task to emulate commands for drivers and devices that
+are incapable of native commands. Thus, you can get accurately
+timed I/O on any device.
+
+Since the timing is all done in software, sampling jitter is much
+higher than with a device that has an on-board timer, and maximum
+sample rate is much lower.
+
+Configuration options:
+ [0] - minor number of device you wish to emulate commands for
+ [1] - subdevice number you wish to emulate commands for
+*/
+/*
+TODO:
+ Support for digital io commands could be added, except I can't see why
+ anyone would want to use them
+ What happens if device we are emulating for is de-configured?
+*/
+
+#include "../comedidev.h"
+#include "../comedilib.h"
+
+#include "comedi_fc.h"
+
+#ifdef CONFIG_COMEDI_RTL_V1
+#include <rtl_sched.h>
+#include <asm/rt_irq.h>
+#endif
+#ifdef CONFIG_COMEDI_RTL
+#include <rtl.h>
+#include <rtl_sched.h>
+#include <rtl_compat.h>
+#include <asm/div64.h>
+
+#ifndef RTLINUX_VERSION_CODE
+#define RTLINUX_VERSION_CODE 0
+#endif
+#ifndef RTLINUX_VERSION
+#define RTLINUX_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif
+
+// begin hack to workaround broken HRT_TO_8254() function on rtlinux
+#if RTLINUX_VERSION_CODE <= RTLINUX_VERSION(3,0,100)
+// this function sole purpose is to divide a long long by 838
+static inline RTIME nano2count(long long ns)
+{
+ do_div(ns, 838);
+ return ns;
+}
+
+#ifdef rt_get_time()
+#undef rt_get_time()
+#endif
+#define rt_get_time() nano2count(gethrtime())
+
+#else
+
+#define nano2count(x) HRT_TO_8254(x)
+#endif
+// end hack
+
+// rtl-rtai compatibility
+#define rt_task_wait_period() rt_task_wait()
+#define rt_pend_linux_srq(irq) rtl_global_pend_irq(irq)
+#define rt_free_srq(irq) rtl_free_soft_irq(irq)
+#define rt_request_srq(x,y,z) rtl_get_soft_irq(y,"timer")
+#define rt_task_init(a,b,c,d,e,f,g) rt_task_init(a,b,c,d,(e)+1)
+#define rt_task_resume(x) rt_task_wakeup(x)
+#define rt_set_oneshot_mode()
+#define start_rt_timer(x)
+#define stop_rt_timer()
+
+#endif
+#ifdef CONFIG_COMEDI_RTAI
+#include <rtai.h>
+#include <rtai_sched.h>
+
+#if RTAI_VERSION_CODE < RTAI_MANGLE_VERSION(3,3,0)
+#define comedi_rt_task_context_t int
+#else
+#define comedi_rt_task_context_t long
+#endif
+
+#endif
+
+/* This defines the fastest speed we will emulate. Note that
+ * without a watchdog (like in RTAI), we could easily overrun our
+ * task period because analog input tends to be slow. */
+#define SPEED_LIMIT 100000 /* in nanoseconds */
+
+static int timer_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int timer_detach(struct comedi_device * dev);
+static int timer_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num);
+static int timer_start_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_timer = {
+ module:THIS_MODULE,
+ driver_name:"comedi_rt_timer",
+ attach:timer_attach,
+ detach:timer_detach,
+// open: timer_open,
+};
+
+COMEDI_INITCLEANUP(driver_timer);
+
+struct timer_private {
+ comedi_t *device; // device we are emulating commands for
+ int subd; // subdevice we are emulating commands for
+ RT_TASK *rt_task; // rt task that starts scans
+ RT_TASK *scan_task; // rt task that controls conversion timing in a scan
+ /* io_function can point to either an input or output function
+ * depending on what kind of subdevice we are emulating for */
+ int (*io_function) (struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index);
+ // RTIME has units of 1 = 838 nanoseconds
+ // time at which first scan started, used to check scan timing
+ RTIME start;
+ // time between scans
+ RTIME scan_period;
+ // time between conversions in a scan
+ RTIME convert_period;
+ // flags
+ volatile int stop; // indicates we should stop
+ volatile int rt_task_active; // indicates rt_task is servicing a struct comedi_cmd
+ volatile int scan_task_active; // indicates scan_task is servicing a struct comedi_cmd
+ unsigned timer_running:1;
+};
+#define devpriv ((struct timer_private *)dev->private)
+
+static int timer_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->stop = 1;
+
+ return 0;
+}
+
+// checks for scan timing error
+inline static int check_scan_timing(struct comedi_device * dev,
+ unsigned long long scan)
+{
+ RTIME now, timing_error;
+
+ now = rt_get_time();
+ timing_error = now - (devpriv->start + scan * devpriv->scan_period);
+ if (timing_error > devpriv->scan_period) {
+ comedi_error(dev, "timing error");
+ rt_printk("scan started %i ns late\n", timing_error * 838);
+ return -1;
+ }
+
+ return 0;
+}
+
+// checks for conversion timing error
+inline static int check_conversion_timing(struct comedi_device * dev,
+ RTIME scan_start, unsigned int conversion)
+{
+ RTIME now, timing_error;
+
+ now = rt_get_time();
+ timing_error =
+ now - (scan_start + conversion * devpriv->convert_period);
+ if (timing_error > devpriv->convert_period) {
+ comedi_error(dev, "timing error");
+ rt_printk("conversion started %i ns late\n",
+ timing_error * 838);
+ return -1;
+ }
+
+ return 0;
+}
+
+// devpriv->io_function for an input subdevice
+static int timer_data_read(struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ int ret;
+ unsigned int data;
+
+ ret = comedi_data_read(devpriv->device, devpriv->subd,
+ CR_CHAN(cmd->chanlist[index]),
+ CR_RANGE(cmd->chanlist[index]),
+ CR_AREF(cmd->chanlist[index]), &data);
+ if (ret < 0) {
+ comedi_error(dev, "read error");
+ return -EIO;
+ }
+ if (s->flags & SDF_LSAMPL) {
+ cfc_write_long_to_buffer(s, data);
+ } else {
+ comedi_buf_put(s->async, data);
+ }
+
+ return 0;
+}
+
+// devpriv->io_function for an output subdevice
+static int timer_data_write(struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index)
+{
+ struct comedi_subdevice *s = dev->write_subdev;
+ unsigned int num_bytes;
+ short data;
+ unsigned int long_data;
+ int ret;
+
+ if (s->flags & SDF_LSAMPL) {
+ num_bytes =
+ cfc_read_array_from_buffer(s, &long_data,
+ sizeof(long_data));
+ } else {
+ num_bytes = cfc_read_array_from_buffer(s, &data, sizeof(data));
+ long_data = data;
+ }
+
+ if (num_bytes == 0) {
+ comedi_error(dev, "buffer underrun");
+ return -EAGAIN;
+ }
+ ret = comedi_data_write(devpriv->device, devpriv->subd,
+ CR_CHAN(cmd->chanlist[index]),
+ CR_RANGE(cmd->chanlist[index]),
+ CR_AREF(cmd->chanlist[index]), long_data);
+ if (ret < 0) {
+ comedi_error(dev, "write error");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+// devpriv->io_function for DIO subdevices
+static int timer_dio_read(struct comedi_device * dev, struct comedi_cmd * cmd,
+ unsigned int index)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ int ret;
+ unsigned int data;
+
+ ret = comedi_dio_bitfield(devpriv->device, devpriv->subd, 0, &data);
+ if (ret < 0) {
+ comedi_error(dev, "read error");
+ return -EIO;
+ }
+
+ if (s->flags & SDF_LSAMPL)
+ cfc_write_long_to_buffer(s, data);
+ else
+ cfc_write_to_buffer(s, data);
+
+ return 0;
+}
+
+// performs scans
+static void scan_task_func(comedi_rt_task_context_t d)
+{
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ int i, ret;
+ unsigned long long n;
+ RTIME scan_start;
+
+ // every struct comedi_cmd causes one execution of while loop
+ while (1) {
+ devpriv->scan_task_active = 1;
+ // each for loop completes one scan
+ for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE;
+ n++) {
+ if (n) {
+ // suspend task until next scan
+ ret = rt_task_suspend(devpriv->scan_task);
+ if (ret < 0) {
+ comedi_error(dev,
+ "error suspending scan task");
+ async->events |= COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ }
+ // check if stop flag was set (by timer_cancel())
+ if (devpriv->stop)
+ goto cleanup;
+ ret = check_scan_timing(dev, n);
+ if (ret < 0) {
+ async->events |= COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ scan_start = rt_get_time();
+ for (i = 0; i < cmd->scan_end_arg; i++) {
+ // conversion timing
+ if (cmd->convert_src == TRIG_TIMER && i) {
+ rt_task_wait_period();
+ ret = check_conversion_timing(dev,
+ scan_start, i);
+ if (ret < 0) {
+ async->events |=
+ COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ }
+ ret = devpriv->io_function(dev, cmd, i);
+ if (ret < 0) {
+ async->events |= COMEDI_CB_ERROR;
+ goto cleanup;
+ }
+ }
+ s->async->events |= COMEDI_CB_BLOCK;
+ comedi_event(dev, s);
+ s->async->events = 0;
+ }
+
+ cleanup:
+
+ comedi_unlock(devpriv->device, devpriv->subd);
+ async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ async->events = 0;
+ devpriv->scan_task_active = 0;
+ // suspend task until next struct comedi_cmd
+ rt_task_suspend(devpriv->scan_task);
+ }
+}
+
+static void timer_task_func(comedi_rt_task_context_t d)
+{
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int ret;
+ unsigned long long n;
+
+ // every struct comedi_cmd causes one execution of while loop
+ while (1) {
+ devpriv->rt_task_active = 1;
+ devpriv->scan_task_active = 1;
+ devpriv->start = rt_get_time();
+
+ for (n = 0; n < cmd->stop_arg || cmd->stop_src == TRIG_NONE;
+ n++) {
+ // scan timing
+ if (n)
+ rt_task_wait_period();
+ if (devpriv->scan_task_active == 0) {
+ goto cleanup;
+ }
+ ret = rt_task_make_periodic(devpriv->scan_task,
+ devpriv->start + devpriv->scan_period * n,
+ devpriv->convert_period);
+ if (ret < 0) {
+ comedi_error(dev, "bug!");
+ }
+ }
+
+ cleanup:
+
+ devpriv->rt_task_active = 0;
+ // suspend until next struct comedi_cmd
+ rt_task_suspend(devpriv->rt_task);
+ }
+}
+
+static int timer_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct comedi_insn xinsn = *insn;
+
+ xinsn.data = data;
+ xinsn.subdev = devpriv->subd;
+
+ return comedi_do_insn(devpriv->device, &xinsn);
+}
+
+static int cmdtest_helper(struct comedi_cmd * cmd,
+ unsigned int start_src,
+ unsigned int scan_begin_src,
+ unsigned int convert_src,
+ unsigned int scan_end_src, unsigned int stop_src)
+{
+ int err = 0;
+ int tmp;
+
+ tmp = cmd->start_src;
+ cmd->start_src &= start_src;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= scan_begin_src;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= convert_src;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= scan_end_src;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= stop_src;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ return err;
+}
+
+static int timer_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int start_src = 0;
+
+ if (s->type == COMEDI_SUBD_AO)
+ start_src = TRIG_INT;
+ else
+ start_src = TRIG_NOW;
+
+ err = cmdtest_helper(cmd, start_src, /* start_src */
+ TRIG_TIMER | TRIG_FOLLOW, /* scan_begin_src */
+ TRIG_NOW | TRIG_TIMER, /* convert_src */
+ TRIG_COUNT, /* scan_end_src */
+ TRIG_COUNT | TRIG_NONE); /* stop_src */
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually
+ * compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+ if (cmd->scan_begin_src == TRIG_FOLLOW
+ && cmd->convert_src != TRIG_TIMER)
+ err++;
+ if (cmd->convert_src == TRIG_NOW && cmd->scan_begin_src != TRIG_TIMER)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ // limit frequency, this is fairly arbitrary
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < SPEED_LIMIT) {
+ cmd->scan_begin_arg = SPEED_LIMIT;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < SPEED_LIMIT) {
+ cmd->convert_arg = SPEED_LIMIT;
+ err++;
+ }
+ }
+ // make sure conversion and scan frequencies are compatible
+ if (cmd->convert_src == TRIG_TIMER && cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->convert_arg * cmd->scan_end_arg > cmd->scan_begin_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+ if (err)
+ return 3;
+
+ /* step 4: fix up and arguments */
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int timer_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int ret;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ /* hack attack: drivers are not supposed to do this: */
+ dev->rt = 1;
+
+ // make sure tasks have finished cleanup of last struct comedi_cmd
+ if (devpriv->rt_task_active || devpriv->scan_task_active)
+ return -EBUSY;
+
+ ret = comedi_lock(devpriv->device, devpriv->subd);
+ if (ret < 0) {
+ comedi_error(dev, "failed to obtain lock");
+ return ret;
+ }
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->scan_period = nano2count(cmd->scan_begin_arg);
+ break;
+ case TRIG_FOLLOW:
+ devpriv->scan_period =
+ nano2count(cmd->convert_arg * cmd->scan_end_arg);
+ break;
+ default:
+ comedi_error(dev, "bug setting scan period!");
+ return -1;
+ break;
+ }
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ devpriv->convert_period = nano2count(cmd->convert_arg);
+ break;
+ case TRIG_NOW:
+ devpriv->convert_period = 1;
+ break;
+ default:
+ comedi_error(dev, "bug setting conversion period!");
+ return -1;
+ break;
+ }
+
+ if (cmd->start_src == TRIG_NOW)
+ return timer_start_cmd(dev, s);
+
+ s->async->inttrig = timer_inttrig;
+
+ return 0;
+}
+
+static int timer_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trig_num)
+{
+ if (trig_num != 0)
+ return -EINVAL;
+
+ s->async->inttrig = NULL;
+
+ return timer_start_cmd(dev, s);
+}
+
+static int timer_start_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ RTIME now, delay, period;
+ int ret;
+
+ devpriv->stop = 0;
+ s->async->events = 0;
+
+ if (cmd->start_src == TRIG_NOW)
+ delay = nano2count(cmd->start_arg);
+ else
+ delay = 0;
+
+ now = rt_get_time();
+ /* Using 'period' this way gets around some weird bug in gcc-2.95.2
+ * that generates the compile error 'internal error--unrecognizable insn'
+ * when rt_task_make_period() is called (observed with rtlinux-3.1, linux-2.2.19).
+ * - fmhess */
+ period = devpriv->scan_period;
+ ret = rt_task_make_periodic(devpriv->rt_task, now + delay, period);
+ if (ret < 0) {
+ comedi_error(dev, "error starting rt_task");
+ return ret;
+ }
+ return 0;
+}
+
+static int timer_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s, *emul_s;
+ struct comedi_device *emul_dev;
+ /* These should probably be devconfig options[] */
+ const int timer_priority = 4;
+ const int scan_priority = timer_priority + 1;
+ char path[20];
+
+ printk("comedi%d: timer: ", dev->minor);
+
+ dev->board_name = "timer";
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct timer_private))) < 0)
+ return ret;
+
+ sprintf(path, "/dev/comedi%d", it->options[0]);
+ devpriv->device = comedi_open(path);
+ devpriv->subd = it->options[1];
+
+ printk("emulating commands for minor %i, subdevice %d\n",
+ it->options[0], devpriv->subd);
+
+ emul_dev = devpriv->device;
+ emul_s = emul_dev->subdevices + devpriv->subd;
+
+ // input or output subdevice
+ s = dev->subdevices + 0;
+ s->type = emul_s->type;
+ s->subdev_flags = emul_s->subdev_flags; /* SDF_GROUND (to fool check_driver) */
+ s->n_chan = emul_s->n_chan;
+ s->len_chanlist = 1024;
+ s->do_cmd = timer_cmd;
+ s->do_cmdtest = timer_cmdtest;
+ s->cancel = timer_cancel;
+ s->maxdata = emul_s->maxdata;
+ s->range_table = emul_s->range_table;
+ s->range_table_list = emul_s->range_table_list;
+ switch (emul_s->type) {
+ case COMEDI_SUBD_AI:
+ s->insn_read = timer_insn;
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ devpriv->io_function = timer_data_read;
+ break;
+ case COMEDI_SUBD_AO:
+ s->insn_write = timer_insn;
+ s->insn_read = timer_insn;
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ devpriv->io_function = timer_data_write;
+ break;
+ case COMEDI_SUBD_DIO:
+ s->insn_write = timer_insn;
+ s->insn_read = timer_insn;
+ s->insn_bits = timer_insn;
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ devpriv->io_function = timer_dio_read;
+ break;
+ default:
+ comedi_error(dev, "failed to determine subdevice type!");
+ return -EINVAL;
+ }
+
+ rt_set_oneshot_mode();
+ start_rt_timer(1);
+ devpriv->timer_running = 1;
+
+ devpriv->rt_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL);
+
+ // initialize real-time tasks
+ ret = rt_task_init(devpriv->rt_task, timer_task_func,
+ (comedi_rt_task_context_t) dev, 3000, timer_priority, 0, 0);
+ if (ret < 0) {
+ comedi_error(dev, "error initalizing rt_task");
+ kfree(devpriv->rt_task);
+ devpriv->rt_task = 0;
+ return ret;
+ }
+
+ devpriv->scan_task = kzalloc(sizeof(RT_TASK), GFP_KERNEL);
+
+ ret = rt_task_init(devpriv->scan_task, scan_task_func,
+ (comedi_rt_task_context_t) dev, 3000, scan_priority, 0, 0);
+ if (ret < 0) {
+ comedi_error(dev, "error initalizing scan_task");
+ kfree(devpriv->scan_task);
+ devpriv->scan_task = 0;
+ return ret;
+ }
+
+ return 1;
+}
+
+// free allocated resources
+static int timer_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: timer: remove\n", dev->minor);
+
+ if (devpriv) {
+ if (devpriv->rt_task) {
+ rt_task_delete(devpriv->rt_task);
+ kfree(devpriv->rt_task);
+ }
+ if (devpriv->scan_task) {
+ rt_task_delete(devpriv->scan_task);
+ kfree(devpriv->scan_task);
+ }
+ if (devpriv->timer_running)
+ stop_rt_timer();
+ if (devpriv->device)
+ comedi_close(devpriv->device);
+ }
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/comedi_test.c b/drivers/staging/comedi/drivers/comedi_test.c
index 4b4c37d0748..e679328a4f8 100644
--- a/drivers/staging/comedi/drivers/comedi_test.c
+++ b/drivers/staging/comedi/drivers/comedi_test.c
@@ -89,13 +89,13 @@ struct waveform_private {
unsigned int scan_period; /* scan period in usec */
unsigned int convert_period; /* conversion period in usec */
unsigned timer_running:1;
- lsampl_t ao_loopbacks[N_CHANS];
+ unsigned int ao_loopbacks[N_CHANS];
};
#define devpriv ((struct waveform_private *)dev->private)
-static int waveform_attach(comedi_device *dev, comedi_devconfig *it);
-static int waveform_detach(comedi_device *dev);
-static comedi_driver driver_waveform = {
+static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int waveform_detach(struct comedi_device *dev);
+static struct comedi_driver driver_waveform = {
.driver_name = "comedi_test",
.module = THIS_MODULE,
.attach = waveform_attach,
@@ -107,28 +107,28 @@ static comedi_driver driver_waveform = {
COMEDI_INITCLEANUP(driver_waveform);
-static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd);
-static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s);
-static int waveform_ai_cancel(comedi_device *dev, comedi_subdevice *s);
-static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
-static int waveform_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data);
-static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range,
+static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static short fake_sawtooth(struct comedi_device *dev, unsigned int range,
unsigned long current_time);
-static sampl_t fake_squarewave(comedi_device *dev, unsigned int range,
+static short fake_squarewave(struct comedi_device *dev, unsigned int range,
unsigned long current_time);
-static sampl_t fake_flatline(comedi_device *dev, unsigned int range,
+static short fake_flatline(struct comedi_device *dev, unsigned int range,
unsigned long current_time);
-static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
+static short fake_waveform(struct comedi_device *dev, unsigned int channel,
unsigned int range, unsigned long current_time);
/* 1000 nanosec in a microsec */
static const int nano_per_micro = 1000;
/* fake analog input ranges */
-static const comedi_lrange waveform_ai_ranges = {
+static const struct comedi_lrange waveform_ai_ranges = {
2,
{
BIP_RANGE(10),
@@ -143,9 +143,9 @@ static const comedi_lrange waveform_ai_ranges = {
*/
static void waveform_ai_interrupt(unsigned long arg)
{
- comedi_device *dev = (comedi_device *) arg;
- comedi_async *async = dev->read_subdev->async;
- comedi_cmd *cmd = &async->cmd;
+ struct comedi_device *dev = (struct comedi_device *) arg;
+ struct comedi_async *async = dev->read_subdev->async;
+ struct comedi_cmd *cmd = &async->cmd;
unsigned int i, j;
/* all times in microsec */
unsigned long elapsed_time;
@@ -192,9 +192,9 @@ static void waveform_ai_interrupt(unsigned long arg)
comedi_event(dev, dev->read_subdev);
}
-static int waveform_attach(comedi_device *dev, comedi_devconfig *it)
+static int waveform_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int amplitude = it->options[0];
int period = it->options[1];
int i;
@@ -259,7 +259,7 @@ static int waveform_attach(comedi_device *dev, comedi_devconfig *it)
return 1;
}
-static int waveform_detach(comedi_device *dev)
+static int waveform_detach(struct comedi_device *dev)
{
printk("comedi%d: comedi_test: remove\n", dev->minor);
@@ -269,8 +269,8 @@ static int waveform_detach(comedi_device *dev)
return 0;
}
-static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int waveform_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -397,9 +397,9 @@ static int waveform_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
return 0;
}
-static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s)
+static int waveform_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
if (cmd->flags & TRIG_RT) {
comedi_error(dev,
@@ -429,20 +429,20 @@ static int waveform_ai_cmd(comedi_device *dev, comedi_subdevice *s)
return 0;
}
-static int waveform_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int waveform_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
devpriv->timer_running = 0;
del_timer(&devpriv->timer);
return 0;
}
-static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range_index,
+static short fake_sawtooth(struct comedi_device *dev, unsigned int range_index,
unsigned long current_time)
{
- comedi_subdevice *s = dev->read_subdev;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned int offset = s->maxdata / 2;
u64 value;
- const comedi_krange *krange = &s->range_table->range[range_index];
+ const struct comedi_krange *krange = &s->range_table->range[range_index];
u64 binary_amplitude;
binary_amplitude = s->maxdata;
@@ -457,13 +457,13 @@ static sampl_t fake_sawtooth(comedi_device *dev, unsigned int range_index,
return offset + value;
}
-static sampl_t fake_squarewave(comedi_device *dev, unsigned int range_index,
+static short fake_squarewave(struct comedi_device *dev, unsigned int range_index,
unsigned long current_time)
{
- comedi_subdevice *s = dev->read_subdev;
+ struct comedi_subdevice *s = dev->read_subdev;
unsigned int offset = s->maxdata / 2;
u64 value;
- const comedi_krange *krange = &s->range_table->range[range_index];
+ const struct comedi_krange *krange = &s->range_table->range[range_index];
current_time %= devpriv->usec_period;
value = s->maxdata;
@@ -476,14 +476,14 @@ static sampl_t fake_squarewave(comedi_device *dev, unsigned int range_index,
return offset + value;
}
-static sampl_t fake_flatline(comedi_device *dev, unsigned int range_index,
+static short fake_flatline(struct comedi_device *dev, unsigned int range_index,
unsigned long current_time)
{
return dev->read_subdev->maxdata / 2;
}
/* generates a different waveform depending on what channel is read */
-static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
+static short fake_waveform(struct comedi_device *dev, unsigned int channel,
unsigned int range, unsigned long current_time)
{
enum {
@@ -504,8 +504,8 @@ static sampl_t fake_waveform(comedi_device *dev, unsigned int channel,
return fake_flatline(dev, range, current_time);
}
-static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int waveform_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i, chan = CR_CHAN(insn->chanspec);
@@ -515,8 +515,8 @@ static int waveform_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
return insn->n;
}
-static int waveform_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int waveform_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i, chan = CR_CHAN(insn->chanspec);
diff --git a/drivers/staging/comedi/drivers/contec_pci_dio.c b/drivers/staging/comedi/drivers/contec_pci_dio.c
new file mode 100644
index 00000000000..1f194a0a45d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/contec_pci_dio.c
@@ -0,0 +1,230 @@
+/*
+ comedi/drivers/contec_pci_dio.c
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: contec_pci_dio
+Description: Contec PIO1616L digital I/O board
+Devices: [Contec] PIO1616L (contec_pci_dio)
+Author: Stefano Rivoir <s.rivoir@gts.it>
+Updated: Wed, 27 Jun 2007 13:00:06 +0100
+Status: works
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+enum contec_model {
+ PIO1616L = 0,
+};
+
+struct contec_board {
+ const char *name;
+ int model;
+ int in_ports;
+ int out_ports;
+ int in_offs;
+ int out_offs;
+ int out_boffs;
+};
+static const struct contec_board contec_boards[] = {
+ {"PIO1616L", PIO1616L, 16, 16, 0, 2, 10},
+};
+
+#define PCI_DEVICE_ID_PIO1616L 0x8172
+static DEFINE_PCI_DEVICE_TABLE(contec_pci_table) = {
+ {PCI_VENDOR_ID_CONTEC, PCI_DEVICE_ID_PIO1616L, PCI_ANY_ID, PCI_ANY_ID,
+ 0, 0, PIO1616L},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, contec_pci_table);
+
+#define thisboard ((const struct contec_board *)dev->board_ptr)
+
+struct contec_private {
+ int data;
+
+ struct pci_dev *pci_dev;
+
+};
+
+#define devpriv ((struct contec_private *)dev->private)
+
+static int contec_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int contec_detach(struct comedi_device * dev);
+static struct comedi_driver driver_contec = {
+ driver_name:"contec_pci_dio",
+ module:THIS_MODULE,
+ attach:contec_attach,
+ detach:contec_detach,
+};
+
+/* Classic digital IO */
+static int contec_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int contec_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+#if 0
+static int contec_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+
+static int contec_ns_to_timer(unsigned int *ns, int round);
+#endif
+
+static int contec_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: contec: ", dev->minor);
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct contec_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ for (pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pcidev != NULL;
+ pcidev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pcidev)) {
+
+ if (pcidev->vendor == PCI_VENDOR_ID_CONTEC &&
+ pcidev->device == PCI_DEVICE_ID_PIO1616L) {
+ if (it->options[0] || it->options[1]) {
+ /* Check bus and slot. */
+ if (it->options[0] != pcidev->bus->number ||
+ it->options[1] !=
+ PCI_SLOT(pcidev->devfn)) {
+ continue;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+ if (comedi_pci_enable(pcidev, "contec_pci_dio")) {
+ printk("error enabling PCI device and request regions!\n");
+ return -EIO;
+ }
+ dev->iobase = pci_resource_start(pcidev, 0);
+ printk(" base addr %lx ", dev->iobase);
+
+ dev->board_ptr = contec_boards + 0;
+
+ s = dev->subdevices + 0;
+
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = contec_di_insn_bits;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = contec_do_insn_bits;
+
+ printk("attached\n");
+
+ return 1;
+ }
+ }
+
+ printk("card not present!\n");
+
+ return -EIO;
+}
+
+static int contec_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: contec: remove\n", dev->minor);
+
+ if (devpriv && devpriv->pci_dev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+
+ return 0;
+}
+
+#if 0
+static int contec_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ printk("contec_cmdtest called\n");
+ return 0;
+}
+
+static int contec_ns_to_timer(unsigned int *ns, int round)
+{
+ return *ns;
+}
+#endif
+
+static int contec_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ printk("contec_do_insn_bits called\n");
+ printk(" data: %d %d\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ rt_printk(" out: %d on %lx\n", s->state,
+ dev->iobase + thisboard->out_offs);
+ outw(s->state, dev->iobase + thisboard->out_offs);
+ }
+ return 2;
+}
+
+static int contec_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ rt_printk("contec_di_insn_bits called\n");
+ rt_printk(" data: %d %d\n", data[0], data[1]);
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inw(dev->iobase + thisboard->in_offs);
+
+ return 2;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_contec, contec_pci_table);
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c
new file mode 100644
index 00000000000..3b8444f09f2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/daqboard2000.c
@@ -0,0 +1,877 @@
+/*
+ comedi/drivers/daqboard2000.c
+ hardware driver for IOtech DAQboard/2000
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: daqboard2000
+Description: IOTech DAQBoard/2000
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Updated: Mon, 14 Apr 2008 15:28:52 +0100
+Devices: [IOTech] DAQBoard/2000 (daqboard2000)
+
+Much of the functionality of this driver was determined from reading
+the source code for the Windows driver.
+
+The FPGA on the board requires initialization code, which can
+be loaded by comedi_config using the -i
+option. The initialization code is available from http://www.comedi.org
+in the comedi_nonfree_firmware tarball.
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+*/
+/*
+ This card was obviously never intended to leave the Windows world,
+ since it lacked all kind of hardware documentation (except for cable
+ pinouts, plug and pray has something to catch up with yet).
+
+ With some help from our swedish distributor, we got the Windows sourcecode
+ for the card, and here are the findings so far.
+
+ 1. A good document that describes the PCI interface chip is found at:
+ http://plx.plxtech.com/download/9080/databook/9080db-106.pdf
+
+ 2. The initialization done so far is:
+ a. program the FPGA (windows code sans a lot of error messages)
+ b.
+
+ 3. Analog out seems to work OK with DAC's disabled, if DAC's are enabled,
+ you have to output values to all enabled DAC's until result appears, I
+ guess that it has something to do with pacer clocks, but the source
+ gives me no clues. I'll keep it simple so far.
+
+ 4. Analog in.
+ Each channel in the scanlist seems to be controlled by four
+ control words:
+
+ Word0:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+
+ Word1:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | | | | | | |
+ +------+------+ | | | | +-- Digital input (??)
+ | | | | +---- 10 us settling time
+ | | | +------ Suspend acquisition (last to scan)
+ | | +-------- Simultaneous sample and hold
+ | +---------- Signed data format
+ +------------------------- Correction offset low
+
+ Word2:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | | | | | | | | | |
+ +-----+ +--+--+ +++ +++ +--+--+
+ | | | | +----- Expansion channel
+ | | | +----------- Expansion gain
+ | | +--------------- Channel (low)
+ | +--------------------- Correction offset high
+ +----------------------------- Correction gain low
+ Word3:
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! | | | ! | | | ! | | | ! | | | !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | | | | | | | | |
+ +------+------+ | | +-+-+ | | +-- Low bank enable
+ | | | | | +---- High bank enable
+ | | | | +------ Hi/low select
+ | | | +---------- Gain (1,?,2,4,8,16,32,64)
+ | | +-------------- differential/single ended
+ | +---------------- Unipolar
+ +------------------------- Correction gain high
+
+
+
+ 999. The card seems to have an incredible amount of capabilities, but
+ trying to reverse engineer them from the Windows source is beyond my
+ patience.
+
+
+ */
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+
+#define DAQBOARD2000_SUBSYSTEM_IDS2 0x00021616 /* Daqboard/2000 - 2 Dacs */
+#define DAQBOARD2000_SUBSYSTEM_IDS4 0x00041616 /* Daqboard/2000 - 4 Dacs */
+
+#define DAQBOARD2000_DAQ_SIZE 0x1002
+#define DAQBOARD2000_PLX_SIZE 0x100
+
+// Initialization bits for the Serial EEPROM Control Register
+#define DAQBOARD2000_SECRProgPinHi 0x8001767e
+#define DAQBOARD2000_SECRProgPinLo 0x8000767e
+#define DAQBOARD2000_SECRLocalBusHi 0xc000767e
+#define DAQBOARD2000_SECRLocalBusLo 0x8000767e
+#define DAQBOARD2000_SECRReloadHi 0xa000767e
+#define DAQBOARD2000_SECRReloadLo 0x8000767e
+
+// SECR status bits
+#define DAQBOARD2000_EEPROM_PRESENT 0x10000000
+
+// CPLD status bits
+#define DAQBOARD2000_CPLD_INIT 0x0002
+#define DAQBOARD2000_CPLD_DONE 0x0004
+
+// Available ranges
+static const struct comedi_lrange range_daqboard2000_ai = { 13, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625),
+ RANGE(-0.3125, 0.3125),
+ RANGE(-0.156, 0.156),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ RANGE(0, 0.625),
+ RANGE(0, 0.3125)
+ }
+};
+
+static const struct comedi_lrange range_daqboard2000_ao = { 1, {
+ RANGE(-10, 10)
+ }
+};
+
+struct daqboard2000_hw {
+ volatile u16 acqControl; // 0x00
+ volatile u16 acqScanListFIFO; // 0x02
+ volatile u32 acqPacerClockDivLow; // 0x04
+
+ volatile u16 acqScanCounter; // 0x08
+ volatile u16 acqPacerClockDivHigh; // 0x0a
+ volatile u16 acqTriggerCount; // 0x0c
+ volatile u16 fill2; // 0x0e
+ volatile u16 acqResultsFIFO; // 0x10
+ volatile u16 fill3; // 0x12
+ volatile u16 acqResultsShadow; // 0x14
+ volatile u16 fill4; // 0x16
+ volatile u16 acqAdcResult; // 0x18
+ volatile u16 fill5; // 0x1a
+ volatile u16 dacScanCounter; // 0x1c
+ volatile u16 fill6; // 0x1e
+
+ volatile u16 dacControl; // 0x20
+ volatile u16 fill7; // 0x22
+ volatile s16 dacFIFO; // 0x24
+ volatile u16 fill8[2]; // 0x26
+ volatile u16 dacPacerClockDiv; // 0x2a
+ volatile u16 refDacs; // 0x2c
+ volatile u16 fill9; // 0x2e
+
+ volatile u16 dioControl; // 0x30
+ volatile s16 dioP3hsioData; // 0x32
+ volatile u16 dioP3Control; // 0x34
+ volatile u16 calEepromControl; // 0x36
+ volatile s16 dacSetting[4]; // 0x38
+ volatile s16 dioP2ExpansionIO8Bit[32]; // 0x40
+
+ volatile u16 ctrTmrControl; // 0x80
+ volatile u16 fill10[3]; // 0x82
+ volatile s16 ctrInput[4]; // 0x88
+ volatile u16 fill11[8]; // 0x90
+ volatile u16 timerDivisor[2]; // 0xa0
+ volatile u16 fill12[6]; // 0xa4
+
+ volatile u16 dmaControl; // 0xb0
+ volatile u16 trigControl; // 0xb2
+ volatile u16 fill13[2]; // 0xb4
+ volatile u16 calEeprom; // 0xb8
+ volatile u16 acqDigitalMark; // 0xba
+ volatile u16 trigDacs; // 0xbc
+ volatile u16 fill14; // 0xbe
+ volatile s16 dioP2ExpansionIO16Bit[32]; // 0xc0
+};
+
+/* Scan Sequencer programming */
+#define DAQBOARD2000_SeqStartScanList 0x0011
+#define DAQBOARD2000_SeqStopScanList 0x0010
+
+// Prepare for acquisition
+#define DAQBOARD2000_AcqResetScanListFifo 0x0004
+#define DAQBOARD2000_AcqResetResultsFifo 0x0002
+#define DAQBOARD2000_AcqResetConfigPipe 0x0001
+
+// Acqusition status bits
+#define DAQBOARD2000_AcqResultsFIFOMore1Sample 0x0001
+#define DAQBOARD2000_AcqResultsFIFOHasValidData 0x0002
+#define DAQBOARD2000_AcqResultsFIFOOverrun 0x0004
+#define DAQBOARD2000_AcqLogicScanning 0x0008
+#define DAQBOARD2000_AcqConfigPipeFull 0x0010
+#define DAQBOARD2000_AcqScanListFIFOEmpty 0x0020
+#define DAQBOARD2000_AcqAdcNotReady 0x0040
+#define DAQBOARD2000_ArbitrationFailure 0x0080
+#define DAQBOARD2000_AcqPacerOverrun 0x0100
+#define DAQBOARD2000_DacPacerOverrun 0x0200
+#define DAQBOARD2000_AcqHardwareError 0x01c0
+
+// Scan Sequencer programming
+#define DAQBOARD2000_SeqStartScanList 0x0011
+#define DAQBOARD2000_SeqStopScanList 0x0010
+
+/* Pacer Clock Control */
+#define DAQBOARD2000_AdcPacerInternal 0x0030
+#define DAQBOARD2000_AdcPacerExternal 0x0032
+#define DAQBOARD2000_AdcPacerEnable 0x0031
+#define DAQBOARD2000_AdcPacerEnableDacPacer 0x0034
+#define DAQBOARD2000_AdcPacerDisable 0x0030
+#define DAQBOARD2000_AdcPacerNormalMode 0x0060
+#define DAQBOARD2000_AdcPacerCompatibilityMode 0x0061
+#define DAQBOARD2000_AdcPacerInternalOutEnable 0x0008
+#define DAQBOARD2000_AdcPacerExternalRising 0x0100
+
+// DAC status
+#define DAQBOARD2000_DacFull 0x0001
+#define DAQBOARD2000_RefBusy 0x0002
+#define DAQBOARD2000_TrgBusy 0x0004
+#define DAQBOARD2000_CalBusy 0x0008
+#define DAQBOARD2000_Dac0Busy 0x0010
+#define DAQBOARD2000_Dac1Busy 0x0020
+#define DAQBOARD2000_Dac2Busy 0x0040
+#define DAQBOARD2000_Dac3Busy 0x0080
+
+// DAC control
+#define DAQBOARD2000_Dac0Enable 0x0021
+#define DAQBOARD2000_Dac1Enable 0x0031
+#define DAQBOARD2000_Dac2Enable 0x0041
+#define DAQBOARD2000_Dac3Enable 0x0051
+#define DAQBOARD2000_DacEnableBit 0x0001
+#define DAQBOARD2000_Dac0Disable 0x0020
+#define DAQBOARD2000_Dac1Disable 0x0030
+#define DAQBOARD2000_Dac2Disable 0x0040
+#define DAQBOARD2000_Dac3Disable 0x0050
+#define DAQBOARD2000_DacResetFifo 0x0004
+#define DAQBOARD2000_DacPatternDisable 0x0060
+#define DAQBOARD2000_DacPatternEnable 0x0061
+#define DAQBOARD2000_DacSelectSignedData 0x0002
+#define DAQBOARD2000_DacSelectUnsignedData 0x0000
+
+/* Trigger Control */
+#define DAQBOARD2000_TrigAnalog 0x0000
+#define DAQBOARD2000_TrigTTL 0x0010
+#define DAQBOARD2000_TrigTransHiLo 0x0004
+#define DAQBOARD2000_TrigTransLoHi 0x0000
+#define DAQBOARD2000_TrigAbove 0x0000
+#define DAQBOARD2000_TrigBelow 0x0004
+#define DAQBOARD2000_TrigLevelSense 0x0002
+#define DAQBOARD2000_TrigEdgeSense 0x0000
+#define DAQBOARD2000_TrigEnable 0x0001
+#define DAQBOARD2000_TrigDisable 0x0000
+
+// Reference Dac Selection
+#define DAQBOARD2000_PosRefDacSelect 0x0100
+#define DAQBOARD2000_NegRefDacSelect 0x0000
+
+static int daqboard2000_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int daqboard2000_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_daqboard2000 = {
+ driver_name:"daqboard2000",
+ module:THIS_MODULE,
+ attach:daqboard2000_attach,
+ detach:daqboard2000_detach,
+};
+
+struct daq200_boardtype {
+ const char *name;
+ int id;
+};
+static const struct daq200_boardtype boardtypes[] = {
+ {"ids2", DAQBOARD2000_SUBSYSTEM_IDS2},
+ {"ids4", DAQBOARD2000_SUBSYSTEM_IDS4},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct daq200_boardtype))
+#define this_board ((const struct daq200_boardtype *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(daqboard2000_pci_table) = {
+ {0x1616, 0x0409, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, daqboard2000_pci_table);
+
+struct daqboard2000_private {
+ enum {
+ card_daqboard_2000
+ } card;
+ struct pci_dev *pci_dev;
+ void *daq;
+ void *plx;
+ int got_regions;
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct daqboard2000_private *)dev->private)
+
+static void writeAcqScanListEntry(struct comedi_device * dev, u16 entry)
+{
+ struct daqboard2000_hw *fpga = devpriv->daq;
+
+// comedi_udelay(4);
+ fpga->acqScanListFIFO = entry & 0x00ff;
+// comedi_udelay(4);
+ fpga->acqScanListFIFO = (entry >> 8) & 0x00ff;
+}
+
+static void setup_sampling(struct comedi_device * dev, int chan, int gain)
+{
+ u16 word0, word1, word2, word3;
+
+ /* Channel 0-7 diff, channel 8-23 single ended */
+ word0 = 0;
+ word1 = 0x0004; /* Last scan */
+ word2 = (chan << 6) & 0x00c0;
+ switch (chan / 4) {
+ case 0:
+ word3 = 0x0001;
+ break;
+ case 1:
+ word3 = 0x0002;
+ break;
+ case 2:
+ word3 = 0x0005;
+ break;
+ case 3:
+ word3 = 0x0006;
+ break;
+ case 4:
+ word3 = 0x0041;
+ break;
+ case 5:
+ word3 = 0x0042;
+ break;
+ default:
+ word3 = 0;
+ break;
+ }
+/*
+ dev->eeprom.correctionDACSE[i][j][k].offset = 0x800;
+ dev->eeprom.correctionDACSE[i][j][k].gain = 0xc00;
+*/
+ /* These should be read from EEPROM */
+ word2 |= 0x0800;
+ word3 |= 0xc000;
+/* printk("%d %4.4x %4.4x %4.4x %4.4x\n", chan, word0, word1, word2, word3);*/
+ writeAcqScanListEntry(dev, word0);
+ writeAcqScanListEntry(dev, word1);
+ writeAcqScanListEntry(dev, word2);
+ writeAcqScanListEntry(dev, word3);
+}
+
+static int daqboard2000_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ struct daqboard2000_hw *fpga = devpriv->daq;
+ int gain, chan, timeout;
+
+ fpga->acqControl =
+ DAQBOARD2000_AcqResetScanListFifo |
+ DAQBOARD2000_AcqResetResultsFifo |
+ DAQBOARD2000_AcqResetConfigPipe;
+
+ /* If pacer clock is not set to some high value (> 10 us), we
+ risk multiple samples to be put into the result FIFO. */
+ fpga->acqPacerClockDivLow = 1000000; /* 1 second, should be long enough */
+ fpga->acqPacerClockDivHigh = 0;
+
+ gain = CR_RANGE(insn->chanspec);
+ chan = CR_CHAN(insn->chanspec);
+
+ /* This doesn't look efficient. I decided to take the conservative
+ * approach when I did the insn conversion. Perhaps it would be
+ * better to have broken it completely, then someone would have been
+ * forced to fix it. --ds */
+ for (i = 0; i < insn->n; i++) {
+ setup_sampling(dev, chan, gain);
+ /* Enable reading from the scanlist FIFO */
+ fpga->acqControl = DAQBOARD2000_SeqStartScanList;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if (fpga->acqControl & DAQBOARD2000_AcqConfigPipeFull) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ fpga->acqControl = DAQBOARD2000_AdcPacerEnable;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if (fpga->acqControl & DAQBOARD2000_AcqLogicScanning) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ for (timeout = 0; timeout < 20; timeout++) {
+ if (fpga->
+ acqControl &
+ DAQBOARD2000_AcqResultsFIFOHasValidData) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ data[i] = fpga->acqResultsFIFO;
+ fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
+ fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+ }
+
+ return i;
+}
+
+static int daqboard2000_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int daqboard2000_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ struct daqboard2000_hw *fpga = devpriv->daq;
+ int timeout;
+
+ for (i = 0; i < insn->n; i++) {
+ /*
+ * OK, since it works OK without enabling the DAC's, let's keep
+ * it as simple as possible...
+ */
+ //fpga->dacControl = (chan + 2) * 0x0010 | 0x0001; comedi_udelay(1000);
+ fpga->dacSetting[chan] = data[i];
+ for (timeout = 0; timeout < 20; timeout++) {
+ if ((fpga->dacControl & ((chan + 1) * 0x0010)) == 0) {
+ break;
+ }
+ //comedi_udelay(2);
+ }
+ devpriv->ao_readback[chan] = data[i];
+ /*
+ * Since we never enabled the DAC's, we don't need to disable it...
+ * fpga->dacControl = (chan + 2) * 0x0010 | 0x0000; comedi_udelay(1000);
+ */
+ }
+
+ return i;
+}
+
+static void daqboard2000_resetLocalBus(struct comedi_device * dev)
+{
+ printk("daqboard2000_resetLocalBus\n");
+ writel(DAQBOARD2000_SECRLocalBusHi, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRLocalBusLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+}
+
+static void daqboard2000_reloadPLX(struct comedi_device * dev)
+{
+ printk("daqboard2000_reloadPLX\n");
+ writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRReloadHi, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRReloadLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+}
+
+static void daqboard2000_pulseProgPin(struct comedi_device * dev)
+{
+ printk("daqboard2000_pulseProgPin 1\n");
+ writel(DAQBOARD2000_SECRProgPinHi, devpriv->plx + 0x6c);
+ comedi_udelay(10000);
+ writel(DAQBOARD2000_SECRProgPinLo, devpriv->plx + 0x6c);
+ comedi_udelay(10000); /* Not in the original code, but I like symmetry... */
+}
+
+static int daqboard2000_pollCPLD(struct comedi_device * dev, int mask)
+{
+ int result = 0;
+ int i;
+ int cpld;
+
+ /* timeout after 50 tries -> 5ms */
+ for (i = 0; i < 50; i++) {
+ cpld = readw(devpriv->daq + 0x1000);
+ if ((cpld & mask) == mask) {
+ result = 1;
+ break;
+ }
+ comedi_udelay(100);
+ }
+ comedi_udelay(5);
+ return result;
+}
+
+static int daqboard2000_writeCPLD(struct comedi_device * dev, int data)
+{
+ int result = 0;
+
+ comedi_udelay(10);
+ writew(data, devpriv->daq + 0x1000);
+ if ((readw(devpriv->daq + 0x1000) & DAQBOARD2000_CPLD_INIT) ==
+ DAQBOARD2000_CPLD_INIT) {
+ result = 1;
+ }
+ return result;
+}
+
+static int initialize_daqboard2000(struct comedi_device * dev,
+ unsigned char *cpld_array, int len)
+{
+ int result = -EIO;
+ /* Read the serial EEPROM control register */
+ int secr;
+ int retry;
+ int i;
+
+ /* Check to make sure the serial eeprom is present on the board */
+ secr = readl(devpriv->plx + 0x6c);
+ if (!(secr & DAQBOARD2000_EEPROM_PRESENT)) {
+#ifdef DEBUG_EEPROM
+ printk("no serial eeprom\n");
+#endif
+ return -EIO;
+ }
+
+ for (retry = 0; retry < 3; retry++) {
+#ifdef DEBUG_EEPROM
+ printk("Programming EEPROM try %x\n", retry);
+#endif
+
+ daqboard2000_resetLocalBus(dev);
+ daqboard2000_reloadPLX(dev);
+ daqboard2000_pulseProgPin(dev);
+ if (daqboard2000_pollCPLD(dev, DAQBOARD2000_CPLD_INIT)) {
+ for (i = 0; i < len; i++) {
+ if (cpld_array[i] == 0xff
+ && cpld_array[i + 1] == 0x20) {
+#ifdef DEBUG_EEPROM
+ printk("Preamble found at %d\n", i);
+#endif
+ break;
+ }
+ }
+ for (; i < len; i += 2) {
+ int data =
+ (cpld_array[i] << 8) + cpld_array[i +
+ 1];
+ if (!daqboard2000_writeCPLD(dev, data)) {
+ break;
+ }
+ }
+ if (i >= len) {
+#ifdef DEBUG_EEPROM
+ printk("Programmed\n");
+#endif
+ daqboard2000_resetLocalBus(dev);
+ daqboard2000_reloadPLX(dev);
+ result = 0;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+static void daqboard2000_adcStopDmaTransfer(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_adcStopDmaTransfer\n");*/
+}
+
+static void daqboard2000_adcDisarm(struct comedi_device * dev)
+{
+ struct daqboard2000_hw *fpga = devpriv->daq;
+
+ /* Disable hardware triggers */
+ comedi_udelay(2);
+ fpga->trigControl = DAQBOARD2000_TrigAnalog | DAQBOARD2000_TrigDisable;
+ comedi_udelay(2);
+ fpga->trigControl = DAQBOARD2000_TrigTTL | DAQBOARD2000_TrigDisable;
+
+ /* Stop the scan list FIFO from loading the configuration pipe */
+ comedi_udelay(2);
+ fpga->acqControl = DAQBOARD2000_SeqStopScanList;
+
+ /* Stop the pacer clock */
+ comedi_udelay(2);
+ fpga->acqControl = DAQBOARD2000_AdcPacerDisable;
+
+ /* Stop the input dma (abort channel 1) */
+ daqboard2000_adcStopDmaTransfer(dev);
+}
+
+static void daqboard2000_activateReferenceDacs(struct comedi_device * dev)
+{
+ struct daqboard2000_hw *fpga = devpriv->daq;
+ int timeout;
+
+ // Set the + reference dac value in the FPGA
+ fpga->refDacs = 0x80 | DAQBOARD2000_PosRefDacSelect;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+ break;
+ }
+ comedi_udelay(2);
+ }
+/* printk("DAQBOARD2000_PosRefDacSelect %d\n", timeout);*/
+
+ // Set the - reference dac value in the FPGA
+ fpga->refDacs = 0x80 | DAQBOARD2000_NegRefDacSelect;
+ for (timeout = 0; timeout < 20; timeout++) {
+ if ((fpga->dacControl & DAQBOARD2000_RefBusy) == 0) {
+ break;
+ }
+ comedi_udelay(2);
+ }
+/* printk("DAQBOARD2000_NegRefDacSelect %d\n", timeout);*/
+}
+
+static void daqboard2000_initializeCtrs(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_initializeCtrs\n");*/
+}
+
+static void daqboard2000_initializeTmrs(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_initializeTmrs\n");*/
+}
+
+static void daqboard2000_dacDisarm(struct comedi_device * dev)
+{
+/* printk("Implement: daqboard2000_dacDisarm\n");*/
+}
+
+static void daqboard2000_initializeAdc(struct comedi_device * dev)
+{
+ daqboard2000_adcDisarm(dev);
+ daqboard2000_activateReferenceDacs(dev);
+ daqboard2000_initializeCtrs(dev);
+ daqboard2000_initializeTmrs(dev);
+}
+
+static void daqboard2000_initializeDac(struct comedi_device * dev)
+{
+ daqboard2000_dacDisarm(dev);
+}
+
+/*
+The test command, REMOVE!!:
+
+rmmod daqboard2000 ; rmmod comedi; make install ; modprobe daqboard2000; /usr/sbin/comedi_config /dev/comedi0 daqboard/2000 ; tail -40 /var/log/messages
+*/
+
+static int daqboard2000_8255_cb(int dir, int port, int data,
+ unsigned long ioaddr)
+{
+ int result = 0;
+ if (dir) {
+ writew(data, ((void *)ioaddr) + port * 2);
+ result = 0;
+ } else {
+ result = readw(((void *)ioaddr) + port * 2);
+ }
+/*
+ printk("daqboard2000_8255_cb %x %d %d %2.2x -> %2.2x\n",
+ arg, dir, port, data, result);
+*/
+ return result;
+}
+
+static int daqboard2000_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ struct comedi_subdevice *s;
+ struct pci_dev *card = NULL;
+ void *aux_data;
+ unsigned int aux_len;
+ int bus, slot;
+
+ printk("comedi%d: daqboard2000:", dev->minor);
+
+ bus = it->options[0];
+ slot = it->options[1];
+
+ result = alloc_private(dev, sizeof(struct daqboard2000_private));
+ if (result < 0) {
+ return -ENOMEM;
+ }
+ for (card = pci_get_device(0x1616, 0x0409, NULL);
+ card != NULL;
+ card = pci_get_device(0x1616, 0x0409, card)) {
+ if (bus || slot) {
+ /* requested particular bus/slot */
+ if (card->bus->number != bus ||
+ PCI_SLOT(card->devfn) != slot) {
+ continue;
+ }
+ }
+ break; /* found one */
+ }
+ if (!card) {
+ if (bus || slot)
+ printk(" no daqboard2000 found at bus/slot: %d/%d\n",
+ bus, slot);
+ else
+ printk(" no daqboard2000 found\n");
+ return -EIO;
+ } else {
+ u32 id;
+ int i;
+ devpriv->pci_dev = card;
+ id = ((u32) card->subsystem_device << 16) | card->
+ subsystem_vendor;
+ for (i = 0; i < n_boardtypes; i++) {
+ if (boardtypes[i].id == id) {
+ printk(" %s", boardtypes[i].name);
+ dev->board_ptr = boardtypes + i;
+ }
+ }
+ if (!dev->board_ptr) {
+ printk(" unknown subsystem id %08x (pretend it is an ids2)", id);
+ dev->board_ptr = boardtypes;
+ }
+ }
+
+ if ((result = comedi_pci_enable(card, "daqboard2000")) < 0) {
+ printk(" failed to enable PCI device and request regions\n");
+ return -EIO;
+ }
+ devpriv->got_regions = 1;
+ devpriv->plx =
+ ioremap(pci_resource_start(card, 0), DAQBOARD2000_PLX_SIZE);
+ devpriv->daq =
+ ioremap(pci_resource_start(card, 2), DAQBOARD2000_DAQ_SIZE);
+ if (!devpriv->plx || !devpriv->daq) {
+ return -ENOMEM;
+ }
+
+ result = alloc_subdevices(dev, 3);
+ if (result < 0)
+ goto out;
+
+ readl(devpriv->plx + 0x6c);
+
+ /*
+ u8 interrupt;
+ Windows code does restore interrupts, but since we don't use them...
+ pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);
+ printk("Interrupt before is: %x\n", interrupt);
+ */
+
+ aux_data = comedi_aux_data(it->options, 0);
+ aux_len = it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH];
+
+ if (aux_data && aux_len) {
+ result = initialize_daqboard2000(dev, aux_data, aux_len);
+ } else {
+ printk("no FPGA initialization code, aborting\n");
+ result = -EIO;
+ }
+ if (result < 0)
+ goto out;
+ daqboard2000_initializeAdc(dev);
+ daqboard2000_initializeDac(dev);
+ /*
+ Windows code does restore interrupts, but since we don't use them...
+ pci_read_config_byte(card, PCI_INTERRUPT_LINE, &interrupt);
+ printk("Interrupt after is: %x\n", interrupt);
+ */
+
+ dev->iobase = (unsigned long)devpriv->daq;
+
+ dev->board_name = this_board->name;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 24;
+ s->maxdata = 0xffff;
+ s->insn_read = daqboard2000_ai_insn_read;
+ s->range_table = &range_daqboard2000_ai;
+
+ s = dev->subdevices + 1;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = 0xffff;
+ s->insn_read = daqboard2000_ao_insn_read;
+ s->insn_write = daqboard2000_ao_insn_write;
+ s->range_table = &range_daqboard2000_ao;
+
+ s = dev->subdevices + 2;
+ result = subdev_8255_init(dev, s, daqboard2000_8255_cb,
+ (unsigned long)(dev->iobase + 0x40));
+
+ printk("\n");
+ out:
+ return result;
+}
+
+static int daqboard2000_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: daqboard2000: remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ }
+ if (devpriv) {
+ if (devpriv->daq)
+ iounmap(devpriv->daq);
+ if (devpriv->plx)
+ iounmap(devpriv->plx);
+ if (devpriv->pci_dev) {
+ if (devpriv->got_regions) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_daqboard2000, daqboard2000_pci_table);
diff --git a/drivers/staging/comedi/drivers/das08.c b/drivers/staging/comedi/drivers/das08.c
new file mode 100644
index 00000000000..e4563331e96
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08.c
@@ -0,0 +1,1068 @@
+/*
+ comedi/drivers/das08.c
+ DAS08 driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2004 Salvador E. Tropea <set@users.sf.net> <set@ieee.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*****************************************************************
+
+*/
+/*
+Driver: das08
+Description: DAS-08 compatible boards
+Author: Warren Jasper, ds, Frank Hess
+Devices: [Keithley Metrabyte] DAS08 (isa-das08), [ComputerBoards] DAS08 (isa-das08),
+ DAS08-PGM (das08-pgm),
+ DAS08-PGH (das08-pgh), DAS08-PGL (das08-pgl), DAS08-AOH (das08-aoh),
+ DAS08-AOL (das08-aol), DAS08-AOM (das08-aom), DAS08/JR-AO (das08/jr-ao),
+ DAS08/JR-16-AO (das08jr-16-ao), PCI-DAS08 (das08),
+ PC104-DAS08 (pc104-das08), DAS08/JR/16 (das08jr/16)
+Status: works
+
+This is a rewrite of the das08 and das08jr drivers.
+
+Options (for ISA cards):
+ [0] - base io address
+
+Options (for pci-das08):
+ [0] - bus (optional)
+ [1] = slot (optional)
+
+The das08 driver doesn't support asynchronous commands, since
+the cheap das08 hardware doesn't really support them. The
+comedi_rt_timer driver can be used to emulate commands for this
+driver.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "8255.h"
+#include "das08.h"
+
+#define DRV_NAME "das08"
+
+#define PCI_VENDOR_ID_COMPUTERBOARDS 0x1307
+#define PCI_DEVICE_ID_PCIDAS08 0x29
+#define PCIDAS08_SIZE 0x54
+
+// pci configuration registers
+#define INTCSR 0x4c
+#define INTR1_ENABLE 0x1
+#define INTR1_HIGH_POLARITY 0x2
+#define PCI_INTR_ENABLE 0x40
+#define INTR1_EDGE_TRIG 0x100 // requires high polarity
+#define CNTRL 0x50
+#define CNTRL_DIR 0x2
+#define CNTRL_INTR 0x4
+
+/*
+ cio-das08.pdf
+
+ "isa-das08"
+
+ 0 a/d bits 0-3 start 8 bit
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, ip1-3, irq, mux op1-4, inte, mux
+ 3 unused unused
+ 4567 8254
+ 89ab 8255
+
+ requires hard-wiring for async ai
+
+*/
+
+#define DAS08_LSB 0
+#define DAS08_MSB 1
+#define DAS08_TRIG_12BIT 1
+#define DAS08_STATUS 2
+#define DAS08_EOC (1<<7)
+#define DAS08_IRQ (1<<3)
+#define DAS08_IP(x) (((x)>>4)&0x7)
+#define DAS08_CONTROL 2
+#define DAS08_MUX_MASK 0x7
+#define DAS08_MUX(x) ((x) & DAS08_MUX_MASK)
+#define DAS08_INTE (1<<3)
+#define DAS08_DO_MASK 0xf0
+#define DAS08_OP(x) (((x) << 4) & DAS08_DO_MASK)
+
+/*
+ cio-das08jr.pdf
+
+ "das08/jr-ao"
+
+ 0 a/d bits 0-3 unused
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, mux mux
+ 3 di do
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+
+*/
+
+#define DAS08JR_DIO 3
+#define DAS08JR_AO_LSB(x) ((x)?6:4)
+#define DAS08JR_AO_MSB(x) ((x)?7:5)
+
+/*
+ cio-das08_aox.pdf
+
+ "das08-aoh"
+ "das08-aol"
+ "das08-aom"
+
+ 0 a/d bits 0-3 start 8 bit
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, ip1-3, irq, mux op1-4, inte, mux
+ 3 mux, gain status gain control
+ 4567 8254
+ 8 unused ao0_lsb
+ 9 unused ao0_msb
+ a unused ao1_lsb
+ b unused ao1_msb
+ 89ab
+ cdef 8255
+*/
+
+#define DAS08AO_GAIN_CONTROL 3
+#define DAS08AO_GAIN_STATUS 3
+
+#define DAS08AO_AO_LSB(x) ((x)?0xa:8)
+#define DAS08AO_AO_MSB(x) ((x)?0xb:9)
+#define DAS08AO_AO_UPDATE 8
+
+/* gainlist same as _pgx_ below */
+
+static int das08_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08jr_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08jr_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08jr_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das08ao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static void i8254_set_mode_low(unsigned int base, int channel,
+ unsigned int mode);
+
+static const struct comedi_lrange range_das08_pgl = { 9, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25)
+ }
+};
+static const struct comedi_lrange range_das08_pgh = { 12, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_das08_pgm = { 9, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01)
+ }
+}; /*
+ cio-das08jr.pdf
+
+ "das08/jr-ao"
+
+ 0 a/d bits 0-3 unused
+ 1 a/d bits 4-11 start 12 bit
+ 2 eoc, mux mux
+ 3 di do
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+
+ */
+
+static const struct comedi_lrange *const das08_ai_lranges[] = {
+ &range_unknown,
+ &range_bipolar5,
+ &range_das08_pgh,
+ &range_das08_pgl,
+ &range_das08_pgm,
+};
+
+static const int das08_pgh_gainlist[] =
+ { 8, 0, 10, 2, 12, 4, 14, 6, 1, 3, 5, 7 };
+static const int das08_pgl_gainlist[] = { 8, 0, 2, 4, 6, 1, 3, 5, 7 };
+static const int das08_pgm_gainlist[] = { 8, 0, 10, 12, 14, 9, 11, 13, 15 };
+
+static const int *const das08_gainlists[] = {
+ NULL,
+ NULL,
+ das08_pgh_gainlist,
+ das08_pgl_gainlist,
+ das08_pgm_gainlist,
+};
+
+static const struct das08_board_struct das08_boards[] = {
+ {
+ name: "isa-das08", // cio-das08.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:8,
+ i8254_offset:4,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-pgm", // cio-das08pgx.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgm,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-pgh", // cio-das08pgx.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgh,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-pgl", // cio-das08pgx.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgl,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-aoh", // cio-das08_aox.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgh,
+ ai_encoding:das08_encode12,
+ ao: das08ao_ao_winsn, // 8
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0x0c,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-aol", // cio-das08_aox.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgl,
+ ai_encoding:das08_encode12,
+ ao: das08ao_ao_winsn, // 8
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0x0c,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08-aom", // cio-das08_aox.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pgm,
+ ai_encoding:das08_encode12,
+ ao: das08ao_ao_winsn, // 8
+ ao_nbits:12,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0x0c,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08/jr-ao", // cio-das08-jr-ao.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: das08jr_ao_winsn,
+ ao_nbits:12,
+ di: das08jr_di_rbits,
+ do_: das08jr_do_wbits,
+ do_nchan:8,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16, // unchecked
+ },
+ {
+ name: "das08jr-16-ao", // cio-das08jr-16-ao.pdf
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:16,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: das08jr_ao_winsn,
+ ao_nbits:16,
+ di: das08jr_di_rbits,
+ do_: das08jr_do_wbits,
+ do_nchan:8,
+ i8255_offset:0,
+ i8254_offset:0x04,
+ iosize: 16, // unchecked
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "das08", // pci-das08
+ id: PCI_DEVICE_ID_PCIDAS08,
+ bustype: pci,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_bipolar5,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:4,
+ iosize: 8,
+ },
+#endif
+ {
+ name: "pc104-das08",
+ bustype: pc104,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:4,
+ i8255_offset:0,
+ i8254_offset:4,
+ iosize: 16, // unchecked
+ },
+#if 0
+ {
+ name: "das08/f",
+ },
+ {
+ name: "das08jr",
+ },
+#endif
+ {
+ name: "das08jr/16",
+ bustype: isa,
+ ai: das08_ai_rinsn,
+ ai_nbits:16,
+ ai_pg: das08_pg_none,
+ ai_encoding:das08_encode16,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08jr_di_rbits,
+ do_: das08jr_do_wbits,
+ do_nchan:8,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16, // unchecked
+ },
+#if 0
+ {
+ name: "das48-pga", // cio-das48-pga.pdf
+ },
+ {
+ name: "das08-pga-g2", // a KM board
+ },
+#endif
+};
+
+#ifdef CONFIG_COMEDI_PCMCIA
+struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS] = {
+ {
+ name: "pcm-das08",
+ id: 0x0, // XXX
+ bustype: pcmcia,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_bipolar5,
+ ai_encoding:das08_pcm_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:3,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16,
+ },
+ // duplicate so driver name can be used also
+ {
+ name: "das08_cs",
+ id: 0x0, // XXX
+ bustype: pcmcia,
+ ai: das08_ai_rinsn,
+ ai_nbits:12,
+ ai_pg: das08_bipolar5,
+ ai_encoding:das08_pcm_encode12,
+ ao: NULL,
+ ao_nbits:0,
+ di: das08_di_rbits,
+ do_: das08_do_wbits,
+ do_nchan:3,
+ i8255_offset:0,
+ i8254_offset:0,
+ iosize: 16,
+ },
+};
+#endif
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(das08_pci_table) = {
+ {PCI_VENDOR_ID_COMPUTERBOARDS, PCI_DEVICE_ID_PCIDAS08, PCI_ANY_ID,
+ PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, das08_pci_table);
+#endif
+
+#define devpriv ((struct das08_private_struct *)dev->private)
+#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
+
+#define TIMEOUT 100000
+
+static int das08_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan;
+ int range;
+ int lsb, msb;
+
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+
+ /* clear crap */
+ inb(dev->iobase + DAS08_LSB);
+ inb(dev->iobase + DAS08_MSB);
+
+ /* set multiplexer */
+ spin_lock(&dev->spinlock); // lock to prevent race with digital output
+ devpriv->do_mux_bits &= ~DAS08_MUX_MASK;
+ devpriv->do_mux_bits |= DAS08_MUX(chan);
+ outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+ spin_unlock(&dev->spinlock);
+
+ if (s->range_table->length > 1) {
+ /* set gain/range */
+ range = CR_RANGE(insn->chanspec);
+ outb(devpriv->pg_gainlist[range],
+ dev->iobase + DAS08AO_GAIN_CONTROL);
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ /* clear over-range bits for 16-bit boards */
+ if (thisboard->ai_nbits == 16)
+ if (inb(dev->iobase + DAS08_MSB) & 0x80)
+ rt_printk("das08: over-range\n");
+
+ /* trigger conversion */
+ outb_p(0, dev->iobase + DAS08_TRIG_12BIT);
+
+ for (i = 0; i < TIMEOUT; i++) {
+ if (!(inb(dev->iobase + DAS08_STATUS) & DAS08_EOC))
+ break;
+ }
+ if (i == TIMEOUT) {
+ rt_printk("das08: timeout\n");
+ return -ETIME;
+ }
+ msb = inb(dev->iobase + DAS08_MSB);
+ lsb = inb(dev->iobase + DAS08_LSB);
+ if (thisboard->ai_encoding == das08_encode12) {
+ data[n] = (lsb >> 4) | (msb << 4);
+ } else if (thisboard->ai_encoding == das08_pcm_encode12) {
+ data[n] = (msb << 8) + lsb;
+ } else if (thisboard->ai_encoding == das08_encode16) {
+ /* FPOS 16-bit boards are sign-magnitude */
+ if (msb & 0x80)
+ data[n] = (1 << 15) | lsb | ((msb & 0x7f) << 8);
+ else
+ data[n] = (1 << 15) - (lsb | (msb & 0x7f) << 8);
+ } else {
+ comedi_error(dev, "bug! unknown ai encoding");
+ return -1;
+ }
+ }
+
+ return n;
+}
+
+static int das08_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = 0;
+ data[1] = DAS08_IP(inb(dev->iobase + DAS08_STATUS));
+
+ return 2;
+}
+
+static int das08_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int wbits;
+
+ // get current settings of digital output lines
+ wbits = (devpriv->do_mux_bits >> 4) & 0xf;
+ // null bits we are going to set
+ wbits &= ~data[0];
+ // set new bit values
+ wbits |= data[0] & data[1];
+ // remember digital output bits
+ spin_lock(&dev->spinlock); // prevent race with setting of analog input mux
+ devpriv->do_mux_bits &= ~DAS08_DO_MASK;
+ devpriv->do_mux_bits |= DAS08_OP(wbits);
+ outb(devpriv->do_mux_bits, dev->iobase + DAS08_CONTROL);
+ spin_unlock(&dev->spinlock);
+
+ data[1] = wbits;
+
+ return 2;
+}
+
+static int das08jr_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = 0;
+ data[1] = inb(dev->iobase + DAS08JR_DIO);
+
+ return 2;
+}
+
+static int das08jr_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ // null bits we are going to set
+ devpriv->do_bits &= ~data[0];
+ // set new bit values
+ devpriv->do_bits |= data[0] & data[1];
+ outb(devpriv->do_bits, dev->iobase + DAS08JR_DIO);
+
+ data[1] = devpriv->do_bits;
+
+ return 2;
+}
+
+static int das08jr_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int lsb, msb;
+ int chan;
+
+ lsb = data[0] & 0xff;
+ msb = (data[0] >> 8) & 0xf;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+#if 0
+ outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]);
+ outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]);
+#else
+ outb(lsb, dev->iobase + DAS08JR_AO_LSB(chan));
+ outb(msb, dev->iobase + DAS08JR_AO_MSB(chan));
+#endif
+
+ /* load DACs */
+ inb(dev->iobase + DAS08JR_DIO);
+ }
+
+ return n;
+}
+
+/*
+ *
+ * The -aox boards have the DACs at a different offset and use
+ * a different method to force an update.
+ *
+ */
+static int das08ao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int lsb, msb;
+ int chan;
+
+ lsb = data[0] & 0xff;
+ msb = (data[0] >> 8) & 0xf;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+#if 0
+ outb(lsb, dev->iobase + devpriv->ao_offset_lsb[chan]);
+ outb(msb, dev->iobase + devpriv->ao_offset_msb[chan]);
+#else
+ outb(lsb, dev->iobase + DAS08AO_AO_LSB(chan));
+ outb(msb, dev->iobase + DAS08AO_AO_MSB(chan));
+#endif
+
+ /* load DACs */
+ inb(dev->iobase + DAS08AO_AO_UPDATE);
+ }
+
+ return n;
+}
+
+static unsigned int i8254_read_channel_low(unsigned int base, int chan)
+{
+ unsigned int msb, lsb;
+
+ /* The following instructions must be in order.
+ We must avoid other process reading the counter's value in the
+ middle.
+ The spin_lock isn't needed since ioctl calls grab the big kernel
+ lock automatically */
+ /*spin_lock(sp); */
+ outb(chan << 6, base + I8254_CTRL);
+ base += chan;
+ lsb = inb(base);
+ msb = inb(base);
+ /*spin_unlock(sp); */
+
+ return lsb | (msb << 8);
+}
+
+static void i8254_write_channel_low(unsigned int base, int chan,
+ unsigned int value)
+{
+ unsigned int msb, lsb;
+
+ lsb = value & 0xFF;
+ msb = value >> 8;
+
+ /* write lsb, then msb */
+ base += chan;
+ /* See comments in i8254_read_channel_low */
+ /*spin_lock(sp); */
+ outb(lsb, base);
+ outb(msb, base);
+ /*spin_unlock(sp); */
+}
+
+static unsigned int i8254_read_channel(struct i8254_struct *st, int channel)
+{
+ int chan = st->logic2phys[channel];
+
+ return i8254_read_channel_low(st->iobase, chan);
+}
+
+static void i8254_write_channel(struct i8254_struct *st, int channel,
+ unsigned int value)
+{
+ int chan = st->logic2phys[channel];
+
+ i8254_write_channel_low(st->iobase, chan, value);
+}
+
+static void i8254_initialize(struct i8254_struct *st)
+{
+ int i;
+ for (i = 0; i < 3; ++i)
+ i8254_set_mode_low(st->iobase, i, st->mode[i]);
+}
+
+static void i8254_set_mode_low(unsigned int base, int channel,
+ unsigned int mode)
+{
+ outb((channel << 6) | 0x30 | (mode & 0x0F), base + I8254_CTRL);
+}
+
+static void i8254_set_mode(struct i8254_struct *st, int channel,
+ unsigned int mode)
+{
+ int chan = st->logic2phys[channel];
+
+ st->mode[chan] = mode;
+ return i8254_set_mode_low(st->iobase, chan, mode);
+}
+
+static unsigned int i8254_read_status_low(unsigned int base, int channel)
+{
+ outb(0xE0 | (2 << channel), base + I8254_CTRL);
+ return inb(base + channel);
+}
+
+static unsigned int i8254_read_status(struct i8254_struct *st, int channel)
+{
+ int chan = st->logic2phys[channel];
+
+ return i8254_read_status_low(st->iobase, chan);
+}
+
+static int das08_counter_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = insn->chanspec;
+
+ //printk("Reading counter channel %d ",chan);
+ data[0] = i8254_read_channel(&devpriv->i8254, chan);
+ //printk("=> 0x%08X\n",data[0]);
+
+ return 1;
+}
+
+static int das08_counter_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = insn->chanspec;
+
+ //printk("Writing counter channel %d with 0x%04X\n",chan,data[0]);
+ i8254_write_channel(&devpriv->i8254, chan, data[0]);
+
+ return 1;
+}
+
+static int das08_counter_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = insn->chanspec;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SET_COUNTER_MODE:
+ i8254_set_mode(&devpriv->i8254, chan, data[1]);
+ break;
+ case INSN_CONFIG_8254_READ_STATUS:
+ data[1] = i8254_read_status(&devpriv->i8254, chan);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 2;
+}
+
+static int das08_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static struct comedi_driver driver_das08 = {
+ driver_name: DRV_NAME,
+ module:THIS_MODULE,
+ attach:das08_attach,
+ detach:das08_common_detach,
+ board_name:&das08_boards[0].name,
+ num_names:sizeof(das08_boards) /
+ sizeof(struct das08_board_struct),
+ offset:sizeof(struct das08_board_struct),
+};
+
+int das08_common_attach(struct comedi_device * dev, unsigned long iobase)
+{
+ struct comedi_subdevice *s;
+ int ret;
+
+ // allocate ioports for non-pcmcia, non-pci boards
+ if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) {
+ printk(" iobase 0x%lx\n", iobase);
+ if (!request_region(iobase, thisboard->iosize, DRV_NAME)) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ }
+ dev->iobase = iobase;
+
+ dev->board_name = thisboard->name;
+
+ if ((ret = alloc_subdevices(dev, 6)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ /* ai */
+ if (thisboard->ai) {
+ s->type = COMEDI_SUBD_AI;
+ /* XXX some boards actually have differential inputs instead of single ended.
+ * The driver does nothing with arefs though, so it's no big deal. */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 8;
+ s->maxdata = (1 << thisboard->ai_nbits) - 1;
+ s->range_table = das08_ai_lranges[thisboard->ai_pg];
+ s->insn_read = thisboard->ai;
+ devpriv->pg_gainlist = das08_gainlists[thisboard->ai_pg];
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 1;
+ /* ao */
+ if (thisboard->ao) {
+ s->type = COMEDI_SUBD_AO;
+// XXX lacks read-back insn
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = (1 << thisboard->ao_nbits) - 1;
+ s->range_table = &range_bipolar5;
+ s->insn_write = thisboard->ao;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ /* di */
+ if (thisboard->di) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = (thisboard->di == das08_di_rbits) ? 3 : 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->di;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ /* do */
+ if (thisboard->do_) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = thisboard->do_nchan;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->do_;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 4;
+ /* 8255 */
+ if (thisboard->i8255_offset != 0) {
+ subdev_8255_init(dev, s, NULL, (unsigned long)(dev->iobase +
+ thisboard->i8255_offset));
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 5;
+ /* 8254 */
+ if (thisboard->i8254_offset != 0) {
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 0xFFFF;
+ s->insn_read = das08_counter_read;
+ s->insn_write = das08_counter_write;
+ s->insn_config = das08_counter_config;
+ /* Set-up the 8254 structure */
+ devpriv->i8254.channels = 3;
+ devpriv->i8254.logic2phys[0] = 0;
+ devpriv->i8254.logic2phys[1] = 1;
+ devpriv->i8254.logic2phys[2] = 2;
+ devpriv->i8254.iobase = iobase + thisboard->i8254_offset;
+ devpriv->i8254.mode[0] =
+ devpriv->i8254.mode[1] =
+ devpriv->i8254.mode[2] = I8254_MODE0 | I8254_BINARY;
+ i8254_initialize(&devpriv->i8254);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ return 0;
+}
+
+static int das08_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+#ifdef CONFIG_COMEDI_PCI
+ unsigned long pci_iobase = 0;
+ struct pci_dev *pdev;
+#endif
+
+ if ((ret = alloc_private(dev, sizeof(struct das08_private_struct))) < 0)
+ return ret;
+
+ printk("comedi%d: das08: ", dev->minor);
+ // deal with a pci board
+ if (thisboard->bustype == pci) {
+#ifdef CONFIG_COMEDI_PCI
+ if (it->options[0] || it->options[1]) {
+ printk("bus %i slot %i ",
+ it->options[0], it->options[1]);
+ }
+ printk("\n");
+ // find card
+ for (pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pdev != NULL;
+ pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) {
+ if (pdev->vendor == PCI_VENDOR_ID_COMPUTERBOARDS
+ && pdev->device == PCI_DEVICE_ID_PCIDAS08) {
+ if (it->options[0] || it->options[1]) {
+ if (pdev->bus->number == it->options[0]
+ && PCI_SLOT(pdev->devfn) ==
+ it->options[1]) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ if (!pdev) {
+ printk("No pci das08 cards found\n");
+ return -EIO;
+ }
+ devpriv->pdev = pdev;
+ // enable PCI device and reserve I/O spaces
+ if (comedi_pci_enable(pdev, DRV_NAME)) {
+ printk(" Error enabling PCI device and requesting regions\n");
+ return -EIO;
+ }
+ // read base addresses
+ pci_iobase = pci_resource_start(pdev, 1);
+ iobase = pci_resource_start(pdev, 2);
+ printk("pcibase 0x%lx iobase 0x%lx\n", pci_iobase, iobase);
+ devpriv->pci_iobase = pci_iobase;
+#if 0
+/* We could enable to pci-das08's interrupt here to make it possible
+ * to do timed input in this driver, but there is little point since
+ * conversions would have to be started by the interrupt handler
+ * so you might as well use comedi_rt_timer to emulate commands
+ */
+ /* set source of interrupt trigger to counter2 output */
+ outb(CNTRL_INTR | CNTRL_DIR, pci_iobase + CNTRL);
+ /* Enable local interrupt 1 and pci interrupt */
+ outw(INTR1_ENABLE | PCI_INTR_ENABLE, pci_iobase + INTCSR);
+#endif
+#else /* CONFIG_COMEDI_PCI */
+ printk("this driver has not been built with PCI support.\n");
+ return -EINVAL;
+#endif /* CONFIG_COMEDI_PCI */
+ } else {
+ iobase = it->options[0];
+ }
+ printk("\n");
+
+ return das08_common_attach(dev, iobase);
+}
+
+int das08_common_detach(struct comedi_device * dev)
+{
+ printk(KERN_INFO "comedi%d: das08: remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+ // deallocate ioports for non-pcmcia, non-pci boards
+ if ((thisboard->bustype != pcmcia) && (thisboard->bustype != pci)) {
+ if (dev->iobase)
+ release_region(dev->iobase, thisboard->iosize);
+ }
+
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv) {
+ if (devpriv->pdev) {
+ if (devpriv->pci_iobase) {
+ comedi_pci_disable(devpriv->pdev);
+ }
+ pci_dev_put(devpriv->pdev);
+ }
+ }
+#endif
+
+ return 0;
+}
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_das08, das08_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_das08);
+#endif
+
+EXPORT_SYMBOL_GPL(das08_common_attach);
+EXPORT_SYMBOL_GPL(das08_common_detach);
+#ifdef CONFIG_COMEDI_PCMCIA
+EXPORT_SYMBOL_GPL(das08_cs_boards);
+#endif
diff --git a/drivers/staging/comedi/drivers/das08.h b/drivers/staging/comedi/drivers/das08.h
new file mode 100644
index 00000000000..69089ce690f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08.h
@@ -0,0 +1,78 @@
+/*
+ das08.h
+
+ Header for das08.c and das08_cs.c
+
+ Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _DAS08_H
+#define _DAS08_H
+
+enum das08_bustype { isa, pci, pcmcia, pc104 };
+// different ways ai data is encoded in first two registers
+enum das08_ai_encoding { das08_encode12, das08_encode16, das08_pcm_encode12 };
+enum das08_lrange { das08_pg_none, das08_bipolar5, das08_pgh, das08_pgl,
+ das08_pgm };
+
+struct das08_board_struct {
+ const char *name;
+ unsigned int id; // id for pci/pcmcia boards
+ enum das08_bustype bustype;
+ void *ai;
+ unsigned int ai_nbits;
+ enum das08_lrange ai_pg;
+ enum das08_ai_encoding ai_encoding;
+ void *ao;
+ unsigned int ao_nbits;
+ void *di;
+ void *do_;
+ unsigned int do_nchan;
+ unsigned int i8255_offset;
+ unsigned int i8254_offset;
+ unsigned int iosize; // number of ioports used
+};
+
+struct i8254_struct {
+ int channels; // available channels. Some could be used internally.
+ int logic2phys[3]; // to know which physical channel is.
+ int mode[3]; // the index is the real counter.
+ unsigned int iobase;
+};
+
+#define I8254_CNT0 0
+#define I8254_CNT1 1
+#define I8254_CNT2 2
+#define I8254_CTRL 3
+
+struct das08_private_struct {
+ unsigned int do_mux_bits; // bits for do/mux register on boards without seperate do register
+ unsigned int do_bits; // bits for do register on boards with register dedicated to digital out only
+ const unsigned int *pg_gainlist;
+ struct pci_dev *pdev; // struct for pci-das08
+ unsigned int pci_iobase; // additional base address for pci-das08
+ struct i8254_struct i8254;
+};
+
+#define NUM_DAS08_CS_BOARDS 2
+extern struct das08_board_struct das08_cs_boards[NUM_DAS08_CS_BOARDS];
+
+int das08_common_attach(struct comedi_device * dev, unsigned long iobase);
+int das08_common_detach(struct comedi_device * dev);
+
+#endif /* _DAS08_H */
diff --git a/drivers/staging/comedi/drivers/das08_cs.c b/drivers/staging/comedi/drivers/das08_cs.c
new file mode 100644
index 00000000000..be6c88788c4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das08_cs.c
@@ -0,0 +1,488 @@
+/*
+ comedi/drivers/das08_cs.c
+ DAS08 driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2001,2002,2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*****************************************************************
+
+*/
+/*
+Driver: das08_cs
+Description: DAS-08 PCMCIA boards
+Author: Warren Jasper, ds, Frank Hess
+Devices: [ComputerBoards] PCM-DAS08 (pcm-das08)
+Status: works
+
+This is the PCMCIA-specific support split off from the
+das08 driver.
+
+Options (for pcm-das08):
+ NONE
+
+Command support does not exist, but could be added for this board.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/pci.h>
+
+#include "das08.h"
+
+// pcmcia includes
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *cur_dev = NULL;
+
+#define thisboard ((const struct das08_board_struct *)dev->board_ptr)
+
+static int das08_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static struct comedi_driver driver_das08_cs = {
+ driver_name:"das08_cs",
+ module:THIS_MODULE,
+ attach:das08_cs_attach,
+ detach:das08_common_detach,
+ board_name:&das08_cs_boards[0].name,
+ num_names:sizeof(das08_cs_boards) /
+ sizeof(struct das08_board_struct),
+ offset:sizeof(struct das08_board_struct),
+};
+
+static int das08_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ struct pcmcia_device *link = cur_dev; // XXX hack
+
+ if ((ret = alloc_private(dev, sizeof(struct das08_private_struct))) < 0)
+ return ret;
+
+ printk("comedi%d: das08_cs: ", dev->minor);
+ // deal with a pci board
+
+ if (thisboard->bustype == pcmcia) {
+ if (link == NULL) {
+ printk(" no pcmcia cards found\n");
+ return -EIO;
+ }
+ iobase = link->io.BasePort1;
+ } else {
+ printk(" bug! board does not have PCMCIA bustype\n");
+ return -EINVAL;
+ }
+
+ printk("\n");
+
+ return das08_common_attach(dev, iobase);
+}
+
+/*======================================================================
+
+ The following pcmcia code for the pcm-das08 is adapted from the
+ dummy_cs.c driver of the Linux PCMCIA Card Services package.
+
+ The initial developer of the original code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+======================================================================*/
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static const char *version =
+ "das08.c pcmcia code (Frank Hess), modified from dummy_cs.c 1.31 2001/08/24 12:13:13 (David Hinds)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+static void das08_pcmcia_config(struct pcmcia_device *link);
+static void das08_pcmcia_release(struct pcmcia_device *link);
+static int das08_pcmcia_suspend(struct pcmcia_device *p_dev);
+static int das08_pcmcia_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int das08_pcmcia_attach(struct pcmcia_device *);
+static void das08_pcmcia_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "pcm-das08";
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+};
+
+/*======================================================================
+
+ das08_pcmcia_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int das08_pcmcia_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+
+ DEBUG(0, "das08_pcmcia_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ cur_dev = link;
+
+ das08_pcmcia_config(link);
+
+ return 0;
+} /* das08_pcmcia_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void das08_pcmcia_detach(struct pcmcia_device *link)
+{
+
+ DEBUG(0, "das08_pcmcia_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((struct local_info_t *) link->priv)->stop = 1;
+ das08_pcmcia_release(link);
+ }
+
+ /* This points to the parent struct local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* das08_pcmcia_detach */
+
+/*======================================================================
+
+ das08_pcmcia_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void das08_pcmcia_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_fn, last_ret;
+ u_char buf[64];
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ DEBUG(0, "das08_pcmcia_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = GetTupleData;
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+ goto cs_failed;
+ last_fn = ParseTuple;
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
+ goto cs_failed;
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ last_fn = GetFirstTuple;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0)
+ goto next_entry;
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+/* if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+*/
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io) != 0)
+ goto next_entry;
+ }
+
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ last_fn = GetNextTuple;
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0)
+ goto cs_failed;
+ }
+
+ if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+ last_fn = RequestIRQ;
+ if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0)
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ last_fn = RequestConfiguration;
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0)
+ goto cs_failed;
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "pcm-das08");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %u", link->irq.AssignedIRQ);
+ if (link->io.NumPorts1)
+ printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+ link->io.BasePort1 + link->io.NumPorts1 - 1);
+ if (link->io.NumPorts2)
+ printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+ link->io.BasePort2 + link->io.NumPorts2 - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ cs_error(link, last_fn, last_ret);
+ das08_pcmcia_release(link);
+
+} /* das08_pcmcia_config */
+
+/*======================================================================
+
+ After a card is removed, das08_pcmcia_release() will unregister the
+ device, and release the PCMCIA configuration. If the device is
+ still open, this will be postponed until it is closed.
+
+======================================================================*/
+
+static void das08_pcmcia_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "das08_pcmcia_release(0x%p)\n", link);
+ pcmcia_disable_device(link);
+} /* das08_pcmcia_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int das08_pcmcia_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+
+ return 0;
+} /* das08_pcmcia_suspend */
+
+static int das08_pcmcia_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* das08_pcmcia_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id das08_cs_id_table[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x01c5, 0x4001),
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, das08_cs_id_table);
+
+struct pcmcia_driver das08_cs_driver = {
+ .probe = das08_pcmcia_attach,
+ .remove = das08_pcmcia_detach,
+ .suspend = das08_pcmcia_suspend,
+ .resume = das08_pcmcia_resume,
+ .id_table = das08_cs_id_table,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_das08_pcmcia_cs(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&das08_cs_driver);
+ return 0;
+}
+
+static void __exit exit_das08_pcmcia_cs(void)
+{
+ DEBUG(0, "das08_pcmcia_cs: unloading\n");
+ pcmcia_unregister_driver(&das08_cs_driver);
+}
+
+static int __init das08_cs_init_module(void)
+{
+ int ret;
+
+ ret = init_das08_pcmcia_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_das08_cs);
+}
+
+static void __exit das08_cs_exit_module(void)
+{
+ exit_das08_pcmcia_cs();
+ comedi_driver_unregister(&driver_das08_cs);
+}
+
+MODULE_LICENSE("GPL");
+module_init(das08_cs_init_module);
+module_exit(das08_cs_exit_module);
diff --git a/drivers/staging/comedi/drivers/das16.c b/drivers/staging/comedi/drivers/das16.c
new file mode 100644
index 00000000000..6b6b042099d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das16.c
@@ -0,0 +1,1730 @@
+/*
+ comedi/drivers/das16.c
+ DAS16 driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
+ Copyright (C) 2001,2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das16
+Description: DAS16 compatible boards
+Author: Sam Moore, Warren Jasper, ds, Chris Baugher, Frank Hess, Roman Fietze
+Devices: [Keithley Metrabyte] DAS-16 (das-16), DAS-16G (das-16g),
+ DAS-16F (das-16f), DAS-1201 (das-1201), DAS-1202 (das-1202),
+ DAS-1401 (das-1401), DAS-1402 (das-1402), DAS-1601 (das-1601),
+ DAS-1602 (das-1602),
+ [ComputerBoards] PC104-DAS16/JR (pc104-das16jr),
+ PC104-DAS16JR/16 (pc104-das16jr/16),
+ CIO-DAS16JR/16 (cio-das16jr/16),
+ CIO-DAS16/JR (cio-das16/jr), CIO-DAS1401/12 (cio-das1401/12),
+ CIO-DAS1402/12 (cio-das1402/12), CIO-DAS1402/16 (cio-das1402/16),
+ CIO-DAS1601/12 (cio-das1601/12), CIO-DAS1602/12 (cio-das1602/12),
+ CIO-DAS1602/16 (cio-das1602/16), CIO-DAS16/330 (cio-das16/330)
+Status: works
+Updated: 2003-10-12
+
+A rewrite of the das16 and das1600 drivers.
+Options:
+ [0] - base io address
+ [1] - irq (does nothing, irq is not used anymore)
+ [2] - dma (optional, required for comedi_command support)
+ [3] - master clock speed in MHz (optional, 1 or 10, ignored if
+ board can probe clock, defaults to 1)
+ [4] - analog input range lowest voltage in microvolts (optional,
+ only useful if your board does not have software
+ programmable gain)
+ [5] - analog input range highest voltage in microvolts (optional,
+ only useful if board does not have software programmable
+ gain)
+ [6] - analog output range lowest voltage in microvolts (optional)
+ [7] - analog output range highest voltage in microvolts (optional)
+ [8] - use timer mode for DMA. Timer mode is needed e.g. for
+ buggy DMA controllers in NS CS5530A (Geode Companion), and for
+ 'jr' cards that lack a hardware fifo. This option is no
+ longer needed, since timer mode is _always_ used.
+
+Passing a zero for an option is the same as leaving it unspecified.
+
+*/
+/*
+
+Testing and debugging help provided by Daniel Koch.
+
+Keithley Manuals:
+ 2309.PDF (das16)
+ 4919.PDF (das1400, 1600)
+ 4922.PDF (das-1400)
+ 4923.PDF (das1200, 1400, 1600)
+
+Computer boards manuals also available from their website www.measurementcomputing.com
+
+*/
+
+#include <linux/pci.h>
+#include <asm/dma.h>
+#include "../comedidev.h"
+
+#include "8253.h"
+#include "8255.h"
+#include "comedi_fc.h"
+
+#undef DEBUG
+//#define DEBUG
+
+#ifdef DEBUG
+#define DEBUG_PRINT(format, args...) rt_printk("das16: " format, ## args)
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define DAS16_SIZE 20 // number of ioports
+#define DAS16_DMA_SIZE 0xff00 // size in bytes of allocated dma buffer
+
+/*
+ cio-das16.pdf
+
+ "das16"
+ "das16/f"
+
+ 0 a/d bits 0-3 start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b reserved reserved
+ cdef 8254
+ 0123 8255
+
+*/
+
+/*
+ cio-das16jr.pdf
+
+ "das16jr"
+
+ 0 a/d bits 0-3 start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4567 unused unused
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b gain status gain control
+ cdef 8254
+
+*/
+
+/*
+ cio-das16jr_16.pdf
+
+ "das16jr_16"
+
+ 0 a/d bits 0-7 start 16 bit
+ 1 a/d bits 8-15 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4567 unused unused
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b gain status gain control
+ cdef 8254
+
+*/
+/*
+ cio-das160x-1x.pdf
+
+ "das1601/12"
+ "das1602/12"
+ "das1602/16"
+
+ 0 a/d bits 0-3 start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 mux read mux set
+ 3 di 4 bit do 4 bit
+ 4 unused ao0_lsb
+ 5 unused ao0_msb
+ 6 unused ao1_lsb
+ 7 unused ao1_msb
+ 8 status eoc uni/bip interrupt reset
+ 9 dma, int, trig ctrl set dma, int
+ a pacer control unused
+ b gain status gain control
+ cdef 8254
+ 400 8255
+ 404 unused conversion enable
+ 405 unused burst enable
+ 406 unused das1600 enable
+ 407 status
+
+*/
+
+static const int sample_size = 2; // size in bytes of a sample from board
+
+#define DAS16_TRIG 0
+#define DAS16_AI_LSB 0
+#define DAS16_AI_MSB 1
+#define DAS16_MUX 2
+#define DAS16_DIO 3
+#define DAS16_AO_LSB(x) ((x)?6:4)
+#define DAS16_AO_MSB(x) ((x)?7:5)
+#define DAS16_STATUS 8
+#define BUSY (1<<7)
+#define UNIPOLAR (1<<6)
+#define DAS16_MUXBIT (1<<5)
+#define DAS16_INT (1<<4)
+#define DAS16_CONTROL 9
+#define DAS16_INTE (1<<7)
+#define DAS16_IRQ(x) (((x) & 0x7) << 4)
+#define DMA_ENABLE (1<<2)
+#define PACING_MASK 0x3
+#define INT_PACER 0x03
+#define EXT_PACER 0x02
+#define DAS16_SOFT 0x00
+#define DAS16_PACER 0x0A
+#define DAS16_CTR0 (1<<1)
+#define DAS16_TRIG0 (1<<0)
+#define BURST_LEN_BITS(x) (((x) & 0xf) << 4)
+#define DAS16_GAIN 0x0B
+#define DAS16_CNTR0_DATA 0x0C
+#define DAS16_CNTR1_DATA 0x0D
+#define DAS16_CNTR2_DATA 0x0E
+#define DAS16_CNTR_CONTROL 0x0F
+#define DAS16_TERM_CNT 0x00
+#define DAS16_ONE_SHOT 0x02
+#define DAS16_RATE_GEN 0x04
+#define DAS16_CNTR_LSB_MSB 0x30
+#define DAS16_CNTR0 0x00
+#define DAS16_CNTR1 0x40
+#define DAS16_CNTR2 0x80
+
+#define DAS1600_CONV 0x404
+#define DAS1600_CONV_DISABLE 0x40
+#define DAS1600_BURST 0x405
+#define DAS1600_BURST_VAL 0x40
+#define DAS1600_ENABLE 0x406
+#define DAS1600_ENABLE_VAL 0x40
+#define DAS1600_STATUS_B 0x407
+#define DAS1600_BME 0x40
+#define DAS1600_ME 0x20
+#define DAS1600_CD 0x10
+#define DAS1600_WS 0x02
+#define DAS1600_CLK_10MHZ 0x01
+
+static const struct comedi_lrange range_das1x01_bip = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_das1x01_unip = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_das1x02_bip = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_das1x02_unip = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_das16jr = { 9, {
+ // also used by 16/330
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_das16jr_16 = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+
+static const int das16jr_gainlist[] = { 8, 0, 1, 2, 3, 4, 5, 6, 7 };
+static const int das16jr_16_gainlist[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+static const int das1600_gainlist[] = { 0, 1, 2, 3 };
+enum {
+ das16_pg_none = 0,
+ das16_pg_16jr,
+ das16_pg_16jr_16,
+ das16_pg_1601,
+ das16_pg_1602,
+};
+static const int *const das16_gainlists[] = {
+ NULL,
+ das16jr_gainlist,
+ das16jr_16_gainlist,
+ das1600_gainlist,
+ das1600_gainlist,
+};
+static const struct comedi_lrange *const das16_ai_uni_lranges[] = {
+ &range_unknown,
+ &range_das16jr,
+ &range_das16jr_16,
+ &range_das1x01_unip,
+ &range_das1x02_unip,
+};
+static const struct comedi_lrange *const das16_ai_bip_lranges[] = {
+ &range_unknown,
+ &range_das16jr,
+ &range_das16jr_16,
+ &range_das1x01_bip,
+ &range_das1x02_bip,
+};
+
+struct munge_info {
+ uint8_t byte;
+ unsigned have_byte:1;
+};
+
+static int das16_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int das16_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das16_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das16_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *array, unsigned int num_bytes, unsigned int start_chan_index);
+
+static void das16_reset(struct comedi_device * dev);
+static irqreturn_t das16_dma_interrupt(int irq, void *d PT_REGS_ARG);
+static void das16_timer_interrupt(unsigned long arg);
+static void das16_interrupt(struct comedi_device * dev);
+
+static unsigned int das16_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int flags);
+static int das1600_mode_detect(struct comedi_device * dev);
+static unsigned int das16_suggest_transfer_size(struct comedi_device * dev,
+ struct comedi_cmd cmd);
+
+static void reg_dump(struct comedi_device * dev);
+
+struct das16_board {
+ const char *name;
+ void *ai;
+ unsigned int ai_nbits;
+ unsigned int ai_speed; // max conversion speed in nanosec
+ unsigned int ai_pg;
+ void *ao;
+ unsigned int ao_nbits;
+ void *di;
+ void *do_;
+
+ unsigned int i8255_offset;
+ unsigned int i8254_offset;
+
+ unsigned int size;
+ unsigned int id;
+};
+
+static const struct das16_board das16_boards[] = {
+ {
+ name: "das-16",
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:15000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x00,
+ },
+ {
+ name: "das-16g",
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:15000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x00,
+ },
+ {
+ name: "das-16f",
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:8500,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x00,
+ },
+ {
+ name: "cio-das16", // cio-das16.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:20000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x80,
+ },
+ {
+ name: "cio-das16/f", // das16.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_none,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x10,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0x80,
+ },
+ {
+ name: "cio-das16/jr", // cio-das16jr.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:7692,
+ ai_pg: das16_pg_16jr,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "pc104-das16jr", // pc104-das16jr_xx.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:3300,
+ ai_pg: das16_pg_16jr,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "cio-das16jr/16", // cio-das16jr_16.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_16jr_16,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "pc104-das16jr/16", // pc104-das16jr_xx.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_16jr_16,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x10,
+ id: 0x00,
+ },
+ {
+ name: "das-1201", // 4924.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:20000,
+ ai_pg: das16_pg_none,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0x20,
+ },
+ {
+ name: "das-1202", // 4924.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_none,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0x20,
+ },
+ {
+ name: "das-1401", // 4919.pdf and 4922.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1601,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0 // 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0
+ },
+ {
+ name: "das-1402", // 4919.pdf and 4922.pdf (keithley user's manual)
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0 // 4919.pdf says id bits are 0xe0, 4922.pdf says 0xc0
+ },
+ {
+ name: "das-1601", // 4919.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1601,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "das-1602", // 4919.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1401/12", // cio-das1400_series.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:6250,
+ ai_pg: das16_pg_1601,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1402/12", // cio-das1400_series.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:6250,
+ ai_pg: das16_pg_1602,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1402/16", // cio-das1400_series.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1601/12", // cio-das160x-1x.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:6250,
+ ai_pg: das16_pg_1601,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1602/12", // cio-das160x-1x.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das1602/16", // cio-das160x-1x.pdf
+ ai: das16_ai_rinsn,
+ ai_nbits:16,
+ ai_speed:10000,
+ ai_pg: das16_pg_1602,
+ ao: das16_ao_winsn,
+ ao_nbits:12,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0x400,
+ i8254_offset:0x0c,
+ size: 0x408,
+ id: 0xc0},
+ {
+ name: "cio-das16/330", // ?
+ ai: das16_ai_rinsn,
+ ai_nbits:12,
+ ai_speed:3030,
+ ai_pg: das16_pg_16jr,
+ ao: NULL,
+ di: das16_di_rbits,
+ do_: das16_do_wbits,
+ i8255_offset:0,
+ i8254_offset:0x0c,
+ size: 0x14,
+ id: 0xf0},
+#if 0
+ {
+ name: "das16/330i", // ?
+ },
+ {
+ name: "das16/jr/ctr5", // ?
+ },
+ {
+ name: "cio-das16/m1/16", // cio-das16_m1_16.pdf, this board is a bit quirky, no dma
+ },
+#endif
+};
+
+#define n_das16_boards ((sizeof(das16_boards))/(sizeof(struct das16_board)))
+
+static int das16_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16 = {
+ driver_name:"das16",
+ module:THIS_MODULE,
+ attach:das16_attach,
+ detach:das16_detach,
+ board_name:&das16_boards[0].name,
+ num_names:n_das16_boards,
+ offset:sizeof(das16_boards[0]),
+};
+
+#define DAS16_TIMEOUT 1000
+
+/* Period for timer interrupt in jiffies. It's a function
+ * to deal with possibility of dynamic HZ patches */
+static inline int timer_period(void)
+{
+ return HZ / 20;
+}
+struct das16_private_struct {
+ unsigned int ai_unipolar; // unipolar flag
+ unsigned int ai_singleended; // single ended flag
+ unsigned int clockbase; // master clock speed in ns
+ volatile unsigned int control_state; // dma, interrupt and trigger control bits
+ volatile unsigned long adc_byte_count; // number of bytes remaining
+ unsigned int divisor1; // divisor dividing master clock to get conversion frequency
+ unsigned int divisor2; // divisor dividing master clock to get conversion frequency
+ unsigned int dma_chan; // dma channel
+ uint16_t *dma_buffer[2];
+ dma_addr_t dma_buffer_addr[2];
+ unsigned int current_buffer;
+ volatile unsigned int dma_transfer_size; // target number of bytes to transfer per dma shot
+ // user-defined analog input and output ranges defined from config options
+ struct comedi_lrange *user_ai_range_table;
+ struct comedi_lrange *user_ao_range_table;
+
+ struct timer_list timer; // for timed interrupt
+ volatile short timer_running;
+ volatile short timer_mode; // true if using timer mode
+};
+#define devpriv ((struct das16_private_struct *)(dev->private))
+#define thisboard ((struct das16_board *)(dev->board_ptr))
+
+static int das16_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0, tmp;
+ int gain, start_chan, i;
+ int mask;
+
+ /* make sure triggers are valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ mask = TRIG_FOLLOW;
+ // if board supports burst mode
+ if (thisboard->size > 0x400)
+ mask |= TRIG_TIMER | TRIG_EXT;
+ cmd->scan_begin_src &= mask;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ mask = TRIG_TIMER | TRIG_EXT;
+ // if board supports burst mode
+ if (thisboard->size > 0x400)
+ mask |= TRIG_NOW;
+ cmd->convert_src &= mask;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ // make sure scan_begin_src and convert_src dont conflict
+ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW && cmd->convert_src != TRIG_NOW)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ // check against maximum frequency
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg <
+ thisboard->ai_speed * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ thisboard->ai_speed * cmd->chanlist_len;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+ if (err)
+ return 3;
+
+ // step 4: fix up arguments
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ unsigned int tmp = cmd->scan_begin_arg;
+ // set divisors, correct timing arguments
+ i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->scan_begin_arg), cmd->flags & TRIG_ROUND_MASK);
+ err += (tmp != cmd->scan_begin_arg);
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ unsigned int tmp = cmd->convert_arg;
+ // set divisors, correct timing arguments
+ i8253_cascade_ns_to_timer_2div(devpriv->clockbase,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ err += (tmp != cmd->convert_arg);
+ }
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ start_chan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (start_chan + i) % s->n_chan) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int das16_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int byte;
+ unsigned long flags;
+ int range;
+
+ if (devpriv->dma_chan == 0 || (dev->irq == 0
+ && devpriv->timer_mode == 0)) {
+ comedi_error(dev,
+ "irq (or use of 'timer mode') dma required to execute comedi_cmd");
+ return -1;
+ }
+ if (cmd->flags & TRIG_RT) {
+ comedi_error(dev,
+ "isa dma transfers cannot be performed with TRIG_RT, aborting");
+ return -1;
+ }
+
+ devpriv->adc_byte_count =
+ cmd->stop_arg * cmd->chanlist_len * sizeof(uint16_t);
+
+ // disable conversions for das1600 mode
+ if (thisboard->size > 0x400) {
+ outb(DAS1600_CONV_DISABLE, dev->iobase + DAS1600_CONV);
+ }
+ // set scan limits
+ byte = CR_CHAN(cmd->chanlist[0]);
+ byte |= CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]) << 4;
+ outb(byte, dev->iobase + DAS16_MUX);
+
+ /* set gain (this is also burst rate register but according to
+ * computer boards manual, burst rate does nothing, even on keithley cards) */
+ if (thisboard->ai_pg != das16_pg_none) {
+ range = CR_RANGE(cmd->chanlist[0]);
+ outb((das16_gainlists[thisboard->ai_pg])[range],
+ dev->iobase + DAS16_GAIN);
+ }
+
+ /* set counter mode and counts */
+ cmd->convert_arg =
+ das16_set_pacer(dev, cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ DEBUG_PRINT("pacer period: %d ns\n", cmd->convert_arg);
+
+ /* enable counters */
+ byte = 0;
+ /* Enable burst mode if appropriate. */
+ if (thisboard->size > 0x400) {
+ if (cmd->convert_src == TRIG_NOW) {
+ outb(DAS1600_BURST_VAL, dev->iobase + DAS1600_BURST);
+ // set burst length
+ byte |= BURST_LEN_BITS(cmd->chanlist_len - 1);
+ } else {
+ outb(0, dev->iobase + DAS1600_BURST);
+ }
+ }
+ outb(byte, dev->iobase + DAS16_PACER);
+
+ // set up dma transfer
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma_chan);
+ devpriv->current_buffer = 0;
+ set_dma_addr(devpriv->dma_chan,
+ devpriv->dma_buffer_addr[devpriv->current_buffer]);
+ // set appropriate size of transfer
+ devpriv->dma_transfer_size = das16_suggest_transfer_size(dev, *cmd);
+ set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_chan);
+ release_dma_lock(flags);
+
+ // set up interrupt
+ if (devpriv->timer_mode) {
+ devpriv->timer_running = 1;
+ devpriv->timer.expires = jiffies + timer_period();
+ add_timer(&devpriv->timer);
+ devpriv->control_state &= ~DAS16_INTE;
+ } else {
+ /* clear interrupt bit */
+ outb(0x00, dev->iobase + DAS16_STATUS);
+ /* enable interrupts */
+ devpriv->control_state |= DAS16_INTE;
+ }
+ devpriv->control_state |= DMA_ENABLE;
+ devpriv->control_state &= ~PACING_MASK;
+ if (cmd->convert_src == TRIG_EXT)
+ devpriv->control_state |= EXT_PACER;
+ else
+ devpriv->control_state |= INT_PACER;
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+ /* Enable conversions if using das1600 mode */
+ if (thisboard->size > 0x400) {
+ outb(0, dev->iobase + DAS1600_CONV);
+ }
+
+ return 0;
+}
+
+static int das16_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ /* disable interrupts, dma and pacer clocked conversions */
+ devpriv->control_state &= ~DAS16_INTE & ~PACING_MASK & ~DMA_ENABLE;
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+ if (devpriv->dma_chan)
+ disable_dma(devpriv->dma_chan);
+
+ // disable SW timer
+ if (devpriv->timer_mode && devpriv->timer_running) {
+ devpriv->timer_running = 0;
+ del_timer(&devpriv->timer);
+ }
+
+ /* disable burst mode */
+ if (thisboard->size > 0x400) {
+ outb(0, dev->iobase + DAS1600_BURST);
+ }
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return 0;
+}
+
+static void das16_reset(struct comedi_device * dev)
+{
+ outb(0, dev->iobase + DAS16_STATUS);
+ outb(0, dev->iobase + DAS16_CONTROL);
+ outb(0, dev->iobase + DAS16_PACER);
+ outb(0, dev->iobase + DAS16_CNTR_CONTROL);
+}
+
+static int das16_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int range;
+ int chan;
+ int msb, lsb;
+
+ // disable interrupts and pacing
+ devpriv->control_state &= ~DAS16_INTE & ~DMA_ENABLE & ~PACING_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+ /* set multiplexer */
+ chan = CR_CHAN(insn->chanspec);
+ chan |= CR_CHAN(insn->chanspec) << 4;
+ outb(chan, dev->iobase + DAS16_MUX);
+
+ /* set gain */
+ if (thisboard->ai_pg != das16_pg_none) {
+ range = CR_RANGE(insn->chanspec);
+ outb((das16_gainlists[thisboard->ai_pg])[range],
+ dev->iobase + DAS16_GAIN);
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outb_p(0, dev->iobase + DAS16_TRIG);
+
+ for (i = 0; i < DAS16_TIMEOUT; i++) {
+ if (!(inb(dev->iobase + DAS16_STATUS) & BUSY))
+ break;
+ }
+ if (i == DAS16_TIMEOUT) {
+ rt_printk("das16: timeout\n");
+ return -ETIME;
+ }
+ msb = inb(dev->iobase + DAS16_AI_MSB);
+ lsb = inb(dev->iobase + DAS16_AI_LSB);
+ if (thisboard->ai_nbits == 12) {
+ data[n] = ((lsb >> 4) & 0xf) | (msb << 4);
+ } else {
+ data[n] = lsb | (msb << 8);
+ }
+ }
+
+ return n;
+}
+
+static int das16_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = inb(dev->iobase + DAS16_DIO) & 0xf;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int das16_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int wbits;
+
+ // only set bits that have been masked
+ data[0] &= 0xf;
+ wbits = s->state;
+ // zero bits that have been masked
+ wbits &= ~data[0];
+ // set masked bits
+ wbits |= data[0] & data[1];
+ s->state = wbits;
+ data[1] = wbits;
+
+ outb(s->state, dev->iobase + DAS16_DIO);
+
+ return 2;
+}
+
+static int das16_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int lsb, msb;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ if (thisboard->ao_nbits == 12) {
+ lsb = (data[i] << 4) & 0xff;
+ msb = (data[i] >> 4) & 0xff;
+ } else {
+ lsb = data[i] & 0xff;
+ msb = (data[i] >> 8) & 0xff;
+ }
+ outb(lsb, dev->iobase + DAS16_AO_LSB(chan));
+ outb(msb, dev->iobase + DAS16_AO_MSB(chan));
+ }
+
+ return i;
+}
+
+static irqreturn_t das16_dma_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int status;
+ struct comedi_device *dev = d;
+
+ status = inb(dev->iobase + DAS16_STATUS);
+
+ if ((status & DAS16_INT) == 0) {
+ DEBUG_PRINT("spurious interrupt\n");
+ return IRQ_NONE;
+ }
+
+ /* clear interrupt */
+ outb(0x00, dev->iobase + DAS16_STATUS);
+ das16_interrupt(dev);
+ return IRQ_HANDLED;
+}
+
+static void das16_timer_interrupt(unsigned long arg)
+{
+ struct comedi_device *dev = (struct comedi_device *) arg;
+
+ das16_interrupt(dev);
+
+ if (devpriv->timer_running)
+ mod_timer(&devpriv->timer, jiffies + timer_period());
+}
+
+/* the pc104-das16jr (at least) has problems if the dma
+ transfer is interrupted in the middle of transferring
+ a 16 bit sample, so this function takes care to get
+ an even transfer count after disabling dma
+ channel.
+*/
+static int disable_dma_on_even(struct comedi_device * dev)
+{
+ int residue;
+ int i;
+ static const int disable_limit = 100;
+ static const int enable_timeout = 100;
+ disable_dma(devpriv->dma_chan);
+ residue = get_dma_residue(devpriv->dma_chan);
+ for (i = 0; i < disable_limit && (residue % 2); ++i) {
+ int j;
+ enable_dma(devpriv->dma_chan);
+ for (j = 0; j < enable_timeout; ++j) {
+ int new_residue;
+ comedi_udelay(2);
+ new_residue = get_dma_residue(devpriv->dma_chan);
+ if (new_residue != residue)
+ break;
+ }
+ disable_dma(devpriv->dma_chan);
+ residue = get_dma_residue(devpriv->dma_chan);
+ }
+ if (i == disable_limit) {
+ comedi_error(dev,
+ "failed to get an even dma transfer, could be trouble.");
+ }
+ return residue;
+}
+
+static void das16_interrupt(struct comedi_device * dev)
+{
+ unsigned long dma_flags, spin_flags;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ int num_bytes, residue;
+ int buffer_index;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return;
+ }
+ // initialize async here to make sure it is not NULL
+ async = s->async;
+ cmd = &async->cmd;
+
+ if (devpriv->dma_chan == 0) {
+ comedi_error(dev, "interrupt with no dma channel?");
+ return;
+ }
+
+ comedi_spin_lock_irqsave(&dev->spinlock, spin_flags);
+ if ((devpriv->control_state & DMA_ENABLE) == 0) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, spin_flags);
+ DEBUG_PRINT("interrupt while dma disabled?\n");
+ return;
+ }
+
+ dma_flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma_chan);
+ residue = disable_dma_on_even(dev);
+
+ // figure out how many points to read
+ if (residue > devpriv->dma_transfer_size) {
+ comedi_error(dev, "residue > transfer size!\n");
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ num_bytes = 0;
+ } else
+ num_bytes = devpriv->dma_transfer_size - residue;
+
+ if (cmd->stop_src == TRIG_COUNT && num_bytes >= devpriv->adc_byte_count) {
+ num_bytes = devpriv->adc_byte_count;
+ async->events |= COMEDI_CB_EOA;
+ }
+
+ buffer_index = devpriv->current_buffer;
+ devpriv->current_buffer = (devpriv->current_buffer + 1) % 2;
+ devpriv->adc_byte_count -= num_bytes;
+
+ // figure out how many bytes for next transfer
+ if (cmd->stop_src == TRIG_COUNT && devpriv->timer_mode == 0 &&
+ devpriv->dma_transfer_size > devpriv->adc_byte_count)
+ devpriv->dma_transfer_size = devpriv->adc_byte_count;
+
+ // re-enable dma
+ if ((async->events & COMEDI_CB_EOA) == 0) {
+ set_dma_addr(devpriv->dma_chan,
+ devpriv->dma_buffer_addr[devpriv->current_buffer]);
+ set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_chan);
+ /* reenable conversions for das1600 mode, (stupid hardware) */
+ if (thisboard->size > 0x400 && devpriv->timer_mode == 0) {
+ outb(0x00, dev->iobase + DAS1600_CONV);
+ }
+ }
+ release_dma_lock(dma_flags);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, spin_flags);
+
+ cfc_write_array_to_buffer(s,
+ devpriv->dma_buffer[buffer_index], num_bytes);
+
+ cfc_handle_events(dev, s);
+}
+
+static unsigned int das16_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int rounding_flags)
+{
+ i8253_cascade_ns_to_timer_2div(devpriv->clockbase, &(devpriv->divisor1),
+ &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 1, devpriv->divisor1, 2);
+ i8254_load(dev->iobase + DAS16_CNTR0_DATA, 0, 2, devpriv->divisor2, 2);
+
+ return ns;
+}
+
+static void reg_dump(struct comedi_device * dev)
+{
+ DEBUG_PRINT("********DAS1600 REGISTER DUMP********\n");
+ DEBUG_PRINT("DAS16_MUX: %x\n", inb(dev->iobase + DAS16_MUX));
+ DEBUG_PRINT("DAS16_DIO: %x\n", inb(dev->iobase + DAS16_DIO));
+ DEBUG_PRINT("DAS16_STATUS: %x\n", inb(dev->iobase + DAS16_STATUS));
+ DEBUG_PRINT("DAS16_CONTROL: %x\n", inb(dev->iobase + DAS16_CONTROL));
+ DEBUG_PRINT("DAS16_PACER: %x\n", inb(dev->iobase + DAS16_PACER));
+ DEBUG_PRINT("DAS16_GAIN: %x\n", inb(dev->iobase + DAS16_GAIN));
+ DEBUG_PRINT("DAS16_CNTR_CONTROL: %x\n",
+ inb(dev->iobase + DAS16_CNTR_CONTROL));
+ DEBUG_PRINT("DAS1600_CONV: %x\n", inb(dev->iobase + DAS1600_CONV));
+ DEBUG_PRINT("DAS1600_BURST: %x\n", inb(dev->iobase + DAS1600_BURST));
+ DEBUG_PRINT("DAS1600_ENABLE: %x\n", inb(dev->iobase + DAS1600_ENABLE));
+ DEBUG_PRINT("DAS1600_STATUS_B: %x\n",
+ inb(dev->iobase + DAS1600_STATUS_B));
+}
+
+static int das16_probe(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int status;
+ int diobits;
+
+ /* status is available on all boards */
+
+ status = inb(dev->iobase + DAS16_STATUS);
+
+ if ((status & UNIPOLAR)) {
+ devpriv->ai_unipolar = 1;
+ } else {
+ devpriv->ai_unipolar = 0;
+ }
+
+ if ((status & DAS16_MUXBIT)) {
+ devpriv->ai_singleended = 1;
+ } else {
+ devpriv->ai_singleended = 0;
+ }
+
+ /* diobits indicates boards */
+
+ diobits = inb(dev->iobase + DAS16_DIO) & 0xf0;
+
+ printk(" id bits are 0x%02x\n", diobits);
+ if (thisboard->id != diobits) {
+ printk(" requested board's id bits are 0x%x (ignore)\n",
+ thisboard->id);
+ }
+
+ return 0;
+}
+
+static int das1600_mode_detect(struct comedi_device * dev)
+{
+ int status = 0;
+
+ status = inb(dev->iobase + DAS1600_STATUS_B);
+
+ if (status & DAS1600_CLK_10MHZ) {
+ devpriv->clockbase = 100;
+ printk(" 10MHz pacer clock\n");
+ } else {
+ devpriv->clockbase = 1000;
+ printk(" 1MHz pacer clock\n");
+ }
+
+ reg_dump(dev);
+
+ return 0;
+}
+
+/*
+ *
+ * Options list:
+ * 0 I/O base
+ * 1 IRQ
+ * 2 DMA
+ * 3 Clock speed (in MHz)
+ */
+
+static int das16_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ unsigned int irq;
+ unsigned long iobase;
+ unsigned int dma_chan;
+ int timer_mode;
+ unsigned long flags;
+ struct comedi_krange *user_ai_range, *user_ao_range;
+
+ iobase = it->options[0];
+#if 0
+ irq = it->options[1];
+ timer_mode = it->options[8];
+#endif
+ /* always use time_mode since using irq can drop samples while
+ * waiting for dma done interrupt (due to hardware limitations) */
+ irq = 0;
+ timer_mode = 1;
+ if (timer_mode)
+ irq = 0;
+
+ printk("comedi%d: das16:", dev->minor);
+
+ // check that clock setting is valid
+ if (it->options[3]) {
+ if (it->options[3] != 0 &&
+ it->options[3] != 1 && it->options[3] != 10) {
+ printk("\n Invalid option. Master clock must be set to 1 or 10 (MHz)\n");
+ return -EINVAL;
+ }
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct das16_private_struct))) < 0)
+ return ret;
+
+ if (thisboard->size < 0x400) {
+ printk(" 0x%04lx-0x%04lx\n", iobase, iobase + thisboard->size);
+ if (!request_region(iobase, thisboard->size, "das16")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ } else {
+ printk(" 0x%04lx-0x%04lx 0x%04lx-0x%04lx\n",
+ iobase, iobase + 0x0f,
+ iobase + 0x400,
+ iobase + 0x400 + (thisboard->size & 0x3ff));
+ if (!request_region(iobase, 0x10, "das16")) {
+ printk(" I/O port conflict: 0x%04lx-0x%04lx\n",
+ iobase, iobase + 0x0f);
+ return -EIO;
+ }
+ if (!request_region(iobase + 0x400, thisboard->size & 0x3ff,
+ "das16")) {
+ release_region(iobase, 0x10);
+ printk(" I/O port conflict: 0x%04lx-0x%04lx\n",
+ iobase + 0x400,
+ iobase + 0x400 + (thisboard->size & 0x3ff));
+ return -EIO;
+ }
+ }
+
+ dev->iobase = iobase;
+
+ // probe id bits to make sure they are consistent
+ if (das16_probe(dev, it)) {
+ printk(" id bits do not match selected board, aborting\n");
+ return -EINVAL;
+ }
+ dev->board_name = thisboard->name;
+
+ // get master clock speed
+ if (thisboard->size < 0x400) {
+ if (it->options[3])
+ devpriv->clockbase = 1000 / it->options[3];
+ else
+ devpriv->clockbase = 1000; // 1 MHz default
+ } else {
+ das1600_mode_detect(dev);
+ }
+
+ /* now for the irq */
+ if (irq > 1 && irq < 8) {
+ if ((ret = comedi_request_irq(irq, das16_dma_interrupt, 0,
+ "das16", dev)) < 0)
+ return ret;
+ dev->irq = irq;
+ printk(" ( irq = %u )", irq);
+ } else if (irq == 0) {
+ printk(" ( no irq )");
+ } else {
+ printk(" invalid irq\n");
+ return -EINVAL;
+ }
+
+ // initialize dma
+ dma_chan = it->options[2];
+ if (dma_chan == 1 || dma_chan == 3) {
+ // allocate dma buffers
+ int i;
+ for (i = 0; i < 2; i++) {
+ devpriv->dma_buffer[i] = pci_alloc_consistent(NULL,
+ DAS16_DMA_SIZE, &devpriv->dma_buffer_addr[i]);
+ if (devpriv->dma_buffer[i] == NULL)
+ return -ENOMEM;
+ }
+ if (request_dma(dma_chan, "das16")) {
+ printk(" failed to allocate dma channel %i\n",
+ dma_chan);
+ return -EINVAL;
+ }
+ devpriv->dma_chan = dma_chan;
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
+ release_dma_lock(flags);
+ printk(" ( dma = %u)\n", dma_chan);
+ } else if (dma_chan == 0) {
+ printk(" ( no dma )\n");
+ } else {
+ printk(" invalid dma channel\n");
+ return -EINVAL;
+ }
+
+ // get any user-defined input range
+ if (thisboard->ai_pg == das16_pg_none &&
+ (it->options[4] || it->options[5])) {
+ // allocate single-range range table
+ devpriv->user_ai_range_table =
+ kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
+ GFP_KERNEL);
+ // initialize ai range
+ devpriv->user_ai_range_table->length = 1;
+ user_ai_range = devpriv->user_ai_range_table->range;
+ user_ai_range->min = it->options[4];
+ user_ai_range->max = it->options[5];
+ user_ai_range->flags = UNIT_volt;
+ }
+ // get any user-defined output range
+ if (it->options[6] || it->options[7]) {
+ // allocate single-range range table
+ devpriv->user_ao_range_table =
+ kmalloc(sizeof(struct comedi_lrange) + sizeof(struct comedi_krange),
+ GFP_KERNEL);
+ // initialize ao range
+ devpriv->user_ao_range_table->length = 1;
+ user_ao_range = devpriv->user_ao_range_table->range;
+ user_ao_range->min = it->options[6];
+ user_ao_range->max = it->options[7];
+ user_ao_range->flags = UNIT_volt;
+ }
+
+ if (timer_mode) {
+ init_timer(&(devpriv->timer));
+ devpriv->timer.function = das16_timer_interrupt;
+ devpriv->timer.data = (unsigned long)dev;
+ }
+ devpriv->timer_mode = timer_mode ? 1 : 0;
+
+ if ((ret = alloc_subdevices(dev, 5)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* ai */
+ if (thisboard->ai) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ if (devpriv->ai_singleended) {
+ s->n_chan = 16;
+ s->len_chanlist = 16;
+ s->subdev_flags |= SDF_GROUND;
+ } else {
+ s->n_chan = 8;
+ s->len_chanlist = 8;
+ s->subdev_flags |= SDF_DIFF;
+ }
+ s->maxdata = (1 << thisboard->ai_nbits) - 1;
+ if (devpriv->user_ai_range_table) { // user defined ai range
+ s->range_table = devpriv->user_ai_range_table;
+ } else if (devpriv->ai_unipolar) {
+ s->range_table = das16_ai_uni_lranges[thisboard->ai_pg];
+ } else {
+ s->range_table = das16_ai_bip_lranges[thisboard->ai_pg];
+ }
+ s->insn_read = thisboard->ai;
+ s->do_cmdtest = das16_cmd_test;
+ s->do_cmd = das16_cmd_exec;
+ s->cancel = das16_cancel;
+ s->munge = das16_ai_munge;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 1;
+ /* ao */
+ if (thisboard->ao) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = (1 << thisboard->ao_nbits) - 1;
+ if (devpriv->user_ao_range_table) { // user defined ao range
+ s->range_table = devpriv->user_ao_range_table;
+ } else {
+ s->range_table = &range_unknown;
+ }
+ s->insn_write = thisboard->ao;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ /* di */
+ if (thisboard->di) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->di;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ /* do */
+ if (thisboard->do_) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = thisboard->do_;
+ // initialize digital output lines
+ outb(s->state, dev->iobase + DAS16_DIO);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 4;
+ /* 8255 */
+ if (thisboard->i8255_offset != 0) {
+ subdev_8255_init(dev, s, NULL, (dev->iobase +
+ thisboard->i8255_offset));
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ das16_reset(dev);
+ /* set the interrupt level */
+ devpriv->control_state = DAS16_IRQ(dev->irq);
+ outb(devpriv->control_state, dev->iobase + DAS16_CONTROL);
+
+ // turn on das1600 mode if available
+ if (thisboard->size > 0x400) {
+ outb(DAS1600_ENABLE_VAL, dev->iobase + DAS1600_ENABLE);
+ outb(0, dev->iobase + DAS1600_CONV);
+ outb(0, dev->iobase + DAS1600_BURST);
+ }
+
+ return 0;
+}
+
+static int das16_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das16: remove\n", dev->minor);
+
+ das16_reset(dev);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 4);
+
+ if (devpriv) {
+ int i;
+ for (i = 0; i < 2; i++) {
+ if (devpriv->dma_buffer[i])
+ pci_free_consistent(NULL, DAS16_DMA_SIZE,
+ devpriv->dma_buffer[i],
+ devpriv->dma_buffer_addr[i]);
+ }
+ if (devpriv->dma_chan)
+ free_dma(devpriv->dma_chan);
+ if (devpriv->user_ai_range_table)
+ kfree(devpriv->user_ai_range_table);
+ if (devpriv->user_ao_range_table)
+ kfree(devpriv->user_ao_range_table);
+ }
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->iobase) {
+ if (thisboard->size < 0x400) {
+ release_region(dev->iobase, thisboard->size);
+ } else {
+ release_region(dev->iobase, 0x10);
+ release_region(dev->iobase + 0x400,
+ thisboard->size & 0x3ff);
+ }
+ }
+
+ return 0;
+}
+
+COMEDI_INITCLEANUP(driver_das16);
+
+// utility function that suggests a dma transfer size in bytes
+static unsigned int das16_suggest_transfer_size(struct comedi_device * dev,
+ struct comedi_cmd cmd)
+{
+ unsigned int size;
+ unsigned int freq;
+
+ /* if we are using timer interrupt, we don't care how long it
+ * will take to complete transfer since it will be interrupted
+ * by timer interrupt */
+ if (devpriv->timer_mode)
+ return DAS16_DMA_SIZE;
+
+ /* otherwise, we are relying on dma terminal count interrupt,
+ * so pick a reasonable size */
+ if (cmd.convert_src == TRIG_TIMER)
+ freq = 1000000000 / cmd.convert_arg;
+ else if (cmd.scan_begin_src == TRIG_TIMER)
+ freq = (1000000000 / cmd.scan_begin_arg) * cmd.chanlist_len;
+ // return some default value
+ else
+ freq = 0xffffffff;
+
+ if (cmd.flags & TRIG_WAKE_EOS) {
+ size = sample_size * cmd.chanlist_len;
+ } else {
+ // make buffer fill in no more than 1/3 second
+ size = (freq / 3) * sample_size;
+ }
+
+ // set a minimum and maximum size allowed
+ if (size > DAS16_DMA_SIZE)
+ size = DAS16_DMA_SIZE - DAS16_DMA_SIZE % sample_size;
+ else if (size < sample_size)
+ size = sample_size;
+
+ if (cmd.stop_src == TRIG_COUNT && size > devpriv->adc_byte_count)
+ size = devpriv->adc_byte_count;
+
+ return size;
+}
+
+static void das16_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *array, unsigned int num_bytes, unsigned int start_chan_index)
+{
+ unsigned int i, num_samples = num_bytes / sizeof(short);
+ short *data = array;
+
+ for (i = 0; i < num_samples; i++) {
+ data[i] = le16_to_cpu(data[i]);
+ if (thisboard->ai_nbits == 12) {
+ data[i] = (data[i] >> 4) & 0xfff;
+ }
+ }
+}
diff --git a/drivers/staging/comedi/drivers/das16m1.c b/drivers/staging/comedi/drivers/das16m1.c
new file mode 100644
index 00000000000..0e423e199ed
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das16m1.c
@@ -0,0 +1,765 @@
+/*
+ comedi/drivers/das16m1.c
+ CIO-DAS16/M1 driver
+ Author: Frank Mori Hess, based on code from the das16
+ driver.
+ Copyright (C) 2001 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das16m1
+Description: CIO-DAS16/M1
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Measurement Computing] CIO-DAS16/M1 (cio-das16/m1)
+Status: works
+
+This driver supports a single board - the CIO-DAS16/M1.
+As far as I know, there are no other boards that have
+the same register layout. Even the CIO-DAS16/M1/16 is
+significantly different.
+
+I was _barely_ able to reach the full 1 MHz capability
+of this board, using a hard real-time interrupt
+(set the TRIG_RT flag in your struct comedi_cmd and use
+rtlinux or RTAI). The board can't do dma, so the bottleneck is
+pulling the data across the ISA bus. I timed the interrupt
+handler, and it took my computer ~470 microseconds to pull 512
+samples from the board. So at 1 Mhz sampling rate,
+expect your CPU to be spending almost all of its
+time in the interrupt handler.
+
+This board has some unusual restrictions for its channel/gain list. If the
+list has 2 or more channels in it, then two conditions must be satisfied:
+(1) - even/odd channels must appear at even/odd indices in the list
+(2) - the list must have an even number of entries.
+
+Options:
+ [0] - base io address
+ [1] - irq (optional, but you probably want it)
+
+irq can be omitted, although the cmd interface will not work without it.
+*/
+
+#include <linux/ioport.h>
+#include "../comedidev.h"
+
+#include "8255.h"
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define DAS16M1_SIZE 16
+#define DAS16M1_SIZE2 8
+
+#define DAS16M1_XTAL 100 //10 MHz master clock
+
+#define FIFO_SIZE 1024 // 1024 sample fifo
+
+/*
+ CIO-DAS16_M1.pdf
+
+ "cio-das16/m1"
+
+ 0 a/d bits 0-3, mux start 12 bit
+ 1 a/d bits 4-11 unused
+ 2 status control
+ 3 di 4 bit do 4 bit
+ 4 unused clear interrupt
+ 5 interrupt, pacer
+ 6 channel/gain queue address
+ 7 channel/gain queue data
+ 89ab 8254
+ cdef 8254
+ 400 8255
+ 404-407 8254
+
+*/
+
+#define DAS16M1_AI 0 // 16-bit wide register
+#define AI_CHAN(x) ((x) & 0xf)
+#define DAS16M1_CS 2
+#define EXT_TRIG_BIT 0x1
+#define OVRUN 0x20
+#define IRQDATA 0x80
+#define DAS16M1_DIO 3
+#define DAS16M1_CLEAR_INTR 4
+#define DAS16M1_INTR_CONTROL 5
+#define EXT_PACER 0x2
+#define INT_PACER 0x3
+#define PACER_MASK 0x3
+#define INTE 0x80
+#define DAS16M1_QUEUE_ADDR 6
+#define DAS16M1_QUEUE_DATA 7
+#define Q_CHAN(x) ((x) & 0x7)
+#define Q_RANGE(x) (((x) & 0xf) << 4)
+#define UNIPOLAR 0x40
+#define DAS16M1_8254_FIRST 0x8
+#define DAS16M1_8254_FIRST_CNTRL 0xb
+#define TOTAL_CLEAR 0x30
+#define DAS16M1_8254_SECOND 0xc
+#define DAS16M1_82C55 0x400
+#define DAS16M1_8254_THIRD 0x404
+
+static const struct comedi_lrange range_das16m1 = { 9,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10),
+ }
+};
+
+static int das16m1_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16m1_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das16m1_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int das16m1_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das16m1_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das16m1_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static int das16m1_poll(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t das16m1_interrupt(int irq, void *d PT_REGS_ARG);
+static void das16m1_handler(struct comedi_device * dev, unsigned int status);
+
+static unsigned int das16m1_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int round_flag);
+
+static int das16m1_irq_bits(unsigned int irq);
+
+struct das16m1_board {
+ const char *name;
+ unsigned int ai_speed;
+};
+
+static const struct das16m1_board das16m1_boards[] = {
+ {
+ name: "cio-das16/m1", // CIO-DAS16_M1.pdf
+ ai_speed:1000, // 1MHz max speed
+ },
+};
+
+#define das16m1_num_boards ((sizeof(das16m1_boards)) / (sizeof(das16m1_boards[0])))
+
+static int das16m1_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das16m1_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das16m1 = {
+ driver_name:"das16m1",
+ module:THIS_MODULE,
+ attach:das16m1_attach,
+ detach:das16m1_detach,
+ board_name:&das16m1_boards[0].name,
+ num_names:das16m1_num_boards,
+ offset:sizeof(das16m1_boards[0]),
+};
+
+struct das16m1_private_struct {
+ unsigned int control_state;
+ volatile unsigned int adc_count; // number of samples completed
+ /* initial value in lower half of hardware conversion counter,
+ * needed to keep track of whether new count has been loaded into
+ * counter yet (loaded by first sample conversion) */
+ u16 initial_hw_count;
+ short ai_buffer[FIFO_SIZE];
+ unsigned int do_bits; // saves status of digital output bits
+ unsigned int divisor1; // divides master clock to obtain conversion speed
+ unsigned int divisor2; // divides master clock to obtain conversion speed
+};
+#define devpriv ((struct das16m1_private_struct *)(dev->private))
+#define thisboard ((const struct das16m1_board *)(dev->board_ptr))
+
+COMEDI_INITCLEANUP(driver_das16m1);
+
+static inline short munge_sample(short data)
+{
+ return (data >> 4) & 0xfff;
+}
+
+static int das16m1_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ unsigned int err = 0, tmp, i;
+
+ /* make sure triggers are valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg), cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check chanlist against board's peculiarities
+ if (cmd->chanlist && cmd->chanlist_len > 1) {
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ // even/odd channels must go into even/odd queue addresses
+ if ((i % 2) != (CR_CHAN(cmd->chanlist[i]) % 2)) {
+ comedi_error(dev, "bad chanlist:\n"
+ " even/odd channels must go have even/odd chanlist indices");
+ err++;
+ }
+ }
+ if ((cmd->chanlist_len % 2) != 0) {
+ comedi_error(dev,
+ "chanlist must be of even length or length 1");
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int das16m1_cmd_exec(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int byte, i;
+
+ if (dev->irq == 0) {
+ comedi_error(dev, "irq required to execute comedi_cmd");
+ return -1;
+ }
+
+ /* disable interrupts and internal pacer */
+ devpriv->control_state &= ~INTE & ~PACER_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ // set software count
+ devpriv->adc_count = 0;
+ /* Initialize lower half of hardware counter, used to determine how
+ * many samples are in fifo. Value doesn't actually load into counter
+ * until counter's next clock (the next a/d conversion) */
+ i8254_load(dev->iobase + DAS16M1_8254_FIRST, 0, 1, 0, 2);
+ /* remember current reading of counter so we know when counter has
+ * actually been loaded */
+ devpriv->initial_hw_count =
+ i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+ /* setup channel/gain queue */
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ outb(i, dev->iobase + DAS16M1_QUEUE_ADDR);
+ byte = Q_CHAN(CR_CHAN(cmd->
+ chanlist[i])) | Q_RANGE(CR_RANGE(cmd->
+ chanlist[i]));
+ outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
+ }
+
+ /* set counter mode and counts */
+ cmd->convert_arg =
+ das16m1_set_pacer(dev, cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+
+ // set control & status register
+ byte = 0;
+ /* if we are using external start trigger (also board dislikes having
+ * both start and conversion triggers external simultaneously) */
+ if (cmd->start_src == TRIG_EXT && cmd->convert_src != TRIG_EXT) {
+ byte |= EXT_TRIG_BIT;
+ }
+ outb(byte, dev->iobase + DAS16M1_CS);
+ /* clear interrupt bit */
+ outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+
+ /* enable interrupts and internal pacer */
+ devpriv->control_state &= ~PACER_MASK;
+ if (cmd->convert_src == TRIG_TIMER) {
+ devpriv->control_state |= INT_PACER;
+ } else {
+ devpriv->control_state |= EXT_PACER;
+ }
+ devpriv->control_state |= INTE;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ return 0;
+}
+
+static int das16m1_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->control_state &= ~INTE & ~PACER_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ return 0;
+}
+
+static int das16m1_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int byte;
+ const int timeout = 1000;
+
+ /* disable interrupts and internal pacer */
+ devpriv->control_state &= ~INTE & ~PACER_MASK;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ /* setup channel/gain queue */
+ outb(0, dev->iobase + DAS16M1_QUEUE_ADDR);
+ byte = Q_CHAN(CR_CHAN(insn->chanspec)) | Q_RANGE(CR_RANGE(insn->
+ chanspec));
+ outb(byte, dev->iobase + DAS16M1_QUEUE_DATA);
+
+ for (n = 0; n < insn->n; n++) {
+ /* clear IRQDATA bit */
+ outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+ /* trigger conversion */
+ outb(0, dev->iobase);
+
+ for (i = 0; i < timeout; i++) {
+ if (inb(dev->iobase + DAS16M1_CS) & IRQDATA)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ data[n] = munge_sample(inw(dev->iobase));
+ }
+
+ return n;
+}
+
+static int das16m1_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = inb(dev->iobase + DAS16M1_DIO) & 0xf;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int das16m1_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int wbits;
+
+ // only set bits that have been masked
+ data[0] &= 0xf;
+ wbits = devpriv->do_bits;
+ // zero bits that have been masked
+ wbits &= ~data[0];
+ // set masked bits
+ wbits |= data[0] & data[1];
+ devpriv->do_bits = wbits;
+ data[1] = wbits;
+
+ outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+
+ return 2;
+}
+
+static int das16m1_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ unsigned int status;
+
+ // prevent race with interrupt handler
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ status = inb(dev->iobase + DAS16M1_CS);
+ das16m1_handler(dev, status);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+static irqreturn_t das16m1_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int status;
+ struct comedi_device *dev = d;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+ // prevent race with comedi_poll()
+ spin_lock(&dev->spinlock);
+
+ status = inb(dev->iobase + DAS16M1_CS);
+
+ if ((status & (IRQDATA | OVRUN)) == 0) {
+ comedi_error(dev, "spurious interrupt");
+ spin_unlock(&dev->spinlock);
+ return IRQ_NONE;
+ }
+
+ das16m1_handler(dev, status);
+
+ /* clear interrupt */
+ outb(0, dev->iobase + DAS16M1_CLEAR_INTR);
+
+ spin_unlock(&dev->spinlock);
+ return IRQ_HANDLED;
+}
+
+static void munge_sample_array(short * array, unsigned int num_elements)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_elements; i++) {
+ array[i] = munge_sample(array[i]);
+ }
+}
+
+static void das16m1_handler(struct comedi_device * dev, unsigned int status)
+{
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ u16 num_samples;
+ u16 hw_counter;
+
+ s = dev->read_subdev;
+ async = s->async;
+ async->events = 0;
+ cmd = &async->cmd;
+
+ // figure out how many samples are in fifo
+ hw_counter = i8254_read(dev->iobase + DAS16M1_8254_FIRST, 0, 1);
+ /* make sure hardware counter reading is not bogus due to initial value
+ * not having been loaded yet */
+ if (devpriv->adc_count == 0 && hw_counter == devpriv->initial_hw_count) {
+ num_samples = 0;
+ } else {
+ /* The calculation of num_samples looks odd, but it uses the following facts.
+ * 16 bit hardware counter is initialized with value of zero (which really
+ * means 0x1000). The counter decrements by one on each conversion
+ * (when the counter decrements from zero it goes to 0xffff). num_samples
+ * is a 16 bit variable, so it will roll over in a similar fashion to the
+ * hardware counter. Work it out, and this is what you get. */
+ num_samples = -hw_counter - devpriv->adc_count;
+ }
+ // check if we only need some of the points
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (num_samples > cmd->stop_arg * cmd->chanlist_len)
+ num_samples = cmd->stop_arg * cmd->chanlist_len;
+ }
+ // make sure we dont try to get too many points if fifo has overrun
+ if (num_samples > FIFO_SIZE)
+ num_samples = FIFO_SIZE;
+ insw(dev->iobase, devpriv->ai_buffer, num_samples);
+ munge_sample_array(devpriv->ai_buffer, num_samples);
+ cfc_write_array_to_buffer(s, devpriv->ai_buffer,
+ num_samples * sizeof(short));
+ devpriv->adc_count += num_samples;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (devpriv->adc_count >= cmd->stop_arg * cmd->chanlist_len) { /* end of acquisition */
+ das16m1_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ /* this probably won't catch overruns since the card doesn't generate
+ * overrun interrupts, but we might as well try */
+ if (status & OVRUN) {
+ das16m1_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_error(dev, "fifo overflow");
+ }
+
+ comedi_event(dev, s);
+
+}
+
+/* This function takes a time in nanoseconds and sets the *
+ * 2 pacer clocks to the closest frequency possible. It also *
+ * returns the actual sampling period. */
+static unsigned int das16m1_set_pacer(struct comedi_device * dev, unsigned int ns,
+ int rounding_flags)
+{
+ i8253_cascade_ns_to_timer_2div(DAS16M1_XTAL, &(devpriv->divisor1),
+ &(devpriv->divisor2), &ns, rounding_flags & TRIG_ROUND_MASK);
+
+ /* Write the values of ctr1 and ctr2 into counters 1 and 2 */
+ i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 1, devpriv->divisor1,
+ 2);
+ i8254_load(dev->iobase + DAS16M1_8254_SECOND, 0, 2, devpriv->divisor2,
+ 2);
+
+ return ns;
+}
+
+static int das16m1_irq_bits(unsigned int irq)
+{
+ int ret;
+
+ switch (irq) {
+ case 10:
+ ret = 0x0;
+ break;
+ case 11:
+ ret = 0x1;
+ break;
+ case 12:
+ ret = 0x2;
+ break;
+ case 15:
+ ret = 0x3;
+ break;
+ case 2:
+ ret = 0x4;
+ break;
+ case 3:
+ ret = 0x5;
+ break;
+ case 5:
+ ret = 0x6;
+ break;
+ case 7:
+ ret = 0x7;
+ break;
+ default:
+ return -1;
+ break;
+ }
+ return (ret << 4);
+}
+
+/*
+ * Options list:
+ * 0 I/O base
+ * 1 IRQ
+ */
+
+static int das16m1_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ unsigned int irq;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+
+ printk("comedi%d: das16m1:", dev->minor);
+
+ if ((ret = alloc_private(dev,
+ sizeof(struct das16m1_private_struct))) < 0)
+ return ret;
+
+ dev->board_name = thisboard->name;
+
+ printk(" io 0x%lx-0x%lx 0x%lx-0x%lx",
+ iobase, iobase + DAS16M1_SIZE,
+ iobase + DAS16M1_82C55, iobase + DAS16M1_82C55 + DAS16M1_SIZE2);
+ if (!request_region(iobase, DAS16M1_SIZE, driver_das16m1.driver_name)) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ if (!request_region(iobase + DAS16M1_82C55, DAS16M1_SIZE2,
+ driver_das16m1.driver_name)) {
+ release_region(iobase, DAS16M1_SIZE);
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* now for the irq */
+ irq = it->options[1];
+ // make sure it is valid
+ if (das16m1_irq_bits(irq) >= 0) {
+ ret = comedi_request_irq(irq, das16m1_interrupt, 0,
+ driver_das16m1.driver_name, dev);
+ if (ret < 0) {
+ printk(", irq unavailable\n");
+ return ret;
+ }
+ dev->irq = irq;
+ printk(", irq %u\n", irq);
+ } else if (irq == 0) {
+ printk(", no irq\n");
+ } else {
+ printk(", invalid irq\n"
+ " valid irqs are 2, 3, 5, 7, 10, 11, 12, or 15\n");
+ return -EINVAL;
+ }
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* ai */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 8;
+ s->subdev_flags = SDF_DIFF;
+ s->len_chanlist = 256;
+ s->maxdata = (1 << 12) - 1;
+ s->range_table = &range_das16m1;
+ s->insn_read = das16m1_ai_rinsn;
+ s->do_cmdtest = das16m1_cmd_test;
+ s->do_cmd = das16m1_cmd_exec;
+ s->cancel = das16m1_cancel;
+ s->poll = das16m1_poll;
+
+ s = dev->subdevices + 1;
+ /* di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das16m1_di_rbits;
+
+ s = dev->subdevices + 2;
+ /* do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das16m1_do_wbits;
+
+ s = dev->subdevices + 3;
+ /* 8255 */
+ subdev_8255_init(dev, s, NULL, dev->iobase + DAS16M1_82C55);
+
+ // disable upper half of hardware conversion counter so it doesn't mess with us
+ outb(TOTAL_CLEAR, dev->iobase + DAS16M1_8254_FIRST_CNTRL);
+
+ // initialize digital output lines
+ outb(devpriv->do_bits, dev->iobase + DAS16M1_DIO);
+
+ /* set the interrupt level */
+ if (dev->irq)
+ devpriv->control_state = das16m1_irq_bits(dev->irq);
+ else
+ devpriv->control_state = 0;
+ outb(devpriv->control_state, dev->iobase + DAS16M1_INTR_CONTROL);
+
+ return 0;
+}
+
+static int das16m1_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das16m1: remove\n", dev->minor);
+
+// das16m1_reset(dev);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->iobase) {
+ release_region(dev->iobase, DAS16M1_SIZE);
+ release_region(dev->iobase + DAS16M1_82C55, DAS16M1_SIZE2);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
new file mode 100644
index 00000000000..cd4cd4e6a79
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das1800.c
@@ -0,0 +1,1758 @@
+/*
+ comedi/drivers/das1800.c
+ Driver for Keitley das1700/das1800 series boards
+ Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das1800
+Description: Keithley Metrabyte DAS1800 (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Keithley Metrabyte] DAS-1701ST (das-1701st),
+ DAS-1701ST-DA (das-1701st-da), DAS-1701/AO (das-1701ao),
+ DAS-1702ST (das-1702st), DAS-1702ST-DA (das-1702st-da),
+ DAS-1702HR (das-1702hr), DAS-1702HR-DA (das-1702hr-da),
+ DAS-1702/AO (das-1702ao), DAS-1801ST (das-1801st),
+ DAS-1801ST-DA (das-1801st-da), DAS-1801HC (das-1801hc),
+ DAS-1801AO (das-1801ao), DAS-1802ST (das-1802st),
+ DAS-1802ST-DA (das-1802st-da), DAS-1802HR (das-1802hr),
+ DAS-1802HR-DA (das-1802hr-da), DAS-1802HC (das-1802hc),
+ DAS-1802AO (das-1802ao)
+Status: works
+
+The waveform analog output on the 'ao' cards is not supported.
+If you need it, send me (Frank Hess) an email.
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed or externally triggered conversions)
+ [2] - DMA0 (optional, requires irq)
+ [3] - DMA1 (optional, requires irq and dma0)
+*/
+/*
+
+This driver supports the following Keithley boards:
+
+das-1701st
+das-1701st-da
+das-1701ao
+das-1702st
+das-1702st-da
+das-1702hr
+das-1702hr-da
+das-1702ao
+das-1801st
+das-1801st-da
+das-1801hc
+das-1801ao
+das-1802st
+das-1802st-da
+das-1802hr
+das-1802hr-da
+das-1802hc
+das-1802ao
+
+Options:
+ [0] - base io address
+ [1] - irq (optional, required for timed or externally triggered conversions)
+ [2] - dma0 (optional, requires irq)
+ [3] - dma1 (optional, requires irq and dma0)
+
+irq can be omitted, although the cmd interface will not work without it.
+
+analog input cmd triggers supported:
+ start_src: TRIG_NOW | TRIG_EXT
+ scan_begin_src: TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT
+ scan_end_src: TRIG_COUNT
+ convert_src: TRIG_TIMER | TRIG_EXT (TRIG_EXT requires scan_begin_src == TRIG_FOLLOW)
+ stop_src: TRIG_COUNT | TRIG_EXT | TRIG_NONE
+
+scan_begin_src triggers TRIG_TIMER and TRIG_EXT use the card's
+'burst mode' which limits the valid conversion time to 64 microseconds
+(convert_arg <= 64000). This limitation does not apply if scan_begin_src
+is TRIG_FOLLOW.
+
+NOTES:
+Only the DAS-1801ST has been tested by me.
+Unipolar and bipolar ranges cannot be mixed in the channel/gain list.
+
+TODO:
+ Make it automatically allocate irq and dma channels if they are not specified
+ Add support for analog out on 'ao' cards
+ read insn for analog out
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+// misc. defines
+#define DAS1800_SIZE 16 //uses 16 io addresses
+#define FIFO_SIZE 1024 // 1024 sample fifo
+#define TIMER_BASE 200 // 5 Mhz master clock
+#define UNIPOLAR 0x4 // bit that determines whether input range is uni/bipolar
+#define DMA_BUF_SIZE 0x1ff00 // size in bytes of dma buffers
+
+/* Registers for the das1800 */
+#define DAS1800_FIFO 0x0
+#define DAS1800_QRAM 0x0
+#define DAS1800_DAC 0x0
+#define DAS1800_SELECT 0x2
+#define ADC 0x0
+#define QRAM 0x1
+#define DAC(a) (0x2 + a)
+#define DAS1800_DIGITAL 0x3
+#define DAS1800_CONTROL_A 0x4
+#define FFEN 0x1
+#define CGEN 0x4
+#define CGSL 0x8
+#define TGEN 0x10
+#define TGSL 0x20
+#define ATEN 0x80
+#define DAS1800_CONTROL_B 0x5
+#define DMA_CH5 0x1
+#define DMA_CH6 0x2
+#define DMA_CH7 0x3
+#define DMA_CH5_CH6 0x5
+#define DMA_CH6_CH7 0x6
+#define DMA_CH7_CH5 0x7
+#define DMA_ENABLED 0x3 //mask used to determine if dma is enabled
+#define DMA_DUAL 0x4
+#define IRQ3 0x8
+#define IRQ5 0x10
+#define IRQ7 0x18
+#define IRQ10 0x28
+#define IRQ11 0x30
+#define IRQ15 0x38
+#define FIMD 0x40
+#define DAS1800_CONTROL_C 0X6
+#define IPCLK 0x1
+#define XPCLK 0x3
+#define BMDE 0x4
+#define CMEN 0x8
+#define UQEN 0x10
+#define SD 0x40
+#define UB 0x80
+#define DAS1800_STATUS 0x7
+// bits that prevent interrupt status bits (and CVEN) from being cleared on write
+#define CLEAR_INTR_MASK (CVEN_MASK | 0x1f)
+#define INT 0x1
+#define DMATC 0x2
+#define CT0TC 0x8
+#define OVF 0x10
+#define FHF 0x20
+#define FNE 0x40
+#define CVEN_MASK 0x40 // masks CVEN on write
+#define CVEN 0x80
+#define DAS1800_BURST_LENGTH 0x8
+#define DAS1800_BURST_RATE 0x9
+#define DAS1800_QRAM_ADDRESS 0xa
+#define DAS1800_COUNTER 0xc
+
+#define IOBASE2 0x400 //offset of additional ioports used on 'ao' cards
+
+enum {
+ das1701st, das1701st_da, das1702st, das1702st_da, das1702hr,
+ das1702hr_da,
+ das1701ao, das1702ao, das1801st, das1801st_da, das1802st, das1802st_da,
+ das1802hr, das1802hr_da, das1801hc, das1802hc, das1801ao, das1802ao
+};
+
+static int das1800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das1800_detach(struct comedi_device * dev);
+static int das1800_probe(struct comedi_device * dev);
+static int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG);
+static int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das1800_ai_handler(struct comedi_device * dev);
+static void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int status);
+static void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s);
+static void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int channel, uint16_t * buffer);
+static void das1800_handle_fifo_half_full(struct comedi_device * dev,
+ struct comedi_subdevice * s);
+static void das1800_handle_fifo_not_empty(struct comedi_device * dev,
+ struct comedi_subdevice * s);
+static int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int das1800_set_frequency(struct comedi_device * dev);
+static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode);
+static unsigned int suggest_transfer_size(struct comedi_cmd * cmd);
+
+// analog input ranges
+static const struct comedi_lrange range_ai_das1801 = {
+ 8,
+ {
+ RANGE(-5, 5),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02),
+ RANGE(0, 5),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ RANGE(0, 0.02),
+ }
+};
+
+static const struct comedi_lrange range_ai_das1802 = {
+ 8,
+ {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ }
+};
+
+struct das1800_board {
+ const char *name;
+ int ai_speed; /* max conversion period in nanoseconds */
+ int resolution; /* bits of ai resolution */
+ int qram_len; /* length of card's channel / gain queue */
+ int common; /* supports AREF_COMMON flag */
+ int do_n_chan; /* number of digital output channels */
+ int ao_ability; /* 0 == no analog out, 1 == basic analog out, 2 == waveform analog out */
+ int ao_n_chan; /* number of analog out channels */
+ const struct comedi_lrange *range_ai; /* available input ranges */
+};
+
+/* Warning: the maximum conversion speeds listed below are
+ * not always achievable depending on board setup (see
+ * user manual.)
+ */
+static const struct das1800_board das1800_boards[] = {
+ {
+ name: "das-1701st",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1701st-da",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1702st",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1702st-da",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1702hr",
+ ai_speed:20000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1702hr-da",
+ ai_speed:20000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1701ao",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1702ao",
+ ai_speed:6250,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1801st",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1801st-da",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1802st",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1802st-da",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:4,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1802hr",
+ ai_speed:10000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:0,
+ ao_n_chan:0,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1802hr-da",
+ ai_speed:10000,
+ resolution:16,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1801hc",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:64,
+ common: 0,
+ do_n_chan:8,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1802hc",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:64,
+ common: 0,
+ do_n_chan:8,
+ ao_ability:1,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+ {
+ name: "das-1801ao",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1801,
+ },
+ {
+ name: "das-1802ao",
+ ai_speed:3000,
+ resolution:12,
+ qram_len:256,
+ common: 1,
+ do_n_chan:4,
+ ao_ability:2,
+ ao_n_chan:2,
+ range_ai:&range_ai_das1802,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct das1800_board *)dev->board_ptr)
+
+struct das1800_private {
+ volatile unsigned int count; /* number of data points left to be taken */
+ unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
+ unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
+ int do_bits; /* digital output bits */
+ int irq_dma_bits; /* bits for control register b */
+ /* dma bits for control register b, stored so that dma can be
+ * turned on and off */
+ int dma_bits;
+ unsigned int dma0; /* dma channels used */
+ unsigned int dma1;
+ volatile unsigned int dma_current; /* dma channel currently in use */
+ uint16_t *ai_buf0; /* pointers to dma buffers */
+ uint16_t *ai_buf1;
+ uint16_t *dma_current_buf; /* pointer to dma buffer currently being used */
+ unsigned int dma_transfer_size; /* size of transfer currently used, in bytes */
+ unsigned long iobase2; /* secondary io address used for analog out on 'ao' boards */
+ short ao_update_bits; /* remembers the last write to the 'update' dac */
+};
+
+#define devpriv ((struct das1800_private *)dev->private)
+
+// analog out range for boards with basic analog out
+static const struct comedi_lrange range_ao_1 = {
+ 1,
+ {
+ RANGE(-10, 10),
+ }
+};
+
+// analog out range for 'ao' boards
+/*
+static const struct comedi_lrange range_ao_2 = {
+ 2,
+ {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ }
+};
+*/
+
+static struct comedi_driver driver_das1800 = {
+ driver_name:"das1800",
+ module:THIS_MODULE,
+ attach:das1800_attach,
+ detach:das1800_detach,
+ num_names:sizeof(das1800_boards) / sizeof(struct das1800_board),
+ board_name:&das1800_boards[0].name,
+ offset:sizeof(struct das1800_board),
+};
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_das1800);
+
+static int das1800_init_dma(struct comedi_device * dev, unsigned int dma0,
+ unsigned int dma1)
+{
+ unsigned long flags;
+
+ // need an irq to do dma
+ if (dev->irq && dma0) {
+ //encode dma0 and dma1 into 2 digit hexadecimal for switch
+ switch ((dma0 & 0x7) | (dma1 << 4)) {
+ case 0x5: // dma0 == 5
+ devpriv->dma_bits |= DMA_CH5;
+ break;
+ case 0x6: // dma0 == 6
+ devpriv->dma_bits |= DMA_CH6;
+ break;
+ case 0x7: // dma0 == 7
+ devpriv->dma_bits |= DMA_CH7;
+ break;
+ case 0x65: // dma0 == 5, dma1 == 6
+ devpriv->dma_bits |= DMA_CH5_CH6;
+ break;
+ case 0x76: // dma0 == 6, dma1 == 7
+ devpriv->dma_bits |= DMA_CH6_CH7;
+ break;
+ case 0x57: // dma0 == 7, dma1 == 5
+ devpriv->dma_bits |= DMA_CH7_CH5;
+ break;
+ default:
+ printk(" only supports dma channels 5 through 7\n"
+ " Dual dma only allows the following combinations:\n"
+ " dma 5,6 / 6,7 / or 7,5\n");
+ return -EINVAL;
+ break;
+ }
+ if (request_dma(dma0, driver_das1800.driver_name)) {
+ printk(" failed to allocate dma channel %i\n", dma0);
+ return -EINVAL;
+ }
+ devpriv->dma0 = dma0;
+ devpriv->dma_current = dma0;
+ if (dma1) {
+ if (request_dma(dma1, driver_das1800.driver_name)) {
+ printk(" failed to allocate dma channel %i\n",
+ dma1);
+ return -EINVAL;
+ }
+ devpriv->dma1 = dma1;
+ }
+ devpriv->ai_buf0 = kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+ if (devpriv->ai_buf0 == NULL)
+ return -ENOMEM;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ if (dma1) {
+ devpriv->ai_buf1 =
+ kmalloc(DMA_BUF_SIZE, GFP_KERNEL | GFP_DMA);
+ if (devpriv->ai_buf1 == NULL)
+ return -ENOMEM;
+ }
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma0);
+ set_dma_mode(devpriv->dma0, DMA_MODE_READ);
+ if (dma1) {
+ disable_dma(devpriv->dma1);
+ set_dma_mode(devpriv->dma1, DMA_MODE_READ);
+ }
+ release_dma_lock(flags);
+ }
+ return 0;
+}
+
+static int das1800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = it->options[0];
+ unsigned int irq = it->options[1];
+ unsigned int dma0 = it->options[2];
+ unsigned int dma1 = it->options[3];
+ unsigned long iobase2;
+ int board;
+ int retval;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct das1800_private)) < 0)
+ return -ENOMEM;
+
+ printk("comedi%d: %s: io 0x%lx", dev->minor, driver_das1800.driver_name,
+ iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ if (dma0) {
+ printk(", dma %u", dma0);
+ if (dma1)
+ printk(" and %u", dma1);
+ }
+ }
+ printk("\n");
+
+ if (iobase == 0) {
+ printk(" io base address required\n");
+ return -EINVAL;
+ }
+
+ /* check if io addresses are available */
+ if (!request_region(iobase, DAS1800_SIZE, driver_das1800.driver_name)) {
+ printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + DAS1800_SIZE - 1);
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ board = das1800_probe(dev);
+ if (board < 0) {
+ printk(" unable to determine board type\n");
+ return -ENODEV;
+ }
+
+ dev->board_ptr = das1800_boards + board;
+ dev->board_name = thisboard->name;
+
+ // if it is an 'ao' board with fancy analog out then we need extra io ports
+ if (thisboard->ao_ability == 2) {
+ iobase2 = iobase + IOBASE2;
+ if (!request_region(iobase2, DAS1800_SIZE,
+ driver_das1800.driver_name)) {
+ printk(" I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase2, iobase2 + DAS1800_SIZE - 1);
+ return -EIO;
+ }
+ devpriv->iobase2 = iobase2;
+ }
+
+ /* grab our IRQ */
+ if (irq) {
+ if (comedi_request_irq(irq, das1800_interrupt, 0,
+ driver_das1800.driver_name, dev)) {
+ printk(" unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = irq;
+
+ // set bits that tell card which irq to use
+ switch (irq) {
+ case 0:
+ break;
+ case 3:
+ devpriv->irq_dma_bits |= 0x8;
+ break;
+ case 5:
+ devpriv->irq_dma_bits |= 0x10;
+ break;
+ case 7:
+ devpriv->irq_dma_bits |= 0x18;
+ break;
+ case 10:
+ devpriv->irq_dma_bits |= 0x28;
+ break;
+ case 11:
+ devpriv->irq_dma_bits |= 0x30;
+ break;
+ case 15:
+ devpriv->irq_dma_bits |= 0x38;
+ break;
+ default:
+ printk(" irq out of range\n");
+ return -EINVAL;
+ break;
+ }
+
+ retval = das1800_init_dma(dev, dma0, dma1);
+ if (retval < 0)
+ return retval;
+
+ if (devpriv->ai_buf0 == NULL) {
+ devpriv->ai_buf0 =
+ kmalloc(FIFO_SIZE * sizeof(uint16_t), GFP_KERNEL);
+ if (devpriv->ai_buf0 == NULL)
+ return -ENOMEM;
+ }
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_GROUND | SDF_CMD_READ;
+ if (thisboard->common)
+ s->subdev_flags |= SDF_COMMON;
+ s->n_chan = thisboard->qram_len;
+ s->len_chanlist = thisboard->qram_len;
+ s->maxdata = (1 << thisboard->resolution) - 1;
+ s->range_table = thisboard->range_ai;
+ s->do_cmd = das1800_ai_do_cmd;
+ s->do_cmdtest = das1800_ai_do_cmdtest;
+ s->insn_read = das1800_ai_rinsn;
+ s->poll = das1800_ai_poll;
+ s->cancel = das1800_cancel;
+
+ /* analog out */
+ s = dev->subdevices + 1;
+ if (thisboard->ao_ability == 1) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_n_chan;
+ s->maxdata = (1 << thisboard->resolution) - 1;
+ s->range_table = &range_ao_1;
+ s->insn_write = das1800_ao_winsn;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* di */
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das1800_di_rbits;
+
+ /* do */
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = thisboard->do_n_chan;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das1800_do_wbits;
+
+ das1800_cancel(dev, dev->read_subdev);
+
+ // initialize digital out channels
+ outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+
+ // initialize analog out channels
+ if (thisboard->ao_ability == 1) {
+ // select 'update' dac channel for baseAddress + 0x0
+ outb(DAC(thisboard->ao_n_chan - 1),
+ dev->iobase + DAS1800_SELECT);
+ outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
+ }
+
+ return 0;
+};
+
+static int das1800_detach(struct comedi_device * dev)
+{
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase)
+ release_region(dev->iobase, DAS1800_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->private) {
+ if (devpriv->iobase2)
+ release_region(devpriv->iobase2, DAS1800_SIZE);
+ if (devpriv->dma0)
+ free_dma(devpriv->dma0);
+ if (devpriv->dma1)
+ free_dma(devpriv->dma1);
+ if (devpriv->ai_buf0)
+ kfree(devpriv->ai_buf0);
+ if (devpriv->ai_buf1)
+ kfree(devpriv->ai_buf1);
+ }
+
+ printk("comedi%d: %s: remove\n", dev->minor,
+ driver_das1800.driver_name);
+
+ return 0;
+};
+
+/* probes and checks das-1800 series board type
+ */
+static int das1800_probe(struct comedi_device * dev)
+{
+ int id;
+ int board;
+
+ id = (inb(dev->iobase + DAS1800_DIGITAL) >> 4) & 0xf; /* get id bits */
+ board = ((struct das1800_board *) dev->board_ptr) - das1800_boards;
+
+ switch (id) {
+ case 0x3:
+ if (board == das1801st_da || board == das1802st_da ||
+ board == das1701st_da || board == das1702st_da) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800st-da series\n");
+ return das1801st;
+ break;
+ case 0x4:
+ if (board == das1802hr_da || board == das1702hr_da) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1802hr-da\n");
+ return das1802hr;
+ break;
+ case 0x5:
+ if (board == das1801ao || board == das1802ao ||
+ board == das1701ao || board == das1702ao) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800ao series\n");
+ return das1801ao;
+ break;
+ case 0x6:
+ if (board == das1802hr || board == das1702hr) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1802hr\n");
+ return das1802hr;
+ break;
+ case 0x7:
+ if (board == das1801st || board == das1802st ||
+ board == das1701st || board == das1702st) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800st series\n");
+ return das1801st;
+ break;
+ case 0x8:
+ if (board == das1801hc || board == das1802hc) {
+ printk(" Board model: %s\n",
+ das1800_boards[board].name);
+ return board;
+ }
+ printk(" Board model (probed, not recommended): das-1800hc series\n");
+ return das1801hc;
+ break;
+ default:
+ printk(" Board model: probe returned 0x%x (unknown, please report)\n", id);
+ return board;
+ break;
+ }
+ return -1;
+}
+
+static int das1800_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ // prevent race with interrupt handler
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ das1800_ai_handler(dev);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+static irqreturn_t das1800_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned int status;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+
+ /* Prevent race with das1800_ai_poll() on multi processor systems.
+ * Also protects indirect addressing in das1800_ai_handler */
+ spin_lock(&dev->spinlock);
+ status = inb(dev->iobase + DAS1800_STATUS);
+
+ /* if interrupt was not caused by das-1800 */
+ if (!(status & INT)) {
+ spin_unlock(&dev->spinlock);
+ return IRQ_NONE;
+ }
+ /* clear the interrupt status bit INT */
+ outb(CLEAR_INTR_MASK & ~INT, dev->iobase + DAS1800_STATUS);
+ // handle interrupt
+ das1800_ai_handler(dev);
+
+ spin_unlock(&dev->spinlock);
+ return IRQ_HANDLED;
+}
+
+// the guts of the interrupt handler, that is shared with das1800_ai_poll
+static void das1800_ai_handler(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + 0; /* analog input subdevice */
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned int status = inb(dev->iobase + DAS1800_STATUS);
+
+ async->events = 0;
+ // select adc for base address + 0
+ outb(ADC, dev->iobase + DAS1800_SELECT);
+ // dma buffer full
+ if (devpriv->irq_dma_bits & DMA_ENABLED) {
+ // look for data from dma transfer even if dma terminal count hasn't happened yet
+ das1800_handle_dma(dev, s, status);
+ } else if (status & FHF) { // if fifo half full
+ das1800_handle_fifo_half_full(dev, s);
+ } else if (status & FNE) { // if fifo not empty
+ das1800_handle_fifo_not_empty(dev, s);
+ }
+
+ async->events |= COMEDI_CB_BLOCK;
+ /* if the card's fifo has overflowed */
+ if (status & OVF) {
+ // clear OVF interrupt bit
+ outb(CLEAR_INTR_MASK & ~OVF, dev->iobase + DAS1800_STATUS);
+ comedi_error(dev, "DAS1800 FIFO overflow");
+ das1800_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return;
+ }
+ // stop taking data if appropriate
+ /* stop_src TRIG_EXT */
+ if (status & CT0TC) {
+ // clear CT0TC interrupt bit
+ outb(CLEAR_INTR_MASK & ~CT0TC, dev->iobase + DAS1800_STATUS);
+ // make sure we get all remaining data from board before quitting
+ if (devpriv->irq_dma_bits & DMA_ENABLED)
+ das1800_flush_dma(dev, s);
+ else
+ das1800_handle_fifo_not_empty(dev, s);
+ das1800_cancel(dev, s); /* disable hardware conversions */
+ async->events |= COMEDI_CB_EOA;
+ } else if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0) { // stop_src TRIG_COUNT
+ das1800_cancel(dev, s); /* disable hardware conversions */
+ async->events |= COMEDI_CB_EOA;
+ }
+
+ comedi_event(dev, s);
+
+ return;
+}
+
+static void das1800_handle_dma(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int status)
+{
+ unsigned long flags;
+ const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+ flags = claim_dma_lock();
+ das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+ devpriv->dma_current_buf);
+ // re-enable dma channel
+ set_dma_addr(devpriv->dma_current,
+ virt_to_bus(devpriv->dma_current_buf));
+ set_dma_count(devpriv->dma_current, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_current);
+ release_dma_lock(flags);
+
+ if (status & DMATC) {
+ // clear DMATC interrupt bit
+ outb(CLEAR_INTR_MASK & ~DMATC, dev->iobase + DAS1800_STATUS);
+ // switch dma channels for next time, if appropriate
+ if (dual_dma) {
+ // read data from the other channel next time
+ if (devpriv->dma_current == devpriv->dma0) {
+ devpriv->dma_current = devpriv->dma1;
+ devpriv->dma_current_buf = devpriv->ai_buf1;
+ } else {
+ devpriv->dma_current = devpriv->dma0;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ }
+ }
+ }
+
+ return;
+}
+
+static inline uint16_t munge_bipolar_sample(const struct comedi_device * dev,
+ uint16_t sample)
+{
+ sample += 1 << (thisboard->resolution - 1);
+ return sample;
+}
+
+static void munge_data(struct comedi_device * dev, uint16_t * array,
+ unsigned int num_elements)
+{
+ unsigned int i;
+ int unipolar;
+
+ /* see if card is using a unipolar or bipolar range so we can munge data correctly */
+ unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
+
+ /* convert to unsigned type if we are in a bipolar mode */
+ if (!unipolar) {
+ for (i = 0; i < num_elements; i++) {
+ array[i] = munge_bipolar_sample(dev, array[i]);
+ }
+ }
+}
+
+/* Utility function used by das1800_flush_dma() and das1800_handle_dma().
+ * Assumes dma lock is held */
+static void das1800_flush_dma_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int channel, uint16_t * buffer)
+{
+ unsigned int num_bytes, num_samples;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ disable_dma(channel);
+
+ /* clear flip-flop to make sure 2-byte registers
+ * get set correctly */
+ clear_dma_ff(channel);
+
+ // figure out how many points to read
+ num_bytes = devpriv->dma_transfer_size - get_dma_residue(channel);
+ num_samples = num_bytes / sizeof(short);
+
+ /* if we only need some of the points */
+ if (cmd->stop_src == TRIG_COUNT && devpriv->count < num_samples)
+ num_samples = devpriv->count;
+
+ munge_data(dev, buffer, num_samples);
+ cfc_write_array_to_buffer(s, buffer, num_bytes);
+ if (s->async->cmd.stop_src == TRIG_COUNT)
+ devpriv->count -= num_samples;
+
+ return;
+}
+
+/* flushes remaining data from board when external trigger has stopped aquisition
+ * and we are using dma transfers */
+static void das1800_flush_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+ flags = claim_dma_lock();
+ das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+ devpriv->dma_current_buf);
+
+ if (dual_dma) {
+ // switch to other channel and flush it
+ if (devpriv->dma_current == devpriv->dma0) {
+ devpriv->dma_current = devpriv->dma1;
+ devpriv->dma_current_buf = devpriv->ai_buf1;
+ } else {
+ devpriv->dma_current = devpriv->dma0;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ }
+ das1800_flush_dma_channel(dev, s, devpriv->dma_current,
+ devpriv->dma_current_buf);
+ }
+
+ release_dma_lock(flags);
+
+ // get any remaining samples in fifo
+ das1800_handle_fifo_not_empty(dev, s);
+
+ return;
+}
+
+static void das1800_handle_fifo_half_full(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ int numPoints = 0; /* number of points to read */
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ numPoints = FIFO_SIZE / 2;
+ /* if we only need some of the points */
+ if (cmd->stop_src == TRIG_COUNT && devpriv->count < numPoints)
+ numPoints = devpriv->count;
+ insw(dev->iobase + DAS1800_FIFO, devpriv->ai_buf0, numPoints);
+ munge_data(dev, devpriv->ai_buf0, numPoints);
+ cfc_write_array_to_buffer(s, devpriv->ai_buf0,
+ numPoints * sizeof(devpriv->ai_buf0[0]));
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->count -= numPoints;
+ return;
+}
+
+static void das1800_handle_fifo_not_empty(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ short dpnt;
+ int unipolar;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ unipolar = inb(dev->iobase + DAS1800_CONTROL_C) & UB;
+
+ while (inb(dev->iobase + DAS1800_STATUS) & FNE) {
+ if (cmd->stop_src == TRIG_COUNT && devpriv->count == 0)
+ break;
+ dpnt = inw(dev->iobase + DAS1800_FIFO);
+ /* convert to unsigned type if we are in a bipolar mode */
+ if (!unipolar) ;
+ dpnt = munge_bipolar_sample(dev, dpnt);
+ cfc_write_to_buffer(s, dpnt);
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->count--;
+ }
+
+ return;
+}
+
+static int das1800_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ outb(0x0, dev->iobase + DAS1800_STATUS); /* disable conversions */
+ outb(0x0, dev->iobase + DAS1800_CONTROL_B); /* disable interrupts and dma */
+ outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* disable and clear fifo and stop triggering */
+ if (devpriv->dma0)
+ disable_dma(devpriv->dma0);
+ if (devpriv->dma1)
+ disable_dma(devpriv->dma1);
+ return 0;
+}
+
+/* test analog input cmd */
+static int das1800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ unsigned int tmp_arg;
+ int i;
+ int unipolar;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_EXT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_EXT)
+ err++;
+ //compatibility check
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->convert_src != TRIG_TIMER)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ // if we are not in burst mode
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ tmp_arg = cmd->convert_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd->convert_arg),
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp_arg != cmd->convert_arg)
+ err++;
+ }
+ // if we are in burst mode
+ else {
+ // check that convert_arg is compatible
+ tmp_arg = cmd->convert_arg;
+ cmd->convert_arg =
+ burst_convert_arg(cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp_arg != cmd->convert_arg)
+ err++;
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ // if scans are timed faster than conversion rate allows
+ if (cmd->convert_arg * cmd->chanlist_len >
+ cmd->scan_begin_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg *
+ cmd->chanlist_len;
+ err++;
+ }
+ tmp_arg = cmd->scan_begin_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1),
+ &(devpriv->divisor2),
+ &(cmd->scan_begin_arg),
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp_arg != cmd->scan_begin_arg)
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 4;
+
+ // make sure user is not trying to mix unipolar and bipolar ranges
+ if (cmd->chanlist) {
+ unipolar = CR_RANGE(cmd->chanlist[0]) & UNIPOLAR;
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (unipolar != (CR_RANGE(cmd->chanlist[i]) & UNIPOLAR)) {
+ comedi_error(dev,
+ "unipolar and bipolar ranges cannot be mixed in the chanlist");
+ err++;
+ break;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+/* analog input cmd interface */
+
+// first, some utility functions used in the main ai_do_cmd()
+
+// returns appropriate bits for control register a, depending on command
+static int control_a_bits(struct comedi_cmd cmd)
+{
+ int control_a;
+
+ control_a = FFEN; //enable fifo
+ if (cmd.stop_src == TRIG_EXT) {
+ control_a |= ATEN;
+ }
+ switch (cmd.start_src) {
+ case TRIG_EXT:
+ control_a |= TGEN | CGSL;
+ break;
+ case TRIG_NOW:
+ control_a |= CGEN;
+ break;
+ default:
+ break;
+ }
+
+ return control_a;
+}
+
+// returns appropriate bits for control register c, depending on command
+static int control_c_bits(struct comedi_cmd cmd)
+{
+ int control_c;
+ int aref;
+
+ /* set clock source to internal or external, select analog reference,
+ * select unipolar / bipolar
+ */
+ aref = CR_AREF(cmd.chanlist[0]);
+ control_c = UQEN; //enable upper qram addresses
+ if (aref != AREF_DIFF)
+ control_c |= SD;
+ if (aref == AREF_COMMON)
+ control_c |= CMEN;
+ /* if a unipolar range was selected */
+ if (CR_RANGE(cmd.chanlist[0]) & UNIPOLAR)
+ control_c |= UB;
+ switch (cmd.scan_begin_src) {
+ case TRIG_FOLLOW: // not in burst mode
+ switch (cmd.convert_src) {
+ case TRIG_TIMER:
+ /* trig on cascaded counters */
+ control_c |= IPCLK;
+ break;
+ case TRIG_EXT:
+ /* trig on falling edge of external trigger */
+ control_c |= XPCLK;
+ break;
+ default:
+ break;
+ }
+ break;
+ case TRIG_TIMER:
+ // burst mode with internal pacer clock
+ control_c |= BMDE | IPCLK;
+ break;
+ case TRIG_EXT:
+ // burst mode with external trigger
+ control_c |= BMDE | XPCLK;
+ break;
+ default:
+ break;
+ }
+
+ return control_c;
+}
+
+// sets up counters
+static int setup_counters(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+ // setup cascaded counters for conversion/scan frequency
+ switch (cmd.scan_begin_src) {
+ case TRIG_FOLLOW: // not in burst mode
+ if (cmd.convert_src == TRIG_TIMER) {
+ /* set conversion frequency */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &(devpriv->divisor1), &(devpriv->divisor2),
+ &(cmd.convert_arg),
+ cmd.flags & TRIG_ROUND_MASK);
+ if (das1800_set_frequency(dev) < 0) {
+ return -1;
+ }
+ }
+ break;
+ case TRIG_TIMER: // in burst mode
+ /* set scan frequency */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), &(cmd.scan_begin_arg),
+ cmd.flags & TRIG_ROUND_MASK);
+ if (das1800_set_frequency(dev) < 0) {
+ return -1;
+ }
+ break;
+ default:
+ break;
+ }
+
+ // setup counter 0 for 'about triggering'
+ if (cmd.stop_src == TRIG_EXT) {
+ // load counter 0 in mode 0
+ i8254_load(dev->iobase + DAS1800_COUNTER, 0, 0, 1, 0);
+ }
+
+ return 0;
+}
+
+// sets up dma
+static void setup_dma(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+ unsigned long lock_flags;
+ const int dual_dma = devpriv->irq_dma_bits & DMA_DUAL;
+
+ if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
+ return;
+
+ /* determine a reasonable dma transfer size */
+ devpriv->dma_transfer_size = suggest_transfer_size(&cmd);
+ lock_flags = claim_dma_lock();
+ disable_dma(devpriv->dma0);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma0);
+ set_dma_addr(devpriv->dma0, virt_to_bus(devpriv->ai_buf0));
+ // set appropriate size of transfer
+ set_dma_count(devpriv->dma0, devpriv->dma_transfer_size);
+ devpriv->dma_current = devpriv->dma0;
+ devpriv->dma_current_buf = devpriv->ai_buf0;
+ enable_dma(devpriv->dma0);
+ // set up dual dma if appropriate
+ if (dual_dma) {
+ disable_dma(devpriv->dma1);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma1);
+ set_dma_addr(devpriv->dma1, virt_to_bus(devpriv->ai_buf1));
+ // set appropriate size of transfer
+ set_dma_count(devpriv->dma1, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma1);
+ }
+ release_dma_lock(lock_flags);
+
+ return;
+}
+
+// programs channel/gain list into card
+static void program_chanlist(struct comedi_device * dev, struct comedi_cmd cmd)
+{
+ int i, n, chan_range;
+ unsigned long irq_flags;
+ const int range_mask = 0x3; //masks unipolar/bipolar bit off range
+ const int range_bitshift = 8;
+
+ n = cmd.chanlist_len;
+ // spinlock protects indirect addressing
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
+ outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*set QRAM address start */
+ /* make channel / gain list */
+ for (i = 0; i < n; i++) {
+ chan_range =
+ CR_CHAN(cmd.chanlist[i]) | ((CR_RANGE(cmd.
+ chanlist[i]) & range_mask) <<
+ range_bitshift);
+ outw(chan_range, dev->iobase + DAS1800_QRAM);
+ }
+ outb(n - 1, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return;
+}
+
+// analog input do_cmd
+static int das1800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int ret;
+ int control_a, control_c;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd cmd = async->cmd;
+
+ if (!dev->irq) {
+ comedi_error(dev,
+ "no irq assigned for das-1800, cannot do hardware conversions");
+ return -1;
+ }
+
+ /* disable dma on TRIG_WAKE_EOS, or TRIG_RT
+ * (because dma in handler is unsafe at hard real-time priority) */
+ if (cmd.flags & (TRIG_WAKE_EOS | TRIG_RT)) {
+ devpriv->irq_dma_bits &= ~DMA_ENABLED;
+ } else {
+ devpriv->irq_dma_bits |= devpriv->dma_bits;
+ }
+ // interrupt on end of conversion for TRIG_WAKE_EOS
+ if (cmd.flags & TRIG_WAKE_EOS) {
+ // interrupt fifo not empty
+ devpriv->irq_dma_bits &= ~FIMD;
+ } else {
+ // interrupt fifo half full
+ devpriv->irq_dma_bits |= FIMD;
+ }
+ // determine how many conversions we need
+ if (cmd.stop_src == TRIG_COUNT) {
+ devpriv->count = cmd.stop_arg * cmd.chanlist_len;
+ }
+
+ das1800_cancel(dev, s);
+
+ // determine proper bits for control registers
+ control_a = control_a_bits(cmd);
+ control_c = control_c_bits(cmd);
+
+ /* setup card and start */
+ program_chanlist(dev, cmd);
+ ret = setup_counters(dev, cmd);
+ if (ret < 0) {
+ comedi_error(dev, "Error setting up counters");
+ return ret;
+ }
+ setup_dma(dev, cmd);
+ outb(control_c, dev->iobase + DAS1800_CONTROL_C);
+ // set conversion rate and length for burst mode
+ if (control_c & BMDE) {
+ // program conversion period with number of microseconds minus 1
+ outb(cmd.convert_arg / 1000 - 1,
+ dev->iobase + DAS1800_BURST_RATE);
+ outb(cmd.chanlist_len - 1, dev->iobase + DAS1800_BURST_LENGTH);
+ }
+ outb(devpriv->irq_dma_bits, dev->iobase + DAS1800_CONTROL_B); // enable irq/dma
+ outb(control_a, dev->iobase + DAS1800_CONTROL_A); /* enable fifo and triggering */
+ outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
+
+ return 0;
+}
+
+/* read analog input */
+static int das1800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan, range, aref, chan_range;
+ int timeout = 1000;
+ short dpnt;
+ int conv_flags = 0;
+ unsigned long irq_flags;
+
+ /* set up analog reference and unipolar / bipolar mode */
+ aref = CR_AREF(insn->chanspec);
+ conv_flags |= UQEN;
+ if (aref != AREF_DIFF)
+ conv_flags |= SD;
+ if (aref == AREF_COMMON)
+ conv_flags |= CMEN;
+ /* if a unipolar range was selected */
+ if (CR_RANGE(insn->chanspec) & UNIPOLAR)
+ conv_flags |= UB;
+
+ outb(conv_flags, dev->iobase + DAS1800_CONTROL_C); /* software conversion enabled */
+ outb(CVEN, dev->iobase + DAS1800_STATUS); /* enable conversions */
+ outb(0x0, dev->iobase + DAS1800_CONTROL_A); /* reset fifo */
+ outb(FFEN, dev->iobase + DAS1800_CONTROL_A);
+
+ chan = CR_CHAN(insn->chanspec);
+ /* mask of unipolar/bipolar bit from range */
+ range = CR_RANGE(insn->chanspec) & 0x3;
+ chan_range = chan | (range << 8);
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(QRAM, dev->iobase + DAS1800_SELECT); /* select QRAM for baseAddress + 0x0 */
+ outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /* set QRAM address start */
+ outw(chan_range, dev->iobase + DAS1800_QRAM);
+ outb(0x0, dev->iobase + DAS1800_QRAM_ADDRESS); /*finish write to QRAM */
+ outb(ADC, dev->iobase + DAS1800_SELECT); /* select ADC for baseAddress + 0x0 */
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outb(0, dev->iobase + DAS1800_FIFO);
+ for (i = 0; i < timeout; i++) {
+ if (inb(dev->iobase + DAS1800_STATUS) & FNE)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ dpnt = inw(dev->iobase + DAS1800_FIFO);
+ /* shift data to offset binary for bipolar ranges */
+ if ((conv_flags & UB) == 0)
+ dpnt += 1 << (thisboard->resolution - 1);
+ data[n] = dpnt;
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return n;
+}
+
+/* writes to an analog output channel */
+static int das1800_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+// int range = CR_RANGE(insn->chanspec);
+ int update_chan = thisboard->ao_n_chan - 1;
+ short output;
+ unsigned long irq_flags;
+
+ // card expects two's complement data
+ output = data[0] - (1 << (thisboard->resolution - 1));
+ // if the write is to the 'update' channel, we need to remember its value
+ if (chan == update_chan)
+ devpriv->ao_update_bits = output;
+ // write to channel
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(DAC(chan), dev->iobase + DAS1800_SELECT); /* select dac channel for baseAddress + 0x0 */
+ outw(output, dev->iobase + DAS1800_DAC);
+ // now we need to write to 'update' channel to update all dac channels
+ if (chan != update_chan) {
+ outb(DAC(update_chan), dev->iobase + DAS1800_SELECT); /* select 'update' channel for baseAddress + 0x0 */
+ outw(devpriv->ao_update_bits, dev->iobase + DAS1800_DAC);
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return 1;
+}
+
+/* reads from digital input channels */
+static int das1800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ data[1] = inb(dev->iobase + DAS1800_DIGITAL) & 0xf;
+ data[0] = 0;
+
+ return 2;
+}
+
+/* writes to digital output channels */
+static int das1800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int wbits;
+
+ // only set bits that have been masked
+ data[0] &= (1 << s->n_chan) - 1;
+ wbits = devpriv->do_bits;
+ wbits &= ~data[0];
+ wbits |= data[0] & data[1];
+ devpriv->do_bits = wbits;
+
+ outb(devpriv->do_bits, dev->iobase + DAS1800_DIGITAL);
+
+ data[1] = devpriv->do_bits;
+
+ return 2;
+}
+
+/* loads counters with divisor1, divisor2 from private structure */
+static int das1800_set_frequency(struct comedi_device * dev)
+{
+ int err = 0;
+
+ // counter 1, mode 2
+ if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 1, devpriv->divisor1,
+ 2))
+ err++;
+ // counter 2, mode 2
+ if (i8254_load(dev->iobase + DAS1800_COUNTER, 0, 2, devpriv->divisor2,
+ 2))
+ err++;
+ if (err)
+ return -1;
+
+ return 0;
+}
+
+/* converts requested conversion timing to timing compatible with
+ * hardware, used only when card is in 'burst mode'
+ */
+static unsigned int burst_convert_arg(unsigned int convert_arg, int round_mode)
+{
+ unsigned int micro_sec;
+
+ // in burst mode, the maximum conversion time is 64 microseconds
+ if (convert_arg > 64000)
+ convert_arg = 64000;
+
+ // the conversion time must be an integral number of microseconds
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ micro_sec = (convert_arg + 500) / 1000;
+ break;
+ case TRIG_ROUND_DOWN:
+ micro_sec = convert_arg / 1000;
+ break;
+ case TRIG_ROUND_UP:
+ micro_sec = (convert_arg - 1) / 1000 + 1;
+ break;
+ }
+
+ // return number of nanoseconds
+ return micro_sec * 1000;
+}
+
+// utility function that suggests a dma transfer size based on the conversion period 'ns'
+static unsigned int suggest_transfer_size(struct comedi_cmd * cmd)
+{
+ unsigned int size = DMA_BUF_SIZE;
+ static const int sample_size = 2; // size in bytes of one sample from board
+ unsigned int fill_time = 300000000; // target time in nanoseconds for filling dma buffer
+ unsigned int max_size; // maximum size we will allow for a transfer
+
+ // make dma buffer fill in 0.3 seconds for timed modes
+ switch (cmd->scan_begin_src) {
+ case TRIG_FOLLOW: // not in burst mode
+ if (cmd->convert_src == TRIG_TIMER)
+ size = (fill_time / cmd->convert_arg) * sample_size;
+ break;
+ case TRIG_TIMER:
+ size = (fill_time / (cmd->scan_begin_arg * cmd->chanlist_len)) *
+ sample_size;
+ break;
+ default:
+ size = DMA_BUF_SIZE;
+ break;
+ }
+
+ // set a minimum and maximum size allowed
+ max_size = DMA_BUF_SIZE;
+ // if we are taking limited number of conversions, limit transfer size to that
+ if (cmd->stop_src == TRIG_COUNT &&
+ cmd->stop_arg * cmd->chanlist_len * sample_size < max_size)
+ max_size = cmd->stop_arg * cmd->chanlist_len * sample_size;
+
+ if (size > max_size)
+ size = max_size;
+ if (size < sample_size)
+ size = sample_size;
+
+ return size;
+}
diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c
new file mode 100644
index 00000000000..2a8ca052510
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das6402.c
@@ -0,0 +1,354 @@
+/*
+ Some comments on the code..
+
+ - it shouldn't be necessary to use outb_p().
+
+ - ignoreirq creates a race condition. It needs to be fixed.
+
+ */
+
+/*
+ comedi/drivers/das6402.c
+ An experimental driver for Computerboards' DAS6402 I/O card
+
+ Copyright (C) 1999 Oystein Svendsen <svendsen@pvv.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: das6402
+Description: Keithley Metrabyte DAS6402 (& compatibles)
+Author: Oystein Svendsen <svendsen@pvv.org>
+Status: bitrotten
+Devices: [Keithley Metrabyte] DAS6402 (das6402)
+
+This driver has suffered bitrot.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define DAS6402_SIZE 16
+
+#define N_WORDS 3000*64
+
+#define STOP 0
+#define START 1
+
+#define SCANL 0x3f00
+#define BYTE unsigned char
+#define WORD unsigned short
+
+/*----- register 8 ----*/
+#define CLRINT 0x01
+#define CLRXTR 0x02
+#define CLRXIN 0x04
+#define EXTEND 0x10
+#define ARMED 0x20 /* enable conting of post sample conv */
+#define POSTMODE 0x40
+#define MHZ 0x80 /* 10 MHz clock */
+/*---------------------*/
+
+/*----- register 9 ----*/
+#define IRQ (0x04 << 4) /* these two are */
+#define IRQV 10 /* dependent on each other */
+
+#define CONVSRC 0x03 /* trig src is Intarnal pacer */
+#define BURSTEN 0x04 /* enable burst */
+#define XINTE 0x08 /* use external int. trig */
+#define INTE 0x80 /* enable analog interrupts */
+/*---------------------*/
+
+/*----- register 10 ---*/
+#define TGEN 0x01 /* Use pin DI1 for externl trigging? */
+#define TGSEL 0x02 /* Use edge triggering */
+#define TGPOL 0x04 /* active edge is falling */
+#define PRETRIG 0x08 /* pretrig */
+/*---------------------*/
+
+/*----- register 11 ---*/
+#define EOB 0x0c
+#define FIFOHFULL 0x08
+#define GAIN 0x01
+#define FIFONEPTY 0x04
+#define MODE 0x10
+#define SEM 0x20
+#define BIP 0x40
+/*---------------------*/
+
+#define M0 0x00
+#define M2 0x04
+
+#define C0 0x00
+#define C1 0x40
+#define C2 0x80
+#define RWLH 0x30
+
+static int das6402_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das6402_detach(struct comedi_device * dev);
+static struct comedi_driver driver_das6402 = {
+ driver_name:"das6402",
+ module:THIS_MODULE,
+ attach:das6402_attach,
+ detach:das6402_detach,
+};
+
+COMEDI_INITCLEANUP(driver_das6402);
+
+struct das6402_private {
+ int ai_bytes_to_read;
+
+ int das6402_ignoreirq;
+};
+#define devpriv ((struct das6402_private *)dev->private)
+
+static void das6402_ai_fifo_dregs(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static void das6402_setcounter(struct comedi_device * dev)
+{
+ BYTE p;
+ unsigned short ctrlwrd;
+
+ /* set up counter0 first, mode 0 */
+ p = M0 | C0 | RWLH;
+ outb_p(p, dev->iobase + 15);
+ ctrlwrd = 2000;
+ p = (BYTE) (0xff & ctrlwrd);
+ outb_p(p, dev->iobase + 12);
+ p = (BYTE) (0xff & (ctrlwrd >> 8));
+ outb_p(p, dev->iobase + 12);
+
+ /* set up counter1, mode 2 */
+ p = M2 | C1 | RWLH;
+ outb_p(p, dev->iobase + 15);
+ ctrlwrd = 10;
+ p = (BYTE) (0xff & ctrlwrd);
+ outb_p(p, dev->iobase + 13);
+ p = (BYTE) (0xff & (ctrlwrd >> 8));
+ outb_p(p, dev->iobase + 13);
+
+ /* set up counter1, mode 2 */
+ p = M2 | C2 | RWLH;
+ outb_p(p, dev->iobase + 15);
+ ctrlwrd = 1000;
+ p = (BYTE) (0xff & ctrlwrd);
+ outb_p(p, dev->iobase + 14);
+ p = (BYTE) (0xff & (ctrlwrd >> 8));
+ outb_p(p, dev->iobase + 14);
+}
+
+static irqreturn_t intr_handler(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices;
+
+ if (!dev->attached || devpriv->das6402_ignoreirq) {
+ printk("das6402: BUG: spurious interrupt\n");
+ return IRQ_HANDLED;
+ }
+#ifdef DEBUG
+ printk("das6402: interrupt! das6402_irqcount=%i\n",
+ devpriv->das6402_irqcount);
+ printk("das6402: iobase+2=%i\n", inw_p(dev->iobase + 2));
+#endif
+
+ das6402_ai_fifo_dregs(dev, s);
+
+ if (s->async->buf_write_count >= devpriv->ai_bytes_to_read) {
+ outw_p(SCANL, dev->iobase + 2); /* clears the fifo */
+ outb(0x07, dev->iobase + 8); /* clears all flip-flops */
+#ifdef DEBUG
+ printk("das6402: Got %i samples\n\n",
+ devpriv->das6402_wordsread - diff);
+#endif
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ }
+
+ outb(0x01, dev->iobase + 8); /* clear only the interrupt flip-flop */
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+#if 0
+static void das6402_ai_fifo_read(struct comedi_device * dev, short * data, int n)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ data[i] = inw(dev->iobase);
+}
+#endif
+
+static void das6402_ai_fifo_dregs(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ while (1) {
+ if (!(inb(dev->iobase + 8) & 0x01))
+ return;
+ comedi_buf_put(s->async, inw(dev->iobase));
+ }
+}
+
+static int das6402_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /*
+ * This function should reset the board from whatever condition it
+ * is in (i.e., acquiring data), to a non-active state.
+ */
+
+ devpriv->das6402_ignoreirq = 1;
+#ifdef DEBUG
+ printk("das6402: Stopping acquisition\n");
+#endif
+ devpriv->das6402_ignoreirq = 1;
+ outb_p(0x02, dev->iobase + 10); /* disable external trigging */
+ outw_p(SCANL, dev->iobase + 2); /* resets the card fifo */
+ outb_p(0, dev->iobase + 9); /* disables interrupts */
+
+ outw_p(SCANL, dev->iobase + 2);
+
+ return 0;
+}
+
+#ifdef unused
+static int das6402_ai_mode2(struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ devpriv->das6402_ignoreirq = 1;
+
+#ifdef DEBUG
+ printk("das6402: Starting acquisition\n");
+#endif
+ outb_p(0x03, dev->iobase + 10); /* enable external trigging */
+ outw_p(SCANL, dev->iobase + 2); /* resets the card fifo */
+ outb_p(IRQ | CONVSRC | BURSTEN | INTE, dev->iobase + 9);
+
+ devpriv->ai_bytes_to_read = it->n * sizeof(short);
+
+ /* um... ignoreirq is a nasty race condition */
+ devpriv->das6402_ignoreirq = 0;
+
+ outw_p(SCANL, dev->iobase + 2);
+
+ return 0;
+}
+#endif
+
+static int board_init(struct comedi_device * dev)
+{
+ BYTE b;
+
+ devpriv->das6402_ignoreirq = 1;
+
+ outb(0x07, dev->iobase + 8);
+
+ /* register 11 */
+ outb_p(MODE, dev->iobase + 11);
+ b = BIP | SEM | MODE | GAIN | FIFOHFULL;
+ outb_p(b, dev->iobase + 11);
+
+ /* register 8 */
+ outb_p(EXTEND, dev->iobase + 8);
+ b = EXTEND | MHZ;
+ outb_p(b, dev->iobase + 8);
+ b = MHZ | CLRINT | CLRXTR | CLRXIN;
+ outb_p(b, dev->iobase + 8);
+
+ /* register 9 */
+ b = IRQ | CONVSRC | BURSTEN | INTE;
+ outb_p(b, dev->iobase + 9);
+
+ /* register 10 */
+ b = TGSEL | TGEN;
+ outb_p(b, dev->iobase + 10);
+
+ b = 0x07;
+ outb_p(b, dev->iobase + 8);
+
+ das6402_setcounter(dev);
+
+ outw_p(SCANL, dev->iobase + 2); /* reset card fifo */
+
+ devpriv->das6402_ignoreirq = 0;
+
+ return 0;
+}
+
+static int das6402_detach(struct comedi_device * dev)
+{
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, DAS6402_SIZE);
+
+ return 0;
+}
+
+static int das6402_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned int irq;
+ unsigned long iobase;
+ int ret;
+ struct comedi_subdevice *s;
+
+ dev->board_name = "das6402";
+
+ iobase = it->options[0];
+ if (iobase == 0)
+ iobase = 0x300;
+
+ printk("comedi%d: das6402: 0x%04lx", dev->minor, iobase);
+
+ if (!request_region(iobase, DAS6402_SIZE, "das6402")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* should do a probe here */
+
+ irq = it->options[0];
+ printk(" ( irq = %u )", irq);
+ ret = comedi_request_irq(irq, intr_handler, 0, "das6402", dev);
+ if (ret < 0) {
+ printk("irq conflict\n");
+ return ret;
+ }
+ dev->irq = irq;
+
+ if ((ret = alloc_private(dev, sizeof(struct das6402_private))) < 0)
+ return ret;
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+
+ /* ai subdevice */
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 8;
+ //s->trig[2]=das6402_ai_mode2;
+ s->cancel = das6402_ai_cancel;
+ s->maxdata = (1 << 12) - 1;
+ s->len_chanlist = 16; /* ? */
+ s->range_table = &range_unknown;
+
+ board_init(dev);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/das800.c b/drivers/staging/comedi/drivers/das800.c
new file mode 100644
index 00000000000..7a6656bf809
--- /dev/null
+++ b/drivers/staging/comedi/drivers/das800.c
@@ -0,0 +1,894 @@
+/*
+ comedi/drivers/das800.c
+ Driver for Keitley das800 series boards and compatibles
+ Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: das800
+Description: Keithley Metrabyte DAS800 (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [Keithley Metrabyte] DAS-800 (das-800), DAS-801 (das-801),
+ DAS-802 (das-802),
+ [Measurement Computing] CIO-DAS800 (cio-das800),
+ CIO-DAS801 (cio-das801), CIO-DAS802 (cio-das802),
+ CIO-DAS802/16 (cio-das802/16)
+Status: works, cio-das802/16 untested - email me if you have tested it
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed or externally triggered conversions)
+
+Notes:
+ IRQ can be omitted, although the cmd interface will not work without it.
+
+ All entries in the channel/gain list must use the same gain and be
+ consecutive channels counting upwards in channel number (these are
+ hardware limitations.)
+
+ I've never tested the gain setting stuff since I only have a
+ DAS-800 board with fixed gain.
+
+ The cio-das802/16 does not have a fifo-empty status bit! Therefore
+ only fifo-half-full transfers are possible with this card.
+*/
+/*
+
+cmd triggers supported:
+ start_src: TRIG_NOW | TRIG_EXT
+ scan_begin_src: TRIG_FOLLOW
+ scan_end_src: TRIG_COUNT
+ convert_src: TRIG_TIMER | TRIG_EXT
+ stop_src: TRIG_NONE | TRIG_COUNT
+
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define DAS800_SIZE 8
+#define TIMER_BASE 1000
+#define N_CHAN_AI 8 // number of analog input channels
+
+/* Registers for the das800 */
+
+#define DAS800_LSB 0
+#define FIFO_EMPTY 0x1
+#define FIFO_OVF 0x2
+#define DAS800_MSB 1
+#define DAS800_CONTROL1 2
+#define CONTROL1_INTE 0x8
+#define DAS800_CONV_CONTROL 2
+#define ITE 0x1
+#define CASC 0x2
+#define DTEN 0x4
+#define IEOC 0x8
+#define EACS 0x10
+#define CONV_HCEN 0x80
+#define DAS800_SCAN_LIMITS 2
+#define DAS800_STATUS 2
+#define IRQ 0x8
+#define BUSY 0x80
+#define DAS800_GAIN 3
+#define CIO_FFOV 0x8 // fifo overflow for cio-das802/16
+#define CIO_ENHF 0x90 // interrupt fifo half full for cio-das802/16
+#define CONTROL1 0x80
+#define CONV_CONTROL 0xa0
+#define SCAN_LIMITS 0xc0
+#define ID 0xe0
+#define DAS800_8254 4
+#define DAS800_STATUS2 7
+#define STATUS2_HCEN 0x80
+#define STATUS2_INTE 0X20
+#define DAS800_ID 7
+
+struct das800_board {
+ const char *name;
+ int ai_speed;
+ const struct comedi_lrange *ai_range;
+ int resolution;
+};
+
+//analog input ranges
+static const struct comedi_lrange range_das800_ai = {
+ 1,
+ {
+ RANGE(-5, 5),
+ }
+};
+
+static const struct comedi_lrange range_das801_ai = {
+ 9,
+ {
+ RANGE(-5, 5),
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-0.5, 0.5),
+ RANGE(0, 1),
+ RANGE(-0.05, 0.05),
+ RANGE(0, 0.1),
+ RANGE(-0.01, 0.01),
+ RANGE(0, 0.02),
+ }
+};
+
+static const struct comedi_lrange range_cio_das801_ai = {
+ 9,
+ {
+ RANGE(-5, 5),
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-0.5, 0.5),
+ RANGE(0, 1),
+ RANGE(-0.05, 0.05),
+ RANGE(0, 0.1),
+ RANGE(-0.005, 0.005),
+ RANGE(0, 0.01),
+ }
+};
+
+static const struct comedi_lrange range_das802_ai = {
+ 9,
+ {
+ RANGE(-5, 5),
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-2.5, 2.5),
+ RANGE(0, 5),
+ RANGE(-1.25, 1.25),
+ RANGE(0, 2.5),
+ RANGE(-0.625, 0.625),
+ RANGE(0, 1.25),
+ }
+};
+
+static const struct comedi_lrange range_das80216_ai = {
+ 8,
+ {
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE(-5, 5),
+ RANGE(0, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(0, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(0, 1.25),
+ }
+};
+
+enum { das800, ciodas800, das801, ciodas801, das802, ciodas802, ciodas80216 };
+
+static const struct das800_board das800_boards[] = {
+ {
+ name: "das-800",
+ ai_speed:25000,
+ ai_range:&range_das800_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das800",
+ ai_speed:20000,
+ ai_range:&range_das800_ai,
+ resolution:12,
+ },
+ {
+ name: "das-801",
+ ai_speed:25000,
+ ai_range:&range_das801_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das801",
+ ai_speed:20000,
+ ai_range:&range_cio_das801_ai,
+ resolution:12,
+ },
+ {
+ name: "das-802",
+ ai_speed:25000,
+ ai_range:&range_das802_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das802",
+ ai_speed:20000,
+ ai_range:&range_das802_ai,
+ resolution:12,
+ },
+ {
+ name: "cio-das802/16",
+ ai_speed:10000,
+ ai_range:&range_das80216_ai,
+ resolution:16,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct das800_board *)dev->board_ptr)
+
+struct das800_private {
+ volatile unsigned int count; /* number of data points left to be taken */
+ volatile int forever; /* flag indicating whether we should take data forever */
+ unsigned int divisor1; /* value to load into board's counter 1 for timed conversions */
+ unsigned int divisor2; /* value to load into board's counter 2 for timed conversions */
+ volatile int do_bits; /* digital output bits */
+};
+
+#define devpriv ((struct das800_private *)dev->private)
+
+static int das800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int das800_detach(struct comedi_device * dev);
+static int das800_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_das800 = {
+ driver_name:"das800",
+ module:THIS_MODULE,
+ attach:das800_attach,
+ detach:das800_detach,
+ num_names:sizeof(das800_boards) / sizeof(struct das800_board),
+ board_name:&das800_boards[0].name,
+ offset:sizeof(struct das800_board),
+};
+
+static irqreturn_t das800_interrupt(int irq, void *d PT_REGS_ARG);
+static void enable_das800(struct comedi_device * dev);
+static void disable_das800(struct comedi_device * dev);
+static int das800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int das800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int das800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int das800_probe(struct comedi_device * dev);
+static int das800_set_frequency(struct comedi_device * dev);
+
+/* checks and probes das-800 series board type */
+static int das800_probe(struct comedi_device * dev)
+{
+ int id_bits;
+ unsigned long irq_flags;
+ int board;
+
+ // 'comedi spin lock irqsave' disables even rt interrupts, we use them to protect indirect addressing
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(ID, dev->iobase + DAS800_GAIN); /* select base address + 7 to be ID register */
+ id_bits = inb(dev->iobase + DAS800_ID) & 0x3; /* get id bits */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ board = thisboard - das800_boards;
+
+ switch (id_bits) {
+ case 0x0:
+ if (board == das800) {
+ printk(" Board model: DAS-800\n");
+ return board;
+ }
+ if (board == ciodas800) {
+ printk(" Board model: CIO-DAS800\n");
+ return board;
+ }
+ printk(" Board model (probed): DAS-800\n");
+ return das800;
+ break;
+ case 0x2:
+ if (board == das801) {
+ printk(" Board model: DAS-801\n");
+ return board;
+ }
+ if (board == ciodas801) {
+ printk(" Board model: CIO-DAS801\n");
+ return board;
+ }
+ printk(" Board model (probed): DAS-801\n");
+ return das801;
+ break;
+ case 0x3:
+ if (board == das802) {
+ printk(" Board model: DAS-802\n");
+ return board;
+ }
+ if (board == ciodas802) {
+ printk(" Board model: CIO-DAS802\n");
+ return board;
+ }
+ if (board == ciodas80216) {
+ printk(" Board model: CIO-DAS802/16\n");
+ return board;
+ }
+ printk(" Board model (probed): DAS-802\n");
+ return das802;
+ break;
+ default:
+ printk(" Board model: probe returned 0x%x (unknown)\n",
+ id_bits);
+ return board;
+ break;
+ }
+ return -1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_das800);
+
+/* interrupt service routine */
+static irqreturn_t das800_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ short i; /* loop index */
+ short dataPoint = 0;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev; /* analog input subdevice */
+ struct comedi_async *async;
+ int status;
+ unsigned long irq_flags;
+ static const int max_loops = 128; // half-fifo size for cio-das802/16
+ // flags
+ int fifo_empty = 0;
+ int fifo_overflow = 0;
+
+ status = inb(dev->iobase + DAS800_STATUS);
+ /* if interrupt was not generated by board or driver not attached, quit */
+ if (!(status & IRQ))
+ return IRQ_NONE;
+ if (!(dev->attached))
+ return IRQ_HANDLED;
+
+ /* wait until here to initialize async, since we will get null dereference
+ * if interrupt occurs before driver is fully attached!
+ */
+ async = s->async;
+
+ // if hardware conversions are not enabled, then quit
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select base address + 7 to be STATUS2 register */
+ status = inb(dev->iobase + DAS800_STATUS2) & STATUS2_HCEN;
+ /* don't release spinlock yet since we want to make sure noone else disables hardware conversions */
+ if (status == 0) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ return IRQ_HANDLED;
+ }
+
+ /* loop while card's fifo is not empty (and limit to half fifo for cio-das802/16) */
+ for (i = 0; i < max_loops; i++) {
+ /* read 16 bits from dev->iobase and dev->iobase + 1 */
+ dataPoint = inb(dev->iobase + DAS800_LSB);
+ dataPoint += inb(dev->iobase + DAS800_MSB) << 8;
+ if (thisboard->resolution == 12) {
+ fifo_empty = dataPoint & FIFO_EMPTY;
+ fifo_overflow = dataPoint & FIFO_OVF;
+ if (fifo_overflow)
+ break;
+ } else {
+ fifo_empty = 0; // cio-das802/16 has no fifo empty status bit
+ }
+ if (fifo_empty) {
+ break;
+ }
+ /* strip off extraneous bits for 12 bit cards */
+ if (thisboard->resolution == 12)
+ dataPoint = (dataPoint >> 4) & 0xfff;
+ /* if there are more data points to collect */
+ if (devpriv->count > 0 || devpriv->forever == 1) {
+ /* write data point to buffer */
+ cfc_write_to_buffer(s, dataPoint);
+ if (devpriv->count > 0)
+ devpriv->count--;
+ }
+ }
+ async->events |= COMEDI_CB_BLOCK;
+ /* check for fifo overflow */
+ if (thisboard->resolution == 12) {
+ fifo_overflow = dataPoint & FIFO_OVF;
+ // else cio-das802/16
+ } else {
+ fifo_overflow = inb(dev->iobase + DAS800_GAIN) & CIO_FFOV;
+ }
+ if (fifo_overflow) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ comedi_error(dev, "DAS800 FIFO overflow");
+ das800_cancel(dev, dev->subdevices + 0);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ async->events = 0;
+ return IRQ_HANDLED;
+ }
+ if (devpriv->count > 0 || devpriv->forever == 1) {
+ /* Re-enable card's interrupt.
+ * We already have spinlock, so indirect addressing is safe */
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(CONTROL1_INTE | devpriv->do_bits,
+ dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ /* otherwise, stop taking data */
+ } else {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ disable_das800(dev); /* diable hardware triggered conversions */
+ async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ async->events = 0;
+ return IRQ_HANDLED;
+}
+
+static int das800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = it->options[0];
+ unsigned int irq = it->options[1];
+ unsigned long irq_flags;
+ int board;
+
+ printk("comedi%d: das800: io 0x%lx", dev->minor, iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+ printk("\n");
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct das800_private)) < 0)
+ return -ENOMEM;
+
+ if (iobase == 0) {
+ printk("io base address required for das800\n");
+ return -EINVAL;
+ }
+
+ /* check if io addresses are available */
+ if (!request_region(iobase, DAS800_SIZE, "das800")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ board = das800_probe(dev);
+ if (board < 0) {
+ printk("unable to determine board type\n");
+ return -ENODEV;
+ }
+ dev->board_ptr = das800_boards + board;
+
+ /* grab our IRQ */
+ if (irq == 1 || irq > 7) {
+ printk("irq out of range\n");
+ return -EINVAL;
+ }
+ if (irq) {
+ if (comedi_request_irq(irq, das800_interrupt, 0, "das800", dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = irq;
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+ s->n_chan = 8;
+ s->len_chanlist = 8;
+ s->maxdata = (1 << thisboard->resolution) - 1;
+ s->range_table = thisboard->ai_range;
+ s->do_cmd = das800_ai_do_cmd;
+ s->do_cmdtest = das800_ai_do_cmdtest;
+ s->insn_read = das800_ai_rinsn;
+ s->cancel = das800_cancel;
+
+ /* di */
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 3;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das800_di_rbits;
+
+ /* do */
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 4;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = das800_do_wbits;
+
+ disable_das800(dev);
+
+ /* initialize digital out channels */
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ return 0;
+};
+
+static int das800_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: das800: remove\n", dev->minor);
+
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase)
+ release_region(dev->iobase, DAS800_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ return 0;
+};
+
+static int das800_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->forever = 0;
+ devpriv->count = 0;
+ disable_das800(dev);
+ return 0;
+}
+
+/* enable_das800 makes the card start taking hardware triggered conversions */
+static void enable_das800(struct comedi_device * dev)
+{
+ unsigned long irq_flags;
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ // enable fifo-half full interrupts for cio-das802/16
+ if (thisboard->resolution == 16)
+ outb(CIO_ENHF, dev->iobase + DAS800_GAIN);
+ outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
+ outb(CONV_HCEN, dev->iobase + DAS800_CONV_CONTROL); /* enable hardware triggering */
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(CONTROL1_INTE | devpriv->do_bits, dev->iobase + DAS800_CONTROL1); /* enable card's interrupt */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+}
+
+/* disable_das800 stops hardware triggered conversions */
+static void disable_das800(struct comedi_device * dev)
+{
+ unsigned long irq_flags;
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
+ outb(0x0, dev->iobase + DAS800_CONV_CONTROL); /* disable hardware triggering of conversions */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+}
+
+static int das800_ai_do_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int gain, startChan;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ /* calculate counter values that give desired timing */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), &(cmd->convert_arg),
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ startChan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (startChan + i) % N_CHAN_AI) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int das800_ai_do_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int startChan, endChan, scan, gain;
+ int conv_bits;
+ unsigned long irq_flags;
+ struct comedi_async *async = s->async;
+
+ if (!dev->irq) {
+ comedi_error(dev,
+ "no irq assigned for das-800, cannot do hardware conversions");
+ return -1;
+ }
+
+ disable_das800(dev);
+
+ /* set channel scan limits */
+ startChan = CR_CHAN(async->cmd.chanlist[0]);
+ endChan = (startChan + async->cmd.chanlist_len - 1) % 8;
+ scan = (endChan << 3) | startChan;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(SCAN_LIMITS, dev->iobase + DAS800_GAIN); /* select base address + 2 to be scan limits register */
+ outb(scan, dev->iobase + DAS800_SCAN_LIMITS); /* set scan limits */
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ /* set gain */
+ gain = CR_RANGE(async->cmd.chanlist[0]);
+ if (thisboard->resolution == 12 && gain > 0)
+ gain += 0x7;
+ gain &= 0xf;
+ outb(gain, dev->iobase + DAS800_GAIN);
+
+ switch (async->cmd.stop_src) {
+ case TRIG_COUNT:
+ devpriv->count = async->cmd.stop_arg * async->cmd.chanlist_len;
+ devpriv->forever = 0;
+ break;
+ case TRIG_NONE:
+ devpriv->forever = 1;
+ devpriv->count = 0;
+ break;
+ default:
+ break;
+ }
+
+ /* enable auto channel scan, send interrupts on end of conversion
+ * and set clock source to internal or external
+ */
+ conv_bits = 0;
+ conv_bits |= EACS | IEOC;
+ if (async->cmd.start_src == TRIG_EXT)
+ conv_bits |= DTEN;
+ switch (async->cmd.convert_src) {
+ case TRIG_TIMER:
+ conv_bits |= CASC | ITE;
+ /* set conversion frequency */
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE, &(devpriv->divisor1),
+ &(devpriv->divisor2), &(async->cmd.convert_arg),
+ async->cmd.flags & TRIG_ROUND_MASK);
+ if (das800_set_frequency(dev) < 0) {
+ comedi_error(dev, "Error setting up counters");
+ return -1;
+ }
+ break;
+ case TRIG_EXT:
+ break;
+ default:
+ break;
+ }
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONV_CONTROL, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be conversion control register */
+ outb(conv_bits, dev->iobase + DAS800_CONV_CONTROL);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+ async->events = 0;
+ enable_das800(dev);
+ return 0;
+}
+
+static int das800_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan;
+ int range;
+ int lsb, msb;
+ int timeout = 1000;
+ unsigned long irq_flags;
+
+ disable_das800(dev); /* disable hardware conversions (enables software conversions) */
+
+ /* set multiplexer */
+ chan = CR_CHAN(insn->chanspec);
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(chan | devpriv->do_bits, dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ /* set gain / range */
+ range = CR_RANGE(insn->chanspec);
+ if (thisboard->resolution == 12 && range)
+ range += 0x7;
+ range &= 0xf;
+ outb(range, dev->iobase + DAS800_GAIN);
+
+ comedi_udelay(5);
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outb_p(0, dev->iobase + DAS800_MSB);
+
+ for (i = 0; i < timeout; i++) {
+ if (!(inb(dev->iobase + DAS800_STATUS) & BUSY))
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ lsb = inb(dev->iobase + DAS800_LSB);
+ msb = inb(dev->iobase + DAS800_MSB);
+ if (thisboard->resolution == 12) {
+ data[n] = (lsb >> 4) & 0xff;
+ data[n] |= (msb << 4);
+ } else {
+ data[n] = (msb << 8) | lsb;
+ }
+ }
+
+ return n;
+}
+
+static int das800_di_rbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bits;
+
+ bits = inb(dev->iobase + DAS800_STATUS) >> 4;
+ bits &= 0x7;
+ data[1] = bits;
+ data[0] = 0;
+
+ return 2;
+}
+
+static int das800_do_wbits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int wbits;
+ unsigned long irq_flags;
+
+ // only set bits that have been masked
+ data[0] &= 0xf;
+ wbits = devpriv->do_bits >> 4;
+ wbits &= ~data[0];
+ wbits |= data[0] & data[1];
+ devpriv->do_bits = wbits << 4;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, irq_flags);
+ outb(CONTROL1, dev->iobase + DAS800_GAIN); /* select dev->iobase + 2 to be control register 1 */
+ outb(devpriv->do_bits | CONTROL1_INTE, dev->iobase + DAS800_CONTROL1);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, irq_flags);
+
+ data[1] = wbits;
+
+ return 2;
+}
+
+/* loads counters with divisor1, divisor2 from private structure */
+static int das800_set_frequency(struct comedi_device * dev)
+{
+ int err = 0;
+
+ if (i8254_load(dev->iobase + DAS800_8254, 0, 1, devpriv->divisor1, 2))
+ err++;
+ if (i8254_load(dev->iobase + DAS800_8254, 0, 2, devpriv->divisor2, 2))
+ err++;
+ if (err)
+ return -1;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dmm32at.c b/drivers/staging/comedi/drivers/dmm32at.c
new file mode 100644
index 00000000000..829083651ed
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dmm32at.c
@@ -0,0 +1,1081 @@
+/*
+ comedi/drivers/dmm32at.c
+ Diamond Systems mm32at code for a Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dmm32at
+Description: Diamond Systems mm32at driver.
+Devices:
+Author: Perry J. Piplani <perry.j.piplani@nasa.gov>
+Updated: Fri Jun 4 09:13:24 CDT 2004
+Status: experimental
+
+This driver is for the Diamond Systems MM-32-AT board
+http://www.diamondsystems.com/products/diamondmm32at It is being used
+on serveral projects inside NASA, without problems so far. For analog
+input commands, TRIG_EXT is not yet supported at all..
+
+Configuration Options:
+ comedi_config /dev/comedi0 dmm32at baseaddr,irq
+*/
+
+/*
+ * The previous block comment is used to automatically generate
+ * documentation in Comedi and Comedilib. The fields:
+ *
+ * Driver: the name of the driver
+ * Description: a short phrase describing the driver. Don't list boards.
+ * Devices: a full list of the boards that attempt to be supported by
+ * the driver. Format is "(manufacturer) board name [comedi name]",
+ * where comedi_name is the name that is used to configure the board.
+ * See the comment near board_name: in the struct comedi_driver structure
+ * below. If (manufacturer) or [comedi name] is missing, the previous
+ * value is used.
+ * Author: you
+ * Updated: date when the _documentation_ was last updated. Use 'date -R'
+ * to get a value for this.
+ * Status: a one-word description of the status. Valid values are:
+ * works - driver works correctly on most boards supported, and
+ * passes comedi_test.
+ * unknown - unknown. Usually put there by ds.
+ * experimental - may not work in any particular release. Author
+ * probably wants assistance testing it.
+ * bitrotten - driver has not been update in a long time, probably
+ * doesn't work, and probably is missing support for significant
+ * Comedi interface features.
+ * untested - author probably wrote it "blind", and is believed to
+ * work, but no confirmation.
+ *
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver. The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+/* Board register addresses */
+
+#define DMM32AT_MEMSIZE 0x10
+
+#define DMM32AT_CONV 0x00
+#define DMM32AT_AILSB 0x00
+#define DMM32AT_AUXDOUT 0x01
+#define DMM32AT_AIMSB 0x01
+#define DMM32AT_AILOW 0x02
+#define DMM32AT_AIHIGH 0x03
+
+#define DMM32AT_DACLSB 0x04
+#define DMM32AT_DACSTAT 0x04
+#define DMM32AT_DACMSB 0x05
+
+#define DMM32AT_FIFOCNTRL 0x07
+#define DMM32AT_FIFOSTAT 0x07
+
+#define DMM32AT_CNTRL 0x08
+#define DMM32AT_AISTAT 0x08
+
+#define DMM32AT_INTCLOCK 0x09
+
+#define DMM32AT_CNTRDIO 0x0a
+
+#define DMM32AT_AICONF 0x0b
+#define DMM32AT_AIRBACK 0x0b
+
+#define DMM32AT_CLK1 0x0d
+#define DMM32AT_CLK2 0x0e
+#define DMM32AT_CLKCT 0x0f
+
+#define DMM32AT_DIOA 0x0c
+#define DMM32AT_DIOB 0x0d
+#define DMM32AT_DIOC 0x0e
+#define DMM32AT_DIOCONF 0x0f
+
+#define dmm_inb(cdev,reg) inb((cdev->iobase)+reg)
+#define dmm_outb(cdev,reg,valu) outb(valu,(cdev->iobase)+reg)
+
+/* Board register values. */
+
+/* DMM32AT_DACSTAT 0x04 */
+#define DMM32AT_DACBUSY 0x80
+
+/* DMM32AT_FIFOCNTRL 0x07 */
+#define DMM32AT_FIFORESET 0x02
+#define DMM32AT_SCANENABLE 0x04
+
+/* DMM32AT_CNTRL 0x08 */
+#define DMM32AT_RESET 0x20
+#define DMM32AT_INTRESET 0x08
+#define DMM32AT_CLKACC 0x00
+#define DMM32AT_DIOACC 0x01
+
+/* DMM32AT_AISTAT 0x08 */
+#define DMM32AT_STATUS 0x80
+
+/* DMM32AT_INTCLOCK 0x09 */
+#define DMM32AT_ADINT 0x80
+#define DMM32AT_CLKSEL 0x03
+
+/* DMM32AT_CNTRDIO 0x0a */
+#define DMM32AT_FREQ12 0x80
+
+/* DMM32AT_AICONF 0x0b */
+#define DMM32AT_RANGE_U10 0x0c
+#define DMM32AT_RANGE_U5 0x0d
+#define DMM32AT_RANGE_B10 0x08
+#define DMM32AT_RANGE_B5 0x00
+#define DMM32AT_SCINT_20 0x00
+#define DMM32AT_SCINT_15 0x10
+#define DMM32AT_SCINT_10 0x20
+#define DMM32AT_SCINT_5 0x30
+
+/* DMM32AT_CLKCT 0x0f */
+#define DMM32AT_CLKCT1 0x56 /* mode3 counter 1 - write low byte only */
+#define DMM32AT_CLKCT2 0xb6 /* mode3 counter 2 - write high and low byte */
+
+/* DMM32AT_DIOCONF 0x0f */
+#define DMM32AT_DIENABLE 0x80
+#define DMM32AT_DIRA 0x10
+#define DMM32AT_DIRB 0x02
+#define DMM32AT_DIRCL 0x01
+#define DMM32AT_DIRCH 0x08
+
+/* board AI ranges in comedi structure */
+static const struct comedi_lrange dmm32at_airanges = {
+ 4,
+ {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ }
+};
+
+/* register values for above ranges */
+static const unsigned char dmm32at_rangebits[] = {
+ DMM32AT_RANGE_U10,
+ DMM32AT_RANGE_U5,
+ DMM32AT_RANGE_B10,
+ DMM32AT_RANGE_B5,
+};
+
+/* only one of these ranges is valid, as set by a jumper on the
+ * board. The application should only use the range set by the jumper
+ */
+static const struct comedi_lrange dmm32at_aoranges = {
+ 4,
+ {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ }
+};
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct dmm32at_board {
+ const char *name;
+ int ai_chans;
+ int ai_bits;
+ const struct comedi_lrange *ai_ranges;
+ int ao_chans;
+ int ao_bits;
+ const struct comedi_lrange *ao_ranges;
+ int have_dio;
+ int dio_chans;
+};
+static const struct dmm32at_board dmm32at_boards[] = {
+ {
+ name: "dmm32at",
+ ai_chans:32,
+ ai_bits: 16,
+ ai_ranges:&dmm32at_airanges,
+ ao_chans:4,
+ ao_bits: 12,
+ ao_ranges:&dmm32at_aoranges,
+ have_dio:1,
+ dio_chans:24,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dmm32at_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ * several hardware drivers keep similar information in this structure,
+ * feel free to suggest moving the variable to the struct comedi_device struct.
+ */
+struct dmm32at_private {
+
+ int data;
+ int ai_inuse;
+ unsigned int ai_scans_left;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[4];
+ unsigned char dio_config;
+
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct dmm32at_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int dmm32at_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dmm32at_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dmm32at = {
+ driver_name:"dmm32at",
+ module:THIS_MODULE,
+ attach:dmm32at_attach,
+ detach:dmm32at_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+/* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in dmm32at_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&dmm32at_boards[0].name,
+ offset:sizeof(struct dmm32at_board),
+ num_names:sizeof(dmm32at_boards) / sizeof(struct dmm32at_board),
+};
+
+/* prototypes for driver functions below */
+static int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dmm32at_ns_to_timer(unsigned int *ns, int round);
+static irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG);
+void dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int dmm32at_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned char aihi, ailo, fifostat, aistat, intstat, airback;
+ unsigned long iobase;
+ unsigned int irq;
+
+ iobase = it->options[0];
+ irq = it->options[1];
+
+ printk("comedi%d: dmm32at: attaching\n", dev->minor);
+ printk("dmm32at: probing at address 0x%04lx, irq %u\n", iobase, irq);
+
+ /* register address space */
+ if (!request_region(iobase, DMM32AT_MEMSIZE, thisboard->name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* the following just makes sure the board is there and gets
+ it to a known state */
+
+ /* reset the board */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_RESET);
+
+ /* allow a millisecond to reset */
+ udelay(1000);
+
+ /* zero scan and fifo control */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, 0x0);
+
+ /* zero interrupt and clock control */
+ dmm_outb(dev, DMM32AT_INTCLOCK, 0x0);
+
+ /* write a test channel range, the high 3 bits should drop */
+ dmm_outb(dev, DMM32AT_AILOW, 0x80);
+ dmm_outb(dev, DMM32AT_AIHIGH, 0xff);
+
+ /* set the range at 10v unipolar */
+ dmm_outb(dev, DMM32AT_AICONF, DMM32AT_RANGE_U10);
+
+ /* should take 10 us to settle, here's a hundred */
+ udelay(100);
+
+ /* read back the values */
+ ailo = dmm_inb(dev, DMM32AT_AILOW);
+ aihi = dmm_inb(dev, DMM32AT_AIHIGH);
+ fifostat = dmm_inb(dev, DMM32AT_FIFOSTAT);
+ aistat = dmm_inb(dev, DMM32AT_AISTAT);
+ intstat = dmm_inb(dev, DMM32AT_INTCLOCK);
+ airback = dmm_inb(dev, DMM32AT_AIRBACK);
+
+ printk("dmm32at: lo=0x%02x hi=0x%02x fifostat=0x%02x\n",
+ ailo, aihi, fifostat);
+ printk("dmm32at: aistat=0x%02x intstat=0x%02x airback=0x%02x\n",
+ aistat, intstat, airback);
+
+ if ((ailo != 0x00) || (aihi != 0x1f) || (fifostat != 0x80) ||
+ (aistat != 0x60 || (intstat != 0x00) || airback != 0x0c)) {
+ printk("dmmat32: board detection failed\n");
+ return -EIO;
+ }
+
+ /* board is there, register interrupt */
+ if (irq) {
+ ret = comedi_request_irq(irq, dmm32at_isr, 0, thisboard->name,
+ dev);
+ if (ret < 0) {
+ printk("irq conflict\n");
+ return ret;
+ }
+ dev->irq = irq;
+ }
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+ //dev->board_ptr = dmm32at_probe(dev);
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct dmm32at_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ /* we support single-ended (ground) and differential */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = thisboard->ai_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = thisboard->ai_ranges;
+ s->len_chanlist = 32; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = dmm32at_ai_rinsn;
+ s->do_cmd = dmm32at_ai_cmd;
+ s->do_cmdtest = dmm32at_ai_cmdtest;
+ s->cancel = dmm32at_ai_cancel;
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = thisboard->ao_ranges;
+ s->insn_write = dmm32at_ao_winsn;
+ s->insn_read = dmm32at_ao_rinsn;
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+
+ /* get access to the DIO regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+ /* set the DIO's to the defualt input setting */
+ devpriv->dio_config = DMM32AT_DIRA | DMM32AT_DIRB |
+ DMM32AT_DIRCL | DMM32AT_DIRCH | DMM32AT_DIENABLE;
+ dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
+
+ /* set up the subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = thisboard->dio_chans;
+ s->maxdata = 1;
+ s->state = 0;
+ s->range_table = &range_digital;
+ s->insn_bits = dmm32at_dio_insn_bits;
+ s->insn_config = dmm32at_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* success */
+ printk("comedi%d: dmm32at: attached\n", dev->minor);
+
+ return 1;
+
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int dmm32at_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dmm32at: remove\n", dev->minor);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, DMM32AT_MEMSIZE);
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+
+static int dmm32at_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int d;
+ unsigned char status;
+ unsigned short msb, lsb;
+ unsigned char chan;
+ int range;
+
+ /* get the channel and range number */
+
+ chan = CR_CHAN(insn->chanspec) & (s->n_chan - 1);
+ range = CR_RANGE(insn->chanspec);
+
+ //printk("channel=0x%02x, range=%d\n",chan,range);
+
+ /* zero scan and fifo control and reset fifo */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET);
+
+ /* write the ai channel range regs */
+ dmm_outb(dev, DMM32AT_AILOW, chan);
+ dmm_outb(dev, DMM32AT_AIHIGH, chan);
+ /* set the range bits */
+ dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]);
+
+ /* wait for circuit to settle */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_AIRBACK);
+ if ((status & DMM32AT_STATUS) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ dmm_outb(dev, DMM32AT_CONV, 0xff);
+ /* wait for conversion to end */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_AISTAT);
+ if ((status & DMM32AT_STATUS) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ lsb = dmm_inb(dev, DMM32AT_AILSB);
+ msb = dmm_inb(dev, DMM32AT_AIMSB);
+
+ /* invert sign bit to make range unsigned, this is an
+ idiosyncracy of the diamond board, it return
+ conversions as a signed value, i.e. -32768 to
+ 32767, flipping the bit and interpreting it as
+ signed gives you a range of 0 to 65535 which is
+ used by comedi */
+ d = ((msb ^ 0x0080) << 8) + lsb;
+
+ data[n] = d;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int dmm32at_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int start_chan, gain, i;
+
+ //printk("dmmat32 in command test\n");
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER /*| TRIG_EXT */ ;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER /*| TRIG_EXT */ ;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SCAN_SPEED 1000000 /* in nanoseconds */
+#define MIN_SCAN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SCAN_SPEED) {
+ cmd->scan_begin_arg = MAX_SCAN_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SCAN_SPEED) {
+ cmd->scan_begin_arg = MIN_SCAN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg >= 17500)
+ cmd->convert_arg = 20000;
+ else if (cmd->convert_arg >= 12500)
+ cmd->convert_arg = 15000;
+ else if (cmd->convert_arg >= 7500)
+ cmd->convert_arg = 10000;
+ else
+ cmd->convert_arg = 5000;
+
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0xfffffff0) {
+ cmd->stop_arg = 0xfffffff0;
+ err++;
+ }
+ if (cmd->stop_arg == 0) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ dmm32at_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ dmm32at_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ /* step 5 check the channel list, the channel list for this
+ board must be consecutive and gains must be the same */
+
+ if (cmd->chanlist) {
+ gain = CR_RANGE(cmd->chanlist[0]);
+ start_chan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ (start_chan + i) % s->n_chan) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ if (CR_RANGE(cmd->chanlist[i]) != gain) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same gain\n");
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int dmm32at_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int i, range;
+ unsigned char chanlo, chanhi, status;
+
+ if (!cmd->chanlist)
+ return -EINVAL;
+
+ /* get the channel list and range */
+ chanlo = CR_CHAN(cmd->chanlist[0]) & (s->n_chan - 1);
+ chanhi = chanlo + cmd->chanlist_len - 1;
+ if (chanhi >= s->n_chan)
+ return -EINVAL;
+ range = CR_RANGE(cmd->chanlist[0]);
+
+ /* reset fifo */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_FIFORESET);
+
+ /* set scan enable */
+ dmm_outb(dev, DMM32AT_FIFOCNTRL, DMM32AT_SCANENABLE);
+
+ /* write the ai channel range regs */
+ dmm_outb(dev, DMM32AT_AILOW, chanlo);
+ dmm_outb(dev, DMM32AT_AIHIGH, chanhi);
+
+ /* set the range bits */
+ dmm_outb(dev, DMM32AT_AICONF, dmm32at_rangebits[range]);
+
+ /* reset the interrupt just in case */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ devpriv->ai_scans_left = cmd->stop_arg;
+ else { /* TRIG_NONE */
+ devpriv->ai_scans_left = 0xffffffff; /* indicates TRIG_NONE to isr */
+ }
+
+ /* wait for circuit to settle */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_AIRBACK);
+ if ((status & DMM32AT_STATUS) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ if (devpriv->ai_scans_left > 1) {
+ /* start the clock and enable the interrupts */
+ dmm32at_setaitimer(dev, cmd->scan_begin_arg);
+ } else {
+ /* start the interrups and initiate a single scan */
+ dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT);
+ dmm_outb(dev, DMM32AT_CONV, 0xff);
+ }
+
+/* printk("dmmat32 in command\n"); */
+
+/* for(i=0;i<cmd->chanlist_len;i++) */
+/* comedi_buf_put(s->async,i*100); */
+
+/* s->async->events |= COMEDI_CB_EOA; */
+/* comedi_event(dev, s); */
+
+ return 0;
+
+}
+
+static int dmm32at_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ devpriv->ai_scans_left = 1;
+ return 0;
+}
+
+static irqreturn_t dmm32at_isr(int irq, void *d PT_REGS_ARG)
+{
+ unsigned char intstat;
+ unsigned int samp;
+ unsigned short msb, lsb;
+ int i;
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ intstat = dmm_inb(dev, DMM32AT_INTCLOCK);
+
+ if (intstat & DMM32AT_ADINT) {
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ /* read data */
+ lsb = dmm_inb(dev, DMM32AT_AILSB);
+ msb = dmm_inb(dev, DMM32AT_AIMSB);
+
+ /* invert sign bit to make range unsigned */
+ samp = ((msb ^ 0x0080) << 8) + lsb;
+ comedi_buf_put(s->async, samp);
+ }
+
+ if (devpriv->ai_scans_left != 0xffffffff) { /* TRIG_COUNT */
+ devpriv->ai_scans_left--;
+ if (devpriv->ai_scans_left == 0) {
+ /* disable further interrupts and clocks */
+ dmm_outb(dev, DMM32AT_INTCLOCK, 0x0);
+ /* set the buffer to be flushed with an EOF */
+ s->async->events |= COMEDI_CB_EOA;
+ }
+
+ }
+ /* flush the buffer */
+ comedi_event(dev, s);
+ }
+
+ /* reset the interrupt */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_INTRESET);
+ return IRQ_HANDLED;
+}
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers. It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device. Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+static int dmm32at_ns_to_timer(unsigned int *ns, int round)
+{
+ /* trivial timer */
+ /* if your timing is done through two cascaded timers, the
+ * i8253_cascade_ns_to_timer() function in 8253.h can be
+ * very helpful. There are also i8254_load() and i8254_mm_load()
+ * which can be used to load values into the ubiquitous 8254 counters
+ */
+
+ return *ns;
+}
+
+static int dmm32at_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned char hi, lo, status;
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+
+ devpriv->ao_readback[chan] = data[i];
+
+ /* get the low byte */
+ lo = data[i] & 0x00ff;
+ /* high byte also contains channel number */
+ hi = (data[i] >> 8) + chan * (1 << 6);
+ //printk("writing 0x%02x 0x%02x\n",hi,lo);
+ /* write the low and high values to the board */
+ dmm_outb(dev, DMM32AT_DACLSB, lo);
+ dmm_outb(dev, DMM32AT_DACMSB, hi);
+
+ /* wait for circuit to settle */
+ for (i = 0; i < 40000; i++) {
+ status = dmm_inb(dev, DMM32AT_DACSTAT);
+ if ((status & DMM32AT_DACBUSY) == 0)
+ break;
+ }
+ if (i == 40000) {
+ printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+ /* dummy read to update trigger the output */
+ status = dmm_inb(dev, DMM32AT_DACMSB);
+
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int dmm32at_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int dmm32at_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned char diobits;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ //outw(s->state,dev->iobase + DMM32AT_DIO);
+ }
+
+ /* get access to the DIO regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+
+ /* if either part of dio is set for output */
+ if (((devpriv->dio_config & DMM32AT_DIRCL) == 0) ||
+ ((devpriv->dio_config & DMM32AT_DIRCH) == 0)) {
+ diobits = (s->state & 0x00ff0000) >> 16;
+ dmm_outb(dev, DMM32AT_DIOC, diobits);
+ }
+ if ((devpriv->dio_config & DMM32AT_DIRB) == 0) {
+ diobits = (s->state & 0x0000ff00) >> 8;
+ dmm_outb(dev, DMM32AT_DIOB, diobits);
+ }
+ if ((devpriv->dio_config & DMM32AT_DIRA) == 0) {
+ diobits = (s->state & 0x000000ff);
+ dmm_outb(dev, DMM32AT_DIOA, diobits);
+ }
+
+ /* now read the state back in */
+ s->state = dmm_inb(dev, DMM32AT_DIOC);
+ s->state <<= 8;
+ s->state |= dmm_inb(dev, DMM32AT_DIOB);
+ s->state <<= 8;
+ s->state |= dmm_inb(dev, DMM32AT_DIOA);
+ data[1] = s->state;
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ //data[1]=inw(dev->iobase + DMM32AT_DIO);
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ //data[1]=s->state;
+
+ return 2;
+}
+
+static int dmm32at_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned char chanbit;
+ int chan = CR_CHAN(insn->chanspec);
+
+ if (insn->n != 1)
+ return -EINVAL;
+
+ if (chan < 8)
+ chanbit = DMM32AT_DIRA;
+ else if (chan < 16)
+ chanbit = DMM32AT_DIRB;
+ else if (chan < 20)
+ chanbit = DMM32AT_DIRCL;
+ else
+ chanbit = DMM32AT_DIRCH;
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ /* if output clear the bit, otherwise set it */
+ if (data[0] == COMEDI_OUTPUT) {
+ devpriv->dio_config &= ~chanbit;
+ } else {
+ devpriv->dio_config |= chanbit;
+ }
+ /* get access to the DIO regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_DIOACC);
+ /* set the DIO's to the new configuration setting */
+ dmm_outb(dev, DMM32AT_DIOCONF, devpriv->dio_config);
+
+ return 1;
+}
+
+void dmm32at_setaitimer(struct comedi_device * dev, unsigned int nansec)
+{
+ unsigned char lo1, lo2, hi2;
+ unsigned short both2;
+
+ /* based on 10mhz clock */
+ lo1 = 200;
+ both2 = nansec / 20000;
+ hi2 = (both2 & 0xff00) >> 8;
+ lo2 = both2 & 0x00ff;
+
+ /* set the counter frequency to 10mhz */
+ dmm_outb(dev, DMM32AT_CNTRDIO, 0);
+
+ /* get access to the clock regs */
+ dmm_outb(dev, DMM32AT_CNTRL, DMM32AT_CLKACC);
+
+ /* write the counter 1 control word and low byte to counter */
+ dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT1);
+ dmm_outb(dev, DMM32AT_CLK1, lo1);
+
+ /* write the counter 2 control word and low byte then to counter */
+ dmm_outb(dev, DMM32AT_CLKCT, DMM32AT_CLKCT2);
+ dmm_outb(dev, DMM32AT_CLK2, lo2);
+ dmm_outb(dev, DMM32AT_CLK2, hi2);
+
+ /* enable the ai conversion interrupt and the clock to start scans */
+ dmm_outb(dev, DMM32AT_INTCLOCK, DMM32AT_ADINT | DMM32AT_CLKSEL);
+
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_dmm32at);
diff --git a/drivers/staging/comedi/drivers/dt2801.c b/drivers/staging/comedi/drivers/dt2801.c
new file mode 100644
index 00000000000..5e0eed835d1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2801.c
@@ -0,0 +1,697 @@
+/*
+ * comedi/drivers/dt2801.c
+ * Device Driver for DataTranslation DT2801
+ *
+ */
+/*
+Driver: dt2801
+Description: Data Translation DT2801 series and DT01-EZ
+Author: ds
+Status: works
+Devices: [Data Translation] DT2801 (dt2801), DT2801-A, DT2801/5716A,
+ DT2805, DT2805/5716A, DT2808, DT2818, DT2809, DT01-EZ
+
+This driver can autoprobe the type of board.
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - unused
+ [2] - A/D reference 0=differential, 1=single-ended
+ [3] - A/D range
+ 0 = [-10,10]
+ 1 = [0,10]
+ [4] - D/A 0 range
+ 0 = [-10,10]
+ 1 = [-5,5]
+ 2 = [-2.5,2.5]
+ 3 = [0,10]
+ 4 = [0,5]
+ [5] - D/A 1 range (same choices)
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#define DT2801_TIMEOUT 1000
+
+/* Hardware Configuration */
+/* ====================== */
+
+#define DT2801_MAX_DMA_SIZE (64 * 1024)
+
+/* Ports */
+#define DT2801_IOSIZE 2
+
+/* define's */
+/* ====================== */
+
+/* Commands */
+#define DT_C_RESET 0x0
+#define DT_C_CLEAR_ERR 0x1
+#define DT_C_READ_ERRREG 0x2
+#define DT_C_SET_CLOCK 0x3
+
+#define DT_C_TEST 0xb
+#define DT_C_STOP 0xf
+
+#define DT_C_SET_DIGIN 0x4
+#define DT_C_SET_DIGOUT 0x5
+#define DT_C_READ_DIG 0x6
+#define DT_C_WRITE_DIG 0x7
+
+#define DT_C_WRITE_DAIM 0x8
+#define DT_C_SET_DA 0x9
+#define DT_C_WRITE_DA 0xa
+
+#define DT_C_READ_ADIM 0xc
+#define DT_C_SET_AD 0xd
+#define DT_C_READ_AD 0xe
+
+/* Command modifiers (only used with read/write), EXTTRIG can be
+ used with some other commands.
+*/
+#define DT_MOD_DMA (1<<4)
+#define DT_MOD_CONT (1<<5)
+#define DT_MOD_EXTCLK (1<<6)
+#define DT_MOD_EXTTRIG (1<<7)
+
+/* Bits in status register */
+#define DT_S_DATA_OUT_READY (1<<0)
+#define DT_S_DATA_IN_FULL (1<<1)
+#define DT_S_READY (1<<2)
+#define DT_S_COMMAND (1<<3)
+#define DT_S_COMPOSITE_ERROR (1<<7)
+
+/* registers */
+#define DT2801_DATA 0
+#define DT2801_STATUS 1
+#define DT2801_CMD 1
+
+static int dt2801_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2801_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2801 = {
+ driver_name:"dt2801",
+ module:THIS_MODULE,
+ attach:dt2801_attach,
+ detach:dt2801_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2801);
+
+#if 0
+// ignore 'defined but not used' warning
+static const struct comedi_lrange range_dt2801_ai_pgh_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ }
+};
+#endif
+static const struct comedi_lrange range_dt2801_ai_pgl_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02),
+ }
+};
+
+#if 0
+// ignore 'defined but not used' warning
+static const struct comedi_lrange range_dt2801_ai_pgh_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ }
+};
+#endif
+static const struct comedi_lrange range_dt2801_ai_pgl_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ RANGE(0, 0.02),
+ }
+};
+
+struct dt2801_board {
+
+ const char *name;
+ int boardcode;
+ int ad_diff;
+ int ad_chan;
+ int adbits;
+ int adrangetype;
+ int dabits;
+};
+
+
+/* Typeid's for the different boards of the DT2801-series
+ (taken from the test-software, that comes with the board)
+ */
+static const struct dt2801_board boardtypes[] = {
+ {
+ name: "dt2801",
+ boardcode:0x09,
+ ad_diff: 2,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2801-a",
+ boardcode:0x52,
+ ad_diff: 2,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2801/5716a",
+ boardcode:0x82,
+ ad_diff: 1,
+ ad_chan: 16,
+ adbits: 16,
+ adrangetype:1,
+ dabits: 12},
+ {
+ name: "dt2805",
+ boardcode:0x12,
+ ad_diff: 1,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2805/5716a",
+ boardcode:0x92,
+ ad_diff: 1,
+ ad_chan: 16,
+ adbits: 16,
+ adrangetype:1,
+ dabits: 12},
+ {
+ name: "dt2808",
+ boardcode:0x20,
+ ad_diff: 0,
+ ad_chan: 16,
+ adbits: 12,
+ adrangetype:2,
+ dabits: 8},
+ {
+ name: "dt2818",
+ boardcode:0xa2,
+ ad_diff: 0,
+ ad_chan: 4,
+ adbits: 12,
+ adrangetype:0,
+ dabits: 12},
+ {
+ name: "dt2809",
+ boardcode:0xb0,
+ ad_diff: 0,
+ ad_chan: 8,
+ adbits: 12,
+ adrangetype:1,
+ dabits: 12},
+};
+
+#define n_boardtypes ((sizeof(boardtypes))/(sizeof(boardtypes[0])))
+#define boardtype (*(const struct dt2801_board *)dev->board_ptr)
+
+struct dt2801_private {
+
+ const struct comedi_lrange *dac_range_types[2];
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct dt2801_private *)dev->private)
+
+static int dt2801_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2801_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/* These are the low-level routines:
+ writecommand: write a command to the board
+ writedata: write data byte
+ readdata: read data byte
+ */
+
+/* Only checks DataOutReady-flag, not the Ready-flag as it is done
+ in the examples of the manual. I don't see why this should be
+ necessary. */
+static int dt2801_readdata(struct comedi_device * dev, int *data)
+{
+ int stat = 0;
+ int timeout = DT2801_TIMEOUT;
+
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & (DT_S_COMPOSITE_ERROR | DT_S_READY)) {
+ return stat;
+ }
+ if (stat & DT_S_DATA_OUT_READY) {
+ *data = inb_p(dev->iobase + DT2801_DATA);
+ return 0;
+ }
+ } while (--timeout > 0);
+
+ return -ETIME;
+}
+
+static int dt2801_readdata2(struct comedi_device * dev, int *data)
+{
+ int lb, hb;
+ int ret;
+
+ ret = dt2801_readdata(dev, &lb);
+ if (ret)
+ return ret;
+ ret = dt2801_readdata(dev, &hb);
+ if (ret)
+ return ret;
+
+ *data = (hb << 8) + lb;
+ return 0;
+}
+
+static int dt2801_writedata(struct comedi_device * dev, unsigned int data)
+{
+ int stat = 0;
+ int timeout = DT2801_TIMEOUT;
+
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+
+ if (stat & DT_S_COMPOSITE_ERROR) {
+ return stat;
+ }
+ if (!(stat & DT_S_DATA_IN_FULL)) {
+ outb_p(data & 0xff, dev->iobase + DT2801_DATA);
+ return 0;
+ }
+#if 0
+ if (stat & DT_S_READY) {
+ printk("dt2801: ready flag set (bad!) in dt2801_writedata()\n");
+ return -EIO;
+ }
+#endif
+ } while (--timeout > 0);
+
+ return -ETIME;
+}
+
+static int dt2801_writedata2(struct comedi_device * dev, unsigned int data)
+{
+ int ret;
+
+ ret = dt2801_writedata(dev, data & 0xff);
+ if (ret < 0)
+ return ret;
+ ret = dt2801_writedata(dev, (data >> 8));
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int dt2801_wait_for_ready(struct comedi_device * dev)
+{
+ int timeout = DT2801_TIMEOUT;
+ int stat;
+
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_READY) {
+ return 0;
+ }
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+
+ if (stat & DT_S_COMPOSITE_ERROR) {
+ return stat;
+ }
+ if (stat & DT_S_READY) {
+ return 0;
+ }
+ } while (--timeout > 0);
+
+ return -ETIME;
+}
+
+static int dt2801_writecmd(struct comedi_device * dev, int command)
+{
+ int stat;
+
+ dt2801_wait_for_ready(dev);
+
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_COMPOSITE_ERROR) {
+ printk("dt2801: composite-error in dt2801_writecmd(), ignoring\n");
+ }
+ if (!(stat & DT_S_READY)) {
+ printk("dt2801: !ready in dt2801_writecmd(), ignoring\n");
+ }
+ outb_p(command, dev->iobase + DT2801_CMD);
+
+ return 0;
+}
+
+static int dt2801_reset(struct comedi_device * dev)
+{
+ int board_code = 0;
+ unsigned int stat;
+ int timeout;
+
+ DPRINTK("dt2801: resetting board...\n");
+ DPRINTK("fingerprint: 0x%02x 0x%02x\n", inb_p(dev->iobase),
+ inb_p(dev->iobase + 1));
+
+ /* pull random data from data port */
+ inb_p(dev->iobase + DT2801_DATA);
+ inb_p(dev->iobase + DT2801_DATA);
+ inb_p(dev->iobase + DT2801_DATA);
+ inb_p(dev->iobase + DT2801_DATA);
+
+ DPRINTK("dt2801: stop\n");
+ //dt2801_writecmd(dev,DT_C_STOP);
+ outb_p(DT_C_STOP, dev->iobase + DT2801_CMD);
+
+ //dt2801_wait_for_ready(dev);
+ comedi_udelay(100);
+ timeout = 10000;
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_READY)
+ break;
+ } while (timeout--);
+ if (!timeout) {
+ printk("dt2801: timeout 1 status=0x%02x\n", stat);
+ }
+ //printk("dt2801: reading dummy\n");
+ //dt2801_readdata(dev,&board_code);
+
+ DPRINTK("dt2801: reset\n");
+ outb_p(DT_C_RESET, dev->iobase + DT2801_CMD);
+ //dt2801_writecmd(dev,DT_C_RESET);
+
+ comedi_udelay(100);
+ timeout = 10000;
+ do {
+ stat = inb_p(dev->iobase + DT2801_STATUS);
+ if (stat & DT_S_READY)
+ break;
+ } while (timeout--);
+ if (!timeout) {
+ printk("dt2801: timeout 2 status=0x%02x\n", stat);
+ }
+
+ DPRINTK("dt2801: reading code\n");
+ dt2801_readdata(dev, &board_code);
+
+ DPRINTK("dt2801: ok. code=0x%02x\n", board_code);
+
+ return board_code;
+}
+
+static int probe_number_of_ai_chans(struct comedi_device * dev)
+{
+ int n_chans;
+ int stat;
+ int data;
+
+ for (n_chans = 0; n_chans < 16; n_chans++) {
+ stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
+ dt2801_writedata(dev, 0);
+ dt2801_writedata(dev, n_chans);
+ stat = dt2801_readdata2(dev, &data);
+
+ if (stat)
+ break;
+ }
+
+ dt2801_reset(dev);
+ dt2801_reset(dev);
+
+ return n_chans;
+}
+
+static const struct comedi_lrange *dac_range_table[] = {
+ &range_bipolar10,
+ &range_bipolar5,
+ &range_bipolar2_5,
+ &range_unipolar10,
+ &range_unipolar5
+};
+
+static const struct comedi_lrange *dac_range_lkup(int opt)
+{
+ if (opt < 0 || opt > 5)
+ return &range_unknown;
+ return dac_range_table[opt];
+}
+
+static const struct comedi_lrange *ai_range_lkup(int type, int opt)
+{
+ switch (type) {
+ case 0:
+ return (opt) ?
+ &range_dt2801_ai_pgl_unipolar :
+ &range_dt2801_ai_pgl_bipolar;
+ case 1:
+ return (opt) ? &range_unipolar10 : &range_bipolar10;
+ case 2:
+ return &range_unipolar5;
+ }
+ return &range_unknown;
+}
+
+/*
+ options:
+ [0] - i/o base
+ [1] - unused
+ [2] - a/d 0=differential, 1=single-ended
+ [3] - a/d range 0=[-10,10], 1=[0,10]
+ [4] - dac0 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
+ [5] - dac1 range 0=[-10,10], 1=[-5,5], 2=[-2.5,2.5] 3=[0,10], 4=[0,5]
+*/
+static int dt2801_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ int board_code, type;
+ int ret = 0;
+ int n_ai_chans;
+
+ iobase = it->options[0];
+ if (!request_region(iobase, DT2801_IOSIZE, "dt2801")) {
+ comedi_error(dev, "I/O port conflict");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* do some checking */
+
+ board_code = dt2801_reset(dev);
+
+ /* heh. if it didn't work, try it again. */
+ if (!board_code)
+ board_code = dt2801_reset(dev);
+
+ for (type = 0; type < n_boardtypes; type++) {
+ if (boardtypes[type].boardcode == board_code)
+ goto havetype;
+ }
+ printk("dt2801: unrecognized board code=0x%02x, contact author\n",
+ board_code);
+ type = 0;
+
+ havetype:
+ dev->board_ptr = boardtypes + type;
+ printk("dt2801: %s at port 0x%lx", boardtype.name, iobase);
+
+ n_ai_chans = probe_number_of_ai_chans(dev);
+ printk(" (ai channels = %d)", n_ai_chans);
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ goto out;
+
+ if ((ret = alloc_private(dev, sizeof(struct dt2801_private))) < 0)
+ goto out;
+
+ dev->board_name = boardtype.name;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+#if 1
+ s->n_chan = n_ai_chans;
+#else
+ if (it->options[2])
+ s->n_chan = boardtype.ad_chan;
+ else
+ s->n_chan = boardtype.ad_chan / 2;
+#endif
+ s->maxdata = (1 << boardtype.adbits) - 1;
+ s->range_table = ai_range_lkup(boardtype.adrangetype, it->options[3]);
+ s->insn_read = dt2801_ai_insn_read;
+
+ s++;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = (1 << boardtype.dabits) - 1;
+ s->range_table_list = devpriv->dac_range_types;
+ devpriv->dac_range_types[0] = dac_range_lkup(it->options[4]);
+ devpriv->dac_range_types[1] = dac_range_lkup(it->options[5]);
+ s->insn_read = dt2801_ao_insn_read;
+ s->insn_write = dt2801_ao_insn_write;
+
+ s++;
+ /* 1st digital subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dt2801_dio_insn_bits;
+ s->insn_config = dt2801_dio_insn_config;
+
+ s++;
+ /* 2nd digital subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dt2801_dio_insn_bits;
+ s->insn_config = dt2801_dio_insn_config;
+
+ ret = 0;
+ out:
+ printk("\n");
+
+ return ret;
+}
+
+static int dt2801_detach(struct comedi_device * dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, DT2801_IOSIZE);
+
+ return 0;
+}
+
+static int dt2801_error(struct comedi_device * dev, int stat)
+{
+ if (stat < 0) {
+ if (stat == -ETIME) {
+ printk("dt2801: timeout\n");
+ } else {
+ printk("dt2801: error %d\n", stat);
+ }
+ return stat;
+ }
+ printk("dt2801: error status 0x%02x, resetting...\n", stat);
+
+ dt2801_reset(dev);
+ dt2801_reset(dev);
+
+ return -EIO;
+}
+
+static int dt2801_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int d;
+ int stat;
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ stat = dt2801_writecmd(dev, DT_C_READ_ADIM);
+ dt2801_writedata(dev, CR_RANGE(insn->chanspec));
+ dt2801_writedata(dev, CR_CHAN(insn->chanspec));
+ stat = dt2801_readdata2(dev, &d);
+
+ if (stat != 0)
+ return dt2801_error(dev, stat);
+
+ data[i] = d;
+ }
+
+ return i;
+}
+
+static int dt2801_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int dt2801_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ dt2801_writecmd(dev, DT_C_WRITE_DAIM);
+ dt2801_writedata(dev, CR_CHAN(insn->chanspec));
+ dt2801_writedata2(dev, data[0]);
+
+ devpriv->ao_readback[CR_CHAN(insn->chanspec)] = data[0];
+
+ return 1;
+}
+
+static int dt2801_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int which = 0;
+
+ if (s == dev->subdevices + 4)
+ which = 1;
+
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ dt2801_writecmd(dev, DT_C_WRITE_DIG);
+ dt2801_writedata(dev, which);
+ dt2801_writedata(dev, s->state);
+ }
+ dt2801_writecmd(dev, DT_C_READ_DIG);
+ dt2801_writedata(dev, which);
+ dt2801_readdata(dev, data + 1);
+
+ return 2;
+}
+
+static int dt2801_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int which = 0;
+
+ if (s == dev->subdevices + 4)
+ which = 1;
+
+ /* configure */
+ if (data[0]) {
+ s->io_bits = 0xff;
+ dt2801_writecmd(dev, DT_C_SET_DIGOUT);
+ } else {
+ s->io_bits = 0;
+ dt2801_writecmd(dev, DT_C_SET_DIGIN);
+ }
+ dt2801_writedata(dev, which);
+
+ return 1;
+}
diff --git a/drivers/staging/comedi/drivers/dt2811.c b/drivers/staging/comedi/drivers/dt2811.c
new file mode 100644
index 00000000000..795932ec67d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2811.c
@@ -0,0 +1,604 @@
+/*
+ comedi/drivers/dt2811.c
+ Hardware driver for Data Translation DT2811
+
+ COMEDI - Linux Control and Measurement Device Interface
+ History:
+ Base Version - David A. Schleef <ds@schleef.org>
+ December 1998 - Updated to work. David does not have a DT2811
+ board any longer so this was suffering from bitrot.
+ Updated performed by ...
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+/*
+Driver: dt2811
+Description: Data Translation DT2811
+Author: ds
+Devices: [Data Translation] DT2811-PGL (dt2811-pgl), DT2811-PGH (dt2811-pgh)
+Status: works
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ, although this is currently unused
+ [2] - A/D reference
+ 0 = signle-ended
+ 1 = differential
+ 2 = pseudo-differential (common reference)
+ [3] - A/D range
+ 0 = [-5,5]
+ 1 = [-2.5,2.5]
+ 2 = [0,5]
+ [4] - D/A 0 range (same choices)
+ [4] - D/A 1 range (same choices)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+static const char *driver_name = "dt2811";
+
+static const struct comedi_lrange range_dt2811_pgh_ai_5_unipolar = { 4, {
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ RANGE(0, 0.625)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgh_ai_2_5_bipolar = { 4, {
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625),
+ RANGE(-0.3125, 0.3125)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgh_ai_5_bipolar = { 4, {
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_5_unipolar = { 4, {
+ RANGE(0, 5),
+ RANGE(0, 0.5),
+ RANGE(0, 0.05),
+ RANGE(0, 0.01)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_2_5_bipolar = { 4, {
+ RANGE(-2.5, 2.5),
+ RANGE(-0.25, 0.25),
+ RANGE(-0.025, 0.025),
+ RANGE(-0.005, 0.005)
+ }
+};
+static const struct comedi_lrange range_dt2811_pgl_ai_5_bipolar = { 4, {
+ RANGE(-5, 5),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.05, 0.05),
+ RANGE(-0.01, 0.01)
+ }
+};
+
+/*
+
+ 0x00 ADCSR R/W A/D Control/Status Register
+ bit 7 - (R) 1 indicates A/D conversion done
+ reading ADDAT clears bit
+ (W) ignored
+ bit 6 - (R) 1 indicates A/D error
+ (W) ignored
+ bit 5 - (R) 1 indicates A/D busy, cleared at end
+ of conversion
+ (W) ignored
+ bit 4 - (R) 0
+ (W)
+ bit 3 - (R) 0
+ bit 2 - (R/W) 1 indicates interrupts enabled
+ bits 1,0 - (R/W) mode bits
+ 00 single conversion on ADGCR load
+ 01 continuous conversion, internal clock,
+ (clock enabled on ADGCR load)
+ 10 continuous conversion, internal clock,
+ external trigger
+ 11 continuous conversion, external clock,
+ external trigger
+
+ 0x01 ADGCR R/W A/D Gain/Channel Register
+ bit 6,7 - (R/W) gain select
+ 00 gain=1, both PGH, PGL models
+ 01 gain=2 PGH, 10 PGL
+ 10 gain=4 PGH, 100 PGL
+ 11 gain=8 PGH, 500 PGL
+ bit 4,5 - reserved
+ bit 3-0 - (R/W) channel select
+ channel number from 0-15
+
+ 0x02,0x03 (R) ADDAT A/D Data Register
+ (W) DADAT0 D/A Data Register 0
+ 0x02 low byte
+ 0x03 high byte
+
+ 0x04,0x05 (W) DADAT0 D/A Data Register 1
+
+ 0x06 (R) DIO0 Digital Input Port 0
+ (W) DIO1 Digital Output Port 1
+
+ 0x07 TMRCTR (R/W) Timer/Counter Register
+ bits 6,7 - reserved
+ bits 5-3 - Timer frequency control (mantissa)
+ 543 divisor freqency (kHz)
+ 000 1 600
+ 001 10 60
+ 010 2 300
+ 011 3 200
+ 100 4 150
+ 101 5 120
+ 110 6 100
+ 111 12 50
+ bits 2-0 - Timer frequency control (exponent)
+ 210 multiply divisor/divide frequency by
+ 000 1
+ 001 10
+ 010 100
+ 011 1000
+ 100 10000
+ 101 100000
+ 110 1000000
+ 111 10000000
+
+ */
+
+#define TIMEOUT 10000
+
+#define DT2811_SIZE 8
+
+#define DT2811_ADCSR 0
+#define DT2811_ADGCR 1
+#define DT2811_ADDATLO 2
+#define DT2811_ADDATHI 3
+#define DT2811_DADAT0LO 2
+#define DT2811_DADAT0HI 3
+#define DT2811_DADAT1LO 4
+#define DT2811_DADAT1HI 5
+#define DT2811_DIO 6
+#define DT2811_TMRCTR 7
+
+/*
+ * flags
+ */
+
+/* ADCSR */
+
+#define DT2811_ADDONE 0x80
+#define DT2811_ADERROR 0x40
+#define DT2811_ADBUSY 0x20
+#define DT2811_CLRERROR 0x10
+#define DT2811_INTENB 0x04
+#define DT2811_ADMODE 0x03
+
+struct dt2811_board {
+
+ const char *name;
+ const struct comedi_lrange *bip_5;
+ const struct comedi_lrange *bip_2_5;
+ const struct comedi_lrange *unip_5;
+};
+
+static const struct dt2811_board boardtypes[] = {
+ {"dt2811-pgh",
+ &range_dt2811_pgh_ai_5_bipolar,
+ &range_dt2811_pgh_ai_2_5_bipolar,
+ &range_dt2811_pgh_ai_5_unipolar,
+ },
+ {"dt2811-pgl",
+ &range_dt2811_pgl_ai_5_bipolar,
+ &range_dt2811_pgl_ai_2_5_bipolar,
+ &range_dt2811_pgl_ai_5_unipolar,
+ },
+};
+
+#define this_board ((const struct dt2811_board *)dev->board_ptr)
+
+static int dt2811_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2811_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2811 = {
+ driver_name:"dt2811",
+ module:THIS_MODULE,
+ attach:dt2811_attach,
+ detach:dt2811_detach,
+ board_name:&boardtypes[0].name,
+ num_names:sizeof(boardtypes) / sizeof(struct dt2811_board),
+ offset:sizeof(struct dt2811_board),
+};
+
+COMEDI_INITCLEANUP(driver_dt2811);
+
+static int dt2811_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int dt2811_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+enum { card_2811_pgh, card_2811_pgl };
+
+struct dt2811_private {
+ int ntrig;
+ int curadchan;
+ enum {
+ adc_singleended, adc_diff, adc_pseudo_diff
+ } adc_mux;
+ enum {
+ dac_bipolar_5, dac_bipolar_2_5, dac_unipolar_5
+ } dac_range[2];
+ const struct comedi_lrange *range_type_list[2];
+ unsigned int ao_readback[2];
+};
+
+#define devpriv ((struct dt2811_private *)dev->private)
+
+static const struct comedi_lrange *dac_range_types[] = {
+ &range_bipolar5,
+ &range_bipolar2_5,
+ &range_unipolar5
+};
+
+#define DT2811_TIMEOUT 5
+
+#if 0
+static irqreturn_t dt2811_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int lo, hi;
+ int data;
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ lo = inb(dev->iobase + DT2811_ADDATLO);
+ hi = inb(dev->iobase + DT2811_ADDATHI);
+
+ data = lo + (hi << 8);
+
+ if (!(--devpriv->ntrig)) {
+ /* how to turn off acquisition */
+ s->async->events |= COMEDI_SB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+#endif
+
+/*
+ options[0] Board base address
+ options[1] IRQ
+ options[2] Input configuration
+ 0 == single-ended
+ 1 == differential
+ 2 == pseudo-differential
+ options[3] Analog input range configuration
+ 0 == bipolar 5 (-5V -- +5V)
+ 1 == bipolar 2.5V (-2.5V -- +2.5V)
+ 2 == unipolar 5V (0V -- +5V)
+ options[4] Analog output 0 range configuration
+ 0 == bipolar 5 (-5V -- +5V)
+ 1 == bipolar 2.5V (-2.5V -- +2.5V)
+ 2 == unipolar 5V (0V -- +5V)
+ options[5] Analog output 1 range configuration
+ 0 == bipolar 5 (-5V -- +5V)
+ 1 == bipolar 2.5V (-2.5V -- +2.5V)
+ 2 == unipolar 5V (0V -- +5V)
+*/
+
+static int dt2811_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ //int i, irq;
+ //unsigned long irqs;
+ //long flags;
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+
+ printk("comedi%d: dt2811: base=0x%04lx\n", dev->minor, iobase);
+
+ if (!request_region(iobase, DT2811_SIZE, driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = this_board->name;
+
+#if 0
+ outb(0, dev->iobase + DT2811_ADCSR);
+ comedi_udelay(100);
+ i = inb(dev->iobase + DT2811_ADDATLO);
+ i = inb(dev->iobase + DT2811_ADDATHI);
+#endif
+
+#if 0
+ irq = it->options[1];
+ if (irq < 0) {
+ save_flags(flags);
+ sti();
+ irqs = probe_irq_on();
+
+ outb(DT2811_CLRERROR | DT2811_INTENB,
+ dev->iobase + DT2811_ADCSR);
+ outb(0, dev->iobase + DT2811_ADGCR);
+
+ comedi_udelay(100);
+
+ irq = probe_irq_off(irqs);
+ restore_flags(flags);
+
+ /*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); */
+
+ if (inb(dev->iobase + DT2811_ADCSR) & DT2811_ADERROR) {
+ printk("error probing irq (bad) \n");
+ }
+ dev->irq = 0;
+ if (irq > 0) {
+ i = inb(dev->iobase + DT2811_ADDATLO);
+ i = inb(dev->iobase + DT2811_ADDATHI);
+ printk("(irq = %d)\n", irq);
+ ret = comedi_request_irq(irq, dt2811_interrupt, 0,
+ driver_name, dev);
+ if (ret < 0)
+ return -EIO;
+ dev->irq = irq;
+ } else if (irq == 0) {
+ printk("(no irq)\n");
+ } else {
+ printk("( multiple irq's -- this is bad! )\n");
+ }
+ }
+#endif
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct dt2811_private))) < 0)
+ return ret;
+ switch (it->options[2]) {
+ case 0:
+ devpriv->adc_mux = adc_singleended;
+ break;
+ case 1:
+ devpriv->adc_mux = adc_diff;
+ break;
+ case 2:
+ devpriv->adc_mux = adc_pseudo_diff;
+ break;
+ default:
+ devpriv->adc_mux = adc_singleended;
+ break;
+ }
+ switch (it->options[4]) {
+ case 0:
+ devpriv->dac_range[0] = dac_bipolar_5;
+ break;
+ case 1:
+ devpriv->dac_range[0] = dac_bipolar_2_5;
+ break;
+ case 2:
+ devpriv->dac_range[0] = dac_unipolar_5;
+ break;
+ default:
+ devpriv->dac_range[0] = dac_bipolar_5;
+ break;
+ }
+ switch (it->options[5]) {
+ case 0:
+ devpriv->dac_range[1] = dac_bipolar_5;
+ break;
+ case 1:
+ devpriv->dac_range[1] = dac_bipolar_2_5;
+ break;
+ case 2:
+ devpriv->dac_range[1] = dac_unipolar_5;
+ break;
+ default:
+ devpriv->dac_range[1] = dac_bipolar_5;
+ break;
+ }
+
+ s = dev->subdevices + 0;
+ /* initialize the ADC subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = devpriv->adc_mux == adc_diff ? 8 : 16;
+ s->insn_read = dt2811_ai_insn;
+ s->maxdata = 0xfff;
+ switch (it->options[3]) {
+ case 0:
+ default:
+ s->range_table = this_board->bip_5;
+ break;
+ case 1:
+ s->range_table = this_board->bip_2_5;
+ break;
+ case 2:
+ s->range_table = this_board->unip_5;
+ break;
+ }
+
+ s = dev->subdevices + 1;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_write = dt2811_ao_insn;
+ s->insn_read = dt2811_ao_insn_read;
+ s->maxdata = 0xfff;
+ s->range_table_list = devpriv->range_type_list;
+ devpriv->range_type_list[0] = dac_range_types[devpriv->dac_range[0]];
+ devpriv->range_type_list[1] = dac_range_types[devpriv->dac_range[1]];
+
+ s = dev->subdevices + 2;
+ /* di subdevice */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 8;
+ s->insn_bits = dt2811_di_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ s = dev->subdevices + 3;
+ /* do subdevice */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_bits = dt2811_do_insn_bits;
+ s->maxdata = 1;
+ s->state = 0;
+ s->range_table = &range_digital;
+
+ return 0;
+}
+
+static int dt2811_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2811: remove\n", dev->minor);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->iobase) {
+ release_region(dev->iobase, DT2811_SIZE);
+ }
+
+ return 0;
+}
+
+static int dt2811_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int timeout = DT2811_TIMEOUT;
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ outb(chan, dev->iobase + DT2811_ADGCR);
+
+ while (timeout
+ && inb(dev->iobase + DT2811_ADCSR) & DT2811_ADBUSY)
+ timeout--;
+ if (!timeout)
+ return -ETIME;
+
+ data[i] = inb(dev->iobase + DT2811_ADDATLO);
+ data[i] |= inb(dev->iobase + DT2811_ADDATHI) << 8;
+ data[i] &= 0xfff;
+ }
+
+ return i;
+}
+
+#if 0
+/* Wow. This is code from the Comedi stone age. But it hasn't been
+ * replaced, so I'll let it stay. */
+int dt2811_adtrig(kdev_t minor, comedi_adtrig * adtrig)
+{
+ struct comedi_device *dev = comedi_devices + minor;
+
+ if (adtrig->n < 1)
+ return 0;
+ dev->curadchan = adtrig->chan;
+ switch (dev->i_admode) {
+ case COMEDI_MDEMAND:
+ dev->ntrig = adtrig->n - 1;
+ /*printk("dt2811: AD soft trigger\n"); */
+ /*outb(DT2811_CLRERROR|DT2811_INTENB,dev->iobase+DT2811_ADCSR); *//* not neccessary */
+ outb(dev->curadchan, dev->iobase + DT2811_ADGCR);
+ do_gettimeofday(&trigtime);
+ break;
+ case COMEDI_MCONTS:
+ dev->ntrig = adtrig->n;
+ break;
+ }
+
+ return 0;
+}
+#endif
+
+static int dt2811_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ outb(data[i] & 0xff, dev->iobase + DT2811_DADAT0LO + 2 * chan);
+ outb((data[i] >> 8) & 0xff,
+ dev->iobase + DT2811_DADAT0HI + 2 * chan);
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int dt2811_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int dt2811_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + DT2811_DIO);
+
+ return 2;
+}
+
+static int dt2811_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outb(s->state, dev->iobase + DT2811_DIO);
+
+ data[1] = s->state;
+
+ return 2;
+}
diff --git a/drivers/staging/comedi/drivers/dt2814.c b/drivers/staging/comedi/drivers/dt2814.c
new file mode 100644
index 00000000000..8320139160a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2814.c
@@ -0,0 +1,383 @@
+/*
+ comedi/drivers/dt2814.c
+ Hardware driver for Data Translation DT2814
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dt2814
+Description: Data Translation DT2814
+Author: ds
+Status: complete
+Devices: [Data Translation] DT2814 (dt2814)
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ
+
+This card has 16 analog inputs multiplexed onto a 12 bit ADC. There
+is a minimally useful onboard clock. The base frequency for the
+clock is selected by jumpers, and the clock divider can be selected
+via programmed I/O. Unfortunately, the clock divider can only be
+a power of 10, from 1 to 10^7, of which only 3 or 4 are useful. In
+addition, the clock does not seem to be very accurate.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#define DT2814_SIZE 2
+
+#define DT2814_CSR 0
+#define DT2814_DATA 1
+
+/*
+ * flags
+ */
+
+#define DT2814_FINISH 0x80
+#define DT2814_ERR 0x40
+#define DT2814_BUSY 0x20
+#define DT2814_ENB 0x10
+#define DT2814_CHANMASK 0x0f
+
+static int dt2814_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2814_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2814 = {
+ driver_name:"dt2814",
+ module:THIS_MODULE,
+ attach:dt2814_attach,
+ detach:dt2814_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2814);
+
+static irqreturn_t dt2814_interrupt(int irq, void *dev PT_REGS_ARG);
+
+struct dt2814_private {
+
+ int ntrig;
+ int curadchan;
+};
+
+#define devpriv ((struct dt2814_private *)dev->private)
+
+#define DT2814_TIMEOUT 10
+#define DT2814_MAX_SPEED 100000 /* Arbitrary 10 khz limit */
+
+static int dt2814_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i, hi, lo;
+ int chan;
+ int status = 0;
+
+ for (n = 0; n < insn->n; n++) {
+ chan = CR_CHAN(insn->chanspec);
+
+ outb(chan, dev->iobase + DT2814_CSR);
+ for (i = 0; i < DT2814_TIMEOUT; i++) {
+ status = inb(dev->iobase + DT2814_CSR);
+ printk("dt2814: status: %02x\n", status);
+ comedi_udelay(10);
+ if (status & DT2814_FINISH)
+ break;
+ }
+ if (i >= DT2814_TIMEOUT) {
+ printk("dt2814: status: %02x\n", status);
+ return -ETIMEDOUT;
+ }
+
+ hi = inb(dev->iobase + DT2814_DATA);
+ lo = inb(dev->iobase + DT2814_DATA);
+
+ data[n] = (hi << 4) | (lo >> 4);
+ }
+
+ return n;
+}
+
+static int dt2814_ns_to_timer(unsigned int *ns, unsigned int flags)
+{
+ int i;
+ unsigned int f;
+
+ /* XXX ignores flags */
+
+ f = 10000; /* ns */
+ for (i = 0; i < 8; i++) {
+ if ((2 * (*ns)) < (f * 11))
+ break;
+ f *= 10;
+ }
+
+ *ns = f;
+
+ return i;
+}
+
+static int dt2814_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->stop_src != TRIG_TIMER && cmd->stop_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg > 1000000000) {
+ cmd->scan_begin_arg = 1000000000;
+ err++;
+ }
+ if (cmd->scan_begin_arg < DT2814_MAX_SPEED) {
+ cmd->scan_begin_arg = DT2814_MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg < 2) {
+ cmd->stop_arg = 2;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->scan_begin_arg;
+ dt2814_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int dt2814_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int chan;
+ int trigvar;
+
+ trigvar =
+ dt2814_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+
+ chan = CR_CHAN(cmd->chanlist[0]);
+
+ devpriv->ntrig = cmd->stop_arg;
+ outb(chan | DT2814_ENB | (trigvar << 5), dev->iobase + DT2814_CSR);
+
+ return 0;
+
+}
+
+static int dt2814_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int i, irq;
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: dt2814: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, DT2814_SIZE, "dt2814")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "dt2814";
+
+ outb(0, dev->iobase + DT2814_CSR);
+ comedi_udelay(100);
+ if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) {
+ printk("reset error (fatal)\n");
+ return -EIO;
+ }
+ i = inb(dev->iobase + DT2814_DATA);
+ i = inb(dev->iobase + DT2814_DATA);
+
+ irq = it->options[1];
+#if 0
+ if (irq < 0) {
+ save_flags(flags);
+ sti();
+ irqs = probe_irq_on();
+
+ outb(0, dev->iobase + DT2814_CSR);
+
+ comedi_udelay(100);
+
+ irq = probe_irq_off(irqs);
+ restore_flags(flags);
+ if (inb(dev->iobase + DT2814_CSR) & DT2814_ERR) {
+ printk("error probing irq (bad) \n");
+ }
+
+ i = inb(dev->iobase + DT2814_DATA);
+ i = inb(dev->iobase + DT2814_DATA);
+ }
+#endif
+ dev->irq = 0;
+ if (irq > 0) {
+ if (comedi_request_irq(irq, dt2814_interrupt, 0, "dt2814", dev)) {
+ printk("(irq %d unavailable)\n", irq);
+ } else {
+ printk("( irq = %d )\n", irq);
+ dev->irq = irq;
+ }
+ } else if (irq == 0) {
+ printk("(no irq)\n");
+ } else {
+#if 0
+ printk("(probe returned multiple irqs--bad)\n");
+#else
+ printk("(irq probe not implemented)\n");
+#endif
+ }
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct dt2814_private))) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+ s->n_chan = 16; /* XXX */
+ s->len_chanlist = 1;
+ s->insn_read = dt2814_ai_insn_read;
+ s->do_cmd = dt2814_ai_cmd;
+ s->do_cmdtest = dt2814_ai_cmdtest;
+ s->maxdata = 0xfff;
+ s->range_table = &range_unknown; /* XXX */
+
+ return 0;
+}
+
+static int dt2814_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2814: remove\n", dev->minor);
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->iobase) {
+ release_region(dev->iobase, DT2814_SIZE);
+ }
+
+ return 0;
+}
+
+static irqreturn_t dt2814_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int lo, hi;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ int data;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ s = dev->subdevices + 0;
+
+ hi = inb(dev->iobase + DT2814_DATA);
+ lo = inb(dev->iobase + DT2814_DATA);
+
+ data = (hi << 4) | (lo >> 4);
+
+ if (!(--devpriv->ntrig)) {
+ int i;
+
+ outb(0, dev->iobase + DT2814_CSR);
+ /* note: turning off timed mode triggers another
+ sample. */
+
+ for (i = 0; i < DT2814_TIMEOUT; i++) {
+ if (inb(dev->iobase + DT2814_CSR) & DT2814_FINISH)
+ break;
+ }
+ inb(dev->iobase + DT2814_DATA);
+ inb(dev->iobase + DT2814_DATA);
+
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
diff --git a/drivers/staging/comedi/drivers/dt2815.c b/drivers/staging/comedi/drivers/dt2815.c
new file mode 100644
index 00000000000..fccec8a77d5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2815.c
@@ -0,0 +1,264 @@
+/*
+ comedi/drivers/dt2815.c
+ Hardware driver for Data Translation DT2815
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: dt2815
+Description: Data Translation DT2815
+Author: ds
+Status: mostly complete, untested
+Devices: [Data Translation] DT2815 (dt2815)
+
+I'm not sure anyone has ever tested this board. If you have information
+contrary, please update.
+
+Configuration options:
+ [0] - I/O port base base address
+ [1] - IRQ (unused)
+ [2] - Voltage unipolar/bipolar configuration
+ 0 == unipolar 5V (0V -- +5V)
+ 1 == bipolar 5V (-5V -- +5V)
+ [3] - Current offset configuration
+ 0 == disabled (0mA -- +32mAV)
+ 1 == enabled (+4mA -- +20mAV)
+ [4] - Firmware program configuration
+ 0 == program 1 (see manual table 5-4)
+ 1 == program 2 (see manual table 5-4)
+ 2 == program 3 (see manual table 5-4)
+ 3 == program 4 (see manual table 5-4)
+ [5] - Analog output 0 range configuration
+ 0 == voltage
+ 1 == current
+ [6] - Analog output 1 range configuration (same options)
+ [7] - Analog output 2 range configuration (same options)
+ [8] - Analog output 3 range configuration (same options)
+ [9] - Analog output 4 range configuration (same options)
+ [10] - Analog output 5 range configuration (same options)
+ [11] - Analog output 6 range configuration (same options)
+ [12] - Analog output 7 range configuration (same options)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+static const struct comedi_lrange range_dt2815_ao_32_current = { 1, {
+ RANGE_mA(0, 32)
+ }
+};
+static const struct comedi_lrange range_dt2815_ao_20_current = { 1, {
+ RANGE_mA(4, 20)
+ }
+};
+
+#define DT2815_SIZE 2
+
+#define DT2815_DATA 0
+#define DT2815_STATUS 1
+
+static int dt2815_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2815_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2815 = {
+ driver_name:"dt2815",
+ module:THIS_MODULE,
+ attach:dt2815_attach,
+ detach:dt2815_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2815);
+
+static void dt2815_free_resources(struct comedi_device * dev);
+
+struct dt2815_private {
+
+ const struct comedi_lrange *range_type_list[8];
+ unsigned int ao_readback[8];
+};
+
+
+#define devpriv ((struct dt2815_private *)dev->private)
+
+static int dt2815_wait_for_status(struct comedi_device * dev, int status)
+{
+ int i;
+
+ for (i = 0; i < 100; i++) {
+ if (inb(dev->iobase + DT2815_STATUS) == status)
+ break;
+ }
+ return status;
+}
+
+static int dt2815_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int dt2815_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int status;
+ unsigned int lo, hi;
+
+ for (i = 0; i < insn->n; i++) {
+ lo = ((data[i] & 0x0f) << 4) | (chan << 1) | 0x01;
+ hi = (data[i] & 0xff0) >> 4;
+
+ status = dt2815_wait_for_status(dev, 0x00);
+ if (status != 0) {
+ rt_printk
+ ("dt2815: failed to write low byte on %d reason %x\n",
+ chan, status);
+ return -EBUSY;
+ }
+
+ outb(lo, dev->iobase + DT2815_DATA);
+
+ status = dt2815_wait_for_status(dev, 0x10);
+ if (status != 0x10) {
+ rt_printk
+ ("dt2815: failed to write high byte on %d reason %x\n",
+ chan, status);
+ return -EBUSY;
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+ return i;
+}
+
+/*
+ options[0] Board base address
+ options[1] IRQ (not applicable)
+ options[2] Voltage unipolar/bipolar configuration
+ 0 == unipolar 5V (0V -- +5V)
+ 1 == bipolar 5V (-5V -- +5V)
+ options[3] Current offset configuration
+ 0 == disabled (0mA -- +32mAV)
+ 1 == enabled (+4mA -- +20mAV)
+ options[4] Firmware program configuration
+ 0 == program 1 (see manual table 5-4)
+ 1 == program 2 (see manual table 5-4)
+ 2 == program 3 (see manual table 5-4)
+ 3 == program 4 (see manual table 5-4)
+ options[5] Analog output 0 range configuration
+ 0 == voltage
+ 1 == current
+ options[6] Analog output 1 range configuration
+ ...
+ options[12] Analog output 7 range configuration
+ 0 == voltage
+ 1 == current
+ */
+
+static int dt2815_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+ const struct comedi_lrange *current_range_type, *voltage_range_type;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: dt2815: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, DT2815_SIZE, "dt2815")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = "dt2815";
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+ if (alloc_private(dev, sizeof(struct dt2815_private)) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 0xfff;
+ s->n_chan = 8;
+ s->insn_write = dt2815_ao_insn;
+ s->insn_read = dt2815_ao_insn_read;
+ s->range_table_list = devpriv->range_type_list;
+
+ current_range_type = (it->options[3])
+ ? &range_dt2815_ao_20_current : &range_dt2815_ao_32_current;
+ voltage_range_type = (it->options[2])
+ ? &range_bipolar5 : &range_unipolar5;
+ for (i = 0; i < 8; i++) {
+ devpriv->range_type_list[i] = (it->options[5 + i])
+ ? current_range_type : voltage_range_type;
+ }
+
+ /* Init the 2815 */
+ outb(0x00, dev->iobase + DT2815_STATUS);
+ for (i = 0; i < 100; i++) {
+ /* This is incredibly slow (approx 20 ms) */
+ unsigned int status;
+
+ comedi_udelay(1000);
+ status = inb(dev->iobase + DT2815_STATUS);
+ if (status == 4) {
+ unsigned int program;
+ program = (it->options[4] & 0x3) << 3 | 0x7;
+ outb(program, dev->iobase + DT2815_DATA);
+ printk(", program: 0x%x (@t=%d)\n", program, i);
+ break;
+ } else if (status != 0x00) {
+ printk("dt2815: unexpected status 0x%x (@t=%d)\n",
+ status, i);
+ if (status & 0x60) {
+ outb(0x00, dev->iobase + DT2815_STATUS);
+ }
+ }
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static void dt2815_free_resources(struct comedi_device * dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, DT2815_SIZE);
+}
+
+static int dt2815_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2815: remove\n", dev->minor);
+
+ dt2815_free_resources(dev);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt2817.c b/drivers/staging/comedi/drivers/dt2817.c
new file mode 100644
index 00000000000..2dc396a44e6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt2817.c
@@ -0,0 +1,178 @@
+/*
+ comedi/drivers/dt2817.c
+ Hardware driver for Data Translation DT2817
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dt2817
+Description: Data Translation DT2817
+Author: ds
+Status: complete
+Devices: [Data Translation] DT2817 (dt2817)
+
+A very simple digital I/O card. Four banks of 8 lines, each bank
+is configurable for input or output. One wonders why it takes a
+50 page manual to describe this thing.
+
+The driver (which, btw, is much less than 50 pages) has 1 subdevice
+with 32 channels, configurable in groups of 8.
+
+Configuration options:
+ [0] - I/O port base base address
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define DT2817_SIZE 5
+
+#define DT2817_CR 0
+#define DT2817_DATA 1
+
+static int dt2817_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt2817_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt2817 = {
+ driver_name:"dt2817",
+ module:THIS_MODULE,
+ attach:dt2817_attach,
+ detach:dt2817_detach,
+};
+
+COMEDI_INITCLEANUP(driver_dt2817);
+
+static int dt2817_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask;
+ int chan;
+ int oe = 0;
+
+ if (insn->n != 1)
+ return -EINVAL;
+
+ chan = CR_CHAN(insn->chanspec);
+ if (chan < 8) {
+ mask = 0xff;
+ } else if (chan < 16) {
+ mask = 0xff00;
+ } else if (chan < 24) {
+ mask = 0xff0000;
+ } else
+ mask = 0xff000000;
+ if (data[0])
+ s->io_bits |= mask;
+ else
+ s->io_bits &= ~mask;
+
+ if (s->io_bits & 0x000000ff)
+ oe |= 0x1;
+ if (s->io_bits & 0x0000ff00)
+ oe |= 0x2;
+ if (s->io_bits & 0x00ff0000)
+ oe |= 0x4;
+ if (s->io_bits & 0xff000000)
+ oe |= 0x8;
+
+ outb(oe, dev->iobase + DT2817_CR);
+
+ return 1;
+}
+
+static int dt2817_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int changed;
+
+ /* It's questionable whether it is more important in
+ * a driver like this to be deterministic or fast.
+ * We choose fast. */
+
+ if (data[0]) {
+ changed = s->state;
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ changed ^= s->state;
+ changed &= s->io_bits;
+ if (changed & 0x000000ff)
+ outb(s->state & 0xff, dev->iobase + DT2817_DATA + 0);
+ if (changed & 0x0000ff00)
+ outb((s->state >> 8) & 0xff,
+ dev->iobase + DT2817_DATA + 1);
+ if (changed & 0x00ff0000)
+ outb((s->state >> 16) & 0xff,
+ dev->iobase + DT2817_DATA + 2);
+ if (changed & 0xff000000)
+ outb((s->state >> 24) & 0xff,
+ dev->iobase + DT2817_DATA + 3);
+ }
+ data[1] = inb(dev->iobase + DT2817_DATA + 0);
+ data[1] |= (inb(dev->iobase + DT2817_DATA + 1) << 8);
+ data[1] |= (inb(dev->iobase + DT2817_DATA + 2) << 16);
+ data[1] |= (inb(dev->iobase + DT2817_DATA + 3) << 24);
+
+ return 2;
+}
+
+static int dt2817_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: dt2817: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, DT2817_SIZE, "dt2817")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "dt2817";
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+
+ s->n_chan = 32;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = dt2817_dio_insn_bits;
+ s->insn_config = dt2817_dio_insn_config;
+
+ s->state = 0;
+ outb(0, dev->iobase + DT2817_CR);
+
+ printk("\n");
+
+ return 0;
+}
+
+static int dt2817_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt2817: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, DT2817_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt282x.c b/drivers/staging/comedi/drivers/dt282x.c
new file mode 100644
index 00000000000..4882c3e679c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt282x.c
@@ -0,0 +1,1471 @@
+/*
+ comedi/drivers/dt282x.c
+ Hardware driver for Data Translation DT2821 series
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: dt282x
+Description: Data Translation DT2821 series (including DT-EZ)
+Author: ds
+Devices: [Data Translation] DT2821 (dt2821),
+ DT2821-F-16SE (dt2821-f), DT2821-F-8DI (dt2821-f),
+ DT2821-G-16SE (dt2821-f), DT2821-G-8DI (dt2821-g),
+ DT2823 (dt2823),
+ DT2824-PGH (dt2824-pgh), DT2824-PGL (dt2824-pgl), DT2825 (dt2825),
+ DT2827 (dt2827), DT2828 (dt2828), DT21-EZ (dt21-ez), DT23-EZ (dt23-ez),
+ DT24-EZ (dt24-ez), DT24-EZ-PGL (dt24-ez-pgl)
+Status: complete
+Updated: Wed, 22 Aug 2001 17:11:34 -0700
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ
+ [2] - DMA 1
+ [3] - DMA 2
+ [4] - AI jumpered for 0=single ended, 1=differential
+ [5] - AI jumpered for 0=straight binary, 1=2's complement
+ [6] - AO 0 jumpered for 0=straight binary, 1=2's complement
+ [7] - AO 1 jumpered for 0=straight binary, 1=2's complement
+ [8] - AI jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5]
+ [9] - AO 0 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
+ 4=[-2.5,2.5]
+ [10]- A0 1 jumpered for 0=[-10,10]V, 1=[0,10], 2=[-5,5], 3=[0,5],
+ 4=[-2.5,2.5]
+
+Notes:
+ - AO commands might be broken.
+ - If you try to run a command on both the AI and AO subdevices
+ simultaneously, bad things will happen. The driver needs to
+ be fixed to check for this situation and return an error.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include "comedi_fc.h"
+
+#define DEBUG
+
+#define DT2821_TIMEOUT 100 /* 500 us */
+#define DT2821_SIZE 0x10
+
+/*
+ * Registers in the DT282x
+ */
+
+#define DT2821_ADCSR 0x00 /* A/D Control/Status */
+#define DT2821_CHANCSR 0x02 /* Channel Control/Status */
+#define DT2821_ADDAT 0x04 /* A/D data */
+#define DT2821_DACSR 0x06 /* D/A Control/Status */
+#define DT2821_DADAT 0x08 /* D/A data */
+#define DT2821_DIODAT 0x0a /* digital data */
+#define DT2821_SUPCSR 0x0c /* Supervisor Control/Status */
+#define DT2821_TMRCTR 0x0e /* Timer/Counter */
+
+/*
+ * At power up, some registers are in a well-known state. The
+ * masks and values are as follows:
+ */
+
+#define DT2821_ADCSR_MASK 0xfff0
+#define DT2821_ADCSR_VAL 0x7c00
+
+#define DT2821_CHANCSR_MASK 0xf0f0
+#define DT2821_CHANCSR_VAL 0x70f0
+
+#define DT2821_DACSR_MASK 0x7c93
+#define DT2821_DACSR_VAL 0x7c90
+
+#define DT2821_SUPCSR_MASK 0xf8ff
+#define DT2821_SUPCSR_VAL 0x0000
+
+#define DT2821_TMRCTR_MASK 0xff00
+#define DT2821_TMRCTR_VAL 0xf000
+
+/*
+ * Bit fields of each register
+ */
+
+/* ADCSR */
+
+#define DT2821_ADERR 0x8000 /* (R) 1 for A/D error */
+#define DT2821_ADCLK 0x0200 /* (R/W) A/D clock enable */
+ /* 0x7c00 read as 1's */
+#define DT2821_MUXBUSY 0x0100 /* (R) multiplexer busy */
+#define DT2821_ADDONE 0x0080 /* (R) A/D done */
+#define DT2821_IADDONE 0x0040 /* (R/W) interrupt on A/D done */
+ /* 0x0030 gain select */
+ /* 0x000f channel select */
+
+/* CHANCSR */
+
+#define DT2821_LLE 0x8000 /* (R/W) Load List Enable */
+ /* 0x7000 read as 1's */
+ /* 0x0f00 (R) present address */
+ /* 0x00f0 read as 1's */
+ /* 0x000f (R) number of entries - 1 */
+
+/* DACSR */
+
+#define DT2821_DAERR 0x8000 /* (R) D/A error */
+#define DT2821_YSEL 0x0200 /* (R/W) DAC 1 select */
+#define DT2821_SSEL 0x0100 /* (R/W) single channel select */
+#define DT2821_DACRDY 0x0080 /* (R) DAC ready */
+#define DT2821_IDARDY 0x0040 /* (R/W) interrupt on DAC ready */
+#define DT2821_DACLK 0x0020 /* (R/W) D/A clock enable */
+#define DT2821_HBOE 0x0002 /* (R/W) DIO high byte output enable */
+#define DT2821_LBOE 0x0001 /* (R/W) DIO low byte output enable */
+
+/* SUPCSR */
+
+#define DT2821_DMAD 0x8000 /* (R) DMA done */
+#define DT2821_ERRINTEN 0x4000 /* (R/W) interrupt on error */
+#define DT2821_CLRDMADNE 0x2000 /* (W) clear DMA done */
+#define DT2821_DDMA 0x1000 /* (R/W) dual DMA */
+#define DT2821_DS1 0x0800 /* (R/W) DMA select 1 */
+#define DT2821_DS0 0x0400 /* (R/W) DMA select 0 */
+#define DT2821_BUFFB 0x0200 /* (R/W) buffer B selected */
+#define DT2821_SCDN 0x0100 /* (R) scan done */
+#define DT2821_DACON 0x0080 /* (W) DAC single conversion */
+#define DT2821_ADCINIT 0x0040 /* (W) A/D initialize */
+#define DT2821_DACINIT 0x0020 /* (W) D/A initialize */
+#define DT2821_PRLD 0x0010 /* (W) preload multiplexer */
+#define DT2821_STRIG 0x0008 /* (W) software trigger */
+#define DT2821_XTRIG 0x0004 /* (R/W) external trigger enable */
+#define DT2821_XCLK 0x0002 /* (R/W) external clock enable */
+#define DT2821_BDINIT 0x0001 /* (W) initialize board */
+
+static const struct comedi_lrange range_dt282x_ai_lo_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25)
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_lo_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25)
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_5_bipolar = { 4, {
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25),
+ RANGE(-0.625, 0.625),
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_5_unipolar = { 4, {
+ RANGE(0, 5),
+ RANGE(0, 2.5),
+ RANGE(0, 1.25),
+ RANGE(0, 0.625),
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_hi_bipolar = { 4, {
+ RANGE(-10, 10),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02)
+ }
+};
+static const struct comedi_lrange range_dt282x_ai_hi_unipolar = { 4, {
+ RANGE(0, 10),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ RANGE(0, 0.02)
+ }
+};
+
+struct dt282x_board {
+ const char *name;
+ int adbits;
+ int adchan_se;
+ int adchan_di;
+ int ai_speed;
+ int ispgl;
+ int dachan;
+ int dabits;
+};
+
+static const struct dt282x_board boardtypes[] = {
+ {name:"dt2821",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2821-f",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:6500,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2821-g",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:4000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2823",
+ adbits: 16,
+ adchan_se:0,
+ adchan_di:4,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 16,
+ },
+ {name:"dt2824-pgh",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 0,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt2824-pgl",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 1,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt2825",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:20000,
+ ispgl: 1,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2827",
+ adbits: 16,
+ adchan_se:0,
+ adchan_di:4,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2828",
+ adbits: 12,
+ adchan_se:4,
+ adchan_di:0,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt2829",
+ adbits: 16,
+ adchan_se:8,
+ adchan_di:0,
+ ai_speed:33250,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 16,
+ },
+ {name:"dt21-ez",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt23-ez",
+ adbits: 16,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt24-ez",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 0,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt24-ez-pgl",
+ adbits: 12,
+ adchan_se:16,
+ adchan_di:8,
+ ai_speed:10000,
+ ispgl: 1,
+ dachan: 0,
+ dabits: 0,
+ },
+};
+
+#define n_boardtypes sizeof(boardtypes)/sizeof(struct dt282x_board)
+#define this_board ((const struct dt282x_board *)dev->board_ptr)
+
+struct dt282x_private {
+ int ad_2scomp; /* we have 2's comp jumper set */
+ int da0_2scomp; /* same, for DAC0 */
+ int da1_2scomp; /* same, for DAC1 */
+
+ const struct comedi_lrange *darangelist[2];
+
+ short ao[2];
+
+ volatile int dacsr; /* software copies of registers */
+ volatile int adcsr;
+ volatile int supcsr;
+
+ volatile int ntrig;
+ volatile int nread;
+
+ struct {
+ int chan;
+ short *buf; /* DMA buffer */
+ volatile int size; /* size of current transfer */
+ } dma[2];
+ int dma_maxsize; /* max size of DMA transfer (in bytes) */
+ int usedma; /* driver uses DMA */
+ volatile int current_dma_index;
+ int dma_dir;
+};
+
+#define devpriv ((struct dt282x_private *)dev->private)
+#define boardtype (*(const struct dt282x_board *)dev->board_ptr)
+
+/*
+ * Some useless abstractions
+ */
+#define chan_to_DAC(a) ((a)&1)
+#define update_dacsr(a) outw(devpriv->dacsr|(a),dev->iobase+DT2821_DACSR)
+#define update_adcsr(a) outw(devpriv->adcsr|(a),dev->iobase+DT2821_ADCSR)
+#define mux_busy() (inw(dev->iobase+DT2821_ADCSR)&DT2821_MUXBUSY)
+#define ad_done() (inw(dev->iobase+DT2821_ADCSR)&DT2821_ADDONE)
+#define update_supcsr(a) outw(devpriv->supcsr|(a),dev->iobase+DT2821_SUPCSR)
+
+/*
+ * danger! macro abuse... a is the expression to wait on, and b is
+ * the statement(s) to execute if it doesn't happen.
+ */
+#define wait_for(a,b) \
+ do{ \
+ int _i; \
+ for(_i=0;_i<DT2821_TIMEOUT;_i++){ \
+ if(a){_i=0;break;} \
+ comedi_udelay(5); \
+ } \
+ if(_i){b} \
+ }while(0)
+
+static int dt282x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt282x_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt282x = {
+ driver_name:"dt282x",
+ module:THIS_MODULE,
+ attach:dt282x_attach,
+ detach:dt282x_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct dt282x_board),
+};
+
+COMEDI_INITCLEANUP(driver_dt282x);
+
+static void free_resources(struct comedi_device * dev);
+static int prep_ai_dma(struct comedi_device * dev, int chan, int size);
+static int prep_ao_dma(struct comedi_device * dev, int chan, int size);
+static int dt282x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt282x_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt282x_ns_to_timer(int *nanosec, int round_mode);
+static void dt282x_disable_dma(struct comedi_device * dev);
+
+static int dt282x_grab_dma(struct comedi_device * dev, int dma1, int dma2);
+
+static void dt282x_munge(struct comedi_device * dev, short * buf,
+ unsigned int nbytes)
+{
+ unsigned int i;
+ unsigned short mask = (1 << boardtype.adbits) - 1;
+ unsigned short sign = 1 << (boardtype.adbits - 1);
+ int n;
+
+ if (devpriv->ad_2scomp) {
+ sign = 1 << (boardtype.adbits - 1);
+ } else {
+ sign = 0;
+ }
+
+ if (nbytes % 2)
+ comedi_error(dev, "bug! odd number of bytes from dma xfer");
+ n = nbytes / 2;
+ for (i = 0; i < n; i++) {
+ buf[i] = (buf[i] & mask) ^ sign;
+ }
+}
+
+static void dt282x_ao_dma_interrupt(struct comedi_device * dev)
+{
+ void *ptr;
+ int size;
+ int i;
+ struct comedi_subdevice *s = dev->subdevices + 1;
+
+ update_supcsr(DT2821_CLRDMADNE);
+
+ if (!s->async->prealloc_buf) {
+ printk("async->data disappeared. dang!\n");
+ return;
+ }
+
+ i = devpriv->current_dma_index;
+ ptr = devpriv->dma[i].buf;
+
+ disable_dma(devpriv->dma[i].chan);
+
+ devpriv->current_dma_index = 1 - i;
+
+ size = cfc_read_array_from_buffer(s, ptr, devpriv->dma_maxsize);
+ if (size == 0) {
+ rt_printk("dt282x: AO underrun\n");
+ dt282x_ao_cancel(dev, s);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ return;
+ }
+ prep_ao_dma(dev, i, size);
+ return;
+}
+
+static void dt282x_ai_dma_interrupt(struct comedi_device * dev)
+{
+ void *ptr;
+ int size;
+ int i;
+ int ret;
+ struct comedi_subdevice *s = dev->subdevices;
+
+ update_supcsr(DT2821_CLRDMADNE);
+
+ if (!s->async->prealloc_buf) {
+ printk("async->data disappeared. dang!\n");
+ return;
+ }
+
+ i = devpriv->current_dma_index;
+ ptr = devpriv->dma[i].buf;
+ size = devpriv->dma[i].size;
+
+ disable_dma(devpriv->dma[i].chan);
+
+ devpriv->current_dma_index = 1 - i;
+
+ dt282x_munge(dev, ptr, size);
+ ret = cfc_write_array_to_buffer(s, ptr, size);
+ if (ret != size) {
+ dt282x_ai_cancel(dev, s);
+ return;
+ }
+ devpriv->nread -= size / 2;
+
+ if (devpriv->nread < 0) {
+ printk("dt282x: off by one\n");
+ devpriv->nread = 0;
+ }
+ if (!devpriv->nread) {
+ dt282x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ return;
+ }
+#if 0
+ /* clear the dual dma flag, making this the last dma segment */
+ /* XXX probably wrong */
+ if (!devpriv->ntrig) {
+ devpriv->supcsr &= ~(DT2821_DDMA);
+ update_supcsr(0);
+ }
+#endif
+ /* restart the channel */
+ prep_ai_dma(dev, i, 0);
+}
+
+static int prep_ai_dma(struct comedi_device * dev, int dma_index, int n)
+{
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
+
+ if (!devpriv->ntrig)
+ return 0;
+
+ if (n == 0)
+ n = devpriv->dma_maxsize;
+ if (n > devpriv->ntrig * 2)
+ n = devpriv->ntrig * 2;
+ devpriv->ntrig -= n / 2;
+
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+ set_dma_mode(dma_chan, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
+}
+
+static int prep_ao_dma(struct comedi_device * dev, int dma_index, int n)
+{
+ int dma_chan;
+ unsigned long dma_ptr;
+ unsigned long flags;
+
+ devpriv->dma[dma_index].size = n;
+ dma_chan = devpriv->dma[dma_index].chan;
+ dma_ptr = virt_to_bus(devpriv->dma[dma_index].buf);
+
+ set_dma_mode(dma_chan, DMA_MODE_WRITE);
+ flags = claim_dma_lock();
+ clear_dma_ff(dma_chan);
+ set_dma_addr(dma_chan, dma_ptr);
+ set_dma_count(dma_chan, n);
+ release_dma_lock(flags);
+
+ enable_dma(dma_chan);
+
+ return n;
+}
+
+static irqreturn_t dt282x_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ struct comedi_subdevice *s_ao;
+ unsigned int supcsr, adcsr, dacsr;
+ int handled = 0;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ s = dev->subdevices + 0;
+ s_ao = dev->subdevices + 1;
+ adcsr = inw(dev->iobase + DT2821_ADCSR);
+ dacsr = inw(dev->iobase + DT2821_DACSR);
+ supcsr = inw(dev->iobase + DT2821_SUPCSR);
+ if (supcsr & DT2821_DMAD) {
+ if (devpriv->dma_dir == DMA_MODE_READ)
+ dt282x_ai_dma_interrupt(dev);
+ else
+ dt282x_ao_dma_interrupt(dev);
+ handled = 1;
+ }
+ if (adcsr & DT2821_ADERR) {
+ if (devpriv->nread != 0) {
+ comedi_error(dev, "A/D error");
+ dt282x_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ handled = 1;
+ }
+ if (dacsr & DT2821_DAERR) {
+#if 0
+ static int warn = 5;
+ if (--warn <= 0) {
+ disable_irq(dev->irq);
+ printk("disabling irq\n");
+ }
+#endif
+ comedi_error(dev, "D/A error");
+ dt282x_ao_cancel(dev, s_ao);
+ s->async->events |= COMEDI_CB_ERROR;
+ handled = 1;
+ }
+#if 0
+ if (adcsr & DT2821_ADDONE) {
+ int ret;
+ short data;
+
+ data = (short) inw(dev->iobase + DT2821_ADDAT);
+ data &= (1 << boardtype.adbits) - 1;
+ if (devpriv->ad_2scomp) {
+ data ^= 1 << (boardtype.adbits - 1);
+ }
+ ret = comedi_buf_put(s->async, data);
+ if (ret == 0) {
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+
+ devpriv->nread--;
+ if (!devpriv->nread) {
+ s->async->events |= COMEDI_CB_EOA;
+ } else {
+ if (supcsr & DT2821_SCDN)
+ update_supcsr(DT2821_STRIG);
+ }
+ handled = 1;
+ }
+#endif
+ comedi_event(dev, s);
+ /* printk("adcsr=0x%02x dacsr-0x%02x supcsr=0x%02x\n", adcsr, dacsr, supcsr); */
+ return IRQ_RETVAL(handled);
+}
+
+static void dt282x_load_changain(struct comedi_device * dev, int n,
+ unsigned int *chanlist)
+{
+ unsigned int i;
+ unsigned int chan, range;
+
+ outw(DT2821_LLE | (n - 1), dev->iobase + DT2821_CHANCSR);
+ for (i = 0; i < n; i++) {
+ chan = CR_CHAN(chanlist[i]);
+ range = CR_RANGE(chanlist[i]);
+ update_adcsr((range << 4) | (chan));
+ }
+ outw(n - 1, dev->iobase + DT2821_CHANCSR);
+}
+
+/*
+ * Performs a single A/D conversion.
+ * - Put channel/gain into channel-gain list
+ * - preload multiplexer
+ * - trigger conversion and wait for it to finish
+ */
+static int dt282x_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ /* XXX should we really be enabling the ad clock here? */
+ devpriv->adcsr = DT2821_ADCLK;
+ update_adcsr(0);
+
+ dt282x_load_changain(dev, 1, &insn->chanspec);
+
+ update_supcsr(DT2821_PRLD);
+ wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
+ return -ETIME;
+ );
+
+ for (i = 0; i < insn->n; i++) {
+ update_supcsr(DT2821_STRIG);
+ wait_for(ad_done(), comedi_error(dev, "timeout\n");
+ return -ETIME;
+ );
+
+ data[i] =
+ inw(dev->iobase +
+ DT2821_ADDAT) & ((1 << boardtype.adbits) - 1);
+ if (devpriv->ad_2scomp)
+ data[i] ^= (1 << (boardtype.adbits - 1));
+ }
+
+ return i;
+}
+
+static int dt282x_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_arg < 4000) {
+ /* XXX board dependent */
+ cmd->convert_arg = 4000;
+ err++;
+ }
+#define SLOWEST_TIMER (250*(1<<15)*255)
+ if (cmd->convert_arg > SLOWEST_TIMER) {
+ cmd->convert_arg = SLOWEST_TIMER;
+ err++;
+ }
+ if (cmd->convert_arg < this_board->ai_speed) {
+ cmd->convert_arg = this_board->ai_speed;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->convert_arg;
+ dt282x_ns_to_timer(&cmd->convert_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int dt282x_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int timer;
+
+ if (devpriv->usedma == 0) {
+ comedi_error(dev,
+ "driver requires 2 dma channels to execute command");
+ return -EIO;
+ }
+
+ dt282x_disable_dma(dev);
+
+ if (cmd->convert_arg < this_board->ai_speed)
+ cmd->convert_arg = this_board->ai_speed;
+ timer = dt282x_ns_to_timer(&cmd->convert_arg, TRIG_ROUND_NEAREST);
+ outw(timer, dev->iobase + DT2821_TMRCTR);
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0;
+ } else {
+ /* external trigger */
+ devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS0 | DT2821_DS1;
+ }
+ update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_ADCINIT);
+
+ devpriv->ntrig = cmd->stop_arg * cmd->scan_end_arg;
+ devpriv->nread = devpriv->ntrig;
+
+ devpriv->dma_dir = DMA_MODE_READ;
+ devpriv->current_dma_index = 0;
+ prep_ai_dma(dev, 0, 0);
+ if (devpriv->ntrig) {
+ prep_ai_dma(dev, 1, 0);
+ devpriv->supcsr |= DT2821_DDMA;
+ update_supcsr(0);
+ }
+
+ devpriv->adcsr = 0;
+
+ dt282x_load_changain(dev, cmd->chanlist_len, cmd->chanlist);
+
+ devpriv->adcsr = DT2821_ADCLK | DT2821_IADDONE;
+ update_adcsr(0);
+
+ update_supcsr(DT2821_PRLD);
+ wait_for(!mux_busy(), comedi_error(dev, "timeout\n");
+ return -ETIME;
+ );
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ update_supcsr(DT2821_STRIG);
+ } else {
+ devpriv->supcsr |= DT2821_XTRIG;
+ update_supcsr(0);
+ }
+
+ return 0;
+}
+
+static void dt282x_disable_dma(struct comedi_device * dev)
+{
+ if (devpriv->usedma) {
+ disable_dma(devpriv->dma[0].chan);
+ disable_dma(devpriv->dma[1].chan);
+ }
+}
+
+static int dt282x_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ dt282x_disable_dma(dev);
+
+ devpriv->adcsr = 0;
+ update_adcsr(0);
+
+ devpriv->supcsr = 0;
+ update_supcsr(DT2821_ADCINIT);
+
+ return 0;
+}
+
+static int dt282x_ns_to_timer(int *nanosec, int round_mode)
+{
+ int prescale, base, divider;
+
+ for (prescale = 0; prescale < 16; prescale++) {
+ if (prescale == 1)
+ continue;
+ base = 250 * (1 << prescale);
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec + base - 1) / base;
+ break;
+ }
+ if (divider < 256) {
+ *nanosec = divider * base;
+ return (prescale << 8) | (255 - divider);
+ }
+ }
+ base = 250 * (1 << 15);
+ divider = 255;
+ *nanosec = divider * base;
+ return (15 << 8) | (255 - divider);
+}
+
+/*
+ * Analog output routine. Selects single channel conversion,
+ * selects correct channel, converts from 2's compliment to
+ * offset binary if necessary, loads the data into the DAC
+ * data register, and performs the conversion.
+ */
+static int dt282x_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int dt282x_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ short d;
+ unsigned int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ d = data[0];
+ d &= (1 << boardtype.dabits) - 1;
+ devpriv->ao[chan] = d;
+
+ devpriv->dacsr |= DT2821_SSEL;
+
+ if (chan) {
+ /* select channel */
+ devpriv->dacsr |= DT2821_YSEL;
+ if (devpriv->da0_2scomp)
+ d ^= (1 << (boardtype.dabits - 1));
+ } else {
+ devpriv->dacsr &= ~DT2821_YSEL;
+ if (devpriv->da1_2scomp)
+ d ^= (1 << (boardtype.dabits - 1));
+ }
+
+ update_dacsr(0);
+
+ outw(d, dev->iobase + DT2821_DADAT);
+
+ update_supcsr(DT2821_DACON);
+
+ return 1;
+}
+
+static int dt282x_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg < 5000 /* XXX unknown */ ) {
+ cmd->scan_begin_arg = 5000;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg > 2) {
+ /* XXX chanlist stuff? */
+ cmd->scan_end_arg = 2;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->scan_begin_arg;
+ dt282x_ns_to_timer(&cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ return 0;
+
+}
+
+static int dt282x_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int x)
+{
+ int size;
+
+ if (x != 0)
+ return -EINVAL;
+
+ size = cfc_read_array_from_buffer(s, devpriv->dma[0].buf,
+ devpriv->dma_maxsize);
+ if (size == 0) {
+ rt_printk("dt282x: AO underrun\n");
+ return -EPIPE;
+ }
+ prep_ao_dma(dev, 0, size);
+
+ size = cfc_read_array_from_buffer(s, devpriv->dma[1].buf,
+ devpriv->dma_maxsize);
+ if (size == 0) {
+ rt_printk("dt282x: AO underrun\n");
+ return -EPIPE;
+ }
+ prep_ao_dma(dev, 1, size);
+
+ update_supcsr(DT2821_STRIG);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
+static int dt282x_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int timer;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (devpriv->usedma == 0) {
+ comedi_error(dev,
+ "driver requires 2 dma channels to execute command");
+ return -EIO;
+ }
+
+ dt282x_disable_dma(dev);
+
+ devpriv->supcsr = DT2821_ERRINTEN | DT2821_DS1 | DT2821_DDMA;
+ update_supcsr(DT2821_CLRDMADNE | DT2821_BUFFB | DT2821_DACINIT);
+
+ devpriv->ntrig = cmd->stop_arg * cmd->chanlist_len;
+ devpriv->nread = devpriv->ntrig;
+
+ devpriv->dma_dir = DMA_MODE_WRITE;
+ devpriv->current_dma_index = 0;
+
+ timer = dt282x_ns_to_timer(&cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
+ outw(timer, dev->iobase + DT2821_TMRCTR);
+
+ devpriv->dacsr = DT2821_SSEL | DT2821_DACLK | DT2821_IDARDY;
+ update_dacsr(0);
+
+ s->async->inttrig = dt282x_ao_inttrig;
+
+ return 0;
+}
+
+static int dt282x_ao_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ dt282x_disable_dma(dev);
+
+ devpriv->dacsr = 0;
+ update_dacsr(0);
+
+ devpriv->supcsr = 0;
+ update_supcsr(DT2821_DACINIT);
+
+ return 0;
+}
+
+static int dt282x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ outw(s->state, dev->iobase + DT2821_DIODAT);
+ }
+ data[1] = inw(dev->iobase + DT2821_DIODAT);
+
+ return 2;
+}
+
+static int dt282x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask;
+
+ mask = (CR_CHAN(insn->chanspec) < 8) ? 0x00ff : 0xff00;
+ if (data[0])
+ s->io_bits |= mask;
+ else
+ s->io_bits &= ~mask;
+
+ if (s->io_bits & 0x00ff)
+ devpriv->dacsr |= DT2821_LBOE;
+ else
+ devpriv->dacsr &= ~DT2821_LBOE;
+ if (s->io_bits & 0xff00)
+ devpriv->dacsr |= DT2821_HBOE;
+ else
+ devpriv->dacsr &= ~DT2821_HBOE;
+
+ outw(devpriv->dacsr, dev->iobase + DT2821_DACSR);
+
+ return 1;
+}
+
+static const struct comedi_lrange *const ai_range_table[] = {
+ &range_dt282x_ai_lo_bipolar,
+ &range_dt282x_ai_lo_unipolar,
+ &range_dt282x_ai_5_bipolar,
+ &range_dt282x_ai_5_unipolar
+};
+static const struct comedi_lrange *const ai_range_pgl_table[] = {
+ &range_dt282x_ai_hi_bipolar,
+ &range_dt282x_ai_hi_unipolar
+};
+static const struct comedi_lrange *opt_ai_range_lkup(int ispgl, int x)
+{
+ if (ispgl) {
+ if (x < 0 || x >= 2)
+ x = 0;
+ return ai_range_pgl_table[x];
+ } else {
+ if (x < 0 || x >= 4)
+ x = 0;
+ return ai_range_table[x];
+ }
+}
+static const struct comedi_lrange *const ao_range_table[] = {
+ &range_bipolar10,
+ &range_unipolar10,
+ &range_bipolar5,
+ &range_unipolar5,
+ &range_bipolar2_5
+};
+static const struct comedi_lrange *opt_ao_range_lkup(int x)
+{
+ if (x < 0 || x >= 5)
+ x = 0;
+ return ao_range_table[x];
+}
+
+enum { opt_iobase = 0, opt_irq, opt_dma1, opt_dma2, /* i/o base, irq, dma channels */
+ opt_diff, /* differential */
+ opt_ai_twos, opt_ao0_twos, opt_ao1_twos, /* twos comp */
+ opt_ai_range, opt_ao0_range, opt_ao1_range, /* range */
+};
+
+/*
+ options:
+ 0 i/o base
+ 1 irq
+ 2 dma1
+ 3 dma2
+ 4 0=single ended, 1=differential
+ 5 ai 0=straight binary, 1=2's comp
+ 6 ao0 0=straight binary, 1=2's comp
+ 7 ao1 0=straight binary, 1=2's comp
+ 8 ai 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V
+ 9 ao0 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V
+ 10 ao1 0=±10 V, 1=0-10 V, 2=±5 V, 3=0-5 V, 4=±2.5 V
+ */
+static int dt282x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int i, irq;
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ dev->board_name = this_board->name;
+
+ iobase = it->options[opt_iobase];
+ if (!iobase)
+ iobase = 0x240;
+
+ printk("comedi%d: dt282x: 0x%04lx", dev->minor, iobase);
+ if (!request_region(iobase, DT2821_SIZE, "dt282x")) {
+ printk(" I/O port conflict\n");
+ return -EBUSY;
+ }
+ dev->iobase = iobase;
+
+ outw(DT2821_BDINIT, dev->iobase + DT2821_SUPCSR);
+ i = inw(dev->iobase + DT2821_ADCSR);
+#ifdef DEBUG
+ printk(" fingerprint=%x,%x,%x,%x,%x",
+ inw(dev->iobase + DT2821_ADCSR),
+ inw(dev->iobase + DT2821_CHANCSR),
+ inw(dev->iobase + DT2821_DACSR),
+ inw(dev->iobase + DT2821_SUPCSR),
+ inw(dev->iobase + DT2821_TMRCTR));
+#endif
+
+ if (((inw(dev->iobase + DT2821_ADCSR) & DT2821_ADCSR_MASK)
+ != DT2821_ADCSR_VAL) ||
+ ((inw(dev->iobase + DT2821_CHANCSR) & DT2821_CHANCSR_MASK)
+ != DT2821_CHANCSR_VAL) ||
+ ((inw(dev->iobase + DT2821_DACSR) & DT2821_DACSR_MASK)
+ != DT2821_DACSR_VAL) ||
+ ((inw(dev->iobase + DT2821_SUPCSR) & DT2821_SUPCSR_MASK)
+ != DT2821_SUPCSR_VAL) ||
+ ((inw(dev->iobase + DT2821_TMRCTR) & DT2821_TMRCTR_MASK)
+ != DT2821_TMRCTR_VAL)) {
+ printk(" board not found");
+ return -EIO;
+ }
+ /* should do board test */
+
+ irq = it->options[opt_irq];
+#if 0
+ if (irq < 0) {
+ unsigned long flags;
+ int irqs;
+
+ save_flags(flags);
+ sti();
+ irqs = probe_irq_on();
+
+ /* trigger interrupt */
+
+ comedi_udelay(100);
+
+ irq = probe_irq_off(irqs);
+ restore_flags(flags);
+ if (0 /* error */ ) {
+ printk(" error probing irq (bad)");
+ }
+ }
+#endif
+ if (irq > 0) {
+ printk(" ( irq = %d )", irq);
+ ret = comedi_request_irq(irq, dt282x_interrupt, 0, "dt282x",
+ dev);
+ if (ret < 0) {
+ printk(" failed to get irq\n");
+ return -EIO;
+ }
+ dev->irq = irq;
+ } else if (irq == 0) {
+ printk(" (no irq)");
+ } else {
+#if 0
+ printk(" (probe returned multiple irqs--bad)");
+#else
+ printk(" (irq probe not implemented)");
+#endif
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct dt282x_private))) < 0)
+ return ret;
+
+ ret = dt282x_grab_dma(dev, it->options[opt_dma1],
+ it->options[opt_dma2]);
+ if (ret < 0)
+ return ret;
+
+ if ((ret = alloc_subdevices(dev, 3)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+
+ dev->read_subdev = s;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ |
+ ((it->options[opt_diff]) ? SDF_DIFF : SDF_COMMON);
+ s->n_chan =
+ (it->options[opt_diff]) ? boardtype.adchan_di : boardtype.
+ adchan_se;
+ s->insn_read = dt282x_ai_insn_read;
+ s->do_cmdtest = dt282x_ai_cmdtest;
+ s->do_cmd = dt282x_ai_cmd;
+ s->cancel = dt282x_ai_cancel;
+ s->maxdata = (1 << boardtype.adbits) - 1;
+ s->len_chanlist = 16;
+ s->range_table =
+ opt_ai_range_lkup(boardtype.ispgl, it->options[opt_ai_range]);
+ devpriv->ad_2scomp = it->options[opt_ai_twos];
+
+ s++;
+ if ((s->n_chan = boardtype.dachan)) {
+ /* ao subsystem */
+ s->type = COMEDI_SUBD_AO;
+ dev->write_subdev = s;
+ s->subdev_flags = SDF_WRITABLE | SDF_CMD_WRITE;
+ s->insn_read = dt282x_ao_insn_read;
+ s->insn_write = dt282x_ao_insn_write;
+ s->do_cmdtest = dt282x_ao_cmdtest;
+ s->do_cmd = dt282x_ao_cmd;
+ s->cancel = dt282x_ao_cancel;
+ s->maxdata = (1 << boardtype.dabits) - 1;
+ s->len_chanlist = 2;
+ s->range_table_list = devpriv->darangelist;
+ devpriv->darangelist[0] =
+ opt_ao_range_lkup(it->options[opt_ao0_range]);
+ devpriv->darangelist[1] =
+ opt_ao_range_lkup(it->options[opt_ao1_range]);
+ devpriv->da0_2scomp = it->options[opt_ao0_twos];
+ devpriv->da1_2scomp = it->options[opt_ao1_twos];
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s++;
+ /* dio subsystem */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->insn_bits = dt282x_dio_insn_bits;
+ s->insn_config = dt282x_dio_insn_config;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ printk("\n");
+
+ return 0;
+}
+
+static void free_resources(struct comedi_device * dev)
+{
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->iobase)
+ release_region(dev->iobase, DT2821_SIZE);
+ if (dev->private) {
+ if (devpriv->dma[0].chan)
+ free_dma(devpriv->dma[0].chan);
+ if (devpriv->dma[1].chan)
+ free_dma(devpriv->dma[1].chan);
+ if (devpriv->dma[0].buf)
+ free_page((unsigned long)devpriv->dma[0].buf);
+ if (devpriv->dma[1].buf)
+ free_page((unsigned long)devpriv->dma[1].buf);
+ }
+}
+
+static int dt282x_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: dt282x: remove\n", dev->minor);
+
+ free_resources(dev);
+
+ return 0;
+}
+
+static int dt282x_grab_dma(struct comedi_device * dev, int dma1, int dma2)
+{
+ int ret;
+
+ devpriv->usedma = 0;
+
+ if (!dma1 && !dma2) {
+ printk(" (no dma)");
+ return 0;
+ }
+
+ if (dma1 == dma2 || dma1 < 5 || dma2 < 5 || dma1 > 7 || dma2 > 7)
+ return -EINVAL;
+
+ if (dma2 < dma1) {
+ int i;
+ i = dma1;
+ dma1 = dma2;
+ dma2 = i;
+ }
+
+ ret = request_dma(dma1, "dt282x A");
+ if (ret)
+ return -EBUSY;
+ devpriv->dma[0].chan = dma1;
+
+ ret = request_dma(dma2, "dt282x B");
+ if (ret)
+ return -EBUSY;
+ devpriv->dma[1].chan = dma2;
+
+ devpriv->dma_maxsize = PAGE_SIZE;
+ devpriv->dma[0].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ devpriv->dma[1].buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ if (!devpriv->dma[0].buf || !devpriv->dma[1].buf) {
+ printk(" can't get DMA memory");
+ return -ENOMEM;
+ }
+
+ printk(" (dma=%d,%d)", dma1, dma2);
+
+ devpriv->usedma = 1;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c
new file mode 100644
index 00000000000..d9467984706
--- /dev/null
+++ b/drivers/staging/comedi/drivers/dt3000.c
@@ -0,0 +1,983 @@
+/*
+ comedi/drivers/dt3000.c
+ Data Translation DT3000 series driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: dt3000
+Description: Data Translation DT3000 series
+Author: ds
+Devices: [Data Translation] DT3001 (dt3000), DT3001-PGL, DT3002, DT3003,
+ DT3003-PGL, DT3004, DT3005, DT3004-200
+Updated: Mon, 14 Apr 2008 15:41:24 +0100
+Status: works
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+There is code to support AI commands, but it may not work.
+
+AO commands are not supported.
+*/
+
+/*
+ The DT3000 series is Data Translation's attempt to make a PCI
+ data acquisition board. The design of this series is very nice,
+ since each board has an on-board DSP (Texas Instruments TMS320C52).
+ However, a few details are a little annoying. The boards lack
+ bus-mastering DMA, which eliminates them from serious work.
+ They also are not capable of autocalibration, which is a common
+ feature in modern hardware. The default firmware is pretty bad,
+ making it nearly impossible to write an RT compatible driver.
+ It would make an interesting project to write a decent firmware
+ for these boards.
+
+ Data Translation originally wanted an NDA for the documentation
+ for the 3k series. However, if you ask nicely, they might send
+ you the docs without one, also.
+*/
+
+#define DEBUG 1
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+
+#define PCI_VENDOR_ID_DT 0x1116
+
+static const struct comedi_lrange range_dt3000_ai = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1.25, 1.25)
+ }
+};
+static const struct comedi_lrange range_dt3000_ai_pgl = { 4, {
+ RANGE(-10, 10),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.02, 0.02)
+ }
+};
+
+struct dt3k_boardtype {
+
+ const char *name;
+ unsigned int device_id;
+ int adchan;
+ int adbits;
+ int ai_speed;
+ const struct comedi_lrange *adrange;
+ int dachan;
+ int dabits;
+};
+
+
+static const struct dt3k_boardtype dt3k_boardtypes[] = {
+ {name:"dt3001",
+ device_id:0x22,
+ adchan: 16,
+ adbits: 12,
+ adrange: &range_dt3000_ai,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3001-pgl",
+ device_id:0x27,
+ adchan: 16,
+ adbits: 12,
+ adrange: &range_dt3000_ai_pgl,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3002",
+ device_id:0x23,
+ adchan: 32,
+ adbits: 12,
+ adrange: &range_dt3000_ai,
+ ai_speed:3000,
+ dachan: 0,
+ dabits: 0,
+ },
+ {name:"dt3003",
+ device_id:0x24,
+ adchan: 64,
+ adbits: 12,
+ adrange: &range_dt3000_ai,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3003-pgl",
+ device_id:0x28,
+ adchan: 64,
+ adbits: 12,
+ adrange: &range_dt3000_ai_pgl,
+ ai_speed:3000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3004",
+ device_id:0x25,
+ adchan: 16,
+ adbits: 16,
+ adrange: &range_dt3000_ai,
+ ai_speed:10000,
+ dachan: 2,
+ dabits: 12,
+ },
+ {name:"dt3005", /* a.k.a. 3004-200 */
+ device_id:0x26,
+ adchan: 16,
+ adbits: 16,
+ adrange: &range_dt3000_ai,
+ ai_speed:5000,
+ dachan: 2,
+ dabits: 12,
+ },
+};
+
+#define n_dt3k_boards sizeof(dt3k_boardtypes)/sizeof(struct dt3k_boardtype)
+#define this_board ((const struct dt3k_boardtype *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(dt3k_pci_table) = {
+ {PCI_VENDOR_ID_DT, 0x0022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0027, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0023, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0024, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0025, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_DT, 0x0026, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, dt3k_pci_table);
+
+#define DT3000_SIZE (4*0x1000)
+
+/* dual-ported RAM location definitions */
+
+#define DPR_DAC_buffer (4*0x000)
+#define DPR_ADC_buffer (4*0x800)
+#define DPR_Command (4*0xfd3)
+#define DPR_SubSys (4*0xfd3)
+#define DPR_Encode (4*0xfd4)
+#define DPR_Params(a) (4*(0xfd5+(a)))
+#define DPR_Tick_Reg_Lo (4*0xff5)
+#define DPR_Tick_Reg_Hi (4*0xff6)
+#define DPR_DA_Buf_Front (4*0xff7)
+#define DPR_DA_Buf_Rear (4*0xff8)
+#define DPR_AD_Buf_Front (4*0xff9)
+#define DPR_AD_Buf_Rear (4*0xffa)
+#define DPR_Int_Mask (4*0xffb)
+#define DPR_Intr_Flag (4*0xffc)
+#define DPR_Response_Mbx (4*0xffe)
+#define DPR_Command_Mbx (4*0xfff)
+
+#define AI_FIFO_DEPTH 2003
+#define AO_FIFO_DEPTH 2048
+
+/* command list */
+
+#define CMD_GETBRDINFO 0
+#define CMD_CONFIG 1
+#define CMD_GETCONFIG 2
+#define CMD_START 3
+#define CMD_STOP 4
+#define CMD_READSINGLE 5
+#define CMD_WRITESINGLE 6
+#define CMD_CALCCLOCK 7
+#define CMD_READEVENTS 8
+#define CMD_WRITECTCTRL 16
+#define CMD_READCTCTRL 17
+#define CMD_WRITECT 18
+#define CMD_READCT 19
+#define CMD_WRITEDATA 32
+#define CMD_READDATA 33
+#define CMD_WRITEIO 34
+#define CMD_READIO 35
+#define CMD_WRITECODE 36
+#define CMD_READCODE 37
+#define CMD_EXECUTE 38
+#define CMD_HALT 48
+
+#define SUBS_AI 0
+#define SUBS_AO 1
+#define SUBS_DIN 2
+#define SUBS_DOUT 3
+#define SUBS_MEM 4
+#define SUBS_CT 5
+
+/* interrupt flags */
+#define DT3000_CMDONE 0x80
+#define DT3000_CTDONE 0x40
+#define DT3000_DAHWERR 0x20
+#define DT3000_DASWERR 0x10
+#define DT3000_DAEMPTY 0x08
+#define DT3000_ADHWERR 0x04
+#define DT3000_ADSWERR 0x02
+#define DT3000_ADFULL 0x01
+
+#define DT3000_COMPLETION_MASK 0xff00
+#define DT3000_COMMAND_MASK 0x00ff
+#define DT3000_NOTPROCESSED 0x0000
+#define DT3000_NOERROR 0x5500
+#define DT3000_ERROR 0xaa00
+#define DT3000_NOTSUPPORTED 0xff00
+
+#define DT3000_EXTERNAL_CLOCK 1
+#define DT3000_RISING_EDGE 2
+
+#define TMODE_MASK 0x1c
+
+#define DT3000_AD_TRIG_INTERNAL (0<<2)
+#define DT3000_AD_TRIG_EXTERNAL (1<<2)
+#define DT3000_AD_RETRIG_INTERNAL (2<<2)
+#define DT3000_AD_RETRIG_EXTERNAL (3<<2)
+#define DT3000_AD_EXTRETRIG (4<<2)
+
+#define DT3000_CHANNEL_MODE_SE 0
+#define DT3000_CHANNEL_MODE_DI 1
+
+struct dt3k_private {
+
+ struct pci_dev *pci_dev;
+ resource_size_t phys_addr;
+ void *io_addr;
+ unsigned int lock;
+ unsigned int ao_readback[2];
+ unsigned int ai_front;
+ unsigned int ai_rear;
+};
+
+#define devpriv ((struct dt3k_private *)dev->private)
+
+static int dt3000_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dt3000_detach(struct comedi_device * dev);
+static struct comedi_driver driver_dt3000 = {
+ driver_name:"dt3000",
+ module:THIS_MODULE,
+ attach:dt3000_attach,
+ detach:dt3000_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_dt3000, dt3k_pci_table);
+
+static void dt3k_ai_empty_fifo(struct comedi_device * dev, struct comedi_subdevice * s);
+static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *arg,
+ unsigned int round_mode);
+static int dt3k_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+#ifdef DEBUG
+static void debug_intr_flags(unsigned int flags);
+#endif
+
+#define TIMEOUT 100
+
+static int dt3k_send_cmd(struct comedi_device * dev, unsigned int cmd)
+{
+ int i;
+ unsigned int status = 0;
+
+ writew(cmd, devpriv->io_addr + DPR_Command_Mbx);
+
+ for (i = 0; i < TIMEOUT; i++) {
+ status = readw(devpriv->io_addr + DPR_Command_Mbx);
+ if ((status & DT3000_COMPLETION_MASK) != DT3000_NOTPROCESSED)
+ break;
+ comedi_udelay(1);
+ }
+ if ((status & DT3000_COMPLETION_MASK) == DT3000_NOERROR) {
+ return 0;
+ }
+
+ printk("dt3k_send_cmd() timeout/error status=0x%04x\n", status);
+
+ return -ETIME;
+}
+
+static unsigned int dt3k_readsingle(struct comedi_device * dev, unsigned int subsys,
+ unsigned int chan, unsigned int gain)
+{
+ writew(subsys, devpriv->io_addr + DPR_SubSys);
+
+ writew(chan, devpriv->io_addr + DPR_Params(0));
+ writew(gain, devpriv->io_addr + DPR_Params(1));
+
+ dt3k_send_cmd(dev, CMD_READSINGLE);
+
+ return readw(devpriv->io_addr + DPR_Params(2));
+}
+
+static void dt3k_writesingle(struct comedi_device * dev, unsigned int subsys,
+ unsigned int chan, unsigned int data)
+{
+ writew(subsys, devpriv->io_addr + DPR_SubSys);
+
+ writew(chan, devpriv->io_addr + DPR_Params(0));
+ writew(0, devpriv->io_addr + DPR_Params(1));
+ writew(data, devpriv->io_addr + DPR_Params(2));
+
+ dt3k_send_cmd(dev, CMD_WRITESINGLE);
+}
+
+static int debug_n_ints = 0;
+
+// FIXME! Assumes shared interrupt is for this card.
+// What's this debug_n_ints stuff? Obviously needs some work...
+static irqreturn_t dt3k_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ unsigned int status;
+
+ if (!dev->attached) {
+ return IRQ_NONE;
+ }
+
+ s = dev->subdevices + 0;
+ status = readw(devpriv->io_addr + DPR_Intr_Flag);
+#ifdef DEBUG
+ debug_intr_flags(status);
+#endif
+
+ if (status & DT3000_ADFULL) {
+ dt3k_ai_empty_fifo(dev, s);
+ s->async->events |= COMEDI_CB_BLOCK;
+ }
+
+ if (status & (DT3000_ADSWERR | DT3000_ADHWERR)) {
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ }
+
+ debug_n_ints++;
+ if (debug_n_ints >= 10) {
+ dt3k_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+#ifdef DEBUG
+static char *intr_flags[] = {
+ "AdFull", "AdSwError", "AdHwError", "DaEmpty",
+ "DaSwError", "DaHwError", "CtDone", "CmDone",
+};
+static void debug_intr_flags(unsigned int flags)
+{
+ int i;
+ printk("dt3k: intr_flags:");
+ for (i = 0; i < 8; i++) {
+ if (flags & (1 << i)) {
+ printk(" %s", intr_flags[i]);
+ }
+ }
+ printk("\n");
+}
+#endif
+
+static void dt3k_ai_empty_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int front;
+ int rear;
+ int count;
+ int i;
+ short data;
+
+ front = readw(devpriv->io_addr + DPR_AD_Buf_Front);
+ count = front - devpriv->ai_front;
+ if (count < 0)
+ count += AI_FIFO_DEPTH;
+
+ printk("reading %d samples\n", count);
+
+ rear = devpriv->ai_rear;
+
+ for (i = 0; i < count; i++) {
+ data = readw(devpriv->io_addr + DPR_ADC_buffer + rear);
+ comedi_buf_put(s->async, data);
+ rear++;
+ if (rear >= AI_FIFO_DEPTH)
+ rear = 0;
+ }
+
+ devpriv->ai_rear = rear;
+ writew(rear, devpriv->io_addr + DPR_AD_Buf_Rear);
+}
+
+static int dt3k_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < this_board->ai_speed) {
+ cmd->scan_begin_arg = this_board->ai_speed;
+ err++;
+ }
+ if (cmd->scan_begin_arg > 100 * 16 * 65535) {
+ cmd->scan_begin_arg = 100 * 16 * 65535;
+ err++;
+ }
+ } else {
+ /* not supported */
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_speed) {
+ cmd->convert_arg = this_board->ai_speed;
+ err++;
+ }
+ if (cmd->convert_arg > 50 * 16 * 65535) {
+ cmd->convert_arg = 50 * 16 * 65535;
+ err++;
+ }
+ } else {
+ /* not supported */
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ } else {
+ /* not supported */
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ dt3k_ns_to_timer(50, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ } else {
+ /* not supported */
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int dt3k_ns_to_timer(unsigned int timer_base, unsigned int *nanosec,
+ unsigned int round_mode)
+{
+ int divider, base, prescale;
+
+ /* This function needs improvment */
+ /* Don't know if divider==0 works. */
+
+ for (prescale = 0; prescale < 16; prescale++) {
+ base = timer_base * (prescale + 1);
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec) / base;
+ break;
+ }
+ if (divider < 65536) {
+ *nanosec = divider * base;
+ return (prescale << 16) | (divider);
+ }
+ }
+
+ prescale = 15;
+ base = timer_base * (1 << prescale);
+ divider = 65535;
+ *nanosec = divider * base;
+ return (prescale << 16) | (divider);
+}
+
+static int dt3k_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int i;
+ unsigned int chan, range, aref;
+ unsigned int divider;
+ unsigned int tscandiv;
+ int ret;
+ unsigned int mode;
+
+ printk("dt3k_ai_cmd:\n");
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ chan = CR_CHAN(cmd->chanlist[i]);
+ range = CR_RANGE(cmd->chanlist[i]);
+
+ writew((range << 6) | chan,
+ devpriv->io_addr + DPR_ADC_buffer + i);
+ }
+ aref = CR_AREF(cmd->chanlist[0]);
+
+ writew(cmd->scan_end_arg, devpriv->io_addr + DPR_Params(0));
+ printk("param[0]=0x%04x\n", cmd->scan_end_arg);
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ divider = dt3k_ns_to_timer(50, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ writew((divider >> 16), devpriv->io_addr + DPR_Params(1));
+ printk("param[1]=0x%04x\n", divider >> 16);
+ writew((divider & 0xffff), devpriv->io_addr + DPR_Params(2));
+ printk("param[2]=0x%04x\n", divider & 0xffff);
+ } else {
+ /* not supported */
+ }
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tscandiv = dt3k_ns_to_timer(100, &cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ writew((tscandiv >> 16), devpriv->io_addr + DPR_Params(3));
+ printk("param[3]=0x%04x\n", tscandiv >> 16);
+ writew((tscandiv & 0xffff), devpriv->io_addr + DPR_Params(4));
+ printk("param[4]=0x%04x\n", tscandiv & 0xffff);
+ } else {
+ /* not supported */
+ }
+
+ mode = DT3000_AD_RETRIG_INTERNAL | 0 | 0;
+ writew(mode, devpriv->io_addr + DPR_Params(5));
+ printk("param[5]=0x%04x\n", mode);
+ writew(aref == AREF_DIFF, devpriv->io_addr + DPR_Params(6));
+ printk("param[6]=0x%04x\n", aref == AREF_DIFF);
+
+ writew(AI_FIFO_DEPTH / 2, devpriv->io_addr + DPR_Params(7));
+ printk("param[7]=0x%04x\n", AI_FIFO_DEPTH / 2);
+
+ writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ ret = dt3k_send_cmd(dev, CMD_CONFIG);
+
+ writew(DT3000_ADFULL | DT3000_ADSWERR | DT3000_ADHWERR,
+ devpriv->io_addr + DPR_Int_Mask);
+
+ debug_n_ints = 0;
+
+ writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ ret = dt3k_send_cmd(dev, CMD_START);
+
+ return 0;
+}
+
+static int dt3k_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int ret;
+
+ writew(SUBS_AI, devpriv->io_addr + DPR_SubSys);
+ ret = dt3k_send_cmd(dev, CMD_STOP);
+
+ writew(0, devpriv->io_addr + DPR_Int_Mask);
+
+ return 0;
+}
+
+static int dt3k_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ unsigned int chan, gain, aref;
+
+ chan = CR_CHAN(insn->chanspec);
+ gain = CR_RANGE(insn->chanspec);
+ /* XXX docs don't explain how to select aref */
+ aref = CR_AREF(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = dt3k_readsingle(dev, SUBS_AI, chan, gain);
+ }
+
+ return i;
+}
+
+static int dt3k_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ unsigned int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (i = 0; i < insn->n; i++) {
+ dt3k_writesingle(dev, SUBS_AO, chan, data[i]);
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int dt3k_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ unsigned int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static void dt3k_dio_config(struct comedi_device * dev, int bits)
+{
+ /* XXX */
+ writew(SUBS_DOUT, devpriv->io_addr + DPR_SubSys);
+
+ writew(bits, devpriv->io_addr + DPR_Params(0));
+#if 0
+ /* don't know */
+ writew(0, devpriv->io_addr + DPR_Params(1));
+ writew(0, devpriv->io_addr + DPR_Params(2));
+#endif
+
+ dt3k_send_cmd(dev, CMD_CONFIG);
+}
+
+static int dt3k_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask;
+
+ mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ mask = (s->io_bits & 0x01) | ((s->io_bits & 0x10) >> 3);
+ dt3k_dio_config(dev, mask);
+
+ return insn->n;
+}
+
+static int dt3k_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[1] & data[0];
+ dt3k_writesingle(dev, SUBS_DOUT, 0, s->state);
+ }
+ data[1] = dt3k_readsingle(dev, SUBS_DIN, 0, 0);
+
+ return 2;
+}
+
+static int dt3k_mem_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int addr = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ writew(SUBS_MEM, devpriv->io_addr + DPR_SubSys);
+ writew(addr, devpriv->io_addr + DPR_Params(0));
+ writew(1, devpriv->io_addr + DPR_Params(1));
+
+ dt3k_send_cmd(dev, CMD_READCODE);
+
+ data[i] = readw(devpriv->io_addr + DPR_Params(2));
+ }
+
+ return i;
+}
+
+static int dt_pci_probe(struct comedi_device * dev, int bus, int slot);
+
+static int dt3000_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int bus, slot;
+ int ret = 0;
+
+ printk("dt3000:");
+ bus = it->options[0];
+ slot = it->options[1];
+
+ if ((ret = alloc_private(dev, sizeof(struct dt3k_private))) < 0)
+ return ret;
+
+ ret = dt_pci_probe(dev, bus, slot);
+ if (ret < 0)
+ return ret;
+ if (ret == 0) {
+ printk(" no DT board found\n");
+ return -ENODEV;
+ }
+
+ dev->board_name = this_board->name;
+
+ if (comedi_request_irq(devpriv->pci_dev->irq, dt3k_interrupt,
+ IRQF_SHARED, "dt3000", dev)) {
+ printk(" unable to allocate IRQ %u\n", devpriv->pci_dev->irq);
+ return -EINVAL;
+ }
+ dev->irq = devpriv->pci_dev->irq;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices;
+ dev->read_subdev = s;
+
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = this_board->adchan;
+ s->insn_read = dt3k_ai_insn;
+ s->maxdata = (1 << this_board->adbits) - 1;
+ s->len_chanlist = 512;
+ s->range_table = &range_dt3000_ai; /* XXX */
+ s->do_cmd = dt3k_ai_cmd;
+ s->do_cmdtest = dt3k_ai_cmdtest;
+ s->cancel = dt3k_ai_cancel;
+
+ s++;
+ /* ao subsystem */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = dt3k_ao_insn_read;
+ s->insn_write = dt3k_ao_insn;
+ s->maxdata = (1 << this_board->dabits) - 1;
+ s->len_chanlist = 1;
+ s->range_table = &range_bipolar10;
+
+ s++;
+ /* dio subsystem */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_config = dt3k_dio_insn_config;
+ s->insn_bits = dt3k_dio_insn_bits;
+ s->maxdata = 1;
+ s->len_chanlist = 8;
+ s->range_table = &range_digital;
+
+ s++;
+ /* mem subsystem */
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 0x1000;
+ s->insn_read = dt3k_mem_insn_read;
+ s->maxdata = 0xff;
+ s->len_chanlist = 1;
+ s->range_table = &range_unknown;
+
+#if 0
+ s++;
+ /* proc subsystem */
+ s->type = COMEDI_SUBD_PROC;
+#endif
+
+ return 0;
+}
+
+static int dt3000_detach(struct comedi_device * dev)
+{
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (devpriv) {
+ if (devpriv->pci_dev) {
+ if (devpriv->phys_addr) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+ pci_dev_put(devpriv->pci_dev);
+ }
+ if (devpriv->io_addr)
+ iounmap(devpriv->io_addr);
+ }
+ /* XXX */
+
+ return 0;
+}
+
+static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board);
+static int setup_pci(struct comedi_device * dev);
+
+static int dt_pci_probe(struct comedi_device * dev, int bus, int slot)
+{
+ int board;
+ int ret;
+ struct pci_dev *pcidev;
+
+ pcidev = NULL;
+ while ((pcidev = dt_pci_find_device(pcidev, &board)) != NULL) {
+ if ((bus == 0 && slot == 0) ||
+ (pcidev->bus->number == bus &&
+ PCI_SLOT(pcidev->devfn) == slot)) {
+ break;
+ }
+ }
+ devpriv->pci_dev = pcidev;
+
+ if (board >= 0)
+ dev->board_ptr = dt3k_boardtypes + board;
+
+ if (!devpriv->pci_dev)
+ return 0;
+
+ if ((ret = setup_pci(dev)) < 0)
+ return ret;
+
+ return 1;
+}
+
+static int setup_pci(struct comedi_device * dev)
+{
+ resource_size_t addr;
+ int ret;
+
+ ret = comedi_pci_enable(devpriv->pci_dev, "dt3000");
+ if (ret < 0)
+ return ret;
+
+ addr = pci_resource_start(devpriv->pci_dev, 0);
+ devpriv->phys_addr = addr;
+ devpriv->io_addr = ioremap(devpriv->phys_addr, DT3000_SIZE);
+ if (!devpriv->io_addr)
+ return -ENOMEM;
+#if DEBUG
+ printk("0x%08llx mapped to %p, ",
+ (unsigned long long)devpriv->phys_addr, devpriv->io_addr);
+#endif
+
+ return 0;
+}
+
+static struct pci_dev *dt_pci_find_device(struct pci_dev *from, int *board)
+{
+ int i;
+
+ for (from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from);
+ from != NULL;
+ from = pci_get_device(PCI_VENDOR_ID_DT, PCI_ANY_ID, from)) {
+ for (i = 0; i < n_dt3k_boards; i++) {
+ if (from->device == dt3k_boardtypes[i].device_id) {
+ *board = i;
+ return from;
+ }
+ }
+ printk("unknown Data Translation PCI device found with device_id=0x%04x\n", from->device);
+ }
+ *board = -1;
+ return from;
+}
diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c
index f2d2173d721..cc4c0463008 100644
--- a/drivers/staging/comedi/drivers/dt9812.c
+++ b/drivers/staging/comedi/drivers/dt9812.c
@@ -300,22 +300,22 @@ struct slot_dt9812 {
struct comedi_dt9812 *comedi;
};
-static const comedi_lrange dt9812_10_ain_range = { 1, {
+static const struct comedi_lrange dt9812_10_ain_range = { 1, {
BIP_RANGE(10),
}
};
-static const comedi_lrange dt9812_2pt5_ain_range = { 1, {
+static const struct comedi_lrange dt9812_2pt5_ain_range = { 1, {
UNI_RANGE(2.5),
}
};
-static const comedi_lrange dt9812_10_aout_range = { 1, {
+static const struct comedi_lrange dt9812_10_aout_range = { 1, {
BIP_RANGE(10),
}
};
-static const comedi_lrange dt9812_2pt5_aout_range = { 1, {
+static const struct comedi_lrange dt9812_2pt5_aout_range = { 1, {
UNI_RANGE(2.5),
}
};
@@ -892,12 +892,12 @@ static struct usb_driver dt9812_usb_driver = {
* Comedi functions
*/
-static void dt9812_comedi_open(comedi_device *dev)
+static void dt9812_comedi_open(struct comedi_device *dev)
{
down(&devpriv->slot->mutex);
if (devpriv->slot->usb) {
/* We have an attached device, fill in current range info */
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
s = &dev->subdevices[0];
s->n_chan = 8;
@@ -940,8 +940,8 @@ static void dt9812_comedi_open(comedi_device *dev)
up(&devpriv->slot->mutex);
}
-static int dt9812_di_rinsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_di_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
u8 bits = 0;
@@ -952,8 +952,8 @@ static int dt9812_di_rinsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_do_winsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_do_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
u8 bits = 0;
@@ -970,8 +970,8 @@ static int dt9812_do_winsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_ai_rinsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
@@ -985,8 +985,8 @@ static int dt9812_ai_rinsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_ao_rinsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
u16 value;
@@ -999,8 +999,8 @@ static int dt9812_ao_rinsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_ao_winsn(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int dt9812_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
@@ -1009,10 +1009,10 @@ static int dt9812_ao_winsn(comedi_device *dev, comedi_subdevice *s,
return n;
}
-static int dt9812_attach(comedi_device *dev, comedi_devconfig *it)
+static int dt9812_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int i;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
dev->board_name = "dt9812";
@@ -1103,12 +1103,12 @@ static int dt9812_attach(comedi_device *dev, comedi_devconfig *it)
return 0;
}
-static int dt9812_detach(comedi_device *dev)
+static int dt9812_detach(struct comedi_device *dev)
{
return 0;
}
-static comedi_driver dt9812_comedi_driver = {
+static struct comedi_driver dt9812_comedi_driver = {
.module = THIS_MODULE,
.driver_name = "dt9812",
.attach = dt9812_attach,
diff --git a/drivers/staging/comedi/drivers/fl512.c b/drivers/staging/comedi/drivers/fl512.c
new file mode 100644
index 00000000000..6d7bb37d2b1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/fl512.c
@@ -0,0 +1,186 @@
+/*
+ comedi/drivers/fl512.c
+ Anders Gnistrup <ex18@kalman.iau.dtu.dk>
+*/
+
+/*
+Driver: fl512
+Description: unknown
+Author: Anders Gnistrup <ex18@kalman.iau.dtu.dk>
+Devices: [unknown] FL512 (fl512)
+Status: unknown
+
+Digital I/O is not supported.
+
+Configuration options:
+ [0] - I/O port base address
+*/
+
+#define DEBUG 0
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#define FL512_SIZE 16 /* the size of the used memory */
+struct fl512_private {
+
+ short ao_readback[2];
+};
+
+#define devpriv ((struct fl512_private *) dev->private)
+
+static const struct comedi_lrange range_fl512 = { 4, {
+ BIP_RANGE(0.5),
+ BIP_RANGE(1),
+ BIP_RANGE(5),
+ BIP_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+static int fl512_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int fl512_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_fl512 = {
+ driver_name:"fl512",
+ module:THIS_MODULE,
+ attach:fl512_attach,
+ detach:fl512_detach,
+};
+
+COMEDI_INITCLEANUP(driver_fl512);
+
+static int fl512_ai_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int fl512_ao_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int fl512_ao_insn_readback(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * fl512_ai_insn : this is the analog input function
+ */
+static int fl512_ai_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned int lo_byte, hi_byte;
+ char chan = CR_CHAN(insn->chanspec);
+ unsigned long iobase = dev->iobase;
+
+ for (n = 0; n < insn->n; n++) { /* sample n times on selected channel */
+ /* XXX probably can move next step out of for() loop -- will make
+ * AI a little bit faster. */
+ outb(chan, iobase + 2); /* select chan */
+ outb(0, iobase + 3); /* start conversion */
+ /* XXX should test "done" flag instead of delay */
+ comedi_udelay(30); /* sleep 30 usec */
+ lo_byte = inb(iobase + 2); /* low 8 byte */
+ hi_byte = inb(iobase + 3) & 0xf; /* high 4 bit and mask */
+ data[n] = lo_byte + (hi_byte << 8);
+ }
+ return n;
+}
+
+/*
+ * fl512_ao_insn : used to write to a DA port n times
+ */
+static int fl512_ao_insn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec); /* get chan to write */
+ unsigned long iobase = dev->iobase; /* get base address */
+
+ for (n = 0; n < insn->n; n++) { /* write n data set */
+ outb(data[n] & 0x0ff, iobase + 4 + 2 * chan); /* write low byte */
+ outb((data[n] & 0xf00) >> 8, iobase + 4 + 2 * chan); /* write high byte */
+ inb(iobase + 4 + 2 * chan); /* trig */
+
+ devpriv->ao_readback[chan] = data[n];
+ }
+ return n;
+}
+
+/*
+ * fl512_ao_insn_readback : used to read previous values written to
+ * DA port
+ */
+static int fl512_ao_insn_readback(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+}
+
+/*
+ * start attach
+ */
+static int fl512_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase;
+ struct comedi_subdevice *s; /* pointer to the subdevice:
+ Analog in, Analog out, ( not made ->and Digital IO) */
+
+ iobase = it->options[0];
+ printk("comedi:%d fl512: 0x%04lx", dev->minor, iobase);
+ if (!request_region(iobase, FL512_SIZE, "fl512")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "fl512";
+ if (alloc_private(dev, sizeof(struct fl512_private)) < 0)
+ return -ENOMEM;
+
+#if DEBUG
+ printk("malloc ok\n");
+#endif
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ /*
+ * this if the definitions of the supdevices, 2 have been defined
+ */
+ /* Analog indput */
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI; /* define subdevice as Analog In */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND; /* you can read it from userspace */
+ s->n_chan = 16; /* Number of Analog input channels */
+ s->maxdata = 0x0fff; /* accept only 12 bits of data */
+ s->range_table = &range_fl512; /* device use one of the ranges */
+ s->insn_read = fl512_ai_insn; /* function to call when read AD */
+ printk("comedi: fl512: subdevice 0 initialized\n");
+
+ /* Analog output */
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_AO; /* define subdevice as Analog OUT */
+ s->subdev_flags = SDF_WRITABLE; /* you can write it from userspace */
+ s->n_chan = 2; /* Number of Analog output channels */
+ s->maxdata = 0x0fff; /* accept only 12 bits of data */
+ s->range_table = &range_fl512; /* device use one of the ranges */
+ s->insn_write = fl512_ao_insn; /* function to call when write DA */
+ s->insn_read = fl512_ao_insn_readback; /* function to call when reading DA */
+ printk("comedi: fl512: subdevice 1 initialized\n");
+
+ return 1;
+}
+
+static int fl512_detach(struct comedi_device * dev)
+{
+ if (dev->iobase)
+ release_region(dev->iobase, FL512_SIZE);
+ printk("comedi%d: fl512: dummy i detach\n", dev->minor);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/gsc_hpdi.c b/drivers/staging/comedi/drivers/gsc_hpdi.c
new file mode 100644
index 00000000000..49e5c86c2dd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/gsc_hpdi.c
@@ -0,0 +1,1060 @@
+/*
+ comedi/drivers/gsc_hpdi.c
+ This is a driver for the General Standards Corporation High
+ Speed Parallel Digital Interface rs485 boards.
+
+ Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2003 Coherent Imaging Systems
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************/
+
+/*
+
+Driver: gsc_hpdi
+Description: General Standards Corporation High
+ Speed Parallel Digital Interface rs485 boards
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: only receive mode works, transmit not supported
+Updated: 2003-02-20
+Devices: [General Standards Corporation] PCI-HPDI32 (gsc_hpdi),
+ PMC-HPDI32
+
+Configuration options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+
+There are some additional hpdi models available from GSC for which
+support could be added to this driver.
+
+*/
+
+#include "../comedidev.h"
+#include <linux/delay.h>
+
+#include "comedi_pci.h"
+#include "plx9080.h"
+#include "comedi_fc.h"
+
+static int hpdi_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int hpdi_detach(struct comedi_device * dev);
+void abort_dma(struct comedi_device * dev, unsigned int channel);
+static int hpdi_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int hpdi_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int hpdi_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG);
+static int dio_config_block_size(struct comedi_device * dev, unsigned int * data);
+
+#undef HPDI_DEBUG // disable debugging messages
+//#define HPDI_DEBUG // enable debugging code
+
+#ifdef HPDI_DEBUG
+#define DEBUG_PRINT(format, args...) rt_printk(format , ## args )
+#else
+#define DEBUG_PRINT(format, args...)
+#endif
+
+#define TIMER_BASE 50 // 20MHz master clock
+#define DMA_BUFFER_SIZE 0x10000
+#define NUM_DMA_BUFFERS 4
+#define NUM_DMA_DESCRIPTORS 256
+
+// indices of base address regions
+enum base_address_regions {
+ PLX9080_BADDRINDEX = 0,
+ HPDI_BADDRINDEX = 2,
+};
+
+enum hpdi_registers {
+ FIRMWARE_REV_REG = 0x0,
+ BOARD_CONTROL_REG = 0x4,
+ BOARD_STATUS_REG = 0x8,
+ TX_PROG_ALMOST_REG = 0xc,
+ RX_PROG_ALMOST_REG = 0x10,
+ FEATURES_REG = 0x14,
+ FIFO_REG = 0x18,
+ TX_STATUS_COUNT_REG = 0x1c,
+ TX_LINE_VALID_COUNT_REG = 0x20,
+ TX_LINE_INVALID_COUNT_REG = 0x24,
+ RX_STATUS_COUNT_REG = 0x28,
+ RX_LINE_COUNT_REG = 0x2c,
+ INTERRUPT_CONTROL_REG = 0x30,
+ INTERRUPT_STATUS_REG = 0x34,
+ TX_CLOCK_DIVIDER_REG = 0x38,
+ TX_FIFO_SIZE_REG = 0x40,
+ RX_FIFO_SIZE_REG = 0x44,
+ TX_FIFO_WORDS_REG = 0x48,
+ RX_FIFO_WORDS_REG = 0x4c,
+ INTERRUPT_EDGE_LEVEL_REG = 0x50,
+ INTERRUPT_POLARITY_REG = 0x54,
+};
+
+int command_channel_valid(unsigned int channel)
+{
+ if (channel == 0 || channel > 6) {
+ rt_printk("gsc_hpdi: bug! invalid cable command channel\n");
+ return 0;
+ }
+ return 1;
+}
+
+// bit definitions
+
+enum firmware_revision_bits {
+ FEATURES_REG_PRESENT_BIT = 0x8000,
+};
+int firmware_revision(uint32_t fwr_bits)
+{
+ return fwr_bits & 0xff;
+}
+
+int pcb_revision(uint32_t fwr_bits)
+{
+ return (fwr_bits >> 8) & 0xff;
+}
+
+int hpdi_subid(uint32_t fwr_bits)
+{
+ return (fwr_bits >> 16) & 0xff;
+}
+
+enum board_control_bits {
+ BOARD_RESET_BIT = 0x1, /* wait 10usec before accessing fifos */
+ TX_FIFO_RESET_BIT = 0x2,
+ RX_FIFO_RESET_BIT = 0x4,
+ TX_ENABLE_BIT = 0x10,
+ RX_ENABLE_BIT = 0x20,
+ DEMAND_DMA_DIRECTION_TX_BIT = 0x40, /* for channel 0, channel 1 can only transmit (when present) */
+ LINE_VALID_ON_STATUS_VALID_BIT = 0x80,
+ START_TX_BIT = 0x10,
+ CABLE_THROTTLE_ENABLE_BIT = 0x20,
+ TEST_MODE_ENABLE_BIT = 0x80000000,
+};
+uint32_t command_discrete_output_bits(unsigned int channel, int output,
+ int output_value)
+{
+ uint32_t bits = 0;
+
+ if (command_channel_valid(channel) == 0)
+ return 0;
+ if (output) {
+ bits |= 0x1 << (16 + channel);
+ if (output_value)
+ bits |= 0x1 << (24 + channel);
+ } else
+ bits |= 0x1 << (24 + channel);
+
+ return bits;
+}
+
+enum board_status_bits {
+ COMMAND_LINE_STATUS_MASK = 0x7f,
+ TX_IN_PROGRESS_BIT = 0x80,
+ TX_NOT_EMPTY_BIT = 0x100,
+ TX_NOT_ALMOST_EMPTY_BIT = 0x200,
+ TX_NOT_ALMOST_FULL_BIT = 0x400,
+ TX_NOT_FULL_BIT = 0x800,
+ RX_NOT_EMPTY_BIT = 0x1000,
+ RX_NOT_ALMOST_EMPTY_BIT = 0x2000,
+ RX_NOT_ALMOST_FULL_BIT = 0x4000,
+ RX_NOT_FULL_BIT = 0x8000,
+ BOARD_JUMPER0_INSTALLED_BIT = 0x10000,
+ BOARD_JUMPER1_INSTALLED_BIT = 0x20000,
+ TX_OVERRUN_BIT = 0x200000,
+ RX_UNDERRUN_BIT = 0x400000,
+ RX_OVERRUN_BIT = 0x800000,
+};
+
+uint32_t almost_full_bits(unsigned int num_words)
+{
+// XXX need to add or subtract one?
+ return (num_words << 16) & 0xff0000;
+}
+
+uint32_t almost_empty_bits(unsigned int num_words)
+{
+ return num_words & 0xffff;
+}
+unsigned int almost_full_num_words(uint32_t bits)
+{
+// XXX need to add or subtract one?
+ return (bits >> 16) & 0xffff;
+}
+unsigned int almost_empty_num_words(uint32_t bits)
+{
+ return bits & 0xffff;
+}
+
+enum features_bits {
+ FIFO_SIZE_PRESENT_BIT = 0x1,
+ FIFO_WORDS_PRESENT_BIT = 0x2,
+ LEVEL_EDGE_INTERRUPTS_PRESENT_BIT = 0x4,
+ GPIO_SUPPORTED_BIT = 0x8,
+ PLX_DMA_CH1_SUPPORTED_BIT = 0x10,
+ OVERRUN_UNDERRUN_SUPPORTED_BIT = 0x20,
+};
+
+enum interrupt_sources {
+ FRAME_VALID_START_INTR = 0,
+ FRAME_VALID_END_INTR = 1,
+ TX_FIFO_EMPTY_INTR = 8,
+ TX_FIFO_ALMOST_EMPTY_INTR = 9,
+ TX_FIFO_ALMOST_FULL_INTR = 10,
+ TX_FIFO_FULL_INTR = 11,
+ RX_EMPTY_INTR = 12,
+ RX_ALMOST_EMPTY_INTR = 13,
+ RX_ALMOST_FULL_INTR = 14,
+ RX_FULL_INTR = 15,
+};
+int command_intr_source(unsigned int channel)
+{
+ if (command_channel_valid(channel) == 0)
+ channel = 1;
+ return channel + 1;
+}
+
+uint32_t intr_bit(int interrupt_source)
+{
+ return 0x1 << interrupt_source;
+}
+
+uint32_t tx_clock_divisor_bits(unsigned int divisor)
+{
+ return divisor & 0xff;
+}
+
+unsigned int fifo_size(uint32_t fifo_size_bits)
+{
+ return fifo_size_bits & 0xfffff;
+}
+
+unsigned int fifo_words(uint32_t fifo_words_bits)
+{
+ return fifo_words_bits & 0xfffff;
+}
+
+uint32_t intr_edge_bit(int interrupt_source)
+{
+ return 0x1 << interrupt_source;
+}
+
+uint32_t intr_active_high_bit(int interrupt_source)
+{
+ return 0x1 << interrupt_source;
+}
+
+struct hpdi_board {
+
+ char *name;
+ int device_id; // pci device id
+ int subdevice_id; // pci subdevice id
+};
+
+
+static const struct hpdi_board hpdi_boards[] = {
+ {
+ name: "pci-hpdi32",
+ device_id:PCI_DEVICE_ID_PLX_9080,
+ subdevice_id:0x2400,
+ },
+#if 0
+ {
+ name: "pxi-hpdi32",
+ device_id:0x9656,
+ subdevice_id:0x2705,
+ },
+#endif
+};
+
+static inline unsigned int num_boards(void)
+{
+ return sizeof(hpdi_boards) / sizeof(struct hpdi_board);
+}
+
+static DEFINE_PCI_DEVICE_TABLE(hpdi_pci_table) = {
+ {PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9080, PCI_VENDOR_ID_PLX, 0x2400,
+ 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, hpdi_pci_table);
+
+static inline struct hpdi_board *board(const struct comedi_device * dev)
+{
+ return (struct hpdi_board *) dev->board_ptr;
+}
+
+struct hpdi_private {
+
+ struct pci_dev *hw_dev; // pointer to board's pci_dev struct
+ // base addresses (physical)
+ resource_size_t plx9080_phys_iobase;
+ resource_size_t hpdi_phys_iobase;
+ // base addresses (ioremapped)
+ void *plx9080_iobase;
+ void *hpdi_iobase;
+ uint32_t *dio_buffer[NUM_DMA_BUFFERS]; // dma buffers
+ dma_addr_t dio_buffer_phys_addr[NUM_DMA_BUFFERS]; // physical addresses of dma buffers
+ struct plx_dma_desc *dma_desc; // array of dma descriptors read by plx9080, allocated to get proper alignment
+ dma_addr_t dma_desc_phys_addr; // physical address of dma descriptor array
+ unsigned int num_dma_descriptors;
+ uint32_t *desc_dio_buffer[NUM_DMA_DESCRIPTORS]; // pointer to start of buffers indexed by descriptor
+ volatile unsigned int dma_desc_index; // index of the dma descriptor that is currently being used
+ unsigned int tx_fifo_size;
+ unsigned int rx_fifo_size;
+ volatile unsigned long dio_count;
+ volatile uint32_t bits[24]; // software copies of values written to hpdi registers
+ volatile unsigned int block_size; // number of bytes at which to generate COMEDI_CB_BLOCK events
+ unsigned dio_config_output:1;
+};
+
+
+static inline struct hpdi_private *priv(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+static struct comedi_driver driver_hpdi = {
+ driver_name:"gsc_hpdi",
+ module:THIS_MODULE,
+ attach:hpdi_attach,
+ detach:hpdi_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_hpdi, hpdi_pci_table);
+
+static int dio_config_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ priv(dev)->dio_config_output = 1;
+ return insn->n;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ priv(dev)->dio_config_output = 0;
+ return insn->n;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ priv(dev)->
+ dio_config_output ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ case INSN_CONFIG_BLOCK_SIZE:
+ return dio_config_block_size(dev, data);
+ break;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static void disable_plx_interrupts(struct comedi_device * dev)
+{
+ writel(0, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+}
+
+// initialize plx9080 chip
+static void init_plx9080(struct comedi_device * dev)
+{
+ uint32_t bits;
+ void *plx_iobase = priv(dev)->plx9080_iobase;
+
+ // plx9080 dump
+ DEBUG_PRINT(" plx interrupt status 0x%x\n",
+ readl(plx_iobase + PLX_INTRCS_REG));
+ DEBUG_PRINT(" plx id bits 0x%x\n", readl(plx_iobase + PLX_ID_REG));
+ DEBUG_PRINT(" plx control reg 0x%x\n",
+ readl(priv(dev)->plx9080_iobase + PLX_CONTROL_REG));
+
+ DEBUG_PRINT(" plx revision 0x%x\n",
+ readl(plx_iobase + PLX_REVISION_REG));
+ DEBUG_PRINT(" plx dma channel 0 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 1 mode 0x%x\n",
+ readl(plx_iobase + PLX_DMA1_MODE_REG));
+ DEBUG_PRINT(" plx dma channel 0 pci address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_PCI_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 local address 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_LOCAL_ADDRESS_REG));
+ DEBUG_PRINT(" plx dma channel 0 transfer size 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_TRANSFER_SIZE_REG));
+ DEBUG_PRINT(" plx dma channel 0 descriptor 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_DESCRIPTOR_REG));
+ DEBUG_PRINT(" plx dma channel 0 command status 0x%x\n",
+ readb(plx_iobase + PLX_DMA0_CS_REG));
+ DEBUG_PRINT(" plx dma channel 0 threshold 0x%x\n",
+ readl(plx_iobase + PLX_DMA0_THRESHOLD_REG));
+ DEBUG_PRINT(" plx bigend 0x%x\n", readl(plx_iobase + PLX_BIGEND_REG));
+#ifdef __BIG_ENDIAN
+ bits = BIGEND_DMA0 | BIGEND_DMA1;
+#else
+ bits = 0;
+#endif
+ writel(bits, priv(dev)->plx9080_iobase + PLX_BIGEND_REG);
+
+ disable_plx_interrupts(dev);
+
+ abort_dma(dev, 0);
+ abort_dma(dev, 1);
+
+ // configure dma0 mode
+ bits = 0;
+ // enable ready input
+ bits |= PLX_DMA_EN_READYIN_BIT;
+ // enable dma chaining
+ bits |= PLX_EN_CHAIN_BIT;
+ // enable interrupt on dma done (probably don't need this, since chain never finishes)
+ bits |= PLX_EN_DMA_DONE_INTR_BIT;
+ // don't increment local address during transfers (we are transferring from a fixed fifo register)
+ bits |= PLX_LOCAL_ADDR_CONST_BIT;
+ // route dma interrupt to pci bus
+ bits |= PLX_DMA_INTR_PCI_BIT;
+ // enable demand mode
+ bits |= PLX_DEMAND_MODE_BIT;
+ // enable local burst mode
+ bits |= PLX_DMA_LOCAL_BURST_EN_BIT;
+ bits |= PLX_LOCAL_BUS_32_WIDE_BITS;
+ writel(bits, plx_iobase + PLX_DMA0_MODE_REG);
+}
+
+/* Allocate and initialize the subdevice structures.
+ */
+static int setup_subdevices(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog input subdevice */
+ dev->read_subdev = s;
+/* dev->write_subdev = s; */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITEABLE | SDF_LSAMPL | SDF_CMD_READ;
+ s->n_chan = 32;
+ s->len_chanlist = 32;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = dio_config_insn;
+ s->do_cmd = hpdi_cmd;
+ s->do_cmdtest = hpdi_cmd_test;
+ s->cancel = hpdi_cancel;
+
+ return 0;
+}
+
+static int init_hpdi(struct comedi_device * dev)
+{
+ uint32_t plx_intcsr_bits;
+
+ writel(BOARD_RESET_BIT, priv(dev)->hpdi_iobase + BOARD_CONTROL_REG);
+ comedi_udelay(10);
+
+ writel(almost_empty_bits(32) | almost_full_bits(32),
+ priv(dev)->hpdi_iobase + RX_PROG_ALMOST_REG);
+ writel(almost_empty_bits(32) | almost_full_bits(32),
+ priv(dev)->hpdi_iobase + TX_PROG_ALMOST_REG);
+
+ priv(dev)->tx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+ TX_FIFO_SIZE_REG));
+ priv(dev)->rx_fifo_size = fifo_size(readl(priv(dev)->hpdi_iobase +
+ RX_FIFO_SIZE_REG));
+
+ writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+ // enable interrupts
+ plx_intcsr_bits =
+ ICS_AERR | ICS_PERR | ICS_PIE | ICS_PLIE | ICS_PAIE | ICS_LIE |
+ ICS_DMA0_E;
+ writel(plx_intcsr_bits, priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+
+ return 0;
+}
+
+// setup dma descriptors so a link completes every 'transfer_size' bytes
+static int setup_dma_descriptors(struct comedi_device * dev,
+ unsigned int transfer_size)
+{
+ unsigned int buffer_index, buffer_offset;
+ uint32_t next_bits = PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
+ PLX_XFER_LOCAL_TO_PCI;
+ unsigned int i;
+
+ if (transfer_size > DMA_BUFFER_SIZE)
+ transfer_size = DMA_BUFFER_SIZE;
+ transfer_size -= transfer_size % sizeof(uint32_t);
+ if (transfer_size == 0)
+ return -1;
+
+ DEBUG_PRINT(" transfer_size %i\n", transfer_size);
+ DEBUG_PRINT(" descriptors at 0x%lx\n",
+ (unsigned long)priv(dev)->dma_desc_phys_addr);
+
+ buffer_offset = 0;
+ buffer_index = 0;
+ for (i = 0; i < NUM_DMA_DESCRIPTORS &&
+ buffer_index < NUM_DMA_BUFFERS; i++) {
+ priv(dev)->dma_desc[i].pci_start_addr =
+ cpu_to_le32(priv(dev)->
+ dio_buffer_phys_addr[buffer_index] + buffer_offset);
+ priv(dev)->dma_desc[i].local_start_addr = cpu_to_le32(FIFO_REG);
+ priv(dev)->dma_desc[i].transfer_size =
+ cpu_to_le32(transfer_size);
+ priv(dev)->dma_desc[i].next =
+ cpu_to_le32((priv(dev)->dma_desc_phys_addr + (i +
+ 1) *
+ sizeof(priv(dev)->dma_desc[0])) | next_bits);
+
+ priv(dev)->desc_dio_buffer[i] =
+ priv(dev)->dio_buffer[buffer_index] +
+ (buffer_offset / sizeof(uint32_t));
+
+ buffer_offset += transfer_size;
+ if (transfer_size + buffer_offset > DMA_BUFFER_SIZE) {
+ buffer_offset = 0;
+ buffer_index++;
+ }
+
+ DEBUG_PRINT(" desc %i\n", i);
+ DEBUG_PRINT(" start addr virt 0x%p, phys 0x%lx\n",
+ priv(dev)->desc_dio_buffer[i],
+ (unsigned long)priv(dev)->dma_desc[i].pci_start_addr);
+ DEBUG_PRINT(" next 0x%lx\n",
+ (unsigned long)priv(dev)->dma_desc[i].next);
+ }
+ priv(dev)->num_dma_descriptors = i;
+ // fix last descriptor to point back to first
+ priv(dev)->dma_desc[i - 1].next =
+ cpu_to_le32(priv(dev)->dma_desc_phys_addr | next_bits);
+ DEBUG_PRINT(" desc %i next fixup 0x%lx\n", i - 1,
+ (unsigned long)priv(dev)->dma_desc[i - 1].next);
+
+ priv(dev)->block_size = transfer_size;
+
+ return transfer_size;
+}
+
+static int hpdi_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pci_dev *pcidev;
+ int i;
+ int retval;
+
+ printk("comedi%d: gsc_hpdi\n", dev->minor);
+
+ if (alloc_private(dev, sizeof(struct hpdi_private)) < 0)
+ return -ENOMEM;
+
+ pcidev = NULL;
+ for (i = 0; i < num_boards() && dev->board_ptr == NULL; i++) {
+ do {
+ pcidev = pci_get_subsys(PCI_VENDOR_ID_PLX,
+ hpdi_boards[i].device_id, PCI_VENDOR_ID_PLX,
+ hpdi_boards[i].subdevice_id, pcidev);
+ // was a particular bus/slot requested?
+ if (it->options[0] || it->options[1]) {
+ // are we on the wrong bus/slot?
+ if (pcidev->bus->number != it->options[0] ||
+ PCI_SLOT(pcidev->devfn) !=
+ it->options[1])
+ continue;
+ }
+ if (pcidev) {
+ priv(dev)->hw_dev = pcidev;
+ dev->board_ptr = hpdi_boards + i;
+ break;
+ }
+ } while (pcidev != NULL);
+ }
+ if (dev->board_ptr == NULL) {
+ printk("gsc_hpdi: no hpdi card found\n");
+ return -EIO;
+ }
+
+ printk("gsc_hpdi: found %s on bus %i, slot %i\n", board(dev)->name,
+ pcidev->bus->number, PCI_SLOT(pcidev->devfn));
+
+ if (comedi_pci_enable(pcidev, driver_hpdi.driver_name)) {
+ printk(KERN_WARNING
+ " failed enable PCI device and request regions\n");
+ return -EIO;
+ }
+ pci_set_master(pcidev);
+
+ //Initialize dev->board_name
+ dev->board_name = board(dev)->name;
+
+ priv(dev)->plx9080_phys_iobase =
+ pci_resource_start(pcidev, PLX9080_BADDRINDEX);
+ priv(dev)->hpdi_phys_iobase =
+ pci_resource_start(pcidev, HPDI_BADDRINDEX);
+
+ // remap, won't work with 2.0 kernels but who cares
+ priv(dev)->plx9080_iobase = ioremap(priv(dev)->plx9080_phys_iobase,
+ pci_resource_len(pcidev, PLX9080_BADDRINDEX));
+ priv(dev)->hpdi_iobase = ioremap(priv(dev)->hpdi_phys_iobase,
+ pci_resource_len(pcidev, HPDI_BADDRINDEX));
+ if (!priv(dev)->plx9080_iobase || !priv(dev)->hpdi_iobase) {
+ printk(" failed to remap io memory\n");
+ return -ENOMEM;
+ }
+
+ DEBUG_PRINT(" plx9080 remapped to 0x%p\n", priv(dev)->plx9080_iobase);
+ DEBUG_PRINT(" hpdi remapped to 0x%p\n", priv(dev)->hpdi_iobase);
+
+ init_plx9080(dev);
+
+ // get irq
+ if (comedi_request_irq(pcidev->irq, handle_interrupt, IRQF_SHARED,
+ driver_hpdi.driver_name, dev)) {
+ printk(" unable to allocate irq %u\n", pcidev->irq);
+ return -EINVAL;
+ }
+ dev->irq = pcidev->irq;
+
+ printk(" irq %u\n", dev->irq);
+
+ // alocate pci dma buffers
+ for (i = 0; i < NUM_DMA_BUFFERS; i++) {
+ priv(dev)->dio_buffer[i] =
+ pci_alloc_consistent(priv(dev)->hw_dev, DMA_BUFFER_SIZE,
+ &priv(dev)->dio_buffer_phys_addr[i]);
+ DEBUG_PRINT("dio_buffer at virt 0x%p, phys 0x%lx\n",
+ priv(dev)->dio_buffer[i],
+ (unsigned long)priv(dev)->dio_buffer_phys_addr[i]);
+ }
+ // allocate dma descriptors
+ priv(dev)->dma_desc = pci_alloc_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) * NUM_DMA_DESCRIPTORS,
+ &priv(dev)->dma_desc_phys_addr);
+ if (priv(dev)->dma_desc_phys_addr & 0xf) {
+ printk(" dma descriptors not quad-word aligned (bug)\n");
+ return -EIO;
+ }
+
+ retval = setup_dma_descriptors(dev, 0x1000);
+ if (retval < 0)
+ return retval;
+
+ retval = setup_subdevices(dev);
+ if (retval < 0)
+ return retval;
+
+ return init_hpdi(dev);
+}
+
+static int hpdi_detach(struct comedi_device * dev)
+{
+ unsigned int i;
+
+ printk("comedi%d: gsc_hpdi: remove\n", dev->minor);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (priv(dev)) {
+ if (priv(dev)->hw_dev) {
+ if (priv(dev)->plx9080_iobase) {
+ disable_plx_interrupts(dev);
+ iounmap((void *)priv(dev)->plx9080_iobase);
+ }
+ if (priv(dev)->hpdi_iobase)
+ iounmap((void *)priv(dev)->hpdi_iobase);
+ // free pci dma buffers
+ for (i = 0; i < NUM_DMA_BUFFERS; i++) {
+ if (priv(dev)->dio_buffer[i])
+ pci_free_consistent(priv(dev)->hw_dev,
+ DMA_BUFFER_SIZE,
+ priv(dev)->dio_buffer[i],
+ priv(dev)->
+ dio_buffer_phys_addr[i]);
+ }
+ // free dma descriptors
+ if (priv(dev)->dma_desc)
+ pci_free_consistent(priv(dev)->hw_dev,
+ sizeof(struct plx_dma_desc) *
+ NUM_DMA_DESCRIPTORS,
+ priv(dev)->dma_desc,
+ priv(dev)->dma_desc_phys_addr);
+ if (priv(dev)->hpdi_phys_iobase) {
+ comedi_pci_disable(priv(dev)->hw_dev);
+ }
+ pci_dev_put(priv(dev)->hw_dev);
+ }
+ }
+ return 0;
+}
+
+static int dio_config_block_size(struct comedi_device * dev, unsigned int * data)
+{
+ unsigned int requested_block_size;
+ int retval;
+
+ requested_block_size = data[1];
+
+ retval = setup_dma_descriptors(dev, requested_block_size);
+ if (retval < 0)
+ return retval;
+
+ data[1] = retval;
+
+ return 2;
+}
+
+static int di_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ // uniqueness check
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 32;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ if (cmd->chanlist) {
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != i) {
+ // XXX could support 8 channels or 16 channels
+ comedi_error(dev,
+ "chanlist must be channels 0 to 31 in order");
+ err++;
+ break;
+ }
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int hpdi_cmd_test(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ if (priv(dev)->dio_config_output) {
+ return -EINVAL;
+ } else
+ return di_cmd_test(dev, s, cmd);
+}
+
+static inline void hpdi_writel(struct comedi_device * dev, uint32_t bits,
+ unsigned int offset)
+{
+ writel(bits | priv(dev)->bits[offset / sizeof(uint32_t)],
+ priv(dev)->hpdi_iobase + offset);
+}
+
+static int di_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ uint32_t bits;
+ unsigned long flags;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+
+ hpdi_writel(dev, RX_FIFO_RESET_BIT, BOARD_CONTROL_REG);
+
+ DEBUG_PRINT("hpdi: in di_cmd\n");
+
+ abort_dma(dev, 0);
+
+ priv(dev)->dma_desc_index = 0;
+
+ /* These register are supposedly unused during chained dma,
+ * but I have found that left over values from last operation
+ * occasionally cause problems with transfer of first dma
+ * block. Initializing them to zero seems to fix the problem. */
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_TRANSFER_SIZE_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG);
+ writel(0, priv(dev)->plx9080_iobase + PLX_DMA0_LOCAL_ADDRESS_REG);
+ // give location of first dma descriptor
+ bits = priv(dev)->
+ dma_desc_phys_addr | PLX_DESC_IN_PCI_BIT | PLX_INTR_TERM_COUNT |
+ PLX_XFER_LOCAL_TO_PCI;
+ writel(bits, priv(dev)->plx9080_iobase + PLX_DMA0_DESCRIPTOR_REG);
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ // enable dma transfer
+ writeb(PLX_DMA_EN_BIT | PLX_DMA_START_BIT | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ if (cmd->stop_src == TRIG_COUNT)
+ priv(dev)->dio_count = cmd->stop_arg;
+ else
+ priv(dev)->dio_count = 1;
+
+ // clear over/under run status flags
+ writel(RX_UNDERRUN_BIT | RX_OVERRUN_BIT,
+ priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+ // enable interrupts
+ writel(intr_bit(RX_FULL_INTR),
+ priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+ DEBUG_PRINT("hpdi: starting rx\n");
+ hpdi_writel(dev, RX_ENABLE_BIT, BOARD_CONTROL_REG);
+
+ return 0;
+}
+
+static int hpdi_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (priv(dev)->dio_config_output) {
+ return -EINVAL;
+ } else
+ return di_cmd(dev, s);
+}
+
+static void drain_dma_buffers(struct comedi_device * dev, unsigned int channel)
+{
+ struct comedi_async *async = dev->read_subdev->async;
+ uint32_t next_transfer_addr;
+ int j;
+ int num_samples = 0;
+ void *pci_addr_reg;
+
+ if (channel)
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA1_PCI_ADDRESS_REG;
+ else
+ pci_addr_reg =
+ priv(dev)->plx9080_iobase + PLX_DMA0_PCI_ADDRESS_REG;
+
+ // loop until we have read all the full buffers
+ j = 0;
+ for (next_transfer_addr = readl(pci_addr_reg);
+ (next_transfer_addr <
+ le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
+ dma_desc_index].pci_start_addr)
+ || next_transfer_addr >=
+ le32_to_cpu(priv(dev)->dma_desc[priv(dev)->
+ dma_desc_index].pci_start_addr) +
+ priv(dev)->block_size)
+ && j < priv(dev)->num_dma_descriptors; j++) {
+ // transfer data from dma buffer to comedi buffer
+ num_samples = priv(dev)->block_size / sizeof(uint32_t);
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ if (num_samples > priv(dev)->dio_count)
+ num_samples = priv(dev)->dio_count;
+ priv(dev)->dio_count -= num_samples;
+ }
+ cfc_write_array_to_buffer(dev->read_subdev,
+ priv(dev)->desc_dio_buffer[priv(dev)->dma_desc_index],
+ num_samples * sizeof(uint32_t));
+ priv(dev)->dma_desc_index++;
+ priv(dev)->dma_desc_index %= priv(dev)->num_dma_descriptors;
+
+ DEBUG_PRINT("next desc addr 0x%lx\n", (unsigned long)
+ priv(dev)->dma_desc[priv(dev)->dma_desc_index].next);
+ DEBUG_PRINT("pci addr reg 0x%x\n", next_transfer_addr);
+ }
+ // XXX check for buffer overrun somehow
+}
+
+static irqreturn_t handle_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ uint32_t hpdi_intr_status, hpdi_board_status;
+ uint32_t plx_status;
+ uint32_t plx_bits;
+ uint8_t dma0_status, dma1_status;
+ unsigned long flags;
+
+ if (!dev->attached) {
+ return IRQ_NONE;
+ }
+
+ plx_status = readl(priv(dev)->plx9080_iobase + PLX_INTRCS_REG);
+ if ((plx_status & (ICS_DMA0_A | ICS_DMA1_A | ICS_LIA)) == 0) {
+ return IRQ_NONE;
+ }
+
+ hpdi_intr_status = readl(priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
+ hpdi_board_status = readl(priv(dev)->hpdi_iobase + BOARD_STATUS_REG);
+
+ async->events = 0;
+
+ if (hpdi_intr_status) {
+ DEBUG_PRINT("hpdi: intr status 0x%x, ", hpdi_intr_status);
+ writel(hpdi_intr_status,
+ priv(dev)->hpdi_iobase + INTERRUPT_STATUS_REG);
+ }
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma0_status = readb(priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+ if (plx_status & ICS_DMA0_A) { // dma chan 0 interrupt
+ writeb((dma0_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA0_CS_REG);
+
+ DEBUG_PRINT("dma0 status 0x%x\n", dma0_status);
+ if (dma0_status & PLX_DMA_EN_BIT) {
+ drain_dma_buffers(dev, 0);
+ }
+ DEBUG_PRINT(" cleared dma ch0 interrupt\n");
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // spin lock makes sure noone else changes plx dma control reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ dma1_status = readb(priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ if (plx_status & ICS_DMA1_A) // XXX
+ { // dma chan 1 interrupt
+ writeb((dma1_status & PLX_DMA_EN_BIT) | PLX_CLEAR_DMA_INTR_BIT,
+ priv(dev)->plx9080_iobase + PLX_DMA1_CS_REG);
+ DEBUG_PRINT("dma1 status 0x%x\n", dma1_status);
+
+ DEBUG_PRINT(" cleared dma ch1 interrupt\n");
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // clear possible plx9080 interrupt sources
+ if (plx_status & ICS_LDIA) { // clear local doorbell interrupt
+ plx_bits = readl(priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ writel(plx_bits, priv(dev)->plx9080_iobase + PLX_DBR_OUT_REG);
+ DEBUG_PRINT(" cleared local doorbell bits 0x%x\n", plx_bits);
+ }
+
+ if (hpdi_board_status & RX_OVERRUN_BIT) {
+ comedi_error(dev, "rx fifo overrun");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ DEBUG_PRINT("dma0_status 0x%x\n",
+ (int)readb(priv(dev)->plx9080_iobase +
+ PLX_DMA0_CS_REG));
+ }
+
+ if (hpdi_board_status & RX_UNDERRUN_BIT) {
+ comedi_error(dev, "rx fifo underrun");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+
+ if (priv(dev)->dio_count == 0)
+ async->events |= COMEDI_CB_EOA;
+
+ DEBUG_PRINT("board status 0x%x, ", hpdi_board_status);
+ DEBUG_PRINT("plx status 0x%x\n", plx_status);
+ if (async->events)
+ DEBUG_PRINT(" events 0x%x\n", async->events);
+
+ cfc_handle_events(dev, s);
+
+ return IRQ_HANDLED;
+}
+
+void abort_dma(struct comedi_device * dev, unsigned int channel)
+{
+ unsigned long flags;
+
+ // spinlock for plx dma control/status reg
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ plx9080_abort_dma(priv(dev)->plx9080_iobase, channel);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+}
+
+static int hpdi_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ hpdi_writel(dev, 0, BOARD_CONTROL_REG);
+
+ writel(0, priv(dev)->hpdi_iobase + INTERRUPT_CONTROL_REG);
+
+ abort_dma(dev, 0);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/icp_multi.c b/drivers/staging/comedi/drivers/icp_multi.c
index 59144d7cb0b..15fce0190b2 100644
--- a/drivers/staging/comedi/drivers/icp_multi.c
+++ b/drivers/staging/comedi/drivers/icp_multi.c
@@ -61,7 +61,7 @@ Options:
#define ICP_MULTI_EXTDEBUG
-// Hardware types of the cards
+/* Hardware types of the cards */
#define TYPE_ICP_MULTI 0
#define IORANGE_ICP_MULTI 32
@@ -81,20 +81,20 @@ Options:
#define ICP_MULTI_SIZE 0x20 /* 32 bytes */
-// Define bits from ADC command/status register
+/* Define bits from ADC command/status register */
#define ADC_ST 0x0001 /* Start ADC */
#define ADC_BSY 0x0001 /* ADC busy */
#define ADC_BI 0x0010 /* Bipolar input range 1 = bipolar */
#define ADC_RA 0x0020 /* Input range 0 = 5V, 1 = 10V */
#define ADC_DI 0x0040 /* Differential input mode 1 = differential */
-// Define bits from DAC command/status register
+/* Define bits from DAC command/status register */
#define DAC_ST 0x0001 /* Start DAC */
#define DAC_BSY 0x0001 /* DAC busy */
#define DAC_BI 0x0010 /* Bipolar input range 1 = bipolar */
#define DAC_RA 0x0020 /* Input range 0 = 5V, 1 = 10V */
-// Define bits from interrupt enable/status registers
+/* Define bits from interrupt enable/status registers */
#define ADC_READY 0x0001 /* A/d conversion ready interrupt */
#define DAC_READY 0x0002 /* D/a conversion ready interrupt */
#define DOUT_ERROR 0x0004 /* Digital output error interrupt */
@@ -104,11 +104,11 @@ Options:
#define CIE2 0x0040 /* Counter 2 overrun interrupt */
#define CIE3 0x0080 /* Counter 3 overrun interrupt */
-// Useful definitions
-#define Status_IRQ 0x00ff // All interrupts
+/* Useful definitions */
+#define Status_IRQ 0x00ff /* All interrupts */
-// Define analogue range
-static const comedi_lrange range_analog = { 4, {
+/* Define analogue range */
+static const struct comedi_lrange range_analog = { 4, {
UNI_RANGE(5),
UNI_RANGE(10),
BIP_RANGE(5),
@@ -123,8 +123,8 @@ static const char range_codes_analog[] = { 0x00, 0x20, 0x10, 0x30 };
Forward declarations
==============================================================================
*/
-static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it);
-static int icp_multi_detach(comedi_device * dev);
+static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int icp_multi_detach(struct comedi_device *dev);
/*
==============================================================================
@@ -133,79 +133,79 @@ static int icp_multi_detach(comedi_device * dev);
*/
static unsigned short pci_list_builded = 0; /*>0 list of card is known */
-typedef struct {
- const char *name; // driver name
+struct boardtype {
+ const char *name; /* driver name */
int device_id;
- int iorange; // I/O range len
- char have_irq; // 1=card support IRQ
- char cardtype; // 0=ICP Multi
- int n_aichan; // num of A/D chans
- int n_aichand; // num of A/D chans in diff mode
- int n_aochan; // num of D/A chans
- int n_dichan; // num of DI chans
- int n_dochan; // num of DO chans
- int n_ctrs; // num of counters
- int ai_maxdata; // resolution of A/D
- int ao_maxdata; // resolution of D/A
- const comedi_lrange *rangelist_ai; // rangelist for A/D
- const char *rangecode; // range codes for programming
- const comedi_lrange *rangelist_ao; // rangelist for D/A
-} boardtype;
-
-static const boardtype boardtypes[] = {
- {"icp_multi", // Driver name
- DEVICE_ID, // PCI device ID
- IORANGE_ICP_MULTI, // I/O range length
- 1, // 1=Card supports interrupts
- TYPE_ICP_MULTI, // Card type = ICP MULTI
- 16, // Num of A/D channels
- 8, // Num of A/D channels in diff mode
- 4, // Num of D/A channels
- 16, // Num of digital inputs
- 8, // Num of digital outputs
- 4, // Num of counters
- 0x0fff, // Resolution of A/D
- 0x0fff, // Resolution of D/A
- &range_analog, // Rangelist for A/D
- range_codes_analog, // Range codes for programming
- &range_analog}, // Rangelist for D/A
+ int iorange; /* I/O range len */
+ char have_irq; /* 1=card support IRQ */
+ char cardtype; /* 0=ICP Multi */
+ int n_aichan; /* num of A/D chans */
+ int n_aichand; /* num of A/D chans in diff mode */
+ int n_aochan; /* num of D/A chans */
+ int n_dichan; /* num of DI chans */
+ int n_dochan; /* num of DO chans */
+ int n_ctrs; /* num of counters */
+ int ai_maxdata; /* resolution of A/D */
+ int ao_maxdata; /* resolution of D/A */
+ const struct comedi_lrange *rangelist_ai; /* rangelist for A/D */
+ const char *rangecode; /* range codes for programming */
+ const struct comedi_lrange *rangelist_ao; /* rangelist for D/A */
};
-#define n_boardtypes (sizeof(boardtypes)/sizeof(boardtype))
+static const struct boardtype boardtypes[] = {
+ {"icp_multi", /* Driver name */
+ DEVICE_ID, /* PCI device ID */
+ IORANGE_ICP_MULTI, /* I/O range length */
+ 1, /* 1=Card supports interrupts */
+ TYPE_ICP_MULTI, /* Card type = ICP MULTI */
+ 16, /* Num of A/D channels */
+ 8, /* Num of A/D channels in diff mode */
+ 4, /* Num of D/A channels */
+ 16, /* Num of digital inputs */
+ 8, /* Num of digital outputs */
+ 4, /* Num of counters */
+ 0x0fff, /* Resolution of A/D */
+ 0x0fff, /* Resolution of D/A */
+ &range_analog, /* Rangelist for A/D */
+ range_codes_analog, /* Range codes for programming */
+ &range_analog}, /* Rangelist for D/A */
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct boardtype))
-static comedi_driver driver_icp_multi = {
+static struct comedi_driver driver_icp_multi = {
driver_name:"icp_multi",
- module:THIS_MODULE,
- attach:icp_multi_attach,
- detach:icp_multi_detach,
- num_names:n_boardtypes,
- board_name:&boardtypes[0].name,
- offset:sizeof(boardtype),
+ module : THIS_MODULE,
+ attach : icp_multi_attach,
+ detach : icp_multi_detach,
+ num_names : n_boardtypes,
+ board_name : &boardtypes[0].name,
+ offset : sizeof(struct boardtype),
};
COMEDI_INITCLEANUP(driver_icp_multi);
-typedef struct {
- struct pcilst_struct *card; // pointer to card
- char valid; // card is usable
- void *io_addr; // Pointer to mapped io address
- resource_size_t phys_iobase; // Physical io address
- unsigned int AdcCmdStatus; // ADC Command/Status register
- unsigned int DacCmdStatus; // DAC Command/Status register
- unsigned int IntEnable; // Interrupt Enable register
- unsigned int IntStatus; // Interrupt Status register
- unsigned int act_chanlist[32]; // list of scaned channel
- unsigned char act_chanlist_len; // len of scanlist
- unsigned char act_chanlist_pos; // actual position in MUX list
- unsigned int *ai_chanlist; // actaul chanlist
- sampl_t *ai_data; // data buffer
- sampl_t ao_data[4]; // data output buffer
- sampl_t di_data; // Digital input data
- unsigned int do_data; // Remember digital output data
-} icp_multi_private;
-
-#define devpriv ((icp_multi_private *)dev->private)
-#define this_board ((const boardtype *)dev->board_ptr)
+struct icp_multi_private {
+ struct pcilst_struct *card; /* pointer to card */
+ char valid; /* card is usable */
+ void *io_addr; /* Pointer to mapped io address */
+ resource_size_t phys_iobase; /* Physical io address */
+ unsigned int AdcCmdStatus; /* ADC Command/Status register */
+ unsigned int DacCmdStatus; /* DAC Command/Status register */
+ unsigned int IntEnable; /* Interrupt Enable register */
+ unsigned int IntStatus; /* Interrupt Status register */
+ unsigned int act_chanlist[32]; /* list of scaned channel */
+ unsigned char act_chanlist_len; /* len of scanlist */
+ unsigned char act_chanlist_pos; /* actual position in MUX list */
+ unsigned int *ai_chanlist; /* actaul chanlist */
+ short *ai_data; /* data buffer */
+ short ao_data[4]; /* data output buffer */
+ short di_data; /* Digital input data */
+ unsigned int do_data; /* Remember digital output data */
+};
+
+#define devpriv ((struct icp_multi_private *)dev->private)
+#define this_board ((const struct boardtype *)dev->board_ptr)
/*
==============================================================================
@@ -214,12 +214,12 @@ typedef struct {
*/
#if 0
-static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
+static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan);
#endif
-static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
+static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan);
-static int icp_multi_reset(comedi_device * dev);
+static int icp_multi_reset(struct comedi_device *dev);
/*
==============================================================================
@@ -236,32 +236,32 @@ static int icp_multi_reset(comedi_device * dev);
This function reads a single analogue input.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue input data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue input data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ai(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n, timeout;
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: BGN: icp_multi_insn_read_ai(...)\n");
#endif
- // Disable A/D conversion ready interrupt
+ /* Disable A/D conversion ready interrupt */
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Set up appropriate channel, mode and range data, for specified channel
+ /* Set up appropriate channel, mode and range data, for specified channel */
setup_channel_list(dev, s, &insn->chanspec, 1);
#ifdef ICP_MULTI_EXTDEBUG
@@ -271,7 +271,7 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
#endif
for (n = 0; n < insn->n; n++) {
- // Set start ADC bit
+ /* Set start ADC bit */
devpriv->AdcCmdStatus |= ADC_ST;
writew(devpriv->AdcCmdStatus,
devpriv->io_addr + ICP_MULTI_ADC_CSR);
@@ -289,7 +289,7 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
readw(devpriv->io_addr + ICP_MULTI_ADC_CSR));
#endif
- // Wait for conversion to complete, or get fed up waiting
+ /* Wait for conversion to complete, or get fed up waiting */
timeout = 100;
while (timeout--) {
if (!(readw(devpriv->io_addr +
@@ -307,19 +307,19 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
comedi_udelay(1);
}
- // If we reach here, a timeout has occurred
+ /* If we reach here, a timeout has occurred */
comedi_error(dev, "A/D insn timeout");
- // Disable interrupt
+ /* Disable interrupt */
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
writew(devpriv->IntStatus,
devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Clear data received
+ /* Clear data received */
data[n] = 0;
#ifdef ICP_MULTI_EXTDEBUG
@@ -332,11 +332,11 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
(readw(devpriv->io_addr + ICP_MULTI_AI) >> 4) & 0x0fff;
}
- // Disable interrupt
+ /* Disable interrupt */
devpriv->IntEnable &= ~ADC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= ADC_READY;
writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
@@ -355,40 +355,40 @@ static int icp_multi_insn_read_ai(comedi_device * dev, comedi_subdevice * s,
This function writes a single analogue output.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_write_ao(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n, chan, range, timeout;
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: BGN: icp_multi_insn_write_ao(...)\n");
#endif
- // Disable D/A conversion ready interrupt
+ /* Disable D/A conversion ready interrupt */
devpriv->IntEnable &= ~DAC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
writew(devpriv->IntStatus, devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Get channel number and range
+ /* Get channel number and range */
chan = CR_CHAN(insn->chanspec);
range = CR_RANGE(insn->chanspec);
- // Set up range and channel data
- // Bit 4 = 1 : Bipolar
- // Bit 5 = 0 : 5V
- // Bit 5 = 1 : 10V
- // Bits 8-9 : Channel number
+ /* Set up range and channel data */
+ /* Bit 4 = 1 : Bipolar */
+ /* Bit 5 = 0 : 5V */
+ /* Bit 5 = 1 : 10V */
+ /* Bits 8-9 : Channel number */
devpriv->DacCmdStatus &= 0xfccf;
devpriv->DacCmdStatus |= this_board->rangecode[range];
devpriv->DacCmdStatus |= (chan << 8);
@@ -396,7 +396,7 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
writew(devpriv->DacCmdStatus, devpriv->io_addr + ICP_MULTI_DAC_CSR);
for (n = 0; n < insn->n; n++) {
- // Wait for analogue output data register to be ready for new data, or get fed up waiting
+ /* Wait for analogue output data register to be ready for new data, or get fed up waiting */
timeout = 100;
while (timeout--) {
if (!(readw(devpriv->io_addr +
@@ -414,19 +414,19 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
comedi_udelay(1);
}
- // If we reach here, a timeout has occurred
+ /* If we reach here, a timeout has occurred */
comedi_error(dev, "D/A insn timeout");
- // Disable interrupt
+ /* Disable interrupt */
devpriv->IntEnable &= ~DAC_READY;
writew(devpriv->IntEnable, devpriv->io_addr + ICP_MULTI_INT_EN);
- // Clear interrupt status
+ /* Clear interrupt status */
devpriv->IntStatus |= DAC_READY;
writew(devpriv->IntStatus,
devpriv->io_addr + ICP_MULTI_INT_STAT);
- // Clear data received
+ /* Clear data received */
devpriv->ao_data[chan] = 0;
#ifdef ICP_MULTI_EXTDEBUG
@@ -435,16 +435,16 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
return -ETIME;
dac_ready:
- // Write data to analogue output data register
+ /* Write data to analogue output data register */
writew(data[n], devpriv->io_addr + ICP_MULTI_AO);
- // Set DAC_ST bit to write the data to selected channel
+ /* Set DAC_ST bit to write the data to selected channel */
devpriv->DacCmdStatus |= DAC_ST;
writew(devpriv->DacCmdStatus,
devpriv->io_addr + ICP_MULTI_DAC_CSR);
devpriv->DacCmdStatus &= ~DAC_ST;
- // Save analogue output data
+ /* Save analogue output data */
devpriv->ao_data[chan] = data[n];
}
@@ -463,24 +463,24 @@ static int icp_multi_insn_write_ao(comedi_device * dev, comedi_subdevice * s,
This function reads a single analogue output.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_read_ao(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ao(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n, chan;
- // Get channel number
+ /* Get channel number */
chan = CR_CHAN(insn->chanspec);
- // Read analogue outputs
+ /* Read analogue outputs */
for (n = 0; n < insn->n; n++)
data[n] = devpriv->ao_data[chan];
@@ -496,17 +496,17 @@ static int icp_multi_insn_read_ao(comedi_device * dev, comedi_subdevice * s,
This function reads the digital inputs.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_bits_di(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_bits_di(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
data[1] = readw(devpriv->io_addr + ICP_MULTI_DI);
@@ -522,17 +522,17 @@ static int icp_multi_insn_bits_di(comedi_device * dev, comedi_subdevice * s,
This function writes the appropriate digital outputs.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to analogue output data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to analogue output data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_bits_do(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_bits_do(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: BGN: icp_multi_insn_bits_do(...)\n");
@@ -564,17 +564,17 @@ static int icp_multi_insn_bits_do(comedi_device * dev, comedi_subdevice * s,
This function reads the specified counter.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to counter data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to counter data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_read_ctr(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_read_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return 0;
}
@@ -588,17 +588,17 @@ static int icp_multi_insn_read_ctr(comedi_device * dev, comedi_subdevice * s,
This function write to the specified counter.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_subdevice *s Pointer to current subdevice structure
- comedi_insn *insn Pointer to current comedi instruction
- lsampl_t *data Pointer to counter data
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_insn *insn Pointer to current comedi instruction
+ unsigned int *data Pointer to counter data
Returns:int Nmuber of instructions executed
==============================================================================
*/
-static int icp_multi_insn_write_ctr(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int icp_multi_insn_write_ctr(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return 0;
}
@@ -620,7 +620,7 @@ static int icp_multi_insn_write_ctr(comedi_device * dev, comedi_subdevice * s,
*/
static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
{
- comedi_device *dev = d;
+ struct comedi_device *dev = d;
int int_no;
#ifdef ICP_MULTI_EXTDEBUG
@@ -628,10 +628,10 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
irq);
#endif
- // Is this interrupt from our board?
+ /* Is this interrupt from our board? */
int_no = readw(devpriv->io_addr + ICP_MULTI_INT_STAT) & Status_IRQ;
if (!int_no)
- // No, exit
+ /* No, exit */
return IRQ_NONE;
#ifdef ICP_MULTI_EXTDEBUG
@@ -639,7 +639,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
readw(devpriv->io_addr + ICP_MULTI_INT_STAT));
#endif
- // Determine which interrupt is active & handle it
+ /* Determine which interrupt is active & handle it */
switch (int_no) {
case ADC_READY:
break;
@@ -679,8 +679,8 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
is built correctly
Parameters:
- comedi_device *dev Pointer to current sevice structure
- comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_device *dev Pointer to current sevice structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
unsigned int *chanlist Pointer to packed channel list
unsigned int n_chan Number of channels to scan
@@ -689,7 +689,7 @@ static irqreturn_t interrupt_service_icp_multi(int irq, void *d PT_REGS_ARG)
==============================================================================
*/
-static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
+static int check_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan)
{
unsigned int i;
@@ -697,14 +697,14 @@ static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
#ifdef ICP_MULTI_EXTDEBUG
printk("icp multi EDBG: check_channel_list(...,%d)\n", n_chan);
#endif
- // Check that we at least have one channel to check
+ /* Check that we at least have one channel to check */
if (n_chan < 1) {
comedi_error(dev, "range/channel list is empty!");
return 0;
}
- // Check all channels
+ /* Check all channels */
for (i = 0; i < n_chan; i++) {
- // Check that channel number is < maximum
+ /* Check that channel number is < maximum */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
if (CR_CHAN(chanlist[i]) > this_board->n_aichand) {
comedi_error(dev,
@@ -734,8 +734,8 @@ static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
Status register.
Parameters:
- comedi_device *dev Pointer to current sevice structure
- comedi_subdevice *s Pointer to current subdevice structure
+ struct comedi_device *dev Pointer to current sevice structure
+ struct comedi_subdevice *s Pointer to current subdevice structure
unsigned int *chanlist Pointer to packed channel list
unsigned int n_chan Number of channels to scan
@@ -743,7 +743,7 @@ static int check_channel_list(comedi_device * dev, comedi_subdevice * s,
==============================================================================
*/
-static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
+static void setup_channel_list(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int *chanlist, unsigned int n_chan)
{
unsigned int i, range, chanprog;
@@ -756,10 +756,10 @@ static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
devpriv->act_chanlist_pos = 0;
for (i = 0; i < n_chan; i++) {
- // Get channel
+ /* Get channel */
chanprog = CR_CHAN(chanlist[i]);
- // Determine if it is a differential channel (Bit 15 = 1)
+ /* Determine if it is a differential channel (Bit 15 = 1) */
if (CR_AREF(chanlist[i]) == AREF_DIFF) {
diff = 1;
chanprog &= 0x0007;
@@ -768,21 +768,21 @@ static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
chanprog &= 0x000f;
}
- // Clear channel, range and input mode bits in A/D command/status register
+ /* Clear channel, range and input mode bits in A/D command/status register */
devpriv->AdcCmdStatus &= 0xf00f;
- // Set channel number and differential mode status bit
+ /* Set channel number and differential mode status bit */
if (diff) {
- // Set channel number, bits 9-11 & mode, bit 6
+ /* Set channel number, bits 9-11 & mode, bit 6 */
devpriv->AdcCmdStatus |= (chanprog << 9);
devpriv->AdcCmdStatus |= ADC_DI;
} else
- // Set channel number, bits 8-11
+ /* Set channel number, bits 8-11 */
devpriv->AdcCmdStatus |= (chanprog << 8);
- // Get range for current channel
+ /* Get range for current channel */
range = this_board->rangecode[CR_RANGE(chanlist[i])];
- // Set range. bits 4-5
+ /* Set range. bits 4-5 */
devpriv->AdcCmdStatus |= range;
/* Output channel, range, mode to ICP Multi */
@@ -806,45 +806,45 @@ static void setup_channel_list(comedi_device * dev, comedi_subdevice * s,
This function resets the icp multi device to a 'safe' state
Parameters:
- comedi_device *dev Pointer to current sevice structure
+ struct comedi_device *dev Pointer to current sevice structure
Returns:int 0 = success
==============================================================================
*/
-static int icp_multi_reset(comedi_device * dev)
+static int icp_multi_reset(struct comedi_device *dev)
{
unsigned int i;
#ifdef ICP_MULTI_EXTDEBUG
printk("icp_multi EDBG: BGN: icp_multi_reset(...)\n");
#endif
- // Clear INT enables and requests
+ /* Clear INT enables and requests */
writew(0, devpriv->io_addr + ICP_MULTI_INT_EN);
writew(0x00ff, devpriv->io_addr + ICP_MULTI_INT_STAT);
if (this_board->n_aochan)
- // Set DACs to 0..5V range and 0V output
+ /* Set DACs to 0..5V range and 0V output */
for (i = 0; i < this_board->n_aochan; i++) {
devpriv->DacCmdStatus &= 0xfcce;
- // Set channel number
+ /* Set channel number */
devpriv->DacCmdStatus |= (i << 8);
- // Output 0V
+ /* Output 0V */
writew(0, devpriv->io_addr + ICP_MULTI_AO);
- // Set start conversion bit
+ /* Set start conversion bit */
devpriv->DacCmdStatus |= DAC_ST;
- // Output to command / status register
+ /* Output to command / status register */
writew(devpriv->DacCmdStatus,
devpriv->io_addr + ICP_MULTI_DAC_CSR);
- // Delay to allow DAC time to recover
+ /* Delay to allow DAC time to recover */
comedi_udelay(1);
}
- // Digital outputs to 0
+ /* Digital outputs to 0 */
writew(0, devpriv->io_addr + ICP_MULTI_DO);
#ifdef ICP_MULTI_EXTDEBUG
@@ -863,16 +863,16 @@ static int icp_multi_reset(comedi_device * dev)
device.
Parameters:
- comedi_device *dev Pointer to current device structure
- comedi_devconfig *it Pointer to current device configuration
+ struct comedi_device *dev Pointer to current device structure
+ struct comedi_devconfig *it Pointer to current device configuration
Returns:int 0 = success
==============================================================================
*/
-static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
+static int icp_multi_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int ret, subdev, n_subdevices;
unsigned int irq;
struct pcilst_struct *card = NULL;
@@ -881,11 +881,12 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
printk("icp_multi EDBG: BGN: icp_multi_attach(...)\n");
- // Alocate private data storage space
- if ((ret = alloc_private(dev, sizeof(icp_multi_private))) < 0)
+ /* Alocate private data storage space */
+ ret = alloc_private(dev, sizeof(struct icp_multi_private));
+ if (ret < 0)
return ret;
- // Initialise list of PCI cards in system, if not already done so
+ /* Initialise list of PCI cards in system, if not already done so */
if (pci_list_builded++ == 0) {
pci_card_list_init(PCI_VENDOR_ID_ICP,
#ifdef ICP_MULTI_EXTDEBUG
@@ -899,9 +900,11 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
printk("Anne's comedi%d: icp_multi: board=%s", dev->minor,
this_board->name);
- if ((card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
- this_board->device_id, it->options[0],
- it->options[1])) == NULL)
+ card = select_and_alloc_pci_card(PCI_VENDOR_ID_ICP,
+ this_board->device_id, it->options[0],
+ it->options[1]);
+
+ if (card == NULL)
return -EIO;
devpriv->card = card;
@@ -943,9 +946,9 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
if (this_board->n_ctrs)
n_subdevices++;
- if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ ret = alloc_subdevices(dev, n_subdevices);
+ if (ret < 0)
return ret;
- }
icp_multi_reset(dev);
@@ -1055,13 +1058,13 @@ static int icp_multi_attach(comedi_device * dev, comedi_devconfig * it)
device.
Parameters:
- comedi_device *dev Pointer to current device structure
+ struct comedi_device *dev Pointer to current device structure
Returns:int 0 = success
==============================================================================
*/
-static int icp_multi_detach(comedi_device * dev)
+static int icp_multi_detach(struct comedi_device *dev)
{
if (dev->private)
@@ -1077,9 +1080,8 @@ static int icp_multi_detach(comedi_device * dev)
if (dev->private && devpriv->card)
pci_card_free(devpriv->card);
- if (--pci_list_builded == 0) {
+ if (--pci_list_builded == 0)
pci_card_list_cleanup(PCI_VENDOR_ID_ICP);
- }
return 0;
}
diff --git a/drivers/staging/comedi/drivers/icp_multi.h b/drivers/staging/comedi/drivers/icp_multi.h
index 6df4a8d15ff..21d84766fea 100644
--- a/drivers/staging/comedi/drivers/icp_multi.h
+++ b/drivers/staging/comedi/drivers/icp_multi.h
@@ -28,7 +28,8 @@ struct pcilst_struct {
unsigned int irq;
};
-struct pcilst_struct *inova_devices; // ptr to root list of all Inova devices
+struct pcilst_struct *inova_devices;
+/* ptr to root list of all Inova devices */
/****************************************************************************/
@@ -150,14 +151,14 @@ static int find_free_pci_card_by_position(unsigned short vendor_id,
&& (inova->pci_slot == pci_slot)) {
if (!(inova->used)) {
*card = inova;
- return 0; // ok, card is found
+ return 0; /* ok, card is found */
} else {
- return 2; // card exist but is used
+ return 2; /* card exist but is used */
}
}
}
- return 1; // no card found
+ return 1; /* no card found */
}
/****************************************************************************/
@@ -243,9 +244,10 @@ static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
struct pcilst_struct *card;
int err;
- if ((pci_bus < 1) & (pci_slot < 1)) { // use autodetection
- if ((card = find_free_pci_card_by_device(vendor_id,
- device_id)) == NULL) {
+ if ((pci_bus < 1) & (pci_slot < 1)) { /* use autodetection */
+
+ card = find_free_pci_card_by_device(vendor_id, device_id);
+ if (card == NULL) {
rt_printk(" - Unused card not found in system!\n");
return NULL;
}
@@ -265,7 +267,8 @@ static struct pcilst_struct *select_and_alloc_pci_card(unsigned short vendor_id,
}
}
- if ((err = pci_card_alloc(card)) != 0) {
+ err = pci_card_alloc(card);
+ if (err != 0) {
if (err > 0)
rt_printk(" - Can't allocate card!\n");
/* else: error already printed. */
diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c
new file mode 100644
index 00000000000..80825ba2541
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ii_pci20kc.c
@@ -0,0 +1,612 @@
+/*
+ * comedi/drivers/ii_pci20kc.c
+ * Driver for Intelligent Instruments PCI-20001C carrier board
+ * and modules.
+ *
+ * Copyright (C) 2000 Markus Kempf <kempf@matsci.uni-sb.de>
+ * with suggestions from David Schleef
+ * 16.06.2000
+ *
+ * Linux device driver for COMEDI
+ * Intelligent Instrumentation
+ * PCI-20001 C-2A Carrier Board
+ * PCI-20341 M-1A 16-Bit analog input module
+ * - differential
+ * - range (-5V - +5V)
+ * - 16 bit
+ * PCI-20006 M-2 16-Bit analog output module
+ * - ranges (-10V - +10V) (0V - +10V) (-5V - +5V)
+ * - 16 bit
+ *
+ * only ONE PCI-20341 module possible
+ * only ONE PCI-20006 module possible
+ * no extern trigger implemented
+ *
+ * NOT WORKING (but soon) only 4 on-board differential channels supported
+ * NOT WORKING (but soon) only ONE di-port and ONE do-port supported instead of 4 digital ports
+ * di-port == Port 0
+ * do-port == Port 1
+ *
+ * The state of this driver is only a starting point for a complete
+ * COMEDI-driver. The final driver should support all features of the
+ * carrier board and modules.
+ *
+ * The test configuration:
+ *
+ * kernel 2.2.14 with RTAI v1.2 and patch-2.2.14rthal2
+ * COMEDI 0.7.45
+ * COMEDILIB 0.7.9
+ *
+ */
+/*
+Driver: ii_pci20kc
+Description: Intelligent Instruments PCI-20001C carrier board
+Author: Markus Kempf <kempf@matsci.uni-sb.de>
+Devices: [Intelligent Instrumentation] PCI-20001C (ii_pci20kc)
+Status: works
+
+Supports the PCI-20001 C-2a Carrier board, and could probably support
+the other carrier boards with small modifications. Modules supported
+are:
+ PCI-20006 M-2 16-bit analog output module
+ PCI-20341 M-1A 16-bit analog input module
+
+Options:
+ 0 Board base address
+ 1 IRQ
+ 2 first option for module 1
+ 3 second option for module 1
+ 4 first option for module 2
+ 5 second option for module 2
+ 6 first option for module 3
+ 7 second option for module 3
+
+options for PCI-20006M:
+ first: Analog output channel 0 range configuration
+ 0 bipolar 10 (-10V -- +10V)
+ 1 unipolar 10 (0V -- +10V)
+ 2 bipolar 5 (-5V -- 5V)
+ second: Analog output channel 1 range configuration
+
+options for PCI-20341M:
+ first: Analog input gain configuration
+ 0 1
+ 1 10
+ 2 100
+ 3 200
+*/
+
+/* XXX needs to use ioremap() for compatibility with 2.4 kernels. Should also
+ * check_mem_region() etc. - fmhess */
+
+#include "../comedidev.h"
+
+#define PCI20000_ID 0x1d
+#define PCI20341_ID 0x77
+#define PCI20006_ID 0xe3
+#define PCI20xxx_EMPTY_ID 0xff
+
+#define PCI20000_OFFSET 0x100
+#define PCI20000_MODULES 3
+
+#define PCI20000_DIO_0 0x80
+#define PCI20000_DIO_1 0x81
+#define PCI20000_DIO_2 0xc0
+#define PCI20000_DIO_3 0xc1
+#define PCI20000_DIO_CONTROL_01 0x83 /* port 0, 1 control */
+#define PCI20000_DIO_CONTROL_23 0xc3 /* port 2, 3 control */
+#define PCI20000_DIO_BUFFER 0x82 /* buffer direction and enable */
+#define PCI20000_DIO_EOC 0xef /* even port, control output */
+#define PCI20000_DIO_OOC 0xfd /* odd port, control output */
+#define PCI20000_DIO_EIC 0x90 /* even port, control input */
+#define PCI20000_DIO_OIC 0x82 /* odd port, control input */
+#define DIO_CAND 0x12 /* and bit 1, bit 4 of control */
+#define DIO_BE 0x01 /* buffer: port enable */
+#define DIO_BO 0x04 /* buffer: output */
+#define DIO_BI 0x05 /* buffer: input */
+#define DIO_PS_0 0x00 /* buffer: port shift 0 */
+#define DIO_PS_1 0x01 /* buffer: port shift 1 */
+#define DIO_PS_2 0x04 /* buffer: port shift 2 */
+#define DIO_PS_3 0x05 /* buffer: port shift 3 */
+
+#define PCI20006_LCHAN0 0x0d
+#define PCI20006_STROBE0 0x0b
+#define PCI20006_LCHAN1 0x15
+#define PCI20006_STROBE1 0x13
+
+#define PCI20341_INIT 0x04
+#define PCI20341_REPMODE 0x00 /* single shot mode */
+#define PCI20341_PACER 0x00 /* Hardware Pacer disabled */
+#define PCI20341_CHAN_NR 0x04 /* number of input channels */
+#define PCI20341_CONFIG_REG 0x10
+#define PCI20341_MOD_STATUS 0x01
+#define PCI20341_OPT_REG 0x11
+#define PCI20341_SET_TIME_REG 0x15
+#define PCI20341_LCHAN_ADDR_REG 0x13
+#define PCI20341_CHAN_LIST 0x80
+#define PCI20341_CC_RESET 0x1b
+#define PCI20341_CHAN_RESET 0x19
+#define PCI20341_SOFT_PACER 0x04
+#define PCI20341_STATUS_REG 0x12
+#define PCI20341_LDATA 0x02
+#define PCI20341_DAISY_CHAIN 0x20 /* On-board inputs only */
+#define PCI20341_MUX 0x04 /* Enable on-board MUX */
+#define PCI20341_SCANLIST 0x80 /* Channel/Gain Scan List */
+
+union pci20xxx_subdev_private {
+ void *iobase;
+ struct {
+ void *iobase;
+ const struct comedi_lrange *ao_range_list[2]; /* range of channels of ao module */
+ unsigned int last_data[2];
+ } pci20006;
+ struct {
+ void *iobase;
+ int timebase;
+ int settling_time;
+ int ai_gain;
+ } pci20341;
+};
+
+struct pci20xxx_private {
+
+ void *ioaddr;
+ union pci20xxx_subdev_private subdev_private[PCI20000_MODULES];
+};
+
+
+#define devpriv ((struct pci20xxx_private *)dev->private)
+#define CHAN (CR_CHAN(it->chanlist[0]))
+
+static int pci20xxx_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pci20xxx_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_pci20xxx = {
+ driver_name:"ii_pci20kc",
+ module:THIS_MODULE,
+ attach:pci20xxx_attach,
+ detach:pci20xxx_detach,
+};
+
+static int pci20006_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1);
+static int pci20341_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1);
+static int pci20xxx_dio_init(struct comedi_device * dev, struct comedi_subdevice * s);
+
+/*
+ options[0] Board base address
+ options[1] IRQ
+ options[2] first option for module 1
+ options[3] second option for module 1
+ options[4] first option for module 2
+ options[5] second option for module 2
+ options[6] first option for module 3
+ options[7] second option for module 3
+
+ options for PCI-20341M:
+ first Analog input gain configuration
+ 0 == 1
+ 1 == 10
+ 2 == 100
+ 3 == 200
+
+ options for PCI-20006M:
+ first Analog output channel 0 range configuration
+ 0 == bipolar 10 (-10V -- +10V)
+ 1 == unipolar 10V (0V -- +10V)
+ 2 == bipolar 5V (-5V -- +5V)
+ second Analog output channel 1 range configuration
+ 0 == bipolar 10 (-10V -- +10V)
+ 1 == unipolar 10V (0V -- +10V)
+ 2 == bipolar 5V (-5V -- +5V)
+*/
+static int pci20xxx_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned char i;
+ int ret;
+ int id;
+ struct comedi_subdevice *s;
+ union pci20xxx_subdev_private *sdp;
+
+ if ((ret = alloc_subdevices(dev, 1 + PCI20000_MODULES)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct pci20xxx_private))) < 0)
+ return ret;
+
+ devpriv->ioaddr = (void *)(unsigned long)it->options[0];
+ dev->board_name = "pci20kc";
+
+ /* Check PCI-20001 C-2A Carrier Board ID */
+ if ((readb(devpriv->ioaddr) & PCI20000_ID) != PCI20000_ID) {
+ printk("comedi%d: ii_pci20kc", dev->minor);
+ printk(" PCI-20001 C-2A Carrier Board at base=0x%p not found !\n", devpriv->ioaddr);
+ return -EINVAL;
+ }
+ printk("comedi%d:\n", dev->minor);
+ printk("ii_pci20kc: PCI-20001 C-2A at base=0x%p\n", devpriv->ioaddr);
+
+ for (i = 0; i < PCI20000_MODULES; i++) {
+ s = dev->subdevices + i;
+ id = readb(devpriv->ioaddr + (i + 1) * PCI20000_OFFSET);
+ s->private = devpriv->subdev_private + i;
+ sdp = s->private;
+ switch (id) {
+ case PCI20006_ID:
+ sdp->pci20006.iobase =
+ devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
+ pci20006_init(dev, s, it->options[2 * i + 2],
+ it->options[2 * i + 3]);
+ printk("comedi%d: ii_pci20kc", dev->minor);
+ printk(" PCI-20006 module in slot %d \n", i + 1);
+ break;
+ case PCI20341_ID:
+ sdp->pci20341.iobase =
+ devpriv->ioaddr + (i + 1) * PCI20000_OFFSET;
+ pci20341_init(dev, s, it->options[2 * i + 2],
+ it->options[2 * i + 3]);
+ printk("comedi%d: ii_pci20kc", dev->minor);
+ printk(" PCI-20341 module in slot %d \n", i + 1);
+ break;
+ default:
+ printk("ii_pci20kc: unknown module code 0x%02x in slot %d: module disabled\n", id, i);
+ /* fall through */
+ case PCI20xxx_EMPTY_ID:
+ s->type = COMEDI_SUBD_UNUSED;
+ break;
+ }
+ }
+
+ /* initialize struct pci20xxx_private */
+ pci20xxx_dio_init(dev, dev->subdevices + PCI20000_MODULES);
+
+ return 1;
+}
+
+static int pci20xxx_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pci20xxx: remove\n", dev->minor);
+
+ return 0;
+}
+
+/* pci20006m */
+
+static int pci20006_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci20006_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static const struct comedi_lrange *pci20006_range_list[] = {
+ &range_bipolar10,
+ &range_unipolar10,
+ &range_bipolar5,
+};
+
+static int pci20006_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+
+ if (opt0 < 0 || opt0 > 2)
+ opt0 = 0;
+ if (opt1 < 0 || opt1 > 2)
+ opt1 = 0;
+
+ sdp->pci20006.ao_range_list[0] = pci20006_range_list[opt0];
+ sdp->pci20006.ao_range_list[1] = pci20006_range_list[opt1];
+
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->len_chanlist = 2;
+ s->insn_read = pci20006_insn_read;
+ s->insn_write = pci20006_insn_write;
+ s->maxdata = 0xffff;
+ s->range_table_list = sdp->pci20006.ao_range_list;
+ return 0;
+}
+
+static int pci20006_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+
+ data[0] = sdp->pci20006.last_data[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int pci20006_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+ int hi, lo;
+ unsigned int boarddata;
+
+ sdp->pci20006.last_data[CR_CHAN(insn->chanspec)] = data[0];
+ boarddata = (((unsigned int)data[0] + 0x8000) & 0xffff); /* comedi-data -> board-data */
+ lo = (boarddata & 0xff);
+ hi = ((boarddata >> 8) & 0xff);
+
+ switch (CR_CHAN(insn->chanspec)) {
+ case 0:
+ writeb(lo, sdp->iobase + PCI20006_LCHAN0);
+ writeb(hi, sdp->iobase + PCI20006_LCHAN0 + 1);
+ writeb(0x00, sdp->iobase + PCI20006_STROBE0);
+ break;
+ case 1:
+ writeb(lo, sdp->iobase + PCI20006_LCHAN1);
+ writeb(hi, sdp->iobase + PCI20006_LCHAN1 + 1);
+ writeb(0x00, sdp->iobase + PCI20006_STROBE1);
+ break;
+ default:
+ printk(" comedi%d: pci20xxx: ao channel Error!\n", dev->minor);
+ return -EINVAL;
+ }
+
+ return 1;
+}
+
+/* PCI20341M */
+
+static int pci20341_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static const int pci20341_timebase[] = { 0x00, 0x00, 0x00, 0x04 };
+static const int pci20341_settling_time[] = { 0x58, 0x58, 0x93, 0x99 };
+
+static const struct comedi_lrange range_bipolar0_5 = { 1, {BIP_RANGE(0.5)} };
+static const struct comedi_lrange range_bipolar0_05 = { 1, {BIP_RANGE(0.05)} };
+static const struct comedi_lrange range_bipolar0_025 = { 1, {BIP_RANGE(0.025)} };
+
+static const struct comedi_lrange *const pci20341_ranges[] = {
+ &range_bipolar5,
+ &range_bipolar0_5,
+ &range_bipolar0_05,
+ &range_bipolar0_025,
+};
+
+static int pci20341_init(struct comedi_device * dev, struct comedi_subdevice * s,
+ int opt0, int opt1)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+ int option;
+
+ /* options handling */
+ if (opt0 < 0 || opt0 > 3)
+ opt0 = 0;
+ sdp->pci20341.timebase = pci20341_timebase[opt0];
+ sdp->pci20341.settling_time = pci20341_settling_time[opt0];
+
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = PCI20341_CHAN_NR;
+ s->len_chanlist = PCI20341_SCANLIST;
+ s->insn_read = pci20341_insn_read;
+ s->maxdata = 0xffff;
+ s->range_table = pci20341_ranges[opt0];
+
+ option = sdp->pci20341.timebase | PCI20341_REPMODE; /* depends on gain, trigger, repetition mode */
+
+ writeb(PCI20341_INIT, sdp->iobase + PCI20341_CONFIG_REG); /* initialize Module */
+ writeb(PCI20341_PACER, sdp->iobase + PCI20341_MOD_STATUS); /* set Pacer */
+ writeb(option, sdp->iobase + PCI20341_OPT_REG); /* option register */
+ writeb(sdp->pci20341.settling_time, sdp->iobase + PCI20341_SET_TIME_REG); /* settling time counter */
+ /* trigger not implemented */
+ return 0;
+}
+
+static int pci20341_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ union pci20xxx_subdev_private *sdp = s->private;
+ unsigned int i = 0, j = 0;
+ int lo, hi;
+ unsigned char eoc; /* end of conversion */
+ unsigned int clb; /* channel list byte */
+ unsigned int boarddata;
+
+ writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG); /* write number of input channels */
+ clb = PCI20341_DAISY_CHAIN | PCI20341_MUX | (sdp->pci20341.ai_gain << 3)
+ | CR_CHAN(insn->chanspec);
+ writeb(clb, sdp->iobase + PCI20341_CHAN_LIST);
+ writeb(0x00, sdp->iobase + PCI20341_CC_RESET); /* reset settling time counter and trigger delay counter */
+ writeb(0x00, sdp->iobase + PCI20341_CHAN_RESET);
+
+ /* generate Pacer */
+
+ for (i = 0; i < insn->n; i++) {
+ /* data polling isn't the niciest way to get the data, I know,
+ * but there are only 6 cycles (mean) and it is easier than
+ * the whole interrupt stuff
+ */
+ j = 0;
+ readb(sdp->iobase + PCI20341_SOFT_PACER); /* generate Pacer */
+ eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
+ while ((eoc < 0x80) && j < 100) { /* poll Interrupt Flag */
+ j++;
+ eoc = readb(sdp->iobase + PCI20341_STATUS_REG);
+ }
+ if (j >= 100) {
+ printk("comedi%d: pci20xxx: AI interrupt channel %i polling exit !\n", dev->minor, i);
+ return -EINVAL;
+ }
+ lo = readb(sdp->iobase + PCI20341_LDATA);
+ hi = readb(sdp->iobase + PCI20341_LDATA + 1);
+ boarddata = lo + 0x100 * hi;
+ data[i] = (short) ((boarddata + 0x8000) & 0xffff); /* board-data -> comedi-data */
+ }
+
+ return i;
+}
+
+/* native DIO */
+
+static void pci20xxx_dio_config(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pci20xxx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pci20xxx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/* initialize struct pci20xxx_private */
+static int pci20xxx_dio_init(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 32;
+ s->insn_bits = pci20xxx_dio_insn_bits;
+ s->insn_config = pci20xxx_dio_insn_config;
+ s->maxdata = 1;
+ s->len_chanlist = 32;
+ s->range_table = &range_digital;
+ s->io_bits = 0;
+
+ /* digital I/O lines default to input on board reset. */
+ pci20xxx_dio_config(dev, s);
+
+ return 0;
+}
+
+static int pci20xxx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int mask, bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x000000ff) {
+ bits = 0x000000ff;
+ } else if (mask & 0x0000ff00) {
+ bits = 0x0000ff00;
+ } else if (mask & 0x00ff0000) {
+ bits = 0x00ff0000;
+ } else {
+ bits = 0xff000000;
+ }
+ if (data[0]) {
+ s->io_bits |= bits;
+ } else {
+ s->io_bits &= ~bits;
+ }
+ pci20xxx_dio_config(dev, s);
+
+ return 1;
+}
+
+static int pci20xxx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask = data[0];
+
+ s->state &= ~mask;
+ s->state |= (mask & data[1]);
+
+ mask &= s->io_bits;
+ if (mask & 0x000000ff)
+ writeb((s->state >> 0) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_0);
+ if (mask & 0x0000ff00)
+ writeb((s->state >> 8) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_1);
+ if (mask & 0x00ff0000)
+ writeb((s->state >> 16) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_2);
+ if (mask & 0xff000000)
+ writeb((s->state >> 24) & 0xff,
+ devpriv->ioaddr + PCI20000_DIO_3);
+
+ data[1] = readb(devpriv->ioaddr + PCI20000_DIO_0);
+ data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
+ data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16;
+ data[1] |= readb(devpriv->ioaddr + PCI20000_DIO_3) << 24;
+
+ return 2;
+}
+
+static void pci20xxx_dio_config(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned char control_01;
+ unsigned char control_23;
+ unsigned char buffer;
+
+ control_01 = readb(devpriv->ioaddr + PCI20000_DIO_CONTROL_01);
+ control_23 = readb(devpriv->ioaddr + PCI20000_DIO_CONTROL_23);
+ buffer = readb(devpriv->ioaddr + PCI20000_DIO_BUFFER);
+
+ if (s->io_bits & 0x000000ff) {
+ /* output port 0 */
+ control_01 &= PCI20000_DIO_EOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_0))) | (DIO_BO <<
+ DIO_PS_0);
+ } else {
+ /* input port 0 */
+ control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_EIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_0)));
+ }
+ if (s->io_bits & 0x0000ff00) {
+ /* output port 1 */
+ control_01 &= PCI20000_DIO_OOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_1))) | (DIO_BO <<
+ DIO_PS_1);
+ } else {
+ /* input port 1 */
+ control_01 = (control_01 & DIO_CAND) | PCI20000_DIO_OIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_1)));
+ }
+ if (s->io_bits & 0x00ff0000) {
+ /* output port 2 */
+ control_23 &= PCI20000_DIO_EOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_2))) | (DIO_BO <<
+ DIO_PS_2);
+ } else {
+ /* input port 2 */
+ control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_EIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_2)));
+ }
+ if (s->io_bits & 0xff000000) {
+ /* output port 3 */
+ control_23 &= PCI20000_DIO_OOC;
+ buffer = (buffer & (~(DIO_BE << DIO_PS_3))) | (DIO_BO <<
+ DIO_PS_3);
+ } else {
+ /* input port 3 */
+ control_23 = (control_23 & DIO_CAND) | PCI20000_DIO_OIC;
+ buffer = (buffer & (~(DIO_BI << DIO_PS_3)));
+ }
+ writeb(control_01, devpriv->ioaddr + PCI20000_DIO_CONTROL_01);
+ writeb(control_23, devpriv->ioaddr + PCI20000_DIO_CONTROL_23);
+ writeb(buffer, devpriv->ioaddr + PCI20000_DIO_BUFFER);
+}
+
+#if 0
+static void pci20xxx_do(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* XXX if the channel is configured for input, does this
+ do bad things? */
+ /* XXX it would be a good idea to only update the registers
+ that _need_ to be updated. This requires changes to
+ comedi, however. */
+ writeb((s->state >> 0) & 0xff, devpriv->ioaddr + PCI20000_DIO_0);
+ writeb((s->state >> 8) & 0xff, devpriv->ioaddr + PCI20000_DIO_1);
+ writeb((s->state >> 16) & 0xff, devpriv->ioaddr + PCI20000_DIO_2);
+ writeb((s->state >> 24) & 0xff, devpriv->ioaddr + PCI20000_DIO_3);
+}
+
+static unsigned int pci20xxx_di(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* XXX same note as above */
+ unsigned int bits;
+
+ bits = readb(devpriv->ioaddr + PCI20000_DIO_0);
+ bits |= readb(devpriv->ioaddr + PCI20000_DIO_1) << 8;
+ bits |= readb(devpriv->ioaddr + PCI20000_DIO_2) << 16;
+ bits |= readb(devpriv->ioaddr + PCI20000_DIO_3) << 24;
+
+ return bits;
+}
+#endif
+
+COMEDI_INITCLEANUP(driver_pci20xxx);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c
new file mode 100644
index 00000000000..a3c887f3b2c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/jr3_pci.c
@@ -0,0 +1,976 @@
+/*
+ comedi/drivers/jr3_pci.c
+ hardware driver for JR3/PCI force sensor board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2007 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: jr3_pci
+Description: JR3/PCI force sensor board
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Devices: [JR3] PCI force sensor board (jr3_pci)
+
+ The DSP on the board requires initialization code, which can
+ be loaded by placing it in /lib/firmware/comedi.
+ The initialization code should be somewhere on the media you got
+ with your card. One version is available from http://www.comedi.org
+ in the comedi_nonfree_firmware tarball.
+
+ Configuration options:
+ [0] - PCI bus number - if bus number and slot number are 0,
+ then driver search for first unused card
+ [1] - PCI slot number
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ctype.h>
+#include <linux/firmware.h>
+#include "comedi_pci.h"
+#include "jr3_pci.h"
+
+/* Hotplug firmware loading stuff */
+
+static void comedi_fw_release(struct device *dev)
+{
+ printk(KERN_DEBUG "firmware_sample_driver: ghost_release\n");
+}
+
+static struct device comedi_fw_device = {
+ .init_name = "comedi",
+ .release = comedi_fw_release
+};
+
+typedef int comedi_firmware_callback(struct comedi_device * dev,
+ const u8 * data, size_t size);
+
+static int comedi_load_firmware(struct comedi_device * dev,
+ char *name, comedi_firmware_callback cb)
+{
+ int result = 0;
+ const struct firmware *fw;
+ char *firmware_path;
+ static const char *prefix = "comedi/";
+
+ firmware_path = kmalloc(strlen(prefix) + strlen(name) + 1, GFP_KERNEL);
+ if (!firmware_path) {
+ result = -ENOMEM;
+ } else {
+ firmware_path[0] = '\0';
+ strcat(firmware_path, prefix);
+ strcat(firmware_path, name);
+ result = device_register(&comedi_fw_device);
+ if (result == 0) {
+ result = request_firmware(&fw, firmware_path,
+ &comedi_fw_device);
+ if (result == 0) {
+ if (!cb) {
+ result = -EINVAL;
+ } else {
+ result = cb(dev, fw->data, fw->size);
+ }
+ release_firmware(fw);
+ }
+ device_unregister(&comedi_fw_device);
+ }
+ kfree(firmware_path);
+ }
+ return result;
+}
+
+#define PCI_VENDOR_ID_JR3 0x1762
+#define PCI_DEVICE_ID_JR3_1_CHANNEL 0x3111
+#define PCI_DEVICE_ID_JR3_2_CHANNEL 0x3112
+#define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113
+#define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114
+
+static int jr3_pci_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int jr3_pci_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_jr3_pci = {
+ driver_name:"jr3_pci",
+ module:THIS_MODULE,
+ attach:jr3_pci_attach,
+ detach:jr3_pci_detach,
+};
+
+static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = {
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_4_CHANNEL,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, jr3_pci_pci_table);
+
+struct jr3_pci_dev_private {
+
+ struct pci_dev *pci_dev;
+ int pci_enabled;
+ volatile struct jr3_t *iobase;
+ int n_channels;
+ struct timer_list timer;
+};
+
+
+struct poll_delay_t {
+
+ int min;
+ int max;
+};
+
+
+struct jr3_pci_subdev_private {
+ volatile struct jr3_channel *channel;
+ unsigned long next_time_min;
+ unsigned long next_time_max;
+ enum { state_jr3_poll,
+ state_jr3_init_wait_for_offset,
+ state_jr3_init_transform_complete,
+ state_jr3_init_set_full_scale_complete,
+ state_jr3_init_use_offset_complete,
+ state_jr3_done
+ } state;
+ int channel_no;
+ int serial_no;
+ int model_no;
+ struct {
+ int length;
+ struct comedi_krange range;
+ } range[9];
+ const struct comedi_lrange *range_table_list[8 * 7 + 2];
+ unsigned int maxdata_list[8 * 7 + 2];
+ u16 errors;
+ int retries;
+};
+
+static struct poll_delay_t poll_delay_min_max(int min, int max)
+{
+ struct poll_delay_t result;
+
+ result.min = min;
+ result.max = max;
+ return result;
+}
+
+static int is_complete(volatile struct jr3_channel *channel)
+{
+ return get_s16(&channel->command_word0) == 0;
+}
+
+struct transform_t {
+ struct {
+ u16 link_type;
+ s16 link_amount;
+ } link[8];
+};
+
+static void set_transforms(volatile struct jr3_channel *channel,
+ struct transform_t transf, short num)
+{
+ int i;
+
+ num &= 0x000f; // Make sure that 0 <= num <= 15
+ for (i = 0; i < 8; i++) {
+
+ set_u16(&channel->transforms[num].link[i].link_type,
+ transf.link[i].link_type);
+ comedi_udelay(1);
+ set_s16(&channel->transforms[num].link[i].link_amount,
+ transf.link[i].link_amount);
+ comedi_udelay(1);
+ if (transf.link[i].link_type == end_x_form) {
+ break;
+ }
+ }
+}
+
+static void use_transform(volatile struct jr3_channel *channel, short transf_num)
+{
+ set_s16(&channel->command_word0, 0x0500 + (transf_num & 0x000f));
+}
+
+static void use_offset(volatile struct jr3_channel *channel, short offset_num)
+{
+ set_s16(&channel->command_word0, 0x0600 + (offset_num & 0x000f));
+}
+
+static void set_offset(volatile struct jr3_channel *channel)
+{
+ set_s16(&channel->command_word0, 0x0700);
+}
+
+struct six_axis_t {
+ s16 fx;
+ s16 fy;
+ s16 fz;
+ s16 mx;
+ s16 my;
+ s16 mz;
+};
+
+static void set_full_scales(volatile struct jr3_channel *channel,
+ struct six_axis_t full_scale)
+{
+ printk("%d %d %d %d %d %d\n",
+ full_scale.fx,
+ full_scale.fy,
+ full_scale.fz, full_scale.mx, full_scale.my, full_scale.mz);
+ set_s16(&channel->full_scale.fx, full_scale.fx);
+ set_s16(&channel->full_scale.fy, full_scale.fy);
+ set_s16(&channel->full_scale.fz, full_scale.fz);
+ set_s16(&channel->full_scale.mx, full_scale.mx);
+ set_s16(&channel->full_scale.my, full_scale.my);
+ set_s16(&channel->full_scale.mz, full_scale.mz);
+ set_s16(&channel->command_word0, 0x0a00);
+}
+
+static struct six_axis_t get_min_full_scales(volatile struct jr3_channel *channel)
+{
+ struct six_axis_t result;
+ result.fx = get_s16(&channel->min_full_scale.fx);
+ result.fy = get_s16(&channel->min_full_scale.fy);
+ result.fz = get_s16(&channel->min_full_scale.fz);
+ result.mx = get_s16(&channel->min_full_scale.mx);
+ result.my = get_s16(&channel->min_full_scale.my);
+ result.mz = get_s16(&channel->min_full_scale.mz);
+ return result;
+}
+
+static struct six_axis_t get_max_full_scales(volatile struct jr3_channel *channel)
+{
+ struct six_axis_t result;
+ result.fx = get_s16(&channel->max_full_scale.fx);
+ result.fy = get_s16(&channel->max_full_scale.fy);
+ result.fz = get_s16(&channel->max_full_scale.fz);
+ result.mx = get_s16(&channel->max_full_scale.mx);
+ result.my = get_s16(&channel->max_full_scale.my);
+ result.mz = get_s16(&channel->max_full_scale.mz);
+ return result;
+}
+
+static int jr3_pci_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int result;
+ struct jr3_pci_subdev_private *p;
+ int channel;
+
+ p = s->private;
+ channel = CR_CHAN(insn->chanspec);
+ if (p == NULL || channel > 57) {
+ result = -EINVAL;
+ } else {
+ int i;
+
+ result = insn->n;
+ if (p->state != state_jr3_done ||
+ (get_u16(&p->channel->
+ errors) & (watch_dog | watch_dog2 |
+ sensor_change))) {
+ /* No sensor or sensor changed */
+ if (p->state == state_jr3_done) {
+ /* Restart polling */
+ p->state = state_jr3_poll;
+ }
+ result = -EAGAIN;
+ }
+ for (i = 0; i < insn->n; i++) {
+ if (channel < 56) {
+ int axis, filter;
+
+ axis = channel % 8;
+ filter = channel / 8;
+ if (p->state != state_jr3_done) {
+ data[i] = 0;
+ } else {
+ int F = 0;
+ switch (axis) {
+ case 0:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ fx);
+ }
+ break;
+ case 1:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ fy);
+ }
+ break;
+ case 2:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ fz);
+ }
+ break;
+ case 3:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ mx);
+ }
+ break;
+ case 4:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ my);
+ }
+ break;
+ case 5:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ mz);
+ }
+ break;
+ case 6:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ v1);
+ }
+ break;
+ case 7:{
+ F = get_s16(&p->
+ channel->
+ filter[filter].
+ v2);
+ }
+ break;
+ }
+ data[i] = F + 0x4000;
+ }
+ } else if (channel == 56) {
+ if (p->state != state_jr3_done) {
+ data[i] = 0;
+ } else {
+ data[i] =
+ get_u16(&p->channel->model_no);
+ }
+ } else if (channel == 57) {
+ if (p->state != state_jr3_done) {
+ data[i] = 0;
+ } else {
+ data[i] =
+ get_u16(&p->channel->serial_no);
+ }
+ }
+ }
+ }
+ return result;
+}
+
+static void jr3_pci_open(struct comedi_device * dev)
+{
+ int i;
+ struct jr3_pci_dev_private *devpriv = dev->private;
+
+ printk("jr3_pci_open\n");
+ for (i = 0; i < devpriv->n_channels; i++) {
+ struct jr3_pci_subdev_private *p;
+
+ p = dev->subdevices[i].private;
+ if (p) {
+ printk("serial: %p %d (%d)\n", p, p->serial_no,
+ p->channel_no);
+ }
+ }
+}
+
+int read_idm_word(const u8 * data, size_t size, int *pos, unsigned int *val)
+{
+ int result = 0;
+ if (pos != 0 && val != 0) {
+ // Skip over non hex
+ for (; *pos < size && !isxdigit(data[*pos]); (*pos)++) {
+ }
+ // Collect value
+ *val = 0;
+ for (; *pos < size && isxdigit(data[*pos]); (*pos)++) {
+ char ch = tolower(data[*pos]);
+ result = 1;
+ if ('0' <= ch && ch <= '9') {
+ *val = (*val << 4) + (ch - '0');
+ } else if ('a' <= ch && ch <= 'f') {
+ *val = (*val << 4) + (ch - 'a' + 10);
+ }
+ }
+ }
+ return result;
+}
+
+static int jr3_download_firmware(struct comedi_device * dev, const u8 * data,
+ size_t size)
+{
+ /*
+ * IDM file format is:
+ * { count, address, data <count> } *
+ * ffff
+ */
+ int result, more, pos, OK;
+
+ result = 0;
+ more = 1;
+ pos = 0;
+ OK = 0;
+ while (more) {
+ unsigned int count, addr;
+
+ more = more && read_idm_word(data, size, &pos, &count);
+ if (more && count == 0xffff) {
+ OK = 1;
+ break;
+ }
+ more = more && read_idm_word(data, size, &pos, &addr);
+ while (more && count > 0) {
+ unsigned int dummy;
+ more = more && read_idm_word(data, size, &pos, &dummy);
+ count--;
+ }
+ }
+
+ if (!OK) {
+ result = -ENODATA;
+ } else {
+ int i;
+ struct jr3_pci_dev_private *p = dev->private;
+
+ for (i = 0; i < p->n_channels; i++) {
+ struct jr3_pci_subdev_private *sp;
+
+ sp = dev->subdevices[i].private;
+ more = 1;
+ pos = 0;
+ while (more) {
+ unsigned int count, addr;
+ more = more
+ && read_idm_word(data, size, &pos,
+ &count);
+ if (more && count == 0xffff) {
+ break;
+ }
+ more = more
+ && read_idm_word(data, size, &pos,
+ &addr);
+ printk("Loading#%d %4.4x bytes at %4.4x\n", i,
+ count, addr);
+ while (more && count > 0) {
+ if (addr & 0x4000) {
+ // 16 bit data, never seen in real life!!
+ unsigned int data1;
+
+ more = more
+ && read_idm_word(data,
+ size, &pos, &data1);
+ count--;
+ // printk("jr3_data, not tested\n");
+ // jr3[addr + 0x20000 * pnum] = data1;
+ } else {
+ // Download 24 bit program
+ unsigned int data1, data2;
+
+ more = more
+ && read_idm_word(data,
+ size, &pos, &data1);
+ more = more
+ && read_idm_word(data,
+ size, &pos, &data2);
+ count -= 2;
+ if (more) {
+ set_u16(&p->iobase->
+ channel[i].
+ program_low
+ [addr], data1);
+ comedi_udelay(1);
+ set_u16(&p->iobase->
+ channel[i].
+ program_high
+ [addr], data2);
+ comedi_udelay(1);
+
+ }
+ }
+ addr++;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+static struct poll_delay_t jr3_pci_poll_subdevice(struct comedi_subdevice * s)
+{
+ struct poll_delay_t result = poll_delay_min_max(1000, 2000);
+ struct jr3_pci_subdev_private *p = s->private;
+
+ if (p) {
+ volatile struct jr3_channel *channel = p->channel;
+ int errors = get_u16(&channel->errors);
+
+ if (errors != p->errors) {
+ printk("Errors: %x -> %x\n", p->errors, errors);
+ p->errors = errors;
+ }
+ if (errors & (watch_dog | watch_dog2 | sensor_change)) {
+ // Sensor communication lost, force poll mode
+ p->state = state_jr3_poll;
+
+ }
+ switch (p->state) {
+ case state_jr3_poll:{
+ u16 model_no = get_u16(&channel->model_no);
+ u16 serial_no = get_u16(&channel->serial_no);
+ if ((errors & (watch_dog | watch_dog2)) ||
+ model_no == 0 || serial_no == 0) {
+ // Still no sensor, keep on polling. Since it takes up to
+ // 10 seconds for offsets to stabilize, polling each
+ // second should suffice.
+ result = poll_delay_min_max(1000, 2000);
+ } else {
+ p->retries = 0;
+ p->state =
+ state_jr3_init_wait_for_offset;
+ result = poll_delay_min_max(1000, 2000);
+ }
+ }
+ break;
+ case state_jr3_init_wait_for_offset:{
+ p->retries++;
+ if (p->retries < 10) {
+ // Wait for offeset to stabilize (< 10 s according to manual)
+ result = poll_delay_min_max(1000, 2000);
+ } else {
+ struct transform_t transf;
+
+ p->model_no =
+ get_u16(&channel->model_no);
+ p->serial_no =
+ get_u16(&channel->serial_no);
+
+ printk("Setting transform for channel %d\n", p->channel_no);
+ printk("Sensor Model = %i\n",
+ p->model_no);
+ printk("Sensor Serial = %i\n",
+ p->serial_no);
+
+ // Transformation all zeros
+ transf.link[0].link_type =
+ (enum link_types)0;
+ transf.link[0].link_amount = 0;
+ transf.link[1].link_type =
+ (enum link_types)0;
+ transf.link[1].link_amount = 0;
+ transf.link[2].link_type =
+ (enum link_types)0;
+ transf.link[2].link_amount = 0;
+ transf.link[3].link_type =
+ (enum link_types)0;
+ transf.link[3].link_amount = 0;
+
+ set_transforms(channel, transf, 0);
+ use_transform(channel, 0);
+ p->state =
+ state_jr3_init_transform_complete;
+ result = poll_delay_min_max(20, 100); // Allow 20 ms for completion
+ }
+ } break;
+ case state_jr3_init_transform_complete:{
+ if (!is_complete(channel)) {
+ printk("state_jr3_init_transform_complete complete = %d\n", is_complete(channel));
+ result = poll_delay_min_max(20, 100);
+ } else {
+ // Set full scale
+ struct six_axis_t min_full_scale;
+ struct six_axis_t max_full_scale;
+
+ min_full_scale =
+ get_min_full_scales(channel);
+ printk("Obtained Min. Full Scales:\n");
+ printk("%i ", (min_full_scale).fx);
+ printk("%i ", (min_full_scale).fy);
+ printk("%i ", (min_full_scale).fz);
+ printk("%i ", (min_full_scale).mx);
+ printk("%i ", (min_full_scale).my);
+ printk("%i ", (min_full_scale).mz);
+ printk("\n");
+
+ max_full_scale =
+ get_max_full_scales(channel);
+ printk("Obtained Max. Full Scales:\n");
+ printk("%i ", (max_full_scale).fx);
+ printk("%i ", (max_full_scale).fy);
+ printk("%i ", (max_full_scale).fz);
+ printk("%i ", (max_full_scale).mx);
+ printk("%i ", (max_full_scale).my);
+ printk("%i ", (max_full_scale).mz);
+ printk("\n");
+
+ set_full_scales(channel,
+ max_full_scale);
+
+ p->state =
+ state_jr3_init_set_full_scale_complete;
+ result = poll_delay_min_max(20, 100); // Allow 20 ms for completion
+ }
+ }
+ break;
+ case state_jr3_init_set_full_scale_complete:{
+ if (!is_complete(channel)) {
+ printk("state_jr3_init_set_full_scale_complete complete = %d\n", is_complete(channel));
+ result = poll_delay_min_max(20, 100);
+ } else {
+ volatile struct force_array *full_scale;
+
+ // Use ranges in kN or we will overflow arount 2000N!
+ full_scale = &channel->full_scale;
+ p->range[0].range.min =
+ -get_s16(&full_scale->fx) *
+ 1000;
+ p->range[0].range.max =
+ get_s16(&full_scale->fx) * 1000;
+ p->range[1].range.min =
+ -get_s16(&full_scale->fy) *
+ 1000;
+ p->range[1].range.max =
+ get_s16(&full_scale->fy) * 1000;
+ p->range[2].range.min =
+ -get_s16(&full_scale->fz) *
+ 1000;
+ p->range[2].range.max =
+ get_s16(&full_scale->fz) * 1000;
+ p->range[3].range.min =
+ -get_s16(&full_scale->mx) * 100;
+ p->range[3].range.max =
+ get_s16(&full_scale->mx) * 100;
+ p->range[4].range.min =
+ -get_s16(&full_scale->my) * 100;
+ p->range[4].range.max =
+ get_s16(&full_scale->my) * 100;
+ p->range[5].range.min =
+ -get_s16(&full_scale->mz) * 100;
+ p->range[5].range.max =
+ get_s16(&full_scale->mz) * 100;
+ p->range[6].range.min = -get_s16(&full_scale->v1) * 100; // ??
+ p->range[6].range.max = get_s16(&full_scale->v1) * 100; // ??
+ p->range[7].range.min = -get_s16(&full_scale->v2) * 100; // ??
+ p->range[7].range.max = get_s16(&full_scale->v2) * 100; // ??
+ p->range[8].range.min = 0;
+ p->range[8].range.max = 65535;
+
+ {
+ int i;
+ for (i = 0; i < 9; i++) {
+ printk("%d %d - %d\n",
+ i,
+ p->range[i].
+ range.min,
+ p->range[i].
+ range.max);
+ }
+ }
+
+ use_offset(channel, 0);
+ p->state =
+ state_jr3_init_use_offset_complete;
+ result = poll_delay_min_max(40, 100); // Allow 40 ms for completion
+ }
+ }
+ break;
+ case state_jr3_init_use_offset_complete:{
+ if (!is_complete(channel)) {
+ printk("state_jr3_init_use_offset_complete complete = %d\n", is_complete(channel));
+ result = poll_delay_min_max(20, 100);
+ } else {
+ printk("Default offsets %d %d %d %d %d %d\n", get_s16(&channel->offsets.fx), get_s16(&channel->offsets.fy), get_s16(&channel->offsets.fz), get_s16(&channel->offsets.mx), get_s16(&channel->offsets.my), get_s16(&channel->offsets.mz));
+
+ set_s16(&channel->offsets.fx, 0);
+ set_s16(&channel->offsets.fy, 0);
+ set_s16(&channel->offsets.fz, 0);
+ set_s16(&channel->offsets.mx, 0);
+ set_s16(&channel->offsets.my, 0);
+ set_s16(&channel->offsets.mz, 0);
+
+ set_offset(channel);
+
+ p->state = state_jr3_done;
+ }
+ }
+ break;
+ case state_jr3_done:{
+ poll_delay_min_max(10000, 20000);
+ }
+ break;
+ default:{
+ poll_delay_min_max(1000, 2000);
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+static void jr3_pci_poll_dev(unsigned long data)
+{
+ unsigned long flags;
+ struct comedi_device *dev = (struct comedi_device *) data;
+ struct jr3_pci_dev_private *devpriv = dev->private;
+ unsigned long now;
+ int delay;
+ int i;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ delay = 1000;
+ now = jiffies;
+ // Poll all channels that are ready to be polled
+ for (i = 0; i < devpriv->n_channels; i++) {
+ struct jr3_pci_subdev_private *subdevpriv = dev->subdevices[i].private;
+ if (now > subdevpriv->next_time_min) {
+ struct poll_delay_t sub_delay;
+
+ sub_delay = jr3_pci_poll_subdevice(&dev->subdevices[i]);
+ subdevpriv->next_time_min =
+ jiffies + msecs_to_jiffies(sub_delay.min);
+ subdevpriv->next_time_max =
+ jiffies + msecs_to_jiffies(sub_delay.max);
+ if (sub_delay.max && sub_delay.max < delay) {
+ // Wake up as late as possible -> poll as many channels as
+ // possible at once
+ delay = sub_delay.max;
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ devpriv->timer.expires = jiffies + msecs_to_jiffies(delay);
+ add_timer(&devpriv->timer);
+}
+
+static int jr3_pci_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ struct pci_dev *card = NULL;
+ int opt_bus, opt_slot, i;
+ struct jr3_pci_dev_private *devpriv;
+
+ printk("comedi%d: jr3_pci\n", dev->minor);
+
+ opt_bus = it->options[0];
+ opt_slot = it->options[1];
+
+ if (sizeof(struct jr3_channel) != 0xc00) {
+ printk("sizeof(struct jr3_channel) = %x [expected %x]\n",
+ (unsigned)sizeof(struct jr3_channel), 0xc00);
+ return -EINVAL;
+ }
+
+ result = alloc_private(dev, sizeof(struct jr3_pci_dev_private));
+ if (result < 0) {
+ return -ENOMEM;
+ }
+ card = NULL;
+ devpriv = dev->private;
+ init_timer(&devpriv->timer);
+ while (1) {
+ card = pci_get_device(PCI_VENDOR_ID_JR3, PCI_ANY_ID, card);
+ if (card == NULL) {
+ /* No card found */
+ break;
+ } else {
+ switch (card->device) {
+ case PCI_DEVICE_ID_JR3_1_CHANNEL:{
+ devpriv->n_channels = 1;
+ }
+ break;
+ case PCI_DEVICE_ID_JR3_2_CHANNEL:{
+ devpriv->n_channels = 2;
+ }
+ break;
+ case PCI_DEVICE_ID_JR3_3_CHANNEL:{
+ devpriv->n_channels = 3;
+ }
+ break;
+ case PCI_DEVICE_ID_JR3_4_CHANNEL:{
+ devpriv->n_channels = 4;
+ }
+ break;
+ default:{
+ devpriv->n_channels = 0;
+ }
+ }
+ if (devpriv->n_channels >= 1) {
+ if (opt_bus == 0 && opt_slot == 0) {
+ /* Take first available card */
+ break;
+ } else if (opt_bus == card->bus->number &&
+ opt_slot == PCI_SLOT(card->devfn)) {
+ /* Take requested card */
+ break;
+ }
+ }
+ }
+ }
+ if (!card) {
+ printk(" no jr3_pci found\n");
+ return -EIO;
+ } else {
+ devpriv->pci_dev = card;
+ dev->board_name = "jr3_pci";
+ }
+ if ((result = comedi_pci_enable(card, "jr3_pci")) < 0) {
+ return -EIO;
+ }
+ devpriv->pci_enabled = 1;
+ devpriv->iobase = ioremap(pci_resource_start(card, 0), sizeof(struct jr3_t));
+ result = alloc_subdevices(dev, devpriv->n_channels);
+ if (result < 0)
+ goto out;
+
+ dev->open = jr3_pci_open;
+ for (i = 0; i < devpriv->n_channels; i++) {
+ dev->subdevices[i].type = COMEDI_SUBD_AI;
+ dev->subdevices[i].subdev_flags = SDF_READABLE | SDF_GROUND;
+ dev->subdevices[i].n_chan = 8 * 7 + 2;
+ dev->subdevices[i].insn_read = jr3_pci_ai_insn_read;
+ dev->subdevices[i].private =
+ kzalloc(sizeof(struct jr3_pci_subdev_private), GFP_KERNEL);
+ if (dev->subdevices[i].private) {
+ struct jr3_pci_subdev_private *p;
+ int j;
+
+ p = dev->subdevices[i].private;
+ p->channel = &devpriv->iobase->channel[i].data;
+ printk("p->channel %p %p (%tx)\n",
+ p->channel, devpriv->iobase,
+ ((char *)(p->channel) -
+ (char *)(devpriv->iobase)));
+ p->channel_no = i;
+ for (j = 0; j < 8; j++) {
+ int k;
+
+ p->range[j].length = 1;
+ p->range[j].range.min = -1000000;
+ p->range[j].range.max = 1000000;
+ for (k = 0; k < 7; k++) {
+ p->range_table_list[j + k * 8] =
+ (struct comedi_lrange *) & p->range[j];
+ p->maxdata_list[j + k * 8] = 0x7fff;
+ }
+ }
+ p->range[8].length = 1;
+ p->range[8].range.min = 0;
+ p->range[8].range.max = 65536;
+
+ p->range_table_list[56] =
+ (struct comedi_lrange *) & p->range[8];
+ p->range_table_list[57] =
+ (struct comedi_lrange *) & p->range[8];
+ p->maxdata_list[56] = 0xffff;
+ p->maxdata_list[57] = 0xffff;
+ // Channel specific range and maxdata
+ dev->subdevices[i].range_table = 0;
+ dev->subdevices[i].range_table_list =
+ p->range_table_list;
+ dev->subdevices[i].maxdata = 0;
+ dev->subdevices[i].maxdata_list = p->maxdata_list;
+ }
+ }
+
+ // Reset DSP card
+ devpriv->iobase->channel[0].reset = 0;
+
+ result = comedi_load_firmware(dev, "jr3pci.idm", jr3_download_firmware);
+ printk("Firmare load %d\n", result);
+
+ if (result < 0) {
+ goto out;
+ }
+ // TODO: use firmware to load preferred offset tables. Suggested format:
+ // model serial Fx Fy Fz Mx My Mz\n
+ //
+ // comedi_load_firmware(dev, "jr3_offsets_table", jr3_download_firmware);
+
+ // It takes a few milliseconds for software to settle
+ // as much as we can read firmware version
+ msleep_interruptible(25);
+ for (i = 0; i < 0x18; i++) {
+ printk("%c",
+ get_u16(&devpriv->iobase->channel[0].data.
+ copyright[i]) >> 8);
+ }
+
+ // Start card timer
+ for (i = 0; i < devpriv->n_channels; i++) {
+ struct jr3_pci_subdev_private *p = dev->subdevices[i].private;
+
+ p->next_time_min = jiffies + msecs_to_jiffies(500);
+ p->next_time_max = jiffies + msecs_to_jiffies(2000);
+ }
+
+ devpriv->timer.data = (unsigned long)dev;
+ devpriv->timer.function = jr3_pci_poll_dev;
+ devpriv->timer.expires = jiffies + msecs_to_jiffies(1000);
+ add_timer(&devpriv->timer);
+
+ out:
+ return result;
+}
+
+static int jr3_pci_detach(struct comedi_device * dev)
+{
+ int i;
+ struct jr3_pci_dev_private *devpriv = dev->private;
+
+ printk("comedi%d: jr3_pci: remove\n", dev->minor);
+ if (devpriv) {
+ del_timer_sync(&devpriv->timer);
+
+ if (dev->subdevices) {
+ for (i = 0; i < devpriv->n_channels; i++) {
+ kfree(dev->subdevices[i].private);
+ }
+ }
+
+ if (devpriv->iobase) {
+ iounmap((void *)devpriv->iobase);
+ }
+ if (devpriv->pci_enabled) {
+ comedi_pci_disable(devpriv->pci_dev);
+ }
+
+ if (devpriv->pci_dev) {
+ pci_dev_put(devpriv->pci_dev);
+ }
+ }
+ return 0;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_jr3_pci, jr3_pci_pci_table);
diff --git a/drivers/staging/comedi/drivers/jr3_pci.h b/drivers/staging/comedi/drivers/jr3_pci.h
new file mode 100644
index 00000000000..3585f2941bc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/jr3_pci.h
@@ -0,0 +1,681 @@
+/* Helper types to take care of the fact that the DSP card memory
+ * is 16 bits, but aligned on a 32 bit PCI boundary
+ */
+
+static inline u16 get_u16(volatile const u32 * p)
+{
+ return (u16) readl(p);
+}
+
+static inline void set_u16(volatile u32 * p, u16 val)
+{
+ writel(val, p);
+}
+
+static inline s16 get_s16(volatile const s32 * p)
+{
+ return (s16) readl(p);
+}
+
+static inline void set_s16(volatile s32 * p, s16 val)
+{
+ writel(val, p);
+}
+
+/* The raw data is stored in a format which facilitates rapid
+ * processing by the JR3 DSP chip. The raw_channel structure shows the
+ * format for a single channel of data. Each channel takes four,
+ * two-byte words.
+ *
+ * Raw_time is an unsigned integer which shows the value of the JR3
+ * DSP's internal clock at the time the sample was received. The clock
+ * runs at 1/10 the JR3 DSP cycle time. JR3's slowest DSP runs at 10
+ * Mhz. At 10 Mhz raw_time would therefore clock at 1 Mhz.
+ *
+ * Raw_data is the raw data received directly from the sensor. The
+ * sensor data stream is capable of representing 16 different
+ * channels. Channel 0 shows the excitation voltage at the sensor. It
+ * is used to regulate the voltage over various cable lengths.
+ * Channels 1-6 contain the coupled force data Fx through Mz. Channel
+ * 7 contains the sensor's calibration data. The use of channels 8-15
+ * varies with different sensors.
+ */
+
+struct raw_channel {
+ u32 raw_time;
+ s32 raw_data;
+ s32 reserved[2];
+};
+
+/* The force_array structure shows the layout for the decoupled and
+ * filtered force data.
+ */
+struct force_array {
+ s32 fx;
+ s32 fy;
+ s32 fz;
+ s32 mx;
+ s32 my;
+ s32 mz;
+ s32 v1;
+ s32 v2;
+};
+
+/* The six_axis_array structure shows the layout for the offsets and
+ * the full scales.
+ */
+struct six_axis_array {
+ s32 fx;
+ s32 fy;
+ s32 fz;
+ s32 mx;
+ s32 my;
+ s32 mz;
+};
+
+/* VECT_BITS */
+/* The vect_bits structure shows the layout for indicating
+ * which axes to use in computing the vectors. Each bit signifies
+ * selection of a single axis. The V1x axis bit corresponds to a hex
+ * value of 0x0001 and the V2z bit corresponds to a hex value of
+ * 0x0020. Example: to specify the axes V1x, V1y, V2x, and V2z the
+ * pattern would be 0x002b. Vector 1 defaults to a force vector and
+ * vector 2 defaults to a moment vector. It is possible to change one
+ * or the other so that two force vectors or two moment vectors are
+ * calculated. Setting the changeV1 bit or the changeV2 bit will
+ * change that vector to be the opposite of its default. Therefore to
+ * have two force vectors, set changeV1 to 1.
+ */
+
+/* vect_bits appears to be unused at this time */
+enum {
+ fx = 0x0001,
+ fy = 0x0002,
+ fz = 0x0004,
+ mx = 0x0008,
+ my = 0x0010,
+ mz = 0x0020,
+ changeV2 = 0x0040,
+ changeV1 = 0x0080
+} vect_bits_t;
+
+/* WARNING_BITS */
+/* The warning_bits structure shows the bit pattern for the warning
+ * word. The bit fields are shown from bit 0 (lsb) to bit 15 (msb).
+ */
+
+/* XX_NEAR_SET */
+/* The xx_near_sat bits signify that the indicated axis has reached or
+ * exceeded the near saturation value.
+ */
+
+enum {
+ fx_near_sat = 0x0001,
+ fy_near_sat = 0x0002,
+ fz_near_sat = 0x0004,
+ mx_near_sat = 0x0008,
+ my_near_sat = 0x0010,
+ mz_near_sat = 0x0020
+} warning_bits_t;
+
+/* ERROR_BITS */
+/* XX_SAT */
+/* MEMORY_ERROR */
+/* SENSOR_CHANGE */
+
+/* The error_bits structure shows the bit pattern for the error word.
+ * The bit fields are shown from bit 0 (lsb) to bit 15 (msb). The
+ * xx_sat bits signify that the indicated axis has reached or exceeded
+ * the saturation value. The memory_error bit indicates that a problem
+ * was detected in the on-board RAM during the power-up
+ * initialization. The sensor_change bit indicates that a sensor other
+ * than the one originally plugged in has passed its CRC check. This
+ * bit latches, and must be reset by the user.
+ *
+ */
+
+/* SYSTEM_BUSY */
+
+/* The system_busy bit indicates that the JR3 DSP is currently busy
+ * and is not calculating force data. This occurs when a new
+ * coordinate transformation, or new sensor full scale is set by the
+ * user. A very fast system using the force data for feedback might
+ * become unstable during the approximately 4 ms needed to accomplish
+ * these calculations. This bit will also become active when a new
+ * sensor is plugged in and the system needs to recalculate the
+ * calibration CRC.
+ */
+
+/* CAL_CRC_BAD */
+
+/* The cal_crc_bad bit indicates that the calibration CRC has not
+ * calculated to zero. CRC is short for cyclic redundancy code. It is
+ * a method for determining the integrity of messages in data
+ * communication. The calibration data stored inside the sensor is
+ * transmitted to the JR3 DSP along with the sensor data. The
+ * calibration data has a CRC attached to the end of it, to assist in
+ * determining the completeness and integrity of the calibration data
+ * received from the sensor. There are two reasons the CRC may not
+ * have calculated to zero. The first is that all the calibration data
+ * has not yet been received, the second is that the calibration data
+ * has been corrupted. A typical sensor transmits the entire contents
+ * of its calibration matrix over 30 times a second. Therefore, if
+ * this bit is not zero within a couple of seconds after the sensor
+ * has been plugged in, there is a problem with the sensor's
+ * calibration data.
+ */
+
+/* WATCH_DOG */
+/* WATCH_DOG2 */
+
+/* The watch_dog and watch_dog2 bits are sensor, not processor, watch
+ * dog bits. Watch_dog indicates that the sensor data line seems to be
+ * acting correctly, while watch_dog2 indicates that sensor data and
+ * clock are being received. It is possible for watch_dog2 to go off
+ * while watch_dog does not. This would indicate an improper clock
+ * signal, while data is acting correctly. If either watch dog barks,
+ * the sensor data is not being received correctly.
+ */
+
+enum error_bits_t {
+ fx_sat = 0x0001,
+ fy_sat = 0x0002,
+ fz_sat = 0x0004,
+ mx_sat = 0x0008,
+ my_sat = 0x0010,
+ mz_sat = 0x0020,
+ memory_error = 0x0400,
+ sensor_change = 0x0800,
+ system_busy = 0x1000,
+ cal_crc_bad = 0x2000,
+ watch_dog2 = 0x4000,
+ watch_dog = 0x8000
+};
+
+/* THRESH_STRUCT */
+
+/* This structure shows the layout for a single threshold packet inside of a
+ * load envelope. Each load envelope can contain several threshold structures.
+ * 1. data_address contains the address of the data for that threshold. This
+ * includes filtered, unfiltered, raw, rate, counters, error and warning data
+ * 2. threshold is the is the value at which, if data is above or below, the
+ * bits will be set ... (pag.24).
+ * 3. bit_pattern contains the bits that will be set if the threshold value is
+ * met or exceeded.
+ */
+
+struct thresh_struct {
+ s32 data_address;
+ s32 threshold;
+ s32 bit_pattern;
+};
+
+/* LE_STRUCT */
+
+/* Layout of a load enveloped packet. Four thresholds are showed ... for more
+ * see manual (pag.25)
+ * 1. latch_bits is a bit pattern that show which bits the user wants to latch.
+ * The latched bits will not be reset once the threshold which set them is
+ * no longer true. In that case the user must reset them using the reset_bit
+ * command.
+ * 2. number_of_xx_thresholds specify how many GE/LE threshold there are.
+ */
+struct le_struct {
+ s32 latch_bits;
+ s32 number_of_ge_thresholds;
+ s32 number_of_le_thresholds;
+ struct thresh_struct thresholds[4];
+ s32 reserved;
+};
+
+/* LINK_TYPES */
+/* Link types is an enumerated value showing the different possible transform
+ * link types.
+ * 0 - end transform packet
+ * 1 - translate along X axis (TX)
+ * 2 - translate along Y axis (TY)
+ * 3 - translate along Z axis (TZ)
+ * 4 - rotate about X axis (RX)
+ * 5 - rotate about Y axis (RY)
+ * 6 - rotate about Z axis (RZ)
+ * 7 - negate all axes (NEG)
+ */
+
+enum link_types {
+ end_x_form,
+ tx,
+ ty,
+ tz,
+ rx,
+ ry,
+ rz,
+ neg
+};
+
+/* TRANSFORM */
+/* Structure used to describe a transform. */
+struct intern_transform {
+ struct {
+ u32 link_type;
+ s32 link_amount;
+ } link[8];
+};
+
+/* JR3 force/torque sensor data definition. For more information see sensor and */
+/* hardware manuals. */
+
+struct jr3_channel {
+ /* Raw_channels is the area used to store the raw data coming from */
+ /* the sensor. */
+
+ struct raw_channel raw_channels[16]; /* offset 0x0000 */
+
+ /* Copyright is a null terminated ASCII string containing the JR3 */
+ /* copyright notice. */
+
+ u32 copyright[0x0018]; /* offset 0x0040 */
+ s32 reserved1[0x0008]; /* offset 0x0058 */
+
+ /* Shunts contains the sensor shunt readings. Some JR3 sensors have
+ * the ability to have their gains adjusted. This allows the
+ * hardware full scales to be adjusted to potentially allow
+ * better resolution or dynamic range. For sensors that have
+ * this ability, the gain of each sensor channel is measured at
+ * the time of calibration using a shunt resistor. The shunt
+ * resistor is placed across one arm of the resistor bridge, and
+ * the resulting change in the output of that channel is
+ * measured. This measurement is called the shunt reading, and
+ * is recorded here. If the user has changed the gain of the //
+ * sensor, and made new shunt measurements, those shunt
+ * measurements can be placed here. The JR3 DSP will then scale
+ * the calibration matrix such so that the gains are again
+ * proper for the indicated shunt readings. If shunts is 0, then
+ * the sensor cannot have its gain changed. For details on
+ * changing the sensor gain, and making shunts readings, please
+ * see the sensor manual. To make these values take effect the
+ * user must call either command (5) use transform # (pg. 33) or
+ * command (10) set new full scales (pg. 38).
+ */
+
+ struct six_axis_array shunts; /* offset 0x0060 */
+ s32 reserved2[2]; /* offset 0x0066 */
+
+ /* Default_FS contains the full scale that is used if the user does */
+ /* not set a full scale. */
+
+ struct six_axis_array default_FS; /* offset 0x0068 */
+ s32 reserved3; /* offset 0x006e */
+
+ /* Load_envelope_num is the load envelope number that is currently
+ * in use. This value is set by the user after one of the load
+ * envelopes has been initialized.
+ */
+
+ s32 load_envelope_num; /* offset 0x006f */
+
+ /* Min_full_scale is the recommend minimum full scale. */
+
+ /* These values in conjunction with max_full_scale (pg. 9) helps
+ * determine the appropriate value for setting the full scales. The
+ * software allows the user to set the sensor full scale to an
+ * arbitrary value. But setting the full scales has some hazards. If
+ * the full scale is set too low, the data will saturate
+ * prematurely, and dynamic range will be lost. If the full scale is
+ * set too high, then resolution is lost as the data is shifted to
+ * the right and the least significant bits are lost. Therefore the
+ * maximum full scale is the maximum value at which no resolution is
+ * lost, and the minimum full scale is the value at which the data
+ * will not saturate prematurely. These values are calculated
+ * whenever a new coordinate transformation is calculated. It is
+ * possible for the recommended maximum to be less than the
+ * recommended minimum. This comes about primarily when using
+ * coordinate translations. If this is the case, it means that any
+ * full scale selection will be a compromise between dynamic range
+ * and resolution. It is usually recommended to compromise in favor
+ * of resolution which means that the recommend maximum full scale
+ * should be chosen.
+ *
+ * WARNING: Be sure that the full scale is no less than 0.4% of the
+ * recommended minimum full scale. Full scales below this value will
+ * cause erroneous results.
+ */
+
+ struct six_axis_array min_full_scale; /* offset 0x0070 */
+ s32 reserved4; /* offset 0x0076 */
+
+ /* Transform_num is the transform number that is currently in use.
+ * This value is set by the JR3 DSP after the user has used command
+ * (5) use transform # (pg. 33).
+ */
+
+ s32 transform_num; /* offset 0x0077 */
+
+ /* Max_full_scale is the recommended maximum full scale. See */
+ /* min_full_scale (pg. 9) for more details. */
+
+ struct six_axis_array max_full_scale; /* offset 0x0078 */
+ s32 reserved5; /* offset 0x007e */
+
+ /* Peak_address is the address of the data which will be monitored
+ * by the peak routine. This value is set by the user. The peak
+ * routine will monitor any 8 contiguous addresses for peak values.
+ * (ex. to watch filter3 data for peaks, set this value to 0x00a8).
+ */
+
+ s32 peak_address; /* offset 0x007f */
+
+ /* Full_scale is the sensor full scales which are currently in use.
+ * Decoupled and filtered data is scaled so that +/- 16384 is equal
+ * to the full scales. The engineering units used are indicated by
+ * the units value discussed on page 16. The full scales for Fx, Fy,
+ * Fz, Mx, My and Mz can be written by the user prior to calling
+ * command (10) set new full scales (pg. 38). The full scales for V1
+ * and V2 are set whenever the full scales are changed or when the
+ * axes used to calculate the vectors are changed. The full scale of
+ * V1 and V2 will always be equal to the largest full scale of the
+ * axes used for each vector respectively.
+ */
+
+ struct force_array full_scale; /* offset 0x0080 */
+
+ /* Offsets contains the sensor offsets. These values are subtracted from
+ * the sensor data to obtain the decoupled data. The offsets are set a
+ * few seconds (< 10) after the calibration data has been received.
+ * They are set so that the output data will be zero. These values
+ * can be written as well as read. The JR3 DSP will use the values
+ * written here within 2 ms of being written. To set future
+ * decoupled data to zero, add these values to the current decoupled
+ * data values and place the sum here. The JR3 DSP will change these
+ * values when a new transform is applied. So if the offsets are
+ * such that FX is 5 and all other values are zero, after rotating
+ * about Z by 90 degrees, FY would be 5 and all others would be zero.
+ */
+
+ struct six_axis_array offsets; /* offset 0x0088 */
+
+ /* Offset_num is the number of the offset currently in use. This
+ * value is set by the JR3 DSP after the user has executed the use
+ * offset # command (pg. 34). It can vary between 0 and 15.
+ */
+
+ s32 offset_num; /* offset 0x008e */
+
+ /* Vect_axes is a bit map showing which of the axes are being used
+ * in the vector calculations. This value is set by the JR3 DSP
+ * after the user has executed the set vector axes command (pg. 37).
+ */
+
+ u32 vect_axes; /* offset 0x008f */
+
+ /* Filter0 is the decoupled, unfiltered data from the JR3 sensor.
+ * This data has had the offsets removed.
+ *
+ * These force_arrays hold the filtered data. The decoupled data is
+ * passed through cascaded low pass filters. Each succeeding filter
+ * has a cutoff frequency of 1/4 of the preceding filter. The cutoff
+ * frequency of filter1 is 1/16 of the sample rate from the sensor.
+ * For a typical sensor with a sample rate of 8 kHz, the cutoff
+ * frequency of filter1 would be 500 Hz. The following filters would
+ * cutoff at 125 Hz, 31.25 Hz, 7.813 Hz, 1.953 Hz and 0.4883 Hz.
+ */
+
+ struct force_array filter[7]; /* offset 0x0090,
+ offset 0x0098,
+ offset 0x00a0,
+ offset 0x00a8,
+ offset 0x00b0,
+ offset 0x00b8 ,
+ offset 0x00c0 */
+
+ /* Rate_data is the calculated rate data. It is a first derivative
+ * calculation. It is calculated at a frequency specified by the
+ * variable rate_divisor (pg. 12). The data on which the rate is
+ * calculated is specified by the variable rate_address (pg. 12).
+ */
+
+ struct force_array rate_data; /* offset 0x00c8 */
+
+ /* Minimum_data & maximum_data are the minimum and maximum (peak)
+ * data values. The JR3 DSP can monitor any 8 contiguous data items
+ * for minimums and maximums at full sensor bandwidth. This area is
+ * only updated at user request. This is done so that the user does
+ * not miss any peaks. To read the data, use either the read peaks
+ * command (pg. 40), or the read and reset peaks command (pg. 39).
+ * The address of the data to watch for peaks is stored in the
+ * variable peak_address (pg. 10). Peak data is lost when executing
+ * a coordinate transformation or a full scale change. Peak data is
+ * also lost when plugging in a new sensor.
+ */
+
+ struct force_array minimum_data; /* offset 0x00d0 */
+ struct force_array maximum_data; /* offset 0x00d8 */
+
+ /* Near_sat_value & sat_value contain the value used to determine if
+ * the raw sensor is saturated. Because of decoupling and offset
+ * removal, it is difficult to tell from the processed data if the
+ * sensor is saturated. These values, in conjunction with the error
+ * and warning words (pg. 14), provide this critical information.
+ * These two values may be set by the host processor. These values
+ * are positive signed values, since the saturation logic uses the
+ * absolute values of the raw data. The near_sat_value defaults to
+ * approximately 80% of the ADC's full scale, which is 26214, while
+ * sat_value defaults to the ADC's full scale:
+ *
+ * sat_value = 32768 - 2^(16 - ADC bits)
+ */
+
+ s32 near_sat_value; /* offset 0x00e0 */
+ s32 sat_value; /* offset 0x00e1 */
+
+ /* Rate_address, rate_divisor & rate_count contain the data used to
+ * control the calculations of the rates. Rate_address is the
+ * address of the data used for the rate calculation. The JR3 DSP
+ * will calculate rates for any 8 contiguous values (ex. to
+ * calculate rates for filter3 data set rate_address to 0x00a8).
+ * Rate_divisor is how often the rate is calculated. If rate_divisor
+ * is 1, the rates are calculated at full sensor bandwidth. If
+ * rate_divisor is 200, rates are calculated every 200 samples.
+ * Rate_divisor can be any value between 1 and 65536. Set
+ * rate_divisor to 0 to calculate rates every 65536 samples.
+ * Rate_count starts at zero and counts until it equals
+ * rate_divisor, at which point the rates are calculated, and
+ * rate_count is reset to 0. When setting a new rate divisor, it is
+ * a good idea to set rate_count to one less than rate divisor. This
+ * will minimize the time necessary to start the rate calculations.
+ */
+
+ s32 rate_address; /* offset 0x00e2 */
+ u32 rate_divisor; /* offset 0x00e3 */
+ u32 rate_count; /* offset 0x00e4 */
+
+ /* Command_word2 through command_word0 are the locations used to
+ * send commands to the JR3 DSP. Their usage varies with the command
+ * and is detailed later in the Command Definitions section (pg.
+ * 29). In general the user places values into various memory
+ * locations, and then places the command word into command_word0.
+ * The JR3 DSP will process the command and place a 0 into
+ * command_word0 to indicate successful completion. Alternatively
+ * the JR3 DSP will place a negative number into command_word0 to
+ * indicate an error condition. Please note the command locations
+ * are numbered backwards. (I.E. command_word2 comes before
+ * command_word1).
+ */
+
+ s32 command_word2; /* offset 0x00e5 */
+ s32 command_word1; /* offset 0x00e6 */
+ s32 command_word0; /* offset 0x00e7 */
+
+ /* Count1 through count6 are unsigned counters which are incremented
+ * every time the matching filters are calculated. Filter1 is
+ * calculated at the sensor data bandwidth. So this counter would
+ * increment at 8 kHz for a typical sensor. The rest of the counters
+ * are incremented at 1/4 the interval of the counter immediately
+ * preceding it, so they would count at 2 kHz, 500 Hz, 125 Hz etc.
+ * These counters can be used to wait for data. Each time the
+ * counter changes, the corresponding data set can be sampled, and
+ * this will insure that the user gets each sample, once, and only
+ * once.
+ */
+
+ u32 count1; /* offset 0x00e8 */
+ u32 count2; /* offset 0x00e9 */
+ u32 count3; /* offset 0x00ea */
+ u32 count4; /* offset 0x00eb */
+ u32 count5; /* offset 0x00ec */
+ u32 count6; /* offset 0x00ed */
+
+ /* Error_count is a running count of data reception errors. If this
+ * counter is changing rapidly, it probably indicates a bad sensor
+ * cable connection or other hardware problem. In most installations
+ * error_count should not change at all. But it is possible in an
+ * extremely noisy environment to experience occasional errors even
+ * without a hardware problem. If the sensor is well grounded, this
+ * is probably unavoidable in these environments. On the occasions
+ * where this counter counts a bad sample, that sample is ignored.
+ */
+
+ u32 error_count; /* offset 0x00ee */
+
+ /* Count_x is a counter which is incremented every time the JR3 DSP
+ * searches its job queues and finds nothing to do. It indicates the
+ * amount of idle time the JR3 DSP has available. It can also be
+ * used to determine if the JR3 DSP is alive. See the Performance
+ * Issues section on pg. 49 for more details.
+ */
+
+ u32 count_x; /* offset 0x00ef */
+
+ /* Warnings & errors contain the warning and error bits
+ * respectively. The format of these two words is discussed on page
+ * 21 under the headings warnings_bits and error_bits.
+ */
+
+ u32 warnings; /* offset 0x00f0 */
+ u32 errors; /* offset 0x00f1 */
+
+ /* Threshold_bits is a word containing the bits that are set by the
+ * load envelopes. See load_envelopes (pg. 17) and thresh_struct
+ * (pg. 23) for more details.
+ */
+
+ s32 threshold_bits; /* offset 0x00f2 */
+
+ /* Last_crc is the value that shows the actual calculated CRC. CRC
+ * is short for cyclic redundancy code. It should be zero. See the
+ * description for cal_crc_bad (pg. 21) for more information.
+ */
+
+ s32 last_CRC; /* offset 0x00f3 */
+
+ /* EEProm_ver_no contains the version number of the sensor EEProm.
+ * EEProm version numbers can vary between 0 and 255.
+ * Software_ver_no contains the software version number. Version
+ * 3.02 would be stored as 302.
+ */
+
+ s32 eeprom_ver_no; /* offset 0x00f4 */
+ s32 software_ver_no; /* offset 0x00f5 */
+
+ /* Software_day & software_year are the release date of the software
+ * the JR3 DSP is currently running. Day is the day of the year,
+ * with January 1 being 1, and December 31, being 365 for non leap
+ * years.
+ */
+
+ s32 software_day; /* offset 0x00f6 */
+ s32 software_year; /* offset 0x00f7 */
+
+ /* Serial_no & model_no are the two values which uniquely identify a
+ * sensor. This model number does not directly correspond to the JR3
+ * model number, but it will provide a unique identifier for
+ * different sensor configurations.
+ */
+
+ u32 serial_no; /* offset 0x00f8 */
+ u32 model_no; /* offset 0x00f9 */
+
+ /* Cal_day & cal_year are the sensor calibration date. Day is the
+ * day of the year, with January 1 being 1, and December 31, being
+ * 366 for leap years.
+ */
+
+ s32 cal_day; /* offset 0x00fa */
+ s32 cal_year; /* offset 0x00fb */
+
+ /* Units is an enumerated read only value defining the engineering
+ * units used in the sensor full scale. The meanings of particular
+ * values are discussed in the section detailing the force_units
+ * structure on page 22. The engineering units are setto customer
+ * specifications during sensor manufacture and cannot be changed by
+ * writing to Units.
+ *
+ * Bits contains the number of bits of resolution of the ADC
+ * currently in use.
+ *
+ * Channels is a bit field showing which channels the current sensor
+ * is capable of sending. If bit 0 is active, this sensor can send
+ * channel 0, if bit 13 is active, this sensor can send channel 13,
+ * etc. This bit can be active, even if the sensor is not currently
+ * sending this channel. Some sensors are configurable as to which
+ * channels to send, and this field only contains information on the
+ * channels available to send, not on the current configuration. To
+ * find which channels are currently being sent, monitor the
+ * Raw_time fields (pg. 19) in the raw_channels array (pg. 7). If
+ * the time is changing periodically, then that channel is being
+ * received.
+ */
+
+ u32 units; /* offset 0x00fc */
+ s32 bits; /* offset 0x00fd */
+ s32 channels; /* offset 0x00fe */
+
+ /* Thickness specifies the overall thickness of the sensor from
+ * flange to flange. The engineering units for this value are
+ * contained in units (pg. 16). The sensor calibration is relative
+ * to the center of the sensor. This value allows easy coordinate
+ * transformation from the center of the sensor to either flange.
+ */
+
+ s32 thickness; /* offset 0x00ff */
+
+ /* Load_envelopes is a table containing the load envelope
+ * descriptions. There are 16 possible load envelope slots in the
+ * table. The slots are on 16 word boundaries and are numbered 0-15.
+ * Each load envelope needs to start at the beginning of a slot but
+ * need not be fully contained in that slot. That is to say that a
+ * single load envelope can be larger than a single slot. The
+ * software has been tested and ran satisfactorily with 50
+ * thresholds active. A single load envelope this large would take
+ * up 5 of the 16 slots. The load envelope data is laid out in an
+ * order that is most efficient for the JR3 DSP. The structure is
+ * detailed later in the section showing the definition of the
+ * le_struct structure (pg. 23).
+ */
+
+ struct le_struct load_envelopes[0x10]; /* offset 0x0100 */
+
+ /* Transforms is a table containing the transform descriptions.
+ * There are 16 possible transform slots in the table. The slots are
+ * on 16 word boundaries and are numbered 0-15. Each transform needs
+ * to start at the beginning of a slot but need not be fully
+ * contained in that slot. That is to say that a single transform
+ * can be larger than a single slot. A transform is 2 * no of links
+ * + 1 words in length. So a single slot can contain a transform
+ * with 7 links. Two slots can contain a transform that is 15 links.
+ * The layout is detailed later in the section showing the
+ * definition of the transform structure (pg. 26).
+ */
+
+ struct intern_transform transforms[0x10]; /* offset 0x0200 */
+};
+
+struct jr3_t {
+ struct {
+ u32 program_low[0x4000]; /* 0x00000 - 0x10000 */
+ struct jr3_channel data; /* 0x10000 - 0x10c00 */
+ char pad2[0x30000 - 0x00c00]; /* 0x10c00 - 0x40000 */
+ u32 program_high[0x8000]; /* 0x40000 - 0x60000 */
+ u32 reset; /* 0x60000 - 0x60004 */
+ char pad3[0x20000 - 0x00004]; /* 0x60004 - 0x80000 */
+ } channel[4];
+};
diff --git a/drivers/staging/comedi/drivers/ke_counter.c b/drivers/staging/comedi/drivers/ke_counter.c
new file mode 100644
index 00000000000..79f6fe5646c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ke_counter.c
@@ -0,0 +1,254 @@
+/*
+ comedi/drivers/ke_counter.c
+ Comedi driver for Kolter-Electronic PCI Counter 1 Card
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ke_counter
+Description: Driver for Kolter Electronic Counter Card
+Devices: [Kolter Electronic] PCI Counter Card (ke_counter)
+Author: Michael Hillmann
+Updated: Mon, 14 Apr 2008 15:42:42 +0100
+Status: tested
+
+Configuration Options:
+ [0] - PCI bus of device (optional)
+ [1] - PCI slot of device (optional)
+ If bus/slot is not specified, the first supported
+ PCI device found will be used.
+
+This driver is a simple driver to read the counter values from
+Kolter Electronic PCI Counter Card.
+*/
+
+#include "../comedidev.h"
+
+#include "comedi_pci.h"
+
+#define CNT_DRIVER_NAME "ke_counter"
+#define PCI_VENDOR_ID_KOLTER 0x1001
+#define CNT_CARD_DEVICE_ID 0x0014
+
+/*-- function prototypes ----------------------------------------------------*/
+
+static int cnt_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int cnt_detach(struct comedi_device * dev);
+
+static DEFINE_PCI_DEVICE_TABLE(cnt_pci_table) = {
+ {PCI_VENDOR_ID_KOLTER, CNT_CARD_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+ 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, cnt_pci_table);
+
+/*-- board specification structure ------------------------------------------*/
+
+struct cnt_board_struct {
+
+ const char *name;
+ int device_id;
+ int cnt_channel_nbr;
+ int cnt_bits;
+};
+
+
+static const struct cnt_board_struct cnt_boards[] = {
+ {
+ name: CNT_DRIVER_NAME,
+ device_id:CNT_CARD_DEVICE_ID,
+ cnt_channel_nbr:3,
+ cnt_bits:24}
+};
+
+#define cnt_board_nbr (sizeof(cnt_boards)/sizeof(struct cnt_board_struct))
+
+/*-- device private structure -----------------------------------------------*/
+
+struct cnt_device_private {
+
+ struct pci_dev *pcidev;
+};
+
+
+#define devpriv ((struct cnt_device_private *)dev->private)
+
+static struct comedi_driver cnt_driver = {
+ driver_name:CNT_DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:cnt_attach,
+ detach:cnt_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(cnt_driver, cnt_pci_table);
+
+/*-- counter write ----------------------------------------------------------*/
+
+/* This should be used only for resetting the counters; maybe it is better
+ to make a special command 'reset'. */
+static int cnt_winsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ outb((unsigned char)((data[0] >> 24) & 0xff),
+ dev->iobase + chan * 0x20 + 0x10);
+ outb((unsigned char)((data[0] >> 16) & 0xff),
+ dev->iobase + chan * 0x20 + 0x0c);
+ outb((unsigned char)((data[0] >> 8) & 0xff),
+ dev->iobase + chan * 0x20 + 0x08);
+ outb((unsigned char)((data[0] >> 0) & 0xff),
+ dev->iobase + chan * 0x20 + 0x04);
+
+ /* return the number of samples written */
+ return 1;
+}
+
+/*-- counter read -----------------------------------------------------------*/
+
+static int cnt_rinsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned char a0, a1, a2, a3, a4;
+ int chan = CR_CHAN(insn->chanspec);
+ int result;
+
+ a0 = inb(dev->iobase + chan * 0x20);
+ a1 = inb(dev->iobase + chan * 0x20 + 0x04);
+ a2 = inb(dev->iobase + chan * 0x20 + 0x08);
+ a3 = inb(dev->iobase + chan * 0x20 + 0x0c);
+ a4 = inb(dev->iobase + chan * 0x20 + 0x10);
+
+ result = (a1 + (a2 * 256) + (a3 * 65536));
+ if (a4 > 0)
+ result = result - s->maxdata;
+
+ *data = (unsigned int) result;
+
+ /* return the number of samples read */
+ return 1;
+}
+
+/*-- attach -----------------------------------------------------------------*/
+
+static int cnt_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *subdevice;
+ struct pci_dev *pci_device;
+ struct cnt_board_struct *board;
+ unsigned long io_base;
+ int error, i;
+
+ /* allocate device private structure */
+ if ((error = alloc_private(dev, sizeof(struct cnt_device_private))) < 0) {
+ return error;
+ }
+
+ /* Probe the device to determine what device in the series it is. */
+ for (pci_device = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
+ pci_device != NULL;
+ pci_device =
+ pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_device)) {
+ if (pci_device->vendor == PCI_VENDOR_ID_KOLTER) {
+ for (i = 0; i < cnt_board_nbr; i++) {
+ if (cnt_boards[i].device_id ==
+ pci_device->device) {
+ /* was a particular bus/slot requested? */
+ if ((it->options[0] != 0)
+ || (it->options[1] != 0)) {
+ /* are we on the wrong bus/slot? */
+ if (pci_device->bus->number !=
+ it->options[0]
+ || PCI_SLOT(pci_device->
+ devfn) !=
+ it->options[1]) {
+ continue;
+ }
+ }
+
+ dev->board_ptr = cnt_boards + i;
+ board = (struct cnt_board_struct *) dev->
+ board_ptr;
+ goto found;
+ }
+ }
+ }
+ }
+ printk("comedi%d: no supported board found! (req. bus/slot: %d/%d)\n",
+ dev->minor, it->options[0], it->options[1]);
+ return -EIO;
+
+ found:
+ printk("comedi%d: found %s at PCI bus %d, slot %d\n", dev->minor,
+ board->name, pci_device->bus->number,
+ PCI_SLOT(pci_device->devfn));
+ devpriv->pcidev = pci_device;
+ dev->board_name = board->name;
+
+ /* enable PCI device and request regions */
+ if ((error = comedi_pci_enable(pci_device, CNT_DRIVER_NAME)) < 0) {
+ printk("comedi%d: failed to enable PCI device and request regions!\n", dev->minor);
+ return error;
+ }
+
+ /* read register base address [PCI_BASE_ADDRESS #0] */
+ io_base = pci_resource_start(pci_device, 0);
+ dev->iobase = io_base;
+
+ /* allocate the subdevice structures */
+ if ((error = alloc_subdevices(dev, 1)) < 0) {
+ return error;
+ }
+
+ subdevice = dev->subdevices + 0;
+ dev->read_subdev = subdevice;
+
+ subdevice->type = COMEDI_SUBD_COUNTER;
+ subdevice->subdev_flags = SDF_READABLE /* | SDF_COMMON */ ;
+ subdevice->n_chan = board->cnt_channel_nbr;
+ subdevice->maxdata = (1 << board->cnt_bits) - 1;
+ subdevice->insn_read = cnt_rinsn;
+ subdevice->insn_write = cnt_winsn;
+
+ // select 20MHz clock
+ outb(3, dev->iobase + 248);
+
+ // reset all counters
+ outb(0, dev->iobase);
+ outb(0, dev->iobase + 0x20);
+ outb(0, dev->iobase + 0x40);
+
+ printk("comedi%d: " CNT_DRIVER_NAME " attached.\n", dev->minor);
+ return 0;
+}
+
+/*-- detach -----------------------------------------------------------------*/
+
+static int cnt_detach(struct comedi_device * dev)
+{
+ if (devpriv && devpriv->pcidev) {
+ if (dev->iobase) {
+ comedi_pci_disable(devpriv->pcidev);
+ }
+ pci_dev_put(devpriv->pcidev);
+ }
+ printk("comedi%d: " CNT_DRIVER_NAME " remove\n", dev->minor);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/me4000.c b/drivers/staging/comedi/drivers/me4000.c
index b432aa7d764..12481a032b9 100644
--- a/drivers/staging/comedi/drivers/me4000.c
+++ b/drivers/staging/comedi/drivers/me4000.c
@@ -92,7 +92,7 @@ static DEFINE_PCI_DEVICE_TABLE(me4000_pci_table) = {
MODULE_DEVICE_TABLE(pci, me4000_pci_table);
-static const me4000_board_t me4000_boards[] = {
+static const struct me4000_board me4000_boards[] = {
{"ME-4650", 0x4650, {0, 0}, {16, 0, 0, 0}, {4}, {0}},
{"ME-4660", 0x4660, {0, 0}, {32, 0, 16, 0}, {4}, {3}},
@@ -113,108 +113,108 @@ static const me4000_board_t me4000_boards[] = {
{0},
};
-#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(me4000_board_t) - 1)
+#define ME4000_BOARD_VERSIONS (sizeof(me4000_boards) / sizeof(struct me4000_board) - 1)
/*-----------------------------------------------------------------------------
Comedi function prototypes
---------------------------------------------------------------------------*/
-static int me4000_attach(comedi_device * dev, comedi_devconfig * it);
-static int me4000_detach(comedi_device * dev);
-static comedi_driver driver_me4000 = {
+static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int me4000_detach(struct comedi_device *dev);
+static struct comedi_driver driver_me4000 = {
driver_name:"me4000",
- module:THIS_MODULE,
- attach:me4000_attach,
- detach:me4000_detach,
+ module : THIS_MODULE,
+ attach : me4000_attach,
+ detach : me4000_detach,
};
/*-----------------------------------------------------------------------------
Meilhaus function prototypes
---------------------------------------------------------------------------*/
-static int me4000_probe(comedi_device * dev, comedi_devconfig * it);
-static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p);
-static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p);
-static int init_ao_context(comedi_device * dev);
-static int init_ai_context(comedi_device * dev);
-static int init_dio_context(comedi_device * dev);
-static int init_cnt_context(comedi_device * dev);
-static int xilinx_download(comedi_device * dev);
-static int reset_board(comedi_device * dev);
+static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it);
+static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p);
+static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p);
+static int init_ao_context(struct comedi_device *dev);
+static int init_ai_context(struct comedi_device *dev);
+static int init_dio_context(struct comedi_device *dev);
+static int init_cnt_context(struct comedi_device *dev);
+static int xilinx_download(struct comedi_device *dev);
+static int reset_board(struct comedi_device *dev);
-static int me4000_dio_insn_bits(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_dio_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_dio_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_dio_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int cnt_reset(comedi_device * dev, unsigned int channel);
+static int cnt_reset(struct comedi_device *dev, unsigned int channel);
-static int cnt_config(comedi_device * dev,
+static int cnt_config(struct comedi_device *dev,
unsigned int channel, unsigned int mode);
-static int me4000_cnt_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_cnt_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_cnt_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_cnt_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_ai_insn_read(comedi_device * dev,
- comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data);
+static int me4000_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data);
-static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s);
+static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
-static int ai_check_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd);
+static int ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int ai_round_cmd_args(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_round_cmd_args(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int *init_ticks,
unsigned int *scan_ticks, unsigned int *chan_ticks);
-static int ai_prepare(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_prepare(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int init_ticks,
unsigned int scan_ticks, unsigned int chan_ticks);
-static int ai_write_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd);
+static int ai_write_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd);
static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG);
-static int me4000_ai_do_cmd_test(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd);
+static int me4000_ai_do_cmd_test(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd);
-static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s);
+static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
-static int me4000_ao_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
-static int me4000_ao_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data);
+static int me4000_ao_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data);
/*-----------------------------------------------------------------------------
Meilhaus inline functions
---------------------------------------------------------------------------*/
-static inline void me4000_outb(comedi_device * dev, unsigned char value,
+static inline void me4000_outb(struct comedi_device *dev, unsigned char value,
unsigned long port)
{
PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
outb(value, port);
}
-static inline void me4000_outl(comedi_device * dev, unsigned long value,
+static inline void me4000_outl(struct comedi_device *dev, unsigned long value,
unsigned long port)
{
PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
outl(value, port);
}
-static inline unsigned long me4000_inl(comedi_device * dev, unsigned long port)
+static inline unsigned long me4000_inl(struct comedi_device *dev, unsigned long port)
{
unsigned long value;
value = inl(port);
@@ -222,7 +222,7 @@ static inline unsigned long me4000_inl(comedi_device * dev, unsigned long port)
return value;
}
-static inline unsigned char me4000_inb(comedi_device * dev, unsigned long port)
+static inline unsigned char me4000_inb(struct comedi_device *dev, unsigned long port)
{
unsigned char value;
value = inb(port);
@@ -230,7 +230,7 @@ static inline unsigned char me4000_inb(comedi_device * dev, unsigned long port)
return value;
}
-static const comedi_lrange me4000_ai_range = {
+static const struct comedi_lrange me4000_ai_range = {
4,
{
UNI_RANGE(2.5),
@@ -240,16 +240,16 @@ static const comedi_lrange me4000_ai_range = {
}
};
-static const comedi_lrange me4000_ao_range = {
+static const struct comedi_lrange me4000_ao_range = {
1,
{
BIP_RANGE(10),
}
};
-static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
+static int me4000_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
int result;
CALL_PDEBUG("In me4000_attach()\n");
@@ -277,7 +277,7 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
s->subdev_flags =
SDF_READABLE | SDF_COMMON | SDF_GROUND | SDF_DIFF;
s->n_chan = thisboard->ai.count;
- s->maxdata = 0xFFFF; // 16 bit ADC
+ s->maxdata = 0xFFFF; /* 16 bit ADC */
s->len_chanlist = ME4000_AI_CHANNEL_LIST_COUNT;
s->range_table = &me4000_ai_range;
s->insn_read = me4000_ai_insn_read;
@@ -312,7 +312,7 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
s->type = COMEDI_SUBD_AO;
s->subdev_flags = SDF_WRITEABLE | SDF_COMMON | SDF_GROUND;
s->n_chan = thisboard->ao.count;
- s->maxdata = 0xFFFF; // 16 bit DAC
+ s->maxdata = 0xFFFF; /* 16 bit DAC */
s->range_table = &me4000_ao_range;
s->insn_write = me4000_ao_insn_write;
s->insn_read = me4000_ao_insn_read;
@@ -358,7 +358,7 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
s->type = COMEDI_SUBD_COUNTER;
s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
s->n_chan = thisboard->cnt.count;
- s->maxdata = 0xFFFF; // 16 bit counters
+ s->maxdata = 0xFFFF; /* 16 bit counters */
s->insn_read = me4000_cnt_insn_read;
s->insn_write = me4000_cnt_insn_write;
s->insn_config = me4000_cnt_insn_config;
@@ -369,18 +369,18 @@ static int me4000_attach(comedi_device * dev, comedi_devconfig * it)
return 0;
}
-static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
+static int me4000_probe(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct pci_dev *pci_device;
int result, i;
- me4000_board_t *board;
+ struct me4000_board *board;
CALL_PDEBUG("In me4000_probe()\n");
/* Allocate private memory */
- if (alloc_private(dev, sizeof(me4000_info_t)) < 0) {
+ if (alloc_private(dev, sizeof(struct me4000_info)) < 0)
return -ENOMEM;
- }
+
/*
* Probe the device to determine what device in the series it is.
*/
@@ -405,7 +405,7 @@ static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
}
}
dev->board_ptr = me4000_boards + i;
- board = (me4000_board_t *) dev->
+ board = (struct me4000_board *) dev->
board_ptr;
info->pci_dev_p = pci_device;
goto found;
@@ -512,7 +512,7 @@ static int me4000_probe(comedi_device * dev, comedi_devconfig * it)
return 0;
}
-static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p)
+static int get_registers(struct comedi_device *dev, struct pci_dev *pci_dev_p)
{
CALL_PDEBUG("In get_registers()\n");
@@ -564,27 +564,25 @@ static int get_registers(comedi_device * dev, struct pci_dev *pci_dev_p)
return 0;
}
-static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p)
+static int init_board_info(struct comedi_device *dev, struct pci_dev *pci_dev_p)
{
int result;
CALL_PDEBUG("In init_board_info()\n");
/* Init spin locks */
- //spin_lock_init(&info->preload_lock);
- //spin_lock_init(&info->ai_ctrl_lock);
+ /* spin_lock_init(&info->preload_lock); */
+ /* spin_lock_init(&info->ai_ctrl_lock); */
/* Get the serial number */
result = pci_read_config_dword(pci_dev_p, 0x2C, &info->serial_no);
- if (result != PCIBIOS_SUCCESSFUL) {
+ if (result != PCIBIOS_SUCCESSFUL)
return result;
- }
/* Get the hardware revision */
result = pci_read_config_byte(pci_dev_p, 0x08, &info->hw_revision);
- if (result != PCIBIOS_SUCCESSFUL) {
+ if (result != PCIBIOS_SUCCESSFUL)
return result;
- }
/* Get the vendor id */
info->vendor_id = pci_dev_p->vendor;
@@ -598,14 +596,14 @@ static int init_board_info(comedi_device * dev, struct pci_dev *pci_dev_p)
return 0;
}
-static int init_ao_context(comedi_device * dev)
+static int init_ao_context(struct comedi_device *dev)
{
int i;
CALL_PDEBUG("In init_ao_context()\n");
for (i = 0; i < thisboard->ao.count; i++) {
- //spin_lock_init(&info->ao_context[i].use_lock);
+ /* spin_lock_init(&info->ao_context[i].use_lock); */
info->ao_context[i].irq = info->irq;
switch (i) {
@@ -681,7 +679,7 @@ static int init_ao_context(comedi_device * dev)
return 0;
}
-static int init_ai_context(comedi_device * dev)
+static int init_ai_context(struct comedi_device *dev)
{
CALL_PDEBUG("In init_ai_context()\n");
@@ -715,7 +713,7 @@ static int init_ai_context(comedi_device * dev)
return 0;
}
-static int init_dio_context(comedi_device * dev)
+static int init_dio_context(struct comedi_device *dev)
{
CALL_PDEBUG("In init_dio_context()\n");
@@ -734,7 +732,7 @@ static int init_dio_context(comedi_device * dev)
return 0;
}
-static int init_cnt_context(comedi_device * dev)
+static int init_cnt_context(struct comedi_device *dev)
{
CALL_PDEBUG("In init_cnt_context()\n");
@@ -755,7 +753,7 @@ static int init_cnt_context(comedi_device * dev)
extern unsigned char *xilinx_firm;
#endif
-static int xilinx_download(comedi_device * dev)
+static int xilinx_download(struct comedi_device *dev)
{
u32 value = 0;
wait_queue_head_t queue;
@@ -782,7 +780,7 @@ static int xilinx_download(comedi_device * dev)
/* Wait until /INIT pin is set */
udelay(20);
- if (!inl(info->plx_regbase + PLX_INTCSR) & 0x20) {
+ if (!(inl(info->plx_regbase + PLX_INTCSR) & 0x20)) {
printk(KERN_ERR
"comedi%d: me4000: xilinx_download(): Can't init Xilinx\n",
dev->minor);
@@ -837,7 +835,7 @@ static int xilinx_download(comedi_device * dev)
return 0;
}
-static int reset_board(comedi_device * dev)
+static int reset_board(struct comedi_device *dev)
{
unsigned long icr;
@@ -895,16 +893,15 @@ static int reset_board(comedi_device * dev)
return 0;
}
-static int me4000_detach(comedi_device * dev)
+static int me4000_detach(struct comedi_device *dev)
{
CALL_PDEBUG("In me4000_detach()\n");
if (info) {
if (info->pci_dev_p) {
reset_board(dev);
- if (info->plx_regbase) {
+ if (info->plx_regbase)
comedi_pci_disable(info->pci_dev_p);
- }
pci_dev_put(info->pci_dev_p);
}
}
@@ -916,8 +913,8 @@ static int me4000_detach(comedi_device * dev)
Analog input section
===========================================================================*/
-static int me4000_ai_insn_read(comedi_device * dev,
- comedi_subdevice * subdevice, comedi_insn * insn, lsampl_t * data)
+static int me4000_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *subdevice, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1040,7 +1037,7 @@ static int me4000_ai_insn_read(comedi_device * dev,
return 1;
}
-static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int me4000_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
unsigned long tmp;
@@ -1057,8 +1054,8 @@ static int me4000_ai_cancel(comedi_device * dev, comedi_subdevice * s)
return 0;
}
-static int ai_check_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int ai_check_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
int aref;
int i;
@@ -1138,9 +1135,9 @@ static int ai_check_chanlist(comedi_device * dev,
return 0;
}
-static int ai_round_cmd_args(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_round_cmd_args(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int *init_ticks,
unsigned int *scan_ticks, unsigned int *chan_ticks)
{
@@ -1163,9 +1160,8 @@ static int ai_round_cmd_args(comedi_device * dev,
rest = (cmd->start_arg * 33) % 1000;
if (cmd->flags & TRIG_ROUND_NEAREST) {
- if (rest > 33) {
+ if (rest > 33)
(*init_ticks)++;
- }
} else if (cmd->flags & TRIG_ROUND_UP) {
if (rest)
(*init_ticks)++;
@@ -1177,9 +1173,8 @@ static int ai_round_cmd_args(comedi_device * dev,
rest = (cmd->scan_begin_arg * 33) % 1000;
if (cmd->flags & TRIG_ROUND_NEAREST) {
- if (rest > 33) {
+ if (rest > 33)
(*scan_ticks)++;
- }
} else if (cmd->flags & TRIG_ROUND_UP) {
if (rest)
(*scan_ticks)++;
@@ -1191,9 +1186,8 @@ static int ai_round_cmd_args(comedi_device * dev,
rest = (cmd->convert_arg * 33) % 1000;
if (cmd->flags & TRIG_ROUND_NEAREST) {
- if (rest > 33) {
+ if (rest > 33)
(*chan_ticks)++;
- }
} else if (cmd->flags & TRIG_ROUND_UP) {
if (rest)
(*chan_ticks)++;
@@ -1207,7 +1201,7 @@ static int ai_round_cmd_args(comedi_device * dev,
return 0;
}
-static void ai_write_timer(comedi_device * dev,
+static void ai_write_timer(struct comedi_device *dev,
unsigned int init_ticks,
unsigned int scan_ticks, unsigned int chan_ticks)
{
@@ -1228,9 +1222,9 @@ static void ai_write_timer(comedi_device * dev,
me4000_outl(dev, chan_ticks - 1, info->ai_context.chan_timer_reg);
}
-static int ai_prepare(comedi_device * dev,
- comedi_subdevice * s,
- comedi_cmd * cmd,
+static int ai_prepare(struct comedi_device *dev,
+ struct comedi_subdevice *s,
+ struct comedi_cmd *cmd,
unsigned int init_ticks,
unsigned int scan_ticks, unsigned int chan_ticks)
{
@@ -1297,8 +1291,8 @@ static int ai_prepare(comedi_device * dev,
return 0;
}
-static int ai_write_chanlist(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int ai_write_chanlist(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
unsigned int entry;
unsigned int chan;
@@ -1337,13 +1331,13 @@ static int ai_write_chanlist(comedi_device * dev,
return 0;
}
-static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s)
+static int me4000_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
int err;
unsigned int init_ticks = 0;
unsigned int scan_ticks = 0;
unsigned int chan_ticks = 0;
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
CALL_PDEBUG("In me4000_ai_do_cmd()\n");
@@ -1381,8 +1375,8 @@ static int me4000_ai_do_cmd(comedi_device * dev, comedi_subdevice * s)
* - invalid chanlist
* So I tried to adopt this scheme.
*/
-static int me4000_ai_do_cmd_test(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int me4000_ai_do_cmd_test(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
unsigned int init_ticks;
@@ -1503,9 +1497,8 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
cmd->stop_src = TRIG_NONE;
err++;
}
- if (err) {
+ if (err)
return 1;
- }
/*
* Stage 2. Check for trigger source conflicts.
@@ -1553,9 +1546,8 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
cmd->scan_end_src = TRIG_NONE;
err++;
}
- if (err) {
+ if (err)
return 2;
- }
/*
* Stage 3. Check if arguments are generally valid.
@@ -1588,9 +1580,9 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
cmd->convert_arg = 2000;
err++;
}
- if (err) {
+
+ if (err)
return 3;
- }
/*
* Stage 4. Check for argument conflicts.
@@ -1604,21 +1596,21 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
dev->minor);
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
+ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
err++;
}
} else if (cmd->start_src == TRIG_NOW &&
@@ -1630,14 +1622,14 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1649,21 +1641,21 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
if (scan_ticks <= cmd->chanlist_len * chan_ticks) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid scan end arg\n",
dev->minor);
- cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; // At least one tick more
+ cmd->scan_end_arg = 2000 * cmd->chanlist_len + 31; /* At least one tick more */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1675,14 +1667,14 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1694,14 +1686,14 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
if (chan_ticks < ME4000_AI_MIN_TICKS) {
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid convert arg\n",
dev->minor);
- cmd->convert_arg = 2000; // 66 ticks at least
+ cmd->convert_arg = 2000; /* 66 ticks at least */
err++;
}
} else if (cmd->start_src == TRIG_EXT &&
@@ -1713,7 +1705,7 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
printk(KERN_ERR
"comedi%d: me4000: me4000_ai_do_cmd_test(): Invalid start arg\n",
dev->minor);
- cmd->start_arg = 2000; // 66 ticks at least
+ cmd->start_arg = 2000; /* 66 ticks at least */
err++;
}
}
@@ -1735,9 +1727,9 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
err++;
}
}
- if (err) {
+
+ if (err)
return 4;
- }
/*
* Stage 5. Check the channel list.
@@ -1751,9 +1743,9 @@ static int me4000_ai_do_cmd_test(comedi_device * dev,
static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
{
unsigned int tmp;
- comedi_device *dev = dev_id;
- comedi_subdevice *s = dev->subdevices;
- me4000_ai_context_t *ai_context = &info->ai_context;
+ struct comedi_device *dev = dev_id;
+ struct comedi_subdevice *s = dev->subdevices;
+ struct me4000_ai_context *ai_context = &info->ai_context;
int i;
int c = 0;
long lval;
@@ -1911,8 +1903,8 @@ static irqreturn_t me4000_ai_isr(int irq, void *dev_id PT_REGS_ARG)
Analog output section
===========================================================================*/
-static int me4000_ao_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_ao_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1969,8 +1961,8 @@ static int me4000_ao_insn_write(comedi_device * dev,
return 1;
}
-static int me4000_ao_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_ao_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1990,16 +1982,16 @@ static int me4000_ao_insn_read(comedi_device * dev,
Digital I/O section
===========================================================================*/
-static int me4000_dio_insn_bits(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_dio_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
CALL_PDEBUG("In me4000_dio_insn_bits()\n");
/* Length of data must be 2 (mask and new data, see below) */
- if (insn->n == 0) {
+ if (insn->n == 0)
return 0;
- }
+
if (insn->n != 2) {
printk("comedi%d: me4000: me4000_dio_insn_bits(): Invalid instruction length\n", dev->minor);
return -EINVAL;
@@ -2041,8 +2033,8 @@ static int me4000_dio_insn_bits(comedi_device * dev,
return 2;
}
-static int me4000_dio_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_dio_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
unsigned long tmp;
int chan = CR_CHAN(insn->chanspec);
@@ -2135,7 +2127,7 @@ static int me4000_dio_insn_config(comedi_device * dev,
Counter section
===========================================================================*/
-static int cnt_reset(comedi_device * dev, unsigned int channel)
+static int cnt_reset(struct comedi_device *dev, unsigned int channel)
{
CALL_PDEBUG("In cnt_reset()\n");
@@ -2166,7 +2158,7 @@ static int cnt_reset(comedi_device * dev, unsigned int channel)
return 0;
}
-static int cnt_config(comedi_device * dev, unsigned int channel,
+static int cnt_config(struct comedi_device *dev, unsigned int channel,
unsigned int mode)
{
int tmp = 0;
@@ -2223,8 +2215,8 @@ static int cnt_config(comedi_device * dev, unsigned int channel,
return 0;
}
-static int me4000_cnt_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int err;
@@ -2266,17 +2258,17 @@ static int me4000_cnt_insn_config(comedi_device * dev,
return 2;
}
-static int me4000_cnt_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
unsigned short tmp;
CALL_PDEBUG("In me4000_cnt_insn_read()\n");
- if (insn->n == 0) {
+ if (insn->n == 0)
return 0;
- }
+
if (insn->n > 1) {
printk(KERN_ERR
"comedi%d: me4000: me4000_cnt_insn_read(): Invalid instruction length %d\n",
@@ -2313,8 +2305,8 @@ static int me4000_cnt_insn_read(comedi_device * dev,
return 1;
}
-static int me4000_cnt_insn_write(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int me4000_cnt_insn_write(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
unsigned short tmp;
diff --git a/drivers/staging/comedi/drivers/me4000.h b/drivers/staging/comedi/drivers/me4000.h
index f12b8873ec3..733b19243c7 100644
--- a/drivers/staging/comedi/drivers/me4000.h
+++ b/drivers/staging/comedi/drivers/me4000.h
@@ -28,37 +28,37 @@
Debug section
===========================================================================*/
-#undef ME4000_CALL_DEBUG // Debug function entry and exit
-#undef ME4000_PORT_DEBUG // Debug port access
-#undef ME4000_ISR_DEBUG // Debug the interrupt service routine
-#undef ME4000_DEBUG // General purpose debug masseges
+#undef ME4000_CALL_DEBUG /* Debug function entry and exit */
+#undef ME4000_PORT_DEBUG /* Debug port access */
+#undef ME4000_ISR_DEBUG /* Debug the interrupt service routine */
+#undef ME4000_DEBUG /* General purpose debug masseges */
#ifdef ME4000_CALL_DEBUG
#undef CALL_PDEBUG
#define CALL_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-# define CALL_PDEBUG(fmt, args...) // no debugging, do nothing
+# define CALL_PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
#ifdef ME4000_PORT_DEBUG
#undef PORT_PDEBUG
#define PORT_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-#define PORT_PDEBUG(fmt, args...) // no debugging, do nothing
+#define PORT_PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
#ifdef ME4000_ISR_DEBUG
#undef ISR_PDEBUG
#define ISR_PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-#define ISR_PDEBUG(fmt, args...) // no debugging, do nothing
+#define ISR_PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
#ifdef ME4000_DEBUG
#undef PDEBUG
#define PDEBUG(fmt, args...) printk(KERN_DEBUG"comedi%d: me4000: " fmt, dev->minor, ##args)
#else
-#define PDEBUG(fmt, args...) // no debugging, do nothing
+#define PDEBUG(fmt, args...) /* no debugging, do nothing */
#endif
/*=============================================================================
@@ -67,78 +67,78 @@
#define PCI_VENDOR_ID_MEILHAUS 0x1402
-#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 // Low Cost version
+#define PCI_DEVICE_ID_MEILHAUS_ME4650 0x4650 /* Low Cost version */
-#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 // Standard version
-#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 // Isolated version
-#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 // Standard version with Sample and Hold
-#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 // Isolated version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4660 0x4660 /* Standard version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4660I 0x4661 /* Isolated version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4660S 0x4662 /* Standard version with Sample and Hold */
+#define PCI_DEVICE_ID_MEILHAUS_ME4660IS 0x4663 /* Isolated version with Sample and Hold */
-#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 // Standard version
-#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 // Isolated version
-#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 // Standard version with Sample and Hold
-#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 // Isolated version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4670 0x4670 /* Standard version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4670I 0x4671 /* Isolated version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4670S 0x4672 /* Standard version with Sample and Hold */
+#define PCI_DEVICE_ID_MEILHAUS_ME4670IS 0x4673 /* Isolated version with Sample and Hold */
-#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 // Standard version
-#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 // Isolated version
-#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 // Standard version with Sample and Hold
-#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 // Isolated version with Sample and Hold
+#define PCI_DEVICE_ID_MEILHAUS_ME4680 0x4680 /* Standard version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4680I 0x4681 /* Isolated version */
+#define PCI_DEVICE_ID_MEILHAUS_ME4680S 0x4682 /* Standard version with Sample and Hold */
+#define PCI_DEVICE_ID_MEILHAUS_ME4680IS 0x4683 /* Isolated version with Sample and Hold */
/*=============================================================================
ME-4000 base register offsets
===========================================================================*/
-#define ME4000_AO_00_CTRL_REG 0x00 // R/W
-#define ME4000_AO_00_STATUS_REG 0x04 // R/_
-#define ME4000_AO_00_FIFO_REG 0x08 // _/W
-#define ME4000_AO_00_SINGLE_REG 0x0C // R/W
-#define ME4000_AO_00_TIMER_REG 0x10 // _/W
-
-#define ME4000_AO_01_CTRL_REG 0x18 // R/W
-#define ME4000_AO_01_STATUS_REG 0x1C // R/_
-#define ME4000_AO_01_FIFO_REG 0x20 // _/W
-#define ME4000_AO_01_SINGLE_REG 0x24 // R/W
-#define ME4000_AO_01_TIMER_REG 0x28 // _/W
-
-#define ME4000_AO_02_CTRL_REG 0x30 // R/W
-#define ME4000_AO_02_STATUS_REG 0x34 // R/_
-#define ME4000_AO_02_FIFO_REG 0x38 // _/W
-#define ME4000_AO_02_SINGLE_REG 0x3C // R/W
-#define ME4000_AO_02_TIMER_REG 0x40 // _/W
-
-#define ME4000_AO_03_CTRL_REG 0x48 // R/W
-#define ME4000_AO_03_STATUS_REG 0x4C // R/_
-#define ME4000_AO_03_FIFO_REG 0x50 // _/W
-#define ME4000_AO_03_SINGLE_REG 0x54 // R/W
-#define ME4000_AO_03_TIMER_REG 0x58 // _/W
-
-#define ME4000_AI_CTRL_REG 0x74 // _/W
-#define ME4000_AI_STATUS_REG 0x74 // R/_
-#define ME4000_AI_CHANNEL_LIST_REG 0x78 // _/W
-#define ME4000_AI_DATA_REG 0x7C // R/_
-#define ME4000_AI_CHAN_TIMER_REG 0x80 // _/W
-#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84 // _/W
-#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88 // _/W
-#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8C // _/W
-#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90 // _/W
-#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 // _/W
-#define ME4000_AI_START_REG 0x98 // R/_
-
-#define ME4000_IRQ_STATUS_REG 0x9C // R/_
-
-#define ME4000_DIO_PORT_0_REG 0xA0 // R/W
-#define ME4000_DIO_PORT_1_REG 0xA4 // R/W
-#define ME4000_DIO_PORT_2_REG 0xA8 // R/W
-#define ME4000_DIO_PORT_3_REG 0xAC // R/W
-#define ME4000_DIO_DIR_REG 0xB0 // R/W
-
-#define ME4000_AO_LOADSETREG_XX 0xB4 // R/W
-
-#define ME4000_DIO_CTRL_REG 0xB8 // R/W
-
-#define ME4000_AO_DEMUX_ADJUST_REG 0xBC // -/W
-
-#define ME4000_AI_SAMPLE_COUNTER_REG 0xC0 // _/W
+#define ME4000_AO_00_CTRL_REG 0x00 /* R/W */
+#define ME4000_AO_00_STATUS_REG 0x04 /* R/_ */
+#define ME4000_AO_00_FIFO_REG 0x08 /* _/W */
+#define ME4000_AO_00_SINGLE_REG 0x0C /* R/W */
+#define ME4000_AO_00_TIMER_REG 0x10 /* _/W */
+
+#define ME4000_AO_01_CTRL_REG 0x18 /* R/W */
+#define ME4000_AO_01_STATUS_REG 0x1C /* R/_ */
+#define ME4000_AO_01_FIFO_REG 0x20 /* _/W */
+#define ME4000_AO_01_SINGLE_REG 0x24 /* R/W */
+#define ME4000_AO_01_TIMER_REG 0x28 /* _/W */
+
+#define ME4000_AO_02_CTRL_REG 0x30 /* R/W */
+#define ME4000_AO_02_STATUS_REG 0x34 /* R/_ */
+#define ME4000_AO_02_FIFO_REG 0x38 /* _/W */
+#define ME4000_AO_02_SINGLE_REG 0x3C /* R/W */
+#define ME4000_AO_02_TIMER_REG 0x40 /* _/W */
+
+#define ME4000_AO_03_CTRL_REG 0x48 /* R/W */
+#define ME4000_AO_03_STATUS_REG 0x4C /* R/_ */
+#define ME4000_AO_03_FIFO_REG 0x50 /* _/W */
+#define ME4000_AO_03_SINGLE_REG 0x54 /* R/W */
+#define ME4000_AO_03_TIMER_REG 0x58 /* _/W */
+
+#define ME4000_AI_CTRL_REG 0x74 /* _/W */
+#define ME4000_AI_STATUS_REG 0x74 /* R/_ */
+#define ME4000_AI_CHANNEL_LIST_REG 0x78 /* _/W */
+#define ME4000_AI_DATA_REG 0x7C /* R/_ */
+#define ME4000_AI_CHAN_TIMER_REG 0x80 /* _/W */
+#define ME4000_AI_CHAN_PRE_TIMER_REG 0x84 /* _/W */
+#define ME4000_AI_SCAN_TIMER_LOW_REG 0x88 /* _/W */
+#define ME4000_AI_SCAN_TIMER_HIGH_REG 0x8C /* _/W */
+#define ME4000_AI_SCAN_PRE_TIMER_LOW_REG 0x90 /* _/W */
+#define ME4000_AI_SCAN_PRE_TIMER_HIGH_REG 0x94 /* _/W */
+#define ME4000_AI_START_REG 0x98 /* R/_ */
+
+#define ME4000_IRQ_STATUS_REG 0x9C /* R/_ */
+
+#define ME4000_DIO_PORT_0_REG 0xA0 /* R/W */
+#define ME4000_DIO_PORT_1_REG 0xA4 /* R/W */
+#define ME4000_DIO_PORT_2_REG 0xA8 /* R/W */
+#define ME4000_DIO_PORT_3_REG 0xAC /* R/W */
+#define ME4000_DIO_DIR_REG 0xB0 /* R/W */
+
+#define ME4000_AO_LOADSETREG_XX 0xB4 /* R/W */
+
+#define ME4000_DIO_CTRL_REG 0xB8 /* R/W */
+
+#define ME4000_AO_DEMUX_ADJUST_REG 0xBC /* -/W */
+
+#define ME4000_AI_SAMPLE_COUNTER_REG 0xC0 /* _/W */
/*=============================================================================
Value to adjust Demux
@@ -159,21 +159,21 @@
PLX base register offsets
===========================================================================*/
-#define PLX_INTCSR 0x4C // Interrupt control and status register
-#define PLX_ICR 0x50 // Initialization control register
+#define PLX_INTCSR 0x4C /* Interrupt control and status register */
+#define PLX_ICR 0x50 /* Initialization control register */
/*=============================================================================
Bits for the PLX_ICSR register
===========================================================================*/
-#define PLX_INTCSR_LOCAL_INT1_EN 0x01 // If set, local interrupt 1 is enabled (r/w)
-#define PLX_INTCSR_LOCAL_INT1_POL 0x02 // If set, local interrupt 1 polarity is active high (r/w)
-#define PLX_INTCSR_LOCAL_INT1_STATE 0x04 // If set, local interrupt 1 is active (r/_)
-#define PLX_INTCSR_LOCAL_INT2_EN 0x08 // If set, local interrupt 2 is enabled (r/w)
-#define PLX_INTCSR_LOCAL_INT2_POL 0x10 // If set, local interrupt 2 polarity is active high (r/w)
-#define PLX_INTCSR_LOCAL_INT2_STATE 0x20 // If set, local interrupt 2 is active (r/_)
-#define PLX_INTCSR_PCI_INT_EN 0x40 // If set, PCI interrupt is enabled (r/w)
-#define PLX_INTCSR_SOFT_INT 0x80 // If set, a software interrupt is generated (r/w)
+#define PLX_INTCSR_LOCAL_INT1_EN 0x01 /* If set, local interrupt 1 is enabled (r/w) */
+#define PLX_INTCSR_LOCAL_INT1_POL 0x02 /* If set, local interrupt 1 polarity is active high (r/w) */
+#define PLX_INTCSR_LOCAL_INT1_STATE 0x04 /* If set, local interrupt 1 is active (r/_) */
+#define PLX_INTCSR_LOCAL_INT2_EN 0x08 /* If set, local interrupt 2 is enabled (r/w) */
+#define PLX_INTCSR_LOCAL_INT2_POL 0x10 /* If set, local interrupt 2 polarity is active high (r/w) */
+#define PLX_INTCSR_LOCAL_INT2_STATE 0x20 /* If set, local interrupt 2 is active (r/_) */
+#define PLX_INTCSR_PCI_INT_EN 0x40 /* If set, PCI interrupt is enabled (r/w) */
+#define PLX_INTCSR_SOFT_INT 0x80 /* If set, a software interrupt is generated (r/w) */
/*=============================================================================
Bits for the PLX_ICR register
@@ -293,45 +293,45 @@
Information about the hardware capabilities
===========================================================================*/
-typedef struct me4000_ao_info {
+struct me4000_ao_info {
int count;
int fifo_count;
-} me4000_ao_info_t;
+};
-typedef struct me4000_ai_info {
+struct me4000_ai_info {
int count;
int sh_count;
int diff_count;
int ex_trig_analog;
-} me4000_ai_info_t;
+};
-typedef struct me4000_dio_info {
+struct me4000_dio_info {
int count;
-} me4000_dio_info_t;
+};
-typedef struct me4000_cnt_info {
+struct me4000_cnt_info {
int count;
-} me4000_cnt_info_t;
+};
-typedef struct me4000_board {
+struct me4000_board {
const char *name;
unsigned short device_id;
- me4000_ao_info_t ao;
- me4000_ai_info_t ai;
- me4000_dio_info_t dio;
- me4000_cnt_info_t cnt;
-} me4000_board_t;
+ struct me4000_ao_info ao;
+ struct me4000_ai_info ai;
+ struct me4000_dio_info dio;
+ struct me4000_cnt_info cnt;
+};
-#define thisboard ((const me4000_board_t *)dev->board_ptr)
+#define thisboard ((const struct me4000_board *)dev->board_ptr)
/*=============================================================================
Global board and subdevice information structures
===========================================================================*/
-typedef struct me4000_ao_context {
+struct me4000_ao_context {
int irq;
- unsigned long mirror; // Store the last written value
+ unsigned long mirror; /* Store the last written value */
unsigned long ctrl_reg;
unsigned long status_reg;
@@ -340,9 +340,9 @@ typedef struct me4000_ao_context {
unsigned long timer_reg;
unsigned long irq_status_reg;
unsigned long preload_reg;
-} me4000_ao_context_t;
+};
-typedef struct me4000_ai_context {
+struct me4000_ai_context {
int irq;
unsigned long ctrl_reg;
@@ -358,51 +358,51 @@ typedef struct me4000_ai_context {
unsigned long start_reg;
unsigned long irq_status_reg;
unsigned long sample_counter_reg;
-} me4000_ai_context_t;
+};
-typedef struct me4000_dio_context {
+struct me4000_dio_context {
unsigned long dir_reg;
unsigned long ctrl_reg;
unsigned long port_0_reg;
unsigned long port_1_reg;
unsigned long port_2_reg;
unsigned long port_3_reg;
-} me4000_dio_context_t;
+};
-typedef struct me4000_cnt_context {
+struct me4000_cnt_context {
unsigned long ctrl_reg;
unsigned long counter_0_reg;
unsigned long counter_1_reg;
unsigned long counter_2_reg;
-} me4000_cnt_context_t;
+};
-typedef struct me4000_info {
- unsigned long plx_regbase; // PLX configuration space base address
- unsigned long me4000_regbase; // Base address of the ME4000
- unsigned long timer_regbase; // Base address of the timer circuit
- unsigned long program_regbase; // Base address to set the program pin for the xilinx
+struct me4000_info {
+ unsigned long plx_regbase; /* PLX configuration space base address */
+ unsigned long me4000_regbase; /* Base address of the ME4000 */
+ unsigned long timer_regbase; /* Base address of the timer circuit */
+ unsigned long program_regbase; /* Base address to set the program pin for the xilinx */
- unsigned long plx_regbase_size; // PLX register set space
- unsigned long me4000_regbase_size; // ME4000 register set space
- unsigned long timer_regbase_size; // Timer circuit register set space
- unsigned long program_regbase_size; // Size of program base address of the ME4000
+ unsigned long plx_regbase_size; /* PLX register set space */
+ unsigned long me4000_regbase_size; /* ME4000 register set space */
+ unsigned long timer_regbase_size; /* Timer circuit register set space */
+ unsigned long program_regbase_size; /* Size of program base address of the ME4000 */
- unsigned int serial_no; // Serial number of the board
- unsigned char hw_revision; // Hardware revision of the board
- unsigned short vendor_id; // Meilhaus vendor id
- unsigned short device_id; // Device id
+ unsigned int serial_no; /* Serial number of the board */
+ unsigned char hw_revision; /* Hardware revision of the board */
+ unsigned short vendor_id; /* Meilhaus vendor id */
+ unsigned short device_id; /* Device id */
- struct pci_dev *pci_dev_p; // General PCI information
+ struct pci_dev *pci_dev_p; /* General PCI information */
- unsigned int irq; // IRQ assigned from the PCI BIOS
+ unsigned int irq; /* IRQ assigned from the PCI BIOS */
- struct me4000_ai_context ai_context; // Analog input specific context
- struct me4000_ao_context ao_context[4]; // Vector with analog output specific context
- struct me4000_dio_context dio_context; // Digital I/O specific context
- struct me4000_cnt_context cnt_context; // Counter specific context
-} me4000_info_t;
+ struct me4000_ai_context ai_context; /* Analog input specific context */
+ struct me4000_ao_context ao_context[4]; /* Vector with analog output specific context */
+ struct me4000_dio_context dio_context; /* Digital I/O specific context */
+ struct me4000_cnt_context cnt_context; /* Counter specific context */
+};
-#define info ((me4000_info_t *)dev->private)
+#define info ((struct me4000_info *)dev->private)
/*-----------------------------------------------------------------------------
Defines for analog input
@@ -412,7 +412,7 @@ typedef struct me4000_info {
#define ME4000_AI_FIFO_COUNT 2048
#define ME4000_AI_MIN_TICKS 66
-#define ME4000_AI_MIN_SAMPLE_TIME 2000 // Minimum sample time [ns]
+#define ME4000_AI_MIN_SAMPLE_TIME 2000 /* Minimum sample time [ns] */
#define ME4000_AI_BASE_FREQUENCY (unsigned int) 33E6
/* Channel list defines and masks */
@@ -436,11 +436,11 @@ typedef struct me4000_info {
#define ME4000_CNT_COUNTER_1 0x40
#define ME4000_CNT_COUNTER_2 0x80
-#define ME4000_CNT_MODE_0 0x00 // Change state if zero crossing
-#define ME4000_CNT_MODE_1 0x02 // Retriggerable One-Shot
-#define ME4000_CNT_MODE_2 0x04 // Asymmetrical divider
-#define ME4000_CNT_MODE_3 0x06 // Symmetrical divider
-#define ME4000_CNT_MODE_4 0x08 // Counter start by software trigger
-#define ME4000_CNT_MODE_5 0x0A // Counter start by hardware trigger
+#define ME4000_CNT_MODE_0 0x00 /* Change state if zero crossing */
+#define ME4000_CNT_MODE_1 0x02 /* Retriggerable One-Shot */
+#define ME4000_CNT_MODE_2 0x04 /* Asymmetrical divider */
+#define ME4000_CNT_MODE_3 0x06 /* Symmetrical divider */
+#define ME4000_CNT_MODE_4 0x08 /* Counter start by software trigger */
+#define ME4000_CNT_MODE_5 0x0A /* Counter start by hardware trigger */
#endif
diff --git a/drivers/staging/comedi/drivers/me_daq.c b/drivers/staging/comedi/drivers/me_daq.c
index 6accec20a0f..0f023d009e6 100644
--- a/drivers/staging/comedi/drivers/me_daq.c
+++ b/drivers/staging/comedi/drivers/me_daq.c
@@ -144,10 +144,10 @@ from http://www.comedi.org
#define ME_COUNTER_VALUE_B 0x0022 /* R | - */
/* Function prototypes */
-static int me_attach(comedi_device *dev, comedi_devconfig *it);
-static int me_detach(comedi_device *dev);
+static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int me_detach(struct comedi_device *dev);
-static const comedi_lrange me2000_ai_range = {
+static const struct comedi_lrange me2000_ai_range = {
8,
{
BIP_RANGE(10),
@@ -161,7 +161,7 @@ static const comedi_lrange me2000_ai_range = {
}
};
-static const comedi_lrange me2600_ai_range = {
+static const struct comedi_lrange me2600_ai_range = {
8,
{
BIP_RANGE(10),
@@ -175,7 +175,7 @@ static const comedi_lrange me2600_ai_range = {
}
};
-static const comedi_lrange me2600_ao_range = {
+static const struct comedi_lrange me2600_ao_range = {
3,
{
BIP_RANGE(10),
@@ -201,11 +201,11 @@ struct me_board {
int ao_channel_nbr; /* DA config */
int ao_resolution;
int ao_resolution_mask;
- const comedi_lrange *ao_range_list;
+ const struct comedi_lrange *ao_range_list;
int ai_channel_nbr; /* AD config */
int ai_resolution;
int ai_resolution_mask;
- const comedi_lrange *ai_range_list;
+ const struct comedi_lrange *ai_range_list;
int dio_channel_nbr; /* DIO config */
};
@@ -246,7 +246,8 @@ static const struct me_board me_boards[] = {
#define me_board_nbr (sizeof(me_boards)/sizeof(struct me_board))
-static comedi_driver me_driver = {
+
+static struct comedi_driver me_driver = {
.driver_name = ME_DRIVER_NAME,
.module = THIS_MODULE,
.attach = me_attach,
@@ -290,8 +291,8 @@ static inline void sleep(unsigned sec)
*
* ------------------------------------------------------------------
*/
-static int me_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int bits;
int mask = 1 << CR_CHAN(insn->chanspec);
@@ -326,8 +327,8 @@ static int me_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
}
/* Digital instant input/outputs */
-static int me_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
unsigned int mask = data[0];
s->state &= ~mask;
@@ -362,8 +363,8 @@ static int me_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
*/
/* Analog instant input */
-static int me_ai_insn_read(comedi_device *dev, comedi_subdevice *subdevice,
- comedi_insn *insn, lsampl_t *data)
+static int me_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *subdevice,
+ struct comedi_insn *insn, unsigned int *data)
{
unsigned short value;
int chan = CR_CHAN((&insn->chanspec)[0]);
@@ -436,7 +437,7 @@ static int me_ai_insn_read(comedi_device *dev, comedi_subdevice *subdevice,
*/
/* Cancel analog input autoscan */
-static int me_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int me_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
/* disable interrupts */
@@ -448,14 +449,14 @@ static int me_ai_cancel(comedi_device *dev, comedi_subdevice *s)
}
/* Test analog input command */
-static int me_ai_do_cmd_test(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int me_ai_do_cmd_test(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
return 0;
}
/* Analog input command */
-static int me_ai_do_cmd(comedi_device *dev, comedi_subdevice *subdevice)
+static int me_ai_do_cmd(struct comedi_device *dev, struct comedi_subdevice *subdevice)
{
return 0;
}
@@ -469,8 +470,8 @@ static int me_ai_do_cmd(comedi_device *dev, comedi_subdevice *subdevice)
*/
/* Analog instant output */
-static int me_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int chan;
int rang;
@@ -519,8 +520,8 @@ static int me_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
}
/* Analog output readback */
-static int me_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int me_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
@@ -541,7 +542,7 @@ static int me_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
*/
/* Xilinx firmware download for card: ME-2600i */
-static int me2600_xilinx_download(comedi_device *dev,
+static int me2600_xilinx_download(struct comedi_device *dev,
unsigned char *me2600_firmware,
unsigned int length)
{
@@ -609,7 +610,7 @@ static int me2600_xilinx_download(comedi_device *dev,
}
/* Reset device */
-static int me_reset(comedi_device *dev)
+static int me_reset(struct comedi_device *dev)
{
/* Reset board */
writew(0x00, dev_private->me_regbase + ME_CONTROL_1);
@@ -631,10 +632,10 @@ static int me_reset(comedi_device *dev)
* - Register PCI device
* - Declare device driver capability
*/
-static int me_attach(comedi_device *dev, comedi_devconfig *it)
+static int me_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
struct pci_dev *pci_device;
- comedi_subdevice *subdevice;
+ struct comedi_subdevice *subdevice;
struct me_board *board;
resource_size_t plx_regbase_tmp;
unsigned long plx_regbase_size_tmp;
@@ -825,7 +826,7 @@ found:
}
/* Detach */
-static int me_detach(comedi_device *dev)
+static int me_detach(struct comedi_device *dev)
{
if (dev_private) {
if (dev_private->me_regbase) {
diff --git a/drivers/staging/comedi/drivers/mite.c b/drivers/staging/comedi/drivers/mite.c
index 9cc527424d0..ae901774453 100644
--- a/drivers/staging/comedi/drivers/mite.c
+++ b/drivers/staging/comedi/drivers/mite.c
@@ -47,7 +47,7 @@
*/
-//#define USE_KMALLOC
+/* #define USE_KMALLOC */
#include "mite.h"
@@ -63,7 +63,7 @@
MODULE_LICENSE("GPL");
-struct mite_struct *mite_devices = NULL;
+struct mite_struct *mite_devices;
#define TOP_OF_PAGE(x) ((x)|(~(PAGE_MASK)))
@@ -103,7 +103,7 @@ static void dump_chip_signature(u32 csigr_bits)
printk("mite: num channels = %i, write post fifo depth = %i, wins = %i, iowins = %i\n", mite_csigr_dmac(csigr_bits), mite_csigr_wpdep(csigr_bits), mite_csigr_wins(csigr_bits), mite_csigr_iowins(csigr_bits));
}
-unsigned mite_fifo_size(struct mite_struct * mite, unsigned channel)
+unsigned mite_fifo_size(struct mite_struct *mite, unsigned channel)
{
unsigned fcr_bits = readl(mite->mite_io_addr +
MITE_FCR(channel));
@@ -139,7 +139,7 @@ int mite_setup2(struct mite_struct *mite, unsigned use_iodwbsr_1)
addr = pci_resource_start(mite->pcidev, 1);
mite->daq_phys_addr = addr;
length = pci_resource_len(mite->pcidev, 1);
- // In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output)
+ /* In case of a 660x board, DAQ size is 8k instead of 4k (see as shown by lspci output) */
mite->daq_io_addr = ioremap(mite->daq_phys_addr, length);
if (!mite->daq_io_addr) {
printk("failed to remap daq io memory address\n");
@@ -212,7 +212,7 @@ void mite_cleanup(void)
void mite_unsetup(struct mite_struct *mite)
{
- //unsigned long offset, start, length;
+ /* unsigned long offset, start, length; */
if (!mite)
return;
@@ -257,7 +257,7 @@ struct mite_channel *mite_request_channel_in_range(struct mite_struct *mite,
unsigned long flags;
struct mite_channel *channel = NULL;
- // spin lock so mite_release_channel can be called safely from interrupts
+ /* spin lock so mite_release_channel can be called safely from interrupts */
comedi_spin_lock_irqsave(&mite->lock, flags);
for (i = min_channel; i <= max_channel; ++i) {
if (mite->channel_allocated[i] == 0) {
@@ -276,7 +276,7 @@ void mite_release_channel(struct mite_channel *mite_chan)
struct mite_struct *mite = mite_chan->mite;
unsigned long flags;
- // spin lock to prevent races with mite_request_channel
+ /* spin lock to prevent races with mite_request_channel */
comedi_spin_lock_irqsave(&mite->lock, flags);
if (mite->channel_allocated[mite_chan->channel]) {
mite_dma_disarm(mite_chan);
@@ -312,12 +312,12 @@ void mite_dma_arm(struct mite_channel *mite_chan)
writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
mmiowb();
comedi_spin_unlock_irqrestore(&mite->lock, flags);
-// mite_dma_tcr(mite, channel);
+/* mite_dma_tcr(mite, channel); */
}
/**************************************/
-int mite_buf_change(struct mite_dma_descriptor_ring *ring, comedi_async * async)
+int mite_buf_change(struct mite_dma_descriptor_ring *ring, struct comedi_async * async)
{
unsigned int n_links;
int i;
@@ -331,9 +331,9 @@ int mite_buf_change(struct mite_dma_descriptor_ring *ring, comedi_async * async)
ring->descriptors_dma_addr = 0;
ring->n_links = 0;
- if (async->prealloc_bufsz == 0) {
+ if (async->prealloc_bufsz == 0)
return 0;
- }
+
n_links = async->prealloc_bufsz >> PAGE_SHIFT;
MDPRINTK("ring->hw_dev=%p, n_links=0x%04x\n", ring->hw_dev, n_links);
@@ -395,9 +395,9 @@ void mite_prep_dma(struct mite_channel *mite_chan,
on e-series boards. */
chcr |= CHCR_BYTE_SWAP_DEVICE | CHCR_BYTE_SWAP_MEMORY;
}
- if (mite_chan->dir == COMEDI_INPUT) {
+ if (mite_chan->dir == COMEDI_INPUT)
chcr |= CHCR_DEV_TO_MEM;
- }
+
writel(chcr, mite->mite_io_addr + MITE_CHCR(mite_chan->channel));
/* to/from memory */
@@ -459,15 +459,15 @@ u32 mite_device_bytes_transferred(struct mite_channel *mite_chan)
return readl(mite->mite_io_addr + MITE_DAR(mite_chan->channel));
}
-u32 mite_bytes_in_transit(struct mite_channel * mite_chan)
+u32 mite_bytes_in_transit(struct mite_channel *mite_chan)
{
struct mite_struct *mite = mite_chan->mite;
return readl(mite->mite_io_addr +
MITE_FCR(mite_chan->channel)) & 0x000000FF;
}
-// returns lower bound for number of bytes transferred from device to memory
-u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
+/* returns lower bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan)
{
u32 device_byte_count;
@@ -475,8 +475,8 @@ u32 mite_bytes_written_to_memory_lb(struct mite_channel * mite_chan)
return device_byte_count - mite_bytes_in_transit(mite_chan);
}
-// returns upper bound for number of bytes transferred from device to memory
-u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
+/* returns upper bound for number of bytes transferred from device to memory */
+u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan)
{
u32 in_transit_count;
@@ -484,8 +484,8 @@ u32 mite_bytes_written_to_memory_ub(struct mite_channel * mite_chan)
return mite_device_bytes_transferred(mite_chan) - in_transit_count;
}
-// returns lower bound for number of bytes read from memory for transfer to device
-u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
+/* returns lower bound for number of bytes read from memory for transfer to device */
+u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan)
{
u32 device_byte_count;
@@ -493,8 +493,8 @@ u32 mite_bytes_read_from_memory_lb(struct mite_channel * mite_chan)
return device_byte_count + mite_bytes_in_transit(mite_chan);
}
-// returns upper bound for number of bytes read from memory for transfer to device
-u32 mite_bytes_read_from_memory_ub(struct mite_channel * mite_chan)
+/* returns upper bound for number of bytes read from memory for transfer to device */
+u32 mite_bytes_read_from_memory_ub(struct mite_channel *mite_chan)
{
u32 in_transit_count;
@@ -526,14 +526,14 @@ void mite_dma_disarm(struct mite_channel *mite_chan)
writel(chor, mite->mite_io_addr + MITE_CHOR(mite_chan->channel));
}
-int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async)
+int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async)
{
int count;
unsigned int nbytes, old_alloc_count;
const unsigned bytes_per_scan = cfc_bytes_per_scan(async->subdevice);
old_alloc_count = async->buf_write_alloc_count;
- // write alloc as much as we can
+ /* write alloc as much as we can */
comedi_buf_write_alloc(async, async->prealloc_bufsz);
nbytes = mite_bytes_written_to_memory_lb(mite_chan);
@@ -547,9 +547,9 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async)
count = nbytes - async->buf_write_count;
/* it's possible count will be negative due to
* conservative value returned by mite_bytes_written_to_memory_lb */
- if (count <= 0) {
+ if (count <= 0)
return 0;
- }
+
comedi_buf_write_free(async, count);
async->scan_progress += count;
@@ -561,7 +561,7 @@ int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async)
return 0;
}
-int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async)
+int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async)
{
int count;
u32 nbytes_ub, nbytes_lb;
@@ -570,7 +570,7 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async)
async->cmd.stop_arg * cfc_bytes_per_scan(async->subdevice);
old_alloc_count = async->buf_read_alloc_count;
- // read alloc as much as we can
+ /* read alloc as much as we can */
comedi_buf_read_alloc(async, async->prealloc_bufsz);
nbytes_lb = mite_bytes_read_from_memory_lb(mite_chan);
if (async->cmd.stop_src == TRIG_COUNT &&
@@ -586,9 +586,9 @@ int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async)
return -1;
}
count = nbytes_lb - async->buf_read_count;
- if (count <= 0) {
+ if (count <= 0)
return 0;
- }
+
if (count) {
comedi_buf_read_free(async, count);
async->events |= COMEDI_CB_BLOCK;
@@ -753,9 +753,8 @@ static void mite_decode(char **bit_str, unsigned int bits)
int i;
for (i = 31; i >= 0; i--) {
- if (bits & (1 << i)) {
+ if (bits & (1 << i))
printk(" %s", bit_str[i]);
- }
}
printk("\n");
}
diff --git a/drivers/staging/comedi/drivers/mite.h b/drivers/staging/comedi/drivers/mite.h
index b84eafa6ff2..cdaf8a31688 100644
--- a/drivers/staging/comedi/drivers/mite.h
+++ b/drivers/staging/comedi/drivers/mite.h
@@ -29,13 +29,13 @@
#define PCI_VENDOR_ID_NATINST 0x1093
-// #define DEBUG_MITE
+/* #define DEBUG_MITE */
#define PCIMIO_COMPAT
#ifdef DEBUG_MITE
-#define MDPRINTK(format,args...) printk(format , ## args )
+#define MDPRINTK(format, args...) printk(format , ## args)
#else
-#define MDPRINTK(format,args...)
+#define MDPRINTK(format, args...)
#endif
#define MAX_MITE_DMA_CHANNELS 8
@@ -142,8 +142,8 @@ void mite_release_channel(struct mite_channel *mite_chan);
unsigned mite_dma_tcr(struct mite_channel *mite_chan);
void mite_dma_arm(struct mite_channel *mite_chan);
void mite_dma_disarm(struct mite_channel *mite_chan);
-int mite_sync_input_dma(struct mite_channel *mite_chan, comedi_async * async);
-int mite_sync_output_dma(struct mite_channel *mite_chan, comedi_async * async);
+int mite_sync_input_dma(struct mite_channel *mite_chan, struct comedi_async * async);
+int mite_sync_output_dma(struct mite_channel *mite_chan, struct comedi_async * async);
u32 mite_bytes_written_to_memory_lb(struct mite_channel *mite_chan);
u32 mite_bytes_written_to_memory_ub(struct mite_channel *mite_chan);
u32 mite_bytes_read_from_memory_lb(struct mite_channel *mite_chan);
@@ -153,7 +153,7 @@ unsigned mite_get_status(struct mite_channel *mite_chan);
int mite_done(struct mite_channel *mite_chan);
#if 0
-unsigned long mite_ll_from_kvmem(struct mite_struct *mite, comedi_async * async,
+unsigned long mite_ll_from_kvmem(struct mite_struct *mite, struct comedi_async * async,
int len);
void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan,
int dir);
@@ -162,7 +162,7 @@ void mite_setregs(struct mite_struct *mite, unsigned long ll_start, int chan,
void mite_prep_dma(struct mite_channel *mite_chan,
unsigned int num_device_bits, unsigned int num_memory_bits);
int mite_buf_change(struct mite_dma_descriptor_ring *ring,
- comedi_async * async);
+ struct comedi_async *async);
#ifdef DEBUG_MITE
void mite_print_chsr(unsigned int chsr);
@@ -179,83 +179,83 @@ enum mite_registers {
written and read back. The bits 0x1f always read as 1.
The rest always read as zero. */
MITE_UNKNOWN_DMA_BURST_REG = 0x28,
- MITE_IODWBSR = 0xc0, //IO Device Window Base Size Register
- MITE_IODWBSR_1 = 0xc4, // IO Device Window Base Size Register 1
+ MITE_IODWBSR = 0xc0, /* IO Device Window Base Size Register */
+ MITE_IODWBSR_1 = 0xc4, /* IO Device Window Base Size Register 1 */
MITE_IODWCR_1 = 0xf4,
MITE_PCI_CONFIG_OFFSET = 0x300,
- MITE_CSIGR = 0x460 //chip signature
+ MITE_CSIGR = 0x460 /* chip signature */
};
-static inline int MITE_CHOR(int channel) // channel operation
+static inline int MITE_CHOR(int channel) /* channel operation */
{
return CHAN_OFFSET(channel) + 0x0;
};
-static inline int MITE_CHCR(int channel) // channel control
+static inline int MITE_CHCR(int channel) /* channel control */
{
return CHAN_OFFSET(channel) + 0x4;
};
-static inline int MITE_TCR(int channel) // transfer count
+static inline int MITE_TCR(int channel) /* transfer count */
{
return CHAN_OFFSET(channel) + 0x8;
};
-static inline int MITE_MCR(int channel) // memory configuration
+static inline int MITE_MCR(int channel) /* memory configuration */
{
return CHAN_OFFSET(channel) + 0xc;
};
-static inline int MITE_MAR(int channel) // memory address
+static inline int MITE_MAR(int channel) /* memory address */
{
return CHAN_OFFSET(channel) + 0x10;
};
-static inline int MITE_DCR(int channel) // device configuration
+static inline int MITE_DCR(int channel) /* device configuration */
{
return CHAN_OFFSET(channel) + 0x14;
};
-static inline int MITE_DAR(int channel) // device address
+static inline int MITE_DAR(int channel) /* device address */
{
return CHAN_OFFSET(channel) + 0x18;
};
-static inline int MITE_LKCR(int channel) // link configuration
+static inline int MITE_LKCR(int channel) /* link configuration */
{
return CHAN_OFFSET(channel) + 0x1c;
};
-static inline int MITE_LKAR(int channel) // link address
+static inline int MITE_LKAR(int channel) /* link address */
{
return CHAN_OFFSET(channel) + 0x20;
};
-static inline int MITE_LLKAR(int channel) // see mite section of tnt5002 manual
+static inline int MITE_LLKAR(int channel) /* see mite section of tnt5002 manual */
{
return CHAN_OFFSET(channel) + 0x24;
};
-static inline int MITE_BAR(int channel) // base address
+static inline int MITE_BAR(int channel) /* base address */
{
return CHAN_OFFSET(channel) + 0x28;
};
-static inline int MITE_BCR(int channel) // base count
+static inline int MITE_BCR(int channel) /* base count */
{
return CHAN_OFFSET(channel) + 0x2c;
};
-static inline int MITE_SAR(int channel) // ? address
+static inline int MITE_SAR(int channel) /* ? address */
{
return CHAN_OFFSET(channel) + 0x30;
};
-static inline int MITE_WSCR(int channel) // ?
+static inline int MITE_WSCR(int channel) /* ? */
{
return CHAN_OFFSET(channel) + 0x34;
};
-static inline int MITE_WSER(int channel) // ?
+static inline int MITE_WSER(int channel) /* ? */
{
return CHAN_OFFSET(channel) + 0x38;
};
-static inline int MITE_CHSR(int channel) // channel status
+static inline int MITE_CHSR(int channel) /* channel status */
{
return CHAN_OFFSET(channel) + 0x3c;
};
-static inline int MITE_FCR(int channel) // fifo count
+static inline int MITE_FCR(int channel) /* fifo count */
{
return CHAN_OFFSET(channel) + 0x40;
};
enum MITE_IODWBSR_bits {
- WENAB = 0x80, // window enable
+ WENAB = 0x80, /* window enable */
};
static inline unsigned MITE_IODWBSR_1_WSIZE_bits(unsigned size)
@@ -276,23 +276,23 @@ static inline int mite_csigr_version(u32 csigr_bits)
return csigr_bits & 0xf;
};
static inline int mite_csigr_type(u32 csigr_bits)
-{ // original mite = 0, minimite = 1
+{ /* original mite = 0, minimite = 1 */
return (csigr_bits >> 4) & 0xf;
};
static inline int mite_csigr_mmode(u32 csigr_bits)
-{ // mite mode, minimite = 1
+{ /* mite mode, minimite = 1 */
return (csigr_bits >> 8) & 0x3;
};
static inline int mite_csigr_imode(u32 csigr_bits)
-{ // cpu port interface mode, pci = 0x3
+{ /* cpu port interface mode, pci = 0x3 */
return (csigr_bits >> 12) & 0x3;
};
static inline int mite_csigr_dmac(u32 csigr_bits)
-{ // number of dma channels
+{ /* number of dma channels */
return (csigr_bits >> 16) & 0xf;
};
static inline int mite_csigr_wpdep(u32 csigr_bits)
-{ // write post fifo depth
+{ /* write post fifo depth */
unsigned int wpdep_bits = (csigr_bits >> 20) & 0x7;
if (wpdep_bits == 0)
return 0;
@@ -304,7 +304,7 @@ static inline int mite_csigr_wins(u32 csigr_bits)
return (csigr_bits >> 24) & 0x1f;
};
static inline int mite_csigr_iowins(u32 csigr_bits)
-{ // number of io windows
+{ /* number of io windows */
return (csigr_bits >> 29) & 0x7;
};
diff --git a/drivers/staging/comedi/drivers/mpc624.c b/drivers/staging/comedi/drivers/mpc624.c
new file mode 100644
index 00000000000..a151602929d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/mpc624.c
@@ -0,0 +1,386 @@
+/*
+ comedi/drivers/mpc624.c
+ Hardware driver for a Micro/sys inc. MPC-624 PC/104 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: mpc624
+Description: Micro/sys MPC-624 PC/104 board
+Devices: [Micro/sys] MPC-624 (mpc624)
+Author: Stanislaw Raczynski <sraczynski@op.pl>
+Updated: Thu, 15 Sep 2005 12:01:18 +0200
+Status: working
+
+ The Micro/sys MPC-624 board is based on the LTC2440 24-bit sigma-delta
+ ADC chip.
+
+ Subdevices supported by the driver:
+ - Analog In: supported
+ - Digital I/O: not supported
+ - LEDs: not supported
+ - EEPROM: not supported
+
+Configuration Options:
+ [0] - I/O base address
+ [1] - convertion rate
+ Convertion rate RMS noise Effective Number Of Bits
+ 0 3.52kHz 23uV 17
+ 1 1.76kHz 3.5uV 20
+ 2 880Hz 2uV 21.3
+ 3 440Hz 1.4uV 21.8
+ 4 220Hz 1uV 22.4
+ 5 110Hz 750uV 22.9
+ 6 55Hz 510nV 23.4
+ 7 27.5Hz 375nV 24
+ 8 13.75Hz 250nV 24.4
+ 9 6.875Hz 200nV 24.6
+ [2] - voltage range
+ 0 -1.01V .. +1.01V
+ 1 -10.1V .. +10.1V
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+// Consecutive I/O port addresses
+#define MPC624_SIZE 16
+
+// Offsets of different ports
+#define MPC624_MASTER_CONTROL 0 // not used
+#define MPC624_GNMUXCH 1 // Gain, Mux, Channel of ADC
+#define MPC624_ADC 2 // read/write to/from ADC
+#define MPC624_EE 3 // read/write to/from serial EEPROM via I2C
+#define MPC624_LEDS 4 // write to LEDs
+#define MPC624_DIO 5 // read/write to/from digital I/O ports
+#define MPC624_IRQ_MASK 6 // IRQ masking enable/disable
+
+// Register bits' names
+#define MPC624_ADBUSY (1<<5)
+#define MPC624_ADSDO (1<<4)
+#define MPC624_ADFO (1<<3)
+#define MPC624_ADCS (1<<2)
+#define MPC624_ADSCK (1<<1)
+#define MPC624_ADSDI (1<<0)
+
+// SDI Speed/Resolution Programming bits
+#define MPC624_OSR4 (1<<31)
+#define MPC624_OSR3 (1<<30)
+#define MPC624_OSR2 (1<<29)
+#define MPC624_OSR1 (1<<28)
+#define MPC624_OSR0 (1<<27)
+
+// 32-bit output value bits' names
+#define MPC624_EOC_BIT (1<<31)
+#define MPC624_DMY_BIT (1<<30)
+#define MPC624_SGN_BIT (1<<29)
+
+// Convertion speeds
+/* OSR4 OSR3 OSR2 OSR1 OSR0 Convertion rate RMS noise ENOB^
+ * X 0 0 0 1 3.52kHz 23uV 17
+ * X 0 0 1 0 1.76kHz 3.5uV 20
+ * X 0 0 1 1 880Hz 2uV 21.3
+ * X 0 1 0 0 440Hz 1.4uV 21.8
+ * X 0 1 0 1 220Hz 1uV 22.4
+ * X 0 1 1 0 110Hz 750uV 22.9
+ * X 0 1 1 1 55Hz 510nV 23.4
+ * X 1 0 0 0 27.5Hz 375nV 24
+ * X 1 0 0 1 13.75Hz 250nV 24.4
+ * X 1 1 1 1 6.875Hz 200nV 24.6
+ *
+ * ^ - Effective Number Of Bits
+ */
+
+#define MPC624_SPEED_3_52_kHz (MPC624_OSR4 | MPC624_OSR0)
+#define MPC624_SPEED_1_76_kHz (MPC624_OSR4 | MPC624_OSR1 )
+#define MPC624_SPEED_880_Hz (MPC624_OSR4 | MPC624_OSR1 | MPC624_OSR0)
+#define MPC624_SPEED_440_Hz (MPC624_OSR4 | MPC624_OSR2 )
+#define MPC624_SPEED_220_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR0)
+#define MPC624_SPEED_110_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 )
+#define MPC624_SPEED_55_Hz (MPC624_OSR4 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
+#define MPC624_SPEED_27_5_Hz (MPC624_OSR4 | MPC624_OSR3 )
+#define MPC624_SPEED_13_75_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR0)
+#define MPC624_SPEED_6_875_Hz (MPC624_OSR4 | MPC624_OSR3 | MPC624_OSR2 | MPC624_OSR1 | MPC624_OSR0)
+//----------------------------------------------------------------------------
+struct skel_private {
+
+ unsigned long int ulConvertionRate; // set by mpc624_attach() from driver's parameters
+};
+
+
+#define devpriv ((struct skel_private *)dev->private)
+//----------------------------------------------------------------------------
+static const struct comedi_lrange range_mpc624_bipolar1 = {
+ 1,
+ {
+// BIP_RANGE(1.01) // this is correct,
+ // but my MPC-624 actually seems to have a range of 2.02
+ BIP_RANGE(2.02)
+ }
+};
+static const struct comedi_lrange range_mpc624_bipolar10 = {
+ 1,
+ {
+// BIP_RANGE(10.1) // this is correct,
+ // but my MPC-624 actually seems to have a range of 20.2
+ BIP_RANGE(20.2)
+ }
+};
+
+//----------------------------------------------------------------------------
+static int mpc624_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mpc624_detach(struct comedi_device * dev);
+//----------------------------------------------------------------------------
+static struct comedi_driver driver_mpc624 = {
+ driver_name:"mpc624",
+ module:THIS_MODULE,
+ attach:mpc624_attach,
+ detach:mpc624_detach
+};
+
+//----------------------------------------------------------------------------
+static int mpc624_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+//----------------------------------------------------------------------------
+static int mpc624_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ rt_printk("comedi%d: mpc624 [0x%04lx, ", dev->minor, iobase);
+ if (request_region(iobase, MPC624_SIZE, "mpc624") == NULL) {
+ rt_printk("I/O port(s) in use\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = "mpc624";
+
+ // Private structure initialization
+ if (alloc_private(dev, sizeof(struct skel_private)) < 0)
+ return -ENOMEM;
+
+ switch (it->options[1]) {
+ case 0:
+ devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
+ rt_printk("3.52 kHz, ");
+ break;
+ case 1:
+ devpriv->ulConvertionRate = MPC624_SPEED_1_76_kHz;
+ rt_printk("1.76 kHz, ");
+ break;
+ case 2:
+ devpriv->ulConvertionRate = MPC624_SPEED_880_Hz;
+ rt_printk("880 Hz, ");
+ break;
+ case 3:
+ devpriv->ulConvertionRate = MPC624_SPEED_440_Hz;
+ rt_printk("440 Hz, ");
+ break;
+ case 4:
+ devpriv->ulConvertionRate = MPC624_SPEED_220_Hz;
+ rt_printk("220 Hz, ");
+ break;
+ case 5:
+ devpriv->ulConvertionRate = MPC624_SPEED_110_Hz;
+ rt_printk("110 Hz, ");
+ break;
+ case 6:
+ devpriv->ulConvertionRate = MPC624_SPEED_55_Hz;
+ rt_printk("55 Hz, ");
+ break;
+ case 7:
+ devpriv->ulConvertionRate = MPC624_SPEED_27_5_Hz;
+ rt_printk("27.5 Hz, ");
+ break;
+ case 8:
+ devpriv->ulConvertionRate = MPC624_SPEED_13_75_Hz;
+ rt_printk("13.75 Hz, ");
+ break;
+ case 9:
+ devpriv->ulConvertionRate = MPC624_SPEED_6_875_Hz;
+ rt_printk("6.875 Hz, ");
+ break;
+ default:
+ rt_printk
+ ("illegal convertion rate setting! Valid numbers are 0..9. Using 9 => 6.875 Hz, ");
+ devpriv->ulConvertionRate = MPC624_SPEED_3_52_kHz;
+ }
+
+ // Subdevices structures
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF;
+ s->n_chan = 8;
+ switch (it->options[1]) {
+ default:
+ s->maxdata = 0x3FFFFFFF;
+ rt_printk("30 bit, ");
+ }
+
+ switch (it->options[1]) {
+ case 0:
+ s->range_table = &range_mpc624_bipolar1;
+ rt_printk("1.01V]: ");
+ break;
+ default:
+ s->range_table = &range_mpc624_bipolar10;
+ rt_printk("10.1V]: ");
+ }
+ s->len_chanlist = 1;
+ s->insn_read = mpc624_ai_rinsn;
+
+ rt_printk("attached\n");
+
+ return 1;
+}
+
+static int mpc624_detach(struct comedi_device * dev)
+{
+ rt_printk("comedi%d: mpc624: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, MPC624_SIZE);
+
+ return 0;
+}
+
+// Timeout 200ms
+#define TIMEOUT 200
+
+static int mpc624_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned long int data_in, data_out;
+ unsigned char ucPort;
+
+ // WARNING: We always write 0 to GNSWA bit, so the channel range is +-/10.1Vdc
+ outb(insn->chanspec, dev->iobase + MPC624_GNMUXCH);
+// rt_printk("Channel %d: \n", insn->chanspec);
+ if (!insn->n) {
+ rt_printk("MPC624: Warning, no data to aquire\n");
+ return 0;
+ }
+
+ for (n = 0; n < insn->n; n++) {
+ // Trigger the convertion
+ outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ outb(MPC624_ADCS | MPC624_ADSCK, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ outb(0, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+
+ // Wait for the convertion to end
+ for (i = 0; i < TIMEOUT; i++) {
+ ucPort = inb(dev->iobase + MPC624_ADC);
+ if (ucPort & MPC624_ADBUSY)
+ comedi_udelay(1000);
+ else
+ break;
+ }
+ if (i == TIMEOUT) {
+ rt_printk("MPC624: timeout (%dms)\n", TIMEOUT);
+ data[n] = 0;
+ return -ETIMEDOUT;
+ }
+ // Start reading data
+ data_in = 0;
+ data_out = devpriv->ulConvertionRate;
+ comedi_udelay(1);
+ for (i = 0; i < 32; i++) {
+ // Set the clock low
+ outb(0, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+
+ if (data_out & (1 << 31)) // the next bit is a 1
+ {
+ // Set the ADSDI line (send to MPC624)
+ outb(MPC624_ADSDI, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ // Set the clock high
+ outb(MPC624_ADSCK | MPC624_ADSDI,
+ dev->iobase + MPC624_ADC);
+ } else // the next bit is a 0
+ {
+ // Set the ADSDI line (send to MPC624)
+ outb(0, dev->iobase + MPC624_ADC);
+ comedi_udelay(1);
+ // Set the clock high
+ outb(MPC624_ADSCK, dev->iobase + MPC624_ADC);
+ }
+ // Read ADSDO on high clock (receive from MPC624)
+ comedi_udelay(1);
+ data_in <<= 1;
+ data_in |=
+ (inb(dev->iobase +
+ MPC624_ADC) & MPC624_ADSDO) >> 4;
+ comedi_udelay(1);
+
+ data_out <<= 1;
+ }
+
+ // Received 32-bit long value consist of:
+ // 31: EOC (End Of Transmission) bit - should be 0
+ // 30: DMY (Dummy) bit - should be 0
+ // 29: SIG (Sign) bit - 1 if the voltage is positive, 0 if negative
+ // 28: MSB (Most Significant Bit) - the first bit of convertion result
+ // ....
+ // 05: LSB (Least Significant Bit) - the last bit of convertion result
+ // 04: sub-LSB - sub-LSBs are basically noise, but when
+ // 03: sub-LSB averaged properly, they can increase convertion
+ // 02: sub-LSB precision up to 29 bits; they can be discarded
+ // 01: sub-LSB without loss of resolution.
+ // 00: sub-LSB
+
+ if (data_in & MPC624_EOC_BIT)
+ rt_printk("MPC624: EOC bit is set (data_in=%lu)!",
+ data_in);
+ if (data_in & MPC624_DMY_BIT)
+ rt_printk("MPC624: DMY bit is set (data_in=%lu)!",
+ data_in);
+ if (data_in & MPC624_SGN_BIT) // check the sign bit
+ { // The voltage is positive
+ data_in &= 0x3FFFFFFF; // EOC and DMY should be 0, but we will mask them out just to be sure
+ data[n] = data_in; // comedi operates on unsigned numbers, so we don't clear the SGN bit
+ // SGN bit is still set! It's correct, since we're converting to unsigned.
+ } else { // The voltage is negative
+ // data_in contains a number in 30-bit two's complement code and we must deal with it
+ data_in |= MPC624_SGN_BIT;
+ data_in = ~data_in;
+ data_in += 1;
+ data_in &= ~(MPC624_EOC_BIT | MPC624_DMY_BIT);
+ // clear EOC and DMY bits
+ data_in = 0x20000000 - data_in;
+ data[n] = data_in;
+ }
+ }
+
+ // Return the number of samples read/written
+ return n;
+}
+
+COMEDI_INITCLEANUP(driver_mpc624);
diff --git a/drivers/staging/comedi/drivers/mpc8260cpm.c b/drivers/staging/comedi/drivers/mpc8260cpm.c
new file mode 100644
index 00000000000..bac0a7bb9cb
--- /dev/null
+++ b/drivers/staging/comedi/drivers/mpc8260cpm.c
@@ -0,0 +1,169 @@
+/*
+ comedi/drivers/mpc8260.c
+ driver for digital I/O pins on the MPC 8260 CPM module
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: mpc8260cpm
+Description: MPC8260 CPM module generic digital I/O lines
+Devices: [Motorola] MPC8260 CPM (mpc8260cpm)
+Author: ds
+Status: experimental
+Updated: Sat, 16 Mar 2002 17:34:48 -0800
+
+This driver is specific to the Motorola MPC8260 processor, allowing
+you to access the processor's generic digital I/O lines.
+
+It is apparently missing some code.
+*/
+
+#include "../comedidev.h"
+
+extern unsigned long mpc8260_dio_reserved[4];
+
+struct mpc8260cpm_private {
+
+ int data;
+
+};
+
+#define devpriv ((struct mpc8260cpm_private *)dev->private)
+
+static int mpc8260cpm_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mpc8260cpm_detach(struct comedi_device * dev);
+static struct comedi_driver driver_mpc8260cpm = {
+ driver_name:"mpc8260cpm",
+ module:THIS_MODULE,
+ attach:mpc8260cpm_attach,
+ detach:mpc8260cpm_detach,
+};
+
+COMEDI_INITCLEANUP(driver_mpc8260cpm);
+
+static int mpc8260cpm_dio_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int mpc8260cpm_dio_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int mpc8260cpm_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+
+ printk("comedi%d: mpc8260cpm: ", dev->minor);
+
+ dev->board_ptr = mpc8260cpm_boards + dev->board;
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct mpc8260cpm_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ for (i = 0; i < 4; i++) {
+ s = dev->subdevices + i;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 32;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_config = mpc8260cpm_dio_config;
+ s->insn_bits = mpc8260cpm_dio_bits;
+ }
+
+ return 1;
+}
+
+static int mpc8260cpm_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: mpc8260cpm: remove\n", dev->minor);
+
+ return 0;
+}
+
+static unsigned long *cpm_pdat(int port)
+{
+ switch (port) {
+ case 0:
+ return &io->iop_pdata;
+ case 1:
+ return &io->iop_pdatb;
+ case 2:
+ return &io->iop_pdatc;
+ case 3:
+ return &io->iop_pdatd;
+ }
+}
+
+static int mpc8260cpm_dio_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned int d;
+ unsigned int mask;
+ int port;
+
+ port = (int)s->private;
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & cpm_reserved_bits[port]) {
+ return -EINVAL;
+ }
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & mask) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (port) {
+ case 0:
+ return &io->iop_pdira;
+ case 1:
+ return &io->iop_pdirb;
+ case 2:
+ return &io->iop_pdirc;
+ case 3:
+ return &io->iop_pdird;
+ }
+
+ return 1;
+}
+
+static int mpc8260cpm_dio_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int port;
+ unsigned long *p;
+
+ p = cpm_pdat((int)s->private);
+
+ return 2;
+}
diff --git a/drivers/staging/comedi/drivers/multiq3.c b/drivers/staging/comedi/drivers/multiq3.c
new file mode 100644
index 00000000000..9e47574171d
--- /dev/null
+++ b/drivers/staging/comedi/drivers/multiq3.c
@@ -0,0 +1,333 @@
+/*
+ comedi/drivers/multiq3.c
+ Hardware driver for Quanser Consulting MultiQ-3 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: multiq3
+Description: Quanser Consulting MultiQ-3
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Status: works
+Devices: [Quanser Consulting] MultiQ-3 (multiq3)
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define MULTIQ3_SIZE 16
+
+/*
+ * MULTIQ-3 port offsets
+ */
+#define MULTIQ3_DIGIN_PORT 0
+#define MULTIQ3_DIGOUT_PORT 0
+#define MULTIQ3_DAC_DATA 2
+#define MULTIQ3_AD_DATA 4
+#define MULTIQ3_AD_CS 4
+#define MULTIQ3_STATUS 6
+#define MULTIQ3_CONTROL 6
+#define MULTIQ3_CLK_DATA 8
+#define MULTIQ3_ENC_DATA 12
+#define MULTIQ3_ENC_CONTROL 14
+
+/*
+ * flags for CONTROL register
+ */
+#define MULTIQ3_AD_MUX_EN 0x0040
+#define MULTIQ3_AD_AUTOZ 0x0080
+#define MULTIQ3_AD_AUTOCAL 0x0100
+#define MULTIQ3_AD_SH 0x0200
+#define MULTIQ3_AD_CLOCK_4M 0x0400
+#define MULTIQ3_DA_LOAD 0x1800
+
+#define MULTIQ3_CONTROL_MUST 0x0600
+
+/*
+ * flags for STATUS register
+ */
+#define MULTIQ3_STATUS_EOC 0x008
+#define MULTIQ3_STATUS_EOC_I 0x010
+
+/*
+ * flags for encoder control
+ */
+#define MULTIQ3_CLOCK_DATA 0x00
+#define MULTIQ3_CLOCK_SETUP 0x18
+#define MULTIQ3_INPUT_SETUP 0x41
+#define MULTIQ3_QUAD_X4 0x38
+#define MULTIQ3_BP_RESET 0x01
+#define MULTIQ3_CNTR_RESET 0x02
+#define MULTIQ3_TRSFRPR_CTR 0x08
+#define MULTIQ3_TRSFRCNTR_OL 0x10
+#define MULTIQ3_EFLAG_RESET 0x06
+
+#define MULTIQ3_TIMEOUT 30
+
+static int multiq3_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int multiq3_detach(struct comedi_device * dev);
+static struct comedi_driver driver_multiq3 = {
+ driver_name:"multiq3",
+ module:THIS_MODULE,
+ attach:multiq3_attach,
+ detach:multiq3_detach,
+};
+
+COMEDI_INITCLEANUP(driver_multiq3);
+
+struct multiq3_private {
+ unsigned int ao_readback[2];
+};
+#define devpriv ((struct multiq3_private *)dev->private)
+
+static int multiq3_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan;
+ unsigned int hi, lo;
+
+ chan = CR_CHAN(insn->chanspec);
+ outw(MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3),
+ dev->iobase + MULTIQ3_CONTROL);
+
+ for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
+ if (inw(dev->iobase + MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC)
+ break;
+ }
+ if (i == MULTIQ3_TIMEOUT)
+ return -ETIMEDOUT;
+
+ for (n = 0; n < insn->n; n++) {
+ outw(0, dev->iobase + MULTIQ3_AD_CS);
+ for (i = 0; i < MULTIQ3_TIMEOUT; i++) {
+ if (inw(dev->iobase +
+ MULTIQ3_STATUS) & MULTIQ3_STATUS_EOC_I)
+ break;
+ }
+ if (i == MULTIQ3_TIMEOUT)
+ return -ETIMEDOUT;
+
+ hi = inb(dev->iobase + MULTIQ3_AD_CS);
+ lo = inb(dev->iobase + MULTIQ3_AD_CS);
+ data[n] = (((hi << 8) | lo) + 0x1000) & 0x1fff;
+ }
+
+ return n;
+}
+
+static int multiq3_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+static int multiq3_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ outw(MULTIQ3_CONTROL_MUST | MULTIQ3_DA_LOAD | chan,
+ dev->iobase + MULTIQ3_CONTROL);
+ outw(data[i], dev->iobase + MULTIQ3_DAC_DATA);
+ outw(MULTIQ3_CONTROL_MUST, dev->iobase + MULTIQ3_CONTROL);
+
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int multiq3_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inw(dev->iobase + MULTIQ3_DIGIN_PORT);
+
+ return 2;
+}
+
+static int multiq3_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outw(s->state, dev->iobase + MULTIQ3_DIGOUT_PORT);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int multiq3_encoder_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+ int control = MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+
+ for (n = 0; n < insn->n; n++) {
+ int value;
+ outw(control, dev->iobase + MULTIQ3_CONTROL);
+ outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_TRSFRCNTR_OL, dev->iobase + MULTIQ3_ENC_CONTROL);
+ value = inb(dev->iobase + MULTIQ3_ENC_DATA);
+ value |= (inb(dev->iobase + MULTIQ3_ENC_DATA) << 8);
+ value |= (inb(dev->iobase + MULTIQ3_ENC_DATA) << 16);
+ data[n] = (value + 0x800000) & 0xffffff;
+ }
+
+ return n;
+}
+
+static void encoder_reset(struct comedi_device * dev)
+{
+ int chan;
+ for (chan = 0; chan < dev->subdevices[4].n_chan; chan++) {
+ int control =
+ MULTIQ3_CONTROL_MUST | MULTIQ3_AD_MUX_EN | (chan << 3);
+ outw(control, dev->iobase + MULTIQ3_CONTROL);
+ outb(MULTIQ3_EFLAG_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_BP_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_CLOCK_DATA, dev->iobase + MULTIQ3_ENC_DATA);
+ outb(MULTIQ3_CLOCK_SETUP, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_INPUT_SETUP, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_QUAD_X4, dev->iobase + MULTIQ3_ENC_CONTROL);
+ outb(MULTIQ3_CNTR_RESET, dev->iobase + MULTIQ3_ENC_CONTROL);
+ }
+}
+
+/*
+ options[0] - I/O port
+ options[1] - irq
+ options[2] - number of encoder chips installed
+ */
+
+static int multiq3_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int result = 0;
+ unsigned long iobase;
+ unsigned int irq;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ printk("comedi%d: multiq3: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, MULTIQ3_SIZE, "multiq3")) {
+ printk("comedi%d: I/O port conflict\n", dev->minor);
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ irq = it->options[1];
+ if (irq) {
+ printk("comedi%d: irq = %u ignored\n", dev->minor, irq);
+ } else {
+ printk("comedi%d: no irq\n", dev->minor);
+ }
+ dev->board_name = "multiq3";
+ result = alloc_subdevices(dev, 5);
+ if (result < 0)
+ return result;
+
+ result = alloc_private(dev, sizeof(struct multiq3_private));
+ if (result < 0)
+ return result;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 8;
+ s->insn_read = multiq3_ai_insn_read;
+ s->maxdata = 0x1fff;
+ s->range_table = &range_bipolar5;
+
+ s = dev->subdevices + 1;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_read = multiq3_ao_insn_read;
+ s->insn_write = multiq3_ao_insn_write;
+ s->maxdata = 0xfff;
+ s->range_table = &range_bipolar5;
+
+ s = dev->subdevices + 2;
+ /* di subdevice */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->insn_bits = multiq3_di_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ s = dev->subdevices + 3;
+ /* do subdevice */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->insn_bits = multiq3_do_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->state = 0;
+
+ s = dev->subdevices + 4;
+ /* encoder (counter) subdevice */
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = it->options[2] * 2;
+ s->insn_read = multiq3_encoder_insn_read;
+ s->maxdata = 0xffffff;
+ s->range_table = &range_unknown;
+
+ encoder_reset(dev);
+
+ return 0;
+}
+
+static int multiq3_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: multiq3: remove\n", dev->minor);
+
+ if (dev->iobase) {
+ release_region(dev->iobase, MULTIQ3_SIZE);
+ }
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_6527.c b/drivers/staging/comedi/drivers/ni_6527.c
new file mode 100644
index 00000000000..e01ecb6760f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_6527.c
@@ -0,0 +1,489 @@
+/*
+ comedi/drivers/ni_6527.c
+ driver for National Instruments PCI-6527
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_6527
+Description: National Instruments 6527
+Author: ds
+Status: works
+Devices: [National Instruments] PCI-6527 (ni6527), PXI-6527
+Updated: Sat, 25 Jan 2003 13:24:40 -0800
+
+
+*/
+
+/*
+ Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+ 370106b.pdf 6527 Register Level Programmer Manual
+
+ */
+
+#define DEBUG 1
+#define DEBUG_FLAGS
+
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define NI6527_DIO_SIZE 4096
+#define NI6527_MITE_SIZE 4096
+
+#define Port_Register(x) (0x00+(x))
+#define ID_Register 0x06
+
+#define Clear_Register 0x07
+#define ClrEdge 0x08
+#define ClrOverflow 0x04
+#define ClrFilter 0x02
+#define ClrInterval 0x01
+
+#define Filter_Interval(x) (0x08+(x))
+#define Filter_Enable(x) (0x0c+(x))
+
+#define Change_Status 0x14
+#define MasterInterruptStatus 0x04
+#define Overflow 0x02
+#define EdgeStatus 0x01
+
+#define Master_Interrupt_Control 0x15
+#define FallingEdgeIntEnable 0x10
+#define RisingEdgeIntEnable 0x08
+#define MasterInterruptEnable 0x04
+#define OverflowIntEnable 0x02
+#define EdgeIntEnable 0x01
+
+#define Rising_Edge_Detection_Enable(x) (0x018+(x))
+#define Falling_Edge_Detection_Enable(x) (0x020+(x))
+
+static int ni6527_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni6527_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni6527 = {
+ driver_name:"ni6527",
+ module:THIS_MODULE,
+ attach:ni6527_attach,
+ detach:ni6527_detach,
+};
+
+struct ni6527_board {
+
+ int dev_id;
+ const char *name;
+};
+
+static const struct ni6527_board ni6527_boards[] = {
+ {
+ dev_id: 0x2b20,
+ name: "pci-6527",
+ },
+ {
+ dev_id: 0x2b10,
+ name: "pxi-6527",
+ },
+};
+
+#define n_ni6527_boards (sizeof(ni6527_boards)/sizeof(ni6527_boards[0]))
+#define this_board ((const struct ni6527_board *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(ni6527_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x2b10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2b20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni6527_pci_table);
+
+struct ni6527_private {
+ struct mite_struct *mite;
+ unsigned int filter_interval;
+ unsigned int filter_enable;
+};
+
+#define devpriv ((struct ni6527_private *)dev->private)
+
+static int ni6527_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni6527_di_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int interval;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0] != INSN_CONFIG_FILTER)
+ return -EINVAL;
+
+ if (data[1]) {
+ interval = (data[1] + 100) / 200;
+ data[1] = interval * 200;
+
+ if (interval != devpriv->filter_interval) {
+ writeb(interval & 0xff,
+ devpriv->mite->daq_io_addr +
+ Filter_Interval(0));
+ writeb((interval >> 8) & 0xff,
+ devpriv->mite->daq_io_addr +
+ Filter_Interval(1));
+ writeb((interval >> 16) & 0x0f,
+ devpriv->mite->daq_io_addr +
+ Filter_Interval(2));
+
+ writeb(ClrInterval,
+ devpriv->mite->daq_io_addr + Clear_Register);
+
+ devpriv->filter_interval = interval;
+ }
+
+ devpriv->filter_enable |= 1 << chan;
+ } else {
+ devpriv->filter_enable &= ~(1 << chan);
+ }
+
+ writeb(devpriv->filter_enable,
+ devpriv->mite->daq_io_addr + Filter_Enable(0));
+ writeb(devpriv->filter_enable >> 8,
+ devpriv->mite->daq_io_addr + Filter_Enable(1));
+ writeb(devpriv->filter_enable >> 16,
+ devpriv->mite->daq_io_addr + Filter_Enable(2));
+
+ return 2;
+}
+
+static int ni6527_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = readb(devpriv->mite->daq_io_addr + Port_Register(0));
+ data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(1)) << 8;
+ data[1] |= readb(devpriv->mite->daq_io_addr + Port_Register(2)) << 16;
+
+ return 2;
+}
+
+static int ni6527_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ /* The open relay state on the board cooresponds to 1,
+ * but in Comedi, it is represented by 0. */
+ if (data[0] & 0x0000ff) {
+ writeb((s->state ^ 0xff),
+ devpriv->mite->daq_io_addr + Port_Register(3));
+ }
+ if (data[0] & 0x00ff00) {
+ writeb((s->state >> 8) ^ 0xff,
+ devpriv->mite->daq_io_addr + Port_Register(4));
+ }
+ if (data[0] & 0xff0000) {
+ writeb((s->state >> 16) ^ 0xff,
+ devpriv->mite->daq_io_addr + Port_Register(5));
+ }
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+static irqreturn_t ni6527_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 2;
+ unsigned int status;
+
+ status = readb(devpriv->mite->daq_io_addr + Change_Status);
+ if ((status & MasterInterruptStatus) == 0)
+ return IRQ_NONE;
+ if ((status & EdgeStatus) == 0)
+ return IRQ_NONE;
+
+ writeb(ClrEdge | ClrOverflow,
+ devpriv->mite->daq_io_addr + Clear_Register);
+
+ comedi_buf_put(s->async, 0);
+ s->async->events |= COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static int ni6527_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_OTHER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni6527_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ //struct comedi_cmd *cmd = &s->async->cmd;
+
+ writeb(ClrEdge | ClrOverflow,
+ devpriv->mite->daq_io_addr + Clear_Register);
+ writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
+ MasterInterruptEnable | EdgeIntEnable,
+ devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni6527_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni6527_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+
+ data[1] = 0;
+ return 2;
+}
+
+static int ni6527_intr_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+ if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+ return -EINVAL;
+
+ writeb(data[1],
+ devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(0));
+ writeb(data[1] >> 8,
+ devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(1));
+ writeb(data[1] >> 16,
+ devpriv->mite->daq_io_addr + Rising_Edge_Detection_Enable(2));
+
+ writeb(data[2],
+ devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(0));
+ writeb(data[2] >> 8,
+ devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(1));
+ writeb(data[2] >> 16,
+ devpriv->mite->daq_io_addr + Falling_Edge_Detection_Enable(2));
+
+ return 2;
+}
+
+static int ni6527_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+
+ printk("comedi%d: ni6527:", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct ni6527_private))) < 0)
+ return ret;
+
+ ret = ni6527_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+
+ dev->board_name = this_board->name;
+ printk(" %s", dev->board_name);
+
+ printk(" ID=0x%02x", readb(devpriv->mite->daq_io_addr + ID_Register));
+
+ if ((ret = alloc_subdevices(dev, 3)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 24;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = ni6527_di_insn_config;
+ s->insn_bits = ni6527_di_insn_bits;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 24;
+ s->range_table = &range_unknown; /* FIXME: actually conductance */
+ s->maxdata = 1;
+ s->insn_bits = ni6527_do_insn_bits;
+
+ s = dev->subdevices + 2;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->range_table = &range_unknown;
+ s->maxdata = 1;
+ s->do_cmdtest = ni6527_intr_cmdtest;
+ s->do_cmd = ni6527_intr_cmd;
+ s->cancel = ni6527_intr_cancel;
+ s->insn_bits = ni6527_intr_insn_bits;
+ s->insn_config = ni6527_intr_insn_config;
+
+ writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(0));
+ writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(1));
+ writeb(0x00, devpriv->mite->daq_io_addr + Filter_Enable(2));
+
+ writeb(ClrEdge | ClrOverflow | ClrFilter | ClrInterval,
+ devpriv->mite->daq_io_addr + Clear_Register);
+ writeb(0x00, devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+
+ ret = comedi_request_irq(mite_irq(devpriv->mite), ni6527_interrupt,
+ IRQF_SHARED, "ni6527", dev);
+ if (ret < 0) {
+ printk(" irq not available");
+ } else
+ dev->irq = mite_irq(devpriv->mite);
+
+ printk("\n");
+
+ return 0;
+}
+
+static int ni6527_detach(struct comedi_device * dev)
+{
+ if (devpriv && devpriv->mite && devpriv->mite->daq_io_addr) {
+ writeb(0x00,
+ devpriv->mite->daq_io_addr + Master_Interrupt_Control);
+ }
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if (devpriv && devpriv->mite) {
+ mite_unsetup(devpriv->mite);
+ }
+
+ return 0;
+}
+
+static int ni6527_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < n_ni6527_boards; i++) {
+ if (mite_device_id(mite) == ni6527_boards[i].dev_id) {
+ dev->board_ptr = ni6527_boards + i;
+ devpriv->mite = mite;
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_ni6527, ni6527_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_65xx.c b/drivers/staging/comedi/drivers/ni_65xx.c
new file mode 100644
index 00000000000..6e85da16a24
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_65xx.c
@@ -0,0 +1,809 @@
+/*
+ comedi/drivers/ni_6514.c
+ driver for National Instruments PCI-6514
+
+ Copyright (C) 2006 Jon Grierson <jd@renko.co.uk>
+ Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2002,2003 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_65xx
+Description: National Instruments 65xx static dio boards
+Author: Jon Grierson <jd@renko.co.uk>, Frank Mori Hess <fmhess@users.sourceforge.net>
+Status: testing
+Devices: [National Instruments] PCI-6509 (ni_65xx), PXI-6509, PCI-6510, PCI-6511,
+ PXI-6511, PCI-6512, PXI-6512, PCI-6513, PXI-6513, PCI-6514, PXI-6514, PCI-6515,
+ PXI-6515, PCI-6516, PCI-6517, PCI-6518, PCI-6519, PCI-6520, PCI-6521, PXI-6521,
+ PCI-6528, PXI-6528
+Updated: Wed Oct 18 08:59:11 EDT 2006
+
+Based on the PCI-6527 driver by ds.
+The interrupt subdevice (subdevice 3) is probably broken for all boards
+except maybe the 6514.
+
+*/
+
+/*
+ Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+ 370106b.pdf 6514 Register Level Programmer Manual
+
+ */
+
+#define _GNU_SOURCE
+#define DEBUG 1
+#define DEBUG_FLAGS
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define NI6514_DIO_SIZE 4096
+#define NI6514_MITE_SIZE 4096
+
+#define NI_65XX_MAX_NUM_PORTS 12
+static const unsigned ni_65xx_channels_per_port = 8;
+static const unsigned ni_65xx_port_offset = 0x10;
+
+static inline unsigned Port_Data(unsigned port)
+{
+ return 0x40 + port * ni_65xx_port_offset;
+}
+static inline unsigned Port_Select(unsigned port)
+{
+ return 0x41 + port * ni_65xx_port_offset;
+}
+static inline unsigned Rising_Edge_Detection_Enable(unsigned port)
+{
+ return 0x42 + port * ni_65xx_port_offset;
+}
+static inline unsigned Falling_Edge_Detection_Enable(unsigned port)
+{
+ return 0x43 + port * ni_65xx_port_offset;
+}
+static inline unsigned Filter_Enable(unsigned port)
+{
+ return 0x44 + port * ni_65xx_port_offset;
+}
+
+#define ID_Register 0x00
+
+#define Clear_Register 0x01
+#define ClrEdge 0x08
+#define ClrOverflow 0x04
+
+#define Filter_Interval 0x08
+
+#define Change_Status 0x02
+#define MasterInterruptStatus 0x04
+#define Overflow 0x02
+#define EdgeStatus 0x01
+
+#define Master_Interrupt_Control 0x03
+#define FallingEdgeIntEnable 0x10
+#define RisingEdgeIntEnable 0x08
+#define MasterInterruptEnable 0x04
+#define OverflowIntEnable 0x02
+#define EdgeIntEnable 0x01
+
+static int ni_65xx_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_65xx_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni_65xx = {
+ driver_name:"ni_65xx",
+ module:THIS_MODULE,
+ attach:ni_65xx_attach,
+ detach:ni_65xx_detach,
+};
+
+struct ni_65xx_board {
+
+ int dev_id;
+ const char *name;
+ unsigned num_dio_ports;
+ unsigned num_di_ports;
+ unsigned num_do_ports;
+ unsigned invert_outputs:1;
+};
+
+static const struct ni_65xx_board ni_65xx_boards[] = {
+ {
+ dev_id: 0x7085,
+ name: "pci-6509",
+ num_dio_ports:12,
+ invert_outputs:0},
+ {
+ dev_id: 0x1710,
+ name: "pxi-6509",
+ num_dio_ports:12,
+ invert_outputs:0},
+ {
+ dev_id: 0x7124,
+ name: "pci-6510",
+ num_di_ports:4},
+ {
+ dev_id: 0x70c3,
+ name: "pci-6511",
+ num_di_ports:8},
+ {
+ dev_id: 0x70d3,
+ name: "pxi-6511",
+ num_di_ports:8},
+ {
+ dev_id: 0x70cc,
+ name: "pci-6512",
+ num_do_ports:8},
+ {
+ dev_id: 0x70d2,
+ name: "pxi-6512",
+ num_do_ports:8},
+ {
+ dev_id: 0x70c8,
+ name: "pci-6513",
+ num_do_ports:8,
+ invert_outputs:1},
+ {
+ dev_id: 0x70d1,
+ name: "pxi-6513",
+ num_do_ports:8,
+ invert_outputs:1},
+ {
+ dev_id: 0x7088,
+ name: "pci-6514",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x70CD,
+ name: "pxi-6514",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7087,
+ name: "pci-6515",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x70c9,
+ name: "pxi-6515",
+ num_di_ports:4,
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7125,
+ name: "pci-6516",
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7126,
+ name: "pci-6517",
+ num_do_ports:4,
+ invert_outputs:1},
+ {
+ dev_id: 0x7127,
+ name: "pci-6518",
+ num_di_ports:2,
+ num_do_ports:2,
+ invert_outputs:1},
+ {
+ dev_id: 0x7128,
+ name: "pci-6519",
+ num_di_ports:2,
+ num_do_ports:2,
+ invert_outputs:1},
+ {
+ dev_id: 0x71c5,
+ name: "pci-6520",
+ num_di_ports:1,
+ num_do_ports:1,
+ },
+ {
+ dev_id: 0x718b,
+ name: "pci-6521",
+ num_di_ports:1,
+ num_do_ports:1,
+ },
+ {
+ dev_id: 0x718c,
+ name: "pxi-6521",
+ num_di_ports:1,
+ num_do_ports:1,
+ },
+ {
+ dev_id: 0x70a9,
+ name: "pci-6528",
+ num_di_ports:3,
+ num_do_ports:3,
+ },
+ {
+ dev_id: 0x7086,
+ name: "pxi-6528",
+ num_di_ports:3,
+ num_do_ports:3,
+ },
+};
+
+#define n_ni_65xx_boards (sizeof(ni_65xx_boards)/sizeof(ni_65xx_boards[0]))
+static inline const struct ni_65xx_board *board(struct comedi_device * dev)
+{
+ return dev->board_ptr;
+}
+static inline unsigned ni_65xx_port_by_channel(unsigned channel)
+{
+ return channel / ni_65xx_channels_per_port;
+}
+static inline unsigned ni_65xx_total_num_ports(const struct ni_65xx_board * board)
+{
+ return board->num_dio_ports + board->num_di_ports + board->num_do_ports;
+}
+
+static DEFINE_PCI_DEVICE_TABLE(ni_65xx_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x1710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7085, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7086, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7087, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7088, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70a9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70d3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7124, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7126, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7127, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x7128, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x718b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x718c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x71c5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_65xx_pci_table);
+
+struct ni_65xx_private {
+ struct mite_struct *mite;
+ unsigned int filter_interval;
+ unsigned short filter_enable[NI_65XX_MAX_NUM_PORTS];
+ unsigned short output_bits[NI_65XX_MAX_NUM_PORTS];
+ unsigned short dio_direction[NI_65XX_MAX_NUM_PORTS];
+};
+
+static inline struct ni_65xx_private *private(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+struct ni_65xx_subdevice_private {
+ unsigned base_port;
+};
+
+static inline struct ni_65xx_subdevice_private *sprivate(struct comedi_subdevice * subdev)
+{
+ return subdev->private;
+}
+static struct ni_65xx_subdevice_private *ni_65xx_alloc_subdevice_private(void)
+{
+ struct ni_65xx_subdevice_private *subdev_private =
+ kzalloc(sizeof(struct ni_65xx_subdevice_private), GFP_KERNEL);
+ if (subdev_private == NULL)
+ return NULL;
+ return subdev_private;
+}
+
+static int ni_65xx_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni_65xx_config_filter(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ const unsigned chan = CR_CHAN(insn->chanspec);
+ const unsigned port =
+ sprivate(s)->base_port + ni_65xx_port_by_channel(chan);
+
+ if (data[0] != INSN_CONFIG_FILTER)
+ return -EINVAL;
+ if (data[1]) {
+ static const unsigned filter_resolution_ns = 200;
+ static const unsigned max_filter_interval = 0xfffff;
+ unsigned interval =
+ (data[1] +
+ (filter_resolution_ns / 2)) / filter_resolution_ns;
+ if (interval > max_filter_interval)
+ interval = max_filter_interval;
+ data[1] = interval * filter_resolution_ns;
+
+ if (interval != private(dev)->filter_interval) {
+ writeb(interval,
+ private(dev)->mite->daq_io_addr +
+ Filter_Interval);
+ private(dev)->filter_interval = interval;
+ }
+
+ private(dev)->filter_enable[port] |=
+ 1 << (chan % ni_65xx_channels_per_port);
+ } else {
+ private(dev)->filter_enable[port] &=
+ ~(1 << (chan % ni_65xx_channels_per_port));
+ }
+
+ writeb(private(dev)->filter_enable[port],
+ private(dev)->mite->daq_io_addr + Filter_Enable(port));
+
+ return 2;
+}
+
+static int ni_65xx_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned port;
+
+ if (insn->n < 1)
+ return -EINVAL;
+ port = sprivate(s)->base_port +
+ ni_65xx_port_by_channel(CR_CHAN(insn->chanspec));
+ switch (data[0]) {
+ case INSN_CONFIG_FILTER:
+ return ni_65xx_config_filter(dev, s, insn, data);
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ if (s->type != COMEDI_SUBD_DIO)
+ return -EINVAL;
+ private(dev)->dio_direction[port] = COMEDI_OUTPUT;
+ writeb(0, private(dev)->mite->daq_io_addr + Port_Select(port));
+ return 1;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ if (s->type != COMEDI_SUBD_DIO)
+ return -EINVAL;
+ private(dev)->dio_direction[port] = COMEDI_INPUT;
+ writeb(1, private(dev)->mite->daq_io_addr + Port_Select(port));
+ return 1;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ if (s->type != COMEDI_SUBD_DIO)
+ return -EINVAL;
+ data[1] = private(dev)->dio_direction[port];
+ return insn->n;
+ break;
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+static int ni_65xx_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned base_bitfield_channel;
+ const unsigned max_ports_per_bitfield = 5;
+ unsigned read_bits = 0;
+ unsigned j;
+ if (insn->n != 2)
+ return -EINVAL;
+ base_bitfield_channel = CR_CHAN(insn->chanspec);
+ for (j = 0; j < max_ports_per_bitfield; ++j) {
+ const unsigned port =
+ sprivate(s)->base_port +
+ ni_65xx_port_by_channel(base_bitfield_channel) + j;
+ unsigned base_port_channel;
+ unsigned port_mask, port_data, port_read_bits;
+ int bitshift;
+ if (port >= ni_65xx_total_num_ports(board(dev)))
+ break;
+ base_port_channel = port * ni_65xx_channels_per_port;
+ port_mask = data[0];
+ port_data = data[1];
+ bitshift = base_port_channel - base_bitfield_channel;
+ if (bitshift >= 32 || bitshift <= -32)
+ break;
+ if (bitshift > 0) {
+ port_mask >>= bitshift;
+ port_data >>= bitshift;
+ } else {
+ port_mask <<= -bitshift;
+ port_data <<= -bitshift;
+ }
+ port_mask &= 0xff;
+ port_data &= 0xff;
+ if (port_mask) {
+ unsigned bits;
+ private(dev)->output_bits[port] &= ~port_mask;
+ private(dev)->output_bits[port] |=
+ port_data & port_mask;
+ bits = private(dev)->output_bits[port];
+ if (board(dev)->invert_outputs)
+ bits = ~bits;
+ writeb(bits,
+ private(dev)->mite->daq_io_addr +
+ Port_Data(port));
+// rt_printk("wrote 0x%x to port %i\n", bits, port);
+ }
+ port_read_bits =
+ readb(private(dev)->mite->daq_io_addr +
+ Port_Data(port));
+// rt_printk("read 0x%x from port %i\n", port_read_bits, port);
+ if (bitshift > 0) {
+ port_read_bits <<= bitshift;
+ } else {
+ port_read_bits >>= -bitshift;
+ }
+ read_bits |= port_read_bits;
+ }
+ data[1] = read_bits;
+ return insn->n;
+}
+
+static irqreturn_t ni_65xx_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 2;
+ unsigned int status;
+
+ status = readb(private(dev)->mite->daq_io_addr + Change_Status);
+ if ((status & MasterInterruptStatus) == 0)
+ return IRQ_NONE;
+ if ((status & EdgeStatus) == 0)
+ return IRQ_NONE;
+
+ writeb(ClrEdge | ClrOverflow,
+ private(dev)->mite->daq_io_addr + Clear_Register);
+
+ comedi_buf_put(s->async, 0);
+ s->async->events |= COMEDI_CB_EOS;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static int ni_65xx_intr_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_OTHER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni_65xx_intr_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ //struct comedi_cmd *cmd = &s->async->cmd;
+
+ writeb(ClrEdge | ClrOverflow,
+ private(dev)->mite->daq_io_addr + Clear_Register);
+ writeb(FallingEdgeIntEnable | RisingEdgeIntEnable |
+ MasterInterruptEnable | EdgeIntEnable,
+ private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni_65xx_intr_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+ return 0;
+}
+
+static int ni_65xx_intr_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+
+ data[1] = 0;
+ return 2;
+}
+
+static int ni_65xx_intr_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+ if (data[0] != INSN_CONFIG_CHANGE_NOTIFY)
+ return -EINVAL;
+
+ writeb(data[1],
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0));
+ writeb(data[1] >> 8,
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0x10));
+ writeb(data[1] >> 16,
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0x20));
+ writeb(data[1] >> 24,
+ private(dev)->mite->daq_io_addr +
+ Rising_Edge_Detection_Enable(0x30));
+
+ writeb(data[2],
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0));
+ writeb(data[2] >> 8,
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0x10));
+ writeb(data[2] >> 16,
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0x20));
+ writeb(data[2] >> 24,
+ private(dev)->mite->daq_io_addr +
+ Falling_Edge_Detection_Enable(0x30));
+
+ return 2;
+}
+
+static int ni_65xx_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned i;
+ int ret;
+
+ printk("comedi%d: ni_65xx:", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct ni_65xx_private))) < 0)
+ return ret;
+
+ ret = ni_65xx_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(private(dev)->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+
+ dev->board_name = board(dev)->name;
+ dev->irq = mite_irq(private(dev)->mite);
+ printk(" %s", dev->board_name);
+
+ printk(" ID=0x%02x",
+ readb(private(dev)->mite->daq_io_addr + ID_Register));
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ if (board(dev)->num_di_ports) {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan =
+ board(dev)->num_di_ports * ni_65xx_channels_per_port;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = ni_65xx_dio_insn_config;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->private = ni_65xx_alloc_subdevice_private();
+ if (s->private == NULL)
+ return -ENOMEM;
+ sprivate(s)->base_port = 0;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 1;
+ if (board(dev)->num_do_ports) {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan =
+ board(dev)->num_do_ports * ni_65xx_channels_per_port;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->private = ni_65xx_alloc_subdevice_private();
+ if (s->private == NULL)
+ return -ENOMEM;
+ sprivate(s)->base_port = board(dev)->num_di_ports;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 2;
+ if (board(dev)->num_dio_ports) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan =
+ board(dev)->num_dio_ports * ni_65xx_channels_per_port;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = ni_65xx_dio_insn_config;
+ s->insn_bits = ni_65xx_dio_insn_bits;
+ s->private = ni_65xx_alloc_subdevice_private();
+ if (s->private == NULL)
+ return -ENOMEM;
+ sprivate(s)->base_port = 0;
+ for (i = 0; i < board(dev)->num_dio_ports; ++i) {
+ // configure all ports for input
+ writeb(0x1,
+ private(dev)->mite->daq_io_addr +
+ Port_Select(i));
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s = dev->subdevices + 3;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = 1;
+ s->range_table = &range_unknown;
+ s->maxdata = 1;
+ s->do_cmdtest = ni_65xx_intr_cmdtest;
+ s->do_cmd = ni_65xx_intr_cmd;
+ s->cancel = ni_65xx_intr_cancel;
+ s->insn_bits = ni_65xx_intr_insn_bits;
+ s->insn_config = ni_65xx_intr_insn_config;
+
+ for (i = 0; i < ni_65xx_total_num_ports(board(dev)); ++i) {
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Filter_Enable(i));
+ if (board(dev)->invert_outputs)
+ writeb(0x01,
+ private(dev)->mite->daq_io_addr + Port_Data(i));
+ else
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Port_Data(i));
+ }
+ writeb(ClrEdge | ClrOverflow,
+ private(dev)->mite->daq_io_addr + Clear_Register);
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr + Master_Interrupt_Control);
+
+ /* Set filter interval to 0 (32bit reg) */
+ writeb(0x00000000, private(dev)->mite->daq_io_addr + Filter_Interval);
+
+ ret = comedi_request_irq(dev->irq, ni_65xx_interrupt, IRQF_SHARED,
+ "ni_65xx", dev);
+ if (ret < 0) {
+ dev->irq = 0;
+ printk(" irq not available");
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int ni_65xx_detach(struct comedi_device * dev)
+{
+ if (private(dev) && private(dev)->mite
+ && private(dev)->mite->daq_io_addr) {
+ writeb(0x00,
+ private(dev)->mite->daq_io_addr +
+ Master_Interrupt_Control);
+ }
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ if (private(dev)) {
+ unsigned i;
+ for (i = 0; i < dev->n_subdevices; ++i) {
+ if (dev->subdevices[i].private) {
+ kfree(dev->subdevices[i].private);
+ dev->subdevices[i].private = NULL;
+ }
+ }
+ if (private(dev)->mite) {
+ mite_unsetup(private(dev)->mite);
+ }
+ }
+ return 0;
+}
+
+static int ni_65xx_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < n_ni_65xx_boards; i++) {
+ if (mite_device_id(mite) == ni_65xx_boards[i].dev_id) {
+ dev->board_ptr = ni_65xx_boards + i;
+ private(dev)->mite = mite;
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_ni_65xx, ni_65xx_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_660x.c b/drivers/staging/comedi/drivers/ni_660x.c
new file mode 100644
index 00000000000..14e35ba721e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_660x.c
@@ -0,0 +1,1324 @@
+/*
+ comedi/drivers/ni_660x.c
+ Hardware driver for NI 660x devices
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+Driver: ni_660x
+Description: National Instruments 660x counter/timer boards
+Devices:
+[National Instruments] PCI-6601 (ni_660x), PCI-6602, PXI-6602,
+ PXI-6608
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+ Herman.Bruyninckx@mech.kuleuven.ac.be,
+ Wim.Meeussen@mech.kuleuven.ac.be,
+ Klaas.Gadeyne@mech.kuleuven.ac.be,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Thu Oct 18 12:56:06 EDT 2007
+Status: experimental
+
+Encoders work. PulseGeneration (both single pulse and pulse train)
+works. Buffered commands work for input but not output.
+
+References:
+DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+
+*/
+
+#include "../comedidev.h"
+#include "mite.h"
+#include "ni_tio.h"
+
+enum ni_660x_constants {
+ min_counter_pfi_chan = 8,
+ max_dio_pfi_chan = 31,
+ counters_per_chip = 4
+};
+
+#define NUM_PFI_CHANNELS 40
+// really there are only up to 3 dma channels, but the register layout allows for 4
+#define MAX_DMA_CHANNEL 4
+
+/* See Register-Level Programmer Manual page 3.1 */
+enum NI_660x_Register {
+ G0InterruptAcknowledge,
+ G0StatusRegister,
+ G1InterruptAcknowledge,
+ G1StatusRegister,
+ G01StatusRegister,
+ G0CommandRegister,
+ STCDIOParallelInput,
+ G1CommandRegister,
+ G0HWSaveRegister,
+ G1HWSaveRegister,
+ STCDIOOutput,
+ STCDIOControl,
+ G0SWSaveRegister,
+ G1SWSaveRegister,
+ G0ModeRegister,
+ G01JointStatus1Register,
+ G1ModeRegister,
+ STCDIOSerialInput,
+ G0LoadARegister,
+ G01JointStatus2Register,
+ G0LoadBRegister,
+ G1LoadARegister,
+ G1LoadBRegister,
+ G0InputSelectRegister,
+ G1InputSelectRegister,
+ G0AutoincrementRegister,
+ G1AutoincrementRegister,
+ G01JointResetRegister,
+ G0InterruptEnable,
+ G1InterruptEnable,
+ G0CountingModeRegister,
+ G1CountingModeRegister,
+ G0SecondGateRegister,
+ G1SecondGateRegister,
+ G0DMAConfigRegister,
+ G0DMAStatusRegister,
+ G1DMAConfigRegister,
+ G1DMAStatusRegister,
+ G2InterruptAcknowledge,
+ G2StatusRegister,
+ G3InterruptAcknowledge,
+ G3StatusRegister,
+ G23StatusRegister,
+ G2CommandRegister,
+ G3CommandRegister,
+ G2HWSaveRegister,
+ G3HWSaveRegister,
+ G2SWSaveRegister,
+ G3SWSaveRegister,
+ G2ModeRegister,
+ G23JointStatus1Register,
+ G3ModeRegister,
+ G2LoadARegister,
+ G23JointStatus2Register,
+ G2LoadBRegister,
+ G3LoadARegister,
+ G3LoadBRegister,
+ G2InputSelectRegister,
+ G3InputSelectRegister,
+ G2AutoincrementRegister,
+ G3AutoincrementRegister,
+ G23JointResetRegister,
+ G2InterruptEnable,
+ G3InterruptEnable,
+ G2CountingModeRegister,
+ G3CountingModeRegister,
+ G3SecondGateRegister,
+ G2SecondGateRegister,
+ G2DMAConfigRegister,
+ G2DMAStatusRegister,
+ G3DMAConfigRegister,
+ G3DMAStatusRegister,
+ DIO32Input,
+ DIO32Output,
+ ClockConfigRegister,
+ GlobalInterruptStatusRegister,
+ DMAConfigRegister,
+ GlobalInterruptConfigRegister,
+ IOConfigReg0_1,
+ IOConfigReg2_3,
+ IOConfigReg4_5,
+ IOConfigReg6_7,
+ IOConfigReg8_9,
+ IOConfigReg10_11,
+ IOConfigReg12_13,
+ IOConfigReg14_15,
+ IOConfigReg16_17,
+ IOConfigReg18_19,
+ IOConfigReg20_21,
+ IOConfigReg22_23,
+ IOConfigReg24_25,
+ IOConfigReg26_27,
+ IOConfigReg28_29,
+ IOConfigReg30_31,
+ IOConfigReg32_33,
+ IOConfigReg34_35,
+ IOConfigReg36_37,
+ IOConfigReg38_39,
+ NumRegisters,
+};
+
+static inline unsigned IOConfigReg(unsigned pfi_channel)
+{
+ unsigned reg = IOConfigReg0_1 + pfi_channel / 2;
+ BUG_ON(reg > IOConfigReg38_39);
+ return reg;
+}
+
+enum ni_660x_register_width {
+ DATA_1B,
+ DATA_2B,
+ DATA_4B
+};
+
+enum ni_660x_register_direction {
+ NI_660x_READ,
+ NI_660x_WRITE,
+ NI_660x_READ_WRITE
+};
+
+enum ni_660x_pfi_output_select {
+ pfi_output_select_high_Z = 0,
+ pfi_output_select_counter = 1,
+ pfi_output_select_do = 2,
+ num_pfi_output_selects
+};
+
+enum ni_660x_subdevices {
+ NI_660X_DIO_SUBDEV = 1,
+ NI_660X_GPCT_SUBDEV_0 = 2
+};
+static inline unsigned NI_660X_GPCT_SUBDEV(unsigned index)
+{
+ return NI_660X_GPCT_SUBDEV_0 + index;
+}
+
+struct NI_660xRegisterData {
+
+ const char *name; // Register Name
+ int offset; // Offset from base address from GPCT chip
+ enum ni_660x_register_direction direction;
+ enum ni_660x_register_width size; // 1 byte, 2 bytes, or 4 bytes
+};
+
+
+static const struct NI_660xRegisterData registerData[NumRegisters] = {
+ {"G0 Interrupt Acknowledge", 0x004, NI_660x_WRITE, DATA_2B},
+ {"G0 Status Register", 0x004, NI_660x_READ, DATA_2B},
+ {"G1 Interrupt Acknowledge", 0x006, NI_660x_WRITE, DATA_2B},
+ {"G1 Status Register", 0x006, NI_660x_READ, DATA_2B},
+ {"G01 Status Register ", 0x008, NI_660x_READ, DATA_2B},
+ {"G0 Command Register", 0x00C, NI_660x_WRITE, DATA_2B},
+ {"STC DIO Parallel Input", 0x00E, NI_660x_READ, DATA_2B},
+ {"G1 Command Register", 0x00E, NI_660x_WRITE, DATA_2B},
+ {"G0 HW Save Register", 0x010, NI_660x_READ, DATA_4B},
+ {"G1 HW Save Register", 0x014, NI_660x_READ, DATA_4B},
+ {"STC DIO Output", 0x014, NI_660x_WRITE, DATA_2B},
+ {"STC DIO Control", 0x016, NI_660x_WRITE, DATA_2B},
+ {"G0 SW Save Register", 0x018, NI_660x_READ, DATA_4B},
+ {"G1 SW Save Register", 0x01C, NI_660x_READ, DATA_4B},
+ {"G0 Mode Register", 0x034, NI_660x_WRITE, DATA_2B},
+ {"G01 Joint Status 1 Register", 0x036, NI_660x_READ, DATA_2B},
+ {"G1 Mode Register", 0x036, NI_660x_WRITE, DATA_2B},
+ {"STC DIO Serial Input", 0x038, NI_660x_READ, DATA_2B},
+ {"G0 Load A Register", 0x038, NI_660x_WRITE, DATA_4B},
+ {"G01 Joint Status 2 Register", 0x03A, NI_660x_READ, DATA_2B},
+ {"G0 Load B Register", 0x03C, NI_660x_WRITE, DATA_4B},
+ {"G1 Load A Register", 0x040, NI_660x_WRITE, DATA_4B},
+ {"G1 Load B Register", 0x044, NI_660x_WRITE, DATA_4B},
+ {"G0 Input Select Register", 0x048, NI_660x_WRITE, DATA_2B},
+ {"G1 Input Select Register", 0x04A, NI_660x_WRITE, DATA_2B},
+ {"G0 Autoincrement Register", 0x088, NI_660x_WRITE, DATA_2B},
+ {"G1 Autoincrement Register", 0x08A, NI_660x_WRITE, DATA_2B},
+ {"G01 Joint Reset Register", 0x090, NI_660x_WRITE, DATA_2B},
+ {"G0 Interrupt Enable", 0x092, NI_660x_WRITE, DATA_2B},
+ {"G1 Interrupt Enable", 0x096, NI_660x_WRITE, DATA_2B},
+ {"G0 Counting Mode Register", 0x0B0, NI_660x_WRITE, DATA_2B},
+ {"G1 Counting Mode Register", 0x0B2, NI_660x_WRITE, DATA_2B},
+ {"G0 Second Gate Register", 0x0B4, NI_660x_WRITE, DATA_2B},
+ {"G1 Second Gate Register", 0x0B6, NI_660x_WRITE, DATA_2B},
+ {"G0 DMA Config Register", 0x0B8, NI_660x_WRITE, DATA_2B},
+ {"G0 DMA Status Register", 0x0B8, NI_660x_READ, DATA_2B},
+ {"G1 DMA Config Register", 0x0BA, NI_660x_WRITE, DATA_2B},
+ {"G1 DMA Status Register", 0x0BA, NI_660x_READ, DATA_2B},
+ {"G2 Interrupt Acknowledge", 0x104, NI_660x_WRITE, DATA_2B},
+ {"G2 Status Register", 0x104, NI_660x_READ, DATA_2B},
+ {"G3 Interrupt Acknowledge", 0x106, NI_660x_WRITE, DATA_2B},
+ {"G3 Status Register", 0x106, NI_660x_READ, DATA_2B},
+ {"G23 Status Register", 0x108, NI_660x_READ, DATA_2B},
+ {"G2 Command Register", 0x10C, NI_660x_WRITE, DATA_2B},
+ {"G3 Command Register", 0x10E, NI_660x_WRITE, DATA_2B},
+ {"G2 HW Save Register", 0x110, NI_660x_READ, DATA_4B},
+ {"G3 HW Save Register", 0x114, NI_660x_READ, DATA_4B},
+ {"G2 SW Save Register", 0x118, NI_660x_READ, DATA_4B},
+ {"G3 SW Save Register", 0x11C, NI_660x_READ, DATA_4B},
+ {"G2 Mode Register", 0x134, NI_660x_WRITE, DATA_2B},
+ {"G23 Joint Status 1 Register", 0x136, NI_660x_READ, DATA_2B},
+ {"G3 Mode Register", 0x136, NI_660x_WRITE, DATA_2B},
+ {"G2 Load A Register", 0x138, NI_660x_WRITE, DATA_4B},
+ {"G23 Joint Status 2 Register", 0x13A, NI_660x_READ, DATA_2B},
+ {"G2 Load B Register", 0x13C, NI_660x_WRITE, DATA_4B},
+ {"G3 Load A Register", 0x140, NI_660x_WRITE, DATA_4B},
+ {"G3 Load B Register", 0x144, NI_660x_WRITE, DATA_4B},
+ {"G2 Input Select Register", 0x148, NI_660x_WRITE, DATA_2B},
+ {"G3 Input Select Register", 0x14A, NI_660x_WRITE, DATA_2B},
+ {"G2 Autoincrement Register", 0x188, NI_660x_WRITE, DATA_2B},
+ {"G3 Autoincrement Register", 0x18A, NI_660x_WRITE, DATA_2B},
+ {"G23 Joint Reset Register", 0x190, NI_660x_WRITE, DATA_2B},
+ {"G2 Interrupt Enable", 0x192, NI_660x_WRITE, DATA_2B},
+ {"G3 Interrupt Enable", 0x196, NI_660x_WRITE, DATA_2B},
+ {"G2 Counting Mode Register", 0x1B0, NI_660x_WRITE, DATA_2B},
+ {"G3 Counting Mode Register", 0x1B2, NI_660x_WRITE, DATA_2B},
+ {"G3 Second Gate Register", 0x1B6, NI_660x_WRITE, DATA_2B},
+ {"G2 Second Gate Register", 0x1B4, NI_660x_WRITE, DATA_2B},
+ {"G2 DMA Config Register", 0x1B8, NI_660x_WRITE, DATA_2B},
+ {"G2 DMA Status Register", 0x1B8, NI_660x_READ, DATA_2B},
+ {"G3 DMA Config Register", 0x1BA, NI_660x_WRITE, DATA_2B},
+ {"G3 DMA Status Register", 0x1BA, NI_660x_READ, DATA_2B},
+ {"32 bit Digital Input", 0x414, NI_660x_READ, DATA_4B},
+ {"32 bit Digital Output", 0x510, NI_660x_WRITE, DATA_4B},
+ {"Clock Config Register", 0x73C, NI_660x_WRITE, DATA_4B},
+ {"Global Interrupt Status Register", 0x754, NI_660x_READ, DATA_4B},
+ {"DMA Configuration Register", 0x76C, NI_660x_WRITE, DATA_4B},
+ {"Global Interrupt Config Register", 0x770, NI_660x_WRITE, DATA_4B},
+ {"IO Config Register 0-1", 0x77C, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 2-3", 0x77E, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 4-5", 0x780, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 6-7", 0x782, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 8-9", 0x784, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 10-11", 0x786, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 12-13", 0x788, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 14-15", 0x78A, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 16-17", 0x78C, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 18-19", 0x78E, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 20-21", 0x790, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 22-23", 0x792, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 24-25", 0x794, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 26-27", 0x796, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 28-29", 0x798, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 30-31", 0x79A, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 32-33", 0x79C, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 34-35", 0x79E, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 36-37", 0x7A0, NI_660x_READ_WRITE, DATA_2B},
+ {"IO Config Register 38-39", 0x7A2, NI_660x_READ_WRITE, DATA_2B}
+};
+
+// kind of ENABLE for the second counter
+enum clock_config_register_bits {
+ CounterSwap = 0x1 << 21
+};
+
+// ioconfigreg
+static inline unsigned ioconfig_bitshift(unsigned pfi_channel)
+{
+ if (pfi_channel % 2)
+ return 0;
+ else
+ return 8;
+}
+static inline unsigned pfi_output_select_mask(unsigned pfi_channel)
+{
+ return 0x3 << ioconfig_bitshift(pfi_channel);
+}
+static inline unsigned pfi_output_select_bits(unsigned pfi_channel,
+ unsigned output_select)
+{
+ return (output_select & 0x3) << ioconfig_bitshift(pfi_channel);
+}
+static inline unsigned pfi_input_select_mask(unsigned pfi_channel)
+{
+ return 0x7 << (4 + ioconfig_bitshift(pfi_channel));
+}
+static inline unsigned pfi_input_select_bits(unsigned pfi_channel,
+ unsigned input_select)
+{
+ return (input_select & 0x7) << (4 + ioconfig_bitshift(pfi_channel));
+}
+
+// dma configuration register bits
+static inline unsigned dma_select_mask(unsigned dma_channel)
+{
+ BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+ return 0x1f << (8 * dma_channel);
+}
+enum dma_selection {
+ dma_selection_none = 0x1f,
+};
+static inline unsigned dma_selection_counter(unsigned counter_index)
+{
+ BUG_ON(counter_index >= counters_per_chip);
+ return counter_index;
+}
+static inline unsigned dma_select_bits(unsigned dma_channel, unsigned selection)
+{
+ BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+ return (selection << (8 * dma_channel)) & dma_select_mask(dma_channel);
+}
+static inline unsigned dma_reset_bit(unsigned dma_channel)
+{
+ BUG_ON(dma_channel >= MAX_DMA_CHANNEL);
+ return 0x80 << (8 * dma_channel);
+}
+
+enum global_interrupt_status_register_bits {
+ Counter_0_Int_Bit = 0x100,
+ Counter_1_Int_Bit = 0x200,
+ Counter_2_Int_Bit = 0x400,
+ Counter_3_Int_Bit = 0x800,
+ Cascade_Int_Bit = 0x20000000,
+ Global_Int_Bit = 0x80000000
+};
+
+enum global_interrupt_config_register_bits {
+ Cascade_Int_Enable_Bit = 0x20000000,
+ Global_Int_Polarity_Bit = 0x40000000,
+ Global_Int_Enable_Bit = 0x80000000
+};
+
+// Offset of the GPCT chips from the base-adress of the card
+static const unsigned GPCT_OFFSET[2] = { 0x0, 0x800 }; /* First chip is at base-address +
+ 0x00, etc. */
+
+/* Board description*/
+struct ni_660x_board {
+ unsigned short dev_id; /* `lspci` will show you this */
+ const char *name;
+ unsigned n_chips; /* total number of TIO chips */
+};
+
+static const struct ni_660x_board ni_660x_boards[] = {
+ {
+ dev_id: 0x2c60,
+ name: "PCI-6601",
+ n_chips: 1,
+ },
+ {
+ dev_id: 0x1310,
+ name: "PCI-6602",
+ n_chips: 2,
+ },
+ {
+ dev_id: 0x1360,
+ name: "PXI-6602",
+ n_chips: 2,
+ },
+ {
+ dev_id: 0x2cc0,
+ name: "PXI-6608",
+ n_chips: 2,
+ },
+};
+
+#define NI_660X_MAX_NUM_CHIPS 2
+#define NI_660X_MAX_NUM_COUNTERS (NI_660X_MAX_NUM_CHIPS * counters_per_chip)
+
+static DEFINE_PCI_DEVICE_TABLE(ni_660x_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x2c60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1310, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2cc0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_660x_pci_table);
+
+struct ni_660x_private {
+ struct mite_struct *mite;
+ struct ni_gpct_device *counter_dev;
+ uint64_t pfi_direction_bits;
+ struct mite_dma_descriptor_ring
+ *mite_rings[NI_660X_MAX_NUM_CHIPS][counters_per_chip];
+ spinlock_t mite_channel_lock;
+ unsigned dma_configuration_soft_copies[NI_660X_MAX_NUM_CHIPS];
+ spinlock_t soft_reg_copy_lock;
+ unsigned short pfi_output_selects[NUM_PFI_CHANNELS];
+};
+
+static inline struct ni_660x_private *private(struct comedi_device * dev)
+{
+ return dev->private;
+}
+
+/* initialized in ni_660x_find_device() */
+static inline const struct ni_660x_board *board(struct comedi_device * dev)
+{
+ return dev->board_ptr;
+}
+
+#define n_ni_660x_boards (sizeof(ni_660x_boards)/sizeof(ni_660x_boards[0]))
+
+static int ni_660x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_660x_detach(struct comedi_device * dev);
+static void init_tio_chip(struct comedi_device * dev, int chipset);
+static void ni_660x_select_pfi_output(struct comedi_device * dev, unsigned pfi_channel,
+ unsigned output_select);
+
+static struct comedi_driver driver_ni_660x = {
+ driver_name:"ni_660x",
+ module:THIS_MODULE,
+ attach:ni_660x_attach,
+ detach:ni_660x_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_ni_660x, ni_660x_pci_table);
+
+static int ni_660x_find_device(struct comedi_device * dev, int bus, int slot);
+static int ni_660x_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source);
+
+/* Possible instructions for a GPCT */
+static int ni_660x_GPCT_rinsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_GPCT_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_GPCT_winsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/* Possible instructions for Digital IO */
+static int ni_660x_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+static int ni_660x_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static inline unsigned ni_660x_num_counters(struct comedi_device * dev)
+{
+ return board(dev)->n_chips * counters_per_chip;
+}
+
+static enum NI_660x_Register ni_gpct_to_660x_register(enum ni_gpct_register reg)
+{
+ enum NI_660x_Register ni_660x_register;
+ switch (reg) {
+ case NITIO_G0_Autoincrement_Reg:
+ ni_660x_register = G0AutoincrementRegister;
+ break;
+ case NITIO_G1_Autoincrement_Reg:
+ ni_660x_register = G1AutoincrementRegister;
+ break;
+ case NITIO_G2_Autoincrement_Reg:
+ ni_660x_register = G2AutoincrementRegister;
+ break;
+ case NITIO_G3_Autoincrement_Reg:
+ ni_660x_register = G3AutoincrementRegister;
+ break;
+ case NITIO_G0_Command_Reg:
+ ni_660x_register = G0CommandRegister;
+ break;
+ case NITIO_G1_Command_Reg:
+ ni_660x_register = G1CommandRegister;
+ break;
+ case NITIO_G2_Command_Reg:
+ ni_660x_register = G2CommandRegister;
+ break;
+ case NITIO_G3_Command_Reg:
+ ni_660x_register = G3CommandRegister;
+ break;
+ case NITIO_G0_HW_Save_Reg:
+ ni_660x_register = G0HWSaveRegister;
+ break;
+ case NITIO_G1_HW_Save_Reg:
+ ni_660x_register = G1HWSaveRegister;
+ break;
+ case NITIO_G2_HW_Save_Reg:
+ ni_660x_register = G2HWSaveRegister;
+ break;
+ case NITIO_G3_HW_Save_Reg:
+ ni_660x_register = G3HWSaveRegister;
+ break;
+ case NITIO_G0_SW_Save_Reg:
+ ni_660x_register = G0SWSaveRegister;
+ break;
+ case NITIO_G1_SW_Save_Reg:
+ ni_660x_register = G1SWSaveRegister;
+ break;
+ case NITIO_G2_SW_Save_Reg:
+ ni_660x_register = G2SWSaveRegister;
+ break;
+ case NITIO_G3_SW_Save_Reg:
+ ni_660x_register = G3SWSaveRegister;
+ break;
+ case NITIO_G0_Mode_Reg:
+ ni_660x_register = G0ModeRegister;
+ break;
+ case NITIO_G1_Mode_Reg:
+ ni_660x_register = G1ModeRegister;
+ break;
+ case NITIO_G2_Mode_Reg:
+ ni_660x_register = G2ModeRegister;
+ break;
+ case NITIO_G3_Mode_Reg:
+ ni_660x_register = G3ModeRegister;
+ break;
+ case NITIO_G0_LoadA_Reg:
+ ni_660x_register = G0LoadARegister;
+ break;
+ case NITIO_G1_LoadA_Reg:
+ ni_660x_register = G1LoadARegister;
+ break;
+ case NITIO_G2_LoadA_Reg:
+ ni_660x_register = G2LoadARegister;
+ break;
+ case NITIO_G3_LoadA_Reg:
+ ni_660x_register = G3LoadARegister;
+ break;
+ case NITIO_G0_LoadB_Reg:
+ ni_660x_register = G0LoadBRegister;
+ break;
+ case NITIO_G1_LoadB_Reg:
+ ni_660x_register = G1LoadBRegister;
+ break;
+ case NITIO_G2_LoadB_Reg:
+ ni_660x_register = G2LoadBRegister;
+ break;
+ case NITIO_G3_LoadB_Reg:
+ ni_660x_register = G3LoadBRegister;
+ break;
+ case NITIO_G0_Input_Select_Reg:
+ ni_660x_register = G0InputSelectRegister;
+ break;
+ case NITIO_G1_Input_Select_Reg:
+ ni_660x_register = G1InputSelectRegister;
+ break;
+ case NITIO_G2_Input_Select_Reg:
+ ni_660x_register = G2InputSelectRegister;
+ break;
+ case NITIO_G3_Input_Select_Reg:
+ ni_660x_register = G3InputSelectRegister;
+ break;
+ case NITIO_G01_Status_Reg:
+ ni_660x_register = G01StatusRegister;
+ break;
+ case NITIO_G23_Status_Reg:
+ ni_660x_register = G23StatusRegister;
+ break;
+ case NITIO_G01_Joint_Reset_Reg:
+ ni_660x_register = G01JointResetRegister;
+ break;
+ case NITIO_G23_Joint_Reset_Reg:
+ ni_660x_register = G23JointResetRegister;
+ break;
+ case NITIO_G01_Joint_Status1_Reg:
+ ni_660x_register = G01JointStatus1Register;
+ break;
+ case NITIO_G23_Joint_Status1_Reg:
+ ni_660x_register = G23JointStatus1Register;
+ break;
+ case NITIO_G01_Joint_Status2_Reg:
+ ni_660x_register = G01JointStatus2Register;
+ break;
+ case NITIO_G23_Joint_Status2_Reg:
+ ni_660x_register = G23JointStatus2Register;
+ break;
+ case NITIO_G0_Counting_Mode_Reg:
+ ni_660x_register = G0CountingModeRegister;
+ break;
+ case NITIO_G1_Counting_Mode_Reg:
+ ni_660x_register = G1CountingModeRegister;
+ break;
+ case NITIO_G2_Counting_Mode_Reg:
+ ni_660x_register = G2CountingModeRegister;
+ break;
+ case NITIO_G3_Counting_Mode_Reg:
+ ni_660x_register = G3CountingModeRegister;
+ break;
+ case NITIO_G0_Second_Gate_Reg:
+ ni_660x_register = G0SecondGateRegister;
+ break;
+ case NITIO_G1_Second_Gate_Reg:
+ ni_660x_register = G1SecondGateRegister;
+ break;
+ case NITIO_G2_Second_Gate_Reg:
+ ni_660x_register = G2SecondGateRegister;
+ break;
+ case NITIO_G3_Second_Gate_Reg:
+ ni_660x_register = G3SecondGateRegister;
+ break;
+ case NITIO_G0_DMA_Config_Reg:
+ ni_660x_register = G0DMAConfigRegister;
+ break;
+ case NITIO_G0_DMA_Status_Reg:
+ ni_660x_register = G0DMAStatusRegister;
+ break;
+ case NITIO_G1_DMA_Config_Reg:
+ ni_660x_register = G1DMAConfigRegister;
+ break;
+ case NITIO_G1_DMA_Status_Reg:
+ ni_660x_register = G1DMAStatusRegister;
+ break;
+ case NITIO_G2_DMA_Config_Reg:
+ ni_660x_register = G2DMAConfigRegister;
+ break;
+ case NITIO_G2_DMA_Status_Reg:
+ ni_660x_register = G2DMAStatusRegister;
+ break;
+ case NITIO_G3_DMA_Config_Reg:
+ ni_660x_register = G3DMAConfigRegister;
+ break;
+ case NITIO_G3_DMA_Status_Reg:
+ ni_660x_register = G3DMAStatusRegister;
+ break;
+ case NITIO_G0_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G0InterruptAcknowledge;
+ break;
+ case NITIO_G1_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G1InterruptAcknowledge;
+ break;
+ case NITIO_G2_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G2InterruptAcknowledge;
+ break;
+ case NITIO_G3_Interrupt_Acknowledge_Reg:
+ ni_660x_register = G3InterruptAcknowledge;
+ break;
+ case NITIO_G0_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G1_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G2_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G3_Status_Reg:
+ ni_660x_register = G0StatusRegister;
+ break;
+ case NITIO_G0_Interrupt_Enable_Reg:
+ ni_660x_register = G0InterruptEnable;
+ break;
+ case NITIO_G1_Interrupt_Enable_Reg:
+ ni_660x_register = G1InterruptEnable;
+ break;
+ case NITIO_G2_Interrupt_Enable_Reg:
+ ni_660x_register = G2InterruptEnable;
+ break;
+ case NITIO_G3_Interrupt_Enable_Reg:
+ ni_660x_register = G3InterruptEnable;
+ break;
+ default:
+ rt_printk("%s: unhandled register 0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return ni_660x_register;
+}
+
+static inline void ni_660x_write_register(struct comedi_device * dev,
+ unsigned chip_index, unsigned bits, enum NI_660x_Register reg)
+{
+ void *const write_address =
+ private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+ registerData[reg].offset;
+
+ switch (registerData[reg].size) {
+ case DATA_2B:
+ writew(bits, write_address);
+ break;
+ case DATA_4B:
+ writel(bits, write_address);
+ break;
+ default:
+ rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+ __FILE__, __FUNCTION__, reg);
+ BUG();
+ break;
+ }
+}
+
+static inline unsigned ni_660x_read_register(struct comedi_device * dev,
+ unsigned chip_index, enum NI_660x_Register reg)
+{
+ void *const read_address =
+ private(dev)->mite->daq_io_addr + GPCT_OFFSET[chip_index] +
+ registerData[reg].offset;
+
+ switch (registerData[reg].size) {
+ case DATA_2B:
+ return readw(read_address);
+ break;
+ case DATA_4B:
+ return readl(read_address);
+ break;
+ default:
+ rt_printk("%s: %s: bug! unhandled case (reg=0x%x) in switch.\n",
+ __FILE__, __FUNCTION__, reg);
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
+ ni_660x_write_register(dev, counter->chip_index, bits,
+ ni_660x_register);
+}
+
+static unsigned ni_gpct_read_register(struct ni_gpct *counter,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ enum NI_660x_Register ni_660x_register = ni_gpct_to_660x_register(reg);
+ return ni_660x_read_register(dev, counter->chip_index,
+ ni_660x_register);
+}
+
+static inline struct mite_dma_descriptor_ring *mite_ring(struct ni_660x_private * priv,
+ struct ni_gpct *counter)
+{
+ return priv->mite_rings[counter->chip_index][counter->counter_index];
+}
+
+static inline void ni_660x_set_dma_channel(struct comedi_device * dev,
+ unsigned mite_channel, struct ni_gpct *counter)
+{
+ unsigned long flags;
+ comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+ ~dma_select_mask(mite_channel);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+ dma_select_bits(mite_channel,
+ dma_selection_counter(counter->counter_index));
+ ni_660x_write_register(dev, counter->chip_index,
+ private(dev)->dma_configuration_soft_copies[counter->
+ chip_index] | dma_reset_bit(mite_channel),
+ DMAConfigRegister);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+}
+
+static inline void ni_660x_unset_dma_channel(struct comedi_device * dev,
+ unsigned mite_channel, struct ni_gpct *counter)
+{
+ unsigned long flags;
+ comedi_spin_lock_irqsave(&private(dev)->soft_reg_copy_lock, flags);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] &=
+ ~dma_select_mask(mite_channel);
+ private(dev)->dma_configuration_soft_copies[counter->chip_index] |=
+ dma_select_bits(mite_channel, dma_selection_none);
+ ni_660x_write_register(dev, counter->chip_index,
+ private(dev)->dma_configuration_soft_copies[counter->
+ chip_index], DMAConfigRegister);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&private(dev)->soft_reg_copy_lock, flags);
+}
+
+static int ni_660x_request_mite_channel(struct comedi_device * dev,
+ struct ni_gpct *counter, enum comedi_io_direction direction)
+{
+ unsigned long flags;
+ struct mite_channel *mite_chan;
+
+ comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+ BUG_ON(counter->mite_chan);
+ mite_chan =
+ mite_request_channel(private(dev)->mite, mite_ring(private(dev),
+ counter));
+ if (mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for counter.");
+ return -EBUSY;
+ }
+ mite_chan->dir = direction;
+ ni_tio_set_mite_channel(counter, mite_chan);
+ ni_660x_set_dma_channel(dev, mite_chan->channel, counter);
+ comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+ return 0;
+}
+
+void ni_660x_release_mite_channel(struct comedi_device * dev, struct ni_gpct *counter)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&private(dev)->mite_channel_lock, flags);
+ if (counter->mite_chan) {
+ struct mite_channel *mite_chan = counter->mite_chan;
+
+ ni_660x_unset_dma_channel(dev, mite_chan->channel, counter);
+ ni_tio_set_mite_channel(counter, NULL);
+ mite_release_channel(mite_chan);
+ }
+ comedi_spin_unlock_irqrestore(&private(dev)->mite_channel_lock, flags);
+}
+
+static int ni_660x_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int retval;
+
+ struct ni_gpct *counter = subdev_to_counter(s);
+// const struct comedi_cmd *cmd = &s->async->cmd;
+
+ retval = ni_660x_request_mite_channel(dev, counter, COMEDI_INPUT);
+ if (retval) {
+ comedi_error(dev,
+ "no dma channel available for use by counter");
+ return retval;
+ }
+ ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+ retval = ni_tio_cmd(counter, s->async);
+
+ return retval;
+}
+
+static int ni_660x_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ struct ni_gpct *counter = subdev_to_counter(s);
+
+ return ni_tio_cmdtest(counter, cmd);
+}
+
+static int ni_660x_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct ni_gpct *counter = subdev_to_counter(s);
+ int retval;
+
+ retval = ni_tio_cancel(counter);
+ ni_660x_release_mite_channel(dev, counter);
+ return retval;
+}
+
+static void set_tio_counterswap(struct comedi_device * dev, int chipset)
+{
+ /* See P. 3.5 of the Register-Level Programming manual. The
+ CounterSwap bit has to be set on the second chip, otherwise
+ it will try to use the same pins as the first chip.
+ */
+ if (chipset)
+ ni_660x_write_register(dev, chipset, CounterSwap,
+ ClockConfigRegister);
+ else
+ ni_660x_write_register(dev, chipset, 0, ClockConfigRegister);
+}
+
+static void ni_660x_handle_gpct_interrupt(struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ ni_tio_handle_interrupt(subdev_to_counter(s), s);
+ if (s->async->events) {
+ if (s->async->
+ events & (COMEDI_CB_EOA | COMEDI_CB_ERROR |
+ COMEDI_CB_OVERFLOW)) {
+ ni_660x_cancel(dev, s);
+ }
+ comedi_event(dev, s);
+ }
+}
+
+static irqreturn_t ni_660x_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ unsigned i;
+
+ if (dev->attached == 0)
+ return IRQ_NONE;
+ smp_mb();
+ for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+ s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
+ ni_660x_handle_gpct_interrupt(dev, s);
+ }
+ return IRQ_HANDLED;
+}
+
+static int ni_660x_buf_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(mite_ring(private(dev), subdev_to_counter(s)),
+ s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int ni_660x_allocate_private(struct comedi_device * dev)
+{
+ int retval;
+ unsigned i;
+
+ if ((retval = alloc_private(dev, sizeof(struct ni_660x_private))) < 0)
+ return retval;
+ spin_lock_init(&private(dev)->mite_channel_lock);
+ spin_lock_init(&private(dev)->soft_reg_copy_lock);
+ for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+ private(dev)->pfi_output_selects[i] = pfi_output_select_counter;
+ }
+ return 0;
+}
+
+static int ni_660x_alloc_mite_rings(struct comedi_device * dev)
+{
+ unsigned i;
+ unsigned j;
+
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (j = 0; j < counters_per_chip; ++j) {
+ private(dev)->mite_rings[i][j] =
+ mite_alloc_ring(private(dev)->mite);
+ if (private(dev)->mite_rings[i][j] == NULL) {
+ return -ENOMEM;
+ }
+ }
+ }
+ return 0;
+}
+
+static void ni_660x_free_mite_rings(struct comedi_device * dev)
+{
+ unsigned i;
+ unsigned j;
+
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ for (j = 0; j < counters_per_chip; ++j) {
+ mite_free_ring(private(dev)->mite_rings[i][j]);
+ }
+ }
+}
+
+static int ni_660x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ unsigned i;
+ unsigned global_interrupt_config_bits;
+
+ printk("comedi%d: ni_660x: ", dev->minor);
+
+ ret = ni_660x_allocate_private(dev);
+ if (ret < 0)
+ return ret;
+ ret = ni_660x_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ dev->board_name = board(dev)->name;
+
+ ret = mite_setup2(private(dev)->mite, 1);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+ comedi_set_hw_dev(dev, &private(dev)->mite->pcidev->dev);
+ ret = ni_660x_alloc_mite_rings(dev);
+ if (ret < 0)
+ return ret;
+
+ printk(" %s ", dev->board_name);
+
+ dev->n_subdevices = 2 + NI_660X_MAX_NUM_COUNTERS;
+
+ if (alloc_subdevices(dev, dev->n_subdevices) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* Old GENERAL-PURPOSE COUNTER/TIME (GPCT) subdevice, no longer used */
+ s->type = COMEDI_SUBD_UNUSED;
+
+ s = dev->subdevices + NI_660X_DIO_SUBDEV;
+ /* DIGITAL I/O SUBDEVICE */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = NUM_PFI_CHANNELS;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_660x_dio_insn_bits;
+ s->insn_config = ni_660x_dio_insn_config;
+ s->io_bits = 0; /* all bits default to input */
+ // we use the ioconfig registers to control dio direction, so zero output enables in stc dio control reg
+ ni_660x_write_register(dev, 0, 0, STCDIOControl);
+
+ private(dev)->counter_dev = ni_gpct_device_construct(dev,
+ &ni_gpct_write_register, &ni_gpct_read_register,
+ ni_gpct_variant_660x, ni_660x_num_counters(dev));
+ if (private(dev)->counter_dev == NULL)
+ return -ENOMEM;
+ for (i = 0; i < NI_660X_MAX_NUM_COUNTERS; ++i) {
+ s = dev->subdevices + NI_660X_GPCT_SUBDEV(i);
+ if (i < ni_660x_num_counters(dev)) {
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL |
+ SDF_CMD_READ /* | SDF_CMD_WRITE */ ;
+ s->n_chan = 3;
+ s->maxdata = 0xffffffff;
+ s->insn_read = ni_660x_GPCT_rinsn;
+ s->insn_write = ni_660x_GPCT_winsn;
+ s->insn_config = ni_660x_GPCT_insn_config;
+ s->do_cmd = &ni_660x_cmd;
+ s->len_chanlist = 1;
+ s->do_cmdtest = &ni_660x_cmdtest;
+ s->cancel = &ni_660x_cancel;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->buf_change = &ni_660x_buf_change;
+ s->private = &private(dev)->counter_dev->counters[i];
+
+ private(dev)->counter_dev->counters[i].chip_index =
+ i / counters_per_chip;
+ private(dev)->counter_dev->counters[i].counter_index =
+ i % counters_per_chip;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ }
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ init_tio_chip(dev, i);
+ }
+ for (i = 0; i < ni_660x_num_counters(dev); ++i) {
+ ni_tio_init_counter(&private(dev)->counter_dev->counters[i]);
+ }
+ for (i = 0; i < NUM_PFI_CHANNELS; ++i) {
+ if (i < min_counter_pfi_chan)
+ ni_660x_set_pfi_routing(dev, i, pfi_output_select_do);
+ else
+ ni_660x_set_pfi_routing(dev, i,
+ pfi_output_select_counter);
+ ni_660x_select_pfi_output(dev, i, pfi_output_select_high_Z);
+ }
+ /* to be safe, set counterswap bits on tio chips after all the counter
+ outputs have been set to high impedance mode */
+ for (i = 0; i < board(dev)->n_chips; ++i) {
+ set_tio_counterswap(dev, i);
+ }
+ if ((ret = comedi_request_irq(mite_irq(private(dev)->mite),
+ &ni_660x_interrupt, IRQF_SHARED, "ni_660x",
+ dev)) < 0) {
+ printk(" irq not available\n");
+ return ret;
+ }
+ dev->irq = mite_irq(private(dev)->mite);
+ global_interrupt_config_bits = Global_Int_Enable_Bit;
+ if (board(dev)->n_chips > 1)
+ global_interrupt_config_bits |= Cascade_Int_Enable_Bit;
+ ni_660x_write_register(dev, 0, global_interrupt_config_bits,
+ GlobalInterruptConfigRegister);
+ printk("attached\n");
+ return 0;
+}
+
+static int ni_660x_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_660x: remove\n", dev->minor);
+
+ /* Free irq */
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->private) {
+ if (private(dev)->counter_dev)
+ ni_gpct_device_destroy(private(dev)->counter_dev);
+ if (private(dev)->mite) {
+ ni_660x_free_mite_rings(dev);
+ mite_unsetup(private(dev)->mite);
+ }
+ }
+ return 0;
+}
+
+static int
+ni_660x_GPCT_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return ni_tio_rinsn(subdev_to_counter(s), insn, data);
+}
+
+static void init_tio_chip(struct comedi_device * dev, int chipset)
+{
+ unsigned i;
+
+ // init dma configuration register
+ private(dev)->dma_configuration_soft_copies[chipset] = 0;
+ for (i = 0; i < MAX_DMA_CHANNEL; ++i) {
+ private(dev)->dma_configuration_soft_copies[chipset] |=
+ dma_select_bits(i,
+ dma_selection_none) & dma_select_mask(i);
+ }
+ ni_660x_write_register(dev, chipset,
+ private(dev)->dma_configuration_soft_copies[chipset],
+ DMAConfigRegister);
+ for(i = 0; i < NUM_PFI_CHANNELS; ++i)
+ {
+ ni_660x_write_register(dev, chipset, 0, IOConfigReg(i));
+ }
+}
+
+static int
+ni_660x_GPCT_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ return ni_tio_insn_config(subdev_to_counter(s), insn, data);
+}
+
+static int ni_660x_GPCT_winsn(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ return ni_tio_winsn(subdev_to_counter(s), insn, data);
+}
+
+static int ni_660x_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+
+ for (i = 0; i < n_ni_660x_boards; i++) {
+ if (mite_device_id(mite) == ni_660x_boards[i].dev_id) {
+ dev->board_ptr = ni_660x_boards + i;
+ private(dev)->mite = mite;
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+static int ni_660x_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned base_bitfield_channel = CR_CHAN(insn->chanspec);
+
+ // Check if we have to write some bits
+ if (data[0]) {
+ s->state &= ~(data[0] << base_bitfield_channel);
+ s->state |= (data[0] & data[1]) << base_bitfield_channel;
+ /* Write out the new digital output lines */
+ ni_660x_write_register(dev, 0, s->state, DIO32Output);
+ }
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ data[1] =
+ (ni_660x_read_register(dev, 0,
+ DIO32Input) >> base_bitfield_channel);
+ return 2;
+}
+
+static void ni_660x_select_pfi_output(struct comedi_device * dev, unsigned pfi_channel,
+ unsigned output_select)
+{
+ static const unsigned counter_4_7_first_pfi = 8;
+ static const unsigned counter_4_7_last_pfi = 23;
+ unsigned active_chipset = 0;
+ unsigned idle_chipset = 0;
+ unsigned active_bits;
+ unsigned idle_bits;
+
+ if(board(dev)->n_chips > 1) {
+ if(output_select == pfi_output_select_counter &&
+ pfi_channel >= counter_4_7_first_pfi &&
+ pfi_channel <= counter_4_7_last_pfi) {
+ active_chipset = 1;
+ idle_chipset = 0;
+ }else {
+ active_chipset = 0;
+ idle_chipset = 1;
+ }
+ }
+
+ if(idle_chipset != active_chipset) {
+ idle_bits = ni_660x_read_register(dev, idle_chipset, IOConfigReg(pfi_channel));
+ idle_bits &= ~pfi_output_select_mask(pfi_channel);
+ idle_bits |= pfi_output_select_bits(pfi_channel, pfi_output_select_high_Z);
+ ni_660x_write_register(dev, idle_chipset, idle_bits, IOConfigReg(pfi_channel));
+ }
+
+ active_bits = ni_660x_read_register(dev, active_chipset, IOConfigReg(pfi_channel));
+ active_bits &= ~pfi_output_select_mask(pfi_channel);
+ active_bits |= pfi_output_select_bits(pfi_channel, output_select);
+ ni_660x_write_register(dev, active_chipset, active_bits, IOConfigReg(pfi_channel));
+}
+
+static int ni_660x_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (source > num_pfi_output_selects)
+ return -EINVAL;
+ if (source == pfi_output_select_high_Z)
+ return -EINVAL;
+ if (chan < min_counter_pfi_chan) {
+ if (source == pfi_output_select_counter)
+ return -EINVAL;
+ } else if (chan > max_dio_pfi_chan) {
+ if (source == pfi_output_select_do)
+ return -EINVAL;
+ }
+ BUG_ON(chan >= NUM_PFI_CHANNELS);
+
+ private(dev)->pfi_output_selects[chan] = source;
+ if (private(dev)->pfi_direction_bits & (((uint64_t) 1) << chan))
+ ni_660x_select_pfi_output(dev, chan,
+ private(dev)->pfi_output_selects[chan]);
+ return 0;
+}
+
+static unsigned ni_660x_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ BUG_ON(chan >= NUM_PFI_CHANNELS);
+ return private(dev)->pfi_output_selects[chan];
+}
+
+static void ni660x_config_filter(struct comedi_device * dev, unsigned pfi_channel,
+ enum ni_gpct_filter_select filter)
+{
+ unsigned bits = ni_660x_read_register(dev, 0, IOConfigReg(pfi_channel));
+ bits &= ~pfi_input_select_mask(pfi_channel);
+ bits |= pfi_input_select_bits(pfi_channel, filter);
+ ni_660x_write_register(dev, 0, bits, IOConfigReg(pfi_channel));
+}
+
+static int ni_660x_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ private(dev)->pfi_direction_bits |= ((uint64_t) 1) << chan;
+ ni_660x_select_pfi_output(dev, chan,
+ private(dev)->pfi_output_selects[chan]);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ private(dev)->pfi_direction_bits &= ~(((uint64_t) 1) << chan);
+ ni_660x_select_pfi_output(dev, chan, pfi_output_select_high_Z);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (private(dev)->
+ pfi_direction_bits & (((uint64_t) 1) << chan)) ?
+ COMEDI_OUTPUT : COMEDI_INPUT;
+ return 0;
+ case INSN_CONFIG_SET_ROUTING:
+ return ni_660x_set_pfi_routing(dev, chan, data[1]);
+ break;
+ case INSN_CONFIG_GET_ROUTING:
+ data[1] = ni_660x_get_pfi_routing(dev, chan);
+ break;
+ case INSN_CONFIG_FILTER:
+ ni660x_config_filter(dev, chan, data[1]);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ };
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_670x.c b/drivers/staging/comedi/drivers/ni_670x.c
new file mode 100644
index 00000000000..d1312e073a6
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_670x.c
@@ -0,0 +1,337 @@
+/*
+ comedi/drivers/ni_670x.c
+ Hardware driver for NI 670x devices
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_670x
+Description: National Instruments 670x
+Author: Bart Joris <bjoris@advalvas.be>
+Updated: Wed, 11 Dec 2002 18:25:35 -0800
+Devices: [National Instruments] PCI-6703 (ni_670x), PCI-6704
+Status: unknown
+
+Commands are not supported.
+*/
+
+/*
+ Bart Joris <bjoris@advalvas.be> Last updated on 20/08/2001
+
+ Manuals:
+
+ 322110a.pdf PCI/PXI-6704 User Manual
+ 322110b.pdf PCI/PXI-6703/6704 User Manual
+
+*/
+
+#include "../comedidev.h"
+
+#include "mite.h"
+
+#define PCI_VENDOR_ID_NATINST 0x1093
+
+#define AO_VALUE_OFFSET 0x00
+#define AO_CHAN_OFFSET 0x0c
+#define AO_STATUS_OFFSET 0x10
+#define AO_CONTROL_OFFSET 0x10
+#define DIO_PORT0_DIR_OFFSET 0x20
+#define DIO_PORT0_DATA_OFFSET 0x24
+#define DIO_PORT1_DIR_OFFSET 0x28
+#define DIO_PORT1_DATA_OFFSET 0x2c
+#define MISC_STATUS_OFFSET 0x14
+#define MISC_CONTROL_OFFSET 0x14
+
+/* Board description*/
+
+struct ni_670x_board {
+ unsigned short dev_id;
+ const char *name;
+ unsigned short ao_chans;
+ unsigned short ao_bits;
+};
+
+static const struct ni_670x_board ni_670x_boards[] = {
+ {
+ dev_id: 0x2c90,
+ name: "PCI-6703",
+ ao_chans:16,
+ ao_bits: 16,
+ },
+ {
+ dev_id: 0x1920,
+ name: "PXI-6704",
+ ao_chans:32,
+ ao_bits: 16,
+ },
+ {
+ dev_id: 0x1290,
+ name: "PCI-6704",
+ ao_chans:32,
+ ao_bits: 16,
+ },
+};
+
+static DEFINE_PCI_DEVICE_TABLE(ni_670x_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x2c90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ //{ PCI_VENDOR_ID_NATINST, 0x0000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_670x_pci_table);
+
+#define thisboard ((struct ni_670x_board *)dev->board_ptr)
+
+struct ni_670x_private {
+
+ struct mite_struct *mite;
+ int boardtype;
+ int dio;
+ unsigned int ao_readback[32];
+};
+
+
+#define devpriv ((struct ni_670x_private *)dev->private)
+#define n_ni_670x_boards (sizeof(ni_670x_boards)/sizeof(ni_670x_boards[0]))
+
+static int ni_670x_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_670x_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_ni_670x = {
+ driver_name:"ni_670x",
+ module:THIS_MODULE,
+ attach:ni_670x_attach,
+ detach:ni_670x_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_ni_670x, ni_670x_pci_table);
+
+static struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
+
+static int ni_670x_find_device(struct comedi_device * dev, int bus, int slot);
+
+static int ni_670x_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_670x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_670x_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int ret;
+ int i;
+
+ printk("comedi%d: ni_670x: ", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct ni_670x_private))) < 0)
+ return ret;
+
+ ret = ni_670x_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+ dev->board_name = thisboard->name;
+ dev->irq = mite_irq(devpriv->mite);
+ printk(" %s", dev->board_name);
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->ao_chans;
+ s->maxdata = 0xffff;
+ if (s->n_chan == 32) {
+ const struct comedi_lrange **range_table_list;
+
+ range_table_list = kmalloc(sizeof(struct comedi_lrange *) * 32,
+ GFP_KERNEL);
+ if (!range_table_list)
+ return -ENOMEM;
+ s->range_table_list = range_table_list;
+ for (i = 0; i < 16; i++) {
+ range_table_list[i] = &range_bipolar10;
+ range_table_list[16 + i] = &range_0_20mA;
+ }
+ } else {
+ s->range_table = &range_bipolar10;
+ }
+ s->insn_write = &ni_670x_ao_winsn;
+ s->insn_read = &ni_670x_ao_rinsn;
+
+ s = dev->subdevices + 1;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = ni_670x_dio_insn_bits;
+ s->insn_config = ni_670x_dio_insn_config;
+
+ writel(0x10, devpriv->mite->daq_io_addr + MISC_CONTROL_OFFSET); /* Config of misc registers */
+ writel(0x00, devpriv->mite->daq_io_addr + AO_CONTROL_OFFSET); /* Config of ao registers */
+
+ printk("attached\n");
+
+ return 1;
+}
+
+static int ni_670x_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_670x: remove\n", dev->minor);
+
+ if (dev->subdevices[0].range_table_list) {
+ kfree(dev->subdevices[0].range_table_list);
+ }
+ if (dev->private && devpriv->mite)
+ mite_unsetup(devpriv->mite);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+}
+
+static int ni_670x_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* Channel number mapping :
+
+ NI 6703/ NI 6704 | NI 6704 Only
+ ----------------------------------------------------
+ vch(0) : 0 | ich(16) : 1
+ vch(1) : 2 | ich(17) : 3
+ . : . | . .
+ . : . | . .
+ . : . | . .
+ vch(15) : 30 | ich(31) : 31 */
+
+ for (i = 0; i < insn->n; i++) {
+ writel(((chan & 15) << 1) | ((chan & 16) >> 4), devpriv->mite->daq_io_addr + AO_CHAN_OFFSET); /* First write in channel register which channel to use */
+ writel(data[i], devpriv->mite->daq_io_addr + AO_VALUE_OFFSET); /* write channel value */
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int ni_670x_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int ni_670x_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ writel(s->state,
+ devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input lines. */
+ data[1] = readl(devpriv->mite->daq_io_addr + DIO_PORT0_DATA_OFFSET);
+
+ return 2;
+}
+
+static int ni_670x_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << chan);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ writel(s->io_bits, devpriv->mite->daq_io_addr + DIO_PORT0_DIR_OFFSET);
+
+ return insn->n;
+}
+
+static int ni_670x_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number
+ || slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+
+ for (i = 0; i < n_ni_670x_boards; i++) {
+ if (mite_device_id(mite) == ni_670x_boards[i].dev_id) {
+ dev->board_ptr = ni_670x_boards + i;
+ devpriv->mite = mite;
+
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
diff --git a/drivers/staging/comedi/drivers/ni_at_a2150.c b/drivers/staging/comedi/drivers/ni_at_a2150.c
new file mode 100644
index 00000000000..5d45bf24a5e
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_at_a2150.c
@@ -0,0 +1,909 @@
+/*
+ comedi/drivers/ni_at_a2150.c
+ Driver for National Instruments AT-A2150 boards
+ Copyright (C) 2001, 2002 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: ni_at_a2150
+Description: National Instruments AT-A2150
+Author: Frank Mori Hess
+Status: works
+Devices: [National Instruments] AT-A2150C (at_a2150c), AT-2150S (at_a2150s)
+
+If you want to ac couple the board's inputs, use AREF_OTHER.
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed conversions)
+ [2] - DMA (optional, required for timed conversions)
+
+*/
+/*
+Yet another driver for obsolete hardware brought to you by Frank Hess.
+Testing and debugging help provided by Dave Andruczyk.
+
+This driver supports the boards:
+
+AT-A2150C
+AT-A2150S
+
+The only difference is their master clock frequencies.
+
+Options:
+ [0] - base io address
+ [1] - irq
+ [2] - dma channel
+
+References (from ftp://ftp.natinst.com/support/manuals):
+
+ 320360.pdf AT-A2150 User Manual
+
+TODO:
+
+analog level triggering
+TRIG_WAKE_EOS
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "comedi_fc.h"
+
+#define A2150_SIZE 28
+#define A2150_DMA_BUFFER_SIZE 0xff00 // size in bytes of dma buffer
+
+//#define A2150_DEBUG // enable debugging code
+#undef A2150_DEBUG // disable debugging code
+
+/* Registers and bits */
+#define CONFIG_REG 0x0
+#define CHANNEL_BITS(x) ((x) & 0x7)
+#define CHANNEL_MASK 0x7
+#define CLOCK_SELECT_BITS(x) (((x) & 0x3) << 3)
+#define CLOCK_DIVISOR_BITS(x) (((x) & 0x3) << 5)
+#define CLOCK_MASK (0xf << 3)
+#define ENABLE0_BIT 0x80 // enable (don't internally ground) channels 0 and 1
+#define ENABLE1_BIT 0x100 // enable (don't internally ground) channels 2 and 3
+#define AC0_BIT 0x200 // ac couple channels 0,1
+#define AC1_BIT 0x400 // ac couple channels 2,3
+#define APD_BIT 0x800 // analog power down
+#define DPD_BIT 0x1000 // digital power down
+#define TRIGGER_REG 0x2 // trigger config register
+#define POST_TRIGGER_BITS 0x2
+#define DELAY_TRIGGER_BITS 0x3
+#define HW_TRIG_EN 0x10 // enable hardware trigger
+#define FIFO_START_REG 0x6 // software start aquistion trigger
+#define FIFO_RESET_REG 0x8 // clears fifo + fifo flags
+#define FIFO_DATA_REG 0xa // read data
+#define DMA_TC_CLEAR_REG 0xe // clear dma terminal count interrupt
+#define STATUS_REG 0x12 // read only
+#define FNE_BIT 0x1 // fifo not empty
+#define OVFL_BIT 0x8 // fifo overflow
+#define EDAQ_BIT 0x10 // end of aquisition interrupt
+#define DCAL_BIT 0x20 // offset calibration in progress
+#define INTR_BIT 0x40 // interrupt has occured
+#define DMA_TC_BIT 0x80 // dma terminal count interrupt has occured
+#define ID_BITS(x) (((x) >> 8) & 0x3)
+#define IRQ_DMA_CNTRL_REG 0x12 // write only
+#define DMA_CHAN_BITS(x) ((x) & 0x7) // sets dma channel
+#define DMA_EN_BIT 0x8 // enables dma
+#define IRQ_LVL_BITS(x) (((x) & 0xf) << 4) // sets irq level
+#define FIFO_INTR_EN_BIT 0x100 // enable fifo interrupts
+#define FIFO_INTR_FHF_BIT 0x200 // interrupt fifo half full
+#define DMA_INTR_EN_BIT 0x800 // enable interrupt on dma terminal count
+#define DMA_DEM_EN_BIT 0x1000 // enables demand mode dma
+#define I8253_BASE_REG 0x14
+#define I8253_MODE_REG 0x17
+#define HW_COUNT_DISABLE 0x30 // disable hardware counting of conversions
+
+struct a2150_board {
+ const char *name;
+ int clock[4]; // master clock periods, in nanoseconds
+ int num_clocks; // number of available master clock speeds
+ int ai_speed; // maximum conversion rate in nanoseconds
+};
+
+//analog input range
+static const struct comedi_lrange range_a2150 = {
+ 1,
+ {
+ RANGE(-2.828, 2.828),
+ }
+};
+
+// enum must match board indices
+enum { a2150_c, a2150_s };
+static const struct a2150_board a2150_boards[] = {
+ {
+ name: "at-a2150c",
+ clock: {31250, 22676, 20833, 19531},
+ num_clocks:4,
+ ai_speed:19531,
+ },
+ {
+ name: "at-a2150s",
+ clock: {62500, 50000, 41667, 0},
+ num_clocks:3,
+ ai_speed:41667,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct a2150_board *)dev->board_ptr)
+
+struct a2150_private {
+
+ volatile unsigned int count; /* number of data points left to be taken */
+ unsigned int dma; // dma channel
+ s16 *dma_buffer; // dma buffer
+ unsigned int dma_transfer_size; // size in bytes of dma transfers
+ int irq_dma_bits; // irq/dma register bits
+ int config_bits; // config register bits
+};
+
+
+#define devpriv ((struct a2150_private *)dev->private)
+
+static int a2150_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int a2150_detach(struct comedi_device * dev);
+static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_a2150 = {
+ driver_name:"ni_at_a2150",
+ module:THIS_MODULE,
+ attach:a2150_attach,
+ detach:a2150_detach,
+};
+
+static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG);
+static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
+ int flags);
+static int a2150_probe(struct comedi_device * dev);
+static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
+ unsigned int num_channels);
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_a2150);
+
+#ifdef A2150_DEBUG
+
+static void ni_dump_regs(struct comedi_device * dev)
+{
+ rt_printk("config bits 0x%x\n", devpriv->config_bits);
+ rt_printk("irq dma bits 0x%x\n", devpriv->irq_dma_bits);
+ rt_printk("status bits 0x%x\n", inw(dev->iobase + STATUS_REG));
+}
+
+#endif
+
+/* interrupt service routine */
+static irqreturn_t a2150_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int i;
+ int status;
+ unsigned long flags;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+ unsigned int max_points, num_points, residue, leftover;
+ short dpnt;
+ static const int sample_size = sizeof(devpriv->dma_buffer[0]);
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+ // initialize async here to make sure s is not NULL
+ async = s->async;
+ async->events = 0;
+ cmd = &async->cmd;
+
+ status = inw(dev->iobase + STATUS_REG);
+
+ if ((status & INTR_BIT) == 0) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_NONE;
+ }
+
+ if (status & OVFL_BIT) {
+ comedi_error(dev, "fifo overflow");
+ a2150_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ }
+
+ if ((status & DMA_TC_BIT) == 0) {
+ comedi_error(dev, "caught non-dma interrupt? Aborting.");
+ a2150_cancel(dev, s);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma);
+
+ // figure out how many points to read
+ max_points = devpriv->dma_transfer_size / sample_size;
+ /* residue is the number of points left to be done on the dma
+ * transfer. It should always be zero at this point unless
+ * the stop_src is set to external triggering.
+ */
+ residue = get_dma_residue(devpriv->dma) / sample_size;
+ num_points = max_points - residue;
+ if (devpriv->count < num_points && cmd->stop_src == TRIG_COUNT)
+ num_points = devpriv->count;
+
+ // figure out how many points will be stored next time
+ leftover = 0;
+ if (cmd->stop_src == TRIG_NONE) {
+ leftover = devpriv->dma_transfer_size / sample_size;
+ } else if (devpriv->count > max_points) {
+ leftover = devpriv->count - max_points;
+ if (leftover > max_points)
+ leftover = max_points;
+ }
+ /* there should only be a residue if collection was stopped by having
+ * the stop_src set to an external trigger, in which case there
+ * will be no more data
+ */
+ if (residue)
+ leftover = 0;
+
+ for (i = 0; i < num_points; i++) {
+ /* write data point to comedi buffer */
+ dpnt = devpriv->dma_buffer[i];
+ // convert from 2's complement to unsigned coding
+ dpnt ^= 0x8000;
+ cfc_write_to_buffer(s, dpnt);
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (--devpriv->count == 0) { /* end of acquisition */
+ a2150_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+ }
+ // re-enable dma
+ if (leftover) {
+ set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
+ set_dma_count(devpriv->dma, leftover * sample_size);
+ enable_dma(devpriv->dma);
+ }
+ release_dma_lock(flags);
+
+ async->events |= COMEDI_CB_BLOCK;
+
+ comedi_event(dev, s);
+
+ /* clear interrupt */
+ outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
+
+ return IRQ_HANDLED;
+}
+
+// probes board type, returns offset
+static int a2150_probe(struct comedi_device * dev)
+{
+ int status = inw(dev->iobase + STATUS_REG);
+ return ID_BITS(status);
+}
+
+static int a2150_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = it->options[0];
+ unsigned int irq = it->options[1];
+ unsigned int dma = it->options[2];
+ static const int timeout = 2000;
+ int i;
+
+ printk("comedi%d: %s: io 0x%lx", dev->minor, driver_a2150.driver_name,
+ iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ } else {
+ printk(", no irq");
+ }
+ if (dma) {
+ printk(", dma %u", dma);
+ } else {
+ printk(", no dma");
+ }
+ printk("\n");
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct a2150_private)) < 0)
+ return -ENOMEM;
+
+ if (iobase == 0) {
+ printk(" io base address required\n");
+ return -EINVAL;
+ }
+
+ /* check if io addresses are available */
+ if (!request_region(iobase, A2150_SIZE, driver_a2150.driver_name)) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* grab our IRQ */
+ if (irq) {
+ // check that irq is supported
+ if (irq < 3 || irq == 8 || irq == 13 || irq > 15) {
+ printk(" invalid irq line %u\n", irq);
+ return -EINVAL;
+ }
+ if (comedi_request_irq(irq, a2150_interrupt, 0,
+ driver_a2150.driver_name, dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ devpriv->irq_dma_bits |= IRQ_LVL_BITS(irq);
+ dev->irq = irq;
+ }
+ // initialize dma
+ if (dma) {
+ if (dma == 4 || dma > 7) {
+ printk(" invalid dma channel %u\n", dma);
+ return -EINVAL;
+ }
+ if (request_dma(dma, driver_a2150.driver_name)) {
+ printk(" failed to allocate dma channel %u\n", dma);
+ return -EINVAL;
+ }
+ devpriv->dma = dma;
+ devpriv->dma_buffer =
+ kmalloc(A2150_DMA_BUFFER_SIZE, GFP_KERNEL | GFP_DMA);
+ if (devpriv->dma_buffer == NULL)
+ return -ENOMEM;
+
+ disable_dma(dma);
+ set_dma_mode(dma, DMA_MODE_READ);
+
+ devpriv->irq_dma_bits |= DMA_CHAN_BITS(dma);
+ }
+
+ dev->board_ptr = a2150_boards + a2150_probe(dev);
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_OTHER | SDF_CMD_READ;
+ s->n_chan = 4;
+ s->len_chanlist = 4;
+ s->maxdata = 0xffff;
+ s->range_table = &range_a2150;
+ s->do_cmd = a2150_ai_cmd;
+ s->do_cmdtest = a2150_ai_cmdtest;
+ s->insn_read = a2150_ai_rinsn;
+ s->cancel = a2150_cancel;
+
+ /* need to do this for software counting of completed conversions, to
+ * prevent hardware count from stopping aquisition */
+ outw(HW_COUNT_DISABLE, dev->iobase + I8253_MODE_REG);
+
+ // set card's irq and dma levels
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // reset and sync adc clock circuitry
+ outw_p(DPD_BIT | APD_BIT, dev->iobase + CONFIG_REG);
+ outw_p(DPD_BIT, dev->iobase + CONFIG_REG);
+ // initialize configuration register
+ devpriv->config_bits = 0;
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+ // wait until offset calibration is done, then enable analog inputs
+ for (i = 0; i < timeout; i++) {
+ if ((DCAL_BIT & inw(dev->iobase + STATUS_REG)) == 0)
+ break;
+ comedi_udelay(1000);
+ }
+ if (i == timeout) {
+ printk(" timed out waiting for offset calibration to complete\n");
+ return -ETIME;
+ }
+ devpriv->config_bits |= ENABLE0_BIT | ENABLE1_BIT;
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+ return 0;
+};
+
+static int a2150_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: %s: remove\n", dev->minor, driver_a2150.driver_name);
+
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase) {
+ // put board in power-down mode
+ outw(APD_BIT | DPD_BIT, dev->iobase + CONFIG_REG);
+ release_region(dev->iobase, A2150_SIZE);
+ }
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (devpriv) {
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ if (devpriv->dma_buffer)
+ kfree(devpriv->dma_buffer);
+ }
+
+ return 0;
+};
+
+static int a2150_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ // disable dma on card
+ devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // disable computer's dma
+ disable_dma(devpriv->dma);
+
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ return 0;
+}
+
+static int a2150_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int startChan;
+ int i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ // check channel/gain list against card's limitations
+ if (cmd->chanlist) {
+ startChan = CR_CHAN(cmd->chanlist[0]);
+ for (i = 1; i < cmd->chanlist_len; i++) {
+ if (CR_CHAN(cmd->chanlist[i]) != (startChan + i)) {
+ comedi_error(dev,
+ "entries in chanlist must be consecutive channels, counting upwards\n");
+ err++;
+ }
+ }
+ if (cmd->chanlist_len == 2 && CR_CHAN(cmd->chanlist[0]) == 1) {
+ comedi_error(dev,
+ "length 2 chanlist must be channels 0,1 or channels 2,3");
+ err++;
+ }
+ if (cmd->chanlist_len == 3) {
+ comedi_error(dev,
+ "chanlist must have 1,2 or 4 channels");
+ err++;
+ }
+ if (CR_AREF(cmd->chanlist[0]) != CR_AREF(cmd->chanlist[1]) ||
+ CR_AREF(cmd->chanlist[2]) != CR_AREF(cmd->chanlist[3]))
+ {
+ comedi_error(dev,
+ "channels 0/1 and 2/3 must have the same analog reference");
+ err++;
+ }
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int a2150_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ unsigned long lock_flags;
+ unsigned int old_config_bits = devpriv->config_bits;
+ unsigned int trigger_bits;
+
+ if (!dev->irq || !devpriv->dma) {
+ comedi_error(dev,
+ " irq and dma required, cannot do hardware conversions");
+ return -1;
+ }
+ if (cmd->flags & TRIG_RT) {
+ comedi_error(dev,
+ " dma incompatible with hard real-time interrupt (TRIG_RT), aborting");
+ return -1;
+ }
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ /* setup chanlist */
+ if (a2150_set_chanlist(dev, CR_CHAN(cmd->chanlist[0]),
+ cmd->chanlist_len) < 0)
+ return -1;
+
+ // setup ac/dc coupling
+ if (CR_AREF(cmd->chanlist[0]) == AREF_OTHER)
+ devpriv->config_bits |= AC0_BIT;
+ else
+ devpriv->config_bits &= ~AC0_BIT;
+ if (CR_AREF(cmd->chanlist[2]) == AREF_OTHER)
+ devpriv->config_bits |= AC1_BIT;
+ else
+ devpriv->config_bits &= ~AC1_BIT;
+
+ // setup timing
+ a2150_get_timing(dev, &cmd->scan_begin_arg, cmd->flags);
+
+ // send timing, channel, config bits
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+ // initialize number of samples remaining
+ devpriv->count = cmd->stop_arg * cmd->chanlist_len;
+
+ // enable computer's dma
+ lock_flags = claim_dma_lock();
+ disable_dma(devpriv->dma);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, virt_to_bus(devpriv->dma_buffer));
+ // set size of transfer to fill in 1/3 second
+#define ONE_THIRD_SECOND 333333333
+ devpriv->dma_transfer_size =
+ sizeof(devpriv->dma_buffer[0]) * cmd->chanlist_len *
+ ONE_THIRD_SECOND / cmd->scan_begin_arg;
+ if (devpriv->dma_transfer_size > A2150_DMA_BUFFER_SIZE)
+ devpriv->dma_transfer_size = A2150_DMA_BUFFER_SIZE;
+ if (devpriv->dma_transfer_size < sizeof(devpriv->dma_buffer[0]))
+ devpriv->dma_transfer_size = sizeof(devpriv->dma_buffer[0]);
+ devpriv->dma_transfer_size -=
+ devpriv->dma_transfer_size % sizeof(devpriv->dma_buffer[0]);
+ set_dma_count(devpriv->dma, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma);
+ release_dma_lock(lock_flags);
+
+ /* clear dma interrupt before enabling it, to try and get rid of that
+ * one spurious interrupt that has been happening */
+ outw(0x00, dev->iobase + DMA_TC_CLEAR_REG);
+
+ // enable dma on card
+ devpriv->irq_dma_bits |= DMA_INTR_EN_BIT | DMA_EN_BIT;
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // may need to wait 72 sampling periods if timing was changed
+ i8254_load(dev->iobase + I8253_BASE_REG, 0, 2, 72, 0);
+
+ // setup start triggering
+ trigger_bits = 0;
+ // decide if we need to wait 72 periods for valid data
+ if (cmd->start_src == TRIG_NOW &&
+ (old_config_bits & CLOCK_MASK) !=
+ (devpriv->config_bits & CLOCK_MASK)) {
+ // set trigger source to delay trigger
+ trigger_bits |= DELAY_TRIGGER_BITS;
+ } else {
+ // otherwise no delay
+ trigger_bits |= POST_TRIGGER_BITS;
+ }
+ // enable external hardware trigger
+ if (cmd->start_src == TRIG_EXT) {
+ trigger_bits |= HW_TRIG_EN;
+ } else if (cmd->start_src == TRIG_OTHER) {
+ // XXX add support for level/slope start trigger using TRIG_OTHER
+ comedi_error(dev, "you shouldn't see this?");
+ }
+ // send trigger config bits
+ outw(trigger_bits, dev->iobase + TRIGGER_REG);
+
+ // start aquisition for soft trigger
+ if (cmd->start_src == TRIG_NOW) {
+ outw(0, dev->iobase + FIFO_START_REG);
+ }
+#ifdef A2150_DEBUG
+ ni_dump_regs(dev);
+#endif
+
+ return 0;
+}
+
+static int a2150_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int i, n;
+ static const int timeout = 100000;
+ static const int filter_delay = 36;
+
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ /* setup chanlist */
+ if (a2150_set_chanlist(dev, CR_CHAN(insn->chanspec), 1) < 0)
+ return -1;
+
+ // set dc coupling
+ devpriv->config_bits &= ~AC0_BIT;
+ devpriv->config_bits &= ~AC1_BIT;
+
+ // send timing, channel, config bits
+ outw(devpriv->config_bits, dev->iobase + CONFIG_REG);
+
+ // disable dma on card
+ devpriv->irq_dma_bits &= ~DMA_INTR_EN_BIT & ~DMA_EN_BIT;
+ outw(devpriv->irq_dma_bits, dev->iobase + IRQ_DMA_CNTRL_REG);
+
+ // setup start triggering
+ outw(0, dev->iobase + TRIGGER_REG);
+
+ // start aquisition for soft trigger
+ outw(0, dev->iobase + FIFO_START_REG);
+
+ /* there is a 35.6 sample delay for data to get through the antialias filter */
+ for (n = 0; n < filter_delay; n++) {
+ for (i = 0; i < timeout; i++) {
+ if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
+ break;
+ comedi_udelay(1);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ inw(dev->iobase + FIFO_DATA_REG);
+ }
+
+ // read data
+ for (n = 0; n < insn->n; n++) {
+ for (i = 0; i < timeout; i++) {
+ if (inw(dev->iobase + STATUS_REG) & FNE_BIT)
+ break;
+ comedi_udelay(1);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+#ifdef A2150_DEBUG
+ ni_dump_regs(dev);
+#endif
+ data[n] = inw(dev->iobase + FIFO_DATA_REG);
+#ifdef A2150_DEBUG
+ rt_printk(" data is %i\n", data[n]);
+#endif
+ data[n] ^= 0x8000;
+ }
+
+ // clear fifo and reset triggering circuitry
+ outw(0, dev->iobase + FIFO_RESET_REG);
+
+ return n;
+}
+
+/* sets bits in devpriv->clock_bits to nearest approximation of requested period,
+ * adjusts requested period to actual timing. */
+static int a2150_get_timing(struct comedi_device * dev, unsigned int *period,
+ int flags)
+{
+ int lub, glb, temp;
+ int lub_divisor_shift, lub_index, glb_divisor_shift, glb_index;
+ int i, j;
+
+ // initialize greatest lower and least upper bounds
+ lub_divisor_shift = 3;
+ lub_index = 0;
+ lub = thisboard->clock[lub_index] * (1 << lub_divisor_shift);
+ glb_divisor_shift = 0;
+ glb_index = thisboard->num_clocks - 1;
+ glb = thisboard->clock[glb_index] * (1 << glb_divisor_shift);
+
+ // make sure period is in available range
+ if (*period < glb)
+ *period = glb;
+ if (*period > lub)
+ *period = lub;
+
+ // we can multiply period by 1, 2, 4, or 8, using (1 << i)
+ for (i = 0; i < 4; i++) {
+ // there are a maximum of 4 master clocks
+ for (j = 0; j < thisboard->num_clocks; j++) {
+ // temp is the period in nanosec we are evaluating
+ temp = thisboard->clock[j] * (1 << i);
+ // if it is the best match yet
+ if (temp < lub && temp >= *period) {
+ lub_divisor_shift = i;
+ lub_index = j;
+ lub = temp;
+ }
+ if (temp > glb && temp <= *period) {
+ glb_divisor_shift = i;
+ glb_index = j;
+ glb = temp;
+ }
+ }
+ }
+ flags &= TRIG_ROUND_MASK;
+ switch (flags) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ // if least upper bound is better approximation
+ if (lub - *period < *period - glb) {
+ *period = lub;
+ } else {
+ *period = glb;
+ }
+ break;
+ case TRIG_ROUND_UP:
+ *period = lub;
+ break;
+ case TRIG_ROUND_DOWN:
+ *period = glb;
+ break;
+ }
+
+ // set clock bits for config register appropriately
+ devpriv->config_bits &= ~CLOCK_MASK;
+ if (*period == lub) {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(lub_index) |
+ CLOCK_DIVISOR_BITS(lub_divisor_shift);
+ } else {
+ devpriv->config_bits |=
+ CLOCK_SELECT_BITS(glb_index) |
+ CLOCK_DIVISOR_BITS(glb_divisor_shift);
+ }
+
+ return 0;
+}
+
+static int a2150_set_chanlist(struct comedi_device * dev, unsigned int start_channel,
+ unsigned int num_channels)
+{
+ if (start_channel + num_channels > 4)
+ return -1;
+
+ devpriv->config_bits &= ~CHANNEL_MASK;
+
+ switch (num_channels) {
+ case 1:
+ devpriv->config_bits |= CHANNEL_BITS(0x4 | start_channel);
+ break;
+ case 2:
+ if (start_channel == 0) {
+ devpriv->config_bits |= CHANNEL_BITS(0x2);
+ } else if (start_channel == 2) {
+ devpriv->config_bits |= CHANNEL_BITS(0x3);
+ } else {
+ return -1;
+ }
+ break;
+ case 4:
+ devpriv->config_bits |= CHANNEL_BITS(0x1);
+ break;
+ default:
+ return -1;
+ break;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_at_ao.c b/drivers/staging/comedi/drivers/ni_at_ao.c
new file mode 100644
index 00000000000..2cc46b67258
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_at_ao.c
@@ -0,0 +1,454 @@
+/*
+ comedi/drivers/ni_at_ao.c
+ Driver for NI AT-AO-6/10 boards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000,2002 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_at_ao
+Description: National Instruments AT-AO-6/10
+Devices: [National Instruments] AT-AO-6 (at-ao-6), AT-AO-10 (at-ao-10)
+Status: should work
+Author: ds
+Updated: Sun Dec 26 12:26:28 EST 2004
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ (unused)
+ [2] - DMA (unused)
+ [3] - analog output range, set by jumpers on hardware (0 for -10 to 10V bipolar, 1 for 0V to 10V unipolar)
+
+*/
+/*
+ * Register-level programming information can be found in NI
+ * document 320379.pdf.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+/* board egisters */
+/* registers with _2_ are accessed when GRP2WR is set in CFG1 */
+
+#define ATAO_SIZE 0x20
+
+#define ATAO_2_DMATCCLR 0x00 /* W 16 */
+#define ATAO_DIN 0x00 /* R 16 */
+#define ATAO_DOUT 0x00 /* W 16 */
+
+#define ATAO_CFG2 0x02 /* W 16 */
+#define CALLD1 0x8000
+#define CALLD0 0x4000
+#define FFRTEN 0x2000
+#define DAC2S8 0x1000
+#define DAC2S6 0x0800
+#define DAC2S4 0x0400
+#define DAC2S2 0x0200
+#define DAC2S0 0x0100
+#define LDAC8 0x0080
+#define LDAC6 0x0040
+#define LDAC4 0x0020
+#define LDAC2 0x0010
+#define LDAC0 0x0008
+#define PROMEN 0x0004
+#define SCLK 0x0002
+#define SDATA 0x0001
+
+#define ATAO_2_INT1CLR 0x02 /* W 16 */
+
+#define ATAO_CFG3 0x04 /* W 16 */
+#define DMAMODE 0x0040
+#define CLKOUT 0x0020
+#define RCLKEN 0x0010
+#define DOUTEN2 0x0008
+#define DOUTEN1 0x0004
+#define EN2_5V 0x0002
+#define SCANEN 0x0001
+
+#define ATAO_2_INT2CLR 0x04 /* W 16 */
+
+#define ATAO_82C53_BASE 0x06 /* RW 8 */
+
+#define ATAO_82C53_CNTR1 0x06 /* RW 8 */
+#define ATAO_82C53_CNTR2 0x07 /* RW 8 */
+#define ATAO_82C53_CNTR3 0x08 /* RW 8 */
+#define ATAO_82C53_CNTRCMD 0x09 /* W 8 */
+#define CNTRSEL1 0x80
+#define CNTRSEL0 0x40
+#define RWSEL1 0x20
+#define RWSEL0 0x10
+#define MODESEL2 0x08
+#define MODESEL1 0x04
+#define MODESEL0 0x02
+#define BCDSEL 0x01
+ /* read-back command */
+#define COUNT 0x20
+#define STATUS 0x10
+#define CNTR3 0x08
+#define CNTR2 0x04
+#define CNTR1 0x02
+ /* status */
+#define OUT 0x80
+#define _NULL 0x40
+#define RW1 0x20
+#define RW0 0x10
+#define MODE2 0x08
+#define MODE1 0x04
+#define MODE0 0x02
+#define BCD 0x01
+
+#define ATAO_2_RTSISHFT 0x06 /* W 8 */
+#define RSI 0x01
+
+#define ATAO_2_RTSISTRB 0x07 /* W 8 */
+
+#define ATAO_CFG1 0x0a /* W 16 */
+#define EXTINT2EN 0x8000
+#define EXTINT1EN 0x4000
+#define CNTINT2EN 0x2000
+#define CNTINT1EN 0x1000
+#define TCINTEN 0x0800
+#define CNT1SRC 0x0400
+#define CNT2SRC 0x0200
+#define FIFOEN 0x0100
+#define GRP2WR 0x0080
+#define EXTUPDEN 0x0040
+#define DMARQ 0x0020
+#define DMAEN 0x0010
+#define CH_mask 0x000f
+#define ATAO_STATUS 0x0a /* R 16 */
+#define FH 0x0040
+#define FE 0x0020
+#define FF 0x0010
+#define INT2 0x0008
+#define INT1 0x0004
+#define TCINT 0x0002
+#define PROMOUT 0x0001
+
+#define ATAO_FIFO_WRITE 0x0c /* W 16 */
+#define ATAO_FIFO_CLEAR 0x0c /* R 16 */
+#define ATAO_DACn(x) (0x0c + 2*(x)) /* W */
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct atao_board {
+ const char *name;
+ int n_ao_chans;
+};
+
+static const struct atao_board atao_boards[] = {
+ {
+ name: "ai-ao-6",
+ n_ao_chans:6,
+ },
+ {
+ name: "ai-ao-10",
+ n_ao_chans:10,
+ },
+};
+
+#define thisboard ((struct atao_board *)dev->board_ptr)
+
+struct atao_private {
+
+ unsigned short cfg1;
+ unsigned short cfg2;
+ unsigned short cfg3;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[10];
+};
+
+#define devpriv ((struct atao_private *)dev->private)
+
+static int atao_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int atao_detach(struct comedi_device * dev);
+static struct comedi_driver driver_atao = {
+ driver_name:"ni_at_ao",
+ module:THIS_MODULE,
+ attach:atao_attach,
+ detach:atao_detach,
+ board_name:&atao_boards[0].name,
+ offset:sizeof(struct atao_board),
+ num_names:sizeof(atao_boards) / sizeof(struct atao_board),
+};
+
+COMEDI_INITCLEANUP(driver_atao);
+
+static void atao_reset(struct comedi_device * dev);
+
+static int atao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int atao_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int atao_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ int ao_unipolar;
+
+ iobase = it->options[0];
+ if (iobase == 0)
+ iobase = 0x1c0;
+ ao_unipolar = it->options[3];
+
+ printk("comedi%d: ni_at_ao: 0x%04lx", dev->minor, iobase);
+
+ if (!request_region(iobase, ATAO_SIZE, "ni_at_ao")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ //dev->board_ptr = atao_probe(dev);
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_private(dev, sizeof(struct atao_private)) < 0)
+ return -ENOMEM;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = thisboard->n_ao_chans;
+ s->maxdata = (1 << 12) - 1;
+ if (ao_unipolar)
+ s->range_table = &range_unipolar10;
+ else
+ s->range_table = &range_bipolar10;
+ s->insn_write = &atao_ao_winsn;
+ s->insn_read = &atao_ao_rinsn;
+
+ s = dev->subdevices + 1;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = atao_dio_insn_bits;
+ s->insn_config = atao_dio_insn_config;
+
+ s = dev->subdevices + 2;
+ /* caldac subdevice */
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 21;
+ s->maxdata = 0xff;
+ s->insn_read = atao_calib_insn_read;
+ s->insn_write = atao_calib_insn_write;
+
+ s = dev->subdevices + 3;
+ /* eeprom subdevice */
+ //s->type=COMEDI_SUBD_EEPROM;
+ s->type = COMEDI_SUBD_UNUSED;
+
+ atao_reset(dev);
+
+ printk("\n");
+
+ return 0;
+}
+
+static int atao_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: atao: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, ATAO_SIZE);
+
+ return 0;
+}
+
+static void atao_reset(struct comedi_device * dev)
+{
+ /* This is the reset sequence described in the manual */
+
+ devpriv->cfg1 = 0;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+
+ outb(RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
+ outb(0x03, dev->iobase + ATAO_82C53_CNTR1);
+ outb(CNTRSEL0 | RWSEL0 | MODESEL2, dev->iobase + ATAO_82C53_CNTRCMD);
+
+ devpriv->cfg2 = 0;
+ outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+
+ devpriv->cfg3 = 0;
+ outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+
+ inw(dev->iobase + ATAO_FIFO_CLEAR);
+
+ devpriv->cfg1 |= GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+
+ outw(0, dev->iobase + ATAO_2_INT1CLR);
+ outw(0, dev->iobase + ATAO_2_INT2CLR);
+ outw(0, dev->iobase + ATAO_2_DMATCCLR);
+
+ devpriv->cfg1 &= ~GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+}
+
+static int atao_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ short bits;
+
+ for (i = 0; i < insn->n; i++) {
+ bits = data[i] - 0x800;
+ if (chan == 0) {
+ devpriv->cfg1 |= GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+ }
+ outw(bits, dev->iobase + ATAO_DACn(chan));
+ if (chan == 0) {
+ devpriv->cfg1 &= ~GRP2WR;
+ outw(devpriv->cfg1, dev->iobase + ATAO_CFG1);
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+static int atao_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int atao_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outw(s->state, dev->iobase + ATAO_DOUT);
+ }
+
+ data[1] = inw(dev->iobase + ATAO_DIN);
+
+ return 2;
+}
+
+static int atao_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned int mask, bit;
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ mask = (chan < 4) ? 0x0f : 0xf0;
+ bit = (chan < 4) ? DOUTEN1 : DOUTEN2;
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= mask;
+ devpriv->cfg3 |= bit;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~mask;
+ devpriv->cfg3 &= ~bit;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ outw(devpriv->cfg3, dev->iobase + ATAO_CFG3);
+
+ return 1;
+}
+
+/*
+ * Figure 2-1 in the manual shows 3 chips labeled DAC8800, which
+ * are 8-channel 8-bit DACs. These are most likely the calibration
+ * DACs. It is not explicitly stated in the manual how to access
+ * the caldacs, but we can guess.
+ */
+static int atao_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ for (i = 0; i < insn->n; i++) {
+ data[i] = 0; /* XXX */
+ }
+ return insn->n;
+}
+
+static int atao_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int bitstring, bit;
+ unsigned int chan = CR_CHAN(insn->chanspec);
+
+ bitstring = ((chan & 0x7) << 8) | (data[insn->n - 1] & 0xff);
+
+ for (bit = 1 << (11 - 1); bit; bit >>= 1) {
+ outw(devpriv->cfg2 | ((bit & bitstring) ? SDATA : 0),
+ dev->iobase + ATAO_CFG2);
+ outw(devpriv->cfg2 | SCLK | ((bit & bitstring) ? SDATA : 0),
+ dev->iobase + ATAO_CFG2);
+ }
+ /* strobe the appropriate caldac */
+ outw(devpriv->cfg2 | (((chan >> 3) + 1) << 14),
+ dev->iobase + ATAO_CFG2);
+ outw(devpriv->cfg2, dev->iobase + ATAO_CFG2);
+
+ return insn->n;
+}
diff --git a/drivers/staging/comedi/drivers/ni_atmio.c b/drivers/staging/comedi/drivers/ni_atmio.c
new file mode 100644
index 00000000000..fcc38535afc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_atmio.c
@@ -0,0 +1,513 @@
+/*
+ comedi/drivers/ni_atmio.c
+ Hardware driver for NI AT-MIO E series cards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: ni_atmio
+Description: National Instruments AT-MIO-E series
+Author: ds
+Devices: [National Instruments] AT-MIO-16E-1 (ni_atmio),
+ AT-MIO-16E-2, AT-MIO-16E-10, AT-MIO-16DE-10, AT-MIO-64E-3,
+ AT-MIO-16XE-50, AT-MIO-16XE-10, AT-AI-16XE-10
+Status: works
+Updated: Thu May 1 20:03:02 CDT 2003
+
+The driver has 2.6 kernel isapnp support, and
+will automatically probe for a supported board if the
+I/O base is left unspecified with comedi_config.
+However, many of
+the isapnp id numbers are unknown. If your board is not
+recognized, please send the output of 'cat /proc/isapnp'
+(you may need to modprobe the isa-pnp module for
+/proc/isapnp to exist) so the
+id numbers for your board can be added to the driver.
+
+Otherwise, you can use the isapnptools package to configure
+your board. Use isapnp to
+configure the I/O base and IRQ for the board, and then pass
+the same values as
+parameters in comedi_config. A sample isapnp.conf file is included
+in the etc/ directory of Comedilib.
+
+Comedilib includes a utility to autocalibrate these boards. The
+boards seem to boot into a state where the all calibration DACs
+are at one extreme of their range, thus the default calibration
+is terrible. Calibration at boot is strongly encouraged.
+
+To use the extended digital I/O on some of the boards, enable the
+8255 driver when configuring the Comedi source tree.
+
+External triggering is supported for some events. The channel index
+(scan_begin_arg, etc.) maps to PFI0 - PFI9.
+
+Some of the more esoteric triggering possibilities of these boards
+are not supported.
+*/
+/*
+ The real guts of the driver is in ni_mio_common.c, which is included
+ both here and in ni_pcimio.c
+
+ Interrupt support added by Truxton Fulton <trux@truxton.com>
+
+ References for specifications:
+
+ 340747b.pdf Register Level Programmer Manual (obsolete)
+ 340747c.pdf Register Level Programmer Manual (new)
+ DAQ-STC reference manual
+
+ Other possibly relevant info:
+
+ 320517c.pdf User manual (obsolete)
+ 320517f.pdf User manual (new)
+ 320889a.pdf delete
+ 320906c.pdf maximum signal ratings
+ 321066a.pdf about 16x
+ 321791a.pdf discontinuation of at-mio-16e-10 rev. c
+ 321808a.pdf about at-mio-16e-10 rev P
+ 321837a.pdf discontinuation of at-mio-16de-10 rev d
+ 321838a.pdf about at-mio-16de-10 rev N
+
+ ISSUES:
+
+ need to deal with external reference for DAC, and other DAC
+ properties in board properties
+
+ deal with at-mio-16de-10 revision D to N changes, etc.
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/isapnp.h>
+
+#include "ni_stc.h"
+#include "8255.h"
+
+#undef DEBUG
+
+#define ATMIO 1
+#undef PCIMIO
+
+/*
+ * AT specific setup
+ */
+
+#define NI_SIZE 0x20
+
+#define MAX_N_CALDACS 32
+
+static const ni_board ni_boards[] = {
+ {device_id:44,
+ isapnp_id:0x0000,/* XXX unknown */
+ name: "at-mio-16e-1",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:8192,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:800,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ has_8255:0,
+ .num_p0_dio_channels = 8,
+ caldac: {mb88341},
+ },
+ {device_id:25,
+ isapnp_id:0x1900,
+ name: "at-mio-16e-2",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:2048,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:2000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ has_8255:0,
+ .num_p0_dio_channels = 8,
+ caldac: {mb88341},
+ },
+ {device_id:36,
+ isapnp_id:0x2400,
+ name: "at-mio-16e-10",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:512,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:10000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:10000,
+ .num_p0_dio_channels = 8,
+ caldac: {ad8804_debug},
+ has_8255:0,
+ },
+ {device_id:37,
+ isapnp_id:0x2500,
+ name: "at-mio-16de-10",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:512,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:10000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:10000,
+ .num_p0_dio_channels = 8,
+ caldac: {ad8804_debug},
+ has_8255:1,
+ },
+ {device_id:38,
+ isapnp_id:0x2600,
+ name: "at-mio-64e-3",
+ n_adchan:64,
+ adbits: 12,
+ ai_fifo_depth:2048,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:2000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ has_8255:0,
+ .num_p0_dio_channels = 8,
+ caldac: {ad8804_debug},
+ },
+ {device_id:39,
+ isapnp_id:0x2700,
+ name: "at-mio-16xe-50",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:512,
+ alwaysdither:1,
+ gainlkup:ai_gain_8,
+ ai_speed:50000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ .ao_range_table = &range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:50000,
+ .num_p0_dio_channels = 8,
+ caldac: {dac8800, dac8043},
+ has_8255:0,
+ },
+ {device_id:50,
+ isapnp_id:0x0000,/* XXX unknown */
+ name: "at-mio-16xe-10",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:512,
+ alwaysdither:1,
+ gainlkup:ai_gain_14,
+ ai_speed:10000,
+ n_aochan:2,
+ aobits: 16,
+ ao_fifo_depth:2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ ao_unipolar:1,
+ ao_speed:1000,
+ .num_p0_dio_channels = 8,
+ caldac: {dac8800, dac8043, ad8522},
+ has_8255:0,
+ },
+ {device_id:51,
+ isapnp_id:0x0000,/* XXX unknown */
+ name: "at-ai-16xe-10",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:512,
+ alwaysdither:1, /* unknown */
+ gainlkup:ai_gain_14,
+ ai_speed:10000,
+ n_aochan:0,
+ aobits: 0,
+ ao_fifo_depth:0,
+ ao_unipolar:0,
+ .num_p0_dio_channels = 8,
+ caldac: {dac8800, dac8043, ad8522},
+ has_8255:0,
+ }
+};
+
+static const int ni_irqpin[] =
+ { -1, -1, -1, 0, 1, 2, -1, 3, -1, -1, 4, 5, 6, -1, -1, 7 };
+
+#define interrupt_pin(a) (ni_irqpin[(a)])
+
+#define IRQ_POLARITY 0
+
+#define NI_E_IRQ_FLAGS 0
+
+typedef struct {
+ struct pnp_dev *isapnp_dev;
+ NI_PRIVATE_COMMON} ni_private;
+#define devpriv ((ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b) (outl((a),(b)+dev->iobase))
+#define ni_readl(a) (inl((a)+dev->iobase))
+#define ni_writew(a,b) (outw((a),(b)+dev->iobase))
+#define ni_readw(a) (inw((a)+dev->iobase))
+#define ni_writeb(a,b) (outb((a),(b)+dev->iobase))
+#define ni_readb(a) (inb((a)+dev->iobase))
+
+/* How we access windowed registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board. The
+ * AT-MIO devices map the low 8 STC registers to iobase+addr*2. */
+
+static void ni_atmio_win_out(struct comedi_device * dev, uint16_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if ((addr) < 8) {
+ ni_writew(data, addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ni_writew(data, Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t ni_atmio_win_in(struct comedi_device * dev, int addr)
+{
+ unsigned long flags;
+ uint16_t ret;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (addr < 8) {
+ ret = ni_readw(addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ret = ni_readw(Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+ return ret;
+}
+
+static struct pnp_device_id device_ids[] = {
+ {.id = "NIC1900",.driver_data = 0},
+ {.id = "NIC2400",.driver_data = 0},
+ {.id = "NIC2500",.driver_data = 0},
+ {.id = "NIC2600",.driver_data = 0},
+ {.id = "NIC2700",.driver_data = 0},
+ {.id = ""}
+};
+
+MODULE_DEVICE_TABLE(pnp, device_ids);
+
+static int ni_atmio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int ni_atmio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_atmio = {
+ driver_name:"ni_atmio",
+ module:THIS_MODULE,
+ attach:ni_atmio_attach,
+ detach:ni_atmio_detach,
+};
+
+COMEDI_INITCLEANUP(driver_atmio);
+
+#include "ni_mio_common.c"
+
+static int ni_getboardtype(struct comedi_device * dev);
+
+/* clean up allocated resources */
+static int ni_atmio_detach(struct comedi_device * dev)
+{
+ mio_common_detach(dev);
+
+ if (dev->iobase)
+ release_region(dev->iobase, NI_SIZE);
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (devpriv->isapnp_dev)
+ pnp_device_detach(devpriv->isapnp_dev);
+
+ return 0;
+}
+
+static int ni_isapnp_find_board(struct pnp_dev **dev)
+{
+ struct pnp_dev *isapnp_dev = NULL;
+ int i;
+
+ for (i = 0; i < n_ni_boards; i++) {
+ isapnp_dev = pnp_find_dev(NULL,
+ ISAPNP_VENDOR('N', 'I', 'C'),
+ ISAPNP_FUNCTION(ni_boards[i].isapnp_id), NULL);
+
+ if (isapnp_dev == NULL || isapnp_dev->card == NULL)
+ continue;
+
+ if (pnp_device_attach(isapnp_dev) < 0) {
+ printk("ni_atmio: %s found but already active, skipping.\n", ni_boards[i].name);
+ continue;
+ }
+ if (pnp_activate_dev(isapnp_dev) < 0) {
+ pnp_device_detach(isapnp_dev);
+ return -EAGAIN;
+ }
+ if (!pnp_port_valid(isapnp_dev, 0)
+ || !pnp_irq_valid(isapnp_dev, 0)) {
+ pnp_device_detach(isapnp_dev);
+ printk("ni_atmio: pnp invalid port or irq, aborting\n");
+ return -ENOMEM;
+ }
+ break;
+ }
+ if (i == n_ni_boards)
+ return -ENODEV;
+ *dev = isapnp_dev;
+ return 0;
+}
+
+static int ni_atmio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pnp_dev *isapnp_dev;
+ int ret;
+ unsigned long iobase;
+ int board;
+ unsigned int irq;
+
+ /* allocate private area */
+ if ((ret = ni_alloc_private(dev)) < 0)
+ return ret;
+ devpriv->stc_writew = &ni_atmio_win_out;
+ devpriv->stc_readw = &ni_atmio_win_in;
+ devpriv->stc_writel = &win_out2;
+ devpriv->stc_readl = &win_in2;
+
+ iobase = it->options[0];
+ irq = it->options[1];
+ isapnp_dev = NULL;
+ if (iobase == 0) {
+ ret = ni_isapnp_find_board(&isapnp_dev);
+ if (ret < 0)
+ return ret;
+
+ iobase = pnp_port_start(isapnp_dev, 0);
+ irq = pnp_irq(isapnp_dev, 0);
+ devpriv->isapnp_dev = isapnp_dev;
+ }
+
+ /* reserve our I/O region */
+
+ printk("comedi%d: ni_atmio: 0x%04lx", dev->minor, iobase);
+ if (!request_region(iobase, NI_SIZE, "ni_atmio")) {
+ printk(" I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+#ifdef DEBUG
+ /* board existence sanity check */
+ {
+ int i;
+
+ printk(" board fingerprint:");
+ for (i = 0; i < 16; i += 2) {
+ printk(" %04x %02x", inw(dev->iobase + i),
+ inb(dev->iobase + i + 1));
+ }
+ }
+#endif
+
+ /* get board type */
+
+ board = ni_getboardtype(dev);
+ if (board < 0)
+ return -EIO;
+
+ dev->board_ptr = ni_boards + board;
+
+ printk(" %s", boardtype.name);
+ dev->board_name = boardtype.name;
+
+ /* irq stuff */
+
+ if (irq != 0) {
+ if (irq > 15 || ni_irqpin[irq] == -1) {
+ printk(" invalid irq %u\n", irq);
+ return -EINVAL;
+ }
+ printk(" ( irq = %u )", irq);
+ if ((ret = comedi_request_irq(irq, ni_E_interrupt,
+ NI_E_IRQ_FLAGS, "ni_atmio", dev)) < 0) {
+ printk(" irq not available\n");
+ return -EINVAL;
+ }
+ dev->irq = irq;
+ }
+
+ /* generic E series stuff in ni_mio_common.c */
+
+ if ((ret = ni_E_init(dev, it)) < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int ni_getboardtype(struct comedi_device * dev)
+{
+ int device_id = ni_read_eeprom(dev, 511);
+ int i;
+
+ for (i = 0; i < n_ni_boards; i++) {
+ if (ni_boards[i].device_id == device_id) {
+ return i;
+ }
+ }
+ if (device_id == 255) {
+ printk(" can't find board\n");
+ } else if (device_id == 0) {
+ printk(" EEPROM read error (?) or device not found\n");
+ } else {
+ printk(" unknown device ID %d -- contact author\n", device_id);
+ }
+ return -1;
+}
diff --git a/drivers/staging/comedi/drivers/ni_atmio16d.c b/drivers/staging/comedi/drivers/ni_atmio16d.c
new file mode 100644
index 00000000000..35fcd172af2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_atmio16d.c
@@ -0,0 +1,860 @@
+/*
+ comedi/drivers/ni_atmio16d.c
+ Hardware driver for National Instruments AT-MIO16D board
+ Copyright (C) 2000 Chris R. Baugher <baugher@enteract.com>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: ni_atmio16d
+Description: National Instruments AT-MIO-16D
+Author: Chris R. Baugher <baugher@enteract.com>
+Status: unknown
+Devices: [National Instruments] AT-MIO-16 (atmio16), AT-MIO-16D (atmio16d)
+*/
+/*
+ * I must give credit here to Michal Dobes <dobes@tesnet.cz> who
+ * wrote the driver for Advantec's pcl812 boards. I used the interrupt
+ * handling code from his driver as an example for this one.
+ *
+ * Chris Baugher
+ * 5/1/2000
+ *
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include "8255.h"
+
+/* Configuration and Status Registers */
+#define COM_REG_1 0x00 /* wo 16 */
+#define STAT_REG 0x00 /* ro 16 */
+#define COM_REG_2 0x02 /* wo 16 */
+/* Event Strobe Registers */
+#define START_CONVERT_REG 0x08 /* wo 16 */
+#define START_DAQ_REG 0x0A /* wo 16 */
+#define AD_CLEAR_REG 0x0C /* wo 16 */
+#define EXT_STROBE_REG 0x0E /* wo 16 */
+/* Analog Output Registers */
+#define DAC0_REG 0x10 /* wo 16 */
+#define DAC1_REG 0x12 /* wo 16 */
+#define INT2CLR_REG 0x14 /* wo 16 */
+/* Analog Input Registers */
+#define MUX_CNTR_REG 0x04 /* wo 16 */
+#define MUX_GAIN_REG 0x06 /* wo 16 */
+#define AD_FIFO_REG 0x16 /* ro 16 */
+#define DMA_TC_INT_CLR_REG 0x16 /* wo 16 */
+/* AM9513A Counter/Timer Registers */
+#define AM9513A_DATA_REG 0x18 /* rw 16 */
+#define AM9513A_COM_REG 0x1A /* wo 16 */
+#define AM9513A_STAT_REG 0x1A /* ro 16 */
+/* MIO-16 Digital I/O Registers */
+#define MIO_16_DIG_IN_REG 0x1C /* ro 16 */
+#define MIO_16_DIG_OUT_REG 0x1C /* wo 16 */
+/* RTSI Switch Registers */
+#define RTSI_SW_SHIFT_REG 0x1E /* wo 8 */
+#define RTSI_SW_STROBE_REG 0x1F /* wo 8 */
+/* DIO-24 Registers */
+#define DIO_24_PORTA_REG 0x00 /* rw 8 */
+#define DIO_24_PORTB_REG 0x01 /* rw 8 */
+#define DIO_24_PORTC_REG 0x02 /* rw 8 */
+#define DIO_24_CNFG_REG 0x03 /* wo 8 */
+
+/* Command Register bits */
+#define COMREG1_2SCADC 0x0001
+#define COMREG1_1632CNT 0x0002
+#define COMREG1_SCANEN 0x0008
+#define COMREG1_DAQEN 0x0010
+#define COMREG1_DMAEN 0x0020
+#define COMREG1_CONVINTEN 0x0080
+#define COMREG2_SCN2 0x0010
+#define COMREG2_INTEN 0x0080
+#define COMREG2_DOUTEN0 0x0100
+#define COMREG2_DOUTEN1 0x0200
+/* Status Register bits */
+#define STAT_AD_OVERRUN 0x0100
+#define STAT_AD_OVERFLOW 0x0200
+#define STAT_AD_DAQPROG 0x0800
+#define STAT_AD_CONVAVAIL 0x2000
+#define STAT_AD_DAQSTOPINT 0x4000
+/* AM9513A Counter/Timer defines */
+#define CLOCK_1_MHZ 0x8B25
+#define CLOCK_100_KHZ 0x8C25
+#define CLOCK_10_KHZ 0x8D25
+#define CLOCK_1_KHZ 0x8E25
+#define CLOCK_100_HZ 0x8F25
+/* Other miscellaneous defines */
+#define ATMIO16D_SIZE 32 /* bus address range */
+#define devpriv ((struct atmio16d_private *)dev->private)
+#define ATMIO16D_TIMEOUT 10
+
+struct atmio16_board_t {
+
+ const char *name;
+ int has_8255;
+};
+
+static const struct atmio16_board_t atmio16_boards[] = {
+ {
+ name: "atmio16",
+ has_8255:0,
+ },
+ {
+ name: "atmio16d",
+ has_8255:1,
+ },
+};
+
+#define n_atmio16_boards sizeof(atmio16_boards)/sizeof(atmio16_boards[0])
+
+#define boardtype ((const struct atmio16_board_t *)dev->board_ptr)
+
+/* function prototypes */
+static int atmio16d_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int atmio16d_detach(struct comedi_device * dev);
+static irqreturn_t atmio16d_interrupt(int irq, void *d PT_REGS_ARG);
+static int atmio16d_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int atmio16d_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int atmio16d_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void reset_counters(struct comedi_device * dev);
+static void reset_atmio16d(struct comedi_device * dev);
+
+/* main driver struct */
+static struct comedi_driver driver_atmio16d = {
+ driver_name:"atmio16",
+ module:THIS_MODULE,
+ attach:atmio16d_attach,
+ detach:atmio16d_detach,
+ board_name:&atmio16_boards[0].name,
+ num_names:n_atmio16_boards,
+ offset:sizeof(struct atmio16_board_t),
+};
+
+COMEDI_INITCLEANUP(driver_atmio16d);
+
+/* range structs */
+static const struct comedi_lrange range_atmio16d_ai_10_bipolar = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.02)
+ }
+};
+
+static const struct comedi_lrange range_atmio16d_ai_5_bipolar = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01)
+ }
+};
+
+static const struct comedi_lrange range_atmio16d_ai_unipolar = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.02)
+ }
+};
+
+/* private data struct */
+struct atmio16d_private {
+ enum { adc_diff, adc_singleended } adc_mux;
+ enum { adc_bipolar10, adc_bipolar5, adc_unipolar10 } adc_range;
+ enum { adc_2comp, adc_straight } adc_coding;
+ enum { dac_bipolar, dac_unipolar } dac0_range, dac1_range;
+ enum { dac_internal, dac_external } dac0_reference, dac1_reference;
+ enum { dac_2comp, dac_straight } dac0_coding, dac1_coding;
+ const struct comedi_lrange *ao_range_type_list[2];
+ unsigned int ao_readback[2];
+ unsigned int com_reg_1_state; /* current state of command register 1 */
+ unsigned int com_reg_2_state; /* current state of command register 2 */
+};
+
+static void reset_counters(struct comedi_device * dev)
+{
+ /* Counter 2 */
+ outw(0xFFC2, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF02, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+ /* Counter 3 */
+ outw(0xFFC4, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF03, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+ /* Counter 4 */
+ outw(0xFFC8, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF04, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ /* Counter 5 */
+ outw(0xFFD0, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF05, dev->iobase + AM9513A_COM_REG);
+ outw(0x4, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF50, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF50, dev->iobase + AM9513A_COM_REG);
+
+ outw(0, dev->iobase + AD_CLEAR_REG);
+}
+
+static void reset_atmio16d(struct comedi_device * dev)
+{
+ int i;
+
+ /* now we need to initialize the board */
+ outw(0, dev->iobase + COM_REG_1);
+ outw(0, dev->iobase + COM_REG_2);
+ outw(0, dev->iobase + MUX_GAIN_REG);
+ /* init AM9513A timer */
+ outw(0xFFFF, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFEF, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF17, dev->iobase + AM9513A_COM_REG);
+ outw(0xF000, dev->iobase + AM9513A_DATA_REG);
+ for (i = 1; i <= 5; ++i) {
+ outw(0xFF00 + i, dev->iobase + AM9513A_COM_REG);
+ outw(0x0004, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF08 + i, dev->iobase + AM9513A_COM_REG);
+ outw(0x3, dev->iobase + AM9513A_DATA_REG);
+ }
+ outw(0xFF5F, dev->iobase + AM9513A_COM_REG);
+ /* timer init done */
+ outw(0, dev->iobase + AD_CLEAR_REG);
+ outw(0, dev->iobase + INT2CLR_REG);
+ /* select straight binary mode for Analog Input */
+ devpriv->com_reg_1_state |= 1;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ devpriv->adc_coding = adc_straight;
+ /* zero the analog outputs */
+ outw(2048, dev->iobase + DAC0_REG);
+ outw(2048, dev->iobase + DAC1_REG);
+}
+
+static irqreturn_t atmio16d_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+// printk("atmio16d_interrupt!\n");
+
+ comedi_buf_put(s->async, inw(dev->iobase + AD_FIFO_REG));
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static int atmio16d_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0, tmp;
+#ifdef DEBUG1
+ printk("atmio16d_ai_cmdtest\n");
+#endif
+ /* make sure triggers are valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_TIMER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_TIMER)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_FOLLOW) {
+ /* internal trigger */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ } else {
+#if 0
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+#endif
+ }
+
+ if (cmd->convert_arg < 10000) {
+ cmd->convert_arg = 10000;
+ err++;
+ }
+#if 0
+ if (cmd->convert_arg > SLOWEST_TIMER) {
+ cmd->convert_arg = SLOWEST_TIMER;
+ err++;
+ }
+#endif
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* any count is allowed */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ return 0;
+}
+
+static int atmio16d_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned int timer, base_clock;
+ unsigned int sample_count, tmp, chan, gain;
+ int i;
+#ifdef DEBUG1
+ printk("atmio16d_ai_cmd\n");
+#endif
+ /* This is slowly becoming a working command interface. *
+ * It is still uber-experimental */
+
+ reset_counters(dev);
+ s->async->cur_chan = 0;
+
+ /* check if scanning multiple channels */
+ if (cmd->chanlist_len < 2) {
+ devpriv->com_reg_1_state &= ~COMREG1_SCANEN;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ } else {
+ devpriv->com_reg_1_state |= COMREG1_SCANEN;
+ devpriv->com_reg_2_state |= COMREG2_SCN2;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+ }
+
+ /* Setup the Mux-Gain Counter */
+ for (i = 0; i < cmd->chanlist_len; ++i) {
+ chan = CR_CHAN(cmd->chanlist[i]);
+ gain = CR_RANGE(cmd->chanlist[i]);
+ outw(i, dev->iobase + MUX_CNTR_REG);
+ tmp = chan | (gain << 6);
+ if (i == cmd->scan_end_arg - 1)
+ tmp |= 0x0010; /* set LASTONE bit */
+ outw(tmp, dev->iobase + MUX_GAIN_REG);
+ }
+
+ /* Now program the sample interval timer */
+ /* Figure out which clock to use then get an
+ * appropriate timer value */
+ if (cmd->convert_arg < 65536000) {
+ base_clock = CLOCK_1_MHZ;
+ timer = cmd->convert_arg / 1000;
+ } else if (cmd->convert_arg < 655360000) {
+ base_clock = CLOCK_100_KHZ;
+ timer = cmd->convert_arg / 10000;
+ } else if (cmd->convert_arg <= 0xffffffff /* 6553600000 */ ) {
+ base_clock = CLOCK_10_KHZ;
+ timer = cmd->convert_arg / 100000;
+ } else if (cmd->convert_arg <= 0xffffffff /* 65536000000 */ ) {
+ base_clock = CLOCK_1_KHZ;
+ timer = cmd->convert_arg / 1000000;
+ }
+ outw(0xFF03, dev->iobase + AM9513A_COM_REG);
+ outw(base_clock, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0B, dev->iobase + AM9513A_COM_REG);
+ outw(0x2, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF44, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFF3, dev->iobase + AM9513A_COM_REG);
+ outw(timer, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF24, dev->iobase + AM9513A_COM_REG);
+
+ /* Now figure out how many samples to get */
+ /* and program the sample counter */
+ sample_count = cmd->stop_arg * cmd->scan_end_arg;
+ outw(0xFF04, dev->iobase + AM9513A_COM_REG);
+ outw(0x1025, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0C, dev->iobase + AM9513A_COM_REG);
+ if (sample_count < 65536) {
+ /* use only Counter 4 */
+ outw(sample_count, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFF4, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF28, dev->iobase + AM9513A_COM_REG);
+ devpriv->com_reg_1_state &= ~COMREG1_1632CNT;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ } else {
+ /* Counter 4 and 5 are needed */
+ if ((tmp = sample_count & 0xFFFF)) {
+ outw(tmp - 1, dev->iobase + AM9513A_DATA_REG);
+ } else {
+ outw(0xFFFF, dev->iobase + AM9513A_DATA_REG);
+ }
+ outw(0xFF48, dev->iobase + AM9513A_COM_REG);
+ outw(0, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF28, dev->iobase + AM9513A_COM_REG);
+ outw(0xFF05, dev->iobase + AM9513A_COM_REG);
+ outw(0x25, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0D, dev->iobase + AM9513A_COM_REG);
+ tmp = sample_count & 0xFFFF;
+ if ((tmp == 0) || (tmp == 1)) {
+ outw((sample_count >> 16) & 0xFFFF,
+ dev->iobase + AM9513A_DATA_REG);
+ } else {
+ outw(((sample_count >> 16) & 0xFFFF) + 1,
+ dev->iobase + AM9513A_DATA_REG);
+ }
+ outw(0xFF70, dev->iobase + AM9513A_COM_REG);
+ devpriv->com_reg_1_state |= COMREG1_1632CNT;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ }
+
+ /* Program the scan interval timer ONLY IF SCANNING IS ENABLED */
+ /* Figure out which clock to use then get an
+ * appropriate timer value */
+ if (cmd->chanlist_len > 1) {
+ if (cmd->scan_begin_arg < 65536000) {
+ base_clock = CLOCK_1_MHZ;
+ timer = cmd->scan_begin_arg / 1000;
+ } else if (cmd->scan_begin_arg < 655360000) {
+ base_clock = CLOCK_100_KHZ;
+ timer = cmd->scan_begin_arg / 10000;
+ } else if (cmd->scan_begin_arg < 0xffffffff /* 6553600000 */ ) {
+ base_clock = CLOCK_10_KHZ;
+ timer = cmd->scan_begin_arg / 100000;
+ } else if (cmd->scan_begin_arg < 0xffffffff /* 65536000000 */ ) {
+ base_clock = CLOCK_1_KHZ;
+ timer = cmd->scan_begin_arg / 1000000;
+ }
+ outw(0xFF02, dev->iobase + AM9513A_COM_REG);
+ outw(base_clock, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF0A, dev->iobase + AM9513A_COM_REG);
+ outw(0x2, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF42, dev->iobase + AM9513A_COM_REG);
+ outw(0xFFF2, dev->iobase + AM9513A_COM_REG);
+ outw(timer, dev->iobase + AM9513A_DATA_REG);
+ outw(0xFF22, dev->iobase + AM9513A_COM_REG);
+ }
+
+ /* Clear the A/D FIFO and reset the MUX counter */
+ outw(0, dev->iobase + AD_CLEAR_REG);
+ outw(0, dev->iobase + MUX_CNTR_REG);
+ outw(0, dev->iobase + INT2CLR_REG);
+ /* enable this acquisition operation */
+ devpriv->com_reg_1_state |= COMREG1_DAQEN;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ /* enable interrupts for conversion completion */
+ devpriv->com_reg_1_state |= COMREG1_CONVINTEN;
+ devpriv->com_reg_2_state |= COMREG2_INTEN;
+ outw(devpriv->com_reg_1_state, dev->iobase + COM_REG_1);
+ outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+ /* apply a trigger. this starts the counters! */
+ outw(0, dev->iobase + START_DAQ_REG);
+
+ return 0;
+}
+
+/* This will cancel a running acquisition operation */
+static int atmio16d_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ reset_atmio16d(dev);
+
+ return 0;
+}
+
+/* Mode 0 is used to get a single conversion on demand */
+static int atmio16d_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, t;
+ int chan;
+ int gain;
+ int status;
+
+#ifdef DEBUG1
+ printk("atmio16d_ai_insn_read\n");
+#endif
+ chan = CR_CHAN(insn->chanspec);
+ gain = CR_RANGE(insn->chanspec);
+
+ /* reset the Analog input circuitry */
+ //outw( 0, dev->iobase+AD_CLEAR_REG );
+ /* reset the Analog Input MUX Counter to 0 */
+ //outw( 0, dev->iobase+MUX_CNTR_REG );
+
+ /* set the Input MUX gain */
+ outw(chan | (gain << 6), dev->iobase + MUX_GAIN_REG);
+
+ for (i = 0; i < insn->n; i++) {
+ /* start the conversion */
+ outw(0, dev->iobase + START_CONVERT_REG);
+ /* wait for it to finish */
+ for (t = 0; t < ATMIO16D_TIMEOUT; t++) {
+ /* check conversion status */
+ status = inw(dev->iobase + STAT_REG);
+#ifdef DEBUG1
+ printk("status=%x\n", status);
+#endif
+ if (status & STAT_AD_CONVAVAIL) {
+ /* read the data now */
+ data[i] = inw(dev->iobase + AD_FIFO_REG);
+ /* change to two's complement if need be */
+ if (devpriv->adc_coding == adc_2comp) {
+ data[i] ^= 0x800;
+ }
+ break;
+ }
+ if (status & STAT_AD_OVERFLOW) {
+ printk("atmio16d: a/d FIFO overflow\n");
+ outw(0, dev->iobase + AD_CLEAR_REG);
+
+ return -ETIME;
+ }
+ }
+ /* end waiting, now check if it timed out */
+ if (t == ATMIO16D_TIMEOUT) {
+ rt_printk("atmio16d: timeout\n");
+
+ return -ETIME;
+ }
+ }
+
+ return i;
+}
+
+static int atmio16d_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+#ifdef DEBUG1
+ printk("atmio16d_ao_insn_read\n");
+#endif
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+ }
+
+ return i;
+}
+
+static int atmio16d_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+ int d;
+#ifdef DEBUG1
+ printk("atmio16d_ao_insn_write\n");
+#endif
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ d = data[i];
+ switch (chan) {
+ case 0:
+ if (devpriv->dac0_coding == dac_2comp) {
+ d ^= 0x800;
+ }
+ outw(d, dev->iobase + DAC0_REG);
+ break;
+ case 1:
+ if (devpriv->dac1_coding == dac_2comp) {
+ d ^= 0x800;
+ }
+ outw(d, dev->iobase + DAC1_REG);
+ break;
+ default:
+ return -EINVAL;
+ }
+ devpriv->ao_readback[chan] = data[i];
+ }
+ return i;
+}
+
+static int atmio16d_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] | data[1]);
+ outw(s->state, dev->iobase + MIO_16_DIG_OUT_REG);
+ }
+ data[1] = inw(dev->iobase + MIO_16_DIG_IN_REG);
+
+ return 2;
+}
+
+static int atmio16d_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int mask;
+
+ for (i = 0; i < insn->n; i++) {
+ mask = (CR_CHAN(insn->chanspec) < 4) ? 0x0f : 0xf0;
+ s->io_bits &= ~mask;
+ if (data[i])
+ s->io_bits |= mask;
+ }
+ devpriv->com_reg_2_state &= ~(COMREG2_DOUTEN0 | COMREG2_DOUTEN1);
+ if (s->io_bits & 0x0f)
+ devpriv->com_reg_2_state |= COMREG2_DOUTEN0;
+ if (s->io_bits & 0xf0)
+ devpriv->com_reg_2_state |= COMREG2_DOUTEN1;
+ outw(devpriv->com_reg_2_state, dev->iobase + COM_REG_2);
+
+ return i;
+}
+
+/*
+ options[0] - I/O port
+ options[1] - MIO irq
+ 0 == no irq
+ N == irq N {3,4,5,6,7,9,10,11,12,14,15}
+ options[2] - DIO irq
+ 0 == no irq
+ N == irq N {3,4,5,6,7,9}
+ options[3] - DMA1 channel
+ 0 == no DMA
+ N == DMA N {5,6,7}
+ options[4] - DMA2 channel
+ 0 == no DMA
+ N == DMA N {5,6,7}
+
+ options[5] - a/d mux
+ 0=differential, 1=single
+ options[6] - a/d range
+ 0=bipolar10, 1=bipolar5, 2=unipolar10
+
+ options[7] - dac0 range
+ 0=bipolar, 1=unipolar
+ options[8] - dac0 reference
+ 0=internal, 1=external
+ options[9] - dac0 coding
+ 0=2's comp, 1=straight binary
+
+ options[10] - dac1 range
+ options[11] - dac1 reference
+ options[12] - dac1 coding
+ */
+
+static int atmio16d_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned int irq;
+ unsigned long iobase;
+ int ret;
+
+ struct comedi_subdevice *s;
+
+ /* make sure the address range is free and allocate it */
+ iobase = it->options[0];
+ printk("comedi%d: atmio16d: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, ATMIO16D_SIZE, "ni_atmio16d")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* board name */
+ dev->board_name = boardtype->name;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct atmio16d_private))) < 0)
+ return ret;
+
+ /* reset the atmio16d hardware */
+ reset_atmio16d(dev);
+
+ /* check if our interrupt is available and get it */
+ irq = it->options[1];
+ if (irq) {
+ if ((ret = comedi_request_irq(irq, atmio16d_interrupt,
+ 0, "atmio16d", dev)) < 0) {
+ printk("failed to allocate irq %u\n", irq);
+ return ret;
+ }
+ dev->irq = irq;
+ printk("( irq = %u )\n", irq);
+ } else {
+ printk("( no irq )");
+ }
+
+ /* set device options */
+ devpriv->adc_mux = it->options[5];
+ devpriv->adc_range = it->options[6];
+
+ devpriv->dac0_range = it->options[7];
+ devpriv->dac0_reference = it->options[8];
+ devpriv->dac0_coding = it->options[9];
+ devpriv->dac1_range = it->options[10];
+ devpriv->dac1_reference = it->options[11];
+ devpriv->dac1_coding = it->options[12];
+
+ /* setup sub-devices */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
+ s->n_chan = (devpriv->adc_mux ? 16 : 8);
+ s->len_chanlist = 16;
+ s->insn_read = atmio16d_ai_insn_read;
+ s->do_cmdtest = atmio16d_ai_cmdtest;
+ s->do_cmd = atmio16d_ai_cmd;
+ s->cancel = atmio16d_ai_cancel;
+ s->maxdata = 0xfff; /* 4095 decimal */
+ switch (devpriv->adc_range) {
+ case adc_bipolar10:
+ s->range_table = &range_atmio16d_ai_10_bipolar;
+ break;
+ case adc_bipolar5:
+ s->range_table = &range_atmio16d_ai_5_bipolar;
+ break;
+ case adc_unipolar10:
+ s->range_table = &range_atmio16d_ai_unipolar;
+ break;
+ }
+
+ /* ao subdevice */
+ s++;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = atmio16d_ao_insn_read;
+ s->insn_write = atmio16d_ao_insn_write;
+ s->maxdata = 0xfff; /* 4095 decimal */
+ s->range_table_list = devpriv->ao_range_type_list;
+ switch (devpriv->dac0_range) {
+ case dac_bipolar:
+ devpriv->ao_range_type_list[0] = &range_bipolar10;
+ break;
+ case dac_unipolar:
+ devpriv->ao_range_type_list[0] = &range_unipolar10;
+ break;
+ }
+ switch (devpriv->dac1_range) {
+ case dac_bipolar:
+ devpriv->ao_range_type_list[1] = &range_bipolar10;
+ break;
+ case dac_unipolar:
+ devpriv->ao_range_type_list[1] = &range_unipolar10;
+ break;
+ }
+
+ /* Digital I/O */
+ s++;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->n_chan = 8;
+ s->insn_bits = atmio16d_dio_insn_bits;
+ s->insn_config = atmio16d_dio_insn_config;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ /* 8255 subdevice */
+ s++;
+ if (boardtype->has_8255) {
+ subdev_8255_init(dev, s, NULL, dev->iobase);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+/* don't yet know how to deal with counter/timers */
+#if 0
+ s++;
+ /* do */
+ s->type = COMEDI_SUBD_TIMER;
+ s->n_chan = 0;
+ s->maxdata = 0
+#endif
+ printk("\n");
+
+ return 0;
+}
+
+static int atmio16d_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: atmio16d: remove\n", dev->minor);
+
+ if (dev->subdevices && boardtype->has_8255)
+ subdev_8255_cleanup(dev, dev->subdevices + 3);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ reset_atmio16d(dev);
+
+ if (dev->iobase)
+ release_region(dev->iobase, ATMIO16D_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_daq_700.c b/drivers/staging/comedi/drivers/ni_daq_700.c
new file mode 100644
index 00000000000..61a31ad2d03
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_daq_700.c
@@ -0,0 +1,841 @@
+/*
+ * comedi/drivers/ni_daq_700.c
+ * Driver for DAQCard-700 DIO only
+ * copied from 8255
+ *
+ * COMEDI - Linux Control and Measurement Device Interface
+ * Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+/*
+Driver: ni_daq_700
+Description: National Instruments PCMCIA DAQCard-700 DIO only
+Author: Fred Brooks <nsaspook@nsaspook.com>,
+ based on ni_daq_dio24 by Daniel Vecino Castel <dvecino@able.es>
+Devices: [National Instruments] PCMCIA DAQ-Card-700 (ni_daq_700)
+Status: works
+Updated: Thu, 21 Feb 2008 12:07:20 +0000
+
+The daqcard-700 appears in Comedi as a single digital I/O subdevice with
+16 channels. The channel 0 corresponds to the daqcard-700's output
+port, bit 0; channel 8 corresponds to the input port, bit 0.
+
+Direction configuration: channels 0-7 output, 8-15 input (8225 device
+emu as port A output, port B input, port C N/A).
+
+IRQ is assigned but not used.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+#define DIO700_SIZE 8 // size of io region used by board
+
+static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio700_detach(struct comedi_device * dev);
+
+enum dio700_bustype { pcmcia_bustype };
+
+struct dio700_board {
+ const char *name;
+ int device_id; // device id for pcmcia board
+ enum dio700_bustype bustype; // PCMCIA
+ int have_dio; // have daqcard-700 dio
+ // function pointers so we can use inb/outb or readb/writeb
+ // as appropriate
+ unsigned int (*read_byte) (unsigned int address);
+ void (*write_byte) (unsigned int byte, unsigned int address);
+};
+
+static const struct dio700_board dio700_boards[] = {
+ {
+ name: "daqcard-700",
+ device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+ {
+ name: "ni_daq_700",
+ device_id:0x4743,// 0x10b is manufacturer id, 0x4743 is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct dio700_board *)dev->board_ptr)
+
+struct dio700_private {
+
+ int data; /* number of data points left to be taken */
+};
+
+
+#define devpriv ((struct dio700_private *)dev->private)
+
+static struct comedi_driver driver_dio700 = {
+ driver_name:"ni_daq_700",
+ module:THIS_MODULE,
+ attach:dio700_attach,
+ detach:dio700_detach,
+ num_names:sizeof(dio700_boards) / sizeof(struct dio700_board),
+ board_name:&dio700_boards[0].name,
+ offset:sizeof(struct dio700_board),
+};
+
+/* the real driver routines */
+
+#define _700_SIZE 8
+
+#define _700_DATA 0
+
+#define DIO_W 0x04
+#define DIO_R 0x05
+
+struct subdev_700_struct {
+ unsigned long cb_arg;
+ int (*cb_func) (int, int, int, unsigned long);
+ int have_irq;
+};
+
+#define CALLBACK_ARG (((struct subdev_700_struct *)s->private)->cb_arg)
+#define CALLBACK_FUNC (((struct subdev_700_struct *)s->private)->cb_func)
+#define subdevpriv ((struct subdev_700_struct *)s->private)
+
+static void do_config(struct comedi_device * dev, struct comedi_subdevice * s);
+
+void subdev_700_interrupt(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ short d;
+
+ d = CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG);
+
+ comedi_buf_put(s->async, d);
+ s->async->events |= COMEDI_CB_EOS;
+
+ comedi_event(dev, s);
+}
+
+static int subdev_700_cb(int dir, int port, int data, unsigned long arg)
+{
+ /* port is always A for output and B for input (8255 emu) */
+ unsigned long iobase = arg;
+
+ if (dir) {
+ outb(data, iobase + DIO_W);
+ return 0;
+ } else {
+ return inb(iobase + DIO_R);
+ }
+}
+
+static int subdev_700_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ if (data[0] & 0xff)
+ CALLBACK_FUNC(1, _700_DATA, s->state & 0xff,
+ CALLBACK_ARG);
+ }
+
+ data[1] = s->state & 0xff;
+ data[1] |= CALLBACK_FUNC(0, _700_DATA, 0, CALLBACK_ARG) << 8;
+
+ return 2;
+}
+
+static int subdev_700_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 1;
+}
+
+static void do_config(struct comedi_device * dev, struct comedi_subdevice * s)
+{ /* use powerup defaults */
+ return;
+}
+
+static int subdev_700_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1 */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_FOLLOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2 */
+
+ if (err)
+ return 2;
+
+ /* step 3 */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != 1) {
+ cmd->scan_end_arg = 1;
+ err++;
+ }
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4 */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int subdev_700_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+static int subdev_700_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ /* FIXME */
+
+ return 0;
+}
+
+int subdev_700_init(struct comedi_device * dev, struct comedi_subdevice * s, int (*cb) (int,
+ int, int, unsigned long), unsigned long arg)
+{
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+
+ s->private = kmalloc(sizeof(struct subdev_700_struct), GFP_KERNEL);
+ if (!s->private)
+ return -ENOMEM;
+
+ CALLBACK_ARG = arg;
+ if (cb == NULL) {
+ CALLBACK_FUNC = subdev_700_cb;
+ } else {
+ CALLBACK_FUNC = cb;
+ }
+ s->insn_bits = subdev_700_insn;
+ s->insn_config = subdev_700_insn_config;
+
+ s->state = 0;
+ s->io_bits = 0x00ff;
+ do_config(dev, s);
+
+ return 0;
+}
+
+int subdev_700_init_irq(struct comedi_device * dev, struct comedi_subdevice * s,
+ int (*cb) (int, int, int, unsigned long), unsigned long arg)
+{
+ int ret;
+
+ ret = subdev_700_init(dev, s, cb, arg);
+ if (ret < 0)
+ return ret;
+
+ s->do_cmdtest = subdev_700_cmdtest;
+ s->do_cmd = subdev_700_cmd;
+ s->cancel = subdev_700_cancel;
+
+ subdevpriv->have_irq = 1;
+
+ return 0;
+}
+
+void subdev_700_cleanup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (s->private) {
+ if (subdevpriv->have_irq) {
+ }
+
+ kfree(s->private);
+ }
+}
+
+EXPORT_SYMBOL(subdev_700_init);
+EXPORT_SYMBOL(subdev_700_init_irq);
+EXPORT_SYMBOL(subdev_700_cleanup);
+EXPORT_SYMBOL(subdev_700_interrupt);
+
+static int dio700_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+#ifdef incomplete
+ unsigned int irq = 0;
+#endif
+ struct pcmcia_device *link;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct dio700_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case pcmcia_bustype:
+ link = pcmcia_cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+ iobase = link->io.BasePort1;
+#ifdef incomplete
+ irq = link->irq.AssignedIRQ;
+#endif
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+ printk("comedi%d: ni_daq_700: %s, io 0x%lx", dev->minor,
+ thisboard->name, iobase);
+#ifdef incomplete
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+#endif
+
+ printk("\n");
+
+ if (iobase == 0) {
+ printk("io base address is zero!\n");
+ return -EINVAL;
+ }
+
+ dev->iobase = iobase;
+
+#ifdef incomplete
+ /* grab our IRQ */
+ dev->irq = irq;
+#endif
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ /* DAQCard-700 dio */
+ s = dev->subdevices + 0;
+ subdev_700_init(dev, s, NULL, dev->iobase);
+
+ return 0;
+};
+
+static int dio700_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_daq_700: cs-remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_700_cleanup(dev, dev->subdevices + 0);
+
+ if (thisboard->bustype != pcmcia_bustype && dev->iobase)
+ release_region(dev->iobase, DIO700_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+};
+
+// PCMCIA crap
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "ni_daq_700.c, based on dummy_cs.c";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void dio700_config(struct pcmcia_device *link);
+static void dio700_release(struct pcmcia_device *link);
+static int dio700_cs_suspend(struct pcmcia_device *p_dev);
+static int dio700_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int dio700_cs_attach(struct pcmcia_device *);
+static void dio700_cs_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "ni_daq_700";
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+};
+
+/*======================================================================
+
+ dio700_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int dio700_cs_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+
+ printk(KERN_INFO "ni_daq_700: cs-attach\n");
+
+ DEBUG(0, "dio700_cs_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ pcmcia_cur_dev = link;
+
+ dio700_config(link);
+
+ return 0;
+} /* dio700_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void dio700_cs_detach(struct pcmcia_device *link)
+{
+
+ printk(KERN_INFO "ni_daq_700: cs-detach!\n");
+
+ DEBUG(0, "dio700_cs_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((struct local_info_t *) link->priv)->stop = 1;
+ dio700_release(link);
+ }
+
+ /* This points to the parent struct local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* dio700_cs_detach */
+
+/*======================================================================
+
+ dio700_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void dio700_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+ win_req_t req;
+ memreq_t map;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ printk(KERN_INFO "ni_daq_700: cs-config\n");
+
+ DEBUG(0, "dio700_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple) != 0)
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse) != 0)
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io) != 0)
+ goto next_entry;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+ req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req.Attributes |= WIN_ENABLE;
+ req.Base = mem->win[0].host_addr;
+ req.Size = mem->win[0].len;
+ if (req.Size < 0x1000)
+ req.Size = 0x1000;
+ req.AccessSpeed = 0;
+ if (pcmcia_request_window(&link, &req, &link->win))
+ goto next_entry;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(link->win, &map))
+ goto next_entry;
+ }
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ Allocate an interrupt line. Note that this does not assign a
+ handler to the interrupt, unless the 'Handler' member of the
+ irq structure is initialized.
+ */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "ni_daq_700");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %d", link->irq.AssignedIRQ);
+ if (link->io.NumPorts1)
+ printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+ link->io.BasePort1 + link->io.NumPorts1 - 1);
+ if (link->io.NumPorts2)
+ printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+ link->io.BasePort2 + link->io.NumPorts2 - 1);
+ if (link->win)
+ printk(", mem 0x%06lx-0x%06lx", req.Base,
+ req.Base + req.Size - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ printk(KERN_INFO "ni_daq_700 cs failed");
+ dio700_release(link);
+
+} /* dio700_config */
+
+static void dio700_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "dio700_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* dio700_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int dio700_cs_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+} /* dio700_cs_suspend */
+
+static int dio700_cs_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* dio700_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id dio700_cs_ids[] = {
+ /* N.B. These IDs should match those in dio700_boards */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x4743), /* daqcard-700 */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_LICENSE("GPL");
+MODULE_DEVICE_TABLE(pcmcia, dio700_cs_ids);
+
+struct pcmcia_driver dio700_cs_driver = {
+ .probe = dio700_cs_attach,
+ .remove = dio700_cs_detach,
+ .suspend = dio700_cs_suspend,
+ .resume = dio700_cs_resume,
+ .id_table = dio700_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_dio700_cs(void)
+{
+ printk("ni_daq_700: cs-init \n");
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&dio700_cs_driver);
+ return 0;
+}
+
+static void __exit exit_dio700_cs(void)
+{
+ DEBUG(0, "ni_daq_700: unloading\n");
+ pcmcia_unregister_driver(&dio700_cs_driver);
+}
+int __init init_module(void)
+{
+ int ret;
+
+ ret = init_dio700_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_dio700);
+}
+
+void __exit cleanup_module(void)
+{
+ exit_dio700_cs();
+ comedi_driver_unregister(&driver_dio700);
+}
diff --git a/drivers/staging/comedi/drivers/ni_daq_dio24.c b/drivers/staging/comedi/drivers/ni_daq_dio24.c
new file mode 100644
index 00000000000..daec5c4b4c9
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_daq_dio24.c
@@ -0,0 +1,598 @@
+/*
+ comedi/drivers/ni_daq_dio24.c
+ Driver for National Instruments PCMCIA DAQ-Card DIO-24
+ Copyright (C) 2002 Daniel Vecino Castel <dvecino@able.es>
+
+ PCMCIA crap at end of file is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
+ from the pcmcia package.
+ The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: ni_daq_dio24
+Description: National Instruments PCMCIA DAQ-Card DIO-24
+Author: Daniel Vecino Castel <dvecino@able.es>
+Devices: [National Instruments] PCMCIA DAQ-Card DIO-24 (ni_daq_dio24)
+Status: ?
+Updated: Thu, 07 Nov 2002 21:53:06 -0800
+
+This is just a wrapper around the 8255.o driver to properly handle
+the PCMCIA interface.
+*/
+
+//#define LABPC_DEBUG // enable debugging messages
+#undef LABPC_DEBUG
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#include "8255.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+#define DIO24_SIZE 4 // size of io region used by board
+
+static int dio24_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dio24_detach(struct comedi_device * dev);
+
+enum dio24_bustype { pcmcia_bustype };
+
+typedef struct dio24_board_struct {
+ const char *name;
+ int device_id; // device id for pcmcia board
+ enum dio24_bustype bustype; // PCMCIA
+ int have_dio; // have 8255 chip
+ // function pointers so we can use inb/outb or readb/writeb as appropriate
+ unsigned int (*read_byte) (unsigned int address);
+ void (*write_byte) (unsigned int byte, unsigned int address);
+} dio24_board;
+
+static const dio24_board dio24_boards[] = {
+ {
+ name: "daqcard-dio24",
+ device_id:0x475c,// 0x10b is manufacturer id, 0x475c is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+ {
+ name: "ni_daq_dio24",
+ device_id:0x475c,// 0x10b is manufacturer id, 0x475c is device id
+ bustype: pcmcia_bustype,
+ have_dio:1,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const dio24_board *)dev->board_ptr)
+
+struct dio24_private {
+
+ int data; /* number of data points left to be taken */
+};
+
+
+#define devpriv ((struct dio24_private *)dev->private)
+
+static struct comedi_driver driver_dio24 = {
+ driver_name:"ni_daq_dio24",
+ module:THIS_MODULE,
+ attach:dio24_attach,
+ detach:dio24_detach,
+ num_names:sizeof(dio24_boards) / sizeof(dio24_board),
+ board_name:&dio24_boards[0].name,
+ offset:sizeof(dio24_board),
+};
+
+static int dio24_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase = 0;
+#ifdef incomplete
+ unsigned int irq = 0;
+#endif
+ struct pcmcia_device *link;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(struct dio24_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case pcmcia_bustype:
+ link = pcmcia_cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+ iobase = link->io.BasePort1;
+#ifdef incomplete
+ irq = link->irq.AssignedIRQ;
+#endif
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+ printk("comedi%d: ni_daq_dio24: %s, io 0x%lx", dev->minor,
+ thisboard->name, iobase);
+#ifdef incomplete
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+#endif
+
+ printk("\n");
+
+ if (iobase == 0) {
+ printk("io base address is zero!\n");
+ return -EINVAL;
+ }
+
+ dev->iobase = iobase;
+
+#ifdef incomplete
+ /* grab our IRQ */
+ dev->irq = irq;
+#endif
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ /* 8255 dio */
+ s = dev->subdevices + 0;
+ subdev_8255_init(dev, s, NULL, dev->iobase);
+
+ return 0;
+};
+
+static int dio24_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_daq_dio24: remove\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 0);
+
+ if (thisboard->bustype != pcmcia_bustype && dev->iobase)
+ release_region(dev->iobase, DIO24_SIZE);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+};
+
+// PCMCIA crap
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "ni_daq_dio24.c, based on dummy_cs.c";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+static void dio24_config(struct pcmcia_device *link);
+static void dio24_release(struct pcmcia_device *link);
+static int dio24_cs_suspend(struct pcmcia_device *p_dev);
+static int dio24_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int dio24_cs_attach(struct pcmcia_device *);
+static void dio24_cs_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "ni_daq_dio24";
+
+typedef struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+} local_info_t;
+
+/*======================================================================
+
+ dio24_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int dio24_cs_attach(struct pcmcia_device *link)
+{
+ local_info_t *local;
+
+ printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - CS-attach!\n");
+
+ DEBUG(0, "dio24_cs_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ pcmcia_cur_dev = link;
+
+ dio24_config(link);
+
+ return 0;
+} /* dio24_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void dio24_cs_detach(struct pcmcia_device *link)
+{
+
+ printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO - cs-detach!\n");
+
+ DEBUG(0, "dio24_cs_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ ((local_info_t *) link->priv)->stop = 1;
+ dio24_release(link);
+ }
+
+ /* This points to the parent local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* dio24_cs_detach */
+
+/*======================================================================
+
+ dio24_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void dio24_config(struct pcmcia_device *link)
+{
+ local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+ win_req_t req;
+ memreq_t map;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ printk(KERN_INFO "ni_daq_dio24: HOLA SOY YO! - config\n");
+
+ DEBUG(0, "dio24_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple)) != 0) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse)) != 0) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple) != 0)
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse) != 0)
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io) != 0)
+ goto next_entry;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+ req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req.Attributes |= WIN_ENABLE;
+ req.Base = mem->win[0].host_addr;
+ req.Size = mem->win[0].len;
+ if (req.Size < 0x1000)
+ req.Size = 0x1000;
+ req.AccessSpeed = 0;
+ if (pcmcia_request_window(&link, &req, &link->win))
+ goto next_entry;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(link->win, &map))
+ goto next_entry;
+ }
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple)) != 0) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ Allocate an interrupt line. Note that this does not assign a
+ handler to the interrupt, unless the 'Handler' member of the
+ irq structure is initialized.
+ */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ if ((last_ret = pcmcia_request_irq(link, &link->irq)) != 0) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf)) != 0) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "ni_daq_dio24");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %d", link->irq.AssignedIRQ);
+ if (link->io.NumPorts1)
+ printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+ link->io.BasePort1 + link->io.NumPorts1 - 1);
+ if (link->io.NumPorts2)
+ printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+ link->io.BasePort2 + link->io.NumPorts2 - 1);
+ if (link->win)
+ printk(", mem 0x%06lx-0x%06lx", req.Base,
+ req.Base + req.Size - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ printk(KERN_INFO "Fallo");
+ dio24_release(link);
+
+} /* dio24_config */
+
+static void dio24_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "dio24_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* dio24_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int dio24_cs_suspend(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+} /* dio24_cs_suspend */
+
+static int dio24_cs_resume(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* dio24_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id dio24_cs_ids[] = {
+ /* N.B. These IDs should match those in dio24_boards */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x475c), /* daqcard-dio24 */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, dio24_cs_ids);
+
+struct pcmcia_driver dio24_cs_driver = {
+ .probe = dio24_cs_attach,
+ .remove = dio24_cs_detach,
+ .suspend = dio24_cs_suspend,
+ .resume = dio24_cs_resume,
+ .id_table = dio24_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_dio24_cs(void)
+{
+ printk("ni_daq_dio24: HOLA SOY YO!\n");
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&dio24_cs_driver);
+ return 0;
+}
+
+static void __exit exit_dio24_cs(void)
+{
+ DEBUG(0, "ni_dio24: unloading\n");
+ pcmcia_unregister_driver(&dio24_cs_driver);
+}
+
+int __init init_module(void)
+{
+ int ret;
+
+ ret = init_dio24_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_dio24);
+}
+
+void __exit cleanup_module(void)
+{
+ exit_dio24_cs();
+ comedi_driver_unregister(&driver_dio24);
+}
diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c
new file mode 100644
index 00000000000..37898d8474c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc.c
@@ -0,0 +1,2005 @@
+/*
+ comedi/drivers/ni_labpc.c
+ Driver for National Instruments Lab-PC series boards and compatibles
+ Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: ni_labpc
+Description: National Instruments Lab-PC (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [National Instruments] Lab-PC-1200 (labpc-1200),
+ Lab-PC-1200AI (labpc-1200ai), Lab-PC+ (lab-pc+), PCI-1200 (ni_labpc)
+Status: works
+
+Tested with lab-pc-1200. For the older Lab-PC+, not all input ranges
+and analog references will work, the available ranges/arefs will
+depend on how you have configured the jumpers on your board
+(see your owner's manual).
+
+Kernel-level ISA plug-and-play support for the lab-pc-1200
+boards has not
+yet been added to the driver, mainly due to the fact that
+I don't know the device id numbers. If you have one
+of these boards,
+please file a bug report at https://bugs.comedi.org/
+so I can get the necessary information from you.
+
+The 1200 series boards have onboard calibration dacs for correcting
+analog input/output offsets and gains. The proper settings for these
+caldacs are stored on the board's eeprom. To read the caldac values
+from the eeprom and store them into a file that can be then be used by
+comedilib, use the comedi_calibrate program.
+
+Configuration options - ISA boards:
+ [0] - I/O port base address
+ [1] - IRQ (optional, required for timed or externally triggered conversions)
+ [2] - DMA channel (optional)
+
+Configuration options - PCI boards:
+ [0] - bus (optional)
+ [1] - slot (optional)
+
+The Lab-pc+ has quirky chanlist requirements
+when scanning multiple channels. Multiple channel scan
+sequence must start at highest channel, then decrement down to
+channel 0. The rest of the cards can scan down like lab-pc+ or scan
+up from channel zero. Chanlists consisting of all one channel
+are also legal, and allow you to pace conversions in bursts.
+
+*/
+
+/*
+
+NI manuals:
+341309a (labpc-1200 register manual)
+340914a (pci-1200)
+320502b (lab-pc+)
+
+*/
+
+#undef LABPC_DEBUG
+//#define LABPC_DEBUG // enable debugging messages
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "mite.h"
+#include "comedi_fc.h"
+#include "ni_labpc.h"
+
+#define DRV_NAME "ni_labpc"
+
+#define LABPC_SIZE 32 // size of io region used by board
+#define LABPC_TIMER_BASE 500 // 2 MHz master clock
+
+/* Registers for the lab-pc+ */
+
+//write-only registers
+#define COMMAND1_REG 0x0
+#define ADC_GAIN_MASK (0x7 << 4)
+#define ADC_CHAN_BITS(x) ((x) & 0x7)
+#define ADC_SCAN_EN_BIT 0x80 // enables multi channel scans
+#define COMMAND2_REG 0x1
+#define PRETRIG_BIT 0x1 // enable pretriggering (used in conjunction with SWTRIG)
+#define HWTRIG_BIT 0x2 // enable paced conversions on external trigger
+#define SWTRIG_BIT 0x4 // enable paced conversions
+#define CASCADE_BIT 0x8 // use two cascaded counters for pacing
+#define DAC_PACED_BIT(channel) (0x40 << ((channel) & 0x1))
+#define COMMAND3_REG 0x2
+#define DMA_EN_BIT 0x1 // enable dma transfers
+#define DIO_INTR_EN_BIT 0x2 // enable interrupts for 8255
+#define DMATC_INTR_EN_BIT 0x4 // enable dma terminal count interrupt
+#define TIMER_INTR_EN_BIT 0x8 // enable timer interrupt
+#define ERR_INTR_EN_BIT 0x10 // enable error interrupt
+#define ADC_FNE_INTR_EN_BIT 0x20 // enable fifo not empty interrupt
+#define ADC_CONVERT_REG 0x3
+#define DAC_LSB_REG(channel) (0x4 + 2 * ((channel) & 0x1))
+#define DAC_MSB_REG(channel) (0x5 + 2 * ((channel) & 0x1))
+#define ADC_CLEAR_REG 0x8
+#define DMATC_CLEAR_REG 0xa
+#define TIMER_CLEAR_REG 0xc
+#define COMMAND6_REG 0xe // 1200 boards only
+#define ADC_COMMON_BIT 0x1 // select ground or common-mode reference
+#define ADC_UNIP_BIT 0x2 // adc unipolar
+#define DAC_UNIP_BIT(channel) (0x4 << ((channel) & 0x1)) // dac unipolar
+#define ADC_FHF_INTR_EN_BIT 0x20 // enable fifo half full interrupt
+#define A1_INTR_EN_BIT 0x40 // enable interrupt on end of hardware count
+#define ADC_SCAN_UP_BIT 0x80 // scan up from channel zero instead of down to zero
+#define COMMAND4_REG 0xf
+#define INTERVAL_SCAN_EN_BIT 0x1 // enables 'interval' scanning
+#define EXT_SCAN_EN_BIT 0x2 // enables external signal on counter b1 output to trigger scan
+#define EXT_CONVERT_OUT_BIT 0x4 // chooses direction (output or input) for EXTCONV* line
+#define ADC_DIFF_BIT 0x8 // chooses differential inputs for adc (in conjunction with board jumper)
+#define EXT_CONVERT_DISABLE_BIT 0x10
+#define COMMAND5_REG 0x1c // 1200 boards only, calibration stuff
+#define EEPROM_WRITE_UNPROTECT_BIT 0x4 // enable eeprom for write
+#define DITHER_EN_BIT 0x8 // enable dithering
+#define CALDAC_LOAD_BIT 0x10 // load calibration dac
+#define SCLOCK_BIT 0x20 // serial clock - rising edge writes, falling edge reads
+#define SDATA_BIT 0x40 // serial data bit for writing to eeprom or calibration dacs
+#define EEPROM_EN_BIT 0x80 // enable eeprom for read/write
+#define INTERVAL_COUNT_REG 0x1e
+#define INTERVAL_LOAD_REG 0x1f
+#define INTERVAL_LOAD_BITS 0x1
+
+// read-only registers
+#define STATUS1_REG 0x0
+#define DATA_AVAIL_BIT 0x1 // data is available in fifo
+#define OVERRUN_BIT 0x2 // overrun has occurred
+#define OVERFLOW_BIT 0x4 // fifo overflow
+#define TIMER_BIT 0x8 // timer interrupt has occured
+#define DMATC_BIT 0x10 // dma terminal count has occured
+#define EXT_TRIG_BIT 0x40 // external trigger has occured
+#define STATUS2_REG 0x1d // 1200 boards only
+#define EEPROM_OUT_BIT 0x1 // programmable eeprom serial output
+#define A1_TC_BIT 0x2 // counter A1 terminal count
+#define FNHF_BIT 0x4 // fifo not half full
+#define ADC_FIFO_REG 0xa
+
+#define DIO_BASE_REG 0x10
+#define COUNTER_A_BASE_REG 0x14
+#define COUNTER_A_CONTROL_REG (COUNTER_A_BASE_REG + 0x3)
+#define INIT_A0_BITS 0x14 // check modes put conversion pacer output in harmless state (a0 mode 2)
+#define INIT_A1_BITS 0x70 // put hardware conversion counter output in harmless state (a1 mode 0)
+#define COUNTER_B_BASE_REG 0x18
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int labpc_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static irqreturn_t labpc_interrupt(int irq, void *d PT_REGS_ARG);
+static int labpc_drain_fifo(struct comedi_device * dev);
+static void labpc_drain_dma(struct comedi_device * dev);
+static void handle_isa_dma(struct comedi_device * dev);
+static void labpc_drain_dregs(struct comedi_device * dev);
+static int labpc_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int labpc_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int labpc_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int labpc_eeprom_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd);
+static void labpc_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd);
+#ifdef CONFIG_COMEDI_PCI
+static int labpc_find_device(struct comedi_device *dev, int bus, int slot);
+#endif
+static int labpc_dio_mem_callback(int dir, int port, int data,
+ unsigned long arg);
+static void labpc_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int num_bits);
+static unsigned int labpc_serial_in(struct comedi_device * dev);
+static unsigned int labpc_eeprom_read(struct comedi_device * dev,
+ unsigned int address);
+static unsigned int labpc_eeprom_read_status(struct comedi_device * dev);
+static unsigned int labpc_eeprom_write(struct comedi_device * dev,
+ unsigned int address, unsigned int value);
+static void write_caldac(struct comedi_device * dev, unsigned int channel,
+ unsigned int value);
+
+enum scan_mode {
+ MODE_SINGLE_CHAN,
+ MODE_SINGLE_CHAN_INTERVAL,
+ MODE_MULT_CHAN_UP,
+ MODE_MULT_CHAN_DOWN,
+};
+
+//analog input ranges
+#define NUM_LABPC_PLUS_AI_RANGES 16
+// indicates unipolar ranges
+static const int labpc_plus_is_unipolar[NUM_LABPC_PLUS_AI_RANGES] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+// map range index to gain bits
+static const int labpc_plus_ai_gain_bits[NUM_LABPC_PLUS_AI_RANGES] = {
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+ 0x00,
+ 0x10,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+};
+static const struct comedi_lrange range_labpc_plus_ai = {
+ NUM_LABPC_PLUS_AI_RANGES,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(4),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.25),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(10),
+ UNI_RANGE(8),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+#define NUM_LABPC_1200_AI_RANGES 14
+// indicates unipolar ranges
+const int labpc_1200_is_unipolar[NUM_LABPC_1200_AI_RANGES] = {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+ 1,
+};
+
+// map range index to gain bits
+const int labpc_1200_ai_gain_bits[NUM_LABPC_1200_AI_RANGES] = {
+ 0x00,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+ 0x00,
+ 0x20,
+ 0x30,
+ 0x40,
+ 0x50,
+ 0x60,
+ 0x70,
+};
+const struct comedi_lrange range_labpc_1200_ai = {
+ NUM_LABPC_1200_AI_RANGES,
+ {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.25),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.05),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2),
+ UNI_RANGE(1),
+ UNI_RANGE(0.5),
+ UNI_RANGE(0.2),
+ UNI_RANGE(0.1),
+ }
+};
+
+//analog output ranges
+#define AO_RANGE_IS_UNIPOLAR 0x1
+static const struct comedi_lrange range_labpc_ao = {
+ 2,
+ {
+ BIP_RANGE(5),
+ UNI_RANGE(10),
+ }
+};
+
+/* functions that do inb/outb and readb/writeb so we can use
+ * function pointers to decide which to use */
+static inline unsigned int labpc_inb(unsigned long address)
+{
+ return inb(address);
+}
+static inline void labpc_outb(unsigned int byte, unsigned long address)
+{
+ outb(byte, address);
+}
+static inline unsigned int labpc_readb(unsigned long address)
+{
+ return readb((void *)address);
+}
+static inline void labpc_writeb(unsigned int byte, unsigned long address)
+{
+ writeb(byte, (void *)address);
+}
+
+static const labpc_board labpc_boards[] = {
+ {
+ name: "lab-pc-1200",
+ ai_speed:10000,
+ bustype: isa_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:1,
+ memory_mapped_io:0,
+ },
+ {
+ name: "lab-pc-1200ai",
+ ai_speed:10000,
+ bustype: isa_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 0,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:1,
+ memory_mapped_io:0,
+ },
+ {
+ name: "lab-pc+",
+ ai_speed:12000,
+ bustype: isa_bustype,
+ register_layout:labpc_plus_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_plus_ai,
+ ai_range_code:labpc_plus_ai_gain_bits,
+ ai_range_is_unipolar:labpc_plus_is_unipolar,
+ ai_scan_up:0,
+ memory_mapped_io:0,
+ },
+#ifdef CONFIG_COMEDI_PCI
+ {
+ name: "pci-1200",
+ device_id:0x161,
+ ai_speed:10000,
+ bustype: pci_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:1,
+ memory_mapped_io:1,
+ },
+ // dummy entry so pci board works when comedi_config is passed driver name
+ {
+ .name = DRV_NAME,
+ .bustype = pci_bustype,
+ },
+#endif
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((labpc_board *)dev->board_ptr)
+
+static const int dma_buffer_size = 0xff00; // size in bytes of dma buffer
+static const int sample_size = 2; // 2 bytes per sample
+
+#define devpriv ((labpc_private *)dev->private)
+
+static struct comedi_driver driver_labpc = {
+ .driver_name = DRV_NAME,
+ .module = THIS_MODULE,
+ .attach = labpc_attach,
+ .detach = labpc_common_detach,
+ .num_names = sizeof(labpc_boards) / sizeof(labpc_board),
+ .board_name = &labpc_boards[0].name,
+ .offset = sizeof(labpc_board),
+};
+
+#ifdef CONFIG_COMEDI_PCI
+static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x161, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, labpc_pci_table);
+#endif /* CONFIG_COMEDI_PCI */
+
+static inline int labpc_counter_load(struct comedi_device * dev,
+ unsigned long base_address, unsigned int counter_number,
+ unsigned int count, unsigned int mode)
+{
+ if (thisboard->memory_mapped_io)
+ return i8254_mm_load((void *)base_address, 0, counter_number,
+ count, mode);
+ else
+ return i8254_load(base_address, 0, counter_number, count, mode);
+}
+
+int labpc_common_attach(struct comedi_device * dev, unsigned long iobase,
+ unsigned int irq, unsigned int dma_chan)
+{
+ struct comedi_subdevice *s;
+ int i;
+ unsigned long dma_flags, isr_flags;
+ short lsb, msb;
+
+ printk("comedi%d: ni_labpc: %s, io 0x%lx", dev->minor, thisboard->name,
+ iobase);
+ if (irq) {
+ printk(", irq %u", irq);
+ }
+ if (dma_chan) {
+ printk(", dma %u", dma_chan);
+ }
+ printk("\n");
+
+ if (iobase == 0) {
+ printk("io base address is zero!\n");
+ return -EINVAL;
+ }
+ // request io regions for isa boards
+ if (thisboard->bustype == isa_bustype) {
+ /* check if io addresses are available */
+ if (!request_region(iobase, LABPC_SIZE,
+ driver_labpc.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ }
+ dev->iobase = iobase;
+
+ if (thisboard->memory_mapped_io) {
+ devpriv->read_byte = labpc_readb;
+ devpriv->write_byte = labpc_writeb;
+ } else {
+ devpriv->read_byte = labpc_inb;
+ devpriv->write_byte = labpc_outb;
+ }
+ // initialize board's command registers
+ devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+ if (thisboard->register_layout == labpc_1200_layout) {
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+
+ /* grab our IRQ */
+ if (irq) {
+ isr_flags = 0;
+ if (thisboard->bustype == pci_bustype)
+ isr_flags |= IRQF_SHARED;
+ if (comedi_request_irq(irq, labpc_interrupt, isr_flags,
+ driver_labpc.driver_name, dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ }
+ }
+ dev->irq = irq;
+
+ // grab dma channel
+ if (dma_chan > 3) {
+ printk(" invalid dma channel %u\n", dma_chan);
+ return -EINVAL;
+ } else if (dma_chan) {
+ // allocate dma buffer
+ devpriv->dma_buffer =
+ kmalloc(dma_buffer_size, GFP_KERNEL | GFP_DMA);
+ if (devpriv->dma_buffer == NULL) {
+ printk(" failed to allocate dma buffer\n");
+ return -ENOMEM;
+ }
+ if (request_dma(dma_chan, driver_labpc.driver_name)) {
+ printk(" failed to allocate dma channel %u\n",
+ dma_chan);
+ return -EINVAL;
+ }
+ devpriv->dma_chan = dma_chan;
+ dma_flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ set_dma_mode(devpriv->dma_chan, DMA_MODE_READ);
+ release_dma_lock(dma_flags);
+ }
+
+ dev->board_name = thisboard->name;
+
+ if (alloc_subdevices(dev, 5) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_GROUND | SDF_COMMON | SDF_DIFF |
+ SDF_CMD_READ;
+ s->n_chan = 8;
+ s->len_chanlist = 8;
+ s->maxdata = (1 << 12) - 1; // 12 bit resolution
+ s->range_table = thisboard->ai_range_table;
+ s->do_cmd = labpc_ai_cmd;
+ s->do_cmdtest = labpc_ai_cmdtest;
+ s->insn_read = labpc_ai_rinsn;
+ s->cancel = labpc_cancel;
+
+ /* analog output */
+ s = dev->subdevices + 1;
+ if (thisboard->has_ao) {
+/* Could provide command support, except it only has a one sample
+ * hardware buffer for analog output and no underrun flag. */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = NUM_AO_CHAN;
+ s->maxdata = (1 << 12) - 1; // 12 bit resolution
+ s->range_table = &range_labpc_ao;
+ s->insn_read = labpc_ao_rinsn;
+ s->insn_write = labpc_ao_winsn;
+ /* initialize analog outputs to a known value */
+ for (i = 0; i < s->n_chan; i++) {
+ devpriv->ao_value[i] = s->maxdata / 2;
+ lsb = devpriv->ao_value[i] & 0xff;
+ msb = (devpriv->ao_value[i] >> 8) & 0xff;
+ devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(i));
+ devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(i));
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* 8255 dio */
+ s = dev->subdevices + 2;
+ // if board uses io memory we have to give a custom callback function to the 8255 driver
+ if (thisboard->memory_mapped_io)
+ subdev_8255_init(dev, s, labpc_dio_mem_callback,
+ (unsigned long)(dev->iobase + DIO_BASE_REG));
+ else
+ subdev_8255_init(dev, s, NULL, dev->iobase + DIO_BASE_REG);
+
+ // calibration subdevices for boards that have one
+ s = dev->subdevices + 3;
+ if (thisboard->register_layout == labpc_1200_layout) {
+ s->type = COMEDI_SUBD_CALIB;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 16;
+ s->maxdata = 0xff;
+ s->insn_read = labpc_calib_read_insn;
+ s->insn_write = labpc_calib_write_insn;
+
+ for (i = 0; i < s->n_chan; i++)
+ write_caldac(dev, i, s->maxdata / 2);
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* EEPROM */
+ s = dev->subdevices + 4;
+ if (thisboard->register_layout == labpc_1200_layout) {
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = EEPROM_SIZE;
+ s->maxdata = 0xff;
+ s->insn_read = labpc_eeprom_read_insn;
+ s->insn_write = labpc_eeprom_write_insn;
+
+ for (i = 0; i < EEPROM_SIZE; i++) {
+ devpriv->eeprom_data[i] = labpc_eeprom_read(dev, i);
+ }
+#ifdef LABPC_DEBUG
+ printk(" eeprom:");
+ for (i = 0; i < EEPROM_SIZE; i++) {
+ printk(" %i:0x%x ", i, devpriv->eeprom_data[i]);
+ }
+ printk("\n");
+#endif
+ } else
+ s->type = COMEDI_SUBD_UNUSED;
+
+ return 0;
+}
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+ unsigned int dma_chan = 0;
+#ifdef CONFIG_COMEDI_PCI
+ int retval;
+#endif
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(labpc_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case isa_bustype:
+ iobase = it->options[0];
+ irq = it->options[1];
+ dma_chan = it->options[2];
+ break;
+ case pci_bustype:
+#ifdef CONFIG_COMEDI_PCI
+ retval = labpc_find_device(dev, it->options[0], it->options[1]);
+ if (retval < 0) {
+ return retval;
+ }
+ retval = mite_setup(devpriv->mite);
+ if (retval < 0)
+ return retval;
+ iobase = (unsigned long)devpriv->mite->daq_io_addr;
+ irq = mite_irq(devpriv->mite);
+#else
+ printk(" this driver has not been built with PCI support.\n");
+ return -EINVAL;
+#endif
+ break;
+ case pcmcia_bustype:
+ printk(" this driver does not support pcmcia cards, use ni_labpc_cs.o\n");
+ return -EINVAL;
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+
+ return labpc_common_attach(dev, iobase, irq, dma_chan);
+}
+
+// adapted from ni_pcimio for finding mite based boards (pc-1200)
+#ifdef CONFIG_COMEDI_PCI
+static int labpc_find_device(struct comedi_device *dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ // if bus/slot are specified then make sure we have the right bus/slot
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number
+ || slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < driver_labpc.num_names; i++) {
+ if (labpc_boards[i].bustype != pci_bustype)
+ continue;
+ if (mite_device_id(mite) == labpc_boards[i].device_id) {
+ devpriv->mite = mite;
+ // fixup board pointer, in case we were using the dummy "ni_labpc" entry
+ dev->board_ptr = &labpc_boards[i];
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+#endif
+
+int labpc_common_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: ni_labpc: detach\n", dev->minor);
+
+ if (dev->subdevices)
+ subdev_8255_cleanup(dev, dev->subdevices + 2);
+
+ /* only free stuff if it has been allocated by _attach */
+ if (devpriv->dma_buffer)
+ kfree(devpriv->dma_buffer);
+ if (devpriv->dma_chan)
+ free_dma(devpriv->dma_chan);
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (thisboard->bustype == isa_bustype && dev->iobase)
+ release_region(dev->iobase, LABPC_SIZE);
+#ifdef CONFIG_COMEDI_PCI
+ if (devpriv->mite)
+ mite_unsetup(devpriv->mite);
+#endif
+
+ return 0;
+};
+
+static void labpc_clear_adc_fifo(const struct comedi_device * dev)
+{
+ devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+ devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+}
+
+static int labpc_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ devpriv->command3_bits = 0;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ return 0;
+}
+
+static enum scan_mode labpc_ai_scan_mode(const struct comedi_cmd * cmd)
+{
+ if (cmd->chanlist_len == 1)
+ return MODE_SINGLE_CHAN;
+
+ /* chanlist may be NULL during cmdtest. */
+ if (cmd->chanlist == NULL)
+ return MODE_MULT_CHAN_UP;
+
+ if (CR_CHAN(cmd->chanlist[0]) == CR_CHAN(cmd->chanlist[1]))
+ return MODE_SINGLE_CHAN_INTERVAL;
+
+ if (CR_CHAN(cmd->chanlist[0]) < CR_CHAN(cmd->chanlist[1]))
+ return MODE_MULT_CHAN_UP;
+
+ if (CR_CHAN(cmd->chanlist[0]) > CR_CHAN(cmd->chanlist[1]))
+ return MODE_MULT_CHAN_DOWN;
+
+ rt_printk("ni_labpc: bug! this should never happen\n");
+
+ return 0;
+}
+
+static int labpc_ai_chanlist_invalid(const struct comedi_device * dev,
+ const struct comedi_cmd * cmd)
+{
+ int mode, channel, range, aref, i;
+
+ if (cmd->chanlist == NULL)
+ return 0;
+
+ mode = labpc_ai_scan_mode(cmd);
+
+ if (mode == MODE_SINGLE_CHAN)
+ return 0;
+
+ if (mode == MODE_SINGLE_CHAN_INTERVAL) {
+ if (cmd->chanlist_len > 0xff) {
+ comedi_error(dev,
+ "ni_labpc: chanlist too long for single channel interval mode\n");
+ return 1;
+ }
+ }
+
+ channel = CR_CHAN(cmd->chanlist[0]);
+ range = CR_RANGE(cmd->chanlist[0]);
+ aref = CR_AREF(cmd->chanlist[0]);
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+
+ switch (mode) {
+ case MODE_SINGLE_CHAN_INTERVAL:
+ if (CR_CHAN(cmd->chanlist[i]) != channel) {
+ comedi_error(dev,
+ "channel scanning order specified in chanlist is not supported by hardware.\n");
+ return 1;
+ }
+ break;
+ case MODE_MULT_CHAN_UP:
+ if (CR_CHAN(cmd->chanlist[i]) != i) {
+ comedi_error(dev,
+ "channel scanning order specified in chanlist is not supported by hardware.\n");
+ return 1;
+ }
+ break;
+ case MODE_MULT_CHAN_DOWN:
+ if (CR_CHAN(cmd->chanlist[i]) !=
+ cmd->chanlist_len - i - 1) {
+ comedi_error(dev,
+ "channel scanning order specified in chanlist is not supported by hardware.\n");
+ return 1;
+ }
+ break;
+ default:
+ rt_printk("ni_labpc: bug! in chanlist check\n");
+ return 1;
+ break;
+ }
+
+ if (CR_RANGE(cmd->chanlist[i]) != range) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same range\n");
+ return 1;
+ }
+
+ if (CR_AREF(cmd->chanlist[i]) != aref) {
+ comedi_error(dev,
+ "entries in chanlist must all have the same reference\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int labpc_use_continuous_mode(const struct comedi_cmd * cmd)
+{
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN)
+ return 1;
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW)
+ return 1;
+
+ return 0;
+}
+
+static unsigned int labpc_ai_convert_period(const struct comedi_cmd * cmd)
+{
+ if (cmd->convert_src != TRIG_TIMER)
+ return 0;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->scan_begin_src == TRIG_TIMER)
+ return cmd->scan_begin_arg;
+
+ return cmd->convert_arg;
+}
+
+static void labpc_set_ai_convert_period(struct comedi_cmd * cmd, unsigned int ns)
+{
+ if (cmd->convert_src != TRIG_TIMER)
+ return;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->scan_begin_src == TRIG_TIMER) {
+ cmd->scan_begin_arg = ns;
+ if (cmd->convert_arg > cmd->scan_begin_arg)
+ cmd->convert_arg = cmd->scan_begin_arg;
+ } else
+ cmd->convert_arg = ns;
+}
+
+static unsigned int labpc_ai_scan_period(const struct comedi_cmd * cmd)
+{
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return 0;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->convert_src == TRIG_TIMER)
+ return 0;
+
+ return cmd->scan_begin_arg;
+}
+
+static void labpc_set_ai_scan_period(struct comedi_cmd * cmd, unsigned int ns)
+{
+ if (cmd->scan_begin_src != TRIG_TIMER)
+ return;
+
+ if (labpc_ai_scan_mode(cmd) == MODE_SINGLE_CHAN &&
+ cmd->convert_src == TRIG_TIMER)
+ return;
+
+ cmd->scan_begin_arg = ns;
+}
+
+static int labpc_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, tmp2;
+ int stop_mask;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ stop_mask = TRIG_COUNT | TRIG_NONE;
+ if (thisboard->register_layout == labpc_1200_layout)
+ stop_mask |= TRIG_EXT;
+ cmd->stop_src &= stop_mask;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT &&
+ cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ // can't have external stop and start triggers at once
+ if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg == TRIG_NOW && cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (!cmd->chanlist_len) {
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < thisboard->ai_speed) {
+ cmd->convert_arg = thisboard->ai_speed;
+ err++;
+ }
+ }
+ // make sure scan timing is not too fast
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->convert_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->scan_begin_arg <
+ thisboard->ai_speed * cmd->chanlist_len) {
+ cmd->scan_begin_arg =
+ thisboard->ai_speed * cmd->chanlist_len;
+ err++;
+ }
+ }
+ // stop source
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ // TRIG_EXT doesn't care since it doesn't trigger off a numbered channel
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ tmp = cmd->convert_arg;
+ tmp2 = cmd->scan_begin_arg;
+ labpc_adc_timing(dev, cmd);
+ if (tmp != cmd->convert_arg || tmp2 != cmd->scan_begin_arg)
+ err++;
+
+ if (err)
+ return 4;
+
+ if (labpc_ai_chanlist_invalid(dev, cmd))
+ return 5;
+
+ return 0;
+}
+
+static int labpc_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int channel, range, aref;
+ unsigned long irq_flags;
+ int ret;
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ enum transfer_type xfer;
+ unsigned long flags;
+
+ if (!dev->irq) {
+ comedi_error(dev, "no irq assigned, cannot perform command");
+ return -1;
+ }
+
+ range = CR_RANGE(cmd->chanlist[0]);
+ aref = CR_AREF(cmd->chanlist[0]);
+
+ // make sure board is disabled before setting up aquisition
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ devpriv->command3_bits = 0;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ // initialize software conversion count
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->count = cmd->stop_arg * cmd->chanlist_len;
+ }
+ // setup hardware conversion counter
+ if (cmd->stop_src == TRIG_EXT) {
+ // load counter a1 with count of 3 (pc+ manual says this is minimum allowed) using mode 0
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 1, 3, 0);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter a1");
+ return -1;
+ }
+ } else // otherwise, just put a1 in mode 0 with no count to set its output low
+ devpriv->write_byte(INIT_A1_BITS,
+ dev->iobase + COUNTER_A_CONTROL_REG);
+
+ // figure out what method we will use to transfer data
+ if (devpriv->dma_chan && // need a dma channel allocated
+ // dma unsafe at RT priority, and too much setup time for TRIG_WAKE_EOS for
+ (cmd->flags & (TRIG_WAKE_EOS | TRIG_RT)) == 0 &&
+ // only available on the isa boards
+ thisboard->bustype == isa_bustype) {
+ xfer = isa_dma_transfer;
+ } else if (thisboard->register_layout == labpc_1200_layout && // pc-plus has no fifo-half full interrupt
+ // wake-end-of-scan should interrupt on fifo not empty
+ (cmd->flags & TRIG_WAKE_EOS) == 0 &&
+ // make sure we are taking more than just a few points
+ (cmd->stop_src != TRIG_COUNT || devpriv->count > 256)) {
+ xfer = fifo_half_full_transfer;
+ } else
+ xfer = fifo_not_empty_transfer;
+ devpriv->current_transfer = xfer;
+
+ // setup command6 register for 1200 boards
+ if (thisboard->register_layout == labpc_1200_layout) {
+ // reference inputs to ground or common?
+ if (aref != AREF_GROUND)
+ devpriv->command6_bits |= ADC_COMMON_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_COMMON_BIT;
+ // bipolar or unipolar range?
+ if (thisboard->ai_range_is_unipolar[range])
+ devpriv->command6_bits |= ADC_UNIP_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_UNIP_BIT;
+ // interrupt on fifo half full?
+ if (xfer == fifo_half_full_transfer)
+ devpriv->command6_bits |= ADC_FHF_INTR_EN_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
+ // enable interrupt on counter a1 terminal count?
+ if (cmd->stop_src == TRIG_EXT)
+ devpriv->command6_bits |= A1_INTR_EN_BIT;
+ else
+ devpriv->command6_bits &= ~A1_INTR_EN_BIT;
+ // are we scanning up or down through channels?
+ if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+ devpriv->command6_bits |= ADC_SCAN_UP_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_SCAN_UP_BIT;
+ // write to register
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+
+ /* setup channel list, etc (command1 register) */
+ devpriv->command1_bits = 0;
+ if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP)
+ channel = CR_CHAN(cmd->chanlist[cmd->chanlist_len - 1]);
+ else
+ channel = CR_CHAN(cmd->chanlist[0]);
+ // munge channel bits for differential / scan disabled mode
+ if (labpc_ai_scan_mode(cmd) != MODE_SINGLE_CHAN && aref == AREF_DIFF)
+ channel *= 2;
+ devpriv->command1_bits |= ADC_CHAN_BITS(channel);
+ devpriv->command1_bits |= thisboard->ai_range_code[range];
+ devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+ // manual says to set scan enable bit on second pass
+ if (labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_UP ||
+ labpc_ai_scan_mode(cmd) == MODE_MULT_CHAN_DOWN) {
+ devpriv->command1_bits |= ADC_SCAN_EN_BIT;
+ /* need a brief delay before enabling scan, or scan list will get screwed when you switch
+ * between scan up to scan down mode - dunno why */
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command1_bits,
+ dev->iobase + COMMAND1_REG);
+ }
+ // setup any external triggering/pacing (command4 register)
+ devpriv->command4_bits = 0;
+ if (cmd->convert_src != TRIG_EXT)
+ devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+ /* XXX should discard first scan when using interval scanning
+ * since manual says it is not synced with scan clock */
+ if (labpc_use_continuous_mode(cmd) == 0) {
+ devpriv->command4_bits |= INTERVAL_SCAN_EN_BIT;
+ if (cmd->scan_begin_src == TRIG_EXT)
+ devpriv->command4_bits |= EXT_SCAN_EN_BIT;
+ }
+ // single-ended/differential
+ if (aref == AREF_DIFF)
+ devpriv->command4_bits |= ADC_DIFF_BIT;
+ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+
+ devpriv->write_byte(cmd->chanlist_len,
+ dev->iobase + INTERVAL_COUNT_REG);
+ // load count
+ devpriv->write_byte(INTERVAL_LOAD_BITS,
+ dev->iobase + INTERVAL_LOAD_REG);
+
+ if (cmd->convert_src == TRIG_TIMER || cmd->scan_begin_src == TRIG_TIMER) {
+ // set up pacing
+ labpc_adc_timing(dev, cmd);
+ // load counter b0 in mode 3
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ 0, devpriv->divisor_b0, 3);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter b0");
+ return -1;
+ }
+ }
+ // set up conversion pacing
+ if (labpc_ai_convert_period(cmd)) {
+ // load counter a0 in mode 2
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_A_BASE_REG,
+ 0, devpriv->divisor_a0, 2);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter a0");
+ return -1;
+ }
+ } else
+ devpriv->write_byte(INIT_A0_BITS,
+ dev->iobase + COUNTER_A_CONTROL_REG);
+
+ // set up scan pacing
+ if (labpc_ai_scan_period(cmd)) {
+ // load counter b1 in mode 2
+ ret = labpc_counter_load(dev, dev->iobase + COUNTER_B_BASE_REG,
+ 1, devpriv->divisor_b1, 2);
+ if (ret < 0) {
+ comedi_error(dev, "error loading counter b1");
+ return -1;
+ }
+ }
+
+ labpc_clear_adc_fifo(dev);
+
+ // set up dma transfer
+ if (xfer == isa_dma_transfer) {
+ irq_flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma_chan);
+ set_dma_addr(devpriv->dma_chan,
+ virt_to_bus(devpriv->dma_buffer));
+ // set appropriate size of transfer
+ devpriv->dma_transfer_size = labpc_suggest_transfer_size(*cmd);
+ if (cmd->stop_src == TRIG_COUNT &&
+ devpriv->count * sample_size <
+ devpriv->dma_transfer_size) {
+ devpriv->dma_transfer_size =
+ devpriv->count * sample_size;
+ }
+ set_dma_count(devpriv->dma_chan, devpriv->dma_transfer_size);
+ enable_dma(devpriv->dma_chan);
+ release_dma_lock(irq_flags);
+ // enable board's dma
+ devpriv->command3_bits |= DMA_EN_BIT | DMATC_INTR_EN_BIT;
+ } else
+ devpriv->command3_bits &= ~DMA_EN_BIT & ~DMATC_INTR_EN_BIT;
+
+ // enable error interrupts
+ devpriv->command3_bits |= ERR_INTR_EN_BIT;
+ // enable fifo not empty interrupt?
+ if (xfer == fifo_not_empty_transfer)
+ devpriv->command3_bits |= ADC_FNE_INTR_EN_BIT;
+ else
+ devpriv->command3_bits &= ~ADC_FNE_INTR_EN_BIT;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ // startup aquisition
+
+ // command2 reg
+ // use 2 cascaded counters for pacing
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits |= CASCADE_BIT;
+ switch (cmd->start_src) {
+ case TRIG_EXT:
+ devpriv->command2_bits |= HWTRIG_BIT;
+ devpriv->command2_bits &= ~PRETRIG_BIT & ~SWTRIG_BIT;
+ break;
+ case TRIG_NOW:
+ devpriv->command2_bits |= SWTRIG_BIT;
+ devpriv->command2_bits &= ~PRETRIG_BIT & ~HWTRIG_BIT;
+ break;
+ default:
+ comedi_error(dev, "bug with start_src");
+ return -1;
+ break;
+ }
+ switch (cmd->stop_src) {
+ case TRIG_EXT:
+ devpriv->command2_bits |= HWTRIG_BIT | PRETRIG_BIT;
+ break;
+ case TRIG_COUNT:
+ case TRIG_NONE:
+ break;
+ default:
+ comedi_error(dev, "bug with stop_src");
+ return -1;
+ }
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return 0;
+}
+
+/* interrupt service routine */
+static irqreturn_t labpc_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async;
+ struct comedi_cmd *cmd;
+
+ if (dev->attached == 0) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+
+ async = s->async;
+ cmd = &async->cmd;
+ async->events = 0;
+
+ // read board status
+ devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
+ if (thisboard->register_layout == labpc_1200_layout)
+ devpriv->status2_bits =
+ devpriv->read_byte(dev->iobase + STATUS2_REG);
+
+ if ((devpriv->status1_bits & (DMATC_BIT | TIMER_BIT | OVERFLOW_BIT |
+ OVERRUN_BIT | DATA_AVAIL_BIT)) == 0
+ && (devpriv->status2_bits & A1_TC_BIT) == 0
+ && (devpriv->status2_bits & FNHF_BIT)) {
+ return IRQ_NONE;
+ }
+
+ if (devpriv->status1_bits & OVERRUN_BIT) {
+ // clear error interrupt
+ devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ comedi_error(dev, "overrun");
+ return IRQ_HANDLED;
+ }
+
+ if (devpriv->current_transfer == isa_dma_transfer) {
+ // if a dma terminal count of external stop trigger has occurred
+ if (devpriv->status1_bits & DMATC_BIT ||
+ (thisboard->register_layout == labpc_1200_layout
+ && devpriv->status2_bits & A1_TC_BIT)) {
+ handle_isa_dma(dev);
+ }
+ } else
+ labpc_drain_fifo(dev);
+
+ if (devpriv->status1_bits & TIMER_BIT) {
+ comedi_error(dev, "handled timer interrupt?");
+ // clear it
+ devpriv->write_byte(0x1, dev->iobase + TIMER_CLEAR_REG);
+ }
+
+ if (devpriv->status1_bits & OVERFLOW_BIT) {
+ // clear error interrupt
+ devpriv->write_byte(0x1, dev->iobase + ADC_CLEAR_REG);
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ comedi_error(dev, "overflow");
+ return IRQ_HANDLED;
+ }
+ // handle external stop trigger
+ if (cmd->stop_src == TRIG_EXT) {
+ if (devpriv->status2_bits & A1_TC_BIT) {
+ labpc_drain_dregs(dev);
+ labpc_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ /* TRIG_COUNT end of acquisition */
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (devpriv->count == 0) {
+ labpc_cancel(dev, s);
+ async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+// read all available samples from ai fifo
+static int labpc_drain_fifo(struct comedi_device * dev)
+{
+ unsigned int lsb, msb;
+ short data;
+ struct comedi_async *async = dev->read_subdev->async;
+ const int timeout = 10000;
+ unsigned int i;
+
+ devpriv->status1_bits = devpriv->read_byte(dev->iobase + STATUS1_REG);
+
+ for (i = 0; (devpriv->status1_bits & DATA_AVAIL_BIT) && i < timeout;
+ i++) {
+ // quit if we have all the data we want
+ if (async->cmd.stop_src == TRIG_COUNT) {
+ if (devpriv->count == 0)
+ break;
+ devpriv->count--;
+ }
+ lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ data = (msb << 8) | lsb;
+ cfc_write_to_buffer(dev->read_subdev, data);
+ devpriv->status1_bits =
+ devpriv->read_byte(dev->iobase + STATUS1_REG);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "ai timeout, fifo never empties");
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ return -1;
+ }
+
+ return 0;
+}
+
+static void labpc_drain_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->read_subdev;
+ struct comedi_async *async = s->async;
+ int status;
+ unsigned long flags;
+ unsigned int max_points, num_points, residue, leftover;
+ int i;
+
+ status = devpriv->status1_bits;
+
+ flags = claim_dma_lock();
+ disable_dma(devpriv->dma_chan);
+ /* clear flip-flop to make sure 2-byte registers for
+ * count and address get set correctly */
+ clear_dma_ff(devpriv->dma_chan);
+
+ // figure out how many points to read
+ max_points = devpriv->dma_transfer_size / sample_size;
+ /* residue is the number of points left to be done on the dma
+ * transfer. It should always be zero at this point unless
+ * the stop_src is set to external triggering.
+ */
+ residue = get_dma_residue(devpriv->dma_chan) / sample_size;
+ num_points = max_points - residue;
+ if (devpriv->count < num_points && async->cmd.stop_src == TRIG_COUNT)
+ num_points = devpriv->count;
+
+ // figure out how many points will be stored next time
+ leftover = 0;
+ if (async->cmd.stop_src != TRIG_COUNT) {
+ leftover = devpriv->dma_transfer_size / sample_size;
+ } else if (devpriv->count > num_points) {
+ leftover = devpriv->count - num_points;
+ if (leftover > max_points)
+ leftover = max_points;
+ }
+
+ /* write data to comedi buffer */
+ for (i = 0; i < num_points; i++) {
+ cfc_write_to_buffer(s, devpriv->dma_buffer[i]);
+ }
+ if (async->cmd.stop_src == TRIG_COUNT)
+ devpriv->count -= num_points;
+
+ // set address and count for next transfer
+ set_dma_addr(devpriv->dma_chan, virt_to_bus(devpriv->dma_buffer));
+ set_dma_count(devpriv->dma_chan, leftover * sample_size);
+ release_dma_lock(flags);
+
+ async->events |= COMEDI_CB_BLOCK;
+}
+
+static void handle_isa_dma(struct comedi_device * dev)
+{
+ labpc_drain_dma(dev);
+
+ enable_dma(devpriv->dma_chan);
+
+ // clear dma tc interrupt
+ devpriv->write_byte(0x1, dev->iobase + DMATC_CLEAR_REG);
+}
+
+/* makes sure all data aquired by board is transfered to comedi (used
+ * when aquisition is terminated by stop_src == TRIG_EXT). */
+static void labpc_drain_dregs(struct comedi_device * dev)
+{
+ if (devpriv->current_transfer == isa_dma_transfer)
+ labpc_drain_dma(dev);
+
+ labpc_drain_fifo(dev);
+}
+
+static int labpc_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int chan, range;
+ int lsb, msb;
+ int timeout = 1000;
+ unsigned long flags;
+
+ // disable timed conversions
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~SWTRIG_BIT & ~HWTRIG_BIT & ~PRETRIG_BIT;
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // disable interrupt generation and dma
+ devpriv->command3_bits = 0;
+ devpriv->write_byte(devpriv->command3_bits, dev->iobase + COMMAND3_REG);
+
+ /* set gain and channel */
+ devpriv->command1_bits = 0;
+ chan = CR_CHAN(insn->chanspec);
+ range = CR_RANGE(insn->chanspec);
+ devpriv->command1_bits |= thisboard->ai_range_code[range];
+ // munge channel bits for differential/scan disabled mode
+ if (CR_AREF(insn->chanspec) == AREF_DIFF)
+ chan *= 2;
+ devpriv->command1_bits |= ADC_CHAN_BITS(chan);
+ devpriv->write_byte(devpriv->command1_bits, dev->iobase + COMMAND1_REG);
+
+ // setup command6 register for 1200 boards
+ if (thisboard->register_layout == labpc_1200_layout) {
+ // reference inputs to ground or common?
+ if (CR_AREF(insn->chanspec) != AREF_GROUND)
+ devpriv->command6_bits |= ADC_COMMON_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_COMMON_BIT;
+ // bipolar or unipolar range?
+ if (thisboard->ai_range_is_unipolar[range])
+ devpriv->command6_bits |= ADC_UNIP_BIT;
+ else
+ devpriv->command6_bits &= ~ADC_UNIP_BIT;
+ // don't interrupt on fifo half full
+ devpriv->command6_bits &= ~ADC_FHF_INTR_EN_BIT;
+ // don't enable interrupt on counter a1 terminal count?
+ devpriv->command6_bits &= ~A1_INTR_EN_BIT;
+ // write to register
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+ // setup command4 register
+ devpriv->command4_bits = 0;
+ devpriv->command4_bits |= EXT_CONVERT_DISABLE_BIT;
+ // single-ended/differential
+ if (CR_AREF(insn->chanspec) == AREF_DIFF)
+ devpriv->command4_bits |= ADC_DIFF_BIT;
+ devpriv->write_byte(devpriv->command4_bits, dev->iobase + COMMAND4_REG);
+
+ // initialize pacer counter output to make sure it doesn't cause any problems
+ devpriv->write_byte(INIT_A0_BITS, dev->iobase + COUNTER_A_CONTROL_REG);
+
+ labpc_clear_adc_fifo(dev);
+
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ devpriv->write_byte(0x1, dev->iobase + ADC_CONVERT_REG);
+
+ for (i = 0; i < timeout; i++) {
+ if (devpriv->read_byte(dev->iobase +
+ STATUS1_REG) & DATA_AVAIL_BIT)
+ break;
+ comedi_udelay(1);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timeout");
+ return -ETIME;
+ }
+ lsb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ msb = devpriv->read_byte(dev->iobase + ADC_FIFO_REG);
+ data[n] = (msb << 8) | lsb;
+ }
+
+ return n;
+}
+
+// analog output insn
+static int labpc_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel, range;
+ unsigned long flags;
+ int lsb, msb;
+
+ channel = CR_CHAN(insn->chanspec);
+
+ // turn off pacing of analog output channel
+ /* note: hardware bug in daqcard-1200 means pacing cannot
+ * be independently enabled/disabled for its the two channels */
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ devpriv->command2_bits &= ~DAC_PACED_BIT(channel);
+ devpriv->write_byte(devpriv->command2_bits, dev->iobase + COMMAND2_REG);
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ // set range
+ if (thisboard->register_layout == labpc_1200_layout) {
+ range = CR_RANGE(insn->chanspec);
+ if (range & AO_RANGE_IS_UNIPOLAR)
+ devpriv->command6_bits |= DAC_UNIP_BIT(channel);
+ else
+ devpriv->command6_bits &= ~DAC_UNIP_BIT(channel);
+ // write to register
+ devpriv->write_byte(devpriv->command6_bits,
+ dev->iobase + COMMAND6_REG);
+ }
+ // send data
+ lsb = data[0] & 0xff;
+ msb = (data[0] >> 8) & 0xff;
+ devpriv->write_byte(lsb, dev->iobase + DAC_LSB_REG(channel));
+ devpriv->write_byte(msb, dev->iobase + DAC_MSB_REG(channel));
+
+ // remember value for readback
+ devpriv->ao_value[channel] = data[0];
+
+ return 1;
+}
+
+// analog output readback insn
+static int labpc_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao_value[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int labpc_calib_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->caldac[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int labpc_calib_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+
+ write_caldac(dev, channel, data[0]);
+ return 1;
+}
+
+static int labpc_eeprom_read_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->eeprom_data[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int labpc_eeprom_write_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel = CR_CHAN(insn->chanspec);
+ int ret;
+
+ // only allow writes to user area of eeprom
+ if (channel < 16 || channel > 127) {
+ printk("eeprom writes are only allowed to channels 16 through 127 (the pointer and user areas)");
+ return -EINVAL;
+ }
+
+ ret = labpc_eeprom_write(dev, channel, data[0]);
+ if (ret < 0)
+ return ret;
+
+ return 1;
+}
+
+// utility function that suggests a dma transfer size in bytes
+static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd)
+{
+ unsigned int size;
+ unsigned int freq;
+
+ if (cmd.convert_src == TRIG_TIMER)
+ freq = 1000000000 / cmd.convert_arg;
+ // return some default value
+ else
+ freq = 0xffffffff;
+
+ // make buffer fill in no more than 1/3 second
+ size = (freq / 3) * sample_size;
+
+ // set a minimum and maximum size allowed
+ if (size > dma_buffer_size)
+ size = dma_buffer_size - dma_buffer_size % sample_size;
+ else if (size < sample_size)
+ size = sample_size;
+
+ return size;
+}
+
+// figures out what counter values to use based on command
+static void labpc_adc_timing(struct comedi_device * dev, struct comedi_cmd * cmd)
+{
+ const int max_counter_value = 0x10000; // max value for 16 bit counter in mode 2
+ const int min_counter_value = 2; // min value for 16 bit counter in mode 2
+ unsigned int base_period;
+
+ // if both convert and scan triggers are TRIG_TIMER, then they both rely on counter b0
+ if (labpc_ai_convert_period(cmd) && labpc_ai_scan_period(cmd)) {
+ // pick the lowest b0 divisor value we can (for maximum input clock speed on convert and scan counters)
+ devpriv->divisor_b0 = (labpc_ai_scan_period(cmd) - 1) /
+ (LABPC_TIMER_BASE * max_counter_value) + 1;
+ if (devpriv->divisor_b0 < min_counter_value)
+ devpriv->divisor_b0 = min_counter_value;
+ if (devpriv->divisor_b0 > max_counter_value)
+ devpriv->divisor_b0 = max_counter_value;
+
+ base_period = LABPC_TIMER_BASE * devpriv->divisor_b0;
+
+ // set a0 for conversion frequency and b1 for scan frequency
+ switch (cmd->flags & TRIG_ROUND_MASK) {
+ default:
+ case TRIG_ROUND_NEAREST:
+ devpriv->divisor_a0 =
+ (labpc_ai_convert_period(cmd) +
+ (base_period / 2)) / base_period;
+ devpriv->divisor_b1 =
+ (labpc_ai_scan_period(cmd) +
+ (base_period / 2)) / base_period;
+ break;
+ case TRIG_ROUND_UP:
+ devpriv->divisor_a0 =
+ (labpc_ai_convert_period(cmd) + (base_period -
+ 1)) / base_period;
+ devpriv->divisor_b1 =
+ (labpc_ai_scan_period(cmd) + (base_period -
+ 1)) / base_period;
+ break;
+ case TRIG_ROUND_DOWN:
+ devpriv->divisor_a0 =
+ labpc_ai_convert_period(cmd) / base_period;
+ devpriv->divisor_b1 =
+ labpc_ai_scan_period(cmd) / base_period;
+ break;
+ }
+ // make sure a0 and b1 values are acceptable
+ if (devpriv->divisor_a0 < min_counter_value)
+ devpriv->divisor_a0 = min_counter_value;
+ if (devpriv->divisor_a0 > max_counter_value)
+ devpriv->divisor_a0 = max_counter_value;
+ if (devpriv->divisor_b1 < min_counter_value)
+ devpriv->divisor_b1 = min_counter_value;
+ if (devpriv->divisor_b1 > max_counter_value)
+ devpriv->divisor_b1 = max_counter_value;
+ // write corrected timings to command
+ labpc_set_ai_convert_period(cmd,
+ base_period * devpriv->divisor_a0);
+ labpc_set_ai_scan_period(cmd,
+ base_period * devpriv->divisor_b1);
+ // if only one TRIG_TIMER is used, we can employ the generic cascaded timing functions
+ } else if (labpc_ai_scan_period(cmd)) {
+ unsigned int scan_period;
+
+ scan_period = labpc_ai_scan_period(cmd);
+ /* calculate cascaded counter values that give desired scan timing */
+ i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+ &(devpriv->divisor_b1), &(devpriv->divisor_b0),
+ &scan_period, cmd->flags & TRIG_ROUND_MASK);
+ labpc_set_ai_scan_period(cmd, scan_period);
+ } else if (labpc_ai_convert_period(cmd)) {
+ unsigned int convert_period;
+
+ convert_period = labpc_ai_convert_period(cmd);
+ /* calculate cascaded counter values that give desired conversion timing */
+ i8253_cascade_ns_to_timer_2div(LABPC_TIMER_BASE,
+ &(devpriv->divisor_a0), &(devpriv->divisor_b0),
+ &convert_period, cmd->flags & TRIG_ROUND_MASK);
+ labpc_set_ai_convert_period(cmd, convert_period);
+ }
+}
+
+static int labpc_dio_mem_callback(int dir, int port, int data,
+ unsigned long iobase)
+{
+ if (dir) {
+ writeb(data, (void *)(iobase + port));
+ return 0;
+ } else {
+ return readb((void *)(iobase + port));
+ }
+}
+
+// lowlevel write to eeprom/dac
+static void labpc_serial_out(struct comedi_device * dev, unsigned int value,
+ unsigned int value_width)
+{
+ int i;
+
+ for (i = 1; i <= value_width; i++) {
+ // clear serial clock
+ devpriv->command5_bits &= ~SCLOCK_BIT;
+ // send bits most significant bit first
+ if (value & (1 << (value_width - i)))
+ devpriv->command5_bits |= SDATA_BIT;
+ else
+ devpriv->command5_bits &= ~SDATA_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ // set clock to load bit
+ devpriv->command5_bits |= SCLOCK_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ }
+}
+
+// lowlevel read from eeprom
+static unsigned int labpc_serial_in(struct comedi_device * dev)
+{
+ unsigned int value = 0;
+ int i;
+ const int value_width = 8; // number of bits wide values are
+
+ for (i = 1; i <= value_width; i++) {
+ // set serial clock
+ devpriv->command5_bits |= SCLOCK_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ // clear clock bit
+ devpriv->command5_bits &= ~SCLOCK_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits,
+ dev->iobase + COMMAND5_REG);
+ // read bits most significant bit first
+ comedi_udelay(1);
+ devpriv->status2_bits =
+ devpriv->read_byte(dev->iobase + STATUS2_REG);
+ if (devpriv->status2_bits & EEPROM_OUT_BIT) {
+ value |= 1 << (value_width - i);
+ }
+ }
+
+ return value;
+}
+
+static unsigned int labpc_eeprom_read(struct comedi_device * dev, unsigned int address)
+{
+ unsigned int value;
+ const int read_instruction = 0x3; // bits to tell eeprom to expect a read
+ const int write_length = 8; // 8 bit write lengths to eeprom
+
+ // enable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send read instruction
+ labpc_serial_out(dev, read_instruction, write_length);
+ // send 8 bit address to read from
+ labpc_serial_out(dev, address, write_length);
+ // read result
+ value = labpc_serial_in(dev);
+
+ // disable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ return value;
+}
+
+static unsigned int labpc_eeprom_write(struct comedi_device * dev,
+ unsigned int address, unsigned int value)
+{
+ const int write_enable_instruction = 0x6;
+ const int write_instruction = 0x2;
+ const int write_length = 8; // 8 bit write lengths to eeprom
+ const int write_in_progress_bit = 0x1;
+ const int timeout = 10000;
+ int i;
+
+ // make sure there isn't already a write in progress
+ for (i = 0; i < timeout; i++) {
+ if ((labpc_eeprom_read_status(dev) & write_in_progress_bit) ==
+ 0)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev, "eeprom write timed out");
+ return -ETIME;
+ }
+ // update software copy of eeprom
+ devpriv->eeprom_data[address] = value;
+
+ // enable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send write_enable instruction
+ labpc_serial_out(dev, write_enable_instruction, write_length);
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send write instruction
+ devpriv->command5_bits |= EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ labpc_serial_out(dev, write_instruction, write_length);
+ // send 8 bit address to write to
+ labpc_serial_out(dev, address, write_length);
+ // write value
+ labpc_serial_out(dev, value, write_length);
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // disable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ return 0;
+}
+
+static unsigned int labpc_eeprom_read_status(struct comedi_device * dev)
+{
+ unsigned int value;
+ const int read_status_instruction = 0x5;
+ const int write_length = 8; // 8 bit write lengths to eeprom
+
+ // enable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits |= EEPROM_EN_BIT | EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // send read status instruction
+ labpc_serial_out(dev, read_status_instruction, write_length);
+ // read result
+ value = labpc_serial_in(dev);
+
+ // disable read/write to eeprom
+ devpriv->command5_bits &= ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ return value;
+}
+
+// writes to 8 bit calibration dacs
+static void write_caldac(struct comedi_device * dev, unsigned int channel,
+ unsigned int value)
+{
+ if (value == devpriv->caldac[channel])
+ return;
+ devpriv->caldac[channel] = value;
+
+ // clear caldac load bit and make sure we don't write to eeprom
+ devpriv->command5_bits &=
+ ~CALDAC_LOAD_BIT & ~EEPROM_EN_BIT & ~EEPROM_WRITE_UNPROTECT_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+
+ // write 4 bit channel
+ labpc_serial_out(dev, channel, 4);
+ // write 8 bit caldac value
+ labpc_serial_out(dev, value, 8);
+
+ // set and clear caldac bit to load caldac value
+ devpriv->command5_bits |= CALDAC_LOAD_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+ devpriv->command5_bits &= ~CALDAC_LOAD_BIT;
+ comedi_udelay(1);
+ devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG);
+}
+
+#ifdef CONFIG_COMEDI_PCI
+COMEDI_PCI_INITCLEANUP(driver_labpc, labpc_pci_table);
+#else
+COMEDI_INITCLEANUP(driver_labpc);
+#endif
+
+EXPORT_SYMBOL_GPL(labpc_common_attach);
+EXPORT_SYMBOL_GPL(labpc_common_detach);
+EXPORT_SYMBOL_GPL(range_labpc_1200_ai);
+EXPORT_SYMBOL_GPL(labpc_1200_ai_gain_bits);
+EXPORT_SYMBOL_GPL(labpc_1200_is_unipolar);
diff --git a/drivers/staging/comedi/drivers/ni_labpc.h b/drivers/staging/comedi/drivers/ni_labpc.h
new file mode 100644
index 00000000000..b44b0d3d02f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc.h
@@ -0,0 +1,85 @@
+/*
+ ni_labpc.h
+
+ Header for ni_labpc.c and ni_labpc_cs.c
+
+ Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _NI_LABPC_H
+#define _NI_LABPC_H
+
+#define EEPROM_SIZE 256 // 256 byte eeprom
+#define NUM_AO_CHAN 2 // boards have two analog output channels
+
+enum labpc_bustype { isa_bustype, pci_bustype, pcmcia_bustype };
+enum labpc_register_layout { labpc_plus_layout, labpc_1200_layout };
+enum transfer_type { fifo_not_empty_transfer, fifo_half_full_transfer,
+ isa_dma_transfer };
+
+typedef struct labpc_board_struct {
+ const char *name;
+ int device_id; // device id for pci and pcmcia boards
+ int ai_speed; // maximum input speed in nanoseconds
+ enum labpc_bustype bustype; // ISA/PCI/etc.
+ enum labpc_register_layout register_layout; // 1200 has extra registers compared to pc+
+ int has_ao; // has analog output true/false
+ const struct comedi_lrange *ai_range_table;
+ const int *ai_range_code;
+ const int *ai_range_is_unipolar;
+ unsigned ai_scan_up:1; // board can auto scan up in ai channels, not just down
+ unsigned memory_mapped_io:1; /* uses memory mapped io instead of ioports */
+} labpc_board;
+
+typedef struct {
+ struct mite_struct *mite; // for mite chip on pci-1200
+ volatile unsigned long long count; /* number of data points left to be taken */
+ unsigned int ao_value[NUM_AO_CHAN]; // software copy of analog output values
+ // software copys of bits written to command registers
+ volatile unsigned int command1_bits;
+ volatile unsigned int command2_bits;
+ volatile unsigned int command3_bits;
+ volatile unsigned int command4_bits;
+ volatile unsigned int command5_bits;
+ volatile unsigned int command6_bits;
+ // store last read of board status registers
+ volatile unsigned int status1_bits;
+ volatile unsigned int status2_bits;
+ unsigned int divisor_a0; /* value to load into board's counter a0 (conversion pacing) for timed conversions */
+ unsigned int divisor_b0; /* value to load into board's counter b0 (master) for timed conversions */
+ unsigned int divisor_b1; /* value to load into board's counter b1 (scan pacing) for timed conversions */
+ unsigned int dma_chan; // dma channel to use
+ u16 *dma_buffer; // buffer ai will dma into
+ unsigned int dma_transfer_size; // transfer size in bytes for current transfer
+ enum transfer_type current_transfer; // we are using dma/fifo-half-full/etc.
+ unsigned int eeprom_data[EEPROM_SIZE]; // stores contents of board's eeprom
+ unsigned int caldac[16]; // stores settings of calibration dacs
+ // function pointers so we can use inb/outb or readb/writeb as appropriate
+ unsigned int (*read_byte) (unsigned long address);
+ void (*write_byte) (unsigned int byte, unsigned long address);
+} labpc_private;
+
+int labpc_common_attach(struct comedi_device * dev, unsigned long iobase,
+ unsigned int irq, unsigned int dma);
+int labpc_common_detach(struct comedi_device * dev);
+
+extern const int labpc_1200_is_unipolar[];
+extern const int labpc_1200_ai_gain_bits[];
+extern const struct comedi_lrange range_labpc_1200_ai;
+
+#endif /* _NI_LABPC_H */
diff --git a/drivers/staging/comedi/drivers/ni_labpc_cs.c b/drivers/staging/comedi/drivers/ni_labpc_cs.c
new file mode 100644
index 00000000000..ac0ce2f58f5
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_labpc_cs.c
@@ -0,0 +1,573 @@
+/*
+ comedi/drivers/ni_labpc_cs.c
+ Driver for National Instruments daqcard-1200 boards
+ Copyright (C) 2001, 2002, 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ PCMCIA crap is adapted from dummy_cs.c 1.31 2001/08/24 12:13:13
+ from the pcmcia package.
+ The initial developer of the pcmcia dummy_cs.c code is David A. Hinds
+ <dahinds@users.sourceforge.net>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+************************************************************************
+*/
+/*
+Driver: ni_labpc_cs
+Description: National Instruments Lab-PC (& compatibles)
+Author: Frank Mori Hess <fmhess@users.sourceforge.net>
+Devices: [National Instruments] DAQCard-1200 (daqcard-1200)
+Status: works
+
+Thanks go to Fredrik Lingvall for much testing and perseverance in
+helping to debug daqcard-1200 support.
+
+The 1200 series boards have onboard calibration dacs for correcting
+analog input/output offsets and gains. The proper settings for these
+caldacs are stored on the board's eeprom. To read the caldac values
+from the eeprom and store them into a file that can be then be used by
+comedilib, use the comedi_calibrate program.
+
+Configuration options:
+ none
+
+The daqcard-1200 has quirky chanlist requirements
+when scanning multiple channels. Multiple channel scan
+sequence must start at highest channel, then decrement down to
+channel 0. Chanlists consisting of all one channel
+are also legal, and allow you to pace conversions in bursts.
+
+*/
+
+/*
+
+NI manuals:
+340988a (daqcard-1200)
+
+*/
+
+#undef LABPC_DEBUG
+//#define LABPC_DEBUG // enable debugging messages
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "8253.h"
+#include "8255.h"
+#include "comedi_fc.h"
+#include "ni_labpc.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+static struct pcmcia_device *pcmcia_cur_dev = NULL;
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+
+static const labpc_board labpc_cs_boards[] = {
+ {
+ name: "daqcard-1200",
+ device_id:0x103, // 0x10b is manufacturer id, 0x103 is device id
+ ai_speed:10000,
+ bustype: pcmcia_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:0,
+ memory_mapped_io:0,
+ },
+ /* duplicate entry, to support using alternate name */
+ {
+ name: "ni_labpc_cs",
+ device_id:0x103,
+ ai_speed:10000,
+ bustype: pcmcia_bustype,
+ register_layout:labpc_1200_layout,
+ has_ao: 1,
+ ai_range_table:&range_labpc_1200_ai,
+ ai_range_code:labpc_1200_ai_gain_bits,
+ ai_range_is_unipolar:labpc_1200_is_unipolar,
+ ai_scan_up:0,
+ memory_mapped_io:0,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const labpc_board *)dev->board_ptr)
+
+static struct comedi_driver driver_labpc_cs = {
+ .driver_name = "ni_labpc_cs",
+ .module = THIS_MODULE,
+ .attach = &labpc_attach,
+ .detach = &labpc_common_detach,
+ .num_names = sizeof(labpc_cs_boards) / sizeof(labpc_board),
+ .board_name = &labpc_cs_boards[0].name,
+ .offset = sizeof(labpc_board),
+};
+
+static int labpc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase = 0;
+ unsigned int irq = 0;
+ struct pcmcia_device *link;
+
+ /* allocate and initialize dev->private */
+ if (alloc_private(dev, sizeof(labpc_private)) < 0)
+ return -ENOMEM;
+
+ // get base address, irq etc. based on bustype
+ switch (thisboard->bustype) {
+ case pcmcia_bustype:
+ link = pcmcia_cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+ iobase = link->io.BasePort1;
+ irq = link->irq.AssignedIRQ;
+ break;
+ default:
+ printk("bug! couldn't determine board type\n");
+ return -EINVAL;
+ break;
+ }
+ return labpc_common_attach(dev, iobase, irq, 0);
+}
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static const char *version =
+ "ni_labpc.c, based on dummy_cs.c 1.31 2001/08/24 12:13:13";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/*====================================================================*/
+
+/*
+ The event() function is this driver's Card Services event handler.
+ It will be called by Card Services when an appropriate card status
+ event is received. The config() and release() entry points are
+ used to configure or release a socket, in response to card
+ insertion and ejection events. They are invoked from the dummy
+ event handler.
+
+ Kernel version 2.6.16 upwards uses suspend() and resume() functions
+ instead of an event() function.
+*/
+
+static void labpc_config(struct pcmcia_device *link);
+static void labpc_release(struct pcmcia_device *link);
+static int labpc_cs_suspend(struct pcmcia_device *p_dev);
+static int labpc_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int labpc_cs_attach(struct pcmcia_device *);
+static void labpc_cs_detach(struct pcmcia_device *);
+
+/*
+ You'll also need to prototype all the functions that will actually
+ be used to talk to your device. See 'memory_cs' for a good example
+ of a fully self-sufficient driver; the other drivers rely more or
+ less on other parts of the kernel.
+*/
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "daqcard-1200";
+
+typedef struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ struct bus_operations *bus;
+} local_info_t;
+
+/*======================================================================
+
+ labpc_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int labpc_cs_attach(struct pcmcia_device *link)
+{
+ local_info_t *local;
+
+ DEBUG(0, "labpc_cs_attach()\n");
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_FORCED_PULSE;
+ link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_PULSE_ID;
+ link->irq.Handler = NULL;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ pcmcia_cur_dev = link;
+
+ labpc_config(link);
+
+ return 0;
+} /* labpc_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void labpc_cs_detach(struct pcmcia_device *link)
+{
+ DEBUG(0, "labpc_cs_detach(0x%p)\n", link);
+
+ /*
+ If the device is currently configured and active, we won't
+ actually delete it yet. Instead, it is marked so that when
+ the release() function is called, that will trigger a proper
+ detach().
+ */
+ if (link->dev_node) {
+ ((local_info_t *) link->priv)->stop = 1;
+ labpc_release(link);
+ }
+
+ /* This points to the parent local_info_t struct */
+ if (link->priv)
+ kfree(link->priv);
+
+} /* labpc_cs_detach */
+
+/*======================================================================
+
+ labpc_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void labpc_config(struct pcmcia_device *link)
+{
+ local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+ win_req_t req;
+ memreq_t map;
+ cistpl_cftable_entry_t dflt = { 0 };
+
+ DEBUG(0, "labpc_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple))
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse))
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Does this card need audio output? */
+ if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+ link->conf.Attributes |= CONF_ENABLE_SPKR;
+ link->conf.Status = CCSR_AUDIO_ENA;
+ }
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io))
+ goto next_entry;
+ }
+
+ if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+ cistpl_mem_t *mem =
+ (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+ req.Attributes = WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM;
+ req.Attributes |= WIN_ENABLE;
+ req.Base = mem->win[0].host_addr;
+ req.Size = mem->win[0].len;
+ if (req.Size < 0x1000)
+ req.Size = 0x1000;
+ req.AccessSpeed = 0;
+ link->win = (window_handle_t) link;
+ if (pcmcia_request_window(&link, &req, &link->win))
+ goto next_entry;
+ map.Page = 0;
+ map.CardOffset = mem->win[0].card_addr;
+ if (pcmcia_map_mem_page(link->win, &map))
+ goto next_entry;
+ }
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ Allocate an interrupt line. Note that this does not assign a
+ handler to the interrupt, unless the 'Handler' member of the
+ irq structure is initialized.
+ */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ if ((last_ret = pcmcia_request_irq(link, &link->irq))) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ sprintf(dev->node.dev_name, "daqcard-1200");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %d", link->irq.AssignedIRQ);
+ if (link->io.NumPorts1)
+ printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+ link->io.BasePort1 + link->io.NumPorts1 - 1);
+ if (link->io.NumPorts2)
+ printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+ link->io.BasePort2 + link->io.NumPorts2 - 1);
+ if (link->win)
+ printk(", mem 0x%06lx-0x%06lx", req.Base,
+ req.Base + req.Size - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ labpc_release(link);
+
+} /* labpc_config */
+
+static void labpc_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "labpc_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* labpc_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int labpc_cs_suspend(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+} /* labpc_cs_suspend */
+
+static int labpc_cs_resume(struct pcmcia_device *link)
+{
+ local_info_t *local = link->priv;
+
+ local->stop = 0;
+ return 0;
+} /* labpc_cs_resume */
+
+/*====================================================================*/
+
+static struct pcmcia_device_id labpc_cs_ids[] = {
+ /* N.B. These IDs should match those in labpc_cs_boards (ni_labpc.c) */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0103), /* daqcard-1200 */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, labpc_cs_ids);
+
+struct pcmcia_driver labpc_cs_driver = {
+ .probe = labpc_cs_attach,
+ .remove = labpc_cs_detach,
+ .suspend = labpc_cs_suspend,
+ .resume = labpc_cs_resume,
+ .id_table = labpc_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+static int __init init_labpc_cs(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&labpc_cs_driver);
+ return 0;
+}
+
+static void __exit exit_labpc_cs(void)
+{
+ DEBUG(0, "ni_labpc: unloading\n");
+ pcmcia_unregister_driver(&labpc_cs_driver);
+}
+
+int __init labpc_init_module(void)
+{
+ int ret;
+
+ ret = init_labpc_cs();
+ if (ret < 0)
+ return ret;
+
+ return comedi_driver_register(&driver_labpc_cs);
+}
+
+void __exit labpc_exit_module(void)
+{
+ exit_labpc_cs();
+ comedi_driver_unregister(&driver_labpc_cs);
+}
+
+MODULE_LICENSE("GPL");
+module_init(labpc_init_module);
+module_exit(labpc_exit_module);
diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
new file mode 100644
index 00000000000..542bd0dcd44
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_mio_common.c
@@ -0,0 +1,5862 @@
+/*
+ comedi/drivers/ni_mio_common.c
+ Hardware driver for DAQ-STC based boards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2001 David A. Schleef <ds@schleef.org>
+ Copyright (C) 2002-2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+ This file is meant to be included by another file, e.g.,
+ ni_atmio.c or ni_pcimio.c.
+
+ Interrupt support originally added by Truxton Fulton
+ <trux@truxton.com>
+
+ References (from ftp://ftp.natinst.com/support/manuals):
+
+ 340747b.pdf AT-MIO E series Register Level Programmer Manual
+ 341079b.pdf PCI E Series RLPM
+ 340934b.pdf DAQ-STC reference manual
+ 67xx and 611x registers (from http://www.ni.com/pdf/daq/us)
+ release_ni611x.pdf
+ release_ni67xx.pdf
+ Other possibly relevant info:
+
+ 320517c.pdf User manual (obsolete)
+ 320517f.pdf User manual (new)
+ 320889a.pdf delete
+ 320906c.pdf maximum signal ratings
+ 321066a.pdf about 16x
+ 321791a.pdf discontinuation of at-mio-16e-10 rev. c
+ 321808a.pdf about at-mio-16e-10 rev P
+ 321837a.pdf discontinuation of at-mio-16de-10 rev d
+ 321838a.pdf about at-mio-16de-10 rev N
+
+ ISSUES:
+
+ - the interrupt routine needs to be cleaned up
+
+ 2006-02-07: S-Series PCI-6143: Support has been added but is not
+ fully tested as yet. Terry Barnaby, BEAM Ltd.
+*/
+
+//#define DEBUG_INTERRUPT
+//#define DEBUG_STATUS_A
+//#define DEBUG_STATUS_B
+
+#include "8255.h"
+#include "mite.h"
+#include "comedi_fc.h"
+
+#ifndef MDPRINTK
+#define MDPRINTK(format,args...)
+#endif
+
+/* A timeout count */
+#define NI_TIMEOUT 1000
+static const unsigned old_RTSI_clock_channel = 7;
+
+/* Note: this table must match the ai_gain_* definitions */
+static const short ni_gainlkup[][16] = {
+ [ai_gain_16] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 0x100, 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
+ [ai_gain_8] = {1, 2, 4, 7, 0x101, 0x102, 0x104, 0x107},
+ [ai_gain_14] = {1, 2, 3, 4, 5, 6, 7,
+ 0x101, 0x102, 0x103, 0x104, 0x105, 0x106, 0x107},
+ [ai_gain_4] = {0, 1, 4, 7},
+ [ai_gain_611x] = {0x00a, 0x00b, 0x001, 0x002,
+ 0x003, 0x004, 0x005, 0x006},
+ [ai_gain_622x] = {0, 1, 4, 5},
+ [ai_gain_628x] = {1, 2, 3, 4, 5, 6, 7},
+ [ai_gain_6143] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+};
+
+static const struct comedi_lrange range_ni_E_ai = { 16, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2.5, 2.5),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.25, 0.25),
+ RANGE(-0.1, 0.1),
+ RANGE(-0.05, 0.05),
+ RANGE(0, 20),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2),
+ RANGE(0, 1),
+ RANGE(0, 0.5),
+ RANGE(0, 0.2),
+ RANGE(0, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_limited = { 8, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-1, 1),
+ RANGE(-0.1, 0.1),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 1),
+ RANGE(0, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_limited14 = { 14, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.2, 0.2),
+ RANGE(-0.1, 0.1),
+ RANGE(0, 10),
+ RANGE(0, 5),
+ RANGE(0, 2),
+ RANGE(0, 1),
+ RANGE(0, 0.5),
+ RANGE(0, 0.2),
+ RANGE(0, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_bipolar4 = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.05, 0.05),
+ }
+};
+static const struct comedi_lrange range_ni_E_ai_611x = { 8, {
+ RANGE(-50, 50),
+ RANGE(-20, 20),
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.2, 0.2),
+ }
+};
+static const struct comedi_lrange range_ni_M_ai_622x = { 4, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-1, 1),
+ RANGE(-0.2, 0.2),
+ }
+};
+static const struct comedi_lrange range_ni_M_ai_628x = { 7, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-0.5, 0.5),
+ RANGE(-0.2, 0.2),
+ RANGE(-0.1, 0.1),
+ }
+};
+static const struct comedi_lrange range_ni_S_ai_6143 = { 1, {
+ RANGE(-5, +5),
+ }
+};
+static const struct comedi_lrange range_ni_E_ao_ext = { 4, {
+ RANGE(-10, 10),
+ RANGE(0, 10),
+ RANGE_ext(-1, 1),
+ RANGE_ext(0, 1),
+ }
+};
+
+static const struct comedi_lrange *const ni_range_lkup[] = {
+ [ai_gain_16] = &range_ni_E_ai,
+ [ai_gain_8] = &range_ni_E_ai_limited,
+ [ai_gain_14] = &range_ni_E_ai_limited14,
+ [ai_gain_4] = &range_ni_E_ai_bipolar4,
+ [ai_gain_611x] = &range_ni_E_ai_611x,
+ [ai_gain_622x] = &range_ni_M_ai_622x,
+ [ai_gain_628x] = &range_ni_M_ai_628x,
+ [ai_gain_6143] = &range_ni_S_ai_6143
+};
+
+static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ni_cdio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_cdio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void handle_cdio_interrupt(struct comedi_device * dev);
+static int ni_cdo_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+
+static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in);
+static int ni_serial_sw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in);
+
+static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan);
+
+static void ni_rtsi_init(struct comedi_device * dev);
+static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_read_eeprom(struct comedi_device * dev, int addr);
+
+#ifdef DEBUG_STATUS_A
+static void ni_mio_print_status_a(int status);
+#else
+#define ni_mio_print_status_a(a)
+#endif
+#ifdef DEBUG_STATUS_B
+static void ni_mio_print_status_b(int status);
+#else
+#define ni_mio_print_status_b(a)
+#endif
+
+static int ni_ai_reset(struct comedi_device * dev, struct comedi_subdevice * s);
+#ifndef PCIDMA
+static void ni_handle_fifo_half_full(struct comedi_device * dev);
+static int ni_ao_fifo_half_empty(struct comedi_device * dev, struct comedi_subdevice * s);
+#endif
+static void ni_handle_fifo_dregs(struct comedi_device * dev);
+static int ni_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+static void ni_load_channelgain_list(struct comedi_device * dev, unsigned int n_chan,
+ unsigned int *list);
+static void shutdown_ai_command(struct comedi_device * dev);
+
+static int ni_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+
+static int ni_ao_reset(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static int ni_8255_callback(int dir, int port, int data, unsigned long arg);
+
+static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_gpct_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_gpct_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void handle_gpct_interrupt(struct comedi_device * dev,
+ unsigned short counter_index);
+
+static int init_cs5529(struct comedi_device * dev);
+static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data);
+static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+#ifdef NI_CS5529_DEBUG
+static unsigned int cs5529_config_read(struct comedi_device * dev,
+ unsigned int reg_select_bits);
+#endif
+static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
+ unsigned int reg_select_bits);
+
+static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
+ unsigned period_ns);
+static void ack_a_interrupt(struct comedi_device * dev, unsigned short a_status);
+static void ack_b_interrupt(struct comedi_device * dev, unsigned short b_status);
+
+enum aimodes {
+ AIMODE_NONE = 0,
+ AIMODE_HALF_FULL = 1,
+ AIMODE_SCAN = 2,
+ AIMODE_SAMPLE = 3,
+};
+
+enum ni_common_subdevices {
+ NI_AI_SUBDEV,
+ NI_AO_SUBDEV,
+ NI_DIO_SUBDEV,
+ NI_8255_DIO_SUBDEV,
+ NI_UNUSED_SUBDEV,
+ NI_CALIBRATION_SUBDEV,
+ NI_EEPROM_SUBDEV,
+ NI_PFI_DIO_SUBDEV,
+ NI_CS5529_CALIBRATION_SUBDEV,
+ NI_SERIAL_SUBDEV,
+ NI_RTSI_SUBDEV,
+ NI_GPCT0_SUBDEV,
+ NI_GPCT1_SUBDEV,
+ NI_FREQ_OUT_SUBDEV,
+ NI_NUM_SUBDEVICES
+};
+static inline unsigned NI_GPCT_SUBDEV(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NI_GPCT0_SUBDEV;
+ break;
+ case 1:
+ return NI_GPCT1_SUBDEV;
+ break;
+ default:
+ break;
+ }
+ BUG();
+ return NI_GPCT0_SUBDEV;
+}
+
+enum timebase_nanoseconds {
+ TIMEBASE_1_NS = 50,
+ TIMEBASE_2_NS = 10000
+};
+
+#define SERIAL_DISABLED 0
+#define SERIAL_600NS 600
+#define SERIAL_1_2US 1200
+#define SERIAL_10US 10000
+
+static const int num_adc_stages_611x = 3;
+
+static void handle_a_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned ai_mite_status);
+static void handle_b_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned ao_mite_status);
+static void get_last_sample_611x(struct comedi_device * dev);
+static void get_last_sample_6143(struct comedi_device * dev);
+
+static inline void ni_set_bitfield(struct comedi_device * dev, int reg,
+ unsigned bit_mask, unsigned bit_values)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+ switch (reg) {
+ case Interrupt_A_Enable_Register:
+ devpriv->int_a_enable_reg &= ~bit_mask;
+ devpriv->int_a_enable_reg |= bit_values & bit_mask;
+ devpriv->stc_writew(dev, devpriv->int_a_enable_reg,
+ Interrupt_A_Enable_Register);
+ break;
+ case Interrupt_B_Enable_Register:
+ devpriv->int_b_enable_reg &= ~bit_mask;
+ devpriv->int_b_enable_reg |= bit_values & bit_mask;
+ devpriv->stc_writew(dev, devpriv->int_b_enable_reg,
+ Interrupt_B_Enable_Register);
+ break;
+ case IO_Bidirection_Pin_Register:
+ devpriv->io_bidirection_pin_reg &= ~bit_mask;
+ devpriv->io_bidirection_pin_reg |= bit_values & bit_mask;
+ devpriv->stc_writew(dev, devpriv->io_bidirection_pin_reg,
+ IO_Bidirection_Pin_Register);
+ break;
+ case AI_AO_Select:
+ devpriv->ai_ao_select_reg &= ~bit_mask;
+ devpriv->ai_ao_select_reg |= bit_values & bit_mask;
+ ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+ break;
+ case G0_G1_Select:
+ devpriv->g0_g1_select_reg &= ~bit_mask;
+ devpriv->g0_g1_select_reg |= bit_values & bit_mask;
+ ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+ break;
+ default:
+ rt_printk("Warning %s() called with invalid register\n",
+ __FUNCTION__);
+ rt_printk("reg is %d\n", reg);
+ break;
+ }
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+}
+
+#ifdef PCIDMA
+static int ni_ai_drain_dma(struct comedi_device * dev);
+
+/* DMA channel setup */
+
+// negative channel means no channel
+static inline void ni_set_ai_dma_channel(struct comedi_device * dev, int channel)
+{
+ unsigned bitfield;
+
+ if (channel >= 0) {
+ bitfield =
+ (ni_stc_dma_channel_select_bitfield(channel) <<
+ AI_DMA_Select_Shift) & AI_DMA_Select_Mask;
+ } else {
+ bitfield = 0;
+ }
+ ni_set_bitfield(dev, AI_AO_Select, AI_DMA_Select_Mask, bitfield);
+}
+
+// negative channel means no channel
+static inline void ni_set_ao_dma_channel(struct comedi_device * dev, int channel)
+{
+ unsigned bitfield;
+
+ if (channel >= 0) {
+ bitfield =
+ (ni_stc_dma_channel_select_bitfield(channel) <<
+ AO_DMA_Select_Shift) & AO_DMA_Select_Mask;
+ } else {
+ bitfield = 0;
+ }
+ ni_set_bitfield(dev, AI_AO_Select, AO_DMA_Select_Mask, bitfield);
+}
+
+// negative mite_channel means no channel
+static inline void ni_set_gpct_dma_channel(struct comedi_device * dev,
+ unsigned gpct_index, int mite_channel)
+{
+ unsigned bitfield;
+
+ if (mite_channel >= 0) {
+ bitfield = GPCT_DMA_Select_Bits(gpct_index, mite_channel);
+ } else {
+ bitfield = 0;
+ }
+ ni_set_bitfield(dev, G0_G1_Select, GPCT_DMA_Select_Mask(gpct_index),
+ bitfield);
+}
+
+// negative mite_channel means no channel
+static inline void ni_set_cdo_dma_channel(struct comedi_device * dev, int mite_channel)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->soft_reg_copy_lock, flags);
+ devpriv->cdio_dma_select_reg &= ~CDO_DMA_Select_Mask;
+ if (mite_channel >= 0) {
+ /*XXX just guessing ni_stc_dma_channel_select_bitfield() returns the right bits,
+ under the assumption the cdio dma selection works just like ai/ao/gpct.
+ Definitely works for dma channels 0 and 1. */
+ devpriv->cdio_dma_select_reg |=
+ (ni_stc_dma_channel_select_bitfield(mite_channel) <<
+ CDO_DMA_Select_Shift) & CDO_DMA_Select_Mask;
+ }
+ ni_writeb(devpriv->cdio_dma_select_reg, M_Offset_CDIO_DMA_Select);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&devpriv->soft_reg_copy_lock, flags);
+}
+
+static int ni_request_ai_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->ai_mite_chan);
+ devpriv->ai_mite_chan =
+ mite_request_channel(devpriv->mite, devpriv->ai_mite_ring);
+ if (devpriv->ai_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for analog input.");
+ return -EBUSY;
+ }
+ devpriv->ai_mite_chan->dir = COMEDI_INPUT;
+ ni_set_ai_dma_channel(dev, devpriv->ai_mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+static int ni_request_ao_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->ao_mite_chan);
+ devpriv->ao_mite_chan =
+ mite_request_channel(devpriv->mite, devpriv->ao_mite_ring);
+ if (devpriv->ao_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for analog outut.");
+ return -EBUSY;
+ }
+ devpriv->ao_mite_chan->dir = COMEDI_OUTPUT;
+ ni_set_ao_dma_channel(dev, devpriv->ao_mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+static int ni_request_gpct_mite_channel(struct comedi_device * dev,
+ unsigned gpct_index, enum comedi_io_direction direction)
+{
+ unsigned long flags;
+ struct mite_channel *mite_chan;
+
+ BUG_ON(gpct_index >= NUM_GPCT);
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->counter_dev->counters[gpct_index].mite_chan);
+ mite_chan =
+ mite_request_channel(devpriv->mite,
+ devpriv->gpct_mite_ring[gpct_index]);
+ if (mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for counter.");
+ return -EBUSY;
+ }
+ mite_chan->dir = direction;
+ ni_tio_set_mite_channel(&devpriv->counter_dev->counters[gpct_index],
+ mite_chan);
+ ni_set_gpct_dma_channel(dev, gpct_index, mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+#endif // PCIDMA
+
+static int ni_request_cdo_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->cdo_mite_chan);
+ devpriv->cdo_mite_chan =
+ mite_request_channel(devpriv->mite, devpriv->cdo_mite_ring);
+ if (devpriv->cdo_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev,
+ "failed to reserve mite dma channel for correlated digital outut.");
+ return -EBUSY;
+ }
+ devpriv->cdo_mite_chan->dir = COMEDI_OUTPUT;
+ ni_set_cdo_dma_channel(dev, devpriv->cdo_mite_chan->channel);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+ return 0;
+}
+
+static void ni_release_ai_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan) {
+ ni_set_ai_dma_channel(dev, -1);
+ mite_release_channel(devpriv->ai_mite_chan);
+ devpriv->ai_mite_chan = NULL;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+static void ni_release_ao_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ao_mite_chan) {
+ ni_set_ao_dma_channel(dev, -1);
+ mite_release_channel(devpriv->ao_mite_chan);
+ devpriv->ao_mite_chan = NULL;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+void ni_release_gpct_mite_channel(struct comedi_device * dev, unsigned gpct_index)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ BUG_ON(gpct_index >= NUM_GPCT);
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->counter_dev->counters[gpct_index].mite_chan) {
+ struct mite_channel *mite_chan =
+ devpriv->counter_dev->counters[gpct_index].mite_chan;
+
+ ni_set_gpct_dma_channel(dev, gpct_index, -1);
+ ni_tio_set_mite_channel(&devpriv->counter_dev->
+ counters[gpct_index], NULL);
+ mite_release_channel(mite_chan);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+static void ni_release_cdo_mite_channel(struct comedi_device * dev)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->cdo_mite_chan) {
+ ni_set_cdo_dma_channel(dev, -1);
+ mite_release_channel(devpriv->cdo_mite_chan);
+ devpriv->cdo_mite_chan = NULL;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif // PCIDMA
+}
+
+// e-series boards use the second irq signals to generate dma requests for their counters
+#ifdef PCIDMA
+static void ni_e_series_enable_second_irq(struct comedi_device * dev,
+ unsigned gpct_index, short enable)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return;
+ switch (gpct_index) {
+ case 0:
+ if (enable) {
+ devpriv->stc_writew(dev, G0_Gate_Second_Irq_Enable,
+ Second_IRQ_A_Enable_Register);
+ } else {
+ devpriv->stc_writew(dev, 0,
+ Second_IRQ_A_Enable_Register);
+ }
+ break;
+ case 1:
+ if (enable) {
+ devpriv->stc_writew(dev, G1_Gate_Second_Irq_Enable,
+ Second_IRQ_B_Enable_Register);
+ } else {
+ devpriv->stc_writew(dev, 0,
+ Second_IRQ_B_Enable_Register);
+ }
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+#endif // PCIDMA
+
+static void ni_clear_ai_fifo(struct comedi_device * dev)
+{
+ if (boardtype.reg_type == ni_reg_6143) {
+ // Flush the 6143 data FIFO
+ ni_writel(0x10, AIFIFO_Control_6143); // Flush fifo
+ ni_writel(0x00, AIFIFO_Control_6143); // Flush fifo
+ while (ni_readl(AIFIFO_Status_6143) & 0x10) ; // Wait for complete
+ } else {
+ devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+ if (boardtype.reg_type == ni_reg_625x) {
+ ni_writeb(0, M_Offset_Static_AI_Control(0));
+ ni_writeb(1, M_Offset_Static_AI_Control(0));
+#if 0
+ /* the NI example code does 3 convert pulses for 625x boards,
+ but that appears to be wrong in practice. */
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+#endif
+ }
+ }
+}
+
+static void win_out2(struct comedi_device * dev, uint32_t data, int reg)
+{
+ devpriv->stc_writew(dev, data >> 16, reg);
+ devpriv->stc_writew(dev, data & 0xffff, reg + 1);
+}
+
+static uint32_t win_in2(struct comedi_device * dev, int reg)
+{
+ uint32_t bits;
+ bits = devpriv->stc_readw(dev, reg) << 16;
+ bits |= devpriv->stc_readw(dev, reg + 1);
+ return bits;
+}
+
+#define ao_win_out(data,addr) ni_ao_win_outw(dev,data,addr)
+static inline void ni_ao_win_outw(struct comedi_device * dev, uint16_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(addr, AO_Window_Address_611x);
+ ni_writew(data, AO_Window_Data_611x);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static inline void ni_ao_win_outl(struct comedi_device * dev, uint32_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(addr, AO_Window_Address_611x);
+ ni_writel(data, AO_Window_Data_611x);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static inline unsigned short ni_ao_win_inw(struct comedi_device * dev, int addr)
+{
+ unsigned long flags;
+ unsigned short data;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(addr, AO_Window_Address_611x);
+ data = ni_readw(AO_Window_Data_611x);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+ return data;
+}
+
+/* ni_set_bits( ) allows different parts of the ni_mio_common driver to
+* share registers (such as Interrupt_A_Register) without interfering with
+* each other.
+*
+* NOTE: the switch/case statements are optimized out for a constant argument
+* so this is actually quite fast--- If you must wrap another function around this
+* make it inline to avoid a large speed penalty.
+*
+* value should only be 1 or 0.
+*/
+static inline void ni_set_bits(struct comedi_device * dev, int reg, unsigned bits,
+ unsigned value)
+{
+ unsigned bit_values;
+
+ if (value)
+ bit_values = bits;
+ else
+ bit_values = 0;
+ ni_set_bitfield(dev, reg, bits, bit_values);
+}
+
+static irqreturn_t ni_E_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ unsigned short a_status;
+ unsigned short b_status;
+ unsigned int ai_mite_status = 0;
+ unsigned int ao_mite_status = 0;
+ unsigned long flags;
+#ifdef PCIDMA
+ struct mite_struct *mite = devpriv->mite;
+#endif
+
+ if (dev->attached == 0)
+ return IRQ_NONE;
+ smp_mb(); // make sure dev->attached is checked before handler does anything else.
+
+ // lock to avoid race with comedi_poll
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+ a_status = devpriv->stc_readw(dev, AI_Status_1_Register);
+ b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+#ifdef PCIDMA
+ if (mite) {
+ unsigned long flags_too;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock,
+ flags_too);
+ if (devpriv->ai_mite_chan) {
+ ai_mite_status = mite_get_status(devpriv->ai_mite_chan);
+ if (ai_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ devpriv->mite->mite_io_addr +
+ MITE_CHOR(devpriv->ai_mite_chan->
+ channel));
+ }
+ if (devpriv->ao_mite_chan) {
+ ao_mite_status = mite_get_status(devpriv->ao_mite_chan);
+ if (ao_mite_status & CHSR_LINKC)
+ writel(CHOR_CLRLC,
+ mite->mite_io_addr +
+ MITE_CHOR(devpriv->ao_mite_chan->
+ channel));
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags_too);
+ }
+#endif
+ ack_a_interrupt(dev, a_status);
+ ack_b_interrupt(dev, b_status);
+ if ((a_status & Interrupt_A_St) || (ai_mite_status & CHSR_INT))
+ handle_a_interrupt(dev, a_status, ai_mite_status);
+ if ((b_status & Interrupt_B_St) || (ao_mite_status & CHSR_INT))
+ handle_b_interrupt(dev, b_status, ao_mite_status);
+ handle_gpct_interrupt(dev, 0);
+ handle_gpct_interrupt(dev, 1);
+ handle_cdio_interrupt(dev);
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return IRQ_HANDLED;
+}
+
+#ifdef PCIDMA
+static void ni_sync_ai_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan)
+ mite_sync_input_dma(devpriv->ai_mite_chan, s->async);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static void mite_handle_b_linkc(struct mite_struct *mite, struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ao_mite_chan) {
+ mite_sync_output_dma(devpriv->ao_mite_chan, s->async);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static int ni_ao_wait_for_dma_load(struct comedi_device * dev)
+{
+ static const int timeout = 10000;
+ int i;
+ for (i = 0; i < timeout; i++) {
+ unsigned short b_status;
+
+ b_status = devpriv->stc_readw(dev, AO_Status_1_Register);
+ if (b_status & AO_FIFO_Half_Full_St)
+ break;
+ /* if we poll too often, the pci bus activity seems
+ to slow the dma transfer down */
+ comedi_udelay(10);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "timed out waiting for dma load");
+ return -EPIPE;
+ }
+ return 0;
+}
+
+#endif //PCIDMA
+static void ni_handle_eos(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (devpriv->aimode == AIMODE_SCAN) {
+#ifdef PCIDMA
+ static const int timeout = 10;
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ ni_sync_ai_dma(dev);
+ if ((s->async->events & COMEDI_CB_EOS))
+ break;
+ comedi_udelay(1);
+ }
+#else
+ ni_handle_fifo_dregs(dev);
+ s->async->events |= COMEDI_CB_EOS;
+#endif
+ }
+ /* handle special case of single scan using AI_End_On_End_Of_Scan */
+ if ((devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
+ shutdown_ai_command(dev);
+ }
+}
+
+static void shutdown_ai_command(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+#ifdef PCIDMA
+ ni_ai_drain_dma(dev);
+#endif
+ ni_handle_fifo_dregs(dev);
+ get_last_sample_611x(dev);
+ get_last_sample_6143(dev);
+
+ s->async->events |= COMEDI_CB_EOA;
+}
+
+static void ni_event(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (s->async->
+ events & (COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW | COMEDI_CB_EOA))
+ {
+ switch (s - dev->subdevices) {
+ case NI_AI_SUBDEV:
+ ni_ai_reset(dev, s);
+ break;
+ case NI_AO_SUBDEV:
+ ni_ao_reset(dev, s);
+ break;
+ case NI_GPCT0_SUBDEV:
+ case NI_GPCT1_SUBDEV:
+ ni_gpct_cancel(dev, s);
+ break;
+ case NI_DIO_SUBDEV:
+ ni_cdio_cancel(dev, s);
+ break;
+ default:
+ break;
+ }
+ }
+ comedi_event(dev, s);
+}
+
+static void handle_gpct_interrupt(struct comedi_device * dev,
+ unsigned short counter_index)
+{
+#ifdef PCIDMA
+ struct comedi_subdevice *s = dev->subdevices + NI_GPCT_SUBDEV(counter_index);
+
+ ni_tio_handle_interrupt(&devpriv->counter_dev->counters[counter_index],
+ s);
+ if (s->async->events)
+ ni_event(dev, s);
+#endif
+}
+
+static void ack_a_interrupt(struct comedi_device * dev, unsigned short a_status)
+{
+ unsigned short ack = 0;
+
+ if (a_status & AI_SC_TC_St) {
+ ack |= AI_SC_TC_Interrupt_Ack;
+ }
+ if (a_status & AI_START1_St) {
+ ack |= AI_START1_Interrupt_Ack;
+ }
+ if (a_status & AI_START_St) {
+ ack |= AI_START_Interrupt_Ack;
+ }
+ if (a_status & AI_STOP_St) {
+ /* not sure why we used to ack the START here also, instead of doing it independently. Frank Hess 2007-07-06 */
+ ack |= AI_STOP_Interrupt_Ack /*| AI_START_Interrupt_Ack */ ;
+ }
+ if (ack)
+ devpriv->stc_writew(dev, ack, Interrupt_A_Ack_Register);
+}
+
+static void handle_a_interrupt(struct comedi_device * dev, unsigned short status,
+ unsigned ai_mite_status)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+ //67xx boards don't have ai subdevice, but their gpct0 might generate an a interrupt
+ if (s->type == COMEDI_SUBD_UNUSED)
+ return;
+
+#ifdef DEBUG_INTERRUPT
+ rt_printk
+ ("ni_mio_common: interrupt: a_status=%04x ai_mite_status=%08x\n",
+ status, ai_mite_status);
+ ni_mio_print_status_a(status);
+#endif
+#ifdef PCIDMA
+ if (ai_mite_status & CHSR_LINKC) {
+ ni_sync_ai_dma(dev);
+ }
+
+ if (ai_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ rt_printk
+ ("unknown mite interrupt, ack! (ai_mite_status=%08x)\n",
+ ai_mite_status);
+ //mite_print_chsr(ai_mite_status);
+ s->async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ //disable_irq(dev->irq);
+ }
+#endif
+
+ /* test for all uncommon interrupt events at the same time */
+ if (status & (AI_Overrun_St | AI_Overflow_St | AI_SC_TC_Error_St |
+ AI_SC_TC_St | AI_START1_St)) {
+ if (status == 0xffff) {
+ rt_printk
+ ("ni_mio_common: a_status=0xffff. Card removed?\n");
+ /* we probably aren't even running a command now,
+ * so it's a good idea to be careful. */
+ if (comedi_get_subdevice_runflags(s) & SRF_RUNNING) {
+ s->async->events |=
+ COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ ni_event(dev, s);
+ }
+ return;
+ }
+ if (status & (AI_Overrun_St | AI_Overflow_St |
+ AI_SC_TC_Error_St)) {
+ rt_printk("ni_mio_common: ai error a_status=%04x\n",
+ status);
+ ni_mio_print_status_a(status);
+
+ shutdown_ai_command(dev);
+
+ s->async->events |= COMEDI_CB_ERROR;
+ if (status & (AI_Overrun_St | AI_Overflow_St))
+ s->async->events |= COMEDI_CB_OVERFLOW;
+
+ ni_event(dev, s);
+
+ return;
+ }
+ if (status & AI_SC_TC_St) {
+#ifdef DEBUG_INTERRUPT
+ rt_printk("ni_mio_common: SC_TC interrupt\n");
+#endif
+ if (!devpriv->ai_continuous) {
+ shutdown_ai_command(dev);
+ }
+ }
+ }
+#ifndef PCIDMA
+ if (status & AI_FIFO_Half_Full_St) {
+ int i;
+ static const int timeout = 10;
+ /* pcmcia cards (at least 6036) seem to stop producing interrupts if we
+ *fail to get the fifo less than half full, so loop to be sure.*/
+ for (i = 0; i < timeout; ++i) {
+ ni_handle_fifo_half_full(dev);
+ if ((devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Half_Full_St) == 0)
+ break;
+ }
+ }
+#endif // !PCIDMA
+
+ if ((status & AI_STOP_St)) {
+ ni_handle_eos(dev, s);
+ }
+
+ ni_event(dev, s);
+
+#ifdef DEBUG_INTERRUPT
+ status = devpriv->stc_readw(dev, AI_Status_1_Register);
+ if (status & Interrupt_A_St) {
+ rt_printk
+ ("handle_a_interrupt: didn't clear interrupt? status=0x%x\n",
+ status);
+ }
+#endif
+}
+
+static void ack_b_interrupt(struct comedi_device * dev, unsigned short b_status)
+{
+ unsigned short ack = 0;
+ if (b_status & AO_BC_TC_St) {
+ ack |= AO_BC_TC_Interrupt_Ack;
+ }
+ if (b_status & AO_Overrun_St) {
+ ack |= AO_Error_Interrupt_Ack;
+ }
+ if (b_status & AO_START_St) {
+ ack |= AO_START_Interrupt_Ack;
+ }
+ if (b_status & AO_START1_St) {
+ ack |= AO_START1_Interrupt_Ack;
+ }
+ if (b_status & AO_UC_TC_St) {
+ ack |= AO_UC_TC_Interrupt_Ack;
+ }
+ if (b_status & AO_UI2_TC_St) {
+ ack |= AO_UI2_TC_Interrupt_Ack;
+ }
+ if (b_status & AO_UPDATE_St) {
+ ack |= AO_UPDATE_Interrupt_Ack;
+ }
+ if (ack)
+ devpriv->stc_writew(dev, ack, Interrupt_B_Ack_Register);
+}
+
+static void handle_b_interrupt(struct comedi_device * dev, unsigned short b_status,
+ unsigned ao_mite_status)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+ //unsigned short ack=0;
+#ifdef DEBUG_INTERRUPT
+ rt_printk("ni_mio_common: interrupt: b_status=%04x m1_status=%08x\n",
+ b_status, ao_mite_status);
+ ni_mio_print_status_b(b_status);
+#endif
+
+#ifdef PCIDMA
+ /* Currently, mite.c requires us to handle LINKC */
+ if (ao_mite_status & CHSR_LINKC) {
+ mite_handle_b_linkc(devpriv->mite, dev);
+ }
+
+ if (ao_mite_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_MRDY |
+ CHSR_DRDY | CHSR_DRQ1 | CHSR_DRQ0 | CHSR_ERROR |
+ CHSR_SABORT | CHSR_XFERR | CHSR_LxERR_mask)) {
+ rt_printk
+ ("unknown mite interrupt, ack! (ao_mite_status=%08x)\n",
+ ao_mite_status);
+ //mite_print_chsr(ao_mite_status);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+#endif
+
+ if (b_status == 0xffff)
+ return;
+ if (b_status & AO_Overrun_St) {
+ rt_printk
+ ("ni_mio_common: AO FIFO underrun status=0x%04x status2=0x%04x\n",
+ b_status, devpriv->stc_readw(dev,
+ AO_Status_2_Register));
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+
+ if (b_status & AO_BC_TC_St) {
+ MDPRINTK("ni_mio_common: AO BC_TC status=0x%04x status2=0x%04x\n", b_status, devpriv->stc_readw(dev, AO_Status_2_Register));
+ s->async->events |= COMEDI_CB_EOA;
+ }
+#ifndef PCIDMA
+ if (b_status & AO_FIFO_Request_St) {
+ int ret;
+
+ ret = ni_ao_fifo_half_empty(dev, s);
+ if (!ret) {
+ rt_printk("ni_mio_common: AO buffer underrun\n");
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_FIFO_Interrupt_Enable |
+ AO_Error_Interrupt_Enable, 0);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ }
+#endif
+
+ ni_event(dev, s);
+}
+
+#ifdef DEBUG_STATUS_A
+static const char *const status_a_strings[] = {
+ "passthru0", "fifo", "G0_gate", "G0_TC",
+ "stop", "start", "sc_tc", "start1",
+ "start2", "sc_tc_error", "overflow", "overrun",
+ "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_a"
+};
+
+static void ni_mio_print_status_a(int status)
+{
+ int i;
+
+ rt_printk("A status:");
+ for (i = 15; i >= 0; i--) {
+ if (status & (1 << i)) {
+ rt_printk(" %s", status_a_strings[i]);
+ }
+ }
+ rt_printk("\n");
+}
+#endif
+
+#ifdef DEBUG_STATUS_B
+static const char *const status_b_strings[] = {
+ "passthru1", "fifo", "G1_gate", "G1_TC",
+ "UI2_TC", "UPDATE", "UC_TC", "BC_TC",
+ "start1", "overrun", "start", "bc_tc_error",
+ "fifo_empty", "fifo_half_full", "fifo_full", "interrupt_b"
+};
+
+static void ni_mio_print_status_b(int status)
+{
+ int i;
+
+ rt_printk("B status:");
+ for (i = 15; i >= 0; i--) {
+ if (status & (1 << i)) {
+ rt_printk(" %s", status_b_strings[i]);
+ }
+ }
+ rt_printk("\n");
+}
+#endif
+
+#ifndef PCIDMA
+
+static void ni_ao_fifo_load(struct comedi_device * dev, struct comedi_subdevice * s, int n)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_cmd *cmd = &async->cmd;
+ int chan;
+ int i;
+ short d;
+ u32 packed_data;
+ int range;
+ int err = 1;
+
+ chan = async->cur_chan;
+ for (i = 0; i < n; i++) {
+ err &= comedi_buf_get(async, &d);
+ if (err == 0)
+ break;
+
+ range = CR_RANGE(cmd->chanlist[chan]);
+
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ packed_data = d & 0xffff;
+ /* 6711 only has 16 bit wide ao fifo */
+ if (boardtype.reg_type != ni_reg_6711) {
+ err &= comedi_buf_get(async, &d);
+ if (err == 0)
+ break;
+ chan++;
+ i++;
+ packed_data |= (d << 16) & 0xffff0000;
+ }
+ ni_writel(packed_data, DAC_FIFO_Data_611x);
+ } else {
+ ni_writew(d, DAC_FIFO_Data);
+ }
+ chan++;
+ chan %= cmd->chanlist_len;
+ }
+ async->cur_chan = chan;
+ if (err == 0) {
+ async->events |= COMEDI_CB_OVERFLOW;
+ }
+}
+
+/*
+ * There's a small problem if the FIFO gets really low and we
+ * don't have the data to fill it. Basically, if after we fill
+ * the FIFO with all the data available, the FIFO is _still_
+ * less than half full, we never clear the interrupt. If the
+ * IRQ is in edge mode, we never get another interrupt, because
+ * this one wasn't cleared. If in level mode, we get flooded
+ * with interrupts that we can't fulfill, because nothing ever
+ * gets put into the buffer.
+ *
+ * This kind of situation is recoverable, but it is easier to
+ * just pretend we had a FIFO underrun, since there is a good
+ * chance it will happen anyway. This is _not_ the case for
+ * RT code, as RT code might purposely be running close to the
+ * metal. Needs to be fixed eventually.
+ */
+static int ni_ao_fifo_half_empty(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int n;
+
+ n = comedi_buf_read_n_available(s->async);
+ if (n == 0) {
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ return 0;
+ }
+
+ n /= sizeof(short);
+ if (n > boardtype.ao_fifo_depth / 2)
+ n = boardtype.ao_fifo_depth / 2;
+
+ ni_ao_fifo_load(dev, s, n);
+
+ s->async->events |= COMEDI_CB_BLOCK;
+
+ return 1;
+}
+
+static int ni_ao_prep_fifo(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int n;
+
+ /* reset fifo */
+ devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (boardtype.reg_type & ni_reg_6xxx_mask)
+ ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
+
+ /* load some data */
+ n = comedi_buf_read_n_available(s->async);
+ if (n == 0)
+ return 0;
+
+ n /= sizeof(short);
+ if (n > boardtype.ao_fifo_depth)
+ n = boardtype.ao_fifo_depth;
+
+ ni_ao_fifo_load(dev, s, n);
+
+ return n;
+}
+
+static void ni_ai_fifo_read(struct comedi_device * dev, struct comedi_subdevice * s, int n)
+{
+ struct comedi_async *async = s->async;
+ int i;
+
+ if (boardtype.reg_type == ni_reg_611x) {
+ short data[2];
+ u32 dl;
+
+ for (i = 0; i < n / 2; i++) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+ /* This may get the hi/lo data in the wrong order */
+ data[0] = (dl >> 16) & 0xffff;
+ data[1] = dl & 0xffff;
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ }
+ /* Check if there's a single sample stuck in the FIFO */
+ if (n % 2) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+ data[0] = dl & 0xffff;
+ cfc_write_to_buffer(s, data[0]);
+ }
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ short data[2];
+ u32 dl;
+
+ // This just reads the FIFO assuming the data is present, no checks on the FIFO status are performed
+ for (i = 0; i < n / 2; i++) {
+ dl = ni_readl(AIFIFO_Data_6143);
+
+ data[0] = (dl >> 16) & 0xffff;
+ data[1] = dl & 0xffff;
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ }
+ if (n % 2) {
+ /* Assume there is a single sample stuck in the FIFO */
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+ data[0] = (dl >> 16) & 0xffff;
+ cfc_write_to_buffer(s, data[0]);
+ }
+ } else {
+ if (n > sizeof(devpriv->ai_fifo_buffer) /
+ sizeof(devpriv->ai_fifo_buffer[0])) {
+ comedi_error(dev, "bug! ai_fifo_buffer too small");
+ async->events |= COMEDI_CB_ERROR;
+ return;
+ }
+ for (i = 0; i < n; i++) {
+ devpriv->ai_fifo_buffer[i] =
+ ni_readw(ADC_FIFO_Data_Register);
+ }
+ cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
+ n * sizeof(devpriv->ai_fifo_buffer[0]));
+ }
+}
+
+static void ni_handle_fifo_half_full(struct comedi_device * dev)
+{
+ int n;
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+
+ n = boardtype.ai_fifo_depth / 2;
+
+ ni_ai_fifo_read(dev, s, n);
+}
+#endif
+
+#ifdef PCIDMA
+static int ni_ai_drain_dma(struct comedi_device * dev)
+{
+ int i;
+ static const int timeout = 10000;
+ unsigned long flags;
+ int retval = 0;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ai_mite_chan) {
+ for (i = 0; i < timeout; i++) {
+ if ((devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St)
+ && mite_bytes_in_transit(devpriv->
+ ai_mite_chan) == 0)
+ break;
+ comedi_udelay(5);
+ }
+ if (i == timeout) {
+ rt_printk
+ ("ni_mio_common: wait for dma drain timed out\n");
+ rt_printk
+ ("mite_bytes_in_transit=%i, AI_Status1_Register=0x%x\n",
+ mite_bytes_in_transit(devpriv->ai_mite_chan),
+ devpriv->stc_readw(dev, AI_Status_1_Register));
+ retval = -1;
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ ni_sync_ai_dma(dev);
+
+ return retval;
+}
+#endif
+/*
+ Empties the AI fifo
+*/
+static void ni_handle_fifo_dregs(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ short data[2];
+ u32 dl;
+ short fifo_empty;
+ int i;
+
+ if (boardtype.reg_type == ni_reg_611x) {
+ while ((devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St) == 0) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+
+ /* This may get the hi/lo data in the wrong order */
+ data[0] = (dl >> 16);
+ data[1] = (dl & 0xffff);
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ }
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ i = 0;
+ while (ni_readl(AIFIFO_Status_6143) & 0x04) {
+ dl = ni_readl(AIFIFO_Data_6143);
+
+ /* This may get the hi/lo data in the wrong order */
+ data[0] = (dl >> 16);
+ data[1] = (dl & 0xffff);
+ cfc_write_array_to_buffer(s, data, sizeof(data));
+ i += 2;
+ }
+ // Check if stranded sample is present
+ if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+ data[0] = (dl >> 16) & 0xffff;
+ cfc_write_to_buffer(s, data[0]);
+ }
+
+ } else {
+ fifo_empty =
+ devpriv->stc_readw(dev,
+ AI_Status_1_Register) & AI_FIFO_Empty_St;
+ while (fifo_empty == 0) {
+ for (i = 0;
+ i <
+ sizeof(devpriv->ai_fifo_buffer) /
+ sizeof(devpriv->ai_fifo_buffer[0]); i++) {
+ fifo_empty =
+ devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St;
+ if (fifo_empty)
+ break;
+ devpriv->ai_fifo_buffer[i] =
+ ni_readw(ADC_FIFO_Data_Register);
+ }
+ cfc_write_array_to_buffer(s, devpriv->ai_fifo_buffer,
+ i * sizeof(devpriv->ai_fifo_buffer[0]));
+ }
+ }
+}
+
+static void get_last_sample_611x(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ short data;
+ u32 dl;
+
+ if (boardtype.reg_type != ni_reg_611x)
+ return;
+
+ /* Check if there's a single sample stuck in the FIFO */
+ if (ni_readb(XXX_Status) & 0x80) {
+ dl = ni_readl(ADC_FIFO_Data_611x);
+ data = (dl & 0xffff);
+ cfc_write_to_buffer(s, data);
+ }
+}
+
+static void get_last_sample_6143(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ short data;
+ u32 dl;
+
+ if (boardtype.reg_type != ni_reg_6143)
+ return;
+
+ /* Check if there's a single sample stuck in the FIFO */
+ if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+
+ /* This may get the hi/lo data in the wrong order */
+ data = (dl >> 16) & 0xffff;
+ cfc_write_to_buffer(s, data);
+ }
+}
+
+static void ni_ai_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int chan_index)
+{
+ struct comedi_async *async = s->async;
+ unsigned int i;
+ unsigned int length = num_bytes / bytes_per_sample(s);
+ short *array = data;
+ unsigned int *larray = data;
+ for (i = 0; i < length; i++) {
+#ifdef PCIDMA
+ if (s->subdev_flags & SDF_LSAMPL)
+ larray[i] = le32_to_cpu(larray[i]);
+ else
+ array[i] = le16_to_cpu(array[i]);
+#endif
+ if (s->subdev_flags & SDF_LSAMPL)
+ larray[i] += devpriv->ai_offset[chan_index];
+ else
+ array[i] += devpriv->ai_offset[chan_index];
+ chan_index++;
+ chan_index %= async->cmd.chanlist_len;
+ }
+}
+
+#ifdef PCIDMA
+
+static int ni_ai_setup_MITE_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AI_SUBDEV;
+ int retval;
+ unsigned long flags;
+
+ retval = ni_request_ai_mite_channel(dev);
+ if (retval)
+ return retval;
+// rt_printk("comedi_debug: using mite channel %i for ai.\n", devpriv->ai_mite_chan->channel);
+
+ /* write alloc the entire buffer */
+ comedi_buf_write_alloc(s->async, s->async->prealloc_bufsz);
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if(devpriv->ai_mite_chan == NULL)
+ {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return -EIO;
+ }
+
+ switch (boardtype.reg_type) {
+ case ni_reg_611x:
+ case ni_reg_6143:
+ mite_prep_dma(devpriv->ai_mite_chan, 32, 16);
+ break;
+ case ni_reg_628x:
+ mite_prep_dma(devpriv->ai_mite_chan, 32, 32);
+ break;
+ default:
+ mite_prep_dma(devpriv->ai_mite_chan, 16, 16);
+ break;
+ };
+ /*start the MITE */
+ mite_dma_arm(devpriv->ai_mite_chan);
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ return 0;
+}
+
+static int ni_ao_setup_MITE_dma(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s = dev->subdevices + NI_AO_SUBDEV;
+ int retval;
+ unsigned long flags;
+
+ retval = ni_request_ao_mite_channel(dev);
+ if (retval)
+ return retval;
+
+ /* read alloc the entire buffer */
+ comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->ao_mite_chan) {
+ if (boardtype.reg_type & (ni_reg_611x | ni_reg_6713)) {
+ mite_prep_dma(devpriv->ao_mite_chan, 32, 32);
+ } else {
+ /* doing 32 instead of 16 bit wide transfers from memory
+ makes the mite do 32 bit pci transfers, doubling pci bandwidth. */
+ mite_prep_dma(devpriv->ao_mite_chan, 16, 32);
+ }
+ mite_dma_arm(devpriv->ao_mite_chan);
+ } else
+ retval = -EIO;
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+
+ return retval;
+}
+
+#endif // PCIDMA
+
+/*
+ used for both cancel ioctl and board initialization
+
+ this is pretty harsh for a cancel, but it works...
+ */
+
+static int ni_ai_reset(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ ni_release_ai_mite_channel(dev);
+ /* ai configuration */
+ devpriv->stc_writew(dev, AI_Configuration_Start | AI_Reset,
+ Joint_Reset_Register);
+
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ AI_SC_TC_Interrupt_Enable | AI_START1_Interrupt_Enable |
+ AI_START2_Interrupt_Enable | AI_START_Interrupt_Enable |
+ AI_STOP_Interrupt_Enable | AI_Error_Interrupt_Enable |
+ AI_FIFO_Interrupt_Enable, 0);
+
+ ni_clear_ai_fifo(dev);
+
+ if (boardtype.reg_type != ni_reg_6143)
+ ni_writeb(0, Misc_Command);
+
+ devpriv->stc_writew(dev, AI_Disarm, AI_Command_1_Register); /* reset pulses */
+ devpriv->stc_writew(dev,
+ AI_Start_Stop | AI_Mode_1_Reserved /*| AI_Trigger_Once */ ,
+ AI_Mode_1_Register);
+ devpriv->stc_writew(dev, 0x0000, AI_Mode_2_Register);
+ /* generate FIFO interrupts on non-empty */
+ devpriv->stc_writew(dev, (0 << 6) | 0x0000, AI_Mode_3_Register);
+ if (boardtype.reg_type == ni_reg_611x) {
+ devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+ devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_High),
+ AI_Output_Control_Register);
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+ devpriv->stc_writew(dev, AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3) |
+ AI_CONVERT_Output_Select(AI_CONVERT_Output_Enable_Low),
+ AI_Output_Control_Register);
+ } else {
+ unsigned ai_output_control_bits;
+ devpriv->stc_writew(dev, AI_SHIFTIN_Pulse_Width |
+ AI_SOC_Polarity |
+ AI_CONVERT_Pulse_Width |
+ AI_LOCALMUX_CLK_Pulse_Width, AI_Personal_Register);
+ ai_output_control_bits = AI_SCAN_IN_PROG_Output_Select(3) |
+ AI_EXTMUX_CLK_Output_Select(0) |
+ AI_LOCALMUX_CLK_Output_Select(2) |
+ AI_SC_TC_Output_Select(3);
+ if (boardtype.reg_type == ni_reg_622x)
+ ai_output_control_bits |=
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_High);
+ else
+ ai_output_control_bits |=
+ AI_CONVERT_Output_Select
+ (AI_CONVERT_Output_Enable_Low);
+ devpriv->stc_writew(dev, ai_output_control_bits,
+ AI_Output_Control_Register);
+ }
+ /* the following registers should not be changed, because there
+ * are no backup registers in devpriv. If you want to change
+ * any of these, add a backup register and other appropriate code:
+ * AI_Mode_1_Register
+ * AI_Mode_3_Register
+ * AI_Personal_Register
+ * AI_Output_Control_Register
+ */
+ devpriv->stc_writew(dev, AI_SC_TC_Error_Confirm | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack, Interrupt_A_Ack_Register); /* clear interrupts */
+
+ devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+
+ return 0;
+}
+
+static int ni_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags = 0;
+ int count;
+
+ // lock to avoid race with interrupt handler
+ if (in_interrupt() == 0)
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+#ifndef PCIDMA
+ ni_handle_fifo_dregs(dev);
+#else
+ ni_sync_ai_dma(dev);
+#endif
+ count = s->async->buf_write_count - s->async->buf_read_count;
+ if (in_interrupt() == 0)
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return count;
+}
+
+static int ni_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ const unsigned int mask = (1 << boardtype.adbits) - 1;
+ unsigned signbits;
+ unsigned short d;
+ unsigned long dl;
+
+ ni_load_channelgain_list(dev, 1, &insn->chanspec);
+
+ ni_clear_ai_fifo(dev);
+
+ signbits = devpriv->ai_offset[0];
+ if (boardtype.reg_type == ni_reg_611x) {
+ for (n = 0; n < num_adc_stages_611x; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ comedi_udelay(1);
+ }
+ for (n = 0; n < insn->n; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ /* The 611x has screwy 32-bit FIFOs. */
+ d = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readb(XXX_Status) & 0x80) {
+ d = (ni_readl(ADC_FIFO_Data_611x) >> 16)
+ & 0xffff;
+ break;
+ }
+ if (!(devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St)) {
+ d = ni_readl(ADC_FIFO_Data_611x) &
+ 0xffff;
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ rt_printk
+ ("ni_mio_common: timeout in 611x ni_ai_insn_read\n");
+ return -ETIME;
+ }
+ d += signbits;
+ data[n] = d;
+ }
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ for (n = 0; n < insn->n; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+
+ /* The 6143 has 32-bit FIFOs. You need to strobe a bit to move a single 16bit stranded sample into the FIFO */
+ dl = 0;
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (ni_readl(AIFIFO_Status_6143) & 0x01) {
+ ni_writel(0x01, AIFIFO_Control_6143); // Get stranded sample into FIFO
+ dl = ni_readl(AIFIFO_Data_6143);
+ break;
+ }
+ }
+ if (i == NI_TIMEOUT) {
+ rt_printk
+ ("ni_mio_common: timeout in 6143 ni_ai_insn_read\n");
+ return -ETIME;
+ }
+ data[n] = (((dl >> 16) & 0xFFFF) + signbits) & 0xFFFF;
+ }
+ } else {
+ for (n = 0; n < insn->n; n++) {
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse,
+ AI_Command_1_Register);
+ for (i = 0; i < NI_TIMEOUT; i++) {
+ if (!(devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St))
+ break;
+ }
+ if (i == NI_TIMEOUT) {
+ rt_printk
+ ("ni_mio_common: timeout in ni_ai_insn_read\n");
+ return -ETIME;
+ }
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ data[n] =
+ ni_readl(M_Offset_AI_FIFO_Data) & mask;
+ } else {
+ d = ni_readw(ADC_FIFO_Data_Register);
+ d += signbits; /* subtle: needs to be short addition */
+ data[n] = d;
+ }
+ }
+ }
+ return insn->n;
+}
+
+void ni_prime_channelgain_list(struct comedi_device * dev)
+{
+ int i;
+ devpriv->stc_writew(dev, AI_CONVERT_Pulse, AI_Command_1_Register);
+ for (i = 0; i < NI_TIMEOUT; ++i) {
+ if (!(devpriv->stc_readw(dev,
+ AI_Status_1_Register) &
+ AI_FIFO_Empty_St)) {
+ devpriv->stc_writew(dev, 1, ADC_FIFO_Clear);
+ return;
+ }
+ comedi_udelay(1);
+ }
+ rt_printk("ni_mio_common: timeout loading channel/gain list\n");
+}
+
+static void ni_m_series_load_channelgain_list(struct comedi_device * dev,
+ unsigned int n_chan, unsigned int *list)
+{
+ unsigned int chan, range, aref;
+ unsigned int i;
+ unsigned offset;
+ unsigned int dither;
+ unsigned range_code;
+
+ devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+
+// offset = 1 << (boardtype.adbits - 1);
+ if ((list[0] & CR_ALT_SOURCE)) {
+ unsigned bypass_bits;
+ chan = CR_CHAN(list[0]);
+ range = CR_RANGE(list[0]);
+ range_code = ni_gainlkup[boardtype.gainlkup][range];
+ dither = ((list[0] & CR_ALT_FILTER) != 0);
+ bypass_bits = MSeries_AI_Bypass_Config_FIFO_Bit;
+ bypass_bits |= chan;
+ bypass_bits |=
+ (devpriv->
+ ai_calib_source) & (MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
+ MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
+ MSeries_AI_Bypass_Mode_Mux_Mask |
+ MSeries_AO_Bypass_AO_Cal_Sel_Mask);
+ bypass_bits |= MSeries_AI_Bypass_Gain_Bits(range_code);
+ if (dither)
+ bypass_bits |= MSeries_AI_Bypass_Dither_Bit;
+ // don't use 2's complement encoding
+ bypass_bits |= MSeries_AI_Bypass_Polarity_Bit;
+ ni_writel(bypass_bits, M_Offset_AI_Config_FIFO_Bypass);
+ } else {
+ ni_writel(0, M_Offset_AI_Config_FIFO_Bypass);
+ }
+ offset = 0;
+ for (i = 0; i < n_chan; i++) {
+ unsigned config_bits = 0;
+ chan = CR_CHAN(list[i]);
+ aref = CR_AREF(list[i]);
+ range = CR_RANGE(list[i]);
+ dither = ((list[i] & CR_ALT_FILTER) != 0);
+
+ range_code = ni_gainlkup[boardtype.gainlkup][range];
+ devpriv->ai_offset[i] = offset;
+ switch (aref) {
+ case AREF_DIFF:
+ config_bits |=
+ MSeries_AI_Config_Channel_Type_Differential_Bits;
+ break;
+ case AREF_COMMON:
+ config_bits |=
+ MSeries_AI_Config_Channel_Type_Common_Ref_Bits;
+ break;
+ case AREF_GROUND:
+ config_bits |=
+ MSeries_AI_Config_Channel_Type_Ground_Ref_Bits;
+ break;
+ case AREF_OTHER:
+ break;
+ }
+ config_bits |= MSeries_AI_Config_Channel_Bits(chan);
+ config_bits |=
+ MSeries_AI_Config_Bank_Bits(boardtype.reg_type, chan);
+ config_bits |= MSeries_AI_Config_Gain_Bits(range_code);
+ if (i == n_chan - 1)
+ config_bits |= MSeries_AI_Config_Last_Channel_Bit;
+ if (dither)
+ config_bits |= MSeries_AI_Config_Dither_Bit;
+ // don't use 2's complement encoding
+ config_bits |= MSeries_AI_Config_Polarity_Bit;
+ ni_writew(config_bits, M_Offset_AI_Config_FIFO_Data);
+ }
+ ni_prime_channelgain_list(dev);
+}
+
+/*
+ * Notes on the 6110 and 6111:
+ * These boards a slightly different than the rest of the series, since
+ * they have multiple A/D converters.
+ * From the driver side, the configuration memory is a
+ * little different.
+ * Configuration Memory Low:
+ * bits 15-9: same
+ * bit 8: unipolar/bipolar (should be 0 for bipolar)
+ * bits 0-3: gain. This is 4 bits instead of 3 for the other boards
+ * 1001 gain=0.1 (+/- 50)
+ * 1010 0.2
+ * 1011 0.1
+ * 0001 1
+ * 0010 2
+ * 0011 5
+ * 0100 10
+ * 0101 20
+ * 0110 50
+ * Configuration Memory High:
+ * bits 12-14: Channel Type
+ * 001 for differential
+ * 000 for calibration
+ * bit 11: coupling (this is not currently handled)
+ * 1 AC coupling
+ * 0 DC coupling
+ * bits 0-2: channel
+ * valid channels are 0-3
+ */
+static void ni_load_channelgain_list(struct comedi_device * dev, unsigned int n_chan,
+ unsigned int *list)
+{
+ unsigned int chan, range, aref;
+ unsigned int i;
+ unsigned int hi, lo;
+ unsigned offset;
+ unsigned int dither;
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ ni_m_series_load_channelgain_list(dev, n_chan, list);
+ return;
+ }
+ if (n_chan == 1 && (boardtype.reg_type != ni_reg_611x)
+ && (boardtype.reg_type != ni_reg_6143)) {
+ if (devpriv->changain_state
+ && devpriv->changain_spec == list[0]) {
+ // ready to go.
+ return;
+ }
+ devpriv->changain_state = 1;
+ devpriv->changain_spec = list[0];
+ } else {
+ devpriv->changain_state = 0;
+ }
+
+ devpriv->stc_writew(dev, 1, Configuration_Memory_Clear);
+
+ // Set up Calibration mode if required
+ if (boardtype.reg_type == ni_reg_6143) {
+ if ((list[0] & CR_ALT_SOURCE)
+ && !devpriv->ai_calib_source_enabled) {
+ // Strobe Relay enable bit
+ ni_writew(devpriv->
+ ai_calib_source |
+ Calibration_Channel_6143_RelayOn,
+ Calibration_Channel_6143);
+ ni_writew(devpriv->ai_calib_source,
+ Calibration_Channel_6143);
+ devpriv->ai_calib_source_enabled = 1;
+ msleep_interruptible(100); // Allow relays to change
+ } else if (!(list[0] & CR_ALT_SOURCE)
+ && devpriv->ai_calib_source_enabled) {
+ // Strobe Relay disable bit
+ ni_writew(devpriv->
+ ai_calib_source |
+ Calibration_Channel_6143_RelayOff,
+ Calibration_Channel_6143);
+ ni_writew(devpriv->ai_calib_source,
+ Calibration_Channel_6143);
+ devpriv->ai_calib_source_enabled = 0;
+ msleep_interruptible(100); // Allow relays to change
+ }
+ }
+
+ offset = 1 << (boardtype.adbits - 1);
+ for (i = 0; i < n_chan; i++) {
+ if ((boardtype.reg_type != ni_reg_6143)
+ && (list[i] & CR_ALT_SOURCE)) {
+ chan = devpriv->ai_calib_source;
+ } else {
+ chan = CR_CHAN(list[i]);
+ }
+ aref = CR_AREF(list[i]);
+ range = CR_RANGE(list[i]);
+ dither = ((list[i] & CR_ALT_FILTER) != 0);
+
+ /* fix the external/internal range differences */
+ range = ni_gainlkup[boardtype.gainlkup][range];
+ if (boardtype.reg_type == ni_reg_611x)
+ devpriv->ai_offset[i] = offset;
+ else
+ devpriv->ai_offset[i] = (range & 0x100) ? 0 : offset;
+
+ hi = 0;
+ if ((list[i] & CR_ALT_SOURCE)) {
+ if (boardtype.reg_type == ni_reg_611x)
+ ni_writew(CR_CHAN(list[i]) & 0x0003,
+ Calibration_Channel_Select_611x);
+ } else {
+ if (boardtype.reg_type == ni_reg_611x)
+ aref = AREF_DIFF;
+ else if (boardtype.reg_type == ni_reg_6143)
+ aref = AREF_OTHER;
+ switch (aref) {
+ case AREF_DIFF:
+ hi |= AI_DIFFERENTIAL;
+ break;
+ case AREF_COMMON:
+ hi |= AI_COMMON;
+ break;
+ case AREF_GROUND:
+ hi |= AI_GROUND;
+ break;
+ case AREF_OTHER:
+ break;
+ }
+ }
+ hi |= AI_CONFIG_CHANNEL(chan);
+
+ ni_writew(hi, Configuration_Memory_High);
+
+ if (boardtype.reg_type != ni_reg_6143) {
+ lo = range;
+ if (i == n_chan - 1)
+ lo |= AI_LAST_CHANNEL;
+ if (dither)
+ lo |= AI_DITHER;
+
+ ni_writew(lo, Configuration_Memory_Low);
+ }
+ }
+
+ /* prime the channel/gain list */
+ if ((boardtype.reg_type != ni_reg_611x)
+ && (boardtype.reg_type != ni_reg_6143)) {
+ ni_prime_channelgain_list(dev);
+ }
+}
+
+static int ni_ns_to_timer(const struct comedi_device * dev, unsigned nanosec,
+ int round_mode)
+{
+ int divider;
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (nanosec + devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (nanosec) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (nanosec + devpriv->clock_ns - 1) / devpriv->clock_ns;
+ break;
+ }
+ return divider - 1;
+}
+
+static unsigned ni_timer_to_ns(const struct comedi_device * dev, int timer)
+{
+ return devpriv->clock_ns * (timer + 1);
+}
+
+static unsigned ni_min_ai_scan_period_ns(struct comedi_device * dev,
+ unsigned num_channels)
+{
+ switch (boardtype.reg_type) {
+ case ni_reg_611x:
+ case ni_reg_6143:
+ // simultaneously-sampled inputs
+ return boardtype.ai_speed;
+ break;
+ default:
+ // multiplexed inputs
+ break;
+ };
+ return boardtype.ai_speed * num_channels;
+}
+
+static int ni_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int sources;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ if ((cmd->flags & CMDF_WRITE)) {
+ cmd->flags &= ~CMDF_WRITE;
+ }
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ sources = TRIG_TIMER | TRIG_EXT;
+ if ((boardtype.reg_type == ni_reg_611x)
+ || (boardtype.reg_type == ni_reg_6143))
+ sources |= TRIG_NOW;
+ cmd->convert_src &= sources;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->start_src != TRIG_NOW &&
+ cmd->start_src != TRIG_INT && cmd->start_src != TRIG_EXT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_OTHER)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->start_arg);
+
+ if (tmp > 16)
+ tmp = 16;
+ tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
+ if (cmd->start_arg != tmp) {
+ cmd->start_arg = tmp;
+ err++;
+ }
+ } else {
+ if (cmd->start_arg != 0) {
+ /* true for both TRIG_NOW and TRIG_INT */
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < ni_min_ai_scan_period_ns(dev,
+ cmd->chanlist_len)) {
+ cmd->scan_begin_arg =
+ ni_min_ai_scan_period_ns(dev,
+ cmd->chanlist_len);
+ err++;
+ }
+ if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) {
+ cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
+ err++;
+ }
+ } else if (cmd->scan_begin_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->scan_begin_arg);
+
+ if (tmp > 16)
+ tmp = 16;
+ tmp |= (cmd->scan_begin_arg & (CR_INVERT | CR_EDGE));
+ if (cmd->scan_begin_arg != tmp) {
+ cmd->scan_begin_arg = tmp;
+ err++;
+ }
+ } else { /* TRIG_OTHER */
+ if (cmd->scan_begin_arg) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if ((boardtype.reg_type == ni_reg_611x)
+ || (boardtype.reg_type == ni_reg_6143)) {
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ } else {
+ if (cmd->convert_arg < boardtype.ai_speed) {
+ cmd->convert_arg = boardtype.ai_speed;
+ err++;
+ }
+ if (cmd->convert_arg > devpriv->clock_ns * 0xffff) {
+ cmd->convert_arg = devpriv->clock_ns * 0xffff;
+ err++;
+ }
+ }
+ } else if (cmd->convert_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->convert_arg);
+
+ if (tmp > 16)
+ tmp = 16;
+ tmp |= (cmd->convert_arg & (CR_ALT_FILTER | CR_INVERT));
+ if (cmd->convert_arg != tmp) {
+ cmd->convert_arg = tmp;
+ err++;
+ }
+ } else if (cmd->convert_src == TRIG_NOW) {
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ unsigned int max_count = 0x01000000;
+
+ if (boardtype.reg_type == ni_reg_611x)
+ max_count -= num_adc_stages_611x;
+ if (cmd->stop_arg > max_count) {
+ cmd->stop_arg = max_count;
+ err++;
+ }
+ if (cmd->stop_arg < 1) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ cmd->scan_begin_arg =
+ ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+ cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK));
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if ((boardtype.reg_type != ni_reg_611x)
+ && (boardtype.reg_type != ni_reg_6143)) {
+ tmp = cmd->convert_arg;
+ cmd->convert_arg =
+ ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+ cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK));
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ int timer;
+ int mode1 = 0; /* mode1 is needed for both stop and convert */
+ int mode2 = 0;
+ int start_stop_select = 0;
+ unsigned int stop_count;
+ int interrupt_a_enable = 0;
+
+ MDPRINTK("ni_ai_cmd\n");
+ if (dev->irq == 0) {
+ comedi_error(dev, "cannot run command without an irq");
+ return -EIO;
+ }
+ ni_clear_ai_fifo(dev);
+
+ ni_load_channelgain_list(dev, cmd->chanlist_len, cmd->chanlist);
+
+ /* start configuration */
+ devpriv->stc_writew(dev, AI_Configuration_Start, Joint_Reset_Register);
+
+ /* disable analog triggering for now, since it
+ * interferes with the use of pfi0 */
+ devpriv->an_trig_etc_reg &= ~Analog_Trigger_Enable;
+ devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ case TRIG_NOW:
+ devpriv->stc_writew(dev, AI_START2_Select(0) |
+ AI_START1_Sync | AI_START1_Edge | AI_START1_Select(0),
+ AI_Trigger_Select_Register);
+ break;
+ case TRIG_EXT:
+ {
+ int chan = CR_CHAN(cmd->start_arg);
+ unsigned int bits = AI_START2_Select(0) |
+ AI_START1_Sync | AI_START1_Select(chan + 1);
+
+ if (cmd->start_arg & CR_INVERT)
+ bits |= AI_START1_Polarity;
+ if (cmd->start_arg & CR_EDGE)
+ bits |= AI_START1_Edge;
+ devpriv->stc_writew(dev, bits,
+ AI_Trigger_Select_Register);
+ break;
+ }
+ }
+
+ mode2 &= ~AI_Pre_Trigger;
+ mode2 &= ~AI_SC_Initial_Load_Source;
+ mode2 &= ~AI_SC_Reload_Mode;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ if (cmd->chanlist_len == 1 || (boardtype.reg_type == ni_reg_611x)
+ || (boardtype.reg_type == ni_reg_6143)) {
+ start_stop_select |= AI_STOP_Polarity;
+ start_stop_select |= AI_STOP_Select(31); // logic low
+ start_stop_select |= AI_STOP_Sync;
+ } else {
+ start_stop_select |= AI_STOP_Select(19); // ai configuration memory
+ }
+ devpriv->stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
+
+ devpriv->ai_cmd2 = 0;
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ stop_count = cmd->stop_arg - 1;
+
+ if (boardtype.reg_type == ni_reg_611x) {
+ // have to take 3 stage adc pipeline into account
+ stop_count += num_adc_stages_611x;
+ }
+ /* stage number of scans */
+ devpriv->stc_writel(dev, stop_count, AI_SC_Load_A_Registers);
+
+ mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Trigger_Once;
+ devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+ /* load SC (Scan Count) */
+ devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+
+ devpriv->ai_continuous = 0;
+ if (stop_count == 0) {
+ devpriv->ai_cmd2 |= AI_End_On_End_Of_Scan;
+ interrupt_a_enable |= AI_STOP_Interrupt_Enable;
+ // this is required to get the last sample for chanlist_len > 1, not sure why
+ if (cmd->chanlist_len > 1)
+ start_stop_select |=
+ AI_STOP_Polarity | AI_STOP_Edge;
+ }
+ break;
+ case TRIG_NONE:
+ /* stage number of scans */
+ devpriv->stc_writel(dev, 0, AI_SC_Load_A_Registers);
+
+ mode1 |= AI_Start_Stop | AI_Mode_1_Reserved | AI_Continuous;
+ devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+
+ /* load SC (Scan Count) */
+ devpriv->stc_writew(dev, AI_SC_Load, AI_Command_1_Register);
+
+ devpriv->ai_continuous = 1;
+
+ break;
+ }
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ /*
+ stop bits for non 611x boards
+ AI_SI_Special_Trigger_Delay=0
+ AI_Pre_Trigger=0
+ AI_START_STOP_Select_Register:
+ AI_START_Polarity=0 (?) rising edge
+ AI_START_Edge=1 edge triggered
+ AI_START_Sync=1 (?)
+ AI_START_Select=0 SI_TC
+ AI_STOP_Polarity=0 rising edge
+ AI_STOP_Edge=0 level
+ AI_STOP_Sync=1
+ AI_STOP_Select=19 external pin (configuration mem)
+ */
+ start_stop_select |= AI_START_Edge | AI_START_Sync;
+ devpriv->stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
+
+ mode2 |= AI_SI_Reload_Mode(0);
+ /* AI_SI_Initial_Load_Source=A */
+ mode2 &= ~AI_SI_Initial_Load_Source;
+ //mode2 |= AI_SC_Reload_Mode;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ /* load SI */
+ timer = ni_ns_to_timer(dev, cmd->scan_begin_arg,
+ TRIG_ROUND_NEAREST);
+ devpriv->stc_writel(dev, timer, AI_SI_Load_A_Registers);
+ devpriv->stc_writew(dev, AI_SI_Load, AI_Command_1_Register);
+ break;
+ case TRIG_EXT:
+ if (cmd->scan_begin_arg & CR_EDGE)
+ start_stop_select |= AI_START_Edge;
+ /* AI_START_Polarity==1 is falling edge */
+ if (cmd->scan_begin_arg & CR_INVERT)
+ start_stop_select |= AI_START_Polarity;
+ if (cmd->scan_begin_src != cmd->convert_src ||
+ (cmd->scan_begin_arg & ~CR_EDGE) !=
+ (cmd->convert_arg & ~CR_EDGE))
+ start_stop_select |= AI_START_Sync;
+ start_stop_select |=
+ AI_START_Select(1 + CR_CHAN(cmd->scan_begin_arg));
+ devpriv->stc_writew(dev, start_stop_select,
+ AI_START_STOP_Select_Register);
+ break;
+ }
+
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ case TRIG_NOW:
+ if (cmd->convert_arg == 0 || cmd->convert_src == TRIG_NOW)
+ timer = 1;
+ else
+ timer = ni_ns_to_timer(dev, cmd->convert_arg,
+ TRIG_ROUND_NEAREST);
+ devpriv->stc_writew(dev, 1, AI_SI2_Load_A_Register); /* 0,0 does not work. */
+ devpriv->stc_writew(dev, timer, AI_SI2_Load_B_Register);
+
+ /* AI_SI2_Reload_Mode = alternate */
+ /* AI_SI2_Initial_Load_Source = A */
+ mode2 &= ~AI_SI2_Initial_Load_Source;
+ mode2 |= AI_SI2_Reload_Mode;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ /* AI_SI2_Load */
+ devpriv->stc_writew(dev, AI_SI2_Load, AI_Command_1_Register);
+
+ mode2 |= AI_SI2_Reload_Mode; // alternate
+ mode2 |= AI_SI2_Initial_Load_Source; // B
+
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+ break;
+ case TRIG_EXT:
+ mode1 |= AI_CONVERT_Source_Select(1 + cmd->convert_arg);
+ if ((cmd->convert_arg & CR_INVERT) == 0)
+ mode1 |= AI_CONVERT_Source_Polarity;
+ devpriv->stc_writew(dev, mode1, AI_Mode_1_Register);
+
+ mode2 |= AI_Start_Stop_Gate_Enable | AI_SC_Gate_Enable;
+ devpriv->stc_writew(dev, mode2, AI_Mode_2_Register);
+
+ break;
+ }
+
+ if (dev->irq) {
+
+ /* interrupt on FIFO, errors, SC_TC */
+ interrupt_a_enable |= AI_Error_Interrupt_Enable |
+ AI_SC_TC_Interrupt_Enable;
+
+#ifndef PCIDMA
+ interrupt_a_enable |= AI_FIFO_Interrupt_Enable;
+#endif
+
+ if (cmd->flags & TRIG_WAKE_EOS
+ || (devpriv->ai_cmd2 & AI_End_On_End_Of_Scan)) {
+ /* wake on end-of-scan */
+ devpriv->aimode = AIMODE_SCAN;
+ } else {
+ devpriv->aimode = AIMODE_HALF_FULL;
+ }
+
+ switch (devpriv->aimode) {
+ case AIMODE_HALF_FULL:
+ /*generate FIFO interrupts and DMA requests on half-full */
+#ifdef PCIDMA
+ devpriv->stc_writew(dev, AI_FIFO_Mode_HF_to_E,
+ AI_Mode_3_Register);
+#else
+ devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
+#endif
+ break;
+ case AIMODE_SAMPLE:
+ /*generate FIFO interrupts on non-empty */
+ devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
+ break;
+ case AIMODE_SCAN:
+#ifdef PCIDMA
+ devpriv->stc_writew(dev, AI_FIFO_Mode_NE,
+ AI_Mode_3_Register);
+#else
+ devpriv->stc_writew(dev, AI_FIFO_Mode_HF,
+ AI_Mode_3_Register);
+#endif
+ interrupt_a_enable |= AI_STOP_Interrupt_Enable;
+ break;
+ default:
+ break;
+ }
+
+ devpriv->stc_writew(dev, AI_Error_Interrupt_Ack | AI_STOP_Interrupt_Ack | AI_START_Interrupt_Ack | AI_START2_Interrupt_Ack | AI_START1_Interrupt_Ack | AI_SC_TC_Interrupt_Ack | AI_SC_TC_Error_Confirm, Interrupt_A_Ack_Register); /* clear interrupts */
+
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ interrupt_a_enable, 1);
+
+ MDPRINTK("Interrupt_A_Enable_Register = 0x%04x\n",
+ devpriv->int_a_enable_reg);
+ } else {
+ /* interrupt on nothing */
+ ni_set_bits(dev, Interrupt_A_Enable_Register, ~0, 0);
+
+ /* XXX start polling if necessary */
+ MDPRINTK("interrupting on nothing\n");
+ }
+
+ /* end configuration */
+ devpriv->stc_writew(dev, AI_Configuration_End, Joint_Reset_Register);
+
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
+ break;
+ case TRIG_EXT:
+ /* XXX AI_SI_Arm? */
+ devpriv->stc_writew(dev,
+ AI_SI2_Arm | AI_SI_Arm | AI_DIV_Arm | AI_SC_Arm,
+ AI_Command_1_Register);
+ break;
+ }
+
+#ifdef PCIDMA
+ {
+ int retval = ni_ai_setup_MITE_dma(dev);
+ if (retval)
+ return retval;
+ }
+ //mite_dump_regs(devpriv->mite);
+#endif
+
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ /* AI_START1_Pulse */
+ devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
+ s->async->inttrig = NULL;
+ break;
+ case TRIG_EXT:
+ s->async->inttrig = NULL;
+ break;
+ case TRIG_INT:
+ s->async->inttrig = &ni_ai_inttrig;
+ break;
+ }
+
+ MDPRINTK("exit ni_ai_cmd\n");
+
+ return 0;
+}
+
+static int ni_ai_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != 0)
+ return -EINVAL;
+
+ devpriv->stc_writew(dev, AI_START1_Pulse | devpriv->ai_cmd2,
+ AI_Command_2_Register);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
+static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int ni_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n < 1)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_ANALOG_TRIG:
+ return ni_ai_config_analog_trig(dev, s, insn, data);
+ case INSN_CONFIG_ALT_SOURCE:
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ if (data[1] & ~(MSeries_AI_Bypass_Cal_Sel_Pos_Mask |
+ MSeries_AI_Bypass_Cal_Sel_Neg_Mask |
+ MSeries_AI_Bypass_Mode_Mux_Mask |
+ MSeries_AO_Bypass_AO_Cal_Sel_Mask)) {
+ return -EINVAL;
+ }
+ devpriv->ai_calib_source = data[1];
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ unsigned int calib_source;
+
+ calib_source = data[1] & 0xf;
+
+ if (calib_source > 0xF)
+ return -EINVAL;
+
+ devpriv->ai_calib_source = calib_source;
+ ni_writew(calib_source, Calibration_Channel_6143);
+ } else {
+ unsigned int calib_source;
+ unsigned int calib_source_adjust;
+
+ calib_source = data[1] & 0xf;
+ calib_source_adjust = (data[1] >> 4) & 0xff;
+
+ if (calib_source >= 8)
+ return -EINVAL;
+ devpriv->ai_calib_source = calib_source;
+ if (boardtype.reg_type == ni_reg_611x) {
+ ni_writeb(calib_source_adjust,
+ Cal_Gain_Select_611x);
+ }
+ }
+ return 2;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ni_ai_config_analog_trig(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int a, b, modebits;
+ int err = 0;
+
+ /* data[1] is flags
+ * data[2] is analog line
+ * data[3] is set level
+ * data[4] is reset level */
+ if (!boardtype.has_analog_trig)
+ return -EINVAL;
+ if ((data[1] & 0xffff0000) != COMEDI_EV_SCAN_BEGIN) {
+ data[1] &= (COMEDI_EV_SCAN_BEGIN | 0xffff);
+ err++;
+ }
+ if (data[2] >= boardtype.n_adchan) {
+ data[2] = boardtype.n_adchan - 1;
+ err++;
+ }
+ if (data[3] > 255) { /* a */
+ data[3] = 255;
+ err++;
+ }
+ if (data[4] > 255) { /* b */
+ data[4] = 255;
+ err++;
+ }
+ /*
+ * 00 ignore
+ * 01 set
+ * 10 reset
+ *
+ * modes:
+ * 1 level: +b- +a-
+ * high mode 00 00 01 10
+ * low mode 00 00 10 01
+ * 2 level: (a<b)
+ * hysteresis low mode 10 00 00 01
+ * hysteresis high mode 01 00 00 10
+ * middle mode 10 01 01 10
+ */
+
+ a = data[3];
+ b = data[4];
+ modebits = data[1] & 0xff;
+ if (modebits & 0xf0) {
+ /* two level mode */
+ if (b < a) {
+ /* swap order */
+ a = data[4];
+ b = data[3];
+ modebits =
+ ((data[1] & 0xf) << 4) | ((data[1] & 0xf0) >>
+ 4);
+ }
+ devpriv->atrig_low = a;
+ devpriv->atrig_high = b;
+ switch (modebits) {
+ case 0x81: /* low hysteresis mode */
+ devpriv->atrig_mode = 6;
+ break;
+ case 0x42: /* high hysteresis mode */
+ devpriv->atrig_mode = 3;
+ break;
+ case 0x96: /* middle window mode */
+ devpriv->atrig_mode = 2;
+ break;
+ default:
+ data[1] &= ~0xff;
+ err++;
+ }
+ } else {
+ /* one level mode */
+ if (b != 0) {
+ data[4] = 0;
+ err++;
+ }
+ switch (modebits) {
+ case 0x06: /* high window mode */
+ devpriv->atrig_high = a;
+ devpriv->atrig_mode = 0;
+ break;
+ case 0x09: /* low window mode */
+ devpriv->atrig_low = a;
+ devpriv->atrig_mode = 1;
+ break;
+ default:
+ data[1] &= ~0xff;
+ err++;
+ }
+ }
+ if (err)
+ return -EAGAIN;
+ return 5;
+}
+
+/* munge data from unsigned to 2's complement for analog output bipolar modes */
+static void ni_ao_munge(struct comedi_device * dev, struct comedi_subdevice * s,
+ void *data, unsigned int num_bytes, unsigned int chan_index)
+{
+ struct comedi_async *async = s->async;
+ unsigned int range;
+ unsigned int i;
+ unsigned int offset;
+ unsigned int length = num_bytes / sizeof(short);
+ short *array = data;
+
+ offset = 1 << (boardtype.aobits - 1);
+ for (i = 0; i < length; i++) {
+ range = CR_RANGE(async->cmd.chanlist[chan_index]);
+ if (boardtype.ao_unipolar == 0 || (range & 1) == 0)
+ array[i] -= offset;
+#ifdef PCIDMA
+ array[i] = cpu_to_le16(array[i]);
+#endif
+ chan_index++;
+ chan_index %= async->cmd.chanlist_len;
+ }
+}
+
+static int ni_m_series_ao_config_chanlist(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int chanspec[], unsigned int n_chans,
+ int timed)
+{
+ unsigned int range;
+ unsigned int chan;
+ unsigned int conf;
+ int i;
+ int invert = 0;
+
+ if(timed) {
+ for (i = 0; i < boardtype.n_aochan; ++i) {
+ devpriv->ao_conf[i] &= ~MSeries_AO_Update_Timed_Bit;
+ ni_writeb(devpriv->ao_conf[i], M_Offset_AO_Config_Bank(i));
+ ni_writeb(0xf, M_Offset_AO_Waveform_Order(i));
+ }
+ }
+ for (i = 0; i < n_chans; i++) {
+ const struct comedi_krange *krange;
+ chan = CR_CHAN(chanspec[i]);
+ range = CR_RANGE(chanspec[i]);
+ krange = s->range_table->range + range;
+ invert = 0;
+ conf = 0;
+ switch (krange->max - krange->min) {
+ case 20000000:
+ conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
+ ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ case 10000000:
+ conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
+ ni_writeb(0, M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ case 4000000:
+ conf |= MSeries_AO_DAC_Reference_10V_Internal_Bits;
+ ni_writeb(MSeries_Attenuate_x5_Bit,
+ M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ case 2000000:
+ conf |= MSeries_AO_DAC_Reference_5V_Internal_Bits;
+ ni_writeb(MSeries_Attenuate_x5_Bit,
+ M_Offset_AO_Reference_Attenuation(chan));
+ break;
+ default:
+ rt_printk("%s: bug! unhandled ao reference voltage\n",
+ __FUNCTION__);
+ break;
+ }
+ switch (krange->max + krange->min) {
+ case 0:
+ conf |= MSeries_AO_DAC_Offset_0V_Bits;
+ break;
+ case 10000000:
+ conf |= MSeries_AO_DAC_Offset_5V_Bits;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled ao offset voltage\n",
+ __FUNCTION__);
+ break;
+ }
+ if (timed)
+ conf |= MSeries_AO_Update_Timed_Bit;
+ ni_writeb(conf, M_Offset_AO_Config_Bank(chan));
+ devpriv->ao_conf[chan] = conf;
+ ni_writeb(i, M_Offset_AO_Waveform_Order(chan));
+ }
+ return invert;
+}
+
+static int ni_old_ao_config_chanlist(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int chanspec[], unsigned int n_chans)
+{
+ unsigned int range;
+ unsigned int chan;
+ unsigned int conf;
+ int i;
+ int invert = 0;
+
+ for (i = 0; i < n_chans; i++) {
+ chan = CR_CHAN(chanspec[i]);
+ range = CR_RANGE(chanspec[i]);
+ conf = AO_Channel(chan);
+
+ if (boardtype.ao_unipolar) {
+ if ((range & 1) == 0) {
+ conf |= AO_Bipolar;
+ invert = (1 << (boardtype.aobits - 1));
+ } else {
+ invert = 0;
+ }
+ if (range & 2)
+ conf |= AO_Ext_Ref;
+ } else {
+ conf |= AO_Bipolar;
+ invert = (1 << (boardtype.aobits - 1));
+ }
+
+ /* not all boards can deglitch, but this shouldn't hurt */
+ if (chanspec[i] & CR_DEGLITCH)
+ conf |= AO_Deglitch;
+
+ /* analog reference */
+ /* AREF_OTHER connects AO ground to AI ground, i think */
+ conf |= (CR_AREF(chanspec[i]) ==
+ AREF_OTHER) ? AO_Ground_Ref : 0;
+
+ ni_writew(conf, AO_Configuration);
+ devpriv->ao_conf[chan] = conf;
+ }
+ return invert;
+}
+
+static int ni_ao_config_chanlist(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int chanspec[], unsigned int n_chans, int timed)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return ni_m_series_ao_config_chanlist(dev, s, chanspec, n_chans,
+ timed);
+ else
+ return ni_old_ao_config_chanlist(dev, s, chanspec, n_chans);
+}
+static int ni_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->ao[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int ni_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int invert;
+
+ invert = ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
+
+ devpriv->ao[chan] = data[0];
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ ni_writew(data[0], M_Offset_DAC_Direct_Data(chan));
+ } else
+ ni_writew(data[0] ^ invert,
+ (chan) ? DAC1_Direct_Data : DAC0_Direct_Data);
+
+ return 1;
+}
+
+static int ni_ao_insn_write_671x(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ unsigned int invert;
+
+ ao_win_out(1 << chan, AO_Immediate_671x);
+ invert = 1 << (boardtype.aobits - 1);
+
+ ni_ao_config_chanlist(dev, s, &insn->chanspec, 1, 0);
+
+ devpriv->ao[chan] = data[0];
+ ao_win_out(data[0] ^ invert, DACx_Direct_Data_671x(chan));
+
+ return 1;
+}
+
+static int ni_ao_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_GET_HARDWARE_BUFFER_SIZE:
+ switch(data[1])
+ {
+ case COMEDI_OUTPUT:
+ data[2] = 1 + boardtype.ao_fifo_depth * sizeof(short);
+ if(devpriv->mite) data[2] += devpriv->mite->fifo_size;
+ break;
+ case COMEDI_INPUT:
+ data[2] = 0;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int ni_ao_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ int ret;
+ int interrupt_b_bits;
+ int i;
+ static const int timeout = 1000;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ /* Null trig at beginning prevent ao start trigger from executing more than
+ once per command (and doing things like trying to allocate the ao dma channel
+ multiple times) */
+ s->async->inttrig = NULL;
+
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_FIFO_Interrupt_Enable | AO_Error_Interrupt_Enable, 0);
+ interrupt_b_bits = AO_Error_Interrupt_Enable;
+#ifdef PCIDMA
+ devpriv->stc_writew(dev, 1, DAC_FIFO_Clear);
+ if (boardtype.reg_type & ni_reg_6xxx_mask)
+ ni_ao_win_outl(dev, 0x6, AO_FIFO_Offset_Load_611x);
+ ret = ni_ao_setup_MITE_dma(dev);
+ if (ret)
+ return ret;
+ ret = ni_ao_wait_for_dma_load(dev);
+ if (ret < 0)
+ return ret;
+#else
+ ret = ni_ao_prep_fifo(dev, s);
+ if (ret == 0)
+ return -EPIPE;
+
+ interrupt_b_bits |= AO_FIFO_Interrupt_Enable;
+#endif
+
+ devpriv->stc_writew(dev, devpriv->ao_mode3 | AO_Not_An_UPDATE,
+ AO_Mode_3_Register);
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ /* wait for DACs to be loaded */
+ for (i = 0; i < timeout; i++) {
+ comedi_udelay(1);
+ if ((devpriv->stc_readw(dev,
+ Joint_Status_2_Register) &
+ AO_TMRDACWRs_In_Progress_St) == 0)
+ break;
+ }
+ if (i == timeout) {
+ comedi_error(dev,
+ "timed out waiting for AO_TMRDACWRs_In_Progress_St to clear");
+ return -EIO;
+ }
+ // stc manual says we are need to clear error interrupt after AO_TMRDACWRs_In_Progress_St clears
+ devpriv->stc_writew(dev, AO_Error_Interrupt_Ack,
+ Interrupt_B_Ack_Register);
+
+ ni_set_bits(dev, Interrupt_B_Enable_Register, interrupt_b_bits, 1);
+
+ devpriv->stc_writew(dev,
+ devpriv->
+ ao_cmd1 | AO_UI_Arm | AO_UC_Arm | AO_BC_Arm |
+ AO_DAC1_Update_Mode | AO_DAC0_Update_Mode,
+ AO_Command_1_Register);
+
+ devpriv->stc_writew(dev, devpriv->ao_cmd2 | AO_START1_Pulse,
+ AO_Command_2_Register);
+
+ return 0;
+}
+
+static int ni_ao_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ int bits;
+ int i;
+ unsigned trigvar;
+
+ if (dev->irq == 0) {
+ comedi_error(dev, "cannot run command without an irq");
+ return -EIO;
+ }
+
+ devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+
+ devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ ao_win_out(CLEAR_WG, AO_Misc_611x);
+
+ bits = 0;
+ for (i = 0; i < cmd->chanlist_len; i++) {
+ int chan;
+
+ chan = CR_CHAN(cmd->chanlist[i]);
+ bits |= 1 << chan;
+ ao_win_out(chan, AO_Waveform_Generation_611x);
+ }
+ ao_win_out(bits, AO_Timed_611x);
+ }
+
+ ni_ao_config_chanlist(dev, s, cmd->chanlist, cmd->chanlist_len, 1);
+
+ if (cmd->stop_src == TRIG_NONE) {
+ devpriv->ao_mode1 |= AO_Continuous;
+ devpriv->ao_mode1 &= ~AO_Trigger_Once;
+ } else {
+ devpriv->ao_mode1 &= ~AO_Continuous;
+ devpriv->ao_mode1 |= AO_Trigger_Once;
+ }
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ case TRIG_NOW:
+ devpriv->ao_trigger_select &=
+ ~(AO_START1_Polarity | AO_START1_Select(-1));
+ devpriv->ao_trigger_select |= AO_START1_Edge | AO_START1_Sync;
+ devpriv->stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
+ break;
+ case TRIG_EXT:
+ devpriv->ao_trigger_select = AO_START1_Select(CR_CHAN(cmd->start_arg)+1);
+ if (cmd->start_arg & CR_INVERT)
+ devpriv->ao_trigger_select |= AO_START1_Polarity; // 0=active high, 1=active low. see daq-stc 3-24 (p186)
+ if (cmd->start_arg & CR_EDGE)
+ devpriv->ao_trigger_select |= AO_START1_Edge; // 0=edge detection disabled, 1=enabled
+ devpriv->stc_writew(dev, devpriv->ao_trigger_select, AO_Trigger_Select_Register);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ devpriv->ao_mode3 &= ~AO_Trigger_Length;
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ devpriv->ao_mode2 &= ~AO_BC_Initial_Load_Source;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ if (cmd->stop_src == TRIG_NONE) {
+ devpriv->stc_writel(dev, 0xffffff, AO_BC_Load_A_Register);
+ } else {
+ devpriv->stc_writel(dev, 0, AO_BC_Load_A_Register);
+ }
+ devpriv->stc_writew(dev, AO_BC_Load, AO_Command_1_Register);
+ devpriv->ao_mode2 &= ~AO_UC_Initial_Load_Source;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ if(boardtype.reg_type & ni_reg_m_series_mask)
+ {
+ // this is how the NI example code does it for m-series boards, verified correct with 6259
+ devpriv->stc_writel(dev, cmd->stop_arg - 1, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ }else
+ {
+ devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, cmd->stop_arg - 1,
+ AO_UC_Load_A_Register);
+ }
+ break;
+ case TRIG_NONE:
+ devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, 0xffffff, AO_UC_Load_A_Register);
+ break;
+ default:
+ devpriv->stc_writel(dev, 0, AO_UC_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UC_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, cmd->stop_arg, AO_UC_Load_A_Register);
+ }
+
+ devpriv->ao_mode1 &=
+ ~(AO_UI_Source_Select(0x1f) | AO_UI_Source_Polarity |
+ AO_UPDATE_Source_Select(0x1f) | AO_UPDATE_Source_Polarity);
+ switch (cmd->scan_begin_src) {
+ case TRIG_TIMER:
+ devpriv->ao_cmd2 &= ~AO_BC_Gate_Enable;
+ trigvar =
+ ni_ns_to_timer(dev, cmd->scan_begin_arg,
+ TRIG_ROUND_NEAREST);
+ devpriv->stc_writel(dev, 1, AO_UI_Load_A_Register);
+ devpriv->stc_writew(dev, AO_UI_Load, AO_Command_1_Register);
+ devpriv->stc_writel(dev, trigvar, AO_UI_Load_A_Register);
+ break;
+ case TRIG_EXT:
+ devpriv->ao_mode1 |=
+ AO_UPDATE_Source_Select(cmd->scan_begin_arg);
+ if (cmd->scan_begin_arg & CR_INVERT)
+ devpriv->ao_mode1 |= AO_UPDATE_Source_Polarity;
+ devpriv->ao_cmd2 |= AO_BC_Gate_Enable;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ devpriv->ao_mode2 &=
+ ~(AO_UI_Reload_Mode(3) | AO_UI_Initial_Load_Source);
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+
+ if (cmd->scan_end_arg > 1) {
+ devpriv->ao_mode1 |= AO_Multiple_Channels;
+ devpriv->stc_writew(dev,
+ AO_Number_Of_Channels(cmd->scan_end_arg -
+ 1) |
+ AO_UPDATE_Output_Select
+ (AO_Update_Output_High_Z),
+ AO_Output_Control_Register);
+ } else {
+ unsigned bits;
+ devpriv->ao_mode1 &= ~AO_Multiple_Channels;
+ bits = AO_UPDATE_Output_Select(AO_Update_Output_High_Z);
+ if (boardtype.reg_type & (ni_reg_m_series_mask | ni_reg_6xxx_mask)) {
+ bits |= AO_Number_Of_Channels(0);
+ } else {
+ bits |= AO_Number_Of_Channels(CR_CHAN(cmd->
+ chanlist[0]));
+ }
+ devpriv->stc_writew(dev, bits,
+ AO_Output_Control_Register);
+ }
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+
+ devpriv->stc_writew(dev, AO_DAC0_Update_Mode | AO_DAC1_Update_Mode,
+ AO_Command_1_Register);
+
+ devpriv->ao_mode3 |= AO_Stop_On_Overrun_Error;
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+
+ devpriv->ao_mode2 &= ~AO_FIFO_Mode_Mask;
+#ifdef PCIDMA
+ devpriv->ao_mode2 |= AO_FIFO_Mode_HF_to_F;
+#else
+ devpriv->ao_mode2 |= AO_FIFO_Mode_HF;
+#endif
+ devpriv->ao_mode2 &= ~AO_FIFO_Retransmit_Enable;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+
+ bits = AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+ AO_TMRDACWR_Pulse_Width;
+ if (boardtype.ao_fifo_depth)
+ bits |= AO_FIFO_Enable;
+ else
+ bits |= AO_DMA_PIO_Control;
+#if 0
+ /* F Hess: windows driver does not set AO_Number_Of_DAC_Packages bit for 6281,
+ verified with bus analyzer. */
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ bits |= AO_Number_Of_DAC_Packages;
+#endif
+ devpriv->stc_writew(dev, bits, AO_Personal_Register);
+ // enable sending of ao dma requests
+ devpriv->stc_writew(dev, AO_AOFREQ_Enable, AO_Start_Select_Register);
+
+ devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->stc_writew(dev, AO_BC_TC_Interrupt_Ack,
+ Interrupt_B_Ack_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ AO_BC_TC_Interrupt_Enable, 1);
+ }
+
+ s->async->inttrig = &ni_ao_inttrig;
+
+ return 0;
+}
+
+static int ni_ao_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ if ((cmd->flags & CMDF_WRITE) == 0) {
+ cmd->flags |= CMDF_WRITE;
+ }
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_INT | TRIG_EXT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_src == TRIG_EXT) {
+ /* external trigger */
+ unsigned int tmp = CR_CHAN(cmd->start_arg);
+
+ if (tmp > 18)
+ tmp = 18;
+ tmp |= (cmd->start_arg & (CR_INVERT | CR_EDGE));
+ if (cmd->start_arg != tmp) {
+ cmd->start_arg = tmp;
+ err++;
+ }
+ } else {
+ if (cmd->start_arg != 0) {
+ /* true for both TRIG_NOW and TRIG_INT */
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < boardtype.ao_speed) {
+ cmd->scan_begin_arg = boardtype.ao_speed;
+ err++;
+ }
+ if (cmd->scan_begin_arg > devpriv->clock_ns * 0xffffff) { /* XXX check */
+ cmd->scan_begin_arg = devpriv->clock_ns * 0xffffff;
+ err++;
+ }
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) { /* XXX check */
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ cmd->scan_begin_arg =
+ ni_timer_to_ns(dev, ni_ns_to_timer(dev,
+ cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK));
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (err)
+ return 4;
+
+ /* step 5: fix up chanlist */
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int ni_ao_reset(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ //devpriv->ao0p=0x0000;
+ //ni_writew(devpriv->ao0p,AO_Configuration);
+
+ //devpriv->ao1p=AO_Channel(1);
+ //ni_writew(devpriv->ao1p,AO_Configuration);
+
+ ni_release_ao_mite_channel(dev);
+
+ devpriv->stc_writew(dev, AO_Configuration_Start, Joint_Reset_Register);
+ devpriv->stc_writew(dev, AO_Disarm, AO_Command_1_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register, ~0, 0);
+ devpriv->stc_writew(dev, AO_BC_Source_Select, AO_Personal_Register);
+ devpriv->stc_writew(dev, 0x3f98, Interrupt_B_Ack_Register);
+ devpriv->stc_writew(dev, AO_BC_Source_Select | AO_UPDATE_Pulse_Width |
+ AO_TMRDACWR_Pulse_Width, AO_Personal_Register);
+ devpriv->stc_writew(dev, 0, AO_Output_Control_Register);
+ devpriv->stc_writew(dev, 0, AO_Start_Select_Register);
+ devpriv->ao_cmd1 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_cmd1, AO_Command_1_Register);
+ devpriv->ao_cmd2 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_cmd2, AO_Command_2_Register);
+ devpriv->ao_mode1 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_mode1, AO_Mode_1_Register);
+ devpriv->ao_mode2 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_mode2, AO_Mode_2_Register);
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ devpriv->ao_mode3 = AO_Last_Gate_Disable;
+ else
+ devpriv->ao_mode3 = 0;
+ devpriv->stc_writew(dev, devpriv->ao_mode3, AO_Mode_3_Register);
+ devpriv->ao_trigger_select = 0;
+ devpriv->stc_writew(dev, devpriv->ao_trigger_select,
+ AO_Trigger_Select_Register);
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ unsigned immediate_bits = 0;
+ unsigned i;
+ for(i = 0; i < s->n_chan; ++i)
+ {
+ immediate_bits |= 1 << i;
+ }
+ ao_win_out(immediate_bits, AO_Immediate_671x);
+ ao_win_out(CLEAR_WG, AO_Misc_611x);
+ }
+ devpriv->stc_writew(dev, AO_Configuration_End, Joint_Reset_Register);
+
+ return 0;
+}
+
+// digital io
+
+static int ni_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_dio_insn_config() chan=%d io=%d\n",
+ CR_CHAN(insn->chanspec), data[0]);
+#endif
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ devpriv->dio_control &= ~DIO_Pins_Dir_Mask;
+ devpriv->dio_control |= DIO_Pins_Dir(s->io_bits);
+ devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+
+ return 1;
+}
+
+static int ni_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0], data[1]);
+#endif
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ /* Perform check to make sure we're not using the
+ serial part of the dio */
+ if ((data[0] & (DIO_SDIN | DIO_SDOUT))
+ && devpriv->serial_interval_ns)
+ return -EBUSY;
+
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ devpriv->dio_output &= ~DIO_Parallel_Data_Mask;
+ devpriv->dio_output |= DIO_Parallel_Data_Out(s->state);
+ devpriv->stc_writew(dev, devpriv->dio_output,
+ DIO_Output_Register);
+ }
+ data[1] = devpriv->stc_readw(dev, DIO_Parallel_Input_Register);
+
+ return 2;
+}
+
+static int ni_m_series_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_m_series_dio_insn_config() chan=%d io=%d\n",
+ CR_CHAN(insn->chanspec), data[0]);
+#endif
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ ni_writel(s->io_bits, M_Offset_DIO_Direction);
+
+ return 1;
+}
+
+static int ni_m_series_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+#ifdef DEBUG_DIO
+ rt_printk("ni_m_series_dio_insn_bits() mask=0x%x bits=0x%x\n", data[0],
+ data[1]);
+#endif
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ ni_writel(s->state, M_Offset_Static_Digital_Output);
+ }
+ data[1] = ni_readl(M_Offset_Static_Digital_Input);
+
+ return 2;
+}
+
+static int ni_cdio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int sources;
+ unsigned i;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ sources = TRIG_INT;
+ cmd->start_src &= sources;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique... */
+
+ if (cmd->start_src != TRIG_INT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_NONE)
+ err++;
+ /* ... and mutually compatible */
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_src == TRIG_INT) {
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ tmp = cmd->scan_begin_arg;
+ tmp &= CR_PACK_FLAGS(CDO_Sample_Source_Select_Mask, 0, 0,
+ CR_INVERT);
+ if (tmp != cmd->scan_begin_arg) {
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_NOW) {
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ /* step 5: check chanlist */
+
+ for (i = 0; i < cmd->chanlist_len; ++i) {
+ if (cmd->chanlist[i] != i)
+ err = 1;
+ }
+
+ if (err)
+ return 5;
+
+ return 0;
+}
+
+static int ni_cdio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ const struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned cdo_mode_bits = CDO_FIFO_Mode_Bit | CDO_Halt_On_Error_Bit;
+ int retval;
+
+ ni_writel(CDO_Reset_Bit, M_Offset_CDIO_Command);
+ switch (cmd->scan_begin_src) {
+ case TRIG_EXT:
+ cdo_mode_bits |=
+ CR_CHAN(cmd->
+ scan_begin_arg) & CDO_Sample_Source_Select_Mask;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (cmd->scan_begin_arg & CR_INVERT)
+ cdo_mode_bits |= CDO_Polarity_Bit;
+ ni_writel(cdo_mode_bits, M_Offset_CDO_Mode);
+ if (s->io_bits) {
+ ni_writel(s->state, M_Offset_CDO_FIFO_Data);
+ ni_writel(CDO_SW_Update_Bit, M_Offset_CDIO_Command);
+ ni_writel(s->io_bits, M_Offset_CDO_Mask_Enable);
+ } else {
+ comedi_error(dev,
+ "attempted to run digital output command with no lines configured as outputs");
+ return -EIO;
+ }
+ retval = ni_request_cdo_mite_channel(dev);
+ if (retval < 0) {
+ return retval;
+ }
+ s->async->inttrig = &ni_cdo_inttrig;
+ return 0;
+}
+
+static int ni_cdo_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+#ifdef PCIDMA
+ unsigned long flags;
+#endif
+ int retval = 0;
+ unsigned i;
+ const unsigned timeout = 100;
+
+ s->async->inttrig = NULL;
+
+ /* read alloc the entire buffer */
+ comedi_buf_read_alloc(s->async, s->async->prealloc_bufsz);
+
+#ifdef PCIDMA
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->cdo_mite_chan) {
+ mite_prep_dma(devpriv->cdo_mite_chan, 32, 32);
+ mite_dma_arm(devpriv->cdo_mite_chan);
+ } else {
+ comedi_error(dev, "BUG: no cdo mite channel?");
+ retval = -EIO;
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ if (retval < 0)
+ return retval;
+#endif
+// XXX not sure what interrupt C group does
+// ni_writeb(Interrupt_Group_C_Enable_Bit, M_Offset_Interrupt_C_Enable);
+ //wait for dma to fill output fifo
+ for (i = 0; i < timeout; ++i) {
+ if (ni_readl(M_Offset_CDIO_Status) & CDO_FIFO_Full_Bit)
+ break;
+ comedi_udelay(10);
+ }
+ if (i == timeout) {
+ comedi_error(dev, "dma failed to fill cdo fifo!");
+ ni_cdio_cancel(dev, s);
+ return -EIO;
+ }
+ ni_writel(CDO_Arm_Bit | CDO_Error_Interrupt_Enable_Set_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Set_Bit, M_Offset_CDIO_Command);
+ return retval;
+}
+
+static int ni_cdio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ ni_writel(CDO_Disarm_Bit | CDO_Error_Interrupt_Enable_Clear_Bit |
+ CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit |
+ CDO_FIFO_Request_Interrupt_Enable_Clear_Bit,
+ M_Offset_CDIO_Command);
+// XXX not sure what interrupt C group does
+// ni_writeb(0, M_Offset_Interrupt_C_Enable);
+ ni_writel(0, M_Offset_CDO_Mask_Enable);
+ ni_release_cdo_mite_channel(dev);
+ return 0;
+}
+
+static void handle_cdio_interrupt(struct comedi_device * dev)
+{
+ unsigned cdio_status;
+ struct comedi_subdevice *s = dev->subdevices + NI_DIO_SUBDEV;
+#ifdef PCIDMA
+ unsigned long flags;
+#endif
+
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ return;
+ }
+#ifdef PCIDMA
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->cdo_mite_chan) {
+ unsigned cdo_mite_status =
+ mite_get_status(devpriv->cdo_mite_chan);
+ if (cdo_mite_status & CHSR_LINKC) {
+ writel(CHOR_CLRLC,
+ devpriv->mite->mite_io_addr +
+ MITE_CHOR(devpriv->cdo_mite_chan->channel));
+ }
+ mite_sync_output_dma(devpriv->cdo_mite_chan, s->async);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+#endif
+
+ cdio_status = ni_readl(M_Offset_CDIO_Status);
+ if (cdio_status & (CDO_Overrun_Bit | CDO_Underflow_Bit)) {
+// rt_printk("cdio error: statux=0x%x\n", cdio_status);
+ ni_writel(CDO_Error_Interrupt_Confirm_Bit, M_Offset_CDIO_Command); // XXX just guessing this is needed and does something useful
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ if (cdio_status & CDO_FIFO_Empty_Bit) {
+// rt_printk("cdio fifo empty\n");
+ ni_writel(CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit,
+ M_Offset_CDIO_Command);
+// s->async->events |= COMEDI_CB_EOA;
+ }
+ ni_event(dev, s);
+}
+
+static int ni_serial_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int err = insn->n;
+ unsigned char byte_out, byte_in = 0;
+
+ if (insn->n != 2)
+ return -EINVAL;
+
+ switch (data[0]) {
+ case INSN_CONFIG_SERIAL_CLOCK:
+
+#ifdef DEBUG_DIO
+ rt_printk("SPI serial clock Config cd\n", data[1]);
+#endif
+ devpriv->serial_hw_mode = 1;
+ devpriv->dio_control |= DIO_HW_Serial_Enable;
+
+ if (data[1] == SERIAL_DISABLED) {
+ devpriv->serial_hw_mode = 0;
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ data[1] = SERIAL_DISABLED;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_600NS) {
+ /* Warning: this clock speed is too fast to reliably
+ control SCXI. */
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase;
+ devpriv->clock_and_fout &= ~DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_600NS;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_1_2US) {
+ devpriv->dio_control &= ~DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ data[1] = SERIAL_1_2US;
+ devpriv->serial_interval_ns = data[1];
+ } else if (data[1] <= SERIAL_10US) {
+ devpriv->dio_control |= DIO_HW_Serial_Timebase;
+ devpriv->clock_and_fout |= Slow_Internal_Timebase |
+ DIO_Serial_Out_Divide_By_2;
+ /* Note: DIO_Serial_Out_Divide_By_2 only affects
+ 600ns/1.2us. If you turn divide_by_2 off with the
+ slow clock, you will still get 10us, except then
+ all your delays are wrong. */
+ data[1] = SERIAL_10US;
+ devpriv->serial_interval_ns = data[1];
+ } else {
+ devpriv->dio_control &= ~(DIO_HW_Serial_Enable |
+ DIO_Software_Serial_Control);
+ devpriv->serial_hw_mode = 0;
+ data[1] = (data[1] / 1000) * 1000;
+ devpriv->serial_interval_ns = data[1];
+ }
+
+ devpriv->stc_writew(dev, devpriv->dio_control,
+ DIO_Control_Register);
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return 1;
+
+ break;
+
+ case INSN_CONFIG_BIDIRECTIONAL_DATA:
+
+ if (devpriv->serial_interval_ns == 0) {
+ return -EINVAL;
+ }
+
+ byte_out = data[1] & 0xFF;
+
+ if (devpriv->serial_hw_mode) {
+ err = ni_serial_hw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else if (devpriv->serial_interval_ns > 0) {
+ err = ni_serial_sw_readwrite8(dev, s, byte_out,
+ &byte_in);
+ } else {
+ rt_printk("ni_serial_insn_config: serial disabled!\n");
+ return -EINVAL;
+ }
+ if (err < 0)
+ return err;
+ data[1] = byte_in & 0xFF;
+ return insn->n;
+
+ break;
+ default:
+ return -EINVAL;
+ }
+
+}
+
+static int ni_serial_hw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in)
+{
+ unsigned int status1;
+ int err = 0, count = 20;
+
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_hw_readwrite8: outputting 0x%x\n", data_out);
+#endif
+
+ devpriv->dio_output &= ~DIO_Serial_Data_Mask;
+ devpriv->dio_output |= DIO_Serial_Data_Out(data_out);
+ devpriv->stc_writew(dev, devpriv->dio_output, DIO_Output_Register);
+
+ status1 = devpriv->stc_readw(dev, Joint_Status_1_Register);
+ if (status1 & DIO_Serial_IO_In_Progress_St) {
+ err = -EBUSY;
+ goto Error;
+ }
+
+ devpriv->dio_control |= DIO_HW_Serial_Start;
+ devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+ devpriv->dio_control &= ~DIO_HW_Serial_Start;
+
+ /* Wait until STC says we're done, but don't loop infinitely. */
+ while ((status1 =
+ devpriv->stc_readw(dev,
+ Joint_Status_1_Register)) &
+ DIO_Serial_IO_In_Progress_St) {
+ /* Delay one bit per loop */
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+ if (--count < 0) {
+ rt_printk
+ ("ni_serial_hw_readwrite8: SPI serial I/O didn't finish in time!\n");
+ err = -ETIME;
+ goto Error;
+ }
+ }
+
+ /* Delay for last bit. This delay is absolutely necessary, because
+ DIO_Serial_IO_In_Progress_St goes high one bit too early. */
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+
+ if (data_in != NULL) {
+ *data_in = devpriv->stc_readw(dev, DIO_Serial_Input_Register);
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_hw_readwrite8: inputted 0x%x\n", *data_in);
+#endif
+ }
+
+ Error:
+ devpriv->stc_writew(dev, devpriv->dio_control, DIO_Control_Register);
+
+ return err;
+}
+
+static int ni_serial_sw_readwrite8(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned char data_out, unsigned char *data_in)
+{
+ unsigned char mask, input = 0;
+
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_sw_readwrite8: outputting 0x%x\n", data_out);
+#endif
+
+ /* Wait for one bit before transfer */
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 1000);
+
+ for (mask = 0x80; mask; mask >>= 1) {
+ /* Output current bit; note that we cannot touch s->state
+ because it is a per-subdevice field, and serial is
+ a separate subdevice from DIO. */
+ devpriv->dio_output &= ~DIO_SDOUT;
+ if (data_out & mask) {
+ devpriv->dio_output |= DIO_SDOUT;
+ }
+ devpriv->stc_writew(dev, devpriv->dio_output,
+ DIO_Output_Register);
+
+ /* Assert SDCLK (active low, inverted), wait for half of
+ the delay, deassert SDCLK, and wait for the other half. */
+ devpriv->dio_control |= DIO_Software_Serial_Control;
+ devpriv->stc_writew(dev, devpriv->dio_control,
+ DIO_Control_Register);
+
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
+
+ devpriv->dio_control &= ~DIO_Software_Serial_Control;
+ devpriv->stc_writew(dev, devpriv->dio_control,
+ DIO_Control_Register);
+
+ comedi_udelay((devpriv->serial_interval_ns + 999) / 2000);
+
+ /* Input current bit */
+ if (devpriv->stc_readw(dev,
+ DIO_Parallel_Input_Register) & DIO_SDIN) {
+/* rt_printk("DIO_P_I_R: 0x%x\n", devpriv->stc_readw(dev, DIO_Parallel_Input_Register)); */
+ input |= mask;
+ }
+ }
+#ifdef DEBUG_DIO
+ rt_printk("ni_serial_sw_readwrite8: inputted 0x%x\n", input);
+#endif
+ if (data_in)
+ *data_in = input;
+
+ return 0;
+}
+
+static void mio_common_detach(struct comedi_device * dev)
+{
+ if (dev->private) {
+ if (devpriv->counter_dev) {
+ ni_gpct_device_destroy(devpriv->counter_dev);
+ }
+ }
+ if (dev->subdevices && boardtype.has_8255)
+ subdev_8255_cleanup(dev, dev->subdevices + NI_8255_DIO_SUBDEV);
+}
+
+static void init_ao_67xx(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int i;
+
+ for (i = 0; i < s->n_chan; i++)
+ {
+ ni_ao_win_outw(dev, AO_Channel(i) | 0x0,
+ AO_Configuration_2_67xx);
+ }
+ ao_win_out(0x0, AO_Later_Single_Point_Updates);
+}
+
+static unsigned ni_gpct_to_stc_register(enum ni_gpct_register reg)
+{
+ unsigned stc_register;
+ switch (reg) {
+ case NITIO_G0_Autoincrement_Reg:
+ stc_register = G_Autoincrement_Register(0);
+ break;
+ case NITIO_G1_Autoincrement_Reg:
+ stc_register = G_Autoincrement_Register(1);
+ break;
+ case NITIO_G0_Command_Reg:
+ stc_register = G_Command_Register(0);
+ break;
+ case NITIO_G1_Command_Reg:
+ stc_register = G_Command_Register(1);
+ break;
+ case NITIO_G0_HW_Save_Reg:
+ stc_register = G_HW_Save_Register(0);
+ break;
+ case NITIO_G1_HW_Save_Reg:
+ stc_register = G_HW_Save_Register(1);
+ break;
+ case NITIO_G0_SW_Save_Reg:
+ stc_register = G_Save_Register(0);
+ break;
+ case NITIO_G1_SW_Save_Reg:
+ stc_register = G_Save_Register(1);
+ break;
+ case NITIO_G0_Mode_Reg:
+ stc_register = G_Mode_Register(0);
+ break;
+ case NITIO_G1_Mode_Reg:
+ stc_register = G_Mode_Register(1);
+ break;
+ case NITIO_G0_LoadA_Reg:
+ stc_register = G_Load_A_Register(0);
+ break;
+ case NITIO_G1_LoadA_Reg:
+ stc_register = G_Load_A_Register(1);
+ break;
+ case NITIO_G0_LoadB_Reg:
+ stc_register = G_Load_B_Register(0);
+ break;
+ case NITIO_G1_LoadB_Reg:
+ stc_register = G_Load_B_Register(1);
+ break;
+ case NITIO_G0_Input_Select_Reg:
+ stc_register = G_Input_Select_Register(0);
+ break;
+ case NITIO_G1_Input_Select_Reg:
+ stc_register = G_Input_Select_Register(1);
+ break;
+ case NITIO_G01_Status_Reg:
+ stc_register = G_Status_Register;
+ break;
+ case NITIO_G01_Joint_Reset_Reg:
+ stc_register = Joint_Reset_Register;
+ break;
+ case NITIO_G01_Joint_Status1_Reg:
+ stc_register = Joint_Status_1_Register;
+ break;
+ case NITIO_G01_Joint_Status2_Reg:
+ stc_register = Joint_Status_2_Register;
+ break;
+ case NITIO_G0_Interrupt_Acknowledge_Reg:
+ stc_register = Interrupt_A_Ack_Register;
+ break;
+ case NITIO_G1_Interrupt_Acknowledge_Reg:
+ stc_register = Interrupt_B_Ack_Register;
+ break;
+ case NITIO_G0_Status_Reg:
+ stc_register = AI_Status_1_Register;
+ break;
+ case NITIO_G1_Status_Reg:
+ stc_register = AO_Status_1_Register;
+ break;
+ case NITIO_G0_Interrupt_Enable_Reg:
+ stc_register = Interrupt_A_Enable_Register;
+ break;
+ case NITIO_G1_Interrupt_Enable_Reg:
+ stc_register = Interrupt_B_Enable_Register;
+ break;
+ default:
+ rt_printk("%s: unhandled register 0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return stc_register;
+}
+
+static void ni_gpct_write_register(struct ni_gpct *counter, unsigned bits,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ unsigned stc_register;
+ /* bits in the join reset register which are relevant to counters */
+ static const unsigned gpct_joint_reset_mask = G0_Reset | G1_Reset;
+ static const unsigned gpct_interrupt_a_enable_mask =
+ G0_Gate_Interrupt_Enable | G0_TC_Interrupt_Enable;
+ static const unsigned gpct_interrupt_b_enable_mask =
+ G1_Gate_Interrupt_Enable | G1_TC_Interrupt_Enable;
+
+ switch (reg) {
+ /* m-series-only registers */
+ case NITIO_G0_Counting_Mode_Reg:
+ ni_writew(bits, M_Offset_G0_Counting_Mode);
+ break;
+ case NITIO_G1_Counting_Mode_Reg:
+ ni_writew(bits, M_Offset_G1_Counting_Mode);
+ break;
+ case NITIO_G0_Second_Gate_Reg:
+ ni_writew(bits, M_Offset_G0_Second_Gate);
+ break;
+ case NITIO_G1_Second_Gate_Reg:
+ ni_writew(bits, M_Offset_G1_Second_Gate);
+ break;
+ case NITIO_G0_DMA_Config_Reg:
+ ni_writew(bits, M_Offset_G0_DMA_Config);
+ break;
+ case NITIO_G1_DMA_Config_Reg:
+ ni_writew(bits, M_Offset_G1_DMA_Config);
+ break;
+ case NITIO_G0_ABZ_Reg:
+ ni_writew(bits, M_Offset_G0_MSeries_ABZ);
+ break;
+ case NITIO_G1_ABZ_Reg:
+ ni_writew(bits, M_Offset_G1_MSeries_ABZ);
+ break;
+
+ /* 32 bit registers */
+ case NITIO_G0_LoadA_Reg:
+ case NITIO_G1_LoadA_Reg:
+ case NITIO_G0_LoadB_Reg:
+ case NITIO_G1_LoadB_Reg:
+ stc_register = ni_gpct_to_stc_register(reg);
+ devpriv->stc_writel(dev, bits, stc_register);
+ break;
+
+ /* 16 bit registers */
+ case NITIO_G0_Interrupt_Enable_Reg:
+ BUG_ON(bits & ~gpct_interrupt_a_enable_mask);
+ ni_set_bitfield(dev, Interrupt_A_Enable_Register,
+ gpct_interrupt_a_enable_mask, bits);
+ break;
+ case NITIO_G1_Interrupt_Enable_Reg:
+ BUG_ON(bits & ~gpct_interrupt_b_enable_mask);
+ ni_set_bitfield(dev, Interrupt_B_Enable_Register,
+ gpct_interrupt_b_enable_mask, bits);
+ break;
+ case NITIO_G01_Joint_Reset_Reg:
+ BUG_ON(bits & ~gpct_joint_reset_mask);
+ /* fall-through */
+ default:
+ stc_register = ni_gpct_to_stc_register(reg);
+ devpriv->stc_writew(dev, bits, stc_register);
+ }
+}
+
+static unsigned ni_gpct_read_register(struct ni_gpct *counter,
+ enum ni_gpct_register reg)
+{
+ struct comedi_device *dev = counter->counter_dev->dev;
+ unsigned stc_register;
+ switch (reg) {
+ /* m-series only registers */
+ case NITIO_G0_DMA_Status_Reg:
+ return ni_readw(M_Offset_G0_DMA_Status);
+ break;
+ case NITIO_G1_DMA_Status_Reg:
+ return ni_readw(M_Offset_G1_DMA_Status);
+ break;
+
+ /* 32 bit registers */
+ case NITIO_G0_HW_Save_Reg:
+ case NITIO_G1_HW_Save_Reg:
+ case NITIO_G0_SW_Save_Reg:
+ case NITIO_G1_SW_Save_Reg:
+ stc_register = ni_gpct_to_stc_register(reg);
+ return devpriv->stc_readl(dev, stc_register);
+ break;
+
+ /* 16 bit registers */
+ default:
+ stc_register = ni_gpct_to_stc_register(reg);
+ return devpriv->stc_readw(dev, stc_register);
+ break;
+ }
+ return 0;
+}
+
+static int ni_freq_out_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->clock_and_fout & FOUT_Divider_mask;
+ return 1;
+}
+
+static int ni_freq_out_insn_write(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ devpriv->clock_and_fout &= ~FOUT_Enable;
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ devpriv->clock_and_fout &= ~FOUT_Divider_mask;
+ devpriv->clock_and_fout |= FOUT_Divider(data[0]);
+ devpriv->clock_and_fout |= FOUT_Enable;
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return insn->n;
+}
+
+static int ni_set_freq_out_clock(struct comedi_device * dev, unsigned int clock_source)
+{
+ switch (clock_source) {
+ case NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC:
+ devpriv->clock_and_fout &= ~FOUT_Timebase_Select;
+ break;
+ case NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC:
+ devpriv->clock_and_fout |= FOUT_Timebase_Select;
+ break;
+ default:
+ return -EINVAL;
+ }
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+ return 3;
+}
+
+static void ni_get_freq_out_clock(struct comedi_device * dev, unsigned int * clock_source,
+ unsigned int * clock_period_ns)
+{
+ if (devpriv->clock_and_fout & FOUT_Timebase_Select) {
+ *clock_source = NI_FREQ_OUT_TIMEBASE_2_CLOCK_SRC;
+ *clock_period_ns = TIMEBASE_2_NS;
+ } else {
+ *clock_source = NI_FREQ_OUT_TIMEBASE_1_DIV_2_CLOCK_SRC;
+ *clock_period_ns = TIMEBASE_1_NS * 2;
+ }
+}
+
+static int ni_freq_out_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ return ni_set_freq_out_clock(dev, data[1]);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ ni_get_freq_out_clock(dev, &data[1], &data[2]);
+ return 3;
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+static int ni_alloc_private(struct comedi_device * dev)
+{
+ int ret;
+
+ ret = alloc_private(dev, sizeof(ni_private));
+ if (ret < 0)
+ return ret;
+
+ spin_lock_init(&devpriv->window_lock);
+ spin_lock_init(&devpriv->soft_reg_copy_lock);
+ spin_lock_init(&devpriv->mite_channel_lock);
+
+ return 0;
+};
+
+static int ni_E_init(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned j;
+ enum ni_gpct_variant counter_variant;
+
+ if (boardtype.n_aochan > MAX_N_AO_CHAN) {
+ printk("bug! boardtype.n_aochan > MAX_N_AO_CHAN\n");
+ return -EINVAL;
+ }
+
+ if (alloc_subdevices(dev, NI_NUM_SUBDEVICES) < 0)
+ return -ENOMEM;
+
+ /* analog input subdevice */
+
+ s = dev->subdevices + NI_AI_SUBDEV;
+ dev->read_subdev = s;
+ if (boardtype.n_adchan) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags =
+ SDF_READABLE | SDF_DIFF | SDF_DITHER | SDF_CMD_READ;
+ if (boardtype.reg_type != ni_reg_611x)
+ s->subdev_flags |= SDF_GROUND | SDF_COMMON | SDF_OTHER;
+ if (boardtype.adbits > 16)
+ s->subdev_flags |= SDF_LSAMPL;
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = boardtype.n_adchan;
+ s->len_chanlist = 512;
+ s->maxdata = (1 << boardtype.adbits) - 1;
+ s->range_table = ni_range_lkup[boardtype.gainlkup];
+ s->insn_read = &ni_ai_insn_read;
+ s->insn_config = &ni_ai_insn_config;
+ s->do_cmdtest = &ni_ai_cmdtest;
+ s->do_cmd = &ni_ai_cmd;
+ s->cancel = &ni_ai_reset;
+ s->poll = &ni_ai_poll;
+ s->munge = &ni_ai_munge;
+#ifdef PCIDMA
+ s->async_dma_dir = DMA_FROM_DEVICE;
+#endif
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* analog output subdevice */
+
+ s = dev->subdevices + NI_AO_SUBDEV;
+ if (boardtype.n_aochan) {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_DEGLITCH | SDF_GROUND;
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ s->subdev_flags |= SDF_SOFT_CALIBRATED;
+ s->n_chan = boardtype.n_aochan;
+ s->maxdata = (1 << boardtype.aobits) - 1;
+ s->range_table = boardtype.ao_range_table;
+ s->insn_read = &ni_ao_insn_read;
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ s->insn_write = &ni_ao_insn_write_671x;
+ } else {
+ s->insn_write = &ni_ao_insn_write;
+ }
+ s->insn_config = &ni_ao_insn_config;
+#ifdef PCIDMA
+ if (boardtype.n_aochan) {
+ s->async_dma_dir = DMA_TO_DEVICE;
+#else
+ if (boardtype.ao_fifo_depth) {
+#endif
+ dev->write_subdev = s;
+ s->subdev_flags |= SDF_CMD_WRITE;
+ s->do_cmd = &ni_ao_cmd;
+ s->do_cmdtest = &ni_ao_cmdtest;
+ s->len_chanlist = boardtype.n_aochan;
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0)
+ s->munge = ni_ao_munge;
+ }
+ s->cancel = &ni_ao_reset;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+ if ((boardtype.reg_type & ni_reg_67xx_mask))
+ init_ao_67xx(dev, s);
+
+ /* digital i/o subdevice */
+
+ s = dev->subdevices + NI_DIO_SUBDEV;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_WRITABLE | SDF_READABLE;
+ s->maxdata = 1;
+ s->io_bits = 0; /* all bits input */
+ s->range_table = &range_digital;
+ s->n_chan = boardtype.num_p0_dio_channels;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ s->subdev_flags |=
+ SDF_LSAMPL | SDF_CMD_WRITE /* | SDF_CMD_READ */ ;
+ s->insn_bits = &ni_m_series_dio_insn_bits;
+ s->insn_config = &ni_m_series_dio_insn_config;
+ s->do_cmd = &ni_cdio_cmd;
+ s->do_cmdtest = &ni_cdio_cmdtest;
+ s->cancel = &ni_cdio_cancel;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->len_chanlist = s->n_chan;
+
+ ni_writel(CDO_Reset_Bit | CDI_Reset_Bit, M_Offset_CDIO_Command);
+ ni_writel(s->io_bits, M_Offset_DIO_Direction);
+ } else {
+ s->insn_bits = &ni_dio_insn_bits;
+ s->insn_config = &ni_dio_insn_config;
+ devpriv->dio_control = DIO_Pins_Dir(s->io_bits);
+ ni_writew(devpriv->dio_control, DIO_Control_Register);
+ }
+
+ /* 8255 device */
+ s = dev->subdevices + NI_8255_DIO_SUBDEV;
+ if (boardtype.has_8255) {
+ subdev_8255_init(dev, s, ni_8255_callback, (unsigned long)dev);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* formerly general purpose counter/timer device, but no longer used */
+ s = dev->subdevices + NI_UNUSED_SUBDEV;
+ s->type = COMEDI_SUBD_UNUSED;
+
+ /* calibration subdevice -- ai and ao */
+ s = dev->subdevices + NI_CALIBRATION_SUBDEV;
+ s->type = COMEDI_SUBD_CALIB;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ // internal PWM analog output used for AI nonlinearity calibration
+ s->subdev_flags = SDF_INTERNAL;
+ s->insn_config = &ni_m_series_pwm_config;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ ni_writel(0x0, M_Offset_Cal_PWM);
+ } else if (boardtype.reg_type == ni_reg_6143) {
+ // internal PWM analog output used for AI nonlinearity calibration
+ s->subdev_flags = SDF_INTERNAL;
+ s->insn_config = &ni_6143_pwm_config;
+ s->n_chan = 1;
+ s->maxdata = 0;
+ } else {
+ s->subdev_flags = SDF_WRITABLE | SDF_INTERNAL;
+ s->insn_read = &ni_calib_insn_read;
+ s->insn_write = &ni_calib_insn_write;
+ caldac_setup(dev, s);
+ }
+
+ /* EEPROM */
+ s = dev->subdevices + NI_EEPROM_SUBDEV;
+ s->type = COMEDI_SUBD_MEMORY;
+ s->subdev_flags = SDF_READABLE | SDF_INTERNAL;
+ s->maxdata = 0xff;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ s->n_chan = M_SERIES_EEPROM_SIZE;
+ s->insn_read = &ni_m_series_eeprom_insn_read;
+ } else {
+ s->n_chan = 512;
+ s->insn_read = &ni_eeprom_insn_read;
+ }
+
+ /* PFI */
+ s = dev->subdevices + NI_PFI_DIO_SUBDEV;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ unsigned i;
+ s->n_chan = 16;
+ ni_writew(s->state, M_Offset_PFI_DO);
+ for (i = 0; i < NUM_PFI_OUTPUT_SELECT_REGS; ++i) {
+ ni_writew(devpriv->pfi_output_select_reg[i],
+ M_Offset_PFI_Output_Select(i + 1));
+ }
+ } else {
+ s->n_chan = 10;
+ }
+ s->maxdata = 1;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ s->insn_bits = &ni_pfi_insn_bits;
+ }
+ s->insn_config = &ni_pfi_insn_config;
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, ~0, 0);
+
+ /* cs5529 calibration adc */
+ s = dev->subdevices + NI_CS5529_CALIBRATION_SUBDEV;
+ if (boardtype.reg_type & ni_reg_67xx_mask) {
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_DIFF | SDF_INTERNAL;
+ // one channel for each analog output channel
+ s->n_chan = boardtype.n_aochan;
+ s->maxdata = (1 << 16) - 1;
+ s->range_table = &range_unknown; /* XXX */
+ s->insn_read = cs5529_ai_insn_read;
+ s->insn_config = NULL;
+ init_cs5529(dev);
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ /* Serial */
+ s = dev->subdevices + NI_SERIAL_SUBDEV;
+ s->type = COMEDI_SUBD_SERIAL;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 1;
+ s->maxdata = 0xff;
+ s->insn_config = ni_serial_insn_config;
+ devpriv->serial_interval_ns = 0;
+ devpriv->serial_hw_mode = 0;
+
+ /* RTSI */
+ s = dev->subdevices + NI_RTSI_SUBDEV;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_INTERNAL;
+ s->n_chan = 8;
+ s->maxdata = 1;
+ s->insn_bits = ni_rtsi_insn_bits;
+ s->insn_config = ni_rtsi_insn_config;
+ ni_rtsi_init(dev);
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ counter_variant = ni_gpct_variant_m_series;
+ } else {
+ counter_variant = ni_gpct_variant_e_series;
+ }
+ devpriv->counter_dev = ni_gpct_device_construct(dev,
+ &ni_gpct_write_register, &ni_gpct_read_register,
+ counter_variant, NUM_GPCT);
+ /* General purpose counters */
+ for (j = 0; j < NUM_GPCT; ++j) {
+ s = dev->subdevices + NI_GPCT_SUBDEV(j);
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_CMD_READ
+ /* | SDF_CMD_WRITE */ ;
+ s->n_chan = 3;
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ s->maxdata = 0xffffffff;
+ else
+ s->maxdata = 0xffffff;
+ s->insn_read = &ni_gpct_insn_read;
+ s->insn_write = &ni_gpct_insn_write;
+ s->insn_config = &ni_gpct_insn_config;
+ s->do_cmd = &ni_gpct_cmd;
+ s->len_chanlist = 1;
+ s->do_cmdtest = &ni_gpct_cmdtest;
+ s->cancel = &ni_gpct_cancel;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+ s->private = &devpriv->counter_dev->counters[j];
+
+ devpriv->counter_dev->counters[j].chip_index = 0;
+ devpriv->counter_dev->counters[j].counter_index = j;
+ ni_tio_init_counter(&devpriv->counter_dev->counters[j]);
+ }
+
+ /* Frequency output */
+ s = dev->subdevices + NI_FREQ_OUT_SUBDEV;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xf;
+ s->insn_read = &ni_freq_out_insn_read;
+ s->insn_write = &ni_freq_out_insn_write;
+ s->insn_config = &ni_freq_out_insn_config;
+
+ /* ai configuration */
+ ni_ai_reset(dev, dev->subdevices + NI_AI_SUBDEV);
+ if ((boardtype.reg_type & ni_reg_6xxx_mask) == 0) {
+ // BEAM is this needed for PCI-6143 ??
+ devpriv->clock_and_fout =
+ Slow_Internal_Time_Divide_By_2 |
+ Slow_Internal_Timebase |
+ Clock_To_Board_Divide_By_2 |
+ Clock_To_Board |
+ AI_Output_Divide_By_2 | AO_Output_Divide_By_2;
+ } else {
+ devpriv->clock_and_fout =
+ Slow_Internal_Time_Divide_By_2 |
+ Slow_Internal_Timebase |
+ Clock_To_Board_Divide_By_2 | Clock_To_Board;
+ }
+ devpriv->stc_writew(dev, devpriv->clock_and_fout,
+ Clock_and_FOUT_Register);
+
+ /* analog output configuration */
+ ni_ao_reset(dev, dev->subdevices + NI_AO_SUBDEV);
+
+ if (dev->irq) {
+ devpriv->stc_writew(dev,
+ (IRQ_POLARITY ? Interrupt_Output_Polarity : 0) |
+ (Interrupt_Output_On_3_Pins & 0) | Interrupt_A_Enable |
+ Interrupt_B_Enable |
+ Interrupt_A_Output_Select(interrupt_pin(dev->
+ irq)) |
+ Interrupt_B_Output_Select(interrupt_pin(dev->irq)),
+ Interrupt_Control_Register);
+ }
+
+ /* DMA setup */
+ ni_writeb(devpriv->ai_ao_select_reg, AI_AO_Select);
+ ni_writeb(devpriv->g0_g1_select_reg, G0_G1_Select);
+
+ if (boardtype.reg_type & ni_reg_6xxx_mask) {
+ ni_writeb(0, Magic_611x);
+ } else if (boardtype.reg_type & ni_reg_m_series_mask) {
+ int channel;
+ for (channel = 0; channel < boardtype.n_aochan; ++channel) {
+ ni_writeb(0xf, M_Offset_AO_Waveform_Order(channel));
+ ni_writeb(0x0,
+ M_Offset_AO_Reference_Attenuation(channel));
+ }
+ ni_writeb(0x0, M_Offset_AO_Calibration);
+ }
+
+ printk("\n");
+ return 0;
+}
+
+static int ni_8255_callback(int dir, int port, int data, unsigned long arg)
+{
+ struct comedi_device *dev = (struct comedi_device *) arg;
+
+ if (dir) {
+ ni_writeb(data, Port_A + 2 * port);
+ return 0;
+ } else {
+ return ni_readb(Port_A + 2 * port);
+ }
+}
+
+/*
+ presents the EEPROM as a subdevice
+*/
+
+static int ni_eeprom_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = ni_read_eeprom(dev, CR_CHAN(insn->chanspec));
+
+ return 1;
+}
+
+/*
+ reads bytes out of eeprom
+*/
+
+static int ni_read_eeprom(struct comedi_device * dev, int addr)
+{
+ int bit;
+ int bitstring;
+
+ bitstring = 0x0300 | ((addr & 0x100) << 3) | (addr & 0xff);
+ ni_writeb(0x04, Serial_Command);
+ for (bit = 0x8000; bit; bit >>= 1) {
+ ni_writeb(0x04 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ ni_writeb(0x05 | ((bit & bitstring) ? 0x02 : 0),
+ Serial_Command);
+ }
+ bitstring = 0;
+ for (bit = 0x80; bit; bit >>= 1) {
+ ni_writeb(0x04, Serial_Command);
+ ni_writeb(0x05, Serial_Command);
+ bitstring |= ((ni_readb(XXX_Status) & PROMOUT) ? bit : 0);
+ }
+ ni_writeb(0x00, Serial_Command);
+
+ return bitstring;
+}
+
+static int ni_m_series_eeprom_insn_read(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->eeprom_buffer[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int ni_get_pwm_config(struct comedi_device * dev, unsigned int * data)
+{
+ data[1] = devpriv->pwm_up_count * devpriv->clock_ns;
+ data[2] = devpriv->pwm_down_count * devpriv->clock_ns;
+ return 3;
+}
+
+static int ni_m_series_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned up_count, down_count;
+ switch (data[0]) {
+ case INSN_CONFIG_PWM_OUTPUT:
+ switch (data[1]) {
+ case TRIG_ROUND_NEAREST:
+ up_count =
+ (data[2] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ up_count = data[2] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ up_count =
+ (data[2] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ switch (data[3]) {
+ case TRIG_ROUND_NEAREST:
+ down_count =
+ (data[4] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ down_count = data[4] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ down_count =
+ (data[4] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ if (up_count * devpriv->clock_ns != data[2] ||
+ down_count * devpriv->clock_ns != data[4]) {
+ data[2] = up_count * devpriv->clock_ns;
+ data[4] = down_count * devpriv->clock_ns;
+ return -EAGAIN;
+ }
+ ni_writel(MSeries_Cal_PWM_High_Time_Bits(up_count) |
+ MSeries_Cal_PWM_Low_Time_Bits(down_count),
+ M_Offset_Cal_PWM);
+ devpriv->pwm_up_count = up_count;
+ devpriv->pwm_down_count = down_count;
+ return 5;
+ break;
+ case INSN_CONFIG_GET_PWM_OUTPUT:
+ return ni_get_pwm_config(dev, data);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static int ni_6143_pwm_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned up_count, down_count;
+ switch (data[0]) {
+ case INSN_CONFIG_PWM_OUTPUT:
+ switch (data[1]) {
+ case TRIG_ROUND_NEAREST:
+ up_count =
+ (data[2] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ up_count = data[2] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ up_count =
+ (data[2] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ switch (data[3]) {
+ case TRIG_ROUND_NEAREST:
+ down_count =
+ (data[4] +
+ devpriv->clock_ns / 2) / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_DOWN:
+ down_count = data[4] / devpriv->clock_ns;
+ break;
+ case TRIG_ROUND_UP:
+ down_count =
+ (data[4] + devpriv->clock_ns -
+ 1) / devpriv->clock_ns;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ if (up_count * devpriv->clock_ns != data[2] ||
+ down_count * devpriv->clock_ns != data[4]) {
+ data[2] = up_count * devpriv->clock_ns;
+ data[4] = down_count * devpriv->clock_ns;
+ return -EAGAIN;
+ }
+ ni_writel(up_count, Calibration_HighTime_6143);
+ devpriv->pwm_up_count = up_count;
+ ni_writel(down_count, Calibration_LowTime_6143);
+ devpriv->pwm_down_count = down_count;
+ return 5;
+ break;
+ case INSN_CONFIG_GET_PWM_OUTPUT:
+ return ni_get_pwm_config(dev, data);
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static void ni_write_caldac(struct comedi_device * dev, int addr, int val);
+/*
+ calibration subdevice
+*/
+static int ni_calib_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ ni_write_caldac(dev, CR_CHAN(insn->chanspec), data[0]);
+
+ return 1;
+}
+
+static int ni_calib_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ data[0] = devpriv->caldacs[CR_CHAN(insn->chanspec)];
+
+ return 1;
+}
+
+static int pack_mb88341(int addr, int val, int *bitstring);
+static int pack_dac8800(int addr, int val, int *bitstring);
+static int pack_dac8043(int addr, int val, int *bitstring);
+static int pack_ad8522(int addr, int val, int *bitstring);
+static int pack_ad8804(int addr, int val, int *bitstring);
+static int pack_ad8842(int addr, int val, int *bitstring);
+
+struct caldac_struct {
+ int n_chans;
+ int n_bits;
+ int (*packbits) (int, int, int *);
+};
+
+static struct caldac_struct caldacs[] = {
+ [mb88341] = {12, 8, pack_mb88341},
+ [dac8800] = {8, 8, pack_dac8800},
+ [dac8043] = {1, 12, pack_dac8043},
+ [ad8522] = {2, 12, pack_ad8522},
+ [ad8804] = {12, 8, pack_ad8804},
+ [ad8842] = {8, 8, pack_ad8842},
+ [ad8804_debug] = {16, 8, pack_ad8804},
+};
+
+static void caldac_setup(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int i, j;
+ int n_dacs;
+ int n_chans = 0;
+ int n_bits;
+ int diffbits = 0;
+ int type;
+ int chan;
+
+ type = boardtype.caldac[0];
+ if (type == caldac_none)
+ return;
+ n_bits = caldacs[type].n_bits;
+ for (i = 0; i < 3; i++) {
+ type = boardtype.caldac[i];
+ if (type == caldac_none)
+ break;
+ if (caldacs[type].n_bits != n_bits)
+ diffbits = 1;
+ n_chans += caldacs[type].n_chans;
+ }
+ n_dacs = i;
+ s->n_chan = n_chans;
+
+ if (diffbits) {
+ unsigned int *maxdata_list;
+
+ if (n_chans > MAX_N_CALDACS) {
+ printk("BUG! MAX_N_CALDACS too small\n");
+ }
+ s->maxdata_list = maxdata_list = devpriv->caldac_maxdata_list;
+ chan = 0;
+ for (i = 0; i < n_dacs; i++) {
+ type = boardtype.caldac[i];
+ for (j = 0; j < caldacs[type].n_chans; j++) {
+ maxdata_list[chan] =
+ (1 << caldacs[type].n_bits) - 1;
+ chan++;
+ }
+ }
+
+ for (chan = 0; chan < s->n_chan; chan++)
+ ni_write_caldac(dev, i, s->maxdata_list[i] / 2);
+ } else {
+ type = boardtype.caldac[0];
+ s->maxdata = (1 << caldacs[type].n_bits) - 1;
+
+ for (chan = 0; chan < s->n_chan; chan++)
+ ni_write_caldac(dev, i, s->maxdata / 2);
+ }
+}
+
+static void ni_write_caldac(struct comedi_device * dev, int addr, int val)
+{
+ unsigned int loadbit = 0, bits = 0, bit, bitstring = 0;
+ int i;
+ int type;
+
+ //printk("ni_write_caldac: chan=%d val=%d\n",addr,val);
+ if (devpriv->caldacs[addr] == val)
+ return;
+ devpriv->caldacs[addr] = val;
+
+ for (i = 0; i < 3; i++) {
+ type = boardtype.caldac[i];
+ if (type == caldac_none)
+ break;
+ if (addr < caldacs[type].n_chans) {
+ bits = caldacs[type].packbits(addr, val, &bitstring);
+ loadbit = SerDacLd(i);
+ //printk("caldac: using i=%d addr=%d %x\n",i,addr,bitstring);
+ break;
+ }
+ addr -= caldacs[type].n_chans;
+ }
+
+ for (bit = 1 << (bits - 1); bit; bit >>= 1) {
+ ni_writeb(((bit & bitstring) ? 0x02 : 0), Serial_Command);
+ comedi_udelay(1);
+ ni_writeb(1 | ((bit & bitstring) ? 0x02 : 0), Serial_Command);
+ comedi_udelay(1);
+ }
+ ni_writeb(loadbit, Serial_Command);
+ comedi_udelay(1);
+ ni_writeb(0, Serial_Command);
+}
+
+static int pack_mb88341(int addr, int val, int *bitstring)
+{
+ /*
+ Fujitsu MB 88341
+ Note that address bits are reversed. Thanks to
+ Ingo Keen for noticing this.
+
+ Note also that the 88341 expects address values from
+ 1-12, whereas we use channel numbers 0-11. The NI
+ docs use 1-12, also, so be careful here.
+ */
+ addr++;
+ *bitstring = ((addr & 0x1) << 11) |
+ ((addr & 0x2) << 9) |
+ ((addr & 0x4) << 7) | ((addr & 0x8) << 5) | (val & 0xff);
+ return 12;
+}
+
+static int pack_dac8800(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr & 0x7) << 8) | (val & 0xff);
+ return 11;
+}
+
+static int pack_dac8043(int addr, int val, int *bitstring)
+{
+ *bitstring = val & 0xfff;
+ return 12;
+}
+
+static int pack_ad8522(int addr, int val, int *bitstring)
+{
+ *bitstring = (val & 0xfff) | (addr ? 0xc000 : 0xa000);
+ return 16;
+}
+
+static int pack_ad8804(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr & 0xf) << 8) | (val & 0xff);
+ return 12;
+}
+
+static int pack_ad8842(int addr, int val, int *bitstring)
+{
+ *bitstring = ((addr + 1) << 8) | (val & 0xff);
+ return 12;
+}
+
+#if 0
+/*
+ * Read the GPCTs current value.
+ */
+static int GPCT_G_Watch(struct comedi_device * dev, int chan)
+{
+ unsigned int hi1, hi2, lo;
+
+ devpriv->gpct_command[chan] &= ~G_Save_Trace;
+ devpriv->stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ devpriv->gpct_command[chan] |= G_Save_Trace;
+ devpriv->stc_writew(dev, devpriv->gpct_command[chan],
+ G_Command_Register(chan));
+
+ /* This procedure is used because the two registers cannot
+ * be read atomically. */
+ do {
+ hi1 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
+ lo = devpriv->stc_readw(dev, G_Save_Register_Low(chan));
+ hi2 = devpriv->stc_readw(dev, G_Save_Register_High(chan));
+ } while (hi1 != hi2);
+
+ return (hi1 << 16) | lo;
+}
+
+static void GPCT_Reset(struct comedi_device * dev, int chan)
+{
+ int temp_ack_reg = 0;
+
+ //printk("GPCT_Reset...");
+ devpriv->gpct_cur_operation[chan] = GPCT_RESET;
+
+ switch (chan) {
+ case 0:
+ devpriv->stc_writew(dev, G0_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_A_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G0_Gate_Error_Confirm;
+ temp_ack_reg |= G0_TC_Error_Confirm;
+ temp_ack_reg |= G0_TC_Interrupt_Ack;
+ temp_ack_reg |= G0_Gate_Interrupt_Ack;
+ devpriv->stc_writew(dev, temp_ack_reg,
+ Interrupt_A_Ack_Register);
+
+ //problem...this interferes with the other ctr...
+ devpriv->an_trig_etc_reg |= GPFO_0_Output_Enable;
+ devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
+ case 1:
+ devpriv->stc_writew(dev, G1_Reset, Joint_Reset_Register);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G1_TC_Interrupt_Enable, 0);
+ ni_set_bits(dev, Interrupt_B_Enable_Register,
+ G0_Gate_Interrupt_Enable, 0);
+ temp_ack_reg |= G1_Gate_Error_Confirm;
+ temp_ack_reg |= G1_TC_Error_Confirm;
+ temp_ack_reg |= G1_TC_Interrupt_Ack;
+ temp_ack_reg |= G1_Gate_Interrupt_Ack;
+ devpriv->stc_writew(dev, temp_ack_reg,
+ Interrupt_B_Ack_Register);
+
+ devpriv->an_trig_etc_reg |= GPFO_1_Output_Enable;
+ devpriv->stc_writew(dev, devpriv->an_trig_etc_reg,
+ Analog_Trigger_Etc_Register);
+ break;
+ };
+
+ devpriv->gpct_mode[chan] = 0;
+ devpriv->gpct_input_select[chan] = 0;
+ devpriv->gpct_command[chan] = 0;
+
+ devpriv->gpct_command[chan] |= G_Synchronized_Gate;
+
+ devpriv->stc_writew(dev, devpriv->gpct_mode[chan],
+ G_Mode_Register(chan));
+ devpriv->stc_writew(dev, devpriv->gpct_input_select[chan],
+ G_Input_Select_Register(chan));
+ devpriv->stc_writew(dev, 0, G_Autoincrement_Register(chan));
+
+ //printk("exit GPCT_Reset\n");
+}
+
+#endif
+
+static int ni_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct *counter = s->private;
+ return ni_tio_insn_config(counter, insn, data);
+}
+
+static int ni_gpct_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct *counter = s->private;
+ return ni_tio_rinsn(counter, insn, data);
+}
+
+static int ni_gpct_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct *counter = s->private;
+ return ni_tio_winsn(counter, insn, data);
+}
+
+static int ni_gpct_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int retval;
+#ifdef PCIDMA
+ struct ni_gpct *counter = s->private;
+// const struct comedi_cmd *cmd = &s->async->cmd;
+
+ retval = ni_request_gpct_mite_channel(dev, counter->counter_index,
+ COMEDI_INPUT);
+ if (retval) {
+ comedi_error(dev,
+ "no dma channel available for use by counter");
+ return retval;
+ }
+ ni_tio_acknowledge_and_confirm(counter, NULL, NULL, NULL, NULL);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 1);
+ retval = ni_tio_cmd(counter, s->async);
+#else
+ retval = -ENOTSUPP;
+#endif
+ return retval;
+}
+
+static int ni_gpct_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+#ifdef PCIDMA
+ struct ni_gpct *counter = s->private;
+
+ return ni_tio_cmdtest(counter, cmd);
+#else
+ return -ENOTSUPP;
+#endif
+}
+
+static int ni_gpct_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+#ifdef PCIDMA
+ struct ni_gpct *counter = s->private;
+ int retval;
+
+ retval = ni_tio_cancel(counter);
+ ni_e_series_enable_second_irq(dev, counter->counter_index, 0);
+ ni_release_gpct_mite_channel(dev, counter->counter_index);
+ return retval;
+#else
+ return 0;
+#endif
+}
+
+/*
+ *
+ * Programmable Function Inputs
+ *
+ */
+
+static int ni_m_series_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ unsigned pfi_reg_index;
+ unsigned array_offset;
+ if ((source & 0x1f) != source)
+ return -EINVAL;
+ pfi_reg_index = 1 + chan / 3;
+ array_offset = pfi_reg_index - 1;
+ devpriv->pfi_output_select_reg[array_offset] &=
+ ~MSeries_PFI_Output_Select_Mask(chan);
+ devpriv->pfi_output_select_reg[array_offset] |=
+ MSeries_PFI_Output_Select_Bits(chan, source);
+ ni_writew(devpriv->pfi_output_select_reg[array_offset],
+ M_Offset_PFI_Output_Select(pfi_reg_index));
+ return 2;
+}
+
+static int ni_old_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ // pre-m-series boards have fixed signals on pfi pins
+ if (source != ni_old_get_pfi_routing(dev, chan))
+ return -EINVAL;
+ return 2;
+}
+
+static int ni_set_pfi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return ni_m_series_set_pfi_routing(dev, chan, source);
+ else
+ return ni_old_set_pfi_routing(dev, chan, source);
+}
+
+static unsigned ni_m_series_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ const unsigned array_offset = chan / 3;
+ return MSeries_PFI_Output_Select_Source(chan,
+ devpriv->pfi_output_select_reg[array_offset]);
+}
+
+static unsigned ni_old_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ // pre-m-series boards have fixed signals on pfi pins
+ switch (chan) {
+ case 0:
+ return NI_PFI_OUTPUT_AI_START1;
+ break;
+ case 1:
+ return NI_PFI_OUTPUT_AI_START2;
+ break;
+ case 2:
+ return NI_PFI_OUTPUT_AI_CONVERT;
+ break;
+ case 3:
+ return NI_PFI_OUTPUT_G_SRC1;
+ break;
+ case 4:
+ return NI_PFI_OUTPUT_G_GATE1;
+ break;
+ case 5:
+ return NI_PFI_OUTPUT_AO_UPDATE_N;
+ break;
+ case 6:
+ return NI_PFI_OUTPUT_AO_START1;
+ break;
+ case 7:
+ return NI_PFI_OUTPUT_AI_START_PULSE;
+ break;
+ case 8:
+ return NI_PFI_OUTPUT_G_SRC0;
+ break;
+ case 9:
+ return NI_PFI_OUTPUT_G_GATE0;
+ break;
+ default:
+ rt_printk("%s: bug, unhandled case in switch.\n", __FUNCTION__);
+ break;
+ }
+ return 0;
+}
+
+static unsigned ni_get_pfi_routing(struct comedi_device * dev, unsigned chan)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return ni_m_series_get_pfi_routing(dev, chan);
+ else
+ return ni_old_get_pfi_routing(dev, chan);
+}
+
+static int ni_config_filter(struct comedi_device * dev, unsigned pfi_channel,
+ enum ni_pfi_filter_select filter)
+{
+ unsigned bits;
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ return -ENOTSUPP;
+ }
+ bits = ni_readl(M_Offset_PFI_Filter);
+ bits &= ~MSeries_PFI_Filter_Select_Mask(pfi_channel);
+ bits |= MSeries_PFI_Filter_Select_Bits(pfi_channel, filter);
+ ni_writel(bits, M_Offset_PFI_Filter);
+ return 0;
+}
+
+static int ni_pfi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if ((boardtype.reg_type & ni_reg_m_series_mask) == 0) {
+ return -ENOTSUPP;
+ }
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ ni_writew(s->state, M_Offset_PFI_DO);
+ }
+ data[1] = ni_readw(M_Offset_PFI_DI);
+ return 2;
+}
+
+static int ni_pfi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan;
+
+ if (insn->n < 1)
+ return -EINVAL;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ switch (data[0]) {
+ case COMEDI_OUTPUT:
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 1);
+ break;
+ case COMEDI_INPUT:
+ ni_set_bits(dev, IO_Bidirection_Pin_Register, 1 << chan, 0);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (devpriv->
+ io_bidirection_pin_reg & (1 << chan)) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return 0;
+ break;
+ case INSN_CONFIG_SET_ROUTING:
+ return ni_set_pfi_routing(dev, chan, data[1]);
+ break;
+ case INSN_CONFIG_GET_ROUTING:
+ data[1] = ni_get_pfi_routing(dev, chan);
+ break;
+ case INSN_CONFIG_FILTER:
+ return ni_config_filter(dev, chan, data[1]);
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/*
+ *
+ * NI RTSI Bus Functions
+ *
+ */
+static void ni_rtsi_init(struct comedi_device * dev)
+{
+ // Initialises the RTSI bus signal switch to a default state
+
+ // Set clock mode to internal
+ devpriv->clock_and_fout2 = MSeries_RTSI_10MHz_Bit;
+ if (ni_set_master_clock(dev, NI_MIO_INTERNAL_CLOCK, 0) < 0) {
+ rt_printk("ni_set_master_clock failed, bug?");
+ }
+ // default internal lines routing to RTSI bus lines
+ devpriv->rtsi_trig_a_output_reg =
+ RTSI_Trig_Output_Bits(0,
+ NI_RTSI_OUTPUT_ADR_START1) | RTSI_Trig_Output_Bits(1,
+ NI_RTSI_OUTPUT_ADR_START2) | RTSI_Trig_Output_Bits(2,
+ NI_RTSI_OUTPUT_SCLKG) | RTSI_Trig_Output_Bits(3,
+ NI_RTSI_OUTPUT_DACUPDN);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
+ devpriv->rtsi_trig_b_output_reg =
+ RTSI_Trig_Output_Bits(4,
+ NI_RTSI_OUTPUT_DA_START1) | RTSI_Trig_Output_Bits(5,
+ NI_RTSI_OUTPUT_G_SRC0) | RTSI_Trig_Output_Bits(6,
+ NI_RTSI_OUTPUT_G_GATE0);
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ devpriv->rtsi_trig_b_output_reg |=
+ RTSI_Trig_Output_Bits(7, NI_RTSI_OUTPUT_RTSI_OSC);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
+
+ // Sets the source and direction of the 4 on board lines
+// devpriv->stc_writew(dev, 0x0000, RTSI_Board_Register);
+}
+
+static int ni_rtsi_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = 0;
+
+ return 2;
+}
+
+/* Find best multiplier/divider to try and get the PLL running at 80 MHz
+ * given an arbitrary frequency input clock */
+static int ni_mseries_get_pll_parameters(unsigned reference_period_ns,
+ unsigned *freq_divider, unsigned *freq_multiplier,
+ unsigned *actual_period_ns)
+{
+ unsigned div;
+ unsigned best_div = 1;
+ static const unsigned max_div = 0x10;
+ unsigned mult;
+ unsigned best_mult = 1;
+ static const unsigned max_mult = 0x100;
+ static const unsigned pico_per_nano = 1000;
+
+ const unsigned reference_picosec = reference_period_ns * pico_per_nano;
+ /* m-series wants the phased-locked loop to output 80MHz, which is divided by 4 to
+ * 20 MHz for most timing clocks */
+ static const unsigned target_picosec = 12500;
+ static const unsigned fudge_factor_80_to_20Mhz = 4;
+ int best_period_picosec = 0;
+ for (div = 1; div <= max_div; ++div) {
+ for (mult = 1; mult <= max_mult; ++mult) {
+ unsigned new_period_ps =
+ (reference_picosec * div) / mult;
+ if (abs(new_period_ps - target_picosec) <
+ abs(best_period_picosec - target_picosec)) {
+ best_period_picosec = new_period_ps;
+ best_div = div;
+ best_mult = mult;
+ }
+ }
+ }
+ if (best_period_picosec == 0) {
+ rt_printk("%s: bug, failed to find pll parameters\n",
+ __FUNCTION__);
+ return -EIO;
+ }
+ *freq_divider = best_div;
+ *freq_multiplier = best_mult;
+ *actual_period_ns =
+ (best_period_picosec * fudge_factor_80_to_20Mhz +
+ (pico_per_nano / 2)) / pico_per_nano;
+ return 0;
+}
+
+static inline unsigned num_configurable_rtsi_channels(struct comedi_device * dev)
+{
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return 8;
+ else
+ return 7;
+}
+
+static int ni_mseries_set_pll_master_clock(struct comedi_device * dev, unsigned source,
+ unsigned period_ns)
+{
+ static const unsigned min_period_ns = 50;
+ static const unsigned max_period_ns = 1000;
+ static const unsigned timeout = 1000;
+ unsigned pll_control_bits;
+ unsigned freq_divider;
+ unsigned freq_multiplier;
+ unsigned i;
+ int retval;
+ if (source == NI_MIO_PLL_PXI10_CLOCK)
+ period_ns = 100;
+ // these limits are somewhat arbitrary, but NI advertises 1 to 20MHz range so we'll use that
+ if (period_ns < min_period_ns || period_ns > max_period_ns) {
+ rt_printk
+ ("%s: you must specify an input clock frequency between %i and %i nanosec "
+ "for the phased-lock loop.\n", __FUNCTION__,
+ min_period_ns, max_period_ns);
+ return -EINVAL;
+ }
+ devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ pll_control_bits =
+ MSeries_PLL_Enable_Bit | MSeries_PLL_VCO_Mode_75_150MHz_Bits;
+ devpriv->clock_and_fout2 |=
+ MSeries_Timebase1_Select_Bit | MSeries_Timebase3_Select_Bit;
+ devpriv->clock_and_fout2 &= ~MSeries_PLL_In_Source_Select_Mask;
+ switch (source) {
+ case NI_MIO_PLL_PXI_STAR_TRIGGER_CLOCK:
+ devpriv->clock_and_fout2 |=
+ MSeries_PLL_In_Source_Select_Star_Trigger_Bits;
+ retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
+ &freq_multiplier, &devpriv->clock_ns);
+ if (retval < 0)
+ return retval;
+ break;
+ case NI_MIO_PLL_PXI10_CLOCK:
+ /* pxi clock is 10MHz */
+ devpriv->clock_and_fout2 |=
+ MSeries_PLL_In_Source_Select_PXI_Clock10;
+ retval = ni_mseries_get_pll_parameters(period_ns, &freq_divider,
+ &freq_multiplier, &devpriv->clock_ns);
+ if (retval < 0)
+ return retval;
+ break;
+ default:
+ {
+ unsigned rtsi_channel;
+ static const unsigned max_rtsi_channel = 7;
+ for (rtsi_channel = 0; rtsi_channel <= max_rtsi_channel;
+ ++rtsi_channel) {
+ if (source ==
+ NI_MIO_PLL_RTSI_CLOCK(rtsi_channel)) {
+ devpriv->clock_and_fout2 |=
+ MSeries_PLL_In_Source_Select_RTSI_Bits
+ (rtsi_channel);
+ break;
+ }
+ }
+ if (rtsi_channel > max_rtsi_channel)
+ return -EINVAL;
+ retval = ni_mseries_get_pll_parameters(period_ns,
+ &freq_divider, &freq_multiplier,
+ &devpriv->clock_ns);
+ if (retval < 0)
+ return retval;
+ }
+ break;
+ }
+ ni_writew(devpriv->clock_and_fout2, M_Offset_Clock_and_Fout2);
+ pll_control_bits |=
+ MSeries_PLL_Divisor_Bits(freq_divider) |
+ MSeries_PLL_Multiplier_Bits(freq_multiplier);
+// rt_printk("using divider=%i, multiplier=%i for PLL. pll_control_bits = 0x%x\n", freq_divider, freq_multiplier, pll_control_bits);
+// rt_printk("clock_ns=%d\n", devpriv->clock_ns);
+ ni_writew(pll_control_bits, M_Offset_PLL_Control);
+ devpriv->clock_source = source;
+ /* it seems to typically take a few hundred microseconds for PLL to lock */
+ for (i = 0; i < timeout; ++i) {
+ if (ni_readw(M_Offset_PLL_Status) & MSeries_PLL_Locked_Bit) {
+ break;
+ }
+ udelay(1);
+ }
+ if (i == timeout) {
+ rt_printk
+ ("%s: timed out waiting for PLL to lock to reference clock source %i with period %i ns.\n",
+ __FUNCTION__, source, period_ns);
+ return -ETIMEDOUT;
+ }
+ return 3;
+}
+
+static int ni_set_master_clock(struct comedi_device * dev, unsigned source,
+ unsigned period_ns)
+{
+ if (source == NI_MIO_INTERNAL_CLOCK) {
+ devpriv->rtsi_trig_direction_reg &= ~Use_RTSI_Clock_Bit;
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ devpriv->clock_ns = TIMEBASE_1_NS;
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ devpriv->clock_and_fout2 &=
+ ~(MSeries_Timebase1_Select_Bit |
+ MSeries_Timebase3_Select_Bit);
+ ni_writew(devpriv->clock_and_fout2,
+ M_Offset_Clock_and_Fout2);
+ ni_writew(0, M_Offset_PLL_Control);
+ }
+ devpriv->clock_source = source;
+ } else {
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ return ni_mseries_set_pll_master_clock(dev, source,
+ period_ns);
+ } else {
+ if (source == NI_MIO_RTSI_CLOCK) {
+ devpriv->rtsi_trig_direction_reg |=
+ Use_RTSI_Clock_Bit;
+ devpriv->stc_writew(dev,
+ devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ if (period_ns == 0) {
+ rt_printk
+ ("%s: we don't handle an unspecified clock period correctly yet, returning error.\n",
+ __FUNCTION__);
+ return -EINVAL;
+ } else {
+ devpriv->clock_ns = period_ns;
+ }
+ devpriv->clock_source = source;
+ } else
+ return -EINVAL;
+ }
+ }
+ return 3;
+}
+
+static int ni_valid_rtsi_output_source(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (chan >= num_configurable_rtsi_channels(dev)) {
+ if (chan == old_RTSI_clock_channel) {
+ if (source == NI_RTSI_OUTPUT_RTSI_OSC)
+ return 1;
+ else {
+ rt_printk
+ ("%s: invalid source for channel=%i, channel %i is always the RTSI clock for pre-m-series boards.\n",
+ __FUNCTION__, chan,
+ old_RTSI_clock_channel);
+ return 0;
+ }
+ }
+ return 0;
+ }
+ switch (source) {
+ case NI_RTSI_OUTPUT_ADR_START1:
+ case NI_RTSI_OUTPUT_ADR_START2:
+ case NI_RTSI_OUTPUT_SCLKG:
+ case NI_RTSI_OUTPUT_DACUPDN:
+ case NI_RTSI_OUTPUT_DA_START1:
+ case NI_RTSI_OUTPUT_G_SRC0:
+ case NI_RTSI_OUTPUT_G_GATE0:
+ case NI_RTSI_OUTPUT_RGOUT0:
+ case NI_RTSI_OUTPUT_RTSI_BRD_0:
+ return 1;
+ break;
+ case NI_RTSI_OUTPUT_RTSI_OSC:
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ return 1;
+ else
+ return 0;
+ break;
+ default:
+ return 0;
+ break;
+ }
+}
+
+static int ni_set_rtsi_routing(struct comedi_device * dev, unsigned chan,
+ unsigned source)
+{
+ if (ni_valid_rtsi_output_source(dev, chan, source) == 0)
+ return -EINVAL;
+ if (chan < 4) {
+ devpriv->rtsi_trig_a_output_reg &= ~RTSI_Trig_Output_Mask(chan);
+ devpriv->rtsi_trig_a_output_reg |=
+ RTSI_Trig_Output_Bits(chan, source);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_a_output_reg,
+ RTSI_Trig_A_Output_Register);
+ } else if (chan < 8) {
+ devpriv->rtsi_trig_b_output_reg &= ~RTSI_Trig_Output_Mask(chan);
+ devpriv->rtsi_trig_b_output_reg |=
+ RTSI_Trig_Output_Bits(chan, source);
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_b_output_reg,
+ RTSI_Trig_B_Output_Register);
+ }
+ return 2;
+}
+
+static unsigned ni_get_rtsi_routing(struct comedi_device * dev, unsigned chan)
+{
+ if (chan < 4) {
+ return RTSI_Trig_Output_Source(chan,
+ devpriv->rtsi_trig_a_output_reg);
+ } else if (chan < num_configurable_rtsi_channels(dev)) {
+ return RTSI_Trig_Output_Source(chan,
+ devpriv->rtsi_trig_b_output_reg);
+ } else {
+ if (chan == old_RTSI_clock_channel)
+ return NI_RTSI_OUTPUT_RTSI_OSC;
+ rt_printk("%s: bug! should never get here?\n", __FUNCTION__);
+ return 0;
+ }
+}
+
+static int ni_rtsi_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int chan = CR_CHAN(insn->chanspec);
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ if (chan < num_configurable_rtsi_channels(dev)) {
+ devpriv->rtsi_trig_direction_reg |=
+ RTSI_Output_Bit(chan,
+ (boardtype.reg_type & ni_reg_m_series_mask) !=
+ 0);
+ } else if (chan == old_RTSI_clock_channel) {
+ devpriv->rtsi_trig_direction_reg |=
+ Drive_RTSI_Clock_Bit;
+ }
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ if (chan < num_configurable_rtsi_channels(dev)) {
+ devpriv->rtsi_trig_direction_reg &=
+ ~RTSI_Output_Bit(chan,
+ (boardtype.reg_type & ni_reg_m_series_mask) !=
+ 0);
+ } else if (chan == old_RTSI_clock_channel) {
+ devpriv->rtsi_trig_direction_reg &=
+ ~Drive_RTSI_Clock_Bit;
+ }
+ devpriv->stc_writew(dev, devpriv->rtsi_trig_direction_reg,
+ RTSI_Trig_Direction_Register);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ if (chan < num_configurable_rtsi_channels(dev)) {
+ data[1] =
+ (devpriv->
+ rtsi_trig_direction_reg & RTSI_Output_Bit(chan,
+ (boardtype.
+ reg_type & ni_reg_m_series_mask)
+ !=
+ 0)) ? INSN_CONFIG_DIO_OUTPUT :
+ INSN_CONFIG_DIO_INPUT;
+ } else if (chan == old_RTSI_clock_channel) {
+ data[1] =
+ (devpriv->
+ rtsi_trig_direction_reg & Drive_RTSI_Clock_Bit)
+ ? INSN_CONFIG_DIO_OUTPUT :
+ INSN_CONFIG_DIO_INPUT;
+ }
+ return 2;
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ return ni_set_master_clock(dev, data[1], data[2]);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ data[1] = devpriv->clock_source;
+ data[2] = devpriv->clock_ns;
+ return 3;
+ break;
+ case INSN_CONFIG_SET_ROUTING:
+ return ni_set_rtsi_routing(dev, chan, data[1]);
+ break;
+ case INSN_CONFIG_GET_ROUTING:
+ data[1] = ni_get_rtsi_routing(dev, chan);
+ return 2;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 1;
+}
+
+static int cs5529_wait_for_idle(struct comedi_device * dev)
+{
+ unsigned short status;
+ const int timeout = HZ;
+ int i;
+
+ for (i = 0; i < timeout; i++) {
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if ((status & CSS_ADC_BUSY) == 0) {
+ break;
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (schedule_timeout(1)) {
+ return -EIO;
+ }
+ }
+//printk("looped %i times waiting for idle\n", i);
+ if (i == timeout) {
+ rt_printk("%s: %s: timeout\n", __FILE__, __FUNCTION__);
+ return -ETIME;
+ }
+ return 0;
+}
+
+static void cs5529_command(struct comedi_device * dev, unsigned short value)
+{
+ static const int timeout = 100;
+ int i;
+
+ ni_ao_win_outw(dev, value, CAL_ADC_Command_67xx);
+ /* give time for command to start being serially clocked into cs5529.
+ * this insures that the CSS_ADC_BUSY bit will get properly
+ * set before we exit this function.
+ */
+ for (i = 0; i < timeout; i++) {
+ if ((ni_ao_win_inw(dev, CAL_ADC_Status_67xx) & CSS_ADC_BUSY))
+ break;
+ comedi_udelay(1);
+ }
+//printk("looped %i times writing command to cs5529\n", i);
+ if (i == timeout) {
+ comedi_error(dev, "possible problem - never saw adc go busy?");
+ }
+}
+
+/* write to cs5529 register */
+static void cs5529_config_write(struct comedi_device * dev, unsigned int value,
+ unsigned int reg_select_bits)
+{
+ ni_ao_win_outw(dev, ((value >> 16) & 0xff),
+ CAL_ADC_Config_Data_High_Word_67xx);
+ ni_ao_win_outw(dev, (value & 0xffff),
+ CAL_ADC_Config_Data_Low_Word_67xx);
+ reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+ cs5529_command(dev, CSCMD_COMMAND | reg_select_bits);
+ if (cs5529_wait_for_idle(dev))
+ comedi_error(dev, "time or signal in cs5529_config_write()");
+}
+
+#ifdef NI_CS5529_DEBUG
+/* read from cs5529 register */
+static unsigned int cs5529_config_read(struct comedi_device * dev,
+ unsigned int reg_select_bits)
+{
+ unsigned int value;
+
+ reg_select_bits &= CSCMD_REGISTER_SELECT_MASK;
+ cs5529_command(dev, CSCMD_COMMAND | CSCMD_READ | reg_select_bits);
+ if (cs5529_wait_for_idle(dev))
+ comedi_error(dev, "timeout or signal in cs5529_config_read()");
+ value = (ni_ao_win_inw(dev,
+ CAL_ADC_Config_Data_High_Word_67xx) << 16) & 0xff0000;
+ value |= ni_ao_win_inw(dev, CAL_ADC_Config_Data_Low_Word_67xx) & 0xffff;
+ return value;
+}
+#endif
+
+static int cs5529_do_conversion(struct comedi_device * dev, unsigned short *data)
+{
+ int retval;
+ unsigned short status;
+
+ cs5529_command(dev, CSCMD_COMMAND | CSCMD_SINGLE_CONVERSION);
+ retval = cs5529_wait_for_idle(dev);
+ if (retval) {
+ comedi_error(dev,
+ "timeout or signal in cs5529_do_conversion()");
+ return -ETIME;
+ }
+ status = ni_ao_win_inw(dev, CAL_ADC_Status_67xx);
+ if (status & CSS_OSC_DETECT) {
+ rt_printk
+ ("ni_mio_common: cs5529 conversion error, status CSS_OSC_DETECT\n");
+ return -EIO;
+ }
+ if (status & CSS_OVERRANGE) {
+ rt_printk
+ ("ni_mio_common: cs5529 conversion error, overrange (ignoring)\n");
+ }
+ if (data) {
+ *data = ni_ao_win_inw(dev, CAL_ADC_Data_67xx);
+ /* cs5529 returns 16 bit signed data in bipolar mode */
+ *data ^= (1 << 15);
+ }
+ return 0;
+}
+
+static int cs5529_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, retval;
+ unsigned short sample;
+ unsigned int channel_select;
+ const unsigned int INTERNAL_REF = 0x1000;
+
+ /* Set calibration adc source. Docs lie, reference select bits 8 to 11
+ * do nothing. bit 12 seems to chooses internal reference voltage, bit
+ * 13 causes the adc input to go overrange (maybe reads external reference?) */
+ if (insn->chanspec & CR_ALT_SOURCE)
+ channel_select = INTERNAL_REF;
+ else
+ channel_select = CR_CHAN(insn->chanspec);
+ ni_ao_win_outw(dev, channel_select, AO_Calibration_Channel_Select_67xx);
+
+ for (n = 0; n < insn->n; n++) {
+ retval = cs5529_do_conversion(dev, &sample);
+ if (retval < 0)
+ return retval;
+ data[n] = sample;
+ }
+ return insn->n;
+}
+
+static int init_cs5529(struct comedi_device * dev)
+{
+ unsigned int config_bits =
+ CSCFG_PORT_MODE | CSCFG_WORD_RATE_2180_CYCLES;
+
+#if 1
+ /* do self-calibration */
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET_GAIN,
+ CSCMD_CONFIG_REGISTER);
+ /* need to force a conversion for calibration to run */
+ cs5529_do_conversion(dev, NULL);
+#else
+ /* force gain calibration to 1 */
+ cs5529_config_write(dev, 0x400000, CSCMD_GAIN_REGISTER);
+ cs5529_config_write(dev, config_bits | CSCFG_SELF_CAL_OFFSET,
+ CSCMD_CONFIG_REGISTER);
+ if (cs5529_wait_for_idle(dev))
+ comedi_error(dev, "timeout or signal in init_cs5529()\n");
+#endif
+#ifdef NI_CS5529_DEBUG
+ rt_printk("config: 0x%x\n", cs5529_config_read(dev,
+ CSCMD_CONFIG_REGISTER));
+ rt_printk("gain: 0x%x\n", cs5529_config_read(dev,
+ CSCMD_GAIN_REGISTER));
+ rt_printk("offset: 0x%x\n", cs5529_config_read(dev,
+ CSCMD_OFFSET_REGISTER));
+#endif
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_mio_cs.c b/drivers/staging/comedi/drivers/ni_mio_cs.c
new file mode 100644
index 00000000000..d6357c25aca
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_mio_cs.c
@@ -0,0 +1,551 @@
+/*
+ comedi/drivers/ni_mio_cs.c
+ Hardware driver for NI PCMCIA MIO E series cards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_mio_cs
+Description: National Instruments DAQCard E series
+Author: ds
+Status: works
+Devices: [National Instruments] DAQCard-AI-16XE-50 (ni_mio_cs),
+ DAQCard-AI-16E-4, DAQCard-6062E, DAQCard-6024E, DAQCard-6036E
+Updated: Thu Oct 23 19:43:17 CDT 2003
+
+See the notes in the ni_atmio.o driver.
+*/
+/*
+ The real guts of the driver is in ni_mio_common.c, which is
+ included by all the E series drivers.
+
+ References for specifications:
+
+ 341080a.pdf DAQCard E Series Register Level Programmer Manual
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+
+#include "ni_stc.h"
+#include "8255.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+
+#undef DEBUG
+
+#define ATMIO 1
+#undef PCIMIO
+
+/*
+ * AT specific setup
+ */
+
+#define NI_SIZE 0x20
+
+#define MAX_N_CALDACS 32
+
+static const ni_board ni_boards[] = {
+ {device_id:0x010d,
+ name: "DAQCard-ai-16xe-50",
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:1024,
+ alwaysdither:0,
+ gainlkup:ai_gain_8,
+ ai_speed:5000,
+ n_aochan:0,
+ aobits: 0,
+ ao_fifo_depth:0,
+ ao_unipolar:0,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {dac8800, dac8043},
+ },
+ {device_id:0x010c,
+ name: "DAQCard-ai-16e-4",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:1024,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:4000,
+ n_aochan:0,
+ aobits: 0,
+ ao_fifo_depth:0,
+ ao_unipolar:0,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {mb88341}, /* verified */
+ },
+ {device_id:0x02c4,
+ name: "DAQCard-6062E",
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:8192,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:2000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:2048,
+ ao_range_table:&range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:1176,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {ad8804_debug}, /* verified */
+ },
+ {device_id:0x075e,
+ name: "DAQCard-6024E", /* specs incorrect! */
+ n_adchan:16,
+ adbits: 12,
+ ai_fifo_depth:1024,
+ alwaysdither:0,
+ gainlkup:ai_gain_16,
+ ai_speed:5000,
+ n_aochan:2,
+ aobits: 12,
+ ao_fifo_depth:0,
+ ao_range_table:&range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:1000000,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {ad8804_debug},
+ },
+ {device_id:0x0245,
+ name: "DAQCard-6036E", /* specs incorrect! */
+ n_adchan:16,
+ adbits: 16,
+ ai_fifo_depth:1024,
+ alwaysdither:1,
+ gainlkup:ai_gain_4,
+ ai_speed:5000,
+ n_aochan:2,
+ aobits: 16,
+ ao_fifo_depth:0,
+ ao_range_table:&range_bipolar10,
+ ao_unipolar:0,
+ ao_speed:1000000,
+ num_p0_dio_channels:8,
+ has_8255:0,
+ caldac: {ad8804_debug},
+ },
+#if 0
+ {device_id:0x0000, /* unknown */
+ name: "DAQCard-6715",
+ n_adchan:0,
+ n_aochan:8,
+ aobits: 12,
+ ao_671x: 8192,
+ num_p0_dio_channels:8,
+ caldac: {mb88341, mb88341},
+ },
+#endif
+ /* N.B. Update ni_mio_cs_ids[] when entries added above. */
+};
+
+#define interrupt_pin(a) 0
+
+#define IRQ_POLARITY 1
+
+#define NI_E_IRQ_FLAGS IRQF_SHARED
+
+struct ni_private {
+
+ struct pcmcia_device *link;
+
+ NI_PRIVATE_COMMON};
+
+#define devpriv ((struct ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b) (outl((a),(b)+dev->iobase))
+#define ni_readl(a) (inl((a)+dev->iobase))
+#define ni_writew(a,b) (outw((a),(b)+dev->iobase))
+#define ni_readw(a) (inw((a)+dev->iobase))
+#define ni_writeb(a,b) (outb((a),(b)+dev->iobase))
+#define ni_readb(a) (inb((a)+dev->iobase))
+
+/* How we access windowed registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board. The
+ * DAQCard devices map the low 8 STC registers to iobase+addr*2. */
+
+static void mio_cs_win_out(struct comedi_device * dev, uint16_t data, int addr)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (addr < 8) {
+ ni_writew(data, addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ni_writew(data, Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t mio_cs_win_in(struct comedi_device * dev, int addr)
+{
+ unsigned long flags;
+ uint16_t ret;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ if (addr < 8) {
+ ret = ni_readw(addr * 2);
+ } else {
+ ni_writew(addr, Window_Address);
+ ret = ni_readw(Window_Data);
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+ return ret;
+}
+
+static int mio_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int mio_cs_detach(struct comedi_device * dev);
+static struct comedi_driver driver_ni_mio_cs = {
+ driver_name:"ni_mio_cs",
+ module:THIS_MODULE,
+ attach:mio_cs_attach,
+ detach:mio_cs_detach,
+};
+
+#include "ni_mio_common.c"
+
+static int ni_getboardtype(struct comedi_device * dev, struct pcmcia_device *link);
+
+/* clean up allocated resources */
+/* called when driver is removed */
+static int mio_cs_detach(struct comedi_device * dev)
+{
+ mio_common_detach(dev);
+
+ /* PCMCIA layer frees the IO region */
+
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+
+ return 0;
+}
+
+static void mio_cs_config(struct pcmcia_device *link);
+static void cs_release(struct pcmcia_device *link);
+static void cs_detach(struct pcmcia_device *);
+
+static struct pcmcia_device *cur_dev = NULL;
+static const dev_info_t dev_info = "ni_mio_cs";
+static dev_node_t dev_node = {
+ "ni_mio_cs",
+ COMEDI_MAJOR, 0,
+ NULL
+};
+static int cs_attach(struct pcmcia_device *link)
+{
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ link->io.NumPorts1 = 16;
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->conf.Attributes = CONF_ENABLE_IRQ;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ cur_dev = link;
+
+ mio_cs_config(link);
+
+ return 0;
+}
+
+static void cs_release(struct pcmcia_device *link)
+{
+ pcmcia_disable_device(link);
+}
+
+static void cs_detach(struct pcmcia_device *link)
+{
+ DPRINTK("cs_detach(link=%p)\n", link);
+
+ if (link->dev_node) {
+ cs_release(link);
+ }
+}
+
+static int mio_cs_suspend(struct pcmcia_device *link)
+{
+ DPRINTK("pm suspend\n");
+
+ return 0;
+}
+
+static int mio_cs_resume(struct pcmcia_device *link)
+{
+ DPRINTK("pm resume\n");
+ return 0;
+}
+
+static void mio_cs_config(struct pcmcia_device *link)
+{
+ tuple_t tuple;
+ u_short buf[128];
+ cisparse_t parse;
+ int manfid = 0, prodid = 0;
+ int ret;
+
+ DPRINTK("mio_cs_config(link=%p)\n", link);
+
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.Attributes = 0;
+
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ ret = pcmcia_get_first_tuple(link, &tuple);
+ ret = pcmcia_get_tuple_data(link, &tuple);
+ ret = pcmcia_parse_tuple(&tuple, &parse);
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+#if 0
+ tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
+ tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;
+ info->multi(first_tuple(link, &tuple, &parse) == 0);
+#endif
+
+ tuple.DesiredTuple = CISTPL_MANFID;
+ tuple.Attributes = TUPLE_RETURN_COMMON;
+ if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+ (pcmcia_get_tuple_data(link, &tuple) == 0)) {
+ manfid = le16_to_cpu(buf[0]);
+ prodid = le16_to_cpu(buf[1]);
+ }
+ //printk("manfid = 0x%04x, 0x%04x\n",manfid,prodid);
+
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ tuple.Attributes = 0;
+ ret = pcmcia_get_first_tuple(link, &tuple);
+ ret = pcmcia_get_tuple_data(link, &tuple);
+ ret = pcmcia_parse_tuple(&tuple, &parse);
+
+#if 0
+ printk(" index: 0x%x\n", parse.cftable_entry.index);
+ printk(" flags: 0x%x\n", parse.cftable_entry.flags);
+ printk(" io flags: 0x%x\n", parse.cftable_entry.io.flags);
+ printk(" io nwin: 0x%x\n", parse.cftable_entry.io.nwin);
+ printk(" io base: 0x%x\n", parse.cftable_entry.io.win[0].base);
+ printk(" io len: 0x%x\n", parse.cftable_entry.io.win[0].len);
+ printk(" irq1: 0x%x\n", parse.cftable_entry.irq.IRQInfo1);
+ printk(" irq2: 0x%x\n", parse.cftable_entry.irq.IRQInfo2);
+ printk(" mem flags: 0x%x\n", parse.cftable_entry.mem.flags);
+ printk(" mem nwin: 0x%x\n", parse.cftable_entry.mem.nwin);
+ printk(" subtuples: 0x%x\n", parse.cftable_entry.subtuples);
+#endif
+
+#if 0
+ link->io.NumPorts1 = 0x20;
+ link->io.IOAddrLines = 5;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+#endif
+ link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
+ link->io.IOAddrLines =
+ parse.cftable_entry.io.flags & CISTPL_IO_LINES_MASK;
+ link->io.NumPorts2 = 0;
+
+ {
+ int base;
+ for (base = 0x000; base < 0x400; base += 0x20) {
+ link->io.BasePort1 = base;
+ ret = pcmcia_request_io(link, &link->io);
+ //printk("RequestIO 0x%02x\n",ret);
+ if (!ret)
+ break;
+ }
+ }
+
+ link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
+ link->irq.IRQInfo2 = parse.cftable_entry.irq.IRQInfo2;
+ ret = pcmcia_request_irq(link, &link->irq);
+ if (ret) {
+ printk("pcmcia_request_irq() returned error: %i\n", ret);
+ }
+ //printk("RequestIRQ 0x%02x\n",ret);
+
+ link->conf.ConfigIndex = 1;
+
+ ret = pcmcia_request_configuration(link, &link->conf);
+ //printk("RequestConfiguration %d\n",ret);
+
+ link->dev_node = &dev_node;
+}
+
+static int mio_cs_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct pcmcia_device *link;
+ unsigned int irq;
+ int ret;
+
+ DPRINTK("mio_cs_attach(dev=%p,it=%p)\n", dev, it);
+
+ link = cur_dev; /* XXX hack */
+ if (!link)
+ return -EIO;
+
+ dev->driver = &driver_ni_mio_cs;
+ dev->iobase = link->io.BasePort1;
+
+ irq = link->irq.AssignedIRQ;
+
+ printk("comedi%d: %s: DAQCard: io 0x%04lx, irq %u, ",
+ dev->minor, dev->driver->driver_name, dev->iobase, irq);
+
+#if 0
+ {
+ int i;
+
+ printk(" board fingerprint:");
+ for (i = 0; i < 32; i += 2) {
+ printk(" %04x %02x", inw(dev->iobase + i),
+ inb(dev->iobase + i + 1));
+ }
+ printk("\n");
+ printk(" board fingerprint (windowed):");
+ for (i = 0; i < 10; i++) {
+ printk(" 0x%04x", win_in(i));
+ }
+ printk("\n");
+ }
+#endif
+
+ dev->board_ptr = ni_boards + ni_getboardtype(dev, link);
+
+ printk(" %s", boardtype.name);
+ dev->board_name = boardtype.name;
+
+ if ((ret = comedi_request_irq(irq, ni_E_interrupt, NI_E_IRQ_FLAGS,
+ "ni_mio_cs", dev)) < 0) {
+ printk(" irq not available\n");
+ return -EINVAL;
+ }
+ dev->irq = irq;
+
+ /* allocate private area */
+ if ((ret = ni_alloc_private(dev)) < 0)
+ return ret;
+ devpriv->stc_writew = &mio_cs_win_out;
+ devpriv->stc_readw = &mio_cs_win_in;
+ devpriv->stc_writel = &win_out2;
+ devpriv->stc_readl = &win_in2;
+
+ if ((ret = ni_E_init(dev, it)) < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
+static int get_prodid(struct comedi_device * dev, struct pcmcia_device *link)
+{
+ tuple_t tuple;
+ u_short buf[128];
+ int prodid = 0;
+
+ tuple.TupleData = (cisdata_t *) buf;
+ tuple.TupleOffset = 0;
+ tuple.TupleDataMax = 255;
+ tuple.DesiredTuple = CISTPL_MANFID;
+ tuple.Attributes = TUPLE_RETURN_COMMON;
+ if ((pcmcia_get_first_tuple(link, &tuple) == 0) &&
+ (pcmcia_get_tuple_data(link, &tuple) == 0)) {
+ prodid = le16_to_cpu(buf[1]);
+ }
+
+ return prodid;
+}
+
+static int ni_getboardtype(struct comedi_device * dev, struct pcmcia_device *link)
+{
+ int id;
+ int i;
+
+ id = get_prodid(dev, link);
+
+ for (i = 0; i < n_ni_boards; i++) {
+ if (ni_boards[i].device_id == id) {
+ return i;
+ }
+ }
+
+ printk("unknown board 0x%04x -- pretend it is a ", id);
+
+ return 0;
+}
+
+#ifdef MODULE
+
+MODULE_LICENSE("GPL");
+
+static struct pcmcia_device_id ni_mio_cs_ids[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010d), /* DAQCard-ai-16xe-50 */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x010c), /* DAQCard-ai-16e-4 */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x02c4), /* DAQCard-6062E */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x075e), /* DAQCard-6024E */
+ PCMCIA_DEVICE_MANF_CARD(0x010b, 0x0245), /* DAQCard-6036E */
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, ni_mio_cs_ids);
+
+struct pcmcia_driver ni_mio_cs_driver = {
+ .probe = &cs_attach,
+ .remove = &cs_detach,
+ .suspend = &mio_cs_suspend,
+ .resume = &mio_cs_resume,
+ .id_table = ni_mio_cs_ids,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+int init_module(void)
+{
+ pcmcia_register_driver(&ni_mio_cs_driver);
+ comedi_driver_register(&driver_ni_mio_cs);
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ pcmcia_unregister_driver(&ni_mio_cs_driver);
+#if 0
+ while (cur_dev != NULL)
+ cs_detach(cur_dev->handle);
+#endif
+ comedi_driver_unregister(&driver_ni_mio_cs);
+}
+#endif
diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c
new file mode 100644
index 00000000000..87def2cc9a2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_pcidio.c
@@ -0,0 +1,1302 @@
+/*
+ comedi/drivers/ni_pcidio.c
+ driver for National Instruments PCI-DIO-96/PCI-6508
+ National Instruments PCI-DIO-32HS
+ National Instruments PCI-6503
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999,2002 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ni_pcidio
+Description: National Instruments PCI-DIO32HS, PCI-DIO96, PCI-6533, PCI-6503
+Author: ds
+Status: works
+Devices: [National Instruments] PCI-DIO-32HS (ni_pcidio), PXI-6533,
+ PCI-DIO-96, PCI-DIO-96B, PXI-6508, PCI-6503, PCI-6503B, PCI-6503X,
+ PXI-6503, PCI-6533, PCI-6534
+Updated: Sun, 21 Apr 2002 21:03:38 -0700
+
+The DIO-96 appears as four 8255 subdevices. See the 8255
+driver notes for details.
+
+The DIO32HS board appears as one subdevice, with 32 channels.
+Each channel is individually I/O configurable. The channel order
+is 0=A0, 1=A1, 2=A2, ... 8=B0, 16=C0, 24=D0. The driver only
+supports simple digital I/O; no handshaking is supported.
+
+DMA mostly works for the PCI-DIO32HS, but only in timed input mode.
+
+This driver could be easily modified to support AT-MIO32HS and
+AT-MIO96.
+
+The PCI-6534 requires a firmware upload after power-up to work, the
+firmware data and instructions for loading it with comedi_config
+it are contained in the
+comedi_nonfree_firmware tarball available from http://www.comedi.org
+*/
+
+/*
+ This driver is for both the NI PCI-DIO-32HS and the PCI-DIO-96,
+ which have very different architectures. But, since the '96 is
+ so simple, it is included here.
+
+ Manuals (available from ftp://ftp.natinst.com/support/manuals)
+
+ 320938c.pdf PCI-DIO-96/PXI-6508/PCI-6503 User Manual
+ 321464b.pdf AT/PCI-DIO-32HS User Manual
+ 341329A.pdf PCI-6533 Register-Level Programmer Manual
+ 341330A.pdf DAQ-DIO Technical Reference Manual
+
+ */
+
+#define USE_DMA
+//#define DEBUG 1
+//#define DEBUG_FLAGS
+
+#include "../comedidev.h"
+
+#include "mite.h"
+#include "8255.h"
+
+#undef DPRINTK
+#ifdef DEBUG
+#define DPRINTK(format, args...) printk(format, ## args)
+#else
+#define DPRINTK(format, args...)
+#endif
+
+#define PCI_VENDOR_ID_NATINST 0x1093
+
+#define PCI_DIO_SIZE 4096
+#define PCI_MITE_SIZE 4096
+
+/* defines for the PCI-DIO-96 */
+
+#define NIDIO_8255_BASE(x) ((x)*4)
+#define NIDIO_A 0
+#define NIDIO_B 4
+#define NIDIO_C 8
+#define NIDIO_D 12
+
+/* defines for the PCI-DIO-32HS */
+
+#define Window_Address 4 /* W */
+#define Interrupt_And_Window_Status 4 /* R */
+#define IntStatus1 (1<<0)
+#define IntStatus2 (1<<1)
+#define WindowAddressStatus_mask 0x7c
+
+#define Master_DMA_And_Interrupt_Control 5 /* W */
+#define InterruptLine(x) ((x)&3)
+#define OpenInt (1<<2)
+#define Group_Status 5 /* R */
+#define DataLeft (1<<0)
+#define Req (1<<2)
+#define StopTrig (1<<3)
+
+#define Group_1_Flags 6 /* R */
+#define Group_2_Flags 7 /* R */
+#define TransferReady (1<<0)
+#define CountExpired (1<<1)
+#define Waited (1<<5)
+#define PrimaryTC (1<<6)
+#define SecondaryTC (1<<7)
+ //#define SerialRose
+ //#define ReqRose
+ //#define Paused
+
+#define Group_1_First_Clear 6 /* W */
+#define Group_2_First_Clear 7 /* W */
+#define ClearWaited (1<<3)
+#define ClearPrimaryTC (1<<4)
+#define ClearSecondaryTC (1<<5)
+#define DMAReset (1<<6)
+#define FIFOReset (1<<7)
+#define ClearAll 0xf8
+
+#define Group_1_FIFO 8 /* W */
+#define Group_2_FIFO 12 /* W */
+
+#define Transfer_Count 20
+#define Chip_ID_D 24
+#define Chip_ID_I 25
+#define Chip_ID_O 26
+#define Chip_Version 27
+#define Port_IO(x) (28+(x))
+#define Port_Pin_Directions(x) (32+(x))
+#define Port_Pin_Mask(x) (36+(x))
+#define Port_Pin_Polarities(x) (40+(x))
+
+#define Master_Clock_Routing 45
+#define RTSIClocking(x) (((x)&3)<<4)
+
+#define Group_1_Second_Clear 46 /* W */
+#define Group_2_Second_Clear 47 /* W */
+#define ClearExpired (1<<0)
+
+#define Port_Pattern(x) (48+(x))
+
+#define Data_Path 64
+#define FIFOEnableA (1<<0)
+#define FIFOEnableB (1<<1)
+#define FIFOEnableC (1<<2)
+#define FIFOEnableD (1<<3)
+#define Funneling(x) (((x)&3)<<4)
+#define GroupDirection (1<<7)
+
+#define Protocol_Register_1 65
+#define OpMode Protocol_Register_1
+#define RunMode(x) ((x)&7)
+#define Numbered (1<<3)
+
+#define Protocol_Register_2 66
+#define ClockReg Protocol_Register_2
+#define ClockLine(x) (((x)&3)<<5)
+#define InvertStopTrig (1<<7)
+#define DataLatching(x) (((x)&3)<<5)
+
+#define Protocol_Register_3 67
+#define Sequence Protocol_Register_3
+
+#define Protocol_Register_14 68 /* 16 bit */
+#define ClockSpeed Protocol_Register_14
+
+#define Protocol_Register_4 70
+#define ReqReg Protocol_Register_4
+#define ReqConditioning(x) (((x)&7)<<3)
+
+#define Protocol_Register_5 71
+#define BlockMode Protocol_Register_5
+
+#define FIFO_Control 72
+#define ReadyLevel(x) ((x)&7)
+
+#define Protocol_Register_6 73
+#define LinePolarities Protocol_Register_6
+#define InvertAck (1<<0)
+#define InvertReq (1<<1)
+#define InvertClock (1<<2)
+#define InvertSerial (1<<3)
+#define OpenAck (1<<4)
+#define OpenClock (1<<5)
+
+#define Protocol_Register_7 74
+#define AckSer Protocol_Register_7
+#define AckLine(x) (((x)&3)<<2)
+#define ExchangePins (1<<7)
+
+#define Interrupt_Control 75
+ /* bits same as flags */
+
+#define DMA_Line_Control_Group1 76
+#define DMA_Line_Control_Group2 108
+// channel zero is none
+static inline unsigned primary_DMAChannel_bits(unsigned channel)
+{
+ return channel & 0x3;
+}
+static inline unsigned secondary_DMAChannel_bits(unsigned channel)
+{
+ return (channel << 2) & 0xc;
+}
+
+#define Transfer_Size_Control 77
+#define TransferWidth(x) ((x)&3)
+#define TransferLength(x) (((x)&3)<<3)
+#define RequireRLevel (1<<5)
+
+#define Protocol_Register_15 79
+#define DAQOptions Protocol_Register_15
+#define StartSource(x) ((x)&0x3)
+#define InvertStart (1<<2)
+#define StopSource(x) (((x)&0x3)<<3)
+#define ReqStart (1<<6)
+#define PreStart (1<<7)
+
+#define Pattern_Detection 81
+#define DetectionMethod (1<<0)
+#define InvertMatch (1<<1)
+#define IE_Pattern_Detection (1<<2)
+
+#define Protocol_Register_9 82
+#define ReqDelay Protocol_Register_9
+
+#define Protocol_Register_10 83
+#define ReqNotDelay Protocol_Register_10
+
+#define Protocol_Register_11 84
+#define AckDelay Protocol_Register_11
+
+#define Protocol_Register_12 85
+#define AckNotDelay Protocol_Register_12
+
+#define Protocol_Register_13 86
+#define Data1Delay Protocol_Register_13
+
+#define Protocol_Register_8 88 /* 32 bit */
+#define StartDelay Protocol_Register_8
+
+enum pci_6534_firmware_registers { /* 16 bit */
+ Firmware_Control_Register = 0x100,
+ Firmware_Status_Register = 0x104,
+ Firmware_Data_Register = 0x108,
+ Firmware_Mask_Register = 0x10c,
+ Firmware_Debug_Register = 0x110,
+};
+/* main fpga registers (32 bit)*/
+enum pci_6534_fpga_registers {
+ FPGA_Control1_Register = 0x200,
+ FPGA_Control2_Register = 0x204,
+ FPGA_Irq_Mask_Register = 0x208,
+ FPGA_Status_Register = 0x20c,
+ FPGA_Signature_Register = 0x210,
+ FPGA_SCALS_Counter_Register = 0x280, /*write-clear */
+ FPGA_SCAMS_Counter_Register = 0x284, /*write-clear */
+ FPGA_SCBLS_Counter_Register = 0x288, /*write-clear */
+ FPGA_SCBMS_Counter_Register = 0x28c, /*write-clear */
+ FPGA_Temp_Control_Register = 0x2a0,
+ FPGA_DAR_Register = 0x2a8,
+ FPGA_ELC_Read_Register = 0x2b8,
+ FPGA_ELC_Write_Register = 0x2bc,
+};
+enum FPGA_Control_Bits {
+ FPGA_Enable_Bit = 0x8000,
+};
+
+#define TIMER_BASE 50 /* nanoseconds */
+
+#ifdef USE_DMA
+#define IntEn (CountExpired|Waited|PrimaryTC|SecondaryTC)
+#else
+#define IntEn (TransferReady|CountExpired|Waited|PrimaryTC|SecondaryTC)
+#endif
+
+static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int nidio_detach(struct comedi_device * dev);
+static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+
+static struct comedi_driver driver_pcidio = {
+ driver_name:"ni_pcidio",
+ module:THIS_MODULE,
+ attach:nidio_attach,
+ detach:nidio_detach,
+};
+
+struct nidio_board {
+
+ int dev_id;
+ const char *name;
+ int n_8255;
+ unsigned int is_diodaq:1;
+ unsigned int uses_firmware:1;
+};
+
+static const struct nidio_board nidio_boards[] = {
+ {
+ dev_id: 0x1150,
+ name: "pci-dio-32hs",
+ n_8255: 0,
+ is_diodaq:1,
+ },
+ {
+ dev_id: 0x1320,
+ name: "pxi-6533",
+ n_8255: 0,
+ is_diodaq:1,
+ },
+ {
+ dev_id: 0x12b0,
+ name: "pci-6534",
+ n_8255: 0,
+ is_diodaq:1,
+ uses_firmware:1,
+ },
+ {
+ dev_id: 0x0160,
+ name: "pci-dio-96",
+ n_8255: 4,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x1630,
+ name: "pci-dio-96b",
+ n_8255: 4,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x13c0,
+ name: "pxi-6508",
+ n_8255: 4,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x0400,
+ name: "pci-6503",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x1250,
+ name: "pci-6503b",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x17d0,
+ name: "pci-6503x",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+ {
+ dev_id: 0x1800,
+ name: "pxi-6503",
+ n_8255: 1,
+ is_diodaq:0,
+ },
+};
+
+#define n_nidio_boards (sizeof(nidio_boards)/sizeof(nidio_boards[0]))
+#define this_board ((const struct nidio_board *)dev->board_ptr)
+
+static DEFINE_PCI_DEVICE_TABLE(ni_pcidio_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x1150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x12b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x0160, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1630, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x13c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x0400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1250, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x17d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_pcidio_pci_table);
+
+struct nidio96_private {
+ struct mite_struct *mite;
+ int boardtype;
+ int dio;
+ unsigned short OpModeBits;
+ struct mite_channel *di_mite_chan;
+ struct mite_dma_descriptor_ring *di_mite_ring;
+ spinlock_t mite_channel_lock;
+};
+#define devpriv ((struct nidio96_private *)dev->private)
+
+static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum);
+static int nidio_find_device(struct comedi_device * dev, int bus, int slot);
+static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode);
+static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s);
+
+#ifdef DEBUG_FLAGS
+static void ni_pcidio_print_flags(unsigned int flags);
+static void ni_pcidio_print_status(unsigned int status);
+#else
+#define ni_pcidio_print_flags(x)
+#define ni_pcidio_print_status(x)
+#endif
+
+static int ni_pcidio_request_di_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ BUG_ON(devpriv->di_mite_chan);
+ devpriv->di_mite_chan =
+ mite_request_channel_in_range(devpriv->mite,
+ devpriv->di_mite_ring, 1, 2);
+ if (devpriv->di_mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock,
+ flags);
+ comedi_error(dev, "failed to reserve mite dma channel.");
+ return -EBUSY;
+ }
+ writeb(primary_DMAChannel_bits(devpriv->di_mite_chan->channel) |
+ secondary_DMAChannel_bits(devpriv->di_mite_chan->channel),
+ devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+ return 0;
+}
+
+static void ni_pcidio_release_di_mite_channel(struct comedi_device * dev)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, flags);
+ if (devpriv->di_mite_chan) {
+ mite_dma_disarm(devpriv->di_mite_chan);
+ mite_dma_reset(devpriv->di_mite_chan);
+ mite_release_channel(devpriv->di_mite_chan);
+ devpriv->di_mite_chan = NULL;
+ writeb(primary_DMAChannel_bits(0) |
+ secondary_DMAChannel_bits(0),
+ devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+ mmiowb();
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, flags);
+}
+
+static int nidio96_8255_cb(int dir, int port, int data, unsigned long iobase)
+{
+ if (dir) {
+ writeb(data, (void *)(iobase + port));
+ return 0;
+ } else {
+ return readb((void *)(iobase + port));
+ }
+}
+
+void ni_pcidio_event(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (s->async->
+ events & (COMEDI_CB_EOA | COMEDI_CB_ERROR | COMEDI_CB_OVERFLOW))
+ {
+ ni_pcidio_cancel(dev, s);
+ }
+ comedi_event(dev, s);
+}
+
+static irqreturn_t nidio_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices;
+ struct comedi_async *async = s->async;
+ struct mite_struct *mite = devpriv->mite;
+
+ //int i, j;
+ long int AuxData = 0;
+ short data1 = 0;
+ short data2 = 0;
+ int flags;
+ int status;
+ int work = 0;
+ unsigned int m_status = 0;
+ unsigned long irq_flags;
+
+ //interrupcions parasites
+ if (dev->attached == 0) {
+ // assume it's from another card
+ return IRQ_NONE;
+ }
+
+ status = readb(devpriv->mite->daq_io_addr +
+ Interrupt_And_Window_Status);
+ flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+ DPRINTK("ni_pcidio_interrupt: status=0x%02x,flags=0x%02x\n",
+ status, flags);
+ ni_pcidio_print_flags(flags);
+ ni_pcidio_print_status(status);
+
+ //printk("buf[0]=%08x\n",*(unsigned int *)async->prealloc_buf);
+ //printk("buf[4096]=%08x\n",*(unsigned int *)(async->prealloc_buf+4096));
+
+ comedi_spin_lock_irqsave(&devpriv->mite_channel_lock, irq_flags);
+ if (devpriv->di_mite_chan)
+ m_status = mite_get_status(devpriv->di_mite_chan);
+#ifdef MITE_DEBUG
+ mite_print_chsr(m_status);
+#endif
+ //printk("mite_bytes_transferred: %d\n",mite_bytes_transferred(mite,DI_DMA_CHAN));
+ //mite_dump_regs(mite);
+ if (m_status & CHSR_INT) {
+ if (m_status & CHSR_LINKC) {
+ writel(CHOR_CLRLC,
+ mite->mite_io_addr +
+ MITE_CHOR(devpriv->di_mite_chan->channel));
+ mite_sync_input_dma(devpriv->di_mite_chan, s->async);
+ /* XXX need to byteswap */
+ }
+ if (m_status & ~(CHSR_INT | CHSR_LINKC | CHSR_DONE | CHSR_DRDY |
+ CHSR_DRQ1 | CHSR_MRDY)) {
+ DPRINTK("unknown mite interrupt, disabling IRQ\n");
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ disable_irq(dev->irq);
+ }
+ }
+ comedi_spin_unlock_irqrestore(&devpriv->mite_channel_lock, irq_flags);
+
+ while (status & DataLeft) {
+ work++;
+ if (work > 20) {
+ DPRINTK("too much work in interrupt\n");
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ break;
+ }
+
+ flags &= IntEn;
+
+ if (flags & TransferReady) {
+ //DPRINTK("TransferReady\n");
+ while (flags & TransferReady) {
+ work++;
+ if (work > 100) {
+ DPRINTK("too much work in interrupt\n");
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ goto out;
+ }
+ AuxData =
+ readl(devpriv->mite->daq_io_addr +
+ Group_1_FIFO);
+ data1 = AuxData & 0xffff;
+ data2 = (AuxData & 0xffff0000) >> 16;
+ comedi_buf_put(async, data1);
+ comedi_buf_put(async, data2);
+ //DPRINTK("read:%d, %d\n",data1,data2);
+ flags = readb(devpriv->mite->daq_io_addr +
+ Group_1_Flags);
+ }
+ //DPRINTK("buf_int_count: %d\n",async->buf_int_count);
+ //DPRINTK("1) IntEn=%d,flags=%d,status=%d\n",IntEn,flags,status);
+ //ni_pcidio_print_flags(flags);
+ //ni_pcidio_print_status(status);
+ async->events |= COMEDI_CB_BLOCK;
+ }
+
+ if (flags & CountExpired) {
+ DPRINTK("CountExpired\n");
+ writeb(ClearExpired,
+ devpriv->mite->daq_io_addr +
+ Group_1_Second_Clear);
+ async->events |= COMEDI_CB_EOA;
+
+ writeb(0x00, devpriv->mite->daq_io_addr + OpMode);
+ break;
+ } else if (flags & Waited) {
+ DPRINTK("Waited\n");
+ writeb(ClearWaited,
+ devpriv->mite->daq_io_addr +
+ Group_1_First_Clear);
+ async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ break;
+ } else if (flags & PrimaryTC) {
+ DPRINTK("PrimaryTC\n");
+ writeb(ClearPrimaryTC,
+ devpriv->mite->daq_io_addr +
+ Group_1_First_Clear);
+ async->events |= COMEDI_CB_EOA;
+ } else if (flags & SecondaryTC) {
+ DPRINTK("SecondaryTC\n");
+ writeb(ClearSecondaryTC,
+ devpriv->mite->daq_io_addr +
+ Group_1_First_Clear);
+ async->events |= COMEDI_CB_EOA;
+ }
+#if 0
+ else {
+ printk("ni_pcidio: unknown interrupt\n");
+ async->events |= COMEDI_CB_ERROR | COMEDI_CB_EOA;
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ }
+#endif
+ flags = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+ status = readb(devpriv->mite->daq_io_addr +
+ Interrupt_And_Window_Status);
+ //DPRINTK("loop end: IntEn=0x%02x,flags=0x%02x,status=0x%02x\n",
+ // IntEn,flags,status);
+ //ni_pcidio_print_flags(flags);
+ //ni_pcidio_print_status(status);
+ }
+
+ out:
+ ni_pcidio_event(dev, s);
+#if 0
+ if (!tag) {
+ writeb(0x03,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+ }
+#endif
+ return IRQ_HANDLED;
+}
+
+#ifdef DEBUG_FLAGS
+static const char *const flags_strings[] = {
+ "TransferReady", "CountExpired", "2", "3",
+ "4", "Waited", "PrimaryTC", "SecondaryTC",
+};
+static void ni_pcidio_print_flags(unsigned int flags)
+{
+ int i;
+
+ printk("group_1_flags:");
+ for (i = 7; i >= 0; i--) {
+ if (flags & (1 << i)) {
+ printk(" %s", flags_strings[i]);
+ }
+ }
+ printk("\n");
+}
+static char *status_strings[] = {
+ "DataLeft1", "Reserved1", "Req1", "StopTrig1",
+ "DataLeft2", "Reserved2", "Req2", "StopTrig2",
+};
+static void ni_pcidio_print_status(unsigned int flags)
+{
+ int i;
+
+ printk("group_status:");
+ for (i = 7; i >= 0; i--) {
+ if (flags & (1 << i)) {
+ printk(" %s", status_strings[i]);
+ }
+ }
+ printk("\n");
+}
+#endif
+
+#ifdef unused
+static void debug_int(struct comedi_device * dev)
+{
+ int a, b;
+ static int n_int = 0;
+ struct timeval tv;
+
+ do_gettimeofday(&tv);
+ a = readb(devpriv->mite->daq_io_addr + Group_Status);
+ b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+ if (n_int < 10) {
+ DPRINTK("status 0x%02x flags 0x%02x time %06d\n", a, b,
+ (int)tv.tv_usec);
+ }
+
+ while (b & 1) {
+ writew(0xff, devpriv->mite->daq_io_addr + Group_1_FIFO);
+ b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+ }
+
+ b = readb(devpriv->mite->daq_io_addr + Group_1_Flags);
+
+ if (n_int < 10) {
+ DPRINTK("new status 0x%02x\n", b);
+ n_int++;
+ }
+}
+#endif
+
+static int ni_pcidio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 1)
+ return -EINVAL;
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << CR_CHAN(insn->chanspec);
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << CR_CHAN(insn->chanspec));
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->io_bits & (1 << CR_CHAN(insn->
+ chanspec))) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+ writel(s->io_bits, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+
+ return 1;
+}
+
+static int ni_pcidio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ writel(s->state, devpriv->mite->daq_io_addr + Port_IO(0));
+ }
+ data[1] = readl(devpriv->mite->daq_io_addr + Port_IO(0));
+
+ return 2;
+}
+
+static int ni_pcidio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW | TRIG_INT;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->start_src != TRIG_NOW && cmd->start_src != TRIG_INT)
+ err++;
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ /* same for both TRIG_INT and TRIG_NOW */
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED (TIMER_BASE) /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ /* no minumum speed */
+ } else {
+ /* TRIG_EXT */
+ /* should be level/edge, hi/lo specification here */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ /* no limit */
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int ni_pcidio_ns_to_timer(int *nanosec, int round_mode)
+{
+ int divider, base;
+
+ base = TIMER_BASE;
+
+ switch (round_mode) {
+ case TRIG_ROUND_NEAREST:
+ default:
+ divider = (*nanosec + base / 2) / base;
+ break;
+ case TRIG_ROUND_DOWN:
+ divider = (*nanosec) / base;
+ break;
+ case TRIG_ROUND_UP:
+ divider = (*nanosec + base - 1) / base;
+ break;
+ }
+
+ *nanosec = base * divider;
+ return divider;
+}
+
+static int ni_pcidio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ /* XXX configure ports for input */
+ writel(0x0000, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+
+ if (1) {
+ /* enable fifos A B C D */
+ writeb(0x0f, devpriv->mite->daq_io_addr + Data_Path);
+
+ /* set transfer width a 32 bits */
+ writeb(TransferWidth(0) | TransferLength(0),
+ devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ } else {
+ writeb(0x03, devpriv->mite->daq_io_addr + Data_Path);
+ writeb(TransferWidth(3) | TransferLength(0),
+ devpriv->mite->daq_io_addr + Transfer_Size_Control);
+ }
+
+ /* protocol configuration */
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /* page 4-5, "input with internal REQs" */
+ writeb(0, devpriv->mite->daq_io_addr + OpMode);
+ writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
+ writeb(1, devpriv->mite->daq_io_addr + Sequence);
+ writeb(0x04, devpriv->mite->daq_io_addr + ReqReg);
+ writeb(4, devpriv->mite->daq_io_addr + BlockMode);
+ writeb(3, devpriv->mite->daq_io_addr + LinePolarities);
+ writeb(0xc0, devpriv->mite->daq_io_addr + AckSer);
+ writel(ni_pcidio_ns_to_timer(&cmd->scan_begin_arg,
+ TRIG_ROUND_NEAREST),
+ devpriv->mite->daq_io_addr + StartDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
+ writeb(1, devpriv->mite->daq_io_addr + AckDelay);
+ writeb(0x0b, devpriv->mite->daq_io_addr + AckNotDelay);
+ writeb(0x01, devpriv->mite->daq_io_addr + Data1Delay);
+ /* manual, page 4-5: ClockSpeed comment is incorrectly listed
+ * on DAQOptions */
+ writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
+ writeb(0, devpriv->mite->daq_io_addr + DAQOptions);
+ } else {
+ /* TRIG_EXT */
+ /* page 4-5, "input with external REQs" */
+ writeb(0, devpriv->mite->daq_io_addr + OpMode);
+ writeb(0x00, devpriv->mite->daq_io_addr + ClockReg);
+ writeb(0, devpriv->mite->daq_io_addr + Sequence);
+ writeb(0x00, devpriv->mite->daq_io_addr + ReqReg);
+ writeb(4, devpriv->mite->daq_io_addr + BlockMode);
+ writeb(0, devpriv->mite->daq_io_addr + LinePolarities);
+ writeb(0x00, devpriv->mite->daq_io_addr + AckSer);
+ writel(1, devpriv->mite->daq_io_addr + StartDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqDelay);
+ writeb(1, devpriv->mite->daq_io_addr + ReqNotDelay);
+ writeb(1, devpriv->mite->daq_io_addr + AckDelay);
+ writeb(0x0C, devpriv->mite->daq_io_addr + AckNotDelay);
+ writeb(0x10, devpriv->mite->daq_io_addr + Data1Delay);
+ writew(0, devpriv->mite->daq_io_addr + ClockSpeed);
+ writeb(0x60, devpriv->mite->daq_io_addr + DAQOptions);
+ }
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ writel(cmd->stop_arg,
+ devpriv->mite->daq_io_addr + Transfer_Count);
+ } else {
+ /* XXX */
+ }
+
+#ifdef USE_DMA
+ writeb(ClearPrimaryTC | ClearSecondaryTC,
+ devpriv->mite->daq_io_addr + Group_1_First_Clear);
+
+ {
+ int retval = setup_mite_dma(dev, s);
+ if (retval)
+ return retval;
+ }
+#else
+ writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group1);
+#endif
+ writeb(0x00, devpriv->mite->daq_io_addr + DMA_Line_Control_Group2);
+
+ /* clear and enable interrupts */
+ writeb(0xff, devpriv->mite->daq_io_addr + Group_1_First_Clear);
+ //writeb(ClearExpired,devpriv->mite->daq_io_addr+Group_1_Second_Clear);
+
+ writeb(IntEn, devpriv->mite->daq_io_addr + Interrupt_Control);
+ writeb(0x03,
+ devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+
+ if (cmd->stop_src == TRIG_NONE) {
+ devpriv->OpModeBits = DataLatching(0) | RunMode(7);
+ } else { // TRIG_TIMER
+ devpriv->OpModeBits = Numbered | RunMode(7);
+ }
+ if (cmd->start_src == TRIG_NOW) {
+ /* start */
+ writeb(devpriv->OpModeBits,
+ devpriv->mite->daq_io_addr + OpMode);
+ s->async->inttrig = NULL;
+ } else {
+ /* TRIG_INT */
+ s->async->inttrig = ni_pcidio_inttrig;
+ }
+
+ DPRINTK("ni_pcidio: command started\n");
+ return 0;
+}
+
+static int setup_mite_dma(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int retval;
+
+ retval = ni_pcidio_request_di_mite_channel(dev);
+ if (retval)
+ return retval;
+
+ devpriv->di_mite_chan->dir = COMEDI_INPUT;
+
+ mite_prep_dma(devpriv->di_mite_chan, 32, 32);
+
+ mite_dma_arm(devpriv->di_mite_chan);
+ return 0;
+}
+
+static int ni_pcidio_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ if (trignum != 0)
+ return -EINVAL;
+
+ writeb(devpriv->OpModeBits, devpriv->mite->daq_io_addr + OpMode);
+ s->async->inttrig = NULL;
+
+ return 1;
+}
+
+static int ni_pcidio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ writeb(0x00,
+ devpriv->mite->daq_io_addr + Master_DMA_And_Interrupt_Control);
+ ni_pcidio_release_di_mite_channel(dev);
+
+ return 0;
+}
+
+static int ni_pcidio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->di_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ memset(s->async->prealloc_buf, 0xaa, s->async->prealloc_bufsz);
+
+ return 0;
+}
+
+static int pci_6534_load_fpga(struct comedi_device * dev, int fpga_index, u8 * data,
+ int data_len)
+{
+ static const int timeout = 1000;
+ int i, j;
+ writew(0x80 | fpga_index,
+ devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ writew(0xc0 | fpga_index,
+ devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ for (i = 0;
+ (readw(devpriv->mite->daq_io_addr +
+ Firmware_Status_Register) & 0x2) == 0
+ && i < timeout; ++i) {
+ udelay(1);
+ }
+ if (i == timeout) {
+ printk("ni_pcidio: failed to load fpga %i, waiting for status 0x2\n", fpga_index);
+ return -EIO;
+ }
+ writew(0x80 | fpga_index,
+ devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ for (i = 0;
+ readw(devpriv->mite->daq_io_addr + Firmware_Status_Register) !=
+ 0x3 && i < timeout; ++i) {
+ udelay(1);
+ }
+ if (i == timeout) {
+ printk("ni_pcidio: failed to load fpga %i, waiting for status 0x3\n", fpga_index);
+ return -EIO;
+ }
+ for (j = 0; j + 1 < data_len;) {
+ unsigned int value = data[j++];
+ value |= data[j++] << 8;
+ writew(value,
+ devpriv->mite->daq_io_addr + Firmware_Data_Register);
+ for (i = 0;
+ (readw(devpriv->mite->daq_io_addr +
+ Firmware_Status_Register) & 0x2) == 0
+ && i < timeout; ++i) {
+ udelay(1);
+ }
+ if (i == timeout) {
+ printk("ni_pcidio: failed to load word into fpga %i\n",
+ fpga_index);
+ return -EIO;
+ }
+ if (need_resched())
+ schedule();
+ }
+ writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ return 0;
+}
+
+static int pci_6534_reset_fpga(struct comedi_device * dev, int fpga_index)
+{
+ return pci_6534_load_fpga(dev, fpga_index, NULL, 0);
+}
+
+static int pci_6534_reset_fpgas(struct comedi_device * dev)
+{
+ int ret;
+ int i;
+ writew(0x0, devpriv->mite->daq_io_addr + Firmware_Control_Register);
+ for (i = 0; i < 3; ++i) {
+ ret = pci_6534_reset_fpga(dev, i);
+ if (ret < 0)
+ break;
+ }
+ writew(0x0, devpriv->mite->daq_io_addr + Firmware_Mask_Register);
+ return ret;
+}
+
+static void pci_6534_init_main_fpga(struct comedi_device * dev)
+{
+ writel(0, devpriv->mite->daq_io_addr + FPGA_Control1_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_Control2_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCALS_Counter_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCAMS_Counter_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCBLS_Counter_Register);
+ writel(0, devpriv->mite->daq_io_addr + FPGA_SCBMS_Counter_Register);
+}
+
+static int pci_6534_upload_firmware(struct comedi_device * dev, int options[])
+{
+ int ret;
+ void *main_fpga_data, *scarab_a_data, *scarab_b_data;
+ int main_fpga_data_len, scarab_a_data_len, scarab_b_data_len;
+
+ if (options[COMEDI_DEVCONF_AUX_DATA_LENGTH] == 0)
+ return 0;
+ ret = pci_6534_reset_fpgas(dev);
+ if (ret < 0)
+ return ret;
+ main_fpga_data = comedi_aux_data(options, 0);
+ main_fpga_data_len = options[COMEDI_DEVCONF_AUX_DATA0_LENGTH];
+ ret = pci_6534_load_fpga(dev, 2, main_fpga_data, main_fpga_data_len);
+ if (ret < 0)
+ return ret;
+ pci_6534_init_main_fpga(dev);
+ scarab_a_data = comedi_aux_data(options, 1);
+ scarab_a_data_len = options[COMEDI_DEVCONF_AUX_DATA1_LENGTH];
+ ret = pci_6534_load_fpga(dev, 0, scarab_a_data, scarab_a_data_len);
+ if (ret < 0)
+ return ret;
+ scarab_b_data = comedi_aux_data(options, 2);
+ scarab_b_data_len = options[COMEDI_DEVCONF_AUX_DATA2_LENGTH];
+ ret = pci_6534_load_fpga(dev, 1, scarab_b_data, scarab_b_data_len);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int nidio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+ int ret;
+ int n_subdevices;
+ unsigned int irq;
+
+ printk("comedi%d: nidio:", dev->minor);
+
+ if ((ret = alloc_private(dev, sizeof(struct nidio96_private))) < 0)
+ return ret;
+ spin_lock_init(&devpriv->mite_channel_lock);
+
+ ret = nidio_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk("error setting up mite\n");
+ return ret;
+ }
+ comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+ devpriv->di_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->di_mite_ring == NULL)
+ return -ENOMEM;
+
+ dev->board_name = this_board->name;
+ irq = mite_irq(devpriv->mite);
+ printk(" %s", dev->board_name);
+ if (this_board->uses_firmware) {
+ ret = pci_6534_upload_firmware(dev, it->options);
+ if (ret < 0)
+ return ret;
+ }
+ if (!this_board->is_diodaq) {
+ n_subdevices = this_board->n_8255;
+ } else {
+ n_subdevices = 1;
+ }
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ if (!this_board->is_diodaq) {
+ for (i = 0; i < this_board->n_8255; i++) {
+ subdev_8255_init(dev, dev->subdevices + i,
+ nidio96_8255_cb,
+ (unsigned long)(devpriv->mite->daq_io_addr +
+ NIDIO_8255_BASE(i)));
+ }
+ } else {
+
+ printk(" rev=%d",
+ readb(devpriv->mite->daq_io_addr + Chip_Version));
+
+ s = dev->subdevices + 0;
+
+ dev->read_subdev = s;
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags =
+ SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL | SDF_PACKED |
+ SDF_CMD_READ;
+ s->n_chan = 32;
+ s->range_table = &range_digital;
+ s->maxdata = 1;
+ s->insn_config = &ni_pcidio_insn_config;
+ s->insn_bits = &ni_pcidio_insn_bits;
+ s->do_cmd = &ni_pcidio_cmd;
+ s->do_cmdtest = &ni_pcidio_cmdtest;
+ s->cancel = &ni_pcidio_cancel;
+ s->len_chanlist = 32; /* XXX */
+ s->buf_change = &ni_pcidio_change;
+ s->async_dma_dir = DMA_BIDIRECTIONAL;
+
+ writel(0, devpriv->mite->daq_io_addr + Port_IO(0));
+ writel(0, devpriv->mite->daq_io_addr + Port_Pin_Directions(0));
+ writel(0, devpriv->mite->daq_io_addr + Port_Pin_Mask(0));
+
+ /* disable interrupts on board */
+ writeb(0x00,
+ devpriv->mite->daq_io_addr +
+ Master_DMA_And_Interrupt_Control);
+
+ ret = comedi_request_irq(irq, nidio_interrupt, IRQF_SHARED,
+ "ni_pcidio", dev);
+ if (ret < 0) {
+ printk(" irq not available");
+ }
+ dev->irq = irq;
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int nidio_detach(struct comedi_device * dev)
+{
+ int i;
+
+ if (this_board && !this_board->is_diodaq) {
+ for (i = 0; i < this_board->n_8255; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+ }
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (devpriv) {
+ if (devpriv->di_mite_ring) {
+ mite_free_ring(devpriv->di_mite_ring);
+ devpriv->di_mite_ring = NULL;
+ }
+ if (devpriv->mite)
+ mite_unsetup(devpriv->mite);
+ }
+ return 0;
+}
+
+static int nidio_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+ for (i = 0; i < n_nidio_boards; i++) {
+ if (mite_device_id(mite) == nidio_boards[i].dev_id) {
+ dev->board_ptr = nidio_boards + i;
+ devpriv->mite = mite;
+
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+COMEDI_PCI_INITCLEANUP(driver_pcidio, ni_pcidio_pci_table);
diff --git a/drivers/staging/comedi/drivers/ni_pcimio.c b/drivers/staging/comedi/drivers/ni_pcimio.c
new file mode 100644
index 00000000000..3a2aba7c8dd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_pcimio.c
@@ -0,0 +1,1788 @@
+/*
+ comedi/drivers/ni_pcimio.c
+ Hardware driver for NI PCI-MIO E series cards
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1997-8 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: ni_pcimio
+Description: National Instruments PCI-MIO-E series and M series (all boards)
+Author: ds, John Hallen, Frank Mori Hess, Rolf Mueller, Herbert Peremans,
+ Herman Bruyninckx, Terry Barnaby
+Status: works
+Devices: [National Instruments] PCI-MIO-16XE-50 (ni_pcimio),
+ PCI-MIO-16XE-10, PXI-6030E, PCI-MIO-16E-1, PCI-MIO-16E-4, PCI-6014, PCI-6040E,
+ PXI-6040E, PCI-6030E, PCI-6031E, PCI-6032E, PCI-6033E, PCI-6071E, PCI-6023E,
+ PCI-6024E, PCI-6025E, PXI-6025E, PCI-6034E, PCI-6035E, PCI-6052E,
+ PCI-6110, PCI-6111, PCI-6220, PCI-6221, PCI-6224, PXI-6224, PCI-6225,
+ PCI-6229, PCI-6250, PCI-6251, PCIe-6251, PCI-6254, PCI-6259, PCIe-6259,
+ PCI-6280, PCI-6281, PXI-6281, PCI-6284, PCI-6289,
+ PCI-6711, PXI-6711, PCI-6713, PXI-6713,
+ PXI-6071E, PCI-6070E, PXI-6070E,
+ PXI-6052E, PCI-6036E, PCI-6731, PCI-6733, PXI-6733,
+ PCI-6143, PXI-6143
+Updated: Wed, 03 Dec 2008 10:51:47 +0000
+
+These boards are almost identical to the AT-MIO E series, except that
+they use the PCI bus instead of ISA (i.e., AT). See the notes for
+the ni_atmio.o driver for additional information about these boards.
+
+Autocalibration is supported on many of the devices, using the
+comedi_calibrate (or comedi_soft_calibrate for m-series) utility.
+M-Series boards do analog input and analog output calibration entirely
+in software. The software calibration corrects
+the analog input for offset, gain and
+nonlinearity. The analog outputs are corrected for offset and gain.
+See the comedilib documentation on comedi_get_softcal_converter() for
+more information.
+
+By default, the driver uses DMA to transfer analog input data to
+memory. When DMA is enabled, not all triggering features are
+supported.
+
+Digital I/O may not work on 673x.
+
+Note that the PCI-6143 is a simultaineous sampling device with 8 convertors.
+With this board all of the convertors perform one simultaineous sample during
+a scan interval. The period for a scan is used for the convert time in a
+Comedi cmd. The convert trigger source is normally set to TRIG_NOW by default.
+
+The RTSI trigger bus is supported on these cards on
+subdevice 10. See the comedilib documentation for details.
+
+Information (number of channels, bits, etc.) for some devices may be
+incorrect. Please check this and submit a bug if there are problems
+for your device.
+
+SCXI is probably broken for m-series boards.
+
+Bugs:
+ - When DMA is enabled, COMEDI_EV_CONVERT does
+ not work correctly.
+
+*/
+/*
+ The PCI-MIO E series driver was originally written by
+ Tomasz Motylewski <...>, and ported to comedi by ds.
+
+ References:
+
+ 341079b.pdf PCI E Series Register-Level Programmer Manual
+ 340934b.pdf DAQ-STC reference manual
+
+ 322080b.pdf 6711/6713/6715 User Manual
+
+ 320945c.pdf PCI E Series User Manual
+ 322138a.pdf PCI-6052E and DAQPad-6052E User Manual
+
+ ISSUES:
+
+ need to deal with external reference for DAC, and other DAC
+ properties in board properties
+
+ deal with at-mio-16de-10 revision D to N changes, etc.
+
+ need to add other CALDAC type
+
+ need to slow down DAC loading. I don't trust NI's claim that
+ two writes to the PCI bus slows IO enough. I would prefer to
+ use comedi_udelay(). Timing specs: (clock)
+ AD8522 30ns
+ DAC8043 120ns
+ DAC8800 60ns
+ MB88341 ?
+
+*/
+
+#include "../comedidev.h"
+
+#include <asm/byteorder.h>
+#include <linux/delay.h>
+
+#include "ni_stc.h"
+#include "mite.h"
+
+//#define PCI_DEBUG
+
+#define PCIDMA
+
+#define PCIMIO 1
+#undef ATMIO
+
+#define MAX_N_CALDACS (16+16+2)
+
+#define DRV_NAME "ni_pcimio"
+
+/* The following two tables must be in the same order */
+static DEFINE_PCI_DEVICE_TABLE(ni_pci_table) = {
+ {PCI_VENDOR_ID_NATINST, 0x0162, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1170, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1190, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x11b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x11c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x11d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1270, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1350, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x14e0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x14f0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1580, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x15b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x1870, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x18b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x18c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2890, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x28c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2a60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2a70, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2a80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2ab0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2b80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2b90, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x2ca0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70aa, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70ab, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70ac, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70af, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70bf, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x70f2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x710d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x716c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x717f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x71bc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_NATINST, 0x717d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, ni_pci_table);
+
+/* These are not all the possible ao ranges for 628x boards.
+ They can do OFFSET +- REFERENCE where OFFSET can be
+ 0V, 5V, APFI<0,1>, or AO<0...3> and RANGE can
+ be 10V, 5V, 2V, 1V, APFI<0,1>, AO<0...3>. That's
+ 63 different possibilities. An AO channel
+ can not act as it's own OFFSET or REFERENCE.
+*/
+static const struct comedi_lrange range_ni_M_628x_ao = { 8, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE(-2, 2),
+ RANGE(-1, 1),
+ RANGE(-5, 15),
+ RANGE(0, 10),
+ RANGE(3, 7),
+ RANGE(4, 6),
+ RANGE_ext(-1, 1)
+ }
+};
+static const struct comedi_lrange range_ni_M_625x_ao = { 3, {
+ RANGE(-10, 10),
+ RANGE(-5, 5),
+ RANGE_ext(-1, 1)
+ }
+};
+static const struct comedi_lrange range_ni_M_622x_ao = { 1, {
+ RANGE(-10, 10),
+ }
+};
+
+static const ni_board ni_boards[] = {
+ {
+ .device_id = 0x0162, // NI also says 0x1620. typo?
+ .name = "pci-mio-16xe-50",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 2048,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_8,
+ .ai_speed = 50000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 50000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1170,
+ .name = "pci-mio-16xe-10", // aka pci-6030E
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x28c0,
+ .name = "pci-6014",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x11d0,
+ .name = "pxi-6030e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1180,
+ .name = "pci-mio-16e-1", /* aka pci-6070e */
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {mb88341},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1190,
+ .name = "pci-mio-16e-4", /* aka pci-6040e */
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_16,
+ /* Note: there have been reported problems with full speed
+ * on this board */
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 512,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, // doc says mb88341
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x11c0,
+ .name = "pxi-6040e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 2000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 512,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {mb88341},
+ .has_8255 = 0,
+ },
+
+ {
+ .device_id = 0x1330,
+ .name = "pci-6031e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1270,
+ .name = "pci-6032e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1340,
+ .name = "pci-6033e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x1350,
+ .name = "pci-6071e",
+ .n_adchan = 64,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2a60,
+ .name = "pci-6023e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2a70,
+ .name = "pci-6024e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2a80,
+ .name = "pci-6025e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 1,
+ },
+ {
+ .device_id = 0x2ab0,
+ .name = "pxi-6025e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug}, /* manual is wrong */
+ .has_8255 = 1,
+ },
+
+ {
+ .device_id = 0x2ca0,
+ .name = "pci-6034e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x2c80,
+ .name = "pci-6035e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x18b0,
+ .name = "pci-6052e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 3000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_unipolar = 1,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 3000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug, ad8804_debug, ad8522}, /* manual is wrong */
+ },
+ {.device_id = 0x14e0,
+ .name = "pci-6110",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 200,
+ .n_aochan = 2,
+ .aobits = 16,
+ .reg_type = ni_reg_611x,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804, ad8804},
+ },
+ {
+ .device_id = 0x14f0,
+ .name = "pci-6111",
+ .n_adchan = 2,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 200,
+ .n_aochan = 2,
+ .aobits = 16,
+ .reg_type = ni_reg_611x,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804, ad8804},
+ },
+#if 0
+ /* The 6115 boards probably need their own driver */
+ {
+ .device_id = 0x2ed0,
+ .name = "pci-6115",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 100,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_671x = 1,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .num_p0_dio_channels = 8,
+ .reg_611x = 1,
+ .caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */
+ },
+#endif
+#if 0
+ {
+ .device_id = 0x0000,
+ .name = "pxi-6115",
+ .n_adchan = 4,
+ .adbits = 12,
+ .ai_fifo_depth = 8192,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_611x,
+ .ai_speed = 100,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_671x = 1,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 2048,
+ .ao_speed = 250,
+ .reg_611x = 1,
+ .num_p0_dio_channels = 8,
+ caldac = {ad8804_debug, ad8804_debug, ad8804_debug}, /* XXX */
+ },
+#endif
+ {
+ .device_id = 0x1880,
+ .name = "pci-6711",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ /* data sheet says 8192, but fifo really holds 16384 samples */
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+ {
+ .device_id = 0x2b90,
+ .name = "pxi-6711",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+ {
+ .device_id = 0x1870,
+ .name = "pci-6713",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x2b80,
+ .name = "pxi-6713",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 12,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x2430,
+ .name = "pci-6731",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 8192,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+#if 0 /* need device ids */
+ {
+ .device_id = 0x0,
+ .name = "pxi-6731",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 8192,
+ .ao_range_table = &range_bipolar10,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6711,
+ .caldac = {ad8804_debug},
+ },
+#endif
+ {
+ .device_id = 0x2410,
+ .name = "pci-6733",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x2420,
+ .name = "pxi-6733",
+ .n_adchan = 0, /* no analog input */
+ .n_aochan = 8,
+ .aobits = 16,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 16384,
+ .ao_range_table = &range_bipolar10,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_6713,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x15b0,
+ .name = "pxi-6071e",
+ .n_adchan = 64,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x11b0,
+ .name = "pxi-6070e",
+ .n_adchan = 16,
+ .adbits = 12,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 12,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 1000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x18c0,
+ .name = "pxi-6052e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_16,
+ .ai_speed = 3000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_unipolar = 1,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_speed = 3000,
+ .num_p0_dio_channels = 8,
+ .caldac = {mb88341, mb88341, ad8522},
+ },
+ {
+ .device_id = 0x1580,
+ .name = "pxi-6031e",
+ .n_adchan = 64,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_14,
+ .ai_speed = 10000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 2048,
+ .ao_range_table = &range_ni_E_ao_ext,
+ .ao_unipolar = 1,
+ .ao_speed = 10000,
+ .num_p0_dio_channels = 8,
+ .caldac = {dac8800, dac8043, ad8522},
+ },
+ {
+ .device_id = 0x2890,
+ .name = "pci-6036e",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ .alwaysdither = 1,
+ .gainlkup = ai_gain_4,
+ .ai_speed = 5000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 0,
+ .ao_range_table = &range_bipolar10,
+ .ao_unipolar = 0,
+ .ao_speed = 100000,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b0,
+ .name = "pci-6220",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 512,
+ //FIXME: guess
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .num_p0_dio_channels = 8,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70af,
+ .name = "pci-6221",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x71bc,
+ .name = "pci-6221_37pin",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70f2,
+ .name = "pci-6224",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70f3,
+ .name = "pxi-6224",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x716c,
+ .name = "pci-6225",
+ .n_adchan = 80,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70aa,
+ .name = "pci-6229",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_622x,
+ .ai_speed = 4000,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_622x_ao,
+ .reg_type = ni_reg_622x,
+ .ao_unipolar = 0,
+ .ao_speed = 1200,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b4,
+ .name = "pci-6250",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b8,
+ .name = "pci-6251",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x717d,
+ .name = "pcie-6251",
+ .n_adchan = 16,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b7,
+ .name = "pci-6254",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70ab,
+ .name = "pci-6259",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x717f,
+ .name = "pcie-6259",
+ .n_adchan = 32,
+ .adbits = 16,
+ .ai_fifo_depth = 4095,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 800,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_625x_ao,
+ .reg_type = ni_reg_625x,
+ .ao_unipolar = 0,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70b6,
+ .name = "pci-6280",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 8191,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70bd,
+ .name = "pci-6281",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70bf,
+ .name = "pxi-6281",
+ .n_adchan = 16,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 2,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 8,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70bc,
+ .name = "pci-6284",
+ .n_adchan = 32,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 0,
+ .aobits = 0,
+ .ao_fifo_depth = 0,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 0,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70ac,
+ .name = "pci-6289",
+ .n_adchan = 32,
+ .adbits = 18,
+ .ai_fifo_depth = 2047,
+ .gainlkup = ai_gain_628x,
+ .ai_speed = 1600,
+ .n_aochan = 4,
+ .aobits = 16,
+ .ao_fifo_depth = 8191,
+ .ao_range_table = &range_ni_M_628x_ao,
+ .reg_type = ni_reg_628x,
+ .ao_unipolar = 1,
+ .ao_speed = 357,
+ .num_p0_dio_channels = 32,
+ .caldac = {caldac_none},
+ .has_8255 = 0,
+ },
+ {
+ .device_id = 0x70C0,
+ .name = "pci-6143",
+ .n_adchan = 8,
+ .adbits = 16,
+ .ai_fifo_depth = 1024,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_6143,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .reg_type = ni_reg_6143,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+ {
+ .device_id = 0x710D,
+ .name = "pxi-6143",
+ .n_adchan = 8,
+ .adbits = 16,
+ .ai_fifo_depth = 1024,
+ .alwaysdither = 0,
+ .gainlkup = ai_gain_6143,
+ .ai_speed = 4000,
+ .n_aochan = 0,
+ .aobits = 0,
+ .reg_type = ni_reg_6143,
+ .ao_unipolar = 0,
+ .ao_fifo_depth = 0,
+ .num_p0_dio_channels = 8,
+ .caldac = {ad8804_debug, ad8804_debug},
+ },
+};
+
+#define n_pcimio_boards ((sizeof(ni_boards)/sizeof(ni_boards[0])))
+
+static int pcimio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcimio_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcimio = {
+ driver_name: DRV_NAME,
+ module:THIS_MODULE,
+ attach:pcimio_attach,
+ detach:pcimio_detach,
+};
+
+COMEDI_PCI_INITCLEANUP(driver_pcimio, ni_pci_table)
+
+typedef struct {
+NI_PRIVATE_COMMON} ni_private;
+#define devpriv ((ni_private *)dev->private)
+
+/* How we access registers */
+
+#define ni_writel(a,b) (writel((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readl(a) (readl(devpriv->mite->daq_io_addr + (a)))
+#define ni_writew(a,b) (writew((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readw(a) (readw(devpriv->mite->daq_io_addr + (a)))
+#define ni_writeb(a,b) (writeb((a), devpriv->mite->daq_io_addr + (b)))
+#define ni_readb(a) (readb(devpriv->mite->daq_io_addr + (a)))
+
+/* How we access STC registers */
+
+/* We automatically take advantage of STC registers that can be
+ * read/written directly in the I/O space of the board. Most
+ * PCIMIO devices map the low 8 STC registers to iobase+addr*2.
+ * The 611x devices map the write registers to iobase+addr*2, and
+ * the read registers to iobase+(addr-1)*2. */
+/* However, the 611x boards still aren't working, so I'm disabling
+ * non-windowed STC access temporarily */
+
+static void e_series_win_out(struct comedi_device * dev, uint16_t data, int reg)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(reg, Window_Address);
+ ni_writew(data, Window_Data);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+}
+
+static uint16_t e_series_win_in(struct comedi_device * dev, int reg)
+{
+ unsigned long flags;
+ uint16_t ret;
+
+ comedi_spin_lock_irqsave(&devpriv->window_lock, flags);
+ ni_writew(reg, Window_Address);
+ ret = ni_readw(Window_Data);
+ comedi_spin_unlock_irqrestore(&devpriv->window_lock, flags);
+
+ return ret;
+}
+
+static void m_series_stc_writew(struct comedi_device * dev, uint16_t data, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case ADC_FIFO_Clear:
+ offset = M_Offset_AI_FIFO_Clear;
+ break;
+ case AI_Command_1_Register:
+ offset = M_Offset_AI_Command_1;
+ break;
+ case AI_Command_2_Register:
+ offset = M_Offset_AI_Command_2;
+ break;
+ case AI_Mode_1_Register:
+ offset = M_Offset_AI_Mode_1;
+ break;
+ case AI_Mode_2_Register:
+ offset = M_Offset_AI_Mode_2;
+ break;
+ case AI_Mode_3_Register:
+ offset = M_Offset_AI_Mode_3;
+ break;
+ case AI_Output_Control_Register:
+ offset = M_Offset_AI_Output_Control;
+ break;
+ case AI_Personal_Register:
+ offset = M_Offset_AI_Personal;
+ break;
+ case AI_SI2_Load_A_Register:
+ // this is actually a 32 bit register on m series boards
+ ni_writel(data, M_Offset_AI_SI2_Load_A);
+ return;
+ break;
+ case AI_SI2_Load_B_Register:
+ // this is actually a 32 bit register on m series boards
+ ni_writel(data, M_Offset_AI_SI2_Load_B);
+ return;
+ break;
+ case AI_START_STOP_Select_Register:
+ offset = M_Offset_AI_START_STOP_Select;
+ break;
+ case AI_Trigger_Select_Register:
+ offset = M_Offset_AI_Trigger_Select;
+ break;
+ case Analog_Trigger_Etc_Register:
+ offset = M_Offset_Analog_Trigger_Etc;
+ break;
+ case AO_Command_1_Register:
+ offset = M_Offset_AO_Command_1;
+ break;
+ case AO_Command_2_Register:
+ offset = M_Offset_AO_Command_2;
+ break;
+ case AO_Mode_1_Register:
+ offset = M_Offset_AO_Mode_1;
+ break;
+ case AO_Mode_2_Register:
+ offset = M_Offset_AO_Mode_2;
+ break;
+ case AO_Mode_3_Register:
+ offset = M_Offset_AO_Mode_3;
+ break;
+ case AO_Output_Control_Register:
+ offset = M_Offset_AO_Output_Control;
+ break;
+ case AO_Personal_Register:
+ offset = M_Offset_AO_Personal;
+ break;
+ case AO_Start_Select_Register:
+ offset = M_Offset_AO_Start_Select;
+ break;
+ case AO_Trigger_Select_Register:
+ offset = M_Offset_AO_Trigger_Select;
+ break;
+ case Clock_and_FOUT_Register:
+ offset = M_Offset_Clock_and_FOUT;
+ break;
+ case Configuration_Memory_Clear:
+ offset = M_Offset_Configuration_Memory_Clear;
+ break;
+ case DAC_FIFO_Clear:
+ offset = M_Offset_AO_FIFO_Clear;
+ break;
+ case DIO_Control_Register:
+ rt_printk
+ ("%s: FIXME: register 0x%x does not map cleanly on to m-series boards.\n",
+ __FUNCTION__, reg);
+ return;
+ break;
+ case G_Autoincrement_Register(0):
+ offset = M_Offset_G0_Autoincrement;
+ break;
+ case G_Autoincrement_Register(1):
+ offset = M_Offset_G1_Autoincrement;
+ break;
+ case G_Command_Register(0):
+ offset = M_Offset_G0_Command;
+ break;
+ case G_Command_Register(1):
+ offset = M_Offset_G1_Command;
+ break;
+ case G_Input_Select_Register(0):
+ offset = M_Offset_G0_Input_Select;
+ break;
+ case G_Input_Select_Register(1):
+ offset = M_Offset_G1_Input_Select;
+ break;
+ case G_Mode_Register(0):
+ offset = M_Offset_G0_Mode;
+ break;
+ case G_Mode_Register(1):
+ offset = M_Offset_G1_Mode;
+ break;
+ case Interrupt_A_Ack_Register:
+ offset = M_Offset_Interrupt_A_Ack;
+ break;
+ case Interrupt_A_Enable_Register:
+ offset = M_Offset_Interrupt_A_Enable;
+ break;
+ case Interrupt_B_Ack_Register:
+ offset = M_Offset_Interrupt_B_Ack;
+ break;
+ case Interrupt_B_Enable_Register:
+ offset = M_Offset_Interrupt_B_Enable;
+ break;
+ case Interrupt_Control_Register:
+ offset = M_Offset_Interrupt_Control;
+ break;
+ case IO_Bidirection_Pin_Register:
+ offset = M_Offset_IO_Bidirection_Pin;
+ break;
+ case Joint_Reset_Register:
+ offset = M_Offset_Joint_Reset;
+ break;
+ case RTSI_Trig_A_Output_Register:
+ offset = M_Offset_RTSI_Trig_A_Output;
+ break;
+ case RTSI_Trig_B_Output_Register:
+ offset = M_Offset_RTSI_Trig_B_Output;
+ break;
+ case RTSI_Trig_Direction_Register:
+ offset = M_Offset_RTSI_Trig_Direction;
+ break;
+ /* FIXME: DIO_Output_Register (16 bit reg) is replaced by M_Offset_Static_Digital_Output (32 bit)
+ and M_Offset_SCXI_Serial_Data_Out (8 bit) */
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return;
+ break;
+ }
+ ni_writew(data, offset);
+}
+
+static uint16_t m_series_stc_readw(struct comedi_device * dev, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case AI_Status_1_Register:
+ offset = M_Offset_AI_Status_1;
+ break;
+ case AO_Status_1_Register:
+ offset = M_Offset_AO_Status_1;
+ break;
+ case AO_Status_2_Register:
+ offset = M_Offset_AO_Status_2;
+ break;
+ case DIO_Serial_Input_Register:
+ return ni_readb(M_Offset_SCXI_Serial_Data_In);
+ break;
+ case Joint_Status_1_Register:
+ offset = M_Offset_Joint_Status_1;
+ break;
+ case Joint_Status_2_Register:
+ offset = M_Offset_Joint_Status_2;
+ break;
+ case G_Status_Register:
+ offset = M_Offset_G01_Status;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return ni_readw(offset);
+}
+
+static void m_series_stc_writel(struct comedi_device * dev, uint32_t data, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case AI_SC_Load_A_Registers:
+ offset = M_Offset_AI_SC_Load_A;
+ break;
+ case AI_SI_Load_A_Registers:
+ offset = M_Offset_AI_SI_Load_A;
+ break;
+ case AO_BC_Load_A_Register:
+ offset = M_Offset_AO_BC_Load_A;
+ break;
+ case AO_UC_Load_A_Register:
+ offset = M_Offset_AO_UC_Load_A;
+ break;
+ case AO_UI_Load_A_Register:
+ offset = M_Offset_AO_UI_Load_A;
+ break;
+ case G_Load_A_Register(0):
+ offset = M_Offset_G0_Load_A;
+ break;
+ case G_Load_A_Register(1):
+ offset = M_Offset_G1_Load_A;
+ break;
+ case G_Load_B_Register(0):
+ offset = M_Offset_G0_Load_B;
+ break;
+ case G_Load_B_Register(1):
+ offset = M_Offset_G1_Load_B;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return;
+ break;
+ }
+ ni_writel(data, offset);
+}
+
+static uint32_t m_series_stc_readl(struct comedi_device * dev, int reg)
+{
+ unsigned offset;
+ switch (reg) {
+ case G_HW_Save_Register(0):
+ offset = M_Offset_G0_HW_Save;
+ break;
+ case G_HW_Save_Register(1):
+ offset = M_Offset_G1_HW_Save;
+ break;
+ case G_Save_Register(0):
+ offset = M_Offset_G0_Save;
+ break;
+ case G_Save_Register(1):
+ offset = M_Offset_G1_Save;
+ break;
+ default:
+ rt_printk("%s: bug! unhandled register=0x%x in switch.\n",
+ __FUNCTION__, reg);
+ BUG();
+ return 0;
+ break;
+ }
+ return ni_readl(offset);
+}
+
+#define interrupt_pin(a) 0
+#define IRQ_POLARITY 1
+
+#define NI_E_IRQ_FLAGS IRQF_SHARED
+
+#include "ni_mio_common.c"
+
+static int pcimio_find_device(struct comedi_device * dev, int bus, int slot);
+static int pcimio_ai_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_ao_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_gpct0_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_gpct1_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+static int pcimio_dio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size);
+
+static void m_series_init_eeprom_buffer(struct comedi_device * dev)
+{
+ static const int Start_Cal_EEPROM = 0x400;
+ static const unsigned window_size = 10;
+ static const int serial_number_eeprom_offset = 0x4;
+ static const int serial_number_eeprom_length = 0x4;
+ unsigned old_iodwbsr_bits;
+ unsigned old_iodwbsr1_bits;
+ unsigned old_iodwcr1_bits;
+ int i;
+
+ old_iodwbsr_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR);
+ old_iodwbsr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+ old_iodwcr1_bits = readl(devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+ writel(0x0, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+ writel(((0x80 | window_size) | devpriv->mite->daq_phys_addr),
+ devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+ writel(0x1 | old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+ writel(0xf, devpriv->mite->mite_io_addr + 0x30);
+
+ BUG_ON(serial_number_eeprom_length > sizeof(devpriv->serial_number));
+ for (i = 0; i < serial_number_eeprom_length; ++i) {
+ char *byte_ptr = (char*)&devpriv->serial_number + i;
+ *byte_ptr = ni_readb(serial_number_eeprom_offset + i);
+ }
+ devpriv->serial_number = be32_to_cpu(devpriv->serial_number);
+
+ for (i = 0; i < M_SERIES_EEPROM_SIZE; ++i) {
+ devpriv->eeprom_buffer[i] = ni_readb(Start_Cal_EEPROM + i);
+ }
+
+ writel(old_iodwbsr1_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR_1);
+ writel(old_iodwbsr_bits, devpriv->mite->mite_io_addr + MITE_IODWBSR);
+ writel(old_iodwcr1_bits, devpriv->mite->mite_io_addr + MITE_IODWCR_1);
+ writel(0x0, devpriv->mite->mite_io_addr + 0x30);
+}
+
+static void init_6143(struct comedi_device * dev)
+{
+ // Disable interrupts
+ devpriv->stc_writew(dev, 0, Interrupt_Control_Register);
+
+ // Initialise 6143 AI specific bits
+ ni_writeb(0x00, Magic_6143); // Set G0,G1 DMA mode to E series version
+ ni_writeb(0x80, PipelineDelay_6143); // Set EOCMode, ADCMode and pipelinedelay
+ ni_writeb(0x00, EOC_Set_6143); // Set EOC Delay
+
+ ni_writel(boardtype.ai_fifo_depth / 2, AIFIFO_Flag_6143); // Set the FIFO half full level
+
+ // Strobe Relay disable bit
+ devpriv->ai_calib_source_enabled = 0;
+ ni_writew(devpriv->ai_calib_source | Calibration_Channel_6143_RelayOff,
+ Calibration_Channel_6143);
+ ni_writew(devpriv->ai_calib_source, Calibration_Channel_6143);
+}
+
+/* cleans up allocated resources */
+static int pcimio_detach(struct comedi_device * dev)
+{
+ mio_common_detach(dev);
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+ if (dev->private) {
+ mite_free_ring(devpriv->ai_mite_ring);
+ mite_free_ring(devpriv->ao_mite_ring);
+ mite_free_ring(devpriv->cdo_mite_ring);
+ mite_free_ring(devpriv->gpct_mite_ring[0]);
+ mite_free_ring(devpriv->gpct_mite_ring[1]);
+ if (devpriv->mite)
+ mite_unsetup(devpriv->mite);
+ }
+
+ return 0;
+}
+
+static int pcimio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+
+ printk("comedi%d: ni_pcimio:", dev->minor);
+
+ ret = ni_alloc_private(dev);
+ if (ret < 0)
+ return ret;
+
+ ret = pcimio_find_device(dev, it->options[0], it->options[1]);
+ if (ret < 0)
+ return ret;
+
+ printk(" %s", boardtype.name);
+ dev->board_name = boardtype.name;
+
+ if (boardtype.reg_type & ni_reg_m_series_mask) {
+ devpriv->stc_writew = &m_series_stc_writew;
+ devpriv->stc_readw = &m_series_stc_readw;
+ devpriv->stc_writel = &m_series_stc_writel;
+ devpriv->stc_readl = &m_series_stc_readl;
+ } else {
+ devpriv->stc_writew = &e_series_win_out;
+ devpriv->stc_readw = &e_series_win_in;
+ devpriv->stc_writel = &win_out2;
+ devpriv->stc_readl = &win_in2;
+ }
+
+ ret = mite_setup(devpriv->mite);
+ if (ret < 0) {
+ printk(" error setting up mite\n");
+ return ret;
+ }
+ comedi_set_hw_dev(dev, &devpriv->mite->pcidev->dev);
+ devpriv->ai_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->ai_mite_ring == NULL)
+ return -ENOMEM;
+ devpriv->ao_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->ao_mite_ring == NULL)
+ return -ENOMEM;
+ devpriv->cdo_mite_ring = mite_alloc_ring(devpriv->mite);
+ if (devpriv->cdo_mite_ring == NULL)
+ return -ENOMEM;
+ devpriv->gpct_mite_ring[0] = mite_alloc_ring(devpriv->mite);
+ if (devpriv->gpct_mite_ring[0] == NULL)
+ return -ENOMEM;
+ devpriv->gpct_mite_ring[1] = mite_alloc_ring(devpriv->mite);
+ if (devpriv->gpct_mite_ring[1] == NULL)
+ return -ENOMEM;
+
+ if (boardtype.reg_type & ni_reg_m_series_mask)
+ m_series_init_eeprom_buffer(dev);
+ if (boardtype.reg_type == ni_reg_6143)
+ init_6143(dev);
+
+ dev->irq = mite_irq(devpriv->mite);
+
+ if (dev->irq == 0) {
+ printk(" unknown irq (bad)\n");
+ } else {
+ printk(" ( irq = %u )", dev->irq);
+ if ((ret = comedi_request_irq(dev->irq, ni_E_interrupt,
+ NI_E_IRQ_FLAGS, DRV_NAME,
+ dev)) < 0) {
+ printk(" irq not available\n");
+ dev->irq = 0;
+ }
+ }
+
+ ret = ni_E_init(dev, it);
+ if (ret < 0)
+ return ret;
+
+ dev->subdevices[NI_AI_SUBDEV].buf_change = &pcimio_ai_change;
+ dev->subdevices[NI_AO_SUBDEV].buf_change = &pcimio_ao_change;
+ dev->subdevices[NI_GPCT_SUBDEV(0)].buf_change = &pcimio_gpct0_change;
+ dev->subdevices[NI_GPCT_SUBDEV(1)].buf_change = &pcimio_gpct1_change;
+ dev->subdevices[NI_DIO_SUBDEV].buf_change = &pcimio_dio_change;
+
+ return ret;
+}
+
+static int pcimio_find_device(struct comedi_device * dev, int bus, int slot)
+{
+ struct mite_struct *mite;
+ int i;
+
+ for (mite = mite_devices; mite; mite = mite->next) {
+ if (mite->used)
+ continue;
+ if (bus || slot) {
+ if (bus != mite->pcidev->bus->number ||
+ slot != PCI_SLOT(mite->pcidev->devfn))
+ continue;
+ }
+
+ for (i = 0; i < n_pcimio_boards; i++) {
+ if (mite_device_id(mite) == ni_boards[i].device_id) {
+ dev->board_ptr = ni_boards + i;
+ devpriv->mite = mite;
+
+ return 0;
+ }
+ }
+ }
+ printk("no device found\n");
+ mite_list_devices();
+ return -EIO;
+}
+
+static int pcimio_ai_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->ai_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_ao_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->ao_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_gpct0_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->gpct_mite_ring[0], s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_gpct1_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->gpct_mite_ring[1], s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+static int pcimio_dio_change(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned long new_size)
+{
+ int ret;
+
+ ret = mite_buf_change(devpriv->cdo_mite_ring, s->async);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/ni_stc.h b/drivers/staging/comedi/drivers/ni_stc.h
new file mode 100644
index 00000000000..1ebf521ab77
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_stc.h
@@ -0,0 +1,1498 @@
+/*
+ module/ni_stc.h
+ Register descriptions for NI DAQ-STC chip
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998-9 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+ References:
+ DAQ-STC Technical Reference Manual
+*/
+
+#ifndef _COMEDI_NI_STC_H
+#define _COMEDI_NI_STC_H
+
+#include "ni_tio.h"
+
+#define _bit15 0x8000
+#define _bit14 0x4000
+#define _bit13 0x2000
+#define _bit12 0x1000
+#define _bit11 0x0800
+#define _bit10 0x0400
+#define _bit9 0x0200
+#define _bit8 0x0100
+#define _bit7 0x0080
+#define _bit6 0x0040
+#define _bit5 0x0020
+#define _bit4 0x0010
+#define _bit3 0x0008
+#define _bit2 0x0004
+#define _bit1 0x0002
+#define _bit0 0x0001
+
+#define NUM_PFI_OUTPUT_SELECT_REGS 6
+
+/* Registers in the National Instruments DAQ-STC chip */
+
+#define Interrupt_A_Ack_Register 2
+#define G0_Gate_Interrupt_Ack _bit15
+#define G0_TC_Interrupt_Ack _bit14
+#define AI_Error_Interrupt_Ack _bit13
+#define AI_STOP_Interrupt_Ack _bit12
+#define AI_START_Interrupt_Ack _bit11
+#define AI_START2_Interrupt_Ack _bit10
+#define AI_START1_Interrupt_Ack _bit9
+#define AI_SC_TC_Interrupt_Ack _bit8
+#define AI_SC_TC_Error_Confirm _bit7
+#define G0_TC_Error_Confirm _bit6
+#define G0_Gate_Error_Confirm _bit5
+
+#define AI_Status_1_Register 2
+#define Interrupt_A_St 0x8000
+#define AI_FIFO_Full_St 0x4000
+#define AI_FIFO_Half_Full_St 0x2000
+#define AI_FIFO_Empty_St 0x1000
+#define AI_Overrun_St 0x0800
+#define AI_Overflow_St 0x0400
+#define AI_SC_TC_Error_St 0x0200
+#define AI_START2_St 0x0100
+#define AI_START1_St 0x0080
+#define AI_SC_TC_St 0x0040
+#define AI_START_St 0x0020
+#define AI_STOP_St 0x0010
+#define G0_TC_St 0x0008
+#define G0_Gate_Interrupt_St 0x0004
+#define AI_FIFO_Request_St 0x0002
+#define Pass_Thru_0_Interrupt_St 0x0001
+
+#define AI_Status_2_Register 5
+
+#define Interrupt_B_Ack_Register 3
+enum Interrupt_B_Ack_Bits {
+ G1_Gate_Error_Confirm = _bit1,
+ G1_TC_Error_Confirm = _bit2,
+ AO_BC_TC_Trigger_Error_Confirm = _bit3,
+ AO_BC_TC_Error_Confirm = _bit4,
+ AO_UI2_TC_Error_Confrim = _bit5,
+ AO_UI2_TC_Interrupt_Ack = _bit6,
+ AO_UC_TC_Interrupt_Ack = _bit7,
+ AO_BC_TC_Interrupt_Ack = _bit8,
+ AO_START1_Interrupt_Ack = _bit9,
+ AO_UPDATE_Interrupt_Ack = _bit10,
+ AO_START_Interrupt_Ack = _bit11,
+ AO_STOP_Interrupt_Ack = _bit12,
+ AO_Error_Interrupt_Ack = _bit13,
+ G1_TC_Interrupt_Ack = _bit14,
+ G1_Gate_Interrupt_Ack = _bit15
+};
+
+#define AO_Status_1_Register 3
+#define Interrupt_B_St _bit15
+#define AO_FIFO_Full_St _bit14
+#define AO_FIFO_Half_Full_St _bit13
+#define AO_FIFO_Empty_St _bit12
+#define AO_BC_TC_Error_St _bit11
+#define AO_START_St _bit10
+#define AO_Overrun_St _bit9
+#define AO_START1_St _bit8
+#define AO_BC_TC_St _bit7
+#define AO_UC_TC_St _bit6
+#define AO_UPDATE_St _bit5
+#define AO_UI2_TC_St _bit4
+#define G1_TC_St _bit3
+#define G1_Gate_Interrupt_St _bit2
+#define AO_FIFO_Request_St _bit1
+#define Pass_Thru_1_Interrupt_St _bit0
+
+#define AI_Command_2_Register 4
+#define AI_End_On_SC_TC _bit15
+#define AI_End_On_End_Of_Scan _bit14
+#define AI_START1_Disable _bit11
+#define AI_SC_Save_Trace _bit10
+#define AI_SI_Switch_Load_On_SC_TC _bit9
+#define AI_SI_Switch_Load_On_STOP _bit8
+#define AI_SI_Switch_Load_On_TC _bit7
+#define AI_SC_Switch_Load_On_TC _bit4
+#define AI_STOP_Pulse _bit3
+#define AI_START_Pulse _bit2
+#define AI_START2_Pulse _bit1
+#define AI_START1_Pulse _bit0
+
+#define AO_Command_2_Register 5
+#define AO_End_On_BC_TC(x) (((x) & 0x3) << 14)
+#define AO_Start_Stop_Gate_Enable _bit13
+#define AO_UC_Save_Trace _bit12
+#define AO_BC_Gate_Enable _bit11
+#define AO_BC_Save_Trace _bit10
+#define AO_UI_Switch_Load_On_BC_TC _bit9
+#define AO_UI_Switch_Load_On_Stop _bit8
+#define AO_UI_Switch_Load_On_TC _bit7
+#define AO_UC_Switch_Load_On_BC_TC _bit6
+#define AO_UC_Switch_Load_On_TC _bit5
+#define AO_BC_Switch_Load_On_TC _bit4
+#define AO_Mute_B _bit3
+#define AO_Mute_A _bit2
+#define AO_UPDATE2_Pulse _bit1
+#define AO_START1_Pulse _bit0
+
+#define AO_Status_2_Register 6
+
+#define DIO_Parallel_Input_Register 7
+
+#define AI_Command_1_Register 8
+#define AI_Analog_Trigger_Reset _bit14
+#define AI_Disarm _bit13
+#define AI_SI2_Arm _bit12
+#define AI_SI2_Load _bit11
+#define AI_SI_Arm _bit10
+#define AI_SI_Load _bit9
+#define AI_DIV_Arm _bit8
+#define AI_DIV_Load _bit7
+#define AI_SC_Arm _bit6
+#define AI_SC_Load _bit5
+#define AI_SCAN_IN_PROG_Pulse _bit4
+#define AI_EXTMUX_CLK_Pulse _bit3
+#define AI_LOCALMUX_CLK_Pulse _bit2
+#define AI_SC_TC_Pulse _bit1
+#define AI_CONVERT_Pulse _bit0
+
+#define AO_Command_1_Register 9
+#define AO_Analog_Trigger_Reset _bit15
+#define AO_START_Pulse _bit14
+#define AO_Disarm _bit13
+#define AO_UI2_Arm_Disarm _bit12
+#define AO_UI2_Load _bit11
+#define AO_UI_Arm _bit10
+#define AO_UI_Load _bit9
+#define AO_UC_Arm _bit8
+#define AO_UC_Load _bit7
+#define AO_BC_Arm _bit6
+#define AO_BC_Load _bit5
+#define AO_DAC1_Update_Mode _bit4
+#define AO_LDAC1_Source_Select _bit3
+#define AO_DAC0_Update_Mode _bit2
+#define AO_LDAC0_Source_Select _bit1
+#define AO_UPDATE_Pulse _bit0
+
+#define DIO_Output_Register 10
+#define DIO_Parallel_Data_Out(a) ((a)&0xff)
+#define DIO_Parallel_Data_Mask 0xff
+#define DIO_SDOUT _bit0
+#define DIO_SDIN _bit4
+#define DIO_Serial_Data_Out(a) (((a)&0xff)<<8)
+#define DIO_Serial_Data_Mask 0xff00
+
+#define DIO_Control_Register 11
+#define DIO_Software_Serial_Control _bit11
+#define DIO_HW_Serial_Timebase _bit10
+#define DIO_HW_Serial_Enable _bit9
+#define DIO_HW_Serial_Start _bit8
+#define DIO_Pins_Dir(a) ((a)&0xff)
+#define DIO_Pins_Dir_Mask 0xff
+
+#define AI_Mode_1_Register 12
+#define AI_CONVERT_Source_Select(a) (((a) & 0x1f) << 11)
+#define AI_SI_Source_select(a) (((a) & 0x1f) << 6)
+#define AI_CONVERT_Source_Polarity _bit5
+#define AI_SI_Source_Polarity _bit4
+#define AI_Start_Stop _bit3
+#define AI_Mode_1_Reserved _bit2
+#define AI_Continuous _bit1
+#define AI_Trigger_Once _bit0
+
+#define AI_Mode_2_Register 13
+#define AI_SC_Gate_Enable _bit15
+#define AI_Start_Stop_Gate_Enable _bit14
+#define AI_Pre_Trigger _bit13
+#define AI_External_MUX_Present _bit12
+#define AI_SI2_Initial_Load_Source _bit9
+#define AI_SI2_Reload_Mode _bit8
+#define AI_SI_Initial_Load_Source _bit7
+#define AI_SI_Reload_Mode(a) (((a) & 0x7)<<4)
+#define AI_SI_Write_Switch _bit3
+#define AI_SC_Initial_Load_Source _bit2
+#define AI_SC_Reload_Mode _bit1
+#define AI_SC_Write_Switch _bit0
+
+#define AI_SI_Load_A_Registers 14
+#define AI_SI_Load_B_Registers 16
+#define AI_SC_Load_A_Registers 18
+#define AI_SC_Load_B_Registers 20
+#define AI_SI_Save_Registers 64
+#define AI_SC_Save_Registers 66
+
+#define AI_SI2_Load_A_Register 23
+#define AI_SI2_Load_B_Register 25
+
+#define Joint_Status_1_Register 27
+#define DIO_Serial_IO_In_Progress_St _bit12
+
+#define DIO_Serial_Input_Register 28
+#define Joint_Status_2_Register 29
+enum Joint_Status_2_Bits {
+ AO_TMRDACWRs_In_Progress_St = 0x20,
+};
+
+#define AO_Mode_1_Register 38
+#define AO_UPDATE_Source_Select(x) (((x)&0x1f)<<11)
+#define AO_UI_Source_Select(x) (((x)&0x1f)<<6)
+#define AO_Multiple_Channels _bit5
+#define AO_UPDATE_Source_Polarity _bit4
+#define AO_UI_Source_Polarity _bit3
+#define AO_UC_Switch_Load_Every_TC _bit2
+#define AO_Continuous _bit1
+#define AO_Trigger_Once _bit0
+
+#define AO_Mode_2_Register 39
+#define AO_FIFO_Mode_Mask ( 0x3 << 14 )
+enum AO_FIFO_Mode_Bits {
+ AO_FIFO_Mode_HF_to_F = (3 << 14),
+ AO_FIFO_Mode_F = (2 << 14),
+ AO_FIFO_Mode_HF = (1 << 14),
+ AO_FIFO_Mode_E = (0 << 14),
+};
+#define AO_FIFO_Retransmit_Enable _bit13
+#define AO_START1_Disable _bit12
+#define AO_UC_Initial_Load_Source _bit11
+#define AO_UC_Write_Switch _bit10
+#define AO_UI2_Initial_Load_Source _bit9
+#define AO_UI2_Reload_Mode _bit8
+#define AO_UI_Initial_Load_Source _bit7
+#define AO_UI_Reload_Mode(x) (((x) & 0x7) << 4)
+#define AO_UI_Write_Switch _bit3
+#define AO_BC_Initial_Load_Source _bit2
+#define AO_BC_Reload_Mode _bit1
+#define AO_BC_Write_Switch _bit0
+
+#define AO_UI_Load_A_Register 40
+#define AO_UI_Load_A_Register_High 40
+#define AO_UI_Load_A_Register_Low 41
+#define AO_UI_Load_B_Register 42
+#define AO_UI_Save_Registers 16
+#define AO_BC_Load_A_Register 44
+#define AO_BC_Load_A_Register_High 44
+#define AO_BC_Load_A_Register_Low 45
+#define AO_BC_Load_B_Register 46
+#define AO_BC_Load_B_Register_High 46
+#define AO_BC_Load_B_Register_Low 47
+#define AO_BC_Save_Registers 18
+#define AO_UC_Load_A_Register 48
+#define AO_UC_Load_A_Register_High 48
+#define AO_UC_Load_A_Register_Low 49
+#define AO_UC_Load_B_Register 50
+#define AO_UC_Save_Registers 20
+
+#define Clock_and_FOUT_Register 56
+enum Clock_and_FOUT_bits {
+ FOUT_Enable = _bit15,
+ FOUT_Timebase_Select = _bit14,
+ DIO_Serial_Out_Divide_By_2 = _bit13,
+ Slow_Internal_Time_Divide_By_2 = _bit12,
+ Slow_Internal_Timebase = _bit11,
+ G_Source_Divide_By_2 = _bit10,
+ Clock_To_Board_Divide_By_2 = _bit9,
+ Clock_To_Board = _bit8,
+ AI_Output_Divide_By_2 = _bit7,
+ AI_Source_Divide_By_2 = _bit6,
+ AO_Output_Divide_By_2 = _bit5,
+ AO_Source_Divide_By_2 = _bit4,
+ FOUT_Divider_mask = 0xf
+};
+static inline unsigned FOUT_Divider(unsigned divider)
+{
+ return (divider & FOUT_Divider_mask);
+}
+
+#define IO_Bidirection_Pin_Register 57
+#define RTSI_Trig_Direction_Register 58
+enum RTSI_Trig_Direction_Bits {
+ Drive_RTSI_Clock_Bit = 0x1,
+ Use_RTSI_Clock_Bit = 0x2,
+};
+static inline unsigned RTSI_Output_Bit(unsigned channel, int is_mseries)
+{
+ unsigned max_channel;
+ unsigned base_bit_shift;
+ if (is_mseries) {
+ base_bit_shift = 8;
+ max_channel = 7;
+ } else {
+ base_bit_shift = 9;
+ max_channel = 6;
+ }
+ if (channel > max_channel) {
+ rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
+ channel);
+ return 0;
+ }
+ return 1 << (base_bit_shift + channel);
+}
+
+#define Interrupt_Control_Register 59
+#define Interrupt_B_Enable _bit15
+#define Interrupt_B_Output_Select(x) ((x)<<12)
+#define Interrupt_A_Enable _bit11
+#define Interrupt_A_Output_Select(x) ((x)<<8)
+#define Pass_Thru_0_Interrupt_Polarity _bit3
+#define Pass_Thru_1_Interrupt_Polarity _bit2
+#define Interrupt_Output_On_3_Pins _bit1
+#define Interrupt_Output_Polarity _bit0
+
+#define AI_Output_Control_Register 60
+#define AI_START_Output_Select _bit10
+#define AI_SCAN_IN_PROG_Output_Select(x) (((x) & 0x3) << 8)
+#define AI_EXTMUX_CLK_Output_Select(x) (((x) & 0x3) << 6)
+#define AI_LOCALMUX_CLK_Output_Select(x) ((x)<<4)
+#define AI_SC_TC_Output_Select(x) ((x)<<2)
+enum ai_convert_output_selection {
+ AI_CONVERT_Output_High_Z = 0,
+ AI_CONVERT_Output_Ground = 1,
+ AI_CONVERT_Output_Enable_Low = 2,
+ AI_CONVERT_Output_Enable_High = 3
+};
+static unsigned AI_CONVERT_Output_Select(enum ai_convert_output_selection
+ selection)
+{
+ return selection & 0x3;
+}
+
+#define AI_START_STOP_Select_Register 62
+#define AI_START_Polarity _bit15
+#define AI_STOP_Polarity _bit14
+#define AI_STOP_Sync _bit13
+#define AI_STOP_Edge _bit12
+#define AI_STOP_Select(a) (((a) & 0x1f)<<7)
+#define AI_START_Sync _bit6
+#define AI_START_Edge _bit5
+#define AI_START_Select(a) ((a) & 0x1f)
+
+#define AI_Trigger_Select_Register 63
+#define AI_START1_Polarity _bit15
+#define AI_START2_Polarity _bit14
+#define AI_START2_Sync _bit13
+#define AI_START2_Edge _bit12
+#define AI_START2_Select(a) (((a) & 0x1f) << 7)
+#define AI_START1_Sync _bit6
+#define AI_START1_Edge _bit5
+#define AI_START1_Select(a) ((a) & 0x1f)
+
+#define AI_DIV_Load_A_Register 64
+
+#define AO_Start_Select_Register 66
+#define AO_UI2_Software_Gate _bit15
+#define AO_UI2_External_Gate_Polarity _bit14
+#define AO_START_Polarity _bit13
+#define AO_AOFREQ_Enable _bit12
+#define AO_UI2_External_Gate_Select(a) (((a) & 0x1f) << 7)
+#define AO_START_Sync _bit6
+#define AO_START_Edge _bit5
+#define AO_START_Select(a) ((a) & 0x1f)
+
+#define AO_Trigger_Select_Register 67
+#define AO_UI2_External_Gate_Enable _bit15
+#define AO_Delayed_START1 _bit14
+#define AO_START1_Polarity _bit13
+#define AO_UI2_Source_Polarity _bit12
+#define AO_UI2_Source_Select(x) (((x)&0x1f)<<7)
+#define AO_START1_Sync _bit6
+#define AO_START1_Edge _bit5
+#define AO_START1_Select(x) (((x)&0x1f)<<0)
+
+#define AO_Mode_3_Register 70
+#define AO_UI2_Switch_Load_Next_TC _bit13
+#define AO_UC_Switch_Load_Every_BC_TC _bit12
+#define AO_Trigger_Length _bit11
+#define AO_Stop_On_Overrun_Error _bit5
+#define AO_Stop_On_BC_TC_Trigger_Error _bit4
+#define AO_Stop_On_BC_TC_Error _bit3
+#define AO_Not_An_UPDATE _bit2
+#define AO_Software_Gate _bit1
+#define AO_Last_Gate_Disable _bit0 /* M Series only */
+
+#define Joint_Reset_Register 72
+#define Software_Reset _bit11
+#define AO_Configuration_End _bit9
+#define AI_Configuration_End _bit8
+#define AO_Configuration_Start _bit5
+#define AI_Configuration_Start _bit4
+#define G1_Reset _bit3
+#define G0_Reset _bit2
+#define AO_Reset _bit1
+#define AI_Reset _bit0
+
+#define Interrupt_A_Enable_Register 73
+#define Pass_Thru_0_Interrupt_Enable _bit9
+#define G0_Gate_Interrupt_Enable _bit8
+#define AI_FIFO_Interrupt_Enable _bit7
+#define G0_TC_Interrupt_Enable _bit6
+#define AI_Error_Interrupt_Enable _bit5
+#define AI_STOP_Interrupt_Enable _bit4
+#define AI_START_Interrupt_Enable _bit3
+#define AI_START2_Interrupt_Enable _bit2
+#define AI_START1_Interrupt_Enable _bit1
+#define AI_SC_TC_Interrupt_Enable _bit0
+
+#define Interrupt_B_Enable_Register 75
+#define Pass_Thru_1_Interrupt_Enable _bit11
+#define G1_Gate_Interrupt_Enable _bit10
+#define G1_TC_Interrupt_Enable _bit9
+#define AO_FIFO_Interrupt_Enable _bit8
+#define AO_UI2_TC_Interrupt_Enable _bit7
+#define AO_UC_TC_Interrupt_Enable _bit6
+#define AO_Error_Interrupt_Enable _bit5
+#define AO_STOP_Interrupt_Enable _bit4
+#define AO_START_Interrupt_Enable _bit3
+#define AO_UPDATE_Interrupt_Enable _bit2
+#define AO_START1_Interrupt_Enable _bit1
+#define AO_BC_TC_Interrupt_Enable _bit0
+
+#define Second_IRQ_A_Enable_Register 74
+enum Second_IRQ_A_Enable_Bits {
+ AI_SC_TC_Second_Irq_Enable = _bit0,
+ AI_START1_Second_Irq_Enable = _bit1,
+ AI_START2_Second_Irq_Enable = _bit2,
+ AI_START_Second_Irq_Enable = _bit3,
+ AI_STOP_Second_Irq_Enable = _bit4,
+ AI_Error_Second_Irq_Enable = _bit5,
+ G0_TC_Second_Irq_Enable = _bit6,
+ AI_FIFO_Second_Irq_Enable = _bit7,
+ G0_Gate_Second_Irq_Enable = _bit8,
+ Pass_Thru_0_Second_Irq_Enable = _bit9
+};
+
+#define Second_IRQ_B_Enable_Register 76
+enum Second_IRQ_B_Enable_Bits {
+ AO_BC_TC_Second_Irq_Enable = _bit0,
+ AO_START1_Second_Irq_Enable = _bit1,
+ AO_UPDATE_Second_Irq_Enable = _bit2,
+ AO_START_Second_Irq_Enable = _bit3,
+ AO_STOP_Second_Irq_Enable = _bit4,
+ AO_Error_Second_Irq_Enable = _bit5,
+ AO_UC_TC_Second_Irq_Enable = _bit6,
+ AO_UI2_TC_Second_Irq_Enable = _bit7,
+ AO_FIFO_Second_Irq_Enable = _bit8,
+ G1_TC_Second_Irq_Enable = _bit9,
+ G1_Gate_Second_Irq_Enable = _bit10,
+ Pass_Thru_1_Second_Irq_Enable = _bit11
+};
+
+#define AI_Personal_Register 77
+#define AI_SHIFTIN_Pulse_Width _bit15
+#define AI_EOC_Polarity _bit14
+#define AI_SOC_Polarity _bit13
+#define AI_SHIFTIN_Polarity _bit12
+#define AI_CONVERT_Pulse_Timebase _bit11
+#define AI_CONVERT_Pulse_Width _bit10
+#define AI_CONVERT_Original_Pulse _bit9
+#define AI_FIFO_Flags_Polarity _bit8
+#define AI_Overrun_Mode _bit7
+#define AI_EXTMUX_CLK_Pulse_Width _bit6
+#define AI_LOCALMUX_CLK_Pulse_Width _bit5
+#define AI_AIFREQ_Polarity _bit4
+
+#define AO_Personal_Register 78
+enum AO_Personal_Bits {
+ AO_Interval_Buffer_Mode = 1 << 3,
+ AO_BC_Source_Select = 1 << 4,
+ AO_UPDATE_Pulse_Width = 1 << 5,
+ AO_UPDATE_Pulse_Timebase = 1 << 6,
+ AO_UPDATE_Original_Pulse = 1 << 7,
+ AO_DMA_PIO_Control = 1 << 8, /* M Series: reserved */
+ AO_AOFREQ_Polarity = 1 << 9, /* M Series: reserved */
+ AO_FIFO_Enable = 1 << 10,
+ AO_FIFO_Flags_Polarity = 1 << 11, /* M Series: reserved */
+ AO_TMRDACWR_Pulse_Width = 1 << 12,
+ AO_Fast_CPU = 1 << 13, /* M Series: reserved */
+ AO_Number_Of_DAC_Packages = 1 << 14, // 1 for "single" mode, 0 for "dual"
+ AO_Multiple_DACS_Per_Package = 1 << 15 // m-series only
+};
+#define RTSI_Trig_A_Output_Register 79
+#define RTSI_Trig_B_Output_Register 80
+enum RTSI_Trig_B_Output_Bits {
+ RTSI_Sub_Selection_1_Bit = 0x8000 // not for m-series
+};
+static inline unsigned RTSI_Trig_Output_Bits(unsigned rtsi_channel,
+ unsigned source)
+{
+ return (source & 0xf) << ((rtsi_channel % 4) * 4);
+};
+static inline unsigned RTSI_Trig_Output_Mask(unsigned rtsi_channel)
+{
+ return 0xf << ((rtsi_channel % 4) * 4);
+};
+
+// inverse to RTSI_Trig_Output_Bits()
+static inline unsigned RTSI_Trig_Output_Source(unsigned rtsi_channel,
+ unsigned bits)
+{
+ return (bits >> ((rtsi_channel % 4) * 4)) & 0xf;
+};
+
+#define RTSI_Board_Register 81
+#define Write_Strobe_0_Register 82
+#define Write_Strobe_1_Register 83
+#define Write_Strobe_2_Register 84
+#define Write_Strobe_3_Register 85
+
+#define AO_Output_Control_Register 86
+#define AO_External_Gate_Enable _bit15
+#define AO_External_Gate_Select(x) (((x)&0x1f)<<10)
+#define AO_Number_Of_Channels(x) (((x)&0xf)<<6)
+#define AO_UPDATE2_Output_Select(x) (((x)&0x3)<<4)
+#define AO_External_Gate_Polarity _bit3
+#define AO_UPDATE2_Output_Toggle _bit2
+enum ao_update_output_selection {
+ AO_Update_Output_High_Z = 0,
+ AO_Update_Output_Ground = 1,
+ AO_Update_Output_Enable_Low = 2,
+ AO_Update_Output_Enable_High = 3
+};
+static unsigned AO_UPDATE_Output_Select(enum ao_update_output_selection
+ selection)
+{
+ return selection & 0x3;
+}
+
+#define AI_Mode_3_Register 87
+#define AI_Trigger_Length _bit15
+#define AI_Delay_START _bit14
+#define AI_Software_Gate _bit13
+#define AI_SI_Special_Trigger_Delay _bit12
+#define AI_SI2_Source_Select _bit11
+#define AI_Delayed_START2 _bit10
+#define AI_Delayed_START1 _bit9
+#define AI_External_Gate_Mode _bit8
+#define AI_FIFO_Mode_HF_to_E (3<<6)
+#define AI_FIFO_Mode_F (2<<6)
+#define AI_FIFO_Mode_HF (1<<6)
+#define AI_FIFO_Mode_NE (0<<6)
+#define AI_External_Gate_Polarity _bit5
+#define AI_External_Gate_Select(a) ((a) & 0x1f)
+
+#define G_Autoincrement_Register(a) (68+(a))
+#define G_Command_Register(a) (6+(a))
+#define G_HW_Save_Register(a) (8+(a)*2)
+#define G_HW_Save_Register_High(a) (8+(a)*2)
+#define G_HW_Save_Register_Low(a) (9+(a)*2)
+#define G_Input_Select_Register(a) (36+(a))
+#define G_Load_A_Register(a) (28+(a)*4)
+#define G_Load_A_Register_High(a) (28+(a)*4)
+#define G_Load_A_Register_Low(a) (29+(a)*4)
+#define G_Load_B_Register(a) (30+(a)*4)
+#define G_Load_B_Register_High(a) (30+(a)*4)
+#define G_Load_B_Register_Low(a) (31+(a)*4)
+#define G_Mode_Register(a) (26+(a))
+#define G_Save_Register(a) (12+(a)*2)
+#define G_Save_Register_High(a) (12+(a)*2)
+#define G_Save_Register_Low(a) (13+(a)*2)
+#define G_Status_Register 4
+#define Analog_Trigger_Etc_Register 61
+
+/* command register */
+#define G_Disarm_Copy _bit15 /* strobe */
+#define G_Save_Trace_Copy _bit14
+#define G_Arm_Copy _bit13 /* strobe */
+#define G_Bank_Switch_Start _bit10 /* strobe */
+#define G_Little_Big_Endian _bit9
+#define G_Synchronized_Gate _bit8
+#define G_Write_Switch _bit7
+#define G_Up_Down(a) (((a)&0x03)<<5)
+#define G_Disarm _bit4 /* strobe */
+#define G_Analog_Trigger_Reset _bit3 /* strobe */
+#define G_Save_Trace _bit1
+#define G_Arm _bit0 /* strobe */
+
+/*channel agnostic names for the command register #defines */
+#define G_Bank_Switch_Enable _bit12
+#define G_Bank_Switch_Mode _bit11
+#define G_Load _bit2 /* strobe */
+
+/* input select register */
+#define G_Gate_Select(a) (((a)&0x1f)<<7)
+#define G_Source_Select(a) (((a)&0x1f)<<2)
+#define G_Write_Acknowledges_Irq _bit1
+#define G_Read_Acknowledges_Irq _bit0
+
+/* same input select register, but with channel agnostic names */
+#define G_Source_Polarity _bit15
+#define G_Output_Polarity _bit14
+#define G_OR_Gate _bit13
+#define G_Gate_Select_Load_Source _bit12
+
+/* mode register */
+#define G_Loading_On_TC _bit12
+#define G_Output_Mode(a) (((a)&0x03)<<8)
+#define G_Trigger_Mode_For_Edge_Gate(a) (((a)&0x03)<<3)
+#define G_Gating_Mode(a) (((a)&0x03)<<0)
+
+/* same input mode register, but with channel agnostic names */
+#define G_Load_Source_Select _bit7
+#define G_Reload_Source_Switching _bit15
+#define G_Loading_On_Gate _bit14
+#define G_Gate_Polarity _bit13
+
+#define G_Counting_Once(a) (((a)&0x03)<<10)
+#define G_Stop_Mode(a) (((a)&0x03)<<5)
+#define G_Gate_On_Both_Edges _bit2
+
+/* G_Status_Register */
+#define G1_Gate_Error_St _bit15
+#define G0_Gate_Error_St _bit14
+#define G1_TC_Error_St _bit13
+#define G0_TC_Error_St _bit12
+#define G1_No_Load_Between_Gates_St _bit11
+#define G0_No_Load_Between_Gates_St _bit10
+#define G1_Armed_St _bit9
+#define G0_Armed_St _bit8
+#define G1_Stale_Data_St _bit7
+#define G0_Stale_Data_St _bit6
+#define G1_Next_Load_Source_St _bit5
+#define G0_Next_Load_Source_St _bit4
+#define G1_Counting_St _bit3
+#define G0_Counting_St _bit2
+#define G1_Save_St _bit1
+#define G0_Save_St _bit0
+
+/* general purpose counter timer */
+#define G_Autoincrement(a) ((a)<<0)
+
+/*Analog_Trigger_Etc_Register*/
+#define Analog_Trigger_Mode(x) ((x) & 0x7)
+#define Analog_Trigger_Enable _bit3
+#define Analog_Trigger_Drive _bit4
+#define GPFO_1_Output_Select _bit7
+#define GPFO_0_Output_Select(a) ((a)<<11)
+#define GPFO_0_Output_Enable _bit14
+#define GPFO_1_Output_Enable _bit15
+
+/* Additional windowed registers unique to E series */
+
+/* 16 bit registers shadowed from DAQ-STC */
+#define Window_Address 0x00
+#define Window_Data 0x02
+
+#define Configuration_Memory_Clear 82
+#define ADC_FIFO_Clear 83
+#define DAC_FIFO_Clear 84
+
+/* i/o port offsets */
+
+/* 8 bit registers */
+#define XXX_Status 0x01
+enum XXX_Status_Bits {
+ PROMOUT = 0x1,
+ AI_FIFO_LOWER_NOT_EMPTY = 0x8,
+};
+#define Serial_Command 0x0d
+#define Misc_Command 0x0f
+#define Port_A 0x19
+#define Port_B 0x1b
+#define Port_C 0x1d
+#define Configuration 0x1f
+#define Strobes 0x01
+#define Channel_A_Mode 0x03
+#define Channel_B_Mode 0x05
+#define Channel_C_Mode 0x07
+#define AI_AO_Select 0x09
+enum AI_AO_Select_Bits {
+ AI_DMA_Select_Shift = 0,
+ AI_DMA_Select_Mask = 0xf,
+ AO_DMA_Select_Shift = 4,
+ AO_DMA_Select_Mask = 0xf << AO_DMA_Select_Shift
+};
+#define G0_G1_Select 0x0b
+static inline unsigned ni_stc_dma_channel_select_bitfield(unsigned channel)
+{
+ if (channel < 4)
+ return 1 << channel;
+ if (channel == 4)
+ return 0x3;
+ if (channel == 5)
+ return 0x5;
+ BUG();
+ return 0;
+}
+static inline unsigned GPCT_DMA_Select_Bits(unsigned gpct_index,
+ unsigned mite_channel)
+{
+ BUG_ON(gpct_index > 1);
+ return ni_stc_dma_channel_select_bitfield(mite_channel) << (4 *
+ gpct_index);
+}
+static inline unsigned GPCT_DMA_Select_Mask(unsigned gpct_index)
+{
+ BUG_ON(gpct_index > 1);
+ return 0xf << (4 * gpct_index);
+}
+
+/* 16 bit registers */
+
+#define Configuration_Memory_Low 0x10
+enum Configuration_Memory_Low_Bits {
+ AI_DITHER = 0x200,
+ AI_LAST_CHANNEL = 0x8000,
+};
+#define Configuration_Memory_High 0x12
+enum Configuration_Memory_High_Bits {
+ AI_AC_COUPLE = 0x800,
+ AI_DIFFERENTIAL = 0x1000,
+ AI_COMMON = 0x2000,
+ AI_GROUND = 0x3000,
+};
+static inline unsigned int AI_CONFIG_CHANNEL(unsigned int channel)
+{
+ return (channel & 0x3f);
+}
+
+#define ADC_FIFO_Data_Register 0x1c
+
+#define AO_Configuration 0x16
+#define AO_Bipolar _bit0
+#define AO_Deglitch _bit1
+#define AO_Ext_Ref _bit2
+#define AO_Ground_Ref _bit3
+#define AO_Channel(x) ((x) << 8)
+
+#define DAC_FIFO_Data 0x1e
+#define DAC0_Direct_Data 0x18
+#define DAC1_Direct_Data 0x1a
+
+/* 611x registers (these boards differ from the e-series) */
+
+#define Magic_611x 0x19 /* w8 (new) */
+#define Calibration_Channel_Select_611x 0x1a /* w16 (new) */
+#define ADC_FIFO_Data_611x 0x1c /* r32 (incompatible) */
+#define AI_FIFO_Offset_Load_611x 0x05 /* r8 (new) */
+#define DAC_FIFO_Data_611x 0x14 /* w32 (incompatible) */
+#define Cal_Gain_Select_611x 0x05 /* w8 (new) */
+
+#define AO_Window_Address_611x 0x18
+#define AO_Window_Data_611x 0x1e
+
+/* 6143 registers */
+#define Magic_6143 0x19 /* w8 */
+#define G0G1_DMA_Select_6143 0x0B /* w8 */
+#define PipelineDelay_6143 0x1f /* w8 */
+#define EOC_Set_6143 0x1D /* w8 */
+#define AIDMA_Select_6143 0x09 /* w8 */
+#define AIFIFO_Data_6143 0x8C /* w32 */
+#define AIFIFO_Flag_6143 0x84 /* w32 */
+#define AIFIFO_Control_6143 0x88 /* w32 */
+#define AIFIFO_Status_6143 0x88 /* w32 */
+#define AIFIFO_DMAThreshold_6143 0x90 /* w32 */
+#define AIFIFO_Words_Available_6143 0x94 /* w32 */
+
+#define Calibration_Channel_6143 0x42 /* w16 */
+#define Calibration_LowTime_6143 0x20 /* w16 */
+#define Calibration_HighTime_6143 0x22 /* w16 */
+#define Relay_Counter_Load_Val__6143 0x4C /* w32 */
+#define Signature_6143 0x50 /* w32 */
+#define Release_Date_6143 0x54 /* w32 */
+#define Release_Oldest_Date_6143 0x58 /* w32 */
+
+#define Calibration_Channel_6143_RelayOn 0x8000 /* Calibration relay switch On */
+#define Calibration_Channel_6143_RelayOff 0x4000 /* Calibration relay switch Off */
+#define Calibration_Channel_Gnd_Gnd 0x00 /* Offset Calibration */
+#define Calibration_Channel_2v5_Gnd 0x02 /* 2.5V Reference */
+#define Calibration_Channel_Pwm_Gnd 0x05 /* +/- 5V Self Cal */
+#define Calibration_Channel_2v5_Pwm 0x0a /* PWM Calibration */
+#define Calibration_Channel_Pwm_Pwm 0x0d /* CMRR */
+#define Calibration_Channel_Gnd_Pwm 0x0e /* PWM Calibration */
+
+/* 671x, 611x registers */
+
+/* 671xi, 611x windowed ao registers */
+enum windowed_regs_67xx_61xx {
+ AO_Immediate_671x = 0x11, /* W 16 */
+ AO_Timed_611x = 0x10, /* W 16 */
+ AO_FIFO_Offset_Load_611x = 0x13, /* W32 */
+ AO_Later_Single_Point_Updates = 0x14, /* W 16 */
+ AO_Waveform_Generation_611x = 0x15, /* W 16 */
+ AO_Misc_611x = 0x16, /* W 16 */
+ AO_Calibration_Channel_Select_67xx = 0x17, /* W 16 */
+ AO_Configuration_2_67xx = 0x18, /* W 16 */
+ CAL_ADC_Command_67xx = 0x19, /* W 8 */
+ CAL_ADC_Status_67xx = 0x1a, /* R 8 */
+ CAL_ADC_Data_67xx = 0x1b, /* R 16 */
+ CAL_ADC_Config_Data_High_Word_67xx = 0x1c, /* RW 16 */
+ CAL_ADC_Config_Data_Low_Word_67xx = 0x1d, /* RW 16 */
+};
+static inline unsigned int DACx_Direct_Data_671x(int channel)
+{
+ return channel;
+}
+enum AO_Misc_611x_Bits {
+ CLEAR_WG = 1,
+};
+enum cs5529_configuration_bits {
+ CSCFG_CAL_CONTROL_MASK = 0x7,
+ CSCFG_SELF_CAL_OFFSET = 0x1,
+ CSCFG_SELF_CAL_GAIN = 0x2,
+ CSCFG_SELF_CAL_OFFSET_GAIN = 0x3,
+ CSCFG_SYSTEM_CAL_OFFSET = 0x5,
+ CSCFG_SYSTEM_CAL_GAIN = 0x6,
+ CSCFG_DONE = 1 << 3,
+ CSCFG_POWER_SAVE_SELECT = 1 << 4,
+ CSCFG_PORT_MODE = 1 << 5,
+ CSCFG_RESET_VALID = 1 << 6,
+ CSCFG_RESET = 1 << 7,
+ CSCFG_UNIPOLAR = 1 << 12,
+ CSCFG_WORD_RATE_2180_CYCLES = 0x0 << 13,
+ CSCFG_WORD_RATE_1092_CYCLES = 0x1 << 13,
+ CSCFG_WORD_RATE_532_CYCLES = 0x2 << 13,
+ CSCFG_WORD_RATE_388_CYCLES = 0x3 << 13,
+ CSCFG_WORD_RATE_324_CYCLES = 0x4 << 13,
+ CSCFG_WORD_RATE_17444_CYCLES = 0x5 << 13,
+ CSCFG_WORD_RATE_8724_CYCLES = 0x6 << 13,
+ CSCFG_WORD_RATE_4364_CYCLES = 0x7 << 13,
+ CSCFG_WORD_RATE_MASK = 0x7 << 13,
+ CSCFG_LOW_POWER = 1 << 16,
+};
+static inline unsigned int CS5529_CONFIG_DOUT(int output)
+{
+ return 1 << (18 + output);
+}
+static inline unsigned int CS5529_CONFIG_AOUT(int output)
+{
+ return 1 << (22 + output);
+}
+enum cs5529_command_bits {
+ CSCMD_POWER_SAVE = 0x1,
+ CSCMD_REGISTER_SELECT_MASK = 0xe,
+ CSCMD_OFFSET_REGISTER = 0x0,
+ CSCMD_GAIN_REGISTER = 0x2,
+ CSCMD_CONFIG_REGISTER = 0x4,
+ CSCMD_READ = 0x10,
+ CSCMD_CONTINUOUS_CONVERSIONS = 0x20,
+ CSCMD_SINGLE_CONVERSION = 0x40,
+ CSCMD_COMMAND = 0x80,
+};
+enum cs5529_status_bits {
+ CSS_ADC_BUSY = 0x1,
+ CSS_OSC_DETECT = 0x2, /* indicates adc error */
+ CSS_OVERRANGE = 0x4,
+};
+#define SerDacLd(x) (0x08<<(x))
+
+/*
+ This is stuff unique to the NI E series drivers,
+ but I thought I'd put it here anyway.
+*/
+
+enum { ai_gain_16 =
+ 0, ai_gain_8, ai_gain_14, ai_gain_4, ai_gain_611x, ai_gain_622x,
+ ai_gain_628x, ai_gain_6143 };
+enum caldac_enum { caldac_none = 0, mb88341, dac8800, dac8043, ad8522,
+ ad8804, ad8842, ad8804_debug
+};
+enum ni_reg_type {
+ ni_reg_normal = 0x0,
+ ni_reg_611x = 0x1,
+ ni_reg_6711 = 0x2,
+ ni_reg_6713 = 0x4,
+ ni_reg_67xx_mask = 0x6,
+ ni_reg_6xxx_mask = 0x7,
+ ni_reg_622x = 0x8,
+ ni_reg_625x = 0x10,
+ ni_reg_628x = 0x18,
+ ni_reg_m_series_mask = 0x18,
+ ni_reg_6143 = 0x20
+};
+
+static const struct comedi_lrange range_ni_E_ao_ext;
+
+enum m_series_register_offsets {
+ M_Offset_CDIO_DMA_Select = 0x7, // write
+ M_Offset_SCXI_Status = 0x7, // read
+ M_Offset_AI_AO_Select = 0x9, // write, same offset as e-series
+ M_Offset_SCXI_Serial_Data_In = 0x9, // read
+ M_Offset_G0_G1_Select = 0xb, // write, same offset as e-series
+ M_Offset_Misc_Command = 0xf,
+ M_Offset_SCXI_Serial_Data_Out = 0x11,
+ M_Offset_SCXI_Control = 0x13,
+ M_Offset_SCXI_Output_Enable = 0x15,
+ M_Offset_AI_FIFO_Data = 0x1c,
+ M_Offset_Static_Digital_Output = 0x24, // write
+ M_Offset_Static_Digital_Input = 0x24, // read
+ M_Offset_DIO_Direction = 0x28,
+ M_Offset_Cal_PWM = 0x40,
+ M_Offset_AI_Config_FIFO_Data = 0x5e,
+ M_Offset_Interrupt_C_Enable = 0x88, // write
+ M_Offset_Interrupt_C_Status = 0x88, // read
+ M_Offset_Analog_Trigger_Control = 0x8c,
+ M_Offset_AO_Serial_Interrupt_Enable = 0xa0,
+ M_Offset_AO_Serial_Interrupt_Ack = 0xa1, // write
+ M_Offset_AO_Serial_Interrupt_Status = 0xa1, // read
+ M_Offset_AO_Calibration = 0xa3,
+ M_Offset_AO_FIFO_Data = 0xa4,
+ M_Offset_PFI_Filter = 0xb0,
+ M_Offset_RTSI_Filter = 0xb4,
+ M_Offset_SCXI_Legacy_Compatibility = 0xbc,
+ M_Offset_Interrupt_A_Ack = 0x104, // write
+ M_Offset_AI_Status_1 = 0x104, // read
+ M_Offset_Interrupt_B_Ack = 0x106, // write
+ M_Offset_AO_Status_1 = 0x106, // read
+ M_Offset_AI_Command_2 = 0x108, // write
+ M_Offset_G01_Status = 0x108, // read
+ M_Offset_AO_Command_2 = 0x10a,
+ M_Offset_AO_Status_2 = 0x10c, // read
+ M_Offset_G0_Command = 0x10c, // write
+ M_Offset_G1_Command = 0x10e, // write
+ M_Offset_G0_HW_Save = 0x110,
+ M_Offset_G0_HW_Save_High = 0x110,
+ M_Offset_AI_Command_1 = 0x110,
+ M_Offset_G0_HW_Save_Low = 0x112,
+ M_Offset_AO_Command_1 = 0x112,
+ M_Offset_G1_HW_Save = 0x114,
+ M_Offset_G1_HW_Save_High = 0x114,
+ M_Offset_G1_HW_Save_Low = 0x116,
+ M_Offset_AI_Mode_1 = 0x118,
+ M_Offset_G0_Save = 0x118,
+ M_Offset_G0_Save_High = 0x118,
+ M_Offset_AI_Mode_2 = 0x11a,
+ M_Offset_G0_Save_Low = 0x11a,
+ M_Offset_AI_SI_Load_A = 0x11c,
+ M_Offset_G1_Save = 0x11c,
+ M_Offset_G1_Save_High = 0x11c,
+ M_Offset_G1_Save_Low = 0x11e,
+ M_Offset_AI_SI_Load_B = 0x120, // write
+ M_Offset_AO_UI_Save = 0x120, // read
+ M_Offset_AI_SC_Load_A = 0x124, // write
+ M_Offset_AO_BC_Save = 0x124, // read
+ M_Offset_AI_SC_Load_B = 0x128, // write
+ M_Offset_AO_UC_Save = 0x128, //read
+ M_Offset_AI_SI2_Load_A = 0x12c,
+ M_Offset_AI_SI2_Load_B = 0x130,
+ M_Offset_G0_Mode = 0x134,
+ M_Offset_G1_Mode = 0x136, // write
+ M_Offset_Joint_Status_1 = 0x136, // read
+ M_Offset_G0_Load_A = 0x138,
+ M_Offset_Joint_Status_2 = 0x13a,
+ M_Offset_G0_Load_B = 0x13c,
+ M_Offset_G1_Load_A = 0x140,
+ M_Offset_G1_Load_B = 0x144,
+ M_Offset_G0_Input_Select = 0x148,
+ M_Offset_G1_Input_Select = 0x14a,
+ M_Offset_AO_Mode_1 = 0x14c,
+ M_Offset_AO_Mode_2 = 0x14e,
+ M_Offset_AO_UI_Load_A = 0x150,
+ M_Offset_AO_UI_Load_B = 0x154,
+ M_Offset_AO_BC_Load_A = 0x158,
+ M_Offset_AO_BC_Load_B = 0x15c,
+ M_Offset_AO_UC_Load_A = 0x160,
+ M_Offset_AO_UC_Load_B = 0x164,
+ M_Offset_Clock_and_FOUT = 0x170,
+ M_Offset_IO_Bidirection_Pin = 0x172,
+ M_Offset_RTSI_Trig_Direction = 0x174,
+ M_Offset_Interrupt_Control = 0x176,
+ M_Offset_AI_Output_Control = 0x178,
+ M_Offset_Analog_Trigger_Etc = 0x17a,
+ M_Offset_AI_START_STOP_Select = 0x17c,
+ M_Offset_AI_Trigger_Select = 0x17e,
+ M_Offset_AI_SI_Save = 0x180, // read
+ M_Offset_AI_DIV_Load_A = 0x180, // write
+ M_Offset_AI_SC_Save = 0x184, // read
+ M_Offset_AO_Start_Select = 0x184, // write
+ M_Offset_AO_Trigger_Select = 0x186,
+ M_Offset_AO_Mode_3 = 0x18c,
+ M_Offset_G0_Autoincrement = 0x188,
+ M_Offset_G1_Autoincrement = 0x18a,
+ M_Offset_Joint_Reset = 0x190,
+ M_Offset_Interrupt_A_Enable = 0x192,
+ M_Offset_Interrupt_B_Enable = 0x196,
+ M_Offset_AI_Personal = 0x19a,
+ M_Offset_AO_Personal = 0x19c,
+ M_Offset_RTSI_Trig_A_Output = 0x19e,
+ M_Offset_RTSI_Trig_B_Output = 0x1a0,
+ M_Offset_RTSI_Shared_MUX = 0x1a2,
+ M_Offset_AO_Output_Control = 0x1ac,
+ M_Offset_AI_Mode_3 = 0x1ae,
+ M_Offset_Configuration_Memory_Clear = 0x1a4,
+ M_Offset_AI_FIFO_Clear = 0x1a6,
+ M_Offset_AO_FIFO_Clear = 0x1a8,
+ M_Offset_G0_Counting_Mode = 0x1b0,
+ M_Offset_G1_Counting_Mode = 0x1b2,
+ M_Offset_G0_Second_Gate = 0x1b4,
+ M_Offset_G1_Second_Gate = 0x1b6,
+ M_Offset_G0_DMA_Config = 0x1b8, // write
+ M_Offset_G0_DMA_Status = 0x1b8, // read
+ M_Offset_G1_DMA_Config = 0x1ba, // write
+ M_Offset_G1_DMA_Status = 0x1ba, // read
+ M_Offset_G0_MSeries_ABZ = 0x1c0,
+ M_Offset_G1_MSeries_ABZ = 0x1c2,
+ M_Offset_Clock_and_Fout2 = 0x1c4,
+ M_Offset_PLL_Control = 0x1c6,
+ M_Offset_PLL_Status = 0x1c8,
+ M_Offset_PFI_Output_Select_1 = 0x1d0,
+ M_Offset_PFI_Output_Select_2 = 0x1d2,
+ M_Offset_PFI_Output_Select_3 = 0x1d4,
+ M_Offset_PFI_Output_Select_4 = 0x1d6,
+ M_Offset_PFI_Output_Select_5 = 0x1d8,
+ M_Offset_PFI_Output_Select_6 = 0x1da,
+ M_Offset_PFI_DI = 0x1dc,
+ M_Offset_PFI_DO = 0x1de,
+ M_Offset_AI_Config_FIFO_Bypass = 0x218,
+ M_Offset_SCXI_DIO_Enable = 0x21c,
+ M_Offset_CDI_FIFO_Data = 0x220, // read
+ M_Offset_CDO_FIFO_Data = 0x220, // write
+ M_Offset_CDIO_Status = 0x224, // read
+ M_Offset_CDIO_Command = 0x224, // write
+ M_Offset_CDI_Mode = 0x228,
+ M_Offset_CDO_Mode = 0x22c,
+ M_Offset_CDI_Mask_Enable = 0x230,
+ M_Offset_CDO_Mask_Enable = 0x234,
+};
+static inline int M_Offset_AO_Waveform_Order(int channel)
+{
+ return 0xc2 + 0x4 * channel;
+};
+static inline int M_Offset_AO_Config_Bank(int channel)
+{
+ return 0xc3 + 0x4 * channel;
+};
+static inline int M_Offset_DAC_Direct_Data(int channel)
+{
+ return 0xc0 + 0x4 * channel;
+}
+static inline int M_Offset_Gen_PWM(int channel)
+{
+ return 0x44 + 0x2 * channel;
+}
+static inline int M_Offset_Static_AI_Control(int i)
+{
+ int offset[] = {
+ 0x64,
+ 0x261,
+ 0x262,
+ 0x263,
+ };
+ if (((unsigned)i) >= sizeof(offset) / sizeof(offset[0])) {
+ rt_printk("%s: invalid channel=%i\n", __FUNCTION__, i);
+ return offset[0];
+ }
+ return offset[i];
+};
+static inline int M_Offset_AO_Reference_Attenuation(int channel)
+{
+ int offset[] = {
+ 0x264,
+ 0x265,
+ 0x266,
+ 0x267
+ };
+ if (((unsigned)channel) >= sizeof(offset) / sizeof(offset[0])) {
+ rt_printk("%s: invalid channel=%i\n", __FUNCTION__, channel);
+ return offset[0];
+ }
+ return offset[channel];
+};
+static inline unsigned M_Offset_PFI_Output_Select(unsigned n)
+{
+ if (n < 1 || n > NUM_PFI_OUTPUT_SELECT_REGS) {
+ rt_printk("%s: invalid pfi output select register=%i\n",
+ __FUNCTION__, n);
+ return M_Offset_PFI_Output_Select_1;
+ }
+ return M_Offset_PFI_Output_Select_1 + (n - 1) * 2;
+}
+
+enum MSeries_AI_Config_FIFO_Data_Bits {
+ MSeries_AI_Config_Channel_Type_Mask = 0x7 << 6,
+ MSeries_AI_Config_Channel_Type_Calibration_Bits = 0x0,
+ MSeries_AI_Config_Channel_Type_Differential_Bits = 0x1 << 6,
+ MSeries_AI_Config_Channel_Type_Common_Ref_Bits = 0x2 << 6,
+ MSeries_AI_Config_Channel_Type_Ground_Ref_Bits = 0x3 << 6,
+ MSeries_AI_Config_Channel_Type_Aux_Bits = 0x5 << 6,
+ MSeries_AI_Config_Channel_Type_Ghost_Bits = 0x7 << 6,
+ MSeries_AI_Config_Polarity_Bit = 0x1000, // 0 for 2's complement encoding
+ MSeries_AI_Config_Dither_Bit = 0x2000,
+ MSeries_AI_Config_Last_Channel_Bit = 0x4000,
+};
+static inline unsigned MSeries_AI_Config_Channel_Bits(unsigned channel)
+{
+ return channel & 0xf;
+}
+static inline unsigned MSeries_AI_Config_Bank_Bits(enum ni_reg_type reg_type,
+ unsigned channel)
+{
+ unsigned bits = channel & 0x30;
+ if (reg_type == ni_reg_622x) {
+ if (channel & 0x40)
+ bits |= 0x400;
+ }
+ return bits;
+}
+static inline unsigned MSeries_AI_Config_Gain_Bits(unsigned range)
+{
+ return (range & 0x7) << 9;
+}
+
+enum MSeries_Clock_and_Fout2_Bits {
+ MSeries_PLL_In_Source_Select_RTSI0_Bits = 0xb,
+ MSeries_PLL_In_Source_Select_Star_Trigger_Bits = 0x14,
+ MSeries_PLL_In_Source_Select_RTSI7_Bits = 0x1b,
+ MSeries_PLL_In_Source_Select_PXI_Clock10 = 0x1d,
+ MSeries_PLL_In_Source_Select_Mask = 0x1f,
+ MSeries_Timebase1_Select_Bit = 0x20, // use PLL for timebase 1
+ MSeries_Timebase3_Select_Bit = 0x40, // use PLL for timebase 3
+ /* use 10MHz instead of 20MHz for RTSI clock frequency. Appears
+ to have no effect, at least on pxi-6281, which always uses
+ 20MHz rtsi clock frequency */
+ MSeries_RTSI_10MHz_Bit = 0x80
+};
+static inline unsigned MSeries_PLL_In_Source_Select_RTSI_Bits(unsigned
+ RTSI_channel)
+{
+ if (RTSI_channel > 7) {
+ rt_printk("%s: bug, invalid RTSI_channel=%i\n", __FUNCTION__,
+ RTSI_channel);
+ return 0;
+ }
+ if (RTSI_channel == 7)
+ return MSeries_PLL_In_Source_Select_RTSI7_Bits;
+ else
+ return MSeries_PLL_In_Source_Select_RTSI0_Bits + RTSI_channel;
+}
+
+enum MSeries_PLL_Control_Bits {
+ MSeries_PLL_Enable_Bit = 0x1000,
+ MSeries_PLL_VCO_Mode_200_325MHz_Bits = 0x0,
+ MSeries_PLL_VCO_Mode_175_225MHz_Bits = 0x2000,
+ MSeries_PLL_VCO_Mode_100_225MHz_Bits = 0x4000,
+ MSeries_PLL_VCO_Mode_75_150MHz_Bits = 0x6000,
+};
+static inline unsigned MSeries_PLL_Divisor_Bits(unsigned divisor)
+{
+ static const unsigned max_divisor = 0x10;
+ if (divisor < 1 || divisor > max_divisor) {
+ rt_printk("%s: bug, invalid divisor=%i\n", __FUNCTION__,
+ divisor);
+ return 0;
+ }
+ return (divisor & 0xf) << 8;
+}
+static inline unsigned MSeries_PLL_Multiplier_Bits(unsigned multiplier)
+{
+ static const unsigned max_multiplier = 0x100;
+ if (multiplier < 1 || multiplier > max_multiplier) {
+ rt_printk("%s: bug, invalid multiplier=%i\n", __FUNCTION__,
+ multiplier);
+ return 0;
+ }
+ return multiplier & 0xff;
+}
+
+enum MSeries_PLL_Status {
+ MSeries_PLL_Locked_Bit = 0x1
+};
+
+enum MSeries_AI_Config_FIFO_Bypass_Bits {
+ MSeries_AI_Bypass_Channel_Mask = 0x7,
+ MSeries_AI_Bypass_Bank_Mask = 0x78,
+ MSeries_AI_Bypass_Cal_Sel_Pos_Mask = 0x380,
+ MSeries_AI_Bypass_Cal_Sel_Neg_Mask = 0x1c00,
+ MSeries_AI_Bypass_Mode_Mux_Mask = 0x6000,
+ MSeries_AO_Bypass_AO_Cal_Sel_Mask = 0x38000,
+ MSeries_AI_Bypass_Gain_Mask = 0x1c0000,
+ MSeries_AI_Bypass_Dither_Bit = 0x200000,
+ MSeries_AI_Bypass_Polarity_Bit = 0x400000, // 0 for 2's complement encoding
+ MSeries_AI_Bypass_Config_FIFO_Bit = 0x80000000
+};
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Pos_Bits(int
+ calibration_source)
+{
+ return (calibration_source << 7) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Cal_Sel_Neg_Bits(int
+ calibration_source)
+{
+ return (calibration_source << 10) & MSeries_AI_Bypass_Cal_Sel_Pos_Mask;
+}
+static inline unsigned MSeries_AI_Bypass_Gain_Bits(int gain)
+{
+ return (gain << 18) & MSeries_AI_Bypass_Gain_Mask;
+}
+
+enum MSeries_AO_Config_Bank_Bits {
+ MSeries_AO_DAC_Offset_Select_Mask = 0x7,
+ MSeries_AO_DAC_Offset_0V_Bits = 0x0,
+ MSeries_AO_DAC_Offset_5V_Bits = 0x1,
+ MSeries_AO_DAC_Reference_Mask = 0x38,
+ MSeries_AO_DAC_Reference_10V_Internal_Bits = 0x0,
+ MSeries_AO_DAC_Reference_5V_Internal_Bits = 0x8,
+ MSeries_AO_Update_Timed_Bit = 0x40,
+ MSeries_AO_Bipolar_Bit = 0x80 // turns on 2's complement encoding
+};
+
+enum MSeries_AO_Reference_Attenuation_Bits {
+ MSeries_Attenuate_x5_Bit = 0x1
+};
+
+static inline unsigned MSeries_Cal_PWM_High_Time_Bits(unsigned count)
+{
+ return (count << 16) & 0xffff0000;
+}
+
+static inline unsigned MSeries_Cal_PWM_Low_Time_Bits(unsigned count)
+{
+ return count & 0xffff;
+}
+
+static inline unsigned MSeries_PFI_Output_Select_Mask(unsigned channel)
+{
+ return 0x1f << (channel % 3) * 5;
+};
+static inline unsigned MSeries_PFI_Output_Select_Bits(unsigned channel,
+ unsigned source)
+{
+ return (source & 0x1f) << ((channel % 3) * 5);
+};
+
+// inverse to MSeries_PFI_Output_Select_Bits
+static inline unsigned MSeries_PFI_Output_Select_Source(unsigned channel,
+ unsigned bits)
+{
+ return (bits >> ((channel % 3) * 5)) & 0x1f;
+};
+
+enum MSeries_Gi_DMA_Config_Bits {
+ Gi_DMA_BankSW_Error_Bit = 0x10,
+ Gi_DMA_Reset_Bit = 0x8,
+ Gi_DMA_Int_Enable_Bit = 0x4,
+ Gi_DMA_Write_Bit = 0x2,
+ Gi_DMA_Enable_Bit = 0x1,
+};
+
+static inline unsigned MSeries_PFI_Filter_Select_Mask(unsigned channel)
+{
+ return 0x3 << (channel * 2);
+}
+static inline unsigned MSeries_PFI_Filter_Select_Bits(unsigned channel,
+ unsigned filter)
+{
+ return (filter << (channel *
+ 2)) & MSeries_PFI_Filter_Select_Mask(channel);
+}
+
+enum CDIO_DMA_Select_Bits {
+ CDI_DMA_Select_Shift = 0,
+ CDI_DMA_Select_Mask = 0xf,
+ CDO_DMA_Select_Shift = 4,
+ CDO_DMA_Select_Mask = 0xf << CDO_DMA_Select_Shift
+};
+
+enum CDIO_Status_Bits {
+ CDO_FIFO_Empty_Bit = 0x1,
+ CDO_FIFO_Full_Bit = 0x2,
+ CDO_FIFO_Request_Bit = 0x4,
+ CDO_Overrun_Bit = 0x8,
+ CDO_Underflow_Bit = 0x10,
+ CDI_FIFO_Empty_Bit = 0x10000,
+ CDI_FIFO_Full_Bit = 0x20000,
+ CDI_FIFO_Request_Bit = 0x40000,
+ CDI_Overrun_Bit = 0x80000,
+ CDI_Overflow_Bit = 0x100000
+};
+
+enum CDIO_Command_Bits {
+ CDO_Disarm_Bit = 0x1,
+ CDO_Arm_Bit = 0x2,
+ CDI_Disarm_Bit = 0x4,
+ CDI_Arm_Bit = 0x8,
+ CDO_Reset_Bit = 0x10,
+ CDI_Reset_Bit = 0x20,
+ CDO_Error_Interrupt_Enable_Set_Bit = 0x40,
+ CDO_Error_Interrupt_Enable_Clear_Bit = 0x80,
+ CDI_Error_Interrupt_Enable_Set_Bit = 0x100,
+ CDI_Error_Interrupt_Enable_Clear_Bit = 0x200,
+ CDO_FIFO_Request_Interrupt_Enable_Set_Bit = 0x400,
+ CDO_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x800,
+ CDI_FIFO_Request_Interrupt_Enable_Set_Bit = 0x1000,
+ CDI_FIFO_Request_Interrupt_Enable_Clear_Bit = 0x2000,
+ CDO_Error_Interrupt_Confirm_Bit = 0x4000,
+ CDI_Error_Interrupt_Confirm_Bit = 0x8000,
+ CDO_Empty_FIFO_Interrupt_Enable_Set_Bit = 0x10000,
+ CDO_Empty_FIFO_Interrupt_Enable_Clear_Bit = 0x20000,
+ CDO_SW_Update_Bit = 0x80000,
+ CDI_SW_Update_Bit = 0x100000
+};
+
+enum CDI_Mode_Bits {
+ CDI_Sample_Source_Select_Mask = 0x3f,
+ CDI_Halt_On_Error_Bit = 0x200,
+ CDI_Polarity_Bit = 0x400, // sample clock on falling edge
+ CDI_FIFO_Mode_Bit = 0x800, // set for half full mode, clear for not empty mode
+ CDI_Data_Lane_Mask = 0x3000, // data lanes specify which dio channels map to byte or word accesses to the dio fifos
+ CDI_Data_Lane_0_15_Bits = 0x0,
+ CDI_Data_Lane_16_31_Bits = 0x1000,
+ CDI_Data_Lane_0_7_Bits = 0x0,
+ CDI_Data_Lane_8_15_Bits = 0x1000,
+ CDI_Data_Lane_16_23_Bits = 0x2000,
+ CDI_Data_Lane_24_31_Bits = 0x3000
+};
+
+enum CDO_Mode_Bits {
+ CDO_Sample_Source_Select_Mask = 0x3f,
+ CDO_Retransmit_Bit = 0x100,
+ CDO_Halt_On_Error_Bit = 0x200,
+ CDO_Polarity_Bit = 0x400, // sample clock on falling edge
+ CDO_FIFO_Mode_Bit = 0x800, // set for half full mode, clear for not full mode
+ CDO_Data_Lane_Mask = 0x3000, // data lanes specify which dio channels map to byte or word accesses to the dio fifos
+ CDO_Data_Lane_0_15_Bits = 0x0,
+ CDO_Data_Lane_16_31_Bits = 0x1000,
+ CDO_Data_Lane_0_7_Bits = 0x0,
+ CDO_Data_Lane_8_15_Bits = 0x1000,
+ CDO_Data_Lane_16_23_Bits = 0x2000,
+ CDO_Data_Lane_24_31_Bits = 0x3000
+};
+
+enum Interrupt_C_Enable_Bits {
+ Interrupt_Group_C_Enable_Bit = 0x1
+};
+
+enum Interrupt_C_Status_Bits {
+ Interrupt_Group_C_Status_Bit = 0x1
+};
+
+#define M_SERIES_EEPROM_SIZE 1024
+
+typedef struct ni_board_struct {
+ int device_id;
+ int isapnp_id;
+ char *name;
+
+ int n_adchan;
+ int adbits;
+
+ int ai_fifo_depth;
+ unsigned int alwaysdither:1;
+ int gainlkup;
+ int ai_speed;
+
+ int n_aochan;
+ int aobits;
+ int ao_fifo_depth;
+ const struct comedi_lrange *ao_range_table;
+ unsigned ao_speed;
+
+ unsigned num_p0_dio_channels;
+
+ int reg_type;
+ unsigned int ao_unipolar:1;
+ unsigned int has_8255:1;
+ unsigned int has_analog_trig:1;
+
+ enum caldac_enum caldac[3];
+} ni_board;
+
+#define n_ni_boards (sizeof(ni_boards)/sizeof(ni_board))
+
+#define boardtype (*(ni_board *)dev->board_ptr)
+
+#define MAX_N_AO_CHAN 8
+#define NUM_GPCT 2
+
+#define NI_PRIVATE_COMMON \
+ uint16_t (*stc_readw)(struct comedi_device *dev, int register); \
+ uint32_t (*stc_readl)(struct comedi_device *dev, int register); \
+ void (*stc_writew)(struct comedi_device *dev, uint16_t value, int register); \
+ void (*stc_writel)(struct comedi_device *dev, uint32_t value, int register); \
+ \
+ unsigned short dio_output; \
+ unsigned short dio_control; \
+ int ao0p,ao1p; \
+ int lastchan; \
+ int last_do; \
+ int rt_irq; \
+ int irqmask; \
+ int aimode; \
+ int ai_continuous; \
+ int blocksize; \
+ int n_left; \
+ unsigned int ai_calib_source; \
+ unsigned int ai_calib_source_enabled; \
+ spinlock_t window_lock; \
+ spinlock_t soft_reg_copy_lock; \
+ spinlock_t mite_channel_lock; \
+ \
+ int changain_state; \
+ unsigned int changain_spec; \
+ \
+ unsigned int caldac_maxdata_list[MAX_N_CALDACS]; \
+ unsigned short ao[MAX_N_AO_CHAN]; \
+ unsigned short caldacs[MAX_N_CALDACS]; \
+ \
+ unsigned short ai_cmd2; \
+ \
+ unsigned short ao_conf[MAX_N_AO_CHAN]; \
+ unsigned short ao_mode1; \
+ unsigned short ao_mode2; \
+ unsigned short ao_mode3; \
+ unsigned short ao_cmd1; \
+ unsigned short ao_cmd2; \
+ unsigned short ao_cmd3; \
+ unsigned short ao_trigger_select; \
+ \
+ struct ni_gpct_device *counter_dev; \
+ unsigned short an_trig_etc_reg; \
+ \
+ unsigned ai_offset[512]; \
+ \
+ unsigned long serial_interval_ns; \
+ unsigned char serial_hw_mode; \
+ unsigned short clock_and_fout; \
+ unsigned short clock_and_fout2; \
+ \
+ unsigned short int_a_enable_reg; \
+ unsigned short int_b_enable_reg; \
+ unsigned short io_bidirection_pin_reg; \
+ unsigned short rtsi_trig_direction_reg; \
+ unsigned short rtsi_trig_a_output_reg; \
+ unsigned short rtsi_trig_b_output_reg; \
+ unsigned short pfi_output_select_reg[NUM_PFI_OUTPUT_SELECT_REGS]; \
+ unsigned short ai_ao_select_reg; \
+ unsigned short g0_g1_select_reg; \
+ unsigned short cdio_dma_select_reg; \
+ \
+ unsigned clock_ns; \
+ unsigned clock_source; \
+ \
+ unsigned short atrig_mode; \
+ unsigned short atrig_high; \
+ unsigned short atrig_low; \
+ \
+ unsigned short pwm_up_count; \
+ unsigned short pwm_down_count; \
+ \
+ short ai_fifo_buffer[0x2000]; \
+ uint8_t eeprom_buffer[M_SERIES_EEPROM_SIZE]; \
+ uint32_t serial_number; \
+ \
+ struct mite_struct *mite; \
+ struct mite_channel *ai_mite_chan; \
+ struct mite_channel *ao_mite_chan;\
+ struct mite_channel *cdo_mite_chan;\
+ struct mite_dma_descriptor_ring *ai_mite_ring; \
+ struct mite_dma_descriptor_ring *ao_mite_ring; \
+ struct mite_dma_descriptor_ring *cdo_mite_ring; \
+ struct mite_dma_descriptor_ring *gpct_mite_ring[NUM_GPCT];
+
+#endif /* _COMEDI_NI_STC_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
new file mode 100644
index 00000000000..05a95754039
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio.c
@@ -0,0 +1,1691 @@
+/*
+ comedi/drivers/ni_tio.c
+ Support for NI general purpose counters
+
+ Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+Driver: ni_tio
+Description: National Instruments general purpose counters
+Devices:
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+ Herman.Bruyninckx@mech.kuleuven.ac.be,
+ Wim.Meeussen@mech.kuleuven.ac.be,
+ Klaas.Gadeyne@mech.kuleuven.ac.be,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Thu Nov 16 09:50:32 EST 2006
+Status: works
+
+This module is not used directly by end-users. Rather, it
+is used by other drivers (for example ni_660x and ni_pcimio)
+to provide support for NI's general purpose counters. It was
+originally based on the counter code from ni_660x.c and
+ni_mio_common.c.
+
+References:
+DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+340934b.pdf DAQ-STC reference manual
+
+*/
+/*
+TODO:
+ Support use of both banks X and Y
+*/
+
+#include "ni_tio_internal.h"
+
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+ unsigned generic_clock_source);
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter);
+
+MODULE_AUTHOR("Comedi <comedi@comedi.org>");
+MODULE_DESCRIPTION("Comedi support for NI general-purpose counters");
+MODULE_LICENSE("GPL");
+
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Alternate_Sync_Bit(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_Alternate_Sync_Bit;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_Alternate_Sync_Bit;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X2_Bit(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_Prescale_X2_Bit;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_Prescale_X2_Bit;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_Prescale_X8_Bit(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_Prescale_X8_Bit;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_Prescale_X8_Bit;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+static inline enum Gi_Counting_Mode_Reg_Bits Gi_HW_Arm_Select_Mask(enum
+ ni_gpct_variant variant)
+{
+ switch (variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ return Gi_M_Series_HW_Arm_Select_Mask;
+ break;
+ case ni_gpct_variant_660x:
+ return Gi_660x_HW_Arm_Select_Mask;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+/* clock sources for ni_660x boards, get bits with Gi_Source_Select_Bits() */
+enum ni_660x_clock_source {
+ NI_660x_Timebase_1_Clock = 0x0, /* 20MHz */
+ NI_660x_Source_Pin_i_Clock = 0x1,
+ NI_660x_Next_Gate_Clock = 0xa,
+ NI_660x_Timebase_2_Clock = 0x12, /* 100KHz */
+ NI_660x_Next_TC_Clock = 0x13,
+ NI_660x_Timebase_3_Clock = 0x1e, /* 80MHz */
+ NI_660x_Logic_Low_Clock = 0x1f,
+};
+static const unsigned ni_660x_max_rtsi_channel = 6;
+static inline unsigned NI_660x_RTSI_Clock(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_rtsi_channel);
+ return (0xb + n);
+}
+static const unsigned ni_660x_max_source_pin = 7;
+static inline unsigned NI_660x_Source_Pin_Clock(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_source_pin);
+ return (0x2 + n);
+}
+
+/* clock sources for ni e and m series boards, get bits with Gi_Source_Select_Bits() */
+enum ni_m_series_clock_source {
+ NI_M_Series_Timebase_1_Clock = 0x0, /* 20MHz */
+ NI_M_Series_Timebase_2_Clock = 0x12, /* 100KHz */
+ NI_M_Series_Next_TC_Clock = 0x13,
+ NI_M_Series_Next_Gate_Clock = 0x14, /* when Gi_Src_SubSelect = 0 */
+ NI_M_Series_PXI_Star_Trigger_Clock = 0x14, /* when Gi_Src_SubSelect = 1 */
+ NI_M_Series_PXI10_Clock = 0x1d,
+ NI_M_Series_Timebase_3_Clock = 0x1e, /* 80MHz, when Gi_Src_SubSelect = 0 */
+ NI_M_Series_Analog_Trigger_Out_Clock = 0x1e, /* when Gi_Src_SubSelect = 1 */
+ NI_M_Series_Logic_Low_Clock = 0x1f,
+};
+static const unsigned ni_m_series_max_pfi_channel = 15;
+static inline unsigned NI_M_Series_PFI_Clock(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_pfi_channel);
+ if (n < 10)
+ return 1 + n;
+ else
+ return 0xb + n;
+}
+static const unsigned ni_m_series_max_rtsi_channel = 7;
+static inline unsigned NI_M_Series_RTSI_Clock(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_rtsi_channel);
+ if (n == 7)
+ return 0x1b;
+ else
+ return 0xb + n;
+}
+
+enum ni_660x_gate_select {
+ NI_660x_Source_Pin_i_Gate_Select = 0x0,
+ NI_660x_Gate_Pin_i_Gate_Select = 0x1,
+ NI_660x_Next_SRC_Gate_Select = 0xa,
+ NI_660x_Next_Out_Gate_Select = 0x14,
+ NI_660x_Logic_Low_Gate_Select = 0x1f,
+};
+static const unsigned ni_660x_max_gate_pin = 7;
+static inline unsigned NI_660x_Gate_Pin_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_gate_pin);
+ return 0x2 + n;
+}
+static inline unsigned NI_660x_RTSI_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_rtsi_channel);
+ return 0xb + n;
+}
+
+enum ni_m_series_gate_select {
+ NI_M_Series_Timestamp_Mux_Gate_Select = 0x0,
+ NI_M_Series_AI_START2_Gate_Select = 0x12,
+ NI_M_Series_PXI_Star_Trigger_Gate_Select = 0x13,
+ NI_M_Series_Next_Out_Gate_Select = 0x14,
+ NI_M_Series_AI_START1_Gate_Select = 0x1c,
+ NI_M_Series_Next_SRC_Gate_Select = 0x1d,
+ NI_M_Series_Analog_Trigger_Out_Gate_Select = 0x1e,
+ NI_M_Series_Logic_Low_Gate_Select = 0x1f,
+};
+static inline unsigned NI_M_Series_RTSI_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_rtsi_channel);
+ if (n == 7)
+ return 0x1b;
+ return 0xb + n;
+}
+static inline unsigned NI_M_Series_PFI_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_m_series_max_pfi_channel);
+ if (n < 10)
+ return 1 + n;
+ return 0xb + n;
+}
+
+static inline unsigned Gi_Source_Select_Bits(unsigned source)
+{
+ return (source << Gi_Source_Select_Shift) & Gi_Source_Select_Mask;
+}
+static inline unsigned Gi_Gate_Select_Bits(unsigned gate_select)
+{
+ return (gate_select << Gi_Gate_Select_Shift) & Gi_Gate_Select_Mask;
+}
+
+enum ni_660x_second_gate_select {
+ NI_660x_Source_Pin_i_Second_Gate_Select = 0x0,
+ NI_660x_Up_Down_Pin_i_Second_Gate_Select = 0x1,
+ NI_660x_Next_SRC_Second_Gate_Select = 0xa,
+ NI_660x_Next_Out_Second_Gate_Select = 0x14,
+ NI_660x_Selected_Gate_Second_Gate_Select = 0x1e,
+ NI_660x_Logic_Low_Second_Gate_Select = 0x1f,
+};
+static const unsigned ni_660x_max_up_down_pin = 7;
+static inline unsigned NI_660x_Up_Down_Pin_Second_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_up_down_pin);
+ return 0x2 + n;
+}
+static inline unsigned NI_660x_RTSI_Second_Gate_Select(unsigned n)
+{
+ BUG_ON(n > ni_660x_max_rtsi_channel);
+ return 0xb + n;
+}
+
+static const unsigned int counter_status_mask =
+ COMEDI_COUNTER_ARMED | COMEDI_COUNTER_COUNTING;
+
+static int __init ni_tio_init_module(void)
+{
+ return 0;
+}
+
+module_init(ni_tio_init_module);
+
+static void __exit ni_tio_cleanup_module(void)
+{
+}
+
+module_exit(ni_tio_cleanup_module);
+
+struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device * dev,
+ void (*write_register) (struct ni_gpct * counter, unsigned bits,
+ enum ni_gpct_register reg),
+ unsigned (*read_register) (struct ni_gpct * counter,
+ enum ni_gpct_register reg), enum ni_gpct_variant variant,
+ unsigned num_counters)
+{
+ unsigned i;
+
+ struct ni_gpct_device *counter_dev =
+ kzalloc(sizeof(struct ni_gpct_device), GFP_KERNEL);
+ if (counter_dev == NULL)
+ return NULL;
+ counter_dev->dev = dev;
+ counter_dev->write_register = write_register;
+ counter_dev->read_register = read_register;
+ counter_dev->variant = variant;
+ spin_lock_init(&counter_dev->regs_lock);
+ BUG_ON(num_counters == 0);
+ counter_dev->counters =
+ kzalloc(sizeof(struct ni_gpct) * num_counters, GFP_KERNEL);
+ if (counter_dev->counters == NULL) {
+ kfree(counter_dev);
+ return NULL;
+ }
+ for (i = 0; i < num_counters; ++i) {
+ counter_dev->counters[i].counter_dev = counter_dev;
+ spin_lock_init(&counter_dev->counters[i].lock);
+ }
+ counter_dev->num_counters = num_counters;
+ return counter_dev;
+}
+
+void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev)
+{
+ if (counter_dev->counters == NULL)
+ return;
+ kfree(counter_dev->counters);
+ kfree(counter_dev);
+}
+
+static int ni_tio_second_gate_registers_present(const struct ni_gpct_device
+ *counter_dev)
+{
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ return 1;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static void ni_tio_reset_count_and_disarm(struct ni_gpct *counter)
+{
+ write_register(counter, Gi_Reset_Bit(counter->counter_index),
+ NITIO_Gxx_Joint_Reset_Reg(counter->counter_index));
+}
+
+void ni_tio_init_counter(struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+ ni_tio_reset_count_and_disarm(counter);
+ /* initialize counter registers */
+ counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->counter_index)] =
+ 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_Autoincrement_Reg(counter->
+ counter_index)],
+ NITIO_Gi_Autoincrement_Reg(counter->counter_index));
+ ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+ ~0, Gi_Synchronize_Gate_Bit);
+ ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index), ~0,
+ 0);
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] = 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)],
+ NITIO_Gi_LoadA_Reg(counter->counter_index));
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] = 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)],
+ NITIO_Gi_LoadB_Reg(counter->counter_index));
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index), ~0, 0);
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index), ~0,
+ 0);
+ }
+ if (ni_tio_second_gate_registers_present(counter_dev)) {
+ counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->
+ counter_index)] = 0x0;
+ write_register(counter,
+ counter_dev->regs[NITIO_Gi_Second_Gate_Reg(counter->
+ counter_index)],
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index));
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_DMA_Config_Reg(counter->counter_index), ~0, 0x0);
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index), ~0, 0x0);
+}
+
+static unsigned int ni_tio_counter_status(struct ni_gpct *counter)
+{
+ unsigned int status = 0;
+ const unsigned bits = read_register(counter,
+ NITIO_Gxx_Status_Reg(counter->counter_index));
+ if (bits & Gi_Armed_Bit(counter->counter_index)) {
+ status |= COMEDI_COUNTER_ARMED;
+ if (bits & Gi_Counting_Bit(counter->counter_index))
+ status |= COMEDI_COUNTER_COUNTING;
+ }
+ return status;
+}
+
+static void ni_tio_set_sync_mode(struct ni_gpct *counter, int force_alt_sync)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned counting_mode_reg =
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index);
+ static const uint64_t min_normal_sync_period_ps = 25000;
+ const uint64_t clock_period_ps = ni_tio_clock_period_ps(counter,
+ ni_tio_generic_clock_src_select(counter));
+
+ if (ni_tio_counting_mode_registers_present(counter_dev) == 0)
+ return;
+
+ switch (ni_tio_get_soft_copy(counter,
+ counting_mode_reg) & Gi_Counting_Mode_Mask) {
+ case Gi_Counting_Mode_QuadratureX1_Bits:
+ case Gi_Counting_Mode_QuadratureX2_Bits:
+ case Gi_Counting_Mode_QuadratureX4_Bits:
+ case Gi_Counting_Mode_Sync_Source_Bits:
+ force_alt_sync = 1;
+ break;
+ default:
+ break;
+ }
+ /* It's not clear what we should do if clock_period is unknown, so we are not
+ using the alt sync bit in that case, but allow the caller to decide by using the
+ force_alt_sync parameter. */
+ if (force_alt_sync ||
+ (clock_period_ps
+ && clock_period_ps < min_normal_sync_period_ps)) {
+ ni_tio_set_bits(counter, counting_mode_reg,
+ Gi_Alternate_Sync_Bit(counter_dev->variant),
+ Gi_Alternate_Sync_Bit(counter_dev->variant));
+ } else {
+ ni_tio_set_bits(counter, counting_mode_reg,
+ Gi_Alternate_Sync_Bit(counter_dev->variant), 0x0);
+ }
+}
+
+static int ni_tio_set_counter_mode(struct ni_gpct *counter, unsigned mode)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned mode_reg_mask;
+ unsigned mode_reg_values;
+ unsigned input_select_bits = 0;
+ /* these bits map directly on to the mode register */
+ static const unsigned mode_reg_direct_mask =
+ NI_GPCT_GATE_ON_BOTH_EDGES_BIT | NI_GPCT_EDGE_GATE_MODE_MASK |
+ NI_GPCT_STOP_MODE_MASK | NI_GPCT_OUTPUT_MODE_MASK |
+ NI_GPCT_HARDWARE_DISARM_MASK | NI_GPCT_LOADING_ON_TC_BIT |
+ NI_GPCT_LOADING_ON_GATE_BIT | NI_GPCT_LOAD_B_SELECT_BIT;
+
+ mode_reg_mask = mode_reg_direct_mask | Gi_Reload_Source_Switching_Bit;
+ mode_reg_values = mode & mode_reg_direct_mask;
+ switch (mode & NI_GPCT_RELOAD_SOURCE_MASK) {
+ case NI_GPCT_RELOAD_SOURCE_FIXED_BITS:
+ break;
+ case NI_GPCT_RELOAD_SOURCE_SWITCHING_BITS:
+ mode_reg_values |= Gi_Reload_Source_Switching_Bit;
+ break;
+ case NI_GPCT_RELOAD_SOURCE_GATE_SELECT_BITS:
+ input_select_bits |= Gi_Gate_Select_Load_Source_Bit;
+ mode_reg_mask |= Gi_Gating_Mode_Mask;
+ mode_reg_values |= Gi_Level_Gating_Bits;
+ break;
+ default:
+ break;
+ }
+ ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
+ mode_reg_mask, mode_reg_values);
+
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ unsigned counting_mode_bits = 0;
+ counting_mode_bits |=
+ (mode >> NI_GPCT_COUNTING_MODE_SHIFT) &
+ Gi_Counting_Mode_Mask;
+ counting_mode_bits |=
+ ((mode >> NI_GPCT_INDEX_PHASE_BITSHIFT) <<
+ Gi_Index_Phase_Bitshift) & Gi_Index_Phase_Mask;
+ if (mode & NI_GPCT_INDEX_ENABLE_BIT) {
+ counting_mode_bits |= Gi_Index_Mode_Bit;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index),
+ Gi_Counting_Mode_Mask | Gi_Index_Phase_Mask |
+ Gi_Index_Mode_Bit, counting_mode_bits);
+ ni_tio_set_sync_mode(counter, 0);
+ }
+
+ ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Up_Down_Mask,
+ (mode >> NI_GPCT_COUNTING_DIRECTION_SHIFT) << Gi_Up_Down_Shift);
+
+ if (mode & NI_GPCT_OR_GATE_BIT) {
+ input_select_bits |= Gi_Or_Gate_Bit;
+ }
+ if (mode & NI_GPCT_INVERT_OUTPUT_BIT) {
+ input_select_bits |= Gi_Output_Polarity_Bit;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Gate_Select_Load_Source_Bit | Gi_Or_Gate_Bit |
+ Gi_Output_Polarity_Bit, input_select_bits);
+
+ return 0;
+}
+
+int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+ unsigned command_transient_bits = 0;
+
+ if (arm) {
+ switch (start_trigger) {
+ case NI_GPCT_ARM_IMMEDIATE:
+ command_transient_bits |= Gi_Arm_Bit;
+ break;
+ case NI_GPCT_ARM_PAIRED_IMMEDIATE:
+ command_transient_bits |= Gi_Arm_Bit | Gi_Arm_Copy_Bit;
+ break;
+ default:
+ break;
+ }
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ unsigned counting_mode_bits = 0;
+
+ switch (start_trigger) {
+ case NI_GPCT_ARM_IMMEDIATE:
+ case NI_GPCT_ARM_PAIRED_IMMEDIATE:
+ break;
+ default:
+ if (start_trigger & NI_GPCT_ARM_UNKNOWN) {
+ /* pass-through the least significant bits so we can figure out what select later */
+ unsigned hw_arm_select_bits =
+ (start_trigger <<
+ Gi_HW_Arm_Select_Shift) &
+ Gi_HW_Arm_Select_Mask
+ (counter_dev->variant);
+
+ counting_mode_bits |=
+ Gi_HW_Arm_Enable_Bit |
+ hw_arm_select_bits;
+ } else {
+ return -EINVAL;
+ }
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->
+ counter_index),
+ Gi_HW_Arm_Select_Mask(counter_dev->
+ variant) | Gi_HW_Arm_Enable_Bit,
+ counting_mode_bits);
+ }
+ } else {
+ command_transient_bits |= Gi_Disarm_Bit;
+ }
+ ni_tio_set_bits_transient(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index), 0, 0,
+ command_transient_bits);
+ return 0;
+}
+
+static unsigned ni_660x_source_select_bits(unsigned int clock_source)
+{
+ unsigned ni_660x_clock;
+ unsigned i;
+ const unsigned clock_select_bits =
+ clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
+
+ switch (clock_select_bits) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Timebase_1_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Timebase_2_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Timebase_3_Clock;
+ break;
+ case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Logic_Low_Clock;
+ break;
+ case NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Source_Pin_i_Clock;
+ break;
+ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Next_Gate_Clock;
+ break;
+ case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
+ ni_660x_clock = NI_660x_Next_TC_Clock;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660x_RTSI_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_source_pin; ++i) {
+ if (clock_select_bits ==
+ NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i)) {
+ ni_660x_clock = NI_660x_Source_Pin_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_source_pin)
+ break;
+ ni_660x_clock = 0;
+ BUG();
+ break;
+ }
+ return Gi_Source_Select_Bits(ni_660x_clock);
+}
+
+static unsigned ni_m_series_source_select_bits(unsigned int clock_source)
+{
+ unsigned ni_m_series_clock;
+ unsigned i;
+ const unsigned clock_select_bits =
+ clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK;
+ switch (clock_select_bits) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Timebase_1_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Timebase_2_Clock;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Timebase_3_Clock;
+ break;
+ case NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Logic_Low_Clock;
+ break;
+ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Next_Gate_Clock;
+ break;
+ case NI_GPCT_NEXT_TC_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Next_TC_Clock;
+ break;
+ case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_PXI10_Clock;
+ break;
+ case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_PXI_Star_Trigger_Clock;
+ break;
+ case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
+ ni_m_series_clock = NI_M_Series_Analog_Trigger_Out_Clock;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (clock_select_bits == NI_GPCT_RTSI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_Series_RTSI_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (clock_select_bits == NI_GPCT_PFI_CLOCK_SRC_BITS(i)) {
+ ni_m_series_clock = NI_M_Series_PFI_Clock(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ rt_printk("invalid clock source 0x%lx\n",
+ (unsigned long)clock_source);
+ BUG();
+ ni_m_series_clock = 0;
+ break;
+ }
+ return Gi_Source_Select_Bits(ni_m_series_clock);
+};
+
+static void ni_tio_set_source_subselect(struct ni_gpct *counter,
+ unsigned int clock_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+
+ if (counter_dev->variant != ni_gpct_variant_m_series)
+ return;
+ switch (clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+ /* Gi_Source_Subselect is zero */
+ case NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS:
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ counter_dev->regs[second_gate_reg] &= ~Gi_Source_Subselect_Bit;
+ break;
+ /* Gi_Source_Subselect is one */
+ case NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS:
+ case NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS:
+ counter_dev->regs[second_gate_reg] |= Gi_Source_Subselect_Bit;
+ break;
+ /* Gi_Source_Subselect doesn't matter */
+ default:
+ return;
+ break;
+ }
+ write_register(counter, counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+}
+
+static int ni_tio_set_clock_src(struct ni_gpct *counter,
+ unsigned int clock_source, unsigned int period_ns)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned input_select_bits = 0;
+ static const uint64_t pico_per_nano = 1000;
+
+/*FIXME: validate clock source */
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_660x:
+ input_select_bits |= ni_660x_source_select_bits(clock_source);
+ break;
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ input_select_bits |=
+ ni_m_series_source_select_bits(clock_source);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (clock_source & NI_GPCT_INVERT_CLOCK_SRC_BIT)
+ input_select_bits |= Gi_Source_Polarity_Bit;
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Source_Select_Mask | Gi_Source_Polarity_Bit,
+ input_select_bits);
+ ni_tio_set_source_subselect(counter, clock_source);
+ if (ni_tio_counting_mode_registers_present(counter_dev)) {
+ const unsigned prescaling_mode =
+ clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK;
+ unsigned counting_mode_bits = 0;
+
+ switch (prescaling_mode) {
+ case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
+ break;
+ case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+ counting_mode_bits |=
+ Gi_Prescale_X2_Bit(counter_dev->variant);
+ break;
+ case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+ counting_mode_bits |=
+ Gi_Prescale_X8_Bit(counter_dev->variant);
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index),
+ Gi_Prescale_X2_Bit(counter_dev->
+ variant) | Gi_Prescale_X8_Bit(counter_dev->
+ variant), counting_mode_bits);
+ }
+ counter->clock_period_ps = pico_per_nano * period_ns;
+ ni_tio_set_sync_mode(counter, 0);
+ return 0;
+}
+
+static unsigned ni_tio_clock_src_modifiers(const struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned counting_mode_bits = ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Counting_Mode_Reg(counter->counter_index));
+ unsigned bits = 0;
+
+ if (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) & Gi_Source_Polarity_Bit)
+ bits |= NI_GPCT_INVERT_CLOCK_SRC_BIT;
+ if (counting_mode_bits & Gi_Prescale_X2_Bit(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS;
+ if (counting_mode_bits & Gi_Prescale_X8_Bit(counter_dev->variant))
+ bits |= NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS;
+ return bits;
+}
+
+static unsigned ni_m_series_clock_src_select(const struct ni_gpct *counter)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ unsigned clock_source = 0;
+ unsigned i;
+ const unsigned input_select = (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) & Gi_Source_Select_Mask) >>
+ Gi_Source_Select_Shift;
+
+ switch (input_select) {
+ case NI_M_Series_Timebase_1_Clock:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Timebase_2_Clock:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Timebase_3_Clock:
+ if (counter_dev->
+ regs[second_gate_reg] & Gi_Source_Subselect_Bit)
+ clock_source =
+ NI_GPCT_ANALOG_TRIGGER_OUT_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Logic_Low_Clock:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Next_Gate_Clock:
+ if (counter_dev->
+ regs[second_gate_reg] & Gi_Source_Subselect_Bit)
+ clock_source = NI_GPCT_PXI_STAR_TRIGGER_CLOCK_SRC_BITS;
+ else
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_PXI10_Clock:
+ clock_source = NI_GPCT_PXI10_CLOCK_SRC_BITS;
+ break;
+ case NI_M_Series_Next_TC_Clock:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (input_select == NI_M_Series_RTSI_Clock(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (input_select == NI_M_Series_PFI_Clock(i)) {
+ clock_source = NI_GPCT_PFI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ BUG();
+ break;
+ }
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
+}
+
+static unsigned ni_660x_clock_src_select(const struct ni_gpct *counter)
+{
+ unsigned clock_source = 0;
+ unsigned i;
+ const unsigned input_select = (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) & Gi_Source_Select_Mask) >>
+ Gi_Source_Select_Shift;
+
+ switch (input_select) {
+ case NI_660x_Timebase_1_Clock:
+ clock_source = NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Timebase_2_Clock:
+ clock_source = NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Timebase_3_Clock:
+ clock_source = NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Logic_Low_Clock:
+ clock_source = NI_GPCT_LOGIC_LOW_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Source_Pin_i_Clock:
+ clock_source = NI_GPCT_SOURCE_PIN_i_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Next_Gate_Clock:
+ clock_source = NI_GPCT_NEXT_GATE_CLOCK_SRC_BITS;
+ break;
+ case NI_660x_Next_TC_Clock:
+ clock_source = NI_GPCT_NEXT_TC_CLOCK_SRC_BITS;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (input_select == NI_660x_RTSI_Clock(i)) {
+ clock_source = NI_GPCT_RTSI_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_source_pin; ++i) {
+ if (input_select == NI_660x_Source_Pin_Clock(i)) {
+ clock_source =
+ NI_GPCT_SOURCE_PIN_CLOCK_SRC_BITS(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_source_pin)
+ break;
+ BUG();
+ break;
+ }
+ clock_source |= ni_tio_clock_src_modifiers(counter);
+ return clock_source;
+}
+
+static unsigned ni_tio_generic_clock_src_select(const struct ni_gpct *counter)
+{
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ return ni_m_series_clock_src_select(counter);
+ break;
+ case ni_gpct_variant_660x:
+ return ni_660x_clock_src_select(counter);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static uint64_t ni_tio_clock_period_ps(const struct ni_gpct *counter,
+ unsigned generic_clock_source)
+{
+ uint64_t clock_period_ps;
+
+ switch (generic_clock_source & NI_GPCT_CLOCK_SRC_SELECT_MASK) {
+ case NI_GPCT_TIMEBASE_1_CLOCK_SRC_BITS:
+ clock_period_ps = 50000;
+ break;
+ case NI_GPCT_TIMEBASE_2_CLOCK_SRC_BITS:
+ clock_period_ps = 10000000;
+ break;
+ case NI_GPCT_TIMEBASE_3_CLOCK_SRC_BITS:
+ clock_period_ps = 12500;
+ break;
+ case NI_GPCT_PXI10_CLOCK_SRC_BITS:
+ clock_period_ps = 100000;
+ break;
+ default:
+ /* clock period is specified by user with prescaling already taken into account. */
+ return counter->clock_period_ps;
+ break;
+ }
+
+ switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
+ case NI_GPCT_NO_PRESCALE_CLOCK_SRC_BITS:
+ break;
+ case NI_GPCT_PRESCALE_X2_CLOCK_SRC_BITS:
+ clock_period_ps *= 2;
+ break;
+ case NI_GPCT_PRESCALE_X8_CLOCK_SRC_BITS:
+ clock_period_ps *= 8;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return clock_period_ps;
+}
+
+static void ni_tio_get_clock_src(struct ni_gpct *counter,
+ unsigned int * clock_source, unsigned int * period_ns)
+{
+ static const unsigned pico_per_nano = 1000;
+ uint64_t temp64;
+ *clock_source = ni_tio_generic_clock_src_select(counter);
+ temp64 = ni_tio_clock_period_ps(counter, *clock_source);
+ do_div(temp64, pico_per_nano);
+ *period_ns = temp64;
+}
+
+static void ni_tio_set_first_gate_modifiers(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ const unsigned mode_mask = Gi_Gate_Polarity_Bit | Gi_Gating_Mode_Mask;
+ unsigned mode_values = 0;
+
+ if (gate_source & CR_INVERT) {
+ mode_values |= Gi_Gate_Polarity_Bit;
+ }
+ if (gate_source & CR_EDGE) {
+ mode_values |= Gi_Rising_Edge_Gating_Bits;
+ } else {
+ mode_values |= Gi_Level_Gating_Bits;
+ }
+ ni_tio_set_bits(counter, NITIO_Gi_Mode_Reg(counter->counter_index),
+ mode_mask, mode_values);
+}
+
+static int ni_660x_set_first_gate(struct ni_gpct *counter, unsigned int gate_source)
+{
+ const unsigned selected_gate = CR_CHAN(gate_source);
+ /* bits of selected_gate that may be meaningful to input select register */
+ const unsigned selected_gate_mask = 0x1f;
+ unsigned ni_660x_gate_select;
+ unsigned i;
+
+ switch (selected_gate) {
+ case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+ ni_660x_gate_select = NI_660x_Next_SRC_Gate_Select;
+ break;
+ case NI_GPCT_NEXT_OUT_GATE_SELECT:
+ case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+ case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
+ case NI_GPCT_GATE_PIN_i_GATE_SELECT:
+ ni_660x_gate_select = selected_gate & selected_gate_mask;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ ni_660x_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
+ if (selected_gate == NI_GPCT_GATE_PIN_GATE_SELECT(i)) {
+ ni_660x_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_gate_pin)
+ break;
+ return -EINVAL;
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Gate_Select_Mask, Gi_Gate_Select_Bits(ni_660x_gate_select));
+ return 0;
+}
+
+static int ni_m_series_set_first_gate(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ const unsigned selected_gate = CR_CHAN(gate_source);
+ /* bits of selected_gate that may be meaningful to input select register */
+ const unsigned selected_gate_mask = 0x1f;
+ unsigned ni_m_series_gate_select;
+ unsigned i;
+
+ switch (selected_gate) {
+ case NI_GPCT_TIMESTAMP_MUX_GATE_SELECT:
+ case NI_GPCT_AI_START2_GATE_SELECT:
+ case NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT:
+ case NI_GPCT_NEXT_OUT_GATE_SELECT:
+ case NI_GPCT_AI_START1_GATE_SELECT:
+ case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+ case NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT:
+ case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+ ni_m_series_gate_select = selected_gate & selected_gate_mask;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (selected_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ ni_m_series_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (selected_gate == NI_GPCT_PFI_GATE_SELECT(i)) {
+ ni_m_series_gate_select =
+ selected_gate & selected_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ return -EINVAL;
+ break;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Gate_Select_Mask,
+ Gi_Gate_Select_Bits(ni_m_series_gate_select));
+ return 0;
+}
+
+static int ni_660x_set_second_gate(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ const unsigned selected_second_gate = CR_CHAN(gate_source);
+ /* bits of second_gate that may be meaningful to second gate register */
+ static const unsigned selected_second_gate_mask = 0x1f;
+ unsigned ni_660x_second_gate_select;
+ unsigned i;
+
+ switch (selected_second_gate) {
+ case NI_GPCT_SOURCE_PIN_i_GATE_SELECT:
+ case NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT:
+ case NI_GPCT_SELECTED_GATE_GATE_SELECT:
+ case NI_GPCT_NEXT_OUT_GATE_SELECT:
+ case NI_GPCT_LOGIC_LOW_GATE_SELECT:
+ ni_660x_second_gate_select =
+ selected_second_gate & selected_second_gate_mask;
+ break;
+ case NI_GPCT_NEXT_SOURCE_GATE_SELECT:
+ ni_660x_second_gate_select =
+ NI_660x_Next_SRC_Second_Gate_Select;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (selected_second_gate == NI_GPCT_RTSI_GATE_SELECT(i)) {
+ ni_660x_second_gate_select =
+ selected_second_gate &
+ selected_second_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
+ if (selected_second_gate ==
+ NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i)) {
+ ni_660x_second_gate_select =
+ selected_second_gate &
+ selected_second_gate_mask;
+ break;
+ }
+ }
+ if (i <= ni_660x_max_up_down_pin)
+ break;
+ return -EINVAL;
+ break;
+ };
+ counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
+ counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
+ counter_dev->regs[second_gate_reg] |=
+ Gi_Second_Gate_Select_Bits(ni_660x_second_gate_select);
+ write_register(counter, counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+ return 0;
+}
+
+static int ni_m_series_set_second_gate(struct ni_gpct *counter,
+ unsigned int gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ const unsigned selected_second_gate = CR_CHAN(gate_source);
+ /* bits of second_gate that may be meaningful to second gate register */
+ static const unsigned selected_second_gate_mask = 0x1f;
+ unsigned ni_m_series_second_gate_select;
+
+ /* FIXME: We don't know what the m-series second gate codes are, so we'll just pass
+ the bits through for now. */
+ switch (selected_second_gate) {
+ default:
+ ni_m_series_second_gate_select =
+ selected_second_gate & selected_second_gate_mask;
+ break;
+ };
+ counter_dev->regs[second_gate_reg] |= Gi_Second_Gate_Mode_Bit;
+ counter_dev->regs[second_gate_reg] &= ~Gi_Second_Gate_Select_Mask;
+ counter_dev->regs[second_gate_reg] |=
+ Gi_Second_Gate_Select_Bits(ni_m_series_second_gate_select);
+ write_register(counter, counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+ return 0;
+}
+
+int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
+ unsigned int gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+
+ switch (gate_index) {
+ case 0:
+ if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Mode_Reg(counter->counter_index),
+ Gi_Gating_Mode_Mask, Gi_Gating_Disabled_Bits);
+ return 0;
+ }
+ ni_tio_set_first_gate_modifiers(counter, gate_source);
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ return ni_m_series_set_first_gate(counter, gate_source);
+ break;
+ case ni_gpct_variant_660x:
+ return ni_660x_set_first_gate(counter, gate_source);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ break;
+ case 1:
+ if (ni_tio_second_gate_registers_present(counter_dev) == 0)
+ return -EINVAL;
+ if (CR_CHAN(gate_source) == NI_GPCT_DISABLED_GATE_SELECT) {
+ counter_dev->regs[second_gate_reg] &=
+ ~Gi_Second_Gate_Mode_Bit;
+ write_register(counter,
+ counter_dev->regs[second_gate_reg],
+ second_gate_reg);
+ return 0;
+ }
+ if (gate_source & CR_INVERT) {
+ counter_dev->regs[second_gate_reg] |=
+ Gi_Second_Gate_Polarity_Bit;
+ } else {
+ counter_dev->regs[second_gate_reg] &=
+ ~Gi_Second_Gate_Polarity_Bit;
+ }
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ return ni_m_series_set_second_gate(counter,
+ gate_source);
+ break;
+ case ni_gpct_variant_660x:
+ return ni_660x_set_second_gate(counter, gate_source);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+static int ni_tio_set_other_src(struct ni_gpct *counter, unsigned index,
+ unsigned int source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+
+ if (counter_dev->variant == ni_gpct_variant_m_series) {
+ unsigned int abz_reg, shift, mask;
+
+ abz_reg = NITIO_Gi_ABZ_Reg(counter->counter_index);
+ switch (index) {
+ case NI_GPCT_SOURCE_ENCODER_A:
+ shift = 10;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_B:
+ shift = 5;
+ break;
+ case NI_GPCT_SOURCE_ENCODER_Z:
+ shift = 0;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ mask = 0x1f << shift;
+ if (source > 0x1f) {
+ /* Disable gate */
+ source = 0x1f;
+ }
+ counter_dev->regs[abz_reg] &= ~mask;
+ counter_dev->regs[abz_reg] |= (source << shift) & mask;
+ write_register(counter, counter_dev->regs[abz_reg], abz_reg);
+// rt_printk("%s %x %d %d\n", __FUNCTION__, counter_dev->regs[abz_reg], index, source);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static unsigned ni_660x_first_gate_to_generic_gate_source(unsigned
+ ni_660x_gate_select)
+{
+ unsigned i;
+
+ switch (ni_660x_gate_select) {
+ case NI_660x_Source_Pin_i_Gate_Select:
+ return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Gate_Pin_i_Gate_Select:
+ return NI_GPCT_GATE_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Next_SRC_Gate_Select:
+ return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+ break;
+ case NI_660x_Next_Out_Gate_Select:
+ return NI_GPCT_NEXT_OUT_GATE_SELECT;
+ break;
+ case NI_660x_Logic_Low_Gate_Select:
+ return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (ni_660x_gate_select == NI_660x_RTSI_Gate_Select(i)) {
+ return NI_GPCT_RTSI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_gate_pin; ++i) {
+ if (ni_660x_gate_select ==
+ NI_660x_Gate_Pin_Gate_Select(i)) {
+ return NI_GPCT_GATE_PIN_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_gate_pin)
+ break;
+ BUG();
+ break;
+ }
+ return 0;
+};
+
+static unsigned ni_m_series_first_gate_to_generic_gate_source(unsigned
+ ni_m_series_gate_select)
+{
+ unsigned i;
+
+ switch (ni_m_series_gate_select) {
+ case NI_M_Series_Timestamp_Mux_Gate_Select:
+ return NI_GPCT_TIMESTAMP_MUX_GATE_SELECT;
+ break;
+ case NI_M_Series_AI_START2_Gate_Select:
+ return NI_GPCT_AI_START2_GATE_SELECT;
+ break;
+ case NI_M_Series_PXI_Star_Trigger_Gate_Select:
+ return NI_GPCT_PXI_STAR_TRIGGER_GATE_SELECT;
+ break;
+ case NI_M_Series_Next_Out_Gate_Select:
+ return NI_GPCT_NEXT_OUT_GATE_SELECT;
+ break;
+ case NI_M_Series_AI_START1_Gate_Select:
+ return NI_GPCT_AI_START1_GATE_SELECT;
+ break;
+ case NI_M_Series_Next_SRC_Gate_Select:
+ return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+ break;
+ case NI_M_Series_Analog_Trigger_Out_Gate_Select:
+ return NI_GPCT_ANALOG_TRIGGER_OUT_GATE_SELECT;
+ break;
+ case NI_M_Series_Logic_Low_Gate_Select:
+ return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+ break;
+ default:
+ for (i = 0; i <= ni_m_series_max_rtsi_channel; ++i) {
+ if (ni_m_series_gate_select ==
+ NI_M_Series_RTSI_Gate_Select(i)) {
+ return NI_GPCT_RTSI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_m_series_max_pfi_channel; ++i) {
+ if (ni_m_series_gate_select ==
+ NI_M_Series_PFI_Gate_Select(i)) {
+ return NI_GPCT_PFI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_m_series_max_pfi_channel)
+ break;
+ BUG();
+ break;
+ }
+ return 0;
+};
+
+static unsigned ni_660x_second_gate_to_generic_gate_source(unsigned
+ ni_660x_gate_select)
+{
+ unsigned i;
+
+ switch (ni_660x_gate_select) {
+ case NI_660x_Source_Pin_i_Second_Gate_Select:
+ return NI_GPCT_SOURCE_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Up_Down_Pin_i_Second_Gate_Select:
+ return NI_GPCT_UP_DOWN_PIN_i_GATE_SELECT;
+ break;
+ case NI_660x_Next_SRC_Second_Gate_Select:
+ return NI_GPCT_NEXT_SOURCE_GATE_SELECT;
+ break;
+ case NI_660x_Next_Out_Second_Gate_Select:
+ return NI_GPCT_NEXT_OUT_GATE_SELECT;
+ break;
+ case NI_660x_Selected_Gate_Second_Gate_Select:
+ return NI_GPCT_SELECTED_GATE_GATE_SELECT;
+ break;
+ case NI_660x_Logic_Low_Second_Gate_Select:
+ return NI_GPCT_LOGIC_LOW_GATE_SELECT;
+ break;
+ default:
+ for (i = 0; i <= ni_660x_max_rtsi_channel; ++i) {
+ if (ni_660x_gate_select ==
+ NI_660x_RTSI_Second_Gate_Select(i)) {
+ return NI_GPCT_RTSI_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_rtsi_channel)
+ break;
+ for (i = 0; i <= ni_660x_max_up_down_pin; ++i) {
+ if (ni_660x_gate_select ==
+ NI_660x_Up_Down_Pin_Second_Gate_Select(i)) {
+ return NI_GPCT_UP_DOWN_PIN_GATE_SELECT(i);
+ break;
+ }
+ }
+ if (i <= ni_660x_max_up_down_pin)
+ break;
+ BUG();
+ break;
+ }
+ return 0;
+};
+
+static unsigned ni_m_series_second_gate_to_generic_gate_source(unsigned
+ ni_m_series_gate_select)
+{
+ /*FIXME: the second gate sources for the m series are undocumented, so we just return
+ * the raw bits for now. */
+ switch (ni_m_series_gate_select) {
+ default:
+ return ni_m_series_gate_select;
+ break;
+ }
+ return 0;
+};
+
+static int ni_tio_get_gate_src(struct ni_gpct *counter, unsigned gate_index,
+ unsigned int * gate_source)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned mode_bits = ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Mode_Reg(counter->counter_index));
+ const unsigned second_gate_reg =
+ NITIO_Gi_Second_Gate_Reg(counter->counter_index);
+ unsigned gate_select_bits;
+
+ switch (gate_index) {
+ case 0:
+ if ((mode_bits & Gi_Gating_Mode_Mask) ==
+ Gi_Gating_Disabled_Bits) {
+ *gate_source = NI_GPCT_DISABLED_GATE_SELECT;
+ return 0;
+ } else {
+ gate_select_bits =
+ (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Input_Select_Reg(counter->
+ counter_index)) &
+ Gi_Gate_Select_Mask) >> Gi_Gate_Select_Shift;
+ }
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ *gate_source =
+ ni_m_series_first_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ case ni_gpct_variant_660x:
+ *gate_source =
+ ni_660x_first_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (mode_bits & Gi_Gate_Polarity_Bit) {
+ *gate_source |= CR_INVERT;
+ }
+ if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+ *gate_source |= CR_EDGE;
+ }
+ break;
+ case 1:
+ if ((mode_bits & Gi_Gating_Mode_Mask) == Gi_Gating_Disabled_Bits
+ || (counter_dev->
+ regs[second_gate_reg] & Gi_Second_Gate_Mode_Bit)
+ == 0) {
+ *gate_source = NI_GPCT_DISABLED_GATE_SELECT;
+ return 0;
+ } else {
+ gate_select_bits =
+ (counter_dev->
+ regs[second_gate_reg] &
+ Gi_Second_Gate_Select_Mask) >>
+ Gi_Second_Gate_Select_Shift;
+ }
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ case ni_gpct_variant_m_series:
+ *gate_source =
+ ni_m_series_second_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ case ni_gpct_variant_660x:
+ *gate_source =
+ ni_660x_second_gate_to_generic_gate_source
+ (gate_select_bits);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ if (counter_dev->
+ regs[second_gate_reg] & Gi_Second_Gate_Polarity_Bit) {
+ *gate_source |= CR_INVERT;
+ }
+ /* second gate can't have edge/level mode set independently */
+ if ((mode_bits & Gi_Gating_Mode_Mask) != Gi_Level_Gating_Bits) {
+ *gate_source |= CR_EDGE;
+ }
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+int ni_tio_insn_config(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ switch (data[0]) {
+ case INSN_CONFIG_SET_COUNTER_MODE:
+ return ni_tio_set_counter_mode(counter, data[1]);
+ break;
+ case INSN_CONFIG_ARM:
+ return ni_tio_arm(counter, 1, data[1]);
+ break;
+ case INSN_CONFIG_DISARM:
+ ni_tio_arm(counter, 0, 0);
+ return 0;
+ break;
+ case INSN_CONFIG_GET_COUNTER_STATUS:
+ data[1] = ni_tio_counter_status(counter);
+ data[2] = counter_status_mask;
+ return 0;
+ break;
+ case INSN_CONFIG_SET_CLOCK_SRC:
+ return ni_tio_set_clock_src(counter, data[1], data[2]);
+ break;
+ case INSN_CONFIG_GET_CLOCK_SRC:
+ ni_tio_get_clock_src(counter, &data[1], &data[2]);
+ return 0;
+ break;
+ case INSN_CONFIG_SET_GATE_SRC:
+ return ni_tio_set_gate_src(counter, data[1], data[2]);
+ break;
+ case INSN_CONFIG_GET_GATE_SRC:
+ return ni_tio_get_gate_src(counter, data[1], &data[2]);
+ break;
+ case INSN_CONFIG_SET_OTHER_SRC:
+ return ni_tio_set_other_src(counter, data[1], data[2]);
+ break;
+ case INSN_CONFIG_RESET:
+ ni_tio_reset_count_and_disarm(counter);
+ return 0;
+ break;
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+int ni_tio_rinsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned channel = CR_CHAN(insn->chanspec);
+ unsigned first_read;
+ unsigned second_read;
+ unsigned correct_read;
+
+ if (insn->n < 1)
+ return 0;
+ switch (channel) {
+ case 0:
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Save_Trace_Bit, 0);
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Save_Trace_Bit, Gi_Save_Trace_Bit);
+ /* The count doesn't get latched until the next clock edge, so it is possible the count
+ may change (once) while we are reading. Since the read of the SW_Save_Reg isn't
+ atomic (apparently even when it's a 32 bit register according to 660x docs),
+ we need to read twice and make sure the reading hasn't changed. If it has,
+ a third read will be correct since the count value will definitely have latched by then. */
+ first_read =
+ read_register(counter,
+ NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ second_read =
+ read_register(counter,
+ NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ if (first_read != second_read)
+ correct_read =
+ read_register(counter,
+ NITIO_Gi_SW_Save_Reg(counter->counter_index));
+ else
+ correct_read = first_read;
+ data[0] = correct_read;
+ return 0;
+ break;
+ case 1:
+ data[0] =
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->
+ counter_index)];
+ break;
+ case 2:
+ data[0] =
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->
+ counter_index)];
+ break;
+ };
+ return 0;
+}
+
+static unsigned ni_tio_next_load_register(struct ni_gpct *counter)
+{
+ const unsigned bits = read_register(counter,
+ NITIO_Gxx_Status_Reg(counter->counter_index));
+
+ if (bits & Gi_Next_Load_Source_Bit(counter->counter_index)) {
+ return NITIO_Gi_LoadB_Reg(counter->counter_index);
+ } else {
+ return NITIO_Gi_LoadA_Reg(counter->counter_index);
+ }
+}
+
+int ni_tio_winsn(struct ni_gpct *counter, struct comedi_insn * insn, unsigned int * data)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ const unsigned channel = CR_CHAN(insn->chanspec);
+ unsigned load_reg;
+
+ if (insn->n < 1)
+ return 0;
+ switch (channel) {
+ case 0:
+ /* Unsafe if counter is armed. Should probably check status and return -EBUSY if armed. */
+ /* Don't disturb load source select, just use whichever load register is already selected. */
+ load_reg = ni_tio_next_load_register(counter);
+ write_register(counter, data[0], load_reg);
+ ni_tio_set_bits_transient(counter,
+ NITIO_Gi_Command_Reg(counter->counter_index), 0, 0,
+ Gi_Load_Bit);
+ /* restore state of load reg to whatever the user set last set it to */
+ write_register(counter, counter_dev->regs[load_reg], load_reg);
+ break;
+ case 1:
+ counter_dev->regs[NITIO_Gi_LoadA_Reg(counter->counter_index)] =
+ data[0];
+ write_register(counter, data[0],
+ NITIO_Gi_LoadA_Reg(counter->counter_index));
+ break;
+ case 2:
+ counter_dev->regs[NITIO_Gi_LoadB_Reg(counter->counter_index)] =
+ data[0];
+ write_register(counter, data[0],
+ NITIO_Gi_LoadB_Reg(counter->counter_index));
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(ni_tio_rinsn);
+EXPORT_SYMBOL_GPL(ni_tio_winsn);
+EXPORT_SYMBOL_GPL(ni_tio_insn_config);
+EXPORT_SYMBOL_GPL(ni_tio_init_counter);
+EXPORT_SYMBOL_GPL(ni_tio_arm);
+EXPORT_SYMBOL_GPL(ni_tio_set_gate_src);
+EXPORT_SYMBOL_GPL(ni_gpct_device_construct);
+EXPORT_SYMBOL_GPL(ni_gpct_device_destroy);
diff --git a/drivers/staging/comedi/drivers/ni_tio.h b/drivers/staging/comedi/drivers/ni_tio.h
new file mode 100644
index 00000000000..0729d60b01c
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio.h
@@ -0,0 +1,163 @@
+/*
+ drivers/ni_tio.h
+ Header file for NI general purpose counter support code (ni_tio.c)
+
+ COMEDI - Linux Control and Measurement Device Interface
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _COMEDI_NI_TIO_H
+#define _COMEDI_NI_TIO_H
+
+#include "../comedidev.h"
+
+// forward declarations
+struct mite_struct;
+struct ni_gpct_device;
+
+enum ni_gpct_register {
+ NITIO_G0_Autoincrement_Reg,
+ NITIO_G1_Autoincrement_Reg,
+ NITIO_G2_Autoincrement_Reg,
+ NITIO_G3_Autoincrement_Reg,
+ NITIO_G0_Command_Reg,
+ NITIO_G1_Command_Reg,
+ NITIO_G2_Command_Reg,
+ NITIO_G3_Command_Reg,
+ NITIO_G0_HW_Save_Reg,
+ NITIO_G1_HW_Save_Reg,
+ NITIO_G2_HW_Save_Reg,
+ NITIO_G3_HW_Save_Reg,
+ NITIO_G0_SW_Save_Reg,
+ NITIO_G1_SW_Save_Reg,
+ NITIO_G2_SW_Save_Reg,
+ NITIO_G3_SW_Save_Reg,
+ NITIO_G0_Mode_Reg,
+ NITIO_G1_Mode_Reg,
+ NITIO_G2_Mode_Reg,
+ NITIO_G3_Mode_Reg,
+ NITIO_G0_LoadA_Reg,
+ NITIO_G1_LoadA_Reg,
+ NITIO_G2_LoadA_Reg,
+ NITIO_G3_LoadA_Reg,
+ NITIO_G0_LoadB_Reg,
+ NITIO_G1_LoadB_Reg,
+ NITIO_G2_LoadB_Reg,
+ NITIO_G3_LoadB_Reg,
+ NITIO_G0_Input_Select_Reg,
+ NITIO_G1_Input_Select_Reg,
+ NITIO_G2_Input_Select_Reg,
+ NITIO_G3_Input_Select_Reg,
+ NITIO_G0_Counting_Mode_Reg,
+ NITIO_G1_Counting_Mode_Reg,
+ NITIO_G2_Counting_Mode_Reg,
+ NITIO_G3_Counting_Mode_Reg,
+ NITIO_G0_Second_Gate_Reg,
+ NITIO_G1_Second_Gate_Reg,
+ NITIO_G2_Second_Gate_Reg,
+ NITIO_G3_Second_Gate_Reg,
+ NITIO_G01_Status_Reg,
+ NITIO_G23_Status_Reg,
+ NITIO_G01_Joint_Reset_Reg,
+ NITIO_G23_Joint_Reset_Reg,
+ NITIO_G01_Joint_Status1_Reg,
+ NITIO_G23_Joint_Status1_Reg,
+ NITIO_G01_Joint_Status2_Reg,
+ NITIO_G23_Joint_Status2_Reg,
+ NITIO_G0_DMA_Config_Reg,
+ NITIO_G1_DMA_Config_Reg,
+ NITIO_G2_DMA_Config_Reg,
+ NITIO_G3_DMA_Config_Reg,
+ NITIO_G0_DMA_Status_Reg,
+ NITIO_G1_DMA_Status_Reg,
+ NITIO_G2_DMA_Status_Reg,
+ NITIO_G3_DMA_Status_Reg,
+ NITIO_G0_ABZ_Reg,
+ NITIO_G1_ABZ_Reg,
+ NITIO_G0_Interrupt_Acknowledge_Reg,
+ NITIO_G1_Interrupt_Acknowledge_Reg,
+ NITIO_G2_Interrupt_Acknowledge_Reg,
+ NITIO_G3_Interrupt_Acknowledge_Reg,
+ NITIO_G0_Status_Reg,
+ NITIO_G1_Status_Reg,
+ NITIO_G2_Status_Reg,
+ NITIO_G3_Status_Reg,
+ NITIO_G0_Interrupt_Enable_Reg,
+ NITIO_G1_Interrupt_Enable_Reg,
+ NITIO_G2_Interrupt_Enable_Reg,
+ NITIO_G3_Interrupt_Enable_Reg,
+ NITIO_Num_Registers,
+};
+
+enum ni_gpct_variant {
+ ni_gpct_variant_e_series,
+ ni_gpct_variant_m_series,
+ ni_gpct_variant_660x
+};
+
+struct ni_gpct {
+ struct ni_gpct_device *counter_dev;
+ unsigned counter_index;
+ unsigned chip_index;
+ uint64_t clock_period_ps; /* clock period in picoseconds */
+ struct mite_channel *mite_chan;
+ spinlock_t lock;
+};
+
+struct ni_gpct_device {
+ struct comedi_device *dev;
+ void (*write_register) (struct ni_gpct * counter, unsigned bits,
+ enum ni_gpct_register reg);
+ unsigned (*read_register) (struct ni_gpct * counter,
+ enum ni_gpct_register reg);
+ enum ni_gpct_variant variant;
+ struct ni_gpct *counters;
+ unsigned num_counters;
+ unsigned regs[NITIO_Num_Registers];
+ spinlock_t regs_lock;
+};
+
+extern struct ni_gpct_device *ni_gpct_device_construct(struct comedi_device * dev,
+ void (*write_register) (struct ni_gpct * counter, unsigned bits,
+ enum ni_gpct_register reg),
+ unsigned (*read_register) (struct ni_gpct * counter,
+ enum ni_gpct_register reg), enum ni_gpct_variant variant,
+ unsigned num_counters);
+extern void ni_gpct_device_destroy(struct ni_gpct_device *counter_dev);
+extern void ni_tio_init_counter(struct ni_gpct *counter);
+extern int ni_tio_rinsn(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_insn_config(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_winsn(struct ni_gpct *counter,
+ struct comedi_insn * insn, unsigned int * data);
+extern int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async);
+extern int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd);
+extern int ni_tio_cancel(struct ni_gpct *counter);
+extern void ni_tio_handle_interrupt(struct ni_gpct *counter,
+ struct comedi_subdevice * s);
+extern void ni_tio_set_mite_channel(struct ni_gpct *counter,
+ struct mite_channel *mite_chan);
+extern void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter,
+ int *gate_error, int *tc_error, int *perm_stale_data, int *stale_data);
+
+static inline struct ni_gpct *subdev_to_counter(struct comedi_subdevice * s)
+{
+ return s->private;
+}
+
+#endif /* _COMEDI_NI_TIO_H */
diff --git a/drivers/staging/comedi/drivers/ni_tio_internal.h b/drivers/staging/comedi/drivers/ni_tio_internal.h
new file mode 100644
index 00000000000..ac5b171cbe1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tio_internal.h
@@ -0,0 +1,774 @@
+/*
+ drivers/ni_tio_internal.h
+ Header file for NI general purpose counter support code (ni_tio.c and
+ ni_tiocmd.c)
+
+ COMEDI - Linux Control and Measurement Device Interface
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _COMEDI_NI_TIO_INTERNAL_H
+#define _COMEDI_NI_TIO_INTERNAL_H
+
+#include "ni_tio.h"
+
+static inline enum ni_gpct_register NITIO_Gi_Autoincrement_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Autoincrement_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Autoincrement_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Autoincrement_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Autoincrement_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Command_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Command_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Command_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Command_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Command_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Counting_Mode_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Counting_Mode_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Counting_Mode_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Counting_Mode_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Counting_Mode_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Input_Select_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Input_Select_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Input_Select_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Input_Select_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Input_Select_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Reset_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Joint_Reset_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Joint_Reset_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Status1_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Joint_Status1_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Joint_Status1_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Joint_Status2_Reg(unsigned
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Joint_Status2_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Joint_Status2_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gxx_Status_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ case 1:
+ return NITIO_G01_Status_Reg;
+ break;
+ case 2:
+ case 3:
+ return NITIO_G23_Status_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_LoadA_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_LoadA_Reg;
+ break;
+ case 1:
+ return NITIO_G1_LoadA_Reg;
+ break;
+ case 2:
+ return NITIO_G2_LoadA_Reg;
+ break;
+ case 3:
+ return NITIO_G3_LoadA_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_LoadB_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_LoadB_Reg;
+ break;
+ case 1:
+ return NITIO_G1_LoadB_Reg;
+ break;
+ case 2:
+ return NITIO_G2_LoadB_Reg;
+ break;
+ case 3:
+ return NITIO_G3_LoadB_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Mode_Reg(unsigned counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Mode_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Mode_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Mode_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Mode_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_SW_Save_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_SW_Save_Reg;
+ break;
+ case 1:
+ return NITIO_G1_SW_Save_Reg;
+ break;
+ case 2:
+ return NITIO_G2_SW_Save_Reg;
+ break;
+ case 3:
+ return NITIO_G3_SW_Save_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Second_Gate_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Second_Gate_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Second_Gate_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Second_Gate_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Second_Gate_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_DMA_Config_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_DMA_Config_Reg;
+ break;
+ case 1:
+ return NITIO_G1_DMA_Config_Reg;
+ break;
+ case 2:
+ return NITIO_G2_DMA_Config_Reg;
+ break;
+ case 3:
+ return NITIO_G3_DMA_Config_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_DMA_Status_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_DMA_Status_Reg;
+ break;
+ case 1:
+ return NITIO_G1_DMA_Status_Reg;
+ break;
+ case 2:
+ return NITIO_G2_DMA_Status_Reg;
+ break;
+ case 3:
+ return NITIO_G3_DMA_Status_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_ABZ_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_ABZ_Reg;
+ break;
+ case 1:
+ return NITIO_G1_ABZ_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Interrupt_Acknowledge_Reg(int
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Interrupt_Acknowledge_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Interrupt_Acknowledge_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Interrupt_Acknowledge_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Interrupt_Acknowledge_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Status_Reg(int counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Status_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Status_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Status_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Status_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline enum ni_gpct_register NITIO_Gi_Interrupt_Enable_Reg(int
+ counter_index)
+{
+ switch (counter_index) {
+ case 0:
+ return NITIO_G0_Interrupt_Enable_Reg;
+ break;
+ case 1:
+ return NITIO_G1_Interrupt_Enable_Reg;
+ break;
+ case 2:
+ return NITIO_G2_Interrupt_Enable_Reg;
+ break;
+ case 3:
+ return NITIO_G3_Interrupt_Enable_Reg;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+enum Gi_Auto_Increment_Reg_Bits {
+ Gi_Auto_Increment_Mask = 0xff
+};
+
+#define Gi_Up_Down_Shift 5
+enum Gi_Command_Reg_Bits {
+ Gi_Arm_Bit = 0x1,
+ Gi_Save_Trace_Bit = 0x2,
+ Gi_Load_Bit = 0x4,
+ Gi_Disarm_Bit = 0x10,
+ Gi_Up_Down_Mask = 0x3 << Gi_Up_Down_Shift,
+ Gi_Always_Down_Bits = 0x0 << Gi_Up_Down_Shift,
+ Gi_Always_Up_Bits = 0x1 << Gi_Up_Down_Shift,
+ Gi_Up_Down_Hardware_IO_Bits = 0x2 << Gi_Up_Down_Shift,
+ Gi_Up_Down_Hardware_Gate_Bits = 0x3 << Gi_Up_Down_Shift,
+ Gi_Write_Switch_Bit = 0x80,
+ Gi_Synchronize_Gate_Bit = 0x100,
+ Gi_Little_Big_Endian_Bit = 0x200,
+ Gi_Bank_Switch_Start_Bit = 0x400,
+ Gi_Bank_Switch_Mode_Bit = 0x800,
+ Gi_Bank_Switch_Enable_Bit = 0x1000,
+ Gi_Arm_Copy_Bit = 0x2000,
+ Gi_Save_Trace_Copy_Bit = 0x4000,
+ Gi_Disarm_Copy_Bit = 0x8000
+};
+
+#define Gi_Index_Phase_Bitshift 5
+#define Gi_HW_Arm_Select_Shift 8
+enum Gi_Counting_Mode_Reg_Bits {
+ Gi_Counting_Mode_Mask = 0x7,
+ Gi_Counting_Mode_Normal_Bits = 0x0,
+ Gi_Counting_Mode_QuadratureX1_Bits = 0x1,
+ Gi_Counting_Mode_QuadratureX2_Bits = 0x2,
+ Gi_Counting_Mode_QuadratureX4_Bits = 0x3,
+ Gi_Counting_Mode_Two_Pulse_Bits = 0x4,
+ Gi_Counting_Mode_Sync_Source_Bits = 0x6,
+ Gi_Index_Mode_Bit = 0x10,
+ Gi_Index_Phase_Mask = 0x3 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_LowA_LowB = 0x0 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_LowA_HighB = 0x1 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_HighA_LowB = 0x2 << Gi_Index_Phase_Bitshift,
+ Gi_Index_Phase_HighA_HighB = 0x3 << Gi_Index_Phase_Bitshift,
+ Gi_HW_Arm_Enable_Bit = 0x80, /* from m-series example code, not documented in 660x register level manual */
+ Gi_660x_HW_Arm_Select_Mask = 0x7 << Gi_HW_Arm_Select_Shift, /* from m-series example code, not documented in 660x register level manual */
+ Gi_660x_Prescale_X8_Bit = 0x1000,
+ Gi_M_Series_Prescale_X8_Bit = 0x2000,
+ Gi_M_Series_HW_Arm_Select_Mask = 0x1f << Gi_HW_Arm_Select_Shift,
+ /* must be set for clocks over 40MHz, which includes synchronous counting and quadrature modes */
+ Gi_660x_Alternate_Sync_Bit = 0x2000,
+ Gi_M_Series_Alternate_Sync_Bit = 0x4000,
+ Gi_660x_Prescale_X2_Bit = 0x4000, /* from m-series example code, not documented in 660x register level manual */
+ Gi_M_Series_Prescale_X2_Bit = 0x8000,
+};
+
+#define Gi_Source_Select_Shift 2
+#define Gi_Gate_Select_Shift 7
+enum Gi_Input_Select_Bits {
+ Gi_Read_Acknowledges_Irq = 0x1, // not present on 660x
+ Gi_Write_Acknowledges_Irq = 0x2, // not present on 660x
+ Gi_Source_Select_Mask = 0x7c,
+ Gi_Gate_Select_Mask = 0x1f << Gi_Gate_Select_Shift,
+ Gi_Gate_Select_Load_Source_Bit = 0x1000,
+ Gi_Or_Gate_Bit = 0x2000,
+ Gi_Output_Polarity_Bit = 0x4000, /* set to invert */
+ Gi_Source_Polarity_Bit = 0x8000 /* set to invert */
+};
+
+enum Gi_Mode_Bits {
+ Gi_Gating_Mode_Mask = 0x3,
+ Gi_Gating_Disabled_Bits = 0x0,
+ Gi_Level_Gating_Bits = 0x1,
+ Gi_Rising_Edge_Gating_Bits = 0x2,
+ Gi_Falling_Edge_Gating_Bits = 0x3,
+ Gi_Gate_On_Both_Edges_Bit = 0x4, /* used in conjunction with rising edge gating mode */
+ Gi_Trigger_Mode_for_Edge_Gate_Mask = 0x18,
+ Gi_Edge_Gate_Starts_Stops_Bits = 0x0,
+ Gi_Edge_Gate_Stops_Starts_Bits = 0x8,
+ Gi_Edge_Gate_Starts_Bits = 0x10,
+ Gi_Edge_Gate_No_Starts_or_Stops_Bits = 0x18,
+ Gi_Stop_Mode_Mask = 0x60,
+ Gi_Stop_on_Gate_Bits = 0x00,
+ Gi_Stop_on_Gate_or_TC_Bits = 0x20,
+ Gi_Stop_on_Gate_or_Second_TC_Bits = 0x40,
+ Gi_Load_Source_Select_Bit = 0x80,
+ Gi_Output_Mode_Mask = 0x300,
+ Gi_Output_TC_Pulse_Bits = 0x100,
+ Gi_Output_TC_Toggle_Bits = 0x200,
+ Gi_Output_TC_or_Gate_Toggle_Bits = 0x300,
+ Gi_Counting_Once_Mask = 0xc00,
+ Gi_No_Hardware_Disarm_Bits = 0x000,
+ Gi_Disarm_at_TC_Bits = 0x400,
+ Gi_Disarm_at_Gate_Bits = 0x800,
+ Gi_Disarm_at_TC_or_Gate_Bits = 0xc00,
+ Gi_Loading_On_TC_Bit = 0x1000,
+ Gi_Gate_Polarity_Bit = 0x2000,
+ Gi_Loading_On_Gate_Bit = 0x4000,
+ Gi_Reload_Source_Switching_Bit = 0x8000
+};
+
+#define Gi_Second_Gate_Select_Shift 7
+/*FIXME: m-series has a second gate subselect bit */
+/*FIXME: m-series second gate sources are undocumented (by NI)*/
+enum Gi_Second_Gate_Bits {
+ Gi_Second_Gate_Mode_Bit = 0x1,
+ Gi_Second_Gate_Select_Mask = 0x1f << Gi_Second_Gate_Select_Shift,
+ Gi_Second_Gate_Polarity_Bit = 0x2000,
+ Gi_Second_Gate_Subselect_Bit = 0x4000, /* m-series only */
+ Gi_Source_Subselect_Bit = 0x8000 /* m-series only */
+};
+static inline unsigned Gi_Second_Gate_Select_Bits(unsigned second_gate_select)
+{
+ return (second_gate_select << Gi_Second_Gate_Select_Shift) &
+ Gi_Second_Gate_Select_Mask;
+}
+
+enum Gxx_Status_Bits {
+ G0_Save_Bit = 0x1,
+ G1_Save_Bit = 0x2,
+ G0_Counting_Bit = 0x4,
+ G1_Counting_Bit = 0x8,
+ G0_Next_Load_Source_Bit = 0x10,
+ G1_Next_Load_Source_Bit = 0x20,
+ G0_Stale_Data_Bit = 0x40,
+ G1_Stale_Data_Bit = 0x80,
+ G0_Armed_Bit = 0x100,
+ G1_Armed_Bit = 0x200,
+ G0_No_Load_Between_Gates_Bit = 0x400,
+ G1_No_Load_Between_Gates_Bit = 0x800,
+ G0_TC_Error_Bit = 0x1000,
+ G1_TC_Error_Bit = 0x2000,
+ G0_Gate_Error_Bit = 0x4000,
+ G1_Gate_Error_Bit = 0x8000
+};
+static inline enum Gxx_Status_Bits Gi_Counting_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Counting_Bit;
+ return G0_Counting_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Armed_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Armed_Bit;
+ return G0_Armed_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Next_Load_Source_Bit(unsigned
+ counter_index)
+{
+ if (counter_index % 2)
+ return G1_Next_Load_Source_Bit;
+ return G0_Next_Load_Source_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Stale_Data_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Stale_Data_Bit;
+ return G0_Stale_Data_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_TC_Error_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_TC_Error_Bit;
+ return G0_TC_Error_Bit;
+}
+static inline enum Gxx_Status_Bits Gi_Gate_Error_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Gate_Error_Bit;
+ return G0_Gate_Error_Bit;
+}
+
+/* joint reset register bits */
+static inline unsigned Gi_Reset_Bit(unsigned counter_index)
+{
+ return 0x1 << (2 + (counter_index % 2));
+}
+
+enum Gxx_Joint_Status2_Bits {
+ G0_Output_Bit = 0x1,
+ G1_Output_Bit = 0x2,
+ G0_HW_Save_Bit = 0x1000,
+ G1_HW_Save_Bit = 0x2000,
+ G0_Permanent_Stale_Bit = 0x4000,
+ G1_Permanent_Stale_Bit = 0x8000
+};
+static inline enum Gxx_Joint_Status2_Bits Gi_Permanent_Stale_Bit(unsigned
+ counter_index)
+{
+ if (counter_index % 2)
+ return G1_Permanent_Stale_Bit;
+ return G0_Permanent_Stale_Bit;
+}
+
+enum Gi_DMA_Config_Reg_Bits {
+ Gi_DMA_Enable_Bit = 0x1,
+ Gi_DMA_Write_Bit = 0x2,
+ Gi_DMA_Int_Bit = 0x4
+};
+
+enum Gi_DMA_Status_Reg_Bits {
+ Gi_DMA_Readbank_Bit = 0x2000,
+ Gi_DRQ_Error_Bit = 0x4000,
+ Gi_DRQ_Status_Bit = 0x8000
+};
+
+enum G02_Interrupt_Acknowledge_Bits {
+ G0_Gate_Error_Confirm_Bit = 0x20,
+ G0_TC_Error_Confirm_Bit = 0x40
+};
+enum G13_Interrupt_Acknowledge_Bits {
+ G1_Gate_Error_Confirm_Bit = 0x2,
+ G1_TC_Error_Confirm_Bit = 0x4
+};
+static inline unsigned Gi_Gate_Error_Confirm_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_Gate_Error_Confirm_Bit;
+ return G0_Gate_Error_Confirm_Bit;
+}
+static inline unsigned Gi_TC_Error_Confirm_Bit(unsigned counter_index)
+{
+ if (counter_index % 2)
+ return G1_TC_Error_Confirm_Bit;
+ return G0_TC_Error_Confirm_Bit;
+}
+
+// bits that are the same in G0/G2 and G1/G3 interrupt acknowledge registers
+enum Gxx_Interrupt_Acknowledge_Bits {
+ Gi_TC_Interrupt_Ack_Bit = 0x4000,
+ Gi_Gate_Interrupt_Ack_Bit = 0x8000
+};
+
+enum Gi_Status_Bits {
+ Gi_Gate_Interrupt_Bit = 0x4,
+ Gi_TC_Bit = 0x8,
+ Gi_Interrupt_Bit = 0x8000
+};
+
+enum G02_Interrupt_Enable_Bits {
+ G0_TC_Interrupt_Enable_Bit = 0x40,
+ G0_Gate_Interrupt_Enable_Bit = 0x100
+};
+enum G13_Interrupt_Enable_Bits {
+ G1_TC_Interrupt_Enable_Bit = 0x200,
+ G1_Gate_Interrupt_Enable_Bit = 0x400
+};
+static inline unsigned Gi_Gate_Interrupt_Enable_Bit(unsigned counter_index)
+{
+ unsigned bit;
+
+ if (counter_index % 2) {
+ bit = G1_Gate_Interrupt_Enable_Bit;
+ } else {
+ bit = G0_Gate_Interrupt_Enable_Bit;
+ }
+ return bit;
+}
+
+static inline void write_register(struct ni_gpct *counter, unsigned bits,
+ enum ni_gpct_register reg)
+{
+ BUG_ON(reg >= NITIO_Num_Registers);
+ counter->counter_dev->write_register(counter, bits, reg);
+}
+
+static inline unsigned read_register(struct ni_gpct *counter,
+ enum ni_gpct_register reg)
+{
+ BUG_ON(reg >= NITIO_Num_Registers);
+ return counter->counter_dev->read_register(counter, reg);
+}
+
+static inline int ni_tio_counting_mode_registers_present(
+ const struct ni_gpct_device *counter_dev)
+{
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ return 0;
+ break;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ return 1;
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return 0;
+}
+
+static inline void ni_tio_set_bits_transient(struct ni_gpct *counter,
+ enum ni_gpct_register register_index, unsigned bit_mask,
+ unsigned bit_values, unsigned transient_bit_values)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned long flags;
+
+ BUG_ON(register_index >= NITIO_Num_Registers);
+ comedi_spin_lock_irqsave(&counter_dev->regs_lock, flags);
+ counter_dev->regs[register_index] &= ~bit_mask;
+ counter_dev->regs[register_index] |= (bit_values & bit_mask);
+ write_register(counter,
+ counter_dev->regs[register_index] | transient_bit_values,
+ register_index);
+ mmiowb();
+ comedi_spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
+}
+
+/* ni_tio_set_bits( ) is for safely writing to registers whose bits may be
+twiddled in interrupt context, or whose software copy may be read in interrupt context.
+*/
+static inline void ni_tio_set_bits(struct ni_gpct *counter,
+ enum ni_gpct_register register_index, unsigned bit_mask,
+ unsigned bit_values)
+{
+ ni_tio_set_bits_transient(counter, register_index, bit_mask, bit_values,
+ 0x0);
+}
+
+/* ni_tio_get_soft_copy( ) is for safely reading the software copy of a register
+whose bits might be modified in interrupt context, or whose software copy
+might need to be read in interrupt context.
+*/
+static inline unsigned ni_tio_get_soft_copy(const struct ni_gpct *counter,
+ enum ni_gpct_register register_index)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned long flags;
+ unsigned value;
+
+ BUG_ON(register_index >= NITIO_Num_Registers);
+ comedi_spin_lock_irqsave(&counter_dev->regs_lock, flags);
+ value = counter_dev->regs[register_index];
+ comedi_spin_unlock_irqrestore(&counter_dev->regs_lock, flags);
+ return value;
+}
+
+int ni_tio_arm(struct ni_gpct *counter, int arm, unsigned start_trigger);
+int ni_tio_set_gate_src(struct ni_gpct *counter, unsigned gate_index,
+ unsigned int gate_source);
+
+#endif /* _COMEDI_NI_TIO_INTERNAL_H */
diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c
new file mode 100644
index 00000000000..16a26e73c99
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ni_tiocmd.c
@@ -0,0 +1,523 @@
+/*
+ comedi/drivers/ni_tiocmd.c
+ Command support for NI general purpose counters
+
+ Copyright (C) 2006 Frank Mori Hess <fmhess@users.sourceforge.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/*
+Driver: ni_tiocmd
+Description: National Instruments general purpose counters command support
+Devices:
+Author: J.P. Mellor <jpmellor@rose-hulman.edu>,
+ Herman.Bruyninckx@mech.kuleuven.ac.be,
+ Wim.Meeussen@mech.kuleuven.ac.be,
+ Klaas.Gadeyne@mech.kuleuven.ac.be,
+ Frank Mori Hess <fmhess@users.sourceforge.net>
+Updated: Fri, 11 Apr 2008 12:32:35 +0100
+Status: works
+
+This module is not used directly by end-users. Rather, it
+is used by other drivers (for example ni_660x and ni_pcimio)
+to provide command support for NI's general purpose counters.
+It was originally split out of ni_tio.c to stop the 'ni_tio'
+module depending on the 'mite' module.
+
+References:
+DAQ 660x Register-Level Programmer Manual (NI 370505A-01)
+DAQ 6601/6602 User Manual (NI 322137B-01)
+340934b.pdf DAQ-STC reference manual
+
+*/
+/*
+TODO:
+ Support use of both banks X and Y
+*/
+
+#include "ni_tio_internal.h"
+#include "mite.h"
+
+MODULE_AUTHOR("Comedi <comedi@comedi.org>");
+MODULE_DESCRIPTION("Comedi command support for NI general-purpose counters");
+MODULE_LICENSE("GPL");
+
+static void ni_tio_configure_dma(struct ni_gpct *counter, short enable,
+ short read_not_write)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ unsigned input_select_bits = 0;
+
+ if (enable) {
+ if (read_not_write) {
+ input_select_bits |= Gi_Read_Acknowledges_Irq;
+ } else {
+ input_select_bits |= Gi_Write_Acknowledges_Irq;
+ }
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Input_Select_Reg(counter->counter_index),
+ Gi_Read_Acknowledges_Irq | Gi_Write_Acknowledges_Irq,
+ input_select_bits);
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_e_series:
+ break;
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ {
+ unsigned gi_dma_config_bits = 0;
+
+ if (enable) {
+ gi_dma_config_bits |= Gi_DMA_Enable_Bit;
+ gi_dma_config_bits |= Gi_DMA_Int_Bit;
+ }
+ if (read_not_write == 0) {
+ gi_dma_config_bits |= Gi_DMA_Write_Bit;
+ }
+ ni_tio_set_bits(counter,
+ NITIO_Gi_DMA_Config_Reg(counter->counter_index),
+ Gi_DMA_Enable_Bit | Gi_DMA_Int_Bit |
+ Gi_DMA_Write_Bit, gi_dma_config_bits);
+ }
+ break;
+ }
+}
+
+static int ni_tio_input_inttrig(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ unsigned long flags;
+ int retval = 0;
+ struct ni_gpct *counter = s->private;
+
+ BUG_ON(counter == NULL);
+ if (trignum != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan)
+ mite_dma_arm(counter->mite_chan);
+ else
+ retval = -EIO;
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ if (retval < 0)
+ return retval;
+ retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ s->async->inttrig = NULL;
+
+ return retval;
+}
+
+static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+ struct ni_gpct_device *counter_dev = counter->counter_dev;
+ struct comedi_cmd *cmd = &async->cmd;
+ int retval = 0;
+
+ /* write alloc the entire buffer */
+ comedi_buf_write_alloc(async, async->prealloc_bufsz);
+ counter->mite_chan->dir = COMEDI_INPUT;
+ switch (counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ mite_prep_dma(counter->mite_chan, 32, 32);
+ break;
+ case ni_gpct_variant_e_series:
+ mite_prep_dma(counter->mite_chan, 16, 32);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ ni_tio_set_bits(counter, NITIO_Gi_Command_Reg(counter->counter_index),
+ Gi_Save_Trace_Bit, 0);
+ ni_tio_configure_dma(counter, 1, 1);
+ switch (cmd->start_src) {
+ case TRIG_NOW:
+ async->inttrig = NULL;
+ mite_dma_arm(counter->mite_chan);
+ retval = ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+ break;
+ case TRIG_INT:
+ async->inttrig = &ni_tio_input_inttrig;
+ break;
+ case TRIG_EXT:
+ async->inttrig = NULL;
+ mite_dma_arm(counter->mite_chan);
+ retval = ni_tio_arm(counter, 1, cmd->start_arg);
+ case TRIG_OTHER:
+ async->inttrig = NULL;
+ mite_dma_arm(counter->mite_chan);
+ break;
+ default:
+ BUG();
+ break;
+ }
+ return retval;
+}
+
+static int ni_tio_output_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+ rt_printk("ni_tio: output commands not yet implemented.\n");
+ return -ENOTSUPP;
+
+ counter->mite_chan->dir = COMEDI_OUTPUT;
+ mite_prep_dma(counter->mite_chan, 32, 32);
+ ni_tio_configure_dma(counter, 1, 0);
+ mite_dma_arm(counter->mite_chan);
+ return ni_tio_arm(counter, 1, NI_GPCT_ARM_IMMEDIATE);
+}
+
+static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async)
+{
+ struct comedi_cmd *cmd = &async->cmd;
+ int set_gate_source = 0;
+ unsigned gate_source;
+ int retval = 0;
+
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ set_gate_source = 1;
+ gate_source = cmd->scan_begin_arg;
+ } else if (cmd->convert_src == TRIG_EXT) {
+ set_gate_source = 1;
+ gate_source = cmd->convert_arg;
+ }
+ if (set_gate_source) {
+ retval = ni_tio_set_gate_src(counter, 0, gate_source);
+ }
+ if (cmd->flags & TRIG_WAKE_EOS) {
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
+ Gi_Gate_Interrupt_Enable_Bit(counter->counter_index),
+ Gi_Gate_Interrupt_Enable_Bit(counter->counter_index));
+ }
+ return retval;
+}
+
+int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async)
+{
+ struct comedi_cmd *cmd = &async->cmd;
+ int retval = 0;
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan == NULL) {
+ rt_printk
+ ("ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n");
+ retval = -EIO;
+ } else {
+ retval = ni_tio_cmd_setup(counter, async);
+ if (retval == 0) {
+ if (cmd->flags & CMDF_WRITE) {
+ retval = ni_tio_output_cmd(counter, async);
+ } else {
+ retval = ni_tio_input_cmd(counter, async);
+ }
+ }
+ }
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ return retval;
+}
+
+int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+ int sources;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ sources = TRIG_NOW | TRIG_INT | TRIG_OTHER;
+ if (ni_tio_counting_mode_registers_present(counter->counter_dev))
+ sources |= TRIG_EXT;
+ cmd->start_src &= sources;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW | TRIG_EXT | TRIG_OTHER;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ sources = TRIG_NOW | TRIG_EXT | TRIG_OTHER;
+ cmd->convert_src &= sources;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique... */
+
+ if (cmd->start_src != TRIG_NOW &&
+ cmd->start_src != TRIG_INT &&
+ cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_OTHER)
+ err++;
+ if (cmd->scan_begin_src != TRIG_FOLLOW &&
+ cmd->scan_begin_src != TRIG_EXT &&
+ cmd->scan_begin_src != TRIG_OTHER)
+ err++;
+ if (cmd->convert_src != TRIG_OTHER &&
+ cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_NONE)
+ err++;
+ /* ... and mutually compatible */
+ if (cmd->convert_src != TRIG_NOW && cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_src != TRIG_EXT) {
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->scan_begin_src != TRIG_EXT) {
+ if (cmd->scan_begin_arg) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ }
+ if (cmd->convert_src != TRIG_EXT) {
+ if (cmd->convert_arg) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+int ni_tio_cancel(struct ni_gpct *counter)
+{
+ unsigned long flags;
+
+ ni_tio_arm(counter, 0, 0);
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan) {
+ mite_dma_disarm(counter->mite_chan);
+ }
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ ni_tio_configure_dma(counter, 0, 0);
+
+ ni_tio_set_bits(counter,
+ NITIO_Gi_Interrupt_Enable_Reg(counter->counter_index),
+ Gi_Gate_Interrupt_Enable_Bit(counter->counter_index), 0x0);
+ return 0;
+}
+
+ /* During buffered input counter operation for e-series, the gate interrupt is acked
+ automatically by the dma controller, due to the Gi_Read/Write_Acknowledges_IRQ bits
+ in the input select register. */
+static int should_ack_gate(struct ni_gpct *counter)
+{
+ unsigned long flags;
+ int retval = 0;
+
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x: // not sure if 660x really supports gate interrupts (the bits are not listed in register-level manual)
+ return 1;
+ break;
+ case ni_gpct_variant_e_series:
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ {
+ if (counter->mite_chan == NULL ||
+ counter->mite_chan->dir != COMEDI_INPUT ||
+ (mite_done(counter->mite_chan))) {
+ retval = 1;
+ }
+ }
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ break;
+ }
+ return retval;
+}
+
+void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error,
+ int *tc_error, int *perm_stale_data, int *stale_data)
+{
+ const unsigned short gxx_status = read_register(counter,
+ NITIO_Gxx_Status_Reg(counter->counter_index));
+ const unsigned short gi_status = read_register(counter,
+ NITIO_Gi_Status_Reg(counter->counter_index));
+ unsigned ack = 0;
+
+ if (gate_error)
+ *gate_error = 0;
+ if (tc_error)
+ *tc_error = 0;
+ if (perm_stale_data)
+ *perm_stale_data = 0;
+ if (stale_data)
+ *stale_data = 0;
+
+ if (gxx_status & Gi_Gate_Error_Bit(counter->counter_index)) {
+ ack |= Gi_Gate_Error_Confirm_Bit(counter->counter_index);
+ if (gate_error) {
+ /*660x don't support automatic acknowledgement of gate interrupt via dma read/write
+ and report bogus gate errors */
+ if (counter->counter_dev->variant !=
+ ni_gpct_variant_660x) {
+ *gate_error = 1;
+ }
+ }
+ }
+ if (gxx_status & Gi_TC_Error_Bit(counter->counter_index)) {
+ ack |= Gi_TC_Error_Confirm_Bit(counter->counter_index);
+ if (tc_error)
+ *tc_error = 1;
+ }
+ if (gi_status & Gi_TC_Bit) {
+ ack |= Gi_TC_Interrupt_Ack_Bit;
+ }
+ if (gi_status & Gi_Gate_Interrupt_Bit) {
+ if (should_ack_gate(counter))
+ ack |= Gi_Gate_Interrupt_Ack_Bit;
+ }
+ if (ack)
+ write_register(counter, ack,
+ NITIO_Gi_Interrupt_Acknowledge_Reg(counter->
+ counter_index));
+ if (ni_tio_get_soft_copy(counter,
+ NITIO_Gi_Mode_Reg(counter->
+ counter_index)) & Gi_Loading_On_Gate_Bit) {
+ if (gxx_status & Gi_Stale_Data_Bit(counter->counter_index)) {
+ if (stale_data)
+ *stale_data = 1;
+ }
+ if (read_register(counter,
+ NITIO_Gxx_Joint_Status2_Reg(counter->
+ counter_index)) &
+ Gi_Permanent_Stale_Bit(counter->counter_index)) {
+ rt_printk("%s: Gi_Permanent_Stale_Data detected.\n",
+ __FUNCTION__);
+ if (perm_stale_data)
+ *perm_stale_data = 1;
+ }
+ }
+}
+
+void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice * s)
+{
+ unsigned gpct_mite_status;
+ unsigned long flags;
+ int gate_error;
+ int tc_error;
+ int perm_stale_data;
+
+ ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error,
+ &perm_stale_data, NULL);
+ if (gate_error) {
+ rt_printk("%s: Gi_Gate_Error detected.\n", __FUNCTION__);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ if (perm_stale_data) {
+ s->async->events |= COMEDI_CB_ERROR;
+ }
+ switch (counter->counter_dev->variant) {
+ case ni_gpct_variant_m_series:
+ case ni_gpct_variant_660x:
+ if (read_register(counter,
+ NITIO_Gi_DMA_Status_Reg(counter->
+ counter_index)) & Gi_DRQ_Error_Bit) {
+ rt_printk("%s: Gi_DRQ_Error detected.\n", __FUNCTION__);
+ s->async->events |= COMEDI_CB_OVERFLOW;
+ }
+ break;
+ case ni_gpct_variant_e_series:
+ break;
+ }
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ if (counter->mite_chan == NULL) {
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+ return;
+ }
+ gpct_mite_status = mite_get_status(counter->mite_chan);
+ if (gpct_mite_status & CHSR_LINKC) {
+ writel(CHOR_CLRLC,
+ counter->mite_chan->mite->mite_io_addr +
+ MITE_CHOR(counter->mite_chan->channel));
+ }
+ mite_sync_input_dma(counter->mite_chan, s->async);
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+}
+
+void ni_tio_set_mite_channel(struct ni_gpct *counter,
+ struct mite_channel *mite_chan)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&counter->lock, flags);
+ counter->mite_chan = mite_chan;
+ comedi_spin_unlock_irqrestore(&counter->lock, flags);
+}
+
+static int __init ni_tiocmd_init_module(void)
+{
+ return 0;
+}
+
+module_init(ni_tiocmd_init_module);
+
+static void __exit ni_tiocmd_cleanup_module(void)
+{
+}
+
+module_exit(ni_tiocmd_cleanup_module);
+
+EXPORT_SYMBOL_GPL(ni_tio_cmd);
+EXPORT_SYMBOL_GPL(ni_tio_cmdtest);
+EXPORT_SYMBOL_GPL(ni_tio_cancel);
+EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt);
+EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel);
+EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm);
diff --git a/drivers/staging/comedi/drivers/pcl711.c b/drivers/staging/comedi/drivers/pcl711.c
new file mode 100644
index 00000000000..ce42506d47b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl711.c
@@ -0,0 +1,623 @@
+/*
+ comedi/drivers/pcl711.c
+ hardware driver for PC-LabCard PCL-711 and AdSys ACL-8112
+ and compatibles
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ Janne Jalkanen <jalkanen@cs.hut.fi>
+ Eric Bunn <ebu@cs.hut.fi>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: pcl711
+Description: Advantech PCL-711 and 711b, ADLink ACL-8112
+Author: ds, Janne Jalkanen <jalkanen@cs.hut.fi>, Eric Bunn <ebu@cs.hut.fi>
+Status: mostly complete
+Devices: [Advantech] PCL-711 (pcl711), PCL-711B (pcl711b),
+ [AdLink] ACL-8112HG (acl8112hg), ACL-8112DG (acl8112dg)
+
+Since these boards do not have DMA or FIFOs, only immediate mode is
+supported.
+
+*/
+
+/*
+ Dave Andruczyk <dave@tech.buffalostate.edu> also wrote a
+ driver for the PCL-711. I used a few ideas from his driver
+ here. His driver also has more comments, if you are
+ interested in understanding how this driver works.
+ http://tech.buffalostate.edu/~dave/driver/
+
+ The ACL-8112 driver was hacked from the sources of the PCL-711
+ driver (the 744 chip used on the 8112 is almost the same as
+ the 711b chip, but it has more I/O channels) by
+ Janne Jalkanen (jalkanen@cs.hut.fi) and
+ Erik Bunn (ebu@cs.hut.fi). Remerged with the PCL-711 driver
+ by ds.
+
+ [acl-8112]
+ This driver supports both TRIGNOW and TRIGCLK,
+ but does not yet support DMA transfers. It also supports
+ both high (HG) and low (DG) versions of the card, though
+ the HG version has been untested.
+
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8253.h"
+
+#define PCL711_SIZE 16
+
+#define PCL711_CTR0 0
+#define PCL711_CTR1 1
+#define PCL711_CTR2 2
+#define PCL711_CTRCTL 3
+#define PCL711_AD_LO 4
+#define PCL711_DA0_LO 4
+#define PCL711_AD_HI 5
+#define PCL711_DA0_HI 5
+#define PCL711_DI_LO 6
+#define PCL711_DA1_LO 6
+#define PCL711_DI_HI 7
+#define PCL711_DA1_HI 7
+#define PCL711_CLRINTR 8
+#define PCL711_GAIN 9
+#define PCL711_MUX 10
+#define PCL711_MODE 11
+#define PCL711_SOFTTRIG 12
+#define PCL711_DO_LO 13
+#define PCL711_DO_HI 14
+
+static const struct comedi_lrange range_pcl711b_ai = { 5, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(0.3125)
+ }
+};
+static const struct comedi_lrange range_acl8112hg_ai = { 12, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01)
+ }
+};
+static const struct comedi_lrange range_acl8112dg_ai = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10)
+ }
+};
+
+/*
+ * flags
+ */
+
+#define PCL711_TIMEOUT 100
+#define PCL711_DRDY 0x10
+
+static const int i8253_osc_base = 500; /* 2 Mhz */
+
+struct pcl711_board {
+
+ const char *name;
+ int is_pcl711b;
+ int is_8112;
+ int is_dg;
+ int n_ranges;
+ int n_aichan;
+ int n_aochan;
+ int maxirq;
+ const struct comedi_lrange *ai_range_type;
+};
+
+
+static const struct pcl711_board boardtypes[] = {
+ {"pcl711", 0, 0, 0, 5, 8, 1, 0, &range_bipolar5},
+ {"pcl711b", 1, 0, 0, 5, 8, 1, 7, &range_pcl711b_ai},
+ {"acl8112hg", 0, 1, 0, 12, 16, 2, 15, &range_acl8112hg_ai},
+ {"acl8112dg", 0, 1, 1, 9, 16, 2, 15, &range_acl8112dg_ai},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl711_board))
+#define this_board ((const struct pcl711_board *)dev->board_ptr)
+
+static int pcl711_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl711_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcl711 = {
+ driver_name:"pcl711",
+ module:THIS_MODULE,
+ attach:pcl711_attach,
+ detach:pcl711_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl711_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl711);
+
+struct pcl711_private {
+
+ int board;
+ int adchan;
+ int ntrig;
+ int aip[8];
+ int mode;
+ unsigned int ao_readback[2];
+ unsigned int divisor1;
+ unsigned int divisor2;
+};
+
+
+#define devpriv ((struct pcl711_private *)dev->private)
+
+static irqreturn_t pcl711_interrupt(int irq, void *d PT_REGS_ARG)
+{
+ int lo, hi;
+ int data;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+
+ hi = inb(dev->iobase + PCL711_AD_HI);
+ lo = inb(dev->iobase + PCL711_AD_LO);
+ outb(0, dev->iobase + PCL711_CLRINTR);
+
+ data = (hi << 8) | lo;
+
+ /* FIXME! Nothing else sets ntrig! */
+ if (!(--devpriv->ntrig)) {
+ if (this_board->is_8112) {
+ outb(1, dev->iobase + PCL711_MODE);
+ } else {
+ outb(0, dev->iobase + PCL711_MODE);
+ }
+
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+static void pcl711_set_changain(struct comedi_device * dev, int chan)
+{
+ int chan_register;
+
+ outb(CR_RANGE(chan), dev->iobase + PCL711_GAIN);
+
+ chan_register = CR_CHAN(chan);
+
+ if (this_board->is_8112) {
+
+ /*
+ * Set the correct channel. The two channel banks are switched
+ * using the mask value.
+ * NB: To use differential channels, you should use mask = 0x30,
+ * but I haven't written the support for this yet. /JJ
+ */
+
+ if (chan_register >= 8) {
+ chan_register = 0x20 | (chan_register & 0x7);
+ } else {
+ chan_register |= 0x10;
+ }
+ } else {
+ outb(chan_register, dev->iobase + PCL711_MUX);
+ }
+}
+
+static int pcl711_ai_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, n;
+ int hi, lo;
+
+ pcl711_set_changain(dev, insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ /*
+ * Write the correct mode (software polling) and start polling by writing
+ * to the trigger register
+ */
+ outb(1, dev->iobase + PCL711_MODE);
+
+ if (this_board->is_8112) {
+ } else {
+ outb(0, dev->iobase + PCL711_SOFTTRIG);
+ }
+
+ i = PCL711_TIMEOUT;
+ while (--i) {
+ hi = inb(dev->iobase + PCL711_AD_HI);
+ if (!(hi & PCL711_DRDY))
+ goto ok;
+ comedi_udelay(1);
+ }
+ rt_printk("comedi%d: pcl711: A/D timeout\n", dev->minor);
+ return -ETIME;
+
+ ok:
+ lo = inb(dev->iobase + PCL711_AD_LO);
+
+ data[n] = ((hi & 0xf) << 8) | lo;
+ }
+
+ return n;
+}
+
+static int pcl711_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int tmp;
+ int err = 0;
+
+ /* step 1 */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2 */
+
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3 */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+ if (cmd->scan_begin_src == TRIG_EXT) {
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ } else {
+#define MAX_SPEED 1000
+#define TIMER_BASE 100
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ }
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_NONE) {
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ } else {
+ /* ignore */
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4 */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ i8253_cascade_ns_to_timer_2div(TIMER_BASE,
+ &devpriv->divisor1, &devpriv->divisor2,
+ &cmd->scan_begin_arg, cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int pcl711_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int timer1, timer2;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ pcl711_set_changain(dev, cmd->chanlist[0]);
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ /*
+ * Set timers
+ * timer chip is an 8253, with timers 1 and 2
+ * cascaded
+ * 0x74 = Select Counter 1 | LSB/MSB | Mode=2 | Binary
+ * Mode 2 = Rate generator
+ *
+ * 0xb4 = Select Counter 2 | LSB/MSB | Mode=2 | Binary
+ */
+
+ i8253_cascade_ns_to_timer(i8253_osc_base, &timer1, &timer2,
+ &cmd->scan_begin_arg, TRIG_ROUND_NEAREST);
+
+ outb(0x74, dev->iobase + PCL711_CTRCTL);
+ outb(timer1 & 0xff, dev->iobase + PCL711_CTR1);
+ outb((timer1 >> 8) & 0xff, dev->iobase + PCL711_CTR1);
+ outb(0xb4, dev->iobase + PCL711_CTRCTL);
+ outb(timer2 & 0xff, dev->iobase + PCL711_CTR2);
+ outb((timer2 >> 8) & 0xff, dev->iobase + PCL711_CTR2);
+
+ /* clear pending interrupts (just in case) */
+ outb(0, dev->iobase + PCL711_CLRINTR);
+
+ /*
+ * Set mode to IRQ transfer
+ */
+ outb(devpriv->mode | 6, dev->iobase + PCL711_MODE);
+ } else {
+ /* external trigger */
+ outb(devpriv->mode | 3, dev->iobase + PCL711_MODE);
+ }
+
+ return 0;
+}
+
+/*
+ analog output
+*/
+static int pcl711_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ outb((data[n] & 0xff),
+ dev->iobase + (chan ? PCL711_DA1_LO : PCL711_DA0_LO));
+ outb((data[n] >> 8),
+ dev->iobase + (chan ? PCL711_DA1_HI : PCL711_DA0_HI));
+
+ devpriv->ao_readback[chan] = data[n];
+ }
+
+ return n;
+}
+
+static int pcl711_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+
+}
+
+/* Digital port read - Untested on 8112 */
+static int pcl711_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL711_DI_LO) |
+ (inb(dev->iobase + PCL711_DI_HI) << 8);
+
+ return 2;
+}
+
+/* Digital port write - Untested on 8112 */
+static int pcl711_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ }
+ if (data[0] & 0x00ff)
+ outb(s->state & 0xff, dev->iobase + PCL711_DO_LO);
+ if (data[0] & 0xff00)
+ outb((s->state >> 8), dev->iobase + PCL711_DO_HI);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+/* Free any resources that we have claimed */
+static int pcl711_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcl711: remove\n", dev->minor);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ if (dev->iobase)
+ release_region(dev->iobase, PCL711_SIZE);
+
+ return 0;
+}
+
+/* Initialization */
+static int pcl711_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ unsigned int irq;
+ struct comedi_subdevice *s;
+
+ /* claim our I/O space */
+
+ iobase = it->options[0];
+ printk("comedi%d: pcl711: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCL711_SIZE, "pcl711")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ /* there should be a sanity check here */
+
+ /* set up some name stuff */
+ dev->board_name = this_board->name;
+
+ /* grab our IRQ */
+ irq = it->options[1];
+ if (irq > this_board->maxirq) {
+ printk("irq out of range\n");
+ return -EINVAL;
+ }
+ if (irq) {
+ if (comedi_request_irq(irq, pcl711_interrupt, 0, "pcl711", dev)) {
+ printk("unable to allocate irq %u\n", irq);
+ return -EINVAL;
+ } else {
+ printk("( irq = %u )\n", irq);
+ }
+ }
+ dev->irq = irq;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct pcl711_private))) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ /* AI subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aichan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->range_table = this_board->ai_range_type;
+ s->insn_read = pcl711_ai_insn;
+ if (irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pcl711_ai_cmdtest;
+ s->do_cmd = pcl711_ai_cmd;
+ }
+
+ s++;
+ /* AO subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->range_table = &range_bipolar5;
+ s->insn_write = pcl711_ao_insn;
+ s->insn_read = pcl711_ao_insn_read;
+
+ s++;
+ /* 16-bit digital input */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 16;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl711_di_insn_bits;
+
+ s++;
+ /* 16-bit digital out */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 16;
+ s->range_table = &range_digital;
+ s->state = 0;
+ s->insn_bits = pcl711_do_insn_bits;
+
+ /*
+ this is the "base value" for the mode register, which is
+ used for the irq on the PCL711
+ */
+ if (this_board->is_pcl711b) {
+ devpriv->mode = (dev->irq << 4);
+ }
+
+ /* clear DAC */
+ outb(0, dev->iobase + PCL711_DA0_LO);
+ outb(0, dev->iobase + PCL711_DA0_HI);
+ outb(0, dev->iobase + PCL711_DA1_LO);
+ outb(0, dev->iobase + PCL711_DA1_HI);
+
+ printk("\n");
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl724.c b/drivers/staging/comedi/drivers/pcl724.c
new file mode 100644
index 00000000000..cd1e784f25f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl724.c
@@ -0,0 +1,222 @@
+/*
+ comedi/drivers/pcl724.c
+
+ Michal Dobes <dobes@tesnet.cz>
+
+ hardware driver for Advantech cards:
+ card: PCL-724, PCL-722, PCL-731
+ driver: pcl724, pcl722, pcl731
+ and ADLink cards:
+ card: ACL-7122, ACL-7124, PET-48DIO
+ driver: acl7122, acl7124, pet48dio
+
+ Options for PCL-724, PCL-731, ACL-7124 and PET-48DIO:
+ [0] - IO Base
+
+ Options for PCL-722 and ACL-7122:
+ [0] - IO Base
+ [1] - IRQ (0=disable IRQ) IRQ isn't supported at this time!
+ [2] -number of DIO:
+ 0, 144: 144 DIO configuration
+ 1, 96: 96 DIO configuration
+*/
+/*
+Driver: pcl724
+Description: Advantech PCL-724, PCL-722, PCL-731 ADLink ACL-7122, ACL-7124,
+ PET-48DIO
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-724 (pcl724), PCL-722 (pcl722), PCL-731 (pcl731),
+ [ADLink] ACL-7122 (acl7122), ACL-7124 (acl7124), PET-48DIO (pet48dio)
+Status: untested
+
+This is driver for digital I/O boards PCL-722/724/731 with 144/24/48 DIO
+and for digital I/O boards ACL-7122/7124/PET-48DIO with 144/24/48 DIO.
+It need 8255.o for operations and only immediate mode is supported.
+See the source for configuration details.
+*/
+/*
+ * check_driver overrides:
+ * struct comedi_insn
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8255.h"
+
+#define PCL722_SIZE 32
+#define PCL722_96_SIZE 16
+#define PCL724_SIZE 4
+#define PCL731_SIZE 8
+#define PET48_SIZE 2
+
+#define SIZE_8255 4
+
+// #define PCL724_IRQ 1 /* no IRQ support now */
+
+static int pcl724_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl724_detach(struct comedi_device * dev);
+
+struct pcl724_board {
+
+ const char *name; // board name
+ int dio; // num of DIO
+ int numofports; // num of 8255 subdevices
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int io_range; // len of IO space
+ char can_have96;
+ char is_pet48;
+};
+
+
+static const struct pcl724_board boardtypes[] = {
+ {"pcl724", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,},
+ {"pcl722", 144, 6, 0x00fc, PCL722_SIZE, 1, 0,},
+ {"pcl731", 48, 2, 0x9cfc, PCL731_SIZE, 0, 0,},
+ {"acl7122", 144, 6, 0x9ee8, PCL722_SIZE, 1, 0,},
+ {"acl7124", 24, 1, 0x00fc, PCL724_SIZE, 0, 0,},
+ {"pet48dio", 48, 2, 0x9eb8, PET48_SIZE, 0, 1,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl724_board))
+#define this_board ((const struct pcl724_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl724 = {
+ driver_name:"pcl724",
+ module:THIS_MODULE,
+ attach:pcl724_attach,
+ detach:pcl724_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl724_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl724);
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+ unsigned long iobase = arg;
+
+ if (dir) {
+ outb(data, iobase + port);
+ return 0;
+ } else {
+ return inb(iobase + port);
+ }
+}
+
+static int subdev_8255mapped_cb(int dir, int port, int data,
+ unsigned long iobase)
+{
+ int movport = SIZE_8255 * (iobase >> 12);
+
+ iobase &= 0x0fff;
+
+ if (dir) {
+ outb(port + movport, iobase);
+ outb(data, iobase + 1);
+ return 0;
+ } else {
+ outb(port + movport, iobase);
+ return inb(iobase + 1);
+ }
+}
+
+static int pcl724_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase;
+ unsigned int iorange;
+ int ret, i, n_subdevices;
+#ifdef PCL724_IRQ
+ unsigned int irq;
+#endif
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ if ((this_board->can_have96) && ((it->options[1] == 1)
+ || (it->options[1] == 96)))
+ iorange = PCL722_96_SIZE; // PCL-724 in 96 DIO configuration
+ printk("comedi%d: pcl724: board=%s, 0x%03lx ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "pcl724")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+
+#ifdef PCL724_IRQ
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ rt_printk
+ (", IRQ %u is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl724, 0,
+ "pcl724", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+#endif
+
+ printk("\n");
+
+ n_subdevices = this_board->numofports;
+ if ((this_board->can_have96) && ((it->options[1] == 1)
+ || (it->options[1] == 96)))
+ n_subdevices = 4; // PCL-724 in 96 DIO configuration
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ if (this_board->is_pet48) {
+ subdev_8255_init(dev, dev->subdevices + i,
+ subdev_8255mapped_cb,
+ (unsigned long)(dev->iobase + i * 0x1000));
+ } else
+ subdev_8255_init(dev, dev->subdevices + i,
+ subdev_8255_cb,
+ (unsigned long)(dev->iobase + SIZE_8255 * i));
+ };
+
+ return 0;
+}
+
+static int pcl724_detach(struct comedi_device * dev)
+{
+ int i;
+
+// printk("comedi%d: pcl724: remove\n",dev->minor);
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+
+#ifdef PCL724_IRQ
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+#endif
+
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl725.c b/drivers/staging/comedi/drivers/pcl725.c
new file mode 100644
index 00000000000..0766ba02bd0
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl725.c
@@ -0,0 +1,111 @@
+/*
+ * comedi/drivers/pcl725.c
+ * Driver for PCL725 and clones
+ * David A. Schleef
+ */
+/*
+Driver: pcl725
+Description: Advantech PCL-725 (& compatibles)
+Author: ds
+Status: unknown
+Devices: [Advantech] PCL-725 (pcl725)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCL725_SIZE 2
+
+#define PCL725_DO 0
+#define PCL725_DI 1
+
+static int pcl725_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl725_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcl725 = {
+ driver_name:"pcl725",
+ module:THIS_MODULE,
+ attach:pcl725_attach,
+ detach:pcl725_detach,
+};
+
+COMEDI_INITCLEANUP(driver_pcl725);
+
+static int pcl725_do_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outb(s->state, dev->iobase + PCL725_DO);
+ }
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcl725_di_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL725_DI);
+
+ return 2;
+}
+
+static int pcl725_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcl725: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCL725_SIZE, "pcl725")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->board_name = "pcl725";
+ dev->iobase = iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 2) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcl725_do_insn;
+ s->range_table = &range_digital;
+
+ s = dev->subdevices + 1;
+ /* di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcl725_di_insn;
+ s->range_table = &range_digital;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int pcl725_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcl725: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, PCL725_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl726.c b/drivers/staging/comedi/drivers/pcl726.c
new file mode 100644
index 00000000000..6dbd33d7907
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl726.c
@@ -0,0 +1,377 @@
+/*
+ comedi/drivers/pcl726.c
+
+ hardware driver for Advantech cards:
+ card: PCL-726, PCL-727, PCL-728
+ driver: pcl726, pcl727, pcl728
+ and for ADLink cards:
+ card: ACL-6126, ACL-6128
+ driver: acl6126, acl6128
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: pcl726
+Description: Advantech PCL-726 & compatibles
+Author: ds
+Status: untested
+Devices: [Advantech] PCL-726 (pcl726), PCL-727 (pcl727), PCL-728 (pcl728),
+ [ADLink] ACL-6126 (acl6126), ACL-6128 (acl6128)
+
+Interrupts are not supported.
+
+ Options for PCL-726:
+ [0] - IO Base
+ [2]...[7] - D/A output range for channel 1-6:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ 4: 4-20mA, 5: unknown (external reference)
+
+ Options for PCL-727:
+ [0] - IO Base
+ [2]...[13] - D/A output range for channel 1-12:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V,
+ 3: 4-20mA
+
+ Options for PCL-728 and ACL-6128:
+ [0] - IO Base
+ [2], [3] - D/A output range for channel 1 and 2:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ 4: 4-20mA, 5: 0-20mA
+
+ Options for ACL-6126:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 3, 5, 6, 7, 9, 10, 11, 12, 15) (currently ignored)
+ [2]...[7] - D/A output range for channel 1-6:
+ 0: 0-5V, 1: 0-10V, 2: +/-5V, 3: +/-10V,
+ 4: 4-20mA
+*/
+
+/*
+ Thanks to Circuit Specialists for having programming info (!) on
+ their web page. (http://www.cir.com/)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#undef ACL6126_IRQ /* no interrupt support (yet) */
+
+#define PCL726_SIZE 16
+#define PCL727_SIZE 32
+#define PCL728_SIZE 8
+
+#define PCL726_DAC0_HI 0
+#define PCL726_DAC0_LO 1
+
+#define PCL726_DO_HI 12
+#define PCL726_DO_LO 13
+#define PCL726_DI_HI 14
+#define PCL726_DI_LO 15
+
+#define PCL727_DO_HI 24
+#define PCL727_DO_LO 25
+#define PCL727_DI_HI 0
+#define PCL727_DI_LO 1
+
+static const struct comedi_lrange range_4_20mA = { 1, {RANGE_mA(4, 20)} };
+static const struct comedi_lrange range_0_20mA = { 1, {RANGE_mA(0, 20)} };
+
+static const struct comedi_lrange *const rangelist_726[] = {
+ &range_unipolar5, &range_unipolar10,
+ &range_bipolar5, &range_bipolar10,
+ &range_4_20mA, &range_unknown
+};
+
+static const struct comedi_lrange *const rangelist_727[] = {
+ &range_unipolar5, &range_unipolar10,
+ &range_bipolar5,
+ &range_4_20mA
+};
+
+static const struct comedi_lrange *const rangelist_728[] = {
+ &range_unipolar5, &range_unipolar10,
+ &range_bipolar5, &range_bipolar10,
+ &range_4_20mA, &range_0_20mA
+};
+
+static int pcl726_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl726_detach(struct comedi_device * dev);
+
+struct pcl726_board {
+
+ const char *name; // driver name
+ int n_aochan; // num of D/A chans
+ int num_of_ranges; // num of ranges
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int io_range; // len of IO space
+ char have_dio; // 1=card have DI/DO ports
+ int di_hi; // ports for DI/DO operations
+ int di_lo;
+ int do_hi;
+ int do_lo;
+ const struct comedi_lrange *const *range_type_list; // list of supported ranges
+};
+
+
+static const struct pcl726_board boardtypes[] = {
+ {"pcl726", 6, 6, 0x0000, PCL726_SIZE, 1,
+ PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+ &rangelist_726[0],},
+ {"pcl727", 12, 4, 0x0000, PCL727_SIZE, 1,
+ PCL727_DI_HI, PCL727_DI_LO, PCL727_DO_HI, PCL727_DO_LO,
+ &rangelist_727[0],},
+ {"pcl728", 2, 6, 0x0000, PCL728_SIZE, 0,
+ 0, 0, 0, 0,
+ &rangelist_728[0],},
+ {"acl6126", 6, 5, 0x96e8, PCL726_SIZE, 1,
+ PCL726_DI_HI, PCL726_DI_LO, PCL726_DO_HI, PCL726_DO_LO,
+ &rangelist_726[0],},
+ {"acl6128", 2, 6, 0x0000, PCL728_SIZE, 0,
+ 0, 0, 0, 0,
+ &rangelist_728[0],},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl726_board))
+#define this_board ((const struct pcl726_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl726 = {
+ driver_name:"pcl726",
+ module:THIS_MODULE,
+ attach:pcl726_attach,
+ detach:pcl726_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl726_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl726);
+
+struct pcl726_private {
+
+ int bipolar[12];
+ const struct comedi_lrange *rangelist[12];
+ unsigned int ao_readback[12];
+};
+
+#define devpriv ((struct pcl726_private *)dev->private)
+
+static int pcl726_ao_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int hi, lo;
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ lo = data[n] & 0xff;
+ hi = (data[n] >> 8) & 0xf;
+ if (devpriv->bipolar[chan])
+ hi ^= 0x8;
+ /*
+ * the programming info did not say which order
+ * to write bytes. switch the order of the next
+ * two lines if you get glitches.
+ */
+ outb(hi, dev->iobase + PCL726_DAC0_HI + 2 * chan);
+ outb(lo, dev->iobase + PCL726_DAC0_LO + 2 * chan);
+ devpriv->ao_readback[chan] = data[n];
+ }
+
+ return n;
+}
+
+static int pcl726_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int n;
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+ return n;
+}
+
+static int pcl726_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + this_board->di_lo) |
+ (inb(dev->iobase + this_board->di_hi) << 8);
+
+ return 2;
+}
+
+static int pcl726_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ }
+ if (data[1] & 0x00ff)
+ outb(s->state & 0xff, dev->iobase + this_board->do_lo);
+ if (data[1] & 0xff00)
+ outb((s->state >> 8), dev->iobase + this_board->do_hi);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcl726_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ unsigned int iorange;
+ int ret, i;
+#ifdef ACL6126_IRQ
+ unsigned int irq;
+#endif
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ printk("comedi%d: pcl726: board=%s, 0x%03lx ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "pcl726")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ dev->board_name = this_board->name;
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl726_private))) < 0)
+ return -ENOMEM;
+
+ for (i = 0; i < 12; i++) {
+ devpriv->bipolar[i] = 0;
+ devpriv->rangelist[i] = &range_unknown;
+ }
+
+#ifdef ACL6126_IRQ
+ irq = 0;
+ if (boardtypes[board].IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ devpriv->first_chan = 2;
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & boardtypes[board].IRQbits) == 0) {
+ rt_printk
+ (", IRQ %d is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl818, 0,
+ "pcl726", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %d, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%d", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+#endif
+
+ printk("\n");
+
+ if ((ret = alloc_subdevices(dev, 3)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ /* ao */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->insn_write = pcl726_ao_insn;
+ s->insn_read = pcl726_ao_insn_read;
+ s->range_table_list = devpriv->rangelist;
+ for (i = 0; i < this_board->n_aochan; i++) {
+ int j;
+
+ j = it->options[2 + 1];
+ if ((j < 0) || (j >= this_board->num_of_ranges)) {
+ printk("Invalid range for channel %d! Must be 0<=%d<%d\n", i, j, this_board->num_of_ranges - 1);
+ j = 0;
+ }
+ devpriv->rangelist[i] = this_board->range_type_list[j];
+ if (devpriv->rangelist[i]->range[0].min ==
+ -devpriv->rangelist[i]->range[0].max)
+ devpriv->bipolar[i] = 1; /* bipolar range */
+ }
+
+ s = dev->subdevices + 1;
+ /* di */
+ if (!this_board->have_dio) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 1;
+ s->insn_bits = pcl726_di_insn_bits;
+ s->range_table = &range_digital;
+ }
+
+ s = dev->subdevices + 2;
+ /* do */
+ if (!this_board->have_dio) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->len_chanlist = 1;
+ s->insn_bits = pcl726_do_insn_bits;
+ s->range_table = &range_digital;
+ }
+
+ return 0;
+}
+
+static int pcl726_detach(struct comedi_device * dev)
+{
+// printk("comedi%d: pcl726: remove\n",dev->minor);
+
+#ifdef ACL6126_IRQ
+ if (dev->irq) {
+ comedi_free_irq(dev->irq, dev);
+ }
+#endif
+
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl730.c b/drivers/staging/comedi/drivers/pcl730.c
new file mode 100644
index 00000000000..f2c6d7c5693
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl730.c
@@ -0,0 +1,168 @@
+/*
+ * comedi/drivers/pcl730.c
+ * Driver for Advantech PCL-730 and clones
+ * José Luis Sánchez
+ */
+/*
+Driver: pcl730
+Description: Advantech PCL-730 (& compatibles)
+Author: José Luis Sánchez (jsanchezv@teleline.es)
+Status: untested
+Devices: [Advantech] PCL-730 (pcl730), [ICP] ISO-730 (iso730),
+ [Adlink] ACL-7130 (acl7130)
+
+Interrupts are not supported.
+The ACL-7130 card have an 8254 timer/counter not supported by this driver.
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCL730_SIZE 4
+#define ACL7130_SIZE 8
+#define PCL730_IDIO_LO 0 /* Isolated Digital I/O low byte (ID0-ID7) */
+#define PCL730_IDIO_HI 1 /* Isolated Digital I/O high byte (ID8-ID15) */
+#define PCL730_DIO_LO 2 /* TTL Digital I/O low byte (D0-D7) */
+#define PCL730_DIO_HI 3 /* TTL Digital I/O high byte (D8-D15) */
+
+static int pcl730_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl730_detach(struct comedi_device * dev);
+
+struct pcl730_board {
+
+ const char *name; // board name
+ unsigned int io_range; // len of I/O space
+};
+
+
+static const struct pcl730_board boardtypes[] = {
+ {"pcl730", PCL730_SIZE,},
+ {"iso730", PCL730_SIZE,},
+ {"acl7130", ACL7130_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl730_board))
+#define this_board ((const struct pcl730_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl730 = {
+ driver_name:"pcl730",
+ module:THIS_MODULE,
+ attach:pcl730_attach,
+ detach:pcl730_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl730_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl730);
+
+static int pcl730_do_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ }
+ if (data[0] & 0x00ff)
+ outb(s->state & 0xff,
+ dev->iobase + ((unsigned long)s->private));
+ if (data[0] & 0xff00)
+ outb((s->state >> 8),
+ dev->iobase + ((unsigned long)s->private) + 1);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcl730_di_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + ((unsigned long)s->private)) |
+ (inb(dev->iobase + ((unsigned long)s->private) + 1) << 8);
+
+ return 2;
+}
+
+static int pcl730_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ unsigned int iorange;
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ printk("comedi%d: pcl730: board=%s 0x%04lx ", dev->minor,
+ this_board->name, iobase);
+ if (!request_region(iobase, iorange, "pcl730")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->board_name = this_board->name;
+ dev->iobase = iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 4) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* Isolated do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_do_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_IDIO_LO;
+
+ s = dev->subdevices + 1;
+ /* Isolated di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_IDIO_LO;
+
+ s = dev->subdevices + 2;
+ /* TTL do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_do_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_DIO_LO;
+
+ s = dev->subdevices + 3;
+ /* TTL di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 16;
+ s->insn_bits = pcl730_di_insn;
+ s->range_table = &range_digital;
+ s->private = (void *)PCL730_DIO_LO;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int pcl730_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcl730: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl812.c b/drivers/staging/comedi/drivers/pcl812.c
new file mode 100644
index 00000000000..11dfd230e56
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl812.c
@@ -0,0 +1,1605 @@
+/*
+ * comedi/drivers/pcl812.c
+ *
+ * Author: Michal Dobes <dobes@tesnet.cz>
+ *
+ * hardware driver for Advantech cards
+ * card: PCL-812, PCL-812PG, PCL-813, PCL-813B
+ * driver: pcl812, pcl812pg, pcl813, pcl813b
+ * and for ADlink cards
+ * card: ACL-8112DG, ACL-8112HG, ACL-8112PG, ACL-8113, ACL-8216
+ * driver: acl8112dg, acl8112hg, acl8112pg, acl8113, acl8216
+ * and for ICP DAS cards
+ * card: ISO-813, A-821PGH, A-821PGL, A-821PGL-NDA, A-822PGH, A-822PGL,
+ * driver: iso813, a821pgh, a-821pgl, a-821pglnda, a822pgh, a822pgl,
+ * card: A-823PGH, A-823PGL, A-826PG
+ * driver: a823pgh, a823pgl, a826pg
+ */
+/*
+Driver: pcl812
+Description: Advantech PCL-812/PG, PCL-813/B,
+ ADLink ACL-8112DG/HG/PG, ACL-8113, ACL-8216,
+ ICP DAS A-821PGH/PGL/PGL-NDA, A-822PGH/PGL, A-823PGH/PGL, A-826PG,
+ ICP DAS ISO-813
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-812 (pcl812), PCL-812PG (pcl812pg),
+ PCL-813 (pcl813), PCL-813B (pcl813b), [ADLink] ACL-8112DG (acl8112dg),
+ ACL-8112HG (acl8112hg), ACL-8113 (acl-8113), ACL-8216 (acl8216),
+ [ICP] ISO-813 (iso813), A-821PGH (a821pgh), A-821PGL (a821pgl),
+ A-821PGL-NDA (a821pclnda), A-822PGH (a822pgh), A-822PGL (a822pgl),
+ A-823PGH (a823pgh), A-823PGL (a823pgl), A-826PG (a826pg)
+Updated: Mon, 06 Aug 2007 12:03:15 +0100
+Status: works (I hope. My board fire up under my hands
+ and I cann't test all features.)
+
+This driver supports insn and cmd interfaces. Some boards support only insn
+becouse their hardware don't allow more (PCL-813/B, ACL-8113, ISO-813).
+Data transfer over DMA is supported only when you measure only one
+channel, this is too hardware limitation of these boards.
+
+Options for PCL-812:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0=trigger source is internal 8253 with 2MHz clock
+ 1=trigger source is external
+ [4] - 0=A/D input range is +/-10V
+ 1=A/D input range is +/-5V
+ 2=A/D input range is +/-2.5V
+ 3=A/D input range is +/-1.25V
+ 4=A/D input range is +/-0.625V
+ 5=A/D input range is +/-0.3125V
+ [5] - 0=D/A outputs 0-5V (internal reference -5V)
+ 1=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+
+Options for PCL-812PG, ACL-8112PG:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0=trigger source is internal 8253 with 2MHz clock
+ 1=trigger source is external
+ [4] - 0=A/D have max +/-5V input
+ 1=A/D have max +/-10V input
+ [5] - 0=D/A outputs 0-5V (internal reference -5V)
+ 1=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+
+Options for ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH, ACL-8216, A-826PG:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7; 10, 11, 12, 14, 15)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0=trigger source is internal 8253 with 2MHz clock
+ 1=trigger source is external
+ [4] - 0=A/D channels are S.E.
+ 1=A/D channels are DIFF
+ [5] - 0=D/A outputs 0-5V (internal reference -5V)
+ 1=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+
+Options for A-821PGL/PGH:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - 0=A/D channels are S.E.
+ 1=A/D channels are DIFF
+ [3] - 0=D/A output 0-5V (internal reference -5V)
+ 1=D/A output 0-10V (internal reference -10V)
+
+Options for A-821PGL-NDA:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - 0=A/D channels are S.E.
+ 1=A/D channels are DIFF
+
+Options for PCL-813:
+ [0] - IO Base
+
+Options for PCL-813B:
+ [0] - IO Base
+ [1] - 0= bipolar inputs
+ 1= unipolar inputs
+
+Options for ACL-8113, ISO-813:
+ [0] - IO Base
+ [1] - 0= 10V bipolar inputs
+ 1= 10V unipolar inputs
+ 2= 20V bipolar inputs
+ 3= 20V unipolar inputs
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+#undef PCL812_EXTDEBUG /* if this is defined then a lot of messages is printed */
+
+// hardware types of the cards
+#define boardPCL812PG 0 /* and ACL-8112PG */
+#define boardPCL813B 1
+#define boardPCL812 2
+#define boardPCL813 3
+#define boardISO813 5
+#define boardACL8113 6
+#define boardACL8112 7 /* ACL-8112DG/HG, A-822PGL/PGH, A-823PGL/PGH */
+#define boardACL8216 8 /* and ICP DAS A-826PG */
+#define boardA821 9 /* PGH, PGL, PGL/NDA versions */
+
+#define PCLx1x_IORANGE 16
+
+#define PCL812_CTR0 0
+#define PCL812_CTR1 1
+#define PCL812_CTR2 2
+#define PCL812_CTRCTL 3
+#define PCL812_AD_LO 4
+#define PCL812_DA1_LO 4
+#define PCL812_AD_HI 5
+#define PCL812_DA1_HI 5
+#define PCL812_DA2_LO 6
+#define PCL812_DI_LO 6
+#define PCL812_DA2_HI 7
+#define PCL812_DI_HI 7
+#define PCL812_CLRINT 8
+#define PCL812_GAIN 9
+#define PCL812_MUX 10
+#define PCL812_MODE 11
+#define PCL812_CNTENABLE 10
+#define PCL812_SOFTTRIG 12
+#define PCL812_DO_LO 13
+#define PCL812_DO_HI 14
+
+#define PCL812_DRDY 0x10 /* =0 data ready */
+
+#define ACL8216_STATUS 8 /* 5. bit signalize data ready */
+
+#define ACL8216_DRDY 0x20 /* =0 data ready */
+
+#define MAX_CHANLIST_LEN 256 /* length of scan list */
+
+static const struct comedi_lrange range_pcl812pg_ai = { 5, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(0.3125),
+ }
+};
+static const struct comedi_lrange range_pcl812pg2_ai = { 5, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range812_bipolar1_25 = { 1, {
+ BIP_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range812_bipolar0_625 = { 1, {
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range812_bipolar0_3125 = { 1, {
+ BIP_RANGE(0.3125),
+ }
+};
+static const struct comedi_lrange range_pcl813b_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_pcl813b2_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_iso813_1_ai = { 5, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ BIP_RANGE(0.3125),
+ }
+};
+static const struct comedi_lrange range_iso813_1_2_ai = { 5, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ UNI_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_iso813_2_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_iso813_2_2_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_acl8113_1_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+static const struct comedi_lrange range_acl8113_1_2_ai = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_acl8113_2_ai = { 3, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ }
+};
+static const struct comedi_lrange range_acl8113_2_2_ai = { 3, {
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ }
+};
+static const struct comedi_lrange range_acl8112dg_ai = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10),
+ }
+};
+static const struct comedi_lrange range_acl8112hg_ai = { 12, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ }
+};
+static const struct comedi_lrange range_a821pgh_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ }
+};
+
+static int pcl812_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl812_detach(struct comedi_device * dev);
+
+struct pcl812_board {
+
+ const char *name; // board name
+ int board_type; // type of this board
+ int n_aichan; // num of AI chans in S.E.
+ int n_aichan_diff; // DIFF num of chans
+ int n_aochan; // num of DA chans
+ int n_dichan; // DI and DO chans
+ int n_dochan;
+ int ai_maxdata; // AI resolution
+ unsigned int ai_ns_min; // max sample speed of card v ns
+ unsigned int i8254_osc_base; // clock base
+ const struct comedi_lrange *rangelist_ai; // rangelist for A/D
+ const struct comedi_lrange *rangelist_ao; // rangelist for D/A
+ unsigned int IRQbits; // allowed IRQ
+ unsigned char DMAbits; // allowed DMA chans
+ unsigned char io_range; // iorange for this board
+ unsigned char haveMPC508; // 1=board use MPC508A multiplexor
+};
+
+
+static const struct pcl812_board boardtypes[] = {
+ {"pcl812", boardPCL812, 16, 0, 2, 16, 16, 0x0fff,
+ 33000, 500, &range_bipolar10, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"pcl812pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
+ 33000, 500, &range_pcl812pg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"acl8112pg", boardPCL812PG, 16, 0, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_pcl812pg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"acl8112dg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+ {"acl8112hg", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+ {"a821pgl", boardA821, 16, 8, 1, 16, 16, 0x0fff,
+ 10000, 500, &range_pcl813b_ai, &range_unipolar5,
+ 0x000c, 0x00, PCLx1x_IORANGE, 0},
+ {"a821pglnda", boardA821, 16, 8, 0, 0, 0, 0x0fff,
+ 10000, 500, &range_pcl813b_ai, NULL,
+ 0x000c, 0x00, PCLx1x_IORANGE, 0},
+ {"a821pgh", boardA821, 16, 8, 1, 16, 16, 0x0fff,
+ 10000, 500, &range_a821pgh_ai, &range_unipolar5,
+ 0x000c, 0x00, PCLx1x_IORANGE, 0},
+ {"a822pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112dg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"a822pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 10000, 500, &range_acl8112hg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"a823pgl", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 8000, 500, &range_acl8112dg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"a823pgh", boardACL8112, 16, 8, 2, 16, 16, 0x0fff,
+ 8000, 500, &range_acl8112hg_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+ {"pcl813", boardPCL813, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_pcl813b_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"pcl813b", boardPCL813B, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_pcl813b_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"acl8113", boardACL8113, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_acl8113_1_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"iso813", boardISO813, 32, 0, 0, 0, 0, 0x0fff,
+ 0, 0, &range_iso813_1_ai, NULL,
+ 0x0000, 0x00, PCLx1x_IORANGE, 0},
+ {"acl8216", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
+ 10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 1},
+ {"a826pg", boardACL8216, 16, 8, 2, 16, 16, 0xffff,
+ 10000, 500, &range_pcl813b2_ai, &range_unipolar5,
+ 0xdcfc, 0x0a, PCLx1x_IORANGE, 0},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl812_board))
+#define this_board ((const struct pcl812_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcl812 = {
+ driver_name:"pcl812",
+ module:THIS_MODULE,
+ attach:pcl812_attach,
+ detach:pcl812_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl812_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl812);
+
+struct pcl812_private {
+
+ unsigned char valid; // =1 device is OK
+ unsigned char dma; // >0 use dma ( usedDMA channel)
+ unsigned char use_diff; // =1 diff inputs
+ unsigned char use_MPC; // 1=board uses MPC508A multiplexor
+ unsigned char use_ext_trg; // 1=board uses external trigger
+ unsigned char range_correction; // =1 we must add 1 to range number
+ unsigned char old_chan_reg; // lastly used chan/gain pair
+ unsigned char old_gain_reg;
+ unsigned char mode_reg_int; // there is stored INT number for some card
+ unsigned char ai_neverending; // =1 we do unlimited AI
+ unsigned char ai_eos; // 1=EOS wake up
+ unsigned char ai_dma; // =1 we use DMA
+ unsigned int ai_poll_ptr; // how many sampes transfer poll
+ unsigned int ai_scans; // len of scanlist
+ unsigned int ai_act_scan; // how many scans we finished
+ unsigned int ai_chanlist[MAX_CHANLIST_LEN]; // our copy of channel/range list
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int ai_flags; // flaglist
+ unsigned int ai_data_len; // len of data buffer
+ short *ai_data; // data buffer
+ unsigned int ai_is16b; // =1 we have 16 bit card
+ unsigned long dmabuf[2]; // PTR to DMA buf
+ unsigned int dmapages[2]; // how many pages we have allocated
+ unsigned int hwdmaptr[2]; // HW PTR to DMA buf
+ unsigned int hwdmasize[2]; // DMA buf size in bytes
+ unsigned int dmabytestomove[2]; // how many bytes DMA transfer
+ int next_dma_buf; // which buffer is next to use
+ unsigned int dma_runs_to_end; // how many times we must switch DMA buffers
+ unsigned int last_dma_run; // how many bytes to transfer on last DMA buffer
+ unsigned int max_812_ai_mode0_rangewait; // setling time for gain
+ unsigned int ao_readback[2]; // data for AO readback
+};
+
+
+#define devpriv ((struct pcl812_private *)dev->private)
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+static void setup_range_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int rangechan, char wait);
+static int pcl812_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+/*
+==============================================================================
+*/
+static int pcl812_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout, hi;
+
+ outb(devpriv->mode_reg_int | 1, dev->iobase + PCL812_MODE); /* select software trigger */
+ setup_range_channel(dev, s, insn->chanspec, 1); // select channel and renge
+ for (n = 0; n < insn->n; n++) {
+ outb(255, dev->iobase + PCL812_SOFTTRIG); /* start conversion */
+ comedi_udelay(5);
+ timeout = 50; /* wait max 50us, it must finish under 33us */
+ while (timeout--) {
+ hi = inb(dev->iobase + PCL812_AD_HI);
+ if (!(hi & PCL812_DRDY))
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ rt_printk
+ ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
+ dev->minor, dev->board_name, dev->iobase);
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+ return -ETIME;
+
+ conv_finish:
+ data[n] = ((hi & 0xf) << 8) | inb(dev->iobase + PCL812_AD_LO);
+ }
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int acl8216_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout;
+
+ outb(1, dev->iobase + PCL812_MODE); /* select software trigger */
+ setup_range_channel(dev, s, insn->chanspec, 1); // select channel and renge
+ for (n = 0; n < insn->n; n++) {
+ outb(255, dev->iobase + PCL812_SOFTTRIG); /* start conversion */
+ comedi_udelay(5);
+ timeout = 50; /* wait max 50us, it must finish under 33us */
+ while (timeout--) {
+ if (!(inb(dev->iobase + ACL8216_STATUS) & ACL8216_DRDY))
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ rt_printk
+ ("comedi%d: pcl812: (%s at 0x%lx) A/D insn read timeout\n",
+ dev->minor, dev->board_name, dev->iobase);
+ outb(0, dev->iobase + PCL812_MODE);
+ return -ETIME;
+
+ conv_finish:
+ data[n] =
+ (inb(dev->iobase +
+ PCL812_AD_HI) << 8) | inb(dev->iobase +
+ PCL812_AD_LO);
+ }
+ outb(0, dev->iobase + PCL812_MODE);
+ return n;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ outb((data[i] & 0xff),
+ dev->iobase + (chan ? PCL812_DA2_LO : PCL812_DA1_LO));
+ outb((data[i] >> 8) & 0x0f,
+ dev->iobase + (chan ? PCL812_DA2_HI : PCL812_DA1_HI));
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ return i;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL812_DI_LO);
+ data[1] |= inb(dev->iobase + PCL812_DI_HI) << 8;
+
+ return 2;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ outb(s->state & 0xff, dev->iobase + PCL812_DO_LO);
+ outb((s->state >> 8), dev->iobase + PCL812_DO_HI);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+#ifdef PCL812_EXTDEBUG
+/*
+==============================================================================
+*/
+static void pcl812_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+ rt_printk("pcl812 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+ cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+ rt_printk("pcl812 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+ cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+ rt_printk("pcl812 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+ cmd->scan_end_src);
+ rt_printk("pcl812 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
+ cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+#endif
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...)\n");
+ pcl812_cmdtest_out(-1, cmd);
+#endif
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ if (devpriv->use_ext_trg) {
+ cmd->convert_src &= TRIG_EXT;
+ } else {
+ cmd->convert_src &= TRIG_TIMER;
+ }
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ pcl812_cmdtest_out(1, cmd);
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=1\n",
+ err);
+#endif
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (devpriv->use_ext_trg) {
+ if (cmd->convert_src != TRIG_EXT) {
+ cmd->convert_src = TRIG_EXT;
+ err++;
+ }
+ } else {
+ if (cmd->convert_src != TRIG_TIMER) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ pcl812_cmdtest_out(2, cmd);
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=2\n",
+ err);
+#endif
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+ } else { /* TRIG_EXT */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > MAX_CHANLIST_LEN) {
+ cmd->chanlist_len = this_board->n_aichan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ pcl812_cmdtest_out(3, cmd);
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=3\n",
+ err);
+#endif
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+#ifdef PCL812_EXTDEBUG
+ rt_printk
+ ("pcl812 EDBG: BGN: pcl812_ai_cmdtest(...) err=%d ret=4\n",
+ err);
+#endif
+ return 4;
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int divisor1 = 0, divisor2 = 0, i, dma_flags, bytes;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_ai_cmd(...)\n");
+#endif
+
+ if (cmd->start_src != TRIG_NOW)
+ return -EINVAL;
+ if (cmd->scan_begin_src != TRIG_FOLLOW)
+ return -EINVAL;
+ if (devpriv->use_ext_trg) {
+ if (cmd->convert_src != TRIG_EXT)
+ return -EINVAL;
+ } else {
+ if (cmd->convert_src != TRIG_TIMER)
+ return -EINVAL;
+ }
+ if (cmd->scan_end_src != TRIG_COUNT)
+ return -EINVAL;
+ if (cmd->scan_end_arg != cmd->chanlist_len)
+ return -EINVAL;
+ if (cmd->chanlist_len > MAX_CHANLIST_LEN)
+ return -EINVAL;
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
+ &divisor1, &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ }
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ memcpy(devpriv->ai_chanlist, cmd->chanlist,
+ sizeof(unsigned int) * cmd->scan_end_arg);
+ setup_range_channel(dev, s, devpriv->ai_chanlist[0], 1); // select first channel and range
+
+ if (devpriv->dma) { // check if we can use DMA transfer
+ devpriv->ai_dma = 1;
+ for (i = 1; i < devpriv->ai_n_chan; i++)
+ if (devpriv->ai_chanlist[0] != devpriv->ai_chanlist[i]) {
+ devpriv->ai_dma = 0; // we cann't use DMA :-(
+ break;
+ }
+ } else
+ devpriv->ai_dma = 0;
+
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_data = s->async->prealloc_buf;
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ devpriv->ai_neverending = 0;
+ } else {
+ devpriv->ai_scans = 0;
+ devpriv->ai_neverending = 1;
+ }
+
+ devpriv->ai_act_scan = 0;
+ devpriv->ai_poll_ptr = 0;
+ s->async->cur_chan = 0;
+
+ if ((devpriv->ai_flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
+ devpriv->ai_eos = 1;
+ if (devpriv->ai_n_chan == 1)
+ devpriv->ai_dma = 0; // DMA is useless for this situation
+ }
+
+ if (devpriv->ai_dma) {
+ if (devpriv->ai_eos) { // we use EOS, so adapt DMA buffer to one scan
+ devpriv->dmabytestomove[0] =
+ devpriv->ai_n_chan * sizeof(short);
+ devpriv->dmabytestomove[1] =
+ devpriv->ai_n_chan * sizeof(short);
+ devpriv->dma_runs_to_end = 1;
+ } else {
+ devpriv->dmabytestomove[0] = devpriv->hwdmasize[0];
+ devpriv->dmabytestomove[1] = devpriv->hwdmasize[1];
+ if (devpriv->ai_data_len < devpriv->hwdmasize[0])
+ devpriv->dmabytestomove[0] =
+ devpriv->ai_data_len;
+ if (devpriv->ai_data_len < devpriv->hwdmasize[1])
+ devpriv->dmabytestomove[1] =
+ devpriv->ai_data_len;
+ if (devpriv->ai_neverending) {
+ devpriv->dma_runs_to_end = 1;
+ } else {
+ bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short); // how many samples we must transfer?
+ devpriv->dma_runs_to_end = bytes / devpriv->dmabytestomove[0]; // how many DMA pages we must fill
+ devpriv->last_dma_run = bytes % devpriv->dmabytestomove[0]; //on last dma transfer must be moved
+ if (devpriv->dma_runs_to_end == 0)
+ devpriv->dmabytestomove[0] =
+ devpriv->last_dma_run;
+ devpriv->dma_runs_to_end--;
+ }
+ }
+ if (devpriv->dmabytestomove[0] > devpriv->hwdmasize[0]) {
+ devpriv->dmabytestomove[0] = devpriv->hwdmasize[0];
+ devpriv->ai_eos = 0;
+ }
+ if (devpriv->dmabytestomove[1] > devpriv->hwdmasize[1]) {
+ devpriv->dmabytestomove[1] = devpriv->hwdmasize[1];
+ devpriv->ai_eos = 0;
+ }
+ devpriv->next_dma_buf = 0;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, devpriv->dmabytestomove[0]);
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+#ifdef PCL812_EXTDEBUG
+ rt_printk
+ ("pcl812 EDBG: DMA %d PTR 0x%0x/0x%0x LEN %u/%u EOS %d\n",
+ devpriv->dma, devpriv->hwdmaptr[0],
+ devpriv->hwdmaptr[1], devpriv->dmabytestomove[0],
+ devpriv->dmabytestomove[1], devpriv->ai_eos);
+#endif
+ }
+
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ start_pacer(dev, 1, divisor1, divisor2);
+ break;
+ }
+
+ if (devpriv->ai_dma) {
+ outb(devpriv->mode_reg_int | 2, dev->iobase + PCL812_MODE); // let's go!
+ } else {
+ outb(devpriv->mode_reg_int | 6, dev->iobase + PCL812_MODE); // let's go!
+ }
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: pcl812_ai_cmd(...)\n");
+#endif
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812_ai_int(int irq, void *d)
+{
+ char err = 1;
+ unsigned int mask, timeout;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+
+ s->async->events = 0;
+
+ timeout = 50; /* wait max 50us, it must finish under 33us */
+ if (devpriv->ai_is16b) {
+ mask = 0xffff;
+ while (timeout--) {
+ if (!(inb(dev->iobase + ACL8216_STATUS) & ACL8216_DRDY)) {
+ err = 0;
+ break;
+ }
+ comedi_udelay(1);
+ }
+ } else {
+ mask = 0x0fff;
+ while (timeout--) {
+ if (!(inb(dev->iobase + PCL812_AD_HI) & PCL812_DRDY)) {
+ err = 0;
+ break;
+ }
+ comedi_udelay(1);
+ }
+ }
+
+ if (err) {
+ rt_printk
+ ("comedi%d: pcl812: (%s at 0x%lx) A/D cmd IRQ without DRDY!\n",
+ dev->minor, dev->board_name, dev->iobase);
+ pcl812_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async,
+ ((inb(dev->iobase + PCL812_AD_HI) << 8) | inb(dev->iobase +
+ PCL812_AD_LO)) & mask);
+
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+
+ if (s->async->cur_chan == 0) { /* one scan done */
+ devpriv->ai_act_scan++;
+ if (!(devpriv->ai_neverending))
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pcl812_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ }
+
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subdevice * s,
+ short * ptr, unsigned int bufptr, unsigned int len)
+{
+ unsigned int i;
+
+ s->async->events = 0;
+ for (i = len; i; i--) {
+ comedi_buf_put(s->async, ptr[bufptr++]); // get one sample
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan++;
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ pcl812_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+ }
+
+ comedi_event(dev, s);
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812_ai_dma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ unsigned long dma_flags;
+ int len, bufptr;
+ short *ptr;
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: interrupt_pcl812_ai_dma(...)\n");
+#endif
+ ptr = (short *) devpriv->dmabuf[devpriv->next_dma_buf];
+ len = (devpriv->dmabytestomove[devpriv->next_dma_buf] >> 1) -
+ devpriv->ai_poll_ptr;
+
+ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+ disable_dma(devpriv->dma);
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[devpriv->next_dma_buf]);
+ if (devpriv->ai_eos) {
+ set_dma_count(devpriv->dma,
+ devpriv->dmabytestomove[devpriv->next_dma_buf]);
+ } else {
+ if (devpriv->dma_runs_to_end) {
+ set_dma_count(devpriv->dma,
+ devpriv->dmabytestomove[devpriv->next_dma_buf]);
+ } else {
+ set_dma_count(devpriv->dma, devpriv->last_dma_run);
+ }
+ devpriv->dma_runs_to_end--;
+ }
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+
+ bufptr = devpriv->ai_poll_ptr;
+ devpriv->ai_poll_ptr = 0;
+
+ transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: interrupt_pcl812_ai_dma(...)\n");
+#endif
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+*/
+static irqreturn_t interrupt_pcl812(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "spurious interrupt");
+ return IRQ_HANDLED;
+ }
+ if (devpriv->ai_dma) {
+ return interrupt_pcl812_ai_dma(irq, d);
+ } else {
+ return interrupt_pcl812_ai_int(irq, d);
+ };
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ unsigned int top1, top2, i;
+
+ if (!devpriv->ai_dma)
+ return 0; // poll is valid only for DMA transfer
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ for (i = 0; i < 10; i++) {
+ top1 = get_dma_residue(devpriv->ai_dma); // where is now DMA
+ top2 = get_dma_residue(devpriv->ai_dma);
+ if (top1 == top2)
+ break;
+ }
+
+ if (top1 != top2) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ top1 = devpriv->dmabytestomove[1 - devpriv->next_dma_buf] - top1; // where is now DMA in buffer
+ top1 >>= 1; // sample position
+ top2 = top1 - devpriv->ai_poll_ptr;
+ if (top2 < 1) { // no new samples
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ transfer_from_dma_buf(dev, s,
+ (void *)devpriv->dmabuf[1 - devpriv->next_dma_buf],
+ devpriv->ai_poll_ptr, top2);
+
+ devpriv->ai_poll_ptr = top1; // new buffer position
+
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+/*
+==============================================================================
+*/
+static void setup_range_channel(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int rangechan, char wait)
+{
+ unsigned char chan_reg = CR_CHAN(rangechan); // normal board
+ unsigned char gain_reg = CR_RANGE(rangechan) + devpriv->range_correction; // gain index
+
+ if ((chan_reg == devpriv->old_chan_reg)
+ && (gain_reg == devpriv->old_gain_reg))
+ return; // we can return, no change
+
+ devpriv->old_chan_reg = chan_reg;
+ devpriv->old_gain_reg = gain_reg;
+
+ if (devpriv->use_MPC) {
+ if (devpriv->use_diff) {
+ chan_reg = chan_reg | 0x30; // DIFF inputs
+ } else {
+ if (chan_reg & 0x80) {
+ chan_reg = chan_reg | 0x20; // SE inputs 8-15
+ } else {
+ chan_reg = chan_reg | 0x10; // SE inputs 0-7
+ }
+ }
+ }
+
+ outb(chan_reg, dev->iobase + PCL812_MUX); /* select channel */
+ outb(gain_reg, dev->iobase + PCL812_GAIN); /* select gain */
+
+ if (wait) {
+ comedi_udelay(devpriv->max_812_ai_mode0_rangewait); // XXX this depends on selected range and can be very long for some high gain ranges!
+ }
+}
+
+/*
+==============================================================================
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: start_pacer(%d,%u,%u)\n", mode, divisor1,
+ divisor2);
+#endif
+ outb(0xb4, dev->iobase + PCL812_CTRCTL);
+ outb(0x74, dev->iobase + PCL812_CTRCTL);
+ comedi_udelay(1);
+
+ if (mode == 1) {
+ outb(divisor2 & 0xff, dev->iobase + PCL812_CTR2);
+ outb((divisor2 >> 8) & 0xff, dev->iobase + PCL812_CTR2);
+ outb(divisor1 & 0xff, dev->iobase + PCL812_CTR1);
+ outb((divisor1 >> 8) & 0xff, dev->iobase + PCL812_CTR1);
+ }
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: start_pacer(...)\n");
+#endif
+}
+
+/*
+==============================================================================
+*/
+static void free_resources(struct comedi_device * dev)
+{
+
+ if (dev->private) {
+ if (devpriv->dmabuf[0])
+ free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+ if (devpriv->dmabuf[1])
+ free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ }
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_ai_cancel(...)\n");
+#endif
+ if (devpriv->ai_dma)
+ disable_dma(devpriv->dma);
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE); /* Stop A/D */
+ start_pacer(dev, -1, 0, 0); // stop 8254
+ outb(0, dev->iobase + PCL812_CLRINT); /* clear INT request */
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: pcl812_ai_cancel(...)\n");
+#endif
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static void pcl812_reset(struct comedi_device * dev)
+{
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: BGN: pcl812_reset(...)\n");
+#endif
+ outb(0, dev->iobase + PCL812_MUX);
+ outb(0 + devpriv->range_correction, dev->iobase + PCL812_GAIN);
+ devpriv->old_chan_reg = -1; // invalidate chain/gain memory
+ devpriv->old_gain_reg = -1;
+
+ switch (this_board->board_type) {
+ case boardPCL812PG:
+ case boardPCL812:
+ case boardACL8112:
+ case boardACL8216:
+ outb(0, dev->iobase + PCL812_DA2_LO);
+ outb(0, dev->iobase + PCL812_DA2_HI);
+ case boardA821:
+ outb(0, dev->iobase + PCL812_DA1_LO);
+ outb(0, dev->iobase + PCL812_DA1_HI);
+ start_pacer(dev, -1, 0, 0); // stop 8254
+ outb(0, dev->iobase + PCL812_DO_HI);
+ outb(0, dev->iobase + PCL812_DO_LO);
+ outb(devpriv->mode_reg_int | 0, dev->iobase + PCL812_MODE);
+ outb(0, dev->iobase + PCL812_CLRINT);
+ break;
+ case boardPCL813B:
+ case boardPCL813:
+ case boardISO813:
+ case boardACL8113:
+ comedi_udelay(5);
+ break;
+ }
+ comedi_udelay(5);
+#ifdef PCL812_EXTDEBUG
+ rt_printk("pcl812 EDBG: END: pcl812_reset(...)\n");
+#endif
+}
+
+/*
+==============================================================================
+*/
+static int pcl812_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret, subdev;
+ unsigned long iobase;
+ unsigned int irq;
+ unsigned int dma;
+ unsigned long pages;
+ struct comedi_subdevice *s;
+ int n_subdevices;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcl812: board=%s, ioport=0x%03lx", dev->minor,
+ this_board->name, iobase);
+
+ if (!request_region(iobase, this_board->io_range, "pcl812")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl812_private))) < 0) {
+ free_resources(dev);
+ return ret; /* Can't alloc mem */
+ }
+
+ dev->board_name = this_board->name;
+
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ printk(", IRQ %u is out of allowed range, DISABLING IT", irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl812, 0,
+ "pcl812", dev)) {
+ printk(", unable to allocate IRQ %u, DISABLING IT", irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+
+ dma = 0;
+ devpriv->dma = dma;
+ if (!dev->irq)
+ goto no_dma; /* if we haven't IRQ, we can't use DMA */
+ if (this_board->DMAbits != 0) { /* board support DMA */
+ dma = it->options[2];
+ if (((1 << dma) & this_board->DMAbits) == 0) {
+ printk(", DMA is out of allowed range, FAIL!\n");
+ return -EINVAL; /* Bad DMA */
+ }
+ ret = request_dma(dma, "pcl812");
+ if (ret) {
+ printk(", unable to allocate DMA %u, FAIL!\n", dma);
+ return -EBUSY; /* DMA isn't free */
+ }
+ devpriv->dma = dma;
+ printk(", dma=%u", dma);
+ pages = 1; /* we want 8KB */
+ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[0]) {
+ printk(", unable to allocate DMA buffer, FAIL!\n");
+ /* maybe experiment with try_to_free_pages() will help .... */
+ free_resources(dev);
+ return -EBUSY; /* no buffer :-( */
+ }
+ devpriv->dmapages[0] = pages;
+ devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+ devpriv->hwdmasize[0] = PAGE_SIZE * (1 << pages);
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1]) {
+ printk(", unable to allocate DMA buffer, FAIL!\n");
+ free_resources(dev);
+ return -EBUSY;
+ }
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] = virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = PAGE_SIZE * (1 << pages);
+ }
+ no_dma:
+
+ n_subdevices = 0;
+ if (this_board->n_aichan > 0)
+ n_subdevices++;
+ if (this_board->n_aochan > 0)
+ n_subdevices++;
+ if (this_board->n_dichan > 0)
+ n_subdevices++;
+ if (this_board->n_dochan > 0)
+ n_subdevices++;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0) {
+ free_resources(dev);
+ return ret;
+ }
+
+ subdev = 0;
+
+ /* analog input */
+ if (this_board->n_aichan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE;
+ switch (this_board->board_type) {
+ case boardA821:
+ if (it->options[2] == 1) {
+ s->n_chan = this_board->n_aichan_diff;
+ s->subdev_flags |= SDF_DIFF;
+ devpriv->use_diff = 1;
+ } else {
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_GROUND;
+ }
+ break;
+ case boardACL8112:
+ case boardACL8216:
+ if (it->options[4] == 1) {
+ s->n_chan = this_board->n_aichan_diff;
+ s->subdev_flags |= SDF_DIFF;
+ devpriv->use_diff = 1;
+ } else {
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_GROUND;
+ }
+ break;
+ default:
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_GROUND;
+ break;
+ }
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = MAX_CHANLIST_LEN;
+ s->range_table = this_board->rangelist_ai;
+ if (this_board->board_type == boardACL8216) {
+ s->insn_read = acl8216_ai_insn_read;
+ } else {
+ s->insn_read = pcl812_ai_insn_read;
+ }
+ devpriv->use_MPC = this_board->haveMPC508;
+ s->cancel = pcl812_ai_cancel;
+ if (dev->irq) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = pcl812_ai_cmdtest;
+ s->do_cmd = pcl812_ai_cmd;
+ s->poll = pcl812_ai_poll;
+ }
+ switch (this_board->board_type) {
+ case boardPCL812PG:
+ if (it->options[4] == 1)
+ s->range_table = &range_pcl812pg2_ai;
+ break;
+ case boardPCL812:
+ switch (it->options[4]) {
+ case 0:
+ s->range_table = &range_bipolar10;
+ break;
+ case 1:
+ s->range_table = &range_bipolar5;
+ break;
+ case 2:
+ s->range_table = &range_bipolar2_5;
+ break;
+ case 3:
+ s->range_table = &range812_bipolar1_25;
+ break;
+ case 4:
+ s->range_table = &range812_bipolar0_625;
+ break;
+ case 5:
+ s->range_table = &range812_bipolar0_3125;
+ break;
+ default:
+ s->range_table = &range_bipolar10;
+ break;
+ printk(", incorrect range number %d, changing to 0 (+/-10V)", it->options[4]);
+ break;
+ }
+ break;
+ break;
+ case boardPCL813B:
+ if (it->options[1] == 1)
+ s->range_table = &range_pcl813b2_ai;
+ break;
+ case boardISO813:
+ switch (it->options[1]) {
+ case 0:
+ s->range_table = &range_iso813_1_ai;
+ break;
+ case 1:
+ s->range_table = &range_iso813_1_2_ai;
+ break;
+ case 2:
+ s->range_table = &range_iso813_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ case 3:
+ s->range_table = &range_iso813_2_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ default:
+ s->range_table = &range_iso813_1_ai;
+ break;
+ printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+ break;
+ }
+ break;
+ case boardACL8113:
+ switch (it->options[1]) {
+ case 0:
+ s->range_table = &range_acl8113_1_ai;
+ break;
+ case 1:
+ s->range_table = &range_acl8113_1_2_ai;
+ break;
+ case 2:
+ s->range_table = &range_acl8113_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ case 3:
+ s->range_table = &range_acl8113_2_2_ai;
+ devpriv->range_correction = 1;
+ break;
+ default:
+ s->range_table = &range_acl8113_1_ai;
+ break;
+ printk(", incorrect range number %d, changing to 0 ", it->options[1]);
+ break;
+ }
+ break;
+ }
+ subdev++;
+ }
+
+ /* analog output */
+ if (this_board->n_aochan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = 0xfff;
+ s->len_chanlist = 1;
+ s->range_table = this_board->rangelist_ao;
+ s->insn_read = pcl812_ao_insn_read;
+ s->insn_write = pcl812_ao_insn_write;
+ switch (this_board->board_type) {
+ case boardA821:
+ if (it->options[3] == 1)
+ s->range_table = &range_unipolar10;
+ break;
+ case boardPCL812:
+ case boardACL8112:
+ case boardPCL812PG:
+ case boardACL8216:
+ if (it->options[5] == 1)
+ s->range_table = &range_unipolar10;
+ if (it->options[5] == 2)
+ s->range_table = &range_unknown;
+ break;
+ }
+ subdev++;
+ }
+
+ /* digital input */
+ if (this_board->n_dichan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl812_di_insn_bits;
+ subdev++;
+ }
+
+ /* digital output */
+ if (this_board->n_dochan > 0) {
+ s = dev->subdevices + subdev;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl812_do_insn_bits;
+ subdev++;
+ }
+
+ switch (this_board->board_type) {
+ case boardACL8216:
+ devpriv->ai_is16b = 1;
+ case boardPCL812PG:
+ case boardPCL812:
+ case boardACL8112:
+ devpriv->max_812_ai_mode0_rangewait = 1;
+ if (it->options[3] > 0)
+ devpriv->use_ext_trg = 1; // we use external trigger
+ case boardA821:
+ devpriv->max_812_ai_mode0_rangewait = 1;
+ devpriv->mode_reg_int = (irq << 4) & 0xf0;
+ break;
+ case boardPCL813B:
+ case boardPCL813:
+ case boardISO813:
+ case boardACL8113:
+ devpriv->max_812_ai_mode0_rangewait = 5; /* maybe there must by greatest timeout */
+ break;
+ }
+
+ printk("\n");
+ devpriv->valid = 1;
+
+ pcl812_reset(dev);
+
+ return 0;
+}
+
+/*
+==============================================================================
+ */
+static int pcl812_detach(struct comedi_device * dev)
+{
+
+#ifdef PCL812_EXTDEBUG
+ rt_printk("comedi%d: pcl812: remove\n", dev->minor);
+#endif
+ free_resources(dev);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl816.c b/drivers/staging/comedi/drivers/pcl816.c
new file mode 100644
index 00000000000..515ba74cc7f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl816.c
@@ -0,0 +1,1251 @@
+/*
+ comedi/drivers/pcl816.c
+
+ Author: Juan Grigera <juan@grigera.com.ar>
+ based on pcl818 by Michal Dobes <dobes@tesnet.cz> and bits of pcl812
+
+ hardware driver for Advantech cards:
+ card: PCL-816, PCL814B
+ driver: pcl816
+*/
+/*
+Driver: pcl816
+Description: Advantech PCL-816 cards, PCL-814
+Author: Juan Grigera <juan@grigera.com.ar>
+Devices: [Advantech] PCL-816 (pcl816), PCL-814B (pcl814b)
+Status: works
+Updated: Tue, 2 Apr 2002 23:15:21 -0800
+
+PCL 816 and 814B have 16 SE/DIFF ADCs, 16 DACs, 16 DI and 16 DO.
+Differences are at resolution (16 vs 12 bits).
+
+The driver support AI command mode, other subdevices not written.
+
+Analog output and digital input and output are not supported.
+
+Configuration Options:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+#define DEBUG(x) x
+
+// boards constants
+// IO space len
+#define PCLx1x_RANGE 16
+
+//#define outb(x,y) printk("OUTB(%x, 200+%d)\n", x,y-0x200); outb(x,y)
+
+// INTEL 8254 counters
+#define PCL816_CTR0 4
+#define PCL816_CTR1 5
+#define PCL816_CTR2 6
+// R: counter read-back register W: counter control
+#define PCL816_CTRCTL 7
+
+// R: A/D high byte W: A/D range control
+#define PCL816_RANGE 9
+// W: clear INT request
+#define PCL816_CLRINT 10
+// R: next mux scan channel W: mux scan channel & range control pointer
+#define PCL816_MUX 11
+// R/W: operation control register
+#define PCL816_CONTROL 12
+
+// R: return status byte W: set DMA/IRQ
+#define PCL816_STATUS 13
+#define PCL816_STATUS_DRDY_MASK 0x80
+
+// R: low byte of A/D W: soft A/D trigger
+#define PCL816_AD_LO 8
+// R: high byte of A/D W: A/D range control
+#define PCL816_AD_HI 9
+
+// type of interrupt handler
+#define INT_TYPE_AI1_INT 1
+#define INT_TYPE_AI1_DMA 2
+#define INT_TYPE_AI3_INT 4
+#define INT_TYPE_AI3_DMA 5
+#ifdef unused
+#define INT_TYPE_AI1_DMA_RTC 9
+#define INT_TYPE_AI3_DMA_RTC 10
+
+// RTC stuff...
+#define RTC_IRQ 8
+#define RTC_IO_EXTENT 0x10
+#endif
+
+#define MAGIC_DMA_WORD 0x5a5a
+
+static const struct comedi_lrange range_pcl816 = { 8, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ }
+};
+struct pcl816_board {
+
+ const char *name; // board name
+ int n_ranges; // len of range list
+ int n_aichan; // num of A/D chans in diferencial mode
+ unsigned int ai_ns_min; // minimal alllowed delay between samples (in ns)
+ int n_aochan; // num of D/A chans
+ int n_dichan; // num of DI chans
+ int n_dochan; // num of DO chans
+ const struct comedi_lrange *ai_range_type; // default A/D rangelist
+ const struct comedi_lrange *ao_range_type; // dafault D/A rangelist
+ unsigned int io_range; // len of IO space
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int DMAbits; // allowed DMA chans
+ int ai_maxdata; // maxdata for A/D
+ int ao_maxdata; // maxdata for D/A
+ int ai_chanlist; // allowed len of channel list A/D
+ int ao_chanlist; // allowed len of channel list D/A
+ int i8254_osc_base; // 1/frequency of on board oscilator in ns
+};
+
+
+static const struct pcl816_board boardtypes[] = {
+ {"pcl816", 8, 16, 10000, 1, 16, 16, &range_pcl816,
+ &range_pcl816, PCLx1x_RANGE,
+ 0x00fc, // IRQ mask
+ 0x0a, // DMA mask
+ 0xffff, // 16-bit card
+ 0xffff, // D/A maxdata
+ 1024,
+ 1, // ao chan list
+ 100},
+ {"pcl814b", 8, 16, 10000, 1, 16, 16, &range_pcl816,
+ &range_pcl816, PCLx1x_RANGE,
+ 0x00fc,
+ 0x0a,
+ 0x3fff, /* 14 bit card */
+ 0x3fff,
+ 1024,
+ 1,
+ 100},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl816_board))
+#define devpriv ((struct pcl816_private *)dev->private)
+#define this_board ((const struct pcl816_board *)dev->board_ptr)
+
+static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl816_detach(struct comedi_device * dev);
+
+#ifdef unused
+static int RTC_lock = 0; /* RTC lock */
+static int RTC_timer_lock = 0; /* RTC int lock */
+#endif
+
+static struct comedi_driver driver_pcl816 = {
+ driver_name:"pcl816",
+ module:THIS_MODULE,
+ attach:pcl816_attach,
+ detach:pcl816_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl816_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl816);
+
+struct pcl816_private {
+
+ unsigned int dma; // used DMA, 0=don't use DMA
+ int dma_rtc; // 1=RTC used with DMA, 0=no RTC alloc
+#ifdef unused
+ unsigned long rtc_iobase; // RTC port region
+ unsigned int rtc_iosize;
+ unsigned int rtc_irq;
+#endif
+ unsigned long dmabuf[2]; // pointers to begin of DMA buffers
+ unsigned int dmapages[2]; // len of DMA buffers in PAGE_SIZEs
+ unsigned int hwdmaptr[2]; // hardware address of DMA buffers
+ unsigned int hwdmasize[2]; // len of DMA buffers in Bytes
+ unsigned int dmasamplsize; // size in samples hwdmasize[0]/2
+ unsigned int last_top_dma; // DMA pointer in last RTC int
+ int next_dma_buf; // which DMA buffer will be used next round
+ long dma_runs_to_end; // how many we must permorm DMA transfer to end of record
+ unsigned long last_dma_run; // how many bytes we must transfer on last DMA page
+
+ unsigned int ai_scans; // len of scanlist
+ unsigned char ai_neverending; // if=1, then we do neverending record (you must use cancel())
+ int irq_free; // 1=have allocated IRQ
+ int irq_blocked; // 1=IRQ now uses any subdev
+#ifdef unused
+ int rtc_irq_blocked; // 1=we now do AI with DMA&RTC
+#endif
+ int irq_was_now_closed; // when IRQ finish, there's stored int816_mode for last interrupt
+ int int816_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+ struct comedi_subdevice *last_int_sub; // ptr to subdevice which now finish
+ int ai_act_scan; // how many scans we finished
+ unsigned int ai_act_chanlist[16]; // MUX setting for actual AI operations
+ unsigned int ai_act_chanlist_len; // how long is actual MUX list
+ unsigned int ai_act_chanlist_pos; // actual position in MUX list
+ unsigned int ai_poll_ptr; // how many sampes transfer poll
+ struct comedi_subdevice *sub_ai; // ptr to AI subdevice
+#ifdef unused
+ struct timer_list rtc_irq_timer; // timer for RTC sanity check
+ unsigned long rtc_freq; // RTC int freq
+#endif
+};
+
+
+/*
+==============================================================================
+*/
+static int check_and_setup_channel_list(struct comedi_device * dev,
+ struct comedi_subdevice * s, unsigned int *chanlist, int chanlen);
+static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+#ifdef unused
+static int set_rtc_irq_bit(unsigned char bit);
+#endif
+
+static int pcl816_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+
+/*
+==============================================================================
+ ANALOG INPUT MODE0, 816 cards, slow version
+*/
+static int pcl816_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout;
+
+ DPRINTK("mode 0 analog input\n");
+ // software trigger, DMA and INT off
+ outb(0, dev->iobase + PCL816_CONTROL);
+ // clear INT (conversion end) flag
+ outb(0, dev->iobase + PCL816_CLRINT);
+
+ // Set the input channel
+ outb(CR_CHAN(insn->chanspec) & 0xf, dev->iobase + PCL816_MUX);
+ outb(CR_RANGE(insn->chanspec), dev->iobase + PCL816_RANGE); /* select gain */
+
+ for (n = 0; n < insn->n; n++) {
+
+ outb(0, dev->iobase + PCL816_AD_LO); /* start conversion */
+
+ timeout = 100;
+ while (timeout--) {
+ if (!(inb(dev->iobase + PCL816_STATUS) &
+ PCL816_STATUS_DRDY_MASK)) {
+ // return read value
+ data[n] =
+ ((inb(dev->iobase +
+ PCL816_AD_HI) << 8) |
+ (inb(dev->iobase + PCL816_AD_LO)));
+
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT (conversion end) flag */
+ break;
+ }
+ comedi_udelay(1);
+ }
+ // Return timeout error
+ if (!timeout) {
+ comedi_error(dev, "A/D insn timeout\n");
+ data[0] = 0;
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT (conversion end) flag */
+ return -EIO;
+ }
+
+ }
+ return n;
+}
+
+/*
+==============================================================================
+ analog input interrupt mode 1 & 3, 818 cards
+ one sample per interrupt version
+*/
+static irqreturn_t interrupt_pcl816_ai_mode13_int(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int low, hi;
+ int timeout = 50; /* wait max 50us */
+
+ while (timeout--) {
+ if (!(inb(dev->iobase + PCL816_STATUS) &
+ PCL816_STATUS_DRDY_MASK))
+ break;
+ comedi_udelay(1);
+ }
+ if (!timeout) { // timeout, bail error
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+ comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+ pcl816_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+
+ }
+
+ // get the sample
+ low = inb(dev->iobase + PCL816_AD_LO);
+ hi = inb(dev->iobase + PCL816_AD_HI);
+
+ comedi_buf_put(s->async, (hi << 8) | low);
+
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+
+ if (++devpriv->ai_act_chanlist_pos >= devpriv->ai_act_chanlist_len)
+ devpriv->ai_act_chanlist_pos = 0;
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan++;
+ }
+
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { /* all data sampled */
+ /* all data sampled */
+ pcl816_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ analog input dma mode 1 & 3, 816 cards
+*/
+static void transfer_from_dma_buf(struct comedi_device * dev, struct comedi_subdevice * s,
+ short * ptr, unsigned int bufptr, unsigned int len)
+{
+ int i;
+
+ s->async->events = 0;
+
+ for (i = 0; i < len; i++) {
+
+ comedi_buf_put(s->async, ptr[bufptr++]);
+
+ if (++devpriv->ai_act_chanlist_pos >=
+ devpriv->ai_act_chanlist_len) {
+ devpriv->ai_act_chanlist_pos = 0;
+ devpriv->ai_act_scan++;
+ }
+
+ if (!devpriv->ai_neverending)
+ if (devpriv->ai_act_scan >= devpriv->ai_scans) { // all data sampled
+ pcl816_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ s->async->events |= COMEDI_CB_BLOCK;
+ break;
+ }
+ }
+
+ comedi_event(dev, s);
+}
+
+static irqreturn_t interrupt_pcl816_ai_mode13_dma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int len, bufptr, this_dma_buf;
+ unsigned long dma_flags;
+ short *ptr;
+
+ disable_dma(devpriv->dma);
+ this_dma_buf = devpriv->next_dma_buf;
+
+ if ((devpriv->dma_runs_to_end > -1) || devpriv->ai_neverending) { // switch dma bufs
+
+ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+// clear_dma_ff (devpriv->dma);
+ set_dma_addr(devpriv->dma,
+ devpriv->hwdmaptr[devpriv->next_dma_buf]);
+ if (devpriv->dma_runs_to_end) {
+ set_dma_count(devpriv->dma,
+ devpriv->hwdmasize[devpriv->next_dma_buf]);
+ } else {
+ set_dma_count(devpriv->dma, devpriv->last_dma_run);
+ }
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+ }
+
+ devpriv->dma_runs_to_end--;
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+
+ ptr = (short *) devpriv->dmabuf[this_dma_buf];
+
+ len = (devpriv->hwdmasize[0] >> 1) - devpriv->ai_poll_ptr;
+ bufptr = devpriv->ai_poll_ptr;
+ devpriv->ai_poll_ptr = 0;
+
+ transfer_from_dma_buf(dev, s, ptr, bufptr, len);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ INT procedure
+*/
+static irqreturn_t interrupt_pcl816(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+ DPRINTK("<I>");
+
+ if (!dev->attached) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+
+ switch (devpriv->int816_mode) {
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ return interrupt_pcl816_ai_mode13_dma(irq, d);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ return interrupt_pcl816_ai_mode13_int(irq, d);
+ }
+
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+ if ((!dev->irq) | (!devpriv->irq_free) | (!devpriv->irq_blocked) |
+ (!devpriv->int816_mode)) {
+ if (devpriv->irq_was_now_closed) {
+ devpriv->irq_was_now_closed = 0;
+ // comedi_error(dev,"last IRQ..");
+ return IRQ_HANDLED;
+ }
+ comedi_error(dev, "bad IRQ!");
+ return IRQ_NONE;
+ }
+ comedi_error(dev, "IRQ from unknow source!");
+ return IRQ_NONE;
+}
+
+/*
+==============================================================================
+ COMMAND MODE
+*/
+static void pcl816_cmdtest_out(int e, struct comedi_cmd * cmd)
+{
+ rt_printk("pcl816 e=%d startsrc=%x scansrc=%x convsrc=%x\n", e,
+ cmd->start_src, cmd->scan_begin_src, cmd->convert_src);
+ rt_printk("pcl816 e=%d startarg=%d scanarg=%d convarg=%d\n", e,
+ cmd->start_arg, cmd->scan_begin_arg, cmd->convert_arg);
+ rt_printk("pcl816 e=%d stopsrc=%x scanend=%x\n", e, cmd->stop_src,
+ cmd->scan_end_src);
+ rt_printk("pcl816 e=%d stoparg=%d scanendarg=%d chanlistlen=%d\n", e,
+ cmd->stop_arg, cmd->scan_end_arg, cmd->chanlist_len);
+}
+
+/*
+==============================================================================
+*/
+static int pcl816_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ DEBUG(rt_printk("pcl816 pcl812_ai_cmdtest\n");
+ pcl816_cmdtest_out(-1, cmd););
+
+ /* step 1: make sure trigger sources are trivially valid */
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ if (!cmd->convert_src & (TRIG_EXT | TRIG_TIMER))
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+
+ if (cmd->convert_src != TRIG_EXT && cmd->convert_src != TRIG_TIMER) {
+ cmd->convert_src = TRIG_TIMER;
+ err++;
+ }
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min) {
+ cmd->convert_arg = this_board->ai_ns_min;
+ err++;
+ }
+ } else { /* TRIG_EXT */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > this_board->n_aichan) {
+ cmd->chanlist_len = this_board->n_aichan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base,
+ &divisor1, &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+ return 4;
+ }
+
+ return 0;
+}
+
+static int pcl816_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned int divisor1 = 0, divisor2 = 0, dma_flags, bytes, dmairq;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if (cmd->start_src != TRIG_NOW)
+ return -EINVAL;
+ if (cmd->scan_begin_src != TRIG_FOLLOW)
+ return -EINVAL;
+ if (cmd->scan_end_src != TRIG_COUNT)
+ return -EINVAL;
+ if (cmd->scan_end_arg != cmd->chanlist_len)
+ return -EINVAL;
+// if(cmd->chanlist_len>MAX_CHANLIST_LEN) return -EINVAL;
+ if (devpriv->irq_blocked)
+ return -EBUSY;
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ai_ns_min)
+ cmd->convert_arg = this_board->ai_ns_min;
+
+ i8253_cascade_ns_to_timer(this_board->i8254_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (divisor1 == 1) { // PCL816 crash if any divisor is set to 1
+ divisor1 = 2;
+ divisor2 /= 2;
+ }
+ if (divisor2 == 1) {
+ divisor2 = 2;
+ divisor1 /= 2;
+ }
+ }
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ if (!check_and_setup_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return -EINVAL;
+ comedi_udelay(1);
+
+ devpriv->ai_act_scan = 0;
+ s->async->cur_chan = 0;
+ devpriv->irq_blocked = 1;
+ devpriv->ai_poll_ptr = 0;
+ devpriv->irq_was_now_closed = 0;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ devpriv->ai_neverending = 0;
+ } else {
+ devpriv->ai_scans = 0;
+ devpriv->ai_neverending = 1;
+ }
+
+ if ((cmd->flags & TRIG_WAKE_EOS)) { // don't we want wake up every scan?
+ printk("pl816: You wankt WAKE_EOS but I dont want handle it");
+ // devpriv->ai_eos=1;
+ //if (devpriv->ai_n_chan==1)
+ // devpriv->dma=0; // DMA is useless for this situation
+ }
+
+ if (devpriv->dma) {
+ bytes = devpriv->hwdmasize[0];
+ if (!devpriv->ai_neverending) {
+ bytes = s->async->cmd.chanlist_len * s->async->cmd.chanlist_len * sizeof(short); // how many
+ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fill
+ devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved
+ devpriv->dma_runs_to_end--;
+ if (devpriv->dma_runs_to_end >= 0)
+ bytes = devpriv->hwdmasize[0];
+ } else
+ devpriv->dma_runs_to_end = -1;
+
+ devpriv->next_dma_buf = 0;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ dma_flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, bytes);
+ release_dma_lock(dma_flags);
+ enable_dma(devpriv->dma);
+ }
+
+ start_pacer(dev, 1, divisor1, divisor2);
+ dmairq = ((devpriv->dma & 0x3) << 4) | (dev->irq & 0x7);
+
+ switch (cmd->convert_src) {
+ case TRIG_TIMER:
+ devpriv->int816_mode = INT_TYPE_AI1_DMA;
+ outb(0x32, dev->iobase + PCL816_CONTROL); // Pacer+IRQ+DMA
+ outb(dmairq, dev->iobase + PCL816_STATUS); // write irq and DMA to card
+ break;
+
+ default:
+ devpriv->int816_mode = INT_TYPE_AI3_DMA;
+ outb(0x34, dev->iobase + PCL816_CONTROL); // Ext trig+IRQ+DMA
+ outb(dmairq, dev->iobase + PCL816_STATUS); // write irq to card
+ break;
+ }
+
+ DPRINTK("pcl816 END: pcl812_ai_cmd()\n");
+ return 0;
+}
+
+static int pcl816_ai_poll(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+ unsigned int top1, top2, i;
+
+ if (!devpriv->dma)
+ return 0; // poll is valid only for DMA transfer
+
+ comedi_spin_lock_irqsave(&dev->spinlock, flags);
+
+ for (i = 0; i < 20; i++) {
+ top1 = get_dma_residue(devpriv->dma); // where is now DMA
+ top2 = get_dma_residue(devpriv->dma);
+ if (top1 == top2)
+ break;
+ }
+ if (top1 != top2) {
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ top1 = devpriv->hwdmasize[0] - top1; // where is now DMA in buffer
+ top1 >>= 1; // sample position
+ top2 = top1 - devpriv->ai_poll_ptr;
+ if (top2 < 1) { // no new samples
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+ return 0;
+ }
+
+ transfer_from_dma_buf(dev, s,
+ (short *) devpriv->dmabuf[devpriv->next_dma_buf],
+ devpriv->ai_poll_ptr, top2);
+
+ devpriv->ai_poll_ptr = top1; // new buffer position
+ comedi_spin_unlock_irqrestore(&dev->spinlock, flags);
+
+ return s->async->buf_write_count - s->async->buf_read_count;
+}
+
+/*
+==============================================================================
+ cancel any mode 1-4 AI
+*/
+static int pcl816_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+// DEBUG(rt_printk("pcl816_ai_cancel()\n");)
+
+ if (devpriv->irq_blocked > 0) {
+ switch (devpriv->int816_mode) {
+#ifdef unused
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ set_rtc_irq_bit(0); // stop RTC
+ del_timer(&devpriv->rtc_irq_timer);
+#endif
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ disable_dma(devpriv->dma);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ outb(inb(dev->iobase + PCL816_CONTROL) & 0x73, dev->iobase + PCL816_CONTROL); /* Stop A/D */
+ comedi_udelay(1);
+ outb(0, dev->iobase + PCL816_CONTROL); /* Stop A/D */
+ outb(0xb0, dev->iobase + PCL816_CTRCTL); /* Stop pacer */
+ outb(0x70, dev->iobase + PCL816_CTRCTL);
+ outb(0, dev->iobase + PCL816_AD_LO);
+ inb(dev->iobase + PCL816_AD_LO);
+ inb(dev->iobase + PCL816_AD_HI);
+ outb(0, dev->iobase + PCL816_CLRINT); /* clear INT request */
+ outb(0, dev->iobase + PCL816_CONTROL); /* Stop A/D */
+ devpriv->irq_blocked = 0;
+ devpriv->irq_was_now_closed = devpriv->int816_mode;
+ devpriv->int816_mode = 0;
+ devpriv->last_int_sub = s;
+// s->busy = 0;
+ break;
+ }
+ }
+
+ DEBUG(rt_printk("comedi: pcl816_ai_cancel() successful\n");
+ )
+ return 0;
+}
+
+/*
+==============================================================================
+ chech for PCL816
+*/
+static int pcl816_check(unsigned long iobase)
+{
+ outb(0x00, iobase + PCL816_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL816_MUX) != 0x00)
+ return 1; //there isn't card
+ outb(0x55, iobase + PCL816_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL816_MUX) != 0x55)
+ return 1; //there isn't card
+ outb(0x00, iobase + PCL816_MUX);
+ comedi_udelay(1);
+ outb(0x18, iobase + PCL816_CONTROL);
+ comedi_udelay(1);
+ if (inb(iobase + PCL816_CONTROL) != 0x18)
+ return 1; //there isn't card
+ return 0; // ok, card exist
+}
+
+/*
+==============================================================================
+ reset whole PCL-816 cards
+*/
+static void pcl816_reset(struct comedi_device * dev)
+{
+// outb (0, dev->iobase + PCL818_DA_LO); // DAC=0V
+// outb (0, dev->iobase + PCL818_DA_HI);
+// comedi_udelay (1);
+// outb (0, dev->iobase + PCL818_DO_HI); // DO=$0000
+// outb (0, dev->iobase + PCL818_DO_LO);
+// comedi_udelay (1);
+ outb(0, dev->iobase + PCL816_CONTROL);
+ outb(0, dev->iobase + PCL816_MUX);
+ outb(0, dev->iobase + PCL816_CLRINT);
+ outb(0xb0, dev->iobase + PCL816_CTRCTL); /* Stop pacer */
+ outb(0x70, dev->iobase + PCL816_CTRCTL);
+ outb(0x30, dev->iobase + PCL816_CTRCTL);
+ outb(0, dev->iobase + PCL816_RANGE);
+}
+
+/*
+==============================================================================
+ Start/stop pacer onboard pacer
+*/
+static void
+start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ outb(0x32, dev->iobase + PCL816_CTRCTL);
+ outb(0xff, dev->iobase + PCL816_CTR0);
+ outb(0x00, dev->iobase + PCL816_CTR0);
+ comedi_udelay(1);
+ outb(0xb4, dev->iobase + PCL816_CTRCTL); // set counter 2 as mode 3
+ outb(0x74, dev->iobase + PCL816_CTRCTL); // set counter 1 as mode 3
+ comedi_udelay(1);
+
+ if (mode == 1) {
+ DPRINTK("mode %d, divisor1 %d, divisor2 %d\n", mode, divisor1,
+ divisor2);
+ outb(divisor2 & 0xff, dev->iobase + PCL816_CTR2);
+ outb((divisor2 >> 8) & 0xff, dev->iobase + PCL816_CTR2);
+ outb(divisor1 & 0xff, dev->iobase + PCL816_CTR1);
+ outb((divisor1 >> 8) & 0xff, dev->iobase + PCL816_CTR1);
+ }
+
+ /* clear pending interrupts (just in case) */
+// outb(0, dev->iobase + PCL816_CLRINT);
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic
+*/
+static int
+check_and_setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, int chanlen)
+{
+ unsigned int chansegment[16];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ // correct channel and range number check itself comedi/range.c
+ if (chanlen < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+
+ if (chanlen > 1) {
+ chansegment[0] = chanlist[0]; // first channel is everytime ok
+ for (i = 1, seglen = 1; i < chanlen; i++, seglen++) {
+ // build part of chanlist
+ DEBUG(rt_printk("%d. %d %d\n", i, CR_CHAN(chanlist[i]),
+ CR_RANGE(chanlist[i]));
+ )
+ if (chanlist[0] == chanlist[i])
+ break; // we detect loop, this must by finish
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % chanlen;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) {
+ // channel list isn't continous :-(
+ rt_printk
+ ("comedi%d: pcl816: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+ dev->minor, i, CR_CHAN(chanlist[i]),
+ nowmustbechan, CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ chansegment[i] = chanlist[i]; // well, this is next correct channel in list
+ }
+
+ for (i = 0, segpos = 0; i < chanlen; i++) { // check whole chanlist
+ DEBUG(rt_printk("%d %d=%d %d\n",
+ CR_CHAN(chansegment[i % seglen]),
+ CR_RANGE(chansegment[i % seglen]),
+ CR_CHAN(chanlist[i]),
+ CR_RANGE(chanlist[i]));
+ )
+ if (chanlist[i] != chansegment[i % seglen]) {
+ rt_printk
+ ("comedi%d: pcl816: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ dev->minor, i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; // chan/gain list is strange
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+
+ devpriv->ai_act_chanlist_len = seglen;
+ devpriv->ai_act_chanlist_pos = 0;
+
+ for (i = 0; i < seglen; i++) { // store range list to card
+ devpriv->ai_act_chanlist[i] = CR_CHAN(chanlist[i]);
+ outb(CR_CHAN(chanlist[0]) & 0xf, dev->iobase + PCL816_MUX);
+ outb(CR_RANGE(chanlist[0]), dev->iobase + PCL816_RANGE); /* select gain */
+ }
+
+ comedi_udelay(1);
+
+ outb(devpriv->ai_act_chanlist[0] | (devpriv->ai_act_chanlist[seglen - 1] << 4), dev->iobase + PCL816_MUX); /* select channel interval to scan */
+
+ return 1; // we can serve this with MUX logic
+}
+
+#ifdef unused
+/*
+==============================================================================
+ Enable(1)/disable(0) periodic interrupts from RTC
+*/
+static int set_rtc_irq_bit(unsigned char bit)
+{
+ unsigned char val;
+ unsigned long flags;
+
+ if (bit == 1) {
+ RTC_timer_lock++;
+ if (RTC_timer_lock > 1)
+ return 0;
+ } else {
+ RTC_timer_lock--;
+ if (RTC_timer_lock < 0)
+ RTC_timer_lock = 0;
+ if (RTC_timer_lock > 0)
+ return 0;
+ }
+
+ save_flags(flags);
+ cli();
+ val = CMOS_READ(RTC_CONTROL);
+ if (bit) {
+ val |= RTC_PIE;
+ } else {
+ val &= ~RTC_PIE;
+ }
+ CMOS_WRITE(val, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+ restore_flags(flags);
+ return 0;
+}
+#endif
+
+/*
+==============================================================================
+ Free any resources that we have claimed
+*/
+static void free_resources(struct comedi_device * dev)
+{
+ //rt_printk("free_resource()\n");
+ if (dev->private) {
+ pcl816_ai_cancel(dev, devpriv->sub_ai);
+ pcl816_reset(dev);
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ if (devpriv->dmabuf[0])
+ free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+ if (devpriv->dmabuf[1])
+ free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+#ifdef unused
+ if (devpriv->rtc_irq)
+ comedi_free_irq(devpriv->rtc_irq, dev);
+ if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+#endif
+ }
+
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->io_range);
+ //rt_printk("free_resource() end\n");
+}
+
+/*
+==============================================================================
+
+ Initialization
+
+*/
+static int pcl816_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ unsigned int irq, dma;
+ unsigned long pages;
+ //int i;
+ struct comedi_subdevice *s;
+
+ /* claim our I/O space */
+ iobase = it->options[0];
+ printk("comedi%d: pcl816: board=%s, ioport=0x%03lx", dev->minor,
+ this_board->name, iobase);
+
+ if (!request_region(iobase, this_board->io_range, "pcl816")) {
+ rt_printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ if (pcl816_check(iobase)) {
+ rt_printk(", I cann't detect board. FAIL!\n");
+ return -EIO;
+ }
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl816_private))) < 0)
+ return ret; /* Can't alloc mem */
+
+ /* set up some name stuff */
+ dev->board_name = this_board->name;
+
+ /* grab our IRQ */
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ rt_printk
+ (", IRQ %u is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl816, 0,
+ "pcl816", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+ if (irq) {
+ devpriv->irq_free = 1;
+ } /* 1=we have allocated irq */
+ else {
+ devpriv->irq_free = 0;
+ }
+ devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */
+ devpriv->int816_mode = 0; /* mode of irq */
+
+#ifdef unused
+ /* grab RTC for DMA operations */
+ devpriv->dma_rtc = 0;
+ if (it->options[2] > 0) { // we want to use DMA
+ if (RTC_lock == 0) {
+ if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
+ "pcl816 (RTC)"))
+ goto no_rtc;
+ }
+ devpriv->rtc_iobase = RTC_PORT(0);
+ devpriv->rtc_iosize = RTC_IO_EXTENT;
+ RTC_lock++;
+#ifdef UNTESTED_CODE
+ if (!comedi_request_irq(RTC_IRQ,
+ interrupt_pcl816_ai_mode13_dma_rtc, 0,
+ "pcl816 DMA (RTC)", dev)) {
+ devpriv->dma_rtc = 1;
+ devpriv->rtc_irq = RTC_IRQ;
+ rt_printk(", dma_irq=%u", devpriv->rtc_irq);
+ } else {
+ RTC_lock--;
+ if (RTC_lock == 0) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+ devpriv->rtc_iobase = 0;
+ devpriv->rtc_iosize = 0;
+ }
+#else
+ printk("pcl816: RTC code missing");
+#endif
+
+ }
+
+ no_rtc:
+#endif
+ /* grab our DMA */
+ dma = 0;
+ devpriv->dma = dma;
+ if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+ goto no_dma; /* if we haven't IRQ, we can't use DMA */
+
+ if (this_board->DMAbits != 0) { /* board support DMA */
+ dma = it->options[2];
+ if (dma < 1)
+ goto no_dma; /* DMA disabled */
+
+ if (((1 << dma) & this_board->DMAbits) == 0) {
+ rt_printk(", DMA is out of allowed range, FAIL!\n");
+ return -EINVAL; /* Bad DMA */
+ }
+ ret = request_dma(dma, "pcl816");
+ if (ret) {
+ rt_printk(", unable to allocate DMA %u, FAIL!\n", dma);
+ return -EBUSY; /* DMA isn't free */
+ }
+
+ devpriv->dma = dma;
+ rt_printk(", dma=%u", dma);
+ pages = 2; /* we need 16KB */
+ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+
+ if (!devpriv->dmabuf[0]) {
+ rt_printk(", unable to allocate DMA buffer, FAIL!\n");
+ /* maybe experiment with try_to_free_pages() will help .... */
+ return -EBUSY; /* no buffer :-( */
+ }
+ devpriv->dmapages[0] = pages;
+ devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+ devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
+ //rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE);
+
+ if (devpriv->dma_rtc == 0) { // we must do duble buff :-(
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1]) {
+ rt_printk
+ (", unable to allocate DMA buffer, FAIL!\n");
+ return -EBUSY;
+ }
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] =
+ virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
+ }
+ }
+
+ no_dma:
+
+/* if (this_board->n_aochan > 0)
+ subdevs[1] = COMEDI_SUBD_AO;
+ if (this_board->n_dichan > 0)
+ subdevs[2] = COMEDI_SUBD_DI;
+ if (this_board->n_dochan > 0)
+ subdevs[3] = COMEDI_SUBD_DO;
+*/
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ if (this_board->n_aichan > 0) {
+ s->type = COMEDI_SUBD_AI;
+ devpriv->sub_ai = s;
+ dev->read_subdev = s;
+ s->subdev_flags = SDF_READABLE | SDF_CMD_READ;
+ s->n_chan = this_board->n_aichan;
+ s->subdev_flags |= SDF_DIFF;
+ //printk (", %dchans DIFF DAC - %d", s->n_chan, i);
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = this_board->ai_chanlist;
+ s->range_table = this_board->ai_range_type;
+ s->cancel = pcl816_ai_cancel;
+ s->do_cmdtest = pcl816_ai_cmdtest;
+ s->do_cmd = pcl816_ai_cmd;
+ s->poll = pcl816_ai_poll;
+ s->insn_read = pcl816_ai_insn_read;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+#if 0
+case COMEDI_SUBD_AO:
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->ao_chanlist;
+ s->range_table = this_board->ao_range_type;
+ break;
+
+case COMEDI_SUBD_DI:
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ break;
+
+case COMEDI_SUBD_DO:
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ break;
+#endif
+
+ pcl816_reset(dev);
+
+ rt_printk("\n");
+
+ return 0;
+}
+
+/*
+==============================================================================
+ Removes device
+ */
+static int pcl816_detach(struct comedi_device * dev)
+{
+ DEBUG(rt_printk("comedi%d: pcl816: remove\n", dev->minor);
+ )
+ free_resources(dev);
+#ifdef unused
+ if (devpriv->dma_rtc)
+ RTC_lock--;
+#endif
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcl818.c b/drivers/staging/comedi/drivers/pcl818.c
new file mode 100644
index 00000000000..43a9d56c6a4
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcl818.c
@@ -0,0 +1,1988 @@
+/*
+ comedi/drivers/pcl818.c
+
+ Author: Michal Dobes <dobes@tesnet.cz>
+
+ hardware driver for Advantech cards:
+ card: PCL-818L, PCL-818H, PCL-818HD, PCL-818HG, PCL-818, PCL-718
+ driver: pcl818l, pcl818h, pcl818hd, pcl818hg, pcl818, pcl718
+*/
+/*
+Driver: pcl818
+Description: Advantech PCL-818 cards, PCL-718
+Author: Michal Dobes <dobes@tesnet.cz>
+Devices: [Advantech] PCL-818L (pcl818l), PCL-818H (pcl818h),
+ PCL-818HD (pcl818hd), PCL-818HG (pcl818hg), PCL-818 (pcl818),
+ PCL-718 (pcl718)
+Status: works
+
+All cards have 16 SE/8 DIFF ADCs, one or two DACs, 16 DI and 16 DO.
+Differences are only at maximal sample speed, range list and FIFO
+support.
+The driver support AI mode 0, 1, 3 other subdevices (AO, DI, DO) support
+only mode 0. If DMA/FIFO/INT are disabled then AI support only mode 0.
+PCL-818HD and PCL-818HG support 1kword FIFO. Driver support this FIFO
+but this code is untested.
+A word or two about DMA. Driver support DMA operations at two ways:
+1) DMA uses two buffers and after one is filled then is generated
+ INT and DMA restart with second buffer. With this mode I'm unable run
+ more that 80Ksamples/secs without data dropouts on K6/233.
+2) DMA uses one buffer and run in autoinit mode and the data are
+ from DMA buffer moved on the fly with 2kHz interrupts from RTC.
+ This mode is used if the interrupt 8 is available for allocation.
+ If not, then first DMA mode is used. With this I can run at
+ full speed one card (100ksamples/secs) or two cards with
+ 60ksamples/secs each (more is problem on account of ISA limitations).
+ To use this mode you must have compiled kernel with disabled
+ "Enhanced Real Time Clock Support".
+ Maybe you can have problems if you use xntpd or similar.
+ If you've data dropouts with DMA mode 2 then:
+ a) disable IDE DMA
+ b) switch text mode console to fb.
+
+ Options for PCL-818L:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0, 5=A/D input -5V.. +5V
+ 1, 10=A/D input -10V..+10V
+ [5] - 0, 5=D/A output 0-5V (internal reference -5V)
+ 1, 10=D/A output 0-10V (internal reference -10V)
+ 2 =D/A output unknow (external reference)
+
+ Options for PCL-818, PCL-818H:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0, 5=D/A output 0-5V (internal reference -5V)
+ 1, 10=D/A output 0-10V (internal reference -10V)
+ 2 =D/A output unknow (external reference)
+
+ Options for PCL-818HD, PCL-818HG:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA/FIFO (-1=use FIFO, 0=disable both FIFO and DMA,
+ 1=use DMA ch 1, 3=use DMA ch 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0, 5=D/A output 0-5V (internal reference -5V)
+ 1, 10=D/A output 0-10V (internal reference -10V)
+ 2 =D/A output unknow (external reference)
+
+ Options for PCL-718:
+ [0] - IO Base
+ [1] - IRQ (0=disable, 2, 3, 4, 5, 6, 7)
+ [2] - DMA (0=disable, 1, 3)
+ [3] - 0, 10=10MHz clock for 8254
+ 1= 1MHz clock for 8254
+ [4] - 0=A/D Range is +/-10V
+ 1= +/-5V
+ 2= +/-2.5V
+ 3= +/-1V
+ 4= +/-0.5V
+ 5= user defined bipolar
+ 6= 0-10V
+ 7= 0-5V
+ 8= 0-2V
+ 9= 0-1V
+ 10= user defined unipolar
+ [5] - 0, 5=D/A outputs 0-5V (internal reference -5V)
+ 1, 10=D/A outputs 0-10V (internal reference -10V)
+ 2=D/A outputs unknow (external reference)
+ [6] - 0, 60=max 60kHz A/D sampling
+ 1,100=max 100kHz A/D sampling (PCL-718 with Option 001 installed)
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/mc146818rtc.h>
+#include <linux/delay.h>
+#include <asm/dma.h>
+
+#include "8253.h"
+
+// #define PCL818_MODE13_AO 1
+
+// boards constants
+
+#define boardPCL818L 0
+#define boardPCL818H 1
+#define boardPCL818HD 2
+#define boardPCL818HG 3
+#define boardPCL818 4
+#define boardPCL718 5
+
+// IO space len
+#define PCLx1x_RANGE 16
+// IO space len if we use FIFO
+#define PCLx1xFIFO_RANGE 32
+
+// W: clear INT request
+#define PCL818_CLRINT 8
+// R: return status byte
+#define PCL818_STATUS 8
+// R: A/D high byte W: A/D range control
+#define PCL818_RANGE 1
+// R: next mux scan channel W: mux scan channel & range control pointer
+#define PCL818_MUX 2
+// R/W: operation control register
+#define PCL818_CONTROL 9
+// W: counter enable
+#define PCL818_CNTENABLE 10
+
+// R: low byte of A/D W: soft A/D trigger
+#define PCL818_AD_LO 0
+// R: high byte of A/D W: A/D range control
+#define PCL818_AD_HI 1
+// W: D/A low&high byte
+#define PCL818_DA_LO 4
+#define PCL818_DA_HI 5
+// R: low&high byte of DI
+#define PCL818_DI_LO 3
+#define PCL818_DI_HI 11
+// W: low&high byte of DO
+#define PCL818_DO_LO 3
+#define PCL818_DO_HI 11
+// W: PCL718 second D/A
+#define PCL718_DA2_LO 6
+#define PCL718_DA2_HI 7
+// counters
+#define PCL818_CTR0 12
+#define PCL818_CTR1 13
+#define PCL818_CTR2 14
+// W: counter control
+#define PCL818_CTRCTL 15
+
+// W: fifo enable/disable
+#define PCL818_FI_ENABLE 6
+// W: fifo interrupt clear
+#define PCL818_FI_INTCLR 20
+// W: fifo interrupt clear
+#define PCL818_FI_FLUSH 25
+// R: fifo status
+#define PCL818_FI_STATUS 25
+// R: one record from FIFO
+#define PCL818_FI_DATALO 23
+#define PCL818_FI_DATAHI 23
+
+// type of interrupt handler
+#define INT_TYPE_AI1_INT 1
+#define INT_TYPE_AI1_DMA 2
+#define INT_TYPE_AI1_FIFO 3
+#define INT_TYPE_AI3_INT 4
+#define INT_TYPE_AI3_DMA 5
+#define INT_TYPE_AI3_FIFO 6
+#ifdef PCL818_MODE13_AO
+#define INT_TYPE_AO1_INT 7
+#define INT_TYPE_AO3_INT 8
+#endif
+
+#ifdef unused
+// RTC stuff...
+#define INT_TYPE_AI1_DMA_RTC 9
+#define INT_TYPE_AI3_DMA_RTC 10
+
+#define RTC_IRQ 8
+#define RTC_IO_EXTENT 0x10
+#endif
+
+#define MAGIC_DMA_WORD 0x5a5a
+
+static const struct comedi_lrange range_pcl818h_ai = { 9, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ UNI_RANGE(10),
+ UNI_RANGE(5),
+ UNI_RANGE(2.5),
+ UNI_RANGE(1.25),
+ BIP_RANGE(10),
+ }
+};
+
+static const struct comedi_lrange range_pcl818hg_ai = { 10, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.005),
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.01),
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.01),
+ }
+};
+
+static const struct comedi_lrange range_pcl818l_l_ai = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ BIP_RANGE(0.625),
+ }
+};
+
+static const struct comedi_lrange range_pcl818l_h_ai = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25),
+ }
+};
+
+static const struct comedi_lrange range718_bipolar1 = { 1, {BIP_RANGE(1),} };
+static const struct comedi_lrange range718_bipolar0_5 = { 1, {BIP_RANGE(0.5),} };
+static const struct comedi_lrange range718_unipolar2 = { 1, {UNI_RANGE(2),} };
+static const struct comedi_lrange range718_unipolar1 = { 1, {BIP_RANGE(1),} };
+
+static int pcl818_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcl818_detach(struct comedi_device * dev);
+
+#ifdef unused
+static int RTC_lock = 0; /* RTC lock */
+static int RTC_timer_lock = 0; /* RTC int lock */
+#endif
+
+struct pcl818_board {
+
+ const char *name; // driver name
+ int n_ranges; // len of range list
+ int n_aichan_se; // num of A/D chans in single ended mode
+ int n_aichan_diff; // num of A/D chans in diferencial mode
+ unsigned int ns_min; // minimal alllowed delay between samples (in ns)
+ int n_aochan; // num of D/A chans
+ int n_dichan; // num of DI chans
+ int n_dochan; // num of DO chans
+ const struct comedi_lrange *ai_range_type; // default A/D rangelist
+ const struct comedi_lrange *ao_range_type; // default D/A rangelist
+ unsigned int io_range; // len of IO space
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int DMAbits; // allowed DMA chans
+ int ai_maxdata; // maxdata for A/D
+ int ao_maxdata; // maxdata for D/A
+ unsigned char fifo; // 1=board has FIFO
+ int is_818;
+};
+
+
+static const struct pcl818_board boardtypes[] = {
+ {"pcl818l", 4, 16, 8, 25000, 1, 16, 16, &range_pcl818l_l_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1},
+ {"pcl818h", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1},
+ {"pcl818hd", 9, 16, 8, 10000, 1, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 1, 1},
+ {"pcl818hg", 12, 16, 8, 10000, 1, 16, 16, &range_pcl818hg_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 1, 1},
+ {"pcl818", 9, 16, 8, 10000, 2, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1},
+ {"pcl718", 1, 16, 8, 16000, 2, 16, 16, &range_unipolar5,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 0},
+ /* pcm3718 */
+ {"pcm3718", 9, 16, 8, 10000, 0, 16, 16, &range_pcl818h_ai,
+ &range_unipolar5, PCLx1x_RANGE, 0x00fc,
+ 0x0a, 0xfff, 0xfff, 0, 1 /* XXX ? */ },
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcl818_board))
+
+static struct comedi_driver driver_pcl818 = {
+ driver_name:"pcl818",
+ module:THIS_MODULE,
+ attach:pcl818_attach,
+ detach:pcl818_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcl818_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcl818);
+
+struct pcl818_private {
+
+ unsigned int dma; // used DMA, 0=don't use DMA
+ int dma_rtc; // 1=RTC used with DMA, 0=no RTC alloc
+ unsigned int io_range;
+#ifdef unused
+ unsigned long rtc_iobase; // RTC port region
+ unsigned int rtc_iosize;
+ unsigned int rtc_irq;
+ struct timer_list rtc_irq_timer; // timer for RTC sanity check
+ unsigned long rtc_freq; // RTC int freq
+ int rtc_irq_blocked; // 1=we now do AI with DMA&RTC
+#endif
+ unsigned long dmabuf[2]; // pointers to begin of DMA buffers
+ unsigned int dmapages[2]; // len of DMA buffers in PAGE_SIZEs
+ unsigned int hwdmaptr[2]; // hardware address of DMA buffers
+ unsigned int hwdmasize[2]; // len of DMA buffers in Bytes
+ unsigned int dmasamplsize; // size in samples hwdmasize[0]/2
+ unsigned int last_top_dma; // DMA pointer in last RTC int
+ int next_dma_buf; // which DMA buffer will be used next round
+ long dma_runs_to_end; // how many we must permorm DMA transfer to end of record
+ unsigned long last_dma_run; // how many bytes we must transfer on last DMA page
+ unsigned char neverending_ai; // if=1, then we do neverending record (you must use cancel())
+ unsigned int ns_min; // manimal alllowed delay between samples (in us) for actual card
+ int i8253_osc_base; // 1/frequency of on board oscilator in ns
+ int irq_free; // 1=have allocated IRQ
+ int irq_blocked; // 1=IRQ now uses any subdev
+ int irq_was_now_closed; // when IRQ finish, there's stored int818_mode for last interrupt
+ int ai_mode; // who now uses IRQ - 1=AI1 int, 2=AI1 dma, 3=AI3 int, 4AI3 dma
+ struct comedi_subdevice *last_int_sub; // ptr to subdevice which now finish
+ int ai_act_scan; // how many scans we finished
+ int ai_act_chan; // actual position in actual scan
+ unsigned int act_chanlist[16]; // MUX setting for actual AI operations
+ unsigned int act_chanlist_len; // how long is actual MUX list
+ unsigned int act_chanlist_pos; // actual position in MUX list
+ unsigned int ai_scans; // len of scanlist
+ unsigned int ai_n_chan; // how many channels is measured
+ unsigned int *ai_chanlist; // actaul chanlist
+ unsigned int ai_flags; // flaglist
+ unsigned int ai_data_len; // len of data buffer
+ short *ai_data; // data buffer
+ unsigned int ai_timer1; // timers
+ unsigned int ai_timer2;
+ struct comedi_subdevice *sub_ai; // ptr to AI subdevice
+ unsigned char usefifo; // 1=use fifo
+ unsigned int ao_readback[2];
+};
+
+
+static const unsigned int muxonechan[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, // used for gain list programming
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff
+};
+
+#define devpriv ((struct pcl818_private *)dev->private)
+#define this_board ((const struct pcl818_board *)dev->board_ptr)
+
+/*
+==============================================================================
+*/
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen);
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan);
+
+static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2);
+
+#ifdef unused
+static int set_rtc_irq_bit(unsigned char bit);
+static void rtc_dropped_irq(unsigned long data);
+static int rtc_setfreq_irq(int freq);
+#endif
+
+/*
+==============================================================================
+ ANALOG INPUT MODE0, 818 cards, slow version
+*/
+static int pcl818_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int timeout;
+
+ /* software trigger, DMA and INT off */
+ outb(0, dev->iobase + PCL818_CONTROL);
+
+ /* select channel */
+ outb(muxonechan[CR_CHAN(insn->chanspec)], dev->iobase + PCL818_MUX);
+
+ /* select gain */
+ outb(CR_RANGE(insn->chanspec), dev->iobase + PCL818_RANGE);
+
+ for (n = 0; n < insn->n; n++) {
+
+ /* clear INT (conversion end) flag */
+ outb(0, dev->iobase + PCL818_CLRINT);
+
+ /* start conversion */
+ outb(0, dev->iobase + PCL818_AD_LO);
+
+ timeout = 100;
+ while (timeout--) {
+ if (inb(dev->iobase + PCL818_STATUS) & 0x10)
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ comedi_error(dev, "A/D insn timeout");
+ /* clear INT (conversion end) flag */
+ outb(0, dev->iobase + PCL818_CLRINT);
+ return -EIO;
+
+ conv_finish:
+ data[n] = ((inb(dev->iobase + PCL818_AD_HI) << 4) |
+ (inb(dev->iobase + PCL818_AD_LO) >> 4));
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+ ANALOG OUTPUT MODE0, 818 cards
+ only one sample per call is supported
+*/
+static int pcl818_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+}
+
+static int pcl818_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ devpriv->ao_readback[chan] = data[n];
+ outb((data[n] & 0x000f) << 4, dev->iobase +
+ (chan) ? PCL718_DA2_LO : PCL818_DA_LO);
+ outb((data[n] & 0x0ff0) >> 4, dev->iobase +
+ (chan) ? PCL718_DA2_HI : PCL818_DA_HI);
+ }
+
+ return n;
+}
+
+/*
+==============================================================================
+ DIGITAL INPUT MODE0, 818 cards
+
+ only one sample per call is supported
+*/
+static int pcl818_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + PCL818_DI_LO) |
+ (inb(dev->iobase + PCL818_DI_HI) << 8);
+
+ return 2;
+}
+
+/*
+==============================================================================
+ DIGITAL OUTPUT MODE0, 818 cards
+
+ only one sample per call is supported
+*/
+static int pcl818_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+
+ outb(s->state & 0xff, dev->iobase + PCL818_DO_LO);
+ outb((s->state >> 8), dev->iobase + PCL818_DO_HI);
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+==============================================================================
+ analog input interrupt mode 1 & 3, 818 cards
+ one sample per interrupt version
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_int(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int low;
+ int timeout = 50; /* wait max 50us */
+
+ while (timeout--) {
+ if (inb(dev->iobase + PCL818_STATUS) & 0x10)
+ goto conv_finish;
+ comedi_udelay(1);
+ }
+ outb(0, dev->iobase + PCL818_STATUS); /* clear INT request */
+ comedi_error(dev, "A/D mode1/3 IRQ without DRDY!");
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+
+ conv_finish:
+ low = inb(dev->iobase + PCL818_AD_LO);
+ comedi_buf_put(s->async, ((inb(dev->iobase + PCL818_AD_HI) << 4) | (low >> 4))); // get one sample
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+
+ if ((low & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 IRQ - channel dropout %x!=%x !\n",
+ (low & 0xf),
+ devpriv->act_chanlist[devpriv->act_chanlist_pos]);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+ if (s->async->cur_chan == 0) {
+ // rt_printk("E");
+ devpriv->ai_act_scan--;
+ }
+
+ if (!devpriv->neverending_ai) {
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ }
+ }
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ analog input dma mode 1 & 3, 818 cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_dma(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int i, len, bufptr;
+ unsigned long flags;
+ short *ptr;
+
+ disable_dma(devpriv->dma);
+ devpriv->next_dma_buf = 1 - devpriv->next_dma_buf;
+ if ((devpriv->dma_runs_to_end) > -1 || devpriv->neverending_ai) { // switch dma bufs
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ set_dma_addr(devpriv->dma,
+ devpriv->hwdmaptr[devpriv->next_dma_buf]);
+ if (devpriv->dma_runs_to_end || devpriv->neverending_ai) {
+ set_dma_count(devpriv->dma,
+ devpriv->hwdmasize[devpriv->next_dma_buf]);
+ } else {
+ set_dma_count(devpriv->dma, devpriv->last_dma_run);
+ }
+ release_dma_lock(flags);
+ enable_dma(devpriv->dma);
+ }
+ rt_printk("comedi: A/D mode1/3 IRQ \n");
+
+ devpriv->dma_runs_to_end--;
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+ ptr = (short *) devpriv->dmabuf[1 - devpriv->next_dma_buf];
+
+ len = devpriv->hwdmasize[0] >> 1;
+ bufptr = 0;
+
+ for (i = 0; i < len; i++) {
+ if ((ptr[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 DMA - channel dropout %d(card)!=%d(chanlist) at %d !\n",
+ (ptr[bufptr] & 0xf),
+ devpriv->act_chanlist[devpriv->
+ act_chanlist_pos],
+ devpriv->act_chanlist_pos);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async, ptr[bufptr++] >> 4); // get one sample
+
+ devpriv->act_chanlist_pos++;
+ if (devpriv->act_chanlist_pos >= devpriv->act_chanlist_len) {
+ devpriv->ai_act_scan--;
+ devpriv->act_chanlist_pos = 0;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ // printk("done int ai13 dma\n");
+ return IRQ_HANDLED;
+ }
+ }
+
+ if (len > 0)
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+#ifdef unused
+/*
+==============================================================================
+ analog input dma mode 1 & 3 over RTC, 818 cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_dma_rtc(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ unsigned long tmp;
+ unsigned int top1, top2, i, bufptr;
+ long ofs_dats;
+ short *dmabuf = (short *) devpriv->dmabuf[0];
+
+ //outb(2,0x378);
+ switch (devpriv->ai_mode) {
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0);
+ mod_timer(&devpriv->rtc_irq_timer,
+ jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
+
+ for (i = 0; i < 10; i++) {
+ top1 = get_dma_residue(devpriv->dma);
+ top2 = get_dma_residue(devpriv->dma);
+ if (top1 == top2)
+ break;
+ }
+
+ if (top1 != top2)
+ return IRQ_HANDLED;
+ top1 = devpriv->hwdmasize[0] - top1; // where is now DMA in buffer
+ top1 >>= 1;
+ ofs_dats = top1 - devpriv->last_top_dma; // new samples from last call
+ if (ofs_dats < 0)
+ ofs_dats = (devpriv->dmasamplsize) + ofs_dats;
+ if (!ofs_dats)
+ return IRQ_HANDLED; // exit=no new samples from last call
+ // obsluz data
+ i = devpriv->last_top_dma - 1;
+ i &= (devpriv->dmasamplsize - 1);
+
+ if (dmabuf[i] != MAGIC_DMA_WORD) { // DMA overflow!
+ comedi_error(dev, "A/D mode1/3 DMA buffer overflow!");
+ //rt_printk("I %d dmabuf[i] %d %d\n",i,dmabuf[i],devpriv->dmasamplsize);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+ //rt_printk("r %ld ",ofs_dats);
+
+ bufptr = devpriv->last_top_dma;
+
+ for (i = 0; i < ofs_dats; i++) {
+ if ((dmabuf[bufptr] & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 DMA - channel dropout %d!=%d !\n",
+ (dmabuf[bufptr] & 0xf),
+ devpriv->act_chanlist[devpriv->
+ act_chanlist_pos]);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async, dmabuf[bufptr++] >> 4); // get one sample
+ bufptr &= (devpriv->dmasamplsize - 1);
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan--;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ //printk("done int ai13 dma\n");
+ return IRQ_HANDLED;
+ }
+ }
+
+ devpriv->last_top_dma = bufptr;
+ bufptr--;
+ bufptr &= (devpriv->dmasamplsize - 1);
+ dmabuf[bufptr] = MAGIC_DMA_WORD;
+ comedi_event(dev, s);
+ //outb(0,0x378);
+ return IRQ_HANDLED;
+ }
+
+ //outb(0,0x378);
+ return IRQ_HANDLED;
+}
+#endif
+
+/*
+==============================================================================
+ analog input interrupt mode 1 & 3, 818HD/HG cards
+*/
+static irqreturn_t interrupt_pcl818_ai_mode13_fifo(int irq, void *d)
+{
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ int i, len, lo;
+
+ outb(0, dev->iobase + PCL818_FI_INTCLR); // clear fifo int request
+
+ lo = inb(dev->iobase + PCL818_FI_STATUS);
+
+ if (lo & 4) {
+ comedi_error(dev, "A/D mode1/3 FIFO overflow!");
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ if (lo & 1) {
+ comedi_error(dev, "A/D mode1/3 FIFO interrupt without data!");
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ if (lo & 2) {
+ len = 512;
+ } else {
+ len = 0;
+ }
+
+ for (i = 0; i < len; i++) {
+ lo = inb(dev->iobase + PCL818_FI_DATALO);
+ if ((lo & 0xf) != devpriv->act_chanlist[devpriv->act_chanlist_pos]) { // dropout!
+ rt_printk
+ ("comedi: A/D mode1/3 FIFO - channel dropout %d!=%d !\n",
+ (lo & 0xf),
+ devpriv->act_chanlist[devpriv->
+ act_chanlist_pos]);
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+
+ comedi_buf_put(s->async, (lo >> 4) | (inb(dev->iobase + PCL818_FI_DATAHI) << 4)); // get one sample
+
+ if (s->async->cur_chan == 0) {
+ devpriv->ai_act_scan--;
+ }
+
+ if (!devpriv->neverending_ai)
+ if (devpriv->ai_act_scan == 0) { /* all data sampled */
+ pcl818_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+ }
+ }
+
+ if (len > 0)
+ comedi_event(dev, s);
+ return IRQ_HANDLED;
+}
+
+/*
+==============================================================================
+ INT procedure
+*/
+static irqreturn_t interrupt_pcl818(int irq, void *d PT_REGS_ARG)
+{
+ struct comedi_device *dev = d;
+
+ if (!dev->attached) {
+ comedi_error(dev, "premature interrupt");
+ return IRQ_HANDLED;
+ }
+ //rt_printk("I\n");
+
+ switch (devpriv->ai_mode) {
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ return interrupt_pcl818_ai_mode13_dma(irq, d);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ return interrupt_pcl818_ai_mode13_int(irq, d);
+ case INT_TYPE_AI1_FIFO:
+ case INT_TYPE_AI3_FIFO:
+ return interrupt_pcl818_ai_mode13_fifo(irq, d);
+#ifdef PCL818_MODE13_AO
+ case INT_TYPE_AO1_INT:
+ case INT_TYPE_AO3_INT:
+ return interrupt_pcl818_ao_mode13_int(irq, d);
+#endif
+ default:
+ break;
+ }
+
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+
+ if ((!dev->irq) || (!devpriv->irq_free) || (!devpriv->irq_blocked)
+ || (!devpriv->ai_mode)) {
+ if (devpriv->irq_was_now_closed) {
+ if (devpriv->neverending_ai &&
+ (devpriv->ai_mode == INT_TYPE_AI1_DMA
+ || devpriv->ai_mode ==
+ INT_TYPE_AI3_DMA)) {
+ /* we had neverending ai but ai_cancel() has been called
+ the cleanup from ai_cancel() has been delayed until know
+ because the card doesn't seem to like being reprogrammed
+ while a DMA transfer is in progress
+ */
+ struct comedi_subdevice *s = dev->subdevices + 0;
+ devpriv->ai_mode = devpriv->irq_was_now_closed;
+ devpriv->irq_was_now_closed = 0;
+ devpriv->neverending_ai = 0;
+ pcl818_ai_cancel(dev, s);
+ }
+ devpriv->irq_was_now_closed = 0;
+ return IRQ_HANDLED;
+ }
+ comedi_error(dev, "bad IRQ!");
+ return IRQ_NONE;
+ }
+
+ comedi_error(dev, "IRQ from unknow source!");
+ return IRQ_NONE;
+}
+
+/*
+==============================================================================
+ ANALOG INPUT MODE 1 or 3 DMA , 818 cards
+*/
+static void pcl818_ai_mode13dma_int(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ unsigned int flags;
+ unsigned int bytes;
+
+ rt_printk("mode13dma_int, mode: %d\n", mode);
+ disable_dma(devpriv->dma); // disable dma
+ bytes = devpriv->hwdmasize[0];
+ if (!devpriv->neverending_ai) {
+ bytes = devpriv->ai_n_chan * devpriv->ai_scans * sizeof(short); // how many
+ devpriv->dma_runs_to_end = bytes / devpriv->hwdmasize[0]; // how many DMA pages we must fiil
+ devpriv->last_dma_run = bytes % devpriv->hwdmasize[0]; //on last dma transfer must be moved
+ devpriv->dma_runs_to_end--;
+ if (devpriv->dma_runs_to_end >= 0)
+ bytes = devpriv->hwdmasize[0];
+ }
+
+ devpriv->next_dma_buf = 0;
+ set_dma_mode(devpriv->dma, DMA_MODE_READ);
+ flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, bytes);
+ release_dma_lock(flags);
+ enable_dma(devpriv->dma);
+
+ if (mode == 1) {
+ devpriv->ai_mode = INT_TYPE_AI1_DMA;
+ outb(0x87 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ+DMA */
+ } else {
+ devpriv->ai_mode = INT_TYPE_AI3_DMA;
+ outb(0x86 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ+DMA */
+ };
+}
+
+#ifdef unused
+/*
+==============================================================================
+ ANALOG INPUT MODE 1 or 3 DMA rtc, 818 cards
+*/
+static void pcl818_ai_mode13dma_rtc(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ unsigned int flags;
+ short *pole;
+
+ set_dma_mode(devpriv->dma, DMA_MODE_READ | DMA_AUTOINIT);
+ flags = claim_dma_lock();
+ clear_dma_ff(devpriv->dma);
+ set_dma_addr(devpriv->dma, devpriv->hwdmaptr[0]);
+ set_dma_count(devpriv->dma, devpriv->hwdmasize[0]);
+ release_dma_lock(flags);
+ enable_dma(devpriv->dma);
+ devpriv->last_top_dma = 0; //devpriv->hwdmasize[0];
+ pole = (short *) devpriv->dmabuf[0];
+ devpriv->dmasamplsize = devpriv->hwdmasize[0] / 2;
+ pole[devpriv->dmasamplsize - 1] = MAGIC_DMA_WORD;
+#ifdef unused
+ devpriv->rtc_freq = rtc_setfreq_irq(2048);
+ devpriv->rtc_irq_timer.expires =
+ jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100;
+ devpriv->rtc_irq_timer.data = (unsigned long)dev;
+ devpriv->rtc_irq_timer.function = rtc_dropped_irq;
+
+ add_timer(&devpriv->rtc_irq_timer);
+#endif
+
+ if (mode == 1) {
+ devpriv->int818_mode = INT_TYPE_AI1_DMA_RTC;
+ outb(0x07 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+DMA */
+ } else {
+ devpriv->int818_mode = INT_TYPE_AI3_DMA_RTC;
+ outb(0x06 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+DMA */
+ };
+}
+#endif
+
+/*
+==============================================================================
+ ANALOG INPUT MODE 1 or 3, 818 cards
+*/
+static int pcl818_ai_cmd_mode(int mode, struct comedi_device * dev,
+ struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int divisor1, divisor2;
+ unsigned int seglen;
+
+ rt_printk("pcl818_ai_cmd_mode()\n");
+ if ((!dev->irq) && (!devpriv->dma_rtc)) {
+ comedi_error(dev, "IRQ not defined!");
+ return -EINVAL;
+ }
+
+ if (devpriv->irq_blocked)
+ return -EBUSY;
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ seglen = check_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan);
+ if (seglen < 1)
+ return -EINVAL;
+ setup_channel_list(dev, s, devpriv->ai_chanlist,
+ devpriv->ai_n_chan, seglen);
+
+ comedi_udelay(1);
+
+ devpriv->ai_act_scan = devpriv->ai_scans;
+ devpriv->ai_act_chan = 0;
+ devpriv->irq_blocked = 1;
+ devpriv->irq_was_now_closed = 0;
+ devpriv->neverending_ai = 0;
+ devpriv->act_chanlist_pos = 0;
+ devpriv->dma_runs_to_end = 0;
+
+ if ((devpriv->ai_scans == 0) || (devpriv->ai_scans == -1))
+ devpriv->neverending_ai = 1; //well, user want neverending
+
+ if (mode == 1) {
+ i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg, TRIG_ROUND_NEAREST);
+ if (divisor1 == 1) { /* PCL718/818 crash if any divisor is set to 1 */
+ divisor1 = 2;
+ divisor2 /= 2;
+ }
+ if (divisor2 == 1) {
+ divisor2 = 2;
+ divisor1 /= 2;
+ }
+ }
+
+ outb(0, dev->iobase + PCL818_CNTENABLE); /* enable pacer */
+
+ switch (devpriv->dma) {
+ case 1: // DMA
+ case 3:
+ if (devpriv->dma_rtc == 0) {
+ pcl818_ai_mode13dma_int(mode, dev, s);
+ }
+#ifdef unused
+ else {
+ pcl818_ai_mode13dma_rtc(mode, dev, s);
+ }
+#else
+ else {
+ return -EINVAL;
+ }
+#endif
+ break;
+ case 0: // IRQ
+ // rt_printk("IRQ\n");
+ if (mode == 1) {
+ devpriv->ai_mode = INT_TYPE_AI1_INT;
+ outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
+ } else {
+ devpriv->ai_mode = INT_TYPE_AI3_INT;
+ outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
+ };
+ break;
+ case -1: // FIFO
+ outb(1, dev->iobase + PCL818_FI_ENABLE); // enable FIFO
+ if (mode == 1) {
+ devpriv->ai_mode = INT_TYPE_AI1_FIFO;
+ outb(0x03, dev->iobase + PCL818_CONTROL); /* Pacer */
+ } else {
+ devpriv->ai_mode = INT_TYPE_AI3_FIFO;
+ outb(0x02, dev->iobase + PCL818_CONTROL);
+ }; /* Ext trig */
+ break;
+ }
+
+ start_pacer(dev, mode, divisor1, divisor2);
+
+#ifdef unused
+ switch (devpriv->ai_mode) {
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ set_rtc_irq_bit(1); /* start RTC */
+ break;
+ }
+#endif
+ rt_printk("pcl818_ai_cmd_mode() end\n");
+ return 0;
+}
+
+#ifdef unused
+/*
+==============================================================================
+ ANALOG OUTPUT MODE 1 or 3, 818 cards
+*/
+#ifdef PCL818_MODE13_AO
+static int pcl818_ao_mode13(int mode, struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ int divisor1, divisor2;
+
+ if (!dev->irq) {
+ comedi_error(dev, "IRQ not defined!");
+ return -EINVAL;
+ }
+
+ if (devpriv->irq_blocked)
+ return -EBUSY;
+
+ start_pacer(dev, -1, 0, 0); // stop pacer
+
+ devpriv->int13_act_scan = it->n;
+ devpriv->int13_act_chan = 0;
+ devpriv->irq_blocked = 1;
+ devpriv->irq_was_now_closed = 0;
+ devpriv->neverending_ai = 0;
+ devpriv->act_chanlist_pos = 0;
+
+ if (mode == 1) {
+ i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+ &divisor2, &it->trigvar, TRIG_ROUND_NEAREST);
+ if (divisor1 == 1) { /* PCL818 crash if any divisor is set to 1 */
+ divisor1 = 2;
+ divisor2 /= 2;
+ }
+ if (divisor2 == 1) {
+ divisor2 = 2;
+ divisor1 /= 2;
+ }
+ }
+
+ outb(0, dev->iobase + PCL818_CNTENABLE); /* enable pacer */
+ if (mode == 1) {
+ devpriv->int818_mode = INT_TYPE_AO1_INT;
+ outb(0x83 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Pacer+IRQ */
+ } else {
+ devpriv->int818_mode = INT_TYPE_AO3_INT;
+ outb(0x82 | (dev->irq << 4), dev->iobase + PCL818_CONTROL); /* Ext trig+IRQ */
+ };
+
+ start_pacer(dev, mode, divisor1, divisor2);
+
+ return 0;
+}
+
+/*
+==============================================================================
+ ANALOG OUTPUT MODE 1, 818 cards
+*/
+static int pcl818_ao_mode1(struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ return pcl818_ao_mode13(1, dev, s, it);
+}
+
+/*
+==============================================================================
+ ANALOG OUTPUT MODE 3, 818 cards
+*/
+static int pcl818_ao_mode3(struct comedi_device * dev, struct comedi_subdevice * s,
+ comedi_trig * it)
+{
+ return pcl818_ao_mode13(3, dev, s, it);
+}
+#endif
+#endif
+
+/*
+==============================================================================
+ Start/stop pacer onboard pacer
+*/
+static void start_pacer(struct comedi_device * dev, int mode, unsigned int divisor1,
+ unsigned int divisor2)
+{
+ outb(0xb4, dev->iobase + PCL818_CTRCTL);
+ outb(0x74, dev->iobase + PCL818_CTRCTL);
+ comedi_udelay(1);
+
+ if (mode == 1) {
+ outb(divisor2 & 0xff, dev->iobase + PCL818_CTR2);
+ outb((divisor2 >> 8) & 0xff, dev->iobase + PCL818_CTR2);
+ outb(divisor1 & 0xff, dev->iobase + PCL818_CTR1);
+ outb((divisor1 >> 8) & 0xff, dev->iobase + PCL818_CTR1);
+ }
+}
+
+/*
+==============================================================================
+ Check if channel list from user is builded correctly
+ If it's ok, then program scan/gain logic
+*/
+static int check_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan)
+{
+ unsigned int chansegment[16];
+ unsigned int i, nowmustbechan, seglen, segpos;
+
+ /* correct channel and range number check itself comedi/range.c */
+ if (n_chan < 1) {
+ comedi_error(dev, "range/channel list is empty!");
+ return 0;
+ }
+
+ if (n_chan > 1) {
+ // first channel is everytime ok
+ chansegment[0] = chanlist[0];
+ // build part of chanlist
+ for (i = 1, seglen = 1; i < n_chan; i++, seglen++) {
+ // rt_printk("%d. %d %d\n",i,CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
+ // we detect loop, this must by finish
+ if (chanlist[0] == chanlist[i])
+ break;
+ nowmustbechan =
+ (CR_CHAN(chansegment[i - 1]) + 1) % s->n_chan;
+ if (nowmustbechan != CR_CHAN(chanlist[i])) { // channel list isn't continous :-(
+ rt_printk
+ ("comedi%d: pcl818: channel list must be continous! chanlist[%i]=%d but must be %d or %d!\n",
+ dev->minor, i, CR_CHAN(chanlist[i]),
+ nowmustbechan, CR_CHAN(chanlist[0]));
+ return 0;
+ }
+ // well, this is next correct channel in list
+ chansegment[i] = chanlist[i];
+ }
+
+ // check whole chanlist
+ for (i = 0, segpos = 0; i < n_chan; i++) {
+ //rt_printk("%d %d=%d %d\n",CR_CHAN(chansegment[i%seglen]),CR_RANGE(chansegment[i%seglen]),CR_CHAN(it->chanlist[i]),CR_RANGE(it->chanlist[i]));
+ if (chanlist[i] != chansegment[i % seglen]) {
+ rt_printk
+ ("comedi%d: pcl818: bad channel or range number! chanlist[%i]=%d,%d,%d and not %d,%d,%d!\n",
+ dev->minor, i, CR_CHAN(chansegment[i]),
+ CR_RANGE(chansegment[i]),
+ CR_AREF(chansegment[i]),
+ CR_CHAN(chanlist[i % seglen]),
+ CR_RANGE(chanlist[i % seglen]),
+ CR_AREF(chansegment[i % seglen]));
+ return 0; // chan/gain list is strange
+ }
+ }
+ } else {
+ seglen = 1;
+ }
+ rt_printk("check_channel_list: seglen %d\n", seglen);
+ return seglen;
+}
+
+static void setup_channel_list(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int *chanlist, unsigned int n_chan, unsigned int seglen)
+{
+ int i;
+
+ devpriv->act_chanlist_len = seglen;
+ devpriv->act_chanlist_pos = 0;
+
+ for (i = 0; i < seglen; i++) { // store range list to card
+ devpriv->act_chanlist[i] = CR_CHAN(chanlist[i]);
+ outb(muxonechan[CR_CHAN(chanlist[i])], dev->iobase + PCL818_MUX); /* select channel */
+ outb(CR_RANGE(chanlist[i]), dev->iobase + PCL818_RANGE); /* select gain */
+ }
+
+ comedi_udelay(1);
+
+ /* select channel interval to scan */
+ outb(devpriv->act_chanlist[0] | (devpriv->act_chanlist[seglen -
+ 1] << 4), dev->iobase + PCL818_MUX);
+}
+
+/*
+==============================================================================
+ Check if board is switched to SE (1) or DIFF(0) mode
+*/
+static int check_single_ended(unsigned int port)
+{
+ if (inb(port + PCL818_STATUS) & 0x20) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/*
+==============================================================================
+*/
+static int ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp, divisor1, divisor2;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err) {
+ return 1;
+ }
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ if (cmd->start_src != TRIG_NOW) {
+ cmd->start_src = TRIG_NOW;
+ err++;
+ }
+ if (cmd->scan_begin_src != TRIG_FOLLOW) {
+ cmd->scan_begin_src = TRIG_FOLLOW;
+ err++;
+ }
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+
+ if (cmd->scan_end_src != TRIG_COUNT) {
+ cmd->scan_end_src = TRIG_COUNT;
+ err++;
+ }
+
+ if (cmd->stop_src != TRIG_NONE && cmd->stop_src != TRIG_COUNT)
+ err++;
+
+ if (err) {
+ return 2;
+ }
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < this_board->ns_min) {
+ cmd->convert_arg = this_board->ns_min;
+ err++;
+ }
+ } else { /* TRIG_EXT */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+ }
+
+ if (!cmd->chanlist_len) {
+ cmd->chanlist_len = 1;
+ err++;
+ }
+ if (cmd->chanlist_len > s->n_chan) {
+ cmd->chanlist_len = s->n_chan;
+ err++;
+ }
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (!cmd->stop_arg) {
+ cmd->stop_arg = 1;
+ err++;
+ }
+ } else { /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err) {
+ return 3;
+ }
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ i8253_cascade_ns_to_timer(devpriv->i8253_osc_base, &divisor1,
+ &divisor2, &cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (cmd->convert_arg < this_board->ns_min)
+ cmd->convert_arg = this_board->ns_min;
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err) {
+ return 4;
+ }
+
+ /* step 5: complain about special chanlist considerations */
+
+ if (cmd->chanlist) {
+ if (!check_channel_list(dev, s, cmd->chanlist,
+ cmd->chanlist_len))
+ return 5; // incorrect channels list
+ }
+
+ return 0;
+}
+
+/*
+==============================================================================
+*/
+static int ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int retval;
+
+ rt_printk("pcl818_ai_cmd()\n");
+ devpriv->ai_n_chan = cmd->chanlist_len;
+ devpriv->ai_chanlist = cmd->chanlist;
+ devpriv->ai_flags = cmd->flags;
+ devpriv->ai_data_len = s->async->prealloc_bufsz;
+ devpriv->ai_data = s->async->prealloc_buf;
+ devpriv->ai_timer1 = 0;
+ devpriv->ai_timer2 = 0;
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ devpriv->ai_scans = cmd->stop_arg;
+ } else {
+ devpriv->ai_scans = 0;
+ }
+
+ if (cmd->scan_begin_src == TRIG_FOLLOW) { // mode 1, 3
+ if (cmd->convert_src == TRIG_TIMER) { // mode 1
+ devpriv->ai_timer1 = cmd->convert_arg;
+ retval = pcl818_ai_cmd_mode(1, dev, s);
+ rt_printk("pcl818_ai_cmd() end\n");
+ return retval;
+ }
+ if (cmd->convert_src == TRIG_EXT) { // mode 3
+ return pcl818_ai_cmd_mode(3, dev, s);
+ }
+ }
+
+ return -1;
+}
+
+/*
+==============================================================================
+ cancel any mode 1-4 AI
+*/
+static int pcl818_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (devpriv->irq_blocked > 0) {
+ rt_printk("pcl818_ai_cancel()\n");
+ devpriv->irq_was_now_closed = devpriv->ai_mode;
+ devpriv->ai_mode = 0;
+
+ switch (devpriv->irq_was_now_closed) {
+#ifdef unused
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ set_rtc_irq_bit(0); // stop RTC
+ del_timer(&devpriv->rtc_irq_timer);
+#endif
+ case INT_TYPE_AI1_DMA:
+ case INT_TYPE_AI3_DMA:
+ if (devpriv->neverending_ai) {
+ /* wait for running dma transfer to end, do cleanup in interrupt */
+ goto end;
+ }
+ disable_dma(devpriv->dma);
+ case INT_TYPE_AI1_INT:
+ case INT_TYPE_AI3_INT:
+ case INT_TYPE_AI1_FIFO:
+ case INT_TYPE_AI3_FIFO:
+#ifdef PCL818_MODE13_AO
+ case INT_TYPE_AO1_INT:
+ case INT_TYPE_AO3_INT:
+#endif
+ outb(inb(dev->iobase + PCL818_CONTROL) & 0x73, dev->iobase + PCL818_CONTROL); /* Stop A/D */
+ comedi_udelay(1);
+ start_pacer(dev, -1, 0, 0);
+ outb(0, dev->iobase + PCL818_AD_LO);
+ inb(dev->iobase + PCL818_AD_LO);
+ inb(dev->iobase + PCL818_AD_HI);
+ outb(0, dev->iobase + PCL818_CLRINT); /* clear INT request */
+ outb(0, dev->iobase + PCL818_CONTROL); /* Stop A/D */
+ if (devpriv->usefifo) { // FIFO shutdown
+ outb(0, dev->iobase + PCL818_FI_INTCLR);
+ outb(0, dev->iobase + PCL818_FI_FLUSH);
+ outb(0, dev->iobase + PCL818_FI_ENABLE);
+ }
+ devpriv->irq_blocked = 0;
+ devpriv->last_int_sub = s;
+ devpriv->neverending_ai = 0;
+ break;
+ }
+ }
+
+ end:
+ rt_printk("pcl818_ai_cancel() end\n");
+ return 0;
+}
+
+/*
+==============================================================================
+ chech for PCL818
+*/
+static int pcl818_check(unsigned long iobase)
+{
+ outb(0x00, iobase + PCL818_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL818_MUX) != 0x00)
+ return 1; //there isn't card
+ outb(0x55, iobase + PCL818_MUX);
+ comedi_udelay(1);
+ if (inb(iobase + PCL818_MUX) != 0x55)
+ return 1; //there isn't card
+ outb(0x00, iobase + PCL818_MUX);
+ comedi_udelay(1);
+ outb(0x18, iobase + PCL818_CONTROL);
+ comedi_udelay(1);
+ if (inb(iobase + PCL818_CONTROL) != 0x18)
+ return 1; //there isn't card
+ return 0; // ok, card exist
+}
+
+/*
+==============================================================================
+ reset whole PCL-818 cards
+*/
+static void pcl818_reset(struct comedi_device * dev)
+{
+ if (devpriv->usefifo) { // FIFO shutdown
+ outb(0, dev->iobase + PCL818_FI_INTCLR);
+ outb(0, dev->iobase + PCL818_FI_FLUSH);
+ outb(0, dev->iobase + PCL818_FI_ENABLE);
+ }
+ outb(0, dev->iobase + PCL818_DA_LO); // DAC=0V
+ outb(0, dev->iobase + PCL818_DA_HI);
+ comedi_udelay(1);
+ outb(0, dev->iobase + PCL818_DO_HI); // DO=$0000
+ outb(0, dev->iobase + PCL818_DO_LO);
+ comedi_udelay(1);
+ outb(0, dev->iobase + PCL818_CONTROL);
+ outb(0, dev->iobase + PCL818_CNTENABLE);
+ outb(0, dev->iobase + PCL818_MUX);
+ outb(0, dev->iobase + PCL818_CLRINT);
+ outb(0xb0, dev->iobase + PCL818_CTRCTL); /* Stop pacer */
+ outb(0x70, dev->iobase + PCL818_CTRCTL);
+ outb(0x30, dev->iobase + PCL818_CTRCTL);
+ if (this_board->is_818) {
+ outb(0, dev->iobase + PCL818_RANGE);
+ } else {
+ outb(0, dev->iobase + PCL718_DA2_LO);
+ outb(0, dev->iobase + PCL718_DA2_HI);
+ }
+}
+
+#ifdef unused
+/*
+==============================================================================
+ Enable(1)/disable(0) periodic interrupts from RTC
+*/
+static int set_rtc_irq_bit(unsigned char bit)
+{
+ unsigned char val;
+ unsigned long flags;
+
+ if (bit == 1) {
+ RTC_timer_lock++;
+ if (RTC_timer_lock > 1)
+ return 0;
+ } else {
+ RTC_timer_lock--;
+ if (RTC_timer_lock < 0)
+ RTC_timer_lock = 0;
+ if (RTC_timer_lock > 0)
+ return 0;
+ }
+
+ save_flags(flags);
+ cli();
+ val = CMOS_READ(RTC_CONTROL);
+ if (bit) {
+ val |= RTC_PIE;
+ } else {
+ val &= ~RTC_PIE;
+ }
+ CMOS_WRITE(val, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+ restore_flags(flags);
+ return 0;
+}
+
+/*
+==============================================================================
+ Restart RTC if something stop it (xntpd every 11 mins or large IDE transfers)
+*/
+static void rtc_dropped_irq(unsigned long data)
+{
+ struct comedi_device *dev = (void *)data;
+ unsigned long flags, tmp;
+
+ switch (devpriv->int818_mode) {
+ case INT_TYPE_AI1_DMA_RTC:
+ case INT_TYPE_AI3_DMA_RTC:
+ mod_timer(&devpriv->rtc_irq_timer,
+ jiffies + HZ / devpriv->rtc_freq + 2 * HZ / 100);
+ save_flags(flags);
+ cli();
+ tmp = (CMOS_READ(RTC_INTR_FLAGS) & 0xF0); /* restart */
+ restore_flags(flags);
+ break;
+ };
+}
+
+/*
+==============================================================================
+ Set frequency of interrupts from RTC
+*/
+static int rtc_setfreq_irq(int freq)
+{
+ int tmp = 0;
+ int rtc_freq;
+ unsigned char val;
+ unsigned long flags;
+
+ if (freq < 2)
+ freq = 2;
+ if (freq > 8192)
+ freq = 8192;
+
+ while (freq > (1 << tmp))
+ tmp++;
+
+ rtc_freq = 1 << tmp;
+
+ save_flags(flags);
+ cli();
+ val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
+ val |= (16 - tmp);
+ CMOS_WRITE(val, RTC_FREQ_SELECT);
+ restore_flags(flags);
+ return rtc_freq;
+}
+#endif
+
+/*
+==============================================================================
+ Free any resources that we have claimed
+*/
+static void free_resources(struct comedi_device * dev)
+{
+ //rt_printk("free_resource()\n");
+ if (dev->private) {
+ pcl818_ai_cancel(dev, devpriv->sub_ai);
+ pcl818_reset(dev);
+ if (devpriv->dma)
+ free_dma(devpriv->dma);
+ if (devpriv->dmabuf[0])
+ free_pages(devpriv->dmabuf[0], devpriv->dmapages[0]);
+ if (devpriv->dmabuf[1])
+ free_pages(devpriv->dmabuf[1], devpriv->dmapages[1]);
+#ifdef unused
+ if (devpriv->rtc_irq)
+ comedi_free_irq(devpriv->rtc_irq, dev);
+ if ((devpriv->dma_rtc) && (RTC_lock == 1)) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+ if (devpriv->dma_rtc)
+ RTC_lock--;
+#endif
+ }
+
+ if (dev->irq)
+ free_irq(dev->irq, dev);
+ if (dev->iobase)
+ release_region(dev->iobase, devpriv->io_range);
+ //rt_printk("free_resource() end\n");
+}
+
+/*
+==============================================================================
+
+ Initialization
+
+*/
+static int pcl818_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ unsigned long iobase;
+ unsigned int irq, dma;
+ unsigned long pages;
+ struct comedi_subdevice *s;
+
+ if ((ret = alloc_private(dev, sizeof(struct pcl818_private))) < 0)
+ return ret; /* Can't alloc mem */
+
+ /* claim our I/O space */
+ iobase = it->options[0];
+ printk("comedi%d: pcl818: board=%s, ioport=0x%03lx",
+ dev->minor, this_board->name, iobase);
+ devpriv->io_range = this_board->io_range;
+ if ((this_board->fifo) && (it->options[2] == -1)) { // we've board with FIFO and we want to use FIFO
+ devpriv->io_range = PCLx1xFIFO_RANGE;
+ devpriv->usefifo = 1;
+ }
+ if (!request_region(iobase, devpriv->io_range, "pcl818")) {
+ rt_printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+
+ if (pcl818_check(iobase)) {
+ rt_printk(", I can't detect board. FAIL!\n");
+ return -EIO;
+ }
+
+ /* set up some name stuff */
+ dev->board_name = this_board->name;
+ /* grab our IRQ */
+ irq = 0;
+ if (this_board->IRQbits != 0) { /* board support IRQ */
+ irq = it->options[1];
+ if (irq) { /* we want to use IRQ */
+ if (((1 << irq) & this_board->IRQbits) == 0) {
+ rt_printk
+ (", IRQ %u is out of allowed range, DISABLING IT",
+ irq);
+ irq = 0; /* Bad IRQ */
+ } else {
+ if (comedi_request_irq(irq, interrupt_pcl818, 0,
+ "pcl818", dev)) {
+ rt_printk
+ (", unable to allocate IRQ %u, DISABLING IT",
+ irq);
+ irq = 0; /* Can't use IRQ */
+ } else {
+ rt_printk(", irq=%u", irq);
+ }
+ }
+ }
+ }
+
+ dev->irq = irq;
+ if (irq) {
+ devpriv->irq_free = 1;
+ } /* 1=we have allocated irq */
+ else {
+ devpriv->irq_free = 0;
+ }
+ devpriv->irq_blocked = 0; /* number of subdevice which use IRQ */
+ devpriv->ai_mode = 0; /* mode of irq */
+
+#ifdef unused
+ /* grab RTC for DMA operations */
+ devpriv->dma_rtc = 0;
+ if (it->options[2] > 0) { // we want to use DMA
+ if (RTC_lock == 0) {
+ if (!request_region(RTC_PORT(0), RTC_IO_EXTENT,
+ "pcl818 (RTC)"))
+ goto no_rtc;
+ }
+ devpriv->rtc_iobase = RTC_PORT(0);
+ devpriv->rtc_iosize = RTC_IO_EXTENT;
+ RTC_lock++;
+ if (!comedi_request_irq(RTC_IRQ,
+ interrupt_pcl818_ai_mode13_dma_rtc, 0,
+ "pcl818 DMA (RTC)", dev)) {
+ devpriv->dma_rtc = 1;
+ devpriv->rtc_irq = RTC_IRQ;
+ rt_printk(", dma_irq=%u", devpriv->rtc_irq);
+ } else {
+ RTC_lock--;
+ if (RTC_lock == 0) {
+ if (devpriv->rtc_iobase)
+ release_region(devpriv->rtc_iobase,
+ devpriv->rtc_iosize);
+ }
+ devpriv->rtc_iobase = 0;
+ devpriv->rtc_iosize = 0;
+ }
+ }
+
+ no_rtc:
+#endif
+ /* grab our DMA */
+ dma = 0;
+ devpriv->dma = dma;
+ if ((devpriv->irq_free == 0) && (devpriv->dma_rtc == 0))
+ goto no_dma; /* if we haven't IRQ, we can't use DMA */
+ if (this_board->DMAbits != 0) { /* board support DMA */
+ dma = it->options[2];
+ if (dma < 1)
+ goto no_dma; /* DMA disabled */
+ if (((1 << dma) & this_board->DMAbits) == 0) {
+ rt_printk(", DMA is out of allowed range, FAIL!\n");
+ return -EINVAL; /* Bad DMA */
+ }
+ ret = request_dma(dma, "pcl818");
+ if (ret) {
+ rt_printk(", unable to allocate DMA %u, FAIL!\n", dma);
+ return -EBUSY; /* DMA isn't free */
+ }
+ devpriv->dma = dma;
+ rt_printk(", dma=%u", dma);
+ pages = 2; /* we need 16KB */
+ devpriv->dmabuf[0] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[0]) {
+ rt_printk(", unable to allocate DMA buffer, FAIL!\n");
+ /* maybe experiment with try_to_free_pages() will help .... */
+ return -EBUSY; /* no buffer :-( */
+ }
+ devpriv->dmapages[0] = pages;
+ devpriv->hwdmaptr[0] = virt_to_bus((void *)devpriv->dmabuf[0]);
+ devpriv->hwdmasize[0] = (1 << pages) * PAGE_SIZE;
+ //rt_printk("%d %d %ld, ",devpriv->dmapages[0],devpriv->hwdmasize[0],PAGE_SIZE);
+ if (devpriv->dma_rtc == 0) { // we must do duble buff :-(
+ devpriv->dmabuf[1] = __get_dma_pages(GFP_KERNEL, pages);
+ if (!devpriv->dmabuf[1]) {
+ rt_printk
+ (", unable to allocate DMA buffer, FAIL!\n");
+ return -EBUSY;
+ }
+ devpriv->dmapages[1] = pages;
+ devpriv->hwdmaptr[1] =
+ virt_to_bus((void *)devpriv->dmabuf[1]);
+ devpriv->hwdmasize[1] = (1 << pages) * PAGE_SIZE;
+ }
+ }
+
+ no_dma:
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ s = dev->subdevices + 0;
+ if (!this_board->n_aichan_se) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_AI;
+ devpriv->sub_ai = s;
+ s->subdev_flags = SDF_READABLE;
+ if (check_single_ended(dev->iobase)) {
+ s->n_chan = this_board->n_aichan_se;
+ s->subdev_flags |= SDF_COMMON | SDF_GROUND;
+ printk(", %dchans S.E. DAC", s->n_chan);
+ } else {
+ s->n_chan = this_board->n_aichan_diff;
+ s->subdev_flags |= SDF_DIFF;
+ printk(", %dchans DIFF DAC", s->n_chan);
+ }
+ s->maxdata = this_board->ai_maxdata;
+ s->len_chanlist = s->n_chan;
+ s->range_table = this_board->ai_range_type;
+ s->cancel = pcl818_ai_cancel;
+ s->insn_read = pcl818_ai_insn_read;
+ if ((irq) || (devpriv->dma_rtc)) {
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->do_cmdtest = ai_cmdtest;
+ s->do_cmd = ai_cmd;
+ }
+ if (this_board->is_818) {
+ if ((it->options[4] == 1) || (it->options[4] == 10))
+ s->range_table = &range_pcl818l_h_ai; // secondary range list jumper selectable
+ } else {
+ switch (it->options[4]) {
+ case 0:
+ s->range_table = &range_bipolar10;
+ break;
+ case 1:
+ s->range_table = &range_bipolar5;
+ break;
+ case 2:
+ s->range_table = &range_bipolar2_5;
+ break;
+ case 3:
+ s->range_table = &range718_bipolar1;
+ break;
+ case 4:
+ s->range_table = &range718_bipolar0_5;
+ break;
+ case 6:
+ s->range_table = &range_unipolar10;
+ break;
+ case 7:
+ s->range_table = &range_unipolar5;
+ break;
+ case 8:
+ s->range_table = &range718_unipolar2;
+ break;
+ case 9:
+ s->range_table = &range718_unipolar1;
+ break;
+ default:
+ s->range_table = &range_unknown;
+ break;
+ }
+ }
+ }
+
+ s = dev->subdevices + 1;
+ if (!this_board->n_aochan) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE | SDF_GROUND;
+ s->n_chan = this_board->n_aochan;
+ s->maxdata = this_board->ao_maxdata;
+ s->len_chanlist = this_board->n_aochan;
+ s->range_table = this_board->ao_range_type;
+ s->insn_read = pcl818_ao_insn_read;
+ s->insn_write = pcl818_ao_insn_write;
+#ifdef unused
+#ifdef PCL818_MODE13_AO
+ if (irq) {
+ s->trig[1] = pcl818_ao_mode1;
+ s->trig[3] = pcl818_ao_mode3;
+ }
+#endif
+#endif
+ if (this_board->is_818) {
+ if ((it->options[4] == 1) || (it->options[4] == 10))
+ s->range_table = &range_unipolar10;
+ if (it->options[4] == 2)
+ s->range_table = &range_unknown;
+ } else {
+ if ((it->options[5] == 1) || (it->options[5] == 10))
+ s->range_table = &range_unipolar10;
+ if (it->options[5] == 2)
+ s->range_table = &range_unknown;
+ }
+ }
+
+ s = dev->subdevices + 2;
+ if (!this_board->n_dichan) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = this_board->n_dichan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dichan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl818_di_insn_bits;
+ }
+
+ s = dev->subdevices + 3;
+ if (!this_board->n_dochan) {
+ s->type = COMEDI_SUBD_UNUSED;
+ } else {
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = this_board->n_dochan;
+ s->maxdata = 1;
+ s->len_chanlist = this_board->n_dochan;
+ s->range_table = &range_digital;
+ s->insn_bits = pcl818_do_insn_bits;
+ }
+
+ /* select 1/10MHz oscilator */
+ if ((it->options[3] == 0) || (it->options[3] == 10)) {
+ devpriv->i8253_osc_base = 100;
+ } else {
+ devpriv->i8253_osc_base = 1000;
+ }
+
+ /* max sampling speed */
+ devpriv->ns_min = this_board->ns_min;
+
+ if (!this_board->is_818) {
+ if ((it->options[6] == 1) || (it->options[6] == 100))
+ devpriv->ns_min = 10000; /* extended PCL718 to 100kHz DAC */
+ }
+
+ pcl818_reset(dev);
+
+ rt_printk("\n");
+
+ return 0;
+}
+
+/*
+==============================================================================
+ Removes device
+ */
+static int pcl818_detach(struct comedi_device * dev)
+{
+ // rt_printk("comedi%d: pcl818: remove\n", dev->minor);
+ free_resources(dev);
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcm3724.c b/drivers/staging/comedi/drivers/pcm3724.c
new file mode 100644
index 00000000000..a3ed3a0e855
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcm3724.c
@@ -0,0 +1,307 @@
+/*
+ comedi/drivers/pcm724.c
+
+ Drew Csillag <drew_csillag@yahoo.com>
+
+ hardware driver for Advantech card:
+ card: PCM-3724
+ driver: pcm3724
+
+ Options for PCM-3724
+ [0] - IO Base
+*/
+/*
+Driver: pcm3724
+Description: Advantech PCM-3724
+Author: Drew Csillag <drew_csillag@yahoo.com>
+Devices: [Advantech] PCM-3724 (pcm724)
+Status: tested
+
+This is driver for digital I/O boards PCM-3724 with 48 DIO.
+It needs 8255.o for operations and only immediate mode is supported.
+See the source for configuration details.
+
+Copy/pasted/hacked from pcm724.c
+*/
+/*
+ * check_driver overrides:
+ * struct comedi_insn
+ */
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+#include <linux/delay.h>
+
+#include "8255.h"
+
+#define PCM3724_SIZE 16
+#define SIZE_8255 4
+
+#define BUF_C0 0x1
+#define BUF_B0 0x2
+#define BUF_A0 0x4
+#define BUF_C1 0x8
+#define BUF_B1 0x10
+#define BUF_A1 0x20
+
+#define GATE_A0 0x4
+#define GATE_B0 0x2
+#define GATE_C0 0x1
+#define GATE_A1 0x20
+#define GATE_B1 0x10
+#define GATE_C1 0x8
+
+/* from 8255.c */
+#define CR_CW 0x80
+#define _8255_CR 3
+#define CR_B_IO 0x02
+#define CR_B_MODE 0x04
+#define CR_C_IO 0x09
+#define CR_A_IO 0x10
+#define CR_A_MODE(a) ((a)<<5)
+#define CR_CW 0x80
+
+static int pcm3724_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcm3724_detach(struct comedi_device * dev);
+
+struct pcm3724_board {
+ const char *name; // driver name
+ int dio; // num of DIO
+ int numofports; // num of 8255 subdevices
+ unsigned int IRQbits; // allowed interrupts
+ unsigned int io_range; // len of IO space
+};
+
+//used to track configured dios
+struct priv_pcm3724 {
+ int dio_1;
+ int dio_2;
+};
+
+static const struct pcm3724_board boardtypes[] = {
+ {"pcm3724", 48, 2, 0x00fc, PCM3724_SIZE,},
+};
+
+#define n_boardtypes (sizeof(boardtypes)/sizeof(struct pcm3724_board))
+#define this_board ((const struct pcm3724_board *)dev->board_ptr)
+
+static struct comedi_driver driver_pcm3724 = {
+ driver_name:"pcm3724",
+ module:THIS_MODULE,
+ attach:pcm3724_attach,
+ detach:pcm3724_detach,
+ board_name:&boardtypes[0].name,
+ num_names:n_boardtypes,
+ offset:sizeof(struct pcm3724_board),
+};
+
+COMEDI_INITCLEANUP(driver_pcm3724);
+
+// (setq c-basic-offset 8)
+
+static int subdev_8255_cb(int dir, int port, int data, unsigned long arg)
+{
+ unsigned long iobase = arg;
+ unsigned char inbres;
+ //printk("8255cb %d %d %d %lx\n", dir,port,data,arg);
+ if (dir) {
+ //printk("8255 cb outb(%x, %lx)\n", data, iobase+port);
+ outb(data, iobase + port);
+ return 0;
+ } else {
+ inbres = inb(iobase + port);
+ //printk("8255 cb inb(%lx) = %x\n", iobase+port, inbres);
+ return inbres;
+ }
+}
+
+static int compute_buffer(int config, int devno, struct comedi_subdevice * s)
+{
+ /* 1 in io_bits indicates output */
+ if (s->io_bits & 0x0000ff) {
+ if (devno == 0) {
+ config |= BUF_A0;
+ } else {
+ config |= BUF_A1;
+ }
+ }
+ if (s->io_bits & 0x00ff00) {
+ if (devno == 0) {
+ config |= BUF_B0;
+ } else {
+ config |= BUF_B1;
+ }
+ }
+ if (s->io_bits & 0xff0000) {
+ if (devno == 0) {
+ config |= BUF_C0;
+ } else {
+ config |= BUF_C1;
+ }
+ }
+ return config;
+}
+
+static void do_3724_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ int chanspec)
+{
+ int config;
+ int buffer_config;
+ unsigned long port_8255_cfg;
+
+ config = CR_CW;
+ buffer_config = 0;
+
+ /* 1 in io_bits indicates output, 1 in config indicates input */
+ if (!(s->io_bits & 0x0000ff)) {
+ config |= CR_A_IO;
+ }
+ if (!(s->io_bits & 0x00ff00)) {
+ config |= CR_B_IO;
+ }
+ if (!(s->io_bits & 0xff0000)) {
+ config |= CR_C_IO;
+ }
+
+ buffer_config = compute_buffer(0, 0, dev->subdevices);
+ buffer_config = compute_buffer(buffer_config, 1, (dev->subdevices) + 1);
+
+ if (s == dev->subdevices) {
+ port_8255_cfg = dev->iobase + _8255_CR;
+ } else {
+ port_8255_cfg = dev->iobase + SIZE_8255 + _8255_CR;
+ }
+ outb(buffer_config, dev->iobase + 8); /* update buffer register */
+ //printk("pcm3724 buffer_config (%lx) %d, %x\n", dev->iobase + _8255_CR, chanspec, buffer_config);
+ outb(config, port_8255_cfg);
+}
+
+static void enable_chan(struct comedi_device * dev, struct comedi_subdevice * s, int chanspec)
+{
+ unsigned int mask;
+ int gatecfg;
+ struct priv_pcm3724 *priv;
+
+ gatecfg = 0;
+ priv = (struct priv_pcm3724 *) (dev->private);
+
+ mask = 1 << CR_CHAN(chanspec);
+ if (s == dev->subdevices) { // subdev 0
+ priv->dio_1 |= mask;
+ } else { //subdev 1
+ priv->dio_2 |= mask;
+ }
+ if (priv->dio_1 & 0xff0000) {
+ gatecfg |= GATE_C0;
+ }
+ if (priv->dio_1 & 0xff00) {
+ gatecfg |= GATE_B0;
+ }
+ if (priv->dio_1 & 0xff) {
+ gatecfg |= GATE_A0;
+ }
+ if (priv->dio_2 & 0xff0000) {
+ gatecfg |= GATE_C1;
+ }
+ if (priv->dio_2 & 0xff00) {
+ gatecfg |= GATE_B1;
+ }
+ if (priv->dio_2 & 0xff) {
+ gatecfg |= GATE_A1;
+ }
+ // printk("gate control %x\n", gatecfg);
+ outb(gatecfg, dev->iobase + 9);
+}
+
+/* overriding the 8255 insn config */
+static int subdev_3724_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ unsigned int mask;
+ unsigned int bits;
+
+ mask = 1 << CR_CHAN(insn->chanspec);
+ if (mask & 0x0000ff) {
+ bits = 0x0000ff;
+ } else if (mask & 0x00ff00) {
+ bits = 0x00ff00;
+ } else if (mask & 0x0f0000) {
+ bits = 0x0f0000;
+ } else {
+ bits = 0xf00000;
+ }
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~bits;
+ break;
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= bits;
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] = (s->io_bits & bits) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ do_3724_config(dev, s, insn->chanspec);
+ enable_chan(dev, s, insn->chanspec);
+ return 1;
+}
+
+static int pcm3724_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned long iobase;
+ unsigned int iorange;
+ int ret, i, n_subdevices;
+
+ iobase = it->options[0];
+ iorange = this_board->io_range;
+ if ((ret = alloc_private(dev, sizeof(struct priv_pcm3724))) < 0)
+ return -ENOMEM;
+
+ ((struct priv_pcm3724 *) (dev->private))->dio_1 = 0;
+ ((struct priv_pcm3724 *) (dev->private))->dio_2 = 0;
+
+ printk("comedi%d: pcm3724: board=%s, 0x%03lx ", dev->minor,
+ this_board->name, iobase);
+ if (!iobase || !request_region(iobase, iorange, "pcm3724")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+ dev->iobase = iobase;
+ dev->board_name = this_board->name;
+ printk("\n");
+
+ n_subdevices = this_board->numofports;
+
+ if ((ret = alloc_subdevices(dev, n_subdevices)) < 0)
+ return ret;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev_8255_init(dev, dev->subdevices + i, subdev_8255_cb,
+ (unsigned long)(dev->iobase + SIZE_8255 * i));
+ ((dev->subdevices) + i)->insn_config = subdev_3724_insn_config;
+ };
+ return 0;
+}
+
+static int pcm3724_detach(struct comedi_device * dev)
+{
+ int i;
+
+ if (dev->subdevices) {
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev_8255_cleanup(dev, dev->subdevices + i);
+ }
+ }
+ if (dev->iobase) {
+ release_region(dev->iobase, this_board->io_range);
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcm3730.c b/drivers/staging/comedi/drivers/pcm3730.c
new file mode 100644
index 00000000000..1de555fe645
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcm3730.c
@@ -0,0 +1,152 @@
+/*
+ * comedi/drivers/pcm3730.c
+ * Driver for PCM3730 and clones
+ * Blaine Lee
+ * from pcl725 by David S.
+ */
+/*
+Driver: pcm3730
+Description: PCM3730
+Author: Blaine Lee
+Devices: [Advantech] PCM-3730 (pcm3730)
+Status: unknown
+
+Configuration options:
+ [0] - I/O port base
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCM3730_SIZE 4 // consecutive io port addresses
+
+#define PCM3730_DOA 0 // offsets for each port
+#define PCM3730_DOB 2
+#define PCM3730_DOC 3
+#define PCM3730_DIA 0
+#define PCM3730_DIB 2
+#define PCM3730_DIC 3
+
+static int pcm3730_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcm3730_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcm3730 = {
+ driver_name:"pcm3730",
+ module:THIS_MODULE,
+ attach:pcm3730_attach,
+ detach:pcm3730_detach,
+};
+
+COMEDI_INITCLEANUP(driver_pcm3730);
+
+static int pcm3730_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ outb(s->state, dev->iobase + (unsigned long)(s->private));
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+static int pcm3730_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ data[1] = inb(dev->iobase + (unsigned long)(s->private));
+ return 2;
+}
+
+static int pcm3730_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcm3730: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCM3730_SIZE, "pcm3730")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+ dev->board_name = "pcm3730";
+ dev->iobase = dev->iobase;
+ dev->irq = 0;
+
+ if (alloc_subdevices(dev, 6) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_do_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DOA;
+
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_do_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DOB;
+
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_do_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DOC;
+
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DIA;
+
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DIB;
+
+ s = dev->subdevices + 5;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->maxdata = 1;
+ s->n_chan = 8;
+ s->insn_bits = pcm3730_di_insn_bits;
+ s->range_table = &range_digital;
+ s->private = (void *)PCM3730_DIC;
+
+ printk("\n");
+
+ return 0;
+}
+
+static int pcm3730_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcm3730: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, PCM3730_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcmad.c b/drivers/staging/comedi/drivers/pcmad.c
new file mode 100644
index 00000000000..fc2a73d97c2
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmad.c
@@ -0,0 +1,173 @@
+/*
+ comedi/drivers/pcmad.c
+ Hardware driver for Winsystems PCM-A/D12 and PCM-A/D16
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000,2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: pcmad
+Description: Winsystems PCM-A/D12, PCM-A/D16
+Author: ds
+Devices: [Winsystems] PCM-A/D12 (pcmad12), PCM-A/D16 (pcmad16)
+Status: untested
+
+This driver was written on a bet that I couldn't write a driver
+in less than 2 hours. I won the bet, but never got paid. =(
+
+Configuration options:
+ [0] - I/O port base
+ [1] - unused
+ [2] - Analog input reference
+ 0 = single ended
+ 1 = differential
+ [3] - Analog input encoding (must match jumpers)
+ 0 = straight binary
+ 1 = two's complement
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define PCMAD_SIZE 4
+
+#define PCMAD_STATUS 0
+#define PCMAD_LSB 1
+#define PCMAD_MSB 2
+#define PCMAD_CONVERT 1
+
+struct pcmad_board_struct {
+ const char *name;
+ int n_ai_bits;
+};
+static const struct pcmad_board_struct pcmad_boards[] = {
+ {
+ name: "pcmad12",
+ n_ai_bits:12,
+ },
+ {
+ name: "pcmad16",
+ n_ai_bits:16,
+ },
+};
+
+#define this_board ((const struct pcmad_board_struct *)(dev->board_ptr))
+#define n_pcmad_boards (sizeof(pcmad_boards)/sizeof(pcmad_boards[0]))
+
+struct pcmad_priv_struct {
+ int differential;
+ int twos_comp;
+};
+#define devpriv ((struct pcmad_priv_struct *)dev->private)
+
+static int pcmad_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmad_detach(struct comedi_device * dev);
+static struct comedi_driver driver_pcmad = {
+ driver_name:"pcmad",
+ module:THIS_MODULE,
+ attach:pcmad_attach,
+ detach:pcmad_detach,
+ board_name:&pcmad_boards[0].name,
+ num_names:n_pcmad_boards,
+ offset:sizeof(pcmad_boards[0]),
+};
+
+COMEDI_INITCLEANUP(driver_pcmad);
+
+#define TIMEOUT 100
+
+static int pcmad_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan;
+ int n;
+
+ chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ outb(chan, dev->iobase + PCMAD_CONVERT);
+
+ for (i = 0; i < TIMEOUT; i++) {
+ if ((inb(dev->iobase + PCMAD_STATUS) & 0x3) == 0x3)
+ break;
+ }
+ data[n] = inb(dev->iobase + PCMAD_LSB);
+ data[n] |= (inb(dev->iobase + PCMAD_MSB) << 8);
+
+ if (devpriv->twos_comp) {
+ data[n] ^= (1 << (this_board->n_ai_bits - 1));
+ }
+ }
+
+ return n;
+}
+
+/*
+ * options:
+ * 0 i/o base
+ * 1 unused
+ * 2 0=single ended 1=differential
+ * 3 0=straight binary 1=two's comp
+ */
+static int pcmad_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: pcmad: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, PCMAD_SIZE, "pcmad")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ if ((ret = alloc_subdevices(dev, 1)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct pcmad_priv_struct))) < 0)
+ return ret;
+
+ dev->board_name = this_board->name;
+
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | AREF_GROUND;
+ s->n_chan = 16; /* XXX */
+ s->len_chanlist = 1;
+ s->insn_read = pcmad_ai_insn_read;
+ s->maxdata = (1 << this_board->n_ai_bits) - 1;
+ s->range_table = &range_unknown;
+
+ return 0;
+}
+
+static int pcmad_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: pcmad: remove\n", dev->minor);
+
+ if (dev->irq) {
+ free_irq(dev->irq, dev);
+ }
+ if (dev->iobase)
+ release_region(dev->iobase, PCMAD_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/pcmda12.c b/drivers/staging/comedi/drivers/pcmda12.c
new file mode 100644
index 00000000000..2a1ff465602
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmda12.c
@@ -0,0 +1,306 @@
+/*
+ comedi/drivers/pcmda12.c
+ Driver for Winsystems PC-104 based PCM-D/A-12 8-channel AO board.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: pcmda12
+Description: A driver for the Winsystems PCM-D/A-12
+Devices: [Winsystems] PCM-D/A-12 (pcmda12)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Fri, 13 Jan 2006 12:01:01 -0500
+Status: works
+
+A driver for the relatively straightforward-to-program PCM-D/A-12.
+This board doesn't support commands, and the only way to set its
+analog output range is to jumper the board. As such,
+comedi_data_write() ignores the range value specified.
+
+The board uses 16 consecutive I/O addresses starting at the I/O port
+base address. Each address corresponds to the LSB then MSB of a
+particular channel from 0-7.
+
+Note that the board is not ISA-PNP capable and thus
+needs the I/O port comedi_config parameter.
+
+Note that passing a nonzero value as the second config option will
+enable "simultaneous xfer" mode for this board, in which AO writes
+will not take effect until a subsequent read of any AO channel. This
+is so that one can speed up programming by preloading all AO registers
+with values before simultaneously setting them to take effect with one
+read command.
+
+Configuration Options:
+ [0] - I/O port base address
+ [1] - Do Simultaneous Xfer (see description)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/pci.h> /* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CHANS 8
+#define IOSIZE 16
+#define LSB(x) ((unsigned char)((x) & 0xff))
+#define MSB(x) ((unsigned char)((((unsigned short)(x))>>8) & 0xff))
+#define LSB_PORT(chan) (dev->iobase + (chan)*2)
+#define MSB_PORT(chan) (LSB_PORT(chan)+1)
+#define BITS 12
+
+/*
+ * Bords
+ */
+struct pcmda12_board {
+ const char *name;
+};
+
+/* note these have no effect and are merely here for reference..
+ these are configured by jumpering the board! */
+static const struct comedi_lrange pcmda12_ranges = {
+ 3,
+ {
+ UNI_RANGE(5), UNI_RANGE(10), BIP_RANGE(5)
+ }
+};
+
+static const struct pcmda12_board pcmda12_boards[] = {
+ {
+ name: "pcmda12",
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmda12_board *)dev->board_ptr)
+
+struct pcmda12_private {
+
+ unsigned int ao_readback[CHANS];
+ int simultaneous_xfer_mode;
+};
+
+
+#define devpriv ((struct pcmda12_private *)(dev->private))
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmda12_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmda12_detach(struct comedi_device * dev);
+
+static void zero_chans(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+ driver_name:"pcmda12",
+ module:THIS_MODULE,
+ attach:pcmda12_attach,
+ detach:pcmda12_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcmda12_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&pcmda12_boards[0].name,
+ offset:sizeof(struct pcmda12_board),
+ num_names:sizeof(pcmda12_boards) / sizeof(struct pcmda12_board),
+};
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmda12_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: %s: io: %lx %s ", dev->minor, driver.driver_name,
+ iobase, it->options[1] ? "simultaneous xfer mode enabled" : "");
+
+ if (!request_region(iobase, IOSIZE, driver.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcmda12_private)) < 0) {
+ printk("cannot allocate private data structure\n");
+ return -ENOMEM;
+ }
+
+ devpriv->simultaneous_xfer_mode = it->options[1];
+
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ *
+ * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+ * 96-channel version of the board.
+ */
+ if (alloc_subdevices(dev, 1) < 0) {
+ printk("cannot allocate subdevice data structures\n");
+ return -ENOMEM;
+ }
+
+ s = dev->subdevices;
+ s->private = NULL;
+ s->maxdata = (0x1 << BITS) - 1;
+ s->range_table = &pcmda12_ranges;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = CHANS;
+ s->insn_write = &ao_winsn;
+ s->insn_read = &ao_rinsn;
+
+ zero_chans(dev); /* clear out all the registers, basically */
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmda12_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+ if (dev->iobase)
+ release_region(dev->iobase, IOSIZE);
+ return 0;
+}
+
+static void zero_chans(struct comedi_device * dev)
+{ /* sets up an
+ ASIC chip to defaults */
+ int i;
+ for (i = 0; i < CHANS; ++i) {
+/* /\* do this as one instruction?? *\/ */
+/* outw(0, LSB_PORT(chan)); */
+ outb(0, LSB_PORT(i));
+ outb(0, MSB_PORT(i));
+ }
+ inb(LSB_PORT(0)); /* update chans. */
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; ++i) {
+
+/* /\* do this as one instruction?? *\/ */
+/* outw(data[i], LSB_PORT(chan)); */
+
+ /* Need to do this as two instructions due to 8-bit bus?? */
+ /* first, load the low byte */
+ outb(LSB(data[i]), LSB_PORT(chan));
+ /* next, write the high byte */
+ outb(MSB(data[i]), MSB_PORT(chan));
+
+ /* save shadow register */
+ devpriv->ao_readback[chan] = data[i];
+
+ if (!devpriv->simultaneous_xfer_mode)
+ inb(LSB_PORT(chan));
+ }
+
+ /* return the number of samples written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+
+ Usually this means copying a value stored in devpriv->ao_readback.
+ However, since this driver supports simultaneous xfer then sometimes
+ this function actually accomplishes work.
+
+ Simultaneaous xfer mode is accomplished by loading ALL the values
+ you want for AO in all the channels, then READing off one of the AO
+ registers to initiate the instantaneous simultaneous update of all
+ DAC outputs, which makes all AO channels update simultaneously.
+ This is useful for some control applications, I would imagine.
+*/
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ if (devpriv->simultaneous_xfer_mode)
+ inb(LSB_PORT(chan));
+ /* read back shadow register */
+ data[i] = devpriv->ao_readback[chan];
+ }
+
+ return i;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/pcmmio.c b/drivers/staging/comedi/drivers/pcmmio.c
new file mode 100644
index 00000000000..01e40f1b562
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmmio.c
@@ -0,0 +1,1333 @@
+/*
+ comedi/drivers/pcmmio.c
+ Driver for Winsystems PC-104 based multifunction IO board.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2007 Calin A. Culianu <calin@ajvar.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: pcmmio
+Description: A driver for the PCM-MIO multifunction board
+Devices: [Winsystems] PCM-MIO (pcmmio)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Wed, May 16 2007 16:21:10 -0500
+Status: works
+
+A driver for the relatively new PCM-MIO multifunction board from
+Winsystems. This board is a PC-104 based I/O board. It contains
+four subdevices:
+ subdevice 0 - 16 channels of 16-bit AI
+ subdevice 1 - 8 channels of 16-bit AO
+ subdevice 2 - first 24 channels of the 48 channel of DIO (with edge-triggered interrupt support)
+ subdevice 3 - last 24 channels of the 48 channel DIO (no interrupt support for this bank of channels)
+
+ Some notes:
+
+ Synchronous reads and writes are the only things implemented for AI and AO,
+ even though the hardware itself can do streaming acquisition, etc. Anyone
+ want to add asynchronous I/O for AI/AO as a feature? Be my guest...
+
+ Asynchronous I/O for the DIO subdevices *is* implemented, however! They are
+ basically edge-triggered interrupts for any configuration of the first
+ 24 DIO-lines.
+
+ Also note that this interrupt support is untested.
+
+ A few words about edge-detection IRQ support (commands on DIO):
+
+ * To use edge-detection IRQ support for the DIO subdevice, pass the IRQ
+ of the board to the comedi_config command. The board IRQ is not jumpered
+ but rather configured through software, so any IRQ from 1-15 is OK.
+
+ * Due to the genericity of the comedi API, you need to create a special
+ comedi_command in order to use edge-triggered interrupts for DIO.
+
+ * Use comedi_commands with TRIG_NOW. Your callback will be called each
+ time an edge is detected on the specified DIO line(s), and the data
+ values will be two sample_t's, which should be concatenated to form
+ one 32-bit unsigned int. This value is the mask of channels that had
+ edges detected from your channel list. Note that the bits positions
+ in the mask correspond to positions in your chanlist when you
+ specified the command and *not* channel id's!
+
+ * To set the polarity of the edge-detection interrupts pass a nonzero value
+ for either CR_RANGE or CR_AREF for edge-up polarity, or a zero
+ value for both CR_RANGE and CR_AREF if you want edge-down polarity.
+
+Configuration Options:
+ [0] - I/O port base address
+ [1] - IRQ (optional -- for edge-detect interrupt support only, leave out if you don't need this feature)
+*/
+
+#include "../comedidev.h"
+#include <linux/pci.h> /* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+
+/* This stuff is all from pcmuio.c -- it refers to the DIO subdevices only */
+#define CHANS_PER_PORT 8
+#define PORTS_PER_ASIC 6
+#define INTR_PORTS_PER_ASIC 3
+#define MAX_CHANS_PER_SUBDEV 24 /* number of channels per comedi subdevice */
+#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
+#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
+#define INTR_CHANS_PER_ASIC 24
+#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
+#define MAX_DIO_CHANS (PORTS_PER_ASIC*1*CHANS_PER_PORT)
+#define MAX_ASICS (MAX_DIO_CHANS/CHANS_PER_ASIC)
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CALC_N_DIO_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/)
+/* IO Memory sizes */
+#define ASIC_IOSIZE (0x0B)
+#define PCMMIO48_IOSIZE ASIC_IOSIZE
+
+/* Some offsets - these are all in the 16byte IO memory offset from
+ the base address. Note that there is a paging scheme to swap out
+ offsets 0x8-0xA using the PAGELOCK register. See the table below.
+
+ Register(s) Pages R/W? Description
+ --------------------------------------------------------------
+ REG_PORTx All R/W Read/Write/Configure IO
+ REG_INT_PENDING All ReadOnly Quickly see which INT_IDx has int.
+ REG_PAGELOCK All WriteOnly Select a page
+ REG_POLx Pg. 1 only WriteOnly Select edge-detection polarity
+ REG_ENABx Pg. 2 only WriteOnly Enable/Disable edge-detect. int.
+ REG_INT_IDx Pg. 3 only R/W See which ports/bits have ints.
+ */
+#define REG_PORT0 0x0
+#define REG_PORT1 0x1
+#define REG_PORT2 0x2
+#define REG_PORT3 0x3
+#define REG_PORT4 0x4
+#define REG_PORT5 0x5
+#define REG_INT_PENDING 0x6
+#define REG_PAGELOCK 0x7 /* page selector register, upper 2 bits select a page
+ and bits 0-5 are used to 'lock down' a particular
+ port above to make it readonly. */
+#define REG_POL0 0x8
+#define REG_POL1 0x9
+#define REG_POL2 0xA
+#define REG_ENAB0 0x8
+#define REG_ENAB1 0x9
+#define REG_ENAB2 0xA
+#define REG_INT_ID0 0x8
+#define REG_INT_ID1 0x9
+#define REG_INT_ID2 0xA
+
+#define NUM_PAGED_REGS 3
+#define NUM_PAGES 4
+#define FIRST_PAGED_REG 0x8
+#define REG_PAGE_BITOFFSET 6
+#define REG_LOCK_BITOFFSET 0
+#define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
+#define REG_LOCK_MASK ~(REG_PAGE_MASK)
+#define PAGE_POL 1
+#define PAGE_ENAB 2
+#define PAGE_INT_ID 3
+
+typedef int (*comedi_insn_fn_t) (struct comedi_device *, struct comedi_subdevice *,
+ struct comedi_insn *, unsigned int *);
+
+static int ai_rinsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+static int ao_rinsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+static int ao_winsn(struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcmmio_board {
+ const char *name;
+ const int dio_num_asics;
+ const int dio_num_ports;
+ const int total_iosize;
+ const int ai_bits;
+ const int ao_bits;
+ const int n_ai_chans;
+ const int n_ao_chans;
+ const struct comedi_lrange *ai_range_table, *ao_range_table;
+ comedi_insn_fn_t ai_rinsn, ao_rinsn, ao_winsn;
+};
+
+static const struct comedi_lrange ranges_ai =
+ { 4, {RANGE(-5., 5.), RANGE(-10., 10.), RANGE(0., 5.), RANGE(0.,
+ 10.)}
+};
+
+static const struct comedi_lrange ranges_ao =
+ { 6, {RANGE(0., 5.), RANGE(0., 10.), RANGE(-5., 5.), RANGE(-10., 10.),
+ RANGE(-2.5, 2.5), RANGE(-2.5, 7.5)}
+};
+
+static const struct pcmmio_board pcmmio_boards[] = {
+ {
+ name: "pcmmio",
+ dio_num_asics:1,
+ dio_num_ports:6,
+ total_iosize:32,
+ ai_bits: 16,
+ ao_bits: 16,
+ n_ai_chans:16,
+ n_ao_chans:8,
+ ai_range_table:&ranges_ai,
+ ao_range_table:&ranges_ao,
+ ai_rinsn:ai_rinsn,
+ ao_rinsn:ao_rinsn,
+ ao_winsn:ao_winsn},
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmmio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this subdevice. */
+struct pcmmio_subdev_private {
+
+ union {
+ /* for DIO: mapping of halfwords (bytes) in port/chanarray to iobase */
+ unsigned long iobases[PORTS_PER_SUBDEV];
+
+ /* for AI/AO */
+ unsigned long iobase;
+ };
+ union {
+ struct {
+
+ /* The below is only used for intr subdevices */
+ struct {
+ int asic; /* if non-negative, this subdev has an interrupt asic */
+ int first_chan; /* if nonnegative, the first channel id for
+ interrupts. */
+ int num_asic_chans; /* the number of asic channels in this subdev
+ that have interrutps */
+ int asic_chan; /* if nonnegative, the first channel id with
+ respect to the asic that has interrupts */
+ int enabled_mask; /* subdev-relative channel mask for channels
+ we are interested in */
+ int active;
+ int stop_count;
+ int continuous;
+ spinlock_t spinlock;
+ } intr;
+ } dio;
+ struct {
+ unsigned int shadow_samples[8]; /* the last unsigned int data written */
+ } ao;
+ };
+};
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pcmmio_private {
+ /* stuff for DIO */
+ struct {
+ unsigned char pagelock; /* current page and lock */
+ unsigned char pol[NUM_PAGED_REGS]; /* shadow of POLx registers */
+ unsigned char enab[NUM_PAGED_REGS]; /* shadow of ENABx registers */
+ int num;
+ unsigned long iobase;
+ unsigned int irq;
+ spinlock_t spinlock;
+ } asics[MAX_ASICS];
+ struct pcmmio_subdev_private *sprivs;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcmmio_private *)dev->private)
+#define subpriv ((struct pcmmio_subdev_private *)s->private)
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmmio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmmio_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+ driver_name:"pcmmio",
+ module:THIS_MODULE,
+ attach:pcmmio_attach,
+ detach:pcmmio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcmmio_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&pcmmio_boards[0].name,
+ offset:sizeof(struct pcmmio_board),
+ num_names:sizeof(pcmmio_boards) / sizeof(struct pcmmio_board),
+};
+
+static int pcmmio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcmmio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static irqreturn_t interrupt_pcmmio(int irq, void *d PT_REGS_ARG);
+static void pcmmio_stop_intr(struct comedi_device *, struct comedi_subdevice *);
+static int pcmmio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmmio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmmio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+
+/* some helper functions to deal with specifics of this device's registers */
+static void init_asics(struct comedi_device * dev); /* sets up/clears ASIC chips to defaults */
+static void switch_page(struct comedi_device * dev, int asic, int page);
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port);
+static void unlock_port(struct comedi_device * dev, int asic, int port);
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmmio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int sdev_no, chans_left, n_dio_subdevs, n_subdevs, port, asic,
+ thisasic_chanct = 0;
+ unsigned long iobase;
+ unsigned int irq[MAX_ASICS];
+
+ iobase = it->options[0];
+ irq[0] = it->options[1];
+
+ printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
+ iobase);
+
+ dev->iobase = iobase;
+
+ if (!iobase || !request_region(iobase,
+ thisboard->total_iosize, driver.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcmmio_private)) < 0) {
+ printk("cannot allocate private data structure\n");
+ return -ENOMEM;
+ }
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ devpriv->asics[asic].num = asic;
+ devpriv->asics[asic].iobase =
+ dev->iobase + 16 + asic * ASIC_IOSIZE;
+ devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
+ this function when we
+ comedi_request_irqs */
+ spin_lock_init(&devpriv->asics[asic].spinlock);
+ }
+
+ chans_left = CHANS_PER_ASIC * thisboard->dio_num_asics;
+ n_dio_subdevs = CALC_N_DIO_SUBDEVS(chans_left);
+ n_subdevs = n_dio_subdevs + 2;
+ devpriv->sprivs =
+ kcalloc(n_subdevs, sizeof(struct pcmmio_subdev_private), GFP_KERNEL);
+ if (!devpriv->sprivs) {
+ printk("cannot allocate subdevice private data structures\n");
+ return -ENOMEM;
+ }
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ *
+ * Allocate 1 AI + 1 AO + 2 DIO subdevs (24 lines per DIO)
+ */
+ if (alloc_subdevices(dev, n_subdevs) < 0) {
+ printk("cannot allocate subdevice data structures\n");
+ return -ENOMEM;
+ }
+
+ /* First, AI */
+ sdev_no = 0;
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = thisboard->ai_range_table;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+ s->type = COMEDI_SUBD_AI;
+ s->n_chan = thisboard->n_ai_chans;
+ s->len_chanlist = s->n_chan;
+ s->insn_read = thisboard->ai_rinsn;
+ subpriv->iobase = dev->iobase + 0;
+ /* initialize the resource enable register by clearing it */
+ outb(0, subpriv->iobase + 3);
+ outb(0, subpriv->iobase + 4 + 3);
+
+ /* Next, AO */
+ ++sdev_no;
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = (1 << thisboard->ao_bits) - 1;
+ s->range_table = thisboard->ao_range_table;
+ s->subdev_flags = SDF_READABLE;
+ s->type = COMEDI_SUBD_AO;
+ s->n_chan = thisboard->n_ao_chans;
+ s->len_chanlist = s->n_chan;
+ s->insn_read = thisboard->ao_rinsn;
+ s->insn_write = thisboard->ao_winsn;
+ subpriv->iobase = dev->iobase + 8;
+ /* initialize the resource enable register by clearing it */
+ outb(0, subpriv->iobase + 3);
+ outb(0, subpriv->iobase + 4 + 3);
+
+ ++sdev_no;
+ port = 0;
+ asic = 0;
+ for (; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
+ int byte_no;
+
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->type = COMEDI_SUBD_DIO;
+ s->insn_bits = pcmmio_dio_insn_bits;
+ s->insn_config = pcmmio_dio_insn_config;
+ s->n_chan = MIN(chans_left, MAX_CHANS_PER_SUBDEV);
+ subpriv->dio.intr.asic = -1;
+ subpriv->dio.intr.first_chan = -1;
+ subpriv->dio.intr.asic_chan = -1;
+ subpriv->dio.intr.num_asic_chans = -1;
+ subpriv->dio.intr.active = 0;
+ s->len_chanlist = 1;
+
+ /* save the ioport address for each 'port' of 8 channels in the
+ subdevice */
+ for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
+ if (port >= PORTS_PER_ASIC) {
+ port = 0;
+ ++asic;
+ thisasic_chanct = 0;
+ }
+ subpriv->iobases[byte_no] =
+ devpriv->asics[asic].iobase + port;
+
+ if (thisasic_chanct <
+ CHANS_PER_PORT * INTR_PORTS_PER_ASIC
+ && subpriv->dio.intr.asic < 0) {
+ /* this is an interrupt subdevice, so setup the struct */
+ subpriv->dio.intr.asic = asic;
+ subpriv->dio.intr.active = 0;
+ subpriv->dio.intr.stop_count = 0;
+ subpriv->dio.intr.first_chan = byte_no * 8;
+ subpriv->dio.intr.asic_chan = thisasic_chanct;
+ subpriv->dio.intr.num_asic_chans =
+ s->n_chan -
+ subpriv->dio.intr.first_chan;
+ s->cancel = pcmmio_cancel;
+ s->do_cmd = pcmmio_cmd;
+ s->do_cmdtest = pcmmio_cmdtest;
+ s->len_chanlist =
+ subpriv->dio.intr.num_asic_chans;
+ }
+ thisasic_chanct += CHANS_PER_PORT;
+ }
+ spin_lock_init(&subpriv->dio.intr.spinlock);
+
+ chans_left -= s->n_chan;
+
+ if (!chans_left) {
+ asic = 0; /* reset the asic to our first asic, to do intr subdevs */
+ port = 0;
+ }
+
+ }
+
+ init_asics(dev); /* clear out all the registers, basically */
+
+ for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
+ if (irq[asic]
+ && comedi_request_irq(irq[asic], interrupt_pcmmio,
+ IRQF_SHARED, thisboard->name, dev)) {
+ int i;
+ /* unroll the allocated irqs.. */
+ for (i = asic - 1; i >= 0; --i) {
+ comedi_free_irq(irq[i], dev);
+ devpriv->asics[i].irq = irq[i] = 0;
+ }
+ irq[asic] = 0;
+ }
+ devpriv->asics[asic].irq = irq[asic];
+ }
+
+ dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
+ irqs.. */
+
+ if (irq[0]) {
+ printk("irq: %u ", irq[0]);
+ if (irq[1] && thisboard->dio_num_asics == 2)
+ printk("second ASIC irq: %u ", irq[1]);
+ } else {
+ printk("(IRQ mode disabled) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmmio_detach(struct comedi_device * dev)
+{
+ int i;
+
+ printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+ if (dev->iobase)
+ release_region(dev->iobase, thisboard->total_iosize);
+
+ for (i = 0; i < MAX_ASICS; ++i) {
+ if (devpriv && devpriv->asics[i].irq)
+ comedi_free_irq(devpriv->asics[i].irq, dev);
+ }
+
+ if (devpriv && devpriv->sprivs)
+ kfree(devpriv->sprivs);
+
+ return 0;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pcmmio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int byte_no;
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* NOTE:
+ reading a 0 means this channel was high
+ writine a 0 sets the channel high
+ reading a 1 means this channel was low
+ writing a 1 means set this channel low
+
+ Therefore everything is always inverted. */
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("write mask: %08x data: %08x\n", data[0], data[1]);
+#endif
+
+ s->state = 0;
+
+ for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
+ /* address of 8-bit port */
+ unsigned long ioaddr = subpriv->iobases[byte_no],
+ /* bit offset of port in 32-bit doubleword */
+ offset = byte_no * 8;
+ /* this 8-bit port's data */
+ unsigned char byte = 0,
+ /* The write mask for this port (if any) */
+ write_mask_byte = (data[0] >> offset) & 0xff,
+ /* The data byte for this port */
+ data_byte = (data[1] >> offset) & 0xff;
+
+ byte = inb(ioaddr); /* read all 8-bits for this port */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
+#endif
+
+ if (write_mask_byte) {
+ /* this byte has some write_bits -- so set the output lines */
+ byte &= ~write_mask_byte; /* clear bits for write mask */
+ byte |= ~data_byte & write_mask_byte; /* set to inverted data_byte */
+ /* Write out the new digital output state */
+ outb(byte, ioaddr);
+ }
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("data_out_byte %02x\n", (unsigned)byte);
+#endif
+ /* save the digital input lines for this byte.. */
+ s->state |= ((unsigned int)byte) << offset;
+ }
+
+ /* now return the DIO lines to data[1] - note they came inverted! */
+ data[1] = ~s->state;
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("s->state %08x data_out %08x\n", s->state, data[1]);
+#endif
+
+ return 2;
+}
+
+/* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+static int pcmmio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
+ chan % 8;
+ unsigned long ioaddr;
+ unsigned char byte;
+
+ /* Compute ioaddr for this channel */
+ ioaddr = subpriv->iobases[byte_no];
+
+ /* NOTE:
+ writing a 0 an IO channel's bit sets the channel to INPUT
+ and pulls the line high as well
+
+ writing a 1 to an IO channel's bit pulls the line low
+
+ All channels are implicitly always in OUTPUT mode -- but when
+ they are high they can be considered to be in INPUT mode..
+
+ Thus, we only force channels low if the config request was INPUT,
+ otherwise we do nothing to the hardware. */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ /* save to io_bits -- don't actually do anything since
+ all input channels are also output channels... */
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ /* write a 0 to the actual register representing the channel
+ to set it to 'input'. 0 means "float high". */
+ byte = inb(ioaddr);
+ byte &= ~(1 << bit_no);
+ /**< set input channel to '0' */
+
+ /* write out byte -- this is the only time we actually affect the
+ hardware as all channels are implicitly output -- but input
+ channels are set to float-high */
+ outb(byte, ioaddr);
+
+ /* save to io_bits */
+ s->io_bits &= ~(1 << chan);
+ break;
+
+ case INSN_CONFIG_DIO_QUERY:
+ /* retreive from shadow register */
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return insn->n;
+}
+
+static void init_asics(struct comedi_device * dev)
+{ /* sets up an
+ ASIC chip to defaults */
+ int asic;
+
+ for (asic = 0; asic < thisboard->dio_num_asics; ++asic) {
+ int port, page;
+ unsigned long baseaddr = devpriv->asics[asic].iobase;
+
+ switch_page(dev, asic, 0); /* switch back to page 0 */
+
+ /* first, clear all the DIO port bits */
+ for (port = 0; port < PORTS_PER_ASIC; ++port)
+ outb(0, baseaddr + REG_PORT0 + port);
+
+ /* Next, clear all the paged registers for each page */
+ for (page = 1; page < NUM_PAGES; ++page) {
+ int reg;
+ /* now clear all the paged registers */
+ switch_page(dev, asic, page);
+ for (reg = FIRST_PAGED_REG;
+ reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+ outb(0, baseaddr + reg);
+ }
+
+ /* DEBUG set rising edge interrupts on port0 of both asics */
+ /*switch_page(dev, asic, PAGE_POL);
+ outb(0xff, baseaddr + REG_POL0);
+ switch_page(dev, asic, PAGE_ENAB);
+ outb(0xff, baseaddr + REG_ENAB0); */
+ /* END DEBUG */
+
+ switch_page(dev, asic, 0); /* switch back to default page 0 */
+
+ }
+}
+
+static void switch_page(struct comedi_device * dev, int asic, int page)
+{
+ if (asic < 0 || asic >= thisboard->dio_num_asics)
+ return; /* paranoia */
+ if (page < 0 || page >= NUM_PAGES)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK;
+ devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET;
+
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ devpriv->asics[asic].iobase + REG_PAGELOCK);
+}
+
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->dio_num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock |= 0x1 << port;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ devpriv->asics[asic].iobase + REG_PAGELOCK);
+ return;
+}
+
+static void unlock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->dio_num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+ devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ devpriv->asics[asic].iobase + REG_PAGELOCK);
+}
+#endif /* notused */
+
+static irqreturn_t interrupt_pcmmio(int irq, void *d PT_REGS_ARG)
+{
+ int asic, got1 = 0;
+ struct comedi_device *dev = (struct comedi_device *) d;
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ if (irq == devpriv->asics[asic].irq) {
+ unsigned long flags;
+ unsigned triggered = 0;
+ unsigned long iobase = devpriv->asics[asic].iobase;
+ /* it is an interrupt for ASIC #asic */
+ unsigned char int_pend;
+
+ comedi_spin_lock_irqsave(&devpriv->asics[asic].spinlock,
+ flags);
+
+ int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+
+ if (int_pend) {
+ int port;
+ for (port = 0; port < INTR_PORTS_PER_ASIC;
+ ++port) {
+ if (int_pend & (0x1 << port)) {
+ unsigned char
+ io_lines_with_edges = 0;
+ switch_page(dev, asic,
+ PAGE_INT_ID);
+ io_lines_with_edges =
+ inb(iobase +
+ REG_INT_ID0 + port);
+
+ if (io_lines_with_edges)
+ /* clear pending interrupt */
+ outb(0, iobase +
+ REG_INT_ID0 +
+ port);
+
+ triggered |=
+ io_lines_with_edges <<
+ port * 8;
+ }
+ }
+
+ ++got1;
+ }
+
+ comedi_spin_unlock_irqrestore(&devpriv->asics[asic].
+ spinlock, flags);
+
+ if (triggered) {
+ struct comedi_subdevice *s;
+ /* TODO here: dispatch io lines to subdevs with commands.. */
+ printk("PCMMIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
+ for (s = dev->subdevices + 2;
+ s < dev->subdevices + dev->n_subdevices;
+ ++s) {
+ if (subpriv->dio.intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */
+ unsigned long flags;
+ unsigned oldevents;
+
+ comedi_spin_lock_irqsave
+ (&subpriv->dio.intr.
+ spinlock, flags);
+
+ oldevents = s->async->events;
+
+ if (subpriv->dio.intr.active) {
+ unsigned mytrig =
+ ((triggered >>
+ subpriv->
+ dio.
+ intr.
+ asic_chan)
+ & ((0x1 << subpriv->dio.intr.num_asic_chans) - 1)) << subpriv->dio.intr.first_chan;
+ if (mytrig & subpriv->
+ dio.intr.
+ enabled_mask) {
+ unsigned int val =
+ 0;
+ unsigned int n,
+ ch, len;
+
+ len = s->async->
+ cmd.
+ chanlist_len;
+ for (n = 0;
+ n < len;
+ n++) {
+ ch = CR_CHAN(s->async->cmd.chanlist[n]);
+ if (mytrig & (1U << ch)) {
+ val |= (1U << n);
+ }
+ }
+ /* Write the scan to the buffer. */
+ if (comedi_buf_put(s->async, ((short *) & val)[0])
+ &&
+ comedi_buf_put
+ (s->async, ((short *) & val)[1])) {
+ s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+ } else {
+ /* Overflow! Stop acquisition!! */
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmmio_stop_intr
+ (dev,
+ s);
+ }
+
+ /* Check for end of acquisition. */
+ if (!subpriv->
+ dio.
+ intr.
+ continuous)
+ {
+ /* stop_src == TRIG_COUNT */
+ if (subpriv->dio.intr.stop_count > 0) {
+ subpriv->
+ dio.
+ intr.
+ stop_count--;
+ if (subpriv->dio.intr.stop_count == 0) {
+ s->async->events |= COMEDI_CB_EOA;
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmmio_stop_intr
+ (dev,
+ s);
+ }
+ }
+ }
+ }
+ }
+
+ comedi_spin_unlock_irqrestore
+ (&subpriv->dio.intr.
+ spinlock, flags);
+
+ if (oldevents !=
+ s->async->events) {
+ comedi_event(dev, s);
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ if (!got1)
+ return IRQ_NONE; /* interrupt from other source */
+ return IRQ_HANDLED;
+}
+
+static void pcmmio_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int nports, firstport, asic, port;
+
+ if ((asic = subpriv->dio.intr.asic) < 0)
+ return; /* not an interrupt subdev */
+
+ subpriv->dio.intr.enabled_mask = 0;
+ subpriv->dio.intr.active = 0;
+ s->async->inttrig = 0;
+ nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT;
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ /* disable all intrs for this subdev.. */
+ outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+}
+
+static int pcmmio_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (!subpriv->dio.intr.continuous && subpriv->dio.intr.stop_count == 0) {
+ /* An empty acquisition! */
+ s->async->events |= COMEDI_CB_EOA;
+ subpriv->dio.intr.active = 0;
+ return 1;
+ } else {
+ unsigned bits = 0, pol_bits = 0, n;
+ int nports, firstport, asic, port;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if ((asic = subpriv->dio.intr.asic) < 0)
+ return 1; /* not an interrupt
+ subdev */
+ subpriv->dio.intr.enabled_mask = 0;
+ subpriv->dio.intr.active = 1;
+ nports = subpriv->dio.intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->dio.intr.asic_chan / CHANS_PER_PORT;
+ if (cmd->chanlist) {
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+ pol_bits |= (CR_AREF(cmd->chanlist[n])
+ || CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
+ << CR_CHAN(cmd->chanlist[n]);
+ }
+ }
+ bits &= ((0x1 << subpriv->dio.intr.num_asic_chans) -
+ 1) << subpriv->dio.intr.first_chan;
+ subpriv->dio.intr.enabled_mask = bits;
+
+ { /* the below code configures the board to use a specific IRQ from 0-15. */
+ unsigned char b;
+ /* set resource enable register to enable IRQ operation */
+ outb(1 << 4, dev->iobase + 3);
+ /* set bits 0-3 of b to the irq number from 0-15 */
+ b = dev->irq & ((1 << 4) - 1);
+ outb(b, dev->iobase + 2);
+ /* done, we told the board what irq to use */
+ }
+
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ unsigned enab =
+ bits >> (subpriv->dio.intr.first_chan + (port -
+ firstport) * 8) & 0xff, pol =
+ pol_bits >> (subpriv->dio.intr.first_chan +
+ (port - firstport) * 8) & 0xff;
+ /* set enab intrs for this subdev.. */
+ outb(enab,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ switch_page(dev, asic, PAGE_POL);
+ outb(pol,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+ }
+ return 0;
+}
+
+static int pcmmio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+ if (subpriv->dio.intr.active)
+ pcmmio_stop_intr(dev, s);
+ comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmmio_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ unsigned long flags;
+ int event = 0;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+ s->async->inttrig = 0;
+ if (subpriv->dio.intr.active) {
+ event = pcmmio_start_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 1;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int pcmmio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+ int event = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->dio.intr.spinlock, flags);
+ subpriv->dio.intr.active = 1;
+
+ /* Set up end of acquisition. */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ subpriv->dio.intr.continuous = 0;
+ subpriv->dio.intr.stop_count = cmd->stop_arg;
+ break;
+ default:
+ /* TRIG_NONE */
+ subpriv->dio.intr.continuous = 1;
+ subpriv->dio.intr.stop_count = 0;
+ break;
+ }
+
+ /* Set up start of acquisition. */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ s->async->inttrig = pcmmio_inttrig_start_intr;
+ break;
+ default:
+ /* TRIG_NOW */
+ event = pcmmio_start_intr(dev, s);
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->dio.intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmmio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= (TRIG_NOW | TRIG_INT);
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_src == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* any count allowed */
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ /* if (err) return 4; */
+
+ return 0;
+}
+
+static int adc_wait_ready(unsigned long iobase)
+{
+ unsigned long retry = 100000;
+ while (retry--)
+ if (inb(iobase + 3) & 0x80)
+ return 0;
+ return 1;
+}
+
+/* All this is for AI and AO */
+static int ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned long iobase = subpriv->iobase;
+
+ /*
+ 1. write the CMD byte (to BASE+2)
+ 2. read junk lo byte (BASE+0)
+ 3. read junk hi byte (BASE+1)
+ 4. (mux settled so) write CMD byte again (BASE+2)
+ 5. read valid lo byte(BASE+0)
+ 6. read valid hi byte(BASE+1)
+
+ Additionally note that the BASE += 4 if the channel >= 8
+ */
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ unsigned chan = CR_CHAN(insn->chanspec), range =
+ CR_RANGE(insn->chanspec), aref =
+ CR_AREF(insn->chanspec);
+ unsigned char command_byte = 0;
+ unsigned iooffset = 0;
+ short sample, adc_adjust = 0;
+
+ if (chan > 7)
+ chan -= 8, iooffset = 4; /* use the second dword for channels > 7 */
+
+ if (aref != AREF_DIFF) {
+ aref = AREF_GROUND;
+ command_byte |= 1 << 7; /* set bit 7 to indicate single-ended */
+ }
+ if (range < 2)
+ adc_adjust = 0x8000; /* bipolar ranges (-5,5 .. -10,10 need to be adjusted -- that is.. they need to wrap around by adding 0x8000 */
+
+ if (chan % 2) {
+ command_byte |= 1 << 6; /* odd-numbered channels have bit 6 set */
+ }
+
+ /* select the channel, bits 4-5 == chan/2 */
+ command_byte |= ((chan / 2) & 0x3) << 4;
+
+ /* set the range, bits 2-3 */
+ command_byte |= (range & 0x3) << 2;
+
+ /* need to do this twice to make sure mux settled */
+ outb(command_byte, iobase + iooffset + 2); /* chan/range/aref select */
+
+ adc_wait_ready(iobase + iooffset); /* wait for the adc to say it finised the conversion */
+
+ outb(command_byte, iobase + iooffset + 2); /* select the chan/range/aref AGAIN */
+
+ adc_wait_ready(iobase + iooffset);
+
+ sample = inb(iobase + iooffset + 0); /* read data lo byte */
+ sample |= inb(iobase + iooffset + 1) << 8; /* read data hi byte */
+ sample += adc_adjust; /* adjustment .. munge data */
+ data[n] = sample;
+ }
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ for (n = 0; n < insn->n; n++) {
+ unsigned chan = CR_CHAN(insn->chanspec);
+ if (chan < s->n_chan)
+ data[n] = subpriv->ao.shadow_samples[chan];
+ }
+ return n;
+}
+
+static int wait_dac_ready(unsigned long iobase)
+{
+ unsigned long retry = 100000L;
+
+ /* This may seem like an absurd way to handle waiting and violates the
+ "no busy waiting" policy. The fact is that the hardware is
+ normally so fast that we usually only need one time through the loop
+ anyway. The longer timeout is for rare occasions and for detecting
+ non-existant hardware. */
+
+ while (retry--) {
+ if (inb(iobase + 3) & 0x80)
+ return 0;
+
+ }
+ return 1;
+}
+
+static int ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ unsigned iobase = subpriv->iobase, iooffset = 0;
+
+ for (n = 0; n < insn->n; n++) {
+ unsigned chan = CR_CHAN(insn->chanspec), range =
+ CR_RANGE(insn->chanspec);
+ if (chan < s->n_chan) {
+ unsigned char command_byte = 0, range_byte =
+ range & ((1 << 4) - 1);
+ if (chan >= 4)
+ chan -= 4, iooffset += 4;
+ /* set the range.. */
+ outb(range_byte, iobase + iooffset + 0);
+ outb(0, iobase + iooffset + 1);
+
+ /* tell it to begin */
+ command_byte = (chan << 1) | 0x60;
+ outb(command_byte, iobase + iooffset + 2);
+
+ wait_dac_ready(iobase + iooffset);
+
+ outb(data[n] & 0xff, iobase + iooffset + 0); /* low order byte */
+ outb((data[n] >> 8) & 0xff, iobase + iooffset + 1); /* high order byte */
+ command_byte = 0x70 | (chan << 1); /* set bit 4 of command byte to indicate data is loaded and trigger conversion */
+ /* trigger converion */
+ outb(command_byte, iobase + iooffset + 2);
+
+ wait_dac_ready(iobase + iooffset);
+
+ subpriv->ao.shadow_samples[chan] = data[n]; /* save to shadow register for ao_rinsn */
+ }
+ }
+ return n;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/pcmuio.c b/drivers/staging/comedi/drivers/pcmuio.c
new file mode 100644
index 00000000000..4e7d8b6327f
--- /dev/null
+++ b/drivers/staging/comedi/drivers/pcmuio.c
@@ -0,0 +1,1101 @@
+/*
+ comedi/drivers/pcmuio.c
+ Driver for Winsystems PC-104 based 48-channel and 96-channel DIO boards.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2006 Calin A. Culianu <calin@ajvar.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: pcmuio
+Description: A driver for the PCM-UIO48A and PCM-UIO96A boards from Winsystems.
+Devices: [Winsystems] PCM-UIO48A (pcmuio48), PCM-UIO96A (pcmuio96)
+Author: Calin Culianu <calin@ajvar.org>
+Updated: Fri, 13 Jan 2006 12:01:01 -0500
+Status: works
+
+A driver for the relatively straightforward-to-program PCM-UIO48A and
+PCM-UIO96A boards from Winsystems. These boards use either one or two
+(in the 96-DIO version) WS16C48 ASIC HighDensity I/O Chips (HDIO).
+This chip is interesting in that each I/O line is individually
+programmable for INPUT or OUTPUT (thus comedi_dio_config can be done
+on a per-channel basis). Also, each chip supports edge-triggered
+interrupts for the first 24 I/O lines. Of course, since the
+96-channel version of the board has two ASICs, it can detect polarity
+changes on up to 48 I/O lines. Since this is essentially an (non-PnP)
+ISA board, I/O Address and IRQ selection are done through jumpers on
+the board. You need to pass that information to this driver as the
+first and second comedi_config option, respectively. Note that the
+48-channel version uses 16 bytes of IO memory and the 96-channel
+version uses 32-bytes (in case you are worried about conflicts). The
+48-channel board is split into two 24-channel comedi subdevices.
+The 96-channel board is split into 4 24-channel DIO subdevices.
+
+Note that IRQ support has been added, but it is untested.
+
+To use edge-detection IRQ support, pass the IRQs of both ASICS
+(for the 96 channel version) or just 1 ASIC (for 48-channel version).
+Then, use use comedi_commands with TRIG_NOW.
+Your callback will be called each time an edge is triggered, and the data
+values will be two sample_t's, which should be concatenated to form one
+32-bit unsigned int. This value is the mask of channels that had
+edges detected from your channel list. Note that the bits positions
+in the mask correspond to positions in your chanlist when you specified
+the command and *not* channel id's!
+
+To set the polarity of the edge-detection interrupts pass a nonzero value for
+either CR_RANGE or CR_AREF for edge-up polarity, or a zero value for both
+CR_RANGE and CR_AREF if you want edge-down polarity.
+
+In the 48-channel version:
+
+On subdev 0, the first 24 channels channels are edge-detect channels.
+
+In the 96-channel board you have the collowing channels that can do edge detection:
+
+subdev 0, channels 0-24 (first 24 channels of 1st ASIC)
+subdev 2, channels 0-24 (first 24 channels of 2nd ASIC)
+
+Configuration Options:
+ [0] - I/O port base address
+ [1] - IRQ (for first ASIC, or first 24 channels)
+ [2] - IRQ for second ASIC (pcmuio96 only - IRQ for chans 48-72 .. can be the same as first irq!)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/pci.h> /* for PCI devices */
+
+#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
+#define CHANS_PER_PORT 8
+#define PORTS_PER_ASIC 6
+#define INTR_PORTS_PER_ASIC 3
+#define MAX_CHANS_PER_SUBDEV 24 /* number of channels per comedi subdevice */
+#define PORTS_PER_SUBDEV (MAX_CHANS_PER_SUBDEV/CHANS_PER_PORT)
+#define CHANS_PER_ASIC (CHANS_PER_PORT*PORTS_PER_ASIC)
+#define INTR_CHANS_PER_ASIC 24
+#define INTR_PORTS_PER_SUBDEV (INTR_CHANS_PER_ASIC/CHANS_PER_PORT)
+#define MAX_DIO_CHANS (PORTS_PER_ASIC*2*CHANS_PER_PORT)
+#define MAX_ASICS (MAX_DIO_CHANS/CHANS_PER_ASIC)
+#define SDEV_NO ((int)(s - dev->subdevices))
+#define CALC_N_SUBDEVS(nchans) ((nchans)/MAX_CHANS_PER_SUBDEV + (!!((nchans)%MAX_CHANS_PER_SUBDEV)) /*+ (nchans > INTR_CHANS_PER_ASIC ? 2 : 1)*/)
+/* IO Memory sizes */
+#define ASIC_IOSIZE (0x10)
+#define PCMUIO48_IOSIZE ASIC_IOSIZE
+#define PCMUIO96_IOSIZE (ASIC_IOSIZE*2)
+
+/* Some offsets - these are all in the 16byte IO memory offset from
+ the base address. Note that there is a paging scheme to swap out
+ offsets 0x8-0xA using the PAGELOCK register. See the table below.
+
+ Register(s) Pages R/W? Description
+ --------------------------------------------------------------
+ REG_PORTx All R/W Read/Write/Configure IO
+ REG_INT_PENDING All ReadOnly Quickly see which INT_IDx has int.
+ REG_PAGELOCK All WriteOnly Select a page
+ REG_POLx Pg. 1 only WriteOnly Select edge-detection polarity
+ REG_ENABx Pg. 2 only WriteOnly Enable/Disable edge-detect. int.
+ REG_INT_IDx Pg. 3 only R/W See which ports/bits have ints.
+ */
+#define REG_PORT0 0x0
+#define REG_PORT1 0x1
+#define REG_PORT2 0x2
+#define REG_PORT3 0x3
+#define REG_PORT4 0x4
+#define REG_PORT5 0x5
+#define REG_INT_PENDING 0x6
+#define REG_PAGELOCK 0x7 /* page selector register, upper 2 bits select a page
+ and bits 0-5 are used to 'lock down' a particular
+ port above to make it readonly. */
+#define REG_POL0 0x8
+#define REG_POL1 0x9
+#define REG_POL2 0xA
+#define REG_ENAB0 0x8
+#define REG_ENAB1 0x9
+#define REG_ENAB2 0xA
+#define REG_INT_ID0 0x8
+#define REG_INT_ID1 0x9
+#define REG_INT_ID2 0xA
+
+#define NUM_PAGED_REGS 3
+#define NUM_PAGES 4
+#define FIRST_PAGED_REG 0x8
+#define REG_PAGE_BITOFFSET 6
+#define REG_LOCK_BITOFFSET 0
+#define REG_PAGE_MASK (~((0x1<<REG_PAGE_BITOFFSET)-1))
+#define REG_LOCK_MASK ~(REG_PAGE_MASK)
+#define PAGE_POL 1
+#define PAGE_ENAB 2
+#define PAGE_INT_ID 3
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct pcmuio_board {
+ const char *name;
+ const int num_asics;
+ const int num_channels_per_port;
+ const int num_ports;
+};
+
+static const struct pcmuio_board pcmuio_boards[] = {
+ {
+ name: "pcmuio48",
+ num_asics:1,
+ num_ports:6,
+ },
+ {
+ name: "pcmuio96",
+ num_asics:2,
+ num_ports:12,
+ },
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct pcmuio_board *)dev->board_ptr)
+
+/* this structure is for data unique to this subdevice. */
+struct pcmuio_subdev_private {
+ /* mapping of halfwords (bytes) in port/chanarray to iobase */
+ unsigned long iobases[PORTS_PER_SUBDEV];
+
+ /* The below is only used for intr subdevices */
+ struct {
+ int asic; /* if non-negative, this subdev has an interrupt asic */
+ int first_chan; /* if nonnegative, the first channel id for
+ interrupts. */
+ int num_asic_chans; /* the number of asic channels in this subdev
+ that have interrutps */
+ int asic_chan; /* if nonnegative, the first channel id with
+ respect to the asic that has interrupts */
+ int enabled_mask; /* subdev-relative channel mask for channels
+ we are interested in */
+ int active;
+ int stop_count;
+ int continuous;
+ spinlock_t spinlock;
+ } intr;
+};
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct pcmuio_private {
+ struct {
+ unsigned char pagelock; /* current page and lock */
+ unsigned char pol[NUM_PAGED_REGS]; /* shadow of POLx registers */
+ unsigned char enab[NUM_PAGED_REGS]; /* shadow of ENABx registers */
+ int num;
+ unsigned long iobase;
+ unsigned int irq;
+ spinlock_t spinlock;
+ } asics[MAX_ASICS];
+ struct pcmuio_subdev_private *sprivs;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct pcmuio_private *)dev->private)
+#define subpriv ((struct pcmuio_subdev_private *)s->private)
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int pcmuio_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int pcmuio_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver = {
+ driver_name:"pcmuio",
+ module:THIS_MODULE,
+ attach:pcmuio_attach,
+ detach:pcmuio_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in pcmuio_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&pcmuio_boards[0].name,
+ offset:sizeof(struct pcmuio_board),
+ num_names:sizeof(pcmuio_boards) / sizeof(struct pcmuio_board),
+};
+
+static int pcmuio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcmuio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static irqreturn_t interrupt_pcmuio(int irq, void *d PT_REGS_ARG);
+static void pcmuio_stop_intr(struct comedi_device *, struct comedi_subdevice *);
+static int pcmuio_cancel(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmuio_cmd(struct comedi_device * dev, struct comedi_subdevice * s);
+static int pcmuio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+
+/* some helper functions to deal with specifics of this device's registers */
+static void init_asics(struct comedi_device * dev); /* sets up/clears ASIC chips to defaults */
+static void switch_page(struct comedi_device * dev, int asic, int page);
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port);
+static void unlock_port(struct comedi_device * dev, int asic, int port);
+#endif
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int pcmuio_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int sdev_no, chans_left, n_subdevs, port, asic, thisasic_chanct = 0;
+ unsigned long iobase;
+ unsigned int irq[MAX_ASICS];
+
+ iobase = it->options[0];
+ irq[0] = it->options[1];
+ irq[1] = it->options[2];
+
+ printk("comedi%d: %s: io: %lx ", dev->minor, driver.driver_name,
+ iobase);
+
+ dev->iobase = iobase;
+
+ if (!iobase || !request_region(iobase,
+ thisboard->num_asics * ASIC_IOSIZE,
+ driver.driver_name)) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct pcmuio_private)) < 0) {
+ printk("cannot allocate private data structure\n");
+ return -ENOMEM;
+ }
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ devpriv->asics[asic].num = asic;
+ devpriv->asics[asic].iobase = dev->iobase + asic * ASIC_IOSIZE;
+ devpriv->asics[asic].irq = 0; /* this gets actually set at the end of
+ this function when we
+ comedi_request_irqs */
+ spin_lock_init(&devpriv->asics[asic].spinlock);
+ }
+
+ chans_left = CHANS_PER_ASIC * thisboard->num_asics;
+ n_subdevs = CALC_N_SUBDEVS(chans_left);
+ devpriv->sprivs =
+ kcalloc(n_subdevs, sizeof(struct pcmuio_subdev_private), GFP_KERNEL);
+ if (!devpriv->sprivs) {
+ printk("cannot allocate subdevice private data structures\n");
+ return -ENOMEM;
+ }
+ /*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ *
+ * Allocate 2 subdevs (32 + 16 DIO lines) or 3 32 DIO subdevs for the
+ * 96-channel version of the board.
+ */
+ if (alloc_subdevices(dev, n_subdevs) < 0) {
+ printk("cannot allocate subdevice data structures\n");
+ return -ENOMEM;
+ }
+
+ port = 0;
+ asic = 0;
+ for (sdev_no = 0; sdev_no < (int)dev->n_subdevices; ++sdev_no) {
+ int byte_no;
+
+ s = dev->subdevices + sdev_no;
+ s->private = devpriv->sprivs + sdev_no;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->type = COMEDI_SUBD_DIO;
+ s->insn_bits = pcmuio_dio_insn_bits;
+ s->insn_config = pcmuio_dio_insn_config;
+ s->n_chan = MIN(chans_left, MAX_CHANS_PER_SUBDEV);
+ subpriv->intr.asic = -1;
+ subpriv->intr.first_chan = -1;
+ subpriv->intr.asic_chan = -1;
+ subpriv->intr.num_asic_chans = -1;
+ subpriv->intr.active = 0;
+ s->len_chanlist = 1;
+
+ /* save the ioport address for each 'port' of 8 channels in the
+ subdevice */
+ for (byte_no = 0; byte_no < PORTS_PER_SUBDEV; ++byte_no, ++port) {
+ if (port >= PORTS_PER_ASIC) {
+ port = 0;
+ ++asic;
+ thisasic_chanct = 0;
+ }
+ subpriv->iobases[byte_no] =
+ devpriv->asics[asic].iobase + port;
+
+ if (thisasic_chanct <
+ CHANS_PER_PORT * INTR_PORTS_PER_ASIC
+ && subpriv->intr.asic < 0) {
+ /* this is an interrupt subdevice, so setup the struct */
+ subpriv->intr.asic = asic;
+ subpriv->intr.active = 0;
+ subpriv->intr.stop_count = 0;
+ subpriv->intr.first_chan = byte_no * 8;
+ subpriv->intr.asic_chan = thisasic_chanct;
+ subpriv->intr.num_asic_chans =
+ s->n_chan - subpriv->intr.first_chan;
+ dev->read_subdev = s;
+ s->subdev_flags |= SDF_CMD_READ;
+ s->cancel = pcmuio_cancel;
+ s->do_cmd = pcmuio_cmd;
+ s->do_cmdtest = pcmuio_cmdtest;
+ s->len_chanlist = subpriv->intr.num_asic_chans;
+ }
+ thisasic_chanct += CHANS_PER_PORT;
+ }
+ spin_lock_init(&subpriv->intr.spinlock);
+
+ chans_left -= s->n_chan;
+
+ if (!chans_left) {
+ asic = 0; /* reset the asic to our first asic, to do intr subdevs */
+ port = 0;
+ }
+
+ }
+
+ init_asics(dev); /* clear out all the registers, basically */
+
+ for (asic = 0; irq[0] && asic < MAX_ASICS; ++asic) {
+ if (irq[asic]
+ && comedi_request_irq(irq[asic], interrupt_pcmuio,
+ IRQF_SHARED, thisboard->name, dev)) {
+ int i;
+ /* unroll the allocated irqs.. */
+ for (i = asic - 1; i >= 0; --i) {
+ comedi_free_irq(irq[i], dev);
+ devpriv->asics[i].irq = irq[i] = 0;
+ }
+ irq[asic] = 0;
+ }
+ devpriv->asics[asic].irq = irq[asic];
+ }
+
+ dev->irq = irq[0]; /* grr.. wish comedi dev struct supported multiple
+ irqs.. */
+
+ if (irq[0]) {
+ printk("irq: %u ", irq[0]);
+ if (irq[1] && thisboard->num_asics == 2)
+ printk("second ASIC irq: %u ", irq[1]);
+ } else {
+ printk("(IRQ mode disabled) ");
+ }
+
+ printk("attached\n");
+
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int pcmuio_detach(struct comedi_device * dev)
+{
+ int i;
+
+ printk("comedi%d: %s: remove\n", dev->minor, driver.driver_name);
+ if (dev->iobase)
+ release_region(dev->iobase, ASIC_IOSIZE * thisboard->num_asics);
+
+ for (i = 0; i < MAX_ASICS; ++i) {
+ if (devpriv->asics[i].irq)
+ comedi_free_irq(devpriv->asics[i].irq, dev);
+ }
+
+ if (devpriv && devpriv->sprivs)
+ kfree(devpriv->sprivs);
+
+ return 0;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int pcmuio_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int byte_no;
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* NOTE:
+ reading a 0 means this channel was high
+ writine a 0 sets the channel high
+ reading a 1 means this channel was low
+ writing a 1 means set this channel low
+
+ Therefore everything is always inverted. */
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("write mask: %08x data: %08x\n", data[0], data[1]);
+#endif
+
+ s->state = 0;
+
+ for (byte_no = 0; byte_no < s->n_chan / CHANS_PER_PORT; ++byte_no) {
+ /* address of 8-bit port */
+ unsigned long ioaddr = subpriv->iobases[byte_no],
+ /* bit offset of port in 32-bit doubleword */
+ offset = byte_no * 8;
+ /* this 8-bit port's data */
+ unsigned char byte = 0,
+ /* The write mask for this port (if any) */
+ write_mask_byte = (data[0] >> offset) & 0xff,
+ /* The data byte for this port */
+ data_byte = (data[1] >> offset) & 0xff;
+
+ byte = inb(ioaddr); /* read all 8-bits for this port */
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("byte %d wmb %02x db %02x offset %02d io %04x, data_in %02x ", byte_no, (unsigned)write_mask_byte, (unsigned)data_byte, offset, ioaddr, (unsigned)byte);
+#endif
+
+ if (write_mask_byte) {
+ /* this byte has some write_bits -- so set the output lines */
+ byte &= ~write_mask_byte; /* clear bits for write mask */
+ byte |= ~data_byte & write_mask_byte; /* set to inverted data_byte */
+ /* Write out the new digital output state */
+ outb(byte, ioaddr);
+ }
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("data_out_byte %02x\n", (unsigned)byte);
+#endif
+ /* save the digital input lines for this byte.. */
+ s->state |= ((unsigned int)byte) << offset;
+ }
+
+ /* now return the DIO lines to data[1] - note they came inverted! */
+ data[1] = ~s->state;
+
+#ifdef DAMMIT_ITS_BROKEN
+ /* DEBUG */
+ printk("s->state %08x data_out %08x\n", s->state, data[1]);
+#endif
+
+ return 2;
+}
+
+/* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+static int pcmuio_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec), byte_no = chan / 8, bit_no =
+ chan % 8;
+ unsigned long ioaddr;
+ unsigned char byte;
+
+ /* Compute ioaddr for this channel */
+ ioaddr = subpriv->iobases[byte_no];
+
+ /* NOTE:
+ writing a 0 an IO channel's bit sets the channel to INPUT
+ and pulls the line high as well
+
+ writing a 1 to an IO channel's bit pulls the line low
+
+ All channels are implicitly always in OUTPUT mode -- but when
+ they are high they can be considered to be in INPUT mode..
+
+ Thus, we only force channels low if the config request was INPUT,
+ otherwise we do nothing to the hardware. */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ /* save to io_bits -- don't actually do anything since
+ all input channels are also output channels... */
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ /* write a 0 to the actual register representing the channel
+ to set it to 'input'. 0 means "float high". */
+ byte = inb(ioaddr);
+ byte &= ~(1 << bit_no);
+ /**< set input channel to '0' */
+
+ /* write out byte -- this is the only time we actually affect the
+ hardware as all channels are implicitly output -- but input
+ channels are set to float-high */
+ outb(byte, ioaddr);
+
+ /* save to io_bits */
+ s->io_bits &= ~(1 << chan);
+ break;
+
+ case INSN_CONFIG_DIO_QUERY:
+ /* retreive from shadow register */
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+
+ default:
+ return -EINVAL;
+ break;
+ }
+
+ return insn->n;
+}
+
+static void init_asics(struct comedi_device * dev)
+{ /* sets up an
+ ASIC chip to defaults */
+ int asic;
+
+ for (asic = 0; asic < thisboard->num_asics; ++asic) {
+ int port, page;
+ unsigned long baseaddr = dev->iobase + asic * ASIC_IOSIZE;
+
+ switch_page(dev, asic, 0); /* switch back to page 0 */
+
+ /* first, clear all the DIO port bits */
+ for (port = 0; port < PORTS_PER_ASIC; ++port)
+ outb(0, baseaddr + REG_PORT0 + port);
+
+ /* Next, clear all the paged registers for each page */
+ for (page = 1; page < NUM_PAGES; ++page) {
+ int reg;
+ /* now clear all the paged registers */
+ switch_page(dev, asic, page);
+ for (reg = FIRST_PAGED_REG;
+ reg < FIRST_PAGED_REG + NUM_PAGED_REGS; ++reg)
+ outb(0, baseaddr + reg);
+ }
+
+ /* DEBUG set rising edge interrupts on port0 of both asics */
+ /*switch_page(dev, asic, PAGE_POL);
+ outb(0xff, baseaddr + REG_POL0);
+ switch_page(dev, asic, PAGE_ENAB);
+ outb(0xff, baseaddr + REG_ENAB0); */
+ /* END DEBUG */
+
+ switch_page(dev, asic, 0); /* switch back to default page 0 */
+
+ }
+}
+
+static void switch_page(struct comedi_device * dev, int asic, int page)
+{
+ if (asic < 0 || asic >= thisboard->num_asics)
+ return; /* paranoia */
+ if (page < 0 || page >= NUM_PAGES)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock &= ~REG_PAGE_MASK;
+ devpriv->asics[asic].pagelock |= page << REG_PAGE_BITOFFSET;
+
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+
+#ifdef notused
+static void lock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+
+ devpriv->asics[asic].pagelock |= 0x1 << port;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+
+static void unlock_port(struct comedi_device * dev, int asic, int port)
+{
+ if (asic < 0 || asic >= thisboard->num_asics)
+ return; /* paranoia */
+ if (port < 0 || port >= PORTS_PER_ASIC)
+ return; /* more paranoia */
+ devpriv->asics[asic].pagelock &= ~(0x1 << port) | REG_LOCK_MASK;
+ /* now write out the shadow register */
+ outb(devpriv->asics[asic].pagelock,
+ dev->iobase + ASIC_IOSIZE * asic + REG_PAGELOCK);
+}
+#endif /* notused */
+
+static irqreturn_t interrupt_pcmuio(int irq, void *d PT_REGS_ARG)
+{
+ int asic, got1 = 0;
+ struct comedi_device *dev = (struct comedi_device *) d;
+
+ for (asic = 0; asic < MAX_ASICS; ++asic) {
+ if (irq == devpriv->asics[asic].irq) {
+ unsigned long flags;
+ unsigned triggered = 0;
+ unsigned long iobase = devpriv->asics[asic].iobase;
+ /* it is an interrupt for ASIC #asic */
+ unsigned char int_pend;
+
+ comedi_spin_lock_irqsave(&devpriv->asics[asic].spinlock,
+ flags);
+
+ int_pend = inb(iobase + REG_INT_PENDING) & 0x07;
+
+ if (int_pend) {
+ int port;
+ for (port = 0; port < INTR_PORTS_PER_ASIC;
+ ++port) {
+ if (int_pend & (0x1 << port)) {
+ unsigned char
+ io_lines_with_edges = 0;
+ switch_page(dev, asic,
+ PAGE_INT_ID);
+ io_lines_with_edges =
+ inb(iobase +
+ REG_INT_ID0 + port);
+
+ if (io_lines_with_edges)
+ /* clear pending interrupt */
+ outb(0, iobase +
+ REG_INT_ID0 +
+ port);
+
+ triggered |=
+ io_lines_with_edges <<
+ port * 8;
+ }
+ }
+
+ ++got1;
+ }
+
+ comedi_spin_unlock_irqrestore(&devpriv->asics[asic].
+ spinlock, flags);
+
+ if (triggered) {
+ struct comedi_subdevice *s;
+ /* TODO here: dispatch io lines to subdevs with commands.. */
+ printk("PCMUIO DEBUG: got edge detect interrupt %d asic %d which_chans: %06x\n", irq, asic, triggered);
+ for (s = dev->subdevices;
+ s < dev->subdevices + dev->n_subdevices;
+ ++s) {
+ if (subpriv->intr.asic == asic) { /* this is an interrupt subdev, and it matches this asic! */
+ unsigned long flags;
+ unsigned oldevents;
+
+ comedi_spin_lock_irqsave
+ (&subpriv->intr.
+ spinlock, flags);
+
+ oldevents = s->async->events;
+
+ if (subpriv->intr.active) {
+ unsigned mytrig =
+ ((triggered >>
+ subpriv->
+ intr.
+ asic_chan)
+ & ((0x1 << subpriv->intr.num_asic_chans) - 1)) << subpriv->intr.first_chan;
+ if (mytrig & subpriv->
+ intr.
+ enabled_mask) {
+ unsigned int val =
+ 0;
+ unsigned int n,
+ ch, len;
+
+ len = s->async->
+ cmd.
+ chanlist_len;
+ for (n = 0;
+ n < len;
+ n++) {
+ ch = CR_CHAN(s->async->cmd.chanlist[n]);
+ if (mytrig & (1U << ch)) {
+ val |= (1U << n);
+ }
+ }
+ /* Write the scan to the buffer. */
+ if (comedi_buf_put(s->async, ((short *) & val)[0])
+ &&
+ comedi_buf_put
+ (s->async, ((short *) & val)[1])) {
+ s->async->events |= (COMEDI_CB_BLOCK | COMEDI_CB_EOS);
+ } else {
+ /* Overflow! Stop acquisition!! */
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmuio_stop_intr
+ (dev,
+ s);
+ }
+
+ /* Check for end of acquisition. */
+ if (!subpriv->
+ intr.
+ continuous)
+ {
+ /* stop_src == TRIG_COUNT */
+ if (subpriv->intr.stop_count > 0) {
+ subpriv->
+ intr.
+ stop_count--;
+ if (subpriv->intr.stop_count == 0) {
+ s->async->events |= COMEDI_CB_EOA;
+ /* TODO: STOP_ACQUISITION_CALL_HERE!! */
+ pcmuio_stop_intr
+ (dev,
+ s);
+ }
+ }
+ }
+ }
+ }
+
+ comedi_spin_unlock_irqrestore
+ (&subpriv->intr.
+ spinlock, flags);
+
+ if (oldevents !=
+ s->async->events) {
+ comedi_event(dev, s);
+ }
+
+ }
+
+ }
+ }
+
+ }
+ }
+ if (!got1)
+ return IRQ_NONE; /* interrupt from other source */
+ return IRQ_HANDLED;
+}
+
+static void pcmuio_stop_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ int nports, firstport, asic, port;
+
+ if ((asic = subpriv->intr.asic) < 0)
+ return; /* not an interrupt subdev */
+
+ subpriv->intr.enabled_mask = 0;
+ subpriv->intr.active = 0;
+ s->async->inttrig = 0;
+ nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ /* disable all intrs for this subdev.. */
+ outb(0, devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+}
+
+static int pcmuio_start_intr(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ if (!subpriv->intr.continuous && subpriv->intr.stop_count == 0) {
+ /* An empty acquisition! */
+ s->async->events |= COMEDI_CB_EOA;
+ subpriv->intr.active = 0;
+ return 1;
+ } else {
+ unsigned bits = 0, pol_bits = 0, n;
+ int nports, firstport, asic, port;
+ struct comedi_cmd *cmd = &s->async->cmd;
+
+ if ((asic = subpriv->intr.asic) < 0)
+ return 1; /* not an interrupt
+ subdev */
+ subpriv->intr.enabled_mask = 0;
+ subpriv->intr.active = 1;
+ nports = subpriv->intr.num_asic_chans / CHANS_PER_PORT;
+ firstport = subpriv->intr.asic_chan / CHANS_PER_PORT;
+ if (cmd->chanlist) {
+ for (n = 0; n < cmd->chanlist_len; n++) {
+ bits |= (1U << CR_CHAN(cmd->chanlist[n]));
+ pol_bits |= (CR_AREF(cmd->chanlist[n])
+ || CR_RANGE(cmd->chanlist[n]) ? 1U : 0U)
+ << CR_CHAN(cmd->chanlist[n]);
+ }
+ }
+ bits &= ((0x1 << subpriv->intr.num_asic_chans) -
+ 1) << subpriv->intr.first_chan;
+ subpriv->intr.enabled_mask = bits;
+
+ switch_page(dev, asic, PAGE_ENAB);
+ for (port = firstport; port < firstport + nports; ++port) {
+ unsigned enab =
+ bits >> (subpriv->intr.first_chan + (port -
+ firstport) * 8) & 0xff, pol =
+ pol_bits >> (subpriv->intr.first_chan + (port -
+ firstport) * 8) & 0xff;
+ /* set enab intrs for this subdev.. */
+ outb(enab,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ switch_page(dev, asic, PAGE_POL);
+ outb(pol,
+ devpriv->asics[asic].iobase + REG_ENAB0 + port);
+ }
+ }
+ return 0;
+}
+
+static int pcmuio_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ unsigned long flags;
+
+ comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+ if (subpriv->intr.active)
+ pcmuio_stop_intr(dev, s);
+ comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+ return 0;
+}
+
+/*
+ * Internal trigger function to start acquisition for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmuio_inttrig_start_intr(struct comedi_device * dev, struct comedi_subdevice * s,
+ unsigned int trignum)
+{
+ unsigned long flags;
+ int event = 0;
+
+ if (trignum != 0)
+ return -EINVAL;
+
+ comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+ s->async->inttrig = 0;
+ if (subpriv->intr.active) {
+ event = pcmuio_start_intr(dev, s);
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 1;
+}
+
+/*
+ * 'do_cmd' function for an 'INTERRUPT' subdevice.
+ */
+static int pcmuio_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct comedi_cmd *cmd = &s->async->cmd;
+ unsigned long flags;
+ int event = 0;
+
+ comedi_spin_lock_irqsave(&subpriv->intr.spinlock, flags);
+ subpriv->intr.active = 1;
+
+ /* Set up end of acquisition. */
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ subpriv->intr.continuous = 0;
+ subpriv->intr.stop_count = cmd->stop_arg;
+ break;
+ default:
+ /* TRIG_NONE */
+ subpriv->intr.continuous = 1;
+ subpriv->intr.stop_count = 0;
+ break;
+ }
+
+ /* Set up start of acquisition. */
+ switch (cmd->start_src) {
+ case TRIG_INT:
+ s->async->inttrig = pcmuio_inttrig_start_intr;
+ break;
+ default:
+ /* TRIG_NOW */
+ event = pcmuio_start_intr(dev, s);
+ break;
+ }
+ comedi_spin_unlock_irqrestore(&subpriv->intr.spinlock, flags);
+
+ if (event) {
+ comedi_event(dev, s);
+ }
+
+ return 0;
+}
+
+/*
+ * 'do_cmdtest' function for an 'INTERRUPT' subdevice.
+ */
+static int
+pcmuio_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s, struct comedi_cmd * cmd)
+{
+ int err = 0;
+ unsigned int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= (TRIG_NOW | TRIG_INT);
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= (TRIG_COUNT | TRIG_NONE);
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* these tests are true if more than one _src bit is set */
+ if ((cmd->start_src & (cmd->start_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_begin_src & (cmd->scan_begin_src - 1)) != 0)
+ err++;
+ if ((cmd->convert_src & (cmd->convert_src - 1)) != 0)
+ err++;
+ if ((cmd->scan_end_src & (cmd->scan_end_src - 1)) != 0)
+ err++;
+ if ((cmd->stop_src & (cmd->stop_src - 1)) != 0)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ /* cmd->start_src == TRIG_NOW || cmd->start_src == TRIG_INT */
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_begin_src == TRIG_EXT */
+ if (cmd->scan_begin_arg != 0) {
+ cmd->scan_begin_arg = 0;
+ err++;
+ }
+
+ /* cmd->convert_src == TRIG_NOW */
+ if (cmd->convert_arg != 0) {
+ cmd->convert_arg = 0;
+ err++;
+ }
+
+ /* cmd->scan_end_src == TRIG_COUNT */
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+
+ switch (cmd->stop_src) {
+ case TRIG_COUNT:
+ /* any count allowed */
+ break;
+ case TRIG_NONE:
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ /* if (err) return 4; */
+
+ return 0;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver);
diff --git a/drivers/staging/comedi/drivers/plx9052.h b/drivers/staging/comedi/drivers/plx9052.h
new file mode 100644
index 00000000000..5894739ff42
--- /dev/null
+++ b/drivers/staging/comedi/drivers/plx9052.h
@@ -0,0 +1,86 @@
+/*
+ comedi/drivers/plx9052.h
+ Definitions for the PLX-9052 PCI interface chip
+
+ Copyright (C) 2002 MEV Ltd. <http://www.mev.co.uk/>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef _PLX9052_H_
+#define _PLX9052_H_
+
+/*
+ * PLX PCI9052 INTCSR register.
+ */
+#define PLX9052_INTCSR 0x4C /* Offset in Local Configuration Registers */
+/* Local Interrupt 1 Enable */
+#define PLX9052_INTCSR_LI1ENAB_MASK 0x0001
+#define PLX9052_INTCSR_LI1ENAB_DISABLED 0x0000
+#define PLX9052_INTCSR_LI1ENAB_ENABLED 0x0001
+/* Local Interrupt 1 Polarity */
+#define PLX9052_INTCSR_LI1POL_MASK 0x0002
+#define PLX9052_INTCSR_LI1POL_LOW 0x0000
+#define PLX9052_INTCSR_LI1POL_HIGH 0x0002
+/* Local Interrupt 1 Status (read-only) */
+#define PLX9052_INTCSR_LI1STAT_MASK 0x0004
+#define PLX9052_INTCSR_LI1STAT_INACTIVE 0x0000
+#define PLX9052_INTCSR_LI1STAT_ACTIVE 0x0004
+/* Local Interrupt 2 Enable */
+#define PLX9052_INTCSR_LI2ENAB_MASK 0x0008
+#define PLX9052_INTCSR_LI2ENAB_DISABLED 0x0000
+#define PLX9052_INTCSR_LI2ENAB_ENABLED 0x0008
+/* Local Interrupt 2 Polarity */
+#define PLX9052_INTCSR_LI2POL_MASK 0x0010
+#define PLX9052_INTCSR_LI2POL_LOW 0x0000
+#define PLX9052_INTCSR_LI2POL_HIGH 0x0010
+/* Local Interrupt 2 Status (read-only) */
+#define PLX9052_INTCSR_LI2STAT_MASK 0x0020
+#define PLX9052_INTCSR_LI2STAT_INACTIVE 0x0000
+#define PLX9052_INTCSR_LI2STAT_ACTIVE 0x0020
+/* PCI Interrupt Enable */
+#define PLX9052_INTCSR_PCIENAB_MASK 0x0040
+#define PLX9052_INTCSR_PCIENAB_DISABLED 0x0000
+#define PLX9052_INTCSR_PCIENAB_ENABLED 0x0040
+/* Software Interrupt */
+#define PLX9052_INTCSR_SOFTINT_MASK 0x0080
+#define PLX9052_INTCSR_SOFTINT_UNASSERTED 0x0000
+#define PLX9052_INTCSR_SOFTINT_ASSERTED 0x0080
+/* Local Interrupt 1 Select Enable */
+#define PLX9052_INTCSR_LI1SEL_MASK 0x0100
+#define PLX9052_INTCSR_LI1SEL_LEVEL 0x0000
+#define PLX9052_INTCSR_LI1SEL_EDGE 0x0100
+/* Local Interrupt 2 Select Enable */
+#define PLX9052_INTCSR_LI2SEL_MASK 0x0200
+#define PLX9052_INTCSR_LI2SEL_LEVEL 0x0000
+#define PLX9052_INTCSR_LI2SEL_EDGE 0x0200
+/* Local Edge Triggerable Interrupt 1 Clear Bit */
+#define PLX9052_INTCSR_LI1CLRINT_MASK 0x0400
+#define PLX9052_INTCSR_LI1CLRINT_UNASSERTED 0x0000
+#define PLX9052_INTCSR_LI1CLRINT_ASSERTED 0x0400
+/* Local Edge Triggerable Interrupt 2 Clear Bit */
+#define PLX9052_INTCSR_LI2CLRINT_MASK 0x0800
+#define PLX9052_INTCSR_LI2CLRINT_UNASSERTED 0x0000
+#define PLX9052_INTCSR_LI2CLRINT_ASSERTED 0x0800
+/* ISA Interface Mode Enable (read-only over PCI bus) */
+#define PLX9052_INTCSR_ISAMODE_MASK 0x1000
+#define PLX9052_INTCSR_ISAMODE_DISABLED 0x0000
+#define PLX9052_INTCSR_ISAMODE_ENABLED 0x1000
+
+#endif /* _PLX9052_H_ */
diff --git a/drivers/staging/comedi/drivers/plx9080.h b/drivers/staging/comedi/drivers/plx9080.h
index a5a1a6808c5..9231ba80203 100644
--- a/drivers/staging/comedi/drivers/plx9080.h
+++ b/drivers/staging/comedi/drivers/plx9080.h
@@ -27,7 +27,7 @@
#ifndef __COMEDI_PLX9080_H
#define __COMEDI_PLX9080_H
-// descriptor block used for chained dma transfers
+/* descriptor block used for chained dma transfers */
struct plx_dma_desc {
volatile uint32_t pci_start_addr;
volatile uint32_t local_start_addr;
@@ -52,14 +52,14 @@ struct plx_dma_desc {
#define LRNG_ANY32 0x00000000 /* Locate anywhere in 32 bit */
#define LRNG_LT1MB 0x00000002 /* Locate in 1st meg */
#define LRNG_ANY64 0x00000004 /* Locate anywhere in 64 bit */
-#define LRNG_MEM_MASK 0xfffffff0 // bits that specify range for memory io
-#define LRNG_IO_MASK 0xfffffffa // bits that specify range for normal io
+#define LRNG_MEM_MASK 0xfffffff0 /* bits that specify range for memory io */
+#define LRNG_IO_MASK 0xfffffffa /* bits that specify range for normal io */
#define PLX_LAS0MAP_REG 0x0004 /* L, Local Addr Space 0 Remap Register */
#define PLX_LAS1MAP_REG 0x00f4 /* L, Local Addr Space 1 Remap Register */
#define LMAP_EN 0x00000001 /* Enable slave decode */
-#define LMAP_MEM_MASK 0xfffffff0 // bits that specify decode for memory io
-#define LMAP_IO_MASK 0xfffffffa // bits that specify decode bits for normal io
+#define LMAP_MEM_MASK 0xfffffff0 /* bits that specify decode for memory io */
+#define LMAP_IO_MASK 0xfffffffa /* bits that specify decode bits for normal io */
/* Mode/Arbitration Register.
*/
@@ -169,7 +169,7 @@ enum bigend_bits {
#define ICS_AERR 0x00000001 /* Assert LSERR on ABORT */
#define ICS_PERR 0x00000002 /* Assert LSERR on Parity Error */
#define ICS_SERR 0x00000004 /* Generate PCI SERR# */
-#define ICS_MBIE 0x00000008 // mailbox interrupt enable
+#define ICS_MBIE 0x00000008 /* mailbox interrupt enable */
#define ICS_PIE 0x00000100 /* PCI Interrupt Enable */
#define ICS_PDIE 0x00000200 /* PCI Doorbell Interrupt Enable */
#define ICS_PAIE 0x00000400 /* PCI Abort Interrupt Enable */
@@ -190,7 +190,7 @@ enum bigend_bits {
#define ICS_TA_DMA0 0x02000000 /* Target Abort - DMA #0 */
#define ICS_TA_DMA1 0x04000000 /* Target Abort - DMA #1 */
#define ICS_TA_RA 0x08000000 /* Target Abort - Retry Timeout */
-#define ICS_MBIA(x) (0x10000000 << ((x) & 0x3)) // mailbox x is active
+#define ICS_MBIA(x) (0x10000000 << ((x) & 0x3)) /* mailbox x is active */
#define PLX_CONTROL_REG 0x006C /* L, EEPROM Cntl & PCI Cmd Codes */
#define CTL_RDMA 0x0000000E /* DMA Read Command */
@@ -208,51 +208,51 @@ enum bigend_bits {
#define CTL_RESET 0x40000000 /* !! Adapter Reset !! */
#define CTL_READY 0x80000000 /* Local Init Done */
-#define PLX_ID_REG 0x70 // hard-coded plx vendor and device ids
+#define PLX_ID_REG 0x70 /* hard-coded plx vendor and device ids */
-#define PLX_REVISION_REG 0x74 // silicon revision
+#define PLX_REVISION_REG 0x74 /* silicon revision */
-#define PLX_DMA0_MODE_REG 0x80 // dma channel 0 mode register
-#define PLX_DMA1_MODE_REG 0x94 // dma channel 0 mode register
+#define PLX_DMA0_MODE_REG 0x80 /* dma channel 0 mode register */
+#define PLX_DMA1_MODE_REG 0x94 /* dma channel 0 mode register */
#define PLX_LOCAL_BUS_16_WIDE_BITS 0x1
#define PLX_LOCAL_BUS_32_WIDE_BITS 0x3
#define PLX_LOCAL_BUS_WIDTH_MASK 0x3
-#define PLX_DMA_EN_READYIN_BIT 0x40 // enable ready in input
-#define PLX_EN_BTERM_BIT 0x80 // enable BTERM# input
-#define PLX_DMA_LOCAL_BURST_EN_BIT 0x100 // enable local burst mode
-#define PLX_EN_CHAIN_BIT 0x200 // enables chaining
-#define PLX_EN_DMA_DONE_INTR_BIT 0x400 // enables interrupt on dma done
-#define PLX_LOCAL_ADDR_CONST_BIT 0x800 // hold local address constant (don't increment)
-#define PLX_DEMAND_MODE_BIT 0x1000 // enables demand-mode for dma transfer
+#define PLX_DMA_EN_READYIN_BIT 0x40 /* enable ready in input */
+#define PLX_EN_BTERM_BIT 0x80 /* enable BTERM# input */
+#define PLX_DMA_LOCAL_BURST_EN_BIT 0x100 /* enable local burst mode */
+#define PLX_EN_CHAIN_BIT 0x200 /* enables chaining */
+#define PLX_EN_DMA_DONE_INTR_BIT 0x400 /* enables interrupt on dma done */
+#define PLX_LOCAL_ADDR_CONST_BIT 0x800 /* hold local address constant (don't increment) */
+#define PLX_DEMAND_MODE_BIT 0x1000 /* enables demand-mode for dma transfer */
#define PLX_EOT_ENABLE_BIT 0x4000
#define PLX_STOP_MODE_BIT 0x8000
-#define PLX_DMA_INTR_PCI_BIT 0x20000 // routes dma interrupt to pci bus (instead of local bus)
+#define PLX_DMA_INTR_PCI_BIT 0x20000 /* routes dma interrupt to pci bus (instead of local bus) */
-#define PLX_DMA0_PCI_ADDRESS_REG 0x84 // pci address that dma transfers start at
+#define PLX_DMA0_PCI_ADDRESS_REG 0x84 /* pci address that dma transfers start at */
#define PLX_DMA1_PCI_ADDRESS_REG 0x98
-#define PLX_DMA0_LOCAL_ADDRESS_REG 0x88 // local address that dma transfers start at
+#define PLX_DMA0_LOCAL_ADDRESS_REG 0x88 /* local address that dma transfers start at */
#define PLX_DMA1_LOCAL_ADDRESS_REG 0x9c
-#define PLX_DMA0_TRANSFER_SIZE_REG 0x8c // number of bytes to transfer (first 23 bits)
+#define PLX_DMA0_TRANSFER_SIZE_REG 0x8c /* number of bytes to transfer (first 23 bits) */
#define PLX_DMA1_TRANSFER_SIZE_REG 0xa0
-#define PLX_DMA0_DESCRIPTOR_REG 0x90 // descriptor pointer register
+#define PLX_DMA0_DESCRIPTOR_REG 0x90 /* descriptor pointer register */
#define PLX_DMA1_DESCRIPTOR_REG 0xa4
-#define PLX_DESC_IN_PCI_BIT 0x1 // descriptor is located in pci space (not local space)
-#define PLX_END_OF_CHAIN_BIT 0x2 // end of chain bit
-#define PLX_INTR_TERM_COUNT 0x4 // interrupt when this descriptor's transfer is finished
-#define PLX_XFER_LOCAL_TO_PCI 0x8 // transfer from local to pci bus (not pci to local)
+#define PLX_DESC_IN_PCI_BIT 0x1 /* descriptor is located in pci space (not local space) */
+#define PLX_END_OF_CHAIN_BIT 0x2 /* end of chain bit */
+#define PLX_INTR_TERM_COUNT 0x4 /* interrupt when this descriptor's transfer is finished */
+#define PLX_XFER_LOCAL_TO_PCI 0x8 /* transfer from local to pci bus (not pci to local) */
-#define PLX_DMA0_CS_REG 0xa8 // command status register
+#define PLX_DMA0_CS_REG 0xa8 /* command status register */
#define PLX_DMA1_CS_REG 0xa9
-#define PLX_DMA_EN_BIT 0x1 // enable dma channel
-#define PLX_DMA_START_BIT 0x2 // start dma transfer
-#define PLX_DMA_ABORT_BIT 0x4 // abort dma transfer
-#define PLX_CLEAR_DMA_INTR_BIT 0x8 // clear dma interrupt
-#define PLX_DMA_DONE_BIT 0x10 // transfer done status bit
+#define PLX_DMA_EN_BIT 0x1 /* enable dma channel */
+#define PLX_DMA_START_BIT 0x2 /* start dma transfer */
+#define PLX_DMA_ABORT_BIT 0x4 /* abort dma transfer */
+#define PLX_CLEAR_DMA_INTR_BIT 0x8 /* clear dma interrupt */
+#define PLX_DMA_DONE_BIT 0x10 /* transfer done status bit */
-#define PLX_DMA0_THRESHOLD_REG 0xb0 // command status register
+#define PLX_DMA0_THRESHOLD_REG 0xb0 /* command status register */
/*
* Accesses near the end of memory can cause the PLX chip
@@ -392,12 +392,12 @@ static inline int plx9080_abort_dma(void *iobase, unsigned int channel)
else
dma_cs_addr = iobase + PLX_DMA0_CS_REG;
- // abort dma transfer if necessary
+ /* abort dma transfer if necessary */
dma_status = readb(dma_cs_addr);
- if ((dma_status & PLX_DMA_EN_BIT) == 0) {
+ if ((dma_status & PLX_DMA_EN_BIT) == 0)
return 0;
- }
- // wait to make sure done bit is zero
+
+ /* wait to make sure done bit is zero */
for (i = 0; (dma_status & PLX_DMA_DONE_BIT) && i < timeout; i++) {
comedi_udelay(1);
dma_status = readb(dma_cs_addr);
@@ -408,9 +408,9 @@ static inline int plx9080_abort_dma(void *iobase, unsigned int channel)
channel);
return -ETIMEDOUT;
}
- // disable and abort channel
+ /* disable and abort channel */
writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
- // wait for dma done bit
+ /* wait for dma done bit */
dma_status = readb(dma_cs_addr);
for (i = 0; (dma_status & PLX_DMA_DONE_BIT) == 0 && i < timeout; i++) {
comedi_udelay(1);
diff --git a/drivers/staging/comedi/drivers/poc.c b/drivers/staging/comedi/drivers/poc.c
new file mode 100644
index 00000000000..8a0bf685493
--- /dev/null
+++ b/drivers/staging/comedi/drivers/poc.c
@@ -0,0 +1,247 @@
+/*
+ comedi/drivers/poc.c
+ Mini-drivers for POC (Piece of Crap) boards
+ Copyright (C) 2000 Frank Mori Hess <fmhess@users.sourceforge.net>
+ Copyright (C) 2001 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+/*
+Driver: poc
+Description: Generic driver for very simple devices
+Author: ds
+Devices: [Keithley Metrabyte] DAC-02 (dac02), [Advantech] PCL-733 (pcl733),
+ PCL-734 (pcl734)
+Updated: Sat, 16 Mar 2002 17:34:48 -0800
+Status: unknown
+
+This driver is indended to support very simple ISA-based devices,
+including:
+ dac02 - Keithley DAC-02 analog output board
+ pcl733 - Advantech PCL-733
+ pcl734 - Advantech PCL-734
+
+Configuration options:
+ [0] - I/O port base
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+static int poc_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int poc_detach(struct comedi_device * dev);
+static int readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+static int dac02_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcl733_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int pcl734_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+struct boarddef_struct {
+ const char *name;
+ unsigned int iosize;
+ int (*setup) (struct comedi_device *);
+ int type;
+ int n_chan;
+ int n_bits;
+ int (*winsn) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*rinsn) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ int (*insnbits) (struct comedi_device *, struct comedi_subdevice *, struct comedi_insn *,
+ unsigned int *);
+ const struct comedi_lrange *range;
+};
+static const struct boarddef_struct boards[] = {
+ {
+ name: "dac02",
+ iosize: 8,
+ //setup: dac02_setup,
+ type: COMEDI_SUBD_AO,
+ n_chan: 2,
+ n_bits: 12,
+ winsn: dac02_ao_winsn,
+ rinsn: readback_insn,
+ range: &range_unknown,
+ },
+ {
+ name: "pcl733",
+ iosize: 4,
+ type: COMEDI_SUBD_DI,
+ n_chan: 32,
+ n_bits: 1,
+ insnbits:pcl733_insn_bits,
+ range: &range_digital,
+ },
+ {
+ name: "pcl734",
+ iosize: 4,
+ type: COMEDI_SUBD_DO,
+ n_chan: 32,
+ n_bits: 1,
+ insnbits:pcl734_insn_bits,
+ range: &range_digital,
+ },
+};
+
+#define n_boards (sizeof(boards)/sizeof(boards[0]))
+#define this_board ((const struct boarddef_struct *)dev->board_ptr)
+
+static struct comedi_driver driver_poc = {
+ driver_name:"poc",
+ module:THIS_MODULE,
+ attach:poc_attach,
+ detach:poc_detach,
+ board_name:&boards[0].name,
+ num_names:n_boards,
+ offset:sizeof(boards[0]),
+};
+
+static int poc_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ unsigned long iobase;
+ unsigned int iosize;
+
+ iobase = it->options[0];
+ printk("comedi%d: poc: using %s iobase 0x%lx\n", dev->minor,
+ this_board->name, iobase);
+
+ dev->board_name = this_board->name;
+
+ if (iobase == 0) {
+ printk("io base address required\n");
+ return -EINVAL;
+ }
+
+ iosize = this_board->iosize;
+ /* check if io addresses are available */
+ if (!request_region(iobase, iosize, "dac02")) {
+ printk("I/O port conflict: failed to allocate ports 0x%lx to 0x%lx\n", iobase, iobase + iosize - 1);
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+ if (alloc_private(dev, sizeof(unsigned int) * this_board->n_chan) < 0)
+ return -ENOMEM;
+
+ /* analog output subdevice */
+ s = dev->subdevices + 0;
+ s->type = this_board->type;
+ s->n_chan = this_board->n_chan;
+ s->maxdata = (1 << this_board->n_bits) - 1;
+ s->range_table = this_board->range;
+ s->insn_write = this_board->winsn;
+ s->insn_read = this_board->rinsn;
+ s->insn_bits = this_board->insnbits;
+ if (s->type == COMEDI_SUBD_AO || s->type == COMEDI_SUBD_DO) {
+ s->subdev_flags = SDF_WRITABLE;
+ }
+
+ return 0;
+}
+
+static int poc_detach(struct comedi_device * dev)
+{
+ /* only free stuff if it has been allocated by _attach */
+ if (dev->iobase)
+ release_region(dev->iobase, this_board->iosize);
+
+ printk("comedi%d: dac02: remove\n", dev->minor);
+
+ return 0;
+}
+
+static int readback_insn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan;
+
+ chan = CR_CHAN(insn->chanspec);
+ data[0] = ((unsigned int *) dev->private)[chan];
+
+ return 1;
+}
+
+/* DAC-02 registers */
+#define DAC02_LSB(a) (2 * a)
+#define DAC02_MSB(a) (2 * a + 1)
+
+static int dac02_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int temp;
+ int chan;
+ int output;
+
+ chan = CR_CHAN(insn->chanspec);
+ ((unsigned int *) dev->private)[chan] = data[0];
+ output = data[0];
+#ifdef wrong
+ // convert to complementary binary if range is bipolar
+ if ((CR_RANGE(insn->chanspec) & 0x2) == 0)
+ output = ~output;
+#endif
+ temp = (output << 4) & 0xf0;
+ outb(temp, dev->iobase + DAC02_LSB(chan));
+ temp = (output >> 4) & 0xff;
+ outb(temp, dev->iobase + DAC02_MSB(chan));
+
+ return 1;
+}
+
+static int pcl733_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ data[1] = inb(dev->iobase + 0);
+ data[1] |= (inb(dev->iobase + 1) << 8);
+ data[1] |= (inb(dev->iobase + 2) << 16);
+ data[1] |= (inb(dev->iobase + 3) << 24);
+
+ return 2;
+}
+
+static int pcl734_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= (data[0] & data[1]);
+ if ((data[0] >> 0) & 0xff)
+ outb((s->state >> 0) & 0xff, dev->iobase + 0);
+ if ((data[0] >> 8) & 0xff)
+ outb((s->state >> 8) & 0xff, dev->iobase + 1);
+ if ((data[0] >> 16) & 0xff)
+ outb((s->state >> 16) & 0xff, dev->iobase + 2);
+ if ((data[0] >> 24) & 0xff)
+ outb((s->state >> 24) & 0xff, dev->iobase + 3);
+ }
+ data[1] = s->state;
+
+ return 2;
+}
+
+COMEDI_INITCLEANUP(driver_poc);
diff --git a/drivers/staging/comedi/drivers/quatech_daqp_cs.c b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
new file mode 100644
index 00000000000..795c4522867
--- /dev/null
+++ b/drivers/staging/comedi/drivers/quatech_daqp_cs.c
@@ -0,0 +1,1363 @@
+/*======================================================================
+
+ comedi/drivers/quatech_daqp_cs.c
+
+ Quatech DAQP PCMCIA data capture cards COMEDI client driver
+ Copyright (C) 2000, 2003 Brent Baccala <baccala@freesoft.org>
+ The DAQP interface code in this file is released into the public domain.
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+ http://www.comedi.org/
+
+ quatech_daqp_cs.c 1.10
+
+ Documentation for the DAQP PCMCIA cards can be found on Quatech's site:
+
+ ftp://ftp.quatech.com/Manuals/daqp-208.pdf
+
+ This manual is for both the DAQP-208 and the DAQP-308.
+
+ What works:
+
+ - A/D conversion
+ - 8 channels
+ - 4 gain ranges
+ - ground ref or differential
+ - single-shot and timed both supported
+ - D/A conversion, single-shot
+ - digital I/O
+
+ What doesn't:
+
+ - any kind of triggering - external or D/A channel 1
+ - the card's optional expansion board
+ - the card's timer (for anything other than A/D conversion)
+ - D/A update modes other than immediate (i.e, timed)
+ - fancier timing modes
+ - setting card's FIFO buffer thresholds to anything but default
+
+======================================================================*/
+
+/*
+Driver: quatech_daqp_cs
+Description: Quatech DAQP PCMCIA data capture cards
+Author: Brent Baccala <baccala@freesoft.org>
+Status: works
+Devices: [Quatech] DAQP-208 (daqp), DAQP-308
+*/
+
+#include "../comedidev.h"
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+/*
+ All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
+ you do not define PCMCIA_DEBUG at all, all the debug code will be
+ left out. If you compile with PCMCIA_DEBUG=0, the debug code will
+ be present but disabled -- but it can then be enabled for specific
+ modules at load time with a 'pc_debug=#' option to insmod.
+*/
+
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+module_param(pc_debug, int, 0644);
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+static char *version = "quatech_daqp_cs.c 1.10 2003/04/21 (Brent Baccala)";
+#else
+#define DEBUG(n, args...)
+#endif
+
+/* Maximum number of separate DAQP devices we'll allow */
+#define MAX_DEV 4
+
+struct local_info_t {
+ struct pcmcia_device *link;
+ dev_node_t node;
+ int stop;
+ int table_index;
+ char board_name[32];
+
+ enum { semaphore, buffer } interrupt_mode;
+
+ struct semaphore eos;
+
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
+ int count;
+};
+
+/* A list of "instances" of the device. */
+
+static struct local_info_t *dev_table[MAX_DEV] = { NULL, /* ... */ };
+
+/* The DAQP communicates with the system through a 16 byte I/O window. */
+
+#define DAQP_FIFO_SIZE 4096
+
+#define DAQP_FIFO 0
+#define DAQP_SCANLIST 1
+#define DAQP_CONTROL 2
+#define DAQP_STATUS 2
+#define DAQP_DIGITAL_IO 3
+#define DAQP_PACER_LOW 4
+#define DAQP_PACER_MID 5
+#define DAQP_PACER_HIGH 6
+#define DAQP_COMMAND 7
+#define DAQP_DA 8
+#define DAQP_TIMER 10
+#define DAQP_AUX 15
+
+#define DAQP_SCANLIST_DIFFERENTIAL 0x4000
+#define DAQP_SCANLIST_GAIN(x) ((x)<<12)
+#define DAQP_SCANLIST_CHANNEL(x) ((x)<<8)
+#define DAQP_SCANLIST_START 0x0080
+#define DAQP_SCANLIST_EXT_GAIN(x) ((x)<<4)
+#define DAQP_SCANLIST_EXT_CHANNEL(x) (x)
+
+#define DAQP_CONTROL_PACER_100kHz 0xc0
+#define DAQP_CONTROL_PACER_1MHz 0x80
+#define DAQP_CONTROL_PACER_5MHz 0x40
+#define DAQP_CONTROL_PACER_EXTERNAL 0x00
+#define DAQP_CONTORL_EXPANSION 0x20
+#define DAQP_CONTROL_EOS_INT_ENABLE 0x10
+#define DAQP_CONTROL_FIFO_INT_ENABLE 0x08
+#define DAQP_CONTROL_TRIGGER_ONESHOT 0x00
+#define DAQP_CONTROL_TRIGGER_CONTINUOUS 0x04
+#define DAQP_CONTROL_TRIGGER_INTERNAL 0x00
+#define DAQP_CONTROL_TRIGGER_EXTERNAL 0x02
+#define DAQP_CONTROL_TRIGGER_RISING 0x00
+#define DAQP_CONTROL_TRIGGER_FALLING 0x01
+
+#define DAQP_STATUS_IDLE 0x80
+#define DAQP_STATUS_RUNNING 0x40
+#define DAQP_STATUS_EVENTS 0x38
+#define DAQP_STATUS_DATA_LOST 0x20
+#define DAQP_STATUS_END_OF_SCAN 0x10
+#define DAQP_STATUS_FIFO_THRESHOLD 0x08
+#define DAQP_STATUS_FIFO_FULL 0x04
+#define DAQP_STATUS_FIFO_NEARFULL 0x02
+#define DAQP_STATUS_FIFO_EMPTY 0x01
+
+#define DAQP_COMMAND_ARM 0x80
+#define DAQP_COMMAND_RSTF 0x40
+#define DAQP_COMMAND_RSTQ 0x20
+#define DAQP_COMMAND_STOP 0x10
+#define DAQP_COMMAND_LATCH 0x08
+#define DAQP_COMMAND_100kHz 0x00
+#define DAQP_COMMAND_50kHz 0x02
+#define DAQP_COMMAND_25kHz 0x04
+#define DAQP_COMMAND_FIFO_DATA 0x01
+#define DAQP_COMMAND_FIFO_PROGRAM 0x00
+
+#define DAQP_AUX_TRIGGER_TTL 0x00
+#define DAQP_AUX_TRIGGER_ANALOG 0x80
+#define DAQP_AUX_TRIGGER_PRETRIGGER 0x40
+#define DAQP_AUX_TIMER_INT_ENABLE 0x20
+#define DAQP_AUX_TIMER_RELOAD 0x00
+#define DAQP_AUX_TIMER_PAUSE 0x08
+#define DAQP_AUX_TIMER_GO 0x10
+#define DAQP_AUX_TIMER_GO_EXTERNAL 0x18
+#define DAQP_AUX_TIMER_EXTERNAL_SRC 0x04
+#define DAQP_AUX_TIMER_INTERNAL_SRC 0x00
+#define DAQP_AUX_DA_DIRECT 0x00
+#define DAQP_AUX_DA_OVERFLOW 0x01
+#define DAQP_AUX_DA_EXTERNAL 0x02
+#define DAQP_AUX_DA_PACER 0x03
+
+#define DAQP_AUX_RUNNING 0x80
+#define DAQP_AUX_TRIGGERED 0x40
+#define DAQP_AUX_DA_BUFFER 0x20
+#define DAQP_AUX_TIMER_OVERFLOW 0x10
+#define DAQP_AUX_CONVERSION 0x08
+#define DAQP_AUX_DATA_LOST 0x04
+#define DAQP_AUX_FIFO_NEARFULL 0x02
+#define DAQP_AUX_FIFO_EMPTY 0x01
+
+/* These range structures tell COMEDI how the sample values map to
+ * voltages. The A/D converter has four ranges: +/- 10V through
+ * +/- 1.25V, and the D/A converter has only one: +/- 5V.
+ */
+
+static const struct comedi_lrange range_daqp_ai = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(5),
+ BIP_RANGE(2.5),
+ BIP_RANGE(1.25)
+ }
+};
+
+static const struct comedi_lrange range_daqp_ao = { 1, {BIP_RANGE(5)} };
+
+/*====================================================================*/
+
+/* comedi interface code */
+
+static int daqp_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int daqp_detach(struct comedi_device * dev);
+static struct comedi_driver driver_daqp = {
+ driver_name:"quatech_daqp_cs",
+ module:THIS_MODULE,
+ attach:daqp_attach,
+ detach:daqp_detach,
+};
+
+#ifdef DAQP_DEBUG
+
+static void daqp_dump(struct comedi_device * dev)
+{
+ printk("DAQP: status %02x; aux status %02x\n",
+ inb(dev->iobase + DAQP_STATUS), inb(dev->iobase + DAQP_AUX));
+}
+
+static void hex_dump(char *str, void *ptr, int len)
+{
+ unsigned char *cptr = ptr;
+ int i;
+
+ printk(str);
+
+ for (i = 0; i < len; i++) {
+ if (i % 16 == 0) {
+ printk("\n0x%08x:", (unsigned int)cptr);
+ }
+ printk(" %02x", *(cptr++));
+ }
+ printk("\n");
+}
+
+#endif
+
+/* Cancel a running acquisition */
+
+static int daqp_ai_cancel(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ outb(DAQP_COMMAND_STOP, dev->iobase + DAQP_COMMAND);
+
+ /* flush any linguring data in FIFO - superfluous here */
+ /* outb(DAQP_COMMAND_RSTF, dev->iobase+DAQP_COMMAND); */
+
+ local->interrupt_mode = semaphore;
+
+ return 0;
+}
+
+/* Interrupt handler
+ *
+ * Operates in one of two modes. If local->interrupt_mode is
+ * 'semaphore', just signal the local->eos semaphore and return
+ * (one-shot mode). Otherwise (continuous mode), read data in from
+ * the card, transfer it to the buffer provided by the higher-level
+ * comedi kernel module, and signal various comedi callback routines,
+ * which run pretty quick.
+ */
+
+static void daqp_interrupt(int irq, void *dev_id PT_REGS_ARG)
+{
+ struct local_info_t *local = (struct local_info_t *) dev_id;
+ struct comedi_device *dev;
+ struct comedi_subdevice *s;
+ int loop_limit = 10000;
+ int status;
+
+ if (local == NULL) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): irq %d for unknown device.\n", irq);
+ return;
+ }
+
+ dev = local->dev;
+ if (dev == NULL) {
+ printk(KERN_WARNING "daqp_interrupt(): NULL comedi_device.\n");
+ return;
+ }
+
+ if (!dev->attached) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): struct comedi_device not yet attached.\n");
+ return;
+ }
+
+ s = local->s;
+ if (s == NULL) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): NULL comedi_subdevice.\n");
+ return;
+ }
+
+ if ((struct local_info_t *) s->private != local) {
+ printk(KERN_WARNING
+ "daqp_interrupt(): invalid comedi_subdevice.\n");
+ return;
+ }
+
+ switch (local->interrupt_mode) {
+
+ case semaphore:
+
+ up(&local->eos);
+ break;
+
+ case buffer:
+
+ while (!((status = inb(dev->iobase + DAQP_STATUS))
+ & DAQP_STATUS_FIFO_EMPTY)) {
+
+ short data;
+
+ if (status & DAQP_STATUS_DATA_LOST) {
+ s->async->events |=
+ COMEDI_CB_EOA | COMEDI_CB_OVERFLOW;
+ printk("daqp: data lost\n");
+ daqp_ai_cancel(dev, s);
+ break;
+ }
+
+ data = inb(dev->iobase + DAQP_FIFO);
+ data |= inb(dev->iobase + DAQP_FIFO) << 8;
+ data ^= 0x8000;
+
+ comedi_buf_put(s->async, data);
+
+ /* If there's a limit, decrement it
+ * and stop conversion if zero
+ */
+
+ if (local->count > 0) {
+ local->count--;
+ if (local->count == 0) {
+ daqp_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA;
+ break;
+ }
+ }
+
+ if ((loop_limit--) <= 0)
+ break;
+ }
+
+ if (loop_limit <= 0) {
+ printk(KERN_WARNING
+ "loop_limit reached in daqp_interrupt()\n");
+ daqp_ai_cancel(dev, s);
+ s->async->events |= COMEDI_CB_EOA | COMEDI_CB_ERROR;
+ }
+
+ s->async->events |= COMEDI_CB_BLOCK;
+
+ comedi_event(dev, s);
+ }
+}
+
+/* One-shot analog data acquisition routine */
+
+static int daqp_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+ int i;
+ int v;
+ int counter = 10000;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ /* Stop any running conversion */
+ daqp_ai_cancel(dev, s);
+
+ outb(0, dev->iobase + DAQP_AUX);
+
+ /* Reset scan list queue */
+ outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+
+ /* Program one scan list entry */
+
+ v = DAQP_SCANLIST_CHANNEL(CR_CHAN(insn->chanspec))
+ | DAQP_SCANLIST_GAIN(CR_RANGE(insn->chanspec));
+
+ if (CR_AREF(insn->chanspec) == AREF_DIFF) {
+ v |= DAQP_SCANLIST_DIFFERENTIAL;
+ }
+
+ v |= DAQP_SCANLIST_START;
+
+ outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
+ outb(v >> 8, dev->iobase + DAQP_SCANLIST);
+
+ /* Reset data FIFO (see page 28 of DAQP User's Manual) */
+
+ outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+
+ /* Set trigger */
+
+ v = DAQP_CONTROL_TRIGGER_ONESHOT | DAQP_CONTROL_TRIGGER_INTERNAL
+ | DAQP_CONTROL_PACER_100kHz | DAQP_CONTROL_EOS_INT_ENABLE;
+
+ outb(v, dev->iobase + DAQP_CONTROL);
+
+ /* Reset any pending interrupts (my card has a tendancy to require
+ * require multiple reads on the status register to achieve this)
+ */
+
+ while (--counter
+ && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+ if (!counter) {
+ printk("daqp: couldn't clear interrupts in status register\n");
+ return -1;
+ }
+
+ /* Make sure semaphore is blocked */
+ sema_init(&local->eos, 0);
+ local->interrupt_mode = semaphore;
+ local->dev = dev;
+ local->s = s;
+
+ for (i = 0; i < insn->n; i++) {
+
+ /* Start conversion */
+ outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
+ dev->iobase + DAQP_COMMAND);
+
+ /* Wait for interrupt service routine to unblock semaphore */
+ /* Maybe could use a timeout here, but it's interruptible */
+ if (down_interruptible(&local->eos))
+ return -EINTR;
+
+ data[i] = inb(dev->iobase + DAQP_FIFO);
+ data[i] |= inb(dev->iobase + DAQP_FIFO) << 8;
+ data[i] ^= 0x8000;
+ }
+
+ return insn->n;
+}
+
+/* This function converts ns nanoseconds to a counter value suitable
+ * for programming the device. We always use the DAQP's 5 MHz clock,
+ * which with its 24-bit counter, allows values up to 84 seconds.
+ * Also, the function adjusts ns so that it cooresponds to the actual
+ * time that the device will use.
+ */
+
+static int daqp_ns_to_timer(unsigned int *ns, int round)
+{
+ int timer;
+
+ timer = *ns / 200;
+ *ns = timer * 200;
+
+ return timer;
+}
+
+/* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executed by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes.
+ */
+
+static int daqp_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_FOLLOW;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_NOW;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_FOLLOW)
+ err++;
+ if (cmd->convert_src != TRIG_NOW && cmd->convert_src != TRIG_TIMER)
+ err++;
+ if (cmd->scan_begin_src == TRIG_FOLLOW && cmd->convert_src == TRIG_NOW)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* 100 kHz - in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER
+ && cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+
+ /* If both scan_begin and convert are both timer values, the only
+ * way that can make sense is if the scan time is the number of
+ * conversions times the convert time
+ */
+
+ if (cmd->scan_begin_src == TRIG_TIMER && cmd->convert_src == TRIG_TIMER
+ && cmd->scan_begin_arg !=
+ cmd->convert_arg * cmd->scan_end_arg) {
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER && cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ daqp_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ daqp_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+static int daqp_ai_cmd(struct comedi_device * dev, struct comedi_subdevice * s)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ int counter = 100;
+ int scanlist_start_on_every_entry;
+ int threshold;
+
+ int i;
+ int v;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ /* Stop any running conversion */
+ daqp_ai_cancel(dev, s);
+
+ outb(0, dev->iobase + DAQP_AUX);
+
+ /* Reset scan list queue */
+ outb(DAQP_COMMAND_RSTQ, dev->iobase + DAQP_COMMAND);
+
+ /* Program pacer clock
+ *
+ * There's two modes we can operate in. If convert_src is
+ * TRIG_TIMER, then convert_arg specifies the time between
+ * each conversion, so we program the pacer clock to that
+ * frequency and set the SCANLIST_START bit on every scanlist
+ * entry. Otherwise, convert_src is TRIG_NOW, which means
+ * we want the fastest possible conversions, scan_begin_src
+ * is TRIG_TIMER, and scan_begin_arg specifies the time between
+ * each scan, so we program the pacer clock to this frequency
+ * and only set the SCANLIST_START bit on the first entry.
+ */
+
+ if (cmd->convert_src == TRIG_TIMER) {
+ int counter = daqp_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
+ outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
+ outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
+ scanlist_start_on_every_entry = 1;
+ } else {
+ int counter = daqp_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ outb(counter & 0xff, dev->iobase + DAQP_PACER_LOW);
+ outb((counter >> 8) & 0xff, dev->iobase + DAQP_PACER_MID);
+ outb((counter >> 16) & 0xff, dev->iobase + DAQP_PACER_HIGH);
+ scanlist_start_on_every_entry = 0;
+ }
+
+ /* Program scan list */
+
+ for (i = 0; i < cmd->chanlist_len; i++) {
+
+ int chanspec = cmd->chanlist[i];
+
+ /* Program one scan list entry */
+
+ v = DAQP_SCANLIST_CHANNEL(CR_CHAN(chanspec))
+ | DAQP_SCANLIST_GAIN(CR_RANGE(chanspec));
+
+ if (CR_AREF(chanspec) == AREF_DIFF) {
+ v |= DAQP_SCANLIST_DIFFERENTIAL;
+ }
+
+ if (i == 0 || scanlist_start_on_every_entry) {
+ v |= DAQP_SCANLIST_START;
+ }
+
+ outb(v & 0xff, dev->iobase + DAQP_SCANLIST);
+ outb(v >> 8, dev->iobase + DAQP_SCANLIST);
+ }
+
+ /* Now it's time to program the FIFO threshold, basically the
+ * number of samples the card will buffer before it interrupts
+ * the CPU.
+ *
+ * If we don't have a stop count, then use half the size of
+ * the FIFO (the manufacturer's recommendation). Consider
+ * that the FIFO can hold 2K samples (4K bytes). With the
+ * threshold set at half the FIFO size, we have a margin of
+ * error of 1024 samples. At the chip's maximum sample rate
+ * of 100,000 Hz, the CPU would have to delay interrupt
+ * service for a full 10 milliseconds in order to lose data
+ * here (as opposed to higher up in the kernel). I've never
+ * seen it happen. However, for slow sample rates it may
+ * buffer too much data and introduce too much delay for the
+ * user application.
+ *
+ * If we have a stop count, then things get more interesting.
+ * If the stop count is less than the FIFO size (actually
+ * three-quarters of the FIFO size - see below), we just use
+ * the stop count itself as the threshold, the card interrupts
+ * us when that many samples have been taken, and we kill the
+ * acquisition at that point and are done. If the stop count
+ * is larger than that, then we divide it by 2 until it's less
+ * than three quarters of the FIFO size (we always leave the
+ * top quarter of the FIFO as protection against sluggish CPU
+ * interrupt response) and use that as the threshold. So, if
+ * the stop count is 4000 samples, we divide by two twice to
+ * get 1000 samples, use that as the threshold, take four
+ * interrupts to get our 4000 samples and are done.
+ *
+ * The algorithm could be more clever. For example, if 81000
+ * samples are requested, we could set the threshold to 1500
+ * samples and take 54 interrupts to get 81000. But 54 isn't
+ * a power of two, so this algorithm won't find that option.
+ * Instead, it'll set the threshold at 1266 and take 64
+ * interrupts to get 81024 samples, of which the last 24 will
+ * be discarded... but we won't get the last interrupt until
+ * they've been collected. To find the first option, the
+ * computer could look at the prime decomposition of the
+ * sample count (81000 = 3^4 * 5^3 * 2^3) and factor it into a
+ * threshold (1500 = 3 * 5^3 * 2^2) and an interrupt count (54
+ * = 3^3 * 2). Hmmm... a one-line while loop or prime
+ * decomposition of integers... I'll leave it the way it is.
+ *
+ * I'll also note a mini-race condition before ignoring it in
+ * the code. Let's say we're taking 4000 samples, as before.
+ * After 1000 samples, we get an interrupt. But before that
+ * interrupt is completely serviced, another sample is taken
+ * and loaded into the FIFO. Since the interrupt handler
+ * empties the FIFO before returning, it will read 1001 samples.
+ * If that happens four times, we'll end up taking 4004 samples,
+ * not 4000. The interrupt handler will discard the extra four
+ * samples (by halting the acquisition with four samples still
+ * in the FIFO), but we will have to wait for them.
+ *
+ * In short, this code works pretty well, but for either of
+ * the two reasons noted, might end up waiting for a few more
+ * samples than actually requested. Shouldn't make too much
+ * of a difference.
+ */
+
+ /* Save away the number of conversions we should perform, and
+ * compute the FIFO threshold (in bytes, not samples - that's
+ * why we multiple local->count by 2 = sizeof(sample))
+ */
+
+ if (cmd->stop_src == TRIG_COUNT) {
+ local->count = cmd->stop_arg * cmd->scan_end_arg;
+ threshold = 2 * local->count;
+ while (threshold > DAQP_FIFO_SIZE * 3 / 4)
+ threshold /= 2;
+ } else {
+ local->count = -1;
+ threshold = DAQP_FIFO_SIZE / 2;
+ }
+
+ /* Reset data FIFO (see page 28 of DAQP User's Manual) */
+
+ outb(DAQP_COMMAND_RSTF, dev->iobase + DAQP_COMMAND);
+
+ /* Set FIFO threshold. First two bytes are near-empty
+ * threshold, which is unused; next two bytes are near-full
+ * threshold. We computed the number of bytes we want in the
+ * FIFO when the interrupt is generated, what the card wants
+ * is actually the number of available bytes left in the FIFO
+ * when the interrupt is to happen.
+ */
+
+ outb(0x00, dev->iobase + DAQP_FIFO);
+ outb(0x00, dev->iobase + DAQP_FIFO);
+
+ outb((DAQP_FIFO_SIZE - threshold) & 0xff, dev->iobase + DAQP_FIFO);
+ outb((DAQP_FIFO_SIZE - threshold) >> 8, dev->iobase + DAQP_FIFO);
+
+ /* Set trigger */
+
+ v = DAQP_CONTROL_TRIGGER_CONTINUOUS | DAQP_CONTROL_TRIGGER_INTERNAL
+ | DAQP_CONTROL_PACER_5MHz | DAQP_CONTROL_FIFO_INT_ENABLE;
+
+ outb(v, dev->iobase + DAQP_CONTROL);
+
+ /* Reset any pending interrupts (my card has a tendancy to require
+ * require multiple reads on the status register to achieve this)
+ */
+
+ while (--counter
+ && (inb(dev->iobase + DAQP_STATUS) & DAQP_STATUS_EVENTS)) ;
+ if (!counter) {
+ printk("daqp: couldn't clear interrupts in status register\n");
+ return -1;
+ }
+
+ local->interrupt_mode = buffer;
+ local->dev = dev;
+ local->s = s;
+
+ /* Start conversion */
+ outb(DAQP_COMMAND_ARM | DAQP_COMMAND_FIFO_DATA,
+ dev->iobase + DAQP_COMMAND);
+
+ return 0;
+}
+
+/* Single-shot analog output routine */
+
+static int daqp_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+ int d;
+ unsigned int chan;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ chan = CR_CHAN(insn->chanspec);
+ d = data[0];
+ d &= 0x0fff;
+ d ^= 0x0800; /* Flip the sign */
+ d |= chan << 12;
+
+ /* Make sure D/A update mode is direct update */
+ outb(0, dev->iobase + DAQP_AUX);
+
+ outw(d, dev->iobase + DAQP_DA);
+
+ return 1;
+}
+
+/* Digital input routine */
+
+static int daqp_di_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ data[0] = inb(dev->iobase + DAQP_DIGITAL_IO);
+
+ return 1;
+}
+
+/* Digital output routine */
+
+static int daqp_do_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct local_info_t *local = (struct local_info_t *) s->private;
+
+ if (local->stop) {
+ return -EIO;
+ }
+
+ outw(data[0] & 0xf, dev->iobase + DAQP_DIGITAL_IO);
+
+ return 1;
+}
+
+/* daqp_attach is called via comedi_config to attach a comedi device
+ * to a /dev/comedi*. Note that this is different from daqp_cs_attach()
+ * which is called by the pcmcia subsystem to attach the PCMCIA card
+ * when it is inserted.
+ */
+
+static int daqp_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int ret;
+ struct local_info_t *local = dev_table[it->options[0]];
+ tuple_t tuple;
+ int i;
+ struct comedi_subdevice *s;
+
+ if (it->options[0] < 0 || it->options[0] >= MAX_DEV || !local) {
+ printk("comedi%d: No such daqp device %d\n",
+ dev->minor, it->options[0]);
+ return -EIO;
+ }
+
+ /* Typically brittle code that I don't completely understand,
+ * but "it works on my card". The intent is to pull the model
+ * number of the card out the PCMCIA CIS and stash it away as
+ * the COMEDI board_name. Looks like the third field in
+ * CISTPL_VERS_1 (offset 2) holds what we're looking for. If
+ * it doesn't work, who cares, just leave it as "DAQP".
+ */
+
+ strcpy(local->board_name, "DAQP");
+ dev->board_name = local->board_name;
+
+ tuple.DesiredTuple = CISTPL_VERS_1;
+ if (pcmcia_get_first_tuple(local->link, &tuple) == 0) {
+ u_char buf[128];
+
+ buf[0] = buf[sizeof(buf) - 1] = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 2;
+ if (pcmcia_get_tuple_data(local->link, &tuple) == 0) {
+
+ for (i = 0; i < tuple.TupleDataLen - 4; i++)
+ if (buf[i] == 0)
+ break;
+ for (i++; i < tuple.TupleDataLen - 4; i++)
+ if (buf[i] == 0)
+ break;
+ i++;
+ if ((i < tuple.TupleDataLen - 4)
+ && (strncmp(buf + i, "DAQP", 4) == 0)) {
+ strncpy(local->board_name, buf + i,
+ sizeof(local->board_name));
+ }
+ }
+ }
+
+ dev->iobase = local->link->io.BasePort1;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+
+ printk("comedi%d: attaching daqp%d (io 0x%04lx)\n",
+ dev->minor, it->options[0], dev->iobase);
+
+ s = dev->subdevices + 0;
+ dev->read_subdev = s;
+ s->private = local;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF | SDF_CMD_READ;
+ s->n_chan = 8;
+ s->len_chanlist = 2048;
+ s->maxdata = 0xffff;
+ s->range_table = &range_daqp_ai;
+ s->insn_read = daqp_ai_insn_read;
+ s->do_cmdtest = daqp_ai_cmdtest;
+ s->do_cmd = daqp_ai_cmd;
+ s->cancel = daqp_ai_cancel;
+
+ s = dev->subdevices + 1;
+ dev->write_subdev = s;
+ s->private = local;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 2;
+ s->len_chanlist = 1;
+ s->maxdata = 0x0fff;
+ s->range_table = &range_daqp_ao;
+ s->insn_write = daqp_ao_insn_write;
+
+ s = dev->subdevices + 2;
+ s->private = local;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 1;
+ s->len_chanlist = 1;
+ s->insn_read = daqp_di_insn_read;
+
+ s = dev->subdevices + 3;
+ s->private = local;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 1;
+ s->len_chanlist = 1;
+ s->insn_write = daqp_do_insn_write;
+
+ return 1;
+}
+
+/* daqp_detach (called from comedi_comdig) does nothing. If the PCMCIA
+ * card is removed, daqp_cs_detach() is called by the pcmcia subsystem.
+ */
+
+static int daqp_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: detaching daqp\n", dev->minor);
+
+ return 0;
+}
+
+/*====================================================================
+
+ PCMCIA interface code
+
+ The rest of the code in this file is based on dummy_cs.c v1.24
+ from the Linux pcmcia_cs distribution v3.1.8 and is subject
+ to the following license agreement.
+
+ The remaining contents of this file are subject to the Mozilla Public
+ License Version 1.1 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of
+ the License at http://www.mozilla.org/MPL/
+
+ Software distributed under the License is distributed on an "AS
+ IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ rights and limitations under the License.
+
+ The initial developer of the original code is David A. Hinds
+ <dhinds@pcmcia.sourceforge.org>. Portions created by David A. Hinds
+ are Copyright (C) 1999 David A. Hinds. All Rights Reserved.
+
+ Alternatively, the contents of this file may be used under the
+ terms of the GNU Public License version 2 (the "GPL"), in which
+ case the provisions of the GPL are applicable instead of the
+ above. If you wish to allow the use of your version of this file
+ only under the terms of the GPL and not to allow others to use
+ your version of this file under the MPL, indicate your decision
+ by deleting the provisions above and replace them with the notice
+ and other provisions required by the GPL. If you do not delete
+ the provisions above, a recipient may use your version of this
+ file under either the MPL or the GPL.
+
+======================================================================*/
+
+/*
+ The event() function is this driver's Card Services event handler.
+ It will be called by Card Services when an appropriate card status
+ event is received. The config() and release() entry points are
+ used to configure or release a socket, in response to card
+ insertion and ejection events.
+
+ Kernel version 2.6.16 upwards uses suspend() and resume() functions
+ instead of an event() function.
+*/
+
+static void daqp_cs_config(struct pcmcia_device *link);
+static void daqp_cs_release(struct pcmcia_device *link);
+static int daqp_cs_suspend(struct pcmcia_device *p_dev);
+static int daqp_cs_resume(struct pcmcia_device *p_dev);
+
+/*
+ The attach() and detach() entry points are used to create and destroy
+ "instances" of the driver, where each instance represents everything
+ needed to manage one actual PCMCIA card.
+*/
+
+static int daqp_cs_attach(struct pcmcia_device *);
+static void daqp_cs_detach(struct pcmcia_device *);
+
+/*
+ The dev_info variable is the "key" that is used to match up this
+ device driver with appropriate cards, through the card configuration
+ database.
+*/
+
+static const dev_info_t dev_info = "quatech_daqp_cs";
+
+/*======================================================================
+
+ daqp_cs_attach() creates an "instance" of the driver, allocating
+ local data structures for one device. The device is registered
+ with Card Services.
+
+ The dev_link structure is initialized, but we don't actually
+ configure the card at this point -- we wait until we receive a
+ card insertion event.
+
+======================================================================*/
+
+static int daqp_cs_attach(struct pcmcia_device *link)
+{
+ struct local_info_t *local;
+ int i;
+
+ DEBUG(0, "daqp_cs_attach()\n");
+
+ for (i = 0; i < MAX_DEV; i++)
+ if (dev_table[i] == NULL)
+ break;
+ if (i == MAX_DEV) {
+ printk(KERN_NOTICE "daqp_cs: no devices available\n");
+ return -ENODEV;
+ }
+
+ /* Allocate space for private device-specific data */
+ local = kzalloc(sizeof(struct local_info_t), GFP_KERNEL);
+ if (!local)
+ return -ENOMEM;
+
+ local->table_index = i;
+ dev_table[i] = local;
+ local->link = link;
+ link->priv = local;
+
+ /* Interrupt setup */
+ link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+ link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+ link->irq.Handler = daqp_interrupt;
+ link->irq.Instance = local;
+
+ /*
+ General socket configuration defaults can go here. In this
+ client, we assume very little, and rely on the CIS for almost
+ everything. In most clients, many details (i.e., number, sizes,
+ and attributes of IO windows) are fixed by the nature of the
+ device, and can be hard-wired here.
+ */
+ link->conf.Attributes = 0;
+ link->conf.IntType = INT_MEMORY_AND_IO;
+
+ daqp_cs_config(link);
+
+ return 0;
+} /* daqp_cs_attach */
+
+/*======================================================================
+
+ This deletes a driver "instance". The device is de-registered
+ with Card Services. If it has been released, all local data
+ structures are freed. Otherwise, the structures will be freed
+ when the device is released.
+
+======================================================================*/
+
+static void daqp_cs_detach(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+
+ DEBUG(0, "daqp_cs_detach(0x%p)\n", link);
+
+ if (link->dev_node) {
+ dev->stop = 1;
+ daqp_cs_release(link);
+ }
+
+ /* Unlink device structure, and free it */
+ dev_table[dev->table_index] = NULL;
+ if (dev)
+ kfree(dev);
+
+} /* daqp_cs_detach */
+
+/*======================================================================
+
+ daqp_cs_config() is scheduled to run after a CARD_INSERTION event
+ is received, to configure the PCMCIA socket, and to make the
+ device available to the system.
+
+======================================================================*/
+
+static void daqp_cs_config(struct pcmcia_device *link)
+{
+ struct local_info_t *dev = link->priv;
+ tuple_t tuple;
+ cisparse_t parse;
+ int last_ret;
+ u_char buf[64];
+
+ DEBUG(0, "daqp_cs_config(0x%p)\n", link);
+
+ /*
+ This reads the card's CONFIG tuple to find its configuration
+ registers.
+ */
+ tuple.DesiredTuple = CISTPL_CONFIG;
+ tuple.Attributes = 0;
+ tuple.TupleData = buf;
+ tuple.TupleDataMax = sizeof(buf);
+ tuple.TupleOffset = 0;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_get_tuple_data(link, &tuple))) {
+ cs_error(link, GetTupleData, last_ret);
+ goto cs_failed;
+ }
+ if ((last_ret = pcmcia_parse_tuple(&tuple, &parse))) {
+ cs_error(link, ParseTuple, last_ret);
+ goto cs_failed;
+ }
+ link->conf.ConfigBase = parse.config.base;
+ link->conf.Present = parse.config.rmask[0];
+
+ /*
+ In this loop, we scan the CIS for configuration table entries,
+ each of which describes a valid card configuration, including
+ voltage, IO window, memory window, and interrupt settings.
+
+ We make no assumptions about the card to be configured: we use
+ just the information available in the CIS. In an ideal world,
+ this would work for any PCMCIA card, but it requires a complete
+ and accurate CIS. In practice, a driver usually "knows" most of
+ these things without consulting the CIS, and most client drivers
+ will only use the CIS to fill in implementation-defined details.
+ */
+ tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+ if ((last_ret = pcmcia_get_first_tuple(link, &tuple))) {
+ cs_error(link, GetFirstTuple, last_ret);
+ goto cs_failed;
+ }
+ while (1) {
+ cistpl_cftable_entry_t dflt = { 0 };
+ cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+ if (pcmcia_get_tuple_data(link, &tuple))
+ goto next_entry;
+ if (pcmcia_parse_tuple(&tuple, &parse))
+ goto next_entry;
+
+ if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+ dflt = *cfg;
+ if (cfg->index == 0)
+ goto next_entry;
+ link->conf.ConfigIndex = cfg->index;
+
+ /* Do we need to allocate an interrupt? */
+ if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
+ link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+ /* IO window settings */
+ link->io.NumPorts1 = link->io.NumPorts2 = 0;
+ if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+ cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ if (!(io->flags & CISTPL_IO_8BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ if (!(io->flags & CISTPL_IO_16BIT))
+ link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+ link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+ link->io.BasePort1 = io->win[0].base;
+ link->io.NumPorts1 = io->win[0].len;
+ if (io->nwin > 1) {
+ link->io.Attributes2 = link->io.Attributes1;
+ link->io.BasePort2 = io->win[1].base;
+ link->io.NumPorts2 = io->win[1].len;
+ }
+ }
+
+ /* This reserves IO space but doesn't actually enable it */
+ if (pcmcia_request_io(link, &link->io))
+ goto next_entry;
+
+ /* If we got this far, we're cool! */
+ break;
+
+ next_entry:
+ if ((last_ret = pcmcia_get_next_tuple(link, &tuple))) {
+ cs_error(link, GetNextTuple, last_ret);
+ goto cs_failed;
+ }
+ }
+
+ /*
+ Allocate an interrupt line. Note that this does not assign a
+ handler to the interrupt, unless the 'Handler' member of the
+ irq structure is initialized.
+ */
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ if ((last_ret = pcmcia_request_irq(link, &link->irq))) {
+ cs_error(link, RequestIRQ, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ This actually configures the PCMCIA socket -- setting up
+ the I/O windows and the interrupt mapping, and putting the
+ card and host interface into "Memory and IO" mode.
+ */
+ if ((last_ret = pcmcia_request_configuration(link, &link->conf))) {
+ cs_error(link, RequestConfiguration, last_ret);
+ goto cs_failed;
+ }
+
+ /*
+ At this point, the dev_node_t structure(s) need to be
+ initialized and arranged in a linked list at link->dev.
+ */
+ /* Comedi's PCMCIA script uses this device name (extracted
+ * from /var/lib/pcmcia/stab) to pass to comedi_config
+ */
+ /* sprintf(dev->node.dev_name, "daqp%d", dev->table_index); */
+ sprintf(dev->node.dev_name, "quatech_daqp_cs");
+ dev->node.major = dev->node.minor = 0;
+ link->dev_node = &dev->node;
+
+ /* Finally, report what we've done */
+ printk(KERN_INFO "%s: index 0x%02x",
+ dev->node.dev_name, link->conf.ConfigIndex);
+ if (link->conf.Attributes & CONF_ENABLE_IRQ)
+ printk(", irq %u", link->irq.AssignedIRQ);
+ if (link->io.NumPorts1)
+ printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+ link->io.BasePort1 + link->io.NumPorts1 - 1);
+ if (link->io.NumPorts2)
+ printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+ link->io.BasePort2 + link->io.NumPorts2 - 1);
+ printk("\n");
+
+ return;
+
+ cs_failed:
+ daqp_cs_release(link);
+
+} /* daqp_cs_config */
+
+static void daqp_cs_release(struct pcmcia_device *link)
+{
+ DEBUG(0, "daqp_cs_release(0x%p)\n", link);
+
+ pcmcia_disable_device(link);
+} /* daqp_cs_release */
+
+/*======================================================================
+
+ The card status event handler. Mostly, this schedules other
+ stuff to run after an event is received.
+
+ When a CARD_REMOVAL event is received, we immediately set a
+ private flag to block future accesses to this device. All the
+ functions that actually access the device should check this flag
+ to make sure the card is still present.
+
+======================================================================*/
+
+static int daqp_cs_suspend(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ /* Mark the device as stopped, to block IO until later */
+ local->stop = 1;
+ return 0;
+}
+
+static int daqp_cs_resume(struct pcmcia_device *link)
+{
+ struct local_info_t *local = link->priv;
+
+ local->stop = 0;
+
+ return 0;
+}
+
+/*====================================================================*/
+
+#ifdef MODULE
+
+static struct pcmcia_device_id daqp_cs_id_table[] = {
+ PCMCIA_DEVICE_MANF_CARD(0x0137, 0x0027),
+ PCMCIA_DEVICE_NULL
+};
+
+MODULE_DEVICE_TABLE(pcmcia, daqp_cs_id_table);
+
+struct pcmcia_driver daqp_cs_driver = {
+ .probe = daqp_cs_attach,
+ .remove = daqp_cs_detach,
+ .suspend = daqp_cs_suspend,
+ .resume = daqp_cs_resume,
+ .id_table = daqp_cs_id_table,
+ .owner = THIS_MODULE,
+ .drv = {
+ .name = dev_info,
+ },
+};
+
+int __init init_module(void)
+{
+ DEBUG(0, "%s\n", version);
+ pcmcia_register_driver(&daqp_cs_driver);
+ comedi_driver_register(&driver_daqp);
+ return 0;
+}
+
+void __exit cleanup_module(void)
+{
+ DEBUG(0, "daqp_cs: unloading\n");
+ comedi_driver_unregister(&driver_daqp);
+ pcmcia_unregister_driver(&daqp_cs_driver);
+}
+
+#endif
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c
index 65d5242a258..ca347f21d14 100644
--- a/drivers/staging/comedi/drivers/rtd520.c
+++ b/drivers/staging/comedi/drivers/rtd520.c
@@ -196,7 +196,7 @@ Configuration options:
/*
The board has 3 input modes and the gains of 1,2,4,...32 (, 64, 128)
*/
-static const comedi_lrange rtd_ai_7520_range = { 18, {
+static const struct comedi_lrange rtd_ai_7520_range = { 18, {
/* +-5V input range gain steps */
BIP_RANGE(5.0),
BIP_RANGE(5.0 / 2),
@@ -223,7 +223,7 @@ static const comedi_lrange rtd_ai_7520_range = { 18, {
};
/* PCI4520 has two more gains (6 more entries) */
-static const comedi_lrange rtd_ai_4520_range = { 24, {
+static const struct comedi_lrange rtd_ai_4520_range = { 24, {
/* +-5V input range gain steps */
BIP_RANGE(5.0),
BIP_RANGE(5.0 / 2),
@@ -255,7 +255,7 @@ static const comedi_lrange rtd_ai_4520_range = { 24, {
};
/* Table order matches range values */
-static const comedi_lrange rtd_ao_range = { 4, {
+static const struct comedi_lrange rtd_ao_range = { 4, {
RANGE(0, 5),
RANGE(0, 10),
RANGE(-5, 5),
@@ -266,7 +266,7 @@ static const comedi_lrange rtd_ao_range = { 4, {
/*
Board descriptions
*/
-typedef struct rtdBoard_struct {
+struct rtdBoard {
const char *name; /* must be first */
int device_id;
int aiChans;
@@ -274,12 +274,12 @@ typedef struct rtdBoard_struct {
int aiMaxGain;
int range10Start; /* start of +-10V range */
int rangeUniStart; /* start of +10V range */
-} rtdBoard;
+};
-static const rtdBoard rtd520Boards[] = {
+static const struct rtdBoard rtd520Boards[] = {
{
name: "DM7520",
- device_id:0x7520,
+ device_id : 0x7520,
aiChans: 16,
aiBits: 12,
aiMaxGain:32,
@@ -288,7 +288,7 @@ static const rtdBoard rtd520Boards[] = {
},
{
name: "PCI4520",
- device_id:0x4520,
+ device_id : 0x4520,
aiChans: 16,
aiBits: 12,
aiMaxGain:128,
@@ -308,13 +308,13 @@ MODULE_DEVICE_TABLE(pci, rtd520_pci_table);
/*
* Useful for shorthand access to the particular board structure
*/
-#define thisboard ((const rtdBoard *)dev->board_ptr)
+#define thisboard ((const struct rtdBoard *)dev->board_ptr)
/*
This structure is for data unique to this hardware driver.
This is also unique for each board in the system.
*/
-typedef struct {
+struct rtdPrivate {
/* memory mapped board structures */
void *las0;
void *las1;
@@ -334,7 +334,7 @@ typedef struct {
unsigned char chanBipolar[RTD_MAX_CHANLIST / 8]; /* bit array */
/* read back data */
- lsampl_t aoValue[2]; /* Used for AO read back */
+ unsigned int aoValue[2]; /* Used for AO read back */
/* timer gate (when enabled) */
u8 utcGate[4]; /* 1 extra allows simple range check */
@@ -358,7 +358,7 @@ typedef struct {
u8 dma1Control;
#endif /* USE_DMA */
unsigned fifoLen;
-} rtdPrivate;
+};
/* bit defines for "flags" */
#define SEND_EOS 0x01 /* send End Of Scan events */
@@ -366,18 +366,18 @@ typedef struct {
#define DMA1_ACTIVE 0x04 /* DMA1 is active */
/* Macros for accessing channel list bit array */
-#define CHAN_ARRAY_TEST(array,index) \
+#define CHAN_ARRAY_TEST(array, index) \
(((array)[(index)/8] >> ((index) & 0x7)) & 0x1)
-#define CHAN_ARRAY_SET(array,index) \
+#define CHAN_ARRAY_SET(array, index) \
(((array)[(index)/8] |= 1 << ((index) & 0x7)))
-#define CHAN_ARRAY_CLEAR(array,index) \
+#define CHAN_ARRAY_CLEAR(array, index) \
(((array)[(index)/8] &= ~(1 << ((index) & 0x7))))
/*
* most drivers define the following macro to make it easy to
* access the private structure.
*/
-#define devpriv ((rtdPrivate *)dev->private)
+#define devpriv ((struct rtdPrivate *)dev->private)
/* Macros to access registers */
@@ -394,15 +394,15 @@ typedef struct {
writel (0, devpriv->las0+LAS0_CGT_CLEAR)
/* Reset channel gain table read and write pointers */
-#define RtdEnableCGT(dev,v) \
+#define RtdEnableCGT(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_CGT_ENABLE)
/* Write channel gain table entry */
-#define RtdWriteCGTable(dev,v) \
+#define RtdWriteCGTable(dev, v) \
writel (v, devpriv->las0+LAS0_CGT_WRITE)
/* Write Channel Gain Latch */
-#define RtdWriteCGLatch(dev,v) \
+#define RtdWriteCGLatch(dev, v) \
writel (v, devpriv->las0+LAS0_CGL_WRITE)
/* Reset ADC FIFO */
@@ -410,39 +410,39 @@ typedef struct {
writel (0, devpriv->las0+LAS0_ADC_FIFO_CLEAR)
/* Set ADC start conversion source select (write only) */
-#define RtdAdcConversionSource(dev,v) \
+#define RtdAdcConversionSource(dev, v) \
writel (v, devpriv->las0+LAS0_ADC_CONVERSION)
/* Set burst start source select (write only) */
-#define RtdBurstStartSource(dev,v) \
+#define RtdBurstStartSource(dev, v) \
writel (v, devpriv->las0+LAS0_BURST_START)
/* Set Pacer start source select (write only) */
-#define RtdPacerStartSource(dev,v) \
+#define RtdPacerStartSource(dev, v) \
writel (v, devpriv->las0+LAS0_PACER_START)
/* Set Pacer stop source select (write only) */
-#define RtdPacerStopSource(dev,v) \
+#define RtdPacerStopSource(dev, v) \
writel (v, devpriv->las0+LAS0_PACER_STOP)
/* Set Pacer clock source select (write only) 0=external 1=internal */
-#define RtdPacerClockSource(dev,v) \
+#define RtdPacerClockSource(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_SELECT)
/* Set sample counter source select (write only) */
-#define RtdAdcSampleCounterSource(dev,v) \
+#define RtdAdcSampleCounterSource(dev, v) \
writel (v, devpriv->las0+LAS0_ADC_SCNT_SRC)
/* Set Pacer trigger mode select (write only) 0=single cycle, 1=repeat */
-#define RtdPacerTriggerMode(dev,v) \
+#define RtdPacerTriggerMode(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_PACER_REPEAT)
/* Set About counter stop enable (write only) */
-#define RtdAboutStopEnable(dev,v) \
+#define RtdAboutStopEnable(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ACNT_STOP_ENABLE)
/* Set external trigger polarity (write only) 0=positive edge, 1=negative */
-#define RtdTriggerPolarity(dev,v) \
+#define RtdTriggerPolarity(dev, v) \
writel ((v > 0) ? 1 : 0, devpriv->las0+LAS0_ETRG_POLARITY)
/* Start single ADC conversion */
@@ -473,15 +473,15 @@ typedef struct {
readw (devpriv->las0+LAS0_IT)
/* Interrupt mask */
-#define RtdInterruptMask(dev,v) \
- writew ((devpriv->intMask = (v)),devpriv->las0+LAS0_IT)
+#define RtdInterruptMask(dev, v) \
+ writew ((devpriv->intMask = (v)), devpriv->las0+LAS0_IT)
/* Interrupt status clear (only bits set in mask) */
#define RtdInterruptClear(dev) \
readw (devpriv->las0+LAS0_CLEAR)
/* Interrupt clear mask */
-#define RtdInterruptClearMask(dev,v) \
+#define RtdInterruptClearMask(dev, v) \
writew ((devpriv->intClearMask = (v)), devpriv->las0+LAS0_CLEAR)
/* Interrupt overrun status */
@@ -495,92 +495,92 @@ typedef struct {
/* Pacer counter, 24bit */
#define RtdPacerCount(dev) \
readl (devpriv->las0+LAS0_PCLK)
-#define RtdPacerCounter(dev,v) \
- writel ((v) & 0xffffff,devpriv->las0+LAS0_PCLK)
+#define RtdPacerCounter(dev, v) \
+ writel ((v) & 0xffffff, devpriv->las0+LAS0_PCLK)
/* Burst counter, 10bit */
#define RtdBurstCount(dev) \
readl (devpriv->las0+LAS0_BCLK)
-#define RtdBurstCounter(dev,v) \
- writel ((v) & 0x3ff,devpriv->las0+LAS0_BCLK)
+#define RtdBurstCounter(dev, v) \
+ writel ((v) & 0x3ff, devpriv->las0+LAS0_BCLK)
/* Delay counter, 16bit */
#define RtdDelayCount(dev) \
readl (devpriv->las0+LAS0_DCLK)
-#define RtdDelayCounter(dev,v) \
+#define RtdDelayCounter(dev, v) \
writel ((v) & 0xffff, devpriv->las0+LAS0_DCLK)
/* About counter, 16bit */
#define RtdAboutCount(dev) \
readl (devpriv->las0+LAS0_ACNT)
-#define RtdAboutCounter(dev,v) \
+#define RtdAboutCounter(dev, v) \
writel ((v) & 0xffff, devpriv->las0+LAS0_ACNT)
/* ADC sample counter, 10bit */
#define RtdAdcSampleCount(dev) \
readl (devpriv->las0+LAS0_ADC_SCNT)
-#define RtdAdcSampleCounter(dev,v) \
+#define RtdAdcSampleCounter(dev, v) \
writel ((v) & 0x3ff, devpriv->las0+LAS0_ADC_SCNT)
/* User Timer/Counter (8254) */
-#define RtdUtcCounterGet(dev,n) \
+#define RtdUtcCounterGet(dev, n) \
readb (devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
-#define RtdUtcCounterPut(dev,n,v) \
+#define RtdUtcCounterPut(dev, n, v) \
writeb ((v) & 0xff, devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0 : ((1 == n) ? LAS0_UTC1 : LAS0_UTC2)))
/* Set UTC (8254) control byte */
-#define RtdUtcCtrlPut(dev,n,v) \
+#define RtdUtcCtrlPut(dev, n, v) \
writeb (devpriv->utcCtrl[(n) & 3] = (((n) & 3) << 6) | ((v) & 0x3f), \
devpriv->las0 + LAS0_UTC_CTRL)
/* Set UTCn clock source (write only) */
-#define RtdUtcClockSource(dev,n,v) \
+#define RtdUtcClockSource(dev, n, v) \
writew (v, devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0_CLOCK : \
((1 == n) ? LAS0_UTC1_CLOCK : LAS0_UTC2_CLOCK)))
/* Set UTCn gate source (write only) */
-#define RtdUtcGateSource(dev,n,v) \
+#define RtdUtcGateSource(dev, n, v) \
writew (v, devpriv->las0 \
+ ((n <= 0) ? LAS0_UTC0_GATE : \
((1 == n) ? LAS0_UTC1_GATE : LAS0_UTC2_GATE)))
/* User output N source select (write only) */
-#define RtdUsrOutSource(dev,n,v) \
- writel (v,devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
+#define RtdUsrOutSource(dev, n, v) \
+ writel (v, devpriv->las0+((n <= 0) ? LAS0_UOUT0_SELECT : LAS0_UOUT1_SELECT))
/* Digital IO */
#define RtdDio0Read(dev) \
(readw (devpriv->las0+LAS0_DIO0) & 0xff)
-#define RtdDio0Write(dev,v) \
+#define RtdDio0Write(dev, v) \
writew ((v) & 0xff, devpriv->las0+LAS0_DIO0)
#define RtdDio1Read(dev) \
(readw (devpriv->las0+LAS0_DIO1) & 0xff)
-#define RtdDio1Write(dev,v) \
+#define RtdDio1Write(dev, v) \
writew ((v) & 0xff, devpriv->las0+LAS0_DIO1)
#define RtdDioStatusRead(dev) \
(readw (devpriv->las0+LAS0_DIO_STATUS) & 0xff)
-#define RtdDioStatusWrite(dev,v) \
+#define RtdDioStatusWrite(dev, v) \
writew ((devpriv->dioStatus = (v)), devpriv->las0+LAS0_DIO_STATUS)
#define RtdDio0CtrlRead(dev) \
(readw (devpriv->las0+LAS0_DIO0_CTRL) & 0xff)
-#define RtdDio0CtrlWrite(dev,v) \
+#define RtdDio0CtrlWrite(dev, v) \
writew ((v) & 0xff, devpriv->las0+LAS0_DIO0_CTRL)
/* Digital to Analog converter */
/* Write one data value (sign + 12bit + marker bits) */
/* Note: matches what DMA would put. Actual value << 3 */
-#define RtdDacFifoPut(dev,n,v) \
+#define RtdDacFifoPut(dev, n, v) \
writew ((v), devpriv->las1 +(((n) == 0) ? LAS1_DAC1_FIFO : LAS1_DAC2_FIFO))
/* Start single DAC conversion */
-#define RtdDacUpdate(dev,n) \
+#define RtdDacUpdate(dev, n) \
writew (0, devpriv->las0 +(((n) == 0) ? LAS0_DAC1 : LAS0_DAC2))
/* Start single DAC conversion on both DACs */
@@ -588,20 +588,20 @@ typedef struct {
writew (0, devpriv->las0+LAS0_DAC)
/* Set DAC output type and range */
-#define RtdDacRange(dev,n,v) \
+#define RtdDacRange(dev, n, v) \
writew ((v) & 7, devpriv->las0 \
+(((n) == 0) ? LAS0_DAC1_CTRL : LAS0_DAC2_CTRL))
/* Reset DAC FIFO */
-#define RtdDacClearFifo(dev,n) \
+#define RtdDacClearFifo(dev, n) \
writel (0, devpriv->las0+(((n) == 0) ? LAS0_DAC1_RESET : LAS0_DAC2_RESET))
/* Set source for DMA 0 (write only, shadow?) */
-#define RtdDma0Source(dev,n) \
+#define RtdDma0Source(dev, n) \
writel ((n) & 0xf, devpriv->las0+LAS0_DMA0_SRC)
/* Set source for DMA 1 (write only, shadow?) */
-#define RtdDma1Source(dev,n) \
+#define RtdDma1Source(dev, n) \
writel ((n) & 0xf, devpriv->las0+LAS0_DMA1_SRC)
/* Reset board state for DMA 0 */
@@ -615,51 +615,51 @@ typedef struct {
/* PLX9080 interrupt mask and status */
#define RtdPlxInterruptRead(dev) \
readl (devpriv->lcfg+LCFG_ITCSR)
-#define RtdPlxInterruptWrite(dev,v) \
+#define RtdPlxInterruptWrite(dev, v) \
writel (v, devpriv->lcfg+LCFG_ITCSR)
/* Set mode for DMA 0 */
-#define RtdDma0Mode(dev,m) \
+#define RtdDma0Mode(dev, m) \
writel ((m), devpriv->lcfg+LCFG_DMAMODE0)
/* Set PCI address for DMA 0 */
-#define RtdDma0PciAddr(dev,a) \
+#define RtdDma0PciAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMAPADR0)
/* Set local address for DMA 0 */
-#define RtdDma0LocalAddr(dev,a) \
+#define RtdDma0LocalAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMALADR0)
/* Set byte count for DMA 0 */
-#define RtdDma0Count(dev,c) \
+#define RtdDma0Count(dev, c) \
writel ((c), devpriv->lcfg+LCFG_DMASIZ0)
/* Set next descriptor for DMA 0 */
-#define RtdDma0Next(dev,a) \
+#define RtdDma0Next(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMADPR0)
/* Set mode for DMA 1 */
-#define RtdDma1Mode(dev,m) \
+#define RtdDma1Mode(dev, m) \
writel ((m), devpriv->lcfg+LCFG_DMAMODE1)
/* Set PCI address for DMA 1 */
-#define RtdDma1PciAddr(dev,a) \
+#define RtdDma1PciAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMAADR1)
/* Set local address for DMA 1 */
-#define RtdDma1LocalAddr(dev,a) \
+#define RtdDma1LocalAddr(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMALADR1)
/* Set byte count for DMA 1 */
-#define RtdDma1Count(dev,c) \
+#define RtdDma1Count(dev, c) \
writel ((c), devpriv->lcfg+LCFG_DMASIZ1)
/* Set next descriptor for DMA 1 */
-#define RtdDma1Next(dev,a) \
+#define RtdDma1Next(dev, a) \
writel ((a), devpriv->lcfg+LCFG_DMADPR1)
/* Set control for DMA 0 (write only, shadow?) */
-#define RtdDma0Control(dev,n) \
+#define RtdDma0Control(dev, n) \
writeb (devpriv->dma0Control = (n), devpriv->lcfg+LCFG_DMACSR0)
/* Get status for DMA 0 */
@@ -667,7 +667,7 @@ typedef struct {
readb (devpriv->lcfg+LCFG_DMACSR0)
/* Set control for DMA 1 (write only, shadow?) */
-#define RtdDma1Control(dev,n) \
+#define RtdDma1Control(dev, n) \
writeb (devpriv->dma1Control = (n), devpriv->lcfg+LCFG_DMACSR1)
/* Get status for DMA 1 */
@@ -675,39 +675,39 @@ typedef struct {
readb (devpriv->lcfg+LCFG_DMACSR1)
/*
- * The comedi_driver structure tells the Comedi core module
+ * The struct comedi_driver structure tells the Comedi core module
* which functions to call to configure/deconfigure (attac/detach)
* the board, and also about the kernel module that contains
* the device code.
*/
-static int rtd_attach(comedi_device * dev, comedi_devconfig * it);
-static int rtd_detach(comedi_device * dev);
+static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int rtd_detach(struct comedi_device *dev);
-static comedi_driver rtd520Driver = {
+static struct comedi_driver rtd520Driver = {
driver_name: DRV_NAME,
- module:THIS_MODULE,
- attach:rtd_attach,
- detach:rtd_detach,
+ module : THIS_MODULE,
+ attach : rtd_attach,
+ detach : rtd_detach,
};
-static int rtd_ai_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_ao_winsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int rtd_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
- comedi_cmd * cmd);
-static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s);
-static int rtd_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-//static int rtd_ai_poll (comedi_device *dev,comedi_subdevice *s);
+static int rtd_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int rtd_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+/* static int rtd_ai_poll (struct comedi_device *dev,struct comedi_subdevice *s); */
static int rtd_ns_to_timer(unsigned int *ns, int roundMode);
static irqreturn_t rtd_interrupt(int irq, void *d PT_REGS_ARG);
-static int rtd520_probe_fifo_depth(comedi_device *dev);
+static int rtd520_probe_fifo_depth(struct comedi_device *dev);
/*
* Attach is called by the Comedi core to configure the driver
@@ -715,9 +715,9 @@ static int rtd520_probe_fifo_depth(comedi_device *dev);
* in the driver structure, dev->board_ptr contains that
* address.
*/
-static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
+static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{ /* board name and options flags */
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
struct pci_dev *pcidev;
int ret;
resource_size_t physLas0; /* configuation */
@@ -739,7 +739,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
* Allocate the private structure area. alloc_private() is a
* convenient macro defined in comedidev.h.
*/
- if (alloc_private(dev, sizeof(rtdPrivate)) < 0)
+ if (alloc_private(dev, sizeof(struct rtdPrivate)) < 0)
return -ENOMEM;
/*
@@ -779,7 +779,8 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
devpriv->pci_dev = pcidev;
dev->board_name = thisboard->name;
- if ((ret = comedi_pci_enable(pcidev, DRV_NAME)) < 0) {
+ ret = comedi_pci_enable(pcidev, DRV_NAME);
+ if (ret < 0) {
printk("Failed to enable PCI device and request regions.\n");
return ret;
}
@@ -866,7 +867,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
s->do_cmd = rtd_ai_cmd;
s->do_cmdtest = rtd_ai_cmdtest;
s->cancel = rtd_ai_cancel;
- /*s->poll = rtd_ai_poll; *//* not ready yet */
+ /* s->poll = rtd_ai_poll; */ /* not ready yet */
s = dev->subdevices + 1;
/* analog output subdevice */
@@ -918,8 +919,10 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
/* TODO: set user out source ??? */
/* check if our interrupt is available and get it */
- if ((ret = comedi_request_irq(devpriv->pci_dev->irq, rtd_interrupt,
- IRQF_SHARED, DRV_NAME, dev)) < 0) {
+ ret = comedi_request_irq(devpriv->pci_dev->irq, rtd_interrupt,
+ IRQF_SHARED, DRV_NAME, dev);
+
+ if (ret < 0) {
printk("Could not get interrupt! (%u)\n",
devpriv->pci_dev->irq);
return ret;
@@ -1005,7 +1008,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
#if 0
/* hit an error, clean up memory and return ret */
-//rtd_attach_die_error:
+/* rtd_attach_die_error: */
#ifdef USE_DMA
for (index = 0; index < DMA_CHAIN_COUNT; index++) {
if (NULL != devpriv->dma0Buff[index]) { /* free buffer memory */
@@ -1057,7 +1060,7 @@ static int rtd_attach(comedi_device * dev, comedi_devconfig * it)
* allocated by _attach(). dev->private and dev->subdevices are
* deallocated automatically by the core.
*/
-static int rtd_detach(comedi_device * dev)
+static int rtd_detach(struct comedi_device *dev)
{
#ifdef USE_DMA
int index;
@@ -1137,7 +1140,7 @@ static int rtd_detach(comedi_device * dev)
/*
Convert a single comedi channel-gain entry to a RTD520 table entry
*/
-static unsigned short rtdConvertChanGain(comedi_device * dev,
+static unsigned short rtdConvertChanGain(struct comedi_device *dev,
unsigned int comediChan, int chanIndex)
{ /* index in channel list */
unsigned int chan, range, aref;
@@ -1187,7 +1190,7 @@ static unsigned short rtdConvertChanGain(comedi_device * dev,
/*
Setup the channel-gain table from a comedi list
*/
-static void rtd_load_channelgain_list(comedi_device * dev,
+static void rtd_load_channelgain_list(struct comedi_device *dev,
unsigned int n_chan, unsigned int *list)
{
if (n_chan > 1) { /* setup channel gain table */
@@ -1206,9 +1209,9 @@ static void rtd_load_channelgain_list(comedi_device * dev,
/* determine fifo size by doing adc conversions until the fifo half
empty status flag clears */
-static int rtd520_probe_fifo_depth(comedi_device *dev)
+static int rtd520_probe_fifo_depth(struct comedi_device *dev)
{
- lsampl_t chanspec = CR_PACK(0, 0, AREF_GROUND);
+ unsigned int chanspec = CR_PACK(0, 0, AREF_GROUND);
unsigned i;
static const unsigned limit = 0x2000;
unsigned fifo_size = 0;
@@ -1234,7 +1237,7 @@ static int rtd520_probe_fifo_depth(comedi_device *dev)
return -EIO;
}
RtdAdcClearFifo(dev);
- if(fifo_size != 0x400 || fifo_size != 0x2000)
+ if(fifo_size != 0x400 && fifo_size != 0x2000)
{
rt_printk("\ncomedi: %s: unexpected fifo size of %i, expected 1024 or 8192.\n",
DRV_NAME, fifo_size);
@@ -1251,8 +1254,8 @@ static int rtd520_probe_fifo_depth(comedi_device *dev)
Note, we don't do any settling delays. Use a instruction list to
select, delay, then read.
*/
-static int rtd_ai_rinsn(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ai_rinsn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int n, ii;
int stat;
@@ -1304,12 +1307,12 @@ static int rtd_ai_rinsn(comedi_device * dev,
The manual claims that we can do a lword read, but it doesn't work here.
*/
-static int ai_read_n(comedi_device * dev, comedi_subdevice * s, int count)
+static int ai_read_n(struct comedi_device *dev, struct comedi_subdevice *s, int count)
{
int ii;
for (ii = 0; ii < count; ii++) {
- sampl_t sample;
+ short sample;
s16 d;
if (0 == devpriv->aiCount) { /* done */
@@ -1343,10 +1346,10 @@ static int ai_read_n(comedi_device * dev, comedi_subdevice * s, int count)
/*
unknown amout of data is waiting in fifo.
*/
-static int ai_read_dregs(comedi_device * dev, comedi_subdevice * s)
+static int ai_read_dregs(struct comedi_device *dev, struct comedi_subdevice *s)
{
while (RtdFifoStatus(dev) & FS_ADC_NOT_EMPTY) { /* 1 -> not empty */
- sampl_t sample;
+ short sample;
s16 d = RtdAdcFifoGet(dev); /* get 2s comp value */
if (0 == devpriv->aiCount) { /* done */
@@ -1372,20 +1375,20 @@ static int ai_read_dregs(comedi_device * dev, comedi_subdevice * s)
/*
Terminate a DMA transfer and wait for everything to quiet down
*/
-void abort_dma(comedi_device * dev, unsigned int channel)
+void abort_dma(struct comedi_device *dev, unsigned int channel)
{ /* DMA channel 0, 1 */
unsigned long dma_cs_addr; /* the control/status register */
uint8_t status;
unsigned int ii;
- //unsigned long flags;
+ /* unsigned long flags; */
dma_cs_addr = (unsigned long)devpriv->lcfg
+ ((channel == 0) ? LCFG_DMACSR0 : LCFG_DMACSR1);
- // spinlock for plx dma control/status reg
- //comedi_spin_lock_irqsave( &dev->spinlock, flags );
+ /* spinlock for plx dma control/status reg */
+ /* comedi_spin_lock_irqsave( &dev->spinlock, flags ); */
- // abort dma transfer if necessary
+ /* abort dma transfer if necessary */
status = readb(dma_cs_addr);
if ((status & PLX_DMA_EN_BIT) == 0) { /* not enabled (Error?) */
DPRINTK("rtd520: AbortDma on non-active channel %d (0x%x)\n",
@@ -1410,7 +1413,7 @@ void abort_dma(comedi_device * dev, unsigned int channel)
/* set abort bit for channel */
writeb(PLX_DMA_ABORT_BIT, dma_cs_addr);
- // wait for dma done bit to be set
+ /* wait for dma done bit to be set */
status = readb(dma_cs_addr);
for (ii = 0;
(status & PLX_DMA_DONE_BIT) == 0 && ii < RTD_DMA_TIMEOUT;
@@ -1424,14 +1427,14 @@ void abort_dma(comedi_device * dev, unsigned int channel)
}
abortDmaExit:
- //comedi_spin_unlock_irqrestore( &dev->spinlock, flags );
+ /* comedi_spin_unlock_irqrestore( &dev->spinlock, flags ); */
}
/*
Process what is in the DMA transfer buffer and pass to comedi
Note: this is not re-entrant
*/
-static int ai_process_dma(comedi_device * dev, comedi_subdevice * s)
+static int ai_process_dma(struct comedi_device *dev, struct comedi_subdevice *s)
{
int ii, n;
s16 *dp;
@@ -1441,7 +1444,7 @@ static int ai_process_dma(comedi_device * dev, comedi_subdevice * s)
dp = devpriv->dma0Buff[devpriv->dma0Offset];
for (ii = 0; ii < devpriv->fifoLen / 2;) { /* convert samples */
- sampl_t sample;
+ short sample;
if (CHAN_ARRAY_TEST(devpriv->chanBipolar, s->async->cur_chan)) {
sample = (*dp >> 3) + 2048; /* convert to comedi unsigned data */
@@ -1494,10 +1497,10 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
void *d /* our data */
PT_REGS_ARG)
{ /* cpu context (ignored) */
- comedi_device *dev = d; /* must be called "dev" for devpriv */
+ struct comedi_device *dev = d; /* must be called "dev" for devpriv */
u16 status;
u16 fifoStatus;
- comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */
+ struct comedi_subdevice *s = dev->subdevices + 0; /* analog in subdevice */
if (!dev->attached) {
return IRQ_NONE;
@@ -1645,7 +1648,7 @@ static irqreturn_t rtd_interrupt(int irq, /* interrupt number (ignored) */
/*
return the number of samples available
*/
-static int rtd_ai_poll(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_poll(struct comedi_device *dev, struct comedi_subdevice *s)
{
/* TODO: This needs to mask interrupts, read_dregs, and then re-enable */
/* Not sure what to do if DMA is active */
@@ -1662,8 +1665,8 @@ static int rtd_ai_poll(comedi_device * dev, comedi_subdevice * s)
the command passes.
*/
-static int rtd_ai_cmdtest(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int rtd_ai_cmdtest(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -1867,9 +1870,9 @@ static int rtd_ai_cmdtest(comedi_device * dev,
This is usually done by an interrupt handler.
Userland gets to the data using read calls.
*/
-static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
int timer;
/* stop anything currently running */
@@ -2064,7 +2067,7 @@ static int rtd_ai_cmd(comedi_device * dev, comedi_subdevice * s)
/*
Stop a running data aquisition.
*/
-static int rtd_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int rtd_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
u16 status;
@@ -2132,8 +2135,8 @@ static int rtd_ns_to_timer(unsigned int *ns, int round_mode)
/*
Output one (or more) analog values to a single port as fast as possible.
*/
-static int rtd_ao_winsn(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ao_winsn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -2152,7 +2155,7 @@ static int rtd_ao_winsn(comedi_device * dev,
/* VERIFY: comedi range and offset conversions */
if ((range > 1) /* bipolar */
- &&(data[i] < 2048)) {
+ && (data[i] < 2048)) {
/* offset and sign extend */
val = (((int)data[i]) - 2048) << 3;
} else { /* unipolor */
@@ -2187,8 +2190,8 @@ static int rtd_ao_winsn(comedi_device * dev,
/* AO subdevices should have a read insn as well as a write insn.
* Usually this means copying a value stored in devpriv. */
-static int rtd_ao_rinsn(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_ao_rinsn(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -2210,8 +2213,8 @@ static int rtd_ao_rinsn(comedi_device * dev,
* This allows packed reading/writing of the DIO channels. The
* comedi core can convert between insn_bits and insn_read/write
*/
-static int rtd_dio_insn_bits(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_dio_insn_bits(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
if (insn->n != 2)
return -EINVAL;
@@ -2237,8 +2240,8 @@ static int rtd_dio_insn_bits(comedi_device * dev,
/*
Configure one bit on a IO port as Input or Output (hence the name :-).
*/
-static int rtd_dio_insn_config(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+static int rtd_dio_insn_config(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
diff --git a/drivers/staging/comedi/drivers/rtd520.h b/drivers/staging/comedi/drivers/rtd520.h
index 0eb50b8e605..a3ec2599c4b 100644
--- a/drivers/staging/comedi/drivers/rtd520.h
+++ b/drivers/staging/comedi/drivers/rtd520.h
@@ -29,366 +29,366 @@
LAS0 Runtime Area
Local Address Space 0 Offset Read Function Write Function
*/
-#define LAS0_SPARE_00 0x0000 // - -
-#define LAS0_SPARE_04 0x0004 // - -
-#define LAS0_USER_IO 0x0008 // Read User Inputs Write User Outputs
-#define LAS0_SPARE_0C 0x000C // - -
-#define LAS0_ADC 0x0010 // Read FIFO Status Software A/D Start
-#define LAS0_DAC1 0x0014 // - Software D/A1 Update
-#define LAS0_DAC2 0x0018 // - Software D/A2 Update
-#define LAS0_SPARE_1C 0x001C // - -
-#define LAS0_SPARE_20 0x0020 // - -
-#define LAS0_DAC 0x0024 // - Software Simultaneous D/A1 and D/A2 Update
-#define LAS0_PACER 0x0028 // Software Pacer Start Software Pacer Stop
-#define LAS0_TIMER 0x002C // Read Timer Counters Status HDIN Software Trigger
-#define LAS0_IT 0x0030 // Read Interrupt Status Write Interrupt Enable Mask Register
-#define LAS0_CLEAR 0x0034 // Clear ITs set by Clear Mask Set Interrupt Clear Mask
-#define LAS0_OVERRUN 0x0038 // Read pending interrupts Clear Overrun Register
-#define LAS0_SPARE_3C 0x003C // - -
+#define LAS0_SPARE_00 0x0000 /* - - */
+#define LAS0_SPARE_04 0x0004 /* - - */
+#define LAS0_USER_IO 0x0008 /* Read User Inputs Write User Outputs */
+#define LAS0_SPARE_0C 0x000C /* - - */
+#define LAS0_ADC 0x0010 /* Read FIFO Status Software A/D Start */
+#define LAS0_DAC1 0x0014 /* - Software D/A1 Update */
+#define LAS0_DAC2 0x0018 /* - Software D/A2 Update */
+#define LAS0_SPARE_1C 0x001C /* - - */
+#define LAS0_SPARE_20 0x0020 /* - - */
+#define LAS0_DAC 0x0024 /* - Software Simultaneous D/A1 and D/A2 Update */
+#define LAS0_PACER 0x0028 /* Software Pacer Start Software Pacer Stop */
+#define LAS0_TIMER 0x002C /* Read Timer Counters Status HDIN Software Trigger */
+#define LAS0_IT 0x0030 /* Read Interrupt Status Write Interrupt Enable Mask Register */
+#define LAS0_CLEAR 0x0034 /* Clear ITs set by Clear Mask Set Interrupt Clear Mask */
+#define LAS0_OVERRUN 0x0038 /* Read pending interrupts Clear Overrun Register */
+#define LAS0_SPARE_3C 0x003C /* - - */
/*
LAS0 Runtime Area Timer/Counter,Dig.IO
Name Local Address Function
*/
-#define LAS0_PCLK 0x0040 // Pacer Clock value (24bit) Pacer Clock load (24bit)
-#define LAS0_BCLK 0x0044 // Burst Clock value (10bit) Burst Clock load (10bit)
-#define LAS0_ADC_SCNT 0x0048 // A/D Sample counter value (10bit) A/D Sample counter load (10bit)
-#define LAS0_DAC1_UCNT 0x004C // D/A1 Update counter value (10 bit) D/A1 Update counter load (10bit)
-#define LAS0_DAC2_UCNT 0x0050 // D/A2 Update counter value (10 bit) D/A2 Update counter load (10bit)
-#define LAS0_DCNT 0x0054 // Delay counter value (16 bit) Delay counter load (16bit)
-#define LAS0_ACNT 0x0058 // About counter value (16 bit) About counter load (16bit)
-#define LAS0_DAC_CLK 0x005C // DAC clock value (16bit) DAC clock load (16bit)
-#define LAS0_UTC0 0x0060 // 8254 TC Counter 0 User TC 0 value Load count in TC Counter 0
-#define LAS0_UTC1 0x0064 // 8254 TC Counter 1 User TC 1 value Load count in TC Counter 1
-#define LAS0_UTC2 0x0068 // 8254 TC Counter 2 User TC 2 value Load count in TC Counter 2
-#define LAS0_UTC_CTRL 0x006C // 8254 TC Control Word Program counter mode for TC
-#define LAS0_DIO0 0x0070 // Digital I/O Port 0 Read Port Digital I/O Port 0 Write Port
-#define LAS0_DIO1 0x0074 // Digital I/O Port 1 Read Port Digital I/O Port 1 Write Port
-#define LAS0_DIO0_CTRL 0x0078 // Clear digital IRQ status flag/read Clear digital chip/program Port 0
-#define LAS0_DIO_STATUS 0x007C // Read Digital I/O Status word Program digital control register &
+#define LAS0_PCLK 0x0040 /* Pacer Clock value (24bit) Pacer Clock load (24bit) */
+#define LAS0_BCLK 0x0044 /* Burst Clock value (10bit) Burst Clock load (10bit) */
+#define LAS0_ADC_SCNT 0x0048 /* A/D Sample counter value (10bit) A/D Sample counter load (10bit) */
+#define LAS0_DAC1_UCNT 0x004C /* D/A1 Update counter value (10 bit) D/A1 Update counter load (10bit) */
+#define LAS0_DAC2_UCNT 0x0050 /* D/A2 Update counter value (10 bit) D/A2 Update counter load (10bit) */
+#define LAS0_DCNT 0x0054 /* Delay counter value (16 bit) Delay counter load (16bit) */
+#define LAS0_ACNT 0x0058 /* About counter value (16 bit) About counter load (16bit) */
+#define LAS0_DAC_CLK 0x005C /* DAC clock value (16bit) DAC clock load (16bit) */
+#define LAS0_UTC0 0x0060 /* 8254 TC Counter 0 User TC 0 value Load count in TC Counter 0 */
+#define LAS0_UTC1 0x0064 /* 8254 TC Counter 1 User TC 1 value Load count in TC Counter 1 */
+#define LAS0_UTC2 0x0068 /* 8254 TC Counter 2 User TC 2 value Load count in TC Counter 2 */
+#define LAS0_UTC_CTRL 0x006C /* 8254 TC Control Word Program counter mode for TC */
+#define LAS0_DIO0 0x0070 /* Digital I/O Port 0 Read Port Digital I/O Port 0 Write Port */
+#define LAS0_DIO1 0x0074 /* Digital I/O Port 1 Read Port Digital I/O Port 1 Write Port */
+#define LAS0_DIO0_CTRL 0x0078 /* Clear digital IRQ status flag/read Clear digital chip/program Port 0 */
+#define LAS0_DIO_STATUS 0x007C /* Read Digital I/O Status word Program digital control register & */
/*
LAS0 Setup Area
Name Local Address Function
*/
-#define LAS0_BOARD_RESET 0x0100 // Board reset
-#define LAS0_DMA0_SRC 0x0104 // DMA 0 Sources select
-#define LAS0_DMA1_SRC 0x0108 // DMA 1 Sources select
-#define LAS0_ADC_CONVERSION 0x010C // A/D Conversion Signal select
-#define LAS0_BURST_START 0x0110 // Burst Clock Start Trigger select
-#define LAS0_PACER_START 0x0114 // Pacer Clock Start Trigger select
-#define LAS0_PACER_STOP 0x0118 // Pacer Clock Stop Trigger select
-#define LAS0_ACNT_STOP_ENABLE 0x011C // About Counter Stop Enable
-#define LAS0_PACER_REPEAT 0x0120 // Pacer Start Trigger Mode select
-#define LAS0_DIN_START 0x0124 // High Speed Digital Input Sampling Signal select
-#define LAS0_DIN_FIFO_CLEAR 0x0128 // Digital Input FIFO Clear
-#define LAS0_ADC_FIFO_CLEAR 0x012C // A/D FIFO Clear
-#define LAS0_CGT_WRITE 0x0130 // Channel Gain Table Write
-#define LAS0_CGL_WRITE 0x0134 // Channel Gain Latch Write
-#define LAS0_CG_DATA 0x0138 // Digital Table Write
-#define LAS0_CGT_ENABLE 0x013C // Channel Gain Table Enable
-#define LAS0_CG_ENABLE 0x0140 // Digital Table Enable
-#define LAS0_CGT_PAUSE 0x0144 // Table Pause Enable
-#define LAS0_CGT_RESET 0x0148 // Reset Channel Gain Table
-#define LAS0_CGT_CLEAR 0x014C // Clear Channel Gain Table
-#define LAS0_DAC1_CTRL 0x0150 // D/A1 output type/range
-#define LAS0_DAC1_SRC 0x0154 // D/A1 update source
-#define LAS0_DAC1_CYCLE 0x0158 // D/A1 cycle mode
-#define LAS0_DAC1_RESET 0x015C // D/A1 FIFO reset
-#define LAS0_DAC1_FIFO_CLEAR 0x0160 // D/A1 FIFO clear
-#define LAS0_DAC2_CTRL 0x0164 // D/A2 output type/range
-#define LAS0_DAC2_SRC 0x0168 // D/A2 update source
-#define LAS0_DAC2_CYCLE 0x016C // D/A2 cycle mode
-#define LAS0_DAC2_RESET 0x0170 // D/A2 FIFO reset
-#define LAS0_DAC2_FIFO_CLEAR 0x0174 // D/A2 FIFO clear
-#define LAS0_ADC_SCNT_SRC 0x0178 // A/D Sample Counter Source select
-#define LAS0_PACER_SELECT 0x0180 // Pacer Clock select
-#define LAS0_SBUS0_SRC 0x0184 // SyncBus 0 Source select
-#define LAS0_SBUS0_ENABLE 0x0188 // SyncBus 0 enable
-#define LAS0_SBUS1_SRC 0x018C // SyncBus 1 Source select
-#define LAS0_SBUS1_ENABLE 0x0190 // SyncBus 1 enable
-#define LAS0_SBUS2_SRC 0x0198 // SyncBus 2 Source select
-#define LAS0_SBUS2_ENABLE 0x019C // SyncBus 2 enable
-#define LAS0_ETRG_POLARITY 0x01A4 // External Trigger polarity select
-#define LAS0_EINT_POLARITY 0x01A8 // External Interrupt polarity select
-#define LAS0_UTC0_CLOCK 0x01AC // UTC0 Clock select
-#define LAS0_UTC0_GATE 0x01B0 // UTC0 Gate select
-#define LAS0_UTC1_CLOCK 0x01B4 // UTC1 Clock select
-#define LAS0_UTC1_GATE 0x01B8 // UTC1 Gate select
-#define LAS0_UTC2_CLOCK 0x01BC // UTC2 Clock select
-#define LAS0_UTC2_GATE 0x01C0 // UTC2 Gate select
-#define LAS0_UOUT0_SELECT 0x01C4 // User Output 0 source select
-#define LAS0_UOUT1_SELECT 0x01C8 // User Output 1 source select
-#define LAS0_DMA0_RESET 0x01CC // DMA0 Request state machine reset
-#define LAS0_DMA1_RESET 0x01D0 // DMA1 Request state machine reset
+#define LAS0_BOARD_RESET 0x0100 /* Board reset */
+#define LAS0_DMA0_SRC 0x0104 /* DMA 0 Sources select */
+#define LAS0_DMA1_SRC 0x0108 /* DMA 1 Sources select */
+#define LAS0_ADC_CONVERSION 0x010C /* A/D Conversion Signal select */
+#define LAS0_BURST_START 0x0110 /* Burst Clock Start Trigger select */
+#define LAS0_PACER_START 0x0114 /* Pacer Clock Start Trigger select */
+#define LAS0_PACER_STOP 0x0118 /* Pacer Clock Stop Trigger select */
+#define LAS0_ACNT_STOP_ENABLE 0x011C /* About Counter Stop Enable */
+#define LAS0_PACER_REPEAT 0x0120 /* Pacer Start Trigger Mode select */
+#define LAS0_DIN_START 0x0124 /* High Speed Digital Input Sampling Signal select */
+#define LAS0_DIN_FIFO_CLEAR 0x0128 /* Digital Input FIFO Clear */
+#define LAS0_ADC_FIFO_CLEAR 0x012C /* A/D FIFO Clear */
+#define LAS0_CGT_WRITE 0x0130 /* Channel Gain Table Write */
+#define LAS0_CGL_WRITE 0x0134 /* Channel Gain Latch Write */
+#define LAS0_CG_DATA 0x0138 /* Digital Table Write */
+#define LAS0_CGT_ENABLE 0x013C /* Channel Gain Table Enable */
+#define LAS0_CG_ENABLE 0x0140 /* Digital Table Enable */
+#define LAS0_CGT_PAUSE 0x0144 /* Table Pause Enable */
+#define LAS0_CGT_RESET 0x0148 /* Reset Channel Gain Table */
+#define LAS0_CGT_CLEAR 0x014C /* Clear Channel Gain Table */
+#define LAS0_DAC1_CTRL 0x0150 /* D/A1 output type/range */
+#define LAS0_DAC1_SRC 0x0154 /* D/A1 update source */
+#define LAS0_DAC1_CYCLE 0x0158 /* D/A1 cycle mode */
+#define LAS0_DAC1_RESET 0x015C /* D/A1 FIFO reset */
+#define LAS0_DAC1_FIFO_CLEAR 0x0160 /* D/A1 FIFO clear */
+#define LAS0_DAC2_CTRL 0x0164 /* D/A2 output type/range */
+#define LAS0_DAC2_SRC 0x0168 /* D/A2 update source */
+#define LAS0_DAC2_CYCLE 0x016C /* D/A2 cycle mode */
+#define LAS0_DAC2_RESET 0x0170 /* D/A2 FIFO reset */
+#define LAS0_DAC2_FIFO_CLEAR 0x0174 /* D/A2 FIFO clear */
+#define LAS0_ADC_SCNT_SRC 0x0178 /* A/D Sample Counter Source select */
+#define LAS0_PACER_SELECT 0x0180 /* Pacer Clock select */
+#define LAS0_SBUS0_SRC 0x0184 /* SyncBus 0 Source select */
+#define LAS0_SBUS0_ENABLE 0x0188 /* SyncBus 0 enable */
+#define LAS0_SBUS1_SRC 0x018C /* SyncBus 1 Source select */
+#define LAS0_SBUS1_ENABLE 0x0190 /* SyncBus 1 enable */
+#define LAS0_SBUS2_SRC 0x0198 /* SyncBus 2 Source select */
+#define LAS0_SBUS2_ENABLE 0x019C /* SyncBus 2 enable */
+#define LAS0_ETRG_POLARITY 0x01A4 /* External Trigger polarity select */
+#define LAS0_EINT_POLARITY 0x01A8 /* External Interrupt polarity select */
+#define LAS0_UTC0_CLOCK 0x01AC /* UTC0 Clock select */
+#define LAS0_UTC0_GATE 0x01B0 /* UTC0 Gate select */
+#define LAS0_UTC1_CLOCK 0x01B4 /* UTC1 Clock select */
+#define LAS0_UTC1_GATE 0x01B8 /* UTC1 Gate select */
+#define LAS0_UTC2_CLOCK 0x01BC /* UTC2 Clock select */
+#define LAS0_UTC2_GATE 0x01C0 /* UTC2 Gate select */
+#define LAS0_UOUT0_SELECT 0x01C4 /* User Output 0 source select */
+#define LAS0_UOUT1_SELECT 0x01C8 /* User Output 1 source select */
+#define LAS0_DMA0_RESET 0x01CC /* DMA0 Request state machine reset */
+#define LAS0_DMA1_RESET 0x01D0 /* DMA1 Request state machine reset */
/*
LAS1
Name Local Address Function
*/
-#define LAS1_ADC_FIFO 0x0000 // Read A/D FIFO (16bit) -
-#define LAS1_HDIO_FIFO 0x0004 // Read High Speed Digital Input FIFO (16bit) -
-#define LAS1_DAC1_FIFO 0x0008 // - Write D/A1 FIFO (16bit)
-#define LAS1_DAC2_FIFO 0x000C // - Write D/A2 FIFO (16bit)
+#define LAS1_ADC_FIFO 0x0000 /* Read A/D FIFO (16bit) - */
+#define LAS1_HDIO_FIFO 0x0004 /* Read High Speed Digital Input FIFO (16bit) - */
+#define LAS1_DAC1_FIFO 0x0008 /* - Write D/A1 FIFO (16bit) */
+#define LAS1_DAC2_FIFO 0x000C /* - Write D/A2 FIFO (16bit) */
/*
LCFG: PLX 9080 local config & runtime registers
Name Local Address Function
*/
-#define LCFG_ITCSR 0x0068 // INTCSR, Interrupt Control/Status Register
-#define LCFG_DMAMODE0 0x0080 // DMA Channel 0 Mode Register
-#define LCFG_DMAPADR0 0x0084 // DMA Channel 0 PCI Address Register
-#define LCFG_DMALADR0 0x0088 // DMA Channel 0 Local Address Reg
-#define LCFG_DMASIZ0 0x008C // DMA Channel 0 Transfer Size (Bytes) Register
-#define LCFG_DMADPR0 0x0090 // DMA Channel 0 Descriptor Pointer Register
-#define LCFG_DMAMODE1 0x0094 // DMA Channel 1 Mode Register
-#define LCFG_DMAPADR1 0x0098 // DMA Channel 1 PCI Address Register
-#define LCFG_DMALADR1 0x009C // DMA Channel 1 Local Address Register
-#define LCFG_DMASIZ1 0x00A0 // DMA Channel 1 Transfer Size (Bytes) Register
-#define LCFG_DMADPR1 0x00A4 // DMA Channel 1 Descriptor Pointer Register
-#define LCFG_DMACSR0 0x00A8 // DMA Channel 0 Command/Status Register
-#define LCFG_DMACSR1 0x00A9 // DMA Channel 0 Command/Status Register
-#define LCFG_DMAARB 0x00AC // DMA Arbitration Register
-#define LCFG_DMATHR 0x00B0 // DMA Threshold Register
+#define LCFG_ITCSR 0x0068 /* INTCSR, Interrupt Control/Status Register */
+#define LCFG_DMAMODE0 0x0080 /* DMA Channel 0 Mode Register */
+#define LCFG_DMAPADR0 0x0084 /* DMA Channel 0 PCI Address Register */
+#define LCFG_DMALADR0 0x0088 /* DMA Channel 0 Local Address Reg */
+#define LCFG_DMASIZ0 0x008C /* DMA Channel 0 Transfer Size (Bytes) Register */
+#define LCFG_DMADPR0 0x0090 /* DMA Channel 0 Descriptor Pointer Register */
+#define LCFG_DMAMODE1 0x0094 /* DMA Channel 1 Mode Register */
+#define LCFG_DMAPADR1 0x0098 /* DMA Channel 1 PCI Address Register */
+#define LCFG_DMALADR1 0x009C /* DMA Channel 1 Local Address Register */
+#define LCFG_DMASIZ1 0x00A0 /* DMA Channel 1 Transfer Size (Bytes) Register */
+#define LCFG_DMADPR1 0x00A4 /* DMA Channel 1 Descriptor Pointer Register */
+#define LCFG_DMACSR0 0x00A8 /* DMA Channel 0 Command/Status Register */
+#define LCFG_DMACSR1 0x00A9 /* DMA Channel 0 Command/Status Register */
+#define LCFG_DMAARB 0x00AC /* DMA Arbitration Register */
+#define LCFG_DMATHR 0x00B0 /* DMA Threshold Register */
/*======================================================================
Resister bit definitions
======================================================================*/
-// FIFO Status Word Bits (RtdFifoStatus)
-#define FS_DAC1_NOT_EMPTY 0x0001 // D0 - DAC1 FIFO not empty
-#define FS_DAC1_HEMPTY 0x0002 // D1 - DAC1 FIFO half empty
-#define FS_DAC1_NOT_FULL 0x0004 // D2 - DAC1 FIFO not full
-#define FS_DAC2_NOT_EMPTY 0x0010 // D4 - DAC2 FIFO not empty
-#define FS_DAC2_HEMPTY 0x0020 // D5 - DAC2 FIFO half empty
-#define FS_DAC2_NOT_FULL 0x0040 // D6 - DAC2 FIFO not full
-#define FS_ADC_NOT_EMPTY 0x0100 // D8 - ADC FIFO not empty
-#define FS_ADC_HEMPTY 0x0200 // D9 - ADC FIFO half empty
-#define FS_ADC_NOT_FULL 0x0400 // D10 - ADC FIFO not full
-#define FS_DIN_NOT_EMPTY 0x1000 // D12 - DIN FIFO not empty
-#define FS_DIN_HEMPTY 0x2000 // D13 - DIN FIFO half empty
-#define FS_DIN_NOT_FULL 0x4000 // D14 - DIN FIFO not full
-
-// Timer Status Word Bits (GetTimerStatus)
+/* FIFO Status Word Bits (RtdFifoStatus) */
+#define FS_DAC1_NOT_EMPTY 0x0001 /* D0 - DAC1 FIFO not empty */
+#define FS_DAC1_HEMPTY 0x0002 /* D1 - DAC1 FIFO half empty */
+#define FS_DAC1_NOT_FULL 0x0004 /* D2 - DAC1 FIFO not full */
+#define FS_DAC2_NOT_EMPTY 0x0010 /* D4 - DAC2 FIFO not empty */
+#define FS_DAC2_HEMPTY 0x0020 /* D5 - DAC2 FIFO half empty */
+#define FS_DAC2_NOT_FULL 0x0040 /* D6 - DAC2 FIFO not full */
+#define FS_ADC_NOT_EMPTY 0x0100 /* D8 - ADC FIFO not empty */
+#define FS_ADC_HEMPTY 0x0200 /* D9 - ADC FIFO half empty */
+#define FS_ADC_NOT_FULL 0x0400 /* D10 - ADC FIFO not full */
+#define FS_DIN_NOT_EMPTY 0x1000 /* D12 - DIN FIFO not empty */
+#define FS_DIN_HEMPTY 0x2000 /* D13 - DIN FIFO half empty */
+#define FS_DIN_NOT_FULL 0x4000 /* D14 - DIN FIFO not full */
+
+/* Timer Status Word Bits (GetTimerStatus) */
#define TS_PCLK_GATE 0x0001
-// D0 - Pacer Clock Gate [0 - gated, 1 - enabled]
+/* D0 - Pacer Clock Gate [0 - gated, 1 - enabled] */
#define TS_BCLK_GATE 0x0002
-// D1 - Burst Clock Gate [0 - disabled, 1 - running]
+/* D1 - Burst Clock Gate [0 - disabled, 1 - running] */
#define TS_DCNT_GATE 0x0004
-// D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in
-// progress]
+/* D2 - Pacer Clock Delayed Start Trigger [0 - delay over, 1 - delay in */
+/* progress] */
#define TS_ACNT_GATE 0x0008
-// D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress]
+/* D3 - Pacer Clock About Trigger [0 - completed, 1 - in progress] */
#define TS_PCLK_RUN 0x0010
-// D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start
-// triggered only by Software Pacer Start Command, 1 - Pacer Clock can
-// be start triggered]
-
-// External Trigger polarity select
-// External Interrupt polarity select
-#define POL_POSITIVE 0x0 // positive edge
-#define POL_NEGATIVE 0x1 // negative edge
-
-// User Output Signal select (SetUout0Source, SetUout1Source)
-#define UOUT_ADC 0x0 // A/D Conversion Signal
-#define UOUT_DAC1 0x1 // D/A1 Update
-#define UOUT_DAC2 0x2 // D/A2 Update
-#define UOUT_SOFTWARE 0x3 // Software Programmable
-
-// Pacer clock select (SetPacerSource)
-#define PCLK_INTERNAL 1 // Internal Pacer Clock
-#define PCLK_EXTERNAL 0 // External Pacer Clock
-
-// A/D Sample Counter Sources (SetAdcntSource, SetupSampleCounter)
-#define ADC_SCNT_CGT_RESET 0x0 // needs restart with StartPacer
+/* D4 - Pacer Clock Shutdown Flag [0 - Pacer Clock cannot be start */
+/* triggered only by Software Pacer Start Command, 1 - Pacer Clock can */
+/* be start triggered] */
+
+/* External Trigger polarity select */
+/* External Interrupt polarity select */
+#define POL_POSITIVE 0x0 /* positive edge */
+#define POL_NEGATIVE 0x1 /* negative edge */
+
+/* User Output Signal select (SetUout0Source, SetUout1Source) */
+#define UOUT_ADC 0x0 /* A/D Conversion Signal */
+#define UOUT_DAC1 0x1 /* D/A1 Update */
+#define UOUT_DAC2 0x2 /* D/A2 Update */
+#define UOUT_SOFTWARE 0x3 /* Software Programmable */
+
+/* Pacer clock select (SetPacerSource) */
+#define PCLK_INTERNAL 1 /* Internal Pacer Clock */
+#define PCLK_EXTERNAL 0 /* External Pacer Clock */
+
+/* A/D Sample Counter Sources (SetAdcntSource, SetupSampleCounter) */
+#define ADC_SCNT_CGT_RESET 0x0 /* needs restart with StartPacer */
#define ADC_SCNT_FIFO_WRITE 0x1
-// A/D Conversion Signal Select (for SetConversionSelect)
-#define ADC_START_SOFTWARE 0x0 // Software A/D Start
-#define ADC_START_PCLK 0x1 // Pacer Clock (Ext. Int. see Func.509)
-#define ADC_START_BCLK 0x2 // Burst Clock
-#define ADC_START_DIGITAL_IT 0x3 // Digital Interrupt
-#define ADC_START_DAC1_MARKER1 0x4 // D/A 1 Data Marker 1
-#define ADC_START_DAC2_MARKER1 0x5 // D/A 2 Data Marker 1
-#define ADC_START_SBUS0 0x6 // SyncBus 0
-#define ADC_START_SBUS1 0x7 // SyncBus 1
-#define ADC_START_SBUS2 0x8 // SyncBus 2
-
-// Burst Clock start trigger select (SetBurstStart)
-#define BCLK_START_SOFTWARE 0x0 // Software A/D Start (StartBurst)
-#define BCLK_START_PCLK 0x1 // Pacer Clock
-#define BCLK_START_ETRIG 0x2 // External Trigger
-#define BCLK_START_DIGITAL_IT 0x3 // Digital Interrupt
-#define BCLK_START_SBUS0 0x4 // SyncBus 0
-#define BCLK_START_SBUS1 0x5 // SyncBus 1
-#define BCLK_START_SBUS2 0x6 // SyncBus 2
-
-// Pacer Clock start trigger select (SetPacerStart)
-#define PCLK_START_SOFTWARE 0x0 // Software Pacer Start (StartPacer)
-#define PCLK_START_ETRIG 0x1 // External trigger
-#define PCLK_START_DIGITAL_IT 0x2 // Digital interrupt
-#define PCLK_START_UTC2 0x3 // User TC 2 out
-#define PCLK_START_SBUS0 0x4 // SyncBus 0
-#define PCLK_START_SBUS1 0x5 // SyncBus 1
-#define PCLK_START_SBUS2 0x6 // SyncBus 2
-#define PCLK_START_D_SOFTWARE 0x8 // Delayed Software Pacer Start
-#define PCLK_START_D_ETRIG 0x9 // Delayed external trigger
-#define PCLK_START_D_DIGITAL_IT 0xA // Delayed digital interrupt
-#define PCLK_START_D_UTC2 0xB // Delayed User TC 2 out
-#define PCLK_START_D_SBUS0 0xC // Delayed SyncBus 0
-#define PCLK_START_D_SBUS1 0xD // Delayed SyncBus 1
-#define PCLK_START_D_SBUS2 0xE // Delayed SyncBus 2
-#define PCLK_START_ETRIG_GATED 0xF // External Trigger Gated controlled mode
-
-// Pacer Clock Stop Trigger select (SetPacerStop)
-#define PCLK_STOP_SOFTWARE 0x0 // Software Pacer Stop (StopPacer)
-#define PCLK_STOP_ETRIG 0x1 // External Trigger
-#define PCLK_STOP_DIGITAL_IT 0x2 // Digital Interrupt
-#define PCLK_STOP_ACNT 0x3 // About Counter
-#define PCLK_STOP_UTC2 0x4 // User TC2 out
-#define PCLK_STOP_SBUS0 0x5 // SyncBus 0
-#define PCLK_STOP_SBUS1 0x6 // SyncBus 1
-#define PCLK_STOP_SBUS2 0x7 // SyncBus 2
-#define PCLK_STOP_A_SOFTWARE 0x8 // About Software Pacer Stop
-#define PCLK_STOP_A_ETRIG 0x9 // About External Trigger
-#define PCLK_STOP_A_DIGITAL_IT 0xA // About Digital Interrupt
-#define PCLK_STOP_A_UTC2 0xC // About User TC2 out
-#define PCLK_STOP_A_SBUS0 0xD // About SyncBus 0
-#define PCLK_STOP_A_SBUS1 0xE // About SyncBus 1
-#define PCLK_STOP_A_SBUS2 0xF // About SyncBus 2
-
-// About Counter Stop Enable
-#define ACNT_STOP 0x0 // stop enable
-#define ACNT_NO_STOP 0x1 // stop disabled
-
-// DAC update source (SetDAC1Start & SetDAC2Start)
-#define DAC_START_SOFTWARE 0x0 // Software Update
-#define DAC_START_CGT 0x1 // CGT controlled Update
-#define DAC_START_DAC_CLK 0x2 // D/A Clock
-#define DAC_START_EPCLK 0x3 // External Pacer Clock
-#define DAC_START_SBUS0 0x4 // SyncBus 0
-#define DAC_START_SBUS1 0x5 // SyncBus 1
-#define DAC_START_SBUS2 0x6 // SyncBus 2
-
-// DAC Cycle Mode (SetDAC1Cycle, SetDAC2Cycle, SetupDAC)
-#define DAC_CYCLE_SINGLE 0x0 // not cycle
-#define DAC_CYCLE_MULTI 0x1 // cycle
-
-// 8254 Operation Modes (Set8254Mode, SetupTimerCounter)
-#define M8254_EVENT_COUNTER 0 // Event Counter
-#define M8254_HW_ONE_SHOT 1 // Hardware-Retriggerable One-Shot
-#define M8254_RATE_GENERATOR 2 // Rate Generator
-#define M8254_SQUARE_WAVE 3 // Square Wave Mode
-#define M8254_SW_STROBE 4 // Software Triggered Strobe
-#define M8254_HW_STROBE 5 // Hardware Triggered Strobe (Retriggerable)
-
-// User Timer/Counter 0 Clock Select (SetUtc0Clock)
-#define CUTC0_8MHZ 0x0 // 8MHz
-#define CUTC0_EXT_TC_CLOCK1 0x1 // Ext. TC Clock 1
-#define CUTC0_EXT_TC_CLOCK2 0x2 // Ext. TC Clock 2
-#define CUTC0_EXT_PCLK 0x3 // Ext. Pacer Clock
-
-// User Timer/Counter 1 Clock Select (SetUtc1Clock)
-#define CUTC1_8MHZ 0x0 // 8MHz
-#define CUTC1_EXT_TC_CLOCK1 0x1 // Ext. TC Clock 1
-#define CUTC1_EXT_TC_CLOCK2 0x2 // Ext. TC Clock 2
-#define CUTC1_EXT_PCLK 0x3 // Ext. Pacer Clock
-#define CUTC1_UTC0_OUT 0x4 // User Timer/Counter 0 out
-#define CUTC1_DIN_SIGNAL 0x5 // High-Speed Digital Input Sampling signal
-
-// User Timer/Counter 2 Clock Select (SetUtc2Clock)
-#define CUTC2_8MHZ 0x0 // 8MHz
-#define CUTC2_EXT_TC_CLOCK1 0x1 // Ext. TC Clock 1
-#define CUTC2_EXT_TC_CLOCK2 0x2 // Ext. TC Clock 2
-#define CUTC2_EXT_PCLK 0x3 // Ext. Pacer Clock
-#define CUTC2_UTC1_OUT 0x4 // User Timer/Counter 1 out
-
-// User Timer/Counter 0 Gate Select (SetUtc0Gate)
-#define GUTC0_NOT_GATED 0x0 // Not gated
-#define GUTC0_GATED 0x1 // Gated
-#define GUTC0_EXT_TC_GATE1 0x2 // Ext. TC Gate 1
-#define GUTC0_EXT_TC_GATE2 0x3 // Ext. TC Gate 2
-
-// User Timer/Counter 1 Gate Select (SetUtc1Gate)
-#define GUTC1_NOT_GATED 0x0 // Not gated
-#define GUTC1_GATED 0x1 // Gated
-#define GUTC1_EXT_TC_GATE1 0x2 // Ext. TC Gate 1
-#define GUTC1_EXT_TC_GATE2 0x3 // Ext. TC Gate 2
-#define GUTC1_UTC0_OUT 0x4 // User Timer/Counter 0 out
-
-// User Timer/Counter 2 Gate Select (SetUtc2Gate)
-#define GUTC2_NOT_GATED 0x0 // Not gated
-#define GUTC2_GATED 0x1 // Gated
-#define GUTC2_EXT_TC_GATE1 0x2 // Ext. TC Gate 1
-#define GUTC2_EXT_TC_GATE2 0x3 // Ext. TC Gate 2
-#define GUTC2_UTC1_OUT 0x4 // User Timer/Counter 1 out
-
-// Interrupt Source Masks (SetITMask, ClearITMask, GetITStatus)
-#define IRQM_ADC_FIFO_WRITE 0x0001 // ADC FIFO Write
-#define IRQM_CGT_RESET 0x0002 // Reset CGT
-#define IRQM_CGT_PAUSE 0x0008 // Pause CGT
-#define IRQM_ADC_ABOUT_CNT 0x0010 // About Counter out
-#define IRQM_ADC_DELAY_CNT 0x0020 // Delay Counter out
-#define IRQM_ADC_SAMPLE_CNT 0x0040 // ADC Sample Counter
-#define IRQM_DAC1_UCNT 0x0080 // DAC1 Update Counter
-#define IRQM_DAC2_UCNT 0x0100 // DAC2 Update Counter
-#define IRQM_UTC1 0x0200 // User TC1 out
-#define IRQM_UTC1_INV 0x0400 // User TC1 out, inverted
-#define IRQM_UTC2 0x0800 // User TC2 out
-#define IRQM_DIGITAL_IT 0x1000 // Digital Interrupt
-#define IRQM_EXTERNAL_IT 0x2000 // External Interrupt
-#define IRQM_ETRIG_RISING 0x4000 // External Trigger rising-edge
-#define IRQM_ETRIG_FALLING 0x8000 // External Trigger falling-edge
-
-// DMA Request Sources (LAS0)
-#define DMAS_DISABLED 0x0 // DMA Disabled
-#define DMAS_ADC_SCNT 0x1 // ADC Sample Counter
-#define DMAS_DAC1_UCNT 0x2 // D/A1 Update Counter
-#define DMAS_DAC2_UCNT 0x3 // D/A2 Update Counter
-#define DMAS_UTC1 0x4 // User TC1 out
-#define DMAS_ADFIFO_HALF_FULL 0x8 // A/D FIFO half full
-#define DMAS_DAC1_FIFO_HALF_EMPTY 0x9 // D/A1 FIFO half empty
-#define DMAS_DAC2_FIFO_HALF_EMPTY 0xA // D/A2 FIFO half empty
-
-// DMA Local Addresses (0x40000000+LAS1 offset)
-#define DMALADDR_ADC 0x40000000 // A/D FIFO
-#define DMALADDR_HDIN 0x40000004 // High Speed Digital Input FIFO
-#define DMALADDR_DAC1 0x40000008 // D/A1 FIFO
-#define DMALADDR_DAC2 0x4000000C // D/A2 FIFO
-
-// Port 0 compare modes (SetDIO0CompareMode)
-#define DIO_MODE_EVENT 0 // Event Mode
-#define DIO_MODE_MATCH 1 // Match Mode
-
-// Digital Table Enable (Port 1 disable)
-#define DTBL_DISABLE 0 // Enable Digital Table
-#define DTBL_ENABLE 1 // Disable Digital Table
-
-// Sampling Signal for High Speed Digital Input (SetHdinStart)
-#define HDIN_SOFTWARE 0x0 // Software Trigger
-#define HDIN_ADC 0x1 // A/D Conversion Signal
-#define HDIN_UTC0 0x2 // User TC out 0
-#define HDIN_UTC1 0x3 // User TC out 1
-#define HDIN_UTC2 0x4 // User TC out 2
-#define HDIN_EPCLK 0x5 // External Pacer Clock
-#define HDIN_ETRG 0x6 // External Trigger
-
-// Channel Gain Table / Channel Gain Latch
-#define CSC_LATCH 0 // Channel Gain Latch mode
-#define CSC_CGT 1 // Channel Gain Table mode
-
-// Channel Gain Table Pause Enable
-#define CGT_PAUSE_DISABLE 0 // Channel Gain Table Pause Disable
-#define CGT_PAUSE_ENABLE 1 // Channel Gain Table Pause Enable
-
-// DAC output type/range (p63)
-#define AOUT_UNIP5 0 // 0..+5 Volt
-#define AOUT_UNIP10 1 // 0..+10 Volt
-#define AOUT_BIP5 2 // -5..+5 Volt
-#define AOUT_BIP10 3 // -10..+10 Volt
-
-// Ghannel Gain Table field definitions (p61)
-// Gain
+/* A/D Conversion Signal Select (for SetConversionSelect) */
+#define ADC_START_SOFTWARE 0x0 /* Software A/D Start */
+#define ADC_START_PCLK 0x1 /* Pacer Clock (Ext. Int. see Func.509) */
+#define ADC_START_BCLK 0x2 /* Burst Clock */
+#define ADC_START_DIGITAL_IT 0x3 /* Digital Interrupt */
+#define ADC_START_DAC1_MARKER1 0x4 /* D/A 1 Data Marker 1 */
+#define ADC_START_DAC2_MARKER1 0x5 /* D/A 2 Data Marker 1 */
+#define ADC_START_SBUS0 0x6 /* SyncBus 0 */
+#define ADC_START_SBUS1 0x7 /* SyncBus 1 */
+#define ADC_START_SBUS2 0x8 /* SyncBus 2 */
+
+/* Burst Clock start trigger select (SetBurstStart) */
+#define BCLK_START_SOFTWARE 0x0 /* Software A/D Start (StartBurst) */
+#define BCLK_START_PCLK 0x1 /* Pacer Clock */
+#define BCLK_START_ETRIG 0x2 /* External Trigger */
+#define BCLK_START_DIGITAL_IT 0x3 /* Digital Interrupt */
+#define BCLK_START_SBUS0 0x4 /* SyncBus 0 */
+#define BCLK_START_SBUS1 0x5 /* SyncBus 1 */
+#define BCLK_START_SBUS2 0x6 /* SyncBus 2 */
+
+/* Pacer Clock start trigger select (SetPacerStart) */
+#define PCLK_START_SOFTWARE 0x0 /* Software Pacer Start (StartPacer) */
+#define PCLK_START_ETRIG 0x1 /* External trigger */
+#define PCLK_START_DIGITAL_IT 0x2 /* Digital interrupt */
+#define PCLK_START_UTC2 0x3 /* User TC 2 out */
+#define PCLK_START_SBUS0 0x4 /* SyncBus 0 */
+#define PCLK_START_SBUS1 0x5 /* SyncBus 1 */
+#define PCLK_START_SBUS2 0x6 /* SyncBus 2 */
+#define PCLK_START_D_SOFTWARE 0x8 /* Delayed Software Pacer Start */
+#define PCLK_START_D_ETRIG 0x9 /* Delayed external trigger */
+#define PCLK_START_D_DIGITAL_IT 0xA /* Delayed digital interrupt */
+#define PCLK_START_D_UTC2 0xB /* Delayed User TC 2 out */
+#define PCLK_START_D_SBUS0 0xC /* Delayed SyncBus 0 */
+#define PCLK_START_D_SBUS1 0xD /* Delayed SyncBus 1 */
+#define PCLK_START_D_SBUS2 0xE /* Delayed SyncBus 2 */
+#define PCLK_START_ETRIG_GATED 0xF /* External Trigger Gated controlled mode */
+
+/* Pacer Clock Stop Trigger select (SetPacerStop) */
+#define PCLK_STOP_SOFTWARE 0x0 /* Software Pacer Stop (StopPacer) */
+#define PCLK_STOP_ETRIG 0x1 /* External Trigger */
+#define PCLK_STOP_DIGITAL_IT 0x2 /* Digital Interrupt */
+#define PCLK_STOP_ACNT 0x3 /* About Counter */
+#define PCLK_STOP_UTC2 0x4 /* User TC2 out */
+#define PCLK_STOP_SBUS0 0x5 /* SyncBus 0 */
+#define PCLK_STOP_SBUS1 0x6 /* SyncBus 1 */
+#define PCLK_STOP_SBUS2 0x7 /* SyncBus 2 */
+#define PCLK_STOP_A_SOFTWARE 0x8 /* About Software Pacer Stop */
+#define PCLK_STOP_A_ETRIG 0x9 /* About External Trigger */
+#define PCLK_STOP_A_DIGITAL_IT 0xA /* About Digital Interrupt */
+#define PCLK_STOP_A_UTC2 0xC /* About User TC2 out */
+#define PCLK_STOP_A_SBUS0 0xD /* About SyncBus 0 */
+#define PCLK_STOP_A_SBUS1 0xE /* About SyncBus 1 */
+#define PCLK_STOP_A_SBUS2 0xF /* About SyncBus 2 */
+
+/* About Counter Stop Enable */
+#define ACNT_STOP 0x0 /* stop enable */
+#define ACNT_NO_STOP 0x1 /* stop disabled */
+
+/* DAC update source (SetDAC1Start & SetDAC2Start) */
+#define DAC_START_SOFTWARE 0x0 /* Software Update */
+#define DAC_START_CGT 0x1 /* CGT controlled Update */
+#define DAC_START_DAC_CLK 0x2 /* D/A Clock */
+#define DAC_START_EPCLK 0x3 /* External Pacer Clock */
+#define DAC_START_SBUS0 0x4 /* SyncBus 0 */
+#define DAC_START_SBUS1 0x5 /* SyncBus 1 */
+#define DAC_START_SBUS2 0x6 /* SyncBus 2 */
+
+/* DAC Cycle Mode (SetDAC1Cycle, SetDAC2Cycle, SetupDAC) */
+#define DAC_CYCLE_SINGLE 0x0 /* not cycle */
+#define DAC_CYCLE_MULTI 0x1 /* cycle */
+
+/* 8254 Operation Modes (Set8254Mode, SetupTimerCounter) */
+#define M8254_EVENT_COUNTER 0 /* Event Counter */
+#define M8254_HW_ONE_SHOT 1 /* Hardware-Retriggerable One-Shot */
+#define M8254_RATE_GENERATOR 2 /* Rate Generator */
+#define M8254_SQUARE_WAVE 3 /* Square Wave Mode */
+#define M8254_SW_STROBE 4 /* Software Triggered Strobe */
+#define M8254_HW_STROBE 5 /* Hardware Triggered Strobe (Retriggerable) */
+
+/* User Timer/Counter 0 Clock Select (SetUtc0Clock) */
+#define CUTC0_8MHZ 0x0 /* 8MHz */
+#define CUTC0_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
+#define CUTC0_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
+#define CUTC0_EXT_PCLK 0x3 /* Ext. Pacer Clock */
+
+/* User Timer/Counter 1 Clock Select (SetUtc1Clock) */
+#define CUTC1_8MHZ 0x0 /* 8MHz */
+#define CUTC1_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
+#define CUTC1_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
+#define CUTC1_EXT_PCLK 0x3 /* Ext. Pacer Clock */
+#define CUTC1_UTC0_OUT 0x4 /* User Timer/Counter 0 out */
+#define CUTC1_DIN_SIGNAL 0x5 /* High-Speed Digital Input Sampling signal */
+
+/* User Timer/Counter 2 Clock Select (SetUtc2Clock) */
+#define CUTC2_8MHZ 0x0 /* 8MHz */
+#define CUTC2_EXT_TC_CLOCK1 0x1 /* Ext. TC Clock 1 */
+#define CUTC2_EXT_TC_CLOCK2 0x2 /* Ext. TC Clock 2 */
+#define CUTC2_EXT_PCLK 0x3 /* Ext. Pacer Clock */
+#define CUTC2_UTC1_OUT 0x4 /* User Timer/Counter 1 out */
+
+/* User Timer/Counter 0 Gate Select (SetUtc0Gate) */
+#define GUTC0_NOT_GATED 0x0 /* Not gated */
+#define GUTC0_GATED 0x1 /* Gated */
+#define GUTC0_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
+#define GUTC0_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
+
+/* User Timer/Counter 1 Gate Select (SetUtc1Gate) */
+#define GUTC1_NOT_GATED 0x0 /* Not gated */
+#define GUTC1_GATED 0x1 /* Gated */
+#define GUTC1_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
+#define GUTC1_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
+#define GUTC1_UTC0_OUT 0x4 /* User Timer/Counter 0 out */
+
+/* User Timer/Counter 2 Gate Select (SetUtc2Gate) */
+#define GUTC2_NOT_GATED 0x0 /* Not gated */
+#define GUTC2_GATED 0x1 /* Gated */
+#define GUTC2_EXT_TC_GATE1 0x2 /* Ext. TC Gate 1 */
+#define GUTC2_EXT_TC_GATE2 0x3 /* Ext. TC Gate 2 */
+#define GUTC2_UTC1_OUT 0x4 /* User Timer/Counter 1 out */
+
+/* Interrupt Source Masks (SetITMask, ClearITMask, GetITStatus) */
+#define IRQM_ADC_FIFO_WRITE 0x0001 /* ADC FIFO Write */
+#define IRQM_CGT_RESET 0x0002 /* Reset CGT */
+#define IRQM_CGT_PAUSE 0x0008 /* Pause CGT */
+#define IRQM_ADC_ABOUT_CNT 0x0010 /* About Counter out */
+#define IRQM_ADC_DELAY_CNT 0x0020 /* Delay Counter out */
+#define IRQM_ADC_SAMPLE_CNT 0x0040 /* ADC Sample Counter */
+#define IRQM_DAC1_UCNT 0x0080 /* DAC1 Update Counter */
+#define IRQM_DAC2_UCNT 0x0100 /* DAC2 Update Counter */
+#define IRQM_UTC1 0x0200 /* User TC1 out */
+#define IRQM_UTC1_INV 0x0400 /* User TC1 out, inverted */
+#define IRQM_UTC2 0x0800 /* User TC2 out */
+#define IRQM_DIGITAL_IT 0x1000 /* Digital Interrupt */
+#define IRQM_EXTERNAL_IT 0x2000 /* External Interrupt */
+#define IRQM_ETRIG_RISING 0x4000 /* External Trigger rising-edge */
+#define IRQM_ETRIG_FALLING 0x8000 /* External Trigger falling-edge */
+
+/* DMA Request Sources (LAS0) */
+#define DMAS_DISABLED 0x0 /* DMA Disabled */
+#define DMAS_ADC_SCNT 0x1 /* ADC Sample Counter */
+#define DMAS_DAC1_UCNT 0x2 /* D/A1 Update Counter */
+#define DMAS_DAC2_UCNT 0x3 /* D/A2 Update Counter */
+#define DMAS_UTC1 0x4 /* User TC1 out */
+#define DMAS_ADFIFO_HALF_FULL 0x8 /* A/D FIFO half full */
+#define DMAS_DAC1_FIFO_HALF_EMPTY 0x9 /* D/A1 FIFO half empty */
+#define DMAS_DAC2_FIFO_HALF_EMPTY 0xA /* D/A2 FIFO half empty */
+
+/* DMA Local Addresses (0x40000000+LAS1 offset) */
+#define DMALADDR_ADC 0x40000000 /* A/D FIFO */
+#define DMALADDR_HDIN 0x40000004 /* High Speed Digital Input FIFO */
+#define DMALADDR_DAC1 0x40000008 /* D/A1 FIFO */
+#define DMALADDR_DAC2 0x4000000C /* D/A2 FIFO */
+
+/* Port 0 compare modes (SetDIO0CompareMode) */
+#define DIO_MODE_EVENT 0 /* Event Mode */
+#define DIO_MODE_MATCH 1 /* Match Mode */
+
+/* Digital Table Enable (Port 1 disable) */
+#define DTBL_DISABLE 0 /* Enable Digital Table */
+#define DTBL_ENABLE 1 /* Disable Digital Table */
+
+/* Sampling Signal for High Speed Digital Input (SetHdinStart) */
+#define HDIN_SOFTWARE 0x0 /* Software Trigger */
+#define HDIN_ADC 0x1 /* A/D Conversion Signal */
+#define HDIN_UTC0 0x2 /* User TC out 0 */
+#define HDIN_UTC1 0x3 /* User TC out 1 */
+#define HDIN_UTC2 0x4 /* User TC out 2 */
+#define HDIN_EPCLK 0x5 /* External Pacer Clock */
+#define HDIN_ETRG 0x6 /* External Trigger */
+
+/* Channel Gain Table / Channel Gain Latch */
+#define CSC_LATCH 0 /* Channel Gain Latch mode */
+#define CSC_CGT 1 /* Channel Gain Table mode */
+
+/* Channel Gain Table Pause Enable */
+#define CGT_PAUSE_DISABLE 0 /* Channel Gain Table Pause Disable */
+#define CGT_PAUSE_ENABLE 1 /* Channel Gain Table Pause Enable */
+
+/* DAC output type/range (p63) */
+#define AOUT_UNIP5 0 /* 0..+5 Volt */
+#define AOUT_UNIP10 1 /* 0..+10 Volt */
+#define AOUT_BIP5 2 /* -5..+5 Volt */
+#define AOUT_BIP10 3 /* -10..+10 Volt */
+
+/* Ghannel Gain Table field definitions (p61) */
+/* Gain */
#define GAIN1 0
#define GAIN2 1
#define GAIN4 2
@@ -398,15 +398,15 @@
#define GAIN64 6
#define GAIN128 7
-// Input range/polarity
-#define AIN_BIP5 0 // -5..+5 Volt
-#define AIN_BIP10 1 // -10..+10 Volt
-#define AIN_UNIP10 2 // 0..+10 Volt
+/* Input range/polarity */
+#define AIN_BIP5 0 /* -5..+5 Volt */
+#define AIN_BIP10 1 /* -10..+10 Volt */
+#define AIN_UNIP10 2 /* 0..+10 Volt */
-// non referenced single ended select bit
-#define NRSE_AGND 0 // AGND referenced SE input
-#define NRSE_AINS 1 // AIN SENSE referenced SE input
+/* non referenced single ended select bit */
+#define NRSE_AGND 0 /* AGND referenced SE input */
+#define NRSE_AINS 1 /* AIN SENSE referenced SE input */
-// single ended vs differential
-#define GND_SE 0 // Single-Ended
-#define GND_DIFF 1 // Differential
+/* single ended vs differential */
+#define GND_SE 0 /* Single-Ended */
+#define GND_DIFF 1 /* Differential */
diff --git a/drivers/staging/comedi/drivers/rti800.c b/drivers/staging/comedi/drivers/rti800.c
new file mode 100644
index 00000000000..334ac5773a1
--- /dev/null
+++ b/drivers/staging/comedi/drivers/rti800.c
@@ -0,0 +1,458 @@
+/*
+ comedi/drivers/rti800.c
+ Hardware driver for Analog Devices RTI-800/815 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1998 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: rti800
+Description: Analog Devices RTI-800/815
+Author: ds
+Status: unknown
+Updated: Fri, 05 Sep 2008 14:50:44 +0100
+Devices: [Analog Devices] RTI-800 (rti800), RTI-815 (rti815)
+
+Configuration options:
+ [0] - I/O port base address
+ [1] - IRQ
+ [2] - A/D reference
+ 0 = differential
+ 1 = pseudodifferential (common)
+ 2 = single-ended
+ [3] - A/D range
+ 0 = [-10,10]
+ 1 = [-5,5]
+ 2 = [0,10]
+ [4] - A/D encoding
+ 0 = two's complement
+ 1 = straight binary
+ [5] - DAC 0 range
+ 0 = [-10,10]
+ 1 = [0,10]
+ [6] - DAC 0 encoding
+ 0 = two's complement
+ 1 = straight binary
+ [7] - DAC 1 range (same as DAC 0)
+ [8] - DAC 1 encoding (same as DAC 0)
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define RTI800_SIZE 16
+
+#define RTI800_CSR 0
+#define RTI800_MUXGAIN 1
+#define RTI800_CONVERT 2
+#define RTI800_ADCLO 3
+#define RTI800_ADCHI 4
+#define RTI800_DAC0LO 5
+#define RTI800_DAC0HI 6
+#define RTI800_DAC1LO 7
+#define RTI800_DAC1HI 8
+#define RTI800_CLRFLAGS 9
+#define RTI800_DI 10
+#define RTI800_DO 11
+#define RTI800_9513A_DATA 12
+#define RTI800_9513A_CNTRL 13
+#define RTI800_9513A_STATUS 13
+
+/*
+ * flags for CSR register
+ */
+
+#define RTI800_BUSY 0x80
+#define RTI800_DONE 0x40
+#define RTI800_OVERRUN 0x20
+#define RTI800_TCR 0x10
+#define RTI800_DMA_ENAB 0x08
+#define RTI800_INTR_TC 0x04
+#define RTI800_INTR_EC 0x02
+#define RTI800_INTR_OVRN 0x01
+
+#define Am9513_8BITBUS
+
+#define Am9513_output_control(a) outb(a,dev->iobase+RTI800_9513A_CNTRL)
+#define Am9513_output_data(a) outb(a,dev->iobase+RTI800_9513A_DATA)
+#define Am9513_input_data() inb(dev->iobase+RTI800_9513A_DATA)
+#define Am9513_input_status() inb(dev->iobase+RTI800_9513A_STATUS)
+
+#include "am9513.h"
+
+static const struct comedi_lrange range_rti800_ai_10_bipolar = { 4, {
+ BIP_RANGE(10),
+ BIP_RANGE(1),
+ BIP_RANGE(0.1),
+ BIP_RANGE(0.02)
+ }
+};
+static const struct comedi_lrange range_rti800_ai_5_bipolar = { 4, {
+ BIP_RANGE(5),
+ BIP_RANGE(0.5),
+ BIP_RANGE(0.05),
+ BIP_RANGE(0.01)
+ }
+};
+static const struct comedi_lrange range_rti800_ai_unipolar = { 4, {
+ UNI_RANGE(10),
+ UNI_RANGE(1),
+ UNI_RANGE(0.1),
+ UNI_RANGE(0.02)
+ }
+};
+
+struct rti800_board {
+
+ const char *name;
+ int has_ao;
+};
+
+static const struct rti800_board boardtypes[] = {
+ {"rti800", 0},
+ {"rti815", 1},
+};
+
+#define this_board ((const struct rti800_board *)dev->board_ptr)
+
+static int rti800_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int rti800_detach(struct comedi_device * dev);
+static struct comedi_driver driver_rti800 = {
+ driver_name:"rti800",
+ module:THIS_MODULE,
+ attach:rti800_attach,
+ detach:rti800_detach,
+ num_names:sizeof(boardtypes) / sizeof(struct rti800_board),
+ board_name:&boardtypes[0].name,
+ offset:sizeof(struct rti800_board),
+};
+
+COMEDI_INITCLEANUP(driver_rti800);
+
+static irqreturn_t rti800_interrupt(int irq, void *dev PT_REGS_ARG);
+
+struct rti800_private {
+ enum {
+ adc_diff, adc_pseudodiff, adc_singleended
+ } adc_mux;
+ enum {
+ adc_bipolar10, adc_bipolar5, adc_unipolar10
+ } adc_range;
+ enum {
+ adc_2comp, adc_straight
+ } adc_coding;
+ enum {
+ dac_bipolar10, dac_unipolar10
+ } dac0_range, dac1_range;
+ enum {
+ dac_2comp, dac_straight
+ } dac0_coding, dac1_coding;
+ const struct comedi_lrange *ao_range_type_list[2];
+ unsigned int ao_readback[2];
+ int muxgain_bits;
+};
+
+#define devpriv ((struct rti800_private *)dev->private)
+
+#define RTI800_TIMEOUT 100
+
+static irqreturn_t rti800_interrupt(int irq, void *dev PT_REGS_ARG)
+{
+ return IRQ_HANDLED;
+}
+
+// settling delay times in usec for different gains
+static const int gaindelay[] = { 10, 20, 40, 80 };
+
+static int rti800_ai_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, t;
+ int status;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned gain = CR_RANGE(insn->chanspec);
+ unsigned muxgain_bits;
+
+ inb(dev->iobase + RTI800_ADCHI);
+ outb(0, dev->iobase + RTI800_CLRFLAGS);
+
+ muxgain_bits = chan | (gain << 5);
+ if (muxgain_bits != devpriv->muxgain_bits) {
+ devpriv->muxgain_bits = muxgain_bits;
+ outb(devpriv->muxgain_bits, dev->iobase + RTI800_MUXGAIN);
+ /* without a delay here, the RTI_OVERRUN bit
+ * gets set, and you will have an error. */
+ if (insn->n > 0) {
+ BUG_ON(gain >=
+ sizeof(gaindelay) / sizeof(gaindelay[0]));
+ comedi_udelay(gaindelay[gain]);
+ }
+ }
+
+ for (i = 0; i < insn->n; i++) {
+ outb(0, dev->iobase + RTI800_CONVERT);
+ for (t = RTI800_TIMEOUT; t; t--) {
+ status = inb(dev->iobase + RTI800_CSR);
+ if (status & RTI800_OVERRUN) {
+ rt_printk("rti800: a/d overrun\n");
+ outb(0, dev->iobase + RTI800_CLRFLAGS);
+ return -EIO;
+ }
+ if (status & RTI800_DONE)
+ break;
+ comedi_udelay(1);
+ }
+ if (t == 0) {
+ rt_printk("rti800: timeout\n");
+ return -ETIME;
+ }
+ data[i] = inb(dev->iobase + RTI800_ADCLO);
+ data[i] |= (0xf & inb(dev->iobase + RTI800_ADCHI)) << 8;
+
+ if (devpriv->adc_coding == adc_2comp) {
+ data[i] ^= 0x800;
+ }
+ }
+
+ return i;
+}
+
+static int rti800_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+static int rti800_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ int d;
+ int i;
+
+ for (i = 0; i < insn->n; i++) {
+ devpriv->ao_readback[chan] = d = data[i];
+ if (devpriv->dac0_coding == dac_2comp) {
+ d ^= 0x800;
+ }
+ outb(d & 0xff,
+ dev->iobase + (chan ? RTI800_DAC1LO : RTI800_DAC0LO));
+ outb(d >> 8,
+ dev->iobase + (chan ? RTI800_DAC1HI : RTI800_DAC0HI));
+ }
+ return i;
+}
+
+static int rti800_di_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+ data[1] = inb(dev->iobase + RTI800_DI);
+ return 2;
+}
+
+static int rti800_do_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Outputs are inverted... */
+ outb(s->state ^ 0xff, dev->iobase + RTI800_DO);
+ }
+
+ data[1] = s->state;
+
+ return 2;
+}
+
+/*
+ options[0] - I/O port
+ options[1] - irq
+ options[2] - a/d mux
+ 0=differential, 1=pseudodiff, 2=single
+ options[3] - a/d range
+ 0=bipolar10, 1=bipolar5, 2=unipolar10
+ options[4] - a/d coding
+ 0=2's comp, 1=straight binary
+ options[5] - dac0 range
+ 0=bipolar10, 1=unipolar10
+ options[6] - dac0 coding
+ 0=2's comp, 1=straight binary
+ options[7] - dac1 range
+ options[8] - dac1 coding
+ */
+
+static int rti800_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ unsigned int irq;
+ unsigned long iobase;
+ int ret;
+ struct comedi_subdevice *s;
+
+ iobase = it->options[0];
+ printk("comedi%d: rti800: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, RTI800_SIZE, "rti800")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+#ifdef DEBUG
+ printk("fingerprint=%x,%x,%x,%x,%x ",
+ inb(dev->iobase + 0),
+ inb(dev->iobase + 1),
+ inb(dev->iobase + 2),
+ inb(dev->iobase + 3), inb(dev->iobase + 4));
+#endif
+
+ outb(0, dev->iobase + RTI800_CSR);
+ inb(dev->iobase + RTI800_ADCHI);
+ outb(0, dev->iobase + RTI800_CLRFLAGS);
+
+ irq = it->options[1];
+ if (irq) {
+ printk("( irq = %u )", irq);
+ if ((ret = comedi_request_irq(irq, rti800_interrupt, 0,
+ "rti800", dev)) < 0) {
+ printk(" Failed to allocate IRQ\n");
+ return ret;
+ }
+ dev->irq = irq;
+ } else {
+ printk("( no irq )");
+ }
+
+ dev->board_name = this_board->name;
+
+ if ((ret = alloc_subdevices(dev, 4)) < 0)
+ return ret;
+ if ((ret = alloc_private(dev, sizeof(struct rti800_private))) < 0)
+ return ret;
+
+ devpriv->adc_mux = it->options[2];
+ devpriv->adc_range = it->options[3];
+ devpriv->adc_coding = it->options[4];
+ devpriv->dac0_range = it->options[5];
+ devpriv->dac0_coding = it->options[6];
+ devpriv->dac1_range = it->options[7];
+ devpriv->dac1_coding = it->options[8];
+ devpriv->muxgain_bits = -1;
+
+ s = dev->subdevices + 0;
+ /* ai subdevice */
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = (devpriv->adc_mux ? 16 : 8);
+ s->insn_read = rti800_ai_insn_read;
+ s->maxdata = 0xfff;
+ switch (devpriv->adc_range) {
+ case adc_bipolar10:
+ s->range_table = &range_rti800_ai_10_bipolar;
+ break;
+ case adc_bipolar5:
+ s->range_table = &range_rti800_ai_5_bipolar;
+ break;
+ case adc_unipolar10:
+ s->range_table = &range_rti800_ai_unipolar;
+ break;
+ }
+
+ s++;
+ if (this_board->has_ao) {
+ /* ao subdevice (only on rti815) */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 2;
+ s->insn_read = rti800_ao_insn_read;
+ s->insn_write = rti800_ao_insn_write;
+ s->maxdata = 0xfff;
+ s->range_table_list = devpriv->ao_range_type_list;
+ switch (devpriv->dac0_range) {
+ case dac_bipolar10:
+ devpriv->ao_range_type_list[0] = &range_bipolar10;
+ break;
+ case dac_unipolar10:
+ devpriv->ao_range_type_list[0] = &range_unipolar10;
+ break;
+ }
+ switch (devpriv->dac1_range) {
+ case dac_bipolar10:
+ devpriv->ao_range_type_list[1] = &range_bipolar10;
+ break;
+ case dac_unipolar10:
+ devpriv->ao_range_type_list[1] = &range_unipolar10;
+ break;
+ }
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ s++;
+ /* di */
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 8;
+ s->insn_bits = rti800_di_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+ s++;
+ /* do */
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 8;
+ s->insn_bits = rti800_do_insn_bits;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+
+/* don't yet know how to deal with counter/timers */
+#if 0
+ s++;
+ /* do */
+ s->type = COMEDI_SUBD_TIMER;
+#endif
+
+ printk("\n");
+
+ return 0;
+}
+
+static int rti800_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: rti800: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, RTI800_SIZE);
+
+ if (dev->irq)
+ comedi_free_irq(dev->irq, dev);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/rti802.c b/drivers/staging/comedi/drivers/rti802.c
new file mode 100644
index 00000000000..cc2c385db0b
--- /dev/null
+++ b/drivers/staging/comedi/drivers/rti802.c
@@ -0,0 +1,151 @@
+/*
+ comedi/drivers/rti802.c
+ Hardware driver for Analog Devices RTI-802 board
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 1999 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ */
+/*
+Driver: rti802
+Description: Analog Devices RTI-802
+Author: Anders Blomdell <anders.blomdell@control.lth.se>
+Devices: [Analog Devices] RTI-802 (rti802)
+Status: works
+
+Configuration Options:
+ [0] - i/o base
+ [1] - unused
+ [2] - dac#0 0=two's comp, 1=straight
+ [3] - dac#0 0=bipolar, 1=unipolar
+ [4] - dac#1 ...
+ ...
+ [17] - dac#7 ...
+*/
+
+#include "../comedidev.h"
+
+#include <linux/ioport.h>
+
+#define RTI802_SIZE 4
+
+#define RTI802_SELECT 0
+#define RTI802_DATALOW 1
+#define RTI802_DATAHIGH 2
+
+static int rti802_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int rti802_detach(struct comedi_device * dev);
+static struct comedi_driver driver_rti802 = {
+ driver_name:"rti802",
+ module:THIS_MODULE,
+ attach:rti802_attach,
+ detach:rti802_detach,
+};
+
+COMEDI_INITCLEANUP(driver_rti802);
+
+struct rti802_private {
+ enum {
+ dac_2comp, dac_straight
+ } dac_coding[8];
+ const struct comedi_lrange *range_type_list[8];
+ unsigned int ao_readback[8];
+};
+
+#define devpriv ((struct rti802_private *)dev->private)
+
+static int rti802_ao_insn_read(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
+
+ return i;
+}
+
+static int rti802_ao_insn_write(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i, d;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++) {
+ d = devpriv->ao_readback[chan] = data[i];
+ if (devpriv->dac_coding[chan] == dac_2comp)
+ d ^= 0x800;
+ outb(chan, dev->iobase + RTI802_SELECT);
+ outb(d & 0xff, dev->iobase + RTI802_DATALOW);
+ outb(d >> 8, dev->iobase + RTI802_DATAHIGH);
+ }
+ return i;
+}
+
+static int rti802_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int i;
+ unsigned long iobase;
+
+ iobase = it->options[0];
+ printk("comedi%d: rti802: 0x%04lx ", dev->minor, iobase);
+ if (!request_region(iobase, RTI802_SIZE, "rti802")) {
+ printk("I/O port conflict\n");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ dev->board_name = "rti802";
+
+ if (alloc_subdevices(dev, 1) < 0
+ || alloc_private(dev, sizeof(struct rti802_private))) {
+ return -ENOMEM;
+ }
+
+ s = dev->subdevices;
+ /* ao subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->maxdata = 0xfff;
+ s->n_chan = 8;
+ s->insn_read = rti802_ao_insn_read;
+ s->insn_write = rti802_ao_insn_write;
+ s->range_table_list = devpriv->range_type_list;
+
+ for (i = 0; i < 8; i++) {
+ devpriv->dac_coding[i] = (it->options[3 + 2 * i])
+ ? (dac_straight)
+ : (dac_2comp);
+ devpriv->range_type_list[i] = (it->options[2 + 2 * i])
+ ? &range_unipolar10 : &range_bipolar10;
+ }
+
+ printk("\n");
+
+ return 0;
+}
+
+static int rti802_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: rti802: remove\n", dev->minor);
+
+ if (dev->iobase)
+ release_region(dev->iobase, RTI802_SIZE);
+
+ return 0;
+}
diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c
new file mode 100644
index 00000000000..a7b6f711afc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/s526.c
@@ -0,0 +1,977 @@
+/*
+ comedi/drivers/s526.c
+ Sensoray s526 Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: s526
+Description: Sensoray 526 driver
+Devices: [Sensoray] 526 (s526)
+Author: Richie
+ Everett Wang <everett.wang@everteq.com>
+Updated: Thu, 14 Sep. 2006
+Status: experimental
+
+Encoder works
+Analog input works
+Analog output works
+PWM output works
+Commands are not supported yet.
+
+Configuration Options:
+
+comedi_config /dev/comedi0 s526 0x2C0,0x3
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define S526_SIZE 64
+
+#define S526_START_AI_CONV 0
+#define S526_AI_READ 0
+
+/* Ports */
+#define S526_IOSIZE 0x40
+#define S526_NUM_PORTS 27
+
+/* registers */
+#define REG_TCR 0x00
+#define REG_WDC 0x02
+#define REG_DAC 0x04
+#define REG_ADC 0x06
+#define REG_ADD 0x08
+#define REG_DIO 0x0A
+#define REG_IER 0x0C
+#define REG_ISR 0x0E
+#define REG_MSC 0x10
+#define REG_C0L 0x12
+#define REG_C0H 0x14
+#define REG_C0M 0x16
+#define REG_C0C 0x18
+#define REG_C1L 0x1A
+#define REG_C1H 0x1C
+#define REG_C1M 0x1E
+#define REG_C1C 0x20
+#define REG_C2L 0x22
+#define REG_C2H 0x24
+#define REG_C2M 0x26
+#define REG_C2C 0x28
+#define REG_C3L 0x2A
+#define REG_C3H 0x2C
+#define REG_C3M 0x2E
+#define REG_C3C 0x30
+#define REG_EED 0x32
+#define REG_EEC 0x34
+
+static const int s526_ports[] = {
+ REG_TCR,
+ REG_WDC,
+ REG_DAC,
+ REG_ADC,
+ REG_ADD,
+ REG_DIO,
+ REG_IER,
+ REG_ISR,
+ REG_MSC,
+ REG_C0L,
+ REG_C0H,
+ REG_C0M,
+ REG_C0C,
+ REG_C1L,
+ REG_C1H,
+ REG_C1M,
+ REG_C1C,
+ REG_C2L,
+ REG_C2H,
+ REG_C2M,
+ REG_C2C,
+ REG_C3L,
+ REG_C3H,
+ REG_C3M,
+ REG_C3C,
+ REG_EED,
+ REG_EEC
+};
+
+struct counter_mode_register_t {
+ unsigned short coutSource:1;
+ unsigned short coutPolarity:1;
+ unsigned short autoLoadResetRcap:3;
+ unsigned short hwCtEnableSource:2;
+ unsigned short ctEnableCtrl:2;
+ unsigned short clockSource:2;
+ unsigned short countDir:1;
+ unsigned short countDirCtrl:1;
+ unsigned short outputRegLatchCtrl:1;
+ unsigned short preloadRegSel:1;
+ unsigned short reserved:1;
+};
+
+union {
+ struct counter_mode_register_t reg;
+ unsigned short value;
+} cmReg;
+
+#define MAX_GPCT_CONFIG_DATA 6
+
+/* Different Application Classes for GPCT Subdevices */
+/* The list is not exhaustive and needs discussion! */
+enum S526_GPCT_APP_CLASS {
+ CountingAndTimeMeasurement,
+ SinglePulseGeneration,
+ PulseTrainGeneration,
+ PositionMeasurement,
+ Miscellaneous
+};
+
+/* Config struct for different GPCT subdevice Application Classes and
+ their options
+*/
+struct s526GPCTConfig {
+ enum S526_GPCT_APP_CLASS app;
+ int data[MAX_GPCT_CONFIG_DATA];
+};
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct s526_board {
+ const char *name;
+ int gpct_chans;
+ int gpct_bits;
+ int ad_chans;
+ int ad_bits;
+ int da_chans;
+ int da_bits;
+ int have_dio;
+};
+
+static const struct s526_board s526_boards[] = {
+ {
+ name: "s526",
+ gpct_chans:4,
+ gpct_bits:24,
+ ad_chans:8,
+ ad_bits: 16,
+ da_chans:4,
+ da_bits: 16,
+ have_dio:1,
+ }
+};
+
+#define ADDR_REG(reg) (dev->iobase + (reg))
+#define ADDR_CHAN_REG(reg, chan) (dev->iobase + (reg) + (chan) * 8)
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct s526_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct s526_private {
+
+ int data;
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[2];
+
+ struct s526GPCTConfig s526_gpct_config[4];
+ unsigned short s526_ai_config;
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct s526_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int s526_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int s526_detach(struct comedi_device * dev);
+static struct comedi_driver driver_s526 = {
+ driver_name:"s526",
+ module:THIS_MODULE,
+ attach:s526_attach,
+ detach:s526_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in s526_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&s526_boards[0].name,
+ offset:sizeof(struct s526_board),
+ num_names:sizeof(s526_boards) / sizeof(struct s526_board),
+};
+
+static int s526_gpct_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_gpct_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int s526_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int s526_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+ int iobase;
+ int i, n;
+// short value;
+// int subdev_channel = 0;
+
+ printk("comedi%d: s526: ", dev->minor);
+
+ iobase = it->options[0];
+ if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->name)) {
+ comedi_error(dev, "I/O port conflict");
+ return -EIO;
+ }
+ dev->iobase = iobase;
+
+ printk("iobase=0x%lx\n", dev->iobase);
+
+ /*** make it a little quieter, exw, 8/29/06
+ for (i = 0; i < S526_NUM_PORTS; i++) {
+ printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i])));
+ }
+ ***/
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_ptr = &s526_boards[0];
+
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct s526_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ dev->n_subdevices = 4;
+ if (alloc_subdevices(dev, dev->n_subdevices) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* GENERAL-PURPOSE COUNTER/TIME (GPCT) */
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE | SDF_LSAMPL;
+ /* KG: What does SDF_LSAMPL (see multiq3.c) mean? */
+ s->n_chan = thisboard->gpct_chans;
+ s->maxdata = 0x00ffffff; /* 24 bit counter */
+ s->insn_read = s526_gpct_rinsn;
+ s->insn_config = s526_gpct_insn_config;
+ s->insn_write = s526_gpct_winsn;
+
+ /* Command are not implemented yet, however they are necessary to
+ allocate the necessary memory for the comedi_async struct (used
+ to trigger the GPCT in case of pulsegenerator function */
+ //s->do_cmd = s526_gpct_cmd;
+ //s->do_cmdtest = s526_gpct_cmdtest;
+ //s->cancel = s526_gpct_cancel;
+
+ s = dev->subdevices + 1;
+ //dev->read_subdev=s;
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ /* we support differential */
+ s->subdev_flags = SDF_READABLE | SDF_DIFF;
+ /* channels 0 to 7 are the regular differential inputs */
+ /* channel 8 is "reference 0" (+10V), channel 9 is "reference 1" (0V) */
+ s->n_chan = 10;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar10;
+ s->len_chanlist = 16; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = s526_ai_rinsn;
+ s->insn_config = s526_ai_insn_config;
+
+ s = dev->subdevices + 2;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 4;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar10;
+ s->insn_write = s526_ao_winsn;
+ s->insn_read = s526_ao_rinsn;
+
+ s = dev->subdevices + 3;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 2;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = s526_dio_insn_bits;
+ s->insn_config = s526_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 1;
+
+#if 0
+ // Example of Counter Application
+ //One-shot (software trigger)
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 1; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 1; // Auto load 0:disabled, 1:enabled
+ cmReg.reg.hwCtEnableSource = 3; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 2; // Hardware
+ cmReg.reg.clockSource = 2; // Internal
+ cmReg.reg.countDir = 1; // Down
+ cmReg.reg.countDirCtrl = 1; // Software
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+ outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+
+ outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset RCAP (fires one-shot)
+
+#else
+
+ // Set Counter Mode Register
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 0; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 0; // Auto load disabled
+ cmReg.reg.hwCtEnableSource = 2; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 1; // 1: Software, >1 : Hardware
+ cmReg.reg.clockSource = 3; // x4
+ cmReg.reg.countDir = 0; // up
+ cmReg.reg.countDirCtrl = 0; // quadrature
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ n = 0;
+ printk("Mode reg=0x%04x, 0x%04lx\n", cmReg.value, ADDR_CHAN_REG(REG_C0M,
+ n));
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
+ udelay(1000);
+ printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n)));
+
+ // Load the pre-laod register high word
+// value = (short) (0x55);
+// outw(value, ADDR_CHAN_REG(REG_C0H, n));
+
+ // Load the pre-laod register low word
+// value = (short)(0xaa55);
+// outw(value, ADDR_CHAN_REG(REG_C0L, n));
+
+ // Write the Counter Control Register
+// outw(value, ADDR_CHAN_REG(REG_C0C, 0));
+
+ // Reset the counter if it is software preload
+ if (cmReg.reg.autoLoadResetRcap == 0) {
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, n)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, n)); // Load the counter from PR0
+ }
+
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n));
+ udelay(1000);
+ printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n)));
+
+#endif
+ printk("Current registres:\n");
+
+ for (i = 0; i < S526_NUM_PORTS; i++) {
+ printk("0x%02lx: 0x%04x\n", ADDR_REG(s526_ports[i]),
+ inw(ADDR_REG(s526_ports[i])));
+ }
+ return 1;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int s526_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: s526: remove\n", dev->minor);
+
+ if (dev->iobase > 0)
+ release_region(dev->iobase, S526_IOSIZE);
+
+ return 0;
+}
+
+static int s526_gpct_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i; // counts the Data
+ int counter_channel = CR_CHAN(insn->chanspec);
+ unsigned short datalow;
+ unsigned short datahigh;
+
+ // Check if (n > 0)
+ if (insn->n <= 0) {
+ printk("s526: INSN_READ: n should be > 0\n");
+ return -EINVAL;
+ }
+ // Read the low word first
+ for (i = 0; i < insn->n; i++) {
+ datalow = inw(ADDR_CHAN_REG(REG_C0L, counter_channel));
+ datahigh = inw(ADDR_CHAN_REG(REG_C0H, counter_channel));
+ data[i] = (int)(datahigh & 0x00FF);
+ data[i] = (data[i] << 16) | (datalow & 0xFFFF);
+// printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n", counter_channel, data[i], datahigh, datalow);
+ }
+ return i;
+}
+
+static int s526_gpct_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int subdev_channel = CR_CHAN(insn->chanspec); // Unpack chanspec
+ int i;
+ short value;
+
+// printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", subdev_channel);
+
+ for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) {
+ devpriv->s526_gpct_config[subdev_channel].data[i] =
+ insn->data[i];
+// printk("data[%d]=%x\n", i, insn->data[i]);
+ }
+
+ // Check what type of Counter the user requested, data[0] contains
+ // the Application type
+ switch (insn->data[0]) {
+ case INSN_CONFIG_GPCT_QUADRATURE_ENCODER:
+ /*
+ data[0]: Application Type
+ data[1]: Counter Mode Register Value
+ data[2]: Pre-load Register Value
+ data[3]: Conter Control Register
+ */
+ printk("s526: GPCT_INSN_CONFIG: Configuring Encoder\n");
+ devpriv->s526_gpct_config[subdev_channel].app =
+ PositionMeasurement;
+
+/*
+ // Example of Counter Application
+ //One-shot (software trigger)
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 1; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 0; // Auto load disabled
+ cmReg.reg.hwCtEnableSource = 3; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 2; // Hardware
+ cmReg.reg.clockSource = 2; // Internal
+ cmReg.reg.countDir = 1; // Down
+ cmReg.reg.countDirCtrl = 1; // Software
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+ outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+
+ outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset RCAP (fires one-shot)
+
+*/
+
+#if 1
+ // Set Counter Mode Register
+ cmReg.reg.coutSource = 0; // out RCAP
+ cmReg.reg.coutPolarity = 0; // Polarity inverted
+ cmReg.reg.autoLoadResetRcap = 0; // Auto load disabled
+ cmReg.reg.hwCtEnableSource = 2; // NOT RCAP
+ cmReg.reg.ctEnableCtrl = 1; // 1: Software, >1 : Hardware
+ cmReg.reg.clockSource = 3; // x4
+ cmReg.reg.countDir = 0; // up
+ cmReg.reg.countDirCtrl = 0; // quadrature
+ cmReg.reg.outputRegLatchCtrl = 0; // latch on read
+ cmReg.reg.preloadRegSel = 0; // PR0
+ cmReg.reg.reserved = 0;
+
+ // Set Counter Mode Register
+// printk("s526: Counter Mode register=%x\n", cmReg.value);
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Reset the counter if it is software preload
+ if (cmReg.reg.autoLoadResetRcap == 0) {
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+// outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+ }
+#else
+ cmReg.reg.countDirCtrl = 0; // 0 quadrature, 1 software control
+
+ // data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4
+ if (insn->data[1] == GPCT_X2) {
+ cmReg.reg.clockSource = 1;
+ } else if (insn->data[1] == GPCT_X4) {
+ cmReg.reg.clockSource = 2;
+ } else {
+ cmReg.reg.clockSource = 0;
+ }
+
+ // When to take into account the indexpulse:
+ if (insn->data[2] == GPCT_IndexPhaseLowLow) {
+ } else if (insn->data[2] == GPCT_IndexPhaseLowHigh) {
+ } else if (insn->data[2] == GPCT_IndexPhaseHighLow) {
+ } else if (insn->data[2] == GPCT_IndexPhaseHighHigh) {
+ }
+ // Take into account the index pulse?
+ if (insn->data[3] == GPCT_RESET_COUNTER_ON_INDEX)
+ cmReg.reg.autoLoadResetRcap = 4; // Auto load with INDEX^
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register high word
+ value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register low word
+ value = (short) (insn->data[2] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Write the Counter Control Register
+ if (insn->data[3] != 0) {
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+ }
+ // Reset the counter if it is software preload
+ if (cmReg.reg.autoLoadResetRcap == 0) {
+ outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Reset the counter
+ outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); // Load the counter from PR0
+ }
+#endif
+ break;
+
+ case INSN_CONFIG_GPCT_SINGLE_PULSE_GENERATOR:
+ /*
+ data[0]: Application Type
+ data[1]: Counter Mode Register Value
+ data[2]: Pre-load Register 0 Value
+ data[3]: Pre-load Register 1 Value
+ data[4]: Conter Control Register
+ */
+ printk("s526: GPCT_INSN_CONFIG: Configuring SPG\n");
+ devpriv->s526_gpct_config[subdev_channel].app =
+ SinglePulseGeneration;
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 0; // PR0
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 0 high word
+ value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 0 low word
+ value = (short) (insn->data[2] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 1; // PR1
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 1 high word
+ value = (short) ((insn->data[3] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 1 low word
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Write the Counter Control Register
+ if (insn->data[3] != 0) {
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+ }
+ break;
+
+ case INSN_CONFIG_GPCT_PULSE_TRAIN_GENERATOR:
+ /*
+ data[0]: Application Type
+ data[1]: Counter Mode Register Value
+ data[2]: Pre-load Register 0 Value
+ data[3]: Pre-load Register 1 Value
+ data[4]: Conter Control Register
+ */
+ printk("s526: GPCT_INSN_CONFIG: Configuring PTG\n");
+ devpriv->s526_gpct_config[subdev_channel].app =
+ PulseTrainGeneration;
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 0; // PR0
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 0 high word
+ value = (short) ((insn->data[2] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 0 low word
+ value = (short) (insn->data[2] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Set Counter Mode Register
+ cmReg.value = (short) (insn->data[1] & 0xFFFF);
+ cmReg.reg.preloadRegSel = 1; // PR1
+ outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, subdev_channel));
+
+ // Load the pre-laod register 1 high word
+ value = (short) ((insn->data[3] >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+
+ // Load the pre-laod register 1 low word
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+
+ // Write the Counter Control Register
+ if (insn->data[3] != 0) {
+ value = (short) (insn->data[3] & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0C, subdev_channel));
+ }
+ break;
+
+ default:
+ printk("s526: unsupported GPCT_insn_config\n");
+ return -EINVAL;
+ break;
+ }
+
+ return insn->n;
+}
+
+static int s526_gpct_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int subdev_channel = CR_CHAN(insn->chanspec); // Unpack chanspec
+ short value;
+
+ printk("s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel);
+ cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel));
+ printk("s526: Counter Mode Register: %x\n", cmReg.value);
+ // Check what Application of Counter this channel is configured for
+ switch (devpriv->s526_gpct_config[subdev_channel].app) {
+ case PositionMeasurement:
+ printk("S526: INSN_WRITE: PM\n");
+ outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
+ subdev_channel));
+ outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
+ break;
+
+ case SinglePulseGeneration:
+ printk("S526: INSN_WRITE: SPG\n");
+ outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H,
+ subdev_channel));
+ outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel));
+ break;
+
+ case PulseTrainGeneration:
+ /* data[0] contains the PULSE_WIDTH
+ data[1] contains the PULSE_PERIOD
+ @pre PULSE_PERIOD > PULSE_WIDTH > 0
+ The above periods must be expressed as a multiple of the
+ pulse frequency on the selected source
+ */
+ printk("S526: INSN_WRITE: PTG\n");
+ if ((insn->data[1] > insn->data[0]) && (insn->data[0] > 0)) {
+ (devpriv->s526_gpct_config[subdev_channel]).data[0] =
+ insn->data[0];
+ (devpriv->s526_gpct_config[subdev_channel]).data[1] =
+ insn->data[1];
+ } else {
+ printk("%d \t %d\n", insn->data[1], insn->data[2]);
+ printk("s526: INSN_WRITE: PTG: Problem with Pulse params\n");
+ return -EINVAL;
+ }
+
+ value = (short) ((*data >> 16) & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0H, subdev_channel));
+ value = (short) (*data & 0xFFFF);
+ outw(value, ADDR_CHAN_REG(REG_C0L, subdev_channel));
+ break;
+ default: // Impossible
+ printk("s526: INSN_WRITE: Functionality %d not implemented yet\n", devpriv->s526_gpct_config[subdev_channel].app);
+ return -EINVAL;
+ break;
+ }
+ // return the number of samples written
+ return insn->n;
+}
+
+#define ISR_ADC_DONE 0x4
+static int s526_ai_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int result = -EINVAL;
+
+ if (insn->n < 1)
+ return result;
+
+ result = insn->n;
+
+ /* data[0] : channels was set in relevant bits.
+ data[1] : delay
+ */
+ /* COMMENT: abbotti 2008-07-24: I don't know why you'd want to
+ * enable channels here. The channel should be enabled in the
+ * INSN_READ handler. */
+
+ // Enable ADC interrupt
+ outw(ISR_ADC_DONE, ADDR_REG(REG_IER));
+// printk("s526: ADC current value: 0x%04x\n", inw(ADDR_REG(REG_ADC)));
+ devpriv->s526_ai_config = (data[0] & 0x3FF) << 5;
+ if (data[1] > 0)
+ devpriv->s526_ai_config |= 0x8000; //set the delay
+
+ devpriv->s526_ai_config |= 0x0001; // ADC start bit.
+
+ return result;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int s526_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short value;
+ unsigned int d;
+ unsigned int status;
+
+ /* Set configured delay, enable channel for this channel only,
+ * select "ADC read" channel, set "ADC start" bit. */
+ value = (devpriv->s526_ai_config & 0x8000) |
+ ((1 << 5) << chan) | (chan << 1) | 0x0001;
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ outw(value, ADDR_REG(REG_ADC));
+// printk("s526: Wrote 0x%04x to ADC\n", value);
+// printk("s526: ADC reg=0x%04x\n", inw(ADDR_REG(REG_ADC)));
+
+#define TIMEOUT 100
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ status = inw(ADDR_REG(REG_ISR));
+ if (status & ISR_ADC_DONE) {
+ outw(ISR_ADC_DONE, ADDR_REG(REG_ISR));
+ break;
+ }
+ }
+ if (i == TIMEOUT) {
+ /* rt_printk() should be used instead of printk()
+ * whenever the code can be called from real-time. */
+ rt_printk("s526: ADC(0x%04x) timeout\n",
+ inw(ADDR_REG(REG_ISR)));
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ d = inw(ADDR_REG(REG_ADD));
+// printk("AI[%d]=0x%04x\n", n, (unsigned short)(d & 0xFFFF));
+
+ /* munge data */
+ data[n] = d ^ 0x8000;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int s526_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+ unsigned short val;
+
+// printk("s526_ao_winsn\n");
+ val = chan << 1;
+// outw(val, dev->iobase + REG_DAC);
+ outw(val, ADDR_REG(REG_DAC));
+
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* a typical programming sequence */
+// outw(data[i], dev->iobase + REG_ADD); // write the data to preload register
+ outw(data[i], ADDR_REG(REG_ADD)); // write the data to preload register
+ devpriv->ao_readback[chan] = data[i];
+// outw(val + 1, dev->iobase + REG_DAC); // starts the D/A conversion.
+ outw(val + 1, ADDR_REG(REG_DAC)); // starts the D/A conversion.
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int s526_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int s526_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ outw(s->state, ADDR_REG(REG_DIO));
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; // low 8 bits are the data
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ //data[1]=s->state;
+
+ return 2;
+}
+
+static int s526_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+ short value;
+
+ printk("S526 DIO insn_config\n");
+
+ if (insn->n != 1)
+ return -EINVAL;
+
+ value = inw(ADDR_REG(REG_DIO));
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+
+ if (data[0] == COMEDI_OUTPUT) {
+ value |= 1 << (chan + 10); // bit 10/11 set the group 1/2's mode
+ s->io_bits |= (0xF << chan);
+ } else {
+ value &= ~(1 << (chan + 10)); // 1 is output, 0 is input.
+ s->io_bits &= ~(0xF << chan);
+ }
+ outw(value, ADDR_REG(REG_DIO));
+
+ return 1;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_s526);
diff --git a/drivers/staging/comedi/drivers/s626.c b/drivers/staging/comedi/drivers/s626.c
index 469ee8c474c..30dec9dab19 100644
--- a/drivers/staging/comedi/drivers/s626.c
+++ b/drivers/staging/comedi/drivers/s626.c
@@ -82,7 +82,7 @@ MODULE_AUTHOR("Gianluca Palli <gpalli@deis.unibo.it>");
MODULE_DESCRIPTION("Sensoray 626 Comedi driver module");
MODULE_LICENSE("GPL");
-typedef struct s626_board_struct {
+struct s626_board {
const char *name;
int ai_chans;
int ai_bits;
@@ -91,22 +91,22 @@ typedef struct s626_board_struct {
int dio_chans;
int dio_banks;
int enc_chans;
-} s626_board;
+};
-static const s626_board s626_boards[] = {
+static const struct s626_board s626_boards[] = {
{
name: "s626",
- ai_chans:S626_ADC_CHANNELS,
+ ai_chans : S626_ADC_CHANNELS,
ai_bits: 14,
- ao_chans:S626_DAC_CHANNELS,
+ ao_chans : S626_DAC_CHANNELS,
ao_bits: 13,
- dio_chans:S626_DIO_CHANNELS,
- dio_banks:S626_DIO_BANKS,
- enc_chans:S626_ENCODER_CHANNELS,
+ dio_chans : S626_DIO_CHANNELS,
+ dio_banks : S626_DIO_BANKS,
+ enc_chans : S626_ENCODER_CHANNELS,
}
};
-#define thisboard ((const s626_board *)dev->board_ptr)
+#define thisboard ((const struct s626_board *)dev->board_ptr)
#define PCI_VENDOR_ID_S626 0x1131
#define PCI_DEVICE_ID_S626 0x7146
@@ -118,57 +118,49 @@ static DEFINE_PCI_DEVICE_TABLE(s626_pci_table) = {
MODULE_DEVICE_TABLE(pci, s626_pci_table);
-static int s626_attach(comedi_device * dev, comedi_devconfig * it);
-static int s626_detach(comedi_device * dev);
+static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it);
+static int s626_detach(struct comedi_device *dev);
-static comedi_driver driver_s626 = {
+static struct comedi_driver driver_s626 = {
driver_name:"s626",
- module:THIS_MODULE,
- attach:s626_attach,
- detach:s626_detach,
+ module : THIS_MODULE,
+ attach : s626_attach,
+ detach : s626_detach,
};
-typedef struct {
+struct s626_private {
struct pci_dev *pdev;
void *base_addr;
int got_regions;
short allocatedBuf;
- uint8_t ai_cmd_running; // ai_cmd is running
- uint8_t ai_continous; // continous aquisition
- int ai_sample_count; // number of samples to aquire
- unsigned int ai_sample_timer; // time between samples in
- // units of the timer
- int ai_convert_count; // conversion counter
- unsigned int ai_convert_timer; // time between conversion in
- // units of the timer
- uint16_t CounterIntEnabs; //Counter interrupt enable
- //mask for MISC2 register.
- uint8_t AdcItems; //Number of items in ADC poll
- //list.
- DMABUF RPSBuf; //DMA buffer used to hold ADC
- //(RPS1) program.
- DMABUF ANABuf; //DMA buffer used to receive
- //ADC data and hold DAC data.
- uint32_t *pDacWBuf; //Pointer to logical adrs of
- //DMA buffer used to hold DAC
- //data.
- uint16_t Dacpol; //Image of DAC polarity
- //register.
- uint8_t TrimSetpoint[12]; //Images of TrimDAC setpoints.
- //registers.
- uint16_t ChargeEnabled; //Image of MISC2 Battery
- //Charge Enabled (0 or
- //WRMISC2_CHARGE_ENABLE).
- uint16_t WDInterval; //Image of MISC2 watchdog
- //interval control bits.
- uint32_t I2CAdrs; //I2C device address for
- //onboard EEPROM (board rev
- //dependent).
- // short I2Cards;
- lsampl_t ao_readback[S626_DAC_CHANNELS];
-} s626_private;
-
-typedef struct {
+ uint8_t ai_cmd_running; /* ai_cmd is running */
+ uint8_t ai_continous; /* continous aquisition */
+ int ai_sample_count; /* number of samples to aquire */
+ unsigned int ai_sample_timer;
+ /* time between samples in units of the timer */
+ int ai_convert_count; /* conversion counter */
+ unsigned int ai_convert_timer;
+ /* time between conversion in units of the timer */
+ uint16_t CounterIntEnabs;
+ /* Counter interrupt enable mask for MISC2 register. */
+ uint8_t AdcItems; /* Number of items in ADC poll list. */
+ struct bufferDMA RPSBuf; /* DMA buffer used to hold ADC (RPS1) program. */
+ struct bufferDMA ANABuf;
+ /* DMA buffer used to receive ADC data and hold DAC data. */
+ uint32_t *pDacWBuf;
+ /* Pointer to logical adrs of DMA buffer used to hold DAC data. */
+ uint16_t Dacpol; /* Image of DAC polarity register. */
+ uint8_t TrimSetpoint[12]; /* Images of TrimDAC setpoints */
+ uint16_t ChargeEnabled; /* Image of MISC2 Battery */
+ /* Charge Enabled (0 or WRMISC2_CHARGE_ENABLE). */
+ uint16_t WDInterval; /* Image of MISC2 watchdog interval control bits. */
+ uint32_t I2CAdrs;
+ /* I2C device address for onboard EEPROM (board rev dependent). */
+ /* short I2Cards; */
+ unsigned int ao_readback[S626_DAC_CHANNELS];
+};
+
+struct dio_private {
uint16_t RDDIn;
uint16_t WRDOut;
uint16_t RDEdgSel;
@@ -178,324 +170,322 @@ typedef struct {
uint16_t RDCapFlg;
uint16_t RDIntSel;
uint16_t WRIntSel;
-} dio_private;
+};
-static dio_private dio_private_A = {
+static struct dio_private dio_private_A = {
RDDIn:LP_RDDINA,
- WRDOut:LP_WRDOUTA,
- RDEdgSel:LP_RDEDGSELA,
- WREdgSel:LP_WREDGSELA,
- RDCapSel:LP_RDCAPSELA,
- WRCapSel:LP_WRCAPSELA,
- RDCapFlg:LP_RDCAPFLGA,
- RDIntSel:LP_RDINTSELA,
- WRIntSel:LP_WRINTSELA,
+ WRDOut : LP_WRDOUTA,
+ RDEdgSel : LP_RDEDGSELA,
+ WREdgSel : LP_WREDGSELA,
+ RDCapSel : LP_RDCAPSELA,
+ WRCapSel : LP_WRCAPSELA,
+ RDCapFlg : LP_RDCAPFLGA,
+ RDIntSel : LP_RDINTSELA,
+ WRIntSel : LP_WRINTSELA,
};
-static dio_private dio_private_B = {
+static struct dio_private dio_private_B = {
RDDIn:LP_RDDINB,
- WRDOut:LP_WRDOUTB,
- RDEdgSel:LP_RDEDGSELB,
- WREdgSel:LP_WREDGSELB,
- RDCapSel:LP_RDCAPSELB,
- WRCapSel:LP_WRCAPSELB,
- RDCapFlg:LP_RDCAPFLGB,
- RDIntSel:LP_RDINTSELB,
- WRIntSel:LP_WRINTSELB,
+ WRDOut : LP_WRDOUTB,
+ RDEdgSel : LP_RDEDGSELB,
+ WREdgSel : LP_WREDGSELB,
+ RDCapSel : LP_RDCAPSELB,
+ WRCapSel : LP_WRCAPSELB,
+ RDCapFlg : LP_RDCAPFLGB,
+ RDIntSel : LP_RDINTSELB,
+ WRIntSel : LP_WRINTSELB,
};
-static dio_private dio_private_C = {
+static struct dio_private dio_private_C = {
RDDIn:LP_RDDINC,
- WRDOut:LP_WRDOUTC,
- RDEdgSel:LP_RDEDGSELC,
- WREdgSel:LP_WREDGSELC,
- RDCapSel:LP_RDCAPSELC,
- WRCapSel:LP_WRCAPSELC,
- RDCapFlg:LP_RDCAPFLGC,
- RDIntSel:LP_RDINTSELC,
- WRIntSel:LP_WRINTSELC,
+ WRDOut : LP_WRDOUTC,
+ RDEdgSel : LP_RDEDGSELC,
+ WREdgSel : LP_WREDGSELC,
+ RDCapSel : LP_RDCAPSELC,
+ WRCapSel : LP_WRCAPSELC,
+ RDCapFlg : LP_RDCAPFLGC,
+ RDIntSel : LP_RDINTSELC,
+ WRIntSel : LP_WRINTSELC,
};
/* to group dio devices (48 bits mask and data are not allowed ???)
-static dio_private *dio_private_word[]={
+static struct dio_private *dio_private_word[]={
&dio_private_A,
&dio_private_B,
&dio_private_C,
};
*/
-#define devpriv ((s626_private *)dev->private)
-#define diopriv ((dio_private *)s->private)
+#define devpriv ((struct s626_private *)dev->private)
+#define diopriv ((struct dio_private *)s->private)
COMEDI_PCI_INITCLEANUP_NOMODULE(driver_s626, s626_pci_table);
-//ioctl routines
-static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-/* static int s626_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data); */
-static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s);
-static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
- comedi_cmd * cmd);
-static int s626_ai_cancel(comedi_device * dev, comedi_subdevice * s);
-static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_dio_set_irq(comedi_device * dev, unsigned int chan);
-static int s626_dio_reset_irq(comedi_device * dev, unsigned int gruop,
+/* ioctl routines */
+static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data); */
+static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s);
+static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd);
+static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s);
+static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan);
+static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int gruop,
unsigned int mask);
-static int s626_dio_clear_irq(comedi_device * dev);
-static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
-static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data);
+static int s626_dio_clear_irq(struct comedi_device *dev);
+static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_enc_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
+static int s626_enc_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data);
static int s626_ns_to_timer(int *nanosec, int round_mode);
-static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd);
-static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd);
+static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum);
static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG);
-static lsampl_t s626_ai_reg_to_uint(int data);
-/* static lsampl_t s626_uint_to_reg(comedi_subdevice *s, int data); */
+static unsigned int s626_ai_reg_to_uint(int data);
+/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data); */
-//end ioctl routines
+/* end ioctl routines */
-//internal routines
-static void s626_dio_init(comedi_device * dev);
-static void ResetADC(comedi_device * dev, uint8_t * ppl);
-static void LoadTrimDACs(comedi_device * dev);
-static void WriteTrimDAC(comedi_device * dev, uint8_t LogicalChan,
+/* internal routines */
+static void s626_dio_init(struct comedi_device *dev);
+static void ResetADC(struct comedi_device *dev, uint8_t *ppl);
+static void LoadTrimDACs(struct comedi_device *dev);
+static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
uint8_t DacData);
-static uint8_t I2Cread(comedi_device * dev, uint8_t addr);
-static uint32_t I2Chandshake(comedi_device * dev, uint32_t val);
-static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata);
-static void SendDAC(comedi_device * dev, uint32_t val);
-static void WriteMISC2(comedi_device * dev, uint16_t NewImage);
-static void DEBItransfer(comedi_device * dev);
-static uint16_t DEBIread(comedi_device * dev, uint16_t addr);
-static void DEBIwrite(comedi_device * dev, uint16_t addr, uint16_t wdata);
-static void DEBIreplace(comedi_device * dev, uint16_t addr, uint16_t mask,
+static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr);
+static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val);
+static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata);
+static void SendDAC(struct comedi_device *dev, uint32_t val);
+static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage);
+static void DEBItransfer(struct comedi_device *dev);
+static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr);
+static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata);
+static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
uint16_t wdata);
-static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize);
-
-// COUNTER OBJECT ------------------------------------------------
-typedef struct enc_private_struct {
- // Pointers to functions that differ for A and B counters:
- uint16_t(*GetEnable) (comedi_device * dev, struct enc_private_struct *); //Return clock enable.
- uint16_t(*GetIntSrc) (comedi_device * dev, struct enc_private_struct *); //Return interrupt source.
- uint16_t(*GetLoadTrig) (comedi_device * dev, struct enc_private_struct *); //Return preload trigger source.
- uint16_t(*GetMode) (comedi_device * dev, struct enc_private_struct *); //Return standardized operating mode.
- void (*PulseIndex) (comedi_device * dev, struct enc_private_struct *); //Generate soft index strobe.
- void (*SetEnable) (comedi_device * dev, struct enc_private_struct *, uint16_t enab); //Program clock enable.
- void (*SetIntSrc) (comedi_device * dev, struct enc_private_struct *, uint16_t IntSource); //Program interrupt source.
- void (*SetLoadTrig) (comedi_device * dev, struct enc_private_struct *, uint16_t Trig); //Program preload trigger source.
- void (*SetMode) (comedi_device * dev, struct enc_private_struct *, uint16_t Setup, uint16_t DisableIntSrc); //Program standardized operating mode.
- void (*ResetCapFlags) (comedi_device * dev, struct enc_private_struct *); //Reset event capture flags.
-
- uint16_t MyCRA; // Address of CRA register.
- uint16_t MyCRB; // Address of CRB register.
- uint16_t MyLatchLsw; // Address of Latch least-significant-word
- // register.
- uint16_t MyEventBits[4]; // Bit translations for IntSrc -->RDMISC2.
-} enc_private; //counter object
-
-#define encpriv ((enc_private *)(dev->subdevices+5)->private)
-
-//counters routines
-static void s626_timer_load(comedi_device * dev, enc_private * k, int tick);
-static uint32_t ReadLatch(comedi_device * dev, enc_private * k);
-static void ResetCapFlags_A(comedi_device * dev, enc_private * k);
-static void ResetCapFlags_B(comedi_device * dev, enc_private * k);
-static uint16_t GetMode_A(comedi_device * dev, enc_private * k);
-static uint16_t GetMode_B(comedi_device * dev, enc_private * k);
-static void SetMode_A(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize);
+
+/* COUNTER OBJECT ------------------------------------------------ */
+struct enc_private {
+ /* Pointers to functions that differ for A and B counters: */
+ uint16_t(*GetEnable) (struct comedi_device *dev, struct enc_private *); /* Return clock enable. */
+ uint16_t(*GetIntSrc) (struct comedi_device *dev, struct enc_private *); /* Return interrupt source. */
+ uint16_t(*GetLoadTrig) (struct comedi_device *dev, struct enc_private *); /* Return preload trigger source. */
+ uint16_t(*GetMode) (struct comedi_device *dev, struct enc_private *); /* Return standardized operating mode. */
+ void (*PulseIndex) (struct comedi_device *dev, struct enc_private *); /* Generate soft index strobe. */
+ void (*SetEnable) (struct comedi_device *dev, struct enc_private *, uint16_t enab); /* Program clock enable. */
+ void (*SetIntSrc) (struct comedi_device *dev, struct enc_private *, uint16_t IntSource); /* Program interrupt source. */
+ void (*SetLoadTrig) (struct comedi_device *dev, struct enc_private *, uint16_t Trig); /* Program preload trigger source. */
+ void (*SetMode) (struct comedi_device *dev, struct enc_private *, uint16_t Setup, uint16_t DisableIntSrc); /* Program standardized operating mode. */
+ void (*ResetCapFlags) (struct comedi_device *dev, struct enc_private *); /* Reset event capture flags. */
+
+ uint16_t MyCRA; /* Address of CRA register. */
+ uint16_t MyCRB; /* Address of CRB register. */
+ uint16_t MyLatchLsw; /* Address of Latch least-significant-word */
+ /* register. */
+ uint16_t MyEventBits[4]; /* Bit translations for IntSrc -->RDMISC2. */
+};
+
+#define encpriv ((struct enc_private *)(dev->subdevices+5)->private)
+
+/* counters routines */
+static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick);
+static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k);
+static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k);
+static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k);
+static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc);
-static void SetMode_B(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc);
-static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab);
-static void SetEnable_B(comedi_device * dev, enc_private * k, uint16_t enab);
-static uint16_t GetEnable_A(comedi_device * dev, enc_private * k);
-static uint16_t GetEnable_B(comedi_device * dev, enc_private * k);
-static void SetLatchSource(comedi_device * dev, enc_private * k,
+static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab);
+static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, uint16_t enab);
+static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k);
+static void SetLatchSource(struct comedi_device *dev, struct enc_private *k,
uint16_t value);
-/* static uint16_t GetLatchSource(comedi_device *dev, enc_private *k ); */
-static void SetLoadTrig_A(comedi_device * dev, enc_private * k, uint16_t Trig);
-static void SetLoadTrig_B(comedi_device * dev, enc_private * k, uint16_t Trig);
-static uint16_t GetLoadTrig_A(comedi_device * dev, enc_private * k);
-static uint16_t GetLoadTrig_B(comedi_device * dev, enc_private * k);
-static void SetIntSrc_B(comedi_device * dev, enc_private * k,
+/* static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k ); */
+static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig);
+static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, uint16_t Trig);
+static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k);
+static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource);
-static void SetIntSrc_A(comedi_device * dev, enc_private * k,
+static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource);
-static uint16_t GetIntSrc_A(comedi_device * dev, enc_private * k);
-static uint16_t GetIntSrc_B(comedi_device * dev, enc_private * k);
-/* static void SetClkMult(comedi_device *dev, enc_private *k, uint16_t value ) ; */
-/* static uint16_t GetClkMult(comedi_device *dev, enc_private *k ) ; */
-/* static void SetIndexPol(comedi_device *dev, enc_private *k, uint16_t value ); */
-/* static uint16_t GetClkPol(comedi_device *dev, enc_private *k ) ; */
-/* static void SetIndexSrc( comedi_device *dev,enc_private *k, uint16_t value ); */
-/* static uint16_t GetClkSrc( comedi_device *dev,enc_private *k ); */
-/* static void SetIndexSrc( comedi_device *dev,enc_private *k, uint16_t value ); */
-/* static uint16_t GetIndexSrc( comedi_device *dev,enc_private *k ); */
-static void PulseIndex_A(comedi_device * dev, enc_private * k);
-static void PulseIndex_B(comedi_device * dev, enc_private * k);
-static void Preload(comedi_device * dev, enc_private * k, uint32_t value);
-static void CountersInit(comedi_device * dev);
-//end internal routines
-
-/////////////////////////////////////////////////////////////////////////
-// Counter objects constructor.
-
-// Counter overflow/index event flag masks for RDMISC2.
-#define INDXMASK(C) ( 1 << ( ( (C) > 2 ) ? ( (C) * 2 - 1 ) : ( (C) * 2 + 4 ) ) )
-#define OVERMASK(C) ( 1 << ( ( (C) > 2 ) ? ( (C) * 2 + 5 ) : ( (C) * 2 + 10 ) ) )
+static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k);
+static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k);
+/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) ; */
+/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) ; */
+/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ); */
+/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) ; */
+/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ); */
+/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k ); */
+/* static void SetIndexSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ); */
+/* static uint16_t GetIndexSrc( struct comedi_device *dev,struct enc_private *k ); */
+static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k);
+static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k);
+static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value);
+static void CountersInit(struct comedi_device *dev);
+/* end internal routines */
+
+/* Counter objects constructor. */
+
+/* Counter overflow/index event flag masks for RDMISC2. */
+#define INDXMASK(C) (1 << (((C) > 2) ? ((C) * 2 - 1) : ((C) * 2 + 4)))
+#define OVERMASK(C) (1 << (((C) > 2) ? ((C) * 2 + 5) : ((C) * 2 + 10)))
#define EVBITS(C) { 0, OVERMASK(C), INDXMASK(C), OVERMASK(C) | INDXMASK(C) }
-// Translation table to map IntSrc into equivalent RDMISC2 event flag
-// bits.
-//static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) };
+/* Translation table to map IntSrc into equivalent RDMISC2 event flag bits. */
+/* static const uint16_t EventBits[][4] = { EVBITS(0), EVBITS(1), EVBITS(2), EVBITS(3), EVBITS(4), EVBITS(5) }; */
-/* enc_private; */
-static enc_private enc_private_data[] = {
+/* struct enc_private; */
+static struct enc_private enc_private_data[] = {
{
GetEnable:GetEnable_A,
- GetIntSrc:GetIntSrc_A,
- GetLoadTrig:GetLoadTrig_A,
- GetMode: GetMode_A,
- PulseIndex:PulseIndex_A,
- SetEnable:SetEnable_A,
- SetIntSrc:SetIntSrc_A,
- SetLoadTrig:SetLoadTrig_A,
- SetMode: SetMode_A,
- ResetCapFlags:ResetCapFlags_A,
- MyCRA: LP_CR0A,
- MyCRB: LP_CR0B,
- MyLatchLsw:LP_CNTR0ALSW,
- MyEventBits:EVBITS(0),
+ GetIntSrc : GetIntSrc_A,
+ GetLoadTrig : GetLoadTrig_A,
+ GetMode : GetMode_A,
+ PulseIndex : PulseIndex_A,
+ SetEnable : SetEnable_A,
+ SetIntSrc : SetIntSrc_A,
+ SetLoadTrig : SetLoadTrig_A,
+ SetMode : SetMode_A,
+ ResetCapFlags : ResetCapFlags_A,
+ MyCRA : LP_CR0A,
+ MyCRB : LP_CR0B,
+ MyLatchLsw : LP_CNTR0ALSW,
+ MyEventBits : EVBITS(0),
},
{
GetEnable:GetEnable_A,
- GetIntSrc:GetIntSrc_A,
- GetLoadTrig:GetLoadTrig_A,
- GetMode: GetMode_A,
- PulseIndex:PulseIndex_A,
- SetEnable:SetEnable_A,
- SetIntSrc:SetIntSrc_A,
- SetLoadTrig:SetLoadTrig_A,
- SetMode: SetMode_A,
- ResetCapFlags:ResetCapFlags_A,
- MyCRA: LP_CR1A,
- MyCRB: LP_CR1B,
- MyLatchLsw:LP_CNTR1ALSW,
- MyEventBits:EVBITS(1),
+ GetIntSrc : GetIntSrc_A,
+ GetLoadTrig : GetLoadTrig_A,
+ GetMode : GetMode_A,
+ PulseIndex : PulseIndex_A,
+ SetEnable : SetEnable_A,
+ SetIntSrc : SetIntSrc_A,
+ SetLoadTrig : SetLoadTrig_A,
+ SetMode : SetMode_A,
+ ResetCapFlags : ResetCapFlags_A,
+ MyCRA : LP_CR1A,
+ MyCRB : LP_CR1B,
+ MyLatchLsw : LP_CNTR1ALSW,
+ MyEventBits : EVBITS(1),
},
{
GetEnable:GetEnable_A,
- GetIntSrc:GetIntSrc_A,
- GetLoadTrig:GetLoadTrig_A,
- GetMode: GetMode_A,
- PulseIndex:PulseIndex_A,
- SetEnable:SetEnable_A,
- SetIntSrc:SetIntSrc_A,
- SetLoadTrig:SetLoadTrig_A,
- SetMode: SetMode_A,
- ResetCapFlags:ResetCapFlags_A,
- MyCRA: LP_CR2A,
- MyCRB: LP_CR2B,
- MyLatchLsw:LP_CNTR2ALSW,
- MyEventBits:EVBITS(2),
+ GetIntSrc : GetIntSrc_A,
+ GetLoadTrig : GetLoadTrig_A,
+ GetMode : GetMode_A,
+ PulseIndex : PulseIndex_A,
+ SetEnable : SetEnable_A,
+ SetIntSrc : SetIntSrc_A,
+ SetLoadTrig : SetLoadTrig_A,
+ SetMode : SetMode_A,
+ ResetCapFlags : ResetCapFlags_A,
+ MyCRA : LP_CR2A,
+ MyCRB : LP_CR2B,
+ MyLatchLsw : LP_CNTR2ALSW,
+ MyEventBits : EVBITS(2),
},
{
GetEnable:GetEnable_B,
- GetIntSrc:GetIntSrc_B,
- GetLoadTrig:GetLoadTrig_B,
- GetMode: GetMode_B,
- PulseIndex:PulseIndex_B,
- SetEnable:SetEnable_B,
- SetIntSrc:SetIntSrc_B,
- SetLoadTrig:SetLoadTrig_B,
- SetMode: SetMode_B,
- ResetCapFlags:ResetCapFlags_B,
- MyCRA: LP_CR0A,
- MyCRB: LP_CR0B,
- MyLatchLsw:LP_CNTR0BLSW,
- MyEventBits:EVBITS(3),
+ GetIntSrc : GetIntSrc_B,
+ GetLoadTrig : GetLoadTrig_B,
+ GetMode : GetMode_B,
+ PulseIndex : PulseIndex_B,
+ SetEnable : SetEnable_B,
+ SetIntSrc : SetIntSrc_B,
+ SetLoadTrig : SetLoadTrig_B,
+ SetMode : SetMode_B,
+ ResetCapFlags : ResetCapFlags_B,
+ MyCRA : LP_CR0A,
+ MyCRB : LP_CR0B,
+ MyLatchLsw : LP_CNTR0BLSW,
+ MyEventBits : EVBITS(3),
},
{
GetEnable:GetEnable_B,
- GetIntSrc:GetIntSrc_B,
- GetLoadTrig:GetLoadTrig_B,
- GetMode: GetMode_B,
- PulseIndex:PulseIndex_B,
- SetEnable:SetEnable_B,
- SetIntSrc:SetIntSrc_B,
- SetLoadTrig:SetLoadTrig_B,
- SetMode: SetMode_B,
- ResetCapFlags:ResetCapFlags_B,
- MyCRA: LP_CR1A,
- MyCRB: LP_CR1B,
- MyLatchLsw:LP_CNTR1BLSW,
- MyEventBits:EVBITS(4),
+ GetIntSrc : GetIntSrc_B,
+ GetLoadTrig : GetLoadTrig_B,
+ GetMode : GetMode_B,
+ PulseIndex : PulseIndex_B,
+ SetEnable : SetEnable_B,
+ SetIntSrc : SetIntSrc_B,
+ SetLoadTrig : SetLoadTrig_B,
+ SetMode : SetMode_B,
+ ResetCapFlags : ResetCapFlags_B,
+ MyCRA : LP_CR1A,
+ MyCRB : LP_CR1B,
+ MyLatchLsw : LP_CNTR1BLSW,
+ MyEventBits : EVBITS(4),
},
{
GetEnable:GetEnable_B,
- GetIntSrc:GetIntSrc_B,
- GetLoadTrig:GetLoadTrig_B,
- GetMode: GetMode_B,
- PulseIndex:PulseIndex_B,
- SetEnable:SetEnable_B,
- SetIntSrc:SetIntSrc_B,
- SetLoadTrig:SetLoadTrig_B,
- SetMode: SetMode_B,
- ResetCapFlags:ResetCapFlags_B,
- MyCRA: LP_CR2A,
- MyCRB: LP_CR2B,
- MyLatchLsw:LP_CNTR2BLSW,
- MyEventBits:EVBITS(5),
+ GetIntSrc : GetIntSrc_B,
+ GetLoadTrig : GetLoadTrig_B,
+ GetMode : GetMode_B,
+ PulseIndex : PulseIndex_B,
+ SetEnable : SetEnable_B,
+ SetIntSrc : SetIntSrc_B,
+ SetLoadTrig : SetLoadTrig_B,
+ SetMode : SetMode_B,
+ ResetCapFlags : ResetCapFlags_B,
+ MyCRA : LP_CR2A,
+ MyCRB : LP_CR2B,
+ MyLatchLsw : LP_CNTR2BLSW,
+ MyEventBits : EVBITS(5),
},
};
-// enab/disable a function or test status bit(s) that are accessed
-// through Main Control Registers 1 or 2.
-#define MC_ENABLE( REGADRS, CTRLWORD ) writel( ( (uint32_t)( CTRLWORD ) << 16 ) | (uint32_t)( CTRLWORD ),devpriv->base_addr+( REGADRS ) )
+/* enab/disable a function or test status bit(s) that are accessed */
+/* through Main Control Registers 1 or 2. */
+#define MC_ENABLE(REGADRS, CTRLWORD) writel(((uint32_t)(CTRLWORD) << 16) | (uint32_t)(CTRLWORD), devpriv->base_addr+(REGADRS))
-#define MC_DISABLE( REGADRS, CTRLWORD ) writel( (uint32_t)( CTRLWORD ) << 16 , devpriv->base_addr+( REGADRS ) )
+#define MC_DISABLE(REGADRS, CTRLWORD) writel((uint32_t)(CTRLWORD) << 16 , devpriv->base_addr+(REGADRS))
-#define MC_TEST( REGADRS, CTRLWORD ) ( ( readl(devpriv->base_addr+( REGADRS )) & CTRLWORD ) != 0 )
+#define MC_TEST(REGADRS, CTRLWORD) ((readl(devpriv->base_addr+(REGADRS)) & CTRLWORD) != 0)
/* #define WR7146(REGARDS,CTRLWORD)
writel(CTRLWORD,(uint32_t)(devpriv->base_addr+(REGARDS))) */
-#define WR7146(REGARDS,CTRLWORD) writel(CTRLWORD,devpriv->base_addr+(REGARDS))
+#define WR7146(REGARDS, CTRLWORD) writel(CTRLWORD, devpriv->base_addr+(REGARDS))
/* #define RR7146(REGARDS)
readl((uint32_t)(devpriv->base_addr+(REGARDS))) */
#define RR7146(REGARDS) readl(devpriv->base_addr+(REGARDS))
-#define BUGFIX_STREG(REGADRS) ( REGADRS - 4 )
+#define BUGFIX_STREG(REGADRS) (REGADRS - 4)
-// Write a time slot control record to TSL2.
-#define VECTPORT( VECTNUM ) (P_TSL2 + ( (VECTNUM) << 2 ))
-#define SETVECT( VECTNUM, VECTVAL ) WR7146(VECTPORT( VECTNUM ), (VECTVAL))
+/* Write a time slot control record to TSL2. */
+#define VECTPORT(VECTNUM) (P_TSL2 + ((VECTNUM) << 2))
+#define SETVECT(VECTNUM, VECTVAL) WR7146(VECTPORT(VECTNUM), (VECTVAL))
-// Code macros used for constructing I2C command bytes.
-#define I2C_B2(ATTR,VAL) ( ( (ATTR) << 6 ) | ( (VAL) << 24 ) )
-#define I2C_B1(ATTR,VAL) ( ( (ATTR) << 4 ) | ( (VAL) << 16 ) )
-#define I2C_B0(ATTR,VAL) ( ( (ATTR) << 2 ) | ( (VAL) << 8 ) )
+/* Code macros used for constructing I2C command bytes. */
+#define I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
+#define I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
+#define I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8))
-static const comedi_lrange s626_range_table = { 2, {
+static const struct comedi_lrange s626_range_table = { 2, {
RANGE(-5, 5),
RANGE(-10, 10),
}
};
-static int s626_attach(comedi_device * dev, comedi_devconfig * it)
+static int s626_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
/* uint8_t PollList; */
/* uint16_t AdcData; */
@@ -507,10 +497,10 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
int ret;
resource_size_t resourceStart;
dma_addr_t appdma;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
struct pci_dev *pdev;
- if (alloc_private(dev, sizeof(s626_private)) < 0)
+ if (alloc_private(dev, sizeof(struct s626_private)) < 0)
return -ENOMEM;
for (pdev = pci_get_device(PCI_VENDOR_ID_S626, PCI_DEVICE_ID_S626,
@@ -535,7 +525,8 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
return -ENODEV;
}
- if ((result = comedi_pci_enable(pdev, "s626")) < 0) {
+ result = comedi_pci_enable(pdev, "s626");
+ if (result < 0) {
printk("s626_attach: comedi_pci_enable fails\n");
return -ENODEV;
}
@@ -550,21 +541,22 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
}
if (devpriv->base_addr) {
- //disable master interrupt
+ /* disable master interrupt */
writel(0, devpriv->base_addr + P_IER);
- //soft reset
+ /* soft reset */
writel(MC1_SOFT_RESET, devpriv->base_addr + P_MC1);
- //DMA FIXME DMA//
+ /* DMA FIXME DMA// */
DEBUG("s626_attach: DMA ALLOCATION\n");
- //adc buffer allocation
+ /* adc buffer allocation */
devpriv->allocatedBuf = 0;
- if ((devpriv->ANABuf.LogicalBase =
- pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,
- &appdma)) == NULL) {
+ devpriv->ANABuf.LogicalBase =
+ pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
+
+ if (devpriv->ANABuf.LogicalBase == NULL) {
printk("s626_attach: DMA Memory mapping error\n");
return -ENOMEM;
}
@@ -575,9 +567,10 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
devpriv->allocatedBuf++;
- if ((devpriv->RPSBuf.LogicalBase =
- pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE,
- &appdma)) == NULL) {
+ devpriv->RPSBuf.LogicalBase =
+ pci_alloc_consistent(devpriv->pdev, DMABUF_SIZE, &appdma);
+
+ if (devpriv->RPSBuf.LogicalBase == NULL) {
printk("s626_attach: DMA Memory mapping error\n");
return -ENOMEM;
}
@@ -599,12 +592,14 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
dev->iobase = (unsigned long)devpriv->base_addr;
dev->irq = devpriv->pdev->irq;
- //set up interrupt handler
+ /* set up interrupt handler */
if (dev->irq == 0) {
printk(" unknown irq (bad)\n");
} else {
- if ((ret = comedi_request_irq(dev->irq, s626_irq_handler,
- IRQF_SHARED, "s626", dev)) < 0) {
+ ret = comedi_request_irq(dev->irq, s626_irq_handler,
+ IRQF_SHARED, "s626", dev);
+
+ if (ret < 0) {
printk(" irq not available\n");
dev->irq = 0;
}
@@ -689,119 +684,121 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
s->maxdata = 0xffffff;
s->range_table = &range_unknown;
- //stop ai_command
+ /* stop ai_command */
devpriv->ai_cmd_running = 0;
if (devpriv->base_addr && (devpriv->allocatedBuf == 2)) {
dma_addr_t pPhysBuf;
uint16_t chan;
- // enab DEBI and audio pins, enable I2C interface.
+ /* enab DEBI and audio pins, enable I2C interface. */
MC_ENABLE(P_MC1, MC1_DEBI | MC1_AUDIO | MC1_I2C);
- // Configure DEBI operating mode.
- WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 // Local bus is 16
- // bits wide.
- | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) // Declare DEBI
- // transfer timeout
- // interval.
- | DEBI_SWAP // Set up byte lane
- // steering.
- | DEBI_CFG_INTEL); // Intel-compatible
- // local bus (DEBI
- // never times out).
+ /* Configure DEBI operating mode. */
+ WR7146(P_DEBICFG, DEBI_CFG_SLAVE16 /* Local bus is 16 */
+ /* bits wide. */
+ | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) /* Declare DEBI */
+ /* transfer timeout */
+ /* interval. */
+ | DEBI_SWAP /* Set up byte lane */
+ /* steering. */
+ | DEBI_CFG_INTEL); /* Intel-compatible */
+ /* local bus (DEBI */
+ /* never times out). */
DEBUG("s626_attach: %d debi init -- %d\n",
DEBI_CFG_SLAVE16 | (DEBI_TOUT << DEBI_CFG_TOUT_BIT) |
DEBI_SWAP | DEBI_CFG_INTEL,
DEBI_CFG_INTEL | DEBI_CFG_TOQ | DEBI_CFG_INCQ |
DEBI_CFG_16Q);
- //DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ
- //| DEBI_CFG_INCQ| DEBI_CFG_16Q); //end
+ /* DEBI INIT S626 WR7146( P_DEBICFG, DEBI_CFG_INTEL | DEBI_CFG_TOQ */
+ /* | DEBI_CFG_INCQ| DEBI_CFG_16Q); //end */
- // Paging is disabled.
- WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); // Disable MMU paging.
+ /* Paging is disabled. */
+ WR7146(P_DEBIPAGE, DEBI_PAGE_DISABLE); /* Disable MMU paging. */
- // Init GPIO so that ADC Start* is negated.
+ /* Init GPIO so that ADC Start* is negated. */
WR7146(P_GPIO, GPIO_BASE | GPIO1_HI);
- //IsBoardRevA is a boolean that indicates whether the board is
- //RevA.
-
- // VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC
- // EEPROM ADDRESS SELECTION. Initialize the I2C interface, which
- // is used to access the onboard serial EEPROM. The EEPROM's I2C
- // DeviceAddress is hardwired to a value that is dependent on the
- // 626 board revision. On all board revisions, the EEPROM stores
- // TrimDAC calibration constants for analog I/O. On RevB and
- // higher boards, the DeviceAddress is hardwired to 0 to enable
- // the EEPROM to also store the PCI SubVendorID and SubDeviceID;
- // this is the address at which the SAA7146 expects a
- // configuration EEPROM to reside. On RevA boards, the EEPROM
- // device address, which is hardwired to 4, prevents the SAA7146
- // from retrieving PCI sub-IDs, so the SAA7146 uses its built-in
- // default values, instead.
-
- // devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM
- // DeviceType (0xA0)
- // and DeviceAddress<<1.
-
- devpriv->I2CAdrs = 0xA0; // I2C device address for onboard
- // eeprom(revb)
-
- // Issue an I2C ABORT command to halt any I2C operation in
- //progress and reset BUSY flag.
- WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT); // Write I2C control:
- // abort any I2C
- // activity.
- MC_ENABLE(P_MC2, MC2_UPLD_IIC); // Invoke command
- // upload
- while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0) ; // and wait for
- // upload to
- // complete.
-
- // Per SAA7146 data sheet, write to STATUS reg twice to reset all
- // I2C error flags.
+ /* IsBoardRevA is a boolean that indicates whether the board is RevA.
+ *
+ * VERSION 2.01 CHANGE: REV A & B BOARDS NOW SUPPORTED BY DYNAMIC
+ * EEPROM ADDRESS SELECTION. Initialize the I2C interface, which
+ * is used to access the onboard serial EEPROM. The EEPROM's I2C
+ * DeviceAddress is hardwired to a value that is dependent on the
+ * 626 board revision. On all board revisions, the EEPROM stores
+ * TrimDAC calibration constants for analog I/O. On RevB and
+ * higher boards, the DeviceAddress is hardwired to 0 to enable
+ * the EEPROM to also store the PCI SubVendorID and SubDeviceID;
+ * this is the address at which the SAA7146 expects a
+ * configuration EEPROM to reside. On RevA boards, the EEPROM
+ * device address, which is hardwired to 4, prevents the SAA7146
+ * from retrieving PCI sub-IDs, so the SAA7146 uses its built-in
+ * default values, instead.
+ */
+
+ /* devpriv->I2Cards= IsBoardRevA ? 0xA8 : 0xA0; // Set I2C EEPROM */
+ /* DeviceType (0xA0) */
+ /* and DeviceAddress<<1. */
+
+ devpriv->I2CAdrs = 0xA0; /* I2C device address for onboard */
+ /* eeprom(revb) */
+
+ /* Issue an I2C ABORT command to halt any I2C operation in */
+ /* progress and reset BUSY flag. */
+ WR7146(P_I2CSTAT, I2C_CLKSEL | I2C_ABORT);
+ /* Write I2C control: abort any I2C activity. */
+ MC_ENABLE(P_MC2, MC2_UPLD_IIC);
+ /* Invoke command upload */
+ while ((RR7146(P_MC2) & MC2_UPLD_IIC) == 0)
+ ;
+ /* and wait for upload to complete. */
+
+ /* Per SAA7146 data sheet, write to STATUS reg twice to
+ * reset all I2C error flags. */
for (i = 0; i < 2; i++) {
- WR7146(P_I2CSTAT, I2C_CLKSEL); // Write I2C control: reset
- // error flags.
- MC_ENABLE(P_MC2, MC2_UPLD_IIC); // Invoke command upload
- while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ; // and wait for
- // upload to
- // complete.
+ WR7146(P_I2CSTAT, I2C_CLKSEL);
+ /* Write I2C control: reset error flags. */
+ MC_ENABLE(P_MC2, MC2_UPLD_IIC); /* Invoke command upload */
+ while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+ ;
+ /* and wait for upload to complete. */
}
- // Init audio interface functional attributes: set DAC/ADC serial
- // clock rates, invert DAC serial clock so that DAC data setup
- // times are satisfied, enable DAC serial clock out.
+ /* Init audio interface functional attributes: set DAC/ADC
+ * serial clock rates, invert DAC serial clock so that
+ * DAC data setup times are satisfied, enable DAC serial
+ * clock out.
+ */
+
WR7146(P_ACON2, ACON2_INIT);
- // Set up TSL1 slot list, which is used to control the
- // accumulation of ADC data: RSD1 = shift data in on SD1. SIB_A1
- // = store data uint8_t at next available location in FB BUFFER1
- // register.
- WR7146(P_TSL1, RSD1 | SIB_A1); // Fetch ADC high data
- // uint8_t.
- WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS); // Fetch ADC low data
- // uint8_t; end of
- // TSL1.
-
- // enab TSL1 slot list so that it executes all the time.
+ /* Set up TSL1 slot list, which is used to control the
+ * accumulation of ADC data: RSD1 = shift data in on SD1.
+ * SIB_A1 = store data uint8_t at next available location in
+ * FB BUFFER1 register. */
+ WR7146(P_TSL1, RSD1 | SIB_A1);
+ /* Fetch ADC high data uint8_t. */
+ WR7146(P_TSL1 + 4, RSD1 | SIB_A1 | EOS);
+ /* Fetch ADC low data uint8_t; end of TSL1. */
+
+ /* enab TSL1 slot list so that it executes all the time. */
WR7146(P_ACON1, ACON1_ADCSTART);
- // Initialize RPS registers used for ADC.
+ /* Initialize RPS registers used for ADC. */
- //Physical start of RPS program.
+ /* Physical start of RPS program. */
WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
- WR7146(P_RPSPAGE1, 0); // RPS program performs no
- // explicit mem writes.
- WR7146(P_RPS1_TOUT, 0); // Disable RPS timeouts.
+ WR7146(P_RPSPAGE1, 0);
+ /* RPS program performs no explicit mem writes. */
+ WR7146(P_RPS1_TOUT, 0); /* Disable RPS timeouts. */
- // SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface to a
- // known state by invoking ADCs until FB BUFFER 1 register shows
- // that it is correctly receiving ADC data. This is necessary
- // because the SAA7146 ADC interface does not start up in a
- // defined state after a PCI reset.
+ /* SAA7146 BUG WORKAROUND. Initialize SAA7146 ADC interface
+ * to a known state by invoking ADCs until FB BUFFER 1
+ * register shows that it is correctly receiving ADC data.
+ * This is necessary because the SAA7146 ADC interface does
+ * not start up in a defined state after a PCI reset.
+ */
/* PollList = EOPL; // Create a simple polling */
/* // list for analog input */
@@ -829,115 +826,123 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
/* break; */
/* } */
- // end initADC
+ /* end initADC */
- // init the DAC interface
+ /* init the DAC interface */
- // Init Audio2's output DMAC attributes: burst length = 1 DWORD,
- // threshold = 1 DWORD.
+ /* Init Audio2's output DMAC attributes: burst length = 1
+ * DWORD, threshold = 1 DWORD.
+ */
WR7146(P_PCI_BT_A, 0);
- // Init Audio2's output DMA physical addresses. The protection
- // address is set to 1 DWORD past the base address so that a
- // single DWORD will be transferred each time a DMA transfer is
- // enabled.
+ /* Init Audio2's output DMA physical addresses. The protection
+ * address is set to 1 DWORD past the base address so that a
+ * single DWORD will be transferred each time a DMA transfer is
+ * enabled. */
pPhysBuf =
devpriv->ANABuf.PhysicalBase +
(DAC_WDMABUF_OS * sizeof(uint32_t));
- WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); // Buffer base adrs.
- WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); // Protection address.
+ WR7146(P_BASEA2_OUT, (uint32_t) pPhysBuf); /* Buffer base adrs. */
+ WR7146(P_PROTA2_OUT, (uint32_t) (pPhysBuf + sizeof(uint32_t))); /* Protection address. */
- // Cache Audio2's output DMA buffer logical address. This is
- // where DAC data is buffered for A2 output DMA transfers.
+ /* Cache Audio2's output DMA buffer logical address. This is
+ * where DAC data is buffered for A2 output DMA transfers. */
devpriv->pDacWBuf =
(uint32_t *) devpriv->ANABuf.LogicalBase +
DAC_WDMABUF_OS;
- // Audio2's output channels does not use paging. The protection
- // violation handling bit is set so that the DMAC will
- // automatically halt and its PCI address pointer will be reset
- // when the protection address is reached.
+ /* Audio2's output channels does not use paging. The protection
+ * violation handling bit is set so that the DMAC will
+ * automatically halt and its PCI address pointer will be reset
+ * when the protection address is reached. */
+
WR7146(P_PAGEA2_OUT, 8);
- // Initialize time slot list 2 (TSL2), which is used to control
- // the clock generation for and serialization of data to be sent
- // to the DAC devices. Slot 0 is a NOP that is used to trap TSL
- // execution; this permits other slots to be safely modified
- // without first turning off the TSL sequencer (which is
- // apparently impossible to do). Also, SD3 (which is driven by a
- // pull-up resistor) is shifted in and stored to the MSB of
- // FB_BUFFER2 to be used as evidence that the slot sequence has
- // not yet finished executing.
- SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS); // Slot 0: Trap TSL
- // execution, shift 0xFF
- // into FB_BUFFER2.
-
- // Initialize slot 1, which is constant. Slot 1 causes a DWORD to
- // be transferred from audio channel 2's output FIFO to the FIFO's
- // output buffer so that it can be serialized and sent to the DAC
- // during subsequent slots. All remaining slots are dynamically
- // populated as required by the target DAC device.
- SETVECT(1, LF_A2); // Slot 1: Fetch DWORD from Audio2's
- // output FIFO.
-
- // Start DAC's audio interface (TSL2) running.
+ /* Initialize time slot list 2 (TSL2), which is used to control
+ * the clock generation for and serialization of data to be sent
+ * to the DAC devices. Slot 0 is a NOP that is used to trap TSL
+ * execution; this permits other slots to be safely modified
+ * without first turning off the TSL sequencer (which is
+ * apparently impossible to do). Also, SD3 (which is driven by a
+ * pull-up resistor) is shifted in and stored to the MSB of
+ * FB_BUFFER2 to be used as evidence that the slot sequence has
+ * not yet finished executing.
+ */
+
+ SETVECT(0, XSD2 | RSD3 | SIB_A2 | EOS);
+ /* Slot 0: Trap TSL execution, shift 0xFF into FB_BUFFER2. */
+
+ /* Initialize slot 1, which is constant. Slot 1 causes a
+ * DWORD to be transferred from audio channel 2's output FIFO
+ * to the FIFO's output buffer so that it can be serialized
+ * and sent to the DAC during subsequent slots. All remaining
+ * slots are dynamically populated as required by the target
+ * DAC device.
+ */
+ SETVECT(1, LF_A2);
+ /* Slot 1: Fetch DWORD from Audio2's output FIFO. */
+
+ /* Start DAC's audio interface (TSL2) running. */
WR7146(P_ACON1, ACON1_DACSTART);
- ////////////////////////////////////////////////////////
+ /* end init DAC interface */
- // end init DAC interface
-
- // Init Trim DACs to calibrated values. Do it twice because the
- // SAA7146 audio channel does not always reset properly and
- // sometimes causes the first few TrimDAC writes to malfunction.
+ /* Init Trim DACs to calibrated values. Do it twice because the
+ * SAA7146 audio channel does not always reset properly and
+ * sometimes causes the first few TrimDAC writes to malfunction.
+ */
LoadTrimDACs(dev);
- LoadTrimDACs(dev); // Insurance.
+ LoadTrimDACs(dev); /* Insurance. */
- //////////////////////////////////////////////////////////////////
- // Manually init all gate array hardware in case this is a soft
- // reset (we have no way of determining whether this is a warm or
- // cold start). This is necessary because the gate array will
- // reset only in response to a PCI hard reset; there is no soft
- // reset function.
+ /* Manually init all gate array hardware in case this is a soft
+ * reset (we have no way of determining whether this is a warm
+ * or cold start). This is necessary because the gate array will
+ * reset only in response to a PCI hard reset; there is no soft
+ * reset function. */
- // Init all DAC outputs to 0V and init all DAC setpoint and
- // polarity images.
+ /* Init all DAC outputs to 0V and init all DAC setpoint and
+ * polarity images.
+ */
for (chan = 0; chan < S626_DAC_CHANNELS; chan++)
SetDAC(dev, chan, 0);
- // Init image of WRMISC2 Battery Charger Enabled control bit.
- // This image is used when the state of the charger control bit,
- // which has no direct hardware readback mechanism, is queried.
+ /* Init image of WRMISC2 Battery Charger Enabled control bit.
+ * This image is used when the state of the charger control bit,
+ * which has no direct hardware readback mechanism, is queried.
+ */
devpriv->ChargeEnabled = 0;
- // Init image of watchdog timer interval in WRMISC2. This image
- // maintains the value of the control bits of MISC2 are
- // continuously reset to zero as long as the WD timer is disabled.
+ /* Init image of watchdog timer interval in WRMISC2. This image
+ * maintains the value of the control bits of MISC2 are
+ * continuously reset to zero as long as the WD timer is disabled.
+ */
devpriv->WDInterval = 0;
- // Init Counter Interrupt enab mask for RDMISC2. This mask is
- // applied against MISC2 when testing to determine which timer
- // events are requesting interrupt service.
+ /* Init Counter Interrupt enab mask for RDMISC2. This mask is
+ * applied against MISC2 when testing to determine which timer
+ * events are requesting interrupt service.
+ */
devpriv->CounterIntEnabs = 0;
- // Init counters.
+ /* Init counters. */
CountersInit(dev);
- // Without modifying the state of the Battery Backup enab, disable
- // the watchdog timer, set DIO channels 0-5 to operate in the
- // standard DIO (vs. counter overflow) mode, disable the battery
- // charger, and reset the watchdog interval selector to zero.
+ /* Without modifying the state of the Battery Backup enab, disable
+ * the watchdog timer, set DIO channels 0-5 to operate in the
+ * standard DIO (vs. counter overflow) mode, disable the battery
+ * charger, and reset the watchdog interval selector to zero.
+ */
WriteMISC2(dev, (uint16_t) (DEBIread(dev,
LP_RDMISC2) & MISC2_BATT_ENABLE));
- // Initialize the digital I/O subsystem.
+ /* Initialize the digital I/O subsystem. */
s626_dio_init(dev);
- //enable interrupt test
- // writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER);
+ /* enable interrupt test */
+ /* writel(IRQ_GPIO3 | IRQ_RPS1,devpriv->base_addr+P_IER); */
}
DEBUG("s626_attach: comedi%d s626 attached %04x\n", dev->minor,
@@ -946,9 +951,9 @@ static int s626_attach(comedi_device * dev, comedi_devconfig * it)
return 1;
}
-static lsampl_t s626_ai_reg_to_uint(int data)
+static unsigned int s626_ai_reg_to_uint(int data)
{
- lsampl_t tempdata;
+ unsigned int tempdata;
tempdata = (data >> 18);
if (tempdata & 0x2000)
@@ -959,21 +964,21 @@ static lsampl_t s626_ai_reg_to_uint(int data)
return tempdata;
}
-/* static lsampl_t s626_uint_to_reg(comedi_subdevice *s, int data){ */
+/* static unsigned int s626_uint_to_reg(struct comedi_subdevice *s, int data){ */
/* return 0; */
/* } */
static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
{
- comedi_device *dev = d;
- comedi_subdevice *s;
- comedi_cmd *cmd;
- enc_private *k;
+ struct comedi_device *dev = d;
+ struct comedi_subdevice *s;
+ struct comedi_cmd *cmd;
+ struct enc_private *k;
unsigned long flags;
int32_t *readaddr;
uint32_t irqtype, irqstatus;
int i = 0;
- sampl_t tempdata;
+ short tempdata;
uint8_t group;
uint16_t irqbit;
@@ -981,47 +986,48 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
if (dev->attached == 0)
return IRQ_NONE;
- // lock to avoid race with comedi_poll
+ /* lock to avoid race with comedi_poll */
comedi_spin_lock_irqsave(&dev->spinlock, flags);
- //save interrupt enable register state
+ /* save interrupt enable register state */
irqstatus = readl(devpriv->base_addr + P_IER);
- //read interrupt type
+ /* read interrupt type */
irqtype = readl(devpriv->base_addr + P_ISR);
- //disable master interrupt
+ /* disable master interrupt */
writel(0, devpriv->base_addr + P_IER);
- //clear interrupt
+ /* clear interrupt */
writel(irqtype, devpriv->base_addr + P_ISR);
- //do somethings
+ /* do somethings */
DEBUG("s626_irq_handler: interrupt type %d\n", irqtype);
switch (irqtype) {
- case IRQ_RPS1: // end_of_scan occurs
+ case IRQ_RPS1: /* end_of_scan occurs */
DEBUG("s626_irq_handler: RPS1 irq detected\n");
- // manage ai subdevice
+ /* manage ai subdevice */
s = dev->subdevices;
cmd = &(s->async->cmd);
- // Init ptr to DMA buffer that holds new ADC data. We skip the
- // first uint16_t in the buffer because it contains junk data from
- // the final ADC of the previous poll list scan.
+ /* Init ptr to DMA buffer that holds new ADC data. We skip the
+ * first uint16_t in the buffer because it contains junk data from
+ * the final ADC of the previous poll list scan.
+ */
readaddr = (int32_t *) devpriv->ANABuf.LogicalBase + 1;
- // get the data and hand it over to comedi
+ /* get the data and hand it over to comedi */
for (i = 0; i < (s->async->cmd.chanlist_len); i++) {
- // Convert ADC data to 16-bit integer values and copy to application
- // buffer.
+ /* Convert ADC data to 16-bit integer values and copy to application */
+ /* buffer. */
tempdata = s626_ai_reg_to_uint((int)*readaddr);
readaddr++;
- //put data into read buffer
- // comedi_buf_put(s->async, tempdata);
+ /* put data into read buffer */
+ /* comedi_buf_put(s->async, tempdata); */
if (cfc_write_to_buffer(s, tempdata) == 0)
printk("s626_irq_handler: cfc_write_to_buffer error!\n");
@@ -1029,7 +1035,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
i, tempdata);
}
- //end of scan occurs
+ /* end of scan occurs */
s->async->events |= COMEDI_CB_EOS;
if (!(devpriv->ai_continous))
@@ -1037,13 +1043,13 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
if (devpriv->ai_sample_count <= 0) {
devpriv->ai_cmd_running = 0;
- // Stop RPS program.
+ /* Stop RPS program. */
MC_DISABLE(P_MC1, MC1_ERPS1);
- //send end of acquisition
+ /* send end of acquisition */
s->async->events |= COMEDI_CB_EOA;
- //disable master interrupt
+ /* disable master interrupt */
irqstatus = 0;
}
@@ -1054,40 +1060,40 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
DEBUG("s626_irq_handler: External trigger is set!!!\n");
}
- // tell comedi that data is there
+ /* tell comedi that data is there */
DEBUG("s626_irq_handler: events %d\n", s->async->events);
comedi_event(dev, s);
break;
- case IRQ_GPIO3: //check dio and conter interrupt
+ case IRQ_GPIO3: /* check dio and conter interrupt */
DEBUG("s626_irq_handler: GPIO3 irq detected\n");
- // manage ai subdevice
+ /* manage ai subdevice */
s = dev->subdevices;
cmd = &(s->async->cmd);
- //s626_dio_clear_irq(dev);
+ /* s626_dio_clear_irq(dev); */
for (group = 0; group < S626_DIO_BANKS; group++) {
irqbit = 0;
- //read interrupt type
+ /* read interrupt type */
irqbit = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDCapFlg);
- //check if interrupt is generated from dio channels
+ /* check if interrupt is generated from dio channels */
if (irqbit) {
s626_dio_reset_irq(dev, group, irqbit);
DEBUG("s626_irq_handler: check interrupt on dio group %d %d\n", group, i);
if (devpriv->ai_cmd_running) {
- //check if interrupt is an ai acquisition start trigger
+ /* check if interrupt is an ai acquisition start trigger */
if ((irqbit >> (cmd->start_arg -
(16 * group)))
== 1
&& cmd->start_src == TRIG_EXT) {
DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->start_arg);
- // Start executing the RPS program.
+ /* Start executing the RPS program. */
MC_ENABLE(P_MC1, MC1_ERPS1);
DEBUG("s626_irq_handler: aquisition start triggered!!!\n");
@@ -1110,7 +1116,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
TRIG_EXT) {
DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->scan_begin_arg);
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
DEBUG("s626_irq_handler: scan triggered!!! %d\n", devpriv->ai_sample_count);
@@ -1151,7 +1157,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
TRIG_EXT) {
DEBUG("s626_irq_handler: Edge capture interrupt recieved from channel %d\n", cmd->convert_arg);
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
DEBUG("s626_irq_handler: adc convert triggered!!!\n");
@@ -1175,10 +1181,10 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
}
}
- //read interrupt type
+ /* read interrupt type */
irqbit = DEBIread(dev, LP_RDMISC2);
- //check interrupt on counters
+ /* check interrupt on counters */
DEBUG("s626_irq_handler: check counters interrupt %d\n",
irqbit);
@@ -1186,35 +1192,35 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
DEBUG("s626_irq_handler: interrupt on counter 1A overflow\n");
k = &encpriv[0];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT2A) {
DEBUG("s626_irq_handler: interrupt on counter 2A overflow\n");
k = &encpriv[1];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT3A) {
DEBUG("s626_irq_handler: interrupt on counter 3A overflow\n");
k = &encpriv[2];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT1B) {
DEBUG("s626_irq_handler: interrupt on counter 1B overflow\n");
k = &encpriv[3];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
}
if (irqbit & IRQ_COINT2B) {
DEBUG("s626_irq_handler: interrupt on counter 2B overflow\n");
k = &encpriv[4];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
if (devpriv->ai_convert_count > 0) {
@@ -1225,7 +1231,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
if (cmd->convert_src == TRIG_TIMER) {
DEBUG("s626_irq_handler: conver timer trigger!!! %d\n", devpriv->ai_convert_count);
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
}
}
@@ -1234,13 +1240,13 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
DEBUG("s626_irq_handler: interrupt on counter 3B overflow\n");
k = &encpriv[5];
- //clear interrupt capture flag
+ /* clear interrupt capture flag */
k->ResetCapFlags(dev, k);
if (cmd->scan_begin_src == TRIG_TIMER) {
DEBUG("s626_irq_handler: scan timer trigger!!!\n");
- // Trigger ADC scan loop start by setting RPS Signal 0.
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
MC_ENABLE(P_MC2, MC2_ADC_RPS);
}
@@ -1253,7 +1259,7 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
}
}
- //enable interrupt
+ /* enable interrupt */
writel(irqstatus, devpriv->base_addr + P_IER);
DEBUG("s626_irq_handler: exit interrupt service routine.\n");
@@ -1262,21 +1268,21 @@ static irqreturn_t s626_irq_handler(int irq, void *d PT_REGS_ARG)
return IRQ_HANDLED;
}
-static int s626_detach(comedi_device * dev)
+static int s626_detach(struct comedi_device *dev)
{
if (devpriv) {
- //stop ai_command
+ /* stop ai_command */
devpriv->ai_cmd_running = 0;
if (devpriv->base_addr) {
- //interrupt mask
- WR7146(P_IER, 0); // Disable master interrupt.
- WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); // Clear board's IRQ status flag.
+ /* interrupt mask */
+ WR7146(P_IER, 0); /* Disable master interrupt. */
+ WR7146(P_ISR, IRQ_GPIO3 | IRQ_RPS1); /* Clear board's IRQ status flag. */
- // Disable the watchdog timer and battery charger.
+ /* Disable the watchdog timer and battery charger. */
WriteMISC2(dev, 0);
- // Close all interfaces on 7146 device.
+ /* Close all interfaces on 7146 device. */
WR7146(P_MC1, MC1_SHUTDOWN);
WR7146(P_ACON1, ACON1_BASE);
@@ -1284,18 +1290,15 @@ static int s626_detach(comedi_device * dev)
CloseDMAB(dev, &devpriv->ANABuf, DMABUF_SIZE);
}
- if (dev->irq) {
+ if (dev->irq)
comedi_free_irq(dev->irq, dev);
- }
- if (devpriv->base_addr) {
+ if (devpriv->base_addr)
iounmap(devpriv->base_addr);
- }
if (devpriv->pdev) {
- if (devpriv->got_regions) {
+ if (devpriv->got_regions)
comedi_pci_disable(devpriv->pdev);
- }
pci_dev_put(devpriv->pdev);
}
}
@@ -1308,213 +1311,225 @@ static int s626_detach(comedi_device * dev)
/*
* this functions build the RPS program for hardware driven acquistion
*/
-void ResetADC(comedi_device * dev, uint8_t * ppl)
+void ResetADC(struct comedi_device *dev, uint8_t *ppl)
{
register uint32_t *pRPS;
uint32_t JmpAdrs;
uint16_t i;
uint16_t n;
uint32_t LocalPPL;
- comedi_cmd *cmd = &(dev->subdevices->async->cmd);
+ struct comedi_cmd *cmd = &(dev->subdevices->async->cmd);
- // Stop RPS program in case it is currently running.
+ /* Stop RPS program in case it is currently running. */
MC_DISABLE(P_MC1, MC1_ERPS1);
- // Set starting logical address to write RPS commands.
+ /* Set starting logical address to write RPS commands. */
pRPS = (uint32_t *) devpriv->RPSBuf.LogicalBase;
- // Initialize RPS instruction pointer.
+ /* Initialize RPS instruction pointer. */
WR7146(P_RPSADDR1, (uint32_t) devpriv->RPSBuf.PhysicalBase);
- // Construct RPS program in RPSBuf DMA buffer
+ /* Construct RPS program in RPSBuf DMA buffer */
if (cmd != NULL && cmd->scan_begin_src != TRIG_FOLLOW) {
DEBUG("ResetADC: scan_begin pause inserted\n");
- // Wait for Start trigger.
+ /* Wait for Start trigger. */
*pRPS++ = RPS_PAUSE | RPS_SIGADC;
*pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
}
- // SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary
- // because the first RPS DEBI Write following a non-RPS DEBI write
- // seems to always fail. If we don't do this dummy write, the ADC
- // gain might not be set to the value required for the first slot in
- // the poll list; the ADC gain would instead remain unchanged from
- // the previously programmed value.
- *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); // Write DEBI Write command
- // and address to shadow RAM.
+
+ /* SAA7146 BUG WORKAROUND Do a dummy DEBI Write. This is necessary
+ * because the first RPS DEBI Write following a non-RPS DEBI write
+ * seems to always fail. If we don't do this dummy write, the ADC
+ * gain might not be set to the value required for the first slot in
+ * the poll list; the ADC gain would instead remain unchanged from
+ * the previously programmed value.
+ */
+ *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
+ /* Write DEBI Write command and address to shadow RAM. */
+
*pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
- *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); // Write DEBI immediate data
- // to shadow RAM:
- *pRPS++ = GSEL_BIPOLAR5V; // arbitrary immediate data
- // value.
- *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; // Reset "shadow RAM
- // uploaded" flag.
- *pRPS++ = RPS_UPLOAD | RPS_DEBI; // Invoke shadow RAM upload.
- *pRPS++ = RPS_PAUSE | RPS_DEBI; // Wait for shadow upload to finish.
-
- // Digitize all slots in the poll list. This is implemented as a
- // for loop to limit the slot count to 16 in case the application
- // forgot to set the EOPL flag in the final slot.
+ *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
+ /* Write DEBI immediate data to shadow RAM: */
+
+ *pRPS++ = GSEL_BIPOLAR5V;
+ /* arbitrary immediate data value. */
+
+ *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
+ /* Reset "shadow RAM uploaded" flag. */
+ *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */
+ *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to finish. */
+
+ /* Digitize all slots in the poll list. This is implemented as a
+ * for loop to limit the slot count to 16 in case the application
+ * forgot to set the EOPL flag in the final slot.
+ */
for (devpriv->AdcItems = 0; devpriv->AdcItems < 16; devpriv->AdcItems++) {
- // Convert application's poll list item to private board class
- // format. Each app poll list item is an uint8_t with form
- // (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
- // +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
+ /* Convert application's poll list item to private board class
+ * format. Each app poll list item is an uint8_t with form
+ * (EOPL,x,x,RANGE,CHAN<3:0>), where RANGE code indicates 0 =
+ * +-10V, 1 = +-5V, and EOPL = End of Poll List marker.
+ */
LocalPPL =
(*ppl << 8) | (*ppl & 0x10 ? GSEL_BIPOLAR5V :
GSEL_BIPOLAR10V);
- // Switch ADC analog gain.
- *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); // Write DEBI command
- // and address to
- // shadow RAM.
+ /* Switch ADC analog gain. */
+ *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); /* Write DEBI command */
+ /* and address to */
+ /* shadow RAM. */
*pRPS++ = DEBI_CMD_WRWORD | LP_GSEL;
- *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); // Write DEBI
- // immediate data to
- // shadow RAM.
+ *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); /* Write DEBI */
+ /* immediate data to */
+ /* shadow RAM. */
*pRPS++ = LocalPPL;
- *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; // Reset "shadow RAM uploaded"
- // flag.
- *pRPS++ = RPS_UPLOAD | RPS_DEBI; // Invoke shadow RAM upload.
- *pRPS++ = RPS_PAUSE | RPS_DEBI; // Wait for shadow upload to
- // finish.
-
- // Select ADC analog input channel.
- *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2); // Write DEBI command
- // and address to
- // shadow RAM.
+ *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; /* Reset "shadow RAM uploaded" */
+ /* flag. */
+ *pRPS++ = RPS_UPLOAD | RPS_DEBI; /* Invoke shadow RAM upload. */
+ *pRPS++ = RPS_PAUSE | RPS_DEBI; /* Wait for shadow upload to */
+ /* finish. */
+
+ /* Select ADC analog input channel. */
+ *pRPS++ = RPS_LDREG | (P_DEBICMD >> 2);
+ /* Write DEBI command and address to shadow RAM. */
*pRPS++ = DEBI_CMD_WRWORD | LP_ISEL;
- *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2); // Write DEBI
- // immediate data to
- // shadow RAM.
+ *pRPS++ = RPS_LDREG | (P_DEBIAD >> 2);
+ /* Write DEBI immediate data to shadow RAM. */
*pRPS++ = LocalPPL;
- *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI; // Reset "shadow RAM uploaded"
- // flag.
- *pRPS++ = RPS_UPLOAD | RPS_DEBI; // Invoke shadow RAM upload.
- *pRPS++ = RPS_PAUSE | RPS_DEBI; // Wait for shadow upload to
- // finish.
-
- // Delay at least 10 microseconds for analog input settling.
- // Instead of padding with NOPs, we use RPS_JUMP instructions
- // here; this allows us to produce a longer delay than is
- // possible with NOPs because each RPS_JUMP flushes the RPS'
- // instruction prefetch pipeline.
+ *pRPS++ = RPS_CLRSIGNAL | RPS_DEBI;
+ /* Reset "shadow RAM uploaded" flag. */
+
+ *pRPS++ = RPS_UPLOAD | RPS_DEBI;
+ /* Invoke shadow RAM upload. */
+
+ *pRPS++ = RPS_PAUSE | RPS_DEBI;
+ /* Wait for shadow upload to finish. */
+
+ /* Delay at least 10 microseconds for analog input settling.
+ * Instead of padding with NOPs, we use RPS_JUMP instructions
+ * here; this allows us to produce a longer delay than is
+ * possible with NOPs because each RPS_JUMP flushes the RPS'
+ * instruction prefetch pipeline.
+ */
JmpAdrs =
(uint32_t) devpriv->RPSBuf.PhysicalBase +
(uint32_t) ((unsigned long)pRPS -
(unsigned long)devpriv->RPSBuf.LogicalBase);
for (i = 0; i < (10 * RPSCLK_PER_US / 2); i++) {
- JmpAdrs += 8; // Repeat to implement time delay:
- *pRPS++ = RPS_JUMP; // Jump to next RPS instruction.
+ JmpAdrs += 8; /* Repeat to implement time delay: */
+ *pRPS++ = RPS_JUMP; /* Jump to next RPS instruction. */
*pRPS++ = JmpAdrs;
}
if (cmd != NULL && cmd->convert_src != TRIG_NOW) {
DEBUG("ResetADC: convert pause inserted\n");
- // Wait for Start trigger.
+ /* Wait for Start trigger. */
*pRPS++ = RPS_PAUSE | RPS_SIGADC;
*pRPS++ = RPS_CLRSIGNAL | RPS_SIGADC;
}
- // Start ADC by pulsing GPIO1.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // Begin ADC Start pulse.
+ /* Start ADC by pulsing GPIO1. */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_LO;
*pRPS++ = RPS_NOP;
- // VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // End ADC Start pulse.
+ /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_HI;
- // Wait for ADC to complete (GPIO2 is asserted high when ADC not
- // busy) and for data from previous conversion to shift into FB
- // BUFFER 1 register.
- *pRPS++ = RPS_PAUSE | RPS_GPIO2; // Wait for ADC done.
+ /* Wait for ADC to complete (GPIO2 is asserted high when ADC not
+ * busy) and for data from previous conversion to shift into FB
+ * BUFFER 1 register.
+ */
+ *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */
- // Transfer ADC data from FB BUFFER 1 register to DMA buffer.
+ /* Transfer ADC data from FB BUFFER 1 register to DMA buffer. */
*pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2);
*pRPS++ =
(uint32_t) devpriv->ANABuf.PhysicalBase +
(devpriv->AdcItems << 2);
- // If this slot's EndOfPollList flag is set, all channels have
- // now been processed.
+ /* If this slot's EndOfPollList flag is set, all channels have */
+ /* now been processed. */
if (*ppl++ & EOPL) {
- devpriv->AdcItems++; // Adjust poll list item count.
- break; // Exit poll list processing loop.
+ devpriv->AdcItems++; /* Adjust poll list item count. */
+ break; /* Exit poll list processing loop. */
}
}
DEBUG("ResetADC: ADC items %d \n", devpriv->AdcItems);
- // VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the
- // ADC to stabilize for 2 microseconds before starting the final
- // (dummy) conversion. This delay is necessary to allow sufficient
- // time between last conversion finished and the start of the dummy
- // conversion. Without this delay, the last conversion's data value
- // is sometimes set to the previous conversion's data value.
+ /* VERSION 2.01 CHANGE: DELAY CHANGED FROM 250NS to 2US. Allow the
+ * ADC to stabilize for 2 microseconds before starting the final
+ * (dummy) conversion. This delay is necessary to allow sufficient
+ * time between last conversion finished and the start of the dummy
+ * conversion. Without this delay, the last conversion's data value
+ * is sometimes set to the previous conversion's data value.
+ */
for (n = 0; n < (2 * RPSCLK_PER_US); n++)
*pRPS++ = RPS_NOP;
- // Start a dummy conversion to cause the data from the last
- // conversion of interest to be shifted in.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // Begin ADC Start pulse.
+ /* Start a dummy conversion to cause the data from the last
+ * conversion of interest to be shifted in.
+ */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* Begin ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_LO;
*pRPS++ = RPS_NOP;
- // VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE.
- *pRPS++ = RPS_LDREG | (P_GPIO >> 2); // End ADC Start pulse.
+ /* VERSION 2.03 CHANGE: STRETCH OUT ADC START PULSE. */
+ *pRPS++ = RPS_LDREG | (P_GPIO >> 2); /* End ADC Start pulse. */
*pRPS++ = GPIO_BASE | GPIO1_HI;
- // Wait for the data from the last conversion of interest to arrive
- // in FB BUFFER 1 register.
- *pRPS++ = RPS_PAUSE | RPS_GPIO2; // Wait for ADC done.
+ /* Wait for the data from the last conversion of interest to arrive
+ * in FB BUFFER 1 register.
+ */
+ *pRPS++ = RPS_PAUSE | RPS_GPIO2; /* Wait for ADC done. */
- // Transfer final ADC data from FB BUFFER 1 register to DMA buffer.
- *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); //
+ /* Transfer final ADC data from FB BUFFER 1 register to DMA buffer. */
+ *pRPS++ = RPS_STREG | (BUGFIX_STREG(P_FB_BUFFER1) >> 2); /* */
*pRPS++ =
(uint32_t) devpriv->ANABuf.PhysicalBase +
(devpriv->AdcItems << 2);
- // Indicate ADC scan loop is finished.
- // *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; // Signal ReadADC() that scan is done.
+ /* Indicate ADC scan loop is finished. */
+ /* *pRPS++= RPS_CLRSIGNAL | RPS_SIGADC ; // Signal ReadADC() that scan is done. */
- //invoke interrupt
+ /* invoke interrupt */
if (devpriv->ai_cmd_running == 1) {
DEBUG("ResetADC: insert irq in ADC RPS task\n");
*pRPS++ = RPS_IRQ;
}
- // Restart RPS program at its beginning.
- *pRPS++ = RPS_JUMP; // Branch to start of RPS program.
+ /* Restart RPS program at its beginning. */
+ *pRPS++ = RPS_JUMP; /* Branch to start of RPS program. */
*pRPS++ = (uint32_t) devpriv->RPSBuf.PhysicalBase;
- // End of RPS program build
- // ------------------------------------------------------------
+ /* End of RPS program build */
}
/* TO COMPLETE, IF NECESSARY */
-static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ai_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
return -EINVAL;
}
-/* static int s626_ai_rinsn(comedi_device *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data) */
+/* static int s626_ai_rinsn(struct comedi_device *dev,struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) */
/* { */
/* register uint8_t i; */
/* register int32_t *readaddr; */
/* DEBUG("as626_ai_rinsn: ai_rinsn enter \n"); */
-/* // Trigger ADC scan loop start by setting RPS Signal 0. */
+/* Trigger ADC scan loop start by setting RPS Signal 0. */
/* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
-/* // Wait until ADC scan loop is finished (RPS Signal 0 reset). */
+/* Wait until ADC scan loop is finished (RPS Signal 0 reset). */
/* while ( MC_TEST( P_MC2, MC2_ADC_RPS ) ); */
-/* // Init ptr to DMA buffer that holds new ADC data. We skip the */
-/* // first uint16_t in the buffer because it contains junk data from */
-/* // the final ADC of the previous poll list scan. */
+/* Init ptr to DMA buffer that holds new ADC data. We skip the
+ * first uint16_t in the buffer because it contains junk data from
+ * the final ADC of the previous poll list scan.
+ */
/* readaddr = (uint32_t *)devpriv->ANABuf.LogicalBase + 1; */
-/* // Convert ADC data to 16-bit integer values and copy to application */
-/* // buffer. */
+/* Convert ADC data to 16-bit integer values and copy to application buffer. */
/* for ( i = 0; i < devpriv->AdcItems; i++ ) { */
/* *data = s626_ai_reg_to_uint( *readaddr++ ); */
/* DEBUG("s626_ai_rinsn: data %d \n",*data); */
@@ -1525,8 +1540,8 @@ static int s626_ai_insn_config(comedi_device * dev, comedi_subdevice * s,
/* return i; */
/* } */
-static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
uint16_t chan = CR_CHAN(insn->chanspec);
uint16_t range = CR_RANGE(insn->chanspec);
@@ -1534,86 +1549,87 @@ static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
uint32_t GpioImage;
int n;
-/* //interrupt call test */
-/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); //Writing a logical 1 */
-/* //into any of the RPS_PSR */
-/* //bits causes the */
-/* //corresponding interrupt */
-/* //to be generated if */
-/* //enabled */
+ /* interrupt call test */
+/* writel(IRQ_GPIO3,devpriv->base_addr+P_PSR); */
+ /* Writing a logical 1 into any of the RPS_PSR bits causes the
+ * corresponding interrupt to be generated if enabled
+ */
DEBUG("s626_ai_insn_read: entering\n");
- // Convert application's ADC specification into form
- // appropriate for register programming.
+ /* Convert application's ADC specification into form
+ * appropriate for register programming.
+ */
if (range == 0)
AdcSpec = (chan << 8) | (GSEL_BIPOLAR5V);
else
AdcSpec = (chan << 8) | (GSEL_BIPOLAR10V);
- // Switch ADC analog gain.
- DEBIwrite(dev, LP_GSEL, AdcSpec); // Set gain.
+ /* Switch ADC analog gain. */
+ DEBIwrite(dev, LP_GSEL, AdcSpec); /* Set gain. */
- // Select ADC analog input channel.
- DEBIwrite(dev, LP_ISEL, AdcSpec); // Select channel.
+ /* Select ADC analog input channel. */
+ DEBIwrite(dev, LP_ISEL, AdcSpec); /* Select channel. */
for (n = 0; n < insn->n; n++) {
- // Delay 10 microseconds for analog input settling.
+ /* Delay 10 microseconds for analog input settling. */
comedi_udelay(10);
- // Start ADC by pulsing GPIO1 low.
+ /* Start ADC by pulsing GPIO1 low. */
GpioImage = RR7146(P_GPIO);
- // Assert ADC Start command
+ /* Assert ADC Start command */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // and stretch it out.
+ /* and stretch it out. */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // Negate ADC Start command.
+ /* Negate ADC Start command. */
WR7146(P_GPIO, GpioImage | GPIO1_HI);
- // Wait for ADC to complete (GPIO2 is asserted high when
- // ADC not busy) and for data from previous conversion to
- // shift into FB BUFFER 1 register.
+ /* Wait for ADC to complete (GPIO2 is asserted high when */
+ /* ADC not busy) and for data from previous conversion to */
+ /* shift into FB BUFFER 1 register. */
- // Wait for ADC done.
- while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+ /* Wait for ADC done. */
+ while (!(RR7146(P_PSR) & PSR_GPIO2))
+ ;
- // Fetch ADC data.
+ /* Fetch ADC data. */
if (n != 0)
data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
- // Allow the ADC to stabilize for 4 microseconds before
- // starting the next (final) conversion. This delay is
- // necessary to allow sufficient time between last
- // conversion finished and the start of the next
- // conversion. Without this delay, the last conversion's
- // data value is sometimes set to the previous
- // conversion's data value.
+ /* Allow the ADC to stabilize for 4 microseconds before
+ * starting the next (final) conversion. This delay is
+ * necessary to allow sufficient time between last
+ * conversion finished and the start of the next
+ * conversion. Without this delay, the last conversion's
+ * data value is sometimes set to the previous
+ * conversion's data value.
+ */
comedi_udelay(4);
}
- // Start a dummy conversion to cause the data from the
- // previous conversion to be shifted in.
+ /* Start a dummy conversion to cause the data from the
+ * previous conversion to be shifted in. */
GpioImage = RR7146(P_GPIO);
- //Assert ADC Start command
+ /* Assert ADC Start command */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // and stretch it out.
+ /* and stretch it out. */
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
WR7146(P_GPIO, GpioImage & ~GPIO1_HI);
- // Negate ADC Start command.
+ /* Negate ADC Start command. */
WR7146(P_GPIO, GpioImage | GPIO1_HI);
- // Wait for the data to arrive in FB BUFFER 1 register.
+ /* Wait for the data to arrive in FB BUFFER 1 register. */
- // Wait for ADC done.
- while (!(RR7146(P_PSR) & PSR_GPIO2)) ;
+ /* Wait for ADC done. */
+ while (!(RR7146(P_PSR) & PSR_GPIO2))
+ ;
- // Fetch ADC data from audio interface's input shift
- // register.
+ /* Fetch ADC data from audio interface's input shift register. */
- // Fetch ADC data.
+ /* Fetch ADC data. */
if (n != 0)
data[n - 1] = s626_ai_reg_to_uint(RR7146(P_FB_BUFFER1));
@@ -1622,7 +1638,7 @@ static int s626_ai_insn_read(comedi_device * dev, comedi_subdevice * s,
return n;
}
-static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd)
+static int s626_ai_load_polllist(uint8_t *ppl, struct comedi_cmd *cmd)
{
int n;
@@ -1638,7 +1654,7 @@ static int s626_ai_load_polllist(uint8_t * ppl, comedi_cmd * cmd)
return n;
}
-static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
+static int s626_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
if (trignum != 0)
@@ -1646,7 +1662,7 @@ static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
DEBUG("s626_ai_inttrig: trigger adc start...");
- // Start executing the RPS program.
+ /* Start executing the RPS program. */
MC_ENABLE(P_MC1, MC1_ERPS1);
s->async->inttrig = NULL;
@@ -1657,12 +1673,12 @@ static int s626_ai_inttrig(comedi_device * dev, comedi_subdevice * s,
}
/* TO COMPLETE */
-static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int s626_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
uint8_t ppl[16];
- comedi_cmd *cmd = &s->async->cmd;
- enc_private *k;
+ struct comedi_cmd *cmd = &s->async->cmd;
+ struct enc_private *k;
int tick;
DEBUG("s626_ai_cmd: entering command function\n");
@@ -1672,20 +1688,20 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
dev->minor);
return -EBUSY;
}
- //disable interrupt
+ /* disable interrupt */
writel(0, devpriv->base_addr + P_IER);
- //clear interrupt request
+ /* clear interrupt request */
writel(IRQ_RPS1 | IRQ_GPIO3, devpriv->base_addr + P_ISR);
- //clear any pending interrupt
+ /* clear any pending interrupt */
s626_dio_clear_irq(dev);
- // s626_enc_clear_irq(dev);
+ /* s626_enc_clear_irq(dev); */
- //reset ai_cmd_running flag
+ /* reset ai_cmd_running flag */
devpriv->ai_cmd_running = 0;
- // test if cmd is valid
+ /* test if cmd is valid */
if (cmd == NULL) {
DEBUG("s626_ai_cmd: NULL command\n");
return -EINVAL;
@@ -1707,12 +1723,12 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
case TRIG_FOLLOW:
break;
case TRIG_TIMER:
- // set a conter to generate adc trigger at scan_begin_arg interval
+ /* set a conter to generate adc trigger at scan_begin_arg interval */
k = &encpriv[5];
tick = s626_ns_to_timer((int *)&cmd->scan_begin_arg,
cmd->flags & TRIG_ROUND_MASK);
- //load timer value and enable interrupt
+ /* load timer value and enable interrupt */
s626_timer_load(dev, k, tick);
k->SetEnable(dev, k, CLKENAB_ALWAYS);
@@ -1721,7 +1737,7 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
break;
case TRIG_EXT:
- // set the digital line and interrupt for scan trigger
+ /* set the digital line and interrupt for scan trigger */
if (cmd->start_src != TRIG_EXT)
s626_dio_set_irq(dev, cmd->scan_begin_arg);
@@ -1734,19 +1750,19 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
case TRIG_NOW:
break;
case TRIG_TIMER:
- // set a conter to generate adc trigger at convert_arg interval
+ /* set a conter to generate adc trigger at convert_arg interval */
k = &encpriv[4];
tick = s626_ns_to_timer((int *)&cmd->convert_arg,
cmd->flags & TRIG_ROUND_MASK);
- //load timer value and enable interrupt
+ /* load timer value and enable interrupt */
s626_timer_load(dev, k, tick);
k->SetEnable(dev, k, CLKENAB_INDEX);
DEBUG("s626_ai_cmd: convert trigger timer is set with value %d\n", tick);
break;
case TRIG_EXT:
- // set the digital line and interrupt for convert trigger
+ /* set the digital line and interrupt for convert trigger */
if (cmd->scan_begin_src != TRIG_EXT
&& cmd->start_src == TRIG_EXT)
s626_dio_set_irq(dev, cmd->convert_arg);
@@ -1758,12 +1774,12 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
switch (cmd->stop_src) {
case TRIG_COUNT:
- // data arrives as one packet
+ /* data arrives as one packet */
devpriv->ai_sample_count = cmd->stop_arg;
devpriv->ai_continous = 0;
break;
case TRIG_NONE:
- // continous aquisition
+ /* continous aquisition */
devpriv->ai_continous = 1;
devpriv->ai_sample_count = 0;
break;
@@ -1773,17 +1789,17 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
switch (cmd->start_src) {
case TRIG_NOW:
- // Trigger ADC scan loop start by setting RPS Signal 0.
- // MC_ENABLE( P_MC2, MC2_ADC_RPS );
+ /* Trigger ADC scan loop start by setting RPS Signal 0. */
+ /* MC_ENABLE( P_MC2, MC2_ADC_RPS ); */
- // Start executing the RPS program.
+ /* Start executing the RPS program. */
MC_ENABLE(P_MC1, MC1_ERPS1);
DEBUG("s626_ai_cmd: ADC triggered\n");
s->async->inttrig = NULL;
break;
case TRIG_EXT:
- //configure DIO channel for acquisition trigger
+ /* configure DIO channel for acquisition trigger */
s626_dio_set_irq(dev, cmd->start_arg);
DEBUG("s626_ai_cmd: External start trigger is set!!!\n");
@@ -1795,7 +1811,7 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
break;
}
- //enable interrupt
+ /* enable interrupt */
writel(IRQ_GPIO3 | IRQ_RPS1, devpriv->base_addr + P_IER);
DEBUG("s626_ai_cmd: command function terminated\n");
@@ -1803,8 +1819,8 @@ static int s626_ai_cmd(comedi_device * dev, comedi_subdevice * s)
return 0;
}
-static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
- comedi_cmd * cmd)
+static int s626_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0;
int tmp;
@@ -1988,12 +2004,12 @@ static int s626_ai_cmdtest(comedi_device * dev, comedi_subdevice * s,
return 0;
}
-static int s626_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+static int s626_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
- // Stop RPS program in case it is currently running.
+ /* Stop RPS program in case it is currently running. */
MC_DISABLE(P_MC1, MC1_ERPS1);
- //disable master interrupt
+ /* disable master interrupt */
writel(0, devpriv->base_addr + P_IER);
devpriv->ai_cmd_running = 0;
@@ -2010,7 +2026,7 @@ static int s626_ns_to_timer(int *nanosec, int round_mode)
{
int divider, base;
- base = 500; //2MHz internal clock
+ base = 500; /* 2MHz internal clock */
switch (round_mode) {
case TRIG_ROUND_NEAREST:
@@ -2029,8 +2045,8 @@ static int s626_ns_to_timer(int *nanosec, int round_mode)
return divider - 1;
}
-static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
@@ -2048,45 +2064,42 @@ static int s626_ao_winsn(comedi_device * dev, comedi_subdevice * s,
return i;
}
-static int s626_ao_rinsn(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_ao_rinsn(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
- for (i = 0; i < insn->n; i++) {
+ for (i = 0; i < insn->n; i++)
data[i] = devpriv->ao_readback[CR_CHAN(insn->chanspec)];
- }
return i;
}
-/////////////////////////////////////////////////////////////////////
-/////////////// DIGITAL I/O FUNCTIONS /////////////////////////////
-/////////////////////////////////////////////////////////////////////
-// All DIO functions address a group of DIO channels by means of
-// "group" argument. group may be 0, 1 or 2, which correspond to DIO
-// ports A, B and C, respectively.
-/////////////////////////////////////////////////////////////////////
+/* *************** DIGITAL I/O FUNCTIONS ***************
+ * All DIO functions address a group of DIO channels by means of
+ * "group" argument. group may be 0, 1 or 2, which correspond to DIO
+ * ports A, B and C, respectively.
+ */
-static void s626_dio_init(comedi_device * dev)
+static void s626_dio_init(struct comedi_device *dev)
{
uint16_t group;
- comedi_subdevice *s;
+ struct comedi_subdevice *s;
- // Prepare to treat writes to WRCapSel as capture disables.
+ /* Prepare to treat writes to WRCapSel as capture disables. */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
- // For each group of sixteen channels ...
+ /* For each group of sixteen channels ... */
for (group = 0; group < S626_DIO_BANKS; group++) {
s = dev->subdevices + 2 + group;
- DEBIwrite(dev, diopriv->WRIntSel, 0); // Disable all interrupts.
- DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); // Disable all event
- // captures.
- DEBIwrite(dev, diopriv->WREdgSel, 0); // Init all DIOs to
- // default edge
- // polarity.
- DEBIwrite(dev, diopriv->WRDOut, 0); // Program all outputs
- // to inactive state.
+ DEBIwrite(dev, diopriv->WRIntSel, 0); /* Disable all interrupts. */
+ DEBIwrite(dev, diopriv->WRCapSel, 0xFFFF); /* Disable all event */
+ /* captures. */
+ DEBIwrite(dev, diopriv->WREdgSel, 0); /* Init all DIOs to */
+ /* default edge */
+ /* polarity. */
+ DEBIwrite(dev, diopriv->WRDOut, 0); /* Program all outputs */
+ /* to inactive state. */
}
DEBUG("s626_dio_init: DIO initialized \n");
}
@@ -2097,14 +2110,14 @@ static void s626_dio_init(comedi_device * dev)
* This allows packed reading/writing of the DIO channels. The comedi
* core can convert between insn_bits and insn_read/write */
-static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
/* Length of data must be 2 (mask and new data, see below) */
- if (insn->n == 0) {
+ if (insn->n == 0)
return 0;
- }
+
if (insn->n != 2) {
printk("comedi%d: s626: s626_dio_insn_bits(): Invalid instruction length\n", dev->minor);
return -EINVAL;
@@ -2133,8 +2146,8 @@ static int s626_dio_insn_bits(comedi_device * dev, comedi_subdevice * s,
return 2;
}
-static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
switch (data[0]) {
@@ -2160,75 +2173,75 @@ static int s626_dio_insn_config(comedi_device * dev, comedi_subdevice * s,
return 1;
}
-static int s626_dio_set_irq(comedi_device * dev, unsigned int chan)
+static int s626_dio_set_irq(struct comedi_device *dev, unsigned int chan)
{
unsigned int group;
unsigned int bitmask;
unsigned int status;
- //select dio bank
+ /* select dio bank */
group = chan / 16;
bitmask = 1 << (chan - (16 * group));
DEBUG("s626_dio_set_irq: enable interrupt on dio channel %d group %d\n",
chan - (16 * group), group);
- //set channel to capture positive edge
+ /* set channel to capture positive edge */
status = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDEdgSel);
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WREdgSel, bitmask | status);
- //enable interrupt on selected channel
+ /* enable interrupt on selected channel */
status = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDIntSel);
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRIntSel, bitmask | status);
- //enable edge capture write command
+ /* enable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_EDCAP);
- //enable edge capture on selected channel
+ /* enable edge capture on selected channel */
status = DEBIread(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->RDCapSel);
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRCapSel, bitmask | status);
return 0;
}
-static int s626_dio_reset_irq(comedi_device * dev, unsigned int group,
+static int s626_dio_reset_irq(struct comedi_device *dev, unsigned int group,
unsigned int mask)
{
DEBUG("s626_dio_reset_irq: disable interrupt on dio channel %d group %d\n", mask, group);
- //disable edge capture write command
+ /* disable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
- //enable edge capture on selected channel
+ /* enable edge capture on selected channel */
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRCapSel, mask);
return 0;
}
-static int s626_dio_clear_irq(comedi_device * dev)
+static int s626_dio_clear_irq(struct comedi_device *dev)
{
unsigned int group;
- //disable edge capture write command
+ /* disable edge capture write command */
DEBIwrite(dev, LP_MISC1, MISC1_NOEDCAP);
for (group = 0; group < S626_DIO_BANKS; group++) {
- //clear pending events and interrupt
+ /* clear pending events and interrupt */
DEBIwrite(dev,
- ((dio_private *) (dev->subdevices + 2 +
+ ((struct dio_private *) (dev->subdevices + 2 +
group)->private)->WRCapSel, 0xffff);
}
@@ -2238,26 +2251,26 @@ static int s626_dio_clear_irq(comedi_device * dev)
/* Now this function initializes the value of the counter (data[0])
and set the subdevice. To complete with trigger and interrupt
configuration */
-static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
- uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | // Preload upon
- // index.
- (INDXSRC_SOFT << BF_INDXSRC) | // Disable hardware index.
- (CLKSRC_COUNTER << BF_CLKSRC) | // Operating mode is Counter.
- (CLKPOL_POS << BF_CLKPOL) | // Active high clock.
- //( CNTDIR_UP << BF_CLKPOL ) | // Count direction is Down.
- (CLKMULT_1X << BF_CLKMULT) | // Clock multiplier is 1x.
+ uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */
+ /* index. */
+ (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */
+ (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is Counter. */
+ (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */
+ /* ( CNTDIR_UP << BF_CLKPOL ) | // Count direction is Down. */
+ (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */
(CLKENAB_INDEX << BF_CLKENAB);
/* uint16_t DisableIntSrc=TRUE; */
- // uint32_t Preloadvalue; //Counter initial value
+ /* uint32_t Preloadvalue; //Counter initial value */
uint16_t valueSrclatch = LATCHSRC_AB_READ;
uint16_t enab = CLKENAB_ALWAYS;
- enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+ struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
DEBUG("s626_enc_insn_config: encoder config\n");
- // (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]);
+ /* (data==NULL) ? (Preloadvalue=0) : (Preloadvalue=data[0]); */
k->SetMode(dev, k, Setup, TRUE);
Preload(dev, k, *(insn->data));
@@ -2268,12 +2281,12 @@ static int s626_enc_insn_config(comedi_device * dev, comedi_subdevice * s,
return insn->n;
}
-static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int n;
- enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+ struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
DEBUG("s626_enc_insn_read: encoder read channel %d \n",
CR_CHAN(insn->chanspec));
@@ -2286,20 +2299,20 @@ static int s626_enc_insn_read(comedi_device * dev, comedi_subdevice * s,
return n;
}
-static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
- comedi_insn * insn, lsampl_t * data)
+static int s626_enc_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
- enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
+ struct enc_private *k = &encpriv[CR_CHAN(insn->chanspec)];
DEBUG("s626_enc_insn_write: encoder write channel %d \n",
CR_CHAN(insn->chanspec));
- // Set the preload register
+ /* Set the preload register */
Preload(dev, k, data[0]);
- // Software index pulse forces the preload register to load
- // into the counter
+ /* Software index pulse forces the preload register to load */
+ /* into the counter */
k->SetLoadTrig(dev, k, 0);
k->PulseIndex(dev, k);
k->SetLoadTrig(dev, k, 2);
@@ -2309,175 +2322,165 @@ static int s626_enc_insn_write(comedi_device * dev, comedi_subdevice * s,
return 1;
}
-static void s626_timer_load(comedi_device * dev, enc_private * k, int tick)
+static void s626_timer_load(struct comedi_device *dev, struct enc_private *k, int tick)
{
- uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | // Preload upon
- // index.
- (INDXSRC_SOFT << BF_INDXSRC) | // Disable hardware index.
- (CLKSRC_TIMER << BF_CLKSRC) | // Operating mode is Timer.
- (CLKPOL_POS << BF_CLKPOL) | // Active high clock.
- (CNTDIR_DOWN << BF_CLKPOL) | // Count direction is Down.
- (CLKMULT_1X << BF_CLKMULT) | // Clock multiplier is 1x.
+ uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */
+ /* index. */
+ (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */
+ (CLKSRC_TIMER << BF_CLKSRC) | /* Operating mode is Timer. */
+ (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */
+ (CNTDIR_DOWN << BF_CLKPOL) | /* Count direction is Down. */
+ (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */
(CLKENAB_INDEX << BF_CLKENAB);
uint16_t valueSrclatch = LATCHSRC_A_INDXA;
- // uint16_t enab=CLKENAB_ALWAYS;
+ /* uint16_t enab=CLKENAB_ALWAYS; */
k->SetMode(dev, k, Setup, FALSE);
- // Set the preload register
+ /* Set the preload register */
Preload(dev, k, tick);
- // Software index pulse forces the preload register to load
- // into the counter
+ /* Software index pulse forces the preload register to load */
+ /* into the counter */
k->SetLoadTrig(dev, k, 0);
k->PulseIndex(dev, k);
- //set reload on counter overflow
+ /* set reload on counter overflow */
k->SetLoadTrig(dev, k, 1);
- //set interrupt on overflow
+ /* set interrupt on overflow */
k->SetIntSrc(dev, k, INTSRC_OVER);
SetLatchSource(dev, k, valueSrclatch);
- // k->SetEnable(dev,k,(uint16_t)(enab != 0));
+ /* k->SetEnable(dev,k,(uint16_t)(enab != 0)); */
}
-///////////////////////////////////////////////////////////////////////
-///////////////////// DAC FUNCTIONS /////////////////////////////////
-///////////////////////////////////////////////////////////////////////
+/* *********** DAC FUNCTIONS *********** */
-// Slot 0 base settings.
-#define VECT0 ( XSD2 | RSD3 | SIB_A2 ) // Slot 0 always shifts in
- // 0xFF and store it to
- // FB_BUFFER2.
+/* Slot 0 base settings. */
+#define VECT0 (XSD2 | RSD3 | SIB_A2)
+/* Slot 0 always shifts in 0xFF and store it to FB_BUFFER2. */
-// TrimDac LogicalChan-to-PhysicalChan mapping table.
+/* TrimDac LogicalChan-to-PhysicalChan mapping table. */
static uint8_t trimchan[] = { 10, 9, 8, 3, 2, 7, 6, 1, 0, 5, 4 };
-// TrimDac LogicalChan-to-EepromAdrs mapping table.
+/* TrimDac LogicalChan-to-EepromAdrs mapping table. */
static uint8_t trimadrs[] =
{ 0x40, 0x41, 0x42, 0x50, 0x51, 0x52, 0x53, 0x60, 0x61, 0x62, 0x63 };
-static void LoadTrimDACs(comedi_device * dev)
+static void LoadTrimDACs(struct comedi_device *dev)
{
register uint8_t i;
- // Copy TrimDac setpoint values from EEPROM to TrimDacs.
+ /* Copy TrimDac setpoint values from EEPROM to TrimDacs. */
for (i = 0; i < (sizeof(trimchan) / sizeof(trimchan[0])); i++)
WriteTrimDAC(dev, i, I2Cread(dev, trimadrs[i]));
}
-static void WriteTrimDAC(comedi_device * dev, uint8_t LogicalChan,
+static void WriteTrimDAC(struct comedi_device *dev, uint8_t LogicalChan,
uint8_t DacData)
{
uint32_t chan;
- // Save the new setpoint in case the application needs to read it back later.
+ /* Save the new setpoint in case the application needs to read it back later. */
devpriv->TrimSetpoint[LogicalChan] = (uint8_t) DacData;
- // Map logical channel number to physical channel number.
+ /* Map logical channel number to physical channel number. */
chan = (uint32_t) trimchan[LogicalChan];
- // Set up TSL2 records for TrimDac write operation. All slots shift
- // 0xFF in from pulled-up SD3 so that the end of the slot sequence
- // can be detected.
- SETVECT(2, XSD2 | XFIFO_1 | WS3); // Slot 2: Send high uint8_t
- // to target TrimDac.
- SETVECT(3, XSD2 | XFIFO_0 | WS3); // Slot 3: Send low uint8_t to
- // target TrimDac.
- SETVECT(4, XSD2 | XFIFO_3 | WS1); // Slot 4: Send NOP high
- // uint8_t to DAC0 to keep
- // clock running.
- SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS); // Slot 5: Send NOP low
- // uint8_t to DAC0.
-
- // Construct and transmit target DAC's serial packet: ( 0000 AAAA
- // ),( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the DAC
- // channel's address, and D<7:0> is the DAC setpoint. Append a WORD
- // value (that writes a channel 0 NOP command to a non-existent main
- // DAC channel) that serves to keep the clock running after the
- // packet has been sent to the target DAC.
-
- SendDAC(dev, ((uint32_t) chan << 8) // Address the DAC channel
- // within the trimdac device.
- | (uint32_t) DacData); // Include DAC setpoint data.
-}
+ /* Set up TSL2 records for TrimDac write operation. All slots shift
+ * 0xFF in from pulled-up SD3 so that the end of the slot sequence
+ * can be detected.
+ */
-/////////////////////////////////////////////////////////////////////////
-//////////////// EEPROM ACCESS FUNCTIONS //////////////////////////////
-/////////////////////////////////////////////////////////////////////////
+ SETVECT(2, XSD2 | XFIFO_1 | WS3);
+ /* Slot 2: Send high uint8_t to target TrimDac. */
+ SETVECT(3, XSD2 | XFIFO_0 | WS3);
+ /* Slot 3: Send low uint8_t to target TrimDac. */
+ SETVECT(4, XSD2 | XFIFO_3 | WS1);
+ /* Slot 4: Send NOP high uint8_t to DAC0 to keep clock running. */
+ SETVECT(5, XSD2 | XFIFO_2 | WS1 | EOS);
+ /* Slot 5: Send NOP low uint8_t to DAC0. */
+
+ /* Construct and transmit target DAC's serial packet:
+ * ( 0000 AAAA ), ( DDDD DDDD ),( 0x00 ),( 0x00 ) where A<3:0> is the
+ * DAC channel's address, and D<7:0> is the DAC setpoint. Append a
+ * WORD value (that writes a channel 0 NOP command to a non-existent
+ * main DAC channel) that serves to keep the clock running after the
+ * packet has been sent to the target DAC.
+ */
+
+ /* Address the DAC channel within the trimdac device. */
+ SendDAC(dev, ((uint32_t) chan << 8)
+ | (uint32_t) DacData); /* Include DAC setpoint data. */
+}
-///////////////////////////////////////////
-// Read uint8_t from EEPROM.
+/* ************** EEPROM ACCESS FUNCTIONS ************** */
+/* Read uint8_t from EEPROM. */
-static uint8_t I2Cread(comedi_device * dev, uint8_t addr)
+static uint8_t I2Cread(struct comedi_device *dev, uint8_t addr)
{
uint8_t rtnval;
- // Send EEPROM target address.
- if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW) // Byte2 = I2C
- // command:
- // write to
- // I2C EEPROM
- // device.
- | I2C_B1(I2C_ATTRSTOP, addr) // Byte1 = EEPROM
- // internal target
- // address.
- | I2C_B0(I2C_ATTRNOP, 0))) // Byte0 = Not
- // sent.
- {
- // Abort function and declare error if handshake failed.
+ /* Send EEPROM target address. */
+ if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CW)
+ /* Byte2 = I2C command: write to I2C EEPROM device. */
+ | I2C_B1(I2C_ATTRSTOP, addr)
+ /* Byte1 = EEPROM internal target address. */
+ | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */
+ /* Abort function and declare error if handshake failed. */
DEBUG("I2Cread: error handshake I2Cread a\n");
return 0;
}
- // Execute EEPROM read.
- if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) // Byte2 = I2C
- // command: read
- // from I2C EEPROM
- // device.
- | I2C_B1(I2C_ATTRSTOP, 0) // Byte1 receives
- // uint8_t from
- // EEPROM.
- | I2C_B0(I2C_ATTRNOP, 0))) // Byte0 = Not
- // sent.
- {
- // Abort function and declare error if handshake failed.
+ /* Execute EEPROM read. */
+ if (I2Chandshake(dev, I2C_B2(I2C_ATTRSTART, I2CR) /* Byte2 = I2C */
+ /* command: read */
+ /* from I2C EEPROM */
+ /* device. */
+ | I2C_B1(I2C_ATTRSTOP, 0) /* Byte1 receives */
+ /* uint8_t from */
+ /* EEPROM. */
+ | I2C_B0(I2C_ATTRNOP, 0))) { /* Byte0 = Not sent. */
+
+ /* Abort function and declare error if handshake failed. */
DEBUG("I2Cread: error handshake I2Cread b\n");
return 0;
}
- // Return copy of EEPROM value.
+ /* Return copy of EEPROM value. */
rtnval = (uint8_t) (RR7146(P_I2CCTRL) >> 16);
return rtnval;
}
-static uint32_t I2Chandshake(comedi_device * dev, uint32_t val)
+static uint32_t I2Chandshake(struct comedi_device *dev, uint32_t val)
{
- // Write I2C command to I2C Transfer Control shadow register.
+ /* Write I2C command to I2C Transfer Control shadow register. */
WR7146(P_I2CCTRL, val);
- // Upload I2C shadow registers into working registers and wait for
- // upload confirmation.
+ /* Upload I2C shadow registers into working registers and wait for */
+ /* upload confirmation. */
MC_ENABLE(P_MC2, MC2_UPLD_IIC);
- while (!MC_TEST(P_MC2, MC2_UPLD_IIC)) ;
+ while (!MC_TEST(P_MC2, MC2_UPLD_IIC))
+ ;
- // Wait until I2C bus transfer is finished or an error occurs.
- while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY) ;
+ /* Wait until I2C bus transfer is finished or an error occurs. */
+ while ((RR7146(P_I2CCTRL) & (I2C_BUSY | I2C_ERR)) == I2C_BUSY)
+ ;
- // Return non-zero if I2C error occured.
+ /* Return non-zero if I2C error occured. */
return RR7146(P_I2CCTRL) & I2C_ERR;
}
-// Private helper function: Write setpoint to an application DAC channel.
+/* Private helper function: Write setpoint to an application DAC channel. */
-static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata)
+static void SetDAC(struct comedi_device *dev, uint16_t chan, short dacdata)
{
register uint16_t signmask;
register uint32_t WSImage;
- // Adjust DAC data polarity and set up Polarity Control Register
- // image.
+ /* Adjust DAC data polarity and set up Polarity Control Register */
+ /* image. */
signmask = 1 << chan;
if (dacdata < 0) {
dacdata = -dacdata;
@@ -2485,237 +2488,252 @@ static void SetDAC(comedi_device * dev, uint16_t chan, short dacdata)
} else
devpriv->Dacpol &= ~signmask;
- // Limit DAC setpoint value to valid range.
+ /* Limit DAC setpoint value to valid range. */
if ((uint16_t) dacdata > 0x1FFF)
dacdata = 0x1FFF;
- // Set up TSL2 records (aka "vectors") for DAC update. Vectors V2
- // and V3 transmit the setpoint to the target DAC. V4 and V5 send
- // data to a non-existent TrimDac channel just to keep the clock
- // running after sending data to the target DAC. This is necessary
- // to eliminate the clock glitch that would otherwise occur at the
- // end of the target DAC's serial data stream. When the sequence
- // restarts at V0 (after executing V5), the gate array automatically
- // disables gating for the DAC clock and all DAC chip selects.
- WSImage = (chan & 2) ? WS1 : WS2; // Choose DAC chip select to
- // be asserted.
- SETVECT(2, XSD2 | XFIFO_1 | WSImage); // Slot 2: Transmit high
- // data byte to target DAC.
- SETVECT(3, XSD2 | XFIFO_0 | WSImage); // Slot 3: Transmit low data
- // byte to target DAC.
- SETVECT(4, XSD2 | XFIFO_3 | WS3); // Slot 4: Transmit to
- // non-existent TrimDac
- // channel to keep clock
- SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS); // Slot 5: running after
- // writing target DAC's
- // low data byte.
-
- // Construct and transmit target DAC's serial packet: ( A10D DDDD
- // ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>, and D<12:0>
- // is the DAC setpoint. Append a WORD value (that writes to a
- // non-existent TrimDac channel) that serves to keep the clock
- // running after the packet has been sent to the target DAC.
- SendDAC(dev, 0x0F000000 //Continue clock after target DAC
- //data (write to non-existent
- //trimdac).
- | 0x00004000 // Address the two main dual-DAC
- // devices (TSL's chip select enables
- // target device).
- | ((uint32_t) (chan & 1) << 15) // Address the DAC
- // channel within the
- // device.
- | (uint32_t) dacdata); // Include DAC setpoint data.
+ /* Set up TSL2 records (aka "vectors") for DAC update. Vectors V2
+ * and V3 transmit the setpoint to the target DAC. V4 and V5 send
+ * data to a non-existent TrimDac channel just to keep the clock
+ * running after sending data to the target DAC. This is necessary
+ * to eliminate the clock glitch that would otherwise occur at the
+ * end of the target DAC's serial data stream. When the sequence
+ * restarts at V0 (after executing V5), the gate array automatically
+ * disables gating for the DAC clock and all DAC chip selects.
+ */
+
+ WSImage = (chan & 2) ? WS1 : WS2;
+ /* Choose DAC chip select to be asserted. */
+ SETVECT(2, XSD2 | XFIFO_1 | WSImage);
+ /* Slot 2: Transmit high data byte to target DAC. */
+ SETVECT(3, XSD2 | XFIFO_0 | WSImage);
+ /* Slot 3: Transmit low data byte to target DAC. */
+ SETVECT(4, XSD2 | XFIFO_3 | WS3);
+ /* Slot 4: Transmit to non-existent TrimDac channel to keep clock */
+ SETVECT(5, XSD2 | XFIFO_2 | WS3 | EOS);
+ /* Slot 5: running after writing target DAC's low data byte. */
+
+ /* Construct and transmit target DAC's serial packet:
+ * ( A10D DDDD ),( DDDD DDDD ),( 0x0F ),( 0x00 ) where A is chan<0>,
+ * and D<12:0> is the DAC setpoint. Append a WORD value (that writes
+ * to a non-existent TrimDac channel) that serves to keep the clock
+ * running after the packet has been sent to the target DAC.
+ */
+ SendDAC(dev, 0x0F000000
+ /* Continue clock after target DAC data (write to non-existent trimdac). */
+ | 0x00004000
+ /* Address the two main dual-DAC devices (TSL's chip select enables
+ * target device). */
+ | ((uint32_t) (chan & 1) << 15)
+ /* Address the DAC channel within the device. */
+ | (uint32_t) dacdata); /* Include DAC setpoint data. */
}
-////////////////////////////////////////////////////////
-// Private helper function: Transmit serial data to DAC via Audio
-// channel 2. Assumes: (1) TSL2 slot records initialized, and (2)
-// Dacpol contains valid target image.
+/* Private helper function: Transmit serial data to DAC via Audio
+ * channel 2. Assumes: (1) TSL2 slot records initialized, and (2)
+ * Dacpol contains valid target image.
+ */
-static void SendDAC(comedi_device * dev, uint32_t val)
+static void SendDAC(struct comedi_device *dev, uint32_t val)
{
- // START THE SERIAL CLOCK RUNNING -------------
+ /* START THE SERIAL CLOCK RUNNING ------------- */
- // Assert DAC polarity control and enable gating of DAC serial clock
- // and audio bit stream signals. At this point in time we must be
- // assured of being in time slot 0. If we are not in slot 0, the
- // serial clock and audio stream signals will be disabled; this is
- // because the following DEBIwrite statement (which enables signals
- // to be passed through the gate array) would execute before the
- // trailing edge of WS1/WS3 (which turns off the signals), thus
- // causing the signals to be inactive during the DAC write.
+ /* Assert DAC polarity control and enable gating of DAC serial clock
+ * and audio bit stream signals. At this point in time we must be
+ * assured of being in time slot 0. If we are not in slot 0, the
+ * serial clock and audio stream signals will be disabled; this is
+ * because the following DEBIwrite statement (which enables signals
+ * to be passed through the gate array) would execute before the
+ * trailing edge of WS1/WS3 (which turns off the signals), thus
+ * causing the signals to be inactive during the DAC write.
+ */
DEBIwrite(dev, LP_DACPOL, devpriv->Dacpol);
- // TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ----------------
+ /* TRANSFER OUTPUT DWORD VALUE INTO A2'S OUTPUT FIFO ---------------- */
- // Copy DAC setpoint value to DAC's output DMA buffer.
+ /* Copy DAC setpoint value to DAC's output DMA buffer. */
- //WR7146( (uint32_t)devpriv->pDacWBuf, val );
+ /* WR7146( (uint32_t)devpriv->pDacWBuf, val ); */
*devpriv->pDacWBuf = val;
- // enab the output DMA transfer. This will cause the DMAC to copy
- // the DAC's data value to A2's output FIFO. The DMA transfer will
- // then immediately terminate because the protection address is
- // reached upon transfer of the first DWORD value.
+ /* enab the output DMA transfer. This will cause the DMAC to copy
+ * the DAC's data value to A2's output FIFO. The DMA transfer will
+ * then immediately terminate because the protection address is
+ * reached upon transfer of the first DWORD value.
+ */
MC_ENABLE(P_MC1, MC1_A2OUT);
- // While the DMA transfer is executing ...
+ /* While the DMA transfer is executing ... */
- // Reset Audio2 output FIFO's underflow flag (along with any other
- // FIFO underflow/overflow flags). When set, this flag will
- // indicate that we have emerged from slot 0.
+ /* Reset Audio2 output FIFO's underflow flag (along with any other
+ * FIFO underflow/overflow flags). When set, this flag will
+ * indicate that we have emerged from slot 0.
+ */
WR7146(P_ISR, ISR_AFOU);
- // Wait for the DMA transfer to finish so that there will be data
- // available in the FIFO when time slot 1 tries to transfer a DWORD
- // from the FIFO to the output buffer register. We test for DMA
- // Done by polling the DMAC enable flag; this flag is automatically
- // cleared when the transfer has finished.
- while ((RR7146(P_MC1) & MC1_A2OUT) != 0) ;
+ /* Wait for the DMA transfer to finish so that there will be data
+ * available in the FIFO when time slot 1 tries to transfer a DWORD
+ * from the FIFO to the output buffer register. We test for DMA
+ * Done by polling the DMAC enable flag; this flag is automatically
+ * cleared when the transfer has finished.
+ */
+ while ((RR7146(P_MC1) & MC1_A2OUT) != 0)
+ ;
- // START THE OUTPUT STREAM TO THE TARGET DAC --------------------
+ /* START THE OUTPUT STREAM TO THE TARGET DAC -------------------- */
- // FIFO data is now available, so we enable execution of time slots
- // 1 and higher by clearing the EOS flag in slot 0. Note that SD3
- // will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
- // detection.
+ /* FIFO data is now available, so we enable execution of time slots
+ * 1 and higher by clearing the EOS flag in slot 0. Note that SD3
+ * will be shifted in and stored in FB_BUFFER2 for end-of-slot-list
+ * detection.
+ */
SETVECT(0, XSD2 | RSD3 | SIB_A2);
- // Wait for slot 1 to execute to ensure that the Packet will be
- // transmitted. This is detected by polling the Audio2 output FIFO
- // underflow flag, which will be set when slot 1 execution has
- // finished transferring the DAC's data DWORD from the output FIFO
- // to the output buffer register.
- while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0) ;
-
- // Set up to trap execution at slot 0 when the TSL sequencer cycles
- // back to slot 0 after executing the EOS in slot 5. Also,
- // simultaneously shift out and in the 0x00 that is ALWAYS the value
- // stored in the last byte to be shifted out of the FIFO's DWORD
- // buffer register.
+ /* Wait for slot 1 to execute to ensure that the Packet will be
+ * transmitted. This is detected by polling the Audio2 output FIFO
+ * underflow flag, which will be set when slot 1 execution has
+ * finished transferring the DAC's data DWORD from the output FIFO
+ * to the output buffer register.
+ */
+ while ((RR7146(P_SSR) & SSR_AF2_OUT) == 0)
+ ;
+
+ /* Set up to trap execution at slot 0 when the TSL sequencer cycles
+ * back to slot 0 after executing the EOS in slot 5. Also,
+ * simultaneously shift out and in the 0x00 that is ALWAYS the value
+ * stored in the last byte to be shifted out of the FIFO's DWORD
+ * buffer register.
+ */
SETVECT(0, XSD2 | XFIFO_2 | RSD2 | SIB_A2 | EOS);
- // WAIT FOR THE TRANSACTION TO FINISH -----------------------
-
- // Wait for the TSL to finish executing all time slots before
- // exiting this function. We must do this so that the next DAC
- // write doesn't start, thereby enabling clock/chip select signals:
- // 1. Before the TSL sequence cycles back to slot 0, which disables
- // the clock/cs signal gating and traps slot // list execution. If
- // we have not yet finished slot 5 then the clock/cs signals are
- // still gated and we have // not finished transmitting the stream.
- // 2. While slots 2-5 are executing due to a late slot 0 trap. In
- // this case, the slot sequence is currently // repeating, but with
- // clock/cs signals disabled. We must wait for slot 0 to trap
- // execution before setting // up the next DAC setpoint DMA transfer
- // and enabling the clock/cs signals. To detect the end of slot 5,
- // we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If
- // the TSL has not yet finished executing slot 5 ...
+ /* WAIT FOR THE TRANSACTION TO FINISH ----------------------- */
+
+ /* Wait for the TSL to finish executing all time slots before
+ * exiting this function. We must do this so that the next DAC
+ * write doesn't start, thereby enabling clock/chip select signals:
+ *
+ * 1. Before the TSL sequence cycles back to slot 0, which disables
+ * the clock/cs signal gating and traps slot // list execution.
+ * we have not yet finished slot 5 then the clock/cs signals are
+ * still gated and we have not finished transmitting the stream.
+ *
+ * 2. While slots 2-5 are executing due to a late slot 0 trap. In
+ * this case, the slot sequence is currently repeating, but with
+ * clock/cs signals disabled. We must wait for slot 0 to trap
+ * execution before setting up the next DAC setpoint DMA transfer
+ * and enabling the clock/cs signals. To detect the end of slot 5,
+ * we test for the FB_BUFFER2 MSB contents to be equal to 0xFF. If
+ * the TSL has not yet finished executing slot 5 ...
+ */
if ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) {
- // The trap was set on time and we are still executing somewhere
- // in slots 2-5, so we now wait for slot 0 to execute and trap
- // TSL execution. This is detected when FB_BUFFER2 MSB changes
- // from 0xFF to 0x00, which slot 0 causes to happen by shifting
- // out/in on SD2 the 0x00 that is always referenced by slot 5.
- while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0) ;
+ /* The trap was set on time and we are still executing somewhere
+ * in slots 2-5, so we now wait for slot 0 to execute and trap
+ * TSL execution. This is detected when FB_BUFFER2 MSB changes
+ * from 0xFF to 0x00, which slot 0 causes to happen by shifting
+ * out/in on SD2 the 0x00 that is always referenced by slot 5.
+ */
+ while ((RR7146(P_FB_BUFFER2) & 0xFF000000) != 0)
+ ;
}
- // Either (1) we were too late setting the slot 0 trap; the TSL
- // sequencer restarted slot 0 before we could set the EOS trap flag,
- // or (2) we were not late and execution is now trapped at slot 0.
- // In either case, we must now change slot 0 so that it will store
- // value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
- // In order to do this, we reprogram slot 0 so that it will shift in
- // SD3, which is driven only by a pull-up resistor.
+ /* Either (1) we were too late setting the slot 0 trap; the TSL
+ * sequencer restarted slot 0 before we could set the EOS trap flag,
+ * or (2) we were not late and execution is now trapped at slot 0.
+ * In either case, we must now change slot 0 so that it will store
+ * value 0xFF (instead of 0x00) to FB_BUFFER2 next time it executes.
+ * In order to do this, we reprogram slot 0 so that it will shift in
+ * SD3, which is driven only by a pull-up resistor.
+ */
SETVECT(0, RSD3 | SIB_A2 | EOS);
- // Wait for slot 0 to execute, at which time the TSL is setup for
- // the next DAC write. This is detected when FB_BUFFER2 MSB changes
- // from 0x00 to 0xFF.
- while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0) ;
+ /* Wait for slot 0 to execute, at which time the TSL is setup for
+ * the next DAC write. This is detected when FB_BUFFER2 MSB changes
+ * from 0x00 to 0xFF.
+ */
+ while ((RR7146(P_FB_BUFFER2) & 0xFF000000) == 0)
+ ;
}
-static void WriteMISC2(comedi_device * dev, uint16_t NewImage)
+static void WriteMISC2(struct comedi_device *dev, uint16_t NewImage)
{
- DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); // enab writes to
- // MISC2 register.
- DEBIwrite(dev, LP_WRMISC2, NewImage); // Write new image to MISC2.
- DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE); // Disable writes to MISC2.
+ DEBIwrite(dev, LP_MISC1, MISC1_WENABLE); /* enab writes to */
+ /* MISC2 register. */
+ DEBIwrite(dev, LP_WRMISC2, NewImage); /* Write new image to MISC2. */
+ DEBIwrite(dev, LP_MISC1, MISC1_WDISABLE); /* Disable writes to MISC2. */
}
-/////////////////////////////////////////////////////////////////////
-// Initialize the DEBI interface for all transfers.
+/* Initialize the DEBI interface for all transfers. */
-static uint16_t DEBIread(comedi_device * dev, uint16_t addr)
+static uint16_t DEBIread(struct comedi_device *dev, uint16_t addr)
{
uint16_t retval;
- // Set up DEBI control register value in shadow RAM.
+ /* Set up DEBI control register value in shadow RAM. */
WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
- // Execute the DEBI transfer.
+ /* Execute the DEBI transfer. */
DEBItransfer(dev);
- // Fetch target register value.
+ /* Fetch target register value. */
retval = (uint16_t) RR7146(P_DEBIAD);
- // Return register value.
+ /* Return register value. */
return retval;
}
-// Execute a DEBI transfer. This must be called from within a
-// critical section.
-static void DEBItransfer(comedi_device * dev)
+/* Execute a DEBI transfer. This must be called from within a */
+/* critical section. */
+static void DEBItransfer(struct comedi_device *dev)
{
- // Initiate upload of shadow RAM to DEBI control register.
+ /* Initiate upload of shadow RAM to DEBI control register. */
MC_ENABLE(P_MC2, MC2_UPLD_DEBI);
- // Wait for completion of upload from shadow RAM to DEBI control
- // register.
- while (!MC_TEST(P_MC2, MC2_UPLD_DEBI)) ;
+ /* Wait for completion of upload from shadow RAM to DEBI control */
+ /* register. */
+ while (!MC_TEST(P_MC2, MC2_UPLD_DEBI))
+ ;
- // Wait until DEBI transfer is done.
- while (RR7146(P_PSR) & PSR_DEBI_S) ;
+ /* Wait until DEBI transfer is done. */
+ while (RR7146(P_PSR) & PSR_DEBI_S)
+ ;
}
-// Write a value to a gate array register.
-static void DEBIwrite(comedi_device * dev, uint16_t addr, uint16_t wdata)
+/* Write a value to a gate array register. */
+static void DEBIwrite(struct comedi_device *dev, uint16_t addr, uint16_t wdata)
{
- // Set up DEBI control register value in shadow RAM.
+ /* Set up DEBI control register value in shadow RAM. */
WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
WR7146(P_DEBIAD, wdata);
- // Execute the DEBI transfer.
+ /* Execute the DEBI transfer. */
DEBItransfer(dev);
}
-/////////////////////////////////////////////////////////////////////////////
-// Replace the specified bits in a gate array register. Imports: mask
-// specifies bits that are to be preserved, wdata is new value to be
-// or'd with the masked original.
-static void DEBIreplace(comedi_device * dev, uint16_t addr, uint16_t mask,
+/* Replace the specified bits in a gate array register. Imports: mask
+ * specifies bits that are to be preserved, wdata is new value to be
+ * or'd with the masked original.
+ */
+static void DEBIreplace(struct comedi_device *dev, uint16_t addr, uint16_t mask,
uint16_t wdata)
{
- // Copy target gate array register into P_DEBIAD register.
- WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr); // Set up DEBI control
- // reg value in shadow
- // RAM.
- DEBItransfer(dev); // Execute the DEBI
- // Read transfer.
+ /* Copy target gate array register into P_DEBIAD register. */
+ WR7146(P_DEBICMD, DEBI_CMD_RDWORD | addr);
+ /* Set up DEBI control reg value in shadow RAM. */
+ DEBItransfer(dev); /* Execute the DEBI Read transfer. */
- // Write back the modified image.
- WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr); // Set up DEBI control
- // reg value in shadow
- // RAM.
+ /* Write back the modified image. */
+ WR7146(P_DEBICMD, DEBI_CMD_WRWORD | addr);
+ /* Set up DEBI control reg value in shadow RAM. */
- WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask)); // Modify the register image.
- DEBItransfer(dev); // Execute the DEBI Write transfer.
+ WR7146(P_DEBIAD, wdata | ((uint16_t) RR7146(P_DEBIAD) & mask));
+ /* Modify the register image. */
+ DEBItransfer(dev); /* Execute the DEBI Write transfer. */
}
-static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize)
+static void CloseDMAB(struct comedi_device *dev, struct bufferDMA *pdma, size_t bsize)
{
void *vbptr;
dma_addr_t vpptr;
@@ -2723,7 +2741,7 @@ static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize)
DEBUG("CloseDMAB: Entering S626DRV_CloseDMAB():\n");
if (pdma == NULL)
return;
- //find the matching allocation from the board struct
+ /* find the matching allocation from the board struct */
vbptr = pdma->LogicalBase;
vpptr = pdma->PhysicalBase;
@@ -2737,268 +2755,260 @@ static void CloseDMAB(comedi_device * dev, DMABUF * pdma, size_t bsize)
}
}
-////////////////////////////////////////////////////////////////////////
-///////////////// COUNTER FUNCTIONS //////////////////////////////////
-////////////////////////////////////////////////////////////////////////
-// All counter functions address a specific counter by means of the
-// "Counter" argument, which is a logical counter number. The Counter
-// argument may have any of the following legal values: 0=0A, 1=1A,
-// 2=2A, 3=0B, 4=1B, 5=2B.
-////////////////////////////////////////////////////////////////////////
+/* ****** COUNTER FUNCTIONS ******* */
+/* All counter functions address a specific counter by means of the
+ * "Counter" argument, which is a logical counter number. The Counter
+ * argument may have any of the following legal values: 0=0A, 1=1A,
+ * 2=2A, 3=0B, 4=1B, 5=2B.
+ */
-// Forward declarations for functions that are common to both A and B
-// counters:
+/* Forward declarations for functions that are common to both A and B counters: */
-/////////////////////////////////////////////////////////////////////
-//////////////////// PRIVATE COUNTER FUNCTIONS /////////////////////
-/////////////////////////////////////////////////////////////////////
+/* ****** PRIVATE COUNTER FUNCTIONS ****** */
-/////////////////////////////////////////////////////////////////
-// Read a counter's output latch.
+/* Read a counter's output latch. */
-static uint32_t ReadLatch(comedi_device * dev, enc_private * k)
+static uint32_t ReadLatch(struct comedi_device *dev, struct enc_private *k)
{
register uint32_t value;
- //DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n");
+ /* DEBUG FIXME DEBUG("ReadLatch: Read Latch enter\n"); */
- // Latch counts and fetch LSW of latched counts value.
+ /* Latch counts and fetch LSW of latched counts value. */
value = (uint32_t) DEBIread(dev, k->MyLatchLsw);
- // Fetch MSW of latched counts and combine with LSW.
+ /* Fetch MSW of latched counts and combine with LSW. */
value |= ((uint32_t) DEBIread(dev, k->MyLatchLsw + 2) << 16);
- // DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n");
+ /* DEBUG FIXME DEBUG("ReadLatch: Read Latch exit\n"); */
- // Return latched counts.
+ /* Return latched counts. */
return value;
}
-///////////////////////////////////////////////////////////////////
-// Reset a counter's index and overflow event capture flags.
+/* Reset a counter's index and overflow event capture flags. */
-static void ResetCapFlags_A(comedi_device * dev, enc_private * k)
+static void ResetCapFlags_A(struct comedi_device *dev, struct enc_private *k)
{
DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
}
-static void ResetCapFlags_B(comedi_device * dev, enc_private * k)
+static void ResetCapFlags_B(struct comedi_device *dev, struct enc_private *k)
{
DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B);
}
-/////////////////////////////////////////////////////////////////////////
-// Return counter setup in a format (COUNTER_SETUP) that is consistent
-// for both A and B counters.
+/* Return counter setup in a format (COUNTER_SETUP) that is consistent */
+/* for both A and B counters. */
-static uint16_t GetMode_A(comedi_device * dev, enc_private * k)
+static uint16_t GetMode_A(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t cra;
register uint16_t crb;
register uint16_t setup;
- // Fetch CRA and CRB register images.
+ /* Fetch CRA and CRB register images. */
cra = DEBIread(dev, k->MyCRA);
crb = DEBIread(dev, k->MyCRB);
- // Populate the standardized counter setup bit fields. Note:
- // IndexSrc is restricted to ENC_X or IndxPol.
- setup = ((cra & STDMSK_LOADSRC) // LoadSrc = LoadSrcA.
- | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) // LatchSrc = LatchSrcA.
- | ((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC) // IntSrc = IntSrcA.
- | ((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) // IndxSrc = IndxSrcA<1>.
- | ((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL) // IndxPol = IndxPolA.
- | ((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB)); // ClkEnab = ClkEnabA.
-
- // Adjust mode-dependent parameters.
- if (cra & (2 << CRABIT_CLKSRC_A)) // If Timer mode (ClkSrcA<1> == 1):
- setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) // Indicate Timer mode.
- | ((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) // Set ClkPol to indicate count direction (ClkSrcA<0>).
- | (MULT_X1 << STDBIT_CLKMULT)); // ClkMult must be 1x in Timer mode.
-
- else // If Counter mode (ClkSrcA<1> == 0):
- setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) // Indicate Counter mode.
- | ((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) // Pass through ClkPol.
- | (((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ? // Force ClkMult to 1x if not legal, else pass through.
+ /* Populate the standardized counter setup bit fields. Note: */
+ /* IndexSrc is restricted to ENC_X or IndxPol. */
+ setup = ((cra & STDMSK_LOADSRC) /* LoadSrc = LoadSrcA. */
+ | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcA. */
+ | ((cra << (STDBIT_INTSRC - CRABIT_INTSRC_A)) & STDMSK_INTSRC) /* IntSrc = IntSrcA. */
+ | ((cra << (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1))) & STDMSK_INDXSRC) /* IndxSrc = IndxSrcA<1>. */
+ | ((cra >> (CRABIT_INDXPOL_A - STDBIT_INDXPOL)) & STDMSK_INDXPOL) /* IndxPol = IndxPolA. */
+ | ((crb >> (CRBBIT_CLKENAB_A - STDBIT_CLKENAB)) & STDMSK_CLKENAB)); /* ClkEnab = ClkEnabA. */
+
+ /* Adjust mode-dependent parameters. */
+ if (cra & (2 << CRABIT_CLKSRC_A)) /* If Timer mode (ClkSrcA<1> == 1): */
+ setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */
+ | ((cra << (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) & STDMSK_CLKPOL) /* Set ClkPol to indicate count direction (ClkSrcA<0>). */
+ | (MULT_X1 << STDBIT_CLKMULT)); /* ClkMult must be 1x in Timer mode. */
+
+ else /* If Counter mode (ClkSrcA<1> == 0): */
+ setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Counter mode. */
+ | ((cra >> (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) & STDMSK_CLKPOL) /* Pass through ClkPol. */
+ | (((cra & CRAMSK_CLKMULT_A) == (MULT_X0 << CRABIT_CLKMULT_A)) ? /* Force ClkMult to 1x if not legal, else pass through. */
(MULT_X1 << STDBIT_CLKMULT) :
((cra >> (CRABIT_CLKMULT_A -
STDBIT_CLKMULT)) &
STDMSK_CLKMULT)));
- // Return adjusted counter setup.
+ /* Return adjusted counter setup. */
return setup;
}
-static uint16_t GetMode_B(comedi_device * dev, enc_private * k)
+static uint16_t GetMode_B(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t cra;
register uint16_t crb;
register uint16_t setup;
- // Fetch CRA and CRB register images.
+ /* Fetch CRA and CRB register images. */
cra = DEBIread(dev, k->MyCRA);
crb = DEBIread(dev, k->MyCRB);
- // Populate the standardized counter setup bit fields. Note:
- // IndexSrc is restricted to ENC_X or IndxPol.
- setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC) // IntSrc = IntSrcB.
- | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) // LatchSrc = LatchSrcB.
- | ((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC) // LoadSrc = LoadSrcB.
- | ((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL) // IndxPol = IndxPolB.
- | ((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB) // ClkEnab = ClkEnabB.
- | ((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC)); // IndxSrc = IndxSrcB<1>.
-
- // Adjust mode-dependent parameters.
- if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B)) // If Extender mode (ClkMultB == MULT_X0):
- setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC) // Indicate Extender mode.
- | (MULT_X1 << STDBIT_CLKMULT) // Indicate multiplier is 1x.
- | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); // Set ClkPol equal to Timer count direction (ClkSrcB<0>).
-
- else if (cra & (2 << CRABIT_CLKSRC_B)) // If Timer mode (ClkSrcB<1> == 1):
- setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) // Indicate Timer mode.
- | (MULT_X1 << STDBIT_CLKMULT) // Indicate multiplier is 1x.
- | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); // Set ClkPol equal to Timer count direction (ClkSrcB<0>).
-
- else // If Counter mode (ClkSrcB<1> == 0):
- setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) // Indicate Timer mode.
- | ((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT) // Clock multiplier is passed through.
- | ((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL)); // Clock polarity is passed through.
-
- // Return adjusted counter setup.
+ /* Populate the standardized counter setup bit fields. Note: */
+ /* IndexSrc is restricted to ENC_X or IndxPol. */
+ setup = (((crb << (STDBIT_INTSRC - CRBBIT_INTSRC_B)) & STDMSK_INTSRC) /* IntSrc = IntSrcB. */
+ | ((crb << (STDBIT_LATCHSRC - CRBBIT_LATCHSRC)) & STDMSK_LATCHSRC) /* LatchSrc = LatchSrcB. */
+ | ((crb << (STDBIT_LOADSRC - CRBBIT_LOADSRC_B)) & STDMSK_LOADSRC) /* LoadSrc = LoadSrcB. */
+ | ((crb << (STDBIT_INDXPOL - CRBBIT_INDXPOL_B)) & STDMSK_INDXPOL) /* IndxPol = IndxPolB. */
+ | ((crb >> (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) & STDMSK_CLKENAB) /* ClkEnab = ClkEnabB. */
+ | ((cra >> ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)) & STDMSK_INDXSRC)); /* IndxSrc = IndxSrcB<1>. */
+
+ /* Adjust mode-dependent parameters. */
+ if ((crb & CRBMSK_CLKMULT_B) == (MULT_X0 << CRBBIT_CLKMULT_B)) /* If Extender mode (ClkMultB == MULT_X0): */
+ setup |= ((CLKSRC_EXTENDER << STDBIT_CLKSRC) /* Indicate Extender mode. */
+ | (MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */
+ | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
+
+ else if (cra & (2 << CRABIT_CLKSRC_B)) /* If Timer mode (ClkSrcB<1> == 1): */
+ setup |= ((CLKSRC_TIMER << STDBIT_CLKSRC) /* Indicate Timer mode. */
+ | (MULT_X1 << STDBIT_CLKMULT) /* Indicate multiplier is 1x. */
+ | ((cra >> (CRABIT_CLKSRC_B - STDBIT_CLKPOL)) & STDMSK_CLKPOL)); /* Set ClkPol equal to Timer count direction (ClkSrcB<0>). */
+
+ else /* If Counter mode (ClkSrcB<1> == 0): */
+ setup |= ((CLKSRC_COUNTER << STDBIT_CLKSRC) /* Indicate Timer mode. */
+ | ((crb >> (CRBBIT_CLKMULT_B - STDBIT_CLKMULT)) & STDMSK_CLKMULT) /* Clock multiplier is passed through. */
+ | ((crb << (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) & STDMSK_CLKPOL)); /* Clock polarity is passed through. */
+
+ /* Return adjusted counter setup. */
return setup;
}
-/////////////////////////////////////////////////////////////////////////////////////////////
-// Set the operating mode for the specified counter. The setup
-// parameter is treated as a COUNTER_SETUP data type. The following
-// parameters are programmable (all other parms are ignored): ClkMult,
-// ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+/*
+ * Set the operating mode for the specified counter. The setup
+ * parameter is treated as a COUNTER_SETUP data type. The following
+ * parameters are programmable (all other parms are ignored): ClkMult,
+ * ClkPol, ClkEnab, IndexSrc, IndexPol, LoadSrc.
+ */
-static void SetMode_A(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_A(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc)
{
register uint16_t cra;
register uint16_t crb;
- register uint16_t setup = Setup; // Cache the Standard Setup.
+ register uint16_t setup = Setup; /* Cache the Standard Setup. */
- // Initialize CRA and CRB images.
- cra = ((setup & CRAMSK_LOADSRC_A) // Preload trigger is passed through.
- | ((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1)))); // IndexSrc is restricted to ENC_X or IndxPol.
+ /* Initialize CRA and CRB images. */
+ cra = ((setup & CRAMSK_LOADSRC_A) /* Preload trigger is passed through. */
+ | ((setup & STDMSK_INDXSRC) >> (STDBIT_INDXSRC - (CRABIT_INDXSRC_A + 1)))); /* IndexSrc is restricted to ENC_X or IndxPol. */
- crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A // Reset any pending CounterA event captures.
- | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB))); // Clock enable is passed through.
+ crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A /* Reset any pending CounterA event captures. */
+ | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_A - STDBIT_CLKENAB))); /* Clock enable is passed through. */
- // Force IntSrc to Disabled if DisableIntSrc is asserted.
+ /* Force IntSrc to Disabled if DisableIntSrc is asserted. */
if (!DisableIntSrc)
cra |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
CRABIT_INTSRC_A));
- // Populate all mode-dependent attributes of CRA & CRB images.
+ /* Populate all mode-dependent attributes of CRA & CRB images. */
switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
- case CLKSRC_EXTENDER: // Extender Mode: Force to Timer mode
- // (Extender valid only for B counters).
-
- case CLKSRC_TIMER: // Timer Mode:
- cra |= ((2 << CRABIT_CLKSRC_A) // ClkSrcA<1> selects system clock
- | ((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) // with count direction (ClkSrcA<0>) obtained from ClkPol.
- | (1 << CRABIT_CLKPOL_A) // ClkPolA behaves as always-on clock enable.
- | (MULT_X1 << CRABIT_CLKMULT_A)); // ClkMult must be 1x.
+ case CLKSRC_EXTENDER: /* Extender Mode: Force to Timer mode */
+ /* (Extender valid only for B counters). */
+
+ case CLKSRC_TIMER: /* Timer Mode: */
+ cra |= ((2 << CRABIT_CLKSRC_A) /* ClkSrcA<1> selects system clock */
+ | ((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRABIT_CLKSRC_A)) /* with count direction (ClkSrcA<0>) obtained from ClkPol. */
+ | (1 << CRABIT_CLKPOL_A) /* ClkPolA behaves as always-on clock enable. */
+ | (MULT_X1 << CRABIT_CLKMULT_A)); /* ClkMult must be 1x. */
break;
- default: // Counter Mode:
- cra |= (CLKSRC_COUNTER // Select ENC_C and ENC_D as clock/direction inputs.
- | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) // Clock polarity is passed through.
- | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? // Force multiplier to x1 if not legal, otherwise pass through.
+ default: /* Counter Mode: */
+ cra |= (CLKSRC_COUNTER /* Select ENC_C and ENC_D as clock/direction inputs. */
+ | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKPOL_A - STDBIT_CLKPOL)) /* Clock polarity is passed through. */
+ | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force multiplier to x1 if not legal, otherwise pass through. */
(MULT_X1 << CRABIT_CLKMULT_A) :
((setup & STDMSK_CLKMULT) << (CRABIT_CLKMULT_A -
STDBIT_CLKMULT))));
}
- // Force positive index polarity if IndxSrc is software-driven only,
- // otherwise pass it through.
+ /* Force positive index polarity if IndxSrc is software-driven only, */
+ /* otherwise pass it through. */
if (~setup & STDMSK_INDXSRC)
cra |= ((setup & STDMSK_INDXPOL) << (CRABIT_INDXPOL_A -
STDBIT_INDXPOL));
- // If IntSrc has been forced to Disabled, update the MISC2 interrupt
- // enable mask to indicate the counter interrupt is disabled.
+ /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */
+ /* enable mask to indicate the counter interrupt is disabled. */
if (DisableIntSrc)
devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
- // While retaining CounterB and LatchSrc configurations, program the
- // new counter operating mode.
+ /* While retaining CounterB and LatchSrc configurations, program the */
+ /* new counter operating mode. */
DEBIreplace(dev, k->MyCRA, CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B, cra);
DEBIreplace(dev, k->MyCRB,
(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_A)), crb);
}
-static void SetMode_B(comedi_device * dev, enc_private * k, uint16_t Setup,
+static void SetMode_B(struct comedi_device *dev, struct enc_private *k, uint16_t Setup,
uint16_t DisableIntSrc)
{
register uint16_t cra;
register uint16_t crb;
- register uint16_t setup = Setup; // Cache the Standard Setup.
+ register uint16_t setup = Setup; /* Cache the Standard Setup. */
- // Initialize CRA and CRB images.
- cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)); // IndexSrc field is restricted to ENC_X or IndxPol.
+ /* Initialize CRA and CRB images. */
+ cra = ((setup & STDMSK_INDXSRC) << ((CRABIT_INDXSRC_B + 1) - STDBIT_INDXSRC)); /* IndexSrc field is restricted to ENC_X or IndxPol. */
- crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B // Reset event captures and disable interrupts.
- | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) // Clock enable is passed through.
- | ((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B))); // Preload trigger source is passed through.
+ crb = (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B /* Reset event captures and disable interrupts. */
+ | ((setup & STDMSK_CLKENAB) << (CRBBIT_CLKENAB_B - STDBIT_CLKENAB)) /* Clock enable is passed through. */
+ | ((setup & STDMSK_LOADSRC) >> (STDBIT_LOADSRC - CRBBIT_LOADSRC_B))); /* Preload trigger source is passed through. */
- // Force IntSrc to Disabled if DisableIntSrc is asserted.
+ /* Force IntSrc to Disabled if DisableIntSrc is asserted. */
if (!DisableIntSrc)
crb |= ((setup & STDMSK_INTSRC) >> (STDBIT_INTSRC -
CRBBIT_INTSRC_B));
- // Populate all mode-dependent attributes of CRA & CRB images.
+ /* Populate all mode-dependent attributes of CRA & CRB images. */
switch ((setup & STDMSK_CLKSRC) >> STDBIT_CLKSRC) {
- case CLKSRC_TIMER: // Timer Mode:
- cra |= ((2 << CRABIT_CLKSRC_B) // ClkSrcB<1> selects system clock
- | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); // with direction (ClkSrcB<0>) obtained from ClkPol.
- crb |= ((1 << CRBBIT_CLKPOL_B) // ClkPolB behaves as always-on clock enable.
- | (MULT_X1 << CRBBIT_CLKMULT_B)); // ClkMultB must be 1x.
+ case CLKSRC_TIMER: /* Timer Mode: */
+ cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB<1> selects system clock */
+ | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction (ClkSrcB<0>) obtained from ClkPol. */
+ crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB behaves as always-on clock enable. */
+ | (MULT_X1 << CRBBIT_CLKMULT_B)); /* ClkMultB must be 1x. */
break;
- case CLKSRC_EXTENDER: // Extender Mode:
- cra |= ((2 << CRABIT_CLKSRC_B) // ClkSrcB source is OverflowA (same as "timer")
- | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); // with direction obtained from ClkPol.
- crb |= ((1 << CRBBIT_CLKPOL_B) // ClkPolB controls IndexB -- always set to active.
- | (MULT_X0 << CRBBIT_CLKMULT_B)); // ClkMultB selects OverflowA as the clock source.
+ case CLKSRC_EXTENDER: /* Extender Mode: */
+ cra |= ((2 << CRABIT_CLKSRC_B) /* ClkSrcB source is OverflowA (same as "timer") */
+ | ((setup & STDMSK_CLKPOL) << (CRABIT_CLKSRC_B - STDBIT_CLKPOL))); /* with direction obtained from ClkPol. */
+ crb |= ((1 << CRBBIT_CLKPOL_B) /* ClkPolB controls IndexB -- always set to active. */
+ | (MULT_X0 << CRBBIT_CLKMULT_B)); /* ClkMultB selects OverflowA as the clock source. */
break;
- default: // Counter Mode:
- cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B); // Select ENC_C and ENC_D as clock/direction inputs.
- crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) // ClkPol is passed through.
- | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? // Force ClkMult to x1 if not legal, otherwise pass through.
+ default: /* Counter Mode: */
+ cra |= (CLKSRC_COUNTER << CRABIT_CLKSRC_B); /* Select ENC_C and ENC_D as clock/direction inputs. */
+ crb |= (((setup & STDMSK_CLKPOL) >> (STDBIT_CLKPOL - CRBBIT_CLKPOL_B)) /* ClkPol is passed through. */
+ | (((setup & STDMSK_CLKMULT) == (MULT_X0 << STDBIT_CLKMULT)) ? /* Force ClkMult to x1 if not legal, otherwise pass through. */
(MULT_X1 << CRBBIT_CLKMULT_B) :
((setup & STDMSK_CLKMULT) << (CRBBIT_CLKMULT_B -
STDBIT_CLKMULT))));
}
- // Force positive index polarity if IndxSrc is software-driven only,
- // otherwise pass it through.
+ /* Force positive index polarity if IndxSrc is software-driven only, */
+ /* otherwise pass it through. */
if (~setup & STDMSK_INDXSRC)
crb |= ((setup & STDMSK_INDXPOL) >> (STDBIT_INDXPOL -
CRBBIT_INDXPOL_B));
- // If IntSrc has been forced to Disabled, update the MISC2 interrupt
- // enable mask to indicate the counter interrupt is disabled.
+ /* If IntSrc has been forced to Disabled, update the MISC2 interrupt */
+ /* enable mask to indicate the counter interrupt is disabled. */
if (DisableIntSrc)
devpriv->CounterIntEnabs &= ~k->MyEventBits[3];
- // While retaining CounterA and LatchSrc configurations, program the
- // new counter operating mode.
+ /* While retaining CounterA and LatchSrc configurations, program the */
+ /* new counter operating mode. */
DEBIreplace(dev, k->MyCRA,
(uint16_t) (~(CRAMSK_INDXSRC_B | CRAMSK_CLKSRC_B)), cra);
DEBIreplace(dev, k->MyCRB, CRBMSK_CLKENAB_A | CRBMSK_LATCHSRC, crb);
}
-////////////////////////////////////////////////////////////////////////
-// Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index.
+/* Return/set a counter's enable. enab: 0=always enabled, 1=enabled by index. */
-static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab)
+static void SetEnable_A(struct comedi_device *dev, struct enc_private *k, uint16_t enab)
{
DEBUG("SetEnable_A: SetEnable_A enter 3541\n");
DEBIreplace(dev, k->MyCRB,
@@ -3006,29 +3016,29 @@ static void SetEnable_A(comedi_device * dev, enc_private * k, uint16_t enab)
(uint16_t) (enab << CRBBIT_CLKENAB_A));
}
-static void SetEnable_B(comedi_device * dev, enc_private * k, uint16_t enab)
+static void SetEnable_B(struct comedi_device *dev, struct enc_private *k, uint16_t enab)
{
DEBIreplace(dev, k->MyCRB,
(uint16_t) (~(CRBMSK_INTCTRL | CRBMSK_CLKENAB_B)),
(uint16_t) (enab << CRBBIT_CLKENAB_B));
}
-static uint16_t GetEnable_A(comedi_device * dev, enc_private * k)
+static uint16_t GetEnable_A(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_A) & 1;
}
-static uint16_t GetEnable_B(comedi_device * dev, enc_private * k)
+static uint16_t GetEnable_B(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_CLKENAB_B) & 1;
}
-////////////////////////////////////////////////////////////////////////
-// Return/set a counter pair's latch trigger source. 0: On read
-// access, 1: A index latches A, 2: B index latches B, 3: A overflow
-// latches B.
+/* Return/set a counter pair's latch trigger source. 0: On read
+ * access, 1: A index latches A, 2: B index latches B, 3: A overflow
+ * latches B.
+ */
-static void SetLatchSource(comedi_device * dev, enc_private * k, uint16_t value)
+static void SetLatchSource(struct comedi_device *dev, struct enc_private *k, uint16_t value)
{
DEBUG("SetLatchSource: SetLatchSource enter 3550 \n");
DEBIreplace(dev, k->MyCRB,
@@ -3038,210 +3048,206 @@ static void SetLatchSource(comedi_device * dev, enc_private * k, uint16_t value)
DEBUG("SetLatchSource: SetLatchSource exit \n");
}
-/* static uint16_t GetLatchSource(comedi_device *dev, enc_private *k ) */
-/* { */
-/* return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3; */
-/* } */
+/*
+ * static uint16_t GetLatchSource(struct comedi_device *dev, struct enc_private *k )
+ * {
+ * return ( DEBIread( dev, k->MyCRB) >> CRBBIT_LATCHSRC ) & 3;
+ * }
+ */
-/////////////////////////////////////////////////////////////////////////
-// Return/set the event that will trigger transfer of the preload
-// register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
-// 2=OverflowA (B counters only), 3=disabled.
+/*
+ * Return/set the event that will trigger transfer of the preload
+ * register into the counter. 0=ThisCntr_Index, 1=ThisCntr_Overflow,
+ * 2=OverflowA (B counters only), 3=disabled.
+ */
-static void SetLoadTrig_A(comedi_device * dev, enc_private * k, uint16_t Trig)
+static void SetLoadTrig_A(struct comedi_device *dev, struct enc_private *k, uint16_t Trig)
{
DEBIreplace(dev, k->MyCRA, (uint16_t) (~CRAMSK_LOADSRC_A),
(uint16_t) (Trig << CRABIT_LOADSRC_A));
}
-static void SetLoadTrig_B(comedi_device * dev, enc_private * k, uint16_t Trig)
+static void SetLoadTrig_B(struct comedi_device *dev, struct enc_private *k, uint16_t Trig)
{
DEBIreplace(dev, k->MyCRB,
(uint16_t) (~(CRBMSK_LOADSRC_B | CRBMSK_INTCTRL)),
(uint16_t) (Trig << CRBBIT_LOADSRC_B));
}
-static uint16_t GetLoadTrig_A(comedi_device * dev, enc_private * k)
+static uint16_t GetLoadTrig_A(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRA) >> CRABIT_LOADSRC_A) & 3;
}
-static uint16_t GetLoadTrig_B(comedi_device * dev, enc_private * k)
+static uint16_t GetLoadTrig_B(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_LOADSRC_B) & 3;
}
-////////////////////
-// Return/set counter interrupt source and clear any captured
-// index/overflow events. IntSource: 0=Disabled, 1=OverflowOnly,
-// 2=IndexOnly, 3=IndexAndOverflow.
+/* Return/set counter interrupt source and clear any captured
+ * index/overflow events. IntSource: 0=Disabled, 1=OverflowOnly,
+ * 2=IndexOnly, 3=IndexAndOverflow.
+ */
-static void SetIntSrc_A(comedi_device * dev, enc_private * k,
+static void SetIntSrc_A(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource)
{
- // Reset any pending counter overflow or index captures.
+ /* Reset any pending counter overflow or index captures. */
DEBIreplace(dev, k->MyCRB, (uint16_t) (~CRBMSK_INTCTRL),
CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A);
- // Program counter interrupt source.
+ /* Program counter interrupt source. */
DEBIreplace(dev, k->MyCRA, ~CRAMSK_INTSRC_A,
(uint16_t) (IntSource << CRABIT_INTSRC_A));
- // Update MISC2 interrupt enable mask.
+ /* Update MISC2 interrupt enable mask. */
devpriv->CounterIntEnabs =
(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
MyEventBits[IntSource];
}
-static void SetIntSrc_B(comedi_device * dev, enc_private * k,
+static void SetIntSrc_B(struct comedi_device *dev, struct enc_private *k,
uint16_t IntSource)
{
uint16_t crb;
- // Cache writeable CRB register image.
+ /* Cache writeable CRB register image. */
crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL;
- // Reset any pending counter overflow or index captures.
+ /* Reset any pending counter overflow or index captures. */
DEBIwrite(dev, k->MyCRB,
(uint16_t) (crb | CRBMSK_INTRESETCMD | CRBMSK_INTRESET_B));
- // Program counter interrupt source.
+ /* Program counter interrupt source. */
DEBIwrite(dev, k->MyCRB,
(uint16_t) ((crb & ~CRBMSK_INTSRC_B) | (IntSource <<
CRBBIT_INTSRC_B)));
- // Update MISC2 interrupt enable mask.
+ /* Update MISC2 interrupt enable mask. */
devpriv->CounterIntEnabs =
(devpriv->CounterIntEnabs & ~k->MyEventBits[3]) | k->
MyEventBits[IntSource];
}
-static uint16_t GetIntSrc_A(comedi_device * dev, enc_private * k)
+static uint16_t GetIntSrc_A(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRA) >> CRABIT_INTSRC_A) & 3;
}
-static uint16_t GetIntSrc_B(comedi_device * dev, enc_private * k)
+static uint16_t GetIntSrc_B(struct comedi_device *dev, struct enc_private *k)
{
return (DEBIread(dev, k->MyCRB) >> CRBBIT_INTSRC_B) & 3;
}
-/////////////////////////////////////////////////////////////////////////
-// Return/set the clock multiplier.
+/* Return/set the clock multiplier. */
-/* static void SetClkMult(comedi_device *dev, enc_private *k, uint16_t value ) */
+/* static void SetClkMult(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKMULT ) | ( value << STDBIT_CLKMULT ) ), FALSE ); */
/* } */
-/* static uint16_t GetClkMult(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetClkMult(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_CLKMULT ) & 3; */
/* } */
-/* ////////////////////////////////////////////////////////////////////////// */
-/* // Return/set the clock polarity. */
+/* Return/set the clock polarity. */
-/* static void SetClkPol( comedi_device *dev,enc_private *k, uint16_t value ) */
+/* static void SetClkPol( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKPOL ) | ( value << STDBIT_CLKPOL ) ), FALSE ); */
/* } */
-/* static uint16_t GetClkPol(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetClkPol(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_CLKPOL ) & 1; */
/* } */
-/* /////////////////////////////////////////////////////////////////////// */
-/* // Return/set the clock source. */
+/* Return/set the clock source. */
-/* static void SetClkSrc( comedi_device *dev,enc_private *k, uint16_t value ) */
+/* static void SetClkSrc( struct comedi_device *dev,struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_CLKSRC ) | ( value << STDBIT_CLKSRC ) ), FALSE ); */
/* } */
-/* static uint16_t GetClkSrc( comedi_device *dev,enc_private *k ) */
+/* static uint16_t GetClkSrc( struct comedi_device *dev,struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_CLKSRC ) & 3; */
/* } */
-/* //////////////////////////////////////////////////////////////////////// */
-/* // Return/set the index polarity. */
+/* Return/set the index polarity. */
-/* static void SetIndexPol(comedi_device *dev, enc_private *k, uint16_t value ) */
+/* static void SetIndexPol(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */
/* { */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXPOL ) | ( (value != 0) << STDBIT_INDXPOL ) ), FALSE ); */
/* } */
-/* static uint16_t GetIndexPol(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetIndexPol(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_INDXPOL ) & 1; */
/* } */
-/* //////////////////////////////////////////////////////////////////////// */
-/* // Return/set the index source. */
+/* Return/set the index source. */
-/* static void SetIndexSrc(comedi_device *dev, enc_private *k, uint16_t value ) */
+/* static void SetIndexSrc(struct comedi_device *dev, struct enc_private *k, uint16_t value ) */
/* { */
/* DEBUG("SetIndexSrc: set index src enter 3700\n"); */
/* k->SetMode(dev, k, (uint16_t)( ( k->GetMode(dev, k ) & ~STDMSK_INDXSRC ) | ( (value != 0) << STDBIT_INDXSRC ) ), FALSE ); */
/* } */
-/* static uint16_t GetIndexSrc(comedi_device *dev, enc_private *k ) */
+/* static uint16_t GetIndexSrc(struct comedi_device *dev, struct enc_private *k ) */
/* { */
/* return ( k->GetMode(dev, k ) >> STDBIT_INDXSRC ) & 1; */
/* } */
-///////////////////////////////////////////////////////////////////
-// Generate an index pulse.
+/* Generate an index pulse. */
-static void PulseIndex_A(comedi_device * dev, enc_private * k)
+static void PulseIndex_A(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t cra;
DEBUG("PulseIndex_A: pulse index enter\n");
- cra = DEBIread(dev, k->MyCRA); // Pulse index.
+ cra = DEBIread(dev, k->MyCRA); /* Pulse index. */
DEBIwrite(dev, k->MyCRA, (uint16_t) (cra ^ CRAMSK_INDXPOL_A));
DEBUG("PulseIndex_A: pulse index step1\n");
DEBIwrite(dev, k->MyCRA, cra);
}
-static void PulseIndex_B(comedi_device * dev, enc_private * k)
+static void PulseIndex_B(struct comedi_device *dev, struct enc_private *k)
{
register uint16_t crb;
- crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; // Pulse index.
+ crb = DEBIread(dev, k->MyCRB) & ~CRBMSK_INTCTRL; /* Pulse index. */
DEBIwrite(dev, k->MyCRB, (uint16_t) (crb ^ CRBMSK_INDXPOL_B));
DEBIwrite(dev, k->MyCRB, crb);
}
-/////////////////////////////////////////////////////////
-// Write value into counter preload register.
+/* Write value into counter preload register. */
-static void Preload(comedi_device * dev, enc_private * k, uint32_t value)
+static void Preload(struct comedi_device *dev, struct enc_private *k, uint32_t value)
{
DEBUG("Preload: preload enter\n");
- DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); // Write value to preload register.
+ DEBIwrite(dev, (uint16_t) (k->MyLatchLsw), (uint16_t) value); /* Write value to preload register. */
DEBUG("Preload: preload step 1\n");
DEBIwrite(dev, (uint16_t) (k->MyLatchLsw + 2),
(uint16_t) (value >> 16));
}
-static void CountersInit(comedi_device * dev)
+static void CountersInit(struct comedi_device *dev)
{
int chan;
- enc_private *k;
- uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | // Preload upon
- // index.
- (INDXSRC_SOFT << BF_INDXSRC) | // Disable hardware index.
- (CLKSRC_COUNTER << BF_CLKSRC) | // Operating mode is counter.
- (CLKPOL_POS << BF_CLKPOL) | // Active high clock.
- (CNTDIR_UP << BF_CLKPOL) | // Count direction is up.
- (CLKMULT_1X << BF_CLKMULT) | // Clock multiplier is 1x.
- (CLKENAB_INDEX << BF_CLKENAB); // Enabled by index
-
- // Disable all counter interrupts and clear any captured counter events.
+ struct enc_private *k;
+ uint16_t Setup = (LOADSRC_INDX << BF_LOADSRC) | /* Preload upon */
+ /* index. */
+ (INDXSRC_SOFT << BF_INDXSRC) | /* Disable hardware index. */
+ (CLKSRC_COUNTER << BF_CLKSRC) | /* Operating mode is counter. */
+ (CLKPOL_POS << BF_CLKPOL) | /* Active high clock. */
+ (CNTDIR_UP << BF_CLKPOL) | /* Count direction is up. */
+ (CLKMULT_1X << BF_CLKMULT) | /* Clock multiplier is 1x. */
+ (CLKENAB_INDEX << BF_CLKENAB); /* Enabled by index */
+
+ /* Disable all counter interrupts and clear any captured counter events. */
for (chan = 0; chan < S626_ENCODER_CHANNELS; chan++) {
k = &encpriv[chan];
k->SetMode(dev, k, Setup, TRUE);
diff --git a/drivers/staging/comedi/drivers/s626.h b/drivers/staging/comedi/drivers/s626.h
index 11d8b1ceb0b..891126f2509 100644
--- a/drivers/staging/comedi/drivers/s626.h
+++ b/drivers/staging/comedi/drivers/s626.h
@@ -51,15 +51,15 @@
Example code
- insn.insn=INSN_CONFIG; //configuration instruction
- insn.n=1; //number of operation (must be 1)
- insn.data=&initialvalue; //initial value loaded into encoder
- //during configuration
- insn.subdev=5; //encoder subdevice
- insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); //encoder_channel
- //to configure
-
- comedi_do_insn(cf,&insn); //executing configuration
+ insn.insn=INSN_CONFIG; // configuration instruction
+ insn.n=1; // number of operation (must be 1)
+ insn.data=&initialvalue; // initial value loaded into encoder
+ // during configuration
+ insn.subdev=5; // encoder subdevice
+ insn.chanspec=CR_PACK(encoder_channel,0,AREF_OTHER); // encoder_channel
+ // to configure
+
+ comedi_do_insn(cf,&insn); // executing configuration
*/
#ifdef _DEBUG_
@@ -88,147 +88,136 @@
#define INLINE static __inline
#endif
-/////////////////////////////////////////////////////
#include<linux/slab.h>
#define S626_SIZE 0x0200
#define SIZEOF_ADDRESS_SPACE 0x0200
-#define DMABUF_SIZE 4096 // 4k pages
+#define DMABUF_SIZE 4096 /* 4k pages */
#define S626_ADC_CHANNELS 16
#define S626_DAC_CHANNELS 4
#define S626_ENCODER_CHANNELS 6
#define S626_DIO_CHANNELS 48
-#define S626_DIO_BANKS 3 // Number of DIO groups.
-#define S626_DIO_EXTCHANS 40 // Number of
- // extended-capability
- // DIO channels.
+#define S626_DIO_BANKS 3 /* Number of DIO groups. */
+#define S626_DIO_EXTCHANS 40 /* Number of */
+ /* extended-capability */
+ /* DIO channels. */
-#define NUM_TRIMDACS 12 // Number of valid TrimDAC channels.
+#define NUM_TRIMDACS 12 /* Number of valid TrimDAC channels. */
-// PCI bus interface types.
-#define INTEL 1 // Intel bus type.
-#define MOTOROLA 2 // Motorola bus type.
+/* PCI bus interface types. */
+#define INTEL 1 /* Intel bus type. */
+#define MOTOROLA 2 /* Motorola bus type. */
-//////////////////////////////////////////////////////////
+#define PLATFORM INTEL /* *** SELECT PLATFORM TYPE *** */
-//////////////////////////////////////////////////////////
-#define PLATFORM INTEL // *** SELECT PLATFORM TYPE ***
-//////////////////////////////////////////////////////////
+#define RANGE_5V 0x10 /* +/-5V range */
+#define RANGE_10V 0x00 /* +/-10V range */
-#define RANGE_5V 0x10 // +/-5V range
-#define RANGE_10V 0x00 // +/-10V range
+#define EOPL 0x80 /* End of ADC poll list marker. */
+#define GSEL_BIPOLAR5V 0x00F0 /* LP_GSEL setting for 5V bipolar range. */
+#define GSEL_BIPOLAR10V 0x00A0 /* LP_GSEL setting for 10V bipolar range. */
-#define EOPL 0x80 // End of ADC poll list marker.
-#define GSEL_BIPOLAR5V 0x00F0 // LP_GSEL setting for 5V bipolar range.
-#define GSEL_BIPOLAR10V 0x00A0 // LP_GSEL setting for 10V bipolar range.
+/* Error codes that must be visible to this base class. */
+#define ERR_ILLEGAL_PARM 0x00010000 /* Illegal function parameter value was specified. */
+#define ERR_I2C 0x00020000 /* I2C error. */
+#define ERR_COUNTERSETUP 0x00200000 /* Illegal setup specified for counter channel. */
+#define ERR_DEBI_TIMEOUT 0x00400000 /* DEBI transfer timed out. */
-// Error codes that must be visible to this base class.
-#define ERR_ILLEGAL_PARM 0x00010000 // Illegal function parameter value was specified.
-#define ERR_I2C 0x00020000 // I2C error.
-#define ERR_COUNTERSETUP 0x00200000 // Illegal setup specified for counter channel.
-#define ERR_DEBI_TIMEOUT 0x00400000 // DEBI transfer timed out.
+/* Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF. */
+#define ADC_DMABUF_DWORDS 40 /* ADC DMA buffer must hold 16 samples, plus pre/post garbage samples. */
+#define DAC_WDMABUF_DWORDS 1 /* DAC output DMA buffer holds a single sample. */
-// Organization (physical order) and size (in DWORDs) of logical DMA buffers contained by ANA_DMABUF.
-#define ADC_DMABUF_DWORDS 40 // ADC DMA buffer must hold 16 samples, plus pre/post garbage samples.
-#define DAC_WDMABUF_DWORDS 1 // DAC output DMA buffer holds a single sample.
+/* All remaining space in 4KB DMA buffer is available for the RPS1 program. */
-// All remaining space in 4KB DMA buffer is available for the RPS1 program.
-
-// Address offsets, in DWORDS, from base of DMA buffer.
+/* Address offsets, in DWORDS, from base of DMA buffer. */
#define DAC_WDMABUF_OS ADC_DMABUF_DWORDS
-// Interrupt enab bit in ISR and IER.
-#define IRQ_GPIO3 0x00000040 // IRQ enable for GPIO3.
+/* Interrupt enab bit in ISR and IER. */
+#define IRQ_GPIO3 0x00000040 /* IRQ enable for GPIO3. */
#define IRQ_RPS1 0x10000000
-#define ISR_AFOU 0x00000800 // Audio fifo
- // under/overflow
- // detected.
-#define IRQ_COINT1A 0x0400 // conter 1A overflow
- // interrupt mask
-#define IRQ_COINT1B 0x0800 // conter 1B overflow
- // interrupt mask
-#define IRQ_COINT2A 0x1000 // conter 2A overflow
- // interrupt mask
-#define IRQ_COINT2B 0x2000 // conter 2B overflow
- // interrupt mask
-#define IRQ_COINT3A 0x4000 // conter 3A overflow
- // interrupt mask
-#define IRQ_COINT3B 0x8000 // conter 3B overflow
- // interrupt mask
-
-// RPS command codes.
-#define RPS_CLRSIGNAL 0x00000000 // CLEAR SIGNAL
-#define RPS_SETSIGNAL 0x10000000 // SET SIGNAL
-#define RPS_NOP 0x00000000 // NOP
-#define RPS_PAUSE 0x20000000 // PAUSE
-#define RPS_UPLOAD 0x40000000 // UPLOAD
-#define RPS_JUMP 0x80000000 // JUMP
-#define RPS_LDREG 0x90000100 // LDREG (1 uint32_t only)
-#define RPS_STREG 0xA0000100 // STREG (1 uint32_t only)
-#define RPS_STOP 0x50000000 // STOP
-#define RPS_IRQ 0x60000000 // IRQ
-
-#define RPS_LOGICAL_OR 0x08000000 // Logical OR conditionals.
-#define RPS_INVERT 0x04000000 // Test for negated semaphores.
-#define RPS_DEBI 0x00000002 // DEBI done
-
-#define RPS_SIG0 0x00200000 // RPS semaphore 0 (used by ADC).
-#define RPS_SIG1 0x00400000 // RPS semaphore 1 (used by DAC).
-#define RPS_SIG2 0x00800000 // RPS semaphore 2 (not used).
-#define RPS_GPIO2 0x00080000 // RPS GPIO2
-#define RPS_GPIO3 0x00100000 // RPS GPIO3
-
-#define RPS_SIGADC RPS_SIG0 // Trigger/status for ADC's RPS program.
-#define RPS_SIGDAC RPS_SIG1 // Trigger/status for DAC's RPS program.
-
-// RPS clock parameters.
-#define RPSCLK_SCALAR 8 // This is apparent ratio of PCI/RPS clks (undocumented!!).
-#define RPSCLK_PER_US ( 33 / RPSCLK_SCALAR ) // Number of RPS clocks in one microsecond.
-
-// Event counter source addresses.
-#define SBA_RPS_A0 0x27 // Time of RPS0 busy, in PCI clocks.
-
-// GPIO constants.
-#define GPIO_BASE 0x10004000 // GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out.
-#define GPIO1_LO 0x00000000 // GPIO1 set to LOW.
-#define GPIO1_HI 0x00001000 // GPIO1 set to HIGH.
-
-// Primary Status Register (PSR) constants.
-#define PSR_DEBI_E 0x00040000 // DEBI event flag.
-#define PSR_DEBI_S 0x00080000 // DEBI status flag.
-#define PSR_A2_IN 0x00008000 // Audio output DMA2 protection address reached.
-#define PSR_AFOU 0x00000800 // Audio FIFO under/overflow detected.
-#define PSR_GPIO2 0x00000020 // GPIO2 input pin: 0=AdcBusy, 1=AdcIdle.
-#define PSR_EC0S 0x00000001 // Event counter 0 threshold reached.
-
-// Secondary Status Register (SSR) constants.
-#define SSR_AF2_OUT 0x00000200 // Audio 2 output FIFO under/overflow detected.
-
-// Master Control Register 1 (MC1) constants.
-#define MC1_SOFT_RESET 0x80000000 // Invoke 7146 soft reset.
-#define MC1_SHUTDOWN 0x3FFF0000 // Shut down all MC1-controlled enables.
-
-#define MC1_ERPS1 0x2000 // enab/disable RPS task 1.
-#define MC1_ERPS0 0x1000 // enab/disable RPS task 0.
-#define MC1_DEBI 0x0800 // enab/disable DEBI pins.
-#define MC1_AUDIO 0x0200 // enab/disable audio port pins.
-#define MC1_I2C 0x0100 // enab/disable I2C interface.
-#define MC1_A2OUT 0x0008 // enab/disable transfer on A2 out.
-#define MC1_A2IN 0x0004 // enab/disable transfer on A2 in.
-#define MC1_A1IN 0x0001 // enab/disable transfer on A1 in.
-
-// Master Control Register 2 (MC2) constants.
-#define MC2_UPLD_DEBIq 0x00020002 // Upload DEBI registers.
-#define MC2_UPLD_IICq 0x00010001 // Upload I2C registers.
-#define MC2_RPSSIG2_ONq 0x20002000 // Assert RPS_SIG2.
-#define MC2_RPSSIG1_ONq 0x10001000 // Assert RPS_SIG1.
-#define MC2_RPSSIG0_ONq 0x08000800 // Assert RPS_SIG0.
-#define MC2_UPLD_DEBI_MASKq 0x00000002 // Upload DEBI mask.
-#define MC2_UPLD_IIC_MASKq 0x00000001 // Upload I2C mask.
-#define MC2_RPSSIG2_MASKq 0x00002000 // RPS_SIG2 bit mask.
-#define MC2_RPSSIG1_MASKq 0x00001000 // RPS_SIG1 bit mask.
-#define MC2_RPSSIG0_MASKq 0x00000800 // RPS_SIG0 bit mask.
+#define ISR_AFOU 0x00000800
+/* Audio fifo under/overflow detected. */
+
+#define IRQ_COINT1A 0x0400 /* conter 1A overflow interrupt mask */
+#define IRQ_COINT1B 0x0800 /* conter 1B overflow interrupt mask */
+#define IRQ_COINT2A 0x1000 /* conter 2A overflow interrupt mask */
+#define IRQ_COINT2B 0x2000 /* conter 2B overflow interrupt mask */
+#define IRQ_COINT3A 0x4000 /* conter 3A overflow interrupt mask */
+#define IRQ_COINT3B 0x8000 /* conter 3B overflow interrupt mask */
+
+/* RPS command codes. */
+#define RPS_CLRSIGNAL 0x00000000 /* CLEAR SIGNAL */
+#define RPS_SETSIGNAL 0x10000000 /* SET SIGNAL */
+#define RPS_NOP 0x00000000 /* NOP */
+#define RPS_PAUSE 0x20000000 /* PAUSE */
+#define RPS_UPLOAD 0x40000000 /* UPLOAD */
+#define RPS_JUMP 0x80000000 /* JUMP */
+#define RPS_LDREG 0x90000100 /* LDREG (1 uint32_t only) */
+#define RPS_STREG 0xA0000100 /* STREG (1 uint32_t only) */
+#define RPS_STOP 0x50000000 /* STOP */
+#define RPS_IRQ 0x60000000 /* IRQ */
+
+#define RPS_LOGICAL_OR 0x08000000 /* Logical OR conditionals. */
+#define RPS_INVERT 0x04000000 /* Test for negated semaphores. */
+#define RPS_DEBI 0x00000002 /* DEBI done */
+
+#define RPS_SIG0 0x00200000 /* RPS semaphore 0 (used by ADC). */
+#define RPS_SIG1 0x00400000 /* RPS semaphore 1 (used by DAC). */
+#define RPS_SIG2 0x00800000 /* RPS semaphore 2 (not used). */
+#define RPS_GPIO2 0x00080000 /* RPS GPIO2 */
+#define RPS_GPIO3 0x00100000 /* RPS GPIO3 */
+
+#define RPS_SIGADC RPS_SIG0 /* Trigger/status for ADC's RPS program. */
+#define RPS_SIGDAC RPS_SIG1 /* Trigger/status for DAC's RPS program. */
+
+/* RPS clock parameters. */
+#define RPSCLK_SCALAR 8 /* This is apparent ratio of PCI/RPS clks (undocumented!!). */
+#define RPSCLK_PER_US (33 / RPSCLK_SCALAR) /* Number of RPS clocks in one microsecond. */
+
+/* Event counter source addresses. */
+#define SBA_RPS_A0 0x27 /* Time of RPS0 busy, in PCI clocks. */
+
+/* GPIO constants. */
+#define GPIO_BASE 0x10004000 /* GPIO 0,2,3 = inputs, GPIO3 = IRQ; GPIO1 = out. */
+#define GPIO1_LO 0x00000000 /* GPIO1 set to LOW. */
+#define GPIO1_HI 0x00001000 /* GPIO1 set to HIGH. */
+
+/* Primary Status Register (PSR) constants. */
+#define PSR_DEBI_E 0x00040000 /* DEBI event flag. */
+#define PSR_DEBI_S 0x00080000 /* DEBI status flag. */
+#define PSR_A2_IN 0x00008000 /* Audio output DMA2 protection address reached. */
+#define PSR_AFOU 0x00000800 /* Audio FIFO under/overflow detected. */
+#define PSR_GPIO2 0x00000020 /* GPIO2 input pin: 0=AdcBusy, 1=AdcIdle. */
+#define PSR_EC0S 0x00000001 /* Event counter 0 threshold reached. */
+
+/* Secondary Status Register (SSR) constants. */
+#define SSR_AF2_OUT 0x00000200 /* Audio 2 output FIFO under/overflow detected. */
+
+/* Master Control Register 1 (MC1) constants. */
+#define MC1_SOFT_RESET 0x80000000 /* Invoke 7146 soft reset. */
+#define MC1_SHUTDOWN 0x3FFF0000 /* Shut down all MC1-controlled enables. */
+
+#define MC1_ERPS1 0x2000 /* enab/disable RPS task 1. */
+#define MC1_ERPS0 0x1000 /* enab/disable RPS task 0. */
+#define MC1_DEBI 0x0800 /* enab/disable DEBI pins. */
+#define MC1_AUDIO 0x0200 /* enab/disable audio port pins. */
+#define MC1_I2C 0x0100 /* enab/disable I2C interface. */
+#define MC1_A2OUT 0x0008 /* enab/disable transfer on A2 out. */
+#define MC1_A2IN 0x0004 /* enab/disable transfer on A2 in. */
+#define MC1_A1IN 0x0001 /* enab/disable transfer on A1 in. */
+
+/* Master Control Register 2 (MC2) constants. */
+#define MC2_UPLD_DEBIq 0x00020002 /* Upload DEBI registers. */
+#define MC2_UPLD_IICq 0x00010001 /* Upload I2C registers. */
+#define MC2_RPSSIG2_ONq 0x20002000 /* Assert RPS_SIG2. */
+#define MC2_RPSSIG1_ONq 0x10001000 /* Assert RPS_SIG1. */
+#define MC2_RPSSIG0_ONq 0x08000800 /* Assert RPS_SIG0. */
+#define MC2_UPLD_DEBI_MASKq 0x00000002 /* Upload DEBI mask. */
+#define MC2_UPLD_IIC_MASKq 0x00000001 /* Upload I2C mask. */
+#define MC2_RPSSIG2_MASKq 0x00002000 /* RPS_SIG2 bit mask. */
+#define MC2_RPSSIG1_MASKq 0x00001000 /* RPS_SIG1 bit mask. */
+#define MC2_RPSSIG0_MASKq 0x00000800 /* RPS_SIG0 bit mask. */
#define MC2_DELAYTRIG_4USq MC2_RPSSIG1_ON
#define MC2_DELAYBUSY_4USq MC2_RPSSIG1_MASK
@@ -236,469 +225,425 @@
#define MC2_DELAYTRIG_6USq MC2_RPSSIG2_ON
#define MC2_DELAYBUSY_6USq MC2_RPSSIG2_MASK
-#define MC2_UPLD_DEBI 0x0002 // Upload DEBI.
-#define MC2_UPLD_IIC 0x0001 // Upload I2C.
-#define MC2_RPSSIG2 0x2000 // RPS signal 2 (not used).
-#define MC2_RPSSIG1 0x1000 // RPS signal 1 (DAC RPS busy).
-#define MC2_RPSSIG0 0x0800 // RPS signal 0 (ADC RPS busy).
-
-#define MC2_ADC_RPS MC2_RPSSIG0 // ADC RPS busy.
-#define MC2_DAC_RPS MC2_RPSSIG1 // DAC RPS busy.
-
-///////////////////oldies///////////
-#define MC2_UPLD_DEBIQ 0x00020002 // Upload DEBI registers.
-#define MC2_UPLD_IICQ 0x00010001 // Upload I2C registers.
-////////////////////////////////////////
-
-// PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS ////////////////////////
-#define P_PCI_BT_A 0x004C // Audio DMA
- // burst/threshold
- // control.
-#define P_DEBICFG 0x007C // DEBI configuration.
-#define P_DEBICMD 0x0080 // DEBI command.
-#define P_DEBIPAGE 0x0084 // DEBI page.
-#define P_DEBIAD 0x0088 // DEBI target address.
-#define P_I2CCTRL 0x008C // I2C control.
-#define P_I2CSTAT 0x0090 // I2C status.
-#define P_BASEA2_IN 0x00AC // Audio input 2 base
- // physical DMAbuf
- // address.
-#define P_PROTA2_IN 0x00B0 // Audio input 2
- // physical DMAbuf
- // protection address.
-#define P_PAGEA2_IN 0x00B4 // Audio input 2
- // paging attributes.
-#define P_BASEA2_OUT 0x00B8 // Audio output 2 base
- // physical DMAbuf
- // address.
-#define P_PROTA2_OUT 0x00BC // Audio output 2
- // physical DMAbuf
- // protection address.
-#define P_PAGEA2_OUT 0x00C0 // Audio output 2
- // paging attributes.
-#define P_RPSPAGE0 0x00C4 // RPS0 page.
-#define P_RPSPAGE1 0x00C8 // RPS1 page.
-#define P_RPS0_TOUT 0x00D4 // RPS0 time-out.
-#define P_RPS1_TOUT 0x00D8 // RPS1 time-out.
-#define P_IER 0x00DC // Interrupt enable.
-#define P_GPIO 0x00E0 // General-purpose I/O.
-#define P_EC1SSR 0x00E4 // Event counter set 1
- // source select.
-#define P_ECT1R 0x00EC // Event counter
- // threshold set 1.
-#define P_ACON1 0x00F4 // Audio control 1.
-#define P_ACON2 0x00F8 // Audio control 2.
-#define P_MC1 0x00FC // Master control 1.
-#define P_MC2 0x0100 // Master control 2.
-#define P_RPSADDR0 0x0104 // RPS0 instruction pointer.
-#define P_RPSADDR1 0x0108 // RPS1 instruction pointer.
-#define P_ISR 0x010C // Interrupt status.
-#define P_PSR 0x0110 // Primary status.
-#define P_SSR 0x0114 // Secondary status.
-#define P_EC1R 0x0118 // Event counter set 1.
-#define P_ADP4 0x0138 // Logical audio DMA
- // pointer of audio
- // input FIFO A2_IN.
-#define P_FB_BUFFER1 0x0144 // Audio feedback buffer 1.
-#define P_FB_BUFFER2 0x0148 // Audio feedback buffer 2.
-#define P_TSL1 0x0180 // Audio time slot list 1.
-#define P_TSL2 0x01C0 // Audio time slot list 2.
-
-// LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS /////////////////
-// Analog I/O registers:
-#define LP_DACPOL 0x0082 // Write DAC polarity.
-#define LP_GSEL 0x0084 // Write ADC gain.
-#define LP_ISEL 0x0086 // Write ADC channel select.
-// Digital I/O (write only):
-#define LP_WRINTSELA 0x0042 // Write A interrupt enable.
-#define LP_WREDGSELA 0x0044 // Write A edge selection.
-#define LP_WRCAPSELA 0x0046 // Write A capture enable.
-#define LP_WRDOUTA 0x0048 // Write A digital output.
-#define LP_WRINTSELB 0x0052 // Write B interrupt enable.
-#define LP_WREDGSELB 0x0054 // Write B edge selection.
-#define LP_WRCAPSELB 0x0056 // Write B capture enable.
-#define LP_WRDOUTB 0x0058 // Write B digital output.
-#define LP_WRINTSELC 0x0062 // Write C interrupt enable.
-#define LP_WREDGSELC 0x0064 // Write C edge selection.
-#define LP_WRCAPSELC 0x0066 // Write C capture enable.
-#define LP_WRDOUTC 0x0068 // Write C digital output.
-
-// Digital I/O (read only):
-#define LP_RDDINA 0x0040 // Read digital input.
-#define LP_RDCAPFLGA 0x0048 // Read edges captured.
-#define LP_RDINTSELA 0x004A // Read interrupt
- // enable register.
-#define LP_RDEDGSELA 0x004C // Read edge
- // selection
- // register.
-#define LP_RDCAPSELA 0x004E // Read capture
- // enable register.
-#define LP_RDDINB 0x0050 // Read digital input.
-#define LP_RDCAPFLGB 0x0058 // Read edges captured.
-#define LP_RDINTSELB 0x005A // Read interrupt
- // enable register.
-#define LP_RDEDGSELB 0x005C // Read edge
- // selection
- // register.
-#define LP_RDCAPSELB 0x005E // Read capture
- // enable register.
-#define LP_RDDINC 0x0060 // Read digital input.
-#define LP_RDCAPFLGC 0x0068 // Read edges captured.
-#define LP_RDINTSELC 0x006A // Read interrupt
- // enable register.
-#define LP_RDEDGSELC 0x006C // Read edge
- // selection
- // register.
-#define LP_RDCAPSELC 0x006E // Read capture
- // enable register.
-// Counter Registers (read/write):
-#define LP_CR0A 0x0000 // 0A setup register.
-#define LP_CR0B 0x0002 // 0B setup register.
-#define LP_CR1A 0x0004 // 1A setup register.
-#define LP_CR1B 0x0006 // 1B setup register.
-#define LP_CR2A 0x0008 // 2A setup register.
-#define LP_CR2B 0x000A // 2B setup register.
-// Counter PreLoad (write) and Latch (read) Registers:
-#define LP_CNTR0ALSW 0x000C // 0A lsw.
-#define LP_CNTR0AMSW 0x000E // 0A msw.
-#define LP_CNTR0BLSW 0x0010 // 0B lsw.
-#define LP_CNTR0BMSW 0x0012 // 0B msw.
-#define LP_CNTR1ALSW 0x0014 // 1A lsw.
-#define LP_CNTR1AMSW 0x0016 // 1A msw.
-#define LP_CNTR1BLSW 0x0018 // 1B lsw.
-#define LP_CNTR1BMSW 0x001A // 1B msw.
-#define LP_CNTR2ALSW 0x001C // 2A lsw.
-#define LP_CNTR2AMSW 0x001E // 2A msw.
-#define LP_CNTR2BLSW 0x0020 // 2B lsw.
-#define LP_CNTR2BMSW 0x0022 // 2B msw.
-// Miscellaneous Registers (read/write):
-#define LP_MISC1 0x0088 // Read/write Misc1.
-#define LP_WRMISC2 0x0090 // Write Misc2.
-#define LP_RDMISC2 0x0082 // Read Misc2.
-
-// Bit masks for MISC1 register that are the same for reads and writes.
-#define MISC1_WENABLE 0x8000 // enab writes to
- // MISC2 (except Clear
- // Watchdog bit).
-#define MISC1_WDISABLE 0x0000 // Disable writes to MISC2.
-#define MISC1_EDCAP 0x1000 // enab edge capture
- // on DIO chans
- // specified by
- // LP_WRCAPSELx.
-#define MISC1_NOEDCAP 0x0000 // Disable edge
- // capture on
- // specified DIO
- // chans.
-
-// Bit masks for MISC1 register reads.
-#define RDMISC1_WDTIMEOUT 0x4000 // Watchdog timer timed out.
-
-// Bit masks for MISC2 register writes.
-#define WRMISC2_WDCLEAR 0x8000 // Reset watchdog
- // timer to zero.
-#define WRMISC2_CHARGE_ENABLE 0x4000 // enab battery
- // trickle charging.
-
-// Bit masks for MISC2 register that are the same for reads and writes.
-#define MISC2_BATT_ENABLE 0x0008 // Backup battery enable.
-#define MISC2_WDENABLE 0x0004 // Watchdog timer enable.
-#define MISC2_WDPERIOD_MASK 0x0003 // Watchdog interval
- // select mask.
-
-// Bit masks for ACON1 register.
-#define A2_RUN 0x40000000 // Run A2 based on TSL2.
-#define A1_RUN 0x20000000 // Run A1 based on TSL1.
-#define A1_SWAP 0x00200000 // Use big-endian for A1.
-#define A2_SWAP 0x00100000 // Use big-endian for A2.
-#define WS_MODES 0x00019999 // WS0 = TSL1 trigger
- // input, WS1-WS4 =
- // CS* outputs.
-
-#if PLATFORM == INTEL // Base ACON1 config:
- // always run A1 based
- // on TSL1.
-#define ACON1_BASE ( WS_MODES | A1_RUN )
+#define MC2_UPLD_DEBI 0x0002 /* Upload DEBI. */
+#define MC2_UPLD_IIC 0x0001 /* Upload I2C. */
+#define MC2_RPSSIG2 0x2000 /* RPS signal 2 (not used). */
+#define MC2_RPSSIG1 0x1000 /* RPS signal 1 (DAC RPS busy). */
+#define MC2_RPSSIG0 0x0800 /* RPS signal 0 (ADC RPS busy). */
+
+#define MC2_ADC_RPS MC2_RPSSIG0 /* ADC RPS busy. */
+#define MC2_DAC_RPS MC2_RPSSIG1 /* DAC RPS busy. */
+
+/* ***** oldies ***** */
+#define MC2_UPLD_DEBIQ 0x00020002 /* Upload DEBI registers. */
+#define MC2_UPLD_IICQ 0x00010001 /* Upload I2C registers. */
+
+/* PCI BUS (SAA7146) REGISTER ADDRESS OFFSETS */
+#define P_PCI_BT_A 0x004C /* Audio DMA burst/threshold control. */
+#define P_DEBICFG 0x007C /* DEBI configuration. */
+#define P_DEBICMD 0x0080 /* DEBI command. */
+#define P_DEBIPAGE 0x0084 /* DEBI page. */
+#define P_DEBIAD 0x0088 /* DEBI target address. */
+#define P_I2CCTRL 0x008C /* I2C control. */
+#define P_I2CSTAT 0x0090 /* I2C status. */
+#define P_BASEA2_IN 0x00AC /* Audio input 2 base physical DMAbuf
+ * address. */
+#define P_PROTA2_IN 0x00B0 /* Audio input 2 physical DMAbuf
+ * protection address. */
+#define P_PAGEA2_IN 0x00B4 /* Audio input 2 paging attributes. */
+#define P_BASEA2_OUT 0x00B8 /* Audio output 2 base physical DMAbuf
+ * address. */
+#define P_PROTA2_OUT 0x00BC /* Audio output 2 physical DMAbuf
+ * protection address. */
+#define P_PAGEA2_OUT 0x00C0 /* Audio output 2 paging attributes. */
+#define P_RPSPAGE0 0x00C4 /* RPS0 page. */
+#define P_RPSPAGE1 0x00C8 /* RPS1 page. */
+#define P_RPS0_TOUT 0x00D4 /* RPS0 time-out. */
+#define P_RPS1_TOUT 0x00D8 /* RPS1 time-out. */
+#define P_IER 0x00DC /* Interrupt enable. */
+#define P_GPIO 0x00E0 /* General-purpose I/O. */
+#define P_EC1SSR 0x00E4 /* Event counter set 1 source select. */
+#define P_ECT1R 0x00EC /* Event counter threshold set 1. */
+#define P_ACON1 0x00F4 /* Audio control 1. */
+#define P_ACON2 0x00F8 /* Audio control 2. */
+#define P_MC1 0x00FC /* Master control 1. */
+#define P_MC2 0x0100 /* Master control 2. */
+#define P_RPSADDR0 0x0104 /* RPS0 instruction pointer. */
+#define P_RPSADDR1 0x0108 /* RPS1 instruction pointer. */
+#define P_ISR 0x010C /* Interrupt status. */
+#define P_PSR 0x0110 /* Primary status. */
+#define P_SSR 0x0114 /* Secondary status. */
+#define P_EC1R 0x0118 /* Event counter set 1. */
+#define P_ADP4 0x0138 /* Logical audio DMA pointer of audio
+ * input FIFO A2_IN. */
+#define P_FB_BUFFER1 0x0144 /* Audio feedback buffer 1. */
+#define P_FB_BUFFER2 0x0148 /* Audio feedback buffer 2. */
+#define P_TSL1 0x0180 /* Audio time slot list 1. */
+#define P_TSL2 0x01C0 /* Audio time slot list 2. */
+
+/* LOCAL BUS (GATE ARRAY) REGISTER ADDRESS OFFSETS */
+/* Analog I/O registers: */
+#define LP_DACPOL 0x0082 /* Write DAC polarity. */
+#define LP_GSEL 0x0084 /* Write ADC gain. */
+#define LP_ISEL 0x0086 /* Write ADC channel select. */
+/* Digital I/O (write only): */
+#define LP_WRINTSELA 0x0042 /* Write A interrupt enable. */
+#define LP_WREDGSELA 0x0044 /* Write A edge selection. */
+#define LP_WRCAPSELA 0x0046 /* Write A capture enable. */
+#define LP_WRDOUTA 0x0048 /* Write A digital output. */
+#define LP_WRINTSELB 0x0052 /* Write B interrupt enable. */
+#define LP_WREDGSELB 0x0054 /* Write B edge selection. */
+#define LP_WRCAPSELB 0x0056 /* Write B capture enable. */
+#define LP_WRDOUTB 0x0058 /* Write B digital output. */
+#define LP_WRINTSELC 0x0062 /* Write C interrupt enable. */
+#define LP_WREDGSELC 0x0064 /* Write C edge selection. */
+#define LP_WRCAPSELC 0x0066 /* Write C capture enable. */
+#define LP_WRDOUTC 0x0068 /* Write C digital output. */
+
+/* Digital I/O (read only): */
+#define LP_RDDINA 0x0040 /* Read digital input. */
+#define LP_RDCAPFLGA 0x0048 /* Read edges captured. */
+#define LP_RDINTSELA 0x004A /* Read interrupt enable register. */
+#define LP_RDEDGSELA 0x004C /* Read edge selection register. */
+#define LP_RDCAPSELA 0x004E /* Read capture enable register. */
+#define LP_RDDINB 0x0050 /* Read digital input. */
+#define LP_RDCAPFLGB 0x0058 /* Read edges captured. */
+#define LP_RDINTSELB 0x005A /* Read interrupt enable register. */
+#define LP_RDEDGSELB 0x005C /* Read edge selection register. */
+#define LP_RDCAPSELB 0x005E /* Read capture enable register. */
+#define LP_RDDINC 0x0060 /* Read digital input. */
+#define LP_RDCAPFLGC 0x0068 /* Read edges captured. */
+#define LP_RDINTSELC 0x006A /* Read interrupt enable register. */
+#define LP_RDEDGSELC 0x006C /* Read edge selection register. */
+#define LP_RDCAPSELC 0x006E /* Read capture enable register. */
+
+/* Counter Registers (read/write): */
+#define LP_CR0A 0x0000 /* 0A setup register. */
+#define LP_CR0B 0x0002 /* 0B setup register. */
+#define LP_CR1A 0x0004 /* 1A setup register. */
+#define LP_CR1B 0x0006 /* 1B setup register. */
+#define LP_CR2A 0x0008 /* 2A setup register. */
+#define LP_CR2B 0x000A /* 2B setup register. */
+
+/* Counter PreLoad (write) and Latch (read) Registers: */
+#define LP_CNTR0ALSW 0x000C /* 0A lsw. */
+#define LP_CNTR0AMSW 0x000E /* 0A msw. */
+#define LP_CNTR0BLSW 0x0010 /* 0B lsw. */
+#define LP_CNTR0BMSW 0x0012 /* 0B msw. */
+#define LP_CNTR1ALSW 0x0014 /* 1A lsw. */
+#define LP_CNTR1AMSW 0x0016 /* 1A msw. */
+#define LP_CNTR1BLSW 0x0018 /* 1B lsw. */
+#define LP_CNTR1BMSW 0x001A /* 1B msw. */
+#define LP_CNTR2ALSW 0x001C /* 2A lsw. */
+#define LP_CNTR2AMSW 0x001E /* 2A msw. */
+#define LP_CNTR2BLSW 0x0020 /* 2B lsw. */
+#define LP_CNTR2BMSW 0x0022 /* 2B msw. */
+
+/* Miscellaneous Registers (read/write): */
+#define LP_MISC1 0x0088 /* Read/write Misc1. */
+#define LP_WRMISC2 0x0090 /* Write Misc2. */
+#define LP_RDMISC2 0x0082 /* Read Misc2. */
+
+/* Bit masks for MISC1 register that are the same for reads and writes. */
+#define MISC1_WENABLE 0x8000 /* enab writes to MISC2 (except Clear
+ * Watchdog bit). */
+#define MISC1_WDISABLE 0x0000 /* Disable writes to MISC2. */
+#define MISC1_EDCAP 0x1000 /* enab edge capture on DIO chans
+ * specified by LP_WRCAPSELx. */
+#define MISC1_NOEDCAP 0x0000 /* Disable edge capture on specified
+ * DIO chans. */
+
+/* Bit masks for MISC1 register reads. */
+#define RDMISC1_WDTIMEOUT 0x4000 /* Watchdog timer timed out. */
+
+/* Bit masks for MISC2 register writes. */
+#define WRMISC2_WDCLEAR 0x8000 /* Reset watchdog timer to zero. */
+#define WRMISC2_CHARGE_ENABLE 0x4000 /* enab battery trickle charging. */
+
+/* Bit masks for MISC2 register that are the same for reads and writes. */
+#define MISC2_BATT_ENABLE 0x0008 /* Backup battery enable. */
+#define MISC2_WDENABLE 0x0004 /* Watchdog timer enable. */
+#define MISC2_WDPERIOD_MASK 0x0003 /* Watchdog interval */
+ /* select mask. */
+
+/* Bit masks for ACON1 register. */
+#define A2_RUN 0x40000000 /* Run A2 based on TSL2. */
+#define A1_RUN 0x20000000 /* Run A1 based on TSL1. */
+#define A1_SWAP 0x00200000 /* Use big-endian for A1. */
+#define A2_SWAP 0x00100000 /* Use big-endian for A2. */
+#define WS_MODES 0x00019999 /* WS0 = TSL1 trigger */
+ /* input, WS1-WS4 = */
+ /* CS* outputs. */
+
+#if PLATFORM == INTEL /* Base ACON1 config: always run A1 based
+ * on TSL1. */
+#define ACON1_BASE (WS_MODES | A1_RUN)
#elif PLATFORM == MOTOROLA
-#define ACON1_BASE ( WS_MODES | A1_RUN | A1_SWAP | A2_SWAP )
+#define ACON1_BASE (WS_MODES | A1_RUN | A1_SWAP | A2_SWAP)
#endif
-#define ACON1_ADCSTART ACON1_BASE // Start ADC: run A1
- // based on TSL1.
-#define ACON1_DACSTART ( ACON1_BASE | A2_RUN ) // Start
- // transmit to
- // DAC: run A2
- // based on
- // TSL2.
-#define ACON1_DACSTOP ACON1_BASE // Halt A2.
-
-// Bit masks for ACON2 register.
-#define A1_CLKSRC_BCLK1 0x00000000 // A1 bit rate = BCLK1 (ADC).
-#define A2_CLKSRC_X1 0x00800000 // A2 bit rate = ACLK/1 (DACs).
-#define A2_CLKSRC_X2 0x00C00000 // A2 bit rate = ACLK/2 (DACs).
-#define A2_CLKSRC_X4 0x01400000 // A2 bit rate = ACLK/4 (DACs).
-#define INVERT_BCLK2 0x00100000 // Invert BCLK2 (DACs).
-#define BCLK2_OE 0x00040000 // enab BCLK2 (DACs).
-#define ACON2_XORMASK 0x000C0000 // XOR mask for ACON2
- // active-low bits.
-
-#define ACON2_INIT ( ACON2_XORMASK ^ ( A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE ) )
-
-// Bit masks for timeslot records.
-#define WS1 0x40000000 // WS output to assert.
+#define ACON1_ADCSTART ACON1_BASE /* Start ADC: run A1
+ * based on TSL1. */
+#define ACON1_DACSTART (ACON1_BASE | A2_RUN)
+/* Start transmit to DAC: run A2 based on TSL2. */
+#define ACON1_DACSTOP ACON1_BASE /* Halt A2. */
+
+/* Bit masks for ACON2 register. */
+#define A1_CLKSRC_BCLK1 0x00000000 /* A1 bit rate = BCLK1 (ADC). */
+#define A2_CLKSRC_X1 0x00800000 /* A2 bit rate = ACLK/1 (DACs). */
+#define A2_CLKSRC_X2 0x00C00000 /* A2 bit rate = ACLK/2 (DACs). */
+#define A2_CLKSRC_X4 0x01400000 /* A2 bit rate = ACLK/4 (DACs). */
+#define INVERT_BCLK2 0x00100000 /* Invert BCLK2 (DACs). */
+#define BCLK2_OE 0x00040000 /* enab BCLK2 (DACs). */
+#define ACON2_XORMASK 0x000C0000 /* XOR mask for ACON2 */
+ /* active-low bits. */
+
+#define ACON2_INIT (ACON2_XORMASK ^ (A1_CLKSRC_BCLK1 | A2_CLKSRC_X2 | INVERT_BCLK2 | BCLK2_OE))
+
+/* Bit masks for timeslot records. */
+#define WS1 0x40000000 /* WS output to assert. */
#define WS2 0x20000000
#define WS3 0x10000000
#define WS4 0x08000000
-#define RSD1 0x01000000 // Shift A1 data in on SD1.
-#define SDW_A1 0x00800000 // Store rcv'd char at
- // next char slot of
- // DWORD1 buffer.
-#define SIB_A1 0x00400000 // Store rcv'd char at
- // next char slot of
- // FB1 buffer.
-#define SF_A1 0x00200000 // Write unsigned long
- // buffer to input
- // FIFO.
-
-//Select parallel-to-serial converter's data source:
-#define XFIFO_0 0x00000000 // Data fifo byte 0.
-#define XFIFO_1 0x00000010 // Data fifo byte 1.
-#define XFIFO_2 0x00000020 // Data fifo byte 2.
-#define XFIFO_3 0x00000030 // Data fifo byte 3.
-#define XFB0 0x00000040 // FB_BUFFER byte 0.
-#define XFB1 0x00000050 // FB_BUFFER byte 1.
-#define XFB2 0x00000060 // FB_BUFFER byte 2.
-#define XFB3 0x00000070 // FB_BUFFER byte 3.
-#define SIB_A2 0x00000200 // Store next dword
- // from A2's input
- // shifter to FB2
- // buffer.
-#define SF_A2 0x00000100 // Store next dword
- // from A2's input
- // shifter to its
- // input fifo.
-#define LF_A2 0x00000080 // Load next dword
- // from A2's output
- // fifo into its
- // output dword
- // buffer.
-#define XSD2 0x00000008 // Shift data out on SD2.
-#define RSD3 0x00001800 // Shift data in on SD3.
-#define RSD2 0x00001000 // Shift data in on SD2.
-#define LOW_A2 0x00000002 // Drive last SD low
- // for 7 clks, then
- // tri-state.
-#define EOS 0x00000001 // End of superframe.
-
-//////////////////////
-
-// I2C configuration constants.
-#define I2C_CLKSEL 0x0400 // I2C bit rate =
- // PCIclk/480 = 68.75
- // KHz.
-#define I2C_BITRATE 68.75 // I2C bus data bit
- // rate (determined by
- // I2C_CLKSEL) in KHz.
-#define I2C_WRTIME 15.0 // Worst case time,in
- // msec, for EEPROM
- // internal write op.
-
-// I2C manifest constants.
-
-// Max retries to wait for EEPROM write.
-#define I2C_RETRIES ( I2C_WRTIME * I2C_BITRATE / 9.0 )
-#define I2C_ERR 0x0002 // I2C control/status
- // flag ERROR.
-#define I2C_BUSY 0x0001 // I2C control/status
- // flag BUSY.
-#define I2C_ABORT 0x0080 // I2C status flag ABORT.
-#define I2C_ATTRSTART 0x3 // I2C attribute START.
-#define I2C_ATTRCONT 0x2 // I2C attribute CONT.
-#define I2C_ATTRSTOP 0x1 // I2C attribute STOP.
-#define I2C_ATTRNOP 0x0 // I2C attribute NOP.
-
-// I2C read command | EEPROM address.
-#define I2CR ( devpriv->I2CAdrs | 1 )
-
-// I2C write command | EEPROM address.
-#define I2CW ( devpriv->I2CAdrs )
-
-// Code macros used for constructing I2C command bytes.
-#define I2C_B2(ATTR,VAL) ( ( (ATTR) << 6 ) | ( (VAL) << 24 ) )
-#define I2C_B1(ATTR,VAL) ( ( (ATTR) << 4 ) | ( (VAL) << 16 ) )
-#define I2C_B0(ATTR,VAL) ( ( (ATTR) << 2 ) | ( (VAL) << 8 ) )
-
-////////////////////////////////////////////////////////
-//oldest
-#define P_DEBICFGq 0x007C // DEBI configuration.
-#define P_DEBICMDq 0x0080 // DEBI command.
-#define P_DEBIPAGEq 0x0084 // DEBI page.
-#define P_DEBIADq 0x0088 // DEBI target address.
-
-#define DEBI_CFG_TOQ 0x03C00000 // timeout (15 PCI cycles)
-#define DEBI_CFG_FASTQ 0x10000000 // fast mode enable
-#define DEBI_CFG_16Q 0x00080000 // 16-bit access enable
-#define DEBI_CFG_INCQ 0x00040000 // enable address increment
-#define DEBI_CFG_TIMEROFFQ 0x00010000 // disable timer
-#define DEBI_CMD_RDQ 0x00050000 // read immediate 2 bytes
-#define DEBI_CMD_WRQ 0x00040000 // write immediate 2 bytes
-#define DEBI_PAGE_DISABLEQ 0x00000000 // paging disable
-
-///////////////////////////////////////////
-// DEBI command constants.
-#define DEBI_CMD_SIZE16 ( 2 << 17 ) // Transfer size is
- // always 2 bytes.
-#define DEBI_CMD_READ 0x00010000 // Read operation.
-#define DEBI_CMD_WRITE 0x00000000 // Write operation.
-
-// Read immediate 2 bytes.
-#define DEBI_CMD_RDWORD ( DEBI_CMD_READ | DEBI_CMD_SIZE16 )
-
-// Write immediate 2 bytes.
-#define DEBI_CMD_WRWORD ( DEBI_CMD_WRITE | DEBI_CMD_SIZE16 )
-
-// DEBI configuration constants.
-#define DEBI_CFG_XIRQ_EN 0x80000000 // enab external
- // interrupt on GPIO3.
-#define DEBI_CFG_XRESUME 0x40000000 // Resume block
- // transfer when XIRQ
- // deasserted.
-#define DEBI_CFG_FAST 0x10000000 // Fast mode enable.
-
-// 4-bit field that specifies DEBI timeout value in PCI clock cycles:
-#define DEBI_CFG_TOUT_BIT 22 // Finish DEBI cycle after
- // this many clocks.
-
-// 2-bit field that specifies Endian byte lane steering:
-#define DEBI_CFG_SWAP_NONE 0x00000000 // Straight - don't
- // swap any bytes
- // (Intel).
-#define DEBI_CFG_SWAP_2 0x00100000 // 2-byte swap (Motorola).
-#define DEBI_CFG_SWAP_4 0x00200000 // 4-byte swap.
-#define DEBI_CFG_16 0x00080000 // Slave is able to
- // serve 16-bit
- // cycles.
-
-#define DEBI_CFG_SLAVE16 0x00080000 // Slave is able to
- // serve 16-bit
- // cycles.
-#define DEBI_CFG_INC 0x00040000 // enab address
- // increment for block
- // transfers.
-#define DEBI_CFG_INTEL 0x00020000 // Intel style local bus.
-#define DEBI_CFG_TIMEROFF 0x00010000 // Disable timer.
+#define RSD1 0x01000000 /* Shift A1 data in on SD1. */
+#define SDW_A1 0x00800000 /* Store rcv'd char at next
+ * char slot of DWORD1 buffer. */
+#define SIB_A1 0x00400000 /* Store rcv'd char at next
+ * char slot of FB1 buffer. */
+#define SF_A1 0x00200000 /* Write unsigned long
+ * buffer to input FIFO. */
+
+/* Select parallel-to-serial converter's data source: */
+#define XFIFO_0 0x00000000 /* Data fifo byte 0. */
+#define XFIFO_1 0x00000010 /* Data fifo byte 1. */
+#define XFIFO_2 0x00000020 /* Data fifo byte 2. */
+#define XFIFO_3 0x00000030 /* Data fifo byte 3. */
+#define XFB0 0x00000040 /* FB_BUFFER byte 0. */
+#define XFB1 0x00000050 /* FB_BUFFER byte 1. */
+#define XFB2 0x00000060 /* FB_BUFFER byte 2. */
+#define XFB3 0x00000070 /* FB_BUFFER byte 3. */
+#define SIB_A2 0x00000200 /* Store next dword from A2's
+ * input shifter to FB2 buffer. */
+#define SF_A2 0x00000100 /* Store next dword from A2's
+ * input shifter to its input
+ * fifo. */
+#define LF_A2 0x00000080 /* Load next dword from A2's
+ * output fifo into its
+ * output dword buffer. */
+#define XSD2 0x00000008 /* Shift data out on SD2. */
+#define RSD3 0x00001800 /* Shift data in on SD3. */
+#define RSD2 0x00001000 /* Shift data in on SD2. */
+#define LOW_A2 0x00000002 /* Drive last SD low */
+ /* for 7 clks, then */
+ /* tri-state. */
+#define EOS 0x00000001 /* End of superframe. */
+
+
+/* I2C configuration constants. */
+#define I2C_CLKSEL 0x0400
+/* I2C bit rate = PCIclk/480 = 68.75 KHz. */
+
+#define I2C_BITRATE 68.75
+/* I2C bus data bit rate (determined by I2C_CLKSEL) in KHz. */
+
+#define I2C_WRTIME 15.0
+/* Worst case time, in msec, for EEPROM internal write op. */
+
+/* I2C manifest constants. */
+
+/* Max retries to wait for EEPROM write. */
+#define I2C_RETRIES (I2C_WRTIME * I2C_BITRATE / 9.0)
+#define I2C_ERR 0x0002 /* I2C control/status */
+ /* flag ERROR. */
+#define I2C_BUSY 0x0001 /* I2C control/status */
+ /* flag BUSY. */
+#define I2C_ABORT 0x0080 /* I2C status flag ABORT. */
+#define I2C_ATTRSTART 0x3 /* I2C attribute START. */
+#define I2C_ATTRCONT 0x2 /* I2C attribute CONT. */
+#define I2C_ATTRSTOP 0x1 /* I2C attribute STOP. */
+#define I2C_ATTRNOP 0x0 /* I2C attribute NOP. */
+
+/* I2C read command | EEPROM address. */
+#define I2CR (devpriv->I2CAdrs | 1)
+
+/* I2C write command | EEPROM address. */
+#define I2CW (devpriv->I2CAdrs)
+
+/* Code macros used for constructing I2C command bytes. */
+#define I2C_B2(ATTR, VAL) (((ATTR) << 6) | ((VAL) << 24))
+#define I2C_B1(ATTR, VAL) (((ATTR) << 4) | ((VAL) << 16))
+#define I2C_B0(ATTR, VAL) (((ATTR) << 2) | ((VAL) << 8))
+
+/* oldest */
+#define P_DEBICFGq 0x007C /* DEBI configuration. */
+#define P_DEBICMDq 0x0080 /* DEBI command. */
+#define P_DEBIPAGEq 0x0084 /* DEBI page. */
+#define P_DEBIADq 0x0088 /* DEBI target address. */
+
+#define DEBI_CFG_TOQ 0x03C00000 /* timeout (15 PCI cycles) */
+#define DEBI_CFG_FASTQ 0x10000000 /* fast mode enable */
+#define DEBI_CFG_16Q 0x00080000 /* 16-bit access enable */
+#define DEBI_CFG_INCQ 0x00040000 /* enable address increment */
+#define DEBI_CFG_TIMEROFFQ 0x00010000 /* disable timer */
+#define DEBI_CMD_RDQ 0x00050000 /* read immediate 2 bytes */
+#define DEBI_CMD_WRQ 0x00040000 /* write immediate 2 bytes */
+#define DEBI_PAGE_DISABLEQ 0x00000000 /* paging disable */
+
+/* DEBI command constants. */
+#define DEBI_CMD_SIZE16 (2 << 17) /* Transfer size is */
+ /* always 2 bytes. */
+#define DEBI_CMD_READ 0x00010000 /* Read operation. */
+#define DEBI_CMD_WRITE 0x00000000 /* Write operation. */
+
+/* Read immediate 2 bytes. */
+#define DEBI_CMD_RDWORD (DEBI_CMD_READ | DEBI_CMD_SIZE16)
+
+/* Write immediate 2 bytes. */
+#define DEBI_CMD_WRWORD (DEBI_CMD_WRITE | DEBI_CMD_SIZE16)
+
+/* DEBI configuration constants. */
+#define DEBI_CFG_XIRQ_EN 0x80000000 /* enab external */
+ /* interrupt on GPIO3. */
+#define DEBI_CFG_XRESUME 0x40000000 /* Resume block */
+ /* transfer when XIRQ */
+ /* deasserted. */
+#define DEBI_CFG_FAST 0x10000000 /* Fast mode enable. */
+
+/* 4-bit field that specifies DEBI timeout value in PCI clock cycles: */
+#define DEBI_CFG_TOUT_BIT 22 /* Finish DEBI cycle after */
+ /* this many clocks. */
+
+/* 2-bit field that specifies Endian byte lane steering: */
+#define DEBI_CFG_SWAP_NONE 0x00000000 /* Straight - don't */
+ /* swap any bytes */
+ /* (Intel). */
+#define DEBI_CFG_SWAP_2 0x00100000 /* 2-byte swap (Motorola). */
+#define DEBI_CFG_SWAP_4 0x00200000 /* 4-byte swap. */
+#define DEBI_CFG_16 0x00080000 /* Slave is able to */
+ /* serve 16-bit */
+ /* cycles. */
+
+#define DEBI_CFG_SLAVE16 0x00080000 /* Slave is able to */
+ /* serve 16-bit */
+ /* cycles. */
+#define DEBI_CFG_INC 0x00040000 /* enab address */
+ /* increment for block */
+ /* transfers. */
+#define DEBI_CFG_INTEL 0x00020000 /* Intel style local bus. */
+#define DEBI_CFG_TIMEROFF 0x00010000 /* Disable timer. */
#if PLATFORM == INTEL
-#define DEBI_TOUT 7 // Wait 7 PCI clocks
- // (212 ns) before
- // polling RDY.
+#define DEBI_TOUT 7 /* Wait 7 PCI clocks */
+ /* (212 ns) before */
+ /* polling RDY. */
-// Intel byte lane steering (pass through all byte lanes).
+/* Intel byte lane steering (pass through all byte lanes). */
#define DEBI_SWAP DEBI_CFG_SWAP_NONE
#elif PLATFORM == MOTOROLA
-#define DEBI_TOUT 15 // Wait 15 PCI clocks (454 ns)
- // maximum before timing out.
-#define DEBI_SWAP DEBI_CFG_SWAP_2 // Motorola byte lane steering.
+#define DEBI_TOUT 15 /* Wait 15 PCI clocks (454 ns) */
+ /* maximum before timing out. */
+#define DEBI_SWAP DEBI_CFG_SWAP_2 /* Motorola byte lane steering. */
#endif
-// DEBI page table constants.
-#define DEBI_PAGE_DISABLE 0x00000000 // Paging disable.
-
-///////////////////EXTRA FROM OTHER SANSORAY * .h////////
-
-// LoadSrc values:
-#define LOADSRC_INDX 0 // Preload core in response to
- // Index.
-#define LOADSRC_OVER 1 // Preload core in response to
- // Overflow.
-#define LOADSRCB_OVERA 2 // Preload B core in response
- // to A Overflow.
-#define LOADSRC_NONE 3 // Never preload core.
-
-// IntSrc values:
-#define INTSRC_NONE 0 // Interrupts disabled.
-#define INTSRC_OVER 1 // Interrupt on Overflow.
-#define INTSRC_INDX 2 // Interrupt on Index.
-#define INTSRC_BOTH 3 // Interrupt on Index or Overflow.
-
-// LatchSrc values:
-#define LATCHSRC_AB_READ 0 // Latch on read.
-#define LATCHSRC_A_INDXA 1 // Latch A on A Index.
-#define LATCHSRC_B_INDXB 2 // Latch B on B Index.
-#define LATCHSRC_B_OVERA 3 // Latch B on A Overflow.
-
-// IndxSrc values:
-#define INDXSRC_HARD 0 // Hardware or software index.
-#define INDXSRC_SOFT 1 // Software index only.
-
-// IndxPol values:
-#define INDXPOL_POS 0 // Index input is active high.
-#define INDXPOL_NEG 1 // Index input is active low.
-
-// ClkSrc values:
-#define CLKSRC_COUNTER 0 // Counter mode.
-#define CLKSRC_TIMER 2 // Timer mode.
-#define CLKSRC_EXTENDER 3 // Extender mode.
-
-// ClkPol values:
-#define CLKPOL_POS 0 // Counter/Extender clock is
- // active high.
-#define CLKPOL_NEG 1 // Counter/Extender clock is
- // active low.
-#define CNTDIR_UP 0 // Timer counts up.
-#define CNTDIR_DOWN 1 // Timer counts down.
-
-// ClkEnab values:
-#define CLKENAB_ALWAYS 0 // Clock always enabled.
-#define CLKENAB_INDEX 1 // Clock is enabled by index.
-
-// ClkMult values:
-#define CLKMULT_4X 0 // 4x clock multiplier.
-#define CLKMULT_2X 1 // 2x clock multiplier.
-#define CLKMULT_1X 2 // 1x clock multiplier.
-
-// Bit Field positions in COUNTER_SETUP structure:
-#define BF_LOADSRC 9 // Preload trigger.
-#define BF_INDXSRC 7 // Index source.
-#define BF_INDXPOL 6 // Index polarity.
-#define BF_CLKSRC 4 // Clock source.
-#define BF_CLKPOL 3 // Clock polarity/count direction.
-#define BF_CLKMULT 1 // Clock multiplier.
-#define BF_CLKENAB 0 // Clock enable.
-
-// Enumerated counter operating modes specified by ClkSrc bit field in
-// a COUNTER_SETUP.
-
-#define CLKSRC_COUNTER 0 // Counter: ENC_C clock, ENC_D
- // direction.
-#define CLKSRC_TIMER 2 // Timer: SYS_C clock,
- // direction specified by
- // ClkPol.
-#define CLKSRC_EXTENDER 3 // Extender: OVR_A clock,
- // ENC_D direction.
-
-// Enumerated counter clock multipliers.
-
-#define MULT_X0 0x0003 // Supports no multipliers;
- // fixed physical multiplier =
- // 3.
-#define MULT_X1 0x0002 // Supports multiplier x1;
- // fixed physical multiplier =
- // 2.
-#define MULT_X2 0x0001 // Supports multipliers x1,
- // x2; physical multipliers =
- // 1 or 2.
-#define MULT_X4 0x0000 // Supports multipliers x1,
- // x2, x4; physical
- // multipliers = 0, 1 or 2.
-
-// Sanity-check limits for parameters.
-
-#define NUM_COUNTERS 6 // Maximum valid counter
- // logical channel number.
+/* DEBI page table constants. */
+#define DEBI_PAGE_DISABLE 0x00000000 /* Paging disable. */
+
+/* ******* EXTRA FROM OTHER SANSORAY * .h ******* */
+
+/* LoadSrc values: */
+#define LOADSRC_INDX 0 /* Preload core in response to */
+ /* Index. */
+#define LOADSRC_OVER 1 /* Preload core in response to */
+ /* Overflow. */
+#define LOADSRCB_OVERA 2 /* Preload B core in response */
+ /* to A Overflow. */
+#define LOADSRC_NONE 3 /* Never preload core. */
+
+/* IntSrc values: */
+#define INTSRC_NONE 0 /* Interrupts disabled. */
+#define INTSRC_OVER 1 /* Interrupt on Overflow. */
+#define INTSRC_INDX 2 /* Interrupt on Index. */
+#define INTSRC_BOTH 3 /* Interrupt on Index or Overflow. */
+
+/* LatchSrc values: */
+#define LATCHSRC_AB_READ 0 /* Latch on read. */
+#define LATCHSRC_A_INDXA 1 /* Latch A on A Index. */
+#define LATCHSRC_B_INDXB 2 /* Latch B on B Index. */
+#define LATCHSRC_B_OVERA 3 /* Latch B on A Overflow. */
+
+/* IndxSrc values: */
+#define INDXSRC_HARD 0 /* Hardware or software index. */
+#define INDXSRC_SOFT 1 /* Software index only. */
+
+/* IndxPol values: */
+#define INDXPOL_POS 0 /* Index input is active high. */
+#define INDXPOL_NEG 1 /* Index input is active low. */
+
+/* ClkSrc values: */
+#define CLKSRC_COUNTER 0 /* Counter mode. */
+#define CLKSRC_TIMER 2 /* Timer mode. */
+#define CLKSRC_EXTENDER 3 /* Extender mode. */
+
+/* ClkPol values: */
+#define CLKPOL_POS 0 /* Counter/Extender clock is */
+ /* active high. */
+#define CLKPOL_NEG 1 /* Counter/Extender clock is */
+ /* active low. */
+#define CNTDIR_UP 0 /* Timer counts up. */
+#define CNTDIR_DOWN 1 /* Timer counts down. */
+
+/* ClkEnab values: */
+#define CLKENAB_ALWAYS 0 /* Clock always enabled. */
+#define CLKENAB_INDEX 1 /* Clock is enabled by index. */
+
+/* ClkMult values: */
+#define CLKMULT_4X 0 /* 4x clock multiplier. */
+#define CLKMULT_2X 1 /* 2x clock multiplier. */
+#define CLKMULT_1X 2 /* 1x clock multiplier. */
+
+/* Bit Field positions in COUNTER_SETUP structure: */
+#define BF_LOADSRC 9 /* Preload trigger. */
+#define BF_INDXSRC 7 /* Index source. */
+#define BF_INDXPOL 6 /* Index polarity. */
+#define BF_CLKSRC 4 /* Clock source. */
+#define BF_CLKPOL 3 /* Clock polarity/count direction. */
+#define BF_CLKMULT 1 /* Clock multiplier. */
+#define BF_CLKENAB 0 /* Clock enable. */
+
+/* Enumerated counter operating modes specified by ClkSrc bit field in */
+/* a COUNTER_SETUP. */
+
+#define CLKSRC_COUNTER 0 /* Counter: ENC_C clock, ENC_D */
+ /* direction. */
+#define CLKSRC_TIMER 2 /* Timer: SYS_C clock, */
+ /* direction specified by */
+ /* ClkPol. */
+#define CLKSRC_EXTENDER 3 /* Extender: OVR_A clock, */
+ /* ENC_D direction. */
+
+/* Enumerated counter clock multipliers. */
+
+#define MULT_X0 0x0003 /* Supports no multipliers; */
+ /* fixed physical multiplier = */
+ /* 3. */
+#define MULT_X1 0x0002 /* Supports multiplier x1; */
+ /* fixed physical multiplier = */
+ /* 2. */
+#define MULT_X2 0x0001 /* Supports multipliers x1, */
+ /* x2; physical multipliers = */
+ /* 1 or 2. */
+#define MULT_X4 0x0000 /* Supports multipliers x1, */
+ /* x2, x4; physical */
+ /* multipliers = 0, 1 or 2. */
+
+/* Sanity-check limits for parameters. */
+
+#define NUM_COUNTERS 6 /* Maximum valid counter */
+ /* logical channel number. */
#define NUM_INTSOURCES 4
#define NUM_LATCHSOURCES 4
#define NUM_CLKMULTS 4
@@ -708,59 +653,59 @@
#define NUM_INDEXSOURCES 2
#define NUM_LOADTRIGS 4
-// Bit field positions in CRA and CRB counter control registers.
-
-// Bit field positions in CRA:
-#define CRABIT_INDXSRC_B 14 // B index source.
-#define CRABIT_CLKSRC_B 12 // B clock source.
-#define CRABIT_INDXPOL_A 11 // A index polarity.
-#define CRABIT_LOADSRC_A 9 // A preload trigger.
-#define CRABIT_CLKMULT_A 7 // A clock multiplier.
-#define CRABIT_INTSRC_A 5 // A interrupt source.
-#define CRABIT_CLKPOL_A 4 // A clock polarity.
-#define CRABIT_INDXSRC_A 2 // A index source.
-#define CRABIT_CLKSRC_A 0 // A clock source.
-
-// Bit field positions in CRB:
-#define CRBBIT_INTRESETCMD 15 // Interrupt reset command.
-#define CRBBIT_INTRESET_B 14 // B interrupt reset enable.
-#define CRBBIT_INTRESET_A 13 // A interrupt reset enable.
-#define CRBBIT_CLKENAB_A 12 // A clock enable.
-#define CRBBIT_INTSRC_B 10 // B interrupt source.
-#define CRBBIT_LATCHSRC 8 // A/B latch source.
-#define CRBBIT_LOADSRC_B 6 // B preload trigger.
-#define CRBBIT_CLKMULT_B 3 // B clock multiplier.
-#define CRBBIT_CLKENAB_B 2 // B clock enable.
-#define CRBBIT_INDXPOL_B 1 // B index polarity.
-#define CRBBIT_CLKPOL_B 0 // B clock polarity.
-
-// Bit field masks for CRA and CRB.
-
-#define CRAMSK_INDXSRC_B ( (uint16_t)( 3 << CRABIT_INDXSRC_B) )
-#define CRAMSK_CLKSRC_B ( (uint16_t)( 3 << CRABIT_CLKSRC_B) )
-#define CRAMSK_INDXPOL_A ( (uint16_t)( 1 << CRABIT_INDXPOL_A) )
-#define CRAMSK_LOADSRC_A ( (uint16_t)( 3 << CRABIT_LOADSRC_A) )
-#define CRAMSK_CLKMULT_A ( (uint16_t)( 3 << CRABIT_CLKMULT_A) )
-#define CRAMSK_INTSRC_A ( (uint16_t)( 3 << CRABIT_INTSRC_A) )
-#define CRAMSK_CLKPOL_A ( (uint16_t)( 3 << CRABIT_CLKPOL_A) )
-#define CRAMSK_INDXSRC_A ( (uint16_t)( 3 << CRABIT_INDXSRC_A) )
-#define CRAMSK_CLKSRC_A ( (uint16_t)( 3 << CRABIT_CLKSRC_A) )
-
-#define CRBMSK_INTRESETCMD ( (uint16_t)( 1 << CRBBIT_INTRESETCMD) )
-#define CRBMSK_INTRESET_B ( (uint16_t)( 1 << CRBBIT_INTRESET_B) )
-#define CRBMSK_INTRESET_A ( (uint16_t)( 1 << CRBBIT_INTRESET_A) )
-#define CRBMSK_CLKENAB_A ( (uint16_t)( 1 << CRBBIT_CLKENAB_A) )
-#define CRBMSK_INTSRC_B ( (uint16_t)( 3 << CRBBIT_INTSRC_B) )
-#define CRBMSK_LATCHSRC ( (uint16_t)( 3 << CRBBIT_LATCHSRC) )
-#define CRBMSK_LOADSRC_B ( (uint16_t)( 3 << CRBBIT_LOADSRC_B) )
-#define CRBMSK_CLKMULT_B ( (uint16_t)( 3 << CRBBIT_CLKMULT_B) )
-#define CRBMSK_CLKENAB_B ( (uint16_t)( 1 << CRBBIT_CLKENAB_B) )
-#define CRBMSK_INDXPOL_B ( (uint16_t)( 1 << CRBBIT_INDXPOL_B) )
-#define CRBMSK_CLKPOL_B ( (uint16_t)( 1 << CRBBIT_CLKPOL_B) )
-
-#define CRBMSK_INTCTRL ( CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B ) // Interrupt reset control bits.
-
-// Bit field positions for standardized SETUP structure.
+/* Bit field positions in CRA and CRB counter control registers. */
+
+/* Bit field positions in CRA: */
+#define CRABIT_INDXSRC_B 14 /* B index source. */
+#define CRABIT_CLKSRC_B 12 /* B clock source. */
+#define CRABIT_INDXPOL_A 11 /* A index polarity. */
+#define CRABIT_LOADSRC_A 9 /* A preload trigger. */
+#define CRABIT_CLKMULT_A 7 /* A clock multiplier. */
+#define CRABIT_INTSRC_A 5 /* A interrupt source. */
+#define CRABIT_CLKPOL_A 4 /* A clock polarity. */
+#define CRABIT_INDXSRC_A 2 /* A index source. */
+#define CRABIT_CLKSRC_A 0 /* A clock source. */
+
+/* Bit field positions in CRB: */
+#define CRBBIT_INTRESETCMD 15 /* Interrupt reset command. */
+#define CRBBIT_INTRESET_B 14 /* B interrupt reset enable. */
+#define CRBBIT_INTRESET_A 13 /* A interrupt reset enable. */
+#define CRBBIT_CLKENAB_A 12 /* A clock enable. */
+#define CRBBIT_INTSRC_B 10 /* B interrupt source. */
+#define CRBBIT_LATCHSRC 8 /* A/B latch source. */
+#define CRBBIT_LOADSRC_B 6 /* B preload trigger. */
+#define CRBBIT_CLKMULT_B 3 /* B clock multiplier. */
+#define CRBBIT_CLKENAB_B 2 /* B clock enable. */
+#define CRBBIT_INDXPOL_B 1 /* B index polarity. */
+#define CRBBIT_CLKPOL_B 0 /* B clock polarity. */
+
+/* Bit field masks for CRA and CRB. */
+
+#define CRAMSK_INDXSRC_B ((uint16_t)(3 << CRABIT_INDXSRC_B))
+#define CRAMSK_CLKSRC_B ((uint16_t)(3 << CRABIT_CLKSRC_B))
+#define CRAMSK_INDXPOL_A ((uint16_t)(1 << CRABIT_INDXPOL_A))
+#define CRAMSK_LOADSRC_A ((uint16_t)(3 << CRABIT_LOADSRC_A))
+#define CRAMSK_CLKMULT_A ((uint16_t)(3 << CRABIT_CLKMULT_A))
+#define CRAMSK_INTSRC_A ((uint16_t)(3 << CRABIT_INTSRC_A))
+#define CRAMSK_CLKPOL_A ((uint16_t)(3 << CRABIT_CLKPOL_A))
+#define CRAMSK_INDXSRC_A ((uint16_t)(3 << CRABIT_INDXSRC_A))
+#define CRAMSK_CLKSRC_A ((uint16_t)(3 << CRABIT_CLKSRC_A))
+
+#define CRBMSK_INTRESETCMD ((uint16_t)(1 << CRBBIT_INTRESETCMD))
+#define CRBMSK_INTRESET_B ((uint16_t)(1 << CRBBIT_INTRESET_B))
+#define CRBMSK_INTRESET_A ((uint16_t)(1 << CRBBIT_INTRESET_A))
+#define CRBMSK_CLKENAB_A ((uint16_t)(1 << CRBBIT_CLKENAB_A))
+#define CRBMSK_INTSRC_B ((uint16_t)(3 << CRBBIT_INTSRC_B))
+#define CRBMSK_LATCHSRC ((uint16_t)(3 << CRBBIT_LATCHSRC))
+#define CRBMSK_LOADSRC_B ((uint16_t)(3 << CRBBIT_LOADSRC_B))
+#define CRBMSK_CLKMULT_B ((uint16_t)(3 << CRBBIT_CLKMULT_B))
+#define CRBMSK_CLKENAB_B ((uint16_t)(1 << CRBBIT_CLKENAB_B))
+#define CRBMSK_INDXPOL_B ((uint16_t)(1 << CRBBIT_INDXPOL_B))
+#define CRBMSK_CLKPOL_B ((uint16_t)(1 << CRBBIT_CLKPOL_B))
+
+#define CRBMSK_INTCTRL (CRBMSK_INTRESETCMD | CRBMSK_INTRESET_A | CRBMSK_INTRESET_B) /* Interrupt reset control bits. */
+
+/* Bit field positions for standardized SETUP structure. */
#define STDBIT_INTSRC 13
#define STDBIT_LATCHSRC 11
@@ -772,19 +717,18 @@
#define STDBIT_CLKMULT 1
#define STDBIT_CLKENAB 0
-// Bit field masks for standardized SETUP structure.
+/* Bit field masks for standardized SETUP structure. */
-#define STDMSK_INTSRC ( (uint16_t)( 3 << STDBIT_INTSRC ) )
-#define STDMSK_LATCHSRC ( (uint16_t)( 3 << STDBIT_LATCHSRC ) )
-#define STDMSK_LOADSRC ( (uint16_t)( 3 << STDBIT_LOADSRC ) )
-#define STDMSK_INDXSRC ( (uint16_t)( 1 << STDBIT_INDXSRC ) )
-#define STDMSK_INDXPOL ( (uint16_t)( 1 << STDBIT_INDXPOL ) )
-#define STDMSK_CLKSRC ( (uint16_t)( 3 << STDBIT_CLKSRC ) )
-#define STDMSK_CLKPOL ( (uint16_t)( 1 << STDBIT_CLKPOL ) )
-#define STDMSK_CLKMULT ( (uint16_t)( 3 << STDBIT_CLKMULT ) )
-#define STDMSK_CLKENAB ( (uint16_t)( 1 << STDBIT_CLKENAB ) )
+#define STDMSK_INTSRC ((uint16_t)(3 << STDBIT_INTSRC))
+#define STDMSK_LATCHSRC ((uint16_t)(3 << STDBIT_LATCHSRC))
+#define STDMSK_LOADSRC ((uint16_t)(3 << STDBIT_LOADSRC))
+#define STDMSK_INDXSRC ((uint16_t)(1 << STDBIT_INDXSRC))
+#define STDMSK_INDXPOL ((uint16_t)(1 << STDBIT_INDXPOL))
+#define STDMSK_CLKSRC ((uint16_t)(3 << STDBIT_CLKSRC))
+#define STDMSK_CLKPOL ((uint16_t)(1 << STDBIT_CLKPOL))
+#define STDMSK_CLKMULT ((uint16_t)(3 << STDBIT_CLKMULT))
+#define STDMSK_CLKENAB ((uint16_t)(1 << STDBIT_CLKENAB))
-//////////////////////////////////////////////////////////
/* typedef struct indexCounter */
/* { */
@@ -795,8 +739,8 @@
/* unsigned int enc; */
/* }CallCounter; */
-typedef struct bufferDMA {
+struct bufferDMA {
dma_addr_t PhysicalBase;
void *LogicalBase;
uint32_t DMAHandle;
-} DMABUF;
+};
diff --git a/drivers/staging/comedi/drivers/serial2002.c b/drivers/staging/comedi/drivers/serial2002.c
new file mode 100644
index 00000000000..844fd5e2e3a
--- /dev/null
+++ b/drivers/staging/comedi/drivers/serial2002.c
@@ -0,0 +1,870 @@
+/*
+ comedi/drivers/serial2002.c
+ Skeleton code for a Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2002 Anders Blomdell <anders.blomdell@control.lth.se>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+/*
+Driver: serial2002
+Description: Driver for serial connected hardware
+Devices:
+Author: Anders Blomdell
+Updated: Fri, 7 Jun 2002 12:56:45 -0700
+Status: in development
+
+*/
+
+#include "../comedidev.h"
+
+#include <linux/delay.h>
+#include <linux/ioport.h>
+
+#include <asm/termios.h>
+#include <asm/ioctls.h>
+#include <linux/serial.h>
+#include <linux/poll.h>
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct serial2002_board {
+ const char *name;
+};
+
+static const struct serial2002_board serial2002_boards[] = {
+ {
+ name: "serial2002"}
+};
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct serial2002_board *)dev->board_ptr)
+
+struct serial2002_range_table_t {
+
+ // HACK...
+ int length;
+ struct comedi_krange range;
+};
+
+
+struct serial2002_private {
+
+ int port; // /dev/ttyS<port>
+ int speed; // baudrate
+ struct file *tty;
+ unsigned int ao_readback[32];
+ unsigned char digital_in_mapping[32];
+ unsigned char digital_out_mapping[32];
+ unsigned char analog_in_mapping[32];
+ unsigned char analog_out_mapping[32];
+ unsigned char encoder_in_mapping[32];
+ struct serial2002_range_table_t in_range[32], out_range[32];
+};
+
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct serial2002_private *)dev->private)
+
+static int serial2002_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int serial2002_detach(struct comedi_device * dev);
+struct comedi_driver driver_serial2002 = {
+ driver_name:"serial2002",
+ module:THIS_MODULE,
+ attach:serial2002_attach,
+ detach:serial2002_detach,
+ board_name:&serial2002_boards[0].name,
+ offset:sizeof(struct serial2002_board),
+ num_names:sizeof(serial2002_boards) / sizeof(struct serial2002_board),
+};
+
+static int serial2002_di_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_do_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int serial2002_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+
+struct serial_data {
+ enum { is_invalid, is_digital, is_channel } kind;
+ int index;
+ unsigned long value;
+};
+
+static long tty_ioctl(struct file *f, unsigned op, unsigned long param)
+{
+#ifdef HAVE_UNLOCKED_IOCTL
+ if (f->f_op->unlocked_ioctl) {
+ return f->f_op->unlocked_ioctl(f, op, param);
+ }
+#endif
+ if (f->f_op->ioctl) {
+ return f->f_op->ioctl(f->f_dentry->d_inode, f, op, param);
+ }
+ return -ENOSYS;
+}
+
+static int tty_write(struct file *f, unsigned char *buf, int count)
+{
+ int result;
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ f->f_pos = 0;
+ result = f->f_op->write(f, buf, count, &f->f_pos);
+ set_fs(oldfs);
+ return result;
+}
+
+#if 0
+/*
+ * On 2.6.26.3 this occaisonally gave me page faults, worked around by
+ * settings.c_cc[VMIN] = 0; settings.c_cc[VTIME] = 0
+ */
+static int tty_available(struct file *f)
+{
+ long result = 0;
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ tty_ioctl(f, FIONREAD, (unsigned long)&result);
+ set_fs(oldfs);
+ return result;
+}
+#endif
+
+static int tty_read(struct file *f, int timeout)
+{
+ int result;
+
+ result = -1;
+ if (!IS_ERR(f)) {
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ if (f->f_op->poll) {
+ struct poll_wqueues table;
+ struct timeval start, now;
+
+ do_gettimeofday(&start);
+ poll_initwait(&table);
+ while (1) {
+ long elapsed;
+ int mask;
+
+ mask = f->f_op->poll(f, &table.pt);
+ if (mask & (POLLRDNORM | POLLRDBAND | POLLIN |
+ POLLHUP | POLLERR)) {
+ break;
+ }
+ do_gettimeofday(&now);
+ elapsed =
+ (1000000 * (now.tv_sec - start.tv_sec) +
+ now.tv_usec - start.tv_usec);
+ if (elapsed > timeout) {
+ break;
+ }
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule_timeout(((timeout -
+ elapsed) * HZ) / 10000);
+ }
+ poll_freewait(&table);
+ {
+ unsigned char ch;
+
+ f->f_pos = 0;
+ if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
+ result = ch;
+ }
+ }
+ } else {
+ /* Device does not support poll, busy wait */
+ int retries = 0;
+ while (1) {
+ unsigned char ch;
+
+ retries++;
+ if (retries >= timeout) {
+ break;
+ }
+
+ f->f_pos = 0;
+ if (f->f_op->read(f, &ch, 1, &f->f_pos) == 1) {
+ result = ch;
+ break;
+ }
+ comedi_udelay(100);
+ }
+ }
+ set_fs(oldfs);
+ }
+ return result;
+}
+
+static void tty_setspeed(struct file *f, int speed)
+{
+ mm_segment_t oldfs;
+
+ oldfs = get_fs();
+ set_fs(KERNEL_DS);
+ {
+ // Set speed
+ struct termios settings;
+
+ tty_ioctl(f, TCGETS, (unsigned long)&settings);
+// printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX));
+ settings.c_iflag = 0;
+ settings.c_oflag = 0;
+ settings.c_lflag = 0;
+ settings.c_cflag = CLOCAL | CS8 | CREAD;
+ settings.c_cc[VMIN] = 0;
+ settings.c_cc[VTIME] = 0;
+ switch (speed) {
+ case 2400:{
+ settings.c_cflag |= B2400;
+ }
+ break;
+ case 4800:{
+ settings.c_cflag |= B4800;
+ }
+ break;
+ case 9600:{
+ settings.c_cflag |= B9600;
+ }
+ break;
+ case 19200:{
+ settings.c_cflag |= B19200;
+ }
+ break;
+ case 38400:{
+ settings.c_cflag |= B38400;
+ }
+ break;
+ case 57600:{
+ settings.c_cflag |= B57600;
+ }
+ break;
+ case 115200:{
+ settings.c_cflag |= B115200;
+ }
+ break;
+ default:{
+ settings.c_cflag |= B9600;
+ }
+ break;
+ }
+ tty_ioctl(f, TCSETS, (unsigned long)&settings);
+// printk("Speed: %d\n", settings.c_cflag & (CBAUD | CBAUDEX));
+ }
+ {
+ // Set low latency
+ struct serial_struct settings;
+
+ tty_ioctl(f, TIOCGSERIAL, (unsigned long)&settings);
+ settings.flags |= ASYNC_LOW_LATENCY;
+ tty_ioctl(f, TIOCSSERIAL, (unsigned long)&settings);
+ }
+
+ set_fs(oldfs);
+}
+
+static void poll_digital(struct file *f, int channel)
+{
+ char cmd;
+
+ cmd = 0x40 | (channel & 0x1f);
+ tty_write(f, &cmd, 1);
+}
+
+static void poll_channel(struct file *f, int channel)
+{
+ char cmd;
+
+ cmd = 0x60 | (channel & 0x1f);
+ tty_write(f, &cmd, 1);
+}
+
+static struct serial_data serial_read(struct file *f, int timeout)
+{
+ struct serial_data result;
+ int length;
+
+ result.kind = is_invalid;
+ result.index = 0;
+ result.value = 0;
+ length = 0;
+ while (1) {
+ int data = tty_read(f, timeout);
+
+ length++;
+ if (data < 0) {
+ printk("serial2002 error\n");
+ break;
+ } else if (data & 0x80) {
+ result.value = (result.value << 7) | (data & 0x7f);
+ } else {
+ if (length == 1) {
+ switch ((data >> 5) & 0x03) {
+ case 0:{
+ result.value = 0;
+ result.kind = is_digital;
+ }
+ break;
+ case 1:{
+ result.value = 1;
+ result.kind = is_digital;
+ }
+ break;
+ }
+ } else {
+ result.value =
+ (result.
+ value << 2) | ((data & 0x60) >> 5);
+ result.kind = is_channel;
+ }
+ result.index = data & 0x1f;
+ break;
+ }
+ }
+ return result;
+
+}
+
+static void serial_write(struct file *f, struct serial_data data)
+{
+ if (data.kind == is_digital) {
+ unsigned char ch =
+ ((data.value << 5) & 0x20) | (data.index & 0x1f);
+ tty_write(f, &ch, 1);
+ } else {
+ unsigned char ch[6];
+ int i = 0;
+ if (data.value >= (1L << 30)) {
+ ch[i] = 0x80 | ((data.value >> 30) & 0x03);
+ i++;
+ }
+ if (data.value >= (1L << 23)) {
+ ch[i] = 0x80 | ((data.value >> 23) & 0x7f);
+ i++;
+ }
+ if (data.value >= (1L << 16)) {
+ ch[i] = 0x80 | ((data.value >> 16) & 0x7f);
+ i++;
+ }
+ if (data.value >= (1L << 9)) {
+ ch[i] = 0x80 | ((data.value >> 9) & 0x7f);
+ i++;
+ }
+ ch[i] = 0x80 | ((data.value >> 2) & 0x7f);
+ i++;
+ ch[i] = ((data.value << 5) & 0x60) | (data.index & 0x1f);
+ i++;
+ tty_write(f, ch, i);
+ }
+}
+
+static void serial_2002_open(struct comedi_device * dev)
+{
+ char port[20];
+
+ sprintf(port, "/dev/ttyS%d", devpriv->port);
+ devpriv->tty = filp_open(port, 0, O_RDWR);
+ if (IS_ERR(devpriv->tty)) {
+ printk("serial_2002: file open error = %ld\n",
+ PTR_ERR(devpriv->tty));
+ } else {
+ struct config_t {
+
+ int kind;
+ int bits;
+ int min;
+ int max;
+ };
+
+ struct config_t dig_in_config[32];
+ struct config_t dig_out_config[32];
+ struct config_t chan_in_config[32];
+ struct config_t chan_out_config[32];
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ dig_in_config[i].kind = 0;
+ dig_in_config[i].bits = 0;
+ dig_in_config[i].min = 0;
+ dig_in_config[i].max = 0;
+ dig_out_config[i].kind = 0;
+ dig_out_config[i].bits = 0;
+ dig_out_config[i].min = 0;
+ dig_out_config[i].max = 0;
+ chan_in_config[i].kind = 0;
+ chan_in_config[i].bits = 0;
+ chan_in_config[i].min = 0;
+ chan_in_config[i].max = 0;
+ chan_out_config[i].kind = 0;
+ chan_out_config[i].bits = 0;
+ chan_out_config[i].min = 0;
+ chan_out_config[i].max = 0;
+ }
+
+ tty_setspeed(devpriv->tty, devpriv->speed);
+ poll_channel(devpriv->tty, 31); // Start reading configuration
+ while (1) {
+ struct serial_data data;
+
+ data = serial_read(devpriv->tty, 1000);
+ if (data.kind != is_channel || data.index != 31
+ || !(data.value & 0xe0)) {
+ break;
+ } else {
+ int command, channel, kind;
+ struct config_t *cur_config = 0;
+
+ channel = data.value & 0x1f;
+ kind = (data.value >> 5) & 0x7;
+ command = (data.value >> 8) & 0x3;
+ switch (kind) {
+ case 1:{
+ cur_config = dig_in_config;
+ }
+ break;
+ case 2:{
+ cur_config = dig_out_config;
+ }
+ break;
+ case 3:{
+ cur_config = chan_in_config;
+ }
+ break;
+ case 4:{
+ cur_config = chan_out_config;
+ }
+ break;
+ case 5:{
+ cur_config = chan_in_config;
+ }
+ break;
+ }
+
+ if (cur_config) {
+ cur_config[channel].kind = kind;
+ switch (command) {
+ case 0:{
+ cur_config[channel].
+ bits =
+ (data.
+ value >> 10) &
+ 0x3f;
+ }
+ break;
+ case 1:{
+ int unit, sign, min;
+ unit = (data.
+ value >> 10) &
+ 0x7;
+ sign = (data.
+ value >> 13) &
+ 0x1;
+ min = (data.
+ value >> 14) &
+ 0xfffff;
+
+ switch (unit) {
+ case 0:{
+ min = min * 1000000;
+ }
+ break;
+ case 1:{
+ min = min * 1000;
+ }
+ break;
+ case 2:{
+ min = min * 1;
+ }
+ break;
+ }
+ if (sign) {
+ min = -min;
+ }
+ cur_config[channel].
+ min = min;
+ }
+ break;
+ case 2:{
+ int unit, sign, max;
+ unit = (data.
+ value >> 10) &
+ 0x7;
+ sign = (data.
+ value >> 13) &
+ 0x1;
+ max = (data.
+ value >> 14) &
+ 0xfffff;
+
+ switch (unit) {
+ case 0:{
+ max = max * 1000000;
+ }
+ break;
+ case 1:{
+ max = max * 1000;
+ }
+ break;
+ case 2:{
+ max = max * 1;
+ }
+ break;
+ }
+ if (sign) {
+ max = -max;
+ }
+ cur_config[channel].
+ max = max;
+ }
+ break;
+ }
+ }
+ }
+ }
+ for (i = 0; i <= 4; i++) {
+ // Fill in subdev data
+ struct config_t *c;
+ unsigned char *mapping = 0;
+ struct serial2002_range_table_t *range = 0;
+ int kind = 0;
+
+ switch (i) {
+ case 0:{
+ c = dig_in_config;
+ mapping = devpriv->digital_in_mapping;
+ kind = 1;
+ }
+ break;
+ case 1:{
+ c = dig_out_config;
+ mapping = devpriv->digital_out_mapping;
+ kind = 2;
+ }
+ break;
+ case 2:{
+ c = chan_in_config;
+ mapping = devpriv->analog_in_mapping;
+ range = devpriv->in_range;
+ kind = 3;
+ }
+ break;
+ case 3:{
+ c = chan_out_config;
+ mapping = devpriv->analog_out_mapping;
+ range = devpriv->out_range;
+ kind = 4;
+ }
+ break;
+ case 4:{
+ c = chan_in_config;
+ mapping = devpriv->encoder_in_mapping;
+ range = devpriv->in_range;
+ kind = 5;
+ }
+ break;
+ default:{
+ c = 0;
+ }
+ break;
+ }
+ if (c) {
+ struct comedi_subdevice *s;
+ const struct comedi_lrange **range_table_list = NULL;
+ unsigned int *maxdata_list;
+ int j, chan;
+
+ for (chan = 0, j = 0; j < 32; j++) {
+ if (c[j].kind == kind) {
+ chan++;
+ }
+ }
+ s = &dev->subdevices[i];
+ s->n_chan = chan;
+ s->maxdata = 0;
+ if (s->maxdata_list) {
+ kfree(s->maxdata_list);
+ }
+ s->maxdata_list = maxdata_list =
+ kmalloc(sizeof(unsigned int) * s->n_chan,
+ GFP_KERNEL);
+ if (s->range_table_list) {
+ kfree(s->range_table_list);
+ }
+ if (range) {
+ s->range_table = 0;
+ s->range_table_list = range_table_list =
+ kmalloc(sizeof
+ (struct serial2002_range_table_t) *
+ s->n_chan, GFP_KERNEL);
+ }
+ for (chan = 0, j = 0; j < 32; j++) {
+ if (c[j].kind == kind) {
+ if (mapping) {
+ mapping[chan] = j;
+ }
+ if (range) {
+ range[j].length = 1;
+ range[j].range.min =
+ c[j].min;
+ range[j].range.max =
+ c[j].max;
+ range_table_list[chan] =
+ (const struct
+ comedi_lrange *)
+ &range[j];
+ }
+ maxdata_list[chan] =
+ ((long long)1 << c[j].
+ bits) - 1;
+ chan++;
+ }
+ }
+ }
+ }
+ }
+}
+
+static void serial_2002_close(struct comedi_device * dev)
+{
+ if (!IS_ERR(devpriv->tty) && (devpriv->tty != 0)) {
+ filp_close(devpriv->tty, 0);
+ }
+}
+
+static int serial2002_di_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->digital_in_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data read;
+
+ poll_digital(devpriv->tty, chan);
+ while (1) {
+ read = serial_read(devpriv->tty, 1000);
+ if (read.kind != is_digital || read.index == chan) {
+ break;
+ }
+ }
+ data[n] = read.value;
+ }
+ return n;
+}
+
+static int serial2002_do_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->digital_out_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data write;
+
+ write.kind = is_digital;
+ write.index = chan;
+ write.value = data[n];
+ serial_write(devpriv->tty, write);
+ }
+ return n;
+}
+
+static int serial2002_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->analog_in_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data read;
+
+ poll_channel(devpriv->tty, chan);
+ while (1) {
+ read = serial_read(devpriv->tty, 1000);
+ if (read.kind != is_channel || read.index == chan) {
+ break;
+ }
+ }
+ data[n] = read.value;
+ }
+ return n;
+}
+
+static int serial2002_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->analog_out_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data write;
+
+ write.kind = is_channel;
+ write.index = chan;
+ write.value = data[n];
+ serial_write(devpriv->tty, write);
+ devpriv->ao_readback[chan] = data[n];
+ }
+ return n;
+}
+
+static int serial2002_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (n = 0; n < insn->n; n++) {
+ data[n] = devpriv->ao_readback[chan];
+ }
+
+ return n;
+}
+
+static int serial2002_ei_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n;
+ int chan;
+
+ chan = devpriv->encoder_in_mapping[CR_CHAN(insn->chanspec)];
+ for (n = 0; n < insn->n; n++) {
+ struct serial_data read;
+
+ poll_channel(devpriv->tty, chan);
+ while (1) {
+ read = serial_read(devpriv->tty, 1000);
+ if (read.kind != is_channel || read.index == chan) {
+ break;
+ }
+ }
+ data[n] = read.value;
+ }
+ return n;
+}
+
+static int serial2002_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: serial2002: ", dev->minor);
+ dev->board_name = thisboard->name;
+ if (alloc_private(dev, sizeof(struct serial2002_private)) < 0) {
+ return -ENOMEM;
+ }
+ dev->open = serial_2002_open;
+ dev->close = serial_2002_close;
+ devpriv->port = it->options[0];
+ devpriv->speed = it->options[1];
+ printk("/dev/ttyS%d @ %d\n", devpriv->port, devpriv->speed);
+
+ if (alloc_subdevices(dev, 5) < 0)
+ return -ENOMEM;
+
+ /* digital input subdevice */
+ s = dev->subdevices + 0;
+ s->type = COMEDI_SUBD_DI;
+ s->subdev_flags = SDF_READABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_read = &serial2002_di_rinsn;
+
+ /* digital output subdevice */
+ s = dev->subdevices + 1;
+ s->type = COMEDI_SUBD_DO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_write = &serial2002_do_winsn;
+
+ /* analog input subdevice */
+ s = dev->subdevices + 2;
+ s->type = COMEDI_SUBD_AI;
+ s->subdev_flags = SDF_READABLE | SDF_GROUND;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = 0;
+ s->insn_read = &serial2002_ai_rinsn;
+
+ /* analog output subdevice */
+ s = dev->subdevices + 3;
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITEABLE;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = 0;
+ s->insn_write = &serial2002_ao_winsn;
+ s->insn_read = &serial2002_ao_rinsn;
+
+ /* encoder input subdevice */
+ s = dev->subdevices + 4;
+ s->type = COMEDI_SUBD_COUNTER;
+ s->subdev_flags = SDF_READABLE | SDF_LSAMPL;
+ s->n_chan = 0;
+ s->maxdata = 1;
+ s->range_table = 0;
+ s->insn_read = &serial2002_ei_rinsn;
+
+ return 1;
+}
+
+static int serial2002_detach(struct comedi_device * dev)
+{
+ struct comedi_subdevice *s;
+ int i;
+
+ printk("comedi%d: serial2002: remove\n", dev->minor);
+ for (i = 0; i < 4; i++) {
+ s = &dev->subdevices[i];
+ if (s->maxdata_list) {
+ kfree(s->maxdata_list);
+ }
+ if (s->range_table_list) {
+ kfree(s->range_table_list);
+ }
+ }
+ return 0;
+}
+
+COMEDI_INITCLEANUP(driver_serial2002);
diff --git a/drivers/staging/comedi/drivers/skel.c b/drivers/staging/comedi/drivers/skel.c
new file mode 100644
index 00000000000..c7700d134cc
--- /dev/null
+++ b/drivers/staging/comedi/drivers/skel.c
@@ -0,0 +1,624 @@
+/*
+ comedi/drivers/skel.c
+ Skeleton code for a Comedi driver
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: skel
+Description: Skeleton driver, an example for driver writers
+Devices:
+Author: ds
+Updated: Mon, 18 Mar 2002 15:34:01 -0800
+Status: works
+
+This driver is a documented example on how Comedi drivers are
+written.
+
+Configuration Options:
+ none
+*/
+
+/*
+ * The previous block comment is used to automatically generate
+ * documentation in Comedi and Comedilib. The fields:
+ *
+ * Driver: the name of the driver
+ * Description: a short phrase describing the driver. Don't list boards.
+ * Devices: a full list of the boards that attempt to be supported by
+ * the driver. Format is "(manufacturer) board name [comedi name]",
+ * where comedi_name is the name that is used to configure the board.
+ * See the comment near board_name: in the struct comedi_driver structure
+ * below. If (manufacturer) or [comedi name] is missing, the previous
+ * value is used.
+ * Author: you
+ * Updated: date when the _documentation_ was last updated. Use 'date -R'
+ * to get a value for this.
+ * Status: a one-word description of the status. Valid values are:
+ * works - driver works correctly on most boards supported, and
+ * passes comedi_test.
+ * unknown - unknown. Usually put there by ds.
+ * experimental - may not work in any particular release. Author
+ * probably wants assistance testing it.
+ * bitrotten - driver has not been update in a long time, probably
+ * doesn't work, and probably is missing support for significant
+ * Comedi interface features.
+ * untested - author probably wrote it "blind", and is believed to
+ * work, but no confirmation.
+ *
+ * These headers should be followed by a blank line, and any comments
+ * you wish to say about the driver. The comment area is the place
+ * to put any known bugs, limitations, unsupported features, supported
+ * command triggers, whether or not commands are supported on particular
+ * subdevices, etc.
+ *
+ * Somewhere in the comment should be information about configuration
+ * options that are used with comedi_config.
+ */
+
+#include "../comedidev.h"
+
+#include <linux/pci.h> /* for PCI devices */
+
+/* Imaginary registers for the imaginary board */
+
+#define SKEL_SIZE 0
+
+#define SKEL_START_AI_CONV 0
+#define SKEL_AI_READ 0
+
+/*
+ * Board descriptions for two imaginary boards. Describing the
+ * boards in this way is optional, and completely driver-dependent.
+ * Some drivers use arrays such as this, other do not.
+ */
+struct skel_board {
+ const char *name;
+ int ai_chans;
+ int ai_bits;
+ int have_dio;
+};
+
+static const struct skel_board skel_boards[] = {
+ {
+ name: "skel-100",
+ ai_chans:16,
+ ai_bits: 12,
+ have_dio:1,
+ },
+ {
+ name: "skel-200",
+ ai_chans:8,
+ ai_bits: 16,
+ have_dio:0,
+ },
+};
+
+/* This is used by modprobe to translate PCI IDs to drivers. Should
+ * only be used for PCI and ISA-PnP devices */
+/* Please add your PCI vendor ID to comedidev.h, and it will be forwarded
+ * upstream. */
+#define PCI_VENDOR_ID_SKEL 0xdafe
+static DEFINE_PCI_DEVICE_TABLE(skel_pci_table) = {
+ {PCI_VENDOR_ID_SKEL, 0x0100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {PCI_VENDOR_ID_SKEL, 0x0200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+ {0}
+};
+
+MODULE_DEVICE_TABLE(pci, skel_pci_table);
+
+/*
+ * Useful for shorthand access to the particular board structure
+ */
+#define thisboard ((const struct skel_board *)dev->board_ptr)
+
+/* this structure is for data unique to this hardware driver. If
+ several hardware drivers keep similar information in this structure,
+ feel free to suggest moving the variable to the struct comedi_device struct. */
+struct skel_private {
+
+ int data;
+
+ /* would be useful for a PCI device */
+ struct pci_dev *pci_dev;
+
+ /* Used for AO readback */
+ unsigned int ao_readback[2];
+};
+
+/*
+ * most drivers define the following macro to make it easy to
+ * access the private structure.
+ */
+#define devpriv ((struct skel_private *)dev->private)
+
+/*
+ * The struct comedi_driver structure tells the Comedi core module
+ * which functions to call to configure/deconfigure (attach/detach)
+ * the board, and also about the kernel module that contains
+ * the device code.
+ */
+static int skel_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int skel_detach(struct comedi_device * dev);
+static struct comedi_driver driver_skel = {
+ driver_name:"dummy",
+ module:THIS_MODULE,
+ attach:skel_attach,
+ detach:skel_detach,
+/* It is not necessary to implement the following members if you are
+ * writing a driver for a ISA PnP or PCI card */
+ /* Most drivers will support multiple types of boards by
+ * having an array of board structures. These were defined
+ * in skel_boards[] above. Note that the element 'name'
+ * was first in the structure -- Comedi uses this fact to
+ * extract the name of the board without knowing any details
+ * about the structure except for its length.
+ * When a device is attached (by comedi_config), the name
+ * of the device is given to Comedi, and Comedi tries to
+ * match it by going through the list of board names. If
+ * there is a match, the address of the pointer is put
+ * into dev->board_ptr and driver->attach() is called.
+ *
+ * Note that these are not necessary if you can determine
+ * the type of board in software. ISA PnP, PCI, and PCMCIA
+ * devices are such boards.
+ */
+ board_name:&skel_boards[0].name,
+ offset:sizeof(struct skel_board),
+ num_names:sizeof(skel_boards) / sizeof(struct skel_board),
+};
+
+static int skel_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data);
+static int skel_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd);
+static int skel_ns_to_timer(unsigned int *ns, int round);
+
+/*
+ * Attach is called by the Comedi core to configure the driver
+ * for a particular board. If you specified a board_name array
+ * in the driver structure, dev->board_ptr contains that
+ * address.
+ */
+static int skel_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: skel: ", dev->minor);
+
+/*
+ * If you can probe the device to determine what device in a series
+ * it is, this is the place to do it. Otherwise, dev->board_ptr
+ * should already be initialized.
+ */
+ /* dev->board_ptr = skel_probe(dev, it); */
+
+/*
+ * Initialize dev->board_name. Note that we can use the "thisboard"
+ * macro now, since we just initialized it in the last line.
+ */
+ dev->board_name = thisboard->name;
+
+/*
+ * Allocate the private structure area. alloc_private() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_private(dev, sizeof(struct skel_private)) < 0)
+ return -ENOMEM;
+
+/*
+ * Allocate the subdevice structures. alloc_subdevice() is a
+ * convenient macro defined in comedidev.h.
+ */
+ if (alloc_subdevices(dev, 3) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* dev->read_subdev=s; */
+ /* analog input subdevice */
+ s->type = COMEDI_SUBD_AI;
+ /* we support single-ended (ground) and differential */
+ s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_DIFF;
+ s->n_chan = thisboard->ai_chans;
+ s->maxdata = (1 << thisboard->ai_bits) - 1;
+ s->range_table = &range_bipolar10;
+ s->len_chanlist = 16; /* This is the maximum chanlist length that
+ the board can handle */
+ s->insn_read = skel_ai_rinsn;
+/*
+* s->subdev_flags |= SDF_CMD_READ;
+* s->do_cmd = skel_ai_cmd;
+*/
+ s->do_cmdtest = skel_ai_cmdtest;
+
+ s = dev->subdevices + 1;
+ /* analog output subdevice */
+ s->type = COMEDI_SUBD_AO;
+ s->subdev_flags = SDF_WRITABLE;
+ s->n_chan = 1;
+ s->maxdata = 0xffff;
+ s->range_table = &range_bipolar5;
+ s->insn_write = skel_ao_winsn;
+ s->insn_read = skel_ao_rinsn;
+
+ s = dev->subdevices + 2;
+ /* digital i/o subdevice */
+ if (thisboard->have_dio) {
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 16;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = skel_dio_insn_bits;
+ s->insn_config = skel_dio_insn_config;
+ } else {
+ s->type = COMEDI_SUBD_UNUSED;
+ }
+
+ printk("attached\n");
+
+ return 0;
+}
+
+/*
+ * _detach is called to deconfigure a device. It should deallocate
+ * resources.
+ * This function is also called when _attach() fails, so it should be
+ * careful not to release resources that were not necessarily
+ * allocated by _attach(). dev->private and dev->subdevices are
+ * deallocated automatically by the core.
+ */
+static int skel_detach(struct comedi_device * dev)
+{
+ printk("comedi%d: skel: remove\n", dev->minor);
+
+ return 0;
+}
+
+/*
+ * "instructions" read/write data in "one-shot" or "software-triggered"
+ * mode.
+ */
+static int skel_ai_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int n, i;
+ unsigned int d;
+ unsigned int status;
+
+ /* a typical programming sequence */
+
+ /* write channel to multiplexer */
+ /* outw(chan,dev->iobase + SKEL_MUX); */
+
+ /* don't wait for mux to settle */
+
+ /* convert n samples */
+ for (n = 0; n < insn->n; n++) {
+ /* trigger conversion */
+ /* outw(0,dev->iobase + SKEL_CONVERT); */
+
+#define TIMEOUT 100
+ /* wait for conversion to end */
+ for (i = 0; i < TIMEOUT; i++) {
+ status = 1;
+ /* status = inb(dev->iobase + SKEL_STATUS); */
+ if (status)
+ break;
+ }
+ if (i == TIMEOUT) {
+ /* rt_printk() should be used instead of printk()
+ * whenever the code can be called from real-time. */
+ rt_printk("timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ /* read data */
+ /* d = inw(dev->iobase + SKEL_AI_DATA); */
+ d = 0;
+
+ /* mangle the data as necessary */
+ d ^= 1 << (thisboard->ai_bits - 1);
+
+ data[n] = d;
+ }
+
+ /* return the number of samples read/written */
+ return n;
+}
+
+static int skel_ai_cmdtest(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_cmd * cmd)
+{
+ int err = 0;
+ int tmp;
+
+ /* cmdtest tests a particular command to see if it is valid.
+ * Using the cmdtest ioctl, a user can create a valid cmd
+ * and then have it executes by the cmd ioctl.
+ *
+ * cmdtest returns 1,2,3,4 or 0, depending on which tests
+ * the command passes. */
+
+ /* step 1: make sure trigger sources are trivially valid */
+
+ tmp = cmd->start_src;
+ cmd->start_src &= TRIG_NOW;
+ if (!cmd->start_src || tmp != cmd->start_src)
+ err++;
+
+ tmp = cmd->scan_begin_src;
+ cmd->scan_begin_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src)
+ err++;
+
+ tmp = cmd->convert_src;
+ cmd->convert_src &= TRIG_TIMER | TRIG_EXT;
+ if (!cmd->convert_src || tmp != cmd->convert_src)
+ err++;
+
+ tmp = cmd->scan_end_src;
+ cmd->scan_end_src &= TRIG_COUNT;
+ if (!cmd->scan_end_src || tmp != cmd->scan_end_src)
+ err++;
+
+ tmp = cmd->stop_src;
+ cmd->stop_src &= TRIG_COUNT | TRIG_NONE;
+ if (!cmd->stop_src || tmp != cmd->stop_src)
+ err++;
+
+ if (err)
+ return 1;
+
+ /* step 2: make sure trigger sources are unique and mutually compatible */
+
+ /* note that mutual compatiblity is not an issue here */
+ if (cmd->scan_begin_src != TRIG_TIMER &&
+ cmd->scan_begin_src != TRIG_EXT)
+ err++;
+ if (cmd->convert_src != TRIG_TIMER && cmd->convert_src != TRIG_EXT)
+ err++;
+ if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE)
+ err++;
+
+ if (err)
+ return 2;
+
+ /* step 3: make sure arguments are trivially compatible */
+
+ if (cmd->start_arg != 0) {
+ cmd->start_arg = 0;
+ err++;
+ }
+#define MAX_SPEED 10000 /* in nanoseconds */
+#define MIN_SPEED 1000000000 /* in nanoseconds */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_arg < MAX_SPEED) {
+ cmd->scan_begin_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->scan_begin_arg > MIN_SPEED) {
+ cmd->scan_begin_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* should be level/edge, hi/lo specification here */
+ /* should specify multiple external triggers */
+ if (cmd->scan_begin_arg > 9) {
+ cmd->scan_begin_arg = 9;
+ err++;
+ }
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_arg < MAX_SPEED) {
+ cmd->convert_arg = MAX_SPEED;
+ err++;
+ }
+ if (cmd->convert_arg > MIN_SPEED) {
+ cmd->convert_arg = MIN_SPEED;
+ err++;
+ }
+ } else {
+ /* external trigger */
+ /* see above */
+ if (cmd->convert_arg > 9) {
+ cmd->convert_arg = 9;
+ err++;
+ }
+ }
+
+ if (cmd->scan_end_arg != cmd->chanlist_len) {
+ cmd->scan_end_arg = cmd->chanlist_len;
+ err++;
+ }
+ if (cmd->stop_src == TRIG_COUNT) {
+ if (cmd->stop_arg > 0x00ffffff) {
+ cmd->stop_arg = 0x00ffffff;
+ err++;
+ }
+ } else {
+ /* TRIG_NONE */
+ if (cmd->stop_arg != 0) {
+ cmd->stop_arg = 0;
+ err++;
+ }
+ }
+
+ if (err)
+ return 3;
+
+ /* step 4: fix up any arguments */
+
+ if (cmd->scan_begin_src == TRIG_TIMER) {
+ tmp = cmd->scan_begin_arg;
+ skel_ns_to_timer(&cmd->scan_begin_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->scan_begin_arg)
+ err++;
+ }
+ if (cmd->convert_src == TRIG_TIMER) {
+ tmp = cmd->convert_arg;
+ skel_ns_to_timer(&cmd->convert_arg,
+ cmd->flags & TRIG_ROUND_MASK);
+ if (tmp != cmd->convert_arg)
+ err++;
+ if (cmd->scan_begin_src == TRIG_TIMER &&
+ cmd->scan_begin_arg <
+ cmd->convert_arg * cmd->scan_end_arg) {
+ cmd->scan_begin_arg =
+ cmd->convert_arg * cmd->scan_end_arg;
+ err++;
+ }
+ }
+
+ if (err)
+ return 4;
+
+ return 0;
+}
+
+/* This function doesn't require a particular form, this is just
+ * what happens to be used in some of the drivers. It should
+ * convert ns nanoseconds to a counter value suitable for programming
+ * the device. Also, it should adjust ns so that it cooresponds to
+ * the actual time that the device will use. */
+static int skel_ns_to_timer(unsigned int *ns, int round)
+{
+ /* trivial timer */
+ /* if your timing is done through two cascaded timers, the
+ * i8253_cascade_ns_to_timer() function in 8253.h can be
+ * very helpful. There are also i8254_load() and i8254_mm_load()
+ * which can be used to load values into the ubiquitous 8254 counters
+ */
+
+ return *ns;
+}
+
+static int skel_ao_winsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ printk("skel_ao_winsn\n");
+ /* Writing a list of values to an AO channel is probably not
+ * very useful, but that's how the interface is defined. */
+ for (i = 0; i < insn->n; i++) {
+ /* a typical programming sequence */
+ /* outw(data[i],dev->iobase + SKEL_DA0 + chan); */
+ devpriv->ao_readback[chan] = data[i];
+ }
+
+ /* return the number of samples read/written */
+ return i;
+}
+
+/* AO subdevices should have a read insn as well as a write insn.
+ * Usually this means copying a value stored in devpriv. */
+static int skel_ao_rinsn(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int i;
+ int chan = CR_CHAN(insn->chanspec);
+
+ for (i = 0; i < insn->n; i++)
+ data[i] = devpriv->ao_readback[chan];
+
+ return i;
+}
+
+/* DIO devices are slightly special. Although it is possible to
+ * implement the insn_read/insn_write interface, it is much more
+ * useful to applications if you implement the insn_bits interface.
+ * This allows packed reading/writing of the DIO channels. The
+ * comedi core can convert between insn_bits and insn_read/write */
+static int skel_dio_insn_bits(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ if (insn->n != 2)
+ return -EINVAL;
+
+ /* The insn data is a mask in data[0] and the new data
+ * in data[1], each channel cooresponding to a bit. */
+ if (data[0]) {
+ s->state &= ~data[0];
+ s->state |= data[0] & data[1];
+ /* Write out the new digital output lines */
+ /* outw(s->state,dev->iobase + SKEL_DIO); */
+ }
+
+ /* on return, data[1] contains the value of the digital
+ * input and output lines. */
+ /* data[1]=inw(dev->iobase + SKEL_DIO); */
+ /* or we could just return the software copy of the output values if
+ * it was a purely digital output subdevice */
+ /* data[1]=s->state; */
+
+ return 2;
+}
+
+static int skel_dio_insn_config(struct comedi_device * dev, struct comedi_subdevice * s,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int chan = CR_CHAN(insn->chanspec);
+
+ /* The input or output configuration of each digital line is
+ * configured by a special insn_config instruction. chanspec
+ * contains the channel to be changed, and data[0] contains the
+ * value COMEDI_INPUT or COMEDI_OUTPUT. */
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ s->io_bits |= 1 << chan;
+ break;
+ case INSN_CONFIG_DIO_INPUT:
+ s->io_bits &= ~(1 << chan);
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (s->
+ io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ /* outw(s->io_bits,dev->iobase + SKEL_DIO_CONFIG); */
+
+ return insn->n;
+}
+
+/*
+ * A convenient macro that defines init_module() and cleanup_module(),
+ * as necessary.
+ */
+COMEDI_INITCLEANUP(driver_skel);
+/* If you are writing a PCI driver you should use COMEDI_PCI_INITCLEANUP instead.
+*/
+/* COMEDI_PCI_INITCLEANUP(driver_skel, skel_pci_table) */
diff --git a/drivers/staging/comedi/drivers/ssv_dnp.c b/drivers/staging/comedi/drivers/ssv_dnp.c
new file mode 100644
index 00000000000..1628d216cdd
--- /dev/null
+++ b/drivers/staging/comedi/drivers/ssv_dnp.c
@@ -0,0 +1,311 @@
+/*
+ comedi/drivers/ssv_dnp.c
+ generic comedi driver for SSV Embedded Systems' DIL/Net-PCs
+ Copyright (C) 2001 Robert Schwebel <robert@schwebel.de>
+
+ COMEDI - Linux Control and Measurement Device Interface
+ Copyright (C) 2000 David A. Schleef <ds@schleef.org>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+/*
+Driver: ssv_dnp
+Description: SSV Embedded Systems DIL/Net-PC
+Author: Robert Schwebel <robert@schwebel.de>
+Devices: [SSV Embedded Systems] DIL/Net-PC 1486 (dnp-1486)
+Status: unknown
+*/
+
+/* include files ----------------------------------------------------------- */
+
+#include "../comedidev.h"
+
+/* Some global definitions: the registers of the DNP ----------------------- */
+/* */
+/* For port A and B the mode register has bits corresponding to the output */
+/* pins, where Bit-N = 0 -> input, Bit-N = 1 -> output. Note that bits */
+/* 4 to 7 correspond to pin 0..3 for port C data register. Ensure that bits */
+/* 0..3 remain unchanged! For details about Port C Mode Register see */
+/* the remarks in dnp_insn_config() below. */
+
+#define CSCIR 0x22 /* Chip Setup and Control Index Register */
+#define CSCDR 0x23 /* Chip Setup and Control Data Register */
+#define PAMR 0xa5 /* Port A Mode Register */
+#define PADR 0xa9 /* Port A Data Register */
+#define PBMR 0xa4 /* Port B Mode Register */
+#define PBDR 0xa8 /* Port B Data Register */
+#define PCMR 0xa3 /* Port C Mode Register */
+#define PCDR 0xa7 /* Port C Data Register */
+
+/* This data structure holds information about the supported boards -------- */
+
+struct dnp_board {
+ const char *name;
+ int ai_chans;
+ int ai_bits;
+ int have_dio;
+};
+
+static const struct dnp_board dnp_boards[] = { /* we only support one DNP 'board' */
+ { /* variant at the moment */
+ name: "dnp-1486",
+ ai_chans:16,
+ ai_bits: 12,
+ have_dio:1,
+ },
+};
+
+/* Useful for shorthand access to the particular board structure ----------- */
+#define thisboard ((const struct dnp_board *)dev->board_ptr)
+
+/* This structure is for data unique to the DNP driver --------------------- */
+struct dnp_private_data {
+
+ //
+};
+
+
+/* Shorthand macro for faster access to the private data ------------------- */
+#define devpriv ((dnp_private *)dev->private)
+
+/* ------------------------------------------------------------------------- */
+/* The struct comedi_driver structure tells the Comedi core module which functions */
+/* to call to configure/deconfigure (attach/detach) the board, and also */
+/* about the kernel module that contains the device code. */
+/* */
+/* In the following section we define the API of this driver. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int dnp_detach(struct comedi_device * dev);
+
+static struct comedi_driver driver_dnp = {
+ driver_name:"ssv_dnp",
+ module:THIS_MODULE,
+ attach:dnp_attach,
+ detach:dnp_detach,
+ board_name:&dnp_boards[0].name,
+ /* only necessary for non-PnP devs */
+ offset:sizeof(struct dnp_board),/* like ISA-PnP, PCI or PCMCIA. */
+ num_names:sizeof(dnp_boards) / sizeof(struct dnp_board),
+};
+
+COMEDI_INITCLEANUP(driver_dnp);
+
+static int dnp_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+static int dnp_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data);
+
+/* ------------------------------------------------------------------------- */
+/* Attach is called by comedi core to configure the driver for a particular */
+/* board. If you specified a board_name array in the driver structure, */
+/* dev->board_ptr contains that address. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+
+ struct comedi_subdevice *s;
+
+ printk("comedi%d: dnp: ", dev->minor);
+
+ /* Autoprobing: this should find out which board we have. Currently only */
+ /* the 1486 board is supported and autoprobing is not implemented :-) */
+ //dev->board_ptr = dnp_probe(dev);
+
+ /* Initialize the name of the board. We can use the "thisboard" macro now. */
+ dev->board_name = thisboard->name;
+
+ /* Allocate the private structure area. alloc_private() is a convenient */
+ /* macro defined in comedidev.h. */
+ if (alloc_private(dev, sizeof(struct dnp_private_data)) < 0)
+ return -ENOMEM;
+
+ /* Allocate the subdevice structures. alloc_subdevice() is a convenient */
+ /* macro defined in comedidev.h. */
+
+ if (alloc_subdevices(dev, 1) < 0)
+ return -ENOMEM;
+
+ s = dev->subdevices + 0;
+ /* digital i/o subdevice */
+ s->type = COMEDI_SUBD_DIO;
+ s->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ s->n_chan = 20;
+ s->maxdata = 1;
+ s->range_table = &range_digital;
+ s->insn_bits = dnp_dio_insn_bits;
+ s->insn_config = dnp_dio_insn_config;
+
+ printk("attached\n");
+
+ /* We use the I/O ports 0x22,0x23 and 0xa3-0xa9, which are always
+ * allocated for the primary 8259, so we don't need to allocate them
+ * ourselves. */
+
+ /* configure all ports as input (default) */
+ outb(PAMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PBMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PCMR, CSCIR);
+ outb((inb(CSCDR) & 0xAA), CSCDR);
+
+ return 1;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* detach is called to deconfigure a device. It should deallocate the */
+/* resources. This function is also called when _attach() fails, so it */
+/* should be careful not to release resources that were not necessarily */
+/* allocated by _attach(). dev->private and dev->subdevices are */
+/* deallocated automatically by the core. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_detach(struct comedi_device * dev)
+{
+
+ /* configure all ports as input (default) */
+ outb(PAMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PBMR, CSCIR);
+ outb(0x00, CSCDR);
+ outb(PCMR, CSCIR);
+ outb((inb(CSCDR) & 0xAA), CSCDR);
+
+ /* announce that we are finished */
+ printk("comedi%d: dnp: remove\n", dev->minor);
+
+ return 0;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* The insn_bits interface allows packed reading/writing of DIO channels. */
+/* The comedi core can convert between insn_bits and insn_read/write, so you */
+/* are able to use these instructions as well. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_dio_insn_bits(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ if (insn->n != 2)
+ return -EINVAL; /* insn uses data[0] and data[1] */
+
+ /* The insn data is a mask in data[0] and the new data in data[1], each */
+ /* channel cooresponding to a bit. */
+
+ /* Ports A and B are straight forward: each bit corresponds to an output */
+ /* pin with the same order. Port C is different: bits 0...3 correspond to */
+ /* bits 4...7 of the output register (PCDR). */
+
+ if (data[0]) {
+
+ outb(PADR, CSCIR);
+ outb((inb(CSCDR)
+ & ~(u8) (data[0] & 0x0000FF))
+ | (u8) (data[1] & 0x0000FF), CSCDR);
+
+ outb(PBDR, CSCIR);
+ outb((inb(CSCDR)
+ & ~(u8) ((data[0] & 0x00FF00) >> 8))
+ | (u8) ((data[1] & 0x00FF00) >> 8), CSCDR);
+
+ outb(PCDR, CSCIR);
+ outb((inb(CSCDR)
+ & ~(u8) ((data[0] & 0x0F0000) >> 12))
+ | (u8) ((data[1] & 0x0F0000) >> 12), CSCDR);
+ }
+
+ /* on return, data[1] contains the value of the digital input lines. */
+ outb(PADR, CSCIR);
+ data[0] = inb(CSCDR);
+ outb(PBDR, CSCIR);
+ data[0] += inb(CSCDR) << 8;
+ outb(PCDR, CSCIR);
+ data[0] += ((inb(CSCDR) & 0xF0) << 12);
+
+ return 2;
+
+}
+
+/* ------------------------------------------------------------------------- */
+/* Configure the direction of the bidirectional digital i/o pins. chanspec */
+/* contains the channel to be changed and data[0] contains either */
+/* COMEDI_INPUT or COMEDI_OUTPUT. */
+/* ------------------------------------------------------------------------- */
+
+static int dnp_dio_insn_config(struct comedi_device * dev,
+ struct comedi_subdevice * s, struct comedi_insn * insn, unsigned int * data)
+{
+
+ u8 register_buffer;
+
+ int chan = CR_CHAN(insn->chanspec); /* reduces chanspec to lower 16 bits */
+
+ switch (data[0]) {
+ case INSN_CONFIG_DIO_OUTPUT:
+ case INSN_CONFIG_DIO_INPUT:
+ break;
+ case INSN_CONFIG_DIO_QUERY:
+ data[1] =
+ (inb(CSCDR) & (1 << chan)) ? COMEDI_OUTPUT :
+ COMEDI_INPUT;
+ return insn->n;
+ break;
+ default:
+ return -EINVAL;
+ break;
+ }
+ /* Test: which port does the channel belong to? */
+
+ /* We have to pay attention with port C: this is the meaning of PCMR: */
+ /* Bit in PCMR: 7 6 5 4 3 2 1 0 */
+ /* Corresponding port C pin: d 3 d 2 d 1 d 0 d= don't touch */
+
+ if ((chan >= 0) && (chan <= 7)) {
+ /* this is port A */
+ outb(PAMR, CSCIR);
+ } else if ((chan >= 8) && (chan <= 15)) {
+ /* this is port B */
+ chan -= 8;
+ outb(PBMR, CSCIR);
+ } else if ((chan >= 16) && (chan <= 19)) {
+ /* this is port C; multiplication with 2 brings bits into correct */
+ /* position for PCMR! */
+ chan -= 16;
+ chan *= 2;
+ outb(PCMR, CSCIR);
+ } else {
+ return -EINVAL;
+ }
+
+ /* read 'old' direction of the port and set bits (out=1, in=0) */
+ register_buffer = inb(CSCDR);
+ if (data[0] == COMEDI_OUTPUT) {
+ register_buffer |= (1 << chan);
+ } else {
+ register_buffer &= ~(1 << chan);
+ }
+ outb(register_buffer, CSCDR);
+
+ return 1;
+
+}
diff --git a/drivers/staging/comedi/drivers/unioxx5.c b/drivers/staging/comedi/drivers/unioxx5.c
new file mode 100644
index 00000000000..dd3b1119319
--- /dev/null
+++ b/drivers/staging/comedi/drivers/unioxx5.c
@@ -0,0 +1,515 @@
+/***************************************************************************
+ * *
+ * comedi/drivers/unioxx5.c *
+ * Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards. *
+ * *
+ * Copyright (C) 2006 Kruchinin Daniil (asgard) [asgard@etersoft.ru] *
+ * *
+ * COMEDI - Linux Control and Measurement Device Interface *
+ * Copyright (C) 1998,2000 David A. Schleef <ds@schleef.org> *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
+ * *
+ ***************************************************************************/
+/*
+
+Driver: unioxx5
+Description: Driver for Fastwel UNIOxx-5 (analog and digital i/o) boards.
+Author: Kruchinin Daniil (asgard) <asgard@etersoft.ru>
+Status: unknown
+Updated: 2006-10-09
+Devices: [Fastwel] UNIOxx-5 (unioxx5),
+
+ This card supports digital and analog I/O. It written for g01
+ subdevices only.
+ channels range: 0 .. 23 dio channels
+ and 0 .. 11 analog modules range
+ During attaching unioxx5 module displays modules identifiers
+ (see dmesg after comedi_config) in format:
+ | [module_number] module_id |
+
+*/
+
+#include "../comedidev.h"
+#include <linux/ioport.h>
+
+#define DRIVER_NAME "unioxx5"
+#define UNIOXX5_SIZE 0x10
+#define UNIOXX5_SUBDEV_BASE 0xA000 /* base addr of first subdev */
+#define UNIOXX5_SUBDEV_ODDS 0x400
+
+/* modules types */
+#define MODULE_DIGITAL 0
+#define MODULE_OUTPUT_MASK 0x80 /* analog input/output */
+
+/* constants for digital i/o */
+#define UNIOXX5_NUM_OF_CHANS 24
+
+/* constants for analog i/o */
+#define TxBE 0x10 /* transmit buffer enable */
+#define RxCA 0x20 /* 1 receive character available */
+#define Rx2CA 0x40 /* 2 receive character available */
+#define Rx4CA 0x80 /* 4 receive character available */
+
+/* bytes mask errors */
+#define Rx2CA_ERR_MASK 0x04 /* 2 bytes receiving error */
+#define Rx4CA_ERR_MASK 0x08 /* 4 bytes receiving error */
+
+/* channel modes */
+#define ALL_2_INPUT 0 /* config all digital channels to input */
+#define ALL_2_OUTPUT 1 /* config all digital channels to output */
+
+/* 'private' structure for each subdevice */
+struct unioxx5_subd_priv {
+ int usp_iobase;
+ unsigned char usp_module_type[12]; /* 12 modules. each can be 70L or 73L */
+ unsigned char usp_extra_data[12][4]; /* for saving previous written value for analog modules */
+ unsigned char usp_prev_wr_val[3]; /* previous written value */
+ unsigned char usp_prev_cn_val[3]; /* previous channel value */
+};
+
+static int unioxx5_attach(struct comedi_device * dev, struct comedi_devconfig * it);
+static int unioxx5_subdev_write(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_subdev_read(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_insn_config(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data);
+static int unioxx5_detach(struct comedi_device * dev);
+static int __unioxx5_subdev_init(struct comedi_subdevice * subdev, int subdev_iobase,
+ int minor);
+static int __unioxx5_digital_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+static int __unioxx5_digital_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+//static void __unioxx5_digital_config(struct unioxx5_subd_priv* usp, int mode);
+static int __unioxx5_analog_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+static int __unioxx5_analog_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor);
+static int __unioxx5_define_chan_offset(int chan_num);
+static void __unioxx5_analog_config(struct unioxx5_subd_priv * usp, int channel);
+
+static struct comedi_driver unioxx5_driver = {
+ driver_name:DRIVER_NAME,
+ module:THIS_MODULE,
+ attach:unioxx5_attach,
+ detach:unioxx5_detach
+};
+
+COMEDI_INITCLEANUP(unioxx5_driver);
+
+static int unioxx5_attach(struct comedi_device * dev, struct comedi_devconfig * it)
+{
+ int iobase, i, n_subd;
+ int id, num, ba;
+
+ iobase = it->options[0];
+
+ dev->board_name = DRIVER_NAME;
+ dev->iobase = iobase;
+ iobase += UNIOXX5_SUBDEV_BASE;
+
+ /* defining number of subdevices and getting they types (it must be 'g01') */
+ for (i = n_subd = 0, ba = iobase; i < 4; i++, ba += UNIOXX5_SUBDEV_ODDS) {
+ id = inb(ba + 0xE);
+ num = inb(ba + 0xF);
+
+ if (id != 'g' || num != 1)
+ continue;
+
+ n_subd++;
+ }
+
+ /* unioxx5 can has from two to four subdevices */
+ if (n_subd < 2) {
+ printk(KERN_ERR
+ "your card must has at least 2 'g01' subdevices\n");
+ return -1;
+ }
+
+ if (alloc_subdevices(dev, n_subd) < 0) {
+ printk(KERN_ERR "out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* initializing each of for same subdevices */
+ for (i = 0; i < n_subd; i++, iobase += UNIOXX5_SUBDEV_ODDS) {
+ if (__unioxx5_subdev_init(&dev->subdevices[i], iobase,
+ dev->minor) < 0)
+ return -1;
+ }
+
+ printk("attached\n");
+ return 0;
+}
+
+static int unioxx5_subdev_read(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct unioxx5_subd_priv *usp = subdev->private;
+ int channel, type;
+
+ channel = CR_CHAN(insn->chanspec);
+ type = usp->usp_module_type[channel / 2]; /* defining module type(analog or digital) */
+
+ if (type == MODULE_DIGITAL) {
+ if (!__unioxx5_digital_read(usp, data, channel, dev->minor))
+ return -1;
+ } else {
+ if (!__unioxx5_analog_read(usp, data, channel, dev->minor))
+ return -1;
+ }
+
+ return 1;
+}
+
+static int unioxx5_subdev_write(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ struct unioxx5_subd_priv *usp = subdev->private;
+ int channel, type;
+
+ channel = CR_CHAN(insn->chanspec);
+ type = usp->usp_module_type[channel / 2]; /* defining module type(analog or digital) */
+
+ if (type == MODULE_DIGITAL) {
+ if (!__unioxx5_digital_write(usp, data, channel, dev->minor))
+ return -1;
+ } else {
+ if (!__unioxx5_analog_write(usp, data, channel, dev->minor))
+ return -1;
+ }
+
+ return 1;
+}
+
+/* for digital modules only */
+static int unioxx5_insn_config(struct comedi_device * dev, struct comedi_subdevice * subdev,
+ struct comedi_insn * insn, unsigned int * data)
+{
+ int channel_offset, flags, channel = CR_CHAN(insn->chanspec), type;
+ struct unioxx5_subd_priv *usp = subdev->private;
+ int mask = 1 << (channel & 0x07);
+
+ type = usp->usp_module_type[channel / 2];
+
+ if (type != MODULE_DIGITAL) {
+ printk(KERN_ERR
+ "comedi%d: channel configuration accessible only for digital modules\n",
+ dev->minor);
+ return -1;
+ }
+
+ if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ dev->minor, channel);
+ return -1;
+ }
+
+ /* gets previously written value */
+ flags = usp->usp_prev_cn_val[channel_offset - 1];
+
+ switch (*data) {
+ case COMEDI_INPUT:
+ flags &= ~mask;
+ break;
+ case COMEDI_OUTPUT:
+ flags |= mask;
+ break;
+ default:
+ printk(KERN_ERR "comedi%d: unknown flag\n", dev->minor);
+ return -1;
+ }
+
+ /* *\
+ * sets channels buffer to 1(after this we are allowed to *
+ * change channel type on input or output) *
+ \* */
+ outb(1, usp->usp_iobase + 0);
+ outb(flags, usp->usp_iobase + channel_offset); /* changes type of _one_ channel */
+ outb(0, usp->usp_iobase + 0); /* sets channels bank to 0(allows directly input/output) */
+ usp->usp_prev_cn_val[channel_offset - 1] = flags; /* saves written value */
+
+ return 0;
+}
+
+static int unioxx5_detach(struct comedi_device * dev)
+{
+ int i;
+ struct comedi_subdevice *subdev;
+ struct unioxx5_subd_priv *usp;
+
+ for (i = 0; i < dev->n_subdevices; i++) {
+ subdev = &dev->subdevices[i];
+ usp = subdev->private;
+ release_region(usp->usp_iobase, UNIOXX5_SIZE);
+ kfree(subdev->private);
+ }
+
+ return 0;
+}
+
+/* initializing subdevice with given address */
+static int __unioxx5_subdev_init(struct comedi_subdevice * subdev, int subdev_iobase,
+ int minor)
+{
+ struct unioxx5_subd_priv *usp;
+ int i, to, ndef_flag = 0;
+
+ if (!request_region(subdev_iobase, UNIOXX5_SIZE, DRIVER_NAME)) {
+ printk(KERN_ERR "comedi%d: I/O port conflict\n", minor);
+ return -EIO;
+ }
+
+ if ((usp = (struct unioxx5_subd_priv *) kzalloc(sizeof(*usp),
+ GFP_KERNEL)) == NULL) {
+ printk(KERN_ERR "comedi%d: erorr! --> out of memory!\n", minor);
+ return -1;
+ }
+
+ usp->usp_iobase = subdev_iobase;
+ printk("comedi%d: |", minor);
+
+ /* defining modules types */
+ for (i = 0; i < 12; i++) {
+ to = 10000;
+
+ __unioxx5_analog_config(usp, i * 2);
+ outb(i + 1, subdev_iobase + 5); /* sends channel number to card */
+ outb('H', subdev_iobase + 6); /* requests EEPROM world */
+ while (!(inb(subdev_iobase + 0) & TxBE)) ; /* waits while writting will be allowed */
+ outb(0, subdev_iobase + 6);
+
+ /* waits while reading of two bytes will be allowed */
+ while (!(inb(subdev_iobase + 0) & Rx2CA)) {
+ if (--to <= 0) {
+ ndef_flag = 1;
+ break;
+ }
+ }
+
+ if (ndef_flag) {
+ usp->usp_module_type[i] = 0;
+ ndef_flag = 0;
+ } else
+ usp->usp_module_type[i] = inb(subdev_iobase + 6);
+
+ printk(" [%d] 0x%02x |", i, usp->usp_module_type[i]);
+ comedi_udelay(1);
+ }
+
+ printk("\n");
+
+ /* initial subdevice for digital or analog i/o */
+ subdev->type = COMEDI_SUBD_DIO;
+ subdev->private = usp;
+ subdev->subdev_flags = SDF_READABLE | SDF_WRITABLE;
+ subdev->n_chan = UNIOXX5_NUM_OF_CHANS;
+ subdev->maxdata = 0xFFF;
+ subdev->range_table = &range_digital;
+ subdev->insn_read = unioxx5_subdev_read;
+ subdev->insn_write = unioxx5_subdev_write;
+ subdev->insn_config = unioxx5_insn_config; /* for digital modules only!!! */
+
+ printk("subdevice configured\n");
+
+ return 0;
+}
+
+static int __unioxx5_digital_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int channel_offset, val;
+ int mask = 1 << (channel & 0x07);
+
+ if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ minor, channel);
+ return 0;
+ }
+
+ val = usp->usp_prev_wr_val[channel_offset - 1]; /* getting previous written value */
+
+ if (*data)
+ val |= mask;
+ else
+ val &= ~mask;
+
+ outb(val, usp->usp_iobase + channel_offset);
+ usp->usp_prev_wr_val[channel_offset - 1] = val; /* saving new written value */
+
+ return 1;
+}
+
+/* function for digital reading */
+static int __unioxx5_digital_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int channel_offset, mask = 1 << (channel & 0x07);
+
+ if ((channel_offset = __unioxx5_define_chan_offset(channel)) < 0) {
+ printk(KERN_ERR
+ "comedi%d: undefined channel %d. channel range is 0 .. 23\n",
+ minor, channel);
+ return 0;
+ }
+
+ *data = inb(usp->usp_iobase + channel_offset);
+ *data &= mask;
+
+ if (channel_offset > 1)
+ channel -= 2 << channel_offset; /* this operation is created for correct readed value to 0 or 1 */
+
+ *data >>= channel;
+ return 1;
+}
+
+#if 0 /* not used? */
+static void __unioxx5_digital_config(struct unioxx5_subd_priv * usp, int mode)
+{
+ int i, mask;
+
+ mask = (mode == ALL_2_OUTPUT) ? 0xFF : 0x00;
+ printk("COMEDI: mode = %d\n", mask);
+
+ outb(1, usp->usp_iobase + 0);
+
+ for (i = 0; i < 3; i++)
+ outb(mask, usp->usp_iobase + i);
+
+ outb(0, usp->usp_iobase + 0);
+}
+#endif
+
+static int __unioxx5_analog_write(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int module, i;
+
+ module = channel / 2; /* definig module number(0 .. 11) */
+ i = (channel % 2) << 1; /* depends on type of channel (A or B) */
+
+ /* defining if given module can work on output */
+ if (!(usp->usp_module_type[module] & MODULE_OUTPUT_MASK)) {
+ printk(KERN_ERR
+ "comedi%d: module in position %d with id 0x%0x is for input only!\n",
+ minor, module, usp->usp_module_type[module]);
+ return 0;
+ }
+
+ __unioxx5_analog_config(usp, channel);
+ /* saving minor byte */
+ usp->usp_extra_data[module][i++] = (unsigned char)(*data & 0x00FF);
+ /* saving major byte */
+ usp->usp_extra_data[module][i] = (unsigned char)((*data & 0xFF00) >> 8);
+
+ //while(!((inb(usp->usp_iobase + 0)) & TxBE));
+ outb(module + 1, usp->usp_iobase + 5); /* sending module number to card(1 .. 12) */
+ outb('W', usp->usp_iobase + 6); /* sends (W)rite command to module */
+
+ /* sending for bytes to module(one byte per cycle iteration) */
+ for (i = 0; i < 4; i++) {
+ while (!((inb(usp->usp_iobase + 0)) & TxBE)) ; /* waits while writting will be allowed */
+ outb(usp->usp_extra_data[module][i], usp->usp_iobase + 6);
+ }
+
+ return 1;
+}
+
+static int __unioxx5_analog_read(struct unioxx5_subd_priv * usp, unsigned int * data,
+ int channel, int minor)
+{
+ int module_no, read_ch;
+ char control;
+
+ module_no = channel / 2;
+ read_ch = channel % 2; /* depend on type of channel (A or B) */
+
+ /* defining if given module can work on input */
+ if (usp->usp_module_type[module_no] & MODULE_OUTPUT_MASK) {
+ printk(KERN_ERR
+ "comedi%d: module in position %d with id 0x%02x is for output only",
+ minor, module_no, usp->usp_module_type[module_no]);
+ return 0;
+ }
+
+ __unioxx5_analog_config(usp, channel);
+ outb(module_no + 1, usp->usp_iobase + 5); /* sends module number to card(1 .. 12) */
+ outb('V', usp->usp_iobase + 6); /* sends to module (V)erify command */
+ control = inb(usp->usp_iobase); /* get control register byte */
+
+ /* waits while reading four bytes will be allowed */
+ while (!((control = inb(usp->usp_iobase + 0)) & Rx4CA)) ;
+
+ /* if four bytes readding error occurs - return 0(false) */
+ if ((control & Rx4CA_ERR_MASK)) {
+ printk("COMEDI: 4 bytes error\n");
+ return 0;
+ }
+
+ if (read_ch)
+ *data = inw(usp->usp_iobase + 6); /* channel B */
+ else
+ *data = inw(usp->usp_iobase + 4); /* channel A */
+
+ return 1;
+}
+
+/* configure channels for analog i/o (even to output, odd to input) */
+static void __unioxx5_analog_config(struct unioxx5_subd_priv * usp, int channel)
+{
+ int chan_a, chan_b, conf, channel_offset;
+
+ channel_offset = __unioxx5_define_chan_offset(channel);
+ conf = usp->usp_prev_cn_val[channel_offset - 1];
+ chan_a = chan_b = 1;
+
+ /* setting channel A and channel B mask */
+ if (channel % 2 == 0) {
+ chan_a <<= channel & 0x07;
+ chan_b <<= (channel + 1) & 0x07;
+ } else {
+ chan_a <<= (channel - 1) & 0x07;
+ chan_b <<= channel & 0x07;
+ }
+
+ conf |= chan_a; /* even channel ot output */
+ conf &= ~chan_b; /* odd channel to input */
+
+ outb(1, usp->usp_iobase + 0);
+ outb(conf, usp->usp_iobase + channel_offset);
+ outb(0, usp->usp_iobase + 0);
+
+ usp->usp_prev_cn_val[channel_offset - 1] = conf;
+}
+
+/* *\
+ * this function defines if the given channel number *
+ * enters in default numeric interspace(from 0 to 23) *
+ * and it returns address offset for usage needed *
+ * channel. *
+\* */
+
+static int __unioxx5_define_chan_offset(int chan_num)
+{
+
+ if (chan_num < 0 || chan_num > 23)
+ return -1;
+
+ return (chan_num >> 3) + 1;
+}
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c
index 35138257be7..d0b59e98314 100644
--- a/drivers/staging/comedi/drivers/usbdux.c
+++ b/drivers/staging/comedi/drivers/usbdux.c
@@ -1,4 +1,4 @@
-#define DRIVER_VERSION "v2.1"
+#define DRIVER_VERSION "v2.2"
#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
#define DRIVER_DESC "Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"
/*
@@ -25,8 +25,8 @@ Driver: usbdux
Description: University of Stirling USB DAQ & INCITE Technology Limited
Devices: [ITL] USB-DUX (usbdux.o)
Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 25 Nov 2007
-Status: Testing
+Updated: 8 Dec 2008
+Status: Stable
Configuration options:
You have to upload firmware with the -i option. The
firmware is usually installed under /usr/share/usb or
@@ -79,6 +79,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
* 1.2: added PWM suport via EP4
* 2.0: PWM seems to be stable and is not interfering with the other functions
* 2.1: changed PWM API
+ * 2.2: added firmware kernel request to fix an udev problem
*
*/
@@ -94,6 +95,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
#include <linux/smp_lock.h>
#include <linux/fcntl.h>
#include <linux/compiler.h>
+#include <linux/firmware.h>
#include "../comedidev.h"
@@ -212,7 +214,7 @@ sampling rate. If you sample two channels you get 4kHz and so on.
/**************************************************/
/* comedi constants */
-static const comedi_lrange range_usbdux_ai_range = { 4, {
+static const struct comedi_lrange range_usbdux_ai_range = { 4, {
BIP_RANGE(4.096),
BIP_RANGE(4.096 / 2),
UNI_RANGE(4.096),
@@ -220,7 +222,7 @@ static const comedi_lrange range_usbdux_ai_range = { 4, {
}
};
-static const comedi_lrange range_usbdux_ao_range = { 2, {
+static const struct comedi_lrange range_usbdux_ao_range = { 2, {
BIP_RANGE(4.096),
UNI_RANGE(4.096),
}
@@ -251,7 +253,7 @@ struct usbduxsub {
/* pwm-transfer handling */
struct urb *urbPwm;
/* PWM period */
- lsampl_t pwmPeriod;
+ unsigned int pwmPeriod;
/* PWM internal delay for the GPIF in the FX2 */
int8_t pwmDelay;
/* size of the PWM buffer which holds the bit pattern */
@@ -267,7 +269,7 @@ struct usbduxsub {
/* interface structure in 2.6 */
struct usb_interface *interface;
/* comedi device for the interrupt context */
- comedi_device *comedidev;
+ struct comedi_device *comedidev;
/* is it USB_SPEED_HIGH or not? */
short int high_speed;
/* asynchronous command is running */
@@ -361,7 +363,7 @@ static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
* This will cancel a running acquisition operation.
* This is called by comedi but never from inside the driver.
*/
-static int usbdux_ai_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct usbduxsub *this_usbduxsub;
int res = 0;
@@ -390,8 +392,8 @@ static void usbduxsub_ai_IsocIrq(struct urb *urb)
{
int i, err, n;
struct usbduxsub *this_usbduxsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
/* the context variable points to the subdevice */
this_comedidev = urb->context;
@@ -559,7 +561,7 @@ static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
}
/* force unlink, is called by comedi */
-static int usbdux_ao_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ao_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct usbduxsub *this_usbduxsub = dev->private;
int res = 0;
@@ -584,8 +586,8 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
int i, ret;
int8_t *datap;
struct usbduxsub *this_usbduxsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
/* the context variable points to the subdevice */
this_comedidev = urb->context;
@@ -654,7 +656,7 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb)
((uint8_t *) (urb->transfer_buffer))[0] =
s->async->cmd.chanlist_len;
for (i = 0; i < s->async->cmd.chanlist_len; i++) {
- sampl_t temp;
+ short temp;
if (i >= NUMOUTCHANNELS)
break;
@@ -718,31 +720,29 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub)
int errcode = 0;
uint8_t local_transfer_buffer[16];
- if (usbduxsub->probed) {
- /* 7f92 to zero */
- local_transfer_buffer[0] = 0;
- errcode = usb_control_msg(usbduxsub->usbdev,
- /* create a pipe for a control transfer */
- usb_sndctrlpipe(usbduxsub->usbdev, 0),
- /* bRequest, "Firmware" */
- USBDUXSUB_FIRMWARE,
- /* bmRequestType */
- VENDOR_DIR_OUT,
- /* Value */
- USBDUXSUB_CPUCS,
- /* Index */
- 0x0000,
- /* address of the transfer buffer */
- local_transfer_buffer,
- /* Length */
- 1,
- /* Timeout */
- EZTIMEOUT);
- if (errcode < 0) {
- dev_err(&usbduxsub->interface->dev,
- "comedi_: control msg failed (start)\n");
- return errcode;
- }
+ /* 7f92 to zero */
+ local_transfer_buffer[0] = 0;
+ errcode = usb_control_msg(usbduxsub->usbdev,
+ /* create a pipe for a control transfer */
+ usb_sndctrlpipe(usbduxsub->usbdev, 0),
+ /* bRequest, "Firmware" */
+ USBDUXSUB_FIRMWARE,
+ /* bmRequestType */
+ VENDOR_DIR_OUT,
+ /* Value */
+ USBDUXSUB_CPUCS,
+ /* Index */
+ 0x0000,
+ /* address of the transfer buffer */
+ local_transfer_buffer,
+ /* Length */
+ 1,
+ /* Timeout */
+ EZTIMEOUT);
+ if (errcode < 0) {
+ dev_err(&usbduxsub->interface->dev,
+ "comedi_: control msg failed (start)\n");
+ return errcode;
}
return 0;
}
@@ -752,28 +752,27 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub)
int errcode = 0;
uint8_t local_transfer_buffer[16];
- if (usbduxsub->probed) {
- /* 7f92 to one */
- local_transfer_buffer[0] = 1;
- errcode = usb_control_msg(usbduxsub->usbdev,
- usb_sndctrlpipe(usbduxsub->usbdev, 0),
- /* bRequest, "Firmware" */
- USBDUXSUB_FIRMWARE,
- /* bmRequestType */
- VENDOR_DIR_OUT,
- /* Value */
- USBDUXSUB_CPUCS,
- /* Index */
- 0x0000, local_transfer_buffer,
- /* Length */
- 1,
- /* Timeout */
- EZTIMEOUT);
- if (errcode < 0) {
- dev_err(&usbduxsub->interface->dev,
- "comedi_: control msg failed (stop)\n");
- return errcode;
- }
+
+ /* 7f92 to one */
+ local_transfer_buffer[0] = 1;
+ errcode = usb_control_msg(usbduxsub->usbdev,
+ usb_sndctrlpipe(usbduxsub->usbdev, 0),
+ /* bRequest, "Firmware" */
+ USBDUXSUB_FIRMWARE,
+ /* bmRequestType */
+ VENDOR_DIR_OUT,
+ /* Value */
+ USBDUXSUB_CPUCS,
+ /* Index */
+ 0x0000, local_transfer_buffer,
+ /* Length */
+ 1,
+ /* Timeout */
+ EZTIMEOUT);
+ if (errcode < 0) {
+ dev_err(&usbduxsub->interface->dev,
+ "comedi_: control msg failed (stop)\n");
+ return errcode;
}
return 0;
}
@@ -784,13 +783,7 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
{
int errcode;
- if (usbduxsub->probed) {
- dev_dbg(&usbduxsub->interface->dev,
- "comedi%d: usbdux: uploading %d bytes"
- " to addr %d, first byte=%d.\n",
- usbduxsub->comedidev->minor, len,
- startAddr, local_transfer_buffer[0]);
- errcode = usb_control_msg(usbduxsub->usbdev,
+ errcode = usb_control_msg(usbduxsub->usbdev,
usb_sndctrlpipe(usbduxsub->usbdev, 0),
/* brequest, firmware */
USBDUXSUB_FIRMWARE,
@@ -806,16 +799,12 @@ static int usbduxsub_upload(struct usbduxsub *usbduxsub,
len,
/* timeout */
EZTIMEOUT);
- dev_dbg(&usbduxsub->interface->dev,
- "comedi_: result=%d\n", errcode);
- if (errcode < 0) {
- dev_err(&usbduxsub->interface->dev,
- "comedi_: upload failed\n");
- return errcode;
- }
- } else {
- /* no device on the bus for this index */
- return -EFAULT;
+ dev_dbg(&usbduxsub->interface->dev,
+ "comedi_: result=%d\n", errcode);
+ if (errcode < 0) {
+ dev_err(&usbduxsub->interface->dev,
+ "comedi_: upload failed\n");
+ return errcode;
}
return 0;
}
@@ -907,8 +896,8 @@ static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub)
return 0;
}
-static int usbdux_ai_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int usbdux_ai_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0, tmp, i;
unsigned int tmpTimer;
@@ -1127,7 +1116,7 @@ static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command)
return -EFAULT;
}
-static int usbdux_ai_inttrig(comedi_device *dev, comedi_subdevice *s,
+static int usbdux_ai_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
int ret;
@@ -1171,9 +1160,9 @@ static int usbdux_ai_inttrig(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan, range;
int i, ret;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1287,11 +1276,11 @@ static int usbdux_ai_cmd(comedi_device *dev, comedi_subdevice *s)
}
/* Mode 0 is used to get a single conversion on demand */
-static int usbdux_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_ai_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
- lsampl_t one = 0;
+ unsigned int one = 0;
int chan, range;
int err;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1348,8 +1337,8 @@ static int usbdux_ai_insn_read(comedi_device *dev, comedi_subdevice *s,
/************************************/
/* analog out */
-static int usbdux_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_ao_insn_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i;
int chan = CR_CHAN(insn->chanspec);
@@ -1370,8 +1359,8 @@ static int usbdux_ao_insn_read(comedi_device *dev, comedi_subdevice *s,
return i;
}
-static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_ao_insn_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int i, err;
int chan = CR_CHAN(insn->chanspec);
@@ -1420,7 +1409,7 @@ static int usbdux_ao_insn_write(comedi_device *dev, comedi_subdevice *s,
return i;
}
-static int usbdux_ao_inttrig(comedi_device *dev, comedi_subdevice *s,
+static int usbdux_ao_inttrig(struct comedi_device *dev, struct comedi_subdevice *s,
unsigned int trignum)
{
int ret;
@@ -1461,8 +1450,8 @@ static int usbdux_ao_inttrig(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_ao_cmdtest(comedi_device *dev, comedi_subdevice *s,
- comedi_cmd *cmd)
+static int usbdux_ao_cmdtest(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_cmd *cmd)
{
int err = 0, tmp;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1600,9 +1589,9 @@ static int usbdux_ao_cmdtest(comedi_device *dev, comedi_subdevice *s,
return 0;
}
-static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan, gain;
int i, ret;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1708,8 +1697,8 @@ static int usbdux_ao_cmd(comedi_device *dev, comedi_subdevice *s)
return 0;
}
-static int usbdux_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_dio_insn_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
int chan = CR_CHAN(insn->chanspec);
@@ -1739,8 +1728,8 @@ static int usbdux_dio_insn_config(comedi_device *dev, comedi_subdevice *s,
return insn->n;
}
-static int usbdux_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_dio_insn_bits(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
@@ -1786,8 +1775,8 @@ static int usbdux_dio_insn_bits(comedi_device *dev, comedi_subdevice *s,
}
/* reads the 4 counters, only two are used just now */
-static int usbdux_counter_read(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_read(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
int chan = insn->chanspec;
@@ -1820,8 +1809,8 @@ static int usbdux_counter_read(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_counter_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
int err;
@@ -1850,8 +1839,8 @@ static int usbdux_counter_write(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_counter_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_counter_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
/* nothing to do so far */
return 2;
@@ -1894,7 +1883,7 @@ static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink)
}
/* force unlink - is called by comedi */
-static int usbdux_pwm_cancel(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_pwm_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
struct usbduxsub *this_usbduxsub = dev->private;
int res = 0;
@@ -1916,8 +1905,8 @@ static void usbduxsub_pwm_irq(struct urb *urb)
{
int ret;
struct usbduxsub *this_usbduxsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
/* printk(KERN_DEBUG "PWM: IRQ\n"); */
@@ -2007,8 +1996,8 @@ static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub)
return 0;
}
-static int usbdux_pwm_period(comedi_device *dev, comedi_subdevice *s,
- lsampl_t period)
+static int usbdux_pwm_period(struct comedi_device *dev, struct comedi_subdevice *s,
+ unsigned int period)
{
struct usbduxsub *this_usbduxsub = dev->private;
int fx2delay = 255;
@@ -2035,7 +2024,7 @@ static int usbdux_pwm_period(comedi_device *dev, comedi_subdevice *s,
}
/* is called from insn so there's no need to do all the sanity checks */
-static int usbdux_pwm_start(comedi_device *dev, comedi_subdevice *s)
+static int usbdux_pwm_start(struct comedi_device *dev, struct comedi_subdevice *s)
{
int ret, i;
struct usbduxsub *this_usbduxsub = dev->private;
@@ -2067,8 +2056,8 @@ static int usbdux_pwm_start(comedi_device *dev, comedi_subdevice *s)
}
/* generates the bit pattern for PWM with the optional sign bit */
-static int usbdux_pwm_pattern(comedi_device *dev, comedi_subdevice *s,
- int channel, lsampl_t value, lsampl_t sign)
+static int usbdux_pwm_pattern(struct comedi_device *dev, struct comedi_subdevice *s,
+ int channel, unsigned int value, unsigned int sign)
{
struct usbduxsub *this_usbduxsub = dev->private;
int i, szbuf;
@@ -2108,8 +2097,8 @@ static int usbdux_pwm_pattern(comedi_device *dev, comedi_subdevice *s,
return 1;
}
-static int usbdux_pwm_write(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_pwm_write(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
@@ -2133,16 +2122,16 @@ static int usbdux_pwm_write(comedi_device *dev, comedi_subdevice *s,
data[0], 0);
}
-static int usbdux_pwm_read(comedi_device *x1, comedi_subdevice *x2,
- comedi_insn *x3, lsampl_t *x4)
+static int usbdux_pwm_read(struct comedi_device *x1, struct comedi_subdevice *x2,
+ struct comedi_insn *x3, unsigned int *x4)
{
/* not needed */
return -EINVAL;
};
/* switches on/off PWM */
-static int usbdux_pwm_config(comedi_device *dev, comedi_subdevice *s,
- comedi_insn *insn, lsampl_t *data)
+static int usbdux_pwm_config(struct comedi_device *dev, struct comedi_subdevice *s,
+ struct comedi_insn *insn, unsigned int *data)
{
struct usbduxsub *this_usbduxsub = dev->private;
switch (data[0]) {
@@ -2292,13 +2281,13 @@ static unsigned hex2unsigned(char *h)
#define FIRMWARE_MAX_LEN 0x2000
/* taken from David Brownell's fxload and adjusted for this driver */
-static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
+static int read_firmware(struct usbduxsub *usbduxsub, const void *firmwarePtr,
long size)
{
struct device *dev = &usbduxsub->interface->dev;
int i = 0;
unsigned char *fp = (char *)firmwarePtr;
- unsigned char *firmwareBinary = NULL;
+ unsigned char *firmwareBinary;
int res = 0;
int maxAddr = 0;
@@ -2322,6 +2311,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
j++;
if (j >= sizeof(buf)) {
dev_err(dev, "comedi_: bogus firmware file!\n");
+ kfree(firmwareBinary);
return -1;
}
}
@@ -2344,6 +2334,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
if (buf[0] != ':') {
dev_err(dev, "comedi_: upload: not an ihex record: %s",
buf);
+ kfree(firmwareBinary);
return -EFAULT;
}
@@ -2360,6 +2351,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
if (maxAddr >= FIRMWARE_MAX_LEN) {
dev_err(dev, "comedi_: firmware upload goes "
"beyond FX2 RAM boundaries.\n");
+ kfree(firmwareBinary);
return -EFAULT;
}
/* dev_dbg(dev, "comedi_: off=%x, len=%x:\n", off, len); */
@@ -2375,6 +2367,7 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
if (type != 0) {
dev_err(dev, "comedi_: unsupported record type: %u\n",
type);
+ kfree(firmwareBinary);
return -EFAULT;
}
@@ -2395,6 +2388,34 @@ static int read_firmware(struct usbduxsub *usbduxsub, void *firmwarePtr,
return res;
}
+static void usbdux_firmware_request_complete_handler(const struct firmware *fw,
+ void *context)
+{
+ struct usbduxsub *usbduxsub_tmp = context;
+ struct usb_device *usbdev = usbduxsub_tmp->usbdev;
+ int ret;
+
+ if (fw == NULL) {
+ dev_err(&usbdev->dev,
+ "Firmware complete handler without firmware!\n");
+ return;
+ }
+
+ /*
+ * we need to upload the firmware here because fw will be
+ * freed once we've left this function
+ */
+ ret = read_firmware(usbduxsub_tmp, fw->data, fw->size);
+
+ if (ret) {
+ dev_err(&usbdev->dev,
+ "Could not upload firmware (err=%d)\n",
+ ret);
+ return;
+ }
+ comedi_usb_auto_config(usbdev, BOARDNAME);
+}
+
/* allocate memory for the urbs and initialise them */
static int usbduxsub_probe(struct usb_interface *uinterf,
const struct usb_device_id *id)
@@ -2403,6 +2424,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
struct device *dev = &uinterf->dev;
int i;
int index;
+ int ret;
dev_dbg(dev, "comedi_: usbdux_: "
"finding a free structure for the usb-device\n");
@@ -2637,6 +2659,19 @@ static int usbduxsub_probe(struct usb_interface *uinterf,
/* we've reached the bottom of the function */
usbduxsub[index].probed = 1;
up(&start_stop_sem);
+
+ ret = request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_HOTPLUG,
+ "usbdux_firmware.hex",
+ &udev->dev,
+ usbduxsub + index,
+ usbdux_firmware_request_complete_handler);
+
+ if (ret) {
+ dev_err(dev, "Could not load firmware (err=%d)\n", ret);
+ return ret;
+ }
+
dev_info(dev, "comedi_: usbdux%d "
"has been successfully initialised.\n", index);
/* success */
@@ -2658,6 +2693,7 @@ static void usbduxsub_disconnect(struct usb_interface *intf)
"comedi_: BUG! called with wrong ptr!!!\n");
return;
}
+ comedi_usb_auto_unconfig(udev);
down(&start_stop_sem);
down(&usbduxsub_tmp->sem);
tidy_up(usbduxsub_tmp);
@@ -2667,14 +2703,14 @@ static void usbduxsub_disconnect(struct usb_interface *intf)
}
/* is called when comedi-config is called */
-static int usbdux_attach(comedi_device *dev, comedi_devconfig *it)
+static int usbdux_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
int index;
int i;
struct usbduxsub *udev;
- comedi_subdevice *s = NULL;
+ struct comedi_subdevice *s = NULL;
dev->private = NULL;
down(&start_stop_sem);
@@ -2834,7 +2870,7 @@ static int usbdux_attach(comedi_device *dev, comedi_devconfig *it)
return 0;
}
-static int usbdux_detach(comedi_device *dev)
+static int usbdux_detach(struct comedi_device *dev)
{
struct usbduxsub *usbduxsub_tmp;
@@ -2867,26 +2903,13 @@ static int usbdux_detach(comedi_device *dev)
}
/* main driver struct */
-static comedi_driver driver_usbdux = {
+static struct comedi_driver driver_usbdux = {
.driver_name = "usbdux",
.module = THIS_MODULE,
.attach = usbdux_attach,
.detach = usbdux_detach,
};
-static void init_usb_devices(void)
-{
- int index;
-
- /* all devices entries are invalid to begin with */
- /* they will become valid by the probe function */
- /* and then finally by the attach-function */
- for (index = 0; index < NUMUSBDUX; index++) {
- memset(&(usbduxsub[index]), 0x00, sizeof(usbduxsub[index]));
- init_MUTEX(&(usbduxsub[index].sem));
- }
-}
-
/* Table with the USB-devices: just now only testing IDs */
static struct usb_device_id usbduxsub_table[] = {
{USB_DEVICE(0x13d8, 0x0001) },
@@ -2907,18 +2930,17 @@ static struct usb_driver usbduxsub_driver = {
/* Can't use the nice macro as I have also to initialise the USB */
/* subsystem: */
/* registering the usb-system _and_ the comedi-driver */
-static int init_usbdux(void)
+static int __init init_usbdux(void)
{
printk(KERN_INFO KBUILD_MODNAME ": "
DRIVER_VERSION ":" DRIVER_DESC "\n");
- init_usb_devices();
usb_register(&usbduxsub_driver);
comedi_driver_register(&driver_usbdux);
return 0;
}
/* deregistering the comedi driver and the usb-subsystem */
-static void exit_usbdux(void)
+static void __exit exit_usbdux(void)
{
comedi_driver_unregister(&driver_usbdux);
usb_deregister(&usbduxsub_driver);
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c
index 3a00ff0cfc5..2fb64de3f86 100644
--- a/drivers/staging/comedi/drivers/usbduxfast.c
+++ b/drivers/staging/comedi/drivers/usbduxfast.c
@@ -1,33 +1,20 @@
-#define DRIVER_VERSION "v0.99a"
-#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
-#define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
-/*
- comedi/drivers/usbduxfast.c
- Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.com
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
/*
-Driver: usbduxfast
-Description: ITL USB-DUXfast
-Devices: [ITL] USB-DUX (usbduxfast.o)
-Author: Bernd Porr <BerndPorr@f2s.com>
-Updated: 04 Dec 2006
-Status: testing
-*/
+ * Copyright (C) 2004 Bernd Porr, Bernd.Porr@f2s.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
/*
* I must give credit here to Chris Baugher who
@@ -42,12 +29,16 @@ Status: testing
* 0.9: Dropping the first data packet which seems to be from the last transfer.
* Buffer overflows in the FX2 are handed over to comedi.
* 0.92: Dropping now 4 packets. The quad buffer has to be emptied.
- * Added insn command basically for testing. Sample rate is 1MHz/16ch=62.5kHz
+ * Added insn command basically for testing. Sample rate is
+ * 1MHz/16ch=62.5kHz
* 0.99: Ian Abbott pointed out a bug which has been corrected. Thanks!
* 0.99a: added external trigger.
+ * 1.00: added firmware kernel request to the driver which fixed
+ * udev coldplug problem
*/
#include <linux/kernel.h>
+#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -59,536 +50,549 @@ Status: testing
#include "comedi_fc.h"
#include "../comedidev.h"
-// (un)comment this if you want to have debug info.
-//#define CONFIG_COMEDI_DEBUG
-#undef CONFIG_COMEDI_DEBUG
+#define DRIVER_VERSION "v1.0"
+#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com"
+#define DRIVER_DESC "USB-DUXfast, BerndPorr@f2s.com"
#define BOARDNAME "usbduxfast"
-// timeout for the USB-transfer
-#define EZTIMEOUT 30
+/*
+ * timeout for the USB-transfer
+ */
+#define EZTIMEOUT 30
-// constants for "firmware" upload and download
-#define USBDUXFASTSUB_FIRMWARE 0xA0
-#define VENDOR_DIR_IN 0xC0
-#define VENDOR_DIR_OUT 0x40
+/*
+ * constants for "firmware" upload and download
+ */
+#define USBDUXFASTSUB_FIRMWARE 0xA0
+#define VENDOR_DIR_IN 0xC0
+#define VENDOR_DIR_OUT 0x40
-// internal adresses of the 8051 processor
-#define USBDUXFASTSUB_CPUCS 0xE600
+/*
+ * internal adresses of the 8051 processor
+ */
+#define USBDUXFASTSUB_CPUCS 0xE600
-// max lenghth of the transfer-buffer for software upload
-#define TB_LEN 0x2000
+/*
+ * max lenghth of the transfer-buffer for software upload
+ */
+#define TB_LEN 0x2000
-// Input endpoint number
-#define BULKINEP 6
+/*
+ * input endpoint number
+ */
+#define BULKINEP 6
-// Endpoint for the A/D channellist: bulk OUT
-#define CHANNELLISTEP 4
+/*
+ * endpoint for the A/D channellist: bulk OUT
+ */
+#define CHANNELLISTEP 4
-// Number of channels
-#define NUMCHANNELS 32
+/*
+ * number of channels
+ */
+#define NUMCHANNELS 32
-// size of the waveform descriptor
-#define WAVESIZE 0x20
+/*
+ * size of the waveform descriptor
+ */
+#define WAVESIZE 0x20
-// Size of one A/D value
-#define SIZEADIN ((sizeof(int16_t)))
+/*
+ * size of one A/D value
+ */
+#define SIZEADIN (sizeof(int16_t))
-// Size of the input-buffer IN BYTES
-#define SIZEINBUF 512
+/*
+ * size of the input-buffer IN BYTES
+ */
+#define SIZEINBUF 512
-// 16 bytes.
-#define SIZEINSNBUF 512
+/*
+ * 16 bytes
+ */
+#define SIZEINSNBUF 512
-// Size of the buffer for the dux commands
-#define SIZEOFDUXBUFFER 256 // bytes
+/*
+ * size of the buffer for the dux commands in bytes
+ */
+#define SIZEOFDUXBUFFER 256
-// Number of in-URBs which receive the data: min=5
-#define NUMOFINBUFFERSHIGH 10
+/*
+ * number of in-URBs which receive the data: min=5
+ */
+#define NUMOFINBUFFERSHIGH 10
-// Total number of usbduxfast devices
-#define NUMUSBDUXFAST 16
+/*
+ * total number of usbduxfast devices
+ */
+#define NUMUSBDUXFAST 16
-// Number of subdevices
-#define N_SUBDEVICES 1
+/*
+ * number of subdevices
+ */
+#define N_SUBDEVICES 1
-// Analogue in subdevice
-#define SUBDEV_AD 0
+/*
+ * analogue in subdevice
+ */
+#define SUBDEV_AD 0
-// min delay steps for more than one channel
-// basically when the mux gives up. ;-)
-#define MIN_SAMPLING_PERIOD 9 // steps at 30MHz in the FX2
+/*
+ * min delay steps for more than one channel
+ * basically when the mux gives up ;-)
+ *
+ * steps at 30MHz in the FX2
+ */
+#define MIN_SAMPLING_PERIOD 9
-// Max number of 1/30MHz delay steps:
-#define MAX_SAMPLING_PERIOD 500
+/*
+ * max number of 1/30MHz delay steps
+ */
+#define MAX_SAMPLING_PERIOD 500
-// Number of received packets to ignore before we start handing data over to comedi.
-// It's quad buffering and we have to ignore 4 packets.
-#define PACKETS_TO_IGNORE 4
+/*
+ * number of received packets to ignore before we start handing data
+ * over to comedi, it's quad buffering and we have to ignore 4 packets
+ */
+#define PACKETS_TO_IGNORE 4
-/////////////////////////////////////////////
-// comedi constants
-static const comedi_lrange range_usbduxfast_ai_range = { 2, {
- BIP_RANGE(0.75),
- BIP_RANGE(0.5),
- }
+/*
+ * comedi constants
+ */
+static const struct comedi_lrange range_usbduxfast_ai_range = {
+ 2, { BIP_RANGE(0.75), BIP_RANGE(0.5) }
};
/*
* private structure of one subdevice
+ *
+ * this is the structure which holds all the data of this driver
+ * one sub device just now: A/D
*/
-
-// This is the structure which holds all the data of this driver
-// one sub device just now: A/D
-typedef struct {
- // attached?
- int attached;
- // is it associated with a subdevice?
- int probed;
- // pointer to the usb-device
- struct usb_device *usbdev;
- // BULK-transfer handling: urb
- struct urb *urbIn;
+struct usbduxfastsub_s {
+ int attached; /* is attached? */
+ int probed; /* is it associated with a subdevice? */
+ struct usb_device *usbdev; /* pointer to the usb-device */
+ struct urb *urbIn; /* BULK-transfer handling: urb */
int8_t *transfer_buffer;
- // input buffer for single insn
- int16_t *insnBuffer;
- // interface number
- int ifnum;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // interface structure in 2.6
- struct usb_interface *interface;
-#endif
- // comedi device for the interrupt context
- comedi_device *comedidev;
- // asynchronous command is running
- short int ai_cmd_running;
- // continous aquisition
- short int ai_continous;
- // number of samples to aquire
- long int ai_sample_count;
- // commands
- uint8_t *dux_commands;
- // counter which ignores the first buffers
- int ignore;
+ int16_t *insnBuffer; /* input buffer for single insn */
+ int ifnum; /* interface number */
+ struct usb_interface *interface; /* interface structure */
+ struct comedi_device *comedidev; /* comedi device for the interrupt
+ context */
+ short int ai_cmd_running; /* asynchronous command is running */
+ short int ai_continous; /* continous aquisition */
+ long int ai_sample_count; /* number of samples to aquire */
+ uint8_t *dux_commands; /* commands */
+ int ignore; /* counter which ignores the first
+ buffers */
struct semaphore sem;
-} usbduxfastsub_t;
+};
-// The pointer to the private usb-data of the driver
-// is also the private data for the comedi-device.
-// This has to be global as the usb subsystem needs
-// global variables. The other reason is that this
-// structure must be there _before_ any comedi
-// command is issued. The usb subsystem must be
-// initialised before comedi can access it.
-static usbduxfastsub_t usbduxfastsub[NUMUSBDUXFAST];
+/*
+ * The pointer to the private usb-data of the driver
+ * is also the private data for the comedi-device.
+ * This has to be global as the usb subsystem needs
+ * global variables. The other reason is that this
+ * structure must be there _before_ any comedi
+ * command is issued. The usb subsystem must be
+ * initialised before comedi can access it.
+ */
+static struct usbduxfastsub_s usbduxfastsub[NUMUSBDUXFAST];
static DECLARE_MUTEX(start_stop_sem);
-// bulk transfers to usbduxfast
-
+/*
+ * bulk transfers to usbduxfast
+ */
#define SENDADCOMMANDS 0
#define SENDINITEP6 1
-static int send_dux_commands(usbduxfastsub_t * this_usbduxfastsub, int cmd_type)
+static int send_dux_commands(struct usbduxfastsub_s *udfs, int cmd_type)
{
- int result, nsent;
- this_usbduxfastsub->dux_commands[0] = cmd_type;
+ int tmp, nsent;
+
+ udfs->dux_commands[0] = cmd_type;
+
#ifdef CONFIG_COMEDI_DEBUG
- int i;
- printk("comedi%d: usbduxfast: dux_commands: ",
- this_usbduxfastsub->comedidev->minor);
- for (i = 0; i < SIZEOFDUXBUFFER; i++) {
- printk(" %02x", this_usbduxfastsub->dux_commands[i]);
- }
+ printk(KERN_DEBUG "comedi%d: usbduxfast: dux_commands: ",
+ udfs->comedidev->minor);
+ for (tmp = 0; tmp < SIZEOFDUXBUFFER; tmp++)
+ printk(" %02x", udfs->dux_commands[tmp]);
printk("\n");
#endif
- result = usb_bulk_msg(this_usbduxfastsub->usbdev,
- usb_sndbulkpipe(this_usbduxfastsub->usbdev,
- CHANNELLISTEP),
- this_usbduxfastsub->dux_commands, SIZEOFDUXBUFFER,
- &nsent, 10000);
- if (result < 0) {
- printk("comedi%d: could not transmit dux_commands to the usb-device, err=%d\n", this_usbduxfastsub->comedidev->minor, result);
- }
- return result;
+
+ tmp = usb_bulk_msg(udfs->usbdev,
+ usb_sndbulkpipe(udfs->usbdev, CHANNELLISTEP),
+ udfs->dux_commands, SIZEOFDUXBUFFER, &nsent, 10000);
+ if (tmp < 0)
+ printk(KERN_ERR "comedi%d: could not transmit dux_commands to"
+ "the usb-device, err=%d\n", udfs->comedidev->minor, tmp);
+ return tmp;
}
-// Stops the data acquision
-// It should be safe to call this function from any context
-static int usbduxfastsub_unlink_InURBs(usbduxfastsub_t * usbduxfastsub_tmp)
+/*
+ * Stops the data acquision.
+ * It should be safe to call this function from any context.
+ */
+static int usbduxfastsub_unlink_InURBs(struct usbduxfastsub_s *udfs)
{
int j = 0;
int err = 0;
- if (usbduxfastsub_tmp && usbduxfastsub_tmp->urbIn) {
- usbduxfastsub_tmp->ai_cmd_running = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
- j = usb_unlink_urb(usbduxfastsub_tmp->urbIn);
- if (j < 0) {
- err = j;
- }
-#else
- // waits until a running transfer is over
- usb_kill_urb(usbduxfastsub_tmp->urbIn);
+ if (udfs && udfs->urbIn) {
+ udfs->ai_cmd_running = 0;
+ /* waits until a running transfer is over */
+ usb_kill_urb(udfs->urbIn);
j = 0;
-#endif
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi: usbduxfast: unlinked InURB: res=%d\n", j);
+ printk(KERN_DEBUG "comedi: usbduxfast: unlinked InURB: res=%d\n", j);
#endif
return err;
}
-/* This will stop a running acquisition operation */
-// Is called from within this driver from both the
-// interrupt context and from comedi
-static int usbduxfast_ai_stop(usbduxfastsub_t * this_usbduxfastsub,
+/*
+ * This will stop a running acquisition operation.
+ * Is called from within this driver from both the
+ * interrupt context and from comedi.
+ */
+static int usbduxfast_ai_stop(struct usbduxfastsub_s *udfs,
int do_unlink)
{
int ret = 0;
- if (!this_usbduxfastsub) {
- printk("comedi?: usbduxfast_ai_stop: this_usbduxfastsub=NULL!\n");
+ if (!udfs) {
+ printk(KERN_ERR "comedi?: usbduxfast_ai_stop: udfs=NULL!\n");
return -EFAULT;
}
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi: usbduxfast_ai_stop\n");
+ printk(KERN_DEBUG "comedi: usbduxfast_ai_stop\n");
#endif
- this_usbduxfastsub->ai_cmd_running = 0;
+ udfs->ai_cmd_running = 0;
- if (do_unlink) {
- // stop aquistion
- ret = usbduxfastsub_unlink_InURBs(this_usbduxfastsub);
- }
+ if (do_unlink)
+ ret = usbduxfastsub_unlink_InURBs(udfs); /* stop aquistion */
return ret;
}
-// This will cancel a running acquisition operation.
-// This is called by comedi but never from inside the
-// driver.
-static int usbduxfast_ai_cancel(comedi_device * dev, comedi_subdevice * s)
+/*
+ * This will cancel a running acquisition operation.
+ * This is called by comedi but never from inside the driver.
+ */
+static int usbduxfast_ai_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
{
- usbduxfastsub_t *this_usbduxfastsub;
- int res = 0;
+ struct usbduxfastsub_s *udfs;
+ int ret;
- // force unlink of all urbs
+ /* force unlink of all urbs */
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi: usbduxfast_ai_cancel\n");
+ printk(KERN_DEBUG "comedi: usbduxfast_ai_cancel\n");
#endif
- this_usbduxfastsub = dev->private;
- if (!this_usbduxfastsub) {
- printk("comedi: usbduxfast_ai_cancel: this_usbduxfastsub=NULL\n");
+ udfs = dev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi: usbduxfast_ai_cancel: udfs=NULL\n");
return -EFAULT;
}
- down(&this_usbduxfastsub->sem);
- if (!(this_usbduxfastsub->probed)) {
- up(&this_usbduxfastsub->sem);
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
- // unlink
- res = usbduxfast_ai_stop(this_usbduxfastsub, 1);
- up(&this_usbduxfastsub->sem);
+ /* unlink */
+ ret = usbduxfast_ai_stop(udfs, 1);
+ up(&udfs->sem);
- return res;
+ return ret;
}
-// analogue IN
-// interrupt service routine
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void usbduxfastsub_ai_Irq(struct urb *urb)
-#else
+/*
+ * analogue IN
+ * interrupt service routine
+ */
static void usbduxfastsub_ai_Irq(struct urb *urb PT_REGS_ARG)
-#endif
{
int n, err;
- usbduxfastsub_t *this_usbduxfastsub;
- comedi_device *this_comedidev;
- comedi_subdevice *s;
+ struct usbduxfastsub_s *udfs;
+ struct comedi_device *this_comedidev;
+ struct comedi_subdevice *s;
uint16_t *p;
- // sanity checks
- // is the urb there?
+ /* sanity checks - is the urb there? */
if (!urb) {
- printk("comedi_: usbduxfast_: ao int-handler called with urb=NULL!\n");
+ printk(KERN_ERR "comedi_: usbduxfast_: ao int-handler called "
+ "with urb=NULL!\n");
return;
}
- // the context variable points to the subdevice
+ /* the context variable points to the subdevice */
this_comedidev = urb->context;
if (!this_comedidev) {
- printk("comedi_: usbduxfast_: urb context is a NULL pointer!\n");
+ printk(KERN_ERR "comedi_: usbduxfast_: urb context is a NULL "
+ "pointer!\n");
return;
}
- // the private structure of the subdevice is usbduxfastsub_t
- this_usbduxfastsub = this_comedidev->private;
- if (!this_usbduxfastsub) {
- printk("comedi_: usbduxfast_: private of comedi subdev is a NULL pointer!\n");
+ /* the private structure of the subdevice is usbduxfastsub_s */
+ udfs = this_comedidev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi_: usbduxfast_: private of comedi "
+ "subdev is a NULL pointer!\n");
return;
}
- // are we running a command?
- if (unlikely(!(this_usbduxfastsub->ai_cmd_running))) {
- // not running a command
- // do not continue execution if no asynchronous command is running
- // in particular not resubmit
+ /* are we running a command? */
+ if (unlikely(!udfs->ai_cmd_running)) {
+ /*
+ * not running a command
+ * do not continue execution if no asynchronous command
+ * is running in particular not resubmit
+ */
return;
}
- if (unlikely(!(this_usbduxfastsub->attached))) {
- // no comedi device there
+ if (unlikely(!udfs->attached)) {
+ /* no comedi device there */
return;
}
- // subdevice which is the AD converter
+ /* subdevice which is the AD converter */
s = this_comedidev->subdevices + SUBDEV_AD;
- // first we test if something unusual has just happened
+ /* first we test if something unusual has just happened */
switch (urb->status) {
case 0:
break;
- // happens after an unlink command or when the device is plugged out
+ /*
+ * happens after an unlink command or when the device
+ * is plugged out
+ */
case -ECONNRESET:
case -ENOENT:
case -ESHUTDOWN:
case -ECONNABORTED:
- // tell this comedi
+ /* tell this comedi */
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev, s);
- // stop the transfer w/o unlink
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
+ comedi_event(udfs->comedidev, s);
+ /* stop the transfer w/o unlink */
+ usbduxfast_ai_stop(udfs, 0);
return;
default:
- printk("comedi%d: usbduxfast: non-zero urb status received in ai intr context: %d\n", this_usbduxfastsub->comedidev->minor, urb->status);
+ printk("comedi%d: usbduxfast: non-zero urb status received in "
+ "ai intr context: %d\n",
+ udfs->comedidev->minor, urb->status);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev, s);
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
+ comedi_event(udfs->comedidev, s);
+ usbduxfast_ai_stop(udfs, 0);
return;
}
p = urb->transfer_buffer;
- if (!this_usbduxfastsub->ignore) {
- if (!(this_usbduxfastsub->ai_continous)) {
- // not continous, fixed number of samples
+ if (!udfs->ignore) {
+ if (!udfs->ai_continous) {
+ /* not continous, fixed number of samples */
n = urb->actual_length / sizeof(uint16_t);
- if (unlikely(this_usbduxfastsub->ai_sample_count < n)) {
- // we have send only a fraction of the bytes received
+ if (unlikely(udfs->ai_sample_count < n)) {
+ /*
+ * we have send only a fraction of the bytes
+ * received
+ */
cfc_write_array_to_buffer(s,
urb->transfer_buffer,
- this_usbduxfastsub->ai_sample_count *
- sizeof(uint16_t));
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
- // say comedi that the acquistion is over
+ udfs->ai_sample_count
+ * sizeof(uint16_t));
+ usbduxfast_ai_stop(udfs, 0);
+ /* say comedi that the acquistion is over */
s->async->events |= COMEDI_CB_EOA;
- comedi_event(this_usbduxfastsub->comedidev, s);
+ comedi_event(udfs->comedidev, s);
return;
}
- this_usbduxfastsub->ai_sample_count -= n;
+ udfs->ai_sample_count -= n;
}
- // write the full buffer to comedi
- cfc_write_array_to_buffer(s,
- urb->transfer_buffer, urb->actual_length);
+ /* write the full buffer to comedi */
+ cfc_write_array_to_buffer(s, urb->transfer_buffer,
+ urb->actual_length);
- // tell comedi that data is there
- comedi_event(this_usbduxfastsub->comedidev, s);
+ /* tell comedi that data is there */
+ comedi_event(udfs->comedidev, s);
} else {
- // ignore this packet
- this_usbduxfastsub->ignore--;
+ /* ignore this packet */
+ udfs->ignore--;
}
- // command is still running
- // resubmit urb for BULK transfer
- urb->dev = this_usbduxfastsub->usbdev;
+ /*
+ * command is still running
+ * resubmit urb for BULK transfer
+ */
+ urb->dev = udfs->usbdev;
urb->status = 0;
err = usb_submit_urb(urb, GFP_ATOMIC);
if (err < 0) {
- printk("comedi%d: usbduxfast: urb resubm failed: %d",
- this_usbduxfastsub->comedidev->minor, err);
+ printk(KERN_ERR "comedi%d: usbduxfast: urb resubm failed: %d",
+ udfs->comedidev->minor, err);
s->async->events |= COMEDI_CB_EOA;
s->async->events |= COMEDI_CB_ERROR;
- comedi_event(this_usbduxfastsub->comedidev, s);
- usbduxfast_ai_stop(this_usbduxfastsub, 0);
+ comedi_event(udfs->comedidev, s);
+ usbduxfast_ai_stop(udfs, 0);
}
}
-static int usbduxfastsub_start(usbduxfastsub_t * usbduxfastsub)
+static int usbduxfastsub_start(struct usbduxfastsub_s *udfs)
{
- int errcode = 0;
+ int ret;
unsigned char local_transfer_buffer[16];
- if (usbduxfastsub->probed) {
- // 7f92 to zero
- local_transfer_buffer[0] = 0;
- errcode = usb_control_msg(usbduxfastsub->usbdev,
- // create a pipe for a control transfer
- usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
- // bRequest, "Firmware"
- USBDUXFASTSUB_FIRMWARE,
- // bmRequestType
- VENDOR_DIR_OUT,
- // Value
- USBDUXFASTSUB_CPUCS,
- // Index
- 0x0000,
- // address of the transfer buffer
- local_transfer_buffer,
- // Length
- 1,
- // Timeout
- EZTIMEOUT);
- if (errcode < 0) {
- printk("comedi_: usbduxfast_: control msg failed (start)\n");
- return errcode;
- }
+ /* 7f92 to zero */
+ local_transfer_buffer[0] = 0;
+ ret = usb_control_msg(udfs->usbdev,
+ usb_sndctrlpipe(udfs->usbdev, 0),
+ USBDUXFASTSUB_FIRMWARE, /* bRequest, "Firmware" */
+ VENDOR_DIR_OUT, /* bmRequestType */
+ USBDUXFASTSUB_CPUCS, /* Value */
+ 0x0000, /* Index */
+ local_transfer_buffer, /* address of the transfer buffer */
+ 1, /* Length */
+ EZTIMEOUT); /* Timeout */
+ if (ret < 0) {
+ printk("comedi_: usbduxfast_: control msg failed (start)\n");
+ return ret;
}
+
return 0;
}
-static int usbduxfastsub_stop(usbduxfastsub_t * usbduxfastsub)
+static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs)
{
- int errcode = 0;
-
+ int ret;
unsigned char local_transfer_buffer[16];
- if (usbduxfastsub->probed) {
- // 7f92 to one
- local_transfer_buffer[0] = 1;
- errcode = usb_control_msg(usbduxfastsub->usbdev,
- usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
- // bRequest, "Firmware"
- USBDUXFASTSUB_FIRMWARE,
- // bmRequestType
- VENDOR_DIR_OUT,
- // Value
- USBDUXFASTSUB_CPUCS,
- // Index
- 0x0000, local_transfer_buffer,
- // Length
- 1,
- // Timeout
- EZTIMEOUT);
- if (errcode < 0) {
- printk("comedi_: usbduxfast: control msg failed (stop)\n");
- return errcode;
- }
+
+ /* 7f92 to one */
+ local_transfer_buffer[0] = 1;
+ ret = usb_control_msg(udfs->usbdev,
+ usb_sndctrlpipe(udfs->usbdev, 0),
+ USBDUXFASTSUB_FIRMWARE, /* bRequest, "Firmware" */
+ VENDOR_DIR_OUT, /* bmRequestType */
+ USBDUXFASTSUB_CPUCS, /* Value */
+ 0x0000, /* Index */
+ local_transfer_buffer,
+ 1, /* Length */
+ EZTIMEOUT); /* Timeout */
+ if (ret < 0) {
+ printk(KERN_ERR "comedi_: usbduxfast: control msg failed "
+ "(stop)\n");
+ return ret;
}
+
return 0;
}
-static int usbduxfastsub_upload(usbduxfastsub_t * usbduxfastsub,
+static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs,
unsigned char *local_transfer_buffer,
unsigned int startAddr, unsigned int len)
{
- int errcode;
+ int ret;
- if (usbduxfastsub->probed) {
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: uploading %d bytes",
- usbduxfastsub->comedidev->minor, len);
- printk(" to addr %d, first byte=%d.\n",
- startAddr, local_transfer_buffer[0]);
+ printk(KERN_DEBUG "comedi: usbduxfast: uploading %d bytes", len);
+ printk(KERN_DEBUG " to addr %d, first byte=%d.\n",
+ startAddr, local_transfer_buffer[0]);
#endif
- errcode = usb_control_msg(usbduxfastsub->usbdev,
- usb_sndctrlpipe(usbduxfastsub->usbdev, 0),
- // brequest, firmware
- USBDUXFASTSUB_FIRMWARE,
- // bmRequestType
- VENDOR_DIR_OUT,
- // value
- startAddr,
- // index
- 0x0000,
- // our local safe buffer
- local_transfer_buffer,
- // length
- len,
- // timeout
- EZTIMEOUT);
+ ret = usb_control_msg(udfs->usbdev,
+ usb_sndctrlpipe(udfs->usbdev, 0),
+ USBDUXFASTSUB_FIRMWARE, /* brequest, firmware */
+ VENDOR_DIR_OUT, /* bmRequestType */
+ startAddr, /* value */
+ 0x0000, /* index */
+ local_transfer_buffer, /* our local safe buffer */
+ len, /* length */
+ EZTIMEOUT); /* timeout */
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: result=%d\n", errcode);
+ printk(KERN_DEBUG "comedi_: usbduxfast: result=%d\n", ret);
#endif
- if (errcode < 0) {
- printk("comedi_: usbduxfast: uppload failed\n");
- return errcode;
- }
- } else {
- // no device on the bus for this index
- return -EFAULT;
+
+ if (ret < 0) {
+ printk(KERN_ERR "comedi_: usbduxfast: uppload failed\n");
+ return ret;
}
+
return 0;
}
-int firmwareUpload(usbduxfastsub_t * usbduxfastsub,
- unsigned char *firmwareBinary, int sizeFirmware)
+int firmwareUpload(struct usbduxfastsub_s *udfs, unsigned char *firmwareBinary,
+ int sizeFirmware)
{
int ret;
- if (!firmwareBinary) {
+ if (!firmwareBinary)
return 0;
- }
- ret = usbduxfastsub_stop(usbduxfastsub);
+
+ ret = usbduxfastsub_stop(udfs);
if (ret < 0) {
- printk("comedi_: usbduxfast: can not stop firmware\n");
+ printk(KERN_ERR "comedi_: usbduxfast: can not stop firmware\n");
return ret;
}
- ret = usbduxfastsub_upload(usbduxfastsub,
- firmwareBinary, 0, sizeFirmware);
+ ret = usbduxfastsub_upload(udfs, firmwareBinary, 0, sizeFirmware);
if (ret < 0) {
- printk("comedi_: usbduxfast: firmware upload failed\n");
+ printk(KERN_ERR "comedi_: usbduxfast: firmware upload failed\n");
return ret;
}
- ret = usbduxfastsub_start(usbduxfastsub);
+ ret = usbduxfastsub_start(udfs);
if (ret < 0) {
- printk("comedi_: usbduxfast: can not start firmware\n");
+ printk(KERN_ERR "comedi_: usbduxfast: can not start firmware\n");
return ret;
}
+
return 0;
}
-int usbduxfastsub_submit_InURBs(usbduxfastsub_t * usbduxfastsub)
+int usbduxfastsub_submit_InURBs(struct usbduxfastsub_s *udfs)
{
- int errFlag;
+ int ret;
- if (!usbduxfastsub) {
+ if (!udfs)
return -EFAULT;
- }
- usb_fill_bulk_urb(usbduxfastsub->urbIn,
- usbduxfastsub->usbdev,
- usb_rcvbulkpipe(usbduxfastsub->usbdev, BULKINEP),
- usbduxfastsub->transfer_buffer,
- SIZEINBUF, usbduxfastsub_ai_Irq, usbduxfastsub->comedidev);
+
+ usb_fill_bulk_urb(udfs->urbIn, udfs->usbdev,
+ usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+ udfs->transfer_buffer,
+ SIZEINBUF, usbduxfastsub_ai_Irq, udfs->comedidev);
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: submitting in-urb: %x,%x\n",
- usbduxfastsub->comedidev->minor,
- (int)(usbduxfastsub->urbIn->context),
- (int)(usbduxfastsub->urbIn->dev));
+ printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
+ "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
+ udfs->urbIn->dev);
#endif
- errFlag = usb_submit_urb(usbduxfastsub->urbIn, GFP_ATOMIC);
- if (errFlag) {
- printk("comedi_: usbduxfast: ai: usb_submit_urb error %d\n",
- errFlag);
- return errFlag;
+ ret = usb_submit_urb(udfs->urbIn, GFP_ATOMIC);
+ if (ret) {
+ printk(KERN_ERR "comedi_: usbduxfast: ai: usb_submit_urb error"
+ " %d\n", ret);
+ return ret;
}
return 0;
}
-static int usbduxfast_ai_cmdtest(comedi_device * dev,
- comedi_subdevice * s, comedi_cmd * cmd)
+static int usbduxfast_ai_cmdtest(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_cmd *cmd)
{
int err = 0, stop_mask = 0;
- long int steps, tmp = 0;
+ long int steps, tmp;
int minSamplPer;
- usbduxfastsub_t *this_usbduxfastsub = dev->private;
- if (!(this_usbduxfastsub->probed)) {
+ struct usbduxfastsub_s *udfs = dev->private;
+
+ if (!udfs->probed)
return -ENODEV;
- }
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
- printk("comedi%d: usbduxfast: convert_arg=%u scan_begin_arg=%u\n",
- dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
+ printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmdtest\n", dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast: convert_arg=%u "
+ "scan_begin_arg=%u\n",
+ dev->minor, cmd->convert_arg, cmd->scan_begin_arg);
#endif
/* step 1: make sure trigger sources are trivially valid */
@@ -621,7 +625,9 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
if (err)
return 1;
- /* step 2: make sure trigger sources are unique and mutually compatible */
+ /*
+ * step 2: make sure trigger sources are unique and mutually compatible
+ */
if (cmd->start_src != TRIG_NOW &&
cmd->start_src != TRIG_EXT && cmd->start_src != TRIG_INT)
@@ -636,7 +642,7 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
cmd->stop_src != TRIG_EXT && cmd->stop_src != TRIG_NONE)
err++;
- // can't have external stop and start triggers at once
+ /* can't have external stop and start triggers at once */
if (cmd->start_src == TRIG_EXT && cmd->stop_src == TRIG_EXT)
err++;
@@ -650,29 +656,28 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
err++;
}
- if (!cmd->chanlist_len) {
+ if (!cmd->chanlist_len)
err++;
- }
+
if (cmd->scan_end_arg != cmd->chanlist_len) {
cmd->scan_end_arg = cmd->chanlist_len;
err++;
}
- if (cmd->chanlist_len == 1) {
+ if (cmd->chanlist_len == 1)
minSamplPer = 1;
- } else {
+ else
minSamplPer = MIN_SAMPLING_PERIOD;
- }
if (cmd->convert_src == TRIG_TIMER) {
steps = cmd->convert_arg * 30;
- if (steps < (minSamplPer * 1000)) {
+ if (steps < (minSamplPer * 1000))
steps = minSamplPer * 1000;
- }
- if (steps > (MAX_SAMPLING_PERIOD * 1000)) {
+
+ if (steps > (MAX_SAMPLING_PERIOD * 1000))
steps = MAX_SAMPLING_PERIOD * 1000;
- }
- // calc arg again
+
+ /* calc arg again */
tmp = steps / 30;
if (cmd->convert_arg != tmp) {
cmd->convert_arg = tmp;
@@ -680,10 +685,10 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
}
}
- if (cmd->scan_begin_src == TRIG_TIMER) {
+ if (cmd->scan_begin_src == TRIG_TIMER)
err++;
- }
- // stop source
+
+ /* stop source */
switch (cmd->stop_src) {
case TRIG_COUNT:
if (!cmd->stop_arg) {
@@ -697,7 +702,10 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
err++;
}
break;
- // TRIG_EXT doesn't care since it doesn't trigger off a numbered channel
+ /*
+ * TRIG_EXT doesn't care since it doesn't trigger
+ * off a numbered channel
+ */
default:
break;
}
@@ -711,600 +719,688 @@ static int usbduxfast_ai_cmdtest(comedi_device * dev,
}
-static int usbduxfast_ai_inttrig(comedi_device * dev,
- comedi_subdevice * s, unsigned int trignum)
+static int usbduxfast_ai_inttrig(struct comedi_device *dev,
+ struct comedi_subdevice *s, unsigned int trignum)
{
int ret;
- usbduxfastsub_t *this_usbduxfastsub = dev->private;
- if (!this_usbduxfastsub) {
+ struct usbduxfastsub_s *udfs = dev->private;
+
+ if (!udfs)
return -EFAULT;
- }
- down(&this_usbduxfastsub->sem);
- if (!(this_usbduxfastsub->probed)) {
- up(&this_usbduxfastsub->sem);
+
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast_ai_inttrig\n", dev->minor);
#endif
if (trignum != 0) {
- printk("comedi%d: usbduxfast_ai_inttrig: invalid trignum\n",
- dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: invalid"
+ " trignum\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
- if (!(this_usbduxfastsub->ai_cmd_running)) {
- this_usbduxfastsub->ai_cmd_running = 1;
- ret = usbduxfastsub_submit_InURBs(this_usbduxfastsub);
+ if (!udfs->ai_cmd_running) {
+ udfs->ai_cmd_running = 1;
+ ret = usbduxfastsub_submit_InURBs(udfs);
if (ret < 0) {
- printk("comedi%d: usbduxfast_ai_inttrig: urbSubmit: err=%d\n", dev->minor, ret);
- this_usbduxfastsub->ai_cmd_running = 0;
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast_ai_inttrig: "
+ "urbSubmit: err=%d\n", dev->minor, ret);
+ udfs->ai_cmd_running = 0;
+ up(&udfs->sem);
return ret;
}
s->async->inttrig = NULL;
} else {
- printk("comedi%d: ai_inttrig but acqu is already running\n",
- dev->minor);
+ printk(KERN_ERR "comedi%d: ai_inttrig but acqu is already"
+ " running\n", dev->minor);
}
- up(&this_usbduxfastsub->sem);
+ up(&udfs->sem);
return 1;
}
-// offsets for the GPIF bytes
-// the first byte is the command byte
-#define LENBASE 1+0x00
-#define OPBASE 1+0x08
-#define OUTBASE 1+0x10
-#define LOGBASE 1+0x18
+/*
+ * offsets for the GPIF bytes
+ * the first byte is the command byte
+ */
+#define LENBASE (1+0x00)
+#define OPBASE (1+0x08)
+#define OUTBASE (1+0x10)
+#define LOGBASE (1+0x18)
-static int usbduxfast_ai_cmd(comedi_device * dev, comedi_subdevice * s)
+static int usbduxfast_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s)
{
- comedi_cmd *cmd = &s->async->cmd;
+ struct comedi_cmd *cmd = &s->async->cmd;
unsigned int chan, gain, rngmask = 0xff;
int i, j, ret;
- usbduxfastsub_t *this_usbduxfastsub = dev->private;
+ struct usbduxfastsub_s *udfs;
int result;
long steps, steps_tmp;
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast_ai_cmd\n", dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast_ai_cmd\n", dev->minor);
#endif
- if (!this_usbduxfastsub) {
+ udfs = dev->private;
+ if (!udfs)
return -EFAULT;
- }
- down(&this_usbduxfastsub->sem);
- if (!(this_usbduxfastsub->probed)) {
- up(&this_usbduxfastsub->sem);
+
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
- if (this_usbduxfastsub->ai_cmd_running) {
- printk("comedi%d: ai_cmd not possible. Another ai_cmd is running.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ if (udfs->ai_cmd_running) {
+ printk(KERN_ERR "comedi%d: ai_cmd not possible. Another ai_cmd"
+ " is running.\n", dev->minor);
+ up(&udfs->sem);
return -EBUSY;
}
- // set current channel of the running aquisition to zero
+ /* set current channel of the running aquisition to zero */
s->async->cur_chan = 0;
- // ignore the first buffers from the device if there is an error condition
- this_usbduxfastsub->ignore = PACKETS_TO_IGNORE;
+ /*
+ * ignore the first buffers from the device if there
+ * is an error condition
+ */
+ udfs->ignore = PACKETS_TO_IGNORE;
if (cmd->chanlist_len > 0) {
gain = CR_RANGE(cmd->chanlist[0]);
for (i = 0; i < cmd->chanlist_len; ++i) {
chan = CR_CHAN(cmd->chanlist[i]);
if (chan != i) {
- printk("comedi%d: cmd is accepting only consecutive channels.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: cmd is accepting "
+ "only consecutive channels.\n",
+ dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
if ((gain != CR_RANGE(cmd->chanlist[i]))
&& (cmd->chanlist_len > 3)) {
- printk("comedi%d: the gain must be the same for all channels.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: the gain must be"
+ " the same for all channels.\n",
+ dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
if (i >= NUMCHANNELS) {
- printk("comedi%d: channel list too long\n",
- dev->minor);
+ printk(KERN_ERR "comedi%d: channel list too"
+ " long\n", dev->minor);
break;
}
}
}
steps = 0;
if (cmd->scan_begin_src == TRIG_TIMER) {
- printk("comedi%d: usbduxfast: scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: "
+ "scan_begin_src==TRIG_TIMER not valid.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
- if (cmd->convert_src == TRIG_TIMER) {
+ if (cmd->convert_src == TRIG_TIMER)
steps = (cmd->convert_arg * 30) / 1000;
- }
+
if ((steps < MIN_SAMPLING_PERIOD) && (cmd->chanlist_len != 1)) {
- printk("comedi%d: usbduxfast: ai_cmd: steps=%ld, scan_begin_arg=%d. Not properly tested by cmdtest?\n", dev->minor, steps, cmd->scan_begin_arg);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: steps=%ld, "
+ "scan_begin_arg=%d. Not properly tested by cmdtest?\n",
+ dev->minor, steps, cmd->scan_begin_arg);
+ up(&udfs->sem);
return -EINVAL;
}
if (steps > MAX_SAMPLING_PERIOD) {
- printk("comedi%d: usbduxfast: ai_cmd: sampling rate too low.\n",
- dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: sampling rate "
+ "too low.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
if ((cmd->start_src == TRIG_EXT) && (cmd->chanlist_len != 1)
&& (cmd->chanlist_len != 16)) {
- printk("comedi%d: usbduxfast: ai_cmd: TRIG_EXT only with 1 or 16 channels possible.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: usbduxfast: ai_cmd: TRIG_EXT only"
+ " with 1 or 16 channels possible.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: steps=%ld, convert_arg=%u, ai_timer=%u\n",
- dev->minor,
- steps, cmd->convert_arg, this_usbduxfastsub->ai_timer);
+ printk(KERN_DEBUG "comedi%d: usbduxfast: steps=%ld, convert_arg=%u\n",
+ dev->minor, steps, cmd->convert_arg);
#endif
switch (cmd->chanlist_len) {
- // one channel
case 1:
+ /*
+ * one channel
+ */
+
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // for external trigger: looping in this state until the RDY0 pin
- // becomes zero
- if (cmd->start_src == TRIG_EXT) { // we loop here until ready has been set
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 0x01; // branch back to state 0
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 0] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0x00; // RDY0 = 0
- } else { // we just proceed to state 1
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 0] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+ /*
+ * for external trigger: looping in this state until
+ * the RDY0 pin becomes zero
+ */
+
+ /* we loop here until ready has been set */
+ if (cmd->start_src == TRIG_EXT) {
+ /* branch back to state 0 */
+ udfs->dux_commands[LENBASE+0] = 0x01;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+0] = 0x01;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ /* RDY0 = 0 */
+ udfs->dux_commands[LOGBASE+0] = 0x00;
+ } else { /* we just proceed to state 1 */
+ udfs->dux_commands[LENBASE+0] = 1;
+ udfs->dux_commands[OPBASE+0] = 0;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
}
if (steps < MIN_SAMPLING_PERIOD) {
- // for fast single channel aqu without mux
+ /* for fast single channel aqu without mux */
if (steps <= 1) {
- // we just stay here at state 1 and rexecute the same state
- // this gives us 30MHz sampling rate
- this_usbduxfastsub->dux_commands[LENBASE + 1] = 0x89; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x03; // deceision state with data
- this_usbduxfastsub->dux_commands[OUTBASE + 1] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0xFF; // doesn't matter
+ /*
+ * we just stay here at state 1 and rexecute
+ * the same state this gives us 30MHz sampling
+ * rate
+ */
+
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+1] = 0x89;
+ /* deceision state with data */
+ udfs->dux_commands[OPBASE+1] = 0x03;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+1] = 0xFF;
} else {
- // we loop through two states: data and delay: max rate is 15Mhz
- this_usbduxfastsub->dux_commands[LENBASE + 1] =
- steps - 1;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 1] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0; // doesn't matter
-
- this_usbduxfastsub->dux_commands[LENBASE + 2] = 0x09; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 2] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0xFF; // doesn't matter
+ /*
+ * we loop through two states: data and delay
+ * max rate is 15MHz
+ */
+ udfs->dux_commands[LENBASE+1] = steps - 1;
+ /* data */
+ udfs->dux_commands[OPBASE+1] = 0x02;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+1] = 0;
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+2] = 0x09;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+2] = 0x01;
+ udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+2] = 0xFF;
}
} else {
- // we loop through 3 states: 2x delay and 1x data. This gives a min
- // sampling rate of 60kHz.
+ /*
+ * we loop through 3 states: 2x delay and 1x data
+ * this gives a min sampling rate of 60kHz
+ */
- // we have 1 state with duration 1
+ /* we have 1 state with duration 1 */
steps = steps - 1;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 1] =
- steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 1] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 2] =
- steps - steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 2] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- // get the data and branch back
- this_usbduxfastsub->dux_commands[LENBASE + 3] = 0x09; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 3] = 0x03; // deceision state w data
- this_usbduxfastsub->dux_commands[OUTBASE + 3] =
- 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0xFF; // doesn't matter
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+1] = steps / 2;
+ udfs->dux_commands[OPBASE+1] = 0;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+2] = steps - steps / 2;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ /* get the data and branch back */
+
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+3] = 0x09;
+ /* deceision state w data */
+ udfs->dux_commands[OPBASE+3] = 0x03;
+ udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+3] = 0xFF;
}
break;
case 2:
- // two channels
- // commit data to the FIFO
+ /*
+ * two channels
+ * commit data to the FIFO
+ */
+
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
- // we have 1 state with duration 1: state 0
+ udfs->dux_commands[LENBASE+0] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+0] = 0x02;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
+
+ /* we have 1 state with duration 1: state 0 */
steps_tmp = steps - 1;
if (CR_RANGE(cmd->chanlist[1]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 1] = steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFE & rngmask; //count
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 2] =
- steps_tmp - steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 3] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 3] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
-
- // we have 2 states with duration 1: step 6 and the IDLE state
+
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+1] = steps_tmp / 2;
+ udfs->dux_commands[OPBASE+1] = 0;
+ /* count */
+ udfs->dux_commands[OUTBASE+1] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+2] = steps_tmp - steps_tmp / 2;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ udfs->dux_commands[LENBASE+3] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+3] = 0x02;
+ udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+3] = 0;
+
+ /*
+ * we have 2 states with duration 1: step 6 and
+ * the IDLE state
+ */
steps_tmp = steps - 2;
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 4] = steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 4] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 4] = (0xFF - 0x02) & rngmask; //reset
- this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 5] =
- steps_tmp - steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 5] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 6] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 6] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 6] = 0;
+
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
+ udfs->dux_commands[OPBASE+4] = 0;
+ /* reset */
+ udfs->dux_commands[OUTBASE+4] = (0xFF - 0x02) & rngmask;
+ udfs->dux_commands[LOGBASE+4] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+5] = steps_tmp - steps_tmp / 2;
+ udfs->dux_commands[OPBASE+5] = 0;
+ udfs->dux_commands[OUTBASE+5] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+5] = 0;
+
+ udfs->dux_commands[LENBASE+6] = 1;
+ udfs->dux_commands[OPBASE+6] = 0;
+ udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+6] = 0;
break;
case 3:
- // three channels
+ /*
+ * three channels
+ */
for (j = 0; j < 1; j++) {
if (CR_RANGE(cmd->chanlist[j]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // commit data to the FIFO and do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + j * 2] =
- steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + j * 2] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + j * 2] = 0xFF & rngmask; // no change
- this_usbduxfastsub->dux_commands[LOGBASE + j * 2] = 0;
+ /*
+ * commit data to the FIFO and do the first part
+ * of the delay
+ */
+ udfs->dux_commands[LENBASE+j*2] = steps / 2;
+ /* data */
+ udfs->dux_commands[OPBASE+j*2] = 0x02;
+ /* no change */
+ udfs->dux_commands[OUTBASE+j*2] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+j*2] = 0;
if (CR_RANGE(cmd->chanlist[j + 1]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the second part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + j * 2 + 1] =
- steps - steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + j * 2 + 1] = 0; // no data
- this_usbduxfastsub->dux_commands[OUTBASE + j * 2 + 1] = 0xFE & rngmask; //count
- this_usbduxfastsub->dux_commands[LOGBASE + j * 2 + 1] =
- 0;
+
+ /* do the second part of the delay */
+ udfs->dux_commands[LENBASE+j*2+1] = steps - steps / 2;
+ /* no data */
+ udfs->dux_commands[OPBASE+j*2+1] = 0;
+ /* count */
+ udfs->dux_commands[OUTBASE+j*2+1] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+j*2+1] = 0;
}
- // 2 steps with duration 1: the idele step and step 6:
+ /* 2 steps with duration 1: the idele step and step 6: */
steps_tmp = steps - 2;
- // commit data to the FIFO and do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 4] = steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 4] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFF & rngmask; // no change
- this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
+
+ /* commit data to the FIFO and do the first part of the delay */
+ udfs->dux_commands[LENBASE+4] = steps_tmp / 2;
+ /* data */
+ udfs->dux_commands[OPBASE+4] = 0x02;
+ udfs->dux_commands[OUTBASE+4] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+4] = 0;
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // do the second part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 5] =
- steps_tmp - steps_tmp / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 5] = 0; // no data
- this_usbduxfastsub->dux_commands[OUTBASE + 5] = (0xFF - 0x02) & rngmask; // reset
- this_usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 6] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 6] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 6] = 0;
+
+ /* do the second part of the delay */
+ udfs->dux_commands[LENBASE+5] = steps_tmp - steps_tmp / 2;
+ /* no data */
+ udfs->dux_commands[OPBASE+5] = 0;
+ /* reset */
+ udfs->dux_commands[OUTBASE+5] = (0xFF - 0x02) & rngmask;
+ udfs->dux_commands[LOGBASE+5] = 0;
+
+ udfs->dux_commands[LENBASE+6] = 1;
+ udfs->dux_commands[OPBASE+6] = 0;
+ udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+6] = 0;
case 16:
if (CR_RANGE(cmd->chanlist[0]) > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- if (cmd->start_src == TRIG_EXT) { // we loop here until ready has been set
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 0x01; // branch back to state 0
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 0] = (0xFF - 0x02) & rngmask; // reset
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0x00; // RDY0 = 0
- } else { // we just proceed to state 1
- this_usbduxfastsub->dux_commands[LENBASE + 0] = 255; // 30us reset pulse
- this_usbduxfastsub->dux_commands[OPBASE + 0] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 0] = (0xFF - 0x02) & rngmask; // reset
- this_usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+
+ if (cmd->start_src == TRIG_EXT) {
+ /*
+ * we loop here until ready has been set
+ */
+
+ /* branch back to state 0 */
+ udfs->dux_commands[LENBASE+0] = 0x01;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+0] = 0x01;
+ /* reset */
+ udfs->dux_commands[OUTBASE+0] = (0xFF-0x02) & rngmask;
+ /* RDY0 = 0 */
+ udfs->dux_commands[LOGBASE+0] = 0x00;
+ } else {
+ /*
+ * we just proceed to state 1
+ */
+
+ /* 30us reset pulse */
+ udfs->dux_commands[LENBASE+0] = 255;
+ udfs->dux_commands[OPBASE+0] = 0;
+ /* reset */
+ udfs->dux_commands[OUTBASE+0] = (0xFF-0x02) & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
}
- // commit data to the FIFO
- this_usbduxfastsub->dux_commands[LENBASE + 1] = 1;
- this_usbduxfastsub->dux_commands[OPBASE + 1] = 0x02; // data
- this_usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
+ /* commit data to the FIFO */
+ udfs->dux_commands[LENBASE+1] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+1] = 0x02;
+ udfs->dux_commands[OUTBASE+1] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
- // we have 2 states with duration 1
+ /* we have 2 states with duration 1 */
steps = steps - 2;
- // do the first part of the delay
- this_usbduxfastsub->dux_commands[LENBASE + 2] = steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- // and the second part
- this_usbduxfastsub->dux_commands[LENBASE + 3] =
- steps - steps / 2;
- this_usbduxfastsub->dux_commands[OPBASE + 3] = 0;
- this_usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
-
- this_usbduxfastsub->dux_commands[LENBASE + 4] = 0x09; // branch back to state 1
- this_usbduxfastsub->dux_commands[OPBASE + 4] = 0x01; // deceision state w/o data
- this_usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFF & rngmask;
- this_usbduxfastsub->dux_commands[LOGBASE + 4] = 0xFF; // doesn't matter
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+2] = steps / 2;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ /* and the second part */
+ udfs->dux_commands[LENBASE+3] = steps - steps / 2;
+ udfs->dux_commands[OPBASE+3] = 0;
+ udfs->dux_commands[OUTBASE+3] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+3] = 0;
+
+ /* branch back to state 1 */
+ udfs->dux_commands[LENBASE+4] = 0x09;
+ /* deceision state w/o data */
+ udfs->dux_commands[OPBASE+4] = 0x01;
+ udfs->dux_commands[OUTBASE+4] = 0xFF & rngmask;
+ /* doesn't matter */
+ udfs->dux_commands[LOGBASE+4] = 0xFF;
break;
default:
- printk("comedi %d: unsupported combination of channels\n",
- dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi %d: unsupported combination of "
+ "channels\n", dev->minor);
+ up(&udfs->sem);
return -EFAULT;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi %d: sending commands to the usb device\n", dev->minor);
+ printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
+ dev->minor);
#endif
- // 0 means that the AD commands are sent
- result = send_dux_commands(this_usbduxfastsub, SENDADCOMMANDS);
+ /* 0 means that the AD commands are sent */
+ result = send_dux_commands(udfs, SENDADCOMMANDS);
if (result < 0) {
- printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: adc command could not be submitted."
+ "Aborting...\n", dev->minor);
+ up(&udfs->sem);
return result;
}
if (cmd->stop_src == TRIG_COUNT) {
- this_usbduxfastsub->ai_sample_count =
- (cmd->stop_arg) * (cmd->scan_end_arg);
- if (usbduxfastsub->ai_sample_count < 1) {
- printk("comedi%d: (cmd->stop_arg)*(cmd->scan_end_arg)<1, aborting.\n", dev->minor);
- up(&this_usbduxfastsub->sem);
+ udfs->ai_sample_count = cmd->stop_arg * cmd->scan_end_arg;
+ if (udfs->ai_sample_count < 1) {
+ printk(KERN_ERR "comedi%d: "
+ "(cmd->stop_arg)*(cmd->scan_end_arg)<1, "
+ "aborting.\n", dev->minor);
+ up(&udfs->sem);
return -EFAULT;
}
- this_usbduxfastsub->ai_continous = 0;
+ udfs->ai_continous = 0;
} else {
- // continous aquisition
- this_usbduxfastsub->ai_continous = 1;
- this_usbduxfastsub->ai_sample_count = 0;
+ /* continous aquisition */
+ udfs->ai_continous = 1;
+ udfs->ai_sample_count = 0;
}
if ((cmd->start_src == TRIG_NOW) || (cmd->start_src == TRIG_EXT)) {
- // enable this acquisition operation
- this_usbduxfastsub->ai_cmd_running = 1;
- ret = usbduxfastsub_submit_InURBs(this_usbduxfastsub);
+ /* enable this acquisition operation */
+ udfs->ai_cmd_running = 1;
+ ret = usbduxfastsub_submit_InURBs(udfs);
if (ret < 0) {
- this_usbduxfastsub->ai_cmd_running = 0;
- // fixme: unlink here??
- up(&this_usbduxfastsub->sem);
+ udfs->ai_cmd_running = 0;
+ /* fixme: unlink here?? */
+ up(&udfs->sem);
return ret;
}
s->async->inttrig = NULL;
} else {
- /* TRIG_INT */
- // don't enable the acquision operation
- // wait for an internal signal
+ /*
+ * TRIG_INT
+ * don't enable the acquision operation
+ * wait for an internal signal
+ */
s->async->inttrig = usbduxfast_ai_inttrig;
}
- up(&this_usbduxfastsub->sem);
+ up(&udfs->sem);
return 0;
}
-/* Mode 0 is used to get a single conversion on demand */
-static int usbduxfast_ai_insn_read(comedi_device * dev,
- comedi_subdevice * s, comedi_insn * insn, lsampl_t * data)
+/*
+ * Mode 0 is used to get a single conversion on demand.
+ */
+static int usbduxfast_ai_insn_read(struct comedi_device *dev,
+ struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
int i, j, n, actual_length;
int chan, range, rngmask;
int err;
- usbduxfastsub_t *usbduxfastsub = dev->private;
+ struct usbduxfastsub_s *udfs;
- if (!usbduxfastsub) {
- printk("comedi%d: ai_insn_read: no usb dev.\n", dev->minor);
+ udfs = dev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi%d: ai_insn_read: no usb dev.\n",
+ dev->minor);
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n",
- dev->minor, insn->n, insn->subdev);
+ printk(KERN_DEBUG "comedi%d: ai_insn_read, insn->n=%d, "
+ "insn->subdev=%d\n", dev->minor, insn->n, insn->subdev);
#endif
- down(&usbduxfastsub->sem);
- if (!(usbduxfastsub->probed)) {
- up(&usbduxfastsub->sem);
+ down(&udfs->sem);
+ if (!udfs->probed) {
+ up(&udfs->sem);
return -ENODEV;
}
- if (usbduxfastsub->ai_cmd_running) {
- printk("comedi%d: ai_insn_read not possible. Async Command is running.\n", dev->minor);
- up(&usbduxfastsub->sem);
+ if (udfs->ai_cmd_running) {
+ printk(KERN_ERR "comedi%d: ai_insn_read not possible. Async "
+ "Command is running.\n", dev->minor);
+ up(&udfs->sem);
return -EBUSY;
}
- // sample one channel
+ /* sample one channel */
chan = CR_CHAN(insn->chanspec);
range = CR_RANGE(insn->chanspec);
- // set command for the first channel
+ /* set command for the first channel */
if (range > 0)
rngmask = 0xff - 0x04;
else
rngmask = 0xff;
- // commit data to the FIFO
- usbduxfastsub->dux_commands[LENBASE + 0] = 1;
- usbduxfastsub->dux_commands[OPBASE + 0] = 0x02; // data
- usbduxfastsub->dux_commands[OUTBASE + 0] = 0xFF & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
-
- // do the first part of the delay
- usbduxfastsub->dux_commands[LENBASE + 1] = 12;
- usbduxfastsub->dux_commands[OPBASE + 1] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 1] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 1] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 2] = 1;
- usbduxfastsub->dux_commands[OPBASE + 2] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 2] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 2] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 3] = 1;
- usbduxfastsub->dux_commands[OPBASE + 3] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 3] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 3] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 4] = 1;
- usbduxfastsub->dux_commands[OPBASE + 4] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 4] = 0xFE & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 4] = 0;
-
- // second part
- usbduxfastsub->dux_commands[LENBASE + 5] = 12;
- usbduxfastsub->dux_commands[OPBASE + 5] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 5] = 0xFF & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 5] = 0;
-
- usbduxfastsub->dux_commands[LENBASE + 6] = 1;
- usbduxfastsub->dux_commands[OPBASE + 6] = 0;
- usbduxfastsub->dux_commands[OUTBASE + 6] = 0xFF & rngmask;
- usbduxfastsub->dux_commands[LOGBASE + 0] = 0;
+
+ /* commit data to the FIFO */
+ udfs->dux_commands[LENBASE+0] = 1;
+ /* data */
+ udfs->dux_commands[OPBASE+0] = 0x02;
+ udfs->dux_commands[OUTBASE+0] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
+
+ /* do the first part of the delay */
+ udfs->dux_commands[LENBASE+1] = 12;
+ udfs->dux_commands[OPBASE+1] = 0;
+ udfs->dux_commands[OUTBASE+1] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+1] = 0;
+
+ udfs->dux_commands[LENBASE+2] = 1;
+ udfs->dux_commands[OPBASE+2] = 0;
+ udfs->dux_commands[OUTBASE+2] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+2] = 0;
+
+ udfs->dux_commands[LENBASE+3] = 1;
+ udfs->dux_commands[OPBASE+3] = 0;
+ udfs->dux_commands[OUTBASE+3] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+3] = 0;
+
+ udfs->dux_commands[LENBASE+4] = 1;
+ udfs->dux_commands[OPBASE+4] = 0;
+ udfs->dux_commands[OUTBASE+4] = 0xFE & rngmask;
+ udfs->dux_commands[LOGBASE+4] = 0;
+
+ /* second part */
+ udfs->dux_commands[LENBASE+5] = 12;
+ udfs->dux_commands[OPBASE+5] = 0;
+ udfs->dux_commands[OUTBASE+5] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+5] = 0;
+
+ udfs->dux_commands[LENBASE+6] = 1;
+ udfs->dux_commands[OPBASE+6] = 0;
+ udfs->dux_commands[OUTBASE+6] = 0xFF & rngmask;
+ udfs->dux_commands[LOGBASE+0] = 0;
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi %d: sending commands to the usb device\n", dev->minor);
+ printk(KERN_DEBUG "comedi %d: sending commands to the usb device\n",
+ dev->minor);
#endif
- // 0 means that the AD commands are sent
- err = send_dux_commands(usbduxfastsub, SENDADCOMMANDS);
+ /* 0 means that the AD commands are sent */
+ err = send_dux_commands(udfs, SENDADCOMMANDS);
if (err < 0) {
- printk("comedi%d: adc command could not be submitted. Aborting...\n", dev->minor);
- up(&usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: adc command could not be submitted."
+ "Aborting...\n", dev->minor);
+ up(&udfs->sem);
return err;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: submitting in-urb: %x,%x\n",
- usbduxfastsub->comedidev->minor,
- (int)(usbduxfastsub->urbIn->context),
- (int)(usbduxfastsub->urbIn->dev));
+ printk(KERN_DEBUG "comedi%d: usbduxfast: submitting in-urb: "
+ "0x%p,0x%p\n", udfs->comedidev->minor, udfs->urbIn->context,
+ udfs->urbIn->dev);
#endif
for (i = 0; i < PACKETS_TO_IGNORE; i++) {
- err = usb_bulk_msg(usbduxfastsub->usbdev,
- usb_rcvbulkpipe(usbduxfastsub->usbdev,
- BULKINEP),
- usbduxfastsub->transfer_buffer, SIZEINBUF,
+ err = usb_bulk_msg(udfs->usbdev,
+ usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+ udfs->transfer_buffer, SIZEINBUF,
&actual_length, 10000);
if (err < 0) {
- printk("comedi%d: insn timeout. No data.\n",
+ printk(KERN_ERR "comedi%d: insn timeout. No data.\n",
dev->minor);
- up(&usbduxfastsub->sem);
+ up(&udfs->sem);
return err;
}
}
- // data points
+ /* data points */
for (i = 0; i < insn->n;) {
- err = usb_bulk_msg(usbduxfastsub->usbdev,
- usb_rcvbulkpipe(usbduxfastsub->usbdev,
- BULKINEP),
- usbduxfastsub->transfer_buffer, SIZEINBUF,
+ err = usb_bulk_msg(udfs->usbdev,
+ usb_rcvbulkpipe(udfs->usbdev, BULKINEP),
+ udfs->transfer_buffer, SIZEINBUF,
&actual_length, 10000);
if (err < 0) {
- printk("comedi%d: insn data error: %d\n",
+ printk(KERN_ERR "comedi%d: insn data error: %d\n",
dev->minor, err);
- up(&usbduxfastsub->sem);
+ up(&udfs->sem);
return err;
}
n = actual_length / sizeof(uint16_t);
if ((n % 16) != 0) {
- printk("comedi%d: insn data packet corrupted.\n",
- dev->minor);
- up(&usbduxfastsub->sem);
+ printk(KERN_ERR "comedi%d: insn data packet "
+ "corrupted.\n", dev->minor);
+ up(&udfs->sem);
return -EINVAL;
}
for (j = chan; (j < n) && (i < insn->n); j = j + 16) {
- data[i] =
- ((uint16_t *) (usbduxfastsub->
- transfer_buffer))[j];
+ data[i] = ((uint16_t *) (udfs->transfer_buffer))[j];
i++;
}
}
- up(&usbduxfastsub->sem);
+ up(&udfs->sem);
return i;
}
static unsigned hex2unsigned(char *h)
{
unsigned hi, lo;
- if (h[0] > '9') {
+
+ if (h[0] > '9')
hi = h[0] - 'A' + 0x0a;
- } else {
+ else
hi = h[0] - '0';
- }
- if (h[1] > '9') {
+
+ if (h[1] > '9')
lo = h[1] - 'A' + 0x0a;
- } else {
+ else
lo = h[1] - '0';
- }
+
return hi * 0x10 + lo;
}
-// for FX2
+/* for FX2 */
#define FIRMWARE_MAX_LEN 0x2000
-// taken from David Brownell's fxload and adjusted for this driver
-static int read_firmware(usbduxfastsub_t * usbduxfastsub, void *firmwarePtr,
- long size)
+/*
+ * taken from David Brownell's fxload and adjusted for this driver
+ */
+static int read_firmware(struct usbduxfastsub_s *udfs, const void *firmwarePtr,
+ long size)
{
int i = 0;
unsigned char *fp = (char *)firmwarePtr;
- unsigned char *firmwareBinary = NULL;
+ unsigned char *firmwareBinary;
int res = 0;
int maxAddr = 0;
firmwareBinary = kmalloc(FIRMWARE_MAX_LEN, GFP_KERNEL);
if (!firmwareBinary) {
- printk("comedi_: usbduxfast: mem alloc for firmware failed\n");
+ printk(KERN_ERR "comedi_: usbduxfast: mem alloc for firmware "
+ " failed\n");
return -ENOMEM;
}
@@ -1315,31 +1411,37 @@ static int read_firmware(usbduxfastsub_t * usbduxfastsub, void *firmwarePtr,
int idx, off;
int j = 0;
- // get one line
+ /* get one line */
while ((i < size) && (fp[i] != 13) && (fp[i] != 10)) {
buf[j] = fp[i];
i++;
j++;
if (j >= sizeof(buf)) {
- printk("comedi_: usbduxfast: bogus firmware file!\n");
+ printk(KERN_ERR "comedi_: usbduxfast: bogus "
+ "firmware file!\n");
+ kfree(firmwareBinary);
return -1;
}
}
- // get rid of LF/CR/...
+ /* get rid of LF/CR/... */
while ((i < size) && ((fp[i] == 13) || (fp[i] == 10)
- || (fp[i] == 0))) {
+ || (fp[i] == 0)))
i++;
- }
buf[j] = 0;
- //printk("comedi_: buf=%s\n",buf);
+ /* printk("comedi_: buf=%s\n",buf); */
- /* EXTENSION: "# comment-till-end-of-line", for copyrights etc */
+ /*
+ * EXTENSION: "# comment-till-end-of-line",
+ * for copyrights etc
+ */
if (buf[0] == '#')
continue;
if (buf[0] != ':') {
- printk("comedi_: usbduxfast: upload: not an ihex record: %s", buf);
+ printk(KERN_ERR "comedi_: usbduxfast: upload: not an "
+ "ihex record: %s", buf);
+ kfree(firmwareBinary);
return -EFAULT;
}
@@ -1349,266 +1451,309 @@ static int read_firmware(usbduxfastsub_t * usbduxfastsub, void *firmwarePtr,
/* Read the target offset */
off = (hex2unsigned(buf + 3) * 0x0100) + hex2unsigned(buf + 5);
- if ((off + len) > maxAddr) {
+ if ((off + len) > maxAddr)
maxAddr = off + len;
- }
if (maxAddr >= FIRMWARE_MAX_LEN) {
- printk("comedi_: usbduxfast: firmware upload goes beyond FX2 RAM boundaries.");
+ printk(KERN_ERR "comedi_: usbduxfast: firmware upload "
+ "goes beyond FX2 RAM boundaries.");
+ kfree(firmwareBinary);
return -EFAULT;
}
- //printk("comedi_: usbduxfast: off=%x, len=%x:",off,len);
+ /* printk("comedi_: usbduxfast: off=%x, len=%x:",off,len); */
/* Read the record type */
type = hex2unsigned(buf + 7);
/* If this is an EOF record, then make it so. */
- if (type == 1) {
+ if (type == 1)
break;
- }
if (type != 0) {
- printk("comedi_: usbduxfast: unsupported record type: %u\n", type);
+ printk(KERN_ERR "comedi_: usbduxfast: unsupported "
+ "record type: %u\n", type);
+ kfree(firmwareBinary);
return -EFAULT;
}
for (idx = 0, cp = buf + 9; idx < len; idx += 1, cp += 2) {
firmwareBinary[idx + off] = hex2unsigned(cp);
- //printk("%02x ",firmwareBinary[idx+off]);
+ /* printk("%02x ",firmwareBinary[idx+off]); */
}
- //printk("\n");
+
+ /* printk("\n"); */
if (i >= size) {
- printk("comedi_: usbduxfast: unexpected end of hex file\n");
+ printk(KERN_ERR "comedi_: usbduxfast: unexpected end "
+ "of hex file\n");
break;
}
}
- res = firmwareUpload(usbduxfastsub, firmwareBinary, maxAddr + 1);
+ res = firmwareUpload(udfs, firmwareBinary, maxAddr + 1);
kfree(firmwareBinary);
return res;
}
-static void tidy_up(usbduxfastsub_t * usbduxfastsub_tmp)
+static void tidy_up(struct usbduxfastsub_s *udfs)
{
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: tiding up\n");
+ printk(KERN_DEBUG "comedi_: usbduxfast: tiding up\n");
#endif
- if (!usbduxfastsub_tmp) {
+
+ if (!udfs)
return;
- }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // shows the usb subsystem that the driver is down
- if (usbduxfastsub_tmp->interface) {
- usb_set_intfdata(usbduxfastsub_tmp->interface, NULL);
- }
-#endif
- usbduxfastsub_tmp->probed = 0;
+ /* shows the usb subsystem that the driver is down */
+ if (udfs->interface)
+ usb_set_intfdata(udfs->interface, NULL);
- if (usbduxfastsub_tmp->urbIn) {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8)
- // waits until a running transfer is over
- // thus, under 2.4 hotplugging while a command
- // is running is not safe
- usb_kill_urb(usbduxfastsub_tmp->urbIn);
-#endif
- if (usbduxfastsub_tmp->transfer_buffer) {
- kfree(usbduxfastsub_tmp->transfer_buffer);
- usbduxfastsub_tmp->transfer_buffer = NULL;
- }
- usb_free_urb(usbduxfastsub_tmp->urbIn);
- usbduxfastsub_tmp->urbIn = NULL;
- }
- if (usbduxfastsub_tmp->insnBuffer) {
- kfree(usbduxfastsub_tmp->insnBuffer);
- usbduxfastsub_tmp->insnBuffer = NULL;
- }
- if (usbduxfastsub_tmp->dux_commands) {
- kfree(usbduxfastsub_tmp->dux_commands);
- usbduxfastsub_tmp->dux_commands = NULL;
+ udfs->probed = 0;
+
+ if (udfs->urbIn) {
+ /* waits until a running transfer is over */
+ usb_kill_urb(udfs->urbIn);
+
+ kfree(udfs->transfer_buffer);
+ udfs->transfer_buffer = NULL;
+
+ usb_free_urb(udfs->urbIn);
+ udfs->urbIn = NULL;
}
- usbduxfastsub_tmp->ai_cmd_running = 0;
+
+ kfree(udfs->insnBuffer);
+ udfs->insnBuffer = NULL;
+
+ kfree(udfs->dux_commands);
+ udfs->dux_commands = NULL;
+
+ udfs->ai_cmd_running = 0;
}
-// allocate memory for the urbs and initialise them
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void *usbduxfastsub_probe(struct usb_device *udev,
- unsigned int interfnum, const struct usb_device_id *id)
+static void usbduxfast_firmware_request_complete_handler(const struct firmware *fw,
+ void *context)
{
-#else
+ struct usbduxfastsub_s *usbduxfastsub_tmp = context;
+ struct usb_device *usbdev = usbduxfastsub_tmp->usbdev;
+ int ret;
+
+ if (fw == NULL)
+ return;
+
+ /*
+ * we need to upload the firmware here because fw will be
+ * freed once we've left this function
+ */
+ ret = read_firmware(usbduxfastsub_tmp, fw->data, fw->size);
+
+ if (ret) {
+ dev_err(&usbdev->dev,
+ "Could not upload firmware (err=%d)\n",
+ ret);
+ return;
+ }
+
+ comedi_usb_auto_config(usbdev, BOARDNAME);
+}
+
+/*
+ * allocate memory for the urbs and initialise them
+ */
static int usbduxfastsub_probe(struct usb_interface *uinterf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(uinterf);
-#endif
int i;
int index;
+ int ret;
if (udev->speed != USB_SPEED_HIGH) {
- printk("comedi_: usbduxfast_: This driver needs USB 2.0 to operate. Aborting...\n");
+ printk(KERN_ERR "comedi_: usbduxfast_: This driver needs"
+ "USB 2.0 to operate. Aborting...\n");
return -ENODEV;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast_: finding a free structure for the usb-device\n");
+ printk(KERN_DEBUG "comedi_: usbduxfast_: finding a free structure for "
+ "the usb-device\n");
#endif
down(&start_stop_sem);
- // look for a free place in the usbduxfast array
+ /* look for a free place in the usbduxfast array */
index = -1;
for (i = 0; i < NUMUSBDUXFAST; i++) {
- if (!(usbduxfastsub[i].probed)) {
+ if (!usbduxfastsub[i].probed) {
index = i;
break;
}
}
- // no more space
+ /* no more space */
if (index == -1) {
- printk("Too many usbduxfast-devices connected.\n");
+ printk(KERN_ERR "Too many usbduxfast-devices connected.\n");
up(&start_stop_sem);
return -EMFILE;
}
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: usbduxfastsub[%d] is ready to connect to comedi.\n", index);
+ printk(KERN_DEBUG "comedi_: usbduxfast: usbduxfastsub[%d] is ready to "
+ "connect to comedi.\n", index);
#endif
init_MUTEX(&(usbduxfastsub[index].sem));
- // save a pointer to the usb device
+ /* save a pointer to the usb device */
usbduxfastsub[index].usbdev = udev;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- // save the interface number
- usbduxfastsub[index].ifnum = interfnum;
-#else
- // 2.6: save the interface itself
+ /* save the interface itself */
usbduxfastsub[index].interface = uinterf;
- // get the interface number from the interface
+ /* get the interface number from the interface */
usbduxfastsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber;
- // hand the private data over to the usb subsystem
- // will be needed for disconnect
+ /*
+ * hand the private data over to the usb subsystem
+ * will be needed for disconnect
+ */
usb_set_intfdata(uinterf, &(usbduxfastsub[index]));
-#endif
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: ifnum=%d\n", usbduxfastsub[index].ifnum);
+ printk(KERN_DEBUG "comedi_: usbduxfast: ifnum=%d\n",
+ usbduxfastsub[index].ifnum);
#endif
- // create space for the commands going to the usb device
+ /* create space for the commands going to the usb device */
usbduxfastsub[index].dux_commands = kmalloc(SIZEOFDUXBUFFER,
- GFP_KERNEL);
+ GFP_KERNEL);
if (!usbduxfastsub[index].dux_commands) {
- printk("comedi_: usbduxfast: error alloc space for dac commands\n");
+ printk(KERN_ERR "comedi_: usbduxfast: error alloc space for "
+ "dac commands\n");
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- // create space of the instruction buffer
+ /* create space of the instruction buffer */
usbduxfastsub[index].insnBuffer = kmalloc(SIZEINSNBUF, GFP_KERNEL);
- if (!(usbduxfastsub[index].insnBuffer)) {
- printk("comedi_: usbduxfast: could not alloc space for insnBuffer\n");
+ if (!usbduxfastsub[index].insnBuffer) {
+ printk(KERN_ERR "comedi_: usbduxfast: could not alloc space "
+ "for insnBuffer\n");
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- // setting to alternate setting 1: enabling bulk ep
+ /* setting to alternate setting 1: enabling bulk ep */
i = usb_set_interface(usbduxfastsub[index].usbdev,
usbduxfastsub[index].ifnum, 1);
if (i < 0) {
- printk("comedi_: usbduxfast%d: could not switch to alternate setting 1.\n", index);
+ printk(KERN_ERR "comedi_: usbduxfast%d: could not switch to "
+ "alternate setting 1.\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENODEV;
}
usbduxfastsub[index].urbIn = usb_alloc_urb(0, GFP_KERNEL);
- if (usbduxfastsub[index].urbIn == NULL) {
- printk("comedi_: usbduxfast%d: Could not alloc. urb\n", index);
+ if (!usbduxfastsub[index].urbIn) {
+ printk(KERN_ERR "comedi_: usbduxfast%d: Could not alloc."
+ "urb\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
usbduxfastsub[index].transfer_buffer = kmalloc(SIZEINBUF, GFP_KERNEL);
- if (!(usbduxfastsub[index].transfer_buffer)) {
- printk("comedi_: usbduxfast%d: could not alloc. transb.\n",
- index);
+ if (!usbduxfastsub[index].transfer_buffer) {
+ printk(KERN_ERR "comedi_: usbduxfast%d: could not alloc. "
+ "transb.\n", index);
tidy_up(&(usbduxfastsub[index]));
up(&start_stop_sem);
return -ENOMEM;
}
- // we've reached the bottom of the function
+ /* we've reached the bottom of the function */
usbduxfastsub[index].probed = 1;
up(&start_stop_sem);
- printk("comedi_: usbduxfast%d has been successfully initialized.\n",
- index);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
- return (void *)(&usbduxfastsub[index]);
-#else
- // success
+
+ ret = request_firmware_nowait(THIS_MODULE,
+ FW_ACTION_HOTPLUG,
+ "usbduxfast_firmware.hex",
+ &udev->dev,
+ usbduxfastsub + index,
+ usbduxfast_firmware_request_complete_handler);
+
+ if (ret) {
+ dev_err(&udev->dev, "could not load firmware (err=%d)\n",
+ ret);
+ return ret;
+ }
+
+ printk(KERN_INFO "comedi_: usbduxfast%d has been successfully "
+ "initialized.\n", index);
+ /* success */
return 0;
-#endif
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
-static void usbduxfastsub_disconnect(struct usb_device *udev, void *ptr)
-{
- usbduxfastsub_t *usbduxfastsub_tmp = (usbduxfastsub_t *) ptr;
-#else
static void usbduxfastsub_disconnect(struct usb_interface *intf)
{
- usbduxfastsub_t *usbduxfastsub_tmp = usb_get_intfdata(intf);
+ struct usbduxfastsub_s *udfs = usb_get_intfdata(intf);
struct usb_device *udev = interface_to_usbdev(intf);
-#endif
- if (!usbduxfastsub_tmp) {
- printk("comedi_: usbduxfast: disconnect called with null pointer.\n");
+
+ if (!udfs) {
+ printk(KERN_ERR "comedi_: usbduxfast: disconnect called with "
+ "null pointer.\n");
return;
}
- if (usbduxfastsub_tmp->usbdev != udev) {
- printk("comedi_: usbduxfast: BUG! called with wrong ptr!!!\n");
+ if (udfs->usbdev != udev) {
+ printk(KERN_ERR "comedi_: usbduxfast: BUG! called with wrong "
+ "ptr!!!\n");
return;
}
+
+ comedi_usb_auto_unconfig(udev);
+
down(&start_stop_sem);
- down(&usbduxfastsub_tmp->sem);
- tidy_up(usbduxfastsub_tmp);
- up(&usbduxfastsub_tmp->sem);
+ down(&udfs->sem);
+ tidy_up(udfs);
+ up(&udfs->sem);
up(&start_stop_sem);
+
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: disconnected from the usb\n");
+ printk(KERN_DEBUG "comedi_: usbduxfast: disconnected from the usb\n");
#endif
}
-// is called when comedi-config is called
-static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
+/*
+ * is called when comedi-config is called
+ */
+static int usbduxfast_attach(struct comedi_device *dev, struct comedi_devconfig *it)
{
int ret;
int index;
int i;
- comedi_subdevice *s = NULL;
+ struct comedi_subdevice *s = NULL;
dev->private = NULL;
down(&start_stop_sem);
- // find a valid device which has been detected by the probe function of the usb
+ /*
+ * find a valid device which has been detected by the
+ * probe function of the usb
+ */
index = -1;
for (i = 0; i < NUMUSBDUXFAST; i++) {
- if ((usbduxfastsub[i].probed) && (!usbduxfastsub[i].attached)) {
+ if (usbduxfastsub[i].probed && !usbduxfastsub[i].attached) {
index = i;
break;
}
}
if (index < 0) {
- printk("comedi%d: usbduxfast: error: attach failed, no usbduxfast devs connected to the usb bus.\n", dev->minor);
+ printk(KERN_ERR "comedi%d: usbduxfast: error: attach failed, "
+ "no usbduxfast devs connected to the usb bus.\n",
+ dev->minor);
up(&start_stop_sem);
return -ENODEV;
}
down(&(usbduxfastsub[index].sem));
- // pointer back to the corresponding comedi device
+ /* pointer back to the corresponding comedi device */
usbduxfastsub[index].comedidev = dev;
- // trying to upload the firmware into the chip
+ /* trying to upload the firmware into the chip */
if (comedi_aux_data(it->options, 0) &&
- it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
- read_firmware(usbduxfastsub,
- comedi_aux_data(it->options, 0),
- it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
+ it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) {
+ read_firmware(&usbduxfastsub[index],
+ comedi_aux_data(it->options, 0),
+ it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]);
}
dev->board_name = BOARDNAME;
@@ -1616,155 +1761,150 @@ static int usbduxfast_attach(comedi_device * dev, comedi_devconfig * it)
/* set number of subdevices */
dev->n_subdevices = N_SUBDEVICES;
- // allocate space for the subdevices
- if ((ret = alloc_subdevices(dev, N_SUBDEVICES)) < 0) {
- printk("comedi%d: usbduxfast: error alloc space for subdev\n",
- dev->minor);
+ /* allocate space for the subdevices */
+ ret = alloc_subdevices(dev, N_SUBDEVICES);
+ if (ret < 0) {
+ printk(KERN_ERR "comedi%d: usbduxfast: error alloc space for "
+ "subdev\n", dev->minor);
+ up(&(usbduxfastsub[index].sem));
up(&start_stop_sem);
return ret;
}
- printk("comedi%d: usbduxfast: usb-device %d is attached to comedi.\n",
- dev->minor, index);
- // private structure is also simply the usb-structure
+ printk(KERN_INFO "comedi%d: usbduxfast: usb-device %d is attached to "
+ "comedi.\n", dev->minor, index);
+ /* private structure is also simply the usb-structure */
dev->private = usbduxfastsub + index;
- // the first subdevice is the A/D converter
+ /* the first subdevice is the A/D converter */
s = dev->subdevices + SUBDEV_AD;
- // the URBs get the comedi subdevice
- // which is responsible for reading
- // this is the subdevice which reads data
+ /*
+ * the URBs get the comedi subdevice which is responsible for reading
+ * this is the subdevice which reads data
+ */
dev->read_subdev = s;
- // the subdevice receives as private structure the
- // usb-structure
+ /* the subdevice receives as private structure the usb-structure */
s->private = NULL;
- // analog input
+ /* analog input */
s->type = COMEDI_SUBD_AI;
- // readable and ref is to ground
+ /* readable and ref is to ground */
s->subdev_flags = SDF_READABLE | SDF_GROUND | SDF_CMD_READ;
- // 16 channels
+ /* 16 channels */
s->n_chan = 16;
- // length of the channellist
+ /* length of the channellist */
s->len_chanlist = 16;
- // callback functions
+ /* callback functions */
s->insn_read = usbduxfast_ai_insn_read;
s->do_cmdtest = usbduxfast_ai_cmdtest;
s->do_cmd = usbduxfast_ai_cmd;
s->cancel = usbduxfast_ai_cancel;
- // max value from the A/D converter (12bit+1 bit for overflow)
+ /* max value from the A/D converter (12bit+1 bit for overflow) */
s->maxdata = 0x1000;
- // range table to convert to physical units
+ /* range table to convert to physical units */
s->range_table = &range_usbduxfast_ai_range;
- // finally decide that it's attached
+ /* finally decide that it's attached */
usbduxfastsub[index].attached = 1;
up(&(usbduxfastsub[index].sem));
-
up(&start_stop_sem);
-
- printk("comedi%d: successfully attached to usbduxfast.\n", dev->minor);
+ printk(KERN_INFO "comedi%d: successfully attached to usbduxfast.\n",
+ dev->minor);
return 0;
}
-static int usbduxfast_detach(comedi_device * dev)
+static int usbduxfast_detach(struct comedi_device *dev)
{
- usbduxfastsub_t *usbduxfastsub_tmp;
-
-#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: detach usb device\n", dev->minor);
-#endif
+ struct usbduxfastsub_s *udfs;
if (!dev) {
- printk("comedi?: usbduxfast: detach without dev variable...\n");
+ printk(KERN_ERR "comedi?: usbduxfast: detach without dev "
+ "variable...\n");
return -EFAULT;
}
- usbduxfastsub_tmp = dev->private;
- if (!usbduxfastsub_tmp) {
- printk("comedi?: usbduxfast: detach without ptr to usbduxfastsub[]\n");
+#ifdef CONFIG_COMEDI_DEBUG
+ printk(KERN_DEBUG "comedi%d: usbduxfast: detach usb device\n",
+ dev->minor);
+#endif
+
+ udfs = dev->private;
+ if (!udfs) {
+ printk(KERN_ERR "comedi?: usbduxfast: detach without ptr to "
+ "usbduxfastsub[]\n");
return -EFAULT;
}
- down(&usbduxfastsub_tmp->sem);
+ down(&udfs->sem);
down(&start_stop_sem);
- // Don't allow detach to free the private structure
- // It's one entry of of usbduxfastsub[]
+ /*
+ * Don't allow detach to free the private structure
+ * It's one entry of of usbduxfastsub[]
+ */
dev->private = NULL;
- usbduxfastsub_tmp->attached = 0;
- usbduxfastsub_tmp->comedidev = NULL;
+ udfs->attached = 0;
+ udfs->comedidev = NULL;
#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi%d: usbduxfast: detach: successfully removed\n",
- dev->minor);
+ printk(KERN_DEBUG "comedi%d: usbduxfast: detach: successfully "
+ "removed\n", dev->minor);
#endif
up(&start_stop_sem);
- up(&usbduxfastsub_tmp->sem);
+ up(&udfs->sem);
return 0;
}
-/* main driver struct */
-static comedi_driver driver_usbduxfast = {
- driver_name:"usbduxfast",
- module:THIS_MODULE,
- attach:usbduxfast_attach,
- detach:usbduxfast_detach,
+/*
+ * main driver struct
+ */
+static struct comedi_driver driver_usbduxfast = {
+ .driver_name = "usbduxfast",
+ .module = THIS_MODULE,
+ .attach = usbduxfast_attach,
+ .detach = usbduxfast_detach
};
-static void init_usb_devices(void)
-{
- int index;
-#ifdef CONFIG_COMEDI_DEBUG
- printk("comedi_: usbduxfast: setting all possible devs to invalid\n");
-#endif
- // all devices entries are invalid to begin with
- // they will become valid by the probe function
- // and then finally by the attach-function
- for (index = 0; index < NUMUSBDUXFAST; index++) {
- memset(&(usbduxfastsub[index]), 0x00,
- sizeof(usbduxfastsub[index]));
- init_MUTEX(&(usbduxfastsub[index].sem));
- }
-}
-
-// Table with the USB-devices: just now only testing IDs
+/*
+ * Table with the USB-devices: just now only testing IDs
+ */
static struct usb_device_id usbduxfastsub_table[] = {
- // { USB_DEVICE(0x4b4, 0x8613), //testing
- // },
- {USB_DEVICE(0x13d8, 0x0010) //real ID
- },
- {USB_DEVICE(0x13d8, 0x0011) //real ID
- },
- {} /* Terminating entry */
+ /* { USB_DEVICE(0x4b4, 0x8613) }, testing */
+ { USB_DEVICE(0x13d8, 0x0010) }, /* real ID */
+ { USB_DEVICE(0x13d8, 0x0011) }, /* real ID */
+ { } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, usbduxfastsub_table);
-// The usbduxfastsub-driver
+/*
+ * The usbduxfastsub-driver
+ */
static struct usb_driver usbduxfastsub_driver = {
#ifdef COMEDI_HAVE_USB_DRIVER_OWNER
- owner:THIS_MODULE,
+ .owner = THIS_MODULE,
#endif
- name:BOARDNAME,
- probe:usbduxfastsub_probe,
- disconnect:usbduxfastsub_disconnect,
- id_table:usbduxfastsub_table,
+ .name = BOARDNAME,
+ .probe = usbduxfastsub_probe,
+ .disconnect = usbduxfastsub_disconnect,
+ .id_table = usbduxfastsub_table
};
-// Can't use the nice macro as I have also to initialise the USB
-// subsystem:
-// registering the usb-system _and_ the comedi-driver
-static int init_usbduxfast(void)
+/*
+ * Can't use the nice macro as I have also to initialise the USB subsystem:
+ * registering the usb-system _and_ the comedi-driver
+ */
+static int __init init_usbduxfast(void)
{
- printk(KERN_INFO KBUILD_MODNAME ": "
- DRIVER_VERSION ":" DRIVER_DESC "\n");
- init_usb_devices();
+ printk(KERN_INFO
+ KBUILD_MODNAME ": " DRIVER_VERSION ":" DRIVER_DESC "\n");
usb_register(&usbduxfastsub_driver);
comedi_driver_register(&driver_usbduxfast);
return 0;
}
-// deregistering the comedi driver and the usb-subsystem
-static void exit_usbduxfast(void)
+/*
+ * deregistering the comedi driver and the usb-subsystem
+ */
+static void __exit exit_usbduxfast(void)
{
comedi_driver_unregister(&driver_usbduxfast);
usb_deregister(&usbduxfastsub_driver);
diff --git a/drivers/staging/comedi/interrupt.h b/drivers/staging/comedi/interrupt.h
index 3038e461948..d1f09892da2 100644
--- a/drivers/staging/comedi/interrupt.h
+++ b/drivers/staging/comedi/interrupt.h
@@ -21,15 +21,6 @@
#include <linux/interrupt.h>
-#include <linux/version.h>
-
-#ifndef IRQ_NONE
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x) (void)(x)
-#endif
-
#ifndef IRQF_DISABLED
#define IRQF_DISABLED SA_INTERRUPT
#define IRQF_SAMPLE_RANDOM SA_SAMPLE_RANDOM
diff --git a/drivers/staging/comedi/kcomedilib/data.c b/drivers/staging/comedi/kcomedilib/data.c
index 79aec204115..9797e13e377 100644
--- a/drivers/staging/comedi/kcomedilib/data.c
+++ b/drivers/staging/comedi/kcomedilib/data.c
@@ -27,10 +27,10 @@
#include <linux/string.h>
-int comedi_data_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t data)
+int comedi_data_write(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int data)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_WRITE;
@@ -42,10 +42,10 @@ int comedi_data_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_data_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
- unsigned int range, unsigned int aref, lsampl_t * data)
+int comedi_data_read(void *dev, unsigned int subdev, unsigned int chan,
+ unsigned int range, unsigned int aref, unsigned int *data)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_READ;
@@ -57,11 +57,11 @@ int comedi_data_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_data_read_hint(comedi_t * dev, unsigned int subdev,
+int comedi_data_read_hint(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref)
{
- comedi_insn insn;
- lsampl_t dummy_data;
+ struct comedi_insn insn;
+ unsigned int dummy_data;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_READ;
@@ -73,9 +73,9 @@ int comedi_data_read_hint(comedi_t * dev, unsigned int subdev,
return comedi_do_insn(dev, &insn);
}
-int comedi_data_read_delayed(comedi_t * dev, unsigned int subdev,
+int comedi_data_read_delayed(void *dev, unsigned int subdev,
unsigned int chan, unsigned int range, unsigned int aref,
- lsampl_t * data, unsigned int nano_sec)
+ unsigned int *data, unsigned int nano_sec)
{
int retval;
diff --git a/drivers/staging/comedi/kcomedilib/dio.c b/drivers/staging/comedi/kcomedilib/dio.c
index a9f488aed36..8595567e48f 100644
--- a/drivers/staging/comedi/kcomedilib/dio.c
+++ b/drivers/staging/comedi/kcomedilib/dio.c
@@ -26,10 +26,10 @@
#include <linux/string.h>
-int comedi_dio_config(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_config(void *dev, unsigned int subdev, unsigned int chan,
unsigned int io)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_CONFIG;
@@ -41,10 +41,10 @@ int comedi_dio_config(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_dio_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_read(void *dev, unsigned int subdev, unsigned int chan,
unsigned int *val)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_READ;
@@ -56,10 +56,10 @@ int comedi_dio_read(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_dio_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
+int comedi_dio_write(void *dev, unsigned int subdev, unsigned int chan,
unsigned int val)
{
- comedi_insn insn;
+ struct comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_WRITE;
@@ -71,11 +71,11 @@ int comedi_dio_write(comedi_t * dev, unsigned int subdev, unsigned int chan,
return comedi_do_insn(dev, &insn);
}
-int comedi_dio_bitfield(comedi_t * dev, unsigned int subdev, unsigned int mask,
+int comedi_dio_bitfield(void *dev, unsigned int subdev, unsigned int mask,
unsigned int *bits)
{
- comedi_insn insn;
- lsampl_t data[2];
+ struct comedi_insn insn;
+ unsigned int data[2];
int ret;
memset(&insn, 0, sizeof(insn));
diff --git a/drivers/staging/comedi/kcomedilib/get.c b/drivers/staging/comedi/kcomedilib/get.c
index 2004ad4480c..b6b726a69f1 100644
--- a/drivers/staging/comedi/kcomedilib/get.c
+++ b/drivers/staging/comedi/kcomedilib/get.c
@@ -26,51 +26,51 @@
#include "../comedilib.h"
#include "../comedidev.h"
-int comedi_get_n_subdevices(comedi_t * d)
+int comedi_get_n_subdevices(void *d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
return dev->n_subdevices;
}
-int comedi_get_version_code(comedi_t * d)
+int comedi_get_version_code(void *d)
{
return COMEDI_VERSION_CODE;
}
-const char *comedi_get_driver_name(comedi_t * d)
+const char *comedi_get_driver_name(void * d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
return dev->driver->driver_name;
}
-const char *comedi_get_board_name(comedi_t * d)
+const char *comedi_get_board_name(void * d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
return dev->board_name;
}
-int comedi_get_subdevice_type(comedi_t * d, unsigned int subdevice)
+int comedi_get_subdevice_type(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->type;
}
-unsigned int comedi_get_subdevice_flags(comedi_t * d, unsigned int subdevice)
+unsigned int comedi_get_subdevice_flags(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->subdev_flags;
}
-int comedi_find_subdevice_by_type(comedi_t * d, int type, unsigned int subd)
+int comedi_find_subdevice_by_type(void *d, int type, unsigned int subd)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
if (subd > dev->n_subdevices)
return -ENODEV;
@@ -82,27 +82,27 @@ int comedi_find_subdevice_by_type(comedi_t * d, int type, unsigned int subd)
return -1;
}
-int comedi_get_n_channels(comedi_t * d, unsigned int subdevice)
+int comedi_get_n_channels(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->n_chan;
}
-int comedi_get_len_chanlist(comedi_t * d, unsigned int subdevice)
+int comedi_get_len_chanlist(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
return s->len_chanlist;
}
-lsampl_t comedi_get_maxdata(comedi_t * d, unsigned int subdevice,
+unsigned int comedi_get_maxdata(void *d, unsigned int subdevice,
unsigned int chan)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
if (s->maxdata_list)
return s->maxdata_list[chan];
@@ -111,11 +111,11 @@ lsampl_t comedi_get_maxdata(comedi_t * d, unsigned int subdevice,
}
#ifdef KCOMEDILIB_DEPRECATED
-int comedi_get_rangetype(comedi_t * d, unsigned int subdevice,
+int comedi_get_rangetype(void *d, unsigned int subdevice,
unsigned int chan)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
int ret;
if (s->range_table_list) {
@@ -130,10 +130,10 @@ int comedi_get_rangetype(comedi_t * d, unsigned int subdevice,
}
#endif
-int comedi_get_n_ranges(comedi_t * d, unsigned int subdevice, unsigned int chan)
+int comedi_get_n_ranges(void *d, unsigned int subdevice, unsigned int chan)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
int ret;
if (s->range_table_list) {
@@ -148,22 +148,22 @@ int comedi_get_n_ranges(comedi_t * d, unsigned int subdevice, unsigned int chan)
/*
* ALPHA (non-portable)
*/
-int comedi_get_krange(comedi_t * d, unsigned int subdevice, unsigned int chan,
- unsigned int range, comedi_krange * krange)
+int comedi_get_krange(void *d, unsigned int subdevice, unsigned int chan,
+ unsigned int range, struct comedi_krange *krange)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- const comedi_lrange *lr;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ const struct comedi_lrange *lr;
if (s->range_table_list) {
lr = s->range_table_list[chan];
} else {
lr = s->range_table;
}
- if (range >= lr->length) {
+ if (range >= lr->length)
return -EINVAL;
- }
- memcpy(krange, lr->range + range, sizeof(comedi_krange));
+
+ memcpy(krange, lr->range + range, sizeof(struct comedi_krange));
return 0;
}
@@ -171,11 +171,11 @@ int comedi_get_krange(comedi_t * d, unsigned int subdevice, unsigned int chan,
/*
* ALPHA (may be renamed)
*/
-unsigned int comedi_get_buf_head_pos(comedi_t * d, unsigned int subdevice)
+unsigned int comedi_get_buf_head_pos(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
async = s->async;
if (async == NULL)
@@ -184,11 +184,11 @@ unsigned int comedi_get_buf_head_pos(comedi_t * d, unsigned int subdevice)
return async->buf_write_count;
}
-int comedi_get_buffer_contents(comedi_t * d, unsigned int subdevice)
+int comedi_get_buffer_contents(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
unsigned int num_bytes;
if (subdevice >= dev->n_subdevices)
@@ -203,12 +203,12 @@ int comedi_get_buffer_contents(comedi_t * d, unsigned int subdevice)
/*
* ALPHA
*/
-int comedi_set_user_int_count(comedi_t * d, unsigned int subdevice,
+int comedi_set_user_int_count(void *d, unsigned int subdevice,
unsigned int buf_user_count)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
int num_bytes;
async = s->async;
@@ -224,12 +224,12 @@ int comedi_set_user_int_count(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_mark_buffer_read(comedi_t * d, unsigned int subdevice,
+int comedi_mark_buffer_read(void *d, unsigned int subdevice,
unsigned int num_bytes)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
if (subdevice >= dev->n_subdevices)
return -1;
@@ -243,12 +243,12 @@ int comedi_mark_buffer_read(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_mark_buffer_written(comedi_t * d, unsigned int subdevice,
+int comedi_mark_buffer_written(void *d, unsigned int subdevice,
unsigned int num_bytes)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
int bytes_written;
if (subdevice >= dev->n_subdevices)
@@ -263,11 +263,11 @@ int comedi_mark_buffer_written(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_get_buffer_size(comedi_t * d, unsigned int subdev)
+int comedi_get_buffer_size(void *d, unsigned int subdev)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdev;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdev;
+ struct comedi_async *async;
if (subdev >= dev->n_subdevices)
return -1;
@@ -278,11 +278,11 @@ int comedi_get_buffer_size(comedi_t * d, unsigned int subdev)
return async->prealloc_bufsz;
}
-int comedi_get_buffer_offset(comedi_t * d, unsigned int subdevice)
+int comedi_get_buffer_offset(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices + subdevice;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices + subdevice;
+ struct comedi_async *async;
if (subdevice >= dev->n_subdevices)
return -1;
diff --git a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
index 510fbdcec49..a4fa9571c58 100644
--- a/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
+++ b/drivers/staging/comedi/kcomedilib/kcomedilib_main.c
@@ -42,10 +42,10 @@ MODULE_AUTHOR("David Schleef <ds@schleef.org>");
MODULE_DESCRIPTION("Comedi kernel library");
MODULE_LICENSE("GPL");
-comedi_t *comedi_open(const char *filename)
+void *comedi_open(const char *filename)
{
struct comedi_device_file_info *dev_file_info;
- comedi_device *dev;
+ struct comedi_device *dev;
unsigned int minor;
if (strncmp(filename, "/dev/comedi", 11) != 0)
@@ -57,41 +57,41 @@ comedi_t *comedi_open(const char *filename)
return NULL;
dev_file_info = comedi_get_device_file_info(minor);
- if(dev_file_info == NULL)
+ if (dev_file_info == NULL)
return NULL;
dev = dev_file_info->device;
- if(dev == NULL || !dev->attached)
+ if (dev == NULL || !dev->attached)
return NULL;
if (!try_module_get(dev->driver->module))
return NULL;
- return (comedi_t *) dev;
+ return (void *) dev;
}
-comedi_t *comedi_open_old(unsigned int minor)
+void *comedi_open_old(unsigned int minor)
{
struct comedi_device_file_info *dev_file_info;
- comedi_device *dev;
+ struct comedi_device *dev;
if (minor >= COMEDI_NUM_MINORS)
return NULL;
dev_file_info = comedi_get_device_file_info(minor);
- if(dev_file_info == NULL)
+ if (dev_file_info == NULL)
return NULL;
dev = dev_file_info->device;
- if(dev == NULL || !dev->attached)
+ if (dev == NULL || !dev->attached)
return NULL;
- return (comedi_t *) dev;
+ return (void *) dev;
}
-int comedi_close(comedi_t * d)
+int comedi_close(void *d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
module_put(dev->driver->module);
@@ -113,19 +113,19 @@ char *comedi_strerror(int err)
return "unknown error";
}
-int comedi_fileno(comedi_t * d)
+int comedi_fileno(void *d)
{
- comedi_device *dev = (comedi_device *) d;
+ struct comedi_device *dev = (struct comedi_device *) d;
/* return something random */
return dev->minor;
}
-int comedi_command(comedi_t * d, comedi_cmd * cmd)
+int comedi_command(void *d, struct comedi_cmd *cmd)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
unsigned runflags;
if (cmd->subdev >= dev->n_subdevices)
@@ -161,10 +161,10 @@ int comedi_command(comedi_t * d, comedi_cmd * cmd)
return s->do_cmd(dev, s);
}
-int comedi_command_test(comedi_t * d, comedi_cmd * cmd)
+int comedi_command_test(void *d, struct comedi_cmd *cmd)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
if (cmd->subdev >= dev->n_subdevices)
return -ENODEV;
@@ -183,10 +183,10 @@ int comedi_command_test(comedi_t * d, comedi_cmd * cmd)
* COMEDI_INSN
* perform an instruction
*/
-int comedi_do_insn(comedi_t * d, comedi_insn * insn)
+int comedi_do_insn(void *d, struct comedi_insn *insn)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
int ret = 0;
if (insn->insn & INSN_MASK_SPECIAL) {
@@ -256,7 +256,8 @@ int comedi_do_insn(comedi_t * d, comedi_insn * insn)
/* XXX check lock */
- if ((ret = check_chanlist(s, 1, &insn->chanspec)) < 0) {
+ ret = check_chanlist(s, 1, &insn->chanspec);
+ if (ret < 0) {
rt_printk("bad chanspec\n");
ret = -EINVAL;
goto error;
@@ -323,16 +324,16 @@ int comedi_do_insn(comedi_t * d, comedi_insn * insn)
- lock while subdevice being programmed
*/
-int comedi_lock(comedi_t * d, unsigned int subdevice)
+int comedi_lock(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
unsigned long flags;
int ret = 0;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
comedi_spin_lock_irqsave(&s->spin_lock, flags);
@@ -366,17 +367,17 @@ int comedi_lock(comedi_t * d, unsigned int subdevice)
none
*/
-int comedi_unlock(comedi_t * d, unsigned int subdevice)
+int comedi_unlock(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
unsigned long flags;
- comedi_async *async;
+ struct comedi_async *async;
int ret;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
async = s->async;
@@ -418,15 +419,15 @@ int comedi_unlock(comedi_t * d, unsigned int subdevice)
nothing
*/
-int comedi_cancel(comedi_t * d, unsigned int subdevice)
+int comedi_cancel(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
int ret = 0;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
if (s->lock && s->lock != d)
@@ -443,13 +444,15 @@ int comedi_cancel(comedi_t * d, unsigned int subdevice)
if (!s->cancel || !s->async)
return -EINVAL;
- if ((ret = s->cancel(dev, s)))
+ ret = s->cancel(dev, s);
+
+ if (ret)
return ret;
#ifdef CONFIG_COMEDI_RT
- if (comedi_get_subdevice_runflags(s) & SRF_RT) {
+ if (comedi_get_subdevice_runflags(s) & SRF_RT)
comedi_switch_to_non_rt(dev);
- }
+
#endif
comedi_set_subdevice_runflags(s, SRF_RUNNING | SRF_RT, 0);
s->async->inttrig = NULL;
@@ -461,16 +464,16 @@ int comedi_cancel(comedi_t * d, unsigned int subdevice)
/*
registration of callback functions
*/
-int comedi_register_callback(comedi_t * d, unsigned int subdevice,
+int comedi_register_callback(void *d, unsigned int subdevice,
unsigned int mask, int (*cb) (unsigned int, void *), void *arg)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
+ struct comedi_async *async;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
async = s->async;
@@ -498,15 +501,15 @@ int comedi_register_callback(comedi_t * d, unsigned int subdevice,
return 0;
}
-int comedi_poll(comedi_t * d, unsigned int subdevice)
+int comedi_poll(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s = dev->subdevices;
- comedi_async *async;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s = dev->subdevices;
+ struct comedi_async *async;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
async = s->async;
@@ -525,22 +528,21 @@ int comedi_poll(comedi_t * d, unsigned int subdevice)
}
/* WARNING: not portable */
-int comedi_map(comedi_t * d, unsigned int subdevice, void *ptr)
+int comedi_map(void *d, unsigned int subdevice, void *ptr)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
if (!s->async)
return -EINVAL;
- if (ptr) {
+ if (ptr)
*((void **)ptr) = s->async->prealloc_buf;
- }
/* XXX no reference counting */
@@ -548,14 +550,14 @@ int comedi_map(comedi_t * d, unsigned int subdevice, void *ptr)
}
/* WARNING: not portable */
-int comedi_unmap(comedi_t * d, unsigned int subdevice)
+int comedi_unmap(void *d, unsigned int subdevice)
{
- comedi_device *dev = (comedi_device *) d;
- comedi_subdevice *s;
+ struct comedi_device *dev = (struct comedi_device *) d;
+ struct comedi_subdevice *s;
- if (subdevice >= dev->n_subdevices) {
+ if (subdevice >= dev->n_subdevices)
return -EINVAL;
- }
+
s = dev->subdevices + subdevice;
if (!s->async)
diff --git a/drivers/staging/comedi/kcomedilib/ksyms.c b/drivers/staging/comedi/kcomedilib/ksyms.c
index 76b45063a9f..3db86dabf87 100644
--- a/drivers/staging/comedi/kcomedilib/ksyms.c
+++ b/drivers/staging/comedi/kcomedilib/ksyms.c
@@ -40,8 +40,6 @@
#include <linux/mm.h>
#include <linux/slab.h>
-#if LINUX_VERSION_CODE >= 0x020200
-
/* functions specific to kcomedilib */
EXPORT_SYMBOL(comedi_register_callback);
@@ -140,5 +138,3 @@ EXPORT_SYMBOL(comedi_get_len_chanlist);
/* alpha */
//EXPORT_SYMBOL(comedi_set_global_oor_behavior);
-
-#endif
diff --git a/drivers/staging/comedi/pci_ids.h b/drivers/staging/comedi/pci_ids.h
index c61ba90f960..d979aa8e396 100644
--- a/drivers/staging/comedi/pci_ids.h
+++ b/drivers/staging/comedi/pci_ids.h
@@ -28,4 +28,4 @@
#define PCI_DEVICE_ID_QUANCOM_GPIB 0x3302
#endif
-#endif // __COMPAT_LINUX_PCI_IDS_H
+#endif /* __COMPAT_LINUX_PCI_IDS_H */
diff --git a/drivers/staging/comedi/proc.c b/drivers/staging/comedi/proc.c
index 5a2b72d8757..36ae2cd92ad 100644
--- a/drivers/staging/comedi/proc.c
+++ b/drivers/staging/comedi/proc.c
@@ -31,12 +31,12 @@
#define __NO_VERSION__
#include "comedidev.h"
#include <linux/proc_fs.h>
-//#include <linux/string.h>
+/* #include <linux/string.h> */
int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
int *eof, void *data);
-extern comedi_driver *comedi_drivers;
+extern struct comedi_driver *comedi_drivers;
int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
int *eof, void *data)
@@ -44,7 +44,7 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
int i;
int devices_q = 0;
int l = 0;
- comedi_driver *driv;
+ struct comedi_driver *driv;
l += sprintf(buf + l,
"comedi version " COMEDI_RELEASE "\n"
@@ -53,9 +53,10 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
for (i = 0; i < COMEDI_NUM_BOARD_MINORS; i++) {
struct comedi_device_file_info *dev_file_info = comedi_get_device_file_info(i);
- comedi_device *dev;
+ struct comedi_device *dev;
- if(dev_file_info == NULL) continue;
+ if (dev_file_info == NULL)
+ continue;
dev = dev_file_info->device;
if (dev->attached) {
@@ -66,9 +67,8 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
dev->board_name, dev->n_subdevices);
}
}
- if (!devices_q) {
+ if (!devices_q)
l += sprintf(buf + l, "no devices\n");
- }
for (driv = comedi_drivers; driv; driv = driv->next) {
l += sprintf(buf + l, "%s:\n", driv->driver_name);
@@ -77,9 +77,8 @@ int comedi_read_procmem(char *buf, char **start, off_t offset, int len,
*(char **)((char *)driv->board_name +
i * driv->offset));
}
- if (!driv->num_names) {
+ if (!driv->num_names)
l += sprintf(buf + l, " %s\n", driv->driver_name);
- }
}
return l;
diff --git a/drivers/staging/comedi/range.c b/drivers/staging/comedi/range.c
index 61dc3cd6a9f..ac200d929f3 100644
--- a/drivers/staging/comedi/range.c
+++ b/drivers/staging/comedi/range.c
@@ -24,12 +24,12 @@
#include "comedidev.h"
#include <asm/uaccess.h>
-const comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
-const comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
-const comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
-const comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
-const comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
-const comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
+const struct comedi_lrange range_bipolar10 = { 1, {BIP_RANGE(10)} };
+const struct comedi_lrange range_bipolar5 = { 1, {BIP_RANGE(5)} };
+const struct comedi_lrange range_bipolar2_5 = { 1, {BIP_RANGE(2.5)} };
+const struct comedi_lrange range_unipolar10 = { 1, {UNI_RANGE(10)} };
+const struct comedi_lrange range_unipolar5 = { 1, {UNI_RANGE(5)} };
+const struct comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
/*
COMEDI_RANGEINFO
@@ -42,16 +42,16 @@ const comedi_lrange range_unknown = { 1, {{0, 1000000, UNIT_none}} };
range info structure
writes:
- n comedi_krange structures to rangeinfo->range_ptr
+ n struct comedi_krange structures to rangeinfo->range_ptr
*/
-int do_rangeinfo_ioctl(comedi_device * dev, comedi_rangeinfo * arg)
+int do_rangeinfo_ioctl(struct comedi_device *dev, struct comedi_rangeinfo *arg)
{
- comedi_rangeinfo it;
+ struct comedi_rangeinfo it;
int subd, chan;
- const comedi_lrange *lr;
- comedi_subdevice *s;
+ const struct comedi_lrange *lr;
+ struct comedi_subdevice *s;
- if (copy_from_user(&it, arg, sizeof(comedi_rangeinfo)))
+ if (copy_from_user(&it, arg, sizeof(struct comedi_rangeinfo)))
return -EFAULT;
subd = (it.range_type >> 24) & 0xf;
chan = (it.range_type >> 16) & 0xff;
@@ -78,17 +78,17 @@ int do_rangeinfo_ioctl(comedi_device * dev, comedi_rangeinfo * arg)
}
if (copy_to_user(it.range_ptr, lr->range,
- sizeof(comedi_krange) * lr->length))
+ sizeof(struct comedi_krange) * lr->length))
return -EFAULT;
return 0;
}
-static int aref_invalid(comedi_subdevice * s, unsigned int chanspec)
+static int aref_invalid(struct comedi_subdevice *s, unsigned int chanspec)
{
unsigned int aref;
- // disable reporting invalid arefs... maybe someday
+ /* disable reporting invalid arefs... maybe someday */
return 0;
aref = CR_AREF(chanspec);
@@ -120,7 +120,7 @@ static int aref_invalid(comedi_subdevice * s, unsigned int chanspec)
This function checks each element in a channel/gain list to make
make sure it is valid.
*/
-int check_chanlist(comedi_subdevice * s, int n, unsigned int *chanlist)
+int check_chanlist(struct comedi_subdevice *s, int n, unsigned int *chanlist)
{
int i;
int chan;
@@ -135,9 +135,8 @@ int check_chanlist(comedi_subdevice * s, int n, unsigned int *chanlist)
i, chanlist[i], s->n_chan,
s->range_table->length);
#if 0
- for (i = 0; i < n; i++) {
+ for (i = 0; i < n; i++)
printk("[%d]=0x%08x\n", i, chanlist[i]);
- }
#endif
return -EINVAL;
}
diff --git a/drivers/staging/comedi/rt.c b/drivers/staging/comedi/rt.c
index 385b81b94ac..e9f5777595a 100644
--- a/drivers/staging/comedi/rt.c
+++ b/drivers/staging/comedi/rt.c
@@ -57,7 +57,7 @@ struct comedi_irq_struct {
irqreturn_t(*handler) (int irq, void *dev_id PT_REGS_ARG);
unsigned long flags;
const char *device;
- comedi_device *dev_id;
+ struct comedi_device *dev_id;
};
static int comedi_rt_get_irq(struct comedi_irq_struct *it);
@@ -67,7 +67,7 @@ static struct comedi_irq_struct *comedi_irqs[NR_IRQS];
int comedi_request_irq(unsigned irq, irqreturn_t(*handler) (int,
void *PT_REGS_ARG), unsigned long flags, const char *device,
- comedi_device * dev_id)
+ struct comedi_device *dev_id)
{
struct comedi_irq_struct *it;
int ret;
@@ -78,15 +78,15 @@ int comedi_request_irq(unsigned irq, irqreturn_t(*handler) (int,
ret = request_irq(irq, handler, unshared_flags, device, dev_id);
if (ret < 0) {
- // we failed, so fall back on allowing shared interrupt (which we won't ever make RT)
+ /* we failed, so fall back on allowing shared interrupt (which we won't ever make RT) */
if (flags & IRQF_SHARED) {
rt_printk
("comedi: cannot get unshared interrupt, will not use RT interrupts.\n");
ret = request_irq(irq, handler, flags, device, dev_id);
}
- if (ret < 0) {
+ if (ret < 0)
return ret;
- }
+
} else {
it = kzalloc(sizeof(struct comedi_irq_struct), GFP_KERNEL);
if (!it)
@@ -102,7 +102,7 @@ int comedi_request_irq(unsigned irq, irqreturn_t(*handler) (int,
return 0;
}
-void comedi_free_irq(unsigned int irq, comedi_device * dev_id)
+void comedi_free_irq(unsigned int irq, struct comedi_device *dev_id)
{
struct comedi_irq_struct *it;
@@ -121,7 +121,7 @@ void comedi_free_irq(unsigned int irq, comedi_device * dev_id)
comedi_irqs[irq] = NULL;
}
-int comedi_switch_to_rt(comedi_device * dev)
+int comedi_switch_to_rt(struct comedi_device *dev)
{
struct comedi_irq_struct *it;
unsigned long flags;
@@ -145,7 +145,7 @@ int comedi_switch_to_rt(comedi_device * dev)
return 0;
}
-void comedi_switch_to_non_rt(comedi_device * dev)
+void comedi_switch_to_non_rt(struct comedi_device *dev)
{
struct comedi_irq_struct *it;
unsigned long flags;
@@ -170,7 +170,7 @@ void wake_up_int_handler(int arg1, void *arg2)
wake_up_interruptible((wait_queue_head_t *) arg2);
}
-void comedi_rt_pend_wakeup(wait_queue_head_t * q)
+void comedi_rt_pend_wakeup(wait_queue_head_t *q)
{
rt_pend_call(wake_up_int_handler, 0, q);
}
@@ -180,7 +180,7 @@ void comedi_rt_pend_wakeup(wait_queue_head_t * q)
#ifndef HAVE_RT_REQUEST_IRQ_WITH_ARG
#define DECLARE_VOID_IRQ(irq) \
-static void handle_void_irq_ ## irq (void){ handle_void_irq(irq);}
+static void handle_void_irq_ ## irq (void){ handle_void_irq(irq); }
static void handle_void_irq(int irq)
{
@@ -192,7 +192,7 @@ static void handle_void_irq(int irq)
return;
}
it->handler(irq, it->dev_id PT_REGS_NULL);
- rt_enable_irq(irq); //needed by rtai-adeos, seems like it shouldn't hurt earlier versions
+ rt_enable_irq(irq); /* needed by rtai-adeos, seems like it shouldn't hurt earlier versions */
}
DECLARE_VOID_IRQ(0);
@@ -220,8 +220,7 @@ DECLARE_VOID_IRQ(21);
DECLARE_VOID_IRQ(22);
DECLARE_VOID_IRQ(23);
-typedef void (*V_FP_V) (void);
-static V_FP_V handle_void_irq_ptrs[] = {
+static void handle_void_irq_ptrs[] = {
handle_void_irq_0,
handle_void_irq_1,
handle_void_irq_2,
@@ -402,11 +401,11 @@ static int comedi_rt_release_irq(struct comedi_irq_struct *it)
void comedi_rt_init(void)
{
- //rt_pend_tq_init();
+ /* rt_pend_tq_init(); */
}
void comedi_rt_cleanup(void)
{
- //rt_pend_tq_cleanup();
+ /* rt_pend_tq_cleanup(); */
}
#endif
diff --git a/drivers/staging/comedi/rt_pend_tq.c b/drivers/staging/comedi/rt_pend_tq.c
index 995f076e0af..f9dfd9d40cd 100644
--- a/drivers/staging/comedi/rt_pend_tq.c
+++ b/drivers/staging/comedi/rt_pend_tq.c
@@ -3,7 +3,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sched.h>
-#include "comedidev.h" // for rt spinlocks
+#include "comedidev.h" /* for rt spinlocks */
#include "rt_pend_tq.h"
#ifdef CONFIG_COMEDI_RTAI
#include <rtai.h>
@@ -25,9 +25,9 @@ volatile static struct rt_pend_tq rt_pend_tq[RT_PEND_TQ_SIZE];
volatile static struct rt_pend_tq *volatile rt_pend_head = rt_pend_tq,
*volatile rt_pend_tail = rt_pend_tq;
int rt_pend_tq_irq = 0;
-spinlock_t rt_pend_tq_lock = SPIN_LOCK_UNLOCKED;
+DEFINE_SPINLOCK(rt_pend_tq_lock);
-// WARNING: following code not checked against race conditions yet.
+/* WARNING: following code not checked against race conditions yet. */
#define INC_CIRCULAR_PTR(ptr,begin,size) do {if(++(ptr)>=(begin)+(size)) (ptr)=(begin); } while(0)
#define DEC_CIRCULAR_PTR(ptr,begin,size) do {if(--(ptr)<(begin)) (ptr)=(begin)+(size)-1; } while(0)
@@ -42,7 +42,7 @@ int rt_pend_call(void (*func) (int arg1, void *arg2), int arg1, void *arg2)
comedi_spin_lock_irqsave(&rt_pend_tq_lock, flags);
INC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
if (rt_pend_head == rt_pend_tail) {
- // overflow, we just refuse to take this request
+ /* overflow, we just refuse to take this request */
DEC_CIRCULAR_PTR(rt_pend_head, rt_pend_tq, RT_PEND_TQ_SIZE);
comedi_spin_unlock_irqrestore(&rt_pend_tq_lock, flags);
return -EAGAIN;
diff --git a/drivers/staging/dst/Kconfig b/drivers/staging/dst/Kconfig
new file mode 100644
index 00000000000..448d342ac2a
--- /dev/null
+++ b/drivers/staging/dst/Kconfig
@@ -0,0 +1,67 @@
+config DST
+ tristate "Distributed storage"
+ depends on NET && CRYPTO && SYSFS && BLK_DEV
+ select CONNECTOR
+ ---help---
+ DST is a network block device storage, which can be used to organize
+ exported storage on the remote nodes into the local block device.
+
+ DST works on top of any network media and protocol; it is just a matter
+ of configuration utility to understand the correct addresses. The most
+ common example is TCP over IP, which allows to pass through firewalls and
+ create remote backup storage in a different datacenter. DST requires
+ single port to be enabled on the exporting node and outgoing connections
+ on the local node.
+
+ DST works with in-kernel client and server, which improves performance by
+ eliminating unneded data copies and by not depending on the version
+ of the external IO components. It requires userspace configuration utility
+ though.
+
+ DST uses transaction model, when each store has to be explicitly acked
+ from the remote node to be considered as successfully written. There
+ may be lots of in-flight transactions. When remote host does not ack
+ the transaction it will be resent predefined number of times with specified
+ timeouts between them. All those parameters are configurable. Transactions
+ are marked as failed after all resends complete unsuccessfully; having
+ long enough resend timeout and/or large number of resends allows not to
+ return error to the higher (FS usually) layer in case of short network
+ problems or remote node outages. In case of network RAID setup this means
+ that storage will not degrade until transactions are marked as failed, and
+ thus will not force checksum recalculation and data rebuild. In case of
+ connection failure DST will try to reconnect to the remote node automatically.
+ DST sends ping commands at idle time to detect if remote node is alive.
+
+ Because of transactional model it is possible to use zero-copy sending
+ without worry of data corruption (which in turn could be detected by the
+ strong checksums though).
+
+ DST may fully encrypt the data channel in case of untrusted channel and implement
+ strong checksum of the transferred data. It is possible to configure algorithms
+ and crypto keys; they should match on both sides of the network channel.
+ Crypto processing does not introduce noticeble performance overhead, since DST
+ uses configurable pool of threads to perform crypto processing.
+
+ DST utilizes memory pool model of all its transaction allocations (it is the
+ only additional allocation on the client) and server allocations (bio pools,
+ while pages are allocated from the slab).
+
+ At startup DST performs a simple negotiation with the export node to determine
+ access permissions and size of the exported storage. It can be extended if
+ new parameters should be autonegotiated.
+
+ DST carries block IO flags in the protocol, which allows to transparently implement
+ barriers and sync/flush operations. Those flags are used in the export node where
+ IO against the local storage is performed, which means that sync write will be sync
+ on the remote node too, which in turn improves data integrity and improved resistance
+ to errors and data corruption during power outages or storage damages.
+
+ Homepage: http://www.ioremap.net/projects/dst
+ Userspace configuration utility and the latest releases: http://www.ioremap.net/archive/dst/
+
+config DST_DEBUG
+ bool "DST debug"
+ depends on DST
+ ---help---
+ This option will enable HEAVY debugging of the DST.
+ Turn it on ONLY if you have to debug some really obscure problem.
diff --git a/drivers/staging/dst/Makefile b/drivers/staging/dst/Makefile
new file mode 100644
index 00000000000..3a8b0cf9643
--- /dev/null
+++ b/drivers/staging/dst/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_DST) += nst.o
+
+nst-y := dcore.o state.o export.o thread_pool.o crypto.o trans.o
diff --git a/drivers/staging/dst/crypto.c b/drivers/staging/dst/crypto.c
new file mode 100644
index 00000000000..7250f90f592
--- /dev/null
+++ b/drivers/staging/dst/crypto.c
@@ -0,0 +1,731 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bio.h>
+#include <linux/crypto.h>
+#include <linux/dst.h>
+#include <linux/kernel.h>
+#include <linux/scatterlist.h>
+#include <linux/slab.h>
+
+/*
+ * Tricky bastard, but IV can be more complex with time...
+ */
+static inline u64 dst_gen_iv(struct dst_trans *t)
+{
+ return t->gen;
+}
+
+/*
+ * Crypto machinery: hash/cipher support for the given crypto controls.
+ */
+static struct crypto_hash *dst_init_hash(struct dst_crypto_ctl *ctl, u8 *key)
+{
+ int err;
+ struct crypto_hash *hash;
+
+ hash = crypto_alloc_hash(ctl->hash_algo, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(hash)) {
+ err = PTR_ERR(hash);
+ dprintk("%s: failed to allocate hash '%s', err: %d.\n",
+ __func__, ctl->hash_algo, err);
+ goto err_out_exit;
+ }
+
+ ctl->crypto_attached_size = crypto_hash_digestsize(hash);
+
+ if (!ctl->hash_keysize)
+ return hash;
+
+ err = crypto_hash_setkey(hash, key, ctl->hash_keysize);
+ if (err) {
+ dprintk("%s: failed to set key for hash '%s', err: %d.\n",
+ __func__, ctl->hash_algo, err);
+ goto err_out_free;
+ }
+
+ return hash;
+
+err_out_free:
+ crypto_free_hash(hash);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static struct crypto_ablkcipher *dst_init_cipher(struct dst_crypto_ctl *ctl, u8 *key)
+{
+ int err = -EINVAL;
+ struct crypto_ablkcipher *cipher;
+
+ if (!ctl->cipher_keysize)
+ goto err_out_exit;
+
+ cipher = crypto_alloc_ablkcipher(ctl->cipher_algo, 0, 0);
+ if (IS_ERR(cipher)) {
+ err = PTR_ERR(cipher);
+ dprintk("%s: failed to allocate cipher '%s', err: %d.\n",
+ __func__, ctl->cipher_algo, err);
+ goto err_out_exit;
+ }
+
+ crypto_ablkcipher_clear_flags(cipher, ~0);
+
+ err = crypto_ablkcipher_setkey(cipher, key, ctl->cipher_keysize);
+ if (err) {
+ dprintk("%s: failed to set key for cipher '%s', err: %d.\n",
+ __func__, ctl->cipher_algo, err);
+ goto err_out_free;
+ }
+
+ return cipher;
+
+err_out_free:
+ crypto_free_ablkcipher(cipher);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+/*
+ * Crypto engine has a pool of pages to encrypt data into before sending
+ * it over the network. This pool is freed/allocated here.
+ */
+static void dst_crypto_pages_free(struct dst_crypto_engine *e)
+{
+ unsigned int i;
+
+ for (i=0; i<e->page_num; ++i)
+ __free_page(e->pages[i]);
+ kfree(e->pages);
+}
+
+static int dst_crypto_pages_alloc(struct dst_crypto_engine *e, int num)
+{
+ int i;
+
+ e->pages = kmalloc(num * sizeof(struct page **), GFP_KERNEL);
+ if (!e->pages)
+ return -ENOMEM;
+
+ for (i=0; i<num; ++i) {
+ e->pages[i] = alloc_page(GFP_KERNEL);
+ if (!e->pages[i])
+ goto err_out_free_pages;
+ }
+
+ e->page_num = num;
+ return 0;
+
+err_out_free_pages:
+ while (--i >= 0)
+ __free_page(e->pages[i]);
+
+ kfree(e->pages);
+ return -ENOMEM;
+}
+
+/*
+ * Initialize crypto engine for given node.
+ * Setup cipher/hash, keys, pool of threads and private data.
+ */
+static int dst_crypto_engine_init(struct dst_crypto_engine *e, struct dst_node *n)
+{
+ int err;
+ struct dst_crypto_ctl *ctl = &n->crypto;
+
+ err = dst_crypto_pages_alloc(e, n->max_pages);
+ if (err)
+ goto err_out_exit;
+
+ e->size = PAGE_SIZE;
+ e->data = kmalloc(e->size, GFP_KERNEL);
+ if (!e->data) {
+ err = -ENOMEM;
+ goto err_out_free_pages;
+ }
+
+ if (ctl->hash_algo[0]) {
+ e->hash = dst_init_hash(ctl, n->hash_key);
+ if (IS_ERR(e->hash)) {
+ err = PTR_ERR(e->hash);
+ e->hash = NULL;
+ goto err_out_free;
+ }
+ }
+
+ if (ctl->cipher_algo[0]) {
+ e->cipher = dst_init_cipher(ctl, n->cipher_key);
+ if (IS_ERR(e->cipher)) {
+ err = PTR_ERR(e->cipher);
+ e->cipher = NULL;
+ goto err_out_free_hash;
+ }
+ }
+
+ return 0;
+
+err_out_free_hash:
+ crypto_free_hash(e->hash);
+err_out_free:
+ kfree(e->data);
+err_out_free_pages:
+ dst_crypto_pages_free(e);
+err_out_exit:
+ return err;
+}
+
+static void dst_crypto_engine_exit(struct dst_crypto_engine *e)
+{
+ if (e->hash)
+ crypto_free_hash(e->hash);
+ if (e->cipher)
+ crypto_free_ablkcipher(e->cipher);
+ dst_crypto_pages_free(e);
+ kfree(e->data);
+}
+
+/*
+ * Waiting for cipher processing to be completed.
+ */
+struct dst_crypto_completion
+{
+ struct completion complete;
+ int error;
+};
+
+static void dst_crypto_complete(struct crypto_async_request *req, int err)
+{
+ struct dst_crypto_completion *c = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
+ c->error = err;
+ complete(&c->complete);
+}
+
+static int dst_crypto_process(struct ablkcipher_request *req,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src,
+ void *iv, int enc, unsigned long timeout)
+{
+ struct dst_crypto_completion c;
+ int err;
+
+ init_completion(&c.complete);
+ c.error = -EINPROGRESS;
+
+ ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ dst_crypto_complete, &c);
+
+ ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
+
+ if (enc)
+ err = crypto_ablkcipher_encrypt(req);
+ else
+ err = crypto_ablkcipher_decrypt(req);
+
+ switch (err) {
+ case -EINPROGRESS:
+ case -EBUSY:
+ err = wait_for_completion_interruptible_timeout(&c.complete,
+ timeout);
+ if (!err)
+ err = -ETIMEDOUT;
+ else
+ err = c.error;
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+/*
+ * DST uses generic iteration approach for data crypto processing.
+ * Single block IO request is switched into array of scatterlists,
+ * which are submitted to the crypto processing iterator.
+ *
+ * Input and output iterator initialization are different, since
+ * in output case we can not encrypt data in-place and need a
+ * temporary storage, which is then being sent to the remote peer.
+ */
+static int dst_trans_iter_out(struct bio *bio, struct dst_crypto_engine *e,
+ int (* iterator) (struct dst_crypto_engine *e,
+ struct scatterlist *dst,
+ struct scatterlist *src))
+{
+ struct bio_vec *bv;
+ int err, i;
+
+ sg_init_table(e->src, bio->bi_vcnt);
+ sg_init_table(e->dst, bio->bi_vcnt);
+
+ bio_for_each_segment(bv, bio, i) {
+ sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+ sg_set_page(&e->dst[i], e->pages[i], bv->bv_len, bv->bv_offset);
+
+ err = iterator(e, &e->dst[i], &e->src[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int dst_trans_iter_in(struct bio *bio, struct dst_crypto_engine *e,
+ int (* iterator) (struct dst_crypto_engine *e,
+ struct scatterlist *dst,
+ struct scatterlist *src))
+{
+ struct bio_vec *bv;
+ int err, i;
+
+ sg_init_table(e->src, bio->bi_vcnt);
+ sg_init_table(e->dst, bio->bi_vcnt);
+
+ bio_for_each_segment(bv, bio, i) {
+ sg_set_page(&e->src[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+ sg_set_page(&e->dst[i], bv->bv_page, bv->bv_len, bv->bv_offset);
+
+ err = iterator(e, &e->dst[i], &e->src[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
+static int dst_crypt_iterator(struct dst_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ struct ablkcipher_request *req = e->data;
+ u8 iv[32];
+
+ memset(iv, 0, sizeof(iv));
+
+ memcpy(iv, &e->iv, sizeof(e->iv));
+
+ return dst_crypto_process(req, sg_dst, sg_src, iv, e->enc, e->timeout);
+}
+
+static int dst_crypt(struct dst_crypto_engine *e, struct bio *bio)
+{
+ struct ablkcipher_request *req = e->data;
+
+ memset(req, 0, sizeof(struct ablkcipher_request));
+ ablkcipher_request_set_tfm(req, e->cipher);
+
+ if (e->enc)
+ return dst_trans_iter_out(bio, e, dst_crypt_iterator);
+ else
+ return dst_trans_iter_in(bio, e, dst_crypt_iterator);
+}
+
+static int dst_hash_iterator(struct dst_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ return crypto_hash_update(e->data, sg_src, sg_src->length);
+}
+
+static int dst_hash(struct dst_crypto_engine *e, struct bio *bio, void *dst)
+{
+ struct hash_desc *desc = e->data;
+ int err;
+
+ desc->tfm = e->hash;
+ desc->flags = 0;
+
+ err = crypto_hash_init(desc);
+ if (err)
+ return err;
+
+ err = dst_trans_iter_in(bio, e, dst_hash_iterator);
+ if (err)
+ return err;
+
+ err = crypto_hash_final(desc, dst);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+/*
+ * Initialize/cleanup a crypto thread. The only thing it should
+ * do is to allocate a pool of pages as temporary storage.
+ * And to setup cipher and/or hash.
+ */
+static void *dst_crypto_thread_init(void *data)
+{
+ struct dst_node *n = data;
+ struct dst_crypto_engine *e;
+ int err = -ENOMEM;
+
+ e = kzalloc(sizeof(struct dst_crypto_engine), GFP_KERNEL);
+ if (!e)
+ goto err_out_exit;
+ e->src = kcalloc(2 * n->max_pages, sizeof(struct scatterlist),
+ GFP_KERNEL);
+ if (!e->src)
+ goto err_out_free;
+
+ e->dst = e->src + n->max_pages;
+
+ err = dst_crypto_engine_init(e, n);
+ if (err)
+ goto err_out_free_all;
+
+ return e;
+
+err_out_free_all:
+ kfree(e->src);
+err_out_free:
+ kfree(e);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static void dst_crypto_thread_cleanup(void *private)
+{
+ struct dst_crypto_engine *e = private;
+
+ dst_crypto_engine_exit(e);
+ kfree(e->src);
+ kfree(e);
+}
+
+/*
+ * Initialize crypto engine for given node: store keys, create pool
+ * of threads, initialize each one.
+ *
+ * Each thread has unique ID, but 0 and 1 are reserved for receiving and accepting
+ * threads (if export node), so IDs could start from 2, but starting them
+ * from 10 allows easily understand what this thread is for.
+ */
+int dst_node_crypto_init(struct dst_node *n, struct dst_crypto_ctl *ctl)
+{
+ void *key = (ctl + 1);
+ int err = -ENOMEM, i;
+ char name[32];
+
+ if (ctl->hash_keysize) {
+ n->hash_key = kmalloc(ctl->hash_keysize, GFP_KERNEL);
+ if (!n->hash_key)
+ goto err_out_exit;
+ memcpy(n->hash_key, key, ctl->hash_keysize);
+ }
+
+ if (ctl->cipher_keysize) {
+ n->cipher_key = kmalloc(ctl->cipher_keysize, GFP_KERNEL);
+ if (!n->cipher_key)
+ goto err_out_free_hash;
+ memcpy(n->cipher_key, key, ctl->cipher_keysize);
+ }
+ memcpy(&n->crypto, ctl, sizeof(struct dst_crypto_ctl));
+
+ for (i=0; i<ctl->thread_num; ++i) {
+ snprintf(name, sizeof(name), "%s-crypto-%d", n->name, i);
+ /* Unique ids... */
+ err = thread_pool_add_worker(n->pool, name, i+10,
+ dst_crypto_thread_init, dst_crypto_thread_cleanup, n);
+ if (err)
+ goto err_out_free_threads;
+ }
+
+ return 0;
+
+err_out_free_threads:
+ while (--i >= 0)
+ thread_pool_del_worker_id(n->pool, i+10);
+
+ if (ctl->cipher_keysize)
+ kfree(n->cipher_key);
+ ctl->cipher_keysize = 0;
+err_out_free_hash:
+ if (ctl->hash_keysize)
+ kfree(n->hash_key);
+ ctl->hash_keysize = 0;
+err_out_exit:
+ return err;
+}
+
+void dst_node_crypto_exit(struct dst_node *n)
+{
+ struct dst_crypto_ctl *ctl = &n->crypto;
+
+ if (ctl->cipher_algo[0] || ctl->hash_algo[0]) {
+ kfree(n->hash_key);
+ kfree(n->cipher_key);
+ }
+}
+
+/*
+ * Thrad pool setup callback. Just stores a transaction in private data.
+ */
+static int dst_trans_crypto_setup(void *crypto_engine, void *trans)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+
+ e->private = trans;
+ return 0;
+}
+
+#if 0
+static void dst_dump_bio(struct bio *bio)
+{
+ u8 *p;
+ struct bio_vec *bv;
+ int i;
+
+ bio_for_each_segment(bv, bio, i) {
+ dprintk("%s: %llu/%u: size: %u, offset: %u, data: ",
+ __func__, bio->bi_sector, bio->bi_size,
+ bv->bv_len, bv->bv_offset);
+
+ p = kmap(bv->bv_page) + bv->bv_offset;
+ for (i=0; i<bv->bv_len; ++i)
+ printk("%02x ", p[i]);
+ kunmap(bv->bv_page);
+ printk("\n");
+ }
+}
+#endif
+
+/*
+ * Encrypt/hash data and send it to the network.
+ */
+static int dst_crypto_process_sending(struct dst_crypto_engine *e,
+ struct bio *bio, u8 *hash)
+{
+ int err;
+
+ if (e->cipher) {
+ err = dst_crypt(e, bio);
+ if (err)
+ goto err_out_exit;
+ }
+
+ if (e->hash) {
+ err = dst_hash(e, bio, hash);
+ if (err)
+ goto err_out_exit;
+
+#ifdef CONFIG_DST_DEBUG
+ {
+ unsigned int i;
+
+ /* dst_dump_bio(bio); */
+
+ printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash: ",
+ __func__, (u64)bio->bi_sector,
+ bio->bi_size, bio_data_dir(bio));
+ for (i=0; i<crypto_hash_digestsize(e->hash); ++i)
+ printk("%02x ", hash[i]);
+ printk("\n");
+ }
+#endif
+ }
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Check if received data is valid. Decipher if it is.
+ */
+static int dst_crypto_process_receiving(struct dst_crypto_engine *e,
+ struct bio *bio, u8 *hash, u8 *recv_hash)
+{
+ int err;
+
+ if (e->hash) {
+ int mismatch;
+
+ err = dst_hash(e, bio, hash);
+ if (err)
+ goto err_out_exit;
+
+ mismatch = !!memcmp(recv_hash, hash,
+ crypto_hash_digestsize(e->hash));
+#ifdef CONFIG_DST_DEBUG
+ /* dst_dump_bio(bio); */
+
+ printk(KERN_DEBUG "%s: bio: %llu/%u, rw: %lu, hash mismatch: %d",
+ __func__, (u64)bio->bi_sector, bio->bi_size,
+ bio_data_dir(bio), mismatch);
+ if (mismatch) {
+ unsigned int i;
+
+ printk(", recv/calc: ");
+ for (i=0; i<crypto_hash_digestsize(e->hash); ++i) {
+ printk("%02x/%02x ", recv_hash[i], hash[i]);
+ }
+ }
+ printk("\n");
+#endif
+ err = -1;
+ if (mismatch)
+ goto err_out_exit;
+ }
+
+ if (e->cipher) {
+ err = dst_crypt(e, bio);
+ if (err)
+ goto err_out_exit;
+ }
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Thread pool callback to encrypt data and send it to the netowork.
+ */
+static int dst_trans_crypto_action(void *crypto_engine, void *schedule_data)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+ struct dst_trans *t = schedule_data;
+ struct bio *bio = t->bio;
+ int err;
+
+ dprintk("%s: t: %p, gen: %llu, cipher: %p, hash: %p.\n",
+ __func__, t, t->gen, e->cipher, e->hash);
+
+ e->enc = t->enc;
+ e->iv = dst_gen_iv(t);
+
+ if (bio_data_dir(bio) == WRITE) {
+ err = dst_crypto_process_sending(e, bio, t->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ if (e->hash) {
+ t->cmd.csize = crypto_hash_digestsize(e->hash);
+ t->cmd.size += t->cmd.csize;
+ }
+
+ return dst_trans_send(t);
+ } else {
+ u8 *hash = e->data + e->size/2;
+
+ err = dst_crypto_process_receiving(e, bio, hash, t->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ dst_trans_remove(t);
+ dst_trans_put(t);
+ }
+
+ return 0;
+
+err_out_exit:
+ t->error = err;
+ dst_trans_put(t);
+ return err;
+}
+
+/*
+ * Schedule crypto processing for given transaction.
+ */
+int dst_trans_crypto(struct dst_trans *t)
+{
+ struct dst_node *n = t->n;
+ int err;
+
+ err = thread_pool_schedule(n->pool,
+ dst_trans_crypto_setup, dst_trans_crypto_action,
+ t, MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ dst_trans_put(t);
+ return err;
+}
+
+/*
+ * Crypto machinery for the export node.
+ */
+static int dst_export_crypto_setup(void *crypto_engine, void *bio)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+
+ e->private = bio;
+ return 0;
+}
+
+static int dst_export_crypto_action(void *crypto_engine, void *schedule_data)
+{
+ struct dst_crypto_engine *e = crypto_engine;
+ struct bio *bio = schedule_data;
+ struct dst_export_priv *p = bio->bi_private;
+ int err;
+
+ dprintk("%s: e: %p, data: %p, bio: %llu/%u, dir: %lu.\n", __func__,
+ e, e->data, (u64)bio->bi_sector, bio->bi_size, bio_data_dir(bio));
+
+ e->enc = (bio_data_dir(bio) == READ);
+ e->iv = p->cmd.id;
+
+ if (bio_data_dir(bio) == WRITE) {
+ u8 *hash = e->data + e->size/2;
+
+ err = dst_crypto_process_receiving(e, bio, hash, p->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ generic_make_request(bio);
+ } else {
+ err = dst_crypto_process_sending(e, bio, p->cmd.hash);
+ if (err)
+ goto err_out_exit;
+
+ if (e->hash) {
+ p->cmd.csize = crypto_hash_digestsize(e->hash);
+ p->cmd.size += p->cmd.csize;
+ }
+
+ err = dst_export_send_bio(bio);
+ }
+ return 0;
+
+err_out_exit:
+ bio_put(bio);
+ return err;
+}
+
+int dst_export_crypto(struct dst_node *n, struct bio *bio)
+{
+ int err;
+
+ err = thread_pool_schedule(n->pool,
+ dst_export_crypto_setup, dst_export_crypto_action,
+ bio, MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ bio_put(bio);
+ return err;
+}
diff --git a/drivers/staging/dst/dcore.c b/drivers/staging/dst/dcore.c
new file mode 100644
index 00000000000..fad25b75304
--- /dev/null
+++ b/drivers/staging/dst/dcore.c
@@ -0,0 +1,995 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/buffer_head.h>
+#include <linux/connector.h>
+#include <linux/dst.h>
+#include <linux/device.h>
+#include <linux/jhash.h>
+#include <linux/idr.h>
+#include <linux/init.h>
+#include <linux/namei.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+
+#include <linux/in.h>
+#include <linux/in6.h>
+
+#include <net/sock.h>
+
+static int dst_major;
+
+static DEFINE_MUTEX(dst_hash_lock);
+static struct list_head *dst_hashtable;
+static unsigned int dst_hashtable_size = 128;
+module_param(dst_hashtable_size, uint, 0644);
+
+static char dst_name[] = "Dementianting goldfish";
+
+static DEFINE_IDR(dst_index_idr);
+static struct cb_id cn_dst_id = { CN_DST_IDX, CN_DST_VAL };
+
+/*
+ * DST sysfs tree for device called 'storage':
+ *
+ * /sys/bus/dst/devices/storage/
+ * /sys/bus/dst/devices/storage/type : 192.168.4.80:1025
+ * /sys/bus/dst/devices/storage/size : 800
+ * /sys/bus/dst/devices/storage/name : storage
+ */
+
+static int dst_dev_match(struct device *dev, struct device_driver *drv)
+{
+ return 1;
+}
+
+static struct bus_type dst_dev_bus_type = {
+ .name = "dst",
+ .match = &dst_dev_match,
+};
+
+static void dst_node_release(struct device *dev)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+
+ kfree(info);
+}
+
+static struct device dst_node_dev = {
+ .bus = &dst_dev_bus_type,
+ .release = &dst_node_release
+};
+
+/*
+ * Setting size of the node after it was changed.
+ */
+static void dst_node_set_size(struct dst_node *n)
+{
+ struct block_device *bdev;
+
+ set_capacity(n->disk, n->size >> 9);
+
+ bdev = bdget_disk(n->disk, 0);
+ if (bdev) {
+ mutex_lock(&bdev->bd_inode->i_mutex);
+ i_size_write(bdev->bd_inode, n->size);
+ mutex_unlock(&bdev->bd_inode->i_mutex);
+ bdput(bdev);
+ }
+}
+
+/*
+ * Distributed storage request processing function.
+ */
+static int dst_request(struct request_queue *q, struct bio *bio)
+{
+ struct dst_node *n = q->queuedata;
+ int err = -EIO;
+
+ if (bio_empty_barrier(bio) && !q->prepare_discard_fn) {
+ /*
+ * This is a dirty^Wnice hack, but if we complete this
+ * operation with -EOPNOTSUPP like intended, XFS
+ * will stuck and freeze the machine. This may be
+ * not particulary XFS problem though, but it is the
+ * only FS which sends empty barrier at umount time
+ * I worked with.
+ *
+ * Empty barriers are not allowed anyway, see 51fd77bd9f512
+ * for example, although later it was changed to bio_discard()
+ * only, which does not work in this case.
+ */
+ //err = -EOPNOTSUPP;
+ err = 0;
+ goto end_io;
+ }
+
+ bio_get(bio);
+
+ return dst_process_bio(n, bio);
+
+end_io:
+ bio_endio(bio, err);
+ return err;
+}
+
+/*
+ * Open/close callbacks for appropriate block device.
+ */
+static int dst_bdev_open(struct block_device *bdev, fmode_t mode)
+{
+ struct dst_node *n = bdev->bd_disk->private_data;
+
+ dst_node_get(n);
+ return 0;
+}
+
+static int dst_bdev_release(struct gendisk *disk, fmode_t mode)
+{
+ struct dst_node *n = disk->private_data;
+
+ dst_node_put(n);
+ return 0;
+}
+
+static struct block_device_operations dst_blk_ops = {
+ .open = dst_bdev_open,
+ .release = dst_bdev_release,
+ .owner = THIS_MODULE,
+};
+
+/*
+ * Block layer binding - disk is created when array is fully configured
+ * by userspace request.
+ */
+static int dst_node_create_disk(struct dst_node *n)
+{
+ int err = -ENOMEM;
+ u32 index = 0;
+
+ n->queue = blk_init_queue(NULL, NULL);
+ if (!n->queue)
+ goto err_out_exit;
+
+ n->queue->queuedata = n;
+ blk_queue_make_request(n->queue, dst_request);
+ blk_queue_max_phys_segments(n->queue, n->max_pages);
+ blk_queue_max_hw_segments(n->queue, n->max_pages);
+
+ err = -ENOMEM;
+ n->disk = alloc_disk(1);
+ if (!n->disk)
+ goto err_out_free_queue;
+
+ if (!(n->state->permissions & DST_PERM_WRITE)) {
+ printk(KERN_INFO "DST node %s attached read-only.\n", n->name);
+ set_disk_ro(n->disk, 1);
+ }
+
+ if (!idr_pre_get(&dst_index_idr, GFP_KERNEL))
+ goto err_out_put;
+
+ mutex_lock(&dst_hash_lock);
+ err = idr_get_new(&dst_index_idr, NULL, &index);
+ mutex_unlock(&dst_hash_lock);
+ if (err)
+ goto err_out_put;
+
+ n->disk->major = dst_major;
+ n->disk->first_minor = index;
+ n->disk->fops = &dst_blk_ops;
+ n->disk->queue = n->queue;
+ n->disk->private_data = n;
+ snprintf(n->disk->disk_name, sizeof(n->disk->disk_name), "dst-%s", n->name);
+
+ return 0;
+
+err_out_put:
+ put_disk(n->disk);
+err_out_free_queue:
+ blk_cleanup_queue(n->queue);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Sysfs machinery: show device's size.
+ */
+static ssize_t dst_show_size(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+
+ return sprintf(buf, "%llu\n", info->size);
+}
+
+/*
+ * Show local exported device.
+ */
+static ssize_t dst_show_local(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+
+ return sprintf(buf, "%s\n", info->local);
+}
+
+/*
+ * Shows type of the remote node - device major/minor number
+ * for local nodes and address (af_inet ipv4/ipv6 only) for remote nodes.
+ */
+static ssize_t dst_show_type(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct dst_info *info = container_of(dev, struct dst_info, device);
+ int family = info->net.addr.sa_family;
+
+ if (family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&info->net.addr;
+ return sprintf(buf, "%u.%u.%u.%u:%d\n",
+ NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&info->net.addr;
+ return sprintf(buf,
+ "%pi6:%d\n",
+ &sin->sin6_addr, ntohs(sin->sin6_port));
+ } else {
+ int i, sz = PAGE_SIZE - 2; /* 0 symbol and '\n' below */
+ int size, addrlen = info->net.addr.sa_data_len;
+ unsigned char *a = (unsigned char *)&info->net.addr.sa_data;
+ char *buf_orig = buf;
+
+ size = snprintf(buf, sz, "family: %d, addrlen: %u, addr: ",
+ family, addrlen);
+ sz -= size;
+ buf += size;
+
+ for (i=0; i<addrlen; ++i) {
+ if (sz < 3)
+ break;
+
+ size = snprintf(buf, sz, "%02x ", a[i]);
+ sz -= size;
+ buf += size;
+ }
+ buf += sprintf(buf, "\n");
+
+ return buf - buf_orig;
+ }
+ return 0;
+}
+
+static struct device_attribute dst_node_attrs[] = {
+ __ATTR(size, 0444, dst_show_size, NULL),
+ __ATTR(type, 0444, dst_show_type, NULL),
+ __ATTR(local, 0444, dst_show_local, NULL),
+};
+
+static int dst_create_node_attributes(struct dst_node *n)
+{
+ int err, i;
+
+ for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i) {
+ err = device_create_file(&n->info->device,
+ &dst_node_attrs[i]);
+ if (err)
+ goto err_out_remove_all;
+ }
+ return 0;
+
+err_out_remove_all:
+ while (--i >= 0)
+ device_remove_file(&n->info->device,
+ &dst_node_attrs[i]);
+
+ return err;
+}
+
+static void dst_remove_node_attributes(struct dst_node *n)
+{
+ int i;
+
+ for (i=0; i<ARRAY_SIZE(dst_node_attrs); ++i)
+ device_remove_file(&n->info->device,
+ &dst_node_attrs[i]);
+}
+
+/*
+ * Sysfs cleanup and initialization.
+ * Shows number of useful parameters.
+ */
+static void dst_node_sysfs_exit(struct dst_node *n)
+{
+ if (n->info) {
+ dst_remove_node_attributes(n);
+ device_unregister(&n->info->device);
+ n->info = NULL;
+ }
+}
+
+static int dst_node_sysfs_init(struct dst_node *n)
+{
+ int err;
+
+ n->info = kzalloc(sizeof(struct dst_info), GFP_KERNEL);
+ if (!n->info)
+ return -ENOMEM;
+
+ memcpy(&n->info->device, &dst_node_dev, sizeof(struct device));
+ n->info->size = n->size;
+
+ dev_set_name(&n->info->device, "dst-%s", n->name);
+ err = device_register(&n->info->device);
+ if (err) {
+ dprintk(KERN_ERR "Failed to register node '%s', err: %d.\n",
+ n->name, err);
+ goto err_out_exit;
+ }
+
+ dst_create_node_attributes(n);
+
+ return 0;
+
+err_out_exit:
+ kfree(n->info);
+ n->info = NULL;
+ return err;
+}
+
+/*
+ * DST node hash tables machinery.
+ */
+static inline unsigned int dst_hash(char *str, unsigned int size)
+{
+ return (jhash(str, size, 0) % dst_hashtable_size);
+}
+
+static void dst_node_remove(struct dst_node *n)
+{
+ mutex_lock(&dst_hash_lock);
+ list_del_init(&n->node_entry);
+ mutex_unlock(&dst_hash_lock);
+}
+
+static void dst_node_add(struct dst_node *n)
+{
+ unsigned hash = dst_hash(n->name, sizeof(n->name));
+
+ mutex_lock(&dst_hash_lock);
+ list_add_tail(&n->node_entry, &dst_hashtable[hash]);
+ mutex_unlock(&dst_hash_lock);
+}
+
+/*
+ * Cleaning node when it is about to be freed.
+ * There are still users of the socket though,
+ * so connection cleanup should be protected.
+ */
+static void dst_node_cleanup(struct dst_node *n)
+{
+ struct dst_state *st = n->state;
+
+ if (!st)
+ return;
+
+ if (n->queue) {
+ blk_cleanup_queue(n->queue);
+
+ mutex_lock(&dst_hash_lock);
+ idr_remove(&dst_index_idr, n->disk->first_minor);
+ mutex_unlock(&dst_hash_lock);
+
+ put_disk(n->disk);
+ }
+
+ if (n->bdev) {
+ sync_blockdev(n->bdev);
+ blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
+ }
+
+ dst_state_lock(st);
+ st->need_exit = 1;
+ dst_state_exit_connected(st);
+ dst_state_unlock(st);
+
+ wake_up(&st->thread_wait);
+
+ dst_state_put(st);
+ n->state = NULL;
+}
+
+/*
+ * Free security attributes attached to given node.
+ */
+static void dst_security_exit(struct dst_node *n)
+{
+ struct dst_secure *s, *tmp;
+
+ list_for_each_entry_safe(s, tmp, &n->security_list, sec_entry) {
+ list_del(&s->sec_entry);
+ kfree(s);
+ }
+}
+
+/*
+ * Free node when there are no more users.
+ * Actually node has to be freed on behalf od userspace process,
+ * since there are number of threads, which are embedded in the
+ * node, so they can not exit and free node from there, that is
+ * why there is a wakeup if reference counter is not equal to zero.
+ */
+void dst_node_put(struct dst_node *n)
+{
+ if (unlikely(!n))
+ return;
+
+ dprintk("%s: n: %p, refcnt: %d.\n",
+ __func__, n, atomic_read(&n->refcnt));
+
+ if (atomic_dec_and_test(&n->refcnt)) {
+ dst_node_remove(n);
+ n->trans_scan_timeout = 0;
+ dst_node_cleanup(n);
+ thread_pool_destroy(n->pool);
+ dst_node_sysfs_exit(n);
+ dst_node_crypto_exit(n);
+ dst_security_exit(n);
+ dst_node_trans_exit(n);
+
+ kfree(n);
+
+ dprintk("%s: freed n: %p.\n", __func__, n);
+ } else {
+ wake_up(&n->wait);
+ }
+}
+
+/*
+ * This function finds devices major/minor numbers for given pathname.
+ */
+static int dst_lookup_device(const char *path, dev_t *dev)
+{
+ int err;
+ struct nameidata nd;
+ struct inode *inode;
+
+ err = path_lookup(path, LOOKUP_FOLLOW, &nd);
+ if (err)
+ return err;
+
+ inode = nd.path.dentry->d_inode;
+ if (!inode) {
+ err = -ENOENT;
+ goto out;
+ }
+
+ if (!S_ISBLK(inode->i_mode)) {
+ err = -ENOTBLK;
+ goto out;
+ }
+
+ *dev = inode->i_rdev;
+
+out:
+ path_put(&nd.path);
+ return err;
+}
+
+/*
+ * Setting up export device: lookup by the name, get its size
+ * and setup listening socket, which will accept clients, which
+ * will submit IO for given storage.
+ */
+static int dst_setup_export(struct dst_node *n, struct dst_ctl *ctl,
+ struct dst_export_ctl *le)
+{
+ int err;
+ dev_t dev = 0; /* gcc likes to scream here */
+
+ snprintf(n->info->local, sizeof(n->info->local), "%s", le->device);
+
+ err = dst_lookup_device(le->device, &dev);
+ if (err)
+ return err;
+
+ n->bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE);
+ if (!n->bdev)
+ return -ENODEV;
+
+ if (n->size != 0)
+ n->size = min_t(loff_t, n->bdev->bd_inode->i_size, n->size);
+ else
+ n->size = n->bdev->bd_inode->i_size;
+
+ n->info->size = n->size;
+ err = dst_node_init_listened(n, le);
+ if (err)
+ goto err_out_cleanup;
+
+ return 0;
+
+err_out_cleanup:
+ blkdev_put(n->bdev, FMODE_READ|FMODE_WRITE);
+ n->bdev = NULL;
+
+ return err;
+}
+
+/* Empty thread pool callbacks for the network processing threads. */
+static inline void *dst_thread_network_init(void *data)
+{
+ dprintk("%s: data: %p.\n", __func__, data);
+ return data;
+}
+
+static inline void dst_thread_network_cleanup(void *data)
+{
+ dprintk("%s: data: %p.\n", __func__, data);
+}
+
+/*
+ * Allocate DST node and initialize some of its parameters.
+ */
+static struct dst_node *dst_alloc_node(struct dst_ctl *ctl,
+ int (*start)(struct dst_node *),
+ int num)
+{
+ struct dst_node *n;
+ int err;
+
+ n = kzalloc(sizeof(struct dst_node), GFP_KERNEL);
+ if (!n)
+ return NULL;
+
+ INIT_LIST_HEAD(&n->node_entry);
+
+ INIT_LIST_HEAD(&n->security_list);
+ mutex_init(&n->security_lock);
+
+ init_waitqueue_head(&n->wait);
+
+ n->trans_scan_timeout = msecs_to_jiffies(ctl->trans_scan_timeout);
+ if (!n->trans_scan_timeout)
+ n->trans_scan_timeout = HZ;
+
+ n->trans_max_retries = ctl->trans_max_retries;
+ if (!n->trans_max_retries)
+ n->trans_max_retries = 10;
+
+ /*
+ * Pretty much arbitrary default numbers.
+ * 32 matches maximum number of pages in bio originated from ext3 (31).
+ */
+ n->max_pages = ctl->max_pages;
+ if (!n->max_pages)
+ n->max_pages = 32;
+
+ if (n->max_pages > 1024)
+ n->max_pages = 1024;
+
+ n->start = start;
+ n->size = ctl->size;
+
+ atomic_set(&n->refcnt, 1);
+ atomic_long_set(&n->gen, 0);
+ snprintf(n->name, sizeof(n->name), "%s", ctl->name);
+
+ err = dst_node_sysfs_init(n);
+ if (err)
+ goto err_out_free;
+
+ n->pool = thread_pool_create(num, n->name, dst_thread_network_init,
+ dst_thread_network_cleanup, n);
+ if (IS_ERR(n->pool)) {
+ err = PTR_ERR(n->pool);
+ goto err_out_sysfs_exit;
+ }
+
+ dprintk("%s: n: %p, name: %s.\n", __func__, n, n->name);
+
+ return n;
+
+err_out_sysfs_exit:
+ dst_node_sysfs_exit(n);
+err_out_free:
+ kfree(n);
+ return NULL;
+}
+
+/*
+ * Starting a node, connected to the remote server:
+ * register block device and initialize transaction mechanism.
+ * In revers order though.
+ *
+ * It will autonegotiate some parameters with the remote node
+ * and update local if needed.
+ *
+ * Transaction initialization should be the last thing before
+ * starting the node, since transaction should include not only
+ * block IO, but also crypto related data (if any), which are
+ * initialized separately.
+ */
+static int dst_start_remote(struct dst_node *n)
+{
+ int err;
+
+ err = dst_node_trans_init(n, sizeof(struct dst_trans));
+ if (err)
+ return err;
+
+ err = dst_node_create_disk(n);
+ if (err)
+ return err;
+
+ dst_node_set_size(n);
+ add_disk(n->disk);
+
+ dprintk("DST: started remote node '%s', minor: %d.\n", n->name, n->disk->first_minor);
+
+ return 0;
+}
+
+/*
+ * Adding remote node and initialize connection.
+ */
+static int dst_add_remote(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ int err;
+ struct dst_network_ctl *rctl = data;
+
+ if (n)
+ return -EEXIST;
+
+ if (size != sizeof(struct dst_network_ctl))
+ return -EINVAL;
+
+ n = dst_alloc_node(ctl, dst_start_remote, 1);
+ if (!n)
+ return -ENOMEM;
+
+ memcpy(&n->info->net, rctl, sizeof(struct dst_network_ctl));
+ err = dst_node_init_connected(n, rctl);
+ if (err)
+ goto err_out_free;
+
+ dst_node_add(n);
+
+ return 0;
+
+err_out_free:
+ dst_node_put(n);
+ return err;
+}
+
+/*
+ * Adding export node: initializing block device and listening socket.
+ */
+static int dst_add_export(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ int err;
+ struct dst_export_ctl *le = data;
+
+ if (n)
+ return -EEXIST;
+
+ if (size != sizeof(struct dst_export_ctl))
+ return -EINVAL;
+
+ n = dst_alloc_node(ctl, dst_start_export, 2);
+ if (!n)
+ return -EINVAL;
+
+ err = dst_setup_export(n, ctl, le);
+ if (err)
+ goto err_out_free;
+
+ dst_node_add(n);
+
+ return 0;
+
+err_out_free:
+ dst_node_put(n);
+ return err;
+}
+
+static int dst_node_remove_unload(struct dst_node *n)
+{
+ printk(KERN_INFO "STOPPED name: '%s', size: %llu.\n",
+ n->name, n->size);
+
+ if (n->disk)
+ del_gendisk(n->disk);
+
+ dst_node_remove(n);
+ dst_node_sysfs_exit(n);
+
+ /*
+ * This is not a hack. Really.
+ * Node's reference counter allows to implement fine grained
+ * node freeing, but since all transactions (which hold node's
+ * reference counter) are processed in the dedicated thread,
+ * it is possible that reference will hit zero in that thread,
+ * so we will not be able to exit thread and cleanup the node.
+ *
+ * So, we remove disk, so no new activity is possible, and
+ * wait until all pending transaction are completed (either
+ * in receiving thread or by timeout in workqueue), in this
+ * case reference counter will be less or equal to 2 (once set in
+ * dst_alloc_node() and then in connector message parser;
+ * or when we force module unloading, and connector message
+ * parser does not hold a reference, in this case reference
+ * counter will be equal to 1),
+ * and subsequent dst_node_put() calls will free the node.
+ */
+ dprintk("%s: going to sleep with %d refcnt.\n", __func__, atomic_read(&n->refcnt));
+ wait_event(n->wait, atomic_read(&n->refcnt) <= 2);
+
+ dst_node_put(n);
+ return 0;
+}
+
+/*
+ * Remove node from the hash table.
+ */
+static int dst_del_node(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ if (!n)
+ return -ENODEV;
+
+ return dst_node_remove_unload(n);
+}
+
+/*
+ * Initialize crypto processing for given node.
+ */
+static int dst_crypto_init(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ struct dst_crypto_ctl *crypto = data;
+
+ if (!n)
+ return -ENODEV;
+
+ if (size != sizeof(struct dst_crypto_ctl) + crypto->hash_keysize +
+ crypto->cipher_keysize)
+ return -EINVAL;
+
+ if (n->trans_cache)
+ return -EEXIST;
+
+ return dst_node_crypto_init(n, crypto);
+}
+
+/*
+ * Security attributes for given node.
+ */
+static int dst_security_init(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ struct dst_secure *s;
+
+ if (!n)
+ return -ENODEV;
+
+ if (size != sizeof(struct dst_secure_user))
+ return -EINVAL;
+
+ s = kmalloc(sizeof(struct dst_secure), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ memcpy(&s->sec, data, size);
+
+ mutex_lock(&n->security_lock);
+ list_add_tail(&s->sec_entry, &n->security_list);
+ mutex_unlock(&n->security_lock);
+
+ return 0;
+}
+
+/*
+ * Kill'em all!
+ */
+static int dst_start_node(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size)
+{
+ int err;
+
+ if (!n)
+ return -ENODEV;
+
+ if (n->trans_cache)
+ return 0;
+
+ err = n->start(n);
+ if (err)
+ return err;
+
+ printk(KERN_INFO "STARTED name: '%s', size: %llu.\n", n->name, n->size);
+ return 0;
+}
+
+typedef int (*dst_command_func)(struct dst_node *n, struct dst_ctl *ctl,
+ void *data, unsigned int size);
+
+/*
+ * List of userspace commands.
+ */
+static dst_command_func dst_commands[] = {
+ [DST_ADD_REMOTE] = &dst_add_remote,
+ [DST_ADD_EXPORT] = &dst_add_export,
+ [DST_DEL_NODE] = &dst_del_node,
+ [DST_CRYPTO] = &dst_crypto_init,
+ [DST_SECURITY] = &dst_security_init,
+ [DST_START] = &dst_start_node,
+};
+
+/*
+ * Configuration parser.
+ */
+static void cn_dst_callback(void *data)
+{
+ struct dst_ctl *ctl;
+ struct cn_msg *msg = data;
+ int err;
+ struct dst_ctl_ack ack;
+ struct dst_node *n = NULL, *tmp;
+ unsigned int hash;
+
+ if (msg->len < sizeof(struct dst_ctl)) {
+ err = -EBADMSG;
+ goto out;
+ }
+
+ ctl = (struct dst_ctl *)msg->data;
+
+ if (ctl->cmd >= DST_CMD_MAX) {
+ err = -EINVAL;
+ goto out;
+ }
+ hash = dst_hash(ctl->name, sizeof(ctl->name));
+
+ mutex_lock(&dst_hash_lock);
+ list_for_each_entry(tmp, &dst_hashtable[hash], node_entry) {
+ if (!memcmp(tmp->name, ctl->name, sizeof(tmp->name))) {
+ n = tmp;
+ dst_node_get(n);
+ break;
+ }
+ }
+ mutex_unlock(&dst_hash_lock);
+
+ err = dst_commands[ctl->cmd](n, ctl, msg->data + sizeof(struct dst_ctl),
+ msg->len - sizeof(struct dst_ctl));
+
+ dst_node_put(n);
+out:
+ memcpy(&ack.msg, msg, sizeof(struct cn_msg));
+
+ ack.msg.ack = msg->ack + 1;
+ ack.msg.len = sizeof(struct dst_ctl_ack) - sizeof(struct cn_msg);
+
+ ack.error = err;
+
+ cn_netlink_send(&ack.msg, 0, GFP_KERNEL);
+}
+
+/*
+ * Global initialization: sysfs, hash table, block device registration,
+ * connector and various caches.
+ */
+static int __init dst_sysfs_init(void)
+{
+ return bus_register(&dst_dev_bus_type);
+}
+
+static void dst_sysfs_exit(void)
+{
+ bus_unregister(&dst_dev_bus_type);
+}
+
+static int __init dst_hashtable_init(void)
+{
+ unsigned int i;
+
+ dst_hashtable = kcalloc(dst_hashtable_size, sizeof(struct list_head),
+ GFP_KERNEL);
+ if (!dst_hashtable)
+ return -ENOMEM;
+
+ for (i=0; i<dst_hashtable_size; ++i)
+ INIT_LIST_HEAD(&dst_hashtable[i]);
+
+ return 0;
+}
+
+static void dst_hashtable_exit(void)
+{
+ unsigned int i;
+ struct dst_node *n, *tmp;
+
+ for (i=0; i<dst_hashtable_size; ++i) {
+ list_for_each_entry_safe(n, tmp, &dst_hashtable[i], node_entry) {
+ dst_node_remove_unload(n);
+ }
+ }
+
+ kfree(dst_hashtable);
+}
+
+static int __init dst_sys_init(void)
+{
+ int err = -ENOMEM;
+
+ err = dst_hashtable_init();
+ if (err)
+ goto err_out_exit;
+
+ err = dst_export_init();
+ if (err)
+ goto err_out_hashtable_exit;
+
+ err = register_blkdev(dst_major, DST_NAME);
+ if (err < 0)
+ goto err_out_export_exit;
+ if (err)
+ dst_major = err;
+
+ err = dst_sysfs_init();
+ if (err)
+ goto err_out_unregister;
+
+ err = cn_add_callback(&cn_dst_id, "DST", cn_dst_callback);
+ if (err)
+ goto err_out_sysfs_exit;
+
+ printk(KERN_INFO "Distributed storage, '%s' release.\n", dst_name);
+
+ return 0;
+
+err_out_sysfs_exit:
+ dst_sysfs_exit();
+err_out_unregister:
+ unregister_blkdev(dst_major, DST_NAME);
+err_out_export_exit:
+ dst_export_exit();
+err_out_hashtable_exit:
+ dst_hashtable_exit();
+err_out_exit:
+ return err;
+}
+
+static void __exit dst_sys_exit(void)
+{
+ cn_del_callback(&cn_dst_id);
+ unregister_blkdev(dst_major, DST_NAME);
+ dst_hashtable_exit();
+ dst_sysfs_exit();
+ dst_export_exit();
+}
+
+module_init(dst_sys_init);
+module_exit(dst_sys_exit);
+
+MODULE_DESCRIPTION("Distributed storage");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/dst/export.c b/drivers/staging/dst/export.c
new file mode 100644
index 00000000000..80ae4ebe610
--- /dev/null
+++ b/drivers/staging/dst/export.c
@@ -0,0 +1,657 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/dst.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/socket.h>
+
+#include <net/sock.h>
+
+/*
+ * Export bioset is used for server block IO requests.
+ */
+static struct bio_set *dst_bio_set;
+
+int __init dst_export_init(void)
+{
+ int err = -ENOMEM;
+
+ dst_bio_set = bioset_create(32, sizeof(struct dst_export_priv));
+ if (!dst_bio_set)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+void dst_export_exit(void)
+{
+ bioset_free(dst_bio_set);
+}
+
+/*
+ * When client connects and autonegotiates with the server node,
+ * its permissions are checked in a security attributes and sent
+ * back.
+ */
+static unsigned int dst_check_permissions(struct dst_state *main, struct dst_state *st)
+{
+ struct dst_node *n = main->node;
+ struct dst_secure *sentry;
+ struct dst_secure_user *s;
+ struct saddr *sa = &st->ctl.addr;
+ unsigned int perm = 0;
+
+ mutex_lock(&n->security_lock);
+ list_for_each_entry(sentry, &n->security_list, sec_entry) {
+ s = &sentry->sec;
+
+ if (s->addr.sa_family != sa->sa_family)
+ continue;
+
+ if (s->addr.sa_data_len != sa->sa_data_len)
+ continue;
+
+ /*
+ * This '2' below is a port field. This may be very wrong to do
+ * in atalk for example though. If there will be any need to extent
+ * protocol to something else, I can create per-family helpers and
+ * use them instead of this memcmp.
+ */
+ if (memcmp(s->addr.sa_data + 2, sa->sa_data + 2,
+ sa->sa_data_len - 2))
+ continue;
+
+ perm = s->permissions;
+ }
+ mutex_unlock(&n->security_lock);
+
+ return perm;
+}
+
+/*
+ * Accept new client: allocate appropriate network state and check permissions.
+ */
+static struct dst_state *dst_accept_client(struct dst_state *st)
+{
+ unsigned int revents = 0;
+ unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+ unsigned int mask = err_mask | POLLIN;
+ struct dst_node *n = st->node;
+ int err = 0;
+ struct socket *sock = NULL;
+ struct dst_state *new;
+
+ while (!err && !sock) {
+ revents = dst_state_poll(st);
+
+ if (!(revents & mask)) {
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait(&st->thread_wait,
+ &wait, TASK_INTERRUPTIBLE);
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ revents = dst_state_poll(st);
+
+ if (revents & mask)
+ break;
+
+ if (signal_pending(current))
+ break;
+
+ /*
+ * Magic HZ? Polling check above is not safe in
+ * all cases (like socket reset in BH context),
+ * so it is simpler just to postpone it to the
+ * process context instead of implementing special
+ * locking there.
+ */
+ schedule_timeout(HZ);
+ }
+ finish_wait(&st->thread_wait, &wait);
+ }
+
+ err = -ECONNRESET;
+ dst_state_lock(st);
+
+ dprintk("%s: st: %p, revents: %x [err: %d, in: %d].\n",
+ __func__, st, revents, revents & err_mask,
+ revents & POLLIN);
+
+ if (revents & err_mask) {
+ dprintk("%s: revents: %x, socket: %p, err: %d.\n",
+ __func__, revents, st->socket, err);
+ err = -ECONNRESET;
+ }
+
+ if (!n->trans_scan_timeout || st->need_exit)
+ err = -ENODEV;
+
+ if (st->socket && (revents & POLLIN))
+ err = kernel_accept(st->socket, &sock, 0);
+
+ dst_state_unlock(st);
+ }
+
+ if (err)
+ goto err_out_exit;
+
+ new = dst_state_alloc(st->node);
+ if (!new) {
+ err = -ENOMEM;
+ goto err_out_release;
+ }
+ new->socket = sock;
+
+ new->ctl.addr.sa_data_len = sizeof(struct sockaddr);
+ err = kernel_getpeername(sock, (struct sockaddr *)&new->ctl.addr,
+ (int *)&new->ctl.addr.sa_data_len);
+ if (err)
+ goto err_out_put;
+
+ new->permissions = dst_check_permissions(st, new);
+ if (new->permissions == 0) {
+ err = -EPERM;
+ dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
+ "Client is not allowed to connect");
+ goto err_out_put;
+ }
+
+ err = dst_poll_init(new);
+ if (err)
+ goto err_out_put;
+
+ dst_dump_addr(sock, (struct sockaddr *)&new->ctl.addr,
+ "Connected client");
+
+ return new;
+
+err_out_put:
+ dst_state_put(new);
+err_out_release:
+ sock_release(sock);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+/*
+ * Each server's block request sometime finishes.
+ * Usually it happens in hard irq context of the appropriate controller,
+ * so to play good with all cases we just queue BIO into the queue
+ * and wake up processing thread, which gets completed request and
+ * send (encrypting if needed) it back to the client (if it was a read
+ * request), or sends back reply that writing succesfully completed.
+ */
+static int dst_export_process_request_queue(struct dst_state *st)
+{
+ unsigned long flags;
+ struct dst_export_priv *p = NULL;
+ struct bio *bio;
+ int err = 0;
+
+ while (!list_empty(&st->request_list)) {
+ spin_lock_irqsave(&st->request_lock, flags);
+ if (!list_empty(&st->request_list)) {
+ p = list_first_entry(&st->request_list,
+ struct dst_export_priv, request_entry);
+ list_del(&p->request_entry);
+ }
+ spin_unlock_irqrestore(&st->request_lock, flags);
+
+ if (!p)
+ break;
+
+ bio = p->bio;
+
+ if (dst_need_crypto(st->node) && (bio_data_dir(bio) == READ))
+ err = dst_export_crypto(st->node, bio);
+ else
+ err = dst_export_send_bio(bio);
+
+ if (err)
+ break;
+ }
+
+ return err;
+}
+
+/*
+ * Cleanup export state.
+ * It has to wait until all requests are finished,
+ * and then free them all.
+ */
+static void dst_state_cleanup_export(struct dst_state *st)
+{
+ struct dst_export_priv *p;
+ unsigned long flags;
+
+ /*
+ * This loop waits for all pending bios to be completed and freed.
+ */
+ while (atomic_read(&st->refcnt) > 1) {
+ dprintk("%s: st: %p, refcnt: %d, list_empty: %d.\n",
+ __func__, st, atomic_read(&st->refcnt),
+ list_empty(&st->request_list));
+ wait_event_timeout(st->thread_wait,
+ (atomic_read(&st->refcnt) == 1) ||
+ !list_empty(&st->request_list),
+ HZ/2);
+
+ while (!list_empty(&st->request_list)) {
+ p = NULL;
+ spin_lock_irqsave(&st->request_lock, flags);
+ if (!list_empty(&st->request_list)) {
+ p = list_first_entry(&st->request_list,
+ struct dst_export_priv, request_entry);
+ list_del(&p->request_entry);
+ }
+ spin_unlock_irqrestore(&st->request_lock, flags);
+
+ if (p)
+ bio_put(p->bio);
+
+ dprintk("%s: st: %p, refcnt: %d, list_empty: %d, p: %p.\n",
+ __func__, st, atomic_read(&st->refcnt),
+ list_empty(&st->request_list), p);
+ }
+ }
+
+ dst_state_put(st);
+}
+
+/*
+ * Client accepting thread.
+ * Not only accepts new connection, but also schedules receiving thread
+ * and performs request completion described above.
+ */
+static int dst_accept(void *init_data, void *schedule_data)
+{
+ struct dst_state *main_st = schedule_data;
+ struct dst_node *n = init_data;
+ struct dst_state *st;
+ int err;
+
+ while (n->trans_scan_timeout && !main_st->need_exit) {
+ dprintk("%s: main_st: %p, n: %p.\n", __func__, main_st, n);
+ st = dst_accept_client(main_st);
+ if (IS_ERR(st))
+ continue;
+
+ err = dst_state_schedule_receiver(st);
+ if (!err) {
+ while (n->trans_scan_timeout) {
+ err = wait_event_interruptible_timeout(st->thread_wait,
+ !list_empty(&st->request_list) ||
+ !n->trans_scan_timeout ||
+ st->need_exit,
+ HZ);
+
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ if (list_empty(&st->request_list))
+ continue;
+
+ err = dst_export_process_request_queue(st);
+ if (err)
+ break;
+ }
+
+ st->need_exit = 1;
+ wake_up(&st->thread_wait);
+ }
+
+ dst_state_cleanup_export(st);
+ }
+
+ dprintk("%s: freeing listening socket st: %p.\n", __func__, main_st);
+
+ dst_state_lock(main_st);
+ dst_poll_exit(main_st);
+ dst_state_socket_release(main_st);
+ dst_state_unlock(main_st);
+ dst_state_put(main_st);
+ dprintk("%s: freed listening socket st: %p.\n", __func__, main_st);
+
+ return 0;
+}
+
+int dst_start_export(struct dst_node *n)
+{
+ if (list_empty(&n->security_list)) {
+ printk(KERN_ERR "You are trying to export node '%s' without security attributes.\n"
+ "No clients will be allowed to connect. Exiting.\n", n->name);
+ return -EINVAL;
+ }
+ return dst_node_trans_init(n, sizeof(struct dst_export_priv));
+}
+
+/*
+ * Initialize listening state and schedule accepting thread.
+ */
+int dst_node_init_listened(struct dst_node *n, struct dst_export_ctl *le)
+{
+ struct dst_state *st;
+ int err = -ENOMEM;
+ struct dst_network_ctl *ctl = &le->ctl;
+
+ memcpy(&n->info->net, ctl, sizeof(struct dst_network_ctl));
+
+ st = dst_state_alloc(n);
+ if (IS_ERR(st)) {
+ err = PTR_ERR(st);
+ goto err_out_exit;
+ }
+ memcpy(&st->ctl, ctl, sizeof(struct dst_network_ctl));
+
+ err = dst_state_socket_create(st);
+ if (err)
+ goto err_out_put;
+
+ st->socket->sk->sk_reuse = 1;
+
+ err = kernel_bind(st->socket, (struct sockaddr *)&ctl->addr,
+ ctl->addr.sa_data_len);
+ if (err)
+ goto err_out_socket_release;
+
+ err = kernel_listen(st->socket, 1024);
+ if (err)
+ goto err_out_socket_release;
+ n->state = st;
+
+ err = dst_poll_init(st);
+ if (err)
+ goto err_out_socket_release;
+
+ dst_state_get(st);
+
+ err = thread_pool_schedule(n->pool, dst_thread_setup,
+ dst_accept, st, MAX_SCHEDULE_TIMEOUT);
+ if (err)
+ goto err_out_poll_exit;
+
+ return 0;
+
+err_out_poll_exit:
+ dst_poll_exit(st);
+err_out_socket_release:
+ dst_state_socket_release(st);
+err_out_put:
+ dst_state_put(st);
+err_out_exit:
+ n->state = NULL;
+ return err;
+}
+
+/*
+ * Free bio and related private data.
+ * Also drop a reference counter for appropriate state,
+ * which waits when there are no more block IOs in-flight.
+ */
+static void dst_bio_destructor(struct bio *bio)
+{
+ struct bio_vec *bv;
+ struct dst_export_priv *priv = bio->bi_private;
+ int i;
+
+ bio_for_each_segment(bv, bio, i) {
+ if (!bv->bv_page)
+ break;
+
+ __free_page(bv->bv_page);
+ }
+
+ if (priv)
+ dst_state_put(priv->state);
+ bio_free(bio, dst_bio_set);
+}
+
+/*
+ * Block IO completion. Queue request to be sent back to
+ * the client (or just confirmation).
+ */
+static void dst_bio_end_io(struct bio *bio, int err)
+{
+ struct dst_export_priv *p = bio->bi_private;
+ struct dst_state *st = p->state;
+ unsigned long flags;
+
+ spin_lock_irqsave(&st->request_lock, flags);
+ list_add_tail(&p->request_entry, &st->request_list);
+ spin_unlock_irqrestore(&st->request_lock, flags);
+
+ wake_up(&st->thread_wait);
+}
+
+/*
+ * Allocate read request for the server.
+ */
+static int dst_export_read_request(struct bio *bio, unsigned int total_size)
+{
+ unsigned int size;
+ struct page *page;
+ int err;
+
+ while (total_size) {
+ err = -ENOMEM;
+ page = alloc_page(GFP_KERNEL);
+ if (!page)
+ goto err_out_exit;
+
+ size = min_t(unsigned int, PAGE_SIZE, total_size);
+
+ err = bio_add_page(bio, page, size, 0);
+ dprintk("%s: bio: %llu/%u, size: %u, err: %d.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size,
+ size, err);
+ if (err <= 0)
+ goto err_out_free_page;
+
+ total_size -= size;
+ }
+
+ return 0;
+
+err_out_free_page:
+ __free_page(page);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Allocate write request for the server.
+ * Should not only get pages, but also read data from the network.
+ */
+static int dst_export_write_request(struct dst_state *st,
+ struct bio *bio, unsigned int total_size)
+{
+ unsigned int size;
+ struct page *page;
+ void *data;
+ int err;
+
+ while (total_size) {
+ err = -ENOMEM;
+ page = alloc_page(GFP_KERNEL);
+ if (!page)
+ goto err_out_exit;
+
+ data = kmap(page);
+ if (!data)
+ goto err_out_free_page;
+
+ size = min_t(unsigned int, PAGE_SIZE, total_size);
+
+ err = dst_data_recv(st, data, size);
+ if (err)
+ goto err_out_unmap_page;
+
+ err = bio_add_page(bio, page, size, 0);
+ if (err <= 0)
+ goto err_out_unmap_page;
+
+ kunmap(page);
+
+ total_size -= size;
+ }
+
+ return 0;
+
+err_out_unmap_page:
+ kunmap(page);
+err_out_free_page:
+ __free_page(page);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Groovy, we've gotten an IO request from the client.
+ * Allocate BIO from the bioset, private data from the mempool
+ * and lots of pages for IO.
+ */
+int dst_process_io(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ struct dst_cmd *cmd = st->data;
+ struct bio *bio;
+ struct dst_export_priv *priv;
+ int err = -ENOMEM;
+
+ if (unlikely(!n->bdev)) {
+ err = -EINVAL;
+ goto err_out_exit;
+ }
+
+ bio = bio_alloc_bioset(GFP_KERNEL,
+ PAGE_ALIGN(cmd->size) >> PAGE_SHIFT,
+ dst_bio_set);
+ if (!bio)
+ goto err_out_exit;
+
+ priv = (struct dst_export_priv *)(((void *)bio) - sizeof (struct dst_export_priv));
+
+ priv->state = dst_state_get(st);
+ priv->bio = bio;
+
+ bio->bi_private = priv;
+ bio->bi_end_io = dst_bio_end_io;
+ bio->bi_destructor = dst_bio_destructor;
+ bio->bi_bdev = n->bdev;
+
+ /*
+ * Server side is only interested in two low bits:
+ * uptodate (set by itself actually) and rw block
+ */
+ bio->bi_flags |= cmd->flags & 3;
+
+ bio->bi_rw = cmd->rw;
+ bio->bi_size = 0;
+ bio->bi_sector = cmd->sector;
+
+ dst_bio_to_cmd(bio, &priv->cmd, DST_IO_RESPONSE, cmd->id);
+
+ priv->cmd.flags = 0;
+ priv->cmd.size = cmd->size;
+
+ if (bio_data_dir(bio) == WRITE) {
+ err = dst_recv_cdata(st, priv->cmd.hash);
+ if (err)
+ goto err_out_free;
+
+ err = dst_export_write_request(st, bio, cmd->size);
+ if (err)
+ goto err_out_free;
+
+ if (dst_need_crypto(n))
+ return dst_export_crypto(n, bio);
+ } else {
+ err = dst_export_read_request(bio, cmd->size);
+ if (err)
+ goto err_out_free;
+ }
+
+ dprintk("%s: bio: %llu/%u, rw: %lu, dir: %lu, flags: %lx, phys: %d.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size,
+ bio->bi_rw, bio_data_dir(bio),
+ bio->bi_flags, bio->bi_phys_segments);
+
+ generic_make_request(bio);
+
+ return 0;
+
+err_out_free:
+ bio_put(bio);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Ok, block IO is ready, let's send it back to the client...
+ */
+int dst_export_send_bio(struct bio *bio)
+{
+ struct dst_export_priv *p = bio->bi_private;
+ struct dst_state *st = p->state;
+ struct dst_cmd *cmd = &p->cmd;
+ int err;
+
+ dprintk("%s: id: %llu, bio: %llu/%u, csize: %u, flags: %lu, rw: %lu.\n",
+ __func__, cmd->id, (u64)bio->bi_sector, bio->bi_size,
+ cmd->csize, bio->bi_flags, bio->bi_rw);
+
+ dst_convert_cmd(cmd);
+
+ dst_state_lock(st);
+ if (!st->socket) {
+ err = -ECONNRESET;
+ goto err_out_unlock;
+ }
+
+ if (bio_data_dir(bio) == WRITE) {
+ /* ... or just confirmation that writing has completed. */
+ cmd->size = cmd->csize = 0;
+ err = dst_data_send_header(st->socket, cmd,
+ sizeof(struct dst_cmd), 0);
+ if (err)
+ goto err_out_unlock;
+ } else {
+ err = dst_send_bio(st, cmd, bio);
+ if (err)
+ goto err_out_unlock;
+ }
+
+ dst_state_unlock(st);
+
+ bio_put(bio);
+ return 0;
+
+err_out_unlock:
+ dst_state_unlock(st);
+
+ bio_put(bio);
+ return err;
+}
diff --git a/drivers/staging/dst/state.c b/drivers/staging/dst/state.c
new file mode 100644
index 00000000000..d057e52f3b6
--- /dev/null
+++ b/drivers/staging/dst/state.c
@@ -0,0 +1,839 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/buffer_head.h>
+#include <linux/blkdev.h>
+#include <linux/bio.h>
+#include <linux/connector.h>
+#include <linux/dst.h>
+#include <linux/device.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/socket.h>
+#include <linux/slab.h>
+
+#include <net/sock.h>
+
+/*
+ * Polling machinery.
+ */
+
+struct dst_poll_helper
+{
+ poll_table pt;
+ struct dst_state *st;
+};
+
+static int dst_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+ struct dst_state *st = container_of(wait, struct dst_state, wait);
+
+ wake_up(&st->thread_wait);
+ return 1;
+}
+
+static void dst_queue_func(struct file *file, wait_queue_head_t *whead,
+ poll_table *pt)
+{
+ struct dst_state *st = container_of(pt, struct dst_poll_helper, pt)->st;
+
+ st->whead = whead;
+ init_waitqueue_func_entry(&st->wait, dst_queue_wake);
+ add_wait_queue(whead, &st->wait);
+}
+
+void dst_poll_exit(struct dst_state *st)
+{
+ if (st->whead) {
+ remove_wait_queue(st->whead, &st->wait);
+ st->whead = NULL;
+ }
+}
+
+int dst_poll_init(struct dst_state *st)
+{
+ struct dst_poll_helper ph;
+
+ ph.st = st;
+ init_poll_funcptr(&ph.pt, &dst_queue_func);
+
+ st->socket->ops->poll(NULL, st->socket, &ph.pt);
+ return 0;
+}
+
+/*
+ * Header receiving function - may block.
+ */
+static int dst_data_recv_header(struct socket *sock,
+ void *data, unsigned int size, int block)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ iov.iov_base = data;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = (block)?MSG_WAITALL:MSG_DONTWAIT;
+
+ err = kernel_recvmsg(sock, &msg, &iov, 1, iov.iov_len,
+ msg.msg_flags);
+ if (err != size)
+ return -1;
+
+ return 0;
+}
+
+/*
+ * Header sending function - may block.
+ */
+int dst_data_send_header(struct socket *sock,
+ void *data, unsigned int size, int more)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ iov.iov_base = data;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_WAITALL | (more)?MSG_MORE:0;
+
+ err = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+ if (err != size) {
+ dprintk("%s: size: %u, more: %d, err: %d.\n",
+ __func__, size, more, err);
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Block autoconfiguration: request size of the storage and permissions.
+ */
+static int dst_request_remote_config(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ int err = -EINVAL;
+ struct dst_cmd *cmd = st->data;
+
+ memset(cmd, 0, sizeof(struct dst_cmd));
+ cmd->cmd = DST_CFG;
+
+ dst_convert_cmd(cmd);
+
+ err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+ if (err)
+ goto out;
+
+ err = dst_data_recv_header(st->socket, cmd, sizeof(struct dst_cmd), 1);
+ if (err)
+ goto out;
+
+ dst_convert_cmd(cmd);
+
+ if (cmd->cmd != DST_CFG) {
+ err = -EINVAL;
+ dprintk("%s: checking result: cmd: %d, size reported: %llu.\n",
+ __func__, cmd->cmd, cmd->sector);
+ goto out;
+ }
+
+ if (n->size != 0)
+ n->size = min_t(loff_t, n->size, cmd->sector);
+ else
+ n->size = cmd->sector;
+
+ n->info->size = n->size;
+ st->permissions = cmd->rw;
+
+out:
+ dprintk("%s: n: %p, err: %d, size: %llu, permission: %x.\n",
+ __func__, n, err, n->size, st->permissions);
+ return err;
+}
+
+/*
+ * Socket machinery.
+ */
+
+#define DST_DEFAULT_TIMEO 20000
+
+int dst_state_socket_create(struct dst_state *st)
+{
+ int err;
+ struct socket *sock;
+ struct dst_network_ctl *ctl = &st->ctl;
+
+ err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &sock);
+ if (err < 0)
+ return err;
+
+ sock->sk->sk_sndtimeo = sock->sk->sk_rcvtimeo =
+ msecs_to_jiffies(DST_DEFAULT_TIMEO);
+ sock->sk->sk_allocation = GFP_NOIO;
+
+ st->socket = st->read_socket = sock;
+ return 0;
+}
+
+void dst_state_socket_release(struct dst_state *st)
+{
+ dprintk("%s: st: %p, socket: %p, n: %p.\n",
+ __func__, st, st->socket, st->node);
+ if (st->socket) {
+ sock_release(st->socket);
+ st->socket = NULL;
+ st->read_socket = NULL;
+ }
+}
+
+void dst_dump_addr(struct socket *sk, struct sockaddr *sa, char *str)
+{
+ if (sk->ops->family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+ printk(KERN_INFO "%s %u.%u.%u.%u:%d.\n",
+ str, NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (sk->ops->family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)sa;
+ printk(KERN_INFO "%s %pi6:%d",
+ str, &sin->sin6_addr, ntohs(sin->sin6_port));
+ }
+}
+
+void dst_state_exit_connected(struct dst_state *st)
+{
+ if (st->socket) {
+ dst_poll_exit(st);
+ st->socket->ops->shutdown(st->socket, 2);
+
+ dst_dump_addr(st->socket, (struct sockaddr *)&st->ctl.addr,
+ "Disconnected peer");
+ dst_state_socket_release(st);
+ }
+}
+
+static int dst_state_init_connected(struct dst_state *st)
+{
+ int err;
+ struct dst_network_ctl *ctl = &st->ctl;
+
+ err = dst_state_socket_create(st);
+ if (err)
+ goto err_out_exit;
+
+ err = kernel_connect(st->socket, (struct sockaddr *)&st->ctl.addr,
+ st->ctl.addr.sa_data_len, 0);
+ if (err)
+ goto err_out_release;
+
+ err = dst_poll_init(st);
+ if (err)
+ goto err_out_release;
+
+ dst_dump_addr(st->socket, (struct sockaddr *)&ctl->addr,
+ "Connected to peer");
+
+ return 0;
+
+err_out_release:
+ dst_state_socket_release(st);
+err_out_exit:
+ return err;
+}
+
+/*
+ * State reset is used to reconnect to the remote peer.
+ * May fail, but who cares, we will try again later.
+ */
+static void inline dst_state_reset_nolock(struct dst_state *st)
+{
+ dst_state_exit_connected(st);
+ dst_state_init_connected(st);
+}
+
+static void inline dst_state_reset(struct dst_state *st)
+{
+ dst_state_lock(st);
+ dst_state_reset_nolock(st);
+ dst_state_unlock(st);
+}
+
+/*
+ * Basic network sending/receiving functions.
+ * Blocked mode is used.
+ */
+static int dst_data_recv_raw(struct dst_state *st, void *buf, u64 size)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ BUG_ON(!size);
+
+ iov.iov_base = buf;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_DONTWAIT;
+
+ err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
+ msg.msg_flags);
+ if (err <= 0) {
+ dprintk("%s: failed to recv data: size: %llu, err: %d.\n",
+ __func__, size, err);
+ if (err == 0)
+ err = -ECONNRESET;
+
+ dst_state_exit_connected(st);
+ }
+
+ return err;
+}
+
+/*
+ * Ping command to early detect failed nodes.
+ */
+static int dst_send_ping(struct dst_state *st)
+{
+ struct dst_cmd *cmd = st->data;
+ int err = -ECONNRESET;
+
+ dst_state_lock(st);
+ if (st->socket) {
+ memset(cmd, 0, sizeof(struct dst_cmd));
+
+ cmd->cmd = __cpu_to_be32(DST_PING);
+
+ err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+ }
+ dprintk("%s: st: %p, socket: %p, err: %d.\n", __func__, st, st->socket, err);
+ dst_state_unlock(st);
+
+ return err;
+}
+
+/*
+ * Receiving function, which should either return error or read
+ * whole block request. If there was no traffic for a one second,
+ * send a ping, since remote node may die.
+ */
+int dst_data_recv(struct dst_state *st, void *data, unsigned int size)
+{
+ unsigned int revents = 0;
+ unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+ unsigned int mask = err_mask | POLLIN;
+ struct dst_node *n = st->node;
+ int err = 0;
+
+ while (size && !err) {
+ revents = dst_state_poll(st);
+
+ if (!(revents & mask)) {
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait(&st->thread_wait, &wait,
+ TASK_INTERRUPTIBLE);
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ revents = dst_state_poll(st);
+
+ if (revents & mask)
+ break;
+
+ if (signal_pending(current))
+ break;
+
+ if (!schedule_timeout(HZ)) {
+ err = dst_send_ping(st);
+ if (err)
+ return err;
+ }
+
+ continue;
+ }
+ finish_wait(&st->thread_wait, &wait);
+ }
+
+ err = -ECONNRESET;
+ dst_state_lock(st);
+
+ if ( st->socket &&
+ (st->read_socket == st->socket) &&
+ (revents & POLLIN)) {
+ err = dst_data_recv_raw(st, data, size);
+ if (err > 0) {
+ data += err;
+ size -= err;
+ err = 0;
+ }
+ }
+
+ if (revents & err_mask || !st->socket) {
+ dprintk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
+ __func__, revents, st->socket, size, err);
+ err = -ECONNRESET;
+ }
+
+ dst_state_unlock(st);
+
+ if (!n->trans_scan_timeout)
+ err = -ENODEV;
+ }
+
+ return err;
+}
+
+/*
+ * Send block autoconf reply.
+ */
+static int dst_process_cfg(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ struct dst_cmd *cmd = st->data;
+ int err;
+
+ cmd->sector = n->size;
+ cmd->rw = st->permissions;
+
+ dst_convert_cmd(cmd);
+
+ dst_state_lock(st);
+ err = dst_data_send_header(st->socket, cmd, sizeof(struct dst_cmd), 0);
+ dst_state_unlock(st);
+
+ return err;
+}
+
+/*
+ * Receive block IO from the network.
+ */
+static int dst_recv_bio(struct dst_state *st, struct bio *bio, unsigned int total_size)
+{
+ struct bio_vec *bv;
+ int i, err;
+ void *data;
+ unsigned int sz;
+
+ bio_for_each_segment(bv, bio, i) {
+ sz = min(total_size, bv->bv_len);
+
+ dprintk("%s: bio: %llu/%u, total: %u, len: %u, sz: %u, off: %u.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size, total_size,
+ bv->bv_len, sz, bv->bv_offset);
+
+ data = kmap(bv->bv_page) + bv->bv_offset;
+ err = dst_data_recv(st, data, sz);
+ kunmap(bv->bv_page);
+
+ bv->bv_len = sz;
+
+ if (err)
+ return err;
+
+ total_size -= sz;
+ if (total_size == 0)
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * Our block IO has just completed and arrived: get it.
+ */
+static int dst_process_io_response(struct dst_state *st)
+{
+ struct dst_node *n = st->node;
+ struct dst_cmd *cmd = st->data;
+ struct dst_trans *t;
+ int err = 0;
+ struct bio *bio;
+
+ mutex_lock(&n->trans_lock);
+ t = dst_trans_search(n, cmd->id);
+ mutex_unlock(&n->trans_lock);
+
+ if (!t)
+ goto err_out_exit;
+
+ bio = t->bio;
+
+ dprintk("%s: bio: %llu/%u, cmd_size: %u, csize: %u, dir: %lu.\n",
+ __func__, (u64)bio->bi_sector, bio->bi_size, cmd->size,
+ cmd->csize, bio_data_dir(bio));
+
+ if (bio_data_dir(bio) == READ) {
+ if (bio->bi_size != cmd->size - cmd->csize)
+ goto err_out_exit;
+
+ if (dst_need_crypto(n)) {
+ err = dst_recv_cdata(st, t->cmd.hash);
+ if (err)
+ goto err_out_exit;
+ }
+
+ err = dst_recv_bio(st, t->bio, bio->bi_size);
+ if (err)
+ goto err_out_exit;
+
+ if (dst_need_crypto(n))
+ return dst_trans_crypto(t);
+ } else {
+ err = -EBADMSG;
+ if (cmd->size || cmd->csize)
+ goto err_out_exit;
+ }
+
+ dst_trans_remove(t);
+ dst_trans_put(t);
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Receive crypto data.
+ */
+int dst_recv_cdata(struct dst_state *st, void *cdata)
+{
+ struct dst_cmd *cmd = st->data;
+ struct dst_node *n = st->node;
+ struct dst_crypto_ctl *c = &n->crypto;
+ int err;
+
+ if (cmd->csize != c->crypto_attached_size) {
+ dprintk("%s: cmd: cmd: %u, sector: %llu, size: %u, "
+ "csize: %u != digest size %u.\n",
+ __func__, cmd->cmd, cmd->sector, cmd->size,
+ cmd->csize, c->crypto_attached_size);
+ err = -EINVAL;
+ goto err_out_exit;
+ }
+
+ err = dst_data_recv(st, cdata, cmd->csize);
+ if (err)
+ goto err_out_exit;
+
+ cmd->size -= cmd->csize;
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Receive the command and start its processing.
+ */
+static int dst_recv_processing(struct dst_state *st)
+{
+ int err = -EINTR;
+ struct dst_cmd *cmd = st->data;
+
+ /*
+ * If socket will be reset after this statement, then
+ * dst_data_recv() will just fail and loop will
+ * start again, so it can be done without any locks.
+ *
+ * st->read_socket is needed to prevents state machine
+ * breaking between this data reading and subsequent one
+ * in protocol specific functions during connection reset.
+ * In case of reset we have to read next command and do
+ * not expect data for old command to magically appear in
+ * new connection.
+ */
+ st->read_socket = st->socket;
+ err = dst_data_recv(st, cmd, sizeof(struct dst_cmd));
+ if (err)
+ goto out_exit;
+
+ dst_convert_cmd(cmd);
+
+ dprintk("%s: cmd: %u, size: %u, csize: %u, id: %llu, "
+ "sector: %llu, flags: %llx, rw: %llx.\n",
+ __func__, cmd->cmd, cmd->size,
+ cmd->csize, cmd->id, cmd->sector,
+ cmd->flags, cmd->rw);
+
+ /*
+ * This should catch protocol breakage and random garbage instead of commands.
+ */
+ if (unlikely(cmd->csize > st->size - sizeof(struct dst_cmd))) {
+ err = -EBADMSG;
+ goto out_exit;
+ }
+
+ err = -EPROTO;
+ switch (cmd->cmd) {
+ case DST_IO_RESPONSE:
+ err = dst_process_io_response(st);
+ break;
+ case DST_IO:
+ err = dst_process_io(st);
+ break;
+ case DST_CFG:
+ err = dst_process_cfg(st);
+ break;
+ case DST_PING:
+ err = 0;
+ break;
+ default:
+ break;
+ }
+
+out_exit:
+ return err;
+}
+
+/*
+ * Receiving thread. For the client node we should try to reconnect,
+ * for accepted client we just drop the state and expect it to reconnect.
+ */
+static int dst_recv(void *init_data, void *schedule_data)
+{
+ struct dst_state *st = schedule_data;
+ struct dst_node *n = init_data;
+ int err = 0;
+
+ dprintk("%s: start st: %p, n: %p, scan: %lu, need_exit: %d.\n",
+ __func__, st, n, n->trans_scan_timeout, st->need_exit);
+
+ while (n->trans_scan_timeout && !st->need_exit) {
+ err = dst_recv_processing(st);
+ if (err < 0) {
+ if (!st->ctl.type)
+ break;
+
+ if (!n->trans_scan_timeout || st->need_exit)
+ break;
+
+ dst_state_reset(st);
+ msleep(1000);
+ }
+ }
+
+ st->need_exit = 1;
+ wake_up(&st->thread_wait);
+
+ dprintk("%s: freeing receiving socket st: %p.\n", __func__, st);
+ dst_state_lock(st);
+ dst_state_exit_connected(st);
+ dst_state_unlock(st);
+ dst_state_put(st);
+
+ dprintk("%s: freed receiving socket st: %p.\n", __func__, st);
+
+ return err;
+}
+
+/*
+ * Network state dies here and borns couple of lines below.
+ * This object is the main network state processing engine:
+ * sending, receiving, reconnections, all network related
+ * tasks are handled on behalf of the state.
+ */
+static void dst_state_free(struct dst_state *st)
+{
+ dprintk("%s: st: %p.\n", __func__, st);
+ if (st->cleanup)
+ st->cleanup(st);
+ kfree(st->data);
+ kfree(st);
+}
+
+struct dst_state *dst_state_alloc(struct dst_node *n)
+{
+ struct dst_state *st;
+ int err = -ENOMEM;
+
+ st = kzalloc(sizeof(struct dst_state), GFP_KERNEL);
+ if (!st)
+ goto err_out_exit;
+
+ st->node = n;
+ st->need_exit = 0;
+
+ st->size = PAGE_SIZE;
+ st->data = kmalloc(st->size, GFP_KERNEL);
+ if (!st->data)
+ goto err_out_free;
+
+ spin_lock_init(&st->request_lock);
+ INIT_LIST_HEAD(&st->request_list);
+
+ mutex_init(&st->state_lock);
+ init_waitqueue_head(&st->thread_wait);
+
+ /*
+ * One for processing thread, another one for node itself.
+ */
+ atomic_set(&st->refcnt, 2);
+
+ dprintk("%s: st: %p, n: %p.\n", __func__, st, st->node);
+
+ return st;
+
+err_out_free:
+ kfree(st);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+int dst_state_schedule_receiver(struct dst_state *st)
+{
+ return thread_pool_schedule_private(st->node->pool, dst_thread_setup,
+ dst_recv, st, MAX_SCHEDULE_TIMEOUT, st->node);
+}
+
+/*
+ * Initialize client's connection to the remote peer: allocate state,
+ * connect and perform block IO autoconfiguration.
+ */
+int dst_node_init_connected(struct dst_node *n, struct dst_network_ctl *r)
+{
+ struct dst_state *st;
+ int err = -ENOMEM;
+
+ st = dst_state_alloc(n);
+ if (IS_ERR(st)) {
+ err = PTR_ERR(st);
+ goto err_out_exit;
+ }
+ memcpy(&st->ctl, r, sizeof(struct dst_network_ctl));
+
+ err = dst_state_init_connected(st);
+ if (err)
+ goto err_out_free_data;
+
+ err = dst_request_remote_config(st);
+ if (err)
+ goto err_out_exit_connected;
+ n->state = st;
+
+ err = dst_state_schedule_receiver(st);
+ if (err)
+ goto err_out_exit_connected;
+
+ return 0;
+
+err_out_exit_connected:
+ dst_state_exit_connected(st);
+err_out_free_data:
+ dst_state_free(st);
+err_out_exit:
+ n->state = NULL;
+ return err;
+}
+
+void dst_state_put(struct dst_state *st)
+{
+ dprintk("%s: st: %p, refcnt: %d.\n",
+ __func__, st, atomic_read(&st->refcnt));
+ if (atomic_dec_and_test(&st->refcnt))
+ dst_state_free(st);
+}
+
+/*
+ * Send block IO to the network one by one using zero-copy ->sendpage().
+ */
+int dst_send_bio(struct dst_state *st, struct dst_cmd *cmd, struct bio *bio)
+{
+ struct bio_vec *bv;
+ struct dst_crypto_ctl *c = &st->node->crypto;
+ int err, i = 0;
+ int flags = MSG_WAITALL;
+
+ err = dst_data_send_header(st->socket, cmd,
+ sizeof(struct dst_cmd) + c->crypto_attached_size, bio->bi_vcnt);
+ if (err)
+ goto err_out_exit;
+
+ bio_for_each_segment(bv, bio, i) {
+ if (i < bio->bi_vcnt - 1)
+ flags |= MSG_MORE;
+
+ err = kernel_sendpage(st->socket, bv->bv_page, bv->bv_offset,
+ bv->bv_len, flags);
+ if (err <= 0)
+ goto err_out_exit;
+ }
+
+ return 0;
+
+err_out_exit:
+ dprintk("%s: %d/%d, flags: %x, err: %d.\n",
+ __func__, i, bio->bi_vcnt, flags, err);
+ return err;
+}
+
+/*
+ * Send transaction to the remote peer.
+ */
+int dst_trans_send(struct dst_trans *t)
+{
+ int err;
+ struct dst_state *st = t->n->state;
+ struct bio *bio = t->bio;
+
+ dst_convert_cmd(&t->cmd);
+
+ dst_state_lock(st);
+ if (!st->socket) {
+ err = dst_state_init_connected(st);
+ if (err)
+ goto err_out_unlock;
+ }
+
+ if (bio_data_dir(bio) == WRITE) {
+ err = dst_send_bio(st, &t->cmd, t->bio);
+ } else {
+ err = dst_data_send_header(st->socket, &t->cmd,
+ sizeof(struct dst_cmd), 0);
+ }
+ if (err)
+ goto err_out_reset;
+
+ dst_state_unlock(st);
+ return 0;
+
+err_out_reset:
+ dst_state_reset_nolock(st);
+err_out_unlock:
+ dst_state_unlock(st);
+
+ return err;
+}
diff --git a/drivers/staging/dst/thread_pool.c b/drivers/staging/dst/thread_pool.c
new file mode 100644
index 00000000000..7bed4e85102
--- /dev/null
+++ b/drivers/staging/dst/thread_pool.c
@@ -0,0 +1,345 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/dst.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+
+/*
+ * Thread pool abstraction allows to schedule a work to be performed
+ * on behalf of kernel thread. One does not operate with threads itself,
+ * instead user provides setup and cleanup callbacks for thread pool itself,
+ * and action and cleanup callbacks for each submitted work.
+ *
+ * Each worker has private data initialized at creation time and data,
+ * provided by user at scheduling time.
+ *
+ * When action is being performed, thread can not be used by other users,
+ * instead they will sleep until there is free thread to pick their work.
+ */
+struct thread_pool_worker
+{
+ struct list_head worker_entry;
+
+ struct task_struct *thread;
+
+ struct thread_pool *pool;
+
+ int error;
+ int has_data;
+ int need_exit;
+ unsigned int id;
+
+ wait_queue_head_t wait;
+
+ void *private;
+ void *schedule_data;
+
+ int (* action)(void *private, void *schedule_data);
+ void (* cleanup)(void *private);
+};
+
+static void thread_pool_exit_worker(struct thread_pool_worker *w)
+{
+ kthread_stop(w->thread);
+
+ w->cleanup(w->private);
+ kfree(w);
+}
+
+/*
+ * Called to mark thread as ready and allow users to schedule new work.
+ */
+static void thread_pool_worker_make_ready(struct thread_pool_worker *w)
+{
+ struct thread_pool *p = w->pool;
+
+ mutex_lock(&p->thread_lock);
+
+ if (!w->need_exit) {
+ list_move_tail(&w->worker_entry, &p->ready_list);
+ w->has_data = 0;
+ mutex_unlock(&p->thread_lock);
+
+ wake_up(&p->wait);
+ } else {
+ p->thread_num--;
+ list_del(&w->worker_entry);
+ mutex_unlock(&p->thread_lock);
+
+ thread_pool_exit_worker(w);
+ }
+}
+
+/*
+ * Thread action loop: waits until there is new work.
+ */
+static int thread_pool_worker_func(void *data)
+{
+ struct thread_pool_worker *w = data;
+
+ while (!kthread_should_stop()) {
+ wait_event_interruptible(w->wait,
+ kthread_should_stop() || w->has_data);
+
+ if (kthread_should_stop())
+ break;
+
+ if (!w->has_data)
+ continue;
+
+ w->action(w->private, w->schedule_data);
+ thread_pool_worker_make_ready(w);
+ }
+
+ return 0;
+}
+
+/*
+ * Remove single worker without specifying which one.
+ */
+void thread_pool_del_worker(struct thread_pool *p)
+{
+ struct thread_pool_worker *w = NULL;
+
+ while (!w && p->thread_num) {
+ wait_event(p->wait, !list_empty(&p->ready_list) || !p->thread_num);
+
+ dprintk("%s: locking list_empty: %d, thread_num: %d.\n",
+ __func__, list_empty(&p->ready_list), p->thread_num);
+
+ mutex_lock(&p->thread_lock);
+ if (!list_empty(&p->ready_list)) {
+ w = list_first_entry(&p->ready_list,
+ struct thread_pool_worker,
+ worker_entry);
+
+ dprintk("%s: deleting w: %p, thread_num: %d, list: %p [%p.%p].\n",
+ __func__, w, p->thread_num, &p->ready_list,
+ p->ready_list.prev, p->ready_list.next);
+
+ p->thread_num--;
+ list_del(&w->worker_entry);
+ }
+ mutex_unlock(&p->thread_lock);
+ }
+
+ if (w)
+ thread_pool_exit_worker(w);
+ dprintk("%s: deleted w: %p, thread_num: %d.\n",
+ __func__, w, p->thread_num);
+}
+
+/*
+ * Remove a worker with given ID.
+ */
+void thread_pool_del_worker_id(struct thread_pool *p, unsigned int id)
+{
+ struct thread_pool_worker *w;
+ int found = 0;
+
+ mutex_lock(&p->thread_lock);
+ list_for_each_entry(w, &p->ready_list, worker_entry) {
+ if (w->id == id) {
+ found = 1;
+ p->thread_num--;
+ list_del(&w->worker_entry);
+ break;
+ }
+ }
+
+ if (!found) {
+ list_for_each_entry(w, &p->active_list, worker_entry) {
+ if (w->id == id) {
+ w->need_exit = 1;
+ break;
+ }
+ }
+ }
+ mutex_unlock(&p->thread_lock);
+
+ if (found)
+ thread_pool_exit_worker(w);
+}
+
+/*
+ * Add new worker thread with given parameters.
+ * If initialization callback fails, return error.
+ */
+int thread_pool_add_worker(struct thread_pool *p,
+ char *name,
+ unsigned int id,
+ void *(* init)(void *private),
+ void (* cleanup)(void *private),
+ void *private)
+{
+ struct thread_pool_worker *w;
+ int err = -ENOMEM;
+
+ w = kzalloc(sizeof(struct thread_pool_worker), GFP_KERNEL);
+ if (!w)
+ goto err_out_exit;
+
+ w->pool = p;
+ init_waitqueue_head(&w->wait);
+ w->cleanup = cleanup;
+ w->id = id;
+
+ w->thread = kthread_run(thread_pool_worker_func, w, "%s", name);
+ if (IS_ERR(w->thread)) {
+ err = PTR_ERR(w->thread);
+ goto err_out_free;
+ }
+
+ w->private = init(private);
+ if (IS_ERR(w->private)) {
+ err = PTR_ERR(w->private);
+ goto err_out_stop_thread;
+ }
+
+ mutex_lock(&p->thread_lock);
+ list_add_tail(&w->worker_entry, &p->ready_list);
+ p->thread_num++;
+ mutex_unlock(&p->thread_lock);
+
+ return 0;
+
+err_out_stop_thread:
+ kthread_stop(w->thread);
+err_out_free:
+ kfree(w);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Destroy the whole pool.
+ */
+void thread_pool_destroy(struct thread_pool *p)
+{
+ while (p->thread_num) {
+ dprintk("%s: num: %d.\n", __func__, p->thread_num);
+ thread_pool_del_worker(p);
+ }
+
+ kfree(p);
+}
+
+/*
+ * Create a pool with given number of threads.
+ * They will have sequential IDs started from zero.
+ */
+struct thread_pool *thread_pool_create(int num, char *name,
+ void *(* init)(void *private),
+ void (* cleanup)(void *private),
+ void *private)
+{
+ struct thread_pool_worker *w, *tmp;
+ struct thread_pool *p;
+ int err = -ENOMEM;
+ int i;
+
+ p = kzalloc(sizeof(struct thread_pool), GFP_KERNEL);
+ if (!p)
+ goto err_out_exit;
+
+ init_waitqueue_head(&p->wait);
+ mutex_init(&p->thread_lock);
+ INIT_LIST_HEAD(&p->ready_list);
+ INIT_LIST_HEAD(&p->active_list);
+ p->thread_num = 0;
+
+ for (i=0; i<num; ++i) {
+ err = thread_pool_add_worker(p, name, i, init,
+ cleanup, private);
+ if (err)
+ goto err_out_free_all;
+ }
+
+ return p;
+
+err_out_free_all:
+ list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
+ list_del(&w->worker_entry);
+ thread_pool_exit_worker(w);
+ }
+ kfree(p);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+/*
+ * Schedule execution of the action on a given thread,
+ * provided ID pointer has to match previously stored
+ * private data.
+ */
+int thread_pool_schedule_private(struct thread_pool *p,
+ int (* setup)(void *private, void *data),
+ int (* action)(void *private, void *data),
+ void *data, long timeout, void *id)
+{
+ struct thread_pool_worker *w, *tmp, *worker = NULL;
+ int err = 0;
+
+ while (!worker && !err) {
+ timeout = wait_event_interruptible_timeout(p->wait,
+ !list_empty(&p->ready_list),
+ timeout);
+
+ if (!timeout) {
+ err = -ETIMEDOUT;
+ break;
+ }
+
+ worker = NULL;
+ mutex_lock(&p->thread_lock);
+ list_for_each_entry_safe(w, tmp, &p->ready_list, worker_entry) {
+ if (id && id != w->private)
+ continue;
+
+ worker = w;
+
+ list_move_tail(&w->worker_entry, &p->active_list);
+
+ err = setup(w->private, data);
+ if (!err) {
+ w->schedule_data = data;
+ w->action = action;
+ w->has_data = 1;
+ wake_up(&w->wait);
+ } else {
+ list_move_tail(&w->worker_entry, &p->ready_list);
+ }
+
+ break;
+ }
+ mutex_unlock(&p->thread_lock);
+ }
+
+ return err;
+}
+
+/*
+ * Schedule execution on arbitrary thread from the pool.
+ */
+int thread_pool_schedule(struct thread_pool *p,
+ int (* setup)(void *private, void *data),
+ int (* action)(void *private, void *data),
+ void *data, long timeout)
+{
+ return thread_pool_schedule_private(p, setup,
+ action, data, timeout, NULL);
+}
diff --git a/drivers/staging/dst/trans.c b/drivers/staging/dst/trans.c
new file mode 100644
index 00000000000..557d372a496
--- /dev/null
+++ b/drivers/staging/dst/trans.c
@@ -0,0 +1,335 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/bio.h>
+#include <linux/dst.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+/*
+ * Transaction memory pool size.
+ */
+static int dst_mempool_num = 32;
+module_param(dst_mempool_num, int, 0644);
+
+/*
+ * Transaction tree management.
+ */
+static inline int dst_trans_cmp(dst_gen_t gen, dst_gen_t new)
+{
+ if (gen < new)
+ return 1;
+ if (gen > new)
+ return -1;
+ return 0;
+}
+
+struct dst_trans *dst_trans_search(struct dst_node *node, dst_gen_t gen)
+{
+ struct rb_root *root = &node->trans_root;
+ struct rb_node *n = root->rb_node;
+ struct dst_trans *t, *ret = NULL;
+ int cmp;
+
+ while (n) {
+ t = rb_entry(n, struct dst_trans, trans_entry);
+
+ cmp = dst_trans_cmp(t->gen, gen);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else {
+ ret = t;
+ break;
+ }
+ }
+
+ dprintk("%s: %s transaction: id: %llu.\n", __func__,
+ (ret)?"found":"not found", gen);
+
+ return ret;
+}
+
+static int dst_trans_insert(struct dst_trans *new)
+{
+ struct rb_root *root = &new->n->trans_root;
+ struct rb_node **n = &root->rb_node, *parent = NULL;
+ struct dst_trans *ret = NULL, *t;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ t = rb_entry(parent, struct dst_trans, trans_entry);
+
+ cmp = dst_trans_cmp(t->gen, new->gen);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = t;
+ break;
+ }
+ }
+
+ new->send_time = jiffies;
+ if (ret) {
+ printk("%s: exist: old: gen: %llu, bio: %llu/%u, send_time: %lu, "
+ "new: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
+ __func__,
+ ret->gen, (u64)ret->bio->bi_sector,
+ ret->bio->bi_size, ret->send_time,
+ new->gen, (u64)new->bio->bi_sector,
+ new->bio->bi_size, new->send_time);
+ return -EEXIST;
+ }
+
+ rb_link_node(&new->trans_entry, parent, n);
+ rb_insert_color(&new->trans_entry, root);
+
+ dprintk("%s: inserted: gen: %llu, bio: %llu/%u, send_time: %lu.\n",
+ __func__, new->gen, (u64)new->bio->bi_sector,
+ new->bio->bi_size, new->send_time);
+
+ return 0;
+}
+
+int dst_trans_remove_nolock(struct dst_trans *t)
+{
+ struct dst_node *n = t->n;
+
+ if (t->trans_entry.rb_parent_color) {
+ rb_erase(&t->trans_entry, &n->trans_root);
+ t->trans_entry.rb_parent_color = 0;
+ }
+ return 0;
+}
+
+int dst_trans_remove(struct dst_trans *t)
+{
+ int ret;
+ struct dst_node *n = t->n;
+
+ mutex_lock(&n->trans_lock);
+ ret = dst_trans_remove_nolock(t);
+ mutex_unlock(&n->trans_lock);
+
+ return ret;
+}
+
+/*
+ * When transaction is completed and there are no more users,
+ * we complete appriate block IO request with given error status.
+ */
+void dst_trans_put(struct dst_trans *t)
+{
+ if (atomic_dec_and_test(&t->refcnt)) {
+ struct bio *bio = t->bio;
+
+ dprintk("%s: completed t: %p, gen: %llu, bio: %p.\n",
+ __func__, t, t->gen, bio);
+
+ bio_endio(bio, t->error);
+ bio_put(bio);
+
+ dst_node_put(t->n);
+ mempool_free(t, t->n->trans_pool);
+ }
+}
+
+/*
+ * Process given block IO request: allocate transaction, insert it into the tree
+ * and send/schedule crypto processing.
+ */
+int dst_process_bio(struct dst_node *n, struct bio *bio)
+{
+ struct dst_trans *t;
+ int err = -ENOMEM;
+
+ t = mempool_alloc(n->trans_pool, GFP_NOFS);
+ if (!t)
+ goto err_out_exit;
+
+ t->n = dst_node_get(n);
+ t->bio = bio;
+ t->error = 0;
+ t->retries = 0;
+ atomic_set(&t->refcnt, 1);
+ t->gen = atomic_long_inc_return(&n->gen);
+
+ t->enc = bio_data_dir(bio);
+ dst_bio_to_cmd(bio, &t->cmd, DST_IO, t->gen);
+
+ mutex_lock(&n->trans_lock);
+ err = dst_trans_insert(t);
+ mutex_unlock(&n->trans_lock);
+ if (err)
+ goto err_out_free;
+
+ dprintk("%s: gen: %llu, bio: %llu/%u, dir/enc: %d, need_crypto: %d.\n",
+ __func__, t->gen, (u64)bio->bi_sector,
+ bio->bi_size, t->enc, dst_need_crypto(n));
+
+ if (dst_need_crypto(n) && t->enc)
+ dst_trans_crypto(t);
+ else
+ dst_trans_send(t);
+
+ return 0;
+
+err_out_free:
+ dst_node_put(n);
+ mempool_free(t, n->trans_pool);
+err_out_exit:
+ bio_endio(bio, err);
+ bio_put(bio);
+ return err;
+}
+
+/*
+ * Scan for timeout/stale transactions.
+ * Each transaction is being resent multiple times before error completion.
+ */
+static void dst_trans_scan(struct work_struct *work)
+{
+ struct dst_node *n = container_of(work, struct dst_node, trans_work.work);
+ struct rb_node *rb_node;
+ struct dst_trans *t;
+ unsigned long timeout = n->trans_scan_timeout;
+ int num = 10 * n->trans_max_retries;
+
+ mutex_lock(&n->trans_lock);
+
+ for (rb_node = rb_first(&n->trans_root); rb_node; ) {
+ t = rb_entry(rb_node, struct dst_trans, trans_entry);
+
+ if (timeout && time_after(t->send_time + timeout, jiffies)
+ && t->retries == 0)
+ break;
+#if 0
+ dprintk("%s: t: %p, gen: %llu, n: %s, retries: %u, max: %u.\n",
+ __func__, t, t->gen, n->name,
+ t->retries, n->trans_max_retries);
+#endif
+ if (--num == 0)
+ break;
+
+ dst_trans_get(t);
+
+ rb_node = rb_next(rb_node);
+
+ if (timeout && (++t->retries < n->trans_max_retries)) {
+ dst_trans_send(t);
+ } else {
+ t->error = -ETIMEDOUT;
+ dst_trans_remove_nolock(t);
+ dst_trans_put(t);
+ }
+
+ dst_trans_put(t);
+ }
+
+ mutex_unlock(&n->trans_lock);
+
+ /*
+ * If no timeout specified then system is in the middle of exiting process,
+ * so no need to reschedule scanning process again.
+ */
+ if (timeout) {
+ if (!num)
+ timeout = HZ;
+ schedule_delayed_work(&n->trans_work, timeout);
+ }
+}
+
+/*
+ * Flush all transactions and mark them as timed out.
+ * Destroy transaction pools.
+ */
+void dst_node_trans_exit(struct dst_node *n)
+{
+ struct dst_trans *t;
+ struct rb_node *rb_node;
+
+ if (!n->trans_cache)
+ return;
+
+ dprintk("%s: n: %p, cancelling the work.\n", __func__, n);
+ cancel_delayed_work_sync(&n->trans_work);
+ flush_scheduled_work();
+ dprintk("%s: n: %p, work has been cancelled.\n", __func__, n);
+
+ for (rb_node = rb_first(&n->trans_root); rb_node; ) {
+ t = rb_entry(rb_node, struct dst_trans, trans_entry);
+
+ dprintk("%s: t: %p, gen: %llu, n: %s.\n",
+ __func__, t, t->gen, n->name);
+
+ rb_node = rb_next(rb_node);
+
+ t->error = -ETIMEDOUT;
+ dst_trans_remove_nolock(t);
+ dst_trans_put(t);
+ }
+
+ mempool_destroy(n->trans_pool);
+ kmem_cache_destroy(n->trans_cache);
+}
+
+/*
+ * Initialize transaction storage for given node.
+ * Transaction stores not only control information,
+ * but also network command and crypto data (if needed)
+ * to reduce number of allocations. Thus transaction size
+ * differs from node to node.
+ */
+int dst_node_trans_init(struct dst_node *n, unsigned int size)
+{
+ /*
+ * We need this, since node with given name can be dropped from the
+ * hash table, but be still alive, so subsequent creation of the node
+ * with the same name may collide with existing cache name.
+ */
+
+ snprintf(n->cache_name, sizeof(n->cache_name), "%s-%p", n->name, n);
+
+ n->trans_cache = kmem_cache_create(n->cache_name,
+ size + n->crypto.crypto_attached_size,
+ 0, 0, NULL);
+ if (!n->trans_cache)
+ goto err_out_exit;
+
+ n->trans_pool = mempool_create_slab_pool(dst_mempool_num, n->trans_cache);
+ if (!n->trans_pool)
+ goto err_out_cache_destroy;
+
+ mutex_init(&n->trans_lock);
+ n->trans_root = RB_ROOT;
+
+ INIT_DELAYED_WORK(&n->trans_work, dst_trans_scan);
+ schedule_delayed_work(&n->trans_work, n->trans_scan_timeout);
+
+ dprintk("%s: n: %p, size: %u, crypto: %u.\n",
+ __func__, n, size, n->crypto.crypto_attached_size);
+
+ return 0;
+
+err_out_cache_destroy:
+ kmem_cache_destroy(n->trans_cache);
+err_out_exit:
+ return -ENOMEM;
+}
diff --git a/drivers/staging/echo/bit_operations.h b/drivers/staging/echo/bit_operations.h
index cecdcf3fd75..4c4ccbc9731 100644
--- a/drivers/staging/echo/bit_operations.h
+++ b/drivers/staging/echo/bit_operations.h
@@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: bit_operations.h,v 1.11 2006/11/28 15:37:03 steveu Exp $
*/
/*! \file */
@@ -34,7 +32,7 @@
/*! \brief Find the bit position of the highest set bit in a word
\param bits The word to be searched
\return The bit number of the highest set bit, or -1 if the word is zero. */
-static __inline__ int top_bit(unsigned int bits)
+static inline int top_bit(unsigned int bits)
{
int res;
@@ -50,7 +48,7 @@ static __inline__ int top_bit(unsigned int bits)
/*! \brief Find the bit position of the lowest set bit in a word
\param bits The word to be searched
\return The bit number of the lowest set bit, or -1 if the word is zero. */
-static __inline__ int bottom_bit(unsigned int bits)
+static inline int bottom_bit(unsigned int bits)
{
int res;
@@ -63,7 +61,7 @@ static __inline__ int bottom_bit(unsigned int bits)
return res;
}
#else
-static __inline__ int top_bit(unsigned int bits)
+static inline int top_bit(unsigned int bits)
{
int i;
@@ -93,7 +91,7 @@ static __inline__ int top_bit(unsigned int bits)
return i;
}
-static __inline__ int bottom_bit(unsigned int bits)
+static inline int bottom_bit(unsigned int bits)
{
int i;
@@ -127,7 +125,7 @@ static __inline__ int bottom_bit(unsigned int bits)
/*! \brief Bit reverse a byte.
\param data The byte to be reversed.
\return The bit reversed version of data. */
-static __inline__ uint8_t bit_reverse8(uint8_t x)
+static inline uint8_t bit_reverse8(uint8_t x)
{
#if defined(__i386__) || defined(__x86_64__)
/* If multiply is fast */
@@ -172,32 +170,32 @@ uint32_t make_mask32(uint32_t x);
uint16_t make_mask16(uint16_t x);
/*! \brief Find the least significant one in a word, and return a word
- with just that bit set.
+ with just that bit set.
\param x The word to be searched.
\return The word with the single set bit. */
-static __inline__ uint32_t least_significant_one32(uint32_t x)
+static inline uint32_t least_significant_one32(uint32_t x)
{
- return (x & (-(int32_t) x));
+ return x & (-(int32_t) x);
}
/*! \brief Find the most significant one in a word, and return a word
- with just that bit set.
+ with just that bit set.
\param x The word to be searched.
\return The word with the single set bit. */
-static __inline__ uint32_t most_significant_one32(uint32_t x)
+static inline uint32_t most_significant_one32(uint32_t x)
{
#if defined(__i386__) || defined(__x86_64__)
return 1 << top_bit(x);
#else
x = make_mask32(x);
- return (x ^ (x >> 1));
+ return x ^ (x >> 1);
#endif
}
/*! \brief Find the parity of a byte.
\param x The byte to be checked.
\return 1 for odd, or 0 for even. */
-static __inline__ int parity8(uint8_t x)
+static inline int parity8(uint8_t x)
{
x = (x ^ (x >> 4)) & 0x0F;
return (0x6996 >> x) & 1;
@@ -206,7 +204,7 @@ static __inline__ int parity8(uint8_t x)
/*! \brief Find the parity of a 16 bit word.
\param x The word to be checked.
\return 1 for odd, or 0 for even. */
-static __inline__ int parity16(uint16_t x)
+static inline int parity16(uint16_t x)
{
x ^= (x >> 8);
x = (x ^ (x >> 4)) & 0x0F;
@@ -216,7 +214,7 @@ static __inline__ int parity16(uint16_t x)
/*! \brief Find the parity of a 32 bit word.
\param x The word to be checked.
\return 1 for odd, or 0 for even. */
-static __inline__ int parity32(uint32_t x)
+static inline int parity32(uint32_t x)
{
x ^= (x >> 16);
x ^= (x >> 8);
diff --git a/drivers/staging/echo/echo.c b/drivers/staging/echo/echo.c
index fd4007e329e..6d7217e1bd0 100644
--- a/drivers/staging/echo/echo.c
+++ b/drivers/staging/echo/echo.c
@@ -27,8 +27,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: echo.c,v 1.20 2006/12/01 18:00:48 steveu Exp $
*/
/*! \file */
@@ -113,17 +111,17 @@
#define MIN_TX_POWER_FOR_ADAPTION 64
#define MIN_RX_POWER_FOR_ADAPTION 64
-#define DTD_HANGOVER 600 /* 600 samples, or 75ms */
-#define DC_LOG2BETA 3 /* log2() of DC filter Beta */
+#define DTD_HANGOVER 600 /* 600 samples, or 75ms */
+#define DC_LOG2BETA 3 /* log2() of DC filter Beta */
/*-----------------------------------------------------------------------*\
- FUNCTIONS
+ FUNCTIONS
\*-----------------------------------------------------------------------*/
/* adapting coeffs using the traditional stochastic descent (N)LMS algorithm */
#ifdef __bfin__
-static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
int shift)
{
int i, j;
@@ -147,13 +145,13 @@ static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
/* st: and en: help us locate the assembler in echo.s */
- //asm("st:");
+ /* asm("st:"); */
n = ec->taps;
for (i = 0, j = offset2; i < n; i++, j++) {
exp = *phist++ * factor;
ec->fir_taps16[1][i] += (int16_t) ((exp + (1 << 14)) >> 15);
}
- //asm("en:");
+ /* asm("en:"); */
/* Note the asm for the inner loop above generated by Blackfin gcc
4.1.1 is pretty good (note even parallel instructions used):
@@ -195,7 +193,7 @@ static void __inline__ lms_adapt_bg(struct oslec_state *ec, int clean,
*/
#else
-static __inline__ void lms_adapt_bg(struct oslec_state *ec, int clean,
+static inline void lms_adapt_bg(struct oslec_state *ec, int clean,
int shift)
{
int i;
@@ -249,9 +247,8 @@ struct oslec_state *oslec_create(int len, int adaption_mode)
fir16_create(&ec->fir_state, ec->fir_taps16[0], ec->taps);
fir16_create(&ec->fir_state_bg, ec->fir_taps16[1], ec->taps);
- for (i = 0; i < 5; i++) {
+ for (i = 0; i < 5; i++)
ec->xvtx[i] = ec->yvtx[i] = ec->xvrx[i] = ec->yvrx[i] = 0;
- }
ec->cng_level = 1000;
oslec_adaption_mode(ec, adaption_mode);
@@ -271,14 +268,13 @@ struct oslec_state *oslec_create(int len, int adaption_mode)
return ec;
- error_oom:
+error_oom:
for (i = 0; i < 2; i++)
kfree(ec->fir_taps16[i]);
kfree(ec);
return NULL;
}
-
EXPORT_SYMBOL_GPL(oslec_create);
void oslec_free(struct oslec_state *ec)
@@ -292,14 +288,12 @@ void oslec_free(struct oslec_state *ec)
kfree(ec->snapshot);
kfree(ec);
}
-
EXPORT_SYMBOL_GPL(oslec_free);
void oslec_adaption_mode(struct oslec_state *ec, int adaption_mode)
{
ec->adaption_mode = adaption_mode;
}
-
EXPORT_SYMBOL_GPL(oslec_adaption_mode);
void oslec_flush(struct oslec_state *ec)
@@ -326,14 +320,12 @@ void oslec_flush(struct oslec_state *ec)
ec->curr_pos = ec->taps - 1;
ec->Pstates = 0;
}
-
EXPORT_SYMBOL_GPL(oslec_flush);
void oslec_snapshot(struct oslec_state *ec)
{
memcpy(ec->snapshot, ec->fir_taps16[0], ec->taps * sizeof(int16_t));
}
-
EXPORT_SYMBOL_GPL(oslec_snapshot);
/* Dual Path Echo Canceller ------------------------------------------------*/
@@ -399,7 +391,7 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
/* efficient "out with the old and in with the new" algorithm so
we don't have to recalculate over the whole block of
samples. */
- new = (int)tx *(int)tx;
+ new = (int)tx * (int)tx;
old = (int)ec->fir_state.history[ec->fir_state.curr_pos] *
(int)ec->fir_state.history[ec->fir_state.curr_pos];
ec->Pstates +=
@@ -498,15 +490,15 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
if ((ec->adaption_mode & ECHO_CAN_USE_ADAPTION) &&
(ec->nonupdate_dwell == 0) &&
- (8 * ec->Lclean_bg <
- 7 * ec->Lclean) /* (ec->Lclean_bg < 0.875*ec->Lclean) */ &&
- (8 * ec->Lclean_bg <
- ec->Ltx) /* (ec->Lclean_bg < 0.125*ec->Ltx) */ ) {
+ /* (ec->Lclean_bg < 0.875*ec->Lclean) */
+ (8 * ec->Lclean_bg < 7 * ec->Lclean) &&
+ /* (ec->Lclean_bg < 0.125*ec->Ltx) */
+ (8 * ec->Lclean_bg < ec->Ltx)) {
if (ec->cond_met == 6) {
/* BG filter has had better results for 6 consecutive samples */
ec->adapt = 1;
memcpy(ec->fir_taps16[0], ec->fir_taps16[1],
- ec->taps * sizeof(int16_t));
+ ec->taps * sizeof(int16_t));
} else
ec->cond_met++;
} else
@@ -580,7 +572,6 @@ int16_t oslec_update(struct oslec_state *ec, int16_t tx, int16_t rx)
return (int16_t) ec->clean_nlp << 1;
}
-
EXPORT_SYMBOL_GPL(oslec_update);
/* This function is seperated from the echo canceller is it is usually called
@@ -604,7 +595,7 @@ EXPORT_SYMBOL_GPL(oslec_update);
precision, which noise shapes things, giving very clean DC removal.
*/
-int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
+int16_t oslec_hpf_tx(struct oslec_state *ec, int16_t tx)
{
int tmp, tmp1;
@@ -629,7 +620,6 @@ int16_t oslec_hpf_tx(struct oslec_state * ec, int16_t tx)
return tx;
}
-
EXPORT_SYMBOL_GPL(oslec_hpf_tx);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/echo/echo.h b/drivers/staging/echo/echo.h
index 34fb816b15c..c835e5c5314 100644
--- a/drivers/staging/echo/echo.h
+++ b/drivers/staging/echo/echo.h
@@ -23,8 +23,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: echo.h,v 1.9 2006/10/24 13:45:28 steveu Exp $
*/
#ifndef __ECHO_H
diff --git a/drivers/staging/echo/fir.h b/drivers/staging/echo/fir.h
index d35f16805f4..ac6c553e89f 100644
--- a/drivers/staging/echo/fir.h
+++ b/drivers/staging/echo/fir.h
@@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: fir.h,v 1.8 2006/10/24 13:45:28 steveu Exp $
*/
/*! \page fir_page FIR filtering
@@ -102,8 +100,8 @@ struct fir_float_state_t {
float *history;
};
-static __inline__ const int16_t *fir16_create(struct fir16_state_t *fir,
- const int16_t * coeffs, int taps)
+static inline const int16_t *fir16_create(struct fir16_state_t *fir,
+ const int16_t *coeffs, int taps)
{
fir->taps = taps;
fir->curr_pos = taps - 1;
@@ -116,7 +114,7 @@ static __inline__ const int16_t *fir16_create(struct fir16_state_t *fir,
return fir->history;
}
-static __inline__ void fir16_flush(struct fir16_state_t *fir)
+static inline void fir16_flush(struct fir16_state_t *fir)
{
#if defined(USE_MMX) || defined(USE_SSE2) || defined(__bfin__)
memset(fir->history, 0, 2 * fir->taps * sizeof(int16_t));
@@ -125,7 +123,7 @@ static __inline__ void fir16_flush(struct fir16_state_t *fir)
#endif
}
-static __inline__ void fir16_free(struct fir16_state_t *fir)
+static inline void fir16_free(struct fir16_state_t *fir)
{
kfree(fir->history);
}
@@ -148,16 +146,16 @@ static inline int32_t dot_asm(short *x, short *y, int len)
"A0 += R0.L*R1.L (IS);\n\t"
"R0 = A0;\n\t"
"%0 = R0;\n\t"
- :"=&d"(dot)
- :"a"(x), "a"(y), "a"(len)
- :"I0", "I1", "A1", "A0", "R0", "R1"
+ : "=&d"(dot)
+ : "a"(x), "a"(y), "a"(len)
+ : "I0", "I1", "A1", "A0", "R0", "R1"
);
return dot;
}
#endif
-static __inline__ int16_t fir16(struct fir16_state_t *fir, int16_t sample)
+static inline int16_t fir16(struct fir16_state_t *fir, int16_t sample)
{
int32_t y;
#if defined(USE_MMX)
@@ -250,8 +248,8 @@ static __inline__ int16_t fir16(struct fir16_state_t *fir, int16_t sample)
return (int16_t) (y >> 15);
}
-static __inline__ const int16_t *fir32_create(struct fir32_state_t *fir,
- const int32_t * coeffs, int taps)
+static inline const int16_t *fir32_create(struct fir32_state_t *fir,
+ const int32_t *coeffs, int taps)
{
fir->taps = taps;
fir->curr_pos = taps - 1;
@@ -260,17 +258,17 @@ static __inline__ const int16_t *fir32_create(struct fir32_state_t *fir,
return fir->history;
}
-static __inline__ void fir32_flush(struct fir32_state_t *fir)
+static inline void fir32_flush(struct fir32_state_t *fir)
{
memset(fir->history, 0, fir->taps * sizeof(int16_t));
}
-static __inline__ void fir32_free(struct fir32_state_t *fir)
+static inline void fir32_free(struct fir32_state_t *fir)
{
kfree(fir->history);
}
-static __inline__ int16_t fir32(struct fir32_state_t *fir, int16_t sample)
+static inline int16_t fir32(struct fir32_state_t *fir, int16_t sample)
{
int i;
int32_t y;
diff --git a/drivers/staging/echo/mmx.h b/drivers/staging/echo/mmx.h
index 44e5cfebc18..c1dcd7299cb 100644
--- a/drivers/staging/echo/mmx.h
+++ b/drivers/staging/echo/mmx.h
@@ -44,238 +44,238 @@ union xmm_t {
char b[16];
};
-#define mmx_i2r(op,imm,reg) \
- __asm__ __volatile__ (#op " %0, %%" #reg \
- : /* nothing */ \
- : "i" (imm) )
-
-#define mmx_m2r(op,mem,reg) \
- __asm__ __volatile__ (#op " %0, %%" #reg \
- : /* nothing */ \
- : "m" (mem))
-
-#define mmx_r2m(op,reg,mem) \
- __asm__ __volatile__ (#op " %%" #reg ", %0" \
- : "=m" (mem) \
- : /* nothing */ )
-
-#define mmx_r2r(op,regs,regd) \
- __asm__ __volatile__ (#op " %" #regs ", %" #regd)
-
-#define emms() __asm__ __volatile__ ("emms")
-
-#define movd_m2r(var,reg) mmx_m2r (movd, var, reg)
-#define movd_r2m(reg,var) mmx_r2m (movd, reg, var)
-#define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd)
-
-#define movq_m2r(var,reg) mmx_m2r (movq, var, reg)
-#define movq_r2m(reg,var) mmx_r2m (movq, reg, var)
-#define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd)
-
-#define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg)
-#define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd)
-#define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg)
-#define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd)
-
-#define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg)
-#define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd)
-
-#define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg)
-#define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd)
-#define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg)
-#define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd)
-#define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg)
-#define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd)
-
-#define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg)
-#define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd)
-#define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg)
-#define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd)
-
-#define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg)
-#define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd)
-#define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg)
-#define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd)
-
-#define pand_m2r(var,reg) mmx_m2r (pand, var, reg)
-#define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd)
-
-#define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg)
-#define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd)
-
-#define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg)
-#define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd)
-#define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg)
-#define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd)
-#define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg)
-#define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd)
-
-#define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg)
-#define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd)
-#define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg)
-#define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd)
-#define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg)
-#define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd)
-
-#define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg)
-#define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd)
-
-#define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg)
-#define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd)
-
-#define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg)
-#define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd)
-
-#define por_m2r(var,reg) mmx_m2r (por, var, reg)
-#define por_r2r(regs,regd) mmx_r2r (por, regs, regd)
-
-#define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg)
-#define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg)
-#define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd)
-#define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg)
-#define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg)
-#define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd)
-#define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg)
-#define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg)
-#define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd)
-
-#define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg)
-#define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg)
-#define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd)
-#define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg)
-#define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg)
-#define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd)
-
-#define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg)
-#define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg)
-#define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd)
-#define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg)
-#define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg)
-#define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd)
-#define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg)
-#define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg)
-#define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd)
-
-#define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg)
-#define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd)
-#define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg)
-#define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd)
-#define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg)
-#define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd)
-
-#define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg)
-#define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd)
-#define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg)
-#define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd)
-
-#define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg)
-#define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd)
-#define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg)
-#define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd)
-
-#define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg)
-#define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd)
-#define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg)
-#define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd)
-#define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg)
-#define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd)
-
-#define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg)
-#define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd)
-#define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg)
-#define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd)
-#define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg)
-#define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd)
-
-#define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg)
-#define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd)
+#define mmx_i2r(op, imm, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "i" (imm))
+
+#define mmx_m2r(op, mem, reg) \
+ __asm__ __volatile__ (#op " %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem))
+
+#define mmx_r2m(op, reg, mem) \
+ __asm__ __volatile__ (#op " %%" #reg ", %0" \
+ : "=m" (mem) \
+ : /* nothing */)
+
+#define mmx_r2r(op, regs, regd) \
+ __asm__ __volatile__ (#op " %" #regs ", %" #regd)
+
+#define emms() __asm__ __volatile__ ("emms")
+
+#define movd_m2r(var, reg) mmx_m2r(movd, var, reg)
+#define movd_r2m(reg, var) mmx_r2m(movd, reg, var)
+#define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd)
+
+#define movq_m2r(var, reg) mmx_m2r(movq, var, reg)
+#define movq_r2m(reg, var) mmx_r2m(movq, reg, var)
+#define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd)
+
+#define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg)
+#define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd)
+#define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg)
+#define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd)
+
+#define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg)
+#define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd)
+
+#define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg)
+#define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd)
+#define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg)
+#define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd)
+#define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg)
+#define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd)
+
+#define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg)
+#define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd)
+#define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg)
+#define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd)
+
+#define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg)
+#define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd)
+#define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg)
+#define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd)
+
+#define pand_m2r(var, reg) mmx_m2r(pand, var, reg)
+#define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd)
+
+#define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg)
+#define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd)
+
+#define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg)
+#define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd)
+#define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg)
+#define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd)
+#define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg)
+#define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd)
+
+#define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg)
+#define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd)
+#define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg)
+#define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd)
+#define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg)
+#define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd)
+
+#define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg)
+#define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd)
+
+#define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg)
+#define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd)
+
+#define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg)
+#define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd)
+
+#define por_m2r(var, reg) mmx_m2r(por, var, reg)
+#define por_r2r(regs, regd) mmx_r2r(por, regs, regd)
+
+#define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg)
+#define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg)
+#define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd)
+#define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg)
+#define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg)
+#define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd)
+#define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg)
+#define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg)
+#define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd)
+
+#define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg)
+#define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg)
+#define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd)
+#define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg)
+#define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg)
+#define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd)
+
+#define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg)
+#define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg)
+#define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd)
+#define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg)
+#define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg)
+#define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd)
+#define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg)
+#define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg)
+#define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd)
+
+#define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg)
+#define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd)
+#define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg)
+#define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd)
+#define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg)
+#define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd)
+
+#define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg)
+#define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd)
+#define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg)
+#define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd)
+
+#define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg)
+#define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd)
+#define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg)
+#define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd)
+
+#define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg)
+#define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd)
+#define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg)
+#define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd)
+#define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg)
+#define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd)
+
+#define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg)
+#define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd)
+#define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg)
+#define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd)
+#define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg)
+#define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd)
+
+#define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg)
+#define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd)
/* 3DNOW extensions */
-#define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg)
-#define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd)
+#define pavgusb_m2r(var, reg) mmx_m2r(pavgusb, var, reg)
+#define pavgusb_r2r(regs, regd) mmx_r2r(pavgusb, regs, regd)
/* AMD MMX extensions - also available in intel SSE */
-#define mmx_m2ri(op,mem,reg,imm) \
- __asm__ __volatile__ (#op " %1, %0, %%" #reg \
- : /* nothing */ \
- : "m" (mem), "i" (imm))
-#define mmx_r2ri(op,regs,regd,imm) \
- __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
- : /* nothing */ \
- : "i" (imm) )
+#define mmx_m2ri(op, mem, reg, imm) \
+ __asm__ __volatile__ (#op " %1, %0, %%" #reg \
+ : /* nothing */ \
+ : "m" (mem), "i" (imm))
+#define mmx_r2ri(op, regs, regd, imm) \
+ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \
+ : /* nothing */ \
+ : "i" (imm))
-#define mmx_fetch(mem,hint) \
- __asm__ __volatile__ ("prefetch" #hint " %0" \
- : /* nothing */ \
- : "m" (mem))
+#define mmx_fetch(mem, hint) \
+ __asm__ __volatile__ ("prefetch" #hint " %0" \
+ : /* nothing */ \
+ : "m" (mem))
-#define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg)
+#define maskmovq(regs, maskreg) mmx_r2ri(maskmovq, regs, maskreg)
-#define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var)
+#define movntq_r2m(mmreg, var) mmx_r2m(movntq, mmreg, var)
-#define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg)
-#define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd)
-#define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg)
-#define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd)
+#define pavgb_m2r(var, reg) mmx_m2r(pavgb, var, reg)
+#define pavgb_r2r(regs, regd) mmx_r2r(pavgb, regs, regd)
+#define pavgw_m2r(var, reg) mmx_m2r(pavgw, var, reg)
+#define pavgw_r2r(regs, regd) mmx_r2r(pavgw, regs, regd)
-#define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm)
+#define pextrw_r2r(mmreg, reg, imm) mmx_r2ri(pextrw, mmreg, reg, imm)
-#define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm)
+#define pinsrw_r2r(reg, mmreg, imm) mmx_r2ri(pinsrw, reg, mmreg, imm)
-#define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg)
-#define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd)
+#define pmaxsw_m2r(var, reg) mmx_m2r(pmaxsw, var, reg)
+#define pmaxsw_r2r(regs, regd) mmx_r2r(pmaxsw, regs, regd)
-#define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg)
-#define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd)
+#define pmaxub_m2r(var, reg) mmx_m2r(pmaxub, var, reg)
+#define pmaxub_r2r(regs, regd) mmx_r2r(pmaxub, regs, regd)
-#define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg)
-#define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd)
+#define pminsw_m2r(var, reg) mmx_m2r(pminsw, var, reg)
+#define pminsw_r2r(regs, regd) mmx_r2r(pminsw, regs, regd)
-#define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg)
-#define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd)
+#define pminub_m2r(var, reg) mmx_m2r(pminub, var, reg)
+#define pminub_r2r(regs, regd) mmx_r2r(pminub, regs, regd)
-#define pmovmskb(mmreg,reg) \
- __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
+#define pmovmskb(mmreg, reg) \
+ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg)
-#define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg)
-#define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd)
+#define pmulhuw_m2r(var, reg) mmx_m2r(pmulhuw, var, reg)
+#define pmulhuw_r2r(regs, regd) mmx_r2r(pmulhuw, regs, regd)
-#define prefetcht0(mem) mmx_fetch (mem, t0)
-#define prefetcht1(mem) mmx_fetch (mem, t1)
-#define prefetcht2(mem) mmx_fetch (mem, t2)
-#define prefetchnta(mem) mmx_fetch (mem, nta)
+#define prefetcht0(mem) mmx_fetch(mem, t0)
+#define prefetcht1(mem) mmx_fetch(mem, t1)
+#define prefetcht2(mem) mmx_fetch(mem, t2)
+#define prefetchnta(mem) mmx_fetch(mem, nta)
-#define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg)
-#define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd)
+#define psadbw_m2r(var, reg) mmx_m2r(psadbw, var, reg)
+#define psadbw_r2r(regs, regd) mmx_r2r(psadbw, regs, regd)
-#define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm)
-#define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm)
+#define pshufw_m2r(var, reg, imm) mmx_m2ri(pshufw, var, reg, imm)
+#define pshufw_r2r(regs, regd, imm) mmx_r2ri(pshufw, regs, regd, imm)
-#define sfence() __asm__ __volatile__ ("sfence\n\t")
+#define sfence() __asm__ __volatile__ ("sfence\n\t")
/* SSE2 */
-#define pshufhw_m2r(var,reg,imm) mmx_m2ri(pshufhw, var, reg, imm)
-#define pshufhw_r2r(regs,regd,imm) mmx_r2ri(pshufhw, regs, regd, imm)
-#define pshuflw_m2r(var,reg,imm) mmx_m2ri(pshuflw, var, reg, imm)
-#define pshuflw_r2r(regs,regd,imm) mmx_r2ri(pshuflw, regs, regd, imm)
+#define pshufhw_m2r(var, reg, imm) mmx_m2ri(pshufhw, var, reg, imm)
+#define pshufhw_r2r(regs, regd, imm) mmx_r2ri(pshufhw, regs, regd, imm)
+#define pshuflw_m2r(var, reg, imm) mmx_m2ri(pshuflw, var, reg, imm)
+#define pshuflw_r2r(regs, regd, imm) mmx_r2ri(pshuflw, regs, regd, imm)
-#define pshufd_r2r(regs,regd,imm) mmx_r2ri(pshufd, regs, regd, imm)
+#define pshufd_r2r(regs, regd, imm) mmx_r2ri(pshufd, regs, regd, imm)
-#define movdqa_m2r(var,reg) mmx_m2r (movdqa, var, reg)
-#define movdqa_r2m(reg,var) mmx_r2m (movdqa, reg, var)
-#define movdqa_r2r(regs,regd) mmx_r2r (movdqa, regs, regd)
-#define movdqu_m2r(var,reg) mmx_m2r (movdqu, var, reg)
-#define movdqu_r2m(reg,var) mmx_r2m (movdqu, reg, var)
-#define movdqu_r2r(regs,regd) mmx_r2r (movdqu, regs, regd)
+#define movdqa_m2r(var, reg) mmx_m2r(movdqa, var, reg)
+#define movdqa_r2m(reg, var) mmx_r2m(movdqa, reg, var)
+#define movdqa_r2r(regs, regd) mmx_r2r(movdqa, regs, regd)
+#define movdqu_m2r(var, reg) mmx_m2r(movdqu, var, reg)
+#define movdqu_r2m(reg, var) mmx_r2m(movdqu, reg, var)
+#define movdqu_r2r(regs, regd) mmx_r2r(movdqu, regs, regd)
-#define pmullw_r2m(reg,var) mmx_r2m (pmullw, reg, var)
+#define pmullw_r2m(reg, var) mmx_r2m(pmullw, reg, var)
-#define pslldq_i2r(imm,reg) mmx_i2r (pslldq, imm, reg)
-#define psrldq_i2r(imm,reg) mmx_i2r (psrldq, imm, reg)
+#define pslldq_i2r(imm, reg) mmx_i2r(pslldq, imm, reg)
+#define psrldq_i2r(imm, reg) mmx_i2r(psrldq, imm, reg)
-#define punpcklqdq_r2r(regs,regd) mmx_r2r (punpcklqdq, regs, regd)
-#define punpckhqdq_r2r(regs,regd) mmx_r2r (punpckhqdq, regs, regd)
+#define punpcklqdq_r2r(regs, regd) mmx_r2r(punpcklqdq, regs, regd)
+#define punpckhqdq_r2r(regs, regd) mmx_r2r(punpckhqdq, regs, regd)
#endif /* AVCODEC_I386MMX_H */
diff --git a/drivers/staging/epl/Benchmark.h b/drivers/staging/epl/Benchmark.h
index 62dee3b1437..4cc01bd12a1 100644
--- a/drivers/staging/epl/Benchmark.h
+++ b/drivers/staging/epl/Benchmark.h
@@ -73,12 +73,6 @@
#include "global.h"
-#if (TARGET_SYSTEM == _NO_OS_) && (DEV_SYSTEM == _DEV_GNU_CF548X_)
-#include "common.h"
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-
-// #include <linux/config.h>
#include <linux/kernel.h>
#ifdef CONFIG_COLDFIRE
@@ -93,12 +87,6 @@
#define BENCHMARK_MODULES 0x00000000
#endif
-#else
- // disable Benchmarking
-#undef BENCHMARK_MODULES
-#define BENCHMARK_MODULES 0x00000000
-#endif
-
/***************************************************************************/
/* */
/* */
diff --git a/drivers/staging/epl/Debug.h b/drivers/staging/epl/Debug.h
index 05de9d541fd..851a22213ad 100644
--- a/drivers/staging/epl/Debug.h
+++ b/drivers/staging/epl/Debug.h
@@ -163,25 +163,6 @@
#endif
//---------------------------------------------------------------------------
-#if (DEV_SYSTEM == _DEV_WIN32_) && defined (TRACE_MSG)
-
- // For WIN32 the macro DEBUG_TRACE0 can be defined as function call TraceLvl()
- // or as macro TRACE().
- //
- // Here the parameter 'lvl' can be used with more than one
- // debug-level (using OR).
- //
- // Example: DEBUG_TRACE1(DEBUG_LVL_30 | DEBUG_LVL_02, "Hello %d", bCount);
-
-#define DEBUG_TRACE0(lvl,str) TraceLvl((lvl),str)
-#define DEBUG_TRACE1(lvl,str,p1) TraceLvl((lvl),str,p1)
-#define DEBUG_TRACE2(lvl,str,p1,p2) TraceLvl((lvl),str,p1,p2)
-#define DEBUG_TRACE3(lvl,str,p1,p2,p3) TraceLvl((lvl),str,p1,p2,p3)
-#define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4) TraceLvl((lvl),str,p1,p2,p3,p4)
-#define DEBUG_GLB_LVL() dwDebugLevel_g
-
-#else
-
// At microcontrollers we do reduce the memory usage by deleting DEBUG_TRACE-lines
// (compiler does delete the lines).
//
@@ -643,25 +624,23 @@
#define DEBUG_TRACE3(lvl,str,p1,p2,p3) lvl##_TRACE3(str,p1,p2,p3)
#define DEBUG_TRACE4(lvl,str,p1,p2,p3,p4) lvl##_TRACE4(str,p1,p2,p3,p4)
-#endif
-
//---------------------------------------------------------------------------
// The macro DEBUG_DUMP_DATA() can be used with the same debug-levels to dump
// out data bytes. Function DumpData() has to be included.
// NOTE: DUMP_DATA has to be defined in project settings.
-#if (!defined (NDEBUG) && defined (DUMP_DATA)) || (DEV_SYSTEM == _DEV_WIN32_)
+#if (!defined (NDEBUG) && defined (DUMP_DATA))
#ifdef __cplusplus
extern "C" {
#endif
- void DumpData(char *szStr_p, BYTE MEM * pbData_p, WORD wSize_p);
+ void DumpData(char *szStr_p, u8 *pbData_p, u16 wSize_p);
#ifdef __cplusplus
} // von extern "C"
#endif
#define DEBUG_DUMP_DATA(lvl,str,ptr,siz) if ((DEBUG_GLB_LVL() & (lvl))==(lvl)) \
- DumpData (str, (BYTE MEM*) (ptr), (WORD) (siz));
+ DumpData (str, (u8 *)(ptr), (u16)(siz));
#else
#define DEBUG_DUMP_DATA(lvl,str,ptr,siz)
@@ -675,24 +654,6 @@ extern "C" {
// deleted from compiler (in release version too).
#if !defined (NDEBUG) || defined (DEBUG_KEEP_ASSERT)
-#if (DEV_SYSTEM == _DEV_WIN32_)
-
- // For WIN32 process will be killed after closing message box.
-
-#define DEBUG_ASSERT0(expr,str) if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
- MessageBox (NULL, \
- "Assertion failed: line " __LINE__ " file " __FILE__ \
- "\n -> " str "\n"); \
- ExitProcess (-1); }
-
-#define DEBUG_ASSERT1(expr,str,p1) if (!(expr ) && ((DEBUG_GLB_LVL() & DEBUG_LVL_ASSERT)!=0)) { \
- MessageBox (NULL, \
- "Assertion failed: line " __LINE__ " file " __FILE__ \
- "\n -> " str "\n"); \
- ExitProcess (-1); }
-
-#else
-
// For microcontrollers process will be stopped using endless loop.
#define DEBUG_ASSERT0(expr,str) if (!(expr )) { \
@@ -705,10 +666,9 @@ extern "C" {
DEBUG_LVL_ASSERT_TRACE4 ( \
"Assertion failed: line %d file '%s'\n" \
" -> '%s'\n" \
- " -> 0x%08lX\n", __LINE__, __FILE__, str, (DWORD) p1); \
+ " -> 0x%08lX\n", __LINE__, __FILE__, str, (u32) p1); \
while (1); }
-#endif
#else
diff --git a/drivers/staging/epl/Edrv8139.c b/drivers/staging/epl/Edrv8139.c
index 296354aaa9c..44e3f7b144b 100644
--- a/drivers/staging/epl/Edrv8139.c
+++ b/drivers/staging/epl/Edrv8139.c
@@ -81,7 +81,6 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -234,8 +233,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -282,9 +281,9 @@ typedef struct
typedef struct {
struct pci_dev *m_pPciDev; // pointer to PCI device structure
void *m_pIoAddr; // pointer to register space of Ethernet controller
- BYTE *m_pbRxBuf; // pointer to Rx buffer
+ u8 *m_pbRxBuf; // pointer to Rx buffer
dma_addr_t m_pRxBufDma;
- BYTE *m_pbTxBuf; // pointer to Tx buffer
+ u8 *m_pbTxBuf; // pointer to Tx buffer
dma_addr_t m_pTxBufDma;
BOOL m_afTxBufUsed[EDRV_MAX_TX_BUFFERS];
unsigned int m_uiCurTxDesc;
@@ -359,7 +358,7 @@ static struct pci_driver EdrvDriver = {
// local function prototypes
//---------------------------------------------------------------------------
-static BYTE EdrvCalcHash(BYTE * pbMAC_p);
+static u8 EdrvCalcHash(u8 * pbMAC_p);
//---------------------------------------------------------------------------
//
@@ -453,20 +452,20 @@ tEplKernel EdrvShutdown(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p)
+tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD dwData;
- BYTE bHash;
+ u32 dwData;
+ u8 bHash;
bHash = EdrvCalcHash(pbMacAddr_p);
/*
dwData = ether_crc(6, pbMacAddr_p);
printk("EdrvDefineRxMacAddrEntry('%02X:%02X:%02X:%02X:%02X:%02X') hash = %u / %u ether_crc = 0x%08lX\n",
- (WORD) pbMacAddr_p[0], (WORD) pbMacAddr_p[1], (WORD) pbMacAddr_p[2],
- (WORD) pbMacAddr_p[3], (WORD) pbMacAddr_p[4], (WORD) pbMacAddr_p[5],
- (WORD) bHash, (WORD) (dwData >> 26), dwData);
+ (u16) pbMacAddr_p[0], (u16) pbMacAddr_p[1], (u16) pbMacAddr_p[2],
+ (u16) pbMacAddr_p[3], (u16) pbMacAddr_p[4], (u16) pbMacAddr_p[5],
+ (u16) bHash, (u16) (dwData >> 26), dwData);
*/
if (bHash > 31) {
dwData = EDRV_REGDW_READ(EDRV_REGDW_MAR4);
@@ -494,11 +493,11 @@ tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p)
+tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD dwData;
- BYTE bHash;
+ u32 dwData;
+ u8 bHash;
bHash = EdrvCalcHash(pbMacAddr_p);
@@ -532,7 +531,7 @@ tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p)
tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD i;
+ u32 i;
if (pBuffer_p->m_uiMaxBufferLen > EDRV_MAX_FRAME_SIZE) {
Ret = kEplEdrvNoFreeBufEntry;
@@ -605,7 +604,7 @@ tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiBufferNumber;
- DWORD dwTemp;
+ u32 dwTemp;
uiBufferNumber = pBuffer_p->m_uiBufferNumber;
@@ -620,11 +619,11 @@ tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
dwTemp =
EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
(EdrvInstance_l.m_uiCurTxDesc *
- sizeof(DWORD))));
- printk("%s InvOp TSD%u = 0x%08lX", __func__,
+ sizeof(u32))));
+ printk("%s InvOp TSD%u = 0x%08X", __func__,
EdrvInstance_l.m_uiCurTxDesc, dwTemp);
printk(" Cmd = 0x%02X\n",
- (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
goto Exit;
}
// save pointer to buffer structure for TxHandler
@@ -640,22 +639,22 @@ tEplKernel EdrvSendTxMsg(tEdrvTxBuffer * pBuffer_p)
}
// set DMA address of buffer
EDRV_REGDW_WRITE((EDRV_REGDW_TSAD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))),
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
(EdrvInstance_l.m_pTxBufDma +
(uiBufferNumber * EDRV_MAX_FRAME_SIZE)));
dwTemp =
EDRV_REGDW_READ((EDRV_REGDW_TSAD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))));
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
// printk("%s TSAD%u = 0x%08lX", __func__, EdrvInstance_l.m_uiCurTxDesc, dwTemp);
// start transmission
EDRV_REGDW_WRITE((EDRV_REGDW_TSD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))),
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))),
(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
dwTemp =
EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
- (EdrvInstance_l.m_uiCurTxDesc * sizeof(DWORD))));
-// printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (DWORD)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
+ (EdrvInstance_l.m_uiCurTxDesc * sizeof(u32))));
+// printk(" TSD%u = 0x%08lX / 0x%08lX\n", EdrvInstance_l.m_uiCurTxDesc, dwTemp, (u32)(EDRV_REGDW_TSD_TXTH_DEF | pBuffer_p->m_uiTxMsgLen));
Exit:
return Ret;
@@ -720,7 +719,7 @@ tEplKernel EdrvTxMsgStart(tEdrvTxBuffer * pBuffer_p)
//---------------------------------------------------------------------------
static void EdrvReinitRx(void)
{
- BYTE bCmd;
+ u8 bCmd;
// simply switch off and on the receiver
// this will reset the CAPR register
@@ -751,21 +750,16 @@ void EdrvInterruptHandler(void)
}
#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p)
-#else
-static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
- struct pt_regs *ptRegs_p)
-#endif
{
// EdrvInterruptHandler();
tEdrvRxBuffer RxBuffer;
tEdrvTxBuffer *pTxBuffer;
- WORD wStatus;
- DWORD dwTxStatus;
- DWORD dwRxStatus;
- WORD wCurRx;
- BYTE *pbRxBuf;
+ u16 wStatus;
+ u32 dwTxStatus;
+ u32 dwRxStatus;
+ u16 wCurRx;
+ u8 *pbRxBuf;
unsigned int uiLength;
int iHandled = IRQ_HANDLED;
@@ -793,7 +787,7 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
dwTxStatus =
EDRV_REGDW_READ((EDRV_REGDW_TSD0 +
(EdrvInstance_l.m_uiCurTxDesc *
- sizeof(DWORD))));
+ sizeof(u32))));
if ((dwTxStatus & (EDRV_REGDW_TSD_TOK | EDRV_REGDW_TSD_TABT | EDRV_REGDW_TSD_TUN)) != 0) { // transmit finished
EdrvInstance_l.m_uiCurTxDesc =
(EdrvInstance_l.m_uiCurTxDesc + 1) & 0x03;
@@ -855,8 +849,8 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
// calculate pointer to current frame in receive buffer
pbRxBuf = EdrvInstance_l.m_pbRxBuf + wCurRx;
- // read receive status DWORD
- dwRxStatus = le32_to_cpu(*((DWORD *) pbRxBuf));
+ // read receive status u32
+ dwRxStatus = le32_to_cpu(*((u32 *) pbRxBuf));
// calculate length of received frame
uiLength = dwRxStatus >> 16;
@@ -896,9 +890,9 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
m_pfnRxHandler(&RxBuffer);
}
- // calulate new offset (DWORD aligned)
+ // calulate new offset (u32 aligned)
wCurRx =
- (WORD) ((wCurRx + uiLength + sizeof(dwRxStatus) +
+ (u16) ((wCurRx + uiLength + sizeof(dwRxStatus) +
3) & ~0x3);
EDRV_TRACE_CAPR(wCurRx - 0x10);
EDRV_REGW_WRITE(EDRV_REGW_CAPR, wCurRx - 0x10);
@@ -941,7 +935,7 @@ static int TgtEthIsr(int nIrqNum_p, void *ppDevInstData_p,
static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
{
int iResult = 0;
- DWORD dwTemp;
+ u32 dwTemp;
if (EdrvInstance_l.m_pPciDev != NULL) { // Edrv is already connected to a PCI device
printk("%s device %s discarded\n", __func__,
@@ -1008,7 +1002,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TCR);
if (((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_C)
&& ((dwTemp & EDRV_REGDW_TCR_VER_MASK) != EDRV_REGDW_TCR_VER_D)) { // unsupported chip
- printk("%s Unsupported chip! TCR = 0x%08lX\n", __func__,
+ printk("%s Unsupported chip! TCR = 0x%08X\n", __func__,
dwTemp);
iResult = -ENODEV;
goto Exit;
@@ -1043,11 +1037,11 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
printk("%s set local MAC address\n", __func__);
// write this MAC address to controller
EDRV_REGDW_WRITE(EDRV_REGDW_IDR0,
- le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
+ le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[0])));
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR0);
EDRV_REGDW_WRITE(EDRV_REGDW_IDR4,
- le32_to_cpu(*((DWORD*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
+ le32_to_cpu(*((u32*)&EdrvInstance_l.m_InitParam.m_abMyMacAddr[4])));
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_IDR4);
break;
}
@@ -1087,7 +1081,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
dwTemp = EDRV_REGDW_READ(EDRV_REGDW_TSAD3);
printk(" Command = 0x%02X\n",
- (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
// set pointer for receive buffer in controller
printk("%s set pointer to Rx buffer\n", __func__);
@@ -1098,7 +1092,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
EDRV_REGB_WRITE(EDRV_REGB_COMMAND,
(EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
printk(" Command = 0x%02X\n",
- (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
// clear missed packet counter to enable Rx/Tx process
EDRV_REGDW_WRITE(EDRV_REGDW_MPC, 0);
@@ -1123,7 +1117,7 @@ static int EdrvInitOne(struct pci_dev *pPciDev, const struct pci_device_id *pId)
// enable transmitter and receiver
printk("%s enable Tx and Rx", __func__);
EDRV_REGB_WRITE(EDRV_REGB_COMMAND, (EDRV_REGB_COMMAND_RE | EDRV_REGB_COMMAND_TE));
- printk(" Command = 0x%02X\n", (WORD) EDRV_REGB_READ(EDRV_REGB_COMMAND));
+ printk(" Command = 0x%02X\n", (u16) EDRV_REGB_READ(EDRV_REGB_COMMAND));
*/
// disable early interrupts
EDRV_REGW_WRITE(EDRV_REGW_MULINT, 0);
@@ -1215,15 +1209,15 @@ static void EdrvRemoveOne(struct pci_dev *pPciDev)
//#define CRC32_POLY 0xEDB88320 //
// G(x) = x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
-static BYTE EdrvCalcHash(BYTE * pbMAC_p)
+static u8 EdrvCalcHash(u8 * pbMAC_p)
{
- DWORD dwByteCounter;
- DWORD dwBitCounter;
- DWORD dwData;
- DWORD dwCrc;
- DWORD dwCarry;
- BYTE *pbData;
- BYTE bHash;
+ u32 dwByteCounter;
+ u32 dwBitCounter;
+ u32 dwData;
+ u32 dwCrc;
+ u32 dwCarry;
+ u8 *pbData;
+ u8 bHash;
pbData = pbMAC_p;
@@ -1246,7 +1240,7 @@ static BYTE EdrvCalcHash(BYTE * pbMAC_p)
// printk("MyCRC = 0x%08lX\n", dwCrc);
// only upper 6 bits (HASH_BITS) are used
// which point to specific bit in the hash registers
- bHash = (BYTE) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
+ bHash = (u8) ((dwCrc >> (32 - HASH_BITS)) & 0x3f);
return bHash;
}
diff --git a/drivers/staging/epl/EdrvFec.h b/drivers/staging/epl/EdrvFec.h
index 5f252fbed74..56728d1e95e 100644
--- a/drivers/staging/epl/EdrvFec.h
+++ b/drivers/staging/epl/EdrvFec.h
@@ -96,9 +96,9 @@
// Rx and Tx buffer descriptor format
typedef struct {
- WORD m_wStatus; // control / status --- used by edrv, do not change in application
- WORD m_wLength; // transfer length
- BYTE *m_pbData; // buffer address
+ u16 m_wStatus; // control / status --- used by edrv, do not change in application
+ u16 m_wLength; // transfer length
+ u8 *m_pbData; // buffer address
} tBufferDescr;
#if ((TARGET_HARDWARE & TGT_CPU_MASK_) == TGT_CPU_5282)
diff --git a/drivers/staging/epl/EdrvFec5282.h b/drivers/staging/epl/EdrvFec5282.h
deleted file mode 100644
index a16bb1d4da7..00000000000
--- a/drivers/staging/epl/EdrvFec5282.h
+++ /dev/null
@@ -1,340 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: interface for ethernetdriver
- "fast ethernet controller" (FEC)
- freescale coldfire MCF528x and compatible FEC
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EdrvFec5282.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- Dev C++ and GNU-Compiler for m68k
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2005/08/01 m.b.: start of implementation
-
-****************************************************************************/
-
-#ifndef _EDRVFEC_H_
-#define _EDRVFEC_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-// base addresses
-#define FEC0_ADDR 0x0000
-#define FEC1_ADDR 0x0000 //tbd
-
-// control / status registers
-#define FEC_EIR 0x1004 // interrupt event register
-#define FEC_EIMR 0x1008 // interrupt mask register
-#define FEC_RDAR 0x1010 // receive descriptor active register
-#define FEC_TDAR 0x1014 // transmit descriptor active register
-#define FEC_ECR 0x1024 // ethernet control register
-#define FEC_MMFR 0x1040 // MII data register
-#define FEC_MSCR 0x1044 // MII speed register
-#define FEC_MIBC 0x1064 // MIB control/status register
-#define FEC_RCR 0x1084 // receive control register
-#define FEC_TCR 0x10C4 // transmit control register
-#define FEC_PALR 0x10E4 // physical address low register
-#define FEC_PAUR 0x10E8 // physical address high + type register
-#define FEC_OPD 0x10EC // opcode + pause register
-#define FEC_IAUR 0x1118 // upper 32 bit of individual hash table
-#define FEC_IALR 0x111C // lower 32 bit of individual hash table
-#define FEC_GAUR 0x1120 // upper 32 bit of group hash table
-#define FEC_GALR 0x1124 // lower 32 bit of group hash table
-#define FEC_TFWR 0x1144 // transmit FIFO watermark
-#define FEC_FRBR 0x114C // FIFO receive bound register
-#define FEC_FRSR 0x1150 // FIFO receive FIFO start register
-#define FEC_ERDSR 0x1180 // pointer to receive descriptor ring
-#define FEC_ETDSR 0x1184 // pointer to transmit descriptor ring
-#define FEC_EMRBR 0x1188 // maximum receive buffer size
-
-// mib block counters memory map
-#define FEC_RMON_T_DROP 0x1200 // count of frames not counted correctly
-#define FEC_RMON_T_PACKETS 0x1204 // RMON tx packet count
-#define FEC_RMON_T_BC_PKT 0x1208 // RMON tx broadcast packets
-#define FEC_RMON_T_MC_PKT 0x120C // RMON tx multicast packets
-#define FEC_RMON_T_CRC_ALIGN 0x1210 // RMON tx packets w CRC/align error
-#define FEC_RMON_T_UNDERSIZE 0x1214 // RMON tx packets < 64 bytes, good CRC
-#define FEC_RMON_T_OVERSIZE 0x1218 // RMON tx packets > MAX_FL bytes, good CRC
-#define FEC_RMON_T_FRAG 0x121C // RMON tx packets < 64 bytes, bad CRC
-#define FEC_RMON_T_JAB 0x1220 // RMON tx packets > MAX_FL bytes, bad CRC
-#define FEC_RMON_T_COL 0x1224 // RMON tx collision count
-#define FEC_RMON_T_P64 0x1228 // RMON tx 64 byte packets
-#define FEC_RMON_T_P65TO127 0x122C // RMON tx 65 to 127 byte packets
-#define FEC_RMON_T_P128TO255 0x1230 // RMON tx 128 to 255 byte packets
-#define FEC_RMON_T_P256TO511 0x1234 // RMON tx 256 to 511 byte packets
-#define FEC_RMON_T_P512TO1023 0x1238 // RMON tx 512 to 1023 byte packets
-#define FEC_RMON_T_P1024TO2047 0x123C // RMON tx 1024 to 2047 byte packets
-#define FEC_RMON_T_P_GTE2048 0x1240 // RMON tx w > 2048 bytes
-#define FEC_RMON_T_OCTETS 0x1244 // RMON tx octets
-#define FEC_IEEE_T_DROP 0x1248 // count of frames not counted correctly
-#define FEC_IEEE_T_FRAME_OK 0x124C // frames transmitted OK
-#define FEC_IEEE_T_1COL 0x1250 // frames transmitted with single collision
-#define FEC_IEEE_T_MCOL 0x1254 // frames transmitted with multiple collisions
-#define FEC_IEEE_T_DEF 0x1258 // frames transmitted after deferral delay
-#define FEC_IEEE_T_LCOL 0x125C // frames transmitted with late collisions
-#define FEC_IEEE_T_EXCOL 0x1260 // frames transmitted with excessive collisions
-#define FEC_IEEE_T_MACERR 0x1264 // frames transmitted with tx-FIFO underrun
-#define FEC_IEEE_T_CSERR 0x1268 // frames transmitted with carrier sense error
-#define FEC_IEEE_T_SQE 0x126C // frames transmitted with SQE error
-#define FEC_IEEE_T_FDXFC 0x1270 // flow control pause frames transmitted
-#define FEC_IEEE_T_OCTETS_OK 0x1274 // octet count for frames transmitted w/o error
-#define FEC_RMON_R_PACKETS 0x1284 // RMON rx packet count
-#define FEC_RMON_R_BC_PKT 0x1288 // RMON rx broadcast packets
-#define FEC_RMON_R_MC_PKT 0x128C // RMON rx multicast packets
-#define FEC_RMON_R_CRC_ALIGN 0x1290 // RMON rx packets w CRC/align error
-#define FEC_RMON_R_UNDERSIZE 0x1294 // RMON rx packets < 64 bytes, good CRC
-#define FEC_RMON_R_OVERSIZE 0x1298 // RMON rx packets > MAX_FL bytes, good CRC
-#define FEC_RMON_R_FRAG 0x129C // RMON rx packets < 64 bytes, bad CRC
-#define FEC_RMON_R_JAB 0x12A0 // RMON rx packets > MAX_FL bytes, bad CRC
-#define FEC_RMON_R_RESVD_0 0x12A4 //
-#define FEC_RMON_R_P64 0x12A8 // RMON rx 64 byte packets
-#define FEC_RMON_R_P65T0127 0x12AC // RMON rx 65 to 127 byte packets
-#define FEC_RMON_R_P128TO255 0x12B0 // RMON rx 128 to 255 byte packets
-#define FEC_RMON_R_P256TO511 0x12B4 // RMON rx 256 to 511 byte packets
-#define FEC_RMON_R_P512TO1023 0x12B8 // RMON rx 512 to 1023 byte packets
-#define FEC_RMON_R_P1024TO2047 0x12BC // RMON rx 1024 to 2047 byte packets
-#define FEC_RMON_R_GTE2048 0x12C0 // RMON rx w > 2048 bytes
-#define FEC_RMON_R_OCTETS 0x12C4 // RMON rx octets
-#define FEC_IEEE_R_DROP 0x12C8 // count of frames not counted correctly
-#define FEC_IEEE_R_FRAME_OK 0x12CC // frames received OK
-#define FEC_IEEE_R_CRC 0x12D0 // frames received with CRC error
-#define FEC_IEEE_R_ALIGN 0x12D4 // frames received with alignment error
-#define FEC_IEEE_R_MACERR 0x12D8 // receive FIFO overflow count
-#define FEC_IEEE_R_FDXFC 0x12DC // flow control pause frames received
-#define FEC_IEEE_R_OCTETS_OK 0x12E0 // octet count for frames rcvd w/o error
-
-// register bit definitions and macros
-#define FEC_EIR_UN (0x00080000)
-#define FEC_EIR_RL (0x00100000)
-#define FEC_EIR_LC (0x00200000)
-#define FEC_EIR_EBERR (0x00400000)
-#define FEC_EIR_MII (0x00800000)
-#define FEC_EIR_RXB (0x01000000)
-#define FEC_EIR_RXF (0x02000000)
-#define FEC_EIR_TXB (0x04000000)
-#define FEC_EIR_TXF (0x08000000)
-#define FEC_EIR_GRA (0x10000000)
-#define FEC_EIR_BABT (0x20000000)
-#define FEC_EIR_BABR (0x40000000)
-#define FEC_EIR_HBERR (0x80000000)
-
-#define FEC_EIMR_UN (0x00080000)
-#define FEC_EIMR_RL (0x00100000)
-#define FEC_EIMR_LC (0x00200000)
-#define FEC_EIMR_EBERR (0x00400000)
-#define FEC_EIMR_MII (0x00800000)
-#define FEC_EIMR_RXB (0x01000000)
-#define FEC_EIMR_RXF (0x02000000)
-#define FEC_EIMR_TXB (0x04000000)
-#define FEC_EIMR_TXF (0x08000000)
-#define FEC_EIMR_GRA (0x10000000)
-#define FEC_EIMR_BABT (0x20000000)
-#define FEC_EIMR_BABR (0x40000000)
-#define FEC_EIMR_HBERR (0x80000000)
-
-#define FEC_RDAR_R_DES_ACTIVE (0x01000000)
-
-#define FEC_TDAR_X_DES_ACTIVE (0x01000000)
-
-#define FEC_ECR_RESET (0x00000001)
-#define FEC_ECR_ETHER_EN (0x00000002)
-
-#define FEC_MMFR_DATA(x) (((x) & 0xFFFF))
-#define FEC_MMFR_TA (0x00020000)
-#define FEC_MMFR_RA(x) (((x) & 0x1F) << 18)
-#define FEC_MMFR_PA(x) (((x) & 0x1F) << 23)
-#define FEC_MMFR_OP_WR (0x10000000)
-#define FEC_MMFR_OP_RD (0x20000000)
-#define FEC_MMFR_ST (0x40000000)
-
-#define FEC_MSCR_MII_SPEED(x) (((x) & 0x1F) << 1)
-#define FEC_MSCR_DIS_PREAMBLE (0x00000008)
-
-#define FEC_MIBC_MIB_IDLE (0x40000000)
-#define FEC_MIBC_MIB_DISABLE (0x80000000)
-
-#define FEC_RCR_LOOP (0x00000001)
-#define FEC_RCR_DRT (0x00000002)
-#define FEC_RCR_MII_MODE (0x00000004)
-#define FEC_RCR_PROM (0x00000008)
-#define FEC_RCR_BC_REJ (0x00000010)
-#define FEC_RCR_FCE (0x00000020)
-#define FEC_RCR_MAX_FL(x) (((x) & 0x07FF) << 16)
-
-#define FEC_TCR_GTS (0x00000001)
-#define FEC_TCR_HBC (0x00000002)
-#define FEC_TCR_FDEN (0x00000004)
-#define FEC_TCR_TFC_PAUSE (0x00000008)
-#define FEC_TCR_RFC_PAUSE (0x00000010)
-
-#define FEC_PALR_BYTE3(x) (((x) & 0xFF) << 0)
-#define FEC_PALR_BYTE2(x) (((x) & 0xFF) << 8)
-#define FEC_PALR_BYTE1(x) (((x) & 0xFF) << 16)
-#define FEC_PALR_BYTE0(x) (((x) & 0xFF) << 24)
-
-//#define FEC_PAUR_TYPE(x) (((x) & 0xFFFF) << 0)
-#define FEC_PAUR_BYTE5(x) (((x) & 0xFF) << 16)
-#define FEC_PAUR_BYTE4(x) (((x) & 0xFF) << 24)
-
-#define FEC_OPD_PAUSE_DUR(x) (((x) & 0xFFFF))
-//#define FEC_OPD_OPCODE(x) (((x) & 0xFFFF) << 16)
-
-//m.b.
-#define FEC_IAUR_BYTE7(x) (((x) & 0xFF) << 0)
-#define FEC_IAUR_BYTE6(x) (((x) & 0xFF) << 8)
-#define FEC_IAUR_BYTE5(x) (((x) & 0xFF) << 16)
-#define FEC_IAUR_BYTE4(x) (((x) & 0xFF) << 24)
-
-#define FEC_IALR_BYTE3(x) (((x) & 0xFF) << 0)
-#define FEC_IALR_BYTE2(x) (((x) & 0xFF) << 8)
-#define FEC_IALR_BYTE1(x) (((x) & 0xFF) << 16)
-#define FEC_IALR_BYTE0(x) (((x) & 0xFF) << 24)
-
-#define FEC_GAUR_BYTE7(x) (((x) & 0xFF) << 0)
-#define FEC_GAUR_BYTE6(x) (((x) & 0xFF) << 8)
-#define FEC_GAUR_BYTE5(x) (((x) & 0xFF) << 16)
-#define FEC_GAUR_BYTE4(x) (((x) & 0xFF) << 24)
-
-#define FEC_GALR_BYTE3(x) (((x) & 0xFF) << 0)
-#define FEC_GALR_BYTE2(x) (((x) & 0xFF) << 8)
-#define FEC_GALR_BYTE1(x) (((x) & 0xFF) << 16)
-#define FEC_GALR_BYTE0(x) (((x) & 0xFF) << 24)
-// ^^^^
-
-#define FEC_TFWR_X_WMRK_64 (0x00000001)
-#define FEC_TFWR_X_WMRK_128 (0x00000002)
-#define FEC_TFWR_X_WMRK_192 (0x00000003)
-
-//m.b.
-#define FEC_FRBR_R_BOUND(x) (((x) & 0xFF) << 2)
-
-//m.b.
-#define FEC_FRSR_R_FSTART(x) (((x) & 0xFF) << 2)
-
-//m.b.
-#define FEC_ERDSR_R_DES_START(x) (((x) & 0x3FFFFFFF) << 2)
-
-//m.b.
-#define FEC_ETSDR_X_DES_START(x) (((x) & 0x3FFFFFFF) << 2)
-
-#define FEC_EMRBR_R_BUF_SIZE(x) (((x) & 0x7F) << 4)
-
-#define FEC_RxBD_TR 0x0001
-#define FEC_RxBD_OV 0x0002
-#define FEC_RxBD_CR 0x0004
-#define FEC_RxBD_NO 0x0010
-#define FEC_RxBD_LG 0x0020
-#define FEC_RxBD_MC 0x0040
-#define FEC_RxBD_BC 0x0080
-#define FEC_RxBD_M 0x0100
-#define FEC_RxBD_L 0x0800
-#define FEC_RxBD_R02 0x1000
-#define FEC_RxBD_W 0x2000
-#define FEC_RxBD_R01 0x4000
-#define FEC_RxBD_INUSE 0x4000
-#define FEC_RxBD_E 0x8000
-
-//m.b.
-//#define FEC_TxBD_CSL 0x0001
-//#define FEC_TxBD_UN 0x0002
-//#define FEC_TxBD_RL 0x0040
-//#define FEC_TxBD_LC 0x0080
-//#define FEC_TxBD_HB 0x0100
-//#define FEC_TxBD_DEF 0x0200
-#define FEC_TxBD_ABC 0x0200
-// ^^^^
-#define FEC_TxBD_TC 0x0400
-#define FEC_TxBD_L 0x0800
-#define FEC_TxBD_TO2 0x1000
-#define FEC_TxBD_W 0x2000
-#define FEC_TxBD_TO1 0x4000
-#define FEC_TxBD_INUSE 0x4000
-#define FEC_TxBD_R 0x8000
-
-//---------------------------------------------------------------------------
-// types
-//---------------------------------------------------------------------------
-
-// Rx and Tx buffer descriptor format
-typedef struct {
- WORD m_wStatus; // control / status --- used by edrv, do not change in application
- WORD m_wLength; // transfer length
- BYTE *m_pbData; // buffer address
-} tBufferDescr;
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#if (NO_OF_INSTANCES > 1)
-#define ECI_WRITE_DW_REG(off,val) (*(DWORD *)(void *)(&__IPSBAR[off]) = val)
-#define ECI_READ_DW_REG(off) (*(DWORD *)(void *)(&__IPSBAR[off]))
-#else
-#if (EDRV_USED_ETH_CTRL == 0)
-#define ECI_WRITE_DW_REG(off,val) (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]) = val)
-#define ECI_READ_DW_REG(off) (*(DWORD *)(void *)(&__IPSBAR[FEC0_ADDR+off]))
-#else
-#define ECI_WRITE_DW_REG(off,val) (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]) = val)
-#define ECI_READ_DW_REG(off) (*(DWORD *)(void *)(&__IPSBAR[FEC1_ADDR+off]))
-#endif
-#endif
-
-#endif // #ifndef _EDRV_FEC_H_
diff --git a/drivers/staging/epl/EdrvSim.h b/drivers/staging/epl/EdrvSim.h
index 39300e321d6..191ec1457d2 100644
--- a/drivers/staging/epl/EdrvSim.h
+++ b/drivers/staging/epl/EdrvSim.h
@@ -83,7 +83,7 @@
// function prototypes
//---------------------------------------------------------------------------
-void EdrvRxInterruptHandler(BYTE bBufferInFrame_p, BYTE * pbEthernetData_p,
- WORD wDataLen_p);
+void EdrvRxInterruptHandler(u8 bBufferInFrame_p, u8 * pbEthernetData_p,
+ u16 wDataLen_p);
#endif // #ifndef _EDRVSIM_H_
diff --git a/drivers/staging/epl/Epl.h b/drivers/staging/epl/Epl.h
index be60f771b63..7f22b04022b 100644
--- a/drivers/staging/epl/Epl.h
+++ b/drivers/staging/epl/Epl.h
@@ -89,7 +89,7 @@ typedef struct {
unsigned int m_uiNodeId;
tEplNmtState m_NmtState;
tEplNmtNodeEvent m_NodeEvent;
- WORD m_wErrorCode; // EPL error code if m_NodeEvent == kEplNmtNodeEventError
+ u16 m_wErrorCode; // EPL error code if m_NodeEvent == kEplNmtNodeEventError
BOOL m_fMandatory;
} tEplApiEventNode;
@@ -97,7 +97,7 @@ typedef struct {
typedef struct {
tEplNmtState m_NmtState; // local NMT state
tEplNmtBootEvent m_BootEvent;
- WORD m_wErrorCode; // EPL error code if m_BootEvent == kEplNmtBootEventError
+ u16 m_wErrorCode; // EPL error code if m_BootEvent == kEplNmtBootEventError
} tEplApiEventBoot;
@@ -131,33 +131,33 @@ typedef union {
} tEplApiEventArg;
-typedef tEplKernel(PUBLIC ROM * tEplApiCbEvent) (tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p);
+typedef tEplKernel(*tEplApiCbEvent) (tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p);
typedef struct {
unsigned int m_uiSizeOfStruct;
BOOL m_fAsyncOnly; // do not need to register PRes
unsigned int m_uiNodeId; // local node ID
- BYTE m_abMacAddress[6]; // local MAC address
+ u8 m_abMacAddress[6]; // local MAC address
// 0x1F82: NMT_FeatureFlags_U32
- DWORD m_dwFeatureFlags;
+ u32 m_dwFeatureFlags;
// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
- DWORD m_dwCycleLen; // required for error detection
+ u32 m_dwCycleLen; // required for error detection
// 0x1F98: NMT_CycleTiming_REC
// 0x1F98.1: IsochrTxMaxPayload_U16
unsigned int m_uiIsochrTxMaxPayload; // const
// 0x1F98.2: IsochrRxMaxPayload_U16
unsigned int m_uiIsochrRxMaxPayload; // const
// 0x1F98.3: PResMaxLatency_U32
- DWORD m_dwPresMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwPresMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.4: PReqActPayloadLimit_U16
unsigned int m_uiPreqActPayloadLimit; // required for initialisation (+28 bytes)
// 0x1F98.5: PResActPayloadLimit_U16
unsigned int m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+28 bytes)
// 0x1F98.6: ASndMaxLatency_U32
- DWORD m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.7: MultiplCycleCnt_U8
unsigned int m_uiMultiplCycleCnt; // required for error detection
// 0x1F98.8: AsyncMTU_U16
@@ -167,30 +167,30 @@ typedef struct {
// $$$ Multiplexed Slot
// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
- DWORD m_dwLossOfFrameTolerance;
+ u32 m_dwLossOfFrameTolerance;
// 0x1F8A: NMT_MNCycleTiming_REC
// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
- DWORD m_dwWaitSocPreq;
+ u32 m_dwWaitSocPreq;
// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
- DWORD m_dwAsyncSlotTimeout;
-
- DWORD m_dwDeviceType; // NMT_DeviceType_U32
- DWORD m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
- DWORD m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
- DWORD m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
- DWORD m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
- QWORD m_qwVendorSpecificExt1;
- DWORD m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
- DWORD m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
- DWORD m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwIpAddress;
- DWORD m_dwSubnetMask;
- DWORD m_dwDefaultGateway;
- BYTE m_sHostname[32];
- BYTE m_abVendorSpecificExt2[48];
+ u32 m_dwAsyncSlotTimeout;
+
+ u32 m_dwDeviceType; // NMT_DeviceType_U32
+ u32 m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
+ u32 m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
+ u32 m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
+ u32 m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
+ u64 m_qwVendorSpecificExt1;
+ u32 m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+ u32 m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+ u32 m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwIpAddress;
+ u32 m_dwSubnetMask;
+ u32 m_dwDefaultGateway;
+ u8 m_sHostname[32];
+ u8 m_abVendorSpecificExt2[48];
char *m_pszDevName; // NMT_ManufactDevName_VS (0x1008/0 local OD)
char *m_pszHwVersion; // NMT_ManufactHwVers_VS (0x1009/0 local OD)
@@ -212,62 +212,61 @@ typedef struct {
// function prototypes
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p);
+tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p);
-tEplKernel PUBLIC EplApiShutdown(void);
+tEplKernel EplApiShutdown(void);
-tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_le_p,
- unsigned int *puiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p);
+tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_le_p,
+ unsigned int *puiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p);
-tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_le_p,
- unsigned int uiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p);
+tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_le_p,
+ unsigned int uiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p);
-tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p);
+tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p);
-tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_p,
- unsigned int *puiSize_p);
+tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_p,
+ unsigned int *puiSize_p);
-tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_p,
- unsigned int uiSize_p);
+tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_p,
+ unsigned int uiSize_p);
-tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p);
+tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p);
-tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
- void *pVar_p,
- unsigned int *puiVarEntries_p,
- tEplObdSize * pEntrySize_p,
- unsigned int uiFirstSubindex_p);
+tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
+ void *pVar_p,
+ unsigned int *puiVarEntries_p,
+ tEplObdSize *pEntrySize_p,
+ unsigned int uiFirstSubindex_p);
-tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
+tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p);
-tEplKernel PUBLIC EplApiProcess(void);
+tEplKernel EplApiProcess(void);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
- tEplNmtNodeCommand NodeCommand_p);
+tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+ tEplNmtNodeCommand NodeCommand_p);
#endif
-tEplKernel PUBLIC EplApiGetIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse **
- ppIdentResponse_p);
+tEplKernel EplApiGetIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse **ppIdentResponse_p);
// functions for process image will be implemented in separate file
-tEplKernel PUBLIC EplApiProcessImageSetup(void);
-tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p);
-tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage * pPI_p);
+tEplKernel EplApiProcessImageSetup(void);
+tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p);
+tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p);
#endif // #ifndef _EPL_API_H_
diff --git a/drivers/staging/epl/EplAmi.h b/drivers/staging/epl/EplAmi.h
index 6fa04a4f0a1..3b46ea11442 100644
--- a/drivers/staging/epl/EplAmi.h
+++ b/drivers/staging/epl/EplAmi.h
@@ -69,7 +69,7 @@
16.09.2002 -as
To save code space the functions AmiSetByte and AmiGetByte
- are replaced by macros. For targets which assign BYTE by
+ are replaced by macros. For targets which assign u8 by
an 16Bit type, the definition of macros must changed to
functions.
@@ -86,11 +86,6 @@
#ifndef _EPLAMI_H_
#define _EPLAMI_H_
-#if ((DEV_SYSTEM & _DEV_64BIT_SUPPORT_) == 0)
-// #ifdef USE_VAR64
-#error 'ERROR: development system does not support 64 bit operations!'
-// #endif
-#endif
//---------------------------------------------------------------------------
// types
@@ -104,44 +99,21 @@
extern "C" {
#endif
-#if (TARGET_SYSTEM == _WIN32_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define INLINE_ENABLED TRUE
-#define EPL_AMI_INLINED
-#include "../EplStack/amix86.c"
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-#if defined(__m68k__) // it is an big endian machine
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define INLINE_ENABLED TRUE
-#define EPL_AMI_INLINED
-#include "../EplStack/amibe.c"
-#endif
-#endif
-#endif
-
//---------------------------------------------------------------------------
//
// write functions
//
// To save code space the function AmiSetByte is replaced by
// an macro.
-// void PUBLIC AmiSetByte (void FAR* pAddr_p, BYTE bByteVal_p);
+// void AmiSetByte (void * pAddr_p, u8 bByteVal_p);
-#define AmiSetByteToBe(pAddr_p, bByteVal_p) {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
-#define AmiSetByteToLe(pAddr_p, bByteVal_p) {*(BYTE FAR*)(pAddr_p) = (bByteVal_p);}
+#define AmiSetByteToBe(pAddr_p, bByteVal_p) {*(u8 *)(pAddr_p) = (bByteVal_p);}
+#define AmiSetByteToLe(pAddr_p, bByteVal_p) {*(u8 *)(pAddr_p) = (bByteVal_p);}
-#if !defined(INLINE_ENABLED)
- void PUBLIC AmiSetWordToBe(void FAR * pAddr_p, WORD wWordVal_p);
- void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p, DWORD dwDwordVal_p);
- void PUBLIC AmiSetWordToLe(void FAR * pAddr_p, WORD wWordVal_p);
- void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p, DWORD dwDwordVal_p);
-#endif
+void AmiSetWordToBe(void *pAddr_p, u16 wWordVal_p);
+void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p);
+void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p);
+void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p);
//---------------------------------------------------------------------------
//
@@ -149,17 +121,15 @@ extern "C" {
//
// To save code space the function AmiGetByte is replaced by
// an macro.
-// BYTE PUBLIC AmiGetByte (void FAR* pAddr_p);
-
-#define AmiGetByteFromBe(pAddr_p) (*(BYTE FAR*)(pAddr_p))
-#define AmiGetByteFromLe(pAddr_p) (*(BYTE FAR*)(pAddr_p))
+// u8 AmiGetByte (void * pAddr_p);
-#if !defined(INLINE_ENABLED)
+#define AmiGetByteFromBe(pAddr_p) (*(u8 *)(pAddr_p))
+#define AmiGetByteFromLe(pAddr_p) (*(u8 *)(pAddr_p))
- WORD PUBLIC AmiGetWordFromBe(void FAR * pAddr_p);
- DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p);
- WORD PUBLIC AmiGetWordFromLe(void FAR * pAddr_p);
- DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p);
+u16 AmiGetWordFromBe(void *pAddr_p);
+u32 AmiGetDwordFromBe(void *pAddr_p);
+u16 AmiGetWordFromLe(void *pAddr_p);
+u32 AmiGetDwordFromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -174,8 +144,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p, DWORD dwDwordVal_p);
- void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p, DWORD dwDwordVal_p);
+void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p);
+void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p);
//---------------------------------------------------------------------------
//
@@ -185,12 +155,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: DWORD = read value
+// Return: u32 = read value
//
//---------------------------------------------------------------------------
- DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p);
- DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p);
+u32 AmiGetDword24FromBe(void *pAddr_p);
+u32 AmiGetDword24FromLe(void *pAddr_p);
//#ifdef USE_VAR64
@@ -207,8 +177,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -218,12 +188,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p);
+u64 AmiGetQword40FromBe(void *pAddr_p);
+u64 AmiGetQword40FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -238,8 +208,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -249,12 +219,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p);
+u64 AmiGetQword48FromBe(void *pAddr_p);
+u64 AmiGetQword48FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -269,8 +239,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -280,12 +250,12 @@ extern "C" {
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p);
+u64 AmiGetQword56FromBe(void *pAddr_p);
+u64 AmiGetQword56FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -300,8 +270,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p, QWORD qwQwordVal_p);
- void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p, QWORD qwQwordVal_p);
+void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p);
+void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p);
//---------------------------------------------------------------------------
//
@@ -315,8 +285,8 @@ extern "C" {
//
//---------------------------------------------------------------------------
- QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p);
- QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p);
+u64 AmiGetQword64FromBe(void *pAddr_p);
+u64 AmiGetQword64FromLe(void *pAddr_p);
//---------------------------------------------------------------------------
//
@@ -330,9 +300,7 @@ extern "C" {
// Return: void
//
//---------------------------------------------------------------------------
-
- void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p);
+void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
//---------------------------------------------------------------------------
//
@@ -346,14 +314,7 @@ extern "C" {
// Return: void
//
//---------------------------------------------------------------------------
-
- void PUBLIC AmiGetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p);
-
-#endif
-
-#undef INLINE_ENABLED // disable actual inlining of functions
-#define EPL_AMI_INCLUDED
+void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p);
#ifdef __cplusplus
}
diff --git a/drivers/staging/epl/EplApiGeneric.c b/drivers/staging/epl/EplApiGeneric.c
index ae19e34cd7b..c4419569183 100644
--- a/drivers/staging/epl/EplApiGeneric.c
+++ b/drivers/staging/epl/EplApiGeneric.c
@@ -162,44 +162,41 @@ static tEplApiInstance EplApiInstance_g;
//---------------------------------------------------------------------------
// NMT state change event callback function
-static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p);
+static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
// update DLL configuration from OD
-static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
+static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
// update OD from init param
-static tEplKernel PUBLIC EplApiUpdateObd(void);
+static tEplKernel EplApiUpdateObd(void);
// process events from user event queue
-static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p);
+static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
// callback function of SDO module
-static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p);
+static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p);
#endif
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
// callback functions of NmtMnu module
-static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
- tEplNmtNodeEvent NodeEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p,
- BOOL fMandatory_p);
-
-static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p);
+static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
+ tEplNmtNodeEvent NodeEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p, BOOL fMandatory_p);
+
+static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p);
#endif
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
// callback function of Ledu module
-static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
- BOOL fOn_p);
+static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p);
#endif
// OD initialization function (implemented in Objdict.c)
-tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
//=========================================================================//
// //
@@ -226,7 +223,7 @@ tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
+tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdInitParam ObdInitParam;
@@ -415,7 +412,7 @@ tEplKernel PUBLIC EplApiInitialize(tEplApiInitParam * pInitParam_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiShutdown(void)
+tEplKernel EplApiShutdown(void)
{
tEplKernel Ret = kEplSuccessful;
@@ -523,7 +520,7 @@ tEplKernel PUBLIC EplApiShutdown(void)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
+tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -553,15 +550,15 @@ tEplKernel PUBLIC EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
- void *pVar_p,
- unsigned int *puiVarEntries_p,
- tEplObdSize * pEntrySize_p,
- unsigned int uiFirstSubindex_p)
+tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
+ void *pVar_p,
+ unsigned int *puiVarEntries_p,
+ tEplObdSize *pEntrySize_p,
+ unsigned int uiFirstSubindex_p)
{
- BYTE bVarEntries;
- BYTE bIndexEntries;
- BYTE MEM *pbData;
+ u8 bVarEntries;
+ u8 bIndexEntries;
+ u8 *pbData;
unsigned int uiSubindex;
tEplVarParam VarParam;
tEplObdSize EntrySize;
@@ -577,8 +574,8 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
goto Exit;
}
- pbData = (BYTE MEM *) pVar_p;
- bVarEntries = (BYTE) * puiVarEntries_p;
+ pbData = (u8 *)pVar_p;
+ bVarEntries = (u8) * puiVarEntries_p;
UsedSize = 0;
// init VarParam structure with default values
@@ -591,7 +588,7 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
EntrySize = (tEplObdSize) sizeof(bIndexEntries);
RetCode = EplObdReadEntry(uiObjIndex_p,
0x00,
- (void GENERIC *)&bIndexEntries,
+ (void *)&bIndexEntries,
&EntrySize);
if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
@@ -610,7 +607,7 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
// object actually has.
if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
(bVarEntries != 0x00)) {
- bIndexEntries = (BYTE) (bVarEntries + uiFirstSubindex_p - 1);
+ bIndexEntries = (u8) (bVarEntries + uiFirstSubindex_p - 1);
}
// map entries
for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
@@ -677,13 +674,13 @@ tEplKernel PUBLIC EplApiLinkObject(unsigned int uiObjIndex_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_le_p,
- unsigned int *puiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p)
+tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_le_p,
+ unsigned int *puiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -765,13 +762,13 @@ tEplKernel PUBLIC EplApiReadObject(tEplSdoComConHdl * pSdoComConHdl_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiNodeId_p,
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_le_p,
- unsigned int uiSize_p,
- tEplSdoType SdoType_p, void *pUserArg_p)
+tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiNodeId_p,
+ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_le_p,
+ unsigned int uiSize_p,
+ tEplSdoType SdoType_p, void *pUserArg_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -850,7 +847,7 @@ tEplKernel PUBLIC EplApiWriteObject(tEplSdoComConHdl * pSdoComConHdl_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
+tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -881,10 +878,9 @@ tEplKernel PUBLIC EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pDstData_p,
- unsigned int *puiSize_p)
+tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pDstData_p, unsigned int *puiSize_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdSize ObdSize;
@@ -911,10 +907,10 @@ tEplKernel PUBLIC EplApiReadLocalObject(unsigned int uiIndex_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- void *pSrcData_p,
- unsigned int uiSize_p)
+tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ void *pSrcData_p,
+ unsigned int uiSize_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -939,8 +935,8 @@ tEplKernel PUBLIC EplApiWriteLocalObject(unsigned int uiIndex_p,
//
// ----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
- tEplNmtNodeCommand NodeCommand_p)
+tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
+ tEplNmtNodeCommand NodeCommand_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -966,7 +962,7 @@ tEplKernel PUBLIC EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
+tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1001,8 +997,8 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
{
if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
&& (pParam_p->m_uiSubIndex == 3)
- && (*((DWORD *) pParam_p->m_pArg) != 0)) {
- DWORD dwVerifyConfInvalid = 0;
+ && (*((u32 *) pParam_p->m_pArg) != 0)) {
+ u32 dwVerifyConfInvalid = 0;
// set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
Ret =
EplObdWriteEntry(0x1020, 4,
@@ -1016,9 +1012,9 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
case 0x1F9E: // NMT_ResetCmd_U8
{
if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
- BYTE bNmtCommand;
+ u8 bNmtCommand;
- bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+ bNmtCommand = *((u8 *) pParam_p->m_pArg);
// check value range
switch ((tEplNmtCommand) bNmtCommand) {
case kEplNmtCmdResetNode:
@@ -1036,9 +1032,9 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
break;
}
} else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
- BYTE bNmtCommand;
+ u8 bNmtCommand;
- bNmtCommand = *((BYTE *) pParam_p->m_pArg);
+ bNmtCommand = *((u8 *) pParam_p->m_pArg);
// check value range
switch ((tEplNmtCommand) bNmtCommand) {
case kEplNmtCmdResetNode:
@@ -1115,7 +1111,7 @@ tEplKernel PUBLIC EplApiCbObdAccess(tEplObdCbParam MEM * pParam_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p)
+static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p)
{
tEplKernel Ret;
tEplEventError *pEventError;
@@ -1188,15 +1184,14 @@ static tEplKernel PUBLIC EplApiProcessEvent(tEplEvent * pEplEvent_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p)
+static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
{
tEplKernel Ret = kEplSuccessful;
- BYTE bNmtState;
+ u8 bNmtState;
tEplApiEventArg EventArg;
// save NMT state in OD
- bNmtState = (BYTE) NmtStateChange_p.m_NewNmtState;
+ bNmtState = (u8) NmtStateChange_p.m_NewNmtState;
Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
if (Ret != kEplSuccessful) {
goto Exit;
@@ -1275,7 +1270,7 @@ static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
case kEplNmtCsNotActive:
{
// indicate completion of reset in NMT_ResetCmd_U8
- bNmtState = (BYTE) kEplNmtCmdInvalidService;
+ bNmtState = (u8) kEplNmtCmdInvalidService;
Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
if (Ret != kEplSuccessful) {
goto Exit;
@@ -1411,14 +1406,14 @@ static tEplKernel PUBLIC EplApiCbNmtStateChange(tEplEventNmtStateChange
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
+static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
{
tEplKernel Ret = kEplSuccessful;
tEplDllConfigParam DllConfigParam;
tEplDllIdentParam DllIdentParam;
tEplObdSize ObdSize;
- WORD wTemp;
- BYTE bTemp;
+ u16 wTemp;
+ u8 bTemp;
// configure Dll
EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
@@ -1634,11 +1629,11 @@ static tEplKernel PUBLIC EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiUpdateObd(void)
+static tEplKernel EplApiUpdateObd(void)
{
tEplKernel Ret = kEplSuccessful;
- WORD wTemp;
- BYTE bTemp;
+ u16 wTemp;
+ u8 bTemp;
// set node id in OD
Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId, // node id
@@ -1680,14 +1675,14 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
} */
}
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
goto Exit;
}*/
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1706,7 +1701,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
EPL_C_DLL_ISOCHR_MAX_PAYL) {
wTemp =
- (WORD) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
+ (u16) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1717,7 +1712,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
EPL_C_DLL_ISOCHR_MAX_PAYL) {
wTemp =
- (WORD) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
+ (u16) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1735,7 +1730,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
}*/
if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
- bTemp = (BYTE) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
+ bTemp = (u8) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
/* if(Ret != kEplSuccessful)
{
@@ -1745,7 +1740,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
EPL_C_DLL_MAX_ASYNC_MTU) {
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
/* if(Ret != kEplSuccessful)
{
@@ -1754,7 +1749,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
}
if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
- wTemp = (WORD) EplApiInstance_g.m_InitParam.m_uiPrescaler;
+ wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiPrescaler;
Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
// ignore return code
Ret = kEplSuccessful;
@@ -1844,7 +1839,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
// write Device Name (0x1008)
Ret =
EplObdWriteEntry(0x1008, 0,
- (void GENERIC *)EplApiInstance_g.
+ (void *)EplApiInstance_g.
m_InitParam.m_pszDevName,
(tEplObdSize) strlen(EplApiInstance_g.
m_InitParam.
@@ -1859,7 +1854,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
// write Hardware version (0x1009)
Ret =
EplObdWriteEntry(0x1009, 0,
- (void GENERIC *)EplApiInstance_g.
+ (void *)EplApiInstance_g.
m_InitParam.m_pszHwVersion,
(tEplObdSize) strlen(EplApiInstance_g.
m_InitParam.
@@ -1874,7 +1869,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
// write Software version (0x100A)
Ret =
EplObdWriteEntry(0x100A, 0,
- (void GENERIC *)EplApiInstance_g.
+ (void *)EplApiInstance_g.
m_InitParam.m_pszSwVersion,
(tEplObdSize) strlen(EplApiInstance_g.
m_InitParam.
@@ -1905,7 +1900,7 @@ static tEplKernel PUBLIC EplApiUpdateObd(void)
//---------------------------------------------------------------------------
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p)
+static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
@@ -1946,10 +1941,10 @@ static tEplKernel PUBLIC EplApiCbSdoCon(tEplSdoComFinished * pSdoComFinished_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
- tEplNmtNodeEvent NodeEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p, BOOL fMandatory_p)
+static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
+ tEplNmtNodeEvent NodeEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p, BOOL fMandatory_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
@@ -1990,9 +1985,9 @@ static tEplKernel PUBLIC EplApiCbNodeEvent(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p)
+static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
@@ -2033,8 +2028,7 @@ static tEplKernel PUBLIC EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplApiCbLedStateChange(tEplLedType LedType_p,
- BOOL fOn_p)
+static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p)
{
tEplKernel Ret;
tEplApiEventArg EventArg;
diff --git a/drivers/staging/epl/EplApiLinuxKernel.c b/drivers/staging/epl/EplApiLinuxKernel.c
index 05ca0628d6a..cb3e275e3aa 100644
--- a/drivers/staging/epl/EplApiLinuxKernel.c
+++ b/drivers/staging/epl/EplApiLinuxKernel.c
@@ -72,9 +72,6 @@
// kernel modul and driver
-//#include <linux/version.h>
-//#include <linux/config.h>
-
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
@@ -92,25 +89,11 @@
#include <asm/uaccess.h>
#include <linux/vmalloc.h>
-#ifdef CONFIG_DEVFS_FS
-#include <linux/major.h>
-#include <linux/devfs_fs_kernel.h>
-#endif
-
#include "Epl.h"
#include "EplApiLinux.h"
//#include "kernel/EplPdokCal.h"
#include "proc_fs.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // remove ("make invisible") obsolete symbols for kernel versions 2.6
- // and higher
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#define EXPORT_NO_SYMBOLS
-#else
-#error "This driver needs a 2.6.x kernel or higher"
-#endif
/***************************************************************************/
/* */
@@ -139,7 +122,7 @@ MODULE_DESCRIPTION("EPL API driver");
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#else
#define TGT_DBG_SIGNAL_TRACE_POINT(p)
@@ -159,19 +142,10 @@ void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
// Global variables
//---------------------------------------------------------------------------
-#ifdef CONFIG_DEVFS_FS
-
- // driver major number
-static int nDrvMajorNumber_g;
-
-#else
-
// device number (major and minor)
static dev_t nDevNum_g;
static struct cdev *pEpl_cdev_g;
-#endif
-
static volatile unsigned int uiEplState_g = EPL_STATE_NOTOPEN;
static struct semaphore SemaphoreCbEvent_g; // semaphore for EplLinCbEvent
@@ -204,11 +178,11 @@ typedef struct {
// Prototypes of internal functions
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p);
+tEplKernel EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p);
-tEplKernel PUBLIC EplLinCbSync(void);
+tEplKernel EplLinCbSync(void);
static int __init EplLinInit(void);
static void __exit EplLinExit(void);
@@ -226,8 +200,6 @@ static int EplLinIoctl(struct inode *pDeviceFile_p, struct file *pInstance_p,
// Kernel Module specific Data Structures
//---------------------------------------------------------------------------
-EXPORT_NO_SYMBOLS;
-
module_init(EplLinInit);
module_exit(EplLinExit);
@@ -259,9 +231,6 @@ static int __init EplLinInit(void)
tEplKernel EplRet;
int iErr;
int iRet;
-#ifdef CONFIG_DEVFS_FS
- int nMinorNumber;
-#endif
TRACE0("EPL: + EplLinInit...\n");
TRACE2("EPL: Driver build: %s / %s\n", __DATE__, __TIME__);
@@ -275,44 +244,6 @@ static int __init EplLinInit(void)
init_waitqueue_head(&WaitQueueProcess_g);
init_waitqueue_head(&WaitQueueRelease_g);
-#ifdef CONFIG_DEVFS_FS
-
- // register character device handler
- TRACE2("EPL: Installing Driver '%s', Version %s...\n",
- EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION);
- TRACE0("EPL: (using dynamic major number assignment)\n");
- nDrvMajorNumber_g =
- register_chrdev(0, EPLLIN_DRV_NAME, &EplLinFileOps_g);
- if (nDrvMajorNumber_g != 0) {
- TRACE2
- ("EPL: Driver '%s' installed successful, assigned MajorNumber=%d\n",
- EPLLIN_DRV_NAME, nDrvMajorNumber_g);
- } else {
- TRACE1
- ("EPL: ERROR: Driver '%s' is unable to get a free MajorNumber!\n",
- EPLLIN_DRV_NAME);
- iRet = -EIO;
- goto Exit;
- }
-
- // create device node in DEVFS
- nMinorNumber = 0;
- TRACE1("EPL: Creating device node '/dev/%s'...\n", EPLLIN_DEV_NAME);
- iErr =
- devfs_mk_cdev(MKDEV(nDrvMajorNumber_g, nMinorNumber),
- S_IFCHR | S_IRUGO | S_IWUGO, EPLLIN_DEV_NAME);
- if (iErr == 0) {
- TRACE1("EPL: Device node '/dev/%s' created successful.\n",
- EPLLIN_DEV_NAME);
- } else {
- TRACE1("EPL: ERROR: unable to create device node '/dev/%s'\n",
- EPLLIN_DEV_NAME);
- iRet = -EIO;
- goto Exit;
- }
-
-#else
-
// register character device handler
// only one Minor required
TRACE2("EPL: Installing Driver '%s', Version %s...\n",
@@ -341,7 +272,6 @@ static int __init EplLinInit(void)
iRet = -EIO;
goto Exit;
}
-#endif
// create device node in PROCFS
EplRet = EplLinProcInit();
@@ -377,25 +307,12 @@ static void __exit EplLinExit(void)
TRACE0("EPL: + EplLinExit...\n");
-#ifdef CONFIG_DEVFS_FS
-
- // remove device node from DEVFS
- devfs_remove(EPLLIN_DEV_NAME);
- TRACE1("EPL: Device node '/dev/%s' removed.\n", EPLLIN_DEV_NAME);
-
- // unregister character device handler
- unregister_chrdev(nDrvMajorNumber_g, EPLLIN_DRV_NAME);
-
-#else
-
// remove cdev structure
cdev_del(pEpl_cdev_g);
// unregister character device handler
unregister_chrdev_region(nDevNum_g, 1);
-#endif
-
TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME);
TRACE0("EPL: - EplLinExit\n");
@@ -416,8 +333,6 @@ static int EplLinOpen(struct inode *pDeviceFile_p, // information about the devi
TRACE0("EPL: + EplLinOpen...\n");
- MOD_INC_USE_COUNT;
-
if (uiEplState_g != EPL_STATE_NOTOPEN) { // stack already initialized
iRet = -EALREADY;
} else {
@@ -490,8 +405,6 @@ static int EplLinRelease(struct inode *pDeviceFile_p, // information about the d
uiEplState_g = EPL_STATE_NOTOPEN;
iRet = 0;
- MOD_DEC_USE_COUNT;
-
TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet);
return (iRet);
@@ -1158,9 +1071,9 @@ static int EplLinIoctl(struct inode *pDeviceFile_p, // information about the dev
// //
//=========================================================================//
-tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p)
+tEplKernel EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p)
{
tEplKernel EplRet = kEplSuccessful;
int iErr;
@@ -1224,7 +1137,7 @@ tEplKernel PUBLIC EplLinCbEvent(tEplApiEventType EventType_p, // IN: event type
return EplRet;
}
-tEplKernel PUBLIC EplLinCbSync(void)
+tEplKernel EplLinCbSync(void)
{
tEplKernel EplRet = kEplSuccessful;
int iErr;
diff --git a/drivers/staging/epl/EplApiProcessImage.c b/drivers/staging/epl/EplApiProcessImage.c
index 2b2fdf229a7..7d55086a8e4 100644
--- a/drivers/staging/epl/EplApiProcessImage.c
+++ b/drivers/staging/epl/EplApiProcessImage.c
@@ -69,11 +69,8 @@
****************************************************************************/
#include "Epl.h"
-//#include "kernel/EplPdokCal.h"
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-#include <asm/uaccess.h>
-#endif
+#include <linux/uaccess.h>
/***************************************************************************/
/* */
@@ -129,10 +126,10 @@
#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
typedef struct {
#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
- BYTE m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
+ u8 m_abProcessImageInput[EPL_API_PROCESS_IMAGE_SIZE_IN];
#endif
#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
- BYTE m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
+ u8 m_abProcessImageOutput[EPL_API_PROCESS_IMAGE_SIZE_OUT];
#endif
} tEplApiProcessImageInstance;
@@ -169,7 +166,7 @@ static tEplApiProcessImageInstance EplApiProcessImageInstance_g;
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiProcessImageSetup(void)
+tEplKernel EplApiProcessImageSetup(void)
{
tEplKernel Ret = kEplSuccessful;
#if ((EPL_API_PROCESS_IMAGE_SIZE_IN > 0) || (EPL_API_PROCESS_IMAGE_SIZE_OUT > 0))
@@ -280,24 +277,16 @@ tEplKernel PUBLIC EplApiProcessImageSetup(void)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p)
+tEplKernel EplApiProcessImageExchangeIn(tEplApiProcessImage *pPI_p)
{
tEplKernel Ret = kEplSuccessful;
#if EPL_API_PROCESS_IMAGE_SIZE_IN > 0
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
copy_to_user(pPI_p->m_pImage,
EplApiProcessImageInstance_g.m_abProcessImageInput,
min(pPI_p->m_uiSize,
sizeof(EplApiProcessImageInstance_g.
m_abProcessImageInput)));
-#else
- EPL_MEMCPY(pPI_p->m_pImage,
- EplApiProcessImageInstance_g.m_abProcessImageInput,
- min(pPI_p->m_uiSize,
- sizeof(EplApiProcessImageInstance_g.
- m_abProcessImageInput)));
-#endif
#endif
return Ret;
@@ -315,24 +304,16 @@ tEplKernel PUBLIC EplApiProcessImageExchangeIn(tEplApiProcessImage * pPI_p)
// State:
//----------------------------------------------------------------------------
-tEplKernel PUBLIC EplApiProcessImageExchangeOut(tEplApiProcessImage * pPI_p)
+tEplKernel EplApiProcessImageExchangeOut(tEplApiProcessImage *pPI_p)
{
tEplKernel Ret = kEplSuccessful;
#if EPL_API_PROCESS_IMAGE_SIZE_OUT > 0
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
copy_from_user(EplApiProcessImageInstance_g.m_abProcessImageOutput,
pPI_p->m_pImage,
min(pPI_p->m_uiSize,
sizeof(EplApiProcessImageInstance_g.
m_abProcessImageOutput)));
-#else
- EPL_MEMCPY(EplApiProcessImageInstance_g.m_abProcessImageOutput,
- pPI_p->m_pImage,
- min(pPI_p->m_uiSize,
- sizeof(EplApiProcessImageInstance_g.
- m_abProcessImageOutput)));
-#endif
#endif
return Ret;
diff --git a/drivers/staging/epl/EplDll.h b/drivers/staging/epl/EplDll.h
index 36657f2daf8..b960199bd0e 100644
--- a/drivers/staging/epl/EplDll.h
+++ b/drivers/staging/epl/EplDll.h
@@ -135,22 +135,22 @@ typedef struct {
unsigned int m_uiNodeId; // local node ID
// 0x1F82: NMT_FeatureFlags_U32
- DWORD m_dwFeatureFlags;
+ u32 m_dwFeatureFlags;
// Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
- DWORD m_dwCycleLen; // required for error detection
+ u32 m_dwCycleLen; // required for error detection
// 0x1F98: NMT_CycleTiming_REC
// 0x1F98.1: IsochrTxMaxPayload_U16
unsigned int m_uiIsochrTxMaxPayload; // const
// 0x1F98.2: IsochrRxMaxPayload_U16
unsigned int m_uiIsochrRxMaxPayload; // const
// 0x1F98.3: PResMaxLatency_U32
- DWORD m_dwPresMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwPresMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.4: PReqActPayloadLimit_U16
unsigned int m_uiPreqActPayloadLimit; // required for initialisation (+24 bytes)
// 0x1F98.5: PResActPayloadLimit_U16
unsigned int m_uiPresActPayloadLimit; // required for initialisation of Pres frame (+24 bytes)
// 0x1F98.6: ASndMaxLatency_U32
- DWORD m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
+ u32 m_dwAsndMaxLatency; // const in [ns], only required for IdentRes
// 0x1F98.7: MultiplCycleCnt_U8
unsigned int m_uiMultiplCycleCnt; // required for error detection
// 0x1F98.8: AsyncMTU_U16
@@ -159,42 +159,42 @@ typedef struct {
// $$$ Multiplexed Slot
// 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
- DWORD m_dwLossOfFrameTolerance;
+ u32 m_dwLossOfFrameTolerance;
// 0x1F8A: NMT_MNCycleTiming_REC
// 0x1F8A.1: WaitSoCPReq_U32 in [ns]
- DWORD m_dwWaitSocPreq;
+ u32 m_dwWaitSocPreq;
// 0x1F8A.2: AsyncSlotTimeout_U32 in [ns]
- DWORD m_dwAsyncSlotTimeout;
+ u32 m_dwAsyncSlotTimeout;
} tEplDllConfigParam;
typedef struct {
unsigned int m_uiSizeOfStruct;
- DWORD m_dwDeviceType; // NMT_DeviceType_U32
- DWORD m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
- DWORD m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
- DWORD m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
- DWORD m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
- QWORD m_qwVendorSpecificExt1;
- DWORD m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
- DWORD m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
- DWORD m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_dwIpAddress;
- DWORD m_dwSubnetMask;
- DWORD m_dwDefaultGateway;
- BYTE m_sHostname[32];
- BYTE m_abVendorSpecificExt2[48];
+ u32 m_dwDeviceType; // NMT_DeviceType_U32
+ u32 m_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
+ u32 m_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
+ u32 m_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
+ u32 m_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
+ u64 m_qwVendorSpecificExt1;
+ u32 m_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+ u32 m_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+ u32 m_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_dwIpAddress;
+ u32 m_dwSubnetMask;
+ u32 m_dwDefaultGateway;
+ u8 m_sHostname[32];
+ u8 m_abVendorSpecificExt2[48];
} tEplDllIdentParam;
typedef struct {
unsigned int m_uiNodeId;
- WORD m_wPreqPayloadLimit; // object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16
- WORD m_wPresPayloadLimit; // object 0x1F8D: NMT_PResPayloadLimitList_AU16
- DWORD m_dwPresTimeout; // object 0x1F92: NMT_MNCNPResTimeout_AU32
+ u16 m_wPreqPayloadLimit; // object 0x1F8B: NMT_MNPReqPayloadLimitList_AU16
+ u16 m_wPresPayloadLimit; // object 0x1F8D: NMT_PResPayloadLimitList_AU16
+ u32 m_dwPresTimeout; // object 0x1F92: NMT_MNCNPResTimeout_AU32
} tEplDllNodeInfo;
diff --git a/drivers/staging/epl/EplDllCal.h b/drivers/staging/epl/EplDllCal.h
index 24460087e98..70b27b1b676 100644
--- a/drivers/staging/epl/EplDllCal.h
+++ b/drivers/staging/epl/EplDllCal.h
@@ -112,7 +112,7 @@ typedef struct {
typedef struct {
tEplDllReqServiceId m_Service;
unsigned int m_uiNodeId;
- BYTE m_bSoaFlag1;
+ u8 m_bSoaFlag1;
} tEplDllCalIssueRequest;
diff --git a/drivers/staging/epl/EplDllk.c b/drivers/staging/epl/EplDllk.c
index 9e22641055c..25d2c34325d 100644
--- a/drivers/staging/epl/EplDllk.c
+++ b/drivers/staging/epl/EplDllk.c
@@ -121,8 +121,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -195,12 +195,12 @@ typedef enum {
} tEplDllState;
typedef struct {
- BYTE m_be_abSrcMac[6];
+ u8 m_be_abSrcMac[6];
tEdrvTxBuffer *m_pTxBuffer; // Buffers for Tx-Frames
unsigned int m_uiMaxTxFrames;
- BYTE m_bFlag1; // Flag 1 with EN, EC for PRes, StatusRes
- BYTE m_bMnFlag1; // Flag 1 with EA, ER from PReq, SoA of MN
- BYTE m_bFlag2; // Flag 2 with PR and RS for PRes, StatusRes, IdentRes
+ u8 m_bFlag1; // Flag 1 with EN, EC for PRes, StatusRes
+ u8 m_bMnFlag1; // Flag 1 with EA, ER from PReq, SoA of MN
+ u8 m_bFlag2; // Flag 2 with PR and RS for PRes, StatusRes, IdentRes
tEplDllConfigParam m_DllConfigParam;
tEplDllIdentParam m_DllIdentParam;
tEplDllState m_DllState;
@@ -257,7 +257,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
// called by high resolution timer module to monitor EPL cycle as CN
#if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p);
+static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p);
#endif
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
@@ -278,10 +278,9 @@ static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
ReqServiceId_p,
unsigned int uiNodeId_p);
-static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p);
+static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p);
-static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
- pEventArg_p);
+static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p);
#endif
@@ -514,7 +513,7 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_ETHERTYPE_EPL);
// source node ID
AmiSetByteToLe(&pTxFrame->m_le_bSrcNodeId,
- (BYTE) EplDllkInstance_g.m_DllConfigParam.
+ (u8) EplDllkInstance_g.m_DllConfigParam.
m_uiNodeId);
// source MAC address
EPL_MEMCPY(&pTxFrame->m_be_abSrcMac[0],
@@ -531,7 +530,7 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
{ // IdentResponses and StatusResponses are Broadcast
AmiSetByteToLe(&pTxFrame->
m_le_bDstNodeId,
- (BYTE)
+ (u8)
EPL_C_ADR_BROADCAST);
break;
}
@@ -550,10 +549,10 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_MULTICAST_SOC);
// destination node ID
AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
- (BYTE) EPL_C_ADR_BROADCAST);
+ (u8) EPL_C_ADR_BROADCAST);
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soc.m_le_bFlag2, (u8) 0);
break;
case kEplMsgTypeSoa:
@@ -562,13 +561,13 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_MULTICAST_SOA);
// destination node ID
AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
- (BYTE) EPL_C_ADR_BROADCAST);
+ (u8) EPL_C_ADR_BROADCAST);
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bFlag2, (u8) 0);
// EPL profile version
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bEplVersion,
- (BYTE) EPL_SPEC_VERSION);
+ (u8) EPL_SPEC_VERSION);
break;
case kEplMsgTypePres:
@@ -577,18 +576,18 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
EPL_C_DLL_MULTICAST_PRES);
// destination node ID
AmiSetByteToLe(&pTxFrame->m_le_bDstNodeId,
- (BYTE) EPL_C_ADR_BROADCAST);
+ (u8) EPL_C_ADR_BROADCAST);
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bFlag2, (u8) 0);
// PDO size
//AmiSetWordToLe(&pTxFrame->m_Data.m_Pres.m_le_wSize, 0);
break;
case kEplMsgTypePreq:
// reset Flags
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (BYTE) 0);
- //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (BYTE) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag1, (u8) 0);
+ //AmiSetByteToLe(&pTxFrame->m_Data.m_Preq.m_le_bFlag2, (u8) 0);
// PDO size
//AmiSetWordToLe(&pTxFrame->m_Data.m_Preq.m_le_wSize, 0);
break;
@@ -597,7 +596,7 @@ tEplKernel EplDllkCreateTxFrame(unsigned int *puiHandle_p,
break;
}
// EPL message type
- AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (BYTE) MsgType_p);
+ AmiSetByteToLe(&pTxFrame->m_le_bMessageType, (u8) MsgType_p);
}
*ppFrame_p = pTxFrame;
@@ -673,7 +672,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
tEdrvTxBuffer *pTxBuffer;
unsigned int uiHandle;
unsigned int uiFrameSize;
- BYTE abMulticastMac[6];
+ u8 abMulticastMac[6];
tEplDllAsyncReqPriority AsyncReqPriority;
unsigned int uiFrameCount;
tEplNmtState NmtState;
@@ -712,7 +711,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
// EPL profile version
AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_bEplProfileVersion,
- (BYTE) EPL_SPEC_VERSION);
+ (u8) EPL_SPEC_VERSION);
// FeatureFlags
AmiSetDwordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_dwFeatureFlags,
@@ -721,18 +720,18 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
// MTU
AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_wMtu,
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.m_uiAsyncMtu);
// PollInSize
AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_wPollInSize,
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.
m_uiPreqActPayloadLimit);
// PollOutSize
AmiSetWordToLe(&pTxFrame->m_Data.m_Asnd.m_Payload.
m_IdentResponse.m_le_wPollOutSize,
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.
m_uiPresActPayloadLimit);
// ResponseTime / PresMaxLatency
@@ -936,7 +935,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
// EplDllkInstance_g.m_aNodeInfo[uiIndex].m_uiNodeId = uiIndex + 1;
EplDllkInstance_g.m_aNodeInfo[uiIndex].
m_wPresPayloadLimit =
- (WORD) EplDllkInstance_g.
+ (u16) EplDllkInstance_g.
m_DllConfigParam.
m_uiIsochrRxMaxPayload;
}
@@ -1233,7 +1232,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
}
if (uiFrameCount > 0) {
EplDllkInstance_g.m_bFlag2 =
- (BYTE) (((AsyncReqPriority <<
+ (u8) (((AsyncReqPriority <<
EPL_FRAME_FLAG2_PR_SHIFT)
& EPL_FRAME_FLAG2_PR)
| (uiFrameCount &
@@ -1307,7 +1306,7 @@ tEplKernel EplDllkProcess(tEplEvent * pEvent_p)
}
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.
@@ -1533,7 +1532,7 @@ tEplKernel EplDllkSetAsndServiceIdFilter(tEplDllAsndServiceId ServiceId_p,
//
//---------------------------------------------------------------------------
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p)
{
tEplKernel Ret = kEplSuccessful;
tEplDllkNodeInfo *pNodeInfo;
@@ -1664,7 +1663,7 @@ tEplKernel EplDllkAddNode(tEplDllNodeInfo * pNodeInfo_p)
pIntNodeInfo->m_pPreqTxBuffer =
&EplDllkInstance_g.m_pTxBuffer[uiHandle];
AmiSetByteToLe(&pFrame->m_le_bDstNodeId,
- (BYTE) pNodeInfo_p->m_uiNodeId);
+ (u8) pNodeInfo_p->m_uiNodeId);
// set up destination MAC address
EPL_MEMCPY(pFrame->m_be_abDstMac, pIntNodeInfo->m_be_abMacAddr,
@@ -2431,7 +2430,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
tEplDllReqServiceId ReqServiceId;
unsigned int uiAsndServiceId;
unsigned int uiNodeId;
- BYTE bFlag1;
+ u8 bFlag1;
BENCHMARK_MOD_02_SET(3);
NmtState = EplNmtkGetNmtState();
@@ -2466,7 +2465,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
// update frame (NMT state, RD, RS, PR, MS, EN flags)
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.
@@ -2541,7 +2540,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
// update frame (NMT state, RD, RS, PR, MS, EN flags)
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.
@@ -2803,7 +2802,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
}
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.
m_le_bFlag2,
EplDllkInstance_g.m_bFlag2);
@@ -2888,7 +2887,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
m_Payload.
m_StatusResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->
m_Data.m_Asnd.
m_Payload.
@@ -2954,7 +2953,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
m_Payload.
m_IdentResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->
m_Data.m_Asnd.
m_Payload.
@@ -3155,7 +3154,7 @@ static void EplDllkCbFrameReceived(tEdrvRxBuffer * pRxBuffer_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3286,7 +3285,7 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
m_Payload.
m_StatusResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
m_Payload.
m_StatusResponse.
@@ -3322,7 +3321,7 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
m_Payload.
m_IdentResponse.
m_le_bNmtStatus,
- (BYTE) NmtState);
+ (u8) NmtState);
AmiSetByteToLe(&pTxFrame->m_Data.m_Asnd.
m_Payload.
m_IdentResponse.
@@ -3362,12 +3361,12 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
if ((AmiGetByteFromLe
(&pTxFrame->
m_le_bMessageType)
- == (BYTE) kEplMsgTypeAsnd)
+ == (u8) kEplMsgTypeAsnd)
&&
(AmiGetByteFromLe
(&pTxFrame->m_Data.m_Asnd.
m_le_bServiceId)
- == (BYTE) kEplDllAsndNmtCommand)) { // post event directly to NmtMnu module
+ == (u8) kEplDllAsndNmtCommand)) { // post event directly to NmtMnu module
Event.m_EventSink =
kEplEventSinkNmtMnu;
Event.m_EventType =
@@ -3449,7 +3448,7 @@ static void EplDllkCbFrameTransmitted(tEdrvTxBuffer * pTxBuffer_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3485,7 +3484,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
unsigned int uiFrameSize_p)
{
tEplMsgType MsgType;
- WORD wEtherType;
+ u16 wEtherType;
// check frame
if (pFrame_p != NULL) {
@@ -3506,7 +3505,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
if (wEtherType == EPL_C_DLL_ETHERTYPE_EPL) {
// source node ID
AmiSetByteToLe(&pFrame_p->m_le_bSrcNodeId,
- (BYTE) EplDllkInstance_g.
+ (u8) EplDllkInstance_g.
m_DllConfigParam.m_uiNodeId);
// check message type
@@ -3515,7 +3514,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
if (MsgType == 0) {
MsgType = kEplMsgTypeAsnd;
AmiSetByteToLe(&pFrame_p->m_le_bMessageType,
- (BYTE) MsgType);
+ (u8) MsgType);
}
if (MsgType == kEplMsgTypeAsnd) {
@@ -3546,7 +3545,7 @@ static tEplKernel EplDllkCheckFrame(tEplFrame * pFrame_p,
//---------------------------------------------------------------------------
#if EPL_TIMER_USE_HIGHRES != FALSE
-static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
+static tEplKernel EplDllkCbCnTimer(tEplTimerEventArg *pEventArg_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtState NmtState;
@@ -3583,7 +3582,7 @@ static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3617,7 +3616,7 @@ static tEplKernel PUBLIC EplDllkCbCnTimer(tEplTimerEventArg * pEventArg_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
+static tEplKernel EplDllkCbMnTimerCycle(tEplTimerEventArg *pEventArg_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtState NmtState;
@@ -3639,7 +3638,7 @@ static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3670,8 +3669,7 @@ static tEplKernel PUBLIC EplDllkCbMnTimerCycle(tEplTimerEventArg * pEventArg_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
- pEventArg_p)
+static tEplKernel EplDllkCbMnTimerResponse(tEplTimerEventArg *pEventArg_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtState NmtState;
@@ -3693,7 +3691,7 @@ static tEplKernel PUBLIC EplDllkCbMnTimerResponse(tEplTimerEventArg *
Exit:
if (Ret != kEplSuccessful) {
- DWORD dwArg;
+ u32 dwArg;
BENCHMARK_MOD_02_TOGGLE(9);
@@ -3827,24 +3825,24 @@ static tEplKernel EplDllkMnSendSoa(tEplNmtState NmtState_p,
// update frame (target)
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
m_le_bReqServiceId,
- (BYTE) EplDllkInstance_g.
+ (u8) EplDllkInstance_g.
m_LastReqServiceId);
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
m_le_bReqServiceTarget,
- (BYTE) EplDllkInstance_g.
+ (u8) EplDllkInstance_g.
m_uiLastTargetNodeId);
} else { // invite nobody
// update frame (target)
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
- m_le_bReqServiceId, (BYTE) 0);
+ m_le_bReqServiceId, (u8) 0);
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.
- m_le_bReqServiceTarget, (BYTE) 0);
+ m_le_bReqServiceTarget, (u8) 0);
}
// update frame (NMT state)
AmiSetByteToLe(&pTxFrame->m_Data.m_Soa.m_le_bNmtStatus,
- (BYTE) NmtState_p);
+ (u8) NmtState_p);
// send SoA frame
Ret = EdrvSendTxMsg(pTxBuffer);
@@ -3921,7 +3919,7 @@ static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
tEplKernel Ret = kEplSuccessful;
tEdrvTxBuffer *pTxBuffer = NULL;
tEplFrame *pTxFrame;
- BYTE bFlag1 = 0;
+ u8 bFlag1 = 0;
if (EplDllkInstance_g.m_pCurNodeInfo == NULL) { // start with first isochronous CN
EplDllkInstance_g.m_pCurNodeInfo =
@@ -3972,7 +3970,7 @@ static tEplKernel EplDllkMnSendPreq(tEplNmtState NmtState_p,
if (pTxBuffer == &EplDllkInstance_g.m_pTxBuffer[EPL_DLLK_TXFRAME_PRES]) { // PRes of MN will be sent
// update NMT state
AmiSetByteToLe(&pTxFrame->m_Data.m_Pres.m_le_bNmtStatus,
- (BYTE) NmtState_p);
+ (u8) NmtState_p);
*pDllStateProposed_p = kEplDllMsWaitSoaTrig;
}
// $$$ d.k. set EPL_FRAME_FLAG1_MS if necessary
@@ -4015,7 +4013,7 @@ static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
unsigned int uiNodeId_p)
{
tEplKernel Ret = kEplSuccessful;
- BYTE abBuffer[18];
+ u8 abBuffer[18];
tEplFrame *pFrame = (tEplFrame *) abBuffer;
tEplFrameInfo FrameInfo;
@@ -4026,13 +4024,13 @@ static tEplKernel EplDllkAsyncFrameNotReceived(tEplDllReqServiceId
// ASnd service registered?
if (EplDllkInstance_g.m_aAsndFilter[ReqServiceId_p] == kEplDllAsndFilterAny) { // ASnd service ID is registered
AmiSetByteToLe(&pFrame->m_le_bSrcNodeId,
- (BYTE) uiNodeId_p);
+ (u8) uiNodeId_p);
// EPL MsgType ASnd
AmiSetByteToLe(&pFrame->m_le_bMessageType,
- (BYTE) kEplMsgTypeAsnd);
+ (u8) kEplMsgTypeAsnd);
// ASnd Service ID
AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
- (BYTE) ReqServiceId_p);
+ (u8) ReqServiceId_p);
// create frame info structure
FrameInfo.m_pFrame = pFrame;
FrameInfo.m_uiFrameSize = 18; // empty non existing ASnd frame
diff --git a/drivers/staging/epl/EplDllkCal.c b/drivers/staging/epl/EplDllkCal.c
index 359083ebe12..0e283d5d018 100644
--- a/drivers/staging/epl/EplDllkCal.c
+++ b/drivers/staging/epl/EplDllkCal.c
@@ -142,9 +142,9 @@ typedef struct {
tShbInstance m_ShbInstanceTxGen; // FIFO for Tx frames with generic priority
#else
unsigned int m_uiFrameSizeNmt;
- BYTE m_abFrameNmt[1500];
+ u8 m_abFrameNmt[1500];
unsigned int m_uiFrameSizeGen;
- BYTE m_abFrameGen[1500];
+ u8 m_abFrameGen[1500];
#endif
tEplDllkCalStatistics m_Statistics;
@@ -202,7 +202,7 @@ static tEplDllkCalInstance EplDllkCalInstance_g;
//
//---------------------------------------------------------------------------
-tEplKernel EplDllkCalAddInstance()
+tEplKernel EplDllkCalAddInstance(void)
{
tEplKernel Ret = kEplSuccessful;
#ifndef EPL_NO_FIFO
@@ -279,7 +279,7 @@ tEplKernel EplDllkCalAddInstance()
//
//---------------------------------------------------------------------------
-tEplKernel EplDllkCalDelInstance()
+tEplKernel EplDllkCalDelInstance(void)
{
tEplKernel Ret = kEplSuccessful;
#ifndef EPL_NO_FIFO
@@ -536,7 +536,7 @@ tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
case kEplDllAsyncReqPrioNmt: // NMT request priority
ShbError =
ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxNmt,
- (BYTE *) pFrame_p, *puiFrameSize_p,
+ (u8 *) pFrame_p, *puiFrameSize_p,
&ulFrameSize);
// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
break;
@@ -544,7 +544,7 @@ tEplKernel EplDllkCalAsyncGetTxFrame(void *pFrame_p,
default: // generic priority
ShbError =
ShbCirReadDataBlock(EplDllkCalInstance_g.m_ShbInstanceTxGen,
- (BYTE *) pFrame_p, *puiFrameSize_p,
+ (u8 *) pFrame_p, *puiFrameSize_p,
&ulFrameSize);
// returns kShbOk, kShbDataTruncated, kShbInvalidArg, kShbNoReadableData
break;
@@ -876,7 +876,7 @@ tEplKernel EplDllkCalGetStatistics(tEplDllkCalStatistics ** ppStatistics)
//---------------------------------------------------------------------------
tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/EplDlluCal.c b/drivers/staging/epl/EplDlluCal.c
index 7f4a1745023..f96fe84c497 100644
--- a/drivers/staging/epl/EplDlluCal.c
+++ b/drivers/staging/epl/EplDlluCal.c
@@ -173,7 +173,7 @@ static tEplKernel EplDlluCalSetAsndServiceIdFilter(tEplDllAsndServiceId
//
//---------------------------------------------------------------------------
-tEplKernel EplDlluCalAddInstance()
+tEplKernel EplDlluCalAddInstance(void)
{
tEplKernel Ret = kEplSuccessful;
@@ -198,7 +198,7 @@ tEplKernel EplDlluCalAddInstance()
//
//---------------------------------------------------------------------------
-tEplKernel EplDlluCalDelInstance()
+tEplKernel EplDlluCalDelInstance(void)
{
tEplKernel Ret = kEplSuccessful;
@@ -355,7 +355,7 @@ tEplKernel EplDlluCalAsyncSend(tEplFrameInfo * pFrameInfo_p,
//---------------------------------------------------------------------------
tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p)
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/EplErrorHandlerk.c b/drivers/staging/epl/EplErrorHandlerk.c
index d12521fc99a..6baed04ef11 100644
--- a/drivers/staging/epl/EplErrorHandlerk.c
+++ b/drivers/staging/epl/EplErrorHandlerk.c
@@ -97,9 +97,9 @@
//---------------------------------------------------------------------------
typedef struct {
- DWORD m_dwCumulativeCnt; // subindex 1
- DWORD m_dwThresholdCnt; // subindex 2
- DWORD m_dwThreshold; // subindex 3
+ u32 m_dwCumulativeCnt; // subindex 1
+ u32 m_dwThresholdCnt; // subindex 2
+ u32 m_dwThreshold; // subindex 3
} tEplErrorHandlerkErrorCounter;
@@ -112,9 +112,9 @@ typedef struct {
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
tEplErrorHandlerkErrorCounter m_MnCrcErr; // object 0x1C00
tEplErrorHandlerkErrorCounter m_MnCycTimeExceed; // object 0x1C02
- DWORD m_adwMnCnLossPresCumCnt[254]; // object 0x1C07
- DWORD m_adwMnCnLossPresThrCnt[254]; // object 0x1C08
- DWORD m_adwMnCnLossPresThreshold[254]; // object 0x1C09
+ u32 m_adwMnCnLossPresCumCnt[254]; // object 0x1C07
+ u32 m_adwMnCnLossPresThrCnt[254]; // object 0x1C08
+ u32 m_adwMnCnLossPresThreshold[254]; // object 0x1C09
BOOL m_afMnCnLossPresEvent[254];
#endif
@@ -135,7 +135,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
unsigned int uiIndex_p);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
+static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
unsigned int uiValueCount_p,
unsigned int uiIndex_p);
#endif
@@ -176,7 +176,7 @@ static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkInit(void)
+tEplKernel EplErrorHandlerkInit(void)
{
tEplKernel Ret;
@@ -203,7 +203,7 @@ tEplKernel PUBLIC EplErrorHandlerkInit(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
+tEplKernel EplErrorHandlerkAddInstance(void)
{
tEplKernel Ret;
@@ -306,7 +306,7 @@ tEplKernel PUBLIC EplErrorHandlerkAddInstance(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkDelInstance()
+tEplKernel EplErrorHandlerkDelInstance(void)
{
tEplKernel Ret;
@@ -333,7 +333,7 @@ tEplKernel PUBLIC EplErrorHandlerkDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p)
+tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p)
{
tEplKernel Ret;
unsigned long ulDllErrorEvents;
@@ -713,7 +713,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
tEplVarParam VarParam;
VarParam.m_pData = &pErrorCounter_p->m_dwCumulativeCnt;
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_uiSubindex = 0x01;
VarParam.m_ValidFlag = kVarValidAll;
@@ -723,7 +723,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
}
VarParam.m_pData = &pErrorCounter_p->m_dwThresholdCnt;
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_uiSubindex = 0x02;
VarParam.m_ValidFlag = kVarValidAll;
@@ -733,7 +733,7 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
}
VarParam.m_pData = &pErrorCounter_p->m_dwThreshold;
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_uiSubindex = 0x03;
VarParam.m_ValidFlag = kVarValidAll;
@@ -763,18 +763,18 @@ static tEplKernel EplErrorHandlerkLinkErrorCounter(tEplErrorHandlerkErrorCounter
//---------------------------------------------------------------------------
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
-static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
+static tEplKernel EplErrorHandlerkLinkArray(u32 * pdwValue_p,
unsigned int uiValueCount_p,
unsigned int uiIndex_p)
{
tEplKernel Ret = kEplSuccessful;
tEplVarParam VarParam;
tEplObdSize EntrySize;
- BYTE bIndexEntries;
+ u8 bIndexEntries;
EntrySize = (tEplObdSize) sizeof(bIndexEntries);
Ret = EplObdReadEntry(uiIndex_p,
- 0x00, (void GENERIC *)&bIndexEntries, &EntrySize);
+ 0x00, (void *)&bIndexEntries, &EntrySize);
if ((Ret != kEplSuccessful) || (bIndexEntries == 0x00)) {
// Object doesn't exist or invalid entry number
@@ -786,7 +786,7 @@ static tEplKernel EplErrorHandlerkLinkArray(DWORD * pdwValue_p,
uiValueCount_p = bIndexEntries;
}
- VarParam.m_Size = sizeof(DWORD);
+ VarParam.m_Size = sizeof(u32);
VarParam.m_uiIndex = uiIndex_p;
VarParam.m_ValidFlag = kVarValidAll;
diff --git a/drivers/staging/epl/EplEvent.h b/drivers/staging/epl/EplEvent.h
index b6dc1b9b2ab..910bd69a18c 100644
--- a/drivers/staging/epl/EplEvent.h
+++ b/drivers/staging/epl/EplEvent.h
@@ -248,8 +248,8 @@ typedef struct {
tEplEventSource m_EventSource; // module which posted this error event
tEplKernel m_EplError; // EPL error which occured
union {
- BYTE m_bArg;
- DWORD m_dwArg;
+ u8 m_bArg;
+ u32 m_dwArg;
tEplEventSource m_EventSource; // from Eventk/u module (originating error source)
tEplEventObdError m_ObdError; // from Obd module
// tEplErrHistoryEntry m_HistoryEntry; // from Nmtk/u module
@@ -267,10 +267,10 @@ typedef struct {
} tEplErrorHandlerkEvent;
// callback function to get informed about sync event
-typedef tEplKernel(PUBLIC * tEplSyncCb) (void);
+typedef tEplKernel(*tEplSyncCb) (void);
// callback function for generic events
-typedef tEplKernel(PUBLIC * tEplProcessEventCb) (tEplEvent * pEplEvent_p);
+typedef tEplKernel(*tEplProcessEventCb) (tEplEvent *pEplEvent_p);
//---------------------------------------------------------------------------
// function prototypes
diff --git a/drivers/staging/epl/EplEventk.c b/drivers/staging/epl/EplEventk.c
index 8068a6c5a0d..ef36815c798 100644
--- a/drivers/staging/epl/EplEventk.c
+++ b/drivers/staging/epl/EplEventk.c
@@ -100,8 +100,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -172,7 +172,7 @@ static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkInit(tEplSyncCb pfnCbSync_p)
+tEplKernel EplEventkInit(tEplSyncCb pfnCbSync_p)
{
tEplKernel Ret;
@@ -196,7 +196,7 @@ tEplKernel PUBLIC EplEventkInit(tEplSyncCb pfnCbSync_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
+tEplKernel EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -275,7 +275,7 @@ tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkDelInstance()
+tEplKernel EplEventkDelInstance(void)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -339,7 +339,7 @@ tEplKernel PUBLIC EplEventkDelInstance()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p)
+tEplKernel EplEventkProcess(tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplEventSource EventSource;
@@ -562,7 +562,7 @@ tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p)
+tEplKernel EplEventkPost(tEplEvent *pEvent_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -755,12 +755,12 @@ tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p)
+tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p)
{
tEplKernel Ret;
- BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+ u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
tEplEventError *pEventError = (tEplEventError *) abBuffer;
tEplEvent EplEvent;
@@ -814,7 +814,7 @@ static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
tShbError ShbError;
//unsigned long ulBlockCount;
//unsigned long ulDataSize;
- BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+ u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
// d.k.: abDataBuffer contains the complete tEplEvent structure
// and behind this the argument
diff --git a/drivers/staging/epl/EplEventu.c b/drivers/staging/epl/EplEventu.c
index 815f9a87abf..3ae2841ad02 100644
--- a/drivers/staging/epl/EplEventu.c
+++ b/drivers/staging/epl/EplEventu.c
@@ -96,8 +96,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -172,7 +172,7 @@ static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
+tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
{
tEplKernel Ret;
@@ -199,8 +199,7 @@ tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
- pfnApiProcessEventCb_p)
+tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -280,7 +279,7 @@ tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuDelInstance()
+tEplKernel EplEventuDelInstance(void)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -348,7 +347,7 @@ tEplKernel PUBLIC EplEventuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p)
+tEplKernel EplEventuProcess(tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplEventSource EventSource;
@@ -515,7 +514,7 @@ tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p)
+tEplKernel EplEventuPost(tEplEvent *pEvent_p)
{
tEplKernel Ret;
#ifndef EPL_NO_FIFO
@@ -689,12 +688,12 @@ tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p)
+tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p)
{
tEplKernel Ret;
- BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
+ u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
tEplEventError *pEventError = (tEplEventError *) abBuffer;
tEplEvent EplEvent;
@@ -751,7 +750,7 @@ static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
tShbError ShbError;
//unsigned long ulBlockCount;
//unsigned long ulDataSize;
- BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
+ u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
// d.k.: abDataBuffer contains the complete tEplEvent structure
// and behind this the argument
diff --git a/drivers/staging/epl/EplFrame.h b/drivers/staging/epl/EplFrame.h
index 9a7f8b9f594..ba1ae9e9e90 100644
--- a/drivers/staging/epl/EplFrame.h
+++ b/drivers/staging/epl/EplFrame.h
@@ -122,155 +122,155 @@
typedef struct {
// Offset 17
- BYTE m_le_bRes1; // reserved
+ u8 m_le_bRes1; // reserved
// Offset 18
- BYTE m_le_bFlag1; // Flags: MC, PS
+ u8 m_le_bFlag1; // Flags: MC, PS
// Offset 19
- BYTE m_le_bFlag2; // Flags: res
+ u8 m_le_bFlag2; // Flags: res
// Offset 20
tEplNetTime m_le_NetTime; // supported if D_NMT_NetTimeIsRealTime_BOOL is set
// Offset 28
- QWORD m_le_RelativeTime; // in us (supported if D_NMT_RelativeTime_BOOL is set)
+ u64 m_le_RelativeTime; // in us (supported if D_NMT_RelativeTime_BOOL is set)
} PACK_STRUCT tEplSocFrame;
typedef struct {
// Offset 17
- BYTE m_le_bRes1; // reserved
+ u8 m_le_bRes1; // reserved
// Offset 18
- BYTE m_le_bFlag1; // Flags: MS, EA, RD
+ u8 m_le_bFlag1; // Flags: MS, EA, RD
// Offset 19
- BYTE m_le_bFlag2; // Flags: res
+ u8 m_le_bFlag2; // Flags: res
// Offset 20
- BYTE m_le_bPdoVersion;
+ u8 m_le_bPdoVersion;
// Offset 21
- BYTE m_le_bRes2; // reserved
+ u8 m_le_bRes2; // reserved
// Offset 22
- WORD m_le_wSize;
+ u16 m_le_wSize;
// Offset 24
- BYTE m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ];
+ u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16 */ ];
} PACK_STRUCT tEplPreqFrame;
typedef struct {
// Offset 17
- BYTE m_le_bNmtStatus; // NMT state
+ u8 m_le_bNmtStatus; // NMT state
// Offset 18
- BYTE m_le_bFlag1; // Flags: MS, EN, RD
+ u8 m_le_bFlag1; // Flags: MS, EN, RD
// Offset 19
- BYTE m_le_bFlag2; // Flags: PR, RS
+ u8 m_le_bFlag2; // Flags: PR, RS
// Offset 20
- BYTE m_le_bPdoVersion;
+ u8 m_le_bPdoVersion;
// Offset 21
- BYTE m_le_bRes2; // reserved
+ u8 m_le_bRes2; // reserved
// Offset 22
- WORD m_le_wSize;
+ u16 m_le_wSize;
// Offset 24
- BYTE m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16
+ u8 m_le_abPayload[256 /*D_NMT_IsochrRxMaxPayload_U16
/ D_NMT_IsochrTxMaxPayload_U16 */ ];
} PACK_STRUCT tEplPresFrame;
typedef struct {
// Offset 17
- BYTE m_le_bNmtStatus; // NMT state
+ u8 m_le_bNmtStatus; // NMT state
// Offset 18
- BYTE m_le_bFlag1; // Flags: EA, ER
+ u8 m_le_bFlag1; // Flags: EA, ER
// Offset 19
- BYTE m_le_bFlag2; // Flags: res
+ u8 m_le_bFlag2; // Flags: res
// Offset 20
- BYTE m_le_bReqServiceId;
+ u8 m_le_bReqServiceId;
// Offset 21
- BYTE m_le_bReqServiceTarget;
+ u8 m_le_bReqServiceTarget;
// Offset 22
- BYTE m_le_bEplVersion;
+ u8 m_le_bEplVersion;
} PACK_STRUCT tEplSoaFrame;
typedef struct {
- WORD m_wEntryType;
- WORD m_wErrorCode;
+ u16 m_wEntryType;
+ u16 m_wErrorCode;
tEplNetTime m_TimeStamp;
- BYTE m_abAddInfo[8];
+ u8 m_abAddInfo[8];
} PACK_STRUCT tEplErrHistoryEntry;
typedef struct {
// Offset 18
- BYTE m_le_bFlag1; // Flags: EN, EC
- BYTE m_le_bFlag2; // Flags: PR, RS
- BYTE m_le_bNmtStatus; // NMT state
- BYTE m_le_bRes1[3];
- QWORD m_le_qwStaticError; // static error bit field
+ u8 m_le_bFlag1; // Flags: EN, EC
+ u8 m_le_bFlag2; // Flags: PR, RS
+ u8 m_le_bNmtStatus; // NMT state
+ u8 m_le_bRes1[3];
+ u64 m_le_qwStaticError; // static error bit field
tEplErrHistoryEntry m_le_aErrHistoryEntry[14];
} PACK_STRUCT tEplStatusResponse;
typedef struct {
// Offset 18
- BYTE m_le_bFlag1; // Flags: res
- BYTE m_le_bFlag2; // Flags: PR, RS
- BYTE m_le_bNmtStatus; // NMT state
- BYTE m_le_bIdentRespFlags; // Flags: FW
- BYTE m_le_bEplProfileVersion;
- BYTE m_le_bRes1;
- DWORD m_le_dwFeatureFlags; // NMT_FeatureFlags_U32
- WORD m_le_wMtu; // NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU
- WORD m_le_wPollInSize; // NMT_CycleTiming_REC.PReqActPayload_U16
- WORD m_le_wPollOutSize; // NMT_CycleTiming_REC.PResActPayload_U16
- DWORD m_le_dwResponseTime; // NMT_CycleTiming_REC.PResMaxLatency_U32
- WORD m_le_wRes2;
- DWORD m_le_dwDeviceType; // NMT_DeviceType_U32
- DWORD m_le_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
- DWORD m_le_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
- DWORD m_le_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
- DWORD m_le_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
- QWORD m_le_qwVendorSpecificExt1;
- DWORD m_le_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
- DWORD m_le_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
- DWORD m_le_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_le_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
- DWORD m_le_dwIpAddress;
- DWORD m_le_dwSubnetMask;
- DWORD m_le_dwDefaultGateway;
- BYTE m_le_sHostname[32];
- BYTE m_le_abVendorSpecificExt2[48];
+ u8 m_le_bFlag1; // Flags: res
+ u8 m_le_bFlag2; // Flags: PR, RS
+ u8 m_le_bNmtStatus; // NMT state
+ u8 m_le_bIdentRespFlags; // Flags: FW
+ u8 m_le_bEplProfileVersion;
+ u8 m_le_bRes1;
+ u32 m_le_dwFeatureFlags; // NMT_FeatureFlags_U32
+ u16 m_le_wMtu; // NMT_CycleTiming_REC.AsyncMTU_U16: C_IP_MIN_MTU - C_IP_MAX_MTU
+ u16 m_le_wPollInSize; // NMT_CycleTiming_REC.PReqActPayload_U16
+ u16 m_le_wPollOutSize; // NMT_CycleTiming_REC.PResActPayload_U16
+ u32 m_le_dwResponseTime; // NMT_CycleTiming_REC.PResMaxLatency_U32
+ u16 m_le_wRes2;
+ u32 m_le_dwDeviceType; // NMT_DeviceType_U32
+ u32 m_le_dwVendorId; // NMT_IdentityObject_REC.VendorId_U32
+ u32 m_le_dwProductCode; // NMT_IdentityObject_REC.ProductCode_U32
+ u32 m_le_dwRevisionNumber; // NMT_IdentityObject_REC.RevisionNo_U32
+ u32 m_le_dwSerialNumber; // NMT_IdentityObject_REC.SerialNo_U32
+ u64 m_le_qwVendorSpecificExt1;
+ u32 m_le_dwVerifyConfigurationDate; // CFM_VerifyConfiguration_REC.ConfDate_U32
+ u32 m_le_dwVerifyConfigurationTime; // CFM_VerifyConfiguration_REC.ConfTime_U32
+ u32 m_le_dwApplicationSwDate; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_le_dwApplicationSwTime; // PDL_LocVerApplSw_REC.ApplSwTime_U32 on programmable device or time portion of NMT_ManufactSwVers_VS on non-programmable device
+ u32 m_le_dwIpAddress;
+ u32 m_le_dwSubnetMask;
+ u32 m_le_dwDefaultGateway;
+ u8 m_le_sHostname[32];
+ u8 m_le_abVendorSpecificExt2[48];
} PACK_STRUCT tEplIdentResponse;
typedef struct {
// Offset 18
- BYTE m_le_bNmtCommandId;
- BYTE m_le_bRes1;
- BYTE m_le_abNmtCommandData[32];
+ u8 m_le_bNmtCommandId;
+ u8 m_le_bRes1;
+ u8 m_le_abNmtCommandData[32];
} PACK_STRUCT tEplNmtCommandService;
typedef struct {
- BYTE m_le_bReserved;
- BYTE m_le_bTransactionId;
- BYTE m_le_bFlags;
- BYTE m_le_bCommandId;
- WORD m_le_wSegmentSize;
- WORD m_le_wReserved;
- BYTE m_le_abCommandData[8]; // just reserve a minimum number of bytes as a placeholder
+ u8 m_le_bReserved;
+ u8 m_le_bTransactionId;
+ u8 m_le_bFlags;
+ u8 m_le_bCommandId;
+ u16 m_le_wSegmentSize;
+ u16 m_le_wReserved;
+ u8 m_le_abCommandData[8]; // just reserve a minimum number of bytes as a placeholder
} PACK_STRUCT tEplAsySdoCom;
// asynchronous SDO Sequence Header
typedef struct {
- BYTE m_le_bRecSeqNumCon;
- BYTE m_le_bSendSeqNumCon;
- BYTE m_le_abReserved[2];
+ u8 m_le_bRecSeqNumCon;
+ u8 m_le_bSendSeqNumCon;
+ u8 m_le_abReserved[2];
tEplAsySdoCom m_le_abSdoSeqPayload;
} PACK_STRUCT tEplAsySdoSeq;
typedef struct {
// Offset 18
- BYTE m_le_bNmtCommandId;
- BYTE m_le_bTargetNodeId;
- BYTE m_le_abNmtCommandData[32];
+ u8 m_le_bNmtCommandId;
+ u8 m_le_bTargetNodeId;
+ u8 m_le_abNmtCommandData[32];
} PACK_STRUCT tEplNmtRequestService;
@@ -281,14 +281,14 @@ typedef union {
tEplNmtCommandService m_NmtCommandService;
tEplNmtRequestService m_NmtRequestService;
tEplAsySdoSeq m_SdoSequenceFrame;
- BYTE m_le_abPayload[256 /*D_NMT_ASndTxMaxPayload_U16
+ u8 m_le_abPayload[256 /*D_NMT_ASndTxMaxPayload_U16
/ D_NMT_ASndRxMaxPayload_U16 */ ];
} tEplAsndPayload;
typedef struct {
// Offset 17
- BYTE m_le_bServiceId;
+ u8 m_le_bServiceId;
// Offset 18
tEplAsndPayload m_Payload;
@@ -306,17 +306,17 @@ typedef union {
typedef struct {
// Offset 0
- BYTE m_be_abDstMac[6]; // MAC address of the addressed nodes
+ u8 m_be_abDstMac[6]; // MAC address of the addressed nodes
// Offset 6
- BYTE m_be_abSrcMac[6]; // MAC address of the transmitting node
+ u8 m_be_abSrcMac[6]; // MAC address of the transmitting node
// Offset 12
- WORD m_be_wEtherType; // Ethernet message type (big endian)
+ u16 m_be_wEtherType; // Ethernet message type (big endian)
// Offset 14
- BYTE m_le_bMessageType; // EPL message type
+ u8 m_le_bMessageType; // EPL message type
// Offset 15
- BYTE m_le_bDstNodeId; // EPL node ID of the addressed nodes
+ u8 m_le_bDstNodeId; // EPL node ID of the addressed nodes
// Offset 16
- BYTE m_le_bSrcNodeId; // EPL node ID of the transmitting node
+ u8 m_le_bSrcNodeId; // EPL node ID of the transmitting node
// Offset 17
tEplFrameData m_Data;
diff --git a/drivers/staging/epl/EplIdentu.c b/drivers/staging/epl/EplIdentu.c
index ce59ef09ccd..93d5a40a2f7 100644
--- a/drivers/staging/epl/EplIdentu.c
+++ b/drivers/staging/epl/EplIdentu.c
@@ -138,7 +138,7 @@ static tEplIdentuInstance EplIdentuInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p);
//=========================================================================//
// //
@@ -164,7 +164,7 @@ static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p);
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuInit()
+tEplKernel EplIdentuInit(void)
{
tEplKernel Ret;
@@ -191,7 +191,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuInit()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuAddInstance()
+tEplKernel EplIdentuAddInstance(void)
{
tEplKernel Ret;
@@ -228,7 +228,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuAddInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuDelInstance()
+tEplKernel EplIdentuDelInstance(void)
{
tEplKernel Ret;
@@ -263,7 +263,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuDelInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplIdentuReset()
+tEplKernel EplIdentuReset(void)
{
tEplKernel Ret;
int iIndex;
@@ -300,9 +300,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplIdentuReset()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse **
- ppIdentResponse_p)
+tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse **ppIdentResponse_p)
{
tEplKernel Ret;
@@ -338,9 +337,8 @@ tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
- tEplIdentuCbResponse
- pfnCbResponse_p)
+tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentuCbResponse pfnCbResponse_p)
{
tEplKernel Ret;
@@ -388,9 +386,9 @@ tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void)
+u32 EplIdentuGetRunningRequests(void)
{
- DWORD dwReqs = 0;
+ u32 dwReqs = 0;
unsigned int uiIndex;
for (uiIndex = 0; uiIndex < 32; uiIndex++) {
@@ -426,7 +424,7 @@ EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplIdentuCbIdentResponse(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplIdentuCbIdentResponse(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiNodeId;
diff --git a/drivers/staging/epl/EplInc.h b/drivers/staging/epl/EplInc.h
index 77f93d14416..f91797a3687 100644
--- a/drivers/staging/epl/EplInc.h
+++ b/drivers/staging/epl/EplInc.h
@@ -140,8 +140,8 @@
// IEEE 1588 conformant net time structure
typedef struct {
- DWORD m_dwSec;
- DWORD m_dwNanoSec;
+ u32 m_dwSec;
+ u32 m_dwNanoSec;
} tEplNetTime;
@@ -154,8 +154,8 @@ typedef struct {
// -------------------------------------------------------------------------
#define EPL_SPEC_VERSION 0x20 // ETHERNET Powerlink V. 2.0
-#define EPL_STACK_VERSION(ver,rev,rel) ((((DWORD)(ver)) & 0xFF)|((((DWORD)(rev))&0xFF)<<8)|(((DWORD)(rel))<<16))
-#define EPL_OBJ1018_VERSION(ver,rev,rel) ((((DWORD)(ver))<<16) |(((DWORD)(rev))&0xFFFF))
+#define EPL_STACK_VERSION(ver,rev,rel) ((((u32)(ver)) & 0xFF)|((((u32)(rev))&0xFF)<<8)|(((u32)(rel))<<16))
+#define EPL_OBJ1018_VERSION(ver,rev,rel) ((((u32)(ver))<<16) |(((u32)(rev))&0xFFFF))
#define EPL_STRING_VERSION(ver,rev,rel) "V" #ver "." #rev " r" #rel
#include "EplVersion.h"
@@ -236,21 +236,6 @@ typedef struct {
#define tabentries(a) (sizeof(a)/sizeof(*(a)))
#endif
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-// definitions for DLL export
-#if ((DEV_SYSTEM == _DEV_WIN32_) || (DEV_SYSTEM == _DEV_WIN_CE_)) && defined (COP_LIB)
-
-#define EPLDLLEXPORT __declspec (dllexport)
-
-#else
-
-#define EPLDLLEXPORT
-
-#endif
-
// ============================================================================
// common debug macros
// ============================================================================
diff --git a/drivers/staging/epl/EplInstDef.h b/drivers/staging/epl/EplInstDef.h
index 89efbf27826..29ab7fb7888 100644
--- a/drivers/staging/epl/EplInstDef.h
+++ b/drivers/staging/epl/EplInstDef.h
@@ -71,6 +71,8 @@
#ifndef _EPLINSTDEF_H_
#define _EPLINSTDEF_H_
+#include <linux/kernel.h>
+
// =========================================================================
// types and macros for generating instances
// =========================================================================
@@ -83,8 +85,8 @@ typedef enum {
//------------------------------------------------------------------------------------------
-typedef void MEM *tEplPtrInstance;
-typedef BYTE tEplInstanceHdl;
+typedef void *tEplPtrInstance;
+typedef u8 tEplInstanceHdl;
// define const for illegale values
#define CCM_ILLINSTANCE NULL
@@ -99,8 +101,6 @@ typedef BYTE tEplInstanceHdl;
//--------------------------------------------------------------------------------------
// memory attributes for instance table
-#define INST_NEAR // faster access to variables
-#define INST_FAR // variables wich have to located in xdata
#define STATIC // prevent warnings for variables with same name
#define INSTANCE_TYPE_BEGIN typedef struct {
@@ -117,12 +117,12 @@ typedef BYTE tEplInstanceHdl;
#define CCM_DECL_INSTANCE_HDL_ tEplInstanceHdl InstanceHandle,
// macros for declaration of pointer to instance handle within function header or prototype of API functions
-#define CCM_DECL_PTR_INSTANCE_HDL tEplInstanceHdl MEM* pInstanceHandle
-#define CCM_DECL_PTR_INSTANCE_HDL_ tEplInstanceHdl MEM* pInstanceHandle,
+#define CCM_DECL_PTR_INSTANCE_HDL tEplInstanceHdl *pInstanceHandle
+#define CCM_DECL_PTR_INSTANCE_HDL_ tEplInstanceHdl *pInstanceHandle,
// macros for declaration instance as lokacl variable within functions
-#define CCM_DECL_INSTANCE_PTR_LOCAL tCcmInstanceInfo MEM* pInstance;
-#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL tEplInstanceHdl MEM* pInstanceHandle;
+#define CCM_DECL_INSTANCE_PTR_LOCAL tCcmInstanceInfo *pInstance;
+#define CCM_DECL_PTR_INSTANCE_HDL_LOCAL tEplInstanceHdl *pInstanceHandle;
// reference:
@@ -163,10 +163,10 @@ typedef BYTE tEplInstanceHdl;
//--------------------------------------------------------------------------------------
// macros for declaration within the function header, prototype or local var list
- // Declaration of pointers within function paramater list must defined as void MEM*
+ // Declaration of pointers within function paramater list must defined as void *
// pointer.
-#define EPL_MCO_DECL_INSTANCE_PTR void MEM* pInstance
-#define EPL_MCO_DECL_INSTANCE_PTR_ void MEM* pInstance,
+#define EPL_MCO_DECL_INSTANCE_PTR void *pInstance
+#define EPL_MCO_DECL_INSTANCE_PTR_ void *pInstance,
#define EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplPtrInstance pInstance;
// macros for reference of pointer to instance
@@ -191,8 +191,8 @@ typedef BYTE tEplInstanceHdl;
ASSERT (((tEplPtrInstance)pInstance)->m_InstState == kStateUsed);
// macros for declaration of pointer to instance pointer
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR void MEM* MEM* pInstancePtr
-#define EPL_MCO_DECL_PTR_INSTANCE_PTR_ void MEM* MEM* pInstancePtr,
+#define EPL_MCO_DECL_PTR_INSTANCE_PTR void **pInstancePtr
+#define EPL_MCO_DECL_PTR_INSTANCE_PTR_ void **pInstancePtr,
// macros for reference of pointer to instance pointer
// These macros are used for parameter passing to called function.
@@ -212,12 +212,12 @@ typedef BYTE tEplInstanceHdl;
// this macro deletes all instance entries as unused
#define EPL_MCO_DELETE_INSTANCE_TABLE() \
{ \
- tEplInstanceInfo MEM* pInstance = &aEplInstanceTable_g[0]; \
- tFastByte InstNumber = 0; \
- tFastByte i = EPL_MAX_INSTANCES; \
+ tEplInstanceInfo * pInstance = &aEplInstanceTable_g[0]; \
+ tFastByte InstNumber = 0; \
+ tFastByte i = EPL_MAX_INSTANCES; \
do { \
- pInstance->m_InstState = (BYTE) kStateUnused; \
- pInstance->m_bInstIndex = (BYTE) InstNumber; \
+ pInstance->m_InstState = (u8) kStateUnused; \
+ pInstance->m_bInstIndex = (u8) InstNumber; \
pInstance++; InstNumber++; i--; \
} while (i != 0); \
}
@@ -230,8 +230,8 @@ typedef BYTE tEplInstanceHdl;
static tEplPtrInstance GetInstancePtr (tEplInstanceHdl InstHandle_p) { \
return &aEplInstanceTable_g[InstHandle_p]; } \
static tEplPtrInstance GetFreeInstance (void) { \
- tEplInstanceInfo MEM* pInstance = &aEplInstanceTable_g[0]; \
- tFastByte i = EPL_MAX_INSTANCES; \
+ tEplInstanceInfo *pInstance = &aEplInstanceTable_g[0]; \
+ tFastByte i = EPL_MAX_INSTANCES; \
do { if (pInstance->m_InstState != kStateUsed) { \
return (tEplPtrInstance) pInstance; } \
pInstance++; i--; } \
@@ -240,13 +240,13 @@ typedef BYTE tEplInstanceHdl;
// this macro defines the instance table. Each entry is reserved for an instance of CANopen.
#define EPL_MCO_DECL_INSTANCE_VAR() \
- static tEplInstanceInfo MEM aEplInstanceTable_g [EPL_MAX_INSTANCES];
+ static tEplInstanceInfo aEplInstanceTable_g [EPL_MAX_INSTANCES];
// this macro defines member variables in instance table which are needed in
// all modules of Epl stack
#define EPL_MCO_DECL_INSTANCE_MEMBER() \
- STATIC BYTE m_InstState; \
- STATIC BYTE m_bInstIndex;
+ STATIC u8 m_InstState; \
+ STATIC u8 m_bInstIndex;
#define EPL_MCO_INSTANCE_PARAM_IDX_() EPL_MCO_INSTANCE_PARAM_ (EPL_MCO_GLB_VAR (m_bInstIndex))
#define EPL_MCO_INSTANCE_PARAM_IDX() EPL_MCO_INSTANCE_PARAM (EPL_MCO_GLB_VAR (m_bInstIndex))
@@ -254,8 +254,6 @@ typedef BYTE tEplInstanceHdl;
#else // only one instance is used
// Memory attributes for instance table.
-#define INST_NEAR NEAR // faster access to variables
-#define INST_FAR MEM // variables wich have to located in xdata
#define STATIC static // prevent warnings for variables with same name
#define INSTANCE_TYPE_BEGIN
@@ -359,18 +357,6 @@ typedef BYTE tEplInstanceHdl;
#endif
-/*
-#if (CDRV_MAX_INSTANCES > 1)
-
- #define CDRV_REENTRANT REENTRANT
-
-#else
-
- #define CDRV_REENTRANT
-
-#endif
-*/
-
#endif // _EPLINSTDEF_H_
// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
diff --git a/drivers/staging/epl/EplNmt.h b/drivers/staging/epl/EplNmt.h
index 4c11e5bc74a..e351b55eea6 100644
--- a/drivers/staging/epl/EplNmt.h
+++ b/drivers/staging/epl/EplNmt.h
@@ -185,7 +185,7 @@ typedef struct {
typedef struct {
unsigned int m_uiNodeId; // NodeId
tEplNmtState m_NmtState; // NMT state (remember distinguish between MN / CN)
- WORD m_wErrorCode; // EPL error code in case of NMT state NotActive
+ u16 m_wErrorCode; // EPL error code in case of NMT state NotActive
} tEplHeartbeatEvent;
diff --git a/drivers/staging/epl/EplNmtCnu.c b/drivers/staging/epl/EplNmtCnu.c
index f2f46da08c7..c27ca8f8c2f 100644
--- a/drivers/staging/epl/EplNmtCnu.c
+++ b/drivers/staging/epl/EplNmtCnu.c
@@ -108,9 +108,9 @@ static tEplNmtCnuInstance EplNmtCnuInstance_g;
static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p);
-static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p);
+static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p);
-static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p);
//=========================================================================//
// //
@@ -135,7 +135,7 @@ static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p);
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
+tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p)
{
tEplKernel Ret;
@@ -161,7 +161,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
+tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p)
{
tEplKernel Ret;
@@ -201,7 +201,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
+tEplKernel EplNmtCnuDelInstance(void)
{
tEplKernel Ret;
@@ -234,9 +234,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
- tEplNmtCommand
- NmtCommand_p)
+tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
+ tEplNmtCommand NmtCommand_p)
{
tEplKernel Ret;
tEplFrameInfo NmtRequestFrameInfo;
@@ -249,15 +248,15 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
EPL_MEMSET(&NmtRequestFrame.m_be_abSrcMac[0], 0x00, sizeof(NmtRequestFrame.m_be_abSrcMac)); // set by DLL
AmiSetWordToBe(&NmtRequestFrame.m_be_wEtherType,
EPL_C_DLL_ETHERTYPE_EPL);
- AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (BYTE) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
+ AmiSetByteToLe(&NmtRequestFrame.m_le_bDstNodeId, (u8) EPL_C_ADR_MN_DEF_NODE_ID); // node id of the MN
AmiSetByteToLe(&NmtRequestFrame.m_le_bMessageType,
- (BYTE) kEplMsgTypeAsnd);
+ (u8) kEplMsgTypeAsnd);
AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_le_bServiceId,
- (BYTE) kEplDllAsndNmtRequest);
+ (u8) kEplDllAsndNmtRequest);
AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.
m_NmtRequestService.m_le_bNmtCommandId,
- (BYTE) NmtCommand_p);
- AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (BYTE) uiNodeId_p); // target for the nmt command
+ (u8) NmtCommand_p);
+ AmiSetByteToLe(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.m_le_bTargetNodeId, (u8) uiNodeId_p); // target for the nmt command
EPL_MEMSET(&NmtRequestFrame.m_Data.m_Asnd.m_Payload.m_NmtRequestService.
m_le_abNmtCommandData[0], 0x00,
sizeof(NmtRequestFrame.m_Data.m_Asnd.m_Payload.
@@ -297,9 +296,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
- pfnEplNmtCheckEventCb_p)
+tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p)
{
tEplKernel Ret;
@@ -335,7 +332,7 @@ EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
// State:
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtCnuCommandCb(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplNmtCnuCommandCb(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
tEplNmtCommand NmtCommand;
@@ -676,18 +673,18 @@ static tEplNmtCommand EplNmtCnuGetNmtCommand(tEplFrameInfo * pFrameInfo_p)
// State:
//
//---------------------------------------------------------------------------
-static BOOL EplNmtCnuNodeIdList(BYTE * pbNmtCommandDate_p)
+static BOOL EplNmtCnuNodeIdList(u8 * pbNmtCommandDate_p)
{
BOOL fNodeIdInList;
unsigned int uiByteOffset;
- BYTE bBitOffset;
- BYTE bNodeListByte;
+ u8 bBitOffset;
+ u8 bNodeListByte;
// get byte-offset of the own nodeid in NodeIdList
// devide though 8
uiByteOffset = (unsigned int)(EplNmtCnuInstance_g.m_uiNodeId >> 3);
// get bitoffset
- bBitOffset = (BYTE) EplNmtCnuInstance_g.m_uiNodeId % 8;
+ bBitOffset = (u8) EplNmtCnuInstance_g.m_uiNodeId % 8;
bNodeListByte = AmiGetByteFromLe(&pbNmtCommandDate_p[uiByteOffset]);
if ((bNodeListByte & bBitOffset) == 0) {
diff --git a/drivers/staging/epl/EplNmtMnu.c b/drivers/staging/epl/EplNmtMnu.c
index 4ed0b6ce487..d19434f5f6f 100644
--- a/drivers/staging/epl/EplNmtMnu.c
+++ b/drivers/staging/epl/EplNmtMnu.c
@@ -94,8 +94,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -211,8 +211,8 @@ typedef struct {
tEplTimerHdl m_TimerHdlStatReq; // timer to delay StatusRequests and IdentRequests
tEplTimerHdl m_TimerHdlLonger; // 2nd timer for NMT command EnableReadyToOp and CheckCommunication
tEplNmtMnuNodeState m_NodeState; // internal node state (kind of sub state of NMT state)
- DWORD m_dwNodeCfg; // subindex from 0x1F81
- WORD m_wFlags; // flags: CN is being accessed isochronously
+ u32 m_dwNodeCfg; // subindex from 0x1F81
+ u16 m_wFlags; // flags: CN is being accessed isochronously
} tEplNmtMnuNodeInfo;
@@ -224,8 +224,8 @@ typedef struct {
unsigned long m_ulStatusRequestDelay; // in [ms] (object 0x1006 * EPL_C_NMT_STATREQ_CYCLE)
unsigned long m_ulTimeoutReadyToOp; // in [ms] (object 0x1F89/5)
unsigned long m_ulTimeoutCheckCom; // in [ms] (object 0x1006 * MultiplexedCycleCount)
- WORD m_wFlags; // global flags
- DWORD m_dwNmtStartup; // object 0x1F80 NMT_StartUp_U32
+ u16 m_wFlags; // global flags
+ u32 m_dwNmtStartup; // object 0x1F80 NMT_StartUp_U32
tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent;
tEplNmtMnuCbBootEvent m_pfnCbBootEvent;
@@ -241,20 +241,18 @@ static tEplNmtMnuInstance EplNmtMnuInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p);
+static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p);
-static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse *
- pIdentResponse_p);
+static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse *pIdentResponse_p);
-static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
- tEplStatusResponse *
- pStatusResponse_p);
+static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusResponse *pStatusResponse_p);
static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
tEplNmtMnuNodeInfo * pNodeInfo_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtState LocalNmtState_p);
static tEplKernel EplNmtMnuStartBootStep1(void);
@@ -273,7 +271,7 @@ static tEplKernel EplNmtMnuStartNodes(void);
static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtMnuIntNodeEvent
NodeEvent_p);
@@ -380,7 +378,7 @@ tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
//
//---------------------------------------------------------------------------
-tEplKernel EplNmtMnuDelInstance()
+tEplKernel EplNmtMnuDelInstance(void)
{
tEplKernel Ret;
@@ -419,7 +417,7 @@ tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
{
tEplKernel Ret = kEplSuccessful;
tEplFrameInfo FrameInfo;
- BYTE abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
+ u8 abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
tEplFrame *pFrame = (tEplFrame *) abBuffer;
BOOL fSoftDeleteNode = FALSE;
@@ -439,11 +437,11 @@ tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
// build frame
EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer));
- AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (BYTE) uiNodeId_p);
+ AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (u8) uiNodeId_p);
AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
- (BYTE) kEplDllAsndNmtCommand);
+ (u8) kEplDllAsndNmtCommand);
AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
- m_le_bNmtCommandId, (BYTE) NmtCommand_p);
+ m_le_bNmtCommandId, (u8) NmtCommand_p);
if ((pNmtCommandData_p != NULL) && (uiDataSize_p > 0)) { // copy command data to frame
EPL_MEMCPY(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
m_le_abNmtCommandData[0], pNmtCommandData_p,
@@ -574,8 +572,8 @@ tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
tEplKernel Ret = kEplSuccessful;
tEplNmtMnuIntNodeEvent NodeEvent;
tEplObdSize ObdSize;
- BYTE bNmtState;
- WORD wErrorCode = EPL_E_NO_ERROR;
+ u8 bNmtState;
+ u16 wErrorCode = EPL_E_NO_ERROR;
if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST)) {
Ret = kEplInvalidNodeId;
@@ -645,8 +643,7 @@ tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p)
+tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -676,7 +673,7 @@ tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
// build the configuration with infos from OD
case kEplNmtGsResetConfiguration:
{
- DWORD dwTimeout;
+ u32 dwTimeout;
tEplObdSize ObdSize;
// read object 0x1F80 NMT_StartUp_U32
@@ -788,7 +785,7 @@ tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
// node processes only async frames
case kEplNmtMsPreOperational1:
{
- DWORD dwTimeout;
+ u32 dwTimeout;
tEplTimerArg TimerArg;
tEplObdSize ObdSize;
tEplEvent Event;
@@ -928,7 +925,7 @@ tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
+tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -949,7 +946,7 @@ tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
+tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p)
{
tEplKernel Ret;
@@ -970,7 +967,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
EPL_NMTMNU_TIMERARG_NODE_MASK);
if (uiNodeId != 0) {
tEplObdSize ObdSize;
- BYTE bNmtState;
+ u8 bNmtState;
tEplNmtMnuNodeInfo *pNodeInfo;
pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId);
@@ -1150,7 +1147,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
tEplFrame *pFrame = (tEplFrame *) pEvent_p->m_pArg;
unsigned int uiNodeId;
tEplNmtCommand NmtCommand;
- BYTE bNmtState;
+ u8 bNmtState;
uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
NmtCommand =
@@ -1162,30 +1159,30 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
switch (NmtCommand) {
case kEplNmtCmdStartNode:
bNmtState =
- (BYTE) (kEplNmtCsOperational & 0xFF);
+ (u8) (kEplNmtCsOperational & 0xFF);
break;
case kEplNmtCmdStopNode:
- bNmtState = (BYTE) (kEplNmtCsStopped & 0xFF);
+ bNmtState = (u8) (kEplNmtCsStopped & 0xFF);
break;
case kEplNmtCmdEnterPreOperational2:
bNmtState =
- (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+ (u8) (kEplNmtCsPreOperational2 & 0xFF);
break;
case kEplNmtCmdEnableReadyToOperate:
// d.k. do not change expected node state, because of DS 1.0.0 7.3.1.2.1 Plain NMT State Command
// and because node may not change NMT state within EPL_C_NMT_STATE_TOLERANCE
bNmtState =
- (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
+ (u8) (kEplNmtCsPreOperational2 & 0xFF);
break;
case kEplNmtCmdResetNode:
case kEplNmtCmdResetCommunication:
case kEplNmtCmdResetConfiguration:
case kEplNmtCmdSwReset:
- bNmtState = (BYTE) (kEplNmtCsNotActive & 0xFF);
+ bNmtState = (u8) (kEplNmtCsNotActive & 0xFF);
// EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown
// after next unresponded IdentRequest/StatusRequest
break;
@@ -1258,11 +1255,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
- *puiMandatorySlaveCount_p,
- unsigned int
- *puiSignalSlaveCount_p,
- WORD * pwFlags_p)
+tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int *puiMandatorySlaveCount_p,
+ unsigned int *puiSignalSlaveCount_p,
+ u16 *pwFlags_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1296,7 +1291,7 @@ tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
//
//---------------------------------------------------------------------------
/*
-DWORD EplNmtMnuGetRunningTimerStatReq(void)
+u32 EplNmtMnuGetRunningTimerStatReq(void)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiIndex;
@@ -1347,7 +1342,7 @@ Exit:
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
+static tEplKernel EplNmtMnuCbNmtRequest(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1371,9 +1366,8 @@ static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse *
- pIdentResponse_p)
+static tEplKernel EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse *pIdentResponse_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1382,8 +1376,8 @@ static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
kEplNmtMnuIntNodeEventNoIdentResponse);
} else { // node answered IdentRequest
tEplObdSize ObdSize;
- DWORD dwDevType;
- WORD wErrorCode = EPL_E_NO_ERROR;
+ u32 dwDevType;
+ u16 wErrorCode = EPL_E_NO_ERROR;
tEplNmtState NmtState =
(tEplNmtState) (AmiGetByteFromLe
(&pIdentResponse_p->
@@ -1431,9 +1425,8 @@ static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
- tEplStatusResponse *
- pStatusResponse_p)
+static tEplKernel EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusResponse *pStatusResponse_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -1473,7 +1466,7 @@ static tEplKernel EplNmtMnuStartBootStep1(void)
tEplKernel Ret = kEplSuccessful;
unsigned int uiSubIndex;
unsigned int uiLocalNodeId;
- DWORD dwNodeCfg;
+ u32 dwNodeCfg;
tEplObdSize ObdSize;
// $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32
@@ -1633,7 +1626,7 @@ static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
{
tEplKernel Ret = kEplSuccessful;
tEplDllNodeInfo DllNodeInfo;
- DWORD dwNodeCfg;
+ u32 dwNodeCfg;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -1782,7 +1775,7 @@ static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
tEplNmtMnuNodeInfo * pNodeInfo_p)
{
tEplKernel Ret = kEplSuccessful;
- DWORD dwNodeCfg;
+ u32 dwNodeCfg;
tEplTimerArg TimerArg;
dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
@@ -1916,7 +1909,7 @@ static tEplKernel EplNmtMnuStartNodes(void)
static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtMnuIntNodeEvent
NodeEvent_p)
{
@@ -1934,7 +1927,7 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
switch (NodeEvent_p) {
case kEplNmtMnuIntNodeEventIdentResponse:
{
- BYTE bNmtState;
+ u8 bNmtState;
EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
uiNodeId_p,
@@ -1961,7 +1954,7 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
}
// update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2)
- bNmtState = (BYTE) (kEplNmtCsPreOperational1 & 0xFF);
+ bNmtState = (u8) (kEplNmtCsPreOperational1 & 0xFF);
Ret =
EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
1);
@@ -2441,11 +2434,11 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
case kEplNmtMnuIntNodeEventNmtCmdSent:
{
- BYTE bNmtState;
+ u8 bNmtState;
// update expected NMT state with the one that results
// from the sent NMT command
- bNmtState = (BYTE) (NodeNmtState_p & 0xFF);
+ bNmtState = (u8) (NodeNmtState_p & 0xFF);
// write object 0x1F8F NMT_MNNodeExpState_AU8
Ret =
@@ -2630,13 +2623,13 @@ static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
tEplNmtMnuNodeInfo * pNodeInfo_p,
tEplNmtState NodeNmtState_p,
- WORD wErrorCode_p,
+ u16 wErrorCode_p,
tEplNmtState LocalNmtState_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdSize ObdSize;
- BYTE bNmtState;
- BYTE bNmtStatePrev;
+ u8 bNmtState;
+ u8 bNmtStatePrev;
tEplNmtState ExpNmtState;
ObdSize = 1;
@@ -2647,8 +2640,8 @@ static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
}
// compute expected NMT state
ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS);
- // compute BYTE of current NMT state
- bNmtState = ((BYTE) NodeNmtState_p & 0xFF);
+ // compute u8 of current NMT state
+ bNmtState = ((u8) NodeNmtState_p & 0xFF);
if (ExpNmtState == kEplNmtCsNotActive) { // ignore the current state, because the CN shall be not active
Ret = kEplReject;
@@ -2706,7 +2699,7 @@ static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
} else if ((ExpNmtState != NodeNmtState_p)
&& !((ExpNmtState == kEplNmtCsPreOperational1)
&& (NodeNmtState_p == kEplNmtCsPreOperational2))) { // CN is not in expected NMT state (without the exceptions above)
- WORD wbeErrorCode;
+ u16 wbeErrorCode;
if ((pNodeInfo_p->
m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0) {
diff --git a/drivers/staging/epl/EplNmtk.c b/drivers/staging/epl/EplNmtk.c
index 4e2d0e15e94..609d5c02bde 100644
--- a/drivers/staging/epl/EplNmtk.c
+++ b/drivers/staging/epl/EplNmtk.c
@@ -88,8 +88,8 @@
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -107,12 +107,12 @@ void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
// struct for instance table
INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
-STATIC volatile tEplNmtState INST_FAR m_NmtState;
-STATIC volatile BOOL INST_FAR m_fEnableReadyToOperate;
-STATIC volatile BOOL INST_FAR m_fAppReadyToOperate;
-STATIC volatile BOOL INST_FAR m_fTimerMsPreOp2;
-STATIC volatile BOOL INST_FAR m_fAllMandatoryCNIdent;
-STATIC volatile BOOL INST_FAR m_fFrozen;
+STATIC volatile tEplNmtState m_NmtState;
+STATIC volatile BOOL m_fEnableReadyToOperate;
+STATIC volatile BOOL m_fAppReadyToOperate;
+STATIC volatile BOOL m_fTimerMsPreOp2;
+STATIC volatile BOOL m_fAllMandatoryCNIdent;
+STATIC volatile BOOL m_fFrozen;
INSTANCE_TYPE_END
//---------------------------------------------------------------------------
@@ -121,7 +121,7 @@ INSTANCE_TYPE_END
// This macro replace the unspecific pointer to an instance through
// the modul specific type for the local instance table. This macro
// must defined in each modul.
-//#define tEplPtrInstance tEplInstanceInfo MEM*
+//#define tEplPtrInstance tEplInstanceInfo*
EPL_MCO_DECL_INSTANCE_VAR()
//---------------------------------------------------------------------------
// local function prototypes
@@ -163,7 +163,7 @@ EPL_MCO_DEFINE_INSTANCE_FCT()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
tEplKernel Ret;
@@ -189,7 +189,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
//tEplEvent Event;
@@ -258,7 +258,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
//
//---------------------------------------------------------------------------
#if (EPL_USE_DELETEINST_FUNC != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
tEplKernel Ret = kEplSuccessful;
// check for all API function if instance is valid
@@ -296,8 +296,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplEvent * pEvent_p)
+tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplNmtState OldNmtState;
@@ -1804,8 +1803,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC
-EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
+tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR)
{
tEplNmtState NmtState;
diff --git a/drivers/staging/epl/EplNmtkCal.c b/drivers/staging/epl/EplNmtkCal.c
index 4ad71a71e01..4453c09838c 100644
--- a/drivers/staging/epl/EplNmtkCal.c
+++ b/drivers/staging/epl/EplNmtkCal.c
@@ -69,8 +69,6 @@
****************************************************************************/
-#include "kernel/EplNmtkCal.h"
-
// TODO: init function needed to prepare EplNmtkGetNmtState for
// io-controll-call from EplNmtuCal-Modul
diff --git a/drivers/staging/epl/EplNmtu.c b/drivers/staging/epl/EplNmtu.c
index 3de16a1eff5..9ac2e8e4845 100644
--- a/drivers/staging/epl/EplNmtu.c
+++ b/drivers/staging/epl/EplNmtu.c
@@ -132,7 +132,7 @@ static tEplNmtuInstance EplNmtuInstance_g;
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit()
+tEplKernel EplNmtuInit(void)
{
tEplKernel Ret;
@@ -158,7 +158,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance()
+tEplKernel EplNmtuAddInstance(void)
{
tEplKernel Ret;
@@ -187,7 +187,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance()
+tEplKernel EplNmtuDelInstance(void)
{
tEplKernel Ret;
@@ -219,7 +219,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
+tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
{
tEplKernel Ret;
tEplEvent Event;
@@ -253,7 +253,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState()
+tEplNmtState EplNmtuGetNmtState(void)
{
tEplNmtState NmtState;
@@ -284,7 +284,7 @@ EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
+tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p)
{
tEplKernel Ret;
@@ -382,7 +382,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// node listens for EPL-Frames and check timeout
case kEplNmtCsNotActive:
{
- DWORD dwBuffer;
+ u32 dwBuffer;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -475,7 +475,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// node listens for EPL-Frames and check timeout
case kEplNmtMsNotActive:
{
- DWORD dwBuffer;
+ u32 dwBuffer;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -544,7 +544,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// node processes only async frames
case kEplNmtMsPreOperational1:
{
- DWORD dwBuffer = 0;
+ u32 dwBuffer = 0;
tEplObdSize ObdSize;
tEplTimerArg TimerArg;
@@ -664,9 +664,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback
- pfnEplNmtStateChangeCb_p)
+tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
{
tEplKernel Ret;
diff --git a/drivers/staging/epl/EplNmtuCal.c b/drivers/staging/epl/EplNmtuCal.c
index 4a29ef58bf9..92164c57ea1 100644
--- a/drivers/staging/epl/EplNmtuCal.c
+++ b/drivers/staging/epl/EplNmtuCal.c
@@ -119,7 +119,7 @@
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState()
+tEplNmtState EplNmtkCalGetNmtState(void)
{
tEplNmtState NmtState;
// for test direkt call for EplNmtkGetNmtState()
diff --git a/drivers/staging/epl/EplObd.c b/drivers/staging/epl/EplObd.c
index efbb1967a5d..1e463234d81 100644
--- a/drivers/staging/epl/EplObd.c
+++ b/drivers/staging/epl/EplObd.c
@@ -101,8 +101,8 @@
// struct for instance table
INSTANCE_TYPE_BEGIN EPL_MCO_DECL_INSTANCE_MEMBER()
-STATIC tEplObdInitParam INST_FAR m_ObdInitParam;
-STATIC tEplObdStoreLoadObjCallback INST_NEAR m_fpStoreLoadObjCallback;
+STATIC tEplObdInitParam m_ObdInitParam;
+STATIC tEplObdStoreLoadObjCallback m_fpStoreLoadObjCallback;
INSTANCE_TYPE_END
// decomposition of float
@@ -119,11 +119,11 @@ typedef union {
// This macro replace the unspecific pointer to an instance through
// the modul specific type for the local instance table. This macro
// must defined in each modul.
-//#define tEplPtrInstance tEplInstanceInfo MEM*
+//#define tEplPtrInstance tEplInstanceInfo *
EPL_MCO_DECL_INSTANCE_VAR()
-BYTE MEM abEplObdTrashObject_g[8];
+u8 abEplObdTrashObject_g[8];
//---------------------------------------------------------------------------
// local function prototypes
@@ -133,7 +133,7 @@ EPL_MCO_DEFINE_INSTANCE_FCT()
static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdCallback fpCallback_p,
- tEplObdCbParam MEM * pCbParam_p);
+ tEplObdCbParam *pCbParam_p);
static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p);
@@ -146,7 +146,7 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
#endif
static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
- tEplObdVarEntry MEM ** ppVarEntry_p);
+ tEplObdVarEntry **ppVarEntry_p);
static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
unsigned int uiIndex_p,
@@ -156,7 +156,7 @@ static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p);
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,
+static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
unsigned int uiIndex_p,
tEplObdEntryPtr * ppObdEntry_p);
@@ -170,17 +170,15 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdDir Direction_p);
static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
-static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
+static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p);
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdCbStoreParam MEM *
- pCbStoreParam_p);
+static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam *pCbStoreParam_p);
#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
-static void EplObdCopyObjectData(void MEM * pDstData_p,
+static void EplObdCopyObjectData(void *pDstData_p,
void *pSrcData_p,
tEplObdSize ObjSize_p, tEplObdType ObjType_p);
@@ -189,24 +187,22 @@ void *EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p);
static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
BOOL * pfEntryNumerical_p);
-static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- void **ppDstData_p,
- tEplObdSize Size_p,
- tEplObdEntryPtr * ppObdEntry_p,
- tEplObdSubEntryPtr * ppSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- tEplObdSize * pObdSize_p);
-
-static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pObdEntry_p,
- tEplObdSubEntryPtr pSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- void *pSrcData_p,
- void *pDstData_p,
- tEplObdSize ObdSize_p);
+static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ void **ppDstData_p,
+ tEplObdSize Size_p,
+ tEplObdEntryPtr *ppObdEntry_p,
+ tEplObdSubEntryPtr *ppSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ tEplObdSize *pObdSize_p);
+
+static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
+ tEplObdSubEntryPtr pSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ void *pSrcData_p,
+ void *pDstData_p,
+ tEplObdSize ObdSize_p);
//=========================================================================//
// //
@@ -228,8 +224,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM * pInitParam_p)
+tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
{
tEplKernel Ret;
@@ -261,9 +256,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM *
- pInitParam_p)
+tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p)
{
EPL_MCO_DECL_INSTANCE_PTR_LOCAL tEplKernel Ret;
@@ -308,7 +301,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
#if (EPL_USE_DELETEINST_FUNC != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
+tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
{
// check for all API function if instance is valid
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -341,18 +334,16 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
- void MEM *pDstData;
+ tEplObdCbParam CbParam;
+ void *pDstData;
tEplObdSize ObdSize;
Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
@@ -402,17 +393,15 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
+ tEplObdCbParam CbParam;
void *pSrcData;
tEplObdSize ObdSize;
@@ -487,9 +476,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdPart ObdPart_p,
- tEplObdDir Direction_p)
+tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
+ tEplObdDir Direction_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -587,12 +575,11 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
- tEplVarParam MEM * pVarParam_p)
+tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p)
{
tEplKernel Ret;
- tEplObdVarEntry MEM *pVarEntry;
+ tEplObdVarEntry *pVarEntry;
tEplVarParamValid VarValid;
tEplObdSubEntryPtr pSubindexEntry;
@@ -674,9 +661,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p)
{
tEplKernel Ret;
void *pData;
@@ -719,8 +705,7 @@ EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pUserOd_p)
+tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p)
{
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -749,10 +734,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdVarEntry MEM * pVarEntry_p,
- tEplObdType Type_p,
- tEplObdSize ObdSize_p)
+void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
+ tEplObdType Type_p, tEplObdSize ObdSize_p)
{
/*
#if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
@@ -803,9 +786,8 @@ EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p)
{
tEplKernel Ret;
tEplObdSize ObdSize;
@@ -845,11 +827,11 @@ EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
+unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
{
tEplKernel Ret;
tEplObdSize ObdSize;
- BYTE bNodeId;
+ u8 bNodeId;
bNodeId = 0;
ObdSize = sizeof(bNodeId);
@@ -882,22 +864,21 @@ EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p)
+tEplKernel EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p)
{
tEplKernel Ret;
tEplObdSize ObdSize;
- BYTE fHwBool;
- BYTE bNodeId;
+ u8 fHwBool;
+ u8 bNodeId;
// check Node Id
if (uiNodeId_p == EPL_C_ADR_INVALID) {
Ret = kEplInvalidNodeId;
goto Exit;
}
- bNodeId = (BYTE) uiNodeId_p;
- ObdSize = sizeof(BYTE);
+ bNodeId = (u8) uiNodeId_p;
+ ObdSize = sizeof(u8);
// write NodeId to OD entry
Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
EPL_OBD_NODE_ID_INDEX,
@@ -966,10 +947,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- BOOL * pfEntryNumerical_p)
+tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ BOOL *pfEntryNumerical_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
@@ -1018,16 +998,14 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
+ tEplObdCbParam CbParam;
void *pSrcData;
tEplObdSize ObdSize;
@@ -1091,7 +1069,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt8:
case kEplObdTypUInt8:
{
- AmiSetByteToLe(pDstData_p, *((BYTE *) pSrcData));
+ AmiSetByteToLe(pDstData_p, *((u8 *) pSrcData));
break;
}
@@ -1099,7 +1077,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt16:
case kEplObdTypUInt16:
{
- AmiSetWordToLe(pDstData_p, *((WORD *) pSrcData));
+ AmiSetWordToLe(pDstData_p, *((u16 *) pSrcData));
break;
}
@@ -1107,7 +1085,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt24:
case kEplObdTypUInt24:
{
- AmiSetDword24ToLe(pDstData_p, *((DWORD *) pSrcData));
+ AmiSetDword24ToLe(pDstData_p, *((u32 *) pSrcData));
break;
}
@@ -1116,7 +1094,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt32:
case kEplObdTypReal32:
{
- AmiSetDwordToLe(pDstData_p, *((DWORD *) pSrcData));
+ AmiSetDwordToLe(pDstData_p, *((u32 *) pSrcData));
break;
}
@@ -1124,7 +1102,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt40:
case kEplObdTypUInt40:
{
- AmiSetQword40ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword40ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1132,7 +1110,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt48:
case kEplObdTypUInt48:
{
- AmiSetQword48ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword48ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1140,7 +1118,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt56:
case kEplObdTypUInt56:
{
- AmiSetQword56ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword56ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1149,7 +1127,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt64:
case kEplObdTypReal64:
{
- AmiSetQword64ToLe(pDstData_p, *((QWORD *) pSrcData));
+ AmiSetQword64ToLe(pDstData_p, *((u64 *) pSrcData));
break;
}
@@ -1199,19 +1177,17 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
- tEplObdCbParam MEM CbParam;
- void MEM *pDstData;
+ tEplObdCbParam CbParam;
+ void *pDstData;
tEplObdSize ObdSize;
- QWORD qwBuffer;
+ u64 qwBuffer;
void *pBuffer = &qwBuffer;
Ret = EplObdWriteEntryPre(EPL_MCO_INSTANCE_PTR_
@@ -1242,7 +1218,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt8:
case kEplObdTypUInt8:
{
- *((BYTE *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
+ *((u8 *) pBuffer) = AmiGetByteFromLe(pSrcData_p);
break;
}
@@ -1250,7 +1226,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt16:
case kEplObdTypUInt16:
{
- *((WORD *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
+ *((u16 *) pBuffer) = AmiGetWordFromLe(pSrcData_p);
break;
}
@@ -1258,7 +1234,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt24:
case kEplObdTypUInt24:
{
- *((DWORD *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
+ *((u32 *) pBuffer) = AmiGetDword24FromLe(pSrcData_p);
break;
}
@@ -1267,7 +1243,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt32:
case kEplObdTypReal32:
{
- *((DWORD *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
+ *((u32 *) pBuffer) = AmiGetDwordFromLe(pSrcData_p);
break;
}
@@ -1275,7 +1251,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt40:
case kEplObdTypUInt40:
{
- *((QWORD *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword40FromLe(pSrcData_p);
break;
}
@@ -1283,7 +1259,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt48:
case kEplObdTypUInt48:
{
- *((QWORD *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword48FromLe(pSrcData_p);
break;
}
@@ -1291,7 +1267,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypInt56:
case kEplObdTypUInt56:
{
- *((QWORD *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword56FromLe(pSrcData_p);
break;
}
@@ -1300,7 +1276,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
case kEplObdTypUInt64:
case kEplObdTypReal64:
{
- *((QWORD *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
+ *((u64 *) pBuffer) = AmiGetQword64FromLe(pSrcData_p);
break;
}
@@ -1345,10 +1321,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess * pAccessTyp_p)
+tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
@@ -1388,10 +1363,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM ** ppVarEntry_p)
+tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret;
@@ -1435,11 +1409,11 @@ EPL_MCO_DECL_INSTANCE_FCT()
//---------------------------------------------------------------------------
static tEplKernel EplObdCallObjectCallback(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdCallback fpCallback_p,
- tEplObdCbParam MEM * pCbParam_p)
+ tEplObdCbParam *pCbParam_p)
{
tEplKernel Ret;
- tEplObdCallback MEM fpCallback;
+ tEplObdCallback fpCallback;
// check for all API function if instance is valid
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -1481,7 +1455,7 @@ static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)
{
tEplObdSize DataSize;
- void MEM *pData;
+ void *pData;
// If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
// then the current pointer is always NULL. The function
@@ -1490,8 +1464,7 @@ static tEplObdSize EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)
if (pSubIndexEntry_p->m_Type == kEplObdTypVString) {
// The pointer to current value can be received from EplObdGetObjectCurrentPtr()
- pData =
- ((void MEM *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
+ pData = ((void *)EplObdGetObjectCurrentPtr(pSubIndexEntry_p));
if (pData != NULL) {
DataSize =
EplObdGetStrLen((void *)pData, DataSize,
@@ -1526,7 +1499,7 @@ static tEplObdSize EplObdGetStrLen(void *pObjData_p,
{
tEplObdSize StrLen = 0;
- BYTE *pbString;
+ u8 *pbString;
if (pObjData_p == NULL) {
goto Exit;
@@ -1763,18 +1736,18 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
case kEplObdTypInt64:
// switch to lower limit
- pRangeData = ((signed QWORD *)pRangeData) + 1;
+ pRangeData = ((signed u64 *)pRangeData) + 1;
// check if value is to low
- if (*((signed QWORD *)pData_p) < *((signed QWORD *)pRangeData)) {
+ if (*((signed u64 *)pData_p) < *((signed u64 *)pRangeData)) {
Ret = kEplObdValueTooLow;
break;
}
// switch to higher limit
- pRangeData = ((signed QWORD *)pRangeData) + 1;
+ pRangeData = ((signed u64 *)pRangeData) + 1;
// check if value is to high
- if (*((signed QWORD *)pData_p) > *((signed QWORD *)pRangeData)) {
+ if (*((signed u64 *)pData_p) > *((signed u64 *)pRangeData)) {
Ret = kEplObdValueTooHigh;
}
@@ -1787,20 +1760,20 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
case kEplObdTypUInt64:
// switch to lower limit
- pRangeData = ((unsigned QWORD *)pRangeData) + 1;
+ pRangeData = ((unsigned u64 *)pRangeData) + 1;
// check if value is to low
- if (*((unsigned QWORD *)pData_p) <
- *((unsigned QWORD *)pRangeData)) {
+ if (*((unsigned u64 *)pData_p) <
+ *((unsigned u64 *)pRangeData)) {
Ret = kEplObdValueTooLow;
break;
}
// switch to higher limit
- pRangeData = ((unsigned QWORD *)pRangeData) + 1;
+ pRangeData = ((unsigned u64 *)pRangeData) + 1;
// check if value is to high
- if (*((unsigned QWORD *)pData_p) >
- *((unsigned QWORD *)pRangeData)) {
+ if (*((unsigned u64 *)pData_p) >
+ *((unsigned u64 *)pRangeData)) {
Ret = kEplObdValueTooHigh;
}
@@ -1870,29 +1843,28 @@ static tEplKernel EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- void **ppDstData_p,
- tEplObdSize Size_p,
- tEplObdEntryPtr * ppObdEntry_p,
- tEplObdSubEntryPtr * ppSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- tEplObdSize * pObdSize_p)
+static tEplKernel EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ void **ppDstData_p,
+ tEplObdSize Size_p,
+ tEplObdEntryPtr *ppObdEntry_p,
+ tEplObdSubEntryPtr *ppSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ tEplObdSize *pObdSize_p)
{
tEplKernel Ret;
tEplObdEntryPtr pObdEntry;
tEplObdSubEntryPtr pSubEntry;
tEplObdAccess Access;
- void MEM *pDstData;
+ void *pDstData;
tEplObdSize ObdSize;
BOOL fEntryNumerical;
#if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
- tEplObdVStringDomain MEM MemVStringDomain;
- void MEM *pCurrData;
+ tEplObdVStringDomain MemVStringDomain;
+ void *pCurrData;
#endif
// check for all API function if instance is valid
@@ -1908,7 +1880,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
goto Exit;
}
// get pointer to object data
- pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
+ pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
Access = (tEplObdAccess) pSubEntry->m_Access;
@@ -1933,7 +1905,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
// adapted by user callback function, re-read
// this values.
ObdSize = EplObdGetObjectSize(pSubEntry);
- pDstData = (void MEM *)EplObdGetObjectDataPtrIntern(pSubEntry);
+ pDstData = (void *)EplObdGetObjectDataPtrIntern(pSubEntry);
// 09-dec-2004 r.d.:
// Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
@@ -1967,23 +1939,19 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
pCurrData = pSubEntry->m_pCurrent;
if ((pSubEntry->m_Type == kEplObdTypVString)
|| (pSubEntry->m_Type == kEplObdTypOString)) {
- ((tEplObdVString MEM *) pCurrData)->m_Size =
- MemVStringDomain.m_ObjSize;
- ((tEplObdVString MEM *) pCurrData)->m_pString =
- MemVStringDomain.m_pData;
+ ((tEplObdVString *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
+ ((tEplObdVString *)pCurrData)->m_pString = MemVStringDomain.m_pData;
} else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
{
- ((tEplObdVarEntry MEM *) pCurrData)->m_Size =
- MemVStringDomain.m_ObjSize;
- ((tEplObdVarEntry MEM *) pCurrData)->m_pData =
- (void MEM *)MemVStringDomain.m_pData;
+ ((tEplObdVarEntry *)pCurrData)->m_Size = MemVStringDomain.m_ObjSize;
+ ((tEplObdVarEntry *)pCurrData)->m_pData = (void *)MemVStringDomain.m_pData;
}
// Because object size and object pointer are
// adapted by user callback function, re-read
// this values.
ObdSize = MemVStringDomain.m_ObjSize;
- pDstData = (void MEM *)MemVStringDomain.m_pData;
+ pDstData = (void *)MemVStringDomain.m_pData;
}
#endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
@@ -2004,7 +1972,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
}
if (pSubEntry->m_Type == kEplObdTypVString) {
- if (((char MEM *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character
+ if (((char *)pSrcData_p)[Size_p - 1] == '\0') { // last byte of source string contains null character
// reserve one byte in destination for 0-termination
Size_p -= 1;
@@ -2064,13 +2032,12 @@ static tEplKernel PUBLIC EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pObdEntry_p,
- tEplObdSubEntryPtr pSubEntry_p,
- tEplObdCbParam MEM * pCbParam_p,
- void *pSrcData_p,
- void *pDstData_p,
- tEplObdSize ObdSize_p)
+static tEplKernel EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,
+ tEplObdSubEntryPtr pSubEntry_p,
+ tEplObdCbParam *pCbParam_p,
+ void *pSrcData_p,
+ void *pDstData_p,
+ tEplObdSize ObdSize_p)
{
tEplKernel Ret;
@@ -2103,7 +2070,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
// terminate string with 0
if (pSubEntry_p->m_Type == kEplObdTypVString) {
- ((char MEM *)pDstData_p)[ObdSize_p] = '\0';
+ ((char *)pDstData_p)[ObdSize_p] = '\0';
}
// write address of destination to structure of callback parameters
// so callback function can change data subsequently
@@ -2123,7 +2090,7 @@ static tEplKernel PUBLIC EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_
// Function: EplObdGetObjectSize()
//
// Description: function to get size of object
-// The function determines if an object type an fixed data type (BYTE, WORD, ...)
+// The function determines if an object type an fixed data type (u8, u16, ...)
// or non fixed object (string, domain). This information is used to decide
// if download data are stored temporary or not. For objects with fixed data length
// and types a value range checking can process.
@@ -2192,8 +2159,8 @@ static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
case kEplObdTypDomain:
pData = (void *)pSubIndexEntry_p->m_pCurrent;
- if ((void MEM *)pData != (void MEM *)NULL) {
- DataSize = ((tEplObdVarEntry MEM *) pData)->m_Size;
+ if ((void *)pData != (void *)NULL) {
+ DataSize = ((tEplObdVarEntry *) pData)->m_Size;
}
break;
@@ -2205,21 +2172,19 @@ static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
// then the current pointer is always NULL. The function
// returns the length of default string.
pData = (void *)pSubIndexEntry_p->m_pCurrent;
- if ((void MEM *)pData != (void MEM *)NULL) {
+ if ((void *)pData != (void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of current value.
// (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
- DataSize = ((tEplObdVString MEM *) pData)->m_Size;
+ DataSize = ((tEplObdVString *) pData)->m_Size;
} else {
// The current position is not decleared. The string
// is located in ROM, therefor use default pointer.
pData = (void *)pSubIndexEntry_p->m_pDefault;
- if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
+ if ((const void *)pData != (const void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of default value.
- DataSize =
- ((CONST tEplObdVString ROM *) pData)->
- m_Size;
+ DataSize = ((const tEplObdVString *)pData)->m_Size;
}
}
@@ -2229,21 +2194,19 @@ static tEplObdSize EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)
case kEplObdTypOString:
pData = (void *)pSubIndexEntry_p->m_pCurrent;
- if ((void MEM *)pData != (void MEM *)NULL) {
+ if ((void *)pData != (void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of current value.
// (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
- DataSize = ((tEplObdOString MEM *) pData)->m_Size;
+ DataSize = ((tEplObdOString *) pData)->m_Size;
} else {
// The current position is not decleared. The string
// is located in ROM, therefor use default pointer.
pData = (void *)pSubIndexEntry_p->m_pDefault;
- if ((CONST void ROM *)pData != (CONST void ROM *)NULL) {
+ if ((const void *)pData != (const void *)NULL) {
// The max. size of strings defined by STRING-Macro is stored in
// tEplObdVString of default value.
- DataSize =
- ((CONST tEplObdOString ROM *) pData)->
- m_Size;
+ DataSize = ((const tEplObdOString *)pData)->m_Size;
}
}
break;
@@ -2366,7 +2329,7 @@ static void *EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
//---------------------------------------------------------------------------
static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
- tEplObdVarEntry MEM ** ppVarEntry_p)
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret = kEplObdVarEntryNotExist;
@@ -2378,13 +2341,9 @@ static tEplKernel EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,
if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0) {
// check if object is an array
if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0) {
- *ppVarEntry_p =
- &((tEplObdVarEntry MEM *) pSubindexEntry_p->
- m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
+ *ppVarEntry_p = &((tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
} else {
- *ppVarEntry_p =
- (tEplObdVarEntry MEM *) pSubindexEntry_p->
- m_pCurrent;
+ *ppVarEntry_p = (tEplObdVarEntry *)pSubindexEntry_p->m_pCurrent;
}
Ret = kEplSuccessful;
@@ -2420,7 +2379,7 @@ static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
{
tEplObdEntryPtr pObdEntry;
- tEplObdCbParam MEM CbParam;
+ tEplObdCbParam CbParam;
tEplKernel Ret;
// check for all API function if instance is valid
@@ -2474,16 +2433,16 @@ static tEplKernel EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_
//
// Parameters: pSubIndexEntry_p
//
-// Return: void MEM*
+// Return: void *
//
// State:
//
//---------------------------------------------------------------------------
-static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
+static void *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
{
- void MEM *pData;
+ void *pData;
unsigned int uiArrayIndex;
tEplObdSize Size;
@@ -2500,24 +2459,21 @@ static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
} else {
Size = EplObdGetObjectSize(pSubIndexEntry_p);
}
- pData = ((BYTE MEM *) pData) + (Size * uiArrayIndex);
+ pData = ((u8 *) pData) + (Size * uiArrayIndex);
}
// check if VarEntry
if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0) {
// The data pointer is stored in VarEntry->pData
- pData = ((tEplObdVarEntry MEM *) pData)->m_pData;
+ pData = ((tEplObdVarEntry *) pData)->m_pData;
}
// the default pointer is stored for strings in tEplObdVString
else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* ||
(pSubIndexEntry_p->m_Type == kEplObdTypUString) */
) {
- pData =
- (void MEM *)((tEplObdVString MEM *) pData)->
- m_pString;
+ pData = (void *)((tEplObdVString *)pData)->m_pString;
} else if (pSubIndexEntry_p->m_Type == kEplObdTypOString) {
pData =
- (void MEM *)((tEplObdOString MEM *) pData)->
- m_pString;
+ (void *)((tEplObdOString *)pData)->m_pString;
}
}
@@ -2541,7 +2497,7 @@ static void MEM *EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)
//
//---------------------------------------------------------------------------
-static tEplKernel EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,
+static tEplKernel EplObdGetIndexIntern(tEplObdInitParam *pInitParam_p,
unsigned int uiIndex_p,
tEplObdEntryPtr * ppObdEntry_p)
{
@@ -2762,9 +2718,7 @@ static tEplKernel EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,
//
//---------------------------------------------------------------------------
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdStoreLoadObjCallback fpCallback_p)
+tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p)
{
EPL_MCO_CHECK_INSTANCE_STATE();
@@ -2802,26 +2756,26 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
tEplObdSubEntryPtr pSubIndex;
unsigned int nSubIndexCount;
tEplObdAccess Access;
- void MEM *pDstData;
+ void *pDstData;
void *pDefault;
tEplObdSize ObjSize;
tEplKernel Ret;
- tEplObdCbStoreParam MEM CbStore;
- tEplObdVarEntry MEM *pVarEntry;
+ tEplObdCbStoreParam CbStore;
+ tEplObdVarEntry *pVarEntry;
ASSERT(pObdEnty_p != NULL);
Ret = kEplSuccessful;
// prepare structure for STORE RESTORE callback function
- CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p;
+ CbStore.m_bCurrentOdPart = (u8) CurrentOdPart_p;
CbStore.m_pData = NULL;
CbStore.m_ObjSize = 0;
// command of first action depends on direction to access
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
if (Direction_p == kEplObdDirLoad) {
- CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead;
+ CbStore.m_bCommand = (u8) kEplObdCommOpenRead;
// call callback function for previous command
Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
@@ -2829,9 +2783,9 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
goto Exit;
}
// set command for index and subindex loop
- CbStore.m_bCommand = (BYTE) kEplObdCommReadObj;
+ CbStore.m_bCommand = (u8) kEplObdCommReadObj;
} else if (Direction_p == kEplObdDirStore) {
- CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite;
+ CbStore.m_bCommand = (u8) kEplObdCommOpenWrite;
// call callback function for previous command
Ret = EplObdCallStoreCallback(EPL_MCO_INSTANCE_PTR_ & CbStore);
@@ -2839,7 +2793,7 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
goto Exit;
}
// set command for index and subindex loop
- CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj;
+ CbStore.m_bCommand = (u8) kEplObdCommWriteObj;
}
#endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
@@ -2890,7 +2844,7 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
}
else
{
- EplObdInitVarEntry ((tEplObdVarEntry MEM*) (((BYTE MEM*) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
+ EplObdInitVarEntry ((tEplObdVarEntry *) (((u8 *) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
pSubIndex->m_Type, ObjSize);
}
*/
@@ -2911,29 +2865,17 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
pSubIndex->m_pCurrent;
if (pDstData != NULL) {
// 08-dec-2004: code optimization !!!
- // entries ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString
- // and ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+ // entries ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString
+ // and ((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_Size were read
// twice. thats not necessary!
// For copying data we have to set the destination pointer to the real RAM string. This
// pointer to RAM string is located in default string info structure. (translated r.d.)
- pDstData =
- (void MEM
- *)((tEplObdVStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
- ObjSize =
- ((tEplObdVStringDef
- ROM *) pSubIndex->
- m_pDefault)->
- m_Size;
-
- ((tEplObdVString MEM *)
- pSubIndex->
- m_pCurrent)->
- m_pString = pDstData;
- ((tEplObdVString MEM *)
- pSubIndex->
- m_pCurrent)->m_Size =
- ObjSize;
+ pDstData = (void *)((tEplObdVStringDef*) pSubIndex->m_pDefault)->m_pString;
+ ObjSize = ((tEplObdVStringDef *)pSubIndex->m_pDefault)->m_Size;
+
+ ((tEplObdVString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
+ ((tEplObdVString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
}
} else if (pSubIndex->m_Type ==
@@ -2942,29 +2884,17 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
pSubIndex->m_pCurrent;
if (pDstData != NULL) {
// 08-dec-2004: code optimization !!!
- // entries ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString
- // and ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
+ // entries ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_pString
+ // and ((tEplObdOStringDef*) pSubIndex->m_pDefault)->m_Size were read
// twice. thats not necessary!
// For copying data we have to set the destination pointer to the real RAM string. This
// pointer to RAM string is located in default string info structure. (translated r.d.)
- pDstData =
- (void MEM
- *)((tEplObdOStringDef ROM *) pSubIndex->m_pDefault)->m_pString;
- ObjSize =
- ((tEplObdOStringDef
- ROM *) pSubIndex->
- m_pDefault)->
- m_Size;
-
- ((tEplObdOString MEM *)
- pSubIndex->
- m_pCurrent)->
- m_pString = pDstData;
- ((tEplObdOString MEM *)
- pSubIndex->
- m_pCurrent)->m_Size =
- ObjSize;
+ pDstData = (void *)((tEplObdOStringDef *) pSubIndex->m_pDefault)->m_pString;
+ ObjSize = ((tEplObdOStringDef *)pSubIndex->m_pDefault)->m_Size;
+
+ ((tEplObdOString *)pSubIndex->m_pCurrent)->m_pString = pDstData;
+ ((tEplObdOString *)pSubIndex->m_pCurrent)->m_Size = ObjSize;
}
}
@@ -3069,11 +2999,11 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
else {
if (Direction_p == kEplObdDirLoad) {
- CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead;
+ CbStore.m_bCommand = (u8) kEplObdCommCloseRead;
} else if (Direction_p == kEplObdDirStore) {
- CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite;
+ CbStore.m_bCommand = (u8) kEplObdCommCloseWrite;
} else if (Direction_p == kEplObdDirRestore) {
- CbStore.m_bCommand = (BYTE) kEplObdCommClear;
+ CbStore.m_bCommand = (u8) kEplObdCommClear;
} else {
goto Exit;
}
@@ -3104,7 +3034,7 @@ static tEplKernel EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_
// Returns: tEplKernel = error code
// ----------------------------------------------------------------------------
-static void EplObdCopyObjectData(void MEM * pDstData_p,
+static void EplObdCopyObjectData(void *pDstData_p,
void *pSrcData_p,
tEplObdSize ObjSize_p, tEplObdType ObjType_p)
{
@@ -3135,7 +3065,7 @@ static void EplObdCopyObjectData(void MEM * pDstData_p,
EPL_MEMCPY(pDstData_p, pSrcData_p, ObjSize_p);
if (ObjType_p == kEplObdTypVString) {
- ((char MEM *)pDstData_p)[StrSize] = '\0';
+ ((char *)pDstData_p)[StrSize] = '\0';
}
}
}
@@ -3196,7 +3126,7 @@ static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
// ----------------------------------------------------------------------------
#if (EPL_OBD_USE_STORE_RESTORE != FALSE)
static tEplKernel EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdCbStoreParam MEM *
+ tEplObdCbStoreParam *
pCbStoreParam_p)
{
diff --git a/drivers/staging/epl/EplObd.h b/drivers/staging/epl/EplObd.h
index 88cc11e34cc..6bb5a278068 100644
--- a/drivers/staging/epl/EplObd.h
+++ b/drivers/staging/epl/EplObd.h
@@ -68,11 +68,11 @@
****************************************************************************/
-#include "EplInc.h"
-
#ifndef _EPLOBD_H_
#define _EPLOBD_H_
+#include "EplInc.h"
+
// ============================================================================
// defines
// ============================================================================
@@ -206,7 +206,7 @@ typedef unsigned int tEplObdSize; // For all objects as objects size are used an
// -------------------------------------------------------------------------
// types of objects in object dictionary
-// DS-301 defines these types as WORD
+// DS-301 defines these types as u16
typedef enum {
// types which are always supported
kEplObdTypBool = 0x0001,
@@ -255,15 +255,15 @@ typedef unsigned char tEplObdDomain; // 000F
typedef signed long tEplObdInteger24; // 0010
typedef unsigned long tEplObdUnsigned24; // 0016
-typedef signed QWORD tEplObdInteger40; // 0012
-typedef signed QWORD tEplObdInteger48; // 0013
-typedef signed QWORD tEplObdInteger56; // 0014
-typedef signed QWORD tEplObdInteger64; // 0015
+typedef s64 tEplObdInteger40; // 0012
+typedef s64 tEplObdInteger48; // 0013
+typedef s64 tEplObdInteger56; // 0014
+typedef s64 tEplObdInteger64; // 0015
-typedef unsigned QWORD tEplObdUnsigned40; // 0018
-typedef unsigned QWORD tEplObdUnsigned48; // 0019
-typedef unsigned QWORD tEplObdUnsigned56; // 001A
-typedef unsigned QWORD tEplObdUnsigned64; // 001B
+typedef u64 tEplObdUnsigned40; // 0018
+typedef u64 tEplObdUnsigned48; // 0019
+typedef u64 tEplObdUnsigned56; // 001A
+typedef u64 tEplObdUnsigned64; // 001B
typedef double tEplObdReal64; // 0011
@@ -283,22 +283,21 @@ typedef enum {
kVarValidAll = 0x03 // currently only size and data are implemented and used
} tEplVarParamValid;
-typedef tEplKernel(PUBLIC ROM * tEplVarCallback) (CCM_DECL_INSTANCE_HDL_
- void *pParam_p);
+typedef tEplKernel(*tEplVarCallback) (CCM_DECL_INSTANCE_HDL_ void *pParam_p);
typedef struct {
tEplVarParamValid m_ValidFlag;
unsigned int m_uiIndex;
unsigned int m_uiSubindex;
tEplObdSize m_Size;
- void MEM *m_pData;
+ void *m_pData;
// tEplVarCallback m_fpCallback;
// void * m_pArg;
} tEplVarParam;
typedef struct {
- void MEM *m_pData;
+ void *m_pData;
tEplObdSize m_Size;
/*
#if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
@@ -310,7 +309,7 @@ typedef struct {
typedef struct {
tEplObdSize m_Size;
- BYTE *m_pString;
+ u8 *m_pString;
} tEplObdOString; // 000C
@@ -328,8 +327,8 @@ typedef struct {
typedef struct {
tEplObdSize m_Size;
- BYTE *m_pDefString; // $$$ d.k. it is unused, so we could delete it
- BYTE *m_pString;
+ u8 *m_pDefString; // $$$ d.k. it is unused, so we could delete it
+ u8 *m_pString;
} tEplObdOStringDef;
@@ -354,7 +353,7 @@ typedef struct {
tEplObdType m_Type;
tEplObdAccess m_Access;
void *m_pDefault;
- void MEM *m_pCurrent; // points always to RAM
+ void *m_pCurrent; // points always to RAM
} tEplObdSubEntry;
@@ -371,14 +370,12 @@ typedef struct {
unsigned int m_uiIndex;
unsigned int m_uiSubIndex;
void *m_pArg;
- DWORD m_dwAbortCode;
+ u32 m_dwAbortCode;
} tEplObdCbParam;
// define type for callback function: pParam_p points to tEplObdCbParam
-typedef tEplKernel(PUBLIC ROM * tEplObdCallback) (CCM_DECL_INSTANCE_HDL_
- tEplObdCbParam MEM *
- pParam_p);
+typedef tEplKernel(*tEplObdCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbParam *pParam_p);
// do not change the order for this struct!!!
@@ -417,19 +414,14 @@ typedef struct {
typedef struct {
tEplObdCommand m_bCommand;
tEplObdPart m_bCurrentOdPart;
- void MEM *m_pData;
+ void *m_pData;
tEplObdSize m_ObjSize;
} tEplObdCbStoreParam;
-typedef tEplKernel(PUBLIC ROM * tInitTabEntryCallback) (void MEM * pTabEntry_p,
- unsigned int
- uiObjIndex_p);
+typedef tEplKernel(*tInitTabEntryCallback) (void *pTabEntry_p, unsigned int uiObjIndex_p);
-typedef tEplKernel(PUBLIC ROM *
- tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_
- tEplObdCbStoreParam MEM *
- pCbStoreParam_p);
+typedef tEplKernel(*tEplObdStoreLoadObjCallback) (CCM_DECL_INSTANCE_HDL_ tEplObdCbStoreParam *pCbStoreParam_p);
// -------------------------------------------------------------------------
// this stucture is used for parameters for function ObdInitModuleTab()
@@ -438,8 +430,8 @@ typedef struct {
unsigned int m_uiLowerObjIndex; // lower limit of ObjIndex
unsigned int m_uiUpperObjIndex; // upper limit of ObjIndex
tInitTabEntryCallback m_fpInitTabEntry; // will be called if ObjIndex was found
- void MEM *m_pTabBase; // base address of table
- unsigned int m_uiEntrySize; // size of table entry // 25-feb-2005 r.d.: expansion from BYTE to WORD necessary for PDO bit mapping
+ void *m_pTabBase; // base address of table
+ unsigned int m_uiEntrySize; // size of table entry // 25-feb-2005 r.d.: expansion from u8 to u16 necessary for PDO bit mapping
unsigned int m_uiMaxEntries; // max. tabel entries
} tEplObdModulTabParam;
diff --git a/drivers/staging/epl/EplObdMacro.h b/drivers/staging/epl/EplObdMacro.h
index 23f2ad80dde..fc325bfd604 100644
--- a/drivers/staging/epl/EplObdMacro.h
+++ b/drivers/staging/epl/EplObdMacro.h
@@ -80,7 +80,7 @@
// #pragma message ("EPL_OBD_CREATE_ROM_DATA")
-#define EPL_OBD_BEGIN() static DWORD dwObd_OBK_g = 0x0000;
+#define EPL_OBD_BEGIN() static u32 dwObd_OBK_g = 0x0000;
#define EPL_OBD_END()
//---------------------------------------------------------------------------------------
@@ -102,11 +102,11 @@
#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp xDef##ind##_##sub##_g = val;
#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xDef##ind##_##sub##_g[3] = {val,low,high};
#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name)
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static char MEM szCur##ind##_##sub##_g[size+1]; \
+#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static char szCur##ind##_##sub##_g[size+1]; \
static tEplObdVStringDef xDef##ind##_##sub##_g = {size, val, szCur##ind##_##sub##_g};
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static BYTE MEM bCur##ind##_##sub##_g[size]; \
- static tEplObdOStringDef xDef##ind##_##sub##_g = {size, ((BYTE*)""), bCur##ind##_##sub##_g};
+#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static u8 bCur##ind##_##sub##_g[size]; \
+ static tEplObdOStringDef xDef##ind##_##sub##_g = {size, ((u8*)""), bCur##ind##_##sub##_g};
#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name)
#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static dtyp xDef##ind##_##sub##_g = val;
#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xDef##ind##_##sub##_g[3] = {val,low,high};
@@ -129,20 +129,20 @@
//---------------------------------------------------------------------------------------
#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call)
#define EPL_OBD_END_INDEX(ind)
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static dtyp MEM axCur##ind##_g[cnt];
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdVarEntry MEM aVarEntry##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static dtyp axCur##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdVarEntry aVarEntry##ind##_g[cnt];
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdVarEntry aVarEntry##ind##_g[cnt];
//---------------------------------------------------------------------------------------
-#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static tEplObdVString MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static tEplObdOString MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) static dtyp MEM xCur##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
-#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) static tEplObdVarEntry MEM VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR(ind,sub,typ,acc,dtyp,name,val) static dtyp xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static dtyp xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VSTRING(ind,sub,acc,name,size,val) static tEplObdVString xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_OSTRING(ind,sub,acc,name,size) static tEplObdOString xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_VAR_NOINIT(ind,sub,typ,acc,dtyp,name) static dtyp xCur##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_DOMAIN(ind,sub,acc,name) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF(ind,sub,typ,acc,dtyp,name,val) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF_RG(ind,sub,typ,acc,dtyp,name,val,low,high) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
+#define EPL_OBD_SUBINDEX_RAM_USERDEF_NOINIT(ind,sub,typ,acc,dtyp,name) static tEplObdVarEntry VarEntry##ind##_##sub##_g;
//-------------------------------------------------------------------------------------------
#elif defined (EPL_OBD_CREATE_SUBINDEX_TAB)
@@ -159,17 +159,17 @@
#define EPL_OBD_END_PART()
//---------------------------------------------------------------------------------------
-#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[cnt]= {
+#define EPL_OBD_BEGIN_INDEX_RAM(ind,cnt,call) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[cnt]= {
#define EPL_OBD_END_INDEX(ind) EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_ARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
{0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \
{1, typ, (acc)|kEplObdAccArray, &xDef##ind##_0x01_g, &axCur##ind##_g[0]}, \
EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY(ind,cnt,call,typ,acc,dtyp,name,def) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
{0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \
{1, typ, (acc)|kEplObdAccArray|kEplObdAccVar, &xDef##ind##_0x01_g, &aVarEntry##ind##_g[0]}, \
EPL_OBD_END_SUBINDEX()};
-#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdSubEntry MEM aObdSubEntry##ind##Ram_g[]= { \
+#define EPL_OBD_RAM_INDEX_RAM_VARARRAY_NOINIT(ind,cnt,call,typ,acc,dtyp,name) static tEplObdSubEntry aObdSubEntry##ind##Ram_g[]= { \
{0, kEplObdTypUInt8, kEplObdAccCR, &xDef##ind##_0x00_g, NULL}, \
{1, typ, (acc)|kEplObdAccArray|kEplObdAccVar, NULL, &aVarEntry##ind##_g[0]}, \
EPL_OBD_END_SUBINDEX()};
diff --git a/drivers/staging/epl/EplObdkCal.c b/drivers/staging/epl/EplObdkCal.c
index 4c9af89719e..02bd72224ab 100644
--- a/drivers/staging/epl/EplObdkCal.c
+++ b/drivers/staging/epl/EplObdkCal.c
@@ -70,7 +70,6 @@
****************************************************************************/
#include "EplInc.h"
-#include "kernel/EplObdkCal.h"
/***************************************************************************/
/* */
diff --git a/drivers/staging/epl/EplObdu.c b/drivers/staging/epl/EplObdu.c
index 218d152897c..5f1d9986254 100644
--- a/drivers/staging/epl/EplObdu.c
+++ b/drivers/staging/epl/EplObdu.c
@@ -121,10 +121,9 @@
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduWriteEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -153,10 +152,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduReadEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -179,8 +178,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p)
+tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
{
tEplKernel Ret;
@@ -202,7 +200,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p)
+tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p)
{
tEplKernel Ret;
@@ -226,8 +224,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
{
void *pData;
@@ -250,7 +247,7 @@ EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
//
//---------------------------------------------------------------------------
#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
+tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
{
tEplKernel Ret;
@@ -275,9 +272,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p)
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
- BYTE bType_p,
- tEplObdSize ObdSize_p)
+void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p, tEplObdSize ObdSize_p)
{
EplObduCalInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
}
@@ -299,8 +294,7 @@ EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
{
tEplObdSize Size;
@@ -323,7 +317,7 @@ EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId()
+unsigned int EplObduGetNodeId(void)
{
unsigned int uiNodeId;
@@ -347,8 +341,7 @@ EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p)
+tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p, tEplObdNodeIdType NodeIdType_p)
{
tEplKernel Ret;
@@ -373,10 +366,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p)
+tEplKernel EplObduGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p)
{
tEplObdAccess AccessType;
@@ -410,10 +402,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -445,11 +437,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -475,11 +466,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM **
- ppVarEntry_p)
+tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret;
diff --git a/drivers/staging/epl/EplObduCal.c b/drivers/staging/epl/EplObduCal.c
index 85b3df0886b..55612cff821 100644
--- a/drivers/staging/epl/EplObduCal.c
+++ b/drivers/staging/epl/EplObduCal.c
@@ -121,10 +121,9 @@
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -155,10 +154,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -185,8 +183,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p)
+tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p)
{
tEplKernel Ret;
@@ -212,8 +209,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
- pVarParam_p)
+tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p)
{
tEplKernel Ret;
@@ -240,8 +236,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p)
{
void *pData;
@@ -268,8 +263,7 @@ EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
//
//---------------------------------------------------------------------------
#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
- pUserOd_p)
+tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p)
{
tEplKernel Ret;
@@ -298,9 +292,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
- pVarEntry_p, BYTE bType_p,
- tEplObdSize ObdSize_p)
+void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p,
+ tEplObdSize ObdSize_p)
{
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
EplObdInitVarEntry(pVarEntry_p, bType_p, ObdSize_p);
@@ -324,8 +317,8 @@ EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p)
+tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p)
{
tEplObdSize Size;
@@ -352,7 +345,7 @@ EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId()
+unsigned int EplObduCalGetNodeId(void)
{
unsigned int uiNodeId;
@@ -380,9 +373,8 @@ EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId()
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType
- NodeIdType_p)
+tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p)
{
tEplKernel Ret;
@@ -411,11 +403,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p)
+tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p)
{
tEplObdAccess AccesType;
@@ -447,11 +437,10 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p)
+tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p)
{
tEplKernel Ret;
@@ -481,12 +470,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
- uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p)
+tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p)
{
tEplKernel Ret;
@@ -514,10 +500,9 @@ EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
// State:
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM ** ppVarEntry_p)
+tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p)
{
tEplKernel Ret;
diff --git a/drivers/staging/epl/EplObjDef.h b/drivers/staging/epl/EplObjDef.h
deleted file mode 100644
index 7713125a3e8..00000000000
--- a/drivers/staging/epl/EplObjDef.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: defines objdict dictionary
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplObjDef.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- GCC V3.4
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/06/06 k.t.: take ObjDef.h from CANopen and modify for EPL
-
-****************************************************************************/
-
-#ifndef _EPLOBJDEF_H_
-#define _EPLOBJDEF_H_
-
-//---------------------------------------------------------------------------
-// security checks
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// macros to help building OD
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-#if (defined (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB) && (EPL_OBD_USE_VARIABLE_SUBINDEX_TAB != FALSE))
-
-#define CCM_SUBINDEX_RAM_ONLY(a) a;
-#define CCM_SUBINDEX_RAM_ONEOF(a,b) a
-
-#else
-
-#define CCM_SUBINDEX_RAM_ONLY(a)
-#define CCM_SUBINDEX_RAM_ONEOF(a,b) b
-
-#endif
-
-//---------------------------------------------------------------------------
-// To prevent unused memory in subindex tables we need this macro.
-// But not all compilers support to preset the last struct value followed by a comma.
-// Compilers which does not support a comma after last struct value has to place in a dummy subindex.
-#if ((DEV_SYSTEM & _DEV_COMMA_EXT_) != 0)
-
-#define EPL_OBD_END_SUBINDEX()
-#define EPL_OBD_MAX_ARRAY_SUBENTRIES 2
-
-#else
-
-#define EPL_OBD_END_SUBINDEX() {0,0,0,NULL,NULL}
-#define EPL_OBD_MAX_ARRAY_SUBENTRIES 3
-
-#endif
-
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-// globale vars
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-
-// -------------------------------------------------------------------------
-// creation of data in ROM memory
-// -------------------------------------------------------------------------
-#define EPL_OBD_CREATE_ROM_DATA
-#include "objdict.h"
-#undef EPL_OBD_CREATE_ROM_DATA
-
-// -------------------------------------------------------------------------
-// creation of data in RAM memory
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_RAM_DATA
-#include "objdict.h"
-#undef EPL_OBD_CREATE_RAM_DATA
-
-// -------------------------------------------------------------------------
-// creation of subindex tables in ROM and RAM
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_SUBINDEX_TAB
-#include "objdict.h"
-#undef EPL_OBD_CREATE_SUBINDEX_TAB
-
-// -------------------------------------------------------------------------
-// creation of index tables for generic, manufacturer and device part
-// -------------------------------------------------------------------------
-
-#define EPL_OBD_CREATE_INDEX_TAB
-#include "objdict.h"
-#undef EPL_OBD_CREATE_INDEX_TAB
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-// ----------------------------------------------------------------------------
-//
-// Function: EPL_OBD_INIT_RAM_NAME()
-//
-// Description: function to initialize object dictionary
-//
-// Parameters: pInitParam_p = pointer to init param struct of Epl
-//
-// Returns: tEplKernel = error code
-//
-// State:
-//
-// ----------------------------------------------------------------------------
-
-EPLDLLEXPORT tEplKernel PUBLIC EPL_OBD_INIT_RAM_NAME(tEplObdInitParam MEM *
- pInitParam_p)
-{
-
- tEplObdInitParam MEM *pInitParam = pInitParam_p;
-
- // check if pointer to parameter structure is valid
- // if not then only copy subindex tables below
- if (pInitParam != NULL) {
- // at first delete all parameters (all pointers will be set zu NULL)
- EPL_MEMSET(pInitParam, 0, sizeof(tEplObdInitParam));
-
-#define EPL_OBD_CREATE_INIT_FUNCTION
- {
- // inserts code to init pointer to index tables
-#include "objdict.h"
- }
-#undef EPL_OBD_CREATE_INIT_FUNCTION
-
-#if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
- {
- // to begin no user OD is defined
- pInitParam_p->m_pUserPart = NULL;
- }
-#endif
- }
-#define EPL_OBD_CREATE_INIT_SUBINDEX
- {
- // inserts code to copy subindex tables
-#include "objdict.h"
- }
-#undef EPL_OBD_CREATE_INIT_SUBINDEX
-
- return kEplSuccessful;
-
-}
-
-#endif // _EPLOBJDEF_H_
-
-// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
-// damit ein Problem haben, wenn das nicht so ist (z.B. GNU oder Borland C++ Builder).
diff --git a/drivers/staging/epl/EplPdo.h b/drivers/staging/epl/EplPdo.h
index d22ac86e85b..0b3ad5bc7d5 100644
--- a/drivers/staging/epl/EplPdo.h
+++ b/drivers/staging/epl/EplPdo.h
@@ -90,8 +90,8 @@
typedef struct {
void *m_pVar;
- WORD m_wOffset; // in Bits
- WORD m_wSize; // in Bits
+ u16 m_wOffset; // in Bits
+ u16 m_wSize; // in Bits
BOOL m_fNumeric; // numeric value -> use AMI functions
} tEplPdoMapping;
@@ -104,7 +104,7 @@ typedef struct {
// TPDO: 0x00=PRes, MN: CnNodeId=PReq
BOOL m_fTxRx;
- BYTE m_bMappingVersion;
+ u8 m_bMappingVersion;
unsigned int m_uiMaxMappingEntries; // maximum number of mapping entries, i.e. size of m_aPdoMapping
tEplPdoMapping m_aPdoMapping[1];
diff --git a/drivers/staging/epl/EplPdok.c b/drivers/staging/epl/EplPdok.c
index 15999b4f575..db9b3f08384 100644
--- a/drivers/staging/epl/EplPdok.c
+++ b/drivers/staging/epl/EplPdok.c
@@ -73,11 +73,6 @@
#include "kernel/EplEventk.h"
#include "kernel/EplObdk.h"
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
-#include "plccore.h"
-#define PDO_LED 0x08
-#endif
-
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) == 0)
@@ -226,11 +221,6 @@ tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p)
tEplKernel Ret = kEplSuccessful;
tEplEvent Event;
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // reset LED
-// MCF_GPIO_PODR_PCIBG &= ~PDO_LED; // Level
-#endif
-
Event.m_EventSink = kEplEventSinkPdok;
Event.m_EventType = kEplEventTypePdoRx;
// limit copied data to size of PDO (because from some CNs the frame is larger than necessary)
@@ -238,11 +228,6 @@ tEplKernel EplPdokCbPdoReceived(tEplFrameInfo * pFrameInfo_p)
Event.m_pArg = pFrameInfo_p->m_pFrame;
Ret = EplEventkPost(&Event);
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // set LED
-// MCF_GPIO_PODR_PCIBG |= PDO_LED; // Level
-#endif
-
return Ret;
}
@@ -269,22 +254,12 @@ tEplKernel EplPdokCbPdoTransmitted(tEplFrameInfo * pFrameInfo_p)
tEplKernel Ret = kEplSuccessful;
tEplEvent Event;
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // reset LED
- MCF_GPIO_PODR_PCIBG &= ~PDO_LED; // Level
-#endif
-
Event.m_EventSink = kEplEventSinkPdok;
Event.m_EventType = kEplEventTypePdoTx;
Event.m_uiSize = sizeof(tEplFrameInfo);
Event.m_pArg = pFrameInfo_p;
Ret = EplEventkPost(&Event);
-#if (DEV_SYSTEM == _DEV_GNU_CF548X_)
- // set LED
- MCF_GPIO_PODR_PCIBG |= PDO_LED; // Level
-#endif
-
return Ret;
}
@@ -339,19 +314,19 @@ tEplKernel EplPdokCbSoa(tEplFrameInfo * pFrameInfo_p)
tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
{
tEplKernel Ret = kEplSuccessful;
- WORD wPdoSize;
- WORD wBitOffset;
- WORD wBitSize;
- WORD wVarSize;
- QWORD qwObjectMapping;
- BYTE bMappSubindex;
- BYTE bObdSubindex;
- WORD wObdMappIndex;
- WORD wObdCommIndex;
- WORD wPdoId;
- BYTE bObdData;
- BYTE bObjectCount;
- BYTE bFrameData;
+ u16 wPdoSize;
+ u16 wBitOffset;
+ u16 wBitSize;
+ u16 wVarSize;
+ u64 qwObjectMapping;
+ u8 bMappSubindex;
+ u8 bObdSubindex;
+ u16 wObdMappIndex;
+ u16 wObdCommIndex;
+ u16 wPdoId;
+ u8 bObdData;
+ u8 bObjectCount;
+ u8 bFrameData;
BOOL fValid;
tEplObdSize ObdSize;
tEplFrame *pFrame;
@@ -448,7 +423,7 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
// process mapping
for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
bMappSubindex++) {
- ObdSize = 8; // QWORD
+ ObdSize = 8; // u64
// read object mapping from OD
Ret =
EplObdReadEntry(wObdMappIndex,
@@ -463,16 +438,16 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
}
// decode object mapping
wObdCommIndex =
- (WORD) (qwObjectMapping &
+ (u16) (qwObjectMapping &
0x000000000000FFFFLL);
bObdSubindex =
- (BYTE) ((qwObjectMapping &
+ (u8) ((qwObjectMapping &
0x0000000000FF0000LL) >> 16);
wBitOffset =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0x0000FFFF00000000LL) >> 32);
wBitSize =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0xFFFF000000000000LL) >> 48);
// check if object exceeds PDO size
@@ -578,7 +553,7 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
// process mapping
for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
bMappSubindex++) {
- ObdSize = 8; // QWORD
+ ObdSize = 8; // u64
// read object mapping from OD
Ret =
EplObdReadEntry(wObdMappIndex,
@@ -593,21 +568,21 @@ tEplKernel EplPdokProcess(tEplEvent * pEvent_p)
}
// decode object mapping
wObdCommIndex =
- (WORD) (qwObjectMapping &
+ (u16) (qwObjectMapping &
0x000000000000FFFFLL);
bObdSubindex =
- (BYTE) ((qwObjectMapping &
+ (u8) ((qwObjectMapping &
0x0000000000FF0000LL) >> 16);
wBitOffset =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0x0000FFFF00000000LL) >> 32);
wBitSize =
- (WORD) ((qwObjectMapping &
+ (u16) ((qwObjectMapping &
0xFFFF000000000000LL) >> 48);
// calculate max PDO size
ObdSize = wBitSize >> 3;
- wVarSize = (wBitOffset >> 3) + (WORD) ObdSize;
+ wVarSize = (wBitOffset >> 3) + (u16) ObdSize;
if ((unsigned int)(wVarSize + 24) > pFrameInfo->m_uiFrameSize) { // TPDO is too short
// $$$ raise PDO error, set Ret
goto Exit;
diff --git a/drivers/staging/epl/EplPdou.c b/drivers/staging/epl/EplPdou.c
index e7b10653a0e..d6d06242d74 100644
--- a/drivers/staging/epl/EplPdou.c
+++ b/drivers/staging/epl/EplPdou.c
@@ -149,18 +149,18 @@
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
unsigned int uiIndex_p);
-static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p,
unsigned int *puiIndex_p,
unsigned int *puiSubIndex_p,
unsigned int *puiBitOffset_p,
unsigned int *puiBitSize_p);
-static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p,
tEplObdAccess AccessType_p,
- DWORD * pdwAbortCode_p,
+ u32 * pdwAbortCode_p,
unsigned int *puiPdoSize_p);
//=========================================================================//
@@ -226,18 +226,18 @@ tEplKernel EplPdouDelInstance(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
+tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiPdoId;
unsigned int uiIndexType;
tEplObdSize ObdSize;
- BYTE bObjectCount;
- QWORD qwObjectMapping;
+ u8 bObjectCount;
+ u64 qwObjectMapping;
tEplObdAccess AccessType;
- BYTE bMappSubindex;
+ u8 bMappSubindex;
unsigned int uiCurPdoSize;
- WORD wMaxPdoSize;
+ u16 wMaxPdoSize;
unsigned int uiSubIndex;
// fetch PDO ID
@@ -293,7 +293,7 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
if (pParam_p->m_uiSubIndex == 0) { // object mapping count accessed
// PDO is enabled or disabled
- bObjectCount = *((BYTE *) pParam_p->m_pArg);
+ bObjectCount = *((u8 *) pParam_p->m_pArg);
if (bObjectCount == 0) { // PDO shall be disabled
@@ -326,7 +326,7 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
for (bMappSubindex = 1; bMappSubindex <= bObjectCount;
bMappSubindex++) {
// read object mapping from OD
- ObdSize = sizeof(qwObjectMapping); // QWORD
+ ObdSize = sizeof(qwObjectMapping); // u64
Ret = EplObduReadEntry(pParam_p->m_uiIndex,
bMappSubindex, &qwObjectMapping,
&ObdSize);
@@ -360,7 +360,7 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
}
// check existence of object and validity of object length
- qwObjectMapping = *((QWORD *) pParam_p->m_pArg);
+ qwObjectMapping = *((u64 *) pParam_p->m_pArg);
Ret = EplPdouCheckObjectMapping(qwObjectMapping,
AccessType,
@@ -394,12 +394,12 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p)
//
//---------------------------------------------------------------------------
-static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
+static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam *pParam_p,
unsigned int uiIndex_p)
{
tEplKernel Ret = kEplSuccessful;
tEplObdSize ObdSize;
- BYTE bObjectCount;
+ u8 bObjectCount;
ObdSize = 1;
// read number of mapped objects from OD; this indicates if the PDO is valid
@@ -439,7 +439,7 @@ static tEplKernel EplPdouCheckPdoValidity(tEplObdCbParam MEM * pParam_p,
//
//---------------------------------------------------------------------------
-static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
+static void EplPdouDecodeObjectMapping(u64 qwObjectMapping_p,
unsigned int *puiIndex_p,
unsigned int *puiSubIndex_p,
unsigned int *puiBitOffset_p,
@@ -480,9 +480,9 @@ static void EplPdouDecodeObjectMapping(QWORD qwObjectMapping_p,
//
//---------------------------------------------------------------------------
-static tEplKernel EplPdouCheckObjectMapping(QWORD qwObjectMapping_p,
+static tEplKernel EplPdouCheckObjectMapping(u64 qwObjectMapping_p,
tEplObdAccess AccessType_p,
- DWORD * pdwAbortCode_p,
+ u32 * pdwAbortCode_p,
unsigned int *puiPdoSize_p)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/EplSdo.h b/drivers/staging/epl/EplSdo.h
index 1cb3f2de4a3..8002e0cc4d9 100644
--- a/drivers/staging/epl/EplSdo.h
+++ b/drivers/staging/epl/EplSdo.h
@@ -116,20 +116,18 @@ typedef unsigned int tEplSdoConHdl;
// callback function pointer for Protocol Abstraction Layer to call
// asynchronuus SDO Sequence Layer
-typedef tEplKernel(PUBLIC * tEplSequLayerReceiveCb) (tEplSdoConHdl ConHdl_p,
- tEplAsySdoSeq *
- pSdoSeqData_p,
- unsigned int uiDataSize_p);
+typedef tEplKernel(*tEplSequLayerReceiveCb) (tEplSdoConHdl ConHdl_p,
+ tEplAsySdoSeq *pSdoSeqData_p,
+ unsigned int uiDataSize_p);
// handle between asynchronuus SDO Sequence Layer and SDO Command layer
typedef unsigned int tEplSdoSeqConHdl;
// callback function pointer for asynchronuus SDO Sequence Layer to call
// SDO Command layer for received data
-typedef tEplKernel(PUBLIC *
- tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoCom * pAsySdoCom_p,
- unsigned int uiDataSize_p);
+typedef tEplKernel(* tEplSdoComReceiveCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoCom *pAsySdoCom_p,
+ unsigned int uiDataSize_p);
// status of connection
typedef enum {
@@ -143,9 +141,8 @@ typedef enum {
// callback function pointer for asynchronuus SDO Sequence Layer to call
// SDO Command layer for connection status
-typedef tEplKernel(PUBLIC * tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoConState
- AsySdoConState_p);
+typedef tEplKernel(* tEplSdoComConCb) (tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoConState AsySdoConState_p);
// handle between SDO Command layer and application
typedef unsigned int tEplSdoComConHdl;
@@ -210,7 +207,7 @@ typedef enum {
typedef struct {
tEplSdoComConHdl m_SdoComConHdl;
tEplSdoComConState m_SdoComConState;
- DWORD m_dwAbortCode;
+ u32 m_dwAbortCode;
tEplSdoAccessType m_SdoAccessType;
unsigned int m_uiNodeId; // NodeId of the target
unsigned int m_uiTargetIndex; // index which was accessed
@@ -221,8 +218,7 @@ typedef struct {
} tEplSdoComFinished;
// callback function pointer to inform application about connection
-typedef tEplKernel(PUBLIC * tEplSdoFinishedCb) (tEplSdoComFinished *
- pSdoComFinished_p);
+typedef tEplKernel(* tEplSdoFinishedCb) (tEplSdoComFinished *pSdoComFinished_p);
// structure to init SDO transfer to Read or Write by Index
typedef struct {
diff --git a/drivers/staging/epl/EplSdoAsndu.c b/drivers/staging/epl/EplSdoAsndu.c
index 05a00c9a731..aa8bdef317c 100644
--- a/drivers/staging/epl/EplSdoAsndu.c
+++ b/drivers/staging/epl/EplSdoAsndu.c
@@ -110,7 +110,7 @@ static tEplSdoAsndInstance SdoAsndInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
+tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p);
/***************************************************************************/
/* */
@@ -149,7 +149,7 @@ tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p);
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
@@ -176,7 +176,7 @@ tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
@@ -218,7 +218,7 @@ tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduDelInstance()
+tEplKernel EplSdoAsnduDelInstance(void)
{
tEplKernel Ret;
@@ -251,8 +251,8 @@ tEplKernel PUBLIC EplSdoAsnduDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p)
+tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -319,9 +319,9 @@ tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p,
- DWORD dwDataSize_p)
+tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p,
+ u32 dwDataSize_p)
{
tEplKernel Ret;
unsigned int uiArray;
@@ -339,10 +339,10 @@ tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
// own node id not needed -> filled by DLL
// set message type
- AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (BYTE) kEplMsgTypeAsnd); // ASnd == 0x06
+ AmiSetByteToLe(&pSrcData_p->m_le_bMessageType, (u8) kEplMsgTypeAsnd); // ASnd == 0x06
// target node id
AmiSetByteToLe(&pSrcData_p->m_le_bDstNodeId,
- (BYTE) SdoAsndInstance_g.
+ (u8) SdoAsndInstance_g.
m_auiSdoAsndConnection[uiArray]);
// set source-nodeid (filled by DLL 0)
AmiSetByteToLe(&pSrcData_p->m_le_bSrcNodeId, 0x00);
@@ -379,7 +379,7 @@ tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
+tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
{
tEplKernel Ret;
unsigned int uiArray;
@@ -422,7 +422,7 @@ tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsnduCb(tEplFrameInfo * pFrameInfo_p)
+tEplKernel EplSdoAsnduCb(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiCount;
diff --git a/drivers/staging/epl/EplSdoAsySequ.c b/drivers/staging/epl/EplSdoAsySequ.c
index 6b6a9975d78..256d7086634 100644
--- a/drivers/staging/epl/EplSdoAsySequ.c
+++ b/drivers/staging/epl/EplSdoAsySequ.c
@@ -128,11 +128,11 @@ typedef enum {
// structure for History-Buffer
typedef struct {
- BYTE m_bFreeEntries;
- BYTE m_bWrite; // index of the next free buffer entry
- BYTE m_bAck; // index of the next message which should become acknowledged
- BYTE m_bRead; // index between m_bAck and m_bWrite to the next message for retransmission
- BYTE m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE]
+ u8 m_bFreeEntries;
+ u8 m_bWrite; // index of the next free buffer entry
+ u8 m_bAck; // index of the next message which should become acknowledged
+ u8 m_bRead; // index between m_bAck and m_bWrite to the next message for retransmission
+ u8 m_aabHistoryFrame[EPL_SDO_HISTORY_SIZE]
[EPL_SEQ_HISTROY_FRAME_SIZE];
unsigned int m_auiFrameSize[EPL_SDO_HISTORY_SIZE];
@@ -152,8 +152,8 @@ typedef enum {
typedef struct {
tEplSdoConHdl m_ConHandle;
tEplAsySdoState m_SdoState;
- BYTE m_bRecSeqNum; // name from view of the communication partner
- BYTE m_bSendSeqNum; // name from view of the communication partner
+ u8 m_bRecSeqNum; // name from view of the communication partner
+ u8 m_bSendSeqNum; // name from view of the communication partner
tEplAsySdoConHistory m_SdoConHistory;
tEplTimerHdl m_EplTimerHdl;
unsigned int m_uiRetryCount; // retry counter
@@ -203,9 +203,9 @@ static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
unsigned int uiDataSize_p,
tEplFrame * pEplFrame_p);
-tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
- tEplAsySdoSeq * pSdoSeqData_p,
- unsigned int uiDataSize_p);
+tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
+ tEplAsySdoSeq *pSdoSeqData_p,
+ unsigned int uiDataSize_p);
static tEplKernel EplSdoAsyInitHistory(void);
@@ -214,7 +214,7 @@ static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
unsigned int uiSize_p);
static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
- BYTE bRecSeqNumber_p);
+ u8 bRecSeqNumber_p);
static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
tEplFrame ** ppFrame_p,
@@ -267,8 +267,8 @@ static tEplKernel EplSdoAsySeqSetTimer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
- tEplSdoComConCb fpSdoComConCb_p)
+tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+ tEplSdoComConCb fpSdoComConCb_p)
{
tEplKernel Ret;
@@ -297,8 +297,8 @@ tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
- tEplSdoComConCb fpSdoComConCb_p)
+tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
+ tEplSdoComConCb fpSdoComConCb_p)
{
tEplKernel Ret;
@@ -380,7 +380,7 @@ tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqDelInstance()
+tEplKernel EplSdoAsySeqDelInstance(void)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -439,9 +439,9 @@ tEplKernel PUBLIC EplSdoAsySeqDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
- unsigned int uiNodeId_p,
- tEplSdoType SdoType)
+tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
+ unsigned int uiNodeId_p,
+ tEplSdoType SdoType)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -594,9 +594,9 @@ tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
- unsigned int uiDataSize_p,
- tEplFrame * pabData_p)
+tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ unsigned int uiDataSize_p,
+ tEplFrame *pabData_p)
{
tEplKernel Ret;
unsigned int uiHandle;
@@ -640,7 +640,7 @@ tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p)
+tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p)
{
tEplKernel Ret;
tEplTimerEventArg *pTimerEventArg;
@@ -714,7 +714,7 @@ tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
+tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiHandle;
@@ -1498,7 +1498,7 @@ static tEplKernel EplSdoAsySeqProcess(unsigned int uiHandle_p,
// frame received
case kAsySdoSeqEventFrameRec:
{
- BYTE bSendSeqNumCon =
+ u8 bSendSeqNumCon =
AmiGetByteFromLe(&pRecFrame_p->
m_le_bSendSeqNumCon);
@@ -2016,7 +2016,7 @@ static tEplKernel EplSdoAsySeqSendIntern(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
BOOL fFrameInHistory_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_SEQ_FRAME_SIZE];
+ u8 abFrame[EPL_SEQ_FRAME_SIZE];
tEplFrame *pEplFrame;
unsigned int uiFreeEntries;
@@ -2139,9 +2139,9 @@ static tEplKernel EplSdoAsySeqSendLowerLayer(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
- tEplAsySdoSeq * pSdoSeqData_p,
- unsigned int uiDataSize_p)
+tEplKernel EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
+ tEplAsySdoSeq *pSdoSeqData_p,
+ unsigned int uiDataSize_p)
{
tEplKernel Ret;
unsigned int uiCount = 0;
@@ -2154,7 +2154,7 @@ tEplKernel PUBLIC EplSdoAsyReceiveCb(tEplSdoConHdl ConHdl_p,
#endif
EPL_DBGLVL_SDO_TRACE2("Handle: 0x%x , First Databyte 0x%x\n", ConHdl_p,
- ((BYTE *) pSdoSeqData_p)[0]);
+ ((u8 *) pSdoSeqData_p)[0]);
// search controll structure for this connection
pAsySdoSeqCon = &AsySdoSequInstance_g.m_AsySdoConnection[uiCount];
@@ -2328,12 +2328,12 @@ static tEplKernel EplSdoAsyAddFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
//
//---------------------------------------------------------------------------
static tEplKernel EplSdoAsyAckFrameToHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
- BYTE bRecSeqNumber_p)
+ u8 bRecSeqNumber_p)
{
tEplKernel Ret;
tEplAsySdoConHistory *pHistory;
- BYTE bAckIndex;
- BYTE bCurrentSeqNum;
+ u8 bAckIndex;
+ u8 bCurrentSeqNum;
Ret = kEplSuccessful;
@@ -2422,8 +2422,8 @@ static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
// check if entries are available for reading
if ((pHistory->m_bFreeEntries < EPL_SDO_HISTORY_SIZE)
&& (pHistory->m_bWrite != pHistory->m_bRead)) {
-// PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (WORD)pHistory->m_bRead, (WORD)pHistory->m_bWrite, (WORD)pHistory->m_bAck);
-// PRINTF2(", free entries = %u, next frame size = %u\n", (WORD)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
+// PRINTF4("EplSdoAsyReadFromHistory(): init = %d, read = %u, write = %u, ack = %u", (int) fInitRead_p, (u16)pHistory->m_bRead, (u16)pHistory->m_bWrite, (u16)pHistory->m_bAck);
+// PRINTF2(", free entries = %u, next frame size = %u\n", (u16)pHistory->m_bFreeEntries, pHistory->m_auiFrameSize[pHistory->m_bRead]);
// return pointer to stored frame
*ppFrame_p =
@@ -2439,7 +2439,7 @@ static tEplKernel EplSdoAsyReadFromHistory(tEplAsySdoSeqCon * pAsySdoSeqCon_p,
}
} else {
-// PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (WORD)pHistory->m_bRead, (WORD)pHistory->m_bAck, (WORD)pHistory->m_bFreeEntries);
+// PRINTF3("EplSdoAsyReadFromHistory(): read = %u, ack = %u, free entries = %u, no frame\n", (u16)pHistory->m_bRead, (u16)pHistory->m_bAck, (u16)pHistory->m_bFreeEntries);
// no more frames to send
// return null pointer
diff --git a/drivers/staging/epl/EplSdoComu.c b/drivers/staging/epl/EplSdoComu.c
index ce0eb33f4c4..bf35afab152 100644
--- a/drivers/staging/epl/EplSdoComu.c
+++ b/drivers/staging/epl/EplSdoComu.c
@@ -156,14 +156,14 @@ typedef enum {
typedef struct {
tEplSdoSeqConHdl m_SdoSeqConHdl; // if != 0 -> entry used
tEplSdoComState m_SdoComState;
- BYTE m_bTransactionId;
+ u8 m_bTransactionId;
unsigned int m_uiNodeId; // NodeId of the target
// -> needed to reinit connection
// after timeout
tEplSdoTransType m_SdoTransType; // Auto, Expedited, Segmented
tEplSdoServiceType m_SdoServiceType; // WriteByIndex, ReadByIndex
tEplSdoType m_SdoProtType; // protocol layer: Auto, Udp, Asnd, Pdo
- BYTE *m_pData; // pointer to data
+ u8 *m_pData; // pointer to data
unsigned int m_uiTransSize; // number of bytes
// to transfer
unsigned int m_uiTransferredByte; // number of bytes
@@ -174,7 +174,7 @@ typedef struct {
// the SDO transfer
void *m_pUserArg; // user definable argument pointer
- DWORD m_dwLastAbortCode; // save the last abort code
+ u32 m_dwLastAbortCode; // save the last abort code
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
// only for client
unsigned int m_uiTargetIndex; // index to access
@@ -205,12 +205,12 @@ static tEplSdoComInstance SdoComInstance_g;
//---------------------------------------------------------------------------
// local function prototypes
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoCom * pAsySdoCom_p,
- unsigned int uiDataSize_p);
+tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoCom *pAsySdoCom_p,
+ unsigned int uiDataSize_p);
-tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoConState AsySdoConState_p);
+tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoConState AsySdoConState_p);
static tEplKernel EplSdoComSearchConIntern(tEplSdoSeqConHdl SdoSeqConHdl_p,
tEplSdoComConEvent SdoComConEvent_p,
@@ -246,7 +246,7 @@ static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
tEplAsySdoCom * pAsySdoCom_p);
static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
- DWORD dwAbortCode_p);
+ u32 dwAbortCode_p);
#endif
/***************************************************************************/
@@ -285,7 +285,7 @@ static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComInit(void)
+tEplKernel EplSdoComInit(void)
{
tEplKernel Ret;
@@ -312,7 +312,7 @@ tEplKernel PUBLIC EplSdoComInit(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComAddInstance(void)
+tEplKernel EplSdoComAddInstance(void)
{
tEplKernel Ret;
@@ -354,7 +354,7 @@ tEplKernel PUBLIC EplSdoComAddInstance(void)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComDelInstance(void)
+tEplKernel EplSdoComDelInstance(void)
{
tEplKernel Ret;
@@ -398,9 +398,9 @@ tEplKernel PUBLIC EplSdoComDelInstance(void)
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiTargetNodeId_p,
- tEplSdoType ProtType_p)
+tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiTargetNodeId_p,
+ tEplSdoType ProtType_p)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -511,8 +511,7 @@ tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
- pSdoComTransParam_p)
+tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -603,7 +602,7 @@ tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
+tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -669,8 +668,8 @@ tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p)
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
- tEplSdoComFinished * pSdoComFinished_p)
+tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
+ tEplSdoComFinished *pSdoComFinished_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -747,8 +746,8 @@ tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
//
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
- DWORD dwAbortCode_p)
+tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+ u32 dwAbortCode_p)
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
@@ -766,7 +765,7 @@ tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
goto Exit;
}
// save pointer to abort code
- pSdoComCon->m_pData = (BYTE *) & dwAbortCode_p;
+ pSdoComCon->m_pData = (u8 *) & dwAbortCode_p;
Ret = EplSdoComProcessIntern(SdoComConHdl_p,
kEplSdoComConEventAbort,
@@ -803,9 +802,9 @@ tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoCom * pAsySdoCom_p,
- unsigned int uiDataSize_p)
+tEplKernel EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoCom *pAsySdoCom_p,
+ unsigned int uiDataSize_p)
{
tEplKernel Ret;
@@ -815,7 +814,7 @@ tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
EPL_DBGLVL_SDO_TRACE3
("EplSdoComReceiveCb SdoSeqConHdl: 0x%X, First Byte of pAsySdoCom_p: 0x%02X, uiDataSize_p: 0x%04X\n",
- SdoSeqConHdl_p, (WORD) pAsySdoCom_p->m_le_abCommandData[0],
+ SdoSeqConHdl_p, (u16) pAsySdoCom_p->m_le_abCommandData[0],
uiDataSize_p);
return Ret;
@@ -840,8 +839,8 @@ tEplKernel PUBLIC EplSdoComReceiveCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
- tEplAsySdoConState AsySdoConState_p)
+tEplKernel EplSdoComConCb(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ tEplAsySdoConState AsySdoConState_p)
{
tEplKernel Ret;
tEplSdoComConEvent SdoComConEvent = kEplSdoComConEventSendFirst;
@@ -999,10 +998,10 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
{
tEplKernel Ret;
tEplSdoComCon *pSdoComCon;
- BYTE bFlag;
+ u8 bFlag;
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0)
- DWORD dwAbortCode;
+ u32 dwAbortCode;
unsigned int uiSize;
#endif
@@ -1138,7 +1137,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
pSdoComCon->
m_pData
=
- (BYTE
+ (u8
*)
&
dwAbortCode;
@@ -1283,7 +1282,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
if (pSdoComCon->
m_dwLastAbortCode ==
0) {
- ( /*(BYTE*) */
+ ( /*(u8*) */
pSdoComCon->
m_pData) +=
uiSize;
@@ -1321,7 +1320,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
pSdoComCon->
m_pData
=
- (BYTE
+ (u8
*)
&
pSdoComCon->
@@ -1667,7 +1666,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
case kEplSdoComConEventAbort:
{
EplSdoComClientSendAbort(pSdoComCon,
- *((DWORD *)
+ *((u32 *)
pSdoComCon->
m_pData));
@@ -1675,7 +1674,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
pSdoComCon->m_bTransactionId++;
// call callback of application
pSdoComCon->m_dwLastAbortCode =
- *((DWORD *) pSdoComCon->m_pData);
+ *((u32 *) pSdoComCon->m_pData);
Ret =
EplSdoComTransferFinished
(SdoComCon_p, pSdoComCon,
@@ -1869,7 +1868,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
case kEplSdoComConEventAbort:
{
EplSdoComClientSendAbort(pSdoComCon,
- *((DWORD *)
+ *((u32 *)
pSdoComCon->
m_pData));
@@ -1880,7 +1879,7 @@ static tEplKernel EplSdoComProcessIntern(tEplSdoComConHdl SdoComCon_p,
kEplSdoComStateClientConnected;
// call callback of application
pSdoComCon->m_dwLastAbortCode =
- *((DWORD *) pSdoComCon->m_pData);
+ *((u32 *) pSdoComCon->m_pData);
Ret =
EplSdoComTransferFinished
(SdoComCon_p, pSdoComCon,
@@ -1965,7 +1964,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
unsigned int uiSubindex;
tEplObdSize EntrySize;
tEplObdAccess AccessType;
- DWORD dwAbortCode;
+ u32 dwAbortCode;
dwAbortCode = 0;
@@ -1987,7 +1986,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
if (Ret == kEplObdSubindexNotExist) { // subentry doesn't exist
dwAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -1996,7 +1995,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
} else if (Ret != kEplSuccessful) { // entry doesn't exist
dwAbortCode = EPL_SDOAC_OBJECT_NOT_EXIST;
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2014,7 +2013,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
dwAbortCode = EPL_SDOAC_UNSUPPORTED_ACCESS;
}
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2051,7 +2050,7 @@ static tEplKernel EplSdoComServerInitReadByIndex(tEplSdoComCon * pSdoComCon_p,
// error -> abort
dwAbortCode = EPL_SDOAC_GENERAL_ERROR;
// send abort
- pSdoComCon_p->m_pData = (BYTE *) & dwAbortCode;
+ pSdoComCon_p->m_pData = (u8 *) & dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2090,11 +2089,11 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
tEplSdoComSendType SendType_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+ u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
tEplFrame *pFrame;
tEplAsySdoCom *pCommandFrame;
unsigned int uiSizeOfFrame;
- BYTE bFlag;
+ u8 bFlag;
Ret = kEplSuccessful;
@@ -2167,7 +2166,7 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
// set size of frame
AmiSetWordToLe(&pCommandFrame->
m_le_wSegmentSize,
- (WORD) pSdoComCon_p->
+ (u16) pSdoComCon_p->
m_uiTransSize);
// correct byte-counter
@@ -2297,7 +2296,7 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
// set segment size
AmiSetWordToLe(&pCommandFrame->
m_le_wSegmentSize,
- (WORD) pSdoComCon_p->
+ (u16) pSdoComCon_p->
m_uiTransSize);
// send frame
@@ -2324,18 +2323,18 @@ static tEplKernel EplSdoComServerSendFrameIntern(tEplSdoComCon * pSdoComCon_p,
// copy abortcode to frame
AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0],
- *((DWORD *) pSdoComCon_p->m_pData));
+ *((u32 *) pSdoComCon_p->m_pData));
// set size of segment
AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize,
- sizeof(DWORD));
+ sizeof(u32));
// update counter
- pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+ pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
pSdoComCon_p->m_uiTransSize = 0;
// calc framesize
- uiSizeOfFrame += sizeof(DWORD);
+ uiSizeOfFrame += sizeof(u32);
Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
uiSizeOfFrame, pFrame);
break;
@@ -2373,8 +2372,8 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
unsigned int uiBytesToTransfer;
tEplObdSize EntrySize;
tEplObdAccess AccessType;
- DWORD dwAbortCode;
- BYTE *pbSrcData;
+ u32 dwAbortCode;
+ u8 *pbSrcData;
dwAbortCode = 0;
@@ -2427,7 +2426,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
pSdoComCon_p->m_dwLastAbortCode = EPL_SDOAC_SUB_INDEX_NOT_EXIST;
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
- /*pSdoComCon_p->m_pData = (BYTE*)pSdoComCon_p->m_dwLastAbortCode;
+ /*pSdoComCon_p->m_pData = (u8*)pSdoComCon_p->m_dwLastAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2438,7 +2437,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
/*
- pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+ pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2458,7 +2457,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
}
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
- /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+ /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2549,7 +2548,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
EPL_SDOAC_DATA_TYPE_LENGTH_TOO_HIGH;
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
- /*pSdoComCon_p->m_pData = (BYTE*)&dwAbortCode;
+ /*pSdoComCon_p->m_pData = (u8*)&dwAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2571,7 +2570,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
EPL_SDOAC_GENERAL_ERROR;
// send abort
// d.k. This is wrong: k.t. not needed send abort on end of write
-/* pSdoComCon_p->m_pData = (BYTE*)&pSdoComCon_p->m_dwLastAbortCode;
+/* pSdoComCon_p->m_pData = (u8*)&pSdoComCon_p->m_dwLastAbortCode;
Ret = EplSdoComServerSendFrameIntern(pSdoComCon_p,
uiIndex,
uiSubindex,
@@ -2586,7 +2585,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
pSdoComCon_p->m_uiTransSize -= uiBytesToTransfer;
// update target pointer
- ( /*(BYTE*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
+ ( /*(u8*) */ pSdoComCon_p->m_pData) += uiBytesToTransfer;
// send acknowledge without any Command layer data
Ret = EplSdoAsySeqSendData(pSdoComCon_p->m_SdoSeqConHdl,
@@ -2598,7 +2597,7 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
if (pSdoComCon_p->m_dwLastAbortCode != 0) {
// send abort
pSdoComCon_p->m_pData =
- (BYTE *) & pSdoComCon_p->m_dwLastAbortCode;
+ (u8 *) & pSdoComCon_p->m_dwLastAbortCode;
Ret =
EplSdoComServerSendFrameIntern(pSdoComCon_p, uiIndex,
uiSubindex,
@@ -2635,12 +2634,12 @@ static tEplKernel EplSdoComServerInitWriteByIndex(tEplSdoComCon * pSdoComCon_p,
static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+ u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
tEplFrame *pFrame;
tEplAsySdoCom *pCommandFrame;
unsigned int uiSizeOfFrame;
- BYTE bFlags;
- BYTE *pbPayload;
+ u8 bFlags;
+ u8 *pbPayload;
Ret = kEplSuccessful;
@@ -2680,11 +2679,11 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
// create command header
AmiSetWordToLe(pbPayload,
- (WORD) pSdoComCon_p->
+ (u16) pSdoComCon_p->
m_uiTargetIndex);
pbPayload += 2;
AmiSetByteToLe(pbPayload,
- (BYTE) pSdoComCon_p->
+ (u8) pSdoComCon_p->
m_uiTargetSubIndex);
// calc size
uiSizeOfFrame += 4;
@@ -2721,12 +2720,12 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
bFlags);
// create command header
AmiSetWordToLe(pbPayload,
- (WORD)
+ (u16)
pSdoComCon_p->
m_uiTargetIndex);
pbPayload += 2;
AmiSetByteToLe(pbPayload,
- (BYTE)
+ (u8)
pSdoComCon_p->
m_uiTargetSubIndex);
// on byte for reserved
@@ -2760,12 +2759,12 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
// create command header
AmiSetWordToLe(pbPayload,
- (WORD)
+ (u16)
pSdoComCon_p->
m_uiTargetIndex);
pbPayload += 2;
AmiSetByteToLe(pbPayload,
- (BYTE)
+ (u8)
pSdoComCon_p->
m_uiTargetSubIndex);
// + 2 -> one byte for subindex and one byte reserved
@@ -2784,7 +2783,7 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
// fill rest of header
AmiSetWordToLe(&pCommandFrame->
m_le_wSegmentSize,
- (WORD) (4 +
+ (u16) (4 +
pSdoComCon_p->
m_uiTransSize));
@@ -2855,7 +2854,7 @@ static tEplKernel EplSdoComClientSend(tEplSdoComCon * pSdoComCon_p)
AmiSetWordToLe
(&pCommandFrame->
m_le_wSegmentSize,
- (WORD)
+ (u16)
pSdoComCon_p->
m_uiTransSize);
bFlags = 0x30;
@@ -2944,7 +2943,7 @@ static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
tEplAsySdoCom * pAsySdoCom_p)
{
tEplKernel Ret;
- BYTE bBuffer;
+ u8 bBuffer;
unsigned int uiBuffer;
unsigned int uiDataSize;
unsigned long ulBuffer;
@@ -3217,10 +3216,10 @@ static tEplKernel EplSdoComClientProcessFrame(tEplSdoComConHdl SdoComCon_p,
//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
- DWORD dwAbortCode_p)
+ u32 dwAbortCode_p)
{
tEplKernel Ret;
- BYTE abFrame[EPL_MAX_SDO_FRAME_SIZE];
+ u8 abFrame[EPL_MAX_SDO_FRAME_SIZE];
tEplFrame *pFrame;
tEplAsySdoCom *pCommandFrame;
unsigned int uiSizeOfFrame;
@@ -3250,14 +3249,14 @@ static tEplKernel EplSdoComClientSendAbort(tEplSdoComCon * pSdoComCon_p,
AmiSetDwordToLe(&pCommandFrame->m_le_abCommandData[0], dwAbortCode_p);
// set size of segment
- AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(DWORD));
+ AmiSetWordToLe(&pCommandFrame->m_le_wSegmentSize, sizeof(u32));
// update counter
- pSdoComCon_p->m_uiTransferredByte = sizeof(DWORD);
+ pSdoComCon_p->m_uiTransferredByte = sizeof(u32);
pSdoComCon_p->m_uiTransSize = 0;
// calc framesize
- uiSizeOfFrame += sizeof(DWORD);
+ uiSizeOfFrame += sizeof(u32);
// save abort code
pSdoComCon_p->m_dwLastAbortCode = dwAbortCode_p;
diff --git a/drivers/staging/epl/EplSdoUdpu.c b/drivers/staging/epl/EplSdoUdpu.c
index be52233b3ee..b409c9b7be4 100644
--- a/drivers/staging/epl/EplSdoUdpu.c
+++ b/drivers/staging/epl/EplSdoUdpu.c
@@ -72,11 +72,9 @@
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
#include "SocketLinuxKernel.h"
#include <linux/completion.h>
#include <linux/sched.h>
-#endif
/***************************************************************************/
/* */
@@ -110,17 +108,9 @@ typedef struct {
tEplSequLayerReceiveCb m_fpSdoAsySeqCb;
SOCKET m_UdpSocket;
-#if (TARGET_SYSTEM == _WIN32_)
- HANDLE m_ThreadHandle;
- LPCRITICAL_SECTION m_pCriticalSection;
- CRITICAL_SECTION m_CriticalSection;
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
struct completion m_CompletionUdpThread;
int m_ThreadHandle;
int m_iTerminateThread;
-#endif
-
} tEplSdoUdpInstance;
//---------------------------------------------------------------------------
@@ -133,12 +123,7 @@ static tEplSdoUdpInstance SdoUdpInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter);
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
static int EplSdoUdpThread(void *pArg_p);
-#endif
/***************************************************************************/
/* */
@@ -177,7 +162,7 @@ static int EplSdoUdpThread(void *pArg_p);
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
@@ -205,16 +190,10 @@ tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
+tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
{
tEplKernel Ret;
-#if (TARGET_SYSTEM == _WIN32_)
- int iError;
- WSADATA Wsa;
-
-#endif
-
// set instance variables to 0
EPL_MEMSET(&SdoUdpInstance_g, 0x00, sizeof(SdoUdpInstance_g));
@@ -228,24 +207,8 @@ tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
goto Exit;
}
-#if (TARGET_SYSTEM == _WIN32_)
- // start winsock2 for win32
- // windows specific start of socket
- iError = WSAStartup(MAKEWORD(2, 0), &Wsa);
- if (iError != 0) {
- Ret = kEplSdoUdpNoSocket;
- goto Exit;
- }
- // create critical section for acccess of instnace variables
- SdoUdpInstance_g.m_pCriticalSection =
- &SdoUdpInstance_g.m_CriticalSection;
- InitializeCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
init_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
SdoUdpInstance_g.m_iTerminateThread = 0;
-#endif
-
SdoUdpInstance_g.m_ThreadHandle = 0;
SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
@@ -273,32 +236,18 @@ tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p)
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuDelInstance()
+tEplKernel EplSdoUdpuDelInstance(void)
{
tEplKernel Ret;
-#if (TARGET_SYSTEM == _WIN32_)
- BOOL fTermError;
-#endif
-
Ret = kEplSuccessful;
if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
// close thread
-#if (TARGET_SYSTEM == _WIN32_)
- fTermError =
- TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
- if (fTermError == FALSE) {
- Ret = kEplSdoUdpThreadError;
- goto Exit;
- }
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
SdoUdpInstance_g.m_iTerminateThread = 1;
/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
-#endif
-
SdoUdpInstance_g.m_ThreadHandle = 0;
}
@@ -307,19 +256,6 @@ tEplKernel PUBLIC EplSdoUdpuDelInstance()
closesocket(SdoUdpInstance_g.m_UdpSocket);
SdoUdpInstance_g.m_UdpSocket = INVALID_SOCKET;
}
-#if (TARGET_SYSTEM == _WIN32_)
- // delete critical section
- DeleteCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
-#if (TARGET_SYSTEM == _WIN32_)
- // for win 32
- WSACleanup();
-#endif
-
-#if (TARGET_SYSTEM == _WIN32_)
- Exit:
-#endif
return Ret;
}
@@ -340,18 +276,12 @@ tEplKernel PUBLIC EplSdoUdpuDelInstance()
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
- unsigned int uiPort_p)
+tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p, unsigned int uiPort_p)
{
tEplKernel Ret;
struct sockaddr_in Addr;
int iError;
-#if (TARGET_SYSTEM == _WIN32_)
- BOOL fTermError;
- unsigned long ulThreadId;
-#endif
-
Ret = kEplSuccessful;
if (uiPort_p == 0) { // set UDP port to default port number
@@ -364,21 +294,11 @@ tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
if (SdoUdpInstance_g.m_ThreadHandle != 0) { // listen thread was started
// close old thread
-#if (TARGET_SYSTEM == _WIN32_)
- fTermError =
- TerminateThread(SdoUdpInstance_g.m_ThreadHandle, 0);
- if (fTermError == FALSE) {
- Ret = kEplSdoUdpThreadError;
- goto Exit;
- }
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
SdoUdpInstance_g.m_iTerminateThread = 1;
/* kill_proc(SdoUdpInstance_g.m_ThreadHandle, SIGTERM, 1 ); */
send_sig(SIGTERM, SdoUdpInstance_g.m_ThreadHandle, 1);
wait_for_completion(&SdoUdpInstance_g.m_CompletionUdpThread);
SdoUdpInstance_g.m_iTerminateThread = 0;
-#endif
-
SdoUdpInstance_g.m_ThreadHandle = 0;
}
@@ -413,28 +333,12 @@ tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
goto Exit;
}
// create Listen-Thread
-#if (TARGET_SYSTEM == _WIN32_)
- // for win32
-
- // create thread
- SdoUdpInstance_g.m_ThreadHandle = CreateThread(NULL,
- 0,
- EplSdoUdpThread,
- &SdoUdpInstance_g,
- 0, &ulThreadId);
- if (SdoUdpInstance_g.m_ThreadHandle == NULL) {
- Ret = kEplSdoUdpThreadError;
- goto Exit;
- }
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
-
SdoUdpInstance_g.m_ThreadHandle =
kernel_thread(EplSdoUdpThread, &SdoUdpInstance_g, CLONE_KERNEL);
if (SdoUdpInstance_g.m_ThreadHandle == 0) {
Ret = kEplSdoUdpThreadError;
goto Exit;
}
-#endif
Exit:
return Ret;
@@ -459,8 +363,8 @@ tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p)
+tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p)
{
tEplKernel Ret;
unsigned int uiCount;
@@ -526,8 +430,8 @@ tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p, DWORD dwDataSize_p)
+tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p, u32 dwDataSize_p)
{
tEplKernel Ret;
int iError;
@@ -553,22 +457,12 @@ tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
// call sendto
Addr.sin_family = AF_INET;
-#if (TARGET_SYSTEM == _WIN32_)
- // enter critical section for process function
- EnterCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
Addr.sin_port =
(unsigned short)SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].
m_uiPort;
Addr.sin_addr.s_addr =
SdoUdpInstance_g.m_aSdoAbsUdpConnection[uiArray].m_ulIpAddr;
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.m_pCriticalSection);
-#endif
-
iError = sendto(SdoUdpInstance_g.m_UdpSocket, // sockethandle
(const char *)&pSrcData_p->m_le_bMessageType, // data to send
dwDataSize_p, // number of bytes to send
@@ -603,7 +497,7 @@ tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
// State:
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
+tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
{
tEplKernel Ret;
unsigned int uiArray;
@@ -642,17 +536,13 @@ tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p)
// Parameters: lpParameter = pointer to parameter type tEplSdoUdpThreadPara
//
//
-// Returns: DWORD = errorcode
+// Returns: u32 = errorcode
//
//
// State:
//
//---------------------------------------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-static DWORD PUBLIC EplSdoUdpThread(LPVOID lpParameter)
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
static int EplSdoUdpThread(void *pArg_p)
-#endif
{
tEplSdoUdpInstance *pInstance;
@@ -660,21 +550,15 @@ static int EplSdoUdpThread(void *pArg_p)
int iError;
int iCount;
int iFreeEntry;
- BYTE abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
+ u8 abBuffer[EPL_MAX_SDO_REC_FRAME_SIZE];
unsigned int uiSize;
tEplSdoConHdl SdoConHdl;
-#if (TARGET_SYSTEM == _WIN32_)
- pInstance = (tEplSdoUdpInstance *) lpParameter;
-
- for (;;)
-#elif (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
pInstance = (tEplSdoUdpInstance *) pArg_p;
daemonize("EplSdoUdpThread");
allow_signal(SIGTERM);
for (; pInstance->m_iTerminateThread == 0;)
-#endif
{
// wait for data
@@ -685,20 +569,13 @@ static int EplSdoUdpThread(void *pArg_p)
0, // flags
(struct sockaddr *)&RemoteAddr,
(int *)&uiSize);
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
if (iError == -ERESTARTSYS) {
break;
}
-#endif
if (iError > 0) {
// get handle for higher layer
iCount = 0;
iFreeEntry = 0xFFFF;
-#if (TARGET_SYSTEM == _WIN32_)
- // enter critical section for process function
- EnterCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
while (iCount < EPL_SDO_MAX_CONNECTION_UDP) {
// check if this connection is already known
if ((pInstance->m_aSdoAbsUdpConnection[iCount].
@@ -734,11 +611,6 @@ static int EplSdoUdpThread(void *pArg_p)
pInstance->
m_aSdoAbsUdpConnection[iFreeEntry].
m_uiPort = RemoteAddr.sin_port;
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
// call callback
SdoConHdl = iFreeEntry;
SdoConHdl |= EPL_SDO_UDP_HANDLE;
@@ -752,11 +624,6 @@ static int EplSdoUdpThread(void *pArg_p)
} else {
EPL_DBGLVL_SDO_TRACE0
("Error in EplSdoUdpThread() no free handle\n");
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
}
} else {
@@ -764,11 +631,6 @@ static int EplSdoUdpThread(void *pArg_p)
// call callback with correct handle
SdoConHdl = iCount;
SdoConHdl |= EPL_SDO_UDP_HANDLE;
-#if (TARGET_SYSTEM == _WIN32_)
- // leave critical section for process function
- LeaveCriticalSection(SdoUdpInstance_g.
- m_pCriticalSection);
-#endif
// offset 4 -> start of SDO Sequence header
pInstance->m_fpSdoAsySeqCb(SdoConHdl,
(tEplAsySdoSeq *) &
@@ -778,10 +640,7 @@ static int EplSdoUdpThread(void *pArg_p)
} // end of if(iError!=SOCKET_ERROR)
} // end of for(;;)
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
complete_and_exit(&SdoUdpInstance_g.m_CompletionUdpThread, 0);
-#endif
-
return 0;
}
diff --git a/drivers/staging/epl/EplStatusu.c b/drivers/staging/epl/EplStatusu.c
index 689f9124ae2..b291399af10 100644
--- a/drivers/staging/epl/EplStatusu.c
+++ b/drivers/staging/epl/EplStatusu.c
@@ -137,8 +137,7 @@ static tEplStatusuInstance EplStatusuInstance_g;
// local function prototypes
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
- pFrameInfo_p);
+static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p);
//=========================================================================//
// //
@@ -164,7 +163,7 @@ static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuInit()
+tEplKernel EplStatusuInit(void)
{
tEplKernel Ret;
@@ -191,7 +190,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuInit()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuAddInstance()
+tEplKernel EplStatusuAddInstance(void)
{
tEplKernel Ret;
@@ -228,7 +227,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuAddInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuDelInstance()
+tEplKernel EplStatusuDelInstance(void)
{
tEplKernel Ret;
@@ -258,7 +257,7 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuDelInstance()
//
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplStatusuReset()
+tEplKernel EplStatusuReset(void)
{
tEplKernel Ret;
@@ -287,9 +286,8 @@ EPLDLLEXPORT tEplKernel PUBLIC EplStatusuReset()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
- tEplStatusuCbResponse
- pfnCbResponse_p)
+tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusuCbResponse pfnCbResponse_p)
{
tEplKernel Ret;
@@ -342,8 +340,7 @@ tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
// State:
//
//---------------------------------------------------------------------------
-static tEplKernel PUBLIC EplStatusuCbStatusResponse(tEplFrameInfo *
- pFrameInfo_p)
+static tEplKernel EplStatusuCbStatusResponse(tEplFrameInfo *pFrameInfo_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiNodeId;
diff --git a/drivers/staging/epl/EplTarget.h b/drivers/staging/epl/EplTarget.h
index b2b66f82c03..e76d21ff9d9 100644
--- a/drivers/staging/epl/EplTarget.h
+++ b/drivers/staging/epl/EplTarget.h
@@ -83,95 +83,11 @@
// applications needs to use one common library function (e.g. memcpy()). So
// you can set (or change) it here.
-#if (TARGET_SYSTEM == _WIN32_)
-
-#define _WIN32_WINDOWS 0x0401
-#define _WIN32_WINNT 0x0400
-
-#include <stdlib.h>
-#include <stdio.h>
-
- //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
-#include <string.h>
-
-#define EPL_MEMCPY(dst,src,siz) memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
-#define EPL_MEMSET(dst,val,siz) memset((void*)(dst),(int)(val),(size_t)(siz));
-
- // f.j.: die Funktionen für <MemAlloc> und <MemFree> sind in WinMem.c definiert
- //definition der Prototypen
-void FAR *MemAlloc(DWORD dwMemSize_p);
-void MemFree(void FAR * pMem_p);
-
-#define EPL_MALLOC(siz) malloc((size_t)(siz))
-#define EPL_FREE(ptr) free((void *)ptr)
-
-#ifndef PRINTF0
-void trace(const char *fmt, ...);
-#define PRINTF TRACE
-#define PRINTF0(arg) TRACE0(arg)
-#define PRINTF1(arg,p1) TRACE1(arg,p1)
-#define PRINTF2(arg,p1,p2) TRACE2(arg,p1,p2)
-#define PRINTF3(arg,p1,p2,p3) TRACE3(arg,p1,p2,p3)
-#define PRINTF4(arg,p1,p2,p3,p4) TRACE4(arg,p1,p2,p3,p4)
- //#define PRINTF printf
- //#define PRINTF0(arg) PRINTF(arg)
- //#define PRINTF1(arg,p1) PRINTF(arg,p1)
- //#define PRINTF2(arg,p1,p2) PRINTF(arg,p1,p2)
- //#define PRINTF3(arg,p1,p2,p3) PRINTF(arg,p1,p2,p3)
- //#define PRINTF4(arg,p1,p2,p3,p4) PRINTF(arg,p1,p2,p3,p4)
-#endif
-
-#ifdef ASSERTMSG
-#undef ASSERTMSG
-#endif
-
-#define ASSERTMSG(expr,string) if (!(expr)) { \
- MessageBox (NULL, string, "Assertion failed", MB_OK | MB_ICONERROR); \
- exit (-1);}
-
-#elif (TARGET_SYSTEM == _NO_OS_)
-
-#include <stdlib.h>
-#include <stdio.h>
-
- //29.11.2004 f.j. sonst ist memcpy und memset unbekannt
-// #include <string.h>
-
-#define EPL_MEMCPY(dst,src,siz) memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
-#define EPL_MEMSET(dst,val,siz) memset((void*)(dst),(int)(val),(size_t)(siz));
-
-#define EPL_MALLOC(siz) malloc((size_t)(siz))
-#define EPL_FREE(ptr) free((void *)ptr)
-
-#ifndef PRINTF0
-#define PRINTF TRACE
-#define PRINTF0(arg) TRACE0(arg)
-#define PRINTF1(arg,p1) TRACE1(arg,p1)
-#define PRINTF2(arg,p1,p2) TRACE2(arg,p1,p2)
-#define PRINTF3(arg,p1,p2,p3) TRACE3(arg,p1,p2,p3)
-#define PRINTF4(arg,p1,p2,p3,p4) TRACE4(arg,p1,p2,p3,p4)
- //#define PRINTF printf
- //#define PRINTF0(arg) PRINTF(arg)
- //#define PRINTF1(arg,p1) PRINTF(arg,p1)
- //#define PRINTF2(arg,p1,p2) PRINTF(arg,p1,p2)
- //#define PRINTF3(arg,p1,p2,p3) PRINTF(arg,p1,p2,p3)
- //#define PRINTF4(arg,p1,p2,p3,p4) PRINTF(arg,p1,p2,p3,p4)
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-
-#ifndef __KERNEL__
-#include <stdlib.h>
-#include <stdio.h>
-#else
-// #include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
-#endif
//29.11.2004 f.j. sonst ist memcpy und memset unbekannt
// #include <string.h>
@@ -179,13 +95,8 @@ void trace(const char *fmt, ...);
#define EPL_MEMCPY(dst,src,siz) memcpy((void*)(dst),(const void*)(src),(size_t)(siz));
#define EPL_MEMSET(dst,val,siz) memset((void*)(dst),(int)(val),(size_t)(siz));
-#ifndef __KERNEL__
-#define EPL_MALLOC(siz) malloc((size_t)(siz))
-#define EPL_FREE(ptr) free((void *)ptr)
-#else
#define EPL_MALLOC(siz) kmalloc((size_t)(siz), GFP_KERNEL)
#define EPL_FREE(ptr) kfree((void *)ptr)
-#endif
#ifndef PRINTF0
#define PRINTF TRACE
@@ -202,8 +113,6 @@ void trace(const char *fmt, ...);
//#define PRINTF4(arg,p1,p2,p3,p4) PRINTF(arg,p1,p2,p3,p4)
#endif
-#endif
-
#define EPL_TGT_INTMASK_ETH 0x0001 // ethernet interrupt
#define EPL_TGT_INTMASK_DMA 0x0002 // DMA interrupt
@@ -217,17 +126,15 @@ void trace(const char *fmt, ...);
// currently no Timer functions are needed by EPL stack
// so they are not implemented yet
-//void PUBLIC TgtTimerInit(void);
-//DWORD PUBLIC TgtGetTickCount(void);
-//void PUBLIC TgtGetNetTime(tEplNetTime * pNetTime_p);
+//void TgtTimerInit(void);
+//u32 TgtGetTickCount(void);
+//void TgtGetNetTime(tEplNetTime * pNetTime_p);
// functions for ethernet driver
-tEplKernel PUBLIC TgtInitEthIsr(void);
-void PUBLIC TgtFreeEthIsr(void);
-void PUBLIC TgtEnableGlobalInterrupt(BYTE fEnable_p);
-void PUBLIC TgtEnableEthInterrupt0(BYTE fEnable_p,
- unsigned int uiInterruptMask_p);
-void PUBLIC TgtEnableEthInterrupt1(BYTE fEnable_p,
- unsigned int uiInterruptMask_p);
+tEplKernel TgtInitEthIsr(void);
+void TgtFreeEthIsr(void);
+void TgtEnableGlobalInterrupt(u8 fEnable_p);
+void TgtEnableEthInterrupt0(u8 fEnable_p, unsigned int uiInterruptMask_p);
+void TgtEnableEthInterrupt1(u8 fEnable_p, unsigned int uiInterruptMask_p);
#endif // #ifndef _EPLTARGET_H_
diff --git a/drivers/staging/epl/EplTimer.h b/drivers/staging/epl/EplTimer.h
index facbfd8740e..d1a73eaf65c 100644
--- a/drivers/staging/epl/EplTimer.h
+++ b/drivers/staging/epl/EplTimer.h
@@ -107,8 +107,7 @@ typedef struct {
} tEplTimerEventArg;
-typedef tEplKernel(PUBLIC * tEplTimerkCallback) (tEplTimerEventArg *
- pEventArg_p);
+typedef tEplKernel(* tEplTimerkCallback) (tEplTimerEventArg *pEventArg_p);
//---------------------------------------------------------------------------
// function prototypes
diff --git a/drivers/staging/epl/EplTimeruLinuxKernel.c b/drivers/staging/epl/EplTimeruLinuxKernel.c
index 08820d18405..ff80fc80d02 100644
--- a/drivers/staging/epl/EplTimeruLinuxKernel.c
+++ b/drivers/staging/epl/EplTimeruLinuxKernel.c
@@ -99,7 +99,7 @@ typedef struct {
//---------------------------------------------------------------------------
// local function prototypes
//---------------------------------------------------------------------------
-static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
+static void EplTimeruCbMs(unsigned long ulParameter_p);
/***************************************************************************/
/* */
@@ -134,7 +134,7 @@ static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p);
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
+tEplKernel EplTimeruInit(void)
{
tEplKernel Ret;
@@ -157,7 +157,7 @@ tEplKernel PUBLIC EplTimeruInit()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
+tEplKernel EplTimeruAddInstance(void)
{
tEplKernel Ret;
@@ -182,7 +182,7 @@ tEplKernel PUBLIC EplTimeruAddInstance()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
+tEplKernel EplTimeruDelInstance(void)
{
tEplKernel Ret;
@@ -207,9 +207,9 @@ tEplKernel PUBLIC EplTimeruDelInstance()
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
+tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
@@ -257,9 +257,9 @@ tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
+tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
@@ -315,7 +315,7 @@ tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
+tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
@@ -370,7 +370,7 @@ tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
//
//---------------------------------------------------------------------------
-BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
+BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
{
BOOL fActive = FALSE;
tEplTimeruData *pData;
@@ -417,7 +417,7 @@ BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p)
// State:
//
//---------------------------------------------------------------------------
-static void PUBLIC EplTimeruCbMs(unsigned long ulParameter_p)
+static void EplTimeruCbMs(unsigned long ulParameter_p)
{
tEplKernel Ret = kEplSuccessful;
tEplTimeruData *pData;
diff --git a/drivers/staging/epl/EplTimeruNull.c b/drivers/staging/epl/EplTimeruNull.c
deleted file mode 100644
index 40ce403cbd0..00000000000
--- a/drivers/staging/epl/EplTimeruNull.c
+++ /dev/null
@@ -1,312 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: source file for Epl Userspace-Timermodule NULL-Implementation
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplTimeruNull.c,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- KEIL uVision 2
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/07/06 k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "user/EplTimeru.h"
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-
-/***************************************************************************/
-/* */
-/* */
-/* C L A S S <Epl Userspace-Timermodule NULL-Implementation> */
-/* */
-/* */
-/***************************************************************************/
-//
-// Description: Epl Userspace-Timermodule NULL-Implementation
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruInit
-//
-// Description: function init first instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
-{
- tEplKernel Ret;
-
- Ret = EplTimeruAddInstance();
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruAddInstance
-//
-// Description: function init additional instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruDelInstance
-//
-// Description: function delte instance
-// -> under Win32 nothing to do
-// -> no instnace table needed
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruSetTimerMs
-//
-// Description: function create a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // check handle
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruModifyTimerMs
-//
-// Description: function change a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruDeleteTimer
-//
-// Description: function delte a timer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
- // set handle invalide
- *pTimerHdl_p = 0;
-
- Exit:
- return Ret;
-
-}
-
-//=========================================================================//
-// //
-// P R I V A T E F U N C T I O N S //
-// //
-//=========================================================================//
-
-// EOF
diff --git a/drivers/staging/epl/EplTimeruWin32.c b/drivers/staging/epl/EplTimeruWin32.c
deleted file mode 100644
index a967b4e59d4..00000000000
--- a/drivers/staging/epl/EplTimeruWin32.c
+++ /dev/null
@@ -1,513 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: source file for Epl Userspace-Timermodule for Win32
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplTimeruWin32.c,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- GCC V3.4
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/07/06 k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "user/EplTimeru.h"
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// local types
-//---------------------------------------------------------------------------
-typedef struct {
- tEplTimerArg TimerArgument;
- HANDLE DelteHandle;
- unsigned long ulTimeout;
-
-} tEplTimeruThread;
-
-typedef struct {
- LPCRITICAL_SECTION m_pCriticalSection;
- CRITICAL_SECTION m_CriticalSection;
-} tEplTimeruInstance;
-//---------------------------------------------------------------------------
-// modul globale vars
-//---------------------------------------------------------------------------
-static tEplTimeruInstance EplTimeruInstance_g;
-static tEplTimeruThread ThreadData_l;
-//---------------------------------------------------------------------------
-// local function prototypes
-//---------------------------------------------------------------------------
-DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter);
-
-/***************************************************************************/
-/* */
-/* */
-/* C L A S S <Epl Userspace-Timermodule for Win32> */
-/* */
-/* */
-/***************************************************************************/
-//
-// Description: Epl Userspace-Timermodule for Win32
-//
-//
-/***************************************************************************/
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruInit
-//
-// Description: function init first instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruInit()
-{
- tEplKernel Ret;
-
- Ret = EplTimeruAddInstance();
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruAddInstance
-//
-// Description: function init additional instance
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruAddInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- // create critical section
- EplTimeruInstance_g.m_pCriticalSection =
- &EplTimeruInstance_g.m_CriticalSection;
- InitializeCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruDelInstance
-//
-// Description: function delte instance
-// -> under Win32 nothing to do
-// -> no instnace table needed
-//
-//
-//
-// Parameters:
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDelInstance()
-{
- tEplKernel Ret;
-
- Ret = kEplSuccessful;
-
- return Ret;
-}
-
-//---------------------------------------------------------------------------
-//
-// Function: EplTimeruSetTimerMs
-//
-// Description: function create a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
- HANDLE DeleteHandle;
- HANDLE ThreadHandle;
- DWORD ThreadId;
-
- Ret = kEplSuccessful;
-
- // check handle
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
- // enter critical section
- EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // first create event to delete timer
- DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (DeleteHandle == NULL) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // set handle for caller
- *pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
-
- // fill data for thread
- ThreadData_l.DelteHandle = DeleteHandle;
- EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
- sizeof(tEplTimerArg));
- ThreadData_l.ulTimeout = ulTime_p;
-
- // create thread to create waitable timer and wait for timer
- ThreadHandle = CreateThread(NULL,
- 0,
- EplSdoTimeruThreadms,
- &ThreadData_l, 0, &ThreadId);
- if (ThreadHandle == NULL) {
- // leave critical section
- LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // delte handle
- CloseHandle(DeleteHandle);
-
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruModifyTimerMs
-//
-// Description: function change a timer and return a handle to the pointer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-// ulTime_p = time for timer in ms
-// Argument_p = argument for timer
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p)
-{
- tEplKernel Ret;
- HANDLE DeleteHandle;
- HANDLE ThreadHandle;
- DWORD ThreadId;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- DeleteHandle = (HANDLE) (*pTimerHdl_p);
-
- // set event to end timer task for this timer
- SetEvent(DeleteHandle);
-
- // create new timer
- // first create event to delete timer
- DeleteHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
- if (DeleteHandle == NULL) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // set handle for caller
- *pTimerHdl_p = (tEplTimerHdl) DeleteHandle;
-
- // enter critical section
- EnterCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // fill data for thread
- ThreadData_l.DelteHandle = DeleteHandle;
- EPL_MEMCPY(&ThreadData_l.TimerArgument, &Argument_p,
- sizeof(tEplTimerArg));
- ThreadData_l.ulTimeout = ulTime_p;
-
- // create thread to create waitable timer and wait for timer
- ThreadHandle = CreateThread(NULL,
- 0,
- EplSdoTimeruThreadms,
- &ThreadData_l, 0, &ThreadId);
- if (ThreadHandle == NULL) {
- // leave critical section
- LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // delte handle
-
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
- //---------------------------------------------------------------------------
-//
-// Function: EplTimeruDeleteTimer
-//
-// Description: function delte a timer
-//
-//
-//
-// Parameters: pTimerHdl_p = pointer to a buffer to fill in the handle
-//
-//
-// Returns: tEplKernel = errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p)
-{
- tEplKernel Ret;
- HANDLE DeleteHandle;
-
- Ret = kEplSuccessful;
-
- // check parameter
- if (pTimerHdl_p == NULL) {
- Ret = kEplTimerInvalidHandle;
- goto Exit;
- }
-
- DeleteHandle = (HANDLE) (*pTimerHdl_p);
-
- // set event to end timer task for this timer
- SetEvent(DeleteHandle);
-
- // set handle invalide
- *pTimerHdl_p = 0;
-
- Exit:
- return Ret;
-
-}
-
-//=========================================================================//
-// //
-// P R I V A T E F U N C T I O N S //
-// //
-//=========================================================================//
-
-//---------------------------------------------------------------------------
-//
-// Function: EplSdoTimeruThreadms
-//
-// Description: function to process timer as thread
-//
-//
-//
-// Parameters: lpParameter = pointer to structur of type tEplTimeruThread
-//
-//
-// Returns: DWORD = Errorcode
-//
-//
-// State:
-//
-//---------------------------------------------------------------------------
-DWORD PUBLIC EplSdoTimeruThreadms(LPVOID lpParameter)
-{
- tEplKernel Ret;
- tEplTimeruThread *pThreadData;
- HANDLE aHandles[2];
- BOOL fReturn;
- LARGE_INTEGER TimeoutTime;
- unsigned long ulEvent;
- tEplEvent EplEvent;
- tEplTimeruThread ThreadData;
- tEplTimerEventArg TimerEventArg;
-
- Ret = kEplSuccessful;
-
- // get pointer to data
- pThreadData = (tEplTimeruThread *) lpParameter;
- // copy thread data
- EPL_MEMCPY(&ThreadData, pThreadData, sizeof(ThreadData));
- pThreadData = &ThreadData;
-
- // leave critical section
- LeaveCriticalSection(EplTimeruInstance_g.m_pCriticalSection);
-
- // create waitable timer
- aHandles[1] = CreateWaitableTimer(NULL, FALSE, NULL);
- if (aHandles[1] == NULL) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // set timer
- // set timeout interval -> needed to be negativ
- // -> because relative timeout
- // -> multiply by 10000 for 100 ns timebase of function
- TimeoutTime.QuadPart = (((long long)pThreadData->ulTimeout) * -10000);
- fReturn = SetWaitableTimer(aHandles[1],
- &TimeoutTime, 0, NULL, NULL, FALSE);
- if (fReturn == 0) {
- Ret = kEplTimerNoTimerCreated;
- goto Exit;
- }
- // save delte event handle in handle array
- aHandles[0] = pThreadData->DelteHandle;
-
- // wait for one of the events
- ulEvent = WaitForMultipleObjects(2, &aHandles[0], FALSE, INFINITE);
- if (ulEvent == WAIT_OBJECT_0) { // delte event
-
- // close handels
- CloseHandle(aHandles[1]);
- // terminate thread
- goto Exit;
- } else if (ulEvent == (WAIT_OBJECT_0 + 1)) { // timer event
- // call event function
- TimerEventArg.m_TimerHdl =
- (tEplTimerHdl) pThreadData->DelteHandle;
- TimerEventArg.m_ulArg = pThreadData->TimerArgument.m_ulArg;
-
- EplEvent.m_EventSink = pThreadData->TimerArgument.m_EventSink;
- EplEvent.m_EventType = kEplEventTypeTimer;
- EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(tEplNetTime));
- EplEvent.m_pArg = &TimerEventArg;
- EplEvent.m_uiSize = sizeof(TimerEventArg);
-
- Ret = EplEventuPost(&EplEvent);
-
- // close handels
- CloseHandle(aHandles[1]);
- // terminate thread
- goto Exit;
-
- } else { // error
- ulEvent = GetLastError();
- TRACE1("Error in WaitForMultipleObjects Errorcode: 0x%x\n",
- ulEvent);
- // terminate thread
- goto Exit;
- }
-
- Exit:
- return Ret;
-}
-
-// EOF
diff --git a/drivers/staging/epl/SharedBuff.c b/drivers/staging/epl/SharedBuff.c
index 9fb09d6bc28..2b10c375f3e 100644
--- a/drivers/staging/epl/SharedBuff.c
+++ b/drivers/staging/epl/SharedBuff.c
@@ -85,14 +85,8 @@
#include "SharedBuff.h"
#include "ShbIpc.h"
-// d.k. Linux kernel modules needs other header files for memcpy()
-#if (TARGET_SYSTEM == _LINUX_) && defined(__KERNEL__)
#include <linux/string.h>
-#else
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
+#include <linux/kernel.h>
/***************************************************************************/
/* */
@@ -102,8 +96,6 @@
/* */
/***************************************************************************/
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Configuration
//---------------------------------------------------------------------------
@@ -177,7 +169,7 @@ typedef struct {
// Get pointer to Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
+tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
{
tShbCirBuff *pShbCirBuff;
@@ -193,7 +185,7 @@ INLINE_FUNCTION tShbCirBuff *ShbCirGetBuffer(tShbInstance pShbInstance_p)
// Get pointer to Linear Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
+tShbLinBuff *ShbLinGetBuffer(tShbInstance pShbInstance_p)
{
tShbLinBuff *pShbLinBuff;
@@ -210,7 +202,6 @@ int ShbCirSignalHandlerNewData(tShbInstance pShbInstance_p);
void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
unsigned int fTimeOut_p);
-#endif
//=========================================================================//
// //
@@ -218,7 +209,6 @@ void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
// //
//=========================================================================//
-#if !defined(INLINE_ENABLED)
// not inlined external functions
//---------------------------------------------------------------------------
@@ -363,18 +353,13 @@ tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p)
}
-#endif // !defined(INLINE_ENABLED)
-
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Reset Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
- unsigned long ulTimeOut_p,
- tShbCirSigHndlrReset
- pfnSignalHandlerReset_p)
+tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
+ unsigned long ulTimeOut_p,
+ tShbCirSigHndlrReset pfnSignalHandlerReset_p)
{
tShbCirBuff *pShbCirBuff;
@@ -440,9 +425,9 @@ INLINE_FUNCTION tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
// Write data block to Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
- const void *pSrcDataBlock_p,
- unsigned long ulDataBlockSize_p)
+tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
+ const void *pSrcDataBlock_p,
+ unsigned long ulDataBlockSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -608,9 +593,9 @@ INLINE_FUNCTION tShbError ShbCirWriteDataBlock(tShbInstance pShbInstance_p,
// Allocate block within the Circular Shared Buffer for chunk writing
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
- tShbCirChunk * pShbCirChunk_p,
- unsigned long ulDataBufferSize_p)
+tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
+ tShbCirChunk * pShbCirChunk_p,
+ unsigned long ulDataBufferSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -717,12 +702,11 @@ INLINE_FUNCTION tShbError ShbCirAllocDataBlock(tShbInstance pShbInstance_p,
// Write data chunk into an allocated buffer of the Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
- tShbCirChunk * pShbCirChunk_p,
- const void *pSrcDataChunk_p,
- unsigned long ulDataChunkSize_p,
- unsigned int
- *pfBufferCompleted_p)
+tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
+ tShbCirChunk *pShbCirChunk_p,
+ const void *pSrcDataChunk_p,
+ unsigned long ulDataChunkSize_p,
+ unsigned int *pfBufferCompleted_p)
{
tShbCirBuff *pShbCirBuff;
@@ -857,10 +841,10 @@ INLINE_FUNCTION tShbError ShbCirWriteDataChunk(tShbInstance pShbInstance_p,
// Read data block from Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
- void *pDstDataBlock_p,
- unsigned long ulRdBuffSize_p,
- unsigned long *pulDataBlockSize_p)
+tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
+ void *pDstDataBlock_p,
+ unsigned long ulRdBuffSize_p,
+ unsigned long *pulDataBlockSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1009,9 +993,8 @@ INLINE_FUNCTION tShbError ShbCirReadDataBlock(tShbInstance pShbInstance_p,
// Get data size of next readable block from Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
- unsigned long
- *pulDataBlockSize_p)
+tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
+ unsigned long *pulDataBlockSize_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1070,9 +1053,8 @@ INLINE_FUNCTION tShbError ShbCirGetReadDataSize(tShbInstance pShbInstance_p,
// Get number of readable blocks from Circular Shared Buffer
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
- unsigned long
- *pulDataBlockCount_p)
+tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
+ unsigned long *pulDataBlockCount_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1113,12 +1095,9 @@ INLINE_FUNCTION tShbError ShbCirGetReadBlockCount(tShbInstance pShbInstance_p,
// d.k.: new parameter priority as enum
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData(tShbInstance
- pShbInstance_p,
- tShbCirSigHndlrNewData
- pfnSignalHandlerNewData_p,
- tShbPriority
- ShbPriority_p)
+tShbError ShbCirSetSignalHandlerNewData(tShbInstance pShbInstance_p,
+ tShbCirSigHndlrNewData pfnSignalHandlerNewData_p,
+ tShbPriority ShbPriority_p)
{
tShbCirBuff *pShbCirBuff;
@@ -1165,10 +1144,6 @@ INLINE_FUNCTION tShbError ShbCirSetSignalHandlerNewData(tShbInstance
}
-#endif
-
-#if !defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// DEBUG: Trace Circular Shared Buffer
//---------------------------------------------------------------------------
@@ -1413,18 +1388,13 @@ tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p)
}
-#endif // !defined(INLINE_ENABLED)
-
-#if (!defined(SHAREDBUFF_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Write data block to Linear Shared Buffer
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
- unsigned long ulDstBufferOffs_p,
- const void *pSrcDataBlock_p,
- unsigned long ulDataBlockSize_p)
+tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
+ unsigned long ulDstBufferOffs_p,
+ const void *pSrcDataBlock_p,
+ unsigned long ulDataBlockSize_p)
{
tShbLinBuff *pShbLinBuff;
@@ -1489,11 +1459,10 @@ INLINE_FUNCTION tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
//---------------------------------------------------------------------------
// Read data block from Linear Shared Buffer
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
- void *pDstDataBlock_p,
- unsigned long ulSrcBufferOffs_p,
- unsigned long ulDataBlockSize_p)
+tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
+ void *pDstDataBlock_p,
+ unsigned long ulSrcBufferOffs_p,
+ unsigned long ulDataBlockSize_p)
{
tShbLinBuff *pShbLinBuff;
@@ -1555,10 +1524,6 @@ INLINE_FUNCTION tShbError ShbLinReadDataBlock(tShbInstance pShbInstance_p,
}
-#endif
-
-#if !defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// DEBUG: Trace Linear Shared Buffer
//---------------------------------------------------------------------------
@@ -1639,7 +1604,7 @@ tShbError ShbTraceDump(const unsigned char *pabStartAddr_p,
ulBuffSize = ulDataSize_p;
if (pszInfoText_p != NULL) {
- TRACE0(pszInfoText_p);
+ TRACE1("%s", pszInfoText_p);
}
// dump buffer contents
for (nRow = 0;; nRow++) {
@@ -1794,6 +1759,4 @@ void ShbCirSignalHandlerReset(tShbInstance pShbInstance_p,
}
-#endif
-
// EOF
diff --git a/drivers/staging/epl/SharedBuff.h b/drivers/staging/epl/SharedBuff.h
index 0ec1b4b9e6a..4edbd0b2bd5 100644
--- a/drivers/staging/epl/SharedBuff.h
+++ b/drivers/staging/epl/SharedBuff.h
@@ -110,15 +110,6 @@ typedef void (*tShbCirSigHndlrReset) (tShbInstance pShbInstance_p,
extern "C" {
#endif
-/*#if defined(INLINE_FUNCTION_DEF)
- #undef INLINE_FUNCTION
- #define INLINE_FUNCTION INLINE_FUNCTION_DEF
- #define INLINE_ENABLED TRUE
- #define SHAREDBUFF_INLINED
- #include "SharedBuff.c"
-#endif
-*/
-
tShbError ShbInit(void);
tShbError ShbExit(void);
@@ -129,7 +120,6 @@ extern "C" {
unsigned int *pfShbNewCreated_p);
tShbError ShbCirReleaseBuffer(tShbInstance pShbInstance_p);
-#if !defined(INLINE_ENABLED)
tShbError ShbCirResetBuffer(tShbInstance pShbInstance_p,
unsigned long ulTimeOut_p,
@@ -159,7 +149,6 @@ extern "C" {
pfnShbSignalHandlerNewData_p,
tShbPriority ShbPriority_p);
-#endif
// Linear Shared Buffer
tShbError ShbLinAllocBuffer(unsigned long ulBufferSize_p,
@@ -168,7 +157,6 @@ extern "C" {
unsigned int *pfShbNewCreated_p);
tShbError ShbLinReleaseBuffer(tShbInstance pShbInstance_p);
-#if !defined(INLINE_ENABLED)
tShbError ShbLinWriteDataBlock(tShbInstance pShbInstance_p,
unsigned long ulDstBufferOffs_p,
@@ -179,7 +167,6 @@ extern "C" {
unsigned long ulSrcBufferOffs_p,
unsigned long ulDataBlockSize_p);
-#endif
#ifndef NDEBUG
tShbError ShbCirTraceBuffer(tShbInstance pShbInstance_p);
@@ -194,10 +181,6 @@ extern "C" {
#define ShbTraceDump(p0, p1, p2, p3)
#endif
-#undef INLINE_ENABLED // disable actual inlining of functions
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION // define INLINE_FUNCTION to nothing
-
#ifdef __cplusplus
}
#endif
diff --git a/drivers/staging/epl/ShbIpc-LinuxKernel.c b/drivers/staging/epl/ShbIpc-LinuxKernel.c
index 1d3cb3f13de..497938bd09b 100644
--- a/drivers/staging/epl/ShbIpc-LinuxKernel.c
+++ b/drivers/staging/epl/ShbIpc-LinuxKernel.c
@@ -79,8 +79,6 @@
/* */
/***************************************************************************/
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Configuration
//---------------------------------------------------------------------------
@@ -211,13 +209,11 @@ static inline tShbMemHeader *ShbIpcGetShbMemHeader(tShbMemInst * pShbMemInst_p)
// not inlined internal functions
int ShbIpcThreadSignalNewData(void *pvThreadParam_p);
int ShbIpcThreadSignalJobReady(void *pvThreadParam_p);
-#endif
//---------------------------------------------------------------------------
// modul globale vars
//---------------------------------------------------------------------------
-#if !defined(SHBIPC_INLINE_ENABLED)
struct sShbMemTable *psMemTableElementFirst_g;
static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
@@ -230,7 +226,6 @@ static void ShbIpcCrc32GenTable(unsigned long aulCrcTable[256]);
static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
unsigned long aulCrcTable[256]);
-#endif
//=========================================================================//
// //
@@ -238,7 +233,6 @@ static unsigned long ShbIpcCrc32GetCrc(const char *pcString,
// //
//=========================================================================//
-#if !defined(SHBIPC_INLINE_ENABLED)
// not inlined external functions
//---------------------------------------------------------------------------
@@ -433,15 +427,11 @@ tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
return (ShbError);
}
-#endif // !defined(SHBIPC_INLINE_ENABLED)
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Enter atomic section for Shared Buffer access
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
+tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
{
tShbMemInst *pShbMemInst;
@@ -469,7 +459,7 @@ INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
// Leave atomic section for Shared Buffer access
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
+tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
{
tShbMemInst *pShbMemInst;
@@ -496,12 +486,9 @@ INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
// Start signaling of new data (called from reading process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
- pShbInstance_p,
- tSigHndlrNewData
- pfnSignalHandlerNewData_p,
- tShbPriority
- ShbPriority_p)
+tShbError ShbIpcStartSignalingNewData(tShbInstance pShbInstance_p,
+ tSigHndlrNewData pfnSignalHandlerNewData_p,
+ tShbPriority ShbPriority_p)
{
tShbMemInst *pShbMemInst;
tShbMemHeader *pShbMemHeader;
@@ -557,8 +544,7 @@ INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
// Stop signaling of new data (called from reading process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
- pShbInstance_p)
+tShbError ShbIpcStopSignalingNewData(tShbInstance pShbInstance_p)
{
tShbMemInst *pShbMemInst;
tShbMemHeader *pShbMemHeader;
@@ -604,7 +590,7 @@ INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
// Signal new data (called from writing process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
+tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
{
tShbMemHeader *pShbMemHeader;
@@ -625,12 +611,9 @@ INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
// Start signaling for job ready (called from waiting process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
- pShbInstance_p,
- unsigned long
- ulTimeOut_p,
- tSigHndlrJobReady
- pfnSignalHandlerJobReady_p)
+tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
+ unsigned long ulTimeOut_p,
+ tSigHndlrJobReady pfnSignalHandlerJobReady_p)
{
tShbMemInst *pShbMemInst;
tShbMemHeader *pShbMemHeader;
@@ -663,7 +646,7 @@ INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
// Signal job ready (called from executing process)
//---------------------------------------------------------------------------
-INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
+tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
{
tShbMemHeader *pShbMemHeader;
@@ -685,7 +668,7 @@ INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
// Get pointer to common used share memory area
//---------------------------------------------------------------------------
-INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
+void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
{
tShbMemHeader *pShbMemHeader;
@@ -694,7 +677,7 @@ INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
pShbMemHeader =
ShbIpcGetShbMemHeader(ShbIpcGetShbMemInst(pShbInstance_p));
if (pShbMemHeader != NULL) {
- pShbShMemPtr = (BYTE *) pShbMemHeader + sizeof(tShbMemHeader);
+ pShbShMemPtr = (u8 *) pShbMemHeader + sizeof(tShbMemHeader);
} else {
pShbShMemPtr = NULL;
}
@@ -703,16 +686,12 @@ INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
}
-#endif
-
//=========================================================================//
// //
// P R I V A T E F U N C T I O N S //
// //
//=========================================================================//
-#if !defined(SHBIPC_INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// Get pointer to process local information structure
//---------------------------------------------------------------------------
@@ -963,4 +942,3 @@ static void ShbIpcDeleteListElement(int iBufferId)
}
-#endif
diff --git a/drivers/staging/epl/ShbIpc-Win32.c b/drivers/staging/epl/ShbIpc-Win32.c
deleted file mode 100644
index b9181471ae0..00000000000
--- a/drivers/staging/epl/ShbIpc-Win32.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: Project independend shared buffer (linear + circular)
-
- Description: Implementation of platform specific part for the
- shared buffer
- (Implementation for Win32)
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- 2006/06/27 -rs: V 1.00 (initial version)
-
-****************************************************************************/
-
-#define WINVER 0x0400 // #defines necessary for usage of
-#define _WIN32_WINNT 0x0400 // function <SignalObjectAndWait>
-
-#include <windows.h>
-#include <stdio.h>
-#include "global.h"
-#include "sharedbuff.h"
-#include "shbipc.h"
-
-/***************************************************************************/
-/* */
-/* */
-/* G L O B A L D E F I N I T I O N S */
-/* */
-/* */
-/***************************************************************************/
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-// Configuration
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Constant definitions
-//---------------------------------------------------------------------------
-
-#define MAX_LEN_BUFFER_ID MAX_PATH
-
-#define IDX_EVENT_NEW_DATA 0
-#define IDX_EVENT_TERM_REQU 1
-#define IDX_EVENT_TERM_RESP 2
-
-#define NAME_MUTEX_BUFF_ACCESS "BuffAccess"
-#define NAME_EVENT_NEW_DATA "NewData"
-#define NAME_EVENT_TERM_REQU "TermRequ"
-#define NAME_EVENT_TERM_RESP "TermResp"
-#define NAME_EVENT_JOB_READY "JobReady"
-
-#define TIMEOUT_ENTER_ATOMIC 1000 // for debgging: INFINITE
-#define TIMEOUT_TERM_THREAD 2000
-
-#define SBI_MAGIC_ID 0x5342492B // magic ID ("SBI+")
-#define SBH_MAGIC_ID 0x5342482A // magic ID ("SBH*")
-
-//---------------------------------------------------------------------------
-// Local types
-//---------------------------------------------------------------------------
-
-// This structure is the common header for the shared memory region used
-// by all processes attached this shared memory. It includes common
-// information to administrate/manage the shared buffer from a couple of
-// separated processes (e.g. the refernce counter). This structure is
-// located at the start of the shared memory region itself and exists
-// consequently only one times per shared memory instance.
-typedef struct {
- unsigned long m_SbhMagicID; // magic ID ("SBH*")
- unsigned long m_ulShMemSize;
- unsigned long m_ulRefCount;
- char m_szBufferID[MAX_LEN_BUFFER_ID];
-
-#ifndef NDEBUG
- unsigned long m_ulOwnerProcID;
-#endif
-
-} tShbMemHeader;
-
-// This structure is the "external entry point" from a separate process
-// to get access to a shared buffer. This structure includes all platform
-// resp. target specific information to administrate/manage the shared
-// buffer from a separate process. Every process attached to the shared
-// buffer has its own runtime instance of this structure with its individual
-// runtime data (e.g. the scope of an event handle is limitted to the
-// owner process only). The structure member <m_pShbMemHeader> points
-// to the (process specific) start address of the shared memory region
-// itself.
-typedef struct {
- unsigned long m_SbiMagicID; // magic ID ("SBI+")
- HANDLE m_hSharedMem;
- HANDLE m_hMutexBuffAccess;
- HANDLE m_hThreadNewData; // thraed to signal that new data are available
- HANDLE m_ahEventNewData[3]; // IDX_EVENT_NEW_DATA + IDX_EVENT_TERM_REQU + ID_EVENT_TERM_RESP
- tSigHndlrNewData m_pfnSigHndlrNewData;
- HANDLE m_hThreadJobReady; // thread to signal that a job/operation is ready now (e.g. reset buffer)
- HANDLE m_hEventJobReady;
- unsigned long m_ulTimeOutJobReady;
- tSigHndlrJobReady m_pfnSigHndlrJobReady;
- tShbMemHeader *m_pShbMemHeader;
-
-#ifndef NDEBUG
- unsigned long m_ulThreadIDNewData;
- unsigned long m_ulThreadIDJobReady;
-#endif
-
-} tShbMemInst;
-
-//---------------------------------------------------------------------------
-// Global variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Local variables
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Prototypes of internal functions
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// Get pointer to process local information structure
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbMemInst *ShbIpcGetShbMemInst(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
-
- pShbMemInst = (tShbMemInst *) pShbInstance_p;
- ASSERT(pShbMemInst->m_SbiMagicID == SBI_MAGIC_ID);
-
- return (pShbMemInst);
-
-}
-
-//---------------------------------------------------------------------------
-// Get pointer to shared memory header
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbMemHeader *ShbIpcGetShbMemHeader(tShbInstance
- pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = pShbMemInst->m_pShbMemHeader;
- ASSERT(pShbMemHeader->m_SbhMagicID == SBH_MAGIC_ID);
-
- return (pShbMemHeader);
-
-}
-
-// not inlined internal functions
-DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p);
-DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p);
-const char *ShbIpcGetUniformObjectName(const char *pszEventJobName_p,
- const char *pszBufferID_p,
- BOOL fGlobalObject_p);
-
-#endif
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-// true internal functions (not inlined)
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p);
-static void ShbIpcReleasePrivateMem(void *pMem_p);
-#endif
-
-//=========================================================================//
-// //
-// P U B L I C F U N C T I O N S //
-// //
-//=========================================================================//
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-// not inlined external functions
-
-//---------------------------------------------------------------------------
-// Initialize IPC for Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcInit(void)
-{
-
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Deinitialize IPC for Shared Buffer Module
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcExit(void)
-{
-
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Allocate Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
- const char *pszBufferID_p,
- tShbInstance * ppShbInstance_p,
- unsigned int *pfShbNewCreated_p)
-{
-
- HANDLE hSharedMem;
- LPVOID pSharedMem;
- unsigned long ulShMemSize;
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- tShbInstance pShbInstance;
- unsigned int fShMemNewCreated;
- const char *pszObjectName;
- HANDLE hMutexBuffAccess;
- HANDLE hEventNewData;
- HANDLE hEventJobReady;
- tShbError ShbError;
-
- ulShMemSize = ulBufferSize_p + sizeof(tShbMemHeader);
- pSharedMem = NULL;
- pShbInstance = NULL;
- fShMemNewCreated = FALSE;
- ShbError = kShbOk;
-
- //---------------------------------------------------------------
- // (1) open an existing or create a new shared memory
- //---------------------------------------------------------------
- // try to open an already existing shared memory
- // (created by an another process)
- hSharedMem = OpenFileMapping(FILE_MAP_ALL_ACCESS, // DWORD dwDesiredAccess
- FALSE, // BOOL bInheritHandle
- pszBufferID_p); // LPCTSTR lpName
- if (hSharedMem != NULL) {
- // a shared memory already exists
- fShMemNewCreated = FALSE;
- } else {
- // it seams that this process is the first who wants to use the
- // shared memory, so it has to create a new shared memory
- hSharedMem = CreateFileMapping(INVALID_HANDLE_VALUE, // HANDLE hFile
- NULL, // LPSECURITY_ATTRIBUTES lpAttributes
- PAGE_READWRITE, // DWORD flProtect
- 0, // DWORD dwMaximumSizeHigh
- ulShMemSize, // DWORD dwMaximumSizeLow
- pszBufferID_p); // LPCTSTR lpName
-
- fShMemNewCreated = TRUE;
- }
-
- if (hSharedMem == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
-
- //---------------------------------------------------------------
- // (2) get the pointer to the shared memory
- //---------------------------------------------------------------
- pSharedMem = MapViewOfFile(hSharedMem, // HANDLE hFileMappingObject
- FILE_MAP_ALL_ACCESS, // DWORD dwDesiredAccess,
- 0, // DWORD dwFileOffsetHigh,
- 0, // DWORD dwFileOffsetLow,
- ulShMemSize); // SIZE_T dwNumberOfBytesToMap
-
- if (pSharedMem == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
-
- //---------------------------------------------------------------
- // (3) setup or update header and management information
- //---------------------------------------------------------------
- pShbMemHeader = (tShbMemHeader *) pSharedMem;
-
- // allocate a memory block from process specific mempool to save
- // process local information to administrate/manage the shared buffer
- pShbMemInst =
- (tShbMemInst *) ShbIpcAllocPrivateMem(sizeof(tShbMemInst));
- if (pShbMemInst == NULL) {
- ShbError = kShbOutOfMem;
- goto Exit;
- }
- // reset complete header to default values
- pShbMemInst->m_SbiMagicID = SBI_MAGIC_ID;
- pShbMemInst->m_hSharedMem = hSharedMem;
- pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE;
- pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE;
- pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] =
- INVALID_HANDLE_VALUE;
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] =
- INVALID_HANDLE_VALUE;
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] =
- INVALID_HANDLE_VALUE;
- pShbMemInst->m_pfnSigHndlrNewData = NULL;
- pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE;
- pShbMemInst->m_hEventJobReady = INVALID_HANDLE_VALUE;
- pShbMemInst->m_ulTimeOutJobReady = 0;
- pShbMemInst->m_pfnSigHndlrJobReady = NULL;
- pShbMemInst->m_pShbMemHeader = pShbMemHeader;
-
-#ifndef NDEBUG
- {
- pShbMemInst->m_ulThreadIDNewData = 0;
- pShbMemInst->m_ulThreadIDJobReady = 0;
- }
-#endif
-
- // create mutex for buffer access
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_MUTEX_BUFF_ACCESS, pszBufferID_p,
- TRUE);
- hMutexBuffAccess = CreateMutex(NULL, // LPSECURITY_ATTRIBUTES lpMutexAttributes
- FALSE, // BOOL bInitialOwner
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_hMutexBuffAccess = hMutexBuffAccess;
- ASSERT(pShbMemInst->m_hMutexBuffAccess != NULL);
-
- // The EventNewData is used for signaling of new data after a write
- // operation (SetEvent) as well as for waiting for new data on the
- // reader side (WaitForMultipleObjects). Because it's not known if
- // this process will be read or write data, the event will be
- // always created here.
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_NEW_DATA, pszBufferID_p,
- TRUE);
- hEventNewData = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] = hEventNewData;
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] != NULL);
-
- // The EventJobReady is used for signaling that a job is done (SetEvent)
- // as well as for waiting for finishing of a job (WaitForMultipleObjects).
- // Because it's not known if this process will signal or wait, the event
- // will be always created here.
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_JOB_READY, pszBufferID_p,
- TRUE);
- hEventJobReady = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_hEventJobReady = hEventJobReady;
- ASSERT(pShbMemInst->m_hEventJobReady != NULL);
-
- if (fShMemNewCreated) {
- // this process was the first who wanted to use the shared memory,
- // so a new shared memory was created
- // -> setup new header information inside the shared memory region
- // itself
- pShbMemHeader->m_SbhMagicID = SBH_MAGIC_ID;
- pShbMemHeader->m_ulShMemSize = ulShMemSize;
- pShbMemHeader->m_ulRefCount = 1;
- strncpy(pShbMemHeader->m_szBufferID, pszBufferID_p,
- sizeof(pShbMemHeader->m_szBufferID) - 1);
-
-#ifndef NDEBUG
- {
- pShbMemHeader->m_ulOwnerProcID = GetCurrentProcessId();
- }
-#endif
- } else {
- // any other process has created the shared memory and this
- // process has only attached to it
- // -> check and update existing header information inside the
- // shared memory region itself
- if (pShbMemHeader->m_ulShMemSize != ulShMemSize) {
- ShbError = kShbOpenMismatch;
- goto Exit;
- }
-#ifndef NDEBUG
- {
- if (strncmp
- (pShbMemHeader->m_szBufferID, pszBufferID_p,
- sizeof(pShbMemHeader->m_szBufferID) - 1)) {
- ShbError = kShbOpenMismatch;
- goto Exit;
- }
- }
-#endif
-
- pShbMemHeader->m_ulRefCount++;
- }
-
- // set abstarct "handle" for returning to application
- pShbInstance = (tShbInstance *) pShbMemInst;
-
- Exit:
-
- if (ShbError != kShbOk) {
- if (pShbMemInst != NULL) {
- ShbIpcReleasePrivateMem(pShbMemInst);
- }
- if (pSharedMem != NULL) {
- UnmapViewOfFile(pSharedMem);
- }
- if (hSharedMem != NULL) {
- CloseHandle(hSharedMem);
- }
- }
-
- *pfShbNewCreated_p = fShMemNewCreated;
- *ppShbInstance_p = pShbInstance;
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Release Shared Buffer
-//---------------------------------------------------------------------------
-
-tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- HANDLE hEventNewData;
- HANDLE hMutexBuffAccess;
- tShbError ShbError;
- tShbError ShbError2;
-
- if (pShbInstance_p == NULL) {
- return (kShbOk);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
-
- if (!--pShbMemHeader->m_ulRefCount) {
- ShbError = kShbOk;
- } else {
- ShbError = kShbMemUsedByOtherProcs;
- }
-
- ShbError2 = ShbIpcStopSignalingNewData(pShbInstance_p);
- hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
- if (hEventNewData != INVALID_HANDLE_VALUE) {
- CloseHandle(hEventNewData);
- pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] =
- INVALID_HANDLE_VALUE;
- }
-
- hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
- if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
- CloseHandle(hMutexBuffAccess);
- pShbMemInst->m_hMutexBuffAccess = INVALID_HANDLE_VALUE;
- }
-
- UnmapViewOfFile(pShbMemHeader);
- if (pShbMemInst->m_hSharedMem != INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_hSharedMem);
- pShbMemInst->m_hSharedMem = INVALID_HANDLE_VALUE;
- }
-
- ShbIpcReleasePrivateMem(pShbMemInst);
-
- if (ShbError == kShbOk) {
- ShbError = ShbError2;
- }
-
- return (ShbError);
-
-}
-
-#endif // !defined(SHBIPC_INLINE_ENABLED)
-
-#if (!defined(SHBIPC_INLINED)) || defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-// Enter atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hMutexBuffAccess;
- DWORD dwWaitResult;
- tShbError ShbError;
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- ShbError = kShbOk;
-
- hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
- if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
- dwWaitResult =
- WaitForSingleObject(hMutexBuffAccess, TIMEOUT_ENTER_ATOMIC);
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0:
- {
- break;
- }
-
- case WAIT_TIMEOUT:
- {
- TRACE0
- ("\nShbIpcEnterAtomicSection(): WAIT_TIMEOUT");
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
-
- case WAIT_ABANDONED:
- {
- TRACE0
- ("\nShbIpcEnterAtomicSection(): WAIT_ABANDONED");
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
-
- case WAIT_FAILED:
- {
- TRACE1
- ("\nShbIpcEnterAtomicSection(): WAIT_FAILED -> LastError=%ld",
- GetLastError());
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
-
- default:
- {
- TRACE1
- ("\nShbIpcEnterAtomicSection(): unknown error -> LastError=%ld",
- GetLastError());
- ASSERT(0);
- ShbError = kShbBufferInvalid;
- break;
- }
- }
- } else {
- ShbError = kShbBufferInvalid;
- }
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Leave atomic section for Shared Buffer access
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hMutexBuffAccess;
- BOOL fRes;
- tShbError ShbError;
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- ShbError = kShbOk;
-
- hMutexBuffAccess = pShbMemInst->m_hMutexBuffAccess;
- if (hMutexBuffAccess != INVALID_HANDLE_VALUE) {
- fRes = ReleaseMutex(hMutexBuffAccess);
- ASSERT(fRes);
- } else {
- ShbError = kShbBufferInvalid;
- }
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Start signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStartSignalingNewData(tShbInstance
- pShbInstance_p,
- tSigHndlrNewData
- pfnSignalHandlerNewData_p,
- tShbPriority
- ShbPriority_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- const char *pszObjectName;
- HANDLE hEventTermRequ;
- HANDLE hEventTermResp;
- HANDLE hThreadNewData;
- unsigned long ulThreadIDNewData;
- tShbError ShbError;
- int iPriority;
-
- if ((pShbInstance_p == NULL) || (pfnSignalHandlerNewData_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
- ShbError = kShbOk;
-
- if ((pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) ||
- (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] !=
- INVALID_HANDLE_VALUE)
- || (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
- INVALID_HANDLE_VALUE)
- || (pShbMemInst->m_pfnSigHndlrNewData != NULL)) {
- ShbError = kShbAlreadySignaling;
- goto Exit;
- }
-
- pShbMemInst->m_pfnSigHndlrNewData = pfnSignalHandlerNewData_p;
-
- // Because the event <pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA]>
- // is used for signaling of new data after a write operation too (using
- // SetEvent), it is always created here (see <ShbIpcAllocBuffer>).
-
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_TERM_REQU,
- pShbMemHeader->m_szBufferID, FALSE);
- hEventTermRequ = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] = hEventTermRequ;
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] != NULL);
-
- pszObjectName =
- ShbIpcGetUniformObjectName(NAME_EVENT_TERM_RESP,
- pShbMemHeader->m_szBufferID, FALSE);
- hEventTermResp = CreateEvent(NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes
- FALSE, // BOOL bManualReset
- FALSE, // BOOL bInitialState
- pszObjectName); // LPCTSTR lpName
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] = hEventTermResp;
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] != NULL);
-
- hThreadNewData = CreateThread(NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes
- 0, // SIZE_T dwStackSize
- ShbIpcThreadSignalNewData, // LPTHREAD_START_ROUTINE lpStartAddress
- pShbInstance_p, // LPVOID lpParameter
- 0, // DWORD dwCreationFlags
- &ulThreadIDNewData); // LPDWORD lpThreadId
-
- switch (ShbPriority_p) {
- case kShbPriorityLow:
- iPriority = THREAD_PRIORITY_BELOW_NORMAL;
- break;
-
- case kShbPriorityNormal:
- iPriority = THREAD_PRIORITY_NORMAL;
- break;
-
- case kshbPriorityHigh:
- iPriority = THREAD_PRIORITY_ABOVE_NORMAL;
- break;
-
- }
-
- ASSERT(pShbMemInst->m_hThreadNewData != NULL);
-
- SetThreadPriority(hThreadNewData, iPriority);
-
- pShbMemInst->m_hThreadNewData = hThreadNewData;
-
-#ifndef NDEBUG
- {
- pShbMemInst->m_ulThreadIDNewData = ulThreadIDNewData;
- }
-#endif
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Stop signaling of new data (called from reading process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStopSignalingNewData(tShbInstance
- pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hEventTermRequ;
- HANDLE hEventTermResp;
- DWORD dwWaitResult;
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
- // terminate new data signaling thread
- // (set event <hEventTermRequ> to wakeup the thread and dispose it
- // to exit, then wait for confirmation using event <hEventTermResp>)
- hEventTermRequ = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU];
- hEventTermResp = pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP];
- if ((hEventTermRequ != INVALID_HANDLE_VALUE) &&
- (hEventTermResp != INVALID_HANDLE_VALUE)) {
- TRACE0("\nShbIpcStopSignalingNewData(): enter wait state");
- dwWaitResult = SignalObjectAndWait(hEventTermRequ, // HANDLE hObjectToSignal
- hEventTermResp, // HANDLE hObjectToWaitOn
- TIMEOUT_TERM_THREAD, // DWORD dwMilliseconds
- FALSE); // BOOL bAlertable
- TRACE0
- ("\nShbIpcStopSignalingNewData(): wait state leaved: ---> ");
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0: // event "new data signaling thread terminated"
- {
- TRACE0("Event = WAIT_OBJECT_0+0");
- break;
- }
-
- default:
- {
- TRACE0("Unhandled Event");
- ASSERT(0);
- break;
- }
- }
- }
-
- if (pShbMemInst->m_hThreadNewData != INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_hThreadNewData);
- pShbMemInst->m_hThreadNewData = INVALID_HANDLE_VALUE;
- }
-
- if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] !=
- INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU]);
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_REQU] =
- INVALID_HANDLE_VALUE;
- }
-
- if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
- INVALID_HANDLE_VALUE) {
- CloseHandle(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
- pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] =
- INVALID_HANDLE_VALUE;
- }
-
- pShbMemInst->m_pfnSigHndlrNewData = NULL;
-
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Signal new data (called from writing process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcSignalNewData(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hEventNewData;
- BOOL fRes;
-
- // TRACE0("\nShbIpcSignalNewData(): enter\n");
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
- ASSERT(pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA] !=
- INVALID_HANDLE_VALUE);
- hEventNewData = pShbMemInst->m_ahEventNewData[IDX_EVENT_NEW_DATA];
- if (hEventNewData != INVALID_HANDLE_VALUE) {
- fRes = SetEvent(hEventNewData);
- // TRACE1("\nShbIpcSignalNewData(): EventNewData set (Result=%d)\n", (int)fRes);
- ASSERT(fRes);
- }
- // TRACE0("\nShbIpcSignalNewData(): leave\n");
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Start signaling for job ready (called from waiting process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcStartSignalingJobReady(tShbInstance
- pShbInstance_p,
- unsigned long
- ulTimeOut_p,
- tSigHndlrJobReady
- pfnSignalHandlerJobReady_p)
-{
-
- tShbMemInst *pShbMemInst;
- tShbMemHeader *pShbMemHeader;
- HANDLE hThreadJobReady;
- unsigned long ulThreadIDJobReady;
- tShbError ShbError;
-
- if ((pShbInstance_p == NULL) || (pfnSignalHandlerJobReady_p == NULL)) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
- ShbError = kShbOk;
-
- if ((pShbMemInst->m_hThreadJobReady != INVALID_HANDLE_VALUE) ||
- (pShbMemInst->m_pfnSigHndlrJobReady != NULL)) {
- ShbError = kShbAlreadySignaling;
- goto Exit;
- }
-
- pShbMemInst->m_ulTimeOutJobReady = ulTimeOut_p;
- pShbMemInst->m_pfnSigHndlrJobReady = pfnSignalHandlerJobReady_p;
-
- // Because the event <pShbMemInst->m_ahEventJobReady> is used for
- // signaling of a finished job too (using SetEvent), it is always
- // created here (see <ShbIpcAllocBuffer>).
-
- hThreadJobReady = CreateThread(NULL, // LPSECURITY_ATTRIBUTES lpThreadAttributes
- 0, // SIZE_T dwStackSize
- ShbIpcThreadSignalJobReady, // LPTHREAD_START_ROUTINE lpStartAddress
- pShbInstance_p, // LPVOID lpParameter
- 0, // DWORD dwCreationFlags
- &ulThreadIDJobReady); // LPDWORD lpThreadId
-
- pShbMemInst->m_hThreadJobReady = hThreadJobReady;
- ASSERT(pShbMemInst->m_hThreadJobReady != NULL);
-
-#ifndef NDEBUG
- {
- pShbMemInst->m_ulThreadIDJobReady = ulThreadIDJobReady;
- }
-#endif
-
- Exit:
-
- return (ShbError);
-
-}
-
-//---------------------------------------------------------------------------
-// Signal job ready (called from executing process)
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p)
-{
-
- tShbMemInst *pShbMemInst;
- HANDLE hEventJobReady;
- BOOL fRes;
-
- // TRACE0("\nShbIpcSignalJobReady(): enter\n");
-
- if (pShbInstance_p == NULL) {
- return (kShbInvalidArg);
- }
-
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance_p);
-
- ASSERT(pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE);
- hEventJobReady = pShbMemInst->m_hEventJobReady;
- if (hEventJobReady != INVALID_HANDLE_VALUE) {
- fRes = SetEvent(hEventJobReady);
- // TRACE1("\nShbIpcSignalJobReady(): EventJobReady set (Result=%d)\n", (int)fRes);
- ASSERT(fRes);
- }
- // TRACE0("\nShbIpcSignalJobReady(): leave\n");
- return (kShbOk);
-
-}
-
-//---------------------------------------------------------------------------
-// Get pointer to common used share memory area
-//---------------------------------------------------------------------------
-
-INLINE_FUNCTION void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p)
-{
-
- tShbMemHeader *pShbMemHeader;
- void *pShbShMemPtr;
-
- pShbMemHeader = ShbIpcGetShbMemHeader(pShbInstance_p);
- if (pShbMemHeader != NULL) {
- pShbShMemPtr = (BYTE *) pShbMemHeader + sizeof(tShbMemHeader);
- } else {
- pShbShMemPtr = NULL;
- }
-
- return (pShbShMemPtr);
-
-}
-
-#endif
-
-//=========================================================================//
-// //
-// P R I V A T E F U N C T I O N S //
-// //
-//=========================================================================//
-
-#if !defined(SHBIPC_INLINE_ENABLED)
-
-//---------------------------------------------------------------------------
-// Allocate a memory block from process specific mempool
-//---------------------------------------------------------------------------
-
-static void *ShbIpcAllocPrivateMem(unsigned long ulMemSize_p)
-{
-
- HGLOBAL hMem;
- void *pMem;
-
- hMem = GlobalAlloc(GMEM_FIXED, ulMemSize_p + sizeof(HGLOBAL));
- pMem = GlobalLock(hMem);
- if (pMem != NULL) {
- *(HGLOBAL *) pMem = hMem;
- (BYTE *) pMem += sizeof(HGLOBAL);
- }
-
-#ifndef NDEBUG
- {
- memset(pMem, 0xaa, ulMemSize_p);
- }
-#endif
-
- return (pMem);
-
-}
-
-//---------------------------------------------------------------------------
-// Release a memory block from process specific mempool
-//---------------------------------------------------------------------------
-
-static void ShbIpcReleasePrivateMem(void *pMem_p)
-{
-
- HGLOBAL hMem;
-
- if (pMem_p == NULL) {
- return;
- }
-
- (BYTE *) pMem_p -= sizeof(HGLOBAL);
- hMem = *(HGLOBAL *) pMem_p;
-
- GlobalUnlock(hMem);
- GlobalFree(hMem);
-
- return;
-
-}
-
-//---------------------------------------------------------------------------
-// Create uniform object name (needed for inter-process communication)
-//---------------------------------------------------------------------------
-
-const char *ShbIpcGetUniformObjectName(const char *pszObjectJobName_p,
- const char *pszBufferID_p,
- BOOL fGlobalObject_p)
-{
-
- static char szObjectName[MAX_PATH];
- char szObjectPrefix[MAX_PATH];
-
- if (fGlobalObject_p) {
- strncpy(szObjectPrefix, "Global\\", sizeof(szObjectPrefix));
- } else {
- _snprintf(szObjectPrefix, sizeof(szObjectPrefix), "PID%08lX_",
- (unsigned long)GetCurrentProcessId());
- }
-
- _snprintf(szObjectName, sizeof(szObjectName), "%s%s#%s",
- szObjectPrefix, pszBufferID_p, pszObjectJobName_p);
-
- return (szObjectName);
-
-}
-
-//---------------------------------------------------------------------------
-// Thread for new data signaling
-//---------------------------------------------------------------------------
-
-DWORD WINAPI ShbIpcThreadSignalNewData(LPVOID pvThreadParam_p)
-{
-
- tShbInstance pShbInstance;
- tShbMemInst *pShbMemInst;
- DWORD dwWaitResult;
- BOOL fTermRequ;
- int fCallAgain;
-
- TRACE1
- ("\nShbIpcThreadSignalNewData(): SignalThread started (pShbInstance=0x%08lX)\n",
- (DWORD) pvThreadParam_p);
-
- pShbInstance = (tShbMemInst *) pvThreadParam_p;
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
- fTermRequ = FALSE;
-
- do {
- ASSERT((pShbMemInst->m_ahEventNewData[0] !=
- INVALID_HANDLE_VALUE)
- && (pShbMemInst->m_ahEventNewData[0] != NULL));
- ASSERT((pShbMemInst->m_ahEventNewData[1] !=
- INVALID_HANDLE_VALUE)
- && (pShbMemInst->m_ahEventNewData[1] != NULL));
-
- TRACE0("\nShbIpcThreadSignalNewData(): enter wait state");
- dwWaitResult = WaitForMultipleObjects(2, // DWORD nCount
- pShbMemInst->m_ahEventNewData, // const HANDLE* lpHandles
- FALSE, // BOOL bWaitAll
- INFINITE); // DWORD dwMilliseconds
- TRACE0
- ("\nShbIpcThreadSignalNewData(): wait state leaved: ---> ");
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0: // event "new data"
- {
- TRACE0("Event = WAIT_OBJECT_0+0");
- if (pShbMemInst->m_pfnSigHndlrNewData != NULL) {
- TRACE0
- ("\nShbIpcThreadSignalNewData(): calling SignalHandlerNewData");
- do {
- fCallAgain =
- pShbMemInst->
- m_pfnSigHndlrNewData
- (pShbInstance);
- // d.k.: try to run any shared buffer which has higher priority.
- // under Windows this is not really necessary because the Windows scheduler
- // already preempts tasks with lower priority.
- } while (fCallAgain != FALSE);
- }
- break;
- }
-
- case WAIT_OBJECT_0 + 1: // event "terminate"
- {
- TRACE0("Event = WAIT_OBJECT_0+1");
- fTermRequ = TRUE;
- break;
- }
-
- default:
- {
- TRACE0("Unhandled Event");
- ASSERT(0);
- fTermRequ = TRUE;
- break;
- }
- }
- }
- while (!fTermRequ);
-
- if (pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP] !=
- INVALID_HANDLE_VALUE) {
- SetEvent(pShbMemInst->m_ahEventNewData[IDX_EVENT_TERM_RESP]);
- }
-
- TRACE1
- ("\nShbIpcThreadSignalNewData(): SignalThread terminated (pShbInstance=0x%08lX)\n",
- (DWORD) pShbInstance);
-
- ExitThread(0);
-
-}
-
-//---------------------------------------------------------------------------
-// Thread for new data signaling
-//---------------------------------------------------------------------------
-
-DWORD WINAPI ShbIpcThreadSignalJobReady(LPVOID pvThreadParam_p)
-{
-
- tShbInstance *pShbInstance;
- tShbMemInst *pShbMemInst;
- DWORD ulTimeOut;
- DWORD dwWaitResult;
- unsigned int fTimeOut;
-
- TRACE1
- ("\nShbIpcThreadSignalJobReady(): SignalThread started (pShbInstance=0x%08lX)\n",
- (DWORD) pvThreadParam_p);
-
- pShbInstance = (tShbInstance *) pvThreadParam_p;
- pShbMemInst = ShbIpcGetShbMemInst(pShbInstance);
- fTimeOut = FALSE;
-
- if (pShbMemInst->m_ulTimeOutJobReady != 0) {
- ulTimeOut = pShbMemInst->m_ulTimeOutJobReady;
- } else {
- ulTimeOut = INFINITE;
- }
-
- ASSERT((pShbMemInst->m_hEventJobReady != INVALID_HANDLE_VALUE)
- && (pShbMemInst->m_hEventJobReady != NULL));
-
- TRACE0("\nShbIpcThreadSignalJobReady(): enter wait state");
- dwWaitResult = WaitForSingleObject(pShbMemInst->m_hEventJobReady, // HANDLE hHandle
- ulTimeOut); // DWORD dwMilliseconds
- TRACE0("\nShbIpcThreadSignalJobReady(): wait state leaved: ---> ");
- switch (dwWaitResult) {
- case WAIT_OBJECT_0 + 0: // event "new data"
- {
- TRACE0("Event = WAIT_OBJECT_0+0");
- fTimeOut = FALSE;
- break;
- }
-
- case WAIT_TIMEOUT:
- {
- TRACE0("\nEvent = WAIT_TIMEOUT");
- fTimeOut = TRUE;
- // ASSERT(0);
- break;
- }
-
- default:
- {
- TRACE0("Unhandled Event");
- fTimeOut = TRUE;
- ASSERT(0);
- break;
- }
- }
-
- if (pShbMemInst->m_pfnSigHndlrJobReady != NULL) {
- TRACE0
- ("\nShbIpcThreadSignalJobReady(): calling SignalHandlerJobReady");
- pShbMemInst->m_pfnSigHndlrJobReady(pShbInstance, fTimeOut);
- }
-
- pShbMemInst->m_hThreadJobReady = INVALID_HANDLE_VALUE;
- pShbMemInst->m_pfnSigHndlrJobReady = NULL;
-
- TRACE1
- ("\nShbIpcThreadSignalJobReady(): SignalThread terminated (pShbInstance=0x%08lX)\n",
- (DWORD) pShbInstance);
-
- ExitThread(0);
-
-}
-
-#endif
-
-// EOF
diff --git a/drivers/staging/epl/ShbIpc.h b/drivers/staging/epl/ShbIpc.h
index cad8846a082..285f096e771 100644
--- a/drivers/staging/epl/ShbIpc.h
+++ b/drivers/staging/epl/ShbIpc.h
@@ -65,25 +65,6 @@ typedef int (*tSigHndlrNewData) (tShbInstance pShbInstance_p);
typedef void (*tSigHndlrJobReady) (tShbInstance pShbInstance_p,
unsigned int fTimeOut_p);
-#if (TARGET_SYSTEM == _WIN32_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define SHBIPC_INLINE_ENABLED TRUE
-#define SHBIPC_INLINED
-#include "ShbIpc-Win32.c"
-#endif
-
-#elif (TARGET_SYSTEM == _LINUX_)
-#if defined(INLINE_FUNCTION_DEF)
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION INLINE_FUNCTION_DEF
-#define SHBIPC_INLINE_ENABLED TRUE
-#define SHBIPC_INLINED
-#include "ShbIpc-LinuxKernel.c"
-#endif
-#endif
-
//---------------------------------------------------------------------------
// Prototypes
//---------------------------------------------------------------------------
@@ -97,8 +78,6 @@ tShbError ShbIpcAllocBuffer(unsigned long ulBufferSize_p,
unsigned int *pfShbNewCreated_p);
tShbError ShbIpcReleaseBuffer(tShbInstance pShbInstance_p);
-#if !defined(SHBIPC_INLINE_ENABLED)
-
tShbError ShbIpcEnterAtomicSection(tShbInstance pShbInstance_p);
tShbError ShbIpcLeaveAtomicSection(tShbInstance pShbInstance_p);
@@ -116,10 +95,5 @@ tShbError ShbIpcStartSignalingJobReady(tShbInstance pShbInstance_p,
tShbError ShbIpcSignalJobReady(tShbInstance pShbInstance_p);
void *ShbIpcGetShMemPtr(tShbInstance pShbInstance_p);
-#endif
-
-#undef SHBIPC_INLINE_ENABLED // disable actual inlining of functions
-#undef INLINE_FUNCTION
-#define INLINE_FUNCTION // define INLINE_FUNCTION to nothing
#endif // #ifndef _SHBIPC_H_
diff --git a/drivers/staging/epl/TimerHighReskX86.c b/drivers/staging/epl/TimerHighReskX86.c
index 82eee4702aa..d6897de4f14 100644
--- a/drivers/staging/epl/TimerHighReskX86.c
+++ b/drivers/staging/epl/TimerHighReskX86.c
@@ -97,14 +97,10 @@
#define PROVE_OVERRUN
-#ifndef CONFIG_HIGH_RES_TIMERS
-#error "Kernel symbol CONFIG_HIGH_RES_TIMERS is required."
-#endif
-
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
#else
@@ -172,7 +168,7 @@ enum hrtimer_restart EplTimerHighReskCallback(struct hrtimer *pTimer_p);
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskInit(void)
+tEplKernel EplTimerHighReskInit(void)
{
tEplKernel Ret;
@@ -196,7 +192,7 @@ tEplKernel PUBLIC EplTimerHighReskInit(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
+tEplKernel EplTimerHighReskAddInstance(void)
{
tEplKernel Ret;
unsigned int uiIndex;
@@ -206,13 +202,6 @@ tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
EPL_MEMSET(&EplTimerHighReskInstance_l, 0,
sizeof(EplTimerHighReskInstance_l));
-#ifndef CONFIG_HIGH_RES_TIMERS
- printk
- ("EplTimerHighResk: Kernel symbol CONFIG_HIGH_RES_TIMERS is required.\n");
- Ret = kEplNoResource;
- return Ret;
-#endif
-
/*
* Initialize hrtimer structures for all usable timers.
*/
@@ -244,7 +233,7 @@ tEplKernel PUBLIC EplTimerHighReskAddInstance(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskDelInstance(void)
+tEplKernel EplTimerHighReskDelInstance(void)
{
tEplTimerHighReskTimerInfo *pTimerInfo;
tEplKernel Ret;
@@ -298,12 +287,11 @@ tEplKernel PUBLIC EplTimerHighReskDelInstance(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
- unsigned long long ullTimeNs_p,
- tEplTimerkCallback
- pfnCallback_p,
- unsigned long ulArgument_p,
- BOOL fContinuously_p)
+tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long long ullTimeNs_p,
+ tEplTimerkCallback pfnCallback_p,
+ unsigned long ulArgument_p,
+ BOOL fContinuously_p)
{
tEplKernel Ret;
unsigned int uiIndex;
@@ -396,7 +384,7 @@ tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl * pTimerHdl_p)
+tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p)
{
tEplKernel Ret = kEplSuccessful;
unsigned int uiIndex;
diff --git a/drivers/staging/epl/VirtualEthernetLinux.c b/drivers/staging/epl/VirtualEthernetLinux.c
index 5d838dbf73a..21206c4d22f 100644
--- a/drivers/staging/epl/VirtualEthernetLinux.c
+++ b/drivers/staging/epl/VirtualEthernetLinux.c
@@ -74,7 +74,6 @@
****************************************************************************/
-#include <linux/version.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -285,7 +284,7 @@ static tEplKernel VEthRecvFrame(tEplFrameInfo * pFrameInfo_p)
return Ret;
}
-tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p)
+tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p)
{
tEplKernel Ret = kEplSuccessful;
@@ -324,7 +323,7 @@ tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p)
return Ret;
}
-tEplKernel PUBLIC VEthDelInstance(void)
+tEplKernel VEthDelInstance(void)
{
tEplKernel Ret = kEplSuccessful;
diff --git a/drivers/staging/epl/amix86.c b/drivers/staging/epl/amix86.c
index 9f742384dac..d40ad918d3b 100644
--- a/drivers/staging/epl/amix86.c
+++ b/drivers/staging/epl/amix86.c
@@ -74,24 +74,22 @@
//#include "EplAmi.h"
#include "EplInc.h"
-#if (!defined(EPL_AMI_INLINED)) || defined(INLINE_ENABLED)
-
//---------------------------------------------------------------------------
// typedef
//---------------------------------------------------------------------------
typedef struct {
- WORD m_wWord;
+ u16 m_wWord;
} twStruct;
typedef struct {
- DWORD m_dwDword;
+ u32 m_dwDword;
} tdwStruct;
typedef struct {
- QWORD m_qwQword;
+ u64 m_qwQword;
} tqwStruct;
@@ -117,37 +115,36 @@ typedef struct {
//
//---------------------------------------------------------------------------
-//------------< write BYTE in big endian >--------------------------
+//------------< write u8 in big endian >--------------------------
/*
-void PUBLIC AmiSetByteToBe (void FAR* pAddr_p, BYTE bByteVal_p)
+void AmiSetByteToBe (void *pAddr_p, u8 bByteVal_p)
{
- *(BYTE FAR*)pAddr_p = bByteVal_p;
+ *(u8 *)pAddr_p = bByteVal_p;
}
*/
-//------------< write WORD in big endian >--------------------------
+//------------< write u16 in big endian >--------------------------
-INLINE_FUNCTION void PUBLIC AmiSetWordToBe(void FAR * pAddr_p, WORD wWordVal_p)
+void AmiSetWordToBe(void * pAddr_p, u16 wWordVal_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
twStruct wValue;
- wValue.m_wWord = (WORD) ((wWordVal_p & 0x00FF) << 8); //LSB to MSB
- wValue.m_wWord |= (WORD) ((wWordVal_p & 0xFF00) >> 8); //MSB to LSB
+ wValue.m_wWord = (u16) ((wWordVal_p & 0x00FF) << 8); //LSB to MSB
+ wValue.m_wWord |= (u16) ((wWordVal_p & 0xFF00) >> 8); //MSB to LSB
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
pwStruct->m_wWord = wValue.m_wWord;
}
-//------------< write DWORD in big endian >-------------------------
+//------------< write u32 in big endian >-------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDwordToBe(void *pAddr_p, u32 dwDwordVal_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
tdwStruct dwValue;
dwValue.m_dwDword = ((dwDwordVal_p & 0x000000FF) << 24); //LSB to MSB
@@ -155,7 +152,7 @@ INLINE_FUNCTION void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p,
dwValue.m_dwDword |= ((dwDwordVal_p & 0x00FF0000) >> 8);
dwValue.m_dwDword |= ((dwDwordVal_p & 0xFF000000) >> 24); //MSB to LSB
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
pdwStruct->m_dwDword = dwValue.m_dwDword;
}
@@ -176,35 +173,34 @@ INLINE_FUNCTION void PUBLIC AmiSetDwordToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-//------------< write BYTE in little endian >--------------------------
+//------------< write u8 in little endian >--------------------------
/*
-void PUBLIC AmiSetByteToLe (void FAR* pAddr_p, BYTE bByteVal_p)
+void AmiSetByteToLe (void *pAddr_p, u8 bByteVal_p)
{
- *(BYTE FAR*)pAddr_p = bByteVal_p;
+ *(u8 *)pAddr_p = bByteVal_p;
}
*/
-//------------< write WORD in little endian >--------------------------
+//------------< write u16 in little endian >--------------------------
-INLINE_FUNCTION void PUBLIC AmiSetWordToLe(void FAR * pAddr_p, WORD wWordVal_p)
+void AmiSetWordToLe(void *pAddr_p, u16 wWordVal_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
pwStruct->m_wWord = wWordVal_p;
}
-//------------< write DWORD in little endian >-------------------------
+//------------< write u32 in little endian >-------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDwordToLe(void *pAddr_p, u32 dwDwordVal_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
pdwStruct->m_dwDword = dwDwordVal_p;
}
@@ -224,40 +220,40 @@ INLINE_FUNCTION void PUBLIC AmiSetDwordToLe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-//------------< read BYTE in big endian >---------------------------
+//------------< read u8 in big endian >---------------------------
/*
-BYTE PUBLIC AmiGetByteFromBe (void FAR* pAddr_p)
+u8 AmiGetByteFromBe (void *pAddr_p)
{
- return ( *(BYTE FAR*)pAddr_p );
+ return ( *(u8 *)pAddr_p );
}
*/
-//------------< read WORD in big endian >---------------------------
+//------------< read u16 in big endian >---------------------------
-INLINE_FUNCTION WORD PUBLIC AmiGetWordFromBe(void FAR * pAddr_p)
+u16 AmiGetWordFromBe(void *pAddr_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
twStruct wValue;
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
- wValue.m_wWord = (WORD) ((pwStruct->m_wWord & 0x00FF) << 8); //LSB to MSB
- wValue.m_wWord |= (WORD) ((pwStruct->m_wWord & 0xFF00) >> 8); //MSB to LSB
+ wValue.m_wWord = (u16) ((pwStruct->m_wWord & 0x00FF) << 8); //LSB to MSB
+ wValue.m_wWord |= (u16) ((pwStruct->m_wWord & 0xFF00) >> 8); //MSB to LSB
return (wValue.m_wWord);
}
-//------------< read DWORD in big endian >--------------------------
+//------------< read u32 in big endian >--------------------------
-INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p)
+u32 AmiGetDwordFromBe(void *pAddr_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
tdwStruct dwValue;
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
dwValue.m_dwDword = ((pdwStruct->m_dwDword & 0x000000FF) << 24); //LSB to MSB
dwValue.m_dwDword |= ((pdwStruct->m_dwDword & 0x0000FF00) << 8);
@@ -283,36 +279,34 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromBe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-//------------< read BYTE in little endian >---------------------------
+//------------< read u8 in little endian >---------------------------
/*
-BYTE PUBLIC AmiGetByteFromLe (void FAR* pAddr_p)
+u8 AmiGetByteFromLe (void *pAddr_p)
{
- return ( *(BYTE FAR*)pAddr_p );
+ return ( *(u8 *)pAddr_p );
}
*/
-//------------< read WORD in little endian >---------------------------
+//------------< read u16 in little endian >---------------------------
-INLINE_FUNCTION WORD PUBLIC AmiGetWordFromLe(void FAR * pAddr_p)
+u16 AmiGetWordFromLe(void *pAddr_p)
{
- twStruct FAR *pwStruct;
+ twStruct *pwStruct;
- pwStruct = (twStruct FAR *) pAddr_p;
+ pwStruct = (twStruct *) pAddr_p;
return (pwStruct->m_wWord);
-
}
-//------------< read DWORD in little endian >--------------------------
+//------------< read u32 in little endian >--------------------------
-INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p)
+u32 AmiGetDwordFromLe(void *pAddr_p)
{
- tdwStruct FAR *pdwStruct;
+ tdwStruct *pdwStruct;
- pdwStruct = (tdwStruct FAR *) pAddr_p;
+ pdwStruct = (tdwStruct *) pAddr_p;
return (pdwStruct->m_dwDword);
-
}
//---------------------------------------------------------------------------
@@ -330,14 +324,11 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDwordFromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDword24ToBe(void *pAddr_p, u32 dwDwordVal_p)
{
-
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & dwDwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & dwDwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & dwDwordVal_p)[0];
-
+ ((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[2];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[0];
}
//---------------------------------------------------------------------------
@@ -355,14 +346,11 @@ INLINE_FUNCTION void PUBLIC AmiSetDword24ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p,
- DWORD dwDwordVal_p)
+void AmiSetDword24ToLe(void *pAddr_p, u32 dwDwordVal_p)
{
-
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & dwDwordVal_p)[0];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & dwDwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & dwDwordVal_p)[2];
-
+ ((u8 *) pAddr_p)[0] = ((u8 *) & dwDwordVal_p)[0];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & dwDwordVal_p)[1];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & dwDwordVal_p)[2];
}
//---------------------------------------------------------------------------
@@ -373,22 +361,19 @@ INLINE_FUNCTION void PUBLIC AmiSetDword24ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: DWORD = read value
+// Return: u32 = read value
//
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p)
+u32 AmiGetDword24FromBe(void *pAddr_p)
{
-
tdwStruct dwStruct;
dwStruct.m_dwDword = AmiGetDwordFromBe(pAddr_p);
dwStruct.m_dwDword >>= 8;
return (dwStruct.m_dwDword);
-
}
//---------------------------------------------------------------------------
@@ -399,22 +384,19 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: DWORD = read value
+// Return: u32 = read value
//
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p)
+u32 AmiGetDword24FromLe(void *pAddr_p)
{
-
tdwStruct dwStruct;
dwStruct.m_dwDword = AmiGetDwordFromLe(pAddr_p);
dwStruct.m_dwDword &= 0x00FFFFFF;
return (dwStruct.m_dwDword);
-
}
//#ifdef USE_VAR64
@@ -433,20 +415,16 @@ INLINE_FUNCTION DWORD PUBLIC AmiGetDword24FromLe(void FAR * pAddr_p)
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword64ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
-
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[7];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[6];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[5];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[7] = ((BYTE FAR *) & qwQwordVal_p)[0];
-
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[7];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[6];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[5];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[7] = ((u8 *) & qwQwordVal_p)[0];
}
//---------------------------------------------------------------------------
@@ -463,16 +441,12 @@ INLINE_FUNCTION void PUBLIC AmiSetQword64ToBe(void FAR * pAddr_p,
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword64ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
+ u64 *pqwDst;
- QWORD FAR *pqwDst;
-
- pqwDst = (QWORD FAR *) pAddr_p;
+ pqwDst = (u64 *) pAddr_p;
*pqwDst = qwQwordVal_p;
-
}
//---------------------------------------------------------------------------
@@ -488,23 +462,20 @@ INLINE_FUNCTION void PUBLIC AmiSetQword64ToLe(void FAR * pAddr_p,
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p)
+u64 AmiGetQword64FromBe(void *pAddr_p)
{
-
tqwStruct qwStruct;
- ((BYTE FAR *) & qwStruct.m_qwQword)[0] = ((BYTE FAR *) pAddr_p)[7];
- ((BYTE FAR *) & qwStruct.m_qwQword)[1] = ((BYTE FAR *) pAddr_p)[6];
- ((BYTE FAR *) & qwStruct.m_qwQword)[2] = ((BYTE FAR *) pAddr_p)[5];
- ((BYTE FAR *) & qwStruct.m_qwQword)[3] = ((BYTE FAR *) pAddr_p)[4];
- ((BYTE FAR *) & qwStruct.m_qwQword)[4] = ((BYTE FAR *) pAddr_p)[3];
- ((BYTE FAR *) & qwStruct.m_qwQword)[5] = ((BYTE FAR *) pAddr_p)[2];
- ((BYTE FAR *) & qwStruct.m_qwQword)[6] = ((BYTE FAR *) pAddr_p)[1];
- ((BYTE FAR *) & qwStruct.m_qwQword)[7] = ((BYTE FAR *) pAddr_p)[0];
+ ((u8 *) & qwStruct.m_qwQword)[0] = ((u8 *) pAddr_p)[7];
+ ((u8 *) & qwStruct.m_qwQword)[1] = ((u8 *) pAddr_p)[6];
+ ((u8 *) & qwStruct.m_qwQword)[2] = ((u8 *) pAddr_p)[5];
+ ((u8 *) & qwStruct.m_qwQword)[3] = ((u8 *) pAddr_p)[4];
+ ((u8 *) & qwStruct.m_qwQword)[4] = ((u8 *) pAddr_p)[3];
+ ((u8 *) & qwStruct.m_qwQword)[5] = ((u8 *) pAddr_p)[2];
+ ((u8 *) & qwStruct.m_qwQword)[6] = ((u8 *) pAddr_p)[1];
+ ((u8 *) & qwStruct.m_qwQword)[7] = ((u8 *) pAddr_p)[0];
return (qwStruct.m_qwQword);
-
}
//---------------------------------------------------------------------------
@@ -520,18 +491,15 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromBe(void FAR * pAddr_p)
// State: not tested
//
//---------------------------------------------------------------------------
-
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p)
+u64 AmiGetQword64FromLe(void *pAddr_p)
{
-
- tqwStruct FAR *pqwStruct;
+ tqwStruct *pqwStruct;
tqwStruct qwStruct;
- pqwStruct = (tqwStruct FAR *) pAddr_p;
+ pqwStruct = (tqwStruct *) pAddr_p;
qwStruct.m_qwQword = pqwStruct->m_qwQword;
return (qwStruct.m_qwQword);
-
}
//---------------------------------------------------------------------------
@@ -549,15 +517,14 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword64FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword40ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[0];
}
@@ -576,12 +543,11 @@ INLINE_FUNCTION void PUBLIC AmiSetQword40ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword40ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[4];
+ ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[4];
}
@@ -593,13 +559,13 @@ INLINE_FUNCTION void PUBLIC AmiSetQword40ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p)
+u64 AmiGetQword40FromBe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -619,13 +585,13 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p)
+u64 AmiGetQword40FromLe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -652,16 +618,15 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword40FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword48ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[5];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[5];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[0];
}
@@ -680,12 +645,11 @@ INLINE_FUNCTION void PUBLIC AmiSetQword48ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword48ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
- ((WORD FAR *) pAddr_p)[2] = ((WORD FAR *) & qwQwordVal_p)[2];
+ ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+ ((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
}
@@ -697,13 +661,13 @@ INLINE_FUNCTION void PUBLIC AmiSetQword48ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p)
+u64 AmiGetQword48FromBe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -723,13 +687,13 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p)
+u64 AmiGetQword48FromLe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -756,17 +720,16 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword48FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword56ToBe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((BYTE FAR *) pAddr_p)[0] = ((BYTE FAR *) & qwQwordVal_p)[6];
- ((BYTE FAR *) pAddr_p)[1] = ((BYTE FAR *) & qwQwordVal_p)[5];
- ((BYTE FAR *) pAddr_p)[2] = ((BYTE FAR *) & qwQwordVal_p)[4];
- ((BYTE FAR *) pAddr_p)[3] = ((BYTE FAR *) & qwQwordVal_p)[3];
- ((BYTE FAR *) pAddr_p)[4] = ((BYTE FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[5] = ((BYTE FAR *) & qwQwordVal_p)[1];
- ((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[0];
+ ((u8 *) pAddr_p)[0] = ((u8 *) & qwQwordVal_p)[6];
+ ((u8 *) pAddr_p)[1] = ((u8 *) & qwQwordVal_p)[5];
+ ((u8 *) pAddr_p)[2] = ((u8 *) & qwQwordVal_p)[4];
+ ((u8 *) pAddr_p)[3] = ((u8 *) & qwQwordVal_p)[3];
+ ((u8 *) pAddr_p)[4] = ((u8 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[5] = ((u8 *) & qwQwordVal_p)[1];
+ ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[0];
}
@@ -785,13 +748,12 @@ INLINE_FUNCTION void PUBLIC AmiSetQword56ToBe(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p,
- QWORD qwQwordVal_p)
+void AmiSetQword56ToLe(void *pAddr_p, u64 qwQwordVal_p)
{
- ((DWORD FAR *) pAddr_p)[0] = ((DWORD FAR *) & qwQwordVal_p)[0];
- ((WORD FAR *) pAddr_p)[2] = ((WORD FAR *) & qwQwordVal_p)[2];
- ((BYTE FAR *) pAddr_p)[6] = ((BYTE FAR *) & qwQwordVal_p)[6];
+ ((u32 *) pAddr_p)[0] = ((u32 *) & qwQwordVal_p)[0];
+ ((u16 *) pAddr_p)[2] = ((u16 *) & qwQwordVal_p)[2];
+ ((u8 *) pAddr_p)[6] = ((u8 *) & qwQwordVal_p)[6];
}
@@ -803,13 +765,13 @@ INLINE_FUNCTION void PUBLIC AmiSetQword56ToLe(void FAR * pAddr_p,
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p)
+u64 AmiGetQword56FromBe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -829,13 +791,13 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromBe(void FAR * pAddr_p)
//
// Parameters: pAddr_p = pointer to source buffer
//
-// Return: QWORD
+// Return: u64
//
// State: not tested
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p)
+u64 AmiGetQword56FromLe(void *pAddr_p)
{
tqwStruct qwStruct;
@@ -862,13 +824,11 @@ INLINE_FUNCTION QWORD PUBLIC AmiGetQword56FromLe(void FAR * pAddr_p)
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p)
+void AmiSetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
{
- AmiSetDwordToLe(((BYTE FAR *) pAddr_p),
- pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
- AmiSetWordToLe(((BYTE FAR *) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
+ AmiSetDwordToLe(((u8 *) pAddr_p), pTimeOfDay_p->m_dwMs & 0x0FFFFFFF);
+ AmiSetWordToLe(((u8 *) pAddr_p) + 4, pTimeOfDay_p->m_wDays);
}
@@ -887,18 +847,14 @@ INLINE_FUNCTION void PUBLIC AmiSetTimeOfDay(void FAR * pAddr_p,
//
//---------------------------------------------------------------------------
-INLINE_FUNCTION void PUBLIC AmiGetTimeOfDay(void FAR * pAddr_p,
- tTimeOfDay FAR * pTimeOfDay_p)
+void AmiGetTimeOfDay(void *pAddr_p, tTimeOfDay *pTimeOfDay_p)
{
- pTimeOfDay_p->m_dwMs =
- AmiGetDwordFromLe(((BYTE FAR *) pAddr_p)) & 0x0FFFFFFF;
- pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((BYTE FAR *) pAddr_p) + 4);
+ pTimeOfDay_p->m_dwMs = AmiGetDwordFromLe(((u8 *) pAddr_p)) & 0x0FFFFFFF;
+ pTimeOfDay_p->m_wDays = AmiGetWordFromLe(((u8 *) pAddr_p) + 4);
}
-#endif
-
// EOF
// Die letzte Zeile muß unbedingt eine leere Zeile sein, weil manche Compiler
diff --git a/drivers/staging/epl/demo_main.c b/drivers/staging/epl/demo_main.c
index 263fa042291..7ad10fc2b1d 100644
--- a/drivers/staging/epl/demo_main.c
+++ b/drivers/staging/epl/demo_main.c
@@ -74,7 +74,6 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -87,16 +86,6 @@
#include "Epl.h"
#include "proc_fs.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- // remove ("make invisible") obsolete symbols for kernel versions 2.6
- // and higher
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#define EXPORT_NO_SYMBOLS
-#else
-#error "This driver needs a 2.6.x kernel or higher"
-#endif
-
/***************************************************************************/
/* */
/* */
@@ -118,7 +107,7 @@ MODULE_DESCRIPTION("EPL MN demo");
// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
#else
#define TGT_DBG_SIGNAL_TRACE_POINT(p)
@@ -148,30 +137,30 @@ void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
// modul globale vars
//---------------------------------------------------------------------------
-CONST BYTE abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+static const u8 abMacAddr[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
-BYTE bVarIn1_l;
-BYTE bVarOut1_l;
-BYTE bVarOut1Old_l;
-BYTE bModeSelect_l; // state of the pushbuttons to select the mode
-BYTE bSpeedSelect_l; // state of the pushbuttons to increase/decrease the speed
-BYTE bSpeedSelectOld_l; // old state of the pushbuttons
-DWORD dwLeds_l; // current state of all LEDs
-BYTE bLedsRow1_l; // current state of the LEDs in row 1
-BYTE bLedsRow2_l; // current state of the LEDs in row 2
-BYTE abSelect_l[3]; // pushbuttons from CNs
+static u8 bVarIn1_l;
+static u8 bVarOut1_l;
+static u8 bVarOut1Old_l;
+static u8 bModeSelect_l; // state of the pushbuttons to select the mode
+static u8 bSpeedSelect_l; // state of the pushbuttons to increase/decrease the speed
+static u8 bSpeedSelectOld_l; // old state of the pushbuttons
+static u32 dwLeds_l; // current state of all LEDs
+static u8 bLedsRow1_l; // current state of the LEDs in row 1
+static u8 bLedsRow2_l; // current state of the LEDs in row 2
+static u8 abSelect_l[3]; // pushbuttons from CNs
-DWORD dwMode_l; // current mode
-int iCurCycleCount_l; // current cycle count
-int iMaxCycleCount_l; // maximum cycle count (i.e. number of cycles until next light movement step)
-int iToggle; // indicates the light movement direction
+static u32 dwMode_l; // current mode
+static int iCurCycleCount_l; // current cycle count
+static int iMaxCycleCount_l; // maximum cycle count (i.e. number of cycles until next light movement step)
+static int iToggle; // indicates the light movement direction
-BYTE abDomain_l[3000];
+//static u8 abDomain_l[3000];
static wait_queue_head_t WaitQueueShutdown_g; // wait queue for tEplNmtEventSwitchOff
static atomic_t AtomicShutdown_g = ATOMIC_INIT(FALSE);
-static DWORD dw_le_CycleLen_g;
+static u32 dw_le_CycleLen_g;
static uint uiNodeId_g = EPL_C_ADR_INVALID;
module_param_named(nodeid, uiNodeId_g, uint, 0);
@@ -188,23 +177,19 @@ module_param_named(cyclelen, uiCycleLen_g, uint, 0);
// this function prototype here. If you want to use more than one Epl
// instances then the function name of each object dictionary has to differ.
-tEplKernel PUBLIC EplObdInitRam(tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
-tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p);
+tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p);
-tEplKernel PUBLIC AppCbSync(void);
+tEplKernel AppCbSync(void);
-static int __init EplLinInit(void);
-static void __exit EplLinExit(void);
//---------------------------------------------------------------------------
// Kernel Module specific Data Structures
//---------------------------------------------------------------------------
-EXPORT_NO_SYMBOLS;
-
//module_init(EplLinInit);
//module_exit(EplLinExit);
@@ -231,6 +216,7 @@ EXPORT_NO_SYMBOLS;
// State:
//
//---------------------------------------------------------------------------
+#if 0
static int __init EplLinInit(void)
{
tEplKernel EplRet;
@@ -263,7 +249,7 @@ static int __init EplLinInit(void)
EplApiInitParam.m_uiSizeOfStruct = sizeof(EplApiInitParam);
EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr,
sizeof(EplApiInitParam.m_abMacAddress));
-// EplApiInitParam.m_abMacAddress[5] = (BYTE) EplApiInitParam.m_uiNodeId;
+// EplApiInitParam.m_abMacAddress[5] = (u8) EplApiInitParam.m_uiNodeId;
EplApiInitParam.m_dwFeatureFlags = -1;
EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection
EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const
@@ -401,7 +387,7 @@ static int __init EplLinInit(void)
// configure IP address of virtual network interface
// for TCP/IP communication over the POWERLINK network
- sprintf(sBuffer, "%lu.%lu.%lu.%lu",
+ sprintf(sBuffer, "%u.%u.%u.%u",
(EplApiInitParam.m_dwIpAddress >> 24),
((EplApiInitParam.m_dwIpAddress >> 16) & 0xFF),
((EplApiInitParam.m_dwIpAddress >> 8) & 0xFF),
@@ -456,7 +442,7 @@ static void __exit EplLinExit(void)
printk("EplLinProcFree(): 0x%X\n", EplRet);
}
-
+#endif
//=========================================================================//
// //
// P R I V A T E F U N C T I O N S //
@@ -484,9 +470,9 @@ static void __exit EplLinExit(void)
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
- tEplApiEventArg * pEventArg_p, // IN: event argument (union)
- void GENERIC * pUserArg_p)
+tEplKernel AppCbEvent(tEplApiEventType EventType_p, // IN: event type (enum)
+ tEplApiEventArg *pEventArg_p, // IN: event argument (union)
+ void *pUserArg_p)
{
tEplKernel EplRet = kEplSuccessful;
@@ -515,7 +501,7 @@ tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (en
case kEplNmtGsResetCommunication:
{
- DWORD dwBuffer;
+ u32 dwBuffer;
// configure OD for MN in state ResetComm after reseting the OD
// TODO: setup your own network configuration here
@@ -677,8 +663,8 @@ tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (en
case kEplEventSourceDllk:
{ // error occured within the data link layer (e.g. interrupt processing)
- // the DWORD argument contains the DLL state and the NMT event
- printk(" val=%lX\n",
+ // the u32 argument contains the DLL state and the NMT event
+ printk(" val=%X\n",
pEventArg_p->m_InternalError.
m_Arg.m_dwArg);
break;
@@ -802,7 +788,7 @@ tEplKernel PUBLIC AppCbEvent(tEplApiEventType EventType_p, // IN: event type (en
//
//---------------------------------------------------------------------------
-tEplKernel PUBLIC AppCbSync(void)
+tEplKernel AppCbSync(void)
{
tEplKernel EplRet = kEplSuccessful;
@@ -810,7 +796,7 @@ tEplKernel PUBLIC AppCbSync(void)
bVarOut1Old_l = bVarOut1_l;
// set LEDs
-// printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (WORD) bVarIn_l, (WORD) bVarOut_l);
+// printk("bVarIn = 0x%02X bVarOut = 0x%02X\n", (u16) bVarIn_l, (u16) bVarOut_l);
}
if (uiNodeId_g != EPL_C_ADR_MN_DEF_NODE_ID) {
bVarIn1_l++;
diff --git a/drivers/staging/epl/edrv.h b/drivers/staging/epl/edrv.h
index a45984dfb09..62b4e77e069 100644
--- a/drivers/staging/epl/edrv.h
+++ b/drivers/staging/epl/edrv.h
@@ -104,7 +104,7 @@ typedef struct _tEdrvTxBuffer {
unsigned int m_uiTxMsgLen; // IN: length of message to be send (set for each transmit call)
// ----------------------
unsigned int m_uiBufferNumber; // OUT: number of the buffer, set by ethernetdriver
- BYTE *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
+ u8 *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
tEplNetTime m_NetTime; // OUT: Timestamp of end of transmission, set by ethernetdriver
// ----------------------
unsigned int m_uiMaxBufferLen; // IN/OUT: maximum length of the buffer
@@ -114,23 +114,23 @@ typedef struct _tEdrvTxBuffer {
typedef struct _tEdrvRxBuffer {
tEdrvBufferInFrame m_BufferInFrame; // OUT position of received buffer in an ethernet-frame
unsigned int m_uiRxMsgLen; // OUT: length of received buffer (without CRC)
- BYTE *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
+ u8 *m_pbBuffer; // OUT: pointer to the buffer, set by ethernetdriver
tEplNetTime m_NetTime; // OUT: Timestamp of end of receiption
} tEdrvRxBuffer;
-//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, tBufferDescr * pbBuffer_p);
-//typedef void (*tEdrvRxHandler) (BYTE bBufferInFrame_p, BYTE * pbEthernetData_p, WORD wDataLen_p);
+//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, tBufferDescr * pbBuffer_p);
+//typedef void (*tEdrvRxHandler) (u8 bBufferInFrame_p, u8 * pbEthernetData_p, u16 wDataLen_p);
typedef void (*tEdrvRxHandler) (tEdrvRxBuffer * pRxBuffer_p);
typedef void (*tEdrvTxHandler) (tEdrvTxBuffer * pTxBuffer_p);
// format of init structure
typedef struct {
- BYTE m_abMyMacAddr[6]; // the own MAC address
+ u8 m_abMyMacAddr[6]; // the own MAC address
-// BYTE m_bNoOfRxBuffDescr; // number of entries in rx bufferdescriptor table
+// u8 m_bNoOfRxBuffDescr; // number of entries in rx bufferdescriptor table
// tBufferDescr * m_pRxBuffDescrTable; // rx bufferdescriptor table
-// WORD m_wRxBufferSize; // size of the whole rx buffer
+// u16 m_wRxBufferSize; // size of the whole rx buffer
tEdrvRxHandler m_pfnRxHandler;
tEdrvTxHandler m_pfnTxHandler;
@@ -145,11 +145,11 @@ tEplKernel EdrvInit(tEdrvInitParam * pEdrvInitParam_p);
tEplKernel EdrvShutdown(void);
-tEplKernel EdrvDefineRxMacAddrEntry(BYTE * pbMacAddr_p);
-tEplKernel EdrvUndefineRxMacAddrEntry(BYTE * pbMacAddr_p);
+tEplKernel EdrvDefineRxMacAddrEntry(u8 * pbMacAddr_p);
+tEplKernel EdrvUndefineRxMacAddrEntry(u8 * pbMacAddr_p);
-//tEplKernel EdrvDefineUnicastEntry (BYTE * pbUCEntry_p);
-//tEplKernel EdrvUndfineUnicastEntry (BYTE * pbUCEntry_p);
+//tEplKernel EdrvDefineUnicastEntry (u8 * pbUCEntry_p);
+//tEplKernel EdrvUndfineUnicastEntry (u8 * pbUCEntry_p);
tEplKernel EdrvAllocTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
tEplKernel EdrvReleaseTxMsgBuffer(tEdrvTxBuffer * pBuffer_p);
diff --git a/drivers/staging/epl/global.h b/drivers/staging/epl/global.h
index fe167165a83..8c52d97ec9c 100644
--- a/drivers/staging/epl/global.h
+++ b/drivers/staging/epl/global.h
@@ -22,1261 +22,21 @@
#ifndef _GLOBAL_H_
#define _GLOBAL_H_
-//---------------------------------------------------------------------------
-// elements of defines for development system
-//---------------------------------------------------------------------------
-
-// these defines are necessary to check some of characteristics of the development system
-#define _DEV_BIGEND_ 0x80000000L // big endian (motorolla format)
-#define _DEV_ALIGNMENT_4_ 0x00400000L // the CPU needs alignment of 4 bytes
-#define _DEV_ONLY_INT_MAIN_ 0x00004000L // the compiler needs "int main(int)" instead of "void main(void)"
-#define _DEV_COMMA_EXT_ 0x00002000L // support of last comma in struct predefinition
-#define _DEV_64BIT_SUPPORT_ 0x00001000L // support of 64 bit operations
-#define _DEV_BIT64_ 0x00000400L // count of bits: 64 bit
-#define _DEV_BIT32_ 0x00000300L // 32 bit
-#define _DEV_BIT16_ 0x00000200L // 16 bit
-#define _DEV_BIT8_ 0x00000100L // 8 bit
-#define _DEV_RVCT_ARM_ 0x0000001CL // RealView ARM
-#define _DEV_RENESASM32C 0x0000001BL // compiler from: Renesas
-#define _DEV_GNUC_MIPS2_ 0x0000001AL // GNU for MIPS2
-#define _DEV_MPLAB_C30_ 0x00000019L // MPLAB C30 for Microchip dsPIC33F series
-#define _DEV_GNUC_TC_ 0x00000018L // GNU for Infineon TriCore
-#define _DEV_GNUC_X86_ 0x00000017L // GNU for I386
-#define _DEV_IAR_ARM_ 0x00000016L // ARM IAR C/C++ Compiler
-#define _DEV_PARADGM_X86 0x00000015L // Paradigm C/C++ for Beck 1x3
-#define _DEV_GNUC_CF_ 0x00000014L // GNU for Coldfire
-#define _DEV_KEIL_ARM_ 0x00000013L // Keil ARM
-#define _DEV_MSEVC_ 0x00000012L // Microsoft embedded Visual C/C++
-#define _DEV_HIGHTEC_GNUC_X86_ 0x00000011L // Hightec elf386 gcc
-#define _DEV_MSVC_RTX_ 0x00000010L // VC600 + RTX
-#define _DEV_MSVC_V1_5_ 0x0000000FL // Microsoft Visual C/C++ V1.5
-#define _DEV_GNUC_ARM7_ 0x0000000EL // GNU Compiler gcc for ARM7
-#define _DEV_METROWERKS_CW_ 0x0000000DL // Metrowerks Code Warrior
-#define _DEV_MITSUBISHIM16C_ 0x0000000CL //compiler from: Mitsubishi
-#define _DEV_GNUC_C16X_ 0x0000000BL // GNU Compiler gcc166 for Infineon C16x
-#define _DEV_LINUX_GCC_ 0x0000000AL // Linux GNU Compiler gcc
-#define _DEV_GNUC_MPC5X5 0x00000009L // GNU for Motorola PPC5x5
-#define _DEV_TASKINGM16C_ 0x00000008L // Tasking for Mitsubishi M16C
-#define _DEV_FUJITSU_ 0x00000007L // Fujitsu
-#define _DEV_TASKING8_ 0x00000006L // Tasking 8051
-#define _DEV_TASKING16_ 0x00000005L // Tasking 166
-#define _DEV_KEIL8_ 0x00000004L // Keil C51
-#define _DEV_KEIL16_ 0x00000003L // Keil C166
-#define _DEV_BORLANDC_ 0x00000002L // Borland C/C++
-#define _DEV_MSVC16_ 0x00000001L // Microsoft Visual C/C++
-#define _DEV_MSVC32_ 0x00000000L // Microsoft Visual C/C++
-
-// these defines can be used to mask previous elements
-#define _DEV_MASK_COMPILER 0x000000FFL
-#define _DEV_MASK_BITCOUNT 0x00000F00L
-#define _DEV_MASK_ADDSUPPORT 0x0000F000L
-#define _DEV_MASK_ALIGNMENT 0x00F00000L
-
-//---------------------------------------------------------------------------
-// defines for development system (DEV_SYSTEM) including previous elements
-//---------------------------------------------------------------------------
-
-#define _DEV_WIN16_ (_DEV_BIT16_ | _DEV_MSVC16_ )
-#define _DEV_WIN32_ (_DEV_BIT32_ | _DEV_MSVC32_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_MSVC_DOS_ (_DEV_BIT32_ | _DEV_MSVC_V1_5_ )
-#define _DEV_BORLAND_DOS_ (_DEV_BIT32_ | _DEV_BORLANDC_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_KEIL_C51X_ (_DEV_BIT8_ | _DEV_KEIL8_ | _DEV_BIGEND_ | _DEV_COMMA_EXT_) // at least C51 version 7.05 supports comma extension
-#define _DEV_KEIL_C16X_ (_DEV_BIT16_ | _DEV_KEIL16_ | _DEV_COMMA_EXT_) // at least C166 version 5.03 supports comma extension
-#define _DEV_TASKING_C51X_ (_DEV_BIT8_ | _DEV_TASKING8_ | _DEV_BIGEND_)
-#define _DEV_TASKING_C16X_ (_DEV_BIT16_ | _DEV_TASKING16_ )
-#define _DEV_FUJITSU_F590_ (_DEV_BIT8_ | _DEV_FUJITSU_ | _DEV_COMMA_EXT_) // softune is not able to support 64 bit variables QWORD !!!
-//f.j.29.04.03 M16C kann effektiv mit Bytes umgehen
-//#define _DEV_TASKING_M16C_ (_DEV_BIT16_ | _DEV_TASKINGM16C_ )
-#define _DEV_TASKING_M16C_ (_DEV_BIT8_ | _DEV_TASKINGM16C_ )
-#define _DEV_MITSUBISHI_M16C_ (_DEV_BIT8_ | _DEV_MITSUBISHIM16C_ )
-#define _DEV_GNU_MPC5X5_ (_DEV_BIT32_ | _DEV_GNUC_MPC5X5| _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_LINUX_ (_DEV_BIT32_ | _DEV_LINUX_GCC_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_C16X_ (_DEV_BIT16_ | _DEV_GNUC_C16X_ ) //| _DEV_COMMA_EXT_)
-#define _DEV_MCW_MPC5X5_ (_DEV_BIT32_ | _DEV_METROWERKS_CW_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_ARM7_ (_DEV_BIT32_ | _DEV_GNUC_ARM7_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_WIN32_RTX_ (_DEV_BIT32_ | _DEV_MSVC_RTX_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_HIGHTEC_X86_ (_DEV_BIT32_ | _DEV_HIGHTEC_GNUC_X86_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_WIN_CE_ (_DEV_BIT32_ | _DEV_MSEVC_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_KEIL_CARM_ (_DEV_BIT32_ | _DEV_KEIL_ARM_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_IAR_CARM_ (_DEV_BIT32_ | _DEV_IAR_ARM_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_RVCT_CARM_ (_DEV_BIT32_ | _DEV_RVCT_ARM_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_MCW_MCF5XXX_ (_DEV_BIT32_ | _DEV_METROWERKS_CW_ ) //| _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_CF5282_ (_DEV_BIT32_ | _DEV_GNUC_CF_ | _DEV_BIGEND_)
-#define _DEV_PAR_BECK1X3_ (_DEV_BIT16_ | _DEV_PARADGM_X86)
-#define _DEV_GNU_CF548X_ (_DEV_BIT32_ | _DEV_GNUC_CF_ | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_)
-#define _DEV_GNU_I386_ (_DEV_BIT32_ | _DEV_GNUC_X86_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-#define _DEV_GNU_TRICORE_ (_DEV_BIT32_ | _DEV_GNUC_TC_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_ | _DEV_ALIGNMENT_4_)
-#define _DEV_MPLAB_DSPIC33F_ (_DEV_BIT16_ | _DEV_MPLAB_C30_ ) //| _DEV_COMMA_EXT_)
-#define _DEV_GNU_MIPSEL_ (_DEV_BIT32_ | _DEV_GNUC_MIPS2_ | _DEV_BIGEND_ | _DEV_64BIT_SUPPORT_ | _DEV_COMMA_EXT_ | _DEV_ONLY_INT_MAIN_)
-
-#define _DEV_RENESAS_M32C_ (_DEV_BIT32_ | _DEV_RENESASM32C)
-
-//---------------------------------------------------------------------------
-// usefull macros
-//---------------------------------------------------------------------------
-
-#define CHECK_IF_ONLY_INT_MAIN() (DEV_SYSTEM & _DEV_ONLY_INT_MAIN_)
-#define CHECK_MEMORY_ALINMENT() (DEV_SYSTEM & _DEV_MASK_ALIGNMENT)
-
-//---------------------------------------------------------------------------
-// defines for target system (TARGET_SYSTEM)
-//---------------------------------------------------------------------------
-
-#define _DOS_ (16 + 0x10000)
-#define _WIN16_ 16
-#define _WIN32_ 32
-#define _WINCE_ (32 + 0x20000)
-#define _NO_OS_ 0
-#define _LINUX_ 1
-#define _PXROS_ 2
-#define _ECOSPRO_ 3
-
-//---------------------------------------------------------------------------
-// definitions for function inlining
-//---------------------------------------------------------------------------
-
-#define INLINE_FUNCTION // empty define
-#undef INLINE_ENABLED // disable actual inlining of functions
-#undef INLINE_FUNCTION_DEF // disable inlining for all compilers per default
-
-//---------------------------------------------------------------------------
-// definitions for Keil C51
-//---------------------------------------------------------------------------
-
-#ifdef __C51__
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_KEIL_C51X_
-
-#pragma DEBUG OBJECTEXTEND
-#pragma WARNINGLEVEL(2) // maximum warning level
-
-#define NEAR idata // variables mapped to internal data storage location
-#define FAR xdata // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM code // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC xdata // hardware access through external memory (i.e. CAN)
-#define LARGE large // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM xdata // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT reentrant
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for GNU Compiler for Infineon C16x
-// - it have to be befor Keil (it has __C166__ too)
-//---------------------------------------------------------------------------
-#elif defined (__GNUC__) && defined (__C166__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_C16X_
-
-// #define NEAR idata // variables mapped to internal data storage location
-#define NEAR near // variables mapped to internal data storage location
-// #define FAR xhuge // variables mapped to external data storage location
-#define FAR huge // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-// #define HWACC sdata // hardware access through external memory (i.e. CAN)
-#define HWACC huge // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-// #define GENERIC xhuge // generic pointer to point to application data
-#define GENERIC huge // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-
-#define ASSERT(p) \
- if (p) \
- { \
- ; \
- } \
- else \
- { \
- PRINTF0("Assert failed: " #p " (file %s line %d)\n", __FILE__, (int) __LINE__ ); \
- while (1); \
- }
-#else
-#define ASSERT(p)
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Keil C166
-//---------------------------------------------------------------------------
-#elif defined (__C166__) // 24.01.2005 r.d.: Keil ARM7 needs directive 'defined'
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_KEIL_C16X_
-
-#pragma CODE
-#pragma MOD167
-#pragma NOINIT
-#pragma DEBUG
-#pragma WARNINGLEVEL(3) // maximum warning level
-#pragma WARNING DISABLE = 47 // warning <unreferenced parameter> = OFF
-#pragma WARNING DISABLE = 38 // warning <empty translation unit> = OFF
-// #pragma WARNING DISABLE = 102 // warning <different const/volatile qualifiers> = OFF
-#pragma WARNING DISABLE = 174 // warning <unreferenced 'static' function> = OFF
-#pragma WARNING DISABLE = 183 // warning <dead assignement eliminated> = OFF
-
-#define NEAR idata // variables mapped to internal data storage location
-#define FAR xhuge // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-// #define HWACC sdata // hardware access through external memory (i.e. CAN)
-#define HWACC huge // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC xhuge // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for MPLAB C30 for dsPIC33F series
-//---------------------------------------------------------------------------
-#elif defined (__C30__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_MPLAB_DSPIC33F_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-// #ifndef QWORD
-// #define QWORD long long
-// #endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Keil ARM
-//---------------------------------------------------------------------------
-#elif defined (__CA__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_KEIL_CARM_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for RealView ARM compilation tools (provided by recent Keil Microcontroller Development Kits)
-//---------------------------------------------------------------------------
-#elif defined (__ARMCC_VERSION)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_RVCT_CARM_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
-#ifndef NDEBUG
-#define ASSERT(expr) if (!(expr)) {\
- TRACE0 ("Assertion failed: " #expr );\
- while (1);}
-#else
-#define ASSERT(expr)
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for ARM IAR C Compiler
-//---------------------------------------------------------------------------
-#elif defined (__ICCARM__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_IAR_CARM_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long
-#endif
-
- // Workaround:
- // If we use IAR and want to debug but don't want to use C-Spy Debugger
- // assert() doesn't work in debug mode because it needs support for FILE descriptors
- // (_DLIB_FILE_DESCRIPTOR == 1).
-#ifndef NDEBUG
-#define ASSERT(expr) if (!(expr)) {\
- TRACE0 ("Assertion failed: " #expr );\
- while (1);}
-#else
-#define ASSERT(expr)
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-// #define TRACE PRINTF4
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Tasking 8051
-//---------------------------------------------------------------------------
-
-#elif defined (_CC51)
-
-#include <cc51.h>
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_TASKING_C51X_
-
-#define NEAR _data // variables mapped to internal data storage location
-#define FAR _xdat // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC _xdat // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM _xdat // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT _reentrant
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Tasking C167CR and C164CI
-//---------------------------------------------------------------------------
-
-#elif defined (_C166)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_TASKING_C16X_
-
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC /* to be defined */ // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
- // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
- // without checking if it is already included. So an error occurs while compiling.
- // (r.d.)
-#include <stdio.h> // prototype printf() (for TRACE)
-#ifndef NDEBUG
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for FUJITSU FFMC-16LX MB90590
-//---------------------------------------------------------------------------
-
-//#elif (defined (F590) || defined (F543) || defined (F598) || defined (F495) || defined (F350))
-#elif defined(__COMPILER_FCC907__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_FUJITSU_F590_
-
-#define NEAR /* to be defined */ // variables mapped to internal data storage location
-#define FAR /* to be defined */ // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM /* to be defined */ // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC /* to be defined */ // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
- // softune is not able to support 64 bit variables QWORD !!!
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Mitsubishi M16C family for TASKING Compiler CM16
-//---------------------------------------------------------------------------
-
-#elif defined (_CM16C)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_TASKING_M16C_
-
-#define NEAR _near // variables mapped to internal data storage location
-#define FAR _far // variables mapped to external data storage location
-#define CONST _farrom // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC _near // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC _far // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
- // do you use memory model SMALL, than you have to set _far
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
- // Stdio.h has to be alway included here. If printf() is used stdio.h defines NULL
- // without checking if it is already included. So an error occurs while compiling.
- // (r.d.)
-#include <stdio.h> // prototype printf() (for TRACE)
-#ifndef NDEBUG
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Mitsubishi M16C family for Mitsubishi Compiler NC30
-//---------------------------------------------------------------------------
-// name NC30, andere Form will der Compiler nicht !!
-#elif defined (NC30)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_MITSUBISHI_M16C_
-
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC near // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC far // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Renesas M32C family for Renesas Compiler
-//---------------------------------------------------------------------------
-#elif defined (NC308)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_RENESAS_M32C_
-
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM far // Memory attribute to optimize speed and code of pointer access.
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-// #error ("RENESAS o.k.")
-
-//---------------------------------------------------------------------------
-// definitions for ARM7 family with GNU compiler
-//---------------------------------------------------------------------------
-
-#elif defined(__GNUC__) && defined(__arm__) && !defined(__LINUX_ARM_ARCH__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_ARM7_
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define HWACC // hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long // i.A. durch Herr Kuschel
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for Motorola PowerPC family 5x5 (555/565)
-// definitions Linux-PC
-//---------------------------------------------------------------------------
-
-#elif defined (__GNUC__)
-
-#if defined (LINUX) || defined (linux) || defined (__linux__)
-#define LINUX_SYSTEM // define 'LINUX_SYSTEM' uniform for all Linux based systems
- // r.d.: We will need an other solution here! There are two sections here which do check the preproc-definitions:
- // LINUX and __linux__ . The first one was Linux for PC, the second one is this section for embedded Linux (MCF5xxx).
- // But Linux for PC does not need the definitions for embedded Linux.
-#endif
-
- // GNU C compiler supports function inlining
-#define INLINE_FUNCTION_DEF extern inline
-
- // to actually enable inlining just include the following three lines
- // #undef INLINE_FUNCTION
- // #define INLINE_FUNCTION INLINE_FUNCTION_DEF
- // #define INLINE_ENABLED TRUE
-
-#ifdef PXROS
-#define TARGET_SYSTEM _PXROS_
-#ifdef __i386__
-#undef LINUX // this define seems to be set from compiler
-#define DEV_SYSTEM _DEV_HIGHTEC_X86_
-#elif defined (__tricore__)
-#define DEV_SYSTEM _DEV_GNU_TRICORE_
-#else // MPC5x5
-#define DEV_SYSTEM _DEV_GNU_MPC5X5_
-#endif
-
-#elif defined (LINUX) || defined (__linux__)
-#define TARGET_SYSTEM _LINUX_ // Linux definition
-#define DEV_SYSTEM _DEV_LINUX_
-
-#elif defined (GNU_CF5282)
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_CF5282_
-
-#elif defined (ECOSPRO_I386_PEAK_PCI)
-#define TARGET_SYSTEM _ECOSPRO_
-#define DEV_SYSTEM _DEV_GNU_I386_
-
-#elif defined (GNU_CF548X)
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_GNU_CF548X_
-#else
-#error 'ERROR: DEV_SYSTEM not found!'
-#endif
-
-#ifndef QWORD
-#define QWORD long long int
-#endif
-
-#if (TARGET_SYSTEM == _PXROS_)
-
-#ifndef __KERNEL__
-#include <string.h>
-#endif
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM /* to be defined */ // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define HWACC // hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef QWORD
-#define QWORD long long int
-#endif
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-#endif
-
- // ------------------ GNUC for I386 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _LINUX_) || (TARGET_SYSTEM == _ECOSPRO_)
-
-#ifndef __KERNEL__
-#include <string.h>
-#endif
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef __KERNEL__
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#else
#define TRACE printk
-#endif
-#endif
-#endif
-
- // ------------------ GNU without OS ---------------------------------------------
-
-#if (TARGET_SYSTEM == _NO_OS_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-// #include "xuartdrv.h"
-// #include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-// #define TRACE mprintf
-// #ifndef TRACE
-// #define TRACE trace
-// void trace (char *fmt, ...);
-// #endif
-#endif
-
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for MPC565
-//---------------------------------------------------------------------------
-#elif __MWERKS__
-
-#ifdef __MC68K__
-
-#define TARGET_SYSTEM = _MCF548X_
-#define DEV_SYSTEM _DEV_MCW_MCF5XXX_
-
-#else
-#define TARGET_SYSTEM = _MPC565_
-#define DEV_SYSTEM _DEV_MCW_MPC5X5_
-#endif
-
-#define NEAR // variables mapped to internal data storage location
-#define FAR // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define LARGE // functions set parameters to external data storage location
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#define HWACC // hardware access through external memory (i.e. CAN)
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#include <stdio.h> // prototype printf() (for TRACE)
-#define TRACE printf
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for BECK 1x3
-//---------------------------------------------------------------------------
-#elif defined (__BORLANDC__) && defined (__PARADIGM__)
-
-#define TARGET_SYSTEM _NO_OS_
-#define DEV_SYSTEM _DEV_PAR_BECK1X3_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define NEAR __near // variables mapped to internal data storage location
-#define FAR __far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for PC
-//---------------------------------------------------------------------------
-
-#elif defined (__BORLANDC__)
-
- // ------------------ definition target system --------------------------
-
-#ifdef _WIN32
-#define TARGET_SYSTEM _WIN32_ // WIN32 definition
-#define DEV_SYSTEM _DEV_WIN32_
-#else
-#define TARGET_SYSTEM _DOS_
-#define DEV_SYSTEM _DEV_BORLAND_DOS_
-#endif
-
- // ------------------ WIN32 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _WIN32_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC __stdcall
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-#elif (TARGET_SYSTEM == _DOS_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-#endif
-
-#elif (_MSC_VER == 800) // PC MS Visual C/C++ for DOS applications
-
-#define TARGET_SYSTEM _DOS_
-#define DEV_SYSTEM _DEV_MSVC_DOS_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC near // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#define NEAR near // variables mapped to internal data storage location
-#define FAR far // variables mapped to external data storage location
-#define CONST const // variables mapped to ROM (i.e. flash)
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC
-
-#ifndef NDEBUG
-#ifndef TRACE
-#include <stdio.h>
-#define TRACE printf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for RTX under WIN32
-//---------------------------------------------------------------------------
-#elif (defined (UNDER_RTSS) && defined (WIN32))
-
- // ------------------ definition target system --------------------------
-#define TARGET_SYSTEM _WIN32_RTX_
-#define DEV_SYSTEM _DEV_WIN32_RTX_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC __stdcall
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE RtPrintf
-#endif
-#endif
-
-//---------------------------------------------------------------------------
-// definitions for WinCE
-//---------------------------------------------------------------------------
-#elif defined (_WIN32_WCE)
-
- // ------------------ definition target system --------------------------
-#define TARGET_SYSTEM _WINCE_
-#define DEV_SYSTEM _DEV_WIN_CE_
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#ifndef QWORD
- //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
-#define QWORD __int64
-#endif
-
-#define REENTRANT
-#define PUBLIC __cdecl
-
-#ifdef ASSERTMSG
-#undef ASSERTMSG
-#endif
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE printf
-// void trace (char *fmt, ...);
-#endif
-#endif
-
-#else // ===> PC MS Visual C/C++
-
- // ------------------ definition target system --------------------------
-
-#ifdef _WIN32
-#define TARGET_SYSTEM _WIN32_ // WIN32 definition
-#define DEV_SYSTEM _DEV_WIN32_
-#else
-#define TARGET_SYSTEM _WIN16_ // WIN16 definition
-#define DEV_SYSTEM _DEV_WIN16_
-#endif
-
- // ------------------ WIN16 ---------------------------------------------
-
-#if (TARGET_SYSTEM == _WIN16_)
-
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
-
- // These types can be adjusted by users to match application requirements. The goal is to
- // minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external
- // or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-
-#ifndef FAR
-#define FAR far // variables mapped to external data storage location
-#endif
-
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-
-#define LARGE
-
-#define REENTRANT
-#define PUBLIC _far _pascal _export
-
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE trace
-#ifdef __cplusplus
-extern "C" {
-#endif
- void trace(const char *fmt, ...);
-#ifdef __cplusplus
-}
-#endif
-#endif
-#endif
-#endif
- // ------------------ WIN32 ---------------------------------------------
-#if (TARGET_SYSTEM == _WIN32_)
-#define ROM // code or variables mapped to ROM (i.e. flash)
- // usage: CONST BYTE ROM foo = 0x00;
-#define HWACC // hardware access through external memory (i.e. CAN)
- // These types can be adjusted by users to match application requirements. The goal is to// minimize code memory and maximize speed.
-#define GENERIC // generic pointer to point to application data
- // Variables with this attribute can be located in external// or internal data memory.
-#define MEM // Memory attribute to optimize speed and code of pointer access.
-#ifndef NEAR
-#define NEAR // variables mapped to internal data storage location
-#endif
-#ifndef FAR
-#define FAR // variables mapped to external data storage location
-#endif
-#ifndef CONST
-#define CONST const // variables mapped to ROM (i.e. flash)
-#endif
-#define LARGE
-#define REENTRANT
-#define PUBLIC __stdcall
-#ifndef QWORD
- //#define QWORD long long int // MSVC .NET can use "long long int" too (like GNU)
-#define QWORD __int64
-#endif
-#ifndef NDEBUG
-#ifndef TRACE
-#define TRACE trace
-#ifdef __cplusplus
-extern "C" {
-#endif
- void trace(const char *fmt, ...);
-#ifdef __cplusplus
-}
-#endif
-#endif
-#endif
- // MS Visual C++ compiler supports function inlining
-#define INLINE_FUNCTION_DEF __forceinline
- // to actually enable inlining just include the following two lines// #define INLINE_FUNCTION INLINE_FUNCTION_DEF// #define INLINE_ENABLED TRUE
-#endif
-#endif // ===> PC
-//---------------------------------------------------------------------------// definitions of basic types//---------------------------------------------------------------------------
-#ifndef _WINDEF_ // defined in WINDEF.H, included by <windows.h>
- // --- arithmetic types ---
-#ifndef SHORT
-#define SHORT short int
-#endif
-#ifndef USHORT
-#define USHORT unsigned short int
-#endif
-#ifndef INT
-#define INT int
-#endif
-#ifndef UINT
-#define UINT unsigned int
-#endif
-#ifndef LONG
-#define LONG long int
-#endif
-#ifndef ULONG
-#define ULONG unsigned long int
-#endif
- // --- logic types ---
-#ifndef BYTE
-#define BYTE unsigned char
-#endif
-#ifndef WORD
-#define WORD unsigned short int
-#endif
-#ifndef DWORD
-#define DWORD unsigned long int
-#endif
+// --- logic types ---
#ifndef BOOL
#define BOOL unsigned char
#endif
- // --- alias types ---
+
+// --- alias types ---
#ifndef TRUE
#define TRUE 0xFF
#endif
#ifndef FALSE
#define FALSE 0x00
#endif
-#ifndef NULL
-#define NULL ((void *) 0)
-#endif
-#endif
#ifndef _TIME_OF_DAY_DEFINED_
typedef struct {
unsigned long int m_dwMs;
@@ -1359,15 +119,8 @@ typedef struct {
//---------------------------------------------------------------------------
#ifndef ASSERT
-#if !defined (__linux__) && !defined (__KERNEL__)
-#include <assert.h>
-#ifndef ASSERT
-#define ASSERT(p) assert(p)
-#endif
-#else
#define ASSERT(p)
#endif
-#endif
//---------------------------------------------------------------------------
// SYS TEC extensions
diff --git a/drivers/staging/epl/kernel/EplDllk.h b/drivers/staging/epl/kernel/EplDllk.h
index 588e871a922..a97920ab884 100644
--- a/drivers/staging/epl/kernel/EplDllk.h
+++ b/drivers/staging/epl/kernel/EplDllk.h
@@ -74,18 +74,10 @@
#include "../EplDll.h"
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
typedef tEplKernel(*tEplDllkCbAsync) (tEplFrameInfo * pFrameInfo_p);
typedef struct {
- BYTE m_be_abSrcMac[6];
+ u8 m_be_abSrcMac[6];
} tEplDllkInitParam;
@@ -96,22 +88,18 @@ struct _tEplDllkNodeInfo {
struct _tEplDllkNodeInfo *m_pNextNodeInfo;
struct _tEdrvTxBuffer *m_pPreqTxBuffer;
unsigned int m_uiNodeId;
- DWORD m_dwPresTimeout;
+ u32 m_dwPresTimeout;
unsigned long m_ulDllErrorEvents;
tEplNmtState m_NmtState;
- WORD m_wPresPayloadLimit;
- BYTE m_be_abMacAddr[6];
- BYTE m_bSoaFlag1;
+ u16 m_wPresPayloadLimit;
+ u8 m_be_abMacAddr[6];
+ u8 m_bSoaFlag1;
BOOL m_fSoftDelete; // delete node after error and ignore error
};
typedef struct _tEplDllkNodeInfo tEplDllkNodeInfo;
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
tEplKernel EplDllkAddInstance(tEplDllkInitParam * pInitParam_p);
@@ -154,7 +142,7 @@ tEplKernel EplDllkDeleteNode(unsigned int uiNodeId_p);
tEplKernel EplDllkSoftDeleteNode(unsigned int uiNodeId_p);
-tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+tEplKernel EplDllkSetFlag1OfNode(unsigned int uiNodeId_p, u8 bSoaFlag1_p);
tEplKernel EplDllkGetFirstNodeInfo(tEplDllkNodeInfo ** ppNodeInfo_p);
diff --git a/drivers/staging/epl/kernel/EplDllkCal.h b/drivers/staging/epl/kernel/EplDllkCal.h
index 6c4dc7e4a80..ddec1d5e8cc 100644
--- a/drivers/staging/epl/kernel/EplDllkCal.h
+++ b/drivers/staging/epl/kernel/EplDllkCal.h
@@ -74,14 +74,6 @@
#include "../EplDll.h"
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
typedef struct {
unsigned long m_ulCurTxFrameCountGen;
unsigned long m_ulCurTxFrameCountNmt;
@@ -92,10 +84,6 @@ typedef struct {
} tEplDllkCalStatistics;
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
tEplKernel EplDllkCalAddInstance(void);
@@ -124,7 +112,7 @@ tEplKernel EplDllkCalProcess(tEplEvent * pEvent_p);
tEplKernel EplDllkCalAsyncClearQueues(void);
tEplKernel EplDllkCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p);
tEplKernel EplDllkCalAsyncGetSoaRequest(tEplDllReqServiceId * pReqServiceId_p,
unsigned int *puiNodeId_p);
diff --git a/drivers/staging/epl/kernel/EplErrorHandlerk.h b/drivers/staging/epl/kernel/EplErrorHandlerk.h
index 4a67ef88b97..185b597d6e5 100644
--- a/drivers/staging/epl/kernel/EplErrorHandlerk.h
+++ b/drivers/staging/epl/kernel/EplErrorHandlerk.h
@@ -73,28 +73,16 @@
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
// init function
-tEplKernel PUBLIC EplErrorHandlerkInit(void);
+tEplKernel EplErrorHandlerkInit(void);
// add instance
-tEplKernel PUBLIC EplErrorHandlerkAddInstance(void);
+tEplKernel EplErrorHandlerkAddInstance(void);
// delete instance
-tEplKernel PUBLIC EplErrorHandlerkDelInstance(void);
+tEplKernel EplErrorHandlerkDelInstance(void);
// processes error events
-tEplKernel PUBLIC EplErrorHandlerkProcess(tEplEvent * pEvent_p);
+tEplKernel EplErrorHandlerkProcess(tEplEvent *pEvent_p);
#endif // #ifndef _EPL_ERRORHANDLERK_H_
diff --git a/drivers/staging/epl/kernel/EplEventk.h b/drivers/staging/epl/kernel/EplEventk.h
index 1d25aaa2ed4..0c2a60f7207 100644
--- a/drivers/staging/epl/kernel/EplEventk.h
+++ b/drivers/staging/epl/kernel/EplEventk.h
@@ -73,36 +73,24 @@
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
// init function
-tEplKernel PUBLIC EplEventkInit(tEplSyncCb fpSyncCb);
+tEplKernel EplEventkInit(tEplSyncCb fpSyncCb);
// add instance
-tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb fpSyncCb);
+tEplKernel EplEventkAddInstance(tEplSyncCb fpSyncCb);
// delete instance
-tEplKernel PUBLIC EplEventkDelInstance(void);
+tEplKernel EplEventkDelInstance(void);
// Kernelthread that dispatches events in kernelspace
-tEplKernel PUBLIC EplEventkProcess(tEplEvent * pEvent_p);
+tEplKernel EplEventkProcess(tEplEvent *pEvent_p);
// post events from kernelspace
-tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p);
+tEplKernel EplEventkPost(tEplEvent *pEvent_p);
// post errorevents from kernelspace
-tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p);
+tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p);
#endif // #ifndef _EPL_EVENTK_H_
diff --git a/drivers/staging/epl/kernel/EplNmtk.h b/drivers/staging/epl/kernel/EplNmtk.h
index 53409cc8992..5dc8a373159 100644
--- a/drivers/staging/epl/kernel/EplNmtk.h
+++ b/drivers/staging/epl/kernel/EplNmtk.h
@@ -74,31 +74,16 @@
#include "../EplNmt.h"
#include "EplEventk.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkInit(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplKernel EplNmtkDelInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplEvent * pEvent_p);
+tEplKernel EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplEvent *pEvent_p);
-EPLDLLEXPORT tEplNmtState PUBLIC
-EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
+tEplNmtState EplNmtkGetNmtState(EPL_MCO_DECL_PTR_INSTANCE_PTR);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
diff --git a/drivers/staging/epl/kernel/EplNmtkCal.h b/drivers/staging/epl/kernel/EplNmtkCal.h
deleted file mode 100644
index 9edeafca492..00000000000
--- a/drivers/staging/epl/kernel/EplNmtkCal.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: include file for communication abstraction layer of the
- NMT-Kernel-Module
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplNmtkCal.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.3 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- KEIL uVision 2
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/06/16 -k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "EplNmtk.h"
-
-#ifndef _EPLNMTKCAL_H_
-#define _EPLNMTKCAL_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLNMTKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplObdk.h b/drivers/staging/epl/kernel/EplObdk.h
index cf9f5837dd3..78c4d961342 100644
--- a/drivers/staging/epl/kernel/EplObdk.h
+++ b/drivers/staging/epl/kernel/EplObdk.h
@@ -68,128 +68,88 @@
****************************************************************************/
-#include "../EplObd.h"
-
#ifndef _EPLOBDK_H_
#define _EPLOBDK_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// global variables
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
-extern BYTE MEM abEplObdTrashObject_g[8];
+extern u8 abEplObdTrashObject_g[8];
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM * pInitParam_p);
+tEplKernel EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_
- tEplObdInitParam MEM *
- pInitParam_p);
+tEplKernel EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam *pInitParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR);
+tEplKernel EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdStoreLoadObjCallback fpCallback_p);
+tEplKernel EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdPart ObdPart_p,
- tEplObdDir Direction_p);
+tEplKernel EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,
+ tEplObdDir Direction_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_
- tEplVarParam MEM * pVarParam_p);
+tEplKernel EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam *pVarParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+void *EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdEntryPtr pUserOd_p);
+tEplKernel EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- tEplObdVarEntry MEM * pVarEntry_p,
- tEplObdType Type_p,
- tEplObdSize ObdSize_p);
+void EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry *pVarEntry_p,
+ tEplObdType Type_p, tEplObdSize ObdSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+tEplObdSize EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
+unsigned int EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p);
+tEplKernel EplObdSetNodeId(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- BOOL * pfEntryNumerical);
+tEplKernel EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p, BOOL *pfEntryNumerical);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p);
+tEplKernel EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM **
- ppVarEntry_p);
+tEplKernel EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p);
#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
diff --git a/drivers/staging/epl/kernel/EplObdkCal.h b/drivers/staging/epl/kernel/EplObdkCal.h
deleted file mode 100644
index c173a950054..00000000000
--- a/drivers/staging/epl/kernel/EplObdkCal.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/****************************************************************************
-
- (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
- www.systec-electronic.com
-
- Project: openPOWERLINK
-
- Description: include file for communication abstraction layer
- for the Epl-Obd-Kernelspace-Modul
-
- License:
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of SYSTEC electronic GmbH nor the names of its
- contributors may be used to endorse or promote products derived
- from this software without prior written permission. For written
- permission, please contact info@systec-electronic.com.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- POSSIBILITY OF SUCH DAMAGE.
-
- Severability Clause:
-
- If a provision of this License is or becomes illegal, invalid or
- unenforceable in any jurisdiction, that shall not affect:
- 1. the validity or enforceability in that jurisdiction of any other
- provision of this License; or
- 2. the validity or enforceability in other jurisdictions of that or
- any other provision of this License.
-
- -------------------------------------------------------------------------
-
- $RCSfile: EplObdkCal.h,v $
-
- $Author: D.Krueger $
-
- $Revision: 1.4 $ $Date: 2008/04/17 21:36:32 $
-
- $State: Exp $
-
- Build Environment:
- GCC V3.4
-
- -------------------------------------------------------------------------
-
- Revision History:
-
- 2006/06/19 k.t.: start of the implementation
-
-****************************************************************************/
-
-#include "../EplObd.h"
-
-#ifndef _EPLOBDKCAL_H_
-#define _EPLOBDKCAL_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-#endif // #ifndef _EPLOBDKCAL_H_
diff --git a/drivers/staging/epl/kernel/EplPdok.h b/drivers/staging/epl/kernel/EplPdok.h
index b5b18f4cf68..24bfc3f73e9 100644
--- a/drivers/staging/epl/kernel/EplPdok.h
+++ b/drivers/staging/epl/kernel/EplPdok.h
@@ -75,18 +75,6 @@
#include "../EplEvent.h"
#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
// process events from queue (PDOs/frames and SoA for synchronization)
tEplKernel EplPdokProcess(tEplEvent * pEvent_p);
diff --git a/drivers/staging/epl/kernel/EplPdokCal.h b/drivers/staging/epl/kernel/EplPdokCal.h
index 6a183ebe81e..8a31edfdb4f 100644
--- a/drivers/staging/epl/kernel/EplPdokCal.h
+++ b/drivers/staging/epl/kernel/EplPdokCal.h
@@ -72,19 +72,6 @@
#define _EPL_PDOKCAL_H_
#include "../EplInc.h"
-//#include "EplPdo.h"
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
tEplKernel EplPdokCalAddInstance(void);
diff --git a/drivers/staging/epl/kernel/EplTimerHighResk.h b/drivers/staging/epl/kernel/EplTimerHighResk.h
index d5d046d4d37..a2124ee49f7 100644
--- a/drivers/staging/epl/kernel/EplTimerHighResk.h
+++ b/drivers/staging/epl/kernel/EplTimerHighResk.h
@@ -68,42 +68,29 @@
****************************************************************************/
-#include "../EplTimer.h"
-
#ifndef _EPLTIMERHIGHRESK_H_
#define _EPLTIMERHIGHRESK_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "../EplTimer.h"
-tEplKernel PUBLIC EplTimerHighReskInit(void);
+tEplKernel EplTimerHighReskInit(void);
-tEplKernel PUBLIC EplTimerHighReskAddInstance(void);
+tEplKernel EplTimerHighReskAddInstance(void);
-tEplKernel PUBLIC EplTimerHighReskDelInstance(void);
+tEplKernel EplTimerHighReskDelInstance(void);
-tEplKernel PUBLIC EplTimerHighReskSetTimerNs(tEplTimerHdl * pTimerHdl_p,
- unsigned long long ullTimeNs_p,
- tEplTimerkCallback pfnCallback_p,
- unsigned long ulArgument_p,
- BOOL fContinuously_p);
+tEplKernel EplTimerHighReskSetTimerNs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long long ullTimeNs_p,
+ tEplTimerkCallback pfnCallback_p,
+ unsigned long ulArgument_p,
+ BOOL fContinuously_p);
-tEplKernel PUBLIC EplTimerHighReskModifyTimerNs(tEplTimerHdl * pTimerHdl_p,
- unsigned long long ullTimeNs_p,
- tEplTimerkCallback
- pfnCallback_p,
- unsigned long ulArgument_p,
- BOOL fContinuously_p);
+tEplKernel EplTimerHighReskModifyTimerNs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long long ullTimeNs_p,
+ tEplTimerkCallback pfnCallback_p,
+ unsigned long ulArgument_p,
+ BOOL fContinuously_p);
-tEplKernel PUBLIC EplTimerHighReskDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimerHighReskDeleteTimer(tEplTimerHdl *pTimerHdl_p);
#endif // #ifndef _EPLTIMERHIGHRESK_H_
diff --git a/drivers/staging/epl/kernel/EplTimerk.h b/drivers/staging/epl/kernel/EplTimerk.h
index 9160e7260de..47c5f47b8aa 100644
--- a/drivers/staging/epl/kernel/EplTimerk.h
+++ b/drivers/staging/epl/kernel/EplTimerk.h
@@ -68,19 +68,16 @@
****************************************************************************/
-#include "../EplTimer.h"
-#include "../user/EplEventu.h"
-
#ifndef _EPLTIMERK_H_
#define _EPLTIMERK_H_
+#include "../EplTimer.h"
+#include "../user/EplEventu.h"
+
#if EPL_TIMER_USE_USER != FALSE
#include "../user/EplTimeru.h"
#endif
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
#if EPL_TIMER_USE_USER != FALSE
#define EplTimerkInit EplTimeruInit
@@ -91,28 +88,21 @@
#define EplTimerkDeleteTimer EplTimeruDeleteTimer
#endif
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if EPL_TIMER_USE_USER == FALSE
-tEplKernel PUBLIC EplTimerkInit(void);
+tEplKernel EplTimerkInit(void);
-tEplKernel PUBLIC EplTimerkAddInstance(void);
+tEplKernel EplTimerkAddInstance(void);
-tEplKernel PUBLIC EplTimerkDelInstance(void);
+tEplKernel EplTimerkDelInstance(void);
-tEplKernel PUBLIC EplTimerkSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimerkSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimerkModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimerkModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimerkDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimerkDeleteTimer(tEplTimerHdl *pTimerHdl_p);
#endif
#endif // #ifndef _EPLTIMERK_H_
diff --git a/drivers/staging/epl/kernel/VirtualEthernet.h b/drivers/staging/epl/kernel/VirtualEthernet.h
index deff8720e37..4a42cce66ca 100644
--- a/drivers/staging/epl/kernel/VirtualEthernet.h
+++ b/drivers/staging/epl/kernel/VirtualEthernet.h
@@ -73,23 +73,11 @@
#include "EplDllk.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
-tEplKernel PUBLIC VEthAddInstance(tEplDllkInitParam * pInitParam_p);
+tEplKernel VEthAddInstance(tEplDllkInitParam *pInitParam_p);
-tEplKernel PUBLIC VEthDelInstance(void);
+tEplKernel VEthDelInstance(void);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_VETH)) != 0)
diff --git a/drivers/staging/epl/proc_fs.c b/drivers/staging/epl/proc_fs.c
index f4910332d3c..9ccf079e67e 100644
--- a/drivers/staging/epl/proc_fs.c
+++ b/drivers/staging/epl/proc_fs.c
@@ -83,7 +83,6 @@
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/major.h>
-#include <linux/version.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
@@ -95,6 +94,8 @@
#include "fec.h"
#endif
+#include "proc_fs.h"
+
/***************************************************************************/
/* */
/* */
@@ -129,8 +130,8 @@
#ifdef _DBG_TRACE_POINTS_
atomic_t aatmDbgTracePoint_l[DBG_TRACE_POINTS];
-DWORD adwDbgTraceValue_l[DBG_TRACE_VALUES];
-DWORD dwDbgTraceValueOld_l;
+u32 adwDbgTraceValue_l[DBG_TRACE_VALUES];
+u32 dwDbgTraceValueOld_l;
unsigned int uiDbgTraceValuePos_l;
spinlock_t spinlockDbgTraceValue_l;
unsigned long ulDbTraceValueFlags_l;
@@ -145,10 +146,10 @@ static int EplLinProcRead(char *pcBuffer_p, char **ppcStart_p, off_t Offset_p,
static int EplLinProcWrite(struct file *file, const char __user * buffer,
unsigned long count, void *data);
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
+void TgtDbgPostTraceValue(u32 dwTraceValue_p);
-EPLDLLEXPORT DWORD PUBLIC EplIdentuGetRunningRequests(void);
+extern u32 EplIdentuGetRunningRequests(void);
//=========================================================================//
// //
@@ -191,7 +192,7 @@ tEplKernel EplLinProcFree(void)
//---------------------------------------------------------------------------
#ifdef _DBG_TRACE_POINTS_
-void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p)
+void TgtDbgSignalTracePoint(u8 bTracePointNumber_p)
{
if (bTracePointNumber_p >=
@@ -207,7 +208,7 @@ void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p)
}
-void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p)
+void TgtDbgPostTraceValue(u32 dwTraceValue_p)
{
spin_lock_irqsave(&spinlockDbgTraceValue_l, ulDbTraceValueFlags_l);
@@ -263,7 +264,7 @@ static int EplLinProcRead(char *pcBuffer_p,
// ---- EPL state ----
nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
"NMT state: 0x%04X\n",
- (WORD) EplNmtkGetNmtState());
+ (u16) EplNmtkGetNmtState());
EplDllkCalGetStatistics(&pDllkCalStats);
@@ -279,14 +280,14 @@ static int EplLinProcRead(char *pcBuffer_p,
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
// fetch running IdentRequests
nSize += snprintf(pcBuffer_p + nSize, nBufferSize_p - nSize,
- "running IdentRequests: 0x%08lX\n",
+ "running IdentRequests: 0x%08X\n",
EplIdentuGetRunningRequests());
// fetch state of NmtMnu module
{
unsigned int uiMandatorySlaveCount;
unsigned int uiSignalSlaveCount;
- WORD wFlags;
+ u16 wFlags;
EplNmtMnuGetDiagnosticInfo(&uiMandatorySlaveCount,
&uiSignalSlaveCount, &wFlags);
diff --git a/drivers/staging/epl/user/EplCfgMau.h b/drivers/staging/epl/user/EplCfgMau.h
index d25a1e9d36c..4ac770f1310 100644
--- a/drivers/staging/epl/user/EplCfgMau.h
+++ b/drivers/staging/epl/user/EplCfgMau.h
@@ -69,25 +69,22 @@
****************************************************************************/
-#include "../EplInc.h"
-
#ifndef _EPLCFGMA_H_
#define _EPLCFGMA_H_
+#include "../EplInc.h"
+
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
#include "EplObdu.h"
#include "EplSdoComu.h"
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
//define max number of timeouts for configuration of 1 device
#define EPL_CFGMA_MAX_TIMEOUT 3
//callbackfunction, called if configuration is finished
-typedef void (PUBLIC * tfpEplCfgMaCb) (unsigned int uiNodeId_p,
- tEplKernel Errorstate_p);
+typedef void (* tfpEplCfgMaCb)(unsigned int uiNodeId_p,
+ tEplKernel Errorstate_p);
//State for configuartion manager Statemachine
typedef enum {
@@ -131,33 +128,29 @@ typedef enum {
typedef struct {
tEplCfgState m_CfgState; // state of the configuration state maschine
tEplSdoComConHdl m_SdoComConHdl; // handle for sdo connection
- DWORD m_dwLastAbortCode;
+ u32 m_dwLastAbortCode;
unsigned int m_uiLastIndex; // last index of configuration, to compair with actual index
- BYTE *m_pbConcise; // Ptr to concise DCF
- BYTE *m_pbActualIndex; // Ptr to actual index in the DCF segment
+ u8 *m_pbConcise; // Ptr to concise DCF
+ u8 *m_pbActualIndex; // Ptr to actual index in the DCF segment
tfpEplCfgMaCb m_pfnCfgMaCb; // Ptr to CfgMa Callback, is call if configuration finished
tEplKernel m_EplKernelError; // errorcode
- DWORD m_dwNumValueCopy; // numeric values are copied in this variable
+ u32 m_dwNumValueCopy; // numeric values are copied in this variable
unsigned int m_uiPdoNodeId; // buffer for PDO node id
- BYTE m_bNrOfMappedObject; // number of mapped objects
+ u8 m_bNrOfMappedObject; // number of mapped objects
unsigned int m_uiNodeId; // Epl node addresse
tEplSdocState m_SdocState; // bitcoded state of the SDO transfer
unsigned int m_uiLastSubIndex; // last subindex of configuration
BOOL m_fOneTranferOk; // atleased one transfer was successful
- BYTE m_bEventFlag; // for Eventsignaling to the State Maschine
- DWORD m_dwCntObjectInDcf; // number of Objects in DCF
+ u8 m_bEventFlag; // for Eventsignaling to the State Maschine
+ u32 m_dwCntObjectInDcf; // number of Objects in DCF
tEplCfgMaIndexType m_SkipCfg; // TRUE if a adsitional Configurationprocess
// have to insert e.g. PDO-mapping
- WORD m_wTimeOutCnt; // Timeout Counter, break configuration is
+ u16 m_wTimeOutCnt; // Timeout Counter, break configuration is
// m_wTimeOutCnt == CFGMA_MAX_TIMEOUT
} tEplCfgMaNode;
//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
// Function: EplCfgMaInit()
//
// Description: Function creates first instance of Configuration Manager
@@ -166,7 +159,7 @@ typedef struct {
//
// Returns: tEplKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaInit();
+tEplKernel EplCfgMaInit(void);
//---------------------------------------------------------------------------
// Function: EplCfgMaAddInstance()
@@ -177,7 +170,7 @@ tEplKernel PUBLIC EplCfgMaInit();
//
// Returns: tEplKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaAddInstance();
+tEplKernel EplCfgMaAddInstance(void);
//---------------------------------------------------------------------------
// Function: EplCfgMaDelInstance()
@@ -188,7 +181,7 @@ tEplKernel PUBLIC EplCfgMaAddInstance();
//
// Returns: tEplKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaDelInstance();
+tEplKernel plCfgMaDelInstance(void);
//---------------------------------------------------------------------------
// Function: EplCfgMaStartConfig()
@@ -199,16 +192,16 @@ tEplKernel PUBLIC EplCfgMaDelInstance();
// Parameters: uiNodeId_p = NodeId of the node to configure
// pbConcise_p = pointer to DCF
// fpCfgMaCb_p = pointer to callback function (should not be NULL)
-// SizeOfConcise_p = size of DCF in BYTE -> for future use
+// SizeOfConcise_p = size of DCF in u8 -> for future use
// DcfType_p = type of the DCF
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfig(unsigned int uiNodeId_p,
- BYTE * pbConcise_p,
- tfpEplCfgMaCb fpCfgMaCb_p,
- tEplObdSize SizeOfConcise_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfig(unsigned int uiNodeId_p,
+ u8 * pbConcise_p,
+ tfpEplCfgMaCb fpCfgMaCb_p,
+ tEplObdSize SizeOfConcise_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: CfgMaStartConfigurationNode()
@@ -222,9 +215,9 @@ tEplKernel PUBLIC EplCfgMaStartConfig(unsigned int uiNodeId_p,
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
- tfpEplCfgMaCb fpCfgMaCb_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
+ tfpEplCfgMaCb fpCfgMaCb_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: EplCfgMaStartConfigNodeDcf()
@@ -235,16 +228,16 @@ tEplKernel PUBLIC EplCfgMaStartConfigNode(unsigned int uiNodeId_p,
// Parameters: uiNodeId_p = NodeId of the node to configure
// pbConcise_p = pointer to DCF
// fpCfgMaCb_p = pointer to callback function (should not be NULL)
-// SizeOfConcise_p = size of DCF in BYTE -> for future use
+// SizeOfConcise_p = size of DCF in u8 -> for future use
// DcfType_p = type of the DCF
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
- BYTE * pbConcise_p,
- tfpEplCfgMaCb fpCfgMaCb_p,
- tEplObdSize SizeOfConcise_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
+ u8 * pbConcise_p,
+ tfpEplCfgMaCb fpCfgMaCb_p,
+ tEplObdSize SizeOfConcise_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: EplCfgMaLinkDcf()
@@ -253,15 +246,15 @@ tEplKernel PUBLIC EplCfgMaStartConfigNodeDcf(unsigned int uiNodeId_p,
//
// Parameters: uiNodeId_p = NodeId of the node to configure
// pbConcise_p = pointer to DCF
-// SizeOfConcise_p = size of DCF in BYTE -> for future use
+// SizeOfConcise_p = size of DCF in u8 -> for future use
// DcfType_p = type of the DCF
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaLinkDcf(unsigned int uiNodeId_p,
- BYTE * pbConcise_p,
- tEplObdSize SizeOfConcise_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaLinkDcf(unsigned int uiNodeId_p,
+ u8 * pbConcise_p,
+ tEplObdSize SizeOfConcise_p,
+ tEplCfgMaDcfTyp DcfType_p);
//---------------------------------------------------------------------------
// Function: EplCfgMaCheckDcf()
@@ -274,8 +267,7 @@ tEplKernel PUBLIC EplCfgMaLinkDcf(unsigned int uiNodeId_p,
//
// Returns: tCopKernel = error code
//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplCfgMaCheckDcf(unsigned int uiNodeId_p,
- tEplCfgMaDcfTyp DcfType_p);
+tEplKernel EplCfgMaCheckDcf(unsigned int uiNodeId_p, tEplCfgMaDcfTyp DcfType_p);
#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFGMA)) != 0)
diff --git a/drivers/staging/epl/user/EplDllu.h b/drivers/staging/epl/user/EplDllu.h
index 36f8bb76f7c..890f83759ca 100644
--- a/drivers/staging/epl/user/EplDllu.h
+++ b/drivers/staging/epl/user/EplDllu.h
@@ -73,19 +73,7 @@
#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
diff --git a/drivers/staging/epl/user/EplDlluCal.h b/drivers/staging/epl/user/EplDlluCal.h
index b1dcd060957..bc9126b1627 100644
--- a/drivers/staging/epl/user/EplDlluCal.h
+++ b/drivers/staging/epl/user/EplDlluCal.h
@@ -74,19 +74,8 @@
#include "../EplDll.h"
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplDlluCbAsnd) (tEplFrameInfo * pFrameInfo_p);
tEplKernel EplDlluCalAddInstance(void);
@@ -110,7 +99,7 @@ tEplKernel EplDlluCalDeleteNode(unsigned int uiNodeId_p);
tEplKernel EplDlluCalSoftDeleteNode(unsigned int uiNodeId_p);
tEplKernel EplDlluCalIssueRequest(tEplDllReqServiceId Service_p,
- unsigned int uiNodeId_p, BYTE bSoaFlag1_p);
+ unsigned int uiNodeId_p, u8 bSoaFlag1_p);
#endif
diff --git a/drivers/staging/epl/user/EplEventu.h b/drivers/staging/epl/user/EplEventu.h
index 322cffd1187..ab85205b239 100644
--- a/drivers/staging/epl/user/EplEventu.h
+++ b/drivers/staging/epl/user/EplEventu.h
@@ -73,36 +73,24 @@
#include "../EplEvent.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
// init function
-tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
+tEplKernel EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p);
// add instance
-tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
- pfnApiProcessEventCb_p);
+tEplKernel EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p);
// delete instance
-tEplKernel PUBLIC EplEventuDelInstance(void);
+tEplKernel EplEventuDelInstance(void);
// Task that dispatches events in userspace
-tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p);
+tEplKernel EplEventuProcess(tEplEvent * pEvent_p);
// post events from userspace
-tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p);
+tEplKernel EplEventuPost(tEplEvent * pEvent_p);
// post errorevents from userspace
-tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
- tEplKernel EplError_p,
- unsigned int uiArgSize_p, void *pArg_p);
+tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
+ tEplKernel EplError_p,
+ unsigned int uiArgSize_p, void *pArg_p);
#endif // #ifndef _EPL_EVENTU_H_
diff --git a/drivers/staging/epl/user/EplIdentu.h b/drivers/staging/epl/user/EplIdentu.h
index e7302106c74..057c9029e98 100644
--- a/drivers/staging/epl/user/EplIdentu.h
+++ b/drivers/staging/epl/user/EplIdentu.h
@@ -68,41 +68,27 @@
****************************************************************************/
-#include "../EplDll.h"
-
#ifndef _EPLIDENTU_H_
#define _EPLIDENTU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplDll.h"
-typedef tEplKernel(PUBLIC * tEplIdentuCbResponse) (unsigned int uiNodeId_p,
+typedef tEplKernel(* tEplIdentuCbResponse) (unsigned int uiNodeId_p,
tEplIdentResponse *
pIdentResponse_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
-tEplKernel PUBLIC EplIdentuInit(void);
+tEplKernel EplIdentuInit(void);
-tEplKernel PUBLIC EplIdentuAddInstance(void);
+tEplKernel EplIdentuAddInstance(void);
-tEplKernel PUBLIC EplIdentuDelInstance(void);
+tEplKernel EplIdentuDelInstance(void);
-tEplKernel PUBLIC EplIdentuReset(void);
+tEplKernel EplIdentuReset(void);
-tEplKernel PUBLIC EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
- tEplIdentResponse **
- ppIdentResponse_p);
+tEplKernel EplIdentuGetIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentResponse **ppIdentResponse_p);
-tEplKernel PUBLIC EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
- tEplIdentuCbResponse
- pfnCbResponse_p);
+tEplKernel EplIdentuRequestIdentResponse(unsigned int uiNodeId_p,
+ tEplIdentuCbResponse pfnCbResponse_p);
#endif // #ifndef _EPLIDENTU_H_
diff --git a/drivers/staging/epl/user/EplLedu.h b/drivers/staging/epl/user/EplLedu.h
index 78e70d06445..ca9eb431100 100644
--- a/drivers/staging/epl/user/EplLedu.h
+++ b/drivers/staging/epl/user/EplLedu.h
@@ -68,41 +68,27 @@
****************************************************************************/
-#include "../EplLed.h"
-#include "../EplNmt.h"
-#include "EplEventu.h"
-
#ifndef _EPLLEDU_H_
#define _EPLLEDU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplLed.h"
+#include "../EplNmt.h"
+#include "EplEventu.h"
-typedef tEplKernel(PUBLIC * tEplLeduStateChangeCallback) (tEplLedType LedType_p,
+typedef tEplKernel(* tEplLeduStateChangeCallback) (tEplLedType LedType_p,
BOOL fOn_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
-tEplKernel PUBLIC EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
+tEplKernel EplLeduInit(tEplLeduStateChangeCallback pfnCbStateChange_p);
-tEplKernel PUBLIC EplLeduAddInstance(tEplLeduStateChangeCallback
- pfnCbStateChange_p);
+tEplKernel EplLeduAddInstance(tEplLeduStateChangeCallback pfnCbStateChange_p);
-tEplKernel PUBLIC EplLeduDelInstance(void);
+tEplKernel EplLeduDelInstance(void);
-tEplKernel PUBLIC EplLeduCbNmtStateChange(tEplEventNmtStateChange
- NmtStateChange_p);
+tEplKernel EplLeduCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
-tEplKernel PUBLIC EplLeduProcessEvent(tEplEvent * pEplEvent_p);
+tEplKernel EplLeduProcessEvent(tEplEvent * pEplEvent_p);
#endif // #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
diff --git a/drivers/staging/epl/user/EplNmtCnu.h b/drivers/staging/epl/user/EplNmtCnu.h
index e508055b5b8..7d230297f43 100644
--- a/drivers/staging/epl/user/EplNmtCnu.h
+++ b/drivers/staging/epl/user/EplNmtCnu.h
@@ -68,40 +68,24 @@
****************************************************************************/
-#include "EplNmtu.h"
-#include "../EplDll.h"
-#include "../EplFrame.h"
-
#ifndef _EPLNMTCNU_H_
#define _EPLNMTCNU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "EplNmtu.h"
+#include "../EplDll.h"
+#include "../EplFrame.h"
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuInit(unsigned int uiNodeId_p);
+tEplKernel EplNmtCnuInit(unsigned int uiNodeId_p);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuAddInstance(unsigned int uiNodeId_p);
+tEplKernel EplNmtCnuAddInstance(unsigned int uiNodeId_p);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuDelInstance(void);
+tEplKernel EplNmtCnuDelInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p,
- tEplNmtCommand
- NmtCommand_p);
+tEplKernel EplNmtCnuSendNmtRequest(unsigned int uiNodeId_p, tEplNmtCommand NmtCommand_p);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback
- pfnEplNmtCheckEventCb_p);
+tEplKernel EplNmtCnuRegisterCheckEventCb(tEplNmtuCheckEventCallback pfnEplNmtCheckEventCb_p);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
diff --git a/drivers/staging/epl/user/EplNmtMnu.h b/drivers/staging/epl/user/EplNmtMnu.h
index c54efeba303..5e5e0cda324 100644
--- a/drivers/staging/epl/user/EplNmtMnu.h
+++ b/drivers/staging/epl/user/EplNmtMnu.h
@@ -68,34 +68,20 @@
****************************************************************************/
-#include "EplNmtu.h"
-
#ifndef _EPLNMTMNU_H_
#define _EPLNMTMNU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p,
- tEplNmtNodeEvent
- NodeEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p,
- BOOL fMandatory_p);
+#include "EplNmtu.h"
-typedef tEplKernel(PUBLIC *
- tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p,
- tEplNmtState NmtState_p,
- WORD wErrorCode_p);
+typedef tEplKernel(* tEplNmtMnuCbNodeEvent) (unsigned int uiNodeId_p,
+ tEplNmtNodeEvent NodeEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p,
+ BOOL fMandatory_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplNmtMnuCbBootEvent) (tEplNmtBootEvent BootEvent_p,
+ tEplNmtState NmtState_p,
+ u16 wErrorCode_p);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
@@ -107,7 +93,7 @@ tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
tEplKernel EplNmtMnuDelInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p);
+tEplKernel EplNmtMnuProcessEvent(tEplEvent *pEvent_p);
tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
tEplNmtCommand NmtCommand_p);
@@ -115,16 +101,16 @@ tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
tEplNmtNodeCommand NodeCommand_p);
-tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
+tEplKernel EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
NmtStateChange_p);
-tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
+tEplKernel EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p);
-tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
+tEplKernel EplNmtMnuGetDiagnosticInfo(unsigned int
*puiMandatorySlaveCount_p,
unsigned int
*puiSignalSlaveCount_p,
- WORD * pwFlags_p);
+ u16 * pwFlags_p);
#endif
diff --git a/drivers/staging/epl/user/EplNmtu.h b/drivers/staging/epl/user/EplNmtu.h
index 5a56c583060..c1fca80f5a0 100644
--- a/drivers/staging/epl/user/EplNmtu.h
+++ b/drivers/staging/epl/user/EplNmtu.h
@@ -68,19 +68,12 @@
****************************************************************************/
-#include "../EplNmt.h"
-#include "EplEventu.h"
-
#ifndef _EPLNMTU_H_
#define _EPLNMTU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+#include "../EplNmt.h"
+#include "EplEventu.h"
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
// nmt commands
typedef enum {
// requestable ASnd ServiceIds 0x01..0x1F
@@ -121,34 +114,25 @@ typedef enum {
kEplNmtCmdInvalidService = 0xFF
} tEplNmtCommand;
-typedef tEplKernel(PUBLIC *
- tEplNmtuStateChangeCallback) (tEplEventNmtStateChange
- NmtStateChange_p);
-
-typedef tEplKernel(PUBLIC *
- tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p);
+typedef tEplKernel(* tEplNmtuStateChangeCallback) (tEplEventNmtStateChange NmtStateChange_p);
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplNmtuCheckEventCallback) (tEplNmtEvent NmtEvent_p);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuInit(void);
+tEplKernel EplNmtuInit(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuAddInstance(void);
+tEplKernel EplNmtuAddInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuDelInstance(void);
+tEplKernel EplNmtuDelInstance(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
+tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p);
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtuGetNmtState(void);
+tEplNmtState EplNmtuGetNmtState(void);
-EPLDLLEXPORT tEplKernel PUBLIC EplNmtuProcessEvent(tEplEvent * pEplEvent_p);
+tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p);
-EPLDLLEXPORT tEplKernel PUBLIC
-EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback
- pfnEplNmtStateChangeCb_p);
+tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p);
#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
diff --git a/drivers/staging/epl/user/EplNmtuCal.h b/drivers/staging/epl/user/EplNmtuCal.h
index c881582702b..b9850372a4a 100644
--- a/drivers/staging/epl/user/EplNmtuCal.h
+++ b/drivers/staging/epl/user/EplNmtuCal.h
@@ -69,23 +69,12 @@
****************************************************************************/
-#include "EplNmtu.h"
-#include "../kernel/EplNmtk.h"
-
#ifndef _EPLNMTUCAL_H_
#define _EPLNMTUCAL_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "EplNmtu.h"
+#include "../kernel/EplNmtk.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplNmtState PUBLIC EplNmtkCalGetNmtState(void);
+tEplNmtState EplNmtkCalGetNmtState(void);
#endif // #ifndef _EPLNMTUCAL_H_
diff --git a/drivers/staging/epl/user/EplObdu.h b/drivers/staging/epl/user/EplObdu.h
index bc1e1730301..086371276cf 100644
--- a/drivers/staging/epl/user/EplObdu.h
+++ b/drivers/staging/epl/user/EplObdu.h
@@ -68,22 +68,10 @@
****************************************************************************/
-#include "../EplObd.h"
-
#ifndef _EPLOBDU_H_
#define _EPLOBDU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0)
@@ -91,68 +79,57 @@
#error "EPL OBDu module enabled, but OBD_USE_KERNEL == TRUE"
#endif
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObduWriteEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduReadEntry(unsigned int uiIndex_p, unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p);
+tEplKernel EplObduAccessOdPart(tEplObdPart ObdPart_p, tEplObdDir Direction_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduDefineVar(tEplVarParam MEM * pVarParam_p);
+tEplKernel EplObduDefineVar(tEplVarParam *pVarParam_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+void *EplObduGetObjectDataPtr(unsigned int uiIndex_p, unsigned int uiSubIndex_p);
+
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p);
+tEplKernel EplObduRegisterUserOd(tEplObdEntryPtr pUserOd_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduInitVarEntry(tEplObdVarEntry MEM * pVarEntry_p,
- BYTE bType_p,
- tEplObdSize ObdSize_p);
+void EplObduInitVarEntry(tEplObdVarEntry *pVarEntry_p, u8 bType_p,
+ tEplObdSize ObdSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduGetDataSize(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+tEplObdSize EplObduGetDataSize(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduGetNodeId(void);
+unsigned int EplObduGetNodeId(void);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType NodeIdType_p);
+tEplKernel EplObduSetNodeId(unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p);
+
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduGetAccessType(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p);
+tEplKernel EplObduGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduReadEntryToLe(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p, tEplObdSize *pSize_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduWriteEntryFromLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObduWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p, tEplObdSize Size_p);
// ---------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_
- unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM **
- ppVarEntry_p);
+tEplKernel EplObduSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p);
#elif EPL_OBD_USE_KERNEL != FALSE
#include "../kernel/EplObdk.h"
diff --git a/drivers/staging/epl/user/EplObduCal.h b/drivers/staging/epl/user/EplObduCal.h
index 498e0112fac..07277777219 100644
--- a/drivers/staging/epl/user/EplObduCal.h
+++ b/drivers/staging/epl/user/EplObduCal.h
@@ -69,80 +69,58 @@
****************************************************************************/
-#include "../EplObd.h"
-
#ifndef _EPLOBDUCAL_H_
#define _EPLOBDUCAL_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplObd.h"
+tEplKernel EplObduCalWriteEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p);
//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
-//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntry(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduCalReadEntry(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
- tEplObdDir Direction_p);
+tEplKernel EplObduCalAccessOdPart(tEplObdPart ObdPart_p,
+ tEplObdDir Direction_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalDefineVar(tEplVarParam MEM *
- pVarParam_p);
+tEplKernel EplObduCalDefineVar(tEplVarParam *pVarParam_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT void *PUBLIC EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
- unsigned int uiSubIndex_p);
+void *EplObduCalGetObjectDataPtr(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalRegisterUserOd(tEplObdEntryPtr
- pUserOd_p);
+tEplKernel EplObduCalRegisterUserOd(tEplObdEntryPtr pUserOd_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT void PUBLIC EplObduCalInitVarEntry(tEplObdVarEntry MEM *
- pVarEntry_p, BYTE bType_p,
- tEplObdSize ObdSize_p);
+void EplObduCalInitVarEntry(tEplObdVarEntry *pVarEntry_p,
+ u8 bType_p, tEplObdSize ObdSize_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplObdSize PUBLIC EplObduCalGetDataSize(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p);
+tEplObdSize EplObduCalGetDataSize(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT unsigned int PUBLIC EplObduCalGetNodeId(void);
+unsigned int EplObduCalGetNodeId(void);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalSetNodeId(unsigned int uiNodeId_p,
- tEplObdNodeIdType
- NodeIdType_p);
+tEplKernel EplObduCalSetNodeId(unsigned int uiNodeId_p,
+ tEplObdNodeIdType NodeIdType_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalGetAccessType(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- tEplObdAccess *
- pAccessTyp_p);
+tEplKernel EplObduCalGetAccessType(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ tEplObdAccess *pAccessTyp_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalReadEntryToLe(unsigned int uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pDstData_p,
- tEplObdSize * pSize_p);
+tEplKernel EplObduCalReadEntryToLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pDstData_p,
+ tEplObdSize *pSize_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC EplObduCalWriteEntryFromLe(unsigned int
- uiIndex_p,
- unsigned int
- uiSubIndex_p,
- void *pSrcData_p,
- tEplObdSize Size_p);
+tEplKernel EplObduCalWriteEntryFromLe(unsigned int uiIndex_p,
+ unsigned int uiSubIndex_p,
+ void *pSrcData_p,
+ tEplObdSize Size_p);
//---------------------------------------------------------------------------
-EPLDLLEXPORT tEplKernel PUBLIC
-EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
- unsigned int uiSubindex_p,
- tEplObdVarEntry MEM ** ppVarEntry_p);
+tEplKernel EplObduCalSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,
+ unsigned int uiSubindex_p,
+ tEplObdVarEntry **ppVarEntry_p);
#endif // #ifndef _EPLOBDUCAL_H_
diff --git a/drivers/staging/epl/user/EplPdou.h b/drivers/staging/epl/user/EplPdou.h
index 11de4862e8b..b8c832b09db 100644
--- a/drivers/staging/epl/user/EplPdou.h
+++ b/drivers/staging/epl/user/EplPdou.h
@@ -72,24 +72,12 @@
#include "../EplPdo.h"
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-
tEplKernel EplPdouAddInstance(void);
tEplKernel EplPdouDelInstance(void);
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOU)) != 0)
-tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p);
+tEplKernel EplPdouCbObdAccess(tEplObdCbParam *pParam_p);
#else
#define EplPdouCbObdAccess NULL
#endif
@@ -97,12 +85,12 @@ tEplKernel PUBLIC EplPdouCbObdAccess(tEplObdCbParam MEM * pParam_p);
// returns error if bPdoId_p is already valid
/*
tEplKernel EplPdouSetMapping(
- BYTE bPdoId_p, BOOL fTxRx_p, BYTE bNodeId, BYTE bMappingVersion,
- tEplPdoMapping * pMapping_p, BYTE bMaxEntries_p);
+ u8 bPdoId_p, BOOL fTxRx_p, u8 bNodeId, u8 bMappingVersion,
+ tEplPdoMapping * pMapping_p, u8 bMaxEntries_p);
tEplKernel EplPdouGetMapping(
- BYTE bPdoId_p, BOOL fTxRx_p, BYTE * pbNodeId, BYTE * pbMappingVersion,
- tEplPdoMapping * pMapping_p, BYTE * pbMaxEntries_p);
+ u8 bPdoId_p, BOOL fTxRx_p, u8 * pbNodeId, u8 * pbMappingVersion,
+ tEplPdoMapping * pMapping_p, u8 * pbMaxEntries_p);
*/
#endif // #ifndef _EPL_PDOU_H_
diff --git a/drivers/staging/epl/user/EplSdoAsndu.h b/drivers/staging/epl/user/EplSdoAsndu.h
index e34959f4279..a62d4c97870 100644
--- a/drivers/staging/epl/user/EplSdoAsndu.h
+++ b/drivers/staging/epl/user/EplSdoAsndu.h
@@ -68,39 +68,28 @@
****************************************************************************/
-#include "../EplSdo.h"
-#include "../EplDll.h"
-
#ifndef _EPLSDOASNDU_H_
#define _EPLSDOASNDU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplSdo.h"
+#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
-tEplKernel PUBLIC EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoAsnduInit(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoAsnduAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoAsnduDelInstance(void);
+tEplKernel EplSdoAsnduDelInstance(void);
-tEplKernel PUBLIC EplSdoAsnduInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p);
+tEplKernel EplSdoAsnduInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p);
-tEplKernel PUBLIC EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p,
- DWORD dwDataSize_p);
+tEplKernel EplSdoAsnduSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p,
+ u32 dwDataSize_p);
-tEplKernel PUBLIC EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
+tEplKernel EplSdoAsnduDelCon(tEplSdoConHdl SdoConHandle_p);
#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_ASND)) != 0)
diff --git a/drivers/staging/epl/user/EplSdoAsySequ.h b/drivers/staging/epl/user/EplSdoAsySequ.h
index 4658b5f8c53..cc862de1a5b 100644
--- a/drivers/staging/epl/user/EplSdoAsySequ.h
+++ b/drivers/staging/epl/user/EplSdoAsySequ.h
@@ -68,44 +68,33 @@
****************************************************************************/
+#ifndef _EPLSDOASYSEQU_H_
+#define _EPLSDOASYSEQU_H_
+
#include "../EplSdo.h"
#include "EplSdoUdpu.h"
#include "EplSdoAsndu.h"
#include "../EplEvent.h"
#include "EplTimeru.h"
-#ifndef _EPLSDOASYSEQU_H_
-#define _EPLSDOASYSEQU_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
+tEplKernel EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+ tEplSdoComConCb fpSdoComConCb_p);
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoAsySeqInit(tEplSdoComReceiveCb fpSdoComCb_p,
+tEplKernel EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
tEplSdoComConCb fpSdoComConCb_p);
-tEplKernel PUBLIC EplSdoAsySeqAddInstance(tEplSdoComReceiveCb fpSdoComCb_p,
- tEplSdoComConCb fpSdoComConCb_p);
-
-tEplKernel PUBLIC EplSdoAsySeqDelInstance(void);
+tEplKernel EplSdoAsySeqDelInstance(void);
-tEplKernel PUBLIC EplSdoAsySeqInitCon(tEplSdoSeqConHdl * pSdoSeqConHdl_p,
- unsigned int uiNodeId_p,
- tEplSdoType SdoType);
+tEplKernel EplSdoAsySeqInitCon(tEplSdoSeqConHdl *pSdoSeqConHdl_p,
+ unsigned int uiNodeId_p,
+ tEplSdoType SdoType);
-tEplKernel PUBLIC EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
- unsigned int uiDataSize_p,
- tEplFrame * pData_p);
+tEplKernel EplSdoAsySeqSendData(tEplSdoSeqConHdl SdoSeqConHdl_p,
+ unsigned int uiDataSize_p,
+ tEplFrame *pData_p);
-tEplKernel PUBLIC EplSdoAsySeqProcessEvent(tEplEvent * pEvent_p);
+tEplKernel EplSdoAsySeqProcessEvent(tEplEvent *pEvent_p);
-tEplKernel PUBLIC EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p);
+tEplKernel EplSdoAsySeqDelCon(tEplSdoSeqConHdl SdoSeqConHdl_p);
#endif // #ifndef _EPLSDOASYSEQU_H_
diff --git a/drivers/staging/epl/user/EplSdoComu.h b/drivers/staging/epl/user/EplSdoComu.h
index 3e454c7a355..4eee6fa6974 100644
--- a/drivers/staging/epl/user/EplSdoComu.h
+++ b/drivers/staging/epl/user/EplSdoComu.h
@@ -68,58 +68,46 @@
****************************************************************************/
+#ifndef _EPLSDOCOMU_H_
+#define _EPLSDOCOMU_H_
+
#include "../EplSdo.h"
#include "../EplObd.h"
#include "../EplSdoAc.h"
#include "EplObdu.h"
#include "EplSdoAsySequ.h"
-#ifndef _EPLSDOCOMU_H_
-#define _EPLSDOCOMU_H_
-
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
-tEplKernel PUBLIC EplSdoComInit(void);
+tEplKernel EplSdoComInit(void);
-tEplKernel PUBLIC EplSdoComAddInstance(void);
+tEplKernel EplSdoComAddInstance(void);
-tEplKernel PUBLIC EplSdoComDelInstance(void);
+tEplKernel EplSdoComDelInstance(void);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
-tEplKernel PUBLIC EplSdoComDefineCon(tEplSdoComConHdl * pSdoComConHdl_p,
- unsigned int uiTargetNodeId_p,
- tEplSdoType ProtType_p);
+tEplKernel EplSdoComDefineCon(tEplSdoComConHdl *pSdoComConHdl_p,
+ unsigned int uiTargetNodeId_p,
+ tEplSdoType ProtType_p);
-tEplKernel PUBLIC EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *
- pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferByIndex(tEplSdoComTransParamByIndex *pSdoComTransParam_p);
-tEplKernel PUBLIC EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p);
+tEplKernel EplSdoComUndefineCon(tEplSdoComConHdl SdoComConHdl_p);
-tEplKernel PUBLIC EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
- tEplSdoComFinished * pSdoComFinished_p);
+tEplKernel EplSdoComGetState(tEplSdoComConHdl SdoComConHdl_p,
+ tEplSdoComFinished *pSdoComFinished_p);
-tEplKernel PUBLIC EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
- DWORD dwAbortCode_p);
+tEplKernel EplSdoComSdoAbort(tEplSdoComConHdl SdoComConHdl_p,
+ u32 dwAbortCode_p);
#endif
// for future extention
/*
-tEplKernel PUBLIC EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferAllByIndex(tEplSdoComTransParamAllByIndex* pSdoComTransParam_p);
-tEplKernel PUBLIC EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferByName(tEplSdoComTransParamByName* pSdoComTransParam_p);
-tEplKernel PUBLIC EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
+tEplKernel EplSdoComInitTransferFile(tEplSdoComTransParamFile* pSdoComTransParam_p);
*/
diff --git a/drivers/staging/epl/user/EplSdoUdpu.h b/drivers/staging/epl/user/EplSdoUdpu.h
index 2d77b6fff19..13e2a278c11 100644
--- a/drivers/staging/epl/user/EplSdoUdpu.h
+++ b/drivers/staging/epl/user/EplSdoUdpu.h
@@ -68,41 +68,29 @@
****************************************************************************/
-#include "../EplSdo.h"
-
#ifndef _EPLSDOUDPU_H_
#define _EPLSDOUDPU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
+#include "../EplSdo.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
-tEplKernel PUBLIC EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoUdpuInit(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
+tEplKernel EplSdoUdpuAddInstance(tEplSequLayerReceiveCb fpReceiveCb_p);
-tEplKernel PUBLIC EplSdoUdpuDelInstance(void);
+tEplKernel EplSdoUdpuDelInstance(void);
-tEplKernel PUBLIC EplSdoUdpuConfig(unsigned long ulIpAddr_p,
- unsigned int uiPort_p);
+tEplKernel EplSdoUdpuConfig(unsigned long ulIpAddr_p,
+ unsigned int uiPort_p);
-tEplKernel PUBLIC EplSdoUdpuInitCon(tEplSdoConHdl * pSdoConHandle_p,
- unsigned int uiTargetNodeId_p);
+tEplKernel EplSdoUdpuInitCon(tEplSdoConHdl *pSdoConHandle_p,
+ unsigned int uiTargetNodeId_p);
-tEplKernel PUBLIC EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
- tEplFrame * pSrcData_p,
- DWORD dwDataSize_p);
+tEplKernel EplSdoUdpuSendData(tEplSdoConHdl SdoConHandle_p,
+ tEplFrame *pSrcData_p, u32 dwDataSize_p);
-tEplKernel PUBLIC EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
+tEplKernel EplSdoUdpuDelCon(tEplSdoConHdl SdoConHandle_p);
#endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
diff --git a/drivers/staging/epl/user/EplStatusu.h b/drivers/staging/epl/user/EplStatusu.h
index d211935f0e8..0fd3ebb76dc 100644
--- a/drivers/staging/epl/user/EplStatusu.h
+++ b/drivers/staging/epl/user/EplStatusu.h
@@ -68,37 +68,23 @@
****************************************************************************/
-#include "../EplDll.h"
-
#ifndef _EPLSTATUSU_H_
#define _EPLSTATUSU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-typedef tEplKernel(PUBLIC * tEplStatusuCbResponse) (unsigned int uiNodeId_p,
- tEplStatusResponse *
- pStatusResponse_p);
+#include "../EplDll.h"
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+typedef tEplKernel(* tEplStatusuCbResponse) (unsigned int uiNodeId_p,
+ tEplStatusResponse *pStatusResponse_p);
-tEplKernel PUBLIC EplStatusuInit(void);
+tEplKernel EplStatusuInit(void);
-tEplKernel PUBLIC EplStatusuAddInstance(void);
+tEplKernel EplStatusuAddInstance(void);
-tEplKernel PUBLIC EplStatusuDelInstance(void);
+tEplKernel EplStatusuDelInstance(void);
-tEplKernel PUBLIC EplStatusuReset(void);
+tEplKernel EplStatusuReset(void);
-tEplKernel PUBLIC EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
- tEplStatusuCbResponse
- pfnCbResponse_p);
+tEplKernel EplStatusuRequestStatusResponse(unsigned int uiNodeId_p,
+ tEplStatusuCbResponse pfnCbResponse_p);
#endif // #ifndef _EPLSTATUSU_H_
diff --git a/drivers/staging/epl/user/EplTimeru.h b/drivers/staging/epl/user/EplTimeru.h
index 404495501b8..5c447485245 100644
--- a/drivers/staging/epl/user/EplTimeru.h
+++ b/drivers/staging/epl/user/EplTimeru.h
@@ -68,40 +68,28 @@
****************************************************************************/
-#include "../EplTimer.h"
-#include "EplEventu.h"
-
#ifndef _EPLTIMERU_H_
#define _EPLTIMERU_H_
-//---------------------------------------------------------------------------
-// const defines
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// typedef
-//---------------------------------------------------------------------------
-
-//---------------------------------------------------------------------------
-// function prototypes
-//---------------------------------------------------------------------------
+#include "../EplTimer.h"
+#include "EplEventu.h"
-tEplKernel PUBLIC EplTimeruInit(void);
+tEplKernel EplTimeruInit(void);
-tEplKernel PUBLIC EplTimeruAddInstance(void);
+tEplKernel EplTimeruAddInstance(void);
-tEplKernel PUBLIC EplTimeruDelInstance(void);
+tEplKernel EplTimeruDelInstance(void);
-tEplKernel PUBLIC EplTimeruSetTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimeruSetTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimeruModifyTimerMs(tEplTimerHdl * pTimerHdl_p,
- unsigned long ulTime_p,
- tEplTimerArg Argument_p);
+tEplKernel EplTimeruModifyTimerMs(tEplTimerHdl *pTimerHdl_p,
+ unsigned long ulTime_p,
+ tEplTimerArg Argument_p);
-tEplKernel PUBLIC EplTimeruDeleteTimer(tEplTimerHdl * pTimerHdl_p);
+tEplKernel EplTimeruDeleteTimer(tEplTimerHdl *pTimerHdl_p);
-BOOL PUBLIC EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
+BOOL EplTimeruIsTimerActive(tEplTimerHdl TimerHdl_p);
#endif // #ifndef _EPLTIMERU_H_
diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c
index ec98da5da5b..8dc559a77ad 100644
--- a/drivers/staging/et131x/et1310_rx.c
+++ b/drivers/staging/et131x/et1310_rx.c
@@ -1203,8 +1203,7 @@ void et131x_reset_recv(struct et131x_adapter *pAdapter)
pMpRfd = (PMP_RFD) list_entry(element, MP_RFD, list_node);
- list_del(&pMpRfd->list_node);
- list_add_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
+ list_move_tail(&pMpRfd->list_node, &pAdapter->RxRing.RecvList);
}
DBG_LEAVE(et131x_dbginfo);
diff --git a/drivers/staging/frontier/README b/drivers/staging/frontier/README
index 07c9ef9b8fc..cd07af22406 100644
--- a/drivers/staging/frontier/README
+++ b/drivers/staging/frontier/README
@@ -1,28 +1,47 @@
-This directory contains the USB Tranzport and Alphatrack Kernel drivers for Linux.
+This directory contains the Linux USB Tranzport and Alphatrack Kernel drivers.
-At present the tranzport does reads/writes of 8 byte cmds to /dev/tranzport0 to control
-the lights and screen and wheel
+See http://www.frontierdesign.com for details on these devices.
-At present the alphatrack accepts reads/writes of 12 byte cmds to /dev/tranzport0 to control
-the lights and screen and fader.
+Userspace test code is available from
-Both drivers also have some sysfs hooks that are non-functional at the moment.
+git://toutatis.isc.org/home/d/src/git/frontier.git
-The API is currently closely tied to the ardour revision and WILL change.
+At present the tranzport does reads/writes of 8 byte cmds to
+/dev/tranzport0 to control the lights, screen, and wheel.
-A sysfs interface is PERFECT for simple userspace apps to do fun things with the
-lights and screen. It's fairly lousy for handling input events and very lousy
-for watching the state of the shuttle wheel.
+At present the alphatrack accepts reads/writes of 12 byte cmds to
+/dev/tranzport0 to control the lights, screen, fader and touchpad.
-A linux input events interface is great for the input events and shuttle wheel. It's
-theoretically OK on LEDs. A Fader can be mapped to an absolute mouse device.
-But there is no LCD support at all.
+The tranzport driver provides a rudimentary sysfs interface for the status of
+the device and a writable parameter for turning wheel compression on and off.
-In the end this is going to be driven by a midi layer, which handles all those
-cases via a defined API, but - among other things - is slow, doesn't do
-flow control, and is a LOT of extra work. Frankly, I'd like to keep the
+The API is nothing more than the USB commands issued to the device. Why?
+
+The control wheel/fader can generate events far too quickly for
+a typical userspace application to keep up with them via libusb. Input
+needs to be 100% accurate and fast in order for the alphatrack or tranzport
+to be useful.
+
+UIO would be useful except that usb disconnect events need
+to be handled correctly.
+
+A sysfs interface is perfect for simple userspace apps to do fun things with
+the lights and screen. But it's fairly lousy for handling input events and
+very lousy for watching the state of the shuttle wheel.
+
+A linux input events interface is great for the input events and shuttle wheel.
+* It's theoretically OK on LEDs.
+* A fader can be mapped to an absolute mouse device.
+* But there is no LCD support at all, or fader feedback support in that API
+
+So, thus, these stubby drivers exist.
+
+In the end this could be driven by a midi layer, which handles all those
+cases via a well defined API, but - among other things - is slow, doesn't do
+flow control, and is a LOT of extra work, none of which is required at
+the kernel level (probably). Frankly, I'd like to keep the
core driver simple because the only realtime work really required is
the bottom half interrupt handler and the output overlapping.
-Exposing some sort of clean aio api to userspace would be perfect. What that
+Exposing some sort of clean api to userspace would be perfect. What that
API looks like? Gah. beats me.
diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c
index 6136e3f8762..bcba17eae92 100644
--- a/drivers/staging/frontier/alphatrack.c
+++ b/drivers/staging/frontier/alphatrack.c
@@ -41,19 +41,11 @@
#include <linux/mutex.h>
#include <linux/version.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/poll.h>
-#include "surface_sysfs.h"
-
-/* make this work on older kernel versions */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include "frontier_compat.h"
-#endif /* older kernel versions */
-
#include "alphatrack.h"
#define VENDOR_ID 0x165b
@@ -62,19 +54,18 @@
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USB_ALPHATRACK_MINOR_BASE 0
#else
-// FIXME 176 - is another driver's minor - apply for that
-// #define USB_ALPHATRACK_MINOR_BASE 177
+/* FIXME 176 - is another driver's minor - apply for that */
#define USB_ALPHATRACK_MINOR_BASE 176
#endif
/* table of devices that work with this driver */
-static struct usb_device_id usb_alphatrack_table [] = {
- { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
- { } /* Terminating entry */
+static struct usb_device_id usb_alphatrack_table[] = {
+ {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
+ {} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, usb_alphatrack_table);
-MODULE_VERSION("0.40");
+MODULE_VERSION("0.41");
MODULE_AUTHOR("Mike Taht <m@taht.net>");
MODULE_DESCRIPTION("Alphatrack USB Driver");
MODULE_LICENSE("GPL");
@@ -93,18 +84,18 @@ MODULE_SUPPORTED_DEVICE("Frontier Designs Alphatrack Control Surface");
#define ALPHATRACK_USB_TIMEOUT 10
#define OUTPUT_CMD_SIZE 8
#define INPUT_CMD_SIZE 12
+#define ALPHATRACK_DEBUG 0
-
-static int debug = 0;
+static int debug = ALPHATRACK_DEBUG;
/* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+#define dbg_info(dev, format, arg...) do \
+ { if (debug) dev_info(dev , format , ## arg); } while (0)
#define alphatrack_ocmd_info(dev, cmd, format, arg...)
#define alphatrack_icmd_info(dev, cmd, format, arg...)
-
/* Module parameters */
module_param(debug, int, S_IRUGO | S_IWUSR);
@@ -116,14 +107,14 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
static int ring_buffer_size = RING_BUFFER_SIZE;
-module_param(ring_buffer_size, int, S_IRUGO);
+module_param(ring_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size");
/* The write_buffer can one day contain more than one interrupt out transfer.
*/
static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int, S_IRUGO);
+module_param(write_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
/*
@@ -133,55 +124,56 @@ MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
static int min_interrupt_in_interval = ALPHATRACK_USB_TIMEOUT;
module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+MODULE_PARM_DESC(min_interrupt_in_interval,
+ "Minimum interrupt in interval in ms");
static int min_interrupt_out_interval = ALPHATRACK_USB_TIMEOUT;
module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
-
-
+MODULE_PARM_DESC(min_interrupt_out_interval,
+ "Minimum interrupt out interval in ms");
/* Structure to hold all of our device specific stuff */
struct usb_alphatrack {
- struct semaphore sem; /* locks this structure */
- struct usb_interface* intf; /* save off the usb interface pointer */
- int open_count; /* number of times this port has been opened */
-
- struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE]; /* just make c happy */
- struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE]; /* just make c happy */
- unsigned int ring_head;
- unsigned int ring_tail;
-
- wait_queue_head_t read_wait;
- wait_queue_head_t write_wait;
-
- unsigned char* interrupt_in_buffer;
- unsigned char* oldi_buffer;
- struct usb_endpoint_descriptor* interrupt_in_endpoint;
- struct urb* interrupt_in_urb;
- int interrupt_in_interval;
- size_t interrupt_in_endpoint_size;
- int interrupt_in_running;
- int interrupt_in_done;
-
- char* interrupt_out_buffer;
- struct usb_endpoint_descriptor* interrupt_out_endpoint;
- struct urb* interrupt_out_urb;
- int interrupt_out_interval;
- size_t interrupt_out_endpoint_size;
- int interrupt_out_busy;
+ struct semaphore sem; /* locks this structure */
+ struct usb_interface *intf; /* save off the usb interface pointer */
+ int open_count; /* number of times this port has been opened */
+
+ /* make gcc happy */
+ struct alphatrack_icmd (*ring_buffer)[RING_BUFFER_SIZE];
+ struct alphatrack_ocmd (*write_buffer)[WRITE_BUFFER_SIZE];
+ unsigned int ring_head;
+ unsigned int ring_tail;
+
+ wait_queue_head_t read_wait;
+ wait_queue_head_t write_wait;
+
+ unsigned char *interrupt_in_buffer;
+ unsigned char *oldi_buffer;
+ struct usb_endpoint_descriptor *interrupt_in_endpoint;
+ struct urb *interrupt_in_urb;
+ int interrupt_in_interval;
+ size_t interrupt_in_endpoint_size;
+ int interrupt_in_running;
+ int interrupt_in_done;
+
+ char *interrupt_out_buffer;
+ struct usb_endpoint_descriptor *interrupt_out_endpoint;
+ struct urb *interrupt_out_urb;
+ int interrupt_out_interval;
+ size_t interrupt_out_endpoint_size;
+ int interrupt_out_busy;
atomic_t writes_pending;
- int event; /* alternate interface to events */
- int fader; /* 10 bits */
- int lights; /* 23 bits */
- unsigned char dump_state; /* 0 if disabled 1 if enabled */
- unsigned char enable; /* 0 if disabled 1 if enabled */
- unsigned char offline; /* if the device is out of range or asleep */
- unsigned char verbose; /* be verbose in error reporting */
- unsigned char last_cmd[OUTPUT_CMD_SIZE];
- unsigned char screen[32];
+ int event; /* alternate interface to events */
+ int fader; /* 10 bits */
+ int lights; /* 23 bits */
+ unsigned char dump_state; /* 0 if disabled 1 if enabled */
+ unsigned char enable; /* 0 if disabled 1 if enabled */
+ unsigned char offline; /* if the device is out of range or asleep */
+ unsigned char verbose; /* be verbose in error reporting */
+ unsigned char last_cmd[OUTPUT_CMD_SIZE];
+ unsigned char screen[32];
};
/* prevent races between open() and disconnect() */
@@ -219,7 +211,7 @@ static void usb_alphatrack_delete(struct usb_alphatrack *dev)
kfree(dev->ring_buffer);
kfree(dev->interrupt_in_buffer);
kfree(dev->interrupt_out_buffer);
- kfree(dev); // fixme oldi_buffer
+ kfree(dev); /* fixme oldi_buffer */
}
/**
@@ -234,39 +226,52 @@ static void usb_alphatrack_interrupt_in_callback(struct urb *urb)
if (urb->status) {
if (urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN) {
+ urb->status == -ECONNRESET || urb->status == -ESHUTDOWN) {
goto exit;
} else {
- dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
- __func__, urb->status);
- goto resubmit; /* maybe we can recover */
+ dbg_info(&dev->intf->dev,
+ "%s: nonzero status received: %d\n", __func__,
+ urb->status);
+ goto resubmit; /* maybe we can recover */
}
}
if (urb->actual_length != INPUT_CMD_SIZE) {
dev_warn(&dev->intf->dev,
- "Urb length was %d bytes!! Do something intelligent \n", urb->actual_length);
+ "Urb length was %d bytes!!"
+ "Do something intelligent \n", urb->actual_length);
} else {
- alphatrack_ocmd_info(&dev->intf->dev,&(*dev->ring_buffer)[dev->ring_tail].cmd,"%s", "bla");
- if(memcmp(dev->interrupt_in_buffer,dev->oldi_buffer,INPUT_CMD_SIZE)==0) {
- goto resubmit;
+ alphatrack_ocmd_info(&dev->intf->dev,
+ &(*dev->ring_buffer)[dev->ring_tail].cmd,
+ "%s", "bla");
+ if (memcmp
+ (dev->interrupt_in_buffer, dev->oldi_buffer,
+ INPUT_CMD_SIZE) == 0) {
+ goto resubmit;
}
- memcpy(dev->oldi_buffer,dev->interrupt_in_buffer,INPUT_CMD_SIZE);
+ memcpy(dev->oldi_buffer, dev->interrupt_in_buffer,
+ INPUT_CMD_SIZE);
#if SUPPRESS_EXTRA_OFFLINE_EVENTS
- if(dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) { goto resubmit; }
- if(dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; }
+ if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
+ goto resubmit;
+ if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
+ dev->offline = 2;
+ goto resubmit;
+ }
/* Always pass one offline event up the stack */
- if(dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) { dev->offline = 0; }
- if(dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 1; }
+ if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
+ dev->offline = 0;
+ if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
+ dev->offline = 1;
#endif
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
- next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
+ next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
if (next_ring_head != dev->ring_tail) {
memcpy(&((*dev->ring_buffer)[dev->ring_head]),
- dev->interrupt_in_buffer, urb->actual_length);
+ dev->interrupt_in_buffer, urb->actual_length);
dev->ring_head = next_ring_head;
retval = 0;
memset(dev->interrupt_in_buffer, 0, urb->actual_length);
@@ -330,7 +335,7 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
if (!interface) {
err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
+ __func__, subminor);
retval = -ENODEV;
goto unlock_disconnect_exit;
}
@@ -361,11 +366,11 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
usb_fill_int_urb(dev->interrupt_in_urb,
interface_to_usbdev(interface),
usb_rcvintpipe(interface_to_usbdev(interface),
- dev->interrupt_in_endpoint->bEndpointAddress),
+ dev->interrupt_in_endpoint->
+ bEndpointAddress),
dev->interrupt_in_buffer,
dev->interrupt_in_endpoint_size,
- usb_alphatrack_interrupt_in_callback,
- dev,
+ usb_alphatrack_interrupt_in_callback, dev,
dev->interrupt_in_interval);
dev->interrupt_in_running = 1;
@@ -375,7 +380,8 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
if (retval) {
- dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+ dev_err(&interface->dev,
+ "Couldn't submit interrupt_in_urb %d\n", retval);
dev->interrupt_in_running = 0;
dev->open_count = 0;
goto unlock_exit;
@@ -384,7 +390,6 @@ static int usb_alphatrack_open(struct inode *inode, struct file *file)
/* save device in the file's private structure */
file->private_data = dev;
-
unlock_exit:
up(&dev->sem);
@@ -430,7 +435,9 @@ static int usb_alphatrack_release(struct inode *inode, struct file *file)
/* wait until write transfer is finished */
if (dev->interrupt_out_busy)
- wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+ wait_event_interruptible_timeout(dev->write_wait,
+ !dev->interrupt_out_busy,
+ 2 * HZ);
usb_alphatrack_abort_transfers(dev);
dev->open_count = 0;
@@ -444,7 +451,7 @@ exit:
/**
* usb_alphatrack_poll
*/
-static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait)
+static unsigned int usb_alphatrack_poll(struct file *file, poll_table * wait)
{
struct usb_alphatrack *dev;
unsigned int mask = 0;
@@ -465,8 +472,8 @@ static unsigned int usb_alphatrack_poll(struct file *file, poll_table *wait)
/**
* usb_alphatrack_read
*/
-static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, size_t count,
- loff_t *ppos)
+static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct usb_alphatrack *dev;
int retval = 0;
@@ -493,30 +500,36 @@ static ssize_t usb_alphatrack_read(struct file *file, char __user *buffer, size_
}
while (dev->ring_head == dev->ring_tail) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- goto unlock_exit;
- }
- dev->interrupt_in_done = 0 ;
- retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
- if (retval < 0) {
- goto unlock_exit;
- }
- }
-
- alphatrack_ocmd_info(&dev->intf->dev, &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s", ": copying to userspace");
-
- c = 0;
- while((c < count) && (dev->ring_tail != dev->ring_head)) {
- if (copy_to_user(&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], INPUT_CMD_SIZE)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
- c+=INPUT_CMD_SIZE;
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
- }
- retval = c;
+ if (file->f_flags & O_NONBLOCK) {
+ retval = -EAGAIN;
+ goto unlock_exit;
+ }
+ dev->interrupt_in_done = 0;
+ retval =
+ wait_event_interruptible(dev->read_wait,
+ dev->interrupt_in_done);
+ if (retval < 0)
+ goto unlock_exit;
+ }
+
+ alphatrack_ocmd_info(&dev->intf->dev,
+ &(*dev->ring_buffer)[dev->ring_tail].cmd, "%s",
+ ": copying to userspace");
+
+ c = 0;
+ while ((c < count) && (dev->ring_tail != dev->ring_head)) {
+ if (copy_to_user
+ (&buffer[c], &(*dev->ring_buffer)[dev->ring_tail],
+ INPUT_CMD_SIZE)) {
+ retval = -EFAULT;
+ goto unlock_exit;
+ }
+ dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+ c += INPUT_CMD_SIZE;
+ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
+ }
+ retval = c;
unlock_exit:
/* unlock the device */
@@ -529,8 +542,9 @@ exit:
/**
* usb_alphatrack_write
*/
-static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+static ssize_t usb_alphatrack_write(struct file *file,
+ const char __user *buffer, size_t count,
+ loff_t *ppos)
{
struct usb_alphatrack *dev;
size_t bytes_to_write;
@@ -561,19 +575,24 @@ static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer
retval = -EAGAIN;
goto unlock_exit;
}
- retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
- if (retval < 0) {
+ retval =
+ wait_event_interruptible(dev->write_wait,
+ !dev->interrupt_out_busy);
+ if (retval < 0)
goto unlock_exit;
- }
}
/* write the data into interrupt_out_buffer from userspace */
- /* FIXME - if you write more than 12 bytes this breaks */
- bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+ /* FIXME - if you write more than 12 bytes this breaks */
+ bytes_to_write =
+ min(count, write_buffer_size * dev->interrupt_out_endpoint_size);
if (bytes_to_write < count)
- dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+ dev_warn(&dev->intf->dev,
+ "Write buffer overflow, %zd bytes dropped\n",
+ count - bytes_to_write);
- dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);
+ dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n",
+ __func__, count, bytes_to_write);
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
retval = -EFAULT;
@@ -589,11 +608,10 @@ static ssize_t usb_alphatrack_write(struct file *file, const char __user *buffer
usb_fill_int_urb(dev->interrupt_out_urb,
interface_to_usbdev(dev->intf),
usb_sndintpipe(interface_to_usbdev(dev->intf),
- dev->interrupt_out_endpoint->bEndpointAddress),
- dev->interrupt_out_buffer,
- bytes_to_write,
- usb_alphatrack_interrupt_out_callback,
- dev,
+ dev->interrupt_out_endpoint->
+ bEndpointAddress),
+ dev->interrupt_out_buffer, bytes_to_write,
+ usb_alphatrack_interrupt_out_callback, dev,
dev->interrupt_out_interval);
dev->interrupt_out_busy = 1;
atomic_inc(&dev->writes_pending);
@@ -618,12 +636,12 @@ exit:
/* file operations needed when we register this driver */
static const struct file_operations usb_alphatrack_fops = {
- .owner = THIS_MODULE,
- .read = usb_alphatrack_read,
- .write = usb_alphatrack_write,
- .open = usb_alphatrack_open,
- .release = usb_alphatrack_release,
- .poll = usb_alphatrack_poll,
+ .owner = THIS_MODULE,
+ .read = usb_alphatrack_read,
+ .write = usb_alphatrack_write,
+ .open = usb_alphatrack_open,
+ .release = usb_alphatrack_release,
+ .poll = usb_alphatrack_poll,
};
/*
@@ -632,19 +650,19 @@ static const struct file_operations usb_alphatrack_fops = {
*/
static struct usb_class_driver usb_alphatrack_class = {
- .name = "alphatrack%d",
- .fops = &usb_alphatrack_fops,
- .minor_base = USB_ALPHATRACK_MINOR_BASE,
+ .name = "alphatrack%d",
+ .fops = &usb_alphatrack_fops,
+ .minor_base = USB_ALPHATRACK_MINOR_BASE,
};
-
/**
* usb_alphatrack_probe
*
* Called by the usb core when a new device is connected that it thinks
* this driver might be interested in.
*/
-static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_device_id *id)
+static int usb_alphatrack_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_alphatrack *dev = NULL;
@@ -683,28 +701,35 @@ static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_dev
goto error;
}
if (dev->interrupt_out_endpoint == NULL)
- dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint not found"
+ "(using control endpoint instead)\n");
- dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+ dev->interrupt_in_endpoint_size =
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
if (dev->interrupt_in_endpoint_size != 64)
- dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
-
- if(ring_buffer_size == 0) { ring_buffer_size = RING_BUFFER_SIZE; }
+ dev_warn(&intf->dev, "Interrupt in endpoint size is not 64!\n");
- true_size = min(ring_buffer_size,RING_BUFFER_SIZE);
+ if (ring_buffer_size == 0)
+ ring_buffer_size = RING_BUFFER_SIZE;
- /* FIXME - there are more usb_alloc routines for dma correctness. Needed? */
+ true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
-// dev->ring_buffer = kmalloc((true_size*sizeof(struct alphatrack_icmd))+12, GFP_KERNEL);
- dev->ring_buffer = kmalloc((true_size*sizeof(struct alphatrack_icmd)), GFP_KERNEL);
+ /* FIXME - there are more usb_alloc routines for dma correctness.
+ Needed? */
+ dev->ring_buffer =
+ kmalloc((true_size * sizeof(struct alphatrack_icmd)), GFP_KERNEL);
if (!dev->ring_buffer) {
- dev_err(&intf->dev, "Couldn't allocate input ring_buffer of size %d\n",true_size);
+ dev_err(&intf->dev,
+ "Couldn't allocate input ring_buffer of size %d\n",
+ true_size);
goto error;
}
- dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+ dev->interrupt_in_buffer =
+ kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
@@ -721,23 +746,30 @@ static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_dev
goto error;
}
- dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
- udev->descriptor.bMaxPacketSize0;
+ dev->interrupt_out_endpoint_size =
+ dev->interrupt_out_endpoint ? le16_to_cpu(dev->
+ interrupt_out_endpoint->
+ wMaxPacketSize) : udev->
+ descriptor.bMaxPacketSize0;
- if (dev->interrupt_out_endpoint_size !=64)
- dev_warn(&intf->dev, "Interrupt out endpoint size is not 64!)\n");
+ if (dev->interrupt_out_endpoint_size != 64)
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint size is not 64!)\n");
- if(write_buffer_size == 0) { write_buffer_size = WRITE_BUFFER_SIZE; }
- true_size = min(write_buffer_size,WRITE_BUFFER_SIZE);
+ if (write_buffer_size == 0)
+ write_buffer_size = WRITE_BUFFER_SIZE;
+ true_size = min(write_buffer_size, WRITE_BUFFER_SIZE);
- dev->interrupt_out_buffer = kmalloc(true_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+ dev->interrupt_out_buffer =
+ kmalloc(true_size * dev->interrupt_out_endpoint_size, GFP_KERNEL);
if (!dev->interrupt_out_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
goto error;
}
- dev->write_buffer = kmalloc(sizeof(struct alphatrack_ocmd)*true_size, GFP_KERNEL);
+ dev->write_buffer =
+ kmalloc(sizeof(struct alphatrack_ocmd) * true_size, GFP_KERNEL);
if (!dev->write_buffer) {
dev_err(&intf->dev, "Couldn't allocate write_buffer \n");
@@ -749,25 +781,36 @@ static int usb_alphatrack_probe(struct usb_interface *intf, const struct usb_dev
dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
goto error;
}
- dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
+ dev->interrupt_in_interval =
+ min_interrupt_in_interval >
+ dev->interrupt_in_endpoint->
+ bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->
+ bInterval;
if (dev->interrupt_out_endpoint)
- dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+ dev->interrupt_out_interval =
+ min_interrupt_out_interval >
+ dev->interrupt_out_endpoint->
+ bInterval ? min_interrupt_out_interval : dev->
+ interrupt_out_endpoint->bInterval;
/* we can register the device now, as it is ready */
usb_set_intfdata(intf, dev);
- atomic_set(&dev->writes_pending,0);
+ atomic_set(&dev->writes_pending, 0);
retval = usb_register_dev(intf, &usb_alphatrack_class);
if (retval) {
/* something prevented us from registering this driver */
- dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+ dev_err(&intf->dev,
+ "Not able to get a minor for this device.\n");
usb_set_intfdata(intf, NULL);
goto error;
}
/* let the user know what node this device is now attached to */
- dev_info(&intf->dev, "Alphatrack Device #%d now attached to major %d minor %d\n",
- (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR, intf->minor);
+ dev_info(&intf->dev,
+ "Alphatrack Device #%d now attached to major %d minor %d\n",
+ (intf->minor - USB_ALPHATRACK_MINOR_BASE), USB_MAJOR,
+ intf->minor);
exit:
return retval;
@@ -809,7 +852,7 @@ static void usb_alphatrack_disconnect(struct usb_interface *intf)
up(&dev->sem);
}
- atomic_set(&dev->writes_pending,0);
+ atomic_set(&dev->writes_pending, 0);
mutex_unlock(&disconnect_mutex);
dev_info(&intf->dev, "Alphatrack Surface #%d now disconnected\n",
@@ -818,10 +861,10 @@ static void usb_alphatrack_disconnect(struct usb_interface *intf)
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver usb_alphatrack_driver = {
- .name = "alphatrack",
- .probe = usb_alphatrack_probe,
- .disconnect = usb_alphatrack_disconnect,
- .id_table = usb_alphatrack_table,
+ .name = "alphatrack",
+ .probe = usb_alphatrack_probe,
+ .disconnect = usb_alphatrack_disconnect,
+ .id_table = usb_alphatrack_table,
};
/**
@@ -834,7 +877,8 @@ static int __init usb_alphatrack_init(void)
/* register this driver with the USB subsystem */
retval = usb_register(&usb_alphatrack_driver);
if (retval)
- err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
+ err("usb_register failed for the " __FILE__
+ " driver. Error number %d\n", retval);
return retval;
}
@@ -850,4 +894,3 @@ static void __exit usb_alphatrack_exit(void)
module_init(usb_alphatrack_init);
module_exit(usb_alphatrack_exit);
-
diff --git a/drivers/staging/frontier/alphatrack.h b/drivers/staging/frontier/alphatrack.h
index 35c90a90eb0..10a79726359 100644
--- a/drivers/staging/frontier/alphatrack.h
+++ b/drivers/staging/frontier/alphatrack.h
@@ -1,42 +1,38 @@
-#define show_set_bit(a) show_set_mbit(alphatrack,a)
-#define show_set_cmd(a) show_set_mcmd(alphatrack,a)
-#define show_set_int(a) show_set_mint(alphatrack,a)
-#define show_set_char(a) show_set_mchar(alphatrack,a)
-#define show_set_light(a) show_set_ebit(alphatrack,LightID,lights,a)
-#define show_set_button(a) show_set_ebit(alphatrack,ButtonID,button,a)
-
struct alphatrack_icmd {
- unsigned char cmd[12];
+ unsigned char cmd[12];
};
struct alphatrack_ocmd {
- unsigned char cmd[8];
+ unsigned char cmd[8];
};
+/* These are unused by the present driver but provide documentation for the
+ * userspace API.
+ */
enum LightID {
- LIGHT_EQ = 0,
- LIGHT_OUT,
- LIGHT_F2,
- LIGHT_SEND,
- LIGHT_IN,
- LIGHT_F1,
- LIGHT_PAN,
- LIGHT_UNDEF1,
- LIGHT_UNDEF2,
- LIGHT_SHIFT,
- LIGHT_TRACKMUTE,
- LIGHT_TRACKSOLO,
- LIGHT_TRACKREC,
- LIGHT_READ,
- LIGHT_WRITE,
- LIGHT_ANYSOLO,
- LIGHT_AUTO,
- LIGHT_F4,
- LIGHT_RECORD,
- LIGHT_WINDOW,
- LIGHT_PLUGIN,
- LIGHT_F3,
- LIGHT_LOOP
+ LIGHT_EQ = 0,
+ LIGHT_OUT,
+ LIGHT_F2,
+ LIGHT_SEND,
+ LIGHT_IN,
+ LIGHT_F1,
+ LIGHT_PAN,
+ LIGHT_UNDEF1,
+ LIGHT_UNDEF2,
+ LIGHT_SHIFT,
+ LIGHT_TRACKMUTE,
+ LIGHT_TRACKSOLO,
+ LIGHT_TRACKREC,
+ LIGHT_READ,
+ LIGHT_WRITE,
+ LIGHT_ANYSOLO,
+ LIGHT_AUTO,
+ LIGHT_F4,
+ LIGHT_RECORD,
+ LIGHT_WINDOW,
+ LIGHT_PLUGIN,
+ LIGHT_F3,
+ LIGHT_LOOP
};
#define BUTTONMASK_BATTERY 0x00004000
@@ -62,8 +58,9 @@ enum LightID {
#define BUTTONMASK_PRESS2 0x00008010
#define BUTTONMASK_PRESS3 0x00002020
-// last 3 bytes are the slider position
-// 40 is the actual slider moving, the most sig bits, and 3 lsb
+/* last 3 bytes are the slider position
+ * 40 is the actual slider moving, the most sig bits, and 3 lsb
+ */
#define BUTTONMASK_FLIP 0x40000000
#define BUTTONMASK_F1 0x00100000
@@ -76,17 +73,4 @@ enum LightID {
#define BUTTONMASK_PLUGIN 0x00000400
#define BUTTONMASK_AUTO 0x00000100
-
-// #define BUTTONMASK_FOOTSWITCH FIXME
-
-// Lookup. name. midi out. midi in.
-
-struct buttonmap_t {
- u32 mask;
- short midi_in;
- short midi_out;
- char *name;
-// void (*function) (buttonmap_t *);
- void (*function) (void);
-};
-
+/* #define BUTTONMASK_FOOTSWITCH FIXME */
diff --git a/drivers/staging/frontier/frontier_compat.h b/drivers/staging/frontier/frontier_compat.h
deleted file mode 100644
index 00450e637ac..00000000000
--- a/drivers/staging/frontier/frontier_compat.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* USB defines for older kernels */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-
-/**
- * usb_endpoint_dir_out - check if the endpoint has OUT direction
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type OUT, otherwise it returns false.
- */
-
-static inline int usb_endpoint_dir_out(const struct usb_endpoint_descriptor *epd)
-{
- return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT);
-}
-
-static inline int usb_endpoint_dir_in(const struct usb_endpoint_descriptor *epd)
-{
- return ((epd->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN);
-}
-
-
-/**
- * usb_endpoint_xfer_int - check if the endpoint has interrupt transfer type
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint is of type interrupt, otherwise it returns
- * false.
- */
-static inline int usb_endpoint_xfer_int(const struct usb_endpoint_descriptor *epd)
-{
- return ((epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_INT);
-}
-
-
-/**
- * usb_endpoint_is_int_in - check if the endpoint is interrupt IN
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and IN direction,
- * otherwise it returns false.
- */
-
-static inline int usb_endpoint_is_int_in(const struct usb_endpoint_descriptor *epd)
-{
- return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_in(epd));
-}
-
-/**
- * usb_endpoint_is_int_out - check if the endpoint is interrupt OUT
- * @epd: endpoint to be checked
- *
- * Returns true if the endpoint has interrupt transfer type and OUT direction,
- * otherwise it returns false.
- */
-
-static inline int usb_endpoint_is_int_out(const struct usb_endpoint_descriptor *epd)
-{
- return (usb_endpoint_xfer_int(epd) && usb_endpoint_dir_out(epd));
-}
-
-#endif /* older kernel versions */
diff --git a/drivers/staging/frontier/surface_sysfs.h b/drivers/staging/frontier/surface_sysfs.h
deleted file mode 100644
index d50a562d658..00000000000
--- a/drivers/staging/frontier/surface_sysfs.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/* If you are going to abuse the preprocessor, why not ABUSE the preprocessor?
- I stuck this header in a separate file so I don't have to look at it */
-
-// FIXME Need locking or atomic ops
-
-#define show_set_mbit(dname,value,bit) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = (1 && (t->value & (1 << bit))); \
- return sprintf(buf, "%d\n", temp); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- if(temp > 0) { long b = 1 << bit; t->value |= b; } \
- else { long b = ~(1 << bit); t->value &= b ; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_ebit(dname,enumname,value,bit) \
-static ssize_t show_##bit(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- enum enumname l = bit; \
- int temp = t->value & (1 << l); \
- return sprintf(buf, "%d\n", temp); \
-} \
-static ssize_t set_##bit(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- enum enumname l = bit;\
- long b = 1 << l; \
- if(temp > 0) { t->value |= b; } \
- else { t->value &= ~b ; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-// FIXME FOR CORRECTLY SETTING HEX from a string
-#define show_set_mcmd(dname,value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int count = 0;\
- int i; \
- for (i = 0,i<sizeof(dname); i++) count += snprintf(buf, "%02x",t->dname[i]); \
- return(count);\
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_mint(dname,value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- return sprintf(buf, "%d\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-#define show_set_mchar(dname,value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- return sprintf(buf, "%c\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_##dname *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
diff --git a/drivers/staging/frontier/tranzport.c b/drivers/staging/frontier/tranzport.c
index 79abb6b16f7..274b82bd786 100644
--- a/drivers/staging/frontier/tranzport.c
+++ b/drivers/staging/frontier/tranzport.c
@@ -18,7 +18,7 @@
*
*/
-/**
+/*
* This driver uses a ring buffer for time critical reading of
* interrupt in reports and provides read and write methods for
* raw interrupt reports.
@@ -30,7 +30,7 @@
* as we only have 17 commands for the tranzport. In particular this is
* key for getting lights to flash in time as otherwise many commands
* can be buffered up before the light change makes it to the interface.
-*/
+ */
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -40,56 +40,47 @@
#include <linux/mutex.h>
#include <linux/version.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/input.h>
#include <linux/usb.h>
#include <linux/poll.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
-#include frontier_compat.h
-#endif
-
/* Define these values to match your devices */
#define VENDOR_ID 0x165b
-#define PRODUCT_ID 0x8101
+#define PRODUCT_ID 0x8101
#ifdef CONFIG_USB_DYNAMIC_MINORS
#define USB_TRANZPORT_MINOR_BASE 0
-#else
-// FIXME 176 - is the ldusb driver's minor - apply for a minor soon
+#else /* FIXME 177- is the another driver's minor - apply for a minor soon */
#define USB_TRANZPORT_MINOR_BASE 177
#endif
/* table of devices that work with this driver */
-static struct usb_device_id usb_tranzport_table [] = {
- { USB_DEVICE(VENDOR_ID, PRODUCT_ID) },
- { } /* Terminating entry */
+static struct usb_device_id usb_tranzport_table[] = {
+ {USB_DEVICE(VENDOR_ID, PRODUCT_ID)},
+ {} /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, usb_tranzport_table);
-MODULE_VERSION("0.33");
+MODULE_VERSION("0.35");
MODULE_AUTHOR("Mike Taht <m@taht.net>");
MODULE_DESCRIPTION("Tranzport USB Driver");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("Frontier Designs Tranzport Control Surface");
-/* These two aren't done yet */
-
-#define SUPPRESS_EXTRA_ONLINE_EVENTS 0
-#define BUFFERED_WRITES 0
-
#define SUPPRESS_EXTRA_OFFLINE_EVENTS 1
#define COMPRESS_WHEEL_EVENTS 1
#define BUFFERED_READS 1
#define RING_BUFFER_SIZE 1000
#define WRITE_BUFFER_SIZE 34
#define TRANZPORT_USB_TIMEOUT 10
+#define TRANZPORT_DEBUG 0
-
-static int debug = 0;
+static int debug = TRANZPORT_DEBUG;
/* Use our own dbg macro */
-#define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0)
+#define dbg_info(dev, format, arg...) do \
+ { if (debug) dev_info(dev , format , ## arg); } while (0)
/* Module parameters */
@@ -102,13 +93,13 @@ MODULE_PARM_DESC(debug, "Debug enabled or not");
static int ring_buffer_size = RING_BUFFER_SIZE;
-module_param(ring_buffer_size, int, S_IRUGO);
+module_param(ring_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports");
/* The write_buffer can one day contain more than one interrupt out transfer.
*/
static int write_buffer_size = WRITE_BUFFER_SIZE;
-module_param(write_buffer_size, int, S_IRUGO);
+module_param(write_buffer_size, int, S_IRUGO);
MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
/*
@@ -118,69 +109,48 @@ MODULE_PARM_DESC(write_buffer_size, "Write buffer size");
static int min_interrupt_in_interval = TRANZPORT_USB_TIMEOUT;
module_param(min_interrupt_in_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms");
+MODULE_PARM_DESC(min_interrupt_in_interval,
+ "Minimum interrupt in interval in ms");
static int min_interrupt_out_interval = TRANZPORT_USB_TIMEOUT;
module_param(min_interrupt_out_interval, int, 0);
-MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms");
+MODULE_PARM_DESC(min_interrupt_out_interval,
+ "Minimum interrupt out interval in ms");
struct tranzport_cmd {
- unsigned char cmd[8];
+ unsigned char cmd[8];
};
-enum LightID {
- LightRecord = 0,
- LightTrackrec,
- LightTrackmute,
- LightTracksolo,
- LightAnysolo,
- LightLoop,
- LightPunch
- };
-
/* Structure to hold all of our device specific stuff */
struct usb_tranzport {
- struct semaphore sem; /* locks this structure */
- struct usb_interface* intf; /* save off the usb interface pointer */
-
- int open_count; /* number of times this port has been opened */
-
- struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE]; /* just make c happy */
- unsigned int ring_head;
- unsigned int ring_tail;
-
- wait_queue_head_t read_wait;
- wait_queue_head_t write_wait;
-
- unsigned char* interrupt_in_buffer;
- struct usb_endpoint_descriptor* interrupt_in_endpoint;
- struct urb* interrupt_in_urb;
- int interrupt_in_interval;
- size_t interrupt_in_endpoint_size;
- int interrupt_in_running;
- int interrupt_in_done;
-
- char* interrupt_out_buffer;
- struct usb_endpoint_descriptor* interrupt_out_endpoint;
- struct urb* interrupt_out_urb;
- int interrupt_out_interval;
- size_t interrupt_out_endpoint_size;
- int interrupt_out_busy;
-
- /* Sysfs and translation support */
-
- int event; /* alternate interface to events */
- int wheel; /* - for negative, 0 for none, + for positive */
- unsigned char dump_state; /* 0 if disabled 1 if enabled */
- unsigned char enable; /* 0 if disabled 1 if enabled */
- unsigned char offline; /* if the device is out of range or asleep */
- unsigned char compress_wheel; /* flag to compress wheel events */
- unsigned char light; /* 7 bits used */
- unsigned char last_cmd[8];
- unsigned char last_input[8];
- unsigned char screen[40]; // We'll also have cells
-
+ struct semaphore sem; /* locks this structure */
+ struct usb_interface *intf; /* save off the usb interface pointer */
+ int open_count; /* number of times this port opened */
+ struct tranzport_cmd (*ring_buffer)[RING_BUFFER_SIZE];
+ unsigned int ring_head;
+ unsigned int ring_tail;
+ wait_queue_head_t read_wait;
+ wait_queue_head_t write_wait;
+ unsigned char *interrupt_in_buffer;
+ struct usb_endpoint_descriptor *interrupt_in_endpoint;
+ struct urb *interrupt_in_urb;
+ int interrupt_in_interval;
+ size_t interrupt_in_endpoint_size;
+ int interrupt_in_running;
+ int interrupt_in_done;
+ char *interrupt_out_buffer;
+ struct usb_endpoint_descriptor *interrupt_out_endpoint;
+ struct urb *interrupt_out_urb;
+ int interrupt_out_interval;
+ size_t interrupt_out_endpoint_size;
+ int interrupt_out_busy;
+
+ /* Sysfs support */
+
+ unsigned char enable; /* 0 if disabled 1 if enabled */
+ unsigned char offline; /* if the device is out of range or asleep */
+ unsigned char compress_wheel; /* flag to compress wheel events */
};
/* prevent races between open() and disconnect() */
@@ -205,84 +175,39 @@ static void usb_tranzport_abort_transfers(struct usb_tranzport *dev)
usb_kill_urb(dev->interrupt_out_urb);
}
-// FIXME ~light not good enough or correct - need atomic set_bit
-
-#define show_set_light(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- enum LightID light = value; \
- int temp = (1 && (t->light & (1 << light))); \
- return sprintf(buf, "%d\n", temp ); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- enum LightID light = (temp << value) & (t->light << value); \
- t->light = (t->light & ~light) ; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-show_set_light(LightRecord);
-show_set_light(LightTrackrec);
-show_set_light(LightTrackmute);
-show_set_light(LightTracksolo);
-show_set_light(LightAnysolo);
-show_set_light(LightLoop);
-show_set_light(LightPunch);
-
-
-#define show_set_int(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- \
- return sprintf(buf, "%d\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-show_set_int(enable);
-show_set_int(offline);
+#define show_int(value) \
+ static ssize_t show_##value(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+ { \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_tranzport *t = usb_get_intfdata(intf); \
+ return sprintf(buf, "%d\n", t->value); \
+ } \
+ static DEVICE_ATTR(value, S_IRUGO, show_##value, NULL);
+
+#define show_set_int(value) \
+ static ssize_t show_##value(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+ { \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_tranzport *t = usb_get_intfdata(intf); \
+ return sprintf(buf, "%d\n", t->value); \
+ } \
+ static ssize_t set_##value(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ struct usb_interface *intf = to_usb_interface(dev); \
+ struct usb_tranzport *t = usb_get_intfdata(intf); \
+ int temp = simple_strtoul(buf, NULL, 10); \
+ t->value = temp; \
+ return count; \
+ } \
+ static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
+
+show_int(enable);
+show_int(offline);
show_set_int(compress_wheel);
-show_set_int(dump_state);
-show_set_int(wheel);
-show_set_int(event);
-
-#define show_set_cmd(value) \
-static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- \
- return sprintf(buf, "%d\n", t->value); \
-} \
-static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \
-{ \
- struct usb_interface *intf = to_usb_interface(dev); \
- struct usb_tranzport *t = usb_get_intfdata(intf); \
- int temp = simple_strtoul(buf, NULL, 10); \
- \
- t->value = temp; \
- return count; \
-} \
-static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
-
-
-
/**
* usb_tranzport_delete
@@ -290,23 +215,10 @@ static DEVICE_ATTR(value, S_IWUGO | S_IRUGO, show_##value, set_##value);
static void usb_tranzport_delete(struct usb_tranzport *dev)
{
usb_tranzport_abort_transfers(dev);
- /* This is just too twisted to be correct */
- if(dev->intf != NULL) {
- device_remove_file(&dev->intf->dev, &dev_attr_LightRecord);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTrackrec);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTrackmute);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTracksolo);
- device_remove_file(&dev->intf->dev, &dev_attr_LightTrackmute);
- device_remove_file(&dev->intf->dev, &dev_attr_LightAnysolo);
- device_remove_file(&dev->intf->dev, &dev_attr_LightLoop);
- device_remove_file(&dev->intf->dev, &dev_attr_LightPunch);
- device_remove_file(&dev->intf->dev, &dev_attr_wheel);
- device_remove_file(&dev->intf->dev, &dev_attr_enable);
- device_remove_file(&dev->intf->dev, &dev_attr_event);
- device_remove_file(&dev->intf->dev, &dev_attr_offline);
- device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
-
- device_remove_file(&dev->intf->dev, &dev_attr_dump_state);
+ if (dev->intf != NULL) {
+ device_remove_file(&dev->intf->dev, &dev_attr_enable);
+ device_remove_file(&dev->intf->dev, &dev_attr_offline);
+ device_remove_file(&dev->intf->dev, &dev_attr_compress_wheel);
}
/* free data structures */
@@ -330,37 +242,56 @@ static void usb_tranzport_interrupt_in_callback(struct urb *urb)
if (urb->status) {
if (urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN) {
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN) {
goto exit;
} else {
- dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n",
+ dbg_info(&dev->intf->dev,
+ "%s: nonzero status received: %d\n",
__func__, urb->status);
- goto resubmit; /* maybe we can recover */
+ goto resubmit; /* maybe we can recover */
}
}
if (urb->actual_length != 8) {
dev_warn(&dev->intf->dev,
- "Urb length was %d bytes!! Do something intelligent \n", urb->actual_length);
+ "Urb length was %d bytes!!"
+ "Do something intelligent \n",
+ urb->actual_length);
} else {
- dbg_info(&dev->intf->dev, "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__, dev->interrupt_in_buffer[0],dev->interrupt_in_buffer[1],dev->interrupt_in_buffer[2],dev->interrupt_in_buffer[3],dev->interrupt_in_buffer[4],dev->interrupt_in_buffer[5],dev->interrupt_in_buffer[6],dev->interrupt_in_buffer[7]);
+ dbg_info(&dev->intf->dev,
+ "%s: received: %02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__, dev->interrupt_in_buffer[0],
+ dev->interrupt_in_buffer[1],
+ dev->interrupt_in_buffer[2],
+ dev->interrupt_in_buffer[3],
+ dev->interrupt_in_buffer[4],
+ dev->interrupt_in_buffer[5],
+ dev->interrupt_in_buffer[6],
+ dev->interrupt_in_buffer[7]);
#if SUPPRESS_EXTRA_OFFLINE_EVENTS
- if(dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff) { goto resubmit; }
- if(dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 2; goto resubmit; }
+ if (dev->offline == 2 && dev->interrupt_in_buffer[1] == 0xff)
+ goto resubmit;
+ if (dev->offline == 1 && dev->interrupt_in_buffer[1] == 0xff) {
+ dev->offline = 2;
+ goto resubmit;
+ }
-/* Always pass one offline event up the stack */
- if(dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff) { dev->offline = 0; }
- if(dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff) { dev->offline = 1; }
+ /* Always pass one offline event up the stack */
+ if (dev->offline > 0 && dev->interrupt_in_buffer[1] != 0xff)
+ dev->offline = 0;
+ if (dev->offline == 0 && dev->interrupt_in_buffer[1] == 0xff)
+ dev->offline = 1;
-#endif
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
+#endif /* SUPPRESS_EXTRA_OFFLINE_EVENTS */
+ dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
- next_ring_head = (dev->ring_head+1) % ring_buffer_size;
+ next_ring_head = (dev->ring_head + 1) % ring_buffer_size;
if (next_ring_head != dev->ring_tail) {
- memcpy(&((*dev->ring_buffer)[dev->ring_head]), dev->interrupt_in_buffer, urb->actual_length);
+ memcpy(&((*dev->ring_buffer)[dev->ring_head]),
+ dev->interrupt_in_buffer, urb->actual_length);
dev->ring_head = next_ring_head;
retval = 0;
memset(dev->interrupt_in_buffer, 0, urb->actual_length);
@@ -373,7 +304,7 @@ static void usb_tranzport_interrupt_in_callback(struct urb *urb)
}
resubmit:
- /* resubmit if we're still running */
+/* resubmit if we're still running */
if (dev->interrupt_in_running && dev->intf) {
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC);
if (retval)
@@ -392,19 +323,17 @@ exit:
static void usb_tranzport_interrupt_out_callback(struct urb *urb)
{
struct usb_tranzport *dev = urb->context;
-
/* sync/async unlink faults aren't errors */
if (urb->status && !(urb->status == -ENOENT ||
- urb->status == -ECONNRESET ||
- urb->status == -ESHUTDOWN))
+ urb->status == -ECONNRESET ||
+ urb->status == -ESHUTDOWN))
dbg_info(&dev->intf->dev,
- "%s - nonzero write interrupt status received: %d\n",
- __func__, urb->status);
+ "%s - nonzero write interrupt status received: %d\n",
+ __func__, urb->status);
dev->interrupt_out_busy = 0;
wake_up_interruptible(&dev->write_wait);
}
-
/**
* usb_tranzport_open
*/
@@ -424,7 +353,7 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
if (!interface) {
err("%s - error, can't find device for minor %d\n",
- __func__, subminor);
+ __func__, subminor);
retval = -ENODEV;
goto unlock_disconnect_exit;
}
@@ -453,14 +382,14 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
dev->ring_head = 0;
dev->ring_tail = 0;
usb_fill_int_urb(dev->interrupt_in_urb,
- interface_to_usbdev(interface),
- usb_rcvintpipe(interface_to_usbdev(interface),
- dev->interrupt_in_endpoint->bEndpointAddress),
- dev->interrupt_in_buffer,
- dev->interrupt_in_endpoint_size,
- usb_tranzport_interrupt_in_callback,
- dev,
- dev->interrupt_in_interval);
+ interface_to_usbdev(interface),
+ usb_rcvintpipe(interface_to_usbdev(interface),
+ dev->interrupt_in_endpoint->
+ bEndpointAddress),
+ dev->interrupt_in_buffer,
+ dev->interrupt_in_endpoint_size,
+ usb_tranzport_interrupt_in_callback, dev,
+ dev->interrupt_in_interval);
dev->interrupt_in_running = 1;
dev->interrupt_in_done = 0;
@@ -470,7 +399,8 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL);
if (retval) {
- dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval);
+ dev_err(&interface->dev,
+ "Couldn't submit interrupt_in_urb %d\n", retval);
dev->interrupt_in_running = 0;
dev->open_count = 0;
goto unlock_exit;
@@ -479,7 +409,6 @@ static int usb_tranzport_open(struct inode *inode, struct file *file)
/* save device in the file's private structure */
file->private_data = dev;
-
unlock_exit:
up(&dev->sem);
@@ -525,7 +454,9 @@ static int usb_tranzport_release(struct inode *inode, struct file *file)
/* wait until write transfer is finished */
if (dev->interrupt_out_busy)
- wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ);
+ wait_event_interruptible_timeout(dev->write_wait,
+ !dev->interrupt_out_busy,
+ 2 * HZ);
usb_tranzport_abort_transfers(dev);
dev->open_count = 0;
@@ -539,37 +470,31 @@ exit:
/**
* usb_tranzport_poll
*/
-static unsigned int usb_tranzport_poll(struct file *file, poll_table *wait)
+static unsigned int usb_tranzport_poll(struct file *file, poll_table * wait)
{
struct usb_tranzport *dev;
unsigned int mask = 0;
-
dev = file->private_data;
-
poll_wait(file, &dev->read_wait, wait);
poll_wait(file, &dev->write_wait, wait);
-
if (dev->ring_head != dev->ring_tail)
mask |= POLLIN | POLLRDNORM;
if (!dev->interrupt_out_busy)
mask |= POLLOUT | POLLWRNORM;
-
return mask;
}
-
/**
* usb_tranzport_read
*/
-static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t count,
- loff_t *ppos)
+
+static ssize_t usb_tranzport_read(struct file *file, char __user *buffer,
+ size_t count, loff_t *ppos)
{
struct usb_tranzport *dev;
int retval = 0;
-
#if BUFFERED_READS
int c = 0;
#endif
-
#if COMPRESS_WHEEL_EVENTS
signed char oldwheel;
signed char newwheel;
@@ -577,7 +502,7 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t
int next_tail;
#endif
-/* do I have such a thing as a null event? */
+ /* do I have such a thing as a null event? */
dev = file->private_data;
@@ -591,8 +516,7 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t
goto exit;
}
- /* verify that the device wasn't unplugged */
- if (dev->intf == NULL) {
+ /* verify that the device wasn't unplugged */ if (dev->intf == NULL) {
retval = -ENODEV;
err("No device or device unplugged %d\n", retval);
goto unlock_exit;
@@ -604,104 +528,149 @@ static ssize_t usb_tranzport_read(struct file *file, char __user *buffer, size_t
retval = -EAGAIN;
goto unlock_exit;
}
- // atomic_cmp_exchange(&dev->interrupt_in_done,0,0);
- dev->interrupt_in_done = 0 ; /* tiny race - FIXME: make atomic? */
- retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done);
- if (retval < 0) {
+ /* tiny race - FIXME: make atomic? */
+ /* atomic_cmp_exchange(&dev->interrupt_in_done,0,0); */
+ dev->interrupt_in_done = 0;
+ retval = wait_event_interruptible(dev->read_wait,
+ dev->interrupt_in_done);
+ if (retval < 0)
goto unlock_exit;
- }
}
- dbg_info(&dev->intf->dev, "%s: copying to userspace: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
+ dbg_info(&dev->intf->dev,
+ "%s: copying to userspace: "
+ "%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__,
+ (*dev->ring_buffer)[dev->ring_tail].cmd[0],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[1],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[2],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[3],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[4],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[5],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[6],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
#if BUFFERED_READS
- c = 0;
- while((c < count) && (dev->ring_tail != dev->ring_head)) {
+ c = 0;
+ while ((c < count) && (dev->ring_tail != dev->ring_head)) {
-/* This started off in the lower level service routine, and I moved it here. Then my brain died. Not done yet. */
#if COMPRESS_WHEEL_EVENTS
next_tail = (dev->ring_tail+1) % ring_buffer_size;
- if(dev->compress_wheel) cancompress = 1;
- while(dev->ring_head != next_tail && cancompress == 1 ) {
+ if (dev->compress_wheel)
+ cancompress = 1;
+ while (dev->ring_head != next_tail && cancompress == 1) {
newwheel = (*dev->ring_buffer)[next_tail].cmd[6];
oldwheel = (*dev->ring_buffer)[dev->ring_tail].cmd[6];
- // if both are wheel events, and no buttons have changes (FIXME, do I have to check?),
- // and we are the same sign, we can compress +- 7F
- // FIXME: saner check for overflow! - max of +- 7F
- // FIXME the math is wrong for going in reverse, actually, as the midi spec doesn't allow signed chars
-
- dbg_info(&dev->intf->dev, "%s: trying to compress: %02x%02x%02x%02x%02x %02x %02x %02x\n",
- __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
-
- if(((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
- (*dev->ring_buffer)[next_tail].cmd[6] != 0 ) &&
+ /* if both are wheel events, and
+ no buttons have changes (FIXME, do I have to check?),
+ and we are the same sign, we can compress +- 7F
+ */
+ dbg_info(&dev->intf->dev,
+ "%s: trying to compress: "
+ "%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__,
+ (*dev->ring_buffer)[dev->ring_tail].cmd[0],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[1],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[2],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[3],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[4],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[5],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[6],
+ (*dev->ring_buffer)[dev->ring_tail].cmd[7]);
+
+ if (((*dev->ring_buffer)[dev->ring_tail].cmd[6] != 0 &&
+ (*dev->ring_buffer)[next_tail].cmd[6] != 0) &&
((newwheel > 0 && oldwheel > 0) ||
- (newwheel < 0 && oldwheel < 0)) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[2] == (*dev->ring_buffer)[next_tail].cmd[2]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[3] == (*dev->ring_buffer)[next_tail].cmd[3]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[4] == (*dev->ring_buffer)[next_tail].cmd[4]) &&
- ((*dev->ring_buffer)[dev->ring_tail].cmd[5] == (*dev->ring_buffer)[next_tail].cmd[5]))
- {
- dbg_info(&dev->intf->dev, "%s: should compress: %02x%02x%02x%02x%02x%02x%02x%02x\n",
- __func__, (*dev->ring_buffer)[dev->ring_tail].cmd[0],(*dev->ring_buffer)[dev->ring_tail].cmd[1],(*dev->ring_buffer)[dev->ring_tail].cmd[2],(*dev->ring_buffer)[dev->ring_tail].cmd[3],(*dev->ring_buffer)[dev->ring_tail].cmd[4],(*dev->ring_buffer)[dev->ring_tail].cmd[5],(*dev->ring_buffer)[dev->ring_tail].cmd[6],(*dev->ring_buffer)[dev->ring_tail].cmd[7]);
-
+ (newwheel < 0 && oldwheel < 0)) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[2] ==
+ (*dev->ring_buffer)[next_tail].cmd[2]) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[3] ==
+ (*dev->ring_buffer)[next_tail].cmd[3]) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[4] ==
+ (*dev->ring_buffer)[next_tail].cmd[4]) &&
+ ((*dev->ring_buffer)[dev->ring_tail].cmd[5] ==
+ (*dev->ring_buffer)[next_tail].cmd[5])) {
+ dbg_info(&dev->intf->dev,
+ "%s: should compress: "
+ "%02x%02x%02x%02x%02x%02x%02x%02x\n",
+ __func__,
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[0],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[1],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[2],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[3],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[4],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[5],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[6],
+ (*dev->ring_buffer)[dev->ring_tail].
+ cmd[7]);
newwheel += oldwheel;
- if(oldwheel > 0 && !(newwheel > 0)) {
+ if (oldwheel > 0 && !(newwheel > 0)) {
newwheel = 0x7f;
cancompress = 0;
}
- if(oldwheel < 0 && !(newwheel < 0)) {
+ if (oldwheel < 0 && !(newwheel < 0)) {
newwheel = 0x80;
cancompress = 0;
}
- (*dev->ring_buffer)[next_tail].cmd[6] = newwheel;
+ (*dev->ring_buffer)[next_tail].cmd[6] =
+ newwheel;
dev->ring_tail = next_tail;
- next_tail = (dev->ring_tail+1) % ring_buffer_size;
+ next_tail =
+ (dev->ring_tail + 1) % ring_buffer_size;
} else {
cancompress = 0;
}
}
#endif /* COMPRESS_WHEEL_EVENTS */
-
- if (copy_to_user(&buffer[c], &(*dev->ring_buffer)[dev->ring_tail], 8)) {
+ if (copy_to_user(
+ &buffer[c],
+ &(*dev->ring_buffer)[dev->ring_tail], 8)) {
retval = -EFAULT;
goto unlock_exit;
}
-
- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
- c+=8;
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
- }
- retval = c;
+ dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+ c += 8;
+ dbg_info(&dev->intf->dev,
+ "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
+ }
+ retval = c;
#else
- if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) {
- retval = -EFAULT;
- goto unlock_exit;
- }
+/* if (copy_to_user(buffer, &(*dev->ring_buffer)[dev->ring_tail], 8)) { */
+ retval = -EFAULT;
+ goto unlock_exit;
+}
- dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size;
- dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n", __func__,dev->ring_head,dev->ring_tail);
+dev->ring_tail = (dev->ring_tail + 1) % ring_buffer_size;
+dbg_info(&dev->intf->dev, "%s: head, tail are %x, %x\n",
+ __func__, dev->ring_head, dev->ring_tail);
- retval = 8;
+retval = 8;
#endif /* BUFFERED_READS */
unlock_exit:
- /* unlock the device */
- up(&dev->sem);
+/* unlock the device */
+up(&dev->sem);
exit:
- return retval;
+return retval;
}
/**
* usb_tranzport_write
*/
-static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
- size_t count, loff_t *ppos)
+static ssize_t usb_tranzport_write(struct file *file,
+ const char __user *buffer, size_t count,
+ loff_t *ppos)
{
struct usb_tranzport *dev;
size_t bytes_to_write;
@@ -718,7 +687,6 @@ static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
retval = -ERESTARTSYS;
goto exit;
}
-
/* verify that the device wasn't unplugged */
if (dev->intf == NULL) {
retval = -ENODEV;
@@ -732,18 +700,24 @@ static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
retval = -EAGAIN;
goto unlock_exit;
}
- retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy);
- if (retval < 0) {
+ retval = wait_event_interruptible(dev->write_wait,
+ !dev->interrupt_out_busy);
+ if (retval < 0)
goto unlock_exit;
- }
}
/* write the data into interrupt_out_buffer from userspace */
- bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size);
+ bytes_to_write = min(count,
+ write_buffer_size *
+ dev->interrupt_out_endpoint_size);
if (bytes_to_write < count)
- dev_warn(&dev->intf->dev, "Write buffer overflow, %zd bytes dropped\n",count-bytes_to_write);
+ dev_warn(&dev->intf->dev,
+ "Write buffer overflow, %zd bytes dropped\n",
+ count - bytes_to_write);
- dbg_info(&dev->intf->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write);
+ dbg_info(&dev->intf->dev,
+ "%s: count = %zd, bytes_to_write = %zd\n", __func__,
+ count, bytes_to_write);
if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) {
retval = -EFAULT;
@@ -757,14 +731,13 @@ static ssize_t usb_tranzport_write(struct file *file, const char __user *buffer,
/* send off the urb */
usb_fill_int_urb(dev->interrupt_out_urb,
- interface_to_usbdev(dev->intf),
- usb_sndintpipe(interface_to_usbdev(dev->intf),
- dev->interrupt_out_endpoint->bEndpointAddress),
- dev->interrupt_out_buffer,
- bytes_to_write,
- usb_tranzport_interrupt_out_callback,
- dev,
- dev->interrupt_out_interval);
+ interface_to_usbdev(dev->intf),
+ usb_sndintpipe(interface_to_usbdev(dev->intf),
+ dev->interrupt_out_endpoint->
+ bEndpointAddress),
+ dev->interrupt_out_buffer, bytes_to_write,
+ usb_tranzport_interrupt_out_callback, dev,
+ dev->interrupt_out_interval);
dev->interrupt_out_busy = 1;
wmb();
@@ -787,12 +760,12 @@ exit:
/* file operations needed when we register this driver */
static const struct file_operations usb_tranzport_fops = {
- .owner = THIS_MODULE,
- .read = usb_tranzport_read,
- .write = usb_tranzport_write,
- .open = usb_tranzport_open,
- .release = usb_tranzport_release,
- .poll = usb_tranzport_poll,
+ .owner = THIS_MODULE,
+ .read = usb_tranzport_read,
+ .write = usb_tranzport_write,
+ .open = usb_tranzport_open,
+ .release = usb_tranzport_release,
+ .poll = usb_tranzport_poll,
};
/*
@@ -800,20 +773,19 @@ static const struct file_operations usb_tranzport_fops = {
* and to have the device registered with the driver core
*/
static struct usb_class_driver usb_tranzport_class = {
- .name = "tranzport%d",
- .fops = &usb_tranzport_fops,
- .minor_base = USB_TRANZPORT_MINOR_BASE,
+ .name = "tranzport%d",
+ .fops = &usb_tranzport_fops,
+ .minor_base = USB_TRANZPORT_MINOR_BASE,
};
-
/**
* usb_tranzport_probe
*
* Called by the usb core when a new device is connected that it thinks
* this driver might be interested in.
*/
-static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_device_id *id)
-{
+static int usb_tranzport_probe(struct usb_interface *intf,
+ const struct usb_device_id *id) {
struct usb_device *udev = interface_to_usbdev(intf);
struct usb_tranzport *dev = NULL;
struct usb_host_interface *iface_desc;
@@ -824,7 +796,7 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
/* allocate memory for our device state and intialize it */
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
if (dev == NULL) {
dev_err(&intf->dev, "Out of memory\n");
goto exit;
@@ -851,25 +823,33 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
goto error;
}
if (dev->interrupt_out_endpoint == NULL)
- dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n");
-
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint not found"
+ "(using control endpoint instead)\n");
- dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
+ dev->interrupt_in_endpoint_size =
+ le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize);
if (dev->interrupt_in_endpoint_size != 8)
- dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
+ dev_warn(&intf->dev, "Interrupt in endpoint size is not 8!\n");
- if(ring_buffer_size == 0) { ring_buffer_size = RING_BUFFER_SIZE; }
- true_size = min(ring_buffer_size,RING_BUFFER_SIZE);
- /* FIXME - there are more usb_alloc routines for dma correctness. Needed? */
+ if (ring_buffer_size == 0)
+ ring_buffer_size = RING_BUFFER_SIZE;
+ true_size = min(ring_buffer_size, RING_BUFFER_SIZE);
- dev->ring_buffer = kmalloc((true_size*sizeof(struct tranzport_cmd))+8, GFP_KERNEL);
+ /* FIXME - there are more usb_alloc routines for dma correctness.
+ Needed? */
+
+ dev->ring_buffer =
+ kmalloc((true_size * sizeof(struct tranzport_cmd)) + 8, GFP_KERNEL);
if (!dev->ring_buffer) {
- dev_err(&intf->dev, "Couldn't allocate ring_buffer of size %d\n",true_size);
+ dev_err(&intf->dev,
+ "Couldn't allocate ring_buffer size %d\n", true_size);
goto error;
}
- dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
+ dev->interrupt_in_buffer =
+ kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL);
if (!dev->interrupt_in_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n");
goto error;
@@ -879,13 +859,18 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n");
goto error;
}
- dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
- udev->descriptor.bMaxPacketSize0;
+ dev->interrupt_out_endpoint_size =
+ dev->interrupt_out_endpoint ?
+ le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) :
+ udev->descriptor.bMaxPacketSize0;
- if (dev->interrupt_out_endpoint_size !=8)
- dev_warn(&intf->dev, "Interrupt out endpoint size is not 8!)\n");
+ if (dev->interrupt_out_endpoint_size != 8)
+ dev_warn(&intf->dev,
+ "Interrupt out endpoint size is not 8!)\n");
- dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL);
+ dev->interrupt_out_buffer =
+ kmalloc(write_buffer_size * dev->interrupt_out_endpoint_size,
+ GFP_KERNEL);
if (!dev->interrupt_out_buffer) {
dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n");
goto error;
@@ -895,9 +880,18 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n");
goto error;
}
- dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
- if (dev->interrupt_out_endpoint)
- dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+ dev->interrupt_in_interval =
+ min_interrupt_in_interval >
+ dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval
+ : dev->interrupt_in_endpoint->bInterval;
+
+ if (dev->interrupt_out_endpoint) {
+ dev->interrupt_out_interval =
+ min_interrupt_out_interval >
+ dev->interrupt_out_endpoint->bInterval ?
+ min_interrupt_out_interval :
+ dev->interrupt_out_endpoint->bInterval;
+ }
/* we can register the device now, as it is ready */
usb_set_intfdata(intf, dev);
@@ -905,35 +899,33 @@ static int usb_tranzport_probe(struct usb_interface *intf, const struct usb_devi
retval = usb_register_dev(intf, &usb_tranzport_class);
if (retval) {
/* something prevented us from registering this driver */
- dev_err(&intf->dev, "Not able to get a minor for this device.\n");
+ dev_err(&intf->dev,
+ "Not able to get a minor for this device.\n");
usb_set_intfdata(intf, NULL);
goto error;
}
- if((retval = device_create_file(&intf->dev, &dev_attr_LightRecord))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightTrackrec))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightTrackmute))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightTracksolo))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightAnysolo))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightLoop))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_LightPunch))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_wheel))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_event))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_dump_state))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_compress_wheel))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_enable))) goto error;
- if((retval = device_create_file(&intf->dev, &dev_attr_offline))) goto error;
+ retval = device_create_file(&intf->dev, &dev_attr_compress_wheel);
+ if (retval)
+ goto error;
+ retval = device_create_file(&intf->dev, &dev_attr_enable);
+ if (retval)
+ goto error;
+ retval = device_create_file(&intf->dev, &dev_attr_offline);
+ if (retval)
+ goto error;
/* let the user know what node this device is now attached to */
- dev_info(&intf->dev, "Tranzport Device #%d now attached to major %d minor %d\n",
- (intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR, intf->minor);
+ dev_info(&intf->dev,
+ "Tranzport Device #%d now attached to major %d minor %d\n",
+ (intf->minor - USB_TRANZPORT_MINOR_BASE), USB_MAJOR,
+ intf->minor);
exit:
return retval;
error:
usb_tranzport_delete(dev);
-
return retval;
}
@@ -966,15 +958,15 @@ static void usb_tranzport_disconnect(struct usb_interface *intf)
mutex_unlock(&disconnect_mutex);
dev_info(&intf->dev, "Tranzport Surface #%d now disconnected\n",
- (minor - USB_TRANZPORT_MINOR_BASE));
+ (minor - USB_TRANZPORT_MINOR_BASE));
}
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver usb_tranzport_driver = {
- .name = "tranzport",
- .probe = usb_tranzport_probe,
- .disconnect = usb_tranzport_disconnect,
- .id_table = usb_tranzport_table,
+ .name = "tranzport",
+ .probe = usb_tranzport_probe,
+ .disconnect = usb_tranzport_disconnect,
+ .id_table = usb_tranzport_table,
};
/**
@@ -987,14 +979,14 @@ static int __init usb_tranzport_init(void)
/* register this driver with the USB subsystem */
retval = usb_register(&usb_tranzport_driver);
if (retval)
- err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval);
-
+ err("usb_register failed for the " __FILE__
+ " driver. Error number %d\n", retval);
return retval;
}
-
/**
* usb_tranzport_exit
*/
+
static void __exit usb_tranzport_exit(void)
{
/* deregister this driver with the USB subsystem */
@@ -1003,4 +995,3 @@ static void __exit usb_tranzport_exit(void)
module_init(usb_tranzport_init);
module_exit(usb_tranzport_exit);
-
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index f2cf7f66ae0..ca6ade6c4b4 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -10,7 +10,7 @@ config VIDEO_GO7007
select CRC32
default N
---help---
- This is a video4linux driver for some wierd device...
+ This is a video4linux driver for some weird device...
To compile this driver as a module, choose M here: the
module will be called go7007
@@ -20,7 +20,7 @@ config VIDEO_GO7007_USB
depends on VIDEO_GO7007 && USB
default N
---help---
- This is a video4linux driver for some wierd device...
+ This is a video4linux driver for some weird device...
To compile this driver as a module, choose M here: the
module will be called go7007-usb
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 868edb65e7b..06cacd37bbd 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -1827,7 +1827,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
static struct video_device go7007_template = {
.name = "go7007",
- .vfl_type = VID_TYPE_CAPTURE,
.fops = &go7007_fops,
.minor = -1,
.release = go7007_vfl_release,
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index fb6845e3788..d333ea2cd77 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -149,7 +149,7 @@ static int go7007_usb_vendor_request(struct go7007 *go, u16 request,
static int write_reg(struct i2c_client *client, u8 reg, u8 value)
{
struct go7007 *go = i2c_get_adapdata(client->adapter);
- struct go7007_usb *usb = go->hpi_context;
+ struct go7007_usb *usb;
int rc;
int dev_addr = client->addr;
u8 *buf;
@@ -164,8 +164,10 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
if (buf == NULL)
return -ENOMEM;
+ usb = go->hpi_context;
if (down_interruptible(&usb->i2c_lock) != 0) {
printk(KERN_INFO "i2c lock failed\n");
+ kfree(buf);
return -EINTR;
}
rc = go7007_usb_vendor_request(go, 0x55, dev_addr,
@@ -181,7 +183,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
{
struct go7007 *go = i2c_get_adapdata(client->adapter);
- struct go7007_usb *usb = go->hpi_context;
+ struct go7007_usb *usb;
u8 *buf;
struct s2250 *dec = i2c_get_clientdata(client);
@@ -200,6 +202,7 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
memset(buf, 0xcd, 6);
+ usb = go->hpi_context;
if (down_interruptible(&usb->i2c_lock) != 0) {
printk(KERN_INFO "i2c lock failed\n");
return -EINTR;
diff --git a/drivers/staging/heci/Kconfig b/drivers/staging/heci/Kconfig
new file mode 100644
index 00000000000..ae8d588d3a2
--- /dev/null
+++ b/drivers/staging/heci/Kconfig
@@ -0,0 +1,6 @@
+config HECI
+ tristate "Intel Management Engine Interface (MEI) Support"
+ ---help---
+ The Intel Management Engine Interface (Intel MEI) driver allows
+ applications to access the Active Management Technology
+ firmware and other Management Engine sub-systems.
diff --git a/drivers/staging/heci/Makefile b/drivers/staging/heci/Makefile
new file mode 100644
index 00000000000..0524856fa3a
--- /dev/null
+++ b/drivers/staging/heci/Makefile
@@ -0,0 +1,9 @@
+obj-$(CONFIG_HECI) += heci.o
+
+heci-objs := \
+ heci_init.o \
+ interrupt.o \
+ heci_interface.o \
+ io_heci.o \
+ heci_main.o
+
diff --git a/drivers/staging/heci/TODO b/drivers/staging/heci/TODO
new file mode 100644
index 00000000000..f86715d631c
--- /dev/null
+++ b/drivers/staging/heci/TODO
@@ -0,0 +1,6 @@
+TODO:
+ - fix user/kernel pointer mess in the ioctl handlers as pointed
+ out by sparse.
+ - resolve the ioctls and see if most of them can just be simple
+ sysfs files
+ - fix locking issues that sparse points out at the least.
diff --git a/drivers/staging/heci/heci.h b/drivers/staging/heci/heci.h
new file mode 100644
index 00000000000..14192e0cc22
--- /dev/null
+++ b/drivers/staging/heci/heci.h
@@ -0,0 +1,176 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef _HECI_H_
+#define _HECI_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+#include "heci_data_structures.h"
+
+extern const struct guid heci_pthi_guid;
+extern const struct guid heci_wd_guid;
+extern const __u8 heci_start_wd_params[];
+extern const __u8 heci_stop_wd_params[];
+extern const __u8 heci_wd_state_independence_msg[3][4];
+
+/*
+ * heci device ID
+ */
+#define HECI_DEV_ID_82946GZ 0x2974 /* 82946GZ/GL */
+#define HECI_DEV_ID_82G35 0x2984 /* 82G35 Express */
+#define HECI_DEV_ID_82Q965 0x2994 /* 82Q963/Q965 */
+#define HECI_DEV_ID_82G965 0x29A4 /* 82P965/G965 */
+
+#define HECI_DEV_ID_82GM965 0x2A04 /* Mobile PM965/GM965 */
+#define HECI_DEV_ID_82GME965 0x2A14 /* Mobile GME965/GLE960 */
+
+#define HECI_DEV_ID_ICH9_82Q35 0x29B4 /* 82Q35 Express */
+#define HECI_DEV_ID_ICH9_82G33 0x29C4 /* 82G33/G31/P35/P31 Express */
+#define HECI_DEV_ID_ICH9_82Q33 0x29D4 /* 82Q33 Express */
+#define HECI_DEV_ID_ICH9_82X38 0x29E4 /* 82X38/X48 Express */
+#define HECI_DEV_ID_ICH9_3200 0x29F4 /* 3200/3210 Server */
+
+#define HECI_DEV_ID_ICH9_6 0x28B4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_7 0x28C4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_8 0x28D4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_9 0x28E4 /* Bearlake */
+#define HECI_DEV_ID_ICH9_10 0x28F4 /* Bearlake */
+
+#define HECI_DEV_ID_ICH9M_1 0x2A44 /* Cantiga */
+#define HECI_DEV_ID_ICH9M_2 0x2A54 /* Cantiga */
+#define HECI_DEV_ID_ICH9M_3 0x2A64 /* Cantiga */
+#define HECI_DEV_ID_ICH9M_4 0x2A74 /* Cantiga */
+
+#define HECI_DEV_ID_ICH10_1 0x2E04 /* Eaglelake */
+#define HECI_DEV_ID_ICH10_2 0x2E14 /* Eaglelake */
+#define HECI_DEV_ID_ICH10_3 0x2E24 /* Eaglelake */
+#define HECI_DEV_ID_ICH10_4 0x2E34 /* Eaglelake */
+
+/*
+ * heci init function prototypes
+ */
+struct iamt_heci_device *init_heci_device(struct pci_dev *pdev);
+void heci_reset(struct iamt_heci_device *dev, int interrupts);
+int heci_hw_init(struct iamt_heci_device *dev);
+int heci_task_initialize_clients(void *data);
+int heci_initialize_clients(struct iamt_heci_device *dev);
+struct heci_file_private *heci_alloc_file_private(struct file *file);
+int heci_disconnect_host_client(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+void heci_initialize_list(struct io_heci_list *list,
+ struct iamt_heci_device *dev);
+void heci_flush_list(struct io_heci_list *list,
+ struct heci_file_private *file_ext);
+void heci_flush_queues(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+void heci_remove_client_from_file_list(struct iamt_heci_device *dev,
+ __u8 host_client_id);
+
+/*
+ * interrupt function prototype
+ */
+irqreturn_t heci_isr_interrupt(int irq, void *dev_id);
+
+void heci_wd_timer(unsigned long data);
+
+/*
+ * input output function prototype
+ */
+int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext);
+
+int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct file *file);
+
+int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext);
+
+int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext);
+
+int heci_start_read(struct iamt_heci_device *dev, int if_num,
+ struct heci_file_private *file_ext);
+
+int pthi_write(struct iamt_heci_device *dev,
+ struct heci_cb_private *priv_cb);
+
+int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file,
+ char __user *ubuf, size_t length, loff_t *offset);
+
+struct heci_cb_private *find_pthi_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct file *file);
+
+void run_next_iamthif_cmd(struct iamt_heci_device *dev);
+
+void heci_free_cb_private(struct heci_cb_private *priv_cb);
+
+/**
+ * heci_fe_same_id - tell if file private data have same id
+ *
+ * @fe1: private data of 1. file object
+ * @fe2: private data of 2. file object
+ *
+ * returns !=0 - if ids are the same, 0 - if differ.
+ */
+static inline int heci_fe_same_id(const struct heci_file_private *fe1,
+ const struct heci_file_private *fe2)
+{
+ return ((fe1->host_client_id == fe2->host_client_id)
+ && (fe1->me_client_id == fe2->me_client_id));
+}
+
+#endif /* _HECI_H_ */
diff --git a/drivers/staging/heci/heci_data_structures.h b/drivers/staging/heci/heci_data_structures.h
new file mode 100644
index 00000000000..575e8f8e88a
--- /dev/null
+++ b/drivers/staging/heci/heci_data_structures.h
@@ -0,0 +1,530 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef _HECI_DATA_STRUCTURES_H_
+#define _HECI_DATA_STRUCTURES_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+
+/*
+ * error code definition
+ */
+#define ESLOTS_OVERFLOW 1
+#define ECORRUPTED_MESSAGE_HEADER 1000
+#define ECOMPLETE_MESSAGE 1001
+
+#define HECI_FC_MESSAGE_RESERVED_LENGTH 5
+
+/*
+ * Number of queue lists used by this driver
+ */
+#define HECI_IO_LISTS_NUMBER 7
+
+/*
+ * Maximum transmission unit (MTU) of heci messages
+ */
+#define IAMTHIF_MTU 4160
+
+
+/*
+ * HECI HW Section
+ */
+
+/* HECI registers */
+/* H_CB_WW - Host Circular Buffer (CB) Write Window register */
+#define H_CB_WW 0
+/* H_CSR - Host Control Status register */
+#define H_CSR 4
+/* ME_CB_RW - ME Circular Buffer Read Window register (read only) */
+#define ME_CB_RW 8
+/* ME_CSR_HA - ME Control Status Host Access register (read only) */
+#define ME_CSR_HA 0xC
+
+
+/* register bits of H_CSR (Host Control Status register) */
+/* Host Circular Buffer Depth - maximum number of 32-bit entries in CB */
+#define H_CBD 0xFF000000
+/* Host Circular Buffer Write Pointer */
+#define H_CBWP 0x00FF0000
+/* Host Circular Buffer Read Pointer */
+#define H_CBRP 0x0000FF00
+/* Host Reset */
+#define H_RST 0x00000010
+/* Host Ready */
+#define H_RDY 0x00000008
+/* Host Interrupt Generate */
+#define H_IG 0x00000004
+/* Host Interrupt Status */
+#define H_IS 0x00000002
+/* Host Interrupt Enable */
+#define H_IE 0x00000001
+
+
+/* register bits of ME_CSR_HA (ME Control Status Host Access register) */
+/* ME CB (Circular Buffer) Depth HRA (Host Read Access)
+ * - host read only access to ME_CBD */
+#define ME_CBD_HRA 0xFF000000
+/* ME CB Write Pointer HRA - host read only access to ME_CBWP */
+#define ME_CBWP_HRA 0x00FF0000
+/* ME CB Read Pointer HRA - host read only access to ME_CBRP */
+#define ME_CBRP_HRA 0x0000FF00
+/* ME Reset HRA - host read only access to ME_RST */
+#define ME_RST_HRA 0x00000010
+/* ME Ready HRA - host read only access to ME_RDY */
+#define ME_RDY_HRA 0x00000008
+/* ME Interrupt Generate HRA - host read only access to ME_IG */
+#define ME_IG_HRA 0x00000004
+/* ME Interrupt Status HRA - host read only access to ME_IS */
+#define ME_IS_HRA 0x00000002
+/* ME Interrupt Enable HRA - host read only access to ME_IE */
+#define ME_IE_HRA 0x00000001
+
+#define HECI_MINORS_BASE 1
+#define HECI_MINORS_COUNT 1
+
+#define HECI_MINOR_NUMBER 1
+#define HECI_MAX_OPEN_HANDLE_COUNT 253
+
+/*
+ * debug kernel print macro define
+ */
+extern int heci_debug;
+
+#define DBG(format, arg...) do { \
+ if (heci_debug) \
+ printk(KERN_INFO "heci: %s: " format, __func__, ## arg); \
+} while (0)
+
+
+/*
+ * time to wait HECI become ready after init
+ */
+#define HECI_INTEROP_TIMEOUT (HZ * 7)
+
+/*
+ * watch dog definition
+ */
+#define HECI_WATCHDOG_DATA_SIZE 16
+#define HECI_START_WD_DATA_SIZE 20
+#define HECI_WD_PARAMS_SIZE 4
+#define HECI_WD_STATE_INDEPENDENCE_MSG_SENT (1 << 0)
+
+#define HECI_WD_HOST_CLIENT_ID 1
+#define HECI_IAMTHIF_HOST_CLIENT_ID 2
+
+struct guid {
+ __u32 data1;
+ __u16 data2;
+ __u16 data3;
+ __u8 data4[8];
+};
+
+/* File state */
+enum file_state {
+ HECI_FILE_INITIALIZING = 0,
+ HECI_FILE_CONNECTING,
+ HECI_FILE_CONNECTED,
+ HECI_FILE_DISCONNECTING,
+ HECI_FILE_DISCONNECTED
+};
+
+/* HECI device states */
+enum heci_states {
+ HECI_INITIALIZING = 0,
+ HECI_ENABLED,
+ HECI_RESETING,
+ HECI_DISABLED,
+ HECI_RECOVERING_FROM_RESET,
+ HECI_POWER_DOWN,
+ HECI_POWER_UP
+};
+
+enum iamthif_states {
+ HECI_IAMTHIF_IDLE,
+ HECI_IAMTHIF_WRITING,
+ HECI_IAMTHIF_FLOW_CONTROL,
+ HECI_IAMTHIF_READING,
+ HECI_IAMTHIF_READ_COMPLETE
+};
+
+enum heci_file_transaction_states {
+ HECI_IDLE,
+ HECI_WRITING,
+ HECI_WRITE_COMPLETE,
+ HECI_FLOW_CONTROL,
+ HECI_READING,
+ HECI_READ_COMPLETE
+};
+
+/* HECI CB */
+enum heci_cb_major_types {
+ HECI_READ = 0,
+ HECI_WRITE,
+ HECI_IOCTL,
+ HECI_OPEN,
+ HECI_CLOSE
+};
+
+/* HECI user data struct */
+struct heci_message_data {
+ __u32 size;
+ char *data;
+} __attribute__((packed));
+
+#define HECI_CONNECT_TIMEOUT 3 /* at least 2 seconds */
+
+#define IAMTHIF_STALL_TIMER 12 /* seconds */
+#define IAMTHIF_READ_TIMER 15 /* seconds */
+
+struct heci_cb_private {
+ struct list_head cb_list;
+ enum heci_cb_major_types major_file_operations;
+ void *file_private;
+ struct heci_message_data request_buffer;
+ struct heci_message_data response_buffer;
+ unsigned long information;
+ unsigned long read_time;
+ struct file *file_object;
+};
+
+/* Private file struct */
+struct heci_file_private {
+ struct list_head link;
+ struct file *file;
+ enum file_state state;
+ wait_queue_head_t tx_wait;
+ wait_queue_head_t rx_wait;
+ wait_queue_head_t wait;
+ spinlock_t file_lock; /* file lock */
+ spinlock_t read_io_lock; /* read lock */
+ spinlock_t write_io_lock; /* write lock */
+ int read_pending;
+ int status;
+ /* ID of client connected */
+ __u8 host_client_id;
+ __u8 me_client_id;
+ __u8 flow_ctrl_creds;
+ __u8 timer_count;
+ enum heci_file_transaction_states reading_state;
+ enum heci_file_transaction_states writing_state;
+ int sm_state;
+ struct heci_cb_private *read_cb;
+};
+
+struct io_heci_list {
+ struct heci_cb_private heci_cb;
+ int status;
+ struct iamt_heci_device *device_extension;
+};
+
+struct heci_driver_version {
+ __u8 major;
+ __u8 minor;
+ __u8 hotfix;
+ __u16 build;
+} __attribute__((packed));
+
+
+struct heci_client {
+ __u32 max_msg_length;
+ __u8 protocol_version;
+} __attribute__((packed));
+
+/*
+ * HECI BUS Interface Section
+ */
+struct heci_msg_hdr {
+ __u32 me_addr:8;
+ __u32 host_addr:8;
+ __u32 length:9;
+ __u32 reserved:6;
+ __u32 msg_complete:1;
+} __attribute__((packed));
+
+
+struct hbm_cmd {
+ __u8 cmd:7;
+ __u8 is_response:1;
+} __attribute__((packed));
+
+
+struct heci_bus_message {
+ struct hbm_cmd cmd;
+ __u8 command_specific_data[];
+} __attribute__((packed));
+
+struct hbm_version {
+ __u8 minor_version;
+ __u8 major_version;
+} __attribute__((packed));
+
+struct hbm_host_version_request {
+ struct hbm_cmd cmd;
+ __u8 reserved;
+ struct hbm_version host_version;
+} __attribute__((packed));
+
+struct hbm_host_version_response {
+ struct hbm_cmd cmd;
+ int host_version_supported;
+ struct hbm_version me_max_version;
+} __attribute__((packed));
+
+struct hbm_host_stop_request {
+ struct hbm_cmd cmd;
+ __u8 reason;
+ __u8 reserved[2];
+} __attribute__((packed));
+
+struct hbm_host_stop_response {
+ struct hbm_cmd cmd;
+ __u8 reserved[3];
+} __attribute__((packed));
+
+struct hbm_me_stop_request {
+ struct hbm_cmd cmd;
+ __u8 reason;
+ __u8 reserved[2];
+} __attribute__((packed));
+
+struct hbm_host_enum_request {
+ struct hbm_cmd cmd;
+ __u8 reserved[3];
+} __attribute__((packed));
+
+struct hbm_host_enum_response {
+ struct hbm_cmd cmd;
+ __u8 reserved[3];
+ __u8 valid_addresses[32];
+} __attribute__((packed));
+
+struct heci_client_properties {
+ struct guid protocol_name;
+ __u8 protocol_version;
+ __u8 max_number_of_connections;
+ __u8 fixed_address;
+ __u8 single_recv_buf;
+ __u32 max_msg_length;
+} __attribute__((packed));
+
+struct hbm_props_request {
+ struct hbm_cmd cmd;
+ __u8 address;
+ __u8 reserved[2];
+} __attribute__((packed));
+
+
+struct hbm_props_response {
+ struct hbm_cmd cmd;
+ __u8 address;
+ __u8 status;
+ __u8 reserved[1];
+ struct heci_client_properties client_properties;
+} __attribute__((packed));
+
+struct hbm_client_connect_request {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 reserved;
+} __attribute__((packed));
+
+struct hbm_client_connect_response {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 status;
+} __attribute__((packed));
+
+struct hbm_client_disconnect_request {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 reserved[1];
+} __attribute__((packed));
+
+struct hbm_flow_control {
+ struct hbm_cmd cmd;
+ __u8 me_addr;
+ __u8 host_addr;
+ __u8 reserved[HECI_FC_MESSAGE_RESERVED_LENGTH];
+} __attribute__((packed));
+
+struct heci_me_client {
+ struct heci_client_properties props;
+ __u8 client_id;
+ __u8 flow_ctrl_creds;
+} __attribute__((packed));
+
+/* private device struct */
+struct iamt_heci_device {
+ struct pci_dev *pdev; /* pointer to pci device struct */
+ /*
+ * lists of queues
+ */
+ /* array of pointers to aio lists */
+ struct io_heci_list *io_list_array[HECI_IO_LISTS_NUMBER];
+ struct io_heci_list read_list; /* driver read queue */
+ struct io_heci_list write_list; /* driver write queue */
+ struct io_heci_list write_waiting_list; /* write waiting queue */
+ struct io_heci_list ctrl_wr_list; /* managed write IOCTL list */
+ struct io_heci_list ctrl_rd_list; /* managed read IOCTL list */
+ struct io_heci_list pthi_cmd_list; /* PTHI list for cmd waiting */
+
+ /* driver managed PTHI list for reading completed pthi cmd data */
+ struct io_heci_list pthi_read_complete_list;
+ /*
+ * list of files
+ */
+ struct list_head file_list;
+ /*
+ * memory of device
+ */
+ unsigned int mem_base;
+ unsigned int mem_length;
+ void __iomem *mem_addr;
+ /*
+ * lock for the device
+ */
+ spinlock_t device_lock; /* device lock*/
+ struct work_struct work;
+ int recvd_msg;
+
+ struct task_struct *reinit_tsk;
+
+ struct timer_list wd_timer;
+ /*
+ * hw states of host and fw(ME)
+ */
+ __u32 host_hw_state;
+ __u32 me_hw_state;
+ /*
+ * waiting queue for receive message from FW
+ */
+ wait_queue_head_t wait_recvd_msg;
+ wait_queue_head_t wait_stop_wd;
+ /*
+ * heci device states
+ */
+ enum heci_states heci_state;
+ int stop;
+
+ __u32 extra_write_index;
+ __u32 rd_msg_buf[128]; /* used for control messages */
+ __u32 wr_msg_buf[128]; /* used for control messages */
+ __u32 ext_msg_buf[8]; /* for control responses */
+ __u32 rd_msg_hdr;
+
+ struct hbm_version version;
+
+ int host_buffer_is_empty;
+ struct heci_file_private wd_file_ext;
+ struct heci_me_client *me_clients; /* Note: memory has to be allocated*/
+ __u8 heci_me_clients[32]; /* list of existing clients */
+ __u8 num_heci_me_clients;
+ __u8 heci_host_clients[32]; /* list of existing clients */
+ __u8 current_host_client_id;
+
+ int wd_pending;
+ int wd_stoped;
+ __u16 wd_timeout; /* seconds ((wd_data[1] << 8) + wd_data[0]) */
+ unsigned char wd_data[HECI_START_WD_DATA_SIZE];
+
+
+ __u16 wd_due_counter;
+ int asf_mode;
+ int wd_bypass; /* if 1, don't refresh watchdog ME client */
+
+ struct file *iamthif_file_object;
+ struct heci_file_private iamthif_file_ext;
+ int iamthif_ioctl;
+ int iamthif_canceled;
+ __u32 iamthif_timer;
+ __u32 iamthif_stall_timer;
+ unsigned char iamthif_msg_buf[IAMTHIF_MTU];
+ __u32 iamthif_msg_buf_size;
+ __u32 iamthif_msg_buf_index;
+ int iamthif_flow_control_pending;
+ enum iamthif_states iamthif_state;
+
+ struct heci_cb_private *iamthif_current_cb;
+ __u8 write_hang;
+ int need_reset;
+ long open_handle_count;
+
+};
+
+/**
+ * read_heci_register - Read a byte from the heci device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to read the data
+ *
+ * returns the byte read.
+ */
+static inline __u32 read_heci_register(struct iamt_heci_device *dev,
+ unsigned long offset)
+{
+ return readl(dev->mem_addr + offset);
+}
+
+/**
+ * write_heci_register - Write 4 bytes to the heci device
+ *
+ * @dev: the device structure
+ * @offset: offset from which to write the data
+ * @value: the byte to write
+ */
+static inline void write_heci_register(struct iamt_heci_device *dev,
+ unsigned long offset, __u32 value)
+{
+ writel(value, dev->mem_addr + offset);
+}
+
+#endif /* _HECI_DATA_STRUCTURES_H_ */
diff --git a/drivers/staging/heci/heci_init.c b/drivers/staging/heci/heci_init.c
new file mode 100644
index 00000000000..a8a0da910cf
--- /dev/null
+++ b/drivers/staging/heci/heci_init.c
@@ -0,0 +1,1077 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/moduleparam.h>
+#include <linux/wait.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
+
+#include "heci_data_structures.h"
+#include "heci_interface.h"
+#include "heci.h"
+
+
+const __u8 heci_start_wd_params[] = { 0x02, 0x12, 0x13, 0x10 };
+const __u8 heci_stop_wd_params[] = { 0x02, 0x02, 0x14, 0x10 };
+
+const __u8 heci_wd_state_independence_msg[3][4] = {
+ {0x05, 0x02, 0x51, 0x10},
+ {0x05, 0x02, 0x52, 0x10},
+ {0x07, 0x02, 0x01, 0x10}
+};
+
+static const struct guid heci_asf_guid = {
+ 0x75B30CD6, 0xA29E, 0x4AF7,
+ {0xA7, 0x12, 0xE6, 0x17, 0x43, 0x93, 0xC8, 0xA6}
+};
+const struct guid heci_wd_guid = {
+ 0x05B79A6F, 0x4628, 0x4D7F,
+ {0x89, 0x9D, 0xA9, 0x15, 0x14, 0xCB, 0x32, 0xAB}
+};
+const struct guid heci_pthi_guid = {
+ 0x12f80028, 0xb4b7, 0x4b2d,
+ {0xac, 0xa8, 0x46, 0xe0, 0xff, 0x65, 0x81, 0x4c}
+};
+
+
+/*
+ * heci init function prototypes
+ */
+static void heci_check_asf_mode(struct iamt_heci_device *dev);
+static int host_start_message(struct iamt_heci_device *dev);
+static int host_enum_clients_message(struct iamt_heci_device *dev);
+static int allocate_me_clients_storage(struct iamt_heci_device *dev);
+static void host_init_wd(struct iamt_heci_device *dev);
+static void host_init_iamthif(struct iamt_heci_device *dev);
+static int heci_wait_event_int_timeout(struct iamt_heci_device *dev,
+ long timeout);
+
+
+/**
+ * heci_initialize_list - Sets up a queue list.
+ *
+ * @list: An instance of our list structure
+ * @dev: Device object for our driver
+ */
+void heci_initialize_list(struct io_heci_list *list,
+ struct iamt_heci_device *dev)
+{
+ /* initialize our queue list */
+ INIT_LIST_HEAD(&list->heci_cb.cb_list);
+ list->status = 0;
+ list->device_extension = dev;
+}
+
+/**
+ * heci_flush_queues - flush our queues list belong to file_ext.
+ *
+ * @dev: Device object for our driver
+ * @file_ext: private data of the file object
+ */
+void heci_flush_queues(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ int i;
+
+ if (!dev || !file_ext)
+ return;
+
+ /* flush our queue list belong to file_ext */
+ for (i = 0; i < HECI_IO_LISTS_NUMBER; i++) {
+ DBG("remove list entry belong to file_ext\n");
+ heci_flush_list(dev->io_list_array[i], file_ext);
+ }
+}
+
+
+/**
+ * heci_flush_list - remove list entry belong to file_ext.
+ *
+ * @list: An instance of our list structure
+ * @file_ext: private data of the file object
+ */
+void heci_flush_list(struct io_heci_list *list,
+ struct heci_file_private *file_ext)
+{
+ struct heci_file_private *file_ext_tmp;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+
+ if (!list || !file_ext)
+ return;
+
+ if (list->status != 0)
+ return;
+
+ if (list_empty(&list->heci_cb.cb_list))
+ return;
+
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &list->heci_cb.cb_list, cb_list) {
+ if (priv_cb_pos) {
+ file_ext_tmp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext_tmp) {
+ if (heci_fe_same_id(file_ext, file_ext_tmp))
+ list_del(&priv_cb_pos->cb_list);
+ }
+ }
+ }
+}
+
+/**
+ * heci_reset_iamthif_params - initializes heci device iamthif
+ *
+ * @dev: The heci device structure
+ */
+static void heci_reset_iamthif_params(struct iamt_heci_device *dev)
+{
+ /* reset iamthif parameters. */
+ dev->iamthif_current_cb = NULL;
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_file_ext.file = NULL;
+ dev->iamthif_ioctl = 0;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+}
+
+/**
+ * init_heci_device - allocates and initializes the heci device structure
+ *
+ * @pdev: The pci device structure
+ *
+ * returns The heci_device_device pointer on success, NULL on failure.
+ */
+struct iamt_heci_device *init_heci_device(struct pci_dev *pdev)
+{
+ int i;
+ struct iamt_heci_device *dev;
+
+ dev = kzalloc(sizeof(struct iamt_heci_device), GFP_KERNEL);
+ if (!dev)
+ return NULL;
+
+ /* setup our list array */
+ dev->io_list_array[0] = &dev->read_list;
+ dev->io_list_array[1] = &dev->write_list;
+ dev->io_list_array[2] = &dev->write_waiting_list;
+ dev->io_list_array[3] = &dev->ctrl_wr_list;
+ dev->io_list_array[4] = &dev->ctrl_rd_list;
+ dev->io_list_array[5] = &dev->pthi_cmd_list;
+ dev->io_list_array[6] = &dev->pthi_read_complete_list;
+ INIT_LIST_HEAD(&dev->file_list);
+ INIT_LIST_HEAD(&dev->wd_file_ext.link);
+ INIT_LIST_HEAD(&dev->iamthif_file_ext.link);
+ spin_lock_init(&dev->device_lock);
+ init_waitqueue_head(&dev->wait_recvd_msg);
+ init_waitqueue_head(&dev->wait_stop_wd);
+ dev->heci_state = HECI_INITIALIZING;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+
+ /* init work for schedule work */
+ INIT_WORK(&dev->work, NULL);
+ for (i = 0; i < HECI_IO_LISTS_NUMBER; i++)
+ heci_initialize_list(dev->io_list_array[i], dev);
+ dev->pdev = pdev;
+ return dev;
+}
+
+
+
+
+static int heci_wait_event_int_timeout(struct iamt_heci_device *dev,
+ long timeout)
+{
+ return wait_event_interruptible_timeout(dev->wait_recvd_msg,
+ (dev->recvd_msg), timeout);
+}
+
+/**
+ * heci_hw_init - init host and fw to start work.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_hw_init(struct iamt_heci_device *dev)
+{
+ int err = 0;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+ DBG("host_hw_state = 0x%08x, mestate = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+
+ if ((dev->host_hw_state & H_IS) == H_IS) {
+ /* acknowledge interrupt and stop interupts */
+ heci_set_csr_register(dev);
+ }
+ dev->recvd_msg = 0;
+ DBG("reset in start the heci device.\n");
+
+ heci_reset(dev, 1);
+
+ DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+
+ /* wait for ME to turn on ME_RDY */
+ if (!dev->recvd_msg)
+ err = heci_wait_event_int_timeout(dev, HECI_INTEROP_TIMEOUT);
+
+ if (!err && !dev->recvd_msg) {
+ dev->heci_state = HECI_DISABLED;
+ DBG("wait_event_interruptible_timeout failed"
+ "on wait for ME to turn on ME_RDY.\n");
+ return -ENODEV;
+ } else {
+ if (!(((dev->host_hw_state & H_RDY) == H_RDY)
+ && ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA))) {
+ dev->heci_state = HECI_DISABLED;
+ DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state,
+ dev->me_hw_state);
+
+ if (!(dev->host_hw_state & H_RDY) != H_RDY)
+ DBG("host turn off H_RDY.\n");
+
+ if (!(dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+ DBG("ME turn off ME_RDY.\n");
+
+ printk(KERN_ERR
+ "heci: link layer initialization failed.\n");
+ return -ENODEV;
+ }
+ }
+ dev->recvd_msg = 0;
+ DBG("host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+ DBG("ME turn on ME_RDY and host turn on H_RDY.\n");
+ printk(KERN_INFO "heci: link layer has been established.\n");
+ return 0;
+}
+
+/**
+ * heci_hw_reset - reset fw via heci csr register.
+ *
+ * @dev: Device object for our driver
+ * @interrupts: if interrupt should be enable after reset.
+ */
+static void heci_hw_reset(struct iamt_heci_device *dev, int interrupts)
+{
+ dev->host_hw_state |= (H_RST | H_IG);
+
+ if (interrupts)
+ heci_csr_enable_interrupts(dev);
+ else
+ heci_csr_disable_interrupts(dev);
+
+ BUG_ON((dev->host_hw_state & H_RST) != H_RST);
+ BUG_ON((dev->host_hw_state & H_RDY) != 0);
+}
+
+/**
+ * heci_reset - reset host and fw.
+ *
+ * @dev: Device object for our driver
+ * @interrupts: if interrupt should be enable after reset.
+ */
+void heci_reset(struct iamt_heci_device *dev, int interrupts)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ int unexpected = 0;
+
+ if (dev->heci_state == HECI_RECOVERING_FROM_RESET) {
+ dev->need_reset = 1;
+ return;
+ }
+
+ if (dev->heci_state != HECI_INITIALIZING &&
+ dev->heci_state != HECI_DISABLED &&
+ dev->heci_state != HECI_POWER_DOWN &&
+ dev->heci_state != HECI_POWER_UP)
+ unexpected = 1;
+
+ if (dev->reinit_tsk != NULL) {
+ kthread_stop(dev->reinit_tsk);
+ dev->reinit_tsk = NULL;
+ }
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+
+ DBG("before reset host_hw_state = 0x%08x.\n",
+ dev->host_hw_state);
+
+ heci_hw_reset(dev, interrupts);
+
+ dev->host_hw_state &= ~H_RST;
+ dev->host_hw_state |= H_IG;
+
+ write_heci_register(dev, H_CSR, dev->host_hw_state);
+
+ DBG("currently saved host_hw_state = 0x%08x.\n",
+ dev->host_hw_state);
+
+ dev->need_reset = 0;
+
+ if (dev->heci_state != HECI_INITIALIZING) {
+ if ((dev->heci_state != HECI_DISABLED) &&
+ (dev->heci_state != HECI_POWER_DOWN))
+ dev->heci_state = HECI_RESETING;
+
+ list_for_each_entry_safe(file_pos,
+ file_next, &dev->file_list, link) {
+ file_pos->state = HECI_FILE_DISCONNECTED;
+ file_pos->flow_ctrl_creds = 0;
+ file_pos->read_cb = NULL;
+ file_pos->timer_count = 0;
+ }
+ /* remove entry if already in list */
+ DBG("list del iamthif and wd file list.\n");
+ heci_remove_client_from_file_list(dev,
+ dev->wd_file_ext.host_client_id);
+
+ heci_remove_client_from_file_list(dev,
+ dev->iamthif_file_ext.host_client_id);
+
+ heci_reset_iamthif_params(dev);
+ dev->wd_due_counter = 0;
+ dev->extra_write_index = 0;
+ }
+
+ dev->num_heci_me_clients = 0;
+ dev->rd_msg_hdr = 0;
+ dev->stop = 0;
+ dev->wd_pending = 0;
+
+ /* update the state of the registers after reset */
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+
+ DBG("after reset host_hw_state = 0x%08x, me_hw_state = 0x%08x.\n",
+ dev->host_hw_state, dev->me_hw_state);
+
+ if (unexpected)
+ printk(KERN_WARNING "heci: unexpected reset.\n");
+
+ /* Wake up all readings so they can be interrupted */
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if (&file_pos->rx_wait &&
+ waitqueue_active(&file_pos->rx_wait)) {
+ printk(KERN_INFO "heci: Waking up client!\n");
+ wake_up_interruptible(&file_pos->rx_wait);
+ }
+ }
+ /* remove all waiting requests */
+ if (dev->write_list.status == 0 &&
+ !list_empty(&dev->write_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->write_list.heci_cb.cb_list, cb_list) {
+ if (priv_cb_pos) {
+ list_del(&priv_cb_pos->cb_list);
+ heci_free_cb_private(priv_cb_pos);
+ }
+ }
+ }
+}
+
+/**
+ * heci_initialize_clients - heci communication initialization.
+ *
+ * @dev: Device object for our driver
+ */
+int heci_initialize_clients(struct iamt_heci_device *dev)
+{
+ int status;
+
+ msleep(100); /* FW needs time to be ready to talk with us */
+ DBG("link is established start sending messages.\n");
+ /* link is established start sending messages. */
+ status = host_start_message(dev);
+ if (status != 0) {
+ spin_lock_bh(&dev->device_lock);
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("start sending messages failed.\n");
+ return status;
+ }
+
+ /* enumerate clients */
+ status = host_enum_clients_message(dev);
+ if (status != 0) {
+ spin_lock_bh(&dev->device_lock);
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("enum clients failed.\n");
+ return status;
+ }
+ /* allocate storage for ME clients representation */
+ status = allocate_me_clients_storage(dev);
+ if (status != 0) {
+ spin_lock_bh(&dev->device_lock);
+ dev->num_heci_me_clients = 0;
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("allocate clients failed.\n");
+ return status;
+ }
+
+ heci_check_asf_mode(dev);
+ /*heci initialization wd */
+ host_init_wd(dev);
+ /*heci initialization iamthif client */
+ host_init_iamthif(dev);
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->need_reset) {
+ dev->need_reset = 0;
+ dev->heci_state = HECI_DISABLED;
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+
+ memset(dev->heci_host_clients, 0, sizeof(dev->heci_host_clients));
+ dev->open_handle_count = 0;
+ dev->heci_host_clients[0] |= 7;
+ dev->current_host_client_id = 3;
+ dev->heci_state = HECI_ENABLED;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("initialization heci clients successful.\n");
+ return 0;
+}
+
+/**
+ * heci_task_initialize_clients - heci reinitialization task
+ *
+ * @data: Device object for our driver
+ */
+int heci_task_initialize_clients(void *data)
+{
+ int ret;
+ struct iamt_heci_device *dev = (struct iamt_heci_device *) data;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->reinit_tsk != NULL) {
+ spin_unlock_bh(&dev->device_lock);
+ DBG("reinit task already started.\n");
+ return 0;
+ }
+ dev->reinit_tsk = current;
+ current->flags |= PF_NOFREEZE;
+ spin_unlock_bh(&dev->device_lock);
+
+ ret = heci_initialize_clients(dev);
+
+ spin_lock_bh(&dev->device_lock);
+ dev->reinit_tsk = NULL;
+ spin_unlock_bh(&dev->device_lock);
+
+ return ret;
+}
+
+/**
+ * host_start_message - heci host send start message.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_start_message(struct iamt_heci_device *dev)
+{
+ long timeout = 60; /* 60 second */
+
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_host_version_request *host_start_req;
+ struct hbm_host_stop_request *host_stop_req;
+ int err = 0;
+
+ /* host start message */
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_version_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_start_req =
+ (struct hbm_host_version_request *) &dev->wr_msg_buf[1];
+ memset(host_start_req, 0, sizeof(struct hbm_host_version_request));
+ host_start_req->cmd.cmd = HOST_START_REQ_CMD;
+ host_start_req->host_version.major_version = HBM_MAJOR_VERSION;
+ host_start_req->host_version.minor_version = HBM_MINOR_VERSION;
+ dev->recvd_msg = 0;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_start_req),
+ heci_hdr->length)) {
+ DBG("send version to fw fail.\n");
+ return -ENODEV;
+ }
+ DBG("call wait_event_interruptible_timeout for response message.\n");
+ /* wait for response */
+ err = heci_wait_event_int_timeout(dev, timeout * HZ);
+ if (!err && !dev->recvd_msg) {
+ DBG("wait_timeout failed on host start response message.\n");
+ return -ENODEV;
+ }
+ dev->recvd_msg = 0;
+ DBG("wait_timeout successful on host start response message.\n");
+ if ((dev->version.major_version != HBM_MAJOR_VERSION) ||
+ (dev->version.minor_version != HBM_MINOR_VERSION)) {
+ /* send stop message */
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_stop_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_stop_req =
+ (struct hbm_host_stop_request *) &dev->wr_msg_buf[1];
+
+ memset(host_stop_req, 0, sizeof(struct hbm_host_stop_request));
+ host_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+ host_stop_req->reason = DRIVER_STOP_REQUEST;
+ heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_stop_req),
+ heci_hdr->length);
+ DBG("version mismatch.\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+/**
+ * host_enum_clients_message - host send enumeration client request message.
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_enum_clients_message(struct iamt_heci_device *dev)
+{
+ long timeout = 5; /*5 second */
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_host_enum_request *host_enum_req;
+ int err = 0;
+ int i, j;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ /* enumerate clients */
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_enum_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_enum_req = (struct hbm_host_enum_request *) &dev->wr_msg_buf[1];
+ memset(host_enum_req, 0, sizeof(struct hbm_host_enum_request));
+ host_enum_req->cmd.cmd = HOST_ENUM_REQ_CMD;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_enum_req),
+ heci_hdr->length)) {
+ DBG("send enumeration request failed.\n");
+ return -ENODEV;
+ }
+ /* wait for response */
+ dev->recvd_msg = 0;
+ err = heci_wait_event_int_timeout(dev, timeout * HZ);
+ if (!err && !dev->recvd_msg) {
+ DBG("wait_event_interruptible_timeout failed "
+ "on enumeration clients response message.\n");
+ return -ENODEV;
+ }
+ dev->recvd_msg = 0;
+
+ spin_lock_bh(&dev->device_lock);
+ /* count how many ME clients we have */
+ for (i = 0; i < sizeof(dev->heci_me_clients); i++) {
+ for (j = 0; j < 8; j++) {
+ if ((dev->heci_me_clients[i] & (1 << j)) != 0)
+ dev->num_heci_me_clients++;
+
+ }
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ return 0;
+}
+
+/**
+ * host_client_properties - reads properties for client
+ *
+ * @dev: Device object for our driver
+ * @idx: client index in me client array
+ * @client_id: id of the client
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int host_client_properties(struct iamt_heci_device *dev,
+ struct heci_me_client *client)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_props_request *host_cli_req;
+ int err;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_props_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ host_cli_req = (struct hbm_props_request *) &dev->wr_msg_buf[1];
+ memset(host_cli_req, 0, sizeof(struct hbm_props_request));
+ host_cli_req->cmd.cmd = HOST_CLIENT_PROPERTEIS_REQ_CMD;
+ host_cli_req->address = client->client_id;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) (host_cli_req),
+ heci_hdr->length)) {
+ DBG("send props request failed.\n");
+ return -ENODEV;
+ }
+ /* wait for response */
+ dev->recvd_msg = 0;
+ err = heci_wait_event_int_timeout(dev, 10 * HZ);
+ if (!err && !dev->recvd_msg) {
+ DBG("wait failed on props resp msg.\n");
+ return -ENODEV;
+ }
+ dev->recvd_msg = 0;
+ return 0;
+}
+
+/**
+ * allocate_me_clients_storage - allocate storage for me clients
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int allocate_me_clients_storage(struct iamt_heci_device *dev)
+{
+ struct heci_me_client *clients;
+ struct heci_me_client *client;
+ __u8 num, i, j;
+ int err;
+
+ if (dev->num_heci_me_clients <= 0)
+ return 0;
+
+ spin_lock_bh(&dev->device_lock);
+ kfree(dev->me_clients);
+ dev->me_clients = NULL;
+ spin_unlock_bh(&dev->device_lock);
+
+ /* allocate storage for ME clients representation */
+ clients = kcalloc(dev->num_heci_me_clients,
+ sizeof(struct heci_me_client), GFP_KERNEL);
+ if (!clients) {
+ DBG("memory allocation for ME clients failed.\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ dev->me_clients = clients;
+ spin_unlock_bh(&dev->device_lock);
+
+ num = 0;
+ for (i = 0; i < sizeof(dev->heci_me_clients); i++) {
+ for (j = 0; j < 8; j++) {
+ if ((dev->heci_me_clients[i] & (1 << j)) != 0) {
+ client = &dev->me_clients[num];
+ client->client_id = (i * 8) + j;
+ client->flow_ctrl_creds = 0;
+ err = host_client_properties(dev, client);
+ if (err != 0) {
+ spin_lock_bh(&dev->device_lock);
+ kfree(dev->me_clients);
+ dev->me_clients = NULL;
+ spin_unlock_bh(&dev->device_lock);
+ return err;
+ }
+ num++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * heci_init_file_private - initializes private file structure.
+ *
+ * @priv: private file structure to be initialized
+ * @file: the file structure
+ */
+static void heci_init_file_private(struct heci_file_private *priv,
+ struct file *file)
+{
+ memset(priv, 0, sizeof(struct heci_file_private));
+ spin_lock_init(&priv->file_lock);
+ spin_lock_init(&priv->read_io_lock);
+ spin_lock_init(&priv->write_io_lock);
+ init_waitqueue_head(&priv->wait);
+ init_waitqueue_head(&priv->rx_wait);
+ DBG("priv->rx_wait =%p\n", &priv->rx_wait);
+ init_waitqueue_head(&priv->tx_wait);
+ INIT_LIST_HEAD(&priv->link);
+ priv->reading_state = HECI_IDLE;
+ priv->writing_state = HECI_IDLE;
+}
+
+/**
+ * heci_find_me_client - search for ME client guid
+ * sets client_id in heci_file_private if found
+ * @dev: Device object for our driver
+ * @priv: private file structure to set client_id in
+ * @cguid: searched guid of ME client
+ * @client_id: id of host client to be set in file private structure
+ *
+ * returns ME client index
+ */
+static __u8 heci_find_me_client(struct iamt_heci_device *dev,
+ struct heci_file_private *priv,
+ const struct guid *cguid, __u8 client_id)
+{
+ __u8 i;
+
+ if ((dev == NULL) || (priv == NULL) || (cguid == NULL))
+ return 0;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp(cguid,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ priv->me_client_id = dev->me_clients[i].client_id;
+ priv->state = HECI_FILE_CONNECTING;
+ priv->host_client_id = client_id;
+
+ list_add_tail(&priv->link, &dev->file_list);
+ return i;
+ }
+ }
+ return 0;
+}
+
+/**
+ * heci_check_asf_mode - check for ASF client
+ *
+ * @dev: Device object for our driver
+ */
+static void heci_check_asf_mode(struct iamt_heci_device *dev)
+{
+ __u8 i;
+
+ spin_lock_bh(&dev->device_lock);
+ dev->asf_mode = 0;
+ /* find ME ASF client - otherwise assume AMT mode */
+ DBG("find ME ASF client - otherwise assume AMT mode.\n");
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp(&heci_asf_guid,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ dev->asf_mode = 1;
+ spin_unlock_bh(&dev->device_lock);
+ DBG("found ME ASF client.\n");
+ return;
+ }
+ }
+ spin_unlock_bh(&dev->device_lock);
+ DBG("assume AMT mode.\n");
+}
+
+/**
+ * heci_connect_me_client - connect ME client
+ * @dev: Device object for our driver
+ * @priv: private file structure
+ * @timeout: connect timeout in seconds
+ *
+ * returns 1 - if connected, 0 - if not
+ */
+static __u8 heci_connect_me_client(struct iamt_heci_device *dev,
+ struct heci_file_private *priv,
+ long timeout)
+{
+ int err = 0;
+
+ if ((dev == NULL) || (priv == NULL))
+ return 0;
+
+ if (!heci_connect(dev, priv)) {
+ DBG("failed to call heci_connect for client_id=%d.\n",
+ priv->host_client_id);
+ spin_lock_bh(&dev->device_lock);
+ heci_remove_client_from_file_list(dev, priv->host_client_id);
+ priv->state = HECI_FILE_DISCONNECTED;
+ spin_unlock_bh(&dev->device_lock);
+ return 0;
+ }
+
+ err = wait_event_timeout(dev->wait_recvd_msg,
+ (HECI_FILE_CONNECTED == priv->state ||
+ HECI_FILE_DISCONNECTED == priv->state),
+ timeout * HZ);
+ if (HECI_FILE_CONNECTED != priv->state) {
+ spin_lock_bh(&dev->device_lock);
+ heci_remove_client_from_file_list(dev, priv->host_client_id);
+ DBG("failed to connect client_id=%d state=%d.\n",
+ priv->host_client_id, priv->state);
+ if (err)
+ DBG("failed connect err=%08x\n", err);
+ priv->state = HECI_FILE_DISCONNECTED;
+ spin_unlock_bh(&dev->device_lock);
+ return 0;
+ }
+ DBG("successfully connected client_id=%d.\n",
+ priv->host_client_id);
+ return 1;
+}
+
+/**
+ * host_init_wd - heci initialization wd.
+ *
+ * @dev: Device object for our driver
+ */
+static void host_init_wd(struct iamt_heci_device *dev)
+{
+ spin_lock_bh(&dev->device_lock);
+
+ heci_init_file_private(&dev->wd_file_ext, NULL);
+
+ /* look for WD client and connect to it */
+ dev->wd_file_ext.state = HECI_FILE_DISCONNECTED;
+ dev->wd_timeout = 0;
+
+ if (dev->asf_mode) {
+ memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE);
+ } else {
+ /* AMT mode */
+ dev->wd_timeout = AMT_WD_VALUE;
+ DBG("dev->wd_timeout=%d.\n", dev->wd_timeout);
+ memcpy(dev->wd_data, heci_start_wd_params, HECI_WD_PARAMS_SIZE);
+ memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE,
+ &dev->wd_timeout, sizeof(__u16));
+ }
+
+ /* find ME WD client */
+ heci_find_me_client(dev, &dev->wd_file_ext,
+ &heci_wd_guid, HECI_WD_HOST_CLIENT_ID);
+ spin_unlock_bh(&dev->device_lock);
+
+ DBG("check wd_file_ext\n");
+ if (HECI_FILE_CONNECTING == dev->wd_file_ext.state) {
+ if (heci_connect_me_client(dev, &dev->wd_file_ext, 15) == 1) {
+ DBG("dev->wd_timeout=%d.\n", dev->wd_timeout);
+ if (dev->wd_timeout != 0)
+ dev->wd_due_counter = 1;
+ else
+ dev->wd_due_counter = 0;
+ DBG("successfully connected to WD client.\n");
+ }
+ } else
+ DBG("failed to find WD client.\n");
+
+
+ spin_lock_bh(&dev->device_lock);
+ dev->wd_timer.function = &heci_wd_timer;
+ dev->wd_timer.data = (unsigned long) dev;
+ spin_unlock_bh(&dev->device_lock);
+}
+
+
+/**
+ * host_init_iamthif - heci initialization iamthif client.
+ *
+ * @dev: Device object for our driver
+ *
+ */
+static void host_init_iamthif(struct iamt_heci_device *dev)
+{
+ __u8 i;
+
+ spin_lock_bh(&dev->device_lock);
+
+ heci_init_file_private(&dev->iamthif_file_ext, NULL);
+ dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTED;
+
+ /* find ME PTHI client */
+ i = heci_find_me_client(dev, &dev->iamthif_file_ext,
+ &heci_pthi_guid, HECI_IAMTHIF_HOST_CLIENT_ID);
+ if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTING) {
+ DBG("failed to find iamthif client.\n");
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+
+ BUG_ON(dev->me_clients[i].props.max_msg_length != IAMTHIF_MTU);
+
+ spin_unlock_bh(&dev->device_lock);
+ if (heci_connect_me_client(dev, &dev->iamthif_file_ext, 15) == 1) {
+ DBG("connected to iamthif client.\n");
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ }
+}
+
+/**
+ * heci_alloc_file_private - allocates a private file structure and set it up.
+ * @file: the file structure
+ *
+ * returns The allocated file or NULL on failure
+ */
+struct heci_file_private *heci_alloc_file_private(struct file *file)
+{
+ struct heci_file_private *priv;
+
+ priv = kmalloc(sizeof(struct heci_file_private), GFP_KERNEL);
+ if (!priv)
+ return NULL;
+
+ heci_init_file_private(priv, file);
+
+ return priv;
+}
+
+
+
+/**
+ * heci_disconnect_host_client - send disconnect message to fw from host client.
+ *
+ * @dev: Device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_disconnect_host_client(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ int rets, err;
+ long timeout = 15; /* 15 seconds */
+ struct heci_cb_private *priv_cb;
+
+ if ((!dev) || (!file_ext))
+ return -ENODEV;
+
+ if (file_ext->state != HECI_FILE_DISCONNECTING)
+ return 0;
+
+ priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_cb)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&priv_cb->cb_list);
+ priv_cb->file_private = file_ext;
+ priv_cb->major_file_operations = HECI_CLOSE;
+ spin_lock_bh(&dev->device_lock);
+ if (dev->host_buffer_is_empty) {
+ dev->host_buffer_is_empty = 0;
+ if (heci_disconnect(dev, file_ext)) {
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_rd_list.heci_cb.cb_list);
+ } else {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ DBG("failed to call heci_disconnect.\n");
+ goto free;
+ }
+ } else {
+ DBG("add disconnect cb to control write list\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_wr_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ err = wait_event_timeout(dev->wait_recvd_msg,
+ (HECI_FILE_DISCONNECTED == file_ext->state),
+ timeout * HZ);
+ if (HECI_FILE_DISCONNECTED == file_ext->state) {
+ rets = 0;
+ DBG("successfully disconnected from fw client.\n");
+ } else {
+ rets = -ENODEV;
+ if (HECI_FILE_DISCONNECTED != file_ext->state)
+ DBG("wrong status client disconnect.\n");
+
+ if (err)
+ DBG("wait failed disconnect err=%08x\n", err);
+
+ DBG("failed to disconnect from fw client.\n");
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ heci_flush_list(&dev->ctrl_rd_list, file_ext);
+ heci_flush_list(&dev->ctrl_wr_list, file_ext);
+ spin_unlock_bh(&dev->device_lock);
+free:
+ heci_free_cb_private(priv_cb);
+ return rets;
+}
+
+/**
+ * heci_remove_client_from_file_list -
+ * remove file private data from device file list
+ *
+ * @dev: Device object for our driver
+ * @host_client_id: host client id to be removed
+ */
+void heci_remove_client_from_file_list(struct iamt_heci_device *dev,
+ __u8 host_client_id)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if (host_client_id == file_pos->host_client_id) {
+ DBG("remove host client = %d, ME client = %d\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ list_del_init(&file_pos->link);
+ break;
+ }
+ }
+}
diff --git a/drivers/staging/heci/heci_interface.c b/drivers/staging/heci/heci_interface.c
new file mode 100644
index 00000000000..c5f51a7ddf2
--- /dev/null
+++ b/drivers/staging/heci/heci_interface.c
@@ -0,0 +1,485 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+
+#include "heci.h"
+#include "heci_interface.h"
+
+
+/**
+ * heci_set_csr_register - write H_CSR register to the heci device
+ *
+ * @dev: device object for our driver
+ */
+void heci_set_csr_register(struct iamt_heci_device *dev)
+{
+ write_heci_register(dev, H_CSR, dev->host_hw_state);
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+}
+
+/**
+ * heci_csr_enable_interrupts - enable heci device interrupts
+ *
+ * @dev: device object for our driver
+ */
+void heci_csr_enable_interrupts(struct iamt_heci_device *dev)
+{
+ dev->host_hw_state |= H_IE;
+ heci_set_csr_register(dev);
+}
+
+/**
+ * heci_csr_disable_interrupts - disable heci device interrupts
+ *
+ * @dev: device object for our driver
+ */
+void heci_csr_disable_interrupts(struct iamt_heci_device *dev)
+{
+ dev->host_hw_state &= ~H_IE;
+ heci_set_csr_register(dev);
+}
+
+
+/**
+ * _host_get_filled_slots - get number of device filled buffer slots
+ *
+ * @device: the device structure
+ *
+ * returns numer of filled slots
+ */
+static unsigned char _host_get_filled_slots(const struct iamt_heci_device *dev)
+{
+ char read_ptr, write_ptr;
+
+ read_ptr = (char) ((dev->host_hw_state & H_CBRP) >> 8);
+ write_ptr = (char) ((dev->host_hw_state & H_CBWP) >> 16);
+
+ return (unsigned char) (write_ptr - read_ptr);
+}
+
+/**
+ * host_buffer_is_empty - check if host buffer is empty.
+ *
+ * @dev: device object for our driver
+ *
+ * returns 1 if empty, 0 - otherwise.
+ */
+int host_buffer_is_empty(struct iamt_heci_device *dev)
+{
+ unsigned char filled_slots;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ filled_slots = _host_get_filled_slots(dev);
+
+ if (filled_slots > 0)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * count_empty_write_slots - count write empty slots.
+ *
+ * @dev: device object for our driver
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise empty slots count
+ */
+__s32 count_empty_write_slots(const struct iamt_heci_device *dev)
+{
+ unsigned char buffer_depth, filled_slots, empty_slots;
+
+ buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+ filled_slots = _host_get_filled_slots(dev);
+ empty_slots = buffer_depth - filled_slots;
+
+ if (filled_slots > buffer_depth) {
+ /* overflow */
+ return -ESLOTS_OVERFLOW;
+ }
+
+ return (__s32) empty_slots;
+}
+
+/**
+ * heci_write_message - write a message to heci device.
+ *
+ * @dev: device object for our driver
+ * @heci_hdr: header of message
+ * @write_buffer: message buffer will be write
+ * @write_length: message size will be write
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_write_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *header,
+ unsigned char *write_buffer,
+ unsigned long write_length)
+{
+ __u32 temp_msg = 0;
+ unsigned long bytes_written = 0;
+ unsigned char buffer_depth, filled_slots, empty_slots;
+ unsigned long dw_to_write;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ DBG("host_hw_state = 0x%08x.\n", dev->host_hw_state);
+ DBG("heci_write_message header=%08x.\n", *((__u32 *) header));
+ buffer_depth = (unsigned char) ((dev->host_hw_state & H_CBD) >> 24);
+ filled_slots = _host_get_filled_slots(dev);
+ empty_slots = buffer_depth - filled_slots;
+ DBG("filled = %hu, empty = %hu.\n", filled_slots, empty_slots);
+
+ dw_to_write = ((write_length + 3) / 4);
+
+ if (dw_to_write > empty_slots)
+ return 0;
+
+ write_heci_register(dev, H_CB_WW, *((__u32 *) header));
+
+ while (write_length >= 4) {
+ write_heci_register(dev, H_CB_WW,
+ *(__u32 *) (write_buffer + bytes_written));
+ bytes_written += 4;
+ write_length -= 4;
+ }
+
+ if (write_length > 0) {
+ memcpy(&temp_msg, &write_buffer[bytes_written], write_length);
+ write_heci_register(dev, H_CB_WW, temp_msg);
+ }
+
+ dev->host_hw_state |= H_IG;
+ write_heci_register(dev, H_CSR, dev->host_hw_state);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+ if ((dev->me_hw_state & ME_RDY_HRA) != ME_RDY_HRA)
+ return 0;
+
+ dev->write_hang = 0;
+ return 1;
+}
+
+/**
+ * count_full_read_slots - count read full slots.
+ *
+ * @dev: device object for our driver
+ *
+ * returns -1(ESLOTS_OVERFLOW) if overflow, otherwise filled slots count
+ */
+__s32 count_full_read_slots(struct iamt_heci_device *dev)
+{
+ char read_ptr, write_ptr;
+ unsigned char buffer_depth, filled_slots;
+
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+ buffer_depth = (unsigned char)((dev->me_hw_state & ME_CBD_HRA) >> 24);
+ read_ptr = (char) ((dev->me_hw_state & ME_CBRP_HRA) >> 8);
+ write_ptr = (char) ((dev->me_hw_state & ME_CBWP_HRA) >> 16);
+ filled_slots = (unsigned char) (write_ptr - read_ptr);
+
+ if (filled_slots > buffer_depth) {
+ /* overflow */
+ return -ESLOTS_OVERFLOW;
+ }
+
+ DBG("filled_slots =%08x \n", filled_slots);
+ return (__s32) filled_slots;
+}
+
+/**
+ * heci_read_slots - read a message from heci device.
+ *
+ * @dev: device object for our driver
+ * @buffer: message buffer will be write
+ * @buffer_length: message size will be read
+ */
+void heci_read_slots(struct iamt_heci_device *dev,
+ unsigned char *buffer, unsigned long buffer_length)
+{
+ __u32 i = 0;
+ unsigned char temp_buf[sizeof(__u32)];
+
+ while (buffer_length >= sizeof(__u32)) {
+ ((__u32 *) buffer)[i] = read_heci_register(dev, ME_CB_RW);
+ DBG("buffer[%d]= %d\n", i, ((__u32 *) buffer)[i]);
+ i++;
+ buffer_length -= sizeof(__u32);
+ }
+
+ if (buffer_length > 0) {
+ *((__u32 *) &temp_buf) = read_heci_register(dev, ME_CB_RW);
+ memcpy(&buffer[i * 4], temp_buf, buffer_length);
+ }
+
+ dev->host_hw_state |= H_IG;
+ heci_set_csr_register(dev);
+}
+
+/**
+ * flow_ctrl_creds - check flow_control credentials.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if flow_ctrl_creds >0, 0 - otherwise.
+ */
+int flow_ctrl_creds(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ __u8 i;
+
+ if (!dev->num_heci_me_clients)
+ return 0;
+
+ if (file_ext == NULL)
+ return 0;
+
+ if (file_ext->flow_ctrl_creds > 0)
+ return 1;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+ if (dev->me_clients[i].flow_ctrl_creds > 0) {
+ BUG_ON(dev->me_clients[i].props.single_recv_buf
+ == 0);
+ return 1;
+ }
+ return 0;
+ }
+ }
+ BUG();
+ return 0;
+}
+
+/**
+ * flow_ctrl_reduce - reduce flow_control.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ */
+void flow_ctrl_reduce(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ __u8 i;
+
+ if (!dev->num_heci_me_clients)
+ return;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id) {
+ if (dev->me_clients[i].props.single_recv_buf != 0) {
+ BUG_ON(dev->me_clients[i].flow_ctrl_creds <= 0);
+ dev->me_clients[i].flow_ctrl_creds--;
+ } else {
+ BUG_ON(file_ext->flow_ctrl_creds <= 0);
+ file_ext->flow_ctrl_creds--;
+ }
+ return;
+ }
+ }
+ BUG();
+}
+
+/**
+ * heci_send_flow_control - send flow control to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_send_flow_control(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_flow_control *heci_flow_control;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_flow_control);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ heci_flow_control = (struct hbm_flow_control *) &dev->wr_msg_buf[1];
+ memset(heci_flow_control, 0, sizeof(heci_flow_control));
+ heci_flow_control->host_addr = file_ext->host_client_id;
+ heci_flow_control->me_addr = file_ext->me_client_id;
+ heci_flow_control->cmd.cmd = HECI_FLOW_CONTROL_CMD;
+ memset(heci_flow_control->reserved, 0,
+ sizeof(heci_flow_control->reserved));
+ DBG("sending flow control host client = %d, me client = %d\n",
+ file_ext->host_client_id, file_ext->me_client_id);
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) heci_flow_control,
+ sizeof(struct hbm_flow_control)))
+ return 0;
+
+ return 1;
+
+}
+
+/**
+ * other_client_is_connecting - check if other
+ * client with the same client id is connected.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if other client is connected, 0 - otherwise.
+ */
+int other_client_is_connecting(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if ((file_pos->state == HECI_FILE_CONNECTING)
+ && (file_pos != file_ext)
+ && file_ext->me_client_id == file_pos->me_client_id)
+ return 1;
+
+ }
+ return 0;
+}
+
+/**
+ * heci_send_wd - send watch dog message to fw.
+ *
+ * @dev: device object for our driver
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_send_wd(struct iamt_heci_device *dev)
+{
+ struct heci_msg_hdr *heci_hdr;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = dev->wd_file_ext.host_client_id;
+ heci_hdr->me_addr = dev->wd_file_ext.me_client_id;
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ if (!memcmp(dev->wd_data, heci_start_wd_params,
+ HECI_WD_PARAMS_SIZE)) {
+ heci_hdr->length = HECI_START_WD_DATA_SIZE;
+ } else {
+ BUG_ON(memcmp(dev->wd_data, heci_stop_wd_params,
+ HECI_WD_PARAMS_SIZE));
+ heci_hdr->length = HECI_WD_PARAMS_SIZE;
+ }
+
+ if (!heci_write_message(dev, heci_hdr, dev->wd_data, heci_hdr->length))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * heci_disconnect - send disconnect message to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_disconnect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_client_disconnect_request *heci_cli_disconnect;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_client_disconnect_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ heci_cli_disconnect =
+ (struct hbm_client_disconnect_request *) &dev->wr_msg_buf[1];
+ memset(heci_cli_disconnect, 0, sizeof(heci_cli_disconnect));
+ heci_cli_disconnect->host_addr = file_ext->host_client_id;
+ heci_cli_disconnect->me_addr = file_ext->me_client_id;
+ heci_cli_disconnect->cmd.cmd = CLIENT_DISCONNECT_REQ_CMD;
+ heci_cli_disconnect->reserved[0] = 0;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) heci_cli_disconnect,
+ sizeof(struct hbm_client_disconnect_request)))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * heci_connect - send connect message to fw.
+ *
+ * @dev: device object for our driver
+ * @file_ext: private data of the file object
+ *
+ * returns 1 if success, 0 - otherwise.
+ */
+int heci_connect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_client_connect_request *heci_cli_connect;
+
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_client_connect_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ heci_cli_connect =
+ (struct hbm_client_connect_request *) &dev->wr_msg_buf[1];
+ heci_cli_connect->host_addr = file_ext->host_client_id;
+ heci_cli_connect->me_addr = file_ext->me_client_id;
+ heci_cli_connect->cmd.cmd = CLIENT_CONNECT_REQ_CMD;
+ heci_cli_connect->reserved = 0;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *) heci_cli_connect,
+ sizeof(struct hbm_client_connect_request)))
+ return 0;
+
+ return 1;
+}
diff --git a/drivers/staging/heci/heci_interface.h b/drivers/staging/heci/heci_interface.h
new file mode 100644
index 00000000000..37336ebc0a5
--- /dev/null
+++ b/drivers/staging/heci/heci_interface.h
@@ -0,0 +1,170 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+
+#ifndef _HECI_INTERFACE_H_
+#define _HECI_INTERFACE_H_
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/timer.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/aio.h>
+#include <linux/types.h>
+#include "heci_data_structures.h"
+
+
+#define HBM_MINOR_VERSION 0
+#define HBM_MAJOR_VERSION 1
+#define HBM_TIMEOUT 1 /* 1 second */
+
+
+#define HOST_START_REQ_CMD 0x01
+#define HOST_START_RES_CMD 0x81
+
+#define HOST_STOP_REQ_CMD 0x02
+#define HOST_STOP_RES_CMD 0x82
+
+#define ME_STOP_REQ_CMD 0x03
+
+#define HOST_ENUM_REQ_CMD 0x04
+#define HOST_ENUM_RES_CMD 0x84
+
+#define HOST_CLIENT_PROPERTEIS_REQ_CMD 0x05
+#define HOST_CLIENT_PROPERTEIS_RES_CMD 0x85
+
+#define CLIENT_CONNECT_REQ_CMD 0x06
+#define CLIENT_CONNECT_RES_CMD 0x86
+
+#define CLIENT_DISCONNECT_REQ_CMD 0x07
+#define CLIENT_DISCONNECT_RES_CMD 0x87
+
+#define HECI_FLOW_CONTROL_CMD 0x08
+
+
+#define AMT_WD_VALUE 120 /* seconds */
+
+#define HECI_WATCHDOG_DATA_SIZE 16
+#define HECI_START_WD_DATA_SIZE 20
+#define HECI_WD_PARAMS_SIZE 4
+
+/* IOCTL commands */
+#define IOCTL_HECI_GET_VERSION \
+ _IOWR('H' , 0x0, struct heci_message_data)
+#define IOCTL_HECI_CONNECT_CLIENT \
+ _IOWR('H' , 0x01, struct heci_message_data)
+#define IOCTL_HECI_WD \
+ _IOWR('H' , 0x02, struct heci_message_data)
+#define IOCTL_HECI_BYPASS_WD \
+ _IOWR('H' , 0x10, struct heci_message_data)
+
+enum heci_stop_reason_types{
+ DRIVER_STOP_REQUEST = 0x00,
+ DEVICE_D1_ENTRY = 0x01,
+ DEVICE_D2_ENTRY = 0x02,
+ DEVICE_D3_ENTRY = 0x03,
+ SYSTEM_S1_ENTRY = 0x04,
+ SYSTEM_S2_ENTRY = 0x05,
+ SYSTEM_S3_ENTRY = 0x06,
+ SYSTEM_S4_ENTRY = 0x07,
+ SYSTEM_S5_ENTRY = 0x08
+};
+
+enum me_stop_reason_types{
+ FW_UPDATE = 0x00
+};
+
+enum client_connect_status_types{
+ CCS_SUCCESS = 0x00,
+ CCS_NOT_FOUND = 0x01,
+ CCS_ALREADY_STARTED = 0x02,
+ CCS_OUT_OF_RESOURCES = 0x03,
+ CCS_MESSAGE_SMALL = 0x04
+};
+
+enum client_disconnect_status_types{
+ CDS_SUCCESS = 0x00
+};
+
+
+/*
+ * heci interface function prototypes
+ */
+void heci_set_csr_register(struct iamt_heci_device *dev);
+void heci_csr_enable_interrupts(struct iamt_heci_device *dev);
+void heci_csr_disable_interrupts(struct iamt_heci_device *dev);
+
+void heci_read_slots(struct iamt_heci_device *dev,
+ unsigned char *buffer, unsigned long buffer_length);
+
+int heci_write_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *header,
+ unsigned char *write_buffer,
+ unsigned long write_length);
+
+int host_buffer_is_empty(struct iamt_heci_device *dev);
+
+__s32 count_full_read_slots(struct iamt_heci_device *dev);
+
+__s32 count_empty_write_slots(const struct iamt_heci_device *dev);
+
+int flow_ctrl_creds(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+int heci_send_wd(struct iamt_heci_device *dev);
+
+void flow_ctrl_reduce(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+int heci_send_flow_control(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+int heci_disconnect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+int other_client_is_connecting(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+int heci_connect(struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+
+#endif /* _HECI_INTERFACE_H_ */
diff --git a/drivers/staging/heci/heci_main.c b/drivers/staging/heci/heci_main.c
new file mode 100644
index 00000000000..00e44c78142
--- /dev/null
+++ b/drivers/staging/heci/heci_main.c
@@ -0,0 +1,1564 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/device.h>
+#include <linux/unistd.h>
+#include <linux/kthread.h>
+
+#include "heci.h"
+#include "heci_interface.h"
+#include "heci_version.h"
+
+
+#define HECI_READ_TIMEOUT 45
+
+#define HECI_DRIVER_NAME "heci"
+
+/*
+ * heci driver strings
+ */
+static char heci_driver_name[] = HECI_DRIVER_NAME;
+static char heci_driver_string[] = "Intel(R) Management Engine Interface";
+static char heci_driver_version[] = HECI_DRIVER_VERSION;
+static char heci_copyright[] = "Copyright (c) 2003 - 2008 Intel Corporation.";
+
+
+#ifdef HECI_DEBUG
+int heci_debug = 1;
+#else
+int heci_debug;
+#endif
+MODULE_PARM_DESC(heci_debug, "Debug enabled or not");
+module_param(heci_debug, int, 0644);
+
+
+#define HECI_DEV_NAME "heci"
+
+/* heci char device for registration */
+static struct cdev heci_cdev;
+
+/* major number for device */
+static int heci_major;
+/* The device pointer */
+static struct pci_dev *heci_device;
+
+static struct class *heci_class;
+
+
+/* heci_pci_tbl - PCI Device ID Table */
+static struct pci_device_id heci_pci_tbl[] = {
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82946GZ)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G35)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82Q965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82G965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GM965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_82GME965)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q35)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82G33)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82Q33)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_82X38)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_3200)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_6)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_7)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_8)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_9)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9_10)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_1)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_2)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_3)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH9M_4)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_1)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_2)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_3)},
+ {PCI_DEVICE(PCI_VENDOR_ID_INTEL, HECI_DEV_ID_ICH10_4)},
+ /* required last entry */
+ {0, }
+};
+
+MODULE_DEVICE_TABLE(pci, heci_pci_tbl);
+
+/*
+ * Local Function Prototypes
+ */
+static int __init heci_init_module(void);
+static void __exit heci_exit_module(void);
+static int __devinit heci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent);
+static void __devexit heci_remove(struct pci_dev *pdev);
+static int heci_open(struct inode *inode, struct file *file);
+static int heci_release(struct inode *inode, struct file *file);
+static ssize_t heci_read(struct file *file, char __user *ubuf,
+ size_t length, loff_t *offset);
+static int heci_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long data);
+static ssize_t heci_write(struct file *file, const char __user *ubuf,
+ size_t length, loff_t *offset);
+static unsigned int heci_poll(struct file *file, poll_table *wait);
+static struct heci_cb_private *find_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext);
+#ifdef CONFIG_PM
+static int heci_suspend(struct pci_dev *pdev, pm_message_t state);
+static int heci_resume(struct pci_dev *pdev);
+static __u16 g_sus_wd_timeout;
+#else
+#define heci_suspend NULL
+#define heci_resume NULL
+#endif
+/*
+ * PCI driver structure
+ */
+static struct pci_driver heci_driver = {
+ .name = heci_driver_name,
+ .id_table = heci_pci_tbl,
+ .probe = heci_probe,
+ .remove = __devexit_p(heci_remove),
+ .shutdown = __devexit_p(heci_remove),
+ .suspend = heci_suspend,
+ .resume = heci_resume
+};
+
+/*
+ * file operations structure will be use heci char device.
+ */
+static const struct file_operations heci_fops = {
+ .owner = THIS_MODULE,
+ .read = heci_read,
+ .ioctl = heci_ioctl,
+ .open = heci_open,
+ .release = heci_release,
+ .write = heci_write,
+ .poll = heci_poll,
+};
+
+/**
+ * heci_registration_cdev - set up the cdev structure for heci device.
+ *
+ * @dev: char device struct
+ * @hminor: minor number for registration char device
+ * @fops: file operations structure
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_registration_cdev(struct cdev *dev, int hminor,
+ const struct file_operations *fops)
+{
+ int ret, devno = MKDEV(heci_major, hminor);
+
+ cdev_init(dev, fops);
+ dev->owner = THIS_MODULE;
+ ret = cdev_add(dev, devno, 1);
+ /* Fail gracefully if need be */
+ if (ret) {
+ printk(KERN_ERR "heci: Error %d registering heci device %d\n",
+ ret, hminor);
+ }
+ return ret;
+}
+
+/* Display the version of heci driver. */
+static ssize_t version_show(struct class *dev, char *buf)
+{
+ return sprintf(buf, "%s %s.\n",
+ heci_driver_string, heci_driver_version);
+}
+
+static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
+
+/**
+ * heci_register_cdev - registers heci char device
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_register_cdev(void)
+{
+ int ret;
+ dev_t dev;
+
+ /* registration of char devices */
+ ret = alloc_chrdev_region(&dev, HECI_MINORS_BASE, HECI_MINORS_COUNT,
+ HECI_DRIVER_NAME);
+ if (ret) {
+ printk(KERN_ERR "heci: Error allocating char device region.\n");
+ return ret;
+ }
+
+ heci_major = MAJOR(dev);
+
+ ret = heci_registration_cdev(&heci_cdev, HECI_MINOR_NUMBER,
+ &heci_fops);
+ if (ret)
+ unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
+ HECI_MINORS_COUNT);
+
+ return ret;
+}
+
+/**
+ * heci_unregister_cdev - unregisters heci char device
+ */
+static void heci_unregister_cdev(void)
+{
+ cdev_del(&heci_cdev);
+ unregister_chrdev_region(MKDEV(heci_major, HECI_MINORS_BASE),
+ HECI_MINORS_COUNT);
+}
+
+#ifndef HECI_DEVICE_CREATE
+#define HECI_DEVICE_CREATE device_create
+#endif
+/**
+ * heci_sysfs_device_create - adds device entry to sysfs
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_sysfs_device_create(void)
+{
+ struct class *class;
+ void *tmphdev;
+ int err = 0;
+
+ class = class_create(THIS_MODULE, HECI_DRIVER_NAME);
+ if (IS_ERR(class)) {
+ err = PTR_ERR(class);
+ printk(KERN_ERR "heci: Error creating heci class.\n");
+ goto err_out;
+ }
+
+ err = class_create_file(class, &class_attr_version);
+ if (err) {
+ class_destroy(class);
+ printk(KERN_ERR "heci: Error creating heci class file.\n");
+ goto err_out;
+ }
+
+ tmphdev = HECI_DEVICE_CREATE(class, NULL, heci_cdev.dev, NULL,
+ HECI_DEV_NAME);
+ if (IS_ERR(tmphdev)) {
+ err = PTR_ERR(tmphdev);
+ class_remove_file(class, &class_attr_version);
+ class_destroy(class);
+ goto err_out;
+ }
+
+ heci_class = class;
+err_out:
+ return err;
+}
+
+/**
+ * heci_sysfs_device_remove - unregisters the device entry on sysfs
+ */
+static void heci_sysfs_device_remove(void)
+{
+ if ((heci_class == NULL) || (IS_ERR(heci_class)))
+ return;
+
+ device_destroy(heci_class, heci_cdev.dev);
+ class_remove_file(heci_class, &class_attr_version);
+ class_destroy(heci_class);
+}
+
+/**
+ * heci_init_module - Driver Registration Routine
+ *
+ * heci_init_module is the first routine called when the driver is
+ * loaded. All it does is register with the PCI subsystem.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __init heci_init_module(void)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "heci: %s - version %s\n", heci_driver_string,
+ heci_driver_version);
+ printk(KERN_INFO "heci: %s\n", heci_copyright);
+
+ /* init pci module */
+ ret = pci_register_driver(&heci_driver);
+ if (ret < 0) {
+ printk(KERN_ERR "heci: Error registering driver.\n");
+ goto end;
+ }
+
+ ret = heci_register_cdev();
+ if (ret)
+ goto unregister_pci;
+
+ ret = heci_sysfs_device_create();
+ if (ret)
+ goto unregister_cdev;
+
+ return ret;
+
+unregister_cdev:
+ heci_unregister_cdev();
+unregister_pci:
+ pci_unregister_driver(&heci_driver);
+end:
+ return ret;
+}
+
+module_init(heci_init_module);
+
+
+/**
+ * heci_exit_module - Driver Exit Cleanup Routine
+ *
+ * heci_exit_module is called just before the driver is removed
+ * from memory.
+ */
+static void __exit heci_exit_module(void)
+{
+ pci_unregister_driver(&heci_driver);
+ heci_sysfs_device_remove();
+ heci_unregister_cdev();
+}
+
+module_exit(heci_exit_module);
+
+
+/**
+ * heci_probe - Device Initialization Routine
+ *
+ * @pdev: PCI device information struct
+ * @ent: entry in kcs_pci_tbl
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int __devinit heci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct iamt_heci_device *dev = NULL;
+ int i, err = 0;
+
+ if (heci_device) {
+ err = -EEXIST;
+ goto end;
+ }
+ /* enable pci dev */
+ err = pci_enable_device(pdev);
+ if (err) {
+ printk(KERN_ERR "heci: Failed to enable pci device.\n");
+ goto end;
+ }
+ /* set PCI host mastering */
+ pci_set_master(pdev);
+ /* pci request regions for heci driver */
+ err = pci_request_regions(pdev, heci_driver_name);
+ if (err) {
+ printk(KERN_ERR "heci: Failed to get pci regions.\n");
+ goto disable_device;
+ }
+ /* allocates and initializes the heci dev structure */
+ dev = init_heci_device(pdev);
+ if (!dev) {
+ err = -ENOMEM;
+ goto release_regions;
+ }
+ /* mapping IO device memory */
+ for (i = 0; i <= 5; i++) {
+ if (pci_resource_len(pdev, i) == 0)
+ continue;
+ if (pci_resource_flags(pdev, i) & IORESOURCE_IO) {
+ printk(KERN_ERR "heci: heci has IO ports.\n");
+ goto free_device;
+ } else if (pci_resource_flags(pdev, i) & IORESOURCE_MEM) {
+ if (dev->mem_base) {
+ printk(KERN_ERR
+ "heci: Too many mem addresses.\n");
+ goto free_device;
+ }
+ dev->mem_base = pci_resource_start(pdev, i);
+ dev->mem_length = pci_resource_len(pdev, i);
+ }
+ }
+ if (!dev->mem_base) {
+ printk(KERN_ERR "heci: No address to use.\n");
+ err = -ENODEV;
+ goto free_device;
+ }
+ dev->mem_addr = ioremap_nocache(dev->mem_base,
+ dev->mem_length);
+ if (!dev->mem_addr) {
+ printk(KERN_ERR "heci: Remap IO device memory failure.\n");
+ err = -ENOMEM;
+ goto free_device;
+ }
+ /* request and enable interrupt */
+ err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
+ heci_driver_name, dev);
+ if (err) {
+ printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
+ pdev->irq);
+ goto unmap_memory;
+ }
+
+ if (heci_hw_init(dev)) {
+ printk(KERN_ERR "heci: Init hw failure.\n");
+ err = -ENODEV;
+ goto release_irq;
+ }
+ init_timer(&dev->wd_timer);
+
+ heci_initialize_clients(dev);
+ if (dev->heci_state != HECI_ENABLED) {
+ err = -ENODEV;
+ goto release_hw;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ heci_device = pdev;
+ pci_set_drvdata(pdev, dev);
+ spin_unlock_bh(&dev->device_lock);
+
+ if (dev->wd_timeout)
+ mod_timer(&dev->wd_timer, jiffies);
+
+#ifdef CONFIG_PM
+ g_sus_wd_timeout = 0;
+#endif
+ printk(KERN_INFO "heci driver initialization successful.\n");
+ return 0;
+
+release_hw:
+ /* disable interrupts */
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ heci_csr_disable_interrupts(dev);
+
+ del_timer_sync(&dev->wd_timer);
+
+ flush_scheduled_work();
+
+release_irq:
+ free_irq(pdev->irq, dev);
+unmap_memory:
+ if (dev->mem_addr)
+ iounmap(dev->mem_addr);
+free_device:
+ kfree(dev);
+release_regions:
+ pci_release_regions(pdev);
+disable_device:
+ pci_disable_device(pdev);
+end:
+ printk(KERN_ERR "heci driver initialization failed.\n");
+ return err;
+}
+
+/**
+ * heci_remove - Device Removal Routine
+ *
+ * @pdev: PCI device information struct
+ *
+ * heci_remove is called by the PCI subsystem to alert the driver
+ * that it should release a PCI device.
+ */
+static void __devexit heci_remove(struct pci_dev *pdev)
+{
+ struct iamt_heci_device *dev = pci_get_drvdata(pdev);
+
+ if (heci_device != pdev)
+ return;
+
+ if (dev == NULL)
+ return;
+
+ spin_lock_bh(&dev->device_lock);
+ if (heci_device != pdev) {
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+
+ if (dev->reinit_tsk != NULL) {
+ kthread_stop(dev->reinit_tsk);
+ dev->reinit_tsk = NULL;
+ }
+
+ del_timer_sync(&dev->wd_timer);
+ if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
+ && dev->wd_timeout) {
+ dev->wd_timeout = 0;
+ dev->wd_due_counter = 0;
+ memcpy(dev->wd_data, heci_stop_wd_params, HECI_WD_PARAMS_SIZE);
+ dev->stop = 1;
+ if (dev->host_buffer_is_empty &&
+ flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ dev->host_buffer_is_empty = 0;
+
+ if (!heci_send_wd(dev))
+ DBG("send stop WD failed\n");
+ else
+ flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+ dev->wd_pending = 0;
+ } else {
+ dev->wd_pending = 1;
+ }
+ dev->wd_stoped = 0;
+ spin_unlock_bh(&dev->device_lock);
+
+ wait_event_interruptible_timeout(dev->wait_stop_wd,
+ (dev->wd_stoped), 10 * HZ);
+ spin_lock_bh(&dev->device_lock);
+ if (!dev->wd_stoped)
+ DBG("stop wd failed to complete.\n");
+ else
+ DBG("stop wd complete.\n");
+
+ }
+
+ heci_device = NULL;
+ spin_unlock_bh(&dev->device_lock);
+
+ if (dev->iamthif_file_ext.state == HECI_FILE_CONNECTED) {
+ dev->iamthif_file_ext.state = HECI_FILE_DISCONNECTING;
+ heci_disconnect_host_client(dev,
+ &dev->iamthif_file_ext);
+ }
+ if (dev->wd_file_ext.state == HECI_FILE_CONNECTED) {
+ dev->wd_file_ext.state = HECI_FILE_DISCONNECTING;
+ heci_disconnect_host_client(dev,
+ &dev->wd_file_ext);
+ }
+
+ spin_lock_bh(&dev->device_lock);
+
+ /* remove entry if already in list */
+ DBG("list del iamthif and wd file list.\n");
+ heci_remove_client_from_file_list(dev, dev->wd_file_ext.
+ host_client_id);
+ heci_remove_client_from_file_list(dev,
+ dev->iamthif_file_ext.host_client_id);
+
+ dev->iamthif_current_cb = NULL;
+ dev->iamthif_file_ext.file = NULL;
+ dev->num_heci_me_clients = 0;
+
+ spin_unlock_bh(&dev->device_lock);
+
+ flush_scheduled_work();
+
+ /* disable interrupts */
+ heci_csr_disable_interrupts(dev);
+
+ free_irq(pdev->irq, dev);
+ pci_set_drvdata(pdev, NULL);
+
+ if (dev->mem_addr)
+ iounmap(dev->mem_addr);
+
+ kfree(dev);
+
+ pci_release_regions(pdev);
+ pci_disable_device(pdev);
+}
+
+/**
+ * heci_clear_list - remove all callbacks associated with file
+ * from heci_cb_list
+ *
+ * @file: file information struct
+ * @heci_cb_list: callbacks list
+ *
+ * heci_clear_list is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns 1 if callback removed from the list, 0 otherwise
+ */
+static int heci_clear_list(struct iamt_heci_device *dev,
+ struct file *file, struct list_head *heci_cb_list)
+{
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ struct file *file_temp;
+ int rets = 0;
+
+ /* list all list member */
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ heci_cb_list, cb_list) {
+ file_temp = (struct file *)priv_cb_pos->file_object;
+ /* check if list member associated with a file */
+ if (file_temp == file) {
+ /* remove member from the list */
+ list_del(&priv_cb_pos->cb_list);
+ /* check if cb equal to current iamthif cb */
+ if (dev->iamthif_current_cb == priv_cb_pos) {
+ dev->iamthif_current_cb = NULL;
+ /* send flow control to iamthif client */
+ heci_send_flow_control(dev,
+ &dev->iamthif_file_ext);
+ }
+ /* free all allocated buffers */
+ heci_free_cb_private(priv_cb_pos);
+ rets = 1;
+ }
+ }
+ return rets;
+}
+
+/**
+ * heci_clear_lists - remove all callbacks associated with file
+ *
+ * @dev: device information struct
+ * @file: file information struct
+ *
+ * heci_clear_lists is called to clear resources associated with file
+ * when application calls close function or Ctrl-C was pressed
+ *
+ * returns 1 if callback removed from the list, 0 otherwise
+ */
+static int heci_clear_lists(struct iamt_heci_device *dev, struct file *file)
+{
+ int rets = 0;
+
+ /* remove callbacks associated with a file */
+ heci_clear_list(dev, file, &dev->pthi_cmd_list.heci_cb.cb_list);
+ if (heci_clear_list(dev, file,
+ &dev->pthi_read_complete_list.heci_cb.cb_list))
+ rets = 1;
+
+ heci_clear_list(dev, file, &dev->ctrl_rd_list.heci_cb.cb_list);
+
+ if (heci_clear_list(dev, file, &dev->ctrl_wr_list.heci_cb.cb_list))
+ rets = 1;
+
+ if (heci_clear_list(dev, file,
+ &dev->write_waiting_list.heci_cb.cb_list))
+ rets = 1;
+
+ if (heci_clear_list(dev, file, &dev->write_list.heci_cb.cb_list))
+ rets = 1;
+
+ /* check if iamthif_current_cb not NULL */
+ if (dev->iamthif_current_cb && (!rets)) {
+ /* check file and iamthif current cb association */
+ if (dev->iamthif_current_cb->file_object == file) {
+ /* remove cb */
+ heci_free_cb_private(dev->iamthif_current_cb);
+ dev->iamthif_current_cb = NULL;
+ rets = 1;
+ }
+ }
+ return rets;
+}
+
+/**
+ * heci_open - the open function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int heci_open(struct inode *inode, struct file *file)
+{
+ struct heci_file_private *file_ext;
+ int if_num = iminor(inode);
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev))
+ return -ENODEV;
+
+ file_ext = heci_alloc_file_private(file);
+ if (file_ext == NULL)
+ return -ENOMEM;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ kfree(file_ext);
+ return -ENODEV;
+ }
+ if (dev->open_handle_count >= HECI_MAX_OPEN_HANDLE_COUNT) {
+ spin_unlock_bh(&dev->device_lock);
+ kfree(file_ext);
+ return -ENFILE;
+ };
+ dev->open_handle_count++;
+ list_add_tail(&file_ext->link, &dev->file_list);
+ while ((dev->heci_host_clients[dev->current_host_client_id / 8]
+ & (1 << (dev->current_host_client_id % 8))) != 0) {
+
+ dev->current_host_client_id++; /* allow overflow */
+ DBG("current_host_client_id = %d\n",
+ dev->current_host_client_id);
+ DBG("dev->open_handle_count = %lu\n",
+ dev->open_handle_count);
+ }
+ DBG("current_host_client_id = %d\n", dev->current_host_client_id);
+ file_ext->host_client_id = dev->current_host_client_id;
+ dev->heci_host_clients[file_ext->host_client_id / 8] |=
+ (1 << (file_ext->host_client_id % 8));
+ spin_unlock_bh(&dev->device_lock);
+ spin_lock(&file_ext->file_lock);
+ file_ext->state = HECI_FILE_INITIALIZING;
+ file_ext->sm_state = 0;
+
+ file->private_data = file_ext;
+ spin_unlock(&file_ext->file_lock);
+
+ return 0;
+}
+
+/**
+ * heci_release - the release function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ *
+ * returns 0 on success, <0 on error
+ */
+static int heci_release(struct inode *inode, struct file *file)
+{
+ int rets = 0;
+ int if_num = iminor(inode);
+ struct heci_file_private *file_ext = file->private_data;
+ struct heci_cb_private *priv_cb = NULL;
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ if (file_ext != &dev->iamthif_file_ext) {
+ spin_lock(&file_ext->file_lock);
+ if (file_ext->state == HECI_FILE_CONNECTED) {
+ file_ext->state = HECI_FILE_DISCONNECTING;
+ spin_unlock(&file_ext->file_lock);
+ DBG("disconnecting client host client = %d, "
+ "ME client = %d\n",
+ file_ext->host_client_id,
+ file_ext->me_client_id);
+ rets = heci_disconnect_host_client(dev, file_ext);
+ spin_lock(&file_ext->file_lock);
+ }
+ spin_lock_bh(&dev->device_lock);
+ heci_flush_queues(dev, file_ext);
+ DBG("remove client host client = %d, ME client = %d\n",
+ file_ext->host_client_id,
+ file_ext->me_client_id);
+
+ if (dev->open_handle_count > 0) {
+ dev->heci_host_clients[file_ext->host_client_id / 8] &=
+ ~(1 << (file_ext->host_client_id % 8));
+ dev->open_handle_count--;
+ }
+ heci_remove_client_from_file_list(dev,
+ file_ext->host_client_id);
+
+ /* free read cb */
+ if (file_ext->read_cb != NULL) {
+ priv_cb = find_read_list_entry(dev, file_ext);
+ /* Remove entry from read list */
+ if (priv_cb != NULL)
+ list_del(&priv_cb->cb_list);
+
+ priv_cb = file_ext->read_cb;
+ file_ext->read_cb = NULL;
+ }
+
+ spin_unlock_bh(&dev->device_lock);
+ file->private_data = NULL;
+ spin_unlock(&file_ext->file_lock);
+
+ if (priv_cb != NULL)
+ heci_free_cb_private(priv_cb);
+
+ kfree(file_ext);
+ } else {
+ spin_lock_bh(&dev->device_lock);
+
+ if (dev->open_handle_count > 0)
+ dev->open_handle_count--;
+
+ if (dev->iamthif_file_object == file
+ && dev->iamthif_state != HECI_IAMTHIF_IDLE) {
+ DBG("pthi canceled iamthif state %d\n",
+ dev->iamthif_state);
+ dev->iamthif_canceled = 1;
+ if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE) {
+ DBG("run next pthi iamthif cb\n");
+ run_next_iamthif_cmd(dev);
+ }
+ }
+
+ if (heci_clear_lists(dev, file))
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+
+ spin_unlock_bh(&dev->device_lock);
+ }
+ return rets;
+}
+
+static struct heci_cb_private *find_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct heci_file_private *file_ext)
+{
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ struct heci_file_private *file_ext_list_temp;
+
+ if (dev->read_list.status == 0
+ && !list_empty(&dev->read_list.heci_cb.cb_list)) {
+ DBG("remove read_list CB \n");
+ list_for_each_entry_safe(priv_cb_pos,
+ priv_cb_next,
+ &dev->read_list.heci_cb.cb_list, cb_list) {
+
+ file_ext_list_temp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if ((file_ext_list_temp != NULL) &&
+ heci_fe_same_id(file_ext, file_ext_list_temp))
+ return priv_cb_pos;
+
+ }
+ }
+ return NULL;
+}
+
+/**
+ * heci_read - the read client message function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t heci_read(struct file *file, char __user *ubuf,
+ size_t length, loff_t *offset)
+{
+ int i;
+ int rets = 0, err = 0;
+ int if_num = iminor(file->f_dentry->d_inode);
+ struct heci_file_private *file_ext = file->private_data;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb = NULL;
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ spin_lock(&file_ext->file_lock);
+ if ((file_ext->sm_state & HECI_WD_STATE_INDEPENDENCE_MSG_SENT) == 0) {
+ spin_unlock(&file_ext->file_lock);
+ /* Do not allow to read watchdog client */
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp(&heci_wd_guid,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ if (file_ext->me_client_id ==
+ dev->me_clients[i].client_id)
+ return -EBADF;
+ }
+ }
+ } else {
+ file_ext->sm_state &= ~HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
+ spin_unlock(&file_ext->file_lock);
+ }
+
+ if (file_ext == &dev->iamthif_file_ext) {
+ rets = pthi_read(dev, if_num, file, ubuf, length, offset);
+ goto out;
+ }
+
+ if (file_ext->read_cb && file_ext->read_cb->information > *offset) {
+ priv_cb = file_ext->read_cb;
+ goto copy_buffer;
+ } else if (file_ext->read_cb && file_ext->read_cb->information > 0 &&
+ file_ext->read_cb->information <= *offset) {
+ priv_cb = file_ext->read_cb;
+ rets = 0;
+ goto free;
+ } else if ((!file_ext->read_cb || file_ext->read_cb->information == 0)
+ && *offset > 0) {
+ /*Offset needs to be cleaned for contingous reads*/
+ *offset = 0;
+ rets = 0;
+ goto out;
+ }
+
+ spin_lock(&file_ext->read_io_lock);
+ err = heci_start_read(dev, if_num, file_ext);
+ if (err != 0 && err != -EBUSY) {
+ DBG("heci start read failure with status = %d\n", err);
+ spin_unlock(&file_ext->read_io_lock);
+ rets = err;
+ goto out;
+ }
+ if (HECI_READ_COMPLETE != file_ext->reading_state
+ && !waitqueue_active(&file_ext->rx_wait)) {
+ if (file->f_flags & O_NONBLOCK) {
+ rets = -EAGAIN;
+ spin_unlock(&file_ext->read_io_lock);
+ goto out;
+ }
+ spin_unlock(&file_ext->read_io_lock);
+
+ if (wait_event_interruptible(file_ext->rx_wait,
+ (HECI_READ_COMPLETE == file_ext->reading_state
+ || HECI_FILE_INITIALIZING == file_ext->state
+ || HECI_FILE_DISCONNECTED == file_ext->state
+ || HECI_FILE_DISCONNECTING == file_ext->state))) {
+ if (signal_pending(current)) {
+ rets = -EINTR;
+ goto out;
+ }
+ return -ERESTARTSYS;
+ }
+
+ if (HECI_FILE_INITIALIZING == file_ext->state ||
+ HECI_FILE_DISCONNECTED == file_ext->state ||
+ HECI_FILE_DISCONNECTING == file_ext->state) {
+ rets = -EBUSY;
+ goto out;
+ }
+ spin_lock(&file_ext->read_io_lock);
+ }
+
+ priv_cb = file_ext->read_cb;
+
+ if (!priv_cb) {
+ spin_unlock(&file_ext->read_io_lock);
+ return -ENODEV;
+ }
+ if (file_ext->reading_state != HECI_READ_COMPLETE) {
+ spin_unlock(&file_ext->read_io_lock);
+ return 0;
+ }
+ spin_unlock(&file_ext->read_io_lock);
+ /* now copy the data to user space */
+copy_buffer:
+ DBG("priv_cb->response_buffer size - %d\n",
+ priv_cb->response_buffer.size);
+ DBG("priv_cb->information - %lu\n",
+ priv_cb->information);
+ if (length == 0 || ubuf == NULL ||
+ *offset > priv_cb->information) {
+ rets = -EMSGSIZE;
+ goto free;
+ }
+
+ /* length is being turncated to PAGE_SIZE, however, */
+ /* information size may be longer */
+ length = (length < (priv_cb->information - *offset) ?
+ length : (priv_cb->information - *offset));
+
+ if (copy_to_user(ubuf,
+ priv_cb->response_buffer.data + *offset,
+ length)) {
+ rets = -EFAULT;
+ goto free;
+ }
+
+ rets = length;
+ *offset += length;
+ if ((unsigned long)*offset < priv_cb->information)
+ goto out;
+
+free:
+ spin_lock_bh(&dev->device_lock);
+ priv_cb_pos = find_read_list_entry(dev, file_ext);
+ /* Remove entry from read list */
+ if (priv_cb_pos != NULL)
+ list_del(&priv_cb_pos->cb_list);
+ spin_unlock_bh(&dev->device_lock);
+ heci_free_cb_private(priv_cb);
+ spin_lock(&file_ext->read_io_lock);
+ file_ext->reading_state = HECI_IDLE;
+ file_ext->read_cb = NULL;
+ file_ext->read_pending = 0;
+ spin_unlock(&file_ext->read_io_lock);
+out: DBG("end heci read rets= %d\n", rets);
+ return rets;
+}
+
+/**
+ * heci_write - the write function.
+ *
+ * @file: pointer to file structure
+ * @ubuf: pointer to user buffer
+ * @length: buffer length
+ * @offset: data offset in buffer
+ *
+ * returns >=0 data length on success , <0 on error
+ */
+static ssize_t heci_write(struct file *file, const char __user *ubuf,
+ size_t length, loff_t *offset)
+{
+ int rets = 0;
+ __u8 i;
+ int if_num = iminor(file->f_dentry->d_inode);
+ struct heci_file_private *file_ext = file->private_data;
+ struct heci_cb_private *priv_write_cb = NULL;
+ struct heci_msg_hdr heci_hdr;
+ struct iamt_heci_device *dev;
+ unsigned long currtime = get_seconds();
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ if (file_ext == &dev->iamthif_file_ext) {
+ priv_write_cb = find_pthi_read_list_entry(dev, file);
+ if ((priv_write_cb != NULL) &&
+ (((currtime - priv_write_cb->read_time) >
+ IAMTHIF_READ_TIMER) ||
+ (file_ext->reading_state == HECI_READ_COMPLETE))) {
+ (*offset) = 0;
+ list_del(&priv_write_cb->cb_list);
+ heci_free_cb_private(priv_write_cb);
+ priv_write_cb = NULL;
+ }
+ }
+
+ /* free entry used in read */
+ if (file_ext->reading_state == HECI_READ_COMPLETE) {
+ *offset = 0;
+ priv_write_cb = find_read_list_entry(dev, file_ext);
+ if (priv_write_cb != NULL) {
+ list_del(&priv_write_cb->cb_list);
+ heci_free_cb_private(priv_write_cb);
+ priv_write_cb = NULL;
+ spin_lock(&file_ext->read_io_lock);
+ file_ext->reading_state = HECI_IDLE;
+ file_ext->read_cb = NULL;
+ file_ext->read_pending = 0;
+ spin_unlock(&file_ext->read_io_lock);
+ }
+ } else if (file_ext->reading_state == HECI_IDLE &&
+ file_ext->read_pending == 0)
+ (*offset) = 0;
+
+ spin_unlock_bh(&dev->device_lock);
+
+ priv_write_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_write_cb)
+ return -ENOMEM;
+
+ priv_write_cb->file_object = file;
+ priv_write_cb->file_private = file_ext;
+ priv_write_cb->request_buffer.data = kmalloc(length, GFP_KERNEL);
+ if (!priv_write_cb->request_buffer.data) {
+ kfree(priv_write_cb);
+ return -ENOMEM;
+ }
+ DBG("length =%d\n", (int) length);
+
+ if (copy_from_user(priv_write_cb->request_buffer.data,
+ ubuf, length)) {
+ rets = -EFAULT;
+ goto fail;
+ }
+
+ spin_lock(&file_ext->file_lock);
+ file_ext->sm_state = 0;
+ if ((length == 4) &&
+ ((memcmp(heci_wd_state_independence_msg[0], ubuf, 4) == 0) ||
+ (memcmp(heci_wd_state_independence_msg[1], ubuf, 4) == 0) ||
+ (memcmp(heci_wd_state_independence_msg[2], ubuf, 4) == 0)))
+ file_ext->sm_state |= HECI_WD_STATE_INDEPENDENCE_MSG_SENT;
+ spin_unlock(&file_ext->file_lock);
+
+ INIT_LIST_HEAD(&priv_write_cb->cb_list);
+ if (file_ext == &dev->iamthif_file_ext) {
+ priv_write_cb->response_buffer.data =
+ kmalloc(IAMTHIF_MTU, GFP_KERNEL);
+ if (!priv_write_cb->response_buffer.data) {
+ rets = -ENOMEM;
+ goto fail;
+ }
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ goto fail;
+ }
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ dev->iamthif_file_ext.me_client_id)
+ break;
+ }
+
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if ((i == dev->num_heci_me_clients) ||
+ (dev->me_clients[i].client_id !=
+ dev->iamthif_file_ext.me_client_id)) {
+
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ goto fail;
+ } else if ((length > dev->me_clients[i].props.max_msg_length)
+ || (length <= 0)) {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -EMSGSIZE;
+ goto fail;
+ }
+
+
+ priv_write_cb->response_buffer.size = IAMTHIF_MTU;
+ priv_write_cb->major_file_operations = HECI_IOCTL;
+ priv_write_cb->information = 0;
+ priv_write_cb->request_buffer.size = length;
+ if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ENODEV;
+ goto fail;
+ }
+
+ if (!list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)
+ || dev->iamthif_state != HECI_IAMTHIF_IDLE) {
+ DBG("pthi_state = %d\n", (int) dev->iamthif_state);
+ DBG("add PTHI cb to pthi cmd waiting list\n");
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->pthi_cmd_list.heci_cb.cb_list);
+ rets = length;
+ } else {
+ DBG("call pthi write\n");
+ rets = pthi_write(dev, priv_write_cb);
+
+ if (rets != 0) {
+ DBG("pthi write failed with status = %d\n",
+ rets);
+ spin_unlock_bh(&dev->device_lock);
+ goto fail;
+ }
+ rets = length;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ return rets;
+ }
+
+ priv_write_cb->major_file_operations = HECI_WRITE;
+ /* make sure information is zero before we start */
+
+ priv_write_cb->information = 0;
+ priv_write_cb->request_buffer.size = length;
+
+ spin_lock(&file_ext->write_io_lock);
+ DBG("host client = %d, ME client = %d\n",
+ file_ext->host_client_id, file_ext->me_client_id);
+ if (file_ext->state != HECI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ DBG("host client = %d, is not connected to ME client = %d",
+ file_ext->host_client_id,
+ file_ext->me_client_id);
+
+ goto unlock;
+ }
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ file_ext->me_client_id)
+ break;
+ }
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if (i == dev->num_heci_me_clients) {
+ rets = -ENODEV;
+ goto unlock;
+ }
+ if (length > dev->me_clients[i].props.max_msg_length || length <= 0) {
+ rets = -EINVAL;
+ goto unlock;
+ }
+ priv_write_cb->file_private = file_ext;
+
+ spin_lock_bh(&dev->device_lock);
+ if (flow_ctrl_creds(dev, file_ext) &&
+ dev->host_buffer_is_empty) {
+ spin_unlock_bh(&dev->device_lock);
+ dev->host_buffer_is_empty = 0;
+ if (length > ((((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) - sizeof(struct heci_msg_hdr))) {
+
+ heci_hdr.length =
+ (((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) -
+ sizeof(struct heci_msg_hdr);
+ heci_hdr.msg_complete = 0;
+ } else {
+ heci_hdr.length = length;
+ heci_hdr.msg_complete = 1;
+ }
+ heci_hdr.host_addr = file_ext->host_client_id;
+ heci_hdr.me_addr = file_ext->me_client_id;
+ heci_hdr.reserved = 0;
+ DBG("call heci_write_message header=%08x.\n",
+ *((__u32 *) &heci_hdr));
+ spin_unlock(&file_ext->write_io_lock);
+ /* protect heci low level write */
+ spin_lock_bh(&dev->device_lock);
+ if (!heci_write_message(dev, &heci_hdr,
+ (unsigned char *) (priv_write_cb->request_buffer.data),
+ heci_hdr.length)) {
+
+ spin_unlock_bh(&dev->device_lock);
+ heci_free_cb_private(priv_write_cb);
+ rets = -ENODEV;
+ priv_write_cb->information = 0;
+ return rets;
+ }
+ file_ext->writing_state = HECI_WRITING;
+ priv_write_cb->information = heci_hdr.length;
+ if (heci_hdr.msg_complete) {
+ flow_ctrl_reduce(dev, file_ext);
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+ } else {
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ } else {
+
+ spin_unlock_bh(&dev->device_lock);
+ priv_write_cb->information = 0;
+ file_ext->writing_state = HECI_WRITING;
+ spin_unlock(&file_ext->write_io_lock);
+ list_add_tail(&priv_write_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ return length;
+
+unlock:
+ spin_unlock(&file_ext->write_io_lock);
+fail:
+ heci_free_cb_private(priv_write_cb);
+ return rets;
+
+}
+
+/**
+ * heci_ioctl - the IOCTL function
+ *
+ * @inode: pointer to inode structure
+ * @file: pointer to file structure
+ * @cmd: ioctl command
+ * @data: pointer to heci message structure
+ *
+ * returns 0 on success , <0 on error
+ */
+static int heci_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long data)
+{
+ int rets = 0;
+ int if_num = iminor(inode);
+ struct heci_file_private *file_ext = file->private_data;
+ /* in user space */
+ struct heci_message_data __user *u_msg;
+ struct heci_message_data k_msg; /* all in kernel on the stack */
+ struct iamt_heci_device *dev;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (!heci_device)
+ return -ENODEV;
+
+ dev = pci_get_drvdata(heci_device);
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ /* first copy from user all data needed */
+ u_msg = (struct heci_message_data __user *)data;
+ if (copy_from_user(&k_msg, u_msg, sizeof(k_msg))) {
+ DBG("first copy from user all data needed filled\n");
+ return -EFAULT;
+ }
+ DBG("user message size is %d\n", k_msg.size);
+
+ switch (cmd) {
+ case IOCTL_HECI_GET_VERSION:
+ DBG(": IOCTL_HECI_GET_VERSION\n");
+ rets = heci_ioctl_get_version(dev, if_num, u_msg, k_msg,
+ file_ext);
+ break;
+
+ case IOCTL_HECI_CONNECT_CLIENT:
+ DBG(": IOCTL_HECI_CONNECT_CLIENT.\n");
+ rets = heci_ioctl_connect_client(dev, if_num, u_msg, k_msg,
+ file);
+ break;
+
+ case IOCTL_HECI_WD:
+ DBG(": IOCTL_HECI_WD.\n");
+ rets = heci_ioctl_wd(dev, if_num, k_msg, file_ext);
+ break;
+
+ case IOCTL_HECI_BYPASS_WD:
+ DBG(": IOCTL_HECI_BYPASS_WD.\n");
+ rets = heci_ioctl_bypass_wd(dev, if_num, k_msg, file_ext);
+ break;
+
+ default:
+ rets = -EINVAL;
+ break;
+ }
+ return rets;
+}
+
+/**
+ * heci_poll - the poll function
+ *
+ * @file: pointer to file structure
+ * @wait: pointer to poll_table structure
+ *
+ * returns poll mask
+ */
+static unsigned int heci_poll(struct file *file, poll_table *wait)
+{
+ int if_num = iminor(file->f_dentry->d_inode);
+ unsigned int mask = 0;
+ struct heci_file_private *file_ext = file->private_data;
+ struct iamt_heci_device *dev;
+
+ if (!heci_device)
+ return mask;
+
+ dev = pci_get_drvdata(heci_device);
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext))
+ return mask;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return mask;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ if (file_ext == &dev->iamthif_file_ext) {
+ poll_wait(file, &dev->iamthif_file_ext.wait, wait);
+ spin_lock(&dev->iamthif_file_ext.file_lock);
+ if (dev->iamthif_state == HECI_IAMTHIF_READ_COMPLETE
+ && dev->iamthif_file_object == file) {
+ mask |= (POLLIN | POLLRDNORM);
+ spin_lock_bh(&dev->device_lock);
+ DBG("run next pthi cb\n");
+ run_next_iamthif_cmd(dev);
+ spin_unlock_bh(&dev->device_lock);
+ }
+ spin_unlock(&dev->iamthif_file_ext.file_lock);
+
+ } else{
+ poll_wait(file, &file_ext->tx_wait, wait);
+ spin_lock(&file_ext->write_io_lock);
+ if (HECI_WRITE_COMPLETE == file_ext->writing_state)
+ mask |= (POLLIN | POLLRDNORM);
+
+ spin_unlock(&file_ext->write_io_lock);
+ }
+
+ return mask;
+}
+
+#ifdef CONFIG_PM
+static int heci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct iamt_heci_device *dev = pci_get_drvdata(pdev);
+ int err = 0;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->reinit_tsk != NULL) {
+ kthread_stop(dev->reinit_tsk);
+ dev->reinit_tsk = NULL;
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ /* Stop watchdog if exists */
+ del_timer_sync(&dev->wd_timer);
+ if (dev->wd_file_ext.state == HECI_FILE_CONNECTED
+ && dev->wd_timeout) {
+ spin_lock_bh(&dev->device_lock);
+ g_sus_wd_timeout = dev->wd_timeout;
+ dev->wd_timeout = 0;
+ dev->wd_due_counter = 0;
+ memcpy(dev->wd_data, heci_stop_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ dev->stop = 1;
+ if (dev->host_buffer_is_empty &&
+ flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_send_wd(dev))
+ DBG("send stop WD failed\n");
+ else
+ flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+ dev->wd_pending = 0;
+ } else {
+ dev->wd_pending = 1;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ dev->wd_stoped = 0;
+
+ err = wait_event_interruptible_timeout(dev->wait_stop_wd,
+ (dev->wd_stoped),
+ 10 * HZ);
+ if (!dev->wd_stoped)
+ DBG("stop wd failed to complete.\n");
+ else {
+ DBG("stop wd complete %d.\n", err);
+ err = 0;
+ }
+ }
+ /* Set new heci state */
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state == HECI_ENABLED ||
+ dev->heci_state == HECI_RECOVERING_FROM_RESET) {
+ dev->heci_state = HECI_POWER_DOWN;
+ heci_reset(dev, 0);
+ }
+ spin_unlock_bh(&dev->device_lock);
+
+ pci_save_state(pdev);
+
+ pci_disable_device(pdev);
+ free_irq(pdev->irq, dev);
+
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ return err;
+}
+
+static int heci_resume(struct pci_dev *pdev)
+{
+ struct iamt_heci_device *dev;
+ int err = 0;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+
+ dev = pci_get_drvdata(pdev);
+ if (!dev)
+ return -ENODEV;
+
+ /* request and enable interrupt */
+ err = request_irq(pdev->irq, heci_isr_interrupt, IRQF_SHARED,
+ heci_driver_name, dev);
+ if (err) {
+ printk(KERN_ERR "heci: Request_irq failure. irq = %d \n",
+ pdev->irq);
+ return err;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ dev->heci_state = HECI_POWER_UP;
+ heci_reset(dev, 1);
+ spin_unlock_bh(&dev->device_lock);
+
+ /* Start watchdog if stopped in suspend */
+ if (g_sus_wd_timeout != 0) {
+ dev->wd_timeout = g_sus_wd_timeout;
+
+ memcpy(dev->wd_data, heci_start_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ memcpy(dev->wd_data + HECI_WD_PARAMS_SIZE,
+ &dev->wd_timeout, sizeof(__u16));
+ dev->wd_due_counter = 1;
+
+ if (dev->wd_timeout)
+ mod_timer(&dev->wd_timer, jiffies);
+
+ g_sus_wd_timeout = 0;
+ }
+ return err;
+}
+#endif
+
+MODULE_AUTHOR("Intel Corporation");
+MODULE_DESCRIPTION("Intel(R) Management Engine Interface");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(HECI_DRIVER_VERSION);
diff --git a/drivers/staging/heci/heci_version.h b/drivers/staging/heci/heci_version.h
new file mode 100644
index 00000000000..3007aa6e17d
--- /dev/null
+++ b/drivers/staging/heci/heci_version.h
@@ -0,0 +1,54 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#ifndef HECI_VERSION_H
+#define HECI_VERSION_H
+
+#define MAJOR_VERSION 5
+#define MINOR_VERSION 0
+#define QUICK_FIX_NUMBER 0
+#define VER_BUILD 31
+
+#define HECI_DRV_VER1 __stringify(MAJOR_VERSION) "." __stringify(MINOR_VERSION)
+#define HECI_DRV_VER2 __stringify(QUICK_FIX_NUMBER) "." __stringify(VER_BUILD)
+
+#define HECI_DRIVER_VERSION HECI_DRV_VER1 "." HECI_DRV_VER2
+
+#endif
diff --git a/drivers/staging/heci/interrupt.c b/drivers/staging/heci/interrupt.c
new file mode 100644
index 00000000000..aacd2624398
--- /dev/null
+++ b/drivers/staging/heci/interrupt.c
@@ -0,0 +1,1553 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/kthread.h>
+
+#include "heci.h"
+#include "heci_interface.h"
+
+/*
+ * interrupt function prototypes
+ */
+static void heci_bh_handler(struct work_struct *work);
+static int heci_bh_read_handler(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots);
+static int heci_bh_write_handler(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots);
+static void heci_bh_read_bus_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr);
+static int heci_bh_read_pthi_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr);
+static int heci_bh_read_client_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr);
+static void heci_client_connect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *connect_res);
+static void heci_client_disconnect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *disconnect_res);
+static void heci_client_flow_control_response(struct iamt_heci_device *dev,
+ struct hbm_flow_control *flow_control);
+static void heci_client_disconnect_request(struct iamt_heci_device *dev,
+ struct hbm_client_disconnect_request *disconnect_req);
+
+
+/**
+ * heci_isr_interrupt - The ISR of the HECI device
+ *
+ * @irq: The irq number
+ * @dev_id: pointer to the device structure
+ *
+ * returns irqreturn_t
+ */
+irqreturn_t heci_isr_interrupt(int irq, void *dev_id)
+{
+ int err;
+ struct iamt_heci_device *dev = (struct iamt_heci_device *) dev_id;
+
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+
+ if ((dev->host_hw_state & H_IS) != H_IS)
+ return IRQ_NONE;
+
+ /* disable interrupts */
+ heci_csr_disable_interrupts(dev);
+
+ /*
+ * Our device interrupted, schedule work the heci_bh_handler
+ * to handle the interrupt processing. This needs to be a
+ * workqueue item since the handler can sleep.
+ */
+ PREPARE_WORK(&dev->work, heci_bh_handler);
+ DBG("schedule work the heci_bh_handler.\n");
+ err = schedule_work(&dev->work);
+ if (!err) {
+ printk(KERN_ERR "heci: schedule the heci_bh_handler"
+ " failed error=%x\n", err);
+ }
+ return IRQ_HANDLED;
+}
+
+/**
+ * _heci_cmpl - process completed operation.
+ *
+ * @file_ext: private data of the file object.
+ * @priv_cb_pos: callback block.
+ */
+static void _heci_cmpl(struct heci_file_private *file_ext,
+ struct heci_cb_private *priv_cb_pos)
+{
+ if (priv_cb_pos->major_file_operations == HECI_WRITE) {
+ heci_free_cb_private(priv_cb_pos);
+ DBG("completing write call back.\n");
+ file_ext->writing_state = HECI_WRITE_COMPLETE;
+ if ((&file_ext->tx_wait) &&
+ waitqueue_active(&file_ext->tx_wait))
+ wake_up_interruptible(&file_ext->tx_wait);
+
+ } else if (priv_cb_pos->major_file_operations == HECI_READ
+ && HECI_READING == file_ext->reading_state) {
+ DBG("completing read call back information= %lu\n",
+ priv_cb_pos->information);
+ file_ext->reading_state = HECI_READ_COMPLETE;
+ if ((&file_ext->rx_wait) &&
+ waitqueue_active(&file_ext->rx_wait))
+ wake_up_interruptible(&file_ext->rx_wait);
+
+ }
+}
+
+/**
+ * _heci_cmpl_iamthif - process completed iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @priv_cb_pos: callback block.
+ */
+static void _heci_cmpl_iamthif(struct iamt_heci_device *dev,
+ struct heci_cb_private *priv_cb_pos)
+{
+ if (dev->iamthif_canceled != 1) {
+ dev->iamthif_state = HECI_IAMTHIF_READ_COMPLETE;
+ dev->iamthif_stall_timer = 0;
+ memcpy(priv_cb_pos->response_buffer.data,
+ dev->iamthif_msg_buf,
+ dev->iamthif_msg_buf_index);
+ list_add_tail(&priv_cb_pos->cb_list,
+ &dev->pthi_read_complete_list.heci_cb.cb_list);
+ DBG("pthi read completed.\n");
+ } else {
+ run_next_iamthif_cmd(dev);
+ }
+ if (&dev->iamthif_file_ext.wait) {
+ DBG("completing pthi call back.\n");
+ wake_up_interruptible(&dev->iamthif_file_ext.wait);
+ }
+}
+/**
+ * heci_bh_handler - function called after ISR to handle the interrupt
+ * processing.
+ *
+ * @work: pointer to the work structure
+ *
+ * NOTE: This function is called by schedule work
+ */
+static void heci_bh_handler(struct work_struct *work)
+{
+ struct iamt_heci_device *dev =
+ container_of(work, struct iamt_heci_device, work);
+ struct io_heci_list complete_list;
+ __s32 slots;
+ int rets;
+ struct heci_cb_private *cb_pos = NULL, *cb_next = NULL;
+ struct heci_file_private *file_ext;
+ int bus_message_received = 0;
+ struct task_struct *tsk;
+
+ DBG("function called after ISR to handle the interrupt processing.\n");
+ /* initialize our complete list */
+ spin_lock_bh(&dev->device_lock);
+ heci_initialize_list(&complete_list, dev);
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->me_hw_state = read_heci_register(dev, ME_CSR_HA);
+
+ /* check if ME wants a reset */
+ if (((dev->me_hw_state & ME_RDY_HRA) == 0)
+ && (dev->heci_state != HECI_RESETING)
+ && (dev->heci_state != HECI_INITIALIZING)) {
+ DBG("FW not ready.\n");
+ heci_reset(dev, 1);
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+
+ /* check if we need to start the dev */
+ if ((dev->host_hw_state & H_RDY) == 0) {
+ if ((dev->me_hw_state & ME_RDY_HRA) == ME_RDY_HRA) {
+ DBG("we need to start the dev.\n");
+ dev->host_hw_state |= (H_IE | H_IG | H_RDY);
+ heci_set_csr_register(dev);
+ if (dev->heci_state == HECI_INITIALIZING) {
+ dev->recvd_msg = 1;
+ spin_unlock_bh(&dev->device_lock);
+ wake_up_interruptible(&dev->wait_recvd_msg);
+ return;
+
+ } else {
+ spin_unlock_bh(&dev->device_lock);
+ tsk = kthread_run(heci_task_initialize_clients,
+ dev, "heci_reinit");
+ if (IS_ERR(tsk)) {
+ int rc = PTR_ERR(tsk);
+ printk(KERN_WARNING "heci: Unable to"
+ "start the heci thread: %d\n", rc);
+ }
+ return;
+ }
+ } else {
+ DBG("enable interrupt FW not ready.\n");
+ heci_csr_enable_interrupts(dev);
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+ }
+ /* check slots avalable for reading */
+ slots = count_full_read_slots(dev);
+ DBG("slots =%08x extra_write_index =%08x.\n",
+ slots, dev->extra_write_index);
+ while ((slots > 0) && (!dev->extra_write_index)) {
+ DBG("slots =%08x extra_write_index =%08x.\n", slots,
+ dev->extra_write_index);
+ DBG("call heci_bh_read_handler.\n");
+ rets = heci_bh_read_handler(&complete_list, dev, &slots);
+ if (rets != 0)
+ goto end;
+ }
+ rets = heci_bh_write_handler(&complete_list, dev, &slots);
+end:
+ DBG("end of bottom half function.\n");
+ dev->host_hw_state = read_heci_register(dev, H_CSR);
+ dev->host_buffer_is_empty = host_buffer_is_empty(dev);
+
+ if ((dev->host_hw_state & H_IS) == H_IS) {
+ /* acknowledge interrupt and disable interrupts */
+ heci_csr_disable_interrupts(dev);
+
+ PREPARE_WORK(&dev->work, heci_bh_handler);
+ DBG("schedule work the heci_bh_handler.\n");
+ rets = schedule_work(&dev->work);
+ if (!rets) {
+ printk(KERN_ERR "heci: schedule the heci_bh_handler"
+ " failed error=%x\n", rets);
+ }
+ } else {
+ heci_csr_enable_interrupts(dev);
+ }
+
+ if (dev->recvd_msg && waitqueue_active(&dev->wait_recvd_msg)) {
+ DBG("received waiting bus message\n");
+ bus_message_received = 1;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ if (bus_message_received) {
+ DBG("wake up dev->wait_recvd_msg\n");
+ wake_up_interruptible(&dev->wait_recvd_msg);
+ bus_message_received = 0;
+ }
+ if ((complete_list.status != 0)
+ || list_empty(&complete_list.heci_cb.cb_list))
+ return;
+
+
+ list_for_each_entry_safe(cb_pos, cb_next,
+ &complete_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)cb_pos->file_private;
+ list_del(&cb_pos->cb_list);
+ if (file_ext != NULL) {
+ if (file_ext != &dev->iamthif_file_ext) {
+ DBG("completing call back.\n");
+ _heci_cmpl(file_ext, cb_pos);
+ cb_pos = NULL;
+ } else if (file_ext == &dev->iamthif_file_ext) {
+ _heci_cmpl_iamthif(dev, cb_pos);
+ }
+ }
+ }
+}
+
+
+/**
+ * heci_bh_read_handler - bottom half read routine after ISR to
+ * handle the read processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @slots: slots to read.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_handler(struct io_heci_list *cmpl_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots)
+{
+ struct heci_msg_hdr *heci_hdr;
+ int ret = 0;
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ if (!dev->rd_msg_hdr) {
+ dev->rd_msg_hdr = read_heci_register(dev, ME_CB_RW);
+ DBG("slots=%08x.\n", *slots);
+ (*slots)--;
+ DBG("slots=%08x.\n", *slots);
+ }
+ heci_hdr = (struct heci_msg_hdr *) &dev->rd_msg_hdr;
+ DBG("heci_hdr->length =%d\n", heci_hdr->length);
+
+ if ((heci_hdr->reserved) || !(dev->rd_msg_hdr)) {
+ DBG("corrupted message header.\n");
+ ret = -ECORRUPTED_MESSAGE_HEADER;
+ goto end;
+ }
+
+ if ((heci_hdr->host_addr) || (heci_hdr->me_addr)) {
+ list_for_each_entry_safe(file_pos, file_next,
+ &dev->file_list, link) {
+ DBG("list_for_each_entry_safe read host"
+ " client = %d, ME client = %d\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ if ((file_pos->host_client_id == heci_hdr->host_addr)
+ && (file_pos->me_client_id == heci_hdr->me_addr))
+ break;
+ }
+
+ if (&file_pos->link == &dev->file_list) {
+ DBG("corrupted message header\n");
+ ret = -ECORRUPTED_MESSAGE_HEADER;
+ goto end;
+ }
+ }
+ if (((*slots) * sizeof(__u32)) < heci_hdr->length) {
+ DBG("we can't read the message slots=%08x.\n", *slots);
+ /* we can't read the message */
+ ret = -ERANGE;
+ goto end;
+ }
+
+ /* decide where to read the message too */
+ if (!heci_hdr->host_addr) {
+ DBG("call heci_bh_read_bus_message.\n");
+ heci_bh_read_bus_message(dev, heci_hdr);
+ DBG("end heci_bh_read_bus_message.\n");
+ } else if ((heci_hdr->host_addr == dev->iamthif_file_ext.host_client_id)
+ && (HECI_FILE_CONNECTED == dev->iamthif_file_ext.state)
+ && (dev->iamthif_state == HECI_IAMTHIF_READING)) {
+ DBG("call heci_bh_read_iamthif_message.\n");
+ DBG("heci_hdr->length =%d\n", heci_hdr->length);
+ ret = heci_bh_read_pthi_message(cmpl_list, dev, heci_hdr);
+ if (ret != 0)
+ goto end;
+
+ } else {
+ DBG("call heci_bh_read_client_message.\n");
+ ret = heci_bh_read_client_message(cmpl_list, dev, heci_hdr);
+ if (ret != 0)
+ goto end;
+
+ }
+
+ /* reset the number of slots and header */
+ *slots = count_full_read_slots(dev);
+ dev->rd_msg_hdr = 0;
+
+ if (*slots == -ESLOTS_OVERFLOW) {
+ /* overflow - reset */
+ DBG("reseting due to slots overflow.\n");
+ /* set the event since message has been read */
+ ret = -ERANGE;
+ goto end;
+ }
+end:
+ return ret;
+}
+
+
+/**
+ * heci_bh_read_bus_message - bottom half read routine after ISR to
+ * handle the read bus message cmd processing.
+ *
+ * @dev: Device object for our driver
+ * @heci_hdr: header of bus message
+ */
+static void heci_bh_read_bus_message(struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr)
+{
+ struct heci_bus_message *heci_msg;
+ struct hbm_host_version_response *version_res;
+ struct hbm_client_connect_response *connect_res;
+ struct hbm_client_connect_response *disconnect_res;
+ struct hbm_flow_control *flow_control;
+ struct hbm_props_response *props_res;
+ struct hbm_host_enum_response *enum_res;
+ struct hbm_client_disconnect_request *disconnect_req;
+ struct hbm_host_stop_request *h_stop_req;
+ int i;
+ unsigned char *buffer;
+
+ /* read the message to our buffer */
+ buffer = (unsigned char *) dev->rd_msg_buf;
+ BUG_ON(heci_hdr->length >= sizeof(dev->rd_msg_buf));
+ heci_read_slots(dev, buffer, heci_hdr->length);
+ heci_msg = (struct heci_bus_message *) buffer;
+
+ switch (*(__u8 *) heci_msg) {
+ case HOST_START_RES_CMD:
+ version_res = (struct hbm_host_version_response *) heci_msg;
+ if (version_res->host_version_supported) {
+ dev->version.major_version = HBM_MAJOR_VERSION;
+ dev->version.minor_version = HBM_MINOR_VERSION;
+ } else {
+ dev->version = version_res->me_max_version;
+ }
+ dev->recvd_msg = 1;
+ DBG("host start response message received.\n");
+ break;
+
+ case CLIENT_CONNECT_RES_CMD:
+ connect_res =
+ (struct hbm_client_connect_response *) heci_msg;
+ heci_client_connect_response(dev, connect_res);
+ DBG("client connect response message received.\n");
+ wake_up(&dev->wait_recvd_msg);
+ break;
+
+ case CLIENT_DISCONNECT_RES_CMD:
+ disconnect_res =
+ (struct hbm_client_connect_response *) heci_msg;
+ heci_client_disconnect_response(dev, disconnect_res);
+ DBG("client disconnect response message received.\n");
+ wake_up(&dev->wait_recvd_msg);
+ break;
+
+ case HECI_FLOW_CONTROL_CMD:
+ flow_control = (struct hbm_flow_control *) heci_msg;
+ heci_client_flow_control_response(dev, flow_control);
+ DBG("client flow control response message received.\n");
+ break;
+
+ case HOST_CLIENT_PROPERTEIS_RES_CMD:
+ props_res = (struct hbm_props_response *) heci_msg;
+ if (props_res->status != 0) {
+ BUG();
+ break;
+ }
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ props_res->address) {
+ dev->me_clients[i].props =
+ props_res->client_properties;
+ break;
+ }
+
+ }
+ dev->recvd_msg = 1;
+ break;
+
+ case HOST_ENUM_RES_CMD:
+ enum_res = (struct hbm_host_enum_response *) heci_msg;
+ memcpy(dev->heci_me_clients, enum_res->valid_addresses, 32);
+ dev->recvd_msg = 1;
+ break;
+
+ case HOST_STOP_RES_CMD:
+ dev->heci_state = HECI_DISABLED;
+ DBG("reseting because of FW stop response.\n");
+ heci_reset(dev, 1);
+ break;
+
+ case CLIENT_DISCONNECT_REQ_CMD:
+ /* search for client */
+ disconnect_req =
+ (struct hbm_client_disconnect_request *) heci_msg;
+ heci_client_disconnect_request(dev, disconnect_req);
+ break;
+
+ case ME_STOP_REQ_CMD:
+ /* prepare stop request */
+ heci_hdr = (struct heci_msg_hdr *) &dev->ext_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length = sizeof(struct hbm_host_stop_request);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+ h_stop_req =
+ (struct hbm_host_stop_request *) &dev->ext_msg_buf[1];
+ memset(h_stop_req, 0, sizeof(struct hbm_host_stop_request));
+ h_stop_req->cmd.cmd = HOST_STOP_REQ_CMD;
+ h_stop_req->reason = DRIVER_STOP_REQUEST;
+ h_stop_req->reserved[0] = 0;
+ h_stop_req->reserved[1] = 0;
+ dev->extra_write_index = 2;
+ break;
+
+ default:
+ BUG();
+ break;
+
+ }
+}
+
+/**
+ * heci_bh_read_pthi_message - bottom half read routine after ISR to
+ * handle the read pthi message data processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @heci_hdr: header of pthi message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_pthi_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr)
+{
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb;
+ unsigned char *buffer;
+
+ BUG_ON(heci_hdr->me_addr != dev->iamthif_file_ext.me_client_id);
+ BUG_ON(dev->iamthif_state != HECI_IAMTHIF_READING);
+
+ buffer = (unsigned char *) (dev->iamthif_msg_buf +
+ dev->iamthif_msg_buf_index);
+ BUG_ON(sizeof(dev->iamthif_msg_buf) <
+ (dev->iamthif_msg_buf_index + heci_hdr->length));
+
+ heci_read_slots(dev, buffer, heci_hdr->length);
+
+ dev->iamthif_msg_buf_index += heci_hdr->length;
+
+ if (!(heci_hdr->msg_complete))
+ return 0;
+
+ DBG("pthi_message_buffer_index=%d\n", heci_hdr->length);
+ DBG("completed pthi read.\n ");
+ if (!dev->iamthif_current_cb)
+ return -ENODEV;
+
+ priv_cb = dev->iamthif_current_cb;
+ dev->iamthif_current_cb = NULL;
+
+ file_ext = (struct heci_file_private *)priv_cb->file_private;
+ if (!file_ext)
+ return -ENODEV;
+
+ dev->iamthif_stall_timer = 0;
+ priv_cb->information = dev->iamthif_msg_buf_index;
+ priv_cb->read_time = get_seconds();
+ if ((dev->iamthif_ioctl) && (file_ext == &dev->iamthif_file_ext)) {
+ /* found the iamthif cb */
+ DBG("complete the pthi read cb.\n ");
+ if (&dev->iamthif_file_ext) {
+ DBG("add the pthi read cb to complete.\n ");
+ list_add_tail(&priv_cb->cb_list,
+ &complete_list->heci_cb.cb_list);
+ }
+ }
+ return 0;
+}
+
+/**
+ * _heci_bh_state_ok - check if heci header matches file private data
+ *
+ * @file_ext: private data of the file object
+ * @heci_hdr: header of heci client message
+ *
+ * returns !=0 if matches, 0 if no match.
+ */
+static int _heci_bh_state_ok(struct heci_file_private *file_ext,
+ struct heci_msg_hdr *heci_hdr)
+{
+ return ((file_ext->host_client_id == heci_hdr->host_addr)
+ && (file_ext->me_client_id == heci_hdr->me_addr)
+ && (file_ext->state == HECI_FILE_CONNECTED)
+ && (HECI_READ_COMPLETE != file_ext->reading_state));
+}
+
+/**
+ * heci_bh_read_client_message - bottom half read routine after ISR to
+ * handle the read heci client message data processing.
+ *
+ * @complete_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @heci_hdr: header of heci client message
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_read_client_message(struct io_heci_list *complete_list,
+ struct iamt_heci_device *dev,
+ struct heci_msg_hdr *heci_hdr)
+{
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+ unsigned char *buffer = NULL;
+
+ DBG("start client msg\n");
+ if (!((dev->read_list.status == 0) &&
+ !list_empty(&dev->read_list.heci_cb.cb_list)))
+ goto quit;
+
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->read_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if ((file_ext != NULL) &&
+ (_heci_bh_state_ok(file_ext, heci_hdr))) {
+ spin_lock(&file_ext->read_io_lock);
+ file_ext->reading_state = HECI_READING;
+ buffer = (unsigned char *)
+ (priv_cb_pos->response_buffer.data +
+ priv_cb_pos->information);
+ BUG_ON(priv_cb_pos->response_buffer.size <
+ heci_hdr->length +
+ priv_cb_pos->information);
+
+ if (priv_cb_pos->response_buffer.size <
+ heci_hdr->length +
+ priv_cb_pos->information) {
+ DBG("message overflow.\n");
+ list_del(&priv_cb_pos->cb_list);
+ spin_unlock(&file_ext->read_io_lock);
+ return -ENOMEM;
+ }
+ if (buffer) {
+ heci_read_slots(dev, buffer,
+ heci_hdr->length);
+ }
+ priv_cb_pos->information += heci_hdr->length;
+ if (heci_hdr->msg_complete) {
+ file_ext->status = 0;
+ list_del(&priv_cb_pos->cb_list);
+ spin_unlock(&file_ext->read_io_lock);
+ DBG("completed read host client = %d,"
+ "ME client = %d, "
+ "data length = %lu\n",
+ file_ext->host_client_id,
+ file_ext->me_client_id,
+ priv_cb_pos->information);
+
+ *(priv_cb_pos->response_buffer.data +
+ priv_cb_pos->information) = '\0';
+ DBG("priv_cb_pos->res_buffer - %s\n",
+ priv_cb_pos->response_buffer.data);
+ list_add_tail(&priv_cb_pos->cb_list,
+ &complete_list->heci_cb.cb_list);
+ } else {
+ spin_unlock(&file_ext->read_io_lock);
+ }
+
+ break;
+ }
+
+ }
+
+quit:
+ DBG("message read\n");
+ if (!buffer) {
+ heci_read_slots(dev, (unsigned char *) dev->rd_msg_buf,
+ heci_hdr->length);
+ DBG("discarding message, header=%08x.\n",
+ *(__u32 *) dev->rd_msg_buf);
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_bh_iamthif_read - prepare to read iamthif data.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_iamthif_read(struct iamt_heci_device *dev, __s32 *slots)
+{
+
+ if (((*slots) * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr)
+ + sizeof(struct hbm_flow_control))) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_flow_control) + 3) / 4;
+ if (!heci_send_flow_control(dev, &dev->iamthif_file_ext)) {
+ DBG("iamthif flow control failed\n");
+ } else {
+ DBG("iamthif flow control success\n");
+ dev->iamthif_state = HECI_IAMTHIF_READING;
+ dev->iamthif_flow_control_pending = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_stall_timer = IAMTHIF_STALL_TIMER;
+ dev->host_buffer_is_empty = host_buffer_is_empty(dev);
+ }
+ return 0;
+ } else {
+ return -ECOMPLETE_MESSAGE;
+ }
+}
+
+/**
+ * _heci_bh_close - process close related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_close(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_disconnect_request))) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_disconnect_request) + 3) / 4;
+
+ if (!heci_disconnect(dev, file_ext)) {
+ file_ext->status = 0;
+ priv_cb_pos->information = 0;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ECOMPLETE_MESSAGE;
+ } else {
+ file_ext->state = HECI_FILE_DISCONNECTING;
+ file_ext->status = 0;
+ priv_cb_pos->information = 0;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->ctrl_rd_list.heci_cb.cb_list);
+ file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+ }
+ } else {
+ /* return the cancel routine */
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_hb_close - process read related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_read(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_flow_control))) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_flow_control) + 3) / 4;
+ if (!heci_send_flow_control(dev, file_ext)) {
+ file_ext->status = -ENODEV;
+ priv_cb_pos->information = 0;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ENODEV;
+ } else {
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->read_list.heci_cb.cb_list);
+ }
+ } else {
+ /* return the cancel routine */
+ list_del(&priv_cb_pos->cb_list);
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+
+/**
+ * _heci_bh_ioctl - process ioctl related operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_ioctl(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_connect_request))) {
+ file_ext->state = HECI_FILE_CONNECTING;
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ sizeof(struct hbm_client_connect_request) + 3) / 4;
+ if (!heci_connect(dev, file_ext)) {
+ file_ext->status = -ENODEV;
+ priv_cb_pos->information = 0;
+ list_del(&priv_cb_pos->cb_list);
+ return -ENODEV;
+ } else {
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->ctrl_rd_list.heci_cb.cb_list);
+ file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+ }
+ } else {
+ /* return the cancel routine */
+ list_del(&priv_cb_pos->cb_list);
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_bh_cmpl - process completed and no-iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_cmpl(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ struct heci_msg_hdr *heci_hdr;
+
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ (priv_cb_pos->request_buffer.size -
+ priv_cb_pos->information))) {
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length = ((priv_cb_pos->request_buffer.size) -
+ (priv_cb_pos->information));
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+ DBG("priv_cb_pos->request_buffer.size =%d"
+ "heci_hdr->msg_complete= %d\n",
+ priv_cb_pos->request_buffer.size,
+ heci_hdr->msg_complete);
+ DBG("priv_cb_pos->information =%lu\n",
+ priv_cb_pos->information);
+ DBG("heci_hdr->length =%d\n",
+ heci_hdr->length);
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *)
+ (priv_cb_pos->request_buffer.data +
+ priv_cb_pos->information),
+ heci_hdr->length)) {
+ file_ext->status = -ENODEV;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ENODEV;
+ } else {
+ flow_ctrl_reduce(dev, file_ext);
+ file_ext->status = 0;
+ priv_cb_pos->information += heci_hdr->length;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+ }
+ } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+ /* buffer is still empty */
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length =
+ (*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+ heci_hdr->msg_complete = 0;
+ heci_hdr->reserved = 0;
+
+ (*slots) -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+ if (!heci_write_message(dev, heci_hdr,
+ (unsigned char *)
+ (priv_cb_pos->request_buffer.data +
+ priv_cb_pos->information),
+ heci_hdr->length)) {
+ file_ext->status = -ENODEV;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ return -ENODEV;
+ } else {
+ priv_cb_pos->information += heci_hdr->length;
+ DBG("priv_cb_pos->request_buffer.size =%d"
+ " heci_hdr->msg_complete= %d\n",
+ priv_cb_pos->request_buffer.size,
+ heci_hdr->msg_complete);
+ DBG("priv_cb_pos->information =%lu\n",
+ priv_cb_pos->information);
+ DBG("heci_hdr->length =%d\n", heci_hdr->length);
+ }
+ return -ECOMPLETE_MESSAGE;
+ } else {
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * _heci_bh_cmpl_iamthif - process completed iamthif operation.
+ *
+ * @dev: Device object for our driver.
+ * @slots: free slots.
+ * @priv_cb_pos: callback block.
+ * @file_ext: private data of the file object.
+ * @cmpl_list: complete list.
+ *
+ * returns 0, OK; otherwise, error.
+ */
+static int _heci_bh_cmpl_iamthif(struct iamt_heci_device *dev, __s32 *slots,
+ struct heci_cb_private *priv_cb_pos,
+ struct heci_file_private *file_ext,
+ struct io_heci_list *cmpl_list)
+{
+ struct heci_msg_hdr *heci_hdr;
+
+ if ((*slots * sizeof(__u32)) >= (sizeof(struct heci_msg_hdr) +
+ dev->iamthif_msg_buf_size -
+ dev->iamthif_msg_buf_index)) {
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length = dev->iamthif_msg_buf_size -
+ dev->iamthif_msg_buf_index;
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (dev->iamthif_msg_buf +
+ dev->iamthif_msg_buf_index),
+ heci_hdr->length)) {
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ file_ext->status = -ENODEV;
+ list_del(&priv_cb_pos->cb_list);
+ return -ENODEV;
+ } else {
+ flow_ctrl_reduce(dev, file_ext);
+ dev->iamthif_msg_buf_index += heci_hdr->length;
+ priv_cb_pos->information = dev->iamthif_msg_buf_index;
+ file_ext->status = 0;
+ dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
+ dev->iamthif_flow_control_pending = 1;
+ /* save iamthif cb sent to pthi client */
+ dev->iamthif_current_cb = priv_cb_pos;
+ list_move_tail(&priv_cb_pos->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+
+ }
+ } else if (*slots == ((dev->host_hw_state & H_CBD) >> 24)) {
+ /* buffer is still empty */
+ heci_hdr = (struct heci_msg_hdr *) &dev->wr_msg_buf[0];
+ heci_hdr->host_addr = file_ext->host_client_id;
+ heci_hdr->me_addr = file_ext->me_client_id;
+ heci_hdr->length =
+ (*slots * sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+ heci_hdr->msg_complete = 0;
+ heci_hdr->reserved = 0;
+
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ heci_hdr->length + 3) / 4;
+
+ if (!heci_write_message(dev, heci_hdr,
+ (dev->iamthif_msg_buf +
+ dev->iamthif_msg_buf_index),
+ heci_hdr->length)) {
+ file_ext->status = -ENODEV;
+ list_del(&priv_cb_pos->cb_list);
+ } else {
+ dev->iamthif_msg_buf_index += heci_hdr->length;
+ }
+ return -ECOMPLETE_MESSAGE;
+ } else {
+ return -ECORRUPTED_MESSAGE_HEADER;
+ }
+
+ return 0;
+}
+
+/**
+ * heci_bh_write_handler - bottom half write routine after
+ * ISR to handle the write processing.
+ *
+ * @cmpl_list: An instance of our list structure
+ * @dev: Device object for our driver
+ * @slots: slots to write.
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int heci_bh_write_handler(struct io_heci_list *cmpl_list,
+ struct iamt_heci_device *dev,
+ __s32 *slots)
+{
+
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+ struct io_heci_list *list;
+ int ret;
+
+ if (!host_buffer_is_empty(dev)) {
+ DBG("host buffer is not empty.\n");
+ return 0;
+ }
+ dev->write_hang = -1;
+ *slots = count_empty_write_slots(dev);
+ /* complete all waiting for write CB */
+ DBG("complete all waiting for write cb.\n");
+
+ list = &dev->write_waiting_list;
+ if ((list->status == 0)
+ && !list_empty(&list->heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &list->heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext != NULL) {
+ file_ext->status = 0;
+ list_del(&priv_cb_pos->cb_list);
+ if ((HECI_WRITING == file_ext->writing_state) &&
+ (priv_cb_pos->major_file_operations ==
+ HECI_WRITING) &&
+ (file_ext != &dev->iamthif_file_ext)) {
+ DBG("HECI WRITE COMPLETE\n");
+ file_ext->writing_state =
+ HECI_WRITE_COMPLETE;
+ list_add_tail(&priv_cb_pos->cb_list,
+ &cmpl_list->heci_cb.cb_list);
+ }
+ if (file_ext == &dev->iamthif_file_ext) {
+ DBG("check iamthif flow control.\n");
+ if (dev->iamthif_flow_control_pending) {
+ ret = _heci_bh_iamthif_read(dev,
+ slots);
+ if (ret != 0)
+ return ret;
+ }
+ }
+ }
+
+ }
+ }
+
+ if ((dev->stop) && (!dev->wd_pending)) {
+ dev->wd_stoped = 1;
+ wake_up_interruptible(&dev->wait_stop_wd);
+ return 0;
+ }
+
+ if (dev->extra_write_index != 0) {
+ DBG("extra_write_index =%d.\n", dev->extra_write_index);
+ heci_write_message(dev,
+ (struct heci_msg_hdr *) &dev->ext_msg_buf[0],
+ (unsigned char *) &dev->ext_msg_buf[1],
+ (dev->extra_write_index - 1) * sizeof(__u32));
+ *slots -= dev->extra_write_index;
+ dev->extra_write_index = 0;
+ }
+ if (dev->heci_state == HECI_ENABLED) {
+ if ((dev->wd_pending)
+ && flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ if (!heci_send_wd(dev))
+ DBG("wd send failed.\n");
+ else
+ flow_ctrl_reduce(dev, &dev->wd_file_ext);
+
+ dev->wd_pending = 0;
+
+ if (dev->wd_timeout != 0) {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ HECI_START_WD_DATA_SIZE + 3) / 4;
+ dev->wd_due_counter = 2;
+ } else {
+ *slots -= (sizeof(struct heci_msg_hdr) +
+ HECI_WD_PARAMS_SIZE + 3) / 4;
+ dev->wd_due_counter = 0;
+ }
+
+ }
+ }
+ if (dev->stop)
+ return ~ENODEV;
+
+ /* complete control write list CB */
+ if (dev->ctrl_wr_list.status == 0) {
+ /* complete control write list CB */
+ DBG("complete control write list cb.\n");
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->ctrl_wr_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext == NULL) {
+ list_del(&priv_cb_pos->cb_list);
+ return -ENODEV;
+ }
+ switch (priv_cb_pos->major_file_operations) {
+ case HECI_CLOSE:
+ /* send disconnect message */
+ ret = _heci_bh_close(dev, slots,
+ priv_cb_pos,
+ file_ext, cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ break;
+ case HECI_READ:
+ /* send flow control message */
+ ret = _heci_bh_read(dev, slots,
+ priv_cb_pos,
+ file_ext, cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ break;
+ case HECI_IOCTL:
+ /* connect message */
+ if (!other_client_is_connecting(dev, file_ext))
+ continue;
+ ret = _heci_bh_ioctl(dev, slots,
+ priv_cb_pos,
+ file_ext, cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ break;
+
+ default:
+ BUG();
+ }
+
+ }
+ }
+ /* complete write list CB */
+ if ((dev->write_list.status == 0)
+ && !list_empty(&dev->write_list.heci_cb.cb_list)) {
+ DBG("complete write list cb.\n");
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->write_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if (file_ext != NULL) {
+ if (file_ext != &dev->iamthif_file_ext) {
+ if (!flow_ctrl_creds(dev, file_ext)) {
+ DBG("No flow control"
+ " credentials for client"
+ " %d, not sending.\n",
+ file_ext->host_client_id);
+ continue;
+ }
+ ret = _heci_bh_cmpl(dev, slots,
+ priv_cb_pos,
+ file_ext,
+ cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ } else if (file_ext == &dev->iamthif_file_ext) {
+ /* IAMTHIF IOCTL */
+ DBG("complete pthi write cb.\n");
+ if (!flow_ctrl_creds(dev, file_ext)) {
+ DBG("No flow control"
+ " credentials for pthi"
+ " client %d.\n",
+ file_ext->host_client_id);
+ continue;
+ }
+ ret = _heci_bh_cmpl_iamthif(dev, slots,
+ priv_cb_pos,
+ file_ext,
+ cmpl_list);
+ if (ret != 0)
+ return ret;
+
+ }
+ }
+
+ }
+ }
+ return 0;
+}
+
+
+/**
+ * is_treat_specially_client - check if the message belong
+ * to the file private data.
+ *
+ * @file_ext: private data of the file object
+ * @rs: connect response bus message
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+static int is_treat_specially_client(struct heci_file_private *file_ext,
+ struct hbm_client_connect_response *rs)
+{
+ int ret = 0;
+
+ if ((file_ext->host_client_id == rs->host_addr) &&
+ (file_ext->me_client_id == rs->me_addr)) {
+ if (rs->status == 0) {
+ DBG("client connect status = 0x%08x.\n", rs->status);
+ file_ext->state = HECI_FILE_CONNECTED;
+ file_ext->status = 0;
+ } else {
+ DBG("client connect status = 0x%08x.\n", rs->status);
+ file_ext->state = HECI_FILE_DISCONNECTED;
+ file_ext->status = -ENODEV;
+ }
+ ret = 1;
+ }
+ DBG("client state = %d.\n", file_ext->state);
+ return ret;
+}
+
+/**
+ * heci_client_connect_response - connect response bh routine
+ *
+ * @dev: Device object for our driver
+ * @rs: connect response bus message
+ */
+static void heci_client_connect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *rs)
+{
+
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+
+ /* if WD or iamthif client treat specially */
+
+ if ((is_treat_specially_client(&(dev->wd_file_ext), rs)) ||
+ (is_treat_specially_client(&(dev->iamthif_file_ext), rs)))
+ return;
+
+ if (dev->ctrl_rd_list.status == 0
+ && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->ctrl_rd_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if (file_ext == NULL) {
+ list_del(&priv_cb_pos->cb_list);
+ return;
+ }
+ if (HECI_IOCTL == priv_cb_pos->major_file_operations) {
+ if (is_treat_specially_client(file_ext, rs)) {
+ list_del(&priv_cb_pos->cb_list);
+ file_ext->status = 0;
+ file_ext->timer_count = 0;
+ break;
+ }
+ }
+ }
+ }
+}
+
+/**
+ * heci_client_disconnect_response - disconnect response bh routine
+ *
+ * @dev: Device object for our driver
+ * @rs: disconnect response bus message
+ */
+static void heci_client_disconnect_response(struct iamt_heci_device *dev,
+ struct hbm_client_connect_response *rs)
+{
+ struct heci_file_private *file_ext;
+ struct heci_cb_private *priv_cb_pos = NULL, *priv_cb_next = NULL;
+
+ if (dev->ctrl_rd_list.status == 0
+ && !list_empty(&dev->ctrl_rd_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->ctrl_rd_list.heci_cb.cb_list, cb_list) {
+ file_ext = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if (file_ext == NULL) {
+ list_del(&priv_cb_pos->cb_list);
+ return;
+ }
+
+ DBG("list_for_each_entry_safe in ctrl_rd_list.\n");
+ if ((file_ext->host_client_id == rs->host_addr) &&
+ (file_ext->me_client_id == rs->me_addr)) {
+
+ list_del(&priv_cb_pos->cb_list);
+ if (rs->status == 0) {
+ file_ext->state =
+ HECI_FILE_DISCONNECTED;
+ }
+
+ file_ext->status = 0;
+ file_ext->timer_count = 0;
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * same_flow_addr - tell they have same address.
+ *
+ * @file: private data of the file object.
+ * @flow: flow control.
+ *
+ * returns !=0, same; 0,not.
+ */
+static int same_flow_addr(struct heci_file_private *file,
+ struct hbm_flow_control *flow)
+{
+ return ((file->host_client_id == flow->host_addr)
+ && (file->me_client_id == flow->me_addr));
+}
+
+/**
+ * add_single_flow_creds - add single buffer credentials.
+ *
+ * @file: private data ot the file object.
+ * @flow: flow control.
+ */
+static void add_single_flow_creds(struct iamt_heci_device *dev,
+ struct hbm_flow_control *flow)
+{
+ struct heci_me_client *client;
+ int i;
+
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ client = &dev->me_clients[i];
+ if ((client != NULL) &&
+ (flow->me_addr == client->client_id)) {
+ if (client->props.single_recv_buf != 0) {
+ client->flow_ctrl_creds++;
+ DBG("recv flow ctrl msg ME %d (single).\n",
+ flow->me_addr);
+ DBG("flow control credentials=%d.\n",
+ client->flow_ctrl_creds);
+ } else {
+ BUG(); /* error in flow control */
+ }
+ }
+ }
+}
+
+/**
+ * heci_client_flow_control_response - flow control response bh routine
+ *
+ * @dev: Device object for our driver
+ * @flow_control: flow control response bus message
+ */
+static void heci_client_flow_control_response(struct iamt_heci_device *dev,
+ struct hbm_flow_control *flow_control)
+{
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ if (flow_control->host_addr == 0) {
+ /* single receive buffer */
+ add_single_flow_creds(dev, flow_control);
+ } else {
+ /* normal connection */
+ list_for_each_entry_safe(file_pos, file_next,
+ &dev->file_list, link) {
+ DBG("list_for_each_entry_safe in file_list\n");
+
+ DBG("file_ext of host client %d ME client %d.\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ DBG("flow ctrl msg for host %d ME %d.\n",
+ flow_control->host_addr,
+ flow_control->me_addr);
+ if (same_flow_addr(file_pos, flow_control)) {
+ DBG("recv ctrl msg for host %d ME %d.\n",
+ flow_control->host_addr,
+ flow_control->me_addr);
+ file_pos->flow_ctrl_creds++;
+ DBG("flow control credentials=%d.\n",
+ file_pos->flow_ctrl_creds);
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * same_disconn_addr - tell they have same address
+ *
+ * @file: private data of the file object.
+ * @disconn: disconnection request.
+ *
+ * returns !=0, same; 0,not.
+ */
+static int same_disconn_addr(struct heci_file_private *file,
+ struct hbm_client_disconnect_request *disconn)
+{
+ return ((file->host_client_id == disconn->host_addr)
+ && (file->me_client_id == disconn->me_addr));
+}
+
+/**
+ * heci_client_disconnect_request - disconnect request bh routine
+ *
+ * @dev: Device object for our driver.
+ * @disconnect_req: disconnect request bus message.
+ */
+static void heci_client_disconnect_request(struct iamt_heci_device *dev,
+ struct hbm_client_disconnect_request *disconnect_req)
+{
+ struct heci_msg_hdr *heci_hdr;
+ struct hbm_client_connect_response *disconnect_res;
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+
+ list_for_each_entry_safe(file_pos, file_next, &dev->file_list, link) {
+ if (same_disconn_addr(file_pos, disconnect_req)) {
+ DBG("disconnect request host client %d ME client %d.\n",
+ disconnect_req->host_addr,
+ disconnect_req->me_addr);
+ file_pos->state = HECI_FILE_DISCONNECTED;
+ file_pos->timer_count = 0;
+ if (file_pos == &dev->wd_file_ext) {
+ dev->wd_due_counter = 0;
+ dev->wd_pending = 0;
+ } else if (file_pos == &dev->iamthif_file_ext)
+ dev->iamthif_timer = 0;
+
+ /* prepare disconnect response */
+ heci_hdr =
+ (struct heci_msg_hdr *) &dev->ext_msg_buf[0];
+ heci_hdr->host_addr = 0;
+ heci_hdr->me_addr = 0;
+ heci_hdr->length =
+ sizeof(struct hbm_client_connect_response);
+ heci_hdr->msg_complete = 1;
+ heci_hdr->reserved = 0;
+
+ disconnect_res =
+ (struct hbm_client_connect_response *)
+ &dev->ext_msg_buf[1];
+ disconnect_res->host_addr = file_pos->host_client_id;
+ disconnect_res->me_addr = file_pos->me_client_id;
+ *(__u8 *) (&disconnect_res->cmd) =
+ CLIENT_DISCONNECT_RES_CMD;
+ disconnect_res->status = 0;
+ dev->extra_write_index = 2;
+ break;
+ }
+ }
+}
+
+/**
+ * heci_timer - timer function.
+ *
+ * @data: pointer to the device structure
+ *
+ * NOTE: This function is called by timer interrupt work
+ */
+void heci_wd_timer(unsigned long data)
+{
+ struct iamt_heci_device *dev = (struct iamt_heci_device *) data;
+
+ DBG("send watchdog.\n");
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+ if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
+ mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+ spin_unlock_bh(&dev->device_lock);
+ return;
+ }
+ /* Watchdog */
+ if ((dev->wd_due_counter != 0) && (dev->wd_bypass == 0)) {
+ if (--dev->wd_due_counter == 0) {
+ if (dev->host_buffer_is_empty &&
+ flow_ctrl_creds(dev, &dev->wd_file_ext)) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_send_wd(dev)) {
+ DBG("wd send failed.\n");
+ } else {
+ flow_ctrl_reduce(dev,
+ &dev->wd_file_ext);
+ }
+
+ if (dev->wd_timeout != 0)
+ dev->wd_due_counter = 2;
+ else
+ dev->wd_due_counter = 0;
+
+ } else
+ dev->wd_pending = 1;
+
+ }
+ }
+ if (dev->iamthif_stall_timer != 0) {
+ if (--dev->iamthif_stall_timer == 0) {
+ DBG("reseting because of hang to PTHI.\n");
+ heci_reset(dev, 1);
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_ioctl = 1;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+ spin_unlock_bh(&dev->device_lock);
+
+ if (dev->iamthif_current_cb)
+ heci_free_cb_private(dev->iamthif_current_cb);
+
+ spin_lock_bh(&dev->device_lock);
+ dev->iamthif_file_object = NULL;
+ dev->iamthif_current_cb = NULL;
+ run_next_iamthif_cmd(dev);
+ }
+ }
+ mod_timer(&dev->wd_timer, round_jiffies(jiffies + 2 * HZ));
+ spin_unlock_bh(&dev->device_lock);
+}
diff --git a/drivers/staging/heci/io_heci.c b/drivers/staging/heci/io_heci.c
new file mode 100644
index 00000000000..f7544a7bbbe
--- /dev/null
+++ b/drivers/staging/heci/io_heci.c
@@ -0,0 +1,847 @@
+/*
+ * Part of Intel(R) Manageability Engine Interface Linux driver
+ *
+ * Copyright (c) 2003 - 2008 Intel Corp.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce at minimum a disclaimer
+ * substantially similar to the "NO WARRANTY" disclaimer below
+ * ("Disclaimer") and any redistribution must be conditioned upon
+ * including a substantially similar Disclaimer requirement for further
+ * binary redistribution.
+ * 3. Neither the names of the above-listed copyright holders nor the names
+ * of any contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * NO WARRANTY
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGES.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/aio.h>
+#include <linux/pci.h>
+#include <linux/reboot.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+#include <linux/cdev.h>
+#include <linux/list.h>
+#include <linux/unistd.h>
+#include <linux/delay.h>
+
+#include "heci_data_structures.h"
+#include "heci.h"
+#include "heci_interface.h"
+#include "heci_version.h"
+
+
+/**
+ * heci_ioctl_get_version - the get driver version IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @*u_msg: pointer to user data struct in user space
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext)
+{
+ int rets = 0;
+ struct heci_driver_version *version;
+ struct heci_message_data res_msg;
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev)
+ || (!file_ext))
+ return -ENODEV;
+
+ if (k_msg.size < (sizeof(struct heci_driver_version) - 2)) {
+ DBG("user buffer less than heci_driver_version.\n");
+ return -EMSGSIZE;
+ }
+
+ res_msg.data = kmalloc(sizeof(struct heci_driver_version), GFP_KERNEL);
+ if (!res_msg.data) {
+ DBG("failed allocation response buffer size = %d.\n",
+ (int) sizeof(struct heci_driver_version));
+ return -ENOMEM;
+ }
+
+ version = (struct heci_driver_version *) res_msg.data;
+ version->major = MAJOR_VERSION;
+ version->minor = MINOR_VERSION;
+ version->hotfix = QUICK_FIX_NUMBER;
+ version->build = VER_BUILD;
+ res_msg.size = sizeof(struct heci_driver_version);
+ if (k_msg.size < sizeof(struct heci_driver_version))
+ res_msg.size -= 2;
+
+ rets = file_ext->status;
+ /* now copy the data to user space */
+ if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ if (put_user(res_msg.size, &u_msg->size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+end:
+ kfree(res_msg.data);
+ return rets;
+}
+
+/**
+ * heci_ioctl_connect_client - the connect to fw client IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @*u_msg: pointer to user data struct in user space
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data __user *u_msg,
+ struct heci_message_data k_msg,
+ struct file *file)
+{
+ int rets = 0;
+ struct heci_message_data req_msg, res_msg;
+ struct heci_cb_private *priv_cb = NULL;
+ struct heci_client *client;
+ struct heci_file_private *file_ext;
+ struct heci_file_private *file_pos = NULL;
+ struct heci_file_private *file_next = NULL;
+ long timeout = 15; /*15 second */
+ __u8 i;
+ int err = 0;
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file))
+ return -ENODEV;
+
+ file_ext = file->private_data;
+ if (!file_ext)
+ return -ENODEV;
+
+ if (k_msg.size != sizeof(struct guid)) {
+ DBG("user buffer size is not equal to size of struct "
+ "guid(16).\n");
+ return -EMSGSIZE;
+ }
+
+ if (!k_msg.data)
+ return -EIO;
+
+ req_msg.data = kmalloc(sizeof(struct guid), GFP_KERNEL);
+ res_msg.data = kmalloc(sizeof(struct heci_client), GFP_KERNEL);
+
+ if (!res_msg.data) {
+ DBG("failed allocation response buffer size = %d.\n",
+ (int) sizeof(struct heci_client));
+ kfree(req_msg.data);
+ return -ENOMEM;
+ }
+ if (!req_msg.data) {
+ DBG("failed allocation request buffer size = %d.\n",
+ (int) sizeof(struct guid));
+ kfree(res_msg.data);
+ return -ENOMEM;
+ }
+ req_msg.size = sizeof(struct guid);
+ res_msg.size = sizeof(struct heci_client);
+
+ /* copy the message to kernel space -
+ * use a pointer already copied into kernel space
+ */
+ if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ /* buffered ioctl cb */
+ priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_cb) {
+ rets = -ENOMEM;
+ goto end;
+ }
+ INIT_LIST_HEAD(&priv_cb->cb_list);
+ priv_cb->response_buffer.data = res_msg.data;
+ priv_cb->response_buffer.size = res_msg.size;
+ priv_cb->request_buffer.data = req_msg.data;
+ priv_cb->request_buffer.size = req_msg.size;
+ priv_cb->major_file_operations = HECI_IOCTL;
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ if ((file_ext->state != HECI_FILE_INITIALIZING) &&
+ (file_ext->state != HECI_FILE_DISCONNECTED)) {
+ rets = -EBUSY;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+
+ /* find ME client we're trying to connect to */
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (memcmp((struct guid *)req_msg.data,
+ &dev->me_clients[i].props.protocol_name,
+ sizeof(struct guid)) == 0) {
+ if (dev->me_clients[i].props.fixed_address == 0) {
+ file_ext->me_client_id =
+ dev->me_clients[i].client_id;
+ file_ext->state = HECI_FILE_CONNECTING;
+ }
+ break;
+ }
+ }
+ /* if we're connecting to PTHI client so we will use the exist
+ * connection
+ */
+ if (memcmp((struct guid *)req_msg.data, &heci_pthi_guid,
+ sizeof(struct guid)) == 0) {
+ if (dev->iamthif_file_ext.state != HECI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ dev->heci_host_clients[file_ext->host_client_id / 8] &=
+ ~(1 << (file_ext->host_client_id % 8));
+ list_for_each_entry_safe(file_pos,
+ file_next, &dev->file_list, link) {
+ if (heci_fe_same_id(file_ext, file_pos)) {
+ DBG("remove file private data node host"
+ " client = %d, ME client = %d.\n",
+ file_pos->host_client_id,
+ file_pos->me_client_id);
+ list_del(&file_pos->link);
+ }
+
+ }
+ DBG("free file private data memory.\n");
+ kfree(file_ext);
+ file_ext = NULL;
+ file->private_data = &dev->iamthif_file_ext;
+ client = (struct heci_client *) res_msg.data;
+ client->max_msg_length =
+ dev->me_clients[i].props.max_msg_length;
+ client->protocol_version =
+ dev->me_clients[i].props.protocol_version;
+ rets = dev->iamthif_file_ext.status;
+ spin_unlock_bh(&dev->device_lock);
+
+ /* now copy the data to user space */
+ if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ if (put_user(res_msg.size, &u_msg->size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ goto end;
+ }
+ spin_lock(&file_ext->file_lock);
+ if (file_ext->state != HECI_FILE_CONNECTING) {
+ rets = -ENODEV;
+ spin_unlock(&file_ext->file_lock);
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ spin_unlock(&file_ext->file_lock);
+ /* prepare the output buffer */
+ client = (struct heci_client *) res_msg.data;
+ client->max_msg_length = dev->me_clients[i].props.max_msg_length;
+ client->protocol_version = dev->me_clients[i].props.protocol_version;
+ if (dev->host_buffer_is_empty
+ && !other_client_is_connecting(dev, file_ext)) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_connect(dev, file_ext)) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ } else {
+ file_ext->timer_count = HECI_CONNECT_TIMEOUT;
+ priv_cb->file_private = file_ext;
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_rd_list.heci_cb.
+ cb_list);
+ }
+
+
+ } else {
+ priv_cb->file_private = file_ext;
+ DBG("add connect cb to control write list.\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_wr_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+ err = wait_event_timeout(dev->wait_recvd_msg,
+ (HECI_FILE_CONNECTED == file_ext->state
+ || HECI_FILE_DISCONNECTED == file_ext->state),
+ timeout * HZ);
+
+ if (HECI_FILE_CONNECTED == file_ext->state) {
+ DBG("successfully connected to FW client.\n");
+ rets = file_ext->status;
+ /* now copy the data to user space */
+ if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ if (put_user(res_msg.size, &u_msg->size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ goto end;
+ } else {
+ DBG("failed to connect to FW client.file_ext->state = %d.\n",
+ file_ext->state);
+ if (!err) {
+ DBG("wait_event_interruptible_timeout failed on client"
+ " connect message fw response message.\n");
+ }
+ rets = -EFAULT;
+ goto remove_list;
+ }
+
+remove_list:
+ if (priv_cb) {
+ spin_lock_bh(&dev->device_lock);
+ heci_flush_list(&dev->ctrl_rd_list, file_ext);
+ heci_flush_list(&dev->ctrl_wr_list, file_ext);
+ spin_unlock_bh(&dev->device_lock);
+ }
+end:
+ DBG("free connect cb memory.");
+ kfree(req_msg.data);
+ kfree(res_msg.data);
+ kfree(priv_cb);
+ return rets;
+}
+
+/**
+ * heci_ioctl_wd - the wd IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext)
+{
+ int rets = 0;
+ struct heci_message_data req_msg; /*in kernel on the stack */
+
+ if (if_num != HECI_MINOR_NUMBER)
+ return -ENODEV;
+
+ spin_lock(&file_ext->file_lock);
+ if (k_msg.size != HECI_WATCHDOG_DATA_SIZE) {
+ DBG("user buffer has invalid size.\n");
+ spin_unlock(&file_ext->file_lock);
+ return -EMSGSIZE;
+ }
+ spin_unlock(&file_ext->file_lock);
+
+ req_msg.data = kmalloc(HECI_WATCHDOG_DATA_SIZE, GFP_KERNEL);
+ if (!req_msg.data) {
+ DBG("failed allocation request buffer size = %d.\n",
+ HECI_WATCHDOG_DATA_SIZE);
+ return -ENOMEM;
+ }
+ req_msg.size = HECI_WATCHDOG_DATA_SIZE;
+
+ /* copy the message to kernel space - use a pointer already
+ * copied into kernel space
+ */
+ if (copy_from_user(req_msg.data, k_msg.data, req_msg.size)) {
+ rets = -EFAULT;
+ goto end;
+ }
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+
+ if (dev->wd_file_ext.state != HECI_FILE_CONNECTED) {
+ rets = -ENODEV;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+ if (!dev->asf_mode) {
+ rets = -EIO;
+ spin_unlock_bh(&dev->device_lock);
+ goto end;
+ }
+
+ memcpy(&dev->wd_data[HECI_WD_PARAMS_SIZE], req_msg.data,
+ HECI_WATCHDOG_DATA_SIZE);
+
+ dev->wd_timeout = (req_msg.data[1] << 8) + req_msg.data[0];
+ dev->wd_pending = 0;
+ dev->wd_due_counter = 1; /* next timer */
+ if (dev->wd_timeout == 0) {
+ memcpy(dev->wd_data, heci_stop_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ } else {
+ memcpy(dev->wd_data, heci_start_wd_params,
+ HECI_WD_PARAMS_SIZE);
+ mod_timer(&dev->wd_timer, jiffies);
+ }
+ spin_unlock_bh(&dev->device_lock);
+end:
+ kfree(req_msg.data);
+ return rets;
+}
+
+
+/**
+ * heci_ioctl_bypass_wd - the bypass_wd IOCTL function
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @k_msg: data in kernel on the stack
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num,
+ struct heci_message_data k_msg,
+ struct heci_file_private *file_ext)
+{
+ __u8 flag = 0;
+ int rets = 0;
+
+ if (if_num != HECI_MINOR_NUMBER)
+ return -ENODEV;
+
+ spin_lock(&file_ext->file_lock);
+ if (k_msg.size < 1) {
+ DBG("user buffer less than HECI_WATCHDOG_DATA_SIZE.\n");
+ spin_unlock(&file_ext->file_lock);
+ return -EMSGSIZE;
+ }
+ spin_unlock(&file_ext->file_lock);
+ if (copy_from_user(&flag, k_msg.data, 1)) {
+ rets = -EFAULT;
+ goto end;
+ }
+
+ spin_lock_bh(&dev->device_lock);
+ flag = flag ? (1) : (0);
+ dev->wd_bypass = flag;
+ spin_unlock_bh(&dev->device_lock);
+end:
+ return rets;
+}
+
+/**
+ * find_pthi_read_list_entry - finds a PTHIlist entry for current file
+ *
+ * @dev: Device object for our driver
+ * @file: pointer to file object
+ *
+ * returns returned a list entry on success, NULL on failure.
+ */
+struct heci_cb_private *find_pthi_read_list_entry(
+ struct iamt_heci_device *dev,
+ struct file *file)
+{
+ struct heci_file_private *file_ext_temp;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+
+ if ((dev->pthi_read_complete_list.status == 0) &&
+ !list_empty(&dev->pthi_read_complete_list.heci_cb.cb_list)) {
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->pthi_read_complete_list.heci_cb.cb_list, cb_list) {
+ file_ext_temp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+ if ((file_ext_temp != NULL) &&
+ (file_ext_temp == &dev->iamthif_file_ext) &&
+ (priv_cb_pos->file_object == file))
+ return priv_cb_pos;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * pthi_read - read data from pthi client
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @file: pointer to file object
+ * @*ubuf: pointer to user data in user space
+ * @length: data length to read
+ * @offset: data read offset
+ *
+ * returns
+ * returned data length on success,
+ * zero if no data to read,
+ * negative on failure.
+ */
+int pthi_read(struct iamt_heci_device *dev, int if_num, struct file *file,
+ char __user *ubuf, size_t length, loff_t *offset)
+{
+ int rets = 0;
+ struct heci_cb_private *priv_cb = NULL;
+ struct heci_file_private *file_ext = file->private_data;
+ __u8 i;
+ unsigned long currtime = get_seconds();
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev))
+ return -ENODEV;
+
+ if ((file_ext == NULL) || (file_ext != &dev->iamthif_file_ext))
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id ==
+ dev->iamthif_file_ext.me_client_id)
+ break;
+ }
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if ((i == dev->num_heci_me_clients)
+ || (dev->me_clients[i].client_id !=
+ dev->iamthif_file_ext.me_client_id)) {
+ DBG("PTHI client not found.\n");
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ priv_cb = find_pthi_read_list_entry(dev, file);
+ if (!priv_cb) {
+ spin_unlock_bh(&dev->device_lock);
+ return 0; /* No more data to read */
+ } else {
+ if (priv_cb &&
+ (currtime - priv_cb->read_time > IAMTHIF_READ_TIMER)) {
+ /* 15 sec for the message has expired */
+ list_del(&priv_cb->cb_list);
+ spin_unlock_bh(&dev->device_lock);
+ rets = -ETIMEDOUT;
+ goto free;
+ }
+ /* if the whole message will fit remove it from the list */
+ if ((priv_cb->information >= *offset) &&
+ (length >= (priv_cb->information - *offset)))
+ list_del(&priv_cb->cb_list);
+ else if ((priv_cb->information > 0) &&
+ (priv_cb->information <= *offset)) {
+ /* end of the message has been reached */
+ list_del(&priv_cb->cb_list);
+ rets = 0;
+ spin_unlock_bh(&dev->device_lock);
+ goto free;
+ }
+ /* else means that not full buffer will be read and do not
+ * remove message from deletion list
+ */
+ }
+ DBG("pthi priv_cb->response_buffer size - %d\n",
+ priv_cb->response_buffer.size);
+ DBG("pthi priv_cb->information - %lu\n",
+ priv_cb->information);
+ spin_unlock_bh(&dev->device_lock);
+
+ /* length is being turncated to PAGE_SIZE, however,
+ * the information may be longer */
+ length = length < (priv_cb->information - *offset) ?
+ length : (priv_cb->information - *offset);
+
+ if (copy_to_user(ubuf,
+ priv_cb->response_buffer.data + *offset,
+ length))
+ rets = -EFAULT;
+ else {
+ rets = length;
+ if ((*offset + length) < priv_cb->information) {
+ *offset += length;
+ goto out;
+ }
+ }
+free:
+ DBG("free pthi cb memory.\n");
+ *offset = 0;
+ heci_free_cb_private(priv_cb);
+out:
+ return rets;
+}
+
+/**
+ * heci_start_read - the start read client message function.
+ *
+ * @dev: Device object for our driver
+ * @if_num: minor number
+ * @file_ext: private data of the file object
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int heci_start_read(struct iamt_heci_device *dev, int if_num,
+ struct heci_file_private *file_ext)
+{
+ int rets = 0;
+ __u8 i;
+ struct heci_cb_private *priv_cb = NULL;
+
+ if ((if_num != HECI_MINOR_NUMBER) || (!dev) || (!file_ext)) {
+ DBG("received wrong function input param.\n");
+ return -ENODEV;
+ }
+ if (file_ext->state != HECI_FILE_CONNECTED)
+ return -ENODEV;
+
+ spin_lock_bh(&dev->device_lock);
+ if (dev->heci_state != HECI_ENABLED) {
+ spin_unlock_bh(&dev->device_lock);
+ return -ENODEV;
+ }
+ spin_unlock_bh(&dev->device_lock);
+ DBG("check if read is pending.\n");
+ if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) {
+ DBG("read is pending.\n");
+ return -EBUSY;
+ }
+ priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL);
+ if (!priv_cb)
+ return -ENOMEM;
+
+ DBG("allocation call back success\n"
+ "host client = %d, ME client = %d\n",
+ file_ext->host_client_id, file_ext->me_client_id);
+ spin_lock_bh(&dev->device_lock);
+ for (i = 0; i < dev->num_heci_me_clients; i++) {
+ if (dev->me_clients[i].client_id == file_ext->me_client_id)
+ break;
+
+ }
+
+ BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id);
+ if (i == dev->num_heci_me_clients) {
+ rets = -ENODEV;
+ goto unlock;
+ }
+
+ priv_cb->response_buffer.size = dev->me_clients[i].props.max_msg_length;
+ spin_unlock_bh(&dev->device_lock);
+ priv_cb->response_buffer.data =
+ kmalloc(priv_cb->response_buffer.size, GFP_KERNEL);
+ if (!priv_cb->response_buffer.data) {
+ rets = -ENOMEM;
+ goto fail;
+ }
+ DBG("allocation call back data success.\n");
+ priv_cb->major_file_operations = HECI_READ;
+ /* make sure information is zero before we start */
+ priv_cb->information = 0;
+ priv_cb->file_private = (void *) file_ext;
+ file_ext->read_cb = priv_cb;
+ spin_lock_bh(&dev->device_lock);
+ if (dev->host_buffer_is_empty) {
+ dev->host_buffer_is_empty = 0;
+ if (!heci_send_flow_control(dev, file_ext)) {
+ rets = -ENODEV;
+ goto unlock;
+ } else {
+ list_add_tail(&priv_cb->cb_list,
+ &dev->read_list.heci_cb.cb_list);
+ }
+ } else {
+ list_add_tail(&priv_cb->cb_list,
+ &dev->ctrl_wr_list.heci_cb.cb_list);
+ }
+ spin_unlock_bh(&dev->device_lock);
+ return rets;
+unlock:
+ spin_unlock_bh(&dev->device_lock);
+fail:
+ heci_free_cb_private(priv_cb);
+ return rets;
+}
+
+/**
+ * pthi_write - write iamthif data to pthi client
+ *
+ * @dev: Device object for our driver
+ * @priv_cb: heci call back struct
+ *
+ * returns 0 on success, <0 on failure.
+ */
+int pthi_write(struct iamt_heci_device *dev,
+ struct heci_cb_private *priv_cb)
+{
+ int rets = 0;
+ struct heci_msg_hdr heci_hdr;
+
+ if ((!dev) || (!priv_cb))
+ return -ENODEV;
+
+ DBG("write data to pthi client.\n");
+
+ dev->iamthif_state = HECI_IAMTHIF_WRITING;
+ dev->iamthif_current_cb = priv_cb;
+ dev->iamthif_file_object = priv_cb->file_object;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_ioctl = 1;
+ dev->iamthif_msg_buf_size = priv_cb->request_buffer.size;
+ memcpy(dev->iamthif_msg_buf, priv_cb->request_buffer.data,
+ priv_cb->request_buffer.size);
+
+ if (flow_ctrl_creds(dev, &dev->iamthif_file_ext) &&
+ dev->host_buffer_is_empty) {
+ dev->host_buffer_is_empty = 0;
+ if (priv_cb->request_buffer.size >
+ (((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) - sizeof(struct heci_msg_hdr)) {
+ heci_hdr.length =
+ (((dev->host_hw_state & H_CBD) >> 24) *
+ sizeof(__u32)) - sizeof(struct heci_msg_hdr);
+ heci_hdr.msg_complete = 0;
+ } else {
+ heci_hdr.length = priv_cb->request_buffer.size;
+ heci_hdr.msg_complete = 1;
+ }
+
+ heci_hdr.host_addr = dev->iamthif_file_ext.host_client_id;
+ heci_hdr.me_addr = dev->iamthif_file_ext.me_client_id;
+ heci_hdr.reserved = 0;
+ dev->iamthif_msg_buf_index += heci_hdr.length;
+ if (!heci_write_message(dev, &heci_hdr,
+ (unsigned char *)(dev->iamthif_msg_buf),
+ heci_hdr.length))
+ return -ENODEV;
+
+ if (heci_hdr.msg_complete) {
+ flow_ctrl_reduce(dev, &dev->iamthif_file_ext);
+ dev->iamthif_flow_control_pending = 1;
+ dev->iamthif_state = HECI_IAMTHIF_FLOW_CONTROL;
+ DBG("add pthi cb to write waiting list\n");
+ dev->iamthif_current_cb = priv_cb;
+ dev->iamthif_file_object = priv_cb->file_object;
+ list_add_tail(&priv_cb->cb_list,
+ &dev->write_waiting_list.heci_cb.cb_list);
+ } else {
+ DBG("message does not complete, "
+ "so add pthi cb to write list.\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ } else {
+ if (!(dev->host_buffer_is_empty))
+ DBG("host buffer is not empty");
+
+ DBG("No flow control credentials, "
+ "so add iamthif cb to write list.\n");
+ list_add_tail(&priv_cb->cb_list,
+ &dev->write_list.heci_cb.cb_list);
+ }
+ return rets;
+}
+
+/**
+ * iamthif_ioctl_send_msg - send cmd data to pthi client
+ *
+ * @dev: Device object for our driver
+ *
+ * returns 0 on success, <0 on failure.
+ */
+void run_next_iamthif_cmd(struct iamt_heci_device *dev)
+{
+ struct heci_file_private *file_ext_tmp;
+ struct heci_cb_private *priv_cb_pos = NULL;
+ struct heci_cb_private *priv_cb_next = NULL;
+ int status = 0;
+
+ if (!dev)
+ return;
+
+ dev->iamthif_msg_buf_size = 0;
+ dev->iamthif_msg_buf_index = 0;
+ dev->iamthif_canceled = 0;
+ dev->iamthif_ioctl = 1;
+ dev->iamthif_state = HECI_IAMTHIF_IDLE;
+ dev->iamthif_timer = 0;
+ dev->iamthif_file_object = NULL;
+
+ if (dev->pthi_cmd_list.status == 0 &&
+ !list_empty(&dev->pthi_cmd_list.heci_cb.cb_list)) {
+ DBG("complete pthi cmd_list cb.\n");
+
+ list_for_each_entry_safe(priv_cb_pos, priv_cb_next,
+ &dev->pthi_cmd_list.heci_cb.cb_list, cb_list) {
+ list_del(&priv_cb_pos->cb_list);
+ file_ext_tmp = (struct heci_file_private *)
+ priv_cb_pos->file_private;
+
+ if ((file_ext_tmp != NULL) &&
+ (file_ext_tmp == &dev->iamthif_file_ext)) {
+ status = pthi_write(dev, priv_cb_pos);
+ if (status != 0) {
+ DBG("pthi write failed status = %d\n",
+ status);
+ return;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/**
+ * heci_free_cb_private - free heci_cb_private related memory
+ *
+ * @priv_cb: heci callback struct
+ */
+void heci_free_cb_private(struct heci_cb_private *priv_cb)
+{
+ if (priv_cb == NULL)
+ return;
+
+ kfree(priv_cb->request_buffer.data);
+ kfree(priv_cb->response_buffer.data);
+ kfree(priv_cb);
+}
+
diff --git a/drivers/staging/line6/Kconfig b/drivers/staging/line6/Kconfig
new file mode 100644
index 00000000000..7852d4a960c
--- /dev/null
+++ b/drivers/staging/line6/Kconfig
@@ -0,0 +1,21 @@
+config LINE6_USB
+ tristate "Line6 USB support"
+ depends on USB && SND
+ select SND_RAWMIDI
+ help
+ This is a driver for the guitar amp, cab, and effects modeller
+ PODxt Pro by Line6 (and similar devices), supporting the
+ following features:
+ * Reading/writing individual parameters
+ * Reading/writing complete channel, effects setup, and amp
+ setup data
+ * Channel switching
+ * Virtual MIDI interface
+ * Tuner access
+ * Playback/capture/mixer device for any ALSA-compatible PCM
+ audio application
+ * Signal routing (record clean/processed guitar signal,
+ re-amping)
+
+ Preliminary support for the Variax Workbench is included.
+
diff --git a/drivers/staging/line6/Makefile b/drivers/staging/line6/Makefile
new file mode 100644
index 00000000000..a1c93edc6b1
--- /dev/null
+++ b/drivers/staging/line6/Makefile
@@ -0,0 +1,15 @@
+obj-$(CONFIG_LINE6_USB) += line6usb.o
+
+line6usb-objs := \
+ audio.o \
+ capture.o \
+ control.o \
+ driver.o \
+ dumprequest.o \
+ midi.o \
+ midibuf.o \
+ pcm.o \
+ playback.o \
+ pod.o \
+ toneport.o \
+ variax.o
diff --git a/drivers/staging/line6/audio.c b/drivers/staging/line6/audio.c
new file mode 100644
index 00000000000..3aa946899ce
--- /dev/null
+++ b/drivers/staging/line6/audio.c
@@ -0,0 +1,72 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+#include "audio.h"
+
+#include <sound/core.h>
+#include <sound/initval.h>
+
+
+static int line6_index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *line6_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+
+
+/*
+ Initialize the Line6 USB audio system.
+*/
+int line6_init_audio(struct usb_line6 *line6)
+{
+ static int dev;
+ struct snd_card *card;
+
+ card = snd_card_new(line6_index[dev], line6_id[dev], THIS_MODULE, 0);
+
+ if (card == NULL)
+ return -ENOMEM;
+
+ line6->card = card;
+
+ strcpy(card->driver, DRIVER_NAME);
+ strcpy(card->shortname, "Line6-USB");
+ sprintf(card->longname, "Line6 %s at USB %s", line6->properties->name,
+ dev_name(line6->ifcdev)); /* 80 chars - see asound.h */
+ return 0;
+}
+
+/*
+ Register the Line6 USB audio system.
+*/
+int line6_register_audio(struct usb_line6 *line6)
+{
+ int err;
+
+ err = snd_card_register(line6->card);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+/*
+ Cleanup the Line6 USB audio system.
+*/
+void line6_cleanup_audio(struct usb_line6 *line6)
+{
+ struct snd_card *card = line6->card;
+
+ if (card == NULL)
+ return;
+
+ snd_card_disconnect(card);
+ snd_card_free(card);
+ line6->card = NULL;
+}
diff --git a/drivers/staging/line6/audio.h b/drivers/staging/line6/audio.h
new file mode 100644
index 00000000000..cc0245adbcd
--- /dev/null
+++ b/drivers/staging/line6/audio.h
@@ -0,0 +1,24 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef AUDIO_H
+#define AUDIO_H
+
+
+#include "driver.h"
+
+
+extern void line6_cleanup_audio(struct usb_line6 *);
+extern int line6_init_audio(struct usb_line6 *);
+extern int line6_register_audio(struct usb_line6 *);
+
+
+#endif
diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c
new file mode 100644
index 00000000000..8393e25a10b
--- /dev/null
+++ b/drivers/staging/line6/capture.c
@@ -0,0 +1,372 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "pcm.h"
+#include "pod.h"
+#include "capture.h"
+
+
+/*
+ Find a free URB and submit it.
+*/
+static int submit_audio_in_urb(struct snd_pcm_substream *substream)
+{
+ int index;
+ unsigned long flags;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ int i, urb_size;
+ struct urb *urb_in;
+
+ spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+ index = find_first_zero_bit(&line6pcm->active_urb_in, LINE6_ISO_BUFFERS);
+
+ if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+ spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+ dev_err(s2m(substream), "no free URB found\n");
+ return -EINVAL;
+ }
+
+ urb_in = line6pcm->urb_audio_in[index];
+ urb_size = 0;
+
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ struct usb_iso_packet_descriptor *fin = &urb_in->iso_frame_desc[i];
+ fin->offset = urb_size;
+ fin->length = line6pcm->max_packet_size;
+ urb_size += line6pcm->max_packet_size;
+ }
+
+ urb_in->transfer_buffer = line6pcm->buffer_in + index * LINE6_ISO_PACKETS * line6pcm->max_packet_size;
+ urb_in->transfer_buffer_length = urb_size;
+ urb_in->context = substream;
+
+ if (usb_submit_urb(urb_in, GFP_ATOMIC) == 0)
+ set_bit(index, &line6pcm->active_urb_in);
+ else
+ dev_err(s2m(substream), "URB in #%d submission failed\n", index);
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+ return 0;
+}
+
+/*
+ Submit all currently available capture URBs.
+*/
+static int submit_audio_in_all_urbs(struct snd_pcm_substream *substream)
+{
+ int ret, i;
+
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ ret = submit_audio_in_urb(substream);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Unlink all currently active capture URBs.
+*/
+static void unlink_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unsigned int i;
+
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_in)) {
+ if (!test_and_set_bit(i, &line6pcm->unlink_urb_in)) {
+ struct urb *u = line6pcm->urb_audio_in[i];
+ usb_unlink_urb(u);
+ }
+ }
+ }
+}
+
+/*
+ Wait until unlinking of all currently active capture URBs has been
+ finished.
+*/
+static void wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int timeout = HZ;
+ unsigned int i;
+ int alive;
+
+ do {
+ alive = 0;
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_in))
+ alive++;
+ }
+ if (!alive)
+ break;
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ } while (--timeout > 0);
+ if (alive)
+ snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
+
+ line6pcm->active_urb_in = 0;
+ line6pcm->unlink_urb_in = 0;
+}
+
+/*
+ Unlink all currently active capture URBs, and wait for finishing.
+*/
+void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unlink_audio_in_urbs(line6pcm);
+ wait_clear_audio_in_urbs(line6pcm);
+}
+
+/*
+ Callback for completed capture URB.
+*/
+static void audio_in_callback(struct urb *urb)
+{
+ int i, index, length = 0, shutdown = 0;
+ int frames;
+ unsigned long flags;
+
+ struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ /* find index of URB */
+ for (index = 0; index < LINE6_ISO_BUFFERS; ++index)
+ if (urb == line6pcm->urb_audio_in[index])
+ break;
+
+#if DO_DUMP_PCM_RECEIVE
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ struct usb_iso_packet_descriptor *fout = &urb->iso_frame_desc[i];
+ line6_write_hexdump(line6pcm->line6, 'C', urb->transfer_buffer + fout->offset, fout->length);
+ }
+#endif
+
+ spin_lock_irqsave(&line6pcm->lock_audio_in, flags);
+
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ char *fbuf;
+ int fsize;
+ struct usb_iso_packet_descriptor *fin = &urb->iso_frame_desc[i];
+
+ if (fin->status == -18) {
+ shutdown = 1;
+ break;
+ }
+
+ fbuf = urb->transfer_buffer + fin->offset;
+ fsize = fin->actual_length;
+ length += fsize;
+
+ if (fsize > 0) {
+ frames = fsize / bytes_per_frame;
+
+ if (line6pcm->pos_in_done + frames > runtime->buffer_size) {
+ /*
+ The transferred area goes over buffer boundary,
+ copy two separate chunks.
+ */
+ int len;
+ len = runtime->buffer_size - line6pcm->pos_in_done;
+
+ if (len > 0) {
+ memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, len * bytes_per_frame);
+ memcpy(runtime->dma_area, fbuf + len * bytes_per_frame, (frames - len) * bytes_per_frame);
+ } else
+ dev_err(s2m(substream), "driver bug: len = %d\n", len); /* this is somewhat paranoid */
+ } else {
+ /* copy single chunk */
+ memcpy(runtime->dma_area + line6pcm->pos_in_done * bytes_per_frame, fbuf, fsize * bytes_per_frame);
+ }
+
+ if ((line6pcm->pos_in_done += frames) >= runtime->buffer_size)
+ line6pcm->pos_in_done -= runtime->buffer_size;
+ }
+ }
+
+ clear_bit(index, &line6pcm->active_urb_in);
+
+ if (test_bit(index, &line6pcm->unlink_urb_in))
+ shutdown = 1;
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_in, flags);
+
+ if (!shutdown) {
+ submit_audio_in_urb(substream);
+
+ if ((line6pcm->bytes_in += length) >= line6pcm->period_in) {
+ line6pcm->bytes_in -= line6pcm->period_in;
+ snd_pcm_period_elapsed(substream);
+ }
+ }
+}
+
+/* open capture callback */
+static int snd_line6_capture_open(struct snd_pcm_substream *substream)
+{
+ int err;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ err = snd_pcm_hw_constraint_ratdens(runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ (&line6pcm->properties->snd_line6_rates));
+ if (err < 0)
+ return err;
+
+ runtime->hw = line6pcm->properties->snd_line6_capture_hw;
+ return 0;
+}
+
+/* close capture callback */
+static int snd_line6_capture_close(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+/* hw_params capture callback */
+static int snd_line6_capture_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ int ret;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ /* -- Florian Demski [FD] */
+ /* don't ask me why, but this fixes the bug on my machine */
+ if (line6pcm == NULL) {
+ if (substream->pcm == NULL)
+ return -ENOMEM;
+ if (substream->pcm->private_data == NULL)
+ return -ENOMEM;
+ substream->private_data = substream->pcm->private_data;
+ line6pcm = snd_pcm_substream_chip(substream);
+ }
+ /* -- [FD] end */
+
+ ret = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (ret < 0)
+ return ret;
+
+ line6pcm->period_in = params_period_bytes(hw_params);
+ line6pcm->buffer_in = kmalloc(LINE6_ISO_BUFFERS * LINE6_ISO_PACKETS * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
+
+ if (!line6pcm->buffer_in) {
+ dev_err(s2m(substream), "cannot malloc buffer_in\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/* hw_free capture callback */
+static int snd_line6_capture_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+
+ kfree(line6pcm->buffer_in);
+ line6pcm->buffer_in = NULL;
+
+ return snd_pcm_lib_free_pages(substream);
+}
+
+/* trigger callback */
+int snd_line6_capture_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ int err;
+ line6pcm->count_in = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ if (!test_and_set_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags)) {
+ err = submit_audio_in_all_urbs(substream);
+
+ if (err < 0) {
+ clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags);
+ return err;
+ }
+ }
+
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ if (test_and_clear_bit(BIT_RUNNING_CAPTURE, &line6pcm->flags))
+ unlink_audio_in_urbs(line6pcm);
+
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* capture pointer callback */
+static snd_pcm_uframes_t
+snd_line6_capture_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ return line6pcm->pos_in_done;
+}
+
+/* capture operators */
+struct snd_pcm_ops snd_line6_capture_ops = {
+ .open = snd_line6_capture_open,
+ .close = snd_line6_capture_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_line6_capture_hw_params,
+ .hw_free = snd_line6_capture_hw_free,
+ .prepare = snd_line6_prepare,
+ .trigger = snd_line6_trigger,
+ .pointer = snd_line6_capture_pointer,
+};
+
+int create_audio_in_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int i;
+
+ /* create audio URBs and fill in constant values: */
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ struct urb *urb;
+
+ /* URB for audio in: */
+ urb = line6pcm->urb_audio_in[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+ if (urb == NULL) {
+ dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ urb->dev = line6pcm->line6->usbdev;
+ urb->pipe = usb_rcvisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_read & USB_ENDPOINT_NUMBER_MASK);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->start_frame = -1;
+ urb->number_of_packets = LINE6_ISO_PACKETS;
+ urb->interval = LINE6_ISO_INTERVAL;
+ urb->error_count = 0;
+ urb->complete = audio_in_callback;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/line6/capture.h b/drivers/staging/line6/capture.h
new file mode 100644
index 00000000000..5c44464d29d
--- /dev/null
+++ b/drivers/staging/line6/capture.h
@@ -0,0 +1,32 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef CAPTURE_H
+#define CAPTURE_H
+
+
+#include "driver.h"
+
+#include <sound/pcm.h>
+
+#include "pcm.h"
+
+
+extern struct snd_pcm_ops snd_line6_capture_ops;
+
+
+extern int create_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+extern int snd_line6_capture_trigger(struct snd_pcm_substream *substream,
+ int cmd);
+extern void unlink_wait_clear_audio_in_urbs(struct snd_line6_pcm *line6pcm);
+
+
+#endif
diff --git a/drivers/staging/line6/config.h b/drivers/staging/line6/config.h
new file mode 100644
index 00000000000..adad130c5dc
--- /dev/null
+++ b/drivers/staging/line6/config.h
@@ -0,0 +1,48 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef CONFIG_H
+#define CONFIG_H
+
+
+#ifdef CONFIG_USB_DEBUG
+#define DEBUG 1
+#endif
+
+
+/**
+ Development tools.
+*/
+#define DO_DEBUG_MESSAGES 0
+#define DO_DUMP_URB_SEND DO_DEBUG_MESSAGES
+#define DO_DUMP_URB_RECEIVE DO_DEBUG_MESSAGES
+#define DO_DUMP_PCM_SEND 0
+#define DO_DUMP_PCM_RECEIVE 0
+#define DO_DUMP_MIDI_SEND DO_DEBUG_MESSAGES
+#define DO_DUMP_MIDI_RECEIVE DO_DEBUG_MESSAGES
+#define DO_DUMP_ANY (DO_DUMP_URB_SEND || DO_DUMP_URB_RECEIVE || \
+ DO_DUMP_PCM_SEND || DO_DUMP_PCM_RECEIVE || \
+ DO_DUMP_MIDI_SEND || DO_DUMP_MIDI_RECEIVE)
+#define CREATE_RAW_FILE 0
+
+#if DO_DEBUG_MESSAGES
+#define CHECKPOINT printk(KERN_INFO "line6usb: %s (%s:%d)\n", \
+ __func__, __FILE__, __LINE__)
+#endif
+
+#if DO_DEBUG_MESSAGES
+#define DEBUG_MESSAGES(x) (x)
+#else
+#define DEBUG_MESSAGES(x)
+#endif
+
+
+#endif
diff --git a/drivers/staging/line6/control.c b/drivers/staging/line6/control.c
new file mode 100644
index 00000000000..23ad08e17f8
--- /dev/null
+++ b/drivers/staging/line6/control.c
@@ -0,0 +1,840 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include <linux/usb.h>
+
+#include "control.h"
+#include "pod.h"
+#include "usbdefs.h"
+#include "variax.h"
+
+#define DEVICE_ATTR2(_name1, _name2, _mode, _show, _store) \
+struct device_attribute dev_attr_##_name1 = __ATTR(_name2, _mode, _show, _store)
+
+#define LINE6_PARAM_R(PREFIX, prefix, type, param) \
+static ssize_t prefix ## _get_ ## param(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ return prefix ## _get_param_ ## type(dev, buf, PREFIX ## _ ## param); \
+}
+
+#define LINE6_PARAM_RW(PREFIX, prefix, type, param) \
+LINE6_PARAM_R(PREFIX, prefix, type, param); \
+static ssize_t prefix ## _set_ ## param(struct device *dev, \
+ struct device_attribute *attr, const char *buf, size_t count) \
+{ \
+ return prefix ## _set_param_ ## type(dev, buf, count, PREFIX ## _ ## param); \
+}
+
+#define POD_PARAM_R(type, param) LINE6_PARAM_R(POD, pod, type, param)
+#define POD_PARAM_RW(type, param) LINE6_PARAM_RW(POD, pod, type, param)
+#define VARIAX_PARAM_R(type, param) LINE6_PARAM_R(VARIAX, variax, type, param)
+#define VARIAX_PARAM_RW(type, param) LINE6_PARAM_RW(VARIAX, variax, type, param)
+
+
+static ssize_t pod_get_param_int(struct device *dev, char *buf, int param)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ return sprintf(buf, "%d\n", pod->prog_data.control[param]);
+}
+
+static ssize_t pod_set_param_int(struct device *dev, const char *buf, size_t count, int param)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ pod_transmit_parameter(pod, param, value);
+ return count;
+}
+
+static ssize_t variax_get_param_int(struct device *dev, char *buf, int param)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_variax *variax = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&variax->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ return sprintf(buf, "%d\n", variax->model_data.control[param]);
+}
+
+static ssize_t variax_get_param_float(struct device *dev, char *buf, int param)
+{
+ /*
+ We do our own floating point handling here since floats in the
+ kernel are problematic for at least two reasons: - many distros
+ are still shipped with binary kernels optimized for the ancient
+ 80386 without FPU
+ - there isn't a printf("%f")
+ (see http://www.kernelthread.com/publications/faq/335.html)
+ */
+
+ static const int BIAS = 0x7f;
+ static const int OFFSET = 0xf;
+ static const int PRECISION = 1000;
+
+ int len = 0;
+ unsigned part_int, part_frac;
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_variax *variax = usb_get_intfdata(interface);
+ const unsigned char *p = variax->model_data.control + param;
+ int retval = line6_wait_dump(&variax->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+
+ if ((p[0] == 0) && (p[1] == 0) && (p[2] == 0))
+ part_int = part_frac = 0;
+ else {
+ int exponent = (((p[0] & 0x7f) << 1) | (p[1] >> 7)) - BIAS;
+ unsigned mantissa = (p[1] << 8) | p[2] | 0x8000;
+ exponent -= OFFSET;
+
+ if (exponent >= 0) {
+ part_int = mantissa << exponent;
+ part_frac = 0;
+ } else {
+ part_int = mantissa >> -exponent;
+ part_frac = (mantissa << (32 + exponent)) & 0xffffffff;
+ }
+
+ part_frac = (part_frac / ((1UL << 31) / (PRECISION / 2 * 10)) + 5) / 10;
+ }
+
+ len += sprintf(buf + len, "%s%d.%03d\n", ((p[0] & 0x80) ? "-" : ""), part_int, part_frac);
+ return len;
+}
+
+POD_PARAM_RW(int, tweak);
+POD_PARAM_RW(int, wah_position);
+POD_PARAM_RW(int, compression_gain);
+POD_PARAM_RW(int, vol_pedal_position);
+POD_PARAM_RW(int, compression_threshold);
+POD_PARAM_RW(int, pan);
+POD_PARAM_RW(int, amp_model_setup);
+POD_PARAM_RW(int, amp_model);
+POD_PARAM_RW(int, drive);
+POD_PARAM_RW(int, bass);
+POD_PARAM_RW(int, mid);
+POD_PARAM_RW(int, lowmid);
+POD_PARAM_RW(int, treble);
+POD_PARAM_RW(int, highmid);
+POD_PARAM_RW(int, chan_vol);
+POD_PARAM_RW(int, reverb_mix);
+POD_PARAM_RW(int, effect_setup);
+POD_PARAM_RW(int, band_1_frequency);
+POD_PARAM_RW(int, presence);
+POD_PARAM_RW(int, treble__bass);
+POD_PARAM_RW(int, noise_gate_enable);
+POD_PARAM_RW(int, gate_threshold);
+POD_PARAM_RW(int, gate_decay_time);
+POD_PARAM_RW(int, stomp_enable);
+POD_PARAM_RW(int, comp_enable);
+POD_PARAM_RW(int, stomp_time);
+POD_PARAM_RW(int, delay_enable);
+POD_PARAM_RW(int, mod_param_1);
+POD_PARAM_RW(int, delay_param_1);
+POD_PARAM_RW(int, delay_param_1_note_value);
+POD_PARAM_RW(int, band_2_frequency__bass);
+POD_PARAM_RW(int, delay_param_2);
+POD_PARAM_RW(int, delay_volume_mix);
+POD_PARAM_RW(int, delay_param_3);
+POD_PARAM_RW(int, reverb_enable);
+POD_PARAM_RW(int, reverb_type);
+POD_PARAM_RW(int, reverb_decay);
+POD_PARAM_RW(int, reverb_tone);
+POD_PARAM_RW(int, reverb_pre_delay);
+POD_PARAM_RW(int, reverb_pre_post);
+POD_PARAM_RW(int, band_2_frequency);
+POD_PARAM_RW(int, band_3_frequency__bass);
+POD_PARAM_RW(int, wah_enable);
+POD_PARAM_RW(int, modulation_lo_cut);
+POD_PARAM_RW(int, delay_reverb_lo_cut);
+POD_PARAM_RW(int, volume_pedal_minimum);
+POD_PARAM_RW(int, eq_pre_post);
+POD_PARAM_RW(int, volume_pre_post);
+POD_PARAM_RW(int, di_model);
+POD_PARAM_RW(int, di_delay);
+POD_PARAM_RW(int, mod_enable);
+POD_PARAM_RW(int, mod_param_1_note_value);
+POD_PARAM_RW(int, mod_param_2);
+POD_PARAM_RW(int, mod_param_3);
+POD_PARAM_RW(int, mod_param_4);
+POD_PARAM_RW(int, mod_param_5);
+POD_PARAM_RW(int, mod_volume_mix);
+POD_PARAM_RW(int, mod_pre_post);
+POD_PARAM_RW(int, modulation_model);
+POD_PARAM_RW(int, band_3_frequency);
+POD_PARAM_RW(int, band_4_frequency__bass);
+POD_PARAM_RW(int, mod_param_1_double_precision);
+POD_PARAM_RW(int, delay_param_1_double_precision);
+POD_PARAM_RW(int, eq_enable);
+POD_PARAM_RW(int, tap);
+POD_PARAM_RW(int, volume_tweak_pedal_assign);
+POD_PARAM_RW(int, band_5_frequency);
+POD_PARAM_RW(int, tuner);
+POD_PARAM_RW(int, mic_selection);
+POD_PARAM_RW(int, cabinet_model);
+POD_PARAM_RW(int, stomp_model);
+POD_PARAM_RW(int, roomlevel);
+POD_PARAM_RW(int, band_4_frequency);
+POD_PARAM_RW(int, band_6_frequency);
+POD_PARAM_RW(int, stomp_param_1_note_value);
+POD_PARAM_RW(int, stomp_param_2);
+POD_PARAM_RW(int, stomp_param_3);
+POD_PARAM_RW(int, stomp_param_4);
+POD_PARAM_RW(int, stomp_param_5);
+POD_PARAM_RW(int, stomp_param_6);
+POD_PARAM_RW(int, amp_switch_select);
+POD_PARAM_RW(int, delay_param_4);
+POD_PARAM_RW(int, delay_param_5);
+POD_PARAM_RW(int, delay_pre_post);
+POD_PARAM_RW(int, delay_model);
+POD_PARAM_RW(int, delay_verb_model);
+POD_PARAM_RW(int, tempo_msb);
+POD_PARAM_RW(int, tempo_lsb);
+POD_PARAM_RW(int, wah_model);
+POD_PARAM_RW(int, bypass_volume);
+POD_PARAM_RW(int, fx_loop_on_off);
+POD_PARAM_RW(int, tweak_param_select);
+POD_PARAM_RW(int, amp1_engage);
+POD_PARAM_RW(int, band_1_gain);
+POD_PARAM_RW(int, band_2_gain__bass);
+POD_PARAM_RW(int, band_2_gain);
+POD_PARAM_RW(int, band_3_gain__bass);
+POD_PARAM_RW(int, band_3_gain);
+POD_PARAM_RW(int, band_4_gain__bass);
+POD_PARAM_RW(int, band_5_gain__bass);
+POD_PARAM_RW(int, band_4_gain);
+POD_PARAM_RW(int, band_6_gain__bass);
+VARIAX_PARAM_R(int, body);
+VARIAX_PARAM_R(int, pickup1_enable);
+VARIAX_PARAM_R(int, pickup1_type);
+VARIAX_PARAM_R(float, pickup1_position);
+VARIAX_PARAM_R(float, pickup1_angle);
+VARIAX_PARAM_R(float, pickup1_level);
+VARIAX_PARAM_R(int, pickup2_enable);
+VARIAX_PARAM_R(int, pickup2_type);
+VARIAX_PARAM_R(float, pickup2_position);
+VARIAX_PARAM_R(float, pickup2_angle);
+VARIAX_PARAM_R(float, pickup2_level);
+VARIAX_PARAM_R(int, pickup_phase);
+VARIAX_PARAM_R(float, capacitance);
+VARIAX_PARAM_R(float, tone_resistance);
+VARIAX_PARAM_R(float, volume_resistance);
+VARIAX_PARAM_R(int, taper);
+VARIAX_PARAM_R(float, tone_dump);
+VARIAX_PARAM_R(int, save_tone);
+VARIAX_PARAM_R(float, volume_dump);
+VARIAX_PARAM_R(int, tuning_enable);
+VARIAX_PARAM_R(int, tuning6);
+VARIAX_PARAM_R(int, tuning5);
+VARIAX_PARAM_R(int, tuning4);
+VARIAX_PARAM_R(int, tuning3);
+VARIAX_PARAM_R(int, tuning2);
+VARIAX_PARAM_R(int, tuning1);
+VARIAX_PARAM_R(float, detune6);
+VARIAX_PARAM_R(float, detune5);
+VARIAX_PARAM_R(float, detune4);
+VARIAX_PARAM_R(float, detune3);
+VARIAX_PARAM_R(float, detune2);
+VARIAX_PARAM_R(float, detune1);
+VARIAX_PARAM_R(float, mix6);
+VARIAX_PARAM_R(float, mix5);
+VARIAX_PARAM_R(float, mix4);
+VARIAX_PARAM_R(float, mix3);
+VARIAX_PARAM_R(float, mix2);
+VARIAX_PARAM_R(float, mix1);
+VARIAX_PARAM_R(int, pickup_wiring);
+
+static DEVICE_ATTR(tweak, S_IWUGO | S_IRUGO, pod_get_tweak, pod_set_tweak);
+static DEVICE_ATTR(wah_position, S_IWUGO | S_IRUGO, pod_get_wah_position, pod_set_wah_position);
+static DEVICE_ATTR(compression_gain, S_IWUGO | S_IRUGO, pod_get_compression_gain, pod_set_compression_gain);
+static DEVICE_ATTR(vol_pedal_position, S_IWUGO | S_IRUGO, pod_get_vol_pedal_position, pod_set_vol_pedal_position);
+static DEVICE_ATTR(compression_threshold, S_IWUGO | S_IRUGO, pod_get_compression_threshold, pod_set_compression_threshold);
+static DEVICE_ATTR(pan, S_IWUGO | S_IRUGO, pod_get_pan, pod_set_pan);
+static DEVICE_ATTR(amp_model_setup, S_IWUGO | S_IRUGO, pod_get_amp_model_setup, pod_set_amp_model_setup);
+static DEVICE_ATTR(amp_model, S_IWUGO | S_IRUGO, pod_get_amp_model, pod_set_amp_model);
+static DEVICE_ATTR(drive, S_IWUGO | S_IRUGO, pod_get_drive, pod_set_drive);
+static DEVICE_ATTR(bass, S_IWUGO | S_IRUGO, pod_get_bass, pod_set_bass);
+static DEVICE_ATTR(mid, S_IWUGO | S_IRUGO, pod_get_mid, pod_set_mid);
+static DEVICE_ATTR(lowmid, S_IWUGO | S_IRUGO, pod_get_lowmid, pod_set_lowmid);
+static DEVICE_ATTR(treble, S_IWUGO | S_IRUGO, pod_get_treble, pod_set_treble);
+static DEVICE_ATTR(highmid, S_IWUGO | S_IRUGO, pod_get_highmid, pod_set_highmid);
+static DEVICE_ATTR(chan_vol, S_IWUGO | S_IRUGO, pod_get_chan_vol, pod_set_chan_vol);
+static DEVICE_ATTR(reverb_mix, S_IWUGO | S_IRUGO, pod_get_reverb_mix, pod_set_reverb_mix);
+static DEVICE_ATTR(effect_setup, S_IWUGO | S_IRUGO, pod_get_effect_setup, pod_set_effect_setup);
+static DEVICE_ATTR(band_1_frequency, S_IWUGO | S_IRUGO, pod_get_band_1_frequency, pod_set_band_1_frequency);
+static DEVICE_ATTR(presence, S_IWUGO | S_IRUGO, pod_get_presence, pod_set_presence);
+static DEVICE_ATTR2(treble__bass, treble, S_IWUGO | S_IRUGO, pod_get_treble__bass, pod_set_treble__bass);
+static DEVICE_ATTR(noise_gate_enable, S_IWUGO | S_IRUGO, pod_get_noise_gate_enable, pod_set_noise_gate_enable);
+static DEVICE_ATTR(gate_threshold, S_IWUGO | S_IRUGO, pod_get_gate_threshold, pod_set_gate_threshold);
+static DEVICE_ATTR(gate_decay_time, S_IWUGO | S_IRUGO, pod_get_gate_decay_time, pod_set_gate_decay_time);
+static DEVICE_ATTR(stomp_enable, S_IWUGO | S_IRUGO, pod_get_stomp_enable, pod_set_stomp_enable);
+static DEVICE_ATTR(comp_enable, S_IWUGO | S_IRUGO, pod_get_comp_enable, pod_set_comp_enable);
+static DEVICE_ATTR(stomp_time, S_IWUGO | S_IRUGO, pod_get_stomp_time, pod_set_stomp_time);
+static DEVICE_ATTR(delay_enable, S_IWUGO | S_IRUGO, pod_get_delay_enable, pod_set_delay_enable);
+static DEVICE_ATTR(mod_param_1, S_IWUGO | S_IRUGO, pod_get_mod_param_1, pod_set_mod_param_1);
+static DEVICE_ATTR(delay_param_1, S_IWUGO | S_IRUGO, pod_get_delay_param_1, pod_set_delay_param_1);
+static DEVICE_ATTR(delay_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_delay_param_1_note_value, pod_set_delay_param_1_note_value);
+static DEVICE_ATTR2(band_2_frequency__bass, band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency__bass, pod_set_band_2_frequency__bass);
+static DEVICE_ATTR(delay_param_2, S_IWUGO | S_IRUGO, pod_get_delay_param_2, pod_set_delay_param_2);
+static DEVICE_ATTR(delay_volume_mix, S_IWUGO | S_IRUGO, pod_get_delay_volume_mix, pod_set_delay_volume_mix);
+static DEVICE_ATTR(delay_param_3, S_IWUGO | S_IRUGO, pod_get_delay_param_3, pod_set_delay_param_3);
+static DEVICE_ATTR(reverb_enable, S_IWUGO | S_IRUGO, pod_get_reverb_enable, pod_set_reverb_enable);
+static DEVICE_ATTR(reverb_type, S_IWUGO | S_IRUGO, pod_get_reverb_type, pod_set_reverb_type);
+static DEVICE_ATTR(reverb_decay, S_IWUGO | S_IRUGO, pod_get_reverb_decay, pod_set_reverb_decay);
+static DEVICE_ATTR(reverb_tone, S_IWUGO | S_IRUGO, pod_get_reverb_tone, pod_set_reverb_tone);
+static DEVICE_ATTR(reverb_pre_delay, S_IWUGO | S_IRUGO, pod_get_reverb_pre_delay, pod_set_reverb_pre_delay);
+static DEVICE_ATTR(reverb_pre_post, S_IWUGO | S_IRUGO, pod_get_reverb_pre_post, pod_set_reverb_pre_post);
+static DEVICE_ATTR(band_2_frequency, S_IWUGO | S_IRUGO, pod_get_band_2_frequency, pod_set_band_2_frequency);
+static DEVICE_ATTR2(band_3_frequency__bass, band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency__bass, pod_set_band_3_frequency__bass);
+static DEVICE_ATTR(wah_enable, S_IWUGO | S_IRUGO, pod_get_wah_enable, pod_set_wah_enable);
+static DEVICE_ATTR(modulation_lo_cut, S_IWUGO | S_IRUGO, pod_get_modulation_lo_cut, pod_set_modulation_lo_cut);
+static DEVICE_ATTR(delay_reverb_lo_cut, S_IWUGO | S_IRUGO, pod_get_delay_reverb_lo_cut, pod_set_delay_reverb_lo_cut);
+static DEVICE_ATTR(volume_pedal_minimum, S_IWUGO | S_IRUGO, pod_get_volume_pedal_minimum, pod_set_volume_pedal_minimum);
+static DEVICE_ATTR(eq_pre_post, S_IWUGO | S_IRUGO, pod_get_eq_pre_post, pod_set_eq_pre_post);
+static DEVICE_ATTR(volume_pre_post, S_IWUGO | S_IRUGO, pod_get_volume_pre_post, pod_set_volume_pre_post);
+static DEVICE_ATTR(di_model, S_IWUGO | S_IRUGO, pod_get_di_model, pod_set_di_model);
+static DEVICE_ATTR(di_delay, S_IWUGO | S_IRUGO, pod_get_di_delay, pod_set_di_delay);
+static DEVICE_ATTR(mod_enable, S_IWUGO | S_IRUGO, pod_get_mod_enable, pod_set_mod_enable);
+static DEVICE_ATTR(mod_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_mod_param_1_note_value, pod_set_mod_param_1_note_value);
+static DEVICE_ATTR(mod_param_2, S_IWUGO | S_IRUGO, pod_get_mod_param_2, pod_set_mod_param_2);
+static DEVICE_ATTR(mod_param_3, S_IWUGO | S_IRUGO, pod_get_mod_param_3, pod_set_mod_param_3);
+static DEVICE_ATTR(mod_param_4, S_IWUGO | S_IRUGO, pod_get_mod_param_4, pod_set_mod_param_4);
+static DEVICE_ATTR(mod_param_5, S_IWUGO | S_IRUGO, pod_get_mod_param_5, pod_set_mod_param_5);
+static DEVICE_ATTR(mod_volume_mix, S_IWUGO | S_IRUGO, pod_get_mod_volume_mix, pod_set_mod_volume_mix);
+static DEVICE_ATTR(mod_pre_post, S_IWUGO | S_IRUGO, pod_get_mod_pre_post, pod_set_mod_pre_post);
+static DEVICE_ATTR(modulation_model, S_IWUGO | S_IRUGO, pod_get_modulation_model, pod_set_modulation_model);
+static DEVICE_ATTR(band_3_frequency, S_IWUGO | S_IRUGO, pod_get_band_3_frequency, pod_set_band_3_frequency);
+static DEVICE_ATTR2(band_4_frequency__bass, band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency__bass, pod_set_band_4_frequency__bass);
+static DEVICE_ATTR(mod_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_mod_param_1_double_precision, pod_set_mod_param_1_double_precision);
+static DEVICE_ATTR(delay_param_1_double_precision, S_IWUGO | S_IRUGO, pod_get_delay_param_1_double_precision, pod_set_delay_param_1_double_precision);
+static DEVICE_ATTR(eq_enable, S_IWUGO | S_IRUGO, pod_get_eq_enable, pod_set_eq_enable);
+static DEVICE_ATTR(tap, S_IWUGO | S_IRUGO, pod_get_tap, pod_set_tap);
+static DEVICE_ATTR(volume_tweak_pedal_assign, S_IWUGO | S_IRUGO, pod_get_volume_tweak_pedal_assign, pod_set_volume_tweak_pedal_assign);
+static DEVICE_ATTR(band_5_frequency, S_IWUGO | S_IRUGO, pod_get_band_5_frequency, pod_set_band_5_frequency);
+static DEVICE_ATTR(tuner, S_IWUGO | S_IRUGO, pod_get_tuner, pod_set_tuner);
+static DEVICE_ATTR(mic_selection, S_IWUGO | S_IRUGO, pod_get_mic_selection, pod_set_mic_selection);
+static DEVICE_ATTR(cabinet_model, S_IWUGO | S_IRUGO, pod_get_cabinet_model, pod_set_cabinet_model);
+static DEVICE_ATTR(stomp_model, S_IWUGO | S_IRUGO, pod_get_stomp_model, pod_set_stomp_model);
+static DEVICE_ATTR(roomlevel, S_IWUGO | S_IRUGO, pod_get_roomlevel, pod_set_roomlevel);
+static DEVICE_ATTR(band_4_frequency, S_IWUGO | S_IRUGO, pod_get_band_4_frequency, pod_set_band_4_frequency);
+static DEVICE_ATTR(band_6_frequency, S_IWUGO | S_IRUGO, pod_get_band_6_frequency, pod_set_band_6_frequency);
+static DEVICE_ATTR(stomp_param_1_note_value, S_IWUGO | S_IRUGO, pod_get_stomp_param_1_note_value, pod_set_stomp_param_1_note_value);
+static DEVICE_ATTR(stomp_param_2, S_IWUGO | S_IRUGO, pod_get_stomp_param_2, pod_set_stomp_param_2);
+static DEVICE_ATTR(stomp_param_3, S_IWUGO | S_IRUGO, pod_get_stomp_param_3, pod_set_stomp_param_3);
+static DEVICE_ATTR(stomp_param_4, S_IWUGO | S_IRUGO, pod_get_stomp_param_4, pod_set_stomp_param_4);
+static DEVICE_ATTR(stomp_param_5, S_IWUGO | S_IRUGO, pod_get_stomp_param_5, pod_set_stomp_param_5);
+static DEVICE_ATTR(stomp_param_6, S_IWUGO | S_IRUGO, pod_get_stomp_param_6, pod_set_stomp_param_6);
+static DEVICE_ATTR(amp_switch_select, S_IWUGO | S_IRUGO, pod_get_amp_switch_select, pod_set_amp_switch_select);
+static DEVICE_ATTR(delay_param_4, S_IWUGO | S_IRUGO, pod_get_delay_param_4, pod_set_delay_param_4);
+static DEVICE_ATTR(delay_param_5, S_IWUGO | S_IRUGO, pod_get_delay_param_5, pod_set_delay_param_5);
+static DEVICE_ATTR(delay_pre_post, S_IWUGO | S_IRUGO, pod_get_delay_pre_post, pod_set_delay_pre_post);
+static DEVICE_ATTR(delay_model, S_IWUGO | S_IRUGO, pod_get_delay_model, pod_set_delay_model);
+static DEVICE_ATTR(delay_verb_model, S_IWUGO | S_IRUGO, pod_get_delay_verb_model, pod_set_delay_verb_model);
+static DEVICE_ATTR(tempo_msb, S_IWUGO | S_IRUGO, pod_get_tempo_msb, pod_set_tempo_msb);
+static DEVICE_ATTR(tempo_lsb, S_IWUGO | S_IRUGO, pod_get_tempo_lsb, pod_set_tempo_lsb);
+static DEVICE_ATTR(wah_model, S_IWUGO | S_IRUGO, pod_get_wah_model, pod_set_wah_model);
+static DEVICE_ATTR(bypass_volume, S_IWUGO | S_IRUGO, pod_get_bypass_volume, pod_set_bypass_volume);
+static DEVICE_ATTR(fx_loop_on_off, S_IWUGO | S_IRUGO, pod_get_fx_loop_on_off, pod_set_fx_loop_on_off);
+static DEVICE_ATTR(tweak_param_select, S_IWUGO | S_IRUGO, pod_get_tweak_param_select, pod_set_tweak_param_select);
+static DEVICE_ATTR(amp1_engage, S_IWUGO | S_IRUGO, pod_get_amp1_engage, pod_set_amp1_engage);
+static DEVICE_ATTR(band_1_gain, S_IWUGO | S_IRUGO, pod_get_band_1_gain, pod_set_band_1_gain);
+static DEVICE_ATTR2(band_2_gain__bass, band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain__bass, pod_set_band_2_gain__bass);
+static DEVICE_ATTR(band_2_gain, S_IWUGO | S_IRUGO, pod_get_band_2_gain, pod_set_band_2_gain);
+static DEVICE_ATTR2(band_3_gain__bass, band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain__bass, pod_set_band_3_gain__bass);
+static DEVICE_ATTR(band_3_gain, S_IWUGO | S_IRUGO, pod_get_band_3_gain, pod_set_band_3_gain);
+static DEVICE_ATTR2(band_4_gain__bass, band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain__bass, pod_set_band_4_gain__bass);
+static DEVICE_ATTR2(band_5_gain__bass, band_5_gain, S_IWUGO | S_IRUGO, pod_get_band_5_gain__bass, pod_set_band_5_gain__bass);
+static DEVICE_ATTR(band_4_gain, S_IWUGO | S_IRUGO, pod_get_band_4_gain, pod_set_band_4_gain);
+static DEVICE_ATTR2(band_6_gain__bass, band_6_gain, S_IWUGO | S_IRUGO, pod_get_band_6_gain__bass, pod_set_band_6_gain__bass);
+static DEVICE_ATTR(body, S_IRUGO, variax_get_body, line6_nop_write);
+static DEVICE_ATTR(pickup1_enable, S_IRUGO, variax_get_pickup1_enable, line6_nop_write);
+static DEVICE_ATTR(pickup1_type, S_IRUGO, variax_get_pickup1_type, line6_nop_write);
+static DEVICE_ATTR(pickup1_position, S_IRUGO, variax_get_pickup1_position, line6_nop_write);
+static DEVICE_ATTR(pickup1_angle, S_IRUGO, variax_get_pickup1_angle, line6_nop_write);
+static DEVICE_ATTR(pickup1_level, S_IRUGO, variax_get_pickup1_level, line6_nop_write);
+static DEVICE_ATTR(pickup2_enable, S_IRUGO, variax_get_pickup2_enable, line6_nop_write);
+static DEVICE_ATTR(pickup2_type, S_IRUGO, variax_get_pickup2_type, line6_nop_write);
+static DEVICE_ATTR(pickup2_position, S_IRUGO, variax_get_pickup2_position, line6_nop_write);
+static DEVICE_ATTR(pickup2_angle, S_IRUGO, variax_get_pickup2_angle, line6_nop_write);
+static DEVICE_ATTR(pickup2_level, S_IRUGO, variax_get_pickup2_level, line6_nop_write);
+static DEVICE_ATTR(pickup_phase, S_IRUGO, variax_get_pickup_phase, line6_nop_write);
+static DEVICE_ATTR(capacitance, S_IRUGO, variax_get_capacitance, line6_nop_write);
+static DEVICE_ATTR(tone_resistance, S_IRUGO, variax_get_tone_resistance, line6_nop_write);
+static DEVICE_ATTR(volume_resistance, S_IRUGO, variax_get_volume_resistance, line6_nop_write);
+static DEVICE_ATTR(taper, S_IRUGO, variax_get_taper, line6_nop_write);
+static DEVICE_ATTR(tone_dump, S_IRUGO, variax_get_tone_dump, line6_nop_write);
+static DEVICE_ATTR(save_tone, S_IRUGO, variax_get_save_tone, line6_nop_write);
+static DEVICE_ATTR(volume_dump, S_IRUGO, variax_get_volume_dump, line6_nop_write);
+static DEVICE_ATTR(tuning_enable, S_IRUGO, variax_get_tuning_enable, line6_nop_write);
+static DEVICE_ATTR(tuning6, S_IRUGO, variax_get_tuning6, line6_nop_write);
+static DEVICE_ATTR(tuning5, S_IRUGO, variax_get_tuning5, line6_nop_write);
+static DEVICE_ATTR(tuning4, S_IRUGO, variax_get_tuning4, line6_nop_write);
+static DEVICE_ATTR(tuning3, S_IRUGO, variax_get_tuning3, line6_nop_write);
+static DEVICE_ATTR(tuning2, S_IRUGO, variax_get_tuning2, line6_nop_write);
+static DEVICE_ATTR(tuning1, S_IRUGO, variax_get_tuning1, line6_nop_write);
+static DEVICE_ATTR(detune6, S_IRUGO, variax_get_detune6, line6_nop_write);
+static DEVICE_ATTR(detune5, S_IRUGO, variax_get_detune5, line6_nop_write);
+static DEVICE_ATTR(detune4, S_IRUGO, variax_get_detune4, line6_nop_write);
+static DEVICE_ATTR(detune3, S_IRUGO, variax_get_detune3, line6_nop_write);
+static DEVICE_ATTR(detune2, S_IRUGO, variax_get_detune2, line6_nop_write);
+static DEVICE_ATTR(detune1, S_IRUGO, variax_get_detune1, line6_nop_write);
+static DEVICE_ATTR(mix6, S_IRUGO, variax_get_mix6, line6_nop_write);
+static DEVICE_ATTR(mix5, S_IRUGO, variax_get_mix5, line6_nop_write);
+static DEVICE_ATTR(mix4, S_IRUGO, variax_get_mix4, line6_nop_write);
+static DEVICE_ATTR(mix3, S_IRUGO, variax_get_mix3, line6_nop_write);
+static DEVICE_ATTR(mix2, S_IRUGO, variax_get_mix2, line6_nop_write);
+static DEVICE_ATTR(mix1, S_IRUGO, variax_get_mix1, line6_nop_write);
+static DEVICE_ATTR(pickup_wiring, S_IRUGO, variax_get_pickup_wiring, line6_nop_write);
+
+int pod_create_files(int firmware, int type, struct device *dev)
+{
+ int err;
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tweak));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_wah_position));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_compression_gain));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_vol_pedal_position));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_compression_threshold));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pan));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model_setup));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_drive));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mid));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_lowmid));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_treble));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_highmid));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_chan_vol));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_mix));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_effect_setup));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_frequency));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_presence));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_treble__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_noise_gate_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_gate_threshold));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_gate_decay_time));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_comp_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_time));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_note_value));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_volume_mix));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_3));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_enable));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_type));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_decay));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_tone));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_delay));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_reverb_pre_post));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_frequency));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_wah_enable));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_lo_cut));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_reverb_lo_cut));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pedal_minimum));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_eq_pre_post));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_pre_post));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_di_model));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_di_delay));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_note_value));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_4));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_volume_mix));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_pre_post));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_modulation_model));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_frequency));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency__bass));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mod_param_1_double_precision));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_1_double_precision));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_eq_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tap));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_tweak_pedal_assign));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_frequency));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mic_selection));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_cabinet_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_roomlevel));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_frequency));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_frequency));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_1_note_value));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_stomp_param_6));
+ if ((type & (LINE6_BITS_LIVE)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp_switch_select));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_param_5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_pre_post));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_model));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_delay_verb_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_msb));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tempo_lsb));
+ if (firmware >= 300)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_wah_model));
+ if (firmware >= 214)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_bypass_volume));
+ if ((type & (LINE6_BITS_PRO)) != 0)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_fx_loop_on_off));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tweak_param_select));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_amp1_engage));
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_1_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain__bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_2_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain__bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_3_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain__bass));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_5_gain__bass));
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_4_gain));
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ CHECK_RETURN(device_create_file(dev, &dev_attr_band_6_gain__bass));
+ return 0;
+}
+
+void pod_remove_files(int firmware, int type, struct device *dev)
+{
+ device_remove_file(dev, &dev_attr_tweak);
+ device_remove_file(dev, &dev_attr_wah_position);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_compression_gain);
+ device_remove_file(dev, &dev_attr_vol_pedal_position);
+ device_remove_file(dev, &dev_attr_compression_threshold);
+ device_remove_file(dev, &dev_attr_pan);
+ device_remove_file(dev, &dev_attr_amp_model_setup);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_amp_model);
+ device_remove_file(dev, &dev_attr_drive);
+ device_remove_file(dev, &dev_attr_bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_mid);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_lowmid);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_treble);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_highmid);
+ device_remove_file(dev, &dev_attr_chan_vol);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_mix);
+ device_remove_file(dev, &dev_attr_effect_setup);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_1_frequency);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_presence);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_treble__bass);
+ device_remove_file(dev, &dev_attr_noise_gate_enable);
+ device_remove_file(dev, &dev_attr_gate_threshold);
+ device_remove_file(dev, &dev_attr_gate_decay_time);
+ device_remove_file(dev, &dev_attr_stomp_enable);
+ device_remove_file(dev, &dev_attr_comp_enable);
+ device_remove_file(dev, &dev_attr_stomp_time);
+ device_remove_file(dev, &dev_attr_delay_enable);
+ device_remove_file(dev, &dev_attr_mod_param_1);
+ device_remove_file(dev, &dev_attr_delay_param_1);
+ device_remove_file(dev, &dev_attr_delay_param_1_note_value);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_frequency__bass);
+ device_remove_file(dev, &dev_attr_delay_param_2);
+ device_remove_file(dev, &dev_attr_delay_volume_mix);
+ device_remove_file(dev, &dev_attr_delay_param_3);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_enable);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_type);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_decay);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_tone);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_pre_delay);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_reverb_pre_post);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_frequency);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_frequency__bass);
+ device_remove_file(dev, &dev_attr_wah_enable);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_modulation_lo_cut);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_delay_reverb_lo_cut);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_volume_pedal_minimum);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_eq_pre_post);
+ device_remove_file(dev, &dev_attr_volume_pre_post);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_di_model);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_di_delay);
+ device_remove_file(dev, &dev_attr_mod_enable);
+ device_remove_file(dev, &dev_attr_mod_param_1_note_value);
+ device_remove_file(dev, &dev_attr_mod_param_2);
+ device_remove_file(dev, &dev_attr_mod_param_3);
+ device_remove_file(dev, &dev_attr_mod_param_4);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_mod_param_5);
+ device_remove_file(dev, &dev_attr_mod_volume_mix);
+ device_remove_file(dev, &dev_attr_mod_pre_post);
+ device_remove_file(dev, &dev_attr_modulation_model);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_frequency);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_frequency__bass);
+ device_remove_file(dev, &dev_attr_mod_param_1_double_precision);
+ device_remove_file(dev, &dev_attr_delay_param_1_double_precision);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_eq_enable);
+ device_remove_file(dev, &dev_attr_tap);
+ device_remove_file(dev, &dev_attr_volume_tweak_pedal_assign);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_5_frequency);
+ device_remove_file(dev, &dev_attr_tuner);
+ device_remove_file(dev, &dev_attr_mic_selection);
+ device_remove_file(dev, &dev_attr_cabinet_model);
+ device_remove_file(dev, &dev_attr_stomp_model);
+ device_remove_file(dev, &dev_attr_roomlevel);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_frequency);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_6_frequency);
+ device_remove_file(dev, &dev_attr_stomp_param_1_note_value);
+ device_remove_file(dev, &dev_attr_stomp_param_2);
+ device_remove_file(dev, &dev_attr_stomp_param_3);
+ device_remove_file(dev, &dev_attr_stomp_param_4);
+ device_remove_file(dev, &dev_attr_stomp_param_5);
+ device_remove_file(dev, &dev_attr_stomp_param_6);
+ if ((type & (LINE6_BITS_LIVE)) != 0)
+ device_remove_file(dev, &dev_attr_amp_switch_select);
+ device_remove_file(dev, &dev_attr_delay_param_4);
+ device_remove_file(dev, &dev_attr_delay_param_5);
+ device_remove_file(dev, &dev_attr_delay_pre_post);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_delay_model);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ device_remove_file(dev, &dev_attr_delay_verb_model);
+ device_remove_file(dev, &dev_attr_tempo_msb);
+ device_remove_file(dev, &dev_attr_tempo_lsb);
+ if (firmware >= 300)
+ device_remove_file(dev, &dev_attr_wah_model);
+ if (firmware >= 214)
+ device_remove_file(dev, &dev_attr_bypass_volume);
+ if ((type & (LINE6_BITS_PRO)) != 0)
+ device_remove_file(dev, &dev_attr_fx_loop_on_off);
+ device_remove_file(dev, &dev_attr_tweak_param_select);
+ device_remove_file(dev, &dev_attr_amp1_engage);
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_1_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_gain__bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_2_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_gain__bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_3_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_gain__bass);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_5_gain__bass);
+ if ((type & (LINE6_BITS_PODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_4_gain);
+ if ((type & (LINE6_BITS_BASSPODXTALL)) != 0)
+ if (firmware >= 200)
+ device_remove_file(dev, &dev_attr_band_6_gain__bass);
+}
+
+EXPORT_SYMBOL(pod_create_files);
+EXPORT_SYMBOL(pod_remove_files);
+
+int variax_create_files(int firmware, int type, struct device *dev)
+{
+ int err;
+ CHECK_RETURN(device_create_file(dev, &dev_attr_body));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_type));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_position));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_angle));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup1_level));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_type));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_position));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_angle));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup2_level));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_phase));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_capacitance));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tone_resistance));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_resistance));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_taper));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tone_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_save_tone));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning_enable));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning6));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuning1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune6));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_detune1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix6));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix5));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix4));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix3));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix2));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_mix1));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_pickup_wiring));
+ return 0;
+}
+
+void variax_remove_files(int firmware, int type, struct device *dev)
+{
+ device_remove_file(dev, &dev_attr_body);
+ device_remove_file(dev, &dev_attr_pickup1_enable);
+ device_remove_file(dev, &dev_attr_pickup1_type);
+ device_remove_file(dev, &dev_attr_pickup1_position);
+ device_remove_file(dev, &dev_attr_pickup1_angle);
+ device_remove_file(dev, &dev_attr_pickup1_level);
+ device_remove_file(dev, &dev_attr_pickup2_enable);
+ device_remove_file(dev, &dev_attr_pickup2_type);
+ device_remove_file(dev, &dev_attr_pickup2_position);
+ device_remove_file(dev, &dev_attr_pickup2_angle);
+ device_remove_file(dev, &dev_attr_pickup2_level);
+ device_remove_file(dev, &dev_attr_pickup_phase);
+ device_remove_file(dev, &dev_attr_capacitance);
+ device_remove_file(dev, &dev_attr_tone_resistance);
+ device_remove_file(dev, &dev_attr_volume_resistance);
+ device_remove_file(dev, &dev_attr_taper);
+ device_remove_file(dev, &dev_attr_tone_dump);
+ device_remove_file(dev, &dev_attr_save_tone);
+ device_remove_file(dev, &dev_attr_volume_dump);
+ device_remove_file(dev, &dev_attr_tuning_enable);
+ device_remove_file(dev, &dev_attr_tuning6);
+ device_remove_file(dev, &dev_attr_tuning5);
+ device_remove_file(dev, &dev_attr_tuning4);
+ device_remove_file(dev, &dev_attr_tuning3);
+ device_remove_file(dev, &dev_attr_tuning2);
+ device_remove_file(dev, &dev_attr_tuning1);
+ device_remove_file(dev, &dev_attr_detune6);
+ device_remove_file(dev, &dev_attr_detune5);
+ device_remove_file(dev, &dev_attr_detune4);
+ device_remove_file(dev, &dev_attr_detune3);
+ device_remove_file(dev, &dev_attr_detune2);
+ device_remove_file(dev, &dev_attr_detune1);
+ device_remove_file(dev, &dev_attr_mix6);
+ device_remove_file(dev, &dev_attr_mix5);
+ device_remove_file(dev, &dev_attr_mix4);
+ device_remove_file(dev, &dev_attr_mix3);
+ device_remove_file(dev, &dev_attr_mix2);
+ device_remove_file(dev, &dev_attr_mix1);
+ device_remove_file(dev, &dev_attr_pickup_wiring);
+}
+
+EXPORT_SYMBOL(variax_create_files);
+EXPORT_SYMBOL(variax_remove_files);
diff --git a/drivers/staging/line6/control.h b/drivers/staging/line6/control.h
new file mode 100644
index 00000000000..2f19665d95a
--- /dev/null
+++ b/drivers/staging/line6/control.h
@@ -0,0 +1,187 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef LINE6_CONTROL_H
+#define LINE6_CONTROL_H
+
+
+/**
+ List of PODxt Pro controls.
+ See Appendix C of the "PODxt (Pro) Pilot's Handbook" by Line6.
+ Comments after the number refer to the PODxt Pro firmware version required
+ for this feature.
+*/
+enum {
+ POD_tweak = 1,
+ POD_wah_position = 4,
+ POD_compression_gain = 5, /* device: LINE6_BITS_PODXTALL */
+ POD_vol_pedal_position = 7,
+ POD_compression_threshold = 9,
+ POD_pan = 10,
+ POD_amp_model_setup = 11,
+ POD_amp_model = 12, /* firmware: 2.0 */
+ POD_drive = 13,
+ POD_bass = 14,
+ POD_mid = 15, /* device: LINE6_BITS_PODXTALL */
+ POD_lowmid = 15, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_treble = 16, /* device: LINE6_BITS_PODXTALL */
+ POD_highmid = 16, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_chan_vol = 17,
+ POD_reverb_mix = 18, /* device: LINE6_BITS_PODXTALL */
+ POD_effect_setup = 19,
+ POD_band_1_frequency = 20, /* firmware: 2.0 */
+ POD_presence = 21, /* device: LINE6_BITS_PODXTALL */
+ POD_treble__bass = 21, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_noise_gate_enable = 22,
+ POD_gate_threshold = 23,
+ POD_gate_decay_time = 24,
+ POD_stomp_enable = 25,
+ POD_comp_enable = 26,
+ POD_stomp_time = 27,
+ POD_delay_enable = 28,
+ POD_mod_param_1 = 29,
+ POD_delay_param_1 = 30,
+ POD_delay_param_1_note_value = 31,
+ POD_band_2_frequency__bass = 32, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_delay_param_2 = 33,
+ POD_delay_volume_mix = 34,
+ POD_delay_param_3 = 35,
+ POD_reverb_enable = 36, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_type = 37, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_decay = 38, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_tone = 39, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_pre_delay = 40, /* device: LINE6_BITS_PODXTALL */
+ POD_reverb_pre_post = 41, /* device: LINE6_BITS_PODXTALL */
+ POD_band_2_frequency = 42, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_3_frequency__bass = 42, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_wah_enable = 43,
+ POD_modulation_lo_cut = 44, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_delay_reverb_lo_cut = 45, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_volume_pedal_minimum = 46, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_eq_pre_post = 46, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_volume_pre_post = 47,
+ POD_di_model = 48, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_di_delay = 49, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_mod_enable = 50,
+ POD_mod_param_1_note_value = 51,
+ POD_mod_param_2 = 52,
+ POD_mod_param_3 = 53,
+ POD_mod_param_4 = 54,
+ POD_mod_param_5 = 55, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_mod_volume_mix = 56,
+ POD_mod_pre_post = 57,
+ POD_modulation_model = 58,
+ POD_band_3_frequency = 60, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_4_frequency__bass = 60, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_mod_param_1_double_precision = 61,
+ POD_delay_param_1_double_precision = 62,
+ POD_eq_enable = 63, /* firmware: 2.0 */
+ POD_tap = 64,
+ POD_volume_tweak_pedal_assign = 65,
+ POD_band_5_frequency = 68, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_tuner = 69,
+ POD_mic_selection = 70,
+ POD_cabinet_model = 71,
+ POD_stomp_model = 75,
+ POD_roomlevel = 76,
+ POD_band_4_frequency = 77, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_6_frequency = 77, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_stomp_param_1_note_value = 78,
+ POD_stomp_param_2 = 79,
+ POD_stomp_param_3 = 80,
+ POD_stomp_param_4 = 81,
+ POD_stomp_param_5 = 82,
+ POD_stomp_param_6 = 83,
+ POD_amp_switch_select = 84, /* device: LINE6_BITS_LIVE */
+ POD_delay_param_4 = 85,
+ POD_delay_param_5 = 86,
+ POD_delay_pre_post = 87,
+ POD_delay_model = 88, /* device: LINE6_BITS_PODXTALL */
+ POD_delay_verb_model = 88, /* device: LINE6_BITS_BASSPODXTALL */
+ POD_tempo_msb = 89,
+ POD_tempo_lsb = 90,
+ POD_wah_model = 91, /* firmware: 3.0 */
+ POD_bypass_volume = 105, /* firmware: 2.14 */
+ POD_fx_loop_on_off = 107, /* device: LINE6_BITS_PRO */
+ POD_tweak_param_select = 108,
+ POD_amp1_engage = 111,
+ POD_band_1_gain = 114, /* firmware: 2.0 */
+ POD_band_2_gain__bass = 115, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_2_gain = 116, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_3_gain__bass = 116, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_3_gain = 117, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_4_gain__bass = 117, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_5_gain__bass = 118, /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+ POD_band_4_gain = 119, /* device: LINE6_BITS_PODXTALL */ /* firmware: 2.0 */
+ POD_band_6_gain__bass = 119 /* device: LINE6_BITS_BASSPODXTALL */ /* firmware: 2.0 */
+};
+
+/**
+ List of Variax workbench controls (dump).
+*/
+enum {
+ VARIAX_body = 3,
+ VARIAX_pickup1_enable = 4, /* 0: enabled, 1: disabled */
+ VARIAX_pickup1_type = 8,
+ VARIAX_pickup1_position = 9, /* type: 24 bit float */
+ VARIAX_pickup1_angle = 12, /* type: 24 bit float */
+ VARIAX_pickup1_level = 15, /* type: 24 bit float */
+ VARIAX_pickup2_enable = 18, /* 0: enabled, 1: disabled */
+ VARIAX_pickup2_type = 22,
+ VARIAX_pickup2_position = 23, /* type: 24 bit float */
+ VARIAX_pickup2_angle = 26, /* type: 24 bit float */
+ VARIAX_pickup2_level = 29, /* type: 24 bit float */
+ VARIAX_pickup_phase = 32, /* 0: in phase, 1: out of phase */
+ VARIAX_capacitance = 33, /* type: 24 bit float */
+ VARIAX_tone_resistance = 36, /* type: 24 bit float */
+ VARIAX_volume_resistance = 39, /* type: 24 bit float */
+ VARIAX_taper = 42, /* 0: Linear, 1: Audio */
+ VARIAX_tone_dump = 43, /* type: 24 bit float */
+ VARIAX_save_tone = 46,
+ VARIAX_volume_dump = 47, /* type: 24 bit float */
+ VARIAX_tuning_enable = 50,
+ VARIAX_tuning6 = 51,
+ VARIAX_tuning5 = 52,
+ VARIAX_tuning4 = 53,
+ VARIAX_tuning3 = 54,
+ VARIAX_tuning2 = 55,
+ VARIAX_tuning1 = 56,
+ VARIAX_detune6 = 57, /* type: 24 bit float */
+ VARIAX_detune5 = 60, /* type: 24 bit float */
+ VARIAX_detune4 = 63, /* type: 24 bit float */
+ VARIAX_detune3 = 66, /* type: 24 bit float */
+ VARIAX_detune2 = 69, /* type: 24 bit float */
+ VARIAX_detune1 = 72, /* type: 24 bit float */
+ VARIAX_mix6 = 75, /* type: 24 bit float */
+ VARIAX_mix5 = 78, /* type: 24 bit float */
+ VARIAX_mix4 = 81, /* type: 24 bit float */
+ VARIAX_mix3 = 84, /* type: 24 bit float */
+ VARIAX_mix2 = 87, /* type: 24 bit float */
+ VARIAX_mix1 = 90, /* type: 24 bit float */
+ VARIAX_pickup_wiring = 96 /* 0: parallel, 1: series */
+};
+
+/**
+ List of Variax workbench controls (MIDI).
+*/
+enum {
+ VARIAXMIDI_volume = 7,
+ VARIAXMIDI_tone = 79,
+};
+
+
+extern int pod_create_files(int firmware, int type, struct device *dev);
+extern void pod_remove_files(int firmware, int type, struct device *dev);
+extern int variax_create_files(int firmware, int type, struct device *dev);
+extern void variax_remove_files(int firmware, int type, struct device *dev);
+
+
+#endif
diff --git a/drivers/staging/line6/driver.c b/drivers/staging/line6/driver.c
new file mode 100644
index 00000000000..85a20d0002c
--- /dev/null
+++ b/drivers/staging/line6/driver.c
@@ -0,0 +1,1102 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include "audio.h"
+#include "capture.h"
+#include "control.h"
+#include "midi.h"
+#include "playback.h"
+#include "pod.h"
+#include "revision.h"
+#include "toneport.h"
+#include "usbdefs.h"
+#include "variax.h"
+
+
+#define DRIVER_AUTHOR "Markus Grabner <grabner@icg.tugraz.at>"
+#define DRIVER_DESC "Line6 USB Driver"
+#define DRIVER_VERSION "0.8.0"
+
+
+/* table of devices that work with this driver */
+static struct usb_device_id line6_id_table[] = {
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXT) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTLIVE) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_BASSPODXTPRO) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_GUITARPORT) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_POCKETPOD) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODX3LIVE) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXT) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTLIVE) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_PODXTPRO) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_GX) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX1) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_TONEPORT_UX2) },
+ { USB_DEVICE(LINE6_VENDOR_ID, LINE6_DEVID_VARIAX) },
+ { },
+};
+MODULE_DEVICE_TABLE(usb, line6_id_table);
+
+static struct line6_properties line6_properties_table[] = {
+ { "BassPODxt", LINE6_BIT_BASSPODXT, LINE6_BIT_CONTROL_PCM },
+ { "BassPODxt Live", LINE6_BIT_BASSPODXTLIVE, LINE6_BIT_CONTROL_PCM },
+ { "BassPODxt Pro", LINE6_BIT_BASSPODXTPRO, LINE6_BIT_CONTROL_PCM },
+ { "GuitarPort", LINE6_BIT_GUITARPORT, LINE6_BIT_PCM },
+ { "Pocket POD", LINE6_BIT_POCKETPOD, LINE6_BIT_CONTROL_PCM },
+ { "POD X3", LINE6_BIT_PODX3, LINE6_BIT_PCM },
+ { "POD X3 Live", LINE6_BIT_PODX3LIVE, LINE6_BIT_PCM },
+ { "PODxt", LINE6_BIT_PODXT, LINE6_BIT_CONTROL_PCM },
+ { "PODxt Live", LINE6_BIT_PODXTLIVE, LINE6_BIT_CONTROL_PCM },
+ { "PODxt Pro", LINE6_BIT_PODXTPRO, LINE6_BIT_CONTROL_PCM },
+ { "TonePort GX", LINE6_BIT_TONEPORT_GX, LINE6_BIT_PCM },
+ { "TonePort UX1", LINE6_BIT_TONEPORT_UX1, LINE6_BIT_PCM },
+ { "TonePort UX2", LINE6_BIT_TONEPORT_UX2, LINE6_BIT_PCM },
+ { "Variax Workbench", LINE6_BIT_VARIAX, LINE6_BIT_CONTROL }
+};
+
+
+/*
+ This is Line6's MIDI manufacturer ID.
+*/
+const unsigned char line6_midi_id[] = { 0x00, 0x01, 0x0c };
+
+struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
+struct workqueue_struct *line6_workqueue;
+
+
+/**
+ Class for asynchronous messages.
+*/
+struct message {
+ struct usb_line6 *line6;
+ const char *buffer;
+ int size;
+ int done;
+};
+
+
+/*
+ Forward declarations.
+*/
+static void line6_data_received(struct urb *urb);
+static int line6_send_raw_message_async_part(struct message *msg,
+ struct urb *urb);
+
+
+/*
+ Start to listen on endpoint.
+*/
+static int line6_start_listen(struct usb_line6 *line6)
+{
+ usb_fill_int_urb(line6->urb_listen, line6->usbdev,
+ usb_rcvintpipe(line6->usbdev, line6->ep_control_read),
+ line6->buffer_listen, LINE6_BUFSIZE_LISTEN,
+ line6_data_received, line6, line6->interval);
+ line6->urb_listen->actual_length = 0;
+ return usb_submit_urb(line6->urb_listen, GFP_KERNEL);
+}
+
+#if DO_DUMP_ANY
+/*
+ Write hexdump to syslog.
+*/
+void line6_write_hexdump(struct usb_line6 *line6, char dir,
+ const unsigned char *buffer, int size)
+{
+ static const int BYTES_PER_LINE = 8;
+ char hexdump[100];
+ char asc[BYTES_PER_LINE + 1];
+ int i, j;
+
+ for (i = 0; i < size; i += BYTES_PER_LINE) {
+ int hexdumpsize = sizeof(hexdump);
+ char *p = hexdump;
+ int n = min(size - i, BYTES_PER_LINE);
+ asc[n] = 0;
+
+ for (j = 0; j < BYTES_PER_LINE; ++j) {
+ int bytes;
+
+ if (j < n) {
+ unsigned char val = buffer[i + j];
+ bytes = snprintf(p, hexdumpsize, " %02X", val);
+ asc[j] = ((val >= 0x20) && (val < 0x7f)) ? val : '.';
+ } else
+ bytes = snprintf(p, hexdumpsize, " ");
+
+ if (bytes > hexdumpsize)
+ break; /* buffer overflow */
+
+ p += bytes;
+ hexdumpsize -= bytes;
+ }
+
+ dev_info(line6->ifcdev, "%c%04X:%s %s\n", dir, i, hexdump, asc);
+ }
+}
+#endif
+
+#if DO_DUMP_URB_RECEIVE
+/*
+ Dump URB data to syslog.
+*/
+static void line6_dump_urb(struct urb *urb)
+{
+ struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+
+ if (urb->status < 0)
+ return;
+
+ line6_write_hexdump(line6, 'R', (unsigned char *)urb->transfer_buffer,
+ urb->actual_length);
+}
+#endif
+
+/*
+ Send raw message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+ int size)
+{
+ int i, done = 0;
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', buffer, size);
+#endif
+
+ for (i = 0; i < size; i += line6->max_packet_size) {
+ int partial;
+ const char *frag_buf = buffer + i;
+ int frag_size = min(line6->max_packet_size, size - i);
+ int retval;
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev,
+ line6->ep_control_write),
+ (char *)frag_buf, frag_size,
+ &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval) {
+ dev_err(line6->ifcdev,
+ "usb_interrupt_msg failed (%d)\n", retval);
+ break;
+ }
+
+ done += frag_size;
+ }
+
+ return done;
+}
+
+/*
+ Notification of completion of asynchronous request transmission.
+*/
+static void line6_async_request_sent(struct urb *urb)
+{
+ struct message *msg = (struct message *)urb->context;
+
+ if (msg->done >= msg->size) {
+ usb_free_urb(urb);
+ kfree(msg);
+ } else
+ line6_send_raw_message_async_part(msg, urb);
+}
+
+/*
+ Asynchronously send part of a raw message.
+*/
+static int line6_send_raw_message_async_part(struct message *msg,
+ struct urb *urb)
+{
+ int retval;
+ struct usb_line6 *line6 = msg->line6;
+ int done = msg->done;
+ int bytes = min(msg->size - done, line6->max_packet_size);
+
+ usb_fill_int_urb(urb, line6->usbdev,
+ usb_sndintpipe(line6->usbdev, line6->ep_control_write),
+ (char *)msg->buffer + done, bytes,
+ line6_async_request_sent, msg, line6->interval);
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', (char *)msg->buffer + done, bytes);
+#endif
+
+ msg->done += bytes;
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (retval < 0) {
+ dev_err(line6->ifcdev, "%s: usb_submit_urb failed (%d)\n",
+ __func__, retval);
+ usb_free_urb(urb);
+ kfree(msg);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ Asynchronously send raw message.
+*/
+int line6_send_raw_message_async(struct usb_line6 *line6, const char *buffer,
+ int size)
+{
+ struct message *msg;
+ struct urb *urb;
+
+ /* create message: */
+ msg = kmalloc(sizeof(struct message), GFP_ATOMIC);
+
+ if (msg == NULL) {
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* create URB: */
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+ if (urb == NULL) {
+ kfree(msg);
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* set message data: */
+ msg->line6 = line6;
+ msg->buffer = buffer;
+ msg->size = size;
+ msg->done = 0;
+
+ /* start sending: */
+ return line6_send_raw_message_async_part(msg, urb);
+}
+
+/*
+ Send sysex message in pieces of wMaxPacketSize bytes.
+*/
+int line6_send_sysex_message(struct usb_line6 *line6, const char *buffer,
+ int size)
+{
+ return line6_send_raw_message(line6, buffer, size + SYSEX_EXTRA_SIZE) - SYSEX_EXTRA_SIZE;
+}
+
+/*
+ Allocate buffer for sysex message and prepare header.
+ @param code sysex message code
+ @param size number of bytes between code and sysex end
+*/
+char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1, int code2,
+ int size)
+{
+ char *buffer = kmalloc(size + SYSEX_EXTRA_SIZE, GFP_KERNEL);
+
+ if (!buffer) {
+ dev_err(line6->ifcdev, "out of memory\n");
+ return NULL;
+ }
+
+ buffer[0] = LINE6_SYSEX_BEGIN;
+ memcpy(buffer + 1, line6_midi_id, sizeof(line6_midi_id));
+ buffer[sizeof(line6_midi_id) + 1] = code1;
+ buffer[sizeof(line6_midi_id) + 2] = code2;
+ buffer[sizeof(line6_midi_id) + 3 + size] = LINE6_SYSEX_END;
+ return buffer;
+}
+
+/*
+ Notification of data received from the Line6 device.
+*/
+static void line6_data_received(struct urb *urb)
+{
+ struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+ struct MidiBuffer *mb = &line6->line6midi->midibuf_in;
+ int done;
+
+ if (urb->status == -ESHUTDOWN)
+ return;
+
+#if DO_DUMP_URB_RECEIVE
+ line6_dump_urb(urb);
+#endif
+
+ done = midibuf_write(mb, urb->transfer_buffer, urb->actual_length);
+
+ if (done < urb->actual_length) {
+ midibuf_ignore(mb, done);
+ DEBUG_MESSAGES(dev_err(line6->ifcdev, "%d %d buffer overflow - message skipped\n", done, urb->actual_length));
+ }
+
+ for (;;) {
+ done = midibuf_read(mb, line6->buffer_message, LINE6_MESSAGE_MAXLEN);
+
+ if (done == 0)
+ break;
+
+ /* MIDI input filter */
+ if (midibuf_skip_message(mb, line6->line6midi->midi_mask_receive))
+ continue;
+
+ line6->message_length = done;
+#if DO_DUMP_MIDI_RECEIVE
+ line6_write_hexdump(line6, 'r', line6->buffer_message, done);
+#endif
+ line6_midi_receive(line6, line6->buffer_message, done);
+
+ switch (line6->usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ pod_process_message((struct usb_line6_pod *)line6);
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (line6->interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ pod_process_message((struct usb_line6_pod *)line6);
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ variax_process_message((struct usb_line6_variax *)line6);
+ break;
+
+ default:
+ dev_err(line6->ifcdev, "PODxt Live interface %d not supported\n", line6->interface_number);
+ }
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ variax_process_message((struct usb_line6_variax *)line6);
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+ }
+
+ line6_start_listen(line6);
+}
+
+/*
+ Send channel number (i.e., switch to a different sound).
+*/
+int line6_send_program(struct usb_line6 *line6, int value)
+{
+ int retval;
+ unsigned char *buffer;
+ unsigned int partial;
+
+ buffer = kmalloc(2, GFP_KERNEL);
+
+ if (!buffer) {
+ dev_err(line6->ifcdev, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ buffer[0] = LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST;
+ buffer[1] = value;
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', buffer, 2);
+#endif
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev,
+ line6->ep_control_write),
+ buffer, 2, &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval)
+ dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
+
+ kfree(buffer);
+ return retval;
+}
+
+/*
+ Transmit Line6 control parameter.
+*/
+int line6_transmit_parameter(struct usb_line6 *line6, int param, int value)
+{
+ int retval;
+ unsigned char *buffer;
+ unsigned int partial;
+
+ buffer = kmalloc(3, GFP_KERNEL);
+
+ if (!buffer) {
+ dev_err(line6->ifcdev, "out of memory\n");
+ return -ENOMEM;
+ }
+
+ buffer[0] = LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST;
+ buffer[1] = param;
+ buffer[2] = value;
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', buffer, 3);
+#endif
+
+ retval = usb_interrupt_msg(line6->usbdev,
+ usb_sndintpipe(line6->usbdev, line6->ep_control_write),
+ buffer, 3, &partial, LINE6_TIMEOUT * HZ);
+
+ if (retval)
+ dev_err(line6->ifcdev, "usb_interrupt_msg failed (%d)\n", retval);
+
+ kfree(buffer);
+ return retval;
+}
+
+/*
+ Read data from device.
+*/
+int line6_read_data(struct usb_line6 *line6, int address, void *data, size_t datalen)
+{
+ struct usb_device *usbdev = line6->usbdev;
+ int ret;
+ unsigned char len;
+
+ /* query the serial number: */
+ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ (datalen << 8) | 0x21, address, NULL, 0, LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev, "read request failed (error %d)\n", ret);
+ return ret;
+ }
+
+ /* Wait for data length. We'll get a couple of 0xff until length arrives. */
+ do {
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+ USB_DIR_IN,
+ 0x0012, 0x0000, &len, 1,
+ LINE6_TIMEOUT * HZ);
+ if (ret < 0) {
+ dev_err(line6->ifcdev,
+ "receive length failed (error %d)\n", ret);
+ return ret;
+ }
+ }
+ while (len == 0xff)
+ ;
+
+ if (len != datalen) {
+ /* should be equal or something went wrong */
+ dev_err(line6->ifcdev,
+ "length mismatch (expected %d, got %d)\n",
+ (int)datalen, (int)len);
+ return -EINVAL;
+ }
+
+ /* receive the result: */
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
+ 0x0013, 0x0000, data, datalen,
+ LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev, "read failed (error %d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Write data to device.
+*/
+int line6_write_data(struct usb_line6 *line6, int address, void *data,
+ size_t datalen)
+{
+ struct usb_device *usbdev = line6->usbdev;
+ int ret;
+ unsigned char status;
+
+ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ 0x0022, address, data, datalen,
+ LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev,
+ "write request failed (error %d)\n", ret);
+ return ret;
+ }
+
+ do {
+ ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev, 0),
+ 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE |
+ USB_DIR_IN,
+ 0x0012, 0x0000,
+ &status, 1, LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ dev_err(line6->ifcdev,
+ "receiving status failed (error %d)\n", ret);
+ return ret;
+ }
+ }
+ while (status == 0xff)
+ ;
+
+ if (status != 0) {
+ dev_err(line6->ifcdev, "write failed (error %d)\n", ret);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ Read Line6 device serial number.
+ (POD, TonePort, GuitarPort)
+*/
+int line6_read_serial_number(struct usb_line6 *line6, int *serial_number)
+{
+ return line6_read_data(line6, 0x80d0, serial_number, sizeof(*serial_number));
+}
+
+/*
+ No operation (i.e., unsupported).
+*/
+ssize_t line6_nop_read(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ return 0;
+}
+
+/*
+ No operation (i.e., unsupported).
+*/
+ssize_t line6_nop_write(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return count;
+}
+
+/*
+ "write" request on "raw" special file.
+*/
+#if CREATE_RAW_FILE
+ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ line6_send_raw_message(line6, buf, count);
+ return count;
+}
+#endif
+
+/*
+ Generic destructor.
+*/
+static void line6_destruct(struct usb_interface *interface)
+{
+ struct usb_line6 *line6;
+
+ if (interface == NULL)
+ return;
+ line6 = usb_get_intfdata(interface);
+ if (line6 == NULL)
+ return;
+
+ /* free buffer memory first: */
+ kfree(line6->buffer_message);
+ kfree(line6->buffer_listen);
+
+ /* then free URBs: */
+ usb_free_urb(line6->urb_listen);
+
+ /* make sure the device isn't destructed twice: */
+ usb_set_intfdata(interface, NULL);
+
+ /* free interface data: */
+ kfree(line6);
+}
+
+static void line6_list_devices(void)
+{
+ int i;
+
+ for (i = 0; i < LINE6_MAX_DEVICES; ++i) {
+ struct usb_line6 *dev = line6_devices[i];
+ printk(KERN_INFO "Line6 device %d: ", i);
+
+ if (dev == NULL)
+ printk("(not used)\n");
+ else
+ printk("%s:%d\n", dev->properties->name, dev->interface_number);
+ }
+}
+
+/*
+ Probe USB device.
+*/
+static int line6_probe(struct usb_interface *interface, const struct usb_device_id *id)
+{
+ int devtype;
+ struct usb_device *usbdev = NULL;
+ struct usb_line6 *line6 = NULL;
+ const struct line6_properties *properties;
+ int devnum;
+ int interface_number, alternate = 0;
+ int product;
+ int size = 0;
+ int ep_read = 0, ep_write = 0;
+ int ret;
+
+ if (interface == NULL)
+ return -ENODEV;
+ usbdev = interface_to_usbdev(interface);
+ if (usbdev == NULL)
+ return -ENODEV;
+
+ /* increment reference counters: */
+ usb_get_intf(interface);
+ usb_get_dev(usbdev);
+
+ /* we don't handle multiple configurations */
+ if (usbdev->descriptor.bNumConfigurations != 1)
+ return -ENODEV;
+
+ /* check vendor and product id */
+ for (devtype = sizeof(line6_id_table) / sizeof(line6_id_table[0]) - 1; devtype--;)
+ if ((le16_to_cpu(usbdev->descriptor.idVendor) == line6_id_table[devtype].idVendor) &&
+ (le16_to_cpu(usbdev->descriptor.idProduct) == line6_id_table[devtype].idProduct))
+ break;
+
+ if (devtype < 0)
+ return -ENODEV;
+
+ /* find free slot in device table: */
+ for (devnum = 0; devnum < LINE6_MAX_DEVICES; ++devnum)
+ if (line6_devices[devnum] == NULL)
+ break;
+
+ if (devnum == LINE6_MAX_DEVICES)
+ return -ENODEV;
+
+ /* initialize device info: */
+ properties = &line6_properties_table[devtype];
+ dev_info(&interface->dev, "Line6 %s found\n", properties->name);
+ product = le16_to_cpu(usbdev->descriptor.idProduct);
+
+ /* query interface number */
+ interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
+
+ switch (product) {
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODXTLIVE:
+ case LINE6_DEVID_VARIAX:
+ alternate = 1;
+ break;
+
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ switch (interface_number) {
+ case 0:
+ alternate = 1;
+ break;
+ case 1:
+ alternate = 0;
+ break;
+ default:
+ MISSING_CASE;
+ }
+ break;
+
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ alternate = 5;
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_GUITARPORT:
+ alternate = 2; /* 1..4 seem to be ok */
+ break;
+
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ switch (interface_number) {
+ case 0:
+ /* defaults to 44.1kHz, 16-bit */
+ alternate = 2;
+ break;
+ case 1:
+ alternate = 0;
+ break;
+ default:
+ MISSING_CASE;
+ }
+ break;
+
+ default:
+ MISSING_CASE;
+ return -ENODEV;
+ }
+
+ ret = usb_set_interface(usbdev, interface_number, alternate);
+ if (ret < 0) {
+ dev_err(&interface->dev, "set_interface failed\n");
+ return ret;
+ }
+
+ /* initialize device data based on product id: */
+ switch (product) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ size = sizeof(struct usb_line6_pod);
+ ep_read = 0x84;
+ ep_write = 0x03;
+ break;
+
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ /* currently unused! */
+ size = sizeof(struct usb_line6_pod);
+ ep_read = 0x81;
+ ep_write = 0x01;
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_GUITARPORT:
+ size = sizeof(struct usb_line6_toneport);
+ /* these don't have a control channel */
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ size = sizeof(struct usb_line6_pod);
+ ep_read = 0x84;
+ ep_write = 0x03;
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ size = sizeof(struct usb_line6_variax);
+ ep_read = 0x86;
+ ep_write = 0x05;
+ break;
+
+ default:
+ return -ENODEV;
+ }
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ size = sizeof(struct usb_line6_variax);
+ ep_read = 0x82;
+ ep_write = 0x01;
+ break;
+
+ default:
+ MISSING_CASE;
+ return -ENODEV;
+ }
+
+ if (size == 0) {
+ dev_err(line6->ifcdev, "driver bug: interface data size not set\n");
+ return -ENODEV;
+ }
+
+ line6 = kzalloc(size, GFP_KERNEL);
+
+ if (line6 == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ /* store basic data: */
+ line6->interface_number = interface_number;
+ line6->properties = properties;
+ line6->usbdev = usbdev;
+ line6->ifcdev = &interface->dev;
+ line6->ep_control_read = ep_read;
+ line6->ep_control_write = ep_write;
+ line6->product = product;
+
+ /* get data from endpoint descriptor (see usb_maxpacket): */
+ {
+ struct usb_host_endpoint *ep;
+ unsigned epnum = usb_pipeendpoint(usb_rcvintpipe(usbdev, ep_read));
+ ep = usbdev->ep_in[epnum];
+
+ if (ep != NULL) {
+ line6->interval = ep->desc.bInterval;
+ line6->max_packet_size = le16_to_cpu(ep->desc.wMaxPacketSize);
+ } else {
+ line6->interval = LINE6_FALLBACK_INTERVAL;
+ line6->max_packet_size = LINE6_FALLBACK_MAXPACKETSIZE;
+ dev_err(line6->ifcdev, "endpoint not available, using fallback values");
+ }
+ }
+
+ usb_set_intfdata(interface, line6);
+
+ if (properties->capabilities & LINE6_BIT_CONTROL) {
+ /* initialize USB buffers: */
+ line6->buffer_listen = kmalloc(LINE6_BUFSIZE_LISTEN, GFP_KERNEL);
+
+ if (line6->buffer_listen == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ line6_destruct(interface);
+ return -ENOMEM;
+ }
+
+ line6->buffer_message = kmalloc(LINE6_MESSAGE_MAXLEN, GFP_KERNEL);
+
+ if (line6->buffer_message == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ line6_destruct(interface);
+ return -ENOMEM;
+ }
+
+ line6->urb_listen = usb_alloc_urb(0, GFP_KERNEL);
+
+ if (line6->urb_listen == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ line6_destruct(interface);
+ return -ENOMEM;
+ }
+
+ ret = line6_start_listen(line6);
+ if (ret < 0) {
+ dev_err(&interface->dev, "%s: usb_submit_urb failed\n",
+ __func__);
+ line6_destruct(interface);
+ return ret;
+ }
+ }
+
+ /* initialize device data based on product id: */
+ switch (product) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ ret = pod_init(interface, (struct usb_line6_pod *)line6);
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ ret = pod_init(interface, (struct usb_line6_pod *)line6);
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ ret = variax_init(interface, (struct usb_line6_variax *)line6);
+ break;
+
+ default:
+ dev_err(&interface->dev,
+ "PODxt Live interface %d not supported\n",
+ interface_number);
+ ret = -ENODEV;
+ }
+
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ ret = variax_init(interface, (struct usb_line6_variax *)line6);
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_GUITARPORT:
+ ret = toneport_init(interface, (struct usb_line6_toneport *)line6);
+ break;
+
+ default:
+ MISSING_CASE;
+ ret = -ENODEV;
+ }
+
+ if (ret < 0) {
+ line6_destruct(interface);
+ return ret;
+ }
+
+ ret = sysfs_create_link(&interface->dev.kobj, &usbdev->dev.kobj,
+ "usb_device");
+ if (ret < 0) {
+ line6_destruct(interface);
+ return ret;
+ }
+
+ dev_info(&interface->dev, "Line6 %s now attached\n",
+ line6->properties->name);
+ line6_devices[devnum] = line6;
+ line6_list_devices();
+ return ret;
+}
+
+/*
+ Line6 device disconnected.
+*/
+static void line6_disconnect(struct usb_interface *interface)
+{
+ struct usb_line6 *line6;
+ struct usb_device *usbdev;
+ int interface_number, i;
+
+ if (interface == NULL)
+ return;
+ usbdev = interface_to_usbdev(interface);
+ if (usbdev == NULL)
+ return;
+
+ sysfs_remove_link(&interface->dev.kobj, "usb_device");
+
+ interface_number = interface->cur_altsetting->desc.bInterfaceNumber;
+ line6 = usb_get_intfdata(interface);
+
+ if (line6 != NULL) {
+ if (line6->urb_listen != NULL)
+ usb_kill_urb(line6->urb_listen);
+
+ if (usbdev != line6->usbdev)
+ dev_err(line6->ifcdev,
+ "driver bug: inconsistent usb device\n");
+
+ switch (line6->usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTPRO:
+ pod_disconnect(interface);
+ break;
+
+ case LINE6_DEVID_PODXTLIVE:
+ switch (interface_number) {
+ case PODXTLIVE_INTERFACE_POD:
+ pod_disconnect(interface);
+ break;
+
+ case PODXTLIVE_INTERFACE_VARIAX:
+ variax_disconnect(interface);
+ break;
+ }
+
+ break;
+
+ case LINE6_DEVID_VARIAX:
+ variax_disconnect(interface);
+ break;
+
+ case LINE6_DEVID_TONEPORT_GX:
+ case LINE6_DEVID_TONEPORT_UX1:
+ case LINE6_DEVID_TONEPORT_UX2:
+ case LINE6_DEVID_GUITARPORT:
+ toneport_disconnect(interface);
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+
+ dev_info(&interface->dev, "Line6 %s now disconnected\n", line6->properties->name);
+
+ for (i = LINE6_MAX_DEVICES; i--;)
+ if (line6_devices[i] == line6)
+ line6_devices[i] = NULL;
+ }
+
+ line6_destruct(interface);
+
+ /* decrement reference counters: */
+ usb_put_intf(interface);
+ usb_put_dev(usbdev);
+
+ line6_list_devices();
+}
+
+static struct usb_driver line6_driver = {
+ .name = DRIVER_NAME,
+ .probe = line6_probe,
+ .disconnect = line6_disconnect,
+ .id_table = line6_id_table,
+};
+
+/*
+ Module initialization.
+*/
+static int __init line6_init(void)
+{
+ int i, retval;
+
+ printk(KERN_INFO "%s driver version %s%s\n",
+ DRIVER_NAME, DRIVER_VERSION, DRIVER_REVISION);
+ line6_workqueue = create_workqueue(DRIVER_NAME);
+
+ if (line6_workqueue == NULL) {
+ err("couldn't create workqueue");
+ return -EINVAL;
+ }
+
+ for (i = LINE6_MAX_DEVICES; i--;)
+ line6_devices[i] = NULL;
+
+ retval = usb_register(&line6_driver);
+
+ if (retval)
+ err("usb_register failed. Error number %d", retval);
+
+ return retval;
+}
+
+/*
+ Module cleanup.
+*/
+static void __exit line6_exit(void)
+{
+ destroy_workqueue(line6_workqueue);
+ usb_deregister(&line6_driver);
+}
+
+module_init(line6_init);
+module_exit(line6_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRIVER_VERSION);
diff --git a/drivers/staging/line6/driver.h b/drivers/staging/line6/driver.h
new file mode 100644
index 00000000000..9908bfa6afa
--- /dev/null
+++ b/drivers/staging/line6/driver.h
@@ -0,0 +1,204 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef DRIVER_H
+#define DRIVER_H
+
+
+#include "config.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <sound/core.h>
+
+#include "midi.h"
+
+#define DRIVER_NAME "line6usb"
+
+#define LINE6_TIMEOUT 1
+#define LINE6_MAX_DEVICES 8
+#define LINE6_BUFSIZE_LISTEN 32
+#define LINE6_MESSAGE_MAXLEN 256
+
+
+/*
+ Line6 MIDI control commands
+*/
+#define LINE6_PARAM_CHANGE 0xb0
+#define LINE6_PROGRAM_CHANGE 0xc0
+#define LINE6_SYSEX_BEGIN 0xf0
+#define LINE6_SYSEX_END 0xf7
+#define LINE6_RESET 0xff
+
+/*
+ MIDI channel for messages initiated by the host
+ (and eventually echoed back by the device)
+*/
+#define LINE6_CHANNEL_HOST 0x00
+
+/*
+ MIDI channel for messages initiated by the device
+*/
+#define LINE6_CHANNEL_DEVICE 0x02
+
+#define LINE6_CHANNEL_UNKNOWN 5 /* don't know yet what this is good for */
+
+#define LINE6_CHANNEL_MASK 0x0f
+
+
+#define MISSING_CASE \
+ printk(KERN_ERR "line6usb driver bug: missing case in %s:%d\n", \
+ __FILE__, __LINE__)
+
+
+#define CHECK_RETURN(x) \
+do { \
+ err = x; \
+ if (err < 0) \
+ return err; \
+} while (0)
+
+
+extern const unsigned char line6_midi_id[3];
+extern struct usb_line6 *line6_devices[LINE6_MAX_DEVICES];
+extern struct workqueue_struct *line6_workqueue;
+
+static const int SYSEX_DATA_OFS = sizeof(line6_midi_id) + 3;
+static const int SYSEX_EXTRA_SIZE = sizeof(line6_midi_id) + 4;
+
+
+/**
+ Common properties of Line6 devices.
+*/
+struct line6_properties {
+ const char *name;
+ int device_bit;
+ int capabilities;
+};
+
+/**
+ Common data shared by all Line6 devices.
+ Corresponds to a pair of USB endpoints.
+*/
+struct usb_line6 {
+ /**
+ USB device.
+ */
+ struct usb_device *usbdev;
+
+ /**
+ Product id.
+ */
+ int product;
+
+ /**
+ Properties.
+ */
+ const struct line6_properties *properties;
+
+ /**
+ Interface number.
+ */
+ int interface_number;
+
+ /**
+ Interval (ms).
+ */
+ int interval;
+
+ /**
+ Maximum size of USB packet.
+ */
+ int max_packet_size;
+
+ /**
+ Device representing the USB interface.
+ */
+ struct device *ifcdev;
+
+ /**
+ Line6 sound card data structure.
+ Each device has at least MIDI or PCM.
+ */
+ struct snd_card *card;
+
+ /**
+ Line6 PCM device data structure.
+ */
+ struct snd_line6_pcm *line6pcm;
+
+ /**
+ Line6 MIDI device data structure.
+ */
+ struct snd_line6_midi *line6midi;
+
+ /**
+ USB endpoint for listening to control commands.
+ */
+ int ep_control_read;
+
+ /**
+ USB endpoint for writing control commands.
+ */
+ int ep_control_write;
+
+ /**
+ URB for listening to PODxt Pro control endpoint.
+ */
+ struct urb *urb_listen;
+
+ /**
+ Buffer for listening to PODxt Pro control endpoint.
+ */
+ unsigned char *buffer_listen;
+
+ /**
+ Buffer for message to be processed.
+ */
+ unsigned char *buffer_message;
+
+ /**
+ Length of message to be processed.
+ */
+ int message_length;
+};
+
+
+extern char *line6_alloc_sysex_buffer(struct usb_line6 *line6, int code1,
+ int code2, int size);
+extern ssize_t line6_nop_read(struct device *dev,
+ struct device_attribute *attr, char *buf);
+extern ssize_t line6_nop_write(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count);
+extern int line6_read_data(struct usb_line6 *line6, int address, void *data,
+ size_t datalen);
+extern int line6_read_serial_number(struct usb_line6 *line6,
+ int *serial_number);
+extern int line6_send_program(struct usb_line6 *line6, int value);
+extern int line6_send_raw_message(struct usb_line6 *line6, const char *buffer,
+ int size);
+extern int line6_send_raw_message_async(struct usb_line6 *line6,
+ const char *buffer, int size);
+extern int line6_send_sysex_message(struct usb_line6 *line6,
+ const char *buffer, int size);
+extern ssize_t line6_set_raw(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count);
+extern int line6_transmit_parameter(struct usb_line6 *line6, int param,
+ int value);
+extern int line6_write_data(struct usb_line6 *line6, int address, void *data,
+ size_t datalen);
+extern void line6_write_hexdump(struct usb_line6 *line6, char dir,
+ const unsigned char *buffer, int size);
+
+
+#endif
diff --git a/drivers/staging/line6/dumprequest.c b/drivers/staging/line6/dumprequest.c
new file mode 100644
index 00000000000..decbaa971b6
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.c
@@ -0,0 +1,151 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+#include "dumprequest.h"
+
+
+/*
+ Set "dump in progress" flag.
+*/
+void line6_dump_started(struct line6_dump_request *l6dr, int dest)
+{
+ l6dr->in_progress = dest;
+}
+
+/*
+ Invalidate current channel, i.e., set "dump in progress" flag.
+ Reading from the "dump" special file blocks until dump is completed.
+*/
+void line6_invalidate_current(struct line6_dump_request *l6dr)
+{
+ line6_dump_started(l6dr, LINE6_DUMP_CURRENT);
+}
+
+/*
+ Clear "dump in progress" flag and notify waiting processes.
+*/
+void line6_dump_finished(struct line6_dump_request *l6dr)
+{
+ l6dr->in_progress = LINE6_DUMP_NONE;
+ wake_up_interruptible(&l6dr->wait);
+}
+
+/*
+ Send an asynchronous channel dump request.
+*/
+int line6_dump_request_async(struct line6_dump_request *l6dr,
+ struct usb_line6 *line6, int num)
+{
+ int ret;
+ line6_invalidate_current(l6dr);
+ ret = line6_send_raw_message_async(line6, l6dr->reqbufs[num].buffer,
+ l6dr->reqbufs[num].length);
+
+ if (ret < 0)
+ line6_dump_finished(l6dr);
+
+ return ret;
+}
+
+/*
+ Send an asynchronous dump request after a given interval.
+*/
+void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
+ void (*function)(unsigned long), void *data)
+{
+ l6dr->timer.expires = jiffies + seconds * HZ;
+ l6dr->timer.function = function;
+ l6dr->timer.data = (unsigned long)data;
+ add_timer(&l6dr->timer);
+}
+
+/*
+ Wait for completion.
+*/
+int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock)
+{
+ int retval = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ add_wait_queue(&l6dr->wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (l6dr->in_progress) {
+ if (nonblock) {
+ retval = -EAGAIN;
+ break;
+ }
+
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ } else
+ schedule();
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&l6dr->wait, &wait);
+ return retval;
+}
+
+/*
+ Initialize dump request buffer.
+*/
+int line6_dumpreq_initbuf(struct line6_dump_request *l6dr, const void *buf,
+ size_t len, int num)
+{
+ l6dr->reqbufs[num].buffer = kmalloc(len, GFP_KERNEL);
+ if (l6dr->reqbufs[num].buffer == NULL)
+ return -ENOMEM;
+ memcpy(l6dr->reqbufs[num].buffer, buf, len);
+ l6dr->reqbufs[num].length = len;
+ return 0;
+}
+
+/*
+ Initialize dump request data structure (including one buffer).
+*/
+int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
+ size_t len)
+{
+ int ret;
+ ret = line6_dumpreq_initbuf(l6dr, buf, len, 0);
+ if (ret < 0)
+ return ret;
+ init_waitqueue_head(&l6dr->wait);
+ init_timer(&l6dr->timer);
+ return 0;
+}
+
+/*
+ Destruct dump request data structure.
+*/
+void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num)
+{
+ if (l6dr == NULL)
+ return;
+ if (l6dr->reqbufs[num].buffer == NULL)
+ return;
+ kfree(l6dr->reqbufs[num].buffer);
+ l6dr->reqbufs[num].buffer = NULL;
+}
+
+/*
+ Destruct dump request data structure.
+*/
+void line6_dumpreq_destruct(struct line6_dump_request *l6dr)
+{
+ if (l6dr->reqbufs[0].buffer == NULL)
+ return;
+ line6_dumpreq_destructbuf(l6dr, 0);
+ l6dr->ok = 1;
+ del_timer_sync(&l6dr->timer);
+}
diff --git a/drivers/staging/line6/dumprequest.h b/drivers/staging/line6/dumprequest.h
new file mode 100644
index 00000000000..1975d54b3c2
--- /dev/null
+++ b/drivers/staging/line6/dumprequest.h
@@ -0,0 +1,90 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef DUMPREQUEST_H
+#define DUMPREQUEST_H
+
+
+#include <linux/usb.h>
+#include <linux/wait.h>
+
+#include <sound/core.h>
+
+
+enum {
+ LINE6_DUMP_NONE,
+ LINE6_DUMP_CURRENT
+};
+
+
+struct line6_dump_reqbuf {
+ /**
+ Buffer for dump requests.
+ */
+ unsigned char *buffer;
+
+ /**
+ Size of dump request.
+ */
+ size_t length;
+};
+
+/**
+ Provides the functionality to request channel/model/... dump data from a
+ Line6 device.
+*/
+struct line6_dump_request {
+ /**
+ Wait queue for access to program dump data.
+ */
+ wait_queue_head_t wait;
+
+ /**
+ Indicates an unfinished program dump request.
+ 0: no dump
+ 1: dump current settings
+ Other device-specific values are also allowed.
+ */
+ int in_progress;
+
+ /**
+ Timer for delayed dump request.
+ */
+ struct timer_list timer;
+
+ /**
+ Flag if initial dump request has been successful.
+ */
+ char ok;
+
+ /**
+ Dump request buffers
+ */
+ struct line6_dump_reqbuf reqbufs[1];
+};
+
+extern void line6_dump_finished(struct line6_dump_request *l6dr);
+extern int line6_dump_request_async(struct line6_dump_request *l6dr,
+ struct usb_line6 *line6, int num);
+extern void line6_dump_started(struct line6_dump_request *l6dr, int dest);
+extern void line6_dumpreq_destruct(struct line6_dump_request *l6dr);
+extern void line6_dumpreq_destructbuf(struct line6_dump_request *l6dr, int num);
+extern int line6_dumpreq_init(struct line6_dump_request *l6dr, const void *buf,
+ size_t len);
+extern int line6_dumpreq_initbuf(struct line6_dump_request *l6dr,
+ const void *buf, size_t len, int num);
+extern void line6_invalidate_current(struct line6_dump_request *l6dr);
+extern void line6_startup_delayed(struct line6_dump_request *l6dr, int seconds,
+ void (*function)(unsigned long), void *data);
+extern int line6_wait_dump(struct line6_dump_request *l6dr, int nonblock);
+
+
+#endif
diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c
new file mode 100644
index 00000000000..89a2b17e9ca
--- /dev/null
+++ b/drivers/staging/line6/midi.c
@@ -0,0 +1,422 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include <linux/usb.h>
+
+#include <sound/core.h>
+#include <sound/rawmidi.h>
+
+#include "audio.h"
+#include "midi.h"
+#include "pod.h"
+#include "usbdefs.h"
+
+
+#define USE_MIDIBUF 1
+#define OUTPUT_DUMP_ONLY 0
+
+
+#define line6_rawmidi_substream_midi(substream) \
+ ((struct snd_line6_midi *)((substream)->rmidi->private_data))
+
+
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+ int length);
+
+
+/*
+ Pass data received via USB to MIDI.
+*/
+void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+ int length)
+{
+ if (line6->line6midi->substream_receive)
+ snd_rawmidi_receive(line6->line6midi->substream_receive,
+ data, length);
+}
+
+/*
+ Read data from MIDI buffer and transmit them via USB.
+*/
+static void line6_midi_transmit(struct snd_rawmidi_substream *substream)
+{
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+ struct snd_line6_midi *line6midi = line6->line6midi;
+ struct MidiBuffer *mb = &line6midi->midibuf_out;
+ unsigned long flags;
+ unsigned char chunk[line6->max_packet_size];
+ int req, done;
+
+ spin_lock_irqsave(&line6->line6midi->midi_transmit_lock, flags);
+
+ for (;;) {
+ req = min(midibuf_bytes_free(mb), line6->max_packet_size);
+ done = snd_rawmidi_transmit_peek(substream, chunk, req);
+
+ if (done == 0)
+ break;
+
+#if DO_DUMP_MIDI_SEND
+ line6_write_hexdump(line6, 's', chunk, done);
+#endif
+ midibuf_write(mb, chunk, done);
+ snd_rawmidi_transmit_ack(substream, done);
+ }
+
+ for (;;) {
+ done = midibuf_read(mb, chunk, line6->max_packet_size);
+
+ if (done == 0)
+ break;
+
+ if (midibuf_skip_message(mb, line6midi->midi_mask_transmit))
+ continue;
+
+ send_midi_async(line6, chunk, done);
+ }
+
+ spin_unlock_irqrestore(&line6->line6midi->midi_transmit_lock, flags);
+}
+
+/*
+ Notification of completion of MIDI transmission.
+*/
+static void midi_sent(struct urb *urb)
+{
+ unsigned long flags;
+ int status;
+ int num;
+ struct usb_line6 *line6 = (struct usb_line6 *)urb->context;
+
+ status = urb->status;
+ kfree(urb->transfer_buffer);
+ usb_free_urb(urb);
+
+ if (status == -ESHUTDOWN)
+ return;
+
+ spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
+ num = --line6->line6midi->num_active_send_urbs;
+
+ if (num == 0) {
+ line6_midi_transmit(line6->line6midi->substream_transmit);
+ num = line6->line6midi->num_active_send_urbs;
+ }
+
+ if (num == 0)
+ wake_up_interruptible(&line6->line6midi->send_wait);
+
+ spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
+}
+
+/*
+ Send an asynchronous MIDI message.
+ Assumes that line6->line6midi->send_urb_lock is held
+ (i.e., this function is serialized).
+*/
+static int send_midi_async(struct usb_line6 *line6, unsigned char *data,
+ int length)
+{
+ struct urb *urb;
+ int retval;
+ unsigned char *transfer_buffer;
+
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+
+ if (urb == 0) {
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+#if DO_DUMP_URB_SEND
+ line6_write_hexdump(line6, 'S', data, length);
+#endif
+
+ transfer_buffer = kmalloc(length, GFP_ATOMIC);
+
+ if (transfer_buffer == 0) {
+ usb_free_urb(urb);
+ dev_err(line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ memcpy(transfer_buffer, data, length);
+ usb_fill_int_urb(urb, line6->usbdev,
+ usb_sndbulkpipe(line6->usbdev,
+ line6->ep_control_write),
+ transfer_buffer, length, midi_sent, line6,
+ line6->interval);
+ urb->actual_length = 0;
+ retval = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (retval < 0) {
+ dev_err(line6->ifcdev, "usb_submit_urb failed\n");
+ usb_free_urb(urb);
+ return -EINVAL;
+ }
+
+ ++line6->line6midi->num_active_send_urbs;
+
+ switch (line6->usbdev->descriptor.idProduct) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTLIVE:
+ case LINE6_DEVID_PODXTPRO:
+ case LINE6_DEVID_POCKETPOD:
+ pod_midi_postprocess((struct usb_line6_pod *)line6, data,
+ length);
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+
+ return 0;
+}
+
+static int line6_midi_output_open(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static int line6_midi_output_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static void line6_midi_output_trigger(struct snd_rawmidi_substream *substream,
+ int up)
+{
+ unsigned long flags;
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+
+ line6->line6midi->substream_transmit = substream;
+ spin_lock_irqsave(&line6->line6midi->send_urb_lock, flags);
+
+ if (line6->line6midi->num_active_send_urbs == 0)
+ line6_midi_transmit(substream);
+
+ spin_unlock_irqrestore(&line6->line6midi->send_urb_lock, flags);
+}
+
+static void line6_midi_output_drain(struct snd_rawmidi_substream *substream)
+{
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+ wait_queue_head_t *head = &line6->line6midi->send_wait;
+ DECLARE_WAITQUEUE(wait, current);
+ add_wait_queue(head, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (line6->line6midi->num_active_send_urbs > 0)
+ if (signal_pending(current))
+ break;
+ else
+ schedule();
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(head, &wait);
+}
+
+static int line6_midi_input_open(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static int line6_midi_input_close(struct snd_rawmidi_substream *substream)
+{
+ return 0;
+}
+
+static void line6_midi_input_trigger(struct snd_rawmidi_substream *substream,
+ int up)
+{
+ struct usb_line6 *line6 = line6_rawmidi_substream_midi(substream)->line6;
+
+ if (up)
+ line6->line6midi->substream_receive = substream;
+ else
+ line6->line6midi->substream_receive = 0;
+}
+
+static struct snd_rawmidi_ops line6_midi_output_ops = {
+ .open = line6_midi_output_open,
+ .close = line6_midi_output_close,
+ .trigger = line6_midi_output_trigger,
+ .drain = line6_midi_output_drain,
+};
+
+static struct snd_rawmidi_ops line6_midi_input_ops = {
+ .open = line6_midi_input_open,
+ .close = line6_midi_input_close,
+ .trigger = line6_midi_input_trigger,
+};
+
+/*
+ Cleanup the Line6 MIDI device.
+*/
+static void line6_cleanup_midi(struct snd_rawmidi *rmidi)
+{
+}
+
+/* Create a MIDI device */
+static int snd_line6_new_midi(struct snd_line6_midi *line6midi)
+{
+ struct snd_rawmidi *rmidi;
+ int err;
+
+ err = snd_rawmidi_new(line6midi->line6->card, "Line6 MIDI", 0, 1, 1,
+ &rmidi);
+ if (err < 0)
+ return err;
+
+ rmidi->private_data = line6midi;
+ rmidi->private_free = line6_cleanup_midi;
+ strcpy(rmidi->name, line6midi->line6->properties->name);
+
+ rmidi->info_flags =
+ SNDRV_RAWMIDI_INFO_OUTPUT |
+ SNDRV_RAWMIDI_INFO_INPUT |
+ SNDRV_RAWMIDI_INFO_DUPLEX;
+
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT,
+ &line6_midi_output_ops);
+ snd_rawmidi_set_ops(rmidi, SNDRV_RAWMIDI_STREAM_INPUT,
+ &line6_midi_input_ops);
+ return 0;
+}
+
+/*
+ "read" request on "midi_mask_transmit" special file.
+*/
+static ssize_t midi_get_midi_mask_transmit(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", line6->line6midi->midi_mask_transmit);
+}
+
+/*
+ "write" request on "midi_mask" special file.
+*/
+static ssize_t midi_set_midi_mask_transmit(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ line6->line6midi->midi_mask_transmit = value;
+ return count;
+}
+
+/*
+ "read" request on "midi_mask_receive" special file.
+*/
+static ssize_t midi_get_midi_mask_receive(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", line6->line6midi->midi_mask_receive);
+}
+
+/*
+ "write" request on "midi_mask" special file.
+*/
+static ssize_t midi_set_midi_mask_receive(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6 *line6 = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ line6->line6midi->midi_mask_receive = value;
+ return count;
+}
+
+static DEVICE_ATTR(midi_mask_transmit, S_IWUGO | S_IRUGO, midi_get_midi_mask_transmit, midi_set_midi_mask_transmit);
+static DEVICE_ATTR(midi_mask_receive, S_IWUGO | S_IRUGO, midi_get_midi_mask_receive, midi_set_midi_mask_receive);
+
+/* MIDI device destructor */
+static int snd_line6_midi_free(struct snd_device *device)
+{
+ struct snd_line6_midi *line6midi = device->device_data;
+ device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_transmit);
+ device_remove_file(line6midi->line6->ifcdev, &dev_attr_midi_mask_receive);
+ midibuf_destroy(&line6midi->midibuf_in);
+ midibuf_destroy(&line6midi->midibuf_out);
+ return 0;
+}
+
+/*
+ Initialize the Line6 MIDI subsystem.
+*/
+int line6_init_midi(struct usb_line6 *line6)
+{
+ static struct snd_device_ops midi_ops = {
+ .dev_free = snd_line6_midi_free,
+ };
+
+ int err;
+ struct snd_line6_midi *line6midi;
+
+ if (!(line6->properties->capabilities & LINE6_BIT_CONTROL))
+ return 0; /* skip MIDI initialization and report success */
+
+ line6midi = kzalloc(sizeof(struct snd_line6_midi), GFP_KERNEL);
+
+ if (line6midi == NULL)
+ return -ENOMEM;
+
+ err = midibuf_init(&line6midi->midibuf_in, MIDI_BUFFER_SIZE, 0);
+ if (err < 0)
+ return err;
+
+ err = midibuf_init(&line6midi->midibuf_out, MIDI_BUFFER_SIZE, 1);
+ if (err < 0)
+ return err;
+
+ line6midi->line6 = line6;
+ line6midi->midi_mask_transmit = 1;
+ line6midi->midi_mask_receive = 4;
+ line6->line6midi = line6midi;
+
+ err = snd_device_new(line6->card, SNDRV_DEV_RAWMIDI, line6midi,
+ &midi_ops);
+ if (err < 0)
+ return err;
+
+ snd_card_set_dev(line6->card, line6->ifcdev);
+
+ err = snd_line6_new_midi(line6midi);
+ if (err < 0)
+ return err;
+
+ err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_transmit);
+ if (err < 0)
+ return err;
+
+ err = device_create_file(line6->ifcdev, &dev_attr_midi_mask_receive);
+ if (err < 0)
+ return err;
+
+ init_waitqueue_head(&line6midi->send_wait);
+ spin_lock_init(&line6midi->send_urb_lock);
+ spin_lock_init(&line6midi->midi_transmit_lock);
+ return 0;
+}
diff --git a/drivers/staging/line6/midi.h b/drivers/staging/line6/midi.h
new file mode 100644
index 00000000000..c69fd118957
--- /dev/null
+++ b/drivers/staging/line6/midi.h
@@ -0,0 +1,87 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef MIDI_H
+#define MIDI_H
+
+
+#include <sound/rawmidi.h>
+
+#include "midibuf.h"
+
+
+#define MIDI_BUFFER_SIZE 1024
+
+
+struct snd_line6_midi {
+ /**
+ Pointer back to the Line6 driver data structure.
+ */
+ struct usb_line6 *line6;
+
+ /**
+ MIDI substream for receiving (or NULL if not active).
+ */
+ struct snd_rawmidi_substream *substream_receive;
+
+ /**
+ MIDI substream for transmitting (or NULL if not active).
+ */
+ struct snd_rawmidi_substream *substream_transmit;
+
+ /**
+ Number of currently active MIDI send URBs.
+ */
+ int num_active_send_urbs;
+
+ /**
+ Spin lock to protect updates of send_urb.
+ */
+ spinlock_t send_urb_lock;
+
+ /**
+ Spin lock to protect MIDI buffer handling.
+ */
+ spinlock_t midi_transmit_lock;
+
+ /**
+ Wait queue for MIDI transmission.
+ */
+ wait_queue_head_t send_wait;
+
+ /**
+ Bit mask for output MIDI channels.
+ */
+ int midi_mask_transmit;
+
+ /**
+ Bit mask for input MIDI channels.
+ */
+ int midi_mask_receive;
+
+ /**
+ Buffer for incoming MIDI stream.
+ */
+ struct MidiBuffer midibuf_in;
+
+ /**
+ Buffer for outgoing MIDI stream.
+ */
+ struct MidiBuffer midibuf_out;
+};
+
+
+extern int line6_init_midi(struct usb_line6 *line6);
+extern void line6_midi_receive(struct usb_line6 *line6, unsigned char *data,
+ int length);
+
+
+#endif
diff --git a/drivers/staging/line6/midibuf.c b/drivers/staging/line6/midibuf.c
new file mode 100644
index 00000000000..ab0a5f30fbc
--- /dev/null
+++ b/drivers/staging/line6/midibuf.c
@@ -0,0 +1,262 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "config.h"
+
+#include <linux/slab.h>
+
+#include "midibuf.h"
+
+
+static int midibuf_message_length(unsigned char code)
+{
+ if (code < 0x80)
+ return -1;
+ else if (code < 0xf0) {
+ static const int length[] = { 3, 3, 3, 3, 2, 2, 3 };
+ return length[(code >> 4) - 8];
+ } else {
+ /*
+ Note that according to the MIDI specification 0xf2 is
+ the "Song Position Pointer", but this is used by Line6
+ to send sysex messages to the host.
+ */
+ static const int length[] = { -1, 2, -1, 2, -1, -1, 1, 1, 1, 1,
+ 1, 1, 1, -1, 1, 1 };
+ return length[code & 0x0f];
+ }
+}
+
+void midibuf_reset(struct MidiBuffer *this)
+{
+ this->pos_read = this->pos_write = this->full = 0;
+ this->command_prev = -1;
+}
+
+int midibuf_init(struct MidiBuffer *this, int size, int split)
+{
+ this->buf = kmalloc(size, GFP_KERNEL);
+
+ if (this->buf == NULL)
+ return -ENOMEM;
+
+ this->size = size;
+ this->split = split;
+ midibuf_reset(this);
+ return 0;
+}
+
+void midibuf_status(struct MidiBuffer *this)
+{
+ printk(KERN_DEBUG "midibuf size=%d split=%d pos_read=%d pos_write=%d "
+ "full=%d command_prev=%02x\n", this->size, this->split,
+ this->pos_read, this->pos_write, this->full, this->command_prev);
+}
+
+static int midibuf_is_empty(struct MidiBuffer *this)
+{
+ return (this->pos_read == this->pos_write) && !this->full;
+}
+
+static int midibuf_is_full(struct MidiBuffer *this)
+{
+ return this->full;
+}
+
+int midibuf_bytes_free(struct MidiBuffer *this)
+{
+ return
+ midibuf_is_full(this) ?
+ 0 :
+ (this->pos_read - this->pos_write + this->size - 1) % this->size + 1;
+}
+
+int midibuf_bytes_used(struct MidiBuffer *this)
+{
+ return
+ midibuf_is_empty(this) ?
+ 0 :
+ (this->pos_write - this->pos_read + this->size - 1) % this->size + 1;
+}
+
+int midibuf_write(struct MidiBuffer *this, unsigned char *data, int length)
+{
+ int bytes_free;
+ int length1, length2;
+ int skip_active_sense = 0;
+
+ if (midibuf_is_full(this) || (length <= 0))
+ return 0;
+
+ /* skip trailing active sense */
+ if (data[length - 1] == 0xfe) {
+ --length;
+ skip_active_sense = 1;
+ }
+
+ bytes_free = midibuf_bytes_free(this);
+
+ if (length > bytes_free)
+ length = bytes_free;
+
+ if (length > 0) {
+ length1 = this->size - this->pos_write;
+
+ if (length < length1) {
+ /* no buffer wraparound */
+ memcpy(this->buf + this->pos_write, data, length);
+ this->pos_write += length;
+ } else {
+ /* buffer wraparound */
+ length2 = length - length1;
+ memcpy(this->buf + this->pos_write, data, length1);
+ memcpy(this->buf, data + length1, length2);
+ this->pos_write = length2;
+ }
+
+ if (this->pos_write == this->pos_read)
+ this->full = 1;
+ }
+
+ return length + skip_active_sense;
+}
+
+int midibuf_read(struct MidiBuffer *this, unsigned char *data, int length)
+{
+ int bytes_used;
+ int length1, length2;
+ int command;
+ int midi_length;
+ int repeat = 0;
+ int i;
+
+ /* we need to be able to store at least a 3 byte MIDI message */
+ if (length < 3)
+ return -EINVAL;
+
+ if (midibuf_is_empty(this))
+ return 0;
+
+ bytes_used = midibuf_bytes_used(this);
+
+ if (length > bytes_used)
+ length = bytes_used;
+
+ length1 = this->size - this->pos_read;
+
+ /* check MIDI command length */
+ command = this->buf[this->pos_read];
+
+ if (command & 0x80) {
+ midi_length = midibuf_message_length(command);
+ this->command_prev = command;
+ } else {
+ if (this->command_prev > 0) {
+ int midi_length_prev = midibuf_message_length(this->command_prev);
+
+ if (midi_length_prev > 0) {
+ midi_length = midi_length_prev - 1;
+ repeat = 1;
+ } else
+ midi_length = -1;
+ } else
+ midi_length = -1;
+ }
+
+ if (midi_length < 0) {
+ /* search for end of message */
+ if (length < length1) {
+ /* no buffer wraparound */
+ for (i = 1; i < length; ++i)
+ if (this->buf[this->pos_read + i] & 0x80)
+ break;
+
+ midi_length = i;
+ } else {
+ /* buffer wraparound */
+ length2 = length - length1;
+
+ for (i = 1; i < length1; ++i)
+ if (this->buf[this->pos_read + i] & 0x80)
+ break;
+
+ if (i < length1)
+ midi_length = i;
+ else {
+ for (i = 0; i < length2; ++i)
+ if (this->buf[i] & 0x80)
+ break;
+
+ midi_length = length1 + i;
+ }
+ }
+
+ if (midi_length == length)
+ midi_length = -1; /* end of message not found */
+ }
+
+ if (midi_length < 0) {
+ if (!this->split)
+ return 0; /* command is not yet complete */
+ } else {
+ if (length < midi_length)
+ return 0; /* command is not yet complete */
+
+ length = midi_length;
+ }
+
+ if (length < length1) {
+ /* no buffer wraparound */
+ memcpy(data + repeat, this->buf + this->pos_read, length);
+ this->pos_read += length;
+ } else {
+ /* buffer wraparound */
+ length2 = length - length1;
+ memcpy(data + repeat, this->buf + this->pos_read, length1);
+ memcpy(data + repeat + length1, this->buf, length2);
+ this->pos_read = length2;
+ }
+
+ if (repeat)
+ data[0] = this->command_prev;
+
+ this->full = 0;
+ return length + repeat;
+}
+
+int midibuf_ignore(struct MidiBuffer *this, int length)
+{
+ int bytes_used = midibuf_bytes_used(this);
+
+ if (length > bytes_used)
+ length = bytes_used;
+
+ this->pos_read = (this->pos_read + length) % this->size;
+ this->full = 0;
+ return length;
+}
+
+int midibuf_skip_message(struct MidiBuffer *this, unsigned short mask)
+{
+ int cmd = this->command_prev;
+
+ if ((cmd >= 0x80) && (cmd < 0xf0))
+ if ((mask & (1 << (cmd & 0x0f))) == 0)
+ return 1;
+
+ return 0;
+}
+
+void midibuf_destroy(struct MidiBuffer *this)
+{
+ kfree(this->buf);
+ this->buf = NULL;
+}
diff --git a/drivers/staging/line6/midibuf.h b/drivers/staging/line6/midibuf.h
new file mode 100644
index 00000000000..9877581bcd9
--- /dev/null
+++ b/drivers/staging/line6/midibuf.h
@@ -0,0 +1,39 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef MIDIBUF_H
+#define MIDIBUF_H
+
+
+struct MidiBuffer {
+ unsigned char *buf;
+ int size;
+ int split;
+ int pos_read, pos_write;
+ int full;
+ int command_prev;
+};
+
+
+extern int midibuf_bytes_used(struct MidiBuffer *mb);
+extern int midibuf_bytes_free(struct MidiBuffer *mb);
+extern void midibuf_destroy(struct MidiBuffer *mb);
+extern int midibuf_ignore(struct MidiBuffer *mb, int length);
+extern int midibuf_init(struct MidiBuffer *mb, int size, int split);
+extern int midibuf_read(struct MidiBuffer *mb, unsigned char *data, int length);
+extern void midibuf_reset(struct MidiBuffer *mb);
+extern int midibuf_skip_message(struct MidiBuffer *mb, unsigned short mask);
+extern void midibuf_status(struct MidiBuffer *mb);
+extern int midibuf_write(struct MidiBuffer *mb, unsigned char *data,
+ int length);
+
+
+#endif
diff --git a/drivers/staging/line6/pcm.c b/drivers/staging/line6/pcm.c
new file mode 100644
index 00000000000..fc4113f3315
--- /dev/null
+++ b/drivers/staging/line6/pcm.c
@@ -0,0 +1,301 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include <sound/core.h>
+#include <sound/control.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "capture.h"
+#include "playback.h"
+#include "pod.h"
+
+
+/* trigger callback */
+int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ struct snd_pcm_substream *s;
+ int err;
+ unsigned long flags;
+
+ spin_lock_irqsave(&line6pcm->lock_trigger, flags);
+ clear_bit(BIT_PREPARED, &line6pcm->flags);
+
+ snd_pcm_group_for_each_entry(s, substream) {
+ switch (s->stream) {
+ case SNDRV_PCM_STREAM_PLAYBACK:
+ err = snd_line6_playback_trigger(s, cmd);
+
+ if (err < 0) {
+ spin_unlock_irqrestore(&line6pcm->lock_trigger,
+ flags);
+ return err;
+ }
+
+ break;
+
+ case SNDRV_PCM_STREAM_CAPTURE:
+ err = snd_line6_capture_trigger(s, cmd);
+
+ if (err < 0) {
+ spin_unlock_irqrestore(&line6pcm->lock_trigger,
+ flags);
+ return err;
+ }
+
+ break;
+
+ default:
+ dev_err(s2m(substream), "Unknown stream direction %d\n",
+ s->stream);
+ }
+ }
+
+ spin_unlock_irqrestore(&line6pcm->lock_trigger, flags);
+ return 0;
+}
+
+/* control info callback */
+static int snd_line6_control_info(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_info *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
+ uinfo->count = 2;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 256;
+ return 0;
+}
+
+/* control get callback */
+static int snd_line6_control_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i;
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+ for (i = 2; i--;)
+ ucontrol->value.integer.value[i] = line6pcm->volume[i];
+
+ return 0;
+}
+
+/* control put callback */
+static int snd_line6_control_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ int i, changed = 0;
+ struct snd_line6_pcm *line6pcm = snd_kcontrol_chip(kcontrol);
+
+ for (i = 2; i--;)
+ if (line6pcm->volume[i] != ucontrol->value.integer.value[i]) {
+ line6pcm->volume[i] = ucontrol->value.integer.value[i];
+ changed = 1;
+ }
+
+ return changed;
+}
+
+/* control definition */
+static struct snd_kcontrol_new line6_control = {
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .name = "PCM Playback Volume",
+ .index = 0,
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
+ .info = snd_line6_control_info,
+ .get = snd_line6_control_get,
+ .put = snd_line6_control_put
+};
+
+/*
+ Cleanup the PCM device.
+*/
+static void line6_cleanup_pcm(struct snd_pcm *pcm)
+{
+ int i;
+ struct snd_line6_pcm *line6pcm = snd_pcm_chip(pcm);
+
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (line6pcm->urb_audio_out[i]) {
+ usb_kill_urb(line6pcm->urb_audio_out[i]);
+ usb_free_urb(line6pcm->urb_audio_out[i]);
+ }
+ if (line6pcm->urb_audio_in[i]) {
+ usb_kill_urb(line6pcm->urb_audio_in[i]);
+ usb_free_urb(line6pcm->urb_audio_in[i]);
+ }
+ }
+}
+
+/* create a PCM device */
+static int snd_line6_new_pcm(struct snd_line6_pcm *line6pcm)
+{
+ struct snd_pcm *pcm;
+ int err;
+
+ err = snd_pcm_new(line6pcm->line6->card,
+ (char *)line6pcm->line6->properties->name,
+ 0, 1, 1, &pcm);
+ if (err < 0)
+ return err;
+
+ pcm->private_data = line6pcm;
+ pcm->private_free = line6_cleanup_pcm;
+ line6pcm->pcm = pcm;
+ strcpy(pcm->name, line6pcm->line6->properties->name);
+
+ /* set operators */
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_line6_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_line6_capture_ops);
+
+ /* pre-allocation of buffers */
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
+ snd_dma_continuous_data(GFP_KERNEL),
+ 64 * 1024, 128 * 1024);
+
+ return 0;
+}
+
+/* PCM device destructor */
+static int snd_line6_pcm_free(struct snd_device *device)
+{
+ return 0;
+}
+
+/*
+ Create and register the PCM device and mixer entries.
+ Create URBs for playback and capture.
+*/
+int line6_init_pcm(struct usb_line6 *line6,
+ struct line6_pcm_properties *properties)
+{
+ static struct snd_device_ops pcm_ops = {
+ .dev_free = snd_line6_pcm_free,
+ };
+
+ int err;
+ int ep_read = 0, ep_write = 0;
+ struct snd_line6_pcm *line6pcm;
+
+ if (!(line6->properties->capabilities & LINE6_BIT_PCM))
+ return 0; /* skip PCM initialization and report success */
+
+ /* initialize PCM subsystem based on product id: */
+ switch (line6->product) {
+ case LINE6_DEVID_BASSPODXT:
+ case LINE6_DEVID_BASSPODXTLIVE:
+ case LINE6_DEVID_BASSPODXTPRO:
+ case LINE6_DEVID_PODXT:
+ case LINE6_DEVID_PODXTLIVE:
+ case LINE6_DEVID_PODXTPRO:
+ ep_read = 0x82;
+ ep_write = 0x01;
+ break;
+
+ case LINE6_DEVID_PODX3:
+ case LINE6_DEVID_PODX3LIVE:
+ ep_read = 0x86;
+ ep_write = 0x02;
+ break;
+
+ case LINE6_DEVID_POCKETPOD:
+ ep_read = 0x82;
+ ep_write = 0x02;
+ break;
+
+ case LINE6_DEVID_GUITARPORT:
+ case LINE6_DEVID_TONEPORT_GX:
+ ep_read = 0x82;
+ ep_write = 0x01;
+ break;
+
+ case LINE6_DEVID_TONEPORT_UX1:
+ ep_read = 0x00;
+ ep_write = 0x00;
+ break;
+
+ case LINE6_DEVID_TONEPORT_UX2:
+ ep_read = 0x87;
+ ep_write = 0x00;
+ break;
+
+ default:
+ MISSING_CASE;
+ }
+
+ line6pcm = kzalloc(sizeof(struct snd_line6_pcm), GFP_KERNEL);
+
+ if (line6pcm == NULL)
+ return -ENOMEM;
+
+ line6pcm->volume[0] = line6pcm->volume[1] = 128;
+ line6pcm->line6 = line6;
+ line6pcm->ep_audio_read = ep_read;
+ line6pcm->ep_audio_write = ep_write;
+ line6pcm->max_packet_size = usb_maxpacket(line6->usbdev,
+ usb_rcvintpipe(line6->usbdev,
+ ep_read),
+ 0);
+ line6pcm->properties = properties;
+ line6->line6pcm = line6pcm;
+
+ /* PCM device: */
+ err = snd_device_new(line6->card, SNDRV_DEV_PCM, line6, &pcm_ops);
+ if (err < 0)
+ return err;
+
+ snd_card_set_dev(line6->card, line6->ifcdev);
+
+ err = snd_line6_new_pcm(line6pcm);
+ if (err < 0)
+ return err;
+
+ spin_lock_init(&line6pcm->lock_audio_out);
+ spin_lock_init(&line6pcm->lock_audio_in);
+ spin_lock_init(&line6pcm->lock_trigger);
+
+ err = create_audio_out_urbs(line6pcm);
+ if (err < 0)
+ return err;
+
+ err = create_audio_in_urbs(line6pcm);
+ if (err < 0)
+ return err;
+
+ /* mixer: */
+ err = snd_ctl_add(line6->card, snd_ctl_new1(&line6_control, line6pcm));
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+/* prepare pcm callback */
+int snd_line6_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ if (!test_and_set_bit(BIT_PREPARED, &line6pcm->flags)) {
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+ line6pcm->pos_out = 0;
+ line6pcm->pos_out_done = 0;
+
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+ line6pcm->bytes_out = 0;
+ line6pcm->pos_in_done = 0;
+ line6pcm->bytes_in = 0;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h
new file mode 100644
index 00000000000..53db217cd42
--- /dev/null
+++ b/drivers/staging/line6/pcm.h
@@ -0,0 +1,222 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+/*
+ PCM interface to POD series devices.
+*/
+
+#ifndef PCM_H
+#define PCM_H
+
+
+#include <sound/pcm.h>
+
+#include "driver.h"
+#include "usbdefs.h"
+
+
+/* number of URBs */
+#define LINE6_ISO_BUFFERS 8
+
+/* number of USB frames per URB */
+#define LINE6_ISO_PACKETS 2
+
+/* in a "full speed" device (such as the PODxt Pro) this means 1ms */
+#define LINE6_ISO_INTERVAL 1
+
+/* this should be queried dynamically from the USB interface! */
+#define LINE6_ISO_PACKET_SIZE_MAX 252
+
+
+/*
+ Extract the messaging device from the substream instance
+*/
+#define s2m(s) (((struct snd_line6_pcm *) \
+ snd_pcm_substream_chip(s))->line6->ifcdev)
+
+
+enum {
+ BIT_RUNNING_PLAYBACK,
+ BIT_RUNNING_CAPTURE,
+ BIT_PAUSE_PLAYBACK,
+ BIT_PREPARED
+};
+
+struct line6_pcm_properties {
+ struct snd_pcm_hardware snd_line6_playback_hw, snd_line6_capture_hw;
+ struct snd_pcm_hw_constraint_ratdens snd_line6_rates;
+ int bytes_per_frame;
+};
+
+struct snd_line6_pcm {
+ /**
+ Pointer back to the Line6 driver data structure.
+ */
+ struct usb_line6 *line6;
+
+ /**
+ Properties.
+ */
+ struct line6_pcm_properties *properties;
+
+ /**
+ ALSA pcm stream
+ */
+ struct snd_pcm *pcm;
+
+ /**
+ URBs for audio playback.
+ */
+ struct urb *urb_audio_out[LINE6_ISO_BUFFERS];
+
+ /**
+ URBs for audio capture.
+ */
+ struct urb *urb_audio_in[LINE6_ISO_BUFFERS];
+
+ /**
+ Temporary buffer to hold data when playback buffer wraps.
+ */
+ unsigned char *wrap_out;
+
+ /**
+ Temporary buffer for capture.
+ Since the packet size is not known in advance, this buffer is
+ large enough to store maximum size packets.
+ */
+ unsigned char *buffer_in;
+
+ /**
+ Free frame position in the playback buffer.
+ */
+ snd_pcm_uframes_t pos_out;
+
+ /**
+ Count processed bytes for playback.
+ This is modulo period size (to determine when a period is
+ finished).
+ */
+ unsigned bytes_out;
+
+ /**
+ Counter to create desired playback sample rate.
+ */
+ unsigned count_out;
+
+ /**
+ Playback period size in bytes
+ */
+ unsigned period_out;
+
+ /**
+ Processed frame position in the playback buffer.
+ The contents of the output ring buffer have been consumed by
+ the USB subsystem (i.e., sent to the USB device) up to this
+ position.
+ */
+ snd_pcm_uframes_t pos_out_done;
+
+ /**
+ Count processed bytes for capture.
+ This is modulo period size (to determine when a period is
+ finished).
+ */
+ unsigned bytes_in;
+
+ /**
+ Counter to create desired capture sample rate.
+ */
+ unsigned count_in;
+
+ /**
+ Capture period size in bytes
+ */
+ unsigned period_in;
+
+ /**
+ Processed frame position in the capture buffer.
+ The contents of the output ring buffer have been consumed by
+ the USB subsystem (i.e., sent to the USB device) up to this
+ position.
+ */
+ snd_pcm_uframes_t pos_in_done;
+
+ /**
+ Bit mask of active playback URBs.
+ */
+ unsigned long active_urb_out;
+
+ /**
+ Maximum size of USB packet.
+ */
+ int max_packet_size;
+
+ /**
+ USB endpoint for listening to audio data.
+ */
+ int ep_audio_read;
+
+ /**
+ USB endpoint for writing audio data.
+ */
+ int ep_audio_write;
+
+ /**
+ Bit mask of active capture URBs.
+ */
+ unsigned long active_urb_in;
+
+ /**
+ Bit mask of playback URBs currently being unlinked.
+ */
+ unsigned long unlink_urb_out;
+
+ /**
+ Bit mask of capture URBs currently being unlinked.
+ */
+ unsigned long unlink_urb_in;
+
+ /**
+ Spin lock to protect updates of the playback buffer positions (not
+ contents!)
+ */
+ spinlock_t lock_audio_out;
+
+ /**
+ Spin lock to protect updates of the capture buffer positions (not
+ contents!)
+ */
+ spinlock_t lock_audio_in;
+
+ /**
+ Spin lock to protect trigger.
+ */
+ spinlock_t lock_trigger;
+
+ /**
+ PCM playback volume (left and right).
+ */
+ int volume[2];
+
+ /**
+ Several status bits (see BIT_*).
+ */
+ unsigned long flags;
+};
+
+
+extern int line6_init_pcm(struct usb_line6 *line6,
+ struct line6_pcm_properties *properties);
+extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd);
+extern int snd_line6_prepare(struct snd_pcm_substream *substream);
+
+
+#endif
diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c
new file mode 100644
index 00000000000..acb06126a6a
--- /dev/null
+++ b/drivers/staging/line6/playback.c
@@ -0,0 +1,427 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/pcm_params.h>
+
+#include "audio.h"
+#include "pcm.h"
+#include "pod.h"
+#include "playback.h"
+
+
+/*
+ Software stereo volume control.
+*/
+static void change_volume(struct urb *urb_out, int volume[],
+ int bytes_per_frame)
+{
+ int chn = 0;
+
+ if (volume[0] == 256 && volume[1] == 256)
+ return; /* maximum volume - no change */
+
+ if (bytes_per_frame == 4) {
+ short *p, *buf_end;
+ p = (short *)urb_out->transfer_buffer;
+ buf_end = p + urb_out->transfer_buffer_length / sizeof(*p);
+
+ for (; p < buf_end; ++p) {
+ *p = (*p * volume[chn & 1]) >> 8;
+ ++chn;
+ }
+ } else if (bytes_per_frame == 6) {
+ unsigned char *p, *buf_end;
+ p = (unsigned char *)urb_out->transfer_buffer;
+ buf_end = p + urb_out->transfer_buffer_length;
+
+ for (; p < buf_end; p += 3) {
+ int val;
+ val = p[0] + (p[1] << 8) + ((signed char)p[2] << 16);
+ val = (val * volume[chn & 1]) >> 8;
+ p[0] = val;
+ p[1] = val >> 8;
+ p[2] = val >> 16;
+ ++chn;
+ }
+ }
+}
+
+/*
+ Find a free URB, prepare audio data, and submit URB.
+*/
+static int submit_audio_out_urb(struct snd_pcm_substream *substream)
+{
+ int index;
+ unsigned long flags;
+ int i, urb_size, urb_frames;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ const int bytes_per_frame = line6pcm->properties->bytes_per_frame;
+ const int frame_increment = line6pcm->properties->snd_line6_rates.rats[0].num_min;
+ const int frame_factor = line6pcm->properties->snd_line6_rates.rats[0].den * (USB_INTERVALS_PER_SECOND / LINE6_ISO_INTERVAL);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct urb *urb_out;
+
+ spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+ index = find_first_zero_bit(&line6pcm->active_urb_out, LINE6_ISO_BUFFERS);
+
+ if (index < 0 || index >= LINE6_ISO_BUFFERS) {
+ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+ dev_err(s2m(substream), "no free URB found\n");
+ return -EINVAL;
+ }
+
+ urb_out = line6pcm->urb_audio_out[index];
+ urb_size = 0;
+
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ /* compute frame size for given sampling rate */
+ int n, fs;
+ struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
+ line6pcm->count_out += frame_increment;
+ n = line6pcm->count_out / frame_factor;
+ line6pcm->count_out -= n * frame_factor;
+ fs = n * bytes_per_frame;
+ fout->offset = urb_size;
+ fout->length = fs;
+ urb_size += fs;
+ }
+
+ urb_frames = urb_size / bytes_per_frame;
+
+ if (test_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags)) {
+ urb_out->transfer_buffer = line6pcm->wrap_out;
+ memset(line6pcm->wrap_out, 0, urb_size);
+ } else {
+ if (line6pcm->pos_out + urb_frames > runtime->buffer_size) {
+ /*
+ The transferred area goes over buffer boundary,
+ copy the data to the temp buffer.
+ */
+ int len;
+ len = runtime->buffer_size - line6pcm->pos_out;
+ urb_out->transfer_buffer = line6pcm->wrap_out;
+
+ if (len > 0) {
+ memcpy(line6pcm->wrap_out, runtime->dma_area + line6pcm->pos_out * bytes_per_frame, len * bytes_per_frame);
+ memcpy(line6pcm->wrap_out + len * bytes_per_frame, runtime->dma_area, (urb_frames - len) * bytes_per_frame);
+ } else
+ dev_err(s2m(substream), "driver bug: len = %d\n", len); /* this is somewhat paranoid */
+ } else {
+ /* set the buffer pointer */
+ urb_out->transfer_buffer = runtime->dma_area + line6pcm->pos_out * bytes_per_frame;
+ }
+ }
+
+ if ((line6pcm->pos_out += urb_frames) >= runtime->buffer_size)
+ line6pcm->pos_out -= runtime->buffer_size;
+
+ urb_out->transfer_buffer_length = urb_size;
+ urb_out->context = substream;
+ change_volume(urb_out, line6pcm->volume, bytes_per_frame);
+
+#if DO_DUMP_PCM_SEND
+ for (i = 0; i < LINE6_ISO_PACKETS; ++i) {
+ struct usb_iso_packet_descriptor *fout = &urb_out->iso_frame_desc[i];
+ line6_write_hexdump(line6pcm->line6, 'P', urb_out->transfer_buffer + fout->offset, fout->length);
+ }
+#endif
+
+ if (usb_submit_urb(urb_out, GFP_ATOMIC) == 0)
+ set_bit(index, &line6pcm->active_urb_out);
+ else
+ dev_err(s2m(substream), "URB out #%d submission failed\n", index);
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+ return 0;
+}
+
+/*
+ Submit all currently available playback URBs.
+*/
+static int submit_audio_out_all_urbs(struct snd_pcm_substream *substream)
+{
+ int ret, i;
+
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ ret = submit_audio_out_urb(substream);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Unlink all currently active playback URBs.
+*/
+static void unlink_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unsigned int i;
+
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_out)) {
+ if (!test_and_set_bit(i, &line6pcm->unlink_urb_out)) {
+ struct urb *u = line6pcm->urb_audio_out[i];
+ usb_unlink_urb(u);
+ }
+ }
+ }
+}
+
+/*
+ Wait until unlinking of all currently active playback URBs has been finished.
+*/
+static void wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int timeout = HZ;
+ unsigned int i;
+ int alive;
+
+ do {
+ alive = 0;
+ for (i = LINE6_ISO_BUFFERS; i--;) {
+ if (test_bit(i, &line6pcm->active_urb_out))
+ alive++;
+ }
+ if (!alive)
+ break;
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(1);
+ } while (--timeout > 0);
+ if (alive)
+ snd_printk(KERN_ERR "timeout: still %d active urbs..\n", alive);
+
+ line6pcm->active_urb_out = 0;
+ line6pcm->unlink_urb_out = 0;
+}
+
+/*
+ Unlink all currently active playback URBs, and wait for finishing.
+*/
+void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ unlink_audio_out_urbs(line6pcm);
+ wait_clear_audio_out_urbs(line6pcm);
+}
+
+/*
+ Callback for completed playback URB.
+*/
+static void audio_out_callback(struct urb *urb)
+{
+ int i, index, length = 0, shutdown = 0;
+ unsigned long flags;
+
+ struct snd_pcm_substream *substream = (struct snd_pcm_substream *)urb->context;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+
+ /* find index of URB */
+ for (index = LINE6_ISO_BUFFERS; index--;)
+ if (urb == line6pcm->urb_audio_out[index])
+ break;
+
+ if (index < 0)
+ return; /* URB has been unlinked asynchronously */
+
+ for (i = LINE6_ISO_PACKETS; i--;)
+ length += urb->iso_frame_desc[i].length;
+
+ spin_lock_irqsave(&line6pcm->lock_audio_out, flags);
+ line6pcm->pos_out_done += length / line6pcm->properties->bytes_per_frame;
+
+ if (line6pcm->pos_out_done >= runtime->buffer_size)
+ line6pcm->pos_out_done -= runtime->buffer_size;
+
+ clear_bit(index, &line6pcm->active_urb_out);
+
+ for (i = LINE6_ISO_PACKETS; i--;)
+ if (urb->iso_frame_desc[i].status == -ESHUTDOWN) {
+ shutdown = 1;
+ break;
+ }
+
+ if (test_bit(index, &line6pcm->unlink_urb_out))
+ shutdown = 1;
+
+ spin_unlock_irqrestore(&line6pcm->lock_audio_out, flags);
+
+ if (!shutdown) {
+ submit_audio_out_urb(substream);
+
+ if ((line6pcm->bytes_out += length) >= line6pcm->period_out) {
+ line6pcm->bytes_out -= line6pcm->period_out;
+ snd_pcm_period_elapsed(substream);
+ }
+ }
+}
+
+/* open playback callback */
+static int snd_line6_playback_open(struct snd_pcm_substream *substream)
+{
+ int err;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ err = snd_pcm_hw_constraint_ratdens(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
+ (&line6pcm->properties->snd_line6_rates));
+ if (err < 0)
+ return err;
+
+ runtime->hw = line6pcm->properties->snd_line6_playback_hw;
+ return 0;
+}
+
+/* close playback callback */
+static int snd_line6_playback_close(struct snd_pcm_substream *substream)
+{
+ return 0;
+}
+
+/* hw_params playback callback */
+static int snd_line6_playback_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params)
+{
+ int ret;
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+
+ /* -- Florian Demski [FD] */
+ /* don't ask me why, but this fixes the bug on my machine */
+ if (line6pcm == NULL) {
+ if (substream->pcm == NULL)
+ return -ENOMEM;
+ if (substream->pcm->private_data == NULL)
+ return -ENOMEM;
+ substream->private_data = substream->pcm->private_data;
+ line6pcm = snd_pcm_substream_chip(substream);
+ }
+ /* -- [FD] end */
+
+ ret = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (ret < 0)
+ return ret;
+
+ line6pcm->period_out = params_period_bytes(hw_params);
+ line6pcm->wrap_out = kmalloc(2 * LINE6_ISO_PACKET_SIZE_MAX, GFP_KERNEL);
+
+ if (!line6pcm->wrap_out) {
+ dev_err(s2m(substream), "cannot malloc wrap_out\n");
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
+/* hw_free playback callback */
+static int snd_line6_playback_hw_free(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+
+ kfree(line6pcm->wrap_out);
+ line6pcm->wrap_out = NULL;
+
+ return snd_pcm_lib_free_pages(substream);
+}
+
+/* trigger playback callback */
+int snd_line6_playback_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ int err;
+ line6pcm->count_out = 0;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ if (!test_and_set_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags)) {
+ err = submit_audio_out_all_urbs(substream);
+
+ if (err < 0) {
+ clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags);
+ return err;
+ }
+ }
+
+ break;
+
+ case SNDRV_PCM_TRIGGER_STOP:
+ if (test_and_clear_bit(BIT_RUNNING_PLAYBACK, &line6pcm->flags))
+ unlink_audio_out_urbs(line6pcm);
+
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ set_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+ break;
+
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ clear_bit(BIT_PAUSE_PLAYBACK, &line6pcm->flags);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/* playback pointer callback */
+static snd_pcm_uframes_t
+snd_line6_playback_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_line6_pcm *line6pcm = snd_pcm_substream_chip(substream);
+ return line6pcm->pos_out_done;
+}
+
+/* playback operators */
+struct snd_pcm_ops snd_line6_playback_ops = {
+ .open = snd_line6_playback_open,
+ .close = snd_line6_playback_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = snd_line6_playback_hw_params,
+ .hw_free = snd_line6_playback_hw_free,
+ .prepare = snd_line6_prepare,
+ .trigger = snd_line6_trigger,
+ .pointer = snd_line6_playback_pointer,
+};
+
+int create_audio_out_urbs(struct snd_line6_pcm *line6pcm)
+{
+ int i;
+
+ /* create audio URBs and fill in constant values: */
+ for (i = 0; i < LINE6_ISO_BUFFERS; ++i) {
+ struct urb *urb;
+
+ /* URB for audio out: */
+ urb = line6pcm->urb_audio_out[i] = usb_alloc_urb(LINE6_ISO_PACKETS, GFP_KERNEL);
+
+ if (urb == NULL) {
+ dev_err(line6pcm->line6->ifcdev, "Out of memory\n");
+ return -ENOMEM;
+ }
+
+ urb->dev = line6pcm->line6->usbdev;
+ urb->pipe = usb_sndisocpipe(line6pcm->line6->usbdev, line6pcm->ep_audio_write & USB_ENDPOINT_NUMBER_MASK);
+ urb->transfer_flags = URB_ISO_ASAP;
+ urb->start_frame = -1;
+ urb->number_of_packets = LINE6_ISO_PACKETS;
+ urb->interval = LINE6_ISO_INTERVAL;
+ urb->error_count = 0;
+ urb->complete = audio_out_callback;
+ }
+
+ return 0;
+}
diff --git a/drivers/staging/line6/playback.h b/drivers/staging/line6/playback.h
new file mode 100644
index 00000000000..db1e48b3596
--- /dev/null
+++ b/drivers/staging/line6/playback.h
@@ -0,0 +1,30 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef PLAYBACK_H
+#define PLAYBACK_H
+
+
+#include "driver.h"
+
+#include <sound/pcm.h>
+
+
+extern struct snd_pcm_ops snd_line6_playback_ops;
+
+
+extern int create_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+extern int snd_line6_playback_trigger(struct snd_pcm_substream *substream,
+ int cmd);
+extern void unlink_wait_clear_audio_out_urbs(struct snd_line6_pcm *line6pcm);
+
+
+#endif
diff --git a/drivers/staging/line6/pod.c b/drivers/staging/line6/pod.c
new file mode 100644
index 00000000000..fa5caa245d8
--- /dev/null
+++ b/drivers/staging/line6/pod.c
@@ -0,0 +1,1151 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include "audio.h"
+#include "capture.h"
+#include "control.h"
+#include "playback.h"
+#include "pod.h"
+
+
+#define POD_SYSEX_CODE 3
+#define POD_BYTES_PER_FRAME 6 /* 24bit audio (stereo) */
+
+
+enum {
+ POD_SYSEX_CLIP = 0x0f,
+ POD_SYSEX_SAVE = 0x24,
+ POD_SYSEX_SYSTEM = 0x56,
+ POD_SYSEX_SYSTEMREQ = 0x57,
+ /* POD_SYSEX_UPDATE = 0x6c, */ /* software update! */
+ POD_SYSEX_STORE = 0x71,
+ POD_SYSEX_FINISH = 0x72,
+ POD_SYSEX_DUMPMEM = 0x73,
+ POD_SYSEX_DUMP = 0x74,
+ POD_SYSEX_DUMPREQ = 0x75
+ /* POD_SYSEX_DUMPMEM2 = 0x76 */ /* dumps entire internal memory of PODxt Pro */
+};
+
+enum {
+ POD_monitor_level = 0x04,
+ POD_routing = 0x05,
+ POD_tuner_mute = 0x13,
+ POD_tuner_freq = 0x15,
+ POD_tuner_note = 0x16,
+ POD_tuner_pitch = 0x17,
+ POD_system_invalid = 0x7fff
+};
+
+enum {
+ POD_DUMP_MEMORY = 2
+};
+
+enum {
+ POD_BUSY_READ,
+ POD_BUSY_WRITE,
+ POD_CHANNEL_DIRTY,
+ POD_SAVE_PRESSED,
+ POD_BUSY_MIDISEND
+};
+
+
+static struct snd_ratden pod_ratden = {
+ .num_min = 78125,
+ .num_max = 78125,
+ .num_step = 1,
+ .den = 2
+};
+
+static struct line6_pcm_properties pod_pcm_properties = {
+ .snd_line6_playback_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 39062,
+ .rate_max = 39063,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_capture_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S24_3LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 39062,
+ .rate_max = 39063,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = LINE6_ISO_PACKET_SIZE_MAX * POD_BYTES_PER_FRAME, /* at least one URB must fit into one period */
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_rates = {
+ .nrats = 1,
+ .rats = &pod_ratden
+ },
+ .bytes_per_frame = POD_BYTES_PER_FRAME
+};
+
+static const char pod_request_version[] = { 0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7 };
+static const char pod_request_channel[] = { 0xf0, 0x00, 0x01, 0x0c, 0x03, 0x75, 0xf7 };
+static const char pod_version_header[] = { 0xf2, 0x7e, 0x7f, 0x06, 0x02 };
+
+
+/*
+ Mark all parameters as dirty and notify waiting processes.
+*/
+static void pod_mark_batch_all_dirty(struct usb_line6_pod *pod)
+{
+ int i;
+
+ for (i = POD_CONTROL_SIZE; i--;)
+ set_bit(i, pod->param_dirty);
+}
+
+/*
+ Send an asynchronous request for the POD firmware version and device ID.
+*/
+static int pod_version_request_async(struct usb_line6_pod *pod)
+{
+ return line6_send_raw_message_async(&pod->line6, pod->buffer_versionreq, sizeof(pod_request_version));
+}
+
+static void pod_create_files_work(struct work_struct *work)
+{
+ struct usb_line6_pod *pod = container_of(work, struct usb_line6_pod, create_files_work);
+
+ pod_create_files(pod->firmware_version, pod->line6.properties->device_bit, pod->line6.ifcdev);
+}
+
+static void pod_startup_timeout(unsigned long arg)
+{
+ enum {
+ REQUEST_NONE,
+ REQUEST_DUMP,
+ REQUEST_VERSION
+ };
+
+ int request = REQUEST_NONE;
+ struct usb_line6_pod *pod = (struct usb_line6_pod *)arg;
+
+ if (pod->dumpreq.ok) {
+ if (!pod->versionreq_ok)
+ request = REQUEST_VERSION;
+ } else {
+ if (pod->versionreq_ok)
+ request = REQUEST_DUMP;
+ else if (pod->startup_count++ & 1)
+ request = REQUEST_DUMP;
+ else
+ request = REQUEST_VERSION;
+ }
+
+ switch (request) {
+ case REQUEST_DUMP:
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+ break;
+
+ case REQUEST_VERSION:
+ pod_version_request_async(pod);
+ break;
+
+ default:
+ return;
+ }
+
+ line6_startup_delayed(&pod->dumpreq, 1, pod_startup_timeout, pod);
+}
+
+static char *pod_alloc_sysex_buffer(struct usb_line6_pod *pod, int code, int size)
+{
+ return line6_alloc_sysex_buffer(&pod->line6, POD_SYSEX_CODE, code, size);
+}
+
+/*
+ Send channel dump data to the PODxt Pro.
+*/
+static void pod_dump(struct usb_line6_pod *pod, const unsigned char *data)
+{
+ int size = 1 + sizeof(pod->prog_data);
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMP, size);
+ if (!sysex)
+ return;
+ /* Don't know what this is good for, but PODxt Pro transmits it, so we
+ * also do... */
+ sysex[SYSEX_DATA_OFS] = 5;
+ memcpy(sysex + SYSEX_DATA_OFS + 1, data, sizeof(pod->prog_data));
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ memcpy(&pod->prog_data, data, sizeof(pod->prog_data));
+ pod_mark_batch_all_dirty(pod);
+ kfree(sysex);
+}
+
+/*
+ Store parameter value in driver memory and mark it as dirty.
+*/
+static void pod_store_parameter(struct usb_line6_pod *pod, int param, int value)
+{
+ pod->prog_data.control[param] = value;
+ set_bit(param, pod->param_dirty);
+ pod->dirty = 1;
+}
+
+/*
+ Handle SAVE button
+*/
+static void pod_save_button_pressed(struct usb_line6_pod *pod, int type, int index)
+{
+ pod->dirty = 0;
+ set_bit(POD_SAVE_PRESSED, &pod->atomic_flags);
+}
+
+/*
+ Process a completely received message.
+*/
+void pod_process_message(struct usb_line6_pod *pod)
+{
+ const unsigned char *buf = pod->line6.buffer_message;
+
+ /* filter messages by type */
+ switch (buf[0] & 0xf0) {
+ case LINE6_PARAM_CHANGE:
+ case LINE6_PROGRAM_CHANGE:
+ case LINE6_SYSEX_BEGIN:
+ break; /* handle these further down */
+
+ default:
+ return; /* ignore all others */
+ }
+
+ /* process all remaining messages */
+ switch (buf[0]) {
+ case LINE6_PARAM_CHANGE | LINE6_CHANNEL_DEVICE:
+ pod_store_parameter(pod, buf[1], buf[2]);
+ /* intentionally no break here! */
+
+ case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
+ if ((buf[1] == POD_amp_model_setup) ||
+ (buf[1] == POD_effect_setup))
+ /* these also affect other settings */
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+
+ break;
+
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
+ pod->channel_num = buf[1];
+ pod->dirty = 0;
+ set_bit(POD_CHANNEL_DIRTY, &pod->atomic_flags);
+ line6_dump_request_async(&pod->dumpreq, &pod->line6, 0);
+ break;
+
+ case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_DEVICE:
+ case LINE6_SYSEX_BEGIN | LINE6_CHANNEL_UNKNOWN:
+ if (memcmp(buf + 1, line6_midi_id, sizeof(line6_midi_id)) == 0) {
+ switch (buf[5]) {
+ case POD_SYSEX_DUMP:
+ if (pod->line6.message_length == sizeof(pod->prog_data) + 7) {
+ switch (pod->dumpreq.in_progress) {
+ case LINE6_DUMP_CURRENT:
+ memcpy(&pod->prog_data, buf + 7, sizeof(pod->prog_data));
+ pod_mark_batch_all_dirty(pod);
+ pod->dumpreq.ok = 1;
+ break;
+
+ case POD_DUMP_MEMORY:
+ memcpy(&pod->prog_data_buf, buf + 7, sizeof(pod->prog_data_buf));
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown dump code %02X\n", pod->dumpreq.in_progress));
+ }
+
+ line6_dump_finished(&pod->dumpreq);
+ } else
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "wrong size of channel dump message (%d instead of %d)\n",
+ pod->line6.message_length, (int)sizeof(pod->prog_data) + 7));
+
+ break;
+
+ case POD_SYSEX_SYSTEM: {
+ short value = ((int)buf[7] << 12) | ((int)buf[8] << 8) | ((int)buf[9] << 4) | (int)buf[10];
+
+#define PROCESS_SYSTEM_PARAM(x) \
+ case POD_ ## x: \
+ pod->x.value = value; \
+ wake_up_interruptible(&pod->x.wait); \
+ break;
+
+ switch (buf[6]) {
+ PROCESS_SYSTEM_PARAM(monitor_level);
+ PROCESS_SYSTEM_PARAM(routing);
+ PROCESS_SYSTEM_PARAM(tuner_mute);
+ PROCESS_SYSTEM_PARAM(tuner_freq);
+ PROCESS_SYSTEM_PARAM(tuner_note);
+ PROCESS_SYSTEM_PARAM(tuner_pitch);
+
+#undef PROCESS_SYSTEM_PARAM
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown tuner/system response %02X\n", buf[6]));
+ }
+
+ break;
+ }
+
+ case POD_SYSEX_FINISH:
+ /* do we need to respond to this? */
+ break;
+
+ case POD_SYSEX_SAVE:
+ pod_save_button_pressed(pod, buf[6], buf[7]);
+ break;
+
+ case POD_SYSEX_CLIP:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "audio clipped\n"));
+ pod->clipping.value = 1;
+ wake_up_interruptible(&pod->clipping.wait);
+ break;
+
+ case POD_SYSEX_STORE:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "message %02X not yet implemented\n", buf[5]));
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex message %02X\n", buf[5]));
+ }
+ } else if (memcmp(buf, pod_version_header, sizeof(pod_version_header)) == 0) {
+ if (pod->versionreq_ok == 0) {
+ pod->firmware_version = buf[13] * 100 + buf[14] * 10 + buf[15];
+ pod->device_id = ((int)buf[8] << 16) | ((int)buf[9] << 8) | (int)buf[10];
+ pod->versionreq_ok = 1;
+
+ /* Now we know the firmware version, so we schedule a bottom half
+ handler to create the special files: */
+ INIT_WORK(&pod->create_files_work, pod_create_files_work);
+ queue_work(line6_workqueue, &pod->create_files_work);
+ } else
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "multiple firmware version message\n"));
+ } else
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "unknown sysex header\n"));
+
+ break;
+
+ case LINE6_SYSEX_END:
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(pod->line6.ifcdev, "POD: unknown message %02X\n", buf[0]));
+ }
+}
+
+/*
+ Detect some cases that require a channel dump after sending a command to the
+ device. Important notes:
+ *) The actual dump request can not be sent here since we are not allowed to
+ wait for the completion of the first message in this context, and sending
+ the dump request before completion of the previous message leaves the POD
+ in an undefined state. The dump request will be sent when the echoed
+ commands are received.
+ *) This method fails if a param change message is "chopped" after the first
+ byte.
+*/
+void pod_midi_postprocess(struct usb_line6_pod *pod, unsigned char *data, int length)
+{
+ int i;
+
+ if (!pod->midi_postprocess)
+ return;
+
+ for (i = 0; i < length; ++i) {
+ if (data[i] == (LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST)) {
+ line6_invalidate_current(&pod->dumpreq);
+ break;
+ } else if ((data[i] == (LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST)) && (i < length - 1))
+ if ((data[i + 1] == POD_amp_model_setup) || (data[i + 1] == POD_effect_setup)) {
+ line6_invalidate_current(&pod->dumpreq);
+ break;
+ }
+ }
+}
+
+/*
+ Send channel number (i.e., switch to a different sound).
+*/
+static void pod_send_channel(struct usb_line6_pod *pod, int value)
+{
+ line6_invalidate_current(&pod->dumpreq);
+
+ if (line6_send_program(&pod->line6, value) == 0)
+ pod->channel_num = value;
+ else
+ line6_dump_finished(&pod->dumpreq);
+}
+
+/*
+ Transmit PODxt Pro control parameter.
+*/
+void pod_transmit_parameter(struct usb_line6_pod *pod, int param, int value)
+{
+ if (line6_transmit_parameter(&pod->line6, param, value) == 0)
+ pod_store_parameter(pod, param, value);
+
+ if ((param == POD_amp_model_setup) || (param == POD_effect_setup)) /* these also affect other settings */
+ line6_invalidate_current(&pod->dumpreq);
+}
+
+/*
+ Resolve value to memory location.
+*/
+static void pod_resolve(const char *buf, short block0, short block1, unsigned char *location)
+{
+ int value = simple_strtoul(buf, NULL, 10);
+ short block = (value < 0x40) ? block0 : block1;
+ value &= 0x3f;
+ location[0] = block >> 7;
+ location[1] = value | (block & 0x7f);
+}
+
+/*
+ Send command to store channel/effects setup/amp setup to PODxt Pro.
+*/
+static ssize_t pod_send_store_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+ int size = 3 + sizeof(pod->prog_data_buf);
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_STORE, size);
+ if (!sysex)
+ return 0;
+
+ sysex[SYSEX_DATA_OFS] = 5; /* see pod_dump() */
+ pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS + 1);
+ memcpy(sysex + SYSEX_DATA_OFS + 3, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
+
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+ /* needs some delay here on AMD64 platform */
+ return count;
+}
+
+/*
+ Send command to retrieve channel/effects setup/amp setup to PODxt Pro.
+*/
+static ssize_t pod_send_retrieve_command(struct device *dev, const char *buf, size_t count, short block0, short block1)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int size = 4;
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_DUMPMEM, size);
+
+ if (!sysex)
+ return 0;
+
+ pod_resolve(buf, block0, block1, sysex + SYSEX_DATA_OFS);
+ sysex[SYSEX_DATA_OFS + 2] = 0;
+ sysex[SYSEX_DATA_OFS + 3] = 0;
+ line6_dump_started(&pod->dumpreq, POD_DUMP_MEMORY);
+
+ if (line6_send_sysex_message(&pod->line6, sysex, size) < size)
+ line6_dump_finished(&pod->dumpreq);
+
+ kfree(sysex);
+ /* needs some delay here on AMD64 platform */
+ return count;
+}
+
+/*
+ Generic get name function.
+*/
+static ssize_t get_name_generic(struct usb_line6_pod *pod, const char *str, char *buf)
+{
+ int length = 0;
+ const char *p1;
+ char *p2;
+ char *last_non_space = buf;
+
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+
+ for (p1 = str, p2 = buf; *p1; ++p1, ++p2) {
+ *p2 = *p1;
+ if (*p2 != ' ')
+ last_non_space = p2;
+ if (++length == POD_NAME_LENGTH)
+ break;
+ }
+
+ *(last_non_space + 1) = '\n';
+ return last_non_space - buf + 2;
+}
+
+/*
+ "read" request on "channel" special file.
+*/
+static ssize_t pod_get_channel(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->channel_num);
+}
+
+/*
+ "write" request on "channel" special file.
+*/
+static ssize_t pod_set_channel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ pod_send_channel(pod, value);
+ return count;
+}
+
+/*
+ "read" request on "name" special file.
+*/
+static ssize_t pod_get_name(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return get_name_generic(pod, pod->prog_data.header + POD_NAME_OFFSET, buf);
+}
+
+/*
+ "read" request on "name" special file.
+*/
+static ssize_t pod_get_name_buf(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return get_name_generic(pod, pod->prog_data_buf.header + POD_NAME_OFFSET, buf);
+}
+
+/*
+ "read" request on "dump" special file.
+*/
+static ssize_t pod_get_dump(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ memcpy(buf, &pod->prog_data, sizeof(pod->prog_data));
+ return sizeof(pod->prog_data);
+}
+
+/*
+ "write" request on "dump" special file.
+*/
+static ssize_t pod_set_dump(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+ if (count != sizeof(pod->prog_data)) {
+ dev_err(pod->line6.ifcdev,
+ "data block must be exactly %d bytes\n",
+ (int)sizeof(pod->prog_data));
+ return -EINVAL;
+ }
+
+ pod_dump(pod, buf);
+ return sizeof(pod->prog_data);
+}
+
+/*
+ Request system parameter.
+ @param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_get_system_param(struct usb_line6_pod *pod, char *buf, int code, struct ValueWait *param, int tuner, int sign)
+{
+ char *sysex;
+ int value;
+ static const int size = 1;
+ int retval = 0;
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+ return -ENODEV;
+
+ /* send value request to tuner: */
+ param->value = POD_system_invalid;
+ sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEMREQ, size);
+ if (!sysex)
+ return 0;
+ sysex[SYSEX_DATA_OFS] = code;
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+
+ /* wait for tuner to respond: */
+ add_wait_queue(&param->wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (param->value == POD_system_invalid) {
+ if (signal_pending(current)) {
+ retval = -ERESTARTSYS;
+ break;
+ } else
+ schedule();
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&param->wait, &wait);
+
+ if (retval < 0)
+ return retval;
+
+ value = sign ? (int)(signed short)param->value : (int)(unsigned short)param->value;
+ return sprintf(buf, "%d\n", value);
+}
+
+/*
+ Send system parameter.
+ @param tuner non-zero, if code refers to a tuner parameter
+*/
+static ssize_t pod_set_system_param(struct usb_line6_pod *pod, const char *buf,
+ int count, int code, unsigned short mask,
+ int tuner)
+{
+ char *sysex;
+ static const int size = 5;
+ unsigned short value;
+
+ if (((pod->prog_data.control[POD_tuner] & 0x40) == 0) && tuner)
+ return -EINVAL;
+
+ /* send value to tuner: */
+ sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_SYSTEM, size);
+ if (!sysex)
+ return 0;
+ value = simple_strtoul(buf, NULL, 10) & mask;
+ sysex[SYSEX_DATA_OFS] = code;
+ sysex[SYSEX_DATA_OFS + 1] = (value >> 12) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 2] = (value >> 8) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 3] = (value >> 4) & 0x0f;
+ sysex[SYSEX_DATA_OFS + 4] = (value ) & 0x0f;
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+ return count;
+}
+
+/*
+ "read" request on "dump_buf" special file.
+*/
+static ssize_t pod_get_dump_buf(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int retval = line6_wait_dump(&pod->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ memcpy(buf, &pod->prog_data_buf, sizeof(pod->prog_data_buf));
+ return sizeof(pod->prog_data_buf);
+}
+
+/*
+ "write" request on "dump_buf" special file.
+*/
+static ssize_t pod_set_dump_buf(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+
+ if (count != sizeof(pod->prog_data)) {
+ dev_err(pod->line6.ifcdev,
+ "data block must be exactly %d bytes\n",
+ (int)sizeof(pod->prog_data));
+ return -EINVAL;
+ }
+
+ memcpy(&pod->prog_data_buf, buf, sizeof(pod->prog_data));
+ return sizeof(pod->prog_data);
+}
+
+/*
+ "write" request on "finish" special file.
+*/
+static ssize_t pod_set_finish(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int size = 0;
+ char *sysex = pod_alloc_sysex_buffer(pod, POD_SYSEX_FINISH, size);
+ if (!sysex)
+ return 0;
+ line6_send_sysex_message(&pod->line6, sysex, size);
+ kfree(sysex);
+ return count;
+}
+
+/*
+ "write" request on "store_channel" special file.
+*/
+static ssize_t pod_set_store_channel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_store_command(dev, buf, count, 0x0000, 0x00c0);
+}
+
+/*
+ "write" request on "store_effects_setup" special file.
+*/
+static ssize_t pod_set_store_effects_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_store_command(dev, buf, count, 0x0080, 0x0080);
+}
+
+/*
+ "write" request on "store_amp_setup" special file.
+*/
+static ssize_t pod_set_store_amp_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_store_command(dev, buf, count, 0x0040, 0x0100);
+}
+
+/*
+ "write" request on "retrieve_channel" special file.
+*/
+static ssize_t pod_set_retrieve_channel(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_retrieve_command(dev, buf, count, 0x0000, 0x00c0);
+}
+
+/*
+ "write" request on "retrieve_effects_setup" special file.
+*/
+static ssize_t pod_set_retrieve_effects_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_retrieve_command(dev, buf, count, 0x0080, 0x0080);
+}
+
+/*
+ "write" request on "retrieve_amp_setup" special file.
+*/
+static ssize_t pod_set_retrieve_amp_setup(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ return pod_send_retrieve_command(dev, buf, count, 0x0040, 0x0100);
+}
+
+/*
+ "read" request on "dirty" special file.
+*/
+static ssize_t pod_get_dirty(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ buf[0] = pod->dirty ? '1' : '0';
+ buf[1] = '\n';
+ return 2;
+}
+
+/*
+ "read" request on "midi_postprocess" special file.
+*/
+static ssize_t pod_get_midi_postprocess(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->midi_postprocess);
+}
+
+/*
+ "write" request on "midi_postprocess" special file.
+*/
+static ssize_t pod_set_midi_postprocess(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int value = simple_strtoul(buf, NULL, 10);
+ pod->midi_postprocess = value ? 1 : 0;
+ return count;
+}
+
+/*
+ "read" request on "serial_number" special file.
+*/
+static ssize_t pod_get_serial_number(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->serial_number);
+}
+
+/*
+ "read" request on "firmware_version" special file.
+*/
+static ssize_t pod_get_firmware_version(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d.%02d\n", pod->firmware_version / 100,
+ pod->firmware_version % 100);
+}
+
+/*
+ "read" request on "device_id" special file.
+*/
+static ssize_t pod_get_device_id(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ return sprintf(buf, "%d\n", pod->device_id);
+}
+
+/*
+ "read" request on "clip" special file.
+*/
+static ssize_t pod_wait_for_clip(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ int err = 0;
+ DECLARE_WAITQUEUE(wait, current);
+ pod->clipping.value = 0;
+ add_wait_queue(&pod->clipping.wait, &wait);
+ current->state = TASK_INTERRUPTIBLE;
+
+ while (pod->clipping.value == 0) {
+ if (signal_pending(current)) {
+ err = -ERESTARTSYS;
+ break;
+ } else
+ schedule();
+ }
+
+ current->state = TASK_RUNNING;
+ remove_wait_queue(&pod->clipping.wait, &wait);
+ return err;
+}
+
+#define POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+static ssize_t pod_get_ ## code(struct device *dev, \
+ struct device_attribute *attr, char *buf) \
+{ \
+ struct usb_interface *interface = to_usb_interface(dev); \
+ struct usb_line6_pod *pod = usb_get_intfdata(interface); \
+ return pod_get_system_param(pod, buf, POD_ ## code, &pod->code, \
+ tuner, sign); \
+}
+
+#define POD_GET_SET_SYSTEM_PARAM(code, mask, tuner, sign) \
+POD_GET_SYSTEM_PARAM(code, tuner, sign) \
+static ssize_t pod_set_ ## code(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+{ \
+ struct usb_interface *interface = to_usb_interface(dev); \
+ struct usb_line6_pod *pod = usb_get_intfdata(interface); \
+ return pod_set_system_param(pod, buf, count, POD_ ## code, mask, \
+ tuner); \
+}
+
+POD_GET_SET_SYSTEM_PARAM(monitor_level, 0xffff, 0, 0);
+POD_GET_SET_SYSTEM_PARAM(routing, 0x0003, 0, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_mute, 0x0001, 1, 0);
+POD_GET_SET_SYSTEM_PARAM(tuner_freq, 0xffff, 1, 0);
+POD_GET_SYSTEM_PARAM(tuner_note, 1, 1);
+POD_GET_SYSTEM_PARAM(tuner_pitch, 1, 1);
+
+#undef GET_SET_SYSTEM_PARAM
+#undef GET_SYSTEM_PARAM
+
+/* POD special files: */
+static DEVICE_ATTR(channel, S_IWUGO | S_IRUGO, pod_get_channel, pod_set_channel);
+static DEVICE_ATTR(clip, S_IRUGO, pod_wait_for_clip, line6_nop_write);
+static DEVICE_ATTR(device_id, S_IRUGO, pod_get_device_id, line6_nop_write);
+static DEVICE_ATTR(dirty, S_IRUGO, pod_get_dirty, line6_nop_write);
+static DEVICE_ATTR(dump, S_IWUGO | S_IRUGO, pod_get_dump, pod_set_dump);
+static DEVICE_ATTR(dump_buf, S_IWUGO | S_IRUGO, pod_get_dump_buf, pod_set_dump_buf);
+static DEVICE_ATTR(finish, S_IWUGO, line6_nop_read, pod_set_finish);
+static DEVICE_ATTR(firmware_version, S_IRUGO, pod_get_firmware_version, line6_nop_write);
+static DEVICE_ATTR(midi_postprocess, S_IWUGO | S_IRUGO, pod_get_midi_postprocess, pod_set_midi_postprocess);
+static DEVICE_ATTR(monitor_level, S_IWUGO | S_IRUGO, pod_get_monitor_level, pod_set_monitor_level);
+static DEVICE_ATTR(name, S_IRUGO, pod_get_name, line6_nop_write);
+static DEVICE_ATTR(name_buf, S_IRUGO, pod_get_name_buf, line6_nop_write);
+static DEVICE_ATTR(retrieve_amp_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_amp_setup);
+static DEVICE_ATTR(retrieve_channel, S_IWUGO, line6_nop_read, pod_set_retrieve_channel);
+static DEVICE_ATTR(retrieve_effects_setup, S_IWUGO, line6_nop_read, pod_set_retrieve_effects_setup);
+static DEVICE_ATTR(routing, S_IWUGO | S_IRUGO, pod_get_routing, pod_set_routing);
+static DEVICE_ATTR(serial_number, S_IRUGO, pod_get_serial_number, line6_nop_write);
+static DEVICE_ATTR(store_amp_setup, S_IWUGO, line6_nop_read, pod_set_store_amp_setup);
+static DEVICE_ATTR(store_channel, S_IWUGO, line6_nop_read, pod_set_store_channel);
+static DEVICE_ATTR(store_effects_setup, S_IWUGO, line6_nop_read, pod_set_store_effects_setup);
+static DEVICE_ATTR(tuner_freq, S_IWUGO | S_IRUGO, pod_get_tuner_freq, pod_set_tuner_freq);
+static DEVICE_ATTR(tuner_mute, S_IWUGO | S_IRUGO, pod_get_tuner_mute, pod_set_tuner_mute);
+static DEVICE_ATTR(tuner_note, S_IRUGO, pod_get_tuner_note, line6_nop_write);
+static DEVICE_ATTR(tuner_pitch, S_IRUGO, pod_get_tuner_pitch, line6_nop_write);
+
+#if CREATE_RAW_FILE
+static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+#endif
+
+/*
+ POD destructor.
+*/
+static void pod_destruct(struct usb_interface *interface)
+{
+ struct usb_line6_pod *pod = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (pod == NULL)
+ return;
+ line6 = &pod->line6;
+ if (line6 == NULL)
+ return;
+ line6_cleanup_audio(line6);
+
+ /* free dump request data: */
+ line6_dumpreq_destruct(&pod->dumpreq);
+
+ kfree(pod->buffer_versionreq);
+}
+
+/*
+ Create sysfs entries.
+*/
+static int pod_create_files2(struct device *dev)
+{
+ int err;
+
+ CHECK_RETURN(device_create_file(dev, &dev_attr_channel));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_clip));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_device_id));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dirty));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dump_buf));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_finish));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_firmware_version));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_midi_postprocess));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_monitor_level));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_name));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_name_buf));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_amp_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_channel));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_retrieve_effects_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_routing));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_serial_number));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_store_amp_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_store_channel));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_store_effects_setup));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_freq));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_mute));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_note));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tuner_pitch));
+
+#if CREATE_RAW_FILE
+ CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
+#endif
+
+ return 0;
+}
+
+/*
+ Init POD device.
+*/
+int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod)
+{
+ int err;
+ struct usb_line6 *line6 = &pod->line6;
+
+ if ((interface == NULL) || (pod == NULL))
+ return -ENODEV;
+
+ pod->channel_num = 255;
+
+ /* initialize wait queues: */
+ init_waitqueue_head(&pod->monitor_level.wait);
+ init_waitqueue_head(&pod->routing.wait);
+ init_waitqueue_head(&pod->tuner_mute.wait);
+ init_waitqueue_head(&pod->tuner_freq.wait);
+ init_waitqueue_head(&pod->tuner_note.wait);
+ init_waitqueue_head(&pod->tuner_pitch.wait);
+ init_waitqueue_head(&pod->clipping.wait);
+
+ memset(pod->param_dirty, 0xff, sizeof(pod->param_dirty));
+
+ /* initialize USB buffers: */
+ err = line6_dumpreq_init(&pod->dumpreq, pod_request_channel,
+ sizeof(pod_request_channel));
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ pod_destruct(interface);
+ return -ENOMEM;
+ }
+
+ pod->buffer_versionreq = kmalloc(sizeof(pod_request_version),
+ GFP_KERNEL);
+
+ if (pod->buffer_versionreq == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ pod_destruct(interface);
+ return -ENOMEM;
+ }
+
+ memcpy(pod->buffer_versionreq, pod_request_version,
+ sizeof(pod_request_version));
+
+ /* create sysfs entries: */
+ err = pod_create_files2(&interface->dev);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* initialize audio system: */
+ err = line6_init_audio(line6);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* initialize MIDI subsystem: */
+ err = line6_init_midi(line6);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* initialize PCM subsystem: */
+ err = line6_init_pcm(line6, &pod_pcm_properties);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ /* register audio system: */
+ err = line6_register_audio(line6);
+ if (err < 0) {
+ pod_destruct(interface);
+ return err;
+ }
+
+ if (pod->line6.properties->capabilities & LINE6_BIT_CONTROL) {
+ /* query some data: */
+ line6_startup_delayed(&pod->dumpreq, POD_STARTUP_DELAY,
+ pod_startup_timeout, pod);
+ line6_read_serial_number(&pod->line6, &pod->serial_number);
+ }
+
+ return 0;
+}
+
+/*
+ POD device disconnected.
+*/
+void pod_disconnect(struct usb_interface *interface)
+{
+ struct usb_line6_pod *pod;
+
+ if (interface == NULL)
+ return;
+ pod = usb_get_intfdata(interface);
+
+ if (pod != NULL) {
+ struct snd_line6_pcm *line6pcm = pod->line6.line6pcm;
+ struct device *dev = &interface->dev;
+
+ if (line6pcm != NULL) {
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+ }
+
+ if (dev != NULL) {
+ /* remove sysfs entries: */
+ if (pod->versionreq_ok)
+ pod_remove_files(pod->firmware_version, pod->line6.properties->device_bit, dev);
+
+ device_remove_file(dev, &dev_attr_channel);
+ device_remove_file(dev, &dev_attr_clip);
+ device_remove_file(dev, &dev_attr_device_id);
+ device_remove_file(dev, &dev_attr_dirty);
+ device_remove_file(dev, &dev_attr_dump);
+ device_remove_file(dev, &dev_attr_dump_buf);
+ device_remove_file(dev, &dev_attr_finish);
+ device_remove_file(dev, &dev_attr_firmware_version);
+ device_remove_file(dev, &dev_attr_midi_postprocess);
+ device_remove_file(dev, &dev_attr_monitor_level);
+ device_remove_file(dev, &dev_attr_name);
+ device_remove_file(dev, &dev_attr_name_buf);
+ device_remove_file(dev, &dev_attr_retrieve_amp_setup);
+ device_remove_file(dev, &dev_attr_retrieve_channel);
+ device_remove_file(dev, &dev_attr_retrieve_effects_setup);
+ device_remove_file(dev, &dev_attr_routing);
+ device_remove_file(dev, &dev_attr_serial_number);
+ device_remove_file(dev, &dev_attr_store_amp_setup);
+ device_remove_file(dev, &dev_attr_store_channel);
+ device_remove_file(dev, &dev_attr_store_effects_setup);
+ device_remove_file(dev, &dev_attr_tuner_freq);
+ device_remove_file(dev, &dev_attr_tuner_mute);
+ device_remove_file(dev, &dev_attr_tuner_note);
+ device_remove_file(dev, &dev_attr_tuner_pitch);
+
+#if CREATE_RAW_FILE
+ device_remove_file(dev, &dev_attr_raw);
+#endif
+ }
+ }
+
+ pod_destruct(interface);
+}
diff --git a/drivers/staging/line6/pod.h b/drivers/staging/line6/pod.h
new file mode 100644
index 00000000000..7051ca61381
--- /dev/null
+++ b/drivers/staging/line6/pod.h
@@ -0,0 +1,204 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef POD_H
+#define POD_H
+
+
+#include "driver.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/workqueue.h>
+
+#include <sound/core.h>
+
+#include "dumprequest.h"
+
+
+/*
+ PODxt Live interfaces
+*/
+#define PODXTLIVE_INTERFACE_POD 0
+#define PODXTLIVE_INTERFACE_VARIAX 1
+
+/*
+ Locate name in binary program dump
+*/
+#define POD_NAME_OFFSET 0
+#define POD_NAME_LENGTH 16
+
+/*
+ Other constants
+*/
+#define POD_CONTROL_SIZE 0x80
+#define POD_BUFSIZE_DUMPREQ 7
+#define POD_STARTUP_DELAY 3
+
+
+/**
+ Data structure for values that need to be requested explicitly.
+ This is the case for system and tuner settings.
+*/
+struct ValueWait {
+ unsigned short value;
+ wait_queue_head_t wait;
+};
+
+/**
+ Binary PodXT Pro program dump
+*/
+struct pod_program {
+ /**
+ Header information (including program name).
+ */
+ unsigned char header[0x20];
+
+ /**
+ Program parameters.
+ */
+ unsigned char control[POD_CONTROL_SIZE];
+};
+
+struct usb_line6_pod {
+ /**
+ Generic Line6 USB data.
+ */
+ struct usb_line6 line6;
+
+ /**
+ Dump request structure.
+ */
+ struct line6_dump_request dumpreq;
+
+ /**
+ Current program number.
+ */
+ unsigned char channel_num;
+
+ /**
+ Current program settings.
+ */
+ struct pod_program prog_data;
+
+ /**
+ Buffer for data retrieved from or to be stored on PODxt Pro.
+ */
+ struct pod_program prog_data_buf;
+
+ /**
+ Buffer for requesting version number.
+ */
+ unsigned char *buffer_versionreq;
+
+ /**
+ Tuner mute mode.
+ */
+ struct ValueWait tuner_mute;
+
+ /**
+ Tuner base frequency (typically 440Hz).
+ */
+ struct ValueWait tuner_freq;
+
+ /**
+ Note received from tuner.
+ */
+ struct ValueWait tuner_note;
+
+ /**
+ Pitch value received from tuner.
+ */
+ struct ValueWait tuner_pitch;
+
+ /**
+ Instrument monitor level.
+ */
+ struct ValueWait monitor_level;
+
+ /**
+ Audio routing mode.
+ 0: send processed guitar
+ 1: send clean guitar
+ 2: send clean guitar re-amp playback
+ 3: send re-amp playback
+ */
+ struct ValueWait routing;
+
+ /**
+ Wait for audio clipping event.
+ */
+ struct ValueWait clipping;
+
+ /**
+ Bottom-half for creation of sysfs special files.
+ */
+ struct work_struct create_files_work;
+
+ /**
+ Dirty flags for access to parameter data.
+ */
+ unsigned long param_dirty[POD_CONTROL_SIZE / sizeof(unsigned long)];
+
+ /**
+ Some atomic flags.
+ */
+ unsigned long atomic_flags;
+
+ /**
+ Counter for startup process.
+ */
+ int startup_count;
+
+ /**
+ Serial number of device.
+ */
+ int serial_number;
+
+ /**
+ Firmware version (x 100).
+ */
+ int firmware_version;
+
+ /**
+ Device ID.
+ */
+ int device_id;
+
+ /**
+ Flag to indicate modification of current program settings.
+ */
+ char dirty;
+
+ /**
+ Flag if initial firmware version request has been successful.
+ */
+ char versionreq_ok;
+
+ /**
+ Flag to enable MIDI postprocessing.
+ */
+ char midi_postprocess;
+};
+
+
+extern void pod_disconnect(struct usb_interface *interface);
+extern int pod_init(struct usb_interface *interface, struct usb_line6_pod *pod);
+extern void pod_midi_postprocess(struct usb_line6_pod *pod,
+ unsigned char *data, int length);
+extern void pod_process_message(struct usb_line6_pod *pod);
+extern void pod_receive_parameter(struct usb_line6_pod *pod, int param);
+extern void pod_transmit_parameter(struct usb_line6_pod *pod, int param,
+ int value);
+
+
+#endif
diff --git a/drivers/staging/line6/revision.h b/drivers/staging/line6/revision.h
new file mode 100644
index 00000000000..b2a0a85efe6
--- /dev/null
+++ b/drivers/staging/line6/revision.h
@@ -0,0 +1,4 @@
+#ifndef DRIVER_REVISION
+/* current subversion revision */
+#define DRIVER_REVISION " (revision 529)"
+#endif
diff --git a/drivers/staging/line6/toneport.c b/drivers/staging/line6/toneport.c
new file mode 100644
index 00000000000..eaa1229002a
--- /dev/null
+++ b/drivers/staging/line6/toneport.c
@@ -0,0 +1,241 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ * Emil Myhrman (emil.myhrman@gmail.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include "audio.h"
+#include "capture.h"
+#include "playback.h"
+#include "toneport.h"
+
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2);
+
+
+static struct snd_ratden toneport_ratden = {
+ .num_min = 44100,
+ .num_max = 44100,
+ .num_step = 1,
+ .den = 1
+};
+
+static struct line6_pcm_properties toneport_pcm_properties = {
+ .snd_line6_playback_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 44100,
+ .rate_max = 44100,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = 180 * 4,
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_capture_hw = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_SYNC_START),
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .rates = SNDRV_PCM_RATE_KNOT,
+ .rate_min = 44100,
+ .rate_max = 44100,
+ .channels_min = 2,
+ .channels_max = 2,
+ .buffer_bytes_max = 60000,
+ .period_bytes_min = 188 * 4,
+ .period_bytes_max = 8192,
+ .periods_min = 1,
+ .periods_max = 1024
+ },
+ .snd_line6_rates = {
+ .nrats = 1,
+ .rats = &toneport_ratden
+ },
+ .bytes_per_frame = 4
+};
+
+/*
+ For the led on Guitarport.
+ Brightness goes from 0x00 to 0x26. Set a value above this to have led
+ blink.
+ (void cmd_0x02(byte red, byte green)
+*/
+static int led_red = 0x00;
+static int led_green = 0x26;
+
+static void toneport_update_led(struct device *dev)
+{
+ struct usb_interface *interface = to_usb_interface(dev);
+ struct usb_line6_toneport *tp = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (!tp)
+ return;
+
+ line6 = &tp->line6;
+ if (line6)
+ toneport_send_cmd(line6->usbdev, (led_red << 8) | 0x0002,
+ led_green);
+}
+
+static ssize_t toneport_set_led_red(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ char *c;
+ led_red = simple_strtol(buf, &c, 10);
+ toneport_update_led(dev);
+ return count;
+}
+
+static ssize_t toneport_set_led_green(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ char *c;
+ led_green = simple_strtol(buf, &c, 10);
+ toneport_update_led(dev);
+ return count;
+}
+
+static DEVICE_ATTR(led_red, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_red);
+static DEVICE_ATTR(led_green, S_IWUGO | S_IRUGO, line6_nop_read, toneport_set_led_green);
+
+
+static int toneport_send_cmd(struct usb_device *usbdev, int cmd1, int cmd2)
+{
+ int ret;
+
+ ret = usb_control_msg(usbdev, usb_sndctrlpipe(usbdev, 0), 0x67,
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
+ cmd1, cmd2, NULL, 0, LINE6_TIMEOUT * HZ);
+
+ if (ret < 0) {
+ err("send failed (error %d)\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/*
+ Toneport destructor.
+*/
+static void toneport_destruct(struct usb_interface *interface)
+{
+ struct usb_line6_toneport *toneport = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (toneport == NULL)
+ return;
+ line6 = &toneport->line6;
+ if (line6 == NULL)
+ return;
+ line6_cleanup_audio(line6);
+}
+
+/*
+ Init Toneport device.
+*/
+int toneport_init(struct usb_interface *interface,
+ struct usb_line6_toneport *toneport)
+{
+ int err, ticks;
+ struct usb_line6 *line6 = &toneport->line6;
+ struct usb_device *usbdev;
+
+ if ((interface == NULL) || (toneport == NULL))
+ return -ENODEV;
+
+ /* initialize audio system: */
+ err = line6_init_audio(line6);
+ if (err < 0) {
+ toneport_destruct(interface);
+ return err;
+ }
+
+ /* initialize PCM subsystem: */
+ err = line6_init_pcm(line6, &toneport_pcm_properties);
+ if (err < 0) {
+ toneport_destruct(interface);
+ return err;
+ }
+
+ /* register audio system: */
+ err = line6_register_audio(line6);
+ if (err < 0) {
+ toneport_destruct(interface);
+ return err;
+ }
+
+ usbdev = line6->usbdev;
+ line6_read_serial_number(line6, &toneport->serial_number);
+ line6_read_data(line6, 0x80c2, &toneport->firmware_version, 1);
+
+ /* sync time on device with host: */
+ ticks = (int)get_seconds();
+ line6_write_data(line6, 0x80c6, &ticks, 4);
+
+ /*
+ seems to work without the first two...
+ */
+ /* toneport_send_cmd(usbdev, 0x0201, 0x0002); */
+ /* toneport_send_cmd(usbdev, 0x0801, 0x0000); */
+ /* only one that works for me; on GP, TP might be different? */
+ toneport_send_cmd(usbdev, 0x0301, 0x0000);
+
+ if (usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+ CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_red));
+ CHECK_RETURN(device_create_file(&interface->dev, &dev_attr_led_green));
+ toneport_update_led(&usbdev->dev);
+ }
+
+ return 0;
+}
+
+/*
+ Toneport device disconnected.
+*/
+void toneport_disconnect(struct usb_interface *interface)
+{
+ struct usb_line6_toneport *toneport;
+
+ if (interface == NULL)
+ return;
+ toneport = usb_get_intfdata(interface);
+
+ if (toneport->line6.usbdev->descriptor.idProduct != LINE6_DEVID_GUITARPORT) {
+ device_remove_file(&interface->dev, &dev_attr_led_red);
+ device_remove_file(&interface->dev, &dev_attr_led_green);
+ }
+
+ if (toneport != NULL) {
+ struct snd_line6_pcm *line6pcm = toneport->line6.line6pcm;
+
+ if (line6pcm != NULL) {
+ unlink_wait_clear_audio_out_urbs(line6pcm);
+ unlink_wait_clear_audio_in_urbs(line6pcm);
+ }
+ }
+
+ toneport_destruct(interface);
+}
diff --git a/drivers/staging/line6/toneport.h b/drivers/staging/line6/toneport.h
new file mode 100644
index 00000000000..bddc58dd7e3
--- /dev/null
+++ b/drivers/staging/line6/toneport.h
@@ -0,0 +1,45 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef TONEPORT_H
+#define TONEPORT_H
+
+
+#include "driver.h"
+
+#include <linux/usb.h>
+#include <sound/core.h>
+
+
+struct usb_line6_toneport {
+ /**
+ Generic Line6 USB data.
+ */
+ struct usb_line6 line6;
+
+ /**
+ Serial number of device.
+ */
+ int serial_number;
+
+ /**
+ Firmware version (x 100).
+ */
+ int firmware_version;
+};
+
+
+extern void toneport_disconnect(struct usb_interface *interface);
+extern int toneport_init(struct usb_interface *interface,
+ struct usb_line6_toneport *toneport);
+
+
+#endif
diff --git a/drivers/staging/line6/usbdefs.h b/drivers/staging/line6/usbdefs.h
new file mode 100644
index 00000000000..c38f31f2f42
--- /dev/null
+++ b/drivers/staging/line6/usbdefs.h
@@ -0,0 +1,74 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2005-2008 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef USBDEFS_H
+#define USBDEFS_H
+
+
+#define LINE6_VENDOR_ID 0x0e41
+
+#define USB_INTERVALS_PER_SECOND 1000
+
+/*
+ Device ids.
+*/
+#define LINE6_DEVID_BASSPODXT 0x4250
+#define LINE6_DEVID_BASSPODXTLIVE 0x4642
+#define LINE6_DEVID_BASSPODXTPRO 0x4252
+#define LINE6_DEVID_GUITARPORT 0x4750
+#define LINE6_DEVID_POCKETPOD 0x5051
+#define LINE6_DEVID_PODX3 0x414a
+#define LINE6_DEVID_PODX3LIVE 0x414b
+#define LINE6_DEVID_PODXT 0x5044
+#define LINE6_DEVID_PODXTLIVE 0x4650
+#define LINE6_DEVID_PODXTPRO 0x5050
+#define LINE6_DEVID_TONEPORT_GX 0x4147
+#define LINE6_DEVID_TONEPORT_UX1 0x4141
+#define LINE6_DEVID_TONEPORT_UX2 0x4142
+#define LINE6_DEVID_VARIAX 0x534d
+
+#define LINE6_BIT_BASSPODXT (1 << 0)
+#define LINE6_BIT_BASSPODXTLIVE (1 << 1)
+#define LINE6_BIT_BASSPODXTPRO (1 << 2)
+#define LINE6_BIT_GUITARPORT (1 << 3)
+#define LINE6_BIT_POCKETPOD (1 << 4)
+#define LINE6_BIT_PODX3 (1 << 5)
+#define LINE6_BIT_PODX3LIVE (1 << 6)
+#define LINE6_BIT_PODXT (1 << 7)
+#define LINE6_BIT_PODXTLIVE (1 << 8)
+#define LINE6_BIT_PODXTPRO (1 << 9)
+#define LINE6_BIT_TONEPORT_GX (1 << 10)
+#define LINE6_BIT_TONEPORT_UX1 (1 << 11)
+#define LINE6_BIT_TONEPORT_UX2 (1 << 12)
+#define LINE6_BIT_VARIAX (1 << 13)
+
+#define LINE6_BITS_PRO (LINE6_BIT_BASSPODXTPRO | \
+ LINE6_BIT_PODXTPRO)
+#define LINE6_BITS_LIVE (LINE6_BIT_BASSPODXTLIVE | \
+ LINE6_BIT_PODXTLIVE | \
+ LINE6_BIT_PODX3LIVE)
+#define LINE6_BITS_PODXTALL (LINE6_BIT_PODXT | \
+ LINE6_BIT_PODXTLIVE | \
+ LINE6_BIT_PODXTPRO)
+#define LINE6_BITS_BASSPODXTALL (LINE6_BIT_BASSPODXT | \
+ LINE6_BIT_BASSPODXTLIVE | \
+ LINE6_BIT_BASSPODXTPRO)
+
+/* device supports settings parameter via USB */
+#define LINE6_BIT_CONTROL (1 << 0)
+/* device supports PCM input/output via USB */
+#define LINE6_BIT_PCM (1 << 1)
+#define LINE6_BIT_CONTROL_PCM (LINE6_BIT_CONTROL | LINE6_BIT_PCM)
+
+#define LINE6_FALLBACK_INTERVAL 10
+#define LINE6_FALLBACK_MAXPACKETSIZE 16
+
+#endif
diff --git a/drivers/staging/line6/variax.c b/drivers/staging/line6/variax.c
new file mode 100644
index 00000000000..f9d96984733
--- /dev/null
+++ b/drivers/staging/line6/variax.c
@@ -0,0 +1,546 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#include "driver.h"
+
+#include "audio.h"
+#include "control.h"
+#include "variax.h"
+
+
+#define VARIAX_SYSEX_CODE 7
+#define VARIAX_SYSEX_PARAM 0x3b
+#define VARIAX_SYSEX_ACTIVATE 0x2a
+#define VARIAX_MODEL_HEADER_LENGTH 7
+#define VARIAX_MODEL_MESSAGE_LENGTH 199
+#define VARIAX_OFFSET_ACTIVATE 7
+
+
+static const char variax_activate[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x2a, 0x01,
+ 0xf7
+};
+static const char variax_request_bank[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x6d, 0xf7
+};
+static const char variax_request_model1[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05, 0x03,
+ 0x00, 0x00, 0x00, 0xf7
+};
+static const char variax_request_model2[] = {
+ 0xf0, 0x00, 0x01, 0x0c, 0x07, 0x00, 0x3c, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x03,
+ 0x00, 0x00, 0x00, 0xf7
+};
+
+
+/*
+ Decode data transmitted by workbench.
+*/
+static void variax_decode(const unsigned char *raw_data, unsigned char *data,
+ int raw_size)
+{
+ for (; raw_size > 0; raw_size -= 6) {
+ data[2] = raw_data[0] | (raw_data[1] << 4);
+ data[1] = raw_data[2] | (raw_data[3] << 4);
+ data[0] = raw_data[4] | (raw_data[5] << 4);
+ raw_data += 6;
+ data += 3;
+ }
+}
+
+static void variax_activate_timeout(unsigned long arg)
+{
+ struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
+ variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = 1;
+ line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
+ sizeof(variax_activate));
+}
+
+/*
+ Send an asynchronous activation request after a given interval.
+*/
+static void variax_activate_delayed(struct usb_line6_variax *variax,
+ int seconds)
+{
+ variax->activate_timer.expires = jiffies + seconds * HZ;
+ variax->activate_timer.function = variax_activate_timeout;
+ variax->activate_timer.data = (unsigned long)variax;
+ add_timer(&variax->activate_timer);
+}
+
+static void variax_startup_timeout(unsigned long arg)
+{
+ struct usb_line6_variax *variax = (struct usb_line6_variax *)arg;
+
+ if (variax->dumpreq.ok)
+ return;
+
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
+ line6_startup_delayed(&variax->dumpreq, 1, variax_startup_timeout,
+ variax);
+}
+
+/*
+ Process a completely received message.
+*/
+void variax_process_message(struct usb_line6_variax *variax)
+{
+ const unsigned char *buf = variax->line6.buffer_message;
+
+ switch (buf[0]) {
+ case LINE6_PARAM_CHANGE | LINE6_CHANNEL_HOST:
+ switch (buf[1]) {
+ case VARIAXMIDI_volume:
+ variax->volume = buf[2];
+ break;
+
+ case VARIAXMIDI_tone:
+ variax->tone = buf[2];
+ }
+
+ break;
+
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_DEVICE:
+ case LINE6_PROGRAM_CHANGE | LINE6_CHANNEL_HOST:
+ variax->model = buf[1];
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 0);
+ break;
+
+ case LINE6_RESET:
+ dev_info(variax->line6.ifcdev, "VARIAX reset\n");
+ variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
+ break;
+
+ case LINE6_SYSEX_BEGIN:
+ if (memcmp(buf + 1, variax_request_model1 + 1,
+ VARIAX_MODEL_HEADER_LENGTH - 1) == 0) {
+ if (variax->line6.message_length ==
+ VARIAX_MODEL_MESSAGE_LENGTH) {
+ switch (variax->dumpreq.in_progress) {
+ case VARIAX_DUMP_PASS1:
+ variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH, (unsigned char *)&variax->model_data,
+ (sizeof(variax->model_data.name) + sizeof(variax->model_data.control) / 2) * 2);
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 1);
+ line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS2);
+ break;
+
+ case VARIAX_DUMP_PASS2:
+ /* model name is transmitted twice, so skip it here: */
+ variax_decode(buf + VARIAX_MODEL_HEADER_LENGTH,
+ (unsigned char *)&variax->model_data.control + sizeof(variax->model_data.control) / 2,
+ sizeof(variax->model_data.control) / 2 * 2);
+ variax->dumpreq.ok = 1;
+ line6_dump_request_async(&variax->dumpreq, &variax->line6, 2);
+ line6_dump_started(&variax->dumpreq, VARIAX_DUMP_PASS3);
+ }
+ } else {
+ DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "illegal length %d of model data\n", variax->line6.message_length));
+ line6_dump_finished(&variax->dumpreq);
+ }
+ } else if (memcmp(buf + 1, variax_request_bank + 1,
+ sizeof(variax_request_bank) - 2) == 0) {
+ memcpy(variax->bank,
+ buf + sizeof(variax_request_bank) - 1,
+ sizeof(variax->bank));
+ variax->dumpreq.ok = 1;
+ line6_dump_finished(&variax->dumpreq);
+ }
+
+ break;
+
+ case LINE6_SYSEX_END:
+ break;
+
+ default:
+ DEBUG_MESSAGES(dev_err(variax->line6.ifcdev, "Variax: unknown message %02X\n", buf[0]));
+ }
+}
+
+/*
+ "read" request on "volume" special file.
+*/
+static ssize_t variax_get_volume(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->volume);
+}
+
+/*
+ "write" request on "volume" special file.
+*/
+static ssize_t variax_set_volume(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10);
+
+ if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_volume,
+ value) == 0)
+ variax->volume = value;
+
+ return count;
+}
+
+/*
+ "read" request on "model" special file.
+*/
+static ssize_t variax_get_model(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->model);
+}
+
+/*
+ "write" request on "model" special file.
+*/
+static ssize_t variax_set_model(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10);
+
+ if (line6_send_program(&variax->line6, value) == 0)
+ variax->model = value;
+
+ return count;
+}
+
+/*
+ "read" request on "active" special file.
+*/
+static ssize_t variax_get_active(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->buffer_activate[VARIAX_OFFSET_ACTIVATE]);
+}
+
+/*
+ "write" request on "active" special file.
+*/
+static ssize_t variax_set_active(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10) ? 1 : 0;
+ variax->buffer_activate[VARIAX_OFFSET_ACTIVATE] = value;
+ line6_send_raw_message_async(&variax->line6, variax->buffer_activate,
+ sizeof(variax_activate));
+ return count;
+}
+
+/*
+ "read" request on "tone" special file.
+*/
+static ssize_t variax_get_tone(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ return sprintf(buf, "%d\n", variax->tone);
+}
+
+/*
+ "write" request on "tone" special file.
+*/
+static ssize_t variax_set_tone(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int value = simple_strtoul(buf, NULL, 10);
+
+ if (line6_transmit_parameter(&variax->line6, VARIAXMIDI_tone,
+ value) == 0)
+ variax->tone = value;
+
+ return count;
+}
+
+static ssize_t get_string(char *buf, const char *data, int length)
+{
+ int i;
+ memcpy(buf, data, length);
+
+ for (i = length; i--;) {
+ char c = buf[i];
+
+ if ((c != 0) && (c != ' '))
+ break;
+ }
+
+ buf[i + 1] = '\n';
+ return i + 2;
+}
+
+/*
+ "read" request on "name" special file.
+*/
+static ssize_t variax_get_name(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ line6_wait_dump(&variax->dumpreq, 0);
+ return get_string(buf, variax->model_data.name,
+ sizeof(variax->model_data.name));
+}
+
+/*
+ "read" request on "bank" special file.
+*/
+static ssize_t variax_get_bank(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ line6_wait_dump(&variax->dumpreq, 0);
+ return get_string(buf, variax->bank, sizeof(variax->bank));
+}
+
+/*
+ "read" request on "dump" special file.
+*/
+static ssize_t variax_get_dump(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int retval;
+ retval = line6_wait_dump(&variax->dumpreq, 0);
+ if (retval < 0)
+ return retval;
+ memcpy(buf, &variax->model_data.control,
+ sizeof(variax->model_data.control));
+ return sizeof(variax->model_data.control);
+}
+
+#if CREATE_RAW_FILE
+
+/*
+ "write" request on "raw" special file.
+*/
+static ssize_t variax_set_raw2(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(to_usb_interface(dev));
+ int size;
+ int i;
+ char *sysex;
+
+ count -= count % 3;
+ size = count * 2;
+ sysex = variax_alloc_sysex_buffer(variax, VARIAX_SYSEX_PARAM, size);
+
+ if (!sysex)
+ return 0;
+
+ for (i = 0; i < count; i += 3) {
+ const unsigned char *p1 = buf + i;
+ char *p2 = sysex + SYSEX_DATA_OFS + i * 2;
+ p2[0] = p1[2] & 0x0f;
+ p2[1] = p1[2] >> 4;
+ p2[2] = p1[1] & 0x0f;
+ p2[3] = p1[1] >> 4;
+ p2[4] = p1[0] & 0x0f;
+ p2[5] = p1[0] >> 4;
+ }
+
+ line6_send_sysex_message(&variax->line6, sysex, size);
+ kfree(sysex);
+ return count;
+}
+
+#endif
+
+/* Variax workbench special files: */
+static DEVICE_ATTR(model, S_IWUGO | S_IRUGO, variax_get_model, variax_set_model);
+static DEVICE_ATTR(volume, S_IWUGO | S_IRUGO, variax_get_volume, variax_set_volume);
+static DEVICE_ATTR(tone, S_IWUGO | S_IRUGO, variax_get_tone, variax_set_tone);
+static DEVICE_ATTR(name, S_IRUGO, variax_get_name, line6_nop_write);
+static DEVICE_ATTR(bank, S_IRUGO, variax_get_bank, line6_nop_write);
+static DEVICE_ATTR(dump, S_IRUGO, variax_get_dump, line6_nop_write);
+static DEVICE_ATTR(active, S_IWUGO | S_IRUGO, variax_get_active, variax_set_active);
+
+#if CREATE_RAW_FILE
+static DEVICE_ATTR(raw, S_IWUGO, line6_nop_read, line6_set_raw);
+static DEVICE_ATTR(raw2, S_IWUGO, line6_nop_read, variax_set_raw2);
+#endif
+
+
+/*
+ Variax destructor.
+*/
+static void variax_destruct(struct usb_interface *interface)
+{
+ struct usb_line6_variax *variax = usb_get_intfdata(interface);
+ struct usb_line6 *line6;
+
+ if (variax == NULL)
+ return;
+ line6 = &variax->line6;
+ if (line6 == NULL)
+ return;
+ line6_cleanup_audio(line6);
+
+ /* free dump request data: */
+ line6_dumpreq_destructbuf(&variax->dumpreq, 2);
+ line6_dumpreq_destructbuf(&variax->dumpreq, 1);
+ line6_dumpreq_destruct(&variax->dumpreq);
+
+ kfree(variax->buffer_activate);
+ del_timer_sync(&variax->activate_timer);
+}
+
+/*
+ Create sysfs entries.
+*/
+static int variax_create_files2(struct device *dev)
+{
+ int err;
+ CHECK_RETURN(device_create_file(dev, &dev_attr_model));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_volume));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_tone));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_name));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_bank));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_dump));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_active));
+#if CREATE_RAW_FILE
+ CHECK_RETURN(device_create_file(dev, &dev_attr_raw));
+ CHECK_RETURN(device_create_file(dev, &dev_attr_raw2));
+#endif
+ return 0;
+}
+
+/*
+ Init workbench device.
+*/
+int variax_init(struct usb_interface *interface,
+ struct usb_line6_variax *variax)
+{
+ int err;
+
+ if ((interface == NULL) || (variax == NULL))
+ return -ENODEV;
+
+ /* initialize USB buffers: */
+ err = line6_dumpreq_init(&variax->dumpreq, variax_request_model1,
+ sizeof(variax_request_model1));
+
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return err;
+ }
+
+ err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_model2,
+ sizeof(variax_request_model2), 1);
+
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return err;
+ }
+
+ err = line6_dumpreq_initbuf(&variax->dumpreq, variax_request_bank,
+ sizeof(variax_request_bank), 2);
+
+ if (err < 0) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return err;
+ }
+
+ variax->buffer_activate = kmalloc(sizeof(variax_activate), GFP_KERNEL);
+
+ if (variax->buffer_activate == NULL) {
+ dev_err(&interface->dev, "Out of memory\n");
+ variax_destruct(interface);
+ return -ENOMEM;
+ }
+
+ memcpy(variax->buffer_activate, variax_activate,
+ sizeof(variax_activate));
+ init_timer(&variax->activate_timer);
+
+ /* create sysfs entries: */
+ err = variax_create_files(0, 0, &interface->dev);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ err = variax_create_files2(&interface->dev);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ /* initialize audio system: */
+ err = line6_init_audio(&variax->line6);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ /* initialize MIDI subsystem: */
+ err = line6_init_midi(&variax->line6);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ /* register audio system: */
+ err = line6_register_audio(&variax->line6);
+ if (err < 0) {
+ variax_destruct(interface);
+ return err;
+ }
+
+ variax_activate_delayed(variax, VARIAX_ACTIVATE_DELAY);
+ line6_startup_delayed(&variax->dumpreq, VARIAX_STARTUP_DELAY,
+ variax_startup_timeout, variax);
+ return 0;
+}
+
+/*
+ Workbench device disconnected.
+*/
+void variax_disconnect(struct usb_interface *interface)
+{
+ struct device *dev;
+
+ if (interface == NULL)
+ return;
+ dev = &interface->dev;
+
+ if (dev != NULL) {
+ /* remove sysfs entries: */
+ variax_remove_files(0, 0, dev);
+ device_remove_file(dev, &dev_attr_model);
+ device_remove_file(dev, &dev_attr_volume);
+ device_remove_file(dev, &dev_attr_tone);
+ device_remove_file(dev, &dev_attr_name);
+ device_remove_file(dev, &dev_attr_bank);
+ device_remove_file(dev, &dev_attr_dump);
+ device_remove_file(dev, &dev_attr_active);
+#if CREATE_RAW_FILE
+ device_remove_file(dev, &dev_attr_raw);
+ device_remove_file(dev, &dev_attr_raw2);
+#endif
+ }
+
+ variax_destruct(interface);
+}
diff --git a/drivers/staging/line6/variax.h b/drivers/staging/line6/variax.h
new file mode 100644
index 00000000000..ee330ba3089
--- /dev/null
+++ b/drivers/staging/line6/variax.h
@@ -0,0 +1,108 @@
+/*
+ * Line6 Linux USB driver - 0.8.0
+ *
+ * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, version 2.
+ *
+ */
+
+#ifndef VARIAX_H
+#define VARIAX_H
+
+
+#include "driver.h"
+
+#include <linux/spinlock.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+
+#include <sound/core.h>
+
+#include "dumprequest.h"
+
+
+#define VARIAX_ACTIVATE_DELAY 10
+#define VARIAX_STARTUP_DELAY 3
+
+
+enum {
+ VARIAX_DUMP_PASS1 = LINE6_DUMP_CURRENT,
+ VARIAX_DUMP_PASS2,
+ VARIAX_DUMP_PASS3
+};
+
+
+/**
+ Binary Variax model dump
+*/
+struct variax_model {
+ /**
+ Header information (including program name).
+ */
+ unsigned char name[18];
+
+ /**
+ Model parameters.
+ */
+ unsigned char control[78 * 2];
+};
+
+struct usb_line6_variax {
+ /**
+ Generic Line6 USB data.
+ */
+ struct usb_line6 line6;
+
+ /**
+ Dump request structure.
+ Append two extra buffers for 3-pass data query.
+ */
+ struct line6_dump_request dumpreq; struct line6_dump_reqbuf extrabuf[2];
+
+ /**
+ Buffer for activation code.
+ */
+ unsigned char *buffer_activate;
+
+ /**
+ Model number.
+ */
+ int model;
+
+ /**
+ Current model settings.
+ */
+ struct variax_model model_data;
+
+ /**
+ Name of current model bank.
+ */
+ unsigned char bank[18];
+
+ /**
+ Position of volume dial.
+ */
+ int volume;
+
+ /**
+ Position of tone control dial.
+ */
+ int tone;
+
+ /**
+ Timer for delayed activation request.
+ */
+ struct timer_list activate_timer;
+};
+
+
+extern void variax_disconnect(struct usb_interface *interface);
+extern int variax_init(struct usb_interface *interface,
+ struct usb_line6_variax *variax);
+extern void variax_process_message(struct usb_line6_variax *variax);
+
+
+#endif
diff --git a/drivers/staging/me4000/me4000.c b/drivers/staging/me4000/me4000.c
index e1c4a807890..01017b731d0 100644
--- a/drivers/staging/me4000/me4000.c
+++ b/drivers/staging/me4000/me4000.c
@@ -36,8 +36,8 @@
#include <linux/vmalloc.h>
#include <linux/slab.h>
#include <asm/pgtable.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
#include <asm/system.h>
/* Include-File for the Meilhaus ME-4000 I/O board */
@@ -246,17 +246,17 @@ static irqreturn_t me4000_ext_int_isr(int, void *);
Inline functions
---------------------------------------------------------------------------*/
-static int inline me4000_buf_count(struct me4000_circ_buf buf, int size)
+static inline int me4000_buf_count(struct me4000_circ_buf buf, int size)
{
- return ((buf.head - buf.tail) & (size - 1));
+ return (buf.head - buf.tail) & (size - 1);
}
-static int inline me4000_buf_space(struct me4000_circ_buf buf, int size)
+static inline int me4000_buf_space(struct me4000_circ_buf buf, int size)
{
- return ((buf.tail - (buf.head + 1)) & (size - 1));
+ return (buf.tail - (buf.head + 1)) & (size - 1);
}
-static int inline me4000_values_to_end(struct me4000_circ_buf buf, int size)
+static inline int me4000_values_to_end(struct me4000_circ_buf buf, int size)
{
int end;
int n;
@@ -265,7 +265,7 @@ static int inline me4000_values_to_end(struct me4000_circ_buf buf, int size)
return (n < end) ? n : end;
}
-static int inline me4000_space_to_end(struct me4000_circ_buf buf, int size)
+static inline int me4000_space_to_end(struct me4000_circ_buf buf, int size)
{
int end;
int n;
@@ -275,19 +275,19 @@ static int inline me4000_space_to_end(struct me4000_circ_buf buf, int size)
return (n <= end) ? n : (end + 1);
}
-static void inline me4000_outb(unsigned char value, unsigned long port)
+static inline void me4000_outb(unsigned char value, unsigned long port)
{
PORT_PDEBUG("--> 0x%02X port 0x%04lX\n", value, port);
outb(value, port);
}
-static void inline me4000_outl(unsigned long value, unsigned long port)
+static inline void me4000_outl(unsigned long value, unsigned long port)
{
PORT_PDEBUG("--> 0x%08lX port 0x%04lX\n", value, port);
outl(value, port);
}
-static unsigned long inline me4000_inl(unsigned long port)
+static inline unsigned long me4000_inl(unsigned long port)
{
unsigned long value;
value = inl(port);
@@ -295,7 +295,7 @@ static unsigned long inline me4000_inl(unsigned long port)
return value;
}
-static unsigned char inline me4000_inb(unsigned long port)
+static inline unsigned char me4000_inb(unsigned long port)
{
unsigned char value;
value = inb(port);
@@ -309,7 +309,7 @@ static struct pci_driver me4000_driver = {
.probe = me4000_probe
};
-static struct file_operations me4000_ao_fops_sing = {
+static const struct file_operations me4000_ao_fops_sing = {
.owner = THIS_MODULE,
.write = me4000_ao_write_sing,
.ioctl = me4000_ao_ioctl_sing,
@@ -317,7 +317,7 @@ static struct file_operations me4000_ao_fops_sing = {
.release = me4000_release,
};
-static struct file_operations me4000_ao_fops_wrap = {
+static const struct file_operations me4000_ao_fops_wrap = {
.owner = THIS_MODULE,
.write = me4000_ao_write_wrap,
.ioctl = me4000_ao_ioctl_wrap,
@@ -325,7 +325,7 @@ static struct file_operations me4000_ao_fops_wrap = {
.release = me4000_release,
};
-static struct file_operations me4000_ao_fops_cont = {
+static const struct file_operations me4000_ao_fops_cont = {
.owner = THIS_MODULE,
.write = me4000_ao_write_cont,
.poll = me4000_ao_poll_cont,
@@ -335,14 +335,14 @@ static struct file_operations me4000_ao_fops_cont = {
.fsync = me4000_ao_fsync_cont,
};
-static struct file_operations me4000_ai_fops_sing = {
+static const struct file_operations me4000_ai_fops_sing = {
.owner = THIS_MODULE,
.ioctl = me4000_ai_ioctl_sing,
.open = me4000_open,
.release = me4000_release,
};
-static struct file_operations me4000_ai_fops_cont_sw = {
+static const struct file_operations me4000_ai_fops_cont_sw = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -352,7 +352,7 @@ static struct file_operations me4000_ai_fops_cont_sw = {
.fasync = me4000_ai_fasync,
};
-static struct file_operations me4000_ai_fops_cont_et = {
+static const struct file_operations me4000_ai_fops_cont_et = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -361,7 +361,7 @@ static struct file_operations me4000_ai_fops_cont_et = {
.release = me4000_release,
};
-static struct file_operations me4000_ai_fops_cont_et_value = {
+static const struct file_operations me4000_ai_fops_cont_et_value = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -370,7 +370,7 @@ static struct file_operations me4000_ai_fops_cont_et_value = {
.release = me4000_release,
};
-static struct file_operations me4000_ai_fops_cont_et_chanlist = {
+static const struct file_operations me4000_ai_fops_cont_et_chanlist = {
.owner = THIS_MODULE,
.read = me4000_ai_read,
.poll = me4000_ai_poll,
@@ -379,21 +379,21 @@ static struct file_operations me4000_ai_fops_cont_et_chanlist = {
.release = me4000_release,
};
-static struct file_operations me4000_dio_fops = {
+static const struct file_operations me4000_dio_fops = {
.owner = THIS_MODULE,
.ioctl = me4000_dio_ioctl,
.open = me4000_open,
.release = me4000_release,
};
-static struct file_operations me4000_cnt_fops = {
+static const struct file_operations me4000_cnt_fops = {
.owner = THIS_MODULE,
.ioctl = me4000_cnt_ioctl,
.open = me4000_open,
.release = me4000_release,
};
-static struct file_operations me4000_ext_int_fops = {
+static const struct file_operations me4000_ext_int_fops = {
.owner = THIS_MODULE,
.ioctl = me4000_ext_int_ioctl,
.open = me4000_open,
@@ -401,18 +401,26 @@ static struct file_operations me4000_ext_int_fops = {
.fasync = me4000_ext_int_fasync,
};
-static struct file_operations *me4000_ao_fops_array[] = {
- &me4000_ao_fops_sing, // single operations
- &me4000_ao_fops_wrap, // wraparound operations
- &me4000_ao_fops_cont, // continous operations
+static const struct file_operations *me4000_ao_fops_array[] = {
+ /* single operations */
+ &me4000_ao_fops_sing,
+ /* wraparound operations */
+ &me4000_ao_fops_wrap,
+ /* continuous operations */
+ &me4000_ao_fops_cont,
};
-static struct file_operations *me4000_ai_fops_array[] = {
- &me4000_ai_fops_sing, // single operations
- &me4000_ai_fops_cont_sw, // continuous operations with software start
- &me4000_ai_fops_cont_et, // continous operations with external trigger
- &me4000_ai_fops_cont_et_value, // sample values by external trigger
- &me4000_ai_fops_cont_et_chanlist, // work through one channel list by external trigger
+static const struct file_operations *me4000_ai_fops_array[] = {
+ /* single operations */
+ &me4000_ai_fops_sing,
+ /* continuous operations with software start */
+ &me4000_ai_fops_cont_sw,
+ /* continuous operations with external trigger */
+ &me4000_ai_fops_cont_et,
+ /* sample values by external trigger */
+ &me4000_ai_fops_cont_et_value,
+ /* work through one channel list by external trigger */
+ &me4000_ai_fops_cont_et_chanlist,
};
static int __init me4000_init_module(void)
@@ -546,15 +554,13 @@ static void clear_board_info_list(void)
&board_info->ao_context_list, list) {
me4000_ao_reset(ao_context);
free_irq(ao_context->irq, ao_context);
- if (ao_context->circ_buf.buf)
- kfree(ao_context->circ_buf.buf);
+ kfree(ao_context->circ_buf.buf);
list_del(&ao_context->list);
kfree(ao_context);
}
/* Clear analog input context */
- if (board_info->ai_context->circ_buf.buf)
- kfree(board_info->ai_context->circ_buf.buf);
+ kfree(board_info->ai_context->circ_buf.buf);
kfree(board_info->ai_context);
/* Clear digital I/O context */
@@ -1263,9 +1269,8 @@ static int me4000_reset_board(struct me4000_info *info)
info->me4000_regbase + ME4000_AO_DEMUX_ADJUST_REG);
/* Set digital I/O direction for port 0 to output on isolated versions */
- if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1)) {
+ if (!(me4000_inl(info->me4000_regbase + ME4000_DIO_DIR_REG) & 0x1))
me4000_outl(0x1, info->me4000_regbase + ME4000_DIO_CTRL_REG);
- }
return 0;
}
@@ -1463,7 +1468,7 @@ static int me4000_open(struct inode *inode_p, struct file *file_p)
/* Set file operations pointer to single functions */
file_p->f_op = &me4000_dio_fops;
- //me4000_dio_reset(dio_context);
+ /* me4000_dio_reset(dio_context); */
}
/* Counters */
else if (MAJOR(inode_p->i_rdev) == me4000_cnt_major_driver_no) {
@@ -2058,7 +2063,7 @@ static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
ME4000_AO_BUFFER_COUNT);
if (c == 0)
- return (2 * ret);
+ return 2 * ret;
/* Only able to write size of free buffer or size of count */
if (count < c)
@@ -2104,9 +2109,8 @@ static ssize_t me4000_ao_write_cont(struct file *filep, const char *buff,
}
}
- if (filep->f_flags & O_NONBLOCK) {
+ if (filep->f_flags & O_NONBLOCK)
return (ret == 0) ? -EAGAIN : 2 * ret;
- }
return 2 * ret;
}
@@ -2201,7 +2205,7 @@ static int me4000_ao_ioctl_sing(struct inode *inode_p, struct file *file_p,
case ME4000_AO_SIMULTANEOUS_UPDATE:
return
me4000_ao_simultaneous_update(
- (struct me4000_ao_channel_list *)arg,
+ (struct me4000_ao_channel_list *)arg,
ao_context);
case ME4000_AO_EX_TRIG_TIMEOUT:
return me4000_ao_ex_trig_timeout((unsigned long *)arg,
@@ -2361,7 +2365,9 @@ static int me4000_ao_start(unsigned long *arg,
"ME4000:me4000_ao_start():Wait on start of state machine interrupted\n");
return -EINTR;
}
- if (((jiffies - ref) > (timeout * HZ / USER_HZ))) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ /* kernel 2.6 has different definitions for HZ
+ * in user and kernel space */
+ if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
printk(KERN_ERR
"ME4000:me4000_ao_start():Timeout reached\n");
return -EIO;
@@ -2402,8 +2408,8 @@ static int me4000_ao_stop(struct me4000_ao_context *ao_context)
}
/* Clear the stop bit */
- //tmp &= ~ME4000_AO_CTRL_BIT_STOP;
- //me4000_outl(tmp, ao_context->ctrl_reg);
+ /* tmp &= ~ME4000_AO_CTRL_BIT_STOP; */
+ /* me4000_outl(tmp, ao_context->ctrl_reg); */
return 0;
}
@@ -2434,8 +2440,8 @@ static int me4000_ao_immediate_stop(struct me4000_ao_context *ao_context)
}
/* Clear the stop bits */
- //tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP);
- //me4000_outl(tmp, ao_context->ctrl_reg);
+ /* tmp &= ~(ME4000_AO_CTRL_BIT_STOP | ME4000_AO_CTRL_BIT_IMMEDIATE_STOP); */
+ /* me4000_outl(tmp, ao_context->ctrl_reg); */
return 0;
}
@@ -2598,8 +2604,10 @@ static int me4000_ao_simultaneous_disable(struct me4000_ao_context *ao_context)
spin_lock(&ao_context->board_info->preload_lock);
tmp = me4000_inl(ao_context->preload_reg);
- tmp &= ~(0x1 << ao_context->index); // Disable preload bit
- tmp &= ~(0x1 << (ao_context->index + 16)); // Disable hw simultaneous bit
+ /* Disable preload bit */
+ tmp &= ~(0x1 << ao_context->index);
+ /* Disable hw simultaneous bit */
+ tmp &= ~(0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2614,8 +2622,10 @@ static int me4000_ao_simultaneous_ex_trig(struct me4000_ao_context *ao_context)
spin_lock(&ao_context->board_info->preload_lock);
tmp = me4000_inl(ao_context->preload_reg);
- tmp |= (0x1 << ao_context->index); // Enable preload bit
- tmp |= (0x1 << (ao_context->index + 16)); // Enable hw simultaneous bit
+ /* Enable preload bit */
+ tmp |= (0x1 << ao_context->index);
+ /* Enable hw simulatenous bit */
+ tmp |= (0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2630,8 +2640,10 @@ static int me4000_ao_simultaneous_sw(struct me4000_ao_context *ao_context)
spin_lock(&ao_context->board_info->preload_lock);
tmp = me4000_inl(ao_context->preload_reg);
- tmp |= (0x1 << ao_context->index); // Enable preload bit
- tmp &= ~(0x1 << (ao_context->index + 16)); // Disable hw simultaneous bit
+ /* Enable preload bit */
+ tmp |= (0x1 << ao_context->index);
+ /* Enable hw simulatenous bit */
+ tmp &= ~(0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2669,11 +2681,11 @@ static int me4000_ao_preload_update(struct me4000_ao_context *ao_context)
(tmp &
(0x1 <<
(((struct me4000_ao_context *)entry)->index
- + 16)))) {
+ + 16)))) {
tmp &=
~(0x1 <<
(((struct me4000_ao_context *)entry)->
- index));
+ index));
}
}
}
@@ -2732,8 +2744,10 @@ static int me4000_ao_simultaneous_update(struct me4000_ao_channel_list *arg,
"ME4000:me4000_ao_simultaneous_update():Invalid board number specified\n");
return -EFAULT;
}
- tmp &= ~(0x1 << channels.list[i]); // Clear the preload bit
- tmp &= ~(0x1 << (channels.list[i] + 16)); // Clear the hw simultaneous bit
+ /* Clear the preload bit */
+ tmp &= ~(0x1 << channels.list[i]);
+ /* Clear the hw simultaneous bit */
+ tmp &= ~(0x1 << (channels.list[i] + 16));
}
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2759,8 +2773,10 @@ static int me4000_ao_synchronous_ex_trig(struct me4000_ao_context *ao_context)
spin_lock(&ao_context->board_info->preload_lock);
tmp = me4000_inl(ao_context->preload_reg);
- tmp &= ~(0x1 << ao_context->index); // Disable synchronous sw bit
- tmp |= 0x1 << (ao_context->index + 16); // Enable synchronous hw bit
+ /* Disable synchronous sw bit */
+ tmp &= ~(0x1 << ao_context->index);
+ /* Enable synchronous hw bit */
+ tmp |= 0x1 << (ao_context->index + 16);
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2794,8 +2810,10 @@ static int me4000_ao_synchronous_sw(struct me4000_ao_context *ao_context)
spin_lock(&ao_context->board_info->preload_lock);
tmp = me4000_inl(ao_context->preload_reg);
- tmp |= 0x1 << ao_context->index; // Enable synchronous sw bit
- tmp &= ~(0x1 << (ao_context->index + 16)); // Disable synchronous hw bit
+ /* Enable synchronous sw bit */
+ tmp |= 0x1 << ao_context->index;
+ /* Disable synchronous hw bit */
+ tmp &= ~(0x1 << (ao_context->index + 16));
me4000_outl(tmp, ao_context->preload_reg);
spin_unlock(&ao_context->board_info->preload_lock);
@@ -2867,7 +2885,9 @@ static int me4000_ao_ex_trig_timeout(unsigned long *arg,
"ME4000:me4000_ao_ex_trig_timeout():Wait on start of state machine interrupted\n");
return -EINTR;
}
- if (((jiffies - ref) > (timeout * HZ / USER_HZ))) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ /* kernel 2.6 has different definitions for HZ
+ * in user and kernel space */
+ if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
printk(KERN_ERR
"ME4000:me4000_ao_ex_trig_timeout():Timeout reached\n");
return -EIO;
@@ -3243,7 +3263,8 @@ static int me4000_ai_single(struct me4000_ai_single *arg,
"ME4000:me4000_ai_single():Wait on start of state machine interrupted\n");
return -EINTR;
}
- if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ /* 2.6 has different definitions for HZ in user and kernel space */
+ if (((jiffies - jiffy) > (cmd.timeout * HZ / USER_HZ)) && cmd.timeout) {
printk(KERN_ERR
"ME4000:me4000_ai_single():Timeout reached\n");
return -EIO;
@@ -3622,9 +3643,8 @@ static int me4000_ai_config(struct me4000_ai_config *arg,
me4000_outl(tmp, ai_context->ctrl_reg);
/* Write the channel list */
- for (i = 0; i < cmd.channel_list.count; i++) {
+ for (i = 0; i < cmd.channel_list.count; i++)
me4000_outl(list[i], ai_context->channel_list_reg);
- }
/* Setup sample and hold */
if (cmd.sh) {
@@ -3663,8 +3683,7 @@ AI_CONFIG_ERR:
tmp &=
~(ME4000_AI_CTRL_BIT_CHANNEL_FIFO | ME4000_AI_CTRL_BIT_SAMPLE_HOLD);
- if (list)
- kfree(list);
+ kfree(list);
return err;
@@ -3774,25 +3793,22 @@ static int me4000_ai_start_ex(unsigned long *arg,
if (timeout) {
ref = jiffies;
- while (!
- (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
- {
+ while (!(inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
interruptible_sleep_on_timeout(&queue, 1);
if (signal_pending(current)) {
printk(KERN_ERR
"ME4000:me4000_ai_start_ex():Wait on start of state machine interrupted\n");
return -EINTR;
}
- if (((jiffies - ref) > (timeout * HZ / USER_HZ))) { // 2.6 has diffrent definitions for HZ in user and kernel space
+ /* 2.6 has different definitions for HZ in user and kernel space */
+ if ((jiffies - ref) > (timeout * HZ / USER_HZ)) {
printk(KERN_ERR
"ME4000:me4000_ai_start_ex():Timeout reached\n");
return -EIO;
}
}
} else {
- while (!
- (inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM))
- {
+ while (!(inl(ai_context->status_reg) & ME4000_AI_STATUS_BIT_FSM)) {
interruptible_sleep_on_timeout(&queue, 1);
if (signal_pending(current)) {
printk(KERN_ERR
@@ -4113,9 +4129,8 @@ static ssize_t me4000_ai_read(struct file *filep, char *buff, size_t cnt,
return -EPIPE;
}
- if (filep->f_flags & O_NONBLOCK) {
+ if (filep->f_flags & O_NONBLOCK)
return (k == 0) ? -EAGAIN : 2 * ret;
- }
CALL_PDEBUG("me4000_ai_read() is leaved\n");
return ret * 2;
@@ -4254,11 +4269,10 @@ static int eeprom_write_cmd(struct me4000_ai_context *ai_context, unsigned long
udelay(EEPROM_DELAY);
for (i = 0; i < length; i++) {
- if (cmd & ((0x1 << (length - 1)) >> i)) {
+ if (cmd & ((0x1 << (length - 1)) >> i))
value |= PLX_ICR_BIT_EEPROM_WRITE;
- } else {
+ else
value &= ~PLX_ICR_BIT_EEPROM_WRITE;
- }
/* Write to EEPROM */
me4000_outl(value,
@@ -4314,11 +4328,11 @@ static unsigned short eeprom_read_cmd(struct me4000_ai_context *ai_context,
/* Write the read command to the eeprom */
for (i = 0; i < length; i++) {
- if (cmd & ((0x1 << (length - 1)) >> i)) {
+ if (cmd & ((0x1 << (length - 1)) >> i))
value |= PLX_ICR_BIT_EEPROM_WRITE;
- } else {
+ else
value &= ~PLX_ICR_BIT_EEPROM_WRITE;
- }
+
me4000_outl(value,
ai_context->board_info->plx_regbase + PLX_ICR);
udelay(EEPROM_DELAY);
@@ -5440,8 +5454,6 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
int i;
int c = 0;
int c1 = 0;
- //unsigned long before;
- //unsigned long after;
ISR_PDEBUG("me4000_ao_isr() is executed\n");
@@ -5493,7 +5505,6 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
("me4000_ao_isr():Work done or buffer empty\n");
break;
}
- //rdtscl(before);
if (((ao_context->fifo_reg & 0xFF) == ME4000_AO_01_FIFO_REG) ||
((ao_context->fifo_reg & 0xFF) == ME4000_AO_03_FIFO_REG)) {
for (i = 0; i < c1; i++) {
@@ -5509,8 +5520,6 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
ao_context->circ_buf.buf +
ao_context->circ_buf.tail, c1);
- //rdtscl(after);
- //printk(KERN_ERR"ME4000:me4000_ao_isr():Time lapse = %lu\n", after - before);
ao_context->circ_buf.tail =
(ao_context->circ_buf.tail + c1) & (ME4000_AO_BUFFER_COUNT -
@@ -5542,8 +5551,10 @@ static irqreturn_t me4000_ao_isr(int irq, void *dev_id)
/* If state machine is stopped, flow was interrupted */
if (!(me4000_inl(ao_context->status_reg) & ME4000_AO_STATUS_BIT_FSM)) {
printk(KERN_ERR "ME4000:me4000_ao_isr():Broken pipe\n");
- ao_context->pipe_flag = 1; // Set flag in order to inform write routine
- tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ; // Disable interrupt
+ /* Set flag in order to inform write routine */
+ ao_context->pipe_flag = 1;
+ /* Disable interrupt */
+ tmp &= ~ME4000_AO_CTRL_BIT_ENABLE_IRQ;
}
me4000_outl(tmp, ao_context->ctrl_reg);
spin_unlock(&ao_context->int_lock);
diff --git a/drivers/staging/meilhaus/me0600_device.c b/drivers/staging/meilhaus/me0600_device.c
index 8950e47e0e8..bae17d26416 100644
--- a/drivers/staging/meilhaus/me0600_device.c
+++ b/drivers/staging/meilhaus/me0600_device.c
@@ -186,6 +186,7 @@ me_device_t *me0600_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me0600_device;
}
+EXPORT_SYMBOL(me0600_pci_constructor);
// Init and exit of module.
@@ -210,6 +211,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-6xx Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-6xx Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me0600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0600_dio.c b/drivers/staging/meilhaus/me0600_dio.c
index 3a2775749a2..d29303518be 100644
--- a/drivers/staging/meilhaus/me0600_dio.c
+++ b/drivers/staging/meilhaus/me0600_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -91,7 +91,7 @@ static int me0600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_dio_io_single_config(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -162,7 +162,7 @@ static int me0600_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_dio_io_single_read(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -242,7 +242,7 @@ static int me0600_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_dio_io_single_write(me_subdevice_t * subdevice,
+static int me0600_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -329,7 +329,7 @@ static int me0600_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me0600_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -337,7 +337,7 @@ static int me0600_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -346,7 +346,7 @@ static int me0600_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -356,7 +356,7 @@ static int me0600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me0600_dio_subdevice_t *subdevice;
int err;
@@ -381,7 +381,7 @@ me0600_dio_subdevice_t *me0600_dio_constructor(uint32_t reg_base,
kfree(subdevice);
return NULL;
}
- // Initialize spin locks.
+ /* Initialize spin locks. */
spin_lock_init(&subdevice->subdevice_lock);
subdevice->ctrl_reg_lock = ctrl_reg_lock;
diff --git a/drivers/staging/meilhaus/me0600_ext_irq.c b/drivers/staging/meilhaus/me0600_ext_irq.c
index eba18adecb7..2f6fedca322 100644
--- a/drivers/staging/meilhaus/me0600_ext_irq.c
+++ b/drivers/staging/meilhaus/me0600_ext_irq.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -337,11 +337,7 @@ static void me0600_ext_irq_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me0600_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me0600_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me0600_ext_irq_subdevice_t *instance;
uint32_t status;
@@ -397,7 +393,7 @@ static irqreturn_t me0600_isr(int irq, void *dev_id, struct pt_regs *regs)
me0600_ext_irq_subdevice_t *me0600_ext_irq_constructor(uint32_t plx_reg_base,
uint32_t me0600_reg_base,
- spinlock_t * intcsr_lock,
+ spinlock_t *intcsr_lock,
unsigned ext_irq_idx,
int irq)
{
diff --git a/drivers/staging/meilhaus/me0600_optoi.c b/drivers/staging/meilhaus/me0600_optoi.c
index b6d977f228c..43f710ffd27 100644
--- a/drivers/staging/meilhaus/me0600_optoi.c
+++ b/drivers/staging/meilhaus/me0600_optoi.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -68,7 +68,7 @@ static int me0600_optoi_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_optoi_io_single_config(me_subdevice_t * subdevice,
+static int me0600_optoi_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -118,7 +118,7 @@ static int me0600_optoi_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_optoi_io_single_read(me_subdevice_t * subdevice,
+static int me0600_optoi_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -169,7 +169,7 @@ static int me0600_optoi_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_optoi_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_optoi_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -177,7 +177,7 @@ static int me0600_optoi_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_optoi_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_optoi_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -186,7 +186,7 @@ static int me0600_optoi_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_optoi_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_optoi_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -219,7 +219,7 @@ me0600_optoi_subdevice_t *me0600_optoi_constructor(uint32_t reg_base)
kfree(subdevice);
return NULL;
}
- // Initialize spin locks.
+ /* Initialize spin locks. */
spin_lock_init(&subdevice->subdevice_lock);
/* Save the subdevice index */
diff --git a/drivers/staging/meilhaus/me0600_relay.c b/drivers/staging/meilhaus/me0600_relay.c
index 2665c69addd..03835e3df25 100644
--- a/drivers/staging/meilhaus/me0600_relay.c
+++ b/drivers/staging/meilhaus/me0600_relay.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -85,7 +85,7 @@ static int me0600_relay_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_relay_io_single_config(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -135,7 +135,7 @@ static int me0600_relay_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_relay_io_single_read(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -203,7 +203,7 @@ static int me0600_relay_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_relay_io_single_write(me_subdevice_t * subdevice,
+static int me0600_relay_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -279,7 +279,7 @@ static int me0600_relay_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me0600_relay_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_relay_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -287,7 +287,7 @@ static int me0600_relay_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_relay_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_relay_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -296,7 +296,7 @@ static int me0600_relay_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_relay_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_relay_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/me0600_ttli.c b/drivers/staging/meilhaus/me0600_ttli.c
index ab8e13b6f32..7d970f584cc 100644
--- a/drivers/staging/meilhaus/me0600_ttli.c
+++ b/drivers/staging/meilhaus/me0600_ttli.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -67,7 +67,7 @@ static int me0600_ttli_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_ttli_io_single_config(me_subdevice_t * subdevice,
+static int me0600_ttli_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -116,7 +116,7 @@ static int me0600_ttli_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0600_ttli_io_single_read(me_subdevice_t * subdevice,
+static int me0600_ttli_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -164,7 +164,7 @@ static int me0600_ttli_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0600_ttli_query_number_channels(me_subdevice_t * subdevice,
+static int me0600_ttli_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -172,7 +172,7 @@ static int me0600_ttli_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_ttli_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0600_ttli_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -181,7 +181,7 @@ static int me0600_ttli_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0600_ttli_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me0600_ttli_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/me0900_device.c b/drivers/staging/meilhaus/me0900_device.c
index 764d5d307c4..e9c6884b5d2 100644
--- a/drivers/staging/meilhaus/me0900_device.c
+++ b/drivers/staging/meilhaus/me0900_device.c
@@ -152,6 +152,7 @@ me_device_t *me0900_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me0900_device;
}
+EXPORT_SYMBOL(me0900_pci_constructor);
// Init and exit of module.
@@ -175,6 +176,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-9x Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-9x Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me0900_pci_constructor);
diff --git a/drivers/staging/meilhaus/me0900_di.c b/drivers/staging/meilhaus/me0900_di.c
index d7d7394f800..4665b2acbea 100644
--- a/drivers/staging/meilhaus/me0900_di.c
+++ b/drivers/staging/meilhaus/me0900_di.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/version.h>
@@ -71,7 +71,7 @@ static int me0900_di_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_di_io_single_config(me_subdevice_t * subdevice,
+static int me0900_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -115,7 +115,7 @@ static int me0900_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0900_di_io_single_read(me_subdevice_t * subdevice,
+static int me0900_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -161,7 +161,7 @@ static int me0900_di_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0900_di_query_number_channels(me_subdevice_t * subdevice,
+static int me0900_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -169,7 +169,7 @@ static int me0900_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0900_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -178,7 +178,7 @@ static int me0900_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me0900_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
diff --git a/drivers/staging/meilhaus/me0900_do.c b/drivers/staging/meilhaus/me0900_do.c
index b5b9c3a98c9..a2275faf1a0 100644
--- a/drivers/staging/meilhaus/me0900_do.c
+++ b/drivers/staging/meilhaus/me0900_do.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -81,7 +81,7 @@ static int me0900_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_do_io_single_config(me_subdevice_t * subdevice,
+static int me0900_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -125,7 +125,7 @@ static int me0900_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me0900_do_io_single_read(me_subdevice_t * subdevice,
+static int me0900_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -171,7 +171,7 @@ static int me0900_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me0900_do_io_single_write(me_subdevice_t * subdevice,
+static int me0900_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -223,7 +223,7 @@ static int me0900_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me0900_do_query_number_channels(me_subdevice_t * subdevice,
+static int me0900_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -231,7 +231,7 @@ static int me0900_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me0900_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -240,7 +240,7 @@ static int me0900_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me0900_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me0900_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
diff --git a/drivers/staging/meilhaus/me1000_device.c b/drivers/staging/meilhaus/me1000_device.c
index c44e214af26..cf0fb92f24c 100644
--- a/drivers/staging/meilhaus/me1000_device.c
+++ b/drivers/staging/meilhaus/me1000_device.c
@@ -49,8 +49,8 @@
#include "mesubdevice.h"
#include "me1000_dio.h"
-static int me1000_config_load(me_device_t * me_device, struct file *filep,
- me_cfg_device_entry_t * config)
+static int me1000_config_load(me_device_t *me_device, struct file *filep,
+ me_cfg_device_entry_t *config)
{
me1000_device_t *me1000_device;
me1000_dio_subdevice_t *dio;
@@ -181,6 +181,7 @@ me_device_t *me1000_pci_constructor(struct pci_dev * pci_device)
return (me_device_t *) me1000_device;
}
+EXPORT_SYMBOL(me1000_pci_constructor);
// Init and exit of module.
static int __init me1000_init(void)
@@ -203,6 +204,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-1000 Devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-1000 Digital I/O Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1000_dio.c b/drivers/staging/meilhaus/me1000_dio.c
index 87605a9108a..2d7ed07d1f3 100644
--- a/drivers/staging/meilhaus/me1000_dio.c
+++ b/drivers/staging/meilhaus/me1000_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -371,7 +371,7 @@ static int me1000_dio_query_subdevice_caps(struct me_subdevice *subdevice,
me1000_dio_subdevice_t *me1000_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me1000_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me1400_device.c b/drivers/staging/meilhaus/me1400_device.c
index b95bb4fce6a..ca7498b9056 100644
--- a/drivers/staging/meilhaus/me1400_device.c
+++ b/drivers/staging/meilhaus/me1400_device.c
@@ -228,6 +228,7 @@ me_device_t *me1400_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me1400_device;
}
+EXPORT_SYMBOL(me1400_pci_constructor);
// Init and exit of module.
@@ -251,6 +252,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-14xx devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-14xx MIO devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1400_pci_constructor);
diff --git a/drivers/staging/meilhaus/me1400_ext_irq.c b/drivers/staging/meilhaus/me1400_ext_irq.c
index b4df7cc58ab..0dc6b4519b5 100644
--- a/drivers/staging/meilhaus/me1400_ext_irq.c
+++ b/drivers/staging/meilhaus/me1400_ext_irq.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
@@ -323,12 +323,7 @@ static int me1400_ext_irq_query_subdevice_caps_args(struct me_subdevice
return ME_ERRNO_NOT_SUPPORTED;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me1400_ext_irq_isr(int irq, void *dev_id,
- struct pt_regs *regs)
-#endif
{
me1400_ext_irq_subdevice_t *instance;
uint32_t status;
diff --git a/drivers/staging/meilhaus/me1600_ao.c b/drivers/staging/meilhaus/me1600_ao.c
index d127c6b0030..12e3c70e982 100644
--- a/drivers/staging/meilhaus/me1600_ao.c
+++ b/drivers/staging/meilhaus/me1600_ao.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/sched.h>
@@ -55,36 +55,32 @@
static void me1600_ao_destructor(struct me_subdevice *subdevice);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me1600_ao_work_control_task(void *subdevice);
-#else
static void me1600_ao_work_control_task(struct work_struct *work);
-#endif
-static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
-static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep, int channel,
int single_config, int ref, int trig_chan,
int trig_type, int trig_edge, int flags);
-static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep, int channel, int *value,
int time_out, int flags);
-static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep, int channel, int value,
int time_out, int flags);
-static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
+static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
int *subtype);
-static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
-static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit, int *min, int *max,
int *maxdata, int *range);
-static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice, int unit,
+static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice, int unit,
int *count);
-static int me1600_ao_query_range_info(me_subdevice_t * subdevice, int range,
+static int me1600_ao_query_range_info(me_subdevice_t *subdevice, int range,
int *unit, int *min, int *max,
int *maxdata);
@@ -94,10 +90,9 @@ static int me1600_ao_query_range_info(me_subdevice_t * subdevice, int range,
me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
unsigned int ao_idx,
int curr,
- spinlock_t * config_regs_lock,
- spinlock_t * ao_shadows_lock,
- me1600_ao_shadow_t *
- ao_regs_shadows,
+ spinlock_t *config_regs_lock,
+ spinlock_t *ao_shadows_lock,
+ me1600_ao_shadow_t *ao_regs_shadows,
struct workqueue_struct *me1600_wq)
{
me1600_ao_subdevice_t *subdevice;
@@ -200,13 +195,8 @@ me1600_ao_subdevice_t *me1600_ao_constructor(uint32_t reg_base,
subdevice->me1600_workqueue = me1600_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ao_control_task, me1600_ao_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ao_control_task,
me1600_ao_work_control_task);
-#endif
return subdevice;
}
@@ -231,7 +221,7 @@ static void me1600_ao_destructor(struct me_subdevice *subdevice)
}
}
-static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me1600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me1600_ao_subdevice_t *instance;
@@ -313,7 +303,7 @@ static int me1600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -545,7 +535,7 @@ static int me1600_ao_io_single_config(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -612,7 +602,7 @@ static int me1600_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me1600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -756,7 +746,9 @@ static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
queue_delayed_work(instance->me1600_workqueue,
&instance->ao_control_task, 1);
- if ((!flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING) && ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) { //Blocking mode. Wait for software trigger.
+ if ((!(flags & ME_IO_SINGLE_TYPE_WRITE_NONBLOCKING)) &&
+ ((instance->ao_regs_shadows)->trigger & instance->ao_idx)) {
+ /* Blocking mode. Wait for software trigger. */
if (time_out) {
delay = (time_out * HZ) / 1000;
if (delay == 0)
@@ -793,7 +785,7 @@ static int me1600_ao_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me1600_ao_subdevice_t *instance;
@@ -805,7 +797,7 @@ static int me1600_ao_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
+static int me1600_ao_query_subdevice_type(me_subdevice_t *subdevice, int *type,
int *subtype)
{
me1600_ao_subdevice_t *instance;
@@ -818,14 +810,14 @@ static int me1600_ao_query_subdevice_type(me_subdevice_t * subdevice, int *type,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me1600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_AO_TRIG_SYNCHRONOUS;
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -903,7 +895,7 @@ static int me1600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me1600_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me1600_ao_subdevice_t *instance;
@@ -928,7 +920,7 @@ static int me1600_ao_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me1600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me1600_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -960,22 +952,14 @@ static int me1600_ao_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me1600_ao_work_control_task(void *subdevice)
-#else
static void me1600_ao_work_control_task(struct work_struct *work)
-#endif
{
me1600_ao_subdevice_t *instance;
int reschedule = 1;
int signaling = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me1600_ao_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me1600_ao_subdevice_t, ao_control_task);
-#endif
PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
instance->ao_idx);
diff --git a/drivers/staging/meilhaus/me1600_ao.h b/drivers/staging/meilhaus/me1600_ao.h
index b82bf5a1676..4827dcb4bf4 100644
--- a/drivers/staging/meilhaus/me1600_ao.h
+++ b/drivers/staging/meilhaus/me1600_ao.h
@@ -98,11 +98,7 @@ typedef struct me1600_ao_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
me1600_ao_timeout_t timeout; /**< The timeout for start in blocking and non-blocking mode. */
struct workqueue_struct *me1600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ao_control_task;
-#else
struct delayed_work ao_control_task;
-#endif
volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
} me1600_ao_subdevice_t;
diff --git a/drivers/staging/meilhaus/me1600_device.c b/drivers/staging/meilhaus/me1600_device.c
index 3bc2cb1dc86..c244e984049 100644
--- a/drivers/staging/meilhaus/me1600_device.c
+++ b/drivers/staging/meilhaus/me1600_device.c
@@ -48,7 +48,7 @@
#include "mesubdevice.h"
#include "me1600_device.h"
-static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base);
+static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base);
static void me1600_destructor(struct me_device *device);
/**
@@ -142,6 +142,7 @@ me_device_t *me1600_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me1600_device;
}
+EXPORT_SYMBOL(me1600_pci_constructor);
static void me1600_destructor(struct me_device *device)
{
@@ -157,7 +158,7 @@ static void me1600_destructor(struct me_device *device)
kfree(me1600_device);
}
-static void me1600_set_registry(me1600_device_t * subdevice, uint32_t reg_base)
+static void me1600_set_registry(me1600_device_t *subdevice, uint32_t reg_base)
{ // Create shadow structure.
if (subdevice->ao_regs_shadows.count >= 1) {
subdevice->ao_regs_shadows.registry[0] =
@@ -256,6 +257,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-1600 Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-1600 Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me1600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me4600_ai.c b/drivers/staging/meilhaus/me4600_ai.c
index 0a8c9d737e9..a3cfef09a4d 100644
--- a/drivers/staging/meilhaus/me4600_ai.c
+++ b/drivers/staging/meilhaus/me4600_ai.c
@@ -36,8 +36,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
@@ -57,10 +57,10 @@
*/
static void me4600_ai_destructor(struct me_subdevice *subdevice);
-static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
-static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -68,120 +68,112 @@ static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
int trig_chan,
int trig_type, int trig_edge, int flags);
-static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
-static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags);
-static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
struct file *filep,
int read_mode,
int *values, int *count, int flags);
-static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags);
-static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
+static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
instance, int *values,
const int count,
const int flags);
-static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags);
-static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags);
-static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags);
-static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range);
-static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count);
-static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata);
-static int me4600_ai_query_timer(me_subdevice_t * subdevice,
+static int me4600_ai_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks);
-static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
int cap, int *args, int count);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ai_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-static int ai_mux_toggler(me4600_ai_subdevice_t * subdevice);
+static int ai_mux_toggler(me4600_ai_subdevice_t *subdevice);
/** Immidiate stop.
* Reset all IRQ's sources. (block laches)
* Preserve FIFO
*/
-static int ai_stop_immediately(me4600_ai_subdevice_t * instance);
+static int ai_stop_immediately(me4600_ai_subdevice_t *instance);
/** Immidiate stop.
* Reset all IRQ's sources. (block laches)
* Reset data FIFO
*/
-void inline ai_stop_isr(me4600_ai_subdevice_t * instance);
+inline void ai_stop_isr(me4600_ai_subdevice_t *instance);
/** Interrupt logics.
* Read datas
* Reset latches
*/
-void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
+void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
const uint32_t ctrl_status);
-void ai_infinite_isr(me4600_ai_subdevice_t * instance,
+void ai_infinite_isr(me4600_ai_subdevice_t *instance,
const uint32_t irq_status, const uint32_t ctrl_status);
/** Last chunck of datas. We must reschedule sample counter.
* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
* When threshold is wrongly set some IRQ are lost.(!!!)
*/
-void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance);
+inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance);
/** Read datas from FIFO and copy them to buffer */
-static int inline ai_read_data(me4600_ai_subdevice_t * instance,
+static inline int ai_read_data(me4600_ai_subdevice_t *instance,
const int count);
/** Copy rest of data from fifo to circular buffer.*/
-static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance);
+static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance);
/** Set ISM to next state for infinite data aqusation mode*/
-void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance);
+inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance);
/** Set ISM to next state for define amount of data aqusation mode*/
-void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
+inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
uint32_t irq_status);
/** Set ISM to next stage for limited mode */
-void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance);
+inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me4600_ai_work_control_task(void *subdevice);
-#else
static void me4600_ai_work_control_task(struct work_struct *work);
-#endif
/* Definitions
*/
@@ -192,7 +184,7 @@ me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
int isolated,
int sh,
int irq,
- spinlock_t * ctrl_reg_lock,
+ spinlock_t *ctrl_reg_lock,
struct workqueue_struct *me4600_wq)
{
me4600_ai_subdevice_t *subdevice;
@@ -360,13 +352,8 @@ me4600_ai_subdevice_t *me4600_ai_constructor(uint32_t reg_base,
subdevice->me4600_workqueue = me4600_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ai_control_task, me4600_ai_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ai_control_task,
me4600_ai_work_control_task);
-#endif
return subdevice;
}
@@ -397,7 +384,7 @@ static void me4600_ai_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ai_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ai_subdevice_t *instance;
@@ -519,7 +506,7 @@ static int me4600_ai_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -709,7 +696,7 @@ static int me4600_ai_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -915,11 +902,11 @@ static int me4600_ai_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me4600_ai_subdevice_t *instance;
@@ -1586,15 +1573,15 @@ static int me4600_ai_io_stream_config(me_subdevice_t * subdevice,
ME_SINGLE_CHANNEL_NOT_CONFIGURED;
}
- VERIFY_ERROR: // Error in code. Wrong setting check. This should never ever happend!
+VERIFY_ERROR: // Error in code. Wrong setting check. This should never ever happend!
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
- ERROR: // Error in settings.
+ERROR: // Error in settings.
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -1677,7 +1664,7 @@ static int me4600_ai_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
+static inline int me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
instance, int *values,
const int count,
const int flags)
@@ -1712,7 +1699,7 @@ static int inline me4600_ai_io_stream_read_get_value(me4600_ai_subdevice_t *
return n;
}
-static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_read(me_subdevice_t *subdevice,
struct file *filep,
int read_mode,
int *values, int *count, int flags)
@@ -1838,7 +1825,7 @@ static int me4600_ai_io_stream_read(me_subdevice_t * subdevice,
* @param instance The subdevice instance (pointer).
*/
-static int ai_stop_immediately(me4600_ai_subdevice_t * instance)
+static int ai_stop_immediately(me4600_ai_subdevice_t *instance)
{
unsigned long cpu_flags = 0;
volatile uint32_t ctrl;
@@ -1877,7 +1864,7 @@ static int ai_stop_immediately(me4600_ai_subdevice_t * instance)
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -2055,13 +2042,13 @@ static int me4600_ai_io_stream_start(me_subdevice_t * subdevice,
(tmp & ME4600_AI_CTRL_BIT_SC_IRQ_RESET) ? "reset" : "work");
#endif
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -2139,7 +2126,7 @@ static int me4600_ai_io_stream_status(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ai_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{
@@ -2236,7 +2223,7 @@ static int me4600_ai_io_stream_stop(me_subdevice_t * subdevice,
return ret;
}
-static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -2288,7 +2275,7 @@ static int me4600_ai_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me4600_ai_subdevice_t *instance;
@@ -2306,7 +2293,7 @@ static int me4600_ai_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ai_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -2330,7 +2317,7 @@ static int me4600_ai_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_timer(me_subdevice_t * subdevice,
+static int me4600_ai_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks)
@@ -2370,7 +2357,7 @@ static int me4600_ai_query_timer(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ai_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me4600_ai_subdevice_t *instance;
@@ -2383,7 +2370,7 @@ static int me4600_ai_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ai_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed. idx=0\n");
@@ -2394,7 +2381,7 @@ static int me4600_ai_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ai_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_ai_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed. idx=0\n");
@@ -2439,7 +2426,7 @@ static int me4600_ai_query_subdevice_caps_args(struct me_subdevice *subdevice,
return err;
}
-void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
+void ai_limited_isr(me4600_ai_subdevice_t *instance, const uint32_t irq_status,
const uint32_t ctrl_status)
{
int to_read;
@@ -2547,7 +2534,7 @@ void ai_limited_isr(me4600_ai_subdevice_t * instance, const uint32_t irq_status,
}
}
-void ai_infinite_isr(me4600_ai_subdevice_t * instance,
+void ai_infinite_isr(me4600_ai_subdevice_t *instance,
const uint32_t irq_status, const uint32_t ctrl_status)
{
int to_read;
@@ -2603,11 +2590,7 @@ void ai_infinite_isr(me4600_ai_subdevice_t * instance,
}
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ai_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{ /// @note This is time critical function!
uint32_t irq_status;
uint32_t ctrl_status;
@@ -2803,7 +2786,7 @@ static irqreturn_t me4600_ai_isr(int irq, void *dev_id, struct pt_regs *regs)
*
* @param instance The subdevice instance (pointer).
*/
-void inline ai_stop_isr(me4600_ai_subdevice_t * instance)
+inline void ai_stop_isr(me4600_ai_subdevice_t *instance)
{ /// @note This is soft time critical function!
register uint32_t tmp;
@@ -2829,7 +2812,7 @@ void inline ai_stop_isr(me4600_ai_subdevice_t * instance)
* @return On success: Number of copied values.
* @return On error: -ME_ERRNO_RING_BUFFER_OVERFLOW.
*/
-static int inline ai_read_data(me4600_ai_subdevice_t * instance,
+static inline int ai_read_data(me4600_ai_subdevice_t *instance,
const int count)
{ /// @note This is time critical function!
int c = count;
@@ -2875,7 +2858,7 @@ static int inline ai_read_data(me4600_ai_subdevice_t * instance,
return copied;
}
-void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance)
+inline void ai_infinite_ISM(me4600_ai_subdevice_t *instance)
{ /// @note This is time critical function!
register volatile uint32_t ctrl_set, ctrl_reset, tmp;
@@ -2925,7 +2908,7 @@ void inline ai_infinite_ISM(me4600_ai_subdevice_t * instance)
}
-void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
+inline void ai_limited_ISM(me4600_ai_subdevice_t *instance,
uint32_t irq_status)
{ /// @note This is time critical function!
register volatile uint32_t ctrl_set, ctrl_reset = 0xFFFFFFFF, tmp;
@@ -2986,7 +2969,7 @@ void inline ai_limited_ISM(me4600_ai_subdevice_t * instance,
* Leaving SC_RELOAD doesn't do any harm, but in some bad case can make extra interrupts.
* @warning When threshold is wrongly set some IRQ are lost.(!!!)
*/
-void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance)
+inline void ai_reschedule_SC(me4600_ai_subdevice_t *instance)
{
register uint32_t rest;
@@ -3018,7 +3001,7 @@ void inline ai_reschedule_SC(me4600_ai_subdevice_t * instance)
}
/** Start the ISM. All must be reseted before enter to this function. */
-void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance)
+inline void ai_data_acquisition_logic(me4600_ai_subdevice_t *instance)
{
register uint32_t tmp;
@@ -3166,7 +3149,7 @@ void inline ai_data_acquisition_logic(me4600_ai_subdevice_t * instance)
}
}
-static int ai_mux_toggler(me4600_ai_subdevice_t * instance)
+static int ai_mux_toggler(me4600_ai_subdevice_t *instance)
{
uint32_t tmp;
@@ -3276,7 +3259,7 @@ static int ai_mux_toggler(me4600_ai_subdevice_t * instance)
* @return On success: Number of copied values.
* @return On error: Negative error code -ME_ERRNO_RING_BUFFER_OVERFLOW.
*/
-static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance)
+static inline int ai_read_data_pooling(me4600_ai_subdevice_t *instance)
{ /// @note This is time critical function!
int empty_space;
int copied = 0;
@@ -3310,11 +3293,7 @@ static int inline ai_read_data_pooling(me4600_ai_subdevice_t * instance)
return (!status) ? copied : -ME_ERRNO_RING_BUFFER_OVERFLOW;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me4600_ai_work_control_task(void *subdevice)
-#else
static void me4600_ai_work_control_task(struct work_struct *work)
-#endif
{
me4600_ai_subdevice_t *instance;
uint32_t status;
@@ -3323,12 +3302,8 @@ static void me4600_ai_work_control_task(struct work_struct *work)
int reschedule = 0;
int signaling = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me4600_ai_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me4600_ai_subdevice_t, ai_control_task);
-#endif
PINFO("<%s: %ld> executed.\n", __func__, jiffies);
status = inl(instance->status_reg);
diff --git a/drivers/staging/meilhaus/me4600_ai.h b/drivers/staging/meilhaus/me4600_ai.h
index 1d5a1b9c6f9..106e1959f9f 100644
--- a/drivers/staging/meilhaus/me4600_ai.h
+++ b/drivers/staging/meilhaus/me4600_ai.h
@@ -139,11 +139,7 @@ typedef struct me4600_ai_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
struct workqueue_struct *me4600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ai_control_task;
-#else
struct delayed_work ai_control_task;
-#endif
volatile int ai_control_task_flag; /**< Flag controling reexecuting of control task */
diff --git a/drivers/staging/meilhaus/me4600_ao.c b/drivers/staging/meilhaus/me4600_ao.c
index e2bec8229ab..eb472692a7c 100644
--- a/drivers/staging/meilhaus/me4600_ao.c
+++ b/drivers/staging/meilhaus/me4600_ao.c
@@ -38,8 +38,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/version.h>
#include <linux/interrupt.h>
@@ -58,31 +58,31 @@
/* Defines
*/
-static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range);
-static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count);
-static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata);
-static int me4600_ao_query_timer(me_subdevice_t * subdevice,
+static int me4600_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks);
-static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
static int me4600_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
@@ -105,12 +105,12 @@ static void me4600_ao_destructor(struct me_subdevice *subdevice);
/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'.
*/
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
/** Set output as single
*/
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -120,103 +120,93 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
/** Pass to user actual value of output.
*/
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
/** Write to output requed value.
*/
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags);
/** Set output as streamed device.
*/
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags);
/** Wait for / Check empty space in buffer.
*/
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags);
/** Start streaming.
*/
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags);
/** Check actual state. / Wait for end.
*/
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags);
/** Stop streaming.
*/
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags);
/** Write datas to buffor.
*/
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags);
/** Interrupt handler. Copy from buffer to FIFO.
*/
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
- , struct pt_regs *regs
-#endif
- );
+static irqreturn_t me4600_ao_isr(int irq, void *dev_id);
/** Copy data from circular buffer to fifo (fast) in wraparound mode.
*/
-int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (fast).
*/
-int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (slow).
*/
-int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from user space to circular buffer.
*/
-int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
int *user_values);
/** Stop presentation. Preserve FIFOs.
*/
-int inline ao_stop_immediately(me4600_ao_subdevice_t * instance);
+inline int ao_stop_immediately(me4600_ao_subdevice_t *instance);
/** Task for asynchronical state verifying.
*/
-static void me4600_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- void *subdevice
-#else
- struct work_struct *work
-#endif
- );
+static void me4600_ao_work_control_task(struct work_struct *work);
/* Functions
*/
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -290,7 +280,7 @@ static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -463,7 +453,7 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -547,7 +537,7 @@ static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -989,11 +979,11 @@ static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -1025,7 +1015,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
}
if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
- if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
+ if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
PERROR
("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
return ME_ERRNO_INVALID_FLAGS;
@@ -1327,7 +1317,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -1408,7 +1398,7 @@ static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -1845,7 +1835,7 @@ static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -1943,7 +1933,7 @@ static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{ // Stop work and empty buffer and FIFO
@@ -2048,7 +2038,7 @@ static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags)
@@ -2272,11 +2262,7 @@ static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
return err;
}
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19)
- , struct pt_regs *regs
-#endif
- )
+static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
{
me4600_ao_subdevice_t *instance = dev_id;
uint32_t irq_status;
@@ -2498,8 +2484,8 @@ static void me4600_ao_destructor(struct me_subdevice *subdevice)
}
me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
+ spinlock_t *preload_reg_lock,
+ uint32_t *preload_flags,
int ao_idx,
int fifo,
int irq,
@@ -2689,13 +2675,8 @@ me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
subdevice->me4600_workqueue = me4600_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ao_control_task, me4600_ao_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ao_control_task,
me4600_ao_work_control_task);
-#endif
if (subdevice->fifo) { // Set speed for single operations.
outl(ME4600_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
@@ -2709,7 +2690,7 @@ me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
*
* @param instance The subdevice instance (pointer).
*/
-int inline ao_stop_immediately(me4600_ao_subdevice_t * instance)
+inline int ao_stop_immediately(me4600_ao_subdevice_t *instance)
{
unsigned long cpu_flags;
uint32_t ctrl;
@@ -2762,7 +2743,7 @@ int inline ao_stop_immediately(me4600_ao_subdevice_t * instance)
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me4600_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -2827,7 +2808,7 @@ int inline ao_write_data_wraparound(me4600_ao_subdevice_t * instance, int count,
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me4600_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -2897,7 +2878,7 @@ int inline ao_write_data(me4600_ao_subdevice_t * instance, int count,
* @return On error/success: 0. FIFO was full at begining.
* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
*/
-int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me4600_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is slow function!
uint32_t status;
@@ -2955,7 +2936,7 @@ int inline ao_write_data_pooling(me4600_ao_subdevice_t * instance, int count,
* @return On success: Number of copied values.
* @return On error: -ME_ERRNO_INTERNAL.
*/
-int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me4600_ao_subdevice_t *instance, int count,
int *user_values)
{
int i, err;
@@ -2987,13 +2968,7 @@ int inline ao_get_data_from_user(me4600_ao_subdevice_t * instance, int count,
/** @brief Checking actual hardware and logical state.
* @param instance The subdevice instance (pointer).
*/
-static void me4600_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- void *subdevice
-#else
- struct work_struct *work
-#endif
- )
+static void me4600_ao_work_control_task(struct work_struct *work)
{
me4600_ao_subdevice_t *instance;
unsigned long cpu_flags = 0;
@@ -3003,12 +2978,8 @@ static void me4600_ao_work_control_task(
int reschedule = 0;
int signaling = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me4600_ao_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me4600_ao_subdevice_t, ao_control_task);
-#endif
PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
instance->ao_idx);
@@ -3323,7 +3294,7 @@ static void me4600_ao_work_control_task(
#else
/// @note SPECIAL BUILD FOR BOSCH
/// @author Guenter Gebhardt
-static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -3365,7 +3336,7 @@ static int me4600_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -3636,7 +3607,7 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
@@ -3645,7 +3616,7 @@ static int me4600_ao_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -3682,7 +3653,7 @@ static int me4600_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -3830,18 +3801,18 @@ static int me4600_ao_io_single_write(me_subdevice_t * subdevice,
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me4600_ao_subdevice_t *instance;
@@ -4150,7 +4121,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
PDEBUG("Ctrl word = 0x%lX.\n", ctrl);
outl(ctrl, instance->ctrl_reg); // Write the control word
- ERROR:
+ERROR:
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
@@ -4159,7 +4130,7 @@ static int me4600_ao_io_stream_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -4238,7 +4209,7 @@ static int me4600_ao_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static void stop_immediately(me4600_ao_subdevice_t * instance)
+static void stop_immediately(me4600_ao_subdevice_t *instance)
{
unsigned long cpu_flags;
uint32_t tmp;
@@ -4253,7 +4224,7 @@ static void stop_immediately(me4600_ao_subdevice_t * instance)
spin_unlock_irqrestore(&instance->subdevice_lock, cpu_flags);
}
-static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -4778,14 +4749,14 @@ static int me4600_ao_io_stream_start(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -4842,14 +4813,14 @@ static int me4600_ao_io_stream_status(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{
@@ -4891,14 +4862,14 @@ static int me4600_ao_io_stream_stop(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me4600_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags)
@@ -5432,18 +5403,14 @@ static int me4600_ao_io_stream_write(me_subdevice_t * subdevice,
goto ERROR;
}
- ERROR:
+ERROR:
ME_SUBDEVICE_EXIT;
return err;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ao_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
unsigned long tmp;
int value;
@@ -5660,8 +5627,8 @@ static void me4600_ao_destructor(struct me_subdevice *subdevice)
}
me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
+ spinlock_t *preload_reg_lock,
+ uint32_t *preload_flags,
int ao_idx, int fifo, int irq)
{
me4600_ao_subdevice_t *subdevice;
@@ -5823,7 +5790,7 @@ me4600_ao_subdevice_t *me4600_ao_constructor(uint32_t reg_base,
/* Common functions
*/
-static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -5858,7 +5825,7 @@ static int me4600_ao_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me4600_ao_subdevice_t *instance;
@@ -5876,7 +5843,7 @@ static int me4600_ao_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
+static int me4600_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -5900,7 +5867,7 @@ static int me4600_ao_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_timer(me_subdevice_t * subdevice,
+static int me4600_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks)
@@ -5934,7 +5901,7 @@ static int me4600_ao_query_timer(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ao_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me4600_ao_subdevice_t *instance;
@@ -5947,7 +5914,7 @@ static int me4600_ao_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
me4600_ao_subdevice_t *instance;
@@ -5962,7 +5929,7 @@ static int me4600_ao_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
me4600_ao_subdevice_t *instance;
instance = (me4600_ao_subdevice_t *) subdevice;
diff --git a/drivers/staging/meilhaus/me4600_ao.h b/drivers/staging/meilhaus/me4600_ao.h
index 6fbc4a2dd9d..7579435adc6 100644
--- a/drivers/staging/meilhaus/me4600_ao.h
+++ b/drivers/staging/meilhaus/me4600_ao.h
@@ -225,11 +225,7 @@ typedef struct me4600_ao_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
struct workqueue_struct *me4600_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ao_control_task;
-#else
struct delayed_work ao_control_task;
-#endif
volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
diff --git a/drivers/staging/meilhaus/me4600_device.c b/drivers/staging/meilhaus/me4600_device.c
index fa455844f4e..457666ef61a 100644
--- a/drivers/staging/meilhaus/me4600_device.c
+++ b/drivers/staging/meilhaus/me4600_device.c
@@ -336,6 +336,7 @@ me_device_t *me4600_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me4600_device;
}
+EXPORT_SYMBOL(me4600_pci_constructor);
// Init and exit of module.
@@ -368,6 +369,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-46xx Devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-46xx Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me4600_pci_constructor);
diff --git a/drivers/staging/meilhaus/me4600_di.c b/drivers/staging/meilhaus/me4600_di.c
index 7e3c9f4d2df..e107e506138 100644
--- a/drivers/staging/meilhaus/me4600_di.c
+++ b/drivers/staging/meilhaus/me4600_di.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -91,7 +91,7 @@ static int me4600_di_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_di_io_single_config(me_subdevice_t * subdevice,
+static int me4600_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -133,7 +133,7 @@ static int me4600_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_di_io_single_read(me_subdevice_t * subdevice,
+static int me4600_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -177,7 +177,7 @@ static int me4600_di_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_di_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -185,7 +185,7 @@ static int me4600_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -194,7 +194,7 @@ static int me4600_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
@@ -202,7 +202,7 @@ static int me4600_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
}
me4600_di_subdevice_t *me4600_di_constructor(uint32_t reg_base,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me4600_di_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me4600_dio.c b/drivers/staging/meilhaus/me4600_dio.c
index 0af95d1a8f5..baa28ff6b6b 100644
--- a/drivers/staging/meilhaus/me4600_dio.c
+++ b/drivers/staging/meilhaus/me4600_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -94,7 +94,7 @@ static int me4600_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_dio_io_single_config(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -268,7 +268,7 @@ static int me4600_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_dio_io_single_read(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -342,7 +342,7 @@ static int me4600_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_dio_io_single_write(me_subdevice_t * subdevice,
+static int me4600_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -425,7 +425,7 @@ static int me4600_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me4600_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -433,7 +433,7 @@ static int me4600_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -442,7 +442,7 @@ static int me4600_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -452,7 +452,7 @@ static int me4600_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me4600_dio_subdevice_t *me4600_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me4600_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me4600_do.c b/drivers/staging/meilhaus/me4600_do.c
index ee591bc1185..39510f3e6e6 100644
--- a/drivers/staging/meilhaus/me4600_do.c
+++ b/drivers/staging/meilhaus/me4600_do.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -93,7 +93,7 @@ static int me4600_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_do_io_single_config(me_subdevice_t * subdevice,
+static int me4600_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -224,7 +224,7 @@ static int me4600_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me4600_do_io_single_read(me_subdevice_t * subdevice,
+static int me4600_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -284,7 +284,7 @@ static int me4600_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me4600_do_io_single_write(me_subdevice_t * subdevice,
+static int me4600_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -352,7 +352,7 @@ static int me4600_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me4600_do_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -360,7 +360,7 @@ static int me4600_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -369,7 +369,7 @@ static int me4600_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me4600_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = 0;
@@ -377,7 +377,7 @@ static int me4600_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
}
me4600_do_subdevice_t *me4600_do_constructor(uint32_t reg_base,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me4600_do_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me4600_ext_irq.c b/drivers/staging/meilhaus/me4600_ext_irq.c
index adc1e1babf4..6b33cba3da8 100644
--- a/drivers/staging/meilhaus/me4600_ext_irq.c
+++ b/drivers/staging/meilhaus/me4600_ext_irq.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/version.h>
@@ -60,7 +60,7 @@
* Functions
*/
-static int me4600_ext_irq_io_irq_start(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -135,7 +135,7 @@ static int me4600_ext_irq_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ext_irq_io_irq_wait(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -214,7 +214,7 @@ static int me4600_ext_irq_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ext_irq_io_irq_stop(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep,
int channel, int flags)
{
@@ -256,7 +256,7 @@ static int me4600_ext_irq_io_irq_stop(me_subdevice_t * subdevice,
return err;
}
-static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me4600_ext_irq_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me4600_ext_irq_subdevice_t *instance;
@@ -308,7 +308,7 @@ static void me4600_ext_irq_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-static int me4600_ext_irq_query_number_channels(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -316,7 +316,7 @@ static int me4600_ext_irq_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ext_irq_query_subdevice_type(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -325,7 +325,7 @@ static int me4600_ext_irq_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -335,12 +335,7 @@ static int me4600_ext_irq_query_subdevice_caps(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me4600_ext_irq_isr(int irq, void *dev_id,
- struct pt_regs *regs)
-#endif
{
me4600_ext_irq_subdevice_t *instance;
uint32_t ctrl;
diff --git a/drivers/staging/meilhaus/me6000_ao.c b/drivers/staging/meilhaus/me6000_ao.c
index 94f01231f79..f7abdbd485e 100644
--- a/drivers/staging/meilhaus/me6000_ao.c
+++ b/drivers/staging/meilhaus/me6000_ao.c
@@ -36,8 +36,8 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
@@ -57,31 +57,31 @@
/* Defines
*/
-static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range);
-static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count);
-static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata);
-static int me6000_ao_query_timer(me_subdevice_t * subdevice,
+static int me6000_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks);
-static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
@@ -91,11 +91,11 @@ static int me6000_ao_query_subdevice_caps_args(struct me_subdevice *subdevice,
static void me6000_ao_destructor(struct me_subdevice *subdevice);
/** Reset subdevice. Stop all actions. Reset registry. Disable FIFO. Set output to 0V and status to 'none'. */
-static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags);
/** Set output as single */
-static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -104,89 +104,81 @@ static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
int trig_type, int trig_edge, int flags);
/** Pass to user actual value of output. */
-static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
/** Write to output requed value. */
-static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags);
/** Set output as streamed device. */
-static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags);
/** Wait for / Check empty space in buffer. */
-static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags);
/** Start streaming. */
-static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags);
/** Check actual state. / Wait for end. */
-static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags);
/** Stop streaming. */
-static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags);
/** Write datas to buffor. */
-static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags);
/** Interrupt handler. Copy from buffer to FIFO. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me6000_ao_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
/** Copy data from circular buffer to fifo (fast) in wraparound mode. */
-int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (fast).*/
-int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from circular buffer to fifo (slow).*/
-int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
int start_pos);
/** Copy data from user space to circular buffer. */
-int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
int *user_values);
/** Stop presentation. Preserve FIFOs. */
-int inline ao_stop_immediately(me6000_ao_subdevice_t * instance);
+inline int ao_stop_immediately(me6000_ao_subdevice_t *instance);
/** Function for checking timeout in non-blocking mode. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
-static void me6000_ao_work_control_task(void *subdevice);
-#else
static void me6000_ao_work_control_task(struct work_struct *work);
-#endif
/* Functions
*/
-static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
+static int me6000_ao_io_reset_subdevice(me_subdevice_t *subdevice,
struct file *filep, int flags)
{
me6000_ao_subdevice_t *instance;
@@ -274,7 +266,7 @@ static int me6000_ao_io_reset_subdevice(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -473,7 +465,7 @@ static int me6000_ao_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -555,7 +547,7 @@ static int me6000_ao_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -1027,11 +1019,11 @@ static int me6000_ao_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_config(me_subdevice_t *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
me6000_ao_subdevice_t *instance;
@@ -1063,7 +1055,7 @@ static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
}
if (flags & ME_IO_STREAM_CONFIG_HARDWARE_ONLY) {
- if (!flags & ME_IO_STREAM_CONFIG_WRAPAROUND) {
+ if (!(flags & ME_IO_STREAM_CONFIG_WRAPAROUND)) {
PERROR
("Hardware ME_IO_STREAM_CONFIG_HARDWARE_ONLY has to be with ME_IO_STREAM_CONFIG_WRAPAROUND.\n");
return ME_ERRNO_INVALID_FLAGS;
@@ -1359,7 +1351,7 @@ static int me6000_ao_io_stream_config(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_new_values(me_subdevice_t *subdevice,
struct file *filep,
int time_out, int *count, int flags)
{
@@ -1440,7 +1432,7 @@ static int me6000_ao_io_stream_new_values(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_start(me_subdevice_t *subdevice,
struct file *filep,
int start_mode, int time_out, int flags)
{
@@ -1889,7 +1881,7 @@ static int me6000_ao_io_stream_start(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_status(me_subdevice_t *subdevice,
struct file *filep,
int wait,
int *status, int *values, int flags)
@@ -1987,7 +1979,7 @@ static int me6000_ao_io_stream_status(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_stop(me_subdevice_t *subdevice,
struct file *filep,
int stop_mode, int flags)
{ /// @note Stop work and empty buffer and FIFO
@@ -2094,7 +2086,7 @@ static int me6000_ao_io_stream_stop(me_subdevice_t * subdevice,
return err;
}
-static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
+static int me6000_ao_io_stream_write(me_subdevice_t *subdevice,
struct file *filep,
int write_mode,
int *values, int *count, int flags)
@@ -2324,11 +2316,7 @@ static int me6000_ao_io_stream_write(me_subdevice_t * subdevice,
return err;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me6000_ao_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me6000_ao_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me6000_ao_subdevice_t *instance = dev_id;
uint32_t irq_status;
@@ -2544,9 +2532,9 @@ static void me6000_ao_destructor(struct me_subdevice *subdevice)
}
me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
- spinlock_t * preload_reg_lock,
- uint32_t * preload_flags,
- uint32_t * triggering_flags,
+ spinlock_t *preload_reg_lock,
+ uint32_t *preload_flags,
+ uint32_t *triggering_flags,
int ao_idx,
int fifo,
int irq,
@@ -2797,13 +2785,8 @@ me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
subdevice->me6000_workqueue = me6000_wq;
/* workqueue API changed in kernel 2.6.20 */
-#if ( LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) )
- INIT_WORK(&subdevice->ao_control_task, me6000_ao_work_control_task,
- (void *)subdevice);
-#else
INIT_DELAYED_WORK(&subdevice->ao_control_task,
me6000_ao_work_control_task);
-#endif
if (subdevice->fifo) { //Set speed
outl(ME6000_AO_MIN_CHAN_TICKS - 1, subdevice->timer_reg);
@@ -2817,7 +2800,7 @@ me6000_ao_subdevice_t *me6000_ao_constructor(uint32_t reg_base,
*
* @param instance The subdevice instance (pointer).
*/
-int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
+inline int ao_stop_immediately(me6000_ao_subdevice_t *instance)
{
unsigned long cpu_flags;
uint32_t ctrl;
@@ -2825,10 +2808,11 @@ int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
int i;
uint32_t single_mask;
- single_mask =
- (instance->ao_idx - ME6000_AO_SINGLE_STATUS_OFFSET <
- 0) ? 0x0000 : (0x0001 << (instance->ao_idx -
- ME6000_AO_SINGLE_STATUS_OFFSET));
+ if (instance->ao_idx < ME6000_AO_SINGLE_STATUS_OFFSET)
+ single_mask = 0x0000;
+ else
+ single_mask = 0x0001 << (instance->ao_idx -
+ ME6000_AO_SINGLE_STATUS_OFFSET);
timeout =
(instance->hardware_stop_delay >
@@ -2887,7 +2871,7 @@ int inline ao_stop_immediately(me6000_ao_subdevice_t * instance)
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_wraparound(me6000_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -2952,7 +2936,7 @@ int inline ao_write_data_wraparound(me6000_ao_subdevice_t * instance, int count,
* @return On error/success: 0. No datas were copied => no data in buffer.
* @return On error: -ME_ERRNO_FIFO_BUFFER_OVERFLOW.
*/
-int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data(me6000_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is time critical function!
uint32_t status;
@@ -3022,7 +3006,7 @@ int inline ao_write_data(me6000_ao_subdevice_t * instance, int count,
* @return On error/success: 0. FIFO was full at begining.
* @return On error: -ME_ERRNO_RING_BUFFER_UNDEFFLOW.
*/
-int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
+inline int ao_write_data_pooling(me6000_ao_subdevice_t *instance, int count,
int start_pos)
{ /// @note This is slow function!
uint32_t status;
@@ -3080,7 +3064,7 @@ int inline ao_write_data_pooling(me6000_ao_subdevice_t * instance, int count,
* @return On success: Number of copied values.
* @return On error: -ME_ERRNO_INTERNAL.
*/
-int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
+inline int ao_get_data_from_user(me6000_ao_subdevice_t *instance, int count,
int *user_values)
{
int i, err;
@@ -3109,13 +3093,7 @@ int inline ao_get_data_from_user(me6000_ao_subdevice_t * instance, int count,
return copied;
}
-static void me6000_ao_work_control_task(
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- void *subdevice
-#else
- struct work_struct *work
-#endif
- )
+static void me6000_ao_work_control_task(struct work_struct *work)
{
me6000_ao_subdevice_t *instance;
unsigned long cpu_flags = 0;
@@ -3126,12 +3104,8 @@ static void me6000_ao_work_control_task(
int signaling = 0;
uint32_t single_mask;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- instance = (me6000_ao_subdevice_t *) subdevice;
-#else
instance =
container_of((void *)work, me6000_ao_subdevice_t, ao_control_task);
-#endif
PINFO("<%s: %ld> executed. idx=%d\n", __func__, jiffies,
instance->ao_idx);
@@ -3555,7 +3529,7 @@ static void me6000_ao_work_control_task(
}
-static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_by_min_max(me_subdevice_t *subdevice,
int unit,
int *min,
int *max, int *maxdata, int *range)
@@ -3589,7 +3563,7 @@ static int me6000_ao_query_range_by_min_max(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_ranges(me_subdevice_t *subdevice,
int unit, int *count)
{
me6000_ao_subdevice_t *instance;
@@ -3607,7 +3581,7 @@ static int me6000_ao_query_number_ranges(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
+static int me6000_ao_query_range_info(me_subdevice_t *subdevice,
int range,
int *unit,
int *min, int *max, int *maxdata)
@@ -3631,7 +3605,7 @@ static int me6000_ao_query_range_info(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_timer(me_subdevice_t * subdevice,
+static int me6000_ao_query_timer(me_subdevice_t *subdevice,
int timer,
int *base_frequency,
long long *min_ticks, long long *max_ticks)
@@ -3660,7 +3634,7 @@ static int me6000_ao_query_timer(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_ao_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
me6000_ao_subdevice_t *instance;
@@ -3672,7 +3646,7 @@ static int me6000_ao_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_ao_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
me6000_ao_subdevice_t *instance;
@@ -3690,7 +3664,7 @@ static int me6000_ao_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_ao_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me6000_ao_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
me6000_ao_subdevice_t *instance;
instance = (me6000_ao_subdevice_t *) subdevice;
diff --git a/drivers/staging/meilhaus/me6000_ao.h b/drivers/staging/meilhaus/me6000_ao.h
index 9629649cd41..ef4d0189bde 100644
--- a/drivers/staging/meilhaus/me6000_ao.h
+++ b/drivers/staging/meilhaus/me6000_ao.h
@@ -160,11 +160,7 @@ typedef struct me6000_ao_subdevice {
wait_queue_head_t wait_queue; /**< Wait queue to put on tasks waiting for data to arrive. */
struct workqueue_struct *me6000_workqueue;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
- struct work_struct ao_control_task;
-#else
struct delayed_work ao_control_task;
-#endif
volatile int ao_control_task_flag; /**< Flag controling reexecuting of control task */
diff --git a/drivers/staging/meilhaus/me6000_device.c b/drivers/staging/meilhaus/me6000_device.c
index fee4c58b846..1a6cf7f4325 100644
--- a/drivers/staging/meilhaus/me6000_device.c
+++ b/drivers/staging/meilhaus/me6000_device.c
@@ -178,6 +178,7 @@ me_device_t *me6000_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me6000_device;
}
+EXPORT_SYMBOL(me6000_pci_constructor);
// Init and exit of module.
@@ -206,6 +207,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Device Driver Module for ME-6000 Device");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-6000 Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me6000_pci_constructor);
diff --git a/drivers/staging/meilhaus/me6000_dio.c b/drivers/staging/meilhaus/me6000_dio.c
index 07f1069f9ac..c90686efc38 100644
--- a/drivers/staging/meilhaus/me6000_dio.c
+++ b/drivers/staging/meilhaus/me6000_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -91,7 +91,7 @@ static int me6000_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_dio_io_single_config(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -161,7 +161,7 @@ static int me6000_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me6000_dio_io_single_read(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -233,7 +233,7 @@ static int me6000_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me6000_dio_io_single_write(me_subdevice_t * subdevice,
+static int me6000_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -314,7 +314,7 @@ static int me6000_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me6000_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me6000_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -322,7 +322,7 @@ static int me6000_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me6000_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -331,7 +331,7 @@ static int me6000_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me6000_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me6000_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -341,7 +341,7 @@ static int me6000_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me6000_dio_subdevice_t *me6000_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me6000_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8100_device.c b/drivers/staging/meilhaus/me8100_device.c
index 1fb79e49026..41a9345cee5 100644
--- a/drivers/staging/meilhaus/me8100_device.c
+++ b/drivers/staging/meilhaus/me8100_device.c
@@ -159,6 +159,7 @@ me_device_t *me8100_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me8100_device;
}
+EXPORT_SYMBOL(me8100_pci_constructor);
// Init and exit of module.
@@ -182,6 +183,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Template Device");
MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me8100_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8100_di.c b/drivers/staging/meilhaus/me8100_di.c
index 971727c9e30..301dbd8f96a 100644
--- a/drivers/staging/meilhaus/me8100_di.c
+++ b/drivers/staging/meilhaus/me8100_di.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/version.h>
@@ -114,7 +114,7 @@ static int me8100_di_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -208,7 +208,7 @@ static int me8100_di_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -315,7 +315,7 @@ static int me8100_di_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8100_di_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags)
{
me8100_di_subdevice_t *instance;
@@ -358,7 +358,7 @@ static int me8100_di_io_irq_stop(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_io_single_config(me_subdevice_t * subdevice,
+static int me8100_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -405,7 +405,7 @@ static int me8100_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_io_single_read(me_subdevice_t * subdevice,
+static int me8100_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -466,7 +466,7 @@ static int me8100_di_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8100_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8100_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -474,7 +474,7 @@ static int me8100_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8100_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -483,7 +483,7 @@ static int me8100_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8100_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_DIO_BIT_PATTERN_IRQ | ME_CAPS_DIO_BIT_MASK_IRQ_EDGE_ANY;
@@ -503,11 +503,7 @@ static void me8100_di_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8100_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8100_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8100_di_subdevice_t *instance;
uint32_t icsr;
@@ -598,7 +594,7 @@ me8100_di_subdevice_t *me8100_di_constructor(uint32_t me8100_reg_base,
uint32_t plx_reg_base,
unsigned int di_idx,
int irq,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8100_di_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8100_do.c b/drivers/staging/meilhaus/me8100_do.c
index 957b9f92f76..81651a90cc0 100644
--- a/drivers/staging/meilhaus/me8100_do.c
+++ b/drivers/staging/meilhaus/me8100_do.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -92,7 +92,7 @@ static int me8100_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_do_io_single_config(me_subdevice_t * subdevice,
+static int me8100_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -158,7 +158,7 @@ static int me8100_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8100_do_io_single_read(me_subdevice_t * subdevice,
+static int me8100_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -215,7 +215,7 @@ static int me8100_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8100_do_io_single_write(me_subdevice_t * subdevice,
+static int me8100_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -297,7 +297,7 @@ static int me8100_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me8100_do_query_number_channels(me_subdevice_t * subdevice,
+static int me8100_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -305,7 +305,7 @@ static int me8100_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8100_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -314,7 +314,7 @@ static int me8100_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8100_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8100_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_DIO_SINK_SOURCE;
@@ -323,7 +323,7 @@ static int me8100_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
me8100_do_subdevice_t *me8100_do_constructor(uint32_t reg_base,
unsigned int do_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8100_do_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8200_device.c b/drivers/staging/meilhaus/me8200_device.c
index 261c0cbd9d0..b313679fc5c 100644
--- a/drivers/staging/meilhaus/me8200_device.c
+++ b/drivers/staging/meilhaus/me8200_device.c
@@ -166,6 +166,7 @@ me_device_t *me8200_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) me8200_device;
}
+EXPORT_SYMBOL(me8200_pci_constructor);
// Init and exit of module.
@@ -189,6 +190,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Template Device");
MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(me8200_pci_constructor);
diff --git a/drivers/staging/meilhaus/me8200_di.c b/drivers/staging/meilhaus/me8200_di.c
index 27525bc067b..a931fb817c7 100644
--- a/drivers/staging/meilhaus/me8200_di.c
+++ b/drivers/staging/meilhaus/me8200_di.c
@@ -34,7 +34,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/version.h>
@@ -50,52 +50,44 @@
/// Defines
static void me8200_di_destructor(struct me_subdevice *subdevice);
-static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
int irq_edge, int irq_arg, int flags);
-static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
int *value, int time_out, int flags);
-static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags);
-static int me8200_di_io_single_config(me_subdevice_t * subdevice,
+static int me8200_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
int ref,
int trig_chan,
int trig_type, int trig_edge, int flags);
-static int me8200_di_io_single_read(me_subdevice_t * subdevice,
+static int me8200_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags);
static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
struct file *filep, int flags);
-static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
int *number);
-static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype);
-static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr(int irq, void *dev_id);
-#else
-static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr_EX(int irq, void *dev_id);
-#else
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs);
-#endif
-static void me8200_di_check_version(me8200_di_subdevice_t * instance,
+static void me8200_di_check_version(me8200_di_subdevice_t *instance,
unsigned long addr);
///Functions
-static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -246,7 +238,7 @@ static int me8200_di_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -352,7 +344,7 @@ static int me8200_di_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_di_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags)
{
me8200_di_subdevice_t *instance;
@@ -406,7 +398,7 @@ static int me8200_di_io_irq_stop(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_di_io_single_config(me_subdevice_t * subdevice,
+static int me8200_di_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -453,7 +445,7 @@ static int me8200_di_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8200_di_io_single_read(me_subdevice_t * subdevice,
+static int me8200_di_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -518,7 +510,7 @@ static int me8200_di_io_reset_subdevice(struct me_subdevice *subdevice,
return me8200_di_io_irq_stop(subdevice, filep, 0, 0);
}
-static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_di_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -526,7 +518,7 @@ static int me8200_di_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_di_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -535,7 +527,7 @@ static int me8200_di_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8200_di_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps =
@@ -546,11 +538,7 @@ static int me8200_di_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
return ME_ERRNO_SUCCESS;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8200_di_subdevice_t *instance;
uint8_t ctrl;
@@ -629,11 +617,7 @@ static irqreturn_t me8200_isr(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_isr_EX(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_isr_EX(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8200_di_subdevice_t *instance;
uint8_t irq_status = 0;
@@ -715,8 +699,8 @@ static void me8200_di_destructor(struct me_subdevice *subdevice)
me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
unsigned int di_idx,
int irq,
- spinlock_t * irq_ctrl_lock,
- spinlock_t * irq_mode_lock)
+ spinlock_t *irq_ctrl_lock,
+ spinlock_t *irq_mode_lock)
{
me8200_di_subdevice_t *subdevice;
int err;
@@ -843,7 +827,7 @@ me8200_di_subdevice_t *me8200_di_constructor(uint32_t me8200_regbase,
return subdevice;
}
-static void me8200_di_check_version(me8200_di_subdevice_t * instance,
+static void me8200_di_check_version(me8200_di_subdevice_t *instance,
unsigned long addr)
{
diff --git a/drivers/staging/meilhaus/me8200_dio.c b/drivers/staging/meilhaus/me8200_dio.c
index ff8ca1b8b7f..c7f43f011f3 100644
--- a/drivers/staging/meilhaus/me8200_dio.c
+++ b/drivers/staging/meilhaus/me8200_dio.c
@@ -36,7 +36,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -90,7 +90,7 @@ static int me8200_dio_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_dio_io_single_config(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -164,7 +164,7 @@ static int me8200_dio_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8200_dio_io_single_read(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -241,7 +241,7 @@ static int me8200_dio_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8200_dio_io_single_write(me_subdevice_t * subdevice,
+static int me8200_dio_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -332,7 +332,7 @@ static int me8200_dio_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me8200_dio_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_dio_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -340,7 +340,7 @@ static int me8200_dio_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_dio_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_dio_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -349,7 +349,7 @@ static int me8200_dio_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_dio_query_subdevice_caps(me_subdevice_t * subdevice,
+static int me8200_dio_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -359,7 +359,7 @@ static int me8200_dio_query_subdevice_caps(me_subdevice_t * subdevice,
me8200_dio_subdevice_t *me8200_dio_constructor(uint32_t reg_base,
unsigned int dio_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8200_dio_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8200_do.c b/drivers/staging/meilhaus/me8200_do.c
index d2bebd16ff4..40d536c71d5 100644
--- a/drivers/staging/meilhaus/me8200_do.c
+++ b/drivers/staging/meilhaus/me8200_do.c
@@ -37,7 +37,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include <linux/version.h>
@@ -59,7 +59,7 @@
* Functions
*/
-static int me8200_do_io_irq_start(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_start(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int irq_source,
@@ -109,7 +109,7 @@ static int me8200_do_io_irq_start(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_irq_wait(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_wait(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *irq_count,
@@ -184,7 +184,7 @@ static int me8200_do_io_irq_wait(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_irq_stop(me_subdevice_t * subdevice,
+static int me8200_do_io_irq_stop(me_subdevice_t *subdevice,
struct file *filep, int channel, int flags)
{
me8200_do_subdevice_t *instance;
@@ -262,7 +262,7 @@ static int me8200_do_io_reset_subdevice(struct me_subdevice *subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_do_io_single_config(me_subdevice_t * subdevice,
+static int me8200_do_io_single_config(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int single_config,
@@ -307,7 +307,7 @@ static int me8200_do_io_single_config(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_single_read(me_subdevice_t * subdevice,
+static int me8200_do_io_single_read(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int *value, int time_out, int flags)
@@ -354,7 +354,7 @@ static int me8200_do_io_single_read(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_io_single_write(me_subdevice_t * subdevice,
+static int me8200_do_io_single_write(me_subdevice_t *subdevice,
struct file *filep,
int channel,
int value, int time_out, int flags)
@@ -415,7 +415,7 @@ static int me8200_do_io_single_write(me_subdevice_t * subdevice,
return err;
}
-static int me8200_do_query_number_channels(me_subdevice_t * subdevice,
+static int me8200_do_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -423,7 +423,7 @@ static int me8200_do_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_do_query_subdevice_type(me_subdevice_t * subdevice,
+static int me8200_do_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -432,7 +432,7 @@ static int me8200_do_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int me8200_do_query_subdevice_caps(me_subdevice_t * subdevice, int *caps)
+static int me8200_do_query_subdevice_caps(me_subdevice_t *subdevice, int *caps)
{
PDEBUG("executed.\n");
*caps = ME_CAPS_DIO_OVER_TEMP_IRQ;
@@ -452,11 +452,7 @@ static void me8200_do_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
static irqreturn_t me8200_do_isr(int irq, void *dev_id)
-#else
-static irqreturn_t me8200_do_isr(int irq, void *dev_id, struct pt_regs *regs)
-#endif
{
me8200_do_subdevice_t *instance;
uint16_t ctrl;
@@ -505,7 +501,7 @@ static irqreturn_t me8200_do_isr(int irq, void *dev_id, struct pt_regs *regs)
me8200_do_subdevice_t *me8200_do_constructor(uint32_t reg_base,
unsigned int do_idx,
int irq,
- spinlock_t * irq_mode_lock)
+ spinlock_t *irq_mode_lock)
{
me8200_do_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8254.c b/drivers/staging/meilhaus/me8254.c
index 6e44c3d7a0c..d8f742a8ca9 100644
--- a/drivers/staging/meilhaus/me8254.c
+++ b/drivers/staging/meilhaus/me8254.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -183,7 +183,7 @@ static int me8254_io_reset_subdevice(struct me_subdevice *subdevice,
return err;
}
-static int me1400_ab_ref_config(me8254_subdevice_t * instance, int ref)
+static int me1400_ab_ref_config(me8254_subdevice_t *instance, int ref)
{
uint8_t clk_src;
@@ -291,7 +291,7 @@ static int me1400_ab_ref_config(me8254_subdevice_t * instance, int ref)
return ME_ERRNO_SUCCESS;
}
-static int me1400_cd_ref_config(me8254_subdevice_t * instance, int ref)
+static int me1400_cd_ref_config(me8254_subdevice_t *instance, int ref)
{
uint8_t clk_src;
@@ -436,7 +436,7 @@ static int me1400_cd_ref_config(me8254_subdevice_t * instance, int ref)
return ME_ERRNO_SUCCESS;
}
-static int me4600_ref_config(me8254_subdevice_t * instance, int ref)
+static int me4600_ref_config(me8254_subdevice_t *instance, int ref)
{
switch (ref) {
@@ -453,7 +453,7 @@ static int me4600_ref_config(me8254_subdevice_t * instance, int ref)
return ME_ERRNO_SUCCESS;
}
-static int me8100_ref_config(me8254_subdevice_t * instance, int ref)
+static int me8100_ref_config(me8254_subdevice_t *instance, int ref)
{
switch (ref) {
@@ -962,8 +962,8 @@ me8254_subdevice_t *me8254_constructor(uint32_t device_id,
uint32_t reg_base,
unsigned int me8254_idx,
unsigned int ctr_idx,
- spinlock_t * ctrl_reg_lock,
- spinlock_t * clk_src_reg_lock)
+ spinlock_t *ctrl_reg_lock,
+ spinlock_t *clk_src_reg_lock)
{
me8254_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/me8255.c b/drivers/staging/meilhaus/me8255.c
index 180e7f8d214..ec9c6389752 100644
--- a/drivers/staging/meilhaus/me8255.c
+++ b/drivers/staging/meilhaus/me8255.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -318,7 +318,7 @@ me8255_subdevice_t *me8255_constructor(uint32_t device_id,
unsigned int me8255_idx,
unsigned int dio_idx,
int *ctrl_reg_mirror,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
me8255_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/meilhaus/mecirc_buf.h b/drivers/staging/meilhaus/mecirc_buf.h
index e9b591eaa34..516658522ef 100644
--- a/drivers/staging/meilhaus/mecirc_buf.h
+++ b/drivers/staging/meilhaus/mecirc_buf.h
@@ -40,19 +40,19 @@ typedef struct me_circ_buf {
int volatile tail;
} me_circ_buf_t;
-static int inline me_circ_buf_values(me_circ_buf_t * buf)
+static inline int me_circ_buf_values(me_circ_buf_t * buf)
{
// return ((buf->head - buf->tail) & (buf->count - 1));
return ((buf->head - buf->tail) & (buf->mask));
}
-static int inline me_circ_buf_space(me_circ_buf_t * buf)
+static inline int me_circ_buf_space(me_circ_buf_t * buf)
{
// return ((buf->tail - (buf->head + 1)) & (buf->count - 1));
return ((buf->tail - (buf->head + 1)) & (buf->mask));
}
-static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
{
int end;
int n;
@@ -63,7 +63,7 @@ static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
return (n < end) ? n : end;
}
-static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
{
int end;
int n;
@@ -99,19 +99,19 @@ typedef struct me_circ_buf_16b {
# endif //_CBUFF_32b_t
/** How many values is in buffer */
-static int inline me_circ_buf_values(me_circ_buf_t * buf)
+static inline int me_circ_buf_values(me_circ_buf_t * buf)
{
return ((buf->head - buf->tail) & (buf->mask));
}
/** How many space left */
-static int inline me_circ_buf_space(me_circ_buf_t * buf)
+static inline int me_circ_buf_space(me_circ_buf_t * buf)
{
return ((buf->tail - (buf->head + 1)) & (buf->mask));
}
/** How many values can be read from buffor in one chunck. */
-static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_values_to_end(me_circ_buf_t * buf)
{
return (buf->tail <=
buf->head) ? (buf->head - buf->tail) : (buf->mask - buf->tail +
@@ -119,7 +119,7 @@ static int inline me_circ_buf_values_to_end(me_circ_buf_t * buf)
}
/** How many values can be write to buffer in one chunck. */
-static int inline me_circ_buf_space_to_end(me_circ_buf_t * buf)
+static inline int me_circ_buf_space_to_end(me_circ_buf_t * buf)
{
return (buf->tail <=
buf->head) ? (buf->mask - buf->head + 1) : (buf->tail -
diff --git a/drivers/staging/meilhaus/medevice.c b/drivers/staging/meilhaus/medevice.c
index 8f62e16c7a3..75aaec0f681 100644
--- a/drivers/staging/meilhaus/medevice.c
+++ b/drivers/staging/meilhaus/medevice.c
@@ -390,9 +390,9 @@ static int me_device_io_single_write(struct me_device *device,
static int me_device_io_stream_config(struct me_device *device,
struct file *filep,
int subdevice,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
int err = ME_ERRNO_SUCCESS;
@@ -1040,7 +1040,7 @@ static int me_device_query_timer(struct me_device *device,
int subdevice,
int timer,
int *base_frequency,
- uint64_t * min_ticks, uint64_t * max_ticks)
+ uint64_t *min_ticks, uint64_t *max_ticks)
{
int err = ME_ERRNO_SUCCESS;
me_subdevice_t *s;
@@ -1082,14 +1082,14 @@ static int me_device_query_version_device_driver(struct me_device *device,
}
static int me_device_config_load(struct me_device *device, struct file *filep,
- me_cfg_device_entry_t * config)
+ me_cfg_device_entry_t *config)
{
PDEBUG("executed.\n");
return ME_ERRNO_SUCCESS; //If no need for config return success.
// return ME_ERRNO_NOT_SUPPORTED;
}
-static void me_device_destructor(me_device_t * me_device)
+static void me_device_destructor(me_device_t *me_device)
{
PDEBUG("executed.\n");
me_device_deinit(me_device);
@@ -1581,7 +1581,7 @@ static int get_device_descriptions(uint16_t device_id,
return 0;
}
-int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device)
+int me_device_pci_init(me_device_t *me_device, struct pci_dev *pci_device)
{
int err;
int i;
@@ -1720,7 +1720,7 @@ int me_device_pci_init(me_device_t * me_device, struct pci_dev *pci_device)
return 1;
}
-void me_device_deinit(me_device_t * me_device)
+void me_device_deinit(me_device_t *me_device)
{
PDEBUG("executed.\n");
diff --git a/drivers/staging/meilhaus/medlist.c b/drivers/staging/meilhaus/medlist.c
index ef4e36955dc..b6a4065d2da 100644
--- a/drivers/staging/meilhaus/medlist.c
+++ b/drivers/staging/meilhaus/medlist.c
@@ -69,7 +69,7 @@ me_device_t *me_dlist_get_device(struct me_dlist * dlist, unsigned int index)
return device;
}
-void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t * device)
+void me_dlist_add_device_tail(struct me_dlist *dlist, me_device_t *device)
{
PDEBUG_LOCKS("called.\n");
@@ -99,7 +99,7 @@ me_device_t *me_dlist_del_device_tail(struct me_dlist *dlist)
return device;
}
-int me_dlist_init(me_dlist_t * dlist)
+int me_dlist_init(me_dlist_t *dlist)
{
PDEBUG_LOCKS("called.\n");
@@ -108,7 +108,7 @@ int me_dlist_init(me_dlist_t * dlist)
return 0;
}
-void me_dlist_deinit(me_dlist_t * dlist)
+void me_dlist_deinit(me_dlist_t *dlist)
{
struct list_head *s;
diff --git a/drivers/staging/meilhaus/medlock.c b/drivers/staging/meilhaus/medlock.c
index f649e3da4f0..8ded397214f 100644
--- a/drivers/staging/meilhaus/medlock.c
+++ b/drivers/staging/meilhaus/medlock.c
@@ -65,7 +65,7 @@ int me_dlock_exit(struct me_dlock *dlock, struct file *filep)
}
int me_dlock_lock(struct me_dlock *dlock,
- struct file *filep, int lock, int flags, me_slist_t * slist)
+ struct file *filep, int lock, int flags, me_slist_t *slist)
{
int err = ME_ERRNO_SUCCESS;
int i;
@@ -183,7 +183,7 @@ void me_dlock_deinit(struct me_dlock *dlock)
PDEBUG_LOCKS("executed.\n");
}
-int me_dlock_init(me_dlock_t * dlock)
+int me_dlock_init(me_dlock_t *dlock)
{
PDEBUG_LOCKS("executed.\n");
diff --git a/drivers/staging/meilhaus/medummy.c b/drivers/staging/meilhaus/medummy.c
index 6a9f08d50bb..2423745f957 100644
--- a/drivers/staging/meilhaus/medummy.c
+++ b/drivers/staging/meilhaus/medummy.c
@@ -47,7 +47,7 @@
#include "medummy.h"
-static int medummy_io_irq_start(me_device_t * device,
+static int medummy_io_irq_start(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -58,7 +58,7 @@ static int medummy_io_irq_start(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_irq_wait(me_device_t * device,
+static int medummy_io_irq_wait(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -69,7 +69,7 @@ static int medummy_io_irq_wait(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_irq_stop(me_device_t * device,
+static int medummy_io_irq_stop(me_device_t *device,
struct file *filep,
int subdevice, int channel, int flags)
{
@@ -77,14 +77,14 @@ static int medummy_io_irq_stop(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_reset_device(me_device_t * device,
+static int medummy_io_reset_device(me_device_t *device,
struct file *filep, int flags)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_reset_subdevice(me_device_t * device,
+static int medummy_io_reset_subdevice(me_device_t *device,
struct file *filep,
int subdevice, int flags)
{
@@ -92,7 +92,7 @@ static int medummy_io_reset_subdevice(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_single_config(me_device_t * device,
+static int medummy_io_single_config(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -105,7 +105,7 @@ static int medummy_io_single_config(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_single_read(me_device_t * device,
+static int medummy_io_single_read(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -115,7 +115,7 @@ static int medummy_io_single_read(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_single_write(me_device_t * device,
+static int medummy_io_single_write(me_device_t *device,
struct file *filep,
int subdevice,
int channel,
@@ -125,19 +125,19 @@ static int medummy_io_single_write(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_config(me_device_t * device,
+static int medummy_io_stream_config(me_device_t *device,
struct file *filep,
int subdevice,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_new_values(me_device_t * device,
+static int medummy_io_stream_new_values(me_device_t *device,
struct file *filep,
int subdevice,
int timeout, int *count, int flags)
@@ -146,7 +146,7 @@ static int medummy_io_stream_new_values(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_read(me_device_t * device,
+static int medummy_io_stream_read(me_device_t *device,
struct file *filep,
int subdevice,
int read_mode,
@@ -156,7 +156,7 @@ static int medummy_io_stream_read(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_start(me_device_t * device,
+static int medummy_io_stream_start(me_device_t *device,
struct file *filep,
int subdevice,
int start_mode, int time_out, int flags)
@@ -165,7 +165,7 @@ static int medummy_io_stream_start(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_status(me_device_t * device,
+static int medummy_io_stream_status(me_device_t *device,
struct file *filep,
int subdevice,
int wait,
@@ -175,7 +175,7 @@ static int medummy_io_stream_status(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_stop(me_device_t * device,
+static int medummy_io_stream_stop(me_device_t *device,
struct file *filep,
int subdevice, int stop_mode, int flags)
{
@@ -183,7 +183,7 @@ static int medummy_io_stream_stop(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_io_stream_write(me_device_t * device,
+static int medummy_io_stream_write(me_device_t *device,
struct file *filep,
int subdevice,
int write_mode,
@@ -193,14 +193,14 @@ static int medummy_io_stream_write(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_lock_device(me_device_t * device,
+static int medummy_lock_device(me_device_t *device,
struct file *filep, int lock, int flags)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_lock_subdevice(me_device_t * device,
+static int medummy_lock_subdevice(me_device_t *device,
struct file *filep,
int subdevice, int lock, int flags)
{
@@ -208,7 +208,7 @@ static int medummy_lock_subdevice(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_description_device(me_device_t * device,
+static int medummy_query_description_device(me_device_t *device,
char **description)
{
medummy_device_t *instance = (medummy_device_t *) device;
@@ -602,7 +602,7 @@ static int medummy_query_description_device(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_info_device(me_device_t * device,
+static int medummy_query_info_device(me_device_t *device,
int *vendor_id,
int *device_id,
int *serial_no,
@@ -632,14 +632,14 @@ static int medummy_query_info_device(me_device_t * device,
return ME_ERRNO_SUCCESS;
}
-static int medummy_query_name_device_driver(me_device_t * device, char **name)
+static int medummy_query_name_device_driver(me_device_t *device, char **name)
{
PDEBUG("executed.\n");
*name = MEDUMMY_NAME_DRIVER;
return ME_ERRNO_SUCCESS;
}
-static int medummy_query_name_device(me_device_t * device, char **name)
+static int medummy_query_name_device(me_device_t *device, char **name)
{
medummy_device_t *instance = (medummy_device_t *) device;
@@ -1012,41 +1012,41 @@ static int medummy_query_name_device(me_device_t * device, char **name)
return ME_ERRNO_SUCCESS;
}
-static int medummy_query_number_subdevices(me_device_t * device, int *number)
+static int medummy_query_number_subdevices(me_device_t *device, int *number)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_number_channels(me_device_t * device,
+static int medummy_query_number_channels(me_device_t *device,
int subdevice, int *number)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_number_ranges(me_device_t * device,
+static int medummy_query_number_ranges(me_device_t *device,
int subdevice, int unit, int *count)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_subdevice_type(me_device_t * device,
+static int medummy_query_subdevice_type(me_device_t *device,
int subdevice, int *type, int *subtype)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_subdevice_caps(me_device_t * device,
+static int medummy_query_subdevice_caps(me_device_t *device,
int subdevice, int *caps)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_subdevice_caps_args(me_device_t * device,
+static int medummy_query_subdevice_caps_args(me_device_t *device,
int subdevice,
int cap, int *args, int count)
{
@@ -1054,7 +1054,7 @@ static int medummy_query_subdevice_caps_args(me_device_t * device,
return ME_ERRNO_NOT_SUPPORTED;
}
-static int medummy_query_subdevice_by_type(me_device_t * device,
+static int medummy_query_subdevice_by_type(me_device_t *device,
int start_subdevice,
int type,
int subtype, int *subdevice)
@@ -1063,7 +1063,7 @@ static int medummy_query_subdevice_by_type(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_range_by_min_max(me_device_t * device,
+static int medummy_query_range_by_min_max(me_device_t *device,
int subdevice,
int unit,
int *min,
@@ -1073,7 +1073,7 @@ static int medummy_query_range_by_min_max(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_range_info(me_device_t * device,
+static int medummy_query_range_info(me_device_t *device,
int subdevice,
int range,
int *unit, int *min, int *max, int *maxdata)
@@ -1082,17 +1082,17 @@ static int medummy_query_range_info(me_device_t * device,
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-int medummy_query_timer(me_device_t * device,
+int medummy_query_timer(me_device_t *device,
int subdevice,
int timer,
int *base_frequency,
- uint64_t * min_ticks, uint64_t * max_ticks)
+ uint64_t *min_ticks, uint64_t *max_ticks)
{
PDEBUG("executed.\n");
return ME_ERRNO_DEVICE_UNPLUGGED;
}
-static int medummy_query_version_device_driver(me_device_t * device,
+static int medummy_query_version_device_driver(me_device_t *device,
int *version)
{
PDEBUG("executed.\n");
@@ -1101,7 +1101,7 @@ static int medummy_query_version_device_driver(me_device_t * device,
return ME_ERRNO_SUCCESS;
}
-static void medummy_destructor(me_device_t * device)
+static void medummy_destructor(me_device_t *device)
{
PDEBUG("executed.\n");
kfree(device);
@@ -1113,7 +1113,7 @@ static int init_device_info(unsigned short vendor_id,
int bus_type,
int bus_no,
int dev_no,
- int func_no, medummy_device_t * instance)
+ int func_no, medummy_device_t *instance)
{
PDEBUG("executed.\n");
@@ -1129,14 +1129,14 @@ static int init_device_info(unsigned short vendor_id,
return 0;
}
-static int medummy_config_load(me_device_t * device, struct file *filep,
- me_cfg_device_entry_t * config)
+static int medummy_config_load(me_device_t *device, struct file *filep,
+ me_cfg_device_entry_t *config)
{
PDEBUG("executed.\n");
return ME_ERRNO_SUCCESS;
}
-static int init_device_instance(me_device_t * device)
+static int init_device_instance(me_device_t *device)
{
PDEBUG("executed.\n");
@@ -1238,6 +1238,7 @@ me_device_t *medummy_constructor(unsigned short vendor_id,
return (me_device_t *) instance;
}
+EXPORT_SYMBOL(medummy_constructor);
// Init and exit of module.
@@ -1261,6 +1262,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Meilhaus ME-DUMMY Devices");
MODULE_SUPPORTED_DEVICE("Meilhaus ME-DUMMY Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(medummy_constructor);
diff --git a/drivers/staging/meilhaus/memain.c b/drivers/staging/meilhaus/memain.c
index b09d1a6c766..fd9f079b0ed 100644
--- a/drivers/staging/meilhaus/memain.c
+++ b/drivers/staging/meilhaus/memain.c
@@ -37,7 +37,7 @@
#include <linux/pci.h>
//#include <linux/usb.h>
#include <linux/errno.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <linux/cdev.h>
#include <linux/rwsem.h>
@@ -56,6 +56,7 @@
#ifdef BOSCH
static unsigned int me_bosch_fw = 0;
+EXPORT_SYMBOL(me_bosch_fw);
# ifdef module_param
module_param(me_bosch_fw, int, S_IRUGO);
@@ -79,7 +80,7 @@ MODULE_PARM(major, "i");
static struct file *me_filep = NULL;
static int me_count = 0;
-static spinlock_t me_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(me_lock);
static DECLARE_RWSEM(me_rwsem);
/* Board instances are kept in a global list */
@@ -90,7 +91,7 @@ LIST_HEAD(me_device_list);
static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id);
static void me_remove_pci(struct pci_dev *dev);
-static int insert_to_device_list(me_device_t * n_device);
+static int insert_to_device_list(me_device_t *n_device);
static int replace_with_dummy(int vendor_id, int device_id, int serial_no);
static void clear_device_list(void);
static int me_open(struct inode *inode_ptr, struct file *filep);
@@ -472,7 +473,7 @@ static int me_probe_pci(struct pci_dev *dev, const struct pci_device_id *id)
return ME_ERRNO_SUCCESS;
}
-static void release_instance(me_device_t * device)
+static void release_instance(me_device_t *device)
{
int vendor_id;
int device_id;
@@ -517,7 +518,7 @@ static void release_instance(me_device_t * device)
}
}
-static int insert_to_device_list(me_device_t * n_device)
+static int insert_to_device_list(me_device_t *n_device)
{
me_device_t *o_device = NULL;
@@ -762,7 +763,7 @@ static int lock_driver(struct file *filep, int lock, int flags)
return err;
}
-static int me_lock_driver(struct file *filep, me_lock_driver_t * arg)
+static int me_lock_driver(struct file *filep, me_lock_driver_t *arg)
{
int err = 0;
@@ -807,7 +808,7 @@ static int me_release(struct inode *inode_ptr, struct file *filep)
}
static int me_query_version_main_driver(struct file *filep,
- me_query_version_main_driver_t * arg)
+ me_query_version_main_driver_t *arg)
{
int err;
me_query_version_main_driver_t karg;
@@ -828,7 +829,7 @@ static int me_query_version_main_driver(struct file *filep,
}
static int me_config_load_device(struct file *filep,
- me_cfg_device_entry_t * karg, int device_no)
+ me_cfg_device_entry_t *karg, int device_no)
{
int err = ME_ERRNO_SUCCESS;
@@ -874,7 +875,7 @@ static int me_config_load_device(struct file *filep,
return err;
}
-static int me_config_load(struct file *filep, me_config_load_t * arg)
+static int me_config_load(struct file *filep, me_config_load_t *arg)
{
int err;
int i;
@@ -1170,7 +1171,7 @@ static int me_config_load(struct file *filep, me_config_load_t * arg)
return 0;
}
-static int me_io_stream_start(struct file *filep, me_io_stream_start_t * arg)
+static int me_io_stream_start(struct file *filep, me_io_stream_start_t *arg)
{
int err;
int i, k;
@@ -1292,7 +1293,7 @@ static int me_io_stream_start(struct file *filep, me_io_stream_start_t * arg)
return err;
}
-static int me_io_single(struct file *filep, me_io_single_t * arg)
+static int me_io_single(struct file *filep, me_io_single_t *arg)
{
int err;
int i, k;
@@ -1448,7 +1449,7 @@ static int me_io_single(struct file *filep, me_io_single_t * arg)
return err;
}
-static int me_io_stream_config(struct file *filep, me_io_stream_config_t * arg)
+static int me_io_stream_config(struct file *filep, me_io_stream_config_t *arg)
{
int err;
int k = 0;
@@ -1540,7 +1541,7 @@ static int me_io_stream_config(struct file *filep, me_io_stream_config_t * arg)
}
static int me_query_number_devices(struct file *filep,
- me_query_number_devices_t * arg)
+ me_query_number_devices_t *arg)
{
int err;
me_query_number_devices_t karg;
@@ -1569,7 +1570,7 @@ static int me_query_number_devices(struct file *filep,
return 0;
}
-static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t * arg)
+static int me_io_stream_stop(struct file *filep, me_io_stream_stop_t *arg)
{
int err;
int i, k;
@@ -2015,8 +2016,3 @@ MODULE_AUTHOR
MODULE_DESCRIPTION("Central module for Meilhaus Driver System.");
MODULE_SUPPORTED_DEVICE("Meilhaus PCI/cPCI boards.");
MODULE_LICENSE("GPL");
-
-#ifdef BOSCH
-// Export the flag for the BOSCH firmware.
-EXPORT_SYMBOL(me_bosch_fw);
-#endif // BOSCH
diff --git a/drivers/staging/meilhaus/meslist.c b/drivers/staging/meilhaus/meslist.c
index 7e8b66c05f7..ce49114df55 100644
--- a/drivers/staging/meilhaus/meslist.c
+++ b/drivers/staging/meilhaus/meslist.c
@@ -115,7 +115,7 @@ int me_slist_get_subdevice_by_type(struct me_slist *slist,
}
void me_slist_add_subdevice_tail(struct me_slist *slist,
- me_subdevice_t * subdevice)
+ me_subdevice_t *subdevice)
{
PDEBUG_LOCKS("called.\n");
@@ -145,7 +145,7 @@ me_subdevice_t *me_slist_del_subdevice_tail(struct me_slist *slist)
return subdevice;
}
-int me_slist_init(me_slist_t * slist)
+int me_slist_init(me_slist_t *slist)
{
PDEBUG_LOCKS("called.\n");
@@ -154,7 +154,7 @@ int me_slist_init(me_slist_t * slist)
return 0;
}
-void me_slist_deinit(me_slist_t * slist)
+void me_slist_deinit(me_slist_t *slist)
{
struct list_head *s;
diff --git a/drivers/staging/meilhaus/meslock.c b/drivers/staging/meilhaus/meslock.c
index 5230b89b45b..abcdb4a2eba 100644
--- a/drivers/staging/meilhaus/meslock.c
+++ b/drivers/staging/meilhaus/meslock.c
@@ -124,7 +124,7 @@ void me_slock_deinit(struct me_slock *slock)
PDEBUG_LOCKS("executed.\n");
}
-int me_slock_init(me_slock_t * slock)
+int me_slock_init(me_slock_t *slock)
{
PDEBUG_LOCKS("executed.\n");
diff --git a/drivers/staging/meilhaus/mesubdevice.c b/drivers/staging/meilhaus/mesubdevice.c
index 98d4f1f7a82..b2e956726b5 100644
--- a/drivers/staging/meilhaus/mesubdevice.c
+++ b/drivers/staging/meilhaus/mesubdevice.c
@@ -101,9 +101,9 @@ static int me_subdevice_io_single_write(struct me_subdevice *subdevice,
static int me_subdevice_io_stream_config(struct me_subdevice *subdevice,
struct file *filep,
- meIOStreamConfig_t * config_list,
+ meIOStreamConfig_t *config_list,
int count,
- meIOStreamTrigger_t * trigger,
+ meIOStreamTrigger_t *trigger,
int fifo_irq_threshold, int flags)
{
PDEBUG("executed.\n");
@@ -162,7 +162,7 @@ static int me_subdevice_io_stream_write(struct me_subdevice *subdevice,
return ME_ERRNO_NOT_SUPPORTED;
}
-static int me_subdevice_lock_subdevice(me_subdevice_t * subdevice,
+static int me_subdevice_lock_subdevice(me_subdevice_t *subdevice,
struct file *filep, int lock, int flags)
{
PDEBUG("executed.\n");
@@ -235,7 +235,7 @@ static int me_subdevice_query_timer(struct me_subdevice *subdevice,
}
static int me_subdevice_config_load(struct me_subdevice *subdevice,
- me_cfg_device_entry_t * config)
+ me_cfg_device_entry_t *config)
{
PDEBUG("executed.\n");
return ME_ERRNO_SUCCESS;
@@ -248,7 +248,7 @@ static void me_subdevice_destructor(struct me_subdevice *subdevice)
kfree(subdevice);
}
-int me_subdevice_init(me_subdevice_t * subdevice)
+int me_subdevice_init(me_subdevice_t *subdevice)
{
int err;
@@ -308,7 +308,7 @@ int me_subdevice_init(me_subdevice_t * subdevice)
return 0;
}
-void me_subdevice_deinit(me_subdevice_t * subdevice)
+void me_subdevice_deinit(me_subdevice_t *subdevice)
{
PDEBUG("executed.\n");
me_subdevice_io_reset_subdevice(subdevice, NULL,
diff --git a/drivers/staging/meilhaus/metempl_device.c b/drivers/staging/meilhaus/metempl_device.c
index e48632ddc1a..bdaf6df7277 100644
--- a/drivers/staging/meilhaus/metempl_device.c
+++ b/drivers/staging/meilhaus/metempl_device.c
@@ -109,6 +109,7 @@ me_device_t *metempl_pci_constructor(struct pci_dev *pci_device)
return (me_device_t *) metempl_device;
}
+EXPORT_SYMBOL(metempl_pci_constructor);
// Init and exit of module.
@@ -132,6 +133,3 @@ MODULE_AUTHOR("Guenter Gebhardt <g.gebhardt@meilhaus.de>");
MODULE_DESCRIPTION("Device Driver Module for Template Device");
MODULE_SUPPORTED_DEVICE("Meilhaus Template Devices");
MODULE_LICENSE("GPL");
-
-// Export the constructor.
-EXPORT_SYMBOL(metempl_pci_constructor);
diff --git a/drivers/staging/meilhaus/metempl_sub.c b/drivers/staging/meilhaus/metempl_sub.c
index f1d65d889e2..b5a6a978b50 100644
--- a/drivers/staging/meilhaus/metempl_sub.c
+++ b/drivers/staging/meilhaus/metempl_sub.c
@@ -35,7 +35,7 @@
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/types.h>
#include "medefines.h"
@@ -68,7 +68,7 @@ static void metempl_sub_destructor(struct me_subdevice *subdevice)
kfree(instance);
}
-static int metempl_sub_query_number_channels(me_subdevice_t * subdevice,
+static int metempl_sub_query_number_channels(me_subdevice_t *subdevice,
int *number)
{
PDEBUG("executed.\n");
@@ -76,7 +76,7 @@ static int metempl_sub_query_number_channels(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int metempl_sub_query_subdevice_type(me_subdevice_t * subdevice,
+static int metempl_sub_query_subdevice_type(me_subdevice_t *subdevice,
int *type, int *subtype)
{
PDEBUG("executed.\n");
@@ -85,7 +85,7 @@ static int metempl_sub_query_subdevice_type(me_subdevice_t * subdevice,
return ME_ERRNO_SUCCESS;
}
-static int metempl_sub_query_subdevice_caps(me_subdevice_t * subdevice,
+static int metempl_sub_query_subdevice_caps(me_subdevice_t *subdevice,
int *caps)
{
PDEBUG("executed.\n");
@@ -95,7 +95,7 @@ static int metempl_sub_query_subdevice_caps(me_subdevice_t * subdevice,
metempl_sub_subdevice_t *metempl_sub_constructor(uint32_t reg_base,
unsigned int sub_idx,
- spinlock_t * ctrl_reg_lock)
+ spinlock_t *ctrl_reg_lock)
{
metempl_sub_subdevice_t *subdevice;
int err;
diff --git a/drivers/staging/mimio/Kconfig b/drivers/staging/mimio/Kconfig
index c0ba4c800df..505dcb27579 100644
--- a/drivers/staging/mimio/Kconfig
+++ b/drivers/staging/mimio/Kconfig
@@ -1,6 +1,6 @@
config INPUT_MIMIO
tristate "Mimio Xi interactive whiteboard support"
- depends on USB
+ depends on USB && INPUT
default N
help
Say Y here if you want to use a Mimio Xi interactive
diff --git a/drivers/staging/otus/80211core/amsdu.c b/drivers/staging/otus/80211core/amsdu.c
index c9123d58b82..0321288d107 100644
--- a/drivers/staging/otus/80211core/amsdu.c
+++ b/drivers/staging/otus/80211core/amsdu.c
@@ -34,53 +34,53 @@
/* Stephen Chen Atheros Communications, INC. 2007.2 */
/* */
/************************************************************************/
-zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset)
+zbuf_t *zfGetAmsduSubFrame(zdev_t *dev, zbuf_t *buf, u16_t *offset)
{
- u16_t subframeLen;
- u16_t amsduLen = zfwBufGetSize(dev, buf);
- zbuf_t* newBuf;
-
- ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
-
- /* Verify A-MSDU length */
- if (amsduLen < (*offset + 14))
- {
- return NULL;
- }
-
- /* Locate A-MSDU subframe by offset and verify subframe length */
- subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
- zmw_buf_readb(dev, buf, *offset + 13);
- if (subframeLen == 0)
- {
- return NULL;
- }
-
- /* Verify A-MSDU subframe length */
- if ((*offset+14+subframeLen) <= amsduLen)
- {
- /* Allocate a new buffer */
- if ((newBuf = zfwBufAllocate(dev, 24+2+subframeLen)) != NULL)
- {
-#ifdef ZM_ENABLE_NATIVE_WIFI
- /* Copy and convert subframe to wlan frame format */
- /* SHALL NOT INCLUDE QOS and AMSDU header. Ray 20070807 For Vista */
- zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
- zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14, subframeLen);
- zfwBufSetSize(dev, newBuf, 24+subframeLen);
-#else
- /* Copy subframe to new buffer */
- zfRxBufferCopy(dev, newBuf, buf, 0, *offset, 14+subframeLen);
- zfwBufSetSize(dev, newBuf, 14+subframeLen);
-#endif
- /* Update offset */
- *offset += (((14+subframeLen)+3) & 0xfffc);
-
- /* Return buffer pointer */
- return newBuf;
- }
- }
- return NULL;
+ u16_t subframeLen;
+ u16_t amsduLen = zfwBufGetSize(dev, buf);
+ zbuf_t *newBuf;
+
+ ZM_PERFORMANCE_RX_AMSDU(dev, buf, amsduLen);
+
+ /* Verify A-MSDU length */
+ if (amsduLen < (*offset + 14))
+ return NULL;
+
+ /* Locate A-MSDU subframe by offset and verify subframe length */
+ subframeLen = (zmw_buf_readb(dev, buf, *offset + 12) << 8) +
+ zmw_buf_readb(dev, buf, *offset + 13);
+
+ if (subframeLen == 0)
+ return NULL;
+
+ /* Verify A-MSDU subframe length */
+ if ((*offset+14+subframeLen) <= amsduLen) {
+ /* Allocate a new buffer */
+ newBuf = zfwBufAllocate(dev, 24+2+subframeLen);
+ if (newBuf != NULL) {
+ #ifdef ZM_ENABLE_NATIVE_WIFI
+ /* Copy and convert subframe to wlan frame format
+ * SHALL NOT INCLUDE QOS and AMSDU header.
+ * Ray 20070807 For Vista
+ */
+ zfRxBufferCopy(dev, newBuf, buf, 0, 0, 24);
+ zfRxBufferCopy(dev, newBuf, buf, 24, *offset+14,
+ subframeLen);
+ zfwBufSetSize(dev, newBuf, 24+subframeLen);
+ #else
+ /* Copy subframe to new buffer */
+ zfRxBufferCopy(dev, newBuf, buf, 0, *offset,
+ 14+subframeLen);
+ zfwBufSetSize(dev, newBuf, 14+subframeLen);
+ #endif
+ /* Update offset */
+ *offset += (((14+subframeLen)+3) & 0xfffc);
+
+ /* Return buffer pointer */
+ return newBuf;
+ }
+ }
+ return NULL;
}
@@ -101,34 +101,29 @@ zbuf_t* zfGetAmsduSubFrame(zdev_t* dev, zbuf_t* buf, u16_t* offset)
/* Stephen Chen Atheros Communications, INC. 2007.2 */
/* */
/************************************************************************/
-void zfDeAmsdu(zdev_t* dev, zbuf_t* buf, u16_t vap, u8_t encryMode)
+void zfDeAmsdu(zdev_t *dev, zbuf_t *buf, u16_t vap, u8_t encryMode)
{
- u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
- zbuf_t* subframeBuf;
- zmw_get_wlan_dev(dev);
-
- ZM_BUFFER_TRACE(dev, buf)
-
- if (encryMode == ZM_AES || encryMode == ZM_TKIP)
- {
- offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
- }
- else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
- {
- offset += ZM_SIZE_OF_IV;
- }
-
- /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
- while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL)
- {
- wd->commTally.NotifyNDISRxFrmCnt++;
- if (wd->zfcbRecvEth != NULL)
- {
- wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
- ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
- }
- }
- zfwBufFree(dev, buf, 0);
-
- return;
+ u16_t offset = ZM_SIZE_OF_WLAN_DATA_HEADER+ZM_SIZE_OF_QOS_CTRL;
+ zbuf_t *subframeBuf;
+ zmw_get_wlan_dev(dev);
+
+ ZM_BUFFER_TRACE(dev, buf)
+
+ if (encryMode == ZM_AES || encryMode == ZM_TKIP)
+ offset += (ZM_SIZE_OF_IV + ZM_SIZE_OF_EXT_IV);
+ else if (encryMode == ZM_WEP64 || encryMode == ZM_WEP128)
+ offset += ZM_SIZE_OF_IV;
+
+
+ /* Repeatly calling zfGetAmsduSubFrame() until NULL returned */
+ while ((subframeBuf = zfGetAmsduSubFrame(dev, buf, &offset)) != NULL) {
+ wd->commTally.NotifyNDISRxFrmCnt++;
+ if (wd->zfcbRecvEth != NULL) {
+ wd->zfcbRecvEth(dev, subframeBuf, (u8_t)vap);
+ ZM_PERFORMANCE_RX_MSDU(dev, wd->tick);
+ }
+ }
+ zfwBufFree(dev, buf, 0);
+
+ return;
}
diff --git a/drivers/staging/otus/80211core/cmmsta.c b/drivers/staging/otus/80211core/cmmsta.c
index c75ba11ee43..b28a4e25e10 100644
--- a/drivers/staging/otus/80211core/cmmsta.c
+++ b/drivers/staging/otus/80211core/cmmsta.c
@@ -724,6 +724,9 @@ void zfStaUpdateWmeParameter(zdev_t* dev, zbuf_t* buf)
/* process 802.11h Dynamic Frequency Selection */
void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
{
+ //u8_t length, channel, is5G;
+ u16_t offset;
+
zmw_get_wlan_dev(dev);
/*
@@ -736,8 +739,6 @@ void zfStaUpdateDot11HDFS(zdev_t* dev, zbuf_t* buf)
|Value | 37 | 3 | 0 or 1 |unsigned integer |unsigned integer |
+------+----------+------+-------------------+------------------+--------------------+
*/
- //u8_t length, channel, is5G;
- u16_t offset;
/* get EID(Channel Switch Announcement) */
if ( (offset = zfFindElement(dev, buf, ZM_WLAN_EID_CHANNEL_SWITCH_ANNOUNCE)) == 0xffff )
diff --git a/drivers/staging/otus/80211core/coid.c b/drivers/staging/otus/80211core/coid.c
index 6007f3131f8..88f8d3491a8 100644
--- a/drivers/staging/otus/80211core/coid.c
+++ b/drivers/staging/otus/80211core/coid.c
@@ -214,10 +214,10 @@ u32_t zfiWlanQuerySupportMode(zdev_t* dev)
u32_t zfiWlanQueryTransmitPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
u32_t ret = 0;
+ zmw_get_wlan_dev(dev);
+
if (zfStaIsConnected(dev)) {
ret = wd->sta.connPowerInHalfDbm;
} else {
@@ -1432,12 +1432,12 @@ u32_t zfiWlanQueryCurrentFrequency(zdev_t* dev, u8_t qmode)
u32_t zfiWlanQueryFrequencyAttribute(zdev_t* dev, u32_t freq)
{
- zmw_get_wlan_dev(dev);
-
u8_t i;
u16_t frequency = (u16_t) (freq/1000);
u32_t ret = 0;
+ zmw_get_wlan_dev(dev);
+
for (i = 0; i < wd->regulationTable.allowChannelCnt; i++)
{
if ( wd->regulationTable.allowChannel[i].channel == frequency )
diff --git a/drivers/staging/otus/80211core/cwm.c b/drivers/staging/otus/80211core/cwm.c
index 80f1141bf91..1bd0b1ff12d 100644
--- a/drivers/staging/otus/80211core/cwm.c
+++ b/drivers/staging/otus/80211core/cwm.c
@@ -75,9 +75,9 @@ void zfCoreCwmBusy(zdev_t* dev, u16_t busy)
if((wd->wlanMode == ZM_MODE_INFRASTRUCTURE || wd->wlanMode == ZM_MODE_PSEUDO ||
wd->wlanMode == ZM_MODE_IBSS)) {
- if (wd->sta.ie.HtCap.HtCapInfo && HTCAP_SupChannelWidthSet != 0 &&
- wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_RecomTxWidthSet != 0 &&
- (wd->sta.ie.HtInfo.ChannelInfo && ExtHtCap_ExtChannelOffsetAbove) == 1) {
+ if ((wd->sta.ie.HtCap.HtCapInfo & HTCAP_SupChannelWidthSet) &&
+ (wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_RecomTxWidthSet) &&
+ (wd->sta.ie.HtInfo.ChannelInfo & ExtHtCap_ExtChannelOffsetAbove)) {
wd->cwm.cw_width = CWM_WIDTH40;
}
diff --git a/drivers/staging/otus/TODO b/drivers/staging/otus/TODO
index e912293ed1e..4caf026a491 100644
--- a/drivers/staging/otus/TODO
+++ b/drivers/staging/otus/TODO
@@ -1,8 +1,15 @@
+I'm hesitant to add a TODO file here, as the wireless developers would
+really have people help them out on the "clean" ar9170 driver that can
+be found at the linux-wireless developer site.
+
+But, if you wish to clean up this driver instead, here's a short list of
+things that need to be done to get it into a more mergable shape:
+
TODO:
- checkpatch.pl cleanups
- sparse cleanups
- port to in-kernel 80211 stack
- - proper network developer maintainer
+ - review by the wireless developer community
Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
Luis Rodriguez <Luis.Rodriguez@Atheros.com> and the
diff --git a/drivers/staging/otus/hal/hpani.c b/drivers/staging/otus/hal/hpani.c
index ba95b5d012a..0afecd8c2de 100644
--- a/drivers/staging/otus/hal/hpani.c
+++ b/drivers/staging/otus/hal/hpani.c
@@ -55,10 +55,10 @@ extern u16_t zfFlushDelayWrite(zdev_t* dev);
s32_t BEACON_RSSI(zdev_t* dev)
{
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
rssi = ZM_HAL_EP_RND(HpPriv->stats.ast_nodestats.ns_avgbrssi, ZM_HAL_RSSI_EP_MULTIPLIER);
@@ -74,16 +74,16 @@ void zfHpAniAttach(zdev_t* dev)
{
#define N(a) (sizeof(a) / sizeof(a[0]))
u32_t i;
-
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ struct zsHpPriv *HpPriv;
const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
const int coarseHigh[] = { -14, -14, -14, -14, -12 };
const int coarseLow[] = { -64, -64, -64, -64, -70 };
const int firpwr[] = { -78, -78, -78, -78, -80 };
+ zmw_get_wlan_dev(dev);
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+
for (i = 0; i < 5; i++)
{
HpPriv->totalSizeDesired[i] = totalSizeDesired[i];
@@ -139,12 +139,12 @@ u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param)
{
#define N(a) (sizeof(a)/sizeof(a[0]))
typedef s32_t TABLE[];
+ struct zsHpPriv *HpPriv;
+ struct zsAniState *aniState;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
- struct zsAniState *aniState = HpPriv->curani;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ aniState = HpPriv->curani;
switch (cmd)
{
@@ -346,11 +346,10 @@ u8_t zfHpAniControl(zdev_t* dev, ZM_HAL_ANI_CMD cmd, int param)
void zfHpAniRestart(zdev_t* dev)
{
struct zsAniState *aniState;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
aniState = HpPriv->curani;
aniState->listenTime = 0;
@@ -387,10 +386,10 @@ void zfHpAniOfdmErrTrigger(zdev_t* dev)
{
struct zsAniState *aniState;
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
//HALASSERT(chan != NULL);
@@ -466,10 +465,10 @@ void zfHpAniCckErrTrigger(zdev_t* dev)
{
struct zsAniState *aniState;
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
//HALASSERT(chan != NULL);
@@ -511,11 +510,10 @@ void zfHpAniLowerImmunity(zdev_t* dev)
{
struct zsAniState *aniState;
s32_t rssi;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
-
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
aniState = HpPriv->curani;
rssi = BEACON_RSSI(dev);
@@ -586,10 +584,10 @@ s32_t zfHpAniGetListenTime(zdev_t* dev)
struct zsAniState *aniState;
u32_t txFrameCount, rxFrameCount, cycleCount;
s32_t listenTime;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
txFrameCount = 0;//OS_REG_READ(ah, AR_TFCNT);
rxFrameCount = 0;//OS_REG_READ(ah, AR_RFCNT);
@@ -627,10 +625,10 @@ void zfHpAniArPoll(zdev_t* dev, u32_t listenTime, u32_t phyCnt1, u32_t phyCnt2)
{
struct zsAniState *aniState;
//s32_t listenTime;
+ struct zsHpPriv *HpPriv;
zmw_get_wlan_dev(dev);
-
- struct zsHpPriv *HpPriv = (struct zsHpPriv*)wd->hpPrivate;
+ HpPriv = (struct zsHpPriv*)wd->hpPrivate;
/*
* Since we're called from end of rx tasklet, we also check for
diff --git a/drivers/staging/otus/hal/hpmain.c b/drivers/staging/otus/hal/hpmain.c
index 2e65c466aae..322585be2c8 100644
--- a/drivers/staging/otus/hal/hpmain.c
+++ b/drivers/staging/otus/hal/hpmain.c
@@ -152,7 +152,7 @@ u16_t zfHpInit(zdev_t* dev, u32_t frequency)
else
{
#ifndef ZM_OTUS_LINUX_PHASE_2
- /* donwload the normal frimware */
+ /* download the normal firmware */
if ((ret = zfFirmwareDownload(dev, (u32_t*)zcFwImage,
(u32_t)zcFwImageSize, ZM_FIRMWARE_WLAN_ADDR)) != ZM_SUCCESS)
{
@@ -328,8 +328,8 @@ void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40)
u16_t modesIndex = 0;
u16_t freqIndex = 0;
u32_t tmp, tmp1;
- zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
+
u32_t eepromBoardData[15][6] = {
/* Register A-20 A-20/40 G-20/40 G-20 G-Turbo */
{0x9964, 0, 0, 0, 0, 0},
@@ -349,6 +349,9 @@ void zfInitPhy(zdev_t* dev, u32_t frequency, u8_t bw40)
{0xa258, 0, 0, 0, 0, 0},
};
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
+
/* #1 Save the initial value of the related RIFS register settings */
//((struct zsHpPriv*)wd->hpPrivate)->isInitialPhy++;
@@ -1324,9 +1327,10 @@ void zfHpSetFrequencyEx(zdev_t* dev, u32_t frequency, u8_t bw40,
int delta_slope_coeff_man;
int delta_slope_coeff_exp_shgi;
int delta_slope_coeff_man_shgi;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
zm_msg1_scan(ZM_LV_1, "Frequency = ", frequency);
zm_msg1_scan(ZM_LV_1, "bw40 = ", bw40);
@@ -1560,9 +1564,10 @@ u16_t zfHpResetKeyCache(zdev_t* dev)
{
u8_t i;
u32_t key[4] = {0, 0, 0, 0};
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
for(i=0;i<4;i++)
{
@@ -1601,9 +1606,10 @@ u32_t zfHpSetKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t type,
u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
u16_t ret;
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
#if 0 /* remove to zfCoreSetKey() */
zmw_declare_for_critical_section();
@@ -1670,8 +1676,10 @@ u32_t zfHpSetDefaultKey(zdev_t* dev, u8_t keyId, u8_t type, u32_t* key, u32_t* m
u16_t macAddr[3] = {0, 0, 0};
#ifdef ZM_ENABLE_IBSS_WPA2PSK
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK )
{ /* If not wpa2psk , use traditional */
@@ -1702,8 +1710,10 @@ u32_t zfHpSetDefaultKey(zdev_t* dev, u8_t keyId, u8_t type, u32_t* key, u32_t* m
u32_t zfHpSetPerUserKey(zdev_t* dev, u8_t user, u8_t keyId, u8_t* mac, u8_t type, u32_t* key, u32_t* micKey)
{
#ifdef ZM_ENABLE_IBSS_WPA2PSK
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
if ( hpPriv->dot11Mode == ZM_HAL_80211_MODE_IBSS_WPA2PSK )
{ /* If not wpa2psk , use traditional */
@@ -1918,9 +1928,10 @@ u16_t zfHpSetSnifferMode(zdev_t* dev, u16_t on)
u16_t zfHpSetApStaMode(zdev_t* dev, u8_t mode)
{
- zmw_get_wlan_dev(dev);
+ struct zsHpPriv* hpPriv;
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
hpPriv->dot11Mode = mode;
switch(mode)
@@ -1993,8 +2004,10 @@ u16_t zfHpSetBssid(zdev_t* dev, u8_t* bssidSrc)
u8_t zfHpUpdateQosParameter(zdev_t* dev, u16_t* cwminTbl, u16_t* cwmaxTbl,
u16_t* aifsTbl, u16_t* txopTbl)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
zm_msg0_mm(ZM_LV_0, "zfHalUpdateQosParameter()");
@@ -2259,9 +2272,11 @@ u32_t zfHpCwmUpdate(zdev_t* dev)
//
//ret = zfIssueCmd(dev, cmd, 12, ZM_CWM_READ, 0);
//return ret;
- zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
+
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
zfCoreCwmBusy(dev, zfCwmIsExtChanBusy(hpPriv->ctlBusy, hpPriv->extBusy));
@@ -2291,9 +2306,10 @@ u32_t zfHpAniUpdate(zdev_t* dev)
*/
u32_t zfHpAniUpdateRssi(zdev_t* dev, u8_t rssi)
{
- zmw_get_wlan_dev(dev);
+ struct zsHpPriv* hpPriv;
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
hpPriv->stats.ast_nodestats.ns_avgbrssi = rssi;
@@ -2325,11 +2341,12 @@ u32_t zfHpGetMacAddress(zdev_t* dev)
u32_t zfHpGetTransmitPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u16_t tpc = 0;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
+
if (hpPriv->hwFrequency < 3000) {
tpc = hpPriv->tPow2x2g[0] & 0x3f;
wd->maxTxPower2 &= 0x3f;
@@ -2345,11 +2362,12 @@ u32_t zfHpGetTransmitPower(zdev_t* dev)
u8_t zfHpGetMinTxPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u8_t tpc = 0;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
+
if (hpPriv->hwFrequency < 3000)
{
if(wd->BandWidth40)
@@ -2382,11 +2400,12 @@ u8_t zfHpGetMinTxPower(zdev_t* dev)
u8_t zfHpGetMaxTxPower(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
-
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u8_t tpc = 0;
+ zmw_get_wlan_dev(dev);
+ hpPriv = wd->hpPrivate;
+
if (hpPriv->hwFrequency < 3000)
{
tpc = (hpPriv->tPow2xCck[0]&0x3f);
@@ -2421,11 +2440,13 @@ u32_t zfHpLoadEEPROMFromFW(zdev_t* dev)
void zfHpHeartBeat(zdev_t* dev)
{
- zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ struct zsHpPriv* hpPriv;
u8_t polluted = 0;
u8_t ackTpc;
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
+
/* Workaround : Make OTUS fire more beacon in ad hoc mode in 2.4GHz */
if (hpPriv->ibssBcnEnabled != 0)
{
@@ -4219,8 +4240,10 @@ void zfHpPowerSaveSetMode(zdev_t* dev, u8_t staMode, u8_t psMode, u16_t bcnInter
void zfHpPowerSaveSetState(zdev_t* dev, u8_t psState)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
//DbgPrint("INTO zfHpPowerSaveSetState");
@@ -4279,8 +4302,10 @@ void zfHpPowerSaveSetState(zdev_t* dev, u8_t psState)
void zfHpSetAggPktNum(zdev_t* dev, u32_t num)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
num = (num << 16) | (0xa);
@@ -4310,8 +4335,10 @@ void zfHpSetMPDUDensity(zdev_t* dev, u8_t density)
void zfHpSetSlotTime(zdev_t* dev, u8_t type)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = wd->hpPrivate;
+ hpPriv = wd->hpPrivate;
if (type == 0)
{
@@ -4376,8 +4403,10 @@ void zfHpSetRifs(zdev_t* dev, u8_t ht_enable, u8_t ht2040, u8_t g_mode)
void zfHpBeginSiteSurvey(zdev_t* dev, u8_t status)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
if ( status == 1 )
{ // Connected
@@ -4421,8 +4450,10 @@ void zfHpBeginSiteSurvey(zdev_t* dev, u8_t status)
void zfHpFinishSiteSurvey(zdev_t* dev, u8_t status)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -4527,16 +4558,20 @@ void zfHpSWEncrypt(zdev_t* dev, u8_t enable)
u32_t zfHpCapability(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
return hpPriv->halCapability;
}
void zfHpSetRollCallTable(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
if (hpPriv->camRollCallTable != (u64_t) 0)
{
diff --git a/drivers/staging/otus/hal/hpreg.c b/drivers/staging/otus/hal/hpreg.c
index 3cfeba8620f..d9894fe5f4e 100644
--- a/drivers/staging/otus/hal/hpreg.c
+++ b/drivers/staging/otus/hal/hpreg.c
@@ -1770,8 +1770,10 @@ void zfHpGetRegulationTable(zdev_t* dev, u16_t regionCode, u16_t c_lo, u16_t c_h
REG_DOMAIN rd5GHz, rd2GHz;
const struct cmode *cm;
s16_t next=0,b;
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -2473,9 +2475,10 @@ u8_t zfHpGetRegulatoryDomain(zdev_t* dev)
void zfHpDisableDfsChannel(zdev_t* dev, u8_t disableFlag)
{
- zmw_get_wlan_dev(dev);
+ struct zsHpPriv* hpPriv;
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ zmw_get_wlan_dev(dev);
+ hpPriv=wd->hpPrivate;
hpPriv->disableDfsCh = disableFlag;
return;
}
diff --git a/drivers/staging/otus/hal/hprw.c b/drivers/staging/otus/hal/hprw.c
index db7d4957645..d9fad47d5d5 100644
--- a/drivers/staging/otus/hal/hprw.c
+++ b/drivers/staging/otus/hal/hprw.c
@@ -29,8 +29,10 @@ u16_t zfFlushDelayWrite(zdev_t* dev);
void zfInitCmdQueue(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv = (struct zsHpPriv*)(wd->hpPrivate);
+ hpPriv = (struct zsHpPriv*)(wd->hpPrivate);
zmw_declare_for_critical_section();
@@ -48,9 +50,10 @@ void zfInitCmdQueue(zdev_t* dev)
u16_t zfPutCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf)
{
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
/* Make sure command length < ZM_MAX_CMD_SIZE */
zm_assert(cmdLen <= ZM_MAX_CMD_SIZE);
@@ -77,9 +80,10 @@ u16_t zfPutCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf)
u16_t zfGetCmd(zdev_t* dev, u32_t* cmd, u16_t* cmdLen, u16_t* src, u8_t** buf)
{
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
if (hpPriv->cmdTail == hpPriv->cmdHead)
{
@@ -106,9 +110,10 @@ void zfSendCmdEx(zdev_t* dev)
u16_t ncmdLen = 0;
u16_t cmdFlag = 0;
u16_t i;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -141,8 +146,10 @@ void zfSendCmdEx(zdev_t* dev)
void zfiSendCmdComp(zdev_t* dev)
{
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -158,9 +165,10 @@ u16_t zfIssueCmd(zdev_t* dev, u32_t* cmd, u16_t cmdLen, u16_t src, u8_t* buf)
{
u16_t cmdFlag = 0;
u16_t ret;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -214,9 +222,10 @@ void zfIdlRsp(zdev_t* dev, u32_t* rsp, u16_t rspLen)
u16_t i;
s32_t nf;
s32_t noisefloor[4];
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -826,9 +835,10 @@ u16_t zfDelayWriteInternalReg(zdev_t* dev, u32_t addr, u32_t val)
u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
u16_t i;
u16_t ret;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
@@ -892,8 +902,10 @@ u16_t zfFlushDelayWrite(zdev_t* dev)
u32_t cmd[(ZM_MAX_CMD_SIZE/4)];
u16_t i;
u16_t ret;
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zmw_declare_for_critical_section();
diff --git a/drivers/staging/otus/hal/hpusb.c b/drivers/staging/otus/hal/hpusb.c
index 4b76de93fff..ee939005be7 100644
--- a/drivers/staging/otus/hal/hpusb.c
+++ b/drivers/staging/otus/hal/hpusb.c
@@ -64,9 +64,10 @@ void zfAdjustCtrlSetting(zdev_t* dev, u16_t* header, zbuf_t* buf)
u32_t oldPhyCtrl;
u16_t tpc = 0;
+ struct zsHpPriv* hpPriv;
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
/* mm */
if (header == NULL)
@@ -330,8 +331,10 @@ u16_t zfHpSend(zdev_t* dev, u16_t* header, u16_t headerLen,
u16_t i;
u16_t swlpOffset;
#endif /* #if ZM_SW_LOOP_BACK == 1 */
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
zm_msg1_tx(ZM_LV_1, "zfHpSend(), len = ", 12 + headerLen-8 + snapLen + zfwBufGetSize(dev, buf) + 4 + 8);
@@ -576,8 +579,10 @@ void zfiUsbRecv(zdev_t *dev, zbuf_t *buf)
u32_t rxMCS;
u32_t rxBW;
u32_t rxSG;
+ struct zsHpPriv* hpPriv;
+
zmw_get_wlan_dev(dev);
- struct zsHpPriv* hpPriv=wd->hpPrivate;
+ hpPriv=wd->hpPrivate;
//zm_msg0_rx(ZM_LV_0, "zfiUsbRecv()");
diff --git a/drivers/staging/otus/ioctl.c b/drivers/staging/otus/ioctl.c
index 7a5c1e876b0..ce04218253d 100644
--- a/drivers/staging/otus/ioctl.c
+++ b/drivers/staging/otus/ioctl.c
@@ -25,7 +25,7 @@
/************************************************************************/
#include <linux/module.h>
#include <linux/if_arp.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include "usbdrv.h"
@@ -34,7 +34,7 @@
#define ZD_IOCTL_GETWPAIE (SIOCDEVPRIVATE + 3)
#ifdef ZM_ENABLE_CENC
#define ZM_IOCTL_CENC (SIOCDEVPRIVATE + 4)
-#endif //ZM_ENABLE_CENC
+#endif /* ZM_ENABLE_CENC */
#define ZD_PARAM_ROAMING 0x0001
#define ZD_PARAM_PRIVACY 0x0002
#define ZD_PARAM_WPA 0x0003
@@ -45,7 +45,7 @@
#ifdef ZM_ENABLE_CENC
#define P80211_PACKET_CENCFLAG 0x0001
-#endif //ZM_ENABLE_CENC
+#endif /* ZM_ENABLE_CENC */
#define P80211_PACKET_SETKEY 0x0003
#define ZD_CMD_SET_ENCRYPT_KEY 0x0001
@@ -62,204 +62,190 @@
#include <net/iw_handler.h>
#endif
-extern u16_t zfLnxGetVapId(zdev_t* dev);
+extern u16_t zfLnxGetVapId(zdev_t *dev);
static const u32_t channel_frequency_11A[] =
{
-//Even element for Channel Number, Odd for Frequency
- 36,5180,
- 40,5200,
- 44,5220,
- 48,5240,
- 52,5260,
- 56,5280,
- 60,5300,
- 64,5320,
- 100,5500,
- 104,5520,
- 108,5540,
- 112,5560,
- 116,5580,
- 120,5600,
- 124,5620,
- 128,5640,
- 132,5660,
- 136,5680,
- 140,5700,
-//
- 184,4920,
- 188,4940,
- 192,4960,
- 196,4980,
- 8,5040,
- 12,5060,
- 16,5080,
- 34,5170,
- 38,5190,
- 42,5210,
- 46,5230,
-//
- 149,5745,
- 153,5765,
- 157,5785,
- 161,5805,
- 165,5825
-//
+ /* Even element for Channel Number, Odd for Frequency */
+ 36, 5180,
+ 40, 5200,
+ 44, 5220,
+ 48, 5240,
+ 52, 5260,
+ 56, 5280,
+ 60, 5300,
+ 64, 5320,
+ 100, 5500,
+ 104, 5520,
+ 108, 5540,
+ 112, 5560,
+ 116, 5580,
+ 120, 5600,
+ 124, 5620,
+ 128, 5640,
+ 132, 5660,
+ 136, 5680,
+ 140, 5700,
+ /**/
+ 184, 4920,
+ 188, 4940,
+ 192, 4960,
+ 196, 4980,
+ 8, 5040,
+ 12, 5060,
+ 16, 5080,
+ 34, 5170,
+ 38, 5190,
+ 42, 5210,
+ 46, 5230,
+ /**/
+ 149, 5745,
+ 153, 5765,
+ 157, 5785,
+ 161, 5805,
+ 165, 5825
+ /**/
};
int usbdrv_freq2chan(u32_t freq)
{
- /* 2.4G Hz */
- if (freq > 2400 && freq < 3000)
- {
- return ((freq-2412)/5) + 1;
- }
- else
- {
- u16_t ii;
- u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
-
- for(ii = 1; ii < num_chan; ii += 2)
- {
- if (channel_frequency_11A[ii] == freq)
- return channel_frequency_11A[ii-1];
- }
- }
-
- return 0;
+ /* 2.4G Hz */
+ if (freq > 2400 && freq < 3000) {
+ return ((freq-2412)/5) + 1;
+ } else {
+ u16_t ii;
+ u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
+
+ for (ii = 1; ii < num_chan; ii += 2) {
+ if (channel_frequency_11A[ii] == freq)
+ return channel_frequency_11A[ii-1];
+ }
+ }
+
+ return 0;
}
int usbdrv_chan2freq(int chan)
{
- int freq;
-
- /* If channel number is out of range */
- if (chan > 165 || chan <= 0)
- return -1;
-
- /* 2.4G band */
- if (chan >= 1 && chan <= 13)
- {
- freq = (2412 + (chan - 1) * 5);
- return freq;
- }
- else if (chan >= 36 && chan <= 165)
- {
- u16_t ii;
- u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
-
- for(ii = 0; ii < num_chan; ii += 2)
- {
- if (channel_frequency_11A[ii] == chan)
- return channel_frequency_11A[ii+1];
- }
-
- /* Can't find desired frequency */
- if (ii == num_chan)
- return -1;
- }
-
- /* Can't find deisred frequency */
- return -1;
+ int freq;
+
+ /* If channel number is out of range */
+ if (chan > 165 || chan <= 0)
+ return -1;
+
+ /* 2.4G band */
+ if (chan >= 1 && chan <= 13) {
+ freq = (2412 + (chan - 1) * 5);
+ return freq;
+ } else if (chan >= 36 && chan <= 165) {
+ u16_t ii;
+ u16_t num_chan = sizeof(channel_frequency_11A)/sizeof(u32_t);
+
+ for (ii = 0; ii < num_chan; ii += 2) {
+ if (channel_frequency_11A[ii] == chan)
+ return channel_frequency_11A[ii+1];
+ }
+
+ /* Can't find desired frequency */
+ if (ii == num_chan)
+ return -1;
+ }
+
+ /* Can't find deisred frequency */
+ return -1;
}
int usbdrv_ioctl_setessid(struct net_device *dev, struct iw_point *erq)
{
-#ifdef ZM_HOSTAPD_SUPPORT
- //struct usbdrv_private *macp = dev->ml_priv;
- char essidbuf[IW_ESSID_MAX_SIZE+1];
- int i;
+ #ifdef ZM_HOSTAPD_SUPPORT
+ /* struct usbdrv_private *macp = dev->ml_priv; */
+ char essidbuf[IW_ESSID_MAX_SIZE+1];
+ int i;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- memset(essidbuf, 0, sizeof(essidbuf));
+ memset(essidbuf, 0, sizeof(essidbuf));
- printk(KERN_ERR "usbdrv_ioctl_setessid\n");
+ printk(KERN_ERR "usbdrv_ioctl_setessid\n");
- //printk("ssidlen=%d\n", erq->length); //for any, it is 1.
- if (erq->flags) {
- if (erq->length > (IW_ESSID_MAX_SIZE+1))
- return -E2BIG;
+ /* printk("ssidlen=%d\n", erq->length); //for any, it is 1. */
+ if (erq->flags) {
+ if (erq->length > (IW_ESSID_MAX_SIZE+1))
+ return -E2BIG;
- if (copy_from_user(essidbuf, erq->pointer, erq->length))
- return -EFAULT;
- }
+ if (copy_from_user(essidbuf, erq->pointer, erq->length))
+ return -EFAULT;
+ }
- //zd_DisasocAll(2);
- //wait_ms(100);
+ /* zd_DisasocAll(2); */
+ /* wait_ms(100); */
- printk(KERN_ERR "essidbuf: ");
+ printk(KERN_ERR "essidbuf: ");
- for(i = 0; i < erq->length; i++)
- {
- printk(KERN_ERR "%02x ", essidbuf[i]);
- }
+ for (i = 0; i < erq->length; i++)
+ printk(KERN_ERR "%02x ", essidbuf[i]);
- printk(KERN_ERR "\n");
+ printk(KERN_ERR "\n");
- essidbuf[erq->length] = '\0';
- //memcpy(macp->wd.ws.ssid, essidbuf, erq->length);
- //macp->wd.ws.ssidLen = strlen(essidbuf)+2;
- //macp->wd.ws.ssid[1] = strlen(essidbuf); // Update ssid length
+ essidbuf[erq->length] = '\0';
+ /* memcpy(macp->wd.ws.ssid, essidbuf, erq->length); */
+ /* macp->wd.ws.ssidLen = strlen(essidbuf)+2; */
+ /* macp->wd.ws.ssid[1] = strlen(essidbuf); Update ssid length */
- zfiWlanSetSSID(dev, essidbuf, erq->length);
-#if 0
- printk(KERN_ERR "macp->wd.ws.ssid: ");
+ zfiWlanSetSSID(dev, essidbuf, erq->length);
+ #if 0
+ printk(KERN_ERR "macp->wd.ws.ssid: ");
- for(i = 0; i < macp->wd.ws.ssidLen; i++)
- {
- printk(KERN_ERR "%02x ", macp->wd.ws.ssid[i]);
- }
+ for (i = 0; i < macp->wd.ws.ssidLen; i++)
+ printk(KERN_ERR "%02x ", macp->wd.ws.ssid[i]);
- printk(KERN_ERR "\n");
-#endif
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
+ printk(KERN_ERR "\n");
+ #endif
-#endif
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
- return 0;
+ #endif
+
+ return 0;
}
int usbdrv_ioctl_getessid(struct net_device *dev, struct iw_point *erq)
{
- //struct usbdrv_private *macp = dev->ml_priv;
- u8_t essidbuf[IW_ESSID_MAX_SIZE+1];
- u8_t len;
- u8_t i;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
+ u8_t essidbuf[IW_ESSID_MAX_SIZE+1];
+ u8_t len;
+ u8_t i;
- //len = macp->wd.ws.ssidLen;
- //memcpy(essidbuf, macp->wd.ws.ssid, macp->wd.ws.ssidLen);
- zfiWlanQuerySSID(dev, essidbuf, &len);
+ /* len = macp->wd.ws.ssidLen; */
+ /* memcpy(essidbuf, macp->wd.ws.ssid, macp->wd.ws.ssidLen); */
+ zfiWlanQuerySSID(dev, essidbuf, &len);
- essidbuf[len] = 0;
+ essidbuf[len] = 0;
- printk(KERN_ERR "ESSID: ");
+ printk(KERN_ERR "ESSID: ");
- for(i = 0; i < len; i++)
- {
- printk(KERN_ERR "%c", essidbuf[i]);
- }
+ for (i = 0; i < len; i++)
+ printk(KERN_ERR "%c", essidbuf[i]);
- printk(KERN_ERR "\n");
+ printk(KERN_ERR "\n");
- erq->flags= 1;
- erq->length = strlen(essidbuf) + 1;
+ erq->flags = 1;
+ erq->length = strlen(essidbuf) + 1;
- if (erq->pointer)
- if (copy_to_user(erq->pointer, essidbuf, erq->length))
- return -EFAULT;
+ if (erq->pointer) {
+ if (copy_to_user(erq->pointer, essidbuf, erq->length))
+ return -EFAULT;
+ }
- return 0;
+ return 0;
}
-
int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
{
-
- return 0;
+ return 0;
}
#if WIRELESS_EXT > 14
@@ -267,462 +253,418 @@ int usbdrv_ioctl_setrts(struct net_device *dev, struct iw_param *rrq)
* Encode a WPA or RSN information element as a custom
* element using the hostap format.
*/
-u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen, const u8 *leader, u32 leader_len)
+u32 encode_ie(void *buf, u32 bufsize, const u8 *ie, u32 ielen,
+ const u8 *leader, u32 leader_len)
{
- u8 *p;
- u32 i;
-
- if (bufsize < leader_len)
- return 0;
- p = buf;
- memcpy(p, leader, leader_len);
- bufsize -= leader_len;
- p += leader_len;
- for (i = 0; i < ielen && bufsize > 2; i++)
- p += sprintf(p, "%02x", ie[i]);
- return (i == ielen ? p - (u8 *)buf : 0);
+ u8 *p;
+ u32 i;
+
+ if (bufsize < leader_len)
+ return 0;
+ p = buf;
+ memcpy(p, leader, leader_len);
+ bufsize -= leader_len;
+ p += leader_len;
+ for (i = 0; i < ielen && bufsize > 2; i++)
+ p += sprintf(p, "%02x", ie[i]);
+ return (i == ielen ? p - (u8 *)buf:0);
}
-#endif /* WIRELESS_EXT > 14 */
+#endif /* WIRELESS_EXT > 14 */
-/*------------------------------------------------------------------*/
/*
* Translate scan data returned from the card to a card independent
* format that the Wireless Tools will understand
*/
char *usbdrv_translate_scan(struct net_device *dev,
struct iw_request_info *info, char *current_ev,
- char *end_buf, struct zsBssInfo *list)
+ char *end_buf, struct zsBssInfo *list)
{
- struct iw_event iwe; /* Temporary buffer */
- u16_t capabilities;
- char *current_val; /* For rates */
- char *last_ev;
- int i;
-#if WIRELESS_EXT > 14
- char buf[64*2 + 30];
-#endif
+ struct iw_event iwe; /* Temporary buffer */
+ u16_t capabilities;
+ char *current_val; /* For rates */
+ char *last_ev;
+ int i;
+ #if WIRELESS_EXT > 14
+ char buf[64*2 + 30];
+ #endif
+
+ last_ev = current_ev;
+
+ /* First entry *MUST* be the AP MAC address */
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_ADDR_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Other entries will be displayed in the order we give them */
+
+ /* Add the ESSID */
+ iwe.u.data.length = list->ssid[1];
+ if (iwe.u.data.length > 32)
+ iwe.u.data.length = 32;
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.flags = 1;
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, &list->ssid[2]);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add mode */
+ iwe.cmd = SIOCGIWMODE;
+ capabilities = (list->capability[1] << 8) + list->capability[0];
+ if (capabilities & (0x01 | 0x02)) {
+ if (capabilities & 0x01)
+ iwe.u.mode = IW_MODE_MASTER;
+ else
+ iwe.u.mode = IW_MODE_ADHOC;
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_UINT_LEN);
+ }
- last_ev = current_ev;
-
-/* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe.u.ap_addr.sa_data, list->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(
- info,
- current_ev,
- end_buf, &iwe, IW_EV_ADDR_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Other entries will be displayed in the order we give them */
-
-/* Add the ESSID */
- iwe.u.data.length = list->ssid[1];
- if(iwe.u.data.length > 32)
- iwe.u.data.length = 32;
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, &list->ssid[2]);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add mode */
- iwe.cmd = SIOCGIWMODE;
- capabilities = (list->capability[1] << 8) + list->capability[0];
- if(capabilities & (0x01 | 0x02))
- {
- if(capabilities & 0x01)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(
- info,
- current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
- }
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add frequency */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = list->channel;
-/* Channel frequency in KHz */
- if (iwe.u.freq.m > 14)
- {
- if ((184 <= iwe.u.freq.m) && (iwe.u.freq.m<=196))
- iwe.u.freq.m = 4000 + iwe.u.freq.m * 5;
- else
- iwe.u.freq.m = 5000 + iwe.u.freq.m * 5;
- }
- else
- {
- if (iwe.u.freq.m == 14)
- iwe.u.freq.m = 2484;
- else
- iwe.u.freq.m = 2412 + (iwe.u.freq.m - 1) * 5;
- }
- iwe.u.freq.e = 6;
- current_ev = iwe_stream_add_event(
- info,
- current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add quality statistics */
- iwe.cmd = IWEVQUAL;
-#if WIRELESS_EXT > 18
- iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
- |IW_QUAL_NOISE_UPDATED;
-#endif
- iwe.u.qual.level = list->signalStrength;
- iwe.u.qual.noise = 0;
- iwe.u.qual.qual = list->signalQuality;
- current_ev = iwe_stream_add_event(
- info,
- current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Add encryption capability */
-
- iwe.cmd = SIOCGIWENCODE;
- if(capabilities & 0x10)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
-
- iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, list->ssid);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
-/* Rate : stuffing multiple values in a single event require a bit
- * more of magic */
- current_val = current_ev + IW_EV_LCP_LEN;
-
- iwe.cmd = SIOCGIWRATE;
-/* Those two flags are ignored... */
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
-
- for(i = 0 ; i < list->supportedRates[1] ; i++)
- {
-/* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value = ((list->supportedRates[i+2] & 0x7f) * 500000);
-/* Add new value to event */
- current_val = iwe_stream_add_value(
- info,
- current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_val)
- {
- return end_buf;
- }
-
- last_ev = current_val;
- }
-
- for (i = 0 ; i < list->extSupportedRates[1] ; i++)
- {
-/* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe.u.bitrate.value = ((list->extSupportedRates[i+2] & 0x7f) * 500000);
-/* Add new value to event */
- current_val = iwe_stream_add_value(
- info,
- current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
-
- /* Ran out of buffer */
- if (last_ev == current_val)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
- }
-
-/* Check if we added any event */
- if((current_val - current_ev) > IW_EV_LCP_LEN)
- current_ev = current_val;
-#if WIRELESS_EXT > 14
-#define IEEE80211_ELEMID_RSN 0x30
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- snprintf(buf, sizeof(buf), "bcn_int=%d", (list->beaconInterval[1] << 8) + list->beaconInterval[0]);
- iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, buf);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
-
- if (list->wpaIe[1] != 0)
- {
- static const char rsn_leader[] = "rsn_ie=";
- static const char wpa_leader[] = "wpa_ie=";
-
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
- if (list->wpaIe[0] == IEEE80211_ELEMID_RSN)
- iwe.u.data.length = encode_ie(buf, sizeof(buf),
- list->wpaIe, list->wpaIe[1]+2,
- rsn_leader, sizeof(rsn_leader)-1);
- else
- iwe.u.data.length = encode_ie(buf, sizeof(buf),
- list->wpaIe, list->wpaIe[1]+2,
- wpa_leader, sizeof(wpa_leader)-1);
-
- if (iwe.u.data.length != 0)
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, buf);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
- }
- if (list->rsnIe[1] != 0)
- {
- static const char rsn_leader[] = "rsn_ie=";
- memset(&iwe, 0, sizeof(iwe));
- iwe.cmd = IWEVCUSTOM;
-
- if (list->rsnIe[0] == IEEE80211_ELEMID_RSN)
- {
- iwe.u.data.length = encode_ie(buf, sizeof(buf),
- list->rsnIe, list->rsnIe[1]+2,
- rsn_leader, sizeof(rsn_leader)-1);
- if (iwe.u.data.length != 0)
- current_ev = iwe_stream_add_point(
- info,
- current_ev, end_buf, &iwe, buf);
-
- /* Ran out of buffer */
- if (last_ev == current_ev)
- {
- return end_buf;
- }
-
- last_ev = current_ev;
- }
- }
-#endif
-/* The other data in the scan result are not really
- * interesting, so for now drop it */
- return current_ev;
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add frequency */
+ iwe.cmd = SIOCGIWFREQ;
+ iwe.u.freq.m = list->channel;
+ /* Channel frequency in KHz */
+ if (iwe.u.freq.m > 14) {
+ if ((184 <= iwe.u.freq.m) && (iwe.u.freq.m <= 196))
+ iwe.u.freq.m = 4000 + iwe.u.freq.m * 5;
+ else
+ iwe.u.freq.m = 5000 + iwe.u.freq.m * 5;
+ } else {
+ if (iwe.u.freq.m == 14)
+ iwe.u.freq.m = 2484;
+ else
+ iwe.u.freq.m = 2412 + (iwe.u.freq.m - 1) * 5;
+ }
+ iwe.u.freq.e = 6;
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_FREQ_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add quality statistics */
+ iwe.cmd = IWEVQUAL;
+ #if WIRELESS_EXT > 18
+ iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
+ | IW_QUAL_NOISE_UPDATED;
+ #endif
+ iwe.u.qual.level = list->signalStrength;
+ iwe.u.qual.noise = 0;
+ iwe.u.qual.qual = list->signalQuality;
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe, IW_EV_QUAL_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Add encryption capability */
+
+ iwe.cmd = SIOCGIWENCODE;
+ if (capabilities & 0x10)
+ iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+
+ iwe.u.data.length = 0;
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, list->ssid);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ /* Rate : stuffing multiple values in a single event require a bit
+ * more of magic
+ */
+ current_val = current_ev + IW_EV_LCP_LEN;
+
+ iwe.cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+
+ for (i = 0 ; i < list->supportedRates[1] ; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((list->supportedRates[i+2] & 0x7f)
+ * 500000);
+ /* Add new value to event */
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_val)
+ return end_buf;
+
+ last_ev = current_val;
+ }
+
+ for (i = 0 ; i < list->extSupportedRates[1] ; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe.u.bitrate.value = ((list->extSupportedRates[i+2] & 0x7f)
+ * 500000);
+ /* Add new value to event */
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+
+ /* Ran out of buffer */
+ if (last_ev == current_val)
+ return end_buf;
+
+ last_ev = current_ev;
+ }
+
+ /* Check if we added any event */
+ if ((current_val - current_ev) > IW_EV_LCP_LEN)
+ current_ev = current_val;
+ #if WIRELESS_EXT > 14
+ #define IEEE80211_ELEMID_RSN 0x30
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ snprintf(buf, sizeof(buf), "bcn_int=%d", (list->beaconInterval[1] << 8)
+ + list->beaconInterval[0]);
+ iwe.u.data.length = strlen(buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+
+ if (list->wpaIe[1] != 0) {
+ static const char rsn_leader[] = "rsn_ie=";
+ static const char wpa_leader[] = "wpa_ie=";
+
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+ if (list->wpaIe[0] == IEEE80211_ELEMID_RSN)
+ iwe.u.data.length = encode_ie(buf, sizeof(buf),
+ list->wpaIe, list->wpaIe[1]+2,
+ rsn_leader, sizeof(rsn_leader)-1);
+ else
+ iwe.u.data.length = encode_ie(buf, sizeof(buf),
+ list->wpaIe, list->wpaIe[1]+2,
+ wpa_leader, sizeof(wpa_leader)-1);
+
+ if (iwe.u.data.length != 0)
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+ }
+
+ if (list->rsnIe[1] != 0) {
+ static const char rsn_leader[] = "rsn_ie=";
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVCUSTOM;
+
+ if (list->rsnIe[0] == IEEE80211_ELEMID_RSN) {
+ iwe.u.data.length = encode_ie(buf, sizeof(buf),
+ list->rsnIe, list->rsnIe[1]+2,
+ rsn_leader, sizeof(rsn_leader)-1);
+ if (iwe.u.data.length != 0)
+ current_ev = iwe_stream_add_point(info,
+ current_ev, end_buf, &iwe, buf);
+
+ /* Ran out of buffer */
+ if (last_ev == current_ev)
+ return end_buf;
+
+ last_ev = current_ev;
+ }
+ }
+ #endif
+ /* The other data in the scan result are not really
+ * interesting, so for now drop it
+ */
+ return current_ev;
}
int usbdrvwext_giwname(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrq, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrq, char *extra)
{
- //struct usbdrv_private *macp = dev->ml_priv;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
- strcpy(wrq->name, "IEEE 802.11-MIMO");
+ strcpy(wrq->name, "IEEE 802.11-MIMO");
- return 0;
+ return 0;
}
int usbdrvwext_siwfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *freq, char *extra)
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
{
- u32_t FreqKHz;
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (freq->e > 1)
- return -EINVAL;
-
- if (freq->e == 1)
- {
- FreqKHz = (freq->m / 100000);
-
- if (FreqKHz > 4000000)
- {
- if (FreqKHz > 5825000)
- FreqKHz = 5825000;
- else if (FreqKHz < 4920000)
- FreqKHz = 4920000;
- else if (FreqKHz < 5000000)
- FreqKHz = (((FreqKHz - 4000000) / 5000) * 5000) + 4000000;
- else
- FreqKHz = (((FreqKHz - 5000000) / 5000) * 5000) + 5000000;
- }
- else
- {
- if (FreqKHz > 2484000)
- FreqKHz = 2484000;
- else if (FreqKHz < 2412000)
- FreqKHz = 2412000;
- else
- FreqKHz = (((FreqKHz - 2412000) / 5000) * 5000) + 2412000;
- }
-
- }
- else
- {
- FreqKHz = usbdrv_chan2freq(freq->m);
-
- if (FreqKHz != -1)
- FreqKHz *= 1000;
- else
- FreqKHz = 2412000;
- }
-
- //printk("freq->m: %d, freq->e: %d\n", freq->m, freq->e);
- //printk("FreqKHz: %d\n", FreqKHz);
-
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetFrequency(dev, FreqKHz, 0); // Immediate
- //u8_t wpaieLen,wpaie[50];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
-
- return 0;
+ u32_t FreqKHz;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (freq->e > 1)
+ return -EINVAL;
+
+ if (freq->e == 1) {
+ FreqKHz = (freq->m / 100000);
+
+ if (FreqKHz > 4000000) {
+ if (FreqKHz > 5825000)
+ FreqKHz = 5825000;
+ else if (FreqKHz < 4920000)
+ FreqKHz = 4920000;
+ else if (FreqKHz < 5000000)
+ FreqKHz = (((FreqKHz - 4000000) / 5000) * 5000)
+ + 4000000;
+ else
+ FreqKHz = (((FreqKHz - 5000000) / 5000) * 5000)
+ + 5000000;
+ } else {
+ if (FreqKHz > 2484000)
+ FreqKHz = 2484000;
+ else if (FreqKHz < 2412000)
+ FreqKHz = 2412000;
+ else
+ FreqKHz = (((FreqKHz - 2412000) / 5000) * 5000)
+ + 2412000;
+ }
+ } else {
+ FreqKHz = usbdrv_chan2freq(freq->m);
+
+ if (FreqKHz != -1)
+ FreqKHz *= 1000;
+ else
+ FreqKHz = 2412000;
+ }
+
+ /* printk("freq->m: %d, freq->e: %d\n", freq->m, freq->e); */
+ /* printk("FreqKHz: %d\n", FreqKHz); */
+
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetFrequency(dev, FreqKHz, 0); /* Immediate */
+ /* u8_t wpaieLen,wpaie[50]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+
+ return 0;
}
int usbdrvwext_giwfreq(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_freq *freq, char *extra)
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- freq->m = zfiWlanQueryFrequency(dev);
- freq->e = 3;
+ freq->m = zfiWlanQueryFrequency(dev);
+ freq->e = 3;
- return 0;
+ return 0;
}
int usbdrvwext_siwmode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrq, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t WlanMode;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- switch(wrq->mode)
- {
- case IW_MODE_MASTER:
- WlanMode = ZM_MODE_AP;
- break;
- case IW_MODE_INFRA:
- WlanMode = ZM_MODE_INFRASTRUCTURE;
- break;
- case IW_MODE_ADHOC:
- WlanMode = ZM_MODE_IBSS;
- break;
- default:
- WlanMode = ZM_MODE_IBSS;
- break;
- }
-
- zfiWlanSetWlanMode(dev,WlanMode);
- zfiWlanDisable(dev, 1);
- zfiWlanEnable(dev);
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t WlanMode;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ switch (wrq->mode) {
+ case IW_MODE_MASTER:
+ WlanMode = ZM_MODE_AP;
+ break;
+ case IW_MODE_INFRA:
+ WlanMode = ZM_MODE_INFRASTRUCTURE;
+ break;
+ case IW_MODE_ADHOC:
+ WlanMode = ZM_MODE_IBSS;
+ break;
+ default:
+ WlanMode = ZM_MODE_IBSS;
+ break;
+ }
+
+ zfiWlanSetWlanMode(dev, WlanMode);
+ zfiWlanDisable(dev, 1);
+ zfiWlanEnable(dev);
+
+ return 0;
}
int usbdrvwext_giwmode(struct net_device *dev,
- struct iw_request_info *info,
- __u32 *mode, char *extra)
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
{
- unsigned long irqFlag;
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- spin_lock_irqsave(&macp->cs_lock, irqFlag);
-
- switch(zfiWlanQueryWlanMode(dev))
- {
- case ZM_MODE_AP:
- *mode = IW_MODE_MASTER;
- break;
- case ZM_MODE_INFRASTRUCTURE:
- *mode = IW_MODE_INFRA;
- break;
- case ZM_MODE_IBSS:
- *mode = IW_MODE_ADHOC;
- break;
- default:
- *mode = IW_MODE_ADHOC;
- break;
- }
-
- spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
-
- return 0;
+ unsigned long irqFlag;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ spin_lock_irqsave(&macp->cs_lock, irqFlag);
+
+ switch (zfiWlanQueryWlanMode(dev)) {
+ case ZM_MODE_AP:
+ *mode = IW_MODE_MASTER;
+ break;
+ case ZM_MODE_INFRASTRUCTURE:
+ *mode = IW_MODE_INFRA;
+ break;
+ case ZM_MODE_IBSS:
+ *mode = IW_MODE_ADHOC;
+ break;
+ default:
+ *mode = IW_MODE_ADHOC;
+ break;
+ }
+
+ spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+
+ return 0;
}
int usbdrvwext_siwsens(struct net_device *dev,
@@ -743,338 +685,341 @@ int usbdrvwext_giwsens(struct net_device *dev,
}
int usbdrvwext_giwrange(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
- struct iw_range *range = (struct iw_range *) extra;
- int i, val;
- //int num_band_a;
- u16_t channels[60];
- u16_t channel_num;
-
- if(!netif_running(dev))
- return -EINVAL;
-
-#if WIRELESS_EXT > 9
- range->txpower_capa = IW_TXPOW_DBM;
-// XXX what about min/max_pmp, min/max_pmt, etc.
-#endif
-
-#if WIRELESS_EXT > 10
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 13;
-
- range->retry_capa = IW_RETRY_LIMIT;
- range->retry_flags = IW_RETRY_LIMIT;
- range->min_retry = 0;
- range->max_retry = 255;
-#endif /* WIRELESS_EXT > 10 */
-
- channel_num = zfiWlanQueryAllowChannels(dev, channels);
-
- /* Gurantee reported channel numbers is less or equal to IW_MAX_FREQUENCIES */
- if (channel_num > IW_MAX_FREQUENCIES)
- channel_num = IW_MAX_FREQUENCIES;
-
- val = 0;
-
- for (i = 0; i < channel_num; i++)
- {
- range->freq[val].i = usbdrv_freq2chan(channels[i]);
- range->freq[val].m = channels[i];
- range->freq[val].e = 6;
- val++;
- }
-
- range->num_channels = channel_num;
- range->num_frequency = channel_num;
-
-#if 0
- range->num_channels = 14; // Only 2.4G
-
-/* XXX need to filter against the regulatory domain &| active set */
- val = 0;
- for (i = 1; i <= 14; i++) // B,G Bands
- {
- range->freq[val].i = i;
- if (i == 14)
- range->freq[val].m = 2484000;
- else
- range->freq[val].m = (2412+(i-1)*5)*1000;
- range->freq[val].e = 3;
- val++;
- }
-
- num_band_a = (IW_MAX_FREQUENCIES - val);
-
- for (i = 0; i < num_band_a; i++) // A Bands
- {
- range->freq[val].i = channel_frequency_11A[2 * i];
- range->freq[val].m = channel_frequency_11A[2 * i + 1] * 1000;
- range->freq[val].e = 3;
- val++;
- }
- // MIMO Rate Not Defined Now
- //For 802.11a, there are too more frequency. We can't return them all
- range->num_frequency = val;
-#endif
-
-/* Max of /proc/net/wireless */
- range->max_qual.qual = 100; //?? //92;
- range->max_qual.level = 154; //??
- range->max_qual.noise = 154; //??
- range->sensitivity = 3; //??
-
-// XXX these need to be nsd-specific!
- range->min_rts = 0;
- range->max_rts = 2347;
- range->min_frag = 256;
- range->max_frag = 2346;
- range->max_encoding_tokens = 4/*NUM_WEPKEYS*/; //??
- range->num_encoding_sizes = 2; //??
+ struct iw_range *range = (struct iw_range *) extra;
+ int i, val;
+ /* int num_band_a; */
+ u16_t channels[60];
+ u16_t channel_num;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ #if WIRELESS_EXT > 9
+ range->txpower_capa = IW_TXPOW_DBM;
+ /* XXX what about min/max_pmp, min/max_pmt, etc. */
+ #endif
+
+ #if WIRELESS_EXT > 10
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 13;
+
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->min_retry = 0;
+ range->max_retry = 255;
+ #endif /* WIRELESS_EXT > 10 */
+
+ channel_num = zfiWlanQueryAllowChannels(dev, channels);
+
+ /* Gurantee reported channel numbers is less
+ * or equal to IW_MAX_FREQUENCIES
+ */
+ if (channel_num > IW_MAX_FREQUENCIES)
+ channel_num = IW_MAX_FREQUENCIES;
+
+ val = 0;
+
+ for (i = 0; i < channel_num; i++) {
+ range->freq[val].i = usbdrv_freq2chan(channels[i]);
+ range->freq[val].m = channels[i];
+ range->freq[val].e = 6;
+ val++;
+ }
- range->encoding_size[0] = 5; //?? //WEP Key Encoding Size
- range->encoding_size[1] = 13;//??
+ range->num_channels = channel_num;
+ range->num_frequency = channel_num;
-// XXX what about num_bitrates/throughput?
- range->num_bitrates = 0; //??
+ #if 0
+ range->num_channels = 14; /* Only 2.4G */
-/* estimated max throughput */
-// XXX need to cap it if we're running at ~2Mbps..
+ /* XXX need to filter against the regulatory domain &| active set */
+ val = 0;
+ /* B,G Bands */
+ for (i = 1; i <= 14; i++) {
+ range->freq[val].i = i;
+ if (i == 14)
+ range->freq[val].m = 2484000;
+ else
+ range->freq[val].m = (2412+(i-1)*5)*1000;
+ range->freq[val].e = 3;
+ val++;
+ }
- range->throughput = 300000000;
+ num_band_a = (IW_MAX_FREQUENCIES - val);
+ /* A Bands */
+ for (i = 0; i < num_band_a; i++) {
+ range->freq[val].i = channel_frequency_11A[2 * i];
+ range->freq[val].m = channel_frequency_11A[2 * i + 1] * 1000;
+ range->freq[val].e = 3;
+ val++;
+ }
+ /* MIMO Rate Not Defined Now
+ * For 802.11a, there are too more frequency.
+ * We can't return them all.
+ */
+ range->num_frequency = val;
+ #endif
+
+ /* Max of /proc/net/wireless */
+ range->max_qual.qual = 100; /* ?? 92; */
+ range->max_qual.level = 154; /* ?? */
+ range->max_qual.noise = 154; /* ?? */
+ range->sensitivity = 3; /* ?? */
+
+ /* XXX these need to be nsd-specific! */
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+ range->max_encoding_tokens = 4 /* NUM_WEPKEYS ?? */;
+ range->num_encoding_sizes = 2; /* ?? */
+
+ range->encoding_size[0] = 5; /* ?? WEP Key Encoding Size */
+ range->encoding_size[1] = 13; /* ?? */
+
+ /* XXX what about num_bitrates/throughput? */
+ range->num_bitrates = 0; /* ?? */
+
+ /* estimated max throughput
+ * XXX need to cap it if we're running at ~2Mbps..
+ */
+
+ range->throughput = 300000000;
- return 0;
+ return 0;
}
int usbdrvwext_siwap(struct net_device *dev, struct iw_request_info *info,
- struct sockaddr *MacAddr, char *extra)
+ struct sockaddr *MacAddr, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- zfiWlanSetMacAddress(dev,(u16_t *)&MacAddr->sa_data[0]);
- else //STA Mode
- zfiWlanSetBssid(dev,&MacAddr->sa_data[0]);
-
- if (macp->DeviceOpened == 1)
- {
- //u8_t wpaieLen,wpaie[80];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ zfiWlanSetMacAddress(dev, (u16_t *)&MacAddr->sa_data[0]);
+ } else {
+ /* STA Mode */
+ zfiWlanSetBssid(dev, &MacAddr->sa_data[0]);
+ }
+
+ if (macp->DeviceOpened == 1) {
+ /* u8_t wpaieLen,wpaie[80]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+
+ return 0;
}
int usbdrvwext_giwap(struct net_device *dev,
- struct iw_request_info *info,
- struct sockaddr *MacAddr, char *extra)
+ struct iw_request_info *info,
+ struct sockaddr *MacAddr, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- zfiWlanQueryMacAddress(dev, &MacAddr->sa_data[0]);
- else //STA Mode
- {
- if (macp->adapterState == ZM_STATUS_MEDIA_CONNECT)
- {
- zfiWlanQueryBssid(dev, &MacAddr->sa_data[0]);
- }
- else
- {
- u8_t zero_addr[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
- memcpy(&MacAddr->sa_data[0], zero_addr, sizeof(zero_addr));
- }
- }
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ zfiWlanQueryMacAddress(dev, &MacAddr->sa_data[0]);
+ } else {
+ /* STA Mode */
+ if (macp->adapterState == ZM_STATUS_MEDIA_CONNECT) {
+ zfiWlanQueryBssid(dev, &MacAddr->sa_data[0]);
+ } else {
+ u8_t zero_addr[6] = { 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00 };
+ memcpy(&MacAddr->sa_data[0], zero_addr,
+ sizeof(zero_addr));
+ }
+ }
+
+ return 0;
}
int usbdrvwext_iwaplist(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
- //Don't know how to do yet--CWYang(+)
- return 0;
+ /* Don't know how to do yet--CWYang(+) */
+ return 0;
}
int usbdrvwext_siwscan(struct net_device *dev, struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_point *data, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- printk("CWY - usbdrvwext_siwscan\n");
+ printk(KERN_WARNING "CWY - usbdrvwext_siwscan\n");
- zfiWlanScan(dev);
+ zfiWlanScan(dev);
- return 0;
+ return 0;
}
int usbdrvwext_giwscan(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- //struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev);
- char *current_ev = extra;
- char *end_buf;
- int i;
- //struct zsBssList BssList;
- struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1), GFP_KERNEL);
- //BssList = wd->sta.pBssList;
- //zmw_get_wlan_dev(dev);
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- if (data->length == 0)
- {
- end_buf = extra + IW_SCAN_MAX_DATA;
- }
- else
- {
- end_buf = extra + data->length;
- }
-
- printk("giwscan - Report Scan Results\n");
- //printk("giwscan - BssList Sreucture Len : %d\n", sizeof(BssList));
- //printk("giwscan - BssList Count : %d\n", wd->sta.pBssList->bssCount);
- //printk("giwscan - UpdateBssList Count : %d\n", wd->sta.pUpdateBssList->bssCount);
- zfiWlanQueryBssListV1(dev, pBssList);
- //zfiWlanQueryBssList(dev, &BssList);
-
-/* Read and parse all entries */
- printk("giwscan - pBssList->bssCount : %d\n", pBssList->bssCount);
- //printk("giwscan - BssList.bssCount : %d\n", BssList.bssCount);
-
- for (i = 0; i < pBssList->bssCount; i++)
- {
-/* Translate to WE format this entry */
- //current_ev = usbdrv_translate_scan(dev, info, current_ev,
- // extra + IW_SCAN_MAX_DATA, &pBssList->bssInfo[i]);
- current_ev = usbdrv_translate_scan(dev, info, current_ev,
- end_buf, &pBssList->bssInfo[i]);
-
-#if WIRELESS_EXT > 16
- if (current_ev == end_buf)
- {
- kfree(pBssList);
- data->length = current_ev - extra;
- return -E2BIG;
- }
-#endif
- }
+ struct usbdrv_private *macp = dev->ml_priv;
+ /* struct zsWlanDev* wd = (struct zsWlanDev*) zmw_wlan_dev(dev); */
+ char *current_ev = extra;
+ char *end_buf;
+ int i;
+ /* struct zsBssList BssList; */
+ struct zsBssListV1 *pBssList = kmalloc(sizeof(struct zsBssListV1),
+ GFP_KERNEL);
+ /* BssList = wd->sta.pBssList; */
+ /* zmw_get_wlan_dev(dev); */
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ if (data->length == 0)
+ end_buf = extra + IW_SCAN_MAX_DATA;
+ else
+ end_buf = extra + data->length;
+
+ printk(KERN_WARNING "giwscan - Report Scan Results\n");
+ /* printk("giwscan - BssList Sreucture Len : %d\n", sizeof(BssList));
+ * printk("giwscan - BssList Count : %d\n",
+ * wd->sta.pBssList->bssCount);
+ * printk("giwscan - UpdateBssList Count : %d\n",
+ * wd->sta.pUpdateBssList->bssCount);
+ */
+ zfiWlanQueryBssListV1(dev, pBssList);
+ /* zfiWlanQueryBssList(dev, &BssList); */
+
+ /* Read and parse all entries */
+ printk(KERN_WARNING "giwscan - pBssList->bssCount : %d\n",
+ pBssList->bssCount);
+ /* printk("giwscan - BssList.bssCount : %d\n", BssList.bssCount); */
+
+ for (i = 0; i < pBssList->bssCount; i++) {
+ /* Translate to WE format this entry
+ * current_ev = usbdrv_translate_scan(dev, info, current_ev,
+ * extra + IW_SCAN_MAX_DATA, &pBssList->bssInfo[i]);
+ */
+ current_ev = usbdrv_translate_scan(dev, info, current_ev,
+ end_buf, &pBssList->bssInfo[i]);
+
+ #if WIRELESS_EXT > 16
+ if (current_ev == end_buf) {
+ kfree(pBssList);
+ data->length = current_ev - extra;
+ return -E2BIG;
+ }
+ #endif
+ }
-/* Length of data */
- data->length = (current_ev - extra);
- data->flags = 0; /* todo */
+ /* Length of data */
+ data->length = (current_ev - extra);
+ data->flags = 0; /* todo */
- kfree(pBssList);
+ kfree(pBssList);
- return 0;
+ return 0;
}
int usbdrvwext_siwessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *essid, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *essid, char *extra)
{
- char EssidBuf[IW_ESSID_MAX_SIZE+1];
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if (essid->flags == 1)
- {
- if (essid->length > (IW_ESSID_MAX_SIZE+1))
- return -E2BIG;
-
- if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
- return -EFAULT;
-
- EssidBuf[essid->length] = '\0';
- //printk("siwessid - Set Essid : %s\n",EssidBuf);
- //printk("siwessid - Essid Len : %d\n",essid->length);
- //printk("siwessid - Essid Flag : %x\n",essid->flags);
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetSSID(dev, EssidBuf, strlen(EssidBuf));
- zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
- zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
- //u8_t wpaieLen,wpaie[50];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
- }
-
- return 0;
+ char EssidBuf[IW_ESSID_MAX_SIZE + 1];
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (essid->flags == 1) {
+ if (essid->length > (IW_ESSID_MAX_SIZE + 1))
+ return -E2BIG;
+
+ if (copy_from_user(&EssidBuf, essid->pointer, essid->length))
+ return -EFAULT;
+
+ EssidBuf[essid->length] = '\0';
+ /* printk("siwessid - Set Essid : %s\n",EssidBuf); */
+ /* printk("siwessid - Essid Len : %d\n",essid->length); */
+ /* printk("siwessid - Essid Flag : %x\n",essid->flags); */
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetSSID(dev, EssidBuf, strlen(EssidBuf));
+ zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev),
+ FALSE);
+ zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
+ /* u8_t wpaieLen,wpaie[50]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+ }
+
+ return 0;
}
int usbdrvwext_giwessid(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *essid, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *essid, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t EssidLen;
- char EssidBuf[IW_ESSID_MAX_SIZE+1];
- int ssid_len;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t EssidLen;
+ char EssidBuf[IW_ESSID_MAX_SIZE + 1];
+ int ssid_len;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
+ zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
- /* Convert type from unsigned char to char */
- ssid_len = (int)EssidLen;
+ /* Convert type from unsigned char to char */
+ ssid_len = (int)EssidLen;
- /* Make sure the essid length is not greater than IW_ESSID_MAX_SIZE */
- if (ssid_len > IW_ESSID_MAX_SIZE)
- ssid_len = IW_ESSID_MAX_SIZE;
+ /* Make sure the essid length is not greater than IW_ESSID_MAX_SIZE */
+ if (ssid_len > IW_ESSID_MAX_SIZE)
+ ssid_len = IW_ESSID_MAX_SIZE;
- EssidBuf[ssid_len] = '\0';
+ EssidBuf[ssid_len] = '\0';
- essid->flags = 1;
- essid->length = strlen(EssidBuf);
+ essid->flags = 1;
+ essid->length = strlen(EssidBuf);
- memcpy(extra, EssidBuf, essid->length);
- // wireless.c in Kernel would handle copy_to_user -- line 679
- /*if (essid->pointer)
- {
- if ( copy_to_user(essid->pointer, EssidBuf, essid->length) )
- {
- printk("giwessid - copy_to_user Fail\n");
- return -EFAULT;
- }
- }*/
+ memcpy(extra, EssidBuf, essid->length);
+ /* wireless.c in Kernel would handle copy_to_user -- line 679 */
+ /* if (essid->pointer) {
+ * if (copy_to_user(essid->pointer, EssidBuf, essid->length)) {
+ * printk("giwessid - copy_to_user Fail\n");
+ * return -EFAULT;
+ * }
+ * }
+ */
- return 0;
+ return 0;
}
int usbdrvwext_siwnickn(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *nickname)
{
- //Exist but junk--CWYang(+)
+ /* Exist but junk--CWYang(+) */
return 0;
}
@@ -1082,182 +1027,180 @@ int usbdrvwext_giwnickn(struct net_device *dev,
struct iw_request_info *info,
struct iw_point *data, char *nickname)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t EssidLen;
- char EssidBuf[IW_ESSID_MAX_SIZE+1];
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t EssidLen;
+ char EssidBuf[IW_ESSID_MAX_SIZE + 1];
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
- EssidBuf[EssidLen] = 0;
+ zfiWlanQuerySSID(dev, &EssidBuf[0], &EssidLen);
+ EssidBuf[EssidLen] = 0;
- data->flags = 1;
- data->length = strlen(EssidBuf);
+ data->flags = 1;
+ data->length = strlen(EssidBuf);
- memcpy(nickname, EssidBuf, data->length);
+ memcpy(nickname, EssidBuf, data->length);
return 0;
}
int usbdrvwext_siwrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
struct usbdrv_private *macp = dev->ml_priv;
- //Array to Define Rate Number that Send to Driver
- u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0, 48000,
- 24000, 12000, 6000, 54000, 36000, 18000, 9000};
- u16_t zcRateToMCS[] = {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd,
- 0x8, 0xc};
- u8_t i,RateIndex = 4;
- u16_t RateKbps;
-
- //printk("frq->disabled : 0x%x\n",frq->disabled);
- //printk("frq->value : 0x%x\n",frq->value);
-
- RateKbps = frq->value / 1000;
- //printk("RateKbps : %d\n", RateKbps);
- for (i = 0; i < 16; i++)
- {
- if (RateKbps == zcIndextoRateBG[i])
- RateIndex = i;
- }
- if (zcIndextoRateBG[RateIndex] == 0)
- RateIndex = 0xff;
- //printk("RateIndex : %x\n", RateIndex);
- for (i = 0; i < 13; i++)
- if (RateIndex == zcRateToMCS[i])
- break;
- //printk("Index : %x\n", i);
- if (RateKbps == 65000)
- {
- RateIndex = 20;
- printk("RateIndex : %d\n", RateIndex);
- }
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetTxRate(dev, i);
- //zfiWlanDisable(dev);
- //zfiWlanEnable(dev);
- }
-
- return 0;
+ /* Array to Define Rate Number that Send to Driver */
+ u16_t zcIndextoRateBG[16] = {1000, 2000, 5500, 11000, 0, 0, 0, 0,
+ 48000, 24000, 12000, 6000, 54000, 36000, 18000, 9000};
+ u16_t zcRateToMCS[] = {0xff, 0, 1, 2, 3, 0xb, 0xf, 0xa, 0xe, 0x9, 0xd,
+ 0x8, 0xc};
+ u8_t i, RateIndex = 4;
+ u16_t RateKbps;
+
+ /* printk("frq->disabled : 0x%x\n",frq->disabled); */
+ /* printk("frq->value : 0x%x\n",frq->value); */
+
+ RateKbps = frq->value / 1000;
+ /* printk("RateKbps : %d\n", RateKbps); */
+ for (i = 0; i < 16; i++) {
+ if (RateKbps == zcIndextoRateBG[i])
+ RateIndex = i;
+ }
+
+ if (zcIndextoRateBG[RateIndex] == 0)
+ RateIndex = 0xff;
+ /* printk("RateIndex : %x\n", RateIndex); */
+ for (i = 0; i < 13; i++)
+ if (RateIndex == zcRateToMCS[i])
+ break;
+ /* printk("Index : %x\n", i); */
+ if (RateKbps == 65000) {
+ RateIndex = 20;
+ printk(KERN_WARNING "RateIndex : %d\n", RateIndex);
+ }
+
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetTxRate(dev, i);
+ /* zfiWlanDisable(dev); */
+ /* zfiWlanEnable(dev); */
+ }
+
+ return 0;
}
int usbdrvwext_giwrate(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
+ struct usbdrv_private *macp = dev->ml_priv;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- frq->fixed = 0;
- frq->disabled = 0;
- frq->value = zfiWlanQueryRxRate(dev) * 1000;
+ frq->fixed = 0;
+ frq->disabled = 0;
+ frq->value = zfiWlanQueryRxRate(dev) * 1000;
- return 0;
+ return 0;
}
int usbdrvwext_siwrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rts, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- int val = rts->value;
+ struct usbdrv_private *macp = dev->ml_priv;
+ int val = rts->value;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- if (rts->disabled)
- val = 2347;
+ if (rts->disabled)
+ val = 2347;
- if ((val < 0) || (val > 2347))
- return -EINVAL;
+ if ((val < 0) || (val > 2347))
+ return -EINVAL;
- zfiWlanSetRtsThreshold(dev,val);
+ zfiWlanSetRtsThreshold(dev, val);
- return 0;
+ return 0;
}
int usbdrvwext_giwrts(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *rts, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (!netif_running(dev))
+ return -EINVAL;
- rts->value = zfiWlanQueryRtsThreshold(dev);
- rts->disabled = (rts->value >= 2347);
- rts->fixed = 1;
+ if (macp->DeviceOpened != 1)
+ return 0;
- return 0;
+ rts->value = zfiWlanQueryRtsThreshold(dev);
+ rts->disabled = (rts->value >= 2347);
+ rts->fixed = 1;
+ return 0;
}
int usbdrvwext_siwfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frag, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u16_t fragThreshold;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u16_t fragThreshold;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- if (frag->disabled)
- fragThreshold = 0;
- else
- fragThreshold = frag->value;
+ if (frag->disabled)
+ fragThreshold = 0;
+ else
+ fragThreshold = frag->value;
- zfiWlanSetFragThreshold(dev,fragThreshold);
+ zfiWlanSetFragThreshold(dev, fragThreshold);
- return 0;
+ return 0;
}
int usbdrvwext_giwfrag(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frag, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u16 val;
- unsigned long irqFlag;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u16 val;
+ unsigned long irqFlag;
- if(!netif_running(dev))
- return -EINVAL;
+ if (!netif_running(dev))
+ return -EINVAL;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- spin_lock_irqsave(&macp->cs_lock, irqFlag);
+ spin_lock_irqsave(&macp->cs_lock, irqFlag);
- val = zfiWlanQueryFragThreshold(dev);
+ val = zfiWlanQueryFragThreshold(dev);
- frag->value = val;
+ frag->value = val;
- frag->disabled = (val >= 2346);
- frag->fixed = 1;
+ frag->disabled = (val >= 2346);
+ frag->fixed = 1;
- spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+ spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
- return 0;
+ return 0;
}
int usbdrvwext_siwtxpow(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Not support yet--CWYng(+)
+ /* Not support yet--CWYng(+) */
return 0;
}
@@ -1265,7 +1208,7 @@ int usbdrvwext_giwtxpow(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Not support yet--CWYng(+)
+ /* Not support yet--CWYng(+) */
return 0;
}
@@ -1273,7 +1216,7 @@ int usbdrvwext_siwretry(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Do nothing--CWYang(+)
+ /* Do nothing--CWYang(+) */
return 0;
}
@@ -1281,665 +1224,662 @@ int usbdrvwext_giwretry(struct net_device *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
- //Do nothing--CWYang(+)
+ /* Do nothing--CWYang(+) */
return 0;
}
int usbdrvwext_siwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *key)
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
{
- struct zsKeyInfo keyInfo;
- int i, WepState = ZM_ENCRYPTION_WEP_DISABLED;
- struct usbdrv_private *macp = dev->ml_priv;
-
- if(!netif_running(dev))
- return -EINVAL;
-
- if ((erq->flags & IW_ENCODE_DISABLED) == 0)
- {
- keyInfo.key = key;
- keyInfo.keyLength = erq->length;
- keyInfo.keyIndex = (erq->flags & IW_ENCODE_INDEX) - 1;
- if (keyInfo.keyIndex >= 4)
- keyInfo.keyIndex = 0;
- keyInfo.flag = ZM_KEY_FLAG_DEFAULT_KEY;
-
- zfiWlanSetKey(dev, keyInfo);
- WepState = ZM_ENCRYPTION_WEP_ENABLED;
- }
- else
- {
- for (i = 1; i < 4; i++)
- zfiWlanRemoveKey(dev, 0, i);
- WepState = ZM_ENCRYPTION_WEP_DISABLED;
- //zfiWlanSetEncryMode(dev, ZM_NO_WEP);
- }
-
- if (macp->DeviceOpened == 1)
- {
- zfiWlanSetWepStatus(dev, WepState);
- zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
- //zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev));
- //u8_t wpaieLen,wpaie[50];
- //zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen);
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- //if (wpaieLen > 2)
- // zfiWlanSetWpaIe(dev, wpaie, wpaieLen);
- }
-
- return 0;
+ struct zsKeyInfo keyInfo;
+ int i;
+ int WepState = ZM_ENCRYPTION_WEP_DISABLED;
+ struct usbdrv_private *macp = dev->ml_priv;
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if ((erq->flags & IW_ENCODE_DISABLED) == 0) {
+ keyInfo.key = key;
+ keyInfo.keyLength = erq->length;
+ keyInfo.keyIndex = (erq->flags & IW_ENCODE_INDEX) - 1;
+ if (keyInfo.keyIndex >= 4)
+ keyInfo.keyIndex = 0;
+ keyInfo.flag = ZM_KEY_FLAG_DEFAULT_KEY;
+
+ zfiWlanSetKey(dev, keyInfo);
+ WepState = ZM_ENCRYPTION_WEP_ENABLED;
+ } else {
+ for (i = 1; i < 4; i++)
+ zfiWlanRemoveKey(dev, 0, i);
+ WepState = ZM_ENCRYPTION_WEP_DISABLED;
+ /* zfiWlanSetEncryMode(dev, ZM_NO_WEP); */
+ }
+
+ if (macp->DeviceOpened == 1) {
+ zfiWlanSetWepStatus(dev, WepState);
+ zfiWlanSetFrequency(dev, zfiWlanQueryFrequency(dev), FALSE);
+ /* zfiWlanSetEncryMode(dev, zfiWlanQueryEncryMode(dev)); */
+ /* u8_t wpaieLen,wpaie[50]; */
+ /* zfiWlanQueryWpaIe(dev, wpaie, &wpaieLen); */
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ /* if (wpaieLen > 2) */
+ /* zfiWlanSetWpaIe(dev, wpaie, wpaieLen); */
+ }
+
+ return 0;
}
int usbdrvwext_giwencode(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *erq, char *key)
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t EncryptionMode;
- u8_t keyLen = 0;
-
- if (macp->DeviceOpened != 1)
- return 0;
-
- EncryptionMode = zfiWlanQueryEncryMode(dev);
-
- if (EncryptionMode)
- {
- erq->flags = IW_ENCODE_ENABLED;
- }
- else
- {
- erq->flags = IW_ENCODE_DISABLED;
- }
-
-/* We can't return the key, so set the proper flag and return zero */
- erq->flags |= IW_ENCODE_NOKEY;
- memset(key, 0, 16);
-
-/* Copy the key to the user buffer */
- switch(EncryptionMode)
- {
- case ZM_WEP64:
- keyLen = 5;
- break;
- case ZM_WEP128:
- keyLen = 13;
- break;
- case ZM_WEP256:
- keyLen = 29;
- break;
- case ZM_AES:
- keyLen = 16;
- break;
- case ZM_TKIP:
- keyLen = 32;
- break;
-#ifdef ZM_ENABLE_CENC
- case ZM_CENC:
- keyLen = 32;
- break;
-#endif //ZM_ENABLE_CENC
- case ZM_NO_WEP:
- keyLen = 0;
- break;
- default :
- keyLen = 0;
- printk("Unknown EncryMode\n");
- break;
-
- }
- erq->length = keyLen;
-
- return 0;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t EncryptionMode;
+ u8_t keyLen = 0;
+
+ if (macp->DeviceOpened != 1)
+ return 0;
+
+ EncryptionMode = zfiWlanQueryEncryMode(dev);
+
+ if (EncryptionMode)
+ erq->flags = IW_ENCODE_ENABLED;
+ else
+ erq->flags = IW_ENCODE_DISABLED;
+
+ /* We can't return the key, so set the proper flag and return zero */
+ erq->flags |= IW_ENCODE_NOKEY;
+ memset(key, 0, 16);
+
+ /* Copy the key to the user buffer */
+ switch (EncryptionMode) {
+ case ZM_WEP64:
+ keyLen = 5;
+ break;
+ case ZM_WEP128:
+ keyLen = 13;
+ break;
+ case ZM_WEP256:
+ keyLen = 29;
+ break;
+ case ZM_AES:
+ keyLen = 16;
+ break;
+ case ZM_TKIP:
+ keyLen = 32;
+ break;
+ #ifdef ZM_ENABLE_CENC
+ case ZM_CENC:
+ /* ZM_ENABLE_CENC */
+ keyLen = 32;
+ break;
+ #endif
+ case ZM_NO_WEP:
+ keyLen = 0;
+ break;
+ default:
+ keyLen = 0;
+ printk(KERN_ERR "Unknown EncryMode\n");
+ break;
+ }
+ erq->length = keyLen;
+
+ return 0;
}
int usbdrvwext_siwpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
- struct usbdrv_private *macp = dev->ml_priv;
- u8_t PSMode;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u8_t PSMode;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- if (frq->disabled)
- PSMode = ZM_STA_PS_NONE;
- else
- PSMode = ZM_STA_PS_MAX;
+ if (frq->disabled)
+ PSMode = ZM_STA_PS_NONE;
+ else
+ PSMode = ZM_STA_PS_MAX;
- zfiWlanSetPowerSaveMode(dev,PSMode);
+ zfiWlanSetPowerSaveMode(dev, PSMode);
- return 0;
+ return 0;
}
int usbdrvwext_giwpower(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *frq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *frq, char *extra)
{
- unsigned long irqFlag;
- struct usbdrv_private *macp = dev->ml_priv;
+ unsigned long irqFlag;
+ struct usbdrv_private *macp = dev->ml_priv;
- if (macp->DeviceOpened != 1)
- return 0;
+ if (macp->DeviceOpened != 1)
+ return 0;
- spin_lock_irqsave(&macp->cs_lock, irqFlag);
+ spin_lock_irqsave(&macp->cs_lock, irqFlag);
- if (zfiWlanQueryPowerSaveMode(dev) == ZM_STA_PS_NONE)
- frq->disabled = 1;
- else
- frq->disabled = 0;
+ if (zfiWlanQueryPowerSaveMode(dev) == ZM_STA_PS_NONE)
+ frq->disabled = 1;
+ else
+ frq->disabled = 0;
- spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
+ spin_unlock_irqrestore(&macp->cs_lock, irqFlag);
- return 0;
+ return 0;
}
-//int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
-// void *w, char *extra)
-//{
-// struct ieee80211vap *vap = dev->ml_priv;
-// struct ieee80211com *ic = vap->iv_ic;
-// struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
-// int *i = (int *) extra;
-// int param = i[0]; /* parameter id is 1st */
-// int value = i[1]; /* NB: most values are TYPE_INT */
-// int retv = 0;
-// int j, caps;
-// const struct ieee80211_authenticator *auth;
-// const struct ieee80211_aclator *acl;
-//
-// switch (param) {
-// case IEEE80211_PARAM_AUTHMODE:
-// switch (value) {
-// case IEEE80211_AUTH_WPA: /* WPA */
-// case IEEE80211_AUTH_8021X: /* 802.1x */
-// case IEEE80211_AUTH_OPEN: /* open */
-// case IEEE80211_AUTH_SHARED: /* shared-key */
-// case IEEE80211_AUTH_AUTO: /* auto */
-// auth = ieee80211_authenticator_get(value);
-// if (auth == NULL)
-// return -EINVAL;
-// break;
-// default:
-// return -EINVAL;
-// }
-// switch (value) {
-// case IEEE80211_AUTH_WPA: /* WPA w/ 802.1x */
-// vap->iv_flags |= IEEE80211_F_PRIVACY;
-// value = IEEE80211_AUTH_8021X;
-// break;
-// case IEEE80211_AUTH_OPEN: /* open */
-// vap->iv_flags &= ~(IEEE80211_F_WPA|IEEE80211_F_PRIVACY);
-// break;
-// case IEEE80211_AUTH_SHARED: /* shared-key */
-// case IEEE80211_AUTH_AUTO: /* auto */
-// case IEEE80211_AUTH_8021X: /* 802.1x */
-// vap->iv_flags &= ~IEEE80211_F_WPA;
-// /* both require a key so mark the PRIVACY capability */
-// vap->iv_flags |= IEEE80211_F_PRIVACY;
-// break;
-// }
-// /* NB: authenticator attach/detach happens on state change */
-// vap->iv_bss->ni_authmode = value;
-// /* XXX mixed/mode/usage? */
-// vap->iv_auth = auth;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_PROTMODE:
-// if (value > IEEE80211_PROT_RTSCTS)
-// return -EINVAL;
-// ic->ic_protmode = value;
-// /* NB: if not operating in 11g this can wait */
-// if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
-// IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_MCASTCIPHER:
-// if ((vap->iv_caps & cipher2cap(value)) == 0 &&
-// !ieee80211_crypto_available(value))
-// return -EINVAL;
-// rsn->rsn_mcastcipher = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_MCASTKEYLEN:
-// if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
-// return -EINVAL;
-// /* XXX no way to verify driver capability */
-// rsn->rsn_mcastkeylen = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_UCASTCIPHERS:
-// /*
-// * Convert cipher set to equivalent capabilities.
-// * NB: this logic intentionally ignores unknown and
-// * unsupported ciphers so folks can specify 0xff or
-// * similar and get all available ciphers.
-// */
-// caps = 0;
-// for (j = 1; j < 32; j++) /* NB: skip WEP */
-// if ((value & (1<<j)) &&
-// ((vap->iv_caps & cipher2cap(j)) ||
-// ieee80211_crypto_available(j)))
-// caps |= 1<<j;
-// if (caps == 0) /* nothing available */
-// return -EINVAL;
-// /* XXX verify ciphers ok for unicast use? */
-// /* XXX disallow if running as it'll have no effect */
-// rsn->rsn_ucastcipherset = caps;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_UCASTCIPHER:
-// if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0)
-// return -EINVAL;
-// rsn->rsn_ucastcipher = value;
-// break;
-// case IEEE80211_PARAM_UCASTKEYLEN:
-// if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
-// return -EINVAL;
-// /* XXX no way to verify driver capability */
-// rsn->rsn_ucastkeylen = value;
-// break;
-// case IEEE80211_PARAM_KEYMGTALGS:
-// /* XXX check */
-// rsn->rsn_keymgmtset = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_RSNCAPS:
-// /* XXX check */
-// rsn->rsn_caps = value;
-// if (vap->iv_flags & IEEE80211_F_WPA)
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_WPA:
-// if (value > 3)
-// return -EINVAL;
-// /* XXX verify ciphers available */
-// vap->iv_flags &= ~IEEE80211_F_WPA;
-// switch (value) {
-// case 1:
-// vap->iv_flags |= IEEE80211_F_WPA1;
-// break;
-// case 2:
-// vap->iv_flags |= IEEE80211_F_WPA2;
-// break;
-// case 3:
-// vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
-// break;
-// }
-// retv = ENETRESET; /* XXX? */
-// break;
-// case IEEE80211_PARAM_ROAMING:
-// if (!(IEEE80211_ROAMING_DEVICE <= value &&
-// value <= IEEE80211_ROAMING_MANUAL))
-// return -EINVAL;
-// ic->ic_roaming = value;
-// break;
-// case IEEE80211_PARAM_PRIVACY:
-// if (value) {
-// /* XXX check for key state? */
-// vap->iv_flags |= IEEE80211_F_PRIVACY;
-// } else
-// vap->iv_flags &= ~IEEE80211_F_PRIVACY;
-// break;
-// case IEEE80211_PARAM_DROPUNENCRYPTED:
-// if (value)
-// vap->iv_flags |= IEEE80211_F_DROPUNENC;
-// else
-// vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
-// break;
-// case IEEE80211_PARAM_COUNTERMEASURES:
-// if (value) {
-// if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
-// return -EINVAL;
-// vap->iv_flags |= IEEE80211_F_COUNTERM;
-// } else
-// vap->iv_flags &= ~IEEE80211_F_COUNTERM;
-// break;
-// case IEEE80211_PARAM_DRIVER_CAPS:
-// vap->iv_caps = value; /* NB: for testing */
-// break;
-// case IEEE80211_PARAM_MACCMD:
-// acl = vap->iv_acl;
-// switch (value) {
-// case IEEE80211_MACCMD_POLICY_OPEN:
-// case IEEE80211_MACCMD_POLICY_ALLOW:
-// case IEEE80211_MACCMD_POLICY_DENY:
-// if (acl == NULL) {
-// acl = ieee80211_aclator_get("mac");
-// if (acl == NULL || !acl->iac_attach(vap))
-// return -EINVAL;
-// vap->iv_acl = acl;
-// }
-// acl->iac_setpolicy(vap, value);
-// break;
-// case IEEE80211_MACCMD_FLUSH:
-// if (acl != NULL)
-// acl->iac_flush(vap);
-// /* NB: silently ignore when not in use */
-// break;
-// case IEEE80211_MACCMD_DETACH:
-// if (acl != NULL) {
-// vap->iv_acl = NULL;
-// acl->iac_detach(vap);
-// }
-// break;
-// }
-// break;
-// case IEEE80211_PARAM_WMM:
-// if (ic->ic_caps & IEEE80211_C_WME){
-// if (value) {
-// vap->iv_flags |= IEEE80211_F_WME;
-// vap->iv_ic->ic_flags |= IEEE80211_F_WME; /* XXX needed by ic_reset */
-// }
-// else {
-// vap->iv_flags &= ~IEEE80211_F_WME;
-// vap->iv_ic->ic_flags &= ~IEEE80211_F_WME; /* XXX needed by ic_reset */
-// }
-// retv = ENETRESET; /* Renegotiate for capabilities */
-// }
-// break;
-// case IEEE80211_PARAM_HIDESSID:
-// if (value)
-// vap->iv_flags |= IEEE80211_F_HIDESSID;
-// else
-// vap->iv_flags &= ~IEEE80211_F_HIDESSID;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_APBRIDGE:
-// if (value == 0)
-// vap->iv_flags |= IEEE80211_F_NOBRIDGE;
-// else
-// vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
-// break;
-// case IEEE80211_PARAM_INACT:
-// vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
-// break;
-// case IEEE80211_PARAM_INACT_AUTH:
-// vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
-// break;
-// case IEEE80211_PARAM_INACT_INIT:
-// vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
-// break;
-// case IEEE80211_PARAM_ABOLT:
-// caps = 0;
-// /*
-// * Map abolt settings to capability bits;
-// * this also strips unknown/unwanted bits.
-// */
-// if (value & IEEE80211_ABOLT_TURBO_PRIME)
-// caps |= IEEE80211_ATHC_TURBOP;
-// if (value & IEEE80211_ABOLT_COMPRESSION)
-// caps |= IEEE80211_ATHC_COMP;
-// if (value & IEEE80211_ABOLT_FAST_FRAME)
-// caps |= IEEE80211_ATHC_FF;
-// if (value & IEEE80211_ABOLT_XR)
-// caps |= IEEE80211_ATHC_XR;
-// if (value & IEEE80211_ABOLT_AR)
-// caps |= IEEE80211_ATHC_AR;
-// if (value & IEEE80211_ABOLT_BURST)
-// caps |= IEEE80211_ATHC_BURST;
-// if (value & IEEE80211_ABOLT_WME_ELE)
-// caps |= IEEE80211_ATHC_WME;
-// /* verify requested capabilities are supported */
-// if ((caps & ic->ic_ath_cap) != caps)
-// return -EINVAL;
-// if (vap->iv_ath_cap != caps) {
-// if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) {
-// if (ieee80211_set_turbo(dev, caps & IEEE80211_ATHC_TURBOP))
-// return -EINVAL;
-// ieee80211_scan_flush(ic);
-// }
-// vap->iv_ath_cap = caps;
-// ic->ic_athcapsetup(vap->iv_ic, vap->iv_ath_cap);
-// retv = ENETRESET;
-// }
-// break;
-// case IEEE80211_PARAM_DTIM_PERIOD:
-// if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
-// vap->iv_opmode != IEEE80211_M_IBSS)
-// return -EINVAL;
-// if (IEEE80211_DTIM_MIN <= value &&
-// value <= IEEE80211_DTIM_MAX) {
-// vap->iv_dtim_period = value;
-// retv = ENETRESET; /* requires restart */
-// } else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_BEACON_INTERVAL:
-// if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
-// vap->iv_opmode != IEEE80211_M_IBSS)
-// return -EINVAL;
-// if (IEEE80211_BINTVAL_MIN <= value &&
-// value <= IEEE80211_BINTVAL_MAX) {
-// ic->ic_lintval = value; /* XXX multi-bss */
-// retv = ENETRESET; /* requires restart */
-// } else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_DOTH:
-// if (value) {
-// ic->ic_flags |= IEEE80211_F_DOTH;
-// }
-// else
-// ic->ic_flags &= ~IEEE80211_F_DOTH;
-// retv = ENETRESET; /* XXX: need something this drastic? */
-// break;
-// case IEEE80211_PARAM_PWRTARGET:
-// ic->ic_curchanmaxpwr = value;
-// break;
-// case IEEE80211_PARAM_GENREASSOC:
-// IEEE80211_SEND_MGMT(vap->iv_bss, IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
-// break;
-// case IEEE80211_PARAM_COMPRESSION:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value);
-// break;
-// case IEEE80211_PARAM_WMM_AGGRMODE:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_WME, value);
-// break;
-// case IEEE80211_PARAM_FF:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value);
-// break;
-// case IEEE80211_PARAM_TURBO:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value);
-// if (retv == ENETRESET) {
-// if(ieee80211_set_turbo(dev,value))
-// return -EINVAL;
-// ieee80211_scan_flush(ic);
-// }
-// break;
-// case IEEE80211_PARAM_XR:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);
-// break;
-// case IEEE80211_PARAM_BURST:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value);
-// break;
-// case IEEE80211_PARAM_AR:
-// retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value);
-// break;
-// case IEEE80211_PARAM_PUREG:
-// if (value)
-// vap->iv_flags |= IEEE80211_F_PUREG;
-// else
-// vap->iv_flags &= ~IEEE80211_F_PUREG;
-// /* NB: reset only if we're operating on an 11g channel */
-// if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
-// IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_WDS:
-// if (value)
-// vap->iv_flags_ext |= IEEE80211_FEXT_WDS;
-// else
-// vap->iv_flags_ext &= ~IEEE80211_FEXT_WDS;
-// break;
-// case IEEE80211_PARAM_BGSCAN:
-// if (value) {
-// if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
-// return -EINVAL;
-// vap->iv_flags |= IEEE80211_F_BGSCAN;
-// } else {
-// /* XXX racey? */
-// vap->iv_flags &= ~IEEE80211_F_BGSCAN;
-// ieee80211_cancel_scan(vap); /* anything current */
-// }
-// break;
-// case IEEE80211_PARAM_BGSCAN_IDLE:
-// if (value >= IEEE80211_BGSCAN_IDLE_MIN)
-// vap->iv_bgscanidle = value*HZ/1000;
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_BGSCAN_INTERVAL:
-// if (value >= IEEE80211_BGSCAN_INTVAL_MIN)
-// vap->iv_bgscanintvl = value*HZ;
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_MCAST_RATE:
-// /* units are in KILObits per second */
-// if (value >= 256 && value <= 54000)
-// vap->iv_mcast_rate = value;
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_COVERAGE_CLASS:
-// if (value >= 0 && value <= IEEE80211_COVERAGE_CLASS_MAX) {
-// ic->ic_coverageclass = value;
-// if (IS_UP_AUTO(vap))
-// ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
-// retv = 0;
-// }
-// else
-// retv = EINVAL;
-// break;
-// case IEEE80211_PARAM_COUNTRY_IE:
-// if (value)
-// ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;
-// else
-// ic->ic_flags_ext &= ~IEEE80211_FEXT_COUNTRYIE;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_REGCLASS:
-// if (value)
-// ic->ic_flags_ext |= IEEE80211_FEXT_REGCLASS;
-// else
-// ic->ic_flags_ext &= ~IEEE80211_FEXT_REGCLASS;
-// retv = ENETRESET;
-// break;
-// case IEEE80211_PARAM_SCANVALID:
-// vap->iv_scanvalid = value*HZ;
-// break;
-// case IEEE80211_PARAM_ROAM_RSSI_11A:
-// vap->iv_roam.rssi11a = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RSSI_11B:
-// vap->iv_roam.rssi11bOnly = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RSSI_11G:
-// vap->iv_roam.rssi11b = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RATE_11A:
-// vap->iv_roam.rate11a = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RATE_11B:
-// vap->iv_roam.rate11bOnly = value;
-// break;
-// case IEEE80211_PARAM_ROAM_RATE_11G:
-// vap->iv_roam.rate11b = value;
-// break;
-// case IEEE80211_PARAM_UAPSDINFO:
-// if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-// if (ic->ic_caps & IEEE80211_C_UAPSD) {
-// if (value)
-// IEEE80211_VAP_UAPSD_ENABLE(vap);
-// else
-// IEEE80211_VAP_UAPSD_DISABLE(vap);
-// retv = ENETRESET;
-// }
-// }
-// else if (vap->iv_opmode == IEEE80211_M_STA) {
-// vap->iv_uapsdinfo = value;
-// IEEE80211_VAP_UAPSD_ENABLE(vap);
-// retv = ENETRESET;
-// }
-// break;
-// case IEEE80211_PARAM_SLEEP:
-// /* XXX: Forced sleep for testing. Does not actually place the
-// * HW in sleep mode yet. this only makes sense for STAs.
-// */
-// if (value) {
-// /* goto sleep */
-// IEEE80211_VAP_GOTOSLEEP(vap);
-// }
-// else {
-// /* wakeup */
-// IEEE80211_VAP_WAKEUP(vap);
-// }
-// ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
-// break;
-// case IEEE80211_PARAM_QOSNULL:
-// /* Force a QoS Null for testing. */
-// ieee80211_send_qosnulldata(vap->iv_bss, value);
-// break;
-// case IEEE80211_PARAM_PSPOLL:
-// /* Force a PS-POLL for testing. */
-// ieee80211_send_pspoll(vap->iv_bss);
-// break;
-// case IEEE80211_PARAM_EOSPDROP:
-// if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
-// if (value) IEEE80211_VAP_EOSPDROP_ENABLE(vap);
-// else IEEE80211_VAP_EOSPDROP_DISABLE(vap);
-// }
-// break;
-// case IEEE80211_PARAM_MARKDFS:
-// if (value)
-// ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
-// else
-// ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
-// break;
-// case IEEE80211_PARAM_CHANBW:
-// switch (value) {
-// case 0:
-// ic->ic_chanbwflag = 0;
-// break;
-// case 1:
-// ic->ic_chanbwflag = IEEE80211_CHAN_HALF;
-// break;
-// case 2:
-// ic->ic_chanbwflag = IEEE80211_CHAN_QUARTER;
-// break;
-// default:
-// retv = EINVAL;
-// break;
-// }
-// break;
-// case IEEE80211_PARAM_SHORTPREAMBLE:
-// if (value) {
-// ic->ic_caps |= IEEE80211_C_SHPREAMBLE;
-// } else {
-// ic->ic_caps &= ~IEEE80211_C_SHPREAMBLE;
-// }
-// retv = ENETRESET;
-// break;
-// default:
-// retv = EOPNOTSUPP;
-// break;
-// }
-// /* XXX should any of these cause a rescan? */
-// if (retv == ENETRESET)
-// retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
-// return -retv;
-//}
+/*int usbdrvwext_setparam(struct net_device *dev, struct iw_request_info *info,
+* void *w, char *extra)
+*{
+* struct ieee80211vap *vap = dev->ml_priv;
+* struct ieee80211com *ic = vap->iv_ic;
+* struct ieee80211_rsnparms *rsn = &vap->iv_bss->ni_rsn;
+* int *i = (int *) extra;
+* int param = i[0]; // parameter id is 1st
+* int value = i[1]; // NB: most values are TYPE_INT
+* int retv = 0;
+* int j, caps;
+* const struct ieee80211_authenticator *auth;
+* const struct ieee80211_aclator *acl;
+*
+* switch (param) {
+* case IEEE80211_PARAM_AUTHMODE:
+* switch (value) {
+* case IEEE80211_AUTH_WPA: // WPA
+* case IEEE80211_AUTH_8021X: // 802.1x
+* case IEEE80211_AUTH_OPEN: // open
+* case IEEE80211_AUTH_SHARED: // shared-key
+* case IEEE80211_AUTH_AUTO: // auto
+* auth = ieee80211_authenticator_get(value);
+* if (auth == NULL)
+* return -EINVAL;
+* break;
+* default:
+* return -EINVAL;
+* }
+* switch (value) {
+* case IEEE80211_AUTH_WPA: // WPA w/ 802.1x
+* vap->iv_flags |= IEEE80211_F_PRIVACY;
+* value = IEEE80211_AUTH_8021X;
+* break;
+* case IEEE80211_AUTH_OPEN: // open
+* vap->iv_flags &= ~(IEEE80211_F_WPA | IEEE80211_F_PRIVACY);
+* break;
+* case IEEE80211_AUTH_SHARED: // shared-key
+* case IEEE80211_AUTH_AUTO: // auto
+* case IEEE80211_AUTH_8021X: // 802.1x
+* vap->iv_flags &= ~IEEE80211_F_WPA;
+* // both require a key so mark the PRIVACY capability
+* vap->iv_flags |= IEEE80211_F_PRIVACY;
+* break;
+* }
+* // NB: authenticator attach/detach happens on state change
+* vap->iv_bss->ni_authmode = value;
+* // XXX mixed/mode/usage?
+* vap->iv_auth = auth;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_PROTMODE:
+* if (value > IEEE80211_PROT_RTSCTS)
+* return -EINVAL;
+* ic->ic_protmode = value;
+* // NB: if not operating in 11g this can wait
+* if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
+* IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_MCASTCIPHER:
+* if ((vap->iv_caps & cipher2cap(value)) == 0 &&
+* !ieee80211_crypto_available(value))
+* return -EINVAL;
+* rsn->rsn_mcastcipher = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_MCASTKEYLEN:
+* if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
+* return -EINVAL;
+* // XXX no way to verify driver capability
+* rsn->rsn_mcastkeylen = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_UCASTCIPHERS:
+*
+* // Convert cipher set to equivalent capabilities.
+* // NB: this logic intentionally ignores unknown and
+* // unsupported ciphers so folks can specify 0xff or
+* // similar and get all available ciphers.
+*
+* caps = 0;
+* for (j = 1; j < 32; j++) // NB: skip WEP
+* if ((value & (1<<j)) &&
+* ((vap->iv_caps & cipher2cap(j)) ||
+* ieee80211_crypto_available(j)))
+* caps |= 1<<j;
+* if (caps == 0) // nothing available
+* return -EINVAL;
+* // XXX verify ciphers ok for unicast use?
+* // XXX disallow if running as it'll have no effect
+* rsn->rsn_ucastcipherset = caps;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_UCASTCIPHER:
+* if ((rsn->rsn_ucastcipherset & cipher2cap(value)) == 0)
+* return -EINVAL;
+* rsn->rsn_ucastcipher = value;
+* break;
+* case IEEE80211_PARAM_UCASTKEYLEN:
+* if (!(0 < value && value < IEEE80211_KEYBUF_SIZE))
+* return -EINVAL;
+* // XXX no way to verify driver capability
+* rsn->rsn_ucastkeylen = value;
+* break;
+* case IEEE80211_PARAM_KEYMGTALGS:
+* // XXX check
+* rsn->rsn_keymgmtset = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_RSNCAPS:
+* // XXX check
+* rsn->rsn_caps = value;
+* if (vap->iv_flags & IEEE80211_F_WPA)
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_WPA:
+* if (value > 3)
+* return -EINVAL;
+* // XXX verify ciphers available
+* vap->iv_flags &= ~IEEE80211_F_WPA;
+* switch (value) {
+* case 1:
+* vap->iv_flags |= IEEE80211_F_WPA1;
+* break;
+* case 2:
+* vap->iv_flags |= IEEE80211_F_WPA2;
+* break;
+* case 3:
+* vap->iv_flags |= IEEE80211_F_WPA1 | IEEE80211_F_WPA2;
+* break;
+* }
+* retv = ENETRESET; // XXX?
+* break;
+* case IEEE80211_PARAM_ROAMING:
+* if (!(IEEE80211_ROAMING_DEVICE <= value &&
+* value <= IEEE80211_ROAMING_MANUAL))
+* return -EINVAL;
+* ic->ic_roaming = value;
+* break;
+* case IEEE80211_PARAM_PRIVACY:
+* if (value) {
+* // XXX check for key state?
+* vap->iv_flags |= IEEE80211_F_PRIVACY;
+* } else
+* vap->iv_flags &= ~IEEE80211_F_PRIVACY;
+* break;
+* case IEEE80211_PARAM_DROPUNENCRYPTED:
+* if (value)
+* vap->iv_flags |= IEEE80211_F_DROPUNENC;
+* else
+* vap->iv_flags &= ~IEEE80211_F_DROPUNENC;
+* break;
+* case IEEE80211_PARAM_COUNTERMEASURES:
+* if (value) {
+* if ((vap->iv_flags & IEEE80211_F_WPA) == 0)
+* return -EINVAL;
+* vap->iv_flags |= IEEE80211_F_COUNTERM;
+* } else
+* vap->iv_flags &= ~IEEE80211_F_COUNTERM;
+* break;
+* case IEEE80211_PARAM_DRIVER_CAPS:
+* vap->iv_caps = value; // NB: for testing
+* break;
+* case IEEE80211_PARAM_MACCMD:
+* acl = vap->iv_acl;
+* switch (value) {
+* case IEEE80211_MACCMD_POLICY_OPEN:
+* case IEEE80211_MACCMD_POLICY_ALLOW:
+* case IEEE80211_MACCMD_POLICY_DENY:
+* if (acl == NULL) {
+* acl = ieee80211_aclator_get("mac");
+* if (acl == NULL || !acl->iac_attach(vap))
+* return -EINVAL;
+* vap->iv_acl = acl;
+* }
+* acl->iac_setpolicy(vap, value);
+* break;
+* case IEEE80211_MACCMD_FLUSH:
+* if (acl != NULL)
+* acl->iac_flush(vap);
+* // NB: silently ignore when not in use
+* break;
+* case IEEE80211_MACCMD_DETACH:
+* if (acl != NULL) {
+* vap->iv_acl = NULL;
+* acl->iac_detach(vap);
+* }
+* break;
+* }
+* break;
+* case IEEE80211_PARAM_WMM:
+* if (ic->ic_caps & IEEE80211_C_WME){
+* if (value) {
+* vap->iv_flags |= IEEE80211_F_WME;
+* *//* XXX needed by ic_reset *//*
+* vap->iv_ic->ic_flags |= IEEE80211_F_WME;
+* }
+* else {
+* *//* XXX needed by ic_reset *//*
+* vap->iv_flags &= ~IEEE80211_F_WME;
+* vap->iv_ic->ic_flags &= ~IEEE80211_F_WME;
+* }
+* retv = ENETRESET; // Renegotiate for capabilities
+* }
+* break;
+* case IEEE80211_PARAM_HIDESSID:
+* if (value)
+* vap->iv_flags |= IEEE80211_F_HIDESSID;
+* else
+* vap->iv_flags &= ~IEEE80211_F_HIDESSID;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_APBRIDGE:
+* if (value == 0)
+* vap->iv_flags |= IEEE80211_F_NOBRIDGE;
+* else
+* vap->iv_flags &= ~IEEE80211_F_NOBRIDGE;
+* break;
+* case IEEE80211_PARAM_INACT:
+* vap->iv_inact_run = value / IEEE80211_INACT_WAIT;
+* break;
+* case IEEE80211_PARAM_INACT_AUTH:
+* vap->iv_inact_auth = value / IEEE80211_INACT_WAIT;
+* break;
+* case IEEE80211_PARAM_INACT_INIT:
+* vap->iv_inact_init = value / IEEE80211_INACT_WAIT;
+* break;
+* case IEEE80211_PARAM_ABOLT:
+* caps = 0;
+*
+* // Map abolt settings to capability bits;
+* // this also strips unknown/unwanted bits.
+*
+* if (value & IEEE80211_ABOLT_TURBO_PRIME)
+* caps |= IEEE80211_ATHC_TURBOP;
+* if (value & IEEE80211_ABOLT_COMPRESSION)
+* caps |= IEEE80211_ATHC_COMP;
+* if (value & IEEE80211_ABOLT_FAST_FRAME)
+* caps |= IEEE80211_ATHC_FF;
+* if (value & IEEE80211_ABOLT_XR)
+* caps |= IEEE80211_ATHC_XR;
+* if (value & IEEE80211_ABOLT_AR)
+* caps |= IEEE80211_ATHC_AR;
+* if (value & IEEE80211_ABOLT_BURST)
+* caps |= IEEE80211_ATHC_BURST;
+* if (value & IEEE80211_ABOLT_WME_ELE)
+* caps |= IEEE80211_ATHC_WME;
+* // verify requested capabilities are supported
+* if ((caps & ic->ic_ath_cap) != caps)
+* return -EINVAL;
+* if (vap->iv_ath_cap != caps) {
+* if ((vap->iv_ath_cap ^ caps) & IEEE80211_ATHC_TURBOP) {
+* if (ieee80211_set_turbo(dev,
+* caps & IEEE80211_ATHC_TURBOP))
+* return -EINVAL;
+* ieee80211_scan_flush(ic);
+* }
+* vap->iv_ath_cap = caps;
+* ic->ic_athcapsetup(vap->iv_ic, vap->iv_ath_cap);
+* retv = ENETRESET;
+* }
+* break;
+* case IEEE80211_PARAM_DTIM_PERIOD:
+* if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
+* vap->iv_opmode != IEEE80211_M_IBSS)
+* return -EINVAL;
+* if (IEEE80211_DTIM_MIN <= value &&
+* value <= IEEE80211_DTIM_MAX) {
+* vap->iv_dtim_period = value;
+* retv = ENETRESET; // requires restart
+* } else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_BEACON_INTERVAL:
+* if (vap->iv_opmode != IEEE80211_M_HOSTAP &&
+* vap->iv_opmode != IEEE80211_M_IBSS)
+* return -EINVAL;
+* if (IEEE80211_BINTVAL_MIN <= value &&
+* value <= IEEE80211_BINTVAL_MAX) {
+* ic->ic_lintval = value; // XXX multi-bss
+* retv = ENETRESET; // requires restart
+* } else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_DOTH:
+* if (value) {
+* ic->ic_flags |= IEEE80211_F_DOTH;
+* }
+* else
+* ic->ic_flags &= ~IEEE80211_F_DOTH;
+* retv = ENETRESET; // XXX: need something this drastic?
+* break;
+* case IEEE80211_PARAM_PWRTARGET:
+* ic->ic_curchanmaxpwr = value;
+* break;
+* case IEEE80211_PARAM_GENREASSOC:
+* IEEE80211_SEND_MGMT(vap->iv_bss,
+* IEEE80211_FC0_SUBTYPE_REASSOC_REQ, 0);
+* break;
+* case IEEE80211_PARAM_COMPRESSION:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_COMP, value);
+* break;
+* case IEEE80211_PARAM_WMM_AGGRMODE:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_WME, value);
+* break;
+* case IEEE80211_PARAM_FF:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_FF, value);
+* break;
+* case IEEE80211_PARAM_TURBO:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_TURBOP, value);
+* if (retv == ENETRESET) {
+* if(ieee80211_set_turbo(dev,value))
+* return -EINVAL;
+* ieee80211_scan_flush(ic);
+* }
+* break;
+* case IEEE80211_PARAM_XR:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_XR, value);
+* break;
+* case IEEE80211_PARAM_BURST:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_BURST, value);
+* break;
+* case IEEE80211_PARAM_AR:
+* retv = ieee80211_setathcap(vap, IEEE80211_ATHC_AR, value);
+* break;
+* case IEEE80211_PARAM_PUREG:
+* if (value)
+* vap->iv_flags |= IEEE80211_F_PUREG;
+* else
+* vap->iv_flags &= ~IEEE80211_F_PUREG;
+* // NB: reset only if we're operating on an 11g channel
+* if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
+* IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan))
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_WDS:
+* if (value)
+* vap->iv_flags_ext |= IEEE80211_FEXT_WDS;
+* else
+* vap->iv_flags_ext &= ~IEEE80211_FEXT_WDS;
+* break;
+* case IEEE80211_PARAM_BGSCAN:
+* if (value) {
+* if ((vap->iv_caps & IEEE80211_C_BGSCAN) == 0)
+* return -EINVAL;
+* vap->iv_flags |= IEEE80211_F_BGSCAN;
+* } else {
+* // XXX racey?
+* vap->iv_flags &= ~IEEE80211_F_BGSCAN;
+* ieee80211_cancel_scan(vap); // anything current
+* }
+* break;
+* case IEEE80211_PARAM_BGSCAN_IDLE:
+* if (value >= IEEE80211_BGSCAN_IDLE_MIN)
+* vap->iv_bgscanidle = value*HZ/1000;
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_BGSCAN_INTERVAL:
+* if (value >= IEEE80211_BGSCAN_INTVAL_MIN)
+* vap->iv_bgscanintvl = value*HZ;
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_MCAST_RATE:
+* // units are in KILObits per second
+* if (value >= 256 && value <= 54000)
+* vap->iv_mcast_rate = value;
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_COVERAGE_CLASS:
+* if (value >= 0 && value <= IEEE80211_COVERAGE_CLASS_MAX) {
+* ic->ic_coverageclass = value;
+* if (IS_UP_AUTO(vap))
+* ieee80211_new_state(vap, IEEE80211_S_SCAN, 0);
+* retv = 0;
+* }
+* else
+* retv = EINVAL;
+* break;
+* case IEEE80211_PARAM_COUNTRY_IE:
+* if (value)
+* ic->ic_flags_ext |= IEEE80211_FEXT_COUNTRYIE;
+* else
+* ic->ic_flags_ext &= ~IEEE80211_FEXT_COUNTRYIE;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_REGCLASS:
+* if (value)
+* ic->ic_flags_ext |= IEEE80211_FEXT_REGCLASS;
+* else
+* ic->ic_flags_ext &= ~IEEE80211_FEXT_REGCLASS;
+* retv = ENETRESET;
+* break;
+* case IEEE80211_PARAM_SCANVALID:
+* vap->iv_scanvalid = value*HZ;
+* break;
+* case IEEE80211_PARAM_ROAM_RSSI_11A:
+* vap->iv_roam.rssi11a = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RSSI_11B:
+* vap->iv_roam.rssi11bOnly = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RSSI_11G:
+* vap->iv_roam.rssi11b = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RATE_11A:
+* vap->iv_roam.rate11a = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RATE_11B:
+* vap->iv_roam.rate11bOnly = value;
+* break;
+* case IEEE80211_PARAM_ROAM_RATE_11G:
+* vap->iv_roam.rate11b = value;
+* break;
+* case IEEE80211_PARAM_UAPSDINFO:
+* if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+* if (ic->ic_caps & IEEE80211_C_UAPSD) {
+* if (value)
+* IEEE80211_VAP_UAPSD_ENABLE(vap);
+* else
+* IEEE80211_VAP_UAPSD_DISABLE(vap);
+* retv = ENETRESET;
+* }
+* }
+* else if (vap->iv_opmode == IEEE80211_M_STA) {
+* vap->iv_uapsdinfo = value;
+* IEEE80211_VAP_UAPSD_ENABLE(vap);
+* retv = ENETRESET;
+* }
+* break;
+* case IEEE80211_PARAM_SLEEP:
+* // XXX: Forced sleep for testing. Does not actually place the
+* // HW in sleep mode yet. this only makes sense for STAs.
+*
+* if (value) {
+* // goto sleep
+* IEEE80211_VAP_GOTOSLEEP(vap);
+* }
+* else {
+* // wakeup
+* IEEE80211_VAP_WAKEUP(vap);
+* }
+* ieee80211_send_nulldata(ieee80211_ref_node(vap->iv_bss));
+* break;
+* case IEEE80211_PARAM_QOSNULL:
+* // Force a QoS Null for testing.
+* ieee80211_send_qosnulldata(vap->iv_bss, value);
+* break;
+* case IEEE80211_PARAM_PSPOLL:
+* // Force a PS-POLL for testing.
+* ieee80211_send_pspoll(vap->iv_bss);
+* break;
+* case IEEE80211_PARAM_EOSPDROP:
+* if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
+* if (value) IEEE80211_VAP_EOSPDROP_ENABLE(vap);
+* else IEEE80211_VAP_EOSPDROP_DISABLE(vap);
+* }
+* break;
+* case IEEE80211_PARAM_MARKDFS:
+* if (value)
+* ic->ic_flags_ext |= IEEE80211_FEXT_MARKDFS;
+* else
+* ic->ic_flags_ext &= ~IEEE80211_FEXT_MARKDFS;
+* break;
+* case IEEE80211_PARAM_CHANBW:
+* switch (value) {
+* case 0:
+* ic->ic_chanbwflag = 0;
+* break;
+* case 1:
+* ic->ic_chanbwflag = IEEE80211_CHAN_HALF;
+* break;
+* case 2:
+* ic->ic_chanbwflag = IEEE80211_CHAN_QUARTER;
+* break;
+* default:
+* retv = EINVAL;
+* break;
+* }
+* break;
+* case IEEE80211_PARAM_SHORTPREAMBLE:
+* if (value) {
+* ic->ic_caps |= IEEE80211_C_SHPREAMBLE;
+* } else {
+* ic->ic_caps &= ~IEEE80211_C_SHPREAMBLE;
+* }
+* retv = ENETRESET;
+* break;
+* default:
+* retv = EOPNOTSUPP;
+* break;
+* }
+* // XXX should any of these cause a rescan?
+* if (retv == ENETRESET)
+* retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
+* return -retv;
+*}
+*/
int usbdrvwext_setmode(struct net_device *dev, struct iw_request_info *info,
- void *w, char *extra)
+ void *w, char *extra)
{
return 0;
}
@@ -1947,158 +1887,138 @@ int usbdrvwext_setmode(struct net_device *dev, struct iw_request_info *info,
int usbdrvwext_getmode(struct net_device *dev, struct iw_request_info *info,
void *w, char *extra)
{
- //struct usbdrv_private *macp = dev->ml_priv;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
struct iw_point *wri = (struct iw_point *)extra;
char mode[8];
- strcpy(mode,"11g");
- return (copy_to_user(wri->pointer, mode, 6) ? -EFAULT : 0);
+ strcpy(mode, "11g");
+ return copy_to_user(wri->pointer, mode, 6) ? -EFAULT : 0;
}
int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
{
- //void* regp = macp->regp;
+ /* void* regp = macp->regp; */
u16_t cmd;
- //u32_t temp;
- u32_t* p;
+ /* u32_t temp; */
+ u32_t *p;
u32_t i;
cmd = zdreq->cmd;
- switch(cmd)
- {
+ switch (cmd) {
case ZM_IOCTL_REG_READ:
zfiDbgReadReg(dev, zdreq->addr);
break;
-
case ZM_IOCTL_REG_WRITE:
zfiDbgWriteReg(dev, zdreq->addr, zdreq->value);
break;
-
case ZM_IOCTL_MEM_READ:
p = (u32_t *) bus_to_virt(zdreq->addr);
- printk(KERN_DEBUG "usbdrv: read memory addr: 0x%08x value: 0x%08x\n", zdreq->addr, *p);
+ printk(KERN_WARNING
+ "usbdrv: read memory addr: 0x%08x value:"
+ " 0x%08x\n", zdreq->addr, *p);
break;
-
case ZM_IOCTL_MEM_WRITE:
p = (u32_t *) bus_to_virt(zdreq->addr);
*p = zdreq->value;
- printk(KERN_DEBUG "usbdrv: write value: 0x%08x to memory addr: 0x%08x\n", zdreq->value, zdreq->addr);
+ printk(KERN_WARNING
+ "usbdrv : write value : 0x%08x to memory addr :"
+ " 0x%08x\n", zdreq->value, zdreq->addr);
break;
-
- case ZM_IOCTL_TALLY :
+ case ZM_IOCTL_TALLY:
zfiWlanShowTally(dev);
if (zdreq->addr)
zfiWlanResetTally(dev);
break;
+ case ZM_IOCTL_TEST:
+ printk(KERN_WARNING
+ "ZM_IOCTL_TEST:len=%d\n", zdreq->addr);
+ /* zfiWlanReadReg(dev, 0x10f400); */
+ /* zfiWlanReadReg(dev, 0x10f404); */
+ printk(KERN_WARNING "IOCTL TEST\n");
+ #if 1
+ /* print packet */
+ for (i = 0; i < zdreq->addr; i++) {
+ if ((i&0x7) == 0)
+ printk(KERN_WARNING "\n");
+ printk(KERN_WARNING "%02X ",
+ (unsigned char)zdreq->data[i]);
+ }
+ printk(KERN_WARNING "\n");
+ #endif
+
+ /* For Test?? 1 to 0 by CWYang(-) */
+ #if 0
+ struct sk_buff *s;
+
+ /* Allocate a skb */
+ s = alloc_skb(2000, GFP_ATOMIC);
- case ZM_IOCTL_TEST :
- printk(KERN_DEBUG "ZM_IOCTL_TEST:len=%d\n", zdreq->addr);
- //zfiWlanReadReg(dev, 0x10f400);
- //zfiWlanReadReg(dev, 0x10f404);
- printk("IOCTL TEST\n");
- #if 1
- //print packet
- for (i=0; i<zdreq->addr; i++)
- {
- if ((i&0x7) == 0)
- {
- printk("\n");
- }
- printk("%02X ", (unsigned char)zdreq->data[i]);
- }
- printk("\n");
- #endif
-
-
- #if 0 //For Test?? 1 to 0 by CWYang(-)
- {
- struct sk_buff* s;
-
- /* Allocate a skb */
- s = alloc_skb(2000, GFP_ATOMIC);
-
- /* Copy data to skb */
- for (i=0; i<zdreq->addr; i++)
- {
- s->data[i] = zdreq->data[i];
- }
- s->len = zdreq->addr;
-
- /* Call zfIdlRecv() */
- zfiRecv80211(dev, s, NULL);
- }
- #endif
-
- break;
-
-
-/****************************** ZDCONFIG ******************************/
- case ZM_IOCTL_FRAG :
- zfiWlanSetFragThreshold(dev, zdreq->addr);
- break;
-
- case ZM_IOCTL_RTS :
- zfiWlanSetRtsThreshold(dev, zdreq->addr);
- break;
-
- case ZM_IOCTL_SCAN :
- zfiWlanScan(dev);
- break;
-
- case ZM_IOCTL_KEY :
- {
- u8_t key[29];
- struct zsKeyInfo keyInfo;
- u32_t i;
-
- for (i=0; i<29; i++)
- {
- key[i] = 0;
- }
-
- for (i=0; i<zdreq->addr; i++)
- {
- key[i] = zdreq->data[i];
- }
-
- printk("key len=%d, key=%02x%02x%02x%02x%02x...\n",
- zdreq->addr, key[0], key[1], key[2], key[3], key[4]);
-
- keyInfo.keyLength = zdreq->addr;
- keyInfo.keyIndex = 0;
- keyInfo.flag = 0;
- keyInfo.key = key;
- zfiWlanSetKey(dev, keyInfo);
- }
- break;
-
- case ZM_IOCTL_RATE :
- zfiWlanSetTxRate(dev, zdreq->addr);
- break;
-
- case ZM_IOCTL_ENCRYPTION_MODE :
- zfiWlanSetEncryMode(dev, zdreq->addr);
-
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- break;
- //CWYang(+)
- case ZM_IOCTL_SIGNAL_STRENGTH :
- {
- u8_t buffer[2];
- zfiWlanQuerySignalInfo(dev, &buffer[0]);
- printk("Current Signal Strength : %02d\n", buffer[0]);
- }
- break;
- //CWYang(+)
- case ZM_IOCTL_SIGNAL_QUALITY :
- {
- u8_t buffer[2];
- zfiWlanQuerySignalInfo(dev, &buffer[0]);
- printk("Current Signal Quality : %02d\n", buffer[1]);
- }
- break;
+ /* Copy data to skb */
+ for (i = 0; i < zdreq->addr; i++)
+ s->data[i] = zdreq->data[i];
+ s->len = zdreq->addr;
+ /* Call zfIdlRecv() */
+ zfiRecv80211(dev, s, NULL);
+ #endif
+ break;
+ /************************* ZDCONFIG ***************************/
+ case ZM_IOCTL_FRAG:
+ zfiWlanSetFragThreshold(dev, zdreq->addr);
+ break;
+ case ZM_IOCTL_RTS:
+ zfiWlanSetRtsThreshold(dev, zdreq->addr);
+ break;
+ case ZM_IOCTL_SCAN:
+ zfiWlanScan(dev);
+ break;
+ case ZM_IOCTL_KEY: {
+ u8_t key[29];
+ struct zsKeyInfo keyInfo;
+ u32_t i;
+
+ for (i = 0; i < 29; i++)
+ key[i] = 0;
+
+ for (i = 0; i < zdreq->addr; i++)
+ key[i] = zdreq->data[i];
+
+ printk(KERN_WARNING
+ "key len=%d, key=%02x%02x%02x%02x%02x...\n",
+ zdreq->addr, key[0], key[1], key[2], key[3], key[4]);
+
+ keyInfo.keyLength = zdreq->addr;
+ keyInfo.keyIndex = 0;
+ keyInfo.flag = 0;
+ keyInfo.key = key;
+ zfiWlanSetKey(dev, keyInfo);
+ }
+ break;
+ case ZM_IOCTL_RATE:
+ zfiWlanSetTxRate(dev, zdreq->addr);
+ break;
+ case ZM_IOCTL_ENCRYPTION_MODE:
+ zfiWlanSetEncryMode(dev, zdreq->addr);
+
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ break;
+ /* CWYang(+) */
+ case ZM_IOCTL_SIGNAL_STRENGTH: {
+ u8_t buffer[2];
+ zfiWlanQuerySignalInfo(dev, &buffer[0]);
+ printk(KERN_WARNING
+ "Current Signal Strength : %02d\n", buffer[0]);
+ }
+ break;
+ /* CWYang(+) */
+ case ZM_IOCTL_SIGNAL_QUALITY: {
+ u8_t buffer[2];
+ zfiWlanQuerySignalInfo(dev, &buffer[0]);
+ printk(KERN_WARNING
+ "Current Signal Quality : %02d\n", buffer[1]);
+ }
+ break;
case ZM_IOCTL_SET_PIBSS_MODE:
if (zdreq->addr == 1)
zfiWlanSetWlanMode(dev, ZM_MODE_PSEUDO);
@@ -2107,11 +2027,9 @@ int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
zfiWlanDisable(dev, 0);
zfiWlanEnable(dev);
-
break;
-/****************************** ZDCONFIG ******************************/
-
- default :
+ /********************* ZDCONFIG ***********************/
+ default:
printk(KERN_ERR "usbdrv: error command = %x\n", cmd);
break;
}
@@ -2121,793 +2039,736 @@ int zfLnxPrivateIoctl(struct net_device *dev, struct zdap_ioctl* zdreq)
int usbdrv_wpa_ioctl(struct net_device *dev, struct athr_wlan_param *zdparm)
{
- int ret = 0;
- u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- u8_t mac_addr[80];
- struct zsKeyInfo keyInfo;
- struct usbdrv_private *macp = dev->ml_priv;
- u16_t vapId = 0;
-
- //zmw_get_wlan_dev(dev);
-
- switch(zdparm->cmd)
- {
- case ZD_CMD_SET_ENCRYPT_KEY:
-
- /* Set up key information */
- keyInfo.keyLength = zdparm->u.crypt.key_len;
- keyInfo.keyIndex = zdparm->u.crypt.idx;
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR;
- else
- keyInfo.flag = 0;
- keyInfo.key = zdparm->u.crypt.key;
- keyInfo.initIv = zdparm->u.crypt.seq;
- keyInfo.macAddr = (u16_t *)zdparm->sta_addr;
-
- /* Identify the MAC address information */
- if (memcmp(zdparm->sta_addr, bc_addr, sizeof(bc_addr)) == 0)
- {
- keyInfo.flag |= ZM_KEY_FLAG_GK;
- }
- else
- {
- keyInfo.flag |= ZM_KEY_FLAG_PK;
- }
-
- if (!strcmp(zdparm->u.crypt.alg, "NONE"))
- {
- //u8_t zero_mac[]={0,0,0,0,0,0};
-
- /* Set key length to zero */
- keyInfo.keyLength = 0;
-
- if (zdparm->sta_addr[0] & 1)//del group key
- {
- //if (macp->cardSetting.WPAIeLen==0)
- //{//802.1x dynamic WEP
- // mDynKeyMode = 0;
- // mKeyFormat[0] = 0;
- // mPrivacyInvoked[0]=FALSE;
- // mCap[0] &= ~CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0]=0;
- //}
- //mWpaBcKeyLen = mGkInstalled = 0;
- }
- else
- {
- //if (memcmp(zero_mac,zdparm->sta_addr, 6)==0)
- //{
- // mDynKeyMode=0;
- // mKeyFormat[0]=0;
- // pSetting->DynKeyMode=0;
- // pSetting->EncryMode[0]=0;
- // mDynKeyMode=0;
- //}
- }
-
- printk(KERN_ERR "Set Encryption Type NONE\n");
- return ret;
- }
- else if (!strcmp(zdparm->u.crypt.alg, "TKIP"))
- {
- zfiWlanSetEncryMode(dev, ZM_TKIP);
- //Linux Supplicant will inverse Tx/Rx key
- //So we inverse it back //CWYang(+)
- //zfMemoryCopy(&temp[0], &keyInfo.key[16], 8);
- //zfMemoryCopy(&keyInfo.key[16], keyInfo.key[24], 8);
- //zfMemoryCopy(&keyInfo.key[24], &temp[0], 8);
- //u8_t temp;
- //int k;
- //for (k = 0; k < 8; k++)
- //{
- // temp = keyInfo.key[16 + k];
- // keyInfo.key[16 + k] = keyInfo.key[24 + k];
- // keyInfo.key[24 + k] = temp;
- //}
- //CamEncryType = ZM_TKIP;
- ////if (idx == 0)
- //{// Pairwise key
- // mKeyFormat[0] = CamEncryType;
- // mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_TKIP;
- //}
- }
- else if (!strcmp(zdparm->u.crypt.alg, "CCMP"))
- {
- zfiWlanSetEncryMode(dev, ZM_AES);
- //CamEncryType = ZM_AES;
- ////if (idx == 0)
- //{// Pairwise key
- // mKeyFormat[0] = CamEncryType;
- // mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_AES;
- //}
- }
- else if (!strcmp(zdparm->u.crypt.alg, "WEP"))
- {
- if (keyInfo.keyLength == 5)
- { // WEP 64
- zfiWlanSetEncryMode(dev, ZM_WEP64);
- // CamEncryType = ZM_WEP64;
- // tmpDynKeyMode=DYN_KEY_WEP64;
- }
- else if (keyInfo.keyLength == 13)
- {//keylen=13, WEP 128
- zfiWlanSetEncryMode(dev, ZM_WEP128);
- // CamEncryType = ZM_WEP128;
- // tmpDynKeyMode=DYN_KEY_WEP128;
- }
- else
- {
- zfiWlanSetEncryMode(dev, ZM_WEP256);
- }
-
- // For Dynamic WEP key (Non-WPA Radius), the key ID range: 0-3
- // In WPA/RSN mode, the key ID range: 1-3, usually, a broadcast key.
- // For WEP key setting: we set mDynKeyMode and mKeyFormat in following case:
- // 1. For 802.1x dynamically generated WEP key method.
- // 2. For WPA/RSN mode, but key id == 0. (But this is an impossible case)
- // So, only check case 1.
- //if (macp->cardSetting.WPAIeLen==0)
- //{
- // mKeyFormat[0] = CamEncryType;
- // mDynKeyMode = pSetting->DynKeyMode = tmpDynKeyMode;
- // mPrivacyInvoked[0]=TRUE;
- // mCap[0] |= CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0]=1;
- //}
- }
-
- /* DUMP key context */
-//#ifdef WPA_DEBUG
- if (keyInfo.keyLength > 0)
- {
- int ii;
- printk("Otus: Key Context:\n");
- for(ii = 0; ii < keyInfo.keyLength;)
- {
- printk("0x%02x ", keyInfo.key[ii]);
- if((++ii % 16) == 0)
- printk("\n");
- }
- printk("\n");
- }
-//#endif
-
- /* Set encrypt mode */
- //zfiWlanSetEncryMode(dev, CamEncryType);
- vapId = zfLnxGetVapId(dev);
- if (vapId == 0xffff)
- keyInfo.vapId = 0;
- else
- keyInfo.vapId = vapId + 1;
- keyInfo.vapAddr[0] = keyInfo.macAddr[0];
- keyInfo.vapAddr[1] = keyInfo.macAddr[1];
- keyInfo.vapAddr[2] = keyInfo.macAddr[2];
-
- zfiWlanSetKey(dev, keyInfo);
-
- //zfiWlanDisable(dev);
- //zfiWlanEnable(dev);
- break;
-
- case ZD_CMD_SET_MLME:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_MLME\n");
-
- /* Translate STA's address */
- sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x", zdparm->sta_addr[0], zdparm->sta_addr[1],
- zdparm->sta_addr[2], zdparm->sta_addr[3], zdparm->sta_addr[4], zdparm->sta_addr[5]);
-
- switch(zdparm->u.mlme.cmd)
- {
- case MLME_STA_DEAUTH:
- printk(" -------Call zfiWlanDeauth, reason:%d\n",zdparm->u.mlme.reason_code);
- if(zfiWlanDeauth(dev, (u16_t*) zdparm->sta_addr, zdparm->u.mlme.reason_code) != 0)
- printk(KERN_ERR "Can't deauthencate STA: %s\n", mac_addr);
- else
- printk(KERN_ERR "Deauthenticate STA: %s with reason code: %d\n", mac_addr, zdparm->u.mlme.reason_code);
- break;
-
- case MLME_STA_DISASSOC:
- printk(" -------Call zfiWlanDeauth, reason:%d\n",zdparm->u.mlme.reason_code);
- if(zfiWlanDeauth(dev, (u16_t*) zdparm->sta_addr, zdparm->u.mlme.reason_code) != 0)
- printk(KERN_ERR "Can't disassociate STA: %s\n", mac_addr);
- else
- printk(KERN_ERR "Disassociate STA: %s with reason code: %d\n", mac_addr, zdparm->u.mlme.reason_code);
- break;
-
- default:
- printk(KERN_ERR "MLME command: 0x%04x not support\n", zdparm->u.mlme.cmd);
- break;
- }
-
- break;
-
- case ZD_CMD_SCAN_REQ:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
- break;
-
- case ZD_CMD_SET_GENERIC_ELEMENT:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_GENERIC_ELEMENT\n");
-
- /* Copy the WPA IE */
- //zm_msg1_mm(ZM_LV_0, "CWY - wpaie Length : ", zdparm->u.generic_elem.len);
- printk(KERN_ERR "wpaie Length : %d\n", zdparm->u.generic_elem.len);
- if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) // AP Mode
- {
- zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
- }
- else
- {
- macp->supLen = zdparm->u.generic_elem.len;
- memcpy(macp->supIe, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
- }
- zfiWlanSetWpaSupport(dev, 1);
- //zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data, zdparm->u.generic_elem.len);
- {
- int ii;
- u8_t len = zdparm->u.generic_elem.len;
- u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
-
- printk(KERN_ERR "wd->ap.wpaLen: %d\n", len);
-
- /* DUMP WPA IE */
- for(ii = 0; ii < len;)
- {
- printk(KERN_ERR "0x%02x ", wpaie[ii]);
-
- if((++ii % 16) == 0)
- printk(KERN_ERR "\n");
- }
- printk(KERN_ERR "\n");
- }
-
-// #ifdef ZM_HOSTAPD_SUPPORT
- //if (wd->wlanMode == ZM_MODE_AP)
- //{// Update Beacon FIFO in the next TBTT.
- // memcpy(&mWPAIe, pSetting->WPAIe, pSetting->WPAIeLen);
- // printk(KERN_ERR "Copy WPA IE into mWPAIe\n");
- //}
-// #endif
- break;
-
-// #ifdef ZM_HOSTAPD_SUPPORT
- case ZD_CMD_GET_TSC:
- printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_GET_TSC\n");
- break;
-// #endif
-
- default:
- printk(KERN_ERR "usbdrv_wpa_ioctl default: 0x%04x\n", zdparm->cmd);
- ret = -EINVAL;
- break;
- }
-
- return ret;
+ int ret = 0;
+ u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ u8_t mac_addr[80];
+ struct zsKeyInfo keyInfo;
+ struct usbdrv_private *macp = dev->ml_priv;
+ u16_t vapId = 0;
+
+ /* zmw_get_wlan_dev(dev); */
+
+ switch (zdparm->cmd) {
+ case ZD_CMD_SET_ENCRYPT_KEY:
+ /* Set up key information */
+ keyInfo.keyLength = zdparm->u.crypt.key_len;
+ keyInfo.keyIndex = zdparm->u.crypt.idx;
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR;
+ } else
+ keyInfo.flag = 0;
+ keyInfo.key = zdparm->u.crypt.key;
+ keyInfo.initIv = zdparm->u.crypt.seq;
+ keyInfo.macAddr = (u16_t *)zdparm->sta_addr;
+
+ /* Identify the MAC address information */
+ if (memcmp(zdparm->sta_addr, bc_addr, sizeof(bc_addr)) == 0)
+ keyInfo.flag |= ZM_KEY_FLAG_GK;
+ else
+ keyInfo.flag |= ZM_KEY_FLAG_PK;
+
+ if (!strcmp(zdparm->u.crypt.alg, "NONE")) {
+ /* u8_t zero_mac[]={0,0,0,0,0,0}; */
+
+ /* Set key length to zero */
+ keyInfo.keyLength = 0;
+
+ /* del group key */
+ if (zdparm->sta_addr[0] & 1) {
+ /* if (macp->cardSetting.WPAIeLen==0)
+ * { 802.1x dynamic WEP
+ * mDynKeyMode = 0;
+ * mKeyFormat[0] = 0;
+ * mPrivacyInvoked[0]=FALSE;
+ * mCap[0] &= ~CAP_PRIVACY;
+ * macp->cardSetting.EncryOnOff[0]=0;
+ * }
+ * mWpaBcKeyLen = mGkInstalled = 0;
+ */
+ } else {
+ /* if (memcmp(zero_mac,zdparm->sta_addr, 6)==0)
+ * {
+ * mDynKeyMode=0;
+ * mKeyFormat[0]=0;
+ * pSetting->DynKeyMode=0;
+ * pSetting->EncryMode[0]=0;
+ * mDynKeyMode=0;
+ * }
+ */
+ }
+
+ printk(KERN_ERR "Set Encryption Type NONE\n");
+ return ret;
+ } else if (!strcmp(zdparm->u.crypt.alg, "TKIP")) {
+ zfiWlanSetEncryMode(dev, ZM_TKIP);
+ /* //Linux Supplicant will inverse Tx/Rx key
+ * //So we inverse it back, CWYang(+)
+ * zfMemoryCopy(&temp[0], &keyInfo.key[16], 8);
+ * zfMemoryCopy(&keyInfo.key[16], keyInfo.key[24], 8);
+ * zfMemoryCopy(&keyInfo.key[24], &temp[0], 8);
+ * u8_t temp;
+ * int k;
+ * for (k = 0; k < 8; k++)
+ * {
+ * temp = keyInfo.key[16 + k];
+ * keyInfo.key[16 + k] = keyInfo.key[24 + k];
+ * keyInfo.key[24 + k] = temp;
+ * }
+ * CamEncryType = ZM_TKIP;
+ * if (idx == 0)
+ * { // Pairwise key
+ * mKeyFormat[0] = CamEncryType;
+ * mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_TKIP;
+ * }
+ */
+ } else if (!strcmp(zdparm->u.crypt.alg, "CCMP")) {
+ zfiWlanSetEncryMode(dev, ZM_AES);
+ /* CamEncryType = ZM_AES;
+ * if (idx == 0)
+ * { // Pairwise key
+ * mKeyFormat[0] = CamEncryType;
+ * mDynKeyMode = pSetting->DynKeyMode = DYN_KEY_AES;
+ * }
+ */
+ } else if (!strcmp(zdparm->u.crypt.alg, "WEP")) {
+ if (keyInfo.keyLength == 5) {
+ /* WEP 64 */
+ zfiWlanSetEncryMode(dev, ZM_WEP64);
+ /* CamEncryType = ZM_WEP64; */
+ /* tmpDynKeyMode=DYN_KEY_WEP64; */
+ } else if (keyInfo.keyLength == 13) {
+ /* keylen=13, WEP 128 */
+ zfiWlanSetEncryMode(dev, ZM_WEP128);
+ /* CamEncryType = ZM_WEP128; */
+ /* tmpDynKeyMode=DYN_KEY_WEP128; */
+ } else {
+ zfiWlanSetEncryMode(dev, ZM_WEP256);
+ }
+
+ /* For Dynamic WEP key (Non-WPA Radius), the key ID range: 0-3
+ * In WPA/RSN mode, the key ID range: 1-3, usually, a broadcast key.
+ * For WEP key setting: we set mDynKeyMode and mKeyFormat in following
+ * case:
+ * 1. For 802.1x dynamically generated WEP key method.
+ * 2. For WPA/RSN mode, but key id == 0.
+ * (But this is an impossible case)
+ * So, only check case 1.
+ * if (macp->cardSetting.WPAIeLen==0)
+ * {
+ * mKeyFormat[0] = CamEncryType;
+ * mDynKeyMode = pSetting->DynKeyMode = tmpDynKeyMode;
+ * mPrivacyInvoked[0]=TRUE;
+ * mCap[0] |= CAP_PRIVACY;
+ * macp->cardSetting.EncryOnOff[0]=1;
+ * }
+ */
+ }
+
+ /* DUMP key context */
+ /* #ifdef WPA_DEBUG */
+ if (keyInfo.keyLength > 0) {
+ int ii;
+ printk(KERN_WARNING
+ "Otus: Key Context:\n");
+ for (ii = 0; ii < keyInfo.keyLength; ) {
+ printk(KERN_WARNING
+ "0x%02x ", keyInfo.key[ii]);
+ if ((++ii % 16) == 0)
+ printk(KERN_WARNING "\n");
+ }
+ printk(KERN_WARNING "\n");
+ }
+ /* #endif */
+
+ /* Set encrypt mode */
+ /* zfiWlanSetEncryMode(dev, CamEncryType); */
+ vapId = zfLnxGetVapId(dev);
+ if (vapId == 0xffff)
+ keyInfo.vapId = 0;
+ else
+ keyInfo.vapId = vapId + 1;
+ keyInfo.vapAddr[0] = keyInfo.macAddr[0];
+ keyInfo.vapAddr[1] = keyInfo.macAddr[1];
+ keyInfo.vapAddr[2] = keyInfo.macAddr[2];
+
+ zfiWlanSetKey(dev, keyInfo);
+
+ /* zfiWlanDisable(dev); */
+ /* zfiWlanEnable(dev); */
+ break;
+ case ZD_CMD_SET_MLME:
+ printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SET_MLME\n");
+
+ /* Translate STA's address */
+ sprintf(mac_addr, "%02x:%02x:%02x:%02x:%02x:%02x",
+ zdparm->sta_addr[0], zdparm->sta_addr[1],
+ zdparm->sta_addr[2], zdparm->sta_addr[3],
+ zdparm->sta_addr[4], zdparm->sta_addr[5]);
+
+ switch (zdparm->u.mlme.cmd) {
+ case MLME_STA_DEAUTH:
+ printk(KERN_WARNING
+ " -------Call zfiWlanDeauth, reason:%d\n",
+ zdparm->u.mlme.reason_code);
+ if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
+ zdparm->u.mlme.reason_code) != 0)
+ printk(KERN_ERR "Can't deauthencate STA: %s\n",
+ mac_addr);
+ else
+ printk(KERN_ERR "Deauthenticate STA: %s"
+ "with reason code: %d\n",
+ mac_addr, zdparm->u.mlme.reason_code);
+ break;
+ case MLME_STA_DISASSOC:
+ printk(KERN_WARNING
+ " -------Call zfiWlanDeauth, reason:%d\n",
+ zdparm->u.mlme.reason_code);
+ if (zfiWlanDeauth(dev, (u16_t *) zdparm->sta_addr,
+ zdparm->u.mlme.reason_code) != 0)
+ printk(KERN_ERR "Can't disassociate STA: %s\n",
+ mac_addr);
+ else
+ printk(KERN_ERR "Disassociate STA: %s"
+ "with reason code: %d\n",
+ mac_addr, zdparm->u.mlme.reason_code);
+ break;
+ default:
+ printk(KERN_ERR "MLME command: 0x%04x not support\n",
+ zdparm->u.mlme.cmd);
+ break;
+ }
+
+ break;
+ case ZD_CMD_SCAN_REQ:
+ printk(KERN_ERR "usbdrv_wpa_ioctl: ZD_CMD_SCAN_REQ\n");
+ break;
+ case ZD_CMD_SET_GENERIC_ELEMENT:
+ printk(KERN_ERR "usbdrv_wpa_ioctl:"
+ " ZD_CMD_SET_GENERIC_ELEMENT\n");
+
+ /* Copy the WPA IE
+ * zm_msg1_mm(ZM_LV_0, "CWY - wpaie Length : ",
+ * zdparm->u.generic_elem.len);
+ */
+ printk(KERN_ERR "wpaie Length : % d\n",
+ zdparm->u.generic_elem.len);
+ if (zfiWlanQueryWlanMode(dev) == ZM_MODE_AP) {
+ /* AP Mode */
+ zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
+ zdparm->u.generic_elem.len);
+ } else {
+ macp->supLen = zdparm->u.generic_elem.len;
+ memcpy(macp->supIe, zdparm->u.generic_elem.data,
+ zdparm->u.generic_elem.len);
+ }
+ zfiWlanSetWpaSupport(dev, 1);
+ /* zfiWlanSetWpaIe(dev, zdparm->u.generic_elem.data,
+ * zdparm->u.generic_elem.len);
+ */
+ int ii;
+ u8_t len = zdparm->u.generic_elem.len;
+ u8_t *wpaie = (u8_t *)zdparm->u.generic_elem.data;
+
+ printk(KERN_ERR "wd->ap.wpaLen : % d\n", len);
+
+ /* DUMP WPA IE */
+ for(ii = 0; ii < len;) {
+ printk(KERN_ERR "0x%02x ", wpaie[ii]);
+
+ if((++ii % 16) == 0)
+ printk(KERN_ERR "\n");
+ }
+ printk(KERN_ERR "\n");
+
+ /* #ifdef ZM_HOSTAPD_SUPPORT
+ * if (wd->wlanMode == ZM_MODE_AP)
+ * {// Update Beacon FIFO in the next TBTT.
+ * memcpy(&mWPAIe, pSetting->WPAIe, pSetting->WPAIeLen);
+ * printk(KERN_ERR "Copy WPA IE into mWPAIe\n");
+ * }
+ * #endif
+ */
+ break;
+
+ /* #ifdef ZM_HOSTAPD_SUPPORT */
+ case ZD_CMD_GET_TSC:
+ printk(KERN_ERR "usbdrv_wpa_ioctl : ZD_CMD_GET_TSC\n");
+ break;
+ /* #endif */
+
+ default:
+ printk(KERN_ERR "usbdrv_wpa_ioctl default : 0x%04x\n",
+ zdparm->cmd);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
}
#ifdef ZM_ENABLE_CENC
int usbdrv_cenc_ioctl(struct net_device *dev, struct zydas_cenc_param *zdparm)
{
- //struct usbdrv_private *macp = dev->ml_priv;
- struct zsKeyInfo keyInfo;
- u16_t apId;
- u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
- int ret = 0;
- int ii;
-
- /* Get the AP Id */
- apId = zfLnxGetVapId(dev);
-
- if (apId == 0xffff)
- {
- apId = 0;
- }
- else
- {
- apId = apId+1;
- }
-
- switch (zdparm->cmd)
- {
- case ZM_CMD_CENC_SETCENC:
- printk(KERN_ERR "ZM_CMD_CENC_SETCENC\n");
- printk(KERN_ERR "length: %d\n", zdparm->len);
- printk(KERN_ERR "policy: %d\n", zdparm->u.info.cenc_policy);
- break;
- case ZM_CMD_CENC_SETKEY:
- //ret = wai_ioctl_setkey(vap, ioctl_msg);
- printk(KERN_ERR "ZM_CMD_CENC_SETKEY\n");
-
- printk(KERN_ERR "MAC address= ");
- for(ii = 0; ii < 6; ii++)
- {
- printk(KERN_ERR "0x%02x ", zdparm->u.crypt.sta_addr[ii]);
- }
- printk(KERN_ERR "\n");
-
- printk(KERN_ERR "Key Index: %d\n", zdparm->u.crypt.keyid);
- printk(KERN_ERR "Encryption key= ");
- for(ii = 0; ii < 16; ii++)
- {
- printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
- }
- printk(KERN_ERR "\n");
-
- printk(KERN_ERR "MIC key= ");
- for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++)
- {
- printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
- }
- printk(KERN_ERR "\n");
-
- /* Set up key information */
- keyInfo.keyLength = ZM_CENC_KEY_SIZE;
- keyInfo.keyIndex = zdparm->u.crypt.keyid;
- keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR | ZM_KEY_FLAG_CENC;
- keyInfo.key = zdparm->u.crypt.key;
- keyInfo.macAddr = (u16_t *)zdparm->u.crypt.sta_addr;
-
- /* Identify the MAC address information */
- if (memcmp(zdparm->u.crypt.sta_addr, bc_addr, sizeof(bc_addr)) == 0)
- {
- keyInfo.flag |= ZM_KEY_FLAG_GK;
- keyInfo.vapId = apId;
- memcpy(keyInfo.vapAddr, dev->dev_addr, ETH_ALEN);
- }
- else
- {
- keyInfo.flag |= ZM_KEY_FLAG_PK;
- }
-
- zfiWlanSetKey(dev, keyInfo);
-
- break;
- case ZM_CMD_CENC_REKEY:
- //ret = wai_ioctl_rekey(vap, ioctl_msg);
- printk(KERN_ERR "ZM_CMD_CENC_REKEY\n");
- break;
- default:
- ret = -EOPNOTSUPP;
- break;
-
- }
-
- //if (retv == ENETRESET)
- // retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0;
-
- return ret;
-}
-#endif //ZM_ENABLE_CENC
-/////////////////////////////////////////
-int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
-// struct usbdrv_private *macp;
-// void *regp;
- struct zdap_ioctl zdreq;
- struct iwreq *wrq = (struct iwreq *)ifr;
- struct athr_wlan_param zdparm;
- struct usbdrv_private *macp = dev->ml_priv;
+ /* struct usbdrv_private *macp = dev->ml_priv; */
+ struct zsKeyInfo keyInfo;
+ u16_t apId;
+ u8_t bc_addr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+ int ret = 0;
+ int ii;
+
+ /* Get the AP Id */
+ apId = zfLnxGetVapId(dev);
+
+ if (apId == 0xffff) {
+ apId = 0;
+ } else {
+ apId = apId + 1;
+ }
- int err = 0;
- int changed = 0;
+ switch (zdparm->cmd) {
+ case ZM_CMD_CENC_SETCENC:
+ printk(KERN_ERR "ZM_CMD_CENC_SETCENC\n");
+ printk(KERN_ERR "length : % d\n", zdparm->len);
+ printk(KERN_ERR "policy : % d\n", zdparm->u.info.cenc_policy);
+ break;
+ case ZM_CMD_CENC_SETKEY:
+ /* ret = wai_ioctl_setkey(vap, ioctl_msg); */
+ printk(KERN_ERR "ZM_CMD_CENC_SETKEY\n");
+
+ printk(KERN_ERR "MAC address = ");
+ for (ii = 0; ii < 6; ii++) {
+ printk(KERN_ERR "0x%02x ",
+ zdparm->u.crypt.sta_addr[ii]);
+ }
+ printk(KERN_ERR "\n");
-// regp = macp->regp;
+ printk(KERN_ERR "Key Index : % d\n", zdparm->u.crypt.keyid);
+ printk(KERN_ERR "Encryption key = ");
+ for (ii = 0; ii < 16; ii++) {
+ printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
+ }
+ printk(KERN_ERR "\n");
- if(!netif_running(dev))
- return -EINVAL;
+ printk(KERN_ERR "MIC key = ");
+ for(ii = 16; ii < ZM_CENC_KEY_SIZE; ii++) {
+ printk(KERN_ERR "0x%02x ", zdparm->u.crypt.key[ii]);
+ }
+ printk(KERN_ERR "\n");
+
+ /* Set up key information */
+ keyInfo.keyLength = ZM_CENC_KEY_SIZE;
+ keyInfo.keyIndex = zdparm->u.crypt.keyid;
+ keyInfo.flag = ZM_KEY_FLAG_AUTHENTICATOR | ZM_KEY_FLAG_CENC;
+ keyInfo.key = zdparm->u.crypt.key;
+ keyInfo.macAddr = (u16_t *)zdparm->u.crypt.sta_addr;
+
+ /* Identify the MAC address information */
+ if (memcmp(zdparm->u.crypt.sta_addr, bc_addr,
+ sizeof(bc_addr)) == 0) {
+ keyInfo.flag |= ZM_KEY_FLAG_GK;
+ keyInfo.vapId = apId;
+ memcpy(keyInfo.vapAddr, dev->dev_addr, ETH_ALEN);
+ } else {
+ keyInfo.flag |= ZM_KEY_FLAG_PK;
+ }
- switch (cmd)
- {
- case SIOCGIWNAME:
- strcpy(wrq->u.name, "IEEE 802.11-DS");
- break;
+ zfiWlanSetKey(dev, keyInfo);
- case SIOCGIWAP:
- err = usbdrvwext_giwap(dev, NULL, &wrq->u.ap_addr, NULL);
- break;
+ break;
+ case ZM_CMD_CENC_REKEY:
+ /* ret = wai_ioctl_rekey(vap, ioctl_msg); */
+ printk(KERN_ERR "ZM_CMD_CENC_REKEY\n");
+ break;
+ default:
+ ret = -EOPNOTSUPP;
+ break;
+ }
+ /* if (retv == ENETRESET) */
+ /* retv = IS_UP_AUTO(vap) ? ieee80211_open(vap->iv_dev) : 0; */
- case SIOCSIWAP:
- err = usbdrvwext_siwap(dev, NULL, &wrq->u.ap_addr, NULL);
- break;
+ return ret;
+}
+#endif /* ZM_ENABLE_CENC */
+int usbdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+ /* struct usbdrv_private *macp; */
+ /* void *regp; */
+ struct zdap_ioctl zdreq;
+ struct iwreq *wrq = (struct iwreq *)ifr;
+ struct athr_wlan_param zdparm;
+ struct usbdrv_private *macp = dev->ml_priv;
- case SIOCGIWMODE:
- err = usbdrvwext_giwmode(dev, NULL, &wrq->u.mode, NULL);
- break;
+ int err = 0;
+ int changed = 0;
+ /* regp = macp->regp; */
- case SIOCSIWESSID:
- printk(KERN_ERR "CWY - usbdrvwext_siwessid\n");
- //err = usbdrv_ioctl_setessid(dev, &wrq->u.essid);
- err = usbdrvwext_siwessid(dev, NULL, &wrq->u.essid, NULL);
+ if (!netif_running(dev))
+ return -EINVAL;
- if (! err)
- changed = 1;
- break;
+ switch (cmd) {
+ case SIOCGIWNAME:
+ strcpy(wrq->u.name, "IEEE 802.11-DS");
+ break;
+ case SIOCGIWAP:
+ err = usbdrvwext_giwap(dev, NULL, &wrq->u.ap_addr, NULL);
+ break;
+ case SIOCSIWAP:
+ err = usbdrvwext_siwap(dev, NULL, &wrq->u.ap_addr, NULL);
+ break;
+ case SIOCGIWMODE:
+ err = usbdrvwext_giwmode(dev, NULL, &wrq->u.mode, NULL);
+ break;
+ case SIOCSIWESSID:
+ printk(KERN_ERR "CWY - usbdrvwext_siwessid\n");
+ /* err = usbdrv_ioctl_setessid(dev, &wrq->u.essid); */
+ err = usbdrvwext_siwessid(dev, NULL, &wrq->u.essid, NULL);
+ if (!err)
+ changed = 1;
+ break;
+ case SIOCGIWESSID:
+ err = usbdrvwext_giwessid(dev, NULL, &wrq->u.essid, NULL);
+ break;
+ case SIOCSIWRTS:
+ err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
+ if (! err)
+ changed = 1;
+ break;
+ /* set_auth */
+ case SIOCIWFIRSTPRIV + 0x2: {
+ /* printk("CWY - SIOCIWFIRSTPRIV + 0x2(set_auth)\n"); */
+ if (!capable(CAP_NET_ADMIN)) {
+ err = -EPERM;
+ break;
+ }
+ int val = *((int *) wrq->u.name);
+ if ((val < 0) || (val > 2)) {
+ err = -EINVAL;
+ break;
+ } else {
+ zfiWlanSetAuthenticationMode(dev, val);
- case SIOCGIWESSID:
- err = usbdrvwext_giwessid(dev, NULL, &wrq->u.essid, NULL);
- break;
+ if (macp->DeviceOpened == 1) {
+ zfiWlanDisable(dev, 0);
+ zfiWlanEnable(dev);
+ }
+ err = 0;
+ changed = 1;
+ }
+ }
+ break;
+ /* get_auth */
+ case SIOCIWFIRSTPRIV + 0x3: {
+ int AuthMode = ZM_AUTH_MODE_OPEN;
- case SIOCSIWRTS:
+ /* printk("CWY - SIOCIWFIRSTPRIV + 0x3(get_auth)\n"); */
- err = usbdrv_ioctl_setrts(dev, &wrq->u.rts);
- if (! err)
- changed = 1;
- break;
+ if (wrq->u.data.pointer) {
+ wrq->u.data.flags = 1;
+ AuthMode = zfiWlanQueryAuthenticationMode(dev, 0);
+ if (AuthMode == ZM_AUTH_MODE_OPEN) {
+ wrq->u.data.length = 12;
- case SIOCIWFIRSTPRIV + 0x2: /* set_auth */
- {
- //printk("CWY - SIOCIWFIRSTPRIV + 0x2 (set_auth)\n");
- if (! capable(CAP_NET_ADMIN))
- {
- err = -EPERM;
- break;
- }
- {
- int val = *( (int *) wrq->u.name );
- if ((val < 0) || (val > 2))
- {
- err = -EINVAL;
- break;
+ if (copy_to_user(wrq->u.data.pointer,
+ "open system", 12)) {
+ return -EFAULT;
}
- else
- {
- zfiWlanSetAuthenticationMode(dev, val);
+ } else if (AuthMode == ZM_AUTH_MODE_SHARED_KEY) {
+ wrq->u.data.length = 11;
- if (macp->DeviceOpened == 1)
- {
- zfiWlanDisable(dev, 0);
- zfiWlanEnable(dev);
- }
+ if (copy_to_user(wrq->u.data.pointer,
+ "shared key", 11)) {
+ return -EFAULT;
+ }
+ } else if (AuthMode == ZM_AUTH_MODE_AUTO) {
+ wrq->u.data.length = 10;
- err = 0;
- changed = 1;
+ if (copy_to_user(wrq->u.data.pointer,
+ "auto mode", 10)) {
+ return -EFAULT;
}
+ } else {
+ return -EFAULT;
}
}
- break;
-
- case SIOCIWFIRSTPRIV + 0x3: /* get_auth */
- {
- int AuthMode = ZM_AUTH_MODE_OPEN;
-
- //printk("CWY - SIOCIWFIRSTPRIV + 0x3 (get_auth)\n");
+ }
+ break;
+ /* debug command */
+ case ZDAPIOCTL:
+ if (copy_from_user(&zdreq, ifr->ifr_data, sizeof(zdreq))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
- if (wrq->u.data.pointer)
- {
- wrq->u.data.flags = 1;
+ /* printk(KERN_WARNING
+ * "usbdrv : cmd = % 2x, reg = 0x%04lx,
+ *value = 0x%08lx\n",
+ * zdreq.cmd, zdreq.addr, zdreq.value);
+ */
+ zfLnxPrivateIoctl(dev, &zdreq);
- AuthMode = zfiWlanQueryAuthenticationMode(dev, 0);
- if (AuthMode == ZM_AUTH_MODE_OPEN)
- {
- wrq->u.data.length = 12;
+ err = 0;
+ break;
+ case ZD_IOCTL_WPA:
+ if (copy_from_user(&zdparm, ifr->ifr_data,
+ sizeof(struct athr_wlan_param))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
- if (copy_to_user(wrq->u.data.pointer, "open system", 12))
+ usbdrv_wpa_ioctl(dev, &zdparm);
+ err = 0;
+ break;
+ case ZD_IOCTL_PARAM: {
+ int *p;
+ int op;
+ int arg;
+
+ /* Point to the name field and retrieve the
+ * op and arg elements.
+ */
+ p = (int *)wrq->u.name;
+ op = *p++;
+ arg = *p;
+
+ if (op == ZD_PARAM_ROAMING) {
+ printk(KERN_ERR
+ "*************ZD_PARAM_ROAMING : % d\n", arg);
+ /* macp->cardSetting.ap_scan=(U8)arg; */
+ }
+ if (op == ZD_PARAM_PRIVACY) {
+ printk(KERN_ERR "ZD_IOCTL_PRIVACY : ");
+
+ /* Turn on the privacy invoke flag */
+ if (arg) {
+ /* mCap[0] |= CAP_PRIVACY; */
+ /* macp->cardSetting.EncryOnOff[0] = 1; */
+ printk(KERN_ERR "enable\n");
+
+ } else {
+ /* mCap[0] &= ~CAP_PRIVACY; */
+ /* macp->cardSetting.EncryOnOff[0] = 0; */
+ printk(KERN_ERR "disable\n");
+ }
+ /* changed=1; */
+ }
+ if (op == ZD_PARAM_WPA) {
+
+ printk(KERN_ERR "ZD_PARAM_WPA : ");
+
+ if (arg) {
+ printk(KERN_ERR "enable\n");
+
+ if (zfiWlanQueryWlanMode(dev) != ZM_MODE_AP) {
+ printk(KERN_ERR "Station Mode\n");
+ /* zfiWlanQueryWpaIe(dev, (u8_t *)
+ &wpaIe, &wpalen); */
+ /* printk("wpaIe : % 2x, % 2x, % 2x\n",
+ wpaIe[21], wpaIe[22], wpaIe[23]); */
+ /* printk("rsnIe : % 2x, % 2x, % 2x\n",
+ wpaIe[17], wpaIe[18], wpaIe[19]); */
+ if ((macp->supIe[21] == 0x50) &&
+ (macp->supIe[22] == 0xf2) &&
+ (macp->supIe[23] == 0x2)) {
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPAPSK\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPAPSK; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPAPSK; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPAPSK);
+ } else if ((macp->supIe[21] == 0x50) &&
+ (macp->supIe[22] == 0xf2) &&
+ (macp->supIe[23] == 0x1)) {
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPA\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPA; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPA; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPA);
+ } else if ((macp->supIe[17] == 0xf) &&
+ (macp->supIe[18] == 0xac) &&
+ (macp->supIe[19] == 0x2))
{
- return -EFAULT;
- }
- }
- else if (AuthMode == ZM_AUTH_MODE_SHARED_KEY)
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPA2PSK; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPA2PSK);
+ } else if ((macp->supIe[17] == 0xf) &&
+ (macp->supIe[18] == 0xac) &&
+ (macp->supIe[19] == 0x1))
{
- wrq->u.data.length = 11;
-
- if (copy_to_user(wrq->u.data.pointer, "shared key", 11))
- {
- return -EFAULT;
- }
+ printk(KERN_ERR
+ "wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
+ /* wd->sta.authMode = ZM_AUTH_MODE_WPA2; */
+ /* wd->ws.authMode = ZM_AUTH_MODE_WPA2; */
+ zfiWlanSetAuthenticationMode(dev,
+ ZM_AUTH_MODE_WPA2);
+ }
+ /* WPA or WPAPSK */
+ if ((macp->supIe[21] == 0x50) ||
+ (macp->supIe[22] == 0xf2)) {
+ if (macp->supIe[11] == 0x2) {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
+ } else {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
}
- else if (AuthMode == ZM_AUTH_MODE_AUTO)
- {
- wrq->u.data.length = 10;
-
- if (copy_to_user(wrq->u.data.pointer, "auto mode", 10))
- {
- return -EFAULT;
+ }
+ //WPA2 or WPA2PSK
+ if ((macp->supIe[17] == 0xf) ||
+ (macp->supIe[18] == 0xac)) {
+ if (macp->supIe[13] == 0x2) {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_TKIP; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_TKIP; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
+ } else {
+ printk(KERN_ERR
+ "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
+ /* wd->sta.wepStatus = ZM_ENCRYPTION_AES; */
+ /* wd->ws.wepStatus = ZM_ENCRYPTION_AES; */
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
}
}
- else
- {
- return -EFAULT;
- }
}
+ zfiWlanSetWpaSupport(dev, 1);
+ } else {
+ /* Reset the WPA related variables */
+ printk(KERN_ERR "disable\n");
+
+ zfiWlanSetWpaSupport(dev, 0);
+ zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_OPEN);
+ zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_WEP_DISABLED);
+
+ /* Now we only set the length in the WPA IE
+ * field to zero.
+ *macp->cardSetting.WPAIe[1] = 0;
+ */
+ }
+ }
+
+ if (op == ZD_PARAM_COUNTERMEASURES) {
+ printk(KERN_ERR
+ "****************ZD_PARAM_COUNTERMEASURES : ");
+
+ if(arg) {
+ /* mCounterMeasureState=1; */
+ printk(KERN_ERR "enable\n");
+ } else {
+ /* mCounterMeasureState=0; */
+ printk(KERN_ERR "disable\n");
+ }
+ }
+ if (op == ZD_PARAM_DROPUNENCRYPTED) {
+ printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED : ");
+
+ if(arg) {
+ printk(KERN_ERR "enable\n");
+ } else {
+ printk(KERN_ERR "disable\n");
+ }
+ }
+ if (op == ZD_PARAM_AUTH_ALGS) {
+ printk(KERN_ERR "ZD_PARAM_AUTH_ALGS : ");
+
+ if (arg == 0) {
+ printk(KERN_ERR "OPEN_SYSTEM\n");
+ } else {
+ printk(KERN_ERR "SHARED_KEY\n");
+ }
+ }
+ if (op == ZD_PARAM_WPS_FILTER) {
+ printk(KERN_ERR "ZD_PARAM_WPS_FILTER : ");
+
+ if (arg) {
+ /* mCounterMeasureState=1; */
+ macp->forwardMgmt = 1;
+ printk(KERN_ERR "enable\n");
+ } else {
+ /* mCounterMeasureState=0; */
+ macp->forwardMgmt = 0;
+ printk(KERN_ERR "disable\n");
+ }
+ }
+ }
+ err = 0;
+ break;
+ case ZD_IOCTL_GETWPAIE: {
+ struct ieee80211req_wpaie req_wpaie;
+ u16_t apId, i, j;
+
+ /* Get the AP Id */
+ apId = zfLnxGetVapId(dev);
+
+ if (apId == 0xffff) {
+ apId = 0;
+ } else {
+ apId = apId + 1;
}
+
+ if (copy_from_user(&req_wpaie, ifr->ifr_data,
+ sizeof(struct ieee80211req_wpaie))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
+
+ for (i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++) {
+ for (j = 0; j < IEEE80211_ADDR_LEN; j++) {
+ if (macp->stawpaie[i].wpa_macaddr[j] !=
+ req_wpaie.wpa_macaddr[j])
+ break;
+ }
+ if (j == 6)
break;
+ }
+ if (i < ZM_OAL_MAX_STA_SUPPORT) {
+ /* printk("ZD_IOCTL_GETWPAIE - sta index = % d\n", i); */
+ memcpy(req_wpaie.wpa_ie, macp->stawpaie[i].wpa_ie,
+ IEEE80211_MAX_IE_SIZE);
+ }
- case ZDAPIOCTL: //debug command
- if (copy_from_user(&zdreq, ifr->ifr_data, sizeof (zdreq)))
- {
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- //printk(KERN_DEBUG "usbdrv: cmd=%2x, reg=0x%04lx, value=0x%08lx\n",
- // zdreq.cmd, zdreq.addr, zdreq.value);
-
- zfLnxPrivateIoctl(dev, &zdreq);
-
- err = 0;
- break;
-
- case ZD_IOCTL_WPA:
- if (copy_from_user(&zdparm, ifr->ifr_data, sizeof(struct athr_wlan_param)))
- {
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- usbdrv_wpa_ioctl(dev, &zdparm);
- err = 0;
- break;
-
- case ZD_IOCTL_PARAM:
- {
- int *p;
- int op;
- int arg;
-
- /* Point to the name field and retrieve the
- * op and arg elements. */
- p = (int *)wrq->u.name;
- op = *p++;
- arg = *p;
-
- if(op == ZD_PARAM_ROAMING)
- {
- printk(KERN_ERR "************* ZD_PARAM_ROAMING: %d\n", arg);
- //macp->cardSetting.ap_scan=(U8)arg;
- }
- if(op == ZD_PARAM_PRIVACY)
- {
- printk(KERN_ERR "ZD_IOCTL_PRIVACY: ");
-
- /* Turn on the privacy invoke flag */
- if(arg)
- {
- // mCap[0] |= CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0] = 1;
- printk(KERN_ERR "enable\n");
-
- }
- else
- {
- // mCap[0] &= ~CAP_PRIVACY;
- // macp->cardSetting.EncryOnOff[0] = 0;
- printk(KERN_ERR "disable\n");
- }
- //changed=1;
- }
- if(op == ZD_PARAM_WPA)
- {
- printk(KERN_ERR "ZD_PARAM_WPA: ");
-
- if(arg)
- {
- printk(KERN_ERR "enable\n");
-
- if (zfiWlanQueryWlanMode(dev) != ZM_MODE_AP)
- {
- printk(KERN_ERR "Station Mode\n");
- //zfiWlanQueryWpaIe(dev, (u8_t *)&wpaIe, &wpalen);
- //printk("wpaIe : %2x,%2x,%2x\n", wpaIe[21], wpaIe[22], wpaIe[23]);
- //printk("rsnIe : %2x,%2x,%2x\n", wpaIe[17], wpaIe[18], wpaIe[19]);
- if ((macp->supIe[21] == 0x50) &&
- (macp->supIe[22] == 0xf2) &&
- (macp->supIe[23] == 0x2))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPAPSK\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPAPSK;
- //wd->ws.authMode = ZM_AUTH_MODE_WPAPSK;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPAPSK);
- }
- else if ((macp->supIe[21] == 0x50) &&
- (macp->supIe[22] == 0xf2) &&
- (macp->supIe[23] == 0x1))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPA;
- //wd->ws.authMode = ZM_AUTH_MODE_WPA;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA);
- }
- else if ((macp->supIe[17] == 0xf) &&
- (macp->supIe[18] == 0xac) &&
- (macp->supIe[19] == 0x2))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPA2PSK;
- //wd->ws.authMode = ZM_AUTH_MODE_WPA2PSK;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA2PSK);
- }
- else if ((macp->supIe[17] == 0xf) &&
- (macp->supIe[18] == 0xac) &&
- (macp->supIe[19] == 0x1))
- {
- printk(KERN_ERR "wd->sta.authMode = ZM_AUTH_MODE_WPA2\n");
- //wd->sta.authMode = ZM_AUTH_MODE_WPA2;
- //wd->ws.authMode = ZM_AUTH_MODE_WPA2;
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_WPA2);
- }
- if ((macp->supIe[21] == 0x50) || (macp->supIe[22] == 0xf2))//WPA or WPAPSK
- {
- if (macp->supIe[11] == 0x2)
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
- //wd->ws.wepStatus = ZM_ENCRYPTION_TKIP;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
- }
- else
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_AES;
- //wd->ws.wepStatus = ZM_ENCRYPTION_AES;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
- }
- }
- if ((macp->supIe[17] == 0xf) || (macp->supIe[18] == 0xac)) //WPA2 or WPA2PSK
- {
- if (macp->supIe[13] == 0x2)
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_TKIP\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_TKIP;
- //wd->ws.wepStatus = ZM_ENCRYPTION_TKIP;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_TKIP);
- }
- else
- {
- printk(KERN_ERR "wd->sta.wepStatus = ZM_ENCRYPTION_AES\n");
- //wd->sta.wepStatus = ZM_ENCRYPTION_AES;
- //wd->ws.wepStatus = ZM_ENCRYPTION_AES;
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_AES);
- }
- }
- }
- zfiWlanSetWpaSupport(dev, 1);
- }
- else
- {
- /* Reset the WPA related variables */
- printk(KERN_ERR "disable\n");
-
- zfiWlanSetWpaSupport(dev, 0);
- zfiWlanSetAuthenticationMode(dev, ZM_AUTH_MODE_OPEN);
- zfiWlanSetWepStatus(dev, ZM_ENCRYPTION_WEP_DISABLED);
-
- /* Now we only set the length in the WPA IE
- * field to zero. */
- //macp->cardSetting.WPAIe[1] = 0;
- }
- }
- if(op == ZD_PARAM_COUNTERMEASURES)
- {
- printk(KERN_ERR "================ZD_PARAM_COUNTERMEASURES: ");
-
- if(arg)
- {
- // mCounterMeasureState=1;
- printk(KERN_ERR "enable\n");
- }
- else
- {
- // mCounterMeasureState=0;
- printk(KERN_ERR "disable\n");
- }
- }
- if(op == ZD_PARAM_DROPUNENCRYPTED)
- {
- printk(KERN_ERR "ZD_PARAM_DROPUNENCRYPTED: ");
-
- if(arg)
- {
- printk(KERN_ERR "enable\n");
- }
- else
- {
- printk(KERN_ERR "disable\n");
- }
- }
- if(op == ZD_PARAM_AUTH_ALGS)
- {
- printk(KERN_ERR "ZD_PARAM_AUTH_ALGS: ");
-
- if(arg == 0)
- {
- printk(KERN_ERR "OPEN_SYSTEM\n");
- }
- else
- {
- printk(KERN_ERR "SHARED_KEY\n");
- }
- }
- if(op == ZD_PARAM_WPS_FILTER)
- {
- printk(KERN_ERR "ZD_PARAM_WPS_FILTER: ");
-
- if(arg)
- {
- // mCounterMeasureState=1;
- macp->forwardMgmt = 1;
- printk(KERN_ERR "enable\n");
- }
- else
- {
- // mCounterMeasureState=0;
- macp->forwardMgmt = 0;
- printk(KERN_ERR "disable\n");
- }
- }
- }
- err = 0;
- break;
-
- case ZD_IOCTL_GETWPAIE:
- {
- struct ieee80211req_wpaie req_wpaie;
- u16_t apId, i, j;
-
- /* Get the AP Id */
- apId = zfLnxGetVapId(dev);
-
- if (apId == 0xffff)
- {
- apId = 0;
- }
- else
- {
- apId = apId+1;
- }
-
- if (copy_from_user(&req_wpaie, ifr->ifr_data, sizeof(struct ieee80211req_wpaie))){
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- for(i = 0; i < ZM_OAL_MAX_STA_SUPPORT; i++)
- {
- for(j = 0; j < IEEE80211_ADDR_LEN; j++)
- {
- if (macp->stawpaie[i].wpa_macaddr[j] != req_wpaie.wpa_macaddr[j])
- break;
- }
- if (j == 6)
- break;
- }
- if (i < ZM_OAL_MAX_STA_SUPPORT)
- {
- //printk("ZD_IOCTL_GETWPAIE - sta index = %d\n", i);
- memcpy(req_wpaie.wpa_ie, macp->stawpaie[i].wpa_ie, IEEE80211_MAX_IE_SIZE);
- }
-
- if (copy_to_user(wrq->u.data.pointer, &req_wpaie, sizeof(struct ieee80211req_wpaie)))
- {
- return -EFAULT;
- }
- }
-
- err = 0;
- break;
-#ifdef ZM_ENABLE_CENC
- case ZM_IOCTL_CENC:
- if (copy_from_user(&macp->zd_wpa_req, ifr->ifr_data, sizeof(struct athr_wlan_param)))
- {
- printk(KERN_ERR "usbdrv: copy_from_user error\n");
- return -EFAULT;
- }
-
- usbdrv_cenc_ioctl(dev, (struct zydas_cenc_param *)&macp->zd_wpa_req);
- err = 0;
- break;
-#endif //ZM_ENABLE_CENC
- default:
- err = -EOPNOTSUPP;
- break;
- }
-
-
- return err;
+ if (copy_to_user(wrq->u.data.pointer, &req_wpaie,
+ sizeof(struct ieee80211req_wpaie))) {
+ return -EFAULT;
+ }
+ }
+
+ err = 0;
+ break;
+ #ifdef ZM_ENABLE_CENC
+ case ZM_IOCTL_CENC:
+ if (copy_from_user(&macp->zd_wpa_req, ifr->ifr_data,
+ sizeof(struct athr_wlan_param))) {
+ printk(KERN_ERR "usbdrv : copy_from_user error\n");
+ return -EFAULT;
+ }
+
+ usbdrv_cenc_ioctl(dev,
+ (struct zydas_cenc_param *)&macp->zd_wpa_req);
+ err = 0;
+ break;
+ #endif /* ZM_ENABLE_CENC */
+ default:
+ err = -EOPNOTSUPP;
+ break;
+ }
+
+ return err;
}
diff --git a/drivers/staging/otus/usbdrv.c b/drivers/staging/otus/usbdrv.c
index dfe07072011..565a839589f 100644
--- a/drivers/staging/otus/usbdrv.c
+++ b/drivers/staging/otus/usbdrv.c
@@ -936,30 +936,26 @@ int zfLnxAllocAllUrbs(struct usbdrv_private *macp)
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i)
{
endpoint = &iface_desc->endpoint[i].desc;
- if ((endpoint->bEndpointAddress & 0x80) &&
- ((endpoint->bmAttributes & 3) == 0x02))
+ if (usb_endpoint_is_bulk_in(endpoint))
{
/* we found a bulk in endpoint */
printk(KERN_ERR "bulk in: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
}
- if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
- ((endpoint->bmAttributes & 3) == 0x02))
+ if (usb_endpoint_is_bulk_out(endpoint))
{
/* we found a bulk out endpoint */
printk(KERN_ERR "bulk out: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
}
- if ((endpoint->bEndpointAddress & 0x80) &&
- ((endpoint->bmAttributes & 3) == 0x03))
+ if (usb_endpoint_is_int_in(endpoint))
{
/* we found a interrupt in endpoint */
printk(KERN_ERR "interrupt in: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
printk(KERN_ERR "interrupt in: int_interval = %d\n", endpoint->bInterval);
}
- if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
- ((endpoint->bmAttributes & 3) == 0x03))
+ if (usb_endpoint_is_int_out(endpoint))
{
/* we found a interrupt out endpoint */
printk(KERN_ERR "interrupt out: wMaxPacketSize = %x\n", le16_to_cpu(endpoint->wMaxPacketSize));
diff --git a/drivers/staging/otus/wwrap.c b/drivers/staging/otus/wwrap.c
index 1bb5f596d6c..4db8f6e75ad 100644
--- a/drivers/staging/otus/wwrap.c
+++ b/drivers/staging/otus/wwrap.c
@@ -350,8 +350,7 @@ void zfLnxUsbDataIn_callback(urb_t *urb)
buf->len = 0;
#endif
- if ((buf->tail + urb->actual_length) > buf->end)
- BUG();
+ BUG_ON((buf->tail + urb->actual_length) > buf->end);
skb_put(buf, urb->actual_length);
@@ -971,8 +970,7 @@ int zfLnxCencSendMsg(struct sock *netlink_sk, u_int8_t *msg, int len)
out:
return ret;
nlmsg_failure: /*NLMSG_PUT ʧ°Ü£¬Ôò³·ÏúÌ×½Ó×Ö»º´æ*/
- if(skb)
- kfree_skb(skb);
+ kfree_skb(skb);
goto out;
#undef COMMTYPE_GROUP
diff --git a/drivers/staging/otus/zdcompat.h b/drivers/staging/otus/zdcompat.h
index 8acf400fbc0..d9a3b2d5ba1 100644
--- a/drivers/staging/otus/zdcompat.h
+++ b/drivers/staging/otus/zdcompat.h
@@ -45,13 +45,6 @@ struct iw_request_info
#endif
#endif
-#ifndef IRQ_NONE
-typedef void irqreturn_t;
-#define IRQ_NONE
-#define IRQ_HANDLED
-#define IRQ_RETVAL(x)
-#endif
-
#ifndef in_atomic
#define in_atomic() 0
#endif
diff --git a/drivers/staging/p9auth/Kconfig b/drivers/staging/p9auth/Kconfig
new file mode 100644
index 00000000000..d1c66d26202
--- /dev/null
+++ b/drivers/staging/p9auth/Kconfig
@@ -0,0 +1,9 @@
+config PLAN9AUTH
+ tristate "Plan 9 style capability device implementation"
+ default n
+ depends on CRYPTO
+ help
+ This module implements the Plan 9 style capability device.
+
+ To compile this driver as a module, choose
+ M here: the module will be called p9auth.
diff --git a/drivers/staging/p9auth/Makefile b/drivers/staging/p9auth/Makefile
new file mode 100644
index 00000000000..3ebf6ff0eef
--- /dev/null
+++ b/drivers/staging/p9auth/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PLAN9AUTH) += p9auth.o
diff --git a/drivers/staging/p9auth/p9auth.c b/drivers/staging/p9auth/p9auth.c
new file mode 100644
index 00000000000..3cac89b26fa
--- /dev/null
+++ b/drivers/staging/p9auth/p9auth.c
@@ -0,0 +1,383 @@
+/*
+ * Plan 9 style capability device implementation for the Linux Kernel
+ *
+ * Copyright 2008, 2009 Ashwin Ganti <ashwin.ganti@gmail.com>
+ *
+ * Released under the GPLv2
+ *
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/moduleparam.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/cdev.h>
+#include <linux/uaccess.h>
+#include <linux/list.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/crypto.h>
+#include <linux/highmem.h>
+#include <linux/scatterlist.h>
+#include <linux/sched.h>
+#include <linux/cred.h>
+
+#ifndef CAP_MAJOR
+#define CAP_MAJOR 0
+#endif
+
+#ifndef CAP_NR_DEVS
+#define CAP_NR_DEVS 2 /* caphash and capuse */
+#endif
+
+#ifndef CAP_NODE_SIZE
+#define CAP_NODE_SIZE 20
+#endif
+
+#define MAX_DIGEST_SIZE 20
+
+struct cap_node {
+ char data[CAP_NODE_SIZE];
+ struct list_head list;
+};
+
+struct cap_dev {
+ struct cap_node *head;
+ int node_size;
+ unsigned long size;
+ struct semaphore sem;
+ struct cdev cdev;
+};
+
+static int cap_major = CAP_MAJOR;
+static int cap_minor;
+static int cap_nr_devs = CAP_NR_DEVS;
+static int cap_node_size = CAP_NODE_SIZE;
+
+module_param(cap_major, int, S_IRUGO);
+module_param(cap_minor, int, S_IRUGO);
+module_param(cap_nr_devs, int, S_IRUGO);
+
+MODULE_AUTHOR("Ashwin Ganti");
+MODULE_LICENSE("GPL");
+
+static struct cap_dev *cap_devices;
+
+static void hexdump(unsigned char *buf, unsigned int len)
+{
+ while (len--)
+ printk("%02x", *buf++);
+ printk("\n");
+}
+
+static char *cap_hash(char *plain_text, unsigned int plain_text_size,
+ char *key, unsigned int key_size)
+{
+ struct scatterlist sg;
+ char *result;
+ struct crypto_hash *tfm;
+ struct hash_desc desc;
+ int ret;
+
+ tfm = crypto_alloc_hash("hmac(sha1)", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm)) {
+ printk(KERN_ERR
+ "failed to load transform for hmac(sha1): %ld\n",
+ PTR_ERR(tfm));
+ return NULL;
+ }
+
+ desc.tfm = tfm;
+ desc.flags = 0;
+
+ result = kzalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
+ if (!result) {
+ printk(KERN_ERR "out of memory!\n");
+ goto out;
+ }
+
+ sg_set_buf(&sg, plain_text, plain_text_size);
+
+ ret = crypto_hash_setkey(tfm, key, key_size);
+ if (ret) {
+ printk(KERN_ERR "setkey() failed ret=%d\n", ret);
+ kfree(result);
+ result = NULL;
+ goto out;
+ }
+
+ ret = crypto_hash_digest(&desc, &sg, plain_text_size, result);
+ if (ret) {
+ printk(KERN_ERR "digest () failed ret=%d\n", ret);
+ kfree(result);
+ result = NULL;
+ goto out;
+ }
+
+ printk(KERN_DEBUG "crypto hash digest size %d\n",
+ crypto_hash_digestsize(tfm));
+ hexdump(result, MAX_DIGEST_SIZE);
+
+out:
+ crypto_free_hash(tfm);
+ return result;
+}
+
+static int cap_trim(struct cap_dev *dev)
+{
+ struct cap_node *tmp;
+ struct list_head *pos, *q;
+ if (dev->head != NULL) {
+ list_for_each_safe(pos, q, &(dev->head->list)) {
+ tmp = list_entry(pos, struct cap_node, list);
+ list_del(pos);
+ kfree(tmp);
+ }
+ }
+ return 0;
+}
+
+static int cap_open(struct inode *inode, struct file *filp)
+{
+ struct cap_dev *dev;
+ dev = container_of(inode->i_cdev, struct cap_dev, cdev);
+ filp->private_data = dev;
+
+ /* trim to 0 the length of the device if open was write-only */
+ if ((filp->f_flags & O_ACCMODE) == O_WRONLY) {
+ if (down_interruptible(&dev->sem))
+ return -ERESTARTSYS;
+ cap_trim(dev);
+ up(&dev->sem);
+ }
+ /* initialise the head if it is NULL */
+ if (dev->head == NULL) {
+ dev->head = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
+ INIT_LIST_HEAD(&(dev->head->list));
+ }
+ return 0;
+}
+
+static int cap_release(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static ssize_t cap_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *f_pos)
+{
+ struct cap_node *node_ptr, *tmp;
+ struct list_head *pos;
+ struct cap_dev *dev = filp->private_data;
+ ssize_t retval = -ENOMEM;
+ struct cred *new;
+ int len, target_int, source_int, flag = 0;
+ char *user_buf, *user_buf_running, *source_user, *target_user,
+ *rand_str, *hash_str, *result;
+
+ if (down_interruptible(&dev->sem))
+ return -ERESTARTSYS;
+
+ node_ptr = kmalloc(sizeof(struct cap_node), GFP_KERNEL);
+ user_buf = kzalloc(count, GFP_KERNEL);
+
+ if (copy_from_user(user_buf, buf, count)) {
+ retval = -EFAULT;
+ goto out;
+ }
+
+ /*
+ * If the minor number is 0 ( /dev/caphash ) then simply add the
+ * hashed capability supplied by the user to the list of hashes
+ */
+ if (0 == iminor(filp->f_dentry->d_inode)) {
+ printk(KERN_INFO "Capability being written to /dev/caphash : \n");
+ hexdump(user_buf, count);
+ memcpy(node_ptr->data, user_buf, count);
+ list_add(&(node_ptr->list), &(dev->head->list));
+ } else {
+ /*
+ * break the supplied string into tokens with @ as the
+ * delimiter If the string is "user1@user2@randomstring" we
+ * need to split it and hash 'user1@user2' using 'randomstring'
+ * as the key.
+ */
+ user_buf_running = kstrdup(user_buf, GFP_KERNEL);
+ source_user = strsep(&user_buf_running, "@");
+ target_user = strsep(&user_buf_running, "@");
+ rand_str = strsep(&user_buf_running, "@");
+
+ /* hash the string user1@user2 with rand_str as the key */
+ len = strlen(source_user) + strlen(target_user) + 1;
+ hash_str = kzalloc(len, GFP_KERNEL);
+ strcat(hash_str, source_user);
+ strcat(hash_str, "@");
+ strcat(hash_str, target_user);
+
+ printk(KERN_ALERT "the source user is %s \n", source_user);
+ printk(KERN_ALERT "the target user is %s \n", target_user);
+
+ result = cap_hash(hash_str, len, rand_str, strlen(rand_str));
+ if (NULL == result) {
+ retval = -EFAULT;
+ goto out;
+ }
+ memcpy(node_ptr->data, result, CAP_NODE_SIZE);
+ /* Change the process's uid if the hash is present in the
+ * list of hashes
+ */
+ list_for_each(pos, &(cap_devices->head->list)) {
+ /*
+ * Change the user id of the process if the hashes
+ * match
+ */
+ if (0 ==
+ memcmp(result,
+ list_entry(pos, struct cap_node,
+ list)->data,
+ CAP_NODE_SIZE)) {
+ target_int = (unsigned int)
+ simple_strtol(target_user, NULL, 0);
+ source_int = (unsigned int)
+ simple_strtol(source_user, NULL, 0);
+ flag = 1;
+
+ /*
+ * Check whether the process writing to capuse
+ * is actually owned by the source owner
+ */
+ if (source_int != current_uid()) {
+ printk(KERN_ALERT
+ "Process is not owned by the source user of the capability.\n");
+ retval = -EFAULT;
+ goto out;
+ }
+ /*
+ * What all id's need to be changed here? uid,
+ * euid, fsid, savedids ?? Currently I am
+ * changing the effective user id since most of
+ * the authorisation decisions are based on it
+ */
+ new = prepare_creds();
+ if (!new) {
+ retval = -ENOMEM;
+ goto out;
+ }
+ new->uid = (uid_t) target_int;
+ new->euid = (uid_t) target_int;
+ retval = commit_creds(new);
+ if (retval)
+ goto out;
+
+ /*
+ * Remove the capability from the list and
+ * break
+ */
+ tmp = list_entry(pos, struct cap_node, list);
+ list_del(pos);
+ kfree(tmp);
+ break;
+ }
+ }
+ if (0 == flag) {
+ /*
+ * The capability is not present in the list of the
+ * hashes stored, hence return failure
+ */
+ printk(KERN_ALERT
+ "Invalid capabiliy written to /dev/capuse \n");
+ retval = -EFAULT;
+ goto out;
+ }
+ }
+ *f_pos += count;
+ retval = count;
+ /* update the size */
+ if (dev->size < *f_pos)
+ dev->size = *f_pos;
+
+out:
+ up(&dev->sem);
+ return retval;
+}
+
+static const struct file_operations cap_fops = {
+ .owner = THIS_MODULE,
+ .write = cap_write,
+ .open = cap_open,
+ .release = cap_release,
+};
+
+static void cap_cleanup_module(void)
+{
+ int i;
+ dev_t devno = MKDEV(cap_major, cap_minor);
+ if (cap_devices) {
+ for (i = 0; i < cap_nr_devs; i++) {
+ cap_trim(cap_devices + i);
+ cdev_del(&cap_devices[i].cdev);
+ }
+ kfree(cap_devices);
+ }
+ unregister_chrdev_region(devno, cap_nr_devs);
+
+}
+
+static void cap_setup_cdev(struct cap_dev *dev, int index)
+{
+ int err, devno = MKDEV(cap_major, cap_minor + index);
+ cdev_init(&dev->cdev, &cap_fops);
+ dev->cdev.owner = THIS_MODULE;
+ dev->cdev.ops = &cap_fops;
+ err = cdev_add(&dev->cdev, devno, 1);
+ if (err)
+ printk(KERN_NOTICE "Error %d adding cap%d", err, index);
+}
+
+static int cap_init_module(void)
+{
+ int result, i;
+ dev_t dev = 0;
+
+ if (cap_major) {
+ dev = MKDEV(cap_major, cap_minor);
+ result = register_chrdev_region(dev, cap_nr_devs, "cap");
+ } else {
+ result = alloc_chrdev_region(&dev, cap_minor, cap_nr_devs,
+ "cap");
+ cap_major = MAJOR(dev);
+ }
+
+ if (result < 0) {
+ printk(KERN_WARNING "cap: can't get major %d\n",
+ cap_major);
+ return result;
+ }
+
+ cap_devices = kzalloc(cap_nr_devs * sizeof(struct cap_dev),
+ GFP_KERNEL);
+ if (!cap_devices) {
+ result = -ENOMEM;
+ goto fail;
+ }
+
+ /* Initialize each device. */
+ for (i = 0; i < cap_nr_devs; i++) {
+ cap_devices[i].node_size = cap_node_size;
+ init_MUTEX(&cap_devices[i].sem);
+ cap_setup_cdev(&cap_devices[i], i);
+ }
+
+ return 0;
+
+fail:
+ cap_cleanup_module();
+ return result;
+}
+
+module_init(cap_init_module);
+module_exit(cap_cleanup_module);
+
+
diff --git a/drivers/staging/panel/Kconfig b/drivers/staging/panel/Kconfig
index c4b30f2a549..3abe7c9d558 100644
--- a/drivers/staging/panel/Kconfig
+++ b/drivers/staging/panel/Kconfig
@@ -110,7 +110,7 @@ config PANEL_LCD_BWIDTH
---help---
Most LCDs use a standard controller which supports hardware lines of 40
characters, although sometimes only 16, 20 or 24 of them are really wired
- to the terminal. This results in some non-visible but adressable characters,
+ to the terminal. This results in some non-visible but addressable characters,
and is the case for most parallel LCDs. Other LCDs, and some serial ones,
however, use the same line width internally as what is visible. The KS0074
for example, uses 16 characters per line for 16 visible characters per line.
diff --git a/drivers/staging/phison/Kconfig b/drivers/staging/phison/Kconfig
new file mode 100644
index 00000000000..d3c65d315a2
--- /dev/null
+++ b/drivers/staging/phison/Kconfig
@@ -0,0 +1,5 @@
+config IDE_PHISON
+ tristate "PCIE ATA PS5000 IDE support"
+ depends on PCI && ATA && ATA_SFF
+ ---help---
+ This is an experimental driver for PS5000 IDE driver.
diff --git a/drivers/staging/phison/Makefile b/drivers/staging/phison/Makefile
new file mode 100644
index 00000000000..7642a2190e9
--- /dev/null
+++ b/drivers/staging/phison/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_IDE_PHISON) += phison.o
diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c
new file mode 100644
index 00000000000..270ebcb681a
--- /dev/null
+++ b/drivers/staging/phison/phison.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2006 Red Hat <evan_ko@phison.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public License
+ *
+ * [Modify History]
+ * #0001, Evan, 2008.10.22, V0.00, New release.
+ * #0002, Evan, 2008.11.01, V0.90, Test Work In Ubuntu Linux 8.04.
+ * #0003, Evan, 2008.01.08, V0.91, Change Name "PCIE-SSD" to "E-BOX".
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <scsi/scsi_host.h>
+#include <linux/libata.h>
+#include <linux/ata.h>
+
+#define PHISON_DEBUG
+
+#define DRV_NAME "phison_e-box" /* #0003 */
+#define DRV_VERSION "0.91" /* #0003 */
+
+#define PCI_VENDOR_ID_PHISON 0x1987
+#define PCI_DEVICE_ID_PS5000 0x5000
+
+static int phison_pre_reset(struct ata_link *link, unsigned long deadline)
+{
+ int ret;
+ struct ata_port *ap = link->ap;
+
+ ap->cbl = ATA_CBL_NONE;
+ ret = ata_std_prereset(link, deadline);
+ dev_dbg(ap->dev, "phison_pre_reset(), ret = %x\n", ret);
+ return ret;
+}
+
+static struct scsi_host_template phison_sht = {
+ ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static struct ata_port_operations phison_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .prereset = phison_pre_reset,
+};
+
+static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int ret;
+ struct ata_port_info info = {
+ .flags = ATA_FLAG_NO_ATAPI,
+
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA5,
+
+ .port_ops = &phison_ops,
+ };
+ const struct ata_port_info *ppi[] = { &info, NULL };
+
+ ret = ata_pci_sff_init_one(pdev, ppi, &phison_sht, NULL);
+
+ dev_dbg(&pdev->dev, "phison_init_one(), ret = %x\n", ret);
+
+ return ret;
+}
+
+static struct pci_device_id phison_pci_tbl[] = {
+ { PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 },
+ { 0, },
+};
+MODULE_DEVICE_TABLE(pci, phison_pci_tbl);
+
+static struct pci_driver phison_pci_driver = {
+ .name = DRV_NAME,
+ .id_table = phison_pci_tbl,
+ .probe = phison_init_one,
+ .remove = ata_pci_remove_one,
+#ifdef CONFIG_PM /* haven't tested it. */
+ .suspend = ata_pci_device_suspend,
+ .resume = ata_pci_device_resume,
+#endif
+};
+
+static int phison_ide_init(void)
+{
+ return pci_register_driver(&phison_pci_driver);
+}
+
+static void phison_ide_exit(void)
+{
+ pci_unregister_driver(&phison_pci_driver);
+}
+
+module_init(phison_ide_init);
+module_exit(phison_ide_exit);
+
+MODULE_AUTHOR("Evan Ko");
+MODULE_DESCRIPTION("PCIE driver module for PHISON PS5000 E-BOX");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/staging/pohmelfs/Kconfig b/drivers/staging/pohmelfs/Kconfig
new file mode 100644
index 00000000000..58158b8780f
--- /dev/null
+++ b/drivers/staging/pohmelfs/Kconfig
@@ -0,0 +1,28 @@
+config POHMELFS
+ tristate "POHMELFS filesystem support"
+ depends on NET
+ select CONNECTOR
+ select CRYPTO
+ select CRYPTO_BLKCIPHER
+ select CRYPTO_HMAC
+ help
+ POHMELFS stands for Parallel Optimized Host Message Exchange Layered
+ File System. This is a network filesystem which supports coherent
+ caching of data and metadata on clients.
+
+config POHMELFS_DEBUG
+ bool "POHMELFS debugging"
+ depends on POHMELFS
+ default n
+ help
+ Turns on excessive POHMELFS debugging facilities.
+ You usually do not want to slow things down noticeably and get really
+ lots of kernel messages in syslog.
+
+config POHMELFS_CRYPTO
+ bool "POHMELFS crypto support"
+ depends on POHMELFS
+ help
+ This option allows to encrypt and/or protect with strong
+ cryptographic hash all dataflow between server and clients.
+ Each config group can have its own keys.
diff --git a/drivers/staging/pohmelfs/Makefile b/drivers/staging/pohmelfs/Makefile
new file mode 100644
index 00000000000..196561ca26b
--- /dev/null
+++ b/drivers/staging/pohmelfs/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_POHMELFS) += pohmelfs.o
+
+pohmelfs-y := inode.o config.o dir.o net.o path_entry.o trans.o crypto.o lock.o mcache.o
diff --git a/drivers/staging/pohmelfs/config.c b/drivers/staging/pohmelfs/config.c
new file mode 100644
index 00000000000..3e67da9ea38
--- /dev/null
+++ b/drivers/staging/pohmelfs/config.c
@@ -0,0 +1,478 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/connector.h>
+#include <linux/crypto.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/in.h>
+
+#include "netfs.h"
+
+/*
+ * Global configuration list.
+ * Each client can be asked to get one of them.
+ *
+ * Allows to provide remote server address (ipv4/v6/whatever), port
+ * and so on via kernel connector.
+ */
+
+static struct cb_id pohmelfs_cn_id = {.idx = POHMELFS_CN_IDX, .val = POHMELFS_CN_VAL};
+static LIST_HEAD(pohmelfs_config_list);
+static DEFINE_MUTEX(pohmelfs_config_lock);
+
+static inline int pohmelfs_config_eql(struct pohmelfs_ctl *sc, struct pohmelfs_ctl *ctl)
+{
+ if (sc->idx == ctl->idx && sc->type == ctl->type &&
+ sc->proto == ctl->proto &&
+ sc->addrlen == ctl->addrlen &&
+ !memcmp(&sc->addr, &ctl->addr, ctl->addrlen))
+ return 1;
+
+ return 0;
+}
+
+static struct pohmelfs_config_group *pohmelfs_find_config_group(unsigned int idx)
+{
+ struct pohmelfs_config_group *g, *group = NULL;
+
+ list_for_each_entry(g, &pohmelfs_config_list, group_entry) {
+ if (g->idx == idx) {
+ group = g;
+ break;
+ }
+ }
+
+ return group;
+}
+
+static struct pohmelfs_config_group *pohmelfs_find_create_config_group(unsigned int idx)
+{
+ struct pohmelfs_config_group *g;
+
+ g = pohmelfs_find_config_group(idx);
+ if (g)
+ return g;
+
+ g = kzalloc(sizeof(struct pohmelfs_config_group), GFP_KERNEL);
+ if (!g)
+ return NULL;
+
+ INIT_LIST_HEAD(&g->config_list);
+ g->idx = idx;
+ g->num_entry = 0;
+
+ list_add_tail(&g->group_entry, &pohmelfs_config_list);
+
+ return g;
+}
+
+int pohmelfs_copy_config(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_config *c, *dst;
+ int err = -ENODEV;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_config_group(psb->idx);
+ if (!g)
+ goto out_unlock;
+
+ /*
+ * Run over all entries in given config group and try to crate and
+ * initialize those, which do not exist in superblock list.
+ * Skip all existing entries.
+ */
+
+ list_for_each_entry(c, &g->config_list, config_entry) {
+ err = 0;
+ list_for_each_entry(dst, &psb->state_list, config_entry) {
+ if (pohmelfs_config_eql(&dst->state.ctl, &c->state.ctl)) {
+ err = -EEXIST;
+ break;
+ }
+ }
+
+ if (err)
+ continue;
+
+ dst = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
+ if (!dst) {
+ err = -ENOMEM;
+ break;
+ }
+
+ memcpy(&dst->state.ctl, &c->state.ctl, sizeof(struct pohmelfs_ctl));
+
+ list_add_tail(&dst->config_entry, &psb->state_list);
+
+ err = pohmelfs_state_init_one(psb, dst);
+ if (err) {
+ list_del(&dst->config_entry);
+ kfree(dst);
+ }
+
+ err = 0;
+ }
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+
+ return err;
+}
+
+int pohmelfs_copy_crypto(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config_group *g;
+ int err = -ENOENT;
+
+ mutex_lock(&pohmelfs_config_lock);
+ g = pohmelfs_find_config_group(psb->idx);
+ if (!g)
+ goto err_out_exit;
+
+ if (g->hash_string) {
+ err = -ENOMEM;
+ psb->hash_string = kstrdup(g->hash_string, GFP_KERNEL);
+ if (!psb->hash_string)
+ goto err_out_exit;
+ psb->hash_strlen = g->hash_strlen;
+ }
+
+ if (g->cipher_string) {
+ psb->cipher_string = kstrdup(g->cipher_string, GFP_KERNEL);
+ if (!psb->cipher_string)
+ goto err_out_free_hash_string;
+ psb->cipher_strlen = g->cipher_strlen;
+ }
+
+ if (g->hash_keysize) {
+ psb->hash_key = kmalloc(g->hash_keysize, GFP_KERNEL);
+ if (!psb->hash_key)
+ goto err_out_free_cipher_string;
+ memcpy(psb->hash_key, g->hash_key, g->hash_keysize);
+ psb->hash_keysize = g->hash_keysize;
+ }
+
+ if (g->cipher_keysize) {
+ psb->cipher_key = kmalloc(g->cipher_keysize, GFP_KERNEL);
+ if (!psb->cipher_key)
+ goto err_out_free_hash;
+ memcpy(psb->cipher_key, g->cipher_key, g->cipher_keysize);
+ psb->cipher_keysize = g->cipher_keysize;
+ }
+
+ mutex_unlock(&pohmelfs_config_lock);
+
+ return 0;
+
+err_out_free_hash:
+ kfree(psb->hash_key);
+err_out_free_cipher_string:
+ kfree(psb->cipher_string);
+err_out_free_hash_string:
+ kfree(psb->hash_string);
+err_out_exit:
+ mutex_unlock(&pohmelfs_config_lock);
+ return err;
+}
+
+static int pohmelfs_send_reply(int err, int msg_num, int action, struct cn_msg *msg, struct pohmelfs_ctl *ctl)
+{
+ struct pohmelfs_cn_ack *ack;
+
+ ack = kmalloc(sizeof(struct pohmelfs_cn_ack), GFP_KERNEL);
+ if (!ack)
+ return -ENOMEM;
+
+ memset(ack, 0, sizeof(struct pohmelfs_cn_ack));
+ memcpy(&ack->msg, msg, sizeof(struct cn_msg));
+
+ if (action == POHMELFS_CTLINFO_ACK)
+ memcpy(&ack->ctl, ctl, sizeof(struct pohmelfs_ctl));
+
+ ack->msg.len = sizeof(struct pohmelfs_cn_ack) - sizeof(struct cn_msg);
+ ack->msg.ack = msg->ack + 1;
+ ack->error = err;
+ ack->msg_num = msg_num;
+
+ cn_netlink_send(&ack->msg, 0, GFP_KERNEL);
+ kfree(ack);
+ return 0;
+}
+
+static int pohmelfs_cn_disp(struct cn_msg *msg)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+ struct pohmelfs_config *c, *tmp;
+ int err = 0, i = 1;
+
+ if (msg->len != sizeof(struct pohmelfs_ctl))
+ return -EBADMSG;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_config_group(ctl->idx);
+ if (!g) {
+ pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL);
+ goto out_unlock;
+ }
+
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ struct pohmelfs_ctl *sc = &c->state.ctl;
+ if (pohmelfs_send_reply(err, g->num_entry - i, POHMELFS_CTLINFO_ACK, msg, sc)) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+ i += 1;
+ }
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ return err;
+}
+
+static int pohmelfs_cn_ctl(struct cn_msg *msg, int action)
+{
+ struct pohmelfs_config_group *g;
+ struct pohmelfs_ctl *ctl = (struct pohmelfs_ctl *)msg->data;
+ struct pohmelfs_config *c, *tmp;
+ int err = 0;
+
+ if (msg->len != sizeof(struct pohmelfs_ctl))
+ return -EBADMSG;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_create_config_group(ctl->idx);
+ if (!g) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ struct pohmelfs_ctl *sc = &c->state.ctl;
+
+ if (pohmelfs_config_eql(sc, ctl)) {
+ if (action == POHMELFS_FLAGS_ADD) {
+ err = -EEXIST;
+ goto out_unlock;
+ } else if (action == POHMELFS_FLAGS_DEL) {
+ list_del(&c->config_entry);
+ g->num_entry--;
+ kfree(c);
+ goto out_unlock;
+ } else {
+ err = -EEXIST;
+ goto out_unlock;
+ }
+ }
+ }
+ if (action == POHMELFS_FLAGS_DEL) {
+ err = -EBADMSG;
+ goto out_unlock;
+ }
+
+ c = kzalloc(sizeof(struct pohmelfs_config), GFP_KERNEL);
+ if (!c) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+ memcpy(&c->state.ctl, ctl, sizeof(struct pohmelfs_ctl));
+ g->num_entry++;
+ list_add_tail(&c->config_entry, &g->config_list);
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+ err = -ENOMEM;
+
+ return err;
+}
+
+static int pohmelfs_crypto_hash_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
+{
+ char *algo = (char *)c->data;
+ u8 *key = (u8 *)(algo + c->strlen);
+
+ if (g->hash_string)
+ return -EEXIST;
+
+ g->hash_string = kstrdup(algo, GFP_KERNEL);
+ if (!g->hash_string)
+ return -ENOMEM;
+ g->hash_strlen = c->strlen;
+ g->hash_keysize = c->keysize;
+
+ g->hash_key = kmalloc(c->keysize, GFP_KERNEL);
+ if (!g->hash_key) {
+ kfree(g->hash_string);
+ return -ENOMEM;
+ }
+
+ memcpy(g->hash_key, key, c->keysize);
+
+ return 0;
+}
+
+static int pohmelfs_crypto_cipher_init(struct pohmelfs_config_group *g, struct pohmelfs_crypto *c)
+{
+ char *algo = (char *)c->data;
+ u8 *key = (u8 *)(algo + c->strlen);
+
+ if (g->cipher_string)
+ return -EEXIST;
+
+ g->cipher_string = kstrdup(algo, GFP_KERNEL);
+ if (!g->cipher_string)
+ return -ENOMEM;
+ g->cipher_strlen = c->strlen;
+ g->cipher_keysize = c->keysize;
+
+ g->cipher_key = kmalloc(c->keysize, GFP_KERNEL);
+ if (!g->cipher_key) {
+ kfree(g->cipher_string);
+ return -ENOMEM;
+ }
+
+ memcpy(g->cipher_key, key, c->keysize);
+
+ return 0;
+}
+
+
+static int pohmelfs_cn_crypto(struct cn_msg *msg)
+{
+ struct pohmelfs_crypto *crypto = (struct pohmelfs_crypto *)msg->data;
+ struct pohmelfs_config_group *g;
+ int err = 0;
+
+ dprintk("%s: idx: %u, strlen: %u, type: %u, keysize: %u, algo: %s.\n",
+ __func__, crypto->idx, crypto->strlen, crypto->type,
+ crypto->keysize, (char *)crypto->data);
+
+ mutex_lock(&pohmelfs_config_lock);
+ g = pohmelfs_find_create_config_group(crypto->idx);
+ if (!g) {
+ err = -ENOMEM;
+ goto out_unlock;
+ }
+
+ switch (crypto->type) {
+ case POHMELFS_CRYPTO_HASH:
+ err = pohmelfs_crypto_hash_init(g, crypto);
+ break;
+ case POHMELFS_CRYPTO_CIPHER:
+ err = pohmelfs_crypto_cipher_init(g, crypto);
+ break;
+ default:
+ err = -ENOTSUPP;
+ break;
+ }
+
+out_unlock:
+ mutex_unlock(&pohmelfs_config_lock);
+ if (pohmelfs_send_reply(err, 0, POHMELFS_NOINFO_ACK, msg, NULL))
+ err = -ENOMEM;
+
+ return err;
+}
+
+static void pohmelfs_cn_callback(void *data)
+{
+ struct cn_msg *msg = data;
+ int err;
+
+ switch (msg->flags) {
+ case POHMELFS_FLAGS_ADD:
+ err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_ADD);
+ break;
+ case POHMELFS_FLAGS_DEL:
+ err = pohmelfs_cn_ctl(msg, POHMELFS_FLAGS_DEL);
+ break;
+ case POHMELFS_FLAGS_SHOW:
+ err = pohmelfs_cn_disp(msg);
+ break;
+ case POHMELFS_FLAGS_CRYPTO:
+ err = pohmelfs_cn_crypto(msg);
+ break;
+ default:
+ err = -ENOSYS;
+ break;
+ }
+}
+
+int pohmelfs_config_check(struct pohmelfs_config *config, int idx)
+{
+ struct pohmelfs_ctl *ctl = &config->state.ctl;
+ struct pohmelfs_config *tmp;
+ int err = -ENOENT;
+ struct pohmelfs_ctl *sc;
+ struct pohmelfs_config_group *g;
+
+ mutex_lock(&pohmelfs_config_lock);
+
+ g = pohmelfs_find_config_group(ctl->idx);
+ if (g) {
+ list_for_each_entry(tmp, &g->config_list, config_entry) {
+ sc = &tmp->state.ctl;
+
+ if (pohmelfs_config_eql(sc, ctl)) {
+ err = 0;
+ break;
+ }
+ }
+ }
+
+ mutex_unlock(&pohmelfs_config_lock);
+
+ return err;
+}
+
+int __init pohmelfs_config_init(void)
+{
+ return cn_add_callback(&pohmelfs_cn_id, "pohmelfs", pohmelfs_cn_callback);
+}
+
+void pohmelfs_config_exit(void)
+{
+ struct pohmelfs_config *c, *tmp;
+ struct pohmelfs_config_group *g, *gtmp;
+
+ cn_del_callback(&pohmelfs_cn_id);
+
+ mutex_lock(&pohmelfs_config_lock);
+ list_for_each_entry_safe(g, gtmp, &pohmelfs_config_list, group_entry) {
+ list_for_each_entry_safe(c, tmp, &g->config_list, config_entry) {
+ list_del(&c->config_entry);
+ kfree(c);
+ }
+
+ list_del(&g->group_entry);
+
+ if (g->hash_string)
+ kfree(g->hash_string);
+
+ if (g->cipher_string)
+ kfree(g->cipher_string);
+
+ kfree(g);
+ }
+ mutex_unlock(&pohmelfs_config_lock);
+}
diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c
new file mode 100644
index 00000000000..31d765de92c
--- /dev/null
+++ b/drivers/staging/pohmelfs/crypto.c
@@ -0,0 +1,880 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/crypto.h>
+#include <linux/highmem.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/slab.h>
+
+#include "netfs.h"
+
+static struct crypto_hash *pohmelfs_init_hash(struct pohmelfs_sb *psb)
+{
+ int err;
+ struct crypto_hash *hash;
+
+ hash = crypto_alloc_hash(psb->hash_string, 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(hash)) {
+ err = PTR_ERR(hash);
+ dprintk("%s: idx: %u: failed to allocate hash '%s', err: %d.\n",
+ __func__, psb->idx, psb->hash_string, err);
+ goto err_out_exit;
+ }
+
+ psb->crypto_attached_size = crypto_hash_digestsize(hash);
+
+ if (!psb->hash_keysize)
+ return hash;
+
+ err = crypto_hash_setkey(hash, psb->hash_key, psb->hash_keysize);
+ if (err) {
+ dprintk("%s: idx: %u: failed to set key for hash '%s', err: %d.\n",
+ __func__, psb->idx, psb->hash_string, err);
+ goto err_out_free;
+ }
+
+ return hash;
+
+err_out_free:
+ crypto_free_hash(hash);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static struct crypto_ablkcipher *pohmelfs_init_cipher(struct pohmelfs_sb *psb)
+{
+ int err = -EINVAL;
+ struct crypto_ablkcipher *cipher;
+
+ if (!psb->cipher_keysize)
+ goto err_out_exit;
+
+ cipher = crypto_alloc_ablkcipher(psb->cipher_string, 0, 0);
+ if (IS_ERR(cipher)) {
+ err = PTR_ERR(cipher);
+ dprintk("%s: idx: %u: failed to allocate cipher '%s', err: %d.\n",
+ __func__, psb->idx, psb->cipher_string, err);
+ goto err_out_exit;
+ }
+
+ crypto_ablkcipher_clear_flags(cipher, ~0);
+
+ err = crypto_ablkcipher_setkey(cipher, psb->cipher_key, psb->cipher_keysize);
+ if (err) {
+ dprintk("%s: idx: %u: failed to set key for cipher '%s', err: %d.\n",
+ __func__, psb->idx, psb->cipher_string, err);
+ goto err_out_free;
+ }
+
+ return cipher;
+
+err_out_free:
+ crypto_free_ablkcipher(cipher);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
+{
+ int err;
+
+ e->page_num = 0;
+
+ e->size = PAGE_SIZE;
+ e->data = kmalloc(e->size, GFP_KERNEL);
+ if (!e->data) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ if (psb->hash_string) {
+ e->hash = pohmelfs_init_hash(psb);
+ if (IS_ERR(e->hash)) {
+ err = PTR_ERR(e->hash);
+ e->hash = NULL;
+ goto err_out_free;
+ }
+ }
+
+ if (psb->cipher_string) {
+ e->cipher = pohmelfs_init_cipher(psb);
+ if (IS_ERR(e->cipher)) {
+ err = PTR_ERR(e->cipher);
+ e->cipher = NULL;
+ goto err_out_free_hash;
+ }
+ }
+
+ return 0;
+
+err_out_free_hash:
+ crypto_free_hash(e->hash);
+err_out_free:
+ kfree(e->data);
+err_out_exit:
+ return err;
+}
+
+void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e)
+{
+ if (e->hash)
+ crypto_free_hash(e->hash);
+ if (e->cipher)
+ crypto_free_ablkcipher(e->cipher);
+ kfree(e->data);
+}
+
+static void pohmelfs_crypto_complete(struct crypto_async_request *req, int err)
+{
+ struct pohmelfs_crypto_completion *c = req->data;
+
+ if (err == -EINPROGRESS)
+ return;
+
+ dprintk("%s: req: %p, err: %d.\n", __func__, req, err);
+ c->error = err;
+ complete(&c->complete);
+}
+
+static int pohmelfs_crypto_process(struct ablkcipher_request *req,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src,
+ void *iv, int enc, unsigned long timeout)
+{
+ struct pohmelfs_crypto_completion complete;
+ int err;
+
+ init_completion(&complete.complete);
+ complete.error = -EINPROGRESS;
+
+ ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ pohmelfs_crypto_complete, &complete);
+
+ ablkcipher_request_set_crypt(req, sg_src, sg_dst, sg_src->length, iv);
+
+ if (enc)
+ err = crypto_ablkcipher_encrypt(req);
+ else
+ err = crypto_ablkcipher_decrypt(req);
+
+ switch (err) {
+ case -EINPROGRESS:
+ case -EBUSY:
+ err = wait_for_completion_interruptible_timeout(&complete.complete,
+ timeout);
+ if (!err)
+ err = -ETIMEDOUT;
+ else
+ err = complete.error;
+ break;
+ default:
+ break;
+ }
+
+ return err;
+}
+
+int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 cmd_iv,
+ void *data, struct page *page, unsigned int size)
+{
+ int err;
+ struct scatterlist sg;
+
+ if (!e->cipher && !e->hash)
+ return 0;
+
+ dprintk("%s: eng: %p, iv: %llx, data: %p, page: %p/%lu, size: %u.\n",
+ __func__, e, cmd_iv, data, page, (page)?page->index:0, size);
+
+ if (data) {
+ sg_init_one(&sg, data, size);
+ } else {
+ sg_init_table(&sg, 1);
+ sg_set_page(&sg, page, size, 0);
+ }
+
+ if (e->cipher) {
+ struct ablkcipher_request *req = e->data + crypto_hash_digestsize(e->hash);
+ u8 iv[32];
+
+ memset(iv, 0, sizeof(iv));
+ memcpy(iv, &cmd_iv, sizeof(cmd_iv));
+
+ ablkcipher_request_set_tfm(req, e->cipher);
+
+ err = pohmelfs_crypto_process(req, &sg, &sg, iv, 0, e->timeout);
+ if (err)
+ goto err_out_exit;
+ }
+
+ if (e->hash) {
+ struct hash_desc desc;
+ void *dst = e->data + e->size/2;
+
+ desc.tfm = e->hash;
+ desc.flags = 0;
+
+ err = crypto_hash_init(&desc);
+ if (err)
+ goto err_out_exit;
+
+ err = crypto_hash_update(&desc, &sg, size);
+ if (err)
+ goto err_out_exit;
+
+ err = crypto_hash_final(&desc, dst);
+ if (err)
+ goto err_out_exit;
+
+ err = !!memcmp(dst, e->data, crypto_hash_digestsize(e->hash));
+
+ if (err) {
+#ifdef CONFIG_POHMELFS_DEBUG
+ unsigned int i;
+ unsigned char *recv = e->data, *calc = dst;
+
+ dprintk("%s: eng: %p, hash: %p, cipher: %p: iv : %llx, hash mismatch (recv/calc): ",
+ __func__, e, e->hash, e->cipher, cmd_iv);
+ for (i=0; i<crypto_hash_digestsize(e->hash); ++i) {
+#if 0
+ dprintka("%02x ", recv[i]);
+ if (recv[i] != calc[i]) {
+ dprintka("| calc byte: %02x.\n", calc[i]);
+ break;
+ }
+#else
+ dprintka("%02x/%02x ", recv[i], calc[i]);
+#endif
+ }
+ dprintk("\n");
+#endif
+ goto err_out_exit;
+ } else {
+ dprintk("%s: eng: %p, hash: %p, cipher: %p: hashes matched.\n",
+ __func__, e, e->hash, e->cipher);
+ }
+ }
+
+ dprintk("%s: eng: %p, size: %u, hash: %p, cipher: %p: completed.\n",
+ __func__, e, e->size, e->hash, e->cipher);
+
+ return 0;
+
+err_out_exit:
+ dprintk("%s: eng: %p, hash: %p, cipher: %p: err: %d.\n",
+ __func__, e, e->hash, e->cipher, err);
+ return err;
+}
+
+static int pohmelfs_trans_iter(struct netfs_trans *t, struct pohmelfs_crypto_engine *e,
+ int (* iterator) (struct pohmelfs_crypto_engine *e,
+ struct scatterlist *dst,
+ struct scatterlist *src))
+{
+ void *data = t->iovec.iov_base + sizeof(struct netfs_cmd) + t->psb->crypto_attached_size;
+ unsigned int size = t->iovec.iov_len - sizeof(struct netfs_cmd) - t->psb->crypto_attached_size;
+ struct netfs_cmd *cmd = data;
+ unsigned int sz, pages = t->attached_pages, i, csize, cmd_cmd, dpage_idx;
+ struct scatterlist sg_src, sg_dst;
+ int err;
+
+ while (size) {
+ cmd = data;
+ cmd_cmd = __be16_to_cpu(cmd->cmd);
+ csize = __be32_to_cpu(cmd->size);
+ cmd->iv = __cpu_to_be64(e->iv);
+
+ if (cmd_cmd == NETFS_READ_PAGES || cmd_cmd == NETFS_READ_PAGE)
+ csize = __be16_to_cpu(cmd->ext);
+
+ sz = csize + __be16_to_cpu(cmd->cpad) + sizeof(struct netfs_cmd);
+
+ dprintk("%s: size: %u, sz: %u, cmd_size: %u, cmd_cpad: %u.\n",
+ __func__, size, sz, __be32_to_cpu(cmd->size), __be16_to_cpu(cmd->cpad));
+
+ data += sz;
+ size -= sz;
+
+ sg_init_one(&sg_src, cmd->data, sz - sizeof(struct netfs_cmd));
+ sg_init_one(&sg_dst, cmd->data, sz - sizeof(struct netfs_cmd));
+
+ err = iterator(e, &sg_dst, &sg_src);
+ if (err)
+ return err;
+ }
+
+ if (!pages)
+ return 0;
+
+ dpage_idx = 0;
+ for (i=0; i<t->page_num; ++i) {
+ struct page *page = t->pages[i];
+ struct page *dpage = e->pages[dpage_idx];
+
+ if (!page)
+ continue;
+
+ sg_init_table(&sg_src, 1);
+ sg_init_table(&sg_dst, 1);
+ sg_set_page(&sg_src, page, page_private(page), 0);
+ sg_set_page(&sg_dst, dpage, page_private(page), 0);
+
+ err = iterator(e, &sg_dst, &sg_src);
+ if (err)
+ return err;
+
+ pages--;
+ if (!pages)
+ break;
+ dpage_idx++;
+ }
+
+ return 0;
+}
+
+static int pohmelfs_encrypt_iterator(struct pohmelfs_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ struct ablkcipher_request *req = e->data;
+ u8 iv[32];
+
+ memset(iv, 0, sizeof(iv));
+
+ memcpy(iv, &e->iv, sizeof(e->iv));
+
+ return pohmelfs_crypto_process(req, sg_dst, sg_src, iv, 1, e->timeout);
+}
+
+static int pohmelfs_encrypt(struct pohmelfs_crypto_thread *tc)
+{
+ struct netfs_trans *t = tc->trans;
+ struct pohmelfs_crypto_engine *e = &tc->eng;
+ struct ablkcipher_request *req = e->data;
+
+ memset(req, 0, sizeof(struct ablkcipher_request));
+ ablkcipher_request_set_tfm(req, e->cipher);
+
+ e->iv = pohmelfs_gen_iv(t);
+
+ return pohmelfs_trans_iter(t, e, pohmelfs_encrypt_iterator);
+}
+
+static int pohmelfs_hash_iterator(struct pohmelfs_crypto_engine *e,
+ struct scatterlist *sg_dst, struct scatterlist *sg_src)
+{
+ return crypto_hash_update(e->data, sg_src, sg_src->length);
+}
+
+static int pohmelfs_hash(struct pohmelfs_crypto_thread *tc)
+{
+ struct pohmelfs_crypto_engine *e = &tc->eng;
+ struct hash_desc *desc = e->data;
+ unsigned char *dst = tc->trans->iovec.iov_base + sizeof(struct netfs_cmd);
+ int err;
+
+ desc->tfm = e->hash;
+ desc->flags = 0;
+
+ err = crypto_hash_init(desc);
+ if (err)
+ return err;
+
+ err = pohmelfs_trans_iter(tc->trans, e, pohmelfs_hash_iterator);
+ if (err)
+ return err;
+
+ err = crypto_hash_final(desc, dst);
+ if (err)
+ return err;
+
+ {
+ unsigned int i;
+ dprintk("%s: ", __func__);
+ for (i=0; i<tc->psb->crypto_attached_size; ++i)
+ dprintka("%02x ", dst[i]);
+ dprintka("\n");
+ }
+
+ return 0;
+}
+
+static void pohmelfs_crypto_pages_free(struct pohmelfs_crypto_engine *e)
+{
+ unsigned int i;
+
+ for (i=0; i<e->page_num; ++i)
+ __free_page(e->pages[i]);
+ kfree(e->pages);
+}
+
+static int pohmelfs_crypto_pages_alloc(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb)
+{
+ unsigned int i;
+
+ e->pages = kmalloc(psb->trans_max_pages * sizeof(struct page *), GFP_KERNEL);
+ if (!e->pages)
+ return -ENOMEM;
+
+ for (i=0; i<psb->trans_max_pages; ++i) {
+ e->pages[i] = alloc_page(GFP_KERNEL);
+ if (!e->pages[i])
+ break;
+ }
+
+ e->page_num = i;
+ if (!e->page_num)
+ goto err_out_free;
+
+ return 0;
+
+err_out_free:
+ kfree(e->pages);
+ return -ENOMEM;
+}
+
+static void pohmelfs_sys_crypto_exit_one(struct pohmelfs_crypto_thread *t)
+{
+ struct pohmelfs_sb *psb = t->psb;
+
+ if (t->thread)
+ kthread_stop(t->thread);
+
+ mutex_lock(&psb->crypto_thread_lock);
+ list_del(&t->thread_entry);
+ psb->crypto_thread_num--;
+ mutex_unlock(&psb->crypto_thread_lock);
+
+ pohmelfs_crypto_engine_exit(&t->eng);
+ pohmelfs_crypto_pages_free(&t->eng);
+ kfree(t);
+}
+
+static int pohmelfs_crypto_finish(struct netfs_trans *t, struct pohmelfs_sb *psb, int err)
+{
+ struct netfs_cmd *cmd = t->iovec.iov_base;
+ netfs_convert_cmd(cmd);
+
+ if (likely(!err))
+ err = netfs_trans_finish_send(t, psb);
+
+ t->result = err;
+ netfs_trans_put(t);
+
+ return err;
+}
+
+void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th)
+{
+ struct pohmelfs_sb *psb = th->psb;
+
+ th->page = NULL;
+ th->trans = NULL;
+
+ mutex_lock(&psb->crypto_thread_lock);
+ list_move_tail(&th->thread_entry, &psb->crypto_ready_list);
+ mutex_unlock(&psb->crypto_thread_lock);
+ wake_up(&psb->wait);
+}
+
+static int pohmelfs_crypto_thread_trans(struct pohmelfs_crypto_thread *t)
+{
+ struct netfs_trans *trans;
+ int err = 0;
+
+ trans = t->trans;
+ trans->eng = NULL;
+
+ if (t->eng.hash) {
+ err = pohmelfs_hash(t);
+ if (err)
+ goto out_complete;
+ }
+
+ if (t->eng.cipher) {
+ err = pohmelfs_encrypt(t);
+ if (err)
+ goto out_complete;
+ trans->eng = &t->eng;
+ }
+
+out_complete:
+ t->page = NULL;
+ t->trans = NULL;
+
+ if (!trans->eng)
+ pohmelfs_crypto_thread_make_ready(t);
+
+ pohmelfs_crypto_finish(trans, t->psb, err);
+ return err;
+}
+
+static int pohmelfs_crypto_thread_page(struct pohmelfs_crypto_thread *t)
+{
+ struct pohmelfs_crypto_engine *e = &t->eng;
+ struct page *page = t->page;
+ int err;
+
+ WARN_ON(!PageChecked(page));
+
+ err = pohmelfs_crypto_process_input_data(e, e->iv, NULL, page, t->size);
+ if (!err)
+ SetPageUptodate(page);
+ else
+ SetPageError(page);
+ unlock_page(page);
+ page_cache_release(page);
+
+ pohmelfs_crypto_thread_make_ready(t);
+
+ return err;
+}
+
+static int pohmelfs_crypto_thread_func(void *data)
+{
+ struct pohmelfs_crypto_thread *t = data;
+
+ while (!kthread_should_stop()) {
+ wait_event_interruptible(t->wait, kthread_should_stop() ||
+ t->trans || t->page);
+
+ if (kthread_should_stop())
+ break;
+
+ if (!t->trans && !t->page)
+ continue;
+
+ dprintk("%s: thread: %p, trans: %p, page: %p.\n",
+ __func__, t, t->trans, t->page);
+
+ if (t->trans)
+ pohmelfs_crypto_thread_trans(t);
+ else if (t->page)
+ pohmelfs_crypto_thread_page(t);
+ }
+
+ return 0;
+}
+
+static void pohmelfs_crypto_flush(struct pohmelfs_sb *psb, struct list_head *head)
+{
+ while (!list_empty(head)) {
+ struct pohmelfs_crypto_thread *t = NULL;
+
+ mutex_lock(&psb->crypto_thread_lock);
+ if (!list_empty(head)) {
+ t = list_first_entry(head, struct pohmelfs_crypto_thread, thread_entry);
+ list_del_init(&t->thread_entry);
+ }
+ mutex_unlock(&psb->crypto_thread_lock);
+
+ if (t)
+ pohmelfs_sys_crypto_exit_one(t);
+ }
+}
+
+static void pohmelfs_sys_crypto_exit(struct pohmelfs_sb *psb)
+{
+ while (!list_empty(&psb->crypto_active_list) || !list_empty(&psb->crypto_ready_list)) {
+ dprintk("%s: crypto_thread_num: %u.\n", __func__, psb->crypto_thread_num);
+ pohmelfs_crypto_flush(psb, &psb->crypto_active_list);
+ pohmelfs_crypto_flush(psb, &psb->crypto_ready_list);
+ }
+}
+
+static int pohmelfs_sys_crypto_init(struct pohmelfs_sb *psb)
+{
+ unsigned int i;
+ struct pohmelfs_crypto_thread *t;
+ struct pohmelfs_config *c;
+ struct netfs_state *st;
+ int err;
+
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ err = pohmelfs_crypto_engine_init(&st->eng, psb);
+ if (err)
+ goto err_out_exit;
+
+ dprintk("%s: st: %p, eng: %p, hash: %p, cipher: %p.\n",
+ __func__, st, &st->eng, &st->eng.hash, &st->eng.cipher);
+ }
+
+ for (i=0; i<psb->crypto_thread_num; ++i) {
+ err = -ENOMEM;
+ t = kzalloc(sizeof(struct pohmelfs_crypto_thread), GFP_KERNEL);
+ if (!t)
+ goto err_out_free_state_engines;
+
+ init_waitqueue_head(&t->wait);
+
+ t->psb = psb;
+ t->trans = NULL;
+ t->eng.thread = t;
+
+ err = pohmelfs_crypto_engine_init(&t->eng, psb);
+ if (err)
+ goto err_out_free_state_engines;
+
+ err = pohmelfs_crypto_pages_alloc(&t->eng, psb);
+ if (err)
+ goto err_out_free;
+
+ t->thread = kthread_run(pohmelfs_crypto_thread_func, t,
+ "pohmelfs-crypto-%d-%d", psb->idx, i);
+ if (IS_ERR(t->thread)) {
+ err = PTR_ERR(t->thread);
+ t->thread = NULL;
+ goto err_out_free;
+ }
+
+ if (t->eng.cipher)
+ psb->crypto_align_size = crypto_ablkcipher_blocksize(t->eng.cipher);
+
+ mutex_lock(&psb->crypto_thread_lock);
+ list_add_tail(&t->thread_entry, &psb->crypto_ready_list);
+ mutex_unlock(&psb->crypto_thread_lock);
+ }
+
+ psb->crypto_thread_num = i;
+ return 0;
+
+err_out_free:
+ pohmelfs_sys_crypto_exit_one(t);
+err_out_free_state_engines:
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+ pohmelfs_crypto_engine_exit(&st->eng);
+ }
+err_out_exit:
+ pohmelfs_sys_crypto_exit(psb);
+ return err;
+}
+
+void pohmelfs_crypto_exit(struct pohmelfs_sb *psb)
+{
+ pohmelfs_sys_crypto_exit(psb);
+
+ kfree(psb->hash_string);
+ kfree(psb->cipher_string);
+}
+
+static int pohmelfs_crypt_init_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct pohmelfs_sb *psb = private;
+
+ psb->flags = -err;
+ dprintk("%s: err: %d.\n", __func__, err);
+
+ wake_up(&psb->wait);
+
+ return err;
+}
+
+static int pohmelfs_crypto_init_handshake(struct pohmelfs_sb *psb)
+{
+ struct netfs_trans *t;
+ struct netfs_crypto_capabilities *cap;
+ struct netfs_cmd *cmd;
+ char *str;
+ int err = -ENOMEM, size;
+
+ size = sizeof(struct netfs_crypto_capabilities) +
+ psb->cipher_strlen + psb->hash_strlen + 2; /* 0 bytes */
+
+ t = netfs_trans_alloc(psb, size, 0, 0);
+ if (!t)
+ goto err_out_exit;
+
+ t->complete = pohmelfs_crypt_init_complete;
+ t->private = psb;
+
+ cmd = netfs_trans_current(t);
+ cap = (struct netfs_crypto_capabilities *)(cmd + 1);
+ str = (char *)(cap + 1);
+
+ cmd->cmd = NETFS_CAPABILITIES;
+ cmd->id = POHMELFS_CRYPTO_CAPABILITIES;
+ cmd->size = size;
+ cmd->start = 0;
+ cmd->ext = 0;
+ cmd->csize = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, size);
+
+ cap->hash_strlen = psb->hash_strlen;
+ if (cap->hash_strlen) {
+ sprintf(str, "%s", psb->hash_string);
+ str += cap->hash_strlen;
+ }
+
+ cap->cipher_strlen = psb->cipher_strlen;
+ cap->cipher_keysize = psb->cipher_keysize;
+ if (cap->cipher_strlen)
+ sprintf(str, "%s", psb->cipher_string);
+
+ netfs_convert_crypto_capabilities(cap);
+
+ psb->flags = ~0;
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_exit;
+
+ err = wait_event_interruptible_timeout(psb->wait, (psb->flags != ~0),
+ psb->wait_on_page_timeout);
+ if (!err)
+ err = -ETIMEDOUT;
+ else
+ err = -psb->flags;
+
+ if (!err)
+ psb->perform_crypto = 1;
+ psb->flags = 0;
+
+ /*
+ * At this point NETFS_CAPABILITIES response command
+ * should setup superblock in a way, which is acceptible
+ * for both client and server, so if server refuses connection,
+ * it will send error in transaction response.
+ */
+
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+int pohmelfs_crypto_init(struct pohmelfs_sb *psb)
+{
+ int err;
+
+ if (!psb->cipher_string && !psb->hash_string)
+ return 0;
+
+ err = pohmelfs_crypto_init_handshake(psb);
+ if (err)
+ return err;
+
+ err = pohmelfs_sys_crypto_init(psb);
+ if (err)
+ return err;
+
+ return 0;
+}
+
+static int pohmelfs_crypto_thread_get(struct pohmelfs_sb *psb,
+ int (* action)(struct pohmelfs_crypto_thread *t, void *data), void *data)
+{
+ struct pohmelfs_crypto_thread *t = NULL;
+ int err;
+
+ while (!t) {
+ err = wait_event_interruptible_timeout(psb->wait,
+ !list_empty(&psb->crypto_ready_list),
+ psb->wait_on_page_timeout);
+
+ t = NULL;
+ err = 0;
+ mutex_lock(&psb->crypto_thread_lock);
+ if (!list_empty(&psb->crypto_ready_list)) {
+ t = list_entry(psb->crypto_ready_list.prev,
+ struct pohmelfs_crypto_thread,
+ thread_entry);
+
+ list_move_tail(&t->thread_entry,
+ &psb->crypto_active_list);
+
+ action(t, data);
+ wake_up(&t->wait);
+
+ }
+ mutex_unlock(&psb->crypto_thread_lock);
+ }
+
+ return err;
+}
+
+static int pohmelfs_trans_crypt_action(struct pohmelfs_crypto_thread *t, void *data)
+{
+ struct netfs_trans *trans = data;
+
+ netfs_trans_get(trans);
+ t->trans = trans;
+
+ dprintk("%s: t: %p, gen: %u, thread: %p.\n", __func__, trans, trans->gen, t);
+ return 0;
+}
+
+int pohmelfs_trans_crypt(struct netfs_trans *trans, struct pohmelfs_sb *psb)
+{
+ if ((!psb->hash_string && !psb->cipher_string) || !psb->perform_crypto) {
+ netfs_trans_get(trans);
+ return pohmelfs_crypto_finish(trans, psb, 0);
+ }
+
+ return pohmelfs_crypto_thread_get(psb, pohmelfs_trans_crypt_action, trans);
+}
+
+struct pohmelfs_crypto_input_action_data
+{
+ struct page *page;
+ struct pohmelfs_crypto_engine *e;
+ u64 iv;
+ unsigned int size;
+};
+
+static int pohmelfs_crypt_input_page_action(struct pohmelfs_crypto_thread *t, void *data)
+{
+ struct pohmelfs_crypto_input_action_data *act = data;
+
+ memcpy(t->eng.data, act->e->data, t->psb->crypto_attached_size);
+
+ t->size = act->size;
+ t->eng.iv = act->iv;
+
+ t->page = act->page;
+ return 0;
+}
+
+int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
+ struct page *page, unsigned int size, u64 iv)
+{
+ struct inode *inode = page->mapping->host;
+ struct pohmelfs_crypto_input_action_data act;
+ int err = -ENOENT;
+
+ act.page = page;
+ act.e = e;
+ act.size = size;
+ act.iv = iv;
+
+ err = pohmelfs_crypto_thread_get(POHMELFS_SB(inode->i_sb),
+ pohmelfs_crypt_input_page_action, &act);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ SetPageUptodate(page);
+ page_cache_release(page);
+
+ return err;
+}
diff --git a/drivers/staging/pohmelfs/dir.c b/drivers/staging/pohmelfs/dir.c
new file mode 100644
index 00000000000..7a41183a32e
--- /dev/null
+++ b/drivers/staging/pohmelfs/dir.c
@@ -0,0 +1,1093 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/namei.h>
+#include <linux/pagemap.h>
+
+#include "netfs.h"
+
+static int pohmelfs_cmp_hash(struct pohmelfs_name *n, u32 hash)
+{
+ if (n->hash > hash)
+ return -1;
+ if (n->hash < hash)
+ return 1;
+
+ return 0;
+}
+
+static struct pohmelfs_name *pohmelfs_search_hash_unprecise(struct pohmelfs_inode *pi, u32 hash)
+{
+ struct rb_node *n = pi->hash_root.rb_node;
+ struct pohmelfs_name *tmp = NULL;
+ int cmp;
+
+ while (n) {
+ tmp = rb_entry(n, struct pohmelfs_name, hash_node);
+
+ cmp = pohmelfs_cmp_hash(tmp, hash);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else
+ break;
+
+ }
+
+ return tmp;
+}
+
+struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash)
+{
+ struct pohmelfs_name *tmp;
+
+ tmp = pohmelfs_search_hash_unprecise(pi, hash);
+ if (tmp && (tmp->hash == hash))
+ return tmp;
+
+ return NULL;
+}
+
+static void __pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ rb_erase(&node->hash_node, &parent->hash_root);
+}
+
+/*
+ * Remove name cache entry from its caches and free it.
+ */
+static void pohmelfs_name_free(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ __pohmelfs_name_del(parent, node);
+ list_del(&node->sync_create_entry);
+ kfree(node);
+}
+
+static struct pohmelfs_name *pohmelfs_insert_hash(struct pohmelfs_inode *pi,
+ struct pohmelfs_name *new)
+{
+ struct rb_node **n = &pi->hash_root.rb_node, *parent = NULL;
+ struct pohmelfs_name *ret = NULL, *tmp;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ tmp = rb_entry(parent, struct pohmelfs_name, hash_node);
+
+ cmp = pohmelfs_cmp_hash(tmp, new->hash);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ if (ret) {
+ printk("%s: exist: parent: %llu, ino: %llu, hash: %x, len: %u, data: '%s', "
+ "new: ino: %llu, hash: %x, len: %u, data: '%s'.\n",
+ __func__, pi->ino,
+ ret->ino, ret->hash, ret->len, ret->data,
+ new->ino, new->hash, new->len, new->data);
+ ret->ino = new->ino;
+ return ret;
+ }
+
+ rb_link_node(&new->hash_node, parent, n);
+ rb_insert_color(&new->hash_node, &pi->hash_root);
+
+ return NULL;
+}
+
+/*
+ * Free name cache for given inode.
+ */
+void pohmelfs_free_names(struct pohmelfs_inode *parent)
+{
+ struct rb_node *rb_node;
+ struct pohmelfs_name *n;
+
+ for (rb_node = rb_first(&parent->hash_root); rb_node;) {
+ n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
+ rb_node = rb_next(rb_node);
+
+ pohmelfs_name_free(parent, n);
+ }
+}
+
+static void pohmelfs_fix_offset(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ parent->total_len -= node->len;
+}
+
+/*
+ * Free name cache entry helper.
+ */
+void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *node)
+{
+ pohmelfs_fix_offset(parent, node);
+ pohmelfs_name_free(parent, node);
+}
+
+/*
+ * Insert new name cache entry into all hash cache.
+ */
+static int pohmelfs_insert_name(struct pohmelfs_inode *parent, struct pohmelfs_name *n)
+{
+ struct pohmelfs_name *name;
+
+ name = pohmelfs_insert_hash(parent, n);
+ if (name)
+ return -EEXIST;
+
+ parent->total_len += n->len;
+ list_add_tail(&n->sync_create_entry, &parent->sync_create_list);
+
+ return 0;
+}
+
+/*
+ * Allocate new name cache entry.
+ */
+static struct pohmelfs_name *pohmelfs_name_alloc(unsigned int len)
+{
+ struct pohmelfs_name *n;
+
+ n = kzalloc(sizeof(struct pohmelfs_name) + len, GFP_KERNEL);
+ if (!n)
+ return NULL;
+
+ INIT_LIST_HEAD(&n->sync_create_entry);
+
+ n->data = (char *)(n+1);
+
+ return n;
+}
+
+/*
+ * Add new name entry into directory's cache.
+ */
+static int pohmelfs_add_dir(struct pohmelfs_sb *psb, struct pohmelfs_inode *parent,
+ struct pohmelfs_inode *npi, struct qstr *str, unsigned int mode, int link)
+{
+ int err = -ENOMEM;
+ struct pohmelfs_name *n;
+
+ n = pohmelfs_name_alloc(str->len + 1);
+ if (!n)
+ goto err_out_exit;
+
+ n->ino = npi->ino;
+ n->mode = mode;
+ n->len = str->len;
+ n->hash = str->hash;
+ sprintf(n->data, "%s", str->name);
+
+ mutex_lock(&parent->offset_lock);
+ err = pohmelfs_insert_name(parent, n);
+ mutex_unlock(&parent->offset_lock);
+
+ if (err) {
+ if (err != -EEXIST)
+ goto err_out_free;
+ kfree(n);
+ }
+
+ return 0;
+
+err_out_free:
+ kfree(n);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Create new inode for given parameters (name, inode info, parent).
+ * This does not create object on the server, it will be synced there during writeback.
+ */
+struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str,
+ struct netfs_inode_info *info, int link)
+{
+ struct inode *new = NULL;
+ struct pohmelfs_inode *npi;
+ int err = -EEXIST;
+
+ dprintk("%s: creating inode: parent: %llu, ino: %llu, str: %p.\n",
+ __func__, (parent)?parent->ino:0, info->ino, str);
+
+ err = -ENOMEM;
+ new = iget_locked(psb->sb, info->ino);
+ if (!new)
+ goto err_out_exit;
+
+ npi = POHMELFS_I(new);
+ npi->ino = info->ino;
+ err = 0;
+
+ if (new->i_state & I_NEW) {
+ dprintk("%s: filling VFS inode: %lu/%llu.\n",
+ __func__, new->i_ino, info->ino);
+ pohmelfs_fill_inode(new, info);
+
+ if (S_ISDIR(info->mode)) {
+ struct qstr s;
+
+ s.name = ".";
+ s.len = 1;
+ s.hash = jhash(s.name, s.len, 0);
+
+ err = pohmelfs_add_dir(psb, npi, npi, &s, info->mode, 0);
+ if (err)
+ goto err_out_put;
+
+ s.name = "..";
+ s.len = 2;
+ s.hash = jhash(s.name, s.len, 0);
+
+ err = pohmelfs_add_dir(psb, npi, (parent)?parent:npi, &s,
+ (parent)?parent->vfs_inode.i_mode:npi->vfs_inode.i_mode, 0);
+ if (err)
+ goto err_out_put;
+ }
+ }
+
+ if (str) {
+ if (parent) {
+ err = pohmelfs_add_dir(psb, parent, npi, str, info->mode, link);
+
+ dprintk("%s: %s inserted name: '%s', new_offset: %llu, ino: %llu, parent: %llu.\n",
+ __func__, (err)?"unsuccessfully":"successfully",
+ str->name, parent->total_len, info->ino, parent->ino);
+
+ if (err && err != -EEXIST)
+ goto err_out_put;
+ }
+ }
+
+ if (new->i_state & I_NEW) {
+ if (parent)
+ mark_inode_dirty(&parent->vfs_inode);
+ mark_inode_dirty(new);
+ }
+
+ set_bit(NETFS_INODE_OWNED, &npi->state);
+ npi->lock_type = POHMELFS_WRITE_LOCK;
+ unlock_new_inode(new);
+
+ return npi;
+
+err_out_put:
+ printk("%s: putting inode: %p, npi: %p, error: %d.\n", __func__, new, npi, err);
+ iput(new);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+static int pohmelfs_remote_sync_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct pohmelfs_inode *pi = private;
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+ dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
+
+ if (err)
+ pi->error = err;
+ wake_up(&psb->wait);
+ pohmelfs_put_inode(pi);
+
+ return err;
+}
+
+/*
+ * Receive directory content from the server.
+ * This should be only done for objects, which were not created locally,
+ * and which were not synced previously.
+ */
+static int pohmelfs_sync_remote_dir(struct pohmelfs_inode *pi)
+{
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ long ret = msecs_to_jiffies(25000);
+ int err;
+
+ dprintk("%s: dir: %llu, state: %lx: remote_synced: %d.\n",
+ __func__, pi->ino, pi->state, test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state));
+
+ if (test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state))
+ return 0;
+
+ if (!igrab(inode)) {
+ err = -ENOENT;
+ goto err_out_exit;
+ }
+
+ err = pohmelfs_meta_command(pi, NETFS_READDIR, NETFS_TRANS_SINGLE_DST,
+ pohmelfs_remote_sync_complete, pi, 0);
+ if (err)
+ goto err_out_exit;
+
+ pi->error = 0;
+ ret = wait_event_interruptible_timeout(psb->wait,
+ test_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state) || pi->error, ret);
+ dprintk("%s: awake dir: %llu, ret: %ld, err: %d.\n", __func__, pi->ino, ret, pi->error);
+ if (ret <= 0) {
+ err = -ETIMEDOUT;
+ goto err_out_exit;
+ }
+
+ if (pi->error)
+ return pi->error;
+
+ return 0;
+
+err_out_exit:
+ clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+ return err;
+}
+
+static int pohmelfs_dir_open(struct inode *inode, struct file *file)
+{
+ file->private_data = NULL;
+ return 0;
+}
+
+/*
+ * VFS readdir callback. Syncs directory content from server if needed,
+ * and provides direntry info to the userspace.
+ */
+static int pohmelfs_readdir(struct file *file, void *dirent, filldir_t filldir)
+{
+ struct inode *inode = file->f_path.dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_name *n;
+ struct rb_node *rb_node;
+ int err = 0, mode;
+ u64 len;
+
+ dprintk("%s: parent: %llu, fpos: %llu, hash: %08lx.\n",
+ __func__, pi->ino, (u64)file->f_pos,
+ (unsigned long)file->private_data);
+
+ err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
+ if (err)
+ return err;
+
+ err = pohmelfs_sync_remote_dir(pi);
+ if (err)
+ return err;
+
+ if (file->private_data && (file->private_data == (void *)(unsigned long)file->f_pos))
+ return 0;
+
+ mutex_lock(&pi->offset_lock);
+ n = pohmelfs_search_hash_unprecise(pi, (unsigned long)file->private_data);
+
+ while (n) {
+ mode = (n->mode >> 12) & 15;
+
+ dprintk("%s: offset: %llu, parent ino: %llu, name: '%s', len: %u, ino: %llu, "
+ "mode: %o/%o, fpos: %llu, hash: %08x.\n",
+ __func__, file->f_pos, pi->ino, n->data, n->len,
+ n->ino, n->mode, mode, file->f_pos, n->hash);
+
+ file->private_data = (void *)n->hash;
+
+ len = n->len;
+ err = filldir(dirent, n->data, n->len, file->f_pos, n->ino, mode);
+
+ if (err < 0) {
+ dprintk("%s: err: %d.\n", __func__, err);
+ err = 0;
+ break;
+ }
+
+ file->f_pos += len;
+
+ rb_node = rb_next(&n->hash_node);
+
+ if (!rb_node || (rb_node == &n->hash_node)) {
+ file->private_data = (void *)(unsigned long)file->f_pos;
+ break;
+ }
+
+ n = rb_entry(rb_node, struct pohmelfs_name, hash_node);
+ }
+ mutex_unlock(&pi->offset_lock);
+
+ return err;
+}
+
+static loff_t pohmelfs_dir_lseek(struct file *file, loff_t offset, int origin)
+{
+ file->f_pos = offset;
+ file->private_data = NULL;
+ return offset;
+}
+
+const struct file_operations pohmelfs_dir_fops = {
+ .open = pohmelfs_dir_open,
+ .read = generic_read_dir,
+ .llseek = pohmelfs_dir_lseek,
+ .readdir = pohmelfs_readdir,
+};
+
+/*
+ * Lookup single object on server.
+ */
+static int pohmelfs_lookup_single(struct pohmelfs_inode *parent,
+ struct qstr *str, u64 ino)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(parent->vfs_inode.i_sb);
+ long ret = msecs_to_jiffies(5000);
+ int err;
+
+ set_bit(NETFS_COMMAND_PENDING, &parent->state);
+ err = pohmelfs_meta_command_data(parent, parent->ino, NETFS_LOOKUP,
+ (char *)str->name, NETFS_TRANS_SINGLE_DST, NULL, NULL, ino);
+ if (err)
+ goto err_out_exit;
+
+ err = 0;
+ ret = wait_event_interruptible_timeout(psb->wait,
+ !test_bit(NETFS_COMMAND_PENDING, &parent->state), ret);
+ if (ret == 0)
+ err = -ETIMEDOUT;
+ else if (signal_pending(current))
+ err = -EINTR;
+
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+
+ printk("%s: failed: parent: %llu, ino: %llu, name: '%s', err: %d.\n",
+ __func__, parent->ino, ino, str->name, err);
+
+ return err;
+}
+
+/*
+ * VFS lookup callback.
+ * We first try to get inode number from local name cache, if we have one,
+ * then inode can be found in inode cache. If there is no inode or no object in
+ * local cache, try to lookup it on server. This only should be done for directories,
+ * which were not created locally, otherwise remote server does not know about dir at all,
+ * so no need to try to know that.
+ */
+struct dentry *pohmelfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
+{
+ struct pohmelfs_inode *parent = POHMELFS_I(dir);
+ struct pohmelfs_name *n;
+ struct inode *inode = NULL;
+ unsigned long ino = 0;
+ int err, lock_type = POHMELFS_READ_LOCK, need_lock;
+ struct qstr str = dentry->d_name;
+
+ if ((nd->intent.open.flags & O_ACCMODE) > 1)
+ lock_type = POHMELFS_WRITE_LOCK;
+
+ need_lock = pohmelfs_need_lock(parent, lock_type);
+
+ err = pohmelfs_data_lock(parent, 0, ~0, lock_type);
+ if (err)
+ goto out;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str.hash);
+ if (n)
+ ino = n->ino;
+ mutex_unlock(&parent->offset_lock);
+
+ dprintk("%s: 1 ino: %lu, inode: %p, name: '%s', hash: %x, parent_state: %lx.\n",
+ __func__, ino, inode, str.name, str.hash, parent->state);
+
+ if (ino) {
+ inode = ilookup(dir->i_sb, ino);
+ if (inode)
+ goto out;
+ }
+
+ dprintk("%s: dir: %p, dir_ino: %llu, name: '%s', len: %u, dir_state: %lx, ino: %lu.\n",
+ __func__, dir, parent->ino,
+ str.name, str.len, parent->state, ino);
+
+ if (!ino) {
+ if (!need_lock)
+ goto out;
+ }
+
+ err = pohmelfs_lookup_single(parent, &str, ino);
+ if (err)
+ goto out;
+
+ if (!ino) {
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str.hash);
+ if (n)
+ ino = n->ino;
+ mutex_unlock(&parent->offset_lock);
+ }
+
+ if (ino) {
+ inode = ilookup(dir->i_sb, ino);
+ printk("%s: second lookup ino: %lu, inode: %p, name: '%s', hash: %x.\n",
+ __func__, ino, inode, str.name, str.hash);
+ if (!inode) {
+ printk("%s: No inode for ino: %lu, name: '%s', hash: %x.\n",
+ __func__, ino, str.name, str.hash);
+ //return NULL;
+ return ERR_PTR(-EACCES);
+ }
+ } else {
+ printk("%s: No inode number : name: '%s', hash: %x.\n",
+ __func__, str.name, str.hash);
+ }
+out:
+ return d_splice_alias(inode, dentry);
+}
+
+/*
+ * Create new object in local cache. Object will be synced to server
+ * during writeback for given inode.
+ */
+struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str, u64 start, int mode)
+{
+ struct pohmelfs_inode *npi;
+ int err = -ENOMEM;
+ struct netfs_inode_info info;
+
+ dprintk("%s: name: '%s', mode: %o, start: %llu.\n",
+ __func__, str->name, mode, start);
+
+ info.mode = mode;
+ info.ino = start;
+
+ if (!start)
+ info.ino = pohmelfs_new_ino(psb);
+
+ info.nlink = S_ISDIR(mode)?2:1;
+ info.uid = current_fsuid();
+ info.gid = current_fsgid();
+ info.size = 0;
+ info.blocksize = 512;
+ info.blocks = 0;
+ info.rdev = 0;
+ info.version = 0;
+
+ npi = pohmelfs_new_inode(psb, parent, str, &info, !!start);
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+ goto err_out_unlock;
+ }
+
+ return npi;
+
+err_out_unlock:
+ dprintk("%s: err: %d.\n", __func__, err);
+ return ERR_PTR(err);
+}
+
+/*
+ * Create local object and bind it to dentry.
+ */
+static int pohmelfs_create_entry(struct inode *dir, struct dentry *dentry, u64 start, int mode)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
+ struct pohmelfs_inode *npi, *parent;
+ struct qstr str = dentry->d_name;
+ int err;
+
+ parent = POHMELFS_I(dir);
+
+ err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ return err;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ npi = pohmelfs_create_entry_local(psb, parent, &str, start, mode);
+ if (IS_ERR(npi))
+ return PTR_ERR(npi);
+
+ d_instantiate(dentry, &npi->vfs_inode);
+
+ dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
+ __func__, parent->ino, npi->ino, dentry->d_name.name,
+ (signed)dir->i_nlink, (signed)npi->vfs_inode.i_nlink);
+
+ return 0;
+}
+
+/*
+ * VFS create and mkdir callbacks.
+ */
+static int pohmelfs_create(struct inode *dir, struct dentry *dentry, int mode,
+ struct nameidata *nd)
+{
+ return pohmelfs_create_entry(dir, dentry, 0, mode);
+}
+
+static int pohmelfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+{
+ int err;
+
+ inode_inc_link_count(dir);
+ err = pohmelfs_create_entry(dir, dentry, 0, mode | S_IFDIR);
+ if (err)
+ inode_dec_link_count(dir);
+
+ return err;
+}
+
+static int pohmelfs_remove_entry(struct inode *dir, struct dentry *dentry)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(dir->i_sb);
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *parent = POHMELFS_I(dir), *pi = POHMELFS_I(inode);
+ struct pohmelfs_name *n;
+ int err = -ENOENT;
+ struct qstr str = dentry->d_name;
+
+ err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ return err;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ dprintk("%s: dir_ino: %llu, inode: %llu, name: '%s', nlink: %d.\n",
+ __func__, parent->ino, pi->ino,
+ str.name, (signed)inode->i_nlink);
+
+ BUG_ON(!inode);
+
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str.hash);
+ if (n) {
+ pohmelfs_fix_offset(parent, n);
+ if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state)) {
+ pohmelfs_remove_child(pi, n);
+ }
+ pohmelfs_name_free(parent, n);
+ err = 0;
+ }
+ mutex_unlock(&parent->offset_lock);
+
+ if (!err) {
+ psb->avail_size += inode->i_size;
+
+ pohmelfs_inode_del_inode(psb, pi);
+
+ mark_inode_dirty(dir);
+
+ inode->i_ctime = dir->i_ctime;
+ if (inode->i_nlink)
+ inode_dec_link_count(inode);
+ }
+ dprintk("%s: inode: %p, lock: %ld, unhashed: %d.\n",
+ __func__, pi, inode->i_state & I_LOCK, hlist_unhashed(&inode->i_hash));
+
+ return err;
+}
+
+/*
+ * Unlink and rmdir VFS callbacks.
+ */
+static int pohmelfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+ return pohmelfs_remove_entry(dir, dentry);
+}
+
+static int pohmelfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+ int err;
+ struct inode *inode = dentry->d_inode;
+
+ dprintk("%s: parent: %llu, inode: %llu, name: '%s', parent_nlink: %d, nlink: %d.\n",
+ __func__, POHMELFS_I(dir)->ino, POHMELFS_I(inode)->ino,
+ dentry->d_name.name, (signed)dir->i_nlink, (signed)inode->i_nlink);
+
+ err = pohmelfs_remove_entry(dir, dentry);
+ if (!err) {
+ inode_dec_link_count(dir);
+ inode_dec_link_count(inode);
+ }
+
+ return err;
+}
+
+/*
+ * Link creation is synchronous.
+ * I'm lazy.
+ * Earth is somewhat round.
+ */
+static int pohmelfs_create_link(struct pohmelfs_inode *parent, struct qstr *obj,
+ struct pohmelfs_inode *target, struct qstr *tstr)
+{
+ struct super_block *sb = parent->vfs_inode.i_sb;
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+ struct netfs_cmd *cmd;
+ struct netfs_trans *t;
+ void *data;
+ int err, parent_len, target_len = 0, cur_len, path_size = 0;
+
+ err = pohmelfs_data_lock(parent, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ return err;
+
+ err = sb->s_op->write_inode(&parent->vfs_inode, 0);
+ if (err)
+ goto err_out_exit;
+
+ if (tstr)
+ target_len = tstr->len;
+
+ parent_len = pohmelfs_path_length(parent);
+ if (target)
+ target_len += pohmelfs_path_length(target);
+
+ if (parent_len < 0) {
+ err = parent_len;
+ goto err_out_exit;
+ }
+
+ if (target_len < 0) {
+ err = target_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, parent_len + target_len + obj->len + 2, 0, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+ cur_len = netfs_trans_cur_len(t);
+
+ cmd = netfs_trans_current(t);
+ if (IS_ERR(cmd)) {
+ err = PTR_ERR(cmd);
+ goto err_out_free;
+ }
+
+ data = (void *)(cmd + 1);
+ cur_len -= sizeof(struct netfs_cmd);
+
+ err = pohmelfs_construct_path_string(parent, data, parent_len);
+ if (err > 0) {
+ /* Do not place null-byte before the slash */
+ path_size = err - 1;
+ cur_len -= path_size;
+
+ err = snprintf(data + path_size, cur_len, "/%s|", obj->name);
+
+ path_size += err;
+ cur_len -= err;
+
+ cmd->ext = path_size - 1; /* No | symbol */
+
+ if (target) {
+ err = pohmelfs_construct_path_string(target, data + path_size, target_len);
+ if (err > 0) {
+ path_size += err;
+ cur_len -= err;
+ }
+ }
+ }
+
+ if (err < 0)
+ goto err_out_free;
+
+ cmd->start = 0;
+
+ if (!target && tstr) {
+ if (tstr->len > cur_len - 1) {
+ err = -ENAMETOOLONG;
+ goto err_out_free;
+ }
+
+ err = snprintf(data + path_size, cur_len, "%s", tstr->name) + 1; /* 0-byte */
+ path_size += err;
+ cur_len -= err;
+ cmd->start = 1;
+ }
+
+ dprintk("%s: parent: %llu, obj: '%s', target_inode: %llu, target_str: '%s', full: '%s'.\n",
+ __func__, parent->ino, obj->name, (target)?target->ino:0, (tstr)?tstr->name:NULL,
+ (char *)data);
+
+ cmd->cmd = NETFS_LINK;
+ cmd->size = path_size;
+ cmd->id = parent->ino;
+
+ netfs_convert_cmd(cmd);
+
+ netfs_trans_update(cmd, t, path_size);
+
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_free:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ return err;
+}
+
+/*
+ * VFS hard and soft link callbacks.
+ */
+static int pohmelfs_link(struct dentry *old_dentry, struct inode *dir,
+ struct dentry *dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err;
+ struct qstr str = dentry->d_name;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ err = inode->i_sb->s_op->write_inode(inode, 0);
+ if (err)
+ return err;
+
+ err = pohmelfs_create_link(POHMELFS_I(dir), &str, pi, NULL);
+ if (err)
+ return err;
+
+ return pohmelfs_create_entry(dir, dentry, pi->ino, inode->i_mode);
+}
+
+static int pohmelfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
+{
+ struct qstr sym_str;
+ struct qstr str = dentry->d_name;
+ struct inode *inode;
+ int err;
+
+ str.hash = jhash(dentry->d_name.name, dentry->d_name.len, 0);
+
+ sym_str.name = symname;
+ sym_str.len = strlen(symname);
+
+ err = pohmelfs_create_link(POHMELFS_I(dir), &str, NULL, &sym_str);
+ if (err)
+ goto err_out_exit;
+
+ err = pohmelfs_create_entry(dir, dentry, 0, S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO);
+ if (err)
+ goto err_out_exit;
+
+ inode = dentry->d_inode;
+
+ err = page_symlink(inode, symname, sym_str.len + 1);
+ if (err)
+ goto err_out_put;
+
+ return 0;
+
+err_out_put:
+ iput(inode);
+err_out_exit:
+ return err;
+}
+
+static int pohmelfs_send_rename(struct pohmelfs_inode *pi, struct pohmelfs_inode *parent,
+ struct qstr *str)
+{
+ int path_len, err, total_len = 0, inode_len, parent_len;
+ char *path;
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+ parent_len = pohmelfs_path_length(parent);
+ inode_len = pohmelfs_path_length(pi);
+
+ if (parent_len < 0 || inode_len < 0)
+ return -EINVAL;
+
+ path_len = parent_len + inode_len + str->len + 3;
+
+ t = netfs_trans_alloc(psb, path_len, 0, 0);
+ if (!t)
+ return -ENOMEM;
+
+ cmd = netfs_trans_current(t);
+ path = (char *)(cmd + 1);
+
+ err = pohmelfs_construct_path_string(pi, path, inode_len);
+ if (err < 0)
+ goto err_out_unlock;
+
+ cmd->ext = err;
+
+ path += err;
+ total_len += err;
+ path_len -= err;
+
+ *path = '|';
+ path++;
+ total_len++;
+ path_len--;
+
+ err = pohmelfs_construct_path_string(parent, path, parent_len);
+ if (err < 0)
+ goto err_out_unlock;
+
+ /*
+ * Do not place a null-byte before the final slash and the name.
+ */
+ err--;
+ path += err;
+ total_len += err;
+ path_len -= err;
+
+ err = snprintf(path, path_len - 1, "/%s", str->name);
+
+ total_len += err + 1; /* 0 symbol */
+ path_len -= err + 1;
+
+ cmd->cmd = NETFS_RENAME;
+ cmd->id = pi->ino;
+ cmd->start = parent->ino;
+ cmd->size = total_len;
+
+ netfs_convert_cmd(cmd);
+
+ netfs_trans_update(cmd, t, total_len);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_unlock:
+ netfs_trans_free(t);
+ return err;
+}
+
+static int pohmelfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+ struct inode *new_dir, struct dentry *new_dentry)
+{
+ struct inode *inode = old_dentry->d_inode;
+ struct pohmelfs_inode *old_parent, *pi, *new_parent;
+ struct qstr str = new_dentry->d_name;
+ struct pohmelfs_name *n;
+ unsigned int old_hash;
+ int err = -ENOENT;
+
+ pi = POHMELFS_I(inode);
+ old_parent = POHMELFS_I(old_dir);
+
+ if (new_dir) {
+ new_dir->i_sb->s_op->write_inode(new_dir, 0);
+ }
+
+ old_hash = jhash(old_dentry->d_name.name, old_dentry->d_name.len, 0);
+ str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
+
+ str.len = new_dentry->d_name.len;
+ str.name = new_dentry->d_name.name;
+ str.hash = jhash(new_dentry->d_name.name, new_dentry->d_name.len, 0);
+
+ if (new_dir) {
+ new_parent = POHMELFS_I(new_dir);
+ err = -ENOTEMPTY;
+
+ if (S_ISDIR(inode->i_mode) &&
+ new_parent->total_len <= 3)
+ goto err_out_exit;
+ } else {
+ new_parent = old_parent;
+ }
+
+ dprintk("%s: ino: %llu, parent: %llu, name: '%s' -> parent: %llu, name: '%s', i_size: %llu.\n",
+ __func__, pi->ino, old_parent->ino, old_dentry->d_name.name,
+ new_parent->ino, new_dentry->d_name.name, inode->i_size);
+
+ if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state) &&
+ test_bit(NETFS_INODE_OWNED, &pi->state)) {
+ err = pohmelfs_send_rename(pi, new_parent, &str);
+ if (err)
+ goto err_out_exit;
+ }
+
+ n = pohmelfs_name_alloc(str.len + 1);
+ if (!n)
+ goto err_out_exit;
+
+ mutex_lock(&new_parent->offset_lock);
+ n->ino = pi->ino;
+ n->mode = inode->i_mode;
+ n->len = str.len;
+ n->hash = str.hash;
+ sprintf(n->data, "%s", str.name);
+
+ err = pohmelfs_insert_name(new_parent, n);
+ mutex_unlock(&new_parent->offset_lock);
+
+ if (err)
+ goto err_out_exit;
+
+ mutex_lock(&old_parent->offset_lock);
+ n = pohmelfs_search_hash(old_parent, old_hash);
+ if (n)
+ pohmelfs_name_del(old_parent, n);
+ mutex_unlock(&old_parent->offset_lock);
+
+ mark_inode_dirty(inode);
+ mark_inode_dirty(&new_parent->vfs_inode);
+
+ WARN_ON_ONCE(list_empty(&inode->i_dentry));
+
+ return 0;
+
+err_out_exit:
+
+ clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+ mutex_unlock(&inode->i_mutex);
+ return err;
+}
+
+/*
+ * POHMELFS directory inode operations.
+ */
+const struct inode_operations pohmelfs_dir_inode_ops = {
+ .link = pohmelfs_link,
+ .symlink = pohmelfs_symlink,
+ .unlink = pohmelfs_unlink,
+ .mkdir = pohmelfs_mkdir,
+ .rmdir = pohmelfs_rmdir,
+ .create = pohmelfs_create,
+ .lookup = pohmelfs_lookup,
+ .setattr = pohmelfs_setattr,
+ .rename = pohmelfs_rename,
+};
diff --git a/drivers/staging/pohmelfs/inode.c b/drivers/staging/pohmelfs/inode.c
new file mode 100644
index 00000000000..5bf16504cd6
--- /dev/null
+++ b/drivers/staging/pohmelfs/inode.c
@@ -0,0 +1,1976 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/backing-dev.h>
+#include <linux/crypto.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/hash.h>
+#include <linux/ktime.h>
+#include <linux/mm.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/pagevec.h>
+#include <linux/parser.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/writeback.h>
+#include <linux/quotaops.h>
+
+#include "netfs.h"
+
+#define POHMELFS_MAGIC_NUM 0x504f482e
+
+static struct kmem_cache *pohmelfs_inode_cache;
+
+/*
+ * Removes inode from all trees, drops local name cache and removes all queued
+ * requests for object removal.
+ */
+void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi)
+{
+ mutex_lock(&pi->offset_lock);
+ pohmelfs_free_names(pi);
+ mutex_unlock(&pi->offset_lock);
+
+ dprintk("%s: deleted stuff in ino: %llu.\n", __func__, pi->ino);
+}
+
+/*
+ * Sync inode to server.
+ * Returns zero in success and negative error value otherwise.
+ * It will gather path to root directory into structures containing
+ * creation mode, permissions and names, so that the whole path
+ * to given inode could be created using only single network command.
+ */
+int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans)
+{
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err = -ENOMEM, size;
+ struct netfs_cmd *cmd;
+ void *data;
+ int cur_len = netfs_trans_cur_len(trans);
+
+ if (unlikely(cur_len < 0))
+ return -ETOOSMALL;
+
+ cmd = netfs_trans_current(trans);
+ cur_len -= sizeof(struct netfs_cmd);
+
+ data = (void *)(cmd + 1);
+
+ err = pohmelfs_construct_path_string(pi, data, cur_len);
+ if (err < 0)
+ goto err_out_exit;
+
+ size = err;
+
+ cmd->start = i_size_read(inode);
+ cmd->cmd = NETFS_CREATE;
+ cmd->size = size;
+ cmd->id = pi->ino;
+ cmd->ext = inode->i_mode;
+
+ netfs_convert_cmd(cmd);
+
+ netfs_trans_update(cmd, trans, size);
+
+ return 0;
+
+err_out_exit:
+ printk("%s: completed ino: %llu, err: %d.\n", __func__, pi->ino, err);
+ return err;
+}
+
+static int pohmelfs_write_trans_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ unsigned i;
+
+ dprintk("%s: pages: %lu-%lu, page_num: %u, err: %d.\n",
+ __func__, pages[0]->index, pages[page_num-1]->index,
+ page_num, err);
+
+ for (i = 0; i < page_num; i++) {
+ struct page *page = pages[i];
+
+ if (!page)
+ continue;
+
+ end_page_writeback(page);
+
+ if (err < 0) {
+ SetPageError(page);
+ set_page_dirty(page);
+ }
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ /* dprintk("%s: %3u/%u: page: %p.\n", __func__, i, page_num, page); */
+ }
+ return err;
+}
+
+static int pohmelfs_inode_has_dirty_pages(struct address_space *mapping, pgoff_t index)
+{
+ int ret;
+ struct page *page;
+
+ rcu_read_lock();
+ ret = radix_tree_gang_lookup_tag(&mapping->page_tree,
+ (void **)&page, index, 1, PAGECACHE_TAG_DIRTY);
+ rcu_read_unlock();
+ return ret;
+}
+
+static int pohmelfs_writepages(struct address_space *mapping, struct writeback_control *wbc)
+{
+ struct inode *inode = mapping->host;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct backing_dev_info *bdi = mapping->backing_dev_info;
+ int err = 0;
+ int done = 0;
+ int nr_pages;
+ pgoff_t index;
+ pgoff_t end; /* Inclusive */
+ int scanned = 0;
+ int range_whole = 0;
+
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ wbc->encountered_congestion = 1;
+ return 0;
+ }
+
+ if (wbc->range_cyclic) {
+ index = mapping->writeback_index; /* Start from prev offset */
+ end = -1;
+ } else {
+ index = wbc->range_start >> PAGE_CACHE_SHIFT;
+ end = wbc->range_end >> PAGE_CACHE_SHIFT;
+ if (wbc->range_start == 0 && wbc->range_end == LLONG_MAX)
+ range_whole = 1;
+ scanned = 1;
+ }
+retry:
+ while (!done && (index <= end)) {
+ unsigned int i = min(end - index, (pgoff_t)psb->trans_max_pages);
+ int path_len;
+ struct netfs_trans *trans;
+
+ err = pohmelfs_inode_has_dirty_pages(mapping, index);
+ if (!err)
+ break;
+
+ err = pohmelfs_path_length(pi);
+ if (err < 0)
+ break;
+
+ path_len = err;
+
+ if (path_len <= 2) {
+ err = -ENOENT;
+ break;
+ }
+
+ trans = netfs_trans_alloc(psb, path_len, 0, i);
+ if (!trans) {
+ err = -ENOMEM;
+ break;
+ }
+ trans->complete = &pohmelfs_write_trans_complete;
+
+ trans->page_num = nr_pages = find_get_pages_tag(mapping, &index,
+ PAGECACHE_TAG_DIRTY, trans->page_num,
+ trans->pages);
+
+ dprintk("%s: t: %p, nr_pages: %u, end: %lu, index: %lu, max: %u.\n",
+ __func__, trans, nr_pages, end, index, trans->page_num);
+
+ if (!nr_pages)
+ goto err_out_reset;
+
+ err = pohmelfs_write_inode_create(inode, trans);
+ if (err)
+ goto err_out_reset;
+
+ err = 0;
+ scanned = 1;
+
+ for (i = 0; i < trans->page_num; i++) {
+ struct page *page = trans->pages[i];
+
+ lock_page(page);
+
+ if (unlikely(page->mapping != mapping))
+ goto out_continue;
+
+ if (!wbc->range_cyclic && page->index > end) {
+ done = 1;
+ goto out_continue;
+ }
+
+ if (wbc->sync_mode != WB_SYNC_NONE)
+ wait_on_page_writeback(page);
+
+ if (PageWriteback(page) ||
+ !clear_page_dirty_for_io(page)) {
+ dprintk("%s: not clear for io page: %p, writeback: %d.\n",
+ __func__, page, PageWriteback(page));
+ goto out_continue;
+ }
+
+ set_page_writeback(page);
+
+ trans->attached_size += page_private(page);
+ trans->attached_pages++;
+#if 0
+ dprintk("%s: %u/%u added trans: %p, gen: %u, page: %p, [High: %d], size: %lu, idx: %lu.\n",
+ __func__, i, trans->page_num, trans, trans->gen, page,
+ !!PageHighMem(page), page_private(page), page->index);
+#endif
+ wbc->nr_to_write--;
+
+ if (wbc->nr_to_write <= 0)
+ done = 1;
+ if (wbc->nonblocking && bdi_write_congested(bdi)) {
+ wbc->encountered_congestion = 1;
+ done = 1;
+ }
+
+ continue;
+out_continue:
+ unlock_page(page);
+ trans->pages[i] = NULL;
+ }
+
+ err = netfs_trans_finish(trans, psb);
+ if (err)
+ break;
+
+ continue;
+
+err_out_reset:
+ trans->result = err;
+ netfs_trans_reset(trans);
+ netfs_trans_put(trans);
+ break;
+ }
+
+ if (!scanned && !done) {
+ /*
+ * We hit the last page and there is more work to be done: wrap
+ * back to the start of the file
+ */
+ scanned = 1;
+ index = 0;
+ goto retry;
+ }
+
+ if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
+ mapping->writeback_index = index;
+
+ return err;
+}
+
+/*
+ * Inode writeback creation completion callback.
+ * Only invoked for just created inodes, which do not have pages attached,
+ * like dirs and empty files.
+ */
+static int pohmelfs_write_inode_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct inode *inode = private;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ if (inode) {
+ if (err) {
+ mark_inode_dirty(inode);
+ clear_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+ } else {
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+ }
+
+ pohmelfs_put_inode(pi);
+ }
+
+ return err;
+}
+
+int pohmelfs_write_create_inode(struct pohmelfs_inode *pi)
+{
+ struct netfs_trans *t;
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ int err;
+
+ if (test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
+ return 0;
+
+ dprintk("%s: started ino: %llu.\n", __func__, pi->ino);
+
+ err = pohmelfs_path_length(pi);
+ if (err < 0)
+ goto err_out_exit;
+
+ t = netfs_trans_alloc(psb, err + 1, 0, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_put;
+ }
+ t->complete = pohmelfs_write_inode_complete;
+ t->private = igrab(inode);
+ if (!t->private) {
+ err = -ENOENT;
+ goto err_out_put;
+ }
+
+ err = pohmelfs_write_inode_create(inode, t);
+ if (err)
+ goto err_out_put;
+
+ netfs_trans_finish(t, POHMELFS_SB(inode->i_sb));
+
+ return 0;
+
+err_out_put:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ return err;
+}
+
+/*
+ * Sync all not-yet-created children in given directory to the server.
+ */
+static int pohmelfs_write_inode_create_children(struct inode *inode)
+{
+ struct pohmelfs_inode *parent = POHMELFS_I(inode);
+ struct super_block *sb = inode->i_sb;
+ struct pohmelfs_name *n;
+
+ while (!list_empty(&parent->sync_create_list)) {
+ n = NULL;
+ mutex_lock(&parent->offset_lock);
+ if (!list_empty(&parent->sync_create_list)) {
+ n = list_first_entry(&parent->sync_create_list,
+ struct pohmelfs_name, sync_create_entry);
+ list_del_init(&n->sync_create_entry);
+ }
+ mutex_unlock(&parent->offset_lock);
+
+ if (!n)
+ break;
+
+ inode = ilookup(sb, n->ino);
+
+ dprintk("%s: parent: %llu, ino: %llu, inode: %p.\n",
+ __func__, parent->ino, n->ino, inode);
+
+ if (inode && (inode->i_state & I_DIRTY)) {
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ pohmelfs_write_create_inode(pi);
+ //pohmelfs_meta_command(pi, NETFS_INODE_INFO, 0, NULL, NULL, 0);
+ iput(inode);
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Removes given child from given inode on server.
+ */
+int pohmelfs_remove_child(struct pohmelfs_inode *pi, struct pohmelfs_name *n)
+{
+ return pohmelfs_meta_command_data(pi, pi->ino, NETFS_REMOVE, NULL, 0, NULL, NULL, 0);
+}
+
+/*
+ * Writeback for given inode.
+ */
+static int pohmelfs_write_inode(struct inode *inode, int sync)
+{
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ pohmelfs_write_create_inode(pi);
+ pohmelfs_write_inode_create_children(inode);
+
+ return 0;
+}
+
+/*
+ * It is not exported, sorry...
+ */
+static inline wait_queue_head_t *page_waitqueue(struct page *page)
+{
+ const struct zone *zone = page_zone(page);
+
+ return &zone->wait_table[hash_ptr(page, zone->wait_table_bits)];
+}
+
+static int pohmelfs_wait_on_page_locked(struct page *page)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(page->mapping->host->i_sb);
+ long ret = psb->wait_on_page_timeout;
+ DEFINE_WAIT_BIT(wait, &page->flags, PG_locked);
+ int err = 0;
+
+ if (!PageLocked(page))
+ return 0;
+
+ for (;;) {
+ prepare_to_wait(page_waitqueue(page),
+ &wait.wait, TASK_INTERRUPTIBLE);
+
+ dprintk("%s: page: %p, locked: %d, uptodate: %d, error: %d, flags: %lx.\n",
+ __func__, page, PageLocked(page), PageUptodate(page),
+ PageError(page), page->flags);
+
+ if (!PageLocked(page))
+ break;
+
+ if (!signal_pending(current)) {
+ ret = schedule_timeout(ret);
+ if (!ret)
+ break;
+ continue;
+ }
+ ret = -ERESTARTSYS;
+ break;
+ }
+ finish_wait(page_waitqueue(page), &wait.wait);
+
+ if (!ret)
+ err = -ETIMEDOUT;
+
+
+ if (!err)
+ SetPageUptodate(page);
+
+ if (err)
+ printk("%s: page: %p, uptodate: %d, locked: %d, err: %d.\n",
+ __func__, page, PageUptodate(page), PageLocked(page), err);
+
+ return err;
+}
+
+static int pohmelfs_read_page_complete(struct page **pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct page *page = private;
+
+ if (PageChecked(page))
+ return err;
+
+ if (err < 0) {
+ dprintk("%s: page: %p, err: %d.\n", __func__, page, err);
+ SetPageError(page);
+ }
+
+ unlock_page(page);
+
+ return err;
+}
+
+/*
+ * Read a page from remote server.
+ * Function will wait until page is unlocked.
+ */
+static int pohmelfs_readpage(struct file *file, struct page *page)
+{
+ struct inode *inode = page->mapping->host;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ int err, path_len;
+ void *data;
+ u64 isize;
+
+ err = pohmelfs_data_lock(pi, page->index << PAGE_CACHE_SHIFT,
+ PAGE_SIZE, POHMELFS_READ_LOCK);
+ if (err)
+ goto err_out_exit;
+
+ isize = i_size_read(inode);
+ if (isize <= page->index << PAGE_CACHE_SHIFT) {
+ SetPageUptodate(page);
+ unlock_page(page);
+ return 0;
+ }
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ t->complete = pohmelfs_read_page_complete;
+ t->private = page;
+
+ cmd = netfs_trans_current(t);
+ data = (void *)(cmd + 1);
+
+ err = pohmelfs_construct_path_string(pi, data, path_len);
+ if (err < 0)
+ goto err_out_free;
+
+ path_len = err;
+
+ cmd->id = pi->ino;
+ cmd->start = page->index;
+ cmd->start <<= PAGE_CACHE_SHIFT;
+ cmd->size = PAGE_CACHE_SIZE + path_len;
+ cmd->cmd = NETFS_READ_PAGE;
+ cmd->ext = path_len;
+
+ dprintk("%s: path: '%s', page: %p, ino: %llu, start: %llu, size: %lu.\n",
+ __func__, (char *)data, page, pi->ino, cmd->start, PAGE_CACHE_SIZE);
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, path_len);
+
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_return;
+
+ return pohmelfs_wait_on_page_locked(page);
+
+err_out_free:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ SetPageError(page);
+ if (PageLocked(page))
+ unlock_page(page);
+err_out_return:
+ printk("%s: page: %p, start: %lu, size: %lu, err: %d.\n",
+ __func__, page, page->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE, err);
+
+ return err;
+}
+
+/*
+ * Write begin/end magic.
+ * Allocates a page and writes inode if it was not synced to server before.
+ */
+static int pohmelfs_write_begin(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned flags,
+ struct page **pagep, void **fsdata)
+{
+ struct inode *inode = mapping->host;
+ struct page *page;
+ pgoff_t index;
+ unsigned start, end;
+ int err;
+
+ *pagep = NULL;
+
+ index = pos >> PAGE_CACHE_SHIFT;
+ start = pos & (PAGE_CACHE_SIZE - 1);
+ end = start + len;
+
+ page = grab_cache_page(mapping, index);
+#if 0
+ dprintk("%s: page: %p pos: %llu, len: %u, index: %lu, start: %u, end: %u, uptodate: %d.\n",
+ __func__, page, pos, len, index, start, end, PageUptodate(page));
+#endif
+ if (!page) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ while (!PageUptodate(page)) {
+ if (start && test_bit(NETFS_INODE_REMOTE_SYNCED, &POHMELFS_I(inode)->state)) {
+ err = pohmelfs_readpage(file, page);
+ if (err)
+ goto err_out_exit;
+
+ lock_page(page);
+ continue;
+ }
+
+ if (len != PAGE_CACHE_SIZE) {
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr + start, 0, PAGE_CACHE_SIZE - start);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+ SetPageUptodate(page);
+ }
+
+ set_page_private(page, end);
+
+ *pagep = page;
+
+ return 0;
+
+err_out_exit:
+ page_cache_release(page);
+ *pagep = NULL;
+
+ return err;
+}
+
+static int pohmelfs_write_end(struct file *file, struct address_space *mapping,
+ loff_t pos, unsigned len, unsigned copied,
+ struct page *page, void *fsdata)
+{
+ struct inode *inode = mapping->host;
+
+ if (copied != len) {
+ unsigned from = pos & (PAGE_CACHE_SIZE - 1);
+ void *kaddr = kmap_atomic(page, KM_USER0);
+
+ memset(kaddr + from + copied, 0, len - copied);
+ flush_dcache_page(page);
+ kunmap_atomic(kaddr, KM_USER0);
+ }
+
+ SetPageUptodate(page);
+ set_page_dirty(page);
+#if 0
+ dprintk("%s: page: %p [U: %d, D: %d, L: %d], pos: %llu, len: %u, copied: %u.\n",
+ __func__, page,
+ PageUptodate(page), PageDirty(page), PageLocked(page),
+ pos, len, copied);
+#endif
+ flush_dcache_page(page);
+
+ unlock_page(page);
+ page_cache_release(page);
+
+ if (pos + copied > inode->i_size) {
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+
+ psb->avail_size -= pos + copied - inode->i_size;
+
+ i_size_write(inode, pos + copied);
+ }
+
+ return copied;
+}
+
+static int pohmelfs_readpages_trans_complete(struct page **__pages, unsigned int page_num,
+ void *private, int err)
+{
+ struct pohmelfs_inode *pi = private;
+ unsigned int i, num;
+ struct page **pages, *page = (struct page *)__pages;
+ loff_t index = page->index;
+
+ pages = kzalloc(sizeof(void *) * page_num, GFP_NOIO);
+ if (!pages)
+ return -ENOMEM;
+
+ num = find_get_pages_contig(pi->vfs_inode.i_mapping, index, page_num, pages);
+ if (num <= 0) {
+ err = num;
+ goto err_out_free;
+ }
+
+ for (i=0; i<num; ++i) {
+ page = pages[i];
+
+ if (err)
+ printk("%s: %u/%u: page: %p, index: %lu, uptodate: %d, locked: %d, err: %d.\n",
+ __func__, i, num, page, page->index,
+ PageUptodate(page), PageLocked(page), err);
+
+ if (!PageChecked(page)) {
+ if (err < 0)
+ SetPageError(page);
+ unlock_page(page);
+ }
+ page_cache_release(page);
+ page_cache_release(page);
+ }
+
+err_out_free:
+ kfree(pages);
+ return err;
+}
+
+static int pohmelfs_send_readpages(struct pohmelfs_inode *pi, struct page *first, unsigned int num)
+{
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+ int err, path_len;
+ void *data;
+
+ err = pohmelfs_data_lock(pi, first->index << PAGE_CACHE_SHIFT,
+ num * PAGE_SIZE, POHMELFS_READ_LOCK);
+ if (err)
+ goto err_out_exit;
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, path_len, NETFS_TRANS_SINGLE_DST, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ cmd = netfs_trans_current(t);
+ data = (void *)(cmd + 1);
+
+ t->complete = pohmelfs_readpages_trans_complete;
+ t->private = pi;
+ t->page_num = num;
+ t->pages = (struct page **)first;
+
+ err = pohmelfs_construct_path_string(pi, data, path_len);
+ if (err < 0)
+ goto err_out_put;
+
+ path_len = err;
+
+ cmd->cmd = NETFS_READ_PAGES;
+ cmd->start = first->index;
+ cmd->start <<= PAGE_CACHE_SHIFT;
+ cmd->size = (num << 8 | PAGE_CACHE_SHIFT);
+ cmd->id = pi->ino;
+ cmd->ext = path_len;
+
+ dprintk("%s: t: %p, gen: %u, path: '%s', path_len: %u, "
+ "start: %lu, num: %u.\n",
+ __func__, t, t->gen, (char *)data, path_len,
+ first->index, num);
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, path_len);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_put:
+ netfs_trans_free(t);
+err_out_exit:
+ pohmelfs_readpages_trans_complete((struct page **)first, num, pi, err);
+ return err;
+}
+
+#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
+
+static int pohmelfs_readpages(struct file *file, struct address_space *mapping,
+ struct list_head *pages, unsigned nr_pages)
+{
+ unsigned int page_idx, num = 0;
+ struct page *page = NULL, *first = NULL;
+
+ for (page_idx = 0; page_idx < nr_pages; page_idx++) {
+ page = list_to_page(pages);
+
+ prefetchw(&page->flags);
+ list_del(&page->lru);
+
+ if (!add_to_page_cache_lru(page, mapping,
+ page->index, GFP_KERNEL)) {
+
+ if (!num) {
+ num = 1;
+ first = page;
+ continue;
+ }
+
+ dprintk("%s: added to lru page: %p, page_index: %lu, first_index: %lu.\n",
+ __func__, page, page->index, first->index);
+
+ if (unlikely(first->index + num != page->index) || (num > 500)) {
+ pohmelfs_send_readpages(POHMELFS_I(mapping->host),
+ first, num);
+ first = page;
+ num = 0;
+ }
+
+ num++;
+ }
+ }
+ pohmelfs_send_readpages(POHMELFS_I(mapping->host), first, num);
+
+ /*
+ * This will be sync read, so when last page is processed,
+ * all previous are alerady unlocked and ready to be used.
+ */
+ return 0;
+}
+
+/*
+ * Small addres space operations for POHMELFS.
+ */
+const struct address_space_operations pohmelfs_aops = {
+ .readpage = pohmelfs_readpage,
+ .readpages = pohmelfs_readpages,
+ .writepages = pohmelfs_writepages,
+ .write_begin = pohmelfs_write_begin,
+ .write_end = pohmelfs_write_end,
+ .set_page_dirty = __set_page_dirty_nobuffers,
+};
+
+/*
+ * ->detroy_inode() callback. Deletes inode from the caches
+ * and frees private data.
+ */
+static void pohmelfs_destroy_inode(struct inode *inode)
+{
+ struct super_block *sb = inode->i_sb;
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ //pohmelfs_data_unlock(pi, 0, inode->i_size, POHMELFS_READ_LOCK);
+
+ pohmelfs_inode_del_inode(psb, pi);
+
+ dprintk("%s: pi: %p, inode: %p, ino: %llu.\n",
+ __func__, pi, &pi->vfs_inode, pi->ino);
+ kmem_cache_free(pohmelfs_inode_cache, pi);
+ atomic_long_dec(&psb->total_inodes);
+}
+
+/*
+ * ->alloc_inode() callback. Allocates inode and initilizes private data.
+ */
+static struct inode *pohmelfs_alloc_inode(struct super_block *sb)
+{
+ struct pohmelfs_inode *pi;
+
+ pi = kmem_cache_alloc(pohmelfs_inode_cache, GFP_NOIO);
+ if (!pi)
+ return NULL;
+
+ pi->hash_root = RB_ROOT;
+ mutex_init(&pi->offset_lock);
+
+ INIT_LIST_HEAD(&pi->sync_create_list);
+
+ INIT_LIST_HEAD(&pi->inode_entry);
+
+ pi->lock_type = 0;
+ pi->state = 0;
+ pi->total_len = 0;
+ pi->drop_count = 0;
+
+ dprintk("%s: pi: %p, inode: %p.\n", __func__, pi, &pi->vfs_inode);
+
+ atomic_long_inc(&POHMELFS_SB(sb)->total_inodes);
+
+ return &pi->vfs_inode;
+}
+
+/*
+ * We want fsync() to work on POHMELFS.
+ */
+static int pohmelfs_fsync(struct file *file, struct dentry *dentry, int datasync)
+{
+ struct inode *inode = file->f_mapping->host;
+ struct writeback_control wbc = {
+ .sync_mode = WB_SYNC_ALL,
+ .nr_to_write = 0, /* sys_fsync did this */
+ };
+
+ return sync_inode(inode, &wbc);
+}
+
+ssize_t pohmelfs_write(struct file *file, const char __user *buf,
+ size_t len, loff_t *ppos)
+{
+ struct address_space *mapping = file->f_mapping;
+ struct inode *inode = mapping->host;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
+ struct kiocb kiocb;
+ ssize_t ret;
+ loff_t pos = *ppos;
+
+ init_sync_kiocb(&kiocb, file);
+ kiocb.ki_pos = pos;
+ kiocb.ki_left = len;
+
+ dprintk("%s: len: %zu, pos: %llu.\n", __func__, len, pos);
+
+ mutex_lock(&inode->i_mutex);
+ ret = pohmelfs_data_lock(pi, pos, len, POHMELFS_WRITE_LOCK);
+ if (ret)
+ goto err_out_unlock;
+
+ ret = generic_file_aio_write_nolock(&kiocb, &iov, 1, pos);
+ *ppos = kiocb.ki_pos;
+
+ mutex_unlock(&inode->i_mutex);
+ WARN_ON(ret < 0);
+
+ if (ret > 0 && ((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
+ ssize_t err;
+
+ err = sync_page_range(inode, mapping, pos, ret);
+ if (err < 0)
+ ret = err;
+ WARN_ON(ret < 0);
+ }
+
+ return ret;
+
+err_out_unlock:
+ mutex_unlock(&inode->i_mutex);
+ return ret;
+}
+
+const static struct file_operations pohmelfs_file_ops = {
+ .open = generic_file_open,
+ .fsync = pohmelfs_fsync,
+
+ .llseek = generic_file_llseek,
+
+ .read = do_sync_read,
+ .aio_read = generic_file_aio_read,
+
+ .mmap = generic_file_mmap,
+
+ .splice_read = generic_file_splice_read,
+ .splice_write = generic_file_splice_write,
+
+ .write = pohmelfs_write,
+ .aio_write = generic_file_aio_write,
+};
+
+const struct inode_operations pohmelfs_symlink_inode_operations = {
+ .readlink = generic_readlink,
+ .follow_link = page_follow_link_light,
+ .put_link = page_put_link,
+};
+
+int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr)
+{
+ int err;
+
+ err = inode_change_ok(inode, attr);
+ if (err) {
+ dprintk("%s: ino: %llu, inode changes are not allowed.\n", __func__, POHMELFS_I(inode)->ino);
+ goto err_out_exit;
+ }
+
+ if ((attr->ia_valid & ATTR_UID && attr->ia_uid != inode->i_uid) ||
+ (attr->ia_valid & ATTR_GID && attr->ia_gid != inode->i_gid)) {
+ err = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0;
+ if (err)
+ goto err_out_exit;
+ }
+
+ err = inode_setattr(inode, attr);
+ if (err) {
+ dprintk("%s: ino: %llu, failed to set the attributes.\n", __func__, POHMELFS_I(inode)->ino);
+ goto err_out_exit;
+ }
+
+ dprintk("%s: ino: %llu, mode: %o -> %o, uid: %u -> %u, gid: %u -> %u, size: %llu -> %llu.\n",
+ __func__, POHMELFS_I(inode)->ino, inode->i_mode, attr->ia_mode,
+ inode->i_uid, attr->ia_uid, inode->i_gid, attr->ia_gid, inode->i_size, attr->ia_size);
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err;
+
+ err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
+ if (err)
+ goto err_out_exit;
+
+ err = security_inode_setattr(dentry, attr);
+ if (err)
+ goto err_out_exit;
+
+ err = pohmelfs_setattr_raw(inode, attr);
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+static int pohmelfs_send_xattr_req(struct pohmelfs_inode *pi, u64 id, u64 start,
+ const char *name, const void *value, size_t attrsize, int command)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+ int err, path_len, namelen = strlen(name) + 1; /* 0-byte */
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ void *data;
+
+ dprintk("%s: id: %llu, start: %llu, name: '%s', attrsize: %zu, cmd: %d.\n",
+ __func__, id, start, name, attrsize, command);
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ t = netfs_trans_alloc(psb, namelen + path_len + attrsize, 0, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+
+ cmd = netfs_trans_current(t);
+ data = cmd + 1;
+
+ path_len = pohmelfs_construct_path_string(pi, data, path_len);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_put;
+ }
+ data += path_len;
+
+ /*
+ * 'name' is a NUL-terminated string already and
+ * 'namelen' includes 0-byte.
+ */
+ memcpy(data, name, namelen);
+ data += namelen;
+
+ memcpy(data, value, attrsize);
+
+ cmd->cmd = command;
+ cmd->id = id;
+ cmd->start = start;
+ cmd->size = attrsize + namelen + path_len;
+ cmd->ext = path_len;
+ cmd->csize = 0;
+ cmd->cpad = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, namelen + path_len + attrsize);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_put:
+ t->result = err;
+ netfs_trans_put(t);
+err_out_exit:
+ return err;
+}
+
+static int pohmelfs_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t attrsize, int flags)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+
+ if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
+ return -EOPNOTSUPP;
+
+ return pohmelfs_send_xattr_req(pi, flags, attrsize, name,
+ value, attrsize, NETFS_XATTR_SET);
+}
+
+static ssize_t pohmelfs_getxattr(struct dentry *dentry, const char *name,
+ void *value, size_t attrsize)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct pohmelfs_mcache *m;
+ int err;
+ long timeout = psb->mcache_timeout;
+
+ if (!(psb->state_flags & POHMELFS_FLAGS_XATTR))
+ return -EOPNOTSUPP;
+
+ m = pohmelfs_mcache_alloc(psb, 0, attrsize, value);
+ if (IS_ERR(m))
+ return PTR_ERR(m);
+
+ dprintk("%s: ino: %llu, name: '%s', size: %zu.\n",
+ __func__, pi->ino, name, attrsize);
+
+ err = pohmelfs_send_xattr_req(pi, m->gen, attrsize, name, value, 0, NETFS_XATTR_GET);
+ if (err)
+ goto err_out_put;
+
+ do {
+ err = wait_for_completion_timeout(&m->complete, timeout);
+ if (err) {
+ err = m->err;
+ break;
+ }
+
+ /*
+ * This loop is a bit ugly, since it waits until reference counter
+ * hits 1 and then put object here. Main goal is to prevent race with
+ * network thread, when it can start processing given request, i.e.
+ * increase its reference counter but yet not complete it, while
+ * we will exit from ->getxattr() with timeout, and although request
+ * will not be freed (its reference counter was increased by network
+ * thread), data pointer provided by user may be released, so we will
+ * overwrite already freed area in network thread.
+ *
+ * Now after timeout we remove request from the cache, so it can not be
+ * found by network thread, and wait for its reference counter to hit 1,
+ * i.e. if network thread already started to process this request, we wait
+ * it to finish, and then free object locally. If reference counter is
+ * already 1, i.e. request is not used by anyone else, we can free it without
+ * problem.
+ */
+ err = -ETIMEDOUT;
+ timeout = HZ;
+
+ pohmelfs_mcache_remove_locked(psb, m);
+ } while (atomic_read(&m->refcnt) != 1);
+
+ pohmelfs_mcache_put(psb, m);
+
+ dprintk("%s: ino: %llu, err: %d.\n", __func__, pi->ino, err);
+
+ return err;
+
+err_out_put:
+ pohmelfs_mcache_put(psb, m);
+ return err;
+}
+
+static int pohmelfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
+{
+ struct inode *inode = dentry->d_inode;
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+ int err;
+
+ err = pohmelfs_data_lock(pi, 0, ~0, POHMELFS_READ_LOCK);
+ if (err)
+ return err;
+
+ dprintk("%s: ino: %llu, mode: %o, uid: %u, gid: %u, size: %llu.\n",
+ __func__, pi->ino, inode->i_mode, inode->i_uid,
+ inode->i_gid, inode->i_size);
+
+ generic_fillattr(inode, stat);
+ return 0;
+}
+
+const struct inode_operations pohmelfs_file_inode_operations = {
+ .setattr = pohmelfs_setattr,
+ .getattr = pohmelfs_getattr,
+ .setxattr = pohmelfs_setxattr,
+ .getxattr = pohmelfs_getxattr,
+};
+
+/*
+ * Fill inode data: mode, size, operation callbacks and so on...
+ */
+void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info)
+{
+ inode->i_mode = info->mode;
+ inode->i_nlink = info->nlink;
+ inode->i_uid = info->uid;
+ inode->i_gid = info->gid;
+ inode->i_blocks = info->blocks;
+ inode->i_rdev = info->rdev;
+ inode->i_size = info->size;
+ inode->i_version = info->version;
+ inode->i_blkbits = ffs(info->blocksize);
+
+ dprintk("%s: inode: %p, num: %lu/%llu inode is regular: %d, dir: %d, link: %d, mode: %o, size: %llu.\n",
+ __func__, inode, inode->i_ino, info->ino,
+ S_ISREG(inode->i_mode), S_ISDIR(inode->i_mode),
+ S_ISLNK(inode->i_mode), inode->i_mode, inode->i_size);
+
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
+
+ /*
+ * i_mapping is a pointer to i_data during inode initialization.
+ */
+ inode->i_data.a_ops = &pohmelfs_aops;
+
+ if (S_ISREG(inode->i_mode)) {
+ inode->i_fop = &pohmelfs_file_ops;
+ inode->i_op = &pohmelfs_file_inode_operations;
+ } else if (S_ISDIR(inode->i_mode)) {
+ inode->i_fop = &pohmelfs_dir_fops;
+ inode->i_op = &pohmelfs_dir_inode_ops;
+ } else if (S_ISLNK(inode->i_mode)) {
+ inode->i_op = &pohmelfs_symlink_inode_operations;
+ inode->i_fop = &pohmelfs_file_ops;
+ } else {
+ inode->i_fop = &generic_ro_fops;
+ }
+}
+
+static void pohmelfs_drop_inode(struct inode *inode)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct pohmelfs_inode *pi = POHMELFS_I(inode);
+
+ spin_lock(&psb->ino_lock);
+ list_del_init(&pi->inode_entry);
+ spin_unlock(&psb->ino_lock);
+
+ generic_drop_inode(inode);
+}
+
+static struct pohmelfs_inode *pohmelfs_get_inode_from_list(struct pohmelfs_sb *psb,
+ struct list_head *head, unsigned int *count)
+{
+ struct pohmelfs_inode *pi = NULL;
+
+ spin_lock(&psb->ino_lock);
+ if (!list_empty(head)) {
+ pi = list_entry(head->next, struct pohmelfs_inode,
+ inode_entry);
+ list_del_init(&pi->inode_entry);
+ *count = pi->drop_count;
+ pi->drop_count = 0;
+ }
+ spin_unlock(&psb->ino_lock);
+
+ return pi;
+}
+
+static void pohmelfs_flush_transactions(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c;
+
+ mutex_lock(&psb->state_lock);
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ pohmelfs_state_flush_transactions(&c->state);
+ }
+ mutex_unlock(&psb->state_lock);
+}
+
+/*
+ * ->put_super() callback. Invoked before superblock is destroyed,
+ * so it has to clean all private data.
+ */
+static void pohmelfs_put_super(struct super_block *sb)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+ struct pohmelfs_inode *pi;
+ unsigned int count;
+ unsigned int in_drop_list = 0;
+ struct inode *inode, *tmp;
+
+ dprintk("%s.\n", __func__);
+
+ /*
+ * Kill pending transactions, which could affect inodes in-flight.
+ */
+ pohmelfs_flush_transactions(psb);
+
+ while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
+ inode = &pi->vfs_inode;
+
+ dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
+ __func__, pi->ino, pi, inode, count);
+
+ if (atomic_read(&inode->i_count) != count) {
+ printk("%s: ino: %llu, pi: %p, inode: %p, count: %u, i_count: %d.\n",
+ __func__, pi->ino, pi, inode, count,
+ atomic_read(&inode->i_count));
+ count = atomic_read(&inode->i_count);
+ in_drop_list++;
+ }
+
+ while (count--)
+ iput(&pi->vfs_inode);
+ }
+
+ list_for_each_entry_safe(inode, tmp, &sb->s_inodes, i_sb_list) {
+ pi = POHMELFS_I(inode);
+
+ dprintk("%s: ino: %llu, pi: %p, inode: %p, i_count: %u.\n",
+ __func__, pi->ino, pi, inode, atomic_read(&inode->i_count));
+
+ /*
+ * These are special inodes, they were created during
+ * directory reading or lookup, and were not bound to dentry,
+ * so they live here with reference counter being 1 and prevent
+ * umount from succeed since it believes that they are busy.
+ */
+ count = atomic_read(&inode->i_count);
+ if (count) {
+ list_del_init(&inode->i_sb_list);
+ while (count--)
+ iput(&pi->vfs_inode);
+ }
+ }
+
+ psb->trans_scan_timeout = psb->drop_scan_timeout = 0;
+ cancel_rearming_delayed_work(&psb->dwork);
+ cancel_rearming_delayed_work(&psb->drop_dwork);
+ flush_scheduled_work();
+
+ dprintk("%s: stopped workqueues.\n", __func__);
+
+ pohmelfs_crypto_exit(psb);
+ pohmelfs_state_exit(psb);
+
+ kfree(psb);
+ sb->s_fs_info = NULL;
+
+ pohmelfs_ftrans_exit();
+}
+
+static int pohmelfs_remount(struct super_block *sb, int *flags, char *data)
+{
+ *flags |= MS_RDONLY;
+ return 0;
+}
+
+static int pohmelfs_statfs(struct dentry *dentry, struct kstatfs *buf)
+{
+ struct super_block *sb = dentry->d_sb;
+ struct pohmelfs_sb *psb = POHMELFS_SB(sb);
+
+ /*
+ * There are no filesystem size limits yet.
+ */
+ memset(buf, 0, sizeof(struct kstatfs));
+
+ buf->f_type = POHMELFS_MAGIC_NUM; /* 'POH.' */
+ buf->f_bsize = sb->s_blocksize;
+ buf->f_files = psb->ino;
+ buf->f_namelen = 255;
+ buf->f_files = atomic_long_read(&psb->total_inodes);
+ buf->f_bfree = buf->f_bavail = psb->avail_size >> PAGE_SHIFT;
+ buf->f_blocks = psb->total_size >> PAGE_SHIFT;
+
+ dprintk("%s: total: %llu, avail: %llu, inodes: %llu, bsize: %lu.\n",
+ __func__, psb->total_size, psb->avail_size, buf->f_files, sb->s_blocksize);
+
+ return 0;
+}
+
+static int pohmelfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(vfs->mnt_sb);
+
+ seq_printf(seq, ",idx=%u", psb->idx);
+ seq_printf(seq, ",trans_scan_timeout=%u", jiffies_to_msecs(psb->trans_scan_timeout));
+ seq_printf(seq, ",drop_scan_timeout=%u", jiffies_to_msecs(psb->drop_scan_timeout));
+ seq_printf(seq, ",wait_on_page_timeout=%u", jiffies_to_msecs(psb->wait_on_page_timeout));
+ seq_printf(seq, ",trans_retries=%u", psb->trans_retries);
+ seq_printf(seq, ",crypto_thread_num=%u", psb->crypto_thread_num);
+ seq_printf(seq, ",trans_max_pages=%u", psb->trans_max_pages);
+ seq_printf(seq, ",mcache_timeout=%u", jiffies_to_msecs(psb->mcache_timeout));
+ if (psb->crypto_fail_unsupported)
+ seq_printf(seq, ",crypto_fail_unsupported");
+
+ return 0;
+}
+
+static const struct super_operations pohmelfs_sb_ops = {
+ .alloc_inode = pohmelfs_alloc_inode,
+ .destroy_inode = pohmelfs_destroy_inode,
+ .drop_inode = pohmelfs_drop_inode,
+ .write_inode = pohmelfs_write_inode,
+ .put_super = pohmelfs_put_super,
+ .remount_fs = pohmelfs_remount,
+ .statfs = pohmelfs_statfs,
+ .show_options = pohmelfs_show_options,
+};
+
+enum {
+ pohmelfs_opt_idx,
+ pohmelfs_opt_trans_scan_timeout,
+ pohmelfs_opt_drop_scan_timeout,
+ pohmelfs_opt_wait_on_page_timeout,
+ pohmelfs_opt_trans_retries,
+ pohmelfs_opt_crypto_thread_num,
+ pohmelfs_opt_trans_max_pages,
+ pohmelfs_opt_crypto_fail_unsupported,
+ pohmelfs_opt_mcache_timeout,
+};
+
+static struct match_token pohmelfs_tokens[] = {
+ {pohmelfs_opt_idx, "idx=%u"},
+ {pohmelfs_opt_trans_scan_timeout, "trans_scan_timeout=%u"},
+ {pohmelfs_opt_drop_scan_timeout, "drop_scan_timeout=%u"},
+ {pohmelfs_opt_wait_on_page_timeout, "wait_on_page_timeout=%u"},
+ {pohmelfs_opt_trans_retries, "trans_retries=%u"},
+ {pohmelfs_opt_crypto_thread_num, "crypto_thread_num=%u"},
+ {pohmelfs_opt_trans_max_pages, "trans_max_pages=%u"},
+ {pohmelfs_opt_crypto_fail_unsupported, "crypto_fail_unsupported"},
+ {pohmelfs_opt_mcache_timeout, "mcache_timeout=%u"},
+};
+
+static int pohmelfs_parse_options(char *options, struct pohmelfs_sb *psb)
+{
+ char *p;
+ substring_t args[MAX_OPT_ARGS];
+ int option, err;
+
+ if (!options)
+ return 0;
+
+ while ((p = strsep(&options, ",")) != NULL) {
+ int token;
+ if (!*p)
+ continue;
+
+ token = match_token(p, pohmelfs_tokens, args);
+
+ err = match_int(&args[0], &option);
+ if (err)
+ return err;
+
+ switch (token) {
+ case pohmelfs_opt_idx:
+ psb->idx = option;
+ break;
+ case pohmelfs_opt_trans_scan_timeout:
+ psb->trans_scan_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_drop_scan_timeout:
+ psb->drop_scan_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_wait_on_page_timeout:
+ psb->wait_on_page_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_mcache_timeout:
+ psb->mcache_timeout = msecs_to_jiffies(option);
+ break;
+ case pohmelfs_opt_trans_retries:
+ psb->trans_retries = option;
+ break;
+ case pohmelfs_opt_crypto_thread_num:
+ psb->crypto_thread_num = option;
+ break;
+ case pohmelfs_opt_trans_max_pages:
+ psb->trans_max_pages = option;
+ break;
+ case pohmelfs_opt_crypto_fail_unsupported:
+ psb->crypto_fail_unsupported = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static void pohmelfs_flush_inode(struct pohmelfs_inode *pi, unsigned int count)
+{
+ struct inode *inode = &pi->vfs_inode;
+
+ dprintk("%s: %p: ino: %llu, owned: %d.\n",
+ __func__, inode, pi->ino, test_bit(NETFS_INODE_OWNED, &pi->state));
+
+ mutex_lock(&inode->i_mutex);
+ if (test_and_clear_bit(NETFS_INODE_OWNED, &pi->state)) {
+ filemap_fdatawrite(inode->i_mapping);
+ inode->i_sb->s_op->write_inode(inode, 0);
+ }
+
+ truncate_inode_pages(inode->i_mapping, 0);
+
+ pohmelfs_data_unlock(pi, 0, ~0, POHMELFS_WRITE_LOCK);
+ mutex_unlock(&inode->i_mutex);
+}
+
+static void pohmelfs_put_inode_count(struct pohmelfs_inode *pi, unsigned int count)
+{
+ dprintk("%s: ino: %llu, pi: %p, inode: %p, count: %u.\n",
+ __func__, pi->ino, pi, &pi->vfs_inode, count);
+
+ if (test_and_clear_bit(NETFS_INODE_NEED_FLUSH, &pi->state))
+ pohmelfs_flush_inode(pi, count);
+
+ while (count--)
+ iput(&pi->vfs_inode);
+}
+
+static void pohmelfs_drop_scan(struct work_struct *work)
+{
+ struct pohmelfs_sb *psb =
+ container_of(work, struct pohmelfs_sb, drop_dwork.work);
+ struct pohmelfs_inode *pi;
+ unsigned int count = 0;
+
+ while ((pi = pohmelfs_get_inode_from_list(psb, &psb->drop_list, &count))) {
+ pohmelfs_put_inode_count(pi, count);
+ }
+ pohmelfs_check_states(psb);
+
+ if (psb->drop_scan_timeout)
+ schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
+}
+
+/*
+ * Run through all transactions starting from the oldest,
+ * drop transaction from current state and try to send it
+ * to all remote nodes, which are currently installed.
+ */
+static void pohmelfs_trans_scan_state(struct netfs_state *st)
+{
+ struct rb_node *rb_node;
+ struct netfs_trans_dst *dst;
+ struct pohmelfs_sb *psb = st->psb;
+ unsigned int timeout = psb->trans_scan_timeout;
+ struct netfs_trans *t;
+ int err;
+
+ mutex_lock(&st->trans_lock);
+ for (rb_node = rb_first(&st->trans_root); rb_node; ) {
+ dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
+ t = dst->trans;
+
+ if (timeout && time_after(dst->send_time + timeout, jiffies)
+ && dst->retries == 0)
+ break;
+
+ dprintk("%s: t: %p, gen: %u, st: %p, retries: %u, max: %u.\n",
+ __func__, t, t->gen, st, dst->retries, psb->trans_retries);
+ netfs_trans_get(t);
+
+ rb_node = rb_next(rb_node);
+
+ err = -ETIMEDOUT;
+ if (timeout && (++dst->retries < psb->trans_retries)) {
+ err = netfs_trans_resend(t, psb);
+ }
+
+ if (err || (t->flags & NETFS_TRANS_SINGLE_DST)) {
+ if (netfs_trans_remove_nolock(dst, st))
+ netfs_trans_drop_dst_nostate(dst);
+ }
+
+ t->result = err;
+ netfs_trans_put(t);
+ }
+ mutex_unlock(&st->trans_lock);
+}
+
+/*
+ * Walk through all installed network states and resend all
+ * transactions, which are old enough.
+ */
+static void pohmelfs_trans_scan(struct work_struct *work)
+{
+ struct pohmelfs_sb *psb =
+ container_of(work, struct pohmelfs_sb, dwork.work);
+ struct netfs_state *st;
+ struct pohmelfs_config *c;
+
+ mutex_lock(&psb->state_lock);
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ pohmelfs_trans_scan_state(st);
+ }
+ mutex_unlock(&psb->state_lock);
+
+ /*
+ * If no timeout specified then system is in the middle of umount process,
+ * so no need to reschedule scanning process again.
+ */
+ if (psb->trans_scan_timeout)
+ schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
+}
+
+int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
+ unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start)
+{
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ int err = 0, sz;
+ struct netfs_trans *t;
+ int path_len, addon_len = 0;
+ void *data;
+ struct netfs_inode_info *info;
+ struct netfs_cmd *cmd;
+
+ dprintk("%s: ino: %llu, cmd: %u, addon: %p.\n", __func__, pi->ino, cmd_op, addon);
+
+ path_len = pohmelfs_path_length(pi);
+ if (path_len < 0) {
+ err = path_len;
+ goto err_out_exit;
+ }
+
+ if (addon)
+ addon_len = strlen(addon) + 1; /* 0-byte */
+ sz = addon_len;
+
+ if (cmd_op == NETFS_INODE_INFO)
+ sz += sizeof(struct netfs_inode_info);
+
+ t = netfs_trans_alloc(psb, sz + path_len, flags, 0);
+ if (!t) {
+ err = -ENOMEM;
+ goto err_out_exit;
+ }
+ t->complete = complete;
+ t->private = priv;
+
+ cmd = netfs_trans_current(t);
+ data = (void *)(cmd + 1);
+
+ if (cmd_op == NETFS_INODE_INFO) {
+ info = (struct netfs_inode_info *)(cmd + 1);
+ data = (void *)(info + 1);
+
+ /*
+ * We are under i_mutex, can read and change whatever we want...
+ */
+ info->mode = inode->i_mode;
+ info->nlink = inode->i_nlink;
+ info->uid = inode->i_uid;
+ info->gid = inode->i_gid;
+ info->blocks = inode->i_blocks;
+ info->rdev = inode->i_rdev;
+ info->size = inode->i_size;
+ info->version = inode->i_version;
+
+ netfs_convert_inode_info(info);
+ }
+
+ path_len = pohmelfs_construct_path_string(pi, data, path_len);
+ if (path_len < 0)
+ goto err_out_free;
+
+ dprintk("%s: path_len: %d.\n", __func__, path_len);
+
+ if (addon) {
+ path_len--; /* Do not place null-byte before the addon */
+ path_len += sprintf(data + path_len, "/%s", addon) + 1; /* 0 - byte */
+ }
+
+ sz += path_len;
+
+ cmd->cmd = cmd_op;
+ cmd->ext = path_len;
+ cmd->size = sz;
+ cmd->id = id;
+ cmd->start = start;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, sz);
+
+ /*
+ * Note, that it is possible to leak error here: transaction callback will not
+ * be invoked for allocation path failure.
+ */
+ return netfs_trans_finish(t, psb);
+
+err_out_free:
+ netfs_trans_free(t);
+err_out_exit:
+ if (complete)
+ complete(NULL, 0, priv, err);
+ return err;
+}
+
+int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
+ netfs_trans_complete_t complete, void *priv, u64 start)
+{
+ return pohmelfs_meta_command_data(pi, pi->ino, cmd_op, NULL, flags, complete, priv, start);
+}
+
+/*
+ * Send request and wait for POHMELFS root capabilities response,
+ * which will update server's informaion about size of the export,
+ * permissions, number of objects, available size and so on.
+ */
+static int pohmelfs_root_handshake(struct pohmelfs_sb *psb)
+{
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ int err = -ENOMEM;
+
+ t = netfs_trans_alloc(psb, 0, 0, 0);
+ if (!t)
+ goto err_out_exit;
+
+ cmd = netfs_trans_current(t);
+
+ cmd->cmd = NETFS_CAPABILITIES;
+ cmd->id = POHMELFS_ROOT_CAPABILITIES;
+ cmd->size = 0;
+ cmd->start = 0;
+ cmd->ext = 0;
+ cmd->csize = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_trans_update(cmd, t, 0);
+
+ err = netfs_trans_finish(t, psb);
+ if (err)
+ goto err_out_exit;
+
+ psb->flags = ~0;
+ err = wait_event_interruptible_timeout(psb->wait,
+ (psb->flags != ~0),
+ psb->wait_on_page_timeout);
+ if (!err) {
+ err = -ETIMEDOUT;
+ } else {
+ err = -psb->flags;
+ }
+
+ if (err)
+ goto err_out_exit;
+
+ return 0;
+
+err_out_exit:
+ return err;
+}
+
+/*
+ * Allocate private superblock and create root dir.
+ */
+static int pohmelfs_fill_super(struct super_block *sb, void *data, int silent)
+{
+ struct pohmelfs_sb *psb;
+ int err = -ENOMEM;
+ struct inode *root;
+ struct pohmelfs_inode *npi;
+ struct qstr str;
+
+ pohmelfs_ftrans_init();
+
+ psb = kzalloc(sizeof(struct pohmelfs_sb), GFP_KERNEL);
+ if (!psb)
+ goto err_out_exit;
+
+ sb->s_fs_info = psb;
+ sb->s_op = &pohmelfs_sb_ops;
+ sb->s_magic = POHMELFS_MAGIC_NUM;
+ sb->s_maxbytes = MAX_LFS_FILESIZE;
+ sb->s_blocksize = PAGE_SIZE;
+
+ psb->sb = sb;
+
+ psb->ino = 2;
+ psb->idx = 0;
+ psb->active_state = NULL;
+ psb->trans_retries = 5;
+ psb->trans_data_size = PAGE_SIZE;
+ psb->drop_scan_timeout = msecs_to_jiffies(1000);
+ psb->trans_scan_timeout = msecs_to_jiffies(5000);
+ psb->wait_on_page_timeout = msecs_to_jiffies(5000);
+ init_waitqueue_head(&psb->wait);
+
+ spin_lock_init(&psb->ino_lock);
+
+ INIT_LIST_HEAD(&psb->drop_list);
+
+ mutex_init(&psb->mcache_lock);
+ psb->mcache_root = RB_ROOT;
+ psb->mcache_timeout = msecs_to_jiffies(5000);
+ atomic_long_set(&psb->mcache_gen, 0);
+
+ psb->trans_max_pages = 100;
+
+ psb->crypto_align_size = 16;
+ psb->crypto_attached_size = 0;
+ psb->hash_strlen = 0;
+ psb->cipher_strlen = 0;
+ psb->perform_crypto = 0;
+ psb->crypto_thread_num = 2;
+ psb->crypto_fail_unsupported = 0;
+ mutex_init(&psb->crypto_thread_lock);
+ INIT_LIST_HEAD(&psb->crypto_ready_list);
+ INIT_LIST_HEAD(&psb->crypto_active_list);
+
+ atomic_set(&psb->trans_gen, 1);
+ atomic_set(&psb->total_inodes, 0);
+
+ mutex_init(&psb->state_lock);
+ INIT_LIST_HEAD(&psb->state_list);
+
+ err = pohmelfs_parse_options((char *) data, psb);
+ if (err)
+ goto err_out_free_sb;
+
+ err = pohmelfs_copy_crypto(psb);
+ if (err)
+ goto err_out_free_sb;
+
+ err = pohmelfs_state_init(psb);
+ if (err)
+ goto err_out_free_strings;
+
+ err = pohmelfs_crypto_init(psb);
+ if (err)
+ goto err_out_state_exit;
+
+ err = pohmelfs_root_handshake(psb);
+ if (err)
+ goto err_out_crypto_exit;
+
+ str.name = "/";
+ str.hash = jhash("/", 1, 0);
+ str.len = 1;
+
+ npi = pohmelfs_create_entry_local(psb, NULL, &str, 0, 0755|S_IFDIR);
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+ goto err_out_crypto_exit;
+ }
+
+ root = &npi->vfs_inode;
+
+ sb->s_root = d_alloc_root(root);
+ if (!sb->s_root)
+ goto err_out_put_root;
+
+ INIT_DELAYED_WORK(&psb->drop_dwork, pohmelfs_drop_scan);
+ schedule_delayed_work(&psb->drop_dwork, psb->drop_scan_timeout);
+
+ INIT_DELAYED_WORK(&psb->dwork, pohmelfs_trans_scan);
+ schedule_delayed_work(&psb->dwork, psb->trans_scan_timeout);
+
+ return 0;
+
+err_out_put_root:
+ iput(root);
+err_out_crypto_exit:
+ pohmelfs_crypto_exit(psb);
+err_out_state_exit:
+ pohmelfs_state_exit(psb);
+err_out_free_strings:
+ kfree(psb->cipher_string);
+ kfree(psb->hash_string);
+err_out_free_sb:
+ kfree(psb);
+err_out_exit:
+
+ dprintk("%s: err: %d.\n", __func__, err);
+ return err;
+}
+
+/*
+ * Some VFS magic here...
+ */
+static int pohmelfs_get_sb(struct file_system_type *fs_type,
+ int flags, const char *dev_name, void *data, struct vfsmount *mnt)
+{
+ return get_sb_nodev(fs_type, flags, data, pohmelfs_fill_super,
+ mnt);
+}
+
+static struct file_system_type pohmel_fs_type = {
+ .owner = THIS_MODULE,
+ .name = "pohmel",
+ .get_sb = pohmelfs_get_sb,
+ .kill_sb = kill_anon_super,
+};
+
+/*
+ * Cache and module initializations and freeing routings.
+ */
+static void pohmelfs_init_once(void *data)
+{
+ struct pohmelfs_inode *pi = data;
+
+ inode_init_once(&pi->vfs_inode);
+}
+
+static int __init pohmelfs_init_inodecache(void)
+{
+ pohmelfs_inode_cache = kmem_cache_create("pohmelfs_inode_cache",
+ sizeof(struct pohmelfs_inode),
+ 0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD),
+ pohmelfs_init_once);
+ if (!pohmelfs_inode_cache)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static void pohmelfs_destroy_inodecache(void)
+{
+ kmem_cache_destroy(pohmelfs_inode_cache);
+}
+
+static int __init init_pohmel_fs(void)
+{
+ int err;
+
+ err = pohmelfs_config_init();
+ if (err)
+ goto err_out_exit;
+
+ err = pohmelfs_init_inodecache();
+ if (err)
+ goto err_out_config_exit;
+
+ err = pohmelfs_mcache_init();
+ if (err)
+ goto err_out_destroy;
+
+ err = netfs_trans_init();
+ if (err)
+ goto err_out_mcache_exit;
+
+ err = register_filesystem(&pohmel_fs_type);
+ if (err)
+ goto err_out_trans;
+
+ return 0;
+
+err_out_trans:
+ netfs_trans_exit();
+err_out_mcache_exit:
+ pohmelfs_mcache_exit();
+err_out_destroy:
+ pohmelfs_destroy_inodecache();
+err_out_config_exit:
+ pohmelfs_config_exit();
+err_out_exit:
+ return err;
+}
+
+static void __exit exit_pohmel_fs(void)
+{
+ unregister_filesystem(&pohmel_fs_type);
+ pohmelfs_destroy_inodecache();
+ pohmelfs_mcache_exit();
+ pohmelfs_config_exit();
+ netfs_trans_exit();
+}
+
+module_init(init_pohmel_fs);
+module_exit(exit_pohmel_fs);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
+MODULE_DESCRIPTION("Pohmel filesystem");
diff --git a/drivers/staging/pohmelfs/lock.c b/drivers/staging/pohmelfs/lock.c
new file mode 100644
index 00000000000..ad4a18559bd
--- /dev/null
+++ b/drivers/staging/pohmelfs/lock.c
@@ -0,0 +1,182 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/fsnotify.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+#include "netfs.h"
+
+static int pohmelfs_send_lock_trans(struct pohmelfs_inode *pi,
+ u64 id, u64 start, u32 size, int type)
+{
+ struct inode *inode = &pi->vfs_inode;
+ struct pohmelfs_sb *psb = POHMELFS_SB(inode->i_sb);
+ struct netfs_trans *t;
+ struct netfs_cmd *cmd;
+ int path_len, err;
+ void *data;
+ struct netfs_lock *l;
+ int isize = (type & POHMELFS_LOCK_GRAB) ? 0 : sizeof(struct netfs_inode_info);
+
+ err = pohmelfs_path_length(pi);
+ if (err < 0)
+ goto err_out_exit;
+
+ path_len = err;
+
+ err = -ENOMEM;
+ t = netfs_trans_alloc(psb, path_len + sizeof(struct netfs_lock) + isize, 0, 0);
+ if (!t)
+ goto err_out_exit;
+
+ cmd = netfs_trans_current(t);
+ data = cmd + 1;
+
+ err = pohmelfs_construct_path_string(pi, data, path_len);
+ if (err < 0)
+ goto err_out_free;
+ path_len = err;
+
+ l = data + path_len;
+
+ l->start = start;
+ l->size = size;
+ l->type = type;
+ l->ino = pi->ino;
+
+ cmd->cmd = NETFS_LOCK;
+ cmd->start = 0;
+ cmd->id = id;
+ cmd->size = sizeof(struct netfs_lock) + path_len + isize;
+ cmd->ext = path_len;
+ cmd->csize = 0;
+
+ netfs_convert_cmd(cmd);
+ netfs_convert_lock(l);
+
+ if (isize) {
+ struct netfs_inode_info *info = (struct netfs_inode_info *)(l + 1);
+
+ info->mode = inode->i_mode;
+ info->nlink = inode->i_nlink;
+ info->uid = inode->i_uid;
+ info->gid = inode->i_gid;
+ info->blocks = inode->i_blocks;
+ info->rdev = inode->i_rdev;
+ info->size = inode->i_size;
+ info->version = inode->i_version;
+
+ netfs_convert_inode_info(info);
+ }
+
+ netfs_trans_update(cmd, t, path_len + sizeof(struct netfs_lock) + isize);
+
+ return netfs_trans_finish(t, psb);
+
+err_out_free:
+ netfs_trans_free(t);
+err_out_exit:
+ printk("%s: err: %d.\n", __func__, err);
+ return err;
+}
+
+int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+ struct pohmelfs_mcache *m;
+ int err = -ENOMEM;
+ struct iattr iattr;
+ struct inode *inode = &pi->vfs_inode;
+
+ dprintk("%s: %p: ino: %llu, start: %llu, size: %u, "
+ "type: %d, locked as: %d, owned: %d.\n",
+ __func__, &pi->vfs_inode, pi->ino,
+ start, size, type, pi->lock_type,
+ !!test_bit(NETFS_INODE_OWNED, &pi->state));
+
+ if (!pohmelfs_need_lock(pi, type))
+ return 0;
+
+ m = pohmelfs_mcache_alloc(psb, start, size, NULL);
+ if (IS_ERR(m))
+ return PTR_ERR(m);
+
+ err = pohmelfs_send_lock_trans(pi, m->gen, start, size,
+ type | POHMELFS_LOCK_GRAB);
+ if (err)
+ goto err_out_put;
+
+ err = wait_for_completion_timeout(&m->complete, psb->mcache_timeout);
+ if (err)
+ err = m->err;
+ else
+ err = -ETIMEDOUT;
+
+ if (err) {
+ printk("%s: %p: ino: %llu, mgen: %llu, start: %llu, size: %u, err: %d.\n",
+ __func__, &pi->vfs_inode, pi->ino, m->gen, start, size, err);
+ }
+
+ if (err && (err != -ENOENT))
+ goto err_out_put;
+
+ if (!err) {
+ netfs_convert_inode_info(&m->info);
+
+ iattr.ia_valid = ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_SIZE | ATTR_ATIME;
+ iattr.ia_mode = m->info.mode;
+ iattr.ia_uid = m->info.uid;
+ iattr.ia_gid = m->info.gid;
+ iattr.ia_size = m->info.size;
+ iattr.ia_atime = CURRENT_TIME;
+
+ dprintk("%s: %p: ino: %llu, mgen: %llu, start: %llu, isize: %llu -> %llu.\n",
+ __func__, &pi->vfs_inode, pi->ino, m->gen, start, inode->i_size, m->info.size);
+
+ err = pohmelfs_setattr_raw(inode, &iattr);
+ if (!err) {
+ struct dentry *dentry = d_find_alias(inode);
+ if (dentry) {
+ fsnotify_change(dentry, iattr.ia_valid);
+ dput(dentry);
+ }
+ }
+ }
+
+ pi->lock_type = type;
+ set_bit(NETFS_INODE_OWNED, &pi->state);
+
+ pohmelfs_mcache_put(psb, m);
+
+ return 0;
+
+err_out_put:
+ pohmelfs_mcache_put(psb, m);
+ return err;
+}
+
+int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type)
+{
+ dprintk("%s: %p: ino: %llu, start: %llu, size: %u, type: %d.\n",
+ __func__, &pi->vfs_inode, pi->ino, start, size, type);
+ pi->lock_type = 0;
+ clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &pi->state);
+ clear_bit(NETFS_INODE_OWNED, &pi->state);
+ return pohmelfs_send_lock_trans(pi, pi->ino, start, size, type);
+}
diff --git a/drivers/staging/pohmelfs/mcache.c b/drivers/staging/pohmelfs/mcache.c
new file mode 100644
index 00000000000..e22665cdd16
--- /dev/null
+++ b/drivers/staging/pohmelfs/mcache.c
@@ -0,0 +1,171 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/mempool.h>
+
+#include "netfs.h"
+
+static struct kmem_cache *pohmelfs_mcache_cache;
+static mempool_t *pohmelfs_mcache_pool;
+
+static inline int pohmelfs_mcache_cmp(u64 gen, u64 new)
+{
+ if (gen < new)
+ return 1;
+ if (gen > new)
+ return -1;
+ return 0;
+}
+
+struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen)
+{
+ struct rb_root *root = &psb->mcache_root;
+ struct rb_node *n = root->rb_node;
+ struct pohmelfs_mcache *tmp, *ret = NULL;
+ int cmp;
+
+ while (n) {
+ tmp = rb_entry(n, struct pohmelfs_mcache, mcache_entry);
+
+ cmp = pohmelfs_mcache_cmp(tmp->gen, gen);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else {
+ ret = tmp;
+ pohmelfs_mcache_get(ret);
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int pohmelfs_mcache_insert(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ struct rb_root *root = &psb->mcache_root;
+ struct rb_node **n = &root->rb_node, *parent = NULL;
+ struct pohmelfs_mcache *ret = NULL, *tmp;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ tmp = rb_entry(parent, struct pohmelfs_mcache, mcache_entry);
+
+ cmp = pohmelfs_mcache_cmp(tmp->gen, m->gen);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ if (ret)
+ return -EEXIST;
+
+ rb_link_node(&m->mcache_entry, parent, n);
+ rb_insert_color(&m->mcache_entry, root);
+
+ return 0;
+}
+
+static int pohmelfs_mcache_remove(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ if (m && m->mcache_entry.rb_parent_color) {
+ rb_erase(&m->mcache_entry, &psb->mcache_root);
+ m->mcache_entry.rb_parent_color = 0;
+ return 1;
+ }
+ return 0;
+}
+
+void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ mutex_lock(&psb->mcache_lock);
+ pohmelfs_mcache_remove(psb, m);
+ mutex_unlock(&psb->mcache_lock);
+}
+
+struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
+ unsigned int size, void *data)
+{
+ struct pohmelfs_mcache *m;
+ int err = -ENOMEM;
+
+ m = mempool_alloc(pohmelfs_mcache_pool, GFP_KERNEL);
+ if (!m)
+ goto err_out_exit;
+
+ init_completion(&m->complete);
+ m->err = 0;
+ atomic_set(&m->refcnt, 1);
+ m->data = data;
+ m->start = start;
+ m->size = size;
+ m->gen = atomic_long_inc_return(&psb->mcache_gen);
+
+ mutex_lock(&psb->mcache_lock);
+ err = pohmelfs_mcache_insert(psb, m);
+ mutex_unlock(&psb->mcache_lock);
+ if (err)
+ goto err_out_free;
+
+ return m;
+
+err_out_free:
+ mempool_free(m, pohmelfs_mcache_pool);
+err_out_exit:
+ return ERR_PTR(err);
+}
+
+void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m)
+{
+ pohmelfs_mcache_remove_locked(psb, m);
+
+ mempool_free(m, pohmelfs_mcache_pool);
+}
+
+int __init pohmelfs_mcache_init(void)
+{
+ pohmelfs_mcache_cache = kmem_cache_create("pohmelfs_mcache_cache",
+ sizeof(struct pohmelfs_mcache),
+ 0, (SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD), NULL);
+ if (!pohmelfs_mcache_cache)
+ goto err_out_exit;
+
+ pohmelfs_mcache_pool = mempool_create_slab_pool(256, pohmelfs_mcache_cache);
+ if (!pohmelfs_mcache_pool)
+ goto err_out_free;
+
+ return 0;
+
+err_out_free:
+ kmem_cache_destroy(pohmelfs_mcache_cache);
+err_out_exit:
+ return -ENOMEM;
+}
+
+void pohmelfs_mcache_exit(void)
+{
+ mempool_destroy(pohmelfs_mcache_pool);
+ kmem_cache_destroy(pohmelfs_mcache_cache);
+}
diff --git a/drivers/staging/pohmelfs/net.c b/drivers/staging/pohmelfs/net.c
new file mode 100644
index 00000000000..c9b8540c1ef
--- /dev/null
+++ b/drivers/staging/pohmelfs/net.c
@@ -0,0 +1,1247 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/fsnotify.h>
+#include <linux/jhash.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/kthread.h>
+#include <linux/pagemap.h>
+#include <linux/poll.h>
+#include <linux/swap.h>
+#include <linux/syscalls.h>
+#include <linux/vmalloc.h>
+
+#include "netfs.h"
+
+static int pohmelfs_ftrans_size = 10240;
+static u32 *pohmelfs_ftrans;
+
+int pohmelfs_ftrans_init(void)
+{
+ pohmelfs_ftrans = vmalloc(pohmelfs_ftrans_size * 4);
+ if (!pohmelfs_ftrans)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void pohmelfs_ftrans_exit(void)
+{
+ vfree(pohmelfs_ftrans);
+}
+
+void pohmelfs_ftrans_clean(u64 id)
+{
+ if (pohmelfs_ftrans) {
+ u32 i = id & 0xffffffff;
+ int idx = i % pohmelfs_ftrans_size;
+
+ pohmelfs_ftrans[idx] = 0;
+ }
+}
+
+void pohmelfs_ftrans_update(u64 id)
+{
+ if (pohmelfs_ftrans) {
+ u32 i = id & 0xffffffff;
+ int idx = i % pohmelfs_ftrans_size;
+
+ pohmelfs_ftrans[idx] = i;
+ }
+}
+
+int pohmelfs_ftrans_check(u64 id)
+{
+ if (pohmelfs_ftrans) {
+ u32 i = id & 0xffffffff;
+ int idx = i % pohmelfs_ftrans_size;
+
+ return (pohmelfs_ftrans[idx] == i);
+ }
+
+ return -1;
+}
+
+/*
+ * Async machinery lives here.
+ * All commands being sent to server do _not_ require sync reply,
+ * instead, if it is really needed, like readdir or readpage, caller
+ * sleeps waiting for data, which will be placed into provided buffer
+ * and caller will be awakened.
+ *
+ * Every command response can come without some listener. For example
+ * readdir response will add new objects into cache without appropriate
+ * request from userspace. This is used in cache coherency.
+ *
+ * If object is not found for given data, it is discarded.
+ *
+ * All requests are received by dedicated kernel thread.
+ */
+
+/*
+ * Basic network sending/receiving functions.
+ * Blocked mode is used.
+ */
+static int netfs_data_recv(struct netfs_state *st, void *buf, u64 size)
+{
+ struct msghdr msg;
+ struct kvec iov;
+ int err;
+
+ BUG_ON(!size);
+
+ iov.iov_base = buf;
+ iov.iov_len = size;
+
+ msg.msg_iov = (struct iovec *)&iov;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_DONTWAIT;
+
+ err = kernel_recvmsg(st->socket, &msg, &iov, 1, iov.iov_len,
+ msg.msg_flags);
+ if (err <= 0) {
+ printk("%s: failed to recv data: size: %llu, err: %d.\n", __func__, size, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ }
+
+ return err;
+}
+
+static int pohmelfs_data_recv(struct netfs_state *st, void *data, unsigned int size)
+{
+ unsigned int revents = 0;
+ unsigned int err_mask = POLLERR | POLLHUP | POLLRDHUP;
+ unsigned int mask = err_mask | POLLIN;
+ int err = 0;
+
+ while (size && !err) {
+ revents = netfs_state_poll(st);
+
+ if (!(revents & mask)) {
+ DEFINE_WAIT(wait);
+
+ for (;;) {
+ prepare_to_wait(&st->thread_wait, &wait, TASK_INTERRUPTIBLE);
+ if (kthread_should_stop())
+ break;
+
+ revents = netfs_state_poll(st);
+
+ if (revents & mask)
+ break;
+
+ if (signal_pending(current))
+ break;
+
+ schedule();
+ continue;
+ }
+ finish_wait(&st->thread_wait, &wait);
+ }
+
+ err = 0;
+ netfs_state_lock(st);
+ if (st->socket && (st->read_socket == st->socket) && (revents & POLLIN)) {
+ err = netfs_data_recv(st, data, size);
+ if (err > 0) {
+ data += err;
+ size -= err;
+ err = 0;
+ } else if (err == 0)
+ err = -ECONNRESET;
+ }
+
+ if (revents & err_mask) {
+ printk("%s: revents: %x, socket: %p, size: %u, err: %d.\n",
+ __func__, revents, st->socket, size, err);
+ err = -ECONNRESET;
+ }
+ netfs_state_unlock(st);
+
+ if (err < 0) {
+ if (netfs_state_trylock_send(st)) {
+ netfs_state_exit(st);
+ err = netfs_state_init(st);
+ if (!err)
+ err = -EAGAIN;
+ netfs_state_unlock_send(st);
+ } else {
+ st->need_reset = 1;
+ }
+ }
+
+ if (kthread_should_stop())
+ err = -ENODEV;
+
+ if (err)
+ printk("%s: socket: %p, read_socket: %p, revents: %x, rev_error: %d, "
+ "should_stop: %d, size: %u, err: %d.\n",
+ __func__, st->socket, st->read_socket,
+ revents, revents & err_mask, kthread_should_stop(), size, err);
+ }
+
+ return err;
+}
+
+int pohmelfs_data_recv_and_check(struct netfs_state *st, void *data, unsigned int size)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ int err;
+
+ err = pohmelfs_data_recv(st, data, size);
+ if (err)
+ return err;
+
+ return pohmelfs_crypto_process_input_data(&st->eng, cmd->iv, data, NULL, size);
+}
+
+/*
+ * Polling machinery.
+ */
+
+struct netfs_poll_helper
+{
+ poll_table pt;
+ struct netfs_state *st;
+};
+
+static int netfs_queue_wake(wait_queue_t *wait, unsigned mode, int sync, void *key)
+{
+ struct netfs_state *st = container_of(wait, struct netfs_state, wait);
+
+ wake_up(&st->thread_wait);
+ return 1;
+}
+
+static void netfs_queue_func(struct file *file, wait_queue_head_t *whead,
+ poll_table *pt)
+{
+ struct netfs_state *st = container_of(pt, struct netfs_poll_helper, pt)->st;
+
+ st->whead = whead;
+ init_waitqueue_func_entry(&st->wait, netfs_queue_wake);
+ add_wait_queue(whead, &st->wait);
+}
+
+static void netfs_poll_exit(struct netfs_state *st)
+{
+ if (st->whead) {
+ remove_wait_queue(st->whead, &st->wait);
+ st->whead = NULL;
+ }
+}
+
+static int netfs_poll_init(struct netfs_state *st)
+{
+ struct netfs_poll_helper ph;
+
+ ph.st = st;
+ init_poll_funcptr(&ph.pt, &netfs_queue_func);
+
+ st->socket->ops->poll(NULL, st->socket, &ph.pt);
+ return 0;
+}
+
+/*
+ * Get response for readpage command. We search inode and page in its mapping
+ * and copy data into. If it was async request, then we queue page into shared
+ * data and wakeup listener, who will copy it to userspace.
+ *
+ * There is a work in progress of allowing to call copy_to_user() directly from
+ * async receiving kernel thread.
+ */
+static int pohmelfs_read_page_response(struct netfs_state *st)
+{
+ struct pohmelfs_sb *psb = st->psb;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct inode *inode;
+ struct page *page;
+ int err = 0;
+
+ if (cmd->size > PAGE_CACHE_SIZE) {
+ err = -EINVAL;
+ goto err_out_exit;
+ }
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+ err = -ENOENT;
+ goto err_out_exit;
+ }
+
+ page = find_get_page(inode->i_mapping, cmd->start >> PAGE_CACHE_SHIFT);
+ if (!page || !PageLocked(page)) {
+ printk("%s: failed to find/lock page: page: %p, id: %llu, start: %llu, index: %llu.\n",
+ __func__, page, cmd->id, cmd->start, cmd->start >> PAGE_CACHE_SHIFT);
+
+ while (cmd->size) {
+ unsigned int sz = min(cmd->size, st->size);
+
+ err = pohmelfs_data_recv(st, st->data, sz);
+ if (err)
+ break;
+
+ cmd->size -= sz;
+ }
+
+ err = -ENODEV;
+ if (page)
+ goto err_out_page_put;
+ goto err_out_put;
+ }
+
+ if (cmd->size) {
+ void *addr;
+
+ addr = kmap(page);
+ err = pohmelfs_data_recv(st, addr, cmd->size);
+ kunmap(page);
+
+ if (err)
+ goto err_out_page_unlock;
+ }
+
+ dprintk("%s: page: %p, start: %llu, size: %u, locked: %d.\n",
+ __func__, page, cmd->start, cmd->size, PageLocked(page));
+
+ SetPageChecked(page);
+ if ((psb->hash_string || psb->cipher_string) && psb->perform_crypto && cmd->size) {
+ err = pohmelfs_crypto_process_input_page(&st->eng, page, cmd->size, cmd->iv);
+ if (err < 0)
+ goto err_out_page_unlock;
+ } else {
+ SetPageUptodate(page);
+ unlock_page(page);
+ page_cache_release(page);
+ }
+
+ pohmelfs_put_inode(POHMELFS_I(inode));
+ wake_up(&st->psb->wait);
+
+ return 0;
+
+err_out_page_unlock:
+ SetPageError(page);
+ unlock_page(page);
+err_out_page_put:
+ page_cache_release(page);
+err_out_put:
+ pohmelfs_put_inode(POHMELFS_I(inode));
+err_out_exit:
+ wake_up(&st->psb->wait);
+ return err;
+}
+
+static int pohmelfs_check_name(struct pohmelfs_inode *parent, struct qstr *str,
+ struct netfs_inode_info *info)
+{
+ struct inode *inode;
+ struct pohmelfs_name *n;
+ int err = 0;
+ u64 ino = 0;
+
+ mutex_lock(&parent->offset_lock);
+ n = pohmelfs_search_hash(parent, str->hash);
+ if (n)
+ ino = n->ino;
+ mutex_unlock(&parent->offset_lock);
+
+ if (!ino)
+ goto out;
+
+ inode = ilookup(parent->vfs_inode.i_sb, ino);
+ if (!inode)
+ goto out;
+
+ dprintk("%s: parent: %llu, inode: %llu.\n", __func__, parent->ino, ino);
+
+ pohmelfs_fill_inode(inode, info);
+ pohmelfs_put_inode(POHMELFS_I(inode));
+ err = -EEXIST;
+out:
+ return err;
+}
+
+/*
+ * Readdir response from server. If special field is set, we wakeup
+ * listener (readdir() call), which will copy data to userspace.
+ */
+static int pohmelfs_readdir_response(struct netfs_state *st)
+{
+ struct inode *inode;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_inode_info *info;
+ struct pohmelfs_inode *parent = NULL, *npi;
+ int err = 0, last = cmd->ext;
+ struct qstr str;
+
+ if (cmd->size > st->size)
+ return -EINVAL;
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+ parent = POHMELFS_I(inode);
+
+ if (!cmd->size && cmd->start) {
+ err = -cmd->start;
+ goto out;
+ }
+
+ if (cmd->size) {
+ char *name;
+
+ err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+ if (err)
+ goto err_out_put;
+
+ info = (struct netfs_inode_info *)(st->data);
+
+ name = (char *)(info + 1);
+ str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
+ name[str.len] = 0;
+ str.name = name;
+ str.hash = jhash(str.name, str.len, 0);
+
+ netfs_convert_inode_info(info);
+
+ if (parent) {
+ err = pohmelfs_check_name(parent, &str, info);
+ if (err) {
+ if (err == -EEXIST)
+ err = 0;
+ goto out;
+ }
+ }
+
+ info->ino = cmd->start;
+ if (!info->ino)
+ info->ino = pohmelfs_new_ino(st->psb);
+
+ dprintk("%s: parent: %llu, ino: %llu, name: '%s', hash: %x, len: %u, mode: %o.\n",
+ __func__, parent->ino, info->ino, str.name, str.hash, str.len,
+ info->mode);
+
+ npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+
+ if (err != -EEXIST)
+ goto err_out_put;
+ } else {
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
+ clear_bit(NETFS_INODE_OWNED, &npi->state);
+ }
+ }
+out:
+ if (last) {
+ set_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &parent->state);
+ wake_up(&st->psb->wait);
+ }
+ pohmelfs_put_inode(parent);
+
+ return err;
+
+err_out_put:
+ clear_bit(NETFS_INODE_REMOTE_DIR_SYNCED, &parent->state);
+ printk("%s: parent: %llu, ino: %llu, cmd_id: %llu.\n", __func__, parent->ino, cmd->start, cmd->id);
+ pohmelfs_put_inode(parent);
+ wake_up(&st->psb->wait);
+ return err;
+}
+
+/*
+ * Lookup command response.
+ * It searches for inode to be looked at (if it exists) and substitutes
+ * its inode information (size, permission, mode and so on), if inode does
+ * not exist, new one will be created and inserted into caches.
+ */
+static int pohmelfs_lookup_response(struct netfs_state *st)
+{
+ struct inode *inode = NULL;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_inode_info *info;
+ struct pohmelfs_inode *parent = NULL, *npi;
+ int err = -EINVAL;
+ char *name;
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: lookup response: id: %llu, start: %llu, size: %u.\n",
+ __func__, cmd->id, cmd->start, cmd->size);
+ err = -ENOENT;
+ goto err_out_exit;
+ }
+ parent = POHMELFS_I(inode);
+
+ if (!cmd->size) {
+ err = -cmd->start;
+ goto err_out_put;
+ }
+
+ if (cmd->size < sizeof(struct netfs_inode_info)) {
+ printk("%s: broken lookup response: id: %llu, start: %llu, size: %u.\n",
+ __func__, cmd->id, cmd->start, cmd->size);
+ err = -EINVAL;
+ goto err_out_put;
+ }
+
+ err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+ if (err)
+ goto err_out_put;
+
+ info = (struct netfs_inode_info *)(st->data);
+ name = (char *)(info + 1);
+
+ netfs_convert_inode_info(info);
+
+ info->ino = cmd->start;
+ if (!info->ino)
+ info->ino = pohmelfs_new_ino(st->psb);
+
+ dprintk("%s: parent: %llu, ino: %llu, name: '%s', start: %llu.\n",
+ __func__, parent->ino, info->ino, name, cmd->start);
+
+ if (cmd->start)
+ npi = pohmelfs_new_inode(st->psb, parent, NULL, info, 0);
+ else {
+ struct qstr str;
+
+ str.name = name;
+ str.len = cmd->size - sizeof(struct netfs_inode_info) - 1 - cmd->cpad;
+ str.hash = jhash(name, str.len, 0);
+
+ npi = pohmelfs_new_inode(st->psb, parent, &str, info, 0);
+ }
+ if (IS_ERR(npi)) {
+ err = PTR_ERR(npi);
+
+ if (err != -EEXIST)
+ goto err_out_put;
+ } else {
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &npi->state);
+ clear_bit(NETFS_INODE_OWNED, &npi->state);
+ }
+
+ clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+ pohmelfs_put_inode(parent);
+
+ wake_up(&st->psb->wait);
+
+ return 0;
+
+err_out_put:
+ pohmelfs_put_inode(parent);
+err_out_exit:
+ clear_bit(NETFS_COMMAND_PENDING, &parent->state);
+ wake_up(&st->psb->wait);
+ printk("%s: inode: %p, id: %llu, start: %llu, size: %u, err: %d.\n",
+ __func__, inode, cmd->id, cmd->start, cmd->size, err);
+ return err;
+}
+
+/*
+ * Create response, just marks local inode as 'created', so that writeback
+ * for any of its children (or own) would not try to sync it again.
+ */
+static int pohmelfs_create_response(struct netfs_state *st)
+{
+ struct inode *inode;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct pohmelfs_inode *pi;
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu, start: %llu.\n",
+ __func__, cmd->id, cmd->start);
+ goto err_out_exit;
+ }
+
+ pi = POHMELFS_I(inode);
+
+ /*
+ * To lock or not to lock?
+ * We actually do not care if it races...
+ */
+ if (cmd->start)
+ make_bad_inode(inode);
+ set_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state);
+
+ pohmelfs_put_inode(pi);
+
+ wake_up(&st->psb->wait);
+ return 0;
+
+err_out_exit:
+ wake_up(&st->psb->wait);
+ return -ENOENT;
+}
+
+/*
+ * Object remove response. Just says that remove request has been received.
+ * Used in cache coherency protocol.
+ */
+static int pohmelfs_remove_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ int err;
+
+ err = pohmelfs_data_recv_and_check(st, st->data, cmd->size);
+ if (err)
+ return err;
+
+ dprintk("%s: parent: %llu, path: '%s'.\n", __func__, cmd->id, (char *)st->data);
+
+ return 0;
+}
+
+/*
+ * Transaction reply processing.
+ *
+ * Find transaction based on its generation number, bump its reference counter,
+ * so that none could free it under us, drop from the trees and lists and
+ * drop reference counter. When it hits zero (when all destinations replied
+ * and all timeout handled by async scanning code), completion will be called
+ * and transaction will be freed.
+ */
+static int pohmelfs_transaction_response(struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst;
+ struct netfs_trans *t = NULL;
+ struct netfs_cmd *cmd = &st->cmd;
+ short err = (signed)cmd->ext;
+
+ mutex_lock(&st->trans_lock);
+ dst = netfs_trans_search(st, cmd->start);
+ if (dst) {
+ netfs_trans_remove_nolock(dst, st);
+ t = dst->trans;
+
+ pohmelfs_ftrans_update(cmd->start);
+ }
+ mutex_unlock(&st->trans_lock);
+
+ if (!t) {
+ int check = pohmelfs_ftrans_check(cmd->start);
+ printk("%s: failed to find transaction: start: %llu: id: %llu, size: %u, ext: %u, double: %d.\n",
+ __func__, cmd->start, cmd->id, cmd->size, cmd->ext, check);
+ err = -EINVAL;
+ goto out;
+ }
+
+ t->result = err;
+ netfs_trans_drop_dst_nostate(dst);
+
+out:
+ wake_up(&st->psb->wait);
+ return err;
+}
+
+/*
+ * Inode metadata cache coherency message.
+ */
+static int pohmelfs_page_cache_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ struct inode *inode;
+
+ dprintk("%s: st: %p, id: %llu, start: %llu, size: %u.\n", __func__, st, cmd->id, cmd->start, cmd->size);
+
+ inode = ilookup(st->psb->sb, cmd->id);
+ if (!inode) {
+ printk("%s: failed to find inode: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+
+ set_bit(NETFS_INODE_NEED_FLUSH, &POHMELFS_I(inode)->state);
+ pohmelfs_put_inode(POHMELFS_I(inode));
+
+ return 0;
+}
+
+/*
+ * Root capabilities response: export statistics
+ * like used and available size, number of files and dirs,
+ * permissions.
+ */
+static int pohmelfs_root_cap_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_root_capabilities *cap;
+ struct pohmelfs_sb *psb = st->psb;
+
+ if (cmd->size != sizeof(struct netfs_root_capabilities)) {
+ psb->flags = EPROTO;
+ wake_up(&psb->wait);
+ return -EPROTO;
+ }
+
+ cap = st->data;
+
+ netfs_convert_root_capabilities(cap);
+
+ if (psb->total_size < cap->used + cap->avail)
+ psb->total_size = cap->used + cap->avail;
+ if (cap->avail)
+ psb->avail_size = cap->avail;
+ psb->state_flags = cap->flags;
+
+ if (psb->state_flags & POHMELFS_FLAGS_RO) {
+ psb->sb->s_flags |= MS_RDONLY;
+ printk(KERN_INFO "Mounting POHMELFS (%d) read-only.\n", psb->idx);
+ }
+
+ if (psb->state_flags & POHMELFS_FLAGS_XATTR)
+ printk(KERN_INFO "Mounting POHMELFS (%d) "
+ "with extended attributes support.\n", psb->idx);
+
+ if (atomic_read(&psb->total_inodes) <= 1)
+ atomic_long_set(&psb->total_inodes, cap->nr_files);
+
+ dprintk("%s: total: %llu, avail: %llu, flags: %llx, inodes: %llu.\n",
+ __func__, psb->total_size, psb->avail_size, psb->state_flags, cap->nr_files);
+
+ psb->flags = 0;
+ wake_up(&psb->wait);
+ return 0;
+}
+
+/*
+ * Crypto capabilities of the server, where it says that
+ * it supports or does not requested hash/cipher algorithms.
+ */
+static int pohmelfs_crypto_cap_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ struct netfs_crypto_capabilities *cap;
+ struct pohmelfs_sb *psb = st->psb;
+ int err = 0;
+
+ if (cmd->size != sizeof(struct netfs_crypto_capabilities)) {
+ psb->flags = EPROTO;
+ wake_up(&psb->wait);
+ return -EPROTO;
+ }
+
+ cap = st->data;
+
+ dprintk("%s: cipher '%s': %s, hash: '%s': %s.\n",
+ __func__,
+ psb->cipher_string, (cap->cipher_strlen)?"SUPPORTED":"NOT SUPPORTED",
+ psb->hash_string, (cap->hash_strlen)?"SUPPORTED":"NOT SUPPORTED");
+
+ if (!cap->hash_strlen) {
+ if (psb->hash_strlen && psb->crypto_fail_unsupported)
+ err = -ENOTSUPP;
+ psb->hash_strlen = 0;
+ kfree(psb->hash_string);
+ psb->hash_string = NULL;
+ }
+
+ if (!cap->cipher_strlen) {
+ if (psb->cipher_strlen && psb->crypto_fail_unsupported)
+ err = -ENOTSUPP;
+ psb->cipher_strlen = 0;
+ kfree(psb->cipher_string);
+ psb->cipher_string = NULL;
+ }
+
+ return err;
+}
+
+/*
+ * Capabilities handshake response.
+ */
+static int pohmelfs_capabilities_response(struct netfs_state *st)
+{
+ struct netfs_cmd *cmd = &st->cmd;
+ int err = 0;
+
+ err = pohmelfs_data_recv(st, st->data, cmd->size);
+ if (err)
+ return err;
+
+ switch (cmd->id) {
+ case POHMELFS_CRYPTO_CAPABILITIES:
+ return pohmelfs_crypto_cap_response(st);
+ case POHMELFS_ROOT_CAPABILITIES:
+ return pohmelfs_root_cap_response(st);
+ default:
+ break;
+ }
+ return -EINVAL;
+}
+
+/*
+ * Receiving extended attribute.
+ * Does not work properly if received size is more than requested one,
+ * it should not happen with current request/reply model though.
+ */
+static int pohmelfs_getxattr_response(struct netfs_state *st)
+{
+ struct pohmelfs_sb *psb = st->psb;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct pohmelfs_mcache *m;
+ short error = (signed short)cmd->ext, err;
+ unsigned int sz, total_size;
+
+ m = pohmelfs_mcache_search(psb, cmd->id);
+
+ dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
+ __func__, cmd->id, (m)?m->gen:0, error);
+
+ if (!m) {
+ printk("%s: failed to find getxattr cache entry: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+
+ if (cmd->size) {
+ sz = min_t(unsigned int, cmd->size, m->size);
+ err = pohmelfs_data_recv_and_check(st, m->data, sz);
+ if (err) {
+ error = err;
+ goto out;
+ }
+
+ m->size = sz;
+ total_size = cmd->size - sz;
+
+ while (total_size) {
+ sz = min(total_size, st->size);
+
+ err = pohmelfs_data_recv_and_check(st, st->data, sz);
+ if (err) {
+ error = err;
+ break;
+ }
+
+ total_size -= sz;
+ }
+ }
+
+out:
+ m->err = error;
+ complete(&m->complete);
+ pohmelfs_mcache_put(psb, m);
+
+ return error;
+}
+
+int pohmelfs_data_lock_response(struct netfs_state *st)
+{
+ struct pohmelfs_sb *psb = st->psb;
+ struct netfs_cmd *cmd = &st->cmd;
+ struct pohmelfs_mcache *m;
+ short err = (signed short)cmd->ext;
+ u64 id = cmd->id;
+
+ m = pohmelfs_mcache_search(psb, id);
+
+ dprintk("%s: id: %llu, gen: %llu, err: %d.\n",
+ __func__, cmd->id, (m)?m->gen:0, err);
+
+ if (!m) {
+ pohmelfs_data_recv(st, st->data, cmd->size);
+ printk("%s: failed to find data lock response: id: %llu.\n", __func__, cmd->id);
+ return -ENOENT;
+ }
+
+ if (cmd->size)
+ err = pohmelfs_data_recv_and_check(st, &m->info, cmd->size);
+
+ m->err = err;
+ complete(&m->complete);
+ pohmelfs_mcache_put(psb, m);
+
+ return err;
+}
+
+static void __inline__ netfs_state_reset(struct netfs_state *st)
+{
+ netfs_state_lock_send(st);
+ netfs_state_exit(st);
+ netfs_state_init(st);
+ netfs_state_unlock_send(st);
+}
+
+/*
+ * Main receiving function, called from dedicated kernel thread.
+ */
+static int pohmelfs_recv(void *data)
+{
+ int err = -EINTR;
+ struct netfs_state *st = data;
+ struct netfs_cmd *cmd = &st->cmd;
+
+ while (!kthread_should_stop()) {
+ /*
+ * If socket will be reset after this statement, then
+ * pohmelfs_data_recv() will just fail and loop will
+ * start again, so it can be done without any locks.
+ *
+ * st->read_socket is needed to prevents state machine
+ * breaking between this data reading and subsequent one
+ * in protocol specific functions during connection reset.
+ * In case of reset we have to read next command and do
+ * not expect data for old command to magically appear in
+ * new connection.
+ */
+ st->read_socket = st->socket;
+ err = pohmelfs_data_recv(st, cmd, sizeof(struct netfs_cmd));
+ if (err) {
+ msleep(1000);
+ continue;
+ }
+
+ netfs_convert_cmd(cmd);
+
+ dprintk("%s: cmd: %u, id: %llu, start: %llu, size: %u, "
+ "ext: %u, csize: %u, cpad: %u.\n",
+ __func__, cmd->cmd, cmd->id, cmd->start,
+ cmd->size, cmd->ext, cmd->csize, cmd->cpad);
+
+ if (cmd->csize) {
+ struct pohmelfs_crypto_engine *e = &st->eng;
+
+ if (unlikely(cmd->csize > e->size/2)) {
+ netfs_state_reset(st);
+ continue;
+ }
+
+ if (e->hash && unlikely(cmd->csize != st->psb->crypto_attached_size)) {
+ dprintk("%s: cmd: cmd: %u, id: %llu, start: %llu, size: %u, "
+ "csize: %u != digest size %u.\n",
+ __func__, cmd->cmd, cmd->id, cmd->start, cmd->size,
+ cmd->csize, st->psb->crypto_attached_size);
+ netfs_state_reset(st);
+ continue;
+ }
+
+ err = pohmelfs_data_recv(st, e->data, cmd->csize);
+ if (err) {
+ netfs_state_reset(st);
+ continue;
+ }
+
+#ifdef CONFIG_POHMELFS_DEBUG
+ {
+ unsigned int i;
+ unsigned char *hash = e->data;
+
+ dprintk("%s: received hash: ", __func__);
+ for (i=0; i<cmd->csize; ++i) {
+ printk("%02x ", hash[i]);
+ }
+ printk("\n");
+ }
+#endif
+ cmd->size -= cmd->csize;
+ }
+
+ /*
+ * This should catch protocol breakage and random garbage instead of commands.
+ */
+ if (unlikely((cmd->size > st->size) && (cmd->cmd != NETFS_XATTR_GET))) {
+ netfs_state_reset(st);
+ continue;
+ }
+
+ switch (cmd->cmd) {
+ case NETFS_READ_PAGE:
+ err = pohmelfs_read_page_response(st);
+ break;
+ case NETFS_READDIR:
+ err = pohmelfs_readdir_response(st);
+ break;
+ case NETFS_LOOKUP:
+ err = pohmelfs_lookup_response(st);
+ break;
+ case NETFS_CREATE:
+ err = pohmelfs_create_response(st);
+ break;
+ case NETFS_REMOVE:
+ err = pohmelfs_remove_response(st);
+ break;
+ case NETFS_TRANS:
+ err = pohmelfs_transaction_response(st);
+ break;
+ case NETFS_PAGE_CACHE:
+ err = pohmelfs_page_cache_response(st);
+ break;
+ case NETFS_CAPABILITIES:
+ err = pohmelfs_capabilities_response(st);
+ break;
+ case NETFS_LOCK:
+ err = pohmelfs_data_lock_response(st);
+ break;
+ case NETFS_XATTR_GET:
+ err = pohmelfs_getxattr_response(st);
+ break;
+ default:
+ printk("%s: wrong cmd: %u, id: %llu, start: %llu, size: %u, ext: %u.\n",
+ __func__, cmd->cmd, cmd->id, cmd->start, cmd->size, cmd->ext);
+ netfs_state_reset(st);
+ break;
+ }
+ }
+
+ while (!kthread_should_stop())
+ schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+
+ return err;
+}
+
+int netfs_state_init(struct netfs_state *st)
+{
+ int err;
+ struct pohmelfs_ctl *ctl = &st->ctl;
+
+ err = sock_create(ctl->addr.sa_family, ctl->type, ctl->proto, &st->socket);
+ if (err) {
+ printk("%s: failed to create a socket: family: %d, type: %d, proto: %d, err: %d.\n",
+ __func__, ctl->addr.sa_family, ctl->type, ctl->proto, err);
+ goto err_out_exit;
+ }
+
+ st->socket->sk->sk_allocation = GFP_NOIO;
+ st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
+
+ err = kernel_connect(st->socket, (struct sockaddr *)&ctl->addr, ctl->addrlen, 0);
+ if (err) {
+ printk("%s: failed to connect to server: idx: %u, err: %d.\n",
+ __func__, st->psb->idx, err);
+ goto err_out_release;
+ }
+ st->socket->sk->sk_sndtimeo = st->socket->sk->sk_rcvtimeo = msecs_to_jiffies(60000);
+
+ err = netfs_poll_init(st);
+ if (err)
+ goto err_out_release;
+
+ if (st->socket->ops->family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&ctl->addr;
+ printk(KERN_INFO "%s: (re)connected to peer %u.%u.%u.%u:%d.\n", __func__,
+ NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (st->socket->ops->family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&ctl->addr;
+ printk(KERN_INFO "%s: (re)connected to peer "
+ "%pi6:%d",
+ __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+ }
+
+ return 0;
+
+err_out_release:
+ sock_release(st->socket);
+err_out_exit:
+ st->socket = NULL;
+ return err;
+}
+
+void netfs_state_exit(struct netfs_state *st)
+{
+ if (st->socket) {
+ netfs_poll_exit(st);
+ st->socket->ops->shutdown(st->socket, 2);
+
+ if (st->socket->ops->family == AF_INET) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&st->ctl.addr;
+ printk("%s: disconnected from peer %u.%u.%u.%u:%d.\n", __func__,
+ NIPQUAD(sin->sin_addr.s_addr), ntohs(sin->sin_port));
+ } else if (st->socket->ops->family == AF_INET6) {
+ struct sockaddr_in6 *sin = (struct sockaddr_in6 *)&st->ctl.addr;
+ printk("%s: disconnected from peer "
+ "%pi6:%d",
+ __func__, &sin->sin6_addr, ntohs(sin->sin6_port));
+ }
+
+ sock_release(st->socket);
+ st->socket = NULL;
+ st->read_socket = NULL;
+ st->need_reset = 0;
+ }
+}
+
+int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf)
+{
+ struct netfs_state *st = &conf->state;
+ int err = -ENOMEM;
+
+ mutex_init(&st->__state_lock);
+ mutex_init(&st->__state_send_lock);
+ init_waitqueue_head(&st->thread_wait);
+
+ st->psb = psb;
+ st->trans_root = RB_ROOT;
+ mutex_init(&st->trans_lock);
+
+ st->size = psb->trans_data_size;
+ st->data = kmalloc(st->size, GFP_KERNEL);
+ if (!st->data)
+ goto err_out_exit;
+
+ if (psb->perform_crypto) {
+ err = pohmelfs_crypto_engine_init(&st->eng, psb);
+ if (err)
+ goto err_out_free_data;
+ }
+
+ err = netfs_state_init(st);
+ if (err)
+ goto err_out_free_engine;
+
+ st->thread = kthread_run(pohmelfs_recv, st, "pohmelfs/%u", psb->idx);
+ if (IS_ERR(st->thread)) {
+ err = PTR_ERR(st->thread);
+ goto err_out_netfs_exit;
+ }
+
+ if (!psb->active_state)
+ psb->active_state = conf;
+
+ dprintk("%s: conf: %p, st: %p, socket: %p.\n",
+ __func__, conf, st, st->socket);
+ return 0;
+
+err_out_netfs_exit:
+ netfs_state_exit(st);
+err_out_free_engine:
+ pohmelfs_crypto_engine_exit(&st->eng);
+err_out_free_data:
+ kfree(st->data);
+err_out_exit:
+ return err;
+
+}
+
+void pohmelfs_state_flush_transactions(struct netfs_state *st)
+{
+ struct rb_node *rb_node;
+ struct netfs_trans_dst *dst;
+
+ mutex_lock(&st->trans_lock);
+ for (rb_node = rb_first(&st->trans_root); rb_node; ) {
+ dst = rb_entry(rb_node, struct netfs_trans_dst, state_entry);
+ rb_node = rb_next(rb_node);
+
+ dst->trans->result = -EINVAL;
+ netfs_trans_remove_nolock(dst, st);
+ netfs_trans_drop_dst_nostate(dst);
+ }
+ mutex_unlock(&st->trans_lock);
+}
+
+static void pohmelfs_state_exit_one(struct pohmelfs_config *c)
+{
+ struct netfs_state *st = &c->state;
+
+ dprintk("%s: exiting, st: %p.\n", __func__, st);
+ if (st->thread) {
+ kthread_stop(st->thread);
+ st->thread = NULL;
+ }
+
+ netfs_state_lock_send(st);
+ netfs_state_exit(st);
+ netfs_state_unlock_send(st);
+
+ pohmelfs_state_flush_transactions(st);
+
+ pohmelfs_crypto_engine_exit(&st->eng);
+ kfree(st->data);
+
+ kfree(c);
+}
+
+/*
+ * Initialize network stack. It searches for given ID in global
+ * configuration table, this contains information of the remote server
+ * (address (any supported by socket interface) and port, protocol and so on).
+ */
+int pohmelfs_state_init(struct pohmelfs_sb *psb)
+{
+ int err = -ENOMEM;
+
+ err = pohmelfs_copy_config(psb);
+ if (err) {
+ pohmelfs_state_exit(psb);
+ return err;
+ }
+
+ return 0;
+}
+
+void pohmelfs_state_exit(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c, *tmp;
+
+ list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
+ list_del(&c->config_entry);
+ pohmelfs_state_exit_one(c);
+ }
+}
+
+void pohmelfs_switch_active(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c = psb->active_state;
+
+ if (!list_empty(&psb->state_list)) {
+ if (c->config_entry.next != &psb->state_list) {
+ psb->active_state = list_entry(c->config_entry.next,
+ struct pohmelfs_config, config_entry);
+ } else {
+ psb->active_state = list_entry(psb->state_list.next,
+ struct pohmelfs_config, config_entry);
+ }
+
+ dprintk("%s: empty: %d, active %p -> %p.\n",
+ __func__, list_empty(&psb->state_list), c,
+ psb->active_state);
+ } else
+ psb->active_state = NULL;
+}
+
+void pohmelfs_check_states(struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c, *tmp;
+ LIST_HEAD(delete_list);
+
+ mutex_lock(&psb->state_lock);
+ list_for_each_entry_safe(c, tmp, &psb->state_list, config_entry) {
+ if (pohmelfs_config_check(c, psb->idx)) {
+
+ if (psb->active_state == c)
+ pohmelfs_switch_active(psb);
+ list_move(&c->config_entry, &delete_list);
+ }
+ }
+ pohmelfs_copy_config(psb);
+ mutex_unlock(&psb->state_lock);
+
+ list_for_each_entry_safe(c, tmp, &delete_list, config_entry) {
+ list_del(&c->config_entry);
+ pohmelfs_state_exit_one(c);
+ }
+}
diff --git a/drivers/staging/pohmelfs/netfs.h b/drivers/staging/pohmelfs/netfs.h
new file mode 100644
index 00000000000..2ff21ae5bb1
--- /dev/null
+++ b/drivers/staging/pohmelfs/netfs.h
@@ -0,0 +1,932 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __NETFS_H
+#define __NETFS_H
+
+#include <linux/types.h>
+#include <linux/connector.h>
+
+#define POHMELFS_CN_IDX 5
+#define POHMELFS_CN_VAL 0
+
+#define POHMELFS_CTLINFO_ACK 1
+#define POHMELFS_NOINFO_ACK 2
+
+
+/*
+ * Network command structure.
+ * Will be extended.
+ */
+struct netfs_cmd
+{
+ __u16 cmd; /* Command number */
+ __u16 csize; /* Attached crypto information size */
+ __u16 cpad; /* Attached padding size */
+ __u16 ext; /* External flags */
+ __u32 size; /* Size of the attached data */
+ __u32 trans; /* Transaction id */
+ __u64 id; /* Object ID to operate on. Used for feedback.*/
+ __u64 start; /* Start of the object. */
+ __u64 iv; /* IV sequence */
+ __u8 data[0];
+};
+
+static inline void netfs_convert_cmd(struct netfs_cmd *cmd)
+{
+ cmd->id = __be64_to_cpu(cmd->id);
+ cmd->start = __be64_to_cpu(cmd->start);
+ cmd->iv = __be64_to_cpu(cmd->iv);
+ cmd->cmd = __be16_to_cpu(cmd->cmd);
+ cmd->ext = __be16_to_cpu(cmd->ext);
+ cmd->csize = __be16_to_cpu(cmd->csize);
+ cmd->cpad = __be16_to_cpu(cmd->cpad);
+ cmd->size = __be32_to_cpu(cmd->size);
+}
+
+#define NETFS_TRANS_SINGLE_DST (1<<0)
+
+enum {
+ NETFS_READDIR = 1, /* Read directory for given inode number */
+ NETFS_READ_PAGE, /* Read data page from the server */
+ NETFS_WRITE_PAGE, /* Write data page to the server */
+ NETFS_CREATE, /* Create directory entry */
+ NETFS_REMOVE, /* Remove directory entry */
+
+ NETFS_LOOKUP, /* Lookup single object */
+ NETFS_LINK, /* Create a link */
+ NETFS_TRANS, /* Transaction */
+ NETFS_OPEN, /* Open intent */
+ NETFS_INODE_INFO, /* Metadata cache coherency synchronization message */
+
+ NETFS_PAGE_CACHE, /* Page cache invalidation message */
+ NETFS_READ_PAGES, /* Read multiple contiguous pages in one go */
+ NETFS_RENAME, /* Rename object */
+ NETFS_CAPABILITIES, /* Capabilities of the client, for example supported crypto */
+ NETFS_LOCK, /* Distributed lock message */
+
+ NETFS_XATTR_SET, /* Set extended attribute */
+ NETFS_XATTR_GET, /* Get extended attribute */
+ NETFS_CMD_MAX
+};
+
+enum {
+ POHMELFS_FLAGS_ADD = 0, /* Network state control message for ADD */
+ POHMELFS_FLAGS_DEL, /* Network state control message for DEL */
+ POHMELFS_FLAGS_SHOW, /* Network state control message for SHOW */
+ POHMELFS_FLAGS_CRYPTO, /* Crypto data control message */
+};
+
+/*
+ * Always wanted to copy it from socket headers into public one,
+ * since they are __KERNEL__ protected there.
+ */
+#define _K_SS_MAXSIZE 128
+
+struct saddr
+{
+ unsigned short sa_family;
+ char addr[_K_SS_MAXSIZE];
+};
+
+enum {
+ POHMELFS_CRYPTO_HASH = 0,
+ POHMELFS_CRYPTO_CIPHER,
+};
+
+struct pohmelfs_crypto
+{
+ unsigned int idx; /* Config index */
+ unsigned short strlen; /* Size of the attached crypto string including 0-byte
+ * "cbc(aes)" for example */
+ unsigned short type; /* HMAC, cipher, both */
+ unsigned int keysize; /* Key size */
+ unsigned char data[0]; /* Algorithm string, key and IV */
+};
+
+/*
+ * Configuration command used to create table of different remote servers.
+ */
+struct pohmelfs_ctl
+{
+ unsigned int idx; /* Config index */
+ unsigned int type; /* Socket type */
+ unsigned int proto; /* Socket protocol */
+ unsigned int addrlen; /* Size of the address */
+ unsigned short unused; /* Align structure by 4 bytes */
+ struct saddr addr; /* Remote server address */
+};
+
+/*
+ * Ack for userspace about requested command.
+ */
+struct pohmelfs_cn_ack
+{
+ struct cn_msg msg;
+ int error;
+ int msg_num;
+ int unused[3];
+ struct pohmelfs_ctl ctl;
+};
+
+/*
+ * Inode info structure used to sync with server.
+ * Check what stat() returns.
+ */
+struct netfs_inode_info
+{
+ unsigned int mode;
+ unsigned int nlink;
+ unsigned int uid;
+ unsigned int gid;
+ unsigned int blocksize;
+ unsigned int padding;
+ __u64 ino;
+ __u64 blocks;
+ __u64 rdev;
+ __u64 size;
+ __u64 version;
+};
+
+static inline void netfs_convert_inode_info(struct netfs_inode_info *info)
+{
+ info->mode = __cpu_to_be32(info->mode);
+ info->nlink = __cpu_to_be32(info->nlink);
+ info->uid = __cpu_to_be32(info->uid);
+ info->gid = __cpu_to_be32(info->gid);
+ info->blocksize = __cpu_to_be32(info->blocksize);
+ info->blocks = __cpu_to_be64(info->blocks);
+ info->rdev = __cpu_to_be64(info->rdev);
+ info->size = __cpu_to_be64(info->size);
+ info->version = __cpu_to_be64(info->version);
+ info->ino = __cpu_to_be64(info->ino);
+}
+
+/*
+ * Cache state machine.
+ */
+enum {
+ NETFS_COMMAND_PENDING = 0, /* Command is being executed */
+ NETFS_INODE_REMOTE_SYNCED, /* Inode was synced to server */
+ NETFS_INODE_REMOTE_DIR_SYNCED, /* Inode (directory) was synced from the server */
+ NETFS_INODE_OWNED, /* Inode is owned by given host */
+ NETFS_INODE_NEED_FLUSH, /* Inode has to be flushed to the server */
+};
+
+/*
+ * POHMELFS capabilities: information about supported
+ * crypto operations (hash/cipher, modes, key sizes and so on),
+ * root informaion (used/available size, number of objects, permissions)
+ */
+enum pohmelfs_capabilities {
+ POHMELFS_CRYPTO_CAPABILITIES = 0,
+ POHMELFS_ROOT_CAPABILITIES,
+};
+
+/* Read-only mount */
+#define POHMELFS_FLAGS_RO (1<<0)
+/* Extended attributes support on/off */
+#define POHMELFS_FLAGS_XATTR (1<<1)
+
+struct netfs_root_capabilities
+{
+ __u64 nr_files;
+ __u64 used, avail;
+ __u64 flags;
+};
+
+static inline void netfs_convert_root_capabilities(struct netfs_root_capabilities *cap)
+{
+ cap->nr_files = __cpu_to_be64(cap->nr_files);
+ cap->used = __cpu_to_be64(cap->used);
+ cap->avail = __cpu_to_be64(cap->avail);
+ cap->flags = __cpu_to_be64(cap->flags);
+}
+
+struct netfs_crypto_capabilities
+{
+ unsigned short hash_strlen; /* Hash string length, like "hmac(sha1) including 0 byte "*/
+ unsigned short cipher_strlen; /* Cipher string length with the same format */
+ unsigned int cipher_keysize; /* Cipher key size */
+};
+
+static inline void netfs_convert_crypto_capabilities(struct netfs_crypto_capabilities *cap)
+{
+ cap->hash_strlen = __cpu_to_be16(cap->hash_strlen);
+ cap->cipher_strlen = __cpu_to_be16(cap->cipher_strlen);
+ cap->cipher_keysize = __cpu_to_be32(cap->cipher_keysize);
+}
+
+enum pohmelfs_lock_type {
+ POHMELFS_LOCK_GRAB = (1<<15),
+
+ POHMELFS_READ_LOCK = 0,
+ POHMELFS_WRITE_LOCK,
+};
+
+struct netfs_lock
+{
+ __u64 start;
+ __u64 ino;
+ __u32 size;
+ __u32 type;
+};
+
+static inline void netfs_convert_lock(struct netfs_lock *lock)
+{
+ lock->start = __cpu_to_be64(lock->start);
+ lock->ino = __cpu_to_be64(lock->ino);
+ lock->size = __cpu_to_be32(lock->size);
+ lock->type = __cpu_to_be32(lock->type);
+}
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/completion.h>
+#include <linux/rbtree.h>
+#include <linux/net.h>
+#include <linux/poll.h>
+
+/*
+ * Private POHMELFS cache of objects in directory.
+ */
+struct pohmelfs_name
+{
+ struct rb_node hash_node;
+
+ struct list_head sync_create_entry;
+
+ u64 ino;
+
+ u32 hash;
+ u32 mode;
+ u32 len;
+
+ char *data;
+};
+
+/*
+ * POHMELFS inode. Main object.
+ */
+struct pohmelfs_inode
+{
+ struct list_head inode_entry; /* Entry in superblock list.
+ * Objects which are not bound to dentry require to be dropped
+ * in ->put_super()
+ */
+ struct rb_root hash_root; /* The same, but indexed by name hash and len */
+ struct mutex offset_lock; /* Protect both above trees */
+
+ struct list_head sync_create_list; /* List of created but not yet synced to the server children */
+
+ unsigned int drop_count;
+
+ int lock_type; /* How this inode is locked: read or write */
+
+ int error; /* Transaction error for given inode */
+
+ long state; /* State machine above */
+
+ u64 ino; /* Inode number */
+ u64 total_len; /* Total length of all children names, used to create offsets */
+
+ struct inode vfs_inode;
+};
+
+struct netfs_trans;
+typedef int (* netfs_trans_complete_t)(struct page **pages, unsigned int page_num,
+ void *private, int err);
+
+struct netfs_state;
+struct pohmelfs_sb;
+
+struct netfs_trans
+{
+ /*
+ * Transaction header and attached contiguous data live here.
+ */
+ struct iovec iovec;
+
+ /*
+ * Pages attached to transaction.
+ */
+ struct page **pages;
+
+ /*
+ * List and protecting lock for transaction destination
+ * network states.
+ */
+ spinlock_t dst_lock;
+ struct list_head dst_list;
+
+ /*
+ * Number of users for given transaction.
+ * For example each network state attached to transaction
+ * via dst_list increases it.
+ */
+ atomic_t refcnt;
+
+ /*
+ * Number of pages attached to given transaction.
+ * Some slots in above page array can be NULL, since
+ * for example page can be under writeback already,
+ * so we skip it in this transaction.
+ */
+ unsigned int page_num;
+
+ /*
+ * Transaction flags: single dst or broadcast and so on.
+ */
+ unsigned int flags;
+
+ /*
+ * Size of the data, which can be placed into
+ * iovec.iov_base area.
+ */
+ unsigned int total_size;
+
+ /*
+ * Number of pages to be sent to remote server.
+ * Usually equal to above page_num, but in case of partial
+ * writeback it can accumulate only pages already completed
+ * previous writeback.
+ */
+ unsigned int attached_pages;
+
+ /*
+ * Attached number of bytes in all above pages.
+ */
+ unsigned int attached_size;
+
+ /*
+ * Unique transacton generation number.
+ * Used as identity in the network state tree of transactions.
+ */
+ unsigned int gen;
+
+ /*
+ * Transaction completion status.
+ */
+ int result;
+
+ /*
+ * Superblock this transaction belongs to
+ */
+ struct pohmelfs_sb *psb;
+
+ /*
+ * Crypto engine, which processed this transaction.
+ * Can be not NULL only if crypto engine holds encrypted pages.
+ */
+ struct pohmelfs_crypto_engine *eng;
+
+ /* Private data */
+ void *private;
+
+ /* Completion callback, invoked just before transaction is destroyed */
+ netfs_trans_complete_t complete;
+};
+
+static inline int netfs_trans_cur_len(struct netfs_trans *t)
+{
+ return (signed)(t->total_size - t->iovec.iov_len);
+}
+
+static inline void *netfs_trans_current(struct netfs_trans *t)
+{
+ return t->iovec.iov_base + t->iovec.iov_len;
+}
+
+struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
+ unsigned int flags, unsigned int nr);
+void netfs_trans_free(struct netfs_trans *t);
+int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb);
+int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb);
+
+static inline void netfs_trans_reset(struct netfs_trans *t)
+{
+ t->complete = NULL;
+}
+
+struct netfs_trans_dst
+{
+ struct list_head trans_entry;
+ struct rb_node state_entry;
+
+ unsigned long send_time;
+
+ /*
+ * Times this transaction was resent to its old or new,
+ * depending on flags, destinations. When it reaches maximum
+ * allowed number, specified in superblock->trans_retries,
+ * transaction will be freed with ETIMEDOUT error.
+ */
+ unsigned int retries;
+
+ struct netfs_trans *trans;
+ struct netfs_state *state;
+};
+
+struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen);
+void netfs_trans_drop_dst(struct netfs_trans_dst *dst);
+void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst);
+void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st);
+void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st);
+int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb);
+int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st);
+
+int netfs_trans_init(void);
+void netfs_trans_exit(void);
+
+struct pohmelfs_crypto_engine
+{
+ u64 iv; /* Crypto IV for current operation */
+ unsigned long timeout; /* Crypto waiting timeout */
+ unsigned int size; /* Size of crypto scratchpad */
+ void *data; /* Temporal crypto scratchpad */
+ /*
+ * Crypto operations performed on objects.
+ */
+ struct crypto_hash *hash;
+ struct crypto_ablkcipher *cipher;
+
+ struct pohmelfs_crypto_thread *thread; /* Crypto thread which hosts this engine */
+
+ struct page **pages;
+ unsigned int page_num;
+};
+
+struct pohmelfs_crypto_thread
+{
+ struct list_head thread_entry;
+
+ struct task_struct *thread;
+ struct pohmelfs_sb *psb;
+
+ struct pohmelfs_crypto_engine eng;
+
+ struct netfs_trans *trans;
+
+ wait_queue_head_t wait;
+ int error;
+
+ unsigned int size;
+ struct page *page;
+};
+
+void pohmelfs_crypto_thread_make_ready(struct pohmelfs_crypto_thread *th);
+
+/*
+ * Network state, attached to one server.
+ */
+struct netfs_state
+{
+ struct mutex __state_lock; /* Can not allow to use the same socket simultaneously */
+ struct mutex __state_send_lock;
+ struct netfs_cmd cmd; /* Cached command */
+ struct netfs_inode_info info; /* Cached inode info */
+
+ void *data; /* Cached some data */
+ unsigned int size; /* Size of that data */
+
+ struct pohmelfs_sb *psb; /* Superblock */
+
+ struct task_struct *thread; /* Async receiving thread */
+
+ /* Waiting/polling machinery */
+ wait_queue_t wait;
+ wait_queue_head_t *whead;
+ wait_queue_head_t thread_wait;
+
+ struct mutex trans_lock;
+ struct rb_root trans_root;
+
+ struct pohmelfs_ctl ctl; /* Remote peer */
+
+ struct socket *socket; /* Socket object */
+ struct socket *read_socket; /* Cached pointer to socket object.
+ * Used to determine if between lock drops socket was changed.
+ * Never used to read data or any kind of access.
+ */
+ /*
+ * Crypto engines to process incoming data.
+ */
+ struct pohmelfs_crypto_engine eng;
+
+ int need_reset;
+};
+
+int netfs_state_init(struct netfs_state *st);
+void netfs_state_exit(struct netfs_state *st);
+
+static inline void netfs_state_lock_send(struct netfs_state *st)
+{
+ mutex_lock(&st->__state_send_lock);
+}
+
+static inline int netfs_state_trylock_send(struct netfs_state *st)
+{
+ return mutex_trylock(&st->__state_send_lock);
+}
+
+static inline void netfs_state_unlock_send(struct netfs_state *st)
+{
+ BUG_ON(!mutex_is_locked(&st->__state_send_lock));
+
+ mutex_unlock(&st->__state_send_lock);
+}
+
+static inline void netfs_state_lock(struct netfs_state *st)
+{
+ mutex_lock(&st->__state_lock);
+}
+
+static inline void netfs_state_unlock(struct netfs_state *st)
+{
+ BUG_ON(!mutex_is_locked(&st->__state_lock));
+
+ mutex_unlock(&st->__state_lock);
+}
+
+static inline unsigned int netfs_state_poll(struct netfs_state *st)
+{
+ unsigned int revents = POLLHUP | POLLERR;
+
+ netfs_state_lock(st);
+ if (st->socket)
+ revents = st->socket->ops->poll(NULL, st->socket, NULL);
+ netfs_state_unlock(st);
+
+ return revents;
+}
+
+struct pohmelfs_config;
+
+struct pohmelfs_sb
+{
+ struct rb_root mcache_root;
+ struct mutex mcache_lock;
+ atomic_long_t mcache_gen;
+ unsigned long mcache_timeout;
+
+ unsigned int idx;
+
+ unsigned int trans_retries;
+
+ atomic_t trans_gen;
+
+ unsigned int crypto_attached_size;
+ unsigned int crypto_align_size;
+
+ unsigned int crypto_fail_unsupported;
+
+ unsigned int crypto_thread_num;
+ struct list_head crypto_active_list, crypto_ready_list;
+ struct mutex crypto_thread_lock;
+
+ unsigned int trans_max_pages;
+ unsigned long trans_data_size;
+ unsigned long trans_timeout;
+
+ unsigned long drop_scan_timeout;
+ unsigned long trans_scan_timeout;
+
+ unsigned long wait_on_page_timeout;
+
+ struct list_head flush_list;
+ struct list_head drop_list;
+ spinlock_t ino_lock;
+ u64 ino;
+
+ /*
+ * Remote nodes POHMELFS connected to.
+ */
+ struct list_head state_list;
+ struct mutex state_lock;
+
+ /*
+ * Currently active state to request data from.
+ */
+ struct pohmelfs_config *active_state;
+
+
+ wait_queue_head_t wait;
+
+ /*
+ * Timed checks: stale transactions, inodes to be freed and so on.
+ */
+ struct delayed_work dwork;
+ struct delayed_work drop_dwork;
+
+ struct super_block *sb;
+
+ /*
+ * Algorithm strings.
+ */
+ char *hash_string;
+ char *cipher_string;
+
+ u8 *hash_key;
+ u8 *cipher_key;
+
+ /*
+ * Algorithm string lengths.
+ */
+ unsigned int hash_strlen;
+ unsigned int cipher_strlen;
+ unsigned int hash_keysize;
+ unsigned int cipher_keysize;
+
+ /*
+ * Controls whether to perfrom crypto processing or not.
+ */
+ int perform_crypto;
+
+ /*
+ * POHMELFS statistics.
+ */
+ u64 total_size;
+ u64 avail_size;
+ atomic_long_t total_inodes;
+
+ /*
+ * Xattr support, read-only and so on.
+ */
+ u64 state_flags;
+
+ /*
+ * Temporary storage to detect changes in the wait queue.
+ */
+ long flags;
+};
+
+static inline void netfs_trans_update(struct netfs_cmd *cmd,
+ struct netfs_trans *t, unsigned int size)
+{
+ unsigned int sz = ALIGN(size, t->psb->crypto_align_size);
+
+ t->iovec.iov_len += sizeof(struct netfs_cmd) + sz;
+ cmd->cpad = __cpu_to_be16(sz - size);
+}
+
+static inline struct pohmelfs_sb *POHMELFS_SB(struct super_block *sb)
+{
+ return sb->s_fs_info;
+}
+
+static inline struct pohmelfs_inode *POHMELFS_I(struct inode *inode)
+{
+ return container_of(inode, struct pohmelfs_inode, vfs_inode);
+}
+
+static inline u64 pohmelfs_new_ino(struct pohmelfs_sb *psb)
+{
+ u64 ino;
+
+ spin_lock(&psb->ino_lock);
+ ino = psb->ino++;
+ spin_unlock(&psb->ino_lock);
+
+ return ino;
+}
+
+static inline void pohmelfs_put_inode(struct pohmelfs_inode *pi)
+{
+ struct pohmelfs_sb *psb = POHMELFS_SB(pi->vfs_inode.i_sb);
+
+ spin_lock(&psb->ino_lock);
+ list_move_tail(&pi->inode_entry, &psb->drop_list);
+ pi->drop_count++;
+ spin_unlock(&psb->ino_lock);
+}
+
+struct pohmelfs_config
+{
+ struct list_head config_entry;
+
+ struct netfs_state state;
+};
+
+struct pohmelfs_config_group
+{
+ /*
+ * Entry in the global config group list.
+ */
+ struct list_head group_entry;
+
+ /*
+ * Index of the current group.
+ */
+ unsigned int idx;
+ /*
+ * Number of config_list entries in this group entry.
+ */
+ unsigned int num_entry;
+ /*
+ * Algorithm strings.
+ */
+ char *hash_string;
+ char *cipher_string;
+
+ /*
+ * Algorithm string lengths.
+ */
+ unsigned int hash_strlen;
+ unsigned int cipher_strlen;
+
+ /*
+ * Key and its size.
+ */
+ unsigned int hash_keysize;
+ unsigned int cipher_keysize;
+ u8 *hash_key;
+ u8 *cipher_key;
+
+ /*
+ * List of config entries (network state info) for given idx.
+ */
+ struct list_head config_list;
+};
+
+int __init pohmelfs_config_init(void);
+void pohmelfs_config_exit(void);
+int pohmelfs_copy_config(struct pohmelfs_sb *psb);
+int pohmelfs_copy_crypto(struct pohmelfs_sb *psb);
+int pohmelfs_config_check(struct pohmelfs_config *config, int idx);
+int pohmelfs_state_init_one(struct pohmelfs_sb *psb, struct pohmelfs_config *conf);
+
+extern const struct file_operations pohmelfs_dir_fops;
+extern const struct inode_operations pohmelfs_dir_inode_ops;
+
+int pohmelfs_state_init(struct pohmelfs_sb *psb);
+void pohmelfs_state_exit(struct pohmelfs_sb *psb);
+void pohmelfs_state_flush_transactions(struct netfs_state *st);
+
+void pohmelfs_fill_inode(struct inode *inode, struct netfs_inode_info *info);
+
+void pohmelfs_name_del(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
+void pohmelfs_free_names(struct pohmelfs_inode *parent);
+struct pohmelfs_name *pohmelfs_search_hash(struct pohmelfs_inode *pi, u32 hash);
+
+void pohmelfs_inode_del_inode(struct pohmelfs_sb *psb, struct pohmelfs_inode *pi);
+
+struct pohmelfs_inode *pohmelfs_create_entry_local(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str, u64 start, int mode);
+
+int pohmelfs_write_create_inode(struct pohmelfs_inode *pi);
+
+int pohmelfs_write_inode_create(struct inode *inode, struct netfs_trans *trans);
+int pohmelfs_remove_child(struct pohmelfs_inode *parent, struct pohmelfs_name *n);
+
+struct pohmelfs_inode *pohmelfs_new_inode(struct pohmelfs_sb *psb,
+ struct pohmelfs_inode *parent, struct qstr *str,
+ struct netfs_inode_info *info, int link);
+
+int pohmelfs_setattr(struct dentry *dentry, struct iattr *attr);
+int pohmelfs_setattr_raw(struct inode *inode, struct iattr *attr);
+
+int pohmelfs_meta_command(struct pohmelfs_inode *pi, unsigned int cmd_op, unsigned int flags,
+ netfs_trans_complete_t complete, void *priv, u64 start);
+int pohmelfs_meta_command_data(struct pohmelfs_inode *pi, u64 id, unsigned int cmd_op, char *addon,
+ unsigned int flags, netfs_trans_complete_t complete, void *priv, u64 start);
+
+void pohmelfs_check_states(struct pohmelfs_sb *psb);
+void pohmelfs_switch_active(struct pohmelfs_sb *psb);
+
+int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len);
+int pohmelfs_path_length(struct pohmelfs_inode *pi);
+
+struct pohmelfs_crypto_completion
+{
+ struct completion complete;
+ int error;
+};
+
+int pohmelfs_trans_crypt(struct netfs_trans *t, struct pohmelfs_sb *psb);
+void pohmelfs_crypto_exit(struct pohmelfs_sb *psb);
+int pohmelfs_crypto_init(struct pohmelfs_sb *psb);
+
+int pohmelfs_crypto_engine_init(struct pohmelfs_crypto_engine *e, struct pohmelfs_sb *psb);
+void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e);
+
+int pohmelfs_crypto_process_input_data(struct pohmelfs_crypto_engine *e, u64 iv,
+ void *data, struct page *page, unsigned int size);
+int pohmelfs_crypto_process_input_page(struct pohmelfs_crypto_engine *e,
+ struct page *page, unsigned int size, u64 iv);
+
+static inline u64 pohmelfs_gen_iv(struct netfs_trans *t)
+{
+ u64 iv = t->gen;
+
+ iv <<= 32;
+ iv |= ((unsigned long)t) & 0xffffffff;
+
+ return iv;
+}
+
+int pohmelfs_data_lock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
+int pohmelfs_data_unlock(struct pohmelfs_inode *pi, u64 start, u32 size, int type);
+int pohmelfs_data_lock_response(struct netfs_state *st);
+
+static inline int pohmelfs_need_lock(struct pohmelfs_inode *pi, int type)
+{
+ if (test_bit(NETFS_INODE_OWNED, &pi->state)) {
+ if (type == pi->lock_type)
+ return 0;
+ if ((type == POHMELFS_READ_LOCK) && (pi->lock_type == POHMELFS_WRITE_LOCK))
+ return 0;
+ }
+
+ if (!test_bit(NETFS_INODE_REMOTE_SYNCED, &pi->state))
+ return 0;
+
+ return 1;
+}
+
+int __init pohmelfs_mcache_init(void);
+void pohmelfs_mcache_exit(void);
+
+//#define CONFIG_POHMELFS_DEBUG
+
+#ifdef CONFIG_POHMELFS_DEBUG
+#define dprintka(f, a...) printk(f, ##a)
+#define dprintk(f, a...) printk("%d: " f, task_pid_vnr(current), ##a)
+#else
+#define dprintka(f, a...) do {} while (0)
+#define dprintk(f, a...) do {} while (0)
+#endif
+
+static inline void netfs_trans_get(struct netfs_trans *t)
+{
+ atomic_inc(&t->refcnt);
+}
+
+static inline void netfs_trans_put(struct netfs_trans *t)
+{
+ if (atomic_dec_and_test(&t->refcnt)) {
+ dprintk("%s: t: %p, gen: %u, err: %d.\n",
+ __func__, t, t->gen, t->result);
+ if (t->complete)
+ t->complete(t->pages, t->page_num,
+ t->private, t->result);
+ netfs_trans_free(t);
+ }
+}
+
+struct pohmelfs_mcache
+{
+ struct rb_node mcache_entry;
+ struct completion complete;
+
+ atomic_t refcnt;
+
+ u64 gen;
+
+ void *data;
+ u64 start;
+ u32 size;
+ int err;
+
+ struct netfs_inode_info info;
+};
+
+struct pohmelfs_mcache *pohmelfs_mcache_alloc(struct pohmelfs_sb *psb, u64 start,
+ unsigned int size, void *data);
+void pohmelfs_mcache_free(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
+struct pohmelfs_mcache *pohmelfs_mcache_search(struct pohmelfs_sb *psb, u64 gen);
+void pohmelfs_mcache_remove_locked(struct pohmelfs_sb *psb, struct pohmelfs_mcache *m);
+
+static inline void pohmelfs_mcache_get(struct pohmelfs_mcache *m)
+{
+ atomic_inc(&m->refcnt);
+}
+
+static inline void pohmelfs_mcache_put(struct pohmelfs_sb *psb,
+ struct pohmelfs_mcache *m)
+{
+ if (atomic_dec_and_test(&m->refcnt))
+ pohmelfs_mcache_free(psb, m);
+}
+
+int pohmelfs_ftrans_init(void);
+void pohmelfs_ftrans_exit(void);
+void pohmelfs_ftrans_update(u64 id);
+int pohmelfs_ftrans_check(u64 id);
+void pohmelfs_ftrans_clean(u64 id);
+
+#endif /* __KERNEL__*/
+
+#endif /* __NETFS_H */
diff --git a/drivers/staging/pohmelfs/path_entry.c b/drivers/staging/pohmelfs/path_entry.c
new file mode 100644
index 00000000000..3bad888ced1
--- /dev/null
+++ b/drivers/staging/pohmelfs/path_entry.c
@@ -0,0 +1,114 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/ktime.h>
+#include <linux/fs_struct.h>
+#include <linux/pagemap.h>
+#include <linux/writeback.h>
+#include <linux/mount.h>
+#include <linux/mm.h>
+
+#include "netfs.h"
+
+#define UNHASHED_OBSCURE_STRING_SIZE sizeof(" (deleted)")
+
+/*
+ * Create path from root for given inode.
+ * Path is formed as set of stuctures, containing name of the object
+ * and its inode data (mode, permissions and so on).
+ */
+int pohmelfs_construct_path_string(struct pohmelfs_inode *pi, void *data, int len)
+{
+ struct path path;
+ struct dentry *d;
+ char *ptr;
+ int err = 0, strlen, reduce = 0;
+
+ d = d_find_alias(&pi->vfs_inode);
+ if (!d) {
+ printk("%s: no alias, list_empty: %d.\n", __func__, list_empty(&pi->vfs_inode.i_dentry));
+ return -ENOENT;
+ }
+
+ read_lock(&current->fs->lock);
+ path.mnt = mntget(current->fs->root.mnt);
+ read_unlock(&current->fs->lock);
+
+ path.dentry = d;
+
+ if (!IS_ROOT(d) && d_unhashed(d))
+ reduce = 1;
+
+ ptr = d_path(&path, data, len);
+ if (IS_ERR(ptr)) {
+ err = PTR_ERR(ptr);
+ goto out;
+ }
+
+ if (reduce && len >= UNHASHED_OBSCURE_STRING_SIZE) {
+ char *end = data + len - UNHASHED_OBSCURE_STRING_SIZE;
+ *end = '\0';
+ }
+
+ strlen = len - (ptr - (char *)data);
+ memmove(data, ptr, strlen);
+ ptr = data;
+
+ err = strlen;
+
+ dprintk("%s: dname: '%s', len: %u, maxlen: %u, name: '%s', strlen: %d.\n",
+ __func__, d->d_name.name, d->d_name.len, len, ptr, strlen);
+
+out:
+ dput(d);
+ mntput(path.mnt);
+
+ return err;
+}
+
+int pohmelfs_path_length(struct pohmelfs_inode *pi)
+{
+ struct dentry *d, *root, *first;
+ int len = 1; /* Root slash */
+
+ first = d = d_find_alias(&pi->vfs_inode);
+ if (!d) {
+ dprintk("%s: ino: %llu, mode: %o.\n", __func__, pi->ino, pi->vfs_inode.i_mode);
+ return -ENOENT;
+ }
+
+ read_lock(&current->fs->lock);
+ root = dget(current->fs->root.dentry);
+ read_unlock(&current->fs->lock);
+
+ spin_lock(&dcache_lock);
+
+ if (!IS_ROOT(d) && d_unhashed(d))
+ len += UNHASHED_OBSCURE_STRING_SIZE; /* Obscure " (deleted)" string */
+
+ while (d && d != root && !IS_ROOT(d)) {
+ len += d->d_name.len + 1; /* Plus slash */
+ d = d->d_parent;
+ }
+ spin_unlock(&dcache_lock);
+
+ dput(root);
+ dput(first);
+
+ return len + 1; /* Including zero-byte */
+}
diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c
new file mode 100644
index 00000000000..bcb59425a21
--- /dev/null
+++ b/drivers/staging/pohmelfs/trans.c
@@ -0,0 +1,715 @@
+/*
+ * 2007+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/fs.h>
+#include <linux/jhash.h>
+#include <linux/hash.h>
+#include <linux/ktime.h>
+#include <linux/mempool.h>
+#include <linux/mm.h>
+#include <linux/mount.h>
+#include <linux/pagemap.h>
+#include <linux/parser.h>
+#include <linux/poll.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/statfs.h>
+#include <linux/writeback.h>
+
+#include "netfs.h"
+
+static struct kmem_cache *netfs_trans_dst;
+static mempool_t *netfs_trans_dst_pool;
+
+static void netfs_trans_init_static(struct netfs_trans *t, int num, int size)
+{
+ t->page_num = num;
+ t->total_size = size;
+ atomic_set(&t->refcnt, 1);
+
+ spin_lock_init(&t->dst_lock);
+ INIT_LIST_HEAD(&t->dst_list);
+}
+
+static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st)
+{
+ int err = 0;
+ unsigned int i, attached_pages = t->attached_pages, ci;
+ struct msghdr msg;
+ struct page **pages = (t->eng)?t->eng->pages:t->pages;
+ struct page *p;
+ unsigned int size;
+
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_WAITALL | MSG_MORE;
+
+ ci = 0;
+ for (i=0; i<t->page_num; ++i) {
+ struct page *page = pages[ci];
+ struct netfs_cmd cmd;
+ struct iovec io;
+
+ p = t->pages[i];
+
+ if (!p)
+ continue;
+
+ size = page_private(p);
+
+ io.iov_base = &cmd;
+ io.iov_len = sizeof(struct netfs_cmd);
+
+ cmd.cmd = NETFS_WRITE_PAGE;
+ cmd.ext = 0;
+ cmd.id = 0;
+ cmd.size = size;
+ cmd.start = p->index;
+ cmd.start <<= PAGE_CACHE_SHIFT;
+ cmd.csize = 0;
+ cmd.cpad = 0;
+ cmd.iv = pohmelfs_gen_iv(t);
+
+ netfs_convert_cmd(&cmd);
+
+ msg.msg_iov = &io;
+ msg.msg_iovlen = 1;
+ msg.msg_flags = MSG_WAITALL | MSG_MORE;
+
+ err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, sizeof(struct netfs_cmd));
+ if (err <= 0) {
+ printk("%s: %d/%d failed to send transaction header: t: %p, gen: %u, err: %d.\n",
+ __func__, i, t->page_num, t, t->gen, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ goto err_out;
+ }
+
+ msg.msg_flags = MSG_WAITALL|(attached_pages == 1)?0:MSG_MORE;
+
+ err = kernel_sendpage(st->socket, page, 0, size, msg.msg_flags);
+ if (err <= 0) {
+ printk("%s: %d/%d failed to send transaction page: t: %p, gen: %u, size: %u, err: %d.\n",
+ __func__, i, t->page_num, t, t->gen, size, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ goto err_out;
+ }
+
+ dprintk("%s: %d/%d sent t: %p, gen: %u, page: %p/%p, size: %u.\n",
+ __func__, i, t->page_num, t, t->gen, page, p, size);
+
+ err = 0;
+ attached_pages--;
+ if (!attached_pages)
+ break;
+ ci++;
+
+ continue;
+
+err_out:
+ printk("%s: t: %p, gen: %u, err: %d.\n", __func__, t, t->gen, err);
+ netfs_state_exit(st);
+ break;
+ }
+
+ return err;
+}
+
+int netfs_trans_send(struct netfs_trans *t, struct netfs_state *st)
+{
+ int err;
+ struct msghdr msg;
+
+ BUG_ON(!t->iovec.iov_len);
+ BUG_ON(t->iovec.iov_len > 1024*1024*1024);
+
+ netfs_state_lock_send(st);
+ if (!st->socket) {
+ err = netfs_state_init(st);
+ if (err)
+ goto err_out_unlock_return;
+ }
+
+ msg.msg_iov = &t->iovec;
+ msg.msg_iovlen = 1;
+ msg.msg_name = NULL;
+ msg.msg_namelen = 0;
+ msg.msg_control = NULL;
+ msg.msg_controllen = 0;
+ msg.msg_flags = MSG_WAITALL;
+
+ if (t->attached_pages)
+ msg.msg_flags |= MSG_MORE;
+
+ err = kernel_sendmsg(st->socket, &msg, (struct kvec *)msg.msg_iov, 1, t->iovec.iov_len);
+ if (err <= 0) {
+ printk("%s: failed to send contig transaction: t: %p, gen: %u, size: %zu, err: %d.\n",
+ __func__, t, t->gen, t->iovec.iov_len, err);
+ if (err == 0)
+ err = -ECONNRESET;
+ goto err_out_unlock_return;
+ }
+
+ dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n",
+ __func__, (t->page_num)?"partial":"full",
+ t, t->gen, t->iovec.iov_len, t->page_num);
+
+ err = 0;
+ if (t->attached_pages)
+ err = netfs_trans_send_pages(t, st);
+
+err_out_unlock_return:
+
+ if (st->need_reset) {
+ netfs_state_exit(st);
+ }
+ netfs_state_unlock_send(st);
+
+ dprintk("%s: t: %p, gen: %u, err: %d.\n",
+ __func__, t, t->gen, err);
+
+ t->result = err;
+ return err;
+}
+
+static inline int netfs_trans_cmp(unsigned int gen, unsigned int new)
+{
+ if (gen < new)
+ return 1;
+ if (gen > new)
+ return -1;
+ return 0;
+}
+
+struct netfs_trans_dst *netfs_trans_search(struct netfs_state *st, unsigned int gen)
+{
+ struct rb_root *root = &st->trans_root;
+ struct rb_node *n = root->rb_node;
+ struct netfs_trans_dst *tmp, *ret = NULL;
+ struct netfs_trans *t;
+ int cmp;
+
+ while (n) {
+ tmp = rb_entry(n, struct netfs_trans_dst, state_entry);
+ t = tmp->trans;
+
+ cmp = netfs_trans_cmp(t->gen, gen);
+ if (cmp < 0)
+ n = n->rb_left;
+ else if (cmp > 0)
+ n = n->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int netfs_trans_insert(struct netfs_trans_dst *ndst, struct netfs_state *st)
+{
+ struct rb_root *root = &st->trans_root;
+ struct rb_node **n = &root->rb_node, *parent = NULL;
+ struct netfs_trans_dst *ret = NULL, *tmp;
+ struct netfs_trans *t = NULL, *new = ndst->trans;
+ int cmp;
+
+ while (*n) {
+ parent = *n;
+
+ tmp = rb_entry(parent, struct netfs_trans_dst, state_entry);
+ t = tmp->trans;
+
+ cmp = netfs_trans_cmp(t->gen, new->gen);
+ if (cmp < 0)
+ n = &parent->rb_left;
+ else if (cmp > 0)
+ n = &parent->rb_right;
+ else {
+ ret = tmp;
+ break;
+ }
+ }
+
+ if (ret) {
+ printk("%s: exist: old: gen: %u, flags: %x, send_time: %lu, "
+ "new: gen: %u, flags: %x, send_time: %lu.\n",
+ __func__, t->gen, t->flags, ret->send_time,
+ new->gen, new->flags, ndst->send_time);
+ return -EEXIST;
+ }
+
+ rb_link_node(&ndst->state_entry, parent, n);
+ rb_insert_color(&ndst->state_entry, root);
+ ndst->send_time = jiffies;
+
+ return 0;
+}
+
+int netfs_trans_remove_nolock(struct netfs_trans_dst *dst, struct netfs_state *st)
+{
+ if (dst && dst->state_entry.rb_parent_color) {
+ rb_erase(&dst->state_entry, &st->trans_root);
+ dst->state_entry.rb_parent_color = 0;
+ return 1;
+ }
+ return 0;
+}
+
+static int netfs_trans_remove_state(struct netfs_trans_dst *dst)
+{
+ int ret;
+ struct netfs_state *st = dst->state;
+
+ mutex_lock(&st->trans_lock);
+ ret = netfs_trans_remove_nolock(dst, st);
+ mutex_unlock(&st->trans_lock);
+
+ return ret;
+}
+
+/*
+ * Create new destination for given transaction associated with given network state.
+ * Transaction's reference counter is bumped and will be dropped when either
+ * reply is received or when async timeout detection task will fail resending
+ * and drop transaction.
+ */
+static int netfs_trans_push_dst(struct netfs_trans *t, struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst;
+ int err;
+
+ dst = mempool_alloc(netfs_trans_dst_pool, GFP_KERNEL);
+ if (!dst)
+ return -ENOMEM;
+
+ dst->retries = 0;
+ dst->send_time = 0;
+ dst->state = st;
+ dst->trans = t;
+ netfs_trans_get(t);
+
+ mutex_lock(&st->trans_lock);
+ err = netfs_trans_insert(dst, st);
+ mutex_unlock(&st->trans_lock);
+
+ if (err)
+ goto err_out_free;
+
+ spin_lock(&t->dst_lock);
+ list_add_tail(&dst->trans_entry, &t->dst_list);
+ spin_unlock(&t->dst_lock);
+
+ return 0;
+
+err_out_free:
+ t->result = err;
+ netfs_trans_put(t);
+ mempool_free(dst, netfs_trans_dst_pool);
+ return err;
+}
+
+static void netfs_trans_free_dst(struct netfs_trans_dst *dst)
+{
+ netfs_trans_put(dst->trans);
+ mempool_free(dst, netfs_trans_dst_pool);
+}
+
+static void netfs_trans_remove_dst(struct netfs_trans_dst *dst)
+{
+ if (netfs_trans_remove_state(dst))
+ netfs_trans_free_dst(dst);
+}
+
+/*
+ * Drop destination transaction entry when we know it.
+ */
+void netfs_trans_drop_dst(struct netfs_trans_dst *dst)
+{
+ struct netfs_trans *t = dst->trans;
+
+ spin_lock(&t->dst_lock);
+ list_del_init(&dst->trans_entry);
+ spin_unlock(&t->dst_lock);
+
+ netfs_trans_remove_dst(dst);
+}
+
+/*
+ * Drop destination transaction entry when we know it and when we
+ * already removed dst from state tree.
+ */
+void netfs_trans_drop_dst_nostate(struct netfs_trans_dst *dst)
+{
+ struct netfs_trans *t = dst->trans;
+
+ spin_lock(&t->dst_lock);
+ list_del_init(&dst->trans_entry);
+ spin_unlock(&t->dst_lock);
+
+ netfs_trans_free_dst(dst);
+}
+
+/*
+ * This drops destination transaction entry from appropriate network state
+ * tree and drops related reference counter. It is possible that transaction
+ * will be freed here if its reference counter hits zero.
+ * Destination transaction entry will be freed.
+ */
+void netfs_trans_drop_trans(struct netfs_trans *t, struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst, *tmp, *ret = NULL;
+
+ spin_lock(&t->dst_lock);
+ list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
+ if (dst->state == st) {
+ ret = dst;
+ list_del(&dst->trans_entry);
+ break;
+ }
+ }
+ spin_unlock(&t->dst_lock);
+
+ if (ret)
+ netfs_trans_remove_dst(ret);
+}
+
+/*
+ * This drops destination transaction entry from appropriate network state
+ * tree and drops related reference counter. It is possible that transaction
+ * will be freed here if its reference counter hits zero.
+ * Destination transaction entry will be freed.
+ */
+void netfs_trans_drop_last(struct netfs_trans *t, struct netfs_state *st)
+{
+ struct netfs_trans_dst *dst, *tmp, *ret;
+
+ spin_lock(&t->dst_lock);
+ ret = list_entry(t->dst_list.prev, struct netfs_trans_dst, trans_entry);
+ if (ret->state != st) {
+ ret = NULL;
+ list_for_each_entry_safe(dst, tmp, &t->dst_list, trans_entry) {
+ if (dst->state == st) {
+ ret = dst;
+ list_del_init(&dst->trans_entry);
+ break;
+ }
+ }
+ } else {
+ list_del(&ret->trans_entry);
+ }
+ spin_unlock(&t->dst_lock);
+
+ if (ret)
+ netfs_trans_remove_dst(ret);
+}
+
+static int netfs_trans_push(struct netfs_trans *t, struct netfs_state *st)
+{
+ int err;
+
+ err = netfs_trans_push_dst(t, st);
+ if (err)
+ return err;
+
+ err = netfs_trans_send(t, st);
+ if (err)
+ goto err_out_free;
+
+ if (t->flags & NETFS_TRANS_SINGLE_DST)
+ pohmelfs_switch_active(st->psb);
+
+ return 0;
+
+err_out_free:
+ t->result = err;
+ netfs_trans_drop_last(t, st);
+
+ return err;
+}
+
+int netfs_trans_finish_send(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+ struct pohmelfs_config *c;
+ int err = -ENODEV;
+ struct netfs_state *st;
+#if 0
+ dprintk("%s: t: %p, gen: %u, size: %u, page_num: %u, active: %p.\n",
+ __func__, t, t->gen, t->iovec.iov_len, t->page_num, psb->active_state);
+#endif
+ mutex_lock(&psb->state_lock);
+
+ if ((t->flags & NETFS_TRANS_SINGLE_DST) && psb->active_state) {
+ st = &psb->active_state->state;
+
+ err = -EPIPE;
+ if (netfs_state_poll(st) & POLLOUT) {
+ err = netfs_trans_push_dst(t, st);
+ if (!err) {
+ err = netfs_trans_send(t, st);
+ if (err) {
+ netfs_trans_drop_last(t, st);
+ } else {
+ pohmelfs_switch_active(psb);
+ goto out;
+ }
+ }
+ }
+ pohmelfs_switch_active(psb);
+ }
+
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ err = netfs_trans_push(t, st);
+ if (!err && (t->flags & NETFS_TRANS_SINGLE_DST))
+ break;
+ }
+out:
+ mutex_unlock(&psb->state_lock);
+#if 0
+ dprintk("%s: fully sent t: %p, gen: %u, size: %u, page_num: %u, err: %d.\n",
+ __func__, t, t->gen, t->iovec.iov_len, t->page_num, err);
+#endif
+ if (err)
+ t->result = err;
+ return err;
+}
+
+int netfs_trans_finish(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+ int err;
+ struct netfs_cmd *cmd = t->iovec.iov_base;
+
+ t->gen = atomic_inc_return(&psb->trans_gen);
+
+ pohmelfs_ftrans_clean(t->gen);
+
+ cmd->size = t->iovec.iov_len - sizeof(struct netfs_cmd) +
+ t->attached_size + t->attached_pages * sizeof(struct netfs_cmd);
+ cmd->cmd = NETFS_TRANS;
+ cmd->start = t->gen;
+ cmd->id = 0;
+
+ if (psb->perform_crypto) {
+ cmd->ext = psb->crypto_attached_size;
+ cmd->csize = psb->crypto_attached_size;
+ }
+
+ dprintk("%s: t: %u, size: %u, iov_len: %zu, attached_size: %u, attached_pages: %u.\n",
+ __func__, t->gen, cmd->size, t->iovec.iov_len, t->attached_size, t->attached_pages);
+ err = pohmelfs_trans_crypt(t, psb);
+ if (err) {
+ t->result = err;
+ netfs_convert_cmd(cmd);
+ dprintk("%s: trans: %llu, crypto_attached_size: %u, attached_size: %u, attached_pages: %d, trans_size: %u, err: %d.\n",
+ __func__, cmd->start, psb->crypto_attached_size, t->attached_size, t->attached_pages, cmd->size, err);
+ }
+ netfs_trans_put(t);
+ return err;
+}
+
+/*
+ * Resend transaction to remote server(s).
+ * If new servers were added into superblock, we can try to send data
+ * to them too.
+ *
+ * It is called under superblock's state_lock, so we can safely
+ * dereference psb->state_list. Also, transaction's reference counter is
+ * bumped, so it can not go away under us, thus we can safely access all
+ * its members. State is locked.
+ *
+ * This function returns 0 if transaction was successfully sent to at
+ * least one destination target.
+ */
+int netfs_trans_resend(struct netfs_trans *t, struct pohmelfs_sb *psb)
+{
+ struct netfs_trans_dst *dst;
+ struct netfs_state *st;
+ struct pohmelfs_config *c;
+ int err, exist, error = -ENODEV;
+
+ list_for_each_entry(c, &psb->state_list, config_entry) {
+ st = &c->state;
+
+ exist = 0;
+ spin_lock(&t->dst_lock);
+ list_for_each_entry(dst, &t->dst_list, trans_entry) {
+ if (st == dst->state) {
+ exist = 1;
+ break;
+ }
+ }
+ spin_unlock(&t->dst_lock);
+
+ if (exist) {
+ if (!(t->flags & NETFS_TRANS_SINGLE_DST) ||
+ (c->config_entry.next == &psb->state_list)) {
+ dprintk("%s: resending st: %p, t: %p, gen: %u.\n",
+ __func__, st, t, t->gen);
+ err = netfs_trans_send(t, st);
+ if (!err)
+ error = 0;
+ }
+ continue;
+ }
+
+ dprintk("%s: pushing/resending st: %p, t: %p, gen: %u.\n",
+ __func__, st, t, t->gen);
+ err = netfs_trans_push(t, st);
+ if (err)
+ continue;
+ error = 0;
+ if (t->flags & NETFS_TRANS_SINGLE_DST)
+ break;
+ }
+
+ t->result = error;
+ return error;
+}
+
+void *netfs_trans_add(struct netfs_trans *t, unsigned int size)
+{
+ struct iovec *io = &t->iovec;
+ void *ptr;
+
+ if (size > t->total_size) {
+ ptr = ERR_PTR(-EINVAL);
+ goto out;
+ }
+
+ if (io->iov_len + size > t->total_size) {
+ dprintk("%s: too big size t: %p, gen: %u, iov_len: %zu, size: %u, total: %u.\n",
+ __func__, t, t->gen, io->iov_len, size, t->total_size);
+ ptr = ERR_PTR(-E2BIG);
+ goto out;
+ }
+
+ ptr = io->iov_base + io->iov_len;
+ io->iov_len += size;
+
+out:
+ dprintk("%s: t: %p, gen: %u, size: %u, total: %zu.\n",
+ __func__, t, t->gen, size, io->iov_len);
+ return ptr;
+}
+
+void netfs_trans_free(struct netfs_trans *t)
+{
+ if (t->eng)
+ pohmelfs_crypto_thread_make_ready(t->eng->thread);
+ kfree(t);
+}
+
+struct netfs_trans *netfs_trans_alloc(struct pohmelfs_sb *psb, unsigned int size,
+ unsigned int flags, unsigned int nr)
+{
+ struct netfs_trans *t;
+ unsigned int num, cont, pad, size_no_trans;
+ unsigned int crypto_added = 0;
+ struct netfs_cmd *cmd;
+
+ if (psb->perform_crypto)
+ crypto_added = psb->crypto_attached_size;
+
+ /*
+ * |sizeof(struct netfs_trans)|
+ * |sizeof(struct netfs_cmd)| - transaction header
+ * |size| - buffer with requested size
+ * |padding| - crypto padding, zero bytes
+ * |nr * sizeof(struct page *)| - array of page pointers
+ *
+ * Overall size should be less than PAGE_SIZE for guaranteed allocation.
+ */
+
+ cont = size;
+ size = ALIGN(size, psb->crypto_align_size);
+ pad = size - cont;
+
+ size_no_trans = size + sizeof(struct netfs_cmd) * 2 + crypto_added;
+
+ cont = sizeof(struct netfs_trans) + size_no_trans;
+
+ num = (PAGE_SIZE - cont)/sizeof(struct page *);
+
+ if (nr > num)
+ nr = num;
+
+ t = kzalloc(cont + nr*sizeof(struct page *), GFP_NOIO);
+ if (!t)
+ goto err_out_exit;
+
+ t->iovec.iov_base = (void *)(t + 1);
+ t->pages = (struct page **)(t->iovec.iov_base + size_no_trans);
+
+ /*
+ * Reserving space for transaction header.
+ */
+ t->iovec.iov_len = sizeof(struct netfs_cmd) + crypto_added;
+
+ netfs_trans_init_static(t, nr, size_no_trans);
+
+ t->flags = flags;
+ t->psb = psb;
+
+ cmd = (struct netfs_cmd *)t->iovec.iov_base;
+
+ cmd->size = size;
+ cmd->cpad = pad;
+ cmd->csize = crypto_added;
+
+ dprintk("%s: t: %p, gen: %u, size: %u, padding: %u, align_size: %u, flags: %x, "
+ "page_num: %u, base: %p, pages: %p.\n",
+ __func__, t, t->gen, size, pad, psb->crypto_align_size, flags, nr,
+ t->iovec.iov_base, t->pages);
+
+ return t;
+
+err_out_exit:
+ return NULL;
+}
+
+int netfs_trans_init(void)
+{
+ int err = -ENOMEM;
+
+ netfs_trans_dst = kmem_cache_create("netfs_trans_dst", sizeof(struct netfs_trans_dst),
+ 0, 0, NULL);
+ if (!netfs_trans_dst)
+ goto err_out_exit;
+
+ netfs_trans_dst_pool = mempool_create_slab_pool(256, netfs_trans_dst);
+ if (!netfs_trans_dst_pool)
+ goto err_out_free;
+
+ return 0;
+
+err_out_free:
+ kmem_cache_destroy(netfs_trans_dst);
+err_out_exit:
+ return err;
+}
+
+void netfs_trans_exit(void)
+{
+ mempool_destroy(netfs_trans_dst_pool);
+ kmem_cache_destroy(netfs_trans_dst);
+}
diff --git a/drivers/staging/rspiusb/rspiusb.c b/drivers/staging/rspiusb/rspiusb.c
index ca281d6cbd7..ecaffb50311 100644
--- a/drivers/staging/rspiusb/rspiusb.c
+++ b/drivers/staging/rspiusb/rspiusb.c
@@ -781,9 +781,8 @@ static int piusb_probe(struct usb_interface *interface,
dbg("Endpoint[%d]->MaxPacketSize = %d\n", i,
endpoint->wMaxPacketSize);
}
- if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
- USB_ENDPOINT_XFER_BULK) {
- if (endpoint->bEndpointAddress & USB_DIR_IN)
+ if (usb_endpoint_xfer_bulk(endpoint)) {
+ if (usb_endpoint_dir_in(endpoint))
pdx->hEP[i] =
usb_rcvbulkpipe(pdx->udev,
endpoint->bEndpointAddress);
diff --git a/drivers/staging/rt2860/2860_main_dev.c b/drivers/staging/rt2860/2860_main_dev.c
index 08ca81f43cc..ff7f8338073 100644
--- a/drivers/staging/rt2860/2860_main_dev.c
+++ b/drivers/staging/rt2860/2860_main_dev.c
@@ -90,12 +90,10 @@ void init_thread_task(PRTMP_ADAPTER pAd);
static void __exit rt2860_cleanup_module(void);
static int __init rt2860_init_module(void);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#ifdef CONFIG_PM
static int rt2860_suspend(struct pci_dev *pci_dev, pm_message_t state);
static int rt2860_resume(struct pci_dev *pci_dev);
#endif // CONFIG_PM //
-#endif
//
@@ -128,22 +126,15 @@ static struct pci_driver rt2860_driver =
name: "rt2860",
id_table: rt2860_pci_tbl,
probe: rt2860_init_one,
-#if LINUX_VERSION_CODE >= 0x20412
remove: __devexit_p(rt2860_remove_one),
-#else
- remove: __devexit(rt2860_remove_one),
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#ifdef CONFIG_PM
suspend: rt2860_suspend,
resume: rt2860_resume,
#endif
-#endif
};
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#ifdef CONFIG_PM
VOID RT2860RejectPendingPackets(
@@ -284,16 +275,11 @@ static int rt2860_resume(
return 0;
}
#endif // CONFIG_PM //
-#endif
static INT __init rt2860_init_module(VOID)
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
return pci_register_driver(&rt2860_driver);
-#else
- return pci_module_init(&rt2860_driver);
-#endif
}
@@ -374,11 +360,7 @@ static VOID __devexit rt2860_remove_one(
}
// Free pre-allocated net_device memory
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
free_netdev(net_dev);
-#else
- kfree(net_dev);
-#endif
}
//
@@ -758,16 +740,13 @@ static void ac0_dma_done_tasklet(unsigned long data)
int print_int_count;
IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
rt2860_interrupt(int irq, void *dev_instance)
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
-#endif
{
struct net_device *net_dev = (struct net_device *) dev_instance;
PRTMP_ADAPTER pAd = net_dev->ml_priv;
INT_SOURCE_CSR_STRUC IntSource;
POS_COOKIE pObj;
+ BOOLEAN bOldValue;
pObj = (POS_COOKIE) pAd->OS_Cookie;
@@ -800,20 +779,19 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
// RT2661 => when ASIC is sleeping, MAC register cannot be read and written.
// RT2860 => when ASIC is sleeping, MAC register can be read and written.
+ bOldValue = pAd->bPCIclkOff;
+ pAd->bPCIclkOff = FALSE;
{
RTMP_IO_READ32(pAd, INT_SOURCE_CSR, &IntSource.word);
RTMP_IO_WRITE32(pAd, INT_SOURCE_CSR, IntSource.word); // write 1 to clear
}
+ pAd->bPCIclkOff = bOldValue;
// Do nothing if Reset in progress
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- return IRQ_HANDLED;
-#else
- return;
-#endif
+ return IRQ_HANDLED;
}
//
@@ -822,8 +800,6 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
// The priority can be adjust by altering processing if statement
//
- pAd->bPCIclkOff = FALSE;
-
// If required spinlock, each interrupt service routine has to acquire
// and release itself.
//
@@ -832,11 +808,8 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
if (IntSource.word == 0xffffffff)
{
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- return IRQ_HANDLED;
-#else
- return;
-#endif
+ printk("snowpin - IntSource.word == 0xffffffff\n");
+ return IRQ_HANDLED;
}
if (IntSource.word & TxCoherent)
@@ -970,10 +943,7 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
}
#endif // CONFIG_STA_SUPPORT //
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
return IRQ_HANDLED;
-#endif
-
}
/*
@@ -1026,11 +996,7 @@ BOOLEAN RT28XXNetDevInit(
ULONG csr_addr;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
-#else
- print_name = pci_dev ? pci_dev->slot_name : "rt2860";
-#endif // LINUX_VERSION_CODE //
+ print_name = pci_dev ? pci_name(pci_dev) : "rt2860";
net_dev->base_addr = 0;
net_dev->irq = 0;
diff --git a/drivers/staging/rt2860/Makefile b/drivers/staging/rt2860/Makefile
index 6162212b588..b9563647846 100644
--- a/drivers/staging/rt2860/Makefile
+++ b/drivers/staging/rt2860/Makefile
@@ -2,7 +2,6 @@ obj-$(CONFIG_RT2860) += rt2860sta.o
# TODO: all of these should be removed
EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
-EXTRA_CFLAGS += -DRT2860
EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
EXTRA_CFLAGS += -DDBG
EXTRA_CFLAGS += -DDOT11_N_SUPPORT
diff --git a/drivers/staging/rt2860/TODO b/drivers/staging/rt2860/TODO
index 2f70b0faca3..6158dc2a4b6 100644
--- a/drivers/staging/rt2860/TODO
+++ b/drivers/staging/rt2860/TODO
@@ -1,6 +1,6 @@
I'm hesitant to add a TODO file here, as the wireless developers would
really have people help them out on the "clean" rt2860 driver that can
-be found at the rt2860.sf.net site.
+be found at the http://rt2x00.serialmonkey.com/ site.
But, if you wish to clean up this driver instead, here's a short list of
things that need to be done to get it into a more mergable shape:
@@ -8,7 +8,7 @@ things that need to be done to get it into a more mergable shape:
TODO:
- checkpatch.pl clean
- sparse clean
- - port to in-kernel 80211 stack
+ - port to in-kernel 80211 stack and common rt2x00 infrastructure
- remove reading from /etc/ config files
- review by the wireless developer community
diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c
index b67b9eba722..b3f88f52af7 100644
--- a/drivers/staging/rt2860/common/cmm_data.c
+++ b/drivers/staging/rt2860/common/cmm_data.c
@@ -105,9 +105,7 @@ NDIS_STATUS MiniportMMRequest(
PNDIS_PACKET pPacket;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
ULONG FreeNum;
-#ifdef RT2860
unsigned long IrqFlags = 0;
-#endif // RT2860 //
UCHAR IrqState;
UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
@@ -118,10 +116,9 @@ NDIS_STATUS MiniportMMRequest(
// 2860C use Tx Ring
IrqState = pAd->irq_disabled;
-#ifdef RT2860
+
if ((pAd->MACVersion == 0x28600100) && (!IrqState))
RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
-#endif // RT2860 //
do
{
@@ -175,17 +172,14 @@ NDIS_STATUS MiniportMMRequest(
} while (FALSE);
-#ifdef RT2860
// 2860C use Tx Ring
if ((pAd->MACVersion == 0x28600100) && (!IrqState))
RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
-#endif // RT2860 //
return Status;
}
-#ifdef RT2860
NDIS_STATUS MiniportMMRequestUnlock(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
@@ -253,7 +247,6 @@ NDIS_STATUS MiniportMMRequestUnlock(
return Status;
}
-#endif // RT2860 //
/*
@@ -290,17 +283,14 @@ NDIS_STATUS MlmeHardTransmit(
return NDIS_STATUS_FAILURE;
}
-#ifdef RT2860
if ( pAd->MACVersion == 0x28600100 )
return MlmeHardTransmitTxRing(pAd,QueIdx,pPacket);
else
-#endif // RT2860 //
return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
}
-#ifdef RT2860
NDIS_STATUS MlmeHardTransmitTxRing(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
@@ -366,7 +356,7 @@ NDIS_STATUS MlmeHardTransmitTxRing(
{
// outgoing frame always wakeup PHY to prevent frame lost
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
}
#endif // CONFIG_STA_SUPPORT //
pFirstTxWI =(PTXWI_STRUC)pSrcBufVA;
@@ -509,7 +499,6 @@ NDIS_STATUS MlmeHardTransmitTxRing(
return NDIS_STATUS_SUCCESS;
}
-#endif // RT2860 //
NDIS_STATUS MlmeHardTransmitMgmtRing(
@@ -541,7 +530,7 @@ NDIS_STATUS MlmeHardTransmitMgmtRing(
{
// outgoing frame always wakeup PHY to prevent frame lost
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
}
#endif // CONFIG_STA_SUPPORT //
@@ -1076,7 +1065,6 @@ VOID RTMPDeQueuePacket(
break;
}
-#ifdef RT2860
FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
#ifdef DBG_DIAGNOSE
@@ -1101,7 +1089,6 @@ VOID RTMPDeQueuePacket(
RTMPFreeTXDUponTxDmaDone(pAd, QueIdx);
FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
}
-#endif // RT2860 //
// probe the Queue Head
pQueue = &pAd->TxSwQueue[QueIdx];
@@ -1180,12 +1167,10 @@ VOID RTMPDeQueuePacket(
Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
#endif // CONFIG_STA_SUPPORT //
-#ifdef RT2860
DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
// static rate also need NICUpdateFifoStaCounters() function.
//if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
NICUpdateFifoStaCounters(pAd);
-#endif // RT2860 //
}
RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
@@ -1764,7 +1749,6 @@ PQUEUE_HEADER RTMPCheckTxSwQueue(
}
-#ifdef RT2860
BOOLEAN RTMPFreeTXDUponTxDmaDone(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx)
@@ -2309,7 +2293,6 @@ VOID DBGPRINT_RX_RING(
DBGPRINT_RAW(RT_DEBUG_TRACE,(" RxSwReadIdx [%d]=", AC0freeIdx));
DBGPRINT_RAW(RT_DEBUG_TRACE,(" pending-NDIS=%ld\n", pAd->RalinkCounters.PendingNdisPacketCount));
}
-#endif // RT2860 //
/*
========================================================================
@@ -2634,9 +2617,7 @@ MAC_TABLE_ENTRY *MacTableInsertEntry(
pEntry->AuthMode = pAd->StaCfg.AuthMode;
pEntry->WepStatus = pAd->StaCfg.WepStatus;
pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
-#ifdef RT2860
AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)i);
-#endif // RT2860 //
}
#endif // CONFIG_STA_SUPPORT //
}
@@ -2823,9 +2804,7 @@ VOID MacTableReset(
for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
{
-#ifdef RT2860
RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
-#endif // RT2860 //
if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
{
diff --git a/drivers/staging/rt2860/common/cmm_data_2860.c b/drivers/staging/rt2860/common/cmm_data_2860.c
index 419e50c3fc4..fae741e4bee 100644
--- a/drivers/staging/rt2860/common/cmm_data_2860.c
+++ b/drivers/staging/rt2860/common/cmm_data_2860.c
@@ -634,7 +634,7 @@ VOID RT28xxPciAsicRadioOff(
}
// Once go into this function, disable tx because don't want too many packets in queue to prevent HW stops.
- pAd->bPCIclkOffDisableTx = TRUE;
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
@@ -651,7 +651,7 @@ VOID RT28xxPciAsicRadioOff(
{
DBGPRINT(RT_DEBUG_TRACE, ("TbTTTime = 0x%x , give up this sleep. \n", TbTTTime));
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
- pAd->bPCIclkOffDisableTx = FALSE;
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
return;
}
else
@@ -688,18 +688,25 @@ VOID RT28xxPciAsicRadioOff(
if (i >= 50)
{
DBGPRINT(RT_DEBUG_TRACE, ("DMA keeps busy. return on RT28xxPciAsicRadioOff ()\n"));
- pAd->bPCIclkOffDisableTx = FALSE;
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
DmaCfg.field.EnableTxDMA = 1;
RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+ pAd->CheckDmaBusyCount++;
return;
}
+ else
+ {
+ pAd->CheckDmaBusyCount = 0;
+ }
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF);
// Set to 1R.
- tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
- RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+ if (pAd->Antenna.field.RxPath > 1)
+ {
+ tempBBP_R3 = (pAd->StaCfg.BBPR3 & 0xE7);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, tempBBP_R3);
+ }
// In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
@@ -714,8 +721,15 @@ VOID RT28xxPciAsicRadioOff(
AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
}
- // When PCI clock is off, don't want to service interrupt.
- RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+ if (Level != RTMP_HALT)
+ {
+ // Change Interrupt bitmask.
+ RTMP_IO_WRITE32(pAd, INT_MASK_CSR, AutoWakeupInt);
+ }
+ else
+ {
+ NICDisableInterrupt(pAd);
+ }
RTMP_IO_WRITE32(pAd, RX_CRX_IDX, pAd->RxRing.RxCpuIdx);
// Disable MAC Rx
@@ -726,7 +740,8 @@ VOID RT28xxPciAsicRadioOff(
// 2. Send Sleep command
RTMP_IO_WRITE32(pAd, H2M_MAILBOX_STATUS, 0xffffffff);
RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CID, 0xffffffff);
- AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout unit:40us.
+ // send POWER-SAVE command to MCU. high-byte = 1 save power as much as possible. high byte = 0 save less power
+ AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x1);
// 2-1. Wait command success
// Status = 1 : success, Status = 2, already sleep, Status = 3, Maybe MAC is busy so can't finish this task.
brc = AsicCheckCommanOk(pAd, PowerSafeCID);
@@ -734,7 +749,7 @@ VOID RT28xxPciAsicRadioOff(
if (brc == FALSE)
{
// try again
- AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x00); // send POWER-SAVE command to MCU. Timeout unit:40us.
+ AsicSendCommandToMcu(pAd, 0x30, PowerSafeCID, 0xff, 0x01); // send POWER-SAVE command to MCU. Timeout unit:40us.
//RTMPusecDelay(200);
brc = AsicCheckCommanOk(pAd, PowerSafeCID);
}
@@ -759,7 +774,7 @@ VOID RT28xxPciAsicRadioOff(
do
{
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
- if (DmaCfg.field.RxDMABusy == 0)
+ if ((DmaCfg.field.RxDMABusy == 0) && (DmaCfg.field.TxDMABusy == 0))
break;
RTMPusecDelay(20);
i++;
@@ -767,13 +782,12 @@ VOID RT28xxPciAsicRadioOff(
if (i >= 50)
{
+ pAd->CheckDmaBusyCount++;
DBGPRINT(RT_DEBUG_TRACE, ("DMA Rx keeps busy. on RT28xxPciAsicRadioOff ()\n"));
}
- // disable DMA Rx.
+ else
{
- RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &DmaCfg.word);
- DmaCfg.field.EnableRxDMA = 0;
- RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, DmaCfg.word);
+ pAd->CheckDmaBusyCount = 0;
}
if (Level == DOT11POWERSAVE)
@@ -799,7 +813,7 @@ VOID RT28xxPciAsicRadioOff(
if (Level == RTMP_HALT)
{
if ((brc == TRUE) && (i < 50))
- RTMPPCIeLinkCtrlSetting(pAd, 1);
+ RTMPPCIeLinkCtrlSetting(pAd, 0);
}
// 4. Set PCI configuration Space Link Comtrol fields. Only Radio Off needs to call this function
else
@@ -808,7 +822,7 @@ VOID RT28xxPciAsicRadioOff(
RTMPPCIeLinkCtrlSetting(pAd, 3);
}
- pAd->bPCIclkOffDisableTx = FALSE;
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_DISABLE_TX);
}
@@ -835,7 +849,8 @@ BOOLEAN RT28xxPciAsicRadioOn(
{
pAd->Mlme.bPsPollTimerRunning = FALSE;
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
- if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE))
+ if ((Level == GUIRADIO_OFF) || (Level == GUI_IDLE_POWER_SAVE)
+ || (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND)))
{
DBGPRINT(RT_DEBUG_TRACE, ("RT28xxPciAsicRadioOn ()\n"));
// 1. Set PCI Link Control in Configuration Space.
@@ -845,15 +860,14 @@ BOOLEAN RT28xxPciAsicRadioOn(
}
pAd->bPCIclkOff = FALSE;
-
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x3a80);
// 2. Send wake up command.
- AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
+ AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x02);
// 2-1. wait command ok.
brv = AsicCheckCommanOk(pAd, PowerWakeCID);
if (brv)
{
- //RTMP_IO_WRITE32(pAd, INT_MASK_CSR, (DELAYINTMASK|RxINT));
NICEnableInterrupt(pAd);
// 3. Enable Tx DMA.
@@ -893,13 +907,10 @@ BOOLEAN RT28xxPciAsicRadioOn(
VOID RT28xxPciStaAsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx)
+ IN UCHAR Level)
{
AUTO_WAKEUP_STRUC AutoWakeupCfg;
- if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- return;
-
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WAKEUP_NOW))
{
DBGPRINT(RT_DEBUG_TRACE, ("waking up now!\n"));
@@ -907,38 +918,48 @@ VOID RT28xxPciStaAsicForceWakeup(
}
OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
// Support PCIe Advance Power Save
- if (bFromTx == TRUE)
+ if (((Level == FROM_TX) && (pAd->Mlme.bPsPollTimerRunning == TRUE)) ||
+ (Level == RTMP_HALT))
{
pAd->Mlme.bPsPollTimerRunning = FALSE;
RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_WAKEUP);
- RTMPusecDelay(3000);
+ RTMPusecDelay(5000);
DBGPRINT(RT_DEBUG_TRACE, ("=======AsicForceWakeup===bFromTx\n"));
}
AutoWakeupCfg.word = 0;
RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
- if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
- {
- // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
- if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
- && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
- {
- // Must using 40MHz.
- AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
- AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
- }
- else
- {
- // Must using 20MHz.
- AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
- AsicLockChannel(pAd, pAd->CommonCfg.Channel);
- }
- }
+ // If this is called from Halt. ALWAYS force wakeup!!!
+ if (Level == RTMP_HALT)
+ {
+ RT28xxPciAsicRadioOn(pAd, RTMP_HALT);
+ }
+ else
+ {
+ if (RT28xxPciAsicRadioOn(pAd, DOT11POWERSAVE))
+ {
+ // In Radio Off, we turn off RF clk, So now need to call ASICSwitchChannel again.
+ if (INFRA_ON(pAd) && (pAd->CommonCfg.CentralChannel != pAd->CommonCfg.Channel)
+ && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ }
+ else
+ {
+ // Must using 20MHz.
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ }
+ }
+ }
}
else
{
@@ -1122,6 +1143,7 @@ VOID RT28xxPciMlmeRadioOn(
{
NICResetFromError(pAd);
+ /*
RTMPRingCleanUp(pAd, QID_AC_BK);
RTMPRingCleanUp(pAd, QID_AC_BE);
RTMPRingCleanUp(pAd, QID_AC_VI);
@@ -1129,6 +1151,7 @@ VOID RT28xxPciMlmeRadioOn(
RTMPRingCleanUp(pAd, QID_HCCA);
RTMPRingCleanUp(pAd, QID_MGMT);
RTMPRingCleanUp(pAd, QID_RX);
+ */
// Enable Tx/Rx
RTMPEnableRxTx(pAd);
@@ -1162,6 +1185,12 @@ VOID RT28xxPciMlmeRadioOFF(
WPDMA_GLO_CFG_STRUC GloCfg;
UINT32 i;
+ if (pAd->StaCfg.bRadio == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("-->MlmeRadioOff() return on bRadio == TRUE; \n"));
+ return;
+ }
+
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
return;
@@ -1169,13 +1198,12 @@ VOID RT28xxPciMlmeRadioOFF(
// Set LED
RTMPSetLED(pAd, LED_RADIO_OFF);
- // Set Radio off flag
- RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
BOOLEAN Cancelled;
+
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
{
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
@@ -1185,6 +1213,15 @@ VOID RT28xxPciMlmeRadioOFF(
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
BOOLEAN Cancelled;
+
+ // Always radio on since the NIC needs to set the MCU command (LED_RADIO_OFF).
+ if ((pAd->OpMode == OPMODE_STA) &&
+ (IDLE_ON(pAd)) &&
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+ {
+ RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
+ }
+
pAd->Mlme.bPsPollTimerRunning = FALSE;
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
@@ -1197,9 +1234,26 @@ VOID RT28xxPciMlmeRadioOFF(
//==========================================
// Clean up old bss table
BssTableInit(&pAd->ScanTab);
+
+ RTMPRingCleanUp(pAd, QID_AC_BK);
+ RTMPRingCleanUp(pAd, QID_AC_BE);
+ RTMPRingCleanUp(pAd, QID_AC_VI);
+ RTMPRingCleanUp(pAd, QID_AC_VO);
+ RTMPRingCleanUp(pAd, QID_HCCA);
+ RTMPRingCleanUp(pAd, QID_MGMT);
+ RTMPRingCleanUp(pAd, QID_RX);
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
+ {
+ RTMPSetTimer(&pAd->Mlme.RadioOnOffTimer, 500);
+ return;
+ }
}
#endif // CONFIG_STA_SUPPORT //
+ // Set Radio off flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
// Disable Tx/Rx DMA
RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
GloCfg.field.EnableTxDMA = 0;
diff --git a/drivers/staging/rt2860/common/cmm_info.c b/drivers/staging/rt2860/common/cmm_info.c
index dd92ac6eaed..c3e13195e12 100644
--- a/drivers/staging/rt2860/common/cmm_info.c
+++ b/drivers/staging/rt2860/common/cmm_info.c
@@ -814,7 +814,6 @@ INT Show_DescInfo_Proc(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
{
-#ifdef RT2860
INT i, QueIdx=0;
PRT28XX_RXD_STRUC pRxD;
PTXD_STRUC pTxD;
@@ -845,7 +844,6 @@ INT Show_DescInfo_Proc(
hex_dump("Rx Descriptor", (char *)pRxD, 16);
printk("pRxD->DDONE = %x\n", pRxD->DDONE);
}
-#endif // RT2860 //
return TRUE;
}
@@ -1803,9 +1801,7 @@ VOID RTMPAddWcidAttributeEntry(
}
// For key index and ext IV bit, so only need to update the position(offset+3).
-#ifdef RT2860
RTMP_IO_WRITE8(pAd, offset+3, IVEIV);
-#endif // RT2860 //
DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
@@ -2827,9 +2823,7 @@ INT Set_OpMode_Proc(
Value = simple_strtol(arg, 0, 10);
-#ifdef RT2860
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
-#endif // RT2860 //
{
DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
return FALSE;
diff --git a/drivers/staging/rt2860/common/cmm_sync.c b/drivers/staging/rt2860/common/cmm_sync.c
index 40e4109118e..d29e0b630e2 100644
--- a/drivers/staging/rt2860/common/cmm_sync.c
+++ b/drivers/staging/rt2860/common/cmm_sync.c
@@ -470,7 +470,7 @@ VOID ScanNextChannel(
{
// BBP and RF are not accessible in PS mode, we has to wake them up first
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
// leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
if (pAd->StaCfg.Psm == PWR_SAVE)
diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c
index 81c332ac252..69baf522fa0 100644
--- a/drivers/staging/rt2860/common/cmm_wpa.c
+++ b/drivers/staging/rt2860/common/cmm_wpa.c
@@ -39,8 +39,10 @@
// WPA OUI
UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_WEP40[4] = {0x00, 0x50, 0xF2, 0x01};
UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
+UCHAR OUI_WPA_WEP104[4] = {0x00, 0x50, 0xF2, 0x05};
UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
// WPA2 OUI
@@ -49,6 +51,7 @@ UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
+UCHAR OUI_WPA2_WEP104[4] = {0x00, 0x0F, 0xAC, 0x05};
// MSA OUI
UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
@@ -367,6 +370,24 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
+#ifdef CONFIG_STA_SUPPORT
+ if ((pAd->OpMode == OPMODE_STA) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
+ {
+ UINT GroupCipher = pAd->StaCfg.GroupCipher;
+ switch(GroupCipher)
+ {
+ case Ndis802_11GroupWEP40Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP40, 4);
+ break;
+ case Ndis802_11GroupWEP104Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_WEP104, 4);
+ break;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
// swap for big-endian platform
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
@@ -427,11 +448,28 @@ static VOID RTMPInsertRsnIeCipher(
break;
}
+#ifdef CONFIG_STA_SUPPORT
+ if ((pAd->OpMode == OPMODE_STA) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.GroupCipher != Ndis802_11Encryption3Enabled))
+ {
+ UINT GroupCipher = pAd->StaCfg.GroupCipher;
+ switch(GroupCipher)
+ {
+ case Ndis802_11GroupWEP40Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP40, 4);
+ break;
+ case Ndis802_11GroupWEP104Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_WEP104, 4);
+ break;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
// swap for big-endian platform
pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
}
-
}
/*
diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c
index 229747095ae..c00f9ab9c46 100644
--- a/drivers/staging/rt2860/common/mlme.c
+++ b/drivers/staging/rt2860/common/mlme.c
@@ -527,7 +527,6 @@ NDIS_STATUS MlmeInit(
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
@@ -537,7 +536,6 @@ NDIS_STATUS MlmeInit(
RTMPInitTimer(pAd, &pAd->Mlme.RadioOnOffTimer, GET_TIMER_FUNCTION(RadioOnExec), pAd, FALSE);
}
}
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
} while (FALSE);
@@ -711,13 +709,11 @@ VOID MlmeHalt(
RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
RTMPCancelTimer(&pAd->Mlme.RadioOnOffTimer, &Cancelled);
}
-#endif // RT2860 //
#ifdef QOS_DLS_SUPPORT
for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
@@ -808,21 +804,34 @@ VOID MlmePeriodicExec(
ULONG TxTotalCnt;
PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+ //Baron 2008/07/10
+ //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
+ //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
+ //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
+ if(pAd->StaCfg.WepStatus<2)
+ {
+ pAd->StaCfg.WpaSupplicantUP = 0;
+ }
+ else
+ {
+ pAd->StaCfg.WpaSupplicantUP = 1;
+ }
+
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
// If Hardware controlled Radio enabled, we have to check GPIO pin2 every 2 second.
// Move code to here, because following code will return when radio is off
- if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) && (pAd->StaCfg.bHardwareRadio == TRUE) &&
+ if ((pAd->Mlme.PeriodicRound % (MLME_TASK_EXEC_MULTIPLE * 2) == 0) &&
+ (pAd->StaCfg.bHardwareRadio == TRUE) &&
+ (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
- (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
- (pAd->bPCIclkOff == FALSE))
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
{
UINT32 data = 0;
// Read GPIO pin2 as Hardware controlled radio state
- RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+ RTMP_IO_FORCE_READ32(pAd, GPIO_CTRL_CFG, &data);
if (data & 0x04)
{
pAd->StaCfg.bHwRadio = TRUE;
@@ -849,7 +858,6 @@ VOID MlmePeriodicExec(
}
}
}
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
// Do nothing if the driver is starting halt state.
@@ -860,6 +868,45 @@ VOID MlmePeriodicExec(
fRTMP_ADAPTER_RESET_IN_PROGRESS))))
return;
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((pAd->RalinkCounters.LastReceivedByteCount == pAd->RalinkCounters.ReceivedByteCount) && (pAd->StaCfg.bRadio == TRUE))
+ {
+ // If ReceiveByteCount doesn't change, increase SameRxByteCount by 1.
+ pAd->SameRxByteCount++;
+ }
+ else
+ pAd->SameRxByteCount = 0;
+
+ // If after BBP, still not work...need to check to reset PBF&MAC.
+ if (pAd->SameRxByteCount == 702)
+ {
+ pAd->SameRxByteCount = 0;
+ AsicResetPBF(pAd);
+ AsicResetMAC(pAd);
+ }
+
+ // If SameRxByteCount keeps happens for 2 second in infra mode, or for 60 seconds in idle mode.
+ if (((INFRA_ON(pAd)) && (pAd->SameRxByteCount > 20)) || ((IDLE_ON(pAd)) && (pAd->SameRxByteCount > 600)))
+ {
+ if ((pAd->StaCfg.bRadio == TRUE) && (pAd->SameRxByteCount < 700))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("---> SameRxByteCount = %lu !!!!!!!!!!!!!!! \n", pAd->SameRxByteCount));
+ pAd->SameRxByteCount = 700;
+ AsicResetBBP(pAd);
+ }
+ }
+
+ // Update lastReceiveByteCount.
+ pAd->RalinkCounters.LastReceivedByteCount = pAd->RalinkCounters.ReceivedByteCount;
+
+ if ((pAd->CheckDmaBusyCount > 3) && (IDLE_ON(pAd)))
+ {
+ pAd->CheckDmaBusyCount = 0;
+ AsicResetFromDMABusy(pAd);
+ }
+ }
+
RT28XX_MLME_PRE_SANITY_CHECK(pAd);
#ifdef RALINK_ATE
@@ -1022,9 +1069,7 @@ VOID MlmePeriodicExec(
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
-#ifdef RT2860
if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->bPCIclkOff == FALSE))
-#endif // RT2860 //
{
// When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
// and sending CTS-to-self over and over.
@@ -1081,6 +1126,19 @@ VOID STAMlmePeriodicExec(
pAd->StaCfg.bBlockAssoc = FALSE;
}
+ //Baron 2008/07/10
+ //printk("Baron_Test:\t%s", RTMPGetRalinkEncryModeStr(pAd->StaCfg.WepStatus));
+ //If the STA security setting is OPEN or WEP, pAd->StaCfg.WpaSupplicantUP = 0.
+ //If the STA security setting is WPAPSK or WPA2PSK, pAd->StaCfg.WpaSupplicantUP = 1.
+ if(pAd->StaCfg.WepStatus<2)
+ {
+ pAd->StaCfg.WpaSupplicantUP = 0;
+ }
+ else
+ {
+ pAd->StaCfg.WpaSupplicantUP = 1;
+ }
+
if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
{
if (pAd->IndicateMediaState == NdisMediaStateConnected)
@@ -1090,6 +1148,15 @@ VOID STAMlmePeriodicExec(
pAd->PreMediaState = pAd->IndicateMediaState;
}
+ if ((pAd->OpMode == OPMODE_STA) && (IDLE_ON(pAd)) &&
+ (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
+ (pAd->Mlme.SyncMachine.CurrState == SYNC_IDLE) &&
+ (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+ (RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+ {
+ RT28xxPciAsicRadioOff(pAd, GUI_IDLE_POWER_SAVE, 0);
+ }
@@ -2781,7 +2848,7 @@ VOID MlmeCheckPsmChange(
if (INFRA_ON(pAd) &&
(PowerMode != Ndis802_11PowerModeCAM) &&
(pAd->StaCfg.Psm == PWR_ACTIVE) &&
- (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
+ RTMP_TEST_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP))
{
NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
pAd->RalinkCounters.RxCountSinceLastNULL = 0;
@@ -4065,7 +4132,9 @@ VOID BssTableSsidSort(
continue;
// check group cipher
- if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+ if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+ (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+ (pInBss->WPA.GroupCipher != Ndis802_11GroupWEP104Enabled))
continue;
// check pairwise cipher, skip if none matched
@@ -4084,7 +4153,9 @@ VOID BssTableSsidSort(
continue;
// check group cipher
- if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+ if ((pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher) &&
+ (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP40Enabled) &&
+ (pInBss->WPA2.GroupCipher != Ndis802_11GroupWEP104Enabled))
continue;
// check pairwise cipher, skip if none matched
@@ -4371,8 +4442,10 @@ VOID BssCipherParse(
switch (*pTmp)
{
case 1:
- case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
- pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11GroupWEP40Enabled;
+ break;
+ case 5:
+ pBss->WPA.GroupCipher = Ndis802_11GroupWEP104Enabled;
break;
case 2:
pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -4489,8 +4562,10 @@ VOID BssCipherParse(
switch (pCipher->Type)
{
case 1:
- case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
- pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA2.GroupCipher = Ndis802_11GroupWEP40Enabled;
+ break;
+ case 5:
+ pBss->WPA2.GroupCipher = Ndis802_11GroupWEP104Enabled;
break;
case 2:
pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
@@ -4953,16 +5028,13 @@ BOOLEAN MlmeDequeue(
VOID MlmeRestartStateMachine(
IN PRTMP_ADAPTER pAd)
{
-#ifdef RT2860
MLME_QUEUE_ELEM *Elem = NULL;
-#endif // RT2860 //
#ifdef CONFIG_STA_SUPPORT
BOOLEAN Cancelled;
#endif // CONFIG_STA_SUPPORT //
DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
-#ifdef RT2860
NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
if(pAd->Mlme.bRunning)
{
@@ -4990,7 +5062,6 @@ VOID MlmeRestartStateMachine(
DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n"));
}
}
-#endif // RT2860 //
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
@@ -5039,12 +5110,10 @@ VOID MlmeRestartStateMachine(
}
#endif // CONFIG_STA_SUPPORT //
-#ifdef RT2860
// Remove running state
NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
pAd->Mlme.bRunning = FALSE;
NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
-#endif // RT2860 //
}
/*! \brief test if the MLME Queue is empty
@@ -6149,6 +6218,12 @@ VOID AsicAdjustTxPower(
ULONG TxPwr[5];
CHAR Value;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+ || (pAd->bPCIclkOff == TRUE)
+ || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF)
+ || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ return;
+
if (pAd->CommonCfg.BBPCurrentBW == BW_40)
{
if (pAd->CommonCfg.CentralChannel > 14)
@@ -6493,10 +6568,10 @@ VOID AsicForceSleep(
*/
VOID AsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx)
+ IN UCHAR Level)
{
DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
- RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
+ RT28XX_STA_FORCE_WAKEUP(pAd, Level);
}
#endif // CONFIG_STA_SUPPORT //
/*
@@ -6710,7 +6785,6 @@ VOID AsicEnableIbssSync(
csr9.field.bTsfTicking = 0;
RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
-#ifdef RT2860
// move BEACON TXD and frame content to on-chip memory
ptr = (PUCHAR)&pAd->BeaconTxWI;
for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
@@ -6728,7 +6802,6 @@ VOID AsicEnableIbssSync(
RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
ptr +=4;
}
-#endif // RT2860 //
// start sending BEACON
csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
@@ -7097,9 +7170,7 @@ VOID AsicAddSharedKeyEntry(
{
ULONG offset; //, csr0;
SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
INT i;
-#endif // RT2860 //
DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
//============================================================================================
@@ -7121,7 +7192,6 @@ VOID AsicAddSharedKeyEntry(
//
// fill key material - key + TX MIC + RX MIC
//
-#ifdef RT2860
offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
for (i=0; i<MAX_LEN_OF_SHARE_KEY; i++)
{
@@ -7145,7 +7215,6 @@ VOID AsicAddSharedKeyEntry(
RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
}
}
-#endif // RT2860 //
//
@@ -7320,9 +7389,7 @@ VOID AsicAddKeyEntry(
PUCHAR pTxtsc = pCipherKey->TxTsc;
UCHAR CipherAlg = pCipherKey->CipherAlg;
SHAREDKEY_MODE_STRUC csr1;
-#ifdef RT2860
UCHAR i;
-#endif // RT2860 //
DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
//
@@ -7337,7 +7404,6 @@ VOID AsicAddKeyEntry(
// 2.) Set Key to Asic
//
//for (i = 0; i < KeyLen; i++)
-#ifdef RT2860
for (i = 0; i < MAX_LEN_OF_PEER_KEY; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
@@ -7363,7 +7429,6 @@ VOID AsicAddKeyEntry(
RTMP_IO_WRITE8(pAd, offset + i, pRxMic[i]);
}
}
-#endif // RT2860 //
//
@@ -7372,7 +7437,6 @@ VOID AsicAddKeyEntry(
//
if (bTxKey)
{
-#ifdef RT2860
offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
//
// Write IV
@@ -7395,7 +7459,6 @@ VOID AsicAddKeyEntry(
{
RTMP_IO_WRITE8(pAd, offset + i, pTxtsc[i + 2]);
}
-#endif // RT2860 //
AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
}
@@ -7461,12 +7524,10 @@ VOID AsicAddPairwiseKeyEntry(
// EKEY
offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
-#ifdef RT2860
for (i=0; i<MAX_LEN_OF_PEER_KEY; i++)
{
RTMP_IO_WRITE8(pAd, offset + i, pKey[i]);
}
-#endif // RT2860 //
for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
{
UINT32 Value;
@@ -7478,22 +7539,18 @@ VOID AsicAddPairwiseKeyEntry(
// MIC KEY
if (pTxMic)
{
-#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset+i, pTxMic[i]);
}
-#endif // RT2860 //
}
offset += 8;
if (pRxMic)
{
-#ifdef RT2860
for (i=0; i<8; i++)
{
RTMP_IO_WRITE8(pAd, offset+i, pRxMic[i]);
}
-#endif // RT2860 //
}
DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
@@ -7542,11 +7599,9 @@ BOOLEAN AsicSendCommandToMcu(
HOST_CMD_CSR_STRUC H2MCmd;
H2M_MAILBOX_STRUC H2MMailbox;
ULONG i = 0;
-#ifdef RT2860
#ifdef RALINK_ATE
static UINT32 j = 0;
#endif // RALINK_ATE //
-#endif // RT2860 //
do
{
RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
@@ -7558,7 +7613,6 @@ BOOLEAN AsicSendCommandToMcu(
if (i >= 100)
{
-#ifdef RT2860
#ifdef RALINK_ATE
if (pAd->ate.bFWLoading == TRUE)
{
@@ -7583,14 +7637,33 @@ BOOLEAN AsicSendCommandToMcu(
}
else
#endif // RALINK_ATE //
-#endif // RT2860 //
{
+ UINT32 Data;
+
+ // Reset DMA
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x2;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
+ // Reset DMA/CPU ring index
+ RTMPRingCleanUp(pAd, QID_AC_BK);
+ RTMPRingCleanUp(pAd, QID_AC_BE);
+ RTMPRingCleanUp(pAd, QID_AC_VI);
+ RTMPRingCleanUp(pAd, QID_AC_VO);
+ RTMPRingCleanUp(pAd, QID_HCCA);
+ RTMPRingCleanUp(pAd, QID_MGMT);
+ RTMPRingCleanUp(pAd, QID_RX);
+
+ // Clear Reset
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data &= 0xfffffffd;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
}
- return FALSE;
+ //return FALSE;
}
-#ifdef RT2860
#ifdef RALINK_ATE
else if (pAd->ate.bFWLoading == TRUE)
{
@@ -7600,7 +7673,6 @@ BOOLEAN AsicSendCommandToMcu(
j = 0;
}
#endif // RALINK_ATE //
-#endif // RT2860 //
H2MMailbox.field.Owner = 1; // pass ownership to MCU
H2MMailbox.field.CmdToken = Token;
@@ -7619,7 +7691,6 @@ BOOLEAN AsicSendCommandToMcu(
return TRUE;
}
-#ifdef RT2860
BOOLEAN AsicCheckCommanOk(
IN PRTMP_ADAPTER pAd,
IN UCHAR Command)
@@ -7684,7 +7755,6 @@ BOOLEAN AsicCheckCommanOk(
return FALSE;
}
-#endif // RT2860 //
/*
========================================================================
@@ -8096,10 +8166,8 @@ VOID AsicEvaluateRxAnt(
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
@@ -8211,9 +8279,7 @@ VOID AsicRxAntEvalTimeout(
BBPR3 |= (0x0);
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
-#ifdef RT2860
- pAd->StaCfg.BBPR3 = BBPR3;
-#endif // RT2860 //
+ pAd->StaCfg.BBPR3 = BBPR3;
}
#endif // CONFIG_STA_SUPPORT //
@@ -8439,10 +8505,7 @@ VOID AsicStaBbpTuning(
&& (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
)
&& !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
-#ifdef RT2860
- && (pAd->bPCIclkOff == FALSE)
-#endif // RT2860 //
- )
+ && (pAd->bPCIclkOff == FALSE))
{
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
R66 = OrigR66Value;
@@ -8518,6 +8581,106 @@ VOID AsicStaBbpTuning(
}
}
+
+VOID AsicResetFromDMABusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Data;
+ BOOLEAN bCtrl = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
+
+ // Be sure restore link control value so we can write register.
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AsicResetFromDMABusy==>\n"));
+ RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAd->bPCIclkOff = FALSE;
+ bCtrl = TRUE;
+ }
+ // Reset DMA
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x2;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ // After Reset DMA, DMA index will become Zero. So Driver need to reset all ring indexs too.
+ // Reset DMA/CPU ring index
+ RTMPRingCleanUp(pAd, QID_AC_BK);
+ RTMPRingCleanUp(pAd, QID_AC_BE);
+ RTMPRingCleanUp(pAd, QID_AC_VI);
+ RTMPRingCleanUp(pAd, QID_AC_VO);
+ RTMPRingCleanUp(pAd, QID_HCCA);
+ RTMPRingCleanUp(pAd, QID_MGMT);
+ RTMPRingCleanUp(pAd, QID_RX);
+
+ // Clear Reset
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data &= 0xfffffffd;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ // If in Radio off, should call RTMPPCIePowerLinkCtrl again.
+ if ((bCtrl == TRUE) && (pAd->StaCfg.bRadio == FALSE))
+ RTMPPCIeLinkCtrlSetting(pAd, 3);
+
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetFromDMABusy !!!!!!!!!!!!!!!!!!!!!!! \n"));
+}
+
+VOID AsicResetBBP(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+
+ // After hard-reset BBP, initialize all BBP values.
+ NICRestoreBBPValue(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset BBP !!!!!!!!!!!!!!!!!!!!!!! \n"));
+}
+
+VOID AsicResetMAC(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Data;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("---> AsicResetMAC !!!! \n"));
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x4;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+ Data &= 0xfffffffb;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- AsicResetMAC !!!! \n"));
+}
+
+VOID AsicResetPBF(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Value1, Value2;
+ ULONG Data;
+
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &Value1);
+ RTMP_IO_READ32(pAd, PBF_DBG, &Value2);
+
+ Value2 &= 0xff;
+ // sum should be equals to 0xff, which is the total buffer size.
+ if ((Value1 + Value2) < 0xff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("---> Asic HardReset PBF !!!! \n"));
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &Data);
+ Data |= 0x8;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+ Data &= 0xfffffff7;
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, Data);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- Asic HardReset PBF !!!! \n"));
+ }
+}
#endif // CONFIG_STA_SUPPORT //
VOID RTMPSetAGCInitValue(
diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c
index 563f2c5bb85..8a00cee3ee9 100644
--- a/drivers/staging/rt2860/common/rtmp_init.c
+++ b/drivers/staging/rt2860/common/rtmp_init.c
@@ -149,9 +149,7 @@ RTMP_REG_PAIR MACRegTable[] = {
{GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
{GF40_PROT_CFG, 0x03F44084},
{MM20_PROT_CFG, 0x01744004},
-#ifdef RT2860
{MM40_PROT_CFG, 0x03F54084},
-#endif // RT2860 //
{TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
{TX_RTS_CFG, 0x00092b20},
{EXP_ACK_TIME, 0x002400ca}, // default value
@@ -188,9 +186,7 @@ RTMP_REG_PAIR STAMACRegTable[] = {
#define FIRMWAREIMAGEV1_LENGTH 0x1000
#define FIRMWAREIMAGEV2_LENGTH 0x1000
-#ifdef RT2860
#define FIRMWARE_MINOR_VERSION 2
-#endif // RT2860 //
/*
@@ -248,9 +244,7 @@ NDIS_STATUS RTMPAllocAdapterBlock(
// Init spin locks
NdisAllocateSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
NdisAllocateSpinLock(&pAd->RxRingLock);
-#endif // RT2860 //
for (index =0 ; index < NUM_OF_TX_RING; index++)
{
@@ -1555,10 +1549,7 @@ VOID NICInitAsicFromEEPROM(
pAd->LedCntl.word = 0x01;
pAd->Led1 = 0x5555;
pAd->Led2 = 0x2221;
-
-#ifdef RT2860
pAd->Led3 = 0xA9F8;
-#endif // RT2860 //
}
AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
@@ -1594,12 +1585,10 @@ VOID NICInitAsicFromEEPROM(
else
{
RTMPSetLED(pAd, LED_RADIO_ON);
-#ifdef RT2860
AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
AsicSendCommandToMcu(pAd, 0x31, PowerWakeCID, 0x00, 0x00);
// 2-1. wait command ok.
AsicCheckCommanOk(pAd, PowerWakeCID);
-#endif // RT2860 //
}
}
#endif // CONFIG_STA_SUPPORT //
@@ -1677,10 +1666,8 @@ NDIS_STATUS NICInitializeAdapter(
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
WPDMA_GLO_CFG_STRUC GloCfg;
-#ifdef RT2860
UINT32 Value;
DELAY_INT_CFG_STRUC IntCfg;
-#endif // RT2860 //
ULONG i =0, j=0;
AC_TXOP_CSR0_STRUC csr0;
@@ -1719,11 +1706,9 @@ retry:
// asic simulation sequence put this ahead before loading firmware.
// pbf hardware reset
-#ifdef RT2860
RTMP_IO_WRITE32(pAd, WPDMA_RST_IDX, 0x1003f); // 0x10000 for reset rx, 0x3f resets all 6 tx rings.
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe1f);
RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0xe00);
-#endif // RT2860 //
// Initialze ASIC for TX & Rx operation
if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
@@ -1737,7 +1722,6 @@ retry:
}
-#ifdef RT2860
// Write AC_BK base address register
Value = RTMP_GetPhysicalAddressLow(pAd->TxRing[QID_AC_BK].Cell[0].AllocPa);
RTMP_IO_WRITE32(pAd, TX_BASE_PTR1, Value);
@@ -1810,7 +1794,6 @@ retry:
// Write RX_RING_CSR register
Value = RX_RING_SIZE;
RTMP_IO_WRITE32(pAd, RX_MAX_CNT, Value);
-#endif // RT2860 //
// WMM parameter
@@ -1829,7 +1812,6 @@ retry:
RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
-#ifdef RT2860
// 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
i = 0;
do
@@ -1848,7 +1830,6 @@ retry:
IntCfg.word = 0;
RTMP_IO_WRITE32(pAd, DELAY_INT_CFG, IntCfg.word);
-#endif // RT2860 //
// reset action
@@ -1889,7 +1870,6 @@ NDIS_STATUS NICInitializeAsic(
DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
-#ifdef RT2860
if (bHardReset == TRUE)
{
RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
@@ -1914,7 +1894,6 @@ NDIS_STATUS NICInitializeAsic(
}
}
#endif // CONFIG_STA_SUPPORT //
-#endif // RT2860 //
//
@@ -2041,6 +2020,131 @@ NDIS_STATUS NICInitializeAsic(
return NDIS_STATUS_SUCCESS;
}
+
+VOID NICRestoreBBPValue(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR index;
+ UCHAR Value = 0;
+ ULONG Data;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("---> NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n"));
+ // Initialize BBP register to default value (rtmp_init.c)
+ for (index = 0; index < NUM_BBP_REG_PARMS; index++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[index].Register, BBPRegTable[index].Value);
+ }
+ // copy from (rtmp_init.c)
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
+ }
+
+ // copy from (connect.c LinkUp function)
+ if (INFRA_ON(pAd))
+ {
+ // Change to AP channel
+ if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ // RX : control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+ // Record BBPR3 setting, But don't keep R Antenna # information.
+ pAd->StaCfg.BBPR3 = Value;
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data |= 0x1;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value |= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+ // Record BBPR3 setting, But don't keep R Antenna # information.
+ pAd->StaCfg.BBPR3 = Value;
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else
+ {
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+ // Record BBPR3 setting, But don't keep R Antenna # information.
+ pAd->StaCfg.BBPR3 = Value;
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz LINK UP !!! \n" ));
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- NICRestoreBBPValue !!!!!!!!!!!!!!!!!!!!!!! \n"));
+}
+
/*
========================================================================
@@ -3028,11 +3132,10 @@ VOID UserCfgInit(
pAd->CommonCfg.BBPCurrentBW = BW_20;
pAd->LedCntl.word = 0;
-#ifdef RT2860
pAd->LedIndicatorStregth = 0;
pAd->RLnkCtrlOffset = 0;
pAd->HostLnkCtrlOffset = 0;
-#endif // RT2860 //
+ pAd->CheckDmaBusyCount = 0;
pAd->bAutoTxAgcA = FALSE; // Default is OFF
pAd->bAutoTxAgcG = FALSE; // Default is OFF
@@ -3292,9 +3395,7 @@ VOID UserCfgInit(
pAd->ate.bRxFer = 0;
pAd->ate.bQATxStart = FALSE;
pAd->ate.bQARxStart = FALSE;
-#ifdef RT2860
pAd->ate.bFWLoading = FALSE;
-#endif // RT2860 //
#ifdef RALINK_28xx_QA
//pAd->ate.Repeat = 0;
pAd->ate.TxStatus = 0;
@@ -3304,11 +3405,9 @@ VOID UserCfgInit(
pAd->CommonCfg.bWiFiTest = FALSE;
-#ifdef RT2860
- pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
-
+ pAd->bPCIclkOff = FALSE;
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
}
diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c
index 0265a6d1df1..b3650ec4656 100644
--- a/drivers/staging/rt2860/common/spectrum.c
+++ b/drivers/staging/rt2860/common/spectrum.c
@@ -1596,7 +1596,7 @@ static VOID PeerMeasureReportAction(
if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
return;
}
diff --git a/drivers/staging/rt2860/config.mk b/drivers/staging/rt2860/config.mk
index f57d7bbffb2..25bd55a7aab 100644
--- a/drivers/staging/rt2860/config.mk
+++ b/drivers/staging/rt2860/config.mk
@@ -108,10 +108,6 @@ ifeq ($(HAS_EXT_BUILD_CHANNEL_LIST),y)
WFLAGS += -DEXT_BUILD_CHANNEL_LIST
endif
-ifeq ($(CHIPSET),2860)
-WFLAGS +=-DRT2860
-endif
-
ifeq ($(CHIPSET),2870)
WFLAGS +=-DRT2870
endif
diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h
index f2f91b607c4..5e6ed9f62f9 100644
--- a/drivers/staging/rt2860/oid.h
+++ b/drivers/staging/rt2860/oid.h
@@ -544,6 +544,8 @@ typedef enum _NDIS_802_11_WEP_STATUS
Ndis802_11Encryption3KeyAbsent,
Ndis802_11Encryption4Enabled, // TKIP or AES mix
Ndis802_11Encryption4KeyAbsent,
+ Ndis802_11GroupWEP40Enabled,
+ Ndis802_11GroupWEP104Enabled,
} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
diff --git a/drivers/staging/rt2860/rt2860.h b/drivers/staging/rt2860/rt2860.h
index 01720190662..4fbec906e10 100644
--- a/drivers/staging/rt2860/rt2860.h
+++ b/drivers/staging/rt2860/rt2860.h
@@ -46,18 +46,10 @@
Status = NDIS_STATUS_SUCCESS;
/* function declarations */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define IRQ_HANDLE_TYPE irqreturn_t
-#else
-#define IRQ_HANDLE_TYPE void
-#endif
IRQ_HANDLE_TYPE
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19))
rt2860_interrupt(int irq, void *dev_instance);
-#else
-rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-#endif
/* ----------------- Frimware Related MACRO ----------------- */
#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
@@ -237,9 +229,7 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
#define RTMP_MSI_DISABLE(_pAd)
#endif // PCI_MSI_SUPPORT //
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
#define SA_SHIRQ IRQF_SHARED
-#endif
#define RT28XX_IRQ_REQUEST(net_dev) \
{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv); \
@@ -251,20 +241,12 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
printk("RT2860: request_irq ERROR(%d)\n", retval); \
return retval; } }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define RT28XX_IRQ_RELEASE(net_dev) \
{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->ml_priv); \
POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
synchronize_irq(_pObj->pci_dev->irq); \
free_irq(_pObj->pci_dev->irq, (net_dev)); \
RTMP_MSI_DISABLE(_pAd); }
-#else
-#define RT28XX_IRQ_RELEASE(net_dev) \
-{ PRTMP_ADAPTER _pAd = (PRTMP_ADAPTER)((net_dev)->priv); \
- POS_COOKIE _pObj = (POS_COOKIE)(_pAd->OS_Cookie); \
- free_irq(_pObj->pci_dev->irq, (net_dev)); \
- RTMP_MSI_DISABLE(_pAd); }
-#endif
#define RT28XX_IRQ_INIT(pAd) \
{ pAd->int_enable_reg = ((DELAYINTMASK) | \
@@ -333,8 +315,8 @@ rt2860_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
reg16 = cpu2le16(Configuration); \
pci_write_config_word(pci_dev, offset, reg16); \
-#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
- RT28xxPciStaAsicForceWakeup(pAd, bFromTx);
+#define RT28XX_STA_FORCE_WAKEUP(pAd, Level) \
+ RT28xxPciStaAsicForceWakeup(pAd, Level);
#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
RT28xxPciStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
diff --git a/drivers/staging/rt2860/rt28xx.h b/drivers/staging/rt2860/rt28xx.h
index ff23043e560..e5e6f0a8de6 100644
--- a/drivers/staging/rt2860/rt28xx.h
+++ b/drivers/staging/rt2860/rt28xx.h
@@ -1670,11 +1670,9 @@ typedef struct _HW_WCID_ENTRY { // 8-byte per entry
#define E2PROM_CSR 0x0004
#define IO_CNTL_CSR 0x77d0
-#ifdef RT2860
// 8051 firmware image for RT2860 - base address = 0x4000
#define FIRMWARE_IMAGE_BASE 0x2000
#define MAX_FIRMWARE_IMAGE_SIZE 0x2000 // 8kbyte
-#endif // RT2860 //
// ================================================================
@@ -2029,7 +2027,6 @@ typedef struct PACKED _TXWI_STRUC {
//
// Rx descriptor format, Rx Ring
//
-#ifdef RT2860
#ifdef RT_BIG_ENDIAN
typedef struct PACKED _RXD_STRUC {
// Word 0
@@ -2098,7 +2095,6 @@ typedef struct PACKED _RXD_STRUC {
UINT32 Rsv1:13;
} RXD_STRUC, *PRXD_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
#endif
-#endif // RT2860 //
//
// RXWI wireless information format, in PBF. invisible in driver.
//
diff --git a/drivers/staging/rt2860/rt_ate.c b/drivers/staging/rt2860/rt_ate.c
index f3316ec0b15..1ed73c9e6b6 100644
--- a/drivers/staging/rt2860/rt_ate.c
+++ b/drivers/staging/rt2860/rt_ate.c
@@ -68,7 +68,6 @@ static int CheckMCSValid(
IN UCHAR Mode,
IN UCHAR Mcs);
-#ifdef RT2860
static VOID ATEWriteTxWI(
IN PRTMP_ADAPTER pAd,
IN PTXWI_STRUC pOutTxWI,
@@ -87,7 +86,6 @@ static VOID ATEWriteTxWI(
IN UCHAR Txopmode,
IN BOOLEAN CfAck,
IN HTTRANSMIT_SETTING *pTransmit);
-#endif // RT2860 //
static VOID SetJapanFilter(
@@ -95,7 +93,6 @@ static VOID SetJapanFilter(
/*=========================end of prototype=========================*/
-#ifdef RT2860
static INT TxDmaBusy(
IN PRTMP_ADAPTER pAd)
{
@@ -153,7 +150,6 @@ static VOID RtmpDmaEnable(
return;
}
-#endif // RT2860 //
static VOID BbpSoftReset(
@@ -488,7 +484,6 @@ static INT ATETxPwrHandler(
TRUE if all parameters are OK, FALSE otherwise
==========================================================================
*/
-#ifdef RT2860
static INT ATECmdHandler(
IN PRTMP_ADAPTER pAd,
IN PUCHAR arg)
@@ -1297,7 +1292,6 @@ static INT ATECmdHandler(
return TRUE;
}
-#endif // RT2860 //
/* */
/* */
/*=======================End of RT2860=======================*/
@@ -2907,7 +2901,6 @@ VOID ATEAsicAdjustTxPower(
None
========================================================================
*/
-#ifdef RT2860
static VOID ATEWriteTxWI(
IN PRTMP_ADAPTER pAd,
IN PTXWI_STRUC pOutTxWI,
@@ -2972,7 +2965,6 @@ static VOID ATEWriteTxWI(
return;
}
-#endif // RT2860 //
/*
========================================================================
@@ -3249,13 +3241,11 @@ VOID RTMPStationStart(
IN PRTMP_ADAPTER pAd)
{
ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
-#ifdef RT2860
- pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+epAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
//
// We did not cancel this timer when entering ATE mode.
//
// RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
-#endif // RT2860 //
ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
}
#endif // CONFIG_STA_SUPPORT //
@@ -3268,7 +3258,6 @@ VOID RTMPStationStart(
This routine should only be used in ATE mode.
==========================================================================
*/
-#ifdef RT2860
static INT ATESetUpFrame(
IN PRTMP_ADAPTER pAd,
IN UINT32 TxIdx)
@@ -3455,7 +3444,6 @@ static INT ATESetUpFrame(
/* */
/* */
/*=======================End of RT2860=======================*/
-#endif // RT2860 //
VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
@@ -4578,9 +4566,7 @@ VOID RtmpDoAte(
{
if (pAdapter->ate.TxCount == 0)
{
-#ifdef RT2860
pAdapter->ate.TxCount = 0xFFFFFFFF;
-#endif // RT2860 //
}
ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
pAdapter->ate.bQATxStart = TRUE;
@@ -5375,7 +5361,6 @@ TX_START_ERROR:
memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
value = ntohs(value);
-#ifdef RT2860
/* TX_FRAME_COUNT == 0 means tx infinitely */
if (value == 0)
{
@@ -5387,7 +5372,6 @@ TX_START_ERROR:
}
else
-#endif // RT2860 //
{
sprintf((PCHAR)str, "%d", value);
Set_ATE_TX_COUNT_Proc(pAdapter, str);
diff --git a/drivers/staging/rt2860/rt_ate.h b/drivers/staging/rt2860/rt_ate.h
index 48aa70d2f01..38f5c4af546 100644
--- a/drivers/staging/rt2860/rt_ate.h
+++ b/drivers/staging/rt2860/rt_ate.h
@@ -31,12 +31,10 @@
#ifndef UCOS
#define ate_print printk
#define ATEDBGPRINT DBGPRINT
-#ifdef RT2860
#define EEPROM_SIZE 0x200
#ifdef CONFIG_STA_SUPPORT
#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2860STA/e2p.bin"
#endif // CONFIG_STA_SUPPORT //
-#endif // RT2860 //
#else // !UCOS //
#define fATE_LOAD_EEPROM 0x0C43
@@ -69,7 +67,6 @@ do{ int (*org_remote_display)(char *) = NULL; \
#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP)
/* RT2880_iNIC will define "RT2860". */
-#ifdef RT2860
#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) \
{ \
BBP_CSR_CFG_STRUC BbpCsr; \
@@ -131,10 +128,8 @@ do{ int (*org_remote_display)(char *) = NULL; \
ATEDBGPRINT(RT_DEBUG_ERROR, ("BBP write R%d fail\n", _I)); \
} \
}
-#endif // RT2860 //
/* RT2880_iNIC will define RT2860. */
-#ifdef RT2860
#define EEPROM_SIZE 0x200
/* iNIC has its own EEPROM_BIN_FILE_NAME */
#ifndef UCOS
@@ -142,7 +137,6 @@ do{ int (*org_remote_display)(char *) = NULL; \
#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2860STA/e2p.bin"
#endif // CONFIG_STA_SUPPORT //
#endif // !UCOS //
-#endif // RT2860 //
diff --git a/drivers/staging/rt2860/rt_config.h b/drivers/staging/rt2860/rt_config.h
index 7ee7a405b02..a67024fb437 100644
--- a/drivers/staging/rt2860/rt_config.h
+++ b/drivers/staging/rt2860/rt_config.h
@@ -53,9 +53,7 @@
#include "rtmp_def.h"
#include "rt28xx.h"
-#ifdef RT2860
#include "rt2860.h"
-#endif // RT2860 //
#include "oid.h"
diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c
index f14500931ef..f3c128c72a2 100644
--- a/drivers/staging/rt2860/rt_linux.c
+++ b/drivers/staging/rt2860/rt_linux.c
@@ -48,10 +48,8 @@ BUILD_TIMER_FUNCTION(LeapAuthTimeout);
#endif
BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
-#ifdef RT2860
BUILD_TIMER_FUNCTION(PsPollWakeExec);
BUILD_TIMER_FUNCTION(RadioOnExec);
-#endif // RT2860 //
#ifdef QOS_DLS_SUPPORT
BUILD_TIMER_FUNCTION(DlsTimeoutAction);
#endif // QOS_DLS_SUPPORT //
@@ -293,9 +291,7 @@ VOID RTMPFreeAdapter(
NdisFreeSpinLock(&pAd->MgmtRingLock);
-#ifdef RT2860
NdisFreeSpinLock(&pAd->RxRingLock);
-#endif // RT2860 //
for (index =0 ; index < NUM_OF_TX_RING; index++)
{
@@ -854,7 +850,7 @@ void send_monitor_packets(
if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
goto err_free_sk_buff;
}
@@ -1005,35 +1001,14 @@ err_free_sk_buff:
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
{
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
allow_signal(SIGTERM);
allow_signal(SIGKILL);
current->flags |= PF_NOFREEZE;
-#else
- unsigned long flags;
-
- daemonize();
- reparent_to_init();
- strcpy(current->comm, pThreadName);
-
- siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
- /* Allow interception of SIGKILL only
- * Don't allow other signals to interrupt the transmission */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
- spin_lock_irqsave(&current->sigmask_lock, flags);
- flush_signals(current);
- recalc_sigpending(current);
- spin_unlock_irqrestore(&current->sigmask_lock, flags);
-#endif
-#endif
-
- /* signal that we've started the thread */
+ /* signal that we've started the thread */
complete(pNotify);
-
}
void RTMP_IndicateMediaState(
diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h
index 0fd58f5109f..708923cecaa 100644
--- a/drivers/staging/rt2860/rt_linux.h
+++ b/drivers/staging/rt2860/rt_linux.h
@@ -65,7 +65,6 @@
#include <linux/vmalloc.h>
-#include <linux/wireless.h>
#include <net/iw_handler.h>
// load firmware
@@ -90,28 +89,22 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
// add by kathy
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
#define STA_PROFILE_PATH "/etc/Wireless/RT2860STA/RT2860STA.dat"
#define STA_RTMP_FIRMWARE_FILE_NAME "/etc/Wireless/RT2860STA/RT2860STA.bin"
#define STA_NIC_DEVICE_NAME "RT2860STA"
-#define STA_DRIVER_VERSION "1.8.0.0"
+#define STA_DRIVER_VERSION "1.8.1.1"
#ifdef MULTIPLE_CARD_SUPPORT
#define CARD_INFO_PATH "/etc/Wireless/RT2860STA/RT2860STACard.dat"
#endif // MULTIPLE_CARD_SUPPORT //
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
-#ifdef RT2860
#ifndef PCI_DEVICE
#define PCI_DEVICE(vend,dev) \
.vendor = (vend), .device = (dev), \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID
#endif // PCI_DEVICE //
-#endif // RT2860 //
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define RTMP_TIME_AFTER(a,b) \
(typecheck(unsigned long, (unsigned long)a) && \
@@ -123,11 +116,7 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
typecheck(unsigned long, (unsigned long)b) && \
((long)(a) - (long)(b) >= 0))
#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a)
-#else
-#define RTMP_TIME_AFTER(a,b) time_after(a, b)
-#endif
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
#define RT_MOD_INC_USE_COUNT() \
if (!try_module_get(THIS_MODULE)) \
{ \
@@ -136,10 +125,6 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
}
#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
-#else
-#define RT_MOD_INC_USE_COUNT() MOD_INC_USE_COUNT;
-#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
-#endif
#define OS_HZ HZ
@@ -171,21 +156,12 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
#define NDIS_PACKET_TYPE_ALL_MULTICAST 3
#endif // CONFIG_STA_SUPPORT //
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
typedef struct pid * THREAD_PID;
#define THREAD_PID_INIT_VALUE NULL
#define GET_PID(_v) find_get_pid(_v)
#define GET_PID_NUMBER(_v) pid_nr(_v)
#define CHECK_PID_LEGALITY(_pid) if (pid_nr(_pid) >= 0)
#define KILL_THREAD_PID(_A, _B, _C) kill_pid(_A, _B, _C)
-#else
-typedef pid_t THREAD_PID;
-#define THREAD_PID_INIT_VALUE -1
-#define GET_PID(_v) _v
-#define GET_PID_NUMBER(_v) _v
-#define CHECK_PID_LEGALITY(_pid) if (_pid >= 0)
-#define KILL_THREAD_PID(_A, _B, _C) kill_proc(_A, _B, _C)
-#endif
struct os_lock {
spinlock_t lock;
@@ -194,11 +170,9 @@ struct os_lock {
struct os_cookie {
-#ifdef RT2860
struct pci_dev *pci_dev;
struct pci_dev *parent_pci_dev;
dma_addr_t pAd_pa;
-#endif // RT2860 //
struct tasklet_struct rx_done_task;
@@ -209,9 +183,7 @@ struct os_cookie {
struct tasklet_struct ac3_dma_done_task;
struct tasklet_struct hcca_dma_done_task;
struct tasklet_struct tbtt_task;
-#ifdef RT2860
struct tasklet_struct fifo_statistic_full_task;
-#endif // RT2860 //
unsigned long apd_pid; //802.1x daemon pid
@@ -266,7 +238,6 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int
#define RT2860_PCI_DEVICE_ID 0x0601
-#ifdef RT2860
#define PCI_MAP_SINGLE(_handle, _ptr, _size, _sd_idx, _dir) \
linux_pci_map_single(_handle, _ptr, _size, _sd_idx, _dir)
@@ -281,7 +252,6 @@ void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int
#define DEV_ALLOC_SKB(_length) \
dev_alloc_skb(_length)
-#endif // RT2860 //
@@ -401,7 +371,6 @@ extern ULONG RTDebugLevel;
spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
}
-#ifdef RT2860
#if defined(INF_TWINPASS) || defined(INF_DANUBE) || defined(IKANOS_VX_1X0)
//Patch for ASIC turst read/write bug, needs to remove after metel fix
#define RTMP_IO_READ32(_A, _R, _pV) \
@@ -413,6 +382,12 @@ extern ULONG RTDebugLevel;
(*_pV = SWAP32(*((UINT32 *)(_pV)))); \
} \
}
+#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \
+{ \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \
+ (*_pV = SWAP32(*((UINT32 *)(_pV)))); \
+}
#define RTMP_IO_READ8(_A, _R, _pV) \
{ \
(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
@@ -452,6 +427,11 @@ extern ULONG RTDebugLevel;
else \
*_pV = 0; \
}
+#define RTMP_IO_FORCE_READ32(_A, _R, _pV) \
+{ \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
+ (*_pV = readl((void *)((_A)->CSRBaseAddress + (_R)))); \
+}
#define RTMP_IO_READ8(_A, _R, _pV) \
{ \
(*_pV = readl((void *)((_A)->CSRBaseAddress + MAC_CSR0))); \
@@ -492,7 +472,6 @@ extern ULONG RTDebugLevel;
writew((_V), (PUSHORT)((_A)->CSRBaseAddress + (_R))); \
}
#endif
-#endif // RT2860 //
#ifndef wait_event_interruptible_timeout
@@ -544,7 +523,6 @@ typedef void (*TIMER_FUNCTION)(unsigned long);
#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA)
-#ifdef RT2860
#define BUILD_TIMER_FUNCTION(_func) \
void linux_##_func(unsigned long data) \
{ \
@@ -554,7 +532,6 @@ void linux_##_func(unsigned long data) \
if (pTimer->Repeat) \
RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue); \
}
-#endif // RT2860 //
@@ -907,7 +884,6 @@ int rt28xx_packet_xmit(struct sk_buff *skb);
void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
-#ifdef RT2860
#if !defined(PCI_CAP_ID_EXP)
#define PCI_CAP_ID_EXP 0x10
#endif
@@ -921,6 +897,5 @@ void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
#endif
#define PCIBUS_INTEL_VENDOR 0x8086
-#endif // RT2860 //
diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c
index 3873c478f4e..cf17bcdd733 100644
--- a/drivers/staging/rt2860/rt_main_dev.c
+++ b/drivers/staging/rt2860/rt_main_dev.c
@@ -58,11 +58,7 @@ UINT32 CW_MAX_IN_BITS;
char *mac = ""; // default 00:00:00:00:00:00
char *hostname = ""; // default CMPC
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
-MODULE_PARM (mac, "s");
-#else
module_param (mac, charp, 0);
-#endif
MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
@@ -75,9 +71,7 @@ extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
#endif // DOT11_N_SUPPORT //
extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
-#ifdef RT2860
extern void init_thread_task(PRTMP_ADAPTER pAd);
-#endif // RT2860 //
// public function prototype
INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
@@ -87,13 +81,6 @@ INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
static int rt28xx_init(IN struct net_device *net_dev);
INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
-#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
-struct net_device *alloc_netdev(
- int sizeof_priv,
- const char *mask,
- void (*setup)(struct net_device *));
-#endif // LINUX_VERSION_CODE //
-
static void CfgInitHook(PRTMP_ADAPTER pAd);
#ifdef CONFIG_STA_SUPPORT
@@ -235,15 +222,13 @@ int rt28xx_close(IN PNET_DEV dev)
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
-#ifdef RT2860
- RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE);
-#endif // RT2860 //
-
// If dirver doesn't wake up firmware here,
// NICLoadFirmware will hang forever when interface is up again.
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
{
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, RTMP_HALT);
}
#ifdef QOS_DLS_SUPPORT
@@ -323,9 +308,7 @@ int rt28xx_close(IN PNET_DEV dev)
#endif // WPA_SUPPLICANT_SUPPORT //
MlmeRadioOff(pAd);
-#ifdef RT2860
pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
}
#endif // CONFIG_STA_SUPPORT //
@@ -359,7 +342,6 @@ int rt28xx_close(IN PNET_DEV dev)
TpcReqTabExit(pAd);
-#ifdef RT2860
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
{
NICDisableInterrupt(pAd);
@@ -375,7 +357,6 @@ int rt28xx_close(IN PNET_DEV dev)
RT28XX_IRQ_RELEASE(net_dev)
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
}
-#endif // RT2860 //
// Free Ring or USB buffers
@@ -439,12 +420,10 @@ static int rt28xx_init(IN struct net_device *net_dev)
// Disable interrupts here which is as soon as possible
// This statement should never be true. We might consider to remove it later
-#ifdef RT2860
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE))
{
NICDisableInterrupt(pAd);
}
-#endif // RT2860 //
Status = RTMPAllocTxRxRingMemory(pAd);
if (Status != NDIS_STATUS_SUCCESS)
@@ -667,26 +646,6 @@ int rt28xx_open(IN PNET_DEV dev)
#endif // WIRELESS_EXT >= 12 //
#endif // CONFIG_APSTA_MIXED_SUPPORT //
-#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
- IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
- {
- // If dirver doesn't wake up firmware here,
- // NICLoadFirmware will hang forever when interface is up again.
- // RT2860 PCI
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) &&
- OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
- {
- AUTO_WAKEUP_STRUC AutoWakeupCfg;
- AsicForceWakeup(pAd, TRUE);
- AutoWakeupCfg.word = 0;
- RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
- OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
- }
- }
-#endif // RT2860 //
-#endif // CONFIG_STA_SUPPORT //
-
// Init
pObj = (POS_COOKIE)pAd->OS_Cookie;
@@ -753,10 +712,8 @@ int rt28xx_open(IN PNET_DEV dev)
}
#ifdef CONFIG_STA_SUPPORT
-#ifdef RT2860
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
RTMPInitPCIeLinkCtrlValue(pAd);
-#endif // RT2860 //
#endif // CONFIG_STA_SUPPORT //
return (retval);
@@ -808,9 +765,7 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
dev->stop = MainVirtualIF_close; //rt28xx_close;
dev->priv_flags = INT_MAIN;
dev->do_ioctl = rt28xx_ioctl;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
- dev->validate_addr = NULL;
-#endif
+ dev->validate_addr = NULL;
// find available device name
for (i = 0; i < 8; i++)
{
@@ -821,25 +776,11 @@ static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER p
#endif // MULTIPLE_CARD_SUPPORT //
sprintf(slot_name, "ra%d", i);
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
- device = dev_get_by_name(dev_net(dev), slot_name);
-#else
- device = dev_get_by_name(dev->nd_net, slot_name);
-#endif
-#else
- device = dev_get_by_name(slot_name);
-#endif
- if (device != NULL) dev_put(device);
-#else
- for (device = dev_base; device != NULL; device = device->next)
- {
- if (strncmp(device->name, slot_name, 4) == 0)
- break;
- }
-#endif
- if(device == NULL)
+ device = dev_get_by_name(dev_net(dev), slot_name);
+ if (device != NULL)
+ dev_put(device);
+
+ if (device == NULL)
break;
}
@@ -1252,47 +1193,28 @@ INT __devinit rt28xx_probe(
PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL;
INT status;
PVOID handle;
-#ifdef RT2860
struct pci_dev *dev_p = (struct pci_dev *)_dev_p;
-#endif // RT2860 //
#ifdef CONFIG_STA_SUPPORT
DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
#endif // CONFIG_STA_SUPPORT //
-#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
- net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
-#else
net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
-#endif
if (net_dev == NULL)
{
printk("alloc_netdev failed\n");
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
- module_put(THIS_MODULE);
-#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
-#else
- MOD_DEC_USE_COUNT;
-#endif
goto err_out;
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
- SET_MODULE_OWNER(net_dev);
-#endif
-
netif_stop_queue(net_dev);
#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
/* for supporting Network Manager */
/* Set the sysfs physical device reference for the network logical device
* if set prior to registration will cause a symlink during initialization.
*/
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
SET_NETDEV_DEV(net_dev, &(dev_p->dev));
-#endif
#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
// Allocate RTMP_ADAPTER miniport adapter structure
@@ -1313,13 +1235,8 @@ INT __devinit rt28xx_probe(
#endif // CONFIG_STA_SUPPORT //
// Post config
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
- goto err_out_unmap;
-#else
if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
goto err_out_unmap;
-#endif // LINUX_VERSION_CODE //
#ifdef CONFIG_STA_SUPPORT
pAd->OpMode = OPMODE_STA;
@@ -1362,20 +1279,12 @@ err_out_unmap:
RT28XX_UNMAP();
err_out_free_netdev:
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
- free_netdev(net_dev);
-#else
- kfree(net_dev);
-#endif
+ free_netdev(net_dev);
err_out:
RT28XX_PUT_DEVICE(dev_p);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
- return (LONG)NULL;
-#else
- return -ENODEV; /* probe fail */
-#endif // LINUX_VERSION_CODE //
+ return -ENODEV; /* probe fail */
} /* End of rt28xx_probe */
@@ -1495,40 +1404,6 @@ INT rt28xx_send_packets(
-#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
-struct net_device *alloc_netdev(
- int sizeof_priv,
- const char *mask,
- void (*setup)(struct net_device *))
-{
- struct net_device *dev;
- INT alloc_size;
-
-
- /* ensure 32-byte alignment of the private area */
- alloc_size = sizeof (*dev) + sizeof_priv + 31;
-
- dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
- if (dev == NULL)
- {
- DBGPRINT(RT_DEBUG_ERROR,
- ("alloc_netdev: Unable to allocate device memory.\n"));
- return NULL;
- }
-
- memset(dev, 0, alloc_size);
-
- if (sizeof_priv)
- dev->priv = (void *) (((long)(dev + 1) + 31) & ~31);
-
- setup(dev);
- strcpy(dev->name, mask);
-
- return dev;
-}
-#endif // LINUX_VERSION_CODE //
-
-
void CfgInitHook(PRTMP_ADAPTER pAd)
{
pAd->bBroadComHT = TRUE;
diff --git a/drivers/staging/rt2860/rt_profile.c b/drivers/staging/rt2860/rt_profile.c
index 326a3cb52b9..62141f37697 100644
--- a/drivers/staging/rt2860/rt_profile.c
+++ b/drivers/staging/rt2860/rt_profile.c
@@ -1451,7 +1451,7 @@ NDIS_STATUS RTMPReadParametersHook(
IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
{
//PSMode
- if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
+ if (RTMPGetKeyParameter("PSMode", tmpbuf, 32, buffer))
{
if (pAd->StaCfg.BssType == BSS_INFRA)
{
diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h
index 411954206c2..b904b7886c2 100644
--- a/drivers/staging/rt2860/rtmp.h
+++ b/drivers/staging/rt2860/rtmp.h
@@ -203,9 +203,7 @@ typedef struct _ATE_INFO {
BOOLEAN bRxFer;
BOOLEAN bQATxStart; // Have compiled QA in and use it to ATE tx.
BOOLEAN bQARxStart; // Have compiled QA in and use it to ATE rx.
-#ifdef RT2860
BOOLEAN bFWLoading; // Reload firmware when ATE is done.
-#endif // RT2860 //
UINT32 RxTotalCnt;
UINT32 RxCntPerSec;
@@ -366,6 +364,13 @@ typedef struct _QUEUE_HEADER {
#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
+// Macro for power save flag.
+#define RTMP_SET_PSFLAG(_M, _F) ((_M)->PSFlags |= (_F))
+#define RTMP_CLEAR_PSFLAG(_M, _F) ((_M)->PSFlags &= ~(_F))
+#define RTMP_CLEAR_PSFLAGS(_M) ((_M)->PSFlags = 0)
+#define RTMP_TEST_PSFLAG(_M, _F) (((_M)->PSFlags & (_F)) != 0)
+#define RTMP_TEST_PSFLAGS(_M, _F) (((_M)->PSFlags & (_F)) == (_F))
+
#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
@@ -478,7 +483,6 @@ typedef struct _QUEUE_HEADER {
//
#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
//
-#ifdef RT2860
#define RTMP_RF_IO_WRITE32(_A, _V) \
{ \
PHY_CSR4_STRUC Value; \
@@ -642,7 +646,6 @@ typedef struct _QUEUE_HEADER {
} \
} \
}
-#endif // RT2860 //
#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
@@ -894,7 +897,6 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
// Enqueue this frame to MLME engine
// We need to enqueue the whole frame because MLME need to pass data type
// information from 802.11 header
-#ifdef RT2860
#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \
{ \
UINT32 High32TSF, Low32TSF; \
@@ -902,7 +904,6 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
RTMP_IO_READ32(_pAd, TSF_TIMER_DW0, &Low32TSF); \
MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \
}
-#endif // RT2860 //
#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \
NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
@@ -919,9 +920,10 @@ typedef struct _RTMP_SCATTER_GATHER_LIST {
#define STA_PORT_SECURED(_pAd) \
{ \
_pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
- NdisAcquireSpinLock(&_pAd->MacTabLock); \
+ RTMP_SET_PSFLAG(_pAd, fRTMP_PS_CAN_GO_SLEEP); \
+ NdisAcquireSpinLock(&(_pAd)->MacTabLock); \
_pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
- NdisReleaseSpinLock(&_pAd->MacTabLock); \
+ NdisReleaseSpinLock(&(_pAd)->MacTabLock); \
}
#endif // CONFIG_STA_SUPPORT //
@@ -1000,9 +1002,7 @@ typedef struct _RTMP_REORDERBUF
UCHAR DataOffset;
USHORT Datasize;
ULONG AllocSize;
-#ifdef RT2860
NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
-#endif // RT2860 //
} RTMP_REORDERBUF, *PRTMP_REORDERBUF;
//
@@ -1101,6 +1101,7 @@ typedef struct _COUNTER_802_11 {
typedef struct _COUNTER_RALINK {
ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput
+ ULONG LastReceivedByteCount;
ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput
ULONG BeenDisassociatedCount;
ULONG BadCQIAutoRecoveryCount;
@@ -1436,11 +1437,9 @@ typedef struct _MLME_STRUCT {
RALINK_TIMER_STRUCT APSDPeriodicTimer;
RALINK_TIMER_STRUCT LinkDownTimer;
RALINK_TIMER_STRUCT LinkUpTimer;
-#ifdef RT2860
UCHAR bPsPollTimerRunning;
RALINK_TIMER_STRUCT PsPollTimer;
RALINK_TIMER_STRUCT RadioOnOffTimer;
-#endif // RT2860 //
ULONG PeriodicRound;
ULONG OneSecPeriodicRound;
@@ -2228,9 +2227,7 @@ typedef struct _STA_ADMIN_CONFIG {
RT_HT_PHY_INFO DesiredHtPhyInfo;
BOOLEAN bAutoTxRateSwitch;
-#ifdef RT2860
UCHAR BBPR3;
-#endif // RT2860 //
#ifdef EXT_BUILD_CHANNEL_LIST
UCHAR IEEE80211dClientMode;
@@ -2663,7 +2660,6 @@ typedef struct _RTMP_ADAPTER
PNET_DEV net_dev;
ULONG VirtualIfCnt;
-#ifdef RT2860
USHORT LnkCtrlBitMask;
USHORT RLnkCtrlConfiguration;
USHORT RLnkCtrlOffset;
@@ -2671,7 +2667,9 @@ typedef struct _RTMP_ADAPTER
USHORT HostLnkCtrlOffset;
USHORT PCIePowerSaveLevel;
BOOLEAN bPCIclkOff; // flag that indicate if the PICE power status in Configuration SPace..
- BOOLEAN bPCIclkOffDisableTx; //
+ ULONG CheckDmaBusyCount; // Check Interrupt Status Register Count.
+ USHORT ThisTbttNumToNextWakeUp;
+ ULONG SameRxByteCount;
/*****************************************************************************************/
@@ -2688,7 +2686,6 @@ typedef struct _RTMP_ADAPTER
RTMP_DMABUF RxDescRing; // Shared memory for RX descriptors
RTMP_DMABUF TxDescRing[NUM_OF_TX_RING]; // Shared memory for Tx descriptors
RTMP_TX_RING TxRing[NUM_OF_TX_RING]; // AC0~4 + HCCA
-#endif // RT2860 //
NDIS_SPIN_LOCK irq_lock;
@@ -2721,10 +2718,8 @@ typedef struct _RTMP_ADAPTER
/* Rx related parameters */
/*****************************************************************************************/
-#ifdef RT2860
RTMP_RX_RING RxRing;
NDIS_SPIN_LOCK RxRingLock; // Rx Ring spinlock
-#endif // RT2860 //
@@ -2895,6 +2890,7 @@ typedef struct _RTMP_ADAPTER
// flags, see fRTMP_ADAPTER_xxx flags
ULONG Flags; // Represent current device status
+ ULONG PSFlags; // Power Save operation flag.
// current TX sequence #
USHORT Sequence;
@@ -3181,7 +3177,6 @@ typedef struct _TX_BLK_
//------------------------------------------------------------------------------------------
-#ifdef RT2860
//
// Enable & Disable NIC interrupt via writing interrupt mask register
// Since it use ADAPTER structure, it have to be put after structure definition.
@@ -3214,7 +3209,6 @@ __inline VOID NICEnableInterrupt(
//RTMP_IO_WRITE32(pAd, PBF_INT_ENA, 0x00000030); // 1 : enable
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_ACTIVE);
}
-#endif // RT2860 //
#ifdef RT_BIG_ENDIAN
static inline VOID WriteBackToDescriptor(
@@ -3291,7 +3285,6 @@ static inline VOID RTMPWIEndianChange(
Call this function when read or update descriptor
========================================================================
*/
-#ifdef RT2860
static inline VOID RTMPDescriptorEndianChange(
IN PUCHAR pData,
IN ULONG DescriptorType)
@@ -3301,7 +3294,6 @@ static inline VOID RTMPDescriptorEndianChange(
*((UINT32 *)(pData +12)) = SWAP32(*((UINT32 *)(pData + 12))); // Byte 12~15
*((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData + 4))); // Byte 4~7, this must be swapped last
}
-#endif // RT2860 //
/*
========================================================================
@@ -3550,6 +3542,9 @@ NDIS_STATUS NICInitializeAsic(
IN PRTMP_ADAPTER pAd,
IN BOOLEAN bHardReset);
+VOID NICRestoreBBPValue(
+ IN PRTMP_ADAPTER pAd);
+
VOID NICIssueReset(
IN PRTMP_ADAPTER pAd);
@@ -4208,7 +4203,7 @@ VOID AsicForceSleep(
VOID AsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx);
+ IN UCHAR Level);
#endif // CONFIG_STA_SUPPORT //
VOID AsicSetBssid(
@@ -4304,11 +4299,9 @@ BOOLEAN AsicSendCommandToMcu(
IN UCHAR Arg0,
IN UCHAR Arg1);
-#ifdef RT2860
BOOLEAN AsicCheckCommanOk(
IN PRTMP_ADAPTER pAd,
IN UCHAR Command);
-#endif // RT2860 //
VOID MacAddrRandomBssid(
IN PRTMP_ADAPTER pAd,
@@ -6978,7 +6971,6 @@ void kill_thread_task(PRTMP_ADAPTER pAd);
void tbtt_tasklet(unsigned long data);
-#ifdef RT2860
//
// Function Prototype in cmm_data_2860.c
//
@@ -7069,7 +7061,7 @@ BOOLEAN RT28xxPciAsicRadioOn(
VOID RT28xxPciStaAsicForceWakeup(
IN PRTMP_ADAPTER pAd,
- IN BOOLEAN bFromTx);
+ IN UCHAR Level);
VOID RT28xxPciStaAsicSleepThenAutoWakeup(
IN PRTMP_ADAPTER pAd,
@@ -7093,7 +7085,6 @@ VOID RT28xxPciMlmeRadioOn(
VOID RT28xxPciMlmeRadioOFF(
IN PRTMP_ADAPTER pAd);
-#endif // RT2860 //
VOID AsicTurnOffRFClk(
IN PRTMP_ADAPTER pAd,
@@ -7132,6 +7123,18 @@ PCHAR RTMPGetRalinkEncryModeStr(
#ifdef CONFIG_STA_SUPPORT
VOID AsicStaBbpTuning(
IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetFromDMABusy(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetBBP(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetMAC(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicResetPBF(
+ IN PRTMP_ADAPTER pAd);
#endif // CONFIG_STA_SUPPORT //
void RTMP_IndicateMediaState(
diff --git a/drivers/staging/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h
index be982147883..25a53d83a0d 100644
--- a/drivers/staging/rt2860/rtmp_def.h
+++ b/drivers/staging/rt2860/rtmp_def.h
@@ -111,7 +111,6 @@
// Entry number for each DMA descriptor ring
//
-#ifdef RT2860
#define TX_RING_SIZE 64 //64
#define MGMT_RING_SIZE 128
#define RX_RING_SIZE 128 //64
@@ -119,7 +118,6 @@
#define MAX_DMA_DONE_PROCESS TX_RING_SIZE
#define MAX_TX_DONE_PROCESS TX_RING_SIZE //8
#define LOCAL_TXBUF_SIZE 2
-#endif // RT2860 //
#ifdef MULTIPLE_CARD_SUPPORT
@@ -212,6 +210,19 @@
#define fOP_STATUS_WAKEUP_NOW 0x00008000
#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000
+//
+// RTMP_ADAPTER PSFlags : related to advanced power save.
+//
+// Indicate whether driver can go to sleep mode from now. This flag is useful AFTER link up
+#define fRTMP_PS_CAN_GO_SLEEP 0x00000001
+// Indicate whether driver has issue a LinkControl command to PCIe L1
+#define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND 0x00000002
+// Indicate driver should disable kick off hardware to send packets from now.
+#define fRTMP_PS_DISABLE_TX 0x00000004
+// Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me
+//. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine.
+#define fRTMP_PS_GO_TO_SLEEP_NOW 0x00000008
+
#ifdef DOT11N_DRAFT3
#define fOP_STATUS_SCAN_2040 0x00040000
#endif // DOT11N_DRAFT3 //
@@ -1514,12 +1525,14 @@
#define MCAST_HTMIX 3
#endif // MCAST_RATE_SPECIFIC //
-// For AsicRadioOff/AsicRadioOn function
-#define DOT11POWERSAVE 0
-#define GUIRADIO_OFF 1
-#define RTMP_HALT 2
-#define GUI_IDLE_POWER_SAVE 3
-// --
+// For AsicRadioOff/AsicRadioOn/AsicForceWakeup function
+// This is to indicate from where to call this function.
+#define DOT11POWERSAVE 0 // TO do .11 power save sleep
+#define GUIRADIO_OFF 1 // To perform Radio OFf command from GUI
+#define RTMP_HALT 2 // Called from Halt handler.
+#define GUI_IDLE_POWER_SAVE 3 // Call to sleep before link up with AP
+#define FROM_TX 4 // Force wake up from Tx packet.
+
// definition for WpaSupport flag
diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c
index 42db753eed7..34f1c1490f4 100644
--- a/drivers/staging/rt2860/sta/assoc.c
+++ b/drivers/staging/rt2860/sta/assoc.c
@@ -473,12 +473,7 @@ VOID MlmeAssocReqAction(
RSNIe = IE_WPA2;
}
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
- if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif // SIOCSIWGENIE //
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
- RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
// Check for WPA PMK cache list
if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
@@ -504,17 +499,6 @@ VOID MlmeAssocReqAction(
}
}
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
- if (pAd->StaCfg.WpaSupplicantUP == 1)
- {
- MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
- pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
- END_OF_ARGS);
- }
- else
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
{
MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
1, &RSNIe,
@@ -525,11 +509,6 @@ VOID MlmeAssocReqAction(
FrameLen += tmp;
-#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
-#ifdef SIOCSIWGENIE
- if (pAd->StaCfg.WpaSupplicantUP != 1)
-#endif
-#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
{
// Append Variable IE
NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c
index 36f28f8b4aa..d8bcc76688a 100644
--- a/drivers/staging/rt2860/sta/connect.c
+++ b/drivers/staging/rt2860/sta/connect.c
@@ -337,6 +337,10 @@ VOID CntlOidSsidProc(
MLME_DISASSOC_REQ_STRUCT DisassocReq;
ULONG Now;
+ // BBP and RF are not accessible in PS mode, we has to wake them up first
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ AsicForceWakeup(pAd, RTMP_HALT);
+
// Step 1. record the desired user settings to MlmeAux
NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
@@ -1240,6 +1244,13 @@ VOID LinkUp(
UCHAR Value = 0, idx;
MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAd->bPCIclkOff = FALSE;
+ }
+
pEntry = &pAd->MacTab.Content[BSSID_WCID];
//
@@ -1264,7 +1275,6 @@ VOID LinkUp(
//rt2860b. Don't know why need this
SwitchBetweenWepAndCkip(pAd);
-#ifdef RT2860
// Before power save before link up function, We will force use 1R.
// So after link up, check Rx antenna # again.
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
@@ -1282,7 +1292,6 @@ VOID LinkUp(
}
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
if (BssType == BSS_ADHOC)
{
@@ -1330,9 +1339,7 @@ VOID LinkUp(
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
Value &= (~0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
Data &= 0xfffffffe;
@@ -1367,9 +1374,7 @@ VOID LinkUp(
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
Value |= (0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
if (pAd->MACVersion == 0x28600100)
{
@@ -1400,9 +1405,7 @@ VOID LinkUp(
RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
Value &= (~0x20);
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
-#ifdef RT2860
pAd->StaCfg.BBPR3 = Value;
-#endif // RT2860 //
if (pAd->MACVersion == 0x28600100)
{
@@ -1598,6 +1601,8 @@ VOID LinkUp(
IV = 0;
IV |= (pAd->StaCfg.DefaultKeyId << 30);
AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
+
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
}
// NOTE:
// the decision of using "short slot time" or not may change dynamically due to
@@ -1919,6 +1924,7 @@ VOID LinkUp(
}
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
#ifdef DOT11_N_SUPPORT
#ifdef DOT11N_DRAFT3
@@ -1961,6 +1967,7 @@ VOID LinkDown(
IN BOOLEAN IsReqFromAP)
{
UCHAR i, ByteValue = 0;
+ BOOLEAN Cancelled;
// Do nothing if monitor mode is on
if (MONITOR_ON(pAd))
@@ -1972,6 +1979,12 @@ VOID LinkDown(
return;
#endif // RALINK_ATE //
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+ RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
+
+ // Not allow go to sleep within linkdown function.
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
if (pAd->CommonCfg.bWirelessEvent)
{
RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
@@ -1980,7 +1993,6 @@ VOID LinkDown(
DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
BOOLEAN Cancelled;
@@ -1988,17 +2000,15 @@ VOID LinkDown(
RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled);
}
- if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE) ||
+ RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_IDLE_RADIO_OFF))
{
- AUTO_WAKEUP_STRUC AutoWakeupCfg;
- AsicForceWakeup(pAd, TRUE);
- AutoWakeupCfg.word = 0;
- RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+ AsicForceWakeup(pAd, RTMP_HALT);
OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
}
pAd->bPCIclkOff = FALSE;
-#endif // RT2860 //
if (ADHOC_ON(pAd)) // Adhoc mode link down
{
DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
@@ -2266,6 +2276,9 @@ VOID LinkDown(
RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ // Allow go to sleep after linkdown steps.
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+
#ifdef WPA_SUPPLICANT_SUPPORT
#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
if (pAd->StaCfg.WpaSupplicantUP) {
@@ -2510,7 +2523,6 @@ VOID AuthParmFill(
==========================================================================
*/
-#ifdef RT2860
VOID ComposePsPoll(
IN PRTMP_ADAPTER pAd)
{
@@ -2534,7 +2546,6 @@ VOID ComposeNullFrame(
COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
}
-#endif // RT2860 //
diff --git a/drivers/staging/rt2860/sta/dls.c b/drivers/staging/rt2860/sta/dls.c
index 78fb28976fd..873cf7f1de9 100644
--- a/drivers/staging/rt2860/sta/dls.c
+++ b/drivers/staging/rt2860/sta/dls.c
@@ -1419,7 +1419,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
// Add Pair-wise key to Asic
-#ifdef RT2860
AsicAddPairwiseKeyEntry(pAd,
pAd->StaCfg.DLSEntry[i].MacAddr,
(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
@@ -1431,7 +1430,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
PairwiseKey.CipherAlg,
pEntry);
-#endif // RT2860 //
NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
@@ -1477,7 +1475,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
//AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
//AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
// Add Pair-wise key to Asic
-#ifdef RT2860
AsicAddPairwiseKeyEntry(pAd,
pAd->StaCfg.DLSEntry[i].MacAddr,
(UCHAR)pAd->StaCfg.DLSEntry[i].MacTabMatchWCID,
@@ -1488,7 +1485,6 @@ BOOLEAN RTMPRcvFrameDLSCheck(
0,
PairwiseKey.CipherAlg,
pEntry);
-#endif // RT2860 //
NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c
index 36aff247cd9..c5e76a2da56 100644
--- a/drivers/staging/rt2860/sta/rtmp_data.c
+++ b/drivers/staging/rt2860/sta/rtmp_data.c
@@ -75,7 +75,6 @@ VOID STARxEAPOLFrameIndicate(
if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
{
-#ifdef RT2860
MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[BSSID_WCID];
// Set key material and cipherAlg to Asic
@@ -89,7 +88,6 @@ VOID STARxEAPOLFrameIndicate(
pAd->IndicateMediaState = NdisMediaStateConnected;
pAd->ExtraInfo = GENERAL_LINK_UP;
-#endif // RT2860 //
// For Preventing ShardKey Table is cleared by remove key procedure.
pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
@@ -693,14 +691,12 @@ BOOLEAN STARxDoneInterruptHandle(
break;
}
-#ifdef RT2860
if (RxProcessed++ > MAX_RX_PROCESS_CNT)
{
// need to reschedule rx handle
bReschedule = TRUE;
break;
}
-#endif // RT2860 //
RxProcessed ++; // test
@@ -811,6 +807,13 @@ BOOLEAN STARxDoneInterruptHandle(
}
}
+ // fRTMP_PS_GO_TO_SLEEP_NOW is set if receiving beacon.
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW) && (INFRA_ON(pAd)))
+ {
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+ AsicSleepThenAutoWakeup(pAd, pAd->ThisTbttNumToNextWakeUp);
+ bReschedule = FALSE;
+ }
return bReschedule;
}
@@ -828,7 +831,7 @@ BOOLEAN STARxDoneInterruptHandle(
VOID RTMPHandleTwakeupInterrupt(
IN PRTMP_ADAPTER pAd)
{
- AsicForceWakeup(pAd, FALSE);
+ AsicForceWakeup(pAd, DOT11POWERSAVE);
}
/*
@@ -1220,7 +1223,6 @@ NDIS_STATUS STASendPacket(
========================================================================
*/
-#ifdef RT2860
NDIS_STATUS RTMPFreeTXDRequest(
IN PRTMP_ADAPTER pAd,
IN UCHAR QueIdx,
@@ -1264,7 +1266,6 @@ NDIS_STATUS RTMPFreeTXDRequest(
return (Status);
}
-#endif // RT2860 //
@@ -1889,7 +1890,8 @@ VOID STA_AMPDU_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
pAd->RalinkCounters.KickTxCount++;
pAd->RalinkCounters.OneSecTxDoneCount++;
@@ -2019,7 +2021,8 @@ VOID STA_AMSDU_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}
#endif // DOT11_N_SUPPORT //
@@ -2139,7 +2142,8 @@ VOID STA_Legacy_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}
@@ -2249,7 +2253,8 @@ VOID STA_ARalink_Frame_Tx(
//
// Kick out Tx
//
- HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+ if (!RTMP_TEST_PSFLAG(pAd, fRTMP_PS_DISABLE_TX))
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
}
@@ -2526,7 +2531,7 @@ NDIS_STATUS STAHardTransmit(
if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
- AsicForceWakeup(pAd, TRUE);
+ AsicForceWakeup(pAd, FROM_TX);
}
// It should not change PSM bit, when APSD turn on.
diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c
index d196f85395c..148037a79d5 100644
--- a/drivers/staging/rt2860/sta/sync.c
+++ b/drivers/staging/rt2860/sta/sync.c
@@ -228,7 +228,6 @@ VOID MlmeScanReqAction(
// Increase the scan retry counters.
pAd->StaCfg.ScanCnt++;
-#ifdef RT2860
if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
(IDLE_ON(pAd)) &&
(pAd->StaCfg.bRadio == TRUE) &&
@@ -236,7 +235,6 @@ VOID MlmeScanReqAction(
{
RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
}
-#endif // RT2860 //
// first check the parameter sanity
if (MlmeScanReqSanity(pAd,
@@ -349,7 +347,6 @@ VOID MlmeJoinReqAction(
DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
-#ifdef RT2860
if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE)) &&
(IDLE_ON(pAd)) &&
(pAd->StaCfg.bRadio == TRUE) &&
@@ -357,7 +354,6 @@ VOID MlmeJoinReqAction(
{
RT28xxPciAsicRadioOn(pAd, GUI_IDLE_POWER_SAVE);
}
-#endif // RT2860 //
// reset all the timers
RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
@@ -1532,13 +1528,10 @@ VOID PeerBeacon(
// 5. otherwise, put PHY back to sleep to save battery.
if (MessageToMe)
{
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
- // Turn clk to 80Mhz.
}
-#endif // RT2860 //
if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
{
@@ -1549,12 +1542,10 @@ VOID PeerBeacon(
}
else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
{
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
}
-#endif // RT2860 //
}
else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
(pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
@@ -1568,12 +1559,10 @@ VOID PeerBeacon(
{
// TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
// can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
-#ifdef RT2860
if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE))
{
RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, pAd->StaCfg.BBPR3);
}
-#endif // RT2860 //
}
else
{
@@ -1588,7 +1577,10 @@ VOID PeerBeacon(
if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
{
- AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+ // Set a flag to go to sleep . Then after parse this RxDoneInterrupt, will go to sleep mode.
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW);
+ pAd->ThisTbttNumToNextWakeUp = TbttNumToNextWakeUp;
+ //AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
}
}
}
diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c
index 774c6567ae5..2609d845fd5 100644
--- a/drivers/staging/rt2860/sta/wpa.c
+++ b/drivers/staging/rt2860/sta/wpa.c
@@ -1384,6 +1384,10 @@ VOID WpaGroupMsg1Action(
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
//hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
}
@@ -1760,7 +1764,7 @@ BOOLEAN ParseKeyData(
// Get GTK length - refer to IEEE 802.11i-2004 p.82
GTKLEN = pKDE->Len -6;
- if (GTKLEN < LEN_AES_KEY)
+ if (GTKLEN < MIN_LEN_OF_GTK)
{
DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
return FALSE;
@@ -1786,6 +1790,10 @@ BOOLEAN ParseKeyData(
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP64;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_WEP128;
return TRUE;
diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c
index 3ea2b2c4ab0..c5452f152a2 100644
--- a/drivers/staging/rt2860/sta_ioctl.c
+++ b/drivers/staging/rt2860/sta_ioctl.c
@@ -49,15 +49,9 @@ extern ULONG RTDebugLevel;
#define GROUP_KEY_NO 4
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_A, _B, _C, _D, _E)
#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_A, _B, _C, _D, _E)
#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_A, _B, _C, _D, _E, _F)
-#else
-#define IWE_STREAM_ADD_EVENT(_A, _B, _C, _D, _E) iwe_stream_add_event(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_POINT(_A, _B, _C, _D, _E) iwe_stream_add_point(_B, _C, _D, _E)
-#define IWE_STREAM_ADD_VALUE(_A, _B, _C, _D, _E, _F) iwe_stream_add_value(_B, _C, _D, _E, _F)
-#endif
extern UCHAR CipherWpa2Template[];
extern UCHAR CipherWpaPskTkip[];
@@ -358,6 +352,20 @@ VOID RTMPAddKey(
DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
+ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ if (RTMP_TEST_PSFLAG(pAd, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ return;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
+ RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAd->bPCIclkOff = FALSE;
+ }
+
if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
{
if (pKey->KeyIndex & 0x80000000)
@@ -551,6 +559,8 @@ VOID RTMPAddKey(
}
}
end:
+ RTMP_SET_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP);
+ DBGPRINT(RT_DEBUG_INFO, ("<------ RTMPAddKey\n"));
return;
}
@@ -573,9 +583,7 @@ rt_ioctl_giwname(struct net_device *dev,
{
// PRTMP_ADAPTER pAdapter = dev->ml_priv;
-#ifdef RT2860
strncpy(name, "RT2860 Wireless", IFNAMSIZ);
-#endif // RT2860 //
return 0;
}
@@ -670,11 +678,9 @@ int rt_ioctl_siwmode(struct net_device *dev,
case IW_MODE_INFRA:
Set_NetworkType_Proc(pAdapter, "Infra");
break;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
case IW_MODE_MONITOR:
Set_NetworkType_Proc(pAdapter, "Monitor");
break;
-#endif
default:
DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
return -EINVAL;
@@ -715,12 +721,10 @@ int rt_ioctl_giwmode(struct net_device *dev,
*mode = IW_MODE_ADHOC;
else if (INFRA_ON(pAdapter))
*mode = IW_MODE_INFRA;
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
else if (MONITOR_ON(pAdapter))
{
*mode = IW_MODE_MONITOR;
}
-#endif
else
*mode = IW_MODE_AUTO;
@@ -1038,6 +1042,15 @@ int rt_ioctl_siwscan(struct net_device *dev,
return -EINVAL;
}
+ if ((pAdapter->OpMode == OPMODE_STA) && (IDLE_ON(pAdapter))
+ && (pAdapter->StaCfg.bRadio == TRUE)
+ && (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_IDLE_RADIO_OFF)))
+ {
+ RT28xxPciAsicRadioOn(pAdapter, GUI_IDLE_POWER_SAVE);
+ }
+ // Check if still radio off.
+ else if (pAdapter->bPCIclkOff == TRUE)
+ return 0;
#ifdef WPA_SUPPLICANT_SUPPORT
if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
@@ -1756,7 +1769,7 @@ int rt_ioctl_siwencode(struct net_device *dev,
}
else
/* Don't complain if only change the mode */
- if(!erq->flags & IW_ENCODE_MODE) {
+ if (!(erq->flags & IW_ENCODE_MODE)) {
return -EINVAL;
}
}
@@ -2161,12 +2174,6 @@ rt_private_show(struct net_device *dev, struct iw_request_info *info,
wrq->length = strlen(extra) + 1; // 1: size of '\0'
break;
case RAIO_ON:
- if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
- {
- sprintf(extra, "Scanning\n");
- wrq->length = strlen(extra) + 1; // 1: size of '\0'
- break;
- }
pAd->StaCfg.bSwRadio = TRUE;
//if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
{
@@ -2450,6 +2457,20 @@ void fnSetCipherKey(
IN BOOLEAN bGTK,
IN struct iw_encode_ext *ext)
{
+ RTMP_CLEAR_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
+ if (RTMP_TEST_PSFLAG(pAdapter, fRTMP_PS_SET_PCI_CLK_OFF_COMMAND))
+ {
+ if (pAdapter->StaCfg.bRadio == FALSE)
+ {
+ RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
+ return;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPAAddKeyProc1==>\n"));
+ RTMPPCIeLinkCtrlValueRestore(pAdapter, RESTORE_HALT);
+ RTMPusecDelay(6000);
+ pAdapter->bPCIclkOff = FALSE;
+ }
+
NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
@@ -2480,6 +2501,8 @@ void fnSetCipherKey(
keyIdx,
pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
&pAdapter->MacTab.Content[BSSID_WCID]);
+
+ RTMP_SET_PSFLAG(pAdapter, fRTMP_PS_CAN_GO_SLEEP);
}
int rt_ioctl_siwencodeext(struct net_device *dev,
@@ -2544,6 +2567,21 @@ int rt_ioctl_siwencodeext(struct net_device *dev,
NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
+
+ if (pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP40Enabled ||
+ pAdapter->StaCfg.GroupCipher == Ndis802_11GroupWEP104Enabled)
+ {
+ // Set Group key material to Asic
+ AsicAddSharedKeyEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, pAdapter->SharedKey[BSS0][keyIdx].Key, NULL, NULL);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, keyIdx, pAdapter->SharedKey[BSS0][keyIdx].CipherAlg, NULL);
+
+ STA_PORT_SECURED(pAdapter);
+
+ // Indicate Connected for GUI
+ pAdapter->IndicateMediaState = NdisMediaStateConnected;
+ }
break;
case IW_ENCODE_ALG_TKIP:
DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __func__, keyIdx, ext->key_len));
@@ -4259,7 +4297,23 @@ INT RTMPSetInformation(
}
#ifdef WPA_SUPPLICANT_SUPPORT
- if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
+ if ((pAdapter->StaCfg.WpaSupplicantUP != 0) &&
+ (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ Key = pWepKey->KeyMaterial;
+
+ // Set Group key material to Asic
+ AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
+
+ STA_PORT_SECURED(pAdapter);
+
+ // Indicate Connected for GUI
+ pAdapter->IndicateMediaState = NdisMediaStateConnected;
+ }
+ else if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
#endif // WPA_SUPPLICANT_SUPPORT
{
Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
@@ -5265,7 +5319,6 @@ INT RTMPQueryInformation(
case RT_OID_802_11_PRODUCTID:
DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
-#ifdef RT2860
{
USHORT device_id;
@@ -5275,7 +5328,6 @@ INT RTMPQueryInformation(
DBGPRINT(RT_DEBUG_TRACE, (" pci_dev = NULL\n"));
sprintf(tmp, "%04x %04x\n", NIC_PCI_VENDOR_ID, device_id);
}
-#endif // RT2860 //
wrq->u.data.length = strlen(tmp);
Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
break;
diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h
index 88c7c8bf3fc..0134ae6097c 100644
--- a/drivers/staging/rt2860/wpa.h
+++ b/drivers/staging/rt2860/wpa.h
@@ -90,6 +90,7 @@
#define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
#define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
#define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+#define MIN_LEN_OF_GTK 5
// RSN IE Length definition
#define MAX_LEN_OF_RSNIE 90
diff --git a/drivers/staging/rt2870/2870_main_dev.c b/drivers/staging/rt2870/2870_main_dev.c
index 04c764d95d7..9d59e3167fe 100644
--- a/drivers/staging/rt2870/2870_main_dev.c
+++ b/drivers/staging/rt2870/2870_main_dev.c
@@ -265,7 +265,7 @@ INT MlmeThread(
*/
DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
- pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->MLMEThr_task = NULL;
complete_and_exit (&pAd->mlmeComplete, 0);
return 0;
@@ -373,7 +373,7 @@ INT RTUSBCmdThread(
*/
DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
- pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->RTUSBCmdThr_task = NULL;
complete_and_exit (&pAd->CmdQComplete, 0);
return 0;
@@ -467,7 +467,7 @@ INT TimerQThread(
*/
DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__func__));
- pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->TimerQThr_task = NULL;
complete_and_exit(&pAd->TimerQComplete, 0);
return 0;
@@ -944,69 +944,46 @@ VOID RT28xxThreadTerminate(
RTUSBCancelPendingIRPs(pAd);
// Terminate Threads
- CHECK_PID_LEGALITY(pObj->TimerQThr_pid)
+ BUG_ON(pObj->TimerQThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->TimerQThr_task))
{
POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
- printk("Terminate the TimerQThr_pid=%d!\n", GET_PID_NUMBER(pObj->TimerQThr_pid));
+ printk(KERN_DEBUG "Terminate the TimerQThr pid=%d!\n",
+ pid_nr(task_pid(pObj->TimerQThr_task)));
mb();
pAd->TimerFunc_kill = 1;
mb();
- ret = KILL_THREAD_PID(pObj->TimerQThr_pid, SIGTERM, 1);
- if (ret)
- {
- printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
- pAd->net_dev->name, GET_PID_NUMBER(pObj->TimerQThr_pid), ret);
- }
- else
- {
- wait_for_completion(&pAd->TimerQComplete);
- pObj->TimerQThr_pid = THREAD_PID_INIT_VALUE;
- }
+ kthread_stop(pObj->TimerQThr_task);
+ pObj->TimerQThr_task = NULL;
}
- CHECK_PID_LEGALITY(pObj->MLMEThr_pid)
+ BUG_ON(pObj->MLMEThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task))
{
- printk("Terminate the MLMEThr_pid=%d!\n", GET_PID_NUMBER(pObj->MLMEThr_pid));
+ printk(KERN_DEBUG "Terminate the MLMEThr pid=%d!\n",
+ pid_nr(task_pid(pObj->MLMEThr_task)));
mb();
pAd->mlme_kill = 1;
//RT28XX_MLME_HANDLER(pAd);
mb();
- ret = KILL_THREAD_PID(pObj->MLMEThr_pid, SIGTERM, 1);
- if (ret)
- {
- printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
- pAd->net_dev->name, GET_PID_NUMBER(pObj->MLMEThr_pid), ret);
- }
- else
- {
- //wait_for_completion (&pAd->notify);
- wait_for_completion (&pAd->mlmeComplete);
- pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
- }
+ kthread_stop(pObj->MLMEThr_task);
+ pObj->MLMEThr_task = NULL;
}
- CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
+ BUG_ON(pObj->RTUSBCmdThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
{
- printk("Terminate the RTUSBCmdThr_pid=%d!\n", GET_PID_NUMBER(pObj->RTUSBCmdThr_pid));
+ printk(KERN_DEBUG "Terminate the RTUSBCmdThr pid=%d!\n",
+ pid_nr(task_pid(pObj->RTUSBCmdThr_task)));
mb();
NdisAcquireSpinLock(&pAd->CmdQLock);
pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
NdisReleaseSpinLock(&pAd->CmdQLock);
mb();
//RTUSBCMDUp(pAd);
- ret = KILL_THREAD_PID(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
- if (ret)
- {
- printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
- pAd->net_dev->name, GET_PID_NUMBER(pObj->RTUSBCmdThr_pid), ret);
- }
- else
- {
- //wait_for_completion (&pAd->notify);
- wait_for_completion (&pAd->CmdQComplete);
- pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
- }
+ kthread_stop(pObj->RTUSBCmdThr_task);
+ pObj->RTUSBCmdThr_task = NULL;
}
@@ -1067,7 +1044,7 @@ BOOLEAN RT28XXChipsetCheck(
if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
{
- printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+ printk(KERN_DEBUG "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
break;
}
diff --git a/drivers/staging/rt2870/TODO b/drivers/staging/rt2870/TODO
index eae1ac47d3f..2df1bfed9a5 100644
--- a/drivers/staging/rt2870/TODO
+++ b/drivers/staging/rt2870/TODO
@@ -1,7 +1,14 @@
+I'm hesitant to add a TODO file here, as the wireless developers would
+really have people help them out on the "clean" rt2870 driver that can
+be found at the http://rt2x00.serialmonkey.com/ site.
+
+But, if you wish to clean up this driver instead, here's a short list of
+things that need to be done to get it into a more mergable shape:
+
TODO:
- checkpatch.pl clean
- sparse clean
- - port to in-kernel 80211 stack
+ - port to in-kernel 80211 stack and common rt2x00 infrastructure
- remove reading from /etc/ config files
- review by the wireless developer community
diff --git a/drivers/staging/rt2870/common/2870_rtmp_init.c b/drivers/staging/rt2870/common/2870_rtmp_init.c
index 9f5143b3922..cb16d2fcf60 100644
--- a/drivers/staging/rt2870/common/2870_rtmp_init.c
+++ b/drivers/staging/rt2870/common/2870_rtmp_init.c
@@ -727,8 +727,8 @@ NDIS_STATUS AdapterBlockAllocateMemory(
usb_dev = pObj->pUsb_Dev;
- pObj->MLMEThr_pid = THREAD_PID_INIT_VALUE;
- pObj->RTUSBCmdThr_pid = THREAD_PID_INIT_VALUE;
+ pObj->MLMEThr_task = NULL;
+ pObj->RTUSBCmdThr_task = NULL;
*ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
@@ -765,7 +765,7 @@ NDIS_STATUS CreateThreads(
{
PRTMP_ADAPTER pAd = net_dev->ml_priv;
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
- pid_t pid_number = -1;
+ struct task_struct *tsk;
//init_MUTEX(&(pAd->usbdev_semaphore));
@@ -779,36 +779,39 @@ NDIS_STATUS CreateThreads(
init_completion (&pAd->TimerQComplete);
// Creat MLME Thread
- pObj->MLMEThr_pid= THREAD_PID_INIT_VALUE;
- pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
- if (pid_number < 0)
- {
+ pObj->MLMEThr_task = NULL;
+ tsk = kthread_run(MlmeThread, pAd, pAd->net_dev->name);
+
+ if (IS_ERR(tsk)) {
printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
return NDIS_STATUS_FAILURE;
}
- pObj->MLMEThr_pid = GET_PID(pid_number);
+
+ pObj->MLMEThr_task = tsk;
// Wait for the thread to start
wait_for_completion(&(pAd->mlmeComplete));
// Creat Command Thread
- pObj->RTUSBCmdThr_pid= THREAD_PID_INIT_VALUE;
- pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
- if (pid_number < 0)
+ pObj->RTUSBCmdThr_task = NULL;
+ tsk = kthread_run(RTUSBCmdThread, pAd, pAd->net_dev->name);
+
+ if (IS_ERR(tsk) < 0)
{
printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
return NDIS_STATUS_FAILURE;
}
- pObj->RTUSBCmdThr_pid = GET_PID(pid_number);
+
+ pObj->RTUSBCmdThr_task = tsk;
wait_for_completion(&(pAd->CmdQComplete));
- pObj->TimerQThr_pid= THREAD_PID_INIT_VALUE;
- pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
- if (pid_number < 0)
+ pObj->TimerQThr_task = NULL;
+ tsk = kthread_run(TimerQThread, pAd, pAd->net_dev->name);
+ if (IS_ERR(tsk) < 0)
{
printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
return NDIS_STATUS_FAILURE;
}
- pObj->TimerQThr_pid = GET_PID(pid_number);
+ pObj->TimerQThr_task = tsk;
// Wait for the thread to start
wait_for_completion(&(pAd->TimerQComplete));
diff --git a/drivers/staging/rt2870/common/cmm_data.c b/drivers/staging/rt2870/common/cmm_data.c
index fd809abf6df..f8e0ebd7bca 100644
--- a/drivers/staging/rt2870/common/cmm_data.c
+++ b/drivers/staging/rt2870/common/cmm_data.c
@@ -709,9 +709,6 @@ BOOLEAN RTMP_FillTxBlkInfo(
}
return TRUE;
-
-FillTxBlkErr:
- return FALSE;
}
diff --git a/drivers/staging/rt2870/common/rtmp_init.c b/drivers/staging/rt2870/common/rtmp_init.c
index 870a00da3da..099b6a806f8 100644
--- a/drivers/staging/rt2870/common/rtmp_init.c
+++ b/drivers/staging/rt2870/common/rtmp_init.c
@@ -3655,7 +3655,7 @@ VOID UserCfgInit(
#ifdef RALINK_28xx_QA
//pAd->ate.Repeat = 0;
pAd->ate.TxStatus = 0;
- pAd->ate.AtePid = THREAD_PID_INIT_VALUE;
+ pAd->ate.AtePid = NULL;
#endif // RALINK_28xx_QA //
#endif // RALINK_ATE //
diff --git a/drivers/staging/rt2870/common/rtusb_io.c b/drivers/staging/rt2870/common/rtusb_io.c
index 6db443e9268..afde136a9a0 100644
--- a/drivers/staging/rt2870/common/rtusb_io.c
+++ b/drivers/staging/rt2870/common/rtusb_io.c
@@ -958,7 +958,8 @@ NDIS_STATUS RTUSBEnqueueCmdFromNdis(
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
- CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid)
+ BUG_ON(pObj->RTUSBCmdThr_task == NULL);
+ CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task))
return (NDIS_STATUS_RESOURCES);
status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
diff --git a/drivers/staging/rt2870/common/spectrum.c b/drivers/staging/rt2870/common/spectrum.c
index 43782ce9288..74380958eb7 100644
--- a/drivers/staging/rt2870/common/spectrum.c
+++ b/drivers/staging/rt2870/common/spectrum.c
@@ -1595,7 +1595,7 @@ static VOID PeerMeasureReportAction(
if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%zu).\n", __func__, sizeof(MEASURE_RPI_REPORT)));
return;
}
diff --git a/drivers/staging/rt2870/rt2870.h b/drivers/staging/rt2870/rt2870.h
index 30af4b57c3d..5dd15aac9ce 100644
--- a/drivers/staging/rt2870/rt2870.h
+++ b/drivers/staging/rt2870/rt2870.h
@@ -86,6 +86,7 @@
#define RT2870_USB_DEVICES \
{ \
{USB_DEVICE(0x148F,0x2770)}, /* Ralink */ \
+ {USB_DEVICE(0x1737,0x0071)}, /* Linksys WUSB600N */ \
{USB_DEVICE(0x148F,0x2870)}, /* Ralink */ \
{USB_DEVICE(0x148F,0x3070)}, /* Ralink */ \
{USB_DEVICE(0x0B05,0x1731)}, /* Asus */ \
@@ -576,14 +577,16 @@ VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
#define RTUSBMlmeUp(pAd) \
{ \
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
- CHECK_PID_LEGALITY(pObj->MLMEThr_pid) \
+ BUG_ON(pObj->MLMEThr_task == NULL); \
+ CHECK_PID_LEGALITY(task_pid(pObj->MLMEThr_task)) \
up(&(pAd->mlme_semaphore)); \
}
#define RTUSBCMDUp(pAd) \
{ \
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
- CHECK_PID_LEGALITY(pObj->RTUSBCmdThr_pid) \
+ BUG_ON(pObj->RTUSBCmdThr_task == NULL); \
+ CHECK_PID_LEGALITY(task_pid(pObj->RTUSBCmdThr_task)) \
up(&(pAd->RTUSBCmd_semaphore)); \
}
diff --git a/drivers/staging/rt2870/rt_linux.c b/drivers/staging/rt2870/rt_linux.c
index 992e3d16f9b..e38552c5ccb 100644
--- a/drivers/staging/rt2870/rt_linux.c
+++ b/drivers/staging/rt2870/rt_linux.c
@@ -895,7 +895,7 @@ void send_monitor_packets(
if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
{
- DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%zu)\n", __func__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
goto err_free_sk_buff;
}
diff --git a/drivers/staging/rt2870/rt_linux.h b/drivers/staging/rt2870/rt_linux.h
index 859f9cef0a1..5a6ee6ad0e5 100644
--- a/drivers/staging/rt2870/rt_linux.h
+++ b/drivers/staging/rt2870/rt_linux.h
@@ -44,6 +44,7 @@
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
+#include <linux/kthread.h>
#include <linux/spinlock.h>
#include <linux/init.h>
@@ -65,7 +66,6 @@
#include <linux/vmalloc.h>
-#include <linux/wireless.h>
#include <net/iw_handler.h>
// load firmware
@@ -166,14 +166,12 @@ typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
typedef struct pid * THREAD_PID;
-#define THREAD_PID_INIT_VALUE NULL
#define GET_PID(_v) find_get_pid(_v)
#define GET_PID_NUMBER(_v) pid_nr(_v)
#define CHECK_PID_LEGALITY(_pid) if (pid_nr(_pid) >= 0)
#define KILL_THREAD_PID(_A, _B, _C) kill_pid(_A, _B, _C)
#else
typedef pid_t THREAD_PID;
-#define THREAD_PID_INIT_VALUE -1
#define GET_PID(_v) _v
#define GET_PID_NUMBER(_v) _v
#define CHECK_PID_LEGALITY(_pid) if (_pid >= 0)
@@ -189,11 +187,11 @@ struct os_lock {
struct os_cookie {
#ifdef RT2870
- struct usb_device *pUsb_Dev;
+ struct usb_device *pUsb_Dev;
- THREAD_PID MLMEThr_pid;
- THREAD_PID RTUSBCmdThr_pid;
- THREAD_PID TimerQThr_pid;
+ struct task_struct *MLMEThr_task;
+ struct task_struct *RTUSBCmdThr_task;
+ struct task_struct *TimerQThr_task;
#endif // RT2870 //
struct tasklet_struct rx_done_task;
diff --git a/drivers/staging/rt2870/sta_ioctl.c b/drivers/staging/rt2870/sta_ioctl.c
index 91f0fab1131..4b432ce4442 100644
--- a/drivers/staging/rt2870/sta_ioctl.c
+++ b/drivers/staging/rt2870/sta_ioctl.c
@@ -1776,7 +1776,7 @@ int rt_ioctl_siwencode(struct net_device *dev,
}
else
/* Don't complain if only change the mode */
- if(!erq->flags & IW_ENCODE_MODE) {
+ if (!(erq->flags & IW_ENCODE_MODE)) {
return -EINVAL;
}
}
diff --git a/drivers/staging/rt3070/2870_main_dev.c b/drivers/staging/rt3070/2870_main_dev.c
new file mode 100644
index 00000000000..401ddb01213
--- /dev/null
+++ b/drivers/staging/rt3070/2870_main_dev.c
@@ -0,0 +1,1627 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_main.c
+
+ Abstract:
+ main initialization routines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Jan Lee 01-10-2005 modified
+ Sample Jun/01/07 Merge RT2870 and RT2860 drivers.
+*/
+
+#include "rt_config.h"
+
+
+// Following information will be show when you run 'modinfo'
+// *** If you have a solution for the bug in current version of driver, please mail to me.
+// Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. ***
+MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
+MODULE_DESCRIPTION("RT2870 Wireless Lan Linux Driver");
+#ifdef CONFIG_STA_SUPPORT
+MODULE_LICENSE("GPL");
+#ifdef MODULE_VERSION
+MODULE_VERSION(STA_DRIVER_VERSION);
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// record whether the card in the card list is used in the card file
+extern UINT8 MC_CardUsed[];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+/* Kernel thread and vars, which handles packets that are completed. Only
+ * packets that have a "complete" function are sent here. This way, the
+ * completion is run out of kernel context, and doesn't block the rest of
+ * the stack. */
+//static int mlme_kill = 0; // Mlme kernel thread
+//static int RTUSBCmd_kill = 0; // Command kernel thread
+//static int TimerFunc_kill = 0; // TimerQ kernel thread
+
+//static wait_queue_head_t timerWaitQ;
+//static wait_queue_t waitQ;
+
+extern INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
+ IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+
+
+/* module table */
+struct usb_device_id rtusb_usb_id[] = RT2870_USB_DEVICES;
+INT const rtusb_usb_id_len = sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
+MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
+
+#ifndef PF_NOFREEZE
+#define PF_NOFREEZE 0
+#endif
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+
+/**************************************************************************/
+/**************************************************************************/
+//tested for kernel 2.4 series
+/**************************************************************************/
+/**************************************************************************/
+static void *rtusb_probe(struct usb_device *dev, UINT interface,
+ const struct usb_device_id *id_table);
+static void rtusb_disconnect(struct usb_device *dev, void *ptr);
+
+struct usb_driver rtusb_driver = {
+ name:"rt2870",
+ probe:rtusb_probe,
+ disconnect:rtusb_disconnect,
+ id_table:rtusb_usb_id,
+ };
+
+#else
+
+#ifdef CONFIG_PM
+static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
+static int rt2870_resume(struct usb_interface *intf);
+#endif // CONFIG_PM //
+
+/**************************************************************************/
+/**************************************************************************/
+//tested for kernel 2.6series
+/**************************************************************************/
+/**************************************************************************/
+static int rtusb_probe (struct usb_interface *intf,
+ const struct usb_device_id *id);
+static void rtusb_disconnect(struct usb_interface *intf);
+
+struct usb_driver rtusb_driver = {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ .owner = THIS_MODULE,
+#endif
+ .name="rt2870",
+ .probe=rtusb_probe,
+ .disconnect=rtusb_disconnect,
+ .id_table=rtusb_usb_id,
+
+#ifdef CONFIG_PM
+ suspend: rt2870_suspend,
+ resume: rt2870_resume,
+#endif
+ };
+
+#ifdef CONFIG_PM
+
+VOID RT2860RejectPendingPackets(
+ IN PRTMP_ADAPTER pAd)
+{
+ // clear PS packets
+ // clear TxSw packets
+}
+
+static int rt2870_suspend(
+ struct usb_interface *intf,
+ pm_message_t state)
+{
+ struct net_device *net_dev;
+ PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
+ net_dev = pAd->net_dev;
+ netif_device_detach(net_dev);
+
+ pAd->PM_FlgSuspend = 1;
+ if (netif_running(net_dev)) {
+ RTUSBCancelPendingBulkInIRP(pAd);
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
+ return 0;
+}
+
+static int rt2870_resume(
+ struct usb_interface *intf)
+{
+ struct net_device *net_dev;
+ PRTMP_ADAPTER pAd = usb_get_intfdata(intf);
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
+
+ pAd->PM_FlgSuspend = 0;
+ net_dev = pAd->net_dev;
+ netif_device_attach(net_dev);
+ netif_start_queue(net_dev);
+ netif_carrier_on(net_dev);
+ netif_wake_queue(net_dev);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
+ return 0;
+}
+#endif // CONFIG_PM //
+#endif // LINUX_VERSION_CODE //
+
+
+// Init driver module
+INT __init rtusb_init(void)
+{
+ printk("rtusb init --->\n");
+ return usb_register(&rtusb_driver);
+}
+
+// Deinit driver module
+VOID __exit rtusb_exit(void)
+{
+ usb_deregister(&rtusb_driver);
+ printk("<--- rtusb exit\n");
+}
+
+module_init(rtusb_init);
+module_exit(rtusb_exit);
+
+
+
+
+/*--------------------------------------------------------------------- */
+/* function declarations */
+/*--------------------------------------------------------------------- */
+
+/*
+========================================================================
+Routine Description:
+ MLME kernel thread.
+
+Arguments:
+ *Context the pAd, driver control block pointer
+
+Return Value:
+ 0 close the thread
+
+Note:
+========================================================================
+*/
+INT MlmeThread(
+ IN void *Context)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
+ POS_COOKIE pObj;
+ int status;
+
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ rtmp_os_thread_init("rt2870MlmeThread", (PVOID)&(pAd->mlmeComplete));
+
+ while (pAd->mlme_kill == 0)
+ {
+ /* lock the device pointers */
+ //down(&(pAd->mlme_semaphore));
+ status = down_interruptible(&(pAd->mlme_semaphore));
+
+ /* lock the device pointers , need to check if required*/
+ //down(&(pAd->usbdev_semaphore));
+
+ if (!pAd->PM_FlgSuspend)
+ MlmeHandler(pAd);
+
+ /* unlock the device pointers */
+ //up(&(pAd->usbdev_semaphore));
+ if (status != 0)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+ }
+
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+
+ pObj->MLMEThr_pid = NULL;
+
+ complete_and_exit (&pAd->mlmeComplete, 0);
+ return 0;
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ USB command kernel thread.
+
+Arguments:
+ *Context the pAd, driver control block pointer
+
+Return Value:
+ 0 close the thread
+
+Note:
+========================================================================
+*/
+INT RTUSBCmdThread(
+ IN void * Context)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)Context;
+ POS_COOKIE pObj;
+ int status;
+
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ rtmp_os_thread_init("rt2870CmdThread", (PVOID)&(pAd->CmdQComplete));
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RT2870_THREAD_RUNNING;
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ while (pAd->CmdQ.CmdQState == RT2870_THREAD_RUNNING)
+ {
+ /* lock the device pointers */
+ //down(&(pAd->RTUSBCmd_semaphore));
+ status = down_interruptible(&(pAd->RTUSBCmd_semaphore));
+
+ if (pAd->CmdQ.CmdQState == RT2870_THREAD_STOPED)
+ break;
+
+ if (status != 0)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+ /* lock the device pointers , need to check if required*/
+ //down(&(pAd->usbdev_semaphore));
+
+ if (!pAd->PM_FlgSuspend)
+ CMDHandler(pAd);
+
+ /* unlock the device pointers */
+ //up(&(pAd->usbdev_semaphore));
+ }
+
+ if (!pAd->PM_FlgSuspend)
+ { // Clear the CmdQElements.
+ CmdQElmt *pCmdQElmt = NULL;
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
+ while(pAd->CmdQ.size)
+ {
+ RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
+ if (pCmdQElmt)
+ {
+ if (pCmdQElmt->CmdFromNdis == TRUE)
+ {
+ if (pCmdQElmt->buffer != NULL)
+ NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
+
+ NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ {
+ if ((pCmdQElmt->buffer != NULL) && (pCmdQElmt->bufferlength != 0))
+ NdisFreeMemory(pCmdQElmt->buffer, pCmdQElmt->bufferlength, 0);
+ {
+ NdisFreeMemory(pCmdQElmt, sizeof(CmdQElmt), 0);
+ }
+ }
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+ }
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+ DBGPRINT(RT_DEBUG_TRACE,( "<---RTUSBCmdThread\n"));
+
+ pObj->RTUSBCmdThr_pid = NULL;
+
+ complete_and_exit (&pAd->CmdQComplete, 0);
+ return 0;
+
+}
+
+
+static void RT2870_TimerQ_Handle(RTMP_ADAPTER *pAd)
+{
+ int status;
+ RALINK_TIMER_STRUCT *pTimer;
+ RT2870_TIMER_ENTRY *pEntry;
+ unsigned long irqFlag;
+
+ while(!pAd->TimerFunc_kill)
+ {
+// printk("waiting for event!\n");
+ pTimer = NULL;
+
+ status = down_interruptible(&(pAd->RTUSBTimer_semaphore));
+
+ if (pAd->TimerQ.status == RT2870_THREAD_STOPED)
+ break;
+
+ // event happened.
+ while(pAd->TimerQ.pQHead)
+ {
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlag);
+ pEntry = pAd->TimerQ.pQHead;
+ if (pEntry)
+ {
+ pTimer = pEntry->pRaTimer;
+
+ // update pQHead
+ pAd->TimerQ.pQHead = pEntry->pNext;
+ if (pEntry == pAd->TimerQ.pQTail)
+ pAd->TimerQ.pQTail = NULL;
+
+ // return this queue entry to timerQFreeList.
+ pEntry->pNext = pAd->TimerQ.pQPollFreeList;
+ pAd->TimerQ.pQPollFreeList = pEntry;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlag);
+
+ if (pTimer)
+ {
+ if (pTimer->handle != NULL)
+ if (!pAd->PM_FlgSuspend)
+ pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
+ if ((pTimer->Repeat) && (pTimer->State == FALSE))
+ RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
+ }
+ }
+
+ if (status != 0)
+ {
+ pAd->TimerQ.status = RT2870_THREAD_STOPED;
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ break;
+ }
+ }
+}
+
+
+INT TimerQThread(
+ IN OUT PVOID Context)
+{
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+
+ pAd = (PRTMP_ADAPTER)Context;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ rtmp_os_thread_init("rt2870TimerQHandle", (PVOID)&(pAd->TimerQComplete));
+
+ RT2870_TimerQ_Handle(pAd);
+
+ /* notify the exit routine that we're actually exiting now
+ *
+ * complete()/wait_for_completion() is similar to up()/down(),
+ * except that complete() is safe in the case where the structure
+ * is getting deleted in a parallel mode of execution (i.e. just
+ * after the down() -- that's necessary for the thread-shutdown
+ * case.
+ *
+ * complete_and_exit() goes even further than this -- it is safe in
+ * the case that the thread of the caller is going away (not just
+ * the structure) -- this is necessary for the module-remove case.
+ * This is important in preemption kernels, which transfer the flow
+ * of execution immediately upon a complete().
+ */
+ DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
+
+ pObj->TimerQThr_pid = NULL;
+
+ complete_and_exit(&pAd->TimerQComplete, 0);
+ return 0;
+
+}
+
+
+RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer)
+{
+ RT2870_TIMER_ENTRY *pQNode = NULL, *pQTail;
+ unsigned long irqFlags;
+
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ if (pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)
+ {
+ if(pAd->TimerQ.pQPollFreeList)
+ {
+ pQNode = pAd->TimerQ.pQPollFreeList;
+ pAd->TimerQ.pQPollFreeList = pQNode->pNext;
+
+ pQNode->pRaTimer = pTimer;
+ pQNode->pNext = NULL;
+
+ pQTail = pAd->TimerQ.pQTail;
+ if (pAd->TimerQ.pQTail != NULL)
+ pQTail->pNext = pQNode;
+ pAd->TimerQ.pQTail = pQNode;
+ if (pAd->TimerQ.pQHead == NULL)
+ pAd->TimerQ.pQHead = pQNode;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+ if (pQNode)
+ up(&pAd->RTUSBTimer_semaphore);
+ //wake_up(&timerWaitQ);
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+ }
+ return pQNode;
+}
+
+
+BOOLEAN RT2870_TimerQ_Remove(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer)
+{
+ RT2870_TIMER_ENTRY *pNode, *pPrev = NULL;
+ unsigned long irqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ if (pAd->TimerQ.status >= RT2870_THREAD_INITED)
+ {
+ pNode = pAd->TimerQ.pQHead;
+ while (pNode)
+ {
+ if (pNode->pRaTimer == pTimer)
+ break;
+ pPrev = pNode;
+ pNode = pNode->pNext;
+ }
+
+ // Now move it to freeList queue.
+ if (pNode)
+ {
+ if (pNode == pAd->TimerQ.pQHead)
+ pAd->TimerQ.pQHead = pNode->pNext;
+ if (pNode == pAd->TimerQ.pQTail)
+ pAd->TimerQ.pQTail = pPrev;
+ if (pPrev != NULL)
+ pPrev->pNext = pNode->pNext;
+
+ // return this queue entry to timerQFreeList.
+ pNode->pNext = pAd->TimerQ.pQPollFreeList;
+ pAd->TimerQ.pQPollFreeList = pNode;
+ }
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+ return TRUE;
+}
+
+
+void RT2870_TimerQ_Exit(RTMP_ADAPTER *pAd)
+{
+ RT2870_TIMER_ENTRY *pTimerQ;
+ unsigned long irqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ while (pAd->TimerQ.pQHead)
+ {
+ pTimerQ = pAd->TimerQ.pQHead;
+ pAd->TimerQ.pQHead = pTimerQ->pNext;
+ // remove the timeQ
+ }
+ pAd->TimerQ.pQPollFreeList = NULL;
+ os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
+ pAd->TimerQ.pQTail = NULL;
+ pAd->TimerQ.pQHead = NULL;
+ pAd->TimerQ.status = RT2870_THREAD_STOPED;
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+
+}
+
+
+void RT2870_TimerQ_Init(RTMP_ADAPTER *pAd)
+{
+ int i;
+ RT2870_TIMER_ENTRY *pQNode, *pEntry;
+ unsigned long irqFlags;
+
+ NdisAllocateSpinLock(&pAd->TimerQLock);
+
+ RTMP_IRQ_LOCK(&pAd->TimerQLock, irqFlags);
+ NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
+ //InterlockedExchange(&pAd->TimerQ.count, 0);
+
+ /* Initialise the wait q head */
+ //init_waitqueue_head(&timerWaitQ);
+
+ os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RT2870_TIMER_ENTRY) * TIMER_QUEUE_SIZE_MAX);
+ if (pAd->TimerQ.pTimerQPoll)
+ {
+ pEntry = NULL;
+ pQNode = (RT2870_TIMER_ENTRY *)pAd->TimerQ.pTimerQPoll;
+ for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
+ {
+ pQNode->pNext = pEntry;
+ pEntry = pQNode;
+ pQNode++;
+ }
+ pAd->TimerQ.pQPollFreeList = pEntry;
+ pAd->TimerQ.pQHead = NULL;
+ pAd->TimerQ.pQTail = NULL;
+ pAd->TimerQ.status = RT2870_THREAD_INITED;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TimerQLock, irqFlags);
+}
+
+
+VOID RT2870_WatchDog(IN RTMP_ADAPTER *pAd)
+{
+ PHT_TX_CONTEXT pHTTXContext;
+ int idx;
+ ULONG irqFlags;
+ PURB pUrb;
+ BOOLEAN needDumpSeq = FALSE;
+ UINT32 MACValue;
+
+
+ idx = 0;
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+ if ((MACValue & 0xff) !=0 )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 0 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
+ while((MACValue &0xff) != 0 && (idx++ < 10))
+ {
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+ NdisMSleep(1);
+ }
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+ }
+
+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ idx = 0;
+ if ((MACValue & 0xff00) !=0 )
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("TX QUEUE 1 Not EMPTY(Value=0x%0x). !!!!!!!!!!!!!!!\n", MACValue));
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf4000a);
+ while((MACValue &0xff00) != 0 && (idx++ < 10))
+ {
+ RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
+ NdisMSleep(1);
+ }
+ RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pAd->watchDogRxOverFlowCnt >= 2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
+ if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_BULKIN_RESET |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+ needDumpSeq = TRUE;
+ }
+ pAd->watchDogRxOverFlowCnt = 0;
+ }
+
+
+ for (idx = 0; idx < NUM_OF_TX_RING; idx++)
+ {
+ pUrb = NULL;
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
+ if ((pAd->BulkOutPending[idx] == TRUE) && pAd->watchDogTxPendingCnt)
+ {
+ pAd->watchDogTxPendingCnt[idx]++;
+
+ if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
+ (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_BULKOUT_RESET)))
+ )
+ {
+ // FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it!
+ pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[idx]);
+ if (pHTTXContext->IRPPending)
+ { // Check TxContext.
+ pUrb = pHTTXContext->pUrb;
+ }
+ else if (idx == MGMTPIPEIDX)
+ {
+ PTX_CONTEXT pMLMEContext, pNULLContext, pPsPollContext;
+
+ //Check MgmtContext.
+ pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
+ pPsPollContext = (PTX_CONTEXT)(&pAd->PsPollContext);
+ pNULLContext = (PTX_CONTEXT)(&pAd->NullContext);
+
+ if (pMLMEContext->IRPPending)
+ {
+ ASSERT(pMLMEContext->IRPPending);
+ pUrb = pMLMEContext->pUrb;
+ }
+ else if (pNULLContext->IRPPending)
+ {
+ ASSERT(pNULLContext->IRPPending);
+ pUrb = pNULLContext->pUrb;
+ }
+ else if (pPsPollContext->IRPPending)
+ {
+ ASSERT(pPsPollContext->IRPPending);
+ pUrb = pPsPollContext->pUrb;
+ }
+ }
+
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n", idx));
+ if (pUrb)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unlink the pending URB!\n"));
+ // unlink it now
+ RTUSB_UNLINK_URB(pUrb);
+ // Sleep 200 microseconds to give cancellation time to work
+ RTMPusecDelay(200);
+ needDumpSeq = TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Unkonw bulkOut URB maybe hanged!!!!!!!!!!!!\n"));
+ }
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+ }
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // For Sigma debug, dump the ba_reordering sequence.
+ if((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ USHORT Idx;
+ PBA_REC_ENTRY pBAEntry = NULL;
+ UCHAR count = 0;
+ struct reordering_mpdu *mpdu_blk;
+
+ Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
+
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ if((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+ mpdu_blk = pBAEntry->list.next;
+ while (mpdu_blk)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("\t%d:Seq-%d, bAMSDU-%d!\n", count, mpdu_blk->Sequence, mpdu_blk->bAMSDU));
+ mpdu_blk = mpdu_blk->next;
+ count++;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\npBAEntry->LastIndSeq=%d!\n", pBAEntry->LastIndSeq));
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+}
+
+/*
+========================================================================
+Routine Description:
+ Release allocated resources.
+
+Arguments:
+ *dev Point to the PCI or USB device
+ pAd driver control block pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static void _rtusb_disconnect(struct usb_device *dev, PRTMP_ADAPTER pAd)
+{
+ struct net_device *net_dev = NULL;
+
+
+ DBGPRINT(RT_DEBUG_ERROR, ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
+ dev->bus->bus_name, dev->devpath));
+ if (!pAd)
+ {
+#ifdef MULTIPLE_CARD_SUPPORT
+ if ((pAd->MC_RowID >= 0) && (pAd->MC_RowID <= MAX_NUM_OF_MULTIPLE_CARD))
+ MC_CardUsed[pAd->MC_RowID] = 0; // not clear MAC address
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ while(MOD_IN_USE > 0)
+ {
+ MOD_DEC_USE_COUNT;
+ }
+#else
+ usb_put_dev(dev);
+#endif // LINUX_VERSION_CODE //
+
+ printk("rtusb_disconnect: pAd == NULL!\n");
+ return;
+ }
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+
+
+
+ // for debug, wait to show some messages to /proc system
+ udelay(1);
+
+
+
+
+ net_dev = pAd->net_dev;
+ if (pAd->net_dev != NULL)
+ {
+ printk("rtusb_disconnect: unregister_netdev(), dev->name=%s!\n", net_dev->name);
+ unregister_netdev (pAd->net_dev);
+ }
+ udelay(1);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+#else
+ flush_scheduled_work();
+#endif // LINUX_VERSION_CODE //
+ udelay(1);
+
+ // free net_device memory
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ kfree(net_dev);
+#else
+ free_netdev(net_dev);
+#endif // LINUX_VERSION_CODE //
+
+ // free adapter memory
+ RTMPFreeAdapter(pAd);
+
+ // release a use of the usb device structure
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ while(MOD_IN_USE > 0)
+ {
+ MOD_DEC_USE_COUNT;
+ }
+#else
+ usb_put_dev(dev);
+#endif // LINUX_VERSION_CODE //
+ udelay(1);
+
+ DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Probe RT28XX chipset.
+
+Arguments:
+ *dev Point to the PCI or USB device
+ interface
+ *id_table Point to the PCI or USB device ID
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+static void *rtusb_probe(struct usb_device *dev, UINT interface,
+ const struct usb_device_id *id)
+{
+ PRTMP_ADAPTER pAd;
+ rt28xx_probe((void *)dev, (void *)id, interface, &pAd);
+ return (void *)pAd;
+}
+
+//Disconnect function is called within exit routine
+static void rtusb_disconnect(struct usb_device *dev, void *ptr)
+{
+ _rtusb_disconnect(dev, ((PRTMP_ADAPTER)ptr));
+}
+
+#else /* kernel 2.6 series */
+static int rtusb_probe (struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ PRTMP_ADAPTER pAd;
+ return (int)rt28xx_probe((void *)intf, (void *)id, 0, &pAd);
+}
+
+
+static void rtusb_disconnect(struct usb_interface *intf)
+{
+ struct usb_device *dev = interface_to_usbdev(intf);
+ PRTMP_ADAPTER pAd;
+
+
+ pAd = usb_get_intfdata(intf);
+ usb_set_intfdata(intf, NULL);
+
+ _rtusb_disconnect(dev, pAd);
+}
+#endif // LINUX_VERSION_CODE //
+
+
+/*
+========================================================================
+Routine Description:
+ Close kernel threads.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ NONE
+
+Note:
+========================================================================
+*/
+VOID RT28xxThreadTerminate(
+ IN RTMP_ADAPTER *pAd)
+{
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ INT ret;
+
+
+ // Sleep 50 milliseconds so pending io might finish normally
+ RTMPusecDelay(50000);
+
+ // We want to wait until all pending receives and sends to the
+ // device object. We cancel any
+ // irps. Wait until sends and receives have stopped.
+ RTUSBCancelPendingIRPs(pAd);
+
+ // Terminate Threads
+ if (pObj->MLMEThr_pid)
+ {
+ printk("Terminate the MLMEThr_pid=%d!\n", pid_nr(pObj->MLMEThr_pid));
+ mb();
+ pAd->mlme_kill = 1;
+ //RT28XX_MLME_HANDLER(pAd);
+ mb();
+ ret = kill_pid(pObj->MLMEThr_pid, SIGTERM, 1);
+ if (ret)
+ {
+ printk (KERN_WARNING "%s: unable to Mlme thread, pid=%d, ret=%d!\n",
+ pAd->net_dev->name, pid_nr(pObj->MLMEThr_pid), ret);
+ }
+ else
+ {
+ //wait_for_completion (&pAd->notify);
+ wait_for_completion (&pAd->mlmeComplete);
+ pObj->MLMEThr_pid = NULL;
+ }
+ }
+
+ if (pObj->RTUSBCmdThr_pid >= 0)
+ {
+ printk("Terminate the RTUSBCmdThr_pid=%d!\n", pid_nr(pObj->RTUSBCmdThr_pid));
+ mb();
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ pAd->CmdQ.CmdQState = RT2870_THREAD_STOPED;
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+ mb();
+ //RTUSBCMDUp(pAd);
+ ret = kill_pid(pObj->RTUSBCmdThr_pid, SIGTERM, 1);
+ if (ret)
+ {
+ printk(KERN_WARNING "%s: unable to RTUSBCmd thread, pid=%d, ret=%d!\n",
+ pAd->net_dev->name, pid_nr(pObj->RTUSBCmdThr_pid), ret);
+ }
+ else
+ {
+ //wait_for_completion (&pAd->notify);
+ wait_for_completion (&pAd->CmdQComplete);
+ pObj->RTUSBCmdThr_pid = NULL;
+ }
+ }
+ if (pObj->TimerQThr_pid >= 0)
+ {
+ POS_COOKIE pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ printk("Terminate the TimerQThr_pid=%d!\n", pid_nr(pObj->TimerQThr_pid));
+ mb();
+ pAd->TimerFunc_kill = 1;
+ mb();
+ ret = kill_pid(pObj->TimerQThr_pid, SIGTERM, 1);
+ if (ret)
+ {
+ printk(KERN_WARNING "%s: unable to stop TimerQThread, pid=%d, ret=%d!\n",
+ pAd->net_dev->name, pid_nr(pObj->TimerQThr_pid), ret);
+ }
+ else
+ {
+ printk("wait_for_completion TimerQThr\n");
+ wait_for_completion(&pAd->TimerQComplete);
+ pObj->TimerQThr_pid = NULL;
+ }
+ }
+ // Kill tasklets
+ pAd->mlme_kill = 0;
+ pAd->CmdQ.CmdQState = RT2870_THREAD_UNKNOWN;
+ pAd->TimerFunc_kill = 0;
+}
+
+
+void kill_thread_task(IN PRTMP_ADAPTER pAd)
+{
+ POS_COOKIE pObj;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ tasklet_kill(&pObj->rx_done_task);
+ tasklet_kill(&pObj->mgmt_dma_done_task);
+ tasklet_kill(&pObj->ac0_dma_done_task);
+ tasklet_kill(&pObj->ac1_dma_done_task);
+ tasklet_kill(&pObj->ac2_dma_done_task);
+ tasklet_kill(&pObj->ac3_dma_done_task);
+ tasklet_kill(&pObj->hcca_dma_done_task);
+ tasklet_kill(&pObj->tbtt_task);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Check the chipset vendor/product ID.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+
+Return Value:
+ TRUE Check ok
+ FALSE Check fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXChipsetCheck(
+ IN void *_dev_p)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_device *dev_p = interface_to_usbdev(intf);
+#endif // LINUX_VERSION_CODE //
+ UINT32 i;
+
+
+ for(i=0; i<rtusb_usb_id_len; i++)
+ {
+ if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
+ dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct)
+ {
+ printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
+ dev_p->descriptor.idVendor, dev_p->descriptor.idProduct);
+ break;
+ }
+ }
+
+ if (i == rtusb_usb_id_len)
+ {
+ printk("rt2870: Error! Device Descriptor not matching!\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Init net device structure.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+ *net_dev Point to the net device
+ *pAd the raxx interface data pointer
+
+Return Value:
+ TRUE Init ok
+ FALSE Init fail
+
+Note:
+========================================================================
+*/
+BOOLEAN RT28XXNetDevInit(
+ IN void *_dev_p,
+ IN struct net_device *net_dev,
+ IN RTMP_ADAPTER *pAd)
+{
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_device *dev_p = interface_to_usbdev(intf);
+#endif // LINUX_VERSION_CODE //
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ pAd->config = dev_p->config;
+#else
+ pAd->config = &dev_p->config->desc;
+#endif // LINUX_VERSION_CODE //
+ return TRUE;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Init net device structure.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+ *pAd the raxx interface data pointer
+
+Return Value:
+ TRUE Config ok
+ FALSE Config fail
+
+Note:
+========================================================================
+*/
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+BOOLEAN RT28XXProbePostConfig(
+ IN void *_dev_p,
+ IN RTMP_ADAPTER *pAd,
+ IN INT32 interface)
+{
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+ struct usb_interface *intf;
+ struct usb_interface_descriptor *iface_desc;
+ struct usb_endpoint_descriptor *endpoint;
+ ULONG BulkOutIdx;
+ UINT32 i;
+
+
+ /* get the active interface descriptor */
+ intf = &dev_p->actconfig->interface[interface];
+ iface_desc = &intf->altsetting[0];
+
+ /* get # of enpoints */
+ pAd->NumberOfPipes = iface_desc->bNumEndpoints;
+ DBGPRINT(RT_DEBUG_TRACE, ("NumEndpoints=%d\n", iface_desc->bNumEndpoints));
+
+ /* Configure Pipes */
+ endpoint = &iface_desc->endpoint[0];
+ BulkOutIdx = 0;
+
+ for(i=0; i<pAd->NumberOfPipes; i++)
+ {
+ if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
+ ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+ {
+ pAd->BulkInEpAddr = endpoint[i].bEndpointAddress;
+ pAd->BulkInMaxPacketSize = endpoint[i].wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
+ }
+ else if ((endpoint[i].bmAttributes == USB_ENDPOINT_XFER_BULK) &&
+ ((endpoint[i].bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
+ {
+ // There are 6 bulk out EP. EP6 highest priority.
+ // EP1-4 is EDCA. EP5 is HCCA.
+ pAd->BulkOutEpAddr[BulkOutIdx++] = endpoint[i].bEndpointAddress;
+ pAd->BulkOutMaxPacketSize = endpoint[i].wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x \n", endpoint[i].bEndpointAddress));
+ }
+ }
+
+ if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
+ {
+ printk("Could not find both bulk-in and bulk-out endpoints\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+#else
+BOOLEAN RT28XXProbePostConfig(
+ IN void *_dev_p,
+ IN RTMP_ADAPTER *pAd,
+ IN INT32 interface)
+{
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_host_interface *iface_desc;
+ ULONG BulkOutIdx;
+ UINT32 i;
+
+
+ /* get the active interface descriptor */
+ iface_desc = intf->cur_altsetting;
+
+ /* get # of enpoints */
+ pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
+
+ /* Configure Pipes */
+ BulkOutIdx = 0;
+
+ for(i=0; i<pAd->NumberOfPipes; i++)
+ {
+ if ((iface_desc->endpoint[i].desc.bmAttributes ==
+ USB_ENDPOINT_XFER_BULK) &&
+ ((iface_desc->endpoint[i].desc.bEndpointAddress &
+ USB_ENDPOINT_DIR_MASK) == USB_DIR_IN))
+ {
+ pAd->BulkInEpAddr = iface_desc->endpoint[i].desc.bEndpointAddress;
+ pAd->BulkInMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK IN MaximumPacketSize = %d\n", pAd->BulkInMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x\n", iface_desc->endpoint[i].desc.bEndpointAddress));
+ }
+ else if ((iface_desc->endpoint[i].desc.bmAttributes ==
+ USB_ENDPOINT_XFER_BULK) &&
+ ((iface_desc->endpoint[i].desc.bEndpointAddress &
+ USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT))
+ {
+ // there are 6 bulk out EP. EP6 highest priority.
+ // EP1-4 is EDCA. EP5 is HCCA.
+ pAd->BulkOutEpAddr[BulkOutIdx++] = iface_desc->endpoint[i].desc.bEndpointAddress;
+ pAd->BulkOutMaxPacketSize = iface_desc->endpoint[i].desc.wMaxPacketSize;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("BULK OUT MaximumPacketSize = %d\n", pAd->BulkOutMaxPacketSize));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,
+ ("EP address = 0x%2x \n", iface_desc->endpoint[i].desc.bEndpointAddress));
+ }
+ }
+
+ if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0]))
+ {
+ printk("%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+#endif // LINUX_VERSION_CODE //
+
+
+/*
+========================================================================
+Routine Description:
+ Disable DMA.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMADisable(
+ IN RTMP_ADAPTER *pAd)
+{
+ // no use
+}
+
+
+
+/*
+========================================================================
+Routine Description:
+ Enable DMA.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28XXDMAEnable(
+ IN RTMP_ADAPTER *pAd)
+{
+ WPDMA_GLO_CFG_STRUC GloCfg;
+ USB_DMA_CFG_STRUC UsbCfg;
+ int i = 0;
+
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x4);
+ do
+ {
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+ break;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> DMABusy\n"));
+ RTMPusecDelay(1000);
+ i++;
+ }while ( i <200);
+
+
+ RTMPusecDelay(50);
+ GloCfg.field.EnTXWriteBackDDONE = 1;
+ GloCfg.field.EnableRxDMA = 1;
+ GloCfg.field.EnableTxDMA = 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("<== WRITE DMA offset 0x208 = 0x%x\n", GloCfg.word));
+ RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+ UsbCfg.word = 0;
+ UsbCfg.field.phyclear = 0;
+ /* usb version is 1.1,do not use bulk in aggregation */
+ if (pAd->BulkInMaxPacketSize == 512)
+ UsbCfg.field.RxBulkAggEn = 1;
+ /* for last packet, PBF might use more than limited, so minus 2 to prevent from error */
+ UsbCfg.field.RxBulkAggLmt = (MAX_RXBULK_SIZE /1024)-3;
+ UsbCfg.field.RxBulkAggTOut = 0x80; /* 2006-10-18 */
+ UsbCfg.field.RxBulkEn = 1;
+ UsbCfg.field.TxBulkEn = 1;
+
+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, UsbCfg.word);
+
+}
+
+/*
+========================================================================
+Routine Description:
+ Write Beacon buffer to Asic.
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RT28xx_UpdateBeaconToAsic(
+ IN RTMP_ADAPTER *pAd,
+ IN INT apidx,
+ IN ULONG FrameLen,
+ IN ULONG UpdatePos)
+{
+ PUCHAR pBeaconFrame = NULL;
+ UCHAR *ptr;
+ UINT i, padding;
+ BEACON_SYNC_STRUCT *pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ UINT32 longValue;
+// USHORT shortValue;
+ BOOLEAN bBcnReq = FALSE;
+ UCHAR bcn_idx = 0;
+
+
+ if (pBeaconFrame == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("pBeaconFrame is NULL!\n"));
+ return;
+ }
+
+ if (pBeaconSync == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("pBeaconSync is NULL!\n"));
+ return;
+ }
+
+ //if ((pAd->WdsTab.Mode == WDS_BRIDGE_MODE) ||
+ // ((pAd->ApCfg.MBSSID[apidx].MSSIDDev == NULL) || !(pAd->ApCfg.MBSSID[apidx].MSSIDDev->flags & IFF_UP))
+ // )
+ if (bBcnReq == FALSE)
+ {
+ /* when the ra interface is down, do not send its beacon frame */
+ /* clear all zero */
+ for(i=0; i<TXWI_SIZE; i+=4) {
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, 0x00);
+ }
+ pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[bcn_idx], TXWI_SIZE);
+ }
+ else
+ {
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(ptr, TYPE_TXWI);
+#endif
+ if (NdisEqualMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE) == FALSE)
+ { // If BeaconTxWI changed, we need to rewrite the TxWI for the Beacon frames.
+ pBeaconSync->BeaconBitMap &= (~(BEACON_BITMAP_MASK & (1 << bcn_idx)));
+ NdisMoveMemory(pBeaconSync->BeaconTxWI[bcn_idx], &pAd->BeaconTxWI, TXWI_SIZE);
+ }
+
+ if ((pBeaconSync->BeaconBitMap & (1 << bcn_idx)) != (1 << bcn_idx))
+ {
+ for (i=0; i<TXWI_SIZE; i+=4) // 16-byte TXWI field
+ {
+ longValue = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[bcn_idx] + i, longValue);
+ ptr += 4;
+ }
+ }
+
+ ptr = pBeaconSync->BeaconBuf[bcn_idx];
+ padding = (FrameLen & 0x01);
+ NdisZeroMemory((PUCHAR)(pBeaconFrame + FrameLen), padding);
+ FrameLen += padding;
+ for (i = 0 ; i < FrameLen /*HW_BEACON_OFFSET*/; i += 2)
+ {
+ if (NdisEqualMemory(ptr, pBeaconFrame, 2) == FALSE)
+ {
+ NdisMoveMemory(ptr, pBeaconFrame, 2);
+ //shortValue = *ptr + (*(ptr+1)<<8);
+ //RTMP_IO_WRITE8(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, shortValue);
+ RTUSBMultiWrite(pAd, pAd->BeaconOffset[bcn_idx] + TXWI_SIZE + i, ptr, 2);
+ }
+ ptr +=2;
+ pBeaconFrame += 2;
+ }
+
+ pBeaconSync->BeaconBitMap |= (1 << bcn_idx);
+
+ // For AP interface, set the DtimBitOn so that we can send Bcast/Mcast frame out after this beacon frame.
+ }
+
+}
+
+
+VOID RT2870_BssBeaconStop(
+ IN RTMP_ADAPTER *pAd)
+{
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ int i, offset;
+ BOOLEAN Cancelled = TRUE;
+
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ if (pBeaconSync && pBeaconSync->EnableBeacon)
+ {
+ INT NumOfBcn;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ NumOfBcn = MAX_MESH_NUM;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+
+ for(i=0; i<NumOfBcn; i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+
+ for (offset=0; offset<HW_BEACON_OFFSET; offset+=4)
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[i] + offset, 0x00);
+
+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+ pBeaconSync->TimIELocationInBeacon[i] = 0;
+ }
+ pBeaconSync->BeaconBitMap = 0;
+ pBeaconSync->DtimBitOn = 0;
+ }
+}
+
+
+VOID RT2870_BssBeaconStart(
+ IN RTMP_ADAPTER *pAd)
+{
+ int apidx;
+ BEACON_SYNC_STRUCT *pBeaconSync;
+// LARGE_INTEGER tsfTime, deltaTime;
+
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ if (pBeaconSync && pBeaconSync->EnableBeacon)
+ {
+ INT NumOfBcn;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ NumOfBcn = MAX_MESH_NUM;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ for(apidx=0; apidx<NumOfBcn; apidx++)
+ {
+ UCHAR CapabilityInfoLocationInBeacon = 0;
+ UCHAR TimIELocationInBeacon = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ NdisZeroMemory(pBeaconSync->BeaconBuf[apidx], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[apidx] = CapabilityInfoLocationInBeacon;
+ pBeaconSync->TimIELocationInBeacon[apidx] = TimIELocationInBeacon;
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[apidx], TXWI_SIZE);
+ }
+ pBeaconSync->BeaconBitMap = 0;
+ pBeaconSync->DtimBitOn = 0;
+ pAd->CommonCfg.BeaconUpdateTimer.Repeat = TRUE;
+
+ pAd->CommonCfg.BeaconAdjust = 0;
+ pAd->CommonCfg.BeaconFactor = 0xffffffff / (pAd->CommonCfg.BeaconPeriod << 10);
+ pAd->CommonCfg.BeaconRemain = (0xffffffff % (pAd->CommonCfg.BeaconPeriod << 10)) + 1;
+ printk("RT2870_BssBeaconStart:BeaconFactor=%d, BeaconRemain=%d!\n", pAd->CommonCfg.BeaconFactor, pAd->CommonCfg.BeaconRemain);
+ RTMPSetTimer(&pAd->CommonCfg.BeaconUpdateTimer, pAd->CommonCfg.BeaconPeriod);
+
+ }
+}
+
+
+VOID RT2870_BssBeaconInit(
+ IN RTMP_ADAPTER *pAd)
+{
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ int i;
+
+ NdisAllocMemory(pAd->CommonCfg.pBeaconSync, sizeof(BEACON_SYNC_STRUCT), MEM_ALLOC_FLAG);
+ if (pAd->CommonCfg.pBeaconSync)
+ {
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ NdisZeroMemory(pBeaconSync, sizeof(BEACON_SYNC_STRUCT));
+ for(i=0; i < HW_BEACON_MAX_COUNT; i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+ pBeaconSync->TimIELocationInBeacon[i] = 0;
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+ }
+ pBeaconSync->BeaconBitMap = 0;
+
+ //RTMPInitTimer(pAd, &pAd->CommonCfg.BeaconUpdateTimer, GET_TIMER_FUNCTION(BeaconUpdateExec), pAd, TRUE);
+ pBeaconSync->EnableBeacon = TRUE;
+ }
+}
+
+
+VOID RT2870_BssBeaconExit(
+ IN RTMP_ADAPTER *pAd)
+{
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ BOOLEAN Cancelled = TRUE;
+ int i;
+
+ if (pAd->CommonCfg.pBeaconSync)
+ {
+ pBeaconSync = pAd->CommonCfg.pBeaconSync;
+ pBeaconSync->EnableBeacon = FALSE;
+ RTMPCancelTimer(&pAd->CommonCfg.BeaconUpdateTimer, &Cancelled);
+ pBeaconSync->BeaconBitMap = 0;
+
+ for(i=0; i<HW_BEACON_MAX_COUNT; i++)
+ {
+ NdisZeroMemory(pBeaconSync->BeaconBuf[i], HW_BEACON_OFFSET);
+ pBeaconSync->CapabilityInfoLocationInBeacon[i] = 0;
+ pBeaconSync->TimIELocationInBeacon[i] = 0;
+ NdisZeroMemory(pBeaconSync->BeaconTxWI[i], TXWI_SIZE);
+ }
+
+ NdisFreeMemory(pAd->CommonCfg.pBeaconSync, HW_BEACON_OFFSET * HW_BEACON_MAX_COUNT, 0);
+ pAd->CommonCfg.pBeaconSync = NULL;
+ }
+}
+
+VOID BeaconUpdateExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+ LARGE_INTEGER tsfTime_a;//, tsfTime_b, deltaTime_exp, deltaTime_ab;
+ UINT32 delta, remain, remain_low, remain_high;
+// BOOLEAN positive;
+
+ ReSyncBeaconTime(pAd);
+
+
+
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW0, &tsfTime_a.u.LowPart);
+ RTMP_IO_READ32(pAd, TSF_TIMER_DW1, &tsfTime_a.u.HighPart);
+
+
+ //positive=getDeltaTime(tsfTime_a, expectedTime, &deltaTime_exp);
+ remain_high = pAd->CommonCfg.BeaconRemain * tsfTime_a.u.HighPart;
+ remain_low = tsfTime_a.u.LowPart % (pAd->CommonCfg.BeaconPeriod << 10);
+ remain = (remain_high + remain_low)%(pAd->CommonCfg.BeaconPeriod << 10);
+ delta = (pAd->CommonCfg.BeaconPeriod << 10) - remain;
+
+ pAd->CommonCfg.BeaconUpdateTimer.TimerValue = (delta >> 10) + 10;
+
+}
+
diff --git a/drivers/staging/rt3070/Kconfig b/drivers/staging/rt3070/Kconfig
new file mode 100644
index 00000000000..b37fb5d13a4
--- /dev/null
+++ b/drivers/staging/rt3070/Kconfig
@@ -0,0 +1,6 @@
+config RT3070
+ tristate "Ralink 3070 wireless support"
+ depends on USB && X86 && WLAN_80211
+ ---help---
+ This is an experimental driver for the Ralink 3070 wireless chip.
+
diff --git a/drivers/staging/rt3070/Makefile b/drivers/staging/rt3070/Makefile
new file mode 100644
index 00000000000..55980c92925
--- /dev/null
+++ b/drivers/staging/rt3070/Makefile
@@ -0,0 +1,47 @@
+obj-$(CONFIG_RT3070) += rt3070sta.o
+
+# TODO: all of these should be removed
+EXTRA_CFLAGS += -DLINUX -DAGGREGATION_SUPPORT -DPIGGYBACK_SUPPORT -DWMM_SUPPORT
+EXTRA_CFLAGS += -DRT2870 -DRT30xx -DRT3070
+EXTRA_CFLAGS += -DCONFIG_STA_SUPPORT
+EXTRA_CFLAGS += -DDBG
+EXTRA_CFLAGS += -DDOT11_N_SUPPORT
+EXTRA_CFLAGS += -DWPA_SUPPLICANT_SUPPORT
+EXTRA_CFLAGS += -DNATIVE_WPA_SUPPLICANT_SUPPORT
+
+rt3070sta-objs := \
+ common/md5.o \
+ common/mlme.o \
+ common/rtmp_wep.o \
+ common/action.o \
+ common/cmm_data.o \
+ common/rtmp_init.o \
+ common/rtmp_tkip.o \
+ common/cmm_sync.o \
+ common/eeprom.o \
+ common/cmm_sanity.o \
+ common/cmm_info.o \
+ common/cmm_wpa.o \
+ common/dfs.o \
+ common/spectrum.o \
+ sta/assoc.o \
+ sta/aironet.o \
+ sta/auth.o \
+ sta/auth_rsp.o \
+ sta/sync.o \
+ sta/sanity.o \
+ sta/rtmp_data.o \
+ sta/connect.o \
+ sta/wpa.o \
+ rt_linux.o \
+ rt_profile.o \
+ rt_main_dev.o \
+ sta_ioctl.o \
+ common/ba_action.o \
+ 2870_main_dev.o \
+ common/2870_rtmp_init.o \
+ common/rtusb_io.o \
+ common/rtusb_bulk.o \
+ common/rtusb_data.o \
+ common/cmm_data_2870.o
+
diff --git a/drivers/staging/rt3070/action.h b/drivers/staging/rt3070/action.h
new file mode 100644
index 00000000000..ce3877dce81
--- /dev/null
+++ b/drivers/staging/rt3070/action.h
@@ -0,0 +1,68 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ aironet.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 04-06-15 Initial
+*/
+
+#ifndef __ACTION_H__
+#define __ACTION_H__
+
+typedef struct PACKED __HT_INFO_OCTET
+{
+#ifdef RT_BIG_ENDIAN
+ UCHAR Reserved:5;
+ UCHAR STA_Channel_Width:1;
+ UCHAR Forty_MHz_Intolerant:1;
+ UCHAR Request:1;
+#else
+ UCHAR Request:1;
+ UCHAR Forty_MHz_Intolerant:1;
+ UCHAR STA_Channel_Width:1;
+ UCHAR Reserved:5;
+#endif
+} HT_INFORMATION_OCTET;
+
+
+typedef struct PACKED __FRAME_HT_INFO
+{
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ HT_INFORMATION_OCTET HT_Info;
+} FRAME_HT_INFO, *PFRAME_HT_INFO;
+
+#endif /* __ACTION_H__ */
+
+
diff --git a/drivers/staging/rt3070/aironet.h b/drivers/staging/rt3070/aironet.h
new file mode 100644
index 00000000000..1e07b19b8cd
--- /dev/null
+++ b/drivers/staging/rt3070/aironet.h
@@ -0,0 +1,210 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ aironet.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 04-06-15 Initial
+*/
+
+#ifndef __AIRONET_H__
+#define __AIRONET_H__
+
+// Measurement Type definition
+#define MSRN_TYPE_UNUSED 0
+#define MSRN_TYPE_CHANNEL_LOAD_REQ 1
+#define MSRN_TYPE_NOISE_HIST_REQ 2
+#define MSRN_TYPE_BEACON_REQ 3
+#define MSRN_TYPE_FRAME_REQ 4
+
+// Scan Mode in Beacon Request
+#define MSRN_SCAN_MODE_PASSIVE 0
+#define MSRN_SCAN_MODE_ACTIVE 1
+#define MSRN_SCAN_MODE_BEACON_TABLE 2
+
+// PHY type definition for Aironet beacon report, CCX 2 table 36-9
+#define PHY_FH 1
+#define PHY_DSS 2
+#define PHY_UNUSED 3
+#define PHY_OFDM 4
+#define PHY_HR_DSS 5
+#define PHY_ERP 6
+
+// RPI table in dBm
+#define RPI_0 0 // Power <= -87
+#define RPI_1 1 // -87 < Power <= -82
+#define RPI_2 2 // -82 < Power <= -77
+#define RPI_3 3 // -77 < Power <= -72
+#define RPI_4 4 // -72 < Power <= -67
+#define RPI_5 5 // -67 < Power <= -62
+#define RPI_6 6 // -62 < Power <= -57
+#define RPI_7 7 // -57 < Power
+
+// Cisco Aironet IAPP definetions
+#define AIRONET_IAPP_TYPE 0x32
+#define AIRONET_IAPP_SUBTYPE_REQUEST 0x01
+#define AIRONET_IAPP_SUBTYPE_REPORT 0x81
+
+// Measurement Request detail format
+typedef struct _MEASUREMENT_REQUEST {
+ UCHAR Channel;
+ UCHAR ScanMode; // Use only in beacon request, other requests did not use this field
+ USHORT Duration;
+} MEASUREMENT_REQUEST, *PMEASUREMENT_REQUEST;
+
+// Beacon Measurement Report
+// All these field might change to UCHAR, because we didn't do anything to these report.
+// We copy all these beacons and report to CCX 2 AP.
+typedef struct _BEACON_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR PhyType; // Definiation is listed above table 36-9
+ UCHAR RxPower;
+ UCHAR BSSID[6];
+ UCHAR ParentTSF[4];
+ UCHAR TargetTSF[8];
+ USHORT BeaconInterval;
+ USHORT CapabilityInfo;
+} BEACON_REPORT, *PBEACON_REPORT;
+
+// Frame Measurement Report (Optional)
+typedef struct _FRAME_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR TA;
+ UCHAR BSSID[6];
+ UCHAR RSSI;
+ UCHAR Count;
+} FRAME_REPORT, *PFRAME_REPORT;
+
+#pragma pack(1)
+// Channel Load Report
+typedef struct _CHANNEL_LOAD_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR CCABusy;
+} CHANNEL_LOAD_REPORT, *PCHANNEL_LOAD_REPORT;
+#pragma pack()
+
+// Nosie Histogram Report
+typedef struct _NOISE_HIST_REPORT {
+ UCHAR Channel;
+ UCHAR Spare;
+ USHORT Duration;
+ UCHAR Density[8];
+} NOISE_HIST_REPORT, *PNOISE_HIST_REPORT;
+
+// Radio Management Capability element
+typedef struct _RADIO_MANAGEMENT_CAPABILITY {
+ UCHAR Eid; // TODO: Why the Eid is 1 byte, not normal 2 bytes???
+ UCHAR Length;
+ UCHAR AironetOui[3]; // AIronet OUI (00 40 96)
+ UCHAR Type; // Type / Version
+ USHORT Status; // swap16 required
+} RADIO_MANAGEMENT_CAPABILITY, *PRADIO_MANAGEMENT_CAPABILITY;
+
+// Measurement Mode Bit definition
+typedef struct _MEASUREMENT_MODE {
+ UCHAR Rsvd:4;
+ UCHAR Report:1;
+ UCHAR NotUsed:1;
+ UCHAR Enable:1;
+ UCHAR Parallel:1;
+} MEASUREMENT_MODE, *PMEASUREMENT_MODE;
+
+// Measurement Request element, This is little endian mode
+typedef struct _MEASUREMENT_REQUEST_ELEMENT {
+ USHORT Eid;
+ USHORT Length; // swap16 required
+ USHORT Token; // non-zero unique token
+ UCHAR Mode; // Measurement Mode
+ UCHAR Type; // Measurement type
+} MEASUREMENT_REQUEST_ELEMENT, *PMEASUREMENT_REQUEST_ELEMENT;
+
+// Measurement Report element, This is little endian mode
+typedef struct _MEASUREMENT_REPORT_ELEMENT {
+ USHORT Eid;
+ USHORT Length; // swap16 required
+ USHORT Token; // non-zero unique token
+ UCHAR Mode; // Measurement Mode
+ UCHAR Type; // Measurement type
+} MEASUREMENT_REPORT_ELEMENT, *PMEASUREMENT_REPORT_ELEMENT;
+
+// Cisco Aironet IAPP Frame Header, Network byte order used
+typedef struct _AIRONET_IAPP_HEADER {
+ UCHAR CiscoSnapHeader[8]; // 8 bytes Cisco snap header
+ USHORT Length; // IAPP ID & length, remember to swap16 in LE system
+ UCHAR Type; // IAPP type
+ UCHAR SubType; // IAPP subtype
+ UCHAR DA[6]; // Destination MAC address
+ UCHAR SA[6]; // Source MAC address
+ USHORT Token; // Dialog token, no need to swap16 since it is for yoken usage only
+} AIRONET_IAPP_HEADER, *PAIRONET_IAPP_HEADER;
+
+// Radio Measurement Request frame
+typedef struct _AIRONET_RM_REQUEST_FRAME {
+ AIRONET_IAPP_HEADER IAPP; // Common header
+ UCHAR Delay; // Activation Delay
+ UCHAR Offset; // Measurement offset
+} AIRONET_RM_REQUEST_FRAME, *PAIRONET_RM_REQUEST_FRAME;
+
+// Radio Measurement Report frame
+typedef struct _AIRONET_RM_REPORT_FRAME {
+ AIRONET_IAPP_HEADER IAPP; // Common header
+} AIRONET_RM_REPORT_FRAME, *PAIRONET_RM_REPORT_FRAME;
+
+// Saved element request actions which will saved in StaCfg.
+typedef struct _RM_REQUEST_ACTION {
+ MEASUREMENT_REQUEST_ELEMENT ReqElem; // Saved request element
+ MEASUREMENT_REQUEST Measurement; // Saved measurement within the request element
+} RM_REQUEST_ACTION, *PRM_REQUEST_ACTION;
+
+// CCX administration control
+typedef union _CCX_CONTROL {
+ struct {
+ UINT32 Enable:1; // Enable CCX2
+ UINT32 LeapEnable:1; // Enable LEAP at CCX2
+ UINT32 RMEnable:1; // Radio Measurement Enable
+ UINT32 DCRMEnable:1; // Non serving channel Radio Measurement enable
+ UINT32 QOSEnable:1; // Enable QOS for CCX 2.0 support
+ UINT32 FastRoamEnable:1; // Enable fast roaming
+ UINT32 Rsvd:2; // Not used
+ UINT32 dBmToRoam:8; // the condition to roam when receiving Rssi less than this value. It's negative value.
+ UINT32 TuLimit:16; // Limit for different channel scan
+ } field;
+ UINT32 word;
+} CCX_CONTROL, *PCCX_CONTROL;
+
+#endif // __AIRONET_H__
diff --git a/drivers/staging/rt3070/ap.h b/drivers/staging/rt3070/ap.h
new file mode 100644
index 00000000000..f5ba042e52b
--- /dev/null
+++ b/drivers/staging/rt3070/ap.h
@@ -0,0 +1,557 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ ap.h
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+ James Tan 09-06-2002 modified (Revise NTCRegTable)
+ John Chang 12-22-2004 modified for RT2561/2661. merge with STA driver
+*/
+#ifndef __AP_H__
+#define __AP_H__
+
+
+
+// ========================= AP RTMP.h ================================
+
+
+
+// =============================================================
+// Function Prototypes
+// =============================================================
+
+// ap_data.c
+
+BOOLEAN APBridgeToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN ULONG fromwdsidx);
+
+BOOLEAN APHandleRxDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APSendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET ppPacketArray,
+ IN UINT NumberOfPackets);
+
+NDIS_STATUS APSendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+NDIS_STATUS APHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx);
+
+VOID APRxEAPOLFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+NDIS_STATUS APCheckRxError(
+ IN PRTMP_ADAPTER pAd,
+ IN PRT28XX_RXD_STRUC pRxD,
+ IN UCHAR Wcid);
+
+BOOLEAN APCheckClass2Class3Error(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader);
+
+VOID APHandleRxPsPoll(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN USHORT Aid,
+ IN BOOLEAN isActive);
+
+VOID RTMPDescriptorEndianChange(
+ IN PUCHAR pData,
+ IN ULONG DescriptorType);
+
+VOID RTMPFrameEndianChange(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG Dir,
+ IN BOOLEAN FromRxDoneInt);
+
+// ap_assoc.c
+
+VOID APAssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APPeerAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerReassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MbssKickOutStas(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN USHORT Reason);
+
+VOID APMlmeKickOutSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pStaAddr,
+ IN UCHAR Wcid,
+ IN USHORT Reason);
+
+VOID APMlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APCls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader);
+
+
+USHORT APBuildAssociation(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN USHORT CapabilityInfo,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN UCHAR *RSN,
+ IN UCHAR *pRSNLen,
+ IN BOOLEAN bWmmCapable,
+ IN ULONG RalinkIe,
+#ifdef DOT11N_DRAFT3
+ IN EXT_CAP_INFO_ELEMENT ExtCapInfo,
+#endif // DOT11N_DRAFT3 //
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ OUT USHORT *pAid);
+
+/*
+VOID RTMPAddClientSec(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN PUCHAR pKey,
+ IN PUCHAR pTxMic,
+ IN PUCHAR pRxMic,
+ IN MAC_TABLE_ENTRY *pEntry);
+*/
+
+// ap_auth.c
+
+void APAuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APMlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APCls2errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN PHEADER_802_11 pHeader);
+
+// ap_authrsp.c
+
+VOID APAuthRspStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE Sm,
+ IN STATE_MACHINE_FUNC Trans[]);
+
+VOID APPeerAuthAtAuthRspIdleAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr80211,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT StatusCode);
+
+// ap_connect.c
+
+BOOLEAN BeaconTransmitRequired(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx);
+
+VOID APMakeBssBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx);
+
+VOID APUpdateBeaconFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx);
+
+VOID APMakeAllBssBeacon(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APUpdateAllBeaconFrame(
+ IN PRTMP_ADAPTER pAd);
+
+
+// ap_sync.c
+
+VOID APSyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID APScanTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID APInvalidStateWhenScan(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APScanTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerBeaconAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APMlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APPeerBeaconAtScanAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APScanCnclAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ApSiteSurvey(
+ IN PRTMP_ADAPTER pAd);
+
+VOID SupportRate(
+ IN PUCHAR SupRate,
+ IN UCHAR SupRateLen,
+ IN PUCHAR ExtRate,
+ IN UCHAR ExtRateLen,
+ OUT PUCHAR *Rates,
+ OUT PUCHAR RatesLen,
+ OUT PUCHAR pMaxSupportRate);
+
+
+BOOLEAN ApScanRunning(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef DOT11N_DRAFT3
+VOID APOverlappingBSSScan(
+ IN RTMP_ADAPTER *pAd);
+#endif // DOT11N_DRAFT3 //
+
+// ap_wpa.c
+
+VOID APWpaStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+// ap_mlme.c
+
+VOID APMlmePeriodicExec(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APMlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR *ppTable,
+ IN PUCHAR pTableSize,
+ IN PUCHAR pInitTxRateIdx);
+
+VOID APMlmeSetTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PRTMP_TX_RATE_SWITCH pTxRate);
+
+VOID APMlmeDynamicTxRateSwitching(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN APMsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType);
+
+VOID APQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+#ifdef RT2870
+VOID BeaconUpdateExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif // RT2870 //
+
+VOID RTMPSetPiggyBack(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bPiggyBack);
+
+VOID APAsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APAsicRxAntEvalTimeout(
+ IN PRTMP_ADAPTER pAd);
+
+// ap.c
+
+VOID APSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN INT Channel);
+
+NDIS_STATUS APInitialize(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APShutdown(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APStartUp(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID APCleanupPsQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_HEADER pQueue);
+
+VOID MacTableReset(
+ IN PRTMP_ADAPTER pAd);
+
+MAC_TABLE_ENTRY *MacTableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR apidx,
+ IN BOOLEAN CleanAll);
+
+BOOLEAN MacTableDeleteEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr);
+
+MAC_TABLE_ENTRY *MacTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+VOID MacTableMaintenance(
+ IN PRTMP_ADAPTER pAd);
+
+UINT32 MacTableAssocStaNumGet(
+ IN PRTMP_ADAPTER pAd);
+
+MAC_TABLE_ENTRY *APSsPsInquiry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ OUT SST *Sst,
+ OUT USHORT *Aid,
+ OUT UCHAR *PsMode,
+ OUT UCHAR *Rate);
+
+BOOLEAN APPsIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN ULONG Wcid,
+ IN UCHAR Psm);
+
+VOID ApLogEvent(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN USHORT Event);
+
+#ifdef DOT11_N_SUPPORT
+VOID APUpdateOperationMode(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+
+VOID APUpdateCapabilityAndErpIe(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ApCheckAccessControlList(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR Apidx);
+
+VOID ApUpdateAccessControlList(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Apidx);
+
+VOID ApEnqueueNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR TxRate,
+ IN UCHAR PID,
+ IN UCHAR apidx,
+ IN BOOLEAN bQosNull,
+ IN BOOLEAN bEOSP,
+ IN UCHAR OldUP);
+
+VOID ApSendFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuffer,
+ IN ULONG Length,
+ IN UCHAR TxRate,
+ IN UCHAR PID);
+
+VOID ApEnqueueAckFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR TxRate,
+ IN UCHAR apidx);
+
+UCHAR APAutoSelectChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN Optimal);
+
+// ap_sanity.c
+
+
+BOOLEAN PeerAssocReqCmmSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN isRessoc,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pListenInterval,
+ OUT PUCHAR pApAddr,
+ OUT UCHAR *pSsidLen,
+ OUT char *Ssid,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *RSN,
+ OUT UCHAR *pRSNLen,
+ OUT BOOLEAN *pbWmmCapable,
+ OUT ULONG *pRalinkIe,
+#ifdef DOT11N_DRAFT3
+ OUT EXT_CAP_INFO_ELEMENT *pExtCapInfo,
+#endif // DOT11N_DRAFT3 //
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability);
+
+
+BOOLEAN PeerDisassocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerDeauthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN APPeerAuthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr1,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Alg,
+ OUT USHORT *Seq,
+ OUT USHORT *Status,
+ CHAR *ChlgText);
+
+BOOLEAN APPeerProbeReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT CHAR Ssid[],
+ OUT UCHAR *SsidLen);
+
+BOOLEAN APPeerBeaconAndProbeRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT PUCHAR pBssid,
+ OUT CHAR Ssid[],
+ OUT UCHAR *SsidLen,
+ OUT UCHAR *BssType,
+ OUT USHORT *BeaconPeriod,
+ OUT UCHAR *Channel,
+ OUT LARGE_INTEGER *Timestamp,
+ OUT USHORT *CapabilityInfo,
+ OUT UCHAR Rate[],
+ OUT UCHAR *RateLen,
+ OUT BOOLEAN *ExtendedRateIeExist,
+ OUT UCHAR *Erp);
+
+
+// ================== end of AP RTMP.h ========================
+
+
+#endif // __AP_H__
+
diff --git a/drivers/staging/rt3070/chlist.h b/drivers/staging/rt3070/chlist.h
new file mode 100644
index 00000000000..7151e8668cb
--- /dev/null
+++ b/drivers/staging/rt3070/chlist.h
@@ -0,0 +1,1253 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ chlist.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi Wu 2007-12-19 created
+*/
+
+#ifndef __CHLIST_H__
+#define __CHLIST_H__
+
+#include "rtmp_type.h"
+#include "rtmp_def.h"
+
+
+#define ODOR 0
+#define IDOR 1
+#define BOTH 2
+
+#define BAND_5G 0
+#define BAND_24G 1
+#define BAND_BOTH 2
+
+typedef struct _CH_DESP {
+ UCHAR FirstChannel;
+ UCHAR NumOfCh;
+ CHAR MaxTxPwr; // dBm
+ UCHAR Geography; // 0:out door, 1:in door, 2:both
+ BOOLEAN DfsReq; // Dfs require, 0: No, 1: yes.
+} CH_DESP, *PCH_DESP;
+
+typedef struct _CH_REGION {
+ UCHAR CountReg[3];
+ UCHAR DfsType; // 0: CE, 1: FCC, 2: JAP, 3:JAP_W53, JAP_W56
+ CH_DESP ChDesp[10];
+} CH_REGION, *PCH_REGION;
+
+static CH_REGION ChRegion[] =
+{
+ { // Antigua and Berbuda
+ "AG",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Argentina
+ "AR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Aruba
+ "AW",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Australia
+ "AU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Austria
+ "AT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Bahamas
+ "BS",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Barbados
+ "BB",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Bermuda
+ "BM",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Brazil
+ "BR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 24, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Belgium
+ "BE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 18, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 18, IDOR, FALSE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Bulgaria
+ "BG",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Canada
+ "CA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Cayman IsLands
+ "KY",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Chile
+ "CL",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // China
+ "CN",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Colombia
+ "CO",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Costa Rica
+ "CR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Cyprus
+ "CY",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Czech_Republic
+ "CZ",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Denmark
+ "DK",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Dominican Republic
+ "DO",
+ CE,
+ {
+ { 1, 0, 20, BOTH, FALSE}, // 2.4 G, ch 0
+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Equador
+ "EC",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 100, 11, 27, BOTH, FALSE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // El Salvador
+ "SV",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 30, BOTH, TRUE}, // 5G, ch 52~64
+ { 149, 4, 36, BOTH, TRUE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Finland
+ "FI",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // France
+ "FR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Germany
+ "DE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Greece
+ "GR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Guam
+ "GU",
+ CE,
+ {
+ { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Guatemala
+ "GT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Haiti
+ "HT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Honduras
+ "HN",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Hong Kong
+ "HK",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Hungary
+ "HU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Iceland
+ "IS",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // India
+ "IN",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 24, IDOR, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Indonesia
+ "ID",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Ireland
+ "IE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Israel
+ "IL",
+ CE,
+ {
+ { 1, 3, 20, IDOR, FALSE}, // 2.4 G, ch 1~3
+ { 4, 6, 20, BOTH, FALSE}, // 2.4 G, ch 4~9
+ { 10, 4, 20, IDOR, FALSE}, // 2.4 G, ch 10~13
+ { 0}, // end
+ }
+ },
+
+ { // Italy
+ "IT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, ODOR, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Japan
+ "JP",
+ JAP,
+ {
+ { 1, 14, 20, BOTH, FALSE}, // 2.4 G, ch 1~14
+ { 34, 4, 23, IDOR, FALSE}, // 5G, ch 34~46
+ { 0}, // end
+ }
+ },
+
+ { // Jordan
+ "JO",
+ CE,
+ {
+ { 1, 13, 20, IDOR, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 149, 4, 23, IDOR, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Latvia
+ "LV",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Liechtenstein
+ "LI",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Lithuania
+ "LT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Luxemburg
+ "LU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Malaysia
+ "MY",
+ CE,
+ {
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Malta
+ "MT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Marocco
+ "MA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
+ { 0}, // end
+ }
+ },
+
+ { // Mexico
+ "MX",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 5, 30, IDOR, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Netherlands
+ "NL",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // New Zealand
+ "NZ",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 24, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Norway
+ "NO",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 24, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 24, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Peru
+ "PE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Portugal
+ "PT",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Poland
+ "PL",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Romania
+ "RO",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Russia
+ "RU",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 149, 4, 20, IDOR, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Saudi Arabia
+ "SA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 23, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Serbia_and_Montenegro
+ "CS",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 0}, // end
+ }
+ },
+
+ { // Singapore
+ "SG",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Slovakia
+ "SK",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Slovenia
+ "SI",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // South Africa
+ "ZA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 149, 4, 30, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // South Korea
+ "KR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 8, 20, BOTH, FALSE}, // 5G, ch 100~128
+ { 149, 4, 20, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Spain
+ "ES",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 17, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Sweden
+ "SE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Switzerland
+ "CH",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~13
+ { 36, 4, 23, IDOR, TRUE}, // 5G, ch 36~48
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Taiwan
+ "TW",
+ CE,
+ {
+ { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 52, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // Turkey
+ "TR",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 23, BOTH, FALSE}, // 5G, ch 36~48
+ { 52, 4, 23, BOTH, FALSE}, // 5G, ch 52~64
+ { 0}, // end
+ }
+ },
+
+ { // UK
+ "GB",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 23, IDOR, FALSE}, // 5G, ch 52~64
+ { 52, 4, 23, IDOR, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 0}, // end
+ }
+ },
+
+ { // Ukraine
+ "UA",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 0}, // end
+ }
+ },
+
+ { // United_Arab_Emirates
+ "AE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 0}, // end
+ }
+ },
+
+ { // United_States
+ "US",
+ CE,
+ {
+ { 1, 11, 30, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 17, IDOR, FALSE}, // 5G, ch 52~64
+ { 52, 4, 24, BOTH, TRUE}, // 5G, ch 52~64
+ { 100, 11, 30, BOTH, TRUE}, // 5G, ch 100~140
+ { 149, 5, 30, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+
+ { // Venezuela
+ "VE",
+ CE,
+ {
+ { 1, 13, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 149, 4, 27, BOTH, FALSE}, // 5G, ch 149~161
+ { 0}, // end
+ }
+ },
+
+ { // Default
+ "",
+ CE,
+ {
+ { 1, 11, 20, BOTH, FALSE}, // 2.4 G, ch 1~11
+ { 36, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 52, 4, 20, BOTH, FALSE}, // 5G, ch 52~64
+ { 100, 11, 20, BOTH, FALSE}, // 5G, ch 100~140
+ { 149, 5, 20, BOTH, FALSE}, // 5G, ch 149~165
+ { 0}, // end
+ }
+ },
+};
+
+static inline PCH_REGION GetChRegion(
+ IN PUCHAR CntryCode)
+{
+ INT loop = 0;
+ PCH_REGION pChRegion = NULL;
+
+ while (strcmp(ChRegion[loop].CountReg, "") != 0)
+ {
+ if (strncmp(ChRegion[loop].CountReg, CntryCode, 2) == 0)
+ {
+ pChRegion = &ChRegion[loop];
+ break;
+ }
+ loop++;
+ }
+
+ if (pChRegion == NULL)
+ pChRegion = &ChRegion[loop];
+ return pChRegion;
+}
+
+static inline VOID ChBandCheck(
+ IN UCHAR PhyMode,
+ OUT PUCHAR pChType)
+{
+ switch(PhyMode)
+ {
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ *pChType = BAND_5G;
+ break;
+ case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AGN_MIXED:
+ case PHY_11ABGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ *pChType = BAND_BOTH;
+ break;
+
+ default:
+ *pChType = BAND_24G;
+ break;
+ }
+}
+
+static inline UCHAR FillChList(
+ IN PRTMP_ADAPTER pAd,
+ IN PCH_DESP pChDesp,
+ IN UCHAR Offset,
+ IN UCHAR increment)
+{
+ INT i, j, l;
+ UCHAR channel;
+
+ j = Offset;
+ for (i = 0; i < pChDesp->NumOfCh; i++)
+ {
+ channel = pChDesp->FirstChannel + i * increment;
+ for (l=0; l<MAX_NUM_OF_CHANNELS; l++)
+ {
+ if (channel == pAd->TxPower[l].Channel)
+ {
+ pAd->ChannelList[j].Power = pAd->TxPower[l].Power;
+ pAd->ChannelList[j].Power2 = pAd->TxPower[l].Power2;
+ break;
+ }
+ }
+ if (l == MAX_NUM_OF_CHANNELS)
+ continue;
+
+ pAd->ChannelList[j].Channel = pChDesp->FirstChannel + i * increment;
+ pAd->ChannelList[j].MaxTxPwr = pChDesp->MaxTxPwr;
+ pAd->ChannelList[j].DfsReq = pChDesp->DfsReq;
+ j++;
+ }
+ pAd->ChannelListNum = j;
+
+ return j;
+}
+
+static inline VOID CreateChList(
+ IN PRTMP_ADAPTER pAd,
+ IN PCH_REGION pChRegion,
+ IN UCHAR Geography)
+{
+ INT i;
+ UCHAR offset = 0;
+ PCH_DESP pChDesp;
+ UCHAR ChType;
+ UCHAR increment;
+
+ if (pChRegion == NULL)
+ return;
+
+ ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+
+ for (i=0; i<10; i++)
+ {
+ pChDesp = &pChRegion->ChDesp[i];
+ if (pChDesp->FirstChannel == 0)
+ break;
+
+ if (ChType == BAND_5G)
+ {
+ if (pChDesp->FirstChannel <= 14)
+ continue;
+ }
+ else if (ChType == BAND_24G)
+ {
+ if (pChDesp->FirstChannel > 14)
+ continue;
+ }
+
+ if ((pChDesp->Geography == BOTH)
+ || (pChDesp->Geography == Geography))
+ {
+ if (pChDesp->FirstChannel > 14)
+ increment = 4;
+ else
+ increment = 1;
+ offset = FillChList(pAd, pChDesp, offset, increment);
+ }
+ }
+}
+
+static inline VOID BuildChannelListEx(
+ IN PRTMP_ADAPTER pAd)
+{
+ PCH_REGION pChReg;
+
+ pChReg = GetChRegion(pAd->CommonCfg.CountryCode);
+ CreateChList(pAd, pChReg, pAd->CommonCfg.Geography);
+}
+
+static inline VOID BuildBeaconChList(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf,
+ OUT PULONG pBufLen)
+{
+ INT i;
+ ULONG TmpLen;
+ PCH_REGION pChRegion;
+ PCH_DESP pChDesp;
+ UCHAR ChType;
+
+ pChRegion = GetChRegion(pAd->CommonCfg.CountryCode);
+
+ if (pChRegion == NULL)
+ return;
+
+ ChBandCheck(pAd->CommonCfg.PhyMode, &ChType);
+ *pBufLen = 0;
+
+ for (i=0; i<10; i++)
+ {
+ pChDesp = &pChRegion->ChDesp[i];
+ if (pChDesp->FirstChannel == 0)
+ break;
+
+ if (ChType == BAND_5G)
+ {
+ if (pChDesp->FirstChannel <= 14)
+ continue;
+ }
+ else if (ChType == BAND_24G)
+ {
+ if (pChDesp->FirstChannel > 14)
+ continue;
+ }
+
+ if ((pChDesp->Geography == BOTH)
+ || (pChDesp->Geography == pAd->CommonCfg.Geography))
+ {
+ MakeOutgoingFrame(pBuf + *pBufLen, &TmpLen,
+ 1, &pChDesp->FirstChannel,
+ 1, &pChDesp->NumOfCh,
+ 1, &pChDesp->MaxTxPwr,
+ END_OF_ARGS);
+ *pBufLen += TmpLen;
+ }
+ }
+}
+
+
+#ifdef DOT11_N_SUPPORT
+static inline BOOLEAN IsValidChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel)
+
+{
+ INT i;
+
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].Channel == channel)
+ break;
+ }
+
+ if (i == pAd->ChannelListNum)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+
+static inline UCHAR GetExtCh(
+ IN UCHAR Channel,
+ IN UCHAR Direction)
+{
+ CHAR ExtCh;
+
+ if (Direction == EXTCHA_ABOVE)
+ ExtCh = Channel + 4;
+ else
+ ExtCh = (Channel - 4) > 0 ? (Channel - 4) : 0;
+
+ return ExtCh;
+}
+
+
+static inline VOID N_ChannelCheck(
+ IN PRTMP_ADAPTER pAd)
+{
+ //UCHAR ChannelNum = pAd->ChannelListNum;
+ UCHAR Channel = pAd->CommonCfg.Channel;
+
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) && (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (Channel > 14)
+ {
+ if ((Channel == 36) || (Channel == 44) || (Channel == 52) || (Channel == 60) || (Channel == 100) || (Channel == 108) ||
+ (Channel == 116) || (Channel == 124) || (Channel == 132) || (Channel == 149) || (Channel == 157))
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+ }
+ else if ((Channel == 40) || (Channel == 48) || (Channel == 56) || (Channel == 64) || (Channel == 104) || (Channel == 112) ||
+ (Channel == 120) || (Channel == 128) || (Channel == 136) || (Channel == 153) || (Channel == 161))
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ }
+ }
+ else
+ {
+ do
+ {
+ UCHAR ExtCh;
+ UCHAR Dir = pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+ ExtCh = GetExtCh(Channel, Dir);
+ if (IsValidChannel(pAd, ExtCh))
+ break;
+
+ Dir = (Dir == EXTCHA_ABOVE) ? EXTCHA_BELOW : EXTCHA_ABOVE;
+ ExtCh = GetExtCh(Channel, Dir);
+ if (IsValidChannel(pAd, ExtCh))
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = Dir;
+ break;
+ }
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ } while(FALSE);
+
+ if (Channel == 14)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ //pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_NONE; // We didn't set the ExtCh as NONE due to it'll set in RTMPSetHT()
+ }
+ }
+ }
+
+
+}
+
+
+static inline VOID N_SetCenCh(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ if (pAd->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel == 14)
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 1;
+ else
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+
+static inline UINT8 GetCuntryMaxTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 channel)
+{
+ int i;
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].Channel == channel)
+ break;
+ }
+
+ if (i == pAd->ChannelListNum)
+ return 0xff;
+ else
+ return pAd->ChannelList[i].MaxTxPwr;
+}
+#endif // __CHLIST_H__
+
diff --git a/drivers/staging/rt3070/common/2870_rtmp_init.c b/drivers/staging/rt3070/common/2870_rtmp_init.c
new file mode 100644
index 00000000000..fdf8dc176a6
--- /dev/null
+++ b/drivers/staging/rt3070/common/2870_rtmp_init.c
@@ -0,0 +1,1762 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ 2870_rtmp_init.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 2002-08-01 created
+ John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
+ Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
+ Sample Lin 2007-05-31 Merge RT2860 and RT2870 drivers.
+*/
+
+#include "../rt_config.h"
+
+
+static void rx_done_tasklet(unsigned long data);
+static void rt2870_hcca_dma_done_tasklet(unsigned long data);
+static void rt2870_ac3_dma_done_tasklet(unsigned long data);
+static void rt2870_ac2_dma_done_tasklet(unsigned long data);
+static void rt2870_ac1_dma_done_tasklet(unsigned long data);
+static void rt2870_ac0_dma_done_tasklet(unsigned long data);
+static void rt2870_mgmt_dma_done_tasklet(unsigned long data);
+static void rt2870_null_frame_complete_tasklet(unsigned long data);
+static void rt2870_rts_frame_complete_tasklet(unsigned long data);
+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data);
+static void rt2870_dataout_complete_tasklet(unsigned long data);
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize receive data structures.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_RESOURCES
+
+Note:
+ Initialize all receive releated private buffer, include those define
+ in RTMP_ADAPTER structure and all private data structures. The mahor
+ work is to allocate buffer for each packet and chain buffer to
+ NDIS packet descriptor.
+========================================================================
+*/
+NDIS_STATUS NICInitRecv(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitRecv\n"));
+ pObj = pObj;
+
+ //InterlockedExchange(&pAd->PendingRx, 0);
+ pAd->PendingRx = 0;
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = 0 ; //RX_RING_SIZE -1; // Rx Bulk pointer
+ pAd->NextRxBulkInPosition = 0;
+
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ //Allocate URB
+ pRxContext->pUrb = RTUSB_ALLOC_URB(0);
+ if (pRxContext->pUrb == NULL)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ goto out1;
+ }
+
+ // Allocate transfer buffer
+ pRxContext->TransferBuffer = RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE, &pRxContext->data_dma);
+ if (pRxContext->TransferBuffer == NULL)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ goto out1;
+ }
+
+ NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+
+ pRxContext->pAd = pAd;
+ pRxContext->pIrp = NULL;
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+ //pRxContext->ReorderInUse = FALSE;
+ pRxContext->bRxHandling = FALSE;
+ pRxContext->BulkInOffset = 0;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitRecv\n"));
+ return Status;
+
+out1:
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ if (NULL != pRxContext->TransferBuffer)
+ {
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, MAX_RXBULK_SIZE,
+ pRxContext->TransferBuffer, pRxContext->data_dma);
+ pRxContext->TransferBuffer = NULL;
+ }
+
+ if (NULL != pRxContext->pUrb)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ RTUSB_FREE_URB(pRxContext->pUrb);
+ pRxContext->pUrb = NULL;
+ }
+ }
+
+ return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Initialize transmit data structures.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS NICInitTransmit(
+ IN PRTMP_ADAPTER pAd)
+{
+#define LM_USB_ALLOC(pObj, Context, TB_Type, BufferSize, Status, msg1, err1, msg2, err2) \
+ Context->pUrb = RTUSB_ALLOC_URB(0); \
+ if (Context->pUrb == NULL) { \
+ DBGPRINT(RT_DEBUG_ERROR, msg1); \
+ Status = NDIS_STATUS_RESOURCES; \
+ goto err1; } \
+ \
+ Context->TransferBuffer = \
+ (TB_Type)RTUSB_URB_ALLOC_BUFFER(pObj->pUsb_Dev, BufferSize, &Context->data_dma); \
+ if (Context->TransferBuffer == NULL) { \
+ DBGPRINT(RT_DEBUG_ERROR, msg2); \
+ Status = NDIS_STATUS_RESOURCES; \
+ goto err2; }
+
+#define LM_URB_FREE(pObj, Context, BufferSize) \
+ if (NULL != Context->pUrb) { \
+ RTUSB_UNLINK_URB(Context->pUrb); \
+ RTUSB_FREE_URB(Context->pUrb); \
+ Context->pUrb = NULL; } \
+ if (NULL != Context->TransferBuffer) { \
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
+ Context->TransferBuffer, \
+ Context->data_dma); \
+ Context->TransferBuffer = NULL; }
+
+ UCHAR i, acidx;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+ PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
+ PTX_CONTEXT pRTSContext = &(pAd->RTSContext);
+ PTX_CONTEXT pMLMEContext = NULL;
+// PHT_TX_CONTEXT pHTTXContext = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ PVOID RingBaseVa;
+// RTMP_TX_RING *pTxRing;
+ RTMP_MGMT_RING *pMgmtRing;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitTransmit\n"));
+ pObj = pObj;
+
+ // Init 4 set of Tx parameters
+ for(acidx = 0; acidx < NUM_OF_TX_RING; acidx++)
+ {
+ // Initialize all Transmit releated queues
+ InitializeQueueHeader(&pAd->TxSwQueue[acidx]);
+
+ // Next Local tx ring pointer waiting for buck out
+ pAd->NextBulkOutIndex[acidx] = acidx;
+ pAd->BulkOutPending[acidx] = FALSE; // Buck Out control flag
+ //pAd->DataBulkDoneIdx[acidx] = 0;
+ }
+
+ //pAd->NextMLMEIndex = 0;
+ //pAd->PushMgmtIndex = 0;
+ //pAd->PopMgmtIndex = 0;
+ //InterlockedExchange(&pAd->MgmtQueueSize, 0);
+ //InterlockedExchange(&pAd->TxCount, 0);
+
+ //pAd->PrioRingFirstIndex = 0;
+ //pAd->PrioRingTxCnt = 0;
+
+ do
+ {
+ //
+ // TX_RING_SIZE, 4 ACs
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+ {
+#if 1 //def DOT11_N_SUPPORT
+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+
+ NdisZeroMemory(pHTTXContext, sizeof(HT_TX_CONTEXT));
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pHTTXContext, PHTTX_BUFFER, sizeof(HTTX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX TxContext[%d] urb!! \n", acidx),
+ done,
+ ("<-- ERROR in Alloc TX TxContext[%d] HTTX_BUFFER !! \n", acidx),
+ out1);
+
+ NdisZeroMemory(pHTTXContext->TransferBuffer->Aggregation, 4);
+ pHTTXContext->pAd = pAd;
+ pHTTXContext->pIrp = NULL;
+ pHTTXContext->IRPPending = FALSE;
+ pHTTXContext->NextBulkOutPosition = 0;
+ pHTTXContext->ENextBulkOutPosition = 0;
+ pHTTXContext->CurWritePosition = 0;
+ pHTTXContext->CurWriteRealPos = 0;
+ pHTTXContext->BulkOutSize = 0;
+ pHTTXContext->BulkOutPipeId = acidx;
+ pHTTXContext->bRingEmpty = TRUE;
+ pHTTXContext->bCopySavePad = FALSE;
+#endif // DOT11_N_SUPPORT //
+ pAd->BulkOutPending[acidx] = FALSE;
+ }
+
+
+ //
+ // MGMT_RING_SIZE
+ //
+ // Allocate MGMT ring descriptor's memory
+ pAd->MgmtDescRing.AllocSize = MGMT_RING_SIZE * sizeof(TX_CONTEXT);
+ RTMPAllocateMemory(&pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+ if (pAd->MgmtDescRing.AllocVa == NULL)
+ {
+ DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n"));
+ Status = NDIS_STATUS_RESOURCES;
+ goto out1;
+ }
+ NdisZeroMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize);
+ RingBaseVa = pAd->MgmtDescRing.AllocVa;
+
+ // Initialize MGMT Ring and associated buffer memory
+ pMgmtRing = &pAd->MgmtRing;
+ for (i = 0; i < MGMT_RING_SIZE; i++)
+ {
+ // link the pre-allocated Mgmt buffer to MgmtRing.Cell
+ pMgmtRing->Cell[i].AllocSize = sizeof(TX_CONTEXT);
+ pMgmtRing->Cell[i].AllocVa = RingBaseVa;
+ pMgmtRing->Cell[i].pNdisPacket = NULL;
+ pMgmtRing->Cell[i].pNextNdisPacket = NULL;
+
+ //Allocate URB for MLMEContext
+ pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+ pMLMEContext->pUrb = RTUSB_ALLOC_URB(0);
+ if (pMLMEContext->pUrb == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("<-- ERROR in Alloc TX MLMEContext[%d] urb!! \n", i));
+ Status = NDIS_STATUS_RESOURCES;
+ goto out2;
+ }
+ pMLMEContext->pAd = pAd;
+ pMLMEContext->pIrp = NULL;
+ pMLMEContext->TransferBuffer = NULL;
+ pMLMEContext->InUse = FALSE;
+ pMLMEContext->IRPPending = FALSE;
+ pMLMEContext->bWaitingBulkOut = FALSE;
+ pMLMEContext->BulkOutSize = 0;
+ pMLMEContext->SelfIdx = i;
+
+ // Offset to next ring descriptor address
+ RingBaseVa = (PUCHAR) RingBaseVa + sizeof(TX_CONTEXT);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("MGMT Ring: total %d entry allocated\n", i));
+
+ //pAd->MgmtRing.TxSwFreeIdx = (MGMT_RING_SIZE - 1);
+ pAd->MgmtRing.TxSwFreeIdx = MGMT_RING_SIZE;
+ pAd->MgmtRing.TxCpuIdx = 0;
+ pAd->MgmtRing.TxDmaIdx = 0;
+
+ //
+ // BEACON_RING_SIZE
+ //
+ for(i=0; i<BEACON_RING_SIZE; i++) // 2
+ {
+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
+
+
+ NdisZeroMemory(pBeaconContext, sizeof(TX_CONTEXT));
+
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pBeaconContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX BeaconContext[%d] urb!! \n", i),
+ out2,
+ ("<-- ERROR in Alloc TX BeaconContext[%d] TX_BUFFER !! \n", i),
+ out3);
+
+ pBeaconContext->pAd = pAd;
+ pBeaconContext->pIrp = NULL;
+ pBeaconContext->InUse = FALSE;
+ pBeaconContext->IRPPending = FALSE;
+ }
+
+ //
+ // NullContext
+ //
+ NdisZeroMemory(pNullContext, sizeof(TX_CONTEXT));
+
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pNullContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX NullContext urb!! \n"),
+ out3,
+ ("<-- ERROR in Alloc TX NullContext TX_BUFFER !! \n"),
+ out4);
+
+ pNullContext->pAd = pAd;
+ pNullContext->pIrp = NULL;
+ pNullContext->InUse = FALSE;
+ pNullContext->IRPPending = FALSE;
+
+ //
+ // RTSContext
+ //
+ NdisZeroMemory(pRTSContext, sizeof(TX_CONTEXT));
+
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pRTSContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX RTSContext urb!! \n"),
+ out4,
+ ("<-- ERROR in Alloc TX RTSContext TX_BUFFER !! \n"),
+ out5);
+
+ pRTSContext->pAd = pAd;
+ pRTSContext->pIrp = NULL;
+ pRTSContext->InUse = FALSE;
+ pRTSContext->IRPPending = FALSE;
+
+ //
+ // PsPollContext
+ //
+ //NdisZeroMemory(pPsPollContext, sizeof(TX_CONTEXT));
+ //Allocate URB
+ LM_USB_ALLOC(pObj, pPsPollContext, PTX_BUFFER, sizeof(TX_BUFFER), Status,
+ ("<-- ERROR in Alloc TX PsPollContext urb!! \n"),
+ out5,
+ ("<-- ERROR in Alloc TX PsPollContext TX_BUFFER !! \n"),
+ out6);
+
+ pPsPollContext->pAd = pAd;
+ pPsPollContext->pIrp = NULL;
+ pPsPollContext->InUse = FALSE;
+ pPsPollContext->IRPPending = FALSE;
+ pPsPollContext->bAggregatible = FALSE;
+ pPsPollContext->LastOne = TRUE;
+
+ } while (FALSE);
+
+
+done:
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitTransmit\n"));
+
+ return Status;
+
+ /* --------------------------- ERROR HANDLE --------------------------- */
+out6:
+ LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+out5:
+ LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+out4:
+ LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+out3:
+ for(i=0; i<BEACON_RING_SIZE; i++)
+ {
+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
+ if (pBeaconContext)
+ LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+ }
+
+out2:
+ if (pAd->MgmtDescRing.AllocVa)
+ {
+ pMgmtRing = &pAd->MgmtRing;
+ for(i=0; i<MGMT_RING_SIZE; i++)
+ {
+ pMLMEContext = (PTX_CONTEXT) pAd->MgmtRing.Cell[i].AllocVa;
+ if (pMLMEContext)
+ LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+ }
+ NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
+ pAd->MgmtDescRing.AllocVa = NULL;
+ }
+
+out1:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+ {
+ PHT_TX_CONTEXT pTxContext = &(pAd->TxContext[acidx]);
+ if (pTxContext)
+ LM_URB_FREE(pObj, pTxContext, sizeof(HTTX_BUFFER));
+ }
+
+ // Here we didn't have any pre-allocated memory need to free.
+
+ return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Allocate DMA memory blocks for send, receive.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS RTMPAllocTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd)
+{
+// COUNTER_802_11 pCounter = &pAd->WlanCounters;
+ NDIS_STATUS Status;
+ INT num;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocTxRxRingMemory\n"));
+
+
+ do
+ {
+ // Init the CmdQ and CmdQLock
+ NdisAllocateSpinLock(&pAd->CmdQLock);
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ RTUSBInitializeCmdQ(&pAd->CmdQ);
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+
+ NdisAllocateSpinLock(&pAd->MLMEBulkOutLock);
+ //NdisAllocateSpinLock(&pAd->MLMEWaitQueueLock);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[0]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[1]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[2]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[3]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[4]);
+ NdisAllocateSpinLock(&pAd->BulkOutLock[5]);
+ NdisAllocateSpinLock(&pAd->BulkInLock);
+
+ for (num = 0; num < NUM_OF_TX_RING; num++)
+ {
+ NdisAllocateSpinLock(&pAd->TxContextQueueLock[num]);
+ }
+
+#ifdef RALINK_ATE
+ NdisAllocateSpinLock(&pAd->GenericLock);
+#endif // RALINK_ATE //
+
+// NdisAllocateSpinLock(&pAd->MemLock); // Not used in RT28XX
+
+// NdisAllocateSpinLock(&pAd->MacTabLock); // init it in UserCfgInit()
+// NdisAllocateSpinLock(&pAd->BATabLock); // init it in BATableInit()
+
+// for(num=0; num<MAX_LEN_OF_BA_REC_TABLE; num++)
+// {
+// NdisAllocateSpinLock(&pAd->BATable.BARecEntry[num].RxReRingLock);
+// }
+
+ //
+ // Init Mac Table
+ //
+// MacTableInitialize(pAd);
+
+ //
+ // Init send data structures and related parameters
+ //
+ Status = NICInitTransmit(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ //
+ // Init receive data structures and related parameters
+ //
+ Status = NICInitRecv(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ pAd->PendingIoCount = 1;
+
+ } while (FALSE);
+
+ NdisZeroMemory(&pAd->FragFrame, sizeof(FRAGMENT_FRAME));
+ pAd->FragFrame.pFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+
+ if (pAd->FragFrame.pFragPacket == NULL)
+ {
+ Status = NDIS_STATUS_RESOURCES;
+ }
+
+ DBGPRINT_S(Status, ("<-- RTMPAllocTxRxRingMemory, Status=%x\n", Status));
+ return Status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Calls USB_InterfaceStop and frees memory allocated for the URBs
+ calls NdisMDeregisterDevice and frees the memory
+ allocated in VNetInitialize for the Adapter Object
+
+Arguments:
+ *pAd the raxx interface data pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+VOID RTMPFreeTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd)
+{
+#define LM_URB_FREE(pObj, Context, BufferSize) \
+ if (NULL != Context->pUrb) { \
+ RTUSB_UNLINK_URB(Context->pUrb); \
+ RTUSB_FREE_URB(Context->pUrb); \
+ Context->pUrb = NULL; } \
+ if (NULL != Context->TransferBuffer) { \
+ RTUSB_URB_FREE_BUFFER(pObj->pUsb_Dev, BufferSize, \
+ Context->TransferBuffer, \
+ Context->data_dma); \
+ Context->TransferBuffer = NULL; }
+
+
+ UINT i, acidx;
+ PTX_CONTEXT pNullContext = &pAd->NullContext;
+ PTX_CONTEXT pPsPollContext = &pAd->PsPollContext;
+ PTX_CONTEXT pRTSContext = &pAd->RTSContext;
+// PHT_TX_CONTEXT pHTTXContext;
+ //PRTMP_REORDERBUF pReorderBuf;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+// RTMP_TX_RING *pTxRing;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("---> RTMPFreeTxRxRingMemory\n"));
+ pObj = pObj;
+
+ // Free all resources for the RECEIVE buffer queue.
+ for(i=0; i<(RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+ if (pRxContext)
+ LM_URB_FREE(pObj, pRxContext, MAX_RXBULK_SIZE);
+ }
+
+ // Free PsPoll frame resource
+ LM_URB_FREE(pObj, pPsPollContext, sizeof(TX_BUFFER));
+
+ // Free NULL frame resource
+ LM_URB_FREE(pObj, pNullContext, sizeof(TX_BUFFER));
+
+ // Free RTS frame resource
+ LM_URB_FREE(pObj, pRTSContext, sizeof(TX_BUFFER));
+
+
+ // Free beacon frame resource
+ for(i=0; i<BEACON_RING_SIZE; i++)
+ {
+ PTX_CONTEXT pBeaconContext = &(pAd->BeaconContext[i]);
+ if (pBeaconContext)
+ LM_URB_FREE(pObj, pBeaconContext, sizeof(TX_BUFFER));
+ }
+
+
+ // Free mgmt frame resource
+ for(i = 0; i < MGMT_RING_SIZE; i++)
+ {
+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+ //LM_URB_FREE(pObj, pMLMEContext, sizeof(TX_BUFFER));
+ if (NULL != pAd->MgmtRing.Cell[i].pNdisPacket)
+ {
+ RTMPFreeNdisPacket(pAd, pAd->MgmtRing.Cell[i].pNdisPacket);
+ pAd->MgmtRing.Cell[i].pNdisPacket = NULL;
+ pMLMEContext->TransferBuffer = NULL;
+ }
+
+ if (pMLMEContext)
+ {
+ if (NULL != pMLMEContext->pUrb)
+ {
+ RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+ RTUSB_FREE_URB(pMLMEContext->pUrb);
+ pMLMEContext->pUrb = NULL;
+ }
+ }
+ }
+ if (pAd->MgmtDescRing.AllocVa)
+ NdisFreeMemory(pAd->MgmtDescRing.AllocVa, pAd->MgmtDescRing.AllocSize, 0);
+
+
+ // Free Tx frame resource
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ for(acidx=0; acidx<4; acidx++)
+#endif // CONFIG_STA_SUPPORT //
+ {
+ PHT_TX_CONTEXT pHTTXContext = &(pAd->TxContext[acidx]);
+ if (pHTTXContext)
+ LM_URB_FREE(pObj, pHTTXContext, sizeof(HTTX_BUFFER));
+ }
+
+ if (pAd->FragFrame.pFragPacket)
+ RELEASE_NDIS_PACKET(pAd, pAd->FragFrame.pFragPacket, NDIS_STATUS_SUCCESS);
+
+ for(i=0; i<6; i++)
+ {
+ NdisFreeSpinLock(&pAd->BulkOutLock[i]);
+ }
+
+ NdisFreeSpinLock(&pAd->BulkInLock);
+ NdisFreeSpinLock(&pAd->MLMEBulkOutLock);
+
+ NdisFreeSpinLock(&pAd->CmdQLock);
+#ifdef RALINK_ATE
+ NdisFreeSpinLock(&pAd->GenericLock);
+#endif // RALINK_ATE //
+ // Clear all pending bulk-out request flags.
+ RTUSB_CLEAR_BULK_FLAG(pAd, 0xffffffff);
+
+// NdisFreeSpinLock(&pAd->MacTabLock);
+
+// for(i=0; i<MAX_LEN_OF_BA_REC_TABLE; i++)
+// {
+// NdisFreeSpinLock(&pAd->BATable.BARecEntry[i].RxReRingLock);
+// }
+
+ DBGPRINT(RT_DEBUG_ERROR, ("<--- ReleaseAdapter\n"));
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Allocate memory for adapter control block.
+
+Arguments:
+ pAd Pointer to our adapter
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_RESOURCES
+
+Note:
+========================================================================
+*/
+NDIS_STATUS AdapterBlockAllocateMemory(
+ IN PVOID handle,
+ OUT PVOID *ppAd)
+{
+ PUSB_DEV usb_dev;
+ POS_COOKIE pObj = (POS_COOKIE) handle;
+
+
+ usb_dev = pObj->pUsb_Dev;
+
+ pObj->MLMEThr_pid = NULL;
+ pObj->RTUSBCmdThr_pid = NULL;
+
+ *ppAd = (PVOID)vmalloc(sizeof(RTMP_ADAPTER));
+
+ if (*ppAd)
+ {
+ NdisZeroMemory(*ppAd, sizeof(RTMP_ADAPTER));
+ ((PRTMP_ADAPTER)*ppAd)->OS_Cookie = handle;
+ return (NDIS_STATUS_SUCCESS);
+ }
+ else
+ {
+ return (NDIS_STATUS_FAILURE);
+ }
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Create kernel threads & tasklets.
+
+Arguments:
+ *net_dev Pointer to wireless net device interface
+
+Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+
+Note:
+========================================================================
+*/
+NDIS_STATUS CreateThreads(
+ IN struct net_device *net_dev)
+{
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ pid_t pid_number;
+
+ //init_MUTEX(&(pAd->usbdev_semaphore));
+
+ init_MUTEX_LOCKED(&(pAd->mlme_semaphore));
+ init_completion (&pAd->mlmeComplete);
+
+ init_MUTEX_LOCKED(&(pAd->RTUSBCmd_semaphore));
+ init_completion (&pAd->CmdQComplete);
+
+ init_MUTEX_LOCKED(&(pAd->RTUSBTimer_semaphore));
+ init_completion (&pAd->TimerQComplete);
+
+ // Creat MLME Thread
+ pObj->MLMEThr_pid = NULL;
+ pid_number = kernel_thread(MlmeThread, pAd, CLONE_VM);
+ if (pid_number < 0)
+ {
+ printk (KERN_WARNING "%s: unable to start Mlme thread\n",pAd->net_dev->name);
+ return NDIS_STATUS_FAILURE;
+ }
+ pObj->MLMEThr_pid = find_get_pid(pid_number);
+ // Wait for the thread to start
+ wait_for_completion(&(pAd->mlmeComplete));
+
+ // Creat Command Thread
+ pObj->RTUSBCmdThr_pid = NULL;
+ pid_number = kernel_thread(RTUSBCmdThread, pAd, CLONE_VM);
+ if (pid_number < 0)
+ {
+ printk (KERN_WARNING "%s: unable to start RTUSBCmd thread\n",pAd->net_dev->name);
+ return NDIS_STATUS_FAILURE;
+ }
+ pObj->RTUSBCmdThr_pid = find_get_pid(pid_number);
+ wait_for_completion(&(pAd->CmdQComplete));
+
+ pObj->TimerQThr_pid = NULL;
+ pid_number = kernel_thread(TimerQThread, pAd, CLONE_VM);
+ if (pid_number < 0)
+ {
+ printk (KERN_WARNING "%s: unable to start TimerQThread\n",pAd->net_dev->name);
+ return NDIS_STATUS_FAILURE;
+ }
+ pObj->TimerQThr_pid = find_get_pid(pid_number);
+ // Wait for the thread to start
+ wait_for_completion(&(pAd->TimerQComplete));
+
+ // Create receive tasklet
+ tasklet_init(&pObj->rx_done_task, rx_done_tasklet, (ULONG)pAd);
+ tasklet_init(&pObj->mgmt_dma_done_task, rt2870_mgmt_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac0_dma_done_task, rt2870_ac0_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac1_dma_done_task, rt2870_ac1_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac2_dma_done_task, rt2870_ac2_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->ac3_dma_done_task, rt2870_ac3_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->hcca_dma_done_task, rt2870_hcca_dma_done_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->tbtt_task, tbtt_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->null_frame_complete_task, rt2870_null_frame_complete_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->rts_frame_complete_task, rt2870_rts_frame_complete_tasklet, (unsigned long)pAd);
+ tasklet_init(&pObj->pspoll_frame_complete_task, rt2870_pspoll_frame_complete_tasklet, (unsigned long)pAd);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+========================================================================
+Routine Description:
+ As STA's BSSID is a WC too, it uses shared key table.
+ This function write correct unicast TX key to ASIC WCID.
+ And we still make a copy in our MacTab.Content[BSSID_WCID].PairwiseKey.
+ Caller guarantee TKIP/AES always has keyidx = 0. (pairwise key)
+ Caller guarantee WEP calls this function when set Txkey, default key index=0~3.
+
+Arguments:
+ pAd Pointer to our adapter
+ pKey Pointer to the where the key stored
+
+Return Value:
+ NDIS_SUCCESS Add key successfully
+
+Note:
+========================================================================
+*/
+VOID RTMPAddBSSIDCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Aid,
+ IN PNDIS_802_11_KEY pKey,
+ IN UCHAR CipherAlg)
+{
+ PUCHAR pTxMic, pRxMic;
+ BOOLEAN bKeyRSC, bAuthenticator; // indicate the receive SC set by KeyRSC value
+// UCHAR CipherAlg;
+ UCHAR i;
+ ULONG WCIDAttri;
+ USHORT offset;
+ UCHAR KeyIdx, IVEIV[8];
+ UINT32 Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddBSSIDCipher==> Aid = %d\n",Aid));
+
+ // Bit 29 of Add-key KeyRSC
+ bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
+
+ // Bit 28 of Add-key Authenticator
+ bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
+ KeyIdx = (UCHAR)pKey->KeyIndex&0xff;
+
+ if (KeyIdx > 4)
+ return;
+
+
+ if (pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg == CIPHER_TKIP)
+ { if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ // for WPA-None Tx, Rx MIC is the same
+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+ pRxMic = pTxMic;
+ }
+ else if (bAuthenticator == TRUE)
+ {
+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+ pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
+ }
+ else
+ {
+ pRxMic = (PUCHAR) (&pKey->KeyMaterial) + 16;
+ pTxMic = (PUCHAR) (&pKey->KeyMaterial) + 24;
+ }
+
+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x10;
+ for (i=0; i<8; )
+ {
+ Value = *(pTxMic+i);
+ Value += (*(pTxMic+i+1)<<8);
+ Value += (*(pTxMic+i+2)<<16);
+ Value += (*(pTxMic+i+3)<<24);
+ RTUSBWriteMACRegister(pAd, offset+i, Value);
+ i+=4;
+ }
+
+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE) + 0x18;
+ for (i=0; i<8; )
+ {
+ Value = *(pRxMic+i);
+ Value += (*(pRxMic+i+1)<<8);
+ Value += (*(pRxMic+i+2)<<16);
+ Value += (*(pRxMic+i+3)<<24);
+ RTUSBWriteMACRegister(pAd, offset+i, Value);
+ i+=4;
+ }
+
+ // Only Key lenth equal to TKIP key have these
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxMic, pRxMic, 8);
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.TxMic, pTxMic, 8);
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ (" TxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],
+ pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ DBGPRINT(RT_DEBUG_TRACE,
+ (" RxMIC = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x \n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],
+ pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+
+ // 2. Record Security Key.
+ pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen= (UCHAR)pKey->KeyLength;
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ // 3. Check RxTsc. And used to init to ASIC IV.
+ if (bKeyRSC == TRUE)
+ NdisMoveMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, &pKey->KeyRSC, 6);
+ else
+ NdisZeroMemory(pAd->MacTab.Content[Aid].PairwiseKey.RxTsc, 6);
+
+ // 4. Init TxTsc to one based on WiFi WPA specs
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[0] = 1;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[1] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[2] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[3] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[4] = 0;
+ pAd->MacTab.Content[Aid].PairwiseKey.TxTsc[5] = 0;
+
+ CipherAlg = pAd->MacTab.Content[Aid].PairwiseKey.CipherAlg;
+
+ offset = PAIRWISE_KEY_TABLE_BASE + (Aid * HW_KEY_ENTRY_SIZE);
+ RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial,
+ ((pKey->KeyLength == LEN_TKIP_KEY) ? 16 : (USHORT)pKey->KeyLength));
+
+ offset = SHARED_KEY_TABLE_BASE + (KeyIdx * HW_KEY_ENTRY_SIZE);
+ RTUSBMultiWrite(pAd, (USHORT) offset, pKey->KeyMaterial, (USHORT)pKey->KeyLength);
+
+ offset = PAIRWISE_IVEIV_TABLE_BASE + (Aid * HW_IVEIV_ENTRY_SIZE);
+ NdisZeroMemory(IVEIV, 8);
+
+ // IV/EIV
+ if ((CipherAlg == CIPHER_TKIP) ||
+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
+ (CipherAlg == CIPHER_AES))
+ {
+ IVEIV[3] = 0x20; // Eiv bit on. keyid always 0 for pairwise key
+ }
+ // default key idx needs to set.
+ // in TKIP/AES KeyIdx = 0 , WEP KeyIdx is default tx key.
+ else
+ {
+ IVEIV[3] |= (KeyIdx<< 6);
+ }
+ RTUSBMultiWrite(pAd, (USHORT) offset, IVEIV, 8);
+
+ // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
+ if ((CipherAlg == CIPHER_TKIP) ||
+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
+ (CipherAlg == CIPHER_AES))
+ {
+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+ }
+ else
+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Aid* HW_WCID_ATTRI_SIZE);
+ RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+ RTUSBReadMACRegister(pAd, offset, &Value);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BSSID_WCID : offset = %x, WCIDAttri = %lx\n",
+ offset, WCIDAttri));
+
+ // pAddr
+ // Add Bssid mac address at linkup. not here. check!
+ /*offset = MAC_WCID_BASE + (BSSID_WCID * HW_WCID_ENTRY_SIZE);
+ *for (i=0; i<MAC_ADDR_LEN; i++)
+ {
+ RTMP_IO_WRITE8(pAd, offset+i, pKey->BSSID[i]);
+ }
+ */
+
+ DBGPRINT(RT_DEBUG_ERROR, ("AddBSSIDasWCIDEntry: Alg=%s, KeyLength = %d\n",
+ CipherName[CipherAlg], pKey->KeyLength));
+ DBGPRINT(RT_DEBUG_TRACE, ("Key [idx=%x] [KeyLen = %d]\n",
+ pKey->KeyIndex, pKey->KeyLength));
+ for(i=0; i<pKey->KeyLength; i++)
+ DBGPRINT_RAW(RT_DEBUG_TRACE,(" %x:", pKey->KeyMaterial[i]));
+ DBGPRINT(RT_DEBUG_TRACE,(" \n"));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+========================================================================
+Routine Description:
+ Get a received packet.
+
+Arguments:
+ pAd device control block
+ pSaveRxD receive descriptor information
+ *pbReschedule need reschedule flag
+ *pRxPending pending received packet flag
+
+Return Value:
+ the recieved packet
+
+Note:
+========================================================================
+*/
+#define RT2870_RXDMALEN_FIELD_SIZE 4
+PNDIS_PACKET GetPacketFromRxRing(
+ IN PRTMP_ADAPTER pAd,
+ OUT PRT28XX_RXD_STRUC pSaveRxD,
+ OUT BOOLEAN *pbReschedule,
+ IN OUT UINT32 *pRxPending)
+{
+ PRX_CONTEXT pRxContext;
+ PNDIS_PACKET pSkb;
+ PUCHAR pData;
+ ULONG ThisFrameLen;
+ ULONG RxBufferLength;
+ PRXWI_STRUC pRxWI;
+
+ pRxContext = &pAd->RxContext[pAd->NextRxBulkInReadIndex];
+ if ((pRxContext->Readable == FALSE) || (pRxContext->InUse == TRUE))
+ return NULL;
+
+ RxBufferLength = pRxContext->BulkInOffset - pAd->ReadPosition;
+ if (RxBufferLength < (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXWI_STRUC) + sizeof(RXINFO_STRUC)))
+ {
+ goto label_null;
+ }
+
+ pData = &pRxContext->TransferBuffer[pAd->ReadPosition]; /* 4KB */
+ // The RXDMA field is 4 bytes, now just use the first 2 bytes. The Length including the (RXWI + MSDU + Padding)
+ ThisFrameLen = *pData + (*(pData+1)<<8);
+ if (ThisFrameLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("BIRIdx(%d): RXDMALen is zero.[%ld], BulkInBufLen = %ld)\n",
+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+ goto label_null;
+ }
+ if ((ThisFrameLen&0x3) != 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("BIRIdx(%d): RXDMALen not multiple of 4.[%ld], BulkInBufLen = %ld)\n",
+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset));
+ goto label_null;
+ }
+
+ if ((ThisFrameLen + 8)> RxBufferLength) // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BIRIdx(%d):FrameLen(0x%lx) outranges. BulkInLen=0x%lx, remaining RxBufLen=0x%lx, ReadPos=0x%lx\n",
+ pAd->NextRxBulkInReadIndex, ThisFrameLen, pRxContext->BulkInOffset, RxBufferLength, pAd->ReadPosition));
+
+ // error frame. finish this loop
+ goto label_null;
+ }
+
+ // skip USB frame length field
+ pData += RT2870_RXDMALEN_FIELD_SIZE;
+ pRxWI = (PRXWI_STRUC)pData;
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pData, TYPE_RXWI);
+#endif // RT_BIG_ENDIAN //
+ if (pRxWI->MPDUtotalByteCount > ThisFrameLen)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s():pRxWIMPDUtotalByteCount(%d) large than RxDMALen(%ld)\n",
+ __FUNCTION__, pRxWI->MPDUtotalByteCount, ThisFrameLen));
+ goto label_null;
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange(pData, TYPE_RXWI);
+#endif // RT_BIG_ENDIAN //
+
+ // allocate a rx packet
+ pSkb = dev_alloc_skb(ThisFrameLen);
+ if (pSkb == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("%s():Cannot Allocate sk buffer for this Bulk-In buffer!\n", __FUNCTION__));
+ goto label_null;
+ }
+
+ // copy the rx packet
+ memcpy(skb_put(pSkb, ThisFrameLen), pData, ThisFrameLen);
+ RTPKT_TO_OSPKT(pSkb)->dev = get_netdev_from_bssid(pAd, BSS0);
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pSkb), PKTSRC_NDIS);
+
+ // copy RxD
+ *pSaveRxD = *(PRXINFO_STRUC)(pData + ThisFrameLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pSaveRxD, TYPE_RXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // update next packet read position.
+ pAd->ReadPosition += (ThisFrameLen + RT2870_RXDMALEN_FIELD_SIZE + RXINFO_SIZE); // 8 for (RT2870_RXDMALEN_FIELD_SIZE + sizeof(RXINFO_STRUC))
+
+ return pSkb;
+
+label_null:
+
+ return NULL;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Handle received packets.
+
+Arguments:
+ data - URB information pointer
+
+Return Value:
+ None
+
+Note:
+========================================================================
+*/
+static void rx_done_tasklet(unsigned long data)
+{
+ purbb_t pUrb;
+ PRX_CONTEXT pRxContext;
+ PRTMP_ADAPTER pAd;
+ NTSTATUS Status;
+ unsigned int IrqFlags;
+
+ pUrb = (purbb_t)data;
+ pRxContext = (PRX_CONTEXT)pUrb->context;
+ pAd = pRxContext->pAd;
+ Status = pUrb->status;
+
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->BulkInOffset += pUrb->actual_length;
+ //NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ pAd->BulkInComplete++;
+ pAd->NextRxBulkInPosition = 0;
+ if (pRxContext->BulkInOffset) // As jan's comment, it may bulk-in success but size is zero.
+ {
+ pRxContext->Readable = TRUE;
+ INC_RING_INDEX(pAd->NextRxBulkInIndex, RX_RING_SIZE);
+ }
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ }
+ else // STATUS_OTHER
+ {
+ pAd->BulkInCompleteFail++;
+ // Still read this packet although it may comtain wrong bytes.
+ pRxContext->Readable = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // Parsing all packets. because after reset, the index will reset to all zero.
+ if ((!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_BULKIN_RESET |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk In Failed. Status=%d, BIIdx=0x%x, BIRIdx=0x%x, actual_length= 0x%x\n",
+ Status, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pRxContext->pUrb->actual_length));
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN, NULL, 0);
+ }
+ }
+
+ ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ // If the driver is in ATE mode and Rx frame is set into here.
+ if (pAd->ContinBulkIn == TRUE)
+ {
+ RTUSBBulkReceive(pAd);
+ }
+ }
+ else
+#endif // RALINK_ATE //
+ RTUSBBulkReceive(pAd);
+
+ return;
+
+}
+
+
+static void rt2870_mgmt_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pMLMEContext;
+ int index;
+ PNDIS_PACKET pPacket;
+ purbb_t pUrb;
+ NTSTATUS Status;
+ unsigned long IrqFlags;
+
+
+ pUrb = (purbb_t)data;
+ pMLMEContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pMLMEContext->pAd;
+ Status = pUrb->status;
+ index = pMLMEContext->SelfIdx;
+
+ ASSERT((pAd->MgmtRing.TxDmaIdx == index));
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+
+ if (Status != USB_ST_NOERROR)
+ {
+ //Bulk-Out fail status handle
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out MLME Failed, Status=%d!\n", Status));
+ // TODO: How to handle about the MLMEBulkOut failed issue. Need to resend the mgmt pkt?
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ }
+ }
+
+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+ RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+ // Reset MLME context flags
+ pMLMEContext->IRPPending = FALSE;
+ pMLMEContext->InUse = FALSE;
+ pMLMEContext->bWaitingBulkOut = FALSE;
+ pMLMEContext->BulkOutSize = 0;
+
+ pPacket = pAd->MgmtRing.Cell[index].pNdisPacket;
+ pAd->MgmtRing.Cell[index].pNdisPacket = NULL;
+
+ // Increase MgmtRing Index
+ INC_RING_INDEX(pAd->MgmtRing.TxDmaIdx, MGMT_RING_SIZE);
+ pAd->MgmtRing.TxSwFreeIdx++;
+ RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+ // No-matter success or fail, we free the mgmt packet.
+ if (pPacket)
+ RTMPFreeNdisPacket(pAd, pPacket);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET) &&
+ ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG))
+ { // For Mgmt Bulk-Out failed, ignore it now.
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ {
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
+ {
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+ }
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+}
+
+
+static void rt2870_hcca_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 4;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<4);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+}
+
+
+static void rt2870_ac3_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 3;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<3);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+}
+
+
+static void rt2870_ac2_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 2;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<2);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+ return;
+}
+
+
+static void rt2870_ac1_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 1;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /*((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL<<1);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+}
+
+
+static void rt2870_ac0_dma_done_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId = 0;
+ purbb_t pUrb;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+
+ rt2870_dataout_complete_tasklet((unsigned long)pUrb);
+
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ // do nothing and return directly.
+ }
+ else
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET))
+ {
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ { pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ if ((pAd->TxSwQueue[BulkOutPipeId].Number > 0) &&
+ /* ((pHTTXContext->CurWritePosition > (pHTTXContext->NextBulkOutPosition + 0x6000)) || (pHTTXContext->NextBulkOutPosition > pHTTXContext->CurWritePosition + 0x6000)) && */
+ (pAd->DeQueueRunning[BulkOutPipeId] == FALSE) &&
+ (pHTTXContext->bCurWriting == FALSE))
+ {
+ RTMPDeQueuePacket(pAd, FALSE, BulkOutPipeId, MAX_TX_PROCESS);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL);
+ RTUSBKickBulkOut(pAd);
+ }
+ }
+
+
+ return;
+
+}
+
+
+static void rt2870_null_frame_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pNullContext;
+ purbb_t pUrb;
+ NTSTATUS Status;
+ unsigned long irqFlag;
+
+
+ pUrb = (purbb_t)data;
+ pNullContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pNullContext->pAd;
+ Status = pUrb->status;
+
+ // Reset Null frame context flags
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+ pNullContext->IRPPending = FALSE;
+ pNullContext->InUse = FALSE;
+ pAd->BulkOutPending[0] = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+ else // STATUS_OTHER
+ {
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out Null Frame Failed, ReasonCode=%d!\n", Status));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ }
+ }
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_rts_frame_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pRTSContext;
+ purbb_t pUrb;
+ NTSTATUS Status;
+ unsigned long irqFlag;
+
+
+ pUrb = (purbb_t)data;
+ pRTSContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pRTSContext->pAd;
+ Status = pUrb->status;
+
+ // Reset RTS frame context flags
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], irqFlag);
+ pRTSContext->IRPPending = FALSE;
+ pRTSContext->InUse = FALSE;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+ else // STATUS_OTHER
+ {
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out RTS Frame Failed\n"));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], irqFlag);
+ }
+ }
+
+ RTMP_SEM_LOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+ pAd->BulkOutPending[pRTSContext->BulkOutPipeId] = FALSE;
+ RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_pspoll_frame_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pPsPollContext;
+ purbb_t pUrb;
+ NTSTATUS Status;
+
+
+ pUrb = (purbb_t)data;
+ pPsPollContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pPsPollContext->pAd;
+ Status = pUrb->status;
+
+ // Reset PsPoll context flags
+ pPsPollContext->IRPPending = FALSE;
+ pPsPollContext->InUse = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+ else // STATUS_OTHER
+ {
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Bulk Out PSPoll Failed\n"));
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = (MGMTPIPEIDX | BULKOUT_MGMT_RESET_FLAG);
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ }
+ }
+
+ RTMP_SEM_LOCK(&pAd->BulkOutLock[0]);
+ pAd->BulkOutPending[0] = FALSE;
+ RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protectioon of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+static void rt2870_dataout_complete_tasklet(unsigned long data)
+{
+ PRTMP_ADAPTER pAd;
+ purbb_t pUrb;
+ POS_COOKIE pObj;
+ PHT_TX_CONTEXT pHTTXContext;
+ UCHAR BulkOutPipeId;
+ NTSTATUS Status;
+ unsigned long IrqFlags;
+
+
+ pUrb = (purbb_t)data;
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ Status = pUrb->status;
+
+ // Store BulkOut PipeId
+ BulkOutPipeId = pHTTXContext->BulkOutPipeId;
+ pAd->BulkOutDataOneSecCount++;
+
+ //DBGPRINT(RT_DEBUG_LOUD, ("Done-B(%d):I=0x%lx, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", BulkOutPipeId, in_interrupt(), pHTTXContext->CurWritePosition,
+ // pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ pHTTXContext->IRPPending = FALSE;
+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+
+ if (Status == USB_ST_NOERROR)
+ {
+ pAd->BulkOutComplete++;
+
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ pAd->Counters8023.GoodTransmits++;
+ //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ FREE_HTTX_RING(pAd, BulkOutPipeId, pHTTXContext);
+ //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+
+ }
+ else // STATUS_OTHER
+ {
+ PUCHAR pBuf;
+
+ pAd->BulkOutCompleteOther++;
+
+ pBuf = &pHTTXContext->TransferBuffer->field.WirelessPacket[pHTTXContext->NextBulkOutPosition];
+
+ if (!RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST |
+ fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ pAd->bulkResetPipeid = BulkOutPipeId;
+ pAd->bulkResetReq[BulkOutPipeId] = pAd->BulkOutReq;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkOutDataPacket failed: ReasonCode=%d!\n", Status));
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\t>>BulkOut Header:%x %x %x %x %x %x %x %x\n", pBuf[0], pBuf[1], pBuf[2], pBuf[3], pBuf[4], pBuf[5], pBuf[6], pBuf[7]));
+ //DBGPRINT_RAW(RT_DEBUG_ERROR, (">>BulkOutCompleteCancel=0x%x, BulkOutCompleteOther=0x%x\n", pAd->BulkOutCompleteCancel, pAd->BulkOutCompleteOther));
+
+ }
+
+ //
+ // bInUse = TRUE, means some process are filling TX data, after that must turn on bWaitingBulkOut
+ // bWaitingBulkOut = TRUE, means the TX data are waiting for bulk out.
+ //
+ //RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ if ((pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition) &&
+ (pHTTXContext->ENextBulkOutPosition != (pHTTXContext->CurWritePosition+8)) &&
+ !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId)))
+ {
+ // Indicate There is data avaliable
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ //RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protection of rest bulk should be in BulkOut routine
+ RTUSBKickBulkOut(pAd);
+}
+
+/* End of 2870_rtmp_init.c */
diff --git a/drivers/staging/rt3070/common/action.c b/drivers/staging/rt3070/common/action.c
new file mode 100644
index 00000000000..b8ae5363366
--- /dev/null
+++ b/drivers/staging/rt3070/common/action.c
@@ -0,0 +1,1038 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ action.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 2006 created for rt2860
+ */
+
+#include "../rt_config.h"
+#include "../action.h"
+
+
+static VOID ReservedAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ Note:
+ The state machine looks like the following
+
+ ASSOC_IDLE
+ MT2_MLME_DISASSOC_REQ mlme_disassoc_req_action
+ MT2_PEER_DISASSOC_REQ peer_disassoc_action
+ MT2_PEER_ASSOC_REQ drop
+ MT2_PEER_REASSOC_REQ drop
+ MT2_CLS3ERR cls3err_action
+ ==========================================================================
+ */
+VOID ActionStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, (STATE_MACHINE_FUNC *)Trans, MAX_ACT_STATE, MAX_ACT_MSG, (STATE_MACHINE_FUNC)Drop, ACT_IDLE, ACT_MACHINE_BASE);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_SPECTRUM_CATE, (STATE_MACHINE_FUNC)PeerSpectrumAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_QOS_CATE, (STATE_MACHINE_FUNC)PeerQOSAction);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)ReservedAction);
+#ifdef QOS_DLS_SUPPORT
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_DLS_CATE, (STATE_MACHINE_FUNC)PeerDLSAction);
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_BA_CATE, (STATE_MACHINE_FUNC)PeerBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_HT_CATE, (STATE_MACHINE_FUNC)PeerHTAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ADD_BA_CATE, (STATE_MACHINE_FUNC)MlmeADDBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_ORI_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_REC_DELBA_CATE, (STATE_MACHINE_FUNC)MlmeDELBAAction);
+#endif // DOT11_N_SUPPORT //
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_PUBLIC_CATE, (STATE_MACHINE_FUNC)PeerPublicAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_PEER_RM_CATE, (STATE_MACHINE_FUNC)PeerRMAction);
+
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_QOS_CATE, (STATE_MACHINE_FUNC)MlmeQOSAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_MLME_DLS_CATE, (STATE_MACHINE_FUNC)MlmeDLSAction);
+ StateMachineSetAction(S, ACT_IDLE, MT2_ACT_INVALID, (STATE_MACHINE_FUNC)MlmeInvalidAction);
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID MlmeADDBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ MLME_ADDBA_REQ_STRUCT *pInfo;
+ UCHAR Addr[6];
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG Idx;
+ FRAME_ADDBA_REQ Frame;
+ ULONG FrameLen;
+ BA_ORI_ENTRY *pBAEntry = NULL;
+
+ pInfo = (MLME_ADDBA_REQ_STRUCT *)Elem->Msg;
+ NdisZeroMemory(&Frame, sizeof(FRAME_ADDBA_REQ));
+
+ if(MlmeAddBAReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr))
+ {
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeADDBAAction() allocate memory failed \n"));
+ return;
+ }
+ // 1. find entry
+ Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+ if (Idx == 0)
+ {
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() can't find BAOriEntry \n"));
+ return;
+ }
+ else
+ {
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &Frame.Hdr, pInfo->pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pInfo->pAddr);
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ Frame.Category = CATEGORY_BA;
+ Frame.Action = ADDBA_REQ;
+ Frame.BaParm.AMSDUSupported = 0;
+ Frame.BaParm.BAPolicy = IMMED_BA;
+ Frame.BaParm.TID = pInfo->TID;
+ Frame.BaParm.BufSize = pInfo->BaBufSize;
+ Frame.Token = pInfo->Token;
+ Frame.TimeOutValue = pInfo->TimeOutValue;
+ Frame.BaStartSeq.field.FragNum = 0;
+ Frame.BaStartSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID];
+
+ *(USHORT *)(&Frame.BaParm) = cpu2le16(*(USHORT *)(&Frame.BaParm));
+ Frame.TimeOutValue = cpu2le16(Frame.TimeOutValue);
+ Frame.BaStartSeq.word = cpu2le16(Frame.BaStartSeq.word);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ADDBA_REQ), &Frame,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[pInfo->TID], pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BA - Send ADDBA request. StartSeq = %x, FrameLen = %ld. BufSize = %d\n", Frame.BaStartSeq.field.StartSeq, FrameLen, Frame.BaParm.BufSize));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ send DELBA and delete BaEntry if any
+ Parametrs:
+ Elem - MLME message MLME_DELBA_REQ_STRUCT
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDELBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DELBA_REQ_STRUCT *pInfo;
+ PUCHAR pOutBuffer = NULL;
+ PUCHAR pOutBuffer2 = NULL;
+ NDIS_STATUS NStatus;
+ ULONG Idx;
+ FRAME_DELBA_REQ Frame;
+ ULONG FrameLen;
+ FRAME_BAR FrameBar;
+
+ pInfo = (MLME_DELBA_REQ_STRUCT *)Elem->Msg;
+ // must send back DELBA
+ NdisZeroMemory(&Frame, sizeof(FRAME_DELBA_REQ));
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeDELBAAction(), Initiator(%d) \n", pInfo->Initiator));
+
+ if(MlmeDelBAReqSanity(pAd, Elem->Msg, Elem->MsgLen))
+ {
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeDELBAAction() allocate memory failed 1. \n"));
+ return;
+ }
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_ERROR, ("BA - MlmeDELBAAction() allocate memory failed 2. \n"));
+ return;
+ }
+
+ // SEND BAR (Send BAR to refresh peer reordering buffer.)
+ Idx = pAd->MacTab.Content[pInfo->Wcid].BAOriWcidArray[pInfo->TID];
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL funciton.
+ FrameBar.StartingSeq.field.StartSeq = pAd->MacTab.Content[pInfo->Wcid].TxSeq[pInfo->TID]; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.TID = pInfo->TID; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.ACKPolicy = IMMED_BA; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.Compressed = 1; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.MTID = 0; // make sure sequence not clear in DEL funciton.
+
+ MakeOutgoingFrame(pOutBuffer2, &FrameLen,
+ sizeof(FRAME_BAR), &FrameBar,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer2);
+ DBGPRINT(RT_DEBUG_TRACE,("BA - MlmeDELBAAction() . Send BAR to refresh peer reordering buffer \n"));
+
+ // SEND DELBA FRAME
+ FrameLen = 0;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[pInfo->Wcid].Addr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[pInfo->Wcid].Addr);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ Frame.Category = CATEGORY_BA;
+ Frame.Action = DELBA;
+ Frame.DelbaParm.Initiator = pInfo->Initiator;
+ Frame.DelbaParm.TID = pInfo->TID;
+ Frame.ReasonCode = 39; // Time Out
+ *(USHORT *)(&Frame.DelbaParm) = cpu2le16(*(USHORT *)(&Frame.DelbaParm));
+ Frame.ReasonCode = cpu2le16(Frame.ReasonCode);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_DELBA_REQ), &Frame,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("BA - MlmeDELBAAction() . 3 DELBA sent. Initiator(%d)\n", pInfo->Initiator));
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID MlmeQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID MlmeDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+VOID MlmeInvalidAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ //PUCHAR pOutBuffer = NULL;
+ //Return the receiving frame except the MSB of category filed set to 1. 7.3.1.11
+}
+
+VOID PeerQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+#ifdef QOS_DLS_SUPPORT
+VOID PeerDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ switch(Action)
+ {
+ case ACTION_DLS_REQUEST:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ PeerDlsReqAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+
+ case ACTION_DLS_RESPONSE:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ PeerDlsRspAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+
+ case ACTION_DLS_TEARDOWN:
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ PeerDlsTearDownAction(pAd, Elem);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+ }
+}
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ switch(Action)
+ {
+ case ADDBA_REQ:
+ PeerAddBAReqAction(pAd,Elem);
+ break;
+ case ADDBA_RESP:
+ PeerAddBARspAction(pAd,Elem);
+ break;
+ case DELBA:
+ PeerDelBAAction(pAd,Elem);
+ break;
+ }
+}
+
+
+#ifdef DOT11N_DRAFT3
+
+#ifdef CONFIG_STA_SUPPORT
+VOID StaPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Bss2040Coexist)
+{
+ BSS_2040_COEXIST_IE BssCoexist;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+
+ BssCoexist.word = Bss2040Coexist;
+ // AP asks Station to return a 20/40 BSS Coexistence mgmt frame. So we first starts a scan, then send back 20/40 BSS Coexistence mgmt frame
+ if ((BssCoexist.field.InfoReq == 1) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040)))
+ {
+ // Clear record first. After scan , will update those bit and send back to transmiter.
+ pAd->CommonCfg.BSSCoexist2040.field.InfoReq = 1;
+ pAd->CommonCfg.BSSCoexist2040.field.Intolerant40 = 0;
+ pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 0;
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_2040_BSS_COEXIST);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+ }
+}
+
+
+/*
+Description : Build Intolerant Channel Rerpot from Trigger event table.
+return : how many bytes copied.
+*/
+ULONG BuildIntolerantChannelRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest)
+{
+ ULONG FrameLen = 0;
+ ULONG ReadOffset = 0;
+ UCHAR i;
+ UCHAR LastRegClass = 0xff;
+ PUCHAR pLen;
+
+ for ( i = 0;i < MAX_TRIGGER_EVENT;i++)
+ {
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid == TRUE)
+ {
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass == LastRegClass)
+ {
+ *(pDest + ReadOffset) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
+ *pLen++;
+ ReadOffset++;
+ FrameLen++;
+ }
+ else
+ {
+ *(pDest + ReadOffset) = IE_2040_BSS_INTOLERANT_REPORT; // IE
+ *(pDest + ReadOffset + 1) = 2; // Len = RegClass byte + channel byte.
+ pLen = pDest + ReadOffset + 1;
+ LastRegClass = pAd->CommonCfg.TriggerEventTab.EventA[i].RegClass;
+ *(pDest + ReadOffset + 2) = LastRegClass; // Len = RegClass byte + channel byte.
+ *(pDest + ReadOffset + 3) = (UCHAR)pAd->CommonCfg.TriggerEventTab.EventA[i].Channel;
+ FrameLen += 4;
+ ReadOffset += 4;
+ }
+
+ }
+ }
+ return FrameLen;
+}
+
+
+/*
+Description : Send 20/40 BSS Coexistence Action frame If one trigger event is triggered.
+*/
+VOID Send2040CoexistAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ FRAME_ACTION_HDR Frame;
+ ULONG FrameLen;
+ ULONG IntolerantChaRepLen;
+
+ IntolerantChaRepLen = 0;
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction() allocate memory failed \n"));
+ return;
+ }
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->MacTab.Content[Wcid].Addr, pAd->CommonCfg.Bssid);
+ Frame.Category = CATEGORY_PUBLIC;
+ Frame.Action = ACTION_BSS_2040_COEXIST;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ACTION_HDR), &Frame,
+ END_OF_ARGS);
+
+ *(pOutBuffer + FrameLen) = pAd->CommonCfg.BSSCoexist2040.word;
+ FrameLen++;
+
+ if (bAddIntolerantCha == TRUE)
+ IntolerantChaRepLen = BuildIntolerantChannelRep(pAd, pOutBuffer + FrameLen);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen + IntolerantChaRepLen);
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - Send2040CoexistAction( BSSCoexist2040 = 0x%x ) \n", pAd->CommonCfg.BSSCoexist2040.word));
+
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ After scan, Update 20/40 BSS Coexistence IE and send out.
+ According to 802.11n D3.03 11.14.10
+
+ Parameters:
+ ==========================================================================
+ */
+VOID Update2040CoexistFrameAndNotify(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha)
+{
+ BSS_2040_COEXIST_IE OldValue;
+
+ OldValue.word = pAd->CommonCfg.BSSCoexist2040.word;
+ if ((pAd->CommonCfg.TriggerEventTab.EventANo > 0) || (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0))
+ pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq = 1;
+
+ // Need to check !!!!
+ // How STA will set Intolerant40 if implementation dependent. Now we don't set this bit first.!!!!!
+ // So Only check BSS20WidthReq change.
+ if (OldValue.field.BSS20WidthReq != pAd->CommonCfg.BSSCoexist2040.field.BSS20WidthReq)
+ {
+ Send2040CoexistAction(pAd, Wcid, bAddIntolerantCha);
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+BOOLEAN ChannelSwitchSanityCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR NewChannel,
+ IN UCHAR Secondary)
+{
+ UCHAR i;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ if ((NewChannel > 7) && (Secondary == 1))
+ return FALSE;
+
+ if ((NewChannel < 5) && (Secondary == 3))
+ return FALSE;
+
+ // 0. Check if new channel is in the channellist.
+ for (i = 0;i < pAd->ChannelListNum;i++)
+ {
+ if (pAd->ChannelList[i].Channel == NewChannel)
+ {
+ break;
+ }
+ }
+
+ if (i == pAd->ChannelListNum)
+ return FALSE;
+
+ return TRUE;
+}
+
+
+VOID ChannelSwitchAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR NewChannel,
+ IN UCHAR Secondary)
+{
+ UCHAR BBPValue = 0;
+ ULONG MACValue;
+
+ DBGPRINT(RT_DEBUG_TRACE,("SPECTRUM - ChannelSwitchAction(NewChannel = %d , Secondary = %d) \n", NewChannel, Secondary));
+
+ if (ChannelSwitchSanityCheck(pAd, Wcid, NewChannel, Secondary) == FALSE)
+ return;
+
+ // 1. Switches to BW = 20.
+ if (Secondary == 0)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ pAd->CommonCfg.Channel = NewChannel;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel,FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!20MHz !!! \n" ));
+ }
+ // 1. Switches to BW = 40 And Station supports BW = 40.
+ else if (((Secondary == 1) || (Secondary == 3)) && (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == 1))
+ {
+ pAd->CommonCfg.Channel = NewChannel;
+
+ if (Secondary == 1)
+ {
+ // Secondary above.
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
+ MACValue &= 0xfe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ BBPValue|= (0x10);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
+ BBPValue&= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else
+ {
+ // Secondary below.
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &MACValue);
+ MACValue &= 0xfe;
+ MACValue |= 0x1;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, MACValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ BBPValue|= (0x10);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPValue);
+ BBPValue&= (~0x20);
+ BBPValue|= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ pAd->MacTab.Content[Wcid].HTPhyMode.field.BW = 1;
+ }
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+VOID PeerPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+#ifdef DOT11N_DRAFT3
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+#endif // DOT11N_DRAFT3 //
+
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+#ifdef DOT11N_DRAFT3
+ switch(Action)
+ {
+ case ACTION_BSS_2040_COEXIST: // Format defined in IEEE 7.4.7a.1 in 11n Draf3.03
+ {
+ //UCHAR BssCoexist;
+ BSS_2040_COEXIST_ELEMENT *pCoexistInfo;
+ BSS_2040_COEXIST_IE *pBssCoexistIe;
+ BSS_2040_INTOLERANT_CH_REPORT *pIntolerantReport = NULL;
+
+ if (Elem->MsgLen <= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT)) )
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ACTION - 20/40 BSS Coexistence Management Frame length too short! len = %ld!\n", Elem->MsgLen));
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("ACTION - 20/40 BSS Coexistence Management action----> \n"));
+ hex_dump("CoexistenceMgmtFrame", Elem->Msg, Elem->MsgLen);
+
+
+ pCoexistInfo = (BSS_2040_COEXIST_ELEMENT *) &Elem->Msg[LENGTH_802_11+2];
+ //hex_dump("CoexistInfo", (PUCHAR)pCoexistInfo, sizeof(BSS_2040_COEXIST_ELEMENT));
+ if (Elem->MsgLen >= (LENGTH_802_11 + sizeof(BSS_2040_COEXIST_ELEMENT) + sizeof(BSS_2040_INTOLERANT_CH_REPORT)))
+ {
+ pIntolerantReport = (BSS_2040_INTOLERANT_CH_REPORT *)((PUCHAR)pCoexistInfo + sizeof(BSS_2040_COEXIST_ELEMENT));
+ }
+ //hex_dump("IntolerantReport ", (PUCHAR)pIntolerantReport, sizeof(BSS_2040_INTOLERANT_CH_REPORT));
+
+ pBssCoexistIe = (BSS_2040_COEXIST_IE *)(&pCoexistInfo->BssCoexistIe);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (INFRA_ON(pAd))
+ {
+ StaPublicAction(pAd, pCoexistInfo);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ }
+ break;
+ }
+
+#endif // DOT11N_DRAFT3 //
+
+}
+
+
+static VOID ReservedAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Category;
+
+ if (Elem->MsgLen <= LENGTH_802_11)
+ {
+ return;
+ }
+
+ Category = Elem->Msg[LENGTH_802_11];
+ DBGPRINT(RT_DEBUG_TRACE,("Rcv reserved category(%d) Action Frame\n", Category));
+ hex_dump("Reserved Action Frame", &Elem->Msg[0], Elem->MsgLen);
+}
+
+VOID PeerRMAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ return;
+}
+
+#ifdef DOT11_N_SUPPORT
+static VOID respond_ht_information_exchange_action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ FRAME_HT_INFO HTINFOframe, *pFrame;
+ UCHAR *pAddr;
+
+
+ // 2. Always send back ADDBA Response
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - respond_ht_information_exchange_action() allocate memory failed \n"));
+ return;
+ }
+
+ // get RA
+ pFrame = (FRAME_HT_INFO *) &Elem->Msg[0];
+ pAddr = pFrame->Hdr.Addr2;
+
+ NdisZeroMemory(&HTINFOframe, sizeof(FRAME_HT_INFO));
+ // 2-1. Prepare ADDBA Response frame.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &HTINFOframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ HTINFOframe.Category = CATEGORY_HT;
+ HTINFOframe.Action = HT_INFO_EXCHANGE;
+ HTINFOframe.HT_Info.Request = 0;
+ HTINFOframe.HT_Info.Forty_MHz_Intolerant = pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant;
+ HTINFOframe.HT_Info.STA_Channel_Width = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_HT_INFO), &HTINFOframe,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+
+#ifdef DOT11N_DRAFT3
+VOID SendNotifyBWActionFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ FRAME_ACTION_HDR Frame;
+ ULONG FrameLen;
+ PUCHAR pAddr1;
+
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ACT - SendNotifyBWAction() allocate memory failed \n"));
+ return;
+ }
+
+ if (Wcid == MCAST_WCID)
+ pAddr1 = &BROADCAST_ADDR[0];
+ else
+ pAddr1 = pAd->MacTab.Content[Wcid].Addr;
+ ActHeaderInit(pAd, &Frame.Hdr, pAddr1, pAd->ApCfg.MBSSID[apidx].Bssid, pAd->ApCfg.MBSSID[apidx].Bssid);
+
+ Frame.Category = CATEGORY_HT;
+ Frame.Action = NOTIFY_BW_ACTION;
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ACTION_HDR), &Frame,
+ END_OF_ARGS);
+
+ *(pOutBuffer + FrameLen) = pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth;
+ FrameLen++;
+
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ DBGPRINT(RT_DEBUG_TRACE,("ACT - SendNotifyBWAction(NotifyBW= %d)!\n", pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth));
+
+}
+#endif // DOT11N_DRAFT3 //
+
+
+VOID PeerHTAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ switch(Action)
+ {
+ case NOTIFY_BW_ACTION:
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Notify Channel bandwidth action----> \n"));
+#ifdef CONFIG_STA_SUPPORT
+ if(pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+ {
+ // Note, this is to patch DIR-1353 AP. When the AP set to Wep, it will use legacy mode. But AP still keeps
+ // sending BW_Notify Action frame, and cause us to linkup and linkdown.
+ // In legacy mode, don't need to parse HT action frame.
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION -Ignore HT Notify Channel BW when link as legacy mode. BW = %d---> \n",
+ Elem->Msg[LENGTH_802_11+2] ));
+ break;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (Elem->Msg[LENGTH_802_11+2] == 0) // 7.4.8.2. if value is 1, keep the same as supported channel bandwidth.
+ pAd->MacTab.Content[Elem->Wcid].HTPhyMode.field.BW = 0;
+
+ break;
+
+ case SMPS_ACTION:
+ // 7.3.1.25
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - SMPS action----> \n"));
+ if (((Elem->Msg[LENGTH_802_11+2]&0x1) == 0))
+ {
+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_ENABLE;
+ }
+ else if (((Elem->Msg[LENGTH_802_11+2]&0x2) == 0))
+ {
+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_STATIC;
+ }
+ else
+ {
+ pAd->MacTab.Content[Elem->Wcid].MmpsMode = MMPS_DYNAMIC;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("Aid(%d) MIMO PS = %d\n", Elem->Wcid, pAd->MacTab.Content[Elem->Wcid].MmpsMode));
+ // rt2860c : add something for smps change.
+ break;
+
+ case SETPCO_ACTION:
+ break;
+
+ case MIMO_CHA_MEASURE_ACTION:
+ break;
+
+ case HT_INFO_EXCHANGE:
+ {
+ HT_INFORMATION_OCTET *pHT_info;
+
+ pHT_info = (HT_INFORMATION_OCTET *) &Elem->Msg[LENGTH_802_11+2];
+ // 7.4.8.10
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - HT Information Exchange action----> \n"));
+ if (pHT_info->Request)
+ {
+ respond_ht_information_exchange_action(pAd, Elem);
+ }
+ }
+ break;
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Retry sending ADDBA Reqest.
+
+ IRQL = DISPATCH_LEVEL
+
+ Parametrs:
+ p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+ FALSE , then continue indicaterx at this moment.
+ ==========================================================================
+ */
+VOID ORIBATimerTimeout(
+ IN PRTMP_ADAPTER pAd)
+{
+ MAC_TABLE_ENTRY *pEntry;
+ INT i, total;
+// FRAME_BAR FrameBar;
+// ULONG FrameLen;
+// NDIS_STATUS NStatus;
+// PUCHAR pOutBuffer = NULL;
+// USHORT Sequence;
+ UCHAR TID;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ total = pAd->MacTab.Size * NUM_OF_TID;
+
+ for (i = 1; ((i <MAX_LEN_OF_BA_ORI_TABLE) && (total > 0)) ; i++)
+ {
+ if (pAd->BATable.BAOriEntry[i].ORI_BA_Status == Originator_Done)
+ {
+ pEntry = &pAd->MacTab.Content[pAd->BATable.BAOriEntry[i].Wcid];
+ TID = pAd->BATable.BAOriEntry[i].TID;
+
+ ASSERT(pAd->BATable.BAOriEntry[i].Wcid < MAX_LEN_OF_MAC_TABLE);
+ }
+ total --;
+ }
+}
+
+
+VOID SendRefreshBAR(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ FRAME_BAR FrameBar;
+ ULONG FrameLen;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ USHORT Sequence;
+ UCHAR i, TID;
+ USHORT idx;
+ BA_ORI_ENTRY *pBAEntry;
+
+ for (i = 0; i <NUM_OF_TID; i++)
+ {
+ idx = pEntry->BAOriWcidArray[i];
+ if (idx == 0)
+ {
+ continue;
+ }
+ pBAEntry = &pAd->BATable.BAOriEntry[idx];
+
+ if (pBAEntry->ORI_BA_Status == Originator_Done)
+ {
+ TID = pBAEntry->TID;
+
+ ASSERT(pBAEntry->Wcid < MAX_LEN_OF_MAC_TABLE);
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+ return;
+ }
+
+ Sequence = pEntry->TxSeq[TID];
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ BarHeaderInit(pAd, &FrameBar, pEntry->Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
+ FrameBar.StartingSeq.field.StartSeq = Sequence; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.TID = TID; // make sure sequence not clear in DEL funciton.
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_BAR), &FrameBar,
+ END_OF_ARGS);
+ //if (!(CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_RALINK_CHIPSET)))
+ if (1) // Now we always send BAR.
+ {
+ //MiniportMMRequestUnlock(pAd, 0, pOutBuffer, FrameLen);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ //MiniportDataMMRequest(pAd, MapUserPriorityToAccessCategory[TID], pOutBuffer, FrameLen);
+ }
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID ActHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN PUCHAR Addr1,
+ IN PUCHAR Addr2,
+ IN PUCHAR Addr3)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SUBTYPE_ACTION;
+
+ COPY_MAC_ADDR(pHdr80211->Addr1, Addr1);
+ COPY_MAC_ADDR(pHdr80211->Addr2, Addr2);
+ COPY_MAC_ADDR(pHdr80211->Addr3, Addr3);
+}
+
+VOID BarHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PFRAME_BAR pCntlBar,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA)
+{
+// USHORT Duration;
+
+ NdisZeroMemory(pCntlBar, sizeof(FRAME_BAR));
+ pCntlBar->FC.Type = BTYPE_CNTL;
+ pCntlBar->FC.SubType = SUBTYPE_BLOCK_ACK_REQ;
+ pCntlBar->BarControl.MTID = 0;
+ pCntlBar->BarControl.Compressed = 1;
+ pCntlBar->BarControl.ACKPolicy = 0;
+
+
+ pCntlBar->Duration = 16 + RTMPCalcDuration(pAd, RATE_1, sizeof(FRAME_BA));
+
+ COPY_MAC_ADDR(pCntlBar->Addr1, pDA);
+ COPY_MAC_ADDR(pCntlBar->Addr2, pSA);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Insert Category and action code into the action frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. category code of the frame.
+ 4. action code of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID InsertActField(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 Category,
+ IN UINT8 ActCode)
+{
+ ULONG TempLen;
+
+ MakeOutgoingFrame( pFrameBuf, &TempLen,
+ 1, &Category,
+ 1, &ActCode,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
diff --git a/drivers/staging/rt3070/common/ba_action.c b/drivers/staging/rt3070/common/ba_action.c
new file mode 100644
index 00000000000..17e1f87d98d
--- /dev/null
+++ b/drivers/staging/rt3070/common/ba_action.c
@@ -0,0 +1,1810 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+
+#ifdef DOT11_N_SUPPORT
+
+#include "../rt_config.h"
+
+
+
+#define BA_ORI_INIT_SEQ (pEntry->TxSeq[TID]) //1 // inital sequence number of BA session
+
+#define ORI_SESSION_MAX_RETRY 8
+#define ORI_BA_SESSION_TIMEOUT (2000) // ms
+#define REC_BA_SESSION_IDLE_TIMEOUT (1000) // ms
+
+#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
+#define MAX_REORDERING_PACKET_TIMEOUT ((3000 * HZ)/1000) // system ticks -- 100 ms
+
+#define RESET_RCV_SEQ (0xFFFF)
+
+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk);
+
+
+BA_ORI_ENTRY *BATableAllocOriEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx);
+
+BA_REC_ENTRY *BATableAllocRecEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx);
+
+VOID BAOriSessionSetupTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID BARecSessionIdleTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+
+BUILD_TIMER_FUNCTION(BAOriSessionSetupTimeout);
+BUILD_TIMER_FUNCTION(BARecSessionIdleTimeout);
+
+#define ANNOUNCE_REORDERING_PACKET(_pAd, _mpdu_blk) \
+ Announce_Reordering_Packet(_pAd, _mpdu_blk);
+
+VOID BA_MaxWinSizeReasign(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntryPeer,
+ OUT UCHAR *pWinSize)
+{
+ UCHAR MaxSize;
+
+
+ if (pAd->MACVersion >= RALINK_2883_VERSION) // 3*3
+ {
+ if (pAd->MACVersion >= RALINK_3070_VERSION)
+ {
+ if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
+ MaxSize = 7; // for non-open mode
+ else
+ MaxSize = 13;
+ }
+ else
+ MaxSize = 31;
+ }
+ else if (pAd->MACVersion >= RALINK_2880E_VERSION) // 2880 e
+ {
+ if (pEntryPeer->WepStatus != Ndis802_11EncryptionDisabled)
+ MaxSize = 7; // for non-open mode
+ else
+ MaxSize = 13;
+ }
+ else
+ MaxSize = 7;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ba> Win Size = %d, Max Size = %d\n",
+ *pWinSize, MaxSize));
+
+ if ((*pWinSize) > MaxSize)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ba> reassign max win size from %d to %d\n",
+ *pWinSize, MaxSize));
+
+ *pWinSize = MaxSize;
+ }
+}
+
+void Announce_Reordering_Packet(IN PRTMP_ADAPTER pAd,
+ IN struct reordering_mpdu *mpdu)
+{
+ PNDIS_PACKET pPacket;
+
+ pPacket = mpdu->pPacket;
+
+ if (mpdu->bAMSDU)
+ {
+ ASSERT(0);
+ BA_Reorder_AMSDU_Annnounce(pAd, pPacket);
+ }
+ else
+ {
+ //
+ // pass this 802.3 packet to upper layer or forward this packet to WM directly
+ //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket, RTMP_GET_PACKET_IF(pPacket));
+#endif // CONFIG_STA_SUPPORT //
+ }
+}
+
+/*
+ * Insert a reordering mpdu into sorted linked list by sequence no.
+ */
+BOOLEAN ba_reordering_mpdu_insertsorted(struct reordering_list *list, struct reordering_mpdu *mpdu)
+{
+
+ struct reordering_mpdu **ppScan = &list->next;
+
+ while (*ppScan != NULL)
+ {
+ if (SEQ_SMALLER((*ppScan)->Sequence, mpdu->Sequence, MAXSEQ))
+ {
+ ppScan = &(*ppScan)->next;
+ }
+ else if ((*ppScan)->Sequence == mpdu->Sequence)
+ {
+ /* give up this duplicated frame */
+ return(FALSE);
+ }
+ else
+ {
+ /* find position */
+ break;
+ }
+ }
+
+ mpdu->next = *ppScan;
+ *ppScan = mpdu;
+ list->qlen++;
+ return TRUE;
+}
+
+
+/*
+ * caller lock critical section if necessary
+ */
+static inline void ba_enqueue(struct reordering_list *list, struct reordering_mpdu *mpdu_blk)
+{
+ list->qlen++;
+ mpdu_blk->next = list->next;
+ list->next = mpdu_blk;
+}
+
+/*
+ * caller lock critical section if necessary
+ */
+static inline struct reordering_mpdu * ba_dequeue(struct reordering_list *list)
+{
+ struct reordering_mpdu *mpdu_blk = NULL;
+
+ ASSERT(list);
+
+ if (list->qlen)
+ {
+ list->qlen--;
+ mpdu_blk = list->next;
+ if (mpdu_blk)
+ {
+ list->next = mpdu_blk->next;
+ mpdu_blk->next = NULL;
+ }
+ }
+ return mpdu_blk;
+}
+
+
+static inline struct reordering_mpdu *ba_reordering_mpdu_dequeue(struct reordering_list *list)
+{
+ return(ba_dequeue(list));
+}
+
+
+static inline struct reordering_mpdu *ba_reordering_mpdu_probe(struct reordering_list *list)
+ {
+ ASSERT(list);
+
+ return(list->next);
+ }
+
+
+/*
+ * free all resource for reordering mechanism
+ */
+void ba_reordering_resource_release(PRTMP_ADAPTER pAd)
+{
+ BA_TABLE *Tab;
+ PBA_REC_ENTRY pBAEntry;
+ struct reordering_mpdu *mpdu_blk;
+ int i;
+
+ Tab = &pAd->BATable;
+
+ /* I. release all pending reordering packet */
+ NdisAcquireSpinLock(&pAd->BATabLock);
+ for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ pBAEntry = &Tab->BARecEntry[i];
+ if (pBAEntry->REC_BA_Status != Recipient_NONE)
+ {
+ while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
+ {
+ ASSERT(mpdu_blk->pPacket);
+ RELEASE_NDIS_PACKET(pAd, mpdu_blk->pPacket, NDIS_STATUS_FAILURE);
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+ }
+ }
+ NdisReleaseSpinLock(&pAd->BATabLock);
+
+ ASSERT(pBAEntry->list.qlen == 0);
+ /* II. free memory of reordering mpdu table */
+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+ os_free_mem(pAd, pAd->mpdu_blk_pool.mem);
+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+}
+
+
+
+/*
+ * Allocate all resource for reordering mechanism
+ */
+BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num)
+{
+ int i;
+ PUCHAR mem;
+ struct reordering_mpdu *mpdu_blk;
+ struct reordering_list *freelist;
+
+ /* allocate spinlock */
+ NdisAllocateSpinLock(&pAd->mpdu_blk_pool.lock);
+
+ /* initialize freelist */
+ freelist = &pAd->mpdu_blk_pool.freelist;
+ freelist->next = NULL;
+ freelist->qlen = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Allocate %d memory for BA reordering\n", (UINT32)(num*sizeof(struct reordering_mpdu))));
+
+ /* allocate number of mpdu_blk memory */
+ os_alloc_mem(pAd, (PUCHAR *)&mem, (num*sizeof(struct reordering_mpdu)));
+
+ pAd->mpdu_blk_pool.mem = mem;
+
+ if (mem == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Can't Allocate Memory for BA Reordering\n"));
+ return(FALSE);
+ }
+
+ /* build mpdu_blk free list */
+ for (i=0; i<num; i++)
+ {
+ /* get mpdu_blk */
+ mpdu_blk = (struct reordering_mpdu *) mem;
+ /* initial mpdu_blk */
+ NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
+ /* next mpdu_blk */
+ mem += sizeof(struct reordering_mpdu);
+ /* insert mpdu_blk into freelist */
+ ba_enqueue(freelist, mpdu_blk);
+ }
+
+ return(TRUE);
+}
+
+//static int blk_count=0; // sample take off, no use
+
+static struct reordering_mpdu *ba_mpdu_blk_alloc(PRTMP_ADAPTER pAd)
+{
+ struct reordering_mpdu *mpdu_blk;
+
+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+ mpdu_blk = ba_dequeue(&pAd->mpdu_blk_pool.freelist);
+ if (mpdu_blk)
+ {
+// blk_count++;
+ /* reset mpdu_blk */
+ NdisZeroMemory(mpdu_blk, sizeof(struct reordering_mpdu));
+ }
+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+ return mpdu_blk;
+}
+
+static void ba_mpdu_blk_free(PRTMP_ADAPTER pAd, struct reordering_mpdu *mpdu_blk)
+{
+ ASSERT(mpdu_blk);
+
+ NdisAcquireSpinLock(&pAd->mpdu_blk_pool.lock);
+// blk_count--;
+ ba_enqueue(&pAd->mpdu_blk_pool.freelist, mpdu_blk);
+ NdisReleaseSpinLock(&pAd->mpdu_blk_pool.lock);
+}
+
+
+static USHORT ba_indicate_reordering_mpdus_in_order(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN USHORT StartSeq)
+{
+ struct reordering_mpdu *mpdu_blk;
+ USHORT LastIndSeq = RESET_RCV_SEQ;
+
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+ while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
+ {
+ /* find in-order frame */
+ if (!SEQ_STEPONE(mpdu_blk->Sequence, StartSeq, MAXSEQ))
+ {
+ break;
+ }
+ /* dequeue in-order frame from reodering list */
+ mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
+ /* pass this frame up */
+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+ /* move to next sequence */
+ StartSeq = mpdu_blk->Sequence;
+ LastIndSeq = StartSeq;
+ /* free mpdu_blk */
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+
+ /* update last indicated sequence */
+ return LastIndSeq;
+}
+
+static void ba_indicate_reordering_mpdus_le_seq(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN USHORT Sequence)
+{
+ struct reordering_mpdu *mpdu_blk;
+
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+ while ((mpdu_blk = ba_reordering_mpdu_probe(&pBAEntry->list)))
+ {
+ /* find in-order frame */
+ if ((mpdu_blk->Sequence == Sequence) || SEQ_SMALLER(mpdu_blk->Sequence, Sequence, MAXSEQ))
+ {
+ /* dequeue in-order frame from reodering list */
+ mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list);
+ /* pass this frame up */
+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+ /* free mpdu_blk */
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+ else
+ {
+ break;
+ }
+ }
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+}
+
+
+static void ba_refresh_reordering_mpdus(
+ IN PRTMP_ADAPTER pAd,
+ PBA_REC_ENTRY pBAEntry)
+{
+ struct reordering_mpdu *mpdu_blk;
+
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+ /* dequeue in-order frame from reodering list */
+ while ((mpdu_blk = ba_reordering_mpdu_dequeue(&pBAEntry->list)))
+ {
+ /* pass this frame up */
+ ANNOUNCE_REORDERING_PACKET(pAd, mpdu_blk);
+
+ pBAEntry->LastIndSeq = mpdu_blk->Sequence;
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+
+ /* update last indicated sequence */
+ }
+ ASSERT(pBAEntry->list.qlen == 0);
+ pBAEntry->LastIndSeq = RESET_RCV_SEQ;
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+}
+
+
+//static
+void ba_flush_reordering_timeout_mpdus(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN ULONG Now32)
+
+{
+ USHORT Sequence;
+
+// if ((RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+REORDERING_PACKET_TIMEOUT)) &&
+// (pBAEntry->list.qlen > ((pBAEntry->BAWinSize*7)/8))) //||
+// (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(10*REORDERING_PACKET_TIMEOUT))) &&
+// (pBAEntry->list.qlen > (pBAEntry->BAWinSize/8)))
+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(MAX_REORDERING_PACKET_TIMEOUT/6)))
+ &&(pBAEntry->list.qlen > 1)
+ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("timeout[%d] (%08lx-%08lx = %d > %d): %x, flush all!\n ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
+ (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), MAX_REORDERING_PACKET_TIMEOUT,
+ pBAEntry->LastIndSeq));
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ }
+ else
+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
+ && (pBAEntry->list.qlen > 0)
+ )
+ {
+// printk("timeout[%d] (%lx-%lx = %d > %d): %x, ", pBAEntry->list.qlen, Now32, (pBAEntry->LastIndSeqAtTimer),
+// (int)((long) Now32 - (long)(pBAEntry->LastIndSeqAtTimer)), REORDERING_PACKET_TIMEOUT,
+// pBAEntry->LastIndSeq);
+ //
+ // force LastIndSeq to shift to LastIndSeq+1
+ //
+ Sequence = (pBAEntry->LastIndSeq+1) & MAXSEQ;
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ pBAEntry->LastIndSeq = Sequence;
+ //
+ // indicate in-order mpdus
+ //
+ Sequence = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, Sequence);
+ if (Sequence != RESET_RCV_SEQ)
+ {
+ pBAEntry->LastIndSeq = Sequence;
+ }
+
+ //printk("%x, flush one!\n", pBAEntry->LastIndSeq);
+
+ }
+}
+
+
+/*
+ * generate ADDBA request to
+ * set up BA agreement
+ */
+VOID BAOriSessionSetUp(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR TID,
+ IN USHORT TimeOut,
+ IN ULONG DelayTime,
+ IN BOOLEAN isForced)
+
+{
+ //MLME_ADDBA_REQ_STRUCT AddbaReq;
+ BA_ORI_ENTRY *pBAEntry = NULL;
+ USHORT Idx;
+ BOOLEAN Cancelled;
+
+ if ((pAd->CommonCfg.BACapability.field.AutoBA != TRUE) && (isForced == FALSE))
+ return;
+
+ // if this entry is limited to use legacy tx mode, it doesn't generate BA.
+ if (RTMPStaFixedTxMode(pAd, pEntry) != FIXED_TXMODE_HT)
+ return;
+
+ if ((pEntry->BADeclineBitmap & (1<<TID)) && (isForced == FALSE))
+ {
+ // try again after 3 secs
+ DelayTime = 3000;
+// printk("DeCline BA from Peer\n");
+// return;
+ }
+
+
+ Idx = pEntry->BAOriWcidArray[TID];
+ if (Idx == 0)
+ {
+ // allocate a BA session
+ pBAEntry = BATableAllocOriEntry(pAd, &Idx);
+ if (pBAEntry == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ADDBA - MlmeADDBAAction() allocate BA session failed \n"));
+ return;
+ }
+ }
+ else
+ {
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+ }
+
+ if (pBAEntry->ORI_BA_Status >= Originator_WaitRes)
+ {
+ return;
+ }
+
+ pEntry->BAOriWcidArray[TID] = Idx;
+
+ // Initialize BA session
+ pBAEntry->ORI_BA_Status = Originator_WaitRes;
+ pBAEntry->Wcid = pEntry->Aid;
+ pBAEntry->BAWinSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
+ pBAEntry->Sequence = BA_ORI_INIT_SEQ;
+ pBAEntry->Token = 1; // (2008-01-21) Jan Lee recommends it - this token can't be 0
+ pBAEntry->TID = TID;
+ pBAEntry->TimeOutValue = TimeOut;
+ pBAEntry->pAdapter = pAd;
+
+ DBGPRINT(RT_DEBUG_TRACE,("Send AddBA to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d isForced:%d Wcid:%d\n"
+ ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
+ ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
+ ,TID,isForced,pEntry->Aid));
+
+ if (!(pEntry->TXBAbitmap & (1<<TID)))
+ {
+ RTMPInitTimer(pAd, &pBAEntry->ORIBATimer, GET_TIMER_FUNCTION(BAOriSessionSetupTimeout), pBAEntry, FALSE);
+ }
+ else
+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+
+ // set timer to send ADDBA request
+ RTMPSetTimer(&pBAEntry->ORIBATimer, DelayTime);
+}
+
+VOID BAOriSessionAdd(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PFRAME_ADDBA_RSP pFrame)
+{
+ BA_ORI_ENTRY *pBAEntry = NULL;
+ BOOLEAN Cancelled;
+ UCHAR TID;
+ USHORT Idx;
+ PUCHAR pOutBuffer2 = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ FRAME_BAR FrameBar;
+
+ TID = pFrame->BaParm.TID;
+ Idx = pEntry->BAOriWcidArray[TID];
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+
+ // Start fill in parameters.
+ if ((Idx !=0) && (pBAEntry->TID == TID) && (pBAEntry->ORI_BA_Status == Originator_WaitRes))
+ {
+ pBAEntry->BAWinSize = min(pBAEntry->BAWinSize, ((UCHAR)pFrame->BaParm.BufSize));
+ BA_MaxWinSizeReasign(pAd, pEntry, &pBAEntry->BAWinSize);
+
+ pBAEntry->TimeOutValue = pFrame->TimeOutValue;
+ pBAEntry->ORI_BA_Status = Originator_Done;
+ // reset sequence number
+ pBAEntry->Sequence = BA_ORI_INIT_SEQ;
+ // Set Bitmap flag.
+ pEntry->TXBAbitmap |= (1<<TID);
+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+
+ pBAEntry->ORIBATimer.TimerValue = 0; //pFrame->TimeOutValue;
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s : TXBAbitmap = %x, BAWinSize = %d, TimeOut = %ld\n", __FUNCTION__, pEntry->TXBAbitmap,
+ pBAEntry->BAWinSize, pBAEntry->ORIBATimer.TimerValue));
+
+ // SEND BAR ;
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer2); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - BAOriSessionAdd() allocate memory failed \n"));
+ return;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ BarHeaderInit(pAd, &FrameBar, pAd->MacTab.Content[pBAEntry->Wcid].Addr, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+
+ FrameBar.StartingSeq.field.FragNum = 0; // make sure sequence not clear in DEL function.
+ FrameBar.StartingSeq.field.StartSeq = pBAEntry->Sequence; // make sure sequence not clear in DEL funciton.
+ FrameBar.BarControl.TID = pBAEntry->TID; // make sure sequence not clear in DEL funciton.
+ MakeOutgoingFrame(pOutBuffer2, &FrameLen,
+ sizeof(FRAME_BAR), &FrameBar,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer2, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer2);
+
+
+ if (pBAEntry->ORIBATimer.TimerValue)
+ RTMPSetTimer(&pBAEntry->ORIBATimer, pBAEntry->ORIBATimer.TimerValue); // in mSec
+ }
+}
+
+BOOLEAN BARecSessionAdd(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PFRAME_ADDBA_REQ pFrame)
+{
+ BA_REC_ENTRY *pBAEntry = NULL;
+ BOOLEAN Status = TRUE;
+ BOOLEAN Cancelled;
+ USHORT Idx;
+ UCHAR TID;
+ UCHAR BAWinSize;
+ //UINT32 Value;
+ //UINT offset;
+
+
+ ASSERT(pEntry);
+
+ // find TID
+ TID = pFrame->BaParm.TID;
+
+ BAWinSize = min(((UCHAR)pFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+
+ // Intel patch
+ if (BAWinSize == 0)
+ {
+ BAWinSize = 64;
+ }
+
+ Idx = pEntry->BARecWcidArray[TID];
+
+
+ if (Idx == 0)
+ {
+ pBAEntry = BATableAllocRecEntry(pAd, &Idx);
+ }
+ else
+ {
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ // flush all pending reordering mpdus
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s(%ld): Idx = %d, BAWinSize(req %d) = %d\n", __FUNCTION__, pAd->BATable.numAsRecipient, Idx,
+ pFrame->BaParm.BufSize, BAWinSize));
+
+ // Start fill in parameters.
+ if (pBAEntry != NULL)
+ {
+ ASSERT(pBAEntry->list.qlen == 0);
+
+ pBAEntry->REC_BA_Status = Recipient_HandleRes;
+ pBAEntry->BAWinSize = BAWinSize;
+ pBAEntry->Wcid = pEntry->Aid;
+ pBAEntry->TID = TID;
+ pBAEntry->TimeOutValue = pFrame->TimeOutValue;
+ pBAEntry->REC_BA_Status = Recipient_Accept;
+ // initial sequence number
+ pBAEntry->LastIndSeq = RESET_RCV_SEQ; //pFrame->BaStartSeq.field.StartSeq;
+
+ printk("Start Seq = %08x\n", pFrame->BaStartSeq.field.StartSeq);
+
+ if (pEntry->RXBAbitmap & (1<<TID))
+ {
+ RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+ }
+ else
+ {
+ RTMPInitTimer(pAd, &pBAEntry->RECBATimer, GET_TIMER_FUNCTION(BARecSessionIdleTimeout), pBAEntry, TRUE);
+ }
+
+ // Set Bitmap flag.
+ pEntry->RXBAbitmap |= (1<<TID);
+ pEntry->BARecWcidArray[TID] = Idx;
+
+ pEntry->BADeclineBitmap &= ~(1<<TID);
+
+ // Set BA session mask in WCID table.
+ RT28XX_ADD_BA_SESSION_TO_ASIC(pAd, pEntry->Aid, TID);
+
+ DBGPRINT(RT_DEBUG_TRACE,("MACEntry[%d]RXBAbitmap = 0x%x. BARecWcidArray=%d\n",
+ pEntry->Aid, pEntry->RXBAbitmap, pEntry->BARecWcidArray[TID]));
+ }
+ else
+ {
+ Status = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE,("Can't Accept ADDBA for %02x:%02x:%02x:%02x:%02x:%02x TID = %d\n",
+ PRINT_MAC(pEntry->Addr), TID));
+ }
+ return(Status);
+}
+
+
+BA_REC_ENTRY *BATableAllocRecEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx)
+{
+ int i;
+ BA_REC_ENTRY *pBAEntry = NULL;
+
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ if (pAd->BATable.numAsRecipient >= MAX_BARECI_SESSION)
+ {
+ printk("BA Recipeint Session (%ld) > %d\n", pAd->BATable.numAsRecipient,
+ MAX_BARECI_SESSION);
+ goto done;
+ }
+
+ // reserve idx 0 to identify BAWcidArray[TID] as empty
+ for (i=1; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ pBAEntry =&pAd->BATable.BARecEntry[i];
+ if ((pBAEntry->REC_BA_Status == Recipient_NONE))
+ {
+ // get one
+ pAd->BATable.numAsRecipient++;
+ pBAEntry->REC_BA_Status = Recipient_USED;
+ *Idx = i;
+ break;
+ }
+ }
+
+done:
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ return pBAEntry;
+}
+
+BA_ORI_ENTRY *BATableAllocOriEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Idx)
+{
+ int i;
+ BA_ORI_ENTRY *pBAEntry = NULL;
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ if (pAd->BATable.numAsOriginator >= (MAX_LEN_OF_BA_ORI_TABLE))
+ {
+ goto done;
+ }
+
+ // reserve idx 0 to identify BAWcidArray[TID] as empty
+ for (i=1; i<MAX_LEN_OF_BA_ORI_TABLE; i++)
+ {
+ pBAEntry =&pAd->BATable.BAOriEntry[i];
+ if ((pBAEntry->ORI_BA_Status == Originator_NONE))
+ {
+ // get one
+ pAd->BATable.numAsOriginator++;
+ pBAEntry->ORI_BA_Status = Originator_USED;
+ pBAEntry->pAdapter = pAd;
+ *Idx = i;
+ break;
+ }
+ }
+
+done:
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ return pBAEntry;
+}
+
+
+VOID BATableFreeOriEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Idx)
+{
+ BA_ORI_ENTRY *pBAEntry = NULL;
+ MAC_TABLE_ENTRY *pEntry;
+
+
+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
+ return;
+
+ pBAEntry =&pAd->BATable.BAOriEntry[Idx];
+
+ if (pBAEntry->ORI_BA_Status != Originator_NONE)
+ {
+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+ pEntry->BAOriWcidArray[pBAEntry->TID] = 0;
+
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+ if (pBAEntry->ORI_BA_Status == Originator_Done)
+ {
+ pEntry->TXBAbitmap &= (~(1<<(pBAEntry->TID) ));
+ DBGPRINT(RT_DEBUG_TRACE, ("BATableFreeOriEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
+ // Erase Bitmap flag.
+ }
+
+ ASSERT(pAd->BATable.numAsOriginator != 0);
+
+ pAd->BATable.numAsOriginator -= 1;
+
+ pBAEntry->ORI_BA_Status = Originator_NONE;
+ pBAEntry->Token = 0;
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ }
+}
+
+
+VOID BATableFreeRecEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Idx)
+{
+ BA_REC_ENTRY *pBAEntry = NULL;
+ MAC_TABLE_ENTRY *pEntry;
+
+
+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_REC_TABLE))
+ return;
+
+ pBAEntry =&pAd->BATable.BARecEntry[Idx];
+
+ if (pBAEntry->REC_BA_Status != Recipient_NONE)
+ {
+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+ pEntry->BARecWcidArray[pBAEntry->TID] = 0;
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ ASSERT(pAd->BATable.numAsRecipient != 0);
+
+ pAd->BATable.numAsRecipient -= 1;
+
+ pBAEntry->REC_BA_Status = Recipient_NONE;
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ }
+}
+
+
+VOID BAOriSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive,
+ IN BOOLEAN bForceSend)
+{
+ ULONG Idx = 0;
+ BA_ORI_ENTRY *pBAEntry;
+ BOOLEAN Cancelled;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ return;
+ }
+
+ //
+ // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
+ //
+ Idx = pAd->MacTab.Content[Wcid].BAOriWcidArray[TID];
+ if ((Idx == 0) || (Idx >= MAX_LEN_OF_BA_ORI_TABLE))
+ {
+ if (bForceSend == TRUE)
+ {
+ // force send specified TID DelBA
+ MLME_DELBA_REQ_STRUCT DelbaReq;
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+ DelbaReq.Wcid = Wcid;
+ DelbaReq.TID = TID;
+ DelbaReq.Initiator = ORIGINATOR;
+#if 1
+ Elem->MsgLen = sizeof(DelbaReq);
+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+ MlmeDELBAAction(pAd, Elem);
+ kfree(Elem);
+#else
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+#endif
+ }
+
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
+
+ pBAEntry = &pAd->BATable.BAOriEntry[Idx];
+ DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, ORI_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->ORI_BA_Status));
+ //
+ // Prepare DelBA action frame and send to the peer.
+ //
+ if ((bPassive == FALSE) && (TID == pBAEntry->TID) && (pBAEntry->ORI_BA_Status == Originator_Done))
+ {
+ MLME_DELBA_REQ_STRUCT DelbaReq;
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+ DelbaReq.Wcid = Wcid;
+ DelbaReq.TID = pBAEntry->TID;
+ DelbaReq.Initiator = ORIGINATOR;
+#if 1
+ Elem->MsgLen = sizeof(DelbaReq);
+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+ MlmeDELBAAction(pAd, Elem);
+ kfree(Elem);
+#else
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+#endif
+ }
+ RTMPCancelTimer(&pBAEntry->ORIBATimer, &Cancelled);
+ BATableFreeOriEntry(pAd, Idx);
+
+ if (bPassive)
+ {
+ //BAOriSessionSetUp(pAd, &pAd->MacTab.Content[Wcid], TID, 0, 10000, TRUE);
+ }
+}
+
+VOID BARecSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive)
+{
+ ULONG Idx = 0;
+ BA_REC_ENTRY *pBAEntry;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ {
+ return;
+ }
+
+ //
+ // Locate corresponding BA Originator Entry in BA Table with the (pAddr,TID).
+ //
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ if (Idx == 0)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s===>Wcid=%d.TID=%d \n", __FUNCTION__, Wcid, TID));
+
+
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ DBGPRINT(RT_DEBUG_TRACE,("\t===>Idx = %ld, Wcid=%d.TID=%d, REC_BA_Status = %d \n", Idx, Wcid, TID, pBAEntry->REC_BA_Status));
+ //
+ // Prepare DelBA action frame and send to the peer.
+ //
+ if ((TID == pBAEntry->TID) && (pBAEntry->REC_BA_Status == Recipient_Accept))
+ {
+ MLME_DELBA_REQ_STRUCT DelbaReq;
+ BOOLEAN Cancelled;
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+ //ULONG offset;
+ //UINT32 VALUE;
+
+ RTMPCancelTimer(&pBAEntry->RECBATimer, &Cancelled);
+
+ //
+ // 1. Send DELBA Action Frame
+ //
+ if (bPassive == FALSE)
+ {
+ NdisZeroMemory(&DelbaReq, sizeof(DelbaReq));
+ NdisZeroMemory(Elem, sizeof(MLME_QUEUE_ELEM));
+
+ COPY_MAC_ADDR(DelbaReq.Addr, pAd->MacTab.Content[Wcid].Addr);
+ DelbaReq.Wcid = Wcid;
+ DelbaReq.TID = TID;
+ DelbaReq.Initiator = RECIPIENT;
+#if 1
+ Elem->MsgLen = sizeof(DelbaReq);
+ NdisMoveMemory(Elem->Msg, &DelbaReq, sizeof(DelbaReq));
+ MlmeDELBAAction(pAd, Elem);
+ kfree(Elem);
+#else
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ORI_DELBA_CATE, sizeof(MLME_DELBA_REQ_STRUCT), (PVOID)&DelbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+#endif
+ }
+
+
+ //
+ // 2. Free resource of BA session
+ //
+ // flush all pending reordering mpdus
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+
+ NdisAcquireSpinLock(&pAd->BATabLock);
+
+ // Erase Bitmap flag.
+ pBAEntry->LastIndSeq = RESET_RCV_SEQ;
+ pBAEntry->BAWinSize = 0;
+ // Erase Bitmap flag at software mactable
+ pAd->MacTab.Content[Wcid].RXBAbitmap &= (~(1<<(pBAEntry->TID)));
+ pAd->MacTab.Content[Wcid].BARecWcidArray[TID] = 0;
+
+ RT28XX_DEL_BA_SESSION_FROM_ASIC(pAd, Wcid, TID);
+
+ NdisReleaseSpinLock(&pAd->BATabLock);
+
+ }
+
+ BATableFreeRecEntry(pAd, Idx);
+}
+
+VOID BASessionTearDownALL(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid)
+{
+ int i;
+
+ for (i=0; i<NUM_OF_TID; i++)
+ {
+ BAOriSessionTearDown(pAd, Wcid, i, FALSE, FALSE);
+ BARecSessionTearDown(pAd, Wcid, i, FALSE);
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Retry sending ADDBA Reqest.
+
+ IRQL = DISPATCH_LEVEL
+
+ Parametrs:
+ p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+ FALSE , then continue indicaterx at this moment.
+ ==========================================================================
+ */
+VOID BAOriSessionSetupTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ BA_ORI_ENTRY *pBAEntry = (BA_ORI_ENTRY *)FunctionContext;
+ MAC_TABLE_ENTRY *pEntry;
+ PRTMP_ADAPTER pAd;
+
+ if (pBAEntry == NULL)
+ return;
+
+ pAd = pBAEntry->pAdapter;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Do nothing if monitor mode is on
+ if (MONITOR_ON(pAd))
+ return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+ // Nothing to do in ATE mode.
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ pEntry = &pAd->MacTab.Content[pBAEntry->Wcid];
+
+ if ((pBAEntry->ORI_BA_Status == Originator_WaitRes) && (pBAEntry->Token < ORI_SESSION_MAX_RETRY))
+ {
+ MLME_ADDBA_REQ_STRUCT AddbaReq;
+
+ NdisZeroMemory(&AddbaReq, sizeof(AddbaReq));
+ COPY_MAC_ADDR(AddbaReq.pAddr, pEntry->Addr);
+ AddbaReq.Wcid = (UCHAR)(pEntry->Aid);
+ AddbaReq.TID = pBAEntry->TID;
+ AddbaReq.BaBufSize = pAd->CommonCfg.BACapability.field.RxBAWinLimit;
+ AddbaReq.TimeOutValue = 0;
+ AddbaReq.Token = pBAEntry->Token;
+ MlmeEnqueue(pAd, ACTION_STATE_MACHINE, MT2_MLME_ADD_BA_CATE, sizeof(MLME_ADDBA_REQ_STRUCT), (PVOID)&AddbaReq);
+ RT28XX_MLME_HANDLER(pAd);
+ //DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) : Send ADD BA again\n", pBAEntry->Token));
+
+ DBGPRINT(RT_DEBUG_TRACE,("BA Ori Session Timeout(%d) to %02x:%02x:%02x:%02x:%02x:%02x Tid:%d Wcid:%d\n"
+ ,pBAEntry->Token
+ ,pEntry->Addr[0],pEntry->Addr[1],pEntry->Addr[2]
+ ,pEntry->Addr[3],pEntry->Addr[4],pEntry->Addr[5]
+ ,pBAEntry->TID,pEntry->Aid));
+
+ pBAEntry->Token++;
+ RTMPSetTimer(&pBAEntry->ORIBATimer, ORI_BA_SESSION_TIMEOUT);
+ }
+ else
+ {
+ BATableFreeOriEntry(pAd, pEntry->BAOriWcidArray[pBAEntry->TID]);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Retry sending ADDBA Reqest.
+
+ IRQL = DISPATCH_LEVEL
+
+ Parametrs:
+ p8023Header: if this is already 802.3 format, p8023Header is NULL
+
+ Return : TRUE if put into rx reordering buffer, shouldn't indicaterxhere.
+ FALSE , then continue indicaterx at this moment.
+ ==========================================================================
+ */
+VOID BARecSessionIdleTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+
+ BA_REC_ENTRY *pBAEntry = (BA_REC_ENTRY *)FunctionContext;
+ PRTMP_ADAPTER pAd;
+ ULONG Now32;
+
+ if (pBAEntry == NULL)
+ return;
+
+ if ((pBAEntry->REC_BA_Status == Recipient_Accept))
+ {
+ NdisGetSystemUpTime(&Now32);
+
+ if (RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer + REC_BA_SESSION_IDLE_TIMEOUT)))
+ {
+ pAd = pBAEntry->pAdapter;
+ // flush all pending reordering mpdus
+ ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ printk("%ld: REC BA session Timeout\n", Now32);
+ }
+ }
+}
+
+
+VOID PeerAddBAReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ // 7.4.4.1
+ //ULONG Idx;
+ UCHAR Status = 1;
+ UCHAR pAddr[6];
+ FRAME_ADDBA_RSP ADDframe;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ PFRAME_ADDBA_REQ pAddreqFrame = NULL;
+ //UCHAR BufSize;
+ ULONG FrameLen;
+ PULONG ptemp;
+ PMAC_TABLE_ENTRY pMacEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s ==> (Wcid = %d)\n", __FUNCTION__, Elem->Wcid));
+
+ //hex_dump("AddBAReq", Elem->Msg, Elem->MsgLen);
+
+ //ADDBA Request from unknown peer, ignore this.
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ pMacEntry = &pAd->MacTab.Content[Elem->Wcid];
+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerAddBAReqAction----> \n"));
+ ptemp = (PULONG)Elem->Msg;
+ //DBGPRINT_RAW(RT_DEBUG_EMU, ("%08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x:: %08x\n", *(ptemp), *(ptemp+1), *(ptemp+2), *(ptemp+3), *(ptemp+4), *(ptemp+5), *(ptemp+6), *(ptemp+7), *(ptemp+8)));
+
+ if (PeerAddBAReqActionSanity(pAd, Elem->Msg, Elem->MsgLen, pAddr))
+ {
+
+ if ((pAd->CommonCfg.bBADecline == FALSE) && IS_HT_STA(pMacEntry))
+ {
+ pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
+ printk("Rcv Wcid(%d) AddBAReq\n", Elem->Wcid);
+ if (BARecSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pAddreqFrame))
+ Status = 0;
+ else
+ Status = 38; // more parameters have invalid values
+ }
+ else
+ {
+ Status = 37; // the request has been declined.
+ }
+ }
+
+ if (pAd->MacTab.Content[Elem->Wcid].ValidAsCLI)
+ ASSERT(pAd->MacTab.Content[Elem->Wcid].Sst == SST_ASSOC);
+
+ pAddreqFrame = (PFRAME_ADDBA_REQ)(&Elem->Msg[0]);
+ // 2. Always send back ADDBA Response
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ACTION - PeerBAAction() allocate memory failed \n"));
+ return;
+ }
+
+ NdisZeroMemory(&ADDframe, sizeof(FRAME_ADDBA_RSP));
+ // 2-1. Prepare ADDBA Response frame.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ADHOC_ON(pAd))
+ ActHeaderInit(pAd, &ADDframe.Hdr, pAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ else
+ ActHeaderInit(pAd, &ADDframe.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAddr);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ ADDframe.Category = CATEGORY_BA;
+ ADDframe.Action = ADDBA_RESP;
+ ADDframe.Token = pAddreqFrame->Token;
+ // What is the Status code?? need to check.
+ ADDframe.StatusCode = Status;
+ ADDframe.BaParm.BAPolicy = IMMED_BA;
+ ADDframe.BaParm.AMSDUSupported = 0;
+ ADDframe.BaParm.TID = pAddreqFrame->BaParm.TID;
+ ADDframe.BaParm.BufSize = min(((UCHAR)pAddreqFrame->BaParm.BufSize), (UCHAR)pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+ if (ADDframe.BaParm.BufSize == 0)
+ {
+ ADDframe.BaParm.BufSize = 64;
+ }
+ ADDframe.TimeOutValue = 0; //pAddreqFrame->TimeOutValue;
+
+ *(USHORT *)(&ADDframe.BaParm) = cpu2le16(*(USHORT *)(&ADDframe.BaParm));
+ ADDframe.StatusCode = cpu2le16(ADDframe.StatusCode);
+ ADDframe.TimeOutValue = cpu2le16(ADDframe.TimeOutValue);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_ADDBA_RSP), &ADDframe,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(%d): TID(%d), BufSize(%d) <== \n", __FUNCTION__, Elem->Wcid, ADDframe.BaParm.TID,
+ ADDframe.BaParm.BufSize));
+}
+
+
+VOID PeerAddBARspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ //UCHAR Idx, i;
+ //PUCHAR pOutBuffer = NULL;
+ PFRAME_ADDBA_RSP pFrame = NULL;
+ //PBA_ORI_ENTRY pBAEntry;
+
+ //ADDBA Response from unknown peer, ignore this.
+ if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s ==> Wcid(%d)\n", __FUNCTION__, Elem->Wcid));
+
+ //hex_dump("PeerAddBARspAction()", Elem->Msg, Elem->MsgLen);
+
+ if (PeerAddBARspActionSanity(pAd, Elem->Msg, Elem->MsgLen))
+ {
+ pFrame = (PFRAME_ADDBA_RSP)(&Elem->Msg[0]);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\t\t StatusCode = %d\n", pFrame->StatusCode));
+ switch (pFrame->StatusCode)
+ {
+ case 0:
+ // I want a BAsession with this peer as an originator.
+ BAOriSessionAdd(pAd, &pAd->MacTab.Content[Elem->Wcid], pFrame);
+ break;
+ default:
+ // check status == USED ???
+ BAOriSessionTearDown(pAd, Elem->Wcid, pFrame->BaParm.TID, TRUE, FALSE);
+ break;
+ }
+ // Rcv Decline StatusCode
+ if ((pFrame->StatusCode == 37)
+#ifdef CONFIG_STA_SUPPORT
+ || ((pAd->OpMode == OPMODE_STA) && STA_TGN_WIFI_ON(pAd) && (pFrame->StatusCode != 0))
+#endif // CONFIG_STA_SUPPORT //
+ )
+ {
+ pAd->MacTab.Content[Elem->Wcid].BADeclineBitmap |= 1<<pFrame->BaParm.TID;
+ }
+ }
+}
+
+VOID PeerDelBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ //UCHAR Idx;
+ //PUCHAR pOutBuffer = NULL;
+ PFRAME_DELBA_REQ pDelFrame = NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE,("%s ==>\n", __FUNCTION__));
+ //DELBA Request from unknown peer, ignore this.
+ if (PeerDelBAActionSanity(pAd, Elem->Wcid, Elem->Msg, Elem->MsgLen))
+ {
+ pDelFrame = (PFRAME_DELBA_REQ)(&Elem->Msg[0]);
+ if (pDelFrame->DelbaParm.Initiator == ORIGINATOR)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> ORIGINATOR\n"));
+ BARecSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("BA - PeerDelBAAction----> RECIPIENT, Reason = %d\n", pDelFrame->ReasonCode));
+ //hex_dump("DelBA Frame", pDelFrame, Elem->MsgLen);
+ BAOriSessionTearDown(pAd, Elem->Wcid, pDelFrame->DelbaParm.TID, TRUE, FALSE);
+ }
+ }
+}
+
+
+BOOLEAN CntlEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG MsgLen,
+ IN PFRAME_BA_REQ pMsg)
+{
+ PFRAME_BA_REQ pFrame = pMsg;
+ //PRTMP_REORDERBUF pBuffer;
+ //PRTMP_REORDERBUF pDmaBuf;
+ PBA_REC_ENTRY pBAEntry;
+ //BOOLEAN Result;
+ ULONG Idx;
+ //UCHAR NumRxPkt;
+ UCHAR TID;//, i;
+
+ TID = (UCHAR)pFrame->BARControl.TID;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s(): BAR-Wcid(%ld), Tid (%d)\n", __FUNCTION__, Wcid, TID));
+ //hex_dump("BAR", (PCHAR) pFrame, MsgLen);
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+ else if (MsgLen != sizeof(FRAME_BA_REQ))
+ {
+ DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+ else if (MsgLen != sizeof(FRAME_BA_REQ))
+ {
+ DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+
+ if ((Wcid < MAX_LEN_OF_MAC_TABLE) && (TID < 8))
+ {
+ // if this receiving packet is from SA that is in our OriEntry. Since WCID <9 has direct mapping. no need search.
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BAR(%ld) : Tid (%d) - %04x:%04x\n", Wcid, TID, pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq ));
+
+ if (SEQ_SMALLER(pBAEntry->LastIndSeq, pFrame->BAStartingSeq.field.StartSeq, MAXSEQ))
+ {
+ //printk("BAR Seq = %x, LastIndSeq = %x\n", pFrame->BAStartingSeq.field.StartSeq, pBAEntry->LastIndSeq);
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, pFrame->BAStartingSeq.field.StartSeq);
+ pBAEntry->LastIndSeq = (pFrame->BAStartingSeq.field.StartSeq == 0) ? MAXSEQ :(pFrame->BAStartingSeq.field.StartSeq -1);
+ }
+ //ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ return TRUE;
+}
+
+/*
+Description : Send PSMP Action frame If PSMP mode switches.
+*/
+VOID SendPSMPAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR Psmp)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ //ULONG Idx;
+ FRAME_PSMP_ACTION Frame;
+ ULONG FrameLen;
+#ifdef RT30xx
+ UCHAR bbpdata=0;
+ UINT32 macdata;
+#endif // RT30xx //
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("BA - MlmeADDBAAction() allocate memory failed \n"));
+ return;
+ }
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ActHeaderInit(pAd, &Frame.Hdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->MacTab.Content[Wcid].Addr);
+#endif // CONFIG_STA_SUPPORT //
+
+ Frame.Category = CATEGORY_HT;
+ Frame.Action = SMPS_ACTION;
+ switch (Psmp)
+ {
+ case MMPS_ENABLE:
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ // disable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+ bbpdata &= ~(0x04); //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+ // disable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata &= ~(0x09); //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+ Frame.Psmp = 0;
+ break;
+ case MMPS_DYNAMIC:
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ // enable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+ bbpdata |= 0x04; //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+ // enable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata |= 0x09; //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+ Frame.Psmp = 3;
+ break;
+ case MMPS_STATIC:
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ // enable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &bbpdata);
+ bbpdata |= 0x04; //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, bbpdata);
+
+ // enable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata |= 0x09; //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+ Frame.Psmp = 1;
+ break;
+ }
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(FRAME_PSMP_ACTION), &Frame,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_ERROR,("HT - SendPSMPAction( %d ) \n", Frame.Psmp));
+}
+
+
+#define RADIO_MEASUREMENT_REQUEST_ACTION 0
+
+typedef struct PACKED
+{
+ UCHAR RegulatoryClass;
+ UCHAR ChannelNumber;
+ USHORT RandomInterval;
+ USHORT MeasurementDuration;
+ UCHAR MeasurementMode;
+ UCHAR BSSID[MAC_ADDR_LEN];
+ UCHAR ReportingCondition;
+ UCHAR Threshold;
+ UCHAR SSIDIE[2]; // 2 byte
+} BEACON_REQUEST;
+
+typedef struct PACKED
+{
+ UCHAR ID;
+ UCHAR Length;
+ UCHAR Token;
+ UCHAR RequestMode;
+ UCHAR Type;
+} MEASUREMENT_REQ;
+
+
+
+
+void convert_reordering_packet_to_preAMSDU_or_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ PNDIS_PACKET pRxPkt;
+ UCHAR Header802_3[LENGTH_802_3];
+
+ // 1. get 802.3 Header
+ // 2. remove LLC
+ // a. pointer pRxBlk->pData to payload
+ // b. modify pRxBlk->DataSize
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+ ASSERT(pRxBlk->pRxPacket);
+ pRxPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+ RTPKT_TO_OSPKT(pRxPkt)->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ RTPKT_TO_OSPKT(pRxPkt)->data = pRxBlk->pData;
+ RTPKT_TO_OSPKT(pRxPkt)->len = pRxBlk->DataSize;
+ RTPKT_TO_OSPKT(pRxPkt)->tail = RTPKT_TO_OSPKT(pRxPkt)->data + RTPKT_TO_OSPKT(pRxPkt)->len;
+
+ //
+ // copy 802.3 header, if necessary
+ //
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef LINUX
+ NdisMoveMemory(skb_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
+#endif
+#ifdef UCOS
+ NdisMoveMemory(net_pkt_push(pRxPkt, LENGTH_802_3), Header802_3, LENGTH_802_3);
+#endif
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+}
+
+
+#define INDICATE_LEGACY_OR_AMSDU(_pAd, _pRxBlk, _fromWhichBSSID) \
+ do \
+ { \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_AMSDU)) \
+ { \
+ Indicate_AMSDU_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
+ } \
+ else if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_EAP)) \
+ { \
+ Indicate_EAPOL_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
+ } \
+ else \
+ { \
+ Indicate_Legacy_Packet(_pAd, _pRxBlk, _fromWhichBSSID); \
+ } \
+ } while (0);
+
+
+
+static VOID ba_enqueue_reordering_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ struct reordering_mpdu *mpdu_blk;
+ UINT16 Sequence = (UINT16) pRxBlk->pHeader->Sequence;
+
+ mpdu_blk = ba_mpdu_blk_alloc(pAd);
+ if (mpdu_blk != NULL)
+ {
+ // Write RxD buffer address & allocated buffer length
+ NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
+
+ mpdu_blk->Sequence = Sequence;
+
+ mpdu_blk->bAMSDU = RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU);
+
+ convert_reordering_packet_to_preAMSDU_or_802_3_packet(pAd, pRxBlk, FromWhichBSSID);
+
+ STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
+
+ //
+ // it is necessary for reordering packet to record
+ // which BSS it come from
+ //
+ RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
+
+ mpdu_blk->pPacket = pRxBlk->pRxPacket;
+
+ if (ba_reordering_mpdu_insertsorted(&pBAEntry->list, mpdu_blk) == FALSE)
+ {
+ // had been already within reordering list
+ // don't indicate
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_SUCCESS);
+ ba_mpdu_blk_free(pAd, mpdu_blk);
+ }
+
+ ASSERT((0<= pBAEntry->list.qlen) && (pBAEntry->list.qlen <= pBAEntry->BAWinSize));
+ NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!! (%d) Can't allocate reordering mpdu blk\n",
+ pBAEntry->list.qlen));
+ /*
+ * flush all pending reordering mpdus
+ * and receving mpdu to upper layer
+ * make tcp/ip to take care reordering mechanism
+ */
+ //ba_refresh_reordering_mpdus(pAd, pBAEntry);
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, Sequence);
+
+ pBAEntry->LastIndSeq = Sequence;
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Indicate this packet to upper layer or put it into reordering buffer
+
+ Parametrs:
+ pRxBlk : carry necessary packet info 802.11 format
+ FromWhichBSSID : the packet received from which BSS
+
+ Return :
+ none
+
+ Note :
+ the packet queued into reordering buffer need to cover to 802.3 format
+ or pre_AMSDU format
+ ==========================================================================
+ */
+
+VOID Indicate_AMPDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ USHORT Idx;
+ PBA_REC_ENTRY pBAEntry = NULL;
+ UINT16 Sequence = pRxBlk->pHeader->Sequence;
+ ULONG Now32;
+ UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->TID;
+
+
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU) && (pRxBlk->DataSize > MAX_RX_PKT_LEN))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ if (Idx == 0)
+ {
+ /* Rec BA Session had been torn down */
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ }
+ else
+ {
+ // impossible !!!
+ ASSERT(0);
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ ASSERT(pBAEntry);
+
+ // update last rx time
+ NdisGetSystemUpTime(&Now32);
+
+ pBAEntry->rcvSeq = Sequence;
+
+
+ ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+ pBAEntry->LastIndSeqAtTimer = Now32;
+
+ //
+ // Reset Last Indicate Sequence
+ //
+ if (pBAEntry->LastIndSeq == RESET_RCV_SEQ)
+ {
+ ASSERT((pBAEntry->list.qlen == 0) && (pBAEntry->list.next == NULL));
+
+ // reset rcv sequence of BA session
+ pBAEntry->LastIndSeq = Sequence;
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+
+
+ //
+ // I. Check if in order.
+ //
+ if (SEQ_STEPONE(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
+ {
+ USHORT LastIndSeq;
+
+ pBAEntry->LastIndSeq = Sequence;
+ INDICATE_LEGACY_OR_AMSDU(pAd, pRxBlk, FromWhichBSSID);
+ LastIndSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
+ if (LastIndSeq != RESET_RCV_SEQ)
+ {
+ pBAEntry->LastIndSeq = LastIndSeq;
+ }
+ pBAEntry->LastIndSeqAtTimer = Now32;
+ }
+ //
+ // II. Drop Duplicated Packet
+ //
+ else if (Sequence == pBAEntry->LastIndSeq)
+ {
+
+ // drop and release packet
+ pBAEntry->nDropPacket++;
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ //
+ // III. Drop Old Received Packet
+ //
+ else if (SEQ_SMALLER(Sequence, pBAEntry->LastIndSeq, MAXSEQ))
+ {
+
+ // drop and release packet
+ pBAEntry->nDropPacket++;
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ //
+ // IV. Receive Sequence within Window Size
+ //
+ else if (SEQ_SMALLER(Sequence, (((pBAEntry->LastIndSeq+pBAEntry->BAWinSize+1)) & MAXSEQ), MAXSEQ))
+ {
+ ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+ }
+ //
+ // V. Receive seq surpasses Win(lastseq + nMSDU). So refresh all reorder buffer
+ //
+ else
+ {
+ LONG WinStartSeq, TmpSeq;
+
+
+ TmpSeq = Sequence - (pBAEntry->BAWinSize) -1;
+ if (TmpSeq < 0)
+ {
+ TmpSeq = (MAXSEQ+1) + TmpSeq;
+ }
+ WinStartSeq = (TmpSeq+1) & MAXSEQ;
+ ba_indicate_reordering_mpdus_le_seq(pAd, pBAEntry, WinStartSeq);
+ pBAEntry->LastIndSeq = WinStartSeq; //TmpSeq;
+
+ pBAEntry->LastIndSeqAtTimer = Now32;
+
+ ba_enqueue_reordering_packet(pAd, pBAEntry, pRxBlk, FromWhichBSSID);
+
+ TmpSeq = ba_indicate_reordering_mpdus_in_order(pAd, pBAEntry, pBAEntry->LastIndSeq);
+ if (TmpSeq != RESET_RCV_SEQ)
+ {
+ pBAEntry->LastIndSeq = TmpSeq;
+ }
+ }
+}
+
+#endif // DOT11_N_SUPPORT //
+
diff --git a/drivers/staging/rt3070/common/cmm_data.c b/drivers/staging/rt3070/common/cmm_data.c
new file mode 100644
index 00000000000..85f92b9f83d
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data.c
@@ -0,0 +1,2827 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+*/
+
+#include "../rt_config.h"
+
+#define MAX_TX_IN_TBTT (16)
+
+
+UCHAR SNAP_802_1H[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
+UCHAR SNAP_BRIDGE_TUNNEL[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
+// Add Cisco Aironet SNAP heade for CCX2 support
+UCHAR SNAP_AIRONET[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x00};
+UCHAR CKIP_LLC_SNAP[] = {0xaa, 0xaa, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
+UCHAR EAPOL_LLC_SNAP[]= {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e};
+UCHAR EAPOL[] = {0x88, 0x8e};
+UCHAR TPID[] = {0x81, 0x00}; /* VLAN related */
+
+UCHAR IPX[] = {0x81, 0x37};
+UCHAR APPLE_TALK[] = {0x80, 0xf3};
+UCHAR RateIdToPlcpSignal[12] = {
+ 0, /* RATE_1 */ 1, /* RATE_2 */ 2, /* RATE_5_5 */ 3, /* RATE_11 */ // see BBP spec
+ 11, /* RATE_6 */ 15, /* RATE_9 */ 10, /* RATE_12 */ 14, /* RATE_18 */ // see IEEE802.11a-1999 p.14
+ 9, /* RATE_24 */ 13, /* RATE_36 */ 8, /* RATE_48 */ 12 /* RATE_54 */ }; // see IEEE802.11a-1999 p.14
+
+UCHAR OfdmSignalToRateId[16] = {
+ RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 0, 1, 2, 3 respectively
+ RATE_54, RATE_54, RATE_54, RATE_54, // OFDM PLCP Signal = 4, 5, 6, 7 respectively
+ RATE_48, RATE_24, RATE_12, RATE_6, // OFDM PLCP Signal = 8, 9, 10, 11 respectively
+ RATE_54, RATE_36, RATE_18, RATE_9, // OFDM PLCP Signal = 12, 13, 14, 15 respectively
+};
+
+UCHAR OfdmRateToRxwiMCS[12] = {
+ 0, 0, 0, 0,
+ 0, 1, 2, 3, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
+ 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
+};
+UCHAR RxwiMCSToOfdmRate[12] = {
+ RATE_6, RATE_9, RATE_12, RATE_18,
+ RATE_24, RATE_36, RATE_48, RATE_54, // OFDM rate 6,9,12,18 = rxwi mcs 0,1,2,3
+ 4, 5, 6, 7, // OFDM rate 24,36,48,54 = rxwi mcs 4,5,6,7
+};
+
+char* MCSToMbps[] = {"1Mbps","2Mbps","5.5Mbps","11Mbps","06Mbps","09Mbps","12Mbps","18Mbps","24Mbps","36Mbps","48Mbps","54Mbps","MM-0","MM-1","MM-2","MM-3","MM-4","MM-5","MM-6","MM-7","MM-8","MM-9","MM-10","MM-11","MM-12","MM-13","MM-14","MM-15","MM-32","ee1","ee2","ee3"};
+
+UCHAR default_cwmin[]={CW_MIN_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1, CW_MIN_IN_BITS-2};
+//UCHAR default_cwmax[]={CW_MAX_IN_BITS, CW_MAX_IN_BITS, CW_MIN_IN_BITS, CW_MIN_IN_BITS-1};
+UCHAR default_sta_aifsn[]={3,7,2,2};
+
+UCHAR MapUserPriorityToAccessCategory[8] = {QID_AC_BE, QID_AC_BK, QID_AC_BK, QID_AC_BE, QID_AC_VI, QID_AC_VI, QID_AC_VO, QID_AC_VO};
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ API for MLME to transmit management frame to AP (BSS Mode)
+ or station (IBSS Mode)
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to the outgoing 802.11 frame
+ Length Size of outgoing management frame
+
+ Return Value:
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_SUCCESS
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS MiniportMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length)
+{
+ PNDIS_PACKET pPacket;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ ULONG FreeNum;
+ UCHAR IrqState;
+ UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+
+ ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+ QueIdx=3;
+
+ // 2860C use Tx Ring
+
+ IrqState = pAd->irq_disabled;
+
+ do
+ {
+ // Reset is in progress, stop immediately
+ if ( RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ {
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+ // Check Free priority queue
+ // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
+
+ // 2860C use Tx Ring
+ if (pAd->MACVersion == 0x28600100)
+ {
+ FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+ }
+ else
+ {
+ FreeNum = GET_MGMTRING_FREENO(pAd);
+ }
+
+ if ((FreeNum > 0))
+ {
+ // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
+ NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+ break;
+ }
+
+ //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ //pAd->CommonCfg.MlmeRate = RATE_2;
+
+
+ Status = MlmeHardTransmit(pAd, QueIdx, pPacket);
+ if (Status != NDIS_STATUS_SUCCESS)
+ RTMPFreeNdisPacket(pAd, pPacket);
+ }
+ else
+ {
+ pAd->RalinkCounters.MgmtRingFullCount++;
+ DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in MgmtRing, MgmtRingFullCount=%ld!\n",
+ QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+ }
+
+ } while (FALSE);
+
+
+ return Status;
+}
+
+
+
+NDIS_STATUS MlmeDataHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+#define MAX_DATAMM_RETRY 3
+/*
+ ========================================================================
+
+ Routine Description:
+ API for MLME to transmit management frame to AP (BSS Mode)
+ or station (IBSS Mode)
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to the outgoing 802.11 frame
+ Length Size of outgoing management frame
+
+ Return Value:
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_SUCCESS
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS MiniportDataMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length)
+{
+ PNDIS_PACKET pPacket;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ ULONG FreeNum;
+ int retry = 0;
+ UCHAR IrqState;
+ UCHAR rtmpHwHdr[TXINFO_SIZE + TXWI_SIZE]; //RTMP_HW_HDR_LEN];
+
+ ASSERT(Length <= MGMT_DMA_BUFFER_SIZE);
+
+ // 2860C use Tx Ring
+ IrqState = pAd->irq_disabled;
+
+ do
+ {
+ // Reset is in progress, stop immediately
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)||
+ !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ {
+ Status = NDIS_STATUS_FAILURE;
+ break;
+ }
+
+ // Check Free priority queue
+ // Since we use PBF Queue2 for management frame. Its corresponding DMA ring should be using TxRing.
+
+ // 2860C use Tx Ring
+
+ // free Tx(QueIdx) resources
+ FreeNum = GET_TXRING_FREENO(pAd, QueIdx);
+
+ if ((FreeNum > 0))
+ {
+ // We need to reserve space for rtmp hardware header. i.e., TxWI for RT2860 and TxInfo+TxWI for RT2870
+ NdisZeroMemory(&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE));
+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, (PUCHAR)&rtmpHwHdr, (TXINFO_SIZE + TXWI_SIZE), pData, Length);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("MiniportMMRequest (error:: can't allocate NDIS PACKET)\n"));
+ break;
+ }
+
+ //pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ //pAd->CommonCfg.MlmeRate = RATE_2;
+
+
+ Status = MlmeDataHardTransmit(pAd, QueIdx, pPacket);
+ if (Status != NDIS_STATUS_SUCCESS)
+ RTMPFreeNdisPacket(pAd, pPacket);
+ retry = MAX_DATAMM_RETRY;
+ }
+ else
+ {
+ retry ++;
+
+ printk("retry %d\n", retry);
+ pAd->RalinkCounters.MgmtRingFullCount++;
+
+ if (retry >= MAX_DATAMM_RETRY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Qidx(%d), not enough space in DataRing, MgmtRingFullCount=%ld!\n",
+ QueIdx, pAd->RalinkCounters.MgmtRingFullCount));
+ }
+ }
+
+ } while (retry < MAX_DATAMM_RETRY);
+
+
+ return Status;
+}
+
+
+
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware transmit function
+
+ Arguments:
+ pAd Pointer to our adapter
+ pBuffer Pointer to memory of outgoing frame
+ Length Size of outgoing management frame
+
+ Return Value:
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_PENDING
+ NDIS_STATUS_SUCCESS
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS MlmeHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+ return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+
+}
+
+NDIS_STATUS MlmeDataHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ if ((pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+#ifdef CARRIER_DETECTION_SUPPORT
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifdef RT2870
+ return MlmeHardTransmitMgmtRing(pAd,QueIdx,pPacket);
+#endif // RT2870 //
+}
+
+
+
+
+
+NDIS_STATUS MlmeHardTransmitMgmtRing(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ PHEADER_802_11 pHeader_802_11;
+ BOOLEAN bAckRequired, bInsertTimestamp;
+ UCHAR MlmeRate;
+ PTXWI_STRUC pFirstTxWI;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ // Make sure MGMT ring resource won't be used by other threads
+// sample, for IRQ LOCK -> SEM LOCK
+// IrqState = pAd->irq_disabled;
+// if (!IrqState)
+ RTMP_SEM_LOCK(&pAd->MgmtRingLock);
+
+
+ if (pSrcBufVA == NULL)
+ {
+ // The buffer shouldn't be NULL
+// if (!IrqState)
+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // outgoing frame always wakeup PHY to prevent frame lost
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ AsicForceWakeup(pAd, TRUE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pFirstTxWI = (PTXWI_STRUC)(pSrcBufVA + TXINFO_SIZE);
+ pHeader_802_11 = (PHEADER_802_11) (pSrcBufVA + TXINFO_SIZE + TXWI_SIZE); //TXWI_SIZE);
+
+ if (pHeader_802_11->Addr1[0] & 0x01)
+ {
+ MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+ }
+ else
+ {
+ MlmeRate = pAd->CommonCfg.MlmeRate;
+ }
+
+ // Verify Mlme rate for a / g bands.
+ if ((pAd->LatchRfRegs.Channel > 14) && (MlmeRate < RATE_6)) // 11A band
+ MlmeRate = RATE_6;
+
+ if ((pHeader_802_11->FC.Type == BTYPE_DATA) &&
+ (pHeader_802_11->FC.SubType == SUBTYPE_QOS_NULL))
+ {
+ pMacEntry = MacTableLookup(pAd, pHeader_802_11->Addr1);
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Fixed W52 with Activity scan issue in ABG_MIXED and ABGN_MIXED mode.
+ if (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED
+#ifdef DOT11_N_SUPPORT
+ || pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ if (pAd->LatchRfRegs.Channel > 14)
+ pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
+ else
+ pAd->CommonCfg.MlmeTransmit.field.MODE = 0;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ //
+ // Should not be hard code to set PwrMgmt to 0 (PWR_ACTIVE)
+ // Snice it's been set to 0 while on MgtMacHeaderInit
+ // By the way this will cause frame to be send on PWR_SAVE failed.
+ //
+ // pHeader_802_11->FC.PwrMgmt = 0; // (pAd->StaCfg.Psm == PWR_SAVE);
+ //
+ // In WMM-UAPSD, mlme frame should be set psm as power saving but probe request frame
+#ifdef CONFIG_STA_SUPPORT
+ // Data-Null packets alse pass through MMRequest in RT2860, however, we hope control the psm bit to pass APSD
+ if ((pHeader_802_11->FC.Type != BTYPE_DATA) && (pHeader_802_11->FC.Type != BTYPE_CNTL))
+ {
+ if ((pAd->StaCfg.Psm == PWR_SAVE) &&
+ (pHeader_802_11->FC.SubType == SUBTYPE_ACTION))
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ else
+ pHeader_802_11->FC.PwrMgmt = PWR_ACTIVE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ bInsertTimestamp = FALSE;
+ if (pHeader_802_11->FC.Type == BTYPE_CNTL) // must be PS-POLL
+ {
+#ifdef CONFIG_STA_SUPPORT
+ //Set PM bit in ps-poll, to fix WLK 1.2 PowerSaveMode_ext failure issue.
+ if ((pAd->OpMode == OPMODE_STA) && (pHeader_802_11->FC.SubType == SUBTYPE_PS_POLL))
+ {
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ bAckRequired = FALSE;
+ }
+ else // BTYPE_MGMT or BTYPE_DATA(must be NULL frame)
+ {
+ //pAd->Sequence++;
+ //pHeader_802_11->Sequence = pAd->Sequence;
+
+ if (pHeader_802_11->Addr1[0] & 0x01) // MULTICAST, BROADCAST
+ {
+ bAckRequired = FALSE;
+ pHeader_802_11->Duration = 0;
+ }
+ else
+ {
+ bAckRequired = TRUE;
+ pHeader_802_11->Duration = RTMPCalcDuration(pAd, MlmeRate, 14);
+ if (pHeader_802_11->FC.SubType == SUBTYPE_PROBE_RSP)
+ {
+ bInsertTimestamp = TRUE;
+ }
+ }
+ }
+
+ pHeader_802_11->Sequence = pAd->Sequence++;
+ if (pAd->Sequence >0xfff)
+ pAd->Sequence = 0;
+
+ // Before radar detection done, mgmt frame can not be sent but probe req
+ // Because we need to use probe req to trigger driver to send probe req in passive scan
+ if ((pHeader_802_11->FC.SubType != SUBTYPE_PROBE_REQ)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("MlmeHardTransmit --> radar detect not in normal mode !!!\n"));
+// if (!IrqState)
+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+ return (NDIS_STATUS_FAILURE);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pHeader_802_11, DIR_WRITE, FALSE);
+#endif
+
+ //
+ // fill scatter-and-gather buffer list into TXD. Internally created NDIS PACKET
+ // should always has only one ohysical buffer, and the whole frame size equals
+ // to the first scatter buffer size
+ //
+
+ // Initialize TX Descriptor
+ // For inter-frame gap, the number is for this frame and next frame
+ // For MLME rate, we will fix as 2Mb to match other vendor's implement
+// pAd->CommonCfg.MlmeTransmit.field.MODE = 1;
+
+// management frame doesn't need encryption. so use RESERVED_WCID no matter u are sending to specific wcid or not.
+ if (pMacEntry == NULL)
+ {
+ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE, bInsertTimestamp, FALSE, bAckRequired, FALSE,
+ 0, RESERVED_WCID, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE), PID_MGMT, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ }
+ else
+ {
+ RTMPWriteTxWI(pAd, pFirstTxWI, FALSE, FALSE,
+ bInsertTimestamp, FALSE, bAckRequired, FALSE,
+ 0, pMacEntry->Aid, (SrcBufLen - TXINFO_SIZE - TXWI_SIZE),
+ pMacEntry->MaxHTPhyMode.field.MCS, 0,
+ (UCHAR)pMacEntry->MaxHTPhyMode.field.MCS,
+ IFS_BACKOFF, FALSE, &pMacEntry->MaxHTPhyMode);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)pFirstTxWI, TYPE_TXWI);
+#endif
+
+ // Now do hardware-depened kick out.
+ HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen);
+
+ // Make sure to release MGMT ring resource
+// if (!IrqState)
+ RTMP_SEM_UNLOCK(&pAd->MgmtRingLock);
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+/********************************************************************************
+
+ New DeQueue Procedures.
+
+ ********************************************************************************/
+
+#define DEQUEUE_LOCK(lock, bIntContext, IrqFlags) \
+ do{ \
+ if (bIntContext == FALSE) \
+ RTMP_IRQ_LOCK((lock), IrqFlags); \
+ }while(0)
+
+#define DEQUEUE_UNLOCK(lock, bIntContext, IrqFlags) \
+ do{ \
+ if (bIntContext == FALSE) \
+ RTMP_IRQ_UNLOCK((lock), IrqFlags); \
+ }while(0)
+
+
+/*
+ ========================================================================
+ Tx Path design algorithm:
+ Basically, we divide the packets into four types, Broadcast/Multicast, 11N Rate(AMPDU, AMSDU, Normal), B/G Rate(ARALINK, Normal),
+ Specific Packet Type. Following show the classification rule and policy for each kinds of packets.
+ Classification Rule=>
+ Multicast: (*addr1 & 0x01) == 0x01
+ Specific : bDHCPFrame, bARPFrame, bEAPOLFrame, etc.
+ 11N Rate : If peer support HT
+ (1).AMPDU -- If TXBA is negotiated.
+ (2).AMSDU -- If AMSDU is capable for both peer and ourself.
+ *). AMSDU can embedded in a AMPDU, but now we didn't support it.
+ (3).Normal -- Other packets which send as 11n rate.
+
+ B/G Rate : If peer is b/g only.
+ (1).ARALINK-- If both of peer/us supprot Ralink proprietary Aggregation and the TxRate is large than RATE_6
+ (2).Normal -- Other packets which send as b/g rate.
+ Fragment:
+ The packet must be unicast, NOT A-RALINK, NOT A-MSDU, NOT 11n, then can consider about fragment.
+
+ Classified Packet Handle Rule=>
+ Multicast:
+ No ACK, //pTxBlk->bAckRequired = FALSE;
+ No WMM, //pTxBlk->bWMM = FALSE;
+ No piggyback, //pTxBlk->bPiggyBack = FALSE;
+ Force LowRate, //pTxBlk->bForceLowRate = TRUE;
+ Specific : Basically, for specific packet, we should handle it specifically, but now all specific packets are use
+ the same policy to handle it.
+ Force LowRate, //pTxBlk->bForceLowRate = TRUE;
+
+ 11N Rate :
+ No piggyback, //pTxBlk->bPiggyBack = FALSE;
+
+ (1).AMSDU
+ pTxBlk->bWMM = TRUE;
+ (2).AMPDU
+ pTxBlk->bWMM = TRUE;
+ (3).Normal
+
+ B/G Rate :
+ (1).ARALINK
+
+ (2).Normal
+ ========================================================================
+*/
+static UCHAR TxPktClassification(
+ IN RTMP_ADAPTER *pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ UCHAR TxFrameType = TX_UNKOWN_FRAME;
+ UCHAR Wcid;
+ MAC_TABLE_ENTRY *pMacEntry = NULL;
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN bHTRate = FALSE;
+#endif // DOT11_N_SUPPORT //
+
+ Wcid = RTMP_GET_PACKET_WCID(pPacket);
+ if (Wcid == MCAST_WCID)
+ { // Handle for RA is Broadcast/Multicast Address.
+ return TX_MCAST_FRAME;
+ }
+
+ // Handle for unicast packets
+ pMacEntry = &pAd->MacTab.Content[Wcid];
+ if (RTMP_GET_PACKET_LOWRATE(pPacket))
+ { // It's a specific packet need to force low rate, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame
+ TxFrameType = TX_LEGACY_FRAME;
+ }
+#ifdef DOT11_N_SUPPORT
+ else if (IS_HT_RATE(pMacEntry))
+ { // it's a 11n capable packet
+
+ // Depends on HTPhyMode to check if the peer support the HTRate transmission.
+ // Currently didn't support A-MSDU embedded in A-MPDU
+ bHTRate = TRUE;
+ if (RTMP_GET_PACKET_MOREDATA(pPacket) || (pMacEntry->PsMode == PWR_SAVE))
+ TxFrameType = TX_LEGACY_FRAME;
+#ifdef UAPSD_AP_SUPPORT
+ else if (RTMP_GET_PACKET_EOSP(pPacket))
+ TxFrameType = TX_LEGACY_FRAME;
+#endif // UAPSD_AP_SUPPORT //
+ else if((pMacEntry->TXBAbitmap & (1<<(RTMP_GET_PACKET_UP(pPacket)))) != 0)
+ return TX_AMPDU_FRAME;
+ else if(CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AMSDU_INUSED))
+ return TX_AMSDU_FRAME;
+ else
+ TxFrameType = TX_LEGACY_FRAME;
+ }
+#endif // DOT11_N_SUPPORT //
+ else
+ { // it's a legacy b/g packet.
+ if ((CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE) && pAd->CommonCfg.bAggregationCapable) &&
+ (RTMP_GET_PACKET_TXRATE(pPacket) >= RATE_6) &&
+ (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
+ { // if peer support Ralink Aggregation, we use it.
+ TxFrameType = TX_RALINK_FRAME;
+ }
+ else
+ {
+ TxFrameType = TX_LEGACY_FRAME;
+ }
+ }
+
+ // Currently, our fragment only support when a unicast packet send as NOT-ARALINK, NOT-AMSDU and NOT-AMPDU.
+ if ((RTMP_GET_PACKET_FRAGMENTS(pPacket) > 1) && (TxFrameType == TX_LEGACY_FRAME))
+ TxFrameType = TX_FRAG_FRAME;
+
+ return TxFrameType;
+}
+
+
+BOOLEAN RTMP_FillTxBlkInfo(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PACKET_INFO PacketInfo;
+ PNDIS_PACKET pPacket;
+ PMAC_TABLE_ENTRY pMacEntry = NULL;
+
+ pPacket = pTxBlk->pPacket;
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+
+ pTxBlk->Wcid = RTMP_GET_PACKET_WCID(pPacket);
+ pTxBlk->apidx = RTMP_GET_PACKET_IF(pPacket);
+ pTxBlk->UserPriority = RTMP_GET_PACKET_UP(pPacket);
+ pTxBlk->FrameGap = IFS_HTTXOP; // ASIC determine Frame Gap
+
+ if (RTMP_GET_PACKET_CLEAR_EAP_FRAME(pTxBlk->pPacket))
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bClearEAPFrame);
+ else
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bClearEAPFrame);
+
+ // Default to clear this flag
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bForceNonQoS);
+
+
+ if (pTxBlk->Wcid == MCAST_WCID)
+ {
+ pTxBlk->pMacEntry = NULL;
+ {
+#ifdef MCAST_RATE_SPECIFIC
+ PUCHAR pDA = GET_OS_PKT_DATAPTR(pPacket);
+ if (((*pDA & 0x01) == 0x01) && (*pDA != 0xff))
+ pTxBlk->pTransmit = &pAd->CommonCfg.MCastPhyMode;
+ else
+#endif // MCAST_RATE_SPECIFIC //
+ pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+ }
+
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired); // AckRequired = FALSE, when broadcast packet in Adhoc mode.
+ //TX_BLK_SET_FLAG(pTxBlk, fTX_bForceLowRate);
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAllowFrag);
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
+ if (RTMP_GET_PACKET_MOREDATA(pPacket))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
+ }
+
+ }
+ else
+ {
+ pTxBlk->pMacEntry = &pAd->MacTab.Content[pTxBlk->Wcid];
+ pTxBlk->pTransmit = &pTxBlk->pMacEntry->HTPhyMode;
+
+ pMacEntry = pTxBlk->pMacEntry;
+
+
+ // For all unicast packets, need Ack unless the Ack Policy is not set as NORMAL_ACK.
+ if (pAd->CommonCfg.AckPolicy[pTxBlk->QueIdx] != NORMAL_ACK)
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bAckRequired);
+ else
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bAckRequired);
+
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+
+ // If support WMM, enable it.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+ CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM);
+
+// if (pAd->StaCfg.bAutoTxRateSwitch)
+// TX_BLK_SET_FLAG(pTxBlk, fTX_AutoRateSwitch);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if (pTxBlk->TxFrameType == TX_LEGACY_FRAME)
+ {
+ if ( (RTMP_GET_PACKET_LOWRATE(pPacket)) ||
+ ((pAd->OpMode == OPMODE_AP) && (pMacEntry->MaxHTPhyMode.field.MODE == MODE_CCK) && (pMacEntry->MaxHTPhyMode.field.MCS == RATE_1)))
+ { // Specific packet, i.e., bDHCPFrame, bEAPOLFrame, bWAIFrame, need force low rate.
+ pTxBlk->pTransmit = &pAd->MacTab.Content[MCAST_WCID].HTPhyMode;
+#ifdef DOT11_N_SUPPORT
+ // Modify the WMM bit for ICV issue. If we have a packet with EOSP field need to set as 1, how to handle it???
+ if (IS_HT_STA(pTxBlk->pMacEntry) &&
+ (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RALINK_CHIPSET)) &&
+ ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_RDG_CAPABLE)))
+ {
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bWMM);
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bForceNonQoS);
+ }
+#endif // DOT11_N_SUPPORT //
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ( (IS_HT_RATE(pMacEntry) == FALSE) &&
+ (CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE)))
+ { // Currently piggy-back only support when peer is operate in b/g mode.
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bPiggyBack);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ if (RTMP_GET_PACKET_MOREDATA(pPacket))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bMoreData);
+ }
+#ifdef UAPSD_AP_SUPPORT
+ if (RTMP_GET_PACKET_EOSP(pPacket))
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bWMM_UAPSD_EOSP);
+ }
+#endif // UAPSD_AP_SUPPORT //
+ }
+ else if (pTxBlk->TxFrameType == TX_FRAG_FRAME)
+ {
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bAllowFrag);
+ }
+
+ pMacEntry->DebugTxCount++;
+ }
+
+ return TRUE;
+
+FillTxBlkErr:
+ return FALSE;
+}
+
+
+BOOLEAN CanDoAggregateTransmit(
+ IN RTMP_ADAPTER *pAd,
+ IN NDIS_PACKET *pPacket,
+ IN TX_BLK *pTxBlk)
+{
+
+ //printk("Check if can do aggregation! TxFrameType=%d!\n", pTxBlk->TxFrameType);
+
+ if (RTMP_GET_PACKET_WCID(pPacket) == MCAST_WCID)
+ return FALSE;
+
+ if (RTMP_GET_PACKET_DHCP(pPacket) ||
+ RTMP_GET_PACKET_EAPOL(pPacket) ||
+ RTMP_GET_PACKET_WAI(pPacket))
+ return FALSE;
+
+ if ((pTxBlk->TxFrameType == TX_AMSDU_FRAME) &&
+ ((pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))> (RX_BUFFER_AGGRESIZE - 100)))
+ { // For AMSDU, allow the packets with total length < max-amsdu size
+ return FALSE;
+ }
+
+ if ((pTxBlk->TxFrameType == TX_RALINK_FRAME) &&
+ (pTxBlk->TxPacketList.Number == 2))
+ { // For RALINK-Aggregation, allow two frames in one batch.
+ return FALSE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA)) // must be unicast to AP
+ return TRUE;
+ else
+#endif // CONFIG_STA_SUPPORT //
+ return FALSE;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ To do the enqueue operation and extract the first item of waiting
+ list. If a number of available shared memory segments could meet
+ the request of extracted item, the extracted item will be fragmented
+ into shared memory segments.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pQueue Pointer to Waiting Queue
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPDeQueuePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bIntContext,
+ IN UCHAR QIdx, /* BulkOutPipeId */
+ IN UCHAR Max_Tx_Packets)
+{
+ PQUEUE_ENTRY pEntry = NULL;
+ PNDIS_PACKET pPacket;
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ UCHAR Count=0;
+ PQUEUE_HEADER pQueue;
+ ULONG FreeNumber[NUM_OF_TX_RING];
+ UCHAR QueIdx, sQIdx, eQIdx;
+ unsigned long IrqFlags = 0;
+ BOOLEAN hasTxDesc = FALSE;
+ TX_BLK TxBlk;
+ TX_BLK *pTxBlk;
+
+#ifdef DBG_DIAGNOSE
+ BOOLEAN firstRound;
+ RtmpDiagStruct *pDiagStruct = &pAd->DiagStruct;
+#endif
+
+
+ if (QIdx == NUM_OF_TX_RING)
+ {
+ sQIdx = 0;
+//PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ eQIdx = 3; // 4 ACs, start from 0.
+#endif // CONFIG_STA_SUPPORT //
+ }
+ else
+ {
+ sQIdx = eQIdx = QIdx;
+ }
+
+ for (QueIdx=sQIdx; QueIdx <= eQIdx; QueIdx++)
+ {
+ Count=0;
+
+ RT28XX_START_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+#ifdef DBG_DIAGNOSE
+ firstRound = ((QueIdx == 0) ? TRUE : FALSE);
+#endif // DBG_DIAGNOSE //
+
+ while (1)
+ {
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST))))
+ {
+ RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+ return;
+ }
+
+ if (Count >= Max_Tx_Packets)
+ break;
+
+ DEQUEUE_LOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ if (&pAd->TxSwQueue[QueIdx] == NULL)
+ {
+#ifdef DBG_DIAGNOSE
+ if (firstRound == TRUE)
+ pDiagStruct->TxSWQueCnt[pDiagStruct->ArrayCurIdx][0]++;
+#endif // DBG_DIAGNOSE //
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ break;
+ }
+
+
+ // probe the Queue Head
+ pQueue = &pAd->TxSwQueue[QueIdx];
+ if ((pEntry = pQueue->Head) == NULL)
+ {
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ break;
+ }
+
+ pTxBlk = &TxBlk;
+ NdisZeroMemory((PUCHAR)pTxBlk, sizeof(TX_BLK));
+ //InitializeQueueHeader(&pTxBlk->TxPacketList); // Didn't need it because we already memzero it.
+ pTxBlk->QueIdx = QueIdx;
+
+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+
+ // Early check to make sure we have enoguh Tx Resource.
+ hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+ if (!hasTxDesc)
+ {
+ pAd->PrivateInfo.TxRingFullCnt++;
+
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+
+ break;
+ }
+
+ pTxBlk->TxFrameType = TxPktClassification(pAd, pPacket);
+ pEntry = RemoveHeadQueue(pQueue);
+ pTxBlk->TotalFrameNum++;
+ pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
+ pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
+ pTxBlk->pPacket = pPacket;
+ InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+
+ if (pTxBlk->TxFrameType == TX_RALINK_FRAME || pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+ {
+ // Enhance SW Aggregation Mechanism
+ if (NEED_QUEUE_BACK_FOR_AGG(pAd, QueIdx, FreeNumber[QueIdx], pTxBlk->TxFrameType))
+ {
+ InsertHeadQueue(pQueue, PACKET_TO_QUEUE_ENTRY(pPacket));
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+ break;
+ }
+
+ do{
+ if((pEntry = pQueue->Head) == NULL)
+ break;
+
+ // For TX_AMSDU_FRAME/TX_RALINK_FRAME, Need to check if next pakcet can do aggregation.
+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+ FreeNumber[QueIdx] = GET_TXRING_FREENO(pAd, QueIdx);
+ hasTxDesc = RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, FreeNumber[QueIdx], pPacket);
+ if ((hasTxDesc == FALSE) || (CanDoAggregateTransmit(pAd, pPacket, pTxBlk) == FALSE))
+ break;
+
+ //Remove the packet from the TxSwQueue and insert into pTxBlk
+ pEntry = RemoveHeadQueue(pQueue);
+ ASSERT(pEntry);
+ pPacket = QUEUE_ENTRY_TO_PKT(pEntry);
+ pTxBlk->TotalFrameNum++;
+ pTxBlk->TotalFragNum += RTMP_GET_PACKET_FRAGMENTS(pPacket); // The real fragment number maybe vary
+ pTxBlk->TotalFrameLen += GET_OS_PKT_LEN(pPacket);
+ InsertTailQueue(&pTxBlk->TxPacketList, PACKET_TO_QUEUE_ENTRY(pPacket));
+ }while(1);
+
+ if (pTxBlk->TxPacketList.Number == 1)
+ pTxBlk->TxFrameType = TX_LEGACY_FRAME;
+ }
+
+#ifdef RT2870
+ DEQUEUE_UNLOCK(&pAd->irq_lock, bIntContext, IrqFlags);
+#endif // RT2870 //
+
+ Count += pTxBlk->TxPacketList.Number;
+
+ // Do HardTransmit now.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ Status = STAHardTransmit(pAd, pTxBlk, QueIdx);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ RT28XX_STOP_DEQUEUE(pAd, QueIdx, IrqFlags);
+
+#ifdef RT2870
+ if (!hasTxDesc)
+ RTUSBKickBulkOut(pAd);
+#endif // RT2870 //
+
+#ifdef BLOCK_NET_IF
+ if ((pAd->blockQueueTab[QueIdx].SwTxQueueBlockFlag == TRUE)
+ && (pAd->TxSwQueue[QueIdx].Number < 1))
+ {
+ releaseNetIf(&pAd->blockQueueTab[QueIdx]);
+ }
+#endif // BLOCK_NET_IF //
+
+ }
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculates the duration which is required to transmit out frames
+ with given size and specified rate.
+
+ Arguments:
+ pAd Pointer to our adapter
+ Rate Transmit rate
+ Size Frame size in units of byte
+
+ Return Value:
+ Duration number in units of usec
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+USHORT RTMPCalcDuration(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Rate,
+ IN ULONG Size)
+{
+ ULONG Duration = 0;
+
+ if (Rate < RATE_FIRST_OFDM_RATE) // CCK
+ {
+ if ((Rate > RATE_1) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED))
+ Duration = 96; // 72+24 preamble+plcp
+ else
+ Duration = 192; // 144+48 preamble+plcp
+
+ Duration += (USHORT)((Size << 4) / RateIdTo500Kbps[Rate]);
+ if ((Size << 4) % RateIdTo500Kbps[Rate])
+ Duration ++;
+ }
+ else if (Rate <= RATE_LAST_OFDM_RATE)// OFDM rates
+ {
+ Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
+ Duration += 4 * (USHORT)((11 + Size * 4) / RateIdTo500Kbps[Rate]);
+ if ((11 + Size * 4) % RateIdTo500Kbps[Rate])
+ Duration += 4;
+ }
+ else //mimo rate
+ {
+ Duration = 20 + 6; // 16+4 preamble+plcp + Signal Extension
+ }
+
+ return (USHORT)Duration;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculates the duration which is required to transmit out frames
+ with given size and specified rate.
+
+ Arguments:
+ pTxWI Pointer to head of each MPDU to HW.
+ Ack Setting for Ack requirement bit
+ Fragment Setting for Fragment bit
+ RetryMode Setting for retry mode
+ Ifs Setting for IFS gap
+ Rate Setting for transmit rate
+ Service Setting for service
+ Length Frame length
+ TxPreamble Short or Long preamble when using CCK rates
+ QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ See also : BASmartHardTransmit() !!!
+
+ ========================================================================
+*/
+VOID RTMPWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pOutTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN CFACK,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR TID,
+ IN UCHAR TxRate,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING *pTransmit)
+{
+ PMAC_TABLE_ENTRY pMac = NULL;
+ TXWI_STRUC TxWI;
+ PTXWI_STRUC pTxWI;
+
+ if (WCID < MAX_LEN_OF_MAC_TABLE)
+ pMac = &pAd->MacTab.Content[WCID];
+
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ NdisZeroMemory(&TxWI, TXWI_SIZE);
+ pTxWI = &TxWI;
+
+ pTxWI->FRAG= FRAG;
+
+ pTxWI->CFACK = CFACK;
+ pTxWI->TS= InsTimestamp;
+ pTxWI->AMPDU = AMPDU;
+ pTxWI->ACK = Ack;
+ pTxWI->txop= Txopmode;
+
+ pTxWI->NSEQ = NSeq;
+ // John tune the performace with Intel Client in 20 MHz performance
+#ifdef DOT11_N_SUPPORT
+ BASize = pAd->CommonCfg.TxBASize;
+
+ if( BASize >7 )
+ BASize =7;
+ pTxWI->BAWinSize = BASize;
+ pTxWI->ShortGI = pTransmit->field.ShortGI;
+ pTxWI->STBC = pTransmit->field.STBC;
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->WirelessCliID = WCID;
+ pTxWI->MPDUtotalByteCount = Length;
+ pTxWI->PacketId = PID;
+
+ // If CCK or OFDM, BW must be 20
+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->BW)
+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+
+ pTxWI->MCS = pTransmit->field.MCS;
+ pTxWI->PHYMODE = pTransmit->field.MODE;
+ pTxWI->CFACK = CfAck;
+
+#ifdef DOT11_N_SUPPORT
+ if (pMac)
+ {
+ if (pAd->CommonCfg.bMIMOPSEnable)
+ {
+ if ((pMac->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+ {
+ // Dynamic MIMO Power Save Mode
+ pTxWI->MIMOps = 1;
+ }
+ else if (pMac->MmpsMode == MMPS_STATIC)
+ {
+ // Static MIMO Power Save Mode
+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+ {
+ pTxWI->MCS = 7;
+ pTxWI->MIMOps = 0;
+ }
+ }
+ }
+ //pTxWI->MIMOps = (pMac->PsMode == PWR_MMPS)? 1:0;
+ if (pMac->bIAmBadAtheros && (pMac->WepStatus != Ndis802_11WEPDisabled))
+ {
+ pTxWI->MpduDensity = 7;
+ }
+ else
+ {
+ pTxWI->MpduDensity = pMac->MpduDensity;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->PacketId = pTxWI->MCS;
+ NdisMoveMemory(pOutTxWI, &TxWI, sizeof(TXWI_STRUC));
+}
+
+
+VOID RTMPWriteTxWI_Data(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk)
+{
+ HTTRANSMIT_SETTING *pTransmit;
+ PMAC_TABLE_ENTRY pMacEntry;
+#ifdef DOT11_N_SUPPORT
+ UCHAR BASize;
+#endif // DOT11_N_SUPPORT //
+
+
+ ASSERT(pTxWI);
+
+ pTransmit = pTxBlk->pTransmit;
+ pMacEntry = pTxBlk->pMacEntry;
+
+
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ NdisZeroMemory(pTxWI, TXWI_SIZE);
+
+ pTxWI->FRAG = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag);
+ pTxWI->ACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bAckRequired);
+ pTxWI->txop = pTxBlk->FrameGap;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ if (pMacEntry &&
+ (pAd->StaCfg.BssType == BSS_INFRA) &&
+ (pMacEntry->ValidAsDls == TRUE))
+ pTxWI->WirelessCliID = BSSID_WCID;
+ else
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ pTxWI->WirelessCliID = pTxBlk->Wcid;
+
+ pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+ pTxWI->CFACK = TX_BLK_TEST_FLAG(pTxBlk, fTX_bPiggyBack);
+
+ // If CCK or OFDM, BW must be 20
+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->BW)
+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+ pTxWI->AMPDU = ((pTxBlk->TxFrameType == TX_AMPDU_FRAME) ? TRUE : FALSE);
+
+ // John tune the performace with Intel Client in 20 MHz performance
+ BASize = pAd->CommonCfg.TxBASize;
+ if((pTxBlk->TxFrameType == TX_AMPDU_FRAME) && (pMacEntry))
+ {
+ UCHAR RABAOriIdx = 0; //The RA's BA Originator table index.
+
+ RABAOriIdx = pTxBlk->pMacEntry->BAOriWcidArray[pTxBlk->UserPriority];
+ BASize = pAd->BATable.BAOriEntry[RABAOriIdx].BAWinSize;
+ }
+
+ pTxWI->TxBF = pTransmit->field.TxBF;
+ pTxWI->BAWinSize = BASize;
+ pTxWI->ShortGI = pTransmit->field.ShortGI;
+ pTxWI->STBC = pTransmit->field.STBC;
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->MCS = pTransmit->field.MCS;
+ pTxWI->PHYMODE = pTransmit->field.MODE;
+
+#ifdef DOT11_N_SUPPORT
+ if (pMacEntry)
+ {
+ if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+ {
+ // Dynamic MIMO Power Save Mode
+ pTxWI->MIMOps = 1;
+ }
+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
+ {
+ // Static MIMO Power Save Mode
+ if (pTransmit->field.MODE >= MODE_HTMIX && pTransmit->field.MCS > 7)
+ {
+ pTxWI->MCS = 7;
+ pTxWI->MIMOps = 0;
+ }
+ }
+
+ if (pMacEntry->bIAmBadAtheros && (pMacEntry->WepStatus != Ndis802_11WEPDisabled))
+ {
+ pTxWI->MpduDensity = 7;
+ }
+ else
+ {
+ pTxWI->MpduDensity = pMacEntry->MpduDensity;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DBG_DIAGNOSE
+ if (pTxBlk->QueIdx== 0)
+ {
+ pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+ pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
+ }
+#endif // DBG_DIAGNOSE //
+
+ // for rate adapation
+ pTxWI->PacketId = pTxWI->MCS;
+#ifdef INF_AMAZON_SE
+/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+ if( RTMP_GET_PACKET_NOBULKOUT(pTxBlk->pPacket))
+ {
+ if(pTxWI->PHYMODE == MODE_CCK)
+ {
+ pTxWI->PacketId = 6;
+ }
+ }
+#endif // INF_AMAZON_SE //
+}
+
+
+VOID RTMPWriteTxWI_Cache(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk)
+{
+ PHTTRANSMIT_SETTING /*pTxHTPhyMode,*/ pTransmit;
+ PMAC_TABLE_ENTRY pMacEntry;
+
+ //
+ // update TXWI
+ //
+ pMacEntry = pTxBlk->pMacEntry;
+ pTransmit = pTxBlk->pTransmit;
+
+ //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))
+ //if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pMacEntry))
+ //if (TX_BLK_TEST_FLAG(pTxBlk, fTX_AutoRateSwitch))
+ if (pMacEntry->bAutoTxRateSwitch)
+ {
+ pTxWI->txop = IFS_HTTXOP;
+
+ // If CCK or OFDM, BW must be 20
+ pTxWI->BW = (pTransmit->field.MODE <= MODE_OFDM) ? (BW_20) : (pTransmit->field.BW);
+ pTxWI->ShortGI = pTransmit->field.ShortGI;
+ pTxWI->STBC = pTransmit->field.STBC;
+
+ pTxWI->MCS = pTransmit->field.MCS;
+ pTxWI->PHYMODE = pTransmit->field.MODE;
+
+ // set PID for TxRateSwitching
+ pTxWI->PacketId = pTransmit->field.MCS;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ pTxWI->AMPDU = ((pMacEntry->NoBADataCountDown == 0) ? TRUE: FALSE);
+ pTxWI->MIMOps = 0;
+
+#ifdef DOT11N_DRAFT3
+ if (pTxWI->BW)
+ pTxWI->BW = (pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth == 0) ? (BW_20) : (pTransmit->field.BW);
+#endif // DOT11N_DRAFT3 //
+
+ if (pAd->CommonCfg.bMIMOPSEnable)
+ {
+ // MIMO Power Save Mode
+ if ((pMacEntry->MmpsMode == MMPS_DYNAMIC) && (pTransmit->field.MCS > 7))
+ {
+ // Dynamic MIMO Power Save Mode
+ pTxWI->MIMOps = 1;
+ }
+ else if (pMacEntry->MmpsMode == MMPS_STATIC)
+ {
+ // Static MIMO Power Save Mode
+ if ((pTransmit->field.MODE >= MODE_HTMIX) && (pTransmit->field.MCS > 7))
+ {
+ pTxWI->MCS = 7;
+ pTxWI->MIMOps = 0;
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DBG_DIAGNOSE
+ if (pTxBlk->QueIdx== 0)
+ {
+ pAd->DiagStruct.TxDataCnt[pAd->DiagStruct.ArrayCurIdx]++;
+ pAd->DiagStruct.TxMcsCnt[pAd->DiagStruct.ArrayCurIdx][pTxWI->MCS]++;
+ }
+#endif // DBG_DIAGNOSE //
+
+ pTxWI->MPDUtotalByteCount = pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculates the duration which is required to transmit out frames
+ with given size and specified rate.
+
+ Arguments:
+ pTxD Pointer to transmit descriptor
+ Ack Setting for Ack requirement bit
+ Fragment Setting for Fragment bit
+ RetryMode Setting for retry mode
+ Ifs Setting for IFS gap
+ Rate Setting for transmit rate
+ Service Setting for service
+ Length Frame length
+ TxPreamble Short or Long preamble when using CCK rates
+ QueIdx - 0-3, according to 802.11e/d4.4 June/2003
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPWriteTxDescriptor(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXD_STRUC pTxD,
+ IN BOOLEAN bWIV,
+ IN UCHAR QueueSEL)
+{
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+
+ pTxD->WIV = (bWIV) ? 1: 0;
+ pTxD->QSEL= (QueueSEL);
+ if (pAd->bGenOneHCCA == TRUE)
+ pTxD->QSEL= FIFO_HCCA;
+ pTxD->DMADONE = 0;
+}
+
+
+// should be called only when -
+// 1. MEADIA_CONNECTED
+// 2. AGGREGATION_IN_USED
+// 3. Fragmentation not in used
+// 4. either no previous frame (pPrevAddr1=NULL) .OR. previoud frame is aggregatible
+BOOLEAN TxFrameIsAggregatible(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pPrevAddr1,
+ IN PUCHAR p8023hdr)
+{
+
+ // can't aggregate EAPOL (802.1x) frame
+ if ((p8023hdr[12] == 0x88) && (p8023hdr[13] == 0x8e))
+ return FALSE;
+
+ // can't aggregate multicast/broadcast frame
+ if (p8023hdr[0] & 0x01)
+ return FALSE;
+
+ if (INFRA_ON(pAd)) // must be unicast to AP
+ return TRUE;
+ else if ((pPrevAddr1 == NULL) || MAC_ADDR_EQUAL(pPrevAddr1, p8023hdr)) // unicast to same STA
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check the MSDU Aggregation policy
+ 1.HT aggregation is A-MSDU
+ 2.legaacy rate aggregation is software aggregation by Ralink.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN PeerIsAggreOn(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG TxRate,
+ IN PMAC_TABLE_ENTRY pMacEntry)
+{
+ ULONG AFlags = (fCLIENT_STATUS_AMSDU_INUSED | fCLIENT_STATUS_AGGREGATION_CAPABLE);
+
+ if (pMacEntry != NULL && CLIENT_STATUS_TEST_FLAG(pMacEntry, AFlags))
+ {
+#ifdef DOT11_N_SUPPORT
+ if (pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+ {
+ return TRUE;
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef AGGREGATION_SUPPORT
+ if (TxRate >= RATE_6 && pAd->CommonCfg.bAggregationCapable && (!(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && CLIENT_STATUS_TEST_FLAG(pMacEntry, fCLIENT_STATUS_WMM_CAPABLE))))
+ { // legacy Ralink Aggregation support
+ return TRUE;
+ }
+#endif // AGGREGATION_SUPPORT //
+ }
+
+ return FALSE;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check and fine the packet waiting in SW queue with highest priority
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ pQueue Pointer to Waiting Queue
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+PQUEUE_HEADER RTMPCheckTxSwQueue(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pQueIdx)
+{
+
+ ULONG Number;
+ // 2004-11-15 to be removed. test aggregation only
+// if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)) && (*pNumber < 2))
+// return NULL;
+
+ Number = pAd->TxSwQueue[QID_AC_BK].Number
+ + pAd->TxSwQueue[QID_AC_BE].Number
+ + pAd->TxSwQueue[QID_AC_VI].Number
+ + pAd->TxSwQueue[QID_AC_VO].Number
+ + pAd->TxSwQueue[QID_HCCA].Number;
+
+ if (pAd->TxSwQueue[QID_AC_VO].Head != NULL)
+ {
+ *pQueIdx = QID_AC_VO;
+ return (&pAd->TxSwQueue[QID_AC_VO]);
+ }
+ else if (pAd->TxSwQueue[QID_AC_VI].Head != NULL)
+ {
+ *pQueIdx = QID_AC_VI;
+ return (&pAd->TxSwQueue[QID_AC_VI]);
+ }
+ else if (pAd->TxSwQueue[QID_AC_BE].Head != NULL)
+ {
+ *pQueIdx = QID_AC_BE;
+ return (&pAd->TxSwQueue[QID_AC_BE]);
+ }
+ else if (pAd->TxSwQueue[QID_AC_BK].Head != NULL)
+ {
+ *pQueIdx = QID_AC_BK;
+ return (&pAd->TxSwQueue[QID_AC_BK]);
+ }
+ else if (pAd->TxSwQueue[QID_HCCA].Head != NULL)
+ {
+ *pQueIdx = QID_HCCA;
+ return (&pAd->TxSwQueue[QID_HCCA]);
+ }
+
+ // No packet pending in Tx Sw queue
+ *pQueIdx = QID_AC_BK;
+
+ return (NULL);
+}
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Suspend MSDU transmission
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPSuspendMsduTransmission(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("SCANNING, suspend MSDU transmission ...\n"));
+
+
+ //
+ // Before BSS_SCAN_IN_PROGRESS, we need to keep Current R66 value and
+ // use Lowbound as R66 value on ScanNextChannel(...)
+ //
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
+
+ // set BBP_R66 to 0x30/0x40 when scanning (AsicSwitchChannel will set R66 according to channel when scanning)
+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x26 + GET_LNA_GAIN(pAd)));
+ RTMPSetAGCInitValue(pAd, BW_20);
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x000f0000); // abort all TX rings
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Resume MSDU transmission
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPResumeMsduTransmission(
+ IN PRTMP_ADAPTER pAd)
+{
+// UCHAR IrqState;
+
+ DBGPRINT(RT_DEBUG_TRACE,("SCAN done, resume MSDU transmission ...\n"));
+
+
+ // After finish BSS_SCAN_IN_PROGRESS, we need to restore Current R66 value
+ // R66 should not be 0
+ if (pAd->BbpTuning.R66CurrentValue == 0)
+ {
+ pAd->BbpTuning.R66CurrentValue = 0x38;
+ DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"));
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, pAd->BbpTuning.R66CurrentValue);
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+// sample, for IRQ LOCK to SEM LOCK
+// IrqState = pAd->irq_disabled;
+// if (IrqState)
+// RTMPDeQueuePacket(pAd, TRUE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+// else
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+}
+
+
+UINT deaggregate_AMSDU_announce(
+ IN PRTMP_ADAPTER pAd,
+ PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize)
+{
+ USHORT PayloadSize;
+ USHORT SubFrameSize;
+ PHEADER_802_3 pAMSDUsubheader;
+ UINT nMSDU;
+ UCHAR Header802_3[14];
+
+ PUCHAR pPayload, pDA, pSA, pRemovedLLCSNAP;
+ PNDIS_PACKET pClonePacket;
+
+
+
+ nMSDU = 0;
+
+ while (DataSize > LENGTH_802_3)
+ {
+
+ nMSDU++;
+
+ //hex_dump("subheader", pData, 64);
+ pAMSDUsubheader = (PHEADER_802_3)pData;
+ //pData += LENGTH_802_3;
+ PayloadSize = pAMSDUsubheader->Octet[1] + (pAMSDUsubheader->Octet[0]<<8);
+ SubFrameSize = PayloadSize + LENGTH_802_3;
+
+
+ if ((DataSize < SubFrameSize) || (PayloadSize > 1518 ))
+ {
+ break;
+ }
+
+ //printk("%d subframe: Size = %d\n", nMSDU, PayloadSize);
+
+ pPayload = pData + LENGTH_802_3;
+ pDA = pData;
+ pSA = pData + MAC_ADDR_LEN;
+
+ // convert to 802.3 header
+ CONVERT_TO_802_3(Header802_3, pDA, pSA, pPayload, PayloadSize, pRemovedLLCSNAP);
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((Header802_3[12] == 0x88) && (Header802_3[13] == 0x8E) )
+ {
+ // avoid local heap overflow, use dyanamic allocation
+ MLME_QUEUE_ELEM *Elem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+ memmove(Elem->Msg+(LENGTH_802_11 + LENGTH_802_1_H), pPayload, PayloadSize);
+ Elem->MsgLen = LENGTH_802_11 + LENGTH_802_1_H + PayloadSize;
+ WpaEAPOLKeyAction(pAd, Elem);
+ kfree(Elem);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pRemovedLLCSNAP)
+ {
+ pPayload -= LENGTH_802_3;
+ PayloadSize += LENGTH_802_3;
+ NdisMoveMemory(pPayload, &Header802_3[0], LENGTH_802_3);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pClonePacket = ClonePacket(pAd, pPacket, pPayload, PayloadSize);
+ if (pClonePacket)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pClonePacket, RTMP_GET_PACKET_IF(pPacket));
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ // A-MSDU has padding to multiple of 4 including subframe header.
+ // align SubFrameSize up to multiple of 4
+ SubFrameSize = (SubFrameSize+3)&(~0x3);
+
+
+ if (SubFrameSize > 1528 || SubFrameSize < 32)
+ {
+ break;
+ }
+
+ if (DataSize > SubFrameSize)
+ {
+ pData += SubFrameSize;
+ DataSize -= SubFrameSize;
+ }
+ else
+ {
+ // end of A-MSDU
+ DataSize = 0;
+ }
+ }
+
+ // finally release original rx packet
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_SUCCESS);
+
+ return nMSDU;
+}
+
+
+UINT BA_Reorder_AMSDU_Annnounce(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ PUCHAR pData;
+ USHORT DataSize;
+ UINT nMSDU = 0;
+
+ pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
+ DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
+
+ nMSDU = deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
+
+ return nMSDU;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Look up the MAC address in the MAC table. Return NULL if not found.
+ Return:
+ pEntry - pointer to the MAC entry; NULL is not found
+ ==========================================================================
+*/
+MAC_TABLE_ENTRY *MacTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ PUCHAR pAddr)
+{
+ ULONG HashIdx;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ pEntry = pAd->MacTab.Hash[HashIdx];
+
+ while (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsWDS || pEntry->ValidAsApCli || pEntry->ValidAsMesh))
+ {
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+ break;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ return pEntry;
+}
+
+MAC_TABLE_ENTRY *MacTableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR apidx,
+ IN BOOLEAN CleanAll)
+{
+ UCHAR HashIdx;
+ int i, FirstWcid;
+ MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+// USHORT offset;
+// ULONG addr;
+
+ // if FULL, return
+ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+ return NULL;
+
+ FirstWcid = 1;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ if (pAd->StaCfg.BssType == BSS_INFRA)
+ FirstWcid = 2;
+#endif // CONFIG_STA_SUPPORT //
+
+ // allocate one MAC entry
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ for (i = FirstWcid; i< MAX_LEN_OF_MAC_TABLE; i++) // skip entry#0 so that "entry index == AID" for fast lookup
+ {
+ // pick up the first available vacancy
+ if ((pAd->MacTab.Content[i].ValidAsCLI == FALSE) &&
+ (pAd->MacTab.Content[i].ValidAsWDS == FALSE) &&
+ (pAd->MacTab.Content[i].ValidAsApCli== FALSE) &&
+ (pAd->MacTab.Content[i].ValidAsMesh == FALSE)
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ && (pAd->MacTab.Content[i].ValidAsDls == FALSE)
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ )
+ {
+ pEntry = &pAd->MacTab.Content[i];
+ if (CleanAll == TRUE)
+ {
+ pEntry->MaxSupportedRate = RATE_11;
+ pEntry->CurrTxRate = RATE_11;
+ NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+ pEntry->PairwiseKey.KeyLen = 0;
+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+ }
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ if (apidx >= MIN_NET_DEVICE_FOR_DLS)
+ {
+ pEntry->ValidAsCLI = FALSE;
+ pEntry->ValidAsWDS = FALSE;
+ pEntry->ValidAsApCli = FALSE;
+ pEntry->ValidAsMesh = FALSE;
+ pEntry->ValidAsDls = TRUE;
+ pEntry->isCached = FALSE;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pEntry->ValidAsCLI = TRUE;
+ pEntry->ValidAsWDS = FALSE;
+ pEntry->ValidAsApCli = FALSE;
+ pEntry->ValidAsMesh = FALSE;
+ pEntry->ValidAsDls = FALSE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ pEntry->bIAmBadAtheros = FALSE;
+ pEntry->pAd = pAd;
+ pEntry->CMTimerRunning = FALSE;
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+ pEntry->RSNIE_Len = 0;
+ NdisZeroMemory(pEntry->R_Counter, sizeof(pEntry->R_Counter));
+ pEntry->ReTryCounter = PEER_MSG1_RETRY_TIMER_CTR;
+
+ if (pEntry->ValidAsMesh)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_MESH);
+ else if (pEntry->ValidAsApCli)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_APCLI);
+ else if (pEntry->ValidAsWDS)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_WDS);
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ else if (pEntry->ValidAsDls)
+ pEntry->apidx = (apidx - MIN_NET_DEVICE_FOR_DLS);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ else
+ pEntry->apidx = apidx;
+
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pEntry->AuthMode = pAd->StaCfg.AuthMode;
+ pEntry->WepStatus = pAd->StaCfg.WepStatus;
+ pEntry->PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ pEntry->GTKState = REKEY_NEGOTIATING;
+ pEntry->PairwiseKey.KeyLen = 0;
+ pEntry->PairwiseKey.CipherAlg = CIPHER_NONE;
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ if (pEntry->ValidAsDls == TRUE)
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ else
+#endif //QOS_DLS_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pEntry->PMKID_CacheIdx = ENTRY_NOT_FOUND;
+ COPY_MAC_ADDR(pEntry->Addr, pAddr);
+ pEntry->Sst = SST_NOT_AUTH;
+ pEntry->AuthState = AS_NOT_AUTH;
+ pEntry->Aid = (USHORT)i; //0;
+ pEntry->CapabilityInfo = 0;
+ pEntry->PsMode = PWR_ACTIVE;
+ pEntry->PsQIdleCount = 0;
+ pEntry->NoDataIdleCount = 0;
+ pEntry->ContinueTxFailCnt = 0;
+ InitializeQueueHeader(&pEntry->PsQueue);
+
+
+ pAd->MacTab.Size ++;
+
+ // Add this entry into ASIC RX WCID search table
+ RT28XX_STA_ENTRY_ADD(pAd, pEntry);
+
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertEntry - allocate entry #%d, Total= %d\n",i, pAd->MacTab.Size));
+ break;
+ }
+ }
+
+ // add this MAC entry into HASH table
+ if (pEntry)
+ {
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ if (pAd->MacTab.Hash[HashIdx] == NULL)
+ {
+ pAd->MacTab.Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pAd->MacTab.Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+ return pEntry;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Delete a specified client from MAC table
+ ==========================================================================
+ */
+BOOLEAN MacTableDeleteEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr)
+{
+ USHORT HashIdx;
+ MAC_TABLE_ENTRY *pEntry, *pPrevEntry, *pProbeEntry;
+ BOOLEAN Cancelled;
+ //USHORT offset; // unused variable
+ //UCHAR j; // unused variable
+
+ if (wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ //pEntry = pAd->MacTab.Hash[HashIdx];
+ pEntry = &pAd->MacTab.Content[wcid];
+
+ if (pEntry && (pEntry->ValidAsCLI || pEntry->ValidAsApCli || pEntry->ValidAsWDS || pEntry->ValidAsMesh
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ || pEntry->ValidAsDls
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ ))
+ {
+ if (MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+
+ // Delete this entry from ASIC on-chip WCID Table
+ RT28XX_STA_ENTRY_MAC_RESET(pAd, wcid);
+
+#ifdef DOT11_N_SUPPORT
+ // free resources of BA
+ BASessionTearDownALL(pAd, pEntry->Aid);
+#endif // DOT11_N_SUPPORT //
+
+
+ pPrevEntry = NULL;
+ pProbeEntry = pAd->MacTab.Hash[HashIdx];
+ ASSERT(pProbeEntry);
+
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pAd->MacTab.Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ // not found !!!
+ ASSERT(pProbeEntry != NULL);
+
+ RT28XX_STA_ENTRY_KEY_DEL(pAd, BSS0, wcid);
+
+
+ if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
+ {
+ RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+ }
+
+
+ NdisZeroMemory(pEntry, sizeof(MAC_TABLE_ENTRY));
+ pAd->MacTab.Size --;
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableDeleteEntry1 - Total= %d\n", pAd->MacTab.Size));
+ }
+ else
+ {
+ printk("\n%s: Impossible Wcid = %d !!!!!\n", __FUNCTION__, wcid);
+ }
+ }
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ //Reset operating mode when no Sta.
+ if (pAd->MacTab.Size == 0)
+ {
+#ifdef DOT11_N_SUPPORT
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode = 0;
+#endif // DOT11_N_SUPPORT //
+ //AsicUpdateProtect(pAd, 0 /*pAd->CommonCfg.AddHTInfo.AddHtInfo2.OperaionMode*/, (ALLN_SETPROTECT), TRUE, 0 /*pAd->MacTab.fAnyStationNonGF*/);
+ RT28XX_UPDATE_PROTECT(pAd); // edit by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+ }
+
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ This routine reset the entire MAC table. All packets pending in
+ the power-saving queues are freed here.
+ ==========================================================================
+ */
+VOID MacTableReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableReset\n"));
+ //NdisAcquireSpinLock(&pAd->MacTabLock);
+
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
+ {
+
+#ifdef DOT11_N_SUPPORT
+ // free resources of BA
+ BASessionTearDownALL(pAd, i);
+#endif // DOT11_N_SUPPORT //
+
+ pAd->MacTab.Content[i].ValidAsCLI = FALSE;
+
+
+
+#ifdef RT2870
+ NdisZeroMemory(pAd->MacTab.Content[i].Addr, 6);
+ RT28XX_STA_ENTRY_MAC_RESET(pAd, i);
+#endif // RT2870 //
+
+ //AsicDelWcidTab(pAd, i);
+ }
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID AssocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
+ IN PUCHAR pAddr,
+ IN USHORT CapabilityInfo,
+ IN ULONG Timeout,
+ IN USHORT ListenIntv)
+{
+ COPY_MAC_ADDR(AssocReq->Addr, pAddr);
+ // Add mask to support 802.11b mode only
+ AssocReq->CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; // not cf-pollable, not cf-poll-request
+ AssocReq->Timeout = Timeout;
+ AssocReq->ListenIntv = ListenIntv;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID DisassocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
+ IN PUCHAR pAddr,
+ IN USHORT Reason)
+{
+ COPY_MAC_ADDR(DisassocReq->Addr, pAddr);
+ DisassocReq->Reason = Reason;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check the out going frame, if this is an DHCP or ARP datagram
+ will be duplicate another frame at low data rate transmit.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pPacket Pointer to outgoing Ndis frame
+
+ Return Value:
+ TRUE To be duplicate at Low data rate transmit. (1mb)
+ FALSE Do nothing.
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ MAC header + IP Header + UDP Header
+ 14 Bytes 20 Bytes
+
+ UDP Header
+ 00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|
+ Source Port
+ 16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31|
+ Destination Port
+
+ port 0x43 means Bootstrap Protocol, server.
+ Port 0x44 means Bootstrap Protocol, client.
+
+ ========================================================================
+*/
+
+BOOLEAN RTMPCheckDHCPFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ ULONG NumberOfBytesRead = 0;
+ ULONG CurrentOffset = 0;
+ PVOID pVirtualAddress = NULL;
+ UINT NdisBufferLength;
+ PUCHAR pSrc;
+ USHORT Protocol;
+ UCHAR ByteOffset36 = 0;
+ UCHAR ByteOffset38 = 0;
+ BOOLEAN ReadFirstParm = TRUE;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, (PUCHAR *)&pVirtualAddress, &NdisBufferLength);
+
+ NumberOfBytesRead += NdisBufferLength;
+ pSrc = (PUCHAR) pVirtualAddress;
+ Protocol = *(pSrc + 12) * 256 + *(pSrc + 13);
+
+ //
+ // Check DHCP & BOOTP protocol
+ //
+ while (NumberOfBytesRead <= PacketInfo.TotalPacketLength)
+ {
+ if ((NumberOfBytesRead >= 35) && (ReadFirstParm == TRUE))
+ {
+ CurrentOffset = 35 - (NumberOfBytesRead - NdisBufferLength);
+ ByteOffset36 = *(pSrc + CurrentOffset);
+ ReadFirstParm = FALSE;
+ }
+
+ if (NumberOfBytesRead >= 37)
+ {
+ CurrentOffset = 37 - (NumberOfBytesRead - NdisBufferLength);
+ ByteOffset38 = *(pSrc + CurrentOffset);
+ //End of Read
+ break;
+ }
+ return FALSE;
+ }
+
+ // Check for DHCP & BOOTP protocol
+ if ((ByteOffset36 != 0x44) || (ByteOffset38 != 0x43))
+ {
+ //
+ // 2054 (hex 0806) for ARP datagrams
+ // if this packet is not ARP datagrams, then do nothing
+ // ARP datagrams will also be duplicate at 1mb broadcast frames
+ //
+ if (Protocol != 0x0806 )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN RTMPCheckEtherType(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ USHORT TypeLen;
+ UCHAR Byte0, Byte1;
+ PUCHAR pSrcBuf;
+ UINT32 pktLen;
+ UINT16 srcPort, dstPort;
+ BOOLEAN status = TRUE;
+
+
+ pSrcBuf = GET_OS_PKT_DATAPTR(pPacket);
+ pktLen = GET_OS_PKT_LEN(pPacket);
+
+ ASSERT(pSrcBuf);
+
+ RTMP_SET_PACKET_SPECIFIC(pPacket, 0);
+
+ // get Ethernet protocol field
+ TypeLen = (pSrcBuf[12] << 8) + pSrcBuf[13];
+
+ pSrcBuf += LENGTH_802_3; // Skip the Ethernet Header.
+
+ if (TypeLen <= 1500)
+ { // 802.3, 802.3 LLC
+ /*
+ DestMAC(6) + SrcMAC(6) + Lenght(2) +
+ DSAP(1) + SSAP(1) + Control(1) +
+ if the DSAP = 0xAA, SSAP=0xAA, Contorl = 0x03, it has a 5-bytes SNAP header.
+ => + SNAP (5, OriginationID(3) + etherType(2))
+ */
+ if (pSrcBuf[0] == 0xAA && pSrcBuf[1] == 0xAA && pSrcBuf[2] == 0x03)
+ {
+ Sniff2BytesFromNdisBuffer(pSrcBuf, 6, &Byte0, &Byte1);
+ RTMP_SET_PACKET_LLCSNAP(pPacket, 1);
+ TypeLen = (USHORT)((Byte0 << 8) + Byte1);
+ pSrcBuf += 8; // Skip this LLC/SNAP header
+ }
+ else
+ {
+ //It just has 3-byte LLC header, maybe a legacy ether type frame. we didn't handle it.
+ }
+ }
+
+ // If it's a VLAN packet, get the real Type/Length field.
+ if (TypeLen == 0x8100)
+ {
+ /* 0x8100 means VLAN packets */
+
+ /* Dest. MAC Address (6-bytes) +
+ Source MAC Address (6-bytes) +
+ Length/Type = 802.1Q Tag Type (2-byte) +
+ Tag Control Information (2-bytes) +
+ Length / Type (2-bytes) +
+ data payload (0-n bytes) +
+ Pad (0-p bytes) +
+ Frame Check Sequence (4-bytes) */
+
+ RTMP_SET_PACKET_VLAN(pPacket, 1);
+ Sniff2BytesFromNdisBuffer(pSrcBuf, 2, &Byte0, &Byte1);
+ TypeLen = (USHORT)((Byte0 << 8) + Byte1);
+
+ pSrcBuf += 4; // Skip the VLAN Header.
+ }
+
+ switch (TypeLen)
+ {
+ case 0x0800:
+ {
+ ASSERT((pktLen > 34));
+ if (*(pSrcBuf + 9) == 0x11)
+ { // udp packet
+ ASSERT((pktLen > 34)); // 14 for ethernet header, 20 for IP header
+
+ pSrcBuf += 20; // Skip the IP header
+ srcPort = OS_NTOHS(*((UINT16 *)pSrcBuf));
+ dstPort = OS_NTOHS(*((UINT16 *)(pSrcBuf +2)));
+
+ if ((srcPort==0x44 && dstPort==0x43) || (srcPort==0x43 && dstPort==0x44))
+ { //It's a BOOTP/DHCP packet
+ RTMP_SET_PACKET_DHCP(pPacket, 1);
+ }
+ }
+ }
+ break;
+ case 0x0806:
+ {
+ //ARP Packet.
+ RTMP_SET_PACKET_DHCP(pPacket, 1);
+ }
+ break;
+ case 0x888e:
+ {
+ // EAPOL Packet.
+ RTMP_SET_PACKET_EAPOL(pPacket, 1);
+ }
+ break;
+ default:
+ status = FALSE;
+ break;
+ }
+
+ return status;
+
+}
+
+
+
+VOID Update_Rssi_Sample(
+ IN PRTMP_ADAPTER pAd,
+ IN RSSI_SAMPLE *pRssi,
+ IN PRXWI_STRUC pRxWI)
+ {
+ CHAR rssi0 = pRxWI->RSSI0;
+ CHAR rssi1 = pRxWI->RSSI1;
+ CHAR rssi2 = pRxWI->RSSI2;
+
+ if (rssi0 != 0)
+ {
+ pRssi->LastRssi0 = ConvertToRssi(pAd, (CHAR)rssi0, RSSI_0);
+ pRssi->AvgRssi0X8 = (pRssi->AvgRssi0X8 - pRssi->AvgRssi0) + pRssi->LastRssi0;
+ pRssi->AvgRssi0 = pRssi->AvgRssi0X8 >> 3;
+ }
+
+ if (rssi1 != 0)
+ {
+ pRssi->LastRssi1 = ConvertToRssi(pAd, (CHAR)rssi1, RSSI_1);
+ pRssi->AvgRssi1X8 = (pRssi->AvgRssi1X8 - pRssi->AvgRssi1) + pRssi->LastRssi1;
+ pRssi->AvgRssi1 = pRssi->AvgRssi1X8 >> 3;
+ }
+
+ if (rssi2 != 0)
+ {
+ pRssi->LastRssi2 = ConvertToRssi(pAd, (CHAR)rssi2, RSSI_2);
+ pRssi->AvgRssi2X8 = (pRssi->AvgRssi2X8 - pRssi->AvgRssi2) + pRssi->LastRssi2;
+ pRssi->AvgRssi2 = pRssi->AvgRssi2X8 >> 3;
+ }
+}
+
+
+
+// Normal legacy Rx packet indication
+VOID Indicate_Legacy_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ UCHAR Header802_3[LENGTH_802_3];
+
+ // 1. get 802.3 Header
+ // 2. remove LLC
+ // a. pointer pRxBlk->pData to payload
+ // b. modify pRxBlk->DataSize
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pRxBlk->DataSize > MAX_RX_PKT_LEN)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+
+ STATS_INC_RX_PACKETS(pAd, FromWhichBSSID);
+
+#ifdef RT2870
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.bDisableReordering == 0)
+ {
+ PBA_REC_ENTRY pBAEntry;
+ ULONG Now32;
+ UCHAR Wcid = pRxBlk->pRxWI->WirelessCliID;
+ UCHAR TID = pRxBlk->pRxWI->TID;
+ USHORT Idx;
+
+#define REORDERING_PACKET_TIMEOUT ((100 * HZ)/1000) // system ticks -- 100 ms
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ Idx = pAd->MacTab.Content[Wcid].BARecWcidArray[TID];
+ if (Idx != 0)
+ {
+ pBAEntry = &pAd->BATable.BARecEntry[Idx];
+ // update last rx time
+ NdisGetSystemUpTime(&Now32);
+ if ((pBAEntry->list.qlen > 0) &&
+ RTMP_TIME_AFTER((unsigned long)Now32, (unsigned long)(pBAEntry->LastIndSeqAtTimer+(REORDERING_PACKET_TIMEOUT)))
+ )
+ {
+ printk("Indicate_Legacy_Packet():flush reordering_timeout_mpdus! RxWI->Flags=%d, pRxWI.TID=%d, RxD->AMPDU=%d!\n", pRxBlk->Flags, pRxBlk->pRxWI->TID, pRxBlk->RxD.AMPDU);
+ hex_dump("Dump the legacy Packet:", GET_OS_PKT_DATAPTR(pRxBlk->pRxPacket), 64);
+ ba_flush_reordering_timeout_mpdus(pAd, pBAEntry, Now32);
+ }
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+#endif // RT2870 //
+
+ wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
+
+ //
+ // pass this 802.3 packet to upper layer or forward this packet to WM directly
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxPacket, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+
+// Normal, AMPDU or AMSDU
+VOID CmmRxnonRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+#ifdef DOT11_N_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+#ifdef DOT11_N_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMSDU))
+ {
+ // handle A-MSDU
+ Indicate_AMSDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ }
+}
+
+
+VOID CmmRxRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ UCHAR Header802_3[LENGTH_802_3];
+ UINT16 Msdu2Size;
+ UINT16 Payload1Size, Payload2Size;
+ PUCHAR pData2;
+ PNDIS_PACKET pPacket2 = NULL;
+
+
+
+ Msdu2Size = *(pRxBlk->pData) + (*(pRxBlk->pData+1) << 8);
+
+ if ((Msdu2Size <= 1536) && (Msdu2Size < pRxBlk->DataSize))
+ {
+ /* skip two byte MSDU2 len */
+ pRxBlk->pData += 2;
+ pRxBlk->DataSize -= 2;
+ }
+ else
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // get 802.3 Header and remove LLC
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(pRxBlk, Header802_3);
+#endif // CONFIG_STA_SUPPORT //
+
+
+ ASSERT(pRxBlk->pRxPacket);
+
+ // Ralink Aggregation frame
+ pAd->RalinkCounters.OneSecRxAggregationCount ++;
+ Payload1Size = pRxBlk->DataSize - Msdu2Size;
+ Payload2Size = Msdu2Size - LENGTH_802_3;
+
+ pData2 = pRxBlk->pData + Payload1Size + LENGTH_802_3;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pPacket2 = duplicate_pkt(pAd, (pData2-LENGTH_802_3), LENGTH_802_3, pData2, Payload2Size, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+ if (!pPacket2)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // update payload size of 1st packet
+ pRxBlk->DataSize = Payload1Size;
+ wlan_802_11_to_802_3_packet(pAd, pRxBlk, Header802_3, FromWhichBSSID);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pRxBlk->pRxPacket, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pPacket2)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ ANNOUNCE_OR_FORWARD_802_3_PACKET(pAd, pPacket2, FromWhichBSSID);
+#endif // CONFIG_STA_SUPPORT //
+ }
+}
+
+
+#define RESET_FRAGFRAME(_fragFrame) \
+ { \
+ _fragFrame.RxSize = 0; \
+ _fragFrame.Sequence = 0; \
+ _fragFrame.LastFrag = 0; \
+ _fragFrame.Flags = 0; \
+ }
+
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ UCHAR *pData = pRxBlk->pData;
+ USHORT DataSize = pRxBlk->DataSize;
+ PNDIS_PACKET pRetPacket = NULL;
+ UCHAR *pFragBuffer = NULL;
+ BOOLEAN bReassDone = FALSE;
+ UCHAR HeaderRoom = 0;
+
+
+ ASSERT(pHeader);
+
+ HeaderRoom = pData - (UCHAR *)pHeader;
+
+ // Re-assemble the fragmented packets
+ if (pHeader->Frag == 0) // Frag. Number is 0 : First frag or only one pkt
+ {
+ // the first pkt of fragment, record it.
+ if (pHeader->FC.MoreFrag)
+ {
+ ASSERT(pAd->FragFrame.pFragPacket);
+ pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
+ pAd->FragFrame.RxSize = DataSize + HeaderRoom;
+ NdisMoveMemory(pFragBuffer, pHeader, pAd->FragFrame.RxSize);
+ pAd->FragFrame.Sequence = pHeader->Sequence;
+ pAd->FragFrame.LastFrag = pHeader->Frag; // Should be 0
+ ASSERT(pAd->FragFrame.LastFrag == 0);
+ goto done; // end of processing this frame
+ }
+ }
+ else //Middle & End of fragment
+ {
+ if ((pHeader->Sequence != pAd->FragFrame.Sequence) ||
+ (pHeader->Frag != (pAd->FragFrame.LastFrag + 1)))
+ {
+ // Fragment is not the same sequence or out of fragment number order
+ // Reset Fragment control blk
+ RESET_FRAGFRAME(pAd->FragFrame);
+ DBGPRINT(RT_DEBUG_ERROR, ("Fragment is not the same sequence or out of fragment number order.\n"));
+ goto done; // give up this frame
+ }
+ else if ((pAd->FragFrame.RxSize + DataSize) > MAX_FRAME_SIZE)
+ {
+ // Fragment frame is too large, it exeeds the maximum frame size.
+ // Reset Fragment control blk
+ RESET_FRAGFRAME(pAd->FragFrame);
+ DBGPRINT(RT_DEBUG_ERROR, ("Fragment frame is too large, it exeeds the maximum frame size.\n"));
+ goto done; // give up this frame
+ }
+
+ //
+ // Broadcom AP(BCM94704AGR) will send out LLC in fragment's packet, LLC only can accpet at first fragment.
+ // In this case, we will dropt it.
+ //
+ if (NdisEqualMemory(pData, SNAP_802_1H, sizeof(SNAP_802_1H)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Find another LLC at Middle or End fragment(SN=%d, Frag=%d)\n", pHeader->Sequence, pHeader->Frag));
+ goto done; // give up this frame
+ }
+
+ pFragBuffer = GET_OS_PKT_DATAPTR(pAd->FragFrame.pFragPacket);
+
+ // concatenate this fragment into the re-assembly buffer
+ NdisMoveMemory((pFragBuffer + pAd->FragFrame.RxSize), pData, DataSize);
+ pAd->FragFrame.RxSize += DataSize;
+ pAd->FragFrame.LastFrag = pHeader->Frag; // Update fragment number
+
+ // Last fragment
+ if (pHeader->FC.MoreFrag == FALSE)
+ {
+ bReassDone = TRUE;
+ }
+ }
+
+done:
+ // always release rx fragmented packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+
+ // return defragmented packet if packet is reassembled completely
+ // otherwise return NULL
+ if (bReassDone)
+ {
+ PNDIS_PACKET pNewFragPacket;
+
+ // allocate a new packet buffer for fragment
+ pNewFragPacket = RTMP_AllocateFragPacketBuffer(pAd, RX_BUFFER_NORMSIZE);
+ if (pNewFragPacket)
+ {
+ // update RxBlk
+ pRetPacket = pAd->FragFrame.pFragPacket;
+ pAd->FragFrame.pFragPacket = pNewFragPacket;
+ pRxBlk->pHeader = (PHEADER_802_11) GET_OS_PKT_DATAPTR(pRetPacket);
+ pRxBlk->pData = (UCHAR *)pRxBlk->pHeader + HeaderRoom;
+ pRxBlk->DataSize = pAd->FragFrame.RxSize - HeaderRoom;
+ pRxBlk->pRxPacket = pRetPacket;
+ }
+ else
+ {
+ RESET_FRAGFRAME(pAd->FragFrame);
+ }
+ }
+
+ return pRetPacket;
+}
+
+
+VOID Indicate_AMSDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ UINT nMSDU;
+
+ update_os_packet_info(pAd, pRxBlk, FromWhichBSSID);
+ RTMP_SET_PACKET_IF(pRxBlk->pRxPacket, FromWhichBSSID);
+ nMSDU = deaggregate_AMSDU_announce(pAd, pRxBlk->pRxPacket, pRxBlk->pData, pRxBlk->DataSize);
+}
+
+VOID Indicate_EAPOL_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pEntry == NULL)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("Indicate_EAPOL_Packet: drop and release the invalid packet.\n"));
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+}
+
+#define BCN_TBTT_OFFSET 64 //defer 64 us
+VOID ReSyncBeaconTime(
+ IN PRTMP_ADAPTER pAd)
+{
+
+ UINT32 Offset;
+
+
+ Offset = (pAd->TbttTickCount) % (BCN_TBTT_OFFSET);
+
+ pAd->TbttTickCount++;
+
+ //
+ // The updated BeaconInterval Value will affect Beacon Interval after two TBTT
+ // beacasue the original BeaconInterval had been loaded into next TBTT_TIMER
+ //
+ if (Offset == (BCN_TBTT_OFFSET-2))
+ {
+ BCN_TIME_CFG_STRUC csr;
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod << 4) - 1 ; // ASIC register in units of 1/16 TU = 64us
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+ }
+ else
+ {
+ if (Offset == (BCN_TBTT_OFFSET-1))
+ {
+ BCN_TIME_CFG_STRUC csr;
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ csr.field.BeaconInterval = (pAd->CommonCfg.BeaconPeriod) << 4; // ASIC register in units of 1/16 TU
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+ }
+ }
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_data_2870.c b/drivers/staging/rt3070/common/cmm_data_2870.c
new file mode 100644
index 00000000000..b1066aa2bb2
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_data_2870.c
@@ -0,0 +1,980 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+*/
+/*
+ All functions in this file must be USB-depended, or you should out your function
+ in other files.
+
+*/
+#include "../rt_config.h"
+
+
+/*
+ We can do copy the frame into pTxContext when match following conditions.
+ =>
+ =>
+ =>
+*/
+static inline NDIS_STATUS RtmpUSBCanDoWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN HT_TX_CONTEXT *pHTTXContext)
+{
+ NDIS_STATUS canWrite = NDIS_STATUS_RESOURCES;
+
+ if (((pHTTXContext->CurWritePosition) < pHTTXContext->NextBulkOutPosition) && (pHTTXContext->CurWritePosition + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c1!\n"));
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+ }
+ else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < LOCAL_TXBUF_SIZE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c2!\n"));
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+ }
+ else if (pHTTXContext->bCurWriting == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("RtmpUSBCanDoWrite c3!\n"));
+ }
+ else
+ {
+ canWrite = NDIS_STATUS_SUCCESS;
+ }
+
+
+ return canWrite;
+}
+
+
+USHORT RtmpUSB_WriteSubTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber)
+{
+
+ // Dummy function. Should be removed in the future.
+ return 0;
+
+}
+
+USHORT RtmpUSB_WriteFragTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR fragNum,
+ OUT USHORT *FreeNumber)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ PUCHAR pWirelessPacket = NULL;
+ UCHAR QueIdx;
+ NDIS_STATUS Status;
+ unsigned long IrqFlags;
+ UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
+ BOOLEAN TxQLastRound = FALSE;
+
+ //
+ // get Tx Ring Resource & Dma Buffer address
+ //
+ QueIdx = pTxBlk->QueIdx;
+ pHTTXContext = &pAd->TxContext[QueIdx];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ pHTTXContext = &pAd->TxContext[QueIdx];
+ fillOffset = pHTTXContext->CurWritePosition;
+
+ if(fragNum == 0)
+ {
+ // Check if we have enough space for this bulk-out batch.
+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ pHTTXContext->bCurWriting = TRUE;
+
+ // Reserve space for 8 bytes padding.
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+ {
+ pHTTXContext->ENextBulkOutPosition += 8;
+ pHTTXContext->CurWritePosition += 8;
+ fillOffset += 8;
+ }
+ pTxBlk->Priv = 0;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return(Status);
+ }
+ }
+ else
+ {
+ // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+ Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ fillOffset += pTxBlk->Priv;
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return(Status);
+ }
+ }
+
+ NdisZeroMemory((PUCHAR)(&pTxBlk->HeaderBuf[0]), TXINFO_SIZE);
+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ // copy TXWI + WLAN Header + LLC into DMA Header Buffer
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+ // Build our URB for USBD
+ DMAHdrLen = TXWI_SIZE + hwHdrLen;
+ USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
+ USBDMApktLen += padding;
+
+ pTxBlk->Priv += (TXINFO_SIZE + USBDMApktLen);
+
+ // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
+
+ if (fragNum == pTxBlk->TotalFragNum)
+ {
+ pTxInfo->USBDMATxburst = 0;
+ if ((pHTTXContext->CurWritePosition + pTxBlk->Priv + 3906)> MAX_TXBULK_LIMIT)
+ {
+ pTxInfo->SwUseLastRound = 1;
+ TxQLastRound = TRUE;
+ }
+ }
+ else
+ {
+ pTxInfo->USBDMATxburst = 1;
+ }
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+ pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+
+ // Zero the last padding.
+ pWirelessPacket += pTxBlk->SrcBufLen;
+ NdisZeroMemory(pWirelessPacket, padding + 8);
+
+ if (fragNum == pTxBlk->TotalFragNum)
+ {
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ // Update the pHTTXContext->CurWritePosition. 3906 used to prevent the NextBulkOut is a A-RALINK/A-MSDU Frame.
+ pHTTXContext->CurWritePosition += pTxBlk->Priv;
+ if (TxQLastRound == TRUE)
+ pHTTXContext->CurWritePosition = 8;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+ // Finally, set bCurWriting as FALSE
+ pHTTXContext->bCurWriting = FALSE;
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ // succeed and release the skb buffer
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+ }
+
+
+ return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteSingleTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ USHORT hwHdrLen;
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ PUCHAR pWirelessPacket;
+ UCHAR QueIdx;
+ unsigned long IrqFlags;
+ NDIS_STATUS Status;
+ UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
+ BOOLEAN bTxQLastRound = FALSE;
+
+ // For USB, didn't need PCI_MAP_SINGLE()
+ //SrcBufPA = PCI_MAP_SINGLE(pAd, (char *) pTxBlk->pSrcBufData, pTxBlk->SrcBufLen, PCI_DMA_TODEVICE);
+
+
+ //
+ // get Tx Ring Resource & Dma Buffer address
+ //
+ QueIdx = pTxBlk->QueIdx;
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+ pHTTXContext = &pAd->TxContext[QueIdx];
+ fillOffset = pHTTXContext->CurWritePosition;
+
+
+
+ // Check ring full.
+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+ if(Status == NDIS_STATUS_SUCCESS)
+ {
+ pHTTXContext->bCurWriting = TRUE;
+
+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+ // Reserve space for 8 bytes padding.
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+ {
+ pHTTXContext->ENextBulkOutPosition += 8;
+ pHTTXContext->CurWritePosition += 8;
+ fillOffset += 8;
+ }
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ // copy TXWI + WLAN Header + LLC into DMA Header Buffer
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+ // Build our URB for USBD
+ DMAHdrLen = TXWI_SIZE + hwHdrLen;
+ USBDMApktLen = DMAHdrLen + pTxBlk->SrcBufLen;
+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
+ USBDMApktLen += padding;
+
+ pTxBlk->Priv = (TXINFO_SIZE + USBDMApktLen);
+
+ // For TxInfo, the length of USBDMApktLen = TXWI_SIZE + 802.11 header + payload
+ //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(USBDMApktLen), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
+#endif // CONFIG_STA_SUPPORT //
+
+ if ((pHTTXContext->CurWritePosition + 3906 + pTxBlk->Priv) > MAX_TXBULK_LIMIT)
+ {
+ pTxInfo->SwUseLastRound = 1;
+ bTxQLastRound = TRUE;
+ }
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket + TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pWirelessPacket += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+
+ // We unlock it here to prevent the first 8 bytes maybe over-writed issue.
+ // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxcontext.
+ // 2. An interrupt break our routine and handle bulk-out complete.
+ // 3. In the bulk-out compllete, it need to do another bulk-out,
+ // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+ // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+ // 4. Interrupt complete.
+ // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+ // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+ // and the packet will wrong.
+ pHTTXContext->CurWriteRealPos += (TXINFO_SIZE + TXWI_SIZE + hwHdrLen);
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+ pWirelessPacket += pTxBlk->SrcBufLen;
+ NdisZeroMemory(pWirelessPacket, padding + 8);
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ pHTTXContext->CurWritePosition += pTxBlk->Priv;
+ if (bTxQLastRound)
+ pHTTXContext->CurWritePosition = 8;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+ pHTTXContext->bCurWriting = FALSE;
+ }
+
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+
+ // succeed and release the skb buffer
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+ return(Status);
+
+}
+
+
+USHORT RtmpUSB_WriteMultiTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR frameNum,
+ OUT USHORT *FreeNumber)
+{
+ HT_TX_CONTEXT *pHTTXContext;
+ USHORT hwHdrLen; // The hwHdrLen consist of 802.11 header length plus the header padding length.
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ PUCHAR pWirelessPacket = NULL;
+ UCHAR QueIdx;
+ NDIS_STATUS Status;
+ unsigned long IrqFlags;
+ //UINT32 USBDMApktLen = 0, DMAHdrLen, padding;
+
+ //
+ // get Tx Ring Resource & Dma Buffer address
+ //
+ QueIdx = pTxBlk->QueIdx;
+ pHTTXContext = &pAd->TxContext[QueIdx];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ if(frameNum == 0)
+ {
+ // Check if we have enough space for this bulk-out batch.
+ Status = RtmpUSBCanDoWrite(pAd, QueIdx, pHTTXContext);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ pHTTXContext->bCurWriting = TRUE;
+
+ pTxInfo = (PTXINFO_STRUC)(&pTxBlk->HeaderBuf[0]);
+ pTxWI= (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]);
+
+
+ // Reserve space for 8 bytes padding.
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition))
+ {
+
+ pHTTXContext->CurWritePosition += 8;
+ pHTTXContext->ENextBulkOutPosition += 8;
+ }
+ fillOffset = pHTTXContext->CurWritePosition;
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ //
+ // Copy TXINFO + TXWI + WLAN Header + LLC into DMA Header Buffer
+ //
+ if (pTxBlk->TxFrameType == TX_AMSDU_FRAME)
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD, 4)+LENGTH_AMSDU_SUBFRAMEHEAD;
+ hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_AMSDU_SUBFRAMEHEAD + pTxBlk->HdrPadLen + LENGTH_AMSDU_SUBFRAMEHEAD;
+ else if (pTxBlk->TxFrameType == TX_RALINK_FRAME)
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD, 4)+LENGTH_ARALINK_HEADER_FIELD;
+ hwHdrLen = pTxBlk->MpduHeaderLen-LENGTH_ARALINK_HEADER_FIELD + pTxBlk->HdrPadLen + LENGTH_ARALINK_HEADER_FIELD;
+ else
+ //hwHdrLen = ROUND_UP(pTxBlk->MpduHeaderLen, 4);
+ hwHdrLen = pTxBlk->MpduHeaderLen + pTxBlk->HdrPadLen;
+
+ // Update the pTxBlk->Priv.
+ pTxBlk->Priv = TXINFO_SIZE + TXWI_SIZE + hwHdrLen;
+
+ // pTxInfo->USBDMApktLen now just a temp value and will to correct latter.
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(pTxBlk->Priv), FALSE, FIFO_EDCA, FALSE /*NextValid*/, FALSE);
+
+ // Copy it.
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->Priv);
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)(pWirelessPacket+ TXINFO_SIZE + TXWI_SIZE), DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pHTTXContext->CurWriteRealPos += pTxBlk->Priv;
+ pWirelessPacket += pTxBlk->Priv;
+ }
+ }
+ else
+ { // For sub-sequent frames of this bulk-out batch. Just copy it to our bulk-out buffer.
+
+ Status = ((pHTTXContext->bCurWriting == TRUE) ? NDIS_STATUS_SUCCESS : NDIS_STATUS_FAILURE);
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ fillOffset = (pHTTXContext->CurWritePosition + pTxBlk->Priv);
+ pWirelessPacket = &pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset];
+
+ //hwHdrLen = pTxBlk->MpduHeaderLen;
+ NdisMoveMemory(pWirelessPacket, pTxBlk->HeaderBuf, pTxBlk->MpduHeaderLen);
+ pWirelessPacket += (pTxBlk->MpduHeaderLen);
+ pTxBlk->Priv += pTxBlk->MpduHeaderLen;
+ }
+ else
+ { // It should not happened now unless we are going to shutdown.
+ DBGPRINT(RT_DEBUG_ERROR, ("WriteMultiTxResource():bCurWriting is FALSE when handle sub-sequent frames.\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ }
+
+
+ // We unlock it here to prevent the first 8 bytes maybe over-write issue.
+ // 1. First we got CurWritePosition but the first 8 bytes still not write to the pTxContext.
+ // 2. An interrupt break our routine and handle bulk-out complete.
+ // 3. In the bulk-out compllete, it need to do another bulk-out,
+ // if the ENextBulkOutPosition is just the same as CurWritePosition, it will save the first 8 bytes from CurWritePosition,
+ // but the payload still not copyed. the pTxContext->SavedPad[] will save as allzero. and set the bCopyPad = TRUE.
+ // 4. Interrupt complete.
+ // 5. Our interrupted routine go back and fill the first 8 bytes to pTxContext.
+ // 6. Next time when do bulk-out, it found the bCopyPad==TRUE and will copy the SavedPad[] to pTxContext->NextBulkOutPosition.
+ // and the packet will wrong.
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("WriteMultiTxResource: CWPos = %ld, NBOutPos = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
+ goto done;
+ }
+
+ // Copy the frame content into DMA buffer and update the pTxBlk->Priv
+ NdisMoveMemory(pWirelessPacket, pTxBlk->pSrcBufData, pTxBlk->SrcBufLen);
+ pWirelessPacket += pTxBlk->SrcBufLen;
+ pTxBlk->Priv += pTxBlk->SrcBufLen;
+
+done:
+ // Release the skb buffer here
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_SUCCESS);
+
+ return(Status);
+
+}
+
+
+VOID RtmpUSB_FinalWriteTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN USHORT totalMPDUSize,
+ IN USHORT TxIdx)
+{
+ UCHAR QueIdx;
+ HT_TX_CONTEXT *pHTTXContext;
+ UINT32 fillOffset;
+ TXINFO_STRUC *pTxInfo;
+ TXWI_STRUC *pTxWI;
+ UINT32 USBDMApktLen, padding;
+ unsigned long IrqFlags;
+ PUCHAR pWirelessPacket;
+
+ QueIdx = pTxBlk->QueIdx;
+ pHTTXContext = &pAd->TxContext[QueIdx];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+ if (pHTTXContext->bCurWriting == TRUE)
+ {
+ fillOffset = pHTTXContext->CurWritePosition;
+ if (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
+ && (pHTTXContext->bCopySavePad == TRUE))
+ pWirelessPacket = (PUCHAR)(&pHTTXContext->SavedPad[0]);
+ else
+ pWirelessPacket = (PUCHAR)(&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset]);
+
+ //
+ // Update TxInfo->USBDMApktLen ,
+ // the length = TXWI_SIZE + 802.11_hdr + 802.11_hdr_pad + payload_of_all_batch_frames + Bulk-Out-padding
+ //
+ pTxInfo = (PTXINFO_STRUC)(pWirelessPacket);
+
+ // Calculate the bulk-out padding
+ USBDMApktLen = pTxBlk->Priv - TXINFO_SIZE;
+ padding = (4 - (USBDMApktLen % 4)) & 0x03; // round up to 4 byte alignment
+ USBDMApktLen += padding;
+
+ pTxInfo->USBDMATxPktLen = USBDMApktLen;
+
+ //
+ // Update TXWI->MPDUtotalByteCount ,
+ // the length = 802.11 header + payload_of_all_batch_frames
+ pTxWI= (PTXWI_STRUC)(pWirelessPacket + TXINFO_SIZE);
+ pTxWI->MPDUtotalByteCount = totalMPDUSize;
+
+ //
+ // Update the pHTTXContext->CurWritePosition
+ //
+ pHTTXContext->CurWritePosition += (TXINFO_SIZE + USBDMApktLen);
+ if ((pHTTXContext->CurWritePosition + 3906)> MAX_TXBULK_LIMIT)
+ { // Add 3906 for prevent the NextBulkOut packet size is a A-RALINK/A-MSDU Frame.
+ pHTTXContext->CurWritePosition = 8;
+ pTxInfo->SwUseLastRound = 1;
+ }
+ pHTTXContext->CurWriteRealPos = pHTTXContext->CurWritePosition;
+
+
+ //
+ // Zero the last padding.
+ //
+ pWirelessPacket = (&pHTTXContext->TransferBuffer->field.WirelessPacket[fillOffset + pTxBlk->Priv]);
+ NdisZeroMemory(pWirelessPacket, padding + 8);
+
+ // Finally, set bCurWriting as FALSE
+ pHTTXContext->bCurWriting = FALSE;
+
+ }
+ else
+ { // It should not happened now unless we are going to shutdown.
+ DBGPRINT(RT_DEBUG_ERROR, ("FinalWriteTxResource():bCurWriting is FALSE when handle last frames.\n"));
+ }
+
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+
+}
+
+
+VOID RtmpUSBDataLastTxIdx(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN USHORT TxIdx)
+{
+ // DO nothing for USB.
+}
+
+
+/*
+ When can do bulk-out:
+ 1. TxSwFreeIdx < TX_RING_SIZE;
+ It means has at least one Ring entity is ready for bulk-out, kick it out.
+ 2. If TxSwFreeIdx == TX_RING_SIZE
+ Check if the CurWriting flag is FALSE, if it's FALSE, we can do kick out.
+
+*/
+VOID RtmpUSBDataKickOut(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx)
+{
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << QueIdx));
+ RTUSBKickBulkOut(pAd);
+
+}
+
+
+/*
+ Must be run in Interrupt context
+ This function handle RT2870 specific TxDesc and cpu index update and kick the packet out.
+ */
+int RtmpUSBMgmtKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pSrcBufVA,
+ IN UINT SrcBufLen)
+{
+ PTXINFO_STRUC pTxInfo;
+ ULONG BulkOutSize;
+ UCHAR padLen;
+ PUCHAR pDest;
+ ULONG SwIdx = pAd->MgmtRing.TxCpuIdx;
+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[SwIdx].AllocVa;
+ unsigned long IrqFlags;
+
+
+ pTxInfo = (PTXINFO_STRUC)(pSrcBufVA);
+
+ // Build our URB for USBD
+ BulkOutSize = SrcBufLen;
+ BulkOutSize = (BulkOutSize + 3) & (~3);
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(BulkOutSize - TXINFO_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+
+ BulkOutSize += 4; // Always add 4 extra bytes at every packet.
+
+ // If BulkOutSize is multiple of BulkOutMaxPacketSize, add extra 4 bytes again.
+ if ((BulkOutSize % pAd->BulkOutMaxPacketSize) == 0)
+ BulkOutSize += 4;
+
+ padLen = BulkOutSize - SrcBufLen;
+ ASSERT((padLen <= RTMP_PKT_TAIL_PADDING));
+
+ // Now memzero all extra padding bytes.
+ pDest = (PUCHAR)(pSrcBufVA + SrcBufLen);
+ skb_put(GET_OS_PKT_TYPE(pPacket), padLen);
+ NdisZeroMemory(pDest, padLen);
+
+ RTMP_IRQ_LOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+ pAd->MgmtRing.Cell[pAd->MgmtRing.TxCpuIdx].pNdisPacket = pPacket;
+ pMLMEContext->TransferBuffer = (PTX_BUFFER)(GET_OS_PKT_DATAPTR(pPacket));
+
+ // Length in TxInfo should be 8 less than bulkout size.
+ pMLMEContext->BulkOutSize = BulkOutSize;
+ pMLMEContext->InUse = TRUE;
+ pMLMEContext->bWaitingBulkOut = TRUE;
+
+
+ //for debug
+ //hex_dump("RtmpUSBMgmtKickOut", &pMLMEContext->TransferBuffer->field.WirelessPacket[0], (pMLMEContext->BulkOutSize > 16 ? 16 : pMLMEContext->BulkOutSize));
+
+ //pAd->RalinkCounters.KickTxCount++;
+ //pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ //if (pAd->MgmtRing.TxSwFreeIdx == MGMT_RING_SIZE)
+ // needKickOut = TRUE;
+
+ // Decrease the TxSwFreeIdx and Increase the TX_CTX_IDX
+ pAd->MgmtRing.TxSwFreeIdx--;
+ INC_RING_INDEX(pAd->MgmtRing.TxCpuIdx, MGMT_RING_SIZE);
+
+ RTMP_IRQ_UNLOCK(&pAd->MLMEBulkOutLock, IrqFlags);
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+ //if (needKickOut)
+ RTUSBKickBulkOut(pAd);
+
+ return 0;
+}
+
+
+VOID RtmpUSBNullFrameKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR *pNullFrame,
+ IN UINT32 frameLen)
+{
+ if (pAd->NullContext.InUse == FALSE)
+ {
+ PTX_CONTEXT pNullContext;
+ PTXINFO_STRUC pTxInfo;
+ PTXWI_STRUC pTxWI;
+ PUCHAR pWirelessPkt;
+
+ pNullContext = &(pAd->NullContext);
+
+ // Set the in use bit
+ pNullContext->InUse = TRUE;
+ pWirelessPkt = (PUCHAR)&pNullContext->TransferBuffer->field.WirelessPacket[0];
+
+ RTMPZeroMemory(&pWirelessPkt[0], 100);
+ pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[0];
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxInfo->QSEL = FIFO_EDCA;
+ pTxWI = (PTXWI_STRUC)&pWirelessPkt[TXINFO_SIZE];
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+ RTMPMoveMemory(&pWirelessPkt[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)&pWirelessPkt[TXINFO_SIZE + TXWI_SIZE], DIR_WRITE, FALSE);
+#endif // RT_BIG_ENDIAN //
+ pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+
+ // Fill out frame length information for global Bulk out arbitor
+ //pNullContext->BulkOutSize = TransferBufferLength;
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - send NULL Frame @%d Mbps...\n", RateIdToMbps[pAd->CommonCfg.TxRate]));
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+ }
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ Check Rx descriptor, return NDIS_STATUS_FAILURE if any error dound
+
+ Arguments:
+ pRxD Pointer to the Rx descriptor
+
+ Return Value:
+ NDIS_STATUS_SUCCESS No err
+ NDIS_STATUS_FAILURE Error
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPCheckRxError(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC pRxINFO)
+{
+ PCIPHER_KEY pWpaKey;
+ INT dBm;
+
+ if (pAd->bPromiscuous == TRUE)
+ return(NDIS_STATUS_SUCCESS);
+ if(pRxINFO == NULL)
+ return(NDIS_STATUS_FAILURE);
+
+ // Phy errors & CRC errors
+ if (pRxINFO->Crc)
+ {
+ // Check RSSI for Noise Hist statistic collection.
+ dBm = (INT) (pRxWI->RSSI0) - pAd->BbpRssiToDbmDelta;
+ if (dBm <= -87)
+ pAd->StaCfg.RPIDensity[0] += 1;
+ else if (dBm <= -82)
+ pAd->StaCfg.RPIDensity[1] += 1;
+ else if (dBm <= -77)
+ pAd->StaCfg.RPIDensity[2] += 1;
+ else if (dBm <= -72)
+ pAd->StaCfg.RPIDensity[3] += 1;
+ else if (dBm <= -67)
+ pAd->StaCfg.RPIDensity[4] += 1;
+ else if (dBm <= -62)
+ pAd->StaCfg.RPIDensity[5] += 1;
+ else if (dBm <= -57)
+ pAd->StaCfg.RPIDensity[6] += 1;
+ else if (dBm > -57)
+ pAd->StaCfg.RPIDensity[7] += 1;
+
+ return(NDIS_STATUS_FAILURE);
+ }
+
+ // Add Rx size to channel load counter, we should ignore error counts
+ pAd->StaCfg.CLBusyBytes += (pRxWI->MPDUtotalByteCount+ 14);
+
+ // Drop ToDs promiscous frame, it is opened due to CCX 2 channel load statistics
+ if (pHeader->FC.ToDs)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Err;FC.ToDs\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // Paul 04-03 for OFDM Rx length issue
+ if (pRxWI->MPDUtotalByteCount > MAX_AGGREGATION_SIZE)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("received packet too long\n"));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // Drop not U2M frames, cant's drop here because we will drop beacon in this case
+ // I am kind of doubting the U2M bit operation
+ // if (pRxD->U2M == 0)
+ // return(NDIS_STATUS_FAILURE);
+
+ // drop decyption fail frame
+ if (pRxINFO->Decrypted && pRxINFO->CipherErr)
+ {
+
+ //
+ // MIC Error
+ //
+ if ((pRxINFO->CipherErr == 2) && pRxINFO->MyBss)
+ {
+ pWpaKey = &pAd->SharedKey[BSS0][pRxWI->KeyIndex];
+ RTMPReportMicError(pAd, pWpaKey);
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error\n"));
+ }
+
+ if (pRxINFO->Decrypted &&
+ (pAd->SharedKey[BSS0][pRxWI->KeyIndex].CipherAlg == CIPHER_AES) &&
+ (pHeader->Sequence == pAd->FragFrame.Sequence))
+ {
+ //
+ // Acceptable since the First FragFrame no CipherErr problem.
+ //
+ return(NDIS_STATUS_SUCCESS);
+ }
+
+ return(NDIS_STATUS_FAILURE);
+ }
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+VOID RT28xxUsbStaAsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx)
+{
+ AUTO_WAKEUP_STRUC AutoWakeupCfg;
+
+ AutoWakeupCfg.word = 0;
+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+ AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+}
+
+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp)
+{
+ AUTO_WAKEUP_STRUC AutoWakeupCfg;
+
+ // we have decided to SLEEP, so at least do it for a BEACON period.
+ if (TbttNumToNextWakeUp == 0)
+ TbttNumToNextWakeUp = 1;
+
+ AutoWakeupCfg.word = 0;
+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+ AutoWakeupCfg.field.NumofSleepingTbtt = TbttNumToNextWakeUp - 1;
+ AutoWakeupCfg.field.EnableAutoWakeup = 1;
+ AutoWakeupCfg.field.AutoLeadTime = 5;
+ RTMP_IO_WRITE32(pAd, AUTO_WAKEUP_CFG, AutoWakeupCfg.word);
+
+ AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02); // send POWER-SAVE command to MCU. Timeout 40us.
+
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_DOZE);
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+VOID RT28xxUsbMlmeRadioOn(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOn()\n"));
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ return;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ AsicSendCommandToMcu(pAd, 0x31, 0xff, 0x00, 0x02);
+ RTMPusecDelay(10000);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ NICResetFromError(pAd);
+
+ // Enable Tx/Rx
+ RTMPEnableRxTx(pAd);
+
+#ifdef RT3070
+ if (IS_RT3071(pAd))
+ {
+ RT30xxReverseRFSleepModeSetup(pAd);
+ }
+#endif // RT3070 //
+
+ // Clear Radio off flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ RTUSBBulkReceive(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+ // Set LED
+ RTMPSetLED(pAd, LED_RADIO_ON);
+}
+
+VOID RT28xxUsbMlmeRadioOFF(
+ IN PRTMP_ADAPTER pAd)
+{
+ WPDMA_GLO_CFG_STRUC GloCfg;
+ UINT32 Value, i;
+
+ DBGPRINT(RT_DEBUG_TRACE,("RT28xxUsbMlmeRadioOFF()\n"));
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ return;
+
+ // Set LED
+ RTMPSetLED(pAd, LED_RADIO_OFF);
+ // Set Radio off flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Link down first if any association exists
+ if (INFRA_ON(pAd) || ADHOC_ON(pAd))
+ LinkDown(pAd, FALSE);
+ RTMPusecDelay(10000);
+
+ //==========================================
+ // Clean up old bss table
+ BssTableInit(&pAd->ScanTab);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ // Must using 40MHz.
+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.CentralChannel);
+ }
+ else
+ {
+ // Must using 20MHz.
+ AsicTurnOffRFClk(pAd, pAd->CommonCfg.Channel);
+ }
+
+ // Disable Tx/Rx DMA
+ RTUSBReadMACRegister(pAd, WPDMA_GLO_CFG, &GloCfg.word); // disable DMA
+ GloCfg.field.EnableTxDMA = 0;
+ GloCfg.field.EnableRxDMA = 0;
+ RTUSBWriteMACRegister(pAd, WPDMA_GLO_CFG, GloCfg.word); // abort all TX rings
+
+ // Waiting for DMA idle
+ i = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+ break;
+
+ RTMPusecDelay(1000);
+ }while (i++ < 100);
+
+ // Disable MAC Tx/Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= (0xfffffff3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // MAC_SYS_CTRL => value = 0x0 => 40mA
+ //RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0);
+
+ // PWR_PIN_CFG => value = 0x0 => 40mA
+ //RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0);
+
+ // TX_PIN_CFG => value = 0x0 => 20mA
+ //RTMP_IO_WRITE32(pAd, TX_PIN_CFG, 0);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AsicSendCommandToMcu(pAd, 0x30, 0xff, 0xff, 0x02);
+#endif // CONFIG_STA_SUPPORT //
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_info.c b/drivers/staging/rt3070/common/cmm_info.c
new file mode 100644
index 00000000000..54cb1a35f7b
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_info.c
@@ -0,0 +1,3395 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+*/
+
+#include "../rt_config.h"
+
+INT Show_SSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+#ifdef DOT11_N_SUPPORT
+INT Show_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // DOT11_N_SUPPORT //
+
+INT Show_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_CountryCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+#ifdef AGGREGATION_SUPPORT
+INT Show_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef WMM_SUPPORT
+INT Show_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // WMM_SUPPORT //
+
+INT Show_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+#ifdef CONFIG_STA_SUPPORT
+INT Show_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+#endif // CONFIG_STA_SUPPORT //
+
+INT Show_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_Key4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+INT Show_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf);
+
+static struct {
+ CHAR *name;
+ INT (*show_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
+} *PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC, RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC[] = {
+ {"SSID", Show_SSID_Proc},
+ {"WirelessMode", Show_WirelessMode_Proc},
+ {"TxBurst", Show_TxBurst_Proc},
+ {"TxPreamble", Show_TxPreamble_Proc},
+ {"TxPower", Show_TxPower_Proc},
+ {"Channel", Show_Channel_Proc},
+ {"BGProtection", Show_BGProtection_Proc},
+ {"RTSThreshold", Show_RTSThreshold_Proc},
+ {"FragThreshold", Show_FragThreshold_Proc},
+#ifdef DOT11_N_SUPPORT
+ {"HtBw", Show_HtBw_Proc},
+ {"HtMcs", Show_HtMcs_Proc},
+ {"HtGi", Show_HtGi_Proc},
+ {"HtOpMode", Show_HtOpMode_Proc},
+ {"HtExtcha", Show_HtExtcha_Proc},
+ {"HtMpduDensity", Show_HtMpduDensity_Proc},
+ {"HtBaWinSize", Show_HtBaWinSize_Proc},
+ {"HtRdg", Show_HtRdg_Proc},
+ {"HtAmsdu", Show_HtAmsdu_Proc},
+ {"HtAutoBa", Show_HtAutoBa_Proc},
+#endif // DOT11_N_SUPPORT //
+ {"CountryRegion", Show_CountryRegion_Proc},
+ {"CountryRegionABand", Show_CountryRegionABand_Proc},
+ {"CountryCode", Show_CountryCode_Proc},
+#ifdef AGGREGATION_SUPPORT
+ {"PktAggregate", Show_PktAggregate_Proc},
+#endif
+
+#ifdef WMM_SUPPORT
+ {"WmmCapable", Show_WmmCapable_Proc},
+#endif
+ {"IEEE80211H", Show_IEEE80211H_Proc},
+#ifdef CONFIG_STA_SUPPORT
+ {"NetworkType", Show_NetworkType_Proc},
+#endif // CONFIG_STA_SUPPORT //
+ {"AuthMode", Show_AuthMode_Proc},
+ {"EncrypType", Show_EncrypType_Proc},
+ {"DefaultKeyID", Show_DefaultKeyID_Proc},
+ {"Key1", Show_Key1_Proc},
+ {"Key2", Show_Key2_Proc},
+ {"Key3", Show_Key3_Proc},
+ {"Key4", Show_Key4_Proc},
+ {"WPAPSK", Show_WPAPSK_Proc},
+ {NULL, NULL}
+};
+
+/*
+ ==========================================================================
+ Description:
+ Get Driver version.
+
+ Return:
+ ==========================================================================
+*/
+INT Set_DriverVersion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ DBGPRINT(RT_DEBUG_TRACE, ("Driver version-%s\n", STA_DRIVER_VERSION));
+#endif // CONFIG_STA_SUPPORT //
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Country Region.
+ This command will not work, if the field of CountryRegion in eeprom is programmed.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG region;
+
+ region = simple_strtol(arg, 0, 10);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // Country can be set only when EEPROM not programmed
+ if (pAd->CommonCfg.CountryRegion & 0x80)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+ return FALSE;
+ }
+
+ if((region >= 0) && (region <= REGION_MAXIMUM_BG_BAND))
+ {
+ pAd->CommonCfg.CountryRegion = (UCHAR) region;
+ }
+ else if (region == REGION_31_BG_BAND)
+ {
+ pAd->CommonCfg.CountryRegion = (UCHAR) region;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegion_Proc::parameters out of range\n"));
+ return FALSE;
+ }
+
+ // if set country region, driver needs to be reset
+ BuildChannelList(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegion_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegion));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Country Region for A band.
+ This command will not work, if the field of CountryRegion in eeprom is programmed.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG region;
+
+ region = simple_strtol(arg, 0, 10);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ return -EOPNOTSUPP;
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // Country can be set only when EEPROM not programmed
+ if (pAd->CommonCfg.CountryRegionForABand & 0x80)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameter of CountryRegion in eeprom is programmed \n"));
+ return FALSE;
+ }
+
+ if((region >= 0) && (region <= REGION_MAXIMUM_A_BAND))
+ {
+ pAd->CommonCfg.CountryRegionForABand = (UCHAR) region;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_CountryRegionABand_Proc::parameters out of range\n"));
+ return FALSE;
+ }
+
+ // if set country region, driver needs to be reset
+ BuildChannelList(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_CountryRegionABand_Proc::(CountryRegion=%d)\n", pAd->CommonCfg.CountryRegionForABand));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Wireless Mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG WirelessMode;
+ INT success = TRUE;
+
+ WirelessMode = simple_strtol(arg, 0, 10);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ INT MaxPhyMode = PHY_11G;
+
+#ifdef DOT11_N_SUPPORT
+ MaxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+ if (WirelessMode <= MaxPhyMode)
+ {
+ RTMPSetPhyMode(pAd, WirelessMode);
+#ifdef DOT11_N_SUPPORT
+ if (WirelessMode >= PHY_11ABGN_MIXED)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+ pAd->CommonCfg.REGBACapability.field.AutoBA = TRUE;
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ pAd->CommonCfg.REGBACapability.field.AutoBA = FALSE;
+ }
+#endif // DOT11_N_SUPPORT //
+ // Set AdhocMode rates
+ if (pAd->StaCfg.BssType == BSS_ADHOC)
+ {
+ MlmeUpdateTxRates(pAd, FALSE, 0);
+ MakeIbssBeacon(pAd); // re-build BEACON frame
+ AsicEnableIbssSync(pAd); // copy to on-chip memory
+ }
+ }
+ else
+ {
+ success = FALSE;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // it is needed to set SSID to take effect
+ if (success == TRUE)
+ {
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WirelessMode_Proc::(=%ld)\n", WirelessMode));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_WirelessMode_Proc::parameters out of range\n"));
+ }
+
+ return success;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Channel
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ INT success = TRUE;
+ UCHAR Channel;
+
+ Channel = (UCHAR) simple_strtol(arg, 0, 10);
+
+ // check if this channel is valid
+ if (ChannelSanity(pAd, Channel) == TRUE)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->CommonCfg.Channel = Channel;
+
+ if (MONITOR_ON(pAd))
+ {
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ N_SetCenCh(pAd);
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_40, control_channel(%d), CentralChannel(%d) \n",
+ pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAd->CommonCfg.Channel));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ success = TRUE;
+ }
+ else
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ success = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ if (success == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Channel_Proc::(Channel=%d)\n", pAd->CommonCfg.Channel));
+
+ return success;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Short Slot Time Enable or Disable
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ShortSlot_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG ShortSlot;
+
+ ShortSlot = simple_strtol(arg, 0, 10);
+
+ if (ShortSlot == 1)
+ pAd->CommonCfg.bUseShortSlotTime = TRUE;
+ else if (ShortSlot == 0)
+ pAd->CommonCfg.bUseShortSlotTime = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ShortSlot_Proc::(ShortSlot=%d)\n", pAd->CommonCfg.bUseShortSlotTime));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Tx power
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG TxPower;
+ INT success = FALSE;
+
+ TxPower = (ULONG) simple_strtol(arg, 0, 10);
+ if (TxPower <= 100)
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->CommonCfg.TxPowerDefault = TxPower;
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ success = TRUE;
+ }
+ else
+ success = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPower_Proc::(TxPowerPercentage=%ld)\n", pAd->CommonCfg.TxPowerPercentage));
+
+ return success;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set 11B/11G Protection
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ switch (simple_strtol(arg, 0, 10))
+ {
+ case 0: //AUTO
+ pAd->CommonCfg.UseBGProtection = 0;
+ break;
+ case 1: //Always On
+ pAd->CommonCfg.UseBGProtection = 1;
+ break;
+ case 2: //Always OFF
+ pAd->CommonCfg.UseBGProtection = 2;
+ break;
+ default: //Invalid argument
+ return FALSE;
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BGProtection_Proc::(BGProtection=%ld)\n", pAd->CommonCfg.UseBGProtection));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set TxPreamble
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ RT_802_11_PREAMBLE Preamble;
+
+ Preamble = simple_strtol(arg, 0, 10);
+
+
+ switch (Preamble)
+ {
+ case Rt802_11PreambleShort:
+ pAd->CommonCfg.TxPreamble = Preamble;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+ case Rt802_11PreambleLong:
+#ifdef CONFIG_STA_SUPPORT
+ case Rt802_11PreambleAuto:
+ // if user wants AUTO, initialize to LONG here, then change according to AP's
+ // capability upon association.
+#endif // CONFIG_STA_SUPPORT //
+ pAd->CommonCfg.TxPreamble = Preamble;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
+#endif // CONFIG_STA_SUPPORT //
+ break;
+ default: //Invalid argument
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxPreamble_Proc::(TxPreamble=%ld)\n", pAd->CommonCfg.TxPreamble));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set RTS Threshold
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ NDIS_802_11_RTS_THRESHOLD RtsThresh;
+
+ RtsThresh = simple_strtol(arg, 0, 10);
+
+ if((RtsThresh > 0) && (RtsThresh <= MAX_RTS_THRESHOLD))
+ pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
+#ifdef CONFIG_STA_SUPPORT
+ else if (RtsThresh == 0)
+ pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
+#endif // CONFIG_STA_SUPPORT //
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_RTSThreshold_Proc::(RTSThreshold=%d)\n", pAd->CommonCfg.RtsThreshold));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Fragment Threshold
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+
+ FragThresh = simple_strtol(arg, 0, 10);
+
+ if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+ {
+ //Illegal FragThresh so we set it to default
+ pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+ }
+ else if (FragThresh % 2 == 1)
+ {
+ // The length of each fragment shall always be an even number of octets, except for the last fragment
+ // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
+ pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
+ }
+ else
+ {
+ pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->CommonCfg.FragmentThreshold == MAX_FRAG_THRESHOLD)
+ pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+ else
+ pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_FragThreshold_Proc::(FragThreshold=%d)\n", pAd->CommonCfg.FragmentThreshold));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set TxBurst
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG TxBurst;
+
+ TxBurst = simple_strtol(arg, 0, 10);
+ if (TxBurst == 1)
+ pAd->CommonCfg.bEnableTxBurst = TRUE;
+ else if (TxBurst == 0)
+ pAd->CommonCfg.bEnableTxBurst = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_TxBurst_Proc::(TxBurst=%d)\n", pAd->CommonCfg.bEnableTxBurst));
+
+ return TRUE;
+}
+
+#ifdef AGGREGATION_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set TxBurst
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG aggre;
+
+ aggre = simple_strtol(arg, 0, 10);
+
+ if (aggre == 1)
+ pAd->CommonCfg.bAggregationCapable = TRUE;
+ else if (aggre == 0)
+ pAd->CommonCfg.bAggregationCapable = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_PktAggregate_Proc::(AGGRE=%d)\n", pAd->CommonCfg.bAggregationCapable));
+
+ return TRUE;
+}
+#endif
+
+/*
+ ==========================================================================
+ Description:
+ Set IEEE80211H.
+ This parameter is 1 when needs radar detection, otherwise 0
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG ieee80211h;
+
+ ieee80211h = simple_strtol(arg, 0, 10);
+
+ if (ieee80211h == 1)
+ pAd->CommonCfg.bIEEE80211H = TRUE;
+ else if (ieee80211h == 0)
+ pAd->CommonCfg.bIEEE80211H = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_IEEE80211H_Proc::(IEEE80211H=%d)\n", pAd->CommonCfg.bIEEE80211H));
+
+ return TRUE;
+}
+
+
+#ifdef DBG
+/*
+ ==========================================================================
+ Description:
+ For Debug information
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Debug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("==> Set_Debug_Proc *******************\n"));
+
+ if(simple_strtol(arg, 0, 10) <= RT_DEBUG_LOUD)
+ RTDebugLevel = simple_strtol(arg, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== Set_Debug_Proc(RTDebugLevel = %ld)\n", RTDebugLevel));
+
+ return TRUE;
+}
+#endif
+
+INT Show_DescInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Reset statistics counter
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ arg
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ResetStatCounter_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ //UCHAR i;
+ //MAC_TABLE_ENTRY *pEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==>Set_ResetStatCounter_Proc\n"));
+
+ // add the most up-to-date h/w raw counters into software counters
+ NICUpdateRawCounters(pAd);
+
+ NdisZeroMemory(&pAd->WlanCounters, sizeof(COUNTER_802_11));
+ NdisZeroMemory(&pAd->Counters8023, sizeof(COUNTER_802_3));
+ NdisZeroMemory(&pAd->RalinkCounters, sizeof(COUNTER_RALINK));
+
+ return TRUE;
+}
+
+BOOLEAN RTMPCheckStrPrintAble(
+ IN CHAR *pInPutStr,
+ IN UCHAR strLen)
+{
+ UCHAR i=0;
+
+ for (i=0; i<strLen; i++)
+ {
+ if ((pInPutStr[i] < 0x21) ||
+ (pInPutStr[i] > 0x7E))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Remove WPA Key process
+
+ Arguments:
+ pAd Pointer to our adapter
+ pBuf Pointer to the where the key stored
+
+ Return Value:
+ NDIS_SUCCESS Add key successfully
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPSetDesiredRates(
+ IN PRTMP_ADAPTER pAdapter,
+ IN LONG Rates)
+{
+ NDIS_802_11_RATES aryRates;
+
+ memset(&aryRates, 0x00, sizeof(NDIS_802_11_RATES));
+ switch (pAdapter->CommonCfg.PhyMode)
+ {
+ case PHY_11A: // A only
+ switch (Rates)
+ {
+ case 6000000: //6M
+ aryRates[0] = 0x0c; // 6M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+ break;
+ case 9000000: //9M
+ aryRates[0] = 0x12; // 9M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+ break;
+ case 12000000: //12M
+ aryRates[0] = 0x18; // 12M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+ break;
+ case 18000000: //18M
+ aryRates[0] = 0x24; // 18M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+ break;
+ case 24000000: //24M
+ aryRates[0] = 0x30; // 24M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
+ break;
+ case 36000000: //36M
+ aryRates[0] = 0x48; // 36M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
+ break;
+ case 48000000: //48M
+ aryRates[0] = 0x60; // 48M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
+ break;
+ case 54000000: //54M
+ aryRates[0] = 0x6c; // 54M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
+ break;
+ case -1: //Auto
+ default:
+ aryRates[0] = 0x6c; // 54Mbps
+ aryRates[1] = 0x60; // 48Mbps
+ aryRates[2] = 0x48; // 36Mbps
+ aryRates[3] = 0x30; // 24Mbps
+ aryRates[4] = 0x24; // 18M
+ aryRates[5] = 0x18; // 12M
+ aryRates[6] = 0x12; // 9M
+ aryRates[7] = 0x0c; // 6M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ break;
+ }
+ break;
+ case PHY_11BG_MIXED: // B/G Mixed
+ case PHY_11B: // B only
+ case PHY_11ABG_MIXED: // A/B/G Mixed
+ default:
+ switch (Rates)
+ {
+ case 1000000: //1M
+ aryRates[0] = 0x02;
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+ break;
+ case 2000000: //2M
+ aryRates[0] = 0x04;
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+ break;
+ case 5000000: //5.5M
+ aryRates[0] = 0x0b; // 5.5M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+ break;
+ case 11000000: //11M
+ aryRates[0] = 0x16; // 11M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+ break;
+ case 6000000: //6M
+ aryRates[0] = 0x0c; // 6M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_0;
+ break;
+ case 9000000: //9M
+ aryRates[0] = 0x12; // 9M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_1;
+ break;
+ case 12000000: //12M
+ aryRates[0] = 0x18; // 12M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_2;
+ break;
+ case 18000000: //18M
+ aryRates[0] = 0x24; // 18M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_3;
+ break;
+ case 24000000: //24M
+ aryRates[0] = 0x30; // 24M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_4;
+ break;
+ case 36000000: //36M
+ aryRates[0] = 0x48; // 36M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_5;
+ break;
+ case 48000000: //48M
+ aryRates[0] = 0x60; // 48M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_6;
+ break;
+ case 54000000: //54M
+ aryRates[0] = 0x6c; // 54M
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_7;
+ break;
+ case -1: //Auto
+ default:
+ if (pAdapter->CommonCfg.PhyMode == PHY_11B)
+ { //B Only
+ aryRates[0] = 0x16; // 11Mbps
+ aryRates[1] = 0x0b; // 5.5Mbps
+ aryRates[2] = 0x04; // 2Mbps
+ aryRates[3] = 0x02; // 1Mbps
+ }
+ else
+ { //(B/G) Mixed or (A/B/G) Mixed
+ aryRates[0] = 0x6c; // 54Mbps
+ aryRates[1] = 0x60; // 48Mbps
+ aryRates[2] = 0x48; // 36Mbps
+ aryRates[3] = 0x30; // 24Mbps
+ aryRates[4] = 0x16; // 11Mbps
+ aryRates[5] = 0x0b; // 5.5Mbps
+ aryRates[6] = 0x04; // 2Mbps
+ aryRates[7] = 0x02; // 1Mbps
+ }
+ pAdapter->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ break;
+ }
+ break;
+ }
+
+ NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
+ DBGPRINT(RT_DEBUG_TRACE, (" RTMPSetDesiredRates (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
+ pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
+ pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
+ pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
+ pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
+ // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
+ MlmeUpdateTxRates(pAdapter, FALSE, 0);
+}
+
+NDIS_STATUS RTMPWPARemoveKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf)
+{
+ PNDIS_802_11_REMOVE_KEY pKey;
+ ULONG KeyIdx;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+ BOOLEAN bTxKey; // Set the key as transmit key
+ BOOLEAN bPairwise; // Indicate the key is pairwise key
+ BOOLEAN bKeyRSC; // indicate the receive SC set by KeyRSC value.
+ // Otherwise, it will set by the NIC.
+ BOOLEAN bAuthenticator; // indicate key is set by authenticator.
+ INT i;
+
+ DBGPRINT(RT_DEBUG_TRACE,("---> RTMPWPARemoveKeyProc\n"));
+
+ pKey = (PNDIS_802_11_REMOVE_KEY) pBuf;
+ KeyIdx = pKey->KeyIndex & 0xff;
+ // Bit 31 of Add-key, Tx Key
+ bTxKey = (pKey->KeyIndex & 0x80000000) ? TRUE : FALSE;
+ // Bit 30 of Add-key PairwiseKey
+ bPairwise = (pKey->KeyIndex & 0x40000000) ? TRUE : FALSE;
+ // Bit 29 of Add-key KeyRSC
+ bKeyRSC = (pKey->KeyIndex & 0x20000000) ? TRUE : FALSE;
+ // Bit 28 of Add-key Authenticator
+ bAuthenticator = (pKey->KeyIndex & 0x10000000) ? TRUE : FALSE;
+
+ // 1. If bTx is TRUE, return failure information
+ if (bTxKey == TRUE)
+ return(NDIS_STATUS_INVALID_DATA);
+
+ // 2. Check Pairwise Key
+ if (bPairwise)
+ {
+ // a. If BSSID is broadcast, remove all pairwise keys.
+ // b. If not broadcast, remove the pairwise specified by BSSID
+ for (i = 0; i < SHARE_KEY_NUM; i++)
+ {
+ if (MAC_ADDR_EQUAL(pAd->SharedKey[BSS0][i].BssId, pKey->BSSID))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%d)\n", i));
+ pAd->SharedKey[BSS0][i].KeyLen = 0;
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)i);
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+ }
+ }
+ // 3. Group Key
+ else
+ {
+ // a. If BSSID is broadcast, remove all group keys indexed
+ // b. If BSSID matched, delete the group key indexed.
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveKeyProc(KeyIdx=%ld)\n", KeyIdx));
+ pAd->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx);
+ Status = NDIS_STATUS_SUCCESS;
+ }
+
+ return (Status);
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ========================================================================
+
+ Routine Description:
+ Remove All WPA Keys
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPWPARemoveAllKeys(
+ IN PRTMP_ADAPTER pAd)
+{
+
+ UCHAR i;
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPWPARemoveAllKeys(AuthMode=%d, WepStatus=%d)\n", pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus));
+
+ // For WEP/CKIP, there is no need to remove it, since WinXP won't set it again after
+ // Link up. And it will be replaced if user changed it.
+ if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ return;
+
+ // For WPA-None, there is no need to remove it, since WinXP won't set it again after
+ // Link up. And it will be replaced if user changed it.
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ return;
+
+ // set BSSID wcid entry of the Pair-wise Key table as no-security mode
+ AsicRemovePairwiseKeyEntry(pAd, BSS0, BSSID_WCID);
+
+ // set all shared key mode as no-security.
+ for (i = 0; i < SHARE_KEY_NUM; i++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("remove %s key #%d\n", CipherName[pAd->SharedKey[BSS0][i].CipherAlg], i));
+ NdisZeroMemory(&pAd->SharedKey[BSS0][i], sizeof(CIPHER_KEY));
+
+ AsicRemoveSharedKeyEntry(pAd, BSS0, i);
+ }
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ========================================================================
+ Routine Description:
+ Change NIC PHY mode. Re-association may be necessary. possible settings
+ include - PHY_11B, PHY_11BG_MIXED, PHY_11A, and PHY_11ABG_MIXED
+
+ Arguments:
+ pAd - Pointer to our adapter
+ phymode -
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPSetPhyMode(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG phymode)
+{
+ INT i;
+ // the selected phymode must be supported by the RF IC encoded in E2PROM
+
+ pAd->CommonCfg.PhyMode = (UCHAR)phymode;
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPSetPhyMode : PhyMode=%d, channel=%d \n", pAd->CommonCfg.PhyMode, pAd->CommonCfg.Channel));
+#ifdef EXT_BUILD_CHANNEL_LIST
+ BuildChannelListEx(pAd);
+#else
+ BuildChannelList(pAd);
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // sanity check user setting
+ for (i = 0; i < pAd->ChannelListNum; i++)
+ {
+ if (pAd->CommonCfg.Channel == pAd->ChannelList[i].Channel)
+ break;
+ }
+
+ if (i == pAd->ChannelListNum)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->CommonCfg.Channel = FirstChannel(pAd);
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetPhyMode: channel is out of range, use first channel=%d \n", pAd->CommonCfg.Channel));
+ }
+
+ NdisZeroMemory(pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisZeroMemory(pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisZeroMemory(pAd->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+ switch (phymode) {
+ case PHY_11B:
+ pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRateLen = 4;
+ pAd->CommonCfg.ExtRateLen = 0;
+ pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
+ //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_CCK; // This MODE is only FYI. not use
+ break;
+
+ case PHY_11G:
+ case PHY_11BG_MIXED:
+ case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11N_2_4G:
+ case PHY_11ABGN_MIXED:
+ case PHY_11BGN_MIXED:
+ case PHY_11GN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.SupRate[0] = 0x82; // 1 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[1] = 0x84; // 2 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[2] = 0x8B; // 5.5 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[3] = 0x96; // 11 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[4] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[5] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[6] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRateLen = 8;
+ pAd->CommonCfg.ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRate[1] = 0x18; // 12 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRate[2] = 0x30; // 24 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRate[3] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.ExtRateLen = 4;
+ pAd->CommonCfg.DesireRate[0] = 2; // 1 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[1] = 4; // 2 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[2] = 11; // 5.5 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[3] = 22; // 11 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[4] = 12; // 6 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[5] = 18; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[6] = 24; // 12 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[7] = 36; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[8] = 48; // 24 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[9] = 72; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[10] = 96; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[11] = 108; // 54 mbps, in units of 0.5 Mbps
+ break;
+
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AN_MIXED:
+ case PHY_11AGN_MIXED:
+ case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
+ pAd->CommonCfg.SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.SupRateLen = 8;
+ pAd->CommonCfg.ExtRateLen = 0;
+ pAd->CommonCfg.DesireRate[0] = 12; // 6 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[1] = 18; // 9 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[2] = 24; // 12 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[3] = 36; // 18 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[4] = 48; // 24 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[5] = 72; // 36 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[6] = 96; // 48 mbps, in units of 0.5 Mbps
+ pAd->CommonCfg.DesireRate[7] = 108; // 54 mbps, in units of 0.5 Mbps
+ //pAd->CommonCfg.HTPhyMode.field.MODE = MODE_OFDM; // This MODE is only FYI. not use
+ break;
+
+ default:
+ break;
+ }
+
+
+ pAd->CommonCfg.BandState = UNKNOWN_BAND;
+}
+
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ Caller ensures we has 802.11n support.
+ Calls at setting HT from AP/STASetinformation
+
+ Arguments:
+ pAd - Pointer to our adapter
+ phymode -
+
+ ========================================================================
+*/
+VOID RTMPSetHT(
+ IN PRTMP_ADAPTER pAd,
+ IN OID_SET_HT_PHYMODE *pHTPhyMode)
+{
+ //ULONG *pmcs;
+ UINT32 Value = 0;
+ UCHAR BBPValue = 0;
+ UCHAR BBP3Value = 0;
+ UCHAR RxStream = pAd->CommonCfg.RxStream;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : HT_mode(%d), ExtOffset(%d), MCS(%d), BW(%d), STBC(%d), SHORTGI(%d)\n",
+ pHTPhyMode->HtMode, pHTPhyMode->ExtOffset,
+ pHTPhyMode->MCS, pHTPhyMode->BW,
+ pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
+
+ // Don't zero supportedHyPhy structure.
+ RTMPZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
+ RTMPZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+ RTMPZeroMemory(&pAd->CommonCfg.NewExtChanOffset, sizeof(pAd->CommonCfg.NewExtChanOffset));
+ RTMPZeroMemory(&pAd->CommonCfg.DesiredHtPhy, sizeof(pAd->CommonCfg.DesiredHtPhy));
+
+ if (pAd->CommonCfg.bRdg)
+ {
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 1;
+ }
+ else
+ {
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.PlusHTC = 0;
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.RDGSupport = 0;
+ }
+
+ pAd->CommonCfg.HtCapability.HtCapParm.MaxRAmpduFactor = 3;
+ pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor = 3;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : RxBAWinLimit = %d\n", pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+
+ // Mimo power save, A-MSDU size,
+ pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
+ pAd->CommonCfg.DesiredHtPhy.AmsduSize = (UCHAR)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.DesiredHtPhy.MimoPs = (UCHAR)pAd->CommonCfg.BACapability.field.MMPSmode;
+ pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+ pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+ pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetHT : AMsduSize = %d, MimoPs = %d, MpduDensity = %d, MaxRAmpduFactor = %d\n",
+ pAd->CommonCfg.DesiredHtPhy.AmsduSize,
+ pAd->CommonCfg.DesiredHtPhy.MimoPs,
+ pAd->CommonCfg.DesiredHtPhy.MpduDensity,
+ pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor));
+
+ if(pHTPhyMode->HtMode == HTMODE_GF)
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.GF = 1;
+ pAd->CommonCfg.DesiredHtPhy.GF = 1;
+ }
+ else
+ pAd->CommonCfg.DesiredHtPhy.GF = 0;
+
+ // Decide Rx MCSSet
+ switch (RxStream)
+ {
+ case 1:
+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0x00;
+ break;
+
+ case 2:
+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
+ break;
+
+ case 3: // 3*3
+ pAd->CommonCfg.HtCapability.MCSSet[0] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[1] = 0xff;
+ pAd->CommonCfg.HtCapability.MCSSet[2] = 0xff;
+ break;
+ }
+
+ if (pAd->CommonCfg.bForty_Mhz_Intolerant && (pAd->CommonCfg.Channel <= 14) && (pHTPhyMode->BW == BW_40) )
+ {
+ pHTPhyMode->BW = BW_20;
+ pAd->CommonCfg.HtCapability.HtCapInfo.Forty_Mhz_Intolerant = 1;
+ }
+
+ if(pHTPhyMode->BW == BW_40)
+ {
+ pAd->CommonCfg.HtCapability.MCSSet[4] = 0x1; // MCS 32
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 1;
+ if (pAd->CommonCfg.Channel <= 14)
+ pAd->CommonCfg.HtCapability.HtCapInfo.CCKmodein40 = 1;
+
+ pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 1;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 1;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = (pHTPhyMode->ExtOffset == EXTCHA_BELOW)? (EXTCHA_BELOW): EXTCHA_ABOVE;
+ // Set Regsiter for extension channel position.
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBP3Value);
+ if ((pHTPhyMode->ExtOffset == EXTCHA_BELOW))
+ {
+ Value |= 0x1;
+ BBP3Value |= (0x20);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+ }
+ else if ((pHTPhyMode->ExtOffset == EXTCHA_ABOVE))
+ {
+ Value &= 0xfe;
+ BBP3Value &= (~0x20);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+ }
+
+ // Turn on BBP 40MHz mode now only as AP .
+ // Sta can turn on BBP 40MHz after connection with 40MHz AP. Sta only broadcast 40MHz capability before connection.
+ if ((pAd->OpMode == OPMODE_AP) || INFRA_ON(pAd) || ADHOC_ON(pAd)
+ )
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ BBPValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBP3Value);
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth = 0;
+ pAd->CommonCfg.DesiredHtPhy.ChannelWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.RecomWidth = 0;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset = EXTCHA_NONE;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ // Turn on BBP 20MHz mode by request here.
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ }
+ }
+
+ if(pHTPhyMode->STBC == STBC_USE)
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.TxSTBC = 1;
+ pAd->CommonCfg.DesiredHtPhy.TxSTBC = 1;
+ pAd->CommonCfg.HtCapability.HtCapInfo.RxSTBC = 1;
+ pAd->CommonCfg.DesiredHtPhy.RxSTBC = 1;
+ }
+ else
+ {
+ pAd->CommonCfg.DesiredHtPhy.TxSTBC = 0;
+ pAd->CommonCfg.DesiredHtPhy.RxSTBC = 0;
+ }
+
+ if(pHTPhyMode->SHORTGI == GI_400)
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 1;
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 1;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 1;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 1;
+ }
+ else
+ {
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor20 = 0;
+ pAd->CommonCfg.HtCapability.HtCapInfo.ShortGIfor40 = 0;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 = 0;
+ pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 = 0;
+ }
+
+ // We support link adaptation for unsolicit MCS feedback, set to 2.
+ pAd->CommonCfg.HtCapability.ExtHtCapInfo.MCSFeedback = MCSFBK_NONE; //MCSFBK_UNSOLICIT;
+ pAd->CommonCfg.AddHTInfo.ControlChan = pAd->CommonCfg.Channel;
+ // 1, the extension channel above the control channel.
+
+ // EDCA parameters used for AP's own transmission
+ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
+ {
+ pAd->CommonCfg.APEdcaParm.bValid = TRUE;
+ pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
+ pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
+ pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
+ pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
+
+ pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
+ pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
+
+ pAd->CommonCfg.APEdcaParm.Cwmax[0] = 6;
+ pAd->CommonCfg.APEdcaParm.Cwmax[1] = 10;
+ pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
+
+ pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[2] = 94;
+ pAd->CommonCfg.APEdcaParm.Txop[3] = 47;
+ }
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ RTMPSetIndividualHT(pAd, 0);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Caller ensures we has 802.11n support.
+ Calls at setting HT from AP/STASetinformation
+
+ Arguments:
+ pAd - Pointer to our adapter
+ phymode -
+
+ ========================================================================
+*/
+VOID RTMPSetIndividualHT(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx)
+{
+ PRT_HT_PHY_INFO pDesired_ht_phy = NULL;
+ UCHAR TxStream = pAd->CommonCfg.TxStream;
+ UCHAR DesiredMcs = MCS_AUTO;
+
+ do
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pDesired_ht_phy = &pAd->StaCfg.DesiredHtPhyInfo;
+ DesiredMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+ //pAd->StaCfg.bAutoTxRateSwitch = (DesiredMcs == MCS_AUTO) ? TRUE : FALSE;
+ break;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ } while (FALSE);
+
+ if (pDesired_ht_phy == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSetIndividualHT: invalid apidx(%d)\n", apidx));
+ return;
+ }
+ RTMPZeroMemory(pDesired_ht_phy, sizeof(RT_HT_PHY_INFO));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetIndividualHT : Desired MCS = %d\n", DesiredMcs));
+ // Check the validity of MCS
+ if ((TxStream == 1) && ((DesiredMcs >= MCS_8) && (DesiredMcs <= MCS_15)))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS(%d) is invalid in 1S, reset it as MCS_7\n", DesiredMcs));
+ DesiredMcs = MCS_7;
+ }
+
+ if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_20) && (DesiredMcs == MCS_32))
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetIndividualHT: MCS_32 is only supported in 40-MHz, reset it as MCS_0\n"));
+ DesiredMcs = MCS_0;
+ }
+
+ pDesired_ht_phy->bHtEnable = TRUE;
+
+ // Decide desired Tx MCS
+ switch (TxStream)
+ {
+ case 1:
+ if (DesiredMcs == MCS_AUTO)
+ {
+ pDesired_ht_phy->MCSSet[0]= 0xff;
+ pDesired_ht_phy->MCSSet[1]= 0x00;
+ }
+ else if (DesiredMcs <= MCS_7)
+ {
+ pDesired_ht_phy->MCSSet[0]= 1<<DesiredMcs;
+ pDesired_ht_phy->MCSSet[1]= 0x00;
+ }
+ break;
+
+ case 2:
+ if (DesiredMcs == MCS_AUTO)
+ {
+ pDesired_ht_phy->MCSSet[0]= 0xff;
+ pDesired_ht_phy->MCSSet[1]= 0xff;
+ }
+ else if (DesiredMcs <= MCS_15)
+ {
+ ULONG mode;
+
+ mode = DesiredMcs / 8;
+ if (mode < 2)
+ pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
+ }
+ break;
+
+ case 3: // 3*3
+ if (DesiredMcs == MCS_AUTO)
+ {
+ /* MCS0 ~ MCS23, 3 bytes */
+ pDesired_ht_phy->MCSSet[0]= 0xff;
+ pDesired_ht_phy->MCSSet[1]= 0xff;
+ pDesired_ht_phy->MCSSet[2]= 0xff;
+ }
+ else if (DesiredMcs <= MCS_23)
+ {
+ ULONG mode;
+
+ mode = DesiredMcs / 8;
+ if (mode < 3)
+ pDesired_ht_phy->MCSSet[mode] = (1 << (DesiredMcs - mode * 8));
+ }
+ break;
+ }
+
+ if(pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BW_40)
+ {
+ if (DesiredMcs == MCS_AUTO || DesiredMcs == MCS_32)
+ pDesired_ht_phy->MCSSet[4] = 0x1;
+ }
+
+ // update HT Rate setting
+ if (pAd->OpMode == OPMODE_STA)
+ MlmeUpdateHtTxRates(pAd, BSS0);
+ else
+ MlmeUpdateHtTxRates(pAd, apidx);
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Update HT IE from our capability.
+
+ Arguments:
+ Send all HT IE in beacon/probe rsp/assoc rsp/action frame.
+
+
+ ========================================================================
+*/
+VOID RTMPUpdateHTIE(
+ IN RT_HT_CAPABILITY *pRtHt,
+ IN UCHAR *pMcsSet,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo)
+{
+ RTMPZeroMemory(pHtCapability, sizeof(HT_CAPABILITY_IE));
+ RTMPZeroMemory(pAddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+ pHtCapability->HtCapInfo.ChannelWidth = pRtHt->ChannelWidth;
+ pHtCapability->HtCapInfo.MimoPs = pRtHt->MimoPs;
+ pHtCapability->HtCapInfo.GF = pRtHt->GF;
+ pHtCapability->HtCapInfo.ShortGIfor20 = pRtHt->ShortGIfor20;
+ pHtCapability->HtCapInfo.ShortGIfor40 = pRtHt->ShortGIfor40;
+ pHtCapability->HtCapInfo.TxSTBC = pRtHt->TxSTBC;
+ pHtCapability->HtCapInfo.RxSTBC = pRtHt->RxSTBC;
+ pHtCapability->HtCapInfo.AMsduSize = pRtHt->AmsduSize;
+ pHtCapability->HtCapParm.MaxRAmpduFactor = pRtHt->MaxRAmpduFactor;
+ pHtCapability->HtCapParm.MpduDensity = pRtHt->MpduDensity;
+
+ pAddHtInfo->AddHtInfo.ExtChanOffset = pRtHt->ExtChanOffset ;
+ pAddHtInfo->AddHtInfo.RecomWidth = pRtHt->RecomWidth;
+ pAddHtInfo->AddHtInfo2.OperaionMode = pRtHt->OperaionMode;
+ pAddHtInfo->AddHtInfo2.NonGfPresent = pRtHt->NonGfPresent;
+ RTMPMoveMemory(pAddHtInfo->MCSSet, /*pRtHt->MCSSet*/pMcsSet, 4); // rt2860 only support MCS max=32, no need to copy all 16 uchar.
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPUpdateHTIE <== \n"));
+}
+#endif // DOT11_N_SUPPORT //
+
+/*
+ ========================================================================
+ Description:
+ Add Client security information into ASIC WCID table and IVEIV table.
+ Return:
+ ========================================================================
+*/
+VOID RTMPAddWcidAttributeEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ UINT32 WCIDAttri = 0;
+ USHORT offset;
+ UCHAR IVEIV = 0;
+ USHORT Wcid = 0;
+
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (BssIdx > BSS0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPAddWcidAttributeEntry: The BSS-index(%d) is out of range for Infra link. \n", BssIdx));
+ return;
+ }
+
+ // 1. In ADHOC mode, the AID is wcid number. And NO mesh link exists.
+ // 2. In Infra mode, the AID:1 MUST be wcid of infra STA.
+ // the AID:2~ assign to mesh link entry.
+ if (pEntry && ADHOC_ON(pAd))
+ Wcid = pEntry->Aid;
+ else if (pEntry && INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ if (pEntry->ValidAsDls == TRUE)
+ Wcid = pEntry->Aid;
+ else
+#endif // QOS_DLS_SUPPORT //
+ Wcid = BSSID_WCID;
+ }
+ else
+ Wcid = MCAST_WCID;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // Update WCID attribute table
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pEntry && pEntry->ValidAsMesh)
+ WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
+#ifdef QOS_DLS_SUPPORT
+ else if ((pEntry) && (pEntry->ValidAsDls) &&
+ ((CipherAlg == CIPHER_TKIP) ||
+ (CipherAlg == CIPHER_TKIP_NO_MIC) ||
+ (CipherAlg == CIPHER_AES) ||
+ (CipherAlg == CIPHER_NONE)))
+ WCIDAttri = (CipherAlg<<1) | PAIRWISEKEYTABLE;
+#endif // QOS_DLS_SUPPORT //
+ else
+ WCIDAttri = (CipherAlg<<1) | SHAREDKEYTABLE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+
+
+ // Update IV/EIV table
+ offset = MAC_IVEIV_TABLE_BASE + (Wcid * HW_IVEIV_ENTRY_SIZE);
+
+ // WPA mode
+ if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) || (CipherAlg == CIPHER_AES))
+ {
+ // Eiv bit on. keyid always is 0 for pairwise key
+ IVEIV = (KeyIdx <<6) | 0x20;
+ }
+ else
+ {
+ // WEP KeyIdx is default tx key.
+ IVEIV = (KeyIdx << 6);
+ }
+
+ // For key index and ext IV bit, so only need to update the position(offset+3).
+#ifdef RT2870
+ RTUSBMultiWrite_OneByte(pAd, offset+3, &IVEIV);
+#endif // RT2870 //
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPAddWcidAttributeEntry: WCID #%d, KeyIndex #%d, Alg=%s\n",Wcid, KeyIdx, CipherName[CipherAlg]));
+ DBGPRINT(RT_DEBUG_TRACE,(" WCIDAttri = 0x%x \n", WCIDAttri));
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Parse encryption type
+Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ ==========================================================================
+*/
+CHAR *GetEncryptType(CHAR enc)
+{
+ if(enc == Ndis802_11WEPDisabled)
+ return "NONE";
+ if(enc == Ndis802_11WEPEnabled)
+ return "WEP";
+ if(enc == Ndis802_11Encryption2Enabled)
+ return "TKIP";
+ if(enc == Ndis802_11Encryption3Enabled)
+ return "AES";
+ if(enc == Ndis802_11Encryption4Enabled)
+ return "TKIPAES";
+ else
+ return "UNKNOW";
+}
+
+CHAR *GetAuthMode(CHAR auth)
+{
+ if(auth == Ndis802_11AuthModeOpen)
+ return "OPEN";
+ if(auth == Ndis802_11AuthModeShared)
+ return "SHARED";
+ if(auth == Ndis802_11AuthModeAutoSwitch)
+ return "AUTOWEP";
+ if(auth == Ndis802_11AuthModeWPA)
+ return "WPA";
+ if(auth == Ndis802_11AuthModeWPAPSK)
+ return "WPAPSK";
+ if(auth == Ndis802_11AuthModeWPANone)
+ return "WPANONE";
+ if(auth == Ndis802_11AuthModeWPA2)
+ return "WPA2";
+ if(auth == Ndis802_11AuthModeWPA2PSK)
+ return "WPA2PSK";
+ if(auth == Ndis802_11AuthModeWPA1WPA2)
+ return "WPA1WPA2";
+ if(auth == Ndis802_11AuthModeWPA1PSKWPA2PSK)
+ return "WPA1PSKWPA2PSK";
+
+ return "UNKNOW";
+}
+
+#if 1 //#ifndef UCOS
+/*
+ ==========================================================================
+ Description:
+ Get site survey results
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) UI needs to wait 4 seconds after issue a site survey command
+ 2.) iwpriv ra0 get_site_survey
+ 3.) UI needs to prepare at least 4096bytes to get the results
+ ==========================================================================
+*/
+#define LINE_LEN (4+33+20+8+10+9+7+3) // Channel+SSID+Bssid+WepStatus+AuthMode+Signal+WiressMode+NetworkType
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+VOID RTMPIoctlGetSiteSurvey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *msg;
+ INT i=0;
+ INT WaitCnt;
+ INT Status=0;
+ CHAR Ssid[MAX_LEN_OF_SSID +1];
+ INT Rssi = 0, max_len = LINE_LEN;
+ UINT Rssi_Quality = 0;
+ NDIS_802_11_NETWORK_TYPE wireless_mode;
+
+ os_alloc_mem(NULL, (PUCHAR *)&msg, sizeof(CHAR)*((MAX_LEN_OF_BSS_TABLE)*max_len));
+
+ if (msg == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - msg memory alloc fail.\n"));
+ return;
+ }
+
+ memset(msg, 0 ,(MAX_LEN_OF_BSS_TABLE)*max_len );
+ memset(Ssid, 0 ,(MAX_LEN_OF_SSID +1));
+ sprintf(msg,"%s","\n");
+ sprintf(msg+strlen(msg),"%-4s%-33s%-20s%-8s%-10s%-9s%-7s%-3s\n",
+ "Ch", "SSID", "BSSID", "Enc", "Auth", "Siganl(%)", "W-Mode", " NT");
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ WaitCnt = 0;
+#ifdef CONFIG_STA_SUPPORT
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ while ((ScanRunning(pAdapter) == TRUE) && (WaitCnt++ < 200))
+ OS_WAIT(500);
+#endif // CONFIG_STA_SUPPORT //
+
+ for(i=0; i<pAdapter->ScanTab.BssNr ;i++)
+ {
+ if( pAdapter->ScanTab.BssEntry[i].Channel==0)
+ break;
+
+ if((strlen(msg)+max_len ) >= IW_SCAN_MAX_DATA)
+ break;
+
+ //Channel
+ sprintf(msg+strlen(msg),"%-4d", pAdapter->ScanTab.BssEntry[i].Channel);
+ //SSID
+ memcpy(Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+ Ssid[pAdapter->ScanTab.BssEntry[i].SsidLen] = '\0';
+ sprintf(msg+strlen(msg),"%-33s", Ssid);
+ //BSSID
+ sprintf(msg+strlen(msg),"%02x:%02x:%02x:%02x:%02x:%02x ",
+ pAdapter->ScanTab.BssEntry[i].Bssid[0],
+ pAdapter->ScanTab.BssEntry[i].Bssid[1],
+ pAdapter->ScanTab.BssEntry[i].Bssid[2],
+ pAdapter->ScanTab.BssEntry[i].Bssid[3],
+ pAdapter->ScanTab.BssEntry[i].Bssid[4],
+ pAdapter->ScanTab.BssEntry[i].Bssid[5]);
+ //Encryption Type
+ sprintf(msg+strlen(msg),"%-8s",GetEncryptType(pAdapter->ScanTab.BssEntry[i].WepStatus));
+ //Authentication Mode
+ if (pAdapter->ScanTab.BssEntry[i].WepStatus == Ndis802_11WEPEnabled)
+ sprintf(msg+strlen(msg),"%-10s", "UNKNOW");
+ else
+ sprintf(msg+strlen(msg),"%-10s",GetAuthMode(pAdapter->ScanTab.BssEntry[i].AuthMode));
+ // Rssi
+ Rssi = (INT)pAdapter->ScanTab.BssEntry[i].Rssi;
+ if (Rssi >= -50)
+ Rssi_Quality = 100;
+ else if (Rssi >= -80) // between -50 ~ -80dbm
+ Rssi_Quality = (UINT)(24 + ((Rssi + 80) * 26)/10);
+ else if (Rssi >= -90) // between -80 ~ -90dbm
+ Rssi_Quality = (UINT)(((Rssi + 90) * 26)/10);
+ else // < -84 dbm
+ Rssi_Quality = 0;
+ sprintf(msg+strlen(msg),"%-9d", Rssi_Quality);
+ // Wireless Mode
+ wireless_mode = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
+ if (wireless_mode == Ndis802_11FH ||
+ wireless_mode == Ndis802_11DS)
+ sprintf(msg+strlen(msg),"%-7s", "11b");
+ else if (wireless_mode == Ndis802_11OFDM5)
+ sprintf(msg+strlen(msg),"%-7s", "11a");
+ else if (wireless_mode == Ndis802_11OFDM5_N)
+ sprintf(msg+strlen(msg),"%-7s", "11a/n");
+ else if (wireless_mode == Ndis802_11OFDM24)
+ sprintf(msg+strlen(msg),"%-7s", "11b/g");
+ else if (wireless_mode == Ndis802_11OFDM24_N)
+ sprintf(msg+strlen(msg),"%-7s", "11b/g/n");
+ else
+ sprintf(msg+strlen(msg),"%-7s", "unknow");
+ //Network Type
+ if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_ADHOC)
+ sprintf(msg+strlen(msg),"%-3s", " Ad");
+ else
+ sprintf(msg+strlen(msg),"%-3s", " In");
+
+ sprintf(msg+strlen(msg),"\n");
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPIoctlGetSiteSurvey - wrq->u.data.length = %d\n", wrq->u.data.length));
+ os_free_mem(NULL, (PUCHAR)msg);
+}
+
+
+#define MAC_LINE_LEN (14+4+4+10+10+10+6+6) // Addr+aid+psm+datatime+rxbyte+txbyte+current tx rate+last tx rate
+VOID RTMPIoctlGetMacTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq)
+{
+ INT i;
+ RT_802_11_MAC_TABLE MacTab;
+ char *msg;
+
+ MacTab.Num = 0;
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI && (pAd->MacTab.Content[i].Sst == SST_ASSOC))
+ {
+ COPY_MAC_ADDR(MacTab.Entry[MacTab.Num].Addr, &pAd->MacTab.Content[i].Addr);
+ MacTab.Entry[MacTab.Num].Aid = (UCHAR)pAd->MacTab.Content[i].Aid;
+ MacTab.Entry[MacTab.Num].Psm = pAd->MacTab.Content[i].PsMode;
+#ifdef DOT11_N_SUPPORT
+ MacTab.Entry[MacTab.Num].MimoPs = pAd->MacTab.Content[i].MmpsMode;
+#endif // DOT11_N_SUPPORT //
+
+ // Fill in RSSI per entry
+ MacTab.Entry[MacTab.Num].AvgRssi0 = pAd->MacTab.Content[i].RssiSample.AvgRssi0;
+ MacTab.Entry[MacTab.Num].AvgRssi1 = pAd->MacTab.Content[i].RssiSample.AvgRssi1;
+ MacTab.Entry[MacTab.Num].AvgRssi2 = pAd->MacTab.Content[i].RssiSample.AvgRssi2;
+
+ // the connected time per entry
+ MacTab.Entry[MacTab.Num].ConnectedTime = pAd->MacTab.Content[i].StaConnectTime;
+ MacTab.Entry[MacTab.Num].TxRate.field.MCS = pAd->MacTab.Content[i].HTPhyMode.field.MCS;
+ MacTab.Entry[MacTab.Num].TxRate.field.BW = pAd->MacTab.Content[i].HTPhyMode.field.BW;
+ MacTab.Entry[MacTab.Num].TxRate.field.ShortGI = pAd->MacTab.Content[i].HTPhyMode.field.ShortGI;
+ MacTab.Entry[MacTab.Num].TxRate.field.STBC = pAd->MacTab.Content[i].HTPhyMode.field.STBC;
+ MacTab.Entry[MacTab.Num].TxRate.field.rsv = pAd->MacTab.Content[i].HTPhyMode.field.rsv;
+ MacTab.Entry[MacTab.Num].TxRate.field.MODE = pAd->MacTab.Content[i].HTPhyMode.field.MODE;
+ MacTab.Entry[MacTab.Num].TxRate.word = pAd->MacTab.Content[i].HTPhyMode.word;
+
+ MacTab.Num += 1;
+ }
+ }
+ wrq->u.data.length = sizeof(RT_802_11_MAC_TABLE);
+ if (copy_to_user(wrq->u.data.pointer, &MacTab, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+
+ msg = (CHAR *) kmalloc(sizeof(CHAR)*(MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN), MEM_ALLOC_FLAG);
+ memset(msg, 0 ,MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN );
+ sprintf(msg,"%s","\n");
+ sprintf(msg+strlen(msg),"%-14s%-4s%-4s%-10s%-10s%-10s%-6s%-6s\n",
+ "MAC", "AID", "PSM", "LDT", "RxB", "TxB","CTxR", "LTxR");
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (pEntry->ValidAsCLI && (pEntry->Sst == SST_ASSOC))
+ {
+ if((strlen(msg)+MAC_LINE_LEN ) >= (MAX_LEN_OF_MAC_TABLE*MAC_LINE_LEN) )
+ break;
+ sprintf(msg+strlen(msg),"%02x%02x%02x%02x%02x%02x ",
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+ sprintf(msg+strlen(msg),"%-4d", (int)pEntry->Aid);
+ sprintf(msg+strlen(msg),"%-4d", (int)pEntry->PsMode);
+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.LastDataPacketTime*/); // ToDo
+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalRxByteCount*/); // ToDo
+ sprintf(msg+strlen(msg),"%-10d",0/*pAd->MacTab.Content[i].HSCounter.TotalTxByteCount*/); // ToDo
+ sprintf(msg+strlen(msg),"%-6d",RateIdToMbps[pAd->MacTab.Content[i].CurrTxRate]);
+ sprintf(msg+strlen(msg),"%-6d\n",0/*RateIdToMbps[pAd->MacTab.Content[i].LastTxRate]*/); // ToDo
+ }
+ }
+ // for compatible with old API just do the printk to console
+ //wrq->u.data.length = strlen(msg);
+ //if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s", msg));
+ }
+
+ kfree(msg);
+}
+#endif // UCOS //
+
+#ifdef DOT11_N_SUPPORT
+INT Set_BASetup_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], tid;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+/*
+ The BASetup inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the tid value.
+*/
+ //printk("\n%s\n", arg);
+
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ tid = simple_strtol((token+1), 0, 10);
+ if (tid > 15)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x\n", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], tid);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nSetup BA Session: Tid = %d\n", tid);
+ BAOriSessionSetUp(pAd, pEntry, tid, 0, 100, TRUE);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_BADecline_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG bBADecline;
+
+ bBADecline = simple_strtol(arg, 0, 10);
+
+ if (bBADecline == 0)
+ {
+ pAd->CommonCfg.bBADecline = FALSE;
+ }
+ else if (bBADecline == 1)
+ {
+ pAd->CommonCfg.bBADecline = TRUE;
+ }
+ else
+ {
+ return FALSE; //Invalid argument
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_BADecline_Proc::(BADecline=%d)\n", pAd->CommonCfg.bBADecline));
+
+ return TRUE;
+}
+
+INT Set_BAOriTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], tid;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+ //printk("\n%s\n", arg);
+/*
+ The BAOriTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the tid value.
+*/
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ tid = simple_strtol((token+1), 0, 10);
+ if (tid > NUM_OF_TID)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], tid);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nTear down Ori BA Session: Tid = %d\n", tid);
+ BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, TRUE);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_BARecTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], tid;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+ //printk("\n%s\n", arg);
+/*
+ The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the tid value.
+*/
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and tid value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ tid = simple_strtol((token+1), 0, 10);
+ if (tid > NUM_OF_TID)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], tid);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nTear down Rec BA Session: Tid = %d\n", tid);
+ BARecSessionTearDown(pAd, pEntry->Aid, tid, FALSE);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG HtBw;
+
+ HtBw = simple_strtol(arg, 0, 10);
+ if (HtBw == BW_40)
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ else if (HtBw == BW_20)
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBw_Proc::(HtBw=%d)\n", pAd->CommonCfg.RegTransmitSetting.field.BW));
+
+ return TRUE;
+}
+
+INT Set_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG HtMcs, Mcs_tmp;
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN bAutoRate = FALSE;
+#endif // CONFIG_STA_SUPPORT //
+
+ Mcs_tmp = simple_strtol(arg, 0, 10);
+
+ if (Mcs_tmp <= 15 || Mcs_tmp == 32)
+ HtMcs = Mcs_tmp;
+ else
+ HtMcs = MCS_AUTO;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = HtMcs;
+ pAd->StaCfg.bAutoTxRateSwitch = (HtMcs == MCS_AUTO) ? TRUE:FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(HtMcs=%d, bAutoTxRateSwitch = %d)\n",
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS, pAd->StaCfg.bAutoTxRateSwitch));
+
+ if ((pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED) ||
+ (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE < MODE_HTMIX))
+ {
+ if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
+ (HtMcs >= 0 && HtMcs <= 3) &&
+ (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_CCK))
+ {
+ RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs] * 1000000));
+ }
+ else if ((pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO) &&
+ (HtMcs >= 0 && HtMcs <= 7) &&
+ (pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode == FIXED_TXMODE_OFDM))
+ {
+ RTMPSetDesiredRates(pAd, (LONG) (RateIdToMbps[HtMcs+4] * 1000000));
+ }
+ else
+ bAutoRate = TRUE;
+
+ if (bAutoRate)
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ RTMPSetDesiredRates(pAd, -1);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMcs_Proc::(FixedTxMode=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode));
+ }
+ if (ADHOC_ON(pAd))
+ return TRUE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ SetCommonHT(pAd);
+
+ return TRUE;
+}
+
+INT Set_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG HtGi;
+
+ HtGi = simple_strtol(arg, 0, 10);
+
+ if ( HtGi == GI_400)
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
+ else if ( HtGi == GI_800 )
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtGi_Proc::(ShortGI=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.ShortGI));
+
+ return TRUE;
+}
+
+
+INT Set_HtTxBASize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR Size;
+
+ Size = simple_strtol(arg, 0, 10);
+
+ if (Size <=0 || Size >=64)
+ {
+ Size = 8;
+ }
+ pAd->CommonCfg.TxBASize = Size-1;
+ DBGPRINT(RT_DEBUG_ERROR, ("Set_HtTxBASize ::(TxBASize= %d)\n", Size));
+
+ return TRUE;
+}
+
+
+INT Set_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == HTMODE_GF)
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
+ else if ( Value == HTMODE_MM )
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtOpMode_Proc::(HtOpMode=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.HTMODE));
+
+ return TRUE;
+
+}
+
+INT Set_HtStbc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == STBC_USE)
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
+ else if ( Value == STBC_NONE )
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Stbc_Proc::(HtStbc=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.STBC));
+
+ return TRUE;
+}
+
+INT Set_HtHtc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->HTCEnable = FALSE;
+ else if ( Value ==1 )
+ pAd->HTCEnable = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtHtc_Proc::(HtHtc=%d)\n",pAd->HTCEnable));
+
+ return TRUE;
+}
+
+INT Set_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == 0)
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+ else if ( Value ==1 )
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtExtcha_Proc::(HtExtcha=%d)\n",pAd->CommonCfg.RegTransmitSetting.field.EXTCHA));
+
+ return TRUE;
+}
+
+INT Set_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value <=7 && Value >= 0)
+ pAd->CommonCfg.BACapability.field.MpduDensity = Value;
+ else
+ pAd->CommonCfg.BACapability.field.MpduDensity = 4;
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMpduDensity_Proc::(HtMpduDensity=%d)\n",pAd->CommonCfg.BACapability.field.MpduDensity));
+
+ return TRUE;
+}
+
+INT Set_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+
+ if (Value >=1 && Value <= 64)
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
+ }
+ else
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
+ }
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtBaWinSize_Proc::(HtBaWinSize=%d)\n",pAd->CommonCfg.BACapability.field.RxBAWinLimit));
+
+ return TRUE;
+}
+
+INT Set_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value == 0)
+ pAd->CommonCfg.bRdg = FALSE;
+ else if ( Value ==1 )
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->CommonCfg.bRdg = TRUE;
+ }
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtRdg_Proc::(HtRdg=%d)\n",pAd->CommonCfg.bRdg));
+
+ return TRUE;
+}
+
+INT Set_HtLinkAdapt_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->bLinkAdapt = FALSE;
+ else if ( Value ==1 )
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->bLinkAdapt = TRUE;
+ }
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtLinkAdapt_Proc::(HtLinkAdapt=%d)\n",pAd->bLinkAdapt));
+
+ return TRUE;
+}
+
+INT Set_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
+ else if ( Value == 1 )
+ pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAmsdu_Proc::(HtAmsdu=%d)\n",pAd->CommonCfg.BACapability.field.AmsduEnable));
+
+ return TRUE;
+}
+
+INT Set_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+ }
+ else if (Value == 1)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+ pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+ }
+ else
+ return FALSE; //Invalid argument
+
+ pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
+ pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtAutoBa_Proc::(HtAutoBa=%d)\n",pAd->CommonCfg.BACapability.field.AutoBA));
+
+ return TRUE;
+
+}
+
+INT Set_HtProtect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->CommonCfg.bHTProtect = FALSE;
+ else if (Value == 1)
+ pAd->CommonCfg.bHTProtect = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtProtect_Proc::(HtProtect=%d)\n",pAd->CommonCfg.bHTProtect));
+
+ return TRUE;
+}
+
+INT Set_SendPSMPAction_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[6], mode;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ MAC_TABLE_ENTRY *pEntry;
+
+ //printk("\n%s\n", arg);
+/*
+ The BARecTearDown inupt string format should be xx:xx:xx:xx:xx:xx-d,
+ =>The six 2 digit hex-decimal number previous are the Mac address,
+ =>The seventh decimal number is the mode value.
+*/
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and mode value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ mode = simple_strtol((token+1), 0, 10);
+ if (mode > MMPS_ENABLE)
+ return FALSE;
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%02x", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], mode);
+
+ pEntry = MacTableLookup(pAd, mac);
+
+ if (pEntry) {
+ printk("\nSendPSMPAction MIPS mode = %d\n", mode);
+ SendPSMPAction(pAd, pEntry->Aid, mode);
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+
+}
+
+INT Set_HtMIMOPSmode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ if (Value <=3 && Value >= 0)
+ pAd->CommonCfg.BACapability.field.MMPSmode = Value;
+ else
+ pAd->CommonCfg.BACapability.field.MMPSmode = 3;
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMIMOPSmode_Proc::(MIMOPS mode=%d)\n",pAd->CommonCfg.BACapability.field.MMPSmode));
+
+ return TRUE;
+}
+
+
+INT Set_ForceShortGI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->WIFItestbed.bShortGI = FALSE;
+ else if (Value == 1)
+ pAd->WIFItestbed.bShortGI = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceShortGI_Proc::(ForceShortGI=%d)\n", pAd->WIFItestbed.bShortGI));
+
+ return TRUE;
+}
+
+
+
+INT Set_ForceGF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->WIFItestbed.bGreenField = FALSE;
+ else if (Value == 1)
+ pAd->WIFItestbed.bGreenField = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ SetCommonHT(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_ForceGF_Proc::(ForceGF=%d)\n", pAd->WIFItestbed.bGreenField));
+
+ return TRUE;
+}
+
+INT Set_HtMimoPs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+ if (Value == 0)
+ pAd->CommonCfg.bMIMOPSEnable = FALSE;
+ else if (Value == 1)
+ pAd->CommonCfg.bMIMOPSEnable = TRUE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_HtMimoPs_Proc::(HtMimoPs=%d)\n",pAd->CommonCfg.bMIMOPSEnable));
+
+ return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+INT SetCommonHT(
+ IN PRTMP_ADAPTER pAd)
+{
+ OID_SET_HT_PHYMODE SetHT;
+
+ if (pAd->CommonCfg.PhyMode < PHY_11ABGN_MIXED)
+ return FALSE;
+
+ SetHT.PhyMode = pAd->CommonCfg.PhyMode;
+ SetHT.TransmitNo = ((UCHAR)pAd->Antenna.field.TxPath);
+ SetHT.HtMode = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.HTMODE;
+ SetHT.ExtOffset = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.EXTCHA;
+ SetHT.MCS = MCS_AUTO;
+ SetHT.BW = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.BW;
+ SetHT.STBC = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.STBC;
+ SetHT.SHORTGI = (UCHAR)pAd->CommonCfg.RegTransmitSetting.field.ShortGI;
+
+ RTMPSetHT(pAd, &SetHT);
+
+ return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+
+INT Set_FixedTxMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR fix_tx_mode = FIXED_TXMODE_HT;
+
+ if (strcmp(arg, "OFDM") == 0 || strcmp(arg, "ofdm") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_OFDM;
+ }
+ else if (strcmp(arg, "CCK") == 0 || strcmp(arg, "cck") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_CCK;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_FixedTxMode_Proc::(FixedTxMode=%d)\n", fix_tx_mode));
+
+ return TRUE;
+}
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+INT Set_OpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ULONG Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+#ifdef RT2870
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+#endif // RT2870 //
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Can not switch operate mode on interface up !! \n"));
+ return FALSE;
+ }
+
+ if (Value == 0)
+ pAd->OpMode = OPMODE_STA;
+ else if (Value == 1)
+ pAd->OpMode = OPMODE_AP;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_OpMode_Proc::(OpMode=%s)\n", pAd->OpMode == 1 ? "AP Mode" : "STA Mode"));
+
+ return TRUE;
+}
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+
+/////////////////////////////////////////////////////////////////////////
+PCHAR RTMPGetRalinkAuthModeStr(
+ IN NDIS_802_11_AUTHENTICATION_MODE authMode)
+{
+ switch(authMode)
+ {
+ case Ndis802_11AuthModeOpen:
+ return "OPEN";
+ default:
+ case Ndis802_11AuthModeWPAPSK:
+ return "WPAPSK";
+ case Ndis802_11AuthModeShared:
+ return "SHARED";
+ case Ndis802_11AuthModeWPA:
+ return "WPA";
+ case Ndis802_11AuthModeWPA2:
+ return "WPA2";
+ case Ndis802_11AuthModeWPA2PSK:
+ return "WPA2PSK";
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ return "WPAPSKWPA2PSK";
+ case Ndis802_11AuthModeWPA1WPA2:
+ return "WPA1WPA2";
+ }
+}
+
+PCHAR RTMPGetRalinkEncryModeStr(
+ IN USHORT encryMode)
+{
+ switch(encryMode)
+ {
+ default:
+ case Ndis802_11WEPDisabled:
+ return "NONE";
+ case Ndis802_11WEPEnabled:
+ return "WEP";
+ case Ndis802_11Encryption2Enabled:
+ return "TKIP";
+ case Ndis802_11Encryption3Enabled:
+ return "AES";
+ case Ndis802_11Encryption4Enabled:
+ return "TKIPAES";
+ }
+}
+
+INT RTMPShowCfgValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pName,
+ IN PUCHAR pBuf)
+{
+ INT Status = 0;
+
+ for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
+ {
+ if (!strcmp(pName, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name))
+ {
+ if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->show_proc(pAd, pBuf))
+ Status = -EINVAL;
+ break; //Exit for loop.
+ }
+ }
+
+ if(PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name == NULL)
+ {
+ sprintf(pBuf, "\n");
+ for (PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC = RTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name; PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC++)
+ sprintf(pBuf, "%s%s\n", pBuf, PRTMP_PRIVATE_STA_SHOW_CFG_VALUE_PROC->name);
+ }
+
+ return Status;
+}
+
+INT Show_SSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.Ssid);
+#endif // CONFIG_STA_SUPPORT //
+ return 0;
+}
+
+INT Show_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.PhyMode)
+ {
+ case PHY_11BG_MIXED:
+ sprintf(pBuf, "\t11B/G");
+ break;
+ case PHY_11B:
+ sprintf(pBuf, "\t11B");
+ break;
+ case PHY_11A:
+ sprintf(pBuf, "\t11A");
+ break;
+ case PHY_11ABG_MIXED:
+ sprintf(pBuf, "\t11A/B/G");
+ break;
+ case PHY_11G:
+ sprintf(pBuf, "\t11G");
+ break;
+#ifdef DOT11_N_SUPPORT
+ case PHY_11ABGN_MIXED:
+ sprintf(pBuf, "\t11A/B/G/N");
+ break;
+ case PHY_11N_2_4G:
+ sprintf(pBuf, "\t11N only with 2.4G");
+ break;
+ case PHY_11GN_MIXED:
+ sprintf(pBuf, "\t11G/N");
+ break;
+ case PHY_11AN_MIXED:
+ sprintf(pBuf, "\t11A/N");
+ break;
+ case PHY_11BGN_MIXED:
+ sprintf(pBuf, "\t11B/G/N");
+ break;
+ case PHY_11AGN_MIXED:
+ sprintf(pBuf, "\t11A/G/N");
+ break;
+ case PHY_11N_5G:
+ sprintf(pBuf, "\t11N only with 5G");
+ break;
+#endif // DOT11_N_SUPPORT //
+ default:
+ sprintf(pBuf, "\tUnknow Value(%d)", pAd->CommonCfg.PhyMode);
+ break;
+ }
+ return 0;
+}
+
+
+INT Show_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bEnableTxBurst ? "TRUE":"FALSE");
+ return 0;
+}
+
+INT Show_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.TxPreamble)
+ {
+ case Rt802_11PreambleShort:
+ sprintf(pBuf, "\tShort");
+ break;
+ case Rt802_11PreambleLong:
+ sprintf(pBuf, "\tLong");
+ break;
+ case Rt802_11PreambleAuto:
+ sprintf(pBuf, "\tAuto");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.TxPreamble);
+ break;
+ }
+
+ return 0;
+}
+
+INT Show_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%lu", pAd->CommonCfg.TxPowerPercentage);
+ return 0;
+}
+
+INT Show_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%d", pAd->CommonCfg.Channel);
+ return 0;
+}
+
+INT Show_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.UseBGProtection)
+ {
+ case 1: //Always On
+ sprintf(pBuf, "\tON");
+ break;
+ case 2: //Always OFF
+ sprintf(pBuf, "\tOFF");
+ break;
+ case 0: //AUTO
+ sprintf(pBuf, "\tAuto");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%lu)", pAd->CommonCfg.UseBGProtection);
+ break;
+ }
+ return 0;
+}
+
+INT Show_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.RtsThreshold);
+ return 0;
+}
+
+INT Show_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.FragmentThreshold);
+ return 0;
+}
+
+#ifdef DOT11_N_SUPPORT
+INT Show_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ if (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40)
+ {
+ sprintf(pBuf, "\t40 MHz");
+ }
+ else
+ {
+ sprintf(pBuf, "\t20 MHz");
+ }
+ return 0;
+}
+
+INT Show_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ sprintf(pBuf, "\t%u", pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+#endif // CONFIG_STA_SUPPORT //
+ return 0;
+}
+
+INT Show_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.RegTransmitSetting.field.ShortGI)
+ {
+ case GI_400:
+ sprintf(pBuf, "\tGI_400");
+ break;
+ case GI_800:
+ sprintf(pBuf, "\tGI_800");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.ShortGI);
+ break;
+ }
+ return 0;
+}
+
+INT Show_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.RegTransmitSetting.field.HTMODE)
+ {
+ case HTMODE_GF:
+ sprintf(pBuf, "\tGF");
+ break;
+ case HTMODE_MM:
+ sprintf(pBuf, "\tMM");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.HTMODE);
+ break;
+ }
+ return 0;
+}
+
+INT Show_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->CommonCfg.RegTransmitSetting.field.EXTCHA)
+ {
+ case EXTCHA_BELOW:
+ sprintf(pBuf, "\tBelow");
+ break;
+ case EXTCHA_ABOVE:
+ sprintf(pBuf, "\tAbove");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%u)", pAd->CommonCfg.RegTransmitSetting.field.EXTCHA);
+ break;
+ }
+ return 0;
+}
+
+
+INT Show_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.MpduDensity);
+ return 0;
+}
+
+INT Show_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%u", pAd->CommonCfg.BACapability.field.RxBAWinLimit);
+ return 0;
+}
+
+INT Show_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bRdg ? "TRUE":"FALSE");
+ return 0;
+}
+
+INT Show_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AmsduEnable ? "TRUE":"FALSE");
+ return 0;
+}
+
+INT Show_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.BACapability.field.AutoBA ? "TRUE":"FALSE");
+ return 0;
+}
+#endif // DOT11_N_SUPPORT //
+
+INT Show_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegion);
+ return 0;
+}
+
+INT Show_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%d", pAd->CommonCfg.CountryRegionForABand);
+ return 0;
+}
+
+INT Show_CountryCode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.CountryCode);
+ return 0;
+}
+
+#ifdef AGGREGATION_SUPPORT
+INT Show_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bAggregationCapable ? "TRUE":"FALSE");
+ return 0;
+}
+#endif // AGGREGATION_SUPPORT //
+
+#ifdef WMM_SUPPORT
+INT Show_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bWmmCapable ? "TRUE":"FALSE");
+#endif // CONFIG_STA_SUPPORT //
+
+ return 0;
+}
+#endif // WMM_SUPPORT //
+
+INT Show_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ sprintf(pBuf, "\t%s", pAd->CommonCfg.bIEEE80211H ? "TRUE":"FALSE");
+ return 0;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+INT Show_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ switch(pAd->StaCfg.BssType)
+ {
+ case BSS_ADHOC:
+ sprintf(pBuf, "\tAdhoc");
+ break;
+ case BSS_INFRA:
+ sprintf(pBuf, "\tInfra");
+ break;
+ case BSS_ANY:
+ sprintf(pBuf, "\tAny");
+ break;
+ case BSS_MONITOR:
+ sprintf(pBuf, "\tMonitor");
+ break;
+ default:
+ sprintf(pBuf, "\tUnknow Value(%d)", pAd->StaCfg.BssType);
+ break;
+ }
+ return 0;
+}
+#endif // CONFIG_STA_SUPPORT //
+
+INT Show_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeOpen;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AuthMode = pAd->StaCfg.AuthMode;
+#endif // CONFIG_STA_SUPPORT //
+
+ if ((AuthMode >= Ndis802_11AuthModeOpen) &&
+ (AuthMode <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ sprintf(pBuf, "\t%s", RTMPGetRalinkAuthModeStr(AuthMode));
+ else
+ sprintf(pBuf, "\tUnknow Value(%d)", AuthMode);
+
+ return 0;
+}
+
+INT Show_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ NDIS_802_11_WEP_STATUS WepStatus = Ndis802_11WEPDisabled;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ WepStatus = pAd->StaCfg.WepStatus;
+#endif // CONFIG_STA_SUPPORT //
+
+ if ((WepStatus >= Ndis802_11WEPEnabled) &&
+ (WepStatus <= Ndis802_11Encryption4KeyAbsent))
+ sprintf(pBuf, "\t%s", RTMPGetRalinkEncryModeStr(WepStatus));
+ else
+ sprintf(pBuf, "\tUnknow Value(%d)", WepStatus);
+
+ return 0;
+}
+
+INT Show_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ UCHAR DefaultKeyId = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ DefaultKeyId = pAd->StaCfg.DefaultKeyId;
+#endif // CONFIG_STA_SUPPORT //
+
+ sprintf(pBuf, "\t%d", DefaultKeyId);
+
+ return 0;
+}
+
+INT Show_WepKey_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN INT KeyIdx,
+ OUT PUCHAR pBuf)
+{
+ UCHAR Key[16] = {0}, KeyLength = 0;
+ INT index = BSS0;
+
+ KeyLength = pAd->SharedKey[index][KeyIdx].KeyLen;
+ NdisMoveMemory(Key, pAd->SharedKey[index][KeyIdx].Key, KeyLength);
+
+ //check key string is ASCII or not
+ if (RTMPCheckStrPrintAble(Key, KeyLength))
+ sprintf(pBuf, "\t%s", Key);
+ else
+ {
+ int idx;
+ sprintf(pBuf, "\t");
+ for (idx = 0; idx < KeyLength; idx++)
+ sprintf(pBuf+strlen(pBuf), "%02X", Key[idx]);
+ }
+ return 0;
+}
+
+INT Show_Key1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 0, pBuf);
+ return 0;
+}
+
+INT Show_Key2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 1, pBuf);
+ return 0;
+}
+
+INT Show_Key3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 2, pBuf);
+ return 0;
+}
+
+INT Show_Key4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ Show_WepKey_Proc(pAd, 3, pBuf);
+ return 0;
+}
+
+INT Show_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pBuf)
+{
+ INT idx;
+ UCHAR PMK[32] = {0};
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisMoveMemory(PMK, pAd->StaCfg.PMK, 32);
+#endif // CONFIG_STA_SUPPORT //
+
+ sprintf(pBuf, "\tPMK = ");
+ for (idx = 0; idx < 32; idx++)
+ sprintf(pBuf+strlen(pBuf), "%02X", PMK[idx]);
+
+ return 0;
+}
+
diff --git a/drivers/staging/rt3070/common/cmm_sanity.c b/drivers/staging/rt3070/common/cmm_sanity.c
new file mode 100644
index 00000000000..6118df8de7b
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sanity.c
@@ -0,0 +1,1669 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sanity.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 add WMM support
+*/
+#include "../rt_config.h"
+
+
+extern UCHAR CISCO_OUI[];
+
+extern UCHAR WPA_OUI[];
+extern UCHAR RSN_OUI[];
+extern UCHAR WME_INFO_ELEM[];
+extern UCHAR WME_PARM_ELEM[];
+extern UCHAR Ccx2QosInfo[];
+extern UCHAR RALINK_OUI[];
+extern UCHAR BROADCOM_OUI[];
+extern UCHAR WPS_OUI[];
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeAddBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2)
+{
+ PMLME_ADDBA_REQ_STRUCT pInfo;
+
+ pInfo = (MLME_ADDBA_REQ_STRUCT *)Msg;
+
+ if ((MsgLen != sizeof(MLME_ADDBA_REQ_STRUCT)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - message lenght not correct.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - The peer Mac is not associated yet.\n"));
+ return FALSE;
+ }
+
+ /*
+ if ((pInfo->BaBufSize > MAX_RX_REORDERBUF) || (pInfo->BaBufSize < 2))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - Rx Reordering buffer too big or too small\n"));
+ return FALSE;
+ }
+ */
+
+ if ((pInfo->pAddr[0]&0x01) == 0x01)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAddBAReqSanity fail - broadcast address not support BA\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeDelBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen)
+{
+ MLME_DELBA_REQ_STRUCT *pInfo;
+ pInfo = (MLME_DELBA_REQ_STRUCT *)Msg;
+
+ if ((MsgLen != sizeof(MLME_DELBA_REQ_STRUCT)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - message lenght not correct.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->Wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer Mac is not associated yet.\n"));
+ return FALSE;
+ }
+
+ if ((pInfo->TID & 0xf0))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - The peer TID is incorrect.\n"));
+ return FALSE;
+ }
+
+ if (NdisEqualMemory(pAd->MacTab.Content[pInfo->Wcid].Addr, pInfo->Addr, MAC_ADDR_LEN) == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MlmeDelBAReqSanity fail - the peer addr dosen't exist.\n"));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN PeerAddBAReqActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PFRAME_ADDBA_REQ pAddFrame;
+ pAddFrame = (PFRAME_ADDBA_REQ)(pMsg);
+ if (MsgLen < (sizeof(FRAME_ADDBA_REQ)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+ // we support immediate BA.
+ *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+ pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
+ pAddFrame->BaStartSeq.word = cpu2le16(pAddFrame->BaStartSeq.word);
+
+ if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
+ DBGPRINT(RT_DEBUG_ERROR,("ADDBA Request. tid=%x, Bufsize=%x, AMSDUSupported=%x \n", pAddFrame->BaParm.TID, pAddFrame->BaParm.BufSize, pAddFrame->BaParm.AMSDUSupported));
+ return FALSE;
+ }
+
+ // we support immediate BA.
+ if (pAddFrame->BaParm.TID &0xfff0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Request incorrect TID = %d\n", pAddFrame->BaParm.TID));
+ return FALSE;
+ }
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ return TRUE;
+}
+
+BOOLEAN PeerAddBARspActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen)
+{
+ //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PFRAME_ADDBA_RSP pAddFrame;
+
+ pAddFrame = (PFRAME_ADDBA_RSP)(pMsg);
+ if (MsgLen < (sizeof(FRAME_ADDBA_RSP)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response frame length size = %ld incorrect\n", MsgLen));
+ return FALSE;
+ }
+ // we support immediate BA.
+ *(USHORT *)(&pAddFrame->BaParm) = cpu2le16(*(USHORT *)(&pAddFrame->BaParm));
+ pAddFrame->StatusCode = cpu2le16(pAddFrame->StatusCode);
+ pAddFrame->TimeOutValue = cpu2le16(pAddFrame->TimeOutValue);
+
+ if (pAddFrame->BaParm.BAPolicy != IMMED_BA)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBAReqActionSanity: ADDBA Response Ba Policy[%d] not support\n", pAddFrame->BaParm.BAPolicy));
+ return FALSE;
+ }
+
+ // we support immediate BA.
+ if (pAddFrame->BaParm.TID &0xfff0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("PeerAddBARspActionSanity: ADDBA Response incorrect TID = %d\n", pAddFrame->BaParm.TID));
+ return FALSE;
+ }
+ return TRUE;
+
+}
+
+BOOLEAN PeerDelBAActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN VOID *pMsg,
+ IN ULONG MsgLen )
+{
+ //PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PFRAME_DELBA_REQ pDelFrame;
+ if (MsgLen != (sizeof(FRAME_DELBA_REQ)))
+ return FALSE;
+
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ pDelFrame = (PFRAME_DELBA_REQ)(pMsg);
+
+ *(USHORT *)(&pDelFrame->DelbaParm) = cpu2le16(*(USHORT *)(&pDelFrame->DelbaParm));
+ pDelFrame->ReasonCode = cpu2le16(pDelFrame->ReasonCode);
+
+ if (pDelFrame->DelbaParm.TID &0xfff0)
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerBeaconAndProbeRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgChannel,
+ OUT PUCHAR pAddr2,
+ OUT PUCHAR pBssid,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen,
+ OUT UCHAR *pBssType,
+ OUT USHORT *pBeaconPeriod,
+ OUT UCHAR *pChannel,
+ OUT UCHAR *pNewChannel,
+ OUT LARGE_INTEGER *pTimestamp,
+ OUT CF_PARM *pCfParm,
+ OUT USHORT *pAtimWin,
+ OUT USHORT *pCapabilityInfo,
+ OUT UCHAR *pErp,
+ OUT UCHAR *pDtimCount,
+ OUT UCHAR *pDtimPeriod,
+ OUT UCHAR *pBcastFlag,
+ OUT UCHAR *pMessageToMe,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT UCHAR *pCkipFlag,
+ OUT UCHAR *pAironetCellPowerLimit,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT PQBSS_LOAD_PARM pQbssLoad,
+ OUT PQOS_CAPABILITY_PARM pQosCapability,
+ OUT ULONG *pRalinkIe,
+ OUT UCHAR *pHtCapabilityLen,
+#ifdef CONFIG_STA_SUPPORT
+ OUT UCHAR *pPreNHtCapabilityLen,
+#endif // CONFIG_STA_SUPPORT //
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT UCHAR *AddHtInfoLen,
+ OUT ADD_HT_INFO_IE *AddHtInfo,
+ OUT UCHAR *NewExtChannelOffset, // Ht extension channel offset(above or below)
+ OUT USHORT *LengthVIE,
+ OUT PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ CHAR *Ptr;
+#ifdef CONFIG_STA_SUPPORT
+ CHAR TimLen;
+#endif // CONFIG_STA_SUPPORT //
+ PFRAME_802_11 pFrame;
+ PEID_STRUCT pEid;
+ UCHAR SubType;
+ UCHAR Sanity;
+ //UCHAR ECWMin, ECWMax;
+ //MAC_CSR9_STRUC Csr9;
+ ULONG Length = 0;
+
+ // For some 11a AP which didn't have DS_IE, we use two conditions to decide the channel
+ // 1. If the AP is 11n enabled, then check the control channel.
+ // 2. If the AP didn't have any info about channel, use the channel we received this frame as the channel. (May inaccuracy!!)
+ UCHAR CtrlChannel = 0;
+
+ // Add for 3 necessary EID field check
+ Sanity = 0;
+
+ *pAtimWin = 0;
+ *pErp = 0;
+ *pDtimCount = 0;
+ *pDtimPeriod = 0;
+ *pBcastFlag = 0;
+ *pMessageToMe = 0;
+ *pExtRateLen = 0;
+ *pCkipFlag = 0; // Default of CkipFlag is 0
+ *pAironetCellPowerLimit = 0xFF; // Default of AironetCellPowerLimit is 0xFF
+ *LengthVIE = 0; // Set the length of VIE to init value 0
+ *pHtCapabilityLen = 0; // Set the length of VIE to init value 0
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->OpMode == OPMODE_STA)
+ *pPreNHtCapabilityLen = 0; // Set the length of VIE to init value 0
+#endif // CONFIG_STA_SUPPORT //
+ *AddHtInfoLen = 0; // Set the length of VIE to init value 0
+ *pRalinkIe = 0;
+ *pNewChannel = 0;
+ *NewExtChannelOffset = 0xff; //Default 0xff means no such IE
+ pCfParm->bValid = FALSE; // default: no IE_CF found
+ pQbssLoad->bValid = FALSE; // default: no IE_QBSS_LOAD found
+ pEdcaParm->bValid = FALSE; // default: no IE_EDCA_PARAMETER found
+ pQosCapability->bValid = FALSE; // default: no IE_QOS_CAPABILITY found
+
+ pFrame = (PFRAME_802_11)Msg;
+
+ // get subtype from header
+ SubType = (UCHAR)pFrame->Hdr.FC.SubType;
+
+ // get Addr2 and BSSID from header
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ COPY_MAC_ADDR(pBssid, pFrame->Hdr.Addr3);
+
+// hex_dump("Beacon", Msg, MsgLen);
+
+ Ptr = pFrame->Octet;
+ Length += LENGTH_802_11;
+
+ // get timestamp from payload and advance the pointer
+ NdisMoveMemory(pTimestamp, Ptr, TIMESTAMP_LEN);
+
+ pTimestamp->u.LowPart = cpu2le32(pTimestamp->u.LowPart);
+ pTimestamp->u.HighPart = cpu2le32(pTimestamp->u.HighPart);
+
+ Ptr += TIMESTAMP_LEN;
+ Length += TIMESTAMP_LEN;
+
+ // get beacon interval from payload and advance the pointer
+ NdisMoveMemory(pBeaconPeriod, Ptr, 2);
+ Ptr += 2;
+ Length += 2;
+
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+ Ptr += 2;
+ Length += 2;
+
+ if (CAP_IS_ESS_ON(*pCapabilityInfo))
+ *pBssType = BSS_INFRA;
+ else
+ *pBssType = BSS_ADHOC;
+
+ pEid = (PEID_STRUCT) Ptr;
+
+ // get variable fields from payload and advance the pointer
+ while ((Length + 2 + pEid->Len) <= MsgLen)
+ {
+ //
+ // Secure copy VIE to VarIE[MAX_VIE_LEN] didn't overflow.
+ //
+ if ((*LengthVIE + pEid->Len + 2) >= MAX_VIE_LEN)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - Variable IEs out of resource [len(=%d) > MAX_VIE_LEN(=%d)]\n",
+ (*LengthVIE + pEid->Len + 2), MAX_VIE_LEN));
+ break;
+ }
+
+ switch(pEid->Eid)
+ {
+ case IE_SSID:
+ // Already has one SSID EID in this beacon, ignore the second one
+ if (Sanity & 0x1)
+ break;
+ if(pEid->Len <= MAX_LEN_OF_SSID)
+ {
+ NdisMoveMemory(Ssid, pEid->Octet, pEid->Len);
+ *pSsidLen = pEid->Len;
+ Sanity |= 0x1;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+
+ case IE_SUPP_RATES:
+ if(pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ Sanity |= 0x2;
+ NdisMoveMemory(SupRate, pEid->Octet, pEid->Len);
+ *pSupRateLen = pEid->Len;
+
+ // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
+ // from ScanTab. We should report as is. And filter out unsupported
+ // rates in MlmeAux.
+ // Check against the supported rates
+ // RTMPCheckRates(pAd, SupRate, pSupRateLen);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SUPP_RATES (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
+ {
+ NdisMoveMemory(pHtCapability, pEid->Octet, sizeof(HT_CAPABILITY_IE));
+ *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ *pPreNHtCapabilityLen = 0; // Nnow we only support 26 bytes.
+
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_HT_CAP. pEid->Len = %d\n", pEid->Len));
+ }
+
+ break;
+ case IE_ADD_HT:
+ if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
+ {
+ // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
+ // copy first sizeof(ADD_HT_INFO_IE)
+ NdisMoveMemory(AddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+
+ CtrlChannel = AddHtInfo->ControlChan;
+
+ *(USHORT *)(&AddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo2));
+ *(USHORT *)(&AddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&AddHtInfo->AddHtInfo3));
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_ADD_HT. \n"));
+ }
+
+ break;
+ case IE_SECONDARY_CH_OFFSET:
+ if (pEid->Len == 1)
+ {
+ *NewExtChannelOffset = pEid->Octet[0];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+ }
+
+ break;
+ case IE_FH_PARM:
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity(IE_FH_PARM) \n"));
+ break;
+
+ case IE_DS_PARM:
+ if(pEid->Len == 1)
+ {
+ *pChannel = *pEid->Octet;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (ChannelSanity(pAd, *pChannel) == 0)
+ {
+
+ return FALSE;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ Sanity |= 0x4;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_DS_PARM (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+
+ case IE_CF_PARM:
+ if(pEid->Len == 6)
+ {
+ pCfParm->bValid = TRUE;
+ pCfParm->CfpCount = pEid->Octet[0];
+ pCfParm->CfpPeriod = pEid->Octet[1];
+ pCfParm->CfpMaxDuration = pEid->Octet[2] + 256 * pEid->Octet[3];
+ pCfParm->CfpDurRemaining = pEid->Octet[4] + 256 * pEid->Octet[5];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_CF_PARM\n"));
+ return FALSE;
+ }
+ break;
+
+ case IE_IBSS_PARM:
+ if(pEid->Len == 2)
+ {
+ NdisMoveMemory(pAtimWin, pEid->Octet, pEid->Len);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_IBSS_PARM\n"));
+ return FALSE;
+ }
+ break;
+
+#ifdef CONFIG_STA_SUPPORT
+ case IE_TIM:
+ if(INFRA_ON(pAd) && SubType == SUBTYPE_BEACON)
+ {
+ GetTimBit((PUCHAR)pEid, pAd->StaActive.Aid, &TimLen, pBcastFlag, pDtimCount, pDtimPeriod, pMessageToMe);
+ }
+ break;
+#endif // CONFIG_STA_SUPPORT //
+ case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+ if(pEid->Len == 3)
+ {
+ *pNewChannel = pEid->Octet[1]; //extract new channel number
+ }
+ break;
+
+ // New for WPA
+ // CCX v2 has the same IE, we need to parse that too
+ // Wifi WMM use the same IE vale, need to parse that too
+ // case IE_WPA:
+ case IE_VENDOR_SPECIFIC:
+ // Check Broadcom/Atheros 802.11n OUI version, for HT Capability IE.
+ // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+ /*if (NdisEqualMemory(pEid->Octet, BROADCOM_OUI, 3) && (pEid->Len >= 4))
+ {
+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 30))
+ {
+ {
+ NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
+ *pHtCapabilityLen = SIZE_HT_CAP_IE; // Nnow we only support 26 bytes.
+ }
+ }
+ if ((pEid->Octet[3] == OUI_BROADCOM_HT) && (pEid->Len >= 26))
+ {
+ {
+ NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE; // Nnow we only support 26 bytes.
+ }
+ }
+ }
+ */
+ // Check the OUI version, filter out non-standard usage
+ if (NdisEqualMemory(pEid->Octet, RALINK_OUI, 3) && (pEid->Len == 7))
+ {
+ //*pRalinkIe = pEid->Octet[3];
+ if (pEid->Octet[3] != 0)
+ *pRalinkIe = pEid->Octet[3];
+ else
+ *pRalinkIe = 0xf0000000; // Set to non-zero value (can't set bit0-2) to represent this is Ralink Chip. So at linkup, we will set ralinkchip flag.
+ }
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+ // This HT IE is before IEEE draft set HT IE value.2006-09-28 by Jan.
+
+ // Other vendors had production before IE_HT_CAP value is assigned. To backward support those old-firmware AP,
+ // Check broadcom-defiend pre-802.11nD1.0 OUI for HT related IE, including HT Capatilities IE and HT Information IE
+ else if ((*pHtCapabilityLen == 0) && NdisEqualMemory(pEid->Octet, PRE_N_HT_OUI, 3) && (pEid->Len >= 4) && (pAd->OpMode == OPMODE_STA))
+ {
+ if ((pEid->Octet[3] == OUI_PREN_HT_CAP) && (pEid->Len >= 30) && (*pHtCapabilityLen == 0))
+ {
+ NdisMoveMemory(pHtCapability, &pEid->Octet[4], sizeof(HT_CAPABILITY_IE));
+ *pPreNHtCapabilityLen = SIZE_HT_CAP_IE;
+ }
+
+ if ((pEid->Octet[3] == OUI_PREN_ADD_HT) && (pEid->Len >= 26))
+ {
+ NdisMoveMemory(AddHtInfo, &pEid->Octet[4], sizeof(ADD_HT_INFO_IE));
+ *AddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+ else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+ {
+ // Copy to pVIE which will report to microsoft bssid list.
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+ else if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
+ {
+ PUCHAR ptr;
+ int i;
+
+ // parsing EDCA parameters
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
+ ptr = &pEid->Octet[8];
+ for (i=0; i<4; i++)
+ {
+ UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
+ pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
+ pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
+ pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
+ pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
+ pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
+ ptr += 4; // point to next AC
+ }
+ }
+ else if (NdisEqualMemory(pEid->Octet, WME_INFO_ELEM, 6) && (pEid->Len == 7))
+ {
+ // parsing EDCA parameters
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
+
+ // use default EDCA parameter
+ pEdcaParm->bACM[QID_AC_BE] = 0;
+ pEdcaParm->Aifsn[QID_AC_BE] = 3;
+ pEdcaParm->Cwmin[QID_AC_BE] = CW_MIN_IN_BITS;
+ pEdcaParm->Cwmax[QID_AC_BE] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_BE] = 0;
+
+ pEdcaParm->bACM[QID_AC_BK] = 0;
+ pEdcaParm->Aifsn[QID_AC_BK] = 7;
+ pEdcaParm->Cwmin[QID_AC_BK] = CW_MIN_IN_BITS;
+ pEdcaParm->Cwmax[QID_AC_BK] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_BK] = 0;
+
+ pEdcaParm->bACM[QID_AC_VI] = 0;
+ pEdcaParm->Aifsn[QID_AC_VI] = 2;
+ pEdcaParm->Cwmin[QID_AC_VI] = CW_MIN_IN_BITS-1;
+ pEdcaParm->Cwmax[QID_AC_VI] = CW_MAX_IN_BITS;
+ pEdcaParm->Txop[QID_AC_VI] = 96; // AC_VI: 96*32us ~= 3ms
+
+ pEdcaParm->bACM[QID_AC_VO] = 0;
+ pEdcaParm->Aifsn[QID_AC_VO] = 2;
+ pEdcaParm->Cwmin[QID_AC_VO] = CW_MIN_IN_BITS-2;
+ pEdcaParm->Cwmax[QID_AC_VO] = CW_MAX_IN_BITS-1;
+ pEdcaParm->Txop[QID_AC_VO] = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ else
+ {
+ }
+
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+ *pExtRateLen = pEid->Len;
+
+ // TODO: 2004-09-14 not a good design here, cause it exclude extra rates
+ // from ScanTab. We should report as is. And filter out unsupported
+ // rates in MlmeAux.
+ // Check against the supported rates
+ // RTMPCheckRates(pAd, ExtRate, pExtRateLen);
+ }
+ break;
+
+ case IE_ERP:
+ if (pEid->Len == 1)
+ {
+ *pErp = (UCHAR)pEid->Octet[0];
+ }
+ break;
+
+ case IE_AIRONET_CKIP:
+ // 0. Check Aironet IE length, it must be larger or equal to 28
+ // Cisco AP350 used length as 28
+ // Cisco AP12XX used length as 30
+ if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+ break;
+
+ // 1. Copy CKIP flag byte to buffer for process
+ *pCkipFlag = *(pEid->Octet + 8);
+ break;
+
+ case IE_AP_TX_POWER:
+ // AP Control of Client Transmit Power
+ //0. Check Aironet IE length, it must be 6
+ if (pEid->Len != 0x06)
+ break;
+
+ // Get cell power limit in dBm
+ if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+ *pAironetCellPowerLimit = *(pEid->Octet + 4);
+ break;
+
+ // WPA2 & 802.11i RSN
+ case IE_RSN:
+ // There is no OUI for version anymore, check the group cipher OUI before copying
+ if (RTMPEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+ {
+ // Copy to pVIE which will report to microsoft bssid list.
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ }
+ break;
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+ case IE_COUNTRY:
+ Ptr = (PUCHAR) pVIE;
+ NdisMoveMemory(Ptr + *LengthVIE, &pEid->Eid, pEid->Len + 2);
+ *LengthVIE += (pEid->Len + 2);
+ break;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+ default:
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ // For some 11a AP. it did not have the channel EID, patch here
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ UCHAR LatchRfChannel = MsgChannel;
+ if ((pAd->LatchRfRegs.Channel > 14) && ((Sanity & 0x4) == 0))
+ {
+ if (CtrlChannel != 0)
+ *pChannel = CtrlChannel;
+ else
+ *pChannel = LatchRfChannel;
+ Sanity |= 0x4;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (Sanity != 0x7)
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerBeaconAndProbeRspSanity - missing field, Sanity=0x%02x\n", Sanity));
+ return FALSE;
+ }
+ else
+ {
+ return TRUE;
+ }
+
+}
+
+#ifdef DOT11N_DRAFT3
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check for some IE addressed in 802.11n d3.03.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerBeaconAndProbeRspSanity2(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT UCHAR *RegClass)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 pFrame;
+ PEID_STRUCT pEid;
+ ULONG Length = 0;
+
+ pFrame = (PFRAME_802_11)Msg;
+
+ *RegClass = 0;
+ Ptr = pFrame->Octet;
+ Length += LENGTH_802_11;
+
+ // get timestamp from payload and advance the pointer
+ Ptr += TIMESTAMP_LEN;
+ Length += TIMESTAMP_LEN;
+
+ // get beacon interval from payload and advance the pointer
+ Ptr += 2;
+ Length += 2;
+
+ // get capability info from payload and advance the pointer
+ Ptr += 2;
+ Length += 2;
+
+ pEid = (PEID_STRUCT) Ptr;
+
+ // get variable fields from payload and advance the pointer
+ while ((Length + 2 + pEid->Len) <= MsgLen)
+ {
+ switch(pEid->Eid)
+ {
+ case IE_SUPP_REG_CLASS:
+ if(pEid->Len > 0)
+ {
+ *RegClass = *pEid->Octet;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAndProbeRspSanity - wrong IE_SSID (len=%d)\n",pEid->Len));
+ return FALSE;
+ }
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len; // Eid[1] + Len[1]+ content[Len]
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ return TRUE;
+
+}
+#endif // DOT11N_DRAFT3 //
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN MlmeScanReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT UCHAR *pBssType,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen,
+ OUT UCHAR *pScanType)
+{
+ MLME_SCAN_REQ_STRUCT *Info;
+
+ Info = (MLME_SCAN_REQ_STRUCT *)(Msg);
+ *pBssType = Info->BssType;
+ *pSsidLen = Info->SsidLen;
+ NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
+ *pScanType = Info->ScanType;
+
+ if ((*pBssType == BSS_INFRA || *pBssType == BSS_ADHOC || *pBssType == BSS_ANY)
+ && (*pScanType == SCAN_ACTIVE || *pScanType == SCAN_PASSIVE
+#ifdef CONFIG_STA_SUPPORT
+ || *pScanType == SCAN_CISCO_PASSIVE || *pScanType == SCAN_CISCO_ACTIVE
+ || *pScanType == SCAN_CISCO_CHANNEL_LOAD || *pScanType == SCAN_CISCO_NOISE
+#endif // CONFIG_STA_SUPPORT //
+ ))
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqSanity fail - wrong BssType or ScanType\n"));
+ return FALSE;
+ }
+}
+
+// IRQL = DISPATCH_LEVEL
+UCHAR ChannelSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel)
+{
+ int i;
+
+ for (i = 0; i < pAd->ChannelListNum; i ++)
+ {
+ if (channel == pAd->ChannelList[i].Channel)
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerDeauthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pReason)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerAuthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT USHORT *pAlg,
+ OUT USHORT *pSeq,
+ OUT USHORT *pStatus,
+ CHAR *pChlgText)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr, pFrame->Hdr.Addr2);
+ NdisMoveMemory(pAlg, &pFrame->Octet[0], 2);
+ NdisMoveMemory(pSeq, &pFrame->Octet[2], 2);
+ NdisMoveMemory(pStatus, &pFrame->Octet[4], 2);
+
+ if ((*pAlg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+ || (*pAlg == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ )
+ {
+ if (*pSeq == 1 || *pSeq == 2)
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
+ return FALSE;
+ }
+ }
+ else if (*pAlg == Ndis802_11AuthModeShared)
+ {
+ if (*pSeq == 1 || *pSeq == 4)
+ {
+ return TRUE;
+ }
+ else if (*pSeq == 2 || *pSeq == 3)
+ {
+ NdisMoveMemory(pChlgText, &pFrame->Octet[8], CIPHER_TEXT_LEN);
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong Seg#\n"));
+ return FALSE;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAuthSanity fail - wrong algorithm\n"));
+ return FALSE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN MlmeAuthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT ULONG *pTimeout,
+ OUT USHORT *pAlg)
+{
+ MLME_AUTH_REQ_STRUCT *pInfo;
+
+ pInfo = (MLME_AUTH_REQ_STRUCT *)Msg;
+ COPY_MAC_ADDR(pAddr, pInfo->Addr);
+ *pTimeout = pInfo->Timeout;
+ *pAlg = pInfo->Alg;
+
+ if (((*pAlg == Ndis802_11AuthModeShared) ||(*pAlg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+ || (*pAlg == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ ) &&
+ ((*pAddr & 0x01) == 0))
+ {
+ return TRUE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeAuthReqSanity fail - wrong algorithm\n"));
+ return FALSE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN MlmeAssocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pApAddr,
+ OUT USHORT *pCapabilityInfo,
+ OUT ULONG *pTimeout,
+ OUT USHORT *pListenIntv)
+{
+ MLME_ASSOC_REQ_STRUCT *pInfo;
+
+ pInfo = (MLME_ASSOC_REQ_STRUCT *)Msg;
+ *pTimeout = pInfo->Timeout; // timeout
+ COPY_MAC_ADDR(pApAddr, pInfo->Addr); // AP address
+ *pCapabilityInfo = pInfo->CapabilityInfo; // capability info
+ *pListenIntv = pInfo->ListenIntv;
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerDisassocSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pReason)
+{
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ NdisMoveMemory(pReason, &pFrame->Octet[0], 2);
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Sanity check NetworkType (11b, 11g or 11a)
+
+ Arguments:
+ pBss - Pointer to BSS table.
+
+ Return Value:
+ Ndis802_11DS .......(11b)
+ Ndis802_11OFDM24....(11g)
+ Ndis802_11OFDM5.....(11a)
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
+ IN PBSS_ENTRY pBss)
+{
+ NDIS_802_11_NETWORK_TYPE NetWorkType;
+ UCHAR rate, i;
+
+ NetWorkType = Ndis802_11DS;
+
+ if (pBss->Channel <= 14)
+ {
+ //
+ // First check support Rate.
+ //
+ for (i = 0; i < pBss->SupRateLen; i++)
+ {
+ rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
+ if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
+ {
+ continue;
+ }
+ else
+ {
+ //
+ // Otherwise (even rate > 108) means Ndis802_11OFDM24
+ //
+ NetWorkType = Ndis802_11OFDM24;
+ break;
+ }
+ }
+
+ //
+ // Second check Extend Rate.
+ //
+ if (NetWorkType != Ndis802_11OFDM24)
+ {
+ for (i = 0; i < pBss->ExtRateLen; i++)
+ {
+ rate = pBss->SupRate[i] & 0x7f; // Mask out basic rate set bit
+ if ((rate == 2) || (rate == 4) || (rate == 11) || (rate == 22))
+ {
+ continue;
+ }
+ else
+ {
+ //
+ // Otherwise (even rate > 108) means Ndis802_11OFDM24
+ //
+ NetWorkType = Ndis802_11OFDM24;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ NetWorkType = Ndis802_11OFDM5;
+ }
+
+ if (pBss->HtCapabilityLen != 0)
+ {
+ if (NetWorkType == Ndis802_11OFDM5)
+ NetWorkType = Ndis802_11OFDM5_N;
+ else
+ NetWorkType = Ndis802_11OFDM24_N;
+ }
+
+ return NetWorkType;
+}
+
+/*
+ ==========================================================================
+ Description:
+ WPA message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN PeerWpaMessageSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN PEAPOL_PACKET pMsg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ UCHAR mic[LEN_KEY_DESC_MIC], digest[80], KEYDATA[MAX_LEN_OF_RSNIE];
+ BOOLEAN bReplayDiff = FALSE;
+ BOOLEAN bWPA2 = FALSE;
+ KEY_INFO EapolKeyInfo;
+ UCHAR GroupKeyIndex = 0;
+
+
+ NdisZeroMemory(mic, sizeof(mic));
+ NdisZeroMemory(digest, sizeof(digest));
+ NdisZeroMemory(KEYDATA, sizeof(KEYDATA));
+ NdisZeroMemory((PUCHAR)&EapolKeyInfo, sizeof(EapolKeyInfo));
+
+ NdisMoveMemory((PUCHAR)&EapolKeyInfo, (PUCHAR)&pMsg->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT *)&EapolKeyInfo) = cpu2le16(*((USHORT *)&EapolKeyInfo));
+
+ // Choose WPA2 or not
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2) || (pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK))
+ bWPA2 = TRUE;
+
+ // 0. Check MsgType
+ if ((MsgType > EAPOL_GROUP_MSG_2) || (MsgType < EAPOL_PAIR_MSG_1))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("The message type is invalid(%d)! \n", MsgType));
+ return FALSE;
+ }
+
+ // 1. Replay counter check
+ if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1) // For supplicant
+ {
+ // First validate replay counter, only accept message with larger replay counter.
+ // Let equal pass, some AP start with all zero replay counter
+ UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
+
+ NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+ if ((RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY) != 1) &&
+ (RTMPCompareMemory(pMsg->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+ {
+ bReplayDiff = TRUE;
+ }
+ }
+ else if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2) // For authenticator
+ {
+ // check Replay Counter coresponds to MSG from authenticator, otherwise discard
+ if (!NdisEqualMemory(pMsg->KeyDesc.ReplayCounter, pEntry->R_Counter, LEN_KEY_DESC_REPLAY))
+ {
+ bReplayDiff = TRUE;
+ }
+ }
+
+ // Replay Counter different condition
+ if (bReplayDiff)
+ {
+ // send wireless event - for replay counter different
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_REPLAY_COUNTER_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ if (MsgType < EAPOL_GROUP_MSG_1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Replay Counter Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+ }
+
+ hex_dump("Receive replay counter ", pMsg->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ hex_dump("Current replay counter ", pEntry->R_Counter, LEN_KEY_DESC_REPLAY);
+ return FALSE;
+ }
+
+ // 2. Verify MIC except Pairwise Msg1
+ if (MsgType != EAPOL_PAIR_MSG_1)
+ {
+ UCHAR rcvd_mic[LEN_KEY_DESC_MIC];
+
+ // Record the received MIC for check later
+ NdisMoveMemory(rcvd_mic, pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+ if (pEntry->WepStatus == Ndis802_11Encryption2Enabled) // TKIP
+ {
+ hmac_md5(pEntry->PTK, LEN_EAP_MICK, (PUCHAR)pMsg, MsgLen, mic);
+ }
+ else if (pEntry->WepStatus == Ndis802_11Encryption3Enabled) // AES
+ {
+ HMAC_SHA1((PUCHAR)pMsg, MsgLen, pEntry->PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+ }
+
+ if (!NdisEqualMemory(rcvd_mic, mic, LEN_KEY_DESC_MIC))
+ {
+ // send wireless event - for MIC different
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_MIC_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ if (MsgType < EAPOL_GROUP_MSG_1)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in pairwise msg %d of 4-way handshake!\n", MsgType));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in group msg %d of 2-way handshake!\n", (MsgType - EAPOL_PAIR_MSG_4)));
+ }
+
+ hex_dump("Received MIC", rcvd_mic, LEN_KEY_DESC_MIC);
+ hex_dump("Desired MIC", mic, LEN_KEY_DESC_MIC);
+
+ return FALSE;
+ }
+ }
+
+ // Extract the context of the Key Data field if it exist
+ // The field in pairwise_msg_2_WPA1(WPA2) & pairwise_msg_3_WPA1 is un-encrypted.
+ // The field in group_msg_1_WPA1(WPA2) & pairwise_msg_3_WPA2 is encrypted.
+ if (pMsg->KeyDesc.KeyDataLen[1] > 0)
+ {
+ // Decrypt this field
+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ if(pEntry->WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ AES_GTK_KEY_UNWRAP(&pEntry->PTK[16], KEYDATA, pMsg->KeyDesc.KeyDataLen[1],pMsg->KeyDesc.KeyData);
+ }
+ else
+ {
+ INT i;
+ UCHAR Key[32];
+ // Decrypt TKIP GTK
+ // Construct 32 bytes RC4 Key
+ NdisMoveMemory(Key, pMsg->KeyDesc.KeyIv, 16);
+ NdisMoveMemory(&Key[16], &pEntry->PTK[16], 16);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+ //discard first 256 bytes
+ for(i = 0; i < 256; i++)
+ ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+ // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
+ }
+
+ if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+ GroupKeyIndex = EapolKeyInfo.KeyIndex;
+
+ }
+ else if ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3 && !bWPA2))
+ {
+ NdisMoveMemory(KEYDATA, pMsg->KeyDesc.KeyData, pMsg->KeyDesc.KeyDataLen[1]);
+ }
+ else
+ {
+
+ return TRUE;
+ }
+
+ // Parse Key Data field to
+ // 1. verify RSN IE for pairwise_msg_2_WPA1(WPA2) ,pairwise_msg_3_WPA1(WPA2)
+ // 2. verify KDE format for pairwise_msg_3_WPA2, group_msg_1_WPA2
+ // 3. update shared key for pairwise_msg_3_WPA2, group_msg_1_WPA1(WPA2)
+ if (!RTMPParseEapolKeyData(pAd, KEYDATA, pMsg->KeyDesc.KeyDataLen[1], GroupKeyIndex, MsgType, bWPA2, pEntry))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN MlmeDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PRT_802_11_DLS *pDLS,
+ OUT PUSHORT pReason)
+{
+ MLME_DLS_REQ_STRUCT *pInfo;
+
+ pInfo = (MLME_DLS_REQ_STRUCT *)Msg;
+
+ *pDLS = pInfo->pDLS;
+ *pReason = pInfo->Reason;
+
+ return TRUE;
+}
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN PeerDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pDlsTimeout,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+ PEID_STRUCT eid_ptr;
+
+ // to prevent caller from using garbage output value
+ *pCapabilityInfo = 0;
+ *pDlsTimeout = 0;
+ *pHtCapabilityLen = 0;
+
+ Ptr = Fr->Octet;
+
+ // offset to destination MAC address (Category and Action field)
+ Ptr += 2;
+
+ // get DA from payload and advance the pointer
+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get SA from payload and advance the pointer
+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+ Ptr += 2;
+
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pDlsTimeout, Ptr, 2);
+ Ptr += 2;
+
+ // Category and Action field + DA + SA + capability + Timeout
+ eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
+
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_SUPP_RATES:
+ if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
+ {
+ NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
+ DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
+ *pRatesLen = eid_ptr->Len;
+ }
+ else
+ {
+ *pRatesLen = 8;
+ Rates[0] = 0x82;
+ Rates[1] = 0x84;
+ Rates[2] = 0x8b;
+ Rates[3] = 0x96;
+ Rates[4] = 0x12;
+ Rates[5] = 0x24;
+ Rates[6] = 0x48;
+ Rates[7] = 0x6c;
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
+ }
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
+ *pRatesLen = (*pRatesLen) + eid_ptr->Len;
+ }
+ else
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
+ *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
+ {
+ NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+ *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - IE_HT_CAP\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsReqSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return TRUE;
+}
+
+BOOLEAN PeerDlsRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+ PEID_STRUCT eid_ptr;
+
+ // to prevent caller from using garbage output value
+ *pStatus = 0;
+ *pCapabilityInfo = 0;
+ *pHtCapabilityLen = 0;
+
+ Ptr = Fr->Octet;
+
+ // offset to destination MAC address (Category and Action field)
+ Ptr += 2;
+
+ // get status code from payload and advance the pointer
+ NdisMoveMemory(pStatus, Ptr, 2);
+ Ptr += 2;
+
+ // get DA from payload and advance the pointer
+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get SA from payload and advance the pointer
+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ if (pStatus == 0)
+ {
+ // get capability info from payload and advance the pointer
+ NdisMoveMemory(pCapabilityInfo, Ptr, 2);
+ Ptr += 2;
+ }
+
+ // Category and Action field + status code + DA + SA + capability
+ eid_ptr = (PEID_STRUCT) &Fr->Octet[18];
+
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((UCHAR*)Fr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_SUPP_RATES:
+ if ((eid_ptr->Len <= MAX_LEN_OF_SUPPORTED_RATES) && (eid_ptr->Len > 0))
+ {
+ NdisMoveMemory(Rates, eid_ptr->Octet, eid_ptr->Len);
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_SUPP_RATES., Len=%d. Rates[0]=%x\n",eid_ptr->Len, Rates[0]));
+ DBGPRINT(RT_DEBUG_TRACE, ("Rates[1]=%x %x %x %x %x %x %x\n", Rates[1], Rates[2], Rates[3], Rates[4], Rates[5], Rates[6], Rates[7]));
+ *pRatesLen = eid_ptr->Len;
+ }
+ else
+ {
+ *pRatesLen = 8;
+ Rates[0] = 0x82;
+ Rates[1] = 0x84;
+ Rates[2] = 0x8b;
+ Rates[3] = 0x96;
+ Rates[4] = 0x12;
+ Rates[5] = 0x24;
+ Rates[6] = 0x48;
+ Rates[7] = 0x6c;
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_SUPP_RATES., Len=%d\n",eid_ptr->Len));
+ }
+ break;
+
+ case IE_EXT_SUPP_RATES:
+ if (eid_ptr->Len + *pRatesLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, eid_ptr->Len);
+ *pRatesLen = (*pRatesLen) + eid_ptr->Len;
+ }
+ else
+ {
+ NdisMoveMemory(&Rates[*pRatesLen], eid_ptr->Octet, MAX_LEN_OF_SUPPORTED_RATES - (*pRatesLen));
+ *pRatesLen = MAX_LEN_OF_SUPPORTED_RATES;
+ }
+ break;
+
+ case IE_HT_CAP:
+ if (eid_ptr->Len >= sizeof(HT_CAPABILITY_IE))
+ {
+ NdisMoveMemory(pHtCapability, eid_ptr->Octet, sizeof(HT_CAPABILITY_IE));
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+ *pHtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - IE_HT_CAP\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerDlsRspSanity - wrong IE_HT_CAP.eid_ptr->Len = %d\n", eid_ptr->Len));
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return TRUE;
+}
+
+BOOLEAN PeerDlsTearDownSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pReason)
+{
+ CHAR *Ptr;
+ PFRAME_802_11 Fr = (PFRAME_802_11)Msg;
+
+ // to prevent caller from using garbage output value
+ *pReason = 0;
+
+ Ptr = Fr->Octet;
+
+ // offset to destination MAC address (Category and Action field)
+ Ptr += 2;
+
+ // get DA from payload and advance the pointer
+ NdisMoveMemory(pDA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get SA from payload and advance the pointer
+ NdisMoveMemory(pSA, Ptr, MAC_ADDR_LEN);
+ Ptr += MAC_ADDR_LEN;
+
+ // get reason code from payload and advance the pointer
+ NdisMoveMemory(pReason, Ptr, 2);
+ Ptr += 2;
+
+ return TRUE;
+}
+#endif // QOS_DLS_SUPPORT //
+
diff --git a/drivers/staging/rt3070/common/cmm_sync.c b/drivers/staging/rt3070/common/cmm_sync.c
new file mode 100644
index 00000000000..2be7c77a384
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_sync.c
@@ -0,0 +1,711 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sync.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 modified for rt2561/2661
+*/
+#include "../rt_config.h"
+
+// 2.4 Ghz channel plan index in the TxPower arrays.
+#define BG_BAND_REGION_0_START 0 // 1,2,3,4,5,6,7,8,9,10,11
+#define BG_BAND_REGION_0_SIZE 11
+#define BG_BAND_REGION_1_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13
+#define BG_BAND_REGION_1_SIZE 13
+#define BG_BAND_REGION_2_START 9 // 10,11
+#define BG_BAND_REGION_2_SIZE 2
+#define BG_BAND_REGION_3_START 9 // 10,11,12,13
+#define BG_BAND_REGION_3_SIZE 4
+#define BG_BAND_REGION_4_START 13 // 14
+#define BG_BAND_REGION_4_SIZE 1
+#define BG_BAND_REGION_5_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define BG_BAND_REGION_5_SIZE 14
+#define BG_BAND_REGION_6_START 2 // 3,4,5,6,7,8,9
+#define BG_BAND_REGION_6_SIZE 7
+#define BG_BAND_REGION_7_START 4 // 5,6,7,8,9,10,11,12,13
+#define BG_BAND_REGION_7_SIZE 9
+#define BG_BAND_REGION_31_START 0 // 1,2,3,4,5,6,7,8,9,10,11,12,13,14
+#define BG_BAND_REGION_31_SIZE 14
+
+// 5 Ghz channel plan index in the TxPower arrays.
+UCHAR A_BAND_REGION_0_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_1_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+UCHAR A_BAND_REGION_2_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64};
+UCHAR A_BAND_REGION_3_CHANNEL_LIST[]={52, 56, 60, 64, 149, 153, 157, 161};
+UCHAR A_BAND_REGION_4_CHANNEL_LIST[]={149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_5_CHANNEL_LIST[]={149, 153, 157, 161};
+UCHAR A_BAND_REGION_6_CHANNEL_LIST[]={36, 40, 44, 48};
+UCHAR A_BAND_REGION_7_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_8_CHANNEL_LIST[]={52, 56, 60, 64};
+UCHAR A_BAND_REGION_9_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_10_CHANNEL_LIST[]={36, 40, 44, 48, 149, 153, 157, 161, 165};
+UCHAR A_BAND_REGION_11_CHANNEL_LIST[]={36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161};
+
+//BaSizeArray follows the 802.11n definition as MaxRxFactor. 2^(13+factor) bytes. When factor =0, it's about Ba buffer size =8.
+UCHAR BaSizeArray[4] = {8,16,32,64};
+
+/*
+ ==========================================================================
+ Description:
+ Update StaCfg->ChannelList[] according to 1) Country Region 2) RF IC type,
+ and 3) PHY-mode user selected.
+ The outcome is used by driver when doing site survey.
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID BuildChannelList(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i, j, index=0, num=0;
+ PUCHAR pChannelList = NULL;
+
+ NdisZeroMemory(pAd->ChannelList, MAX_NUM_OF_CHANNELS * sizeof(CHANNEL_TX_POWER));
+
+ // if not 11a-only mode, channel list starts from 2.4Ghz band
+ if ((pAd->CommonCfg.PhyMode != PHY_11A)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->CommonCfg.PhyMode != PHY_11AN_MIXED) && (pAd->CommonCfg.PhyMode != PHY_11N_5G)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ switch (pAd->CommonCfg.CountryRegion & 0x7f)
+ {
+ case REGION_0_BG_BAND: // 1 -11
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_0_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_0_SIZE);
+ index += BG_BAND_REGION_0_SIZE;
+ break;
+ case REGION_1_BG_BAND: // 1 - 13
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_1_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_1_SIZE);
+ index += BG_BAND_REGION_1_SIZE;
+ break;
+ case REGION_2_BG_BAND: // 10 - 11
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_2_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_2_SIZE);
+ index += BG_BAND_REGION_2_SIZE;
+ break;
+ case REGION_3_BG_BAND: // 10 - 13
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_3_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_3_SIZE);
+ index += BG_BAND_REGION_3_SIZE;
+ break;
+ case REGION_4_BG_BAND: // 14
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_4_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_4_SIZE);
+ index += BG_BAND_REGION_4_SIZE;
+ break;
+ case REGION_5_BG_BAND: // 1 - 14
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_5_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_5_SIZE);
+ index += BG_BAND_REGION_5_SIZE;
+ break;
+ case REGION_6_BG_BAND: // 3 - 9
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_6_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_6_SIZE);
+ index += BG_BAND_REGION_6_SIZE;
+ break;
+ case REGION_7_BG_BAND: // 5 - 13
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_7_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_7_SIZE);
+ index += BG_BAND_REGION_7_SIZE;
+ break;
+ case REGION_31_BG_BAND: // 1 - 14
+ NdisMoveMemory(&pAd->ChannelList[index], &pAd->TxPower[BG_BAND_REGION_31_START], sizeof(CHANNEL_TX_POWER) * BG_BAND_REGION_31_SIZE);
+ index += BG_BAND_REGION_31_SIZE;
+ break;
+ default: // Error. should never happen
+ break;
+ }
+ for (i=0; i<index; i++)
+ pAd->ChannelList[i].MaxTxPwr = 20;
+ }
+
+ if ((pAd->CommonCfg.PhyMode == PHY_11A) || (pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
+#ifdef DOT11_N_SUPPORT
+ || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED)
+ || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ switch (pAd->CommonCfg.CountryRegionForABand & 0x7f)
+ {
+ case REGION_0_A_BAND:
+ num = sizeof(A_BAND_REGION_0_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_0_CHANNEL_LIST;
+ break;
+ case REGION_1_A_BAND:
+ num = sizeof(A_BAND_REGION_1_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_1_CHANNEL_LIST;
+ break;
+ case REGION_2_A_BAND:
+ num = sizeof(A_BAND_REGION_2_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_2_CHANNEL_LIST;
+ break;
+ case REGION_3_A_BAND:
+ num = sizeof(A_BAND_REGION_3_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_3_CHANNEL_LIST;
+ break;
+ case REGION_4_A_BAND:
+ num = sizeof(A_BAND_REGION_4_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_4_CHANNEL_LIST;
+ break;
+ case REGION_5_A_BAND:
+ num = sizeof(A_BAND_REGION_5_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_5_CHANNEL_LIST;
+ break;
+ case REGION_6_A_BAND:
+ num = sizeof(A_BAND_REGION_6_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_6_CHANNEL_LIST;
+ break;
+ case REGION_7_A_BAND:
+ num = sizeof(A_BAND_REGION_7_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_7_CHANNEL_LIST;
+ break;
+ case REGION_8_A_BAND:
+ num = sizeof(A_BAND_REGION_8_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_8_CHANNEL_LIST;
+ break;
+ case REGION_9_A_BAND:
+ num = sizeof(A_BAND_REGION_9_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_9_CHANNEL_LIST;
+ break;
+
+ case REGION_10_A_BAND:
+ num = sizeof(A_BAND_REGION_10_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_10_CHANNEL_LIST;
+ break;
+
+ case REGION_11_A_BAND:
+ num = sizeof(A_BAND_REGION_11_CHANNEL_LIST)/sizeof(UCHAR);
+ pChannelList = A_BAND_REGION_11_CHANNEL_LIST;
+ break;
+
+ default: // Error. should never happen
+ DBGPRINT(RT_DEBUG_WARN,("countryregion=%d not support", pAd->CommonCfg.CountryRegionForABand));
+ break;
+ }
+
+ if (num != 0)
+ {
+ UCHAR RadarCh[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+ for (i=0; i<num; i++)
+ {
+ for (j=0; j<MAX_NUM_OF_CHANNELS; j++)
+ {
+ if (pChannelList[i] == pAd->TxPower[j].Channel)
+ NdisMoveMemory(&pAd->ChannelList[index+i], &pAd->TxPower[j], sizeof(CHANNEL_TX_POWER));
+ }
+ for (j=0; j<15; j++)
+ {
+ if (pChannelList[i] == RadarCh[j])
+ pAd->ChannelList[index+i].DfsReq = TRUE;
+ }
+ pAd->ChannelList[index+i].MaxTxPwr = 20;
+ }
+ index += num;
+ }
+ }
+
+ pAd->ChannelListNum = index;
+ DBGPRINT(RT_DEBUG_TRACE,("country code=%d/%d, RFIC=%d, PHY mode=%d, support %d channels\n",
+ pAd->CommonCfg.CountryRegion, pAd->CommonCfg.CountryRegionForABand, pAd->RfIcType, pAd->CommonCfg.PhyMode, pAd->ChannelListNum));
+#ifdef DBG
+ for (i=0;i<pAd->ChannelListNum;i++)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("BuildChannel # %d :: Pwr0 = %d, Pwr1 =%d, \n ", pAd->ChannelList[i].Channel, pAd->ChannelList[i].Power, pAd->ChannelList[i].Power2));
+ }
+#endif
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine return the first channel number according to the country
+ code selection and RF IC selection (signal band or dual band). It is called
+ whenever driver need to start a site survey of all supported channels.
+ Return:
+ ch - the first channel number of current country code setting
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+UCHAR FirstChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ return pAd->ChannelList[0].Channel;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine returns the next channel number. This routine is called
+ during driver need to start a site survey of all supported channels.
+ Return:
+ next_channel - the next channel number valid in current country code setting.
+ Note:
+ return 0 if no more next channel
+ ==========================================================================
+ */
+UCHAR NextChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel)
+{
+ int i;
+ UCHAR next_channel = 0;
+
+ for (i = 0; i < (pAd->ChannelListNum - 1); i++)
+ if (channel == pAd->ChannelList[i].Channel)
+ {
+ next_channel = pAd->ChannelList[i+1].Channel;
+ break;
+ }
+ return next_channel;
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is for Cisco Compatible Extensions 2.X
+ Spec31. AP Control of Client Transmit Power
+ Return:
+ None
+ Note:
+ Required by Aironet dBm(mW)
+ 0dBm(1mW), 1dBm(5mW), 13dBm(20mW), 15dBm(30mW),
+ 17dBm(50mw), 20dBm(100mW)
+
+ We supported
+ 3dBm(Lowest), 6dBm(10%), 9dBm(25%), 12dBm(50%),
+ 14dBm(75%), 15dBm(100%)
+
+ The client station's actual transmit power shall be within +/- 5dB of
+ the minimum value or next lower value.
+ ==========================================================================
+ */
+VOID ChangeToCellPowerLimit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AironetCellPowerLimit)
+{
+ //valud 0xFF means that hasn't found power limit information
+ //from the AP's Beacon/Probe response.
+ if (AironetCellPowerLimit == 0xFF)
+ return;
+
+ if (AironetCellPowerLimit < 6) //Used Lowest Power Percentage.
+ pAd->CommonCfg.TxPowerPercentage = 6;
+ else if (AironetCellPowerLimit < 9)
+ pAd->CommonCfg.TxPowerPercentage = 10;
+ else if (AironetCellPowerLimit < 12)
+ pAd->CommonCfg.TxPowerPercentage = 25;
+ else if (AironetCellPowerLimit < 14)
+ pAd->CommonCfg.TxPowerPercentage = 50;
+ else if (AironetCellPowerLimit < 15)
+ pAd->CommonCfg.TxPowerPercentage = 75;
+ else
+ pAd->CommonCfg.TxPowerPercentage = 100; //else used maximum
+
+ if (pAd->CommonCfg.TxPowerPercentage > pAd->CommonCfg.TxPowerDefault)
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+
+}
+
+CHAR ConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber)
+{
+ UCHAR RssiOffset, LNAGain;
+
+ // Rssi equals to zero should be an invalid value
+ if (Rssi == 0)
+ return -99;
+
+ LNAGain = GET_LNA_GAIN(pAd);
+ if (pAd->LatchRfRegs.Channel > 14)
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->ARssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->ARssiOffset1;
+ else
+ RssiOffset = pAd->ARssiOffset2;
+ }
+ else
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->BGRssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->BGRssiOffset1;
+ else
+ RssiOffset = pAd->BGRssiOffset2;
+ }
+
+ return (-12 - RssiOffset - LNAGain - Rssi);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan next channel
+ ==========================================================================
+ */
+VOID ScanNextChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ HEADER_802_11 Hdr80211;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ UCHAR SsidLen = 0, ScanType = pAd->MlmeAux.ScanType, BBPValue = 0;
+#ifdef CONFIG_STA_SUPPORT
+ USHORT Status;
+ PHEADER_802_11 pHdr80211;
+#endif // CONFIG_STA_SUPPORT //
+ UINT ScanTimeIn5gChannel = SHORT_CHANNEL_TIME;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (MONITOR_ON(pAd))
+ return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+ // Nothing to do in ATE mode.
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (pAd->MlmeAux.Channel == 0)
+ {
+ if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
+#ifdef CONFIG_STA_SUPPORT
+ && (INFRA_ON(pAd)
+ || (pAd->OpMode == OPMODE_AP))
+#endif // CONFIG_STA_SUPPORT //
+ )
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ BBPValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
+ }
+ else
+ {
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to channel %d, Total BSS[%02d]\n",pAd->CommonCfg.Channel, pAd->ScanTab.BssNr));
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //
+ // To prevent data lost.
+ // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
+ // Now, we need to send an NULL data with turned PSM bit off to AP, when scan progress done
+ //
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
+ {
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ pHdr80211 = (PHEADER_802_11) pOutBuffer;
+ MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pHdr80211->Duration = 0;
+ pHdr80211->FC.Type = BTYPE_DATA;
+ pHdr80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame\n"));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ RTMPusecDelay(5000);
+ }
+ }
+
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ }
+#ifdef RT2870
+#ifdef CONFIG_STA_SUPPORT
+ else if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) && (pAd->OpMode == OPMODE_STA))
+ {
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ MlmeCntlConfirm(pAd, MT2_SCAN_CONF, MLME_FAIL_NO_RESOURCE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+ else
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // BBP and RF are not accessible in PS mode, we has to wake them up first
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ AsicForceWakeup(pAd, TRUE);
+
+ // leave PSM during scanning. otherwise we may lost ProbeRsp & BEACON
+ if (pAd->StaCfg.Psm == PWR_SAVE)
+ MlmeSetPsmBit(pAd, PWR_ACTIVE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, TRUE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->MlmeAux.Channel > 14)
+ {
+ if ((pAd->CommonCfg.bIEEE80211H == 1) && RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
+ {
+ ScanType = SCAN_PASSIVE;
+ ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
+ }
+ }
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ // carrier detection
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ ScanType = SCAN_PASSIVE;
+ ScanTimeIn5gChannel = MIN_CHANNEL_TIME;
+ }
+#endif // CARRIER_DETECTION_SUPPORT //
+ }
+
+#endif // CONFIG_STA_SUPPORT //
+
+ //Global country domain(ch1-11:active scan, ch12-14 passive scan)
+ if ((pAd->MlmeAux.Channel <= 14) && (pAd->MlmeAux.Channel >= 12) && ((pAd->CommonCfg.CountryRegion & 0x7f) == REGION_31_BG_BAND))
+ {
+ ScanType = SCAN_PASSIVE;
+ }
+
+ // We need to shorten active scan time in order for WZC connect issue
+ // Chnage the channel scan time for CISCO stuff based on its IAPP announcement
+ if (ScanType == FAST_SCAN_ACTIVE)
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, FAST_ACTIVE_SCAN_TIME);
+#ifdef CONFIG_STA_SUPPORT
+ else if (((ScanType == SCAN_CISCO_ACTIVE) ||
+ (ScanType == SCAN_CISCO_PASSIVE) ||
+ (ScanType == SCAN_CISCO_CHANNEL_LOAD) ||
+ (ScanType == SCAN_CISCO_NOISE)) && (pAd->OpMode == OPMODE_STA))
+ {
+ if (pAd->StaCfg.CCXScanTime < 25)
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime * 2);
+ else
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, pAd->StaCfg.CCXScanTime);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ else // must be SCAN_PASSIVE or SCAN_ACTIVE
+ {
+ if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED)
+#ifdef DOT11_N_SUPPORT
+ || (pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) || (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ if (pAd->MlmeAux.Channel > 14)
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, ScanTimeIn5gChannel);
+ else
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MIN_CHANNEL_TIME);
+ }
+ else
+ RTMPSetTimer(&pAd->MlmeAux.ScanTimer, MAX_CHANNEL_TIME);
+ }
+
+ if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE) ||
+ (ScanType == SCAN_CISCO_ACTIVE))
+ {
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - ScanNextChannel() allocate memory fail\n"));
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return;
+ }
+
+ // There is no need to send broadcast probe request if active scan is in effect.
+ if ((ScanType == SCAN_ACTIVE) || (ScanType == FAST_SCAN_ACTIVE)
+ )
+ SsidLen = pAd->MlmeAux.SsidLen;
+ else
+ SsidLen = 0;
+
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr80211,
+ 1, &SsidIe,
+ 1, &SsidLen,
+ SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->CommonCfg.SupRateLen,
+ pAd->CommonCfg.SupRateLen, pAd->CommonCfg.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->CommonCfg.ExtRateLen)
+ {
+ ULONG Tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->CommonCfg.ExtRateLen,
+ pAd->CommonCfg.ExtRateLen, pAd->CommonCfg.ExtRate,
+ END_OF_ARGS);
+ FrameLen += Tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ ULONG Tmp;
+ UCHAR HtLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+ if (pAd->bBroadComHT == TRUE)
+ {
+ HtLen = pAd->MlmeAux.HtCapabilityLen + 4;
+#ifdef RT_BIG_ENDIAN
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+#endif // RT_BIG_ENDIAN //
+ }
+ else
+ {
+ HtLen = pAd->MlmeAux.HtCapabilityLen;
+#ifdef RT_BIG_ENDIAN
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, SIZE_HT_CAP_IE);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#else
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ END_OF_ARGS);
+#endif // RT_BIG_ENDIAN //
+ }
+ FrameLen += Tmp;
+
+#ifdef DOT11N_DRAFT3
+ if (pAd->CommonCfg.BACapability.field.b2040CoexistScanSup == 1)
+ {
+ ULONG Tmp;
+ HtLen = 1;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &ExtHtCapIe,
+ 1, &HtLen,
+ 1, &pAd->CommonCfg.BSSCoexist2040.word,
+ END_OF_ARGS);
+
+ FrameLen += Tmp;
+ }
+#endif // DOT11N_DRAFT3 //
+ }
+#endif // DOT11_N_SUPPORT //
+
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+ // For SCAN_CISCO_PASSIVE, do nothing and silently wait for beacon or other probe reponse
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->Mlme.SyncMachine.CurrState = SCAN_LISTEN;
+#endif // CONFIG_STA_SUPPORT //
+
+ }
+}
+
+VOID MgtProbReqMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SubType;
+ if (SubType == SUBTYPE_ACK)
+ pHdr80211->FC.Type = BTYPE_CNTL;
+ pHdr80211->FC.ToDs = ToDs;
+ COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
+}
+
+
diff --git a/drivers/staging/rt3070/common/cmm_wpa.c b/drivers/staging/rt3070/common/cmm_wpa.c
new file mode 100644
index 00000000000..81c332ac252
--- /dev/null
+++ b/drivers/staging/rt3070/common/cmm_wpa.c
@@ -0,0 +1,1606 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ wpa.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 03-07-22 Initial
+ Paul Lin 03-11-28 Modify for supplicant
+*/
+#include "../rt_config.h"
+// WPA OUI
+UCHAR OUI_WPA_NONE_AKM[4] = {0x00, 0x50, 0xF2, 0x00};
+UCHAR OUI_WPA_VERSION[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_TKIP[4] = {0x00, 0x50, 0xF2, 0x02};
+UCHAR OUI_WPA_CCMP[4] = {0x00, 0x50, 0xF2, 0x04};
+UCHAR OUI_WPA_8021X_AKM[4] = {0x00, 0x50, 0xF2, 0x01};
+UCHAR OUI_WPA_PSK_AKM[4] = {0x00, 0x50, 0xF2, 0x02};
+// WPA2 OUI
+UCHAR OUI_WPA2_WEP40[4] = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR OUI_WPA2_TKIP[4] = {0x00, 0x0F, 0xAC, 0x02};
+UCHAR OUI_WPA2_CCMP[4] = {0x00, 0x0F, 0xAC, 0x04};
+UCHAR OUI_WPA2_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x01};
+UCHAR OUI_WPA2_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x02};
+// MSA OUI
+UCHAR OUI_MSA_8021X_AKM[4] = {0x00, 0x0F, 0xAC, 0x05}; // Not yet final - IEEE 802.11s-D1.06
+UCHAR OUI_MSA_PSK_AKM[4] = {0x00, 0x0F, 0xAC, 0x06}; // Not yet final - IEEE 802.11s-D1.06
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The pseudo-random function(PRF) that hashes various inputs to
+ derive a pseudo-random value. To add liveness to the pseudo-random
+ value, a nonce should be one of the inputs.
+
+ It is used to generate PTK, GTK or some specific random value.
+
+ Arguments:
+ UCHAR *key, - the key material for HMAC_SHA1 use
+ INT key_len - the length of key
+ UCHAR *prefix - a prefix label
+ INT prefix_len - the length of the label
+ UCHAR *data - a specific data with variable length
+ INT data_len - the length of a specific data
+ INT len - the output lenght
+
+ Return Value:
+ UCHAR *output - the calculated result
+
+ Note:
+ 802.11i-2004 Annex H.3
+
+ ========================================================================
+*/
+VOID PRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *prefix,
+ IN INT prefix_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len)
+{
+ INT i;
+ UCHAR *input;
+ INT currentindex = 0;
+ INT total_len;
+
+ // Allocate memory for input
+ os_alloc_mem(NULL, (PUCHAR *)&input, 1024);
+
+ if (input == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!PRF: no memory!!!\n"));
+ return;
+ }
+
+ // Generate concatenation input
+ NdisMoveMemory(input, prefix, prefix_len);
+
+ // Concatenate a single octet containing 0
+ input[prefix_len] = 0;
+
+ // Concatenate specific data
+ NdisMoveMemory(&input[prefix_len + 1], data, data_len);
+ total_len = prefix_len + 1 + data_len;
+
+ // Concatenate a single octet containing 0
+ // This octet shall be update later
+ input[total_len] = 0;
+ total_len++;
+
+ // Iterate to calculate the result by hmac-sha-1
+ // Then concatenate to last result
+ for (i = 0; i < (len + 19) / 20; i++)
+ {
+ HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
+ currentindex += 20;
+
+ // update the last octet
+ input[total_len - 1]++;
+ }
+ os_free_mem(NULL, input);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ It utilizes PRF-384 or PRF-512 to derive session-specific keys from a PMK.
+ It shall be called by 4-way handshake processing.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ PMK - pointer to PMK
+ ANonce - pointer to ANonce
+ AA - pointer to Authenticator Address
+ SNonce - pointer to SNonce
+ SA - pointer to Supplicant Address
+ len - indicate the length of PTK (octet)
+
+ Return Value:
+ Output pointer to the PTK
+
+ Note:
+ Refer to IEEE 802.11i-2004 8.5.1.2
+
+ ========================================================================
+*/
+VOID WpaCountPTK(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *PMK,
+ IN UCHAR *ANonce,
+ IN UCHAR *AA,
+ IN UCHAR *SNonce,
+ IN UCHAR *SA,
+ OUT UCHAR *output,
+ IN UINT len)
+{
+ UCHAR concatenation[76];
+ UINT CurrPos = 0;
+ UCHAR temp[32];
+ UCHAR Prefix[] = {'P', 'a', 'i', 'r', 'w', 'i', 's', 'e', ' ', 'k', 'e', 'y', ' ',
+ 'e', 'x', 'p', 'a', 'n', 's', 'i', 'o', 'n'};
+
+ // initiate the concatenation input
+ NdisZeroMemory(temp, sizeof(temp));
+ NdisZeroMemory(concatenation, 76);
+
+ // Get smaller address
+ if (RTMPCompareMemory(SA, AA, 6) == 1)
+ NdisMoveMemory(concatenation, AA, 6);
+ else
+ NdisMoveMemory(concatenation, SA, 6);
+ CurrPos += 6;
+
+ // Get larger address
+ if (RTMPCompareMemory(SA, AA, 6) == 1)
+ NdisMoveMemory(&concatenation[CurrPos], SA, 6);
+ else
+ NdisMoveMemory(&concatenation[CurrPos], AA, 6);
+
+ // store the larger mac address for backward compatible of
+ // ralink proprietary STA-key issue
+ NdisMoveMemory(temp, &concatenation[CurrPos], MAC_ADDR_LEN);
+ CurrPos += 6;
+
+ // Get smaller Nonce
+ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
+ NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
+ else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
+ NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
+ else
+ NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
+ CurrPos += 32;
+
+ // Get larger Nonce
+ if (RTMPCompareMemory(ANonce, SNonce, 32) == 0)
+ NdisMoveMemory(&concatenation[CurrPos], temp, 32); // patch for ralink proprietary STA-key issue
+ else if (RTMPCompareMemory(ANonce, SNonce, 32) == 1)
+ NdisMoveMemory(&concatenation[CurrPos], ANonce, 32);
+ else
+ NdisMoveMemory(&concatenation[CurrPos], SNonce, 32);
+ CurrPos += 32;
+
+ hex_dump("concatenation=", concatenation, 76);
+
+ // Use PRF to generate PTK
+ PRF(PMK, LEN_MASTER_KEY, Prefix, 22, concatenation, 76, output, len);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Generate random number by software.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ macAddr - pointer to local MAC address
+
+ Return Value:
+
+ Note:
+ 802.1ii-2004 Annex H.5
+
+ ========================================================================
+*/
+VOID GenRandom(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *macAddr,
+ OUT UCHAR *random)
+{
+ INT i, curr;
+ UCHAR local[80], KeyCounter[32];
+ UCHAR result[80];
+ ULONG CurrentTime;
+ UCHAR prefix[] = {'I', 'n', 'i', 't', ' ', 'C', 'o', 'u', 'n', 't', 'e', 'r'};
+
+ // Zero the related information
+ NdisZeroMemory(result, 80);
+ NdisZeroMemory(local, 80);
+ NdisZeroMemory(KeyCounter, 32);
+
+ for (i = 0; i < 32; i++)
+ {
+ // copy the local MAC address
+ COPY_MAC_ADDR(local, macAddr);
+ curr = MAC_ADDR_LEN;
+
+ // concatenate the current time
+ NdisGetSystemUpTime(&CurrentTime);
+ NdisMoveMemory(&local[curr], &CurrentTime, sizeof(CurrentTime));
+ curr += sizeof(CurrentTime);
+
+ // concatenate the last result
+ NdisMoveMemory(&local[curr], result, 32);
+ curr += 32;
+
+ // concatenate a variable
+ NdisMoveMemory(&local[curr], &i, 2);
+ curr += 2;
+
+ // calculate the result
+ PRF(KeyCounter, 32, prefix,12, local, curr, result, 32);
+ }
+
+ NdisMoveMemory(random, result, 32);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build cipher suite in RSN-IE.
+ It only shall be called by RTMPMakeRSNIE.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ ElementID - indicate the WPA1 or WPA2
+ WepStatus - indicate the encryption type
+ bMixCipher - a boolean to indicate the pairwise cipher and group
+ cipher are the same or not
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+static VOID RTMPInsertRsnIeCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ElementID,
+ IN UINT WepStatus,
+ IN BOOLEAN bMixCipher,
+ IN UCHAR FlexibleCipher,
+ OUT PUCHAR pRsnIe,
+ OUT UCHAR *rsn_len)
+{
+ UCHAR PairwiseCnt;
+
+ *rsn_len = 0;
+
+ // decide WPA2 or WPA1
+ if (ElementID == Wpa2Ie)
+ {
+ RSNIE2 *pRsnie_cipher = (RSNIE2*)pRsnIe;
+
+ // Assign the verson as 1
+ pRsnie_cipher->version = 1;
+
+ switch (WepStatus)
+ {
+ // TKIP mode
+ case Ndis802_11Encryption2Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
+ *rsn_len = sizeof(RSNIE2);
+ break;
+
+ // AES mode
+ case Ndis802_11Encryption3Enabled:
+ if (bMixCipher)
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+ else
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_CCMP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
+ *rsn_len = sizeof(RSNIE2);
+ break;
+
+ // TKIP-AES mix mode
+ case Ndis802_11Encryption4Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA2_TKIP, 4);
+
+ PairwiseCnt = 1;
+ // Insert WPA2 TKIP as the first pairwise cipher
+ if (MIX_CIPHER_WPA2_TKIP_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_TKIP, 4);
+ // Insert WPA2 AES as the secondary pairwise cipher
+ if (MIX_CIPHER_WPA2_AES_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA2_CCMP, 4);
+ PairwiseCnt = 2;
+ }
+ }
+ else
+ {
+ // Insert WPA2 AES as the first pairwise cipher
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA2_CCMP, 4);
+ }
+
+ pRsnie_cipher->ucount = PairwiseCnt;
+ *rsn_len = sizeof(RSNIE2) + (4 * (PairwiseCnt - 1));
+ break;
+ }
+
+ // swap for big-endian platform
+ pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
+ pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+ }
+ else
+ {
+ RSNIE *pRsnie_cipher = (RSNIE*)pRsnIe;
+
+ // Assign OUI and version
+ NdisMoveMemory(pRsnie_cipher->oui, OUI_WPA_VERSION, 4);
+ pRsnie_cipher->version = 1;
+
+ switch (WepStatus)
+ {
+ // TKIP mode
+ case Ndis802_11Encryption2Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
+ *rsn_len = sizeof(RSNIE);
+ break;
+
+ // AES mode
+ case Ndis802_11Encryption3Enabled:
+ if (bMixCipher)
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+ else
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_CCMP, 4);
+ pRsnie_cipher->ucount = 1;
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
+ *rsn_len = sizeof(RSNIE);
+ break;
+
+ // TKIP-AES mix mode
+ case Ndis802_11Encryption4Enabled:
+ NdisMoveMemory(pRsnie_cipher->mcast, OUI_WPA_TKIP, 4);
+
+ PairwiseCnt = 1;
+ // Insert WPA TKIP as the first pairwise cipher
+ if (MIX_CIPHER_WPA_TKIP_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_TKIP, 4);
+ // Insert WPA AES as the secondary pairwise cipher
+ if (MIX_CIPHER_WPA_AES_ON(FlexibleCipher))
+ {
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui + 4, OUI_WPA_CCMP, 4);
+ PairwiseCnt = 2;
+ }
+ }
+ else
+ {
+ // Insert WPA AES as the first pairwise cipher
+ NdisMoveMemory(pRsnie_cipher->ucast[0].oui, OUI_WPA_CCMP, 4);
+ }
+
+ pRsnie_cipher->ucount = PairwiseCnt;
+ *rsn_len = sizeof(RSNIE) + (4 * (PairwiseCnt - 1));
+ break;
+ }
+
+ // swap for big-endian platform
+ pRsnie_cipher->version = cpu2le16(pRsnie_cipher->version);
+ pRsnie_cipher->ucount = cpu2le16(pRsnie_cipher->ucount);
+ }
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build AKM suite in RSN-IE.
+ It only shall be called by RTMPMakeRSNIE.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ ElementID - indicate the WPA1 or WPA2
+ AuthMode - indicate the authentication mode
+ apidx - indicate the interface index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+static VOID RTMPInsertRsnIeAKM(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ElementID,
+ IN UINT AuthMode,
+ IN UCHAR apidx,
+ OUT PUCHAR pRsnIe,
+ OUT UCHAR *rsn_len)
+{
+ RSNIE_AUTH *pRsnie_auth;
+
+ pRsnie_auth = (RSNIE_AUTH*)(pRsnIe + (*rsn_len));
+
+ // decide WPA2 or WPA1
+ if (ElementID == Wpa2Ie)
+ {
+ switch (AuthMode)
+ {
+ case Ndis802_11AuthModeWPA2:
+ case Ndis802_11AuthModeWPA1WPA2:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_8021X_AKM, 4);
+ break;
+
+ case Ndis802_11AuthModeWPA2PSK:
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA2_PSK_AKM, 4);
+ break;
+ }
+ }
+ else
+ {
+ switch (AuthMode)
+ {
+ case Ndis802_11AuthModeWPA:
+ case Ndis802_11AuthModeWPA1WPA2:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_8021X_AKM, 4);
+ break;
+
+ case Ndis802_11AuthModeWPAPSK:
+ case Ndis802_11AuthModeWPA1PSKWPA2PSK:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_PSK_AKM, 4);
+ break;
+
+ case Ndis802_11AuthModeWPANone:
+ pRsnie_auth->acount = 1;
+ NdisMoveMemory(pRsnie_auth->auth[0].oui, OUI_WPA_NONE_AKM, 4);
+ break;
+ }
+ }
+
+ pRsnie_auth->acount = cpu2le16(pRsnie_auth->acount);
+
+ (*rsn_len) += sizeof(RSNIE_AUTH); // update current RSNIE length
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build capability in RSN-IE.
+ It only shall be called by RTMPMakeRSNIE.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ ElementID - indicate the WPA1 or WPA2
+ apidx - indicate the interface index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+static VOID RTMPInsertRsnIeCap(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR ElementID,
+ IN UCHAR apidx,
+ OUT PUCHAR pRsnIe,
+ OUT UCHAR *rsn_len)
+{
+ RSN_CAPABILITIES *pRSN_Cap;
+
+ // it could be ignored in WPA1 mode
+ if (ElementID == WpaIe)
+ return;
+
+ pRSN_Cap = (RSN_CAPABILITIES*)(pRsnIe + (*rsn_len));
+
+
+ pRSN_Cap->word = cpu2le16(pRSN_Cap->word);
+
+ (*rsn_len) += sizeof(RSN_CAPABILITIES); // update current RSNIE length
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Build RSN IE context. It is not included element-ID and length.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ AuthMode - indicate the authentication mode
+ WepStatus - indicate the encryption type
+ apidx - indicate the interface index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPMakeRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT AuthMode,
+ IN UINT WepStatus,
+ IN UCHAR apidx)
+{
+ PUCHAR pRsnIe = NULL; // primary RSNIE
+ UCHAR *rsnielen_cur_p = 0; // the length of the primary RSNIE
+ UCHAR *rsnielen_ex_cur_p = 0; // the length of the secondary RSNIE
+ UCHAR PrimaryRsnie;
+ BOOLEAN bMixCipher = FALSE; // indicate the pairwise and group cipher are different
+ UCHAR p_offset;
+ WPA_MIX_PAIR_CIPHER FlexibleCipher = MIX_CIPHER_NOTUSE; // it provide the more flexible cipher combination in WPA-WPA2 and TKIPAES mode
+
+ rsnielen_cur_p = NULL;
+ rsnielen_ex_cur_p = NULL;
+
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ if (AuthMode < Ndis802_11AuthModeWPA)
+ return;
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // Support WPAPSK or WPA2PSK in STA-Infra mode
+ // Support WPANone in STA-Adhoc mode
+ if ((AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (AuthMode != Ndis802_11AuthModeWPANone)
+ )
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("==> RTMPMakeRSNIE(STA)\n"));
+
+ // Zero RSNIE context
+ pAd->StaCfg.RSNIE_Len = 0;
+ NdisZeroMemory(pAd->StaCfg.RSN_IE, MAX_LEN_OF_RSNIE);
+
+ // Pointer to RSNIE
+ rsnielen_cur_p = &pAd->StaCfg.RSNIE_Len;
+ pRsnIe = pAd->StaCfg.RSN_IE;
+
+ bMixCipher = pAd->StaCfg.bMixCipher;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // indicate primary RSNIE as WPA or WPA2
+ if ((AuthMode == Ndis802_11AuthModeWPA) ||
+ (AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (AuthMode == Ndis802_11AuthModeWPANone) ||
+ (AuthMode == Ndis802_11AuthModeWPA1WPA2) ||
+ (AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK))
+ PrimaryRsnie = WpaIe;
+ else
+ PrimaryRsnie = Wpa2Ie;
+
+ {
+ // Build the primary RSNIE
+ // 1. insert cipher suite
+ RTMPInsertRsnIeCipher(pAd, PrimaryRsnie, WepStatus, bMixCipher, FlexibleCipher, pRsnIe, &p_offset);
+
+ // 2. insert AKM
+ RTMPInsertRsnIeAKM(pAd, PrimaryRsnie, AuthMode, apidx, pRsnIe, &p_offset);
+
+ // 3. insert capability
+ RTMPInsertRsnIeCap(pAd, PrimaryRsnie, apidx, pRsnIe, &p_offset);
+ }
+
+ // 4. update the RSNIE length
+ *rsnielen_cur_p = p_offset;
+
+ hex_dump("The primary RSNIE", pRsnIe, (*rsnielen_cur_p));
+
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ Check whether the received frame is EAP frame.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ pEntry - pointer to active entry
+ pData - the received frame
+ DataByteCount - the received frame's length
+ FromWhichBSSID - indicate the interface index
+
+ Return:
+ TRUE - This frame is EAP frame
+ FALSE - otherwise
+ ==========================================================================
+*/
+BOOLEAN RTMPCheckWPAframe(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR pData,
+ IN ULONG DataByteCount,
+ IN UCHAR FromWhichBSSID)
+{
+ ULONG Body_len;
+ BOOLEAN Cancelled;
+
+
+ if(DataByteCount < (LENGTH_802_1_H + LENGTH_EAPOL_H))
+ return FALSE;
+
+
+ // Skip LLC header
+ if (NdisEqualMemory(SNAP_802_1H, pData, 6) ||
+ // Cisco 1200 AP may send packet with SNAP_BRIDGE_TUNNEL
+ NdisEqualMemory(SNAP_BRIDGE_TUNNEL, pData, 6))
+ {
+ pData += 6;
+ }
+ // Skip 2-bytes EAPoL type
+ if (NdisEqualMemory(EAPOL, pData, 2))
+ {
+ pData += 2;
+ }
+ else
+ return FALSE;
+
+ switch (*(pData+1))
+ {
+ case EAPPacket:
+ Body_len = (*(pData+2)<<8) | (*(pData+3));
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP-Packet frame, TYPE = 0, Length = %ld\n", Body_len));
+ break;
+ case EAPOLStart:
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Start frame, TYPE = 1 \n"));
+ if (pEntry->EnqueueEapolStartTimerRunning != EAPOL_START_DISABLE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Cancel the EnqueueEapolStartTimerRunning \n"));
+ RTMPCancelTimer(&pEntry->EnqueueStartForPSKTimer, &Cancelled);
+ pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_DISABLE;
+ }
+ break;
+ case EAPOLLogoff:
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLLogoff frame, TYPE = 2 \n"));
+ break;
+ case EAPOLKey:
+ Body_len = (*(pData+2)<<8) | (*(pData+3));
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL-Key frame, TYPE = 3, Length = %ld\n", Body_len));
+ break;
+ case EAPOLASFAlert:
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOLASFAlert frame, TYPE = 4 \n"));
+ break;
+ default:
+ return FALSE;
+
+ }
+ return TRUE;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ ENCRYPT AES GTK before sending in EAPOL frame.
+ AES GTK length = 128 bit, so fix blocks for aes-key-wrap as 2 in this function.
+ This function references to RFC 3394 for aes key wrap algorithm.
+ Return:
+ ==========================================================================
+*/
+VOID AES_GTK_KEY_WRAP(
+ IN UCHAR *key,
+ IN UCHAR *plaintext,
+ IN UCHAR p_len,
+ OUT UCHAR *ciphertext)
+{
+ UCHAR A[8], BIN[16], BOUT[16];
+ UCHAR R[512];
+ INT num_blocks = p_len/8; // unit:64bits
+ INT i, j;
+ aes_context aesctx;
+ UCHAR xor;
+
+ rtmp_aes_set_key(&aesctx, key, 128);
+
+ // Init IA
+ for (i = 0; i < 8; i++)
+ A[i] = 0xa6;
+
+ //Input plaintext
+ for (i = 0; i < num_blocks; i++)
+ {
+ for (j = 0 ; j < 8; j++)
+ R[8 * (i + 1) + j] = plaintext[8 * i + j];
+ }
+
+ // Key Mix
+ for (j = 0; j < 6; j++)
+ {
+ for(i = 1; i <= num_blocks; i++)
+ {
+ //phase 1
+ NdisMoveMemory(BIN, A, 8);
+ NdisMoveMemory(&BIN[8], &R[8 * i], 8);
+ rtmp_aes_encrypt(&aesctx, BIN, BOUT);
+
+ NdisMoveMemory(A, &BOUT[0], 8);
+ xor = num_blocks * j + i;
+ A[7] = BOUT[7] ^ xor;
+ NdisMoveMemory(&R[8 * i], &BOUT[8], 8);
+ }
+ }
+
+ // Output ciphertext
+ NdisMoveMemory(ciphertext, A, 8);
+
+ for (i = 1; i <= num_blocks; i++)
+ {
+ for (j = 0 ; j < 8; j++)
+ ciphertext[8 * i + j] = R[8 * i + j];
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Misc function to decrypt AES body
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ This function references to RFC 3394 for aes key unwrap algorithm.
+
+ ========================================================================
+*/
+VOID AES_GTK_KEY_UNWRAP(
+ IN UCHAR *key,
+ OUT UCHAR *plaintext,
+ IN UCHAR c_len,
+ IN UCHAR *ciphertext)
+
+{
+ UCHAR A[8], BIN[16], BOUT[16];
+ UCHAR xor;
+ INT i, j;
+ aes_context aesctx;
+ UCHAR *R;
+ INT num_blocks = c_len/8; // unit:64bits
+
+
+ os_alloc_mem(NULL, (PUCHAR *)&R, 512);
+
+ if (R == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!AES_GTK_KEY_UNWRAP: no memory!!!\n"));
+ return;
+ } /* End of if */
+
+ // Initialize
+ NdisMoveMemory(A, ciphertext, 8);
+ //Input plaintext
+ for(i = 0; i < (c_len-8); i++)
+ {
+ R[ i] = ciphertext[i + 8];
+ }
+
+ rtmp_aes_set_key(&aesctx, key, 128);
+
+ for(j = 5; j >= 0; j--)
+ {
+ for(i = (num_blocks-1); i > 0; i--)
+ {
+ xor = (num_blocks -1 )* j + i;
+ NdisMoveMemory(BIN, A, 8);
+ BIN[7] = A[7] ^ xor;
+ NdisMoveMemory(&BIN[8], &R[(i-1)*8], 8);
+ rtmp_aes_decrypt(&aesctx, BIN, BOUT);
+ NdisMoveMemory(A, &BOUT[0], 8);
+ NdisMoveMemory(&R[(i-1)*8], &BOUT[8], 8);
+ }
+ }
+
+ // OUTPUT
+ for(i = 0; i < c_len; i++)
+ {
+ plaintext[i] = R[i];
+ }
+
+
+ os_free_mem(NULL, R);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Report the EAP message type
+
+ Arguments:
+ msg - EAPOL_PAIR_MSG_1
+ EAPOL_PAIR_MSG_2
+ EAPOL_PAIR_MSG_3
+ EAPOL_PAIR_MSG_4
+ EAPOL_GROUP_MSG_1
+ EAPOL_GROUP_MSG_2
+
+ Return:
+ message type string
+
+ ==========================================================================
+*/
+CHAR *GetEapolMsgType(CHAR msg)
+{
+ if(msg == EAPOL_PAIR_MSG_1)
+ return "Pairwise Message 1";
+ else if(msg == EAPOL_PAIR_MSG_2)
+ return "Pairwise Message 2";
+ else if(msg == EAPOL_PAIR_MSG_3)
+ return "Pairwise Message 3";
+ else if(msg == EAPOL_PAIR_MSG_4)
+ return "Pairwise Message 4";
+ else if(msg == EAPOL_GROUP_MSG_1)
+ return "Group Message 1";
+ else if(msg == EAPOL_GROUP_MSG_2)
+ return "Group Message 2";
+ else
+ return "Invalid Message";
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check Sanity RSN IE of EAPoL message
+
+ Arguments:
+
+ Return Value:
+
+
+ ========================================================================
+*/
+BOOLEAN RTMPCheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ IN MAC_TABLE_ENTRY *pEntry,
+ OUT UCHAR *Offset)
+{
+ PUCHAR pVIE;
+ UCHAR len;
+ PEID_STRUCT pEid;
+ BOOLEAN result = FALSE;
+
+ pVIE = pData;
+ len = DataLen;
+ *Offset = 0;
+
+ while (len > sizeof(RSNIE2))
+ {
+ pEid = (PEID_STRUCT) pVIE;
+ // WPA RSN IE
+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
+ {
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA || pEntry->AuthMode == Ndis802_11AuthModeWPAPSK) &&
+ (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
+ (pEntry->RSNIE_Len == (pEid->Len + 2)))
+ {
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ // WPA2 RSN IE
+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
+ {
+ if ((pEntry->AuthMode == Ndis802_11AuthModeWPA2 || pEntry->AuthMode == Ndis802_11AuthModeWPA2PSK) &&
+ (NdisEqualMemory(pVIE, pEntry->RSN_IE, pEntry->RSNIE_Len)) &&
+ (pEntry->RSNIE_Len == (pEid->Len + 2))/* ToDo-AlbertY for mesh*/)
+ {
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ else
+ {
+ break;
+ }
+
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+ }
+
+
+ return result;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
+ GTK is encaptulated in KDE format at p.83 802.11i D10
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ 802.11i D10
+
+ ========================================================================
+*/
+BOOLEAN RTMPParseEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR GroupKeyIndex,
+ IN UCHAR MsgType,
+ IN BOOLEAN bWPA2,
+ IN MAC_TABLE_ENTRY *pEntry)
+{
+ PKDE_ENCAP pKDE = NULL;
+ PUCHAR pMyKeyData = pKeyData;
+ UCHAR KeyDataLength = KeyDataLen;
+ UCHAR GTKLEN = 0;
+ UCHAR DefaultIdx = 0;
+ UCHAR skip_offset;
+
+ // Verify The RSN IE contained in pairewise_msg_2 && pairewise_msg_3 and skip it
+ if (MsgType == EAPOL_PAIR_MSG_2 || MsgType == EAPOL_PAIR_MSG_3)
+ {
+ // Check RSN IE whether it is WPA2/WPA2PSK
+ if (!RTMPCheckRSNIE(pAd, pKeyData, KeyDataLen, pEntry, &skip_offset))
+ {
+ // send wireless event - for RSN IE different
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_RSNIE_DIFF_EVENT_FLAG, pEntry->Addr, pEntry->apidx, 0);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in msg %d of 4-way handshake!\n", MsgType));
+ hex_dump("Receive RSN_IE ", pKeyData, KeyDataLen);
+ hex_dump("Desired RSN_IE ", pEntry->RSN_IE, pEntry->RSNIE_Len);
+
+ return FALSE;
+ }
+ else
+ {
+ if (bWPA2 && MsgType == EAPOL_PAIR_MSG_3)
+ {
+ // skip RSN IE
+ pMyKeyData += skip_offset;
+ KeyDataLength -= skip_offset;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPParseEapolKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
+ }
+ else
+ return TRUE;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("RTMPParseEapolKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
+
+ // Parse EKD format in pairwise_msg_3_WPA2 && group_msg_1_WPA2
+ if (bWPA2 && (MsgType == EAPOL_PAIR_MSG_3 || MsgType == EAPOL_GROUP_MSG_1))
+ {
+ if (KeyDataLength >= 8) // KDE format exclude GTK length
+ {
+ pKDE = (PKDE_ENCAP) pMyKeyData;
+
+
+ DefaultIdx = pKDE->GTKEncap.Kid;
+
+ // Sanity check - KED length
+ if (KeyDataLength < (pKDE->Len + 2))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
+ return FALSE;
+ }
+
+ // Get GTK length - refer to IEEE 802.11i-2004 p.82
+ GTKLEN = pKDE->Len -6;
+ if (GTKLEN < LEN_AES_KEY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
+ return FALSE;
+ }
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KDE format length is too short \n"));
+ return FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("GTK in KDE format ,DefaultKeyID=%d, KeyLen=%d \n", DefaultIdx, GTKLEN));
+ // skip it
+ pMyKeyData += 8;
+ KeyDataLength -= 8;
+
+ }
+ else if (!bWPA2 && MsgType == EAPOL_GROUP_MSG_1)
+ {
+ DefaultIdx = GroupKeyIndex;
+ DBGPRINT(RT_DEBUG_TRACE, ("GTK DefaultKeyID=%d \n", DefaultIdx));
+ }
+
+ // Sanity check - shared key index must be 1 ~ 3
+ if (DefaultIdx < 1 || DefaultIdx > 3)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index(%d) is invalid in %s %s \n", DefaultIdx, ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+ return FALSE;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ // Todo
+#endif // CONFIG_STA_SUPPORT //
+
+ return TRUE;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct EAPoL message for WPA handshaking
+ Its format is below,
+
+ +--------------------+
+ | Protocol Version | 1 octet
+ +--------------------+
+ | Protocol Type | 1 octet
+ +--------------------+
+ | Body Length | 2 octets
+ +--------------------+
+ | Descriptor Type | 1 octet
+ +--------------------+
+ | Key Information | 2 octets
+ +--------------------+
+ | Key Length | 1 octet
+ +--------------------+
+ | Key Repaly Counter | 8 octets
+ +--------------------+
+ | Key Nonce | 32 octets
+ +--------------------+
+ | Key IV | 16 octets
+ +--------------------+
+ | Key RSC | 8 octets
+ +--------------------+
+ | Key ID or Reserved | 8 octets
+ +--------------------+
+ | Key MIC | 16 octets
+ +--------------------+
+ | Key Data Length | 2 octets
+ +--------------------+
+ | Key Data | n octets
+ +--------------------+
+
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ConstructEapolMsg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AuthMode,
+ IN UCHAR WepStatus,
+ IN UCHAR GroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN UCHAR *ReplayCounter,
+ IN UCHAR *KeyNonce,
+ IN UCHAR *TxRSC,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_Len,
+ OUT PEAPOL_PACKET pMsg)
+{
+ BOOLEAN bWPA2 = FALSE;
+
+ // Choose WPA2 or not
+ if ((AuthMode == Ndis802_11AuthModeWPA2) || (AuthMode == Ndis802_11AuthModeWPA2PSK))
+ bWPA2 = TRUE;
+
+ // Init Packet and Fill header
+ pMsg->ProVer = EAPOL_VER;
+ pMsg->ProType = EAPOLKey;
+
+ // Default 95 bytes, the EAPoL-Key descriptor exclude Key-data field
+ pMsg->Body_Len[1] = LEN_EAPOL_KEY_MSG;
+
+ // Fill in EAPoL descriptor
+ if (bWPA2)
+ pMsg->KeyDesc.Type = WPA2_KEY_DESC;
+ else
+ pMsg->KeyDesc.Type = WPA1_KEY_DESC;
+
+ // Fill in Key information, refer to IEEE Std 802.11i-2004 page 78
+ // When either the pairwise or the group cipher is AES, the DESC_TYPE_AES(2) shall be used.
+ pMsg->KeyDesc.KeyInfo.KeyDescVer =
+ (((WepStatus == Ndis802_11Encryption3Enabled) || (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+ // Specify Key Type as Group(0) or Pairwise(1)
+ if (MsgType >= EAPOL_GROUP_MSG_1)
+ pMsg->KeyDesc.KeyInfo.KeyType = GROUPKEY;
+ else
+ pMsg->KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // Specify Key Index, only group_msg1_WPA1
+ if (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1))
+ pMsg->KeyDesc.KeyInfo.KeyIndex = DefaultKeyIdx;
+
+ if (MsgType == EAPOL_PAIR_MSG_3)
+ pMsg->KeyDesc.KeyInfo.Install = 1;
+
+ if ((MsgType == EAPOL_PAIR_MSG_1) || (MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1))
+ pMsg->KeyDesc.KeyInfo.KeyAck = 1;
+
+ if (MsgType != EAPOL_PAIR_MSG_1)
+ pMsg->KeyDesc.KeyInfo.KeyMic = 1;
+
+ if ((bWPA2 && (MsgType >= EAPOL_PAIR_MSG_3)) || (!bWPA2 && (MsgType >= EAPOL_GROUP_MSG_1)))
+ {
+ pMsg->KeyDesc.KeyInfo.Secure = 1;
+ }
+
+ if (bWPA2 && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
+ {
+ pMsg->KeyDesc.KeyInfo.EKD_DL = 1;
+ }
+
+ // key Information element has done.
+ *(USHORT *)(&pMsg->KeyDesc.KeyInfo) = cpu2le16(*(USHORT *)(&pMsg->KeyDesc.KeyInfo));
+
+ // Fill in Key Length
+ {
+ if (MsgType >= EAPOL_GROUP_MSG_1)
+ {
+ // the length of group key cipher
+ pMsg->KeyDesc.KeyLength[1] = ((GroupKeyWepStatus == Ndis802_11Encryption2Enabled) ? TKIP_GTK_LENGTH : LEN_AES_KEY);
+ }
+ else
+ {
+ // the length of pairwise key cipher
+ pMsg->KeyDesc.KeyLength[1] = ((WepStatus == Ndis802_11Encryption2Enabled) ? LEN_TKIP_KEY : LEN_AES_KEY);
+ }
+ }
+
+ // Fill in replay counter
+ NdisMoveMemory(pMsg->KeyDesc.ReplayCounter, ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Fill Key Nonce field
+ // ANonce : pairwise_msg1 & pairwise_msg3
+ // SNonce : pairwise_msg2
+ // GNonce : group_msg1_wpa1
+ if ((MsgType <= EAPOL_PAIR_MSG_3) || ((!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))))
+ NdisMoveMemory(pMsg->KeyDesc.KeyNonce, KeyNonce, LEN_KEY_DESC_NONCE);
+
+ // Fill key IV - WPA2 as 0, WPA1 as random
+ if (!bWPA2 && (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ // Suggest IV be random number plus some number,
+ NdisMoveMemory(pMsg->KeyDesc.KeyIv, &KeyNonce[16], LEN_KEY_DESC_IV);
+ pMsg->KeyDesc.KeyIv[15] += 2;
+ }
+
+ // Fill Key RSC field
+ // It contains the RSC for the GTK being installed.
+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2) || (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ NdisMoveMemory(pMsg->KeyDesc.KeyRsc, TxRSC, 6);
+ }
+
+ // Clear Key MIC field for MIC calculation later
+ NdisZeroMemory(pMsg->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+ ConstructEapolKeyData(pAd,
+ AuthMode,
+ WepStatus,
+ GroupKeyWepStatus,
+ MsgType,
+ DefaultKeyIdx,
+ bWPA2,
+ PTK,
+ GTK,
+ RSNIE,
+ RSNIE_Len,
+ pMsg);
+
+ // Calculate MIC and fill in KeyMic Field except Pairwise Msg 1.
+ if (MsgType != EAPOL_PAIR_MSG_1)
+ {
+ CalculateMIC(pAd, WepStatus, PTK, pMsg);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> ConstructEapolMsg for %s %s\n", ((bWPA2) ? "WPA2" : "WPA"), GetEapolMsgType(MsgType)));
+ DBGPRINT(RT_DEBUG_TRACE, (" Body length = %d \n", pMsg->Body_Len[1]));
+ DBGPRINT(RT_DEBUG_TRACE, (" Key length = %d \n", pMsg->KeyDesc.KeyLength[1]));
+
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Construct the Key Data field of EAPoL message
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ConstructEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AuthMode,
+ IN UCHAR WepStatus,
+ IN UCHAR GroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN BOOLEAN bWPA2Capable,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_LEN,
+ OUT PEAPOL_PACKET pMsg)
+{
+ UCHAR *mpool, *Key_Data, *Rc4GTK;
+ UCHAR ekey[(LEN_KEY_DESC_IV+LEN_EAP_EK)];
+ UCHAR data_offset;
+
+
+ if (MsgType == EAPOL_PAIR_MSG_1 || MsgType == EAPOL_PAIR_MSG_4 || MsgType == EAPOL_GROUP_MSG_2)
+ return;
+
+ // allocate memory pool
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 1500);
+
+ if (mpool == NULL)
+ return;
+
+ /* Rc4GTK Len = 512 */
+ Rc4GTK = (UCHAR *) ROUND_UP(mpool, 4);
+ /* Key_Data Len = 512 */
+ Key_Data = (UCHAR *) ROUND_UP(Rc4GTK + 512, 4);
+
+ NdisZeroMemory(Key_Data, 512);
+ pMsg->KeyDesc.KeyDataLen[1] = 0;
+ data_offset = 0;
+
+ // Encapsulate RSNIE in pairwise_msg2 & pairwise_msg3
+ if (RSNIE_LEN && ((MsgType == EAPOL_PAIR_MSG_2) || (MsgType == EAPOL_PAIR_MSG_3)))
+ {
+ if (bWPA2Capable)
+ Key_Data[data_offset + 0] = IE_WPA2;
+ else
+ Key_Data[data_offset + 0] = IE_WPA;
+
+ Key_Data[data_offset + 1] = RSNIE_LEN;
+ NdisMoveMemory(&Key_Data[data_offset + 2], RSNIE, RSNIE_LEN);
+ data_offset += (2 + RSNIE_LEN);
+ }
+
+ // Encapsulate KDE format in pairwise_msg3_WPA2 & group_msg1_WPA2
+ if (bWPA2Capable && ((MsgType == EAPOL_PAIR_MSG_3) || (MsgType == EAPOL_GROUP_MSG_1)))
+ {
+ // Key Data Encapsulation (KDE) format - 802.11i-2004 Figure-43w and Table-20h
+ Key_Data[data_offset + 0] = 0xDD;
+
+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Key_Data[data_offset + 1] = 0x16;// 4+2+16(OUI+DataType+DataField)
+ }
+ else
+ {
+ Key_Data[data_offset + 1] = 0x26;// 4+2+32(OUI+DataType+DataField)
+ }
+
+ Key_Data[data_offset + 2] = 0x00;
+ Key_Data[data_offset + 3] = 0x0F;
+ Key_Data[data_offset + 4] = 0xAC;
+ Key_Data[data_offset + 5] = 0x01;
+
+ // GTK KDE format - 802.11i-2004 Figure-43x
+ Key_Data[data_offset + 6] = (DefaultKeyIdx & 0x03);
+ Key_Data[data_offset + 7] = 0x00; // Reserved Byte
+
+ data_offset += 8;
+ }
+
+
+ // Encapsulate GTK and encrypt the key-data field with KEK.
+ // Only for pairwise_msg3_WPA2 and group_msg1
+ if ((MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable) || (MsgType == EAPOL_GROUP_MSG_1))
+ {
+ // Fill in GTK
+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ NdisMoveMemory(&Key_Data[data_offset], GTK, LEN_AES_KEY);
+ data_offset += LEN_AES_KEY;
+ }
+ else
+ {
+ NdisMoveMemory(&Key_Data[data_offset], GTK, TKIP_GTK_LENGTH);
+ data_offset += TKIP_GTK_LENGTH;
+ }
+
+ // Still dont know why, but if not append will occur "GTK not include in MSG3"
+ // Patch for compatibility between zero config and funk
+ if (MsgType == EAPOL_PAIR_MSG_3 && bWPA2Capable)
+ {
+ if (GroupKeyWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Key_Data[data_offset + 0] = 0xDD;
+ Key_Data[data_offset + 1] = 0;
+ data_offset += 2;
+ }
+ else
+ {
+ Key_Data[data_offset + 0] = 0xDD;
+ Key_Data[data_offset + 1] = 0;
+ Key_Data[data_offset + 2] = 0;
+ Key_Data[data_offset + 3] = 0;
+ Key_Data[data_offset + 4] = 0;
+ Key_Data[data_offset + 5] = 0;
+ data_offset += 6;
+ }
+ }
+
+ // Encrypt the data material in key data field
+ if (WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ AES_GTK_KEY_WRAP(&PTK[16], Key_Data, data_offset, Rc4GTK);
+ // AES wrap function will grow 8 bytes in length
+ data_offset += 8;
+ }
+ else
+ {
+ // PREPARE Encrypted "Key DATA" field. (Encrypt GTK with RC4, usinf PTK[16]->[31] as Key, IV-field as IV)
+ // put TxTsc in Key RSC field
+ pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
+
+ // ekey is the contanetion of IV-field, and PTK[16]->PTK[31]
+ NdisMoveMemory(ekey, pMsg->KeyDesc.KeyIv, LEN_KEY_DESC_IV);
+ NdisMoveMemory(&ekey[LEN_KEY_DESC_IV], &PTK[16], LEN_EAP_EK);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, ekey, sizeof(ekey)); //INIT SBOX, KEYLEN+3(IV)
+ pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, Key_Data, data_offset);
+ WPAARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, Rc4GTK, Key_Data, data_offset);
+ }
+
+ NdisMoveMemory(pMsg->KeyDesc.KeyData, Rc4GTK, data_offset);
+ }
+ else
+ {
+ NdisMoveMemory(pMsg->KeyDesc.KeyData, Key_Data, data_offset);
+ }
+
+ // set key data length field and total length
+ pMsg->KeyDesc.KeyDataLen[1] = data_offset;
+ pMsg->Body_Len[1] += data_offset;
+
+ os_free_mem(pAd, mpool);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calcaulate MIC. It is used during 4-ways handsharking.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ PeerWepStatus - indicate the encryption type
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID CalculateMIC(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR *PTK,
+ OUT PEAPOL_PACKET pMsg)
+{
+ UCHAR *OutBuffer;
+ ULONG FrameLen = 0;
+ UCHAR mic[LEN_KEY_DESC_MIC];
+ UCHAR digest[80];
+
+ // allocate memory for MIC calculation
+ os_alloc_mem(pAd, (PUCHAR *)&OutBuffer, 512);
+
+ if (OutBuffer == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("!!!CalculateMIC: no memory!!!\n"));
+ return;
+ }
+
+ // make a frame for calculating MIC.
+ MakeOutgoingFrame(OutBuffer, &FrameLen,
+ pMsg->Body_Len[1] + 4, pMsg,
+ END_OF_ARGS);
+
+ NdisZeroMemory(mic, sizeof(mic));
+
+ // Calculate MIC
+ if (PeerWepStatus == Ndis802_11Encryption3Enabled)
+ {
+ HMAC_SHA1(OutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(PTK, LEN_EAP_MICK, OutBuffer, FrameLen, mic);
+ }
+
+ // store the calculated MIC
+ NdisMoveMemory(pMsg->KeyDesc.KeyMic, mic, LEN_KEY_DESC_MIC);
+
+ os_free_mem(pAd, OutBuffer);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Some received frames can't decrypt by Asic, so decrypt them by software.
+
+ Arguments:
+ pAd - pointer to our pAdapter context
+ PeerWepStatus - indicate the encryption type
+
+ Return Value:
+ NDIS_STATUS_SUCCESS - decryption successful
+ NDIS_STATUS_FAILURE - decryption failure
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPSoftDecryptBroadCastData(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
+ IN PCIPHER_KEY pShard_key)
+{
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+
+
+
+ // handle WEP decryption
+ if (GroupCipher == Ndis802_11Encryption1Enabled)
+ {
+ if (RTMPSoftDecryptWEP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, pShard_key))
+ {
+
+ //Minus IV[4] & ICV[4]
+ pRxWI->MPDUtotalByteCount -= 8;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : Software decrypt WEP data fails.\n"));
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ // handle TKIP decryption
+ else if (GroupCipher == Ndis802_11Encryption2Enabled)
+ {
+ if (RTMPSoftDecryptTKIP(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount, 0, pShard_key))
+ {
+
+ //Minus 8 bytes MIC, 8 bytes IV/EIV, 4 bytes ICV
+ pRxWI->MPDUtotalByteCount -= 20;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptTKIP Failed\n"));
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ // handle AES decryption
+ else if (GroupCipher == Ndis802_11Encryption3Enabled)
+ {
+ if (RTMPSoftDecryptAES(pAd, pRxBlk->pData, pRxWI->MPDUtotalByteCount , pShard_key))
+ {
+
+ //8 bytes MIC, 8 bytes IV/EIV (CCMP Header)
+ pRxWI->MPDUtotalByteCount -= 16;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR : RTMPSoftDecryptAES Failed\n"));
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+ }
+ else
+ {
+ // give up this frame
+ return NDIS_STATUS_FAILURE;
+ }
+
+ return NDIS_STATUS_SUCCESS;
+
+}
+
diff --git a/drivers/staging/rt3070/common/dfs.c b/drivers/staging/rt3070/common/dfs.c
new file mode 100644
index 00000000000..28d60145791
--- /dev/null
+++ b/drivers/staging/rt3070/common/dfs.c
@@ -0,0 +1,441 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ ap_dfs.c
+
+ Abstract:
+ Support DFS function.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 03-12-2007 created
+*/
+
+#include "../rt_config.h"
+
+typedef struct _RADAR_DURATION_TABLE
+{
+ ULONG RDDurRegion;
+ ULONG RadarSignalDuration;
+ ULONG Tolerance;
+} RADAR_DURATION_TABLE, *PRADAR_DURATION_TABLE;
+
+
+static UCHAR RdIdleTimeTable[MAX_RD_REGION][4] =
+{
+ {9, 250, 250, 250}, // CE
+ {4, 250, 250, 250}, // FCC
+ {4, 250, 250, 250}, // JAP
+ {15, 250, 250, 250}, // JAP_W53
+ {4, 250, 250, 250} // JAP_W56
+};
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Bbp Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+
+ ========================================================================
+*/
+VOID BbpRadarDetectionStart(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT8 RadarPeriod;
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 114, 0x02);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 121, 0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 122, 0x00);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 123, 0x08/*0x80*/);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 124, 0x28);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, 125, 0xff);
+
+ RadarPeriod = ((UINT)RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + (UINT)pAd->CommonCfg.RadarDetect.DfsSessionTime) < 250 ?
+ (RdIdleTimeTable[pAd->CommonCfg.RadarDetect.RDDurRegion][0] + pAd->CommonCfg.RadarDetect.DfsSessionTime) : 250;
+
+ RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
+ RTMP_IO_WRITE8(pAd, 0x7021, 0x40);
+
+ RadarDetectionStart(pAd, 0, RadarPeriod);
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Bbp Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+
+ ========================================================================
+*/
+VOID BbpRadarDetectionStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTMP_IO_WRITE8(pAd, 0x7020, 0x1d);
+ RTMP_IO_WRITE8(pAd, 0x7021, 0x60);
+
+ RadarDetectionStop(pAd);
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+
+ ========================================================================
+*/
+VOID RadarDetectionStart(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN CTSProtect,
+ IN UINT8 CTSPeriod)
+{
+ UINT8 DfsActiveTime = (pAd->CommonCfg.RadarDetect.DfsSessionTime & 0x1f);
+ UINT8 CtsProtect = (CTSProtect == 1) ? 0x02 : 0x01; // CTS protect.
+
+ if (CTSProtect != 0)
+ {
+ switch(pAd->CommonCfg.RadarDetect.RDDurRegion)
+ {
+ case FCC:
+ case JAP_W56:
+ CtsProtect = 0x03;
+ break;
+
+ case CE:
+ case JAP_W53:
+ default:
+ CtsProtect = 0x02;
+ break;
+ }
+ }
+ else
+ CtsProtect = 0x01;
+
+
+ // send start-RD with CTS protection command to MCU
+ // highbyte [7] reserve
+ // highbyte [6:5] 0x: stop Carrier/Radar detection
+ // highbyte [10]: Start Carrier/Radar detection without CTS protection, 11: Start Carrier/Radar detection with CTS protection
+ // highbyte [4:0] Radar/carrier detection duration. In 1ms.
+
+ // lowbyte [7:0] Radar/carrier detection period, in 1ms.
+ AsicSendCommandToMcu(pAd, 0x60, 0xff, CTSPeriod, DfsActiveTime | (CtsProtect << 5));
+ //AsicSendCommandToMcu(pAd, 0x63, 0xff, 10, 0);
+
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Radar detection routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ TRUE Found radar signal
+ FALSE Not found radar signal
+
+ ========================================================================
+*/
+VOID RadarDetectionStop(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE,("RadarDetectionStop.\n"));
+ AsicSendCommandToMcu(pAd, 0x60, 0xff, 0x00, 0x00); // send start-RD with CTS protection command to MCU
+
+ return;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Radar channel check routine
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ TRUE need to do radar detect
+ FALSE need not to do radar detect
+
+ ========================================================================
+*/
+BOOLEAN RadarChannelCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ch)
+{
+#if 1
+ INT i;
+ BOOLEAN result = FALSE;
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if (Ch == pAd->ChannelList[i].Channel)
+ {
+ result = pAd->ChannelList[i].DfsReq;
+ break;
+ }
+ }
+
+ return result;
+#else
+ INT i;
+ UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+
+ for (i=0; i<15; i++)
+ {
+ if (Ch == Channel[i])
+ {
+ break;
+ }
+ }
+
+ if (i != 15)
+ return TRUE;
+ else
+ return FALSE;
+#endif
+}
+
+ULONG JapRadarType(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ const UCHAR Channel[15]={52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140};
+
+ if (pAd->CommonCfg.RadarDetect.RDDurRegion != JAP)
+ {
+ return pAd->CommonCfg.RadarDetect.RDDurRegion;
+ }
+
+ for (i=0; i<15; i++)
+ {
+ if (pAd->CommonCfg.Channel == Channel[i])
+ {
+ break;
+ }
+ }
+
+ if (i < 4)
+ return JAP_W53;
+ else if (i < 15)
+ return JAP_W56;
+ else
+ return JAP; // W52
+
+}
+
+ULONG RTMPBbpReadRadarDuration(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT8 byteValue = 0;
+ ULONG result;
+
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R115, &byteValue);
+
+ result = 0;
+ switch (byteValue)
+ {
+ case 1: // radar signal detected by pulse mode.
+ case 2: // radar signal detected by width mode.
+ result = RTMPReadRadarDuration(pAd);
+ break;
+
+ case 0: // No radar signal.
+ default:
+
+ result = 0;
+ break;
+ }
+
+ return result;
+}
+
+ULONG RTMPReadRadarDuration(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG result = 0;
+
+#ifdef DFS_SUPPORT
+ UINT8 duration1 = 0, duration2 = 0, duration3 = 0;
+
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R116, &duration1);
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R117, &duration2);
+ BBP_IO_READ8_BY_REG_ID(pAd, BBP_R118, &duration3);
+ result = (duration1 << 16) + (duration2 << 8) + duration3;
+#endif // DFS_SUPPORT //
+
+ return result;
+
+}
+
+VOID RTMPCleanRadarDuration(
+ IN PRTMP_ADAPTER pAd)
+{
+ return;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Radar wave detection. The API should be invoke each second.
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID ApRadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+
+ pAd->CommonCfg.RadarDetect.InServiceMonitorCount++;
+
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if (pAd->ChannelList[i].RemainingTimeForUse > 0)
+ {
+ pAd->ChannelList[i].RemainingTimeForUse --;
+ if ((pAd->Mlme.PeriodicRound%5) == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RadarDetectPeriodic - ch=%d, RemainingTimeForUse=%d\n", pAd->ChannelList[i].Channel, pAd->ChannelList[i].RemainingTimeForUse));
+ }
+ }
+ }
+
+ //radar detect
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ RadarDetectPeriodic(pAd);
+ }
+
+ return;
+}
+
+// Periodic Radar detection, switch channel will occur in RTMPHandleTBTTInterrupt()
+// Before switch channel, driver needs doing channel switch announcement.
+VOID RadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd)
+{
+ // need to check channel availability, after switch channel
+ if (pAd->CommonCfg.RadarDetect.RDMode != RD_SILENCE_MODE)
+ return;
+
+ // channel availability check time is 60sec, use 65 for assurance
+ if (pAd->CommonCfg.RadarDetect.RDCount++ > pAd->CommonCfg.RadarDetect.ChMovingTime)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Not found radar signal, start send beacon and radar detection in service monitor\n\n"));
+ BbpRadarDetectionStop(pAd);
+ AsicEnableBssSync(pAd);
+ pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+
+
+ return;
+ }
+
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ change channel moving time for DFS testing.
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 set ChMovTime=[value]
+ ==========================================================================
+*/
+INT Set_ChMovingTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT8 Value;
+
+ Value = simple_strtol(arg, 0, 10);
+
+ pAd->CommonCfg.RadarDetect.ChMovingTime = Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
+ pAd->CommonCfg.RadarDetect.ChMovingTime));
+
+ return TRUE;
+}
+
+INT Set_LongPulseRadarTh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT8 Value;
+
+ Value = simple_strtol(arg, 0, 10) > 10 ? 10 : simple_strtol(arg, 0, 10);
+
+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh = Value;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s:: %d\n", __FUNCTION__,
+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh));
+
+ return TRUE;
+}
+
+
diff --git a/drivers/staging/rt3070/common/eeprom.c b/drivers/staging/rt3070/common/eeprom.c
new file mode 100644
index 00000000000..63e1dc14d15
--- /dev/null
+++ b/drivers/staging/rt3070/common/eeprom.c
@@ -0,0 +1,1498 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ eeprom.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#include "../rt_config.h"
+
+// IRQL = PASSIVE_LEVEL
+VOID RaiseClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x)
+{
+ *x = *x | EESK;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+ RTMPusecDelay(1); // Max frequency = 1MHz in Spec. definition
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID LowerClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x)
+{
+ *x = *x & ~EESK;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, *x);
+ RTMPusecDelay(1);
+}
+
+// IRQL = PASSIVE_LEVEL
+USHORT ShiftInBits(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x,i;
+ USHORT data=0;
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~( EEDO | EEDI);
+
+ for(i=0; i<16; i++)
+ {
+ data = data << 1;
+ RaiseClock(pAd, &x);
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ LowerClock(pAd, &x); //prevent read failed
+
+ x &= ~(EEDI);
+ if(x & EEDO)
+ data |= 1;
+ }
+
+ return data;
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID ShiftOutBits(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT data,
+ IN USHORT count)
+{
+ UINT32 x,mask;
+
+ mask = 0x01 << (count - 1);
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~(EEDO | EEDI);
+
+ do
+ {
+ x &= ~EEDI;
+ if(data & mask) x |= EEDI;
+
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ mask = mask >> 1;
+ } while(mask);
+
+ x &= ~EEDI;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+}
+
+// IRQL = PASSIVE_LEVEL
+VOID EEpromCleanup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ x &= ~(EECS | EEDI);
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+}
+
+VOID EWEN(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ // output the read_opcode and six pulse in that order
+ ShiftOutBits(pAd, EEPROM_EWEN_OPCODE, 5);
+ ShiftOutBits(pAd, 0, 6);
+
+ EEpromCleanup(pAd);
+}
+
+VOID EWDS(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 x;
+
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+
+ // output the read_opcode and six pulse in that order
+ ShiftOutBits(pAd, EEPROM_EWDS_OPCODE, 5);
+ ShiftOutBits(pAd, 0, 6);
+
+ EEpromCleanup(pAd);
+}
+
+// IRQL = PASSIVE_LEVEL
+USHORT RTMP_EEPROM_READ16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset)
+{
+ UINT32 x;
+ USHORT data;
+
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ pAd->EepromAccess = TRUE;
+ }
+//2008/09/11:KH add to support efuse<--
+//2008/09/11:KH add to support efuse-->
+{
+ Offset /= 2;
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // patch can not access e-Fuse issue
+ if (!IS_RT3090(pAd))
+ {
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+ }
+
+ // output the read_opcode and register number in that order
+ ShiftOutBits(pAd, EEPROM_READ_OPCODE, 3);
+ ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+
+ // Now read the data (16 bits) in from the selected EEPROM word
+ data = ShiftInBits(pAd);
+
+ EEpromCleanup(pAd);
+
+ // Antenna and EEPROM access are both using EESK pin,
+ // Therefor we should avoid accessing EESK at the same time
+ // Then restore antenna after EEPROM access
+ if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
+ {
+ pAd->EepromAccess = FALSE;
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ }
+}
+ return data;
+} //ReadEEprom
+
+VOID RTMP_EEPROM_WRITE16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Data)
+{
+ UINT32 x;
+
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ pAd->EepromAccess = TRUE;
+ }
+ //2008/09/11:KH add to support efuse<--
+//2008/09/11:KH add to support efuse-->
+ {
+ Offset /= 2;
+
+ EWEN(pAd);
+
+ // reset bits and set EECS
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EEDI | EEDO | EESK);
+ x |= EECS;
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ // patch can not access e-Fuse issue
+ if (!IS_RT3090(pAd))
+ {
+ // kick a pulse
+ RaiseClock(pAd, &x);
+ LowerClock(pAd, &x);
+ }
+
+ // output the read_opcode ,register number and data in that order
+ ShiftOutBits(pAd, EEPROM_WRITE_OPCODE, 3);
+ ShiftOutBits(pAd, Offset, pAd->EEPROMAddressNum);
+ ShiftOutBits(pAd, Data, 16); // 16-bit access
+
+ // read DO status
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+
+ EEpromCleanup(pAd);
+
+ RTMPusecDelay(10000); //delay for twp(MAX)=10ms
+
+ EWDS(pAd);
+
+ EEpromCleanup(pAd);
+
+ // Antenna and EEPROM access are both using EESK pin,
+ // Therefor we should avoid accessing EESK at the same time
+ // Then restore antenna after EEPROM access
+ if ((pAd->NicConfig2.field.AntDiversity) || (pAd->RfIcType == RFIC_3020))
+ {
+ pAd->EepromAccess = FALSE;
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ }
+}
+}
+
+//2008/09/11:KH add to support efuse<--
+#ifdef RT30xx
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+UCHAR eFuseReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData)
+{
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ int i;
+ USHORT efuseDataOffset;
+ UINT32 data;
+
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ //Use the eeprom logical address and covert to address to block number
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 0.
+ eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ //rtmp.HwMemoryReadDword(EFUSE_CTRL, (DWORD *) &eFuseCtrlStruc, 4);
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ {
+ break;
+ }
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //if EFSROM_AOUT is not found in physical address, write 0xffff
+ if (eFuseCtrlStruc.field.EFSROM_AOUT == 0x3f)
+ {
+ for(i=0; i<Length/2; i++)
+ *(pData+2*i) = 0xffff;
+ }
+ else
+ {
+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x590-0x59C)
+ efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
+ //data hold 4 bytes data.
+ //In RTMP_IO_READ32 will automatically execute 32-bytes swapping
+ RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+ //Decide the upper 2 bytes or the bottom 2 bytes.
+ // Little-endian S | S Big-endian
+ // addr 3 2 1 0 | 0 1 2 3
+ // Ori-V D C B A | A B C D
+ //After swapping
+ // D C B A | D C B A
+ //Return 2-bytes
+ //The return byte statrs from S. Therefore, the little-endian will return BA, the Big-endian will return DC.
+ //For returning the bottom 2 bytes, the Big-endian should shift right 2-bytes.
+#ifdef RT_BIG_ENDIAN
+ data = data << (8*((Offset & 0x3)^0x2));
+#else
+ data = data >> (8*(Offset & 0x3));
+#endif
+
+ NdisMoveMemory(pData, &data, Length);
+ }
+
+ return (UCHAR) eFuseCtrlStruc.field.EFSROM_AOUT;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFusePhysicalReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData)
+{
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ int i;
+ USHORT efuseDataOffset;
+ UINT32 data;
+
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+ //Read in physical view
+ eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+ //Because the size of each EFUSE_DATA is 4 Bytes, the size of address of each is 2 bits.
+ //The previous 2 bits is the EFUSE_DATA number, the last 2 bits is used to decide which bytes
+ //Decide which EFUSE_DATA to read
+ //590:F E D C
+ //594:B A 9 8
+ //598:7 6 5 4
+ //59C:3 2 1 0
+ efuseDataOffset = EFUSE_DATA3 - (Offset & 0xC) ;
+
+ RTMP_IO_READ32(pAd, efuseDataOffset, &data);
+
+#ifdef RT_BIG_ENDIAN
+ data = data << (8*((Offset & 0x3)^0x2));
+#else
+ data = data >> (8*(Offset & 0x3));
+#endif
+
+ NdisMoveMemory(pData, &data, Length);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFuseReadPhysical(
+ IN PRTMP_ADAPTER pAd,
+ IN PUSHORT lpInBuffer,
+ IN ULONG nInBufferSize,
+ OUT PUSHORT lpOutBuffer,
+ IN ULONG nOutBufferSize
+)
+{
+ USHORT* pInBuf = (USHORT*)lpInBuffer;
+ USHORT* pOutBuf = (USHORT*)lpOutBuffer;
+
+ USHORT Offset = pInBuf[0]; //addr
+ USHORT Length = pInBuf[1]; //length
+ int i;
+
+ for(i=0; i<Length; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd,Offset+i, 2, &pOutBuf[i/2]);
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS eFuseRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT Length)
+{
+ USHORT* pOutBuf = (USHORT*)pData;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UCHAR EFSROM_AOUT;
+ int i;
+
+ for(i=0; i<Length; i+=2)
+ {
+ EFSROM_AOUT = eFuseReadRegisters(pAd, Offset+i, 2, &pOutBuf[i/2]);
+ }
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFusePhysicalWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData)
+{
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ int i;
+ USHORT efuseDataOffset;
+ UINT32 data, eFuseDataBuffer[4];
+
+ //Step0. Write 16-byte of data to EFUSE_DATA0-3 (0x590-0x59C), where EFUSE_DATA0 is the LSB DW, EFUSE_DATA3 is the MSB DW.
+
+ /////////////////////////////////////////////////////////////////
+ //read current values of 16-byte block
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+ eFuseCtrlStruc.field.EFSROM_MODE = 1;
+
+ //Step2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //Step4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &eFuseDataBuffer[i]);
+ efuseDataOffset -= 4;
+ }
+
+ //Update the value, the offset is multiple of 2, length is 2
+ efuseDataOffset = (Offset & 0xc) >> 2;
+ data = pData[0] & 0xffff;
+ //The offset should be 0x***10 or 0x***00
+ if((Offset % 4) != 0)
+ {
+ eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff) | (data << 16);
+ }
+ else
+ {
+ eFuseDataBuffer[efuseDataOffset] = (eFuseDataBuffer[efuseDataOffset] & 0xffff0000) | data;
+ }
+
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_WRITE32(pAd, efuseDataOffset, eFuseDataBuffer[i]);
+ efuseDataOffset -= 4;
+ }
+ /////////////////////////////////////////////////////////////////
+
+ //Step1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+ eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+ //Step3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+
+ RTMPusecDelay(2);
+ i++;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS eFuseWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData)
+{
+ USHORT i;
+ USHORT eFuseData;
+ USHORT LogicalAddress, BlkNum = 0xffff;
+ UCHAR EFSROM_AOUT;
+
+ USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+ USHORT buffer[8];
+ BOOLEAN bWriteSuccess = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters Offset=%x, pData=%x\n", Offset, *pData));
+
+ //Step 0. find the entry in the mapping table
+ //The address of EEPROM is 2-bytes alignment.
+ //The last bit is used for alignment, so it must be 0.
+ tmpOffset = Offset & 0xfffe;
+ EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+ if( EFSROM_AOUT == 0x3f)
+ { //find available logical address pointer
+ //the logical address does not exist, find an empty one
+ //from the first address of block 45=16*45=0x2d0 to the last address of block 47
+ //==>48*16-3(reserved)=2FC
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ //Retrive the logical block nubmer form each logical address pointer
+ //It will access two logical address pointer each time.
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {//Not used logical address pointer
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {//Not used logical address pointer
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START+1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ BlkNum = EFSROM_AOUT;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+
+ //Step 1. Save data of this block which is pointed by the avaible logical address pointer
+ // read and save the original block data
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ buffer[i] = InBuf[2];
+ }
+
+ //Step 2. Update the data in buffer, and write the data to Efuse
+ buffer[ (Offset >> 1) % 8] = pData[0];
+
+ do
+ {
+ //Step 3. Write the data to Efuse
+ if(!bWriteSuccess)
+ {
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = buffer[i];
+
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+ }
+ }
+ else
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+(Offset % 16);
+ InBuf[1] = 2;
+ InBuf[2] = pData[0];
+
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+ }
+
+ //Step 4. Write mapping table
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+ tmpOffset = Offset;
+ tmpOffset >>= 4;
+ tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+ tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ InBuf[2] = tmpOffset<<8;
+ else
+ InBuf[2] = tmpOffset;
+
+ eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+ //Step 5. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+ bWriteSuccess = TRUE;
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ if(buffer[i] != InBuf[2])
+ {
+ bWriteSuccess = FALSE;
+ break;
+ }
+ }
+
+ //Step 6. invlidate mapping entry and find a free mapping entry if not succeed
+ if (!bWriteSuccess)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+ // the offset of current mapping entry
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ //find a new mapping entry
+ BlkNum = 0xffff;
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i+1-EFUSE_USAGE_MAP_START;
+ }
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+
+ //invalidate the original mapping entry if new entry is not found
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ {
+ // Invalidate the high byte
+ for (i=8; i<15; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // invalidate the low byte
+ for (i=0; i<8; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+ }
+ }
+ while(!bWriteSuccess);
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID eFuseWritePhysical(
+ IN PRTMP_ADAPTER pAd,
+ PUSHORT lpInBuffer,
+ ULONG nInBufferSize,
+ PUCHAR lpOutBuffer,
+ ULONG nOutBufferSize
+)
+{
+ USHORT* pInBuf = (USHORT*)lpInBuffer;
+ int i;
+ //USHORT* pOutBuf = (USHORT*)ioBuffer;
+
+ USHORT Offset = pInBuf[0]; //addr
+ USHORT Length = pInBuf[1]; //length
+ USHORT* pValueX = &pInBuf[2]; //value ...
+ // Little-endian S | S Big-endian
+ // addr 3 2 1 0 | 0 1 2 3
+ // Ori-V D C B A | A B C D
+ //After swapping
+ // D C B A | D C B A
+ //Both the little and big-endian use the same sequence to write data.
+ //Therefore, we only need swap data when read the data.
+ for(i=0; i<Length; i+=2)
+ {
+ eFusePhysicalWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS eFuseWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length)
+{
+ int i;
+
+ USHORT* pValueX = (PUSHORT) pData; //value ...
+ //The input value=3070 will be stored as following
+ // Little-endian S | S Big-endian
+ // addr 1 0 | 0 1
+ // Ori-V 30 70 | 30 70
+ //After swapping
+ // 30 70 | 70 30
+ //Casting
+ // 3070 | 7030 (x)
+ //The swapping should be removed for big-endian
+ for(i=0; i<length; i+=2)
+ {
+ eFuseWriteRegisters(pAd, Offset+i, 2, &pValueX[i/2]);
+ }
+
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+INT set_eFuseGetFreeBlockCount_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ USHORT i;
+ USHORT LogicalAddress;
+ USHORT efusefreenum=0;
+ if(!pAd->bUseEfuse)
+ return FALSE;
+ for (i = EFUSE_USAGE_MAP_START; i <= EFUSE_USAGE_MAP_END; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {
+ efusefreenum= (UCHAR) (EFUSE_USAGE_MAP_END-i+1);
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {
+ efusefreenum = (UCHAR) (EFUSE_USAGE_MAP_END-i);
+ break;
+ }
+
+ if(i == EFUSE_USAGE_MAP_END)
+ efusefreenum = 0;
+ }
+ printk("efuseFreeNumber is %d\n",efusefreenum);
+ return TRUE;
+}
+INT set_eFusedump_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+USHORT InBuf[3];
+ INT i=0;
+ if(!pAd->bUseEfuse)
+ return FALSE;
+ for(i =0; i<EFUSE_USAGE_MAP_END/2; i++)
+ {
+ InBuf[0] = 2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+ if(i%4==0)
+ printk("\nBlock %x:",i/8);
+ printk("%04x ",InBuf[2]);
+ }
+ return TRUE;
+}
+INT set_eFuseLoadFromBin_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *src;
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ UCHAR *buffer;
+ UCHAR BinFileSize=0;
+ INT i = 0,j=0,k=1;
+ USHORT *PDATA;
+ USHORT DATA;
+ BinFileSize=strlen("RT30xxEEPROM.bin");
+ src = kmalloc(128, MEM_ALLOC_FLAG);
+ NdisZeroMemory(src, 128);
+
+ if(strlen(arg)>0)
+ {
+
+ NdisMoveMemory(src, arg, strlen(arg));
+ }
+
+ else
+ {
+
+ NdisMoveMemory(src, "RT30xxEEPROM.bin", BinFileSize);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("FileName=%s\n",src));
+ buffer = kmalloc(MAX_EEPROM_BIN_FILE_SIZE, MEM_ALLOC_FLAG);
+
+ if(buffer == NULL)
+ {
+ kfree(src);
+ return FALSE;
+}
+ PDATA=kmalloc(sizeof(USHORT)*8,MEM_ALLOC_FLAG);
+
+ if(PDATA==NULL)
+ {
+ kfree(src);
+
+ kfree(buffer);
+ return FALSE;
+ }
+ /* Don't change to uid 0, let the file be opened as the "normal" user */
+#if 0
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid=current->fsgid = 0;
+#endif
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ if (src && *src)
+ {
+ srcf = filp_open(src, O_RDONLY, 0);
+ if (IS_ERR(srcf))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+ return FALSE;
+ }
+ else
+ {
+ // The object must have a read method
+ if (srcf->f_op && srcf->f_op->read)
+ {
+ memset(buffer, 0x00, MAX_EEPROM_BIN_FILE_SIZE);
+ while(srcf->f_op->read(srcf, &buffer[i], 1, &srcf->f_pos)==1)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[i]));
+ if((i+1)%8==0)
+ DBGPRINT(RT_DEBUG_TRACE, ("\n"));
+ i++;
+ if(i>=MAX_EEPROM_BIN_FILE_SIZE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld reading %s, The file is too large[1024]\n", -PTR_ERR(srcf),src));
+ kfree(PDATA);
+ kfree(buffer);
+ kfree(src);
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error!! System doest not support read function\n"));
+ kfree(PDATA);
+ kfree(buffer);
+ kfree(src);
+ return FALSE;
+ }
+ }
+
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error src or srcf is null\n"));
+ kfree(PDATA);
+ kfree(buffer);
+ return FALSE;
+
+ }
+
+
+ retval=filp_close(srcf,NULL);
+
+ if (retval)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+ }
+ set_fs(orgfs);
+#if 0
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+#endif
+ for(j=0;j<i;j++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%02X ",buffer[j]));
+ if((j+1)%2==0)
+ PDATA[j/2%8]=((buffer[j]<<8)&0xff00)|(buffer[j-1]&0xff);
+ if(j%16==0)
+ {
+ k=buffer[j];
+ }
+ else
+ {
+ k&=buffer[j];
+ if((j+1)%16==0)
+ {
+
+ DBGPRINT(RT_DEBUG_TRACE, (" result=%02X,blk=%02x\n",k,j/16));
+
+ if(k!=0xff)
+ eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+ else
+ {
+ if(eFuseReadRegisters(pAd,j, 2,(PUSHORT)&DATA)!=0x3f)
+ eFuseWriteRegistersFromBin(pAd,(USHORT)j-15, 16, PDATA);
+ }
+ /*
+ for(l=0;l<8;l++)
+ printk("%04x ",PDATA[l]);
+ printk("\n");
+ */
+ NdisZeroMemory(PDATA,16);
+
+
+ }
+ }
+
+
+ }
+
+
+ kfree(PDATA);
+ kfree(buffer);
+ kfree(src);
+ return TRUE;
+}
+NTSTATUS eFuseWriteRegistersFromBin(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData)
+{
+ USHORT i;
+ USHORT eFuseData;
+ USHORT LogicalAddress, BlkNum = 0xffff;
+ UCHAR EFSROM_AOUT,Loop=0;
+ EFUSE_CTRL_STRUC eFuseCtrlStruc;
+ USHORT efuseDataOffset;
+ UINT32 data,tempbuffer;
+ USHORT addr,tmpaddr, InBuf[3], tmpOffset;
+ UINT32 buffer[4];
+ BOOLEAN bWriteSuccess = TRUE;
+ BOOLEAN bNotWrite=TRUE;
+ BOOLEAN bAllocateNewBlk=TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin Offset=%x, pData=%04x:%04x:%04x:%04x\n", Offset, *pData,*(pData+1),*(pData+2),*(pData+3)));
+
+ do
+ {
+ //Step 0. find the entry in the mapping table
+ //The address of EEPROM is 2-bytes alignment.
+ //The last bit is used for alignment, so it must be 0.
+ Loop++;
+ tmpOffset = Offset & 0xfffe;
+ EFSROM_AOUT = eFuseReadRegisters(pAd, tmpOffset, 2, &eFuseData);
+
+ if( EFSROM_AOUT == 0x3f)
+ { //find available logical address pointer
+ //the logical address does not exist, find an empty one
+ //from the first address of block 45=16*45=0x2d0 to the last address of block 47
+ //==>48*16-3(reserved)=2FC
+ bAllocateNewBlk=TRUE;
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ //Retrive the logical block nubmer form each logical address pointer
+ //It will access two logical address pointer each time.
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {//Not used logical address pointer
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {//Not used logical address pointer
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START+1;
+ }
+ break;
+ }
+ }
+ }
+ else
+ {
+ bAllocateNewBlk=FALSE;
+ BlkNum = EFSROM_AOUT;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters BlkNum = %d \n", BlkNum));
+
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegisters: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+ //Step 1.1.0
+ //If the block is not existing in mapping table, create one
+ //and write down the 16-bytes data to the new block
+ if(bAllocateNewBlk)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk\n"));
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Allocate New Blk, Data%d=%04x%04x\n",3-i,pData[2*i+1],pData[2*i]));
+ tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+
+
+ RTMP_IO_WRITE32(pAd, efuseDataOffset,tempbuffer);
+ efuseDataOffset -= 4;
+
+ }
+ /////////////////////////////////////////////////////////////////
+
+ //Step1.1.1. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = BlkNum* 0x10 ;
+
+ //Step1.1.2. Write EFSROM_MODE (0x580, bit7:bit6) to 3.
+ eFuseCtrlStruc.field.EFSROM_MODE = 3;
+
+ //Step1.1.3. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical write procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step1.1.4. Polling EFSROM_KICK(0x580, bit30) until it become 0 again. It¡¦s done.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ }
+ else
+ { //Step1.2.
+ //If the same logical number is existing, check if the writting data and the data
+ //saving in this block are the same.
+ /////////////////////////////////////////////////////////////////
+ //read current values of 16-byte block
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ //Step1.2.0. Write 10-bit of address to EFSROM_AIN (0x580, bit25:bit16). The address must be 16-byte alignment.
+ eFuseCtrlStruc.field.EFSROM_AIN = Offset & 0xfff0;
+
+ //Step1.2.1. Write EFSROM_MODE (0x580, bit7:bit6) to 1.
+ eFuseCtrlStruc.field.EFSROM_MODE = 0;
+
+ //Step1.2.2. Write EFSROM_KICK (0x580, bit30) to 1 to kick-off physical read procedure.
+ eFuseCtrlStruc.field.EFSROM_KICK = 1;
+
+ NdisMoveMemory(&data, &eFuseCtrlStruc, 4);
+ RTMP_IO_WRITE32(pAd, EFUSE_CTRL, data);
+
+ //Step1.2.3. Polling EFSROM_KICK(0x580, bit30) until it become 0 again.
+ i = 0;
+ while(i < 100)
+ {
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, (PUINT32) &eFuseCtrlStruc);
+
+ if(eFuseCtrlStruc.field.EFSROM_KICK == 0)
+ break;
+ RTMPusecDelay(2);
+ i++;
+ }
+
+ //Step1.2.4. Read 16-byte of data from EFUSE_DATA0-3 (0x59C-0x590)
+ efuseDataOffset = EFUSE_DATA3;
+ for(i=0; i< 4; i++)
+ {
+ RTMP_IO_READ32(pAd, efuseDataOffset, (PUINT32) &buffer[i]);
+ efuseDataOffset -= 4;
+ }
+ //Step1.2.5. Check if the data of efuse and the writing data are the same.
+ for(i =0; i<4; i++)
+ {
+ tempbuffer=((pData[2*i+1]<<16)&0xffff0000)|pData[2*i];
+ DBGPRINT(RT_DEBUG_TRACE, ("buffer[%d]=%x,pData[%d]=%x,pData[%d]=%x,tempbuffer=%x\n",i,buffer[i],2*i,pData[2*i],2*i+1,pData[2*i+1],tempbuffer));
+
+ if(((buffer[i]&0xffff0000)==(pData[2*i+1]<<16))&&((buffer[i]&0xffff)==pData[2*i]))
+ bNotWrite&=TRUE;
+ else
+ {
+ bNotWrite&=FALSE;
+ break;
+ }
+ }
+ if(!bNotWrite)
+ {
+ printk("The data is not the same\n");
+
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = pData[i];
+
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 2);
+ }
+
+ }
+ else
+ return TRUE;
+ }
+
+
+
+ //Step 2. Write mapping table
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ //convert the address from 10 to 8 bit ( bit7, 6 = parity and bit5 ~ 0 = bit9~4), and write to logical map entry
+ tmpOffset = Offset;
+ tmpOffset >>= 4;
+ tmpOffset |= ((~((tmpOffset & 0x01) ^ ( tmpOffset >> 1 & 0x01) ^ (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01))) << 6) & 0x40;
+ tmpOffset |= ((~( (tmpOffset >> 2 & 0x01) ^ (tmpOffset >> 3 & 0x01) ^ (tmpOffset >> 4 & 0x01) ^ ( tmpOffset >> 5 & 0x01))) << 7) & 0x80;
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ InBuf[2] = tmpOffset<<8;
+ else
+ InBuf[2] = tmpOffset;
+
+ eFuseWritePhysical(pAd,&InBuf[0], 6, NULL, 0);
+
+ //Step 3. Compare data if not the same, invalidate the mapping entry, then re-write the data until E-fuse is exhausted
+ bWriteSuccess = TRUE;
+ for(i =0; i<8; i++)
+ {
+ addr = BlkNum * 0x10 ;
+
+ InBuf[0] = addr+2*i;
+ InBuf[1] = 2;
+ InBuf[2] = 0x0;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("addr=%x, buffer[i]=%x,InBuf[2]=%x\n",InBuf[0],pData[i],InBuf[2]));
+ if(pData[i] != InBuf[2])
+ {
+ bWriteSuccess = FALSE;
+ break;
+ }
+ }
+
+ //Step 4. invlidate mapping entry and find a free mapping entry if not succeed
+
+ if (!bWriteSuccess&&Loop<2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess BlkNum = %d\n", BlkNum));
+
+ // the offset of current mapping entry
+ addr = EFUSE_USAGE_MAP_START+BlkNum;
+
+ //find a new mapping entry
+ BlkNum = 0xffff;
+ for (i=EFUSE_USAGE_MAP_START; i<=EFUSE_USAGE_MAP_END; i+=2)
+ {
+ eFusePhysicalReadRegisters(pAd, i, 2, &LogicalAddress);
+ if( (LogicalAddress & 0xff) == 0)
+ {
+ BlkNum = i-EFUSE_USAGE_MAP_START;
+ break;
+ }
+ else if(( (LogicalAddress >> 8) & 0xff) == 0)
+ {
+ if (i != EFUSE_USAGE_MAP_END)
+ {
+ BlkNum = i+1-EFUSE_USAGE_MAP_START;
+ }
+ break;
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin::Not bWriteSuccess new BlkNum = %d\n", BlkNum));
+ if(BlkNum == 0xffff)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("eFuseWriteRegistersFromBin: out of free E-fuse space!!!\n"));
+ return FALSE;
+ }
+
+ //invalidate the original mapping entry if new entry is not found
+ tmpaddr = addr;
+
+ if(addr % 2 != 0)
+ addr = addr -1;
+ InBuf[0] = addr;
+ InBuf[1] = 2;
+
+ eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2);
+
+ // write the logical address
+ if(tmpaddr%2 != 0)
+ {
+ // Invalidate the high byte
+ for (i=8; i<15; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ else
+ {
+ // invalidate the low byte
+ for (i=0; i<8; i++)
+ {
+ if( ( (InBuf[2] >> i) & 0x01) == 0)
+ {
+ InBuf[2] |= (0x1 <<i);
+ break;
+ }
+ }
+ }
+ eFuseWritePhysical(pAd, &InBuf[0], 6, NULL, 0);
+ }
+
+ }
+ while(!bWriteSuccess&&Loop<2);
+
+ return TRUE;
+}
+
+#endif // RT30xx //
+//2008/09/11:KH add to support efuse-->
+
diff --git a/drivers/staging/rt3070/common/md5.c b/drivers/staging/rt3070/common/md5.c
new file mode 100644
index 00000000000..774776b4b8c
--- /dev/null
+++ b/drivers/staging/rt3070/common/md5.c
@@ -0,0 +1,1427 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ md5.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ jan 10-28-03 Initial
+ Rita 11-23-04 Modify MD5 and SHA-1
+ Rita 10-14-05 Modify SHA-1 in big-endian platform
+ */
+#include "../rt_config.h"
+
+/**
+ * md5_mac:
+ * @key: pointer to the key used for MAC generation
+ * @key_len: length of the key in bytes
+ * @data: pointer to the data area for which the MAC is generated
+ * @data_len: length of the data in bytes
+ * @mac: pointer to the buffer holding space for the MAC; the buffer should
+ * have space for 128-bit (16 bytes) MD5 hash value
+ *
+ * md5_mac() determines the message authentication code by using secure hash
+ * MD5(key | data | key).
+ */
+void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
+{
+ MD5_CTX context;
+
+ MD5Init(&context);
+ MD5Update(&context, key, key_len);
+ MD5Update(&context, data, data_len);
+ MD5Update(&context, key, key_len);
+ MD5Final(mac, &context);
+}
+
+/**
+ * hmac_md5:
+ * @key: pointer to the key used for MAC generation
+ * @key_len: length of the key in bytes
+ * @data: pointer to the data area for which the MAC is generated
+ * @data_len: length of the data in bytes
+ * @mac: pointer to the buffer holding space for the MAC; the buffer should
+ * have space for 128-bit (16 bytes) MD5 hash value
+ *
+ * hmac_md5() determines the message authentication code using HMAC-MD5.
+ * This implementation is based on the sample code presented in RFC 2104.
+ */
+void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac)
+{
+ MD5_CTX context;
+ u8 k_ipad[65]; /* inner padding - key XORd with ipad */
+ u8 k_opad[65]; /* outer padding - key XORd with opad */
+ u8 tk[16];
+ int i;
+
+ //assert(key != NULL && data != NULL && mac != NULL);
+
+ /* if key is longer than 64 bytes reset it to key = MD5(key) */
+ if (key_len > 64) {
+ MD5_CTX ttcontext;
+
+ MD5Init(&ttcontext);
+ MD5Update(&ttcontext, key, key_len);
+ MD5Final(tk, &ttcontext);
+ //key=(PUCHAR)ttcontext.buf;
+ key = tk;
+ key_len = 16;
+ }
+
+ /* the HMAC_MD5 transform looks like:
+ *
+ * MD5(K XOR opad, MD5(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected */
+
+ /* start out by storing key in pads */
+ NdisZeroMemory(k_ipad, sizeof(k_ipad));
+ NdisZeroMemory(k_opad, sizeof(k_opad));
+ //assert(key_len < sizeof(k_ipad));
+ NdisMoveMemory(k_ipad, key, key_len);
+ NdisMoveMemory(k_opad, key, key_len);
+
+ /* XOR key with ipad and opad values */
+ for (i = 0; i < 64; i++) {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+
+ /* perform inner MD5 */
+ MD5Init(&context); /* init context for 1st pass */
+ MD5Update(&context, k_ipad, 64); /* start with inner pad */
+ MD5Update(&context, data, data_len); /* then text of datagram */
+ MD5Final(mac, &context); /* finish up 1st pass */
+
+ /* perform outer MD5 */
+ MD5Init(&context); /* init context for 2nd pass */
+ MD5Update(&context, k_opad, 64); /* start with outer pad */
+ MD5Update(&context, mac, 16); /* then results of 1st hash */
+ MD5Final(mac, &context); /* finish up 2nd pass */
+}
+
+#ifndef RT_BIG_ENDIAN
+#define byteReverse(buf, len) /* Nothing */
+#else
+void byteReverse(unsigned char *buf, unsigned longs);
+void byteReverse(unsigned char *buf, unsigned longs)
+{
+ do {
+ *(UINT32 *)buf = SWAP32(*(UINT32 *)buf);
+ buf += 4;
+ } while (--longs);
+}
+#endif
+
+
+/* ========================== MD5 implementation =========================== */
+// four base functions for MD5
+#define MD5_F1(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define MD5_F2(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define MD5_F3(x, y, z) ((x) ^ (y) ^ (z))
+#define MD5_F4(x, y, z) ((y) ^ ((x) | (~z)))
+#define CYCLIC_LEFT_SHIFT(w, s) (((w) << (s)) | ((w) >> (32-(s))))
+
+#define MD5Step(f, w, x, y, z, data, t, s) \
+ ( w += f(x, y, z) + data + t, w = (CYCLIC_LEFT_SHIFT(w, s)) & 0xffffffff, w += x )
+
+
+/*
+ * Function Description:
+ * Initiate MD5 Context satisfied in RFC 1321
+ *
+ * Arguments:
+ * pCtx Pointer to MD5 context
+ *
+ * Return Value:
+ * None
+ */
+VOID MD5Init(MD5_CTX *pCtx)
+{
+ pCtx->Buf[0]=0x67452301;
+ pCtx->Buf[1]=0xefcdab89;
+ pCtx->Buf[2]=0x98badcfe;
+ pCtx->Buf[3]=0x10325476;
+
+ pCtx->LenInBitCount[0]=0;
+ pCtx->LenInBitCount[1]=0;
+}
+
+
+/*
+ * Function Description:
+ * Update MD5 Context, allow of an arrary of octets as the next portion
+ * of the message
+ *
+ * Arguments:
+ * pCtx Pointer to MD5 context
+ * pData Pointer to input data
+ * LenInBytes The length of input data (unit: byte)
+ *
+ * Return Value:
+ * None
+ *
+ * Note:
+ * Called after MD5Init or MD5Update(itself)
+ */
+VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
+{
+
+ UINT32 TfTimes;
+ UINT32 temp;
+ unsigned int i;
+
+ temp = pCtx->LenInBitCount[0];
+
+ pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
+
+ if (pCtx->LenInBitCount[0] < temp)
+ pCtx->LenInBitCount[1]++; //carry in
+
+ pCtx->LenInBitCount[1] += LenInBytes >> 29;
+
+ // mod 64 bytes
+ temp = (temp >> 3) & 0x3f;
+
+ // process lacks of 64-byte data
+ if (temp)
+ {
+ UCHAR *pAds = (UCHAR *) pCtx->Input + temp;
+
+ if ((temp+LenInBytes) < 64)
+ {
+ NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
+ return;
+ }
+
+ NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp);
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+ pData += 64-temp;
+ LenInBytes -= 64-temp;
+ } // end of if (temp)
+
+
+ TfTimes = (LenInBytes >> 6);
+
+ for (i=TfTimes; i>0; i--)
+ {
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ pData += 64;
+ LenInBytes -= 64;
+ } // end of for
+
+ // buffering lacks of 64-byte data
+ if(LenInBytes)
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
+
+}
+
+
+/*
+ * Function Description:
+ * Append padding bits and length of original message in the tail
+ * The message digest has to be completed in the end
+ *
+ * Arguments:
+ * Digest Output of Digest-Message for MD5
+ * pCtx Pointer to MD5 context
+ *
+ * Return Value:
+ * None
+ *
+ * Note:
+ * Called after MD5Update
+ */
+VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx)
+{
+ UCHAR Remainder;
+ UCHAR PadLenInBytes;
+ UCHAR *pAppend=0;
+ unsigned int i;
+
+ Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
+
+ PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
+
+ pAppend = (UCHAR *)pCtx->Input + Remainder;
+
+ // padding bits without crossing block(64-byte based) boundary
+ if (Remainder < 56)
+ {
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
+
+ // add data-length field, from low to high
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
+ }
+
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of if
+
+ // padding bits with crossing block(64-byte based) boundary
+ else
+ {
+ // the first block ===
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
+ PadLenInBytes -= (64 - Remainder - 1);
+
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+
+ // the second block ===
+ NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
+
+ // add data-length field
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[0] >> (i << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[1] >> (i << 3)) & 0xff);
+ }
+
+ byteReverse(pCtx->Input, 16);
+ MD5Transform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of else
+
+
+ NdisMoveMemory((UCHAR *)Digest, (UINT32 *)pCtx->Buf, 16); // output
+ byteReverse((UCHAR *)Digest, 4);
+ NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
+}
+
+
+/*
+ * Function Description:
+ * The central algorithm of MD5, consists of four rounds and sixteen
+ * steps per round
+ *
+ * Arguments:
+ * Buf Buffers of four states (output: 16 bytes)
+ * Mes Input data (input: 64 bytes)
+ *
+ * Return Value:
+ * None
+ *
+ * Note:
+ * Called by MD5Update or MD5Final
+ */
+VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16])
+{
+ UINT32 Reg[4], Temp;
+ unsigned int i;
+
+ static UCHAR LShiftVal[16] =
+ {
+ 7, 12, 17, 22,
+ 5, 9 , 14, 20,
+ 4, 11, 16, 23,
+ 6, 10, 15, 21,
+ };
+
+
+ // [equal to 4294967296*abs(sin(index))]
+ static UINT32 MD5Table[64] =
+ {
+ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
+ 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
+ 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
+ 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
+
+ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
+ 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
+ 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
+ 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
+
+ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
+ 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
+ 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
+ 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
+
+ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
+ 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
+ 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
+ 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
+ };
+
+
+ for (i=0; i<4; i++)
+ Reg[i]=Buf[i];
+
+
+ // 64 steps in MD5 algorithm
+ for (i=0; i<16; i++)
+ {
+ MD5Step(MD5_F1, Reg[0], Reg[1], Reg[2], Reg[3], Mes[i],
+ MD5Table[i], LShiftVal[i & 0x3]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+ for (i=16; i<32; i++)
+ {
+ MD5Step(MD5_F2, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(5*(i & 0xf)+1) & 0xf],
+ MD5Table[i], LShiftVal[(0x1 << 2)+(i & 0x3)]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+ for (i=32; i<48; i++)
+ {
+ MD5Step(MD5_F3, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(3*(i & 0xf)+5) & 0xf],
+ MD5Table[i], LShiftVal[(0x1 << 3)+(i & 0x3)]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+ for (i=48; i<64; i++)
+ {
+ MD5Step(MD5_F4, Reg[0], Reg[1], Reg[2], Reg[3], Mes[(7*(i & 0xf)) & 0xf],
+ MD5Table[i], LShiftVal[(0x3 << 2)+(i & 0x3)]);
+
+ // one-word right shift
+ Temp = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+ }
+
+
+ // (temporary)output
+ for (i=0; i<4; i++)
+ Buf[i] += Reg[i];
+
+}
+
+
+
+/* ========================= SHA-1 implementation ========================== */
+// four base functions for SHA-1
+#define SHA1_F1(b, c, d) (((b) & (c)) | ((~b) & (d)))
+#define SHA1_F2(b, c, d) ((b) ^ (c) ^ (d))
+#define SHA1_F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
+
+
+#define SHA1Step(f, a, b, c, d, e, w, k) \
+ ( e += ( f(b, c, d) + w + k + CYCLIC_LEFT_SHIFT(a, 5)) & 0xffffffff, \
+ b = CYCLIC_LEFT_SHIFT(b, 30) )
+
+//Initiate SHA-1 Context satisfied in RFC 3174
+VOID SHAInit(SHA_CTX *pCtx)
+{
+ pCtx->Buf[0]=0x67452301;
+ pCtx->Buf[1]=0xefcdab89;
+ pCtx->Buf[2]=0x98badcfe;
+ pCtx->Buf[3]=0x10325476;
+ pCtx->Buf[4]=0xc3d2e1f0;
+
+ pCtx->LenInBitCount[0]=0;
+ pCtx->LenInBitCount[1]=0;
+}
+
+/*
+ * Function Description:
+ * Update SHA-1 Context, allow of an arrary of octets as the next
+ * portion of the message
+ *
+ * Arguments:
+ * pCtx Pointer to SHA-1 context
+ * pData Pointer to input data
+ * LenInBytes The length of input data (unit: byte)
+ *
+ * Return Value:
+ * error indicate more than pow(2,64) bits of data
+ *
+ * Note:
+ * Called after SHAInit or SHAUpdate(itself)
+ */
+UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes)
+{
+ UINT32 TfTimes;
+ UINT32 temp1,temp2;
+ unsigned int i;
+ UCHAR err=1;
+
+ temp1 = pCtx->LenInBitCount[0];
+ temp2 = pCtx->LenInBitCount[1];
+
+ pCtx->LenInBitCount[0] = (UINT32) (pCtx->LenInBitCount[0] + (LenInBytes << 3));
+ if (pCtx->LenInBitCount[0] < temp1)
+ pCtx->LenInBitCount[1]++; //carry in
+
+
+ pCtx->LenInBitCount[1] = (UINT32) (pCtx->LenInBitCount[1] +(LenInBytes >> 29));
+ if (pCtx->LenInBitCount[1] < temp2)
+ return (err); //check total length of original data
+
+
+ // mod 64 bytes
+ temp1 = (temp1 >> 3) & 0x3f;
+
+ // process lacks of 64-byte data
+ if (temp1)
+ {
+ UCHAR *pAds = (UCHAR *) pCtx->Input + temp1;
+
+ if ((temp1+LenInBytes) < 64)
+ {
+ NdisMoveMemory(pAds, (UCHAR *)pData, LenInBytes);
+ return (0);
+ }
+
+ NdisMoveMemory(pAds, (UCHAR *)pData, 64-temp1);
+ byteReverse((UCHAR *)pCtx->Input, 16);
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+ pData += 64-temp1;
+ LenInBytes -= 64-temp1;
+ } // end of if (temp1)
+
+
+ TfTimes = (LenInBytes >> 6);
+
+ for (i=TfTimes; i>0; i--)
+ {
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, 64);
+ byteReverse((UCHAR *)pCtx->Input, 16);
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ pData += 64;
+ LenInBytes -= 64;
+ } // end of for
+
+ // buffering lacks of 64-byte data
+ if(LenInBytes)
+ NdisMoveMemory(pCtx->Input, (UCHAR *)pData, LenInBytes);
+
+ return (0);
+
+}
+
+// Append padding bits and length of original message in the tail
+// The message digest has to be completed in the end
+VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20])
+{
+ UCHAR Remainder;
+ UCHAR PadLenInBytes;
+ UCHAR *pAppend=0;
+ unsigned int i;
+
+ Remainder = (UCHAR)((pCtx->LenInBitCount[0] >> 3) & 0x3f);
+
+ pAppend = (UCHAR *)pCtx->Input + Remainder;
+
+ PadLenInBytes = (Remainder < 56) ? (56-Remainder) : (120-Remainder);
+
+ // padding bits without crossing block(64-byte based) boundary
+ if (Remainder < 56)
+ {
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, PadLenInBytes);
+
+ // add data-length field, from high to low
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
+ }
+
+ byteReverse((UCHAR *)pCtx->Input, 16);
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 14);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of if
+
+ // padding bits with crossing block(64-byte based) boundary
+ else
+ {
+ // the first block ===
+ *pAppend = 0x80;
+ PadLenInBytes --;
+
+ NdisZeroMemory((UCHAR *)pCtx->Input + Remainder+1, (64-Remainder-1));
+ PadLenInBytes -= (64 - Remainder - 1);
+
+ byteReverse((UCHAR *)pCtx->Input, 16);
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+
+
+ // the second block ===
+ NdisZeroMemory((UCHAR *)pCtx->Input, PadLenInBytes);
+
+ // add data-length field
+ for (i=0; i<4; i++)
+ {
+ pCtx->Input[56+i] = (UCHAR)((pCtx->LenInBitCount[1] >> ((3-i) << 3)) & 0xff);
+ pCtx->Input[60+i] = (UCHAR)((pCtx->LenInBitCount[0] >> ((3-i) << 3)) & 0xff);
+ }
+
+ byteReverse((UCHAR *)pCtx->Input, 16);
+ NdisZeroMemory((UCHAR *)pCtx->Input + 64, 16);
+ SHATransform(pCtx->Buf, (UINT32 *)pCtx->Input);
+ } // end of else
+
+
+ //Output, bytereverse
+ for (i=0; i<20; i++)
+ {
+ Digest [i] = (UCHAR)(pCtx->Buf[i>>2] >> 8*(3-(i & 0x3)));
+ }
+
+ NdisZeroMemory(pCtx, sizeof(pCtx)); // memory free
+}
+
+
+// The central algorithm of SHA-1, consists of four rounds and
+// twenty steps per round
+VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20])
+{
+ UINT32 Reg[5],Temp;
+ unsigned int i;
+ UINT32 W[80];
+
+ static UINT32 SHA1Table[4] = { 0x5a827999, 0x6ed9eba1,
+ 0x8f1bbcdc, 0xca62c1d6 };
+
+ Reg[0]=Buf[0];
+ Reg[1]=Buf[1];
+ Reg[2]=Buf[2];
+ Reg[3]=Buf[3];
+ Reg[4]=Buf[4];
+
+ //the first octet of a word is stored in the 0th element, bytereverse
+ for(i = 0; i < 16; i++)
+ {
+ W[i] = (Mes[i] >> 24) & 0xff;
+ W[i] |= (Mes[i] >> 8 ) & 0xff00;
+ W[i] |= (Mes[i] << 8 ) & 0xff0000;
+ W[i] |= (Mes[i] << 24) & 0xff000000;
+ }
+
+
+ for (i = 0; i < 64; i++)
+ W[16+i] = CYCLIC_LEFT_SHIFT(W[i] ^ W[2+i] ^ W[8+i] ^ W[13+i], 1);
+
+
+ // 80 steps in SHA-1 algorithm
+ for (i=0; i<80; i++)
+ {
+ if (i<20)
+ SHA1Step(SHA1_F1, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[0]);
+
+ else if (i>=20 && i<40)
+ SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[1]);
+
+ else if (i>=40 && i<60)
+ SHA1Step(SHA1_F3, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[2]);
+
+ else
+ SHA1Step(SHA1_F2, Reg[0], Reg[1], Reg[2], Reg[3], Reg[4],
+ W[i], SHA1Table[3]);
+
+
+ // one-word right shift
+ Temp = Reg[4];
+ Reg[4] = Reg[3];
+ Reg[3] = Reg[2];
+ Reg[2] = Reg[1];
+ Reg[1] = Reg[0];
+ Reg[0] = Temp;
+
+ } // end of for-loop
+
+
+ // (temporary)output
+ for (i=0; i<5; i++)
+ Buf[i] += Reg[i];
+
+}
+
+
+/* ========================= AES En/Decryption ========================== */
+
+/* forward S-box */
+static uint32 FSb[256] =
+{
+ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+ 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+ 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+ 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+ 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+ 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+ 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+ 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+ 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+ 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+ 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+ 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+ 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+ 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+ 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+ 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+ 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/* forward table */
+#define FT \
+\
+ V(C6,63,63,A5), V(F8,7C,7C,84), V(EE,77,77,99), V(F6,7B,7B,8D), \
+ V(FF,F2,F2,0D), V(D6,6B,6B,BD), V(DE,6F,6F,B1), V(91,C5,C5,54), \
+ V(60,30,30,50), V(02,01,01,03), V(CE,67,67,A9), V(56,2B,2B,7D), \
+ V(E7,FE,FE,19), V(B5,D7,D7,62), V(4D,AB,AB,E6), V(EC,76,76,9A), \
+ V(8F,CA,CA,45), V(1F,82,82,9D), V(89,C9,C9,40), V(FA,7D,7D,87), \
+ V(EF,FA,FA,15), V(B2,59,59,EB), V(8E,47,47,C9), V(FB,F0,F0,0B), \
+ V(41,AD,AD,EC), V(B3,D4,D4,67), V(5F,A2,A2,FD), V(45,AF,AF,EA), \
+ V(23,9C,9C,BF), V(53,A4,A4,F7), V(E4,72,72,96), V(9B,C0,C0,5B), \
+ V(75,B7,B7,C2), V(E1,FD,FD,1C), V(3D,93,93,AE), V(4C,26,26,6A), \
+ V(6C,36,36,5A), V(7E,3F,3F,41), V(F5,F7,F7,02), V(83,CC,CC,4F), \
+ V(68,34,34,5C), V(51,A5,A5,F4), V(D1,E5,E5,34), V(F9,F1,F1,08), \
+ V(E2,71,71,93), V(AB,D8,D8,73), V(62,31,31,53), V(2A,15,15,3F), \
+ V(08,04,04,0C), V(95,C7,C7,52), V(46,23,23,65), V(9D,C3,C3,5E), \
+ V(30,18,18,28), V(37,96,96,A1), V(0A,05,05,0F), V(2F,9A,9A,B5), \
+ V(0E,07,07,09), V(24,12,12,36), V(1B,80,80,9B), V(DF,E2,E2,3D), \
+ V(CD,EB,EB,26), V(4E,27,27,69), V(7F,B2,B2,CD), V(EA,75,75,9F), \
+ V(12,09,09,1B), V(1D,83,83,9E), V(58,2C,2C,74), V(34,1A,1A,2E), \
+ V(36,1B,1B,2D), V(DC,6E,6E,B2), V(B4,5A,5A,EE), V(5B,A0,A0,FB), \
+ V(A4,52,52,F6), V(76,3B,3B,4D), V(B7,D6,D6,61), V(7D,B3,B3,CE), \
+ V(52,29,29,7B), V(DD,E3,E3,3E), V(5E,2F,2F,71), V(13,84,84,97), \
+ V(A6,53,53,F5), V(B9,D1,D1,68), V(00,00,00,00), V(C1,ED,ED,2C), \
+ V(40,20,20,60), V(E3,FC,FC,1F), V(79,B1,B1,C8), V(B6,5B,5B,ED), \
+ V(D4,6A,6A,BE), V(8D,CB,CB,46), V(67,BE,BE,D9), V(72,39,39,4B), \
+ V(94,4A,4A,DE), V(98,4C,4C,D4), V(B0,58,58,E8), V(85,CF,CF,4A), \
+ V(BB,D0,D0,6B), V(C5,EF,EF,2A), V(4F,AA,AA,E5), V(ED,FB,FB,16), \
+ V(86,43,43,C5), V(9A,4D,4D,D7), V(66,33,33,55), V(11,85,85,94), \
+ V(8A,45,45,CF), V(E9,F9,F9,10), V(04,02,02,06), V(FE,7F,7F,81), \
+ V(A0,50,50,F0), V(78,3C,3C,44), V(25,9F,9F,BA), V(4B,A8,A8,E3), \
+ V(A2,51,51,F3), V(5D,A3,A3,FE), V(80,40,40,C0), V(05,8F,8F,8A), \
+ V(3F,92,92,AD), V(21,9D,9D,BC), V(70,38,38,48), V(F1,F5,F5,04), \
+ V(63,BC,BC,DF), V(77,B6,B6,C1), V(AF,DA,DA,75), V(42,21,21,63), \
+ V(20,10,10,30), V(E5,FF,FF,1A), V(FD,F3,F3,0E), V(BF,D2,D2,6D), \
+ V(81,CD,CD,4C), V(18,0C,0C,14), V(26,13,13,35), V(C3,EC,EC,2F), \
+ V(BE,5F,5F,E1), V(35,97,97,A2), V(88,44,44,CC), V(2E,17,17,39), \
+ V(93,C4,C4,57), V(55,A7,A7,F2), V(FC,7E,7E,82), V(7A,3D,3D,47), \
+ V(C8,64,64,AC), V(BA,5D,5D,E7), V(32,19,19,2B), V(E6,73,73,95), \
+ V(C0,60,60,A0), V(19,81,81,98), V(9E,4F,4F,D1), V(A3,DC,DC,7F), \
+ V(44,22,22,66), V(54,2A,2A,7E), V(3B,90,90,AB), V(0B,88,88,83), \
+ V(8C,46,46,CA), V(C7,EE,EE,29), V(6B,B8,B8,D3), V(28,14,14,3C), \
+ V(A7,DE,DE,79), V(BC,5E,5E,E2), V(16,0B,0B,1D), V(AD,DB,DB,76), \
+ V(DB,E0,E0,3B), V(64,32,32,56), V(74,3A,3A,4E), V(14,0A,0A,1E), \
+ V(92,49,49,DB), V(0C,06,06,0A), V(48,24,24,6C), V(B8,5C,5C,E4), \
+ V(9F,C2,C2,5D), V(BD,D3,D3,6E), V(43,AC,AC,EF), V(C4,62,62,A6), \
+ V(39,91,91,A8), V(31,95,95,A4), V(D3,E4,E4,37), V(F2,79,79,8B), \
+ V(D5,E7,E7,32), V(8B,C8,C8,43), V(6E,37,37,59), V(DA,6D,6D,B7), \
+ V(01,8D,8D,8C), V(B1,D5,D5,64), V(9C,4E,4E,D2), V(49,A9,A9,E0), \
+ V(D8,6C,6C,B4), V(AC,56,56,FA), V(F3,F4,F4,07), V(CF,EA,EA,25), \
+ V(CA,65,65,AF), V(F4,7A,7A,8E), V(47,AE,AE,E9), V(10,08,08,18), \
+ V(6F,BA,BA,D5), V(F0,78,78,88), V(4A,25,25,6F), V(5C,2E,2E,72), \
+ V(38,1C,1C,24), V(57,A6,A6,F1), V(73,B4,B4,C7), V(97,C6,C6,51), \
+ V(CB,E8,E8,23), V(A1,DD,DD,7C), V(E8,74,74,9C), V(3E,1F,1F,21), \
+ V(96,4B,4B,DD), V(61,BD,BD,DC), V(0D,8B,8B,86), V(0F,8A,8A,85), \
+ V(E0,70,70,90), V(7C,3E,3E,42), V(71,B5,B5,C4), V(CC,66,66,AA), \
+ V(90,48,48,D8), V(06,03,03,05), V(F7,F6,F6,01), V(1C,0E,0E,12), \
+ V(C2,61,61,A3), V(6A,35,35,5F), V(AE,57,57,F9), V(69,B9,B9,D0), \
+ V(17,86,86,91), V(99,C1,C1,58), V(3A,1D,1D,27), V(27,9E,9E,B9), \
+ V(D9,E1,E1,38), V(EB,F8,F8,13), V(2B,98,98,B3), V(22,11,11,33), \
+ V(D2,69,69,BB), V(A9,D9,D9,70), V(07,8E,8E,89), V(33,94,94,A7), \
+ V(2D,9B,9B,B6), V(3C,1E,1E,22), V(15,87,87,92), V(C9,E9,E9,20), \
+ V(87,CE,CE,49), V(AA,55,55,FF), V(50,28,28,78), V(A5,DF,DF,7A), \
+ V(03,8C,8C,8F), V(59,A1,A1,F8), V(09,89,89,80), V(1A,0D,0D,17), \
+ V(65,BF,BF,DA), V(D7,E6,E6,31), V(84,42,42,C6), V(D0,68,68,B8), \
+ V(82,41,41,C3), V(29,99,99,B0), V(5A,2D,2D,77), V(1E,0F,0F,11), \
+ V(7B,B0,B0,CB), V(A8,54,54,FC), V(6D,BB,BB,D6), V(2C,16,16,3A)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static uint32 FT0[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static uint32 FT1[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static uint32 FT2[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static uint32 FT3[256] = { FT };
+#undef V
+
+#undef FT
+
+/* reverse S-box */
+
+static uint32 RSb[256] =
+{
+ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+ 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+ 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+ 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+ 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+ 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+ 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+ 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+ 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+ 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+ 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+ 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+ 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+ 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+ 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+ 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+ 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/* reverse table */
+
+#define RT \
+\
+ V(51,F4,A7,50), V(7E,41,65,53), V(1A,17,A4,C3), V(3A,27,5E,96), \
+ V(3B,AB,6B,CB), V(1F,9D,45,F1), V(AC,FA,58,AB), V(4B,E3,03,93), \
+ V(20,30,FA,55), V(AD,76,6D,F6), V(88,CC,76,91), V(F5,02,4C,25), \
+ V(4F,E5,D7,FC), V(C5,2A,CB,D7), V(26,35,44,80), V(B5,62,A3,8F), \
+ V(DE,B1,5A,49), V(25,BA,1B,67), V(45,EA,0E,98), V(5D,FE,C0,E1), \
+ V(C3,2F,75,02), V(81,4C,F0,12), V(8D,46,97,A3), V(6B,D3,F9,C6), \
+ V(03,8F,5F,E7), V(15,92,9C,95), V(BF,6D,7A,EB), V(95,52,59,DA), \
+ V(D4,BE,83,2D), V(58,74,21,D3), V(49,E0,69,29), V(8E,C9,C8,44), \
+ V(75,C2,89,6A), V(F4,8E,79,78), V(99,58,3E,6B), V(27,B9,71,DD), \
+ V(BE,E1,4F,B6), V(F0,88,AD,17), V(C9,20,AC,66), V(7D,CE,3A,B4), \
+ V(63,DF,4A,18), V(E5,1A,31,82), V(97,51,33,60), V(62,53,7F,45), \
+ V(B1,64,77,E0), V(BB,6B,AE,84), V(FE,81,A0,1C), V(F9,08,2B,94), \
+ V(70,48,68,58), V(8F,45,FD,19), V(94,DE,6C,87), V(52,7B,F8,B7), \
+ V(AB,73,D3,23), V(72,4B,02,E2), V(E3,1F,8F,57), V(66,55,AB,2A), \
+ V(B2,EB,28,07), V(2F,B5,C2,03), V(86,C5,7B,9A), V(D3,37,08,A5), \
+ V(30,28,87,F2), V(23,BF,A5,B2), V(02,03,6A,BA), V(ED,16,82,5C), \
+ V(8A,CF,1C,2B), V(A7,79,B4,92), V(F3,07,F2,F0), V(4E,69,E2,A1), \
+ V(65,DA,F4,CD), V(06,05,BE,D5), V(D1,34,62,1F), V(C4,A6,FE,8A), \
+ V(34,2E,53,9D), V(A2,F3,55,A0), V(05,8A,E1,32), V(A4,F6,EB,75), \
+ V(0B,83,EC,39), V(40,60,EF,AA), V(5E,71,9F,06), V(BD,6E,10,51), \
+ V(3E,21,8A,F9), V(96,DD,06,3D), V(DD,3E,05,AE), V(4D,E6,BD,46), \
+ V(91,54,8D,B5), V(71,C4,5D,05), V(04,06,D4,6F), V(60,50,15,FF), \
+ V(19,98,FB,24), V(D6,BD,E9,97), V(89,40,43,CC), V(67,D9,9E,77), \
+ V(B0,E8,42,BD), V(07,89,8B,88), V(E7,19,5B,38), V(79,C8,EE,DB), \
+ V(A1,7C,0A,47), V(7C,42,0F,E9), V(F8,84,1E,C9), V(00,00,00,00), \
+ V(09,80,86,83), V(32,2B,ED,48), V(1E,11,70,AC), V(6C,5A,72,4E), \
+ V(FD,0E,FF,FB), V(0F,85,38,56), V(3D,AE,D5,1E), V(36,2D,39,27), \
+ V(0A,0F,D9,64), V(68,5C,A6,21), V(9B,5B,54,D1), V(24,36,2E,3A), \
+ V(0C,0A,67,B1), V(93,57,E7,0F), V(B4,EE,96,D2), V(1B,9B,91,9E), \
+ V(80,C0,C5,4F), V(61,DC,20,A2), V(5A,77,4B,69), V(1C,12,1A,16), \
+ V(E2,93,BA,0A), V(C0,A0,2A,E5), V(3C,22,E0,43), V(12,1B,17,1D), \
+ V(0E,09,0D,0B), V(F2,8B,C7,AD), V(2D,B6,A8,B9), V(14,1E,A9,C8), \
+ V(57,F1,19,85), V(AF,75,07,4C), V(EE,99,DD,BB), V(A3,7F,60,FD), \
+ V(F7,01,26,9F), V(5C,72,F5,BC), V(44,66,3B,C5), V(5B,FB,7E,34), \
+ V(8B,43,29,76), V(CB,23,C6,DC), V(B6,ED,FC,68), V(B8,E4,F1,63), \
+ V(D7,31,DC,CA), V(42,63,85,10), V(13,97,22,40), V(84,C6,11,20), \
+ V(85,4A,24,7D), V(D2,BB,3D,F8), V(AE,F9,32,11), V(C7,29,A1,6D), \
+ V(1D,9E,2F,4B), V(DC,B2,30,F3), V(0D,86,52,EC), V(77,C1,E3,D0), \
+ V(2B,B3,16,6C), V(A9,70,B9,99), V(11,94,48,FA), V(47,E9,64,22), \
+ V(A8,FC,8C,C4), V(A0,F0,3F,1A), V(56,7D,2C,D8), V(22,33,90,EF), \
+ V(87,49,4E,C7), V(D9,38,D1,C1), V(8C,CA,A2,FE), V(98,D4,0B,36), \
+ V(A6,F5,81,CF), V(A5,7A,DE,28), V(DA,B7,8E,26), V(3F,AD,BF,A4), \
+ V(2C,3A,9D,E4), V(50,78,92,0D), V(6A,5F,CC,9B), V(54,7E,46,62), \
+ V(F6,8D,13,C2), V(90,D8,B8,E8), V(2E,39,F7,5E), V(82,C3,AF,F5), \
+ V(9F,5D,80,BE), V(69,D0,93,7C), V(6F,D5,2D,A9), V(CF,25,12,B3), \
+ V(C8,AC,99,3B), V(10,18,7D,A7), V(E8,9C,63,6E), V(DB,3B,BB,7B), \
+ V(CD,26,78,09), V(6E,59,18,F4), V(EC,9A,B7,01), V(83,4F,9A,A8), \
+ V(E6,95,6E,65), V(AA,FF,E6,7E), V(21,BC,CF,08), V(EF,15,E8,E6), \
+ V(BA,E7,9B,D9), V(4A,6F,36,CE), V(EA,9F,09,D4), V(29,B0,7C,D6), \
+ V(31,A4,B2,AF), V(2A,3F,23,31), V(C6,A5,94,30), V(35,A2,66,C0), \
+ V(74,4E,BC,37), V(FC,82,CA,A6), V(E0,90,D0,B0), V(33,A7,D8,15), \
+ V(F1,04,98,4A), V(41,EC,DA,F7), V(7F,CD,50,0E), V(17,91,F6,2F), \
+ V(76,4D,D6,8D), V(43,EF,B0,4D), V(CC,AA,4D,54), V(E4,96,04,DF), \
+ V(9E,D1,B5,E3), V(4C,6A,88,1B), V(C1,2C,1F,B8), V(46,65,51,7F), \
+ V(9D,5E,EA,04), V(01,8C,35,5D), V(FA,87,74,73), V(FB,0B,41,2E), \
+ V(B3,67,1D,5A), V(92,DB,D2,52), V(E9,10,56,33), V(6D,D6,47,13), \
+ V(9A,D7,61,8C), V(37,A1,0C,7A), V(59,F8,14,8E), V(EB,13,3C,89), \
+ V(CE,A9,27,EE), V(B7,61,C9,35), V(E1,1C,E5,ED), V(7A,47,B1,3C), \
+ V(9C,D2,DF,59), V(55,F2,73,3F), V(18,14,CE,79), V(73,C7,37,BF), \
+ V(53,F7,CD,EA), V(5F,FD,AA,5B), V(DF,3D,6F,14), V(78,44,DB,86), \
+ V(CA,AF,F3,81), V(B9,68,C4,3E), V(38,24,34,2C), V(C2,A3,40,5F), \
+ V(16,1D,C3,72), V(BC,E2,25,0C), V(28,3C,49,8B), V(FF,0D,95,41), \
+ V(39,A8,01,71), V(08,0C,B3,DE), V(D8,B4,E4,9C), V(64,56,C1,90), \
+ V(7B,CB,84,61), V(D5,32,B6,70), V(48,6C,5C,74), V(D0,B8,57,42)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static uint32 RT0[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static uint32 RT1[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static uint32 RT2[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static uint32 RT3[256] = { RT };
+#undef V
+
+#undef RT
+
+/* round constants */
+
+static uint32 RCON[10] =
+{
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000,
+ 0x1B000000, 0x36000000
+};
+
+/* key schedule tables */
+
+static int KT_init = 1;
+
+static uint32 KT0[256];
+static uint32 KT1[256];
+static uint32 KT2[256];
+static uint32 KT3[256];
+
+/* platform-independant 32-bit integer manipulation macros */
+
+#define GET_UINT32(n,b,i) \
+{ \
+ (n) = ( (uint32) (b)[(i) ] << 24 ) \
+ | ( (uint32) (b)[(i) + 1] << 16 ) \
+ | ( (uint32) (b)[(i) + 2] << 8 ) \
+ | ( (uint32) (b)[(i) + 3] ); \
+}
+
+#define PUT_UINT32(n,b,i) \
+{ \
+ (b)[(i) ] = (uint8) ( (n) >> 24 ); \
+ (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \
+ (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \
+ (b)[(i) + 3] = (uint8) ( (n) ); \
+}
+
+/* AES key scheduling routine */
+
+int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits )
+{
+ int i;
+ uint32 *RK, *SK;
+
+ switch( nbits )
+ {
+ case 128: ctx->nr = 10; break;
+ case 192: ctx->nr = 12; break;
+ case 256: ctx->nr = 14; break;
+ default : return( 1 );
+ }
+
+ RK = ctx->erk;
+
+ for( i = 0; i < (nbits >> 5); i++ )
+ {
+ GET_UINT32( RK[i], key, i * 4 );
+ }
+
+ /* setup encryption round keys */
+
+ switch( nbits )
+ {
+ case 128:
+
+ for( i = 0; i < 10; i++, RK += 4 )
+ {
+ RK[4] = RK[0] ^ RCON[i] ^
+ ( FSb[ (uint8) ( RK[3] >> 16 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[3] >> 8 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[3] ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[3] >> 24 ) ] );
+
+ RK[5] = RK[1] ^ RK[4];
+ RK[6] = RK[2] ^ RK[5];
+ RK[7] = RK[3] ^ RK[6];
+ }
+ break;
+
+ case 192:
+
+ for( i = 0; i < 8; i++, RK += 6 )
+ {
+ RK[6] = RK[0] ^ RCON[i] ^
+ ( FSb[ (uint8) ( RK[5] >> 16 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[5] >> 8 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[5] ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[5] >> 24 ) ] );
+
+ RK[7] = RK[1] ^ RK[6];
+ RK[8] = RK[2] ^ RK[7];
+ RK[9] = RK[3] ^ RK[8];
+ RK[10] = RK[4] ^ RK[9];
+ RK[11] = RK[5] ^ RK[10];
+ }
+ break;
+
+ case 256:
+
+ for( i = 0; i < 7; i++, RK += 8 )
+ {
+ RK[8] = RK[0] ^ RCON[i] ^
+ ( FSb[ (uint8) ( RK[7] >> 16 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[7] >> 8 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[7] ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[7] >> 24 ) ] );
+
+ RK[9] = RK[1] ^ RK[8];
+ RK[10] = RK[2] ^ RK[9];
+ RK[11] = RK[3] ^ RK[10];
+
+ RK[12] = RK[4] ^
+ ( FSb[ (uint8) ( RK[11] >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( RK[11] >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( RK[11] >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( RK[11] ) ] );
+
+ RK[13] = RK[5] ^ RK[12];
+ RK[14] = RK[6] ^ RK[13];
+ RK[15] = RK[7] ^ RK[14];
+ }
+ break;
+ }
+
+ /* setup decryption round keys */
+
+ if( KT_init )
+ {
+ for( i = 0; i < 256; i++ )
+ {
+ KT0[i] = RT0[ FSb[i] ];
+ KT1[i] = RT1[ FSb[i] ];
+ KT2[i] = RT2[ FSb[i] ];
+ KT3[i] = RT3[ FSb[i] ];
+ }
+
+ KT_init = 0;
+ }
+
+ SK = ctx->drk;
+
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+
+ for( i = 1; i < ctx->nr; i++ )
+ {
+ RK -= 8;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+
+ *SK++ = KT0[ (uint8) ( *RK >> 24 ) ] ^
+ KT1[ (uint8) ( *RK >> 16 ) ] ^
+ KT2[ (uint8) ( *RK >> 8 ) ] ^
+ KT3[ (uint8) ( *RK ) ]; RK++;
+ }
+
+ RK -= 8;
+
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+ *SK++ = *RK++;
+
+ return( 0 );
+}
+
+/* AES 128-bit block encryption routine */
+
+void rtmp_aes_encrypt(aes_context *ctx, uint8 input[16], uint8 output[16] )
+{
+ uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->erk;
+ GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
+ GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
+ GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
+ GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
+
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+{ \
+ RK += 4; \
+ \
+ X0 = RK[0] ^ FT0[ (uint8) ( Y0 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y1 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y2 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y3 ) ]; \
+ \
+ X1 = RK[1] ^ FT0[ (uint8) ( Y1 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y2 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y3 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y0 ) ]; \
+ \
+ X2 = RK[2] ^ FT0[ (uint8) ( Y2 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y3 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y0 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y1 ) ]; \
+ \
+ X3 = RK[3] ^ FT0[ (uint8) ( Y3 >> 24 ) ] ^ \
+ FT1[ (uint8) ( Y0 >> 16 ) ] ^ \
+ FT2[ (uint8) ( Y1 >> 8 ) ] ^ \
+ FT3[ (uint8) ( Y2 ) ]; \
+}
+
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
+
+ if( ctx->nr > 10 )
+ {
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
+ }
+
+ if( ctx->nr > 12 )
+ {
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
+ }
+
+ /* last round */
+
+ RK += 4;
+
+ X0 = RK[0] ^ ( FSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y3 ) ] );
+
+ X1 = RK[1] ^ ( FSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y0 ) ] );
+
+ X2 = RK[2] ^ ( FSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y1 ) ] );
+
+ X3 = RK[3] ^ ( FSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
+ ( FSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
+ ( FSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
+ ( FSb[ (uint8) ( Y2 ) ] );
+
+ PUT_UINT32( X0, output, 0 );
+ PUT_UINT32( X1, output, 4 );
+ PUT_UINT32( X2, output, 8 );
+ PUT_UINT32( X3, output, 12 );
+}
+
+/* AES 128-bit block decryption routine */
+
+void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] )
+{
+ uint32 *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+ RK = ctx->drk;
+
+ GET_UINT32( X0, input, 0 ); X0 ^= RK[0];
+ GET_UINT32( X1, input, 4 ); X1 ^= RK[1];
+ GET_UINT32( X2, input, 8 ); X2 ^= RK[2];
+ GET_UINT32( X3, input, 12 ); X3 ^= RK[3];
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+{ \
+ RK += 4; \
+ \
+ X0 = RK[0] ^ RT0[ (uint8) ( Y0 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y3 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y2 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y1 ) ]; \
+ \
+ X1 = RK[1] ^ RT0[ (uint8) ( Y1 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y0 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y3 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y2 ) ]; \
+ \
+ X2 = RK[2] ^ RT0[ (uint8) ( Y2 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y1 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y0 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y3 ) ]; \
+ \
+ X3 = RK[3] ^ RT0[ (uint8) ( Y3 >> 24 ) ] ^ \
+ RT1[ (uint8) ( Y2 >> 16 ) ] ^ \
+ RT2[ (uint8) ( Y1 >> 8 ) ] ^ \
+ RT3[ (uint8) ( Y0 ) ]; \
+}
+
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 1 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 2 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 3 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 4 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 5 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 6 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 7 */
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 8 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 9 */
+
+ if( ctx->nr > 10 )
+ {
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 10 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 11 */
+ }
+
+ if( ctx->nr > 12 )
+ {
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); /* round 12 */
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); /* round 13 */
+ }
+
+ /* last round */
+
+ RK += 4;
+
+ X0 = RK[0] ^ ( RSb[ (uint8) ( Y0 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y3 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y2 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y1 ) ] );
+
+ X1 = RK[1] ^ ( RSb[ (uint8) ( Y1 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y0 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y3 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y2 ) ] );
+
+ X2 = RK[2] ^ ( RSb[ (uint8) ( Y2 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y1 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y0 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y3 ) ] );
+
+ X3 = RK[3] ^ ( RSb[ (uint8) ( Y3 >> 24 ) ] << 24 ) ^
+ ( RSb[ (uint8) ( Y2 >> 16 ) ] << 16 ) ^
+ ( RSb[ (uint8) ( Y1 >> 8 ) ] << 8 ) ^
+ ( RSb[ (uint8) ( Y0 ) ] );
+
+ PUT_UINT32( X0, output, 0 );
+ PUT_UINT32( X1, output, 4 );
+ PUT_UINT32( X2, output, 8 );
+ PUT_UINT32( X3, output, 12 );
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ SHA1 function
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID HMAC_SHA1(
+ IN UCHAR *text,
+ IN UINT text_len,
+ IN UCHAR *key,
+ IN UINT key_len,
+ IN UCHAR *digest)
+{
+ SHA_CTX context;
+ UCHAR k_ipad[65]; /* inner padding - key XORd with ipad */
+ UCHAR k_opad[65]; /* outer padding - key XORd with opad */
+ INT i;
+
+ // if key is longer than 64 bytes reset it to key=SHA1(key)
+ if (key_len > 64)
+ {
+ SHA_CTX tctx;
+ SHAInit(&tctx);
+ SHAUpdate(&tctx, key, key_len);
+ SHAFinal(&tctx, key);
+ key_len = 20;
+ }
+ NdisZeroMemory(k_ipad, sizeof(k_ipad));
+ NdisZeroMemory(k_opad, sizeof(k_opad));
+ NdisMoveMemory(k_ipad, key, key_len);
+ NdisMoveMemory(k_opad, key, key_len);
+
+ // XOR key with ipad and opad values
+ for (i = 0; i < 64; i++)
+ {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+
+ // perform inner SHA1
+ SHAInit(&context); /* init context for 1st pass */
+ SHAUpdate(&context, k_ipad, 64); /* start with inner pad */
+ SHAUpdate(&context, text, text_len); /* then text of datagram */
+ SHAFinal(&context, digest); /* finish up 1st pass */
+
+ //perform outer SHA1
+ SHAInit(&context); /* init context for 2nd pass */
+ SHAUpdate(&context, k_opad, 64); /* start with outer pad */
+ SHAUpdate(&context, digest, 20); /* then results of 1st hash */
+ SHAFinal(&context, digest); /* finish up 2nd pass */
+
+}
+
+/*
+* F(P, S, c, i) = U1 xor U2 xor ... Uc
+* U1 = PRF(P, S || Int(i))
+* U2 = PRF(P, U1)
+* Uc = PRF(P, Uc-1)
+*/
+
+void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output)
+{
+ unsigned char digest[36], digest1[SHA_DIGEST_LEN];
+ int i, j;
+
+ /* U1 = PRF(P, S || int(i)) */
+ memcpy(digest, ssid, ssidlength);
+ digest[ssidlength] = (unsigned char)((count>>24) & 0xff);
+ digest[ssidlength+1] = (unsigned char)((count>>16) & 0xff);
+ digest[ssidlength+2] = (unsigned char)((count>>8) & 0xff);
+ digest[ssidlength+3] = (unsigned char)(count & 0xff);
+ HMAC_SHA1(digest, ssidlength+4, (unsigned char*) password, (int) strlen(password), digest1); // for WPA update
+
+ /* output = U1 */
+ memcpy(output, digest1, SHA_DIGEST_LEN);
+
+ for (i = 1; i < iterations; i++)
+ {
+ /* Un = PRF(P, Un-1) */
+ HMAC_SHA1(digest1, SHA_DIGEST_LEN, (unsigned char*) password, (int) strlen(password), digest); // for WPA update
+ memcpy(digest1, digest, SHA_DIGEST_LEN);
+
+ /* output = output xor Un */
+ for (j = 0; j < SHA_DIGEST_LEN; j++)
+ {
+ output[j] ^= digest[j];
+ }
+ }
+}
+/*
+* password - ascii string up to 63 characters in length
+* ssid - octet string up to 32 octets
+* ssidlength - length of ssid in octets
+* output must be 40 octets in length and outputs 256 bits of key
+*/
+int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output)
+{
+ if ((strlen(password) > 63) || (ssidlength > 32))
+ return 0;
+
+ F(password, ssid, ssidlength, 4096, 1, output);
+ F(password, ssid, ssidlength, 4096, 2, &output[SHA_DIGEST_LEN]);
+ return 1;
+}
+
+
diff --git a/drivers/staging/rt3070/common/mlme.c b/drivers/staging/rt3070/common/mlme.c
new file mode 100644
index 00000000000..0ffbfa36699
--- /dev/null
+++ b/drivers/staging/rt3070/common/mlme.c
@@ -0,0 +1,9136 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ mlme.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-08-25 Modify from RT2500 code base
+ John Chang 2004-09-06 modified for RT2600
+*/
+
+#include "../rt_config.h"
+#include <stdarg.h>
+
+UCHAR CISCO_OUI[] = {0x00, 0x40, 0x96};
+
+UCHAR WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
+UCHAR RSN_OUI[] = {0x00, 0x0f, 0xac};
+UCHAR WAPI_OUI[] = {0x00, 0x14, 0x72};
+UCHAR WME_INFO_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
+UCHAR WME_PARM_ELEM[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
+UCHAR Ccx2QosInfo[] = {0x00, 0x40, 0x96, 0x04};
+UCHAR RALINK_OUI[] = {0x00, 0x0c, 0x43};
+UCHAR BROADCOM_OUI[] = {0x00, 0x90, 0x4c};
+UCHAR WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+UCHAR PRE_N_HT_OUI[] = {0x00, 0x90, 0x4c};
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+UCHAR RateSwitchTable[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x11, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+ 0x04, 0x21, 0, 30, 50,
+ 0x05, 0x21, 1, 20, 50,
+ 0x06, 0x21, 2, 20, 50,
+ 0x07, 0x21, 3, 15, 50,
+ 0x08, 0x21, 4, 15, 30,
+ 0x09, 0x21, 5, 10, 25,
+ 0x0a, 0x21, 6, 8, 25,
+ 0x0b, 0x21, 7, 8, 25,
+ 0x0c, 0x20, 12, 15, 30,
+ 0x0d, 0x20, 13, 8, 20,
+ 0x0e, 0x20, 14, 8, 20,
+ 0x0f, 0x20, 15, 8, 25,
+ 0x10, 0x22, 15, 8, 25,
+ 0x11, 0x00, 0, 0, 0,
+ 0x12, 0x00, 0, 0, 0,
+ 0x13, 0x00, 0, 0, 0,
+ 0x14, 0x00, 0, 0, 0,
+ 0x15, 0x00, 0, 0, 0,
+ 0x16, 0x00, 0, 0, 0,
+ 0x17, 0x00, 0, 0, 0,
+ 0x18, 0x00, 0, 0, 0,
+ 0x19, 0x00, 0, 0, 0,
+ 0x1a, 0x00, 0, 0, 0,
+ 0x1b, 0x00, 0, 0, 0,
+ 0x1c, 0x00, 0, 0, 0,
+ 0x1d, 0x00, 0, 0, 0,
+ 0x1e, 0x00, 0, 0, 0,
+ 0x1f, 0x00, 0, 0, 0,
+};
+
+UCHAR RateSwitchTable11B[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x04, 0x03, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+};
+
+UCHAR RateSwitchTable11BG[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+ 0x04, 0x10, 2, 20, 35,
+ 0x05, 0x10, 3, 16, 35,
+ 0x06, 0x10, 4, 10, 25,
+ 0x07, 0x10, 5, 16, 25,
+ 0x08, 0x10, 6, 10, 25,
+ 0x09, 0x10, 7, 10, 13,
+};
+
+UCHAR RateSwitchTable11G[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x08, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x10, 0, 20, 101,
+ 0x01, 0x10, 1, 20, 35,
+ 0x02, 0x10, 2, 20, 35,
+ 0x03, 0x10, 3, 16, 35,
+ 0x04, 0x10, 4, 10, 25,
+ 0x05, 0x10, 5, 16, 25,
+ 0x06, 0x10, 6, 10, 25,
+ 0x07, 0x10, 7, 10, 13,
+};
+
+#ifdef DOT11_N_SUPPORT
+UCHAR RateSwitchTable11N1S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x09, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 10, 25,
+ 0x06, 0x21, 6, 8, 14,
+ 0x07, 0x21, 7, 8, 14,
+ 0x08, 0x23, 7, 8, 14,
+};
+
+UCHAR RateSwitchTable11N2S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11N3S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11N2SForABand[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0b, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x20, 12, 15, 30,
+ 0x07, 0x20, 13, 8, 20,
+ 0x08, 0x20, 14, 8, 20,
+ 0x09, 0x20, 15, 8, 25,
+ 0x0a, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11N3SForABand[] = { // 3*3
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0b, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30, 101,
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x20, 12, 15, 30,
+ 0x07, 0x20, 13, 8, 20,
+ 0x08, 0x20, 14, 8, 20,
+ 0x09, 0x20, 15, 8, 25,
+ 0x0a, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11BGN1S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0d, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x00, 0, 40, 101,
+ 0x01, 0x00, 1, 40, 50,
+ 0x02, 0x00, 2, 35, 45,
+ 0x03, 0x00, 3, 20, 45,
+ 0x04, 0x21, 0, 30,101, //50
+ 0x05, 0x21, 1, 20, 50,
+ 0x06, 0x21, 2, 20, 50,
+ 0x07, 0x21, 3, 15, 50,
+ 0x08, 0x21, 4, 15, 30,
+ 0x09, 0x21, 5, 10, 25,
+ 0x0a, 0x21, 6, 8, 14,
+ 0x0b, 0x21, 7, 8, 14,
+ 0x0c, 0x23, 7, 8, 14,
+};
+
+UCHAR RateSwitchTable11BGN2S[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11BGN3S[] = { // 3*3
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0a, 0x00, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 20, 50,
+ 0x04, 0x21, 4, 15, 50,
+#if 1
+ 0x05, 0x20, 20, 15, 30,
+ 0x06, 0x20, 21, 8, 20,
+ 0x07, 0x20, 22, 8, 20,
+ 0x08, 0x20, 23, 8, 25,
+ 0x09, 0x22, 23, 8, 25,
+#else // for RT2860 2*3 test
+ 0x05, 0x20, 12, 15, 30,
+ 0x06, 0x20, 13, 8, 20,
+ 0x07, 0x20, 14, 8, 20,
+ 0x08, 0x20, 15, 8, 25,
+ 0x09, 0x22, 15, 8, 25,
+#endif
+};
+
+UCHAR RateSwitchTable11BGN2SForABand[] = {
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0b, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x20, 12, 15, 30,
+ 0x07, 0x20, 13, 8, 20,
+ 0x08, 0x20, 14, 8, 20,
+ 0x09, 0x20, 15, 8, 25,
+ 0x0a, 0x22, 15, 8, 25,
+};
+
+UCHAR RateSwitchTable11BGN3SForABand[] = { // 3*3
+// Item No. Mode Curr-MCS TrainUp TrainDown // Mode- Bit0: STBC, Bit1: Short GI, Bit4,5: Mode(0:CCK, 1:OFDM, 2:HT Mix, 3:HT GF)
+ 0x0c, 0x09, 0, 0, 0, // Initial used item after association
+ 0x00, 0x21, 0, 30,101, //50
+ 0x01, 0x21, 1, 20, 50,
+ 0x02, 0x21, 2, 20, 50,
+ 0x03, 0x21, 3, 15, 50,
+ 0x04, 0x21, 4, 15, 30,
+ 0x05, 0x21, 5, 15, 30,
+ 0x06, 0x21, 12, 15, 30,
+ 0x07, 0x20, 20, 15, 30,
+ 0x08, 0x20, 21, 8, 20,
+ 0x09, 0x20, 22, 8, 20,
+ 0x0a, 0x20, 23, 8, 25,
+ 0x0b, 0x22, 23, 8, 25,
+};
+#endif // DOT11_N_SUPPORT //
+
+PUCHAR ReasonString[] = {
+ /* 0 */ "Reserved",
+ /* 1 */ "Unspecified Reason",
+ /* 2 */ "Previous Auth no longer valid",
+ /* 3 */ "STA is leaving / has left",
+ /* 4 */ "DIS-ASSOC due to inactivity",
+ /* 5 */ "AP unable to hanle all associations",
+ /* 6 */ "class 2 error",
+ /* 7 */ "class 3 error",
+ /* 8 */ "STA is leaving / has left",
+ /* 9 */ "require auth before assoc/re-assoc",
+ /* 10 */ "Reserved",
+ /* 11 */ "Reserved",
+ /* 12 */ "Reserved",
+ /* 13 */ "invalid IE",
+ /* 14 */ "MIC error",
+ /* 15 */ "4-way handshake timeout",
+ /* 16 */ "2-way (group key) handshake timeout",
+ /* 17 */ "4-way handshake IE diff among AssosReq/Rsp/Beacon",
+ /* 18 */
+};
+
+extern UCHAR OfdmRateToRxwiMCS[];
+// since RT61 has better RX sensibility, we have to limit TX ACK rate not to exceed our normal data TX rate.
+// otherwise the WLAN peer may not be able to receive the ACK thus downgrade its data TX rate
+ULONG BasicRateMask[12] = {0xfffff001 /* 1-Mbps */, 0xfffff003 /* 2 Mbps */, 0xfffff007 /* 5.5 */, 0xfffff00f /* 11 */,
+ 0xfffff01f /* 6 */ , 0xfffff03f /* 9 */ , 0xfffff07f /* 12 */ , 0xfffff0ff /* 18 */,
+ 0xfffff1ff /* 24 */ , 0xfffff3ff /* 36 */ , 0xfffff7ff /* 48 */ , 0xffffffff /* 54 */};
+
+UCHAR MULTICAST_ADDR[MAC_ADDR_LEN] = {0x1, 0x00, 0x00, 0x00, 0x00, 0x00};
+UCHAR BROADCAST_ADDR[MAC_ADDR_LEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+// e.g. RssiSafeLevelForTxRate[RATE_36]" means if the current RSSI is greater than
+// this value, then it's quaranteed capable of operating in 36 mbps TX rate in
+// clean environment.
+// TxRate: 1 2 5.5 11 6 9 12 18 24 36 48 54 72 100
+CHAR RssiSafeLevelForTxRate[] ={ -92, -91, -90, -87, -88, -86, -85, -83, -81, -78, -72, -71, -40, -40 };
+
+UCHAR RateIdToMbps[] = { 1, 2, 5, 11, 6, 9, 12, 18, 24, 36, 48, 54, 72, 100};
+USHORT RateIdTo500Kbps[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 144, 200};
+
+UCHAR SsidIe = IE_SSID;
+UCHAR SupRateIe = IE_SUPP_RATES;
+UCHAR ExtRateIe = IE_EXT_SUPP_RATES;
+#ifdef DOT11_N_SUPPORT
+UCHAR HtCapIe = IE_HT_CAP;
+UCHAR AddHtInfoIe = IE_ADD_HT;
+UCHAR NewExtChanIe = IE_SECONDARY_CH_OFFSET;
+#ifdef DOT11N_DRAFT3
+UCHAR ExtHtCapIe = IE_EXT_CAPABILITY;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+UCHAR ErpIe = IE_ERP;
+UCHAR DsIe = IE_DS_PARM;
+UCHAR TimIe = IE_TIM;
+UCHAR WpaIe = IE_WPA;
+UCHAR Wpa2Ie = IE_WPA2;
+UCHAR IbssIe = IE_IBSS_PARM;
+UCHAR Ccx2Ie = IE_CCX_V2;
+UCHAR WapiIe = IE_WAPI;
+
+extern UCHAR WPA_OUI[];
+
+UCHAR SES_OUI[] = {0x00, 0x90, 0x4c};
+
+UCHAR ZeroSsid[32] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+// Reset the RFIC setting to new series
+RTMP_RF_REGS RF2850RegTable[] = {
+// ch R1 R2 R3(TX0~4=0) R4
+ {1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b},
+ {2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f},
+ {3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b},
+ {4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f},
+ {5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b},
+ {6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f},
+ {7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b},
+ {8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f},
+ {9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b},
+ {10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f},
+ {11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b},
+ {12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f},
+ {13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b},
+ {14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193},
+
+ // 802.11 UNI / HyperLan 2
+ {36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3},
+ {38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193},
+ {40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183},
+ {44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3},
+ {46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b},
+ {48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b},
+ {52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193},
+ {54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3},
+ {56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b},
+ {60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183},
+ {62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193},
+ {64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3}, // Plugfest#4, Day4, change RFR3 left4th 9->5.
+
+ // 802.11 HyperLan 2
+ {100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783},
+
+ // 2008.04.30 modified
+ // The system team has AN to improve the EVM value
+ // for channel 102 to 108 for the RT2850/RT2750 dual band solution.
+ {102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793},
+ {104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3},
+ {108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193},
+
+ {110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183},
+ {112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b},
+ {116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3},
+ {118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193},
+ {120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183},
+ {124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193},
+ {126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b}, // 0x980ed1bb->0x980ed15b required by Rory 20070927
+ {128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3},
+ {132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b},
+ {134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193},
+ {136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b},
+ {140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183},
+
+ // 802.11 UNII
+ {149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7},
+ {151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187},
+ {153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f},
+ {157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f},
+ {159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7},
+ {161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187},
+ {165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197},
+
+ // Japan
+ {184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b},
+ {188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13},
+ {192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b},
+ {196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23},
+ {208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13},
+ {212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b},
+ {216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23},
+
+ // still lack of MMAC(Japan) ch 34,38,42,46
+};
+UCHAR NUM_OF_2850_CHNL = (sizeof(RF2850RegTable) / sizeof(RTMP_RF_REGS));
+
+FREQUENCY_ITEM FreqItems3020[] =
+{
+ /**************************************************/
+ // ISM : 2.4 to 2.483 GHz //
+ /**************************************************/
+ // 11g
+ /**************************************************/
+ //-CH---N-------R---K-----------
+ {1, 241, 2, 2},
+ {2, 241, 2, 7},
+ {3, 242, 2, 2},
+ {4, 242, 2, 7},
+ {5, 243, 2, 2},
+ {6, 243, 2, 7},
+ {7, 244, 2, 2},
+ {8, 244, 2, 7},
+ {9, 245, 2, 2},
+ {10, 245, 2, 7},
+ {11, 246, 2, 2},
+ {12, 246, 2, 7},
+ {13, 247, 2, 2},
+ {14, 248, 2, 4},
+};
+//2008/07/10:KH Modified to share this variable
+UCHAR NUM_OF_3020_CHNL=(sizeof(FreqItems3020) / sizeof(FREQUENCY_ITEM));
+
+/*
+ ==========================================================================
+ Description:
+ initialize the MLME task and its data structure (queue, spinlock,
+ timer, state machines).
+
+ IRQL = PASSIVE_LEVEL
+
+ Return:
+ always return NDIS_STATUS_SUCCESS
+
+ ==========================================================================
+*/
+NDIS_STATUS MlmeInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> MLME Initialize\n"));
+
+ do
+ {
+ Status = MlmeQueueInit(&pAd->Mlme.Queue);
+ if(Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ pAd->Mlme.bRunning = FALSE;
+ NdisAllocateSpinLock(&pAd->Mlme.TaskLock);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ BssTableInit(&pAd->ScanTab);
+
+ // init STA state machines
+ AssocStateMachineInit(pAd, &pAd->Mlme.AssocMachine, pAd->Mlme.AssocFunc);
+ AuthStateMachineInit(pAd, &pAd->Mlme.AuthMachine, pAd->Mlme.AuthFunc);
+ AuthRspStateMachineInit(pAd, &pAd->Mlme.AuthRspMachine, pAd->Mlme.AuthRspFunc);
+ SyncStateMachineInit(pAd, &pAd->Mlme.SyncMachine, pAd->Mlme.SyncFunc);
+ WpaPskStateMachineInit(pAd, &pAd->Mlme.WpaPskMachine, pAd->Mlme.WpaPskFunc);
+ AironetStateMachineInit(pAd, &pAd->Mlme.AironetMachine, pAd->Mlme.AironetFunc);
+
+#ifdef QOS_DLS_SUPPORT
+ DlsStateMachineInit(pAd, &pAd->Mlme.DlsMachine, pAd->Mlme.DlsFunc);
+#endif // QOS_DLS_SUPPORT //
+
+
+ // Since we are using switch/case to implement it, the init is different from the above
+ // state machine init
+ MlmeCntlInit(pAd, &pAd->Mlme.CntlMachine, NULL);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+ ActionStateMachineInit(pAd, &pAd->Mlme.ActMachine, pAd->Mlme.ActFunc);
+
+ // Init mlme periodic timer
+ RTMPInitTimer(pAd, &pAd->Mlme.PeriodicTimer, GET_TIMER_FUNCTION(MlmePeriodicExec), pAd, TRUE);
+
+ // Set mlme periodic timer
+ RTMPSetTimer(&pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+
+ // software-based RX Antenna diversity
+ RTMPInitTimer(pAd, &pAd->Mlme.RxAntEvalTimer, GET_TIMER_FUNCTION(AsicRxAntEvalTimeout), pAd, FALSE);
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ } while (FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- MLME Initialize\n"));
+
+ return Status;
+}
+
+/*
+ ==========================================================================
+ Description:
+ main loop of the MLME
+ Pre:
+ Mlme has to be initialized, and there are something inside the queue
+ Note:
+ This function is invoked from MPSetInformation and MPReceive;
+ This task guarantee only one MlmeHandler will run.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeHandler(
+ IN PRTMP_ADAPTER pAd)
+{
+ MLME_QUEUE_ELEM *Elem = NULL;
+
+ // Only accept MLME and Frame from peer side, no other (control/data) frame should
+ // get into this state machine
+
+ NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+ if(pAd->Mlme.bRunning)
+ {
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+ return;
+ }
+ else
+ {
+ pAd->Mlme.bRunning = TRUE;
+ }
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+
+ while (!MlmeQueueEmpty(&pAd->Mlme.Queue))
+ {
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Device Halted or Removed or MlmeRest, exit MlmeHandler! (queue num = %ld)\n", pAd->Mlme.Queue.Num));
+ break;
+ }
+
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now in MlmeHandler\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+
+ //From message type, determine which state machine I should drive
+ if (MlmeDequeue(&pAd->Mlme.Queue, &Elem))
+ {
+#ifdef RT2870
+ if (Elem->MsgType == MT2_RESET_CONF)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! reset MLME state machine !!!\n"));
+ MlmeRestartStateMachine(pAd);
+ Elem->Occupied = FALSE;
+ Elem->MsgLen = 0;
+ continue;
+ }
+#endif // RT2870 //
+
+ // if dequeue success
+ switch (Elem->Machine)
+ {
+ // STA state machines
+#ifdef CONFIG_STA_SUPPORT
+ case ASSOC_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AssocMachine, Elem);
+ break;
+ case AUTH_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AuthMachine, Elem);
+ break;
+ case AUTH_RSP_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AuthRspMachine, Elem);
+ break;
+ case SYNC_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.SyncMachine, Elem);
+ break;
+ case MLME_CNTL_STATE_MACHINE:
+ MlmeCntlMachinePerformAction(pAd, &pAd->Mlme.CntlMachine, Elem);
+ break;
+ case WPA_PSK_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.WpaPskMachine, Elem);
+ break;
+#ifdef LEAP_SUPPORT
+ case LEAP_STATE_MACHINE:
+ LeapMachinePerformAction(pAd, &pAd->Mlme.LeapMachine, Elem);
+ break;
+#endif
+ case AIRONET_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.AironetMachine, Elem);
+ break;
+
+#ifdef QOS_DLS_SUPPORT
+ case DLS_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.DlsMachine, Elem);
+ break;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+ case ACTION_STATE_MACHINE:
+ StateMachinePerformAction(pAd, &pAd->Mlme.ActMachine, Elem);
+ break;
+
+
+
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("ERROR: Illegal machine %ld in MlmeHandler()\n", Elem->Machine));
+ break;
+ } // end of switch
+
+ // free MLME element
+ Elem->Occupied = FALSE;
+ Elem->MsgLen = 0;
+
+ }
+ else {
+ DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n"));
+ }
+ }
+
+ NdisAcquireSpinLock(&pAd->Mlme.TaskLock);
+ pAd->Mlme.bRunning = FALSE;
+ NdisReleaseSpinLock(&pAd->Mlme.TaskLock);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Destructor of MLME (Destroy queue, state machine, spin lock and timer)
+ Parameters:
+ Adapter - NIC Adapter pointer
+ Post:
+ The MLME task will no longer work properly
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeHalt(
+ IN PRTMP_ADAPTER pAd)
+{
+ BOOLEAN Cancelled;
+#ifdef RT3070
+ UINT32 TxPinCfg = 0x00050F0F;
+#endif // RT3070 //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeHalt\n"));
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ // disable BEACON generation and other BEACON related hardware timers
+ AsicDisableSync(pAd);
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef QOS_DLS_SUPPORT
+ UCHAR i;
+#endif // QOS_DLS_SUPPORT //
+ // Cancel pending timers
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
+#ifdef QOS_DLS_SUPPORT
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
+ }
+#endif // QOS_DLS_SUPPORT //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->Mlme.RxAntEvalTimer, &Cancelled);
+
+
+
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ // Set LED
+ RTMPSetLED(pAd, LED_HALT);
+ RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
+#ifdef RT2870
+ {
+ LED_CFG_STRUC LedCfg;
+ RTMP_IO_READ32(pAd, LED_CFG, &LedCfg.word);
+ LedCfg.field.LedPolar = 0;
+ LedCfg.field.RLedMode = 0;
+ LedCfg.field.GLedMode = 0;
+ LedCfg.field.YLedMode = 0;
+ RTMP_IO_WRITE32(pAd, LED_CFG, LedCfg.word);
+ }
+#endif // RT2870 //
+#ifdef RT3070
+ //
+ // Turn off LNA_PE
+ //
+ if (IS_RT3070(pAd) || IS_RT3071(pAd))
+ {
+ TxPinCfg &= 0xFFFFF0F0;
+ RTUSBWriteMACRegister(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+#endif // RT3070 //
+ }
+
+ RTMPusecDelay(5000); // 5 msec to gurantee Ant Diversity timer canceled
+
+ MlmeQueueDestroy(&pAd->Mlme.Queue);
+ NdisFreeSpinLock(&pAd->Mlme.TaskLock);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeHalt\n"));
+}
+
+VOID MlmeResetRalinkCounters(
+ IN PRTMP_ADAPTER pAd)
+{
+ pAd->RalinkCounters.LastOneSecRxOkDataCnt = pAd->RalinkCounters.OneSecRxOkDataCnt;
+ // clear all OneSecxxx counters.
+ pAd->RalinkCounters.OneSecBeaconSentCnt = 0;
+ pAd->RalinkCounters.OneSecFalseCCACnt = 0;
+ pAd->RalinkCounters.OneSecRxFcsErrCnt = 0;
+ pAd->RalinkCounters.OneSecRxOkCnt = 0;
+ pAd->RalinkCounters.OneSecTxFailCount = 0;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount = 0;
+ pAd->RalinkCounters.OneSecTxRetryOkCount = 0;
+ pAd->RalinkCounters.OneSecRxOkDataCnt = 0;
+
+ // TODO: for debug only. to be removed
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BE] = 0;
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_BK] = 0;
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VI] = 0;
+ pAd->RalinkCounters.OneSecOsTxCount[QID_AC_VO] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BE] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_BK] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VI] = 0;
+ pAd->RalinkCounters.OneSecDmaDoneCount[QID_AC_VO] = 0;
+ pAd->RalinkCounters.OneSecTxDoneCount = 0;
+ pAd->RalinkCounters.OneSecRxCount = 0;
+ pAd->RalinkCounters.OneSecTxAggregationCount = 0;
+ pAd->RalinkCounters.OneSecRxAggregationCount = 0;
+
+ return;
+}
+
+unsigned long rx_AMSDU;
+unsigned long rx_Total;
+
+/*
+ ==========================================================================
+ Description:
+ This routine is executed periodically to -
+ 1. Decide if it's a right time to turn on PwrMgmt bit of all
+ outgoiing frames
+ 2. Calculate ChannelQuality based on statistics of the last
+ period, so that TX rate won't toggling very frequently between a
+ successful TX and a failed TX.
+ 3. If the calculated ChannelQuality indicated current connection not
+ healthy, then a ROAMing attempt is tried here.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+#define ADHOC_BEACON_LOST_TIME (8*OS_HZ) // 8 sec
+VOID MlmePeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ ULONG TxTotalCnt;
+ PRTMP_ADAPTER pAd = (RTMP_ADAPTER *)FunctionContext;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if ((RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_RADIO_MEASUREMENT |
+ fRTMP_ADAPTER_RESET_IN_PROGRESS))))
+ return;
+
+ RT28XX_MLME_PRE_SANITY_CHECK(pAd);
+
+#ifdef RALINK_ATE
+ /* Do not show RSSI until "Normal 1 second Mlme PeriodicExec". */
+ if (ATE_ON(pAd))
+ {
+ if (pAd->Mlme.PeriodicRound % MLME_TASK_EXEC_MULTIPLE != (MLME_TASK_EXEC_MULTIPLE - 1))
+ {
+ pAd->Mlme.PeriodicRound ++;
+ return;
+ }
+ }
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Do nothing if monitor mode is on
+ if (MONITOR_ON(pAd))
+ return;
+
+ if (pAd->Mlme.PeriodicRound & 0x1)
+ {
+ // This is the fix for wifi 11n extension channel overlapping test case. for 2860D
+ if (((pAd->MACVersion & 0xffff) == 0x0101) &&
+ (STA_TGN_WIFI_ON(pAd)) &&
+ (pAd->CommonCfg.IOTestParm.bToggle == FALSE))
+
+ {
+ RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x24Bf);
+ pAd->CommonCfg.IOTestParm.bToggle = TRUE;
+ }
+ else if ((STA_TGN_WIFI_ON(pAd)) &&
+ ((pAd->MACVersion & 0xffff) == 0x0101))
+ {
+ RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x243f);
+ pAd->CommonCfg.IOTestParm.bToggle = FALSE;
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pAd->bUpdateBcnCntDone = FALSE;
+
+// RECBATimerTimeout(SystemSpecific1,FunctionContext,SystemSpecific2,SystemSpecific3);
+ pAd->Mlme.PeriodicRound ++;
+
+#ifdef RT2870
+ // execute every 100ms, update the Tx FIFO Cnt for update Tx Rate.
+ NICUpdateFifoStaCounters(pAd);
+#endif // RT2870 //
+ // execute every 500ms
+ if ((pAd->Mlme.PeriodicRound % 5 == 0) && RTMPAutoRateSwitchCheck(pAd)/*(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED))*/)
+ {
+#ifdef CONFIG_STA_SUPPORT
+ // perform dynamic tx rate switching based on past TX history
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ && (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)))
+ MlmeDynamicTxRateSwitching(pAd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // Normal 1 second Mlme PeriodicExec.
+ if (pAd->Mlme.PeriodicRound %MLME_TASK_EXEC_MULTIPLE == 0)
+ {
+ pAd->Mlme.OneSecPeriodicRound ++;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ /* request from Baron : move this routine from later to here */
+ /* for showing Rx error count in ATE RXFRAME */
+ NICUpdateRawCounters(pAd);
+ if (pAd->ate.bRxFer == 1)
+ {
+ pAd->ate.RxTotalCnt += pAd->ate.RxCntPerSec;
+ ate_print(KERN_EMERG "MlmePeriodicExec: Rx packet cnt = %d/%d\n", pAd->ate.RxCntPerSec, pAd->ate.RxTotalCnt);
+ pAd->ate.RxCntPerSec = 0;
+
+ if (pAd->ate.RxAntennaSel == 0)
+ ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi0=%d, AvgRssi1=%d, AvgRssi2=%d\n\n",
+ pAd->ate.AvgRssi0, pAd->ate.AvgRssi1, pAd->ate.AvgRssi2);
+ else
+ ate_print(KERN_EMERG "MlmePeriodicExec: Rx AvgRssi=%d\n\n", pAd->ate.AvgRssi0);
+ }
+ MlmeResetRalinkCounters(pAd);
+ return;
+ }
+#endif // RALINK_ATE //
+
+
+ if (rx_Total)
+ {
+
+ // reset counters
+ rx_AMSDU = 0;
+ rx_Total = 0;
+ }
+
+ //ORIBATimerTimeout(pAd);
+
+ // Media status changed, report to NDIS
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE))
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ RTMP_IndicateMediaState(pAd);
+
+ }
+ else
+ {
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ }
+ }
+
+ NdisGetSystemUpTime(&pAd->Mlme.Now32);
+
+ // add the most up-to-date h/w raw counters into software variable, so that
+ // the dynamic tuning mechanism below are based on most up-to-date information
+ NICUpdateRawCounters(pAd);
+
+#ifdef RT2870
+ RT2870_WatchDog(pAd);
+#endif // RT2870 //
+
+#ifdef DOT11_N_SUPPORT
+ // Need statistics after read counter. So put after NICUpdateRawCounters
+ ORIBATimerTimeout(pAd);
+#endif // DOT11_N_SUPPORT //
+
+ // The time period for checking antenna is according to traffic
+ {
+ if (pAd->Mlme.bEnableAutoAntennaCheck)
+ {
+ TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ // dynamic adjust antenna evaluation period according to the traffic
+ if (TxTotalCnt > 50)
+ {
+ if (pAd->Mlme.OneSecPeriodicRound % 10 == 0)
+ {
+ AsicEvaluateRxAnt(pAd);
+ }
+ }
+ else
+ {
+ if (pAd->Mlme.OneSecPeriodicRound % 3 == 0)
+ {
+ AsicEvaluateRxAnt(pAd);
+ }
+ }
+ }
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ STAMlmePeriodicExec(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+ MlmeResetRalinkCounters(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ {
+ // When Adhoc beacon is enabled and RTS/CTS is enabled, there is a chance that hardware MAC FSM will run into a deadlock
+ // and sending CTS-to-self over and over.
+ // Software Patch Solution:
+ // 1. Polling debug state register 0x10F4 every one second.
+ // 2. If in 0x10F4 the ((bit29==1) && (bit7==1)) OR ((bit29==1) && (bit5==1)), it means the deadlock has occurred.
+ // 3. If the deadlock occurred, reset MAC/BBP by setting 0x1004 to 0x0001 for a while then setting it back to 0x000C again.
+
+ UINT32 MacReg = 0;
+
+ RTMP_IO_READ32(pAd, 0x10F4, &MacReg);
+ if (((MacReg & 0x20000000) && (MacReg & 0x80)) || ((MacReg & 0x20000000) && (MacReg & 0x20)))
+ {
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+ RTMPusecDelay(1);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xC);
+
+ DBGPRINT(RT_DEBUG_WARN,("Warning, MAC specific condition occurs \n"));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RT28XX_MLME_HANDLER(pAd);
+ }
+
+
+ pAd->bUpdateBcnCntDone = FALSE;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID STAMlmePeriodicExec(
+ PRTMP_ADAPTER pAd)
+{
+ ULONG TxTotalCnt;
+ int i;
+
+//
+// We return here in ATE mode, because the statistics
+// that ATE needs are not collected via this routine.
+//
+#ifdef RALINK_ATE
+ // It is supposed that we will never reach here in ATE mode.
+ ASSERT(!(ATE_ON(pAd)));
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // WPA MIC error should block association attempt for 60 seconds
+ if (pAd->StaCfg.bBlockAssoc && (pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ) < pAd->Mlme.Now32))
+ pAd->StaCfg.bBlockAssoc = FALSE;
+ }
+
+ if ((pAd->PreMediaState != pAd->IndicateMediaState) && (pAd->CommonCfg.bWirelessEvent))
+ {
+ if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ pAd->PreMediaState = pAd->IndicateMediaState;
+ }
+
+
+
+
+ AsicStaBbpTuning(pAd);
+
+ TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ // update channel quality for Roaming and UI LinkQuality display
+ MlmeCalculateChannelQuality(pAd, pAd->Mlme.Now32);
+ }
+
+ // must be AFTER MlmeDynamicTxRateSwitching() because it needs to know if
+ // Radio is currently in noisy environment
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ AsicAdjustTxPower(pAd);
+
+ if (INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ // Check DLS time out, then tear down those session
+ RTMPCheckDLSTimeOut(pAd);
+#endif // QOS_DLS_SUPPORT //
+
+ // Is PSM bit consistent with user power management policy?
+ // This is the only place that will set PSM bit ON.
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ MlmeCheckPsmChange(pAd, pAd->Mlme.Now32);
+
+ pAd->RalinkCounters.LastOneSecTotalTxCount = TxTotalCnt;
+
+ if ((pAd->StaCfg.LastBeaconRxTime + 1*OS_HZ < pAd->Mlme.Now32) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
+ ((TxTotalCnt + pAd->RalinkCounters.OneSecRxOkCnt < 600)))
+ {
+ RTMPSetAGCInitValue(pAd, BW_20);
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. restore R66 to the low bound(%d) \n", (0x2E + GET_LNA_GAIN(pAd))));
+ }
+
+ //if ((pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+ // (pAd->RalinkCounters.OneSecTxRetryOkCount == 0))
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable)
+ {
+ // When APSD is enabled, the period changes as 20 sec
+ if ((pAd->Mlme.OneSecPeriodicRound % 20) == 8)
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ }
+ else
+ {
+ // Send out a NULL frame every 10 sec to inform AP that STA is still alive (Avoid being age out)
+ if ((pAd->Mlme.OneSecPeriodicRound % 10) == 8)
+ {
+ if (pAd->CommonCfg.bWmmCapable)
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ else
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+ }
+ }
+ }
+
+ if (CQI_IS_DEAD(pAd->Mlme.ChannelQuality))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - No BEACON. Dead CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+ pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
+ pAd->StaCfg.CCXAdjacentAPLinkDownTime = pAd->StaCfg.LastBeaconRxTime;
+
+ // Lost AP, send disconnect & link down event
+ LinkDown(pAd, FALSE);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+ // RTMPPatchMacBbpBug(pAd);
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ else if (CQI_IS_BAD(pAd->Mlme.ChannelQuality))
+ {
+ pAd->RalinkCounters.BadCQIAutoRecoveryCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Bad CQI. Auto Recovery attempt #%ld\n", pAd->RalinkCounters.BadCQIAutoRecoveryCount));
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+
+ // Add auto seamless roaming
+ if (pAd->StaCfg.bFastRoaming)
+ {
+ SHORT dBmToRoam = (SHORT)pAd->StaCfg.dBmToRoam;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Rssi=%d, dBmToRoam=%d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), (CHAR)dBmToRoam));
+
+ if (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) <= (CHAR)dBmToRoam)
+ {
+ MlmeCheckForFastRoaming(pAd, pAd->Mlme.Now32);
+ }
+ }
+ }
+ else if (ADHOC_ON(pAd))
+ {
+ //radar detect
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ RadarDetectPeriodic(pAd);
+ }
+
+ // If all peers leave, and this STA becomes the last one in this IBSS, then change MediaState
+ // to DISCONNECTED. But still holding this IBSS (i.e. sending BEACON) so that other STAs can
+ // join later.
+ if ((pAd->StaCfg.LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32) &&
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ MLME_START_REQ_STRUCT StartReq;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - excessive BEACON lost, last STA in this IBSS, MediaState=Disconnected\n"));
+ LinkDown(pAd, FALSE);
+
+ StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+ }
+
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[i];
+
+ if (pEntry->ValidAsCLI == FALSE)
+ continue;
+
+ if (pEntry->LastBeaconRxTime + ADHOC_BEACON_LOST_TIME < pAd->Mlme.Now32)
+ MacTableDeleteEntry(pAd, pEntry->Aid, pEntry->Addr);
+ }
+ }
+ else // no INFRA nor ADHOC connection
+ {
+
+ if (pAd->StaCfg.bScanReqIsFromWebUI &&
+ ((pAd->StaCfg.LastScanTime + 30 * OS_HZ) > pAd->Mlme.Now32))
+ goto SKIP_AUTO_SCAN_CONN;
+ else
+ pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+
+ if ((pAd->StaCfg.bAutoReconnect == TRUE)
+ && RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP)
+ && (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
+ {
+ if ((pAd->ScanTab.BssNr==0) && (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE))
+ {
+ MLME_SCAN_REQ_STRUCT ScanReq;
+
+ if ((pAd->StaCfg.LastScanTime + 10 * OS_HZ) < pAd->Mlme.Now32)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("STAMlmePeriodicExec():CNTL - ScanTab.BssNr==0, start a new ACTIVE scan SSID[%s]\n", pAd->MlmeAux.AutoReconnectSsid));
+ ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen, BSS_ANY, SCAN_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+ // Reset Missed scan number
+ pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+ }
+ else if (pAd->StaCfg.BssType == BSS_ADHOC) // Quit the forever scan when in a very clean room
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ else if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ if ((pAd->Mlme.OneSecPeriodicRound % 7) == 0)
+ {
+ MlmeAutoScan(pAd);
+ pAd->StaCfg.LastScanTime = pAd->Mlme.Now32;
+ }
+ else
+ {
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ if ((pAd->Mlme.OneSecPeriodicRound % 5) == 1)
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ else
+#endif // CARRIER_DETECTION_SUPPORT //
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ }
+ }
+ }
+
+SKIP_AUTO_SCAN_CONN:
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap !=0) && (pAd->MacTab.fAnyBASession == FALSE))
+ {
+ pAd->MacTab.fAnyBASession = TRUE;
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, FALSE, FALSE);
+ }
+ else if ((pAd->MacTab.Content[BSSID_WCID].TXBAbitmap ==0) && (pAd->MacTab.fAnyBASession == TRUE))
+ {
+ pAd->MacTab.fAnyBASession = FALSE;
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+ }
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SCAN_2040))
+ TriEventCounterMaintenance(pAd);
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+ return;
+}
+
+// Link down report
+VOID LinkDownExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeAutoScan(
+ IN PRTMP_ADAPTER pAd)
+{
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Driver auto scan\n"));
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID_LIST_SCAN,
+ 0,
+ NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeAutoReconnectLastSSID(
+ IN PRTMP_ADAPTER pAd)
+{
+
+
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if ((pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) &&
+ (MlmeValidateSSID(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen) == TRUE))
+ {
+ NDIS_802_11_SSID OidSsid;
+ OidSsid.SsidLength = pAd->MlmeAux.AutoReconnectSsidLen;
+ NdisMoveMemory(OidSsid.Ssid, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Driver auto reconnect to last OID_802_11_SSID setting - %s, len - %d\n", pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen));
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_SSID,
+ sizeof(NDIS_802_11_SSID),
+ &OidSsid);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ==========================================================================
+ Validate SSID for connection try and rescan purpose
+ Valid SSID will have visible chars only.
+ The valid length is from 0 to 32.
+ IRQL = DISPATCH_LEVEL
+ ==========================================================================
+ */
+BOOLEAN MlmeValidateSSID(
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen)
+{
+ int index;
+
+ if (SsidLen > MAX_LEN_OF_SSID)
+ return (FALSE);
+
+ // Check each character value
+ for (index = 0; index < SsidLen; index++)
+ {
+ if (pSsid[index] < 0x20)
+ return (FALSE);
+ }
+
+ // All checked
+ return (TRUE);
+}
+
+VOID MlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR *ppTable,
+ IN PUCHAR pTableSize,
+ IN PUCHAR pInitTxRateIdx)
+{
+ do
+ {
+ // decide the rate table for tuning
+ if (pAd->CommonCfg.TxRateTableSize > 0)
+ {
+ *ppTable = RateSwitchTable;
+ *pTableSize = RateSwitchTable[0];
+ *pInitTxRateIdx = RateSwitchTable[1];
+
+ break;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((pAd->OpMode == OPMODE_STA) && ADHOC_ON(pAd))
+ {
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+ (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ {// 11N 1S Adhoc
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+ }
+ else if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED) &&
+ (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ (pEntry->HTCapability.MCSSet[1] == 0xff) &&
+ (pAd->Antenna.field.TxPath == 2))
+ {// 11N 2S Adhoc
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ }
+
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if ((pEntry->RateLen == 4)
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+
+ }
+ else if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ }
+ break;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ //if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+ // ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {// 11BGN 1S AP
+ *ppTable = RateSwitchTable11BGN1S;
+ *pTableSize = RateSwitchTable11BGN1S[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN1S[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 12) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) &&
+ // (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+ if ((pEntry->RateLen == 12) && (pEntry->HTCapability.MCSSet[0] == 0xff) &&
+ (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+ {// 11BGN 2S AP
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11BGN2S;
+ *pTableSize = RateSwitchTable11BGN2S[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN2S[1];
+
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11BGN2SForABand;
+ *pTableSize = RateSwitchTable11BGN2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11BGN2SForABand[1];
+
+ }
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && ((pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0x00) || (pAd->Antenna.field.TxPath == 1)))
+ if ((pEntry->HTCapability.MCSSet[0] == 0xff) && ((pEntry->HTCapability.MCSSet[1] == 0x00) || (pAd->CommonCfg.TxStream == 1)))
+ {// 11N 1S AP
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0xff) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0xff) && (pAd->Antenna.field.TxPath == 2))
+ if ((pEntry->HTCapability.MCSSet[0] == 0xff) && (pEntry->HTCapability.MCSSet[1] == 0xff) && (pAd->CommonCfg.TxStream == 2))
+ {// 11N 2S AP
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ }
+
+ break;
+ }
+#endif // DOT11_N_SUPPORT //
+ //else if ((pAd->StaActive.SupRateLen == 4) && (pAd->StaActive.ExtRateLen == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen == 4)
+#ifdef DOT11_N_SUPPORT
+//Iverson mark for Adhoc b mode,sta will use rate 54 Mbps when connect with sta b/g/n mode
+// && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {// B only AP
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen > 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen > 8)
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {// B/G mixed AP
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+
+ break;
+ }
+
+ //else if ((pAd->StaActive.SupRateLen + pAd->StaActive.ExtRateLen == 8) && (pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->RateLen == 8)
+#ifdef DOT11_N_SUPPORT
+ && (pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0)
+#endif // DOT11_N_SUPPORT //
+ )
+ {// G only AP
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ break;
+ }
+#ifdef DOT11_N_SUPPORT
+#endif // DOT11_N_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef DOT11_N_SUPPORT
+ //else if ((pAd->StaActive.SupportedPhyInfo.MCSSet[0] == 0) && (pAd->StaActive.SupportedPhyInfo.MCSSet[1] == 0))
+ if ((pEntry->HTCapability.MCSSet[0] == 0) && (pEntry->HTCapability.MCSSet[1] == 0))
+#endif // DOT11_N_SUPPORT //
+ { // Legacy mode
+ if (pAd->CommonCfg.MaxTxRate <= RATE_11)
+ {
+ *ppTable = RateSwitchTable11B;
+ *pTableSize = RateSwitchTable11B[0];
+ *pInitTxRateIdx = RateSwitchTable11B[1];
+ }
+ else if ((pAd->CommonCfg.MaxTxRate > RATE_11) && (pAd->CommonCfg.MinTxRate > RATE_11))
+ {
+ *ppTable = RateSwitchTable11G;
+ *pTableSize = RateSwitchTable11G[0];
+ *pInitTxRateIdx = RateSwitchTable11G[1];
+
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11BG;
+ *pTableSize = RateSwitchTable11BG[0];
+ *pInitTxRateIdx = RateSwitchTable11BG[1];
+ }
+ break;
+ }
+#ifdef DOT11_N_SUPPORT
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ if (pAd->CommonCfg.TxStream == 1)
+ {
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2S;
+ *pTableSize = RateSwitchTable11N2S[0];
+ *pInitTxRateIdx = RateSwitchTable11N2S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.TxStream == 1)
+ {
+ *ppTable = RateSwitchTable11N1S;
+ *pTableSize = RateSwitchTable11N1S[0];
+ *pInitTxRateIdx = RateSwitchTable11N1S[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 1S AP \n"));
+ }
+ else
+ {
+ *ppTable = RateSwitchTable11N2SForABand;
+ *pTableSize = RateSwitchTable11N2SForABand[0];
+ *pInitTxRateIdx = RateSwitchTable11N2SForABand[1];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode,default use 11N 2S AP \n"));
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("DRS: unkown mode (SupRateLen=%d, ExtRateLen=%d, MCSSet[0]=0x%x, MCSSet[1]=0x%x)\n",
+ pAd->StaActive.SupRateLen, pAd->StaActive.ExtRateLen, pAd->StaActive.SupportedPhyInfo.MCSSet[0], pAd->StaActive.SupportedPhyInfo.MCSSet[1]));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ } while(FALSE);
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ This routine checks if there're other APs out there capable for
+ roaming. Caller should call this routine only when Link up in INFRA mode
+ and channel quality is below CQI_GOOD_THRESHOLD.
+
+ IRQL = DISPATCH_LEVEL
+
+ Output:
+ ==========================================================================
+ */
+VOID MlmeCheckForRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
+{
+ USHORT i;
+ BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
+ BSS_ENTRY *pBss;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForRoaming\n"));
+ // put all roaming candidates into RoamTab, and sort in RSSI order
+ BssTableInit(pRoamTab);
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ pBss = &pAd->ScanTab.BssEntry[i];
+
+ if ((pBss->LastBeaconRxTime + BEACON_LOST_TIME) < Now32)
+ continue; // AP disappear
+ if (pBss->Rssi <= RSSI_THRESHOLD_FOR_ROAMING)
+ continue; // RSSI too weak. forget it.
+ if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+ continue; // skip current AP
+ if (pBss->Rssi < (pAd->StaCfg.RssiSample.LastRssi0 + RSSI_DELTA))
+ continue; // only AP with stronger RSSI is eligible for roaming
+
+ // AP passing all above rules is put into roaming candidate table
+ NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+ pRoamTab->BssNr += 1;
+ }
+
+ if (pRoamTab->BssNr > 0)
+ {
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ pAd->RalinkCounters.PoorCQIRoamingCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForRoaming(# of candidate= %d)\n",pRoamTab->BssNr));
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine checks if there're other APs out there capable for
+ roaming. Caller should call this routine only when link up in INFRA mode
+ and channel quality is below CQI_GOOD_THRESHOLD.
+
+ IRQL = DISPATCH_LEVEL
+
+ Output:
+ ==========================================================================
+ */
+VOID MlmeCheckForFastRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now)
+{
+ USHORT i;
+ BSS_TABLE *pRoamTab = &pAd->MlmeAux.RoamTab;
+ BSS_ENTRY *pBss;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> MlmeCheckForFastRoaming\n"));
+ // put all roaming candidates into RoamTab, and sort in RSSI order
+ BssTableInit(pRoamTab);
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ pBss = &pAd->ScanTab.BssEntry[i];
+
+ if ((pBss->Rssi <= -50) && (pBss->Channel == pAd->CommonCfg.Channel))
+ continue; // RSSI too weak. forget it.
+ if (MAC_ADDR_EQUAL(pBss->Bssid, pAd->CommonCfg.Bssid))
+ continue; // skip current AP
+ if (!SSID_EQUAL(pBss->Ssid, pBss->SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
+ continue; // skip different SSID
+ if (pBss->Rssi < (RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2) + RSSI_DELTA))
+ continue; // skip AP without better RSSI
+
+ DBGPRINT(RT_DEBUG_TRACE, ("LastRssi0 = %d, pBss->Rssi = %d\n", RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2), pBss->Rssi));
+ // AP passing all above rules is put into roaming candidate table
+ NdisMoveMemory(&pRoamTab->BssEntry[pRoamTab->BssNr], pBss, sizeof(BSS_ENTRY));
+ pRoamTab->BssNr += 1;
+ }
+
+ if (pRoamTab->BssNr > 0)
+ {
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE)
+ {
+ pAd->RalinkCounters.PoorCQIRoamingCount ++;
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming attempt #%ld\n", pAd->RalinkCounters.PoorCQIRoamingCount));
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_MLME_ROAMING_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+ }
+ // Maybe site survey required
+ else
+ {
+ if ((pAd->StaCfg.LastScanTime + 10 * 1000) < Now)
+ {
+ // check CntlMachine.CurrState to avoid collision with NDIS SetOID request
+ DBGPRINT(RT_DEBUG_TRACE, ("MMCHK - Roaming, No eligable entry, try new scan!\n"));
+ pAd->StaCfg.ScanCnt = 2;
+ pAd->StaCfg.LastScanTime = Now;
+ MlmeAutoScan(pAd);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== MlmeCheckForFastRoaming (BssNr=%d)\n", pRoamTab->BssNr));
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine calculates TxPER, RxPER of the past N-sec period. And
+ according to the calculation result, ChannelQuality is calculated here
+ to decide if current AP is still doing the job.
+
+ If ChannelQuality is not good, a ROAMing attempt may be tried later.
+ Output:
+ StaCfg.ChannelQuality - 0..100
+
+ IRQL = DISPATCH_LEVEL
+
+ NOTE: This routine decide channle quality based on RX CRC error ratio.
+ Caller should make sure a function call to NICUpdateRawCounters(pAd)
+ is performed right before this routine, so that this routine can decide
+ channel quality based on the most up-to-date information
+ ==========================================================================
+ */
+VOID MlmeCalculateChannelQuality(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
+{
+ ULONG TxOkCnt, TxCnt, TxPER, TxPRR;
+ ULONG RxCnt, RxPER;
+ UCHAR NorRssi;
+ CHAR MaxRssi;
+ ULONG BeaconLostTime = BEACON_LOST_TIME;
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ // longer beacon lost time when carrier detection enabled
+ if (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+ {
+ BeaconLostTime = BEACON_LOST_TIME + BEACON_LOST_TIME/2;
+ }
+#endif // CARRIER_DETECTION_SUPPORT //
+
+ MaxRssi = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+
+ //
+ // calculate TX packet error ratio and TX retry ratio - if too few TX samples, skip TX related statistics
+ //
+ TxOkCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount + pAd->RalinkCounters.OneSecTxRetryOkCount;
+ TxCnt = TxOkCnt + pAd->RalinkCounters.OneSecTxFailCount;
+ if (TxCnt < 5)
+ {
+ TxPER = 0;
+ TxPRR = 0;
+ }
+ else
+ {
+ TxPER = (pAd->RalinkCounters.OneSecTxFailCount * 100) / TxCnt;
+ TxPRR = ((TxCnt - pAd->RalinkCounters.OneSecTxNoRetryOkCount) * 100) / TxCnt;
+ }
+
+ //
+ // calculate RX PER - don't take RxPER into consideration if too few sample
+ //
+ RxCnt = pAd->RalinkCounters.OneSecRxOkCnt + pAd->RalinkCounters.OneSecRxFcsErrCnt;
+ if (RxCnt < 5)
+ RxPER = 0;
+ else
+ RxPER = (pAd->RalinkCounters.OneSecRxFcsErrCnt * 100) / RxCnt;
+
+ //
+ // decide ChannelQuality based on: 1)last BEACON received time, 2)last RSSI, 3)TxPER, and 4)RxPER
+ //
+ if (INFRA_ON(pAd) &&
+ (pAd->RalinkCounters.OneSecTxNoRetryOkCount < 2) && // no heavy traffic
+ (pAd->StaCfg.LastBeaconRxTime + BeaconLostTime < Now32))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("BEACON lost > %ld msec with TxOkCnt=%ld -> CQI=0\n", BeaconLostTime, TxOkCnt));
+ pAd->Mlme.ChannelQuality = 0;
+ }
+ else
+ {
+ // Normalize Rssi
+ if (MaxRssi > -40)
+ NorRssi = 100;
+ else if (MaxRssi < -90)
+ NorRssi = 0;
+ else
+ NorRssi = (MaxRssi + 90) * 2;
+
+ // ChannelQuality = W1*RSSI + W2*TxPRR + W3*RxPER (RSSI 0..100), (TxPER 100..0), (RxPER 100..0)
+ pAd->Mlme.ChannelQuality = (RSSI_WEIGHTING * NorRssi +
+ TX_WEIGHTING * (100 - TxPRR) +
+ RX_WEIGHTING* (100 - RxPER)) / 100;
+ if (pAd->Mlme.ChannelQuality >= 100)
+ pAd->Mlme.ChannelQuality = 100;
+ }
+
+}
+
+VOID MlmeSetTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PRTMP_TX_RATE_SWITCH pTxRate)
+{
+ UCHAR MaxMode = MODE_OFDM;
+
+#ifdef DOT11_N_SUPPORT
+ MaxMode = MODE_HTGREENFIELD;
+
+ if (pTxRate->STBC && (pAd->StaCfg.MaxHTPhyMode.field.STBC) && (pAd->Antenna.field.TxPath == 2))
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_USE;
+ else
+#endif // DOT11_N_SUPPORT //
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
+
+ if (pTxRate->CurrMCS < MCS_AUTO)
+ pAd->StaCfg.HTPhyMode.field.MCS = pTxRate->CurrMCS;
+
+ if (pAd->StaCfg.HTPhyMode.field.MCS > 7)
+ pAd->StaCfg.HTPhyMode.field.STBC = STBC_NONE;
+
+ if (ADHOC_ON(pAd))
+ {
+ // If peer adhoc is b-only mode, we can't send 11g rate.
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ pEntry->HTPhyMode.field.STBC = STBC_NONE;
+
+ //
+ // For Adhoc MODE_CCK, driver will use AdhocBOnlyJoined flag to roll back to B only if necessary
+ //
+ pEntry->HTPhyMode.field.MODE = pTxRate->Mode;
+ pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+
+ // Patch speed error in status page
+ pAd->StaCfg.HTPhyMode.field.MODE = pEntry->HTPhyMode.field.MODE;
+ }
+ else
+ {
+ if (pTxRate->Mode <= MaxMode)
+ pAd->StaCfg.HTPhyMode.field.MODE = pTxRate->Mode;
+
+#ifdef DOT11_N_SUPPORT
+ if (pTxRate->ShortGI && (pAd->StaCfg.MaxHTPhyMode.field.ShortGI))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_400;
+ else
+#endif // DOT11_N_SUPPORT //
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+
+#ifdef DOT11_N_SUPPORT
+ // Reexam each bandwidth's SGI support.
+ if (pAd->StaCfg.HTPhyMode.field.ShortGI == GI_400)
+ {
+ if ((pEntry->HTPhyMode.field.BW == BW_20) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE)))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ if ((pEntry->HTPhyMode.field.BW == BW_40) && (!CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE)))
+ pAd->StaCfg.HTPhyMode.field.ShortGI = GI_800;
+ }
+
+ // Turn RTS/CTS rate to 6Mbps.
+ if ((pEntry->HTPhyMode.field.MCS == 0) && (pAd->StaCfg.HTPhyMode.field.MCS != 0))
+ {
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ if (pAd->MacTab.fAnyBASession)
+ {
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ else
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ }
+ else if ((pEntry->HTPhyMode.field.MCS == 8) && (pAd->StaCfg.HTPhyMode.field.MCS != 8))
+ {
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ if (pAd->MacTab.fAnyBASession)
+ {
+ AsicUpdateProtect(pAd, HT_FORCERTSCTS, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ else
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+ }
+ else if ((pEntry->HTPhyMode.field.MCS != 0) && (pAd->StaCfg.HTPhyMode.field.MCS == 0))
+ {
+ AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+
+ }
+ else if ((pEntry->HTPhyMode.field.MCS != 8) && (pAd->StaCfg.HTPhyMode.field.MCS == 8))
+ {
+ AsicUpdateProtect(pAd, HT_RTSCTS_6M, ALLN_SETPROTECT, TRUE, (BOOLEAN)pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.field.STBC = pAd->StaCfg.HTPhyMode.field.STBC;
+ pEntry->HTPhyMode.field.ShortGI = pAd->StaCfg.HTPhyMode.field.ShortGI;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->StaCfg.MaxHTPhyMode.field.MODE == MODE_HTGREENFIELD) &&
+ pAd->WIFItestbed.bGreenField)
+ pEntry->HTPhyMode.field.MODE = MODE_HTGREENFIELD;
+#endif // DOT11_N_SUPPORT //
+ }
+
+ pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine calculates the acumulated TxPER of eaxh TxRate. And
+ according to the calculation result, change CommonCfg.TxRate which
+ is the stable TX Rate we expect the Radio situation could sustained.
+
+ CommonCfg.TxRate will change dynamically within {RATE_1/RATE_6, MaxTxRate}
+ Output:
+ CommonCfg.TxRate -
+
+ IRQL = DISPATCH_LEVEL
+
+ NOTE:
+ call this routine every second
+ ==========================================================================
+ */
+VOID MlmeDynamicTxRateSwitching(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx;
+ ULONG i, AccuTxTotalCnt = 0, TxTotalCnt;
+ ULONG TxErrorRatio = 0;
+ BOOLEAN bTxRateChanged, bUpgradeQuality = FALSE;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+ UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
+ CHAR Rssi, RssiOffset = 0;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+ MAC_TABLE_ENTRY *pEntry;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+ //
+ // walk through MAC table, see if need to change AP's TX rate toward each entry
+ //
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+
+ // check if this entry need to switch rate automatically
+ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+ continue;
+
+ if ((pAd->MacTab.Size == 1) || (pEntry->ValidAsDls))
+ {
+ Rssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.AvgRssi0,
+ pAd->StaCfg.RssiSample.AvgRssi1,
+ pAd->StaCfg.RssiSample.AvgRssi2);
+
+ // Update statistic counter
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+ pAd->bUpdateBcnCntDone = TRUE;
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+
+ // if no traffic in the past 1-sec period, don't change TX rate,
+ // but clear all bad history. because the bad history may affect the next
+ // Chariot throughput test
+ AccuTxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ if (INFRA_ON(pAd) && (i == 1))
+ Rssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.AvgRssi0,
+ pAd->StaCfg.RssiSample.AvgRssi1,
+ pAd->StaCfg.RssiSample.AvgRssi2);
+ else
+ Rssi = RTMPMaxRssi(pAd,
+ pEntry->RssiSample.AvgRssi0,
+ pEntry->RssiSample.AvgRssi1,
+ pEntry->RssiSample.AvgRssi2);
+
+ TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+ pEntry->OneSecTxRetryOkCount +
+ pEntry->OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+ }
+
+ CurrRateIdx = pEntry->CurrTxRateIndex;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+
+ if (CurrRateIdx >= TableSize)
+ {
+ CurrRateIdx = TableSize - 1;
+ }
+
+ // When switch from Fixed rate -> auto rate, the REAL TX rate might be different from pAd->CommonCfg.TxRateIndex.
+ // So need to sync here.
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+ if ((pEntry->HTPhyMode.field.MCS != pCurrTxRate->CurrMCS)
+ //&& (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ )
+ {
+
+ // Need to sync Real Tx rate and our record.
+ // Then return for next DRS.
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(InitTxRateIdx+1)*5];
+ pEntry->CurrTxRateIndex = InitTxRateIdx;
+ MlmeSetTxRate(pAd, pEntry, pCurrTxRate);
+
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+ continue;
+ }
+
+ // decide the next upgrade rate and downgrade rate, if any
+ if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx -1;
+ }
+ else if (CurrRateIdx == 0)
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx;
+ }
+ else if (CurrRateIdx == (TableSize - 1))
+ {
+ UpRateIdx = CurrRateIdx;
+ DownRateIdx = CurrRateIdx - 1;
+ }
+
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+
+#ifdef DOT11_N_SUPPORT
+ if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
+ {
+ TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+ TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ TrainUp = pCurrTxRate->TrainUp;
+ TrainDown = pCurrTxRate->TrainDown;
+ }
+
+ //pAd->DrsCounters.LastTimeTxRateChangeAction = pAd->DrsCounters.LastSecTxRateChangeAction;
+
+ //
+ // Keep the last time TxRateChangeAction status.
+ //
+ pEntry->LastTimeTxRateChangeAction = pEntry->LastSecTxRateChangeAction;
+
+
+
+ //
+ // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+ // (criteria copied from RT2500 for Netopia case)
+ //
+ if (TxTotalCnt <= 15)
+ {
+ CHAR idx = 0;
+ UCHAR TxRateIdx;
+ //UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS7 = 0, MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+ UCHAR MCS0 = 0, MCS1 = 0, MCS2 = 0, MCS3 = 0, MCS4 = 0, MCS5 =0, MCS6 = 0, MCS7 = 0;
+ UCHAR MCS12 = 0, MCS13 = 0, MCS14 = 0, MCS15 = 0;
+ UCHAR MCS20 = 0, MCS21 = 0, MCS22 = 0, MCS23 = 0; // 3*3
+
+ // check the existence and index of each needed MCS
+ while (idx < pTable[0])
+ {
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(idx+1)*5];
+
+ if (pCurrTxRate->CurrMCS == MCS_0)
+ {
+ MCS0 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_1)
+ {
+ MCS1 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_2)
+ {
+ MCS2 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_3)
+ {
+ MCS3 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_4)
+ {
+ MCS4 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_5)
+ {
+ MCS5 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_6)
+ {
+ MCS6 = idx;
+ }
+ //else if (pCurrTxRate->CurrMCS == MCS_7)
+ else if ((pCurrTxRate->CurrMCS == MCS_7) && (pCurrTxRate->ShortGI == GI_800)) // prevent the highest MCS using short GI when 1T and low throughput
+ {
+ MCS7 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_12)
+ {
+ MCS12 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_13)
+ {
+ MCS13 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_14)
+ {
+ MCS14 = idx;
+ }
+ else if ((pCurrTxRate->CurrMCS == MCS_15) && (pCurrTxRate->ShortGI == GI_800))
+ {
+ MCS15 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_20) // 3*3
+ {
+ MCS20 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_21)
+ {
+ MCS21 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_22)
+ {
+ MCS22 = idx;
+ }
+ else if (pCurrTxRate->CurrMCS == MCS_23)
+ {
+ MCS23 = idx;
+ }
+ idx ++;
+ }
+
+ if (pAd->LatchRfRegs.Channel <= 14)
+ {
+ if (pAd->NicConfig2.field.ExternalLNAForG)
+ {
+ RssiOffset = 2;
+ }
+ else
+ {
+ RssiOffset = 5;
+ }
+ }
+ else
+ {
+ if (pAd->NicConfig2.field.ExternalLNAForA)
+ {
+ RssiOffset = 5;
+ }
+ else
+ {
+ RssiOffset = 8;
+ }
+ }
+#ifdef DOT11_N_SUPPORT
+ /*if (MCS15)*/
+ if ((pTable == RateSwitchTable11BGN3S) ||
+ (pTable == RateSwitchTable11N3S) ||
+ (pTable == RateSwitchTable))
+ {// N mode with 3 stream // 3*3
+ if (MCS23 && (Rssi >= -70))
+ TxRateIdx = MCS15;
+ else if (MCS22 && (Rssi >= -72))
+ TxRateIdx = MCS14;
+ else if (MCS21 && (Rssi >= -76))
+ TxRateIdx = MCS13;
+ else if (MCS20 && (Rssi >= -78))
+ TxRateIdx = MCS12;
+ else if (MCS4 && (Rssi >= -82))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi >= -84))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi >= -86))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi >= -88))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+// else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand) || (pTable == RateSwitchTable))
+ else if ((pTable == RateSwitchTable11BGN2S) || (pTable == RateSwitchTable11BGN2SForABand) ||(pTable == RateSwitchTable11N2S) ||(pTable == RateSwitchTable11N2SForABand)) // 3*3
+ {// N mode with 2 stream
+ if (MCS15 && (Rssi >= (-70+RssiOffset)))
+ TxRateIdx = MCS15;
+ else if (MCS14 && (Rssi >= (-72+RssiOffset)))
+ TxRateIdx = MCS14;
+ else if (MCS13 && (Rssi >= (-76+RssiOffset)))
+ TxRateIdx = MCS13;
+ else if (MCS12 && (Rssi >= (-78+RssiOffset)))
+ TxRateIdx = MCS12;
+ else if (MCS4 && (Rssi >= (-82+RssiOffset)))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi >= (-84+RssiOffset)))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi >= (-86+RssiOffset)))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi >= (-88+RssiOffset)))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+ else if ((pTable == RateSwitchTable11BGN1S) || (pTable == RateSwitchTable11N1S))
+ {// N mode with 1 stream
+ if (MCS7 && (Rssi > (-72+RssiOffset)))
+ TxRateIdx = MCS7;
+ else if (MCS6 && (Rssi > (-74+RssiOffset)))
+ TxRateIdx = MCS6;
+ else if (MCS5 && (Rssi > (-77+RssiOffset)))
+ TxRateIdx = MCS5;
+ else if (MCS4 && (Rssi > (-79+RssiOffset)))
+ TxRateIdx = MCS4;
+ else if (MCS3 && (Rssi > (-81+RssiOffset)))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi > (-83+RssiOffset)))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi > (-86+RssiOffset)))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {// Legacy mode
+ if (MCS7 && (Rssi > -70))
+ TxRateIdx = MCS7;
+ else if (MCS6 && (Rssi > -74))
+ TxRateIdx = MCS6;
+ else if (MCS5 && (Rssi > -78))
+ TxRateIdx = MCS5;
+ else if (MCS4 && (Rssi > -82))
+ TxRateIdx = MCS4;
+ else if (MCS4 == 0) // for B-only mode
+ TxRateIdx = MCS3;
+ else if (MCS3 && (Rssi > -85))
+ TxRateIdx = MCS3;
+ else if (MCS2 && (Rssi > -87))
+ TxRateIdx = MCS2;
+ else if (MCS1 && (Rssi > -90))
+ TxRateIdx = MCS1;
+ else
+ TxRateIdx = MCS0;
+ }
+
+ // if (TxRateIdx != pAd->CommonCfg.TxRateIndex)
+ {
+ pEntry->CurrTxRateIndex = TxRateIdx;
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+
+ NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+ pEntry->fLastSecAccordingRSSI = TRUE;
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ continue;
+ }
+
+ if (pEntry->fLastSecAccordingRSSI == TRUE)
+ {
+ pEntry->fLastSecAccordingRSSI = FALSE;
+ pEntry->LastSecTxRateChangeAction = 0;
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ continue;
+ }
+
+ do
+ {
+ BOOLEAN bTrainUpDown = FALSE;
+
+ pEntry->CurrTxRateStableTime ++;
+
+ // downgrade TX quality if PER >= Rate-Down threshold
+ if (TxErrorRatio >= TrainDown)
+ {
+ bTrainUpDown = TRUE;
+ pEntry->TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
+ // upgrade TX quality if PER <= Rate-Up threshold
+ else if (TxErrorRatio <= TrainUp)
+ {
+ bTrainUpDown = TRUE;
+ bUpgradeQuality = TRUE;
+ if (pEntry->TxQuality[CurrRateIdx])
+ pEntry->TxQuality[CurrRateIdx] --; // quality very good in CurrRate
+
+ if (pEntry->TxRateUpPenalty)
+ pEntry->TxRateUpPenalty --;
+ else if (pEntry->TxQuality[UpRateIdx])
+ pEntry->TxQuality[UpRateIdx] --; // may improve next UP rate's quality
+ }
+
+ pEntry->PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+ if (bTrainUpDown)
+ {
+ // perform DRS - consider TxRate Down first, then rate up.
+ if ((CurrRateIdx != DownRateIdx) && (pEntry->TxQuality[CurrRateIdx] >= DRS_TX_QUALITY_WORST_BOUND))
+ {
+ pEntry->CurrTxRateIndex = DownRateIdx;
+ }
+ else if ((CurrRateIdx != UpRateIdx) && (pEntry->TxQuality[UpRateIdx] <= 0))
+ {
+ pEntry->CurrTxRateIndex = UpRateIdx;
+ }
+ }
+ } while (FALSE);
+
+ // if rate-up happen, clear all bad history of all TX rates
+ if (pEntry->CurrTxRateIndex > CurrRateIdx)
+ {
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0;
+ pEntry->LastSecTxRateChangeAction = 1; // rate UP
+ NdisZeroMemory(pEntry->TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pEntry->PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+
+ //
+ // For TxRate fast train up
+ //
+ if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
+ {
+ RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ bTxRateChanged = TRUE;
+ }
+ // if rate-down happen, only clear DownRate's bad history
+ else if (pEntry->CurrTxRateIndex < CurrRateIdx)
+ {
+ pEntry->CurrTxRateStableTime = 0;
+ pEntry->TxRateUpPenalty = 0; // no penalty
+ pEntry->LastSecTxRateChangeAction = 2; // rate DOWN
+ pEntry->TxQuality[pEntry->CurrTxRateIndex] = 0;
+ pEntry->PER[pEntry->CurrTxRateIndex] = 0;
+
+ //
+ // For TxRate fast train down
+ //
+ if (!pAd->StaCfg.StaQuickResponeForRateUpTimerRunning)
+ {
+ RTMPSetTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, 100);
+
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = TRUE;
+ }
+ bTxRateChanged = TRUE;
+ }
+ else
+ {
+ pEntry->LastSecTxRateChangeAction = 0; // rate no change
+ bTxRateChanged = FALSE;
+ }
+
+ pEntry->LastTxOkCount = TxSuccess;
+
+ // reset all OneSecTx counters
+ RESET_ONE_SEC_TX_CNT(pEntry);
+
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pEntry->CurrTxRateIndex+1)*5];
+ if (bTxRateChanged && pNextTxRate)
+ {
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+ }
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Station side, Auto TxRate faster train up timer call back function.
+
+ Arguments:
+ SystemSpecific1 - Not used.
+ FunctionContext - Pointer to our Adapter context.
+ SystemSpecific2 - Not used.
+ SystemSpecific3 - Not used.
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID StaQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)FunctionContext;
+ UCHAR UpRateIdx = 0, DownRateIdx = 0, CurrRateIdx = 0;
+ ULONG TxTotalCnt;
+ ULONG TxErrorRatio = 0;
+ BOOLEAN bTxRateChanged; //, bUpgradeQuality = FALSE;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate = NULL;
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+ UCHAR InitTxRateIdx = 0, TrainUp, TrainDown;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ CHAR Rssi, ratio;
+ ULONG TxRetransmit = 0, TxSuccess = 0, TxFailCount = 0;
+ MAC_TABLE_ENTRY *pEntry;
+ ULONG i;
+
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+ //
+ // walk through MAC table, see if need to change AP's TX rate toward each entry
+ //
+ for (i = 1; i < MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ pEntry = &pAd->MacTab.Content[i];
+
+ // check if this entry need to switch rate automatically
+ if (RTMPCheckEntryEnableAutoRateSwitch(pAd, pEntry) == FALSE)
+ continue;
+
+ if (INFRA_ON(pAd) && (i == 1))
+ Rssi = RTMPMaxRssi(pAd,
+ pAd->StaCfg.RssiSample.AvgRssi0,
+ pAd->StaCfg.RssiSample.AvgRssi1,
+ pAd->StaCfg.RssiSample.AvgRssi2);
+ else
+ Rssi = RTMPMaxRssi(pAd,
+ pEntry->RssiSample.AvgRssi0,
+ pEntry->RssiSample.AvgRssi1,
+ pEntry->RssiSample.AvgRssi2);
+
+ CurrRateIdx = pAd->CommonCfg.TxRateIndex;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &InitTxRateIdx);
+
+ // decide the next upgrade rate and downgrade rate, if any
+ if ((CurrRateIdx > 0) && (CurrRateIdx < (TableSize - 1)))
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx -1;
+ }
+ else if (CurrRateIdx == 0)
+ {
+ UpRateIdx = CurrRateIdx + 1;
+ DownRateIdx = CurrRateIdx;
+ }
+ else if (CurrRateIdx == (TableSize - 1))
+ {
+ UpRateIdx = CurrRateIdx;
+ DownRateIdx = CurrRateIdx - 1;
+ }
+
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(CurrRateIdx+1)*5];
+
+#ifdef DOT11_N_SUPPORT
+ if ((Rssi > -65) && (pCurrTxRate->Mode >= MODE_HTMIX))
+ {
+ TrainUp = (pCurrTxRate->TrainUp + (pCurrTxRate->TrainUp >> 1));
+ TrainDown = (pCurrTxRate->TrainDown + (pCurrTxRate->TrainDown >> 1));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ TrainUp = pCurrTxRate->TrainUp;
+ TrainDown = pCurrTxRate->TrainDown;
+ }
+
+ if (pAd->MacTab.Size == 1)
+ {
+ // Update statistic counter
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+
+ TxRetransmit = StaTx1.field.TxRetransmit;
+ TxSuccess = StaTx1.field.TxSuccess;
+ TxFailCount = TxStaCnt0.field.TxFailCount;
+ TxTotalCnt = TxRetransmit + TxSuccess + TxFailCount;
+
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((TxRetransmit + TxFailCount) * 100) / TxTotalCnt;
+ }
+ else
+ {
+ TxTotalCnt = pEntry->OneSecTxNoRetryOkCount +
+ pEntry->OneSecTxRetryOkCount +
+ pEntry->OneSecTxFailCount;
+
+ if (TxTotalCnt)
+ TxErrorRatio = ((pEntry->OneSecTxRetryOkCount + pEntry->OneSecTxFailCount) * 100) / TxTotalCnt;
+ }
+
+
+ //
+ // CASE 1. when TX samples are fewer than 15, then decide TX rate solely on RSSI
+ // (criteria copied from RT2500 for Netopia case)
+ //
+ if (TxTotalCnt <= 12)
+ {
+ NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+
+ if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+ {
+ pAd->CommonCfg.TxRateIndex = DownRateIdx;
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
+ else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+ {
+ pAd->CommonCfg.TxRateIndex = UpRateIdx;
+ }
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: TxTotalCnt <= 15, train back to original rate \n"));
+ return;
+ }
+
+ do
+ {
+ ULONG OneSecTxNoRetryOKRationCount;
+
+ if (pAd->DrsCounters.LastTimeTxRateChangeAction == 0)
+ ratio = 5;
+ else
+ ratio = 4;
+
+ // downgrade TX quality if PER >= Rate-Down threshold
+ if (TxErrorRatio >= TrainDown)
+ {
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+ }
+
+ pAd->DrsCounters.PER[CurrRateIdx] = (UCHAR)TxErrorRatio;
+
+ OneSecTxNoRetryOKRationCount = (TxSuccess * ratio);
+
+ // perform DRS - consider TxRate Down first, then rate up.
+ if ((pAd->DrsCounters.LastSecTxRateChangeAction == 1) && (CurrRateIdx != DownRateIdx))
+ {
+ if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+ {
+ pAd->CommonCfg.TxRateIndex = DownRateIdx;
+ pAd->DrsCounters.TxQuality[CurrRateIdx] = DRS_TX_QUALITY_WORST_BOUND;
+
+ }
+
+ }
+ else if ((pAd->DrsCounters.LastSecTxRateChangeAction == 2) && (CurrRateIdx != UpRateIdx))
+ {
+ if ((TxErrorRatio >= 50) || (TxErrorRatio >= TrainDown))
+ {
+
+ }
+ else if ((pAd->DrsCounters.LastTxOkCount + 2) >= OneSecTxNoRetryOKRationCount)
+ {
+ pAd->CommonCfg.TxRateIndex = UpRateIdx;
+ }
+ }
+ }while (FALSE);
+
+ // if rate-up happen, clear all bad history of all TX rates
+ if (pAd->CommonCfg.TxRateIndex > CurrRateIdx)
+ {
+ pAd->DrsCounters.TxRateUpPenalty = 0;
+ NdisZeroMemory(pAd->DrsCounters.TxQuality, sizeof(USHORT) * MAX_STEP_OF_TX_RATE_SWITCH);
+ NdisZeroMemory(pAd->DrsCounters.PER, sizeof(UCHAR) * MAX_STEP_OF_TX_RATE_SWITCH);
+ bTxRateChanged = TRUE;
+ }
+ // if rate-down happen, only clear DownRate's bad history
+ else if (pAd->CommonCfg.TxRateIndex < CurrRateIdx)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("QuickDRS: --TX rate from %d to %d \n", CurrRateIdx, pAd->CommonCfg.TxRateIndex));
+
+ pAd->DrsCounters.TxRateUpPenalty = 0; // no penalty
+ pAd->DrsCounters.TxQuality[pAd->CommonCfg.TxRateIndex] = 0;
+ pAd->DrsCounters.PER[pAd->CommonCfg.TxRateIndex] = 0;
+ bTxRateChanged = TRUE;
+ }
+ else
+ {
+ bTxRateChanged = FALSE;
+ }
+
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH) &pTable[(pAd->CommonCfg.TxRateIndex+1)*5];
+ if (bTxRateChanged && pNextTxRate)
+ {
+ MlmeSetTxRate(pAd, pEntry, pNextTxRate);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ This routine is executed periodically inside MlmePeriodicExec() after
+ association with an AP.
+ It checks if StaCfg.Psm is consistent with user policy (recorded in
+ StaCfg.WindowsPowerMode). If not, enforce user policy. However,
+ there're some conditions to consider:
+ 1. we don't support power-saving in ADHOC mode, so Psm=PWR_ACTIVE all
+ the time when Mibss==TRUE
+ 2. When link up in INFRA mode, Psm should not be switch to PWR_SAVE
+ if outgoing traffic available in TxRing or MgmtRing.
+ Output:
+ 1. change pAd->StaCfg.Psm to PWR_SAVE or leave it untouched
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeCheckPsmChange(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32)
+{
+ ULONG PowerMode;
+
+ // condition -
+ // 1. Psm maybe ON only happen in INFRASTRUCTURE mode
+ // 2. user wants either MAX_PSP or FAST_PSP
+ // 3. but current psm is not in PWR_SAVE
+ // 4. CNTL state machine is not doing SCANning
+ // 5. no TX SUCCESS event for the past 1-sec period
+#ifdef NDIS51_MINIPORT
+ if (pAd->StaCfg.WindowsPowerProfile == NdisPowerProfileBattery)
+ PowerMode = pAd->StaCfg.WindowsBatteryPowerMode;
+ else
+#endif
+ PowerMode = pAd->StaCfg.WindowsPowerMode;
+
+ if (INFRA_ON(pAd) &&
+ (PowerMode != Ndis802_11PowerModeCAM) &&
+ (pAd->StaCfg.Psm == PWR_ACTIVE) &&
+// (! RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ (pAd->Mlme.CntlMachine.CurrState == CNTL_IDLE) /*&&
+ (pAd->RalinkCounters.OneSecTxNoRetryOkCount == 0) &&
+ (pAd->RalinkCounters.OneSecTxRetryOkCount == 0)*/)
+ {
+ // add by johnli, use Rx OK data count per second to calculate throughput
+ // If Ttraffic is too high ( > 400 Rx per second), don't go to sleep mode. If tx rate is low, use low criteria
+ // Mode=CCK/MCS=3 => 11 Mbps, Mode=OFDM/MCS=3 => 18 Mbps
+ if (((pAd->StaCfg.HTPhyMode.field.MCS <= 3) &&
+/* Iverson mark
+ (pAd->StaCfg.HTPhyMode.field.MODE <= MODE_OFDM) &&
+*/
+ (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)100)) ||
+ ((pAd->StaCfg.HTPhyMode.field.MCS > 3) &&
+/* Iverson mark
+ (pAd->StaCfg.HTPhyMode.field.MODE > MODE_OFDM) &&
+*/
+ (pAd->RalinkCounters.OneSecRxOkDataCnt < (ULONG)400)))
+ {
+ // Get this time
+ NdisGetSystemUpTime(&pAd->Mlme.LastSendNULLpsmTime);
+ pAd->RalinkCounters.RxCountSinceLastNULL = 0;
+ MlmeSetPsmBit(pAd, PWR_SAVE);
+ if (!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable))
+ {
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, FALSE);
+ }
+ else
+ {
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ }
+ }
+ }
+}
+
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetPsmBit(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT psm)
+{
+ AUTO_RSP_CFG_STRUC csr4;
+
+ pAd->StaCfg.Psm = psm;
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+ csr4.field.AckCtsPsmBit = (psm == PWR_SAVE)? 1:0;
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeSetTxPreamble(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TxPreamble)
+{
+ AUTO_RSP_CFG_STRUC csr4;
+
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ //TxPreamble = Rt802_11PreambleLong;
+
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &csr4.word);
+ if (TxPreamble == Rt802_11PreambleLong)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= LONG PREAMBLE)\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ csr4.field.AutoResponderPreamble = 0;
+ }
+ else
+ {
+ // NOTE: 1Mbps should always use long preamble
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeSetTxPreamble (= SHORT PREAMBLE)\n"));
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ csr4.field.AutoResponderPreamble = 1;
+ }
+
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, csr4.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Update basic rate bitmap
+ ==========================================================================
+ */
+
+VOID UpdateBasicRateBitmap(
+ IN PRTMP_ADAPTER pAdapter)
+{
+ INT i, j;
+ /* 1 2 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54 */
+ UCHAR rate[] = { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 };
+ UCHAR *sup_p = pAdapter->CommonCfg.SupRate;
+ UCHAR *ext_p = pAdapter->CommonCfg.ExtRate;
+ ULONG bitmap = pAdapter->CommonCfg.BasicRateBitmap;
+
+
+ /* if A mode, always use fix BasicRateBitMap */
+ //if (pAdapter->CommonCfg.Channel == PHY_11A)
+ if (pAdapter->CommonCfg.Channel > 14)
+ pAdapter->CommonCfg.BasicRateBitmap = 0x150; /* 6, 12, 24M */
+ /* End of if */
+
+ if (pAdapter->CommonCfg.BasicRateBitmap > 4095)
+ {
+ /* (2 ^ MAX_LEN_OF_SUPPORTED_RATES) -1 */
+ return;
+ } /* End of if */
+
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ sup_p[i] &= 0x7f;
+ ext_p[i] &= 0x7f;
+ } /* End of for */
+
+ for(i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ if (bitmap & (1 << i))
+ {
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (sup_p[j] == rate[i])
+ sup_p[j] |= 0x80;
+ /* End of if */
+ } /* End of for */
+
+ for(j=0; j<MAX_LEN_OF_SUPPORTED_RATES; j++)
+ {
+ if (ext_p[j] == rate[i])
+ ext_p[j] |= 0x80;
+ /* End of if */
+ } /* End of for */
+ } /* End of if */
+ } /* End of for */
+} /* End of UpdateBasicRateBitmap */
+
+// IRQL = PASSIVE_LEVEL
+// IRQL = DISPATCH_LEVEL
+// bLinkUp is to identify the inital link speed.
+// TRUE indicates the rate update at linkup, we should not try to set the rate at 54Mbps.
+VOID MlmeUpdateTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bLinkUp,
+ IN UCHAR apidx)
+{
+ int i, num;
+ UCHAR Rate = RATE_6, MaxDesire = RATE_1, MaxSupport = RATE_1;
+ UCHAR MinSupport = RATE_54;
+ ULONG BasicRateBitmap = 0;
+ UCHAR CurrBasicRate = RATE_1;
+ UCHAR *pSupRate, SupRateLen, *pExtRate, ExtRateLen;
+ PHTTRANSMIT_SETTING pHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+ BOOLEAN *auto_rate_cur_p;
+ UCHAR HtMcs = MCS_AUTO;
+
+ // find max desired rate
+ UpdateBasicRateBitmap(pAd);
+
+ num = 0;
+ auto_rate_cur_p = NULL;
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ switch (pAd->CommonCfg.DesireRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; num++; break;
+ case 4: Rate = RATE_2; num++; break;
+ case 11: Rate = RATE_5_5; num++; break;
+ case 22: Rate = RATE_11; num++; break;
+ case 12: Rate = RATE_6; num++; break;
+ case 18: Rate = RATE_9; num++; break;
+ case 24: Rate = RATE_12; num++; break;
+ case 36: Rate = RATE_18; num++; break;
+ case 48: Rate = RATE_24; num++; break;
+ case 72: Rate = RATE_36; num++; break;
+ case 96: Rate = RATE_48; num++; break;
+ case 108: Rate = RATE_54; num++; break;
+ //default: Rate = RATE_1; break;
+ }
+ if (MaxDesire < Rate) MaxDesire = Rate;
+ }
+
+//===========================================================================
+//===========================================================================
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pHtPhy = &pAd->StaCfg.HTPhyMode;
+ pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+ pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+ HtMcs = pAd->StaCfg.DesiredTransmitSetting.field.MCS;
+
+ if ((pAd->StaCfg.BssType == BSS_ADHOC) &&
+ (pAd->CommonCfg.PhyMode == PHY_11B) &&
+ (MaxDesire > RATE_11))
+ {
+ MaxDesire = RATE_11;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ pAd->CommonCfg.MaxDesiredRate = MaxDesire;
+ pMinHtPhy->word = 0;
+ pMaxHtPhy->word = 0;
+ pHtPhy->word = 0;
+
+ // Auto rate switching is enabled only if more than one DESIRED RATES are
+ // specified; otherwise disabled
+ if (num <= 1)
+ {
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
+ *auto_rate_cur_p = FALSE;
+ }
+ else
+ {
+ //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
+ *auto_rate_cur_p = TRUE;
+ }
+
+#if 1
+ if (HtMcs != MCS_AUTO)
+ {
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = FALSE;
+ *auto_rate_cur_p = FALSE;
+ }
+ else
+ {
+ //OPSTATUS_SET_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED);
+ //pAd->CommonCfg.bAutoTxRateSwitch = TRUE;
+ *auto_rate_cur_p = TRUE;
+ }
+#endif
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
+ {
+ pSupRate = &pAd->StaActive.SupRate[0];
+ pExtRate = &pAd->StaActive.ExtRate[0];
+ SupRateLen = pAd->StaActive.SupRateLen;
+ ExtRateLen = pAd->StaActive.ExtRateLen;
+ }
+ else
+#endif // CONFIG_STA_SUPPORT //
+ {
+ pSupRate = &pAd->CommonCfg.SupRate[0];
+ pExtRate = &pAd->CommonCfg.ExtRate[0];
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+ ExtRateLen = pAd->CommonCfg.ExtRateLen;
+ }
+
+ // find max supported rate
+ for (i=0; i<SupRateLen; i++)
+ {
+ switch (pSupRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
+ case 4: Rate = RATE_2; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
+ case 11: Rate = RATE_5_5; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
+ case 22: Rate = RATE_11; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
+ case 12: Rate = RATE_6; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
+ case 18: Rate = RATE_9; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
+ case 24: Rate = RATE_12; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
+ case 36: Rate = RATE_18; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
+ case 48: Rate = RATE_24; /*if (pSupRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
+ case 72: Rate = RATE_36; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
+ case 96: Rate = RATE_48; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
+ case 108: Rate = RATE_54; if (pSupRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
+ default: Rate = RATE_1; break;
+ }
+ if (MaxSupport < Rate) MaxSupport = Rate;
+
+ if (MinSupport > Rate) MinSupport = Rate;
+ }
+
+ for (i=0; i<ExtRateLen; i++)
+ {
+ switch (pExtRate[i] & 0x7f)
+ {
+ case 2: Rate = RATE_1; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0001; break;
+ case 4: Rate = RATE_2; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0002; break;
+ case 11: Rate = RATE_5_5; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0004; break;
+ case 22: Rate = RATE_11; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0008; break;
+ case 12: Rate = RATE_6; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0010; break;
+ case 18: Rate = RATE_9; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0020; break;
+ case 24: Rate = RATE_12; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0040; break;
+ case 36: Rate = RATE_18; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0080; break;
+ case 48: Rate = RATE_24; /*if (pExtRate[i] & 0x80)*/ BasicRateBitmap |= 0x0100; break;
+ case 72: Rate = RATE_36; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0200; break;
+ case 96: Rate = RATE_48; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0400; break;
+ case 108: Rate = RATE_54; if (pExtRate[i] & 0x80) BasicRateBitmap |= 0x0800; break;
+ default: Rate = RATE_1; break;
+ }
+ if (MaxSupport < Rate) MaxSupport = Rate;
+
+ if (MinSupport > Rate) MinSupport = Rate;
+ }
+
+ RTMP_IO_WRITE32(pAd, LEGACY_BASIC_RATE, BasicRateBitmap);
+
+ // calculate the exptected ACK rate for each TX rate. This info is used to caculate
+ // the DURATION field of outgoing uniicast DATA/MGMT frame
+ for (i=0; i<MAX_LEN_OF_SUPPORTED_RATES; i++)
+ {
+ if (BasicRateBitmap & (0x01 << i))
+ CurrBasicRate = (UCHAR)i;
+ pAd->CommonCfg.ExpectedACKRate[i] = CurrBasicRate;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateTxRates[MaxSupport = %d] = MaxDesire %d Mbps\n", RateIdToMbps[MaxSupport], RateIdToMbps[MaxDesire]));
+ // max tx rate = min {max desire rate, max supported rate}
+ if (MaxSupport < MaxDesire)
+ pAd->CommonCfg.MaxTxRate = MaxSupport;
+ else
+ pAd->CommonCfg.MaxTxRate = MaxDesire;
+
+ pAd->CommonCfg.MinTxRate = MinSupport;
+ // 2003-07-31 john - 2500 doesn't have good sensitivity at high OFDM rates. to increase the success
+ // ratio of initial DHCP packet exchange, TX rate starts from a lower rate depending
+ // on average RSSI
+ // 1. RSSI >= -70db, start at 54 Mbps (short distance)
+ // 2. -70 > RSSI >= -75, start at 24 Mbps (mid distance)
+ // 3. -75 > RSSI, start at 11 Mbps (long distance)
+ //if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)/* &&
+ // OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)*/)
+ if (*auto_rate_cur_p)
+ {
+ short dbm = 0;
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ dbm = pAd->StaCfg.RssiSample.AvgRssi0 - pAd->BbpRssiToDbmDelta;
+#endif // CONFIG_STA_SUPPORT //
+ if (bLinkUp == TRUE)
+ pAd->CommonCfg.TxRate = RATE_24;
+ else
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+
+ if (dbm < -75)
+ pAd->CommonCfg.TxRate = RATE_11;
+ else if (dbm < -70)
+ pAd->CommonCfg.TxRate = RATE_24;
+
+ // should never exceed MaxTxRate (consider 11B-only mode)
+ if (pAd->CommonCfg.TxRate > pAd->CommonCfg.MaxTxRate)
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+
+ pAd->CommonCfg.TxRateIndex = 0;
+ }
+ else
+ {
+ pAd->CommonCfg.TxRate = pAd->CommonCfg.MaxTxRate;
+ pHtPhy->field.MCS = (pAd->CommonCfg.MaxTxRate > 3) ? (pAd->CommonCfg.MaxTxRate - 4) : pAd->CommonCfg.MaxTxRate;
+ pHtPhy->field.MODE = (pAd->CommonCfg.MaxTxRate > 3) ? MODE_OFDM : MODE_CCK;
+
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC = pHtPhy->field.STBC;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI = pHtPhy->field.ShortGI;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS = pHtPhy->field.MCS;
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE = pHtPhy->field.MODE;
+ }
+
+ if (pAd->CommonCfg.TxRate <= RATE_11)
+ {
+ pMaxHtPhy->field.MODE = MODE_CCK;
+ pMaxHtPhy->field.MCS = pAd->CommonCfg.TxRate;
+ pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;
+ }
+ else
+ {
+ pMaxHtPhy->field.MODE = MODE_OFDM;
+ pMaxHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.TxRate];
+ if (pAd->CommonCfg.MinTxRate >= RATE_6 && (pAd->CommonCfg.MinTxRate <= RATE_54))
+ {pMinHtPhy->field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MinTxRate];}
+ else
+ {pMinHtPhy->field.MCS = pAd->CommonCfg.MinTxRate;}
+ }
+
+ pHtPhy->word = (pMaxHtPhy->word);
+ if (bLinkUp && (pAd->OpMode == OPMODE_STA))
+ {
+ pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word = pHtPhy->word;
+ pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word = pMaxHtPhy->word;
+ pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word = pMinHtPhy->word;
+ }
+ else
+ {
+ switch (pAd->CommonCfg.PhyMode)
+ {
+ case PHY_11BG_MIXED:
+ case PHY_11B:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11BGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.MlmeRate = RATE_1;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+
+//#ifdef WIFI_TEST
+ pAd->CommonCfg.RtsRate = RATE_11;
+//#else
+// pAd->CommonCfg.RtsRate = RATE_1;
+//#endif
+ break;
+ case PHY_11G:
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11AGN_MIXED:
+ case PHY_11GN_MIXED:
+ case PHY_11N_2_4G:
+ case PHY_11AN_MIXED:
+ case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ break;
+ case PHY_11ABG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11ABGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ pAd->CommonCfg.MlmeRate = RATE_1;
+ pAd->CommonCfg.RtsRate = RATE_1;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = RATE_1;
+ }
+ else
+ {
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ }
+ break;
+ default: // error
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ pAd->CommonCfg.RtsRate = RATE_1;
+ break;
+ }
+ //
+ // Keep Basic Mlme Rate.
+ //
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.word = pAd->CommonCfg.MlmeTransmit.word;
+ if (pAd->CommonCfg.MlmeTransmit.field.MODE == MODE_OFDM)
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[RATE_24];
+ else
+ pAd->MacTab.Content[MCAST_WCID].HTPhyMode.field.MCS = RATE_1;
+ pAd->CommonCfg.BasicMlmeRate = pAd->CommonCfg.MlmeRate;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (MaxDesire=%d, MaxSupport=%d, MaxTxRate=%d, MinRate=%d, Rate Switching =%d)\n",
+ RateIdToMbps[MaxDesire], RateIdToMbps[MaxSupport], RateIdToMbps[pAd->CommonCfg.MaxTxRate], RateIdToMbps[pAd->CommonCfg.MinTxRate],
+ /*OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED)*/*auto_rate_cur_p));
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (TxRate=%d, RtsRate=%d, BasicRateBitmap=0x%04lx)\n",
+ RateIdToMbps[pAd->CommonCfg.TxRate], RateIdToMbps[pAd->CommonCfg.RtsRate], BasicRateBitmap));
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeUpdateTxRates (MlmeTransmit=0x%x, MinHTPhyMode=%x, MaxHTPhyMode=0x%x, HTPhyMode=0x%x)\n",
+ pAd->CommonCfg.MlmeTransmit.word, pAd->MacTab.Content[BSSID_WCID].MinHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].MaxHTPhyMode.word ,pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word ));
+}
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ This function update HT Rate setting.
+ Input Wcid value is valid for 2 case :
+ 1. it's used for Station in infra mode that copy AP rate to Mactable.
+ 2. OR Station in adhoc mode to copy peer's HT rate to Mactable.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeUpdateHtTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx)
+{
+ UCHAR StbcMcs; //j, StbcMcs, bitmask;
+ CHAR i; // 3*3
+ RT_HT_CAPABILITY *pRtHtCap = NULL;
+ RT_HT_PHY_INFO *pActiveHtPhy = NULL;
+ ULONG BasicMCS;
+ UCHAR j, bitmask;
+ PRT_HT_PHY_INFO pDesireHtPhy = NULL;
+ PHTTRANSMIT_SETTING pHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMaxHtPhy = NULL;
+ PHTTRANSMIT_SETTING pMinHtPhy = NULL;
+ BOOLEAN *auto_rate_cur_p;
+
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates===> \n"));
+
+ auto_rate_cur_p = NULL;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ pDesireHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+ pActiveHtPhy = &pAd->StaCfg.DesiredHtPhyInfo;
+ pHtPhy = &pAd->StaCfg.HTPhyMode;
+ pMaxHtPhy = &pAd->StaCfg.MaxHTPhyMode;
+ pMinHtPhy = &pAd->StaCfg.MinHTPhyMode;
+
+ auto_rate_cur_p = &pAd->StaCfg.bAutoTxRateSwitch;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ if ((ADHOC_ON(pAd) || INFRA_ON(pAd)) && (pAd->OpMode == OPMODE_STA))
+ {
+ if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+ return;
+
+ pRtHtCap = &pAd->StaActive.SupportedHtPhy;
+ pActiveHtPhy = &pAd->StaActive.SupportedPhyInfo;
+ StbcMcs = (UCHAR)pAd->MlmeAux.AddHtInfo.AddHtInfo3.StbcMcs;
+ BasicMCS =pAd->MlmeAux.AddHtInfo.MCSSet[0]+(pAd->MlmeAux.AddHtInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+ if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+ pMaxHtPhy->field.STBC = STBC_USE;
+ else
+ pMaxHtPhy->field.STBC = STBC_NONE;
+ }
+ else
+#endif // CONFIG_STA_SUPPORT //
+ {
+ if (pDesireHtPhy->bHtEnable == FALSE)
+ return;
+
+ pRtHtCap = &pAd->CommonCfg.DesiredHtPhy;
+ StbcMcs = (UCHAR)pAd->CommonCfg.AddHTInfo.AddHtInfo3.StbcMcs;
+ BasicMCS = pAd->CommonCfg.AddHTInfo.MCSSet[0]+(pAd->CommonCfg.AddHTInfo.MCSSet[1]<<8)+(StbcMcs<<16);
+ if ((pAd->CommonCfg.DesiredHtPhy.TxSTBC) && (pRtHtCap->RxSTBC) && (pAd->Antenna.field.TxPath == 2))
+ pMaxHtPhy->field.STBC = STBC_USE;
+ else
+ pMaxHtPhy->field.STBC = STBC_NONE;
+ }
+
+ // Decide MAX ht rate.
+ if ((pRtHtCap->GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ pMaxHtPhy->field.MODE = MODE_HTGREENFIELD;
+ else
+ pMaxHtPhy->field.MODE = MODE_HTMIX;
+
+ if ((pAd->CommonCfg.DesiredHtPhy.ChannelWidth) && (pRtHtCap->ChannelWidth))
+ pMaxHtPhy->field.BW = BW_40;
+ else
+ pMaxHtPhy->field.BW = BW_20;
+
+ if (pMaxHtPhy->field.BW == BW_20)
+ pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20 & pRtHtCap->ShortGIfor20);
+ else
+ pMaxHtPhy->field.ShortGI = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40 & pRtHtCap->ShortGIfor40);
+
+ for (i=23; i>=0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+
+ if ((pActiveHtPhy->MCSSet[j] & bitmask) && (pDesireHtPhy->MCSSet[j] & bitmask))
+ {
+ pMaxHtPhy->field.MCS = i;
+ break;
+ }
+
+ if (i==0)
+ break;
+ }
+
+ // Copy MIN ht rate. rt2860???
+ pMinHtPhy->field.BW = BW_20;
+ pMinHtPhy->field.MCS = 0;
+ pMinHtPhy->field.STBC = 0;
+ pMinHtPhy->field.ShortGI = 0;
+ //If STA assigns fixed rate. update to fixed here.
+#ifdef CONFIG_STA_SUPPORT
+ if ( (pAd->OpMode == OPMODE_STA) && (pDesireHtPhy->MCSSet[0] != 0xff))
+ {
+ if (pDesireHtPhy->MCSSet[4] != 0)
+ {
+ pMaxHtPhy->field.MCS = 32;
+ pMinHtPhy->field.MCS = 32;
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== Use Fixed MCS = %d\n",pMinHtPhy->field.MCS));
+ }
+
+ for (i=23; (CHAR)i >= 0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+ if ( (pDesireHtPhy->MCSSet[j] & bitmask) && (pActiveHtPhy->MCSSet[j] & bitmask))
+ {
+ pMaxHtPhy->field.MCS = i;
+ pMinHtPhy->field.MCS = i;
+ break;
+ }
+ if (i==0)
+ break;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ // Decide ht rate
+ pHtPhy->field.STBC = pMaxHtPhy->field.STBC;
+ pHtPhy->field.BW = pMaxHtPhy->field.BW;
+ pHtPhy->field.MODE = pMaxHtPhy->field.MODE;
+ pHtPhy->field.MCS = pMaxHtPhy->field.MCS;
+ pHtPhy->field.ShortGI = pMaxHtPhy->field.ShortGI;
+
+ // use default now. rt2860
+ if (pDesireHtPhy->MCSSet[0] != 0xff)
+ *auto_rate_cur_p = FALSE;
+ else
+ *auto_rate_cur_p = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateHtTxRates<---.AMsduSize = %d \n", pAd->CommonCfg.DesiredHtPhy.AmsduSize ));
+ DBGPRINT(RT_DEBUG_TRACE,("TX: MCS[0] = %x (choose %d), BW = %d, ShortGI = %d, MODE = %d, \n", pActiveHtPhy->MCSSet[0],pHtPhy->field.MCS,
+ pHtPhy->field.BW, pHtPhy->field.ShortGI, pHtPhy->field.MODE));
+ DBGPRINT(RT_DEBUG_TRACE,("MlmeUpdateHtTxRates<=== \n"));
+}
+#endif // DOT11_N_SUPPORT //
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOff(
+ IN PRTMP_ADAPTER pAd)
+{
+ RT28XX_MLME_RADIO_OFF(pAd);
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRadioOn(
+ IN PRTMP_ADAPTER pAd)
+{
+ RT28XX_MLME_RADIO_ON(pAd);
+}
+
+// ===========================================================================================
+// bss_table.c
+// ===========================================================================================
+
+
+/*! \brief initialize BSS table
+ * \param p_tab pointer to the table
+ * \return none
+ * \pre
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID BssTableInit(
+ IN BSS_TABLE *Tab)
+{
+ int i;
+
+ Tab->BssNr = 0;
+ Tab->BssOverlapNr = 0;
+ for (i = 0; i < MAX_LEN_OF_BSS_TABLE; i++)
+ {
+ NdisZeroMemory(&Tab->BssEntry[i], sizeof(BSS_ENTRY));
+ Tab->BssEntry[i].Rssi = -127; // initial the rssi as a minimum value
+ }
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInit(
+ IN PRTMP_ADAPTER pAd,
+ IN BA_TABLE *Tab)
+{
+ int i;
+
+ Tab->numAsOriginator = 0;
+ Tab->numAsRecipient = 0;
+ NdisAllocateSpinLock(&pAd->BATabLock);
+ for (i = 0; i < MAX_LEN_OF_BA_REC_TABLE; i++)
+ {
+ Tab->BARecEntry[i].REC_BA_Status = Recipient_NONE;
+ NdisAllocateSpinLock(&(Tab->BARecEntry[i].RxReRingLock));
+ }
+ for (i = 0; i < MAX_LEN_OF_BA_ORI_TABLE; i++)
+ {
+ Tab->BAOriEntry[i].ORI_BA_Status = Originator_NONE;
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+/*! \brief search the BSS table by SSID
+ * \param p_tab pointer to the bss table
+ * \param ssid SSID string
+ * \return index of the table, BSS_NOT_FOUND if not in the table
+ * \pre
+ * \post
+ * \note search by sequential search
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ //
+ // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+ // We should distinguish this case.
+ //
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+ULONG BssSsidTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ //
+ // Some AP that support A/B/G mode that may used the same BSSID on 11A and 11B/G.
+ // We should distinguish this case.
+ //
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid) &&
+ SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+ULONG BssTableSearchWithSSID(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR Bssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel)
+{
+ UCHAR i;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ if ((((Tab->BssEntry[i].Channel <= 14) && (Channel <= 14)) ||
+ ((Tab->BssEntry[i].Channel > 14) && (Channel > 14))) &&
+ MAC_ADDR_EQUAL(&(Tab->BssEntry[i].Bssid), Bssid) &&
+ (SSID_EQUAL(pSsid, SsidLen, Tab->BssEntry[i].Ssid, Tab->BssEntry[i].SsidLen) ||
+ (NdisEqualMemory(pSsid, ZeroSsid, SsidLen)) ||
+ (NdisEqualMemory(Tab->BssEntry[i].Ssid, ZeroSsid, Tab->BssEntry[i].SsidLen))))
+ {
+ return i;
+ }
+ }
+ return (ULONG)BSS_NOT_FOUND;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableDeleteEntry(
+ IN OUT BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel)
+{
+ UCHAR i, j;
+
+ for (i = 0; i < Tab->BssNr; i++)
+ {
+ if ((Tab->BssEntry[i].Channel == Channel) &&
+ (MAC_ADDR_EQUAL(Tab->BssEntry[i].Bssid, pBssid)))
+ {
+ for (j = i; j < Tab->BssNr - 1; j++)
+ {
+ NdisMoveMemory(&(Tab->BssEntry[j]), &(Tab->BssEntry[j + 1]), sizeof(BSS_ENTRY));
+ }
+ NdisZeroMemory(&(Tab->BssEntry[Tab->BssNr - 1]), sizeof(BSS_ENTRY));
+ Tab->BssNr -= 1;
+ return;
+ }
+ }
+}
+
+#ifdef DOT11_N_SUPPORT
+/*
+ ========================================================================
+ Routine Description:
+ Delete the Originator Entry in BAtable. Or decrease numAs Originator by 1 if needed.
+
+ Arguments:
+ // IRQL = DISPATCH_LEVEL
+ ========================================================================
+*/
+VOID BATableDeleteORIEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN BA_ORI_ENTRY *pBAORIEntry)
+{
+
+ if (pBAORIEntry->ORI_BA_Status != Originator_NONE)
+ {
+ NdisAcquireSpinLock(&pAd->BATabLock);
+ if (pBAORIEntry->ORI_BA_Status == Originator_Done)
+ {
+ pAd->BATable.numAsOriginator -= 1;
+ DBGPRINT(RT_DEBUG_TRACE, ("BATableDeleteORIEntry numAsOriginator= %ld\n", pAd->BATable.numAsRecipient));
+ // Erase Bitmap flag.
+ }
+ pAd->MacTab.Content[pBAORIEntry->Wcid].TXBAbitmap &= (~(1<<(pBAORIEntry->TID) )); // If STA mode, erase flag here
+ pAd->MacTab.Content[pBAORIEntry->Wcid].BAOriWcidArray[pBAORIEntry->TID] = 0; // If STA mode, erase flag here
+ pBAORIEntry->ORI_BA_Status = Originator_NONE;
+ pBAORIEntry->Token = 1;
+ // Not clear Sequence here.
+ NdisReleaseSpinLock(&pAd->BATabLock);
+ }
+}
+#endif // DOT11_N_SUPPORT //
+
+/*! \brief
+ * \param
+ * \return
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID BssEntrySet(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_ENTRY *pBss,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN PCF_PARM pCfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR Channel,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ COPY_MAC_ADDR(pBss->Bssid, pBssid);
+ // Default Hidden SSID to be TRUE, it will be turned to FALSE after coping SSID
+ pBss->Hidden = 1;
+ if (SsidLen > 0)
+ {
+ // For hidden SSID AP, it might send beacon with SSID len equal to 0
+ // Or send beacon /probe response with SSID len matching real SSID length,
+ // but SSID is all zero. such as "00-00-00-00" with length 4.
+ // We have to prevent this case overwrite correct table
+ if (NdisEqualMemory(Ssid, ZeroSsid, SsidLen) == 0)
+ {
+ NdisZeroMemory(pBss->Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pBss->Ssid, Ssid, SsidLen);
+ pBss->SsidLen = SsidLen;
+ pBss->Hidden = 0;
+ }
+ }
+ else
+ pBss->SsidLen = 0;
+ pBss->BssType = BssType;
+ pBss->BeaconPeriod = BeaconPeriod;
+ if (BssType == BSS_INFRA)
+ {
+ if (pCfParm->bValid)
+ {
+ pBss->CfpCount = pCfParm->CfpCount;
+ pBss->CfpPeriod = pCfParm->CfpPeriod;
+ pBss->CfpMaxDuration = pCfParm->CfpMaxDuration;
+ pBss->CfpDurRemaining = pCfParm->CfpDurRemaining;
+ }
+ }
+ else
+ {
+ pBss->AtimWin = AtimWin;
+ }
+
+ pBss->CapabilityInfo = CapabilityInfo;
+ // The privacy bit indicate security is ON, it maight be WEP, TKIP or AES
+ // Combine with AuthMode, they will decide the connection methods.
+ pBss->Privacy = CAP_IS_PRIVACY_ON(pBss->CapabilityInfo);
+ ASSERT(SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ if (SupRateLen <= MAX_LEN_OF_SUPPORTED_RATES)
+ NdisMoveMemory(pBss->SupRate, SupRate, SupRateLen);
+ else
+ NdisMoveMemory(pBss->SupRate, SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ pBss->SupRateLen = SupRateLen;
+ ASSERT(ExtRateLen <= MAX_LEN_OF_SUPPORTED_RATES);
+ NdisMoveMemory(pBss->ExtRate, ExtRate, ExtRateLen);
+ NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
+ NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+ pBss->NewExtChanOffset = NewExtChanOffset;
+ pBss->ExtRateLen = ExtRateLen;
+ pBss->Channel = Channel;
+ pBss->CentralChannel = Channel;
+ pBss->Rssi = Rssi;
+ // Update CkipFlag. if not exists, the value is 0x0
+ pBss->CkipFlag = CkipFlag;
+
+ // New for microsoft Fixed IEs
+ NdisMoveMemory(pBss->FixIEs.Timestamp, &TimeStamp, 8);
+ pBss->FixIEs.BeaconInterval = BeaconPeriod;
+ pBss->FixIEs.Capabilities = CapabilityInfo;
+
+ // New for microsoft Variable IEs
+ if (LengthVIE != 0)
+ {
+ pBss->VarIELen = LengthVIE;
+ NdisMoveMemory(pBss->VarIEs, pVIE, pBss->VarIELen);
+ }
+ else
+ {
+ pBss->VarIELen = 0;
+ }
+
+ pBss->AddHtInfoLen = 0;
+ pBss->HtCapabilityLen = 0;
+#ifdef DOT11_N_SUPPORT
+ if (HtCapabilityLen> 0)
+ {
+ pBss->HtCapabilityLen = HtCapabilityLen;
+ NdisMoveMemory(&pBss->HtCapability, pHtCapability, HtCapabilityLen);
+ if (AddHtInfoLen > 0)
+ {
+ pBss->AddHtInfoLen = AddHtInfoLen;
+ NdisMoveMemory(&pBss->AddHtInfo, pAddHtInfo, AddHtInfoLen);
+
+ if ((pAddHtInfo->ControlChan > 2)&& (pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
+ {
+ pBss->CentralChannel = pAddHtInfo->ControlChan - 2;
+ }
+ else if ((pAddHtInfo->AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (pHtCapability->HtCapInfo.ChannelWidth == BW_40))
+ {
+ pBss->CentralChannel = pAddHtInfo->ControlChan + 2;
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ BssCipherParse(pBss);
+
+ // new for QOS
+ if (pEdcaParm)
+ NdisMoveMemory(&pBss->EdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+ else
+ pBss->EdcaParm.bValid = FALSE;
+ if (pQosCapability)
+ NdisMoveMemory(&pBss->QosCapability, pQosCapability, sizeof(QOS_CAPABILITY_PARM));
+ else
+ pBss->QosCapability.bValid = FALSE;
+ if (pQbssLoad)
+ NdisMoveMemory(&pBss->QbssLoad, pQbssLoad, sizeof(QBSS_LOAD_PARM));
+ else
+ pBss->QbssLoad.bValid = FALSE;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ PEID_STRUCT pEid;
+ USHORT Length = 0;
+
+
+ NdisZeroMemory(&pBss->WpaIE.IE[0], MAX_CUSTOM_LEN);
+ NdisZeroMemory(&pBss->RsnIE.IE[0], MAX_CUSTOM_LEN);
+#ifdef EXT_BUILD_CHANNEL_LIST
+ NdisZeroMemory(&pBss->CountryString[0], 3);
+ pBss->bHasCountryIE = FALSE;
+#endif // EXT_BUILD_CHANNEL_LIST //
+ pEid = (PEID_STRUCT) pVIE;
+ while ((Length + 2 + (USHORT)pEid->Len) <= LengthVIE)
+ {
+ switch(pEid->Eid)
+ {
+ case IE_WPA:
+ if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+ {
+ if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
+ {
+ pBss->WpaIE.IELen = 0;
+ break;
+ }
+ pBss->WpaIE.IELen = pEid->Len + 2;
+ NdisMoveMemory(pBss->WpaIE.IE, pEid, pBss->WpaIE.IELen);
+ }
+ break;
+ case IE_RSN:
+ if (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+ {
+ if ((pEid->Len + 2) > MAX_CUSTOM_LEN)
+ {
+ pBss->RsnIE.IELen = 0;
+ break;
+ }
+ pBss->RsnIE.IELen = pEid->Len + 2;
+ NdisMoveMemory(pBss->RsnIE.IE, pEid, pBss->RsnIE.IELen);
+ }
+ break;
+#ifdef EXT_BUILD_CHANNEL_LIST
+ case IE_COUNTRY:
+ NdisMoveMemory(&pBss->CountryString[0], pEid->Octet, 3);
+ pBss->bHasCountryIE = TRUE;
+ break;
+#endif // EXT_BUILD_CHANNEL_LIST //
+ }
+ Length = Length + 2 + (USHORT)pEid->Len; // Eid[1] + Len[1]+ content[Len]
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+}
+
+/*!
+ * \brief insert an entry into the bss table
+ * \param p_tab The BSS table
+ * \param Bssid BSSID
+ * \param ssid SSID
+ * \param ssid_len Length of SSID
+ * \param bss_type
+ * \param beacon_period
+ * \param timestamp
+ * \param p_cf
+ * \param atim_win
+ * \param cap
+ * \param rates
+ * \param rates_len
+ * \param channel_idx
+ * \return none
+ * \pre
+ * \post
+ * \note If SSID is identical, the old entry will be replaced by the new one
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+ULONG BssTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN CF_PARM *CfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR ChannelNo,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE)
+{
+ ULONG Idx;
+
+ Idx = BssTableSearchWithSSID(Tab, pBssid, Ssid, SsidLen, ChannelNo);
+ if (Idx == BSS_NOT_FOUND)
+ {
+ if (Tab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+ {
+ //
+ // It may happen when BSS Table was full.
+ // The desired AP will not be added into BSS Table
+ // In this case, if we found the desired AP then overwrite BSS Table.
+ //
+ if(!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, pBssid) ||
+ SSID_EQUAL(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Ssid, SsidLen))
+ {
+ Idx = Tab->BssOverlapNr;
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ Tab->BssOverlapNr = (Tab->BssOverlapNr++) % MAX_LEN_OF_BSS_TABLE;
+ }
+ return Idx;
+ }
+ else
+ {
+ return BSS_NOT_FOUND;
+ }
+ }
+ Idx = Tab->BssNr;
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod, CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ Tab->BssNr++;
+ }
+ else
+ {
+ /* avoid Hidden SSID form beacon to overwirite correct SSID from probe response */
+ if ((SSID_EQUAL(Ssid, SsidLen, Tab->BssEntry[Idx].Ssid, Tab->BssEntry[Idx].SsidLen)) ||
+ (NdisEqualMemory(Tab->BssEntry[Idx].Ssid, ZeroSsid, Tab->BssEntry[Idx].SsidLen)))
+ {
+ BssEntrySet(pAd, &Tab->BssEntry[Idx], pBssid, Ssid, SsidLen, BssType, BeaconPeriod,CfParm, AtimWin,
+ CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,pHtCapability, pAddHtInfo,HtCapabilityLen, AddHtInfoLen,
+ NewExtChanOffset, ChannelNo, Rssi, TimeStamp, CkipFlag, pEdcaParm, pQosCapability, pQbssLoad, LengthVIE, pVIE);
+ }
+ }
+
+ return Idx;
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID TriEventInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+
+ for (i = 0;i < MAX_TRIGGER_EVENT;i++)
+ pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
+
+ pAd->CommonCfg.TriggerEventTab.EventANo = 0;
+ pAd->CommonCfg.TriggerEventTab.EventBCountDown = 0;
+}
+
+ULONG TriEventTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT TRIGGER_EVENT_TAB *Tab,
+ IN PUCHAR pBssid,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR RegClass,
+ IN UCHAR ChannelNo)
+{
+ // Event A
+ if (HtCapabilityLen == 0)
+ {
+ if (Tab->EventANo < MAX_TRIGGER_EVENT)
+ {
+ RTMPMoveMemory(Tab->EventA[Tab->EventANo].BSSID, pBssid, 6);
+ Tab->EventA[Tab->EventANo].bValid = TRUE;
+ Tab->EventA[Tab->EventANo].Channel = ChannelNo;
+ Tab->EventA[Tab->EventANo].CDCounter = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
+ if (RegClass != 0)
+ {
+ // Beacon has Regulatory class IE. So use beacon's
+ Tab->EventA[Tab->EventANo].RegClass = RegClass;
+ }
+ else
+ {
+ // Use Station's Regulatory class instead.
+ if (pAd->StaActive.SupportedHtPhy.bHtEnable == TRUE)
+ {
+ if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+ {
+ Tab->EventA[Tab->EventANo].RegClass = 32;
+ }
+ else if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
+ Tab->EventA[Tab->EventANo].RegClass = 33;
+ }
+ else
+ Tab->EventA[Tab->EventANo].RegClass = ??;
+
+ }
+
+ Tab->EventANo ++;
+ }
+ }
+ else if (pHtCapability->HtCapInfo.Intolerant40)
+ {
+ Tab->EventBCountDown = pAd->CommonCfg.Dot11BssWidthChanTranDelay;
+ }
+
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Trigger Event table Maintainence called once every second.
+
+ Arguments:
+ // IRQL = DISPATCH_LEVEL
+ ========================================================================
+*/
+VOID TriEventCounterMaintenance(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i;
+ BOOLEAN bNotify = FALSE;
+ for (i = 0;i < MAX_TRIGGER_EVENT;i++)
+ {
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].bValid && (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter > 0))
+ {
+ pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter--;
+ if (pAd->CommonCfg.TriggerEventTab.EventA[i].CDCounter == 0)
+ {
+ pAd->CommonCfg.TriggerEventTab.EventA[i].bValid = FALSE;
+ pAd->CommonCfg.TriggerEventTab.EventANo --;
+ // Need to send 20/40 Coexistence Notify frame if has status change.
+ bNotify = TRUE;
+ }
+ }
+ }
+ if (pAd->CommonCfg.TriggerEventTab.EventBCountDown > 0)
+ {
+ pAd->CommonCfg.TriggerEventTab.EventBCountDown--;
+ if (pAd->CommonCfg.TriggerEventTab.EventBCountDown == 0)
+ bNotify = TRUE;
+ }
+
+ if (bNotify == TRUE)
+ Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSsidSort(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *OutTab,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen)
+{
+ INT i;
+ BssTableInit(OutTab);
+
+ for (i = 0; i < pAd->ScanTab.BssNr; i++)
+ {
+ BSS_ENTRY *pInBss = &pAd->ScanTab.BssEntry[i];
+ BOOLEAN bIsHiddenApIncluded = FALSE;
+
+ if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->MlmeAux.Channel > 14) &&
+ RadarChannelCheck(pAd, pInBss->Channel))
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ if (pInBss->Hidden)
+ bIsHiddenApIncluded = TRUE;
+ }
+
+ if ((pInBss->BssType == pAd->StaCfg.BssType) &&
+ (SSID_EQUAL(Ssid, SsidLen, pInBss->Ssid, pInBss->SsidLen) || bIsHiddenApIncluded))
+ {
+ BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ // If no Country IE exists no Connection will be established when IEEE80211dClientMode is strict.
+ if ((pAd->StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict) &&
+ (pInBss->bHasCountryIE == FALSE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("StaCfg.IEEE80211dClientMode == Rt802_11_D_Strict, but this AP doesn't have country IE.\n"));
+ continue;
+ }
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef DOT11_N_SUPPORT
+ // 2.4G/5G N only mode
+ if ((pInBss->HtCapabilityLen == 0) &&
+ ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+ continue;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // New for WPA2
+ // Check the Authmode first
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+ if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+ // None matched
+ continue;
+
+ // Check cipher suite, AP must have more secured cipher than station setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+ continue;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA2.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+ continue;
+ }
+ }
+ // Bss Type matched, SSID matched.
+ // We will check wepstatus for qualification Bss
+ else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("StaCfg.WepStatus=%d, while pInBss->WepStatus=%d\n", pAd->StaCfg.WepStatus, pInBss->WepStatus));
+ //
+ // For the SESv2 case, we will not qualify WepStatus.
+ //
+ if (!pInBss->bSES)
+ continue;
+ }
+
+ // Since the AP is using hidden SSID, and we are trying to connect to ANY
+ // It definitely will fail. So, skip it.
+ // CCX also require not even try to connect it!!
+ if (SsidLen == 0)
+ continue;
+
+#ifdef DOT11_N_SUPPORT
+ // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+ // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+ if ((pInBss->CentralChannel != pInBss->Channel) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ SetCommonHT(pAd);
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ }
+ else
+ {
+ if (pAd->CommonCfg.DesiredHtPhy.ChannelWidth == BAND_WIDTH_20)
+ {
+ SetCommonHT(pAd);
+ }
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // copy matching BSS from InTab to OutTab
+ NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+ OutTab->BssNr++;
+ }
+ else if ((pInBss->BssType == pAd->StaCfg.BssType) && (SsidLen == 0))
+ {
+ BSS_ENTRY *pOutBss = &OutTab->BssEntry[OutTab->BssNr];
+
+
+#ifdef DOT11_N_SUPPORT
+ // 2.4G/5G N only mode
+ if ((pInBss->HtCapabilityLen == 0) &&
+ ((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STA is in N-only Mode, this AP don't have Ht capability in Beacon.\n"));
+ continue;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // New for WPA2
+ // Check the Authmode first
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // Check AuthMode and AuthModeAux for matching, in case AP support dual-mode
+ if ((pAd->StaCfg.AuthMode != pInBss->AuthMode) && (pAd->StaCfg.AuthMode != pInBss->AuthModeAux))
+ // None matched
+ continue;
+
+ // Check cipher suite, AP must have more secured cipher than station setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA.PairCipherAux))
+ continue;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ // If it's not mixed mode, we should only let BSS pass with the same encryption
+ if (pInBss->WPA2.bMixMode == FALSE)
+ if (pAd->StaCfg.WepStatus != pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check group cipher
+ if (pAd->StaCfg.WepStatus < pInBss->WPA2.GroupCipher)
+ continue;
+
+ // check pairwise cipher, skip if none matched
+ // If profile set to AES, let it pass without question.
+ // If profile set to TKIP, we must find one mateched
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipher) &&
+ (pAd->StaCfg.WepStatus != pInBss->WPA2.PairCipherAux))
+ continue;
+ }
+ }
+ // Bss Type matched, SSID matched.
+ // We will check wepstatus for qualification Bss
+ else if (pAd->StaCfg.WepStatus != pInBss->WepStatus)
+ continue;
+
+#ifdef DOT11_N_SUPPORT
+ // If both station and AP use 40MHz, still need to check if the 40MHZ band's legality in my country region
+ // If this 40MHz wideband is not allowed in my country list, use bandwidth 20MHZ instead,
+ if ((pInBss->CentralChannel != pInBss->Channel) &&
+ (pAd->CommonCfg.RegTransmitSetting.field.BW == BW_40))
+ {
+ if (RTMPCheckChannel(pAd, pInBss->CentralChannel, pInBss->Channel) == FALSE)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ SetCommonHT(pAd);
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // copy matching BSS from InTab to OutTab
+ NdisMoveMemory(pOutBss, pInBss, sizeof(BSS_ENTRY));
+
+ OutTab->BssNr++;
+ }
+
+ if (OutTab->BssNr >= MAX_LEN_OF_BSS_TABLE)
+ break;
+ }
+
+ BssTableSortByRssi(OutTab);
+}
+
+
+// IRQL = DISPATCH_LEVEL
+VOID BssTableSortByRssi(
+ IN OUT BSS_TABLE *OutTab)
+{
+ INT i, j;
+ BSS_ENTRY TmpBss;
+
+ for (i = 0; i < OutTab->BssNr - 1; i++)
+ {
+ for (j = i+1; j < OutTab->BssNr; j++)
+ {
+ if (OutTab->BssEntry[j].Rssi > OutTab->BssEntry[i].Rssi)
+ {
+ NdisMoveMemory(&TmpBss, &OutTab->BssEntry[j], sizeof(BSS_ENTRY));
+ NdisMoveMemory(&OutTab->BssEntry[j], &OutTab->BssEntry[i], sizeof(BSS_ENTRY));
+ NdisMoveMemory(&OutTab->BssEntry[i], &TmpBss, sizeof(BSS_ENTRY));
+ }
+ }
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+VOID BssCipherParse(
+ IN OUT PBSS_ENTRY pBss)
+{
+ PEID_STRUCT pEid;
+ PUCHAR pTmp;
+ PRSN_IE_HEADER_STRUCT pRsnHeader;
+ PCIPHER_SUITE_STRUCT pCipher;
+ PAKM_SUITE_STRUCT pAKM;
+ USHORT Count;
+ INT Length;
+ NDIS_802_11_ENCRYPTION_STATUS TmpCipher;
+
+ //
+ // WepStatus will be reset later, if AP announce TKIP or AES on the beacon frame.
+ //
+ if (pBss->Privacy)
+ {
+ pBss->WepStatus = Ndis802_11WEPEnabled;
+ }
+ else
+ {
+ pBss->WepStatus = Ndis802_11WEPDisabled;
+ }
+ // Set default to disable & open authentication before parsing variable IE
+ pBss->AuthMode = Ndis802_11AuthModeOpen;
+ pBss->AuthModeAux = Ndis802_11AuthModeOpen;
+
+ // Init WPA setting
+ pBss->WPA.PairCipher = Ndis802_11WEPDisabled;
+ pBss->WPA.PairCipherAux = Ndis802_11WEPDisabled;
+ pBss->WPA.GroupCipher = Ndis802_11WEPDisabled;
+ pBss->WPA.RsnCapability = 0;
+ pBss->WPA.bMixMode = FALSE;
+
+ // Init WPA2 setting
+ pBss->WPA2.PairCipher = Ndis802_11WEPDisabled;
+ pBss->WPA2.PairCipherAux = Ndis802_11WEPDisabled;
+ pBss->WPA2.GroupCipher = Ndis802_11WEPDisabled;
+ pBss->WPA2.RsnCapability = 0;
+ pBss->WPA2.bMixMode = FALSE;
+
+
+ Length = (INT) pBss->VarIELen;
+
+ while (Length > 0)
+ {
+ // Parse cipher suite base on WPA1 & WPA2, they should be parsed differently
+ pTmp = ((PUCHAR) pBss->VarIEs) + pBss->VarIELen - Length;
+ pEid = (PEID_STRUCT) pTmp;
+ switch (pEid->Eid)
+ {
+ case IE_WPA:
+ //Parse Cisco IE_WPA (LEAP, CCKM, etc.)
+ if ( NdisEqualMemory((pTmp+8), CISCO_OUI, 3))
+ {
+ pTmp += 11;
+ switch (*pTmp)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ pBss->WepStatus = Ndis802_11Encryption1Enabled;
+ pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ pBss->WepStatus = Ndis802_11Encryption2Enabled;
+ pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 4:
+ pBss->WepStatus = Ndis802_11Encryption3Enabled;
+ pBss->WPA.PairCipher = Ndis802_11Encryption1Enabled;
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ default:
+ break;
+ }
+
+ // if Cisco IE_WPA, break
+ break;
+ }
+ else if (NdisEqualMemory(pEid->Octet, SES_OUI, 3) && (pEid->Len == 7))
+ {
+ pBss->bSES = TRUE;
+ break;
+ }
+ else if (NdisEqualMemory(pEid->Octet, WPA_OUI, 4) != 1)
+ {
+ // if unsupported vendor specific IE
+ break;
+ }
+ // Skip OUI, version, and multicast suite
+ // This part should be improved in the future when AP supported multiple cipher suite.
+ // For now, it's OK since almost all APs have fixed cipher suite supported.
+ // pTmp = (PUCHAR) pEid->Octet;
+ pTmp += 11;
+
+ // Cipher Suite Selectors from Spec P802.11i/D3.2 P26.
+ // Value Meaning
+ // 0 None
+ // 1 WEP-40
+ // 2 Tkip
+ // 3 WRAP
+ // 4 AES
+ // 5 WEP-104
+ // Parse group cipher
+ switch (*pTmp)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ pBss->WPA.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ pBss->WPA.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ pBss->WPA.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ // number of unicast suite
+ pTmp += 1;
+
+ // skip all unicast cipher suites
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // Parsing all unicast cipher suite
+ while (Count > 0)
+ {
+ // Skip OUI
+ pTmp += 3;
+ TmpCipher = Ndis802_11WEPDisabled;
+ switch (*pTmp)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ TmpCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ TmpCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ TmpCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ if (TmpCipher > pBss->WPA.PairCipher)
+ {
+ // Move the lower cipher suite to PairCipherAux
+ pBss->WPA.PairCipherAux = pBss->WPA.PairCipher;
+ pBss->WPA.PairCipher = TmpCipher;
+ }
+ else
+ {
+ pBss->WPA.PairCipherAux = TmpCipher;
+ }
+ pTmp++;
+ Count--;
+ }
+
+ // 4. get AKM suite counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+ pTmp += 3;
+
+ switch (*pTmp)
+ {
+ case 1:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA;
+ break;
+ case 2:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPAPSK;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPAPSK;
+ break;
+ default:
+ break;
+ }
+ pTmp += 1;
+
+ // Fixed for WPA-None
+ if (pBss->BssType == BSS_ADHOC)
+ {
+ pBss->AuthMode = Ndis802_11AuthModeWPANone;
+ pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+ pBss->WepStatus = pBss->WPA.GroupCipher;
+ if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+ pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
+ }
+ else
+ pBss->WepStatus = pBss->WPA.PairCipher;
+
+ // Check the Pair & Group, if different, turn on mixed mode flag
+ if (pBss->WPA.GroupCipher != pBss->WPA.PairCipher)
+ pBss->WPA.bMixMode = TRUE;
+
+ break;
+
+ case IE_RSN:
+ pRsnHeader = (PRSN_IE_HEADER_STRUCT) pTmp;
+
+ // 0. Version must be 1
+ if (le2cpu16(pRsnHeader->Version) != 1)
+ break;
+ pTmp += sizeof(RSN_IE_HEADER_STRUCT);
+
+ // 1. Check group cipher
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+ break;
+
+ // Parse group cipher
+ switch (pCipher->Type)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ pBss->WPA2.GroupCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ // set to correct offset for next parsing
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
+
+ // 2. Get pairwise cipher counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // 3. Get pairwise cipher
+ // Parsing all unicast cipher suite
+ while (Count > 0)
+ {
+ // Skip OUI
+ pCipher = (PCIPHER_SUITE_STRUCT) pTmp;
+ TmpCipher = Ndis802_11WEPDisabled;
+ switch (pCipher->Type)
+ {
+ case 1:
+ case 5: // Although WEP is not allowed in WPA related auth mode, we parse it anyway
+ TmpCipher = Ndis802_11Encryption1Enabled;
+ break;
+ case 2:
+ TmpCipher = Ndis802_11Encryption2Enabled;
+ break;
+ case 4:
+ TmpCipher = Ndis802_11Encryption3Enabled;
+ break;
+ default:
+ break;
+ }
+ if (TmpCipher > pBss->WPA2.PairCipher)
+ {
+ // Move the lower cipher suite to PairCipherAux
+ pBss->WPA2.PairCipherAux = pBss->WPA2.PairCipher;
+ pBss->WPA2.PairCipher = TmpCipher;
+ }
+ else
+ {
+ pBss->WPA2.PairCipherAux = TmpCipher;
+ }
+ pTmp += sizeof(CIPHER_SUITE_STRUCT);
+ Count--;
+ }
+
+ // 4. get AKM suite counts
+ //Count = *(PUSHORT) pTmp;
+ Count = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // 5. Get AKM ciphers
+ pAKM = (PAKM_SUITE_STRUCT) pTmp;
+ if (!RTMPEqualMemory(pTmp, RSN_OUI, 3))
+ break;
+
+ switch (pAKM->Type)
+ {
+ case 1:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA2;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA2;
+ break;
+ case 2:
+ // Set AP support WPA mode
+ if (pBss->AuthMode == Ndis802_11AuthModeOpen)
+ pBss->AuthMode = Ndis802_11AuthModeWPA2PSK;
+ else
+ pBss->AuthModeAux = Ndis802_11AuthModeWPA2PSK;
+ break;
+ default:
+ break;
+ }
+ pTmp += (Count * sizeof(AKM_SUITE_STRUCT));
+
+ // Fixed for WPA-None
+ if (pBss->BssType == BSS_ADHOC)
+ {
+ pBss->AuthMode = Ndis802_11AuthModeWPANone;
+ pBss->AuthModeAux = Ndis802_11AuthModeWPANone;
+ pBss->WPA.PairCipherAux = pBss->WPA2.PairCipherAux;
+ pBss->WPA.GroupCipher = pBss->WPA2.GroupCipher;
+ pBss->WepStatus = pBss->WPA.GroupCipher;
+ if (pBss->WPA.PairCipherAux == Ndis802_11WEPDisabled)
+ pBss->WPA.PairCipherAux = pBss->WPA.GroupCipher;
+ }
+ pBss->WepStatus = pBss->WPA2.PairCipher;
+
+ // 6. Get RSN capability
+ //pBss->WPA2.RsnCapability = *(PUSHORT) pTmp;
+ pBss->WPA2.RsnCapability = (pTmp[1]<<8) + pTmp[0];
+ pTmp += sizeof(USHORT);
+
+ // Check the Pair & Group, if different, turn on mixed mode flag
+ if (pBss->WPA2.GroupCipher != pBss->WPA2.PairCipher)
+ pBss->WPA2.bMixMode = TRUE;
+
+ break;
+ default:
+ break;
+ }
+ Length -= (pEid->Len + 2);
+ }
+}
+
+// ===========================================================================================
+// mac_table.c
+// ===========================================================================================
+
+/*! \brief generates a random mac address value for IBSS BSSID
+ * \param Addr the bssid location
+ * \return none
+ * \pre
+ * \post
+ */
+VOID MacAddrRandomBssid(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pAddr)
+{
+ INT i;
+
+ for (i = 0; i < MAC_ADDR_LEN; i++)
+ {
+ pAddr[i] = RandomByte(pAd);
+ }
+
+ pAddr[0] = (pAddr[0] & 0xfe) | 0x02; // the first 2 bits must be 01xxxxxxxx
+}
+
+/*! \brief init the management mac frame header
+ * \param p_hdr mac header
+ * \param subtype subtype of the frame
+ * \param p_ds destination address, don't care if it is a broadcast address
+ * \return none
+ * \pre the station has the following information in the pAd->StaCfg
+ * - bssid
+ * - station address
+ * \post
+ * \note this function initializes the following field
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID MgtMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+
+ pHdr80211->FC.Type = BTYPE_MGMT;
+ pHdr80211->FC.SubType = SubType;
+// if (SubType == SUBTYPE_ACK) // sample, no use, it will conflict with ACTION frame sub type
+// pHdr80211->FC.Type = BTYPE_CNTL;
+ pHdr80211->FC.ToDs = ToDs;
+ COPY_MAC_ADDR(pHdr80211->Addr1, pDA);
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+#endif // CONFIG_STA_SUPPORT //
+ COPY_MAC_ADDR(pHdr80211->Addr3, pBssid);
+}
+
+// ===========================================================================================
+// mem_mgmt.c
+// ===========================================================================================
+
+/*!***************************************************************************
+ * This routine build an outgoing frame, and fill all information specified
+ * in argument list to the frame body. The actual frame size is the summation
+ * of all arguments.
+ * input params:
+ * Buffer - pointer to a pre-allocated memory segment
+ * args - a list of <int arg_size, arg> pairs.
+ * NOTE NOTE NOTE!!!! the last argument must be NULL, otherwise this
+ * function will FAIL!!!
+ * return:
+ * Size of the buffer
+ * usage:
+ * MakeOutgoingFrame(Buffer, output_length, 2, &fc, 2, &dur, 6, p_addr1, 6,p_addr2, END_OF_ARGS);
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ****************************************************************************/
+ULONG MakeOutgoingFrame(
+ OUT CHAR *Buffer,
+ OUT ULONG *FrameLen, ...)
+{
+ CHAR *p;
+ int leng;
+ ULONG TotLeng;
+ va_list Args;
+
+ // calculates the total length
+ TotLeng = 0;
+ va_start(Args, FrameLen);
+ do
+ {
+ leng = va_arg(Args, int);
+ if (leng == END_OF_ARGS)
+ {
+ break;
+ }
+ p = va_arg(Args, PVOID);
+ NdisMoveMemory(&Buffer[TotLeng], p, leng);
+ TotLeng = TotLeng + leng;
+ } while(TRUE);
+
+ va_end(Args); /* clean up */
+ *FrameLen = TotLeng;
+ return TotLeng;
+}
+
+// ===========================================================================================
+// mlme_queue.c
+// ===========================================================================================
+
+/*! \brief Initialize The MLME Queue, used by MLME Functions
+ * \param *Queue The MLME Queue
+ * \return Always Return NDIS_STATE_SUCCESS in this implementation
+ * \pre
+ * \post
+ * \note Because this is done only once (at the init stage), no need to be locked
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+NDIS_STATUS MlmeQueueInit(
+ IN MLME_QUEUE *Queue)
+{
+ INT i;
+
+ NdisAllocateSpinLock(&Queue->Lock);
+
+ Queue->Num = 0;
+ Queue->Head = 0;
+ Queue->Tail = 0;
+
+ for (i = 0; i < MAX_LEN_OF_MLME_QUEUE; i++)
+ {
+ Queue->Entry[i].Occupied = FALSE;
+ Queue->Entry[i].MsgLen = 0;
+ NdisZeroMemory(Queue->Entry[i].Msg, MGMT_DMA_BUFFER_SIZE);
+ }
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*! \brief Enqueue a message for other threads, if they want to send messages to MLME thread
+ * \param *Queue The MLME Queue
+ * \param Machine The State Machine Id
+ * \param MsgType The Message Type
+ * \param MsgLen The Message length
+ * \param *Msg The message pointer
+ * \return TRUE if enqueue is successful, FALSE if the queue is full
+ * \pre
+ * \post
+ * \note The message has to be initialized
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeEnqueue(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Machine,
+ IN ULONG MsgType,
+ IN ULONG MsgLen,
+ IN VOID *Msg)
+{
+ INT Tail;
+ MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return FALSE;
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+
+ if (MlmeQueueFull(Queue))
+ {
+ return FALSE;
+ }
+
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Tail = Queue->Tail;
+ Queue->Tail++;
+ Queue->Num++;
+ if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+ {
+ Queue->Tail = 0;
+ }
+
+ Queue->Entry[Tail].Wcid = RESERVED_WCID;
+ Queue->Entry[Tail].Occupied = TRUE;
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+
+ if (Msg != NULL)
+ {
+ NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+ }
+
+ NdisReleaseSpinLock(&(Queue->Lock));
+ return TRUE;
+}
+
+/*! \brief This function is used when Recv gets a MLME message
+ * \param *Queue The MLME Queue
+ * \param TimeStampHigh The upper 32 bit of timestamp
+ * \param TimeStampLow The lower 32 bit of timestamp
+ * \param Rssi The receiving RSSI strength
+ * \param MsgLen The length of the message
+ * \param *Msg The message pointer
+ * \return TRUE if everything ok, FALSE otherwise (like Queue Full)
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG TimeStampHigh,
+ IN ULONG TimeStampLow,
+ IN UCHAR Rssi0,
+ IN UCHAR Rssi1,
+ IN UCHAR Rssi2,
+ IN ULONG MsgLen,
+ IN VOID *Msg,
+ IN UCHAR Signal)
+{
+ INT Tail, Machine;
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+ INT MsgType;
+ MLME_QUEUE *Queue = (MLME_QUEUE *)&pAd->Mlme.Queue;
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode */
+ if(ATE_ON(pAd))
+ return FALSE;
+#endif // RALINK_ATE //
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"));
+ return FALSE;
+ }
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (MsgLen > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen));
+ return FALSE;
+ }
+
+ if (MlmeQueueFull(Queue))
+ {
+ return FALSE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType))
+ {
+ DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n",pFrame->Hdr.FC.SubType));
+ return FALSE;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // OK, we got all the informations, it is time to put things into queue
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Tail = Queue->Tail;
+ Queue->Tail++;
+ Queue->Num++;
+ if (Queue->Tail == MAX_LEN_OF_MLME_QUEUE)
+ {
+ Queue->Tail = 0;
+ }
+ Queue->Entry[Tail].Occupied = TRUE;
+ Queue->Entry[Tail].Machine = Machine;
+ Queue->Entry[Tail].MsgType = MsgType;
+ Queue->Entry[Tail].MsgLen = MsgLen;
+ Queue->Entry[Tail].TimeStamp.u.LowPart = TimeStampLow;
+ Queue->Entry[Tail].TimeStamp.u.HighPart = TimeStampHigh;
+ Queue->Entry[Tail].Rssi0 = Rssi0;
+ Queue->Entry[Tail].Rssi1 = Rssi1;
+ Queue->Entry[Tail].Rssi2 = Rssi2;
+ Queue->Entry[Tail].Signal = Signal;
+ Queue->Entry[Tail].Wcid = (UCHAR)Wcid;
+
+ Queue->Entry[Tail].Channel = pAd->LatchRfRegs.Channel;
+
+ if (Msg != NULL)
+ {
+ NdisMoveMemory(Queue->Entry[Tail].Msg, Msg, MsgLen);
+ }
+
+ NdisReleaseSpinLock(&(Queue->Lock));
+
+ RT28XX_MLME_HANDLER(pAd);
+
+ return TRUE;
+}
+
+
+/*! \brief Dequeue a message from the MLME Queue
+ * \param *Queue The MLME Queue
+ * \param *Elem The message dequeued from MLME Queue
+ * \return TRUE if the Elem contains something, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeDequeue(
+ IN MLME_QUEUE *Queue,
+ OUT MLME_QUEUE_ELEM **Elem)
+{
+ NdisAcquireSpinLock(&(Queue->Lock));
+ *Elem = &(Queue->Entry[Queue->Head]);
+ Queue->Num--;
+ Queue->Head++;
+ if (Queue->Head == MAX_LEN_OF_MLME_QUEUE)
+ {
+ Queue->Head = 0;
+ }
+ NdisReleaseSpinLock(&(Queue->Lock));
+ return TRUE;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID MlmeRestartStateMachine(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeRestartStateMachine \n"));
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef QOS_DLS_SUPPORT
+ UCHAR i;
+#endif // QOS_DLS_SUPPORT //
+ // Cancel all timer events
+ // Be careful to cancel new added timer
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+
+#ifdef QOS_DLS_SUPPORT
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &Cancelled);
+ }
+#endif // QOS_DLS_SUPPORT //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Change back to original channel in case of doing scan
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ // Resume MSDU which is turned off durning scan
+ RTMPResumeMsduTransmission(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Set all state machines back IDLE
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
+#ifdef QOS_DLS_SUPPORT
+ pAd->Mlme.DlsMachine.CurrState = DLS_IDLE;
+#endif // QOS_DLS_SUPPORT //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+/*! \brief test if the MLME Queue is empty
+ * \param *Queue The MLME Queue
+ * \return TRUE if the Queue is empty, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeQueueEmpty(
+ IN MLME_QUEUE *Queue)
+{
+ BOOLEAN Ans;
+
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Ans = (Queue->Num == 0);
+ NdisReleaseSpinLock(&(Queue->Lock));
+
+ return Ans;
+}
+
+/*! \brief test if the MLME Queue is full
+ * \param *Queue The MLME Queue
+ * \return TRUE if the Queue is empty, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ */
+BOOLEAN MlmeQueueFull(
+ IN MLME_QUEUE *Queue)
+{
+ BOOLEAN Ans;
+
+ NdisAcquireSpinLock(&(Queue->Lock));
+ Ans = (Queue->Num == MAX_LEN_OF_MLME_QUEUE || Queue->Entry[Queue->Tail].Occupied);
+ NdisReleaseSpinLock(&(Queue->Lock));
+
+ return Ans;
+}
+
+/*! \brief The destructor of MLME Queue
+ * \param
+ * \return
+ * \pre
+ * \post
+ * \note Clear Mlme Queue, Set Queue->Num to Zero.
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID MlmeQueueDestroy(
+ IN MLME_QUEUE *pQueue)
+{
+ NdisAcquireSpinLock(&(pQueue->Lock));
+ pQueue->Num = 0;
+ pQueue->Head = 0;
+ pQueue->Tail = 0;
+ NdisReleaseSpinLock(&(pQueue->Lock));
+ NdisFreeSpinLock(&(pQueue->Lock));
+}
+
+/*! \brief To substitute the message type if the message is coming from external
+ * \param pFrame The frame received
+ * \param *Machine The state machine
+ * \param *MsgType the message type for the state machine
+ * \return TRUE if the substitution is successful, FALSE otherwise
+ * \pre
+ * \post
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+#ifdef CONFIG_STA_SUPPORT
+BOOLEAN MsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType)
+{
+ USHORT Seq;
+ UCHAR EAPType;
+ PUCHAR pData;
+
+ // Pointer to start of data frames including SNAP header
+ pData = (PUCHAR) pFrame + LENGTH_802_11;
+
+ // The only data type will pass to this function is EAPOL frame
+ if (pFrame->Hdr.FC.Type == BTYPE_DATA)
+ {
+ if (NdisEqualMemory(SNAP_AIRONET, pData, LENGTH_802_1_H))
+ {
+ // Cisco Aironet SNAP header
+ *Machine = AIRONET_STATE_MACHINE;
+ *MsgType = MT2_AIRONET_MSG;
+ return (TRUE);
+ }
+#ifdef LEAP_SUPPORT
+ if ( pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP ) //LEAP
+ {
+ // LEAP frames
+ *Machine = LEAP_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ return (LeapMsgTypeSubst(EAPType, MsgType));
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ *Machine = WPA_PSK_STATE_MACHINE;
+ EAPType = *((UCHAR*)pFrame + LENGTH_802_11 + LENGTH_802_1_H + 1);
+ return(WpaMsgTypeSubst(EAPType, MsgType));
+ }
+ }
+
+ switch (pFrame->Hdr.FC.SubType)
+ {
+ case SUBTYPE_ASSOC_REQ:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ASSOC_REQ;
+ break;
+ case SUBTYPE_ASSOC_RSP:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ASSOC_RSP;
+ break;
+ case SUBTYPE_REASSOC_REQ:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_REASSOC_REQ;
+ break;
+ case SUBTYPE_REASSOC_RSP:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_REASSOC_RSP;
+ break;
+ case SUBTYPE_PROBE_REQ:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_PROBE_REQ;
+ break;
+ case SUBTYPE_PROBE_RSP:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_PROBE_RSP;
+ break;
+ case SUBTYPE_BEACON:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_BEACON;
+ break;
+ case SUBTYPE_ATIM:
+ *Machine = SYNC_STATE_MACHINE;
+ *MsgType = MT2_PEER_ATIM;
+ break;
+ case SUBTYPE_DISASSOC:
+ *Machine = ASSOC_STATE_MACHINE;
+ *MsgType = MT2_PEER_DISASSOC_REQ;
+ break;
+ case SUBTYPE_AUTH:
+ // get the sequence number from payload 24 Mac Header + 2 bytes algorithm
+ NdisMoveMemory(&Seq, &pFrame->Octet[2], sizeof(USHORT));
+ if (Seq == 1 || Seq == 3)
+ {
+ *Machine = AUTH_RSP_STATE_MACHINE;
+ *MsgType = MT2_PEER_AUTH_ODD;
+ }
+ else if (Seq == 2 || Seq == 4)
+ {
+ *Machine = AUTH_STATE_MACHINE;
+ *MsgType = MT2_PEER_AUTH_EVEN;
+ }
+ else
+ {
+ return FALSE;
+ }
+ break;
+ case SUBTYPE_DEAUTH:
+ *Machine = AUTH_RSP_STATE_MACHINE;
+ *MsgType = MT2_PEER_DEAUTH;
+ break;
+ case SUBTYPE_ACTION:
+ *Machine = ACTION_STATE_MACHINE;
+ // Sometimes Sta will return with category bytes with MSB = 1, if they receive catogory out of their support
+ if ((pFrame->Octet[0]&0x7F) > MAX_PEER_CATE_MSG)
+ {
+ *MsgType = MT2_ACT_INVALID;
+ }
+ else
+ {
+ *MsgType = (pFrame->Octet[0]&0x7F);
+ }
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+
+ return TRUE;
+}
+#endif // CONFIG_STA_SUPPORT //
+
+// ===========================================================================================
+// state_machine.c
+// ===========================================================================================
+
+/*! \brief Initialize the state machine.
+ * \param *S pointer to the state machine
+ * \param Trans State machine transition function
+ * \param StNr number of states
+ * \param MsgNr number of messages
+ * \param DefFunc default function, when there is invalid state/message combination
+ * \param InitState initial state of the state machine
+ * \param Base StateMachine base, internal use only
+ * \pre p_sm should be a legal pointer
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineInit(
+ IN STATE_MACHINE *S,
+ IN STATE_MACHINE_FUNC Trans[],
+ IN ULONG StNr,
+ IN ULONG MsgNr,
+ IN STATE_MACHINE_FUNC DefFunc,
+ IN ULONG InitState,
+ IN ULONG Base)
+{
+ ULONG i, j;
+
+ // set number of states and messages
+ S->NrState = StNr;
+ S->NrMsg = MsgNr;
+ S->Base = Base;
+
+ S->TransFunc = Trans;
+
+ // init all state transition to default function
+ for (i = 0; i < StNr; i++)
+ {
+ for (j = 0; j < MsgNr; j++)
+ {
+ S->TransFunc[i * MsgNr + j] = DefFunc;
+ }
+ }
+
+ // set the starting state
+ S->CurrState = InitState;
+}
+
+/*! \brief This function fills in the function pointer into the cell in the state machine
+ * \param *S pointer to the state machine
+ * \param St state
+ * \param Msg incoming message
+ * \param f the function to be executed when (state, message) combination occurs at the state machine
+ * \pre *S should be a legal pointer to the state machine, st, msg, should be all within the range, Base should be set in the initial state
+ * \post
+
+ IRQL = PASSIVE_LEVEL
+
+ */
+VOID StateMachineSetAction(
+ IN STATE_MACHINE *S,
+ IN ULONG St,
+ IN ULONG Msg,
+ IN STATE_MACHINE_FUNC Func)
+{
+ ULONG MsgIdx;
+
+ MsgIdx = Msg - S->Base;
+
+ if (St < S->NrState && MsgIdx < S->NrMsg)
+ {
+ // boundary checking before setting the action
+ S->TransFunc[St * S->NrMsg + MsgIdx] = Func;
+ }
+}
+
+/*! \brief This function does the state transition
+ * \param *Adapter the NIC adapter pointer
+ * \param *S the state machine
+ * \param *Elem the message to be executed
+ * \return None
+
+ IRQL = DISPATCH_LEVEL
+
+ */
+VOID StateMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ (*(S->TransFunc[S->CurrState * S->NrMsg + Elem->MsgType - S->Base]))(pAd, Elem);
+}
+
+/*
+ ==========================================================================
+ Description:
+ The drop function, when machine executes this, the message is simply
+ ignored. This function does nothing, the message is freed in
+ StateMachinePerformAction()
+ ==========================================================================
+ */
+VOID Drop(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+}
+
+// ===========================================================================================
+// lfsr.c
+// ===========================================================================================
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID LfsrInit(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Seed)
+{
+ if (Seed == 0)
+ pAd->Mlme.ShiftReg = 1;
+ else
+ pAd->Mlme.ShiftReg = Seed;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+UCHAR RandomByte(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ UCHAR R, Result;
+
+ R = 0;
+
+ if (pAd->Mlme.ShiftReg == 0)
+ NdisGetSystemUpTime((ULONG *)&pAd->Mlme.ShiftReg);
+
+ for (i = 0; i < 8; i++)
+ {
+ if (pAd->Mlme.ShiftReg & 0x00000001)
+ {
+ pAd->Mlme.ShiftReg = ((pAd->Mlme.ShiftReg ^ LFSR_MASK) >> 1) | 0x80000000;
+ Result = 1;
+ }
+ else
+ {
+ pAd->Mlme.ShiftReg = pAd->Mlme.ShiftReg >> 1;
+ Result = 0;
+ }
+ R = (R << 1) | Result;
+ }
+
+ return R;
+}
+
+VOID AsicUpdateAutoFallBackTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRateTable)
+{
+ UCHAR i;
+ HT_FBK_CFG0_STRUC HtCfg0;
+ HT_FBK_CFG1_STRUC HtCfg1;
+ LG_FBK_CFG0_STRUC LgCfg0;
+ LG_FBK_CFG1_STRUC LgCfg1;
+ PRTMP_TX_RATE_SWITCH pCurrTxRate, pNextTxRate;
+
+ // set to initial value
+ HtCfg0.word = 0x65432100;
+ HtCfg1.word = 0xedcba988;
+ LgCfg0.word = 0xedcba988;
+ LgCfg1.word = 0x00002100;
+
+ pNextTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1;
+ for (i = 1; i < *((PUCHAR) pRateTable); i++)
+ {
+ pCurrTxRate = (PRTMP_TX_RATE_SWITCH)pRateTable+1+i;
+ switch (pCurrTxRate->Mode)
+ {
+ case 0: //CCK
+ break;
+ case 1: //OFDM
+ {
+ switch(pCurrTxRate->CurrMCS)
+ {
+ case 0:
+ LgCfg0.field.OFDMMCS0FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 1:
+ LgCfg0.field.OFDMMCS1FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 2:
+ LgCfg0.field.OFDMMCS2FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 3:
+ LgCfg0.field.OFDMMCS3FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 4:
+ LgCfg0.field.OFDMMCS4FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 5:
+ LgCfg0.field.OFDMMCS5FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 6:
+ LgCfg0.field.OFDMMCS6FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ case 7:
+ LgCfg0.field.OFDMMCS7FBK = (pNextTxRate->Mode == MODE_OFDM) ? (pNextTxRate->CurrMCS+8): pNextTxRate->CurrMCS;
+ break;
+ }
+ }
+ break;
+#ifdef DOT11_N_SUPPORT
+ case 2: //HT-MIX
+ case 3: //HT-GF
+ {
+ if ((pNextTxRate->Mode >= MODE_HTMIX) && (pCurrTxRate->CurrMCS != pNextTxRate->CurrMCS))
+ {
+ switch(pCurrTxRate->CurrMCS)
+ {
+ case 0:
+ HtCfg0.field.HTMCS0FBK = pNextTxRate->CurrMCS;
+ break;
+ case 1:
+ HtCfg0.field.HTMCS1FBK = pNextTxRate->CurrMCS;
+ break;
+ case 2:
+ HtCfg0.field.HTMCS2FBK = pNextTxRate->CurrMCS;
+ break;
+ case 3:
+ HtCfg0.field.HTMCS3FBK = pNextTxRate->CurrMCS;
+ break;
+ case 4:
+ HtCfg0.field.HTMCS4FBK = pNextTxRate->CurrMCS;
+ break;
+ case 5:
+ HtCfg0.field.HTMCS5FBK = pNextTxRate->CurrMCS;
+ break;
+ case 6:
+ HtCfg0.field.HTMCS6FBK = pNextTxRate->CurrMCS;
+ break;
+ case 7:
+ HtCfg0.field.HTMCS7FBK = pNextTxRate->CurrMCS;
+ break;
+ case 8:
+ HtCfg1.field.HTMCS8FBK = pNextTxRate->CurrMCS;
+ break;
+ case 9:
+ HtCfg1.field.HTMCS9FBK = pNextTxRate->CurrMCS;
+ break;
+ case 10:
+ HtCfg1.field.HTMCS10FBK = pNextTxRate->CurrMCS;
+ break;
+ case 11:
+ HtCfg1.field.HTMCS11FBK = pNextTxRate->CurrMCS;
+ break;
+ case 12:
+ HtCfg1.field.HTMCS12FBK = pNextTxRate->CurrMCS;
+ break;
+ case 13:
+ HtCfg1.field.HTMCS13FBK = pNextTxRate->CurrMCS;
+ break;
+ case 14:
+ HtCfg1.field.HTMCS14FBK = pNextTxRate->CurrMCS;
+ break;
+ case 15:
+ HtCfg1.field.HTMCS15FBK = pNextTxRate->CurrMCS;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicUpdateAutoFallBackTable: not support CurrMCS=%d\n", pCurrTxRate->CurrMCS));
+ }
+ }
+ }
+ break;
+#endif // DOT11_N_SUPPORT //
+ }
+
+ pNextTxRate = pCurrTxRate;
+ }
+
+ RTMP_IO_WRITE32(pAd, HT_FBK_CFG0, HtCfg0.word);
+ RTMP_IO_WRITE32(pAd, HT_FBK_CFG1, HtCfg1.word);
+ RTMP_IO_WRITE32(pAd, LG_FBK_CFG0, LgCfg0.word);
+ RTMP_IO_WRITE32(pAd, LG_FBK_CFG1, LgCfg1.word);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set MAC register value according operation mode.
+ OperationMode AND bNonGFExist are for MM and GF Proteciton.
+ If MM or GF mask is not set, those passing argument doesn't not take effect.
+
+ Operation mode meaning:
+ = 0 : Pure HT, no preotection.
+ = 0x01; there may be non-HT devices in both the control and extension channel, protection is optional in BSS.
+ = 0x10: No Transmission in 40M is protected.
+ = 0x11: Transmission in both 40M and 20M shall be protected
+ if (bNonGFExist)
+ we should choose not to use GF. But still set correct ASIC registers.
+ ========================================================================
+*/
+VOID AsicUpdateProtect(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT OperationMode,
+ IN UCHAR SetMask,
+ IN BOOLEAN bDisableBGProtect,
+ IN BOOLEAN bNonGFExist)
+{
+ PROT_CFG_STRUC ProtCfg, ProtCfg4;
+ UINT32 Protect[6];
+ USHORT offset;
+ UCHAR i;
+ UINT32 MacReg = 0;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+ if (!(pAd->CommonCfg.bHTProtect) && (OperationMode != 8))
+ {
+ return;
+ }
+
+ if (pAd->BATable.numAsOriginator)
+ {
+ //
+ // enable the RTS/CTS to avoid channel collision
+ //
+ SetMask = ALLN_SETPROTECT;
+ OperationMode = 8;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // Config ASIC RTS threshold register
+ RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+ MacReg &= 0xFF0000FF;
+
+ // If the user want disable RtsThreshold and enbale Amsdu/Ralink-Aggregation, set the RtsThreshold as 4096
+ if ((
+#ifdef DOT11_N_SUPPORT
+ (pAd->CommonCfg.BACapability.field.AmsduEnable) ||
+#endif // DOT11_N_SUPPORT //
+ (pAd->CommonCfg.bAggregationCapable == TRUE))
+ && pAd->CommonCfg.RtsThreshold == MAX_RTS_THRESHOLD)
+ {
+ MacReg |= (0x1000 << 8);
+ }
+ else
+ {
+ MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+ // Initial common protection settings
+ RTMPZeroMemory(Protect, sizeof(Protect));
+ ProtCfg4.word = 0;
+ ProtCfg.word = 0;
+ ProtCfg.field.TxopAllowGF40 = 1;
+ ProtCfg.field.TxopAllowGF20 = 1;
+ ProtCfg.field.TxopAllowMM40 = 1;
+ ProtCfg.field.TxopAllowMM20 = 1;
+ ProtCfg.field.TxopAllowOfdm = 1;
+ ProtCfg.field.TxopAllowCck = 1;
+ ProtCfg.field.RTSThEn = 1;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+ // update PHY mode and rate
+ if (pAd->CommonCfg.Channel > 14)
+ ProtCfg.field.ProtectRate = 0x4000;
+ ProtCfg.field.ProtectRate |= pAd->CommonCfg.RtsRate;
+
+ // Handle legacy(B/G) protection
+ if (bDisableBGProtect)
+ {
+ //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+ ProtCfg.field.ProtectCtrl = 0;
+ Protect[0] = ProtCfg.word;
+ Protect[1] = ProtCfg.word;
+ }
+ else
+ {
+ //ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+ ProtCfg.field.ProtectCtrl = 0; // CCK do not need to be protected
+ Protect[0] = ProtCfg.word;
+ ProtCfg.field.ProtectCtrl = ASIC_CTS; // OFDM needs using CCK to protect
+ Protect[1] = ProtCfg.word;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // Decide HT frame protection.
+ if ((SetMask & ALLN_SETPROTECT) != 0)
+ {
+ switch(OperationMode)
+ {
+ case 0x0:
+ // NO PROTECT
+ // 1.All STAs in the BSS are 20/40 MHz HT
+ // 2. in ai 20/40MHz BSS
+ // 3. all STAs are 20MHz in a 20MHz BSS
+ // Pure HT. no protection.
+
+ // MM20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[2] = 0x01744004;
+
+ // MM40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[3] = 0x03f44084;
+
+ // CF20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[4] = 0x01744004;
+
+ // CF40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[5] = 0x03f44084;
+
+ if (bNonGFExist)
+ {
+ // PROT_NAV(19:18) -- 01 (Short NAV protectiion)
+ // PROT_CTRL(17:16) -- 01 (RTS/CTS)
+ Protect[4] = 0x01754004;
+ Protect[5] = 0x03f54084;
+ }
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+ break;
+
+ case 1:
+ // This is "HT non-member protection mode."
+ // If there may be non-HT STAs my BSS
+ ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
+ ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
+ ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083;
+ }
+ //Assign Protection method for 20&40 MHz packets
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+
+ case 2:
+ // If only HT STAs are in BSS. at least one is 20MHz. Only protect 40MHz packets
+ ProtCfg.word = 0x01744004; // PROT_CTRL(17:16) : 0 (None)
+ ProtCfg4.word = 0x03f44084; // duplicaet legacy 24M. BW set 1.
+
+ //Assign Protection method for 40MHz packets
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ if (bNonGFExist)
+ {
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ }
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+ break;
+
+ case 3:
+ // HT mixed mode. PROTECT ALL!
+ // Assign Rate
+ ProtCfg.word = 0x01744004; //duplicaet legacy 24M. BW set 1.
+ ProtCfg4.word = 0x03f44084;
+ // both 20MHz and 40MHz are protected. Whether use RTS or CTS-to-self depends on the
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ ProtCfg.word = 0x01740003; //ERP use Protection bit is set, use protection rate at Clause 18..
+ ProtCfg4.word = 0x03f40003; // Don't duplicate RTS/CTS in CCK mode. 0x03f40083
+ }
+ //Assign Protection method for 20&40 MHz packets
+ ProtCfg.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+ ProtCfg4.field.ProtectCtrl = ASIC_RTS;
+ ProtCfg4.field.ProtectNav = ASIC_SHORTNAV;
+ Protect[2] = ProtCfg.word;
+ Protect[3] = ProtCfg4.word;
+ Protect[4] = ProtCfg.word;
+ Protect[5] = ProtCfg4.word;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+
+ case 8:
+ Protect[2] = 0x01754004;
+ Protect[3] = 0x03f54084;
+ Protect[4] = 0x01754004;
+ Protect[5] = 0x03f54084;
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = TRUE;
+ break;
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ offset = CCK_PROT_CFG;
+ for (i = 0;i < 6;i++)
+ {
+ if ((SetMask & (1<< i)))
+ {
+ RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+ }
+ }
+}
+
+
+#ifdef RT30xx
+/*
+ ========================================================================
+
+ Routine Description: Write RT30xx RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RT30xxWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN UCHAR Value)
+{
+ RF_CSR_CFG_STRUC rfcsr;
+ UINT i = 0;
+
+ do
+ {
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (!rfcsr.field.RF_CSR_KICK)
+ break;
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ rfcsr.field.RF_CSR_WR = 1;
+ rfcsr.field.RF_CSR_KICK = 1;
+ rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
+ rfcsr.field.RF_CSR_DATA = Value;
+
+ RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+
+ return STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Read RT30xx RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RT30xxReadRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN PUCHAR pValue)
+{
+ RF_CSR_CFG_STRUC rfcsr;
+ UINT i=0, k=0;
+
+ for (i=0; i<MAX_BUSY_COUNT; i++)
+ {
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (rfcsr.field.RF_CSR_KICK == BUSY)
+ {
+ continue;
+ }
+ rfcsr.word = 0;
+ rfcsr.field.RF_CSR_WR = 0;
+ rfcsr.field.RF_CSR_KICK = 1;
+ rfcsr.field.TESTCSR_RFACC_REGNUM = RegID;
+ RTMP_IO_WRITE32(pAd, RF_CSR_CFG, rfcsr.word);
+ for (k=0; k<MAX_BUSY_COUNT; k++)
+ {
+ RTMP_IO_READ32(pAd, RF_CSR_CFG, &rfcsr.word);
+
+ if (rfcsr.field.RF_CSR_KICK == IDLE)
+ break;
+ }
+ if ((rfcsr.field.RF_CSR_KICK == IDLE) &&
+ (rfcsr.field.TESTCSR_RFACC_REGNUM == RegID))
+ {
+ *pValue = (UCHAR)rfcsr.field.RF_CSR_DATA;
+ break;
+ }
+ }
+ if (rfcsr.field.RF_CSR_KICK == BUSY)
+ {
+ DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", RegID, rfcsr.word,i,k));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return STATUS_SUCCESS;
+}
+#endif // RT30xx //
+
+#ifdef RT30xx
+// add by johnli, RF power sequence setup
+/*
+ ==========================================================================
+ Description:
+
+ Load RF normal operation-mode setup
+
+ ==========================================================================
+ */
+VOID RT30xxLoadRFNormalModeSetup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue;
+
+ // RX0_PD & TX0_PD, RF R1 register Bit 2 & Bit 3 to 0 and RF_BLOCK_en,RX1_PD & TX1_PD, Bit0, Bit 4 & Bit5 to 1
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ RFValue = (RFValue & (~0x0C)) | 0x31;
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // TX_LO2_en, RF R15 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R15, &RFValue);
+ RFValue &= (~0x08);
+ RT30xxWriteRFRegister(pAd, RF_R15, RFValue);
+
+ // TX_LO1_en, RF R17 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R17, &RFValue);
+ RFValue &= (~0x08);
+ // to fix rx long range issue
+ if (((pAd->MACVersion & 0xffff) >= 0x0211) && (pAd->NicConfig2.field.ExternalLNAForG == 0))
+ {
+ RFValue |= 0x20;
+ }
+ RT30xxWriteRFRegister(pAd, RF_R17, RFValue);
+
+ // RX_LO1_en, RF R20 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R20, &RFValue);
+ RFValue &= (~0x08);
+ RT30xxWriteRFRegister(pAd, RF_R20, RFValue);
+
+ // RX_LO2_en, RF R21 register Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+ RFValue &= (~0x08);
+ RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+ // LDORF_VC, RF R27 register Bit 2 to 0
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ RFValue = (RFValue & (~0x77)) | 0x3;
+ else
+ RFValue = (RFValue & (~0x77));
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+ /* end johnli */
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ Load RF sleep-mode setup
+
+ ==========================================================================
+ */
+VOID RT30xxLoadRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue;
+ UINT32 MACValue;
+
+ // RF_BLOCK_en. RF R1 register Bit 0 to 0
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ RFValue &= (~0x01);
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // VCO_IC, RF R7 register Bit 4 & Bit 5 to 0
+ RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+ RFValue &= (~0x30);
+ RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+ // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 0
+ RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+ RFValue &= (~0x0E);
+ RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+ // RX_CTB_en, RF R21 register Bit 7 to 0
+ RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+ RFValue &= (~0x80);
+ RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+ // LDORF_VC, RF R27 register Bit 0, Bit 1 & Bit 2 to 1
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+ RFValue |= 0x77;
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+
+ RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+ MACValue |= 0x1D000000;
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ Reverse RF sleep-mode setup
+
+ ==========================================================================
+ */
+VOID RT30xxReverseRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR RFValue;
+ UINT32 MACValue;
+
+ // RF_BLOCK_en, RF R1 register Bit 0 to 1
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ RFValue |= 0x01;
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // VCO_IC, RF R7 register Bit 4 & Bit 5 to 1
+ RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+ RFValue |= 0x30;
+ RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+ // Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1
+ RT30xxReadRFRegister(pAd, RF_R09, &RFValue);
+ RFValue |= 0x0E;
+ RT30xxWriteRFRegister(pAd, RF_R09, RFValue);
+
+ // RX_CTB_en, RF R21 register Bit 7 to 1
+ RT30xxReadRFRegister(pAd, RF_R21, &RFValue);
+ RFValue |= 0x80;
+ RT30xxWriteRFRegister(pAd, RF_R21, RFValue);
+
+ // LDORF_VC, RF R27 register Bit 2 to 0
+ RT30xxReadRFRegister(pAd, RF_R27, &RFValue);
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ RFValue = (RFValue & (~0x77)) | 0x3;
+ else
+ RFValue = (RFValue & (~0x77));
+ RT30xxWriteRFRegister(pAd, RF_R27, RFValue);
+
+ // RT3071 version E has fixed this issue
+ if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+ {
+ // patch tx EVM issue temporarily
+ RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+ MACValue = ((MACValue & 0xE0FFFFFF) | 0x0D000000);
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, LDO_CFG0, &MACValue);
+ MACValue = ((MACValue & 0xE0FFFFFF) | 0x01000000);
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, MACValue);
+ }
+}
+// end johnli
+#endif // RT30xx //
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan)
+{
+ ULONG R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0;
+ CHAR TxPwer = 0, TxPwer2 = DEFAULT_RF_TX_POWER; //Bbp94 = BBPR94_DEFAULT, TxPwer2 = DEFAULT_RF_TX_POWER;
+ UCHAR index;
+ UINT32 Value = 0; //BbpReg, Value;
+ RTMP_RF_REGS *RFRegTable;
+
+ // Search Tx power value
+#if 1
+ // We can't use ChannelList to search channel, since some central channl's txpowr doesn't list
+ // in ChannelList, so use TxPower array instead.
+ //
+ for (index = 0; index < MAX_NUM_OF_CHANNELS; index++)
+ {
+ if (Channel == pAd->TxPower[index].Channel)
+ {
+ TxPwer = pAd->TxPower[index].Power;
+ TxPwer2 = pAd->TxPower[index].Power2;
+ break;
+ }
+ }
+#else
+ for (index = 0; index < pAd->ChannelListNum; index++)
+ {
+ if (Channel == pAd->ChannelList[index].Channel)
+ {
+ TxPwer = pAd->ChannelList[index].Power;
+ TxPwer2 = pAd->ChannelList[index].Power2;
+ break;
+ }
+ }
+#endif
+
+ if (index == MAX_NUM_OF_CHANNELS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: Can't find the Channel#%d \n", Channel));
+ }
+
+#ifdef RT30xx
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ if ((IS_RT3070(pAd) || IS_RT3090(pAd)) && ((pAd->RfIcType == RFIC_3020) || (pAd->RfIcType == RFIC_2020) ||
+ (pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022)))
+ {
+ /* modify by WY for Read RF Reg. error */
+ UCHAR RFValue;
+
+ for (index = 0; index < NUM_OF_3020_CHNL; index++)
+ {
+ if (Channel == FreqItems3020[index].Channel)
+ {
+ // Programming channel parameters
+ RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+ RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+ RT30xxReadRFRegister(pAd, RF_R06, &RFValue);
+ RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+ RT30xxWriteRFRegister(pAd, RF_R06, RFValue);
+
+ // Set Tx0 Power
+ RT30xxReadRFRegister(pAd, RF_R12, &RFValue);
+ RFValue = (RFValue & 0xE0) | TxPwer;
+ RT30xxWriteRFRegister(pAd, RF_R12, RFValue);
+
+ // Set Tx1 Power
+ RT30xxReadRFRegister(pAd, RF_R13, &RFValue);
+ RFValue = (RFValue & 0xE0) | TxPwer2;
+ RT30xxWriteRFRegister(pAd, RF_R13, RFValue);
+
+ // Tx/Rx Stream setting
+ RT30xxReadRFRegister(pAd, RF_R01, &RFValue);
+ //if (IS_RT3090(pAd))
+ // RFValue |= 0x01; // Enable RF block.
+ RFValue &= 0x03; //clear bit[7~2]
+ if (pAd->Antenna.field.TxPath == 1)
+ RFValue |= 0xA0;
+ else if (pAd->Antenna.field.TxPath == 2)
+ RFValue |= 0x80;
+ if (pAd->Antenna.field.RxPath == 1)
+ RFValue |= 0x50;
+ else if (pAd->Antenna.field.RxPath == 2)
+ RFValue |= 0x40;
+ RT30xxWriteRFRegister(pAd, RF_R01, RFValue);
+
+ // Set RF offset
+ RT30xxReadRFRegister(pAd, RF_R23, &RFValue);
+ RFValue = (RFValue & 0x80) | pAd->RfFreqOffset;
+ RT30xxWriteRFRegister(pAd, RF_R23, RFValue);
+
+ // Set BW
+ if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+ {
+ RFValue = pAd->Mlme.CaliBW40RfR24;
+ //DISABLE_11N_CHECK(pAd);
+ }
+ else
+ {
+ RFValue = pAd->Mlme.CaliBW20RfR24;
+ }
+ RT30xxWriteRFRegister(pAd, RF_R24, RFValue);
+ RT30xxWriteRFRegister(pAd, RF_R31, RFValue);
+
+ // Enable RF tuning
+ RT30xxReadRFRegister(pAd, RF_R07, &RFValue);
+ RFValue = RFValue | 0x1;
+ RT30xxWriteRFRegister(pAd, RF_R07, RFValue);
+
+ // latch channel for future usage.
+ pAd->LatchRfRegs.Channel = Channel;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+ Channel,
+ pAd->RfIcType,
+ TxPwer,
+ TxPwer2,
+ pAd->Antenna.field.TxPath,
+ FreqItems3020[index].N,
+ FreqItems3020[index].K,
+ FreqItems3020[index].R));
+
+ break;
+ }
+ }
+ }
+ else
+#endif // RT30xx //
+
+ {
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R2 = RFRegTable[index].R2;
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
+ }
+
+ if (pAd->Antenna.field.RxPath == 2)
+ {
+ R2 |= 0x40; // write 1 to off Rxpath.
+ }
+ else if (pAd->Antenna.field.RxPath == 1)
+ {
+ R2 |= 0x20040; // write 1 to off RxPath
+ }
+
+ if (Channel > 14)
+ {
+ // initialize R3, R4
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15);
+
+ // 5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+ // R3
+ if ((TxPwer >= -7) && (TxPwer < 0))
+ {
+ TxPwer = (7+TxPwer);
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10);
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer=%d \n", TxPwer));
+ }
+ else
+ {
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10) | (1 << 9);
+ }
+
+ // R4
+ if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+ {
+ TxPwer2 = (7+TxPwer2);
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7);
+ DBGPRINT(RT_DEBUG_ERROR, ("AsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+ }
+ else
+ {
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7) | (1 << 6);
+ }
+ }
+ else
+ {
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->RfFreqOffset << 15) | (TxPwer2 <<6);// Set freq Offset & TxPwr1
+ }
+
+ // Based on BBP current mode before changing RF channel.
+ if (!bScan && (pAd->CommonCfg.BBPCurrentBW == BW_40))
+ {
+ R4 |=0x200000;
+ }
+
+ // Update variables
+ pAd->LatchRfRegs.Channel = Channel;
+ pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+ pAd->LatchRfRegs.R2 = R2;
+ pAd->LatchRfRegs.R3 = R3;
+ pAd->LatchRfRegs.R4 = R4;
+
+ // Set RF value 1's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 2's set R3[bit2] = [1]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 3's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Change BBP setting during siwtch from a->g, g->a
+ if (Channel <= 14)
+ {
+ ULONG TxPinCfg = 0x00050F0A;//Gary 2007/08/09 0x050A0A
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+
+ // Rx High power VGA offset for LNA select
+ if (pAd->NicConfig2.field.ExternalLNAForG)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+ }
+ else
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+ }
+
+ // 5G band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x04);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+ else
+ {
+ ULONG TxPinCfg = 0x00050F05;//Gary 2007/8/9 0x050505
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0);//(0x44 - GET_LNA_GAIN(pAd))); // According the Rory's suggestion to solve the middle range issue.
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+ // Rx High power VGA offset for LNA select
+ if (pAd->NicConfig2.field.ExternalLNAForA)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x46);
+ }
+ else
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R75, 0x50);
+ }
+
+ // 5G band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x02);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+
+ // R66 should be set according to Channel and use 20MHz when scanning
+ //RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, (0x2E + GET_LNA_GAIN(pAd)));
+ if (bScan)
+ RTMPSetAGCInitValue(pAd, BW_20);
+ else
+ RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+
+ //
+ // On 11A, We should delay and wait RF/BBP to be stable
+ // and the appropriate time should be 1000 micro seconds
+ // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+ //
+ RTMPusecDelay(1000);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%lu, Pwr1=%lu, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+ Channel,
+ pAd->RfIcType,
+ (R3 & 0x00003e00) >> 9,
+ (R4 & 0x000007c0) >> 6,
+ pAd->Antenna.field.TxPath,
+ pAd->LatchRfRegs.R1,
+ pAd->LatchRfRegs.R2,
+ pAd->LatchRfRegs.R3,
+ pAd->LatchRfRegs.R4));
+}
+
+/*
+ ==========================================================================
+ Description:
+ This function is required for 2421 only, and should not be used during
+ site survey. It's only required after NIC decided to stay at a channel
+ for a longer period.
+ When this function is called, it's always after AsicSwitchChannel().
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicLockChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicAntennaSelect(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ if (pAd->Mlme.OneSecPeriodicRound % 2 == 1)
+ {
+ // patch for AsicSetRxAnt failed
+ pAd->RxAnt.EvaluatePeriod = 0;
+
+ // check every 2 second. If rcv-beacon less than 5 in the past 2 second, then AvgRSSI is no longer a
+ // valid indication of the distance between this AP and its clients.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ SHORT realavgrssi1;
+
+ // if no traffic then reset average rssi to trigger evaluation
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->StaCfg.NumOfAvgRssiSample < 5)
+ {
+ pAd->RxAnt.Pair1LastAvgRssi = (-99);
+ pAd->RxAnt.Pair2LastAvgRssi = (-99);
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no traffic/beacon, reset RSSI\n"));
+ }
+
+ pAd->StaCfg.NumOfAvgRssiSample = 0;
+#endif // CONFIG_STA_SUPPORT //
+ realavgrssi1 = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt] >> 3);
+
+ DBGPRINT(RT_DEBUG_TRACE,("Ant-realrssi0(%d), Lastrssi0(%d), EvaluateStableCnt=%d\n", realavgrssi1, pAd->RxAnt.Pair1LastAvgRssi, pAd->RxAnt.EvaluateStableCnt));
+
+ // if the difference between two rssi is larger or less than 5, then evaluate the other antenna
+ if ((pAd->RxAnt.EvaluateStableCnt < 2) || (realavgrssi1 > (pAd->RxAnt.Pair1LastAvgRssi + 5)) || (realavgrssi1 < (pAd->RxAnt.Pair1LastAvgRssi - 5)))
+ {
+ pAd->RxAnt.Pair1LastAvgRssi = realavgrssi1;
+ AsicEvaluateRxAnt(pAd);
+ }
+ }
+ else
+ {
+ // if not connected, always switch antenna to try to connect
+ UCHAR temp;
+
+ temp = pAd->RxAnt.Pair1PrimaryRxAnt;
+ pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
+ pAd->RxAnt.Pair1SecondaryRxAnt = temp;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmePeriodicExec: no connect, switch to another one to try connection\n"));
+
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ }
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Antenna miscellaneous setting.
+
+ Arguments:
+ pAd Pointer to our adapter
+ BandState Indicate current Band State.
+
+ Return Value:
+ None
+
+ IRQL <= DISPATCH_LEVEL
+
+ Note:
+ 1.) Frame End type control
+ only valid for G only (RF_2527 & RF_2529)
+ 0: means DPDT, set BBP R4 bit 5 to 1
+ 1: means SPDT, set BBP R4 bit 5 to 0
+
+
+ ========================================================================
+*/
+VOID AsicAntennaSetting(
+ IN PRTMP_ADAPTER pAd,
+ IN ABGBAND_STATE BandState)
+{
+}
+
+VOID AsicRfTuningExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+}
+
+/*
+ ==========================================================================
+ Description:
+ Gives CCK TX rate 2 more dB TX power.
+ This routine works only in LINK UP in INFRASTRUCTURE mode.
+
+ calculate desired Tx power in RF R3.Tx0~5, should consider -
+ 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+ 1. TxPowerPercentage
+ 2. auto calibration based on TSSI feedback
+ 3. extra 2 db for CCK
+ 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+ NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+ it should be called AFTER MlmeDynamicTxRatSwitching()
+ ==========================================================================
+ */
+VOID AsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ CHAR DeltaPwr = 0;
+ BOOLEAN bAutoTxAgc = FALSE;
+ UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+ UCHAR BbpR1 = 0, BbpR49 = 0, idx;
+ PCHAR pTxAgcCompensate;
+ ULONG TxPwr[5];
+ CHAR Value;
+
+
+
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ if (pAd->CommonCfg.CentralChannel > 14)
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+ }
+ }
+
+ // TX power compensation for temperature variation based on TSSI. try every 4 second
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ /* bg channel */
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ TssiRef = pAd->TssiRefG;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
+ TxAgcStep = pAd->TxAgcStepG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ /* a channel */
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ TssiRef = pAd->TssiRefA;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
+ TxAgcStep = pAd->TxAgcStepA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ {
+ /* BbpR1 is unsigned char */
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+ /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+ /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
+ /* step value is defined in pAd->TxAgcStepG for tx power value */
+
+ /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
+ /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+ above value are examined in mass factory production */
+ /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
+
+ /* plus (+) is 0x00 ~ 0x45, minus (-) is 0xa0 ~ 0xf0 */
+ /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+ /* if value is 0xa5, tx power will be -= TxAgcStep*(2-1) */
+
+ if (BbpR49 > pTssiMinusBoundary[1])
+ {
+ // Reading is larger than the reference value
+ // check for how large we need to decrease the Tx power
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should decrease, idx = 0 means there is nothing to compensate
+// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+ *pTxAgcCompensate = -(TxAgcStep * (idx-1));
+// else
+// *pTxAgcCompensate = -((UCHAR)R3);
+
+ DeltaPwr += (*pTxAgcCompensate);
+ DBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else if (BbpR49 < pTssiPlusBoundary[1])
+ {
+ // Reading is smaller than the reference value
+ // check for how large we need to increase the Tx power
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should increase, idx = 0 means there is nothing to compensate
+ *pTxAgcCompensate = TxAgcStep * (idx-1);
+ DeltaPwr += (*pTxAgcCompensate);
+ DBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else
+ {
+ *pTxAgcCompensate = 0;
+ DBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R49=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, 0));
+ }
+ }
+ }
+ else
+ {
+ if (pAd->CommonCfg.Channel <= 14)
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ DeltaPwr += (*pTxAgcCompensate);
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpR1);
+ BbpR1 &= 0xFC;
+
+#ifdef SINGLE_SKU
+ // Handle regulatory max tx power constrain
+ do
+ {
+ UCHAR TxPwrInEEPROM = 0xFF, CountryTxPwr = 0xFF, criterion;
+ UCHAR AdjustMaxTxPwr[40];
+
+ if (pAd->CommonCfg.Channel > 14) // 5G band
+ TxPwrInEEPROM = ((pAd->CommonCfg.DefineMaxTxPwr & 0xFF00) >> 8);
+ else // 2.4G band
+ TxPwrInEEPROM = (pAd->CommonCfg.DefineMaxTxPwr & 0x00FF);
+ CountryTxPwr = GetCuntryMaxTxPwr(pAd, pAd->CommonCfg.Channel);
+
+ // error handling, range check
+ if ((TxPwrInEEPROM > 0x50) || (CountryTxPwr > 0x50))
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("AsicAdjustTxPower - Invalid max tx power (=0x%02x), CountryTxPwr=%d\n", TxPwrInEEPROM, CountryTxPwr));
+ break;
+ }
+
+ criterion = *((PUCHAR)TxPwr + 2) & 0xF; // FAE use OFDM 6M as criterion
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (criterion=%d, TxPwrInEEPROM=%d, CountryTxPwr=%d)\n", criterion, TxPwrInEEPROM, CountryTxPwr));
+
+ // Adjust max tx power according to the relationship of tx power in E2PROM
+ for (i=0; i<5; i++)
+ {
+ // CCK will have 4dBm larger than OFDM
+ // Therefore, we should separate to parse the tx power field
+ if (i == 0)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+ if (j < 4)
+ {
+ // CCK will have 4dBm larger than OFDM
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion) + 4;
+ }
+ else
+ {
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+ }
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ else
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+ AdjustMaxTxPwr[i*8+j] = TxPwrInEEPROM + (Value - criterion);
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+ }
+ }
+ }
+
+ // Adjust tx power according to the relationship
+ for (i=0; i<5; i++)
+ {
+ if (TxPwr[i] != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F);
+
+ // The system tx power is larger than the regulatory, the power should be restrain
+ if (AdjustMaxTxPwr[i*8+j] > CountryTxPwr)
+ {
+ // decrease to zero and don't need to take care BBPR1
+ if ((Value - (AdjustMaxTxPwr[i*8+j] - CountryTxPwr)) > 0)
+ Value -= (AdjustMaxTxPwr[i*8+j] - CountryTxPwr);
+ else
+ Value = 0;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+ }
+ else
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("AsicAdjustTxPower (i/j=%d/%d, Value=%d, %d, no change)\n", i, j, Value, AdjustMaxTxPwr[i*8+j]));
+
+ TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+ }
+ }
+ } while (FALSE);
+#endif // SINGLE_SKU //
+
+ /* calculate delta power based on the percentage specified from UI */
+ // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+ // We lower TX power here according to the percentage specified from UI
+ if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW // DeltaPwr -= 1;
+ {
+ DeltaPwr -= 1;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW // DeltaPwr -= 3;
+ {
+ DeltaPwr -= 3;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW // DeltaPwr -= 6;
+ {
+ BbpR1 |= 0x01;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW // DeltaPwr -= 9;
+ {
+ BbpR1 |= 0x01;
+ DeltaPwr -= 3;
+ }
+ else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW // DeltaPwr -= 12;
+ {
+ BbpR1 |= 0x02;
+ }
+
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpR1);
+
+ /* reset different new tx power for different TX rate */
+ for(i=0; i<5; i++)
+ {
+ if (TxPwr[i] != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+ if ((Value + DeltaPwr) < 0)
+ {
+ Value = 0; /* min */
+ }
+ else if ((Value + DeltaPwr) > 0xF)
+ {
+ Value = 0xF; /* max */
+ }
+ else
+ {
+ Value += DeltaPwr; /* temperature compensation */
+ }
+
+ /* fill new value to CSR offset */
+ TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+
+ /* write tx power value to CSR */
+ /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
+ TX power for OFDM 6M/9M
+ TX power for CCK5.5M/11M
+ TX power for CCK1M/2M */
+ /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+ }
+ }
+
+
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ put PHY to sleep here, and set next wakeup timer. PHY doesn't not wakeup
+ automatically. Instead, MCU will issue a TwakeUpInterrupt to host after
+ the wakeup timer timeout. Driver has to issue a separate command to wake
+ PHY up.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp)
+{
+ RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp);
+}
+
+/*
+ ==========================================================================
+ Description:
+ AsicForceWakeup() is used whenever manual wakeup is required
+ AsicForceSleep() should only be used when not in INFRA BSS. When
+ in INFRA BSS, we should use AsicSleepThenAutoWakeup() instead.
+ ==========================================================================
+ */
+VOID AsicForceSleep(
+ IN PRTMP_ADAPTER pAd)
+{
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ AsicForceWakeup() is used whenever Twakeup timer (set via AsicSleepThenAutoWakeup)
+ expired.
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+ ==========================================================================
+ */
+VOID AsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("--> AsicForceWakeup \n"));
+ RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx);
+}
+#endif // CONFIG_STA_SUPPORT //
+/*
+ ==========================================================================
+ Description:
+ Set My BSSID
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetBssid(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid)
+{
+ ULONG Addr4;
+ DBGPRINT(RT_DEBUG_TRACE, ("==============> AsicSetBssid %x:%x:%x:%x:%x:%x\n",
+ pBssid[0],pBssid[1],pBssid[2],pBssid[3], pBssid[4],pBssid[5]));
+
+ Addr4 = (ULONG)(pBssid[0]) |
+ (ULONG)(pBssid[1] << 8) |
+ (ULONG)(pBssid[2] << 16) |
+ (ULONG)(pBssid[3] << 24);
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW0, Addr4);
+
+ Addr4 = 0;
+ // always one BSSID in STA mode
+ Addr4 = (ULONG)(pBssid[4]) | (ULONG)(pBssid[5] << 8);
+
+ RTMP_IO_WRITE32(pAd, MAC_BSSID_DW1, Addr4);
+}
+
+VOID AsicSetMcastWC(
+ IN PRTMP_ADAPTER pAd)
+{
+ MAC_TABLE_ENTRY *pEntry = &pAd->MacTab.Content[MCAST_WCID];
+ USHORT offset;
+
+ pEntry->Sst = SST_ASSOC;
+ pEntry->Aid = MCAST_WCID; // Softap supports 1 BSSID and use WCID=0 as multicast Wcid index
+ pEntry->PsMode = PWR_ACTIVE;
+ pEntry->CurrTxRate = pAd->CommonCfg.MlmeRate;
+ offset = MAC_WCID_BASE + BSS0Mcast_WCID * HW_WCID_ENTRY_SIZE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDelWcidTab(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid)
+{
+ ULONG Addr0 = 0x0, Addr1 = 0x0;
+ ULONG offset;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicDelWcidTab==>Wcid = 0x%x\n",Wcid));
+ offset = MAC_WCID_BASE + Wcid * HW_WCID_ENTRY_SIZE;
+ RTMP_IO_WRITE32(pAd, offset, Addr0);
+ offset += 4;
+ RTMP_IO_WRITE32(pAd, offset, Addr1);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableRDG(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+ UINT32 Data = 0;
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+ TxLinkCfg.field.TxRDGEn = 1;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ Data |= 0x80;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ //OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableRDG(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+ UINT32 Data = 0;
+
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+ TxLinkCfg.field.TxRDGEn = 0;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+
+ Data &= 0xFFFFFF00;
+ //Data |= 0x20;
+#ifndef WIFI_TEST
+ //if ( pAd->CommonCfg.bEnableTxBurst )
+ // Data |= 0x60; // for performance issue not set the TXOP to 0
+#endif
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE)
+#ifdef DOT11_N_SUPPORT
+ && (pAd->MacTab.fAnyStationMIMOPSDynamic == FALSE)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+ if (pAd->CommonCfg.bEnableTxBurst)
+ Data |= 0x20;
+ }
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicDisableSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->Disable TSF synchronization\n"));
+
+ // 2003-12-20 disable TSF and TBTT while NIC in power-saving have side effect
+ // that NIC will never wakes up because TSF stops and no more
+ // TBTT interrupts
+ pAd->TbttTickCount = 0;
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+ csr.field.bBeaconGen = 0;
+ csr.field.bTBTTEnable = 0;
+ csr.field.TsfSyncMode = 0;
+ csr.field.bTsfTicking = 0;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableBssSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableBssSync(INFRA mode)\n"));
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr.word);
+// RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, 0x00000000);
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ csr.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+ csr.field.bTsfTicking = 1;
+ csr.field.TsfSyncMode = 1; // sync TSF in INFRASTRUCTURE mode
+ csr.field.bBeaconGen = 0; // do NOT generate BEACON
+ csr.field.bTBTTEnable = 1;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Note:
+ BEACON frame in shared memory should be built ok before this routine
+ can be called. Otherwise, a garbage frame maybe transmitted out every
+ Beacon period.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicEnableIbssSync(
+ IN PRTMP_ADAPTER pAd)
+{
+ BCN_TIME_CFG_STRUC csr9;
+ PUCHAR ptr;
+ UINT i;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->AsicEnableIbssSync(ADHOC mode. MPDUtotalByteCount = %d)\n", pAd->BeaconTxWI.MPDUtotalByteCount));
+
+ RTMP_IO_READ32(pAd, BCN_TIME_CFG, &csr9.word);
+ csr9.field.bBeaconGen = 0;
+ csr9.field.bTBTTEnable = 0;
+ csr9.field.bTsfTicking = 0;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+
+
+#ifdef RT2870
+ // move BEACON TXD and frame content to on-chip memory
+ ptr = (PUCHAR)&pAd->BeaconTxWI;
+ for (i=0; i<TXWI_SIZE; i+=2) // 16-byte TXWI field
+ {
+ //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + i, longptr);
+ RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + i, ptr, 2);
+ ptr += 2;
+ }
+
+ // start right after the 16-byte TXWI field
+ ptr = pAd->BeaconBuf;
+ for (i=0; i< pAd->BeaconTxWI.MPDUtotalByteCount; i+=2)
+ {
+ //UINT32 longptr = *ptr + (*(ptr+1)<<8) + (*(ptr+2)<<16) + (*(ptr+3)<<24);
+ //RTMP_IO_WRITE32(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, longptr);
+ RTUSBMultiWrite(pAd, HW_BEACON_BASE0 + TXWI_SIZE + i, ptr, 2);
+ ptr +=2;
+ }
+#endif // RT2870 //
+
+ //
+ // For Wi-Fi faily generated beacons between participating stations.
+ // Set TBTT phase adaptive adjustment step to 8us (default 16us)
+ // don't change settings 2006-5- by Jerry
+ //RTMP_IO_WRITE32(pAd, TBTT_SYNC_CFG, 0x00001010);
+
+ // start sending BEACON
+ csr9.field.BeaconInterval = pAd->CommonCfg.BeaconPeriod << 4; // ASIC register in units of 1/16 TU
+ csr9.field.bTsfTicking = 1;
+ csr9.field.TsfSyncMode = 2; // sync TSF in IBSS mode
+ csr9.field.bTBTTEnable = 1;
+ csr9.field.bBeaconGen = 1;
+ RTMP_IO_WRITE32(pAd, BCN_TIME_CFG, csr9.word);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetEdcaParm(
+ IN PRTMP_ADAPTER pAd,
+ IN PEDCA_PARM pEdcaParm)
+{
+ EDCA_AC_CFG_STRUC Ac0Cfg, Ac1Cfg, Ac2Cfg, Ac3Cfg;
+ AC_TXOP_CSR0_STRUC csr0;
+ AC_TXOP_CSR1_STRUC csr1;
+ AIFSN_CSR_STRUC AifsnCsr;
+ CWMIN_CSR_STRUC CwminCsr;
+ CWMAX_CSR_STRUC CwmaxCsr;
+ int i;
+
+ Ac0Cfg.word = 0;
+ Ac1Cfg.word = 0;
+ Ac2Cfg.word = 0;
+ Ac3Cfg.word = 0;
+ if ((pEdcaParm == NULL) || (pEdcaParm->bValid == FALSE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AsicSetEdcaParm\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI || pAd->MacTab.Content[i].ValidAsApCli)
+ CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[i], fCLIENT_STATUS_WMM_CAPABLE);
+ }
+
+ //========================================================
+ // MAC Register has a copy .
+ //========================================================
+//#ifndef WIFI_TEST
+ if( pAd->CommonCfg.bEnableTxBurst )
+ {
+ // For CWC test, change txop from 0x30 to 0x20 in TxBurst mode
+ Ac0Cfg.field.AcTxop = 0x20; // Suggest by John for TxBurst in HT Mode
+ }
+ else
+ Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
+//#else
+// Ac0Cfg.field.AcTxop = 0; // QID_AC_BE
+//#endif
+ Ac0Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac0Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac0Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+
+ Ac1Cfg.field.AcTxop = 0; // QID_AC_BK
+ Ac1Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac1Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac1Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ Ac2Cfg.field.AcTxop = 192; // AC_VI: 192*32us ~= 6ms
+ Ac3Cfg.field.AcTxop = 96; // AC_VO: 96*32us ~= 3ms
+ }
+ else
+ {
+ Ac2Cfg.field.AcTxop = 96; // AC_VI: 96*32us ~= 3ms
+ Ac3Cfg.field.AcTxop = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+ Ac2Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac2Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac2Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+ Ac3Cfg.field.Cwmin = CW_MIN_IN_BITS;
+ Ac3Cfg.field.Cwmax = CW_MAX_IN_BITS;
+ Ac3Cfg.field.Aifsn = 2;
+ RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+ //========================================================
+ // DMA Register has a copy too.
+ //========================================================
+ csr0.field.Ac0Txop = 0; // QID_AC_BE
+ csr0.field.Ac1Txop = 0; // QID_AC_BK
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ csr1.field.Ac2Txop = 192; // AC_VI: 192*32us ~= 6ms
+ csr1.field.Ac3Txop = 96; // AC_VO: 96*32us ~= 3ms
+ }
+ else
+ {
+ csr1.field.Ac2Txop = 96; // AC_VI: 96*32us ~= 3ms
+ csr1.field.Ac3Txop = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+ CwminCsr.word = 0;
+ CwminCsr.field.Cwmin0 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin1 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin2 = CW_MIN_IN_BITS;
+ CwminCsr.field.Cwmin3 = CW_MIN_IN_BITS;
+ RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+ CwmaxCsr.word = 0;
+ CwmaxCsr.field.Cwmax0 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax1 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax2 = CW_MAX_IN_BITS;
+ CwmaxCsr.field.Cwmax3 = CW_MAX_IN_BITS;
+ RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+ RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, 0x00002222);
+
+ NdisZeroMemory(&pAd->CommonCfg.APEdcaParm, sizeof(EDCA_PARM));
+ }
+ else
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_WMM_INUSED);
+ //========================================================
+ // MAC Register has a copy.
+ //========================================================
+ //
+ // Modify Cwmin/Cwmax/Txop on queue[QID_AC_VI], Recommend by Jerry 2005/07/27
+ // To degrade our VIDO Queue's throughput for WiFi WMM S3T07 Issue.
+ //
+ //pEdcaParm->Txop[QID_AC_VI] = pEdcaParm->Txop[QID_AC_VI] * 7 / 10; // rt2860c need this
+
+ Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE];
+ Ac0Cfg.field.Cwmin= pEdcaParm->Cwmin[QID_AC_BE];
+ Ac0Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BE];
+ Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]; //+1;
+
+ Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+ Ac1Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_BK]; //+2;
+ Ac1Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_BK];
+ Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK]; //+1;
+
+ Ac2Cfg.field.AcTxop = (pEdcaParm->Txop[QID_AC_VI] * 6) / 10;
+ Ac2Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VI];
+ Ac2Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VI];
+ Ac2Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VI];
+#ifdef INF_AMAZON_SE
+#endif // INF_AMAZON_SE //
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Tuning for Wi-Fi WMM S06
+ if (pAd->CommonCfg.bWiFiTest &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ Ac2Cfg.field.Aifsn -= 1;
+
+ // Tuning for TGn Wi-Fi 5.2.32
+ // STA TestBed changes in this item: conexant legacy sta ==> broadcom 11n sta
+ if (STA_TGN_WIFI_ON(pAd) &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ {
+ Ac0Cfg.field.Aifsn = 3;
+ Ac2Cfg.field.AcTxop = 5;
+ }
+
+#ifdef RT30xx
+ if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+ {
+ // Tuning for WiFi WMM S3-T07: connexant legacy sta ==> broadcom 11n sta.
+ Ac2Cfg.field.Aifsn = 5;
+ }
+#endif // RT30xx //
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ Ac3Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VO];
+ Ac3Cfg.field.Cwmin = pEdcaParm->Cwmin[QID_AC_VO];
+ Ac3Cfg.field.Cwmax = pEdcaParm->Cwmax[QID_AC_VO];
+ Ac3Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_VO];
+
+//#ifdef WIFI_TEST
+ if (pAd->CommonCfg.bWiFiTest)
+ {
+ if (Ac3Cfg.field.AcTxop == 102)
+ {
+ Ac0Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BE] ? pEdcaParm->Txop[QID_AC_BE] : 10;
+ Ac0Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BE]-1; /* AIFSN must >= 1 */
+ Ac1Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_BK];
+ Ac1Cfg.field.Aifsn = pEdcaParm->Aifsn[QID_AC_BK];
+ Ac2Cfg.field.AcTxop = pEdcaParm->Txop[QID_AC_VI];
+ } /* End of if */
+ }
+//#endif // WIFI_TEST //
+
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Ac0Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC1_CFG, Ac1Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC2_CFG, Ac2Cfg.word);
+ RTMP_IO_WRITE32(pAd, EDCA_AC3_CFG, Ac3Cfg.word);
+
+
+ //========================================================
+ // DMA Register has a copy too.
+ //========================================================
+ csr0.field.Ac0Txop = Ac0Cfg.field.AcTxop;
+ csr0.field.Ac1Txop = Ac1Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+
+ csr1.field.Ac2Txop = Ac2Cfg.field.AcTxop;
+ csr1.field.Ac3Txop = Ac3Cfg.field.AcTxop;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr1.word);
+
+ CwminCsr.word = 0;
+ CwminCsr.field.Cwmin0 = pEdcaParm->Cwmin[QID_AC_BE];
+ CwminCsr.field.Cwmin1 = pEdcaParm->Cwmin[QID_AC_BK];
+ CwminCsr.field.Cwmin2 = pEdcaParm->Cwmin[QID_AC_VI];
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ CwminCsr.field.Cwmin3 = pEdcaParm->Cwmin[QID_AC_VO] - 1; //for TGn wifi test
+#endif // CONFIG_STA_SUPPORT //
+ RTMP_IO_WRITE32(pAd, WMM_CWMIN_CFG, CwminCsr.word);
+
+ CwmaxCsr.word = 0;
+ CwmaxCsr.field.Cwmax0 = pEdcaParm->Cwmax[QID_AC_BE];
+ CwmaxCsr.field.Cwmax1 = pEdcaParm->Cwmax[QID_AC_BK];
+ CwmaxCsr.field.Cwmax2 = pEdcaParm->Cwmax[QID_AC_VI];
+ CwmaxCsr.field.Cwmax3 = pEdcaParm->Cwmax[QID_AC_VO];
+ RTMP_IO_WRITE32(pAd, WMM_CWMAX_CFG, CwmaxCsr.word);
+
+ AifsnCsr.word = 0;
+ AifsnCsr.field.Aifsn0 = Ac0Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BE];
+ AifsnCsr.field.Aifsn1 = Ac1Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_BK];
+ AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn; //pEdcaParm->Aifsn[QID_AC_VI];
+#ifdef INF_AMAZON_SE
+#endif // INF_AMAZON_SE //
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Tuning for Wi-Fi WMM S06
+ if (pAd->CommonCfg.bWiFiTest &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ AifsnCsr.field.Aifsn2 = Ac2Cfg.field.Aifsn - 4;
+
+ // Tuning for TGn Wi-Fi 5.2.32
+ // STA TestBed changes in this item: connexant legacy sta ==> broadcom 11n sta
+ if (STA_TGN_WIFI_ON(pAd) &&
+ pEdcaParm->Aifsn[QID_AC_VI] == 10)
+ {
+ AifsnCsr.field.Aifsn0 = 3;
+ AifsnCsr.field.Aifsn2 = 7;
+ }
+
+ if (INFRA_ON(pAd))
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_WMM_CAPABLE);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AifsnCsr.field.Aifsn3 = Ac3Cfg.field.Aifsn - 1; //pEdcaParm->Aifsn[QID_AC_VO]; //for TGn wifi test
+#ifdef RT30xx
+ if (pAd->RfIcType == RFIC_3020 || pAd->RfIcType == RFIC_2020)
+ {
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ AifsnCsr.field.Aifsn2 = 0x2; //pEdcaParm->Aifsn[QID_AC_VI]; //for WiFi WMM S4-T04.
+ }
+#endif // RT30xx //
+#endif // CONFIG_STA_SUPPORT //
+ RTMP_IO_WRITE32(pAd, WMM_AIFSN_CFG, AifsnCsr.word);
+
+ NdisMoveMemory(&pAd->CommonCfg.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+ if (!ADHOC_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("EDCA [#%d]: AIFSN CWmin CWmax TXOP(us) ACM\n", pEdcaParm->EdcaUpdateCount));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_BE %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[0],
+ pEdcaParm->Cwmin[0],
+ pEdcaParm->Cwmax[0],
+ pEdcaParm->Txop[0]<<5,
+ pEdcaParm->bACM[0]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_BK %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[1],
+ pEdcaParm->Cwmin[1],
+ pEdcaParm->Cwmax[1],
+ pEdcaParm->Txop[1]<<5,
+ pEdcaParm->bACM[1]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_VI %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[2],
+ pEdcaParm->Cwmin[2],
+ pEdcaParm->Cwmax[2],
+ pEdcaParm->Txop[2]<<5,
+ pEdcaParm->bACM[2]));
+ DBGPRINT(RT_DEBUG_TRACE,(" AC_VO %2d %2d %2d %4d %d\n",
+ pEdcaParm->Aifsn[3],
+ pEdcaParm->Cwmin[3],
+ pEdcaParm->Cwmax[3],
+ pEdcaParm->Txop[3]<<5,
+ pEdcaParm->bACM[3]));
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicSetSlotTime(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUseShortSlotTime)
+{
+ ULONG SlotTime;
+ UINT32 RegValue = 0;
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->CommonCfg.Channel > 14)
+ bUseShortSlotTime = TRUE;
+#endif // CONFIG_STA_SUPPORT //
+
+ if (bUseShortSlotTime)
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+ else
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED);
+
+ SlotTime = (bUseShortSlotTime)? 9 : 20;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // force using short SLOT time for FAE to demo performance when TxBurst is ON
+ if (pAd->CommonCfg.bEnableTxBurst)
+ SlotTime = 9;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ //
+ // For some reasons, always set it to short slot time.
+ //
+ // ToDo: Should consider capability with 11B
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->StaCfg.BssType == BSS_ADHOC)
+ SlotTime = 20;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_IO_READ32(pAd, BKOFF_SLOT_CFG, &RegValue);
+ RegValue = RegValue & 0xFFFFFF00;
+
+ RegValue |= SlotTime;
+
+ RTMP_IO_WRITE32(pAd, BKOFF_SLOT_CFG, RegValue);
+}
+
+/*
+ ========================================================================
+ Description:
+ Add Shared key information into ASIC.
+ Update shared key, TxMic and RxMic to Asic Shared key table
+ Update its cipherAlg to Asic Shared key Mode.
+
+ Return:
+ ========================================================================
+*/
+VOID AsicAddSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN PUCHAR pKey,
+ IN PUCHAR pTxMic,
+ IN PUCHAR pRxMic)
+{
+ ULONG offset; //, csr0;
+ SHAREDKEY_MODE_STRUC csr1;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicAddSharedKeyEntry BssIndex=%d, KeyIdx=%d\n", BssIndex,KeyIdx));
+//============================================================================================
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicAddSharedKeyEntry: %s key #%d\n", CipherName[CipherAlg], BssIndex*4 + KeyIdx));
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+ if (pRxMic)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+ if (pTxMic)
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ }
+//============================================================================================
+ //
+ // fill key material - key + TX MIC + RX MIC
+ //
+
+#ifdef RT2870
+{
+ offset = SHARED_KEY_TABLE_BASE + (4*BssIndex + KeyIdx)*HW_KEY_ENTRY_SIZE;
+ RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_SHARE_KEY);
+
+ offset += MAX_LEN_OF_SHARE_KEY;
+ if (pTxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+ }
+
+ offset += 8;
+ if (pRxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+ }
+}
+#endif // RT2870 //
+
+ //
+ // Update cipher algorithm. WSTA always use BSS0
+ //
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+ DBGPRINT(RT_DEBUG_TRACE,("Read: SHARED_KEY_MODE_BASE at this Bss[%d] KeyIdx[%d]= 0x%x \n", BssIndex,KeyIdx, csr1.word));
+ if ((BssIndex%2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss0Key3CipherAlg = CipherAlg;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss1Key3CipherAlg = CipherAlg;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID AsicRemoveSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx)
+{
+ //ULONG SecCsr0;
+ SHAREDKEY_MODE_STRUC csr1;
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicRemoveSharedKeyEntry: #%d \n", BssIndex*4 + KeyIdx));
+
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), &csr1.word);
+ if ((BssIndex%2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = 0;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = 0;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = 0;
+ else
+ csr1.field.Bss0Key3CipherAlg = 0;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = 0;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = 0;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = 0;
+ else
+ csr1.field.Bss1Key3CipherAlg = 0;
+ }
+ DBGPRINT(RT_DEBUG_TRACE,("Write: SHARED_KEY_MODE_BASE at this Bss[%d] = 0x%x \n", BssIndex, csr1.word));
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE+4*(BssIndex/2), csr1.word);
+ ASSERT(BssIndex < 4);
+ ASSERT(KeyIdx < 4);
+
+}
+
+
+VOID AsicUpdateWCIDAttribute(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR CipherAlg,
+ IN BOOLEAN bUsePairewiseKeyTable)
+{
+ ULONG WCIDAttri = 0, offset;
+
+ //
+ // Update WCID attribute.
+ // Only TxKey could update WCID attribute.
+ //
+ offset = MAC_WCID_ATTRIBUTE_BASE + (WCID * HW_WCID_ATTRI_SIZE);
+ WCIDAttri = (BssIndex << 4) | (CipherAlg << 1) | (bUsePairewiseKeyTable);
+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+VOID AsicUpdateWCIDIVEIV(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG uIV,
+ IN ULONG uEIV)
+{
+ ULONG offset;
+
+ offset = MAC_IVEIV_TABLE_BASE + (WCID * HW_IVEIV_ENTRY_SIZE);
+
+ RTMP_IO_WRITE32(pAd, offset, uIV);
+ RTMP_IO_WRITE32(pAd, offset + 4, uEIV);
+}
+
+VOID AsicUpdateRxWCIDTable(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN PUCHAR pAddr)
+{
+ ULONG offset;
+ ULONG Addr;
+
+ offset = MAC_WCID_BASE + (WCID * HW_WCID_ENTRY_SIZE);
+ Addr = pAddr[0] + (pAddr[1] << 8) +(pAddr[2] << 16) +(pAddr[3] << 24);
+ RTMP_IO_WRITE32(pAd, offset, Addr);
+ Addr = pAddr[4] + (pAddr[5] << 8);
+ RTMP_IO_WRITE32(pAd, offset + 4, Addr);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set Cipher Key, Cipher algorithm, IV/EIV to Asic
+
+ Arguments:
+ pAd Pointer to our adapter
+ WCID WCID Entry number.
+ BssIndex BSSID index, station or none multiple BSSID support
+ this value should be 0.
+ KeyIdx This KeyIdx will set to IV's KeyID if bTxKey enabled
+ pCipherKey Pointer to Cipher Key.
+ bUsePairewiseKeyTable TRUE means saved the key in SharedKey table,
+ otherwise PairewiseKey table
+ bTxKey This is the transmit key if enabled.
+
+ Return Value:
+ None
+
+ Note:
+ This routine will set the relative key stuff to Asic including WCID attribute,
+ Cipher Key, Cipher algorithm and IV/EIV.
+
+ IV/EIV will be update if this CipherKey is the transmission key because
+ ASIC will base on IV's KeyID value to select Cipher Key.
+
+ If bTxKey sets to FALSE, this is not the TX key, but it could be
+ RX key
+
+ For AP mode bTxKey must be always set to TRUE.
+ ========================================================================
+*/
+VOID AsicAddKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN PCIPHER_KEY pCipherKey,
+ IN BOOLEAN bUsePairewiseKeyTable,
+ IN BOOLEAN bTxKey)
+{
+ ULONG offset;
+// ULONG WCIDAttri = 0;
+ UCHAR IV4 = 0;
+ PUCHAR pKey = pCipherKey->Key;
+// ULONG KeyLen = pCipherKey->KeyLen;
+ PUCHAR pTxMic = pCipherKey->TxMic;
+ PUCHAR pRxMic = pCipherKey->RxMic;
+ PUCHAR pTxtsc = pCipherKey->TxTsc;
+ UCHAR CipherAlg = pCipherKey->CipherAlg;
+ SHAREDKEY_MODE_STRUC csr1;
+
+// ASSERT(KeyLen <= MAX_LEN_OF_PEER_KEY);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> AsicAddKeyEntry\n"));
+ //
+ // 1.) decide key table offset
+ //
+ if (bUsePairewiseKeyTable)
+ offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+ else
+ offset = SHARED_KEY_TABLE_BASE + (4 * BssIndex + KeyIdx) * HW_KEY_ENTRY_SIZE;
+
+ //
+ // 2.) Set Key to Asic
+ //
+ //for (i = 0; i < KeyLen; i++)
+
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, pKey, MAX_LEN_OF_PEER_KEY);
+ offset += MAX_LEN_OF_PEER_KEY;
+
+ //
+ // 3.) Set MIC key if available
+ //
+ if (pTxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pTxMic, 8);
+ }
+ offset += LEN_TKIP_TXMICK;
+
+ if (pRxMic)
+ {
+ RTUSBMultiWrite(pAd, offset, pRxMic, 8);
+ }
+#endif // RT2870 //
+
+ //
+ // 4.) Modify IV/EIV if needs
+ // This will force Asic to use this key ID by setting IV.
+ //
+ if (bTxKey)
+ {
+
+#ifdef RT2870
+ UINT32 tmpVal;
+
+ //
+ // Write IV
+ //
+ IV4 = (KeyIdx << 6);
+ if ((CipherAlg == CIPHER_TKIP) || (CipherAlg == CIPHER_TKIP_NO_MIC) ||(CipherAlg == CIPHER_AES))
+ IV4 |= 0x20; // turn on extension bit means EIV existence
+
+ tmpVal = pTxtsc[1] + (((pTxtsc[1] | 0x20) & 0x7f) << 8) + (pTxtsc[0] << 16) + (IV4 << 24);
+ RTMP_IO_WRITE32(pAd, offset, tmpVal);
+
+ //
+ // Write EIV
+ //
+ offset += 4;
+ RTMP_IO_WRITE32(pAd, offset, *(PUINT32)&pCipherKey->TxTsc[2]);
+#endif // RT2870 //
+ AsicUpdateWCIDAttribute(pAd, WCID, BssIndex, CipherAlg, bUsePairewiseKeyTable);
+ }
+
+ if (!bUsePairewiseKeyTable)
+ {
+ //
+ // Only update the shared key security mode
+ //
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), &csr1.word);
+ if ((BssIndex % 2) == 0)
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss0Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss0Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss0Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss0Key3CipherAlg = CipherAlg;
+ }
+ else
+ {
+ if (KeyIdx == 0)
+ csr1.field.Bss1Key0CipherAlg = CipherAlg;
+ else if (KeyIdx == 1)
+ csr1.field.Bss1Key1CipherAlg = CipherAlg;
+ else if (KeyIdx == 2)
+ csr1.field.Bss1Key2CipherAlg = CipherAlg;
+ else
+ csr1.field.Bss1Key3CipherAlg = CipherAlg;
+ }
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4 * (BssIndex / 2), csr1.word);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<== AsicAddKeyEntry\n"));
+}
+
+
+/*
+ ========================================================================
+ Description:
+ Add Pair-wise key material into ASIC.
+ Update pairwise key, TxMic and RxMic to Asic Pair-wise key table
+
+ Return:
+ ========================================================================
+*/
+VOID AsicAddPairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR WCID,
+ IN CIPHER_KEY *pCipherKey)
+{
+ INT i;
+ ULONG offset;
+ PUCHAR pKey = pCipherKey->Key;
+ PUCHAR pTxMic = pCipherKey->TxMic;
+ PUCHAR pRxMic = pCipherKey->RxMic;
+#ifdef DBG
+ UCHAR CipherAlg = pCipherKey->CipherAlg;
+#endif // DBG //
+
+ // EKEY
+ offset = PAIRWISE_KEY_TABLE_BASE + (WCID * HW_KEY_ENTRY_SIZE);
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->Key[0], MAX_LEN_OF_PEER_KEY);
+#endif // RT2870 //
+ for (i=0; i<MAX_LEN_OF_PEER_KEY; i+=4)
+ {
+ UINT32 Value;
+ RTMP_IO_READ32(pAd, offset + i, &Value);
+ }
+
+ offset += MAX_LEN_OF_PEER_KEY;
+
+ // MIC KEY
+ if (pTxMic)
+ {
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->TxMic[0], 8);
+#endif // RT2870 //
+ }
+ offset += 8;
+ if (pRxMic)
+ {
+#ifdef RT2870
+ RTUSBMultiWrite(pAd, offset, &pCipherKey->RxMic[0], 8);
+#endif // RT2870 //
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicAddPairwiseKeyEntry: WCID #%d Alg=%s\n",WCID, CipherName[CipherAlg]));
+ DBGPRINT(RT_DEBUG_TRACE,(" Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pKey[0],pKey[1],pKey[2],pKey[3],pKey[4],pKey[5],pKey[6],pKey[7],pKey[8],pKey[9],pKey[10],pKey[11],pKey[12],pKey[13],pKey[14],pKey[15]));
+ if (pRxMic)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" Rx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pRxMic[0],pRxMic[1],pRxMic[2],pRxMic[3],pRxMic[4],pRxMic[5],pRxMic[6],pRxMic[7]));
+ }
+ if (pTxMic)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" Tx MIC Key = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pTxMic[0],pTxMic[1],pTxMic[2],pTxMic[3],pTxMic[4],pTxMic[5],pTxMic[6],pTxMic[7]));
+ }
+}
+/*
+ ========================================================================
+ Description:
+ Remove Pair-wise key material from ASIC.
+
+ Return:
+ ========================================================================
+*/
+VOID AsicRemovePairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR Wcid)
+{
+ ULONG WCIDAttri;
+ USHORT offset;
+
+ // re-set the entry's WCID attribute as OPEN-NONE.
+ offset = MAC_WCID_ATTRIBUTE_BASE + (Wcid * HW_WCID_ATTRI_SIZE);
+ WCIDAttri = (BssIdx<<4) | PAIRWISEKEYTABLE;
+ RTMP_IO_WRITE32(pAd, offset, WCIDAttri);
+}
+
+BOOLEAN AsicSendCommandToMcu(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1)
+{
+ HOST_CMD_CSR_STRUC H2MCmd;
+ H2M_MAILBOX_STRUC H2MMailbox;
+ ULONG i = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, H2M_MAILBOX_CSR, &H2MMailbox.word);
+ if (H2MMailbox.field.Owner == 0)
+ break;
+
+ RTMPusecDelay(2);
+ } while(i++ < 100);
+
+ if (i >= 100)
+ {
+ {
+ DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n"));
+ }
+ return FALSE;
+ }
+
+
+ H2MMailbox.field.Owner = 1; // pass ownership to MCU
+ H2MMailbox.field.CmdToken = Token;
+ H2MMailbox.field.HighByte = Arg1;
+ H2MMailbox.field.LowByte = Arg0;
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, H2MMailbox.word);
+
+ H2MCmd.word = 0;
+ H2MCmd.field.HostCommand = Command;
+ RTMP_IO_WRITE32(pAd, HOST_CMD_CSR, H2MCmd.word);
+
+ if (Command != 0x80)
+ {
+ }
+
+ return TRUE;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Verify the support rate for different PHY type
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPCheckRates(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT UCHAR SupRate[],
+ IN OUT UCHAR *SupRateLen)
+{
+ UCHAR RateIdx, i, j;
+ UCHAR NewRate[12], NewRateLen;
+
+ NewRateLen = 0;
+
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ RateIdx = 4;
+ else
+ RateIdx = 12;
+
+ // Check for support rates exclude basic rate bit
+ for (i = 0; i < *SupRateLen; i++)
+ for (j = 0; j < RateIdx; j++)
+ if ((SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ NewRate[NewRateLen++] = SupRate[i];
+
+ *SupRateLen = NewRateLen;
+ NdisMoveMemory(SupRate, NewRate, NewRateLen);
+}
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef DOT11_N_SUPPORT
+BOOLEAN RTMPCheckChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CentralChannel,
+ IN UCHAR Channel)
+{
+ UCHAR k;
+ UCHAR UpperChannel = 0, LowerChannel = 0;
+ UCHAR NoEffectChannelinList = 0;
+
+ // Find upper and lower channel according to 40MHz current operation.
+ if (CentralChannel < Channel)
+ {
+ UpperChannel = Channel;
+ if (CentralChannel > 2)
+ LowerChannel = CentralChannel - 2;
+ else
+ return FALSE;
+ }
+ else if (CentralChannel > Channel)
+ {
+ UpperChannel = CentralChannel + 2;
+ LowerChannel = Channel;
+ }
+
+ for (k = 0;k < pAd->ChannelListNum;k++)
+ {
+ if (pAd->ChannelList[k].Channel == UpperChannel)
+ {
+ NoEffectChannelinList ++;
+ }
+ if (pAd->ChannelList[k].Channel == LowerChannel)
+ {
+ NoEffectChannelinList ++;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("Total Channel in Channel List = [%d]\n", NoEffectChannelinList));
+ if (NoEffectChannelinList == 2)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Verify the support rate for HT phy type
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ FALSE if pAd->CommonCfg.SupportedHtPhy doesn't accept the pHtCapability. (AP Mode)
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+BOOLEAN RTMPCheckHt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo)
+{
+ if (Wcid >= MAX_LEN_OF_MAC_TABLE)
+ return FALSE;
+
+ // If use AMSDU, set flag.
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_AMSDU_INUSED);
+ // Save Peer Capability
+ if (pHtCapability->HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pHtCapability->HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pHtCapability->HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pHtCapability->HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+ {
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[Wcid], fCLIENT_STATUS_RDG_CAPABLE);
+ }
+
+ if (Wcid < MAX_LEN_OF_MAC_TABLE)
+ {
+ pAd->MacTab.Content[Wcid].MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+ }
+
+ // Will check ChannelWidth for MCSSet[4] below
+ pAd->MlmeAux.HtCapability.MCSSet[4] = 0x1;
+ switch (pAd->CommonCfg.RxStream)
+ {
+ case 1:
+ pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[1] = 0x00;
+ pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+ pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+ break;
+ case 2:
+ pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[2] = 0x00;
+ pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+ break;
+ case 3:
+ pAd->MlmeAux.HtCapability.MCSSet[0] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[1] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[2] = 0xff;
+ pAd->MlmeAux.HtCapability.MCSSet[3] = 0x00;
+ break;
+ }
+
+ pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth = pAddHtInfo->AddHtInfo.RecomWidth & pAd->CommonCfg.DesiredHtPhy.ChannelWidth;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPCheckHt:: HtCapInfo.ChannelWidth=%d, RecomWidth=%d, DesiredHtPhy.ChannelWidth=%d, BW40MAvailForA/G=%d/%d, PhyMode=%d \n",
+ pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth, pAddHtInfo->AddHtInfo.RecomWidth, pAd->CommonCfg.DesiredHtPhy.ChannelWidth,
+ pAd->NicConfig2.field.BW40MAvailForA, pAd->NicConfig2.field.BW40MAvailForG, pAd->CommonCfg.PhyMode));
+
+ pAd->MlmeAux.HtCapability.HtCapInfo.GF = pHtCapability->HtCapInfo.GF &pAd->CommonCfg.DesiredHtPhy.GF;
+
+ // Send Assoc Req with my HT capability.
+ pAd->MlmeAux.HtCapability.HtCapInfo.AMsduSize = pAd->CommonCfg.DesiredHtPhy.AmsduSize;
+ pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs = pAd->CommonCfg.DesiredHtPhy.MimoPs;
+ pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor20) & (pHtCapability->HtCapInfo.ShortGIfor20);
+ pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40 = (pAd->CommonCfg.DesiredHtPhy.ShortGIfor40) & (pHtCapability->HtCapInfo.ShortGIfor40);
+ pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC = (pAd->CommonCfg.DesiredHtPhy.TxSTBC)&(pHtCapability->HtCapInfo.RxSTBC);
+ pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC = (pAd->CommonCfg.DesiredHtPhy.RxSTBC)&(pHtCapability->HtCapInfo.TxSTBC);
+ pAd->MlmeAux.HtCapability.HtCapParm.MaxRAmpduFactor = pAd->CommonCfg.DesiredHtPhy.MaxRAmpduFactor;
+ pAd->MlmeAux.HtCapability.HtCapParm.MpduDensity = pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity;
+ pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
+ pAd->MacTab.Content[Wcid].HTCapability.ExtHtCapInfo.PlusHTC = pHtCapability->ExtHtCapInfo.PlusHTC;
+ if (pAd->CommonCfg.bRdg)
+ {
+ pAd->MlmeAux.HtCapability.ExtHtCapInfo.RDGSupport = pHtCapability->ExtHtCapInfo.RDGSupport;
+ pAd->MlmeAux.HtCapability.ExtHtCapInfo.PlusHTC = 1;
+ }
+
+ if (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_20)
+ pAd->MlmeAux.HtCapability.MCSSet[4] = 0x0; // BW20 can't transmit MCS32
+
+ COPY_AP_HTSETTINGS_FROM_BEACON(pAd, pHtCapability);
+ return TRUE;
+}
+#endif // DOT11_N_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Verify the support rate for different PHY type
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPUpdateMlmeRate(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR MinimumRate;
+ UCHAR ProperMlmeRate; //= RATE_54;
+ UCHAR i, j, RateIdx = 12; //1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+ BOOLEAN bMatch = FALSE;
+
+ switch (pAd->CommonCfg.PhyMode)
+ {
+ case PHY_11B:
+ ProperMlmeRate = RATE_11;
+ MinimumRate = RATE_1;
+ break;
+ case PHY_11BG_MIXED:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11ABGN_MIXED:
+ case PHY_11BGN_MIXED:
+#endif // DOT11_N_SUPPORT //
+ if ((pAd->MlmeAux.SupRateLen == 4) &&
+ (pAd->MlmeAux.ExtRateLen == 0))
+ // B only AP
+ ProperMlmeRate = RATE_11;
+ else
+ ProperMlmeRate = RATE_24;
+
+ if (pAd->MlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ break;
+ case PHY_11A:
+#ifdef DOT11_N_SUPPORT
+ case PHY_11N_2_4G: // rt2860 need to check mlmerate for 802.11n
+ case PHY_11GN_MIXED:
+ case PHY_11AGN_MIXED:
+ case PHY_11AN_MIXED:
+ case PHY_11N_5G:
+#endif // DOT11_N_SUPPORT //
+ ProperMlmeRate = RATE_24;
+ MinimumRate = RATE_6;
+ break;
+ case PHY_11ABG_MIXED:
+ ProperMlmeRate = RATE_24;
+ if (pAd->MlmeAux.Channel <= 14)
+ MinimumRate = RATE_1;
+ else
+ MinimumRate = RATE_6;
+ break;
+ default: // error
+ ProperMlmeRate = RATE_1;
+ MinimumRate = RATE_1;
+ break;
+ }
+
+ for (i = 0; i < pAd->MlmeAux.SupRateLen; i++)
+ {
+ for (j = 0; j < RateIdx; j++)
+ {
+ if ((pAd->MlmeAux.SupRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ {
+ if (j == ProperMlmeRate)
+ {
+ bMatch = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (bMatch)
+ break;
+ }
+
+ if (bMatch == FALSE)
+ {
+ for (i = 0; i < pAd->MlmeAux.ExtRateLen; i++)
+ {
+ for (j = 0; j < RateIdx; j++)
+ {
+ if ((pAd->MlmeAux.ExtRate[i] & 0x7f) == RateIdTo500Kbps[j])
+ {
+ if (j == ProperMlmeRate)
+ {
+ bMatch = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (bMatch)
+ break;
+ }
+ }
+
+ if (bMatch == FALSE)
+ {
+ ProperMlmeRate = MinimumRate;
+ }
+
+ pAd->CommonCfg.MlmeRate = MinimumRate;
+ pAd->CommonCfg.RtsRate = ProperMlmeRate;
+ if (pAd->CommonCfg.MlmeRate >= RATE_6)
+ {
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ }
+ else
+ {
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_CCK;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = pAd->CommonCfg.MlmeRate;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_CCK;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = pAd->CommonCfg.MlmeRate;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateMlmeRate ==> MlmeTransmit = 0x%x \n" , pAd->CommonCfg.MlmeTransmit.word));
+}
+
+CHAR RTMPMaxRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2)
+{
+ CHAR larger = -127;
+
+ if ((pAd->Antenna.field.RxPath == 1) && (Rssi0 != 0))
+ {
+ larger = Rssi0;
+ }
+
+ if ((pAd->Antenna.field.RxPath >= 2) && (Rssi1 != 0))
+ {
+ larger = max(Rssi0, Rssi1);
+ }
+
+ if ((pAd->Antenna.field.RxPath == 3) && (Rssi2 != 0))
+ {
+ larger = max(larger, Rssi2);
+ }
+
+ if (larger == -127)
+ larger = 0;
+
+ return larger;
+}
+
+
+// Antenna divesity use GPIO3 and EESK pin for control
+// Antenna and EEPROM access are both using EESK pin,
+// Therefor we should avoid accessing EESK at the same time
+// Then restore antenna after EEPROM access
+VOID AsicSetRxAnt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ant)
+{
+#ifdef RT30xx
+ UINT32 Value;
+ UINT32 x;
+
+ if ((pAd->EepromAccess) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ return;
+ }
+
+ // the antenna selection is through firmware and MAC register(GPIO3)
+ if (Ant == 0)
+ {
+ // Main antenna
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x |= (EESK);
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+ Value &= ~(0x0808);
+ RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to main antenna\n"));
+ }
+ else
+ {
+ // Aux antenna
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &x);
+ x &= ~(EESK);
+ RTMP_IO_WRITE32(pAd, E2PROM_CSR, x);
+
+ RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &Value);
+ Value &= ~(0x0808);
+ Value |= 0x08;
+ RTMP_IO_WRITE32(pAd, GPIO_CTRL_CFG, Value);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicSetRxAnt, switch to aux antenna\n"));
+ }
+#endif // RT30xx //
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ Periodic evaluate antenna link status
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID AsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BBPR3 = 0;
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_NIC_NOT_EXIST |
+ fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS) ||
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
+ || (pAd->EepromAccess)
+#endif // RT30xx //
+ )
+ return;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //if (pAd->StaCfg.Psm == PWR_SAVE)
+ // return;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // two antenna selection mechanism- one is antenna diversity, the other is failed antenna remove
+ // one is antenna diversity:there is only one antenna can rx and tx
+ // the other is failed antenna remove:two physical antenna can rx and tx
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AntDiv - before evaluate Pair1-Ant (%d,%d)\n",
+ pAd->RxAnt.Pair1PrimaryRxAnt, pAd->RxAnt.Pair1SecondaryRxAnt));
+
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1SecondaryRxAnt);
+
+ pAd->RxAnt.EvaluatePeriod = 1; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
+ pAd->RxAnt.FirstPktArrivedWhenEvaluate = FALSE;
+ pAd->RxAnt.RcvPktNumWhenEvaluate = 0;
+
+ // a one-shot timer to end the evalution
+ // dynamic adjust antenna evaluation period according to the traffic
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 100);
+ else
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
+ }
+ else
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->StaCfg.Psm == PWR_SAVE)
+ return;
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+ BBPR3 &= (~0x18);
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ BBPR3 |= (0x10);
+ }
+ else if(pAd->Antenna.field.RxPath == 2)
+ {
+ BBPR3 |= (0x8);
+ }
+ else if(pAd->Antenna.field.RxPath == 1)
+ {
+ BBPR3 |= (0x0);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ {
+ ULONG TxTotalCnt = pAd->RalinkCounters.OneSecTxNoRetryOkCount +
+ pAd->RalinkCounters.OneSecTxRetryOkCount +
+ pAd->RalinkCounters.OneSecTxFailCount;
+
+ // dynamic adjust antenna evaluation period according to the traffic
+ if (TxTotalCnt > 50)
+ {
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 20);
+ pAd->Mlme.bLowThroughput = FALSE;
+ }
+ else
+ {
+ RTMPSetTimer(&pAd->Mlme.RxAntEvalTimer, 300);
+ pAd->Mlme.bLowThroughput = TRUE;
+ }
+ }
+ }
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ After evaluation, check antenna link status
+
+ Arguments:
+ pAd - Adapter pointer
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID AsicRxAntEvalTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR BBPR3 = 0;
+ CHAR larger = -127, rssi0, rssi1, rssi2;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+ OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)
+#ifdef RT30xx
+ || (pAd->EepromAccess)
+#endif // RT30xx //
+ )
+ return;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //if (pAd->StaCfg.Psm == PWR_SAVE)
+ // return;
+
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ if ((pAd->RxAnt.RcvPktNumWhenEvaluate != 0) && (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >= pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1PrimaryRxAnt]))
+ {
+ UCHAR temp;
+
+ //
+ // select PrimaryRxAntPair
+ // Role change, Used Pair1SecondaryRxAnt as PrimaryRxAntPair.
+ // Since Pair1SecondaryRxAnt Quality good than Pair1PrimaryRxAnt
+ //
+ temp = pAd->RxAnt.Pair1PrimaryRxAnt;
+ pAd->RxAnt.Pair1PrimaryRxAnt = pAd->RxAnt.Pair1SecondaryRxAnt;
+ pAd->RxAnt.Pair1SecondaryRxAnt = temp;
+
+ pAd->RxAnt.Pair1LastAvgRssi = (pAd->RxAnt.Pair1AvgRssi[pAd->RxAnt.Pair1SecondaryRxAnt] >> 3);
+ pAd->RxAnt.EvaluateStableCnt = 0;
+ }
+ else
+ {
+ // if the evaluated antenna is not better than original, switch back to original antenna
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+ pAd->RxAnt.EvaluateStableCnt ++;
+ }
+
+ pAd->RxAnt.EvaluatePeriod = 0; // 1:Means switch to SecondaryRxAnt, 0:Means switch to Pair1PrimaryRxAnt
+
+ DBGPRINT(RT_DEBUG_TRACE,("AsicRxAntEvalAction::After Eval(fix in #%d), <%d, %d>, RcvPktNumWhenEvaluate=%ld\n",
+ pAd->RxAnt.Pair1PrimaryRxAnt, (pAd->RxAnt.Pair1AvgRssi[0] >> 3), (pAd->RxAnt.Pair1AvgRssi[1] >> 3), pAd->RxAnt.RcvPktNumWhenEvaluate));
+ }
+ else
+ {
+ if (pAd->StaCfg.Psm == PWR_SAVE)
+ return;
+
+ // if the traffic is low, use average rssi as the criteria
+ if (pAd->Mlme.bLowThroughput == TRUE)
+ {
+ rssi0 = pAd->StaCfg.RssiSample.LastRssi0;
+ rssi1 = pAd->StaCfg.RssiSample.LastRssi1;
+ rssi2 = pAd->StaCfg.RssiSample.LastRssi2;
+ }
+ else
+ {
+ rssi0 = pAd->StaCfg.RssiSample.AvgRssi0;
+ rssi1 = pAd->StaCfg.RssiSample.AvgRssi1;
+ rssi2 = pAd->StaCfg.RssiSample.AvgRssi2;
+ }
+
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ larger = max(rssi0, rssi1);
+
+ if (larger > (rssi2 + 20))
+ pAd->Mlme.RealRxPath = 2;
+ else
+ pAd->Mlme.RealRxPath = 3;
+ }
+ else if(pAd->Antenna.field.RxPath == 2)
+ {
+ if (rssi0 > (rssi1 + 20))
+ pAd->Mlme.RealRxPath = 1;
+ else
+ pAd->Mlme.RealRxPath = 2;
+ }
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+ BBPR3 &= (~0x18);
+ if(pAd->Mlme.RealRxPath == 3)
+ {
+ BBPR3 |= (0x10);
+ }
+ else if(pAd->Mlme.RealRxPath == 2)
+ {
+ BBPR3 |= (0x8);
+ }
+ else if(pAd->Mlme.RealRxPath == 1)
+ {
+ BBPR3 |= (0x0);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+ }
+ }
+
+#endif // CONFIG_STA_SUPPORT //
+
+}
+
+
+
+VOID APSDPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ return;
+
+ pAd->CommonCfg.TriggerTimerCount++;
+
+// Driver should not send trigger frame, it should be send by application layer
+/*
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable
+ && (pAd->CommonCfg.bNeedSendTriggerFrame ||
+ (((pAd->CommonCfg.TriggerTimerCount%20) == 19) && (!pAd->CommonCfg.bAPSDAC_BE || !pAd->CommonCfg.bAPSDAC_BK || !pAd->CommonCfg.bAPSDAC_VI || !pAd->CommonCfg.bAPSDAC_VO))))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Sending trigger frame and enter service period when support APSD\n"));
+ RTMPSendNullFrame(pAd, pAd->CommonCfg.TxRate, TRUE);
+ pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+ pAd->CommonCfg.TriggerTimerCount = 0;
+ pAd->CommonCfg.bInServicePeriod = TRUE;
+ }*/
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Set/reset MAC registers according to bPiggyBack parameter
+
+ Arguments:
+ pAd - Adapter pointer
+ bPiggyBack - Enable / Disable Piggy-Back
+
+ Return Value:
+ None
+
+ ========================================================================
+*/
+VOID RTMPSetPiggyBack(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bPiggyBack)
+{
+ TX_LINK_CFG_STRUC TxLinkCfg;
+
+ RTMP_IO_READ32(pAd, TX_LINK_CFG, &TxLinkCfg.word);
+
+ TxLinkCfg.field.TxCFAckEn = bPiggyBack;
+ RTMP_IO_WRITE32(pAd, TX_LINK_CFG, TxLinkCfg.word);
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ check if this entry need to switch rate automatically
+
+ Arguments:
+ pAd
+ pEntry
+
+ Return Value:
+ TURE
+ FALSE
+
+ ========================================================================
+*/
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ BOOLEAN result = TRUE;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // only associated STA counts
+ if (pEntry && (pEntry->ValidAsCLI) && (pEntry->Sst == SST_ASSOC))
+ {
+ result = pAd->StaCfg.bAutoTxRateSwitch;
+ }
+ else
+ result = FALSE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+ return result;
+}
+
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+ IN PRTMP_ADAPTER pAd)
+{
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->StaCfg.bAutoTxRateSwitch)
+ return TRUE;
+ }
+#endif // CONFIG_STA_SUPPORT //
+ return FALSE;
+}
+
+
+/*
+ ========================================================================
+ Routine Description:
+ check if this entry need to fix tx legacy rate
+
+ Arguments:
+ pAd
+ pEntry
+
+ Return Value:
+ TURE
+ FALSE
+
+ ========================================================================
+*/
+UCHAR RTMPStaFixedTxMode(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry)
+{
+ UCHAR tx_mode = FIXED_TXMODE_HT;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ tx_mode = (UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return tx_mode;
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Overwrite HT Tx Mode by Fixed Legency Tx Mode, if specified.
+
+ Arguments:
+ pAd
+ pEntry
+
+ Return Value:
+ TURE
+ FALSE
+
+ ========================================================================
+*/
+VOID RTMPUpdateLegacyTxSetting(
+ UCHAR fixed_tx_mode,
+ PMAC_TABLE_ENTRY pEntry)
+{
+ HTTRANSMIT_SETTING TransmitSetting;
+
+ if (fixed_tx_mode == FIXED_TXMODE_HT)
+ return;
+
+ TransmitSetting.word = 0;
+
+ TransmitSetting.field.MODE = pEntry->HTPhyMode.field.MODE;
+ TransmitSetting.field.MCS = pEntry->HTPhyMode.field.MCS;
+
+ if (fixed_tx_mode == FIXED_TXMODE_CCK)
+ {
+ TransmitSetting.field.MODE = MODE_CCK;
+ // CCK mode allow MCS 0~3
+ if (TransmitSetting.field.MCS > MCS_3)
+ TransmitSetting.field.MCS = MCS_3;
+ }
+ else
+ {
+ TransmitSetting.field.MODE = MODE_OFDM;
+ // OFDM mode allow MCS 0~7
+ if (TransmitSetting.field.MCS > MCS_7)
+ TransmitSetting.field.MCS = MCS_7;
+ }
+
+ if (pEntry->HTPhyMode.field.MODE >= TransmitSetting.field.MODE)
+ {
+ pEntry->HTPhyMode.word = TransmitSetting.word;
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPUpdateLegacyTxSetting : wcid-%d, MODE=%s, MCS=%d \n",
+ pEntry->Aid, GetPhyMode(pEntry->HTPhyMode.field.MODE), pEntry->HTPhyMode.field.MCS));
+ }
+}
+
+#ifdef CONFIG_STA_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ dynamic tune BBP R66 to find a balance between sensibility and
+ noise isolation
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AsicStaBbpTuning(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR OrigR66Value = 0, R66;//, R66UpperBound = 0x30, R66LowerBound = 0x30;
+ CHAR Rssi;
+
+ // 2860C did not support Fase CCA, therefore can't tune
+ if (pAd->MACVersion == 0x28600100)
+ return;
+
+ //
+ // work as a STA
+ //
+ if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) // no R66 tuning when SCANNING
+ return;
+
+ if ((pAd->OpMode == OPMODE_STA)
+ && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ && !(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ )
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &OrigR66Value);
+ R66 = OrigR66Value;
+
+ if (pAd->Antenna.field.RxPath > 1)
+ Rssi = (pAd->StaCfg.RssiSample.AvgRssi0 + pAd->StaCfg.RssiSample.AvgRssi1) >> 1;
+ else
+ Rssi = pAd->StaCfg.RssiSample.AvgRssi0;
+
+ if (pAd->LatchRfRegs.Channel <= 14)
+ { //BG band
+#ifdef RT30xx
+ // RT3070 is a no LNA solution, it should have different control regarding to AGC gain control
+ // Otherwise, it will have some throughput side effect when low RSSI
+ if (IS_RT30xx(pAd))
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = 0x1C + 2*GET_LNA_GAIN(pAd) + 0x20;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x1C + 2*GET_LNA_GAIN(pAd);
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+ else
+#endif // RT30xx //
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = (0x2E + GET_LNA_GAIN(pAd)) + 0x10;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x2E + GET_LNA_GAIN(pAd);
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+
+ }
+ else
+ { //A band
+ if (pAd->CommonCfg.BBPCurrentBW == BW_20)
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x32 + (GET_LNA_GAIN(pAd)*5)/3;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+ else
+ {
+ if (Rssi > RSSI_FOR_MID_LOW_SENSIBILITY)
+ {
+ R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3 + 0x10;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ else
+ {
+ R66 = 0x3A + (GET_LNA_GAIN(pAd)*5)/3;
+ if (OrigR66Value != R66)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+ }
+ }
+
+
+ }
+}
+#endif // CONFIG_STA_SUPPORT //
+
+VOID RTMPSetAGCInitValue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BandWidth)
+{
+ UCHAR R66 = 0x30;
+
+ if (pAd->LatchRfRegs.Channel <= 14)
+ { // BG band
+ R66 = 0x2E + GET_LNA_GAIN(pAd);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+ { //A band
+ if (BandWidth == BW_20)
+ {
+ R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+#ifdef DOT11_N_SUPPORT
+ else
+ {
+ R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+#endif // DOT11_N_SUPPORT //
+ }
+
+}
+
+VOID AsicTurnOffRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ // RF R2 bit 18 = 0
+ UINT32 R1 = 0, R2 = 0, R3 = 0;
+ UCHAR index;
+ RTMP_RF_REGS *RFRegTable;
+
+#ifdef RT30xx
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ if (IS_RT3090(pAd))
+ {
+ RT30xxLoadRFSleepModeSetup(pAd); // add by johnli, RF power sequence setup, load RF sleep-mode setup
+ }
+ else
+ {
+#endif // RT30xx //
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R1 = RFRegTable[index].R1 & 0xffffdfff;
+ R2 = RFRegTable[index].R2 & 0xfffbffff;
+ R3 = RFRegTable[index].R3 & 0xfff3ffff;
+
+ RTMP_RF_IO_WRITE32(pAd, R1);
+ RTMP_RF_IO_WRITE32(pAd, R2);
+
+ // Program R1b13 to 1, R3/b18,19 to 0, R2b18 to 0.
+ // Set RF R2 bit18=0, R3 bit[18:19]=0
+ //if (pAd->StaCfg.bRadio == FALSE)
+ if (1)
+ {
+ RTMP_RF_IO_WRITE32(pAd, R3);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x, R3 = 0x%08x \n",
+ Channel, pAd->RfIcType, R2, R3));
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("AsicTurnOffRFClk#%d(RF=%d, ) , R2=0x%08x \n",
+ Channel, pAd->RfIcType, R2));
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+#ifdef RT30xx
+ }
+#endif // RT30xx //
+
+}
+
+
+VOID AsicTurnOnRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel)
+{
+ // RF R2 bit 18 = 0
+ UINT32 R1 = 0, R2 = 0, R3 = 0;
+ UCHAR index;
+ RTMP_RF_REGS *RFRegTable;
+
+#ifdef RT30xx
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ if (IS_RT3090(pAd))
+ {
+ }
+ else
+ {
+#endif // RT30xx //
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R3 = pAd->LatchRfRegs.R3;
+ R3 &= 0xfff3ffff;
+ R3 |= 0x00080000;
+ RTMP_RF_IO_WRITE32(pAd, R3);
+
+ R1 = RFRegTable[index].R1;
+ RTMP_RF_IO_WRITE32(pAd, R1);
+
+ R2 = RFRegTable[index].R2;
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
+ }
+
+ if (pAd->Antenna.field.RxPath == 2)
+ {
+ R2 |= 0x40; // write 1 to off Rxpath.
+ }
+ else if (pAd->Antenna.field.RxPath == 1)
+ {
+ R2 |= 0x20040; // write 1 to off RxPath
+ }
+ RTMP_RF_IO_WRITE32(pAd, R2);
+
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+#ifdef RT30xx
+ }
+#endif // RT30xx //
+
+}
+
diff --git a/drivers/staging/rt3070/common/netif_block.c b/drivers/staging/rt3070/common/netif_block.c
new file mode 100644
index 00000000000..4773c11bedd
--- /dev/null
+++ b/drivers/staging/rt3070/common/netif_block.c
@@ -0,0 +1,136 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "../rt_config.h"
+#include "netif_block.h"
+
+static NETIF_ENTRY freeNetIfEntryPool[FREE_NETIF_POOL_SIZE];
+static LIST_HEADER freeNetIfEntryList;
+
+void initblockQueueTab(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+
+ initList(&freeNetIfEntryList);
+ for (i = 0; i < FREE_NETIF_POOL_SIZE; i++)
+ insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)&freeNetIfEntryPool[i]);
+
+ for (i=0; i < NUM_OF_TX_RING; i++)
+ initList(&pAd->blockQueueTab[i].NetIfList);
+
+ return;
+}
+
+BOOLEAN blockNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+ IN PNET_DEV pNetDev)
+{
+ PNETIF_ENTRY pNetIfEntry = NULL;
+
+ if ((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(&freeNetIfEntryList)) != NULL)
+ {
+ netif_stop_queue(pNetDev);
+ pNetIfEntry->pNetDev = pNetDev;
+ insertTailList(&pBlockQueueEntry->NetIfList, (PLIST_ENTRY)pNetIfEntry);
+
+ pBlockQueueEntry->SwTxQueueBlockFlag = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("netif_stop_queue(%s)\n", pNetDev->name));
+ }
+ else
+ return FALSE;
+
+ return TRUE;
+}
+
+VOID releaseNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry)
+{
+ PNETIF_ENTRY pNetIfEntry = NULL;
+ PLIST_HEADER pNetIfList = &pBlockQueueEntry->NetIfList;
+
+ while((pNetIfEntry = (PNETIF_ENTRY)removeHeadList(pNetIfList)) != NULL)
+ {
+ PNET_DEV pNetDev = pNetIfEntry->pNetDev;
+ netif_wake_queue(pNetDev);
+ insertTailList(&freeNetIfEntryList, (PLIST_ENTRY)pNetIfEntry);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("netif_wake_queue(%s)\n", pNetDev->name));
+ }
+ pBlockQueueEntry->SwTxQueueBlockFlag = FALSE;
+ return;
+}
+
+
+VOID StopNetIfQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket)
+{
+ PNET_DEV NetDev = NULL;
+ UCHAR IfIdx = 0;
+ BOOLEAN valid = FALSE;
+
+#ifdef WDS_SUPPORT
+ if (RTMP_GET_PACKET_NET_DEVICE(pPacket) >= MIN_NET_DEVICE_FOR_WDS)
+ {
+ IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_WDS) % MAX_WDS_ENTRY;
+ NetDev = pAd->WdsTab.WdsEntry[IfIdx].dev;
+ }
+ else
+#endif // WDS_SUPPORT //
+ {
+#ifdef MBSS_SUPPORT
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ IfIdx = (RTMP_GET_PACKET_NET_DEVICE(pPacket) - MIN_NET_DEVICE_FOR_MBSSID) % MAX_MBSSID_NUM;
+ NetDev = pAd->ApCfg.MBSSID[IfIdx].MSSIDDev;
+ }
+ else
+ {
+ IfIdx = MAIN_MBSSID;
+ NetDev = pAd->net_dev;
+ }
+#else
+ IfIdx = MAIN_MBSSID;
+ NetDev = pAd->net_dev;
+#endif
+ }
+
+ // WMM support 4 software queues.
+ // One software queue full doesn't mean device have no capbility to transmit packet.
+ // So disable block Net-If queue function while WMM enable.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ valid = (pAd->CommonCfg.bWmmCapable == TRUE) ? FALSE : TRUE;
+#endif // CONFIG_STA_SUPPORT //
+
+ if (valid)
+ blockNetIf(&pAd->blockQueueTab[QueIdx], NetDev);
+ return;
+}
+
diff --git a/drivers/staging/rt3070/common/rtmp_init.c b/drivers/staging/rt3070/common/rtmp_init.c
new file mode 100644
index 00000000000..4503f6c6d95
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_init.c
@@ -0,0 +1,4197 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_init.c
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 2002-08-01 created
+ John Chang 2004-08-20 RT2561/2661 use scatter-gather scheme
+ Jan Lee 2006-09-15 RT2860. Change for 802.11n , EEPROM, Led, BA, HT.
+*/
+#include "../rt_config.h"
+#include "../firmware.h"
+
+//#define BIN_IN_FILE /* use *.bin firmware */
+
+UCHAR BIT8[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
+ULONG BIT32[] = {0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080,
+ 0x00000100, 0x00000200, 0x00000400, 0x00000800,
+ 0x00001000, 0x00002000, 0x00004000, 0x00008000,
+ 0x00010000, 0x00020000, 0x00040000, 0x00080000,
+ 0x00100000, 0x00200000, 0x00400000, 0x00800000,
+ 0x01000000, 0x02000000, 0x04000000, 0x08000000,
+ 0x10000000, 0x20000000, 0x40000000, 0x80000000};
+
+char* CipherName[] = {"none","wep64","wep128","TKIP","AES","CKIP64","CKIP128"};
+
+const unsigned short ccitt_16Table[] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+ 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+ 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+ 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+ 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+ 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+ 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+ 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+ 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+ 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+ 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+ 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+ 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+ 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+ 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+ 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+ 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+ 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+ 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+ 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+ 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+};
+#define ByteCRC16(v, crc) \
+ (unsigned short)((crc << 8) ^ ccitt_16Table[((crc >> 8) ^ (v)) & 255])
+
+unsigned char BitReverse(unsigned char x)
+{
+ int i;
+ unsigned char Temp=0;
+ for(i=0; ; i++)
+ {
+ if(x & 0x80) Temp |= 0x80;
+ if(i==7) break;
+ x <<= 1;
+ Temp >>= 1;
+ }
+ return Temp;
+}
+
+//
+// BBP register initialization set
+//
+REG_PAIR BBPRegTable[] = {
+ {BBP_R65, 0x2C}, // fix rssi issue
+ {BBP_R66, 0x38}, // Also set this default value to pAd->BbpTuning.R66CurrentValue at initial
+ {BBP_R69, 0x12},
+ {BBP_R70, 0xa}, // BBP_R70 will change to 0x8 in ApStartUp and LinkUp for rt2860C, otherwise value is 0xa
+ {BBP_R73, 0x10},
+ {BBP_R81, 0x37},
+ {BBP_R82, 0x62},
+ {BBP_R83, 0x6A},
+ {BBP_R84, 0x99}, // 0x19 is for rt2860E and after. This is for extension channel overlapping IOT. 0x99 is for rt2860D and before
+ {BBP_R86, 0x00}, // middle range issue, Rory @2008-01-28
+ {BBP_R91, 0x04}, // middle range issue, Rory @2008-01-28
+ {BBP_R92, 0x00}, // middle range issue, Rory @2008-01-28
+ {BBP_R103, 0x00}, // near range high-power issue, requested from Gary @2008-0528
+ {BBP_R105, 0x05}, // 0x05 is for rt2860E to turn on FEQ control. It is safe for rt2860D and before, because Bit 7:2 are reserved in rt2860D and before.
+};
+#define NUM_BBP_REG_PARMS (sizeof(BBPRegTable) / sizeof(REG_PAIR))
+
+//
+// RF register initialization set
+//
+#ifdef RT30xx
+REG_PAIR RT30xx_RFRegTable[] = {
+ {RF_R04, 0x40},
+ {RF_R05, 0x03},
+ {RF_R06, 0x02},
+ {RF_R07, 0x70},
+ {RF_R09, 0x0F},
+ {RF_R10, 0x41},
+ {RF_R11, 0x21},
+ {RF_R12, 0x7B},
+ {RF_R14, 0x90},
+ {RF_R15, 0x58},
+ {RF_R16, 0xB3},
+ {RF_R17, 0x92},
+ {RF_R18, 0x2C},
+ {RF_R19, 0x02},
+ {RF_R20, 0xBA},
+ {RF_R21, 0xDB},
+ {RF_R24, 0x16},
+ {RF_R25, 0x01},
+ {RF_R29, 0x1F},
+};
+#define NUM_RF_REG_PARMS (sizeof(RT30xx_RFRegTable) / sizeof(REG_PAIR))
+#endif // RT30xx //
+
+//
+// ASIC register initialization sets
+//
+
+RTMP_REG_PAIR MACRegTable[] = {
+#if defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x200)
+ {BCN_OFFSET0, 0xf8f0e8e0}, /* 0x3800(e0), 0x3A00(e8), 0x3C00(f0), 0x3E00(f8), 512B for each beacon */
+ {BCN_OFFSET1, 0x6f77d0c8}, /* 0x3200(c8), 0x3400(d0), 0x1DC0(77), 0x1BC0(6f), 512B for each beacon */
+#elif defined(HW_BEACON_OFFSET) && (HW_BEACON_OFFSET == 0x100)
+ {BCN_OFFSET0, 0xece8e4e0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+ {BCN_OFFSET1, 0xfcf8f4f0}, /* 0x3800, 0x3A00, 0x3C00, 0x3E00, 512B for each beacon */
+#else
+ #error You must re-calculate new value for BCN_OFFSET0 & BCN_OFFSET1 in MACRegTable[]!!!
+#endif // HW_BEACON_OFFSET //
+
+ {LEGACY_BASIC_RATE, 0x0000013f}, // Basic rate set bitmap
+ {HT_BASIC_RATE, 0x00008003}, // Basic HT rate set , 20M, MCS=3, MM. Format is the same as in TXWI.
+ {MAC_SYS_CTRL, 0x00}, // 0x1004, , default Disable RX
+ {RX_FILTR_CFG, 0x17f97}, //0x1400 , RX filter control,
+ {BKOFF_SLOT_CFG, 0x209}, // default set short slot time, CC_DELAY_TIME should be 2
+ //{TX_SW_CFG0, 0x40a06}, // Gary,2006-08-23
+ {TX_SW_CFG0, 0x0}, // Gary,2008-05-21 for CWC test
+ {TX_SW_CFG1, 0x80606}, // Gary,2006-08-23
+ {TX_LINK_CFG, 0x1020}, // Gary,2006-08-23
+ {TX_TIMEOUT_CFG, 0x000a2090},
+ {MAX_LEN_CFG, MAX_AGGREGATION_SIZE | 0x00001000}, // 0x3018, MAX frame length. Max PSDU = 16kbytes.
+ {LED_CFG, 0x7f031e46}, // Gary, 2006-08-23
+
+//#ifdef CONFIG_STA_SUPPORT
+// {WMM_AIFSN_CFG, 0x00002273},
+// {WMM_CWMIN_CFG, 0x00002344},
+// {WMM_CWMAX_CFG, 0x000034aa},
+//#endif // CONFIG_STA_SUPPORT //
+#ifdef INF_AMAZON_SE
+ {PBF_MAX_PCNT, 0x1F3F6F6F}, //iverson modify for usb issue, 2008/09/19
+ // 6F + 6F < total page count FE
+ // so that RX doesn't occupy TX's buffer space when WMM congestion.
+#else
+ {PBF_MAX_PCNT, 0x1F3FBF9F}, //0x1F3f7f9f}, //Jan, 2006/04/20
+#endif // INF_AMAZON_SE //
+ //{TX_RTY_CFG, 0x6bb80408}, // Jan, 2006/11/16
+ {TX_RTY_CFG, 0x47d01f0f}, // Jan, 2006/11/16, Set TxWI->ACK =0 in Probe Rsp Modify for 2860E ,2007-08-03
+ {AUTO_RSP_CFG, 0x00000013}, // Initial Auto_Responder, because QA will turn off Auto-Responder
+ {CCK_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
+ {OFDM_PROT_CFG, 0x05740003 /*0x01740003*/}, // Initial Auto_Responder, because QA will turn off Auto-Responder. And RTS threshold is enabled.
+//PS packets use Tx1Q (for HCCA) when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef RT2870
+#ifdef CONFIG_STA_SUPPORT
+ {PBF_CFG, 0xf40006}, // Only enable Queue 2
+#endif // CONFIG_STA_SUPPORT //
+ {MM40_PROT_CFG, 0x3F44084}, // Initial Auto_Responder, because QA will turn off Auto-Responder
+ {WPDMA_GLO_CFG, 0x00000030},
+#endif // RT2870 //
+ {GF20_PROT_CFG, 0x01744004}, // set 19:18 --> Short NAV for MIMO PS
+ {GF40_PROT_CFG, 0x03F44084},
+ {MM20_PROT_CFG, 0x01744004},
+ {TXOP_CTRL_CFG, 0x0000583f, /*0x0000243f*/ /*0x000024bf*/}, //Extension channel backoff.
+ {TX_RTS_CFG, 0x00092b20},
+//#ifdef WIFI_TEST
+ {EXP_ACK_TIME, 0x002400ca}, // default value
+//#else
+// {EXP_ACK_TIME, 0x005400ca}, // suggested by Gray @ 20070323 for 11n intel-sta throughput
+//#endif // end - WIFI_TEST //
+ {TXOP_HLDR_ET, 0x00000002},
+
+ /* Jerry comments 2008/01/16: we use SIFS = 10us in CCK defaultly, but it seems that 10us
+ is too small for INTEL 2200bg card, so in MBSS mode, the delta time between beacon0
+ and beacon1 is SIFS (10us), so if INTEL 2200bg card connects to BSS0, the ping
+ will always lost. So we change the SIFS of CCK from 10us to 16us. */
+ {XIFS_TIME_CFG, 0x33a41010},
+ {PWR_PIN_CFG, 0x00000003}, // patch for 2880-E
+};
+
+
+#ifdef CONFIG_STA_SUPPORT
+RTMP_REG_PAIR STAMACRegTable[] = {
+ {WMM_AIFSN_CFG, 0x00002273},
+ {WMM_CWMIN_CFG, 0x00002344},
+ {WMM_CWMAX_CFG, 0x000034aa},
+};
+#endif // CONFIG_STA_SUPPORT //
+
+#define NUM_MAC_REG_PARMS (sizeof(MACRegTable) / sizeof(RTMP_REG_PAIR))
+#ifdef CONFIG_STA_SUPPORT
+#define NUM_STA_MAC_REG_PARMS (sizeof(STAMACRegTable) / sizeof(RTMP_REG_PAIR))
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RT2870
+//
+// RT2870 Firmware Spec only used 1 oct for version expression
+//
+#define FIRMWARE_MINOR_VERSION 7
+
+#endif // RT2870 //
+
+// New 8k byte firmware size for RT3071/RT3072
+#define FIRMWAREIMAGE_MAX_LENGTH 0x2000
+#define FIRMWAREIMAGE_LENGTH (sizeof (FirmwareImage) / sizeof(UCHAR))
+#define FIRMWARE_MAJOR_VERSION 0
+
+#define FIRMWAREIMAGEV1_LENGTH 0x1000
+#define FIRMWAREIMAGEV2_LENGTH 0x1000
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Allocate RTMP_ADAPTER data block and do some initialization
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPAllocAdapterBlock(
+ IN PVOID handle,
+ OUT PRTMP_ADAPTER *ppAdapter)
+{
+ PRTMP_ADAPTER pAd;
+ NDIS_STATUS Status;
+ INT index;
+ UCHAR *pBeaconBuf = NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> RTMPAllocAdapterBlock\n"));
+
+ *ppAdapter = NULL;
+
+ do
+ {
+ // Allocate RTMP_ADAPTER memory block
+ pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG);
+ if (pBeaconBuf == NULL)
+ {
+ Status = NDIS_STATUS_FAILURE;
+ DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n"));
+ break;
+ }
+
+ Status = AdapterBlockAllocateMemory(handle, (PVOID *)&pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n"));
+ break;
+ }
+ pAd->BeaconBuf = pBeaconBuf;
+ printk("\n\n=== pAd = %p, size = %d ===\n\n", pAd, (UINT32)sizeof(RTMP_ADAPTER));
+
+
+ // Init spin locks
+ NdisAllocateSpinLock(&pAd->MgmtRingLock);
+
+ for (index =0 ; index < NUM_OF_TX_RING; index++)
+ {
+ NdisAllocateSpinLock(&pAd->TxSwQueueLock[index]);
+ NdisAllocateSpinLock(&pAd->DeQueueLock[index]);
+ pAd->DeQueueRunning[index] = FALSE;
+ }
+
+ NdisAllocateSpinLock(&pAd->irq_lock);
+
+ } while (FALSE);
+
+ if ((Status != NDIS_STATUS_SUCCESS) && (pBeaconBuf))
+ kfree(pBeaconBuf);
+
+ *ppAdapter = pAd;
+
+ DBGPRINT_S(Status, ("<-- RTMPAllocAdapterBlock, Status=%x\n", Status));
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read initial Tx power per MCS and BW from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPReadTxPwrPerRate(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG data, Adata, Gdata;
+ USHORT i, value, value2;
+ INT Apwrdelta, Gpwrdelta;
+ UCHAR t1,t2,t3,t4;
+ BOOLEAN bValid, bApwrdeltaMinus = TRUE, bGpwrdeltaMinus = TRUE;
+
+ //
+ // Get power delta for 20MHz and 40MHz.
+ //
+ DBGPRINT(RT_DEBUG_TRACE, ("Txpower per Rate\n"));
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_DELTA, value2);
+ Apwrdelta = 0;
+ Gpwrdelta = 0;
+
+ if ((value2 & 0xff) != 0xff)
+ {
+ if ((value2 & 0x80))
+ Gpwrdelta = (value2&0xf);
+
+ if ((value2 & 0x40))
+ bGpwrdeltaMinus = FALSE;
+ else
+ bGpwrdeltaMinus = TRUE;
+ }
+ if ((value2 & 0xff00) != 0xff00)
+ {
+ if ((value2 & 0x8000))
+ Apwrdelta = ((value2&0xf00)>>8);
+
+ if ((value2 & 0x4000))
+ bApwrdeltaMinus = FALSE;
+ else
+ bApwrdeltaMinus = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Gpwrdelta = %x, Apwrdelta = %x .\n", Gpwrdelta, Apwrdelta));
+
+ //
+ // Get Txpower per MCS for 20MHz in 2.4G.
+ //
+ for (i=0; i<5; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4, value);
+ data = value;
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_2_4G + i*4 + 2, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+ data |= (value<<16);
+
+ pAd->Tx20MPwrCfgABand[i] = pAd->Tx40MPwrCfgABand[i] = Adata;
+ pAd->Tx20MPwrCfgGBand[i] = pAd->Tx40MPwrCfgGBand[i] = Gdata;
+
+ if (data != 0xffffffff)
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, data);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 2.4G band-%lx, Adata = %lx, Gdata = %lx \n", data, Adata, Gdata));
+ }
+
+ //
+ // Check this block is valid for 40MHz in 2.4G. If invalid, use parameter for 20MHz in 2.4G
+ //
+ bValid = TRUE;
+ for (i=0; i<6; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + 2 + i*2, value);
+ if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+ {
+ bValid = FALSE;
+ break;
+ }
+ }
+
+ //
+ // Get Txpower per MCS for 40MHz in 2.4G.
+ //
+ if (bValid)
+ {
+ for (i=0; i<4; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4, value);
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_2_4G + i*4 + 2, value);
+ if (bGpwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Gpwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Gpwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Gpwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Gpwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Gpwrdelta)
+ t1 = (value&0xf)-(Gpwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Gpwrdelta)
+ t2 = ((value&0xf0)>>4)-(Gpwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Gpwrdelta)
+ t3 = ((value&0xf00)>>8)-(Gpwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Gpwrdelta)
+ t4 = ((value&0xf000)>>12)-(Gpwrdelta);
+ else
+ t4 = 0;
+ }
+ Gdata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+ if (i == 0)
+ pAd->Tx40MPwrCfgGBand[i+1] = (pAd->Tx40MPwrCfgGBand[i+1] & 0x0000FFFF) | (Gdata & 0xFFFF0000);
+ else
+ pAd->Tx40MPwrCfgGBand[i+1] = Gdata;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 2.4G band, Gdata = %lx \n", Gdata));
+ }
+ }
+
+ //
+ // Check this block is valid for 20MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
+ //
+ bValid = TRUE;
+ for (i=0; i<8; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + 2 + i*2, value);
+ if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+ {
+ bValid = FALSE;
+ break;
+ }
+ }
+
+ //
+ // Get Txpower per MCS for 20MHz in 5G.
+ //
+ if (bValid)
+ {
+ for (i=0; i<5; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_20MHZ_5G + i*4 + 2, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+ if (i == 0)
+ pAd->Tx20MPwrCfgABand[i] = (pAd->Tx20MPwrCfgABand[i] & 0x0000FFFF) | (Adata & 0xFFFF0000);
+ else
+ pAd->Tx20MPwrCfgABand[i] = Adata;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("20MHz BW, 5GHz band, Adata = %lx \n", Adata));
+ }
+ }
+
+ //
+ // Check this block is valid for 40MHz in 5G. If invalid, use parameter for 20MHz in 2.4G
+ //
+ bValid = TRUE;
+ for (i=0; i<6; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + 2 + i*2, value);
+ if (((value & 0x00FF) == 0x00FF) || ((value & 0xFF00) == 0xFF00))
+ {
+ bValid = FALSE;
+ break;
+ }
+ }
+
+ //
+ // Get Txpower per MCS for 40MHz in 5G.
+ //
+ if (bValid)
+ {
+ for (i=0; i<4; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata = t1 + (t2<<4) + (t3<<8) + (t4<<12);
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_TXPOWER_BYRATE_40MHZ_5G + i*4 + 2, value);
+ if (bApwrdeltaMinus == FALSE)
+ {
+ t1 = (value&0xf)+(Apwrdelta);
+ if (t1 > 0xf)
+ t1 = 0xf;
+ t2 = ((value&0xf0)>>4)+(Apwrdelta);
+ if (t2 > 0xf)
+ t2 = 0xf;
+ t3 = ((value&0xf00)>>8)+(Apwrdelta);
+ if (t3 > 0xf)
+ t3 = 0xf;
+ t4 = ((value&0xf000)>>12)+(Apwrdelta);
+ if (t4 > 0xf)
+ t4 = 0xf;
+ }
+ else
+ {
+ if ((value&0xf) > Apwrdelta)
+ t1 = (value&0xf)-(Apwrdelta);
+ else
+ t1 = 0;
+ if (((value&0xf0)>>4) > Apwrdelta)
+ t2 = ((value&0xf0)>>4)-(Apwrdelta);
+ else
+ t2 = 0;
+ if (((value&0xf00)>>8) > Apwrdelta)
+ t3 = ((value&0xf00)>>8)-(Apwrdelta);
+ else
+ t3 = 0;
+ if (((value&0xf000)>>12) > Apwrdelta)
+ t4 = ((value&0xf000)>>12)-(Apwrdelta);
+ else
+ t4 = 0;
+ }
+ Adata |= ((t1<<16) + (t2<<20) + (t3<<24) + (t4<<28));
+
+ if (i == 0)
+ pAd->Tx40MPwrCfgABand[i+1] = (pAd->Tx40MPwrCfgABand[i+1] & 0x0000FFFF) | (Adata & 0xFFFF0000);
+ else
+ pAd->Tx40MPwrCfgABand[i+1] = Adata;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("40MHz BW, 5GHz band, Adata = %lx \n", Adata));
+ }
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read initial channel power parameters from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPReadChannelPwr(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR i, choffset;
+ EEPROM_TX_PWR_STRUC Power;
+ EEPROM_TX_PWR_STRUC Power2;
+
+ // Read Tx power value for all channels
+ // Value from 1 - 0x7f. Default value is 24.
+ // Power value : 2.4G 0x00 (0) ~ 0x1F (31)
+ // : 5.5G 0xF9 (-7) ~ 0x0F (15)
+
+ // 0. 11b/g, ch1 - ch 14
+ for (i = 0; i < 7; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX_PWR_OFFSET + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_G_TX2_PWR_OFFSET + i * 2, Power2.word);
+ pAd->TxPower[i * 2].Channel = i * 2 + 1;
+ pAd->TxPower[i * 2 + 1].Channel = i * 2 + 2;
+
+ if ((Power.field.Byte0 > 31) || (Power.field.Byte0 < 0))
+ pAd->TxPower[i * 2].Power = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 > 31) || (Power.field.Byte1 < 0))
+ pAd->TxPower[i * 2 + 1].Power = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2 + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 > 31) || (Power2.field.Byte0 < 0))
+ pAd->TxPower[i * 2].Power2 = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 > 31) || (Power2.field.Byte1 < 0))
+ pAd->TxPower[i * 2 + 1].Power2 = DEFAULT_RF_TX_POWER;
+ else
+ pAd->TxPower[i * 2 + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 1. U-NII lower/middle band: 36, 38, 40; 44, 46, 48; 52, 54, 56; 60, 62, 64 (including central frequency in BW 40MHz)
+ // 1.1 Fill up channel
+ choffset = 14;
+ for (i = 0; i < 4; i++)
+ {
+ pAd->TxPower[3 * i + choffset + 0].Channel = 36 + i * 8 + 0;
+ pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 1].Channel = 36 + i * 8 + 2;
+ pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 2].Channel = 36 + i * 8 + 4;
+ pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
+ }
+
+ // 1.2 Fill up power
+ for (i = 0; i < 6; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + i * 2, Power2.word);
+
+ if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 2. HipperLAN 2 100, 102 ,104; 108, 110, 112; 116, 118, 120; 124, 126, 128; 132, 134, 136; 140 (including central frequency in BW 40MHz)
+ // 2.1 Fill up channel
+ choffset = 14 + 12;
+ for (i = 0; i < 5; i++)
+ {
+ pAd->TxPower[3 * i + choffset + 0].Channel = 100 + i * 8 + 0;
+ pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 1].Channel = 100 + i * 8 + 2;
+ pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 2].Channel = 100 + i * 8 + 4;
+ pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
+ }
+ pAd->TxPower[3 * 5 + choffset + 0].Channel = 140;
+ pAd->TxPower[3 * 5 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * 5 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ // 2.2 Fill up power
+ for (i = 0; i < 8; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+
+ if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 3. U-NII upper band: 149, 151, 153; 157, 159, 161; 165 (including central frequency in BW 40MHz)
+ // 3.1 Fill up channel
+ choffset = 14 + 12 + 16;
+ for (i = 0; i < 2; i++)
+ {
+ pAd->TxPower[3 * i + choffset + 0].Channel = 149 + i * 8 + 0;
+ pAd->TxPower[3 * i + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 1].Channel = 149 + i * 8 + 2;
+ pAd->TxPower[3 * i + choffset + 1].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 1].Power2 = DEFAULT_RF_TX_POWER;
+
+ pAd->TxPower[3 * i + choffset + 2].Channel = 149 + i * 8 + 4;
+ pAd->TxPower[3 * i + choffset + 2].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * i + choffset + 2].Power2 = DEFAULT_RF_TX_POWER;
+ }
+ pAd->TxPower[3 * 2 + choffset + 0].Channel = 165;
+ pAd->TxPower[3 * 2 + choffset + 0].Power = DEFAULT_RF_TX_POWER;
+ pAd->TxPower[3 * 2 + choffset + 0].Power2 = DEFAULT_RF_TX_POWER;
+
+ // 3.2 Fill up power
+ for (i = 0; i < 4; i++)
+ {
+// Power.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2);
+// Power2.word = RTMP_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX_PWR_OFFSET + (choffset - 14) + i * 2, Power.word);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_A_TX2_PWR_OFFSET + (choffset - 14) + i * 2, Power2.word);
+
+ if ((Power.field.Byte0 < 16) && (Power.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power = Power.field.Byte0;
+
+ if ((Power.field.Byte1 < 16) && (Power.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power = Power.field.Byte1;
+
+ if ((Power2.field.Byte0 < 16) && (Power2.field.Byte0 >= -7))
+ pAd->TxPower[i * 2 + choffset + 0].Power2 = Power2.field.Byte0;
+
+ if ((Power2.field.Byte1 < 16) && (Power2.field.Byte1 >= -7))
+ pAd->TxPower[i * 2 + choffset + 1].Power2 = Power2.field.Byte1;
+ }
+
+ // 4. Print and Debug
+ choffset = 14 + 12 + 16 + 7;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read the following from the registry
+ 1. All the parameters
+ 2. NetworkAddres
+
+ Arguments:
+ Adapter Pointer to our adapter
+ WrapperConfigurationContext For use by NdisOpenConfiguration
+
+ Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+ NDIS_STATUS_RESOURCES
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS NICReadRegParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_HANDLE WrapperConfigurationContext
+ )
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ DBGPRINT_S(Status, ("<-- NICReadRegParameters, Status=%x\n", Status));
+ return Status;
+}
+
+
+#ifdef RT30xx
+/*
+ ========================================================================
+
+ Routine Description:
+ For RF filter calibration purpose
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPFilterCalibration(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR R55x = 0, value, FilterTarget = 0x1E, BBPValue=0;
+ UINT loop = 0, count = 0, loopcnt = 0, ReTry = 0;
+ UCHAR RF_R24_Value = 0;
+
+ // Give bbp filter initial value
+ pAd->Mlme.CaliBW20RfR24 = 0x1F;
+ pAd->Mlme.CaliBW40RfR24 = 0x2F; //Bit[5] must be 1 for BW 40
+
+ do
+ {
+ if (loop == 1) //BandWidth = 40 MHz
+ {
+ // Write 0x27 to RF_R24 to program filter
+ RF_R24_Value = 0x27;
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+ if (IS_RT3090(pAd))
+ FilterTarget = 0x15;
+ else
+ FilterTarget = 0x19;
+
+ // when calibrate BW40, BBP mask must set to BW40.
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ BBPValue|= (0x10);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+ // set to BW40
+ RT30xxReadRFRegister(pAd, RF_R31, &value);
+ value |= 0x20;
+ RT30xxWriteRFRegister(pAd, RF_R31, value);
+ }
+ else //BandWidth = 20 MHz
+ {
+ // Write 0x07 to RF_R24 to program filter
+ RF_R24_Value = 0x07;
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+ if (IS_RT3090(pAd))
+ FilterTarget = 0x13;
+ else
+ FilterTarget = 0x16;
+
+ // set to BW20
+ RT30xxReadRFRegister(pAd, RF_R31, &value);
+ value &= (~0x20);
+ RT30xxWriteRFRegister(pAd, RF_R31, value);
+ }
+
+ // Write 0x01 to RF_R22 to enable baseband loopback mode
+ RT30xxReadRFRegister(pAd, RF_R22, &value);
+ value |= 0x01;
+ RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+ // Write 0x00 to BBP_R24 to set power & frequency of passband test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+ do
+ {
+ // Write 0x90 to BBP_R25 to transmit test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+ RTMPusecDelay(1000);
+ // Read BBP_R55[6:0] for received power, set R55x = BBP_R55[6:0]
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+ R55x = value & 0xFF;
+
+ } while ((ReTry++ < 100) && (R55x == 0));
+
+ // Write 0x06 to BBP_R24 to set power & frequency of stopband test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0x06);
+
+ while(TRUE)
+ {
+ // Write 0x90 to BBP_R25 to transmit test tone
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R25, 0x90);
+
+ //We need to wait for calibration
+ RTMPusecDelay(1000);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R55, &value);
+ value &= 0xFF;
+ if ((R55x - value) < FilterTarget)
+ {
+ RF_R24_Value ++;
+ }
+ else if ((R55x - value) == FilterTarget)
+ {
+ RF_R24_Value ++;
+ count ++;
+ }
+ else
+ {
+ break;
+ }
+
+ // prevent infinite loop cause driver hang.
+ if (loopcnt++ > 100)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", loopcnt));
+ break;
+ }
+
+ // Write RF_R24 to program filter
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+ }
+
+ if (count > 0)
+ {
+ RF_R24_Value = RF_R24_Value - ((count) ? (1) : (0));
+ }
+
+ // Store for future usage
+ if (loopcnt < 100)
+ {
+ if (loop++ == 0)
+ {
+ //BandWidth = 20 MHz
+ pAd->Mlme.CaliBW20RfR24 = (UCHAR)RF_R24_Value;
+ }
+ else
+ {
+ //BandWidth = 40 MHz
+ pAd->Mlme.CaliBW40RfR24 = (UCHAR)RF_R24_Value;
+ break;
+ }
+ }
+ else
+ break;
+
+ RT30xxWriteRFRegister(pAd, RF_R24, RF_R24_Value);
+
+ // reset count
+ count = 0;
+ } while(TRUE);
+
+ //
+ // Set back to initial state
+ //
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, 0);
+
+ RT30xxReadRFRegister(pAd, RF_R22, &value);
+ value &= ~(0x01);
+ RT30xxWriteRFRegister(pAd, RF_R22, value);
+
+ // set BBP back to BW20
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue&= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPFilterCalibration - CaliBW20RfR24=0x%x, CaliBW40RfR24=0x%x\n", pAd->Mlme.CaliBW20RfR24, pAd->Mlme.CaliBW40RfR24));
+}
+#endif // RT30xx //
+
+
+#ifdef RT3070
+VOID NICInitRT30xxRFRegisters(IN PRTMP_ADAPTER pAd)
+{
+ INT i;
+ // Driver must read EEPROM to get RfIcType before initial RF registers
+ // Initialize RF register to default value
+ if (IS_RT3070(pAd) || IS_RT3071(pAd))
+ {
+ // Init RF calibration
+ // Driver should toggle RF R30 bit7 before init RF registers
+ UINT32 RfReg = 0;
+ UINT32 data;
+
+ RT30xxReadRFRegister(pAd, RF_R30, (PUCHAR)&RfReg);
+ RfReg |= 0x80;
+ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+ RTMPusecDelay(1000);
+ RfReg &= 0x7F;
+ RT30xxWriteRFRegister(pAd, RF_R30, (UCHAR)RfReg);
+
+ // Initialize RF register to default value
+ for (i = 0; i < NUM_RF_REG_PARMS; i++)
+ {
+ RT30xxWriteRFRegister(pAd, RT30xx_RFRegTable[i].Register, RT30xx_RFRegTable[i].Value);
+ }
+
+ // add by johnli
+ if (IS_RT3070(pAd))
+ {
+ // Update MAC 0x05D4 from 01xxxxxx to 0Dxxxxxx (voltage 1.2V to 1.35V) for RT3070 to improve yield rate
+ RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+ data = ((data & 0xF0FFFFFF) | 0x0D000000);
+ RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+ }
+ else if (IS_RT3071(pAd))
+ {
+ // Driver should set RF R6 bit6 on before init RF registers
+ RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RfReg);
+ RfReg |= 0x40;
+ RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RfReg);
+
+ // init R31
+ RT30xxWriteRFRegister(pAd, RF_R31, 0x14);
+
+ // RT3071 version E has fixed this issue
+ if ((pAd->NicConfig2.field.DACTestBit == 1) && ((pAd->MACVersion & 0xffff) < 0x0211))
+ {
+ // patch tx EVM issue temporarily
+ RTUSBReadMACRegister(pAd, LDO_CFG0, &data);
+ data = ((data & 0xE0FFFFFF) | 0x0D000000);
+ RTUSBWriteMACRegister(pAd, LDO_CFG0, data);
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, LDO_CFG0, &data);
+ data = ((data & 0xE0FFFFFF) | 0x01000000);
+ RTMP_IO_WRITE32(pAd, LDO_CFG0, data);
+ }
+
+ // patch LNA_PE_G1 failed issue
+ RTUSBReadMACRegister(pAd, GPIO_SWITCH, &data);
+ data &= ~(0x20);
+ RTUSBWriteMACRegister(pAd, GPIO_SWITCH, data);
+ }
+
+ //For RF filter Calibration
+ RTMPFilterCalibration(pAd);
+
+ // Initialize RF R27 register, set RF R27 must be behind RTMPFilterCalibration()
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ RT30xxWriteRFRegister(pAd, RF_R27, 0x3);
+
+ // set led open drain enable
+ RTUSBReadMACRegister(pAd, OPT_14, &data);
+ data |= 0x01;
+ RTUSBWriteMACRegister(pAd, OPT_14, data);
+
+ if (IS_RT3071(pAd))
+ {
+ // add by johnli, RF power sequence setup, load RF normal operation-mode setup
+ RT30xxLoadRFNormalModeSetup(pAd);
+ }
+ }
+
+}
+#endif // RT3070 //
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read initial parameters from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID NICReadEEPROMParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mac_addr)
+{
+ UINT32 data = 0;
+ USHORT i, value, value2;
+ UCHAR TmpPhy;
+ EEPROM_TX_PWR_STRUC Power;
+ EEPROM_VERSION_STRUC Version;
+ EEPROM_ANTENNA_STRUC Antenna;
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICReadEEPROMParameters\n"));
+
+ // Init EEPROM Address Number, before access EEPROM; if 93c46, EEPROMAddressNum=6, else if 93c66, EEPROMAddressNum=8
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
+ DBGPRINT(RT_DEBUG_TRACE, ("--> E2PROM_CSR = 0x%x\n", data));
+
+ if((data & 0x30) == 0)
+ pAd->EEPROMAddressNum = 6; // 93C46
+ else if((data & 0x30) == 0x10)
+ pAd->EEPROMAddressNum = 8; // 93C66
+ else
+ pAd->EEPROMAddressNum = 8; // 93C86
+ DBGPRINT(RT_DEBUG_TRACE, ("--> EEPROMAddressNum = %d\n", pAd->EEPROMAddressNum ));
+
+ // RT2860 MAC no longer auto load MAC address from E2PROM. Driver has to intialize
+ // MAC address registers according to E2PROM setting
+ if (mac_addr == NULL ||
+ strlen(mac_addr) != 17 ||
+ mac_addr[2] != ':' || mac_addr[5] != ':' || mac_addr[8] != ':' ||
+ mac_addr[11] != ':' || mac_addr[14] != ':')
+ {
+ USHORT Addr01,Addr23,Addr45 ;
+
+ RT28xx_EEPROM_READ16(pAd, 0x04, Addr01);
+ RT28xx_EEPROM_READ16(pAd, 0x06, Addr23);
+ RT28xx_EEPROM_READ16(pAd, 0x08, Addr45);
+
+ pAd->PermanentAddress[0] = (UCHAR)(Addr01 & 0xff);
+ pAd->PermanentAddress[1] = (UCHAR)(Addr01 >> 8);
+ pAd->PermanentAddress[2] = (UCHAR)(Addr23 & 0xff);
+ pAd->PermanentAddress[3] = (UCHAR)(Addr23 >> 8);
+ pAd->PermanentAddress[4] = (UCHAR)(Addr45 & 0xff);
+ pAd->PermanentAddress[5] = (UCHAR)(Addr45 >> 8);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from E2PROM \n"));
+ }
+ else
+ {
+ INT j;
+ PUCHAR macptr;
+
+ macptr = mac_addr;
+
+ for (j=0; j<MAC_ADDR_LEN; j++)
+ {
+ AtoH(macptr, &pAd->PermanentAddress[j], 1);
+ macptr=macptr+3;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Initialize MAC Address from module parameter \n"));
+ }
+
+
+ {
+ //more conveninet to test mbssid, so ap's bssid &0xf1
+ if (pAd->PermanentAddress[0] == 0xff)
+ pAd->PermanentAddress[0] = RandomByte(pAd)&0xf8;
+
+ //if (pAd->PermanentAddress[5] == 0xff)
+ // pAd->PermanentAddress[5] = RandomByte(pAd)&0xf8;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->PermanentAddress[0], pAd->PermanentAddress[1],
+ pAd->PermanentAddress[2], pAd->PermanentAddress[3],
+ pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
+ if (pAd->bLocalAdminMAC == FALSE)
+ {
+ MAC_DW0_STRUC csr2;
+ MAC_DW1_STRUC csr3;
+ COPY_MAC_ADDR(pAd->CurrentAddress, pAd->PermanentAddress);
+ csr2.field.Byte0 = pAd->CurrentAddress[0];
+ csr2.field.Byte1 = pAd->CurrentAddress[1];
+ csr2.field.Byte2 = pAd->CurrentAddress[2];
+ csr2.field.Byte3 = pAd->CurrentAddress[3];
+ RTMP_IO_WRITE32(pAd, MAC_ADDR_DW0, csr2.word);
+ csr3.word = 0;
+ csr3.field.Byte4 = pAd->CurrentAddress[4];
+ csr3.field.Byte5 = pAd->CurrentAddress[5];
+ csr3.field.U2MeMask = 0xff;
+ RTMP_IO_WRITE32(pAd, MAC_ADDR_DW1, csr3.word);
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("E2PROM MAC: =%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->PermanentAddress[0], pAd->PermanentAddress[1],
+ pAd->PermanentAddress[2], pAd->PermanentAddress[3],
+ pAd->PermanentAddress[4], pAd->PermanentAddress[5]));
+ }
+ }
+
+ // if not return early. cause fail at emulation.
+ // Init the channel number for TX channel power
+ RTMPReadChannelPwr(pAd);
+
+ // if E2PROM version mismatch with driver's expectation, then skip
+ // all subsequent E2RPOM retieval and set a system error bit to notify GUI
+ RT28xx_EEPROM_READ16(pAd, EEPROM_VERSION_OFFSET, Version.word);
+ pAd->EepromVersion = Version.field.Version + Version.field.FaeReleaseNumber * 256;
+ DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: Version = %d, FAE release #%d\n", Version.field.Version, Version.field.FaeReleaseNumber));
+
+ if (Version.field.Version > VALID_EEPROM_VERSION)
+ {
+ DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n",Version.field.Version, VALID_EEPROM_VERSION));
+ /*pAd->SystemErrorBitmap |= 0x00000001;
+
+ // hard-code default value when no proper E2PROM installed
+ pAd->bAutoTxAgcA = FALSE;
+ pAd->bAutoTxAgcG = FALSE;
+
+ // Default the channel power
+ for (i = 0; i < MAX_NUM_OF_CHANNELS; i++)
+ pAd->TxPower[i].Power = DEFAULT_RF_TX_POWER;
+
+ // Default the channel power
+ for (i = 0; i < MAX_NUM_OF_11JCHANNELS; i++)
+ pAd->TxPower11J[i].Power = DEFAULT_RF_TX_POWER;
+
+ for(i = 0; i < NUM_EEPROM_BBP_PARMS; i++)
+ pAd->EEPROMDefaultValue[i] = 0xffff;
+ return; */
+ }
+
+ // Read BBP default value from EEPROM and store to array(EEPROMDefaultValue) in pAd
+ RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, value);
+ pAd->EEPROMDefaultValue[0] = value;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_NIC2_OFFSET, value);
+ pAd->EEPROMDefaultValue[1] = value;
+
+ RT28xx_EEPROM_READ16(pAd, 0x38, value); // Country Region
+ pAd->EEPROMDefaultValue[2] = value;
+
+ for(i = 0; i < 8; i++)
+ {
+ RT28xx_EEPROM_READ16(pAd, EEPROM_BBP_BASE_OFFSET + i*2, value);
+ pAd->EEPROMDefaultValue[i+3] = value;
+ }
+
+ // We have to parse NIC configuration 0 at here.
+ // If TSSI did not have preloaded value, it should reset the TxAutoAgc to false
+ // Therefore, we have to read TxAutoAgc control beforehand.
+ // Read Tx AGC control bit
+ Antenna.word = pAd->EEPROMDefaultValue[0];
+ if (Antenna.word == 0xFFFF)
+ {
+#ifdef RT30xx
+ if(IS_RT3090(pAd))
+ {
+ Antenna.word = 0;
+ Antenna.field.RfIcType = RFIC_3020;
+ Antenna.field.TxPath = 1;
+ Antenna.field.RxPath = 1;
+ }
+ else
+ {
+#endif // RT30xx //
+ Antenna.word = 0;
+ Antenna.field.RfIcType = RFIC_2820;
+ Antenna.field.TxPath = 1;
+ Antenna.field.RxPath = 2;
+ DBGPRINT(RT_DEBUG_WARN, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
+#ifdef RT30xx
+ }
+#endif // RT30xx //
+ }
+
+ // Choose the desired Tx&Rx stream.
+ if ((pAd->CommonCfg.TxStream == 0) || (pAd->CommonCfg.TxStream > Antenna.field.TxPath))
+ pAd->CommonCfg.TxStream = Antenna.field.TxPath;
+
+ if ((pAd->CommonCfg.RxStream == 0) || (pAd->CommonCfg.RxStream > Antenna.field.RxPath))
+ {
+ pAd->CommonCfg.RxStream = Antenna.field.RxPath;
+
+ if ((pAd->MACVersion < RALINK_2883_VERSION) &&
+ (pAd->CommonCfg.RxStream > 2))
+ {
+ // only 2 Rx streams for RT2860 series
+ pAd->CommonCfg.RxStream = 2;
+ }
+ }
+
+ // 3*3
+ // read value from EEPROM and set them to CSR174 ~ 177 in chain0 ~ chain2
+ // yet implement
+ for(i=0; i<3; i++)
+ {
+ }
+
+ NicConfig2.word = pAd->EEPROMDefaultValue[1];
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((NicConfig2.word & 0x00ff) == 0xff)
+ {
+ NicConfig2.word &= 0xff00;
+ }
+
+ if ((NicConfig2.word >> 8) == 0xff)
+ {
+ NicConfig2.word &= 0x00ff;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (NicConfig2.field.DynamicTxAgcControl == 1)
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
+ else
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("NICReadEEPROMParameters: RxPath = %d, TxPath = %d\n", Antenna.field.RxPath, Antenna.field.TxPath));
+
+ // Save the antenna for future use
+ pAd->Antenna.word = Antenna.word;
+
+ //
+ // Reset PhyMode if we don't support 802.11a
+ // Only RFIC_2850 & RFIC_2750 support 802.11a
+ //
+ if ((Antenna.field.RfIcType != RFIC_2850) && (Antenna.field.RfIcType != RFIC_2750))
+ {
+ if ((pAd->CommonCfg.PhyMode == PHY_11ABG_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11A))
+ pAd->CommonCfg.PhyMode = PHY_11BG_MIXED;
+#ifdef DOT11_N_SUPPORT
+ else if ((pAd->CommonCfg.PhyMode == PHY_11ABGN_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11AN_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11AGN_MIXED) ||
+ (pAd->CommonCfg.PhyMode == PHY_11N_5G))
+ pAd->CommonCfg.PhyMode = PHY_11BGN_MIXED;
+#endif // DOT11_N_SUPPORT //
+ }
+
+ // Read TSSI reference and TSSI boundary for temperature compensation. This is ugly
+ // 0. 11b/g
+ {
+ /* these are tempature reference value (0x00 ~ 0xFE)
+ ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+ TssiPlusBoundaryG [4] [3] [2] [1] [0] (smaller) +
+ TssiMinusBoundaryG[0] [1] [2] [3] [4] (larger) */
+ RT28xx_EEPROM_READ16(pAd, 0x6E, Power.word);
+ pAd->TssiMinusBoundaryG[4] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryG[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x70, Power.word);
+ pAd->TssiMinusBoundaryG[2] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryG[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x72, Power.word);
+ pAd->TssiRefG = Power.field.Byte0; /* reference value [0] */
+ pAd->TssiPlusBoundaryG[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x74, Power.word);
+ pAd->TssiPlusBoundaryG[2] = Power.field.Byte0;
+ pAd->TssiPlusBoundaryG[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0x76, Power.word);
+ pAd->TssiPlusBoundaryG[4] = Power.field.Byte0;
+ pAd->TxAgcStepG = Power.field.Byte1;
+ pAd->TxAgcCompensateG = 0;
+ pAd->TssiMinusBoundaryG[0] = pAd->TssiRefG;
+ pAd->TssiPlusBoundaryG[0] = pAd->TssiRefG;
+
+ // Disable TxAgc if the based value is not right
+ if (pAd->TssiRefG == 0xff)
+ pAd->bAutoTxAgcG = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE,("E2PROM: G Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+ pAd->TssiMinusBoundaryG[4], pAd->TssiMinusBoundaryG[3], pAd->TssiMinusBoundaryG[2], pAd->TssiMinusBoundaryG[1],
+ pAd->TssiRefG,
+ pAd->TssiPlusBoundaryG[1], pAd->TssiPlusBoundaryG[2], pAd->TssiPlusBoundaryG[3], pAd->TssiPlusBoundaryG[4],
+ pAd->TxAgcStepG, pAd->bAutoTxAgcG));
+ }
+ // 1. 11a
+ {
+ RT28xx_EEPROM_READ16(pAd, 0xD4, Power.word);
+ pAd->TssiMinusBoundaryA[4] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryA[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xD6, Power.word);
+ pAd->TssiMinusBoundaryA[2] = Power.field.Byte0;
+ pAd->TssiMinusBoundaryA[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xD8, Power.word);
+ pAd->TssiRefA = Power.field.Byte0;
+ pAd->TssiPlusBoundaryA[1] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xDA, Power.word);
+ pAd->TssiPlusBoundaryA[2] = Power.field.Byte0;
+ pAd->TssiPlusBoundaryA[3] = Power.field.Byte1;
+ RT28xx_EEPROM_READ16(pAd, 0xDC, Power.word);
+ pAd->TssiPlusBoundaryA[4] = Power.field.Byte0;
+ pAd->TxAgcStepA = Power.field.Byte1;
+ pAd->TxAgcCompensateA = 0;
+ pAd->TssiMinusBoundaryA[0] = pAd->TssiRefA;
+ pAd->TssiPlusBoundaryA[0] = pAd->TssiRefA;
+
+ // Disable TxAgc if the based value is not right
+ if (pAd->TssiRefA == 0xff)
+ pAd->bAutoTxAgcA = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE,("E2PROM: A Tssi[-4 .. +4] = %d %d %d %d - %d -%d %d %d %d, step=%d, tuning=%d\n",
+ pAd->TssiMinusBoundaryA[4], pAd->TssiMinusBoundaryA[3], pAd->TssiMinusBoundaryA[2], pAd->TssiMinusBoundaryA[1],
+ pAd->TssiRefA,
+ pAd->TssiPlusBoundaryA[1], pAd->TssiPlusBoundaryA[2], pAd->TssiPlusBoundaryA[3], pAd->TssiPlusBoundaryA[4],
+ pAd->TxAgcStepA, pAd->bAutoTxAgcA));
+ }
+ pAd->BbpRssiToDbmDelta = 0x0;
+
+ // Read frequency offset setting for RF
+ RT28xx_EEPROM_READ16(pAd, EEPROM_FREQ_OFFSET, value);
+ if ((value & 0x00FF) != 0x00FF)
+ pAd->RfFreqOffset = (ULONG) (value & 0x00FF);
+ else
+ pAd->RfFreqOffset = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("E2PROM: RF FreqOffset=0x%lx \n", pAd->RfFreqOffset));
+
+ //CountryRegion byte offset (38h)
+ value = pAd->EEPROMDefaultValue[2] >> 8; // 2.4G band
+ value2 = pAd->EEPROMDefaultValue[2] & 0x00FF; // 5G band
+
+ if ((value <= REGION_MAXIMUM_BG_BAND) && (value2 <= REGION_MAXIMUM_A_BAND))
+ {
+ pAd->CommonCfg.CountryRegion = ((UCHAR) value) | 0x80;
+ pAd->CommonCfg.CountryRegionForABand = ((UCHAR) value2) | 0x80;
+ TmpPhy = pAd->CommonCfg.PhyMode;
+ pAd->CommonCfg.PhyMode = 0xff;
+ RTMPSetPhyMode(pAd, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ }
+
+ //
+ // Get RSSI Offset on EEPROM 0x9Ah & 0x9Ch.
+ // The valid value are (-10 ~ 10)
+ //
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, value);
+ pAd->BGRssiOffset0 = value & 0x00ff;
+ pAd->BGRssiOffset1 = (value >> 8);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET+2, value);
+ pAd->BGRssiOffset2 = value & 0x00ff;
+ pAd->ALNAGain1 = (value >> 8);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, value);
+ pAd->BLNAGain = value & 0x00ff;
+ pAd->ALNAGain0 = (value >> 8);
+
+ // Validate 11b/g RSSI_0 offset.
+ if ((pAd->BGRssiOffset0 < -10) || (pAd->BGRssiOffset0 > 10))
+ pAd->BGRssiOffset0 = 0;
+
+ // Validate 11b/g RSSI_1 offset.
+ if ((pAd->BGRssiOffset1 < -10) || (pAd->BGRssiOffset1 > 10))
+ pAd->BGRssiOffset1 = 0;
+
+ // Validate 11b/g RSSI_2 offset.
+ if ((pAd->BGRssiOffset2 < -10) || (pAd->BGRssiOffset2 > 10))
+ pAd->BGRssiOffset2 = 0;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, value);
+ pAd->ARssiOffset0 = value & 0x00ff;
+ pAd->ARssiOffset1 = (value >> 8);
+ RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET+2), value);
+ pAd->ARssiOffset2 = value & 0x00ff;
+ pAd->ALNAGain2 = (value >> 8);
+
+ if (((UCHAR)pAd->ALNAGain1 == 0xFF) || (pAd->ALNAGain1 == 0x00))
+ pAd->ALNAGain1 = pAd->ALNAGain0;
+ if (((UCHAR)pAd->ALNAGain2 == 0xFF) || (pAd->ALNAGain2 == 0x00))
+ pAd->ALNAGain2 = pAd->ALNAGain0;
+
+ // Validate 11a RSSI_0 offset.
+ if ((pAd->ARssiOffset0 < -10) || (pAd->ARssiOffset0 > 10))
+ pAd->ARssiOffset0 = 0;
+
+ // Validate 11a RSSI_1 offset.
+ if ((pAd->ARssiOffset1 < -10) || (pAd->ARssiOffset1 > 10))
+ pAd->ARssiOffset1 = 0;
+
+ //Validate 11a RSSI_2 offset.
+ if ((pAd->ARssiOffset2 < -10) || (pAd->ARssiOffset2 > 10))
+ pAd->ARssiOffset2 = 0;
+
+ //
+ // Get LED Setting.
+ //
+ RT28xx_EEPROM_READ16(pAd, 0x3a, value);
+ pAd->LedCntl.word = (value&0xff00) >> 8;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LED1_OFFSET, value);
+ pAd->Led1 = value;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LED2_OFFSET, value);
+ pAd->Led2 = value;
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LED3_OFFSET, value);
+ pAd->Led3 = value;
+
+ RTMPReadTxPwrPerRate(pAd);
+
+#ifdef SINGLE_SKU
+ //pAd->CommonCfg.DefineMaxTxPwr = RTMP_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_DEFINE_MAX_TXPWR, pAd->CommonCfg.DefineMaxTxPwr);
+#endif // SINGLE_SKU //
+#ifdef RT30xx
+ if (IS_RT30xx(pAd))
+ {
+ eFusePhysicalReadRegisters(pAd, EFUSE_TAG, 2, &value);
+ pAd->EFuseTag = (value & 0xff);
+ }
+#endif // RT30xx //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICReadEEPROMParameters\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set default value from EEPROM
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID NICInitAsicFromEEPROM(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef CONFIG_STA_SUPPORT
+ UINT32 data = 0;
+ UCHAR BBPR1 = 0;
+#endif // CONFIG_STA_SUPPORT //
+ USHORT i;
+ EEPROM_ANTENNA_STRUC Antenna;
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+ UCHAR BBPR3 = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitAsicFromEEPROM\n"));
+ for(i = 3; i < NUM_EEPROM_BBP_PARMS; i++)
+ {
+ UCHAR BbpRegIdx, BbpValue;
+
+ if ((pAd->EEPROMDefaultValue[i] != 0xFFFF) && (pAd->EEPROMDefaultValue[i] != 0))
+ {
+ BbpRegIdx = (UCHAR)(pAd->EEPROMDefaultValue[i] >> 8);
+ BbpValue = (UCHAR)(pAd->EEPROMDefaultValue[i] & 0xff);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BbpRegIdx, BbpValue);
+ }
+ }
+
+ Antenna.word = pAd->EEPROMDefaultValue[0];
+ if (Antenna.word == 0xFFFF)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("E2PROM error, hard code as 0x%04x\n", Antenna.word));
+ BUG_ON(Antenna.word == 0xFFFF);
+ }
+ pAd->Mlme.RealRxPath = (UCHAR) Antenna.field.RxPath;
+ pAd->RfIcType = (UCHAR) Antenna.field.RfIcType;
+
+ DBGPRINT(RT_DEBUG_WARN, ("pAd->RfIcType = %d, RealRxPath=%d, TxPath = %d\n", pAd->RfIcType, pAd->Mlme.RealRxPath,Antenna.field.TxPath));
+
+ // Save the antenna for future use
+ pAd->Antenna.word = Antenna.word;
+
+ NicConfig2.word = pAd->EEPROMDefaultValue[1];
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((NicConfig2.word & 0x00ff) == 0xff)
+ {
+ NicConfig2.word &= 0xff00;
+ }
+
+ if ((NicConfig2.word >> 8) == 0xff)
+ {
+ NicConfig2.word &= 0x00ff;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Save the antenna for future use
+ pAd->NicConfig2.word = NicConfig2.word;
+
+ // set default antenna as main
+ if (pAd->RfIcType == RFIC_3020)
+ AsicSetRxAnt(pAd, pAd->RxAnt.Pair1PrimaryRxAnt);
+
+ //
+ // Send LED Setting to MCU.
+ //
+ if (pAd->LedCntl.word == 0xFF)
+ {
+ pAd->LedCntl.word = 0x01;
+ pAd->Led1 = 0x5555;
+ pAd->Led2 = 0x2221;
+
+#ifdef RT2870
+ pAd->Led3 = 0x5627;
+#endif // RT2870 //
+ }
+
+ AsicSendCommandToMcu(pAd, 0x52, 0xff, (UCHAR)pAd->Led1, (UCHAR)(pAd->Led1 >> 8));
+ AsicSendCommandToMcu(pAd, 0x53, 0xff, (UCHAR)pAd->Led2, (UCHAR)(pAd->Led2 >> 8));
+ AsicSendCommandToMcu(pAd, 0x54, 0xff, (UCHAR)pAd->Led3, (UCHAR)(pAd->Led3 >> 8));
+ pAd->LedIndicatorStregth = 0xFF;
+ RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, before link up
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Read Hardware controlled Radio state enable bit
+ if (NicConfig2.field.HardwareRadioControl == 1)
+ {
+ pAd->StaCfg.bHardwareRadio = TRUE;
+
+ // Read GPIO pin2 as Hardware controlled radio state
+ RTMP_IO_READ32(pAd, GPIO_CTRL_CFG, &data);
+ if ((data & 0x04) == 0)
+ {
+ pAd->StaCfg.bHwRadio = FALSE;
+ pAd->StaCfg.bRadio = FALSE;
+// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+ }
+ }
+ else
+ pAd->StaCfg.bHardwareRadio = FALSE;
+
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+ RTMPSetLED(pAd, LED_RADIO_OFF);
+ }
+ else
+ {
+ RTMPSetLED(pAd, LED_RADIO_ON);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Turn off patching for cardbus controller
+ if (NicConfig2.field.CardbusAcceleration == 1)
+ {
+// pAd->bTest1 = TRUE;
+ }
+
+ if (NicConfig2.field.DynamicTxAgcControl == 1)
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = TRUE;
+ else
+ pAd->bAutoTxAgcA = pAd->bAutoTxAgcG = FALSE;
+ //
+ // Since BBP has been progamed, to make sure BBP setting will be
+ // upate inside of AsicAntennaSelect, so reset to UNKNOWN_BAND!!
+ //
+ pAd->CommonCfg.BandState = UNKNOWN_BAND;
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BBPR3);
+ BBPR3 &= (~0x18);
+ if(pAd->Antenna.field.RxPath == 3)
+ {
+ BBPR3 |= (0x10);
+ }
+ else if(pAd->Antenna.field.RxPath == 2)
+ {
+ BBPR3 |= (0x8);
+ }
+ else if(pAd->Antenna.field.RxPath == 1)
+ {
+ BBPR3 |= (0x0);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BBPR3);
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Handle the difference when 1T
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BBPR1);
+ if(pAd->Antenna.field.TxPath == 1)
+ {
+ BBPR1 &= (~0x18);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BBPR1);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Use Hw Radio Control Pin=%d; if used Pin=%d;\n", pAd->CommonCfg.bHardwareRadio, pAd->CommonCfg.bHardwareRadio));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("TxPath = %d, RxPath = %d, RFIC=%d, Polar+LED mode=%x\n", pAd->Antenna.field.TxPath, pAd->Antenna.field.RxPath, pAd->RfIcType, pAd->LedCntl.word));
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitAsicFromEEPROM\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Initialize NIC hardware
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS NICInitializeAdapter(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset)
+{
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ WPDMA_GLO_CFG_STRUC GloCfg;
+// INT_MASK_CSR_STRUC IntMask;
+ ULONG i =0, j=0;
+ AC_TXOP_CSR0_STRUC csr0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAdapter\n"));
+
+ // 3. Set DMA global configuration except TX_DMA_EN and RX_DMA_EN bits:
+retry:
+ i = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, WPDMA_GLO_CFG, &GloCfg.word);
+ if ((GloCfg.field.TxDMABusy == 0) && (GloCfg.field.RxDMABusy == 0))
+ break;
+
+ RTMPusecDelay(1000);
+ i++;
+ }while ( i<100);
+ DBGPRINT(RT_DEBUG_TRACE, ("<== DMA offset 0x208 = 0x%x\n", GloCfg.word));
+ GloCfg.word &= 0xff0;
+ GloCfg.field.EnTXWriteBackDDONE =1;
+ RTMP_IO_WRITE32(pAd, WPDMA_GLO_CFG, GloCfg.word);
+
+ // Record HW Beacon offset
+ pAd->BeaconOffset[0] = HW_BEACON_BASE0;
+ pAd->BeaconOffset[1] = HW_BEACON_BASE1;
+ pAd->BeaconOffset[2] = HW_BEACON_BASE2;
+ pAd->BeaconOffset[3] = HW_BEACON_BASE3;
+ pAd->BeaconOffset[4] = HW_BEACON_BASE4;
+ pAd->BeaconOffset[5] = HW_BEACON_BASE5;
+ pAd->BeaconOffset[6] = HW_BEACON_BASE6;
+ pAd->BeaconOffset[7] = HW_BEACON_BASE7;
+
+ //
+ // write all shared Ring's base address into ASIC
+ //
+
+ // asic simulation sequence put this ahead before loading firmware.
+ // pbf hardware reset
+
+ // Initialze ASIC for TX & Rx operation
+ if (NICInitializeAsic(pAd , bHardReset) != NDIS_STATUS_SUCCESS)
+ {
+ if (j++ == 0)
+ {
+ NICLoadFirmware(pAd);
+ goto retry;
+ }
+ return NDIS_STATUS_FAILURE;
+ }
+
+
+
+
+ // WMM parameter
+ csr0.word = 0;
+ RTMP_IO_WRITE32(pAd, WMM_TXOP0_CFG, csr0.word);
+ if (pAd->CommonCfg.PhyMode == PHY_11B)
+ {
+ csr0.field.Ac0Txop = 192; // AC_VI: 192*32us ~= 6ms
+ csr0.field.Ac1Txop = 96; // AC_VO: 96*32us ~= 3ms
+ }
+ else
+ {
+ csr0.field.Ac0Txop = 96; // AC_VI: 96*32us ~= 3ms
+ csr0.field.Ac1Txop = 48; // AC_VO: 48*32us ~= 1.5ms
+ }
+ RTMP_IO_WRITE32(pAd, WMM_TXOP1_CFG, csr0.word);
+
+
+
+
+ // reset action
+ // Load firmware
+ // Status = NICLoadFirmware(pAd);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAdapter\n"));
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Initialize ASIC
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS NICInitializeAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset)
+{
+ ULONG Index = 0;
+ UCHAR R0 = 0xff;
+ UINT32 MacCsr12 = 0, Counter = 0;
+#ifdef RT2870
+ UINT32 MacCsr0 = 0;
+ NTSTATUS Status;
+ UCHAR Value = 0xff;
+#endif // RT2870 //
+#ifdef RT30xx
+ UINT32 eFuseCtrl;
+#endif // RT30xx //
+ USHORT KeyIdx;
+ INT i,apidx;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICInitializeAsic\n"));
+
+
+#ifdef RT2870
+ //
+ // Make sure MAC gets ready after NICLoadFirmware().
+ //
+ Index = 0;
+
+ //To avoid hang-on issue when interface up in kernel 2.4,
+ //we use a local variable "MacCsr0" instead of using "pAd->MACVersion" directly.
+ do
+ {
+ RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+
+ if ((MacCsr0 != 0x00) && (MacCsr0 != 0xFFFFFFFF))
+ break;
+
+ RTMPusecDelay(10);
+ } while (Index++ < 100);
+
+ pAd->MACVersion = MacCsr0;
+ DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+ // turn on bit13 (set to zero) after rt2860D. This is to solve high-current issue.
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacCsr12);
+ MacCsr12 &= (~0x2000);
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, MacCsr12);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x3);
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, 0x0);
+ Status = RTUSBVenderReset(pAd);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+ // Initialize MAC register to default value
+ for(Index=0; Index<NUM_MAC_REG_PARMS; Index++)
+ {
+#ifdef RT3070
+ if ((MACRegTable[Index].Register == TX_SW_CFG0) && (IS_RT3070(pAd) || IS_RT3071(pAd)))
+ {
+ MACRegTable[Index].Value = 0x00000400;
+ }
+#endif // RT3070 //
+ RTMP_IO_WRITE32(pAd, (USHORT)MACRegTable[Index].Register, MACRegTable[Index].Value);
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ for (Index = 0; Index < NUM_STA_MAC_REG_PARMS; Index++)
+ {
+ RTMP_IO_WRITE32(pAd, (USHORT)STAMACRegTable[Index].Register, STAMACRegTable[Index].Value);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+
+#ifdef RT30xx
+ // Initialize RT3070 serial MAc registers which is different from RT2870 serial
+ if (IS_RT3090(pAd))
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+
+ // RT3071 version E has fixed this issue
+ if ((pAd->MACVersion & 0xffff) < 0x0211)
+ {
+ if (pAd->NicConfig2.field.DACTestBit == 1)
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0F); // To fix throughput drop drastically
+ }
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x0);
+ }
+ }
+ else if (IS_RT3070(pAd))
+ {
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG1, 0);
+ RTMP_IO_WRITE32(pAd, TX_SW_CFG2, 0x1F); // To fix throughput drop drastically
+ }
+#endif // RT30xx //
+
+ //
+ // Before program BBP, we need to wait BBP/RF get wake up.
+ //
+ Index = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, MAC_STATUS_CFG, &MacCsr12);
+
+ if ((MacCsr12 & 0x03) == 0) // if BB.RF is stable
+ break;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Check MAC_STATUS_CFG = Busy = %x\n", MacCsr12));
+ RTMPusecDelay(1000);
+ } while (Index++ < 100);
+
+ // The commands to firmware should be after these commands, these commands will init firmware
+ // PCI and USB are not the same because PCI driver needs to wait for PCI bus ready
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0); // initialize BBP R/W access agent
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+ RTMPusecDelay(1000);
+
+ // Read BBP register, make sure BBP is up and running before write new data
+ Index = 0;
+ do
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R0, &R0);
+ DBGPRINT(RT_DEBUG_TRACE, ("BBP version = %x\n", R0));
+ } while ((++Index < 20) && ((R0 == 0xff) || (R0 == 0x00)));
+ //ASSERT(Index < 20); //this will cause BSOD on Check-build driver
+
+ if ((R0 == 0xff) || (R0 == 0x00))
+ return NDIS_STATUS_FAILURE;
+
+ // Initialize BBP register to default value
+ for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, BBPRegTable[Index].Value);
+ }
+
+ // for rt2860E and after, init BBP_R84 with 0x19. This is for extension channel overlapping IOT.
+ // RT3090 should not program BBP R84 to 0x19, otherwise TX will block.
+ if (((pAd->MACVersion&0xffff) != 0x0101) && (!IS_RT30xx(pAd)))
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R84, 0x19);
+
+// add by johnli, RF power sequence setup
+#ifdef RT30xx
+ if (IS_RT30xx(pAd))
+ { //update for RT3070/71/72/90/91/92.
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R79, 0x13);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R80, 0x05);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R81, 0x33);
+ }
+
+ if (IS_RT3090(pAd))
+ {
+ UCHAR bbpreg=0;
+
+ // enable DC filter
+ if ((pAd->MACVersion & 0xffff) >= 0x0211)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R103, 0xc0);
+ }
+
+ // improve power consumption
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R138, &bbpreg);
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ // turn off tx DAC_1
+ bbpreg = (bbpreg | 0x20);
+ }
+
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ // turn off tx ADC_1
+ bbpreg &= (~0x2);
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R138, bbpreg);
+
+ // improve power consumption in RT3071 Ver.E
+ if ((pAd->MACVersion & 0xffff) >= 0x0211)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R31, &bbpreg);
+ bbpreg &= (~0x3);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R31, bbpreg);
+ }
+ }
+#endif // RT30xx //
+// end johnli
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x12);
+ }
+
+ if (pAd->MACVersion >= RALINK_2880E_VERSION && pAd->MACVersion < RALINK_3070_VERSION) // 3*3
+ {
+ // enlarge MAX_LEN_CFG
+ UINT32 csr;
+ RTMP_IO_READ32(pAd, MAX_LEN_CFG, &csr);
+ csr &= 0xFFF;
+ csr |= 0x2000;
+ RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, csr);
+ }
+
+#ifdef RT2870
+{
+ UCHAR MAC_Value[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0,0};
+
+ //Initialize WCID table
+ Value = 0xff;
+ for(Index =0 ;Index < 254;Index++)
+ {
+ RTUSBMultiWrite(pAd, (USHORT)(MAC_WCID_BASE + Index * 8), MAC_Value, 8);
+ }
+}
+#endif // RT2870 //
+
+ // Add radio off control
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+// RTMP_IO_WRITE32(pAd, PWR_PIN_CFG, 0x00001818);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set Radio Off\n"));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Clear raw counters
+ RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
+
+ // ASIC will keep garbage value after boot
+ // Clear all seared key table when initial
+ // This routine can be ignored in radio-ON/OFF operation.
+ if (bHardReset)
+ {
+ for (KeyIdx = 0; KeyIdx < 4; KeyIdx++)
+ {
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE + 4*KeyIdx, 0);
+ }
+
+ // Clear all pairwise key table when initial
+ for (KeyIdx = 0; KeyIdx < 256; KeyIdx++)
+ {
+ RTMP_IO_WRITE32(pAd, MAC_WCID_ATTRIBUTE_BASE + (KeyIdx * HW_WCID_ATTRI_SIZE), 1);
+ }
+ }
+
+ // assert HOST ready bit
+// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x0); // 2004-09-14 asked by Mark
+// RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x4);
+
+ // It isn't necessary to clear this space when not hard reset.
+ if (bHardReset == TRUE)
+ {
+ // clear all on-chip BEACON frame space
+ for (apidx = 0; apidx < HW_BEACON_MAX_COUNT; apidx++)
+ {
+ for (i = 0; i < HW_BEACON_OFFSET>>2; i+=4)
+ RTMP_IO_WRITE32(pAd, pAd->BeaconOffset[apidx] + i, 0x00);
+ }
+ }
+#ifdef RT2870
+ AsicDisableSync(pAd);
+ // Clear raw counters
+ RTMP_IO_READ32(pAd, RX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, RX_STA_CNT2, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &Counter);
+ RTMP_IO_READ32(pAd, TX_STA_CNT2, &Counter);
+ // Default PCI clock cycle per ms is different as default setting, which is based on PCI.
+ RTMP_IO_READ32(pAd, USB_CYC_CFG, &Counter);
+ Counter&=0xffffff00;
+ Counter|=0x000001e;
+ RTMP_IO_WRITE32(pAd, USB_CYC_CFG, Counter);
+#endif // RT2870 //
+#ifdef RT30xx
+ pAd->bUseEfuse=FALSE;
+ RTMP_IO_READ32(pAd, EFUSE_CTRL, &eFuseCtrl);
+ pAd->bUseEfuse = ( (eFuseCtrl & 0x80000000) == 0x80000000) ? 1 : 0;
+ if(pAd->bUseEfuse)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("NVM is Efuse\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("NVM is EEPROM\n"));
+
+ }
+#endif // RT30xx //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // for rt2860E and after, init TXOP_CTRL_CFG with 0x583f. This is for extension channel overlapping IOT.
+ if ((pAd->MACVersion&0xffff) != 0x0101)
+ RTMP_IO_WRITE32(pAd, TXOP_CTRL_CFG, 0x583f);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICInitializeAsic\n"));
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Reset NIC Asics
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+ Reset NIC to initial state AS IS system boot up time.
+
+ ========================================================================
+*/
+VOID NICIssueReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 Value = 0;
+ DBGPRINT(RT_DEBUG_TRACE, ("--> NICIssueReset\n"));
+
+ // Abort Tx, prevent ASIC from writing to Host memory
+ //RTMP_IO_WRITE32(pAd, TX_CNTL_CSR, 0x001f0000);
+
+ // Disable Rx, register value supposed will remain after reset
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= (0xfffffff3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Issue reset and clear from reset state
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x03); // 2004-09-17 change from 0x01
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x00);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- NICIssueReset\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check ASIC registers and find any reason the system might hang
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+BOOLEAN NICCheckForHang(
+ IN PRTMP_ADAPTER pAd)
+{
+ return (FALSE);
+}
+
+VOID NICUpdateFifoStaCounters(
+ IN PRTMP_ADAPTER pAd)
+{
+ TX_STA_FIFO_STRUC StaFifo;
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR i = 0;
+ UCHAR pid = 0, wcid = 0;
+ CHAR reTry;
+ UCHAR succMCS;
+
+#ifdef RALINK_ATE
+ /* Nothing to do in ATE mode */
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ do
+ {
+ RTMP_IO_READ32(pAd, TX_STA_FIFO, &StaFifo.word);
+
+ if (StaFifo.field.bValid == 0)
+ break;
+
+ wcid = (UCHAR)StaFifo.field.wcid;
+
+
+ /* ignore NoACK and MGMT frame use 0xFF as WCID */
+ if ((StaFifo.field.TxAckRequired == 0) || (wcid >= MAX_LEN_OF_MAC_TABLE))
+ {
+ i++;
+ continue;
+ }
+
+ /* PID store Tx MCS Rate */
+ pid = (UCHAR)StaFifo.field.PidType;
+
+ pEntry = &pAd->MacTab.Content[wcid];
+
+ pEntry->DebugFIFOCount++;
+
+#ifdef DOT11_N_SUPPORT
+ if (StaFifo.field.TxBF) // 3*3
+ pEntry->TxBFCount++;
+#endif // DOT11_N_SUPPORT //
+
+#ifdef UAPSD_AP_SUPPORT
+ UAPSD_SP_AUE_Handle(pAd, pEntry, StaFifo.field.TxSuccess);
+#endif // UAPSD_AP_SUPPORT //
+
+ if (!StaFifo.field.TxSuccess)
+ {
+ pEntry->FIFOCount++;
+ pEntry->OneSecTxFailCount++;
+
+ if (pEntry->FIFOCount >= 1)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("#"));
+#ifdef DOT11_N_SUPPORT
+ pEntry->NoBADataCountDown = 64;
+#endif // DOT11_N_SUPPORT //
+
+ if(pEntry->PsMode == PWR_ACTIVE)
+ {
+#ifdef DOT11_N_SUPPORT
+ int tid;
+ for (tid=0; tid<NUM_OF_TID; tid++)
+ {
+ BAOriSessionTearDown(pAd, pEntry->Aid, tid, FALSE, FALSE);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // Update the continuous transmission counter except PS mode
+ pEntry->ContinueTxFailCnt++;
+ }
+ else
+ {
+ // Clear the FIFOCount when sta in Power Save mode. Basically we assume
+ // this tx error happened due to sta just go to sleep.
+ pEntry->FIFOCount = 0;
+ pEntry->ContinueTxFailCnt = 0;
+ }
+ //pEntry->FIFOCount = 0;
+ }
+ //pEntry->bSendBAR = TRUE;
+ }
+ else
+ {
+#ifdef DOT11_N_SUPPORT
+ if ((pEntry->PsMode != PWR_SAVE) && (pEntry->NoBADataCountDown > 0))
+ {
+ pEntry->NoBADataCountDown--;
+ if (pEntry->NoBADataCountDown==0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("@\n"));
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+ pEntry->FIFOCount = 0;
+ pEntry->OneSecTxNoRetryOkCount++;
+ // update NoDataIdleCount when sucessful send packet to STA.
+ pEntry->NoDataIdleCount = 0;
+ pEntry->ContinueTxFailCnt = 0;
+ }
+
+ succMCS = StaFifo.field.SuccessRate & 0x7F;
+
+ reTry = pid - succMCS;
+
+ if (StaFifo.field.TxSuccess)
+ {
+ pEntry->TXMCSExpected[pid]++;
+ if (pid == succMCS)
+ {
+ pEntry->TXMCSSuccessful[pid]++;
+ }
+ else
+ {
+ pEntry->TXMCSAutoFallBack[pid][succMCS]++;
+ }
+ }
+ else
+ {
+ pEntry->TXMCSFailed[pid]++;
+ }
+
+ if (reTry > 0)
+ {
+ if ((pid >= 12) && succMCS <=7)
+ {
+ reTry -= 4;
+ }
+ pEntry->OneSecTxRetryOkCount += reTry;
+ }
+
+ i++;
+ // ASIC store 16 stack
+ } while ( i < (2*TX_RING_SIZE) );
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Read statistical counters from hardware registers and record them
+ in software variables for later on query
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID NICUpdateRawCounters(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 OldValue;//, Value2;
+ //ULONG PageSum, OneSecTransmitCount;
+ //ULONG TxErrorRatio, Retry, Fail;
+ RX_STA_CNT0_STRUC RxStaCnt0;
+ RX_STA_CNT1_STRUC RxStaCnt1;
+ RX_STA_CNT2_STRUC RxStaCnt2;
+ TX_STA_CNT0_STRUC TxStaCnt0;
+ TX_STA_CNT1_STRUC StaTx1;
+ TX_STA_CNT2_STRUC StaTx2;
+ TX_AGG_CNT_STRUC TxAggCnt;
+ TX_AGG_CNT0_STRUC TxAggCnt0;
+ TX_AGG_CNT1_STRUC TxAggCnt1;
+ TX_AGG_CNT2_STRUC TxAggCnt2;
+ TX_AGG_CNT3_STRUC TxAggCnt3;
+ TX_AGG_CNT4_STRUC TxAggCnt4;
+ TX_AGG_CNT5_STRUC TxAggCnt5;
+ TX_AGG_CNT6_STRUC TxAggCnt6;
+ TX_AGG_CNT7_STRUC TxAggCnt7;
+
+ RTMP_IO_READ32(pAd, RX_STA_CNT0, &RxStaCnt0.word);
+ RTMP_IO_READ32(pAd, RX_STA_CNT2, &RxStaCnt2.word);
+
+ {
+ RTMP_IO_READ32(pAd, RX_STA_CNT1, &RxStaCnt1.word);
+ // Update RX PLCP error counter
+ pAd->PrivateInfo.PhyRxErrCnt += RxStaCnt1.field.PlcpErr;
+ // Update False CCA counter
+ pAd->RalinkCounters.OneSecFalseCCACnt += RxStaCnt1.field.FalseCca;
+ }
+
+ // Update FCS counters
+ OldValue= pAd->WlanCounters.FCSErrorCount.u.LowPart;
+ pAd->WlanCounters.FCSErrorCount.u.LowPart += (RxStaCnt0.field.CrcErr); // >> 7);
+ if (pAd->WlanCounters.FCSErrorCount.u.LowPart < OldValue)
+ pAd->WlanCounters.FCSErrorCount.u.HighPart++;
+
+ // Add FCS error count to private counters
+ pAd->RalinkCounters.OneSecRxFcsErrCnt += RxStaCnt0.field.CrcErr;
+ OldValue = pAd->RalinkCounters.RealFcsErrCount.u.LowPart;
+ pAd->RalinkCounters.RealFcsErrCount.u.LowPart += RxStaCnt0.field.CrcErr;
+ if (pAd->RalinkCounters.RealFcsErrCount.u.LowPart < OldValue)
+ pAd->RalinkCounters.RealFcsErrCount.u.HighPart++;
+
+ // Update Duplicate Rcv check
+ pAd->RalinkCounters.DuplicateRcv += RxStaCnt2.field.RxDupliCount;
+ pAd->WlanCounters.FrameDuplicateCount.u.LowPart += RxStaCnt2.field.RxDupliCount;
+ // Update RX Overflow counter
+ pAd->Counters8023.RxNoBuffer += (RxStaCnt2.field.RxFifoOverflowCount);
+
+ //pAd->RalinkCounters.RxCount = 0;
+#ifdef RT2870
+ if (pAd->RalinkCounters.RxCount != pAd->watchDogRxCnt)
+ {
+ pAd->watchDogRxCnt = pAd->RalinkCounters.RxCount;
+ pAd->watchDogRxOverFlowCnt = 0;
+ }
+ else
+ {
+ if (RxStaCnt2.field.RxFifoOverflowCount)
+ pAd->watchDogRxOverFlowCnt++;
+ else
+ pAd->watchDogRxOverFlowCnt = 0;
+ }
+#endif // RT2870 //
+
+
+ //if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) ||
+ // (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_TX_RATE_SWITCH_ENABLED) && (pAd->MacTab.Size != 1)))
+ if (!pAd->bUpdateBcnCntDone)
+ {
+ // Update BEACON sent count
+ RTMP_IO_READ32(pAd, TX_STA_CNT0, &TxStaCnt0.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT1, &StaTx1.word);
+ RTMP_IO_READ32(pAd, TX_STA_CNT2, &StaTx2.word);
+ pAd->RalinkCounters.OneSecBeaconSentCnt += TxStaCnt0.field.TxBeaconCount;
+ pAd->RalinkCounters.OneSecTxRetryOkCount += StaTx1.field.TxRetransmit;
+ pAd->RalinkCounters.OneSecTxNoRetryOkCount += StaTx1.field.TxSuccess;
+ pAd->RalinkCounters.OneSecTxFailCount += TxStaCnt0.field.TxFailCount;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart += StaTx1.field.TxSuccess;
+ pAd->WlanCounters.RetryCount.u.LowPart += StaTx1.field.TxRetransmit;
+ pAd->WlanCounters.FailedCount.u.LowPart += TxStaCnt0.field.TxFailCount;
+ }
+
+ //if (pAd->bStaFifoTest == TRUE)
+ {
+ RTMP_IO_READ32(pAd, TX_AGG_CNT, &TxAggCnt.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT0, &TxAggCnt0.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT1, &TxAggCnt1.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT2, &TxAggCnt2.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT3, &TxAggCnt3.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT4, &TxAggCnt4.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT5, &TxAggCnt5.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT6, &TxAggCnt6.word);
+ RTMP_IO_READ32(pAd, TX_AGG_CNT7, &TxAggCnt7.word);
+ pAd->RalinkCounters.TxAggCount += TxAggCnt.field.AggTxCount;
+ pAd->RalinkCounters.TxNonAggCount += TxAggCnt.field.NonAggTxCount;
+ pAd->RalinkCounters.TxAgg1MPDUCount += TxAggCnt0.field.AggSize1Count;
+ pAd->RalinkCounters.TxAgg2MPDUCount += TxAggCnt0.field.AggSize2Count;
+
+ pAd->RalinkCounters.TxAgg3MPDUCount += TxAggCnt1.field.AggSize3Count;
+ pAd->RalinkCounters.TxAgg4MPDUCount += TxAggCnt1.field.AggSize4Count;
+ pAd->RalinkCounters.TxAgg5MPDUCount += TxAggCnt2.field.AggSize5Count;
+ pAd->RalinkCounters.TxAgg6MPDUCount += TxAggCnt2.field.AggSize6Count;
+
+ pAd->RalinkCounters.TxAgg7MPDUCount += TxAggCnt3.field.AggSize7Count;
+ pAd->RalinkCounters.TxAgg8MPDUCount += TxAggCnt3.field.AggSize8Count;
+ pAd->RalinkCounters.TxAgg9MPDUCount += TxAggCnt4.field.AggSize9Count;
+ pAd->RalinkCounters.TxAgg10MPDUCount += TxAggCnt4.field.AggSize10Count;
+
+ pAd->RalinkCounters.TxAgg11MPDUCount += TxAggCnt5.field.AggSize11Count;
+ pAd->RalinkCounters.TxAgg12MPDUCount += TxAggCnt5.field.AggSize12Count;
+ pAd->RalinkCounters.TxAgg13MPDUCount += TxAggCnt6.field.AggSize13Count;
+ pAd->RalinkCounters.TxAgg14MPDUCount += TxAggCnt6.field.AggSize14Count;
+
+ pAd->RalinkCounters.TxAgg15MPDUCount += TxAggCnt7.field.AggSize15Count;
+ pAd->RalinkCounters.TxAgg16MPDUCount += TxAggCnt7.field.AggSize16Count;
+
+ // Calculate the transmitted A-MPDU count
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += TxAggCnt0.field.AggSize1Count;
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt0.field.AggSize2Count / 2);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize3Count / 3);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt1.field.AggSize4Count / 4);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize5Count / 5);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt2.field.AggSize6Count / 6);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize7Count / 7);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt3.field.AggSize8Count / 8);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize9Count / 9);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt4.field.AggSize10Count / 10);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize11Count / 11);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt5.field.AggSize12Count / 12);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize13Count / 13);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt6.field.AggSize14Count / 14);
+
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize15Count / 15);
+ pAd->RalinkCounters.TransmittedAMPDUCount.u.LowPart += (TxAggCnt7.field.AggSize16Count / 16);
+ }
+
+#ifdef DBG_DIAGNOSE
+ {
+ RtmpDiagStruct *pDiag;
+ COUNTER_RALINK *pRalinkCounters;
+ UCHAR ArrayCurIdx, i;
+
+ pDiag = &pAd->DiagStruct;
+ pRalinkCounters = &pAd->RalinkCounters;
+ ArrayCurIdx = pDiag->ArrayCurIdx;
+
+ if (pDiag->inited == 0)
+ {
+ NdisZeroMemory(pDiag, sizeof(struct _RtmpDiagStrcut_));
+ pDiag->ArrayStartIdx = pDiag->ArrayCurIdx = 0;
+ pDiag->inited = 1;
+ }
+ else
+ {
+ // Tx
+ pDiag->TxFailCnt[ArrayCurIdx] = TxStaCnt0.field.TxFailCount;
+ pDiag->TxAggCnt[ArrayCurIdx] = TxAggCnt.field.AggTxCount;
+ pDiag->TxNonAggCnt[ArrayCurIdx] = TxAggCnt.field.NonAggTxCount;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][0] = TxAggCnt0.field.AggSize1Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][1] = TxAggCnt0.field.AggSize2Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][2] = TxAggCnt1.field.AggSize3Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][3] = TxAggCnt1.field.AggSize4Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][4] = TxAggCnt2.field.AggSize5Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][5] = TxAggCnt2.field.AggSize6Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][6] = TxAggCnt3.field.AggSize7Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][7] = TxAggCnt3.field.AggSize8Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][8] = TxAggCnt4.field.AggSize9Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][9] = TxAggCnt4.field.AggSize10Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][10] = TxAggCnt5.field.AggSize11Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][11] = TxAggCnt5.field.AggSize12Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][12] = TxAggCnt6.field.AggSize13Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][13] = TxAggCnt6.field.AggSize14Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][14] = TxAggCnt7.field.AggSize15Count;
+ pDiag->TxAMPDUCnt[ArrayCurIdx][15] = TxAggCnt7.field.AggSize16Count;
+
+ pDiag->RxCrcErrCnt[ArrayCurIdx] = RxStaCnt0.field.CrcErr;
+
+ INC_RING_INDEX(pDiag->ArrayCurIdx, DIAGNOSE_TIME);
+ ArrayCurIdx = pDiag->ArrayCurIdx;
+ for (i =0; i < 9; i++)
+ {
+ pDiag->TxDescCnt[ArrayCurIdx][i]= 0;
+ pDiag->TxSWQueCnt[ArrayCurIdx][i] =0;
+ pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
+ pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
+ }
+ pDiag->TxDataCnt[ArrayCurIdx] = 0;
+ pDiag->TxFailCnt[ArrayCurIdx] = 0;
+ pDiag->RxDataCnt[ArrayCurIdx] = 0;
+ pDiag->RxCrcErrCnt[ArrayCurIdx] = 0;
+// for (i = 9; i < 16; i++)
+ for (i = 9; i < 24; i++) // 3*3
+ {
+ pDiag->TxDescCnt[ArrayCurIdx][i] = 0;
+ pDiag->TxMcsCnt[ArrayCurIdx][i] = 0;
+ pDiag->RxMcsCnt[ArrayCurIdx][i] = 0;
+}
+
+ if (pDiag->ArrayCurIdx == pDiag->ArrayStartIdx)
+ INC_RING_INDEX(pDiag->ArrayStartIdx, DIAGNOSE_TIME);
+ }
+
+ }
+#endif // DBG_DIAGNOSE //
+
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Reset NIC from error
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+ Reset NIC from error state
+
+ ========================================================================
+*/
+VOID NICResetFromError(
+ IN PRTMP_ADAPTER pAd)
+{
+ // Reset BBP (according to alex, reset ASIC will force reset BBP
+ // Therefore, skip the reset BBP
+ // RTMP_IO_WRITE32(pAd, MAC_CSR1, 0x2);
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x1);
+ // Remove ASIC from reset state
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0x0);
+
+ NICInitializeAdapter(pAd, FALSE);
+ NICInitAsicFromEEPROM(pAd);
+
+ // Switch to current channel, since during reset process, the connection should remains on.
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ erase 8051 firmware image in MAC ASIC
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+VOID NICEraseFirmware(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+
+ for(i=0; i<MAX_FIRMWARE_IMAGE_SIZE; i+=4)
+ RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, 0);
+
+}/* End of NICEraseFirmware */
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Load 8051 firmware RT2561.BIN file into MAC ASIC
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ NDIS_STATUS_SUCCESS firmware image load ok
+ NDIS_STATUS_FAILURE image not found
+
+ IRQL = PASSIVE_LEVEL
+
+ ========================================================================
+*/
+NDIS_STATUS NICLoadFirmware(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef BIN_IN_FILE
+#define NICLF_DEFAULT_USE() \
+ flg_default_firm_use = TRUE; \
+ printk("%s - Use default firmware!\n", __FUNCTION__);
+
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PUCHAR src;
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid, i;
+ mm_segment_t orgfs;
+ PUCHAR pFirmwareImage;
+ UINT FileLength = 0;
+ UINT32 MacReg;
+ ULONG Index;
+ ULONG firm;
+ BOOLEAN flg_default_firm_use = FALSE;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> %s\n", __FUNCTION__));
+
+ /* init */
+ pFirmwareImage = NULL;
+ src = RTMP_FIRMWARE_FILE_NAME;
+
+ /* save uid and gid used for filesystem access.
+ set user and group to 0 (root) */
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid = current->fsgid = 0;
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ pAd->FirmwareVersion = (FIRMWARE_MAJOR_VERSION << 8) + \
+ FIRMWARE_MINOR_VERSION;
+
+
+ /* allocate firmware buffer */
+ pFirmwareImage = kmalloc(MAX_FIRMWARE_IMAGE_SIZE, MEM_ALLOC_FLAG);
+ if (pFirmwareImage == NULL)
+ {
+ /* allocate fail, use default firmware array in firmware.h */
+ printk("%s - Allocate memory fail!\n", __FUNCTION__);
+ NICLF_DEFAULT_USE();
+ }
+ else
+ {
+ /* allocate ok! zero the firmware buffer */
+ memset(pFirmwareImage, 0x00, MAX_FIRMWARE_IMAGE_SIZE);
+ } /* End of if */
+
+
+ /* if ok, read firmware file from *.bin file */
+ if (flg_default_firm_use == FALSE)
+ {
+ do
+ {
+ /* open the bin file */
+ srcf = filp_open(src, O_RDONLY, 0);
+
+ if (IS_ERR(srcf))
+ {
+ printk("%s - Error %ld opening %s\n",
+ __FUNCTION__, -PTR_ERR(srcf), src);
+ NICLF_DEFAULT_USE();
+ break;
+ } /* End of if */
+
+ /* the object must have a read method */
+ if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
+ {
+ printk("%s - %s does not have a write method\n", __FUNCTION__, src);
+ NICLF_DEFAULT_USE();
+ break;
+ } /* End of if */
+
+ /* read the firmware from the file *.bin */
+ FileLength = srcf->f_op->read(srcf,
+ pFirmwareImage,
+ MAX_FIRMWARE_IMAGE_SIZE,
+ &srcf->f_pos);
+
+ if (FileLength != MAX_FIRMWARE_IMAGE_SIZE)
+ {
+ printk("%s: error file length (=%d) in RT2860AP.BIN\n",
+ __FUNCTION__, FileLength);
+ NICLF_DEFAULT_USE();
+ break;
+ }
+ else
+ {
+ PUCHAR ptr = pFirmwareImage;
+ USHORT crc = 0xffff;
+
+
+ /* calculate firmware CRC */
+ for(i=0; i<(MAX_FIRMWARE_IMAGE_SIZE-2); i++, ptr++)
+ crc = ByteCRC16(BitReverse(*ptr), crc);
+ /* End of for */
+
+ if ((pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2] != \
+ (UCHAR)BitReverse((UCHAR)(crc>>8))) ||
+ (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1] != \
+ (UCHAR)BitReverse((UCHAR)crc)))
+ {
+ /* CRC fail */
+ printk("%s: CRC = 0x%02x 0x%02x "
+ "error, should be 0x%02x 0x%02x\n",
+ __FUNCTION__,
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-2],
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-1],
+ (UCHAR)(crc>>8), (UCHAR)(crc));
+ NICLF_DEFAULT_USE();
+ break;
+ }
+ else
+ {
+ /* firmware is ok */
+ pAd->FirmwareVersion = \
+ (pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4] << 8) +
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3];
+
+ /* check if firmware version of the file is too old */
+ if ((pAd->FirmwareVersion) < \
+ ((FIRMWARE_MAJOR_VERSION << 8) +
+ FIRMWARE_MINOR_VERSION))
+ {
+ printk("%s: firmware version too old!\n", __FUNCTION__);
+ NICLF_DEFAULT_USE();
+ break;
+ } /* End of if */
+ } /* End of if */
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("NICLoadFirmware: CRC ok, ver=%d.%d\n",
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-4],
+ pFirmwareImage[MAX_FIRMWARE_IMAGE_SIZE-3]));
+ } /* End of if (FileLength == MAX_FIRMWARE_IMAGE_SIZE) */
+ break;
+ } while(TRUE);
+
+ /* close firmware file */
+ if (IS_ERR(srcf))
+ ;
+ else
+ {
+ retval = filp_close(srcf, NULL);
+ if (retval)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("--> Error %d closing %s\n", -retval, src));
+ } /* End of if */
+ } /* End of if */
+ } /* End of if */
+
+
+ /* write firmware to ASIC */
+ if (flg_default_firm_use == TRUE)
+ {
+ /* use default fimeware, free allocated buffer */
+ if (pFirmwareImage != NULL)
+ kfree(pFirmwareImage);
+ /* End of if */
+
+ /* use default *.bin array */
+ pFirmwareImage = FirmwareImage;
+ FileLength = sizeof(FirmwareImage);
+ } /* End of if */
+
+ /* enable Host program ram write selection */
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x10000);
+
+ for(i=0; i<FileLength; i+=4)
+ {
+ firm = pFirmwareImage[i] +
+ (pFirmwareImage[i+3] << 24) +
+ (pFirmwareImage[i+2] << 16) +
+ (pFirmwareImage[i+1] << 8);
+
+ RTMP_IO_WRITE32(pAd, FIRMWARE_IMAGE_BASE + i, firm);
+ } /* End of for */
+
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00000);
+ RTMP_IO_WRITE32(pAd, PBF_SYS_CTRL, 0x00001);
+
+ /* initialize BBP R/W access agent */
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, 0);
+ RTMP_IO_WRITE32(pAd, H2M_MAILBOX_CSR, 0);
+
+ if (flg_default_firm_use == FALSE)
+ {
+ /* use file firmware, free allocated buffer */
+ if (pFirmwareImage != NULL)
+ kfree(pFirmwareImage);
+ /* End of if */
+ } /* End of if */
+
+ set_fs(orgfs);
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+#else
+
+ NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ PUCHAR pFirmwareImage;
+ ULONG FileLength, Index;
+ //ULONG firm;
+ UINT32 MacReg = 0;
+ UINT32 Version = (pAd->MACVersion >> 16);
+
+ pFirmwareImage = FirmwareImage;
+ FileLength = sizeof(FirmwareImage);
+
+ // New 8k byte firmware size for RT3071/RT3072
+ //printk("Usb Chip\n");
+ if (FIRMWAREIMAGE_LENGTH == FIRMWAREIMAGE_MAX_LENGTH)
+ //The firmware image consists of two parts. One is the origianl and the other is the new.
+ //Use Second Part
+ {
+#ifdef RT2870
+ if ((Version != 0x2860) && (Version != 0x2872) && (Version != 0x3070))
+ { // Use Firmware V2.
+ //printk("KH:Use New Version,part2\n");
+ pFirmwareImage = (PUCHAR)&FirmwareImage[FIRMWAREIMAGEV1_LENGTH];
+ FileLength = FIRMWAREIMAGEV2_LENGTH;
+ }
+ else
+ {
+ //printk("KH:Use New Version,part1\n");
+ pFirmwareImage = FirmwareImage;
+ FileLength = FIRMWAREIMAGEV1_LENGTH;
+ }
+#endif // RT2870 //
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("KH: bin file should be 8KB.\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+
+ RT28XX_WRITE_FIRMWARE(pAd, pFirmwareImage, FileLength);
+
+#endif
+
+ /* check if MCU is ready */
+ Index = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, PBF_SYS_CTRL, &MacReg);
+
+ if (MacReg & 0x80)
+ break;
+
+ RTMPusecDelay(1000);
+ } while (Index++ < 1000);
+
+ if (Index >= 1000)
+ {
+ Status = NDIS_STATUS_FAILURE;
+ DBGPRINT(RT_DEBUG_ERROR, ("NICLoadFirmware: MCU is not ready\n\n\n"));
+ } /* End of if */
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("<=== %s (status=%d)\n", __FUNCTION__, Status));
+ return Status;
+} /* End of NICLoadFirmware */
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Load Tx rate switching parameters
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ NDIS_STATUS_SUCCESS firmware image load ok
+ NDIS_STATUS_FAILURE image not found
+
+ IRQL = PASSIVE_LEVEL
+
+ Rate Table Format:
+ 1. (B0: Valid Item number) (B1:Initial item from zero)
+ 2. Item Number(Dec) Mode(Hex) Current MCS(Dec) TrainUp(Dec) TrainDown(Dec)
+
+ ========================================================================
+*/
+NDIS_STATUS NICLoadRateSwitchingParams(
+ IN PRTMP_ADAPTER pAd)
+{
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ if pSrc1 all zero with length Length, return 0.
+ If not all zero, return 1
+
+ Arguments:
+ pSrc1
+
+ Return Value:
+ 1: not all zero
+ 0: all zero
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+ULONG RTMPNotAllZero(
+ IN PVOID pSrc1,
+ IN ULONG Length)
+{
+ PUCHAR pMem1;
+ ULONG Index = 0;
+
+ pMem1 = (PUCHAR) pSrc1;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ if (pMem1[Index] != 0x0)
+ {
+ break;
+ }
+ }
+
+ if (Index == Length)
+ {
+ return (0);
+ }
+ else
+ {
+ return (1);
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Compare two memory block
+
+ Arguments:
+ pSrc1 Pointer to first memory address
+ pSrc2 Pointer to second memory address
+
+ Return Value:
+ 0: memory is equal
+ 1: pSrc1 memory is larger
+ 2: pSrc2 memory is larger
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+ULONG RTMPCompareMemory(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ IN ULONG Length)
+{
+ PUCHAR pMem1;
+ PUCHAR pMem2;
+ ULONG Index = 0;
+
+ pMem1 = (PUCHAR) pSrc1;
+ pMem2 = (PUCHAR) pSrc2;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ if (pMem1[Index] > pMem2[Index])
+ return (1);
+ else if (pMem1[Index] < pMem2[Index])
+ return (2);
+ }
+
+ // Equal
+ return (0);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Zero out memory block
+
+ Arguments:
+ pSrc1 Pointer to memory address
+ Length Size
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPZeroMemory(
+ IN PVOID pSrc,
+ IN ULONG Length)
+{
+ PUCHAR pMem;
+ ULONG Index = 0;
+
+ pMem = (PUCHAR) pSrc;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ pMem[Index] = 0x00;
+ }
+}
+
+VOID RTMPFillMemory(
+ IN PVOID pSrc,
+ IN ULONG Length,
+ IN UCHAR Fill)
+{
+ PUCHAR pMem;
+ ULONG Index = 0;
+
+ pMem = (PUCHAR) pSrc;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ pMem[Index] = Fill;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy data from memory block 1 to memory block 2
+
+ Arguments:
+ pDest Pointer to destination memory address
+ pSrc Pointer to source memory address
+ Length Copy size
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPMoveMemory(
+ OUT PVOID pDest,
+ IN PVOID pSrc,
+ IN ULONG Length)
+{
+ PUCHAR pMem1;
+ PUCHAR pMem2;
+ UINT Index;
+
+ ASSERT((Length==0) || (pDest && pSrc));
+
+ pMem1 = (PUCHAR) pDest;
+ pMem2 = (PUCHAR) pSrc;
+
+ for (Index = 0; Index < Length; Index++)
+ {
+ pMem1[Index] = pMem2[Index];
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Initialize port configuration structure
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID UserCfgInit(
+ IN PRTMP_ADAPTER pAd)
+{
+// EDCA_PARM DefaultEdcaParm;
+ UINT key_index, bss_index;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit\n"));
+
+ //
+ // part I. intialize common configuration
+ //
+#ifdef RT2870
+ pAd->BulkOutReq = 0;
+
+ pAd->BulkOutComplete = 0;
+ pAd->BulkOutCompleteOther = 0;
+ pAd->BulkOutCompleteCancel = 0;
+ pAd->BulkInReq = 0;
+ pAd->BulkInComplete = 0;
+ pAd->BulkInCompleteFail = 0;
+
+ //pAd->QuickTimerP = 100;
+ //pAd->TurnAggrBulkInCount = 0;
+ pAd->bUsbTxBulkAggre = 0;
+
+ // init as unsed value to ensure driver will set to MCU once.
+ pAd->LedIndicatorStregth = 0xFF;
+
+ pAd->CommonCfg.MaxPktOneTxBulk = 2;
+ pAd->CommonCfg.TxBulkFactor = 1;
+ pAd->CommonCfg.RxBulkFactor =1;
+
+ pAd->CommonCfg.TxPower = 100; //mW
+
+ NdisZeroMemory(&pAd->CommonCfg.IOTestParm, sizeof(pAd->CommonCfg.IOTestParm));
+#endif // RT2870 //
+
+ for(key_index=0; key_index<SHARE_KEY_NUM; key_index++)
+ {
+ for(bss_index = 0; bss_index < MAX_MBSSID_NUM; bss_index++)
+ {
+ pAd->SharedKey[bss_index][key_index].KeyLen = 0;
+ pAd->SharedKey[bss_index][key_index].CipherAlg = CIPHER_NONE;
+ } /* End of for */
+ } /* End of for */
+
+ pAd->EepromAccess = FALSE;
+
+ pAd->Antenna.word = 0;
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+
+ pAd->LedCntl.word = 0;
+
+ pAd->bAutoTxAgcA = FALSE; // Default is OFF
+ pAd->bAutoTxAgcG = FALSE; // Default is OFF
+ pAd->RfIcType = RFIC_2820;
+
+ // Init timer for reset complete event
+ pAd->CommonCfg.CentralChannel = 1;
+ pAd->bForcePrintTX = FALSE;
+ pAd->bForcePrintRX = FALSE;
+ pAd->bStaFifoTest = FALSE;
+ pAd->bProtectionTest = FALSE;
+ pAd->bHCCATest = FALSE;
+ pAd->bGenOneHCCA = FALSE;
+ pAd->CommonCfg.Dsifs = 10; // in units of usec
+ pAd->CommonCfg.TxPower = 100; //mW
+ pAd->CommonCfg.TxPowerPercentage = 0xffffffff; // AUTO
+ pAd->CommonCfg.TxPowerDefault = 0xffffffff; // AUTO
+ pAd->CommonCfg.TxPreamble = Rt802_11PreambleAuto; // use Long preamble on TX by defaut
+ pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+ pAd->CommonCfg.RtsThreshold = 2347;
+ pAd->CommonCfg.FragmentThreshold = 2346;
+ pAd->CommonCfg.UseBGProtection = 0; // 0: AUTO
+ pAd->CommonCfg.bEnableTxBurst = TRUE; //0;
+ pAd->CommonCfg.PhyMode = 0xff; // unknown
+ pAd->CommonCfg.BandState = UNKNOWN_BAND;
+ pAd->CommonCfg.RadarDetect.CSPeriod = 10;
+ pAd->CommonCfg.RadarDetect.CSCount = 0;
+ pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+ pAd->CommonCfg.RadarDetect.ChMovingTime = 65;
+ pAd->CommonCfg.RadarDetect.LongPulseRadarTh = 3;
+ pAd->CommonCfg.bAPSDCapable = FALSE;
+ pAd->CommonCfg.bNeedSendTriggerFrame = FALSE;
+ pAd->CommonCfg.TriggerTimerCount = 0;
+ pAd->CommonCfg.bAPSDForcePowerSave = FALSE;
+ pAd->CommonCfg.bCountryFlag = FALSE;
+ pAd->CommonCfg.TxStream = 0;
+ pAd->CommonCfg.RxStream = 0;
+
+ NdisZeroMemory(&pAd->BeaconTxWI, sizeof(pAd->BeaconTxWI));
+
+#ifdef DOT11_N_SUPPORT
+ NdisZeroMemory(&pAd->CommonCfg.HtCapability, sizeof(pAd->CommonCfg.HtCapability));
+ pAd->HTCEnable = FALSE;
+ pAd->bBroadComHT = FALSE;
+ pAd->CommonCfg.bRdg = FALSE;
+
+#ifdef DOT11N_DRAFT3
+ pAd->CommonCfg.Dot11OBssScanPassiveDwell = dot11OBSSScanPassiveDwell; // Unit : TU. 5~1000
+ pAd->CommonCfg.Dot11OBssScanActiveDwell = dot11OBSSScanActiveDwell; // Unit : TU. 10~1000
+ pAd->CommonCfg.Dot11BssWidthTriggerScanInt = dot11BSSWidthTriggerScanInterval; // Unit : Second
+ pAd->CommonCfg.Dot11OBssScanPassiveTotalPerChannel = dot11OBSSScanPassiveTotalPerChannel; // Unit : TU. 200~10000
+ pAd->CommonCfg.Dot11OBssScanActiveTotalPerChannel = dot11OBSSScanActiveTotalPerChannel; // Unit : TU. 20~10000
+ pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor = dot11BSSWidthChannelTransactionDelayFactor;
+ pAd->CommonCfg.Dot11OBssScanActivityThre = dot11BSSScanActivityThreshold; // Unit : percentage
+ pAd->CommonCfg.Dot11BssWidthChanTranDelay = (pAd->CommonCfg.Dot11BssWidthTriggerScanInt * pAd->CommonCfg.Dot11BssWidthChanTranDelayFactor);
+#endif // DOT11N_DRAFT3 //
+
+ NdisZeroMemory(&pAd->CommonCfg.AddHTInfo, sizeof(pAd->CommonCfg.AddHTInfo));
+ pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+ pAd->CommonCfg.BACapability.field.MpduDensity = 0;
+ pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64; //32;
+ pAd->CommonCfg.BACapability.field.TxBAWinLimit = 64; //32;
+ DBGPRINT(RT_DEBUG_TRACE, ("--> UserCfgInit. BACapability = 0x%x\n", pAd->CommonCfg.BACapability.word));
+
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ BATableInit(pAd, &pAd->BATable);
+
+ pAd->CommonCfg.bExtChannelSwitchAnnouncement = 1;
+ pAd->CommonCfg.bHTProtect = 1;
+ pAd->CommonCfg.bMIMOPSEnable = TRUE;
+ pAd->CommonCfg.bBADecline = FALSE;
+ pAd->CommonCfg.bDisableReordering = FALSE;
+
+ pAd->CommonCfg.TxBASize = 7;
+
+ pAd->CommonCfg.REGBACapability.word = pAd->CommonCfg.BACapability.word;
+#endif // DOT11_N_SUPPORT //
+
+ //pAd->CommonCfg.HTPhyMode.field.BW = BW_20;
+ //pAd->CommonCfg.HTPhyMode.field.MCS = MCS_AUTO;
+ //pAd->CommonCfg.HTPhyMode.field.ShortGI = GI_800;
+ //pAd->CommonCfg.HTPhyMode.field.STBC = STBC_NONE;
+ pAd->CommonCfg.TxRate = RATE_6;
+
+ pAd->CommonCfg.MlmeTransmit.field.MCS = MCS_RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.BW = BW_20;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+
+ pAd->CommonCfg.BeaconPeriod = 100; // in mSec
+
+ //
+ // part II. intialize STA specific configuration
+ //
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_DIRECT);
+ RX_FILTER_CLEAR_FLAG(pAd, fRX_FILTER_ACCEPT_MULTICAST);
+ RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_BROADCAST);
+ RX_FILTER_SET_FLAG(pAd, fRX_FILTER_ACCEPT_ALL_MULTICAST);
+
+ pAd->StaCfg.Psm = PWR_ACTIVE;
+
+ pAd->StaCfg.OrigWepStatus = Ndis802_11EncryptionDisabled;
+ pAd->StaCfg.PairCipher = Ndis802_11EncryptionDisabled;
+ pAd->StaCfg.GroupCipher = Ndis802_11EncryptionDisabled;
+ pAd->StaCfg.bMixCipher = FALSE;
+ pAd->StaCfg.DefaultKeyId = 0;
+
+ // 802.1x port control
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pAd->StaCfg.LastMicErrorTime = 0;
+ pAd->StaCfg.MicErrCnt = 0;
+ pAd->StaCfg.bBlockAssoc = FALSE;
+ pAd->StaCfg.WpaState = SS_NOTUSE;
+
+ pAd->CommonCfg.NdisRadioStateOff = FALSE; // New to support microsoft disable radio with OID command
+
+ pAd->StaCfg.RssiTrigger = 0;
+ NdisZeroMemory(&pAd->StaCfg.RssiSample, sizeof(RSSI_SAMPLE));
+ pAd->StaCfg.RssiTriggerMode = RSSI_TRIGGERED_UPON_BELOW_THRESHOLD;
+ pAd->StaCfg.AtimWin = 0;
+ pAd->StaCfg.DefaultListenCount = 3;//default listen count;
+ pAd->StaCfg.BssType = BSS_INFRA; // BSS_INFRA or BSS_ADHOC or BSS_MONITOR
+ pAd->StaCfg.bScanReqIsFromWebUI = FALSE;
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_DOZE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_WAKEUP_NOW);
+
+ pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ }
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ pAd->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+
+ // global variables mXXXX used in MAC protocol state machines
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+
+ // PHY specification
+ pAd->CommonCfg.PhyMode = PHY_11BG_MIXED; // default PHY mode
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED); // CCK use LONG preamble
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // user desired power mode
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+ pAd->StaCfg.bWindowsACCAMEnable = FALSE;
+
+#ifdef LEAP_SUPPORT
+ // CCX v1.0 releated init value
+ RTMPInitTimer(pAd, &pAd->StaCfg.LeapAuthTimer, GET_TIMER_FUNCTION(LeapAuthTimeout), pAd, FALSE);
+ pAd->StaCfg.LeapAuthMode = CISCO_AuthModeLEAPNone;
+ pAd->StaCfg.bCkipOn = FALSE;
+#endif // LEAP_SUPPORT //
+
+ RTMPInitTimer(pAd, &pAd->StaCfg.StaQuickResponeForRateUpTimer, GET_TIMER_FUNCTION(StaQuickResponeForRateUpExec), pAd, FALSE);
+ pAd->StaCfg.StaQuickResponeForRateUpTimerRunning = FALSE;
+
+ // Patch for Ndtest
+ pAd->StaCfg.ScanCnt = 0;
+
+ // CCX 2.0 control flag init
+ pAd->StaCfg.CCXEnable = FALSE;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
+ pAd->StaCfg.CCXQosECWMin = 4;
+ pAd->StaCfg.CCXQosECWMax = 10;
+
+ pAd->StaCfg.bHwRadio = TRUE; // Default Hardware Radio status is On
+ pAd->StaCfg.bSwRadio = TRUE; // Default Software Radio status is On
+ pAd->StaCfg.bRadio = TRUE; // bHwRadio && bSwRadio
+ pAd->StaCfg.bHardwareRadio = FALSE; // Default is OFF
+ pAd->StaCfg.bShowHiddenSSID = FALSE; // Default no show
+
+ // Nitro mode control
+ pAd->StaCfg.bAutoReconnect = TRUE;
+
+ // Save the init time as last scan time, the system should do scan after 2 seconds.
+ // This patch is for driver wake up from standby mode, system will do scan right away.
+ pAd->StaCfg.LastScanTime = 0;
+ NdisZeroMemory(pAd->nickname, IW_ESSID_MAX_SIZE+1);
+ sprintf(pAd->nickname, "%s", STA_NIC_DEVICE_NAME);
+ RTMPInitTimer(pAd, &pAd->StaCfg.WpaDisassocAndBlockAssocTimer, GET_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc), pAd, FALSE);
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAd->StaCfg.IEEE8021X = FALSE;
+ pAd->StaCfg.IEEE8021x_required_keys = FALSE;
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Default for extra information is not valid
+ pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+
+ // Default Config change flag
+ pAd->bConfigChanged = FALSE;
+
+ //
+ // part III. AP configurations
+ //
+
+
+ //
+ // part IV. others
+ //
+ // dynamic BBP R66:sensibity tuning to overcome background noise
+ pAd->BbpTuning.bEnable = TRUE;
+ pAd->BbpTuning.FalseCcaLowerThreshold = 100;
+ pAd->BbpTuning.FalseCcaUpperThreshold = 512;
+ pAd->BbpTuning.R66Delta = 4;
+ pAd->Mlme.bEnableAutoAntennaCheck = TRUE;
+
+ //
+ // Also initial R66CurrentValue, RTUSBResumeMsduTransmission might use this value.
+ // if not initial this value, the default value will be 0.
+ //
+ pAd->BbpTuning.R66CurrentValue = 0x38;
+
+ pAd->Bbp94 = BBPR94_DEFAULT;
+ pAd->BbpForCCK = FALSE;
+
+ // Default is FALSE for test bit 1
+ //pAd->bTest1 = FALSE;
+
+ // initialize MAC table and allocate spin lock
+ NdisZeroMemory(&pAd->MacTab, sizeof(MAC_TABLE));
+ InitializeQueueHeader(&pAd->MacTab.McastPsQueue);
+ NdisAllocateSpinLock(&pAd->MacTabLock);
+
+ //RTMPInitTimer(pAd, &pAd->RECBATimer, RECBATimerTimeout, pAd, TRUE);
+ //RTMPSetTimer(&pAd->RECBATimer, REORDER_EXEC_INTV);
+
+#ifdef RALINK_ATE
+ NdisZeroMemory(&pAd->ate, sizeof(ATE_INFO));
+ pAd->ate.Mode = ATE_STOP;
+ pAd->ate.TxCount = 200;/* to exceed TX_RING_SIZE ... */
+ pAd->ate.TxLength = 1024;
+ pAd->ate.TxWI.ShortGI = 0;// LONG GI : 800 ns
+ pAd->ate.TxWI.PHYMODE = MODE_CCK;
+ pAd->ate.TxWI.MCS = 3;
+ pAd->ate.TxWI.BW = BW_20;
+ pAd->ate.Channel = 1;
+ pAd->ate.QID = QID_AC_BE;
+ pAd->ate.Addr1[0] = 0x00;
+ pAd->ate.Addr1[1] = 0x11;
+ pAd->ate.Addr1[2] = 0x22;
+ pAd->ate.Addr1[3] = 0xAA;
+ pAd->ate.Addr1[4] = 0xBB;
+ pAd->ate.Addr1[5] = 0xCC;
+ NdisMoveMemory(pAd->ate.Addr2, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
+ NdisMoveMemory(pAd->ate.Addr3, pAd->ate.Addr1, ETH_LENGTH_OF_ADDRESS);
+ pAd->ate.bRxFer = 0;
+ pAd->ate.bQATxStart = FALSE;
+ pAd->ate.bQARxStart = FALSE;
+#ifdef RALINK_28xx_QA
+ //pAd->ate.Repeat = 0;
+ pAd->ate.TxStatus = 0;
+ pAd->ate.AtePid = 0;
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+
+ pAd->CommonCfg.bWiFiTest = FALSE;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<-- UserCfgInit\n"));
+}
+
+// IRQL = PASSIVE_LEVEL
+UCHAR BtoH(char ch)
+{
+ if (ch >= '0' && ch <= '9') return (ch - '0'); // Handle numerals
+ if (ch >= 'A' && ch <= 'F') return (ch - 'A' + 0xA); // Handle capitol hex digits
+ if (ch >= 'a' && ch <= 'f') return (ch - 'a' + 0xA); // Handle small hex digits
+ return(255);
+}
+
+//
+// FUNCTION: AtoH(char *, UCHAR *, int)
+//
+// PURPOSE: Converts ascii string to network order hex
+//
+// PARAMETERS:
+// src - pointer to input ascii string
+// dest - pointer to output hex
+// destlen - size of dest
+//
+// COMMENTS:
+//
+// 2 ascii bytes make a hex byte so must put 1st ascii byte of pair
+// into upper nibble and 2nd ascii byte of pair into lower nibble.
+//
+// IRQL = PASSIVE_LEVEL
+
+void AtoH(char * src, UCHAR * dest, int destlen)
+{
+ char * srcptr;
+ PUCHAR destTemp;
+
+ srcptr = src;
+ destTemp = (PUCHAR) dest;
+
+ while(destlen--)
+ {
+ *destTemp = BtoH(*srcptr++) << 4; // Put 1st ascii byte in upper nibble.
+ *destTemp += BtoH(*srcptr++); // Add 2nd ascii byte to above.
+ destTemp++;
+ }
+}
+
+VOID RTMPPatchMacBbpBug(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG Index;
+
+ // Initialize BBP register to default value
+ for (Index = 0; Index < NUM_BBP_REG_PARMS; Index++)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBPRegTable[Index].Register, (UCHAR)BBPRegTable[Index].Value);
+ }
+
+ // Initialize RF register to default value
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ // Re-init BBP register from EEPROM value
+ NICInitAsicFromEEPROM(pAd);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init timer objects
+
+ Arguments:
+ pAd Pointer to our adapter
+ pTimer Timer structure
+ pTimerFunc Function to execute when timer expired
+ Repeat Ture for period timer
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitTimer(
+ IN PRTMP_ADAPTER pAd,
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN PVOID pTimerFunc,
+ IN PVOID pData,
+ IN BOOLEAN Repeat)
+{
+ //
+ // Set Valid to TRUE for later used.
+ // It will crash if we cancel a timer or set a timer
+ // that we haven't initialize before.
+ //
+ pTimer->Valid = TRUE;
+
+ pTimer->PeriodicType = Repeat;
+ pTimer->State = FALSE;
+ pTimer->cookie = (ULONG) pData;
+
+#ifdef RT2870
+ pTimer->pAd = pAd;
+#endif // RT2870 //
+
+ RTMP_OS_Init_Timer(pAd, &pTimer->TimerObj, pTimerFunc, (PVOID) pTimer);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init timer objects
+
+ Arguments:
+ pTimer Timer structure
+ Value Timer value in milliseconds
+
+ Return Value:
+ None
+
+ Note:
+ To use this routine, must call RTMPInitTimer before.
+
+ ========================================================================
+*/
+VOID RTMPSetTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value)
+{
+ if (pTimer->Valid)
+ {
+ pTimer->TimerValue = Value;
+ pTimer->State = FALSE;
+ if (pTimer->PeriodicType == TRUE)
+ {
+ pTimer->Repeat = TRUE;
+ RTMP_SetPeriodicTimer(&pTimer->TimerObj, Value);
+ }
+ else
+ {
+ pTimer->Repeat = FALSE;
+ RTMP_OS_Add_Timer(&pTimer->TimerObj, Value);
+ }
+ }
+ else
+ {
+ DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n"));
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init timer objects
+
+ Arguments:
+ pTimer Timer structure
+ Value Timer value in milliseconds
+
+ Return Value:
+ None
+
+ Note:
+ To use this routine, must call RTMPInitTimer before.
+
+ ========================================================================
+*/
+VOID RTMPModTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value)
+{
+ BOOLEAN Cancel;
+
+ if (pTimer->Valid)
+ {
+ pTimer->TimerValue = Value;
+ pTimer->State = FALSE;
+ if (pTimer->PeriodicType == TRUE)
+ {
+ RTMPCancelTimer(pTimer, &Cancel);
+ RTMPSetTimer(pTimer, Value);
+ }
+ else
+ {
+ RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value);
+ }
+ }
+ else
+ {
+ DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n"));
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Cancel timer objects
+
+ Arguments:
+ Adapter Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ 1.) To use this routine, must call RTMPInitTimer before.
+ 2.) Reset NIC to initial state AS IS system boot up time.
+
+ ========================================================================
+*/
+VOID RTMPCancelTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ OUT BOOLEAN *pCancelled)
+{
+ if (pTimer->Valid)
+ {
+ if (pTimer->State == FALSE)
+ pTimer->Repeat = FALSE;
+ RTMP_OS_Del_Timer(&pTimer->TimerObj, pCancelled);
+
+ if (*pCancelled == TRUE)
+ pTimer->State = TRUE;
+
+#ifdef RT2870
+ // We need to go-through the TimerQ to findout this timer handler and remove it if
+ // it's still waiting for execution.
+
+ RT2870_TimerQ_Remove(pTimer->pAd, pTimer);
+#endif // RT2870 //
+ }
+ else
+ {
+ //
+ // NdisMCancelTimer just canced the timer and not mean release the timer.
+ // And don't set the "Valid" to False. So that we can use this timer again.
+ //
+ DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n"));
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set LED Status
+
+ Arguments:
+ pAd Pointer to our adapter
+ Status LED Status
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPSetLED(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Status)
+{
+ //ULONG data;
+ UCHAR HighByte = 0;
+ UCHAR LowByte;
+
+// In ATE mode of RT2860 AP/STA, we have erased 8051 firmware.
+// So LED mode is not supported when ATE is running.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ LowByte = pAd->LedCntl.field.LedMode&0x7f;
+ switch (Status)
+ {
+ case LED_LINK_DOWN:
+ HighByte = 0x20;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ pAd->LedIndicatorStregth = 0;
+ break;
+ case LED_LINK_UP:
+ if (pAd->CommonCfg.Channel > 14)
+ HighByte = 0xa0;
+ else
+ HighByte = 0x60;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_RADIO_ON:
+ HighByte = 0x20;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_HALT:
+ LowByte = 0; // Driver sets MAC register and MAC controls LED
+ case LED_RADIO_OFF:
+ HighByte = 0;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_WPS:
+ HighByte = 0x10;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_ON_SITE_SURVEY:
+ HighByte = 0x08;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ case LED_POWER_UP:
+ HighByte = 0x04;
+ AsicSendCommandToMcu(pAd, 0x50, 0xff, LowByte, HighByte);
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_WARN, ("RTMPSetLED::Unknown Status %d\n", Status));
+ break;
+ }
+
+ //
+ // Keep LED status for LED SiteSurvey mode.
+ // After SiteSurvey, we will set the LED mode to previous status.
+ //
+ if ((Status != LED_ON_SITE_SURVEY) && (Status != LED_POWER_UP))
+ pAd->LedStatus = Status;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSetLED::Mode=%d,HighByte=0x%02x,LowByte=0x%02x\n", pAd->LedCntl.field.LedMode, HighByte, LowByte));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set LED Signal Stregth
+
+ Arguments:
+ pAd Pointer to our adapter
+ Dbm Signal Stregth
+
+ Return Value:
+ None
+
+ IRQL = PASSIVE_LEVEL
+
+ Note:
+ Can be run on any IRQL level.
+
+ According to Microsoft Zero Config Wireless Signal Stregth definition as belows.
+ <= -90 No Signal
+ <= -81 Very Low
+ <= -71 Low
+ <= -67 Good
+ <= -57 Very Good
+ > -57 Excellent
+ ========================================================================
+*/
+VOID RTMPSetSignalLED(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_802_11_RSSI Dbm)
+{
+ UCHAR nLed = 0;
+
+ //
+ // if not Signal Stregth, then do nothing.
+ //
+ if (pAd->LedCntl.field.LedMode != LED_MODE_SIGNAL_STREGTH)
+ {
+ return;
+ }
+
+ if (Dbm <= -90)
+ nLed = 0;
+ else if (Dbm <= -81)
+ nLed = 1;
+ else if (Dbm <= -71)
+ nLed = 3;
+ else if (Dbm <= -67)
+ nLed = 7;
+ else if (Dbm <= -57)
+ nLed = 15;
+ else
+ nLed = 31;
+
+ //
+ // Update Signal Stregth to firmware if changed.
+ //
+ if (pAd->LedIndicatorStregth != nLed)
+ {
+ AsicSendCommandToMcu(pAd, 0x51, 0xff, nLed, pAd->LedCntl.field.Polarity);
+ pAd->LedIndicatorStregth = nLed;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Enable RX
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL <= DISPATCH_LEVEL
+
+ Note:
+ Before Enable RX, make sure you have enabled Interrupt.
+ ========================================================================
+*/
+VOID RTMPEnableRxTx(
+ IN PRTMP_ADAPTER pAd)
+{
+// WPDMA_GLO_CFG_STRUC GloCfg;
+// ULONG i = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==> RTMPEnableRxTx\n"));
+
+ // Enable Rx DMA.
+ RT28XXDMAEnable(pAd);
+
+ // enable RX of MAC block
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ UINT32 rx_filter_flag = APNORMAL;
+
+
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, rx_filter_flag); // enable RX of DMA block
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+ }
+
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, 0xc);
+ DBGPRINT(RT_DEBUG_TRACE, ("<== RTMPEnableRxTx\n"));
+}
+
+
diff --git a/drivers/staging/rt3070/common/rtmp_tkip.c b/drivers/staging/rt3070/common/rtmp_tkip.c
new file mode 100644
index 00000000000..bf8986e8367
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_tkip.c
@@ -0,0 +1,1613 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_tkip.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Wu 02-25-02 Initial
+*/
+
+#include "../rt_config.h"
+
+// Rotation functions on 32 bit values
+#define ROL32( A, n ) \
+ ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
+#define ROR32( A, n ) ROL32( (A), 32-(n) )
+
+UINT Tkip_Sbox_Lower[256] =
+{
+ 0xA5,0x84,0x99,0x8D,0x0D,0xBD,0xB1,0x54,
+ 0x50,0x03,0xA9,0x7D,0x19,0x62,0xE6,0x9A,
+ 0x45,0x9D,0x40,0x87,0x15,0xEB,0xC9,0x0B,
+ 0xEC,0x67,0xFD,0xEA,0xBF,0xF7,0x96,0x5B,
+ 0xC2,0x1C,0xAE,0x6A,0x5A,0x41,0x02,0x4F,
+ 0x5C,0xF4,0x34,0x08,0x93,0x73,0x53,0x3F,
+ 0x0C,0x52,0x65,0x5E,0x28,0xA1,0x0F,0xB5,
+ 0x09,0x36,0x9B,0x3D,0x26,0x69,0xCD,0x9F,
+ 0x1B,0x9E,0x74,0x2E,0x2D,0xB2,0xEE,0xFB,
+ 0xF6,0x4D,0x61,0xCE,0x7B,0x3E,0x71,0x97,
+ 0xF5,0x68,0x00,0x2C,0x60,0x1F,0xC8,0xED,
+ 0xBE,0x46,0xD9,0x4B,0xDE,0xD4,0xE8,0x4A,
+ 0x6B,0x2A,0xE5,0x16,0xC5,0xD7,0x55,0x94,
+ 0xCF,0x10,0x06,0x81,0xF0,0x44,0xBA,0xE3,
+ 0xF3,0xFE,0xC0,0x8A,0xAD,0xBC,0x48,0x04,
+ 0xDF,0xC1,0x75,0x63,0x30,0x1A,0x0E,0x6D,
+ 0x4C,0x14,0x35,0x2F,0xE1,0xA2,0xCC,0x39,
+ 0x57,0xF2,0x82,0x47,0xAC,0xE7,0x2B,0x95,
+ 0xA0,0x98,0xD1,0x7F,0x66,0x7E,0xAB,0x83,
+ 0xCA,0x29,0xD3,0x3C,0x79,0xE2,0x1D,0x76,
+ 0x3B,0x56,0x4E,0x1E,0xDB,0x0A,0x6C,0xE4,
+ 0x5D,0x6E,0xEF,0xA6,0xA8,0xA4,0x37,0x8B,
+ 0x32,0x43,0x59,0xB7,0x8C,0x64,0xD2,0xE0,
+ 0xB4,0xFA,0x07,0x25,0xAF,0x8E,0xE9,0x18,
+ 0xD5,0x88,0x6F,0x72,0x24,0xF1,0xC7,0x51,
+ 0x23,0x7C,0x9C,0x21,0xDD,0xDC,0x86,0x85,
+ 0x90,0x42,0xC4,0xAA,0xD8,0x05,0x01,0x12,
+ 0xA3,0x5F,0xF9,0xD0,0x91,0x58,0x27,0xB9,
+ 0x38,0x13,0xB3,0x33,0xBB,0x70,0x89,0xA7,
+ 0xB6,0x22,0x92,0x20,0x49,0xFF,0x78,0x7A,
+ 0x8F,0xF8,0x80,0x17,0xDA,0x31,0xC6,0xB8,
+ 0xC3,0xB0,0x77,0x11,0xCB,0xFC,0xD6,0x3A
+};
+
+UINT Tkip_Sbox_Upper[256] =
+{
+ 0xC6,0xF8,0xEE,0xF6,0xFF,0xD6,0xDE,0x91,
+ 0x60,0x02,0xCE,0x56,0xE7,0xB5,0x4D,0xEC,
+ 0x8F,0x1F,0x89,0xFA,0xEF,0xB2,0x8E,0xFB,
+ 0x41,0xB3,0x5F,0x45,0x23,0x53,0xE4,0x9B,
+ 0x75,0xE1,0x3D,0x4C,0x6C,0x7E,0xF5,0x83,
+ 0x68,0x51,0xD1,0xF9,0xE2,0xAB,0x62,0x2A,
+ 0x08,0x95,0x46,0x9D,0x30,0x37,0x0A,0x2F,
+ 0x0E,0x24,0x1B,0xDF,0xCD,0x4E,0x7F,0xEA,
+ 0x12,0x1D,0x58,0x34,0x36,0xDC,0xB4,0x5B,
+ 0xA4,0x76,0xB7,0x7D,0x52,0xDD,0x5E,0x13,
+ 0xA6,0xB9,0x00,0xC1,0x40,0xE3,0x79,0xB6,
+ 0xD4,0x8D,0x67,0x72,0x94,0x98,0xB0,0x85,
+ 0xBB,0xC5,0x4F,0xED,0x86,0x9A,0x66,0x11,
+ 0x8A,0xE9,0x04,0xFE,0xA0,0x78,0x25,0x4B,
+ 0xA2,0x5D,0x80,0x05,0x3F,0x21,0x70,0xF1,
+ 0x63,0x77,0xAF,0x42,0x20,0xE5,0xFD,0xBF,
+ 0x81,0x18,0x26,0xC3,0xBE,0x35,0x88,0x2E,
+ 0x93,0x55,0xFC,0x7A,0xC8,0xBA,0x32,0xE6,
+ 0xC0,0x19,0x9E,0xA3,0x44,0x54,0x3B,0x0B,
+ 0x8C,0xC7,0x6B,0x28,0xA7,0xBC,0x16,0xAD,
+ 0xDB,0x64,0x74,0x14,0x92,0x0C,0x48,0xB8,
+ 0x9F,0xBD,0x43,0xC4,0x39,0x31,0xD3,0xF2,
+ 0xD5,0x8B,0x6E,0xDA,0x01,0xB1,0x9C,0x49,
+ 0xD8,0xAC,0xF3,0xCF,0xCA,0xF4,0x47,0x10,
+ 0x6F,0xF0,0x4A,0x5C,0x38,0x57,0x73,0x97,
+ 0xCB,0xA1,0xE8,0x3E,0x96,0x61,0x0D,0x0F,
+ 0xE0,0x7C,0x71,0xCC,0x90,0x06,0xF7,0x1C,
+ 0xC2,0x6A,0xAE,0x69,0x17,0x99,0x3A,0x27,
+ 0xD9,0xEB,0x2B,0x22,0xD2,0xA9,0x07,0x33,
+ 0x2D,0x3C,0x15,0xC9,0x87,0xAA,0x50,0xA5,
+ 0x03,0x59,0x09,0x1A,0x65,0xD7,0x84,0xD0,
+ 0x82,0x29,0x5A,0x1E,0x7B,0xA8,0x6D,0x2C
+};
+
+/*****************************/
+/******** SBOX Table *********/
+/*****************************/
+
+UCHAR SboxTable[256] =
+{
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
+ 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
+ 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
+ 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
+ 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
+ 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
+ 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
+ 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
+ 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
+ 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
+ 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
+ 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
+ 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
+ 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
+ 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
+ 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
+ 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
+};
+
+VOID xor_32(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+VOID xor_128(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+VOID next_key(
+ IN PUCHAR key,
+ IN INT round);
+
+VOID byte_sub(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID shift_row(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID mix_column(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+UCHAR RTMPCkipSbox(
+ IN UCHAR a);
+//
+// Expanded IV for TKIP function.
+//
+typedef struct PACKED _IV_CONTROL_
+{
+ union PACKED
+ {
+ struct PACKED
+ {
+ UCHAR rc0;
+ UCHAR rc1;
+ UCHAR rc2;
+
+ union PACKED
+ {
+ struct PACKED
+ {
+#ifdef RT_BIG_ENDIAN
+ UCHAR KeyID:2;
+ UCHAR ExtIV:1;
+ UCHAR Rsvd:5;
+#else
+ UCHAR Rsvd:5;
+ UCHAR ExtIV:1;
+ UCHAR KeyID:2;
+#endif
+ } field;
+ UCHAR Byte;
+ } CONTROL;
+ } field;
+
+ ULONG word;
+ } IV16;
+
+ ULONG IV32;
+} TKIP_IV, *PTKIP_IV;
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Convert from UCHAR[] to ULONG in a portable way
+
+ Arguments:
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+ULONG RTMPTkipGetUInt32(
+ IN PUCHAR pMICKey)
+{
+ ULONG res = 0;
+ INT i;
+
+ for (i = 0; i < 4; i++)
+ {
+ res |= (*pMICKey++) << (8 * i);
+ }
+
+ return res;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Convert from ULONG to UCHAR[] in a portable way
+
+ Arguments:
+ pDst pointer to destination for convert ULONG to UCHAR[]
+ val the value for convert
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipPutUInt32(
+ IN OUT PUCHAR pDst,
+ IN ULONG val)
+{
+ INT i;
+
+ for(i = 0; i < 4; i++)
+ {
+ *pDst++ = (UCHAR) (val & 0xff);
+ val >>= 8;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set the MIC Key.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipSetMICKey(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pMICKey)
+{
+ // Set the key
+ pTkip->K0 = RTMPTkipGetUInt32(pMICKey);
+ pTkip->K1 = RTMPTkipGetUInt32(pMICKey + 4);
+ // and reset the message
+ pTkip->L = pTkip->K0;
+ pTkip->R = pTkip->K1;
+ pTkip->nBytesInM = 0;
+ pTkip->M = 0;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ uChar Append this uChar
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipAppendByte(
+ IN PTKIP_KEY_INFO pTkip,
+ IN UCHAR uChar)
+{
+ // Append the byte to our word-sized buffer
+ pTkip->M |= (uChar << (8* pTkip->nBytesInM));
+ pTkip->nBytesInM++;
+ // Process the word if it is full.
+ if( pTkip->nBytesInM >= 4 )
+ {
+ pTkip->L ^= pTkip->M;
+ pTkip->R ^= ROL32( pTkip->L, 17 );
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ((pTkip->L & 0xff00ff00) >> 8) | ((pTkip->L & 0x00ff00ff) << 8);
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ROL32( pTkip->L, 3 );
+ pTkip->L += pTkip->R;
+ pTkip->R ^= ROR32( pTkip->L, 2 );
+ pTkip->L += pTkip->R;
+ // Clear the buffer
+ pTkip->M = 0;
+ pTkip->nBytesInM = 0;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to source data for Calculate MIC Value
+ Len Indicate the length of the source data
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPTkipAppend(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pSrc,
+ IN UINT nBytes)
+{
+ // This is simple
+ while(nBytes > 0)
+ {
+ RTMPTkipAppendByte(pTkip, *pSrc++);
+ nBytes--;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get the MIC Value.
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ the MIC Value is store in pAd->PrivateInfo.MIC
+ ========================================================================
+*/
+VOID RTMPTkipGetMIC(
+ IN PTKIP_KEY_INFO pTkip)
+{
+ // Append the minimum padding
+ RTMPTkipAppendByte(pTkip, 0x5a );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ RTMPTkipAppendByte(pTkip, 0 );
+ // and then zeroes until the length is a multiple of 4
+ while( pTkip->nBytesInM != 0 )
+ {
+ RTMPTkipAppendByte(pTkip, 0 );
+ }
+ // The appendByte function has already computed the result.
+ RTMPTkipPutUInt32(pTkip->MIC, pTkip->L);
+ RTMPTkipPutUInt32(pTkip->MIC + 4, pTkip->R);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init Tkip function.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
+ KeyId TK Key ID
+ pTA Pointer to transmitter address
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitTkipEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyId,
+ IN PUCHAR pTA,
+ IN PUCHAR pMICKey,
+ IN PUCHAR pTSC,
+ OUT PULONG pIV16,
+ OUT PULONG pIV32)
+{
+ TKIP_IV tkipIv;
+
+ // Prepare 8 bytes TKIP encapsulation for MPDU
+ NdisZeroMemory(&tkipIv, sizeof(TKIP_IV));
+ tkipIv.IV16.field.rc0 = *(pTSC + 1);
+ tkipIv.IV16.field.rc1 = (tkipIv.IV16.field.rc0 | 0x20) & 0x7f;
+ tkipIv.IV16.field.rc2 = *pTSC;
+ tkipIv.IV16.field.CONTROL.field.ExtIV = 1; // 0: non-extended IV, 1: an extended IV
+ tkipIv.IV16.field.CONTROL.field.KeyID = KeyId;
+// tkipIv.IV32 = *(PULONG)(pTSC + 2);
+ NdisMoveMemory(&tkipIv.IV32, (pTSC + 2), 4); // Copy IV
+
+ *pIV16 = tkipIv.IV16.word;
+ *pIV32 = tkipIv.IV32;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init MIC Value calculation function which include set MIC key &
+ calculate first 16 bytes (DA + SA + priority + 0)
+
+ Arguments:
+ pAd Pointer to our adapter
+ pTKey Pointer to the Temporal Key (TK), TK shall be 128bits.
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitMICEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN UCHAR UserPriority,
+ IN PUCHAR pMICKey)
+{
+ ULONG Priority = UserPriority;
+
+ // Init MIC value calculation
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Tx, pMICKey);
+ // DA
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pDA, MAC_ADDR_LEN);
+ // SA
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSA, MAC_ADDR_LEN);
+ // Priority + 3 bytes of 0
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, (PUCHAR)&Priority, 4);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Compare MIC value of received MSDU
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to the received Plain text data
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+ Len the length of the received plain text data exclude MIC value
+
+ Return Value:
+ TRUE MIC value matched
+ FALSE MIC value mismatched
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPTkipCompareMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UCHAR UserPriority,
+ IN UINT Len)
+{
+ UCHAR OldMic[8];
+ ULONG Priority = UserPriority;
+
+ // Init MIC value calculation
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+ // DA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+ // SA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+ // Priority + 3 bytes of 0
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
+
+ // Calculate MIC value from plain text data
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+ // Get MIC valude from received frame
+ NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+ // Get MIC value from decrypted plain data
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+ // Move MIC value from MSDU, this steps should move to data path.
+ // Since the MIC value might cross MPDUs.
+ if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValue(): TKIP MIC Error !\n")); //MIC error.
+
+
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Compare MIC value of received MSDU
+
+ Arguments:
+ pAd Pointer to our adapter
+ pLLC LLC header
+ pSrc Pointer to the received Plain text data
+ pDA Pointer to DA address
+ pSA Pointer to SA address
+ pMICKey pointer to MIC Key
+ Len the length of the received plain text data exclude MIC value
+
+ Return Value:
+ TRUE MIC value matched
+ FALSE MIC value mismatched
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPTkipCompareMICValueWithLLC(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pLLC,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UINT Len)
+{
+ UCHAR OldMic[8];
+ ULONG Priority = 0;
+
+ // Init MIC value calculation
+ RTMPTkipSetMICKey(&pAd->PrivateInfo.Rx, pMICKey);
+ // DA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pDA, MAC_ADDR_LEN);
+ // SA
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSA, MAC_ADDR_LEN);
+ // Priority + 3 bytes of 0
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, (PUCHAR)&Priority, 4);
+
+ // Start with LLC header
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pLLC, 8);
+
+ // Calculate MIC value from plain text data
+ RTMPTkipAppend(&pAd->PrivateInfo.Rx, pSrc, Len);
+
+ // Get MIC valude from received frame
+ NdisMoveMemory(OldMic, pSrc + Len, 8);
+
+ // Get MIC value from decrypted plain data
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Rx);
+
+ // Move MIC value from MSDU, this steps should move to data path.
+ // Since the MIC value might cross MPDUs.
+ if(!NdisEqualMemory(pAd->PrivateInfo.Rx.MIC, OldMic, 8))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTMPTkipCompareMICValueWithLLC(): TKIP MIC Error !\n")); //MIC error.
+
+
+ return (FALSE);
+ }
+ return (TRUE);
+}
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware transmit function
+
+ Arguments:
+ pAd Pointer to our adapter
+ PNDIS_PACKET Pointer to Ndis Packet for MIC calculation
+ pEncap Pointer to LLC encap data
+ LenEncap Total encap length, might be 0 which indicates no encap
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPCalculateMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pEncap,
+ IN PCIPHER_KEY pKey,
+ IN UCHAR apidx)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ PUCHAR pSrc;
+ UCHAR UserPriority;
+ UCHAR vlan_offset = 0;
+
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ UserPriority = RTMP_GET_PACKET_UP(pPacket);
+ pSrc = pSrcBufVA;
+
+ // determine if this is a vlan packet
+ if (((*(pSrc + 12) << 8) + *(pSrc + 13)) == 0x8100)
+ vlan_offset = 4;
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+ {
+ RTMPInitMICEngine(
+ pAd,
+ pKey->Key,
+ pSrc,
+ pSrc + 6,
+ UserPriority,
+ pKey->TxMic);
+ }
+
+
+ if (pEncap != NULL)
+ {
+ // LLC encapsulation
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pEncap, 6);
+ // Protocol Type
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc + 12 + vlan_offset, 2);
+ }
+ SrcBufLen -= (14 + vlan_offset);
+ pSrc += (14 + vlan_offset);
+ do
+ {
+ if (SrcBufLen > 0)
+ {
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pSrc, SrcBufLen);
+ }
+
+ break; // No need handle next packet
+
+ } while (TRUE); // End of copying payload
+
+ // Compute the final MIC Value
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+}
+
+
+/************************************************************/
+/* tkip_sbox() */
+/* Returns a 16 bit value from a 64K entry table. The Table */
+/* is synthesized from two 256 entry byte wide tables. */
+/************************************************************/
+
+UINT tkip_sbox(UINT index)
+{
+ UINT index_low;
+ UINT index_high;
+ UINT left, right;
+
+ index_low = (index % 256);
+ index_high = ((index >> 8) % 256);
+
+ left = Tkip_Sbox_Lower[index_low] + (Tkip_Sbox_Upper[index_low] * 256);
+ right = Tkip_Sbox_Upper[index_high] + (Tkip_Sbox_Lower[index_high] * 256);
+
+ return (left ^ right);
+}
+
+UINT rotr1(UINT a)
+{
+ unsigned int b;
+
+ if ((a & 0x01) == 0x01)
+ {
+ b = (a >> 1) | 0x8000;
+ }
+ else
+ {
+ b = (a >> 1) & 0x7fff;
+ }
+ b = b % 65536;
+ return b;
+}
+
+VOID RTMPTkipMixKey(
+ UCHAR *key,
+ UCHAR *ta,
+ ULONG pnl, /* Least significant 16 bits of PN */
+ ULONG pnh, /* Most significant 32 bits of PN */
+ UCHAR *rc4key,
+ UINT *p1k)
+{
+
+ UINT tsc0;
+ UINT tsc1;
+ UINT tsc2;
+
+ UINT ppk0;
+ UINT ppk1;
+ UINT ppk2;
+ UINT ppk3;
+ UINT ppk4;
+ UINT ppk5;
+
+ INT i;
+ INT j;
+
+ tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
+ tsc1 = (unsigned int)(pnh % 65536);
+ tsc2 = (unsigned int)(pnl % 65536); /* lsb */
+
+ /* Phase 1, step 1 */
+ p1k[0] = tsc1;
+ p1k[1] = tsc0;
+ p1k[2] = (UINT)(ta[0] + (ta[1]*256));
+ p1k[3] = (UINT)(ta[2] + (ta[3]*256));
+ p1k[4] = (UINT)(ta[4] + (ta[5]*256));
+
+ /* Phase 1, step 2 */
+ for (i=0; i<8; i++)
+ {
+ j = 2*(i & 1);
+ p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*key[1+j]) + key[j])) % 65536 )) % 65536;
+ p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*key[5+j]) + key[4+j])) % 65536 )) % 65536;
+ p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*key[9+j]) + key[8+j])) % 65536 )) % 65536;
+ p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*key[13+j]) + key[12+j])) % 65536 )) % 65536;
+ p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*key[1+j]) + key[j]))) % 65536 )) % 65536;
+ p1k[4] = (p1k[4] + i) % 65536;
+ }
+
+ /* Phase 2, Step 1 */
+ ppk0 = p1k[0];
+ ppk1 = p1k[1];
+ ppk2 = p1k[2];
+ ppk3 = p1k[3];
+ ppk4 = p1k[4];
+ ppk5 = (p1k[4] + tsc2) % 65536;
+
+ /* Phase2, Step 2 */
+ ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*key[1]) + key[0])) % 65536);
+ ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*key[3]) + key[2])) % 65536);
+ ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*key[5]) + key[4])) % 65536);
+ ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*key[7]) + key[6])) % 65536);
+ ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*key[9]) + key[8])) % 65536);
+ ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*key[11]) + key[10])) % 65536);
+
+ ppk0 = ppk0 + rotr1(ppk5 ^ ((256*key[13]) + key[12]));
+ ppk1 = ppk1 + rotr1(ppk0 ^ ((256*key[15]) + key[14]));
+ ppk2 = ppk2 + rotr1(ppk1);
+ ppk3 = ppk3 + rotr1(ppk2);
+ ppk4 = ppk4 + rotr1(ppk3);
+ ppk5 = ppk5 + rotr1(ppk4);
+
+ /* Phase 2, Step 3 */
+ /* Phase 2, Step 3 */
+
+ tsc0 = (unsigned int)((pnh >> 16) % 65536); /* msb */
+ tsc1 = (unsigned int)(pnh % 65536);
+ tsc2 = (unsigned int)(pnl % 65536); /* lsb */
+
+ rc4key[0] = (tsc2 >> 8) % 256;
+ rc4key[1] = (((tsc2 >> 8) % 256) | 0x20) & 0x7f;
+ rc4key[2] = tsc2 % 256;
+ rc4key[3] = ((ppk5 ^ ((256*key[1]) + key[0])) >> 1) % 256;
+
+ rc4key[4] = ppk0 % 256;
+ rc4key[5] = (ppk0 >> 8) % 256;
+
+ rc4key[6] = ppk1 % 256;
+ rc4key[7] = (ppk1 >> 8) % 256;
+
+ rc4key[8] = ppk2 % 256;
+ rc4key[9] = (ppk2 >> 8) % 256;
+
+ rc4key[10] = ppk3 % 256;
+ rc4key[11] = (ppk3 >> 8) % 256;
+
+ rc4key[12] = ppk4 % 256;
+ rc4key[13] = (ppk4 >> 8) % 256;
+
+ rc4key[14] = ppk5 % 256;
+ rc4key[15] = (ppk5 >> 8) % 256;
+}
+
+
+/************************************************/
+/* construct_mic_header1() */
+/* Builds the first MIC header block from */
+/* header fields. */
+/************************************************/
+
+void construct_mic_header1(
+ unsigned char *mic_header1,
+ int header_length,
+ unsigned char *mpdu)
+{
+ mic_header1[0] = (unsigned char)((header_length - 2) / 256);
+ mic_header1[1] = (unsigned char)((header_length - 2) % 256);
+ mic_header1[2] = mpdu[0] & 0xcf; /* Mute CF poll & CF ack bits */
+ mic_header1[3] = mpdu[1] & 0xc7; /* Mute retry, more data and pwr mgt bits */
+ mic_header1[4] = mpdu[4]; /* A1 */
+ mic_header1[5] = mpdu[5];
+ mic_header1[6] = mpdu[6];
+ mic_header1[7] = mpdu[7];
+ mic_header1[8] = mpdu[8];
+ mic_header1[9] = mpdu[9];
+ mic_header1[10] = mpdu[10]; /* A2 */
+ mic_header1[11] = mpdu[11];
+ mic_header1[12] = mpdu[12];
+ mic_header1[13] = mpdu[13];
+ mic_header1[14] = mpdu[14];
+ mic_header1[15] = mpdu[15];
+}
+
+/************************************************/
+/* construct_mic_header2() */
+/* Builds the last MIC header block from */
+/* header fields. */
+/************************************************/
+
+void construct_mic_header2(
+ unsigned char *mic_header2,
+ unsigned char *mpdu,
+ int a4_exists,
+ int qc_exists)
+{
+ int i;
+
+ for (i = 0; i<16; i++) mic_header2[i]=0x00;
+
+ mic_header2[0] = mpdu[16]; /* A3 */
+ mic_header2[1] = mpdu[17];
+ mic_header2[2] = mpdu[18];
+ mic_header2[3] = mpdu[19];
+ mic_header2[4] = mpdu[20];
+ mic_header2[5] = mpdu[21];
+
+ // In Sequence Control field, mute sequence numer bits (12-bit)
+ mic_header2[6] = mpdu[22] & 0x0f; /* SC */
+ mic_header2[7] = 0x00; /* mpdu[23]; */
+
+ if ((!qc_exists) & a4_exists)
+ {
+ for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
+
+ }
+
+ if (qc_exists && (!a4_exists))
+ {
+ mic_header2[8] = mpdu[24] & 0x0f; /* mute bits 15 - 4 */
+ mic_header2[9] = mpdu[25] & 0x00;
+ }
+
+ if (qc_exists && a4_exists)
+ {
+ for (i=0;i<6;i++) mic_header2[8+i] = mpdu[24+i]; /* A4 */
+
+ mic_header2[14] = mpdu[30] & 0x0f;
+ mic_header2[15] = mpdu[31] & 0x00;
+ }
+}
+
+
+/************************************************/
+/* construct_mic_iv() */
+/* Builds the MIC IV from header fields and PN */
+/************************************************/
+
+void construct_mic_iv(
+ unsigned char *mic_iv,
+ int qc_exists,
+ int a4_exists,
+ unsigned char *mpdu,
+ unsigned int payload_length,
+ unsigned char *pn_vector)
+{
+ int i;
+
+ mic_iv[0] = 0x59;
+ if (qc_exists && a4_exists)
+ mic_iv[1] = mpdu[30] & 0x0f; /* QoS_TC */
+ if (qc_exists && !a4_exists)
+ mic_iv[1] = mpdu[24] & 0x0f; /* mute bits 7-4 */
+ if (!qc_exists)
+ mic_iv[1] = 0x00;
+ for (i = 2; i < 8; i++)
+ mic_iv[i] = mpdu[i + 8]; /* mic_iv[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+ for (i = 8; i < 14; i++)
+ mic_iv[i] = pn_vector[i - 8]; /* mic_iv[8:13] = PN[0:5] */
+#else
+ for (i = 8; i < 14; i++)
+ mic_iv[i] = pn_vector[13 - i]; /* mic_iv[8:13] = PN[5:0] */
+#endif
+ i = (payload_length / 256);
+ i = (payload_length % 256);
+ mic_iv[14] = (unsigned char) (payload_length / 256);
+ mic_iv[15] = (unsigned char) (payload_length % 256);
+
+}
+
+
+
+/************************************/
+/* bitwise_xor() */
+/* A 128 bit, bitwise exclusive or */
+/************************************/
+
+void bitwise_xor(unsigned char *ina, unsigned char *inb, unsigned char *out)
+{
+ int i;
+ for (i=0; i<16; i++)
+ {
+ out[i] = ina[i] ^ inb[i];
+ }
+}
+
+
+void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
+{
+ int round;
+ int i;
+ unsigned char intermediatea[16];
+ unsigned char intermediateb[16];
+ unsigned char round_key[16];
+
+ for(i=0; i<16; i++) round_key[i] = key[i];
+
+ for (round = 0; round < 11; round++)
+ {
+ if (round == 0)
+ {
+ xor_128(round_key, data, ciphertext);
+ next_key(round_key, round);
+ }
+ else if (round == 10)
+ {
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ xor_128(intermediateb, round_key, ciphertext);
+ }
+ else /* 1 - 9 */
+ {
+ byte_sub(ciphertext, intermediatea);
+ shift_row(intermediatea, intermediateb);
+ mix_column(&intermediateb[0], &intermediatea[0]);
+ mix_column(&intermediateb[4], &intermediatea[4]);
+ mix_column(&intermediateb[8], &intermediatea[8]);
+ mix_column(&intermediateb[12], &intermediatea[12]);
+ xor_128(intermediatea, round_key, ciphertext);
+ next_key(round_key, round);
+ }
+ }
+
+}
+
+void construct_ctr_preload(
+ unsigned char *ctr_preload,
+ int a4_exists,
+ int qc_exists,
+ unsigned char *mpdu,
+ unsigned char *pn_vector,
+ int c)
+{
+
+ int i = 0;
+ for (i=0; i<16; i++) ctr_preload[i] = 0x00;
+ i = 0;
+
+ ctr_preload[0] = 0x01; /* flag */
+ if (qc_exists && a4_exists) ctr_preload[1] = mpdu[30] & 0x0f; /* QoC_Control */
+ if (qc_exists && !a4_exists) ctr_preload[1] = mpdu[24] & 0x0f;
+
+ for (i = 2; i < 8; i++)
+ ctr_preload[i] = mpdu[i + 8]; /* ctr_preload[2:7] = A2[0:5] = mpdu[10:15] */
+#ifdef CONSISTENT_PN_ORDER
+ for (i = 8; i < 14; i++)
+ ctr_preload[i] = pn_vector[i - 8]; /* ctr_preload[8:13] = PN[0:5] */
+#else
+ for (i = 8; i < 14; i++)
+ ctr_preload[i] = pn_vector[13 - i]; /* ctr_preload[8:13] = PN[5:0] */
+#endif
+ ctr_preload[14] = (unsigned char) (c / 256); // Ctr
+ ctr_preload[15] = (unsigned char) (c % 256);
+
+}
+
+
+//
+// TRUE: Success!
+// FALSE: Decrypt Error!
+//
+BOOLEAN RTMPSoftDecryptTKIP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN UCHAR UserPriority,
+ IN PCIPHER_KEY pWpaKey)
+{
+ UCHAR KeyID;
+ UINT HeaderLen;
+ UCHAR fc0;
+ UCHAR fc1;
+ USHORT fc;
+ UINT frame_type;
+ UINT frame_subtype;
+ UINT from_ds;
+ UINT to_ds;
+ INT a4_exists;
+ INT qc_exists;
+ USHORT duration;
+ USHORT seq_control;
+ USHORT qos_control;
+ UCHAR TA[MAC_ADDR_LEN];
+ UCHAR DA[MAC_ADDR_LEN];
+ UCHAR SA[MAC_ADDR_LEN];
+ UCHAR RC4Key[16];
+ UINT p1k[5]; //for mix_key;
+ ULONG pnl;/* Least significant 16 bits of PN */
+ ULONG pnh;/* Most significant 32 bits of PN */
+ UINT num_blocks;
+ UINT payload_remainder;
+ ARCFOURCONTEXT ArcFourContext;
+ UINT crc32 = 0;
+ UINT trailfcs = 0;
+ UCHAR MIC[8];
+ UCHAR TrailMIC[8];
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ fc0 = *pData;
+ fc1 = *(pData + 1);
+
+ fc = *((PUSHORT)pData);
+
+ frame_type = ((fc0 >> 2) & 0x03);
+ frame_subtype = ((fc0 >> 4) & 0x0f);
+
+ from_ds = (fc1 & 0x2) >> 1;
+ to_ds = (fc1 & 0x1);
+
+ a4_exists = (from_ds & to_ds);
+ qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
+ (frame_subtype == 0x09) || /* Likely to change. */
+ (frame_subtype == 0x0a) ||
+ (frame_subtype == 0x0b)
+ );
+
+ HeaderLen = 24;
+ if (a4_exists)
+ HeaderLen += 6;
+
+ KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
+ KeyID = KeyID >> 6;
+
+ if (pWpaKey[KeyID].KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP failed!(KeyID[%d] Length can not be 0)\n", KeyID));
+ return FALSE;
+ }
+
+ duration = *((PUSHORT)(pData+2));
+
+ seq_control = *((PUSHORT)(pData+22));
+
+ if (qc_exists)
+ {
+ if (a4_exists)
+ {
+ qos_control = *((PUSHORT)(pData+30));
+ }
+ else
+ {
+ qos_control = *((PUSHORT)(pData+24));
+ }
+ }
+
+ if (to_ds == 0 && from_ds == 1)
+ {
+ NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
+ NdisMoveMemory(SA, pData+16, MAC_ADDR_LEN);
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN); //BSSID
+ }
+ else if (to_ds == 0 && from_ds == 0 )
+ {
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(DA, pData+4, MAC_ADDR_LEN);
+ NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
+ }
+ else if (to_ds == 1 && from_ds == 0)
+ {
+ NdisMoveMemory(SA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
+ }
+ else if (to_ds == 1 && from_ds == 1)
+ {
+ NdisMoveMemory(TA, pData+10, MAC_ADDR_LEN);
+ NdisMoveMemory(DA, pData+16, MAC_ADDR_LEN);
+ NdisMoveMemory(SA, pData+22, MAC_ADDR_LEN);
+ }
+
+ num_blocks = (DataByteCnt - 16) / 16;
+ payload_remainder = (DataByteCnt - 16) % 16;
+
+ pnl = (*(pData + HeaderLen)) * 256 + *(pData + HeaderLen + 2);
+ pnh = *((PULONG)(pData + HeaderLen + 4));
+ pnh = cpu2le32(pnh);
+ RTMPTkipMixKey(pWpaKey[KeyID].Key, TA, pnl, pnh, RC4Key, p1k);
+
+ ARCFOUR_INIT(&ArcFourContext, RC4Key, 16);
+
+ ARCFOUR_DECRYPT(&ArcFourContext, pData + HeaderLen, pData + HeaderLen + 8, DataByteCnt - HeaderLen - 8);
+ NdisMoveMemory(&trailfcs, pData + DataByteCnt - 8 - 4, 4);
+ crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 4); //Skip IV+EIV 8 bytes & Skip last 4 bytes(FCS).
+ crc32 ^= 0xffffffff; /* complement */
+
+ if(crc32 != cpu2le32(trailfcs))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptTKIP, WEP Data ICV Error !\n")); //ICV error.
+
+ return (FALSE);
+ }
+
+ NdisMoveMemory(TrailMIC, pData + DataByteCnt - 8 - 8 - 4, 8);
+ RTMPInitMICEngine(pAd, pWpaKey[KeyID].Key, DA, SA, UserPriority, pWpaKey[KeyID].RxMic);
+ RTMPTkipAppend(&pAd->PrivateInfo.Tx, pData + HeaderLen, DataByteCnt - HeaderLen - 8 - 12);
+ RTMPTkipGetMIC(&pAd->PrivateInfo.Tx);
+ NdisMoveMemory(MIC, pAd->PrivateInfo.Tx.MIC, 8);
+
+ if (!NdisEqualMemory(MIC, TrailMIC, 8))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptTKIP, WEP Data MIC Error !\n")); //MIC error.
+ //RTMPReportMicError(pAd, &pWpaKey[KeyID]); // marked by AlbertY @ 20060630
+ return (FALSE);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+ //DBGPRINT(RT_DEBUG_TRACE, "RTMPSoftDecryptTKIP Decript done!!\n");
+ return TRUE;
+}
+
+
+
+
+BOOLEAN RTMPSoftDecryptAES(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pWpaKey)
+{
+ UCHAR KeyID;
+ UINT HeaderLen;
+ UCHAR PN[6];
+ UINT payload_len;
+ UINT num_blocks;
+ UINT payload_remainder;
+ USHORT fc;
+ UCHAR fc0;
+ UCHAR fc1;
+ UINT frame_type;
+ UINT frame_subtype;
+ UINT from_ds;
+ UINT to_ds;
+ INT a4_exists;
+ INT qc_exists;
+ UCHAR aes_out[16];
+ int payload_index;
+ UINT i;
+ UCHAR ctr_preload[16];
+ UCHAR chain_buffer[16];
+ UCHAR padded_buffer[16];
+ UCHAR mic_iv[16];
+ UCHAR mic_header1[16];
+ UCHAR mic_header2[16];
+ UCHAR MIC[8];
+ UCHAR TrailMIC[8];
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ fc0 = *pData;
+ fc1 = *(pData + 1);
+
+ fc = *((PUSHORT)pData);
+
+ frame_type = ((fc0 >> 2) & 0x03);
+ frame_subtype = ((fc0 >> 4) & 0x0f);
+
+ from_ds = (fc1 & 0x2) >> 1;
+ to_ds = (fc1 & 0x1);
+
+ a4_exists = (from_ds & to_ds);
+ qc_exists = ((frame_subtype == 0x08) || /* Assumed QoS subtypes */
+ (frame_subtype == 0x09) || /* Likely to change. */
+ (frame_subtype == 0x0a) ||
+ (frame_subtype == 0x0b)
+ );
+
+ HeaderLen = 24;
+ if (a4_exists)
+ HeaderLen += 6;
+
+ KeyID = *((PUCHAR)(pData+ HeaderLen + 3));
+ KeyID = KeyID >> 6;
+
+ if (pWpaKey[KeyID].KeyLen == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSoftDecryptAES failed!(KeyID[%d] Length can not be 0)\n", KeyID));
+ return FALSE;
+ }
+
+ PN[0] = *(pData+ HeaderLen);
+ PN[1] = *(pData+ HeaderLen + 1);
+ PN[2] = *(pData+ HeaderLen + 4);
+ PN[3] = *(pData+ HeaderLen + 5);
+ PN[4] = *(pData+ HeaderLen + 6);
+ PN[5] = *(pData+ HeaderLen + 7);
+
+ payload_len = DataByteCnt - HeaderLen - 8 - 8; // 8 bytes for CCMP header , 8 bytes for MIC
+ payload_remainder = (payload_len) % 16;
+ num_blocks = (payload_len) / 16;
+
+
+
+ // Find start of payload
+ payload_index = HeaderLen + 8; //IV+EIV
+
+ for (i=0; i< num_blocks; i++)
+ {
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ i+1 );
+
+ aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+ NdisMoveMemory(pData + payload_index - 8, chain_buffer, 16);
+ payload_index += 16;
+ }
+
+ //
+ // If there is a short final block, then pad it
+ // encrypt it and copy the unpadded part back
+ //
+ if (payload_remainder > 0)
+ {
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ num_blocks + 1);
+
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+ aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ NdisMoveMemory(pData + payload_index - 8, chain_buffer, payload_remainder);
+ payload_index += payload_remainder;
+ }
+
+ //
+ // Descrypt the MIC
+ //
+ construct_ctr_preload(ctr_preload,
+ a4_exists,
+ qc_exists,
+ pData,
+ PN,
+ 0);
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, 8);
+
+ aes128k128d(pWpaKey[KeyID].Key, ctr_preload, aes_out);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+
+ NdisMoveMemory(TrailMIC, chain_buffer, 8);
+
+ //
+ // Calculate MIC
+ //
+
+ //Force the protected frame bit on
+ *(pData + 1) = *(pData + 1) | 0x40;
+
+ // Find start of payload
+ // Because the CCMP header has been removed
+ payload_index = HeaderLen;
+
+ construct_mic_iv(
+ mic_iv,
+ qc_exists,
+ a4_exists,
+ pData,
+ payload_len,
+ PN);
+
+ construct_mic_header1(
+ mic_header1,
+ HeaderLen,
+ pData);
+
+ construct_mic_header2(
+ mic_header2,
+ pData,
+ a4_exists,
+ qc_exists);
+
+ aes128k128d(pWpaKey[KeyID].Key, mic_iv, aes_out);
+ bitwise_xor(aes_out, mic_header1, chain_buffer);
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+ bitwise_xor(aes_out, mic_header2, chain_buffer);
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+
+ // iterate through each 16 byte payload block
+ for (i = 0; i < num_blocks; i++)
+ {
+ bitwise_xor(aes_out, pData + payload_index, chain_buffer);
+ payload_index += 16;
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+ }
+
+ // Add on the final payload block if it needs padding
+ if (payload_remainder > 0)
+ {
+ NdisZeroMemory(padded_buffer, 16);
+ NdisMoveMemory(padded_buffer, pData + payload_index, payload_remainder);
+
+ bitwise_xor(aes_out, padded_buffer, chain_buffer);
+ aes128k128d(pWpaKey[KeyID].Key, chain_buffer, aes_out);
+ }
+
+ // aes_out contains padded mic, discard most significant
+ // 8 bytes to generate 64 bit MIC
+ for (i = 0 ; i < 8; i++) MIC[i] = aes_out[i];
+
+ if (!NdisEqualMemory(MIC, TrailMIC, 8))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTMPSoftDecryptAES, MIC Error !\n")); //MIC error.
+ return FALSE;
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pData, DIR_READ, FALSE);
+#endif
+
+ return TRUE;
+}
+
+/****************************************/
+/* aes128k128d() */
+/* Performs a 128 bit AES encrypt with */
+/* 128 bit data. */
+/****************************************/
+VOID xor_128(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0;i<16; i++)
+ {
+ out[i] = a[i] ^ b[i];
+ }
+}
+
+VOID next_key(
+ IN PUCHAR key,
+ IN INT round)
+{
+ UCHAR rcon;
+ UCHAR sbox_key[4];
+ UCHAR rcon_table[12] =
+ {
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
+ 0x1b, 0x36, 0x36, 0x36
+ };
+
+ sbox_key[0] = RTMPCkipSbox(key[13]);
+ sbox_key[1] = RTMPCkipSbox(key[14]);
+ sbox_key[2] = RTMPCkipSbox(key[15]);
+ sbox_key[3] = RTMPCkipSbox(key[12]);
+
+ rcon = rcon_table[round];
+
+ xor_32(&key[0], sbox_key, &key[0]);
+ key[0] = key[0] ^ rcon;
+
+ xor_32(&key[4], &key[0], &key[4]);
+ xor_32(&key[8], &key[4], &key[8]);
+ xor_32(&key[12], &key[8], &key[12]);
+}
+
+VOID xor_32(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0;i<4; i++)
+ {
+ out[i] = a[i] ^ b[i];
+ }
+}
+
+VOID byte_sub(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ INT i;
+
+ for (i=0; i< 16; i++)
+ {
+ out[i] = RTMPCkipSbox(in[i]);
+ }
+}
+
+UCHAR RTMPCkipSbox(
+ IN UCHAR a)
+{
+ return SboxTable[(int)a];
+}
+
+VOID shift_row(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ out[0] = in[0];
+ out[1] = in[5];
+ out[2] = in[10];
+ out[3] = in[15];
+ out[4] = in[4];
+ out[5] = in[9];
+ out[6] = in[14];
+ out[7] = in[3];
+ out[8] = in[8];
+ out[9] = in[13];
+ out[10] = in[2];
+ out[11] = in[7];
+ out[12] = in[12];
+ out[13] = in[1];
+ out[14] = in[6];
+ out[15] = in[11];
+}
+
+VOID mix_column(
+ IN PUCHAR in,
+ OUT PUCHAR out)
+{
+ INT i;
+ UCHAR add1b[4];
+ UCHAR add1bf7[4];
+ UCHAR rotl[4];
+ UCHAR swap_halfs[4];
+ UCHAR andf7[4];
+ UCHAR rotr[4];
+ UCHAR temp[4];
+ UCHAR tempb[4];
+
+ for (i=0 ; i<4; i++)
+ {
+ if ((in[i] & 0x80)== 0x80)
+ add1b[i] = 0x1b;
+ else
+ add1b[i] = 0x00;
+ }
+
+ swap_halfs[0] = in[2]; /* Swap halfs */
+ swap_halfs[1] = in[3];
+ swap_halfs[2] = in[0];
+ swap_halfs[3] = in[1];
+
+ rotl[0] = in[3]; /* Rotate left 8 bits */
+ rotl[1] = in[0];
+ rotl[2] = in[1];
+ rotl[3] = in[2];
+
+ andf7[0] = in[0] & 0x7f;
+ andf7[1] = in[1] & 0x7f;
+ andf7[2] = in[2] & 0x7f;
+ andf7[3] = in[3] & 0x7f;
+
+ for (i = 3; i>0; i--) /* logical shift left 1 bit */
+ {
+ andf7[i] = andf7[i] << 1;
+ if ((andf7[i-1] & 0x80) == 0x80)
+ {
+ andf7[i] = (andf7[i] | 0x01);
+ }
+ }
+ andf7[0] = andf7[0] << 1;
+ andf7[0] = andf7[0] & 0xfe;
+
+ xor_32(add1b, andf7, add1bf7);
+
+ xor_32(in, add1bf7, rotr);
+
+ temp[0] = rotr[0]; /* Rotate right 8 bits */
+ rotr[0] = rotr[1];
+ rotr[1] = rotr[2];
+ rotr[2] = rotr[3];
+ rotr[3] = temp[0];
+
+ xor_32(add1bf7, rotr, temp);
+ xor_32(swap_halfs, rotl,tempb);
+ xor_32(temp, tempb, out);
+}
+
diff --git a/drivers/staging/rt3070/common/rtmp_wep.c b/drivers/staging/rt3070/common/rtmp_wep.c
new file mode 100644
index 00000000000..f5f0a3bb17e
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtmp_wep.c
@@ -0,0 +1,508 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_wep.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Wu 10-28-02 Initial
+*/
+
+#include "../rt_config.h"
+
+UINT FCSTAB_32[256] =
+{
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+};
+
+/*
+UCHAR WEPKEY[] = {
+ //IV
+ 0x00, 0x11, 0x22,
+ //WEP KEY
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+ };
+ */
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init WEP function.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pKey Pointer to the WEP KEY
+ KeyId WEP Key ID
+ KeyLen the length of WEP KEY
+ pDest Pointer to the destination which Encryption data will store in.
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPInitWepEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyId,
+ IN UCHAR KeyLen,
+ IN OUT PUCHAR pDest)
+{
+ UINT i;
+ UCHAR WEPKEY[] = {
+ //IV
+ 0x00, 0x11, 0x22,
+ //WEP KEY
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+ };
+
+ pAd->PrivateInfo.FCSCRC32 = PPPINITFCS32; //Init crc32.
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10) && (pAd->OpMode == OPMODE_STA))
+ {
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, pKey, KeyLen); //INIT SBOX, KEYLEN+3(IV)
+ NdisMoveMemory(pDest, pKey, 3); //Append Init Vector
+ }
+ else
+#endif // CONFIG_STA_SUPPORT //
+ {
+ NdisMoveMemory(WEPKEY + 3, pKey, KeyLen);
+
+ for(i = 0; i < 3; i++)
+ WEPKEY[i] = RandomByte(pAd); //Call mlme RandomByte() function.
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, KeyLen + 3); //INIT SBOX, KEYLEN+3(IV)
+
+ NdisMoveMemory(pDest, WEPKEY, 3); //Append Init Vector
+ }
+ *(pDest+3) = (KeyId << 6); //Append KEYID
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Encrypt transimitted data
+
+ Arguments:
+ pAd Pointer to our adapter
+ pSrc Pointer to the transimitted source data that will be encrypt
+ pDest Pointer to the destination where entryption data will be store in.
+ Len Indicate the length of the source data
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPEncryptData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDest,
+ IN UINT Len)
+{
+ pAd->PrivateInfo.FCSCRC32 = RTMP_CALC_FCS32(pAd->PrivateInfo.FCSCRC32, pSrc, Len);
+ ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, pSrc, Len);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Decrypt received WEP data
+
+ Arguments:
+ pAdapter Pointer to our adapter
+ pSrc Pointer to the received data
+ Len the length of the received data
+
+ Return Value:
+ TRUE Decrypt WEP data success
+ FALSE Decrypt WEP data failed
+
+ Note:
+
+ ========================================================================
+*/
+BOOLEAN RTMPSoftDecryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pGroupKey)
+{
+ UINT trailfcs;
+ UINT crc32;
+ UCHAR KeyIdx;
+ UCHAR WEPKEY[] = {
+ //IV
+ 0x00, 0x11, 0x22,
+ //WEP KEY
+ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC
+ };
+ UCHAR *pPayload = (UCHAR *)pData + LENGTH_802_11;
+ ULONG payload_len = DataByteCnt - LENGTH_802_11;
+
+ NdisMoveMemory(WEPKEY, pPayload, 3); //Get WEP IV
+
+ KeyIdx = (*(pPayload + 3) & 0xc0) >> 6;
+ if (pGroupKey[KeyIdx].KeyLen == 0)
+ return (FALSE);
+
+ NdisMoveMemory(WEPKEY + 3, pGroupKey[KeyIdx].Key, pGroupKey[KeyIdx].KeyLen);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, WEPKEY, pGroupKey[KeyIdx].KeyLen + 3);
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, pPayload, pPayload + 4, payload_len - 4);
+ NdisMoveMemory(&trailfcs, pPayload + payload_len - 8, 4);
+ crc32 = RTMP_CALC_FCS32(PPPINITFCS32, pPayload, payload_len - 8); //Skip last 4 bytes(FCS).
+ crc32 ^= 0xffffffff; /* complement */
+
+ if(crc32 != cpu2le32(trailfcs))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("! WEP Data CRC Error !\n")); //CRC error.
+ return (FALSE);
+ }
+ return (TRUE);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Encryption Algorithm "ARCFOUR" initialize
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pKey Pointer to the WEP KEY
+ KeyLen Indicate the length fo the WEP KEY
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID ARCFOUR_INIT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pKey,
+ IN UINT KeyLen)
+{
+ UCHAR t, u;
+ UINT keyindex;
+ UINT stateindex;
+ PUCHAR state;
+ UINT counter;
+
+ state = Ctx->STATE;
+ Ctx->X = 0;
+ Ctx->Y = 0;
+ for (counter = 0; counter < 256; counter++)
+ state[counter] = (UCHAR)counter;
+ keyindex = 0;
+ stateindex = 0;
+ for (counter = 0; counter < 256; counter++)
+ {
+ t = state[counter];
+ stateindex = (stateindex + pKey[keyindex] + t) & 0xff;
+ u = state[stateindex];
+ state[stateindex] = t;
+ state[counter] = u;
+ if (++keyindex >= KeyLen)
+ keyindex = 0;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get bytes from ARCFOUR CONTEXT (S-BOX)
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+
+ Return Value:
+ UCHAR - the value of the ARCFOUR CONTEXT (S-BOX)
+
+ Note:
+
+ ========================================================================
+*/
+UCHAR ARCFOUR_BYTE(
+ IN PARCFOURCONTEXT Ctx)
+{
+ UINT x;
+ UINT y;
+ UCHAR sx, sy;
+ PUCHAR state;
+
+ state = Ctx->STATE;
+ x = (Ctx->X + 1) & 0xff;
+ sx = state[x];
+ y = (sx + Ctx->Y) & 0xff;
+ sy = state[y];
+ Ctx->X = x;
+ Ctx->Y = y;
+ state[y] = sx;
+ state[x] = sy;
+
+ return(state[(sx + sy) & 0xff]);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Decryption Algorithm
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pDest Pointer to the Destination
+ pSrc Pointer to the Source data
+ Len Indicate the length of the Source data
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ARCFOUR_DECRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len)
+{
+ UINT i;
+
+ for (i = 0; i < Len; i++)
+ pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Encryption Algorithm
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pDest Pointer to the Destination
+ pSrc Pointer to the Source data
+ Len Indicate the length of the Source dta
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID ARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len)
+{
+ UINT i;
+
+ for (i = 0; i < Len; i++)
+ pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ The Stream Cipher Encryption Algorithm which conform to the special requirement to encrypt GTK.
+
+ Arguments:
+ Ctx Pointer to ARCFOUR CONTEXT (SBOX)
+ pDest Pointer to the Destination
+ pSrc Pointer to the Source data
+ Len Indicate the length of the Source dta
+
+
+ ========================================================================
+*/
+
+VOID WPAARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len)
+{
+ UINT i;
+ //discard first 256 bytes
+ for (i = 0; i < 256; i++)
+ ARCFOUR_BYTE(Ctx);
+
+ for (i = 0; i < Len; i++)
+ pDest[i] = pSrc[i] ^ ARCFOUR_BYTE(Ctx);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Calculate a new FCS given the current FCS and the new data.
+
+ Arguments:
+ Fcs the original FCS value
+ Cp pointer to the data which will be calculate the FCS
+ Len the length of the data
+
+ Return Value:
+ UINT - FCS 32 bits
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+UINT RTMP_CALC_FCS32(
+ IN UINT Fcs,
+ IN PUCHAR Cp,
+ IN INT Len)
+{
+ while (Len--)
+ Fcs = (((Fcs) >> 8) ^ FCSTAB_32[((Fcs) ^ (*Cp++)) & 0xff]);
+
+ return (Fcs);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get last FCS and encrypt it to the destination
+
+ Arguments:
+ pDest Pointer to the Destination
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPSetICV(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest)
+{
+ pAd->PrivateInfo.FCSCRC32 ^= 0xffffffff; /* complement */
+ pAd->PrivateInfo.FCSCRC32 = cpu2le32(pAd->PrivateInfo.FCSCRC32);
+
+ ARCFOUR_ENCRYPT(&pAd->PrivateInfo.WEPCONTEXT, pDest, (PUCHAR) &pAd->PrivateInfo.FCSCRC32, 4);
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_bulk.c b/drivers/staging/rt3070/common/rtusb_bulk.c
new file mode 100644
index 00000000000..1a05703520f
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_bulk.c
@@ -0,0 +1,1382 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtusb_bulk.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-25-2004 created
+
+*/
+
+#include "../rt_config.h"
+// Match total 6 bulkout endpoint to corresponding queue.
+UCHAR EpToQueue[6]={FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_EDCA, FIFO_MGMT};
+
+//static BOOLEAN SingleBulkOut = FALSE;
+
+void RTUSB_FILL_BULK_URB (struct urb *pUrb,
+ struct usb_device *pUsb_Dev,
+ unsigned int bulkpipe,
+ void *pTransferBuf,
+ int BufSize,
+ usb_complete_t Complete,
+ void *pContext)
+{
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, (usb_complete_t)Complete, pContext);
+#else
+ FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
+#endif
+
+}
+
+VOID RTUSBInitTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PTX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN usb_complete_t Func)
+{
+ PURB pUrb;
+ PUCHAR pSrc = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pUrb = pTxContext->pUrb;
+ ASSERT(pUrb);
+
+ // Store BulkOut PipeId
+ pTxContext->BulkOutPipeId = BulkOutPipeId;
+
+ if (pTxContext->bAggregatible)
+ {
+ pSrc = &pTxContext->TransferBuffer->Aggregation[2];
+ }
+ else
+ {
+ pSrc = (PUCHAR) pTxContext->TransferBuffer->field.WirelessPacket;
+ }
+
+
+ //Initialize a tx bulk urb
+ RTUSB_FILL_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
+ pSrc,
+ pTxContext->BulkOutSize,
+ Func,
+ pTxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ if (pTxContext->bAggregatible)
+ pUrb->transfer_dma = (pTxContext->data_dma + TX_BUFFER_NORMSIZE + 2);
+ else
+ pUrb->transfer_dma = pTxContext->data_dma;
+
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+}
+
+VOID RTUSBInitHTTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PHT_TX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN ULONG BulkOutSize,
+ IN usb_complete_t Func)
+{
+ PURB pUrb;
+ PUCHAR pSrc = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pUrb = pTxContext->pUrb;
+ ASSERT(pUrb);
+
+ // Store BulkOut PipeId
+ pTxContext->BulkOutPipeId = BulkOutPipeId;
+
+ pSrc = &pTxContext->TransferBuffer->field.WirelessPacket[pTxContext->NextBulkOutPosition];
+
+
+ //Initialize a tx bulk urb
+ RTUSB_FILL_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ usb_sndbulkpipe(pObj->pUsb_Dev, pAd->BulkOutEpAddr[BulkOutPipeId]),
+ pSrc,
+ BulkOutSize,
+ Func,
+ pTxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ pUrb->transfer_dma = (pTxContext->data_dma + pTxContext->NextBulkOutPosition);
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+}
+
+VOID RTUSBInitRxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PRX_CONTEXT pRxContext)
+{
+ PURB pUrb;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+ ULONG RX_bulk_size;
+
+
+ pUrb = pRxContext->pUrb;
+ ASSERT(pUrb);
+
+ if ( pAd->BulkInMaxPacketSize == 64)
+ RX_bulk_size = 4096;
+ else
+ RX_bulk_size = MAX_RXBULK_SIZE;
+
+ //Initialize a rx bulk urb
+ RTUSB_FILL_BULK_URB(pUrb,
+ pObj->pUsb_Dev,
+ usb_rcvbulkpipe(pObj->pUsb_Dev, pAd->BulkInEpAddr),
+ &(pRxContext->TransferBuffer[pAd->NextRxBulkInPosition]),
+ RX_bulk_size - (pAd->NextRxBulkInPosition),
+ (usb_complete_t)RTUSBBulkRxComplete,
+ (void *)pRxContext);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ pUrb->transfer_dma = pRxContext->data_dma + pAd->NextRxBulkInPosition;
+ pUrb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+#endif
+
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+
+#define BULK_OUT_LOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_LOCK((pLock), IrqFlags);
+
+#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_UNLOCK((pLock), IrqFlags);
+
+
+VOID RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UCHAR Index)
+{
+
+ PHT_TX_CONTEXT pHTTXContext;
+ PURB pUrb;
+ int ret = 0;
+ PTXINFO_STRUC pTxInfo, pLastTxInfo = NULL;
+ PTXWI_STRUC pTxWI;
+ ULONG TmpBulkEndPos, ThisBulkSize;
+ unsigned long IrqFlags = 0, IrqFlags2 = 0;
+ PUCHAR pWirelessPkt, pAppendant;
+ BOOLEAN bTxQLastRound = FALSE;
+ UCHAR allzero[4]= {0x0,0x0,0x0,0x0};
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ if ((pAd->BulkOutPending[BulkOutPipeId] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+ pAd->BulkOutPending[BulkOutPipeId] = TRUE;
+
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)
+ )
+ {
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+
+ pHTTXContext = &(pAd->TxContext[BulkOutPipeId]);
+
+ BULK_OUT_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+ if ((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition)
+ || ((pHTTXContext->ENextBulkOutPosition-8) == pHTTXContext->CurWritePosition))
+ {
+ BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+
+ // Clear Data flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+
+ // Clear Data flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId));
+ RTUSB_CLEAR_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+
+ //DBGPRINT(RT_DEBUG_TRACE,("BulkOut-B:I=0x%lx, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", in_interrupt(),
+ // pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition,
+ // pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+ pHTTXContext->NextBulkOutPosition = pHTTXContext->ENextBulkOutPosition;
+ ThisBulkSize = 0;
+ TmpBulkEndPos = pHTTXContext->NextBulkOutPosition;
+ pWirelessPkt = &pHTTXContext->TransferBuffer->field.WirelessPacket[0];
+
+ if ((pHTTXContext->bCopySavePad == TRUE))
+ {
+ if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("e1, allzero : %x %x %x %x %x %x %x %x \n",
+ pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
+ ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+ }
+ NdisMoveMemory(&pWirelessPkt[TmpBulkEndPos], pHTTXContext->SavedPad, 8);
+ pHTTXContext->bCopySavePad = FALSE;
+ if (pAd->bForcePrintTX == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE,("RTUSBBulkOutDataPacket --> COPY PAD. CurWrite = %ld, NextBulk = %ld. ENextBulk = %ld.\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition));
+ }
+
+ do
+ {
+ pTxInfo = (PTXINFO_STRUC)&pWirelessPkt[TmpBulkEndPos];
+ pTxWI = (PTXWI_STRUC)&pWirelessPkt[TmpBulkEndPos + TXINFO_SIZE];
+
+ if (pAd->bForcePrintTX == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkOutDataPacket AMPDU = %d.\n", pTxWI->AMPDU));
+
+ // add by Iverson, limit BulkOut size to 4k to pass WMM b mode 2T1R test items
+ //if ((ThisBulkSize != 0) && (pTxWI->AMPDU == 0))
+ if ((ThisBulkSize != 0) && (pTxWI->PHYMODE == MODE_CCK))
+ {
+#ifdef INF_AMAZON_SE
+ /*Iverson Add for AMAZON USB (RT2070 && RT3070) to pass WMM A2-T4 ~ A2-T10*/
+ if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
+ {
+ /*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate*/
+ if(pTxWI->PacketId == 6)
+ {
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (BulkOutPipeId == 1)
+ {
+ /*BK No Limit BulkOut size .*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1000) == 0x1000) && (BulkOutPipeId == 0) ))
+ {
+ /*BE Limit BulkOut size to about 4k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x1c00) == 0x1c00) && (BulkOutPipeId == 2) ))
+ {
+ /*VI Limit BulkOut size to about 7k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || (((ThisBulkSize&0x2500) == 0x2500) && (BulkOutPipeId == 3) ))
+ {
+ /*VO Limit BulkOut size to about 9k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+ else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
+ {
+ /* Limit BulkOut size to about 4k bytes.*/
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+#else
+ if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x1000) == 0x1000))
+ {
+ // Limit BulkOut size to about 4k bytes.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+#endif // INF_AMAZON_SE //
+
+ else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
+ {
+ // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
+ // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+ // end Iverson
+ else
+ {
+#ifdef INF_AMAZON_SE
+//#ifdef DOT11_N_SUPPORT
+// if(((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000) || ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0)))
+// {
+// /* AMAZON_SE: BG mode Disable BulkOut Aggregate, N mode BulkOut Aggregaet size 24K */
+// pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+// break;
+// }
+// else
+//#endif // DOT11_N_SUPPORT //
+// {
+ if(OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && (pTxWI->AMPDU == 0))
+ {
+ if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0)) ||
+ (ThisBulkSize != 0))
+ {
+ /* AMAZON_SE: RT2070 Disable BulkOut Aggregate when WMM for USB issue */
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+/*
+ else if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
+ {
+ // Limit BulkOut size to about 24k bytes.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+*/
+#endif // INF_AMAZON_SE //
+
+ if (((ThisBulkSize&0xffff8000) != 0) || ((ThisBulkSize&0x6000) == 0x6000))
+ { // Limit BulkOut size to about 24k bytes.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+
+ else if (((pAd->BulkOutMaxPacketSize < 512) && ((ThisBulkSize&0xfffff800) != 0) ) /*|| ( (ThisBulkSize != 0) && (pTxWI->AMPDU == 0))*/)
+ { // For USB 1.1 or peer which didn't support AMPDU, limit the BulkOut size.
+ // For performence in b/g mode, now just check for USB 1.1 and didn't care about the APMDU or not! 2008/06/04.
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ }
+
+ if (TmpBulkEndPos == pHTTXContext->CurWritePosition)
+ {
+ pHTTXContext->ENextBulkOutPosition = TmpBulkEndPos;
+ break;
+ }
+ //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if (pTxInfo->QSEL != FIFO_EDCA)
+ {
+ printk("%s(): ====> pTxInfo->QueueSel(%d)!= FIFO_EDCA!!!!\n", __FUNCTION__, pTxInfo->QSEL);
+ printk("\tCWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad);
+ hex_dump("Wrong QSel Pkt:", (PUCHAR)&pWirelessPkt[TmpBulkEndPos], (pHTTXContext->CurWritePosition - pHTTXContext->NextBulkOutPosition));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ if (pTxInfo->USBDMATxPktLen <= 8)
+ {
+ BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+ DBGPRINT(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("e2, USBDMATxPktLen==0, Size=%ld, bCSPad=%d, CWPos=%ld, NBPos=%ld, CWRPos=%ld!\n",
+ pHTTXContext->BulkOutSize, pHTTXContext->bCopySavePad, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->CurWriteRealPos));
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR /*RT_DEBUG_TRACE*/,("%x %x %x %x %x %x %x %x \n",
+ pHTTXContext->SavedPad[0], pHTTXContext->SavedPad[1], pHTTXContext->SavedPad[2],pHTTXContext->SavedPad[3]
+ ,pHTTXContext->SavedPad[4], pHTTXContext->SavedPad[5], pHTTXContext->SavedPad[6],pHTTXContext->SavedPad[7]));
+ }
+ pAd->bForcePrintTX = TRUE;
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ //DBGPRINT(RT_DEBUG_LOUD,("Out:pTxInfo->USBDMATxPktLen=%d!\n", pTxInfo->USBDMATxPktLen));
+ return;
+ }
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.OneSecTransmittedByteCount += pTxWI->MPDUtotalByteCount;
+ pAd->RalinkCounters.TransmittedByteCount += pTxWI->MPDUtotalByteCount;
+
+ pLastTxInfo = pTxInfo;
+
+ // Make sure we use EDCA QUEUE.
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pTxInfo->QSEL = FIFO_EDCA; //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+#endif // CONFIG_STA_SUPPORT //
+ ThisBulkSize += (pTxInfo->USBDMATxPktLen+4);
+ TmpBulkEndPos += (pTxInfo->USBDMATxPktLen+4);
+
+ if (TmpBulkEndPos != pHTTXContext->CurWritePosition)
+ pTxInfo->USBDMANextVLD = 1;
+
+ if (pTxInfo->SwUseLastRound == 1)
+ {
+ if (pHTTXContext->CurWritePosition == 8)
+ pTxInfo->USBDMANextVLD = 0;
+ pTxInfo->SwUseLastRound = 0;
+
+ bTxQLastRound = TRUE;
+ pHTTXContext->ENextBulkOutPosition = 8;
+
+ #ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+ #endif // RT_BIG_ENDIAN //
+
+ break;
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+ }while (TRUE);
+
+ // adjust the pTxInfo->USBDMANextVLD value of last pTxInfo.
+ if (pLastTxInfo)
+ {
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+ pLastTxInfo->USBDMANextVLD = 0;
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pLastTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+ }
+
+ /*
+ We need to copy SavedPad when following condition matched!
+ 1. Not the last round of the TxQueue and
+ 2. any match of following cases:
+ (1). The End Position of this bulk out is reach to the Currenct Write position and
+ the TxInfo and related header already write to the CurWritePosition.
+ =>(ENextBulkOutPosition == CurWritePosition) && (CurWriteRealPos > CurWritePosition)
+
+ (2). The EndPosition of the bulk out is not reach to the Current Write Position.
+ =>(ENextBulkOutPosition != CurWritePosition)
+ */
+ if ((bTxQLastRound == FALSE) &&
+ (((pHTTXContext->ENextBulkOutPosition == pHTTXContext->CurWritePosition) && (pHTTXContext->CurWriteRealPos > pHTTXContext->CurWritePosition)) ||
+ (pHTTXContext->ENextBulkOutPosition != pHTTXContext->CurWritePosition))
+ )
+ {
+ NdisMoveMemory(pHTTXContext->SavedPad, &pWirelessPkt[pHTTXContext->ENextBulkOutPosition], 8);
+ pHTTXContext->bCopySavePad = TRUE;
+ if (RTMPEqualMemory(pHTTXContext->SavedPad, allzero,4))
+ {
+ PUCHAR pBuf = &pHTTXContext->SavedPad[0];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("WARNING-Zero-3:%02x%02x%02x%02x%02x%02x%02x%02x,CWPos=%ld, CWRPos=%ld, bCW=%d, NBPos=%ld, TBPos=%ld, TBSize=%ld\n",
+ pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7], pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos,
+ pHTTXContext->bCurWriting, pHTTXContext->NextBulkOutPosition, TmpBulkEndPos, ThisBulkSize));
+
+ pBuf = &pWirelessPkt[pHTTXContext->CurWritePosition];
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("\tCWPos=%02x%02x%02x%02x%02x%02x%02x%02x\n", pBuf[0], pBuf[1], pBuf[2],pBuf[3],pBuf[4], pBuf[5], pBuf[6],pBuf[7]));
+ }
+ //DBGPRINT(RT_DEBUG_LOUD,("ENPos==CWPos=%ld, CWRPos=%ld, bCSPad=%d!\n", pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->bCopySavePad));
+ }
+
+ if (pAd->bForcePrintTX == TRUE)
+ DBGPRINT(RT_DEBUG_TRACE,("BulkOut-A:Size=%ld, CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad));
+ //DBGPRINT(RT_DEBUG_LOUD,("BulkOut-A:Size=%ld, CWPos=%ld, CWRPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, bLRound=%d!\n", ThisBulkSize, pHTTXContext->CurWritePosition, pHTTXContext->CurWriteRealPos, pHTTXContext->NextBulkOutPosition, pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, bTxQLastRound));
+
+ // USB DMA engine requires to pad extra 4 bytes. This pad doesn't count into real bulkoutsize.
+ pAppendant = &pWirelessPkt[TmpBulkEndPos];
+ NdisZeroMemory(pAppendant, 8);
+ ThisBulkSize += 4;
+ pHTTXContext->LastOne = TRUE;
+ if ((ThisBulkSize % pAd->BulkOutMaxPacketSize) == 0)
+ ThisBulkSize += 4;
+ pHTTXContext->BulkOutSize = ThisBulkSize;
+
+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 1;
+ BULK_OUT_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags2);
+
+ // Init Tx context descriptor
+ RTUSBInitHTTxDesc(pAd, pHTTXContext, BulkOutPipeId, ThisBulkSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
+
+ pUrb = pHTTXContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ pAd->watchDogTxPendingCnt[BulkOutPipeId] = 0;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ return;
+ }
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pHTTXContext->IRPPending = TRUE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutReq++;
+
+}
+
+
+VOID RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PHT_TX_CONTEXT pHTTXContext;
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+ UCHAR BulkOutPipeId;
+
+
+ pHTTXContext = (PHT_TX_CONTEXT)pUrb->context;
+ pAd = pHTTXContext->pAd;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ // Store BulkOut PipeId
+ BulkOutPipeId = pHTTXContext->BulkOutPipeId;
+ pAd->BulkOutDataOneSecCount++;
+
+ switch (BulkOutPipeId)
+ {
+ case 0:
+ pObj->ac0_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac0_dma_done_task);
+ break;
+ case 1:
+ pObj->ac1_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac1_dma_done_task);
+ break;
+ case 2:
+ pObj->ac2_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac2_dma_done_task);
+ break;
+ case 3:
+ pObj->ac3_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->ac3_dma_done_task);
+ break;
+ case 4:
+ pObj->hcca_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->hcca_dma_done_task);
+ break;
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note: NULL frame use BulkOutPipeId = 0
+
+ ========================================================================
+*/
+VOID RTUSBBulkOutNullFrame(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+ return;
+ }
+ pAd->BulkOutPending[0] = TRUE;
+ pAd->watchDogTxPendingCnt[0] = 1;
+ pNullContext->IRPPending = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
+
+
+ // Clear Null frame bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL);
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pNullContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pNullContext, 0, (usb_complete_t)RTUSBBulkOutNullFrameComplete);
+
+ pUrb = pNullContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ pAd->BulkOutPending[0] = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+ pNullContext->IRPPending = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutNullFrame: Submit Tx URB failed %d\n", ret));
+ return;
+ }
+
+}
+
+// NULL frame use BulkOutPipeId = 0
+VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pNullContext;
+ NTSTATUS Status;
+ POS_COOKIE pObj;
+
+
+ pNullContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pNullContext->pAd;
+ Status = pUrb->status;
+
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ pObj->null_frame_complete_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->null_frame_complete_task);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note: MLME use BulkOutPipeId = 0
+
+ ========================================================================
+*/
+VOID RTUSBBulkOutMLMEPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PTX_CONTEXT pMLMEContext;
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa;
+ pUrb = pMLMEContext->pUrb;
+
+ if ((pAd->MgmtRing.TxSwFreeIdx >= MGMT_RING_SIZE) ||
+ (pMLMEContext->InUse == FALSE) ||
+ (pMLMEContext->bWaitingBulkOut == FALSE))
+ {
+
+
+ // Clear MLME bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+
+ return;
+ }
+
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+ if ((pAd->BulkOutPending[MGMTPIPEIDX] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+ return;
+ }
+
+ pAd->BulkOutPending[MGMTPIPEIDX] = TRUE;
+ pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 1;
+ pMLMEContext->IRPPending = TRUE;
+ pMLMEContext->bWaitingBulkOut = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.TransmittedByteCount += pMLMEContext->BulkOutSize;
+
+ // Clear MLME bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pMLMEContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pMLMEContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutMLMEPacketComplete);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ //For mgmt urb buffer, because we use sk_buff, so we need to notify the USB controller do dma mapping.
+ pUrb->transfer_dma = 0;
+ pUrb->transfer_flags &= (~URB_NO_TRANSFER_DMA_MAP);
+#endif
+
+ pUrb = pMLMEContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutMLMEPacket: Submit MLME URB failed %d\n", ret));
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+ pAd->watchDogTxPendingCnt[MGMTPIPEIDX] = 0;
+ pMLMEContext->IRPPending = FALSE;
+ pMLMEContext->bWaitingBulkOut = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[MGMTPIPEIDX], IrqFlags);
+
+ return;
+ }
+
+ //DBGPRINT_RAW(RT_DEBUG_INFO, ("<---RTUSBBulkOutMLMEPacket \n"));
+// printk("<---RTUSBBulkOutMLMEPacket,Cpu=%d!, Dma=%d, SwIdx=%d!\n", pAd->MgmtRing.TxCpuIdx, pAd->MgmtRing.TxDmaIdx, pAd->MgmtRing.TxSwFreeIdx);
+}
+
+
+VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PTX_CONTEXT pMLMEContext;
+ PRTMP_ADAPTER pAd;
+ NTSTATUS Status;
+ POS_COOKIE pObj;
+ int index;
+
+ //DBGPRINT_RAW(RT_DEBUG_INFO, ("--->RTUSBBulkOutMLMEPacketComplete\n"));
+ pMLMEContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pMLMEContext->pAd;
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+ Status = pUrb->status;
+ index = pMLMEContext->SelfIdx;
+
+ pObj->mgmt_dma_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->mgmt_dma_done_task);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note: PsPoll use BulkOutPipeId = 0
+
+ ========================================================================
+*/
+VOID RTUSBBulkOutPsPoll(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTX_CONTEXT pPsPollContext = &(pAd->PsPollContext);
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ if ((pAd->BulkOutPending[0] == TRUE) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_TX))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+ return;
+ }
+ pAd->BulkOutPending[0] = TRUE;
+ pAd->watchDogTxPendingCnt[0] = 1;
+ pPsPollContext->IRPPending = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+
+ // Clear PS-Poll bulk flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL);
+
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR)pPsPollContext->TransferBuffer, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pPsPollContext, MGMTPIPEIDX, (usb_complete_t)RTUSBBulkOutPsPollComplete);
+
+ pUrb = pPsPollContext->pUrb;
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ pAd->BulkOutPending[0] = FALSE;
+ pAd->watchDogTxPendingCnt[0] = 0;
+ pPsPollContext->IRPPending = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkOutPsPoll: Submit Tx URB failed %d\n", ret));
+ return;
+ }
+
+}
+
+// PS-Poll frame use BulkOutPipeId = 0
+VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb,struct pt_regs *pt_regs)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pPsPollContext;
+ NTSTATUS Status;
+ POS_COOKIE pObj;
+
+
+ pPsPollContext= (PTX_CONTEXT)pUrb->context;
+ pAd = pPsPollContext->pAd;
+ Status = pUrb->status;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+ pObj->pspoll_frame_complete_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->pspoll_frame_complete_task);
+
+}
+
+VOID DoBulkIn(IN RTMP_ADAPTER *pAd)
+{
+ PRX_CONTEXT pRxContext;
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
+ if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ return;
+ }
+ pRxContext->InUse = TRUE;
+ pRxContext->IRPPending = TRUE;
+ pAd->PendingRx++;
+ pAd->BulkInReq++;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // Init Rx context descriptor
+ NdisZeroMemory(pRxContext->TransferBuffer, pRxContext->BulkInOffset);
+ RTUSBInitRxDesc(pAd, pRxContext);
+
+ pUrb = pRxContext->pUrb;
+ if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ { // fail
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pAd->PendingRx--;
+ pAd->BulkInReq--;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSBBulkReceive: Submit Rx URB failed %d\n", ret));
+ }
+ else
+ { // success
+ ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+ //printk("BIDone, Pend=%d,BIIdx=%d,BIRIdx=%d!\n", pAd->PendingRx, pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex);
+ }
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ USB_RxPacket initializes a URB and uses the Rx IRP to submit it
+ to USB. It checks if an Rx Descriptor is available and passes the
+ the coresponding buffer to be filled. If no descriptor is available
+ fails the request. When setting the completion routine we pass our
+ Adapter Object as Context.
+
+ Arguments:
+
+ Return Value:
+ TRUE found matched tuple cache
+ FALSE no matched found
+
+ Note:
+
+ ========================================================================
+*/
+#define fRTMP_ADAPTER_NEED_STOP_RX \
+ (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
+ fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
+ fRTMP_ADAPTER_REMOVE_IN_PROGRESS | fRTMP_ADAPTER_BULKIN_RESET)
+
+#define fRTMP_ADAPTER_NEED_STOP_HANDLE_RX \
+ (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
+ fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_RESET_IN_PROGRESS | \
+ fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+VOID RTUSBBulkReceive(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRX_CONTEXT pRxContext;
+ unsigned long IrqFlags;
+
+
+ /* sanity check */
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_HANDLE_RX))
+ return;
+
+ while(1)
+ {
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext = &(pAd->RxContext[pAd->NextRxBulkInReadIndex]);
+ if (((pRxContext->InUse == FALSE) && (pRxContext->Readable == TRUE)) &&
+ (pRxContext->bRxHandling == FALSE))
+ {
+ pRxContext->bRxHandling = TRUE;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // read RxContext, Since not
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ STARxDoneInterruptHandle(pAd, TRUE);
+#endif // CONFIG_STA_SUPPORT //
+
+ // Finish to handle this bulkIn buffer.
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->BulkInOffset = 0;
+ pRxContext->Readable = FALSE;
+ pRxContext->bRxHandling = FALSE;
+ pAd->ReadPosition = 0;
+ pAd->TransferBufferLength = 0;
+ INC_RING_INDEX(pAd->NextRxBulkInReadIndex, RX_RING_SIZE);
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ }
+ else
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ break;
+ }
+ }
+
+ if (!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NEED_STOP_RX)))
+ DoBulkIn(pAd);
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ This routine process Rx Irp and call rx complete function.
+
+ Arguments:
+ DeviceObject Pointer to the device object for next lower
+ device. DeviceObject passed in here belongs to
+ the next lower driver in the stack because we
+ were invoked via IoCallDriver in USB_RxPacket
+ AND it is not OUR device object
+ Irp Ptr to completed IRP
+ Context Ptr to our Adapter object (context specified
+ in IoSetCompletionRoutine
+
+ Return Value:
+ Always returns STATUS_MORE_PROCESSING_REQUIRED
+
+ Note:
+ Always returns STATUS_MORE_PROCESSING_REQUIRED
+ ========================================================================
+*/
+VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ // use a receive tasklet to handle received packets;
+ // or sometimes hardware IRQ will be disabled here, so we can not
+ // use spin_lock_bh()/spin_unlock_bh() after IRQ is disabled. :<
+ PRX_CONTEXT pRxContext;
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+
+
+ pRxContext = (PRX_CONTEXT)pUrb->context;
+ pAd = pRxContext->pAd;
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ pObj->rx_done_task.data = (unsigned long)pUrb;
+ tasklet_hi_schedule(&pObj->rx_done_task);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBKickBulkOut(
+ IN PRTMP_ADAPTER pAd)
+{
+ // BulkIn Reset will reset whole USB PHY. So we need to make sure fRTMP_ADAPTER_BULKIN_RESET not flaged.
+ if (!RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX)
+#ifdef RALINK_ATE
+ && !(ATE_ON(pAd))
+#endif // RALINK_ATE //
+ )
+ {
+ // 2. PS-Poll frame is next
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL))
+ {
+ RTUSBBulkOutPsPoll(pAd);
+ }
+
+ // 5. Mlme frame is next
+ else if ((RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME)) &&
+ (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE))
+ {
+ RTUSBBulkOutMLMEPacket(pAd, pAd->MgmtRing.TxDmaIdx);
+ }
+
+ // 6. Data frame normal is next
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 0, pAd->NextBulkOutIndex[0]);
+ }
+ }
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_2))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 1, pAd->NextBulkOutIndex[1]);
+ }
+ }
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_3))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 2, pAd->NextBulkOutIndex[2]);
+ }
+ }
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_4))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ RTUSBBulkOutDataPacket(pAd, 3, pAd->NextBulkOutIndex[3]);
+ }
+ }
+ //PS packets use HCCA queue when dequeue from PS unicast queue (WiFi WPA2 MA9_DT1 for Marvell B STA)
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NORMAL_5))
+ {
+ if (((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) ||
+ (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ ))
+ {
+ }
+ }
+
+ // 7. Null frame is the last
+ else if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_NULL))
+ {
+ if (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ RTUSBBulkOutNullFrame(pAd);
+ }
+ }
+
+ // 8. No data avaliable
+ else
+ {
+
+ }
+ }
+#ifdef RALINK_ATE
+ /* If the mode is in ATE mode. */
+ else if((ATE_ON(pAd)) &&
+ !RTMP_TEST_FLAG(pAd ,fRTMP_ADAPTER_NEED_STOP_TX))// PETER : watch out !
+ {
+ if (RTUSB_TEST_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE))
+ {
+ ATE_RTUSBBulkOutDataPacket(pAd, 0);
+ }
+ }
+#endif // RALINK_ATE //
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Call from Reset action after BulkOut failed.
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCleanUpDataBulkOutQueue(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR Idx;
+ PHT_TX_CONTEXT pTxContext;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpDataBulkOutQueue\n"));
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ pTxContext = &pAd->TxContext[Idx];
+
+ pTxContext->CurWritePosition = pTxContext->NextBulkOutPosition;
+ pTxContext->LastOne = FALSE;
+ NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
+ pAd->BulkOutPending[Idx] = FALSE;
+ NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpDataBulkOutQueue\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCleanUpMLMEBulkOutQueue(
+ IN PRTMP_ADAPTER pAd)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("--->CleanUpMLMEBulkOutQueue\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("<---CleanUpMLMEBulkOutQueue\n"));
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCancelPendingIRPs(
+ IN PRTMP_ADAPTER pAd)
+{
+ RTUSBCancelPendingBulkInIRP(pAd);
+ RTUSBCancelPendingBulkOutIRP(pAd);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRX_CONTEXT pRxContext;
+ UINT i;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->RTUSBCancelPendingBulkInIRP\n"));
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ pRxContext = &(pAd->RxContext[i]);
+ if(pRxContext->IRPPending == TRUE)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ pRxContext->IRPPending = FALSE;
+ pRxContext->InUse = FALSE;
+ //NdisInterlockedDecrement(&pAd->PendingRx);
+ //pAd->PendingRx--;
+ }
+ }
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("<---RTUSBCancelPendingBulkInIRP\n"));
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBCancelPendingBulkOutIRP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PHT_TX_CONTEXT pHTTXContext;
+ PTX_CONTEXT pMLMEContext;
+ PTX_CONTEXT pBeaconContext;
+ PTX_CONTEXT pNullContext;
+ PTX_CONTEXT pPsPollContext;
+ PTX_CONTEXT pRTSContext;
+ UINT i, Idx;
+// unsigned int IrqFlags;
+// NDIS_SPIN_LOCK *pLock;
+// BOOLEAN *pPending;
+
+
+// pLock = &pAd->BulkOutLock[MGMTPIPEIDX];
+// pPending = &pAd->BulkOutPending[MGMTPIPEIDX];
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ pHTTXContext = &(pAd->TxContext[Idx]);
+
+ if (pHTTXContext->IRPPending == TRUE)
+ {
+
+ // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+ // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+ // when the last IRP on the list has been cancelled; that's how we exit this loop
+ //
+
+ RTUSB_UNLINK_URB(pHTTXContext->pUrb);
+
+ // Sleep 200 microseconds to give cancellation time to work
+ RTMPusecDelay(200);
+ }
+
+#ifdef RALINK_ATE
+ pHTTXContext->bCopySavePad = 0;
+ pHTTXContext->CurWritePosition = 0;
+ pHTTXContext->CurWriteRealPos = 0;
+ pHTTXContext->bCurWriting = FALSE;
+ pHTTXContext->NextBulkOutPosition = 0;
+ pHTTXContext->ENextBulkOutPosition = 0;
+#endif // RALINK_ATE //
+ pAd->BulkOutPending[Idx] = FALSE;
+ }
+
+ //RTMP_IRQ_LOCK(pLock, IrqFlags);
+ for (i = 0; i < MGMT_RING_SIZE; i++)
+ {
+ pMLMEContext = (PTX_CONTEXT)pAd->MgmtRing.Cell[i].AllocVa;
+ if(pMLMEContext && (pMLMEContext->IRPPending == TRUE))
+ {
+
+ // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+ // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+ // when the last IRP on the list has been cancelled; that's how we exit this loop
+ //
+
+ RTUSB_UNLINK_URB(pMLMEContext->pUrb);
+ pMLMEContext->IRPPending = FALSE;
+
+ // Sleep 200 microsecs to give cancellation time to work
+ RTMPusecDelay(200);
+ }
+ }
+ pAd->BulkOutPending[MGMTPIPEIDX] = FALSE;
+ //RTMP_IRQ_UNLOCK(pLock, IrqFlags);
+
+
+ for (i = 0; i < BEACON_RING_SIZE; i++)
+ {
+ pBeaconContext = &(pAd->BeaconContext[i]);
+
+ if(pBeaconContext->IRPPending == TRUE)
+ {
+
+ // Get the USB_CONTEXT and cancel it's IRP; the completion routine will itself
+ // remove it from the HeadPendingSendList and NULL out HeadPendingSendList
+ // when the last IRP on the list has been cancelled; that's how we exit this loop
+ //
+
+ RTUSB_UNLINK_URB(pBeaconContext->pUrb);
+
+ // Sleep 200 microsecs to give cancellation time to work
+ RTMPusecDelay(200);
+ }
+ }
+
+ pNullContext = &(pAd->NullContext);
+ if (pNullContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pNullContext->pUrb);
+
+ pRTSContext = &(pAd->RTSContext);
+ if (pRTSContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pRTSContext->pUrb);
+
+ pPsPollContext = &(pAd->PsPollContext);
+ if (pPsPollContext->IRPPending == TRUE)
+ RTUSB_UNLINK_URB(pPsPollContext->pUrb);
+
+ for (Idx = 0; Idx < 4; Idx++)
+ {
+ NdisAcquireSpinLock(&pAd->BulkOutLock[Idx]);
+ pAd->BulkOutPending[Idx] = FALSE;
+ NdisReleaseSpinLock(&pAd->BulkOutLock[Idx]);
+ }
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_data.c b/drivers/staging/rt3070/common/rtusb_data.c
new file mode 100644
index 00000000000..521309a2ae5
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_data.c
@@ -0,0 +1,218 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtusb_data.c
+
+ Abstract:
+ Ralink USB driver Tx/Rx functions.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan 03-25-2006 created
+
+*/
+#include "../rt_config.h"
+
+extern UCHAR Phy11BGNextRateUpward[]; // defined in mlme.c
+extern UCHAR EpToQueue[];
+
+
+VOID REPORT_AMSDU_FRAMES_TO_LLC(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataSize)
+{
+ PNDIS_PACKET pPacket;
+ UINT nMSDU;
+ struct sk_buff *pSkb;
+
+ nMSDU = 0;
+ /* allocate a rx packet */
+ pSkb = dev_alloc_skb(RX_BUFFER_AGGRESIZE);
+ pPacket = (PNDIS_PACKET)OSPKT_TO_RTPKT(pSkb);
+ if (pSkb)
+ {
+
+ /* convert 802.11 to 802.3 packet */
+ pSkb->dev = get_netdev_from_bssid(pAd, BSS0);
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+ deaggregate_AMSDU_announce(pAd, pPacket, pData, DataSize);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Can't allocate skb\n"));
+ }
+}
+
+NDIS_STATUS RTUSBFreeDescriptorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UINT32 NumberRequired)
+{
+// UCHAR FreeNumber = 0;
+// UINT Index;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+
+
+ pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ if ((pHTTXContext->CurWritePosition < pHTTXContext->NextBulkOutPosition) && ((pHTTXContext->CurWritePosition + NumberRequired + LOCAL_TXBUF_SIZE) > pHTTXContext->NextBulkOutPosition))
+ {
+
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ else if ((pHTTXContext->CurWritePosition == 8) && (pHTTXContext->NextBulkOutPosition < (NumberRequired + LOCAL_TXBUF_SIZE)))
+ {
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ else if (pHTTXContext->bCurWriting == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("RTUSBFreeD c3 --> QueIdx=%d, CWPos=%ld, NBOutPos=%ld!\n", BulkOutPipeId, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition));
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId));
+ }
+ else
+ {
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+
+ return (Status);
+}
+
+
+NDIS_STATUS RTUSBFreeDescriptorRelease(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId)
+{
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+
+ pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ pHTTXContext->bCurWriting = FALSE;
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+ return (NDIS_STATUS_SUCCESS);
+}
+
+
+BOOLEAN RTUSBNeedQueueBackForAgg(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId)
+{
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+ BOOLEAN needQueBack = FALSE;
+
+ pHTTXContext = &pAd->TxContext[BulkOutPipeId];
+
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+ if ((pHTTXContext->IRPPending == TRUE) /*&& (pAd->TxSwQueue[BulkOutPipeId].Number == 0) */)
+ {
+ if ((pHTTXContext->CurWritePosition < pHTTXContext->ENextBulkOutPosition) &&
+ (((pHTTXContext->ENextBulkOutPosition+MAX_AGGREGATION_SIZE) < MAX_TXBULK_LIMIT) || (pHTTXContext->CurWritePosition > MAX_AGGREGATION_SIZE)))
+ {
+ needQueBack = TRUE;
+ }
+ else if ((pHTTXContext->CurWritePosition > pHTTXContext->ENextBulkOutPosition) &&
+ ((pHTTXContext->ENextBulkOutPosition + MAX_AGGREGATION_SIZE) < pHTTXContext->CurWritePosition))
+ {
+ needQueBack = TRUE;
+ }
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[BulkOutPipeId], IrqFlags);
+
+ return needQueBack;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBRejectPendingPackets(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR Index;
+ PQUEUE_ENTRY pEntry;
+ PNDIS_PACKET pPacket;
+ PQUEUE_HEADER pQueue;
+
+
+ for (Index = 0; Index < 4; Index++)
+ {
+ NdisAcquireSpinLock(&pAd->TxSwQueueLock[Index]);
+ while (pAd->TxSwQueue[Index].Head != NULL)
+ {
+ pQueue = (PQUEUE_HEADER) &(pAd->TxSwQueue[Index]);
+ pEntry = RemoveHeadQueue(pQueue);
+ pPacket = QUEUE_ENTRY_TO_PACKET(pEntry);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ NdisReleaseSpinLock(&pAd->TxSwQueueLock[Index]);
+
+ }
+
+}
+
+VOID RTMPWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst)
+{
+ pTxInfo->USBDMATxPktLen = USBDMApktLen;
+ pTxInfo->QSEL = QueueSel;
+ if (QueueSel != FIFO_EDCA)
+ DBGPRINT(RT_DEBUG_TRACE, ("====> QueueSel != FIFO_EDCA<============\n"));
+ pTxInfo->USBDMANextVLD = FALSE; //NextValid; // Need to check with Jan about this.
+ pTxInfo->USBDMATxburst = TxBurst;
+ pTxInfo->WIV = bWiv;
+ pTxInfo->SwUseLastRound = 0;
+ pTxInfo->rsv = 0;
+ pTxInfo->rsv2 = 0;
+}
+
diff --git a/drivers/staging/rt3070/common/rtusb_io.c b/drivers/staging/rt3070/common/rtusb_io.c
new file mode 100644
index 00000000000..a6a52e3445f
--- /dev/null
+++ b/drivers/staging/rt3070/common/rtusb_io.c
@@ -0,0 +1,1908 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtusb_io.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 06-25-2004 created
+*/
+
+#include "../rt_config.h"
+
+
+/*
+ ========================================================================
+
+ Routine Description: NIC initialization complete
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+
+NTSTATUS RTUSBFirmwareRun(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x8,
+ 0,
+ NULL,
+ 0);
+
+ return Status;
+}
+
+
+
+/*
+ ========================================================================
+
+ Routine Description: Write Firmware to NIC.
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBFirmwareWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFwImage,
+ IN ULONG FwLen)
+{
+ UINT32 MacReg;
+ NTSTATUS Status;
+// ULONG i;
+ USHORT writeLen;
+
+ Status = RTUSBReadMACRegister(pAd, MAC_CSR0, &MacReg);
+
+
+ writeLen = FwLen;
+ RTUSBMultiWrite(pAd, FIRMWARE_IMAGE_BASE, pFwImage, writeLen);
+
+ Status = RTUSBWriteMACRegister(pAd, 0x7014, 0xffffffff);
+ Status = RTUSBWriteMACRegister(pAd, 0x701c, 0xffffffff);
+ Status = RTUSBFirmwareRun(pAd);
+
+ RTMPusecDelay(10000);
+ RTUSBWriteMACRegister(pAd,H2M_MAILBOX_CSR,0);
+ AsicSendCommandToMcu(pAd, 0x72, 0x00, 0x00, 0x00);//reset rf by MCU supported by new firmware
+
+ return Status;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Get current firmware operation mode (Return Value)
+
+ Arguments:
+
+ Return Value:
+ 0 or 1 = Downloaded by host driver
+ others = Driver doesn't download firmware
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBFirmwareOpmode(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUINT32 pValue)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x1,
+ 0x11,
+ 0,
+ pValue,
+ 4);
+ return Status;
+}
+NTSTATUS RTUSBVenderReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("-->RTUSBVenderReset\n"));
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x1,
+ 0,
+ NULL,
+ 0);
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("<--RTUSBVenderReset\n"));
+ return Status;
+}
+/*
+ ========================================================================
+
+ Routine Description: Read various length data from RT2573
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBMultiRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x7,
+ 0,
+ Offset,
+ pData,
+ length);
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description: Write various length data to RT2573
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBMultiWrite_OneByte(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData)
+{
+ NTSTATUS Status;
+
+ // TODO: In 2870, use this funciton carefully cause it's not stable.
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x6,
+ 0,
+ Offset,
+ pData,
+ 1);
+
+ return Status;
+}
+
+NTSTATUS RTUSBMultiWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status;
+
+
+ USHORT index = 0,Value;
+ PUCHAR pSrc = pData;
+ USHORT resude = 0;
+
+ resude = length % 2;
+ length += resude;
+ do
+ {
+ Value =(USHORT)( *pSrc | (*(pSrc + 1) << 8));
+ Status = RTUSBSingleWrite(pAd,Offset + index,Value);
+ index +=2;
+ length -= 2;
+ pSrc = pSrc + 2;
+ }while(length > 0);
+
+ return Status;
+}
+
+
+NTSTATUS RTUSBSingleWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN USHORT Value)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x2,
+ Value,
+ Offset,
+ NULL,
+ 0);
+
+ return Status;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Read 32-bit MAC register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUINT32 pValue)
+{
+ NTSTATUS Status;
+ UINT32 localVal;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x7,
+ 0,
+ Offset,
+ &localVal,
+ 4);
+
+ *pValue = le2cpu32(localVal);
+
+
+ if (Status < 0)
+ *pValue = 0xffffffff;
+
+ return Status;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description: Write 32-bit MAC register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN UINT32 Value)
+{
+ NTSTATUS Status;
+ UINT32 localVal;
+
+ localVal = Value;
+
+ Status = RTUSBSingleWrite(pAd, Offset, (USHORT)(localVal & 0xffff));
+ Status = RTUSBSingleWrite(pAd, Offset + 2, (USHORT)((localVal & 0xffff0000) >> 16));
+
+ return Status;
+}
+
+
+
+#if 1
+/*
+ ========================================================================
+
+ Routine Description: Read 8-bit BBP register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN PUCHAR pValue)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ UINT i = 0;
+ NTSTATUS status;
+
+ // Verify the busy condition
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+ if(status >= 0)
+ {
+ if (!(BbpCsr.field.Busy == BUSY))
+ break;
+ }
+ printk("RTUSBReadBBPRegister(BBP_CSR_CFG_1):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ //
+ // Read failed then Return Default value.
+ //
+ *pValue = pAd->BbpWriteLatch[Id];
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ // Prepare for write material
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = Id;
+ RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+ i = 0;
+ // Verify the busy condition
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+ if (status >= 0)
+ {
+ if (!(BbpCsr.field.Busy == BUSY))
+ {
+ *pValue = (UCHAR)BbpCsr.field.Value;
+ break;
+ }
+ }
+ printk("RTUSBReadBBPRegister(BBP_CSR_CFG_2):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ //
+ // Read failed then Return Default value.
+ //
+ *pValue = pAd->BbpWriteLatch[Id];
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ return STATUS_SUCCESS;
+}
+#else
+/*
+ ========================================================================
+
+ Routine Description: Read 8-bit BBP register via firmware
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN PUCHAR pValue)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ int i, k;
+ for (i=0; i<MAX_BUSY_COUNT; i++)
+ {
+ RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == BUSY)
+ {
+ continue;
+ }
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 1;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = Id;
+ RTUSBWriteMACRegister(pAd, H2M_BBP_AGENT, BbpCsr.word);
+ AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
+ for (k=0; k<MAX_BUSY_COUNT; k++)
+ {
+ RTUSBReadMACRegister(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == IDLE)
+ break;
+ }
+ if ((BbpCsr.field.Busy == IDLE) &&
+ (BbpCsr.field.RegNum == Id))
+ {
+ *pValue = (UCHAR)BbpCsr.field.Value;
+ break;
+ }
+ }
+ if (BbpCsr.field.Busy == BUSY)
+ {
+ DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", Id, BbpCsr.word));
+ *pValue = pAd->BbpWriteLatch[Id];
+ return STATUS_UNSUCCESSFUL;
+ }
+ return STATUS_SUCCESS;
+}
+#endif
+
+#if 1
+/*
+ ========================================================================
+
+ Routine Description: Write 8-bit BBP register
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN UCHAR Value)
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ UINT i = 0;
+ NTSTATUS status;
+ // Verify the busy condition
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, BBP_CSR_CFG, &BbpCsr.word);
+ if (status >= 0)
+ {
+ if (!(BbpCsr.field.Busy == BUSY))
+ break;
+ }
+ printk("RTUSBWriteBBPRegister(BBP_CSR_CFG):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ // Prepare for write material
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 0;
+ BbpCsr.field.Value = Value;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.RegNum = Id;
+ RTUSBWriteMACRegister(pAd, BBP_CSR_CFG, BbpCsr.word);
+
+ pAd->BbpWriteLatch[Id] = Value;
+
+ return STATUS_SUCCESS;
+}
+#else
+/*
+ ========================================================================
+
+ Routine Description: Write 8-bit BBP register via firmware
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+
+NTSTATUS RTUSBWriteBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN UCHAR Value)
+
+{
+ BBP_CSR_CFG_STRUC BbpCsr;
+ int BusyCnt;
+ for (BusyCnt=0; BusyCnt<MAX_BUSY_COUNT; BusyCnt++)
+ {
+ RTMP_IO_READ32(pAd, H2M_BBP_AGENT, &BbpCsr.word);
+ if (BbpCsr.field.Busy == BUSY)
+ continue;
+ BbpCsr.word = 0;
+ BbpCsr.field.fRead = 0;
+ BbpCsr.field.BBP_RW_MODE = 1;
+ BbpCsr.field.Busy = 1;
+ BbpCsr.field.Value = Value;
+ BbpCsr.field.RegNum = Id;
+ RTMP_IO_WRITE32(pAd, H2M_BBP_AGENT, BbpCsr.word);
+ AsicSendCommandToMcu(pAd, 0x80, 0xff, 0x0, 0x0);
+ pAd->BbpWriteLatch[Id] = Value;
+ break;
+ }
+ if (BusyCnt == MAX_BUSY_COUNT)
+ {
+ DBGPRINT_ERR(("BBP write R%d=0x%x fail\n", Id, BbpCsr.word));
+ return STATUS_UNSUCCESSFUL;
+ }
+ return STATUS_SUCCESS;
+}
+#endif
+/*
+ ========================================================================
+
+ Routine Description: Write RF register through MAC
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 Value)
+{
+ PHY_CSR4_STRUC PhyCsr4;
+ UINT i = 0;
+ NTSTATUS status;
+
+ NdisZeroMemory(&PhyCsr4, sizeof(PHY_CSR4_STRUC));
+ do
+ {
+ status = RTUSBReadMACRegister(pAd, RF_CSR_CFG0, &PhyCsr4.word);
+ if (status >= 0)
+ {
+ if (!(PhyCsr4.field.Busy))
+ break;
+ }
+ printk("RTUSBWriteRFRegister(RF_CSR_CFG0):retry count=%d!\n", i);
+ i++;
+ }
+ while ((i < RETRY_LIMIT) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)));
+
+ if ((i == RETRY_LIMIT) || (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Retry count exhausted or device removed!!!\n"));
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ RTUSBWriteMACRegister(pAd, RF_CSR_CFG0, Value);
+
+ return STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBReadEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+#ifdef RT30xx
+ if(pAd->bUseEfuse)
+ {
+ Status =eFuseRead(pAd, Offset, pData, length);
+ }
+ else
+#endif // RT30xx //
+ {
+ Status = RTUSB_VendorRequest(
+ pAd,
+ (USBD_TRANSFER_DIRECTION_IN | USBD_SHORT_TRANSFER_OK),
+ DEVICE_VENDOR_REQUEST_IN,
+ 0x9,
+ 0,
+ Offset,
+ pData,
+ length);
+ }
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWriteEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length)
+{
+ NTSTATUS Status = STATUS_SUCCESS;
+
+#ifdef RT30xx
+ if(pAd->bUseEfuse)
+ {
+ Status = eFuseWrite(pAd, Offset, pData, length);
+ }
+ else
+#endif // RT30xx //
+ {
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x8,
+ 0,
+ Offset,
+ pData,
+ length);
+ }
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBPutToSleep(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 value;
+
+ // Timeout 0x40 x 50us
+ value = (SLEEPCID<<16)+(OWNERMCU<<24)+ (0x40<<8)+1;
+ RTUSBWriteMACRegister(pAd, 0x7010, value);
+ RTUSBWriteMACRegister(pAd, 0x404, 0x30);
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("Sleep Mailbox testvalue %x\n", value));
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSBWakeUp(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status;
+
+ Status = RTUSB_VendorRequest(
+ pAd,
+ USBD_TRANSFER_DIRECTION_OUT,
+ DEVICE_VENDOR_REQUEST_OUT,
+ 0x01,
+ 0x09,
+ 0,
+ NULL,
+ 0);
+
+ return Status;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBInitializeCmdQ(
+ IN PCmdQ cmdq)
+{
+ cmdq->head = NULL;
+ cmdq->tail = NULL;
+ cmdq->size = 0;
+ cmdq->CmdQState = RT2870_THREAD_INITED;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTUSBEnqueueCmdFromNdis(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN BOOLEAN SetInformation,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength)
+{
+ NDIS_STATUS status;
+ PCmdQElmt cmdqelmt = NULL;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+
+ if (pObj->RTUSBCmdThr_pid < 0)
+ return (NDIS_STATUS_RESOURCES);
+
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
+ return (NDIS_STATUS_RESOURCES);
+
+ cmdqelmt->buffer = NULL;
+ if (pInformationBuffer != NULL)
+ {
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
+ {
+ kfree(cmdqelmt);
+ return (NDIS_STATUS_RESOURCES);
+ }
+ else
+ {
+ NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+ cmdqelmt->bufferlength = InformationBufferLength;
+ }
+ }
+ else
+ cmdqelmt->bufferlength = 0;
+
+ cmdqelmt->command = Oid;
+ cmdqelmt->CmdFromNdis = TRUE;
+ if (SetInformation == TRUE)
+ cmdqelmt->SetOperation = TRUE;
+ else
+ cmdqelmt->SetOperation = FALSE;
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
+ {
+ EnqueueCmd((&pAd->CmdQ), cmdqelmt);
+ status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = NDIS_STATUS_FAILURE;
+ }
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ if (cmdqelmt->buffer)
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ RTUSBCMDUp(pAd);
+
+
+ return(NDIS_STATUS_SUCCESS);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTUSBEnqueueInternalCmd(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength)
+{
+ NDIS_STATUS status;
+ PCmdQElmt cmdqelmt = NULL;
+
+
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt, sizeof(CmdQElmt));
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt == NULL))
+ return (NDIS_STATUS_RESOURCES);
+ NdisZeroMemory(cmdqelmt, sizeof(CmdQElmt));
+
+ if(InformationBufferLength > 0)
+ {
+ status = RTMPAllocateMemory((PVOID *)&cmdqelmt->buffer, InformationBufferLength);
+ if ((status != NDIS_STATUS_SUCCESS) || (cmdqelmt->buffer == NULL))
+ {
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ return (NDIS_STATUS_RESOURCES);
+ }
+ else
+ {
+ NdisMoveMemory(cmdqelmt->buffer, pInformationBuffer, InformationBufferLength);
+ cmdqelmt->bufferlength = InformationBufferLength;
+ }
+ }
+ else
+ {
+ cmdqelmt->buffer = NULL;
+ cmdqelmt->bufferlength = 0;
+ }
+
+ cmdqelmt->command = Oid;
+ cmdqelmt->CmdFromNdis = FALSE;
+
+ if (cmdqelmt != NULL)
+ {
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ if (pAd->CmdQ.CmdQState & RT2870_THREAD_CAN_DO_INSERT)
+ {
+ EnqueueCmd((&pAd->CmdQ), cmdqelmt);
+ status = NDIS_STATUS_SUCCESS;
+ }
+ else
+ {
+ status = NDIS_STATUS_FAILURE;
+ }
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ if (status == NDIS_STATUS_FAILURE)
+ {
+ if (cmdqelmt->buffer)
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ RTUSBCMDUp(pAd);
+ }
+ return(NDIS_STATUS_SUCCESS);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ IRQL =
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTUSBDequeueCmd(
+ IN PCmdQ cmdq,
+ OUT PCmdQElmt *pcmdqelmt)
+{
+ *pcmdqelmt = cmdq->head;
+
+ if (*pcmdqelmt != NULL)
+ {
+ cmdq->head = cmdq->head->next;
+ cmdq->size--;
+ if (cmdq->size == 0)
+ cmdq->tail = NULL;
+ }
+}
+
+/*
+ ========================================================================
+ usb_control_msg - Builds a control urb, sends it off and waits for completion
+ @dev: pointer to the usb device to send the message to
+ @pipe: endpoint "pipe" to send the message to
+ @request: USB message request value
+ @requesttype: USB message request type value
+ @value: USB message value
+ @index: USB message index value
+ @data: pointer to the data to send
+ @size: length in bytes of the data to send
+ @timeout: time in jiffies to wait for the message to complete before
+ timing out (if 0 the wait is forever)
+ Context: !in_interrupt ()
+
+ This function sends a simple control message to a specified endpoint
+ and waits for the message to complete, or timeout.
+ If successful, it returns the number of bytes transferred, otherwise a negative error number.
+
+ Don't use this function from within an interrupt context, like a
+ bottom half handler. If you need an asynchronous message, or need to send
+ a message from within interrupt context, use usb_submit_urb()
+ If a thread in your driver uses this call, make sure your disconnect()
+ method can wait for it to complete. Since you don't have a handle on
+ the URB used, you can't cancel the request.
+
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSB_VendorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TransferFlags,
+ IN UCHAR RequestType,
+ IN UCHAR Request,
+ IN USHORT Value,
+ IN USHORT Index,
+ IN PVOID TransferBuffer,
+ IN UINT32 TransferBufferLength)
+{
+ int ret;
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("device disconnected\n"));
+ return -1;
+ }
+ else if (in_interrupt())
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("in_interrupt, RTUSB_VendorRequest Request%02x Value%04x Offset%04x\n",Request,Value,Index));
+
+ return -1;
+ }
+ else
+ {
+#define MAX_RETRY_COUNT 10
+
+ int retryCount = 0;
+ void *tmpBuf = TransferBuffer;
+
+ // Acquire Control token
+#ifdef INF_AMAZON_SE
+ ret = down_interruptible(&(pAd->UsbVendorReq_semaphore));
+ if (pAd->UsbVendorReqBuf)
+ {
+ ASSERT(TransferBufferLength <MAX_PARAM_BUFFER_SIZE);
+
+ tmpBuf = (void *)pAd->UsbVendorReqBuf;
+ NdisZeroMemory(pAd->UsbVendorReqBuf, TransferBufferLength);
+
+ if (RequestType == DEVICE_VENDOR_REQUEST_OUT)
+ NdisMoveMemory(tmpBuf, TransferBuffer, TransferBufferLength);
+ }
+#endif // INF_AMAZON_SE //
+ do {
+ if( RequestType == DEVICE_VENDOR_REQUEST_OUT)
+ ret=usb_control_msg(pObj->pUsb_Dev, usb_sndctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
+ else if(RequestType == DEVICE_VENDOR_REQUEST_IN)
+ ret=usb_control_msg(pObj->pUsb_Dev, usb_rcvctrlpipe( pObj->pUsb_Dev, 0 ), Request, RequestType, Value,Index, tmpBuf, TransferBufferLength, CONTROL_TIMEOUT_JIFFIES);
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("vendor request direction is failed\n"));
+ ret = -1;
+ }
+
+ retryCount++;
+ if (ret < 0) {
+ printk("#\n");
+ RTMPusecDelay(5000);
+ }
+ } while((ret < 0) && (retryCount < MAX_RETRY_COUNT));
+
+#ifdef INF_AMAZON_SE
+ if ((pAd->UsbVendorReqBuf) && (RequestType == DEVICE_VENDOR_REQUEST_IN))
+ NdisMoveMemory(TransferBuffer, tmpBuf, TransferBufferLength);
+ up(&(pAd->UsbVendorReq_semaphore));
+#endif // INF_AMAZON_SE //
+
+ if (ret < 0) {
+// DBGPRINT(RT_DEBUG_ERROR, ("USBVendorRequest failed ret=%d \n",ret));
+ DBGPRINT(RT_DEBUG_ERROR, ("RTUSB_VendorRequest failed(%d),TxFlags=0x%x, ReqType=%s, Req=0x%x, Index=0x%x\n",
+ ret, TransferFlags, (RequestType == DEVICE_VENDOR_REQUEST_OUT ? "OUT" : "IN"), Request, Index));
+ if (Request == 0x2)
+ DBGPRINT(RT_DEBUG_ERROR, ("\tRequest Value=0x%04x!\n", Value));
+
+ if ((TransferBuffer!= NULL) && (TransferBufferLength > 0))
+ hex_dump("Failed TransferBuffer value", TransferBuffer, TransferBufferLength);
+ }
+ }
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Creates an IRP to submite an IOCTL_INTERNAL_USB_RESET_PORT
+ synchronously. Callers of this function must be running at
+ PASSIVE LEVEL.
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+NTSTATUS RTUSB_ResetDevice(
+ IN PRTMP_ADAPTER pAd)
+{
+ NTSTATUS Status = TRUE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("--->USB_ResetDevice\n"));
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+ return Status;
+}
+
+VOID CMDHandler(
+ IN PRTMP_ADAPTER pAd)
+{
+ PCmdQElmt cmdqelmt;
+ PUCHAR pData;
+ NDIS_STATUS NdisStatus = NDIS_STATUS_SUCCESS;
+// ULONG Now = 0;
+ NTSTATUS ntStatus;
+// unsigned long IrqFlags;
+
+ while (pAd->CmdQ.size > 0)
+ {
+ NdisStatus = NDIS_STATUS_SUCCESS;
+
+ NdisAcquireSpinLock(&pAd->CmdQLock);
+ RTUSBDequeueCmd(&pAd->CmdQ, &cmdqelmt);
+ NdisReleaseSpinLock(&pAd->CmdQLock);
+
+ if (cmdqelmt == NULL)
+ break;
+
+ pData = cmdqelmt->buffer;
+
+ if(!(RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST) || RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+ {
+ switch (cmdqelmt->command)
+ {
+ case CMDTHREAD_CHECK_GPIO:
+ {
+#ifdef CONFIG_STA_SUPPORT
+ UINT32 data;
+#endif // CONFIG_STA_SUPPORT //
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+
+
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Read GPIO pin2 as Hardware controlled radio state
+
+ RTUSBReadMACRegister( pAd, GPIO_CTRL_CFG, &data);
+
+ if (data & 0x04)
+ {
+ pAd->StaCfg.bHwRadio = TRUE;
+ }
+ else
+ {
+ pAd->StaCfg.bHwRadio = FALSE;
+ }
+
+ if(pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+ {
+ pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+ if(pAd->StaCfg.bRadio == TRUE)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio On !!!\n"));
+
+ MlmeRadioOn(pAd);
+ // Update extra information
+ pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+ }
+ else
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("!!! Radio Off !!!\n"));
+
+ MlmeRadioOff(pAd);
+ // Update extra information
+ pAd->ExtraInfo = HW_RADIO_OFF;
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ break;
+
+#ifdef CONFIG_STA_SUPPORT
+ case CMDTHREAD_QKERIODIC_EXECUT:
+ {
+ StaQuickResponeForRateUpExec(NULL, pAd, NULL, NULL);
+ }
+ break;
+#endif // CONFIG_STA_SUPPORT //
+
+ case CMDTHREAD_RESET_BULK_OUT:
+ {
+ UINT32 MACValue;
+ UCHAR Index;
+ int ret=0;
+ PHT_TX_CONTEXT pHTTXContext;
+// RTMP_TX_RING *pTxRing;
+ unsigned long IrqFlags;
+#ifdef RALINK_ATE
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+#endif // RALINK_ATE //
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT(ResetPipeid=0x%0x)===>\n", pAd->bulkResetPipeid));
+ // All transfers must be aborted or cancelled before attempting to reset the pipe.
+ //RTUSBCancelPendingBulkOutIRP(pAd);
+ // Wait 10ms to let previous packet that are already in HW FIFO to clear. by MAXLEE 12-25-2007
+ Index = 0;
+ do
+ {
+ RTUSBReadMACRegister(pAd, TXRXQ_PCNT, &MACValue);
+ if ((MACValue & 0xf00000/*0x800000*/) == 0)
+ break;
+ Index++;
+ RTMPusecDelay(10000);
+ }while(Index < 100);
+ MACValue = 0;
+ RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+ // To prevent Read Register error, we 2nd check the validity.
+ if ((MACValue & 0xc00000) == 0)
+ RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+ // To prevent Read Register error, we 3rd check the validity.
+ if ((MACValue & 0xc00000) == 0)
+ RTUSBReadMACRegister(pAd, USB_DMA_CFG, &MACValue);
+ MACValue |= 0x80000;
+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
+
+ // Wait 1ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
+ RTMPusecDelay(1000);
+
+ MACValue &= (~0x80000);
+ RTUSBWriteMACRegister(pAd, USB_DMA_CFG, MACValue);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tSet 0x2a0 bit19. Clear USB DMA TX path\n"));
+
+ // Wait 5ms to prevent next URB to bulkout before HW reset. by MAXLEE 12-25-2007
+ //RTMPusecDelay(5000);
+
+ if ((pAd->bulkResetPipeid & BULKOUT_MGMT_RESET_FLAG) == BULKOUT_MGMT_RESET_FLAG)
+ {
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */)
+ {
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_MLME);
+ }
+ RTUSBKickBulkOut(pAd);
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tTX MGMT RECOVER Done!\n"));
+ }
+ else
+ {
+ pHTTXContext = &(pAd->TxContext[pAd->bulkResetPipeid]);
+ //NdisAcquireSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+ RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ if ( pAd->BulkOutPending[pAd->bulkResetPipeid] == FALSE)
+ {
+ pAd->BulkOutPending[pAd->bulkResetPipeid] = TRUE;
+ pHTTXContext->IRPPending = TRUE;
+ pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 1;
+
+ // no matter what, clean the flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+
+ //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+ RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+/*-----------------------------------------------------------------------------------------------*/
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ pNullContext->IRPPending = TRUE;
+ //
+ // If driver is still in ATE TXFRAME mode,
+ // keep on transmitting ATE frames.
+ //
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("pAd->ate.Mode == %d\npAd->ContinBulkOut == %d\npAd->BulkOutRemained == %d\n", pAd->ate.Mode, pAd->ContinBulkOut, atomic_read(&pAd->BulkOutRemained)));
+ if((pAd->ate.Mode == ATE_TXFRAME) && ((pAd->ContinBulkOut == TRUE) || (atomic_read(&pAd->BulkOutRemained) > 0)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("After CMDTHREAD_RESET_BULK_OUT, continue to bulk out frames !\n"));
+
+ // Init Tx context descriptor
+ RTUSBInitTxDesc(pAd, pNullContext, 0/* pAd->bulkResetPipeid */, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
+
+ if((ret = RTUSB_SUBMIT_URB(pNullContext->pUrb))!=0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+ }
+
+ pAd->BulkOutReq++;
+ }
+ }
+ else
+#endif // RALINK_ATE //
+/*-----------------------------------------------------------------------------------------------*/
+ {
+ RTUSBInitHTTxDesc(pAd, pHTTXContext, pAd->bulkResetPipeid, pHTTXContext->BulkOutSize, (usb_complete_t)RTUSBBulkOutDataPacketComplete);
+
+ if((ret = RTUSB_SUBMIT_URB(pHTTXContext->pUrb))!=0)
+ {
+ RTMP_INT_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ pAd->BulkOutPending[pAd->bulkResetPipeid] = FALSE;
+ pHTTXContext->IRPPending = FALSE;
+ pAd->watchDogTxPendingCnt[pAd->bulkResetPipeid] = 0;
+ RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("CmdThread : CMDTHREAD_RESET_BULK_OUT: Submit Tx URB failed %d\n", ret));
+ }
+ else
+ {
+ RTMP_IRQ_LOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("\tCMDTHREAD_RESET_BULK_OUT: TxContext[%d]:CWPos=%ld, NBPos=%ld, ENBPos=%ld, bCopy=%d, pending=%d!\n",
+ pAd->bulkResetPipeid, pHTTXContext->CurWritePosition, pHTTXContext->NextBulkOutPosition,
+ pHTTXContext->ENextBulkOutPosition, pHTTXContext->bCopySavePad, pAd->BulkOutPending[pAd->bulkResetPipeid]));
+ DBGPRINT_RAW(RT_DEBUG_TRACE,("\t\tBulkOut Req=0x%lx, Complete=0x%lx, Other=0x%lx\n",
+ pAd->BulkOutReq, pAd->BulkOutComplete, pAd->BulkOutCompleteOther));
+ RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("\tCMDTHREAD_RESET_BULK_OUT: Submit Tx DATA URB for failed BulkReq(0x%lx) Done, status=%d!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pHTTXContext->pUrb->status));
+
+ }
+ }
+ }
+ else
+ {
+ //NdisReleaseSpinLock(&pAd->BulkOutLock[pAd->bulkResetPipeid]);
+ //RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("CmdThread : TX DATA RECOVER FAIL for BulkReq(0x%lx) because BulkOutPending[%d] is TRUE!\n", pAd->bulkResetReq[pAd->bulkResetPipeid], pAd->bulkResetPipeid));
+ if (pAd->bulkResetPipeid == 0)
+ {
+ UCHAR pendingContext = 0;
+ PHT_TX_CONTEXT pHTTXContext = (PHT_TX_CONTEXT)(&pAd->TxContext[pAd->bulkResetPipeid ]);
+ PTX_CONTEXT pMLMEContext = (PTX_CONTEXT)(pAd->MgmtRing.Cell[pAd->MgmtRing.TxDmaIdx].AllocVa);
+ PTX_CONTEXT pNULLContext = (PTX_CONTEXT)(&pAd->PsPollContext);
+ PTX_CONTEXT pPsPollContext = (PTX_CONTEXT)(&pAd->NullContext);
+
+ if (pHTTXContext->IRPPending)
+ pendingContext |= 1;
+ else if (pMLMEContext->IRPPending)
+ pendingContext |= 2;
+ else if (pNULLContext->IRPPending)
+ pendingContext |= 4;
+ else if (pPsPollContext->IRPPending)
+ pendingContext |= 8;
+ else
+ pendingContext = 0;
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("\tTX Occupied by %d!\n", pendingContext));
+ }
+
+ // no matter what, clean the flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+
+ RTMP_INT_UNLOCK(&pAd->BulkOutLock[pAd->bulkResetPipeid], IrqFlags);
+
+ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << pAd->bulkResetPipeid));
+ }
+
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ //RTUSBKickBulkOut(pAd);
+ }
+
+ }
+ /*
+ // Don't cancel BULKIN.
+ while ((atomic_read(&pAd->PendingRx) > 0) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ if (atomic_read(&pAd->PendingRx) > 0)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!cancel it!\n"));
+ RTUSBCancelPendingBulkInIRP(pAd);
+ }
+ RTMPusecDelay(100000);
+ }
+
+ if ((atomic_read(&pAd->PendingRx) == 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)))
+ {
+ UCHAR i;
+ RTUSBRxPacket(pAd);
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ pRxContext->pAd = pAd;
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+ pRxContext->ReorderInUse = FALSE;
+
+ }
+ RTUSBBulkReceive(pAd);
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("RTUSBBulkReceive\n"));
+ }*/
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_OUT<===\n"));
+ break;
+
+ case CMDTHREAD_RESET_BULK_IN:
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN === >\n"));
+
+ // All transfers must be aborted or cancelled before attempting to reset the pipe.
+ {
+ UINT32 MACValue;
+/*-----------------------------------------------------------------------------------------------*/
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("ATE : BulkIn IRP Pending!!!\n"));
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+ RTMPusecDelay(100000);
+ pAd->PendingRx = 0;
+ }
+ }
+ else
+#endif // RALINK_ATE //
+/*-----------------------------------------------------------------------------------------------*/
+ {
+ //while ((atomic_read(&pAd->PendingRx) > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ if((pAd->PendingRx > 0) && (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("BulkIn IRP Pending!!!\n"));
+ RTUSBCancelPendingBulkInIRP(pAd);
+ RTMPusecDelay(100000);
+ pAd->PendingRx = 0;
+ }
+ }
+
+ // Wait 10ms before reading register.
+ RTMPusecDelay(10000);
+ ntStatus = RTUSBReadMACRegister(pAd, MAC_CSR0, &MACValue);
+
+ if ((NT_SUCCESS(ntStatus) == TRUE) &&
+ (!(RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))))
+ {
+ UCHAR i;
+
+ if (RTMP_TEST_FLAG(pAd, (fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ break;
+ pAd->NextRxBulkInPosition = pAd->RxContext[pAd->NextRxBulkInIndex].BulkInOffset;
+ DBGPRINT(RT_DEBUG_TRACE, ("BULK_IN_RESET: NBIIdx=0x%x,NBIRIdx=0x%x, BIRPos=0x%lx. BIReq=x%lx, BIComplete=0x%lx, BICFail0x%lx\n",
+ pAd->NextRxBulkInIndex, pAd->NextRxBulkInReadIndex, pAd->NextRxBulkInPosition, pAd->BulkInReq, pAd->BulkInComplete, pAd->BulkInCompleteFail));
+ for (i = 0; i < RX_RING_SIZE; i++)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("\tRxContext[%d]: IRPPending=%d, InUse=%d, Readable=%d!\n"
+ , i, pAd->RxContext[i].IRPPending, pAd->RxContext[i].InUse, pAd->RxContext[i].Readable));
+ }
+ /*
+
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("==========================================\n"));
+
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = 0; // Rx Bulk pointer
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ pRxContext->pAd = pAd;
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+ pRxContext->ReorderInUse = FALSE;
+
+ }*/
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
+ for (i = 0; i < pAd->CommonCfg.NumOfBulkInIRP; i++)
+ {
+ //RTUSBBulkReceive(pAd);
+ PRX_CONTEXT pRxContext;
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext = &(pAd->RxContext[pAd->NextRxBulkInIndex]);
+ if ((pAd->PendingRx > 0) || (pRxContext->Readable == TRUE) || (pRxContext->InUse == TRUE))
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ break;
+ }
+ pRxContext->InUse = TRUE;
+ pRxContext->IRPPending = TRUE;
+ pAd->PendingRx++;
+ pAd->BulkInReq++;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+ // Init Rx context descriptor
+ RTUSBInitRxDesc(pAd, pRxContext);
+ pUrb = pRxContext->pUrb;
+ if ((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ { // fail
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pAd->PendingRx--;
+ pAd->BulkInReq--;
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ DBGPRINT(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB failed(%d), status=%d\n", ret, pUrb->status));
+ }
+ else
+ { // success
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CMDTHREAD_RESET_BULK_IN: Submit Rx URB Done, status=%d!\n", pUrb->status));
+ ASSERT((pRxContext->InUse == pRxContext->IRPPending));
+ }
+ }
+
+ }
+ else
+ {
+ // Card must be removed
+ if (NT_SUCCESS(ntStatus) != TRUE)
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Read Register Failed!Card must be removed!!\n\n"));
+ }
+ else
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR, ("CMDTHREAD_RESET_BULK_IN: Cannot do bulk in because flags(0x%lx) on !\n", pAd->Flags));
+ }
+ }
+ }
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_RESET_BULK_IN <===\n"));
+ break;
+
+ case CMDTHREAD_SET_ASIC_WCID:
+ {
+ RT_SET_ASIC_WCID SetAsicWcid;
+ USHORT offset;
+ UINT32 MACValue, MACRValue = 0;
+ SetAsicWcid = *((PRT_SET_ASIC_WCID)(pData));
+
+ if (SetAsicWcid.WCID >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ offset = MAC_WCID_BASE + ((UCHAR)SetAsicWcid.WCID)*HW_WCID_ENTRY_SIZE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("CmdThread : CMDTHREAD_SET_ASIC_WCID : WCID = %ld, SetTid = %lx, DeleteTid = %lx.\n", SetAsicWcid.WCID, SetAsicWcid.SetTid, SetAsicWcid.DeleteTid));
+ MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[3]<<24)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[2]<<16)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[1]<<8)+(pAd->MacTab.Content[SetAsicWcid.WCID].Addr[0]);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("1-MACValue= %x,\n", MACValue));
+ RTUSBWriteMACRegister(pAd, offset, MACValue);
+ // Read bitmask
+ RTUSBReadMACRegister(pAd, offset+4, &MACRValue);
+ if ( SetAsicWcid.DeleteTid != 0xffffffff)
+ MACRValue &= (~SetAsicWcid.DeleteTid);
+ if (SetAsicWcid.SetTid != 0xffffffff)
+ MACRValue |= (SetAsicWcid.SetTid);
+ MACRValue &= 0xffff0000;
+
+ MACValue = (pAd->MacTab.Content[SetAsicWcid.WCID].Addr[5]<<8)+pAd->MacTab.Content[SetAsicWcid.WCID].Addr[4];
+ MACValue |= MACRValue;
+ RTUSBWriteMACRegister(pAd, offset+4, MACValue);
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-MACValue= %x,\n", MACValue));
+ }
+ break;
+
+ case CMDTHREAD_SET_ASIC_WCID_CIPHER:
+ {
+#ifdef CONFIG_STA_SUPPORT
+ RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri;
+ USHORT offset;
+ UINT32 MACRValue = 0;
+ SHAREDKEY_MODE_STRUC csr1;
+ SetAsicWcidAttri = *((PRT_SET_ASIC_WCID_ATTRI)(pData));
+
+ if (SetAsicWcidAttri.WCID >= MAX_LEN_OF_MAC_TABLE)
+ return;
+
+ offset = MAC_WCID_ATTRIBUTE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_WCID_ATTRI_SIZE;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("Cmd : CMDTHREAD_SET_ASIC_WCID_CIPHER : WCID = %ld, Cipher = %lx.\n", SetAsicWcidAttri.WCID, SetAsicWcidAttri.Cipher));
+ // Read bitmask
+ RTUSBReadMACRegister(pAd, offset, &MACRValue);
+ MACRValue = 0;
+ MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
+
+ RTUSBWriteMACRegister(pAd, offset, MACRValue);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
+
+ offset = PAIRWISE_IVEIV_TABLE_BASE + ((UCHAR)SetAsicWcidAttri.WCID)*HW_IVEIV_ENTRY_SIZE;
+ MACRValue = 0;
+ if ( (SetAsicWcidAttri.Cipher <= CIPHER_WEP128))
+ MACRValue |= ( pAd->StaCfg.DefaultKeyId << 30);
+ else
+ MACRValue |= (0x20000000);
+ RTUSBWriteMACRegister(pAd, offset, MACRValue);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("2-offset = %x , MACValue= %x,\n", offset, MACRValue));
+
+ //
+ // Update cipher algorithm. WSTA always use BSS0
+ //
+ // for adhoc mode only ,because wep status slow than add key, when use zero config
+ if (pAd->StaCfg.BssType == BSS_ADHOC )
+ {
+ offset = MAC_WCID_ATTRIBUTE_BASE;
+
+ RTUSBReadMACRegister(pAd, offset, &MACRValue);
+ MACRValue &= (~0xe);
+ MACRValue |= (((UCHAR)SetAsicWcidAttri.Cipher) << 1);
+
+ RTUSBWriteMACRegister(pAd, offset, MACRValue);
+
+ //Update group key cipher,,because wep status slow than add key, when use zero config
+ RTUSBReadMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), &csr1.word);
+
+ csr1.field.Bss0Key0CipherAlg = SetAsicWcidAttri.Cipher;
+ csr1.field.Bss0Key1CipherAlg = SetAsicWcidAttri.Cipher;
+
+ RTUSBWriteMACRegister(pAd, SHARED_KEY_MODE_BASE+4*(0/2), csr1.word);
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ break;
+
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+ case RT_CMD_SET_KEY_TABLE: //General call for AsicAddPairwiseKeyEntry()
+ {
+ RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+ KeyInfo = *((PRT_ADD_PAIRWISE_KEY_ENTRY)(pData));
+ AsicAddPairwiseKeyEntry(pAd,
+ KeyInfo.MacAddr,
+ (UCHAR)KeyInfo.MacTabMatchWCID,
+ &KeyInfo.CipherKey);
+ }
+ break;
+ case RT_CMD_SET_RX_WCID_TABLE: //General call for RTMPAddWcidAttributeEntry()
+ {
+ PMAC_TABLE_ENTRY pEntry;
+ UCHAR KeyIdx;
+ UCHAR CipherAlg;
+ UCHAR ApIdx;
+
+ pEntry = (PMAC_TABLE_ENTRY)(pData);
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ KeyIdx = 0;
+ CipherAlg = pEntry->PairwiseKey.CipherAlg;
+ ApIdx = BSS0;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+ RTMPAddWcidAttributeEntry(
+ pAd,
+ ApIdx,
+ KeyIdx,
+ CipherAlg,
+ pEntry);
+ }
+ break;
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+
+ case CMDTHREAD_SET_CLIENT_MAC_ENTRY:
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ pEntry = (MAC_TABLE_ENTRY *)pData;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ AsicRemovePairwiseKeyEntry(pAd, pEntry->apidx, (UCHAR)pEntry->Aid);
+ if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && (pEntry->WepStatus == Ndis802_11Encryption1Enabled))
+ {
+ UINT32 uIV = 0;
+ PUCHAR ptr;
+
+ ptr = (PUCHAR) &uIV;
+ *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
+ AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
+ AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
+ }
+ else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ UINT32 uIV = 0;
+ PUCHAR ptr;
+
+ ptr = (PUCHAR) &uIV;
+ *(ptr + 3) = (pAd->StaCfg.DefaultKeyId << 6);
+ AsicUpdateWCIDIVEIV(pAd, pEntry->Aid, uIV, 0);
+ AsicUpdateWCIDAttribute(pAd, pEntry->Aid, BSS0, pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg, FALSE);
+ }
+ else
+ {
+ //
+ // Other case, disable engine.
+ // Don't worry WPA key, we will add WPA Key after 4-Way handshaking.
+ //
+ USHORT offset;
+ offset = MAC_WCID_ATTRIBUTE_BASE + (pEntry->Aid * HW_WCID_ATTRI_SIZE);
+ // RX_PKEY_MODE:0 for no security; RX_KEY_TAB:0 for shared key table; BSS_IDX:0
+ RTUSBWriteMACRegister(pAd, offset, 0);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ AsicUpdateRxWCIDTable(pAd, pEntry->Aid, pEntry->Addr);
+ printk("UpdateRxWCIDTable(): Aid=%d, Addr=%02x:%02x:%02x:%02x:%02x:%02x!\n", pEntry->Aid,
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5]);
+ }
+ break;
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+ case CMDTHREAD_UPDATE_PROTECT:
+ {
+ AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT), TRUE, 0);
+ }
+ break;
+// end johnli
+
+ case OID_802_11_ADD_WEP:
+ {
+#ifdef CONFIG_STA_SUPPORT
+ UINT i;
+ UINT32 KeyIdx;
+ PNDIS_802_11_WEP pWepKey;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP \n"));
+
+ pWepKey = (PNDIS_802_11_WEP)pData;
+ KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+
+ // it is a shared key
+ if ((KeyIdx >= 4) || ((pWepKey->KeyLength != 5) && (pWepKey->KeyLength != 13)))
+ {
+ NdisStatus = NDIS_STATUS_INVALID_DATA;
+ DBGPRINT(RT_DEBUG_ERROR, ("CmdThread::OID_802_11_ADD_WEP, INVALID_DATA!!\n"));
+ }
+ else
+ {
+ UCHAR CipherAlg;
+ pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+ CipherAlg = (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 5)? CIPHER_WEP64 : CIPHER_WEP128;
+
+ //
+ // Change the WEP cipher to CKIP cipher if CKIP KP on.
+ // Funk UI or Meetinghouse UI will add ckip key from this path.
+ //
+
+ if (pAd->OpMode == OPMODE_STA)
+ {
+ pAd->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+ pAd->MacTab.Content[BSSID_WCID].PairwiseKey.KeyLen = pAd->SharedKey[BSS0][KeyIdx].KeyLen;
+ }
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+ // Default key for tx (shared key)
+ UCHAR IVEIV[8];
+ UINT32 WCIDAttri, Value;
+ USHORT offset, offset2;
+ NdisZeroMemory(IVEIV, 8);
+ pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+ // Add BSSID to WCTable. because this is Tx wep key.
+ // WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:1=PAIRWISE KEY, BSSIdx is 0
+ WCIDAttri = (CipherAlg<<1)|SHAREDKEYTABLE;
+
+ offset = MAC_WCID_ATTRIBUTE_BASE + (BSSID_WCID* HW_WCID_ATTRI_SIZE);
+ RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+ // 1. IV/EIV
+ // Specify key index to find shared key.
+ IVEIV[3] = (UCHAR)(KeyIdx<< 6); //WEP Eiv bit off. groupkey index is not 0
+ offset = PAIRWISE_IVEIV_TABLE_BASE + (BSS0Mcast_WCID * HW_IVEIV_ENTRY_SIZE);
+ offset2 = PAIRWISE_IVEIV_TABLE_BASE + (BSSID_WCID* HW_IVEIV_ENTRY_SIZE);
+ for (i=0; i<8;)
+ {
+ Value = IVEIV[i];
+ Value += (IVEIV[i+1]<<8);
+ Value += (IVEIV[i+2]<<16);
+ Value += (IVEIV[i+3]<<24);
+ RTUSBWriteMACRegister(pAd, offset+i, Value);
+ RTUSBWriteMACRegister(pAd, offset2+i, Value);
+ i+=4;
+ }
+
+ // 2. WCID Attribute UDF:3, BSSIdx:3, Alg:3, Keytable:use share key, BSSIdx is 0
+ WCIDAttri = (pAd->SharedKey[BSS0][KeyIdx].CipherAlg<<1)|SHAREDKEYTABLE;
+ offset = MAC_WCID_ATTRIBUTE_BASE + (BSS0Mcast_WCID* HW_WCID_ATTRI_SIZE);
+ DBGPRINT(RT_DEBUG_TRACE, ("BSS0Mcast_WCID : offset = %x, WCIDAttri = %x\n", offset, WCIDAttri));
+ RTUSBWriteMACRegister(pAd, offset, WCIDAttri);
+
+ }
+ AsicAddSharedKeyEntry(pAd, BSS0, (UCHAR)KeyIdx, CipherAlg, pWepKey->KeyMaterial, NULL, NULL);
+ DBGPRINT(RT_DEBUG_TRACE, ("CmdThread::OID_802_11_ADD_WEP (KeyIdx=%d, Len=%d-byte)\n", KeyIdx, pWepKey->KeyLength));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ break;
+
+ case CMDTHREAD_802_11_COUNTER_MEASURE:
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Control Thread !! ERROR !! Unknown(cmdqelmt->command=0x%x) !! \n", cmdqelmt->command));
+ break;
+ }
+ }
+
+ if (cmdqelmt->CmdFromNdis == TRUE)
+ {
+ if (cmdqelmt->buffer != NULL)
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ else
+ {
+ if ((cmdqelmt->buffer != NULL) && (cmdqelmt->bufferlength != 0))
+ NdisFreeMemory(cmdqelmt->buffer, cmdqelmt->bufferlength, 0);
+ {
+ NdisFreeMemory(cmdqelmt, sizeof(CmdQElmt), 0);
+ }
+ }
+ } /* end of while */
+}
+
diff --git a/drivers/staging/rt3070/common/spectrum.c b/drivers/staging/rt3070/common/spectrum.c
new file mode 100644
index 00000000000..da57b1202d6
--- /dev/null
+++ b/drivers/staging/rt3070/common/spectrum.c
@@ -0,0 +1,1876 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ action.c
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Fonchi Wu 2008 created for 802.11h
+ */
+
+#include "../rt_config.h"
+#include "../action.h"
+
+VOID MeasureReqTabInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisAllocateSpinLock(&pAd->CommonCfg.MeasureReqTabLock);
+
+ pAd->CommonCfg.pMeasureReqTab = kmalloc(sizeof(MEASURE_REQ_TAB), GFP_ATOMIC);
+ if (pAd->CommonCfg.pMeasureReqTab)
+ NdisZeroMemory(pAd->CommonCfg.pMeasureReqTab, sizeof(MEASURE_REQ_TAB));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pMeasureReqTab.\n", __FUNCTION__));
+
+ return;
+}
+
+VOID MeasureReqTabExit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisFreeSpinLock(pAd->CommonCfg.MeasureReqTabLock);
+
+ if (pAd->CommonCfg.pMeasureReqTab)
+ kfree(pAd->CommonCfg.pMeasureReqTab);
+ pAd->CommonCfg.pMeasureReqTab = NULL;
+
+ return;
+}
+
+static PMEASURE_REQ_ENTRY MeasureReqLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ UINT HashIdx;
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+
+ if (pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+ HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ pEntry = pTab->Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (pEntry->DialogToken == DialogToken)
+ break;
+ else
+ {
+ pPrevEntry = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+
+ return pEntry;
+}
+
+static PMEASURE_REQ_ENTRY MeasureReqInsert(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ INT i;
+ ULONG HashIdx;
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL, pCurrEntry;
+ ULONG Now;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ pEntry = MeasureReqLookUp(pAd, DialogToken);
+ if (pEntry == NULL)
+ {
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ for (i = 0; i < MAX_MEASURE_REQ_TAB_SIZE; i++)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry = &pTab->Content[i];
+
+ if ((pEntry->Valid == TRUE)
+ && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + MQ_REQ_AGE_OUT)))
+ {
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+ pTab->Size--;
+
+ break;
+ }
+
+ if (pEntry->Valid == FALSE)
+ break;
+ }
+
+ if (i < MAX_MEASURE_REQ_TAB_SIZE)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ pEntry->Valid = TRUE;
+ pEntry->DialogToken = DialogToken;
+ pTab->Size++;
+ }
+ else
+ {
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab tab full.\n", __FUNCTION__));
+ }
+
+ // add this Neighbor entry into HASH table
+ if (pEntry)
+ {
+ HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ if (pTab->Hash[HashIdx] == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pTab->Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ }
+
+ return pEntry;
+}
+
+static VOID MeasureReqDelete(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ PMEASURE_REQ_TAB pTab = pAd->CommonCfg.pMeasureReqTab;
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pMeasureReqTab doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ // if empty, return
+ if (pTab->Size == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pMeasureReqTab empty.\n"));
+ return;
+ }
+
+ pEntry = MeasureReqLookUp(pAd, DialogToken);
+ if (pEntry != NULL)
+ {
+ PMEASURE_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = MQ_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PMEASURE_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(MEASURE_REQ_ENTRY));
+ pTab->Size--;
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.MeasureReqTabLock);
+ }
+
+ return;
+}
+
+VOID TpcReqTabInit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisAllocateSpinLock(&pAd->CommonCfg.TpcReqTabLock);
+
+ pAd->CommonCfg.pTpcReqTab = kmalloc(sizeof(TPC_REQ_TAB), GFP_ATOMIC);
+ if (pAd->CommonCfg.pTpcReqTab)
+ NdisZeroMemory(pAd->CommonCfg.pTpcReqTab, sizeof(TPC_REQ_TAB));
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s Fail to alloc memory for pAd->CommonCfg.pTpcReqTab.\n", __FUNCTION__));
+
+ return;
+}
+
+VOID TpcReqTabExit(
+ IN PRTMP_ADAPTER pAd)
+{
+ NdisFreeSpinLock(pAd->CommonCfg.TpcReqTabLock);
+
+ if (pAd->CommonCfg.pTpcReqTab)
+ kfree(pAd->CommonCfg.pTpcReqTab);
+ pAd->CommonCfg.pTpcReqTab = NULL;
+
+ return;
+}
+
+static PTPC_REQ_ENTRY TpcReqLookUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ UINT HashIdx;
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL;
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+
+ if (pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+ HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ pEntry = pTab->Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if (pEntry->DialogToken == DialogToken)
+ break;
+ else
+ {
+ pPrevEntry = pEntry;
+ pEntry = pEntry->pNext;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+
+ return pEntry;
+}
+
+
+static PTPC_REQ_ENTRY TpcReqInsert(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ INT i;
+ ULONG HashIdx;
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL, pCurrEntry;
+ ULONG Now;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return NULL;
+ }
+
+ pEntry = TpcReqLookUp(pAd, DialogToken);
+ if (pEntry == NULL)
+ {
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+ for (i = 0; i < MAX_TPC_REQ_TAB_SIZE; i++)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry = &pTab->Content[i];
+
+ if ((pEntry->Valid == TRUE)
+ && RTMP_TIME_AFTER((unsigned long)Now, (unsigned long)(pEntry->lastTime + TPC_REQ_AGE_OUT)))
+ {
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+ pTab->Size--;
+
+ break;
+ }
+
+ if (pEntry->Valid == FALSE)
+ break;
+ }
+
+ if (i < MAX_TPC_REQ_TAB_SIZE)
+ {
+ NdisGetSystemUpTime(&Now);
+ pEntry->lastTime = Now;
+ pEntry->Valid = TRUE;
+ pEntry->DialogToken = DialogToken;
+ pTab->Size++;
+ }
+ else
+ {
+ pEntry = NULL;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab tab full.\n", __FUNCTION__));
+ }
+
+ // add this Neighbor entry into HASH table
+ if (pEntry)
+ {
+ HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(DialogToken);
+ if (pTab->Hash[HashIdx] == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pTab->Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+ }
+
+ return pEntry;
+}
+
+static VOID TpcReqDelete(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 DialogToken)
+{
+ PTPC_REQ_TAB pTab = pAd->CommonCfg.pTpcReqTab;
+ PTPC_REQ_ENTRY pEntry = NULL;
+
+ if(pTab == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: pTpcReqTab doesn't exist.\n", __FUNCTION__));
+ return;
+ }
+
+ // if empty, return
+ if (pTab->Size == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pTpcReqTab empty.\n"));
+ return;
+ }
+
+ pEntry = TpcReqLookUp(pAd, DialogToken);
+ if (pEntry != NULL)
+ {
+ PTPC_REQ_ENTRY pPrevEntry = NULL;
+ ULONG HashIdx = TPC_DIALOGTOKEN_HASH_INDEX(pEntry->DialogToken);
+ PTPC_REQ_ENTRY pProbeEntry = pTab->Hash[HashIdx];
+
+ RTMP_SEM_LOCK(&pAd->CommonCfg.TpcReqTabLock);
+ // update Hash list
+ do
+ {
+ if (pProbeEntry == pEntry)
+ {
+ if (pPrevEntry == NULL)
+ {
+ pTab->Hash[HashIdx] = pEntry->pNext;
+ }
+ else
+ {
+ pPrevEntry->pNext = pEntry->pNext;
+ }
+ break;
+ }
+
+ pPrevEntry = pProbeEntry;
+ pProbeEntry = pProbeEntry->pNext;
+ } while (pProbeEntry);
+
+ NdisZeroMemory(pEntry, sizeof(TPC_REQ_ENTRY));
+ pTab->Size--;
+
+ RTMP_SEM_UNLOCK(&pAd->CommonCfg.TpcReqTabLock);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get Current TimeS tamp.
+
+ Parametrs:
+
+ Return : Current Time Stamp.
+ ==========================================================================
+ */
+static UINT64 GetCurrentTimeStamp(
+ IN PRTMP_ADAPTER pAd)
+{
+ // get current time stamp.
+ return 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Get Current Transmit Power.
+
+ Parametrs:
+
+ Return : Current Time Stamp.
+ ==========================================================================
+ */
+static UINT8 GetCurTxPwr(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 Wcid)
+{
+ return 16; /* 16 dBm */
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Dialog Token into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Dialog token.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertDialogToken(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 DialogToken)
+{
+ ULONG TempLen;
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &DialogToken,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert TPC Request IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+
+ Return : None.
+ ==========================================================================
+ */
+ static VOID InsertTpcReqIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen)
+{
+ ULONG TempLen;
+ ULONG Len = 0;
+ UINT8 ElementID = IE_TPC_REQUEST;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert TPC Report IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Transmit Power.
+ 4. Link Margin.
+
+ Return : None.
+ ==========================================================================
+ */
+ static VOID InsertTpcReportIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin)
+{
+ ULONG TempLen;
+ ULONG Len = sizeof(TPC_REPORT_INFO);
+ UINT8 ElementID = IE_TPC_REPORT;
+ TPC_REPORT_INFO TpcReportIE;
+
+ TpcReportIE.TxPwr = TxPwr;
+ TpcReportIE.LinkMargin = LinkMargin;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, &TpcReportIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Channel Switch Announcement IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. channel switch announcement mode.
+ 4. new selected channel.
+ 5. channel switch announcement count.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertChSwAnnIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewChannel,
+ IN UINT8 ChSwCnt)
+{
+ ULONG TempLen;
+ ULONG Len = sizeof(CH_SW_ANN_INFO);
+ UINT8 ElementID = IE_CHANNEL_SWITCH_ANNOUNCEMENT;
+ CH_SW_ANN_INFO ChSwAnnIE;
+
+ ChSwAnnIE.ChSwMode = ChSwMode;
+ ChSwAnnIE.Channel = NewChannel;
+ ChSwAnnIE.ChSwCnt = ChSwCnt;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, &ChSwAnnIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Measure Request IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Measure Token.
+ 4. Measure Request Mode.
+ 5. Measure Request Type.
+ 6. Measure Channel.
+ 7. Measure Start time.
+ 8. Measure Duration.
+
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertMeasureReqIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PMEASURE_REQ_INFO pMeasureReqIE)
+{
+ ULONG TempLen;
+ UINT8 Len = sizeof(MEASURE_REQ_INFO);
+ UINT8 ElementID = IE_MEASUREMENT_REQUEST;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, pMeasureReqIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Insert Measure Report IE into frame.
+
+ Parametrs:
+ 1. frame buffer pointer.
+ 2. frame length.
+ 3. Measure Token.
+ 4. Measure Request Mode.
+ 5. Measure Request Type.
+ 6. Length of Report Infomation
+ 7. Pointer of Report Infomation Buffer.
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID InsertMeasureReportIE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN PMEASURE_REPORT_INFO pMeasureReportIE,
+ IN UINT8 ReportLnfoLen,
+ IN PUINT8 pReportInfo)
+{
+ ULONG TempLen;
+ ULONG Len;
+ UINT8 ElementID = IE_MEASUREMENT_REPORT;
+
+ Len = sizeof(MEASURE_REPORT_INFO) + ReportLnfoLen;
+
+ MakeOutgoingFrame(pFrameBuf, &TempLen,
+ 1, &ElementID,
+ 1, &Len,
+ Len, pMeasureReportIE,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+
+ if ((ReportLnfoLen > 0) && (pReportInfo != NULL))
+ {
+ MakeOutgoingFrame(pFrameBuf + *pFrameLen, &TempLen,
+ ReportLnfoLen, pReportInfo,
+ END_OF_ARGS);
+
+ *pFrameLen = *pFrameLen + TempLen;
+ }
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 MeasureCh,
+ IN UINT16 MeasureDuration)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ HEADER_802_11 ActHdr;
+ MEASURE_REQ_INFO MeasureReqIE;
+ UINT8 RmReqDailogToken = RandomByte(pAd);
+ UINT64 MeasureStartTime = GetCurrentTimeStamp(pAd);
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRQ);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, MeasureToken);
+
+ // prepare Measurement IE.
+ NdisZeroMemory(&MeasureReqIE, sizeof(MEASURE_REQ_INFO));
+ MeasureReqIE.Token = RmReqDailogToken;
+ MeasureReqIE.ReqMode.word = MeasureReqMode;
+ MeasureReqIE.ReqType = MeasureReqType;
+ MeasureReqIE.MeasureReq.ChNum = MeasureCh;
+ MeasureReqIE.MeasureReq.MeasureStartTime = cpu2le64(MeasureStartTime);
+ MeasureReqIE.MeasureReq.MeasureDuration = cpu2le16(MeasureDuration);
+ InsertMeasureReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureReqIE);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 ReportInfoLen,
+ IN PUINT8 pReportInfo)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+ HEADER_802_11 ActHdr;
+ MEASURE_REPORT_INFO MeasureRepIE;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_MRP);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ // prepare Measurement IE.
+ NdisZeroMemory(&MeasureRepIE, sizeof(MEASURE_REPORT_INFO));
+ MeasureRepIE.Token = MeasureToken;
+ MeasureRepIE.ReportMode.word = MeasureReqMode;
+ MeasureRepIE.ReportType = MeasureReqType;
+ InsertMeasureReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, &MeasureRepIE, ReportInfoLen, pReportInfo);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UCHAR DialogToken)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRQ);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ // Insert TPC Request IE.
+ InsertTpcReqIE(pAd, (pOutBuffer + FrameLen), &FrameLen);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_TPCRP);
+
+ // fill Dialog Token
+ InsertDialogToken(pAd, (pOutBuffer + FrameLen), &FrameLen, DialogToken);
+
+ // Insert TPC Request IE.
+ InsertTpcReportIE(pAd, (pOutBuffer + FrameLen), &FrameLen, TxPwr, LinkMargin);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Channel Switch Announcement action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+ 2. Channel switch announcement mode.
+ 2. a New selected channel.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueChSwAnn(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewCh)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen;
+
+ HEADER_802_11 ActHdr;
+
+ // build action frame header.
+ MgtMacHeaderInit(pAd, &ActHdr, SUBTYPE_ACTION, 0, pDA,
+ pAd->CurrentAddress);
+
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s() allocate memory failed \n", __FUNCTION__));
+ return;
+ }
+ NdisMoveMemory(pOutBuffer, (PCHAR)&ActHdr, sizeof(HEADER_802_11));
+ FrameLen = sizeof(HEADER_802_11);
+
+ InsertActField(pAd, (pOutBuffer + FrameLen), &FrameLen, CATEGORY_SPECTRUM, SPEC_CHANNEL_SWITCH);
+
+ InsertChSwAnnIE(pAd, (pOutBuffer + FrameLen), &FrameLen, ChSwMode, NewCh, 0);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ return;
+}
+
+static BOOLEAN DfsRequirementCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT8 Channel)
+{
+ BOOLEAN Result = FALSE;
+ INT i;
+
+ do
+ {
+ // check DFS procedure is running.
+ // make sure DFS procedure won't start twice.
+ if (pAd->CommonCfg.RadarDetect.RDMode != RD_NORMAL_MODE)
+ {
+ Result = FALSE;
+ break;
+ }
+
+ // check the new channel carried from Channel Switch Announcemnet is valid.
+ for (i=0; i<pAd->ChannelListNum; i++)
+ {
+ if ((Channel == pAd->ChannelList[i].Channel)
+ &&(pAd->ChannelList[i].RemainingTimeForUse == 0))
+ {
+ // found radar signal in the channel. the channel can't use at least for 30 minutes.
+ pAd->ChannelList[i].RemainingTimeForUse = 1800;//30 min = 1800 sec
+ Result = TRUE;
+ break;
+ }
+ }
+ } while(FALSE);
+
+ return Result;
+}
+
+VOID NotifyChSwAnnToPeerAPs(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRA,
+ IN PUCHAR pTA,
+ IN UINT8 ChSwMode,
+ IN UINT8 Channel)
+{
+#ifdef WDS_SUPPORT
+ if (!((pRA[0] & 0xff) == 0xff)) // is pRA a broadcase address.
+ {
+ INT i;
+ // info neighbor APs that Radar signal found throgh WDS link.
+ for (i = 0; i < MAX_WDS_ENTRY; i++)
+ {
+ if (ValidWdsEntry(pAd, i))
+ {
+ PUCHAR pDA = pAd->WdsTab.WdsEntry[i].PeerWdsAddr;
+
+ // DA equal to SA. have no necessary orignal AP which found Radar signal.
+ if (MAC_ADDR_EQUAL(pTA, pDA))
+ continue;
+
+ // send Channel Switch Action frame to info Neighbro APs.
+ EnqueueChSwAnn(pAd, pDA, ChSwMode, Channel);
+ }
+ }
+ }
+#endif // WDS_SUPPORT //
+}
+
+static VOID StartDFSProcedure(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN UINT8 ChSwMode)
+{
+ // start DFS procedure
+ pAd->CommonCfg.Channel = Channel;
+#ifdef DOT11_N_SUPPORT
+ N_ChannelCheck(pAd);
+#endif // DOT11_N_SUPPORT //
+ pAd->CommonCfg.RadarDetect.RDMode = RD_SWITCHING_MODE;
+ pAd->CommonCfg.RadarDetect.CSCount = 0;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Channel Switch Announcement action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Channel switch announcement infomation buffer.
+
+
+ Return : None.
+ ==========================================================================
+ */
+
+/*
+ Channel Switch Announcement IE.
+ +----+-----+-----------+------------+-----------+
+ | ID | Len |Ch Sw Mode | New Ch Num | Ch Sw Cnt |
+ +----+-----+-----------+------------+-----------+
+ 1 1 1 1 1
+*/
+static BOOLEAN PeerChSwAnnSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PCH_SW_ANN_INFO pChSwAnnInfo)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+
+ // skip 802.11 header.
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pChSwAnnInfo == NULL)
+ return result;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_CHANNEL_SWITCH_ANNOUNCEMENT:
+ NdisMoveMemory(&pChSwAnnInfo->ChSwMode, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pChSwAnnInfo->Channel, eid_ptr->Octet + 1, 1);
+ NdisMoveMemory(&pChSwAnnInfo->ChSwCnt, eid_ptr->Octet + 2, 1);
+
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Measurement request action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Measurement request infomation buffer.
+
+ Return : None.
+ ==========================================================================
+ */
+static BOOLEAN PeerMeasureReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken,
+ OUT PMEASURE_REQ_INFO pMeasureReqInfo)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+ PUCHAR ptr;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+
+ // skip 802.11 header.
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pMeasureReqInfo == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_MEASUREMENT_REQUEST:
+ NdisMoveMemory(&pMeasureReqInfo->Token, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pMeasureReqInfo->ReqMode.word, eid_ptr->Octet + 1, 1);
+ NdisMoveMemory(&pMeasureReqInfo->ReqType, eid_ptr->Octet + 2, 1);
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pMeasureReqInfo->MeasureReq.ChNum, ptr, 1);
+ NdisMoveMemory(&MeasureStartTime, ptr + 1, 8);
+ pMeasureReqInfo->MeasureReq.MeasureStartTime = SWAP64(MeasureStartTime);
+ NdisMoveMemory(&MeasureDuration, ptr + 9, 2);
+ pMeasureReqInfo->MeasureReq.MeasureDuration = SWAP16(MeasureDuration);
+
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Measurement report action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Measurement report infomation buffer.
+ 4. basic report infomation buffer.
+
+ Return : None.
+ ==========================================================================
+ */
+
+/*
+ Measurement Report IE.
+ +----+-----+-------+-------------+--------------+----------------+
+ | ID | Len | Token | Report Mode | Measure Type | Measure Report |
+ +----+-----+-------+-------------+--------------+----------------+
+ 1 1 1 1 1 variable
+
+ Basic Report.
+ +--------+------------+----------+-----+
+ | Ch Num | Start Time | Duration | Map |
+ +--------+------------+----------+-----+
+ 1 8 2 1
+
+ Map Field Bit Format.
+ +-----+---------------+---------------------+-------+------------+----------+
+ | Bss | OFDM Preamble | Unidentified signal | Radar | Unmeasured | Reserved |
+ +-----+---------------+---------------------+-------+------------+----------+
+ 0 1 2 3 4 5-7
+*/
+static BOOLEAN PeerMeasureReportSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken,
+ OUT PMEASURE_REPORT_INFO pMeasureReportInfo,
+ OUT PUINT8 pReportBuf)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+ PUCHAR ptr;
+
+ // skip 802.11 header.
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pMeasureReportInfo == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_MEASUREMENT_REPORT:
+ NdisMoveMemory(&pMeasureReportInfo->Token, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pMeasureReportInfo->ReportMode, eid_ptr->Octet + 1, 1);
+ NdisMoveMemory(&pMeasureReportInfo->ReportType, eid_ptr->Octet + 2, 1);
+ if (pMeasureReportInfo->ReportType == RM_BASIC)
+ {
+ PMEASURE_BASIC_REPORT pReport = (PMEASURE_BASIC_REPORT)pReportBuf;
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pReport->ChNum, ptr, 1);
+ NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+ NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+ NdisMoveMemory(&pReport->Map, ptr + 11, 1);
+
+ }
+ else if (pMeasureReportInfo->ReportType == RM_CCA)
+ {
+ PMEASURE_CCA_REPORT pReport = (PMEASURE_CCA_REPORT)pReportBuf;
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pReport->ChNum, ptr, 1);
+ NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+ NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+ NdisMoveMemory(&pReport->CCA_Busy_Fraction, ptr + 11, 1);
+
+ }
+ else if (pMeasureReportInfo->ReportType == RM_RPI_HISTOGRAM)
+ {
+ PMEASURE_RPI_REPORT pReport = (PMEASURE_RPI_REPORT)pReportBuf;
+ ptr = eid_ptr->Octet + 3;
+ NdisMoveMemory(&pReport->ChNum, ptr, 1);
+ NdisMoveMemory(&pReport->MeasureStartTime, ptr + 1, 8);
+ NdisMoveMemory(&pReport->MeasureDuration, ptr + 9, 2);
+ NdisMoveMemory(&pReport->RPI_Density, ptr + 11, 8);
+ }
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Request action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Dialog Token.
+
+ Return : None.
+ ==========================================================================
+ */
+static BOOLEAN PeerTpcReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pDialogToken == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_TPC_REQUEST:
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Report action frame sanity check.
+
+ Parametrs:
+ 1. MLME message containing the received frame
+ 2. message length.
+ 3. Dialog Token.
+ 4. TPC Report IE.
+
+ Return : None.
+ ==========================================================================
+ */
+static BOOLEAN PeerTpcRepSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUINT8 pDialogToken,
+ OUT PTPC_REPORT_INFO pTpcRepInfo)
+{
+ PFRAME_802_11 Fr = (PFRAME_802_11)pMsg;
+ PUCHAR pFramePtr = Fr->Octet;
+ BOOLEAN result = FALSE;
+ PEID_STRUCT eid_ptr;
+
+ MsgLen -= sizeof(HEADER_802_11);
+
+ // skip category and action code.
+ pFramePtr += 2;
+ MsgLen -= 2;
+
+ if (pDialogToken == NULL)
+ return result;
+
+ NdisMoveMemory(pDialogToken, pFramePtr, 1);
+ pFramePtr += 1;
+ MsgLen -= 1;
+
+ eid_ptr = (PEID_STRUCT)pFramePtr;
+ while (((UCHAR*)eid_ptr + eid_ptr->Len + 1) < ((PUCHAR)pFramePtr + MsgLen))
+ {
+ switch(eid_ptr->Eid)
+ {
+ case IE_TPC_REPORT:
+ NdisMoveMemory(&pTpcRepInfo->TxPwr, eid_ptr->Octet, 1);
+ NdisMoveMemory(&pTpcRepInfo->LinkMargin, eid_ptr->Octet + 1, 1);
+ result = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ eid_ptr = (PEID_STRUCT)((UCHAR*)eid_ptr + 2 + eid_ptr->Len);
+ }
+
+ return result;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Channel Switch Announcement action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerChSwAnnAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ CH_SW_ANN_INFO ChSwAnnInfo;
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR index = 0, Channel = 0, NewChannel = 0;
+ ULONG Bssidx = 0;
+#endif // CONFIG_STA_SUPPORT //
+
+ NdisZeroMemory(&ChSwAnnInfo, sizeof(CH_SW_ANN_INFO));
+ if (! PeerChSwAnnSanity(pAd, Elem->Msg, Elem->MsgLen, &ChSwAnnInfo))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Invalid Channel Switch Action Frame.\n"));
+ return;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->OpMode == OPMODE_STA)
+ {
+ Bssidx = BssTableSearch(&pAd->ScanTab, pFr->Hdr.Addr3, pAd->CommonCfg.Channel);
+ if (Bssidx == BSS_NOT_FOUND)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerChSwAnnAction - Bssidx is not found\n"));
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("\n****Bssidx is %d, Channel = %d\n", index, pAd->ScanTab.BssEntry[Bssidx].Channel));
+ hex_dump("SSID",pAd->ScanTab.BssEntry[Bssidx].Bssid ,6);
+
+ Channel = pAd->CommonCfg.Channel;
+ NewChannel = ChSwAnnInfo.Channel;
+
+ if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
+ {
+ // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
+ // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+ AsicSwitchChannel(pAd, 1, FALSE);
+ AsicLockChannel(pAd, 1);
+ LinkDown(pAd, FALSE);
+ MlmeQueueInit(&pAd->Mlme.Queue);
+ BssTableInit(&pAd->ScanTab);
+ RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
+
+ // channel sanity check
+ for (index = 0 ; index < pAd->ChannelListNum; index++)
+ {
+ if (pAd->ChannelList[index].Channel == NewChannel)
+ {
+ pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+ pAd->CommonCfg.Channel = NewChannel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("&&&&&&&&&&&&&&&&PeerChSwAnnAction - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+ break;
+ }
+ }
+
+ if (index >= pAd->ChannelListNum)
+ {
+ DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Measurement Request action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerMeasureReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+ UINT8 DialogToken;
+ MEASURE_REQ_INFO MeasureReqInfo;
+ MEASURE_REPORT_MODE ReportMode;
+
+ if(PeerMeasureReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReqInfo))
+ {
+ ReportMode.word = 0;
+ ReportMode.field.Incapable = 1;
+ EnqueueMeasurementRep(pAd, pFr->Hdr.Addr2, DialogToken, MeasureReqInfo.Token, ReportMode.word, MeasureReqInfo.ReqType, 0, NULL);
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Measurement Report action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerMeasureReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MEASURE_REPORT_INFO MeasureReportInfo;
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+ UINT8 DialogToken;
+ PUINT8 pMeasureReportInfo;
+
+// if (pAd->CommonCfg.bIEEE80211H != TRUE)
+// return;
+
+ if ((pMeasureReportInfo = kmalloc(sizeof(MEASURE_RPI_REPORT), GFP_ATOMIC)) == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s unable to alloc memory for measure report buffer (size=%d).\n", __FUNCTION__, sizeof(MEASURE_RPI_REPORT)));
+ return;
+ }
+
+ NdisZeroMemory(&MeasureReportInfo, sizeof(MEASURE_REPORT_INFO));
+ NdisZeroMemory(pMeasureReportInfo, sizeof(MEASURE_RPI_REPORT));
+ if (PeerMeasureReportSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &MeasureReportInfo, pMeasureReportInfo))
+ {
+ do {
+ PMEASURE_REQ_ENTRY pEntry = NULL;
+
+ // Not a autonomous measure report.
+ // check the dialog token field. drop it if the dialog token doesn't match.
+ if ((DialogToken != 0)
+ && ((pEntry = MeasureReqLookUp(pAd, DialogToken)) == NULL))
+ break;
+
+ if (pEntry != NULL)
+ MeasureReqDelete(pAd, pEntry->DialogToken);
+
+ if (MeasureReportInfo.ReportType == RM_BASIC)
+ {
+ PMEASURE_BASIC_REPORT pBasicReport = (PMEASURE_BASIC_REPORT)pMeasureReportInfo;
+ if ((pBasicReport->Map.field.Radar)
+ && (DfsRequirementCheck(pAd, pBasicReport->ChNum) == TRUE))
+ {
+ NotifyChSwAnnToPeerAPs(pAd, pFr->Hdr.Addr1, pFr->Hdr.Addr2, 1, pBasicReport->ChNum);
+ StartDFSProcedure(pAd, pBasicReport->ChNum, 1);
+ }
+ }
+ } while (FALSE);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Invalid Measurement Report Frame.\n"));
+
+ kfree(pMeasureReportInfo);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Request action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerTpcReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PFRAME_802_11 pFr = (PFRAME_802_11)Elem->Msg;
+ PUCHAR pFramePtr = pFr->Octet;
+ UINT8 DialogToken;
+ UINT8 TxPwr = GetCurTxPwr(pAd, Elem->Wcid);
+ UINT8 LinkMargin = 0;
+ CHAR RealRssi;
+
+ // link margin: Ratio of the received signal power to the minimum desired by the station (STA). The
+ // STA may incorporate rate information and channel conditions, including interference, into its computation
+ // of link margin.
+
+ RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0),
+ ConvertToRssi(pAd, Elem->Rssi1, RSSI_1),
+ ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+ // skip Category and action code.
+ pFramePtr += 2;
+
+ // Dialog token.
+ NdisMoveMemory(&DialogToken, pFramePtr, 1);
+
+ LinkMargin = (RealRssi / MIN_RCV_PWR);
+ if (PeerTpcReqSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken))
+ EnqueueTPCRep(pAd, pFr->Hdr.Addr2, DialogToken, TxPwr, LinkMargin);
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ TPC Report action frame handler.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+static VOID PeerTpcRepAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UINT8 DialogToken;
+ TPC_REPORT_INFO TpcRepInfo;
+ PTPC_REQ_ENTRY pEntry = NULL;
+
+ NdisZeroMemory(&TpcRepInfo, sizeof(TPC_REPORT_INFO));
+ if (PeerTpcRepSanity(pAd, Elem->Msg, Elem->MsgLen, &DialogToken, &TpcRepInfo))
+ {
+ if ((pEntry = TpcReqLookUp(pAd, DialogToken)) != NULL)
+ {
+ TpcReqDelete(pAd, pEntry->DialogToken);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: DialogToken=%x, TxPwr=%d, LinkMargin=%d\n",
+ __FUNCTION__, DialogToken, TpcRepInfo.TxPwr, TpcRepInfo.LinkMargin));
+ }
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Spectrun action frames Handler such as channel switch annoucement,
+ measurement report, measurement request actions frames.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+VOID PeerSpectrumAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+
+ UCHAR Action = Elem->Msg[LENGTH_802_11+1];
+
+ if (pAd->CommonCfg.bIEEE80211H != TRUE)
+ return;
+
+ switch(Action)
+ {
+ case SPEC_MRQ:
+ // current rt2860 unable do such measure specified in Measurement Request.
+ // reject all measurement request.
+ PeerMeasureReqAction(pAd, Elem);
+ break;
+
+ case SPEC_MRP:
+ PeerMeasureReportAction(pAd, Elem);
+ break;
+
+ case SPEC_TPCRQ:
+ PeerTpcReqAction(pAd, Elem);
+ break;
+
+ case SPEC_TPCRP:
+ PeerTpcRepAction(pAd, Elem);
+ break;
+
+ case SPEC_CHANNEL_SWITCH:
+{
+#ifdef DOT11N_DRAFT3
+ SEC_CHA_OFFSET_IE Secondary;
+ CHA_SWITCH_ANNOUNCE_IE ChannelSwitch;
+
+ // 802.11h only has Channel Switch Announcement IE.
+ RTMPMoveMemory(&ChannelSwitch, &Elem->Msg[LENGTH_802_11+4], sizeof (CHA_SWITCH_ANNOUNCE_IE));
+
+ // 802.11n D3.03 adds secondary channel offset element in the end.
+ if (Elem->MsgLen == (LENGTH_802_11 + 2 + sizeof (CHA_SWITCH_ANNOUNCE_IE) + sizeof (SEC_CHA_OFFSET_IE)))
+ {
+ RTMPMoveMemory(&Secondary, &Elem->Msg[LENGTH_802_11+9], sizeof (SEC_CHA_OFFSET_IE));
+ }
+ else
+ {
+ Secondary.SecondaryChannelOffset = 0;
+ }
+
+ if ((Elem->Msg[LENGTH_802_11+2] == IE_CHANNEL_SWITCH_ANNOUNCEMENT) && (Elem->Msg[LENGTH_802_11+3] == 3))
+ {
+ ChannelSwitchAction(pAd, Elem->Wcid, ChannelSwitch.NewChannel, Secondary.SecondaryChannelOffset);
+ }
+#endif // DOT11N_DRAFT3 //
+}
+ PeerChSwAnnAction(pAd, Elem);
+ break;
+ }
+
+ return;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ Parametrs:
+
+ Return : None.
+ ==========================================================================
+ */
+INT Set_MeasureReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT Aid = 1;
+ UINT ArgIdx;
+ PUCHAR thisChar;
+
+ MEASURE_REQ_MODE MeasureReqMode;
+ UINT8 MeasureReqToken = RandomByte(pAd);
+ UINT8 MeasureReqType = RM_BASIC;
+ UINT8 MeasureCh = 1;
+
+ ArgIdx = 1;
+ while ((thisChar = strsep((char **)&arg, "-")) != NULL)
+ {
+ switch(ArgIdx)
+ {
+ case 1: // Aid.
+ Aid = simple_strtol(thisChar, 0, 16);
+ break;
+
+ case 2: // Measurement Request Type.
+ MeasureReqType = simple_strtol(thisChar, 0, 16);
+ if (MeasureReqType > 3)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow MeasureReqType(%d)\n", __FUNCTION__, MeasureReqType));
+ return TRUE;
+ }
+ break;
+
+ case 3: // Measurement channel.
+ MeasureCh = simple_strtol(thisChar, 0, 16);
+ break;
+ }
+ ArgIdx++;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d, MeasureReqType=%d MeasureCh=%d\n", __FUNCTION__, Aid, MeasureReqType, MeasureCh));
+ if (!VALID_WCID(Aid))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
+ return TRUE;
+ }
+
+ MeasureReqMode.word = 0;
+ MeasureReqMode.field.Enable = 1;
+
+ MeasureReqInsert(pAd, MeasureReqToken);
+
+ EnqueueMeasurementReq(pAd, pAd->MacTab.Content[Aid].Addr,
+ MeasureReqToken, MeasureReqMode.word, MeasureReqType, MeasureCh, 2000);
+
+ return TRUE;
+}
+
+INT Set_TpcReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT Aid;
+
+ UINT8 TpcReqToken = RandomByte(pAd);
+
+ Aid = simple_strtol(arg, 0, 16);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Aid = %d\n", __FUNCTION__, Aid));
+ if (!VALID_WCID(Aid))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: unknow sta of Aid(%d)\n", __FUNCTION__, Aid));
+ return TRUE;
+ }
+
+ TpcReqInsert(pAd, TpcReqToken);
+
+ EnqueueTPCReq(pAd, pAd->MacTab.Content[Aid].Addr, TpcReqToken);
+
+ return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/dfs.h b/drivers/staging/rt3070/dfs.h
new file mode 100644
index 00000000000..752a6352d9d
--- /dev/null
+++ b/drivers/staging/rt3070/dfs.h
@@ -0,0 +1,100 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ dfs.h
+
+ Abstract:
+ Support DFS function.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Fonchi 03-12-2007 created
+*/
+
+#define RADAR_PULSE 1
+#define RADAR_WIDTH 2
+
+#define WIDTH_RD_IDLE 0
+#define WIDTH_RD_CHECK 1
+
+
+VOID BbpRadarDetectionStart(
+ IN PRTMP_ADAPTER pAd);
+
+VOID BbpRadarDetectionStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RadarDetectionStart(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN CTS_Protect,
+ IN UINT8 CTSPeriod);
+
+VOID RadarDetectionStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RadarDetectPeriodic(
+ IN PRTMP_ADAPTER pAd);
+
+
+BOOLEAN RadarChannelCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ch);
+
+ULONG JapRadarType(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG RTMPBbpReadRadarDuration(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG RTMPReadRadarDuration(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPCleanRadarDuration(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPPrepareRDCTSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN ULONG Duration,
+ IN UCHAR RTSRate,
+ IN ULONG CTSBaseAddr,
+ IN UCHAR FrameGap);
+
+VOID RTMPPrepareRadarDetectParams(
+ IN PRTMP_ADAPTER pAd);
+
+
+INT Set_ChMovingTime_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_LongPulseRadarTh_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
diff --git a/drivers/staging/rt3070/firmware.h b/drivers/staging/rt3070/firmware.h
new file mode 100644
index 00000000000..b07783ed8dd
--- /dev/null
+++ b/drivers/staging/rt3070/firmware.h
@@ -0,0 +1,558 @@
+/*
+ Copyright (c) 2007, Ralink Technology Corporation
+ All rights reserved.
+
+ Redistribution. Redistribution and use in binary form, without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions must reproduce the above copyright notice and the
+ following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+ * Neither the name of Ralink Technology Corporation nor the names of its
+ suppliers may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+ * No reverse engineering, decompilation, or disassembly of this software
+ is permitted.
+
+ Limited patent license. Ralink Technology Corporation grants a world-wide,
+ royalty-free, non-exclusive license under patents it now or hereafter
+ owns or controls to make, have made, use, import, offer to sell and
+ sell ("Utilize") this software, but solely to the extent that any
+ such patent is necessary to Utilize the software alone, or in
+ combination with an operating system licensed under an approved Open
+ Source license as listed by the Open Source Initiative at
+ http://opensource.org/licenses. The patent license shall not apply to
+ any other combinations which include this software. No hardware per
+ se is licensed hereunder.
+
+ DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
+ BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+*/
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+/* AUTO GEN PLEASE DO NOT MODIFY IT */
+
+
+UCHAR FirmwareImage [] = {
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
+0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
+0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
+0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xc8, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0x9d, 0x10,
+0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
+0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
+0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
+0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
+0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
+0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
+0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
+0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
+0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
+0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
+0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
+0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
+0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0xd2, 0x04, 0x22, 0x90, 0x70,
+0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
+0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
+0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
+0x91, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
+0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
+0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
+0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
+0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74, 0x80,
+0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
+0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90, 0x04, 0x14, 0x74,
+0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
+0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0x91, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
+0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
+0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
+0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
+0x4c, 0xe5, 0x44, 0x12, 0x0a, 0x9d, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
+0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
+0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
+0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
+0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
+0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
+0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
+0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
+0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
+0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
+0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
+0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
+0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
+0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
+0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
+0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
+0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
+0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
+0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
+0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
+0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
+0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
+0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
+0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
+0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
+0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
+0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
+0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
+0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
+0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
+0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
+0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
+0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
+0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
+0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
+0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
+0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
+0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
+0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
+0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
+0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
+0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
+0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
+0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
+0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
+0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
+0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
+0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
+0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
+0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
+0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
+0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
+0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
+0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
+0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
+0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
+0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
+0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
+0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
+0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
+0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
+0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
+0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
+0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
+0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
+0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
+0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
+0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
+0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
+0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
+0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
+0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
+0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
+0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
+0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
+0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
+0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
+0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
+0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
+0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
+0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
+0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
+0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x94, 0x3f,
+0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x32, 0x02, 0x10, 0x78, 0x02, 0x12, 0x67, 0x02,
+0x12, 0x68, 0x02, 0x12, 0x87, 0x02, 0x12, 0x8c, 0x12, 0x12, 0x88, 0x22, 0x02, 0x16, 0x49, 0x02,
+0x17, 0x1f, 0x02, 0x13, 0x77, 0x02, 0x12, 0x8d, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x17,
+0xc1, 0x22, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe3, 0x1b, 0xe5, 0x4c, 0x30, 0xe0, 0x04, 0x7f, 0x40,
+0x80, 0x02, 0x7f, 0x00, 0x90, 0x10, 0x2f, 0xef, 0xf0, 0x90, 0x01, 0x8c, 0x74, 0x08, 0xf0, 0xe4,
+0x90, 0x01, 0xa7, 0xf0, 0x90, 0x01, 0x8c, 0xe0, 0x30, 0xe0, 0x1c, 0x90, 0x01, 0x80, 0xe0, 0xb4,
+0x02, 0x15, 0xa3, 0xe0, 0xb4, 0x01, 0x10, 0x90, 0x01, 0x84, 0xe0, 0xb4, 0x81, 0x09, 0x90, 0x01,
+0x8c, 0x74, 0x01, 0xf0, 0x12, 0x0d, 0xdd, 0x22, 0x90, 0x04, 0x14, 0xe0, 0x20, 0xe7, 0x03, 0x02,
+0x12, 0x66, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0, 0x12, 0x0a, 0xb6, 0x10,
+0xb7, 0x31, 0x10, 0xe0, 0x50, 0x11, 0x04, 0x51, 0x11, 0x0d, 0x52, 0x11, 0x0d, 0x53, 0x11, 0x0d,
+0x54, 0x11, 0x4e, 0x55, 0x11, 0x7e, 0x70, 0x11, 0xa9, 0x71, 0x11, 0xd7, 0x72, 0x12, 0x1d, 0x73,
+0x12, 0x3e, 0x80, 0x00, 0x00, 0x12, 0x66, 0x20, 0x02, 0x03, 0x30, 0x03, 0x1d, 0x7d, 0x02, 0xaf,
+0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5,
+0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22,
+0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0x64, 0x02, 0x60, 0x03, 0x02, 0x12, 0x66, 0x90, 0x70, 0x11,
+0xe0, 0x64, 0x08, 0x60, 0x08, 0xe0, 0x64, 0x20, 0x60, 0x03, 0x02, 0x12, 0x66, 0x75, 0x4e, 0x03,
+0x75, 0x4f, 0x20, 0x22, 0x90, 0x70, 0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0x90, 0x04, 0x04,
+0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90, 0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57,
+0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0, 0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef,
+0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90,
+0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0xe5, 0x47,
+0x64, 0x07, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0x90,
+0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09, 0x08, 0xe5, 0x3a, 0xb4, 0x03,
+0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0xd2, 0x04, 0x22, 0x90, 0x70,
+0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57, 0xfd, 0xaf, 0x56,
+0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56,
+0xf4, 0x70, 0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70,
+0x11, 0xe0, 0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x0b,
+0xaa, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x70,
+0x03, 0x02, 0x12, 0x66, 0x02, 0x12, 0x5f, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x70, 0x1e, 0xa3, 0xe0,
+0xb4, 0x30, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01, 0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54,
+0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90, 0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5,
+0x4f, 0x75, 0x3a, 0xff, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74, 0x80,
+0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x4b, 0x80, 0x42, 0x90, 0x70, 0x10,
+0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90, 0x04, 0x14, 0x74,
+0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x2a, 0x80, 0x21, 0x90, 0x70,
+0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x0b, 0xaa, 0x90,
+0x04, 0x14, 0x74, 0x80, 0xf0, 0xe4, 0x90, 0x70, 0x13, 0xf0, 0xe5, 0x56, 0xf4, 0x60, 0x07, 0x90,
+0x70, 0x25, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x22, 0xe5, 0x53, 0x70, 0x1a, 0x30, 0x60, 0x09, 0xb2,
+0x4d, 0x30, 0x4d, 0x04, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f,
+0x15, 0x4f, 0x70, 0x02, 0x15, 0x4e, 0x22, 0x22, 0xc2, 0x42, 0xd3, 0x22, 0x22, 0xc2, 0x4b, 0xc2,
+0x4c, 0xe5, 0x44, 0x12, 0x0a, 0xb6, 0x12, 0xaf, 0x00, 0x13, 0x42, 0x04, 0x13, 0x3e, 0x08, 0x13,
+0x19, 0x10, 0x12, 0xc3, 0x20, 0x12, 0xe3, 0x60, 0x12, 0xf4, 0xa0, 0x00, 0x00, 0x13, 0x44, 0x85,
+0x48, 0x43, 0x85, 0x4a, 0x42, 0x85, 0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x13,
+0x44, 0x80, 0x1b, 0xe5, 0x48, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5,
+0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x66, 0x53, 0x43,
+0x0f, 0x80, 0x61, 0x85, 0x49, 0x43, 0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06,
+0x70, 0x52, 0x80, 0x1b, 0xe5, 0x49, 0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f,
+0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54, 0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x35, 0xe5,
+0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5, 0x43, 0x80, 0x2b, 0xe5, 0x47, 0xb4, 0x04, 0x06, 0x53, 0x5e,
+0xfb, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e, 0x04, 0x75, 0x42, 0x09, 0xe5,
+0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5, 0x43, 0x80, 0x06, 0xd2, 0x4b,
+0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x25, 0xe5, 0x42, 0xc4, 0x54, 0xf0, 0xff, 0xe5, 0x43, 0x54,
+0x0f, 0x4f, 0xf5, 0x5f, 0x90, 0x70, 0x44, 0xf0, 0xa3, 0xe5, 0x5e, 0xf0, 0xa3, 0xe5, 0x4a, 0xf0,
+0xa3, 0xe5, 0x48, 0xf0, 0xa3, 0xe5, 0x4c, 0xf0, 0xa3, 0xe5, 0x44, 0xf0, 0xa3, 0xe5, 0x42, 0xf0,
+0xa3, 0xe5, 0x43, 0xf0, 0xd2, 0x60, 0x22, 0xe5, 0x47, 0x60, 0x10, 0x24, 0xc0, 0x70, 0x03, 0x12,
+0x16, 0x29, 0x12, 0x13, 0x8c, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x90, 0x04,
+0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x18, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f, 0x24, 0xff,
+0x92, 0x18, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x19, 0x74, 0x1e, 0xf0, 0xe5,
+0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x25, 0x70, 0x13, 0x30, 0x18, 0x05, 0xe5, 0x5f, 0x20, 0xe5,
+0x0b, 0x30, 0x19, 0x19, 0xe5, 0x5f, 0x54, 0x30, 0xff, 0xbf, 0x30, 0x11, 0xe5, 0x25, 0x70, 0x05,
+0x75, 0x25, 0x0c, 0x80, 0x02, 0x15, 0x25, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5, 0x5f, 0x30,
+0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47, 0x64, 0x03,
+0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x25, 0x70, 0x03, 0x30,
+0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x25, 0x70, 0x05, 0x75, 0x25, 0x07, 0x80, 0x02, 0x15, 0x25, 0xd2,
+0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5, 0x3a, 0x64,
+0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0x90, 0x70, 0x46, 0xe5,
+0x2d, 0xf0, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68, 0x20, 0x6b, 0x07, 0xe5,
+0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20, 0xe2, 0x02, 0xb2, 0x6c,
+0x90, 0x70, 0x47, 0xe5, 0x2d, 0xf0, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x26,
+0x30, 0x68, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01,
+0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02,
+0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80,
+0x26, 0x30, 0x6a, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
+0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80,
+0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c,
+0x80, 0x26, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04,
+0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90, 0x10, 0x00, 0xe0,
+0x90, 0x10, 0x2f, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14, 0xa2, 0x71, 0x92,
+0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e, 0xc2, 0x77, 0xd2,
+0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4c, 0x90, 0x02, 0x29,
+0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x14, 0x24, 0xfe, 0x60, 0x23,
+0x24, 0x03, 0x60, 0x03, 0x02, 0x16, 0x18, 0x90, 0x02, 0x28, 0xe0, 0x30, 0x47, 0x0f, 0x80, 0x07,
+0x90, 0x02, 0x28, 0xe0, 0x20, 0x47, 0x06, 0x54, 0xfe, 0xf0, 0x02, 0x16, 0x18, 0x44, 0x01, 0xf0,
+0x02, 0x16, 0x18, 0xe5, 0x46, 0x30, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0x90, 0x02,
+0x28, 0xe0, 0x54, 0xfe, 0x4f, 0xf0, 0x02, 0x16, 0x18, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
+0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x16, 0x18, 0xe4, 0xf5,
+0x27, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x2d, 0x14, 0x60, 0x2e,
+0x14, 0x60, 0x36, 0x24, 0xfc, 0x60, 0x5f, 0x24, 0xf9, 0x60, 0x1f, 0x24, 0x0e, 0x70, 0x69, 0xe5,
+0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xaf, 0xf0, 0x20, 0x47, 0x04, 0x7e, 0x01,
+0x80, 0x02, 0x7e, 0x00, 0xef, 0x6e, 0x24, 0xff, 0x80, 0x45, 0xa2, 0x47, 0x80, 0x41, 0xe5, 0x46,
+0x30, 0xe2, 0x03, 0xd3, 0x80, 0x27, 0xc3, 0x80, 0x24, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38,
+0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x20,
+0x47, 0x04, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x00, 0xef, 0x6d, 0x4e, 0x24, 0xff, 0x92, 0x38, 0xa2,
+0x47, 0xb3, 0x92, 0x39, 0x80, 0x19, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92,
+0x39, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x80, 0x07, 0xa2, 0x47, 0xb3, 0x92, 0x38, 0x92, 0x39, 0x90,
+0x02, 0x28, 0xe0, 0x54, 0xfc, 0x45, 0x27, 0xf0, 0x90, 0x70, 0x9c, 0xe5, 0x3a, 0xf0, 0xa3, 0xe5,
+0x47, 0xf0, 0x90, 0x70, 0x41, 0xe5, 0x3a, 0xf0, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30, 0x47,
+0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22, 0x8f,
+0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x62, 0xc2, 0xaf, 0xe5, 0x51,
+0x14, 0x60, 0x46, 0x14, 0x60, 0x62, 0x24, 0x02, 0x60, 0x03, 0x02, 0x17, 0x03, 0xd2, 0x59, 0x75,
+0x55, 0x01, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0x7f, 0xf0, 0xa3, 0xe0, 0x20, 0xe7, 0x22, 0x90, 0x04,
+0x34, 0xe0, 0xb4, 0x02, 0x1b, 0xa3, 0xe0, 0xb4, 0x02, 0x16, 0xa3, 0xe0, 0xb4, 0x02, 0x11, 0x7f,
+0x20, 0x12, 0x16, 0x3f, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51, 0x01, 0x80, 0x73,
+0xe5, 0x50, 0x70, 0x05, 0x75, 0x62, 0x03, 0x80, 0x6a, 0x90, 0x12, 0x00, 0xe0, 0x54, 0x03, 0x70,
+0x11, 0x7f, 0x20, 0x12, 0x16, 0x3f, 0x90, 0x02, 0xa2, 0xe0, 0x54, 0xbf, 0xf0, 0x75, 0x51, 0x02,
+0x80, 0x51, 0xe5, 0x50, 0x70, 0x02, 0x80, 0x46, 0x90, 0x02, 0xa3, 0xe0, 0x20, 0xe6, 0x3b, 0x90,
+0x04, 0x37, 0xe0, 0x64, 0x22, 0x70, 0x33, 0x90, 0x01, 0x8a, 0x74, 0x7e, 0xf0, 0x90, 0x01, 0x96,
+0xf0, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0,
+0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xfa, 0xf0, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xf9, 0xf0, 0x75,
+0x62, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05, 0x75, 0x62,
+0x03, 0xf5, 0x51, 0xe5, 0x62, 0x60, 0x15, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xad, 0x62,
+0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x62, 0xb4, 0x03, 0x02, 0xd2, 0x03, 0xd2, 0xaf, 0x22, 0xc2,
+0xaf, 0x30, 0x01, 0x12, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01, 0x7d,
+0x02, 0xaf, 0x40, 0x12, 0x17, 0x8d, 0xe5, 0x52, 0x14, 0x60, 0x09, 0x04, 0x70, 0x4c, 0x75, 0x52,
+0x01, 0x75, 0x55, 0x03, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x44,
+0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x12, 0x04, 0x74,
+0x03, 0xf0, 0x90, 0x02, 0xa2, 0xe0, 0x44, 0xc0, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c, 0xf0,
+0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x0b, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12, 0x17,
+0x8d, 0x80, 0x02, 0xc2, 0x03, 0xe4, 0x90, 0x01, 0x96, 0xf0, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60,
+0x2d, 0xe4, 0xfe, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
+0x19, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e,
+0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22,
+0x22, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1, 0x4d, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10,
+0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90, 0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10,
+0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5, 0x62, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90,
+0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0, 0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90,
+0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0, 0x30, 0x4a, 0x07, 0x90, 0x70, 0x24, 0xe0, 0x44, 0x01,
+0xf0, 0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x9b, 0xc0, } ;
diff --git a/drivers/staging/rt3070/leap.h b/drivers/staging/rt3070/leap.h
new file mode 100644
index 00000000000..6818c1ff4d7
--- /dev/null
+++ b/drivers/staging/rt3070/leap.h
@@ -0,0 +1,215 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ leap.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#ifndef __LEAP_H__
+#define __LEAP_H__
+
+// Messages for Associate state machine
+#define LEAP_MACHINE_BASE 30
+
+#define LEAP_MSG_REQUEST_IDENTITY 31
+#define LEAP_MSG_REQUEST_LEAP 32
+#define LEAP_MSG_SUCCESS 33
+#define LEAP_MSG_FAILED 34
+#define LEAP_MSG_RESPONSE_LEAP 35
+#define LEAP_MSG_EAPOLKEY 36
+#define LEAP_MSG_UNKNOWN 37
+#define LEAP_MSG 38
+//! assoc state-machine states
+#define LEAP_IDLE 0
+#define LEAP_WAIT_IDENTITY_REQUEST 1
+#define LEAP_WAIT_CHANLLENGE_REQUEST 2
+#define LEAP_WAIT_SUCCESS 3
+#define LEAP_WAIT_CHANLLENGE_RESPONSE 4
+#define LEAP_WAIT_EAPOLKEY 5
+
+#define LEAP_REASON_INVALID_AUTH 0x01
+#define LEAP_REASON_AUTH_TIMEOUT 0x02
+#define LEAP_REASON_CHALLENGE_FROM_AP_FAILED 0x03
+#define LEAP_REASON_CHALLENGE_TO_AP_FAILED 0x04
+
+#define CISCO_AuthModeLEAP 0x80
+#define CISCO_AuthModeLEAPNone 0x00
+#define LEAP_AUTH_TIMEOUT 30000
+#define LEAP_CHALLENGE_RESPONSE_LENGTH 24
+#define LEAP_CHALLENGE_REQUEST_LENGTH 8
+
+typedef struct _LEAP_EAPOL_HEADER_ {
+ UCHAR Version;
+ UCHAR Type;
+ UCHAR Length[2];
+} LEAP_EAPOL_HEADER, *PLEAP_EAPOL_HEADER;
+
+typedef struct _LEAP_EAPOL_PACKET_ {
+ UCHAR Code;
+ UCHAR Identifier;
+ UCHAR Length[2];
+ UCHAR Type;
+} LEAP_EAPOL_PACKET, *PLEAP_EAPOL_PACKET;
+
+typedef struct _LEAP_EAP_CONTENTS_ {
+ UCHAR Version;
+ UCHAR Reserved;
+ UCHAR Length;
+} LEAP_EAP_CONTENTS, *PLEAP_EAP_CONTENTS;
+
+/*** EAPOL key ***/
+typedef struct _EAPOL_KEY_HEADER_ {
+ UCHAR Type;
+ UCHAR Length[2];
+ UCHAR Counter[8];
+ UCHAR IV[16];
+ UCHAR Index;
+ UCHAR Signature[16];
+} EAPOL_KEY_HEADER, *PEAPOL_KEY_HEADER;
+
+BOOLEAN LeapMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT ULONG *MsgType);
+
+VOID LeapMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR wep,
+ IN PUCHAR pAddr3);
+
+VOID LeapStartAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapIdentityAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapPeerChallengeAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID HashPwd(
+ IN PUCHAR pwd,
+ IN INT pwdlen,
+ OUT PUCHAR hash);
+
+VOID PeerChallengeResponse(
+ IN PUCHAR szChallenge,
+ IN PUCHAR smbPasswd,
+ OUT PUCHAR szResponse);
+
+VOID ParityKey(
+ OUT PUCHAR szOut,
+ IN PUCHAR szIn);
+
+VOID DesKey(
+ OUT ULONG k[16][2],
+ IN PUCHAR key,
+ IN INT decrypt);
+
+VOID Des(
+ IN ULONG ks[16][2],
+ OUT UCHAR block[8]);
+
+VOID DesEncrypt(
+ IN PUCHAR szClear,
+ IN PUCHAR szKey,
+ OUT PUCHAR szOut);
+
+VOID LeapNetworkChallengeAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID LeapNetworkChallengeResponse(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID HashpwdHash(
+ IN PUCHAR hash,
+ IN PUCHAR hashhash);
+
+VOID ProcessSessionKey(
+ OUT PUCHAR SessionKey,
+ IN PUCHAR hash2,
+ IN PUCHAR ChallengeToRadius,
+ IN PUCHAR ChallengeResponseFromRadius,
+ IN PUCHAR ChallengeFromRadius,
+ IN PUCHAR ChallengeResponseToRadius);
+
+VOID LeapEapolKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID RogueApTableInit(
+ IN ROGUEAP_TABLE *Tab);
+
+ULONG RogueApTableSearch(
+ IN ROGUEAP_TABLE *Tab,
+ IN PUCHAR pAddr);
+
+VOID RogueApEntrySet(
+ IN PRTMP_ADAPTER pAd,
+ OUT ROGUEAP_ENTRY *pRogueAp,
+ IN PUCHAR pAddr,
+ IN UCHAR FaileCode);
+
+ULONG RogueApTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT ROGUEAP_TABLE *Tab,
+ IN PUCHAR pAddr,
+ IN UCHAR FaileCode);
+
+VOID RogueApTableDeleteEntry(
+ IN OUT ROGUEAP_TABLE *Tab,
+ IN PUCHAR pAddr);
+
+VOID LeapAuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LeapSendRogueAPReport(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN CCKMAssocRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen);
+
+#endif // __LEAP_H__
diff --git a/drivers/staging/rt3070/link_list.h b/drivers/staging/rt3070/link_list.h
new file mode 100644
index 00000000000..f6521133fd5
--- /dev/null
+++ b/drivers/staging/rt3070/link_list.h
@@ -0,0 +1,134 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __LINK_LIST_H__
+#define __LINK_LIST_H__
+
+typedef struct _LIST_ENTRY
+{
+ struct _LIST_ENTRY *pNext;
+} LIST_ENTRY, *PLIST_ENTRY;
+
+typedef struct _LIST_HEADR
+{
+ PLIST_ENTRY pHead;
+ PLIST_ENTRY pTail;
+ UCHAR size;
+} LIST_HEADER, *PLIST_HEADER;
+
+static inline VOID initList(
+ IN PLIST_HEADER pList)
+{
+ pList->pHead = pList->pTail = NULL;
+ pList->size = 0;
+ return;
+}
+
+static inline VOID insertTailList(
+ IN PLIST_HEADER pList,
+ IN PLIST_ENTRY pEntry)
+{
+ pEntry->pNext = NULL;
+ if (pList->pTail)
+ pList->pTail->pNext = pEntry;
+ else
+ pList->pHead = pEntry;
+ pList->pTail = pEntry;
+ pList->size++;
+
+ return;
+}
+
+static inline PLIST_ENTRY removeHeadList(
+ IN PLIST_HEADER pList)
+{
+ PLIST_ENTRY pNext;
+ PLIST_ENTRY pEntry;
+
+ pEntry = pList->pHead;
+ if (pList->pHead != NULL)
+ {
+ pNext = pList->pHead->pNext;
+ pList->pHead = pNext;
+ if (pNext == NULL)
+ pList->pTail = NULL;
+ pList->size--;
+ }
+ return pEntry;
+}
+
+static inline int getListSize(
+ IN PLIST_HEADER pList)
+{
+ return pList->size;
+}
+
+static inline PLIST_ENTRY delEntryList(
+ IN PLIST_HEADER pList,
+ IN PLIST_ENTRY pEntry)
+{
+ PLIST_ENTRY pCurEntry;
+ PLIST_ENTRY pPrvEntry;
+
+ if(pList->pHead == NULL)
+ return NULL;
+
+ if(pEntry == pList->pHead)
+ {
+ pCurEntry = pList->pHead;
+ pList->pHead = pCurEntry->pNext;
+
+ if(pList->pHead == NULL)
+ pList->pTail = NULL;
+
+ pList->size--;
+ return pCurEntry;
+ }
+
+ pPrvEntry = pList->pHead;
+ pCurEntry = pPrvEntry->pNext;
+ while(pCurEntry != NULL)
+ {
+ if (pEntry == pCurEntry)
+ {
+ pPrvEntry->pNext = pCurEntry->pNext;
+
+ if(pEntry == pList->pTail)
+ pList->pTail = pPrvEntry;
+
+ pList->size--;
+ break;
+ }
+ pPrvEntry = pCurEntry;
+ pCurEntry = pPrvEntry->pNext;
+ }
+
+ return pCurEntry;
+}
+
+#endif // ___LINK_LIST_H__ //
+
diff --git a/drivers/staging/rt3070/md4.h b/drivers/staging/rt3070/md4.h
new file mode 100644
index 00000000000..f1e5b526350
--- /dev/null
+++ b/drivers/staging/rt3070/md4.h
@@ -0,0 +1,42 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __MD4_H__
+#define __MD4_H__
+
+/* MD4 context. */
+typedef struct _MD4_CTX_ {
+ ULONG state[4]; /* state (ABCD) */
+ ULONG count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ UCHAR buffer[64]; /* input buffer */
+} MD4_CTX;
+
+VOID MD4Init (MD4_CTX *);
+VOID MD4Update (MD4_CTX *, PUCHAR, UINT);
+VOID MD4Final (UCHAR [16], MD4_CTX *);
+
+#endif //__MD4_H__ \ No newline at end of file
diff --git a/drivers/staging/rt3070/md5.h b/drivers/staging/rt3070/md5.h
new file mode 100644
index 00000000000..d85db12170d
--- /dev/null
+++ b/drivers/staging/rt3070/md5.h
@@ -0,0 +1,107 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ md5.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ jan 10-28-03 Initial
+ Rita 11-23-04 Modify MD5 and SHA-1
+*/
+
+#ifndef uint8
+#define uint8 unsigned char
+#endif
+
+#ifndef uint32
+#define uint32 unsigned long int
+#endif
+
+
+#ifndef __MD5_H__
+#define __MD5_H__
+
+#define MD5_MAC_LEN 16
+
+typedef struct _MD5_CTX {
+ UINT32 Buf[4]; // buffers of four states
+ UCHAR Input[64]; // input message
+ UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits
+} MD5_CTX;
+
+VOID MD5Init(MD5_CTX *pCtx);
+VOID MD5Update(MD5_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
+VOID MD5Final(UCHAR Digest[16], MD5_CTX *pCtx);
+VOID MD5Transform(UINT32 Buf[4], UINT32 Mes[16]);
+
+void md5_mac(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
+void hmac_md5(u8 *key, size_t key_len, u8 *data, size_t data_len, u8 *mac);
+
+//
+// SHA context
+//
+typedef struct _SHA_CTX
+{
+ UINT32 Buf[5]; // buffers of five states
+ UCHAR Input[80]; // input message
+ UINT32 LenInBitCount[2]; // length counter for input message, 0 up to 64 bits
+
+} SHA_CTX;
+
+VOID SHAInit(SHA_CTX *pCtx);
+UCHAR SHAUpdate(SHA_CTX *pCtx, UCHAR *pData, UINT32 LenInBytes);
+VOID SHAFinal(SHA_CTX *pCtx, UCHAR Digest[20]);
+VOID SHATransform(UINT32 Buf[5], UINT32 Mes[20]);
+
+#define SHA_DIGEST_LEN 20
+#endif // __MD5_H__
+
+/******************************************************************************/
+#ifndef _AES_H
+#define _AES_H
+
+typedef struct
+{
+ uint32 erk[64]; /* encryption round keys */
+ uint32 drk[64]; /* decryption round keys */
+ int nr; /* number of rounds */
+}
+aes_context;
+
+int rtmp_aes_set_key( aes_context *ctx, uint8 *key, int nbits );
+void rtmp_aes_encrypt( aes_context *ctx, uint8 input[16], uint8 output[16] );
+void rtmp_aes_decrypt( aes_context *ctx, uint8 input[16], uint8 output[16] );
+
+void F(char *password, unsigned char *ssid, int ssidlength, int iterations, int count, unsigned char *output);
+int PasswordHash(char *password, unsigned char *ssid, int ssidlength, unsigned char *output);
+
+#endif /* aes.h */
+
diff --git a/drivers/staging/rt3070/mlme.h b/drivers/staging/rt3070/mlme.h
new file mode 100644
index 00000000000..b0035e1fa8e
--- /dev/null
+++ b/drivers/staging/rt3070/mlme.h
@@ -0,0 +1,1468 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ mlme.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2003-08-28 Created
+ John Chang 2004-09-06 modified for RT2600
+
+*/
+#ifndef __MLME_H__
+#define __MLME_H__
+
+//extern UCHAR BROADCAST_ADDR[];
+
+// maximum supported capability information -
+// ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot
+#define SUPPORTED_CAPABILITY_INFO 0x0533
+
+#define END_OF_ARGS -1
+#define LFSR_MASK 0x80000057
+#define MLME_TASK_EXEC_INTV 100/*200*/ //
+#define LEAD_TIME 5
+#define MLME_TASK_EXEC_MULTIPLE 10 /*5*/ // MLME_TASK_EXEC_MULTIPLE * MLME_TASK_EXEC_INTV = 1 sec
+#define REORDER_EXEC_INTV 100 // 0.1 sec
+//#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
+
+// The definition of Radar detection duration region
+#define CE 0
+#define FCC 1
+#define JAP 2
+#define JAP_W53 3
+#define JAP_W56 4
+#define MAX_RD_REGION 5
+
+#ifdef NDIS51_MINIPORT
+#define BEACON_LOST_TIME 4000 // 2048 msec = 2 sec
+#else
+#define BEACON_LOST_TIME 4 * OS_HZ // 2048 msec = 2 sec
+#endif
+
+#define DLS_TIMEOUT 1200 // unit: msec
+#define AUTH_TIMEOUT 300 // unit: msec
+#define ASSOC_TIMEOUT 300 // unit: msec
+#define JOIN_TIMEOUT 2 * OS_HZ // unit: msec
+#define SHORT_CHANNEL_TIME 90 // unit: msec
+#define MIN_CHANNEL_TIME 110 // unit: msec, for dual band scan
+#define MAX_CHANNEL_TIME 140 // unit: msec, for single band scan
+#define FAST_ACTIVE_SCAN_TIME 30 // Active scan waiting for probe response time
+#define CW_MIN_IN_BITS 4 // actual CwMin = 2^CW_MIN_IN_BITS - 1
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifndef CONFIG_AP_SUPPORT
+#define CW_MAX_IN_BITS 10 // actual CwMax = 2^CW_MAX_IN_BITS - 1
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+extern UINT32 CW_MAX_IN_BITS;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+// Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720).
+// SHould not refer to this constant anymore
+//#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm
+#define RSSI_FOR_MID_TX_POWER -55 // -55 db is considered mid-distance
+#define RSSI_FOR_LOW_TX_POWER -45 // -45 db is considered very short distance and
+ // eligible to use a lower TX power
+#define RSSI_FOR_LOWEST_TX_POWER -30
+//#define MID_TX_POWER_DELTA 0 // 0 db from full TX power upon mid-distance to AP
+#define LOW_TX_POWER_DELTA 6 // -3 db from full TX power upon very short distance. 1 grade is 0.5 db
+#define LOWEST_TX_POWER_DELTA 16 // -8 db from full TX power upon shortest distance. 1 grade is 0.5 db
+
+#define RSSI_TRIGGERED_UPON_BELOW_THRESHOLD 0
+#define RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD 1
+#define RSSI_THRESHOLD_FOR_ROAMING 25
+#define RSSI_DELTA 5
+
+// Channel Quality Indication
+#define CQI_IS_GOOD(cqi) ((cqi) >= 50)
+//#define CQI_IS_FAIR(cqi) (((cqi) >= 20) && ((cqi) < 50))
+#define CQI_IS_POOR(cqi) (cqi < 50) //(((cqi) >= 5) && ((cqi) < 20))
+#define CQI_IS_BAD(cqi) (cqi < 5)
+#define CQI_IS_DEAD(cqi) (cqi == 0)
+
+// weighting factor to calculate Channel quality, total should be 100%
+#define RSSI_WEIGHTING 50
+#define TX_WEIGHTING 30
+#define RX_WEIGHTING 20
+
+//#define PEER_KEY_NOT_USED 0
+//#define PEER_KEY_64_BIT 64
+//#define PEER_KEY_128_BIT 128
+
+//#define PEER_KEY_64BIT_LEN 8
+//#define PEER_KEY_128BIT_LEN 16
+
+#define BSS_NOT_FOUND 0xFFFFFFFF
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define MAX_LEN_OF_MLME_QUEUE 40 //10
+#endif // CONFIG_STA_SUPPORT //
+
+#define SCAN_PASSIVE 18 // scan with no probe request, only wait beacon and probe response
+#define SCAN_ACTIVE 19 // scan with probe request, and wait beacon and probe response
+#define SCAN_CISCO_PASSIVE 20 // Single channel passive scan
+#define SCAN_CISCO_ACTIVE 21 // Single channel active scan
+#define SCAN_CISCO_NOISE 22 // Single channel passive scan for noise histogram collection
+#define SCAN_CISCO_CHANNEL_LOAD 23 // Single channel passive scan for channel load collection
+#define FAST_SCAN_ACTIVE 24 // scan with probe request, and wait beacon and probe response
+
+#ifdef DOT11N_DRAFT3
+#define SCAN_2040_BSS_COEXIST 26
+#endif // DOT11N_DRAFT3 //
+
+//#define BSS_TABLE_EMPTY(x) ((x).BssNr == 0)
+#define MAC_ADDR_IS_GROUP(Addr) (((Addr[0]) & 0x01))
+#define MAC_ADDR_HASH(Addr) (Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define MAC_ADDR_HASH_INDEX(Addr) (MAC_ADDR_HASH(Addr) % HASH_TABLE_SIZE)
+#define TID_MAC_HASH(Addr,TID) (TID^Addr[0] ^ Addr[1] ^ Addr[2] ^ Addr[3] ^ Addr[4] ^ Addr[5])
+#define TID_MAC_HASH_INDEX(Addr,TID) (TID_MAC_HASH(Addr,TID) % HASH_TABLE_SIZE)
+
+// LED Control
+// assoiation ON. one LED ON. another blinking when TX, OFF when idle
+// no association, both LED off
+#define ASIC_LED_ACT_ON(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46)
+#define ASIC_LED_ACT_OFF(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46)
+
+// bit definition of the 2-byte pBEACON->Capability field
+#define CAP_IS_ESS_ON(x) (((x) & 0x0001) != 0)
+#define CAP_IS_IBSS_ON(x) (((x) & 0x0002) != 0)
+#define CAP_IS_CF_POLLABLE_ON(x) (((x) & 0x0004) != 0)
+#define CAP_IS_CF_POLL_REQ_ON(x) (((x) & 0x0008) != 0)
+#define CAP_IS_PRIVACY_ON(x) (((x) & 0x0010) != 0)
+#define CAP_IS_SHORT_PREAMBLE_ON(x) (((x) & 0x0020) != 0)
+#define CAP_IS_PBCC_ON(x) (((x) & 0x0040) != 0)
+#define CAP_IS_AGILITY_ON(x) (((x) & 0x0080) != 0)
+#define CAP_IS_SPECTRUM_MGMT(x) (((x) & 0x0100) != 0) // 802.11e d9
+#define CAP_IS_QOS(x) (((x) & 0x0200) != 0) // 802.11e d9
+#define CAP_IS_SHORT_SLOT(x) (((x) & 0x0400) != 0)
+#define CAP_IS_APSD(x) (((x) & 0x0800) != 0) // 802.11e d9
+#define CAP_IS_IMMED_BA(x) (((x) & 0x1000) != 0) // 802.11e d9
+#define CAP_IS_DSSS_OFDM(x) (((x) & 0x2000) != 0)
+#define CAP_IS_DELAY_BA(x) (((x) & 0x4000) != 0) // 802.11e d9
+
+#define CAP_GENERATE(ess,ibss,priv,s_pre,s_slot,spectrum) (((ess) ? 0x0001 : 0x0000) | ((ibss) ? 0x0002 : 0x0000) | ((priv) ? 0x0010 : 0x0000) | ((s_pre) ? 0x0020 : 0x0000) | ((s_slot) ? 0x0400 : 0x0000) | ((spectrum) ? 0x0100 : 0x0000))
+
+//#define STA_QOS_CAPABILITY 0 // 1-byte. see 802.11e d9.0 for bit definition
+
+#define ERP_IS_NON_ERP_PRESENT(x) (((x) & 0x01) != 0) // 802.11g
+#define ERP_IS_USE_PROTECTION(x) (((x) & 0x02) != 0) // 802.11g
+#define ERP_IS_USE_BARKER_PREAMBLE(x) (((x) & 0x04) != 0) // 802.11g
+
+#define DRS_TX_QUALITY_WORST_BOUND 8// 3 // just test by gary
+#define DRS_PENALTY 8
+
+#define BA_NOTUSE 2
+//BA Policy subfiled value in ADDBA frame
+#define IMMED_BA 1
+#define DELAY_BA 0
+
+// BA Initiator subfield in DELBA frame
+#define ORIGINATOR 1
+#define RECIPIENT 0
+
+// ADDBA Status Code
+#define ADDBA_RESULTCODE_SUCCESS 0
+#define ADDBA_RESULTCODE_REFUSED 37
+#define ADDBA_RESULTCODE_INVALID_PARAMETERS 38
+
+// DELBA Reason Code
+#define DELBA_REASONCODE_QSTA_LEAVING 36
+#define DELBA_REASONCODE_END_BA 37
+#define DELBA_REASONCODE_UNKNOWN_BA 38
+#define DELBA_REASONCODE_TIMEOUT 39
+
+// reset all OneSecTx counters
+#define RESET_ONE_SEC_TX_CNT(__pEntry) \
+if (((__pEntry)) != NULL) \
+{ \
+ (__pEntry)->OneSecTxRetryOkCount = 0; \
+ (__pEntry)->OneSecTxFailCount = 0; \
+ (__pEntry)->OneSecTxNoRetryOkCount = 0; \
+}
+
+//
+// 802.11 frame formats
+//
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT LSIGTxopProSup:1;
+ USHORT Forty_Mhz_Intolerant:1;
+ USHORT PSMP:1;
+ USHORT CCKmodein40:1;
+ USHORT AMsduSize:1;
+ USHORT DelayedBA:1; //rt2860c not support
+ USHORT RxSTBC:2;
+ USHORT TxSTBC:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT ShortGIfor20:1;
+ USHORT GF:1; //green field
+ USHORT MimoPs:2;//momi power safe
+ USHORT ChannelWidth:1;
+ USHORT AdvCoding:1;
+#else
+ USHORT AdvCoding:1;
+ USHORT ChannelWidth:1;
+ USHORT MimoPs:2;//momi power safe
+ USHORT GF:1; //green field
+ USHORT ShortGIfor20:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT TxSTBC:1;
+ USHORT RxSTBC:2;
+ USHORT DelayedBA:1; //rt2860c not support
+ USHORT AMsduSize:1; // only support as zero
+ USHORT CCKmodein40:1;
+ USHORT PSMP:1;
+ USHORT Forty_Mhz_Intolerant:1;
+ USHORT LSIGTxopProSup:1;
+#endif /* !RT_BIG_ENDIAN */
+} HT_CAP_INFO, *PHT_CAP_INFO;
+
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv:3;//momi power safe
+ UCHAR MpduDensity:3;
+ UCHAR MaxRAmpduFactor:2;
+#else
+ UCHAR MaxRAmpduFactor:2;
+ UCHAR MpduDensity:3;
+ UCHAR rsv:3;//momi power safe
+#endif /* !RT_BIG_ENDIAN */
+} HT_CAP_PARM, *PHT_CAP_PARM;
+
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+ UCHAR MCSSet[10];
+ UCHAR SupRate[2]; // unit : 1Mbps
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv:3;
+ UCHAR MpduDensity:1;
+ UCHAR TxStream:2;
+ UCHAR TxRxNotEqual:1;
+ UCHAR TxMCSSetDefined:1;
+#else
+ UCHAR TxMCSSetDefined:1;
+ UCHAR TxRxNotEqual:1;
+ UCHAR TxStream:2;
+ UCHAR MpduDensity:1;
+ UCHAR rsv:3;
+#endif // RT_BIG_ENDIAN //
+ UCHAR rsv3[3];
+} HT_MCS_SET, *PHT_MCS_SET;
+
+// HT Capability INFO field in HT Cap IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv2:4;
+ USHORT RDGSupport:1; //reverse Direction Grant support
+ USHORT PlusHTC:1; //+HTC control field support
+ USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
+ USHORT rsv:5;//momi power safe
+ USHORT TranTime:2;
+ USHORT Pco:1;
+#else
+ USHORT Pco:1;
+ USHORT TranTime:2;
+ USHORT rsv:5;//momi power safe
+ USHORT MCSFeedback:2; //0:no MCS feedback, 2:unsolicited MCS feedback, 3:Full MCS feedback, 1:rsv.
+ USHORT PlusHTC:1; //+HTC control field support
+ USHORT RDGSupport:1; //reverse Direction Grant support
+ USHORT rsv2:4;
+#endif /* RT_BIG_ENDIAN */
+} EXT_HT_CAP_INFO, *PEXT_HT_CAP_INFO;
+
+// HT Beamforming field in HT Cap IE .
+typedef struct PACKED _HT_BF_CAP{
+#ifdef RT_BIG_ENDIAN
+ ULONG rsv:3;
+ ULONG ChanEstimation:2;
+ ULONG CSIRowBFSup:2;
+ ULONG ComSteerBFAntSup:2;
+ ULONG NoComSteerBFAntSup:2;
+ ULONG CSIBFAntSup:2;
+ ULONG MinGrouping:2;
+ ULONG ExpComBF:2;
+ ULONG ExpNoComBF:2;
+ ULONG ExpCSIFbk:2;
+ ULONG ExpComSteerCapable:1;
+ ULONG ExpNoComSteerCapable:1;
+ ULONG ExpCSICapable:1;
+ ULONG Calibration:2;
+ ULONG ImpTxBFCapable:1;
+ ULONG TxNDPCapable:1;
+ ULONG RxNDPCapable:1;
+ ULONG TxSoundCapable:1;
+ ULONG RxSoundCapable:1;
+ ULONG TxBFRecCapable:1;
+#else
+ ULONG TxBFRecCapable:1;
+ ULONG RxSoundCapable:1;
+ ULONG TxSoundCapable:1;
+ ULONG RxNDPCapable:1;
+ ULONG TxNDPCapable:1;
+ ULONG ImpTxBFCapable:1;
+ ULONG Calibration:2;
+ ULONG ExpCSICapable:1;
+ ULONG ExpNoComSteerCapable:1;
+ ULONG ExpComSteerCapable:1;
+ ULONG ExpCSIFbk:2;
+ ULONG ExpNoComBF:2;
+ ULONG ExpComBF:2;
+ ULONG MinGrouping:2;
+ ULONG CSIBFAntSup:2;
+ ULONG NoComSteerBFAntSup:2;
+ ULONG ComSteerBFAntSup:2;
+ ULONG CSIRowBFSup:2;
+ ULONG ChanEstimation:2;
+ ULONG rsv:3;
+#endif // RT_BIG_ENDIAN //
+} HT_BF_CAP, *PHT_BF_CAP;
+
+// HT antenna selection field in HT Cap IE .
+typedef struct PACKED _HT_AS_CAP{
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv:1;
+ UCHAR TxSoundPPDU:1;
+ UCHAR RxASel:1;
+ UCHAR AntIndFbk:1;
+ UCHAR ExpCSIFbk:1;
+ UCHAR AntIndFbkTxASEL:1;
+ UCHAR ExpCSIFbkTxASEL:1;
+ UCHAR AntSelect:1;
+#else
+ UCHAR AntSelect:1;
+ UCHAR ExpCSIFbkTxASEL:1;
+ UCHAR AntIndFbkTxASEL:1;
+ UCHAR ExpCSIFbk:1;
+ UCHAR AntIndFbk:1;
+ UCHAR RxASel:1;
+ UCHAR TxSoundPPDU:1;
+ UCHAR rsv:1;
+#endif // RT_BIG_ENDIAN //
+} HT_AS_CAP, *PHT_AS_CAP;
+
+// Draft 1.0 set IE length 26, but is extensible..
+#define SIZE_HT_CAP_IE 26
+// The structure for HT Capability IE.
+typedef struct PACKED _HT_CAPABILITY_IE{
+ HT_CAP_INFO HtCapInfo;
+ HT_CAP_PARM HtCapParm;
+// HT_MCS_SET HtMCSSet;
+ UCHAR MCSSet[16];
+ EXT_HT_CAP_INFO ExtHtCapInfo;
+ HT_BF_CAP TxBFCap; // beamforming cap. rt2860c not support beamforming.
+ HT_AS_CAP ASCap; //antenna selection.
+} HT_CAPABILITY_IE, *PHT_CAPABILITY_IE;
+
+
+// 802.11n draft3 related structure definitions.
+// 7.3.2.60
+#define dot11OBSSScanPassiveDwell 20 // in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan.
+#define dot11OBSSScanActiveDwell 10 // in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan.
+#define dot11BSSWidthTriggerScanInterval 300 // in sec. max interval between scan operations to be performed to detect BSS channel width trigger events.
+#define dot11OBSSScanPassiveTotalPerChannel 200 // in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan.
+#define dot11OBSSScanActiveTotalPerChannel 20 //in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan
+#define dot11BSSWidthChannelTransactionDelayFactor 5 // min ratio between the delay time in performing a switch from 20MHz BSS to 20/40 BSS operation and the maxima
+ // interval between overlapping BSS scan operations.
+#define dot11BSSScanActivityThreshold 25 // in %%, max total time that a STA may be active on the medium during a period of
+ // (dot11BSSWidthChannelTransactionDelayFactor * dot11BSSWidthTriggerScanInterval) seconds without
+ // being obligated to perform OBSS Scan operations. default is 25(== 0.25%)
+
+typedef struct PACKED _OVERLAP_BSS_SCAN_IE{
+ USHORT ScanPassiveDwell;
+ USHORT ScanActiveDwell;
+ USHORT TriggerScanInt; // Trigger scan interval
+ USHORT PassiveTalPerChannel; // passive total per channel
+ USHORT ActiveTalPerChannel; // active total per channel
+ USHORT DelayFactor; // BSS width channel transition delay factor
+ USHORT ScanActThre; // Scan Activity threshold
+}OVERLAP_BSS_SCAN_IE, *POVERLAP_BSS_SCAN_IE;
+
+
+// 7.3.2.56. 20/40 Coexistence element used in Element ID = 72 = IE_2040_BSS_COEXIST
+typedef union PACKED _BSS_2040_COEXIST_IE{
+ struct PACKED {
+ #ifdef RT_BIG_ENDIAN
+ UCHAR rsv:5;
+ UCHAR BSS20WidthReq:1;
+ UCHAR Intolerant40:1;
+ UCHAR InfoReq:1;
+ #else
+ UCHAR InfoReq:1;
+ UCHAR Intolerant40:1; // Inter-BSS. set 1 when prohibits a receiving BSS from operating as a 20/40 Mhz BSS.
+ UCHAR BSS20WidthReq:1; // Intra-BSS set 1 when prohibits a receiving AP from operating its BSS as a 20/40MHz BSS.
+ UCHAR rsv:5;
+#endif // RT_BIG_ENDIAN //
+ } field;
+ UCHAR word;
+} BSS_2040_COEXIST_IE, *PBSS_2040_COEXIST_IE;
+
+
+typedef struct _TRIGGER_EVENTA{
+ BOOLEAN bValid;
+ UCHAR BSSID[6];
+ UCHAR RegClass; // Regulatory Class
+ USHORT Channel;
+ ULONG CDCounter; // Maintain a seperate count down counter for each Event A.
+} TRIGGER_EVENTA, *PTRIGGER_EVENTA;
+
+// 20/40 trigger event table
+// If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP.
+#define MAX_TRIGGER_EVENT 64
+typedef struct _TRIGGER_EVENT_TAB{
+ UCHAR EventANo;
+ TRIGGER_EVENTA EventA[MAX_TRIGGER_EVENT];
+ ULONG EventBCountDown; // Count down counter for Event B.
+} TRIGGER_EVENT_TAB, *PTRIGGER_EVENT_TAB;
+
+// 7.3.27 20/40 Bss Coexistence Mgmt capability used in extended capabilities information IE( ID = 127 = IE_EXT_CAPABILITY).
+// This is the first octet and was defined in 802.11n D3.03 and 802.11yD9.0
+typedef struct PACKED _EXT_CAP_INFO_ELEMENT{
+#ifdef RT_BIG_ENDIAN
+ UCHAR rsv2:5;
+ UCHAR ExtendChannelSwitch:1;
+ UCHAR rsv:1;
+ UCHAR BssCoexistMgmtSupport:1;
+#else
+ UCHAR BssCoexistMgmtSupport:1;
+ UCHAR rsv:1;
+ UCHAR ExtendChannelSwitch:1;
+ UCHAR rsv2:5;
+#endif // RT_BIG_ENDIAN //
+}EXT_CAP_INFO_ELEMENT, *PEXT_CAP_INFO_ELEMENT;
+
+
+// 802.11n 7.3.2.61
+typedef struct PACKED _BSS_2040_COEXIST_ELEMENT{
+ UCHAR ElementID; // ID = IE_2040_BSS_COEXIST = 72
+ UCHAR Len;
+ BSS_2040_COEXIST_IE BssCoexistIe;
+}BSS_2040_COEXIST_ELEMENT, *PBSS_2040_COEXIST_ELEMENT;
+
+
+//802.11n 7.3.2.59
+typedef struct PACKED _BSS_2040_INTOLERANT_CH_REPORT{
+ UCHAR ElementID; // ID = IE_2040_BSS_INTOLERANT_REPORT = 73
+ UCHAR Len;
+ UCHAR RegulatoryClass;
+ UCHAR ChList[0];
+}BSS_2040_INTOLERANT_CH_REPORT, *PBSS_2040_INTOLERANT_CH_REPORT;
+
+
+// The structure for channel switch annoucement IE. This is in 802.11n D3.03
+typedef struct PACKED _CHA_SWITCH_ANNOUNCE_IE{
+ UCHAR SwitchMode; //channel switch mode
+ UCHAR NewChannel; //
+ UCHAR SwitchCount; //
+} CHA_SWITCH_ANNOUNCE_IE, *PCHA_SWITCH_ANNOUNCE_IE;
+
+
+// The structure for channel switch annoucement IE. This is in 802.11n D3.03
+typedef struct PACKED _SEC_CHA_OFFSET_IE{
+ UCHAR SecondaryChannelOffset; // 1: Secondary above, 3: Secondary below, 0: no Secondary
+} SEC_CHA_OFFSET_IE, *PSEC_CHA_OFFSET_IE;
+
+
+// This structure is extracted from struct RT_HT_CAPABILITY
+typedef struct {
+ BOOLEAN bHtEnable; // If we should use ht rate.
+ BOOLEAN bPreNHt; // If we should use ht rate.
+ //Substract from HT Capability IE
+ UCHAR MCSSet[16]; //only supoort MCS=0-15,32 ,
+} RT_HT_PHY_INFO, *PRT_HT_PHY_INFO;
+
+//This structure substracts ralink supports from all 802.11n-related features.
+//Features not listed here but contained in 802.11n spec are not supported in rt2860.
+typedef struct {
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv:5;
+ USHORT AmsduSize:1; // Max receiving A-MSDU size
+ USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
+ USHORT RxSTBC:2; // 2 bits
+ USHORT TxSTBC:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT ShortGIfor20:1;
+ USHORT GF:1; //green field
+ USHORT MimoPs:2;//mimo power safe MMPS_
+ USHORT ChannelWidth:1;
+#else
+ USHORT ChannelWidth:1;
+ USHORT MimoPs:2;//mimo power safe MMPS_
+ USHORT GF:1; //green field
+ USHORT ShortGIfor20:1;
+ USHORT ShortGIfor40:1; //for40MHz
+ USHORT TxSTBC:1;
+ USHORT RxSTBC:2; // 2 bits
+ USHORT AmsduEnable:1; // Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n
+ USHORT AmsduSize:1; // Max receiving A-MSDU size
+ USHORT rsv:5;
+#endif
+
+ //Substract from Addiont HT INFO IE
+#ifdef RT_BIG_ENDIAN
+ UCHAR RecomWidth:1;
+ UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
+ UCHAR MpduDensity:3;
+ UCHAR MaxRAmpduFactor:2;
+#else
+ UCHAR MaxRAmpduFactor:2;
+ UCHAR MpduDensity:3;
+ UCHAR ExtChanOffset:2; // Please not the difference with following UCHAR NewExtChannelOffset; from 802.11n
+ UCHAR RecomWidth:1;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv2:11;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv3:1;
+ USHORT NonGfPresent:1;
+ USHORT OperaionMode:2;
+#else
+ USHORT OperaionMode:2;
+ USHORT NonGfPresent:1;
+ USHORT rsv3:1;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv2:11;
+#endif
+
+ // New Extension Channel Offset IE
+ UCHAR NewExtChannelOffset;
+ // Extension Capability IE = 127
+ UCHAR BSSCoexist2040;
+} RT_HT_CAPABILITY, *PRT_HT_CAPABILITY;
+
+// field in Addtional HT Information IE .
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR SerInterGranu:3;
+ UCHAR S_PSMPSup:1;
+ UCHAR RifsMode:1;
+ UCHAR RecomWidth:1;
+ UCHAR ExtChanOffset:2;
+#else
+ UCHAR ExtChanOffset:2;
+ UCHAR RecomWidth:1;
+ UCHAR RifsMode:1;
+ UCHAR S_PSMPSup:1; //Indicate support for scheduled PSMP
+ UCHAR SerInterGranu:3; //service interval granularity
+#endif
+} ADD_HTINFO, *PADD_HTINFO;
+
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv2:11;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv:1;
+ USHORT NonGfPresent:1;
+ USHORT OperaionMode:2;
+#else
+ USHORT OperaionMode:2;
+ USHORT NonGfPresent:1;
+ USHORT rsv:1;
+ USHORT OBSS_NonHTExist:1;
+ USHORT rsv2:11;
+#endif
+} ADD_HTINFO2, *PADD_HTINFO2;
+
+
+// TODO: Need sync with spec about the definition of StbcMcs. In Draft 3.03, it's reserved.
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+ USHORT rsv:4;
+ USHORT PcoPhase:1;
+ USHORT PcoActive:1;
+ USHORT LsigTxopProt:1;
+ USHORT STBCBeacon:1;
+ USHORT DualCTSProtect:1;
+ USHORT DualBeacon:1;
+ USHORT StbcMcs:6;
+#else
+ USHORT StbcMcs:6;
+ USHORT DualBeacon:1;
+ USHORT DualCTSProtect:1;
+ USHORT STBCBeacon:1;
+ USHORT LsigTxopProt:1; // L-SIG TXOP protection full support
+ USHORT PcoActive:1;
+ USHORT PcoPhase:1;
+ USHORT rsv:4;
+#endif // RT_BIG_ENDIAN //
+} ADD_HTINFO3, *PADD_HTINFO3;
+
+#define SIZE_ADD_HT_INFO_IE 22
+typedef struct PACKED{
+ UCHAR ControlChan;
+ ADD_HTINFO AddHtInfo;
+ ADD_HTINFO2 AddHtInfo2;
+ ADD_HTINFO3 AddHtInfo3;
+ UCHAR MCSSet[16]; // Basic MCS set
+} ADD_HT_INFO_IE, *PADD_HT_INFO_IE;
+
+typedef struct PACKED{
+ UCHAR NewExtChanOffset;
+} NEW_EXT_CHAN_IE, *PNEW_EXT_CHAN_IE;
+
+
+// 4-byte HTC field. maybe included in any frame except non-QOS data frame. The Order bit must set 1.
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UINT32 RDG:1; //RDG / More PPDU
+ UINT32 ACConstraint:1; //feedback request
+ UINT32 rsv:5; //calibration sequence
+ UINT32 ZLFAnnouce:1; // ZLF announcement
+ UINT32 CSISTEERING:2; //CSI/ STEERING
+ UINT32 FBKReq:2; //feedback request
+ UINT32 CalSeq:2; //calibration sequence
+ UINT32 CalPos:2; // calibration position
+ UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
+ UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
+ UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
+ UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
+ UINT32 TRQ:1; //sounding request
+ UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
+#else
+ UINT32 MA:1; //management action payload exist in (QoS Null+HTC)
+ UINT32 TRQ:1; //sounding request
+ UINT32 MRQ:1; //MCS feedback. Request for a MCS feedback
+ UINT32 MRSorASI:3; // MRQ Sequence identifier. unchanged during entire procedure. 0x000-0x110.
+ UINT32 MFS:3; //SET to the received value of MRS. 0x111 for unsolicited MFB.
+ UINT32 MFBorASC:7; //Link adaptation feedback containing recommended MCS. 0x7f for no feedback or not available
+ UINT32 CalPos:2; // calibration position
+ UINT32 CalSeq:2; //calibration sequence
+ UINT32 FBKReq:2; //feedback request
+ UINT32 CSISTEERING:2; //CSI/ STEERING
+ UINT32 ZLFAnnouce:1; // ZLF announcement
+ UINT32 rsv:5; //calibration sequence
+ UINT32 ACConstraint:1; //feedback request
+ UINT32 RDG:1; //RDG / More PPDU
+#endif /* !RT_BIG_ENDIAN */
+} HT_CONTROL, *PHT_CONTROL;
+
+// 2-byte QOS CONTROL field
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT Txop_QueueSize:8;
+ USHORT AMsduPresent:1;
+ USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
+ USHORT EOSP:1;
+ USHORT TID:4;
+#else
+ USHORT TID:4;
+ USHORT EOSP:1;
+ USHORT AckPolicy:2; //0: normal ACK 1:No ACK 2:scheduled under MTBA/PSMP 3: BA
+ USHORT AMsduPresent:1;
+ USHORT Txop_QueueSize:8;
+#endif /* !RT_BIG_ENDIAN */
+} QOS_CONTROL, *PQOS_CONTROL;
+
+// 2-byte Frame control field
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT Order:1; // Strict order expected
+ USHORT Wep:1; // Wep data
+ USHORT MoreData:1; // More data bit
+ USHORT PwrMgmt:1; // Power management bit
+ USHORT Retry:1; // Retry status bit
+ USHORT MoreFrag:1; // More fragment bit
+ USHORT FrDs:1; // From DS indication
+ USHORT ToDs:1; // To DS indication
+ USHORT SubType:4; // MSDU subtype
+ USHORT Type:2; // MSDU type
+ USHORT Ver:2; // Protocol version
+#else
+ USHORT Ver:2; // Protocol version
+ USHORT Type:2; // MSDU type
+ USHORT SubType:4; // MSDU subtype
+ USHORT ToDs:1; // To DS indication
+ USHORT FrDs:1; // From DS indication
+ USHORT MoreFrag:1; // More fragment bit
+ USHORT Retry:1; // Retry status bit
+ USHORT PwrMgmt:1; // Power management bit
+ USHORT MoreData:1; // More data bit
+ USHORT Wep:1; // Wep data
+ USHORT Order:1; // Strict order expected
+#endif /* !RT_BIG_ENDIAN */
+} FRAME_CONTROL, *PFRAME_CONTROL;
+
+typedef struct PACKED _HEADER_802_11 {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR Addr3[MAC_ADDR_LEN];
+#ifdef RT_BIG_ENDIAN
+ USHORT Sequence:12;
+ USHORT Frag:4;
+#else
+ USHORT Frag:4;
+ USHORT Sequence:12;
+#endif /* !RT_BIG_ENDIAN */
+ UCHAR Octet[0];
+} HEADER_802_11, *PHEADER_802_11;
+
+typedef struct PACKED _FRAME_802_11 {
+ HEADER_802_11 Hdr;
+ UCHAR Octet[1];
+} FRAME_802_11, *PFRAME_802_11;
+
+// QoSNull embedding of management action. When HT Control MA field set to 1.
+typedef struct PACKED _MA_BODY {
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Octet[1];
+} MA_BODY, *PMA_BODY;
+
+typedef struct PACKED _HEADER_802_3 {
+ UCHAR DAAddr1[MAC_ADDR_LEN];
+ UCHAR SAAddr2[MAC_ADDR_LEN];
+ UCHAR Octet[2];
+} HEADER_802_3, *PHEADER_802_3;
+////Block ACK related format
+// 2-byte BA Parameter field in DELBA frames to terminate an already set up bA
+typedef struct PACKED{
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4; // value of TC os TS
+ USHORT Initiator:1; // 1: originator 0:recipient
+ USHORT Rsv:11; // always set to 0
+#else
+ USHORT Rsv:11; // always set to 0
+ USHORT Initiator:1; // 1: originator 0:recipient
+ USHORT TID:4; // value of TC os TS
+#endif /* !RT_BIG_ENDIAN */
+} DELBA_PARM, *PDELBA_PARM;
+
+// 2-byte BA Parameter Set field in ADDBA frames to signal parm for setting up a BA
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT BufSize:10; // number of buffe of size 2304 octetsr
+ USHORT TID:4; // value of TC os TS
+ USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
+ USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
+#else
+ USHORT AMSDUSupported:1; // 0: not permitted 1: permitted
+ USHORT BAPolicy:1; // 1: immediately BA 0:delayed BA
+ USHORT TID:4; // value of TC os TS
+ USHORT BufSize:10; // number of buffe of size 2304 octetsr
+#endif /* !RT_BIG_ENDIAN */
+} BA_PARM, *PBA_PARM;
+
+// 2-byte BA Starting Seq CONTROL field
+typedef union PACKED {
+ struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
+ USHORT FragNum:4; // always set to 0
+#else
+ USHORT FragNum:4; // always set to 0
+ USHORT StartSeq:12; // sequence number of the 1st MSDU for which this BAR is sent
+#endif /* RT_BIG_ENDIAN */
+ } field;
+ USHORT word;
+} BASEQ_CONTROL, *PBASEQ_CONTROL;
+
+//BAControl and BARControl are the same
+// 2-byte BA CONTROL field in BA frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4;
+ USHORT Rsv:9;
+ USHORT Compressed:1;
+ USHORT MTID:1; //EWC V1.24
+ USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
+#else
+ USHORT ACKPolicy:1; // only related to N-Delayed BA. But not support in RT2860b. 0:NormalACK 1:No ACK
+ USHORT MTID:1; //EWC V1.24
+ USHORT Compressed:1;
+ USHORT Rsv:9;
+ USHORT TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} BA_CONTROL, *PBA_CONTROL;
+
+// 2-byte BAR CONTROL field in BAR frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4;
+ USHORT Rsv1:9;
+ USHORT Compressed:1;
+ USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
+ USHORT ACKPolicy:1;
+#else
+ USHORT ACKPolicy:1; // 0:normal ack, 1:no ack.
+ USHORT MTID:1; //if this bit1, use FRAME_MTBA_REQ, if 0, use FRAME_BA_REQ
+ USHORT Compressed:1;
+ USHORT Rsv1:9;
+ USHORT TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} BAR_CONTROL, *PBAR_CONTROL;
+
+// BARControl in MTBAR frame
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT NumTID:4;
+ USHORT Rsv1:9;
+ USHORT Compressed:1;
+ USHORT MTID:1;
+ USHORT ACKPolicy:1;
+#else
+ USHORT ACKPolicy:1;
+ USHORT MTID:1;
+ USHORT Compressed:1;
+ USHORT Rsv1:9;
+ USHORT NumTID:4;
+#endif /* !RT_BIG_ENDIAN */
+} MTBAR_CONTROL, *PMTBAR_CONTROL;
+
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT TID:4;
+ USHORT Rsv1:12;
+#else
+ USHORT Rsv1:12;
+ USHORT TID:4;
+#endif /* !RT_BIG_ENDIAN */
+} PER_TID_INFO, *PPER_TID_INFO;
+
+typedef struct {
+ PER_TID_INFO PerTID;
+ BASEQ_CONTROL BAStartingSeq;
+} EACH_TID, *PEACH_TID;
+
+
+typedef struct PACKED _PSPOLL_FRAME {
+ FRAME_CONTROL FC;
+ USHORT Aid;
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR Ta[MAC_ADDR_LEN];
+} PSPOLL_FRAME, *PPSPOLL_FRAME;
+
+typedef struct PACKED _RTS_FRAME {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+}RTS_FRAME, *PRTS_FRAME;
+
+// BAREQ AND MTBAREQ have the same subtype BAR, 802.11n BAR use compressed bitmap.
+typedef struct PACKED _FRAME_BA_REQ {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BAR_CONTROL BARControl;
+ BASEQ_CONTROL BAStartingSeq;
+} FRAME_BA_REQ, *PFRAME_BA_REQ;
+
+typedef struct PACKED _FRAME_MTBA_REQ {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ MTBAR_CONTROL MTBARControl;
+ PER_TID_INFO PerTIDInfo;
+ BASEQ_CONTROL BAStartingSeq;
+} FRAME_MTBA_REQ, *PFRAME_MTBA_REQ;
+
+// Compressed format is mandantory in HT STA
+typedef struct PACKED _FRAME_MTBA {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BA_CONTROL BAControl;
+ BASEQ_CONTROL BAStartingSeq;
+ UCHAR BitMap[8];
+} FRAME_MTBA, *PFRAME_MTBA;
+
+typedef struct PACKED _FRAME_PSMP_ACTION {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Psmp; // 7.3.1.25
+} FRAME_PSMP_ACTION, *PFRAME_PSMP_ACTION;
+
+typedef struct PACKED _FRAME_ACTION_HDR {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+} FRAME_ACTION_HDR, *PFRAME_ACTION_HDR;
+
+//Action Frame
+//Action Frame Category:Spectrum, Action:Channel Switch. 7.3.2.20
+typedef struct PACKED _CHAN_SWITCH_ANNOUNCE {
+ UCHAR ElementID; // ID = IE_CHANNEL_SWITCH_ANNOUNCEMENT = 37
+ UCHAR Len;
+ CHA_SWITCH_ANNOUNCE_IE CSAnnounceIe;
+} CHAN_SWITCH_ANNOUNCE, *PCHAN_SWITCH_ANNOUNCE;
+
+
+//802.11n : 7.3.2.20a
+typedef struct PACKED _SECOND_CHAN_OFFSET {
+ UCHAR ElementID; // ID = IE_SECONDARY_CH_OFFSET = 62
+ UCHAR Len;
+ SEC_CHA_OFFSET_IE SecChOffsetIe;
+} SECOND_CHAN_OFFSET, *PSECOND_CHAN_OFFSET;
+
+
+typedef struct PACKED _FRAME_SPETRUM_CS {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ CHAN_SWITCH_ANNOUNCE CSAnnounce;
+ SECOND_CHAN_OFFSET SecondChannel;
+} FRAME_SPETRUM_CS, *PFRAME_SPETRUM_CS;
+
+
+typedef struct PACKED _FRAME_ADDBA_REQ {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Token; // 1
+ BA_PARM BaParm; // 2 - 10
+ USHORT TimeOutValue; // 0 - 0
+ BASEQ_CONTROL BaStartSeq; // 0-0
+} FRAME_ADDBA_REQ, *PFRAME_ADDBA_REQ;
+
+typedef struct PACKED _FRAME_ADDBA_RSP {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Token;
+ USHORT StatusCode;
+ BA_PARM BaParm; //0 - 2
+ USHORT TimeOutValue;
+} FRAME_ADDBA_RSP, *PFRAME_ADDBA_RSP;
+
+typedef struct PACKED _FRAME_DELBA_REQ {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ DELBA_PARM DelbaParm;
+ USHORT ReasonCode;
+} FRAME_DELBA_REQ, *PFRAME_DELBA_REQ;
+
+
+//7.2.1.7
+typedef struct PACKED _FRAME_BAR {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BAR_CONTROL BarControl;
+ BASEQ_CONTROL StartingSeq;
+} FRAME_BAR, *PFRAME_BAR;
+
+//7.2.1.7
+typedef struct PACKED _FRAME_BA {
+ FRAME_CONTROL FC;
+ USHORT Duration;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BAR_CONTROL BarControl;
+ BASEQ_CONTROL StartingSeq;
+ UCHAR bitmask[8];
+} FRAME_BA, *PFRAME_BA;
+
+
+// Radio Measuement Request Frame Format
+typedef struct PACKED _FRAME_RM_REQ_ACTION {
+ HEADER_802_11 Hdr;
+ UCHAR Category;
+ UCHAR Action;
+ UCHAR Token;
+ USHORT Repetition;
+ UCHAR data[0];
+} FRAME_RM_REQ_ACTION, *PFRAME_RM_REQ_ACTION;
+
+typedef struct PACKED {
+ UCHAR ID;
+ UCHAR Length;
+ UCHAR ChannelSwitchMode;
+ UCHAR NewRegClass;
+ UCHAR NewChannelNum;
+ UCHAR ChannelSwitchCount;
+} HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE, *PHT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE;
+
+
+//
+// _Limit must be the 2**n - 1
+// _SEQ1 , _SEQ2 must be within 0 ~ _Limit
+//
+#define SEQ_STEPONE(_SEQ1, _SEQ2, _Limit) ((_SEQ1 == ((_SEQ2+1) & _Limit)))
+#define SEQ_SMALLER(_SEQ1, _SEQ2, _Limit) (((_SEQ1-_SEQ2) & ((_Limit+1)>>1)))
+#define SEQ_LARGER(_SEQ1, _SEQ2, _Limit) ((_SEQ1 != _SEQ2) && !(((_SEQ1-_SEQ2) & ((_Limit+1)>>1))))
+#define SEQ_WITHIN_WIN(_SEQ1, _SEQ2, _WIN, _Limit) (SEQ_LARGER(_SEQ1, _SEQ2, _Limit) && \
+ SEQ_SMALLER(_SEQ1, ((_SEQ2+_WIN+1)&_Limit), _Limit))
+
+//
+// Contention-free parameter (without ID and Length)
+//
+typedef struct PACKED {
+ BOOLEAN bValid; // 1: variable contains valid value
+ UCHAR CfpCount;
+ UCHAR CfpPeriod;
+ USHORT CfpMaxDuration;
+ USHORT CfpDurRemaining;
+} CF_PARM, *PCF_PARM;
+
+typedef struct _CIPHER_SUITE {
+ NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher 1, this one has more secured cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS PairCipherAux; // Unicast cipher 2 if AP announce two unicast cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Group cipher
+ USHORT RsnCapability; // RSN capability from beacon
+ BOOLEAN bMixMode; // Indicate Pair & Group cipher might be different
+} CIPHER_SUITE, *PCIPHER_SUITE;
+
+// EDCA configuration from AP's BEACON/ProbeRsp
+typedef struct {
+ BOOLEAN bValid; // 1: variable contains valid value
+ BOOLEAN bAdd; // 1: variable contains valid value
+ BOOLEAN bQAck;
+ BOOLEAN bQueueRequest;
+ BOOLEAN bTxopRequest;
+ BOOLEAN bAPSDCapable;
+// BOOLEAN bMoreDataAck;
+ UCHAR EdcaUpdateCount;
+ UCHAR Aifsn[4]; // 0:AC_BK, 1:AC_BE, 2:AC_VI, 3:AC_VO
+ UCHAR Cwmin[4];
+ UCHAR Cwmax[4];
+ USHORT Txop[4]; // in unit of 32-us
+ BOOLEAN bACM[4]; // 1: Admission Control of AC_BK is mandattory
+} EDCA_PARM, *PEDCA_PARM;
+
+// QBSS LOAD information from QAP's BEACON/ProbeRsp
+typedef struct {
+ BOOLEAN bValid; // 1: variable contains valid value
+ USHORT StaNum;
+ UCHAR ChannelUtilization;
+ USHORT RemainingAdmissionControl; // in unit of 32-us
+} QBSS_LOAD_PARM, *PQBSS_LOAD_PARM;
+
+// QBSS Info field in QSTA's assoc req
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR Rsv2:1;
+ UCHAR MaxSPLength:2;
+ UCHAR Rsv1:1;
+ UCHAR UAPSD_AC_BE:1;
+ UCHAR UAPSD_AC_BK:1;
+ UCHAR UAPSD_AC_VI:1;
+ UCHAR UAPSD_AC_VO:1;
+#else
+ UCHAR UAPSD_AC_VO:1;
+ UCHAR UAPSD_AC_VI:1;
+ UCHAR UAPSD_AC_BK:1;
+ UCHAR UAPSD_AC_BE:1;
+ UCHAR Rsv1:1;
+ UCHAR MaxSPLength:2;
+ UCHAR Rsv2:1;
+#endif /* !RT_BIG_ENDIAN */
+} QBSS_STA_INFO_PARM, *PQBSS_STA_INFO_PARM;
+
+// QBSS Info field in QAP's Beacon/ProbeRsp
+typedef struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ UCHAR UAPSD:1;
+ UCHAR Rsv:3;
+ UCHAR ParamSetCount:4;
+#else
+ UCHAR ParamSetCount:4;
+ UCHAR Rsv:3;
+ UCHAR UAPSD:1;
+#endif /* !RT_BIG_ENDIAN */
+} QBSS_AP_INFO_PARM, *PQBSS_AP_INFO_PARM;
+
+// QOS Capability reported in QAP's BEACON/ProbeRsp
+// QOS Capability sent out in QSTA's AssociateReq/ReAssociateReq
+typedef struct {
+ BOOLEAN bValid; // 1: variable contains valid value
+ BOOLEAN bQAck;
+ BOOLEAN bQueueRequest;
+ BOOLEAN bTxopRequest;
+// BOOLEAN bMoreDataAck;
+ UCHAR EdcaUpdateCount;
+} QOS_CAPABILITY_PARM, *PQOS_CAPABILITY_PARM;
+
+#ifdef CONFIG_STA_SUPPORT
+typedef struct {
+ UCHAR IELen;
+ UCHAR IE[MAX_CUSTOM_LEN];
+} WPA_IE_;
+#endif // CONFIG_STA_SUPPORT //
+
+
+typedef struct {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR Channel;
+ UCHAR CentralChannel; //Store the wide-band central channel for 40MHz. .used in 40MHz AP. Or this is the same as Channel.
+ UCHAR BssType;
+ USHORT AtimWin;
+ USHORT BeaconPeriod;
+
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRateLen;
+ HT_CAPABILITY_IE HtCapability;
+ UCHAR HtCapabilityLen;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChanOffset;
+ CHAR Rssi;
+ UCHAR Privacy; // Indicate security function ON/OFF. Don't mess up with auth mode.
+ UCHAR Hidden;
+
+ USHORT DtimPeriod;
+ USHORT CapabilityInfo;
+
+ USHORT CfpCount;
+ USHORT CfpPeriod;
+ USHORT CfpMaxDuration;
+ USHORT CfpDurRemaining;
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+
+ ULONG LastBeaconRxTime; // OS's timestamp
+
+ BOOLEAN bSES;
+
+ // New for WPA2
+ CIPHER_SUITE WPA; // AP announced WPA cipher suite
+ CIPHER_SUITE WPA2; // AP announced WPA2 cipher suite
+
+ // New for microsoft WPA support
+ NDIS_802_11_FIXED_IEs FixIEs;
+ NDIS_802_11_AUTHENTICATION_MODE AuthModeAux; // Addition mode for WPA2 / WPA capable AP
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus; // Unicast Encryption Algorithm extract from VAR_IE
+ USHORT VarIELen; // Length of next VIE include EID & Length
+ UCHAR VarIEs[MAX_VIE_LEN];
+
+ // CCX Ckip information
+ UCHAR CkipFlag;
+
+ // CCX 2 TSF
+ UCHAR PTSF[4]; // Parent TSF
+ UCHAR TTSF[8]; // Target TSF
+
+ // 802.11e d9, and WMM
+ EDCA_PARM EdcaParm;
+ QOS_CAPABILITY_PARM QosCapability;
+ QBSS_LOAD_PARM QbssLoad;
+#ifdef CONFIG_STA_SUPPORT
+ WPA_IE_ WpaIE;
+ WPA_IE_ RsnIE;
+#ifdef EXT_BUILD_CHANNEL_LIST
+ UCHAR CountryString[3];
+ BOOLEAN bHasCountryIE;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+} BSS_ENTRY, *PBSS_ENTRY;
+
+typedef struct {
+ UCHAR BssNr;
+ UCHAR BssOverlapNr;
+ BSS_ENTRY BssEntry[MAX_LEN_OF_BSS_TABLE];
+} BSS_TABLE, *PBSS_TABLE;
+
+
+typedef struct _MLME_QUEUE_ELEM {
+ ULONG Machine;
+ ULONG MsgType;
+ ULONG MsgLen;
+ UCHAR Msg[MGMT_DMA_BUFFER_SIZE];
+ LARGE_INTEGER TimeStamp;
+ UCHAR Rssi0;
+ UCHAR Rssi1;
+ UCHAR Rssi2;
+ UCHAR Signal;
+ UCHAR Channel;
+ UCHAR Wcid;
+ BOOLEAN Occupied;
+#ifdef MLME_EX
+ USHORT Idx;
+#endif // MLME_EX //
+} MLME_QUEUE_ELEM, *PMLME_QUEUE_ELEM;
+
+typedef struct _MLME_QUEUE {
+ ULONG Num;
+ ULONG Head;
+ ULONG Tail;
+ NDIS_SPIN_LOCK Lock;
+ MLME_QUEUE_ELEM Entry[MAX_LEN_OF_MLME_QUEUE];
+} MLME_QUEUE, *PMLME_QUEUE;
+
+typedef VOID (*STATE_MACHINE_FUNC)(VOID *Adaptor, MLME_QUEUE_ELEM *Elem);
+
+typedef struct _STATE_MACHINE {
+ ULONG Base;
+ ULONG NrState;
+ ULONG NrMsg;
+ ULONG CurrState;
+ STATE_MACHINE_FUNC *TransFunc;
+} STATE_MACHINE, *PSTATE_MACHINE;
+
+
+// MLME AUX data structure that hold temporarliy settings during a connection attempt.
+// Once this attemp succeeds, all settings will be copy to pAd->StaActive.
+// A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of
+// several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely
+// separate this under-trial settings away from pAd->StaActive so that once
+// this new attempt failed, driver can auto-recover back to the active settings.
+typedef struct _MLME_AUX {
+ UCHAR BssType;
+ UCHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR AutoReconnectSsid[MAX_LEN_OF_SSID];
+ UCHAR AutoReconnectSsidLen;
+ USHORT Alg;
+ UCHAR ScanType;
+ UCHAR Channel;
+ UCHAR CentralChannel;
+ USHORT Aid;
+ USHORT CapabilityInfo;
+ USHORT BeaconPeriod;
+ USHORT CfpMaxDuration;
+ USHORT CfpPeriod;
+ USHORT AtimWin;
+
+ // Copy supported rate from desired AP's beacon. We are trying to match
+ // AP's supported and extended rate settings.
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRateLen;
+ HT_CAPABILITY_IE HtCapability;
+ UCHAR HtCapabilityLen;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR NewExtChannelOffset;
+ //RT_HT_CAPABILITY SupportedHtPhy;
+
+ // new for QOS
+ QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
+ EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
+ QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
+
+ // new to keep Ralink specific feature
+ ULONG APRalinkIe;
+
+ BSS_TABLE SsidBssTab; // AP list for the same SSID
+ BSS_TABLE RoamTab; // AP list eligible for roaming
+ ULONG BssIdx;
+ ULONG RoamIdx;
+
+ BOOLEAN CurrReqIsFromNdis;
+
+ RALINK_TIMER_STRUCT BeaconTimer, ScanTimer;
+ RALINK_TIMER_STRUCT AuthTimer;
+ RALINK_TIMER_STRUCT AssocTimer, ReassocTimer, DisassocTimer;
+} MLME_AUX, *PMLME_AUX;
+
+typedef struct _MLME_ADDBA_REQ_STRUCT{
+ UCHAR Wcid; //
+ UCHAR pAddr[MAC_ADDR_LEN];
+ UCHAR BaBufSize;
+ USHORT TimeOutValue;
+ UCHAR TID;
+ UCHAR Token;
+ USHORT BaStartSeq;
+} MLME_ADDBA_REQ_STRUCT, *PMLME_ADDBA_REQ_STRUCT;
+
+
+typedef struct _MLME_DELBA_REQ_STRUCT{
+ UCHAR Wcid; //
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR TID;
+ UCHAR Initiator;
+} MLME_DELBA_REQ_STRUCT, *PMLME_DELBA_REQ_STRUCT;
+
+// assoc struct is equal to reassoc
+typedef struct _MLME_ASSOC_REQ_STRUCT{
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT CapabilityInfo;
+ USHORT ListenIntv;
+ ULONG Timeout;
+} MLME_ASSOC_REQ_STRUCT, *PMLME_ASSOC_REQ_STRUCT, MLME_REASSOC_REQ_STRUCT, *PMLME_REASSOC_REQ_STRUCT;
+
+typedef struct _MLME_DISASSOC_REQ_STRUCT{
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Reason;
+} MLME_DISASSOC_REQ_STRUCT, *PMLME_DISASSOC_REQ_STRUCT;
+
+typedef struct _MLME_AUTH_REQ_STRUCT {
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Alg;
+ ULONG Timeout;
+} MLME_AUTH_REQ_STRUCT, *PMLME_AUTH_REQ_STRUCT;
+
+typedef struct _MLME_DEAUTH_REQ_STRUCT {
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Reason;
+} MLME_DEAUTH_REQ_STRUCT, *PMLME_DEAUTH_REQ_STRUCT;
+
+typedef struct {
+ ULONG BssIdx;
+} MLME_JOIN_REQ_STRUCT;
+
+typedef struct _MLME_SCAN_REQ_STRUCT {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR BssType;
+ UCHAR ScanType;
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+} MLME_SCAN_REQ_STRUCT, *PMLME_SCAN_REQ_STRUCT;
+
+typedef struct _MLME_START_REQ_STRUCT {
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+} MLME_START_REQ_STRUCT, *PMLME_START_REQ_STRUCT;
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+// structure for DLS
+typedef struct _RT_802_11_DLS {
+ USHORT TimeOut; // Use to time out while slience, unit: second , set by UI
+ USHORT CountDownTimer; // Use to time out while slience,unit: second , used by driver only
+ NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
+ UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
+ BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
+ RALINK_TIMER_STRUCT Timer; // Use to time out while handshake
+ USHORT Sequence;
+ USHORT MacTabMatchWCID; // ASIC
+ BOOLEAN bHTCap;
+ PVOID pAd;
+} RT_802_11_DLS, *PRT_802_11_DLS;
+
+typedef struct _MLME_DLS_REQ_STRUCT {
+ PRT_802_11_DLS pDLS;
+ USHORT Reason;
+} MLME_DLS_REQ_STRUCT, *PMLME_DLS_REQ_STRUCT;
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct PACKED {
+ UCHAR Eid;
+ UCHAR Len;
+ CHAR Octet[1];
+} EID_STRUCT,*PEID_STRUCT, BEACON_EID_STRUCT, *PBEACON_EID_STRUCT;
+
+typedef struct PACKED _RTMP_TX_RATE_SWITCH
+{
+ UCHAR ItemNo;
+#ifdef RT_BIG_ENDIAN
+ UCHAR Rsv2:2;
+ UCHAR Mode:2;
+ UCHAR Rsv1:1;
+ UCHAR BW:1;
+ UCHAR ShortGI:1;
+ UCHAR STBC:1;
+#else
+ UCHAR STBC:1;
+ UCHAR ShortGI:1;
+ UCHAR BW:1;
+ UCHAR Rsv1:1;
+ UCHAR Mode:2;
+ UCHAR Rsv2:2;
+#endif
+ UCHAR CurrMCS;
+ UCHAR TrainUp;
+ UCHAR TrainDown;
+} RRTMP_TX_RATE_SWITCH, *PRTMP_TX_RATE_SWITCH;
+
+// ========================== AP mlme.h ===============================
+#define TBTT_PRELOAD_TIME 384 // usec. LomgPreamble + 24-byte at 1Mbps
+#define DEFAULT_DTIM_PERIOD 1
+
+// weighting factor to calculate Channel quality, total should be 100%
+//#define RSSI_WEIGHTING 0
+//#define TX_WEIGHTING 40
+//#define RX_WEIGHTING 60
+
+#define MAC_TABLE_AGEOUT_TIME 300 // unit: sec
+#define MAC_TABLE_ASSOC_TIMEOUT 5 // unit: sec
+#define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE)
+
+// AP shall drop the sta if contine Tx fail count reach it.
+#define MAC_ENTRY_LIFE_CHECK_CNT 20 // packet cnt.
+
+// Value domain of pMacEntry->Sst
+typedef enum _Sst {
+ SST_NOT_AUTH, // 0: equivalent to IEEE 802.11/1999 state 1
+ SST_AUTH, // 1: equivalent to IEEE 802.11/1999 state 2
+ SST_ASSOC // 2: equivalent to IEEE 802.11/1999 state 3
+} SST;
+
+// value domain of pMacEntry->AuthState
+typedef enum _AuthState {
+ AS_NOT_AUTH,
+ AS_AUTH_OPEN, // STA has been authenticated using OPEN SYSTEM
+ AS_AUTH_KEY, // STA has been authenticated using SHARED KEY
+ AS_AUTHENTICATING // STA is waiting for AUTH seq#3 using SHARED KEY
+} AUTH_STATE;
+
+//for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
+typedef enum _ApWpaState {
+ AS_NOTUSE, // 0
+ AS_DISCONNECT, // 1
+ AS_DISCONNECTED, // 2
+ AS_INITIALIZE, // 3
+ AS_AUTHENTICATION, // 4
+ AS_AUTHENTICATION2, // 5
+ AS_INITPMK, // 6
+ AS_INITPSK, // 7
+ AS_PTKSTART, // 8
+ AS_PTKINIT_NEGOTIATING, // 9
+ AS_PTKINITDONE, // 10
+ AS_UPDATEKEYS, // 11
+ AS_INTEGRITY_FAILURE, // 12
+ AS_KEYUPDATE, // 13
+} AP_WPA_STATE;
+
+// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
+typedef enum _GTKState {
+ REKEY_NEGOTIATING,
+ REKEY_ESTABLISHED,
+ KEYERROR,
+} GTK_STATE;
+
+// for-wpa value domain of pMacEntry->WpaState 802.1i D3 p.114
+typedef enum _WpaGTKState {
+ SETKEYS,
+ SETKEYS_DONE,
+} WPA_GTK_STATE;
+// ====================== end of AP mlme.h ============================
+
+
+#endif // MLME_H__
diff --git a/drivers/staging/rt3070/netif_block.h b/drivers/staging/rt3070/netif_block.h
new file mode 100644
index 00000000000..6e5151c4109
--- /dev/null
+++ b/drivers/staging/rt3070/netif_block.h
@@ -0,0 +1,58 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __NET_IF_BLOCK_H__
+#define __NET_IF_BLOCK_H__
+
+//#include <linux/device.h>
+#include "link_list.h"
+#include "rtmp.h"
+
+#define FREE_NETIF_POOL_SIZE 32
+
+typedef struct _NETIF_ENTRY
+{
+ struct _NETIF_ENTRY *pNext;
+ PNET_DEV pNetDev;
+} NETIF_ENTRY, *PNETIF_ENTRY;
+
+void initblockQueueTab(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN blockNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry,
+ IN PNET_DEV pNetDev);
+
+VOID releaseNetIf(
+ IN PBLOCK_QUEUE_ENTRY pBlockQueueEntry);
+
+VOID StopNetIfQueue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+#endif // __NET_IF_BLOCK_H__
+
diff --git a/drivers/staging/rt3070/oid.h b/drivers/staging/rt3070/oid.h
new file mode 100644
index 00000000000..f78bf0a5f14
--- /dev/null
+++ b/drivers/staging/rt3070/oid.h
@@ -0,0 +1,1142 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ oid.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#ifndef _OID_H_
+#define _OID_H_
+
+//#include <linux/wireless.h>
+
+
+#define TRUE 1
+#define FALSE 0
+//
+// IEEE 802.11 Structures and definitions
+//
+#define MAX_TX_POWER_LEVEL 100 /* mW */
+#define MAX_RSSI_TRIGGER -10 /* dBm */
+#define MIN_RSSI_TRIGGER -200 /* dBm */
+#define MAX_FRAG_THRESHOLD 2346 /* byte count */
+#define MIN_FRAG_THRESHOLD 256 /* byte count */
+#define MAX_RTS_THRESHOLD 2347 /* byte count */
+
+// new types for Media Specific Indications
+// Extension channel offset
+#define EXTCHA_NONE 0
+#define EXTCHA_ABOVE 0x1
+#define EXTCHA_BELOW 0x3
+
+// BW
+#define BAND_WIDTH_20 0
+#define BAND_WIDTH_40 1
+#define BAND_WIDTH_BOTH 2
+#define BAND_WIDTH_10 3 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
+// SHORTGI
+#define GAP_INTERVAL_400 1 // only support in HT mode
+#define GAP_INTERVAL_800 0
+#define GAP_INTERVAL_BOTH 2
+
+#define NdisMediaStateConnected 1
+#define NdisMediaStateDisconnected 0
+
+#define NDIS_802_11_LENGTH_SSID 32
+#define NDIS_802_11_LENGTH_RATES 8
+#define NDIS_802_11_LENGTH_RATES_EX 16
+#define MAC_ADDR_LENGTH 6
+#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc
+#define MAX_NUMBER_OF_EVENT 10 // entry # in EVENT table
+#define MAX_NUMBER_OF_MAC 32 // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+#define MAX_NUMBER_OF_ACL 64
+#define MAX_LENGTH_OF_SUPPORT_RATES 12 // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define MAX_NUMBER_OF_DLS_ENTRY 4
+
+
+
+#ifndef UNDER_CE
+// OID definition, since NDIS 5.0 didn't define these, we need to define for our own
+//#if _WIN32_WINNT<=0x0500
+
+#define OID_GEN_MACHINE_NAME 0x0001021A
+
+#ifdef RALINK_ATE
+#define RT_QUERY_ATE_TXDONE_COUNT 0x0401
+#endif // RALINK_ATE //
+#define RT_QUERY_SIGNAL_CONTEXT 0x0402
+#define RT_SET_IAPP_PID 0x0404
+#define RT_SET_APD_PID 0x0405
+#define RT_SET_DEL_MAC_ENTRY 0x0406
+
+//
+// IEEE 802.11 OIDs
+//
+#define OID_GET_SET_TOGGLE 0x8000
+
+#define OID_802_11_NETWORK_TYPES_SUPPORTED 0x0103
+#define OID_802_11_NETWORK_TYPE_IN_USE 0x0104
+#define OID_802_11_RSSI_TRIGGER 0x0107
+#define RT_OID_802_11_RSSI 0x0108 //rt2860 only , kathy
+#define RT_OID_802_11_RSSI_1 0x0109 //rt2860 only , kathy
+#define RT_OID_802_11_RSSI_2 0x010A //rt2860 only , kathy
+#define OID_802_11_NUMBER_OF_ANTENNAS 0x010B
+#define OID_802_11_RX_ANTENNA_SELECTED 0x010C
+#define OID_802_11_TX_ANTENNA_SELECTED 0x010D
+#define OID_802_11_SUPPORTED_RATES 0x010E
+#define OID_802_11_ADD_WEP 0x0112
+#define OID_802_11_REMOVE_WEP 0x0113
+#define OID_802_11_DISASSOCIATE 0x0114
+#define OID_802_11_PRIVACY_FILTER 0x0118
+#define OID_802_11_ASSOCIATION_INFORMATION 0x011E
+#define OID_802_11_TEST 0x011F
+#define RT_OID_802_11_COUNTRY_REGION 0x0507
+#define OID_802_11_BSSID_LIST_SCAN 0x0508
+#define OID_802_11_SSID 0x0509
+#define OID_802_11_BSSID 0x050A
+#define RT_OID_802_11_RADIO 0x050B
+#define RT_OID_802_11_PHY_MODE 0x050C
+#define RT_OID_802_11_STA_CONFIG 0x050D
+#define OID_802_11_DESIRED_RATES 0x050E
+#define RT_OID_802_11_PREAMBLE 0x050F
+#define OID_802_11_WEP_STATUS 0x0510
+#define OID_802_11_AUTHENTICATION_MODE 0x0511
+#define OID_802_11_INFRASTRUCTURE_MODE 0x0512
+#define RT_OID_802_11_RESET_COUNTERS 0x0513
+#define OID_802_11_RTS_THRESHOLD 0x0514
+#define OID_802_11_FRAGMENTATION_THRESHOLD 0x0515
+#define OID_802_11_POWER_MODE 0x0516
+#define OID_802_11_TX_POWER_LEVEL 0x0517
+#define RT_OID_802_11_ADD_WPA 0x0518
+#define OID_802_11_REMOVE_KEY 0x0519
+#define OID_802_11_ADD_KEY 0x0520
+#define OID_802_11_CONFIGURATION 0x0521
+#define OID_802_11_TX_PACKET_BURST 0x0522
+#define RT_OID_802_11_QUERY_NOISE_LEVEL 0x0523
+#define RT_OID_802_11_EXTRA_INFO 0x0524
+#ifdef DBG
+#define RT_OID_802_11_HARDWARE_REGISTER 0x0525
+#endif
+#define OID_802_11_ENCRYPTION_STATUS OID_802_11_WEP_STATUS
+#define OID_802_11_DEAUTHENTICATION 0x0526
+#define OID_802_11_DROP_UNENCRYPTED 0x0527
+#define OID_802_11_MIC_FAILURE_REPORT_FRAME 0x0528
+
+// For 802.1x daemin using to require current driver configuration
+#define OID_802_11_RADIUS_QUERY_SETTING 0x0540
+
+#define RT_OID_DEVICE_NAME 0x0607
+#define RT_OID_VERSION_INFO 0x0608
+#define OID_802_11_BSSID_LIST 0x0609
+#define OID_802_3_CURRENT_ADDRESS 0x060A
+#define OID_GEN_MEDIA_CONNECT_STATUS 0x060B
+#define RT_OID_802_11_QUERY_LINK_STATUS 0x060C
+#define OID_802_11_RSSI 0x060D
+#define OID_802_11_STATISTICS 0x060E
+#define OID_GEN_RCV_OK 0x060F
+#define OID_GEN_RCV_NO_BUFFER 0x0610
+#define RT_OID_802_11_QUERY_EEPROM_VERSION 0x0611
+#define RT_OID_802_11_QUERY_FIRMWARE_VERSION 0x0612
+#define RT_OID_802_11_QUERY_LAST_RX_RATE 0x0613
+#define RT_OID_802_11_TX_POWER_LEVEL_1 0x0614
+#define RT_OID_802_11_QUERY_PIDVID 0x0615
+//for WPA_SUPPLICANT_SUPPORT
+#define OID_SET_COUNTERMEASURES 0x0616
+#define OID_802_11_SET_IEEE8021X 0x0617
+#define OID_802_11_SET_IEEE8021X_REQUIRE_KEY 0x0618
+#define OID_802_11_PMKID 0x0620
+#define RT_OID_WPA_SUPPLICANT_SUPPORT 0x0621
+#define RT_OID_WE_VERSION_COMPILED 0x0622
+#define RT_OID_NEW_DRIVER 0x0623
+
+
+//rt2860 , kathy
+#define RT_OID_802_11_SNR_0 0x0630
+#define RT_OID_802_11_SNR_1 0x0631
+#define RT_OID_802_11_QUERY_LAST_TX_RATE 0x0632
+#define RT_OID_802_11_QUERY_HT_PHYMODE 0x0633
+#define RT_OID_802_11_SET_HT_PHYMODE 0x0634
+#define OID_802_11_RELOAD_DEFAULTS 0x0635
+#define RT_OID_802_11_QUERY_APSD_SETTING 0x0636
+#define RT_OID_802_11_SET_APSD_SETTING 0x0637
+#define RT_OID_802_11_QUERY_APSD_PSM 0x0638
+#define RT_OID_802_11_SET_APSD_PSM 0x0639
+#define RT_OID_802_11_QUERY_DLS 0x063A
+#define RT_OID_802_11_SET_DLS 0x063B
+#define RT_OID_802_11_QUERY_DLS_PARAM 0x063C
+#define RT_OID_802_11_SET_DLS_PARAM 0x063D
+#define RT_OID_802_11_QUERY_WMM 0x063E
+#define RT_OID_802_11_SET_WMM 0x063F
+#define RT_OID_802_11_QUERY_IMME_BA_CAP 0x0640
+#define RT_OID_802_11_SET_IMME_BA_CAP 0x0641
+#define RT_OID_802_11_QUERY_BATABLE 0x0642
+#define RT_OID_802_11_ADD_IMME_BA 0x0643
+#define RT_OID_802_11_TEAR_IMME_BA 0x0644
+#define RT_OID_DRIVER_DEVICE_NAME 0x0645
+#define RT_OID_802_11_QUERY_DAT_HT_PHYMODE 0x0646
+#define RT_OID_QUERY_MULTIPLE_CARD_SUPPORT 0x0647
+
+// Ralink defined OIDs
+// Dennis Lee move to platform specific
+
+#define RT_OID_802_11_BSSID (OID_GET_SET_TOGGLE | OID_802_11_BSSID)
+#define RT_OID_802_11_SSID (OID_GET_SET_TOGGLE | OID_802_11_SSID)
+#define RT_OID_802_11_INFRASTRUCTURE_MODE (OID_GET_SET_TOGGLE | OID_802_11_INFRASTRUCTURE_MODE)
+#define RT_OID_802_11_ADD_WEP (OID_GET_SET_TOGGLE | OID_802_11_ADD_WEP)
+#define RT_OID_802_11_ADD_KEY (OID_GET_SET_TOGGLE | OID_802_11_ADD_KEY)
+#define RT_OID_802_11_REMOVE_WEP (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_WEP)
+#define RT_OID_802_11_REMOVE_KEY (OID_GET_SET_TOGGLE | OID_802_11_REMOVE_KEY)
+#define RT_OID_802_11_DISASSOCIATE (OID_GET_SET_TOGGLE | OID_802_11_DISASSOCIATE)
+#define RT_OID_802_11_AUTHENTICATION_MODE (OID_GET_SET_TOGGLE | OID_802_11_AUTHENTICATION_MODE)
+#define RT_OID_802_11_PRIVACY_FILTER (OID_GET_SET_TOGGLE | OID_802_11_PRIVACY_FILTER)
+#define RT_OID_802_11_BSSID_LIST_SCAN (OID_GET_SET_TOGGLE | OID_802_11_BSSID_LIST_SCAN)
+#define RT_OID_802_11_WEP_STATUS (OID_GET_SET_TOGGLE | OID_802_11_WEP_STATUS)
+#define RT_OID_802_11_RELOAD_DEFAULTS (OID_GET_SET_TOGGLE | OID_802_11_RELOAD_DEFAULTS)
+#define RT_OID_802_11_NETWORK_TYPE_IN_USE (OID_GET_SET_TOGGLE | OID_802_11_NETWORK_TYPE_IN_USE)
+#define RT_OID_802_11_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | OID_802_11_TX_POWER_LEVEL)
+#define RT_OID_802_11_RSSI_TRIGGER (OID_GET_SET_TOGGLE | OID_802_11_RSSI_TRIGGER)
+#define RT_OID_802_11_FRAGMENTATION_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_FRAGMENTATION_THRESHOLD)
+#define RT_OID_802_11_RTS_THRESHOLD (OID_GET_SET_TOGGLE | OID_802_11_RTS_THRESHOLD)
+#define RT_OID_802_11_RX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_RX_ANTENNA_SELECTED)
+#define RT_OID_802_11_TX_ANTENNA_SELECTED (OID_GET_SET_TOGGLE | OID_802_11_TX_ANTENNA_SELECTED)
+#define RT_OID_802_11_SUPPORTED_RATES (OID_GET_SET_TOGGLE | OID_802_11_SUPPORTED_RATES)
+#define RT_OID_802_11_DESIRED_RATES (OID_GET_SET_TOGGLE | OID_802_11_DESIRED_RATES)
+#define RT_OID_802_11_CONFIGURATION (OID_GET_SET_TOGGLE | OID_802_11_CONFIGURATION)
+#define RT_OID_802_11_POWER_MODE (OID_GET_SET_TOGGLE | OID_802_11_POWER_MODE)
+
+
+
+typedef enum _NDIS_802_11_STATUS_TYPE
+{
+ Ndis802_11StatusType_Authentication,
+ Ndis802_11StatusType_MediaStreamMode,
+ Ndis802_11StatusType_PMKID_CandidateList,
+ Ndis802_11StatusTypeMax // not a real type, defined as an upper bound
+} NDIS_802_11_STATUS_TYPE, *PNDIS_802_11_STATUS_TYPE;
+
+typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
+
+typedef struct _NDIS_802_11_STATUS_INDICATION
+{
+ NDIS_802_11_STATUS_TYPE StatusType;
+} NDIS_802_11_STATUS_INDICATION, *PNDIS_802_11_STATUS_INDICATION;
+
+// mask for authentication/integrity fields
+#define NDIS_802_11_AUTH_REQUEST_AUTH_FIELDS 0x0f
+
+#define NDIS_802_11_AUTH_REQUEST_REAUTH 0x01
+#define NDIS_802_11_AUTH_REQUEST_KEYUPDATE 0x02
+#define NDIS_802_11_AUTH_REQUEST_PAIRWISE_ERROR 0x06
+#define NDIS_802_11_AUTH_REQUEST_GROUP_ERROR 0x0E
+
+typedef struct _NDIS_802_11_AUTHENTICATION_REQUEST
+{
+ ULONG Length; // Length of structure
+ NDIS_802_11_MAC_ADDRESS Bssid;
+ ULONG Flags;
+} NDIS_802_11_AUTHENTICATION_REQUEST, *PNDIS_802_11_AUTHENTICATION_REQUEST;
+
+//Added new types for PMKID Candidate lists.
+typedef struct _PMKID_CANDIDATE {
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ ULONG Flags;
+} PMKID_CANDIDATE, *PPMKID_CANDIDATE;
+
+typedef struct _NDIS_802_11_PMKID_CANDIDATE_LIST
+{
+ ULONG Version; // Version of the structure
+ ULONG NumCandidates; // No. of pmkid candidates
+ PMKID_CANDIDATE CandidateList[1];
+} NDIS_802_11_PMKID_CANDIDATE_LIST, *PNDIS_802_11_PMKID_CANDIDATE_LIST;
+
+//Flags for PMKID Candidate list structure
+#define NDIS_802_11_PMKID_CANDIDATE_PREAUTH_ENABLED 0x01
+
+// Added new types for OFDM 5G and 2.4G
+typedef enum _NDIS_802_11_NETWORK_TYPE
+{
+ Ndis802_11FH,
+ Ndis802_11DS,
+ Ndis802_11OFDM5,
+ Ndis802_11OFDM5_N,
+ Ndis802_11OFDM24,
+ Ndis802_11OFDM24_N,
+ Ndis802_11Automode,
+ Ndis802_11NetworkTypeMax // not a real type, defined as an upper bound
+} NDIS_802_11_NETWORK_TYPE, *PNDIS_802_11_NETWORK_TYPE;
+
+typedef struct _NDIS_802_11_NETWORK_TYPE_LIST
+{
+ UINT NumberOfItems; // in list below, at least 1
+ NDIS_802_11_NETWORK_TYPE NetworkType [1];
+} NDIS_802_11_NETWORK_TYPE_LIST, *PNDIS_802_11_NETWORK_TYPE_LIST;
+
+typedef enum _NDIS_802_11_POWER_MODE
+{
+ Ndis802_11PowerModeCAM,
+ Ndis802_11PowerModeMAX_PSP,
+ Ndis802_11PowerModeFast_PSP,
+ Ndis802_11PowerModeLegacy_PSP,
+ Ndis802_11PowerModeMax // not a real mode, defined as an upper bound
+} NDIS_802_11_POWER_MODE, *PNDIS_802_11_POWER_MODE;
+
+typedef ULONG NDIS_802_11_TX_POWER_LEVEL; // in milliwatts
+
+//
+// Received Signal Strength Indication
+//
+typedef LONG NDIS_802_11_RSSI; // in dBm
+
+typedef struct _NDIS_802_11_CONFIGURATION_FH
+{
+ ULONG Length; // Length of structure
+ ULONG HopPattern; // As defined by 802.11, MSB set
+ ULONG HopSet; // to one if non-802.11
+ ULONG DwellTime; // units are Kusec
+} NDIS_802_11_CONFIGURATION_FH, *PNDIS_802_11_CONFIGURATION_FH;
+
+typedef struct _NDIS_802_11_CONFIGURATION
+{
+ ULONG Length; // Length of structure
+ ULONG BeaconPeriod; // units are Kusec
+ ULONG ATIMWindow; // units are Kusec
+ ULONG DSConfig; // Frequency, units are kHz
+ NDIS_802_11_CONFIGURATION_FH FHConfig;
+} NDIS_802_11_CONFIGURATION, *PNDIS_802_11_CONFIGURATION;
+
+typedef struct _NDIS_802_11_STATISTICS
+{
+ ULONG Length; // Length of structure
+ LARGE_INTEGER TransmittedFragmentCount;
+ LARGE_INTEGER MulticastTransmittedFrameCount;
+ LARGE_INTEGER FailedCount;
+ LARGE_INTEGER RetryCount;
+ LARGE_INTEGER MultipleRetryCount;
+ LARGE_INTEGER RTSSuccessCount;
+ LARGE_INTEGER RTSFailureCount;
+ LARGE_INTEGER ACKFailureCount;
+ LARGE_INTEGER FrameDuplicateCount;
+ LARGE_INTEGER ReceivedFragmentCount;
+ LARGE_INTEGER MulticastReceivedFrameCount;
+ LARGE_INTEGER FCSErrorCount;
+ LARGE_INTEGER TKIPLocalMICFailures;
+ LARGE_INTEGER TKIPRemoteMICErrors;
+ LARGE_INTEGER TKIPICVErrors;
+ LARGE_INTEGER TKIPCounterMeasuresInvoked;
+ LARGE_INTEGER TKIPReplays;
+ LARGE_INTEGER CCMPFormatErrors;
+ LARGE_INTEGER CCMPReplays;
+ LARGE_INTEGER CCMPDecryptErrors;
+ LARGE_INTEGER FourWayHandshakeFailures;
+} NDIS_802_11_STATISTICS, *PNDIS_802_11_STATISTICS;
+
+typedef ULONG NDIS_802_11_KEY_INDEX;
+typedef ULONGLONG NDIS_802_11_KEY_RSC;
+
+#define MAX_RADIUS_SRV_NUM 2 // 802.1x failover number
+
+typedef struct PACKED _RADIUS_SRV_INFO {
+ UINT32 radius_ip;
+ UINT32 radius_port;
+ UCHAR radius_key[64];
+ UCHAR radius_key_len;
+} RADIUS_SRV_INFO, *PRADIUS_SRV_INFO;
+
+typedef struct PACKED _RADIUS_KEY_INFO
+{
+ UCHAR radius_srv_num;
+ RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
+ UCHAR ieee8021xWEP; // dynamic WEP
+ UCHAR key_index;
+ UCHAR key_length; // length of key in bytes
+ UCHAR key_material[13];
+} RADIUS_KEY_INFO, *PRADIUS_KEY_INFO;
+
+// It's used by 802.1x daemon to require relative configuration
+typedef struct PACKED _RADIUS_CONF
+{
+ UINT32 Length; // Length of this structure
+ UCHAR mbss_num; // indicate multiple BSS number
+ UINT32 own_ip_addr;
+ UINT32 retry_interval;
+ UINT32 session_timeout_interval;
+ UCHAR EAPifname[IFNAMSIZ];
+ UCHAR EAPifname_len;
+ UCHAR PreAuthifname[IFNAMSIZ];
+ UCHAR PreAuthifname_len;
+ RADIUS_KEY_INFO RadiusInfo[8/*MAX_MBSSID_NUM*/];
+} RADIUS_CONF, *PRADIUS_CONF;
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+// Key mapping keys require a BSSID
+typedef struct _NDIS_802_11_KEY
+{
+ UINT Length; // Length of this structure
+ UINT KeyIndex;
+ UINT KeyLength; // length of key in bytes
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ NDIS_802_11_KEY_RSC KeyRSC;
+ UCHAR KeyMaterial[1]; // variable length depending on above field
+} NDIS_802_11_KEY, *PNDIS_802_11_KEY;
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct _NDIS_802_11_REMOVE_KEY
+{
+ UINT Length; // Length of this structure
+ UINT KeyIndex;
+ NDIS_802_11_MAC_ADDRESS BSSID;
+} NDIS_802_11_REMOVE_KEY, *PNDIS_802_11_REMOVE_KEY;
+
+typedef struct _NDIS_802_11_WEP
+{
+ UINT Length; // Length of this structure
+ UINT KeyIndex; // 0 is the per-client key, 1-N are the
+ // global keys
+ UINT KeyLength; // length of key in bytes
+ UCHAR KeyMaterial[1];// variable length depending on above field
+} NDIS_802_11_WEP, *PNDIS_802_11_WEP;
+
+
+typedef enum _NDIS_802_11_NETWORK_INFRASTRUCTURE
+{
+ Ndis802_11IBSS,
+ Ndis802_11Infrastructure,
+ Ndis802_11AutoUnknown,
+ Ndis802_11Monitor,
+ Ndis802_11InfrastructureMax // Not a real value, defined as upper bound
+} NDIS_802_11_NETWORK_INFRASTRUCTURE, *PNDIS_802_11_NETWORK_INFRASTRUCTURE;
+
+// Add new authentication modes
+typedef enum _NDIS_802_11_AUTHENTICATION_MODE
+{
+ Ndis802_11AuthModeOpen,
+ Ndis802_11AuthModeShared,
+ Ndis802_11AuthModeAutoSwitch,
+ Ndis802_11AuthModeWPA,
+ Ndis802_11AuthModeWPAPSK,
+ Ndis802_11AuthModeWPANone,
+ Ndis802_11AuthModeWPA2,
+ Ndis802_11AuthModeWPA2PSK,
+ Ndis802_11AuthModeWPA1WPA2,
+ Ndis802_11AuthModeWPA1PSKWPA2PSK,
+ Ndis802_11AuthModeMax // Not a real mode, defined as upper bound
+} NDIS_802_11_AUTHENTICATION_MODE, *PNDIS_802_11_AUTHENTICATION_MODE;
+
+typedef UCHAR NDIS_802_11_RATES[NDIS_802_11_LENGTH_RATES]; // Set of 8 data rates
+typedef UCHAR NDIS_802_11_RATES_EX[NDIS_802_11_LENGTH_RATES_EX]; // Set of 16 data rates
+
+typedef struct PACKED _NDIS_802_11_SSID
+{
+ UINT SsidLength; // length of SSID field below, in bytes;
+ // this can be zero.
+ UCHAR Ssid[NDIS_802_11_LENGTH_SSID]; // SSID information field
+} NDIS_802_11_SSID, *PNDIS_802_11_SSID;
+
+
+typedef struct PACKED _NDIS_WLAN_BSSID
+{
+ ULONG Length; // Length of this structure
+ NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
+ UCHAR Reserved[2];
+ NDIS_802_11_SSID Ssid; // SSID
+ ULONG Privacy; // WEP encryption requirement
+ NDIS_802_11_RSSI Rssi; // receive signal strength in dBm
+ NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ NDIS_802_11_CONFIGURATION Configuration;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ NDIS_802_11_RATES SupportedRates;
+} NDIS_WLAN_BSSID, *PNDIS_WLAN_BSSID;
+
+typedef struct PACKED _NDIS_802_11_BSSID_LIST
+{
+ UINT NumberOfItems; // in list below, at least 1
+ NDIS_WLAN_BSSID Bssid[1];
+} NDIS_802_11_BSSID_LIST, *PNDIS_802_11_BSSID_LIST;
+
+// Added Capabilities, IELength and IEs for each BSSID
+typedef struct PACKED _NDIS_WLAN_BSSID_EX
+{
+ ULONG Length; // Length of this structure
+ NDIS_802_11_MAC_ADDRESS MacAddress; // BSSID
+ UCHAR Reserved[2];
+ NDIS_802_11_SSID Ssid; // SSID
+ UINT Privacy; // WEP encryption requirement
+ NDIS_802_11_RSSI Rssi; // receive signal
+ // strength in dBm
+ NDIS_802_11_NETWORK_TYPE NetworkTypeInUse;
+ NDIS_802_11_CONFIGURATION Configuration;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE InfrastructureMode;
+ NDIS_802_11_RATES_EX SupportedRates;
+ ULONG IELength;
+ UCHAR IEs[1];
+} NDIS_WLAN_BSSID_EX, *PNDIS_WLAN_BSSID_EX;
+
+typedef struct PACKED _NDIS_802_11_BSSID_LIST_EX
+{
+ UINT NumberOfItems; // in list below, at least 1
+ NDIS_WLAN_BSSID_EX Bssid[1];
+} NDIS_802_11_BSSID_LIST_EX, *PNDIS_802_11_BSSID_LIST_EX;
+
+typedef struct PACKED _NDIS_802_11_FIXED_IEs
+{
+ UCHAR Timestamp[8];
+ USHORT BeaconInterval;
+ USHORT Capabilities;
+} NDIS_802_11_FIXED_IEs, *PNDIS_802_11_FIXED_IEs;
+
+typedef struct _NDIS_802_11_VARIABLE_IEs
+{
+ UCHAR ElementID;
+ UCHAR Length; // Number of bytes in data field
+ UCHAR data[1];
+} NDIS_802_11_VARIABLE_IEs, *PNDIS_802_11_VARIABLE_IEs;
+
+typedef ULONG NDIS_802_11_FRAGMENTATION_THRESHOLD;
+
+typedef ULONG NDIS_802_11_RTS_THRESHOLD;
+
+typedef ULONG NDIS_802_11_ANTENNA;
+
+typedef enum _NDIS_802_11_PRIVACY_FILTER
+{
+ Ndis802_11PrivFilterAcceptAll,
+ Ndis802_11PrivFilter8021xWEP
+} NDIS_802_11_PRIVACY_FILTER, *PNDIS_802_11_PRIVACY_FILTER;
+
+// Added new encryption types
+// Also aliased typedef to new name
+typedef enum _NDIS_802_11_WEP_STATUS
+{
+ Ndis802_11WEPEnabled,
+ Ndis802_11Encryption1Enabled = Ndis802_11WEPEnabled,
+ Ndis802_11WEPDisabled,
+ Ndis802_11EncryptionDisabled = Ndis802_11WEPDisabled,
+ Ndis802_11WEPKeyAbsent,
+ Ndis802_11Encryption1KeyAbsent = Ndis802_11WEPKeyAbsent,
+ Ndis802_11WEPNotSupported,
+ Ndis802_11EncryptionNotSupported = Ndis802_11WEPNotSupported,
+ Ndis802_11Encryption2Enabled,
+ Ndis802_11Encryption2KeyAbsent,
+ Ndis802_11Encryption3Enabled,
+ Ndis802_11Encryption3KeyAbsent,
+ Ndis802_11Encryption4Enabled, // TKIP or AES mix
+ Ndis802_11Encryption4KeyAbsent,
+} NDIS_802_11_WEP_STATUS, *PNDIS_802_11_WEP_STATUS,
+ NDIS_802_11_ENCRYPTION_STATUS, *PNDIS_802_11_ENCRYPTION_STATUS;
+
+typedef enum _NDIS_802_11_RELOAD_DEFAULTS
+{
+ Ndis802_11ReloadWEPKeys
+} NDIS_802_11_RELOAD_DEFAULTS, *PNDIS_802_11_RELOAD_DEFAULTS;
+
+#define NDIS_802_11_AI_REQFI_CAPABILITIES 1
+#define NDIS_802_11_AI_REQFI_LISTENINTERVAL 2
+#define NDIS_802_11_AI_REQFI_CURRENTAPADDRESS 4
+
+#define NDIS_802_11_AI_RESFI_CAPABILITIES 1
+#define NDIS_802_11_AI_RESFI_STATUSCODE 2
+#define NDIS_802_11_AI_RESFI_ASSOCIATIONID 4
+
+typedef struct _NDIS_802_11_AI_REQFI
+{
+ USHORT Capabilities;
+ USHORT ListenInterval;
+ NDIS_802_11_MAC_ADDRESS CurrentAPAddress;
+} NDIS_802_11_AI_REQFI, *PNDIS_802_11_AI_REQFI;
+
+typedef struct _NDIS_802_11_AI_RESFI
+{
+ USHORT Capabilities;
+ USHORT StatusCode;
+ USHORT AssociationId;
+} NDIS_802_11_AI_RESFI, *PNDIS_802_11_AI_RESFI;
+
+typedef struct _NDIS_802_11_ASSOCIATION_INFORMATION
+{
+ ULONG Length;
+ USHORT AvailableRequestFixedIEs;
+ NDIS_802_11_AI_REQFI RequestFixedIEs;
+ ULONG RequestIELength;
+ ULONG OffsetRequestIEs;
+ USHORT AvailableResponseFixedIEs;
+ NDIS_802_11_AI_RESFI ResponseFixedIEs;
+ ULONG ResponseIELength;
+ ULONG OffsetResponseIEs;
+} NDIS_802_11_ASSOCIATION_INFORMATION, *PNDIS_802_11_ASSOCIATION_INFORMATION;
+
+typedef struct _NDIS_802_11_AUTHENTICATION_EVENT
+{
+ NDIS_802_11_STATUS_INDICATION Status;
+ NDIS_802_11_AUTHENTICATION_REQUEST Request[1];
+} NDIS_802_11_AUTHENTICATION_EVENT, *PNDIS_802_11_AUTHENTICATION_EVENT;
+
+/*
+typedef struct _NDIS_802_11_TEST
+{
+ ULONG Length;
+ ULONG Type;
+ union
+ {
+ NDIS_802_11_AUTHENTICATION_EVENT AuthenticationEvent;
+ NDIS_802_11_RSSI RssiTrigger;
+ };
+} NDIS_802_11_TEST, *PNDIS_802_11_TEST;
+ */
+
+// 802.11 Media stream constraints, associated with OID_802_11_MEDIA_STREAM_MODE
+typedef enum _NDIS_802_11_MEDIA_STREAM_MODE
+{
+ Ndis802_11MediaStreamOff,
+ Ndis802_11MediaStreamOn,
+} NDIS_802_11_MEDIA_STREAM_MODE, *PNDIS_802_11_MEDIA_STREAM_MODE;
+
+// PMKID Structures
+typedef UCHAR NDIS_802_11_PMKID_VALUE[16];
+
+#ifdef CONFIG_STA_SUPPORT
+typedef struct _BSSID_INFO
+{
+ NDIS_802_11_MAC_ADDRESS BSSID;
+ NDIS_802_11_PMKID_VALUE PMKID;
+} BSSID_INFO, *PBSSID_INFO;
+
+typedef struct _NDIS_802_11_PMKID
+{
+ UINT Length;
+ UINT BSSIDInfoCount;
+ BSSID_INFO BSSIDInfo[1];
+} NDIS_802_11_PMKID, *PNDIS_802_11_PMKID;
+#endif // CONFIG_STA_SUPPORT //
+
+
+typedef struct _NDIS_802_11_AUTHENTICATION_ENCRYPTION
+{
+ NDIS_802_11_AUTHENTICATION_MODE AuthModeSupported;
+ NDIS_802_11_ENCRYPTION_STATUS EncryptStatusSupported;
+} NDIS_802_11_AUTHENTICATION_ENCRYPTION, *PNDIS_802_11_AUTHENTICATION_ENCRYPTION;
+
+typedef struct _NDIS_802_11_CAPABILITY
+{
+ ULONG Length;
+ ULONG Version;
+ ULONG NoOfPMKIDs;
+ ULONG NoOfAuthEncryptPairsSupported;
+ NDIS_802_11_AUTHENTICATION_ENCRYPTION AuthenticationEncryptionSupported[1];
+} NDIS_802_11_CAPABILITY, *PNDIS_802_11_CAPABILITY;
+
+//#endif //of WIN 2k
+#endif //UNDER_CE
+
+#if WIRELESS_EXT <= 11
+#ifndef SIOCDEVPRIVATE
+#define SIOCDEVPRIVATE 0x8BE0
+#endif
+#define SIOCIWFIRSTPRIV SIOCDEVPRIVATE
+#endif
+
+#ifdef CONFIG_STA_SUPPORT
+#define RT_PRIV_IOCTL_EXT (SIOCIWFIRSTPRIV + 0x01) // Sync. with AP for wsc upnp daemon
+#define RTPRIV_IOCTL_SET (SIOCIWFIRSTPRIV + 0x02)
+
+#ifdef DBG
+#define RTPRIV_IOCTL_BBP (SIOCIWFIRSTPRIV + 0x03)
+#define RTPRIV_IOCTL_MAC (SIOCIWFIRSTPRIV + 0x05)
+#define RTPRIV_IOCTL_RF (SIOCIWFIRSTPRIV + 0x13)
+#define RTPRIV_IOCTL_E2P (SIOCIWFIRSTPRIV + 0x07)
+#endif
+
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+#define RTPRIV_IOCTL_ATE (SIOCIWFIRSTPRIV + 0x08)
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#define RTPRIV_IOCTL_STATISTICS (SIOCIWFIRSTPRIV + 0x09)
+#define RTPRIV_IOCTL_ADD_PMKID_CACHE (SIOCIWFIRSTPRIV + 0x0A)
+#define RTPRIV_IOCTL_RADIUS_DATA (SIOCIWFIRSTPRIV + 0x0C)
+#define RTPRIV_IOCTL_GSITESURVEY (SIOCIWFIRSTPRIV + 0x0D)
+#define RT_PRIV_IOCTL (SIOCIWFIRSTPRIV + 0x0E) // Sync. with RT61 (for wpa_supplicant)
+#define RTPRIV_IOCTL_GET_MAC_TABLE (SIOCIWFIRSTPRIV + 0x0F)
+
+#define RTPRIV_IOCTL_SHOW (SIOCIWFIRSTPRIV + 0x11)
+enum {
+ SHOW_CONN_STATUS = 4,
+ SHOW_DRVIER_VERION = 5,
+ SHOW_BA_INFO = 6,
+ SHOW_DESC_INFO = 7,
+#ifdef RT2870
+ SHOW_RXBULK_INFO = 8,
+ SHOW_TXBULK_INFO = 9,
+#endif // RT2870 //
+ RAIO_OFF = 10,
+ RAIO_ON = 11,
+#ifdef QOS_DLS_SUPPORT
+ SHOW_DLS_ENTRY_INFO = 19,
+#endif // QOS_DLS_SUPPORT //
+ SHOW_CFG_VALUE = 20,
+};
+
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#ifdef SNMP_SUPPORT
+//SNMP ieee 802dot11, kathy , 2008_0220
+// dot11res(3)
+#define RT_OID_802_11_MANUFACTUREROUI 0x0700
+#define RT_OID_802_11_MANUFACTURERNAME 0x0701
+#define RT_OID_802_11_RESOURCETYPEIDNAME 0x0702
+
+// dot11smt(1)
+#define RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED 0x0703
+#define RT_OID_802_11_POWERMANAGEMENTMODE 0x0704
+#define OID_802_11_WEPDEFAULTKEYVALUE 0x0705 // read , write
+#define OID_802_11_WEPDEFAULTKEYID 0x0706
+#define RT_OID_802_11_WEPKEYMAPPINGLENGTH 0x0707
+#define OID_802_11_SHORTRETRYLIMIT 0x0708
+#define OID_802_11_LONGRETRYLIMIT 0x0709
+#define RT_OID_802_11_PRODUCTID 0x0710
+#define RT_OID_802_11_MANUFACTUREID 0x0711
+
+// //dot11Phy(4)
+#define OID_802_11_CURRENTCHANNEL 0x0712
+
+//dot11mac
+#define RT_OID_802_11_MAC_ADDRESS 0x0713
+#endif // SNMP_SUPPORT //
+
+#define OID_802_11_BUILD_CHANNEL_EX 0x0714
+#define OID_802_11_GET_CH_LIST 0x0715
+#define OID_802_11_GET_COUNTRY_CODE 0x0716
+#define OID_802_11_GET_CHANNEL_GEOGRAPHY 0x0717
+
+//#define RT_OID_802_11_STATISTICS (OID_GET_SET_TOGGLE | OID_802_11_STATISTICS)
+
+#ifdef CONFIG_STA_SUPPORT
+#define RT_OID_WSC_SET_PASSPHRASE 0x0740 // passphrase for wpa(2)-psk
+#define RT_OID_WSC_DRIVER_AUTO_CONNECT 0x0741
+#define RT_OID_WSC_QUERY_DEFAULT_PROFILE 0x0742
+#define RT_OID_WSC_SET_CONN_BY_PROFILE_INDEX 0x0743
+#define RT_OID_WSC_SET_ACTION 0x0744
+#define RT_OID_WSC_SET_SSID 0x0745
+#define RT_OID_WSC_SET_PIN_CODE 0x0746
+#define RT_OID_WSC_SET_MODE 0x0747 // PIN or PBC
+#define RT_OID_WSC_SET_CONF_MODE 0x0748 // Enrollee or Registrar
+#define RT_OID_WSC_SET_PROFILE 0x0749
+#endif // CONFIG_STA_SUPPORT //
+#define RT_OID_802_11_WSC_QUERY_PROFILE 0x0750
+// for consistency with RT61
+#define RT_OID_WSC_QUERY_STATUS 0x0751
+#define RT_OID_WSC_PIN_CODE 0x0752
+#define RT_OID_WSC_UUID 0x0753
+#define RT_OID_WSC_SET_SELECTED_REGISTRAR 0x0754
+#define RT_OID_WSC_EAPMSG 0x0755
+#define RT_OID_WSC_MANUFACTURER 0x0756
+#define RT_OID_WSC_MODEL_NAME 0x0757
+#define RT_OID_WSC_MODEL_NO 0x0758
+#define RT_OID_WSC_SERIAL_NO 0x0759
+#define RT_OID_WSC_MAC_ADDRESS 0x0760
+
+#ifdef LLTD_SUPPORT
+// for consistency with RT61
+#define RT_OID_GET_PHY_MODE 0x761
+#endif // LLTD_SUPPORT //
+
+#ifdef NINTENDO_AP
+//#define RT_OID_NINTENDO 0x0D010770
+#define RT_OID_802_11_NINTENDO_GET_TABLE 0x0771 //((RT_OID_NINTENDO + 0x01) & 0xffff)
+#define RT_OID_802_11_NINTENDO_SET_TABLE 0x0772 //((RT_OID_NINTENDO + 0x02) & 0xffff)
+#define RT_OID_802_11_NINTENDO_CAPABLE 0x0773 //((RT_OID_NINTENDO + 0x03) & 0xffff)
+#endif // NINTENDO_AP //
+
+//Add Paul Chen for Accton
+//#define RT_OID_TX_POWER_LEVEL 0xFF020010
+//#define RT_OID_SET_TX_POWER_LEVEL (OID_GET_SET_TOGGLE | RT_OID_TX_POWER_LEVEL)
+
+// New for MeetingHouse Api support
+#define OID_MH_802_1X_SUPPORTED 0xFFEDC100
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
+typedef union _HTTRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ USHORT MODE:2; // Use definition MODE_xxx.
+// USHORT rsv:3;
+ USHORT TxBF:1;
+ USHORT rsv:2;
+ USHORT STBC:2; //SPACE
+ USHORT ShortGI:1;
+ USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
+ USHORT MCS:7; // MCS
+ } field;
+#else
+ struct {
+ USHORT MCS:7; // MCS
+ USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
+ USHORT ShortGI:1;
+ USHORT STBC:2; //SPACE
+// USHORT rsv:3;
+ USHORT rsv:2;
+ USHORT TxBF:1;
+ USHORT MODE:2; // Use definition MODE_xxx.
+ } field;
+#endif
+ USHORT word;
+ } HTTRANSMIT_SETTING, *PHTTRANSMIT_SETTING;
+
+typedef enum _RT_802_11_PREAMBLE {
+ Rt802_11PreambleLong,
+ Rt802_11PreambleShort,
+ Rt802_11PreambleAuto
+} RT_802_11_PREAMBLE, *PRT_802_11_PREAMBLE;
+
+// Only for STA, need to sync with AP
+// 2005-03-08 match current RaConfig.
+typedef enum _RT_802_11_PHY_MODE {
+ PHY_11BG_MIXED = 0,
+ PHY_11B,
+ PHY_11A,
+ PHY_11ABG_MIXED,
+ PHY_11G,
+#ifdef DOT11_N_SUPPORT
+ PHY_11ABGN_MIXED, // both band 5
+ PHY_11N_2_4G, // 11n-only with 2.4G band 6
+ PHY_11GN_MIXED, // 2.4G band 7
+ PHY_11AN_MIXED, // 5G band 8
+ PHY_11BGN_MIXED, // if check 802.11b. 9
+ PHY_11AGN_MIXED, // if check 802.11b. 10
+ PHY_11N_5G, // 11n-only with 5G band 11
+#endif // DOT11_N_SUPPORT //
+} RT_802_11_PHY_MODE;
+
+// put all proprietery for-query objects here to reduce # of Query_OID
+typedef struct _RT_802_11_LINK_STATUS {
+ ULONG CurrTxRate; // in units of 0.5Mbps
+ ULONG ChannelQuality; // 0..100 %
+ ULONG TxByteCount; // both ok and fail
+ ULONG RxByteCount; // both ok and fail
+ ULONG CentralChannel; // 40MHz central channel number
+} RT_802_11_LINK_STATUS, *PRT_802_11_LINK_STATUS;
+
+typedef struct _RT_802_11_EVENT_LOG {
+ LARGE_INTEGER SystemTime; // timestammp via NdisGetCurrentSystemTime()
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ USHORT Event; // EVENT_xxx
+} RT_802_11_EVENT_LOG, *PRT_802_11_EVENT_LOG;
+
+typedef struct _RT_802_11_EVENT_TABLE {
+ ULONG Num;
+ ULONG Rsv; // to align Log[] at LARGE_INEGER boundary
+ RT_802_11_EVENT_LOG Log[MAX_NUMBER_OF_EVENT];
+} RT_802_11_EVENT_TABLE, PRT_802_11_EVENT_TABLE;
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI. Don't change this definition!!!
+typedef union _MACHTTRANSMIT_SETTING {
+ struct {
+ USHORT MCS:7; // MCS
+ USHORT BW:1; //channel bandwidth 20MHz or 40 MHz
+ USHORT ShortGI:1;
+ USHORT STBC:2; //SPACE
+ USHORT rsv:3;
+ USHORT MODE:2; // Use definition MODE_xxx.
+ } field;
+ USHORT word;
+ } MACHTTRANSMIT_SETTING, *PMACHTTRANSMIT_SETTING;
+
+typedef struct _RT_802_11_MAC_ENTRY {
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ UCHAR Aid;
+ UCHAR Psm; // 0:PWR_ACTIVE, 1:PWR_SAVE
+ UCHAR MimoPs; // 0:MMPS_STATIC, 1:MMPS_DYNAMIC, 3:MMPS_Enabled
+ CHAR AvgRssi0;
+ CHAR AvgRssi1;
+ CHAR AvgRssi2;
+ UINT32 ConnectedTime;
+ MACHTTRANSMIT_SETTING TxRate;
+} RT_802_11_MAC_ENTRY, *PRT_802_11_MAC_ENTRY;
+
+typedef struct _RT_802_11_MAC_TABLE {
+ ULONG Num;
+ RT_802_11_MAC_ENTRY Entry[MAX_NUMBER_OF_MAC];
+} RT_802_11_MAC_TABLE, *PRT_802_11_MAC_TABLE;
+
+// structure for query/set hardware register - MAC, BBP, RF register
+typedef struct _RT_802_11_HARDWARE_REGISTER {
+ ULONG HardwareType; // 0:MAC, 1:BBP, 2:RF register, 3:EEPROM
+ ULONG Offset; // Q/S register offset addr
+ ULONG Data; // R/W data buffer
+} RT_802_11_HARDWARE_REGISTER, *PRT_802_11_HARDWARE_REGISTER;
+
+// structure to tune BBP R17 "RX AGC VGC init"
+//typedef struct _RT_802_11_RX_AGC_VGC_TUNING {
+// UCHAR FalseCcaLowerThreshold; // 0-255, def 10
+// UCHAR FalseCcaUpperThreshold; // 0-255, def 100
+// UCHAR VgcDelta; // R17 +-= VgcDelta whenever flase CCA over UpprThreshold
+// // or lower than LowerThresholdupper threshold
+// UCHAR VgcUpperBound; // max value of R17
+//} RT_802_11_RX_AGC_VGC_TUNING, *PRT_802_11_RX_AGC_VGC_TUNING;
+
+typedef struct _RT_802_11_AP_CONFIG {
+ ULONG EnableTxBurst; // 0-disable, 1-enable
+ ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
+ ULONG IsolateInterStaTraffic; // 0-disable, 1-enable isolation
+ ULONG HideSsid; // 0-disable, 1-enable hiding
+ ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
+ ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time
+ ULONG Rsv1; // must be 0
+ ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
+} RT_802_11_AP_CONFIG, *PRT_802_11_AP_CONFIG;
+
+// structure to query/set STA_CONFIG
+typedef struct _RT_802_11_STA_CONFIG {
+ ULONG EnableTxBurst; // 0-disable, 1-enable
+ ULONG EnableTurboRate; // 0-disable, 1-enable 72/100mbps turbo rate
+ ULONG UseBGProtection; // 0-AUTO, 1-always ON, 2-always OFF
+ ULONG UseShortSlotTime; // 0-no use, 1-use 9-us short slot time when applicable
+ ULONG AdhocMode; // 0-11b rates only (WIFI spec), 1 - b/g mixed, 2 - g only
+ ULONG HwRadioStatus; // 0-OFF, 1-ON, default is 1, Read-Only
+ ULONG Rsv1; // must be 0
+ ULONG SystemErrorBitmap; // ignore upon SET, return system error upon QUERY
+} RT_802_11_STA_CONFIG, *PRT_802_11_STA_CONFIG;
+
+//
+// For OID Query or Set about BA structure
+//
+typedef struct _OID_BACAP_STRUC {
+ UCHAR RxBAWinLimit;
+ UCHAR TxBAWinLimit;
+ UCHAR Policy; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
+ UCHAR MpduDensity; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use. other value invalid
+ UCHAR AmsduEnable; //Enable AMSDU transmisstion
+ UCHAR AmsduSize; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
+ UCHAR MMPSmode; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+ BOOLEAN AutoBA; // Auto BA will automatically
+} OID_BACAP_STRUC, *POID_BACAP_STRUC;
+
+typedef struct _RT_802_11_ACL_ENTRY {
+ UCHAR Addr[MAC_ADDR_LENGTH];
+ USHORT Rsv;
+} RT_802_11_ACL_ENTRY, *PRT_802_11_ACL_ENTRY;
+
+typedef struct PACKED _RT_802_11_ACL {
+ ULONG Policy; // 0-disable, 1-positive list, 2-negative list
+ ULONG Num;
+ RT_802_11_ACL_ENTRY Entry[MAX_NUMBER_OF_ACL];
+} RT_802_11_ACL, *PRT_802_11_ACL;
+
+typedef struct _RT_802_11_WDS {
+ ULONG Num;
+ NDIS_802_11_MAC_ADDRESS Entry[24/*MAX_NUM_OF_WDS_LINK*/];
+ ULONG KeyLength;
+ UCHAR KeyMaterial[32];
+} RT_802_11_WDS, *PRT_802_11_WDS;
+
+typedef struct _RT_802_11_TX_RATES_ {
+ UCHAR SupRateLen;
+ UCHAR SupRate[MAX_LENGTH_OF_SUPPORT_RATES];
+ UCHAR ExtRateLen;
+ UCHAR ExtRate[MAX_LENGTH_OF_SUPPORT_RATES];
+} RT_802_11_TX_RATES, *PRT_802_11_TX_RATES;
+
+
+// Definition of extra information code
+#define GENERAL_LINK_UP 0x0 // Link is Up
+#define GENERAL_LINK_DOWN 0x1 // Link is Down
+#define HW_RADIO_OFF 0x2 // Hardware radio off
+#define SW_RADIO_OFF 0x3 // Software radio off
+#define AUTH_FAIL 0x4 // Open authentication fail
+#define AUTH_FAIL_KEYS 0x5 // Shared authentication fail
+#define ASSOC_FAIL 0x6 // Association failed
+#define EAP_MIC_FAILURE 0x7 // Deauthencation because MIC failure
+#define EAP_4WAY_TIMEOUT 0x8 // Deauthencation on 4-way handshake timeout
+#define EAP_GROUP_KEY_TIMEOUT 0x9 // Deauthencation on group key handshake timeout
+#define EAP_SUCCESS 0xa // EAP succeed
+#define DETECT_RADAR_SIGNAL 0xb // Radar signal occur in current channel
+#define EXTRA_INFO_MAX 0xb // Indicate Last OID
+
+#define EXTRA_INFO_CLEAR 0xffffffff
+
+// This is OID setting structure. So only GF or MM as Mode. This is valid when our wirelss mode has 802.11n in use.
+typedef struct {
+ RT_802_11_PHY_MODE PhyMode; //
+ UCHAR TransmitNo;
+ UCHAR HtMode; //HTMODE_GF or HTMODE_MM
+ UCHAR ExtOffset; //extension channel above or below
+ UCHAR MCS;
+ UCHAR BW;
+ UCHAR STBC;
+ UCHAR SHORTGI;
+ UCHAR rsv;
+} OID_SET_HT_PHYMODE, *POID_SET_HT_PHYMODE;
+
+#ifdef NINTENDO_AP
+#define NINTENDO_MAX_ENTRY 16
+#define NINTENDO_SSID_NAME_LN 8
+#define NINTENDO_SSID_NAME "NWCUSBAP"
+#define NINTENDO_PROBE_REQ_FLAG_MASK 0x03
+#define NINTENDO_PROBE_REQ_ON 0x01
+#define NINTENDO_PROBE_REQ_SIGNAL 0x02
+#define NINTENDO_PROBE_RSP_ON 0x01
+#define NINTENDO_SSID_NICKNAME_LN 20
+
+#define NINTENDO_WEPKEY_LN 13
+
+typedef struct _NINTENDO_SSID
+{
+ UCHAR NINTENDOFixChar[NINTENDO_SSID_NAME_LN];
+ UCHAR zero1;
+ UCHAR registe;
+ UCHAR ID;
+ UCHAR zero2;
+ UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
+} RT_NINTENDO_SSID, *PRT_NINTENDO_SSID;
+
+typedef struct _NINTENDO_ENTRY
+{
+ UCHAR NICKname[NINTENDO_SSID_NICKNAME_LN];
+ UCHAR DS_Addr[ETH_LENGTH_OF_ADDRESS];
+ UCHAR registe;
+ UCHAR UserSpaceAck;
+} RT_NINTENDO_ENTRY, *PRT_NINTENDO_ENTRY;
+
+//RTPRIV_IOCTL_NINTENDO_GET_TABLE
+//RTPRIV_IOCTL_NINTENDO_SET_TABLE
+typedef struct _NINTENDO_TABLE
+{
+ UINT number;
+ RT_NINTENDO_ENTRY entry[NINTENDO_MAX_ENTRY];
+} RT_NINTENDO_TABLE, *PRT_NINTENDO_TABLE;
+
+//RTPRIV_IOCTL_NINTENDO_SEED_WEPKEY
+typedef struct _NINTENDO_SEED_WEPKEY
+{
+ UCHAR seed[NINTENDO_SSID_NICKNAME_LN];
+ UCHAR wepkey[16];//use 13 for 104 bits wep key
+} RT_NINTENDO_SEED_WEPKEY, *PRT_NINTENDO_SEED_WEPKEY;
+#endif // NINTENDO_AP //
+
+#ifdef LLTD_SUPPORT
+typedef struct _RT_LLTD_ASSOICATION_ENTRY {
+ UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+ unsigned short MOR; // maximum operational rate
+ UCHAR phyMode;
+} RT_LLTD_ASSOICATION_ENTRY, *PRT_LLTD_ASSOICATION_ENTRY;
+
+typedef struct _RT_LLTD_ASSOICATION_TABLE {
+ unsigned int Num;
+ RT_LLTD_ASSOICATION_ENTRY Entry[MAX_NUMBER_OF_MAC];
+} RT_LLTD_ASSOICATION_TABLE, *PRT_LLTD_ASSOICATION_TABLE;
+#endif // LLTD_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+//rt2860, kathy 2007-0118
+// structure for DLS
+typedef struct _RT_802_11_DLS_UI {
+ USHORT TimeOut; // unit: second , set by UI
+ USHORT CountDownTimer; // unit: second , used by driver only
+ NDIS_802_11_MAC_ADDRESS MacAddr; // set by UI
+ UCHAR Status; // 0: none , 1: wait STAkey, 2: finish DLS setup , set by driver only
+ BOOLEAN Valid; // 1: valid , 0: invalid , set by UI, use to setup or tear down DLS link
+} RT_802_11_DLS_UI, *PRT_802_11_DLS_UI;
+
+typedef struct _RT_802_11_DLS_INFO {
+ RT_802_11_DLS_UI Entry[MAX_NUMBER_OF_DLS_ENTRY];
+ UCHAR num;
+} RT_802_11_DLS_INFO, *PRT_802_11_DLS_INFO;
+
+typedef enum _RT_802_11_DLS_MODE {
+ DLS_NONE,
+ DLS_WAIT_KEY,
+ DLS_FINISH
+} RT_802_11_DLS_MODE;
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+#define RT_ASSOC_EVENT_FLAG 0x0101
+#define RT_DISASSOC_EVENT_FLAG 0x0102
+#define RT_REQIE_EVENT_FLAG 0x0103
+#define RT_RESPIE_EVENT_FLAG 0x0104
+#define RT_ASSOCINFO_EVENT_FLAG 0x0105
+#define RT_PMKIDCAND_FLAG 0x0106
+#define RT_INTERFACE_DOWN 0x0107
+#define RT_INTERFACE_UP 0x0108
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+#define MAX_CUSTOM_LEN 128
+
+#ifdef CONFIG_STA_SUPPORT
+typedef enum _RT_802_11_D_CLIENT_MODE
+{
+ Rt802_11_D_None,
+ Rt802_11_D_Flexible,
+ Rt802_11_D_Strict,
+} RT_802_11_D_CLIENT_MODE, *PRT_802_11_D_CLIENT_MODE;
+#endif // CONFIG_STA_SUPPORT //
+
+typedef struct _RT_CHANNEL_LIST_INFO
+{
+ UCHAR ChannelList[MAX_NUM_OF_CHS]; // list all supported channels for site survey
+ UCHAR ChannelListNum; // number of channel in ChannelList[]
+} RT_CHANNEL_LIST_INFO, *PRT_CHANNEL_LIST_INFO;
+
+// WSC configured credential
+typedef struct _WSC_CREDENTIAL
+{
+ NDIS_802_11_SSID SSID; // mandatory
+ USHORT AuthType; // mandatory, 1: open, 2: wpa-psk, 4: shared, 8:wpa, 0x10: wpa2, 0x20: wpa2-psk
+ USHORT EncrType; // mandatory, 1: none, 2: wep, 4: tkip, 8: aes
+ UCHAR Key[64]; // mandatory, Maximum 64 byte
+ USHORT KeyLength;
+ UCHAR MacAddr[6]; // mandatory, AP MAC address
+ UCHAR KeyIndex; // optional, default is 1
+ UCHAR Rsvd[3]; // Make alignment
+} WSC_CREDENTIAL, *PWSC_CREDENTIAL;
+
+// WSC configured profiles
+typedef struct _WSC_PROFILE
+{
+ UINT ProfileCnt;
+ WSC_CREDENTIAL Profile[8]; // Support up to 8 profiles
+} WSC_PROFILE, *PWSC_PROFILE;
+
+
+
+#endif // _OID_H_
+
diff --git a/drivers/staging/rt3070/rt2870.h b/drivers/staging/rt3070/rt2870.h
new file mode 100644
index 00000000000..d32a2bf1d04
--- /dev/null
+++ b/drivers/staging/rt3070/rt2870.h
@@ -0,0 +1,756 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __RT2870_H__
+#define __RT2870_H__
+
+//usb header files
+#include <linux/usb.h>
+
+/* rtmp_def.h */
+//
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define BULKAGGRE_ZISE 100
+#define RT28XX_DRVDATA_SET(_a) usb_set_intfdata(_a, pAd);
+#define RT28XX_PUT_DEVICE usb_put_dev
+#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso, GFP_ATOMIC)
+#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb, GFP_ATOMIC)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) usb_buffer_alloc(pUsb_Dev, BufSize, GFP_ATOMIC, pDma_addr)
+#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) usb_buffer_free(pUsb_Dev, BufSize, pTransferBuf, Dma_addr)
+#else
+#define BULKAGGRE_ZISE 60
+#define RT28XX_DRVDATA_SET(_a)
+#define RT28XX_PUT_DEVICE(dev_p)
+#define RTUSB_ALLOC_URB(iso) usb_alloc_urb(iso)
+#define RTUSB_SUBMIT_URB(pUrb) usb_submit_urb(pUrb)
+#define RTUSB_URB_ALLOC_BUFFER(pUsb_Dev, BufSize, pDma_addr) kmalloc(BufSize, GFP_ATOMIC)
+#define RTUSB_URB_FREE_BUFFER(pUsb_Dev, BufSize, pTransferBuf, Dma_addr) kfree(pTransferBuf)
+#endif
+
+#define RXBULKAGGRE_ZISE 12
+#define MAX_TXBULK_LIMIT (LOCAL_TXBUF_SIZE*(BULKAGGRE_ZISE-1))
+#define MAX_TXBULK_SIZE (LOCAL_TXBUF_SIZE*BULKAGGRE_ZISE)
+#define MAX_RXBULK_SIZE (LOCAL_TXBUF_SIZE*RXBULKAGGRE_ZISE)
+#define MAX_MLME_HANDLER_MEMORY 20
+#define BUFFER_SIZE 2400 //2048
+#define TX_RING 0xa
+#define PRIO_RING 0xc
+
+
+// Flags for Bulkflags control for bulk out data
+//
+#define fRTUSB_BULK_OUT_DATA_NULL 0x00000001
+#define fRTUSB_BULK_OUT_RTS 0x00000002
+#define fRTUSB_BULK_OUT_MLME 0x00000004
+
+#define fRTUSB_BULK_OUT_DATA_NORMAL 0x00010000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_2 0x00020000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_3 0x00040000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_4 0x00080000
+#define fRTUSB_BULK_OUT_DATA_NORMAL_5 0x00100000
+
+#define fRTUSB_BULK_OUT_PSPOLL 0x00000020
+#define fRTUSB_BULK_OUT_DATA_FRAG 0x00000040
+#define fRTUSB_BULK_OUT_DATA_FRAG_2 0x00000080
+#define fRTUSB_BULK_OUT_DATA_FRAG_3 0x00000100
+#define fRTUSB_BULK_OUT_DATA_FRAG_4 0x00000200
+
+#ifdef RALINK_ATE
+#define fRTUSB_BULK_OUT_DATA_ATE 0x00100000
+#endif // RALINK_ATE //
+
+#define RT2870_USB_DEVICES \
+{ \
+ {USB_DEVICE(0x148F,0x2770)}, /* Ralink */ \
+ {USB_DEVICE(0x148F,0x2870)}, /* Ralink */ \
+ {USB_DEVICE(0x148F,0x3070)}, /* Ralink 3070 */ \
+ {USB_DEVICE(0x148F,0x3071)}, /* Ralink 3071 */ \
+ {USB_DEVICE(0x148F,0x3072)}, /* Ralink 3072 */ \
+ {USB_DEVICE(0x0B05,0x1731)}, /* Asus */ \
+ {USB_DEVICE(0x0B05,0x1732)}, /* Asus */ \
+ {USB_DEVICE(0x0B05,0x1742)}, /* Asus */ \
+ {USB_DEVICE(0x0DF6,0x0017)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x002B)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x002C)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x003E)}, /* Sitecom 3070 */ \
+ {USB_DEVICE(0x0DF6,0x002D)}, /* Sitecom */ \
+ {USB_DEVICE(0x0DF6,0x0039)}, /* Sitecom 2770 */ \
+ {USB_DEVICE(0x14B2,0x3C06)}, /* Conceptronic */ \
+ {USB_DEVICE(0x14B2,0x3C28)}, /* Conceptronic */ \
+ {USB_DEVICE(0x2019,0xED06)}, /* Planex Communications, Inc. */ \
+ {USB_DEVICE(0x2019,0xAB25)}, /* Planex Communications, Inc. RT3070 */ \
+ {USB_DEVICE(0x07D1,0x3C09)}, /* D-Link */ \
+ {USB_DEVICE(0x07D1,0x3C11)}, /* D-Link */ \
+ {USB_DEVICE(0x2001,0x3C09)}, /* D-Link */ \
+ {USB_DEVICE(0x2001,0x3C0A)}, /* D-Link 3072*/ \
+ {USB_DEVICE(0x14B2,0x3C07)}, /* AL */ \
+ {USB_DEVICE(0x14B2,0x3C12)}, /* AL 3070 */ \
+ {USB_DEVICE(0x050D,0x8053)}, /* Belkin */ \
+ {USB_DEVICE(0x14B2,0x3C23)}, /* Airlink */ \
+ {USB_DEVICE(0x14B2,0x3C27)}, /* Airlink */ \
+ {USB_DEVICE(0x07AA,0x002F)}, /* Corega */ \
+ {USB_DEVICE(0x07AA,0x003C)}, /* Corega */ \
+ {USB_DEVICE(0x07AA,0x003F)}, /* Corega */ \
+ {USB_DEVICE(0x18C5,0x0012)}, /* Corega 3070 */ \
+ {USB_DEVICE(0x1044,0x800B)}, /* Gigabyte */ \
+ {USB_DEVICE(0x1044,0x800D)}, /* Gigabyte GN-WB32L 3070 */ \
+ {USB_DEVICE(0x15A9,0x0006)}, /* Sparklan */ \
+ {USB_DEVICE(0x083A,0xB522)}, /* SMC */ \
+ {USB_DEVICE(0x083A,0xA618)}, /* SMC */ \
+ {USB_DEVICE(0x083A,0x8522)}, /* Arcadyan */ \
+ {USB_DEVICE(0x083A,0x7512)}, /* Arcadyan 2770 */ \
+ {USB_DEVICE(0x083A,0x7522)}, /* Arcadyan */ \
+ {USB_DEVICE(0x083A,0x7511)}, /* Arcadyan 3070 */ \
+ {USB_DEVICE(0x0CDE,0x0022)}, /* ZCOM */ \
+ {USB_DEVICE(0x0586,0x3416)}, /* Zyxel */ \
+ {USB_DEVICE(0x0CDE,0x0025)}, /* Zyxel */ \
+ {USB_DEVICE(0x1740,0x9701)}, /* EnGenius */ \
+ {USB_DEVICE(0x1740,0x9702)}, /* EnGenius */ \
+ {USB_DEVICE(0x1740,0x9703)}, /* EnGenius 3070 */ \
+ {USB_DEVICE(0x0471,0x200f)}, /* Philips */ \
+ {USB_DEVICE(0x14B2,0x3C25)}, /* Draytek */ \
+ {USB_DEVICE(0x13D3,0x3247)}, /* AzureWave */ \
+ {USB_DEVICE(0x13D3,0x3273)}, /* AzureWave 3070*/ \
+ {USB_DEVICE(0x083A,0x6618)}, /* Accton */ \
+ {USB_DEVICE(0x15c5,0x0008)}, /* Amit */ \
+ {USB_DEVICE(0x0E66,0x0001)}, /* Hawking */ \
+ {USB_DEVICE(0x0E66,0x0003)}, /* Hawking */ \
+ {USB_DEVICE(0x129B,0x1828)}, /* Siemens */ \
+ {USB_DEVICE(0x157E,0x300E)}, /* U-Media */ \
+ {USB_DEVICE(0x050d,0x805c)}, \
+ {USB_DEVICE(0x1482,0x3C09)}, /* Abocom*/ \
+ {USB_DEVICE(0x14B2,0x3C09)}, /* Alpha */ \
+ {USB_DEVICE(0x04E8,0x2018)}, /* samsung */ \
+ {USB_DEVICE(0x07B8,0x3070)}, /* AboCom 3070 */ \
+ {USB_DEVICE(0x07B8,0x3071)}, /* AboCom 3071 */ \
+ {USB_DEVICE(0x07B8,0x3072)}, /* Abocom 3072 */ \
+ {USB_DEVICE(0x7392,0x7711)}, /* Edimax 3070 */ \
+ {USB_DEVICE(0x5A57,0x0280)}, /* Zinwell */ \
+ {USB_DEVICE(0x5A57,0x0282)}, /* Zinwell */ \
+ {USB_DEVICE(0x1A32,0x0304)}, /* Quanta 3070 */ \
+ {USB_DEVICE(0x0789,0x0162)}, /* Logitec 2870 */ \
+ {USB_DEVICE(0x0789,0x0163)}, /* Logitec 2870 */ \
+ {USB_DEVICE(0x0789,0x0164)}, /* Logitec 2870 */ \
+ {USB_DEVICE(0x1EDA,0x2310)}, /* AirTies 3070 */ \
+ { }/* Terminating entry */ \
+}
+
+#define FREE_HTTX_RING(_p, _b, _t) \
+{ \
+ if ((_t)->ENextBulkOutPosition == (_t)->CurWritePosition) \
+ { \
+ (_t)->bRingEmpty = TRUE; \
+ } \
+ /*NdisInterlockedDecrement(&(_p)->TxCount); */\
+}
+
+//
+// RXINFO appends at the end of each rx packet.
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _RXINFO_STRUC {
+ UINT32 PlcpSignal:12;
+ UINT32 LastAMSDU:1;
+ UINT32 CipherAlg:1;
+ UINT32 PlcpRssil:1;
+ UINT32 Decrypted:1;
+ UINT32 AMPDU:1; // To be moved
+ UINT32 L2PAD:1;
+ UINT32 RSSI:1;
+ UINT32 HTC:1;
+ UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
+ UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+ UINT32 Crc:1; // 1: CRC error
+ UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
+ UINT32 Bcast:1; // 1: this is a broadcast frame
+ UINT32 Mcast:1; // 1: this is a multicast frame
+ UINT32 U2M:1; // 1: this RX frame is unicast to me
+ UINT32 FRAG:1;
+ UINT32 NULLDATA:1;
+ UINT32 DATA:1;
+ UINT32 BA:1;
+} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#else
+typedef struct PACKED _RXINFO_STRUC {
+ UINT32 BA:1;
+ UINT32 DATA:1;
+ UINT32 NULLDATA:1;
+ UINT32 FRAG:1;
+ UINT32 U2M:1; // 1: this RX frame is unicast to me
+ UINT32 Mcast:1; // 1: this is a multicast frame
+ UINT32 Bcast:1; // 1: this is a broadcast frame
+ UINT32 MyBss:1; // 1: this frame belongs to the same BSSID
+ UINT32 Crc:1; // 1: CRC error
+ UINT32 CipherErr:2; // 0: decryption okay, 1:ICV error, 2:MIC error, 3:KEY not valid
+ UINT32 AMSDU:1; // rx with 802.3 header, not 802.11 header.
+ UINT32 HTC:1;
+ UINT32 RSSI:1;
+ UINT32 L2PAD:1;
+ UINT32 AMPDU:1; // To be moved
+ UINT32 Decrypted:1;
+ UINT32 PlcpRssil:1;
+ UINT32 CipherAlg:1;
+ UINT32 LastAMSDU:1;
+ UINT32 PlcpSignal:12;
+} RXINFO_STRUC, *PRXINFO_STRUC, RT28XX_RXD_STRUC, *PRT28XX_RXD_STRUC;
+#endif
+
+
+//
+// TXINFO
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct _TXINFO_STRUC {
+ // Word 0
+ UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
+ UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
+ UINT32 rsv2:2; // Software use.
+ UINT32 SwUseLastRound:1; // Software use.
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 rsv:8;
+ UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
+} TXINFO_STRUC, *PTXINFO_STRUC;
+#else
+typedef struct _TXINFO_STRUC {
+ // Word 0
+ UINT32 USBDMATxPktLen:16; //used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame.
+ UINT32 rsv:8;
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 SwUseLastRound:1; // Software use.
+ UINT32 rsv2:2; // Software use.
+ UINT32 USBDMANextVLD:1; //used ONLY in USB bulk Aggregation, NextValid
+ UINT32 USBDMATxburst:1;//used ONLY in USB bulk Aggre. Force USB DMA transmit frame from current selected endpoint
+} TXINFO_STRUC, *PTXINFO_STRUC;
+#endif
+
+#define TXINFO_SIZE 4
+#define RXINFO_SIZE 4
+#define TXPADDING_SIZE 11
+
+//
+// Management ring buffer format
+//
+typedef struct _MGMT_STRUC {
+ BOOLEAN Valid;
+ PUCHAR pBuffer;
+ ULONG Length;
+} MGMT_STRUC, *PMGMT_STRUC;
+
+
+/* ----------------- EEPROM Related MACRO ----------------- */
+#ifdef RT30xx
+#define RT28xx_EEPROM_READ16(pAd, offset, var) \
+ do { \
+ RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \
+ if(!pAd->bUseEfuse) \
+ var = le2cpu16(var); \
+ }while(0)
+
+#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
+ do{ \
+ USHORT _tmpVar=var; \
+ if(!pAd->bUseEfuse) \
+ _tmpVar = cpu2le16(var); \
+ RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \
+ }while(0)
+#endif // RT30xx //
+#ifndef RT30xx
+#define RT28xx_EEPROM_READ16(pAd, offset, var) \
+ do { \
+ RTUSBReadEEPROM(pAd, offset, (PUCHAR)&(var), 2); \
+ var = le2cpu16(var); \
+ }while(0)
+
+#define RT28xx_EEPROM_WRITE16(pAd, offset, var) \
+ do{ \
+ USHORT _tmpVar=var; \
+ _tmpVar = cpu2le16(var); \
+ RTUSBWriteEEPROM(pAd, offset, (PUCHAR)&(_tmpVar), 2); \
+ }while(0)
+#endif // RT30xx //
+
+/* ----------------- TASK/THREAD Related MACRO ----------------- */
+#define RT28XX_TASK_THREAD_INIT(pAd, Status) \
+ Status = CreateThreads(net_dev);
+
+
+/* ----------------- Frimware Related MACRO ----------------- */
+#define RT28XX_WRITE_FIRMWARE(_pAd, _pFwImage, _FwLen) \
+ RTUSBFirmwareWrite(_pAd, _pFwImage, _FwLen)
+
+/* ----------------- TX Related MACRO ----------------- */
+#define RT28XX_START_DEQUEUE(pAd, QueIdx, irqFlags) \
+ { \
+ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ if (pAd->DeQueueRunning[QueIdx]) \
+ { \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+ printk("DeQueueRunning[%d]= TRUE!\n", QueIdx); \
+ continue; \
+ } \
+ else \
+ { \
+ pAd->DeQueueRunning[QueIdx] = TRUE; \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags);\
+ } \
+ }
+#define RT28XX_STOP_DEQUEUE(pAd, QueIdx, irqFlags) \
+ do{ \
+ RTMP_IRQ_LOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ pAd->DeQueueRunning[QueIdx] = FALSE; \
+ RTMP_IRQ_UNLOCK(&pAd->DeQueueLock[QueIdx], irqFlags); \
+ }while(0)
+
+
+#define RT28XX_HAS_ENOUGH_FREE_DESC(pAd, pTxBlk, freeNum, pPacket) \
+ (RTUSBFreeDescriptorRequest(pAd, pTxBlk->QueIdx, (pTxBlk->TotalFrameLen + GET_OS_PKT_LEN(pPacket))) == NDIS_STATUS_SUCCESS)
+
+#define RT28XX_RELEASE_DESC_RESOURCE(pAd, QueIdx) \
+ do{}while(0)
+
+#define NEED_QUEUE_BACK_FOR_AGG(_pAd, _QueIdx, _freeNum, _TxFrameType) \
+ ((_TxFrameType == TX_RALINK_FRAME) && (RTUSBNeedQueueBackForAgg(_pAd, _QueIdx)))
+
+
+
+#define fRTMP_ADAPTER_NEED_STOP_TX \
+ (fRTMP_ADAPTER_NIC_NOT_EXIST | fRTMP_ADAPTER_HALT_IN_PROGRESS | \
+ fRTMP_ADAPTER_RESET_IN_PROGRESS | fRTMP_ADAPTER_BULKOUT_RESET | \
+ fRTMP_ADAPTER_RADIO_OFF | fRTMP_ADAPTER_REMOVE_IN_PROGRESS)
+
+
+#define HAL_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber) \
+ RtmpUSB_WriteSubTxResource(pAd, pTxBlk, bIsLast, pFreeNumber)
+
+#define HAL_WriteTxResource(pAd, pTxBlk,bIsLast, pFreeNumber) \
+ RtmpUSB_WriteSingleTxResource(pAd, pTxBlk,bIsLast, pFreeNumber)
+
+#define HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber) \
+ RtmpUSB_WriteFragTxResource(pAd, pTxBlk, fragNum, pFreeNumber)
+
+#define HAL_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber) \
+ RtmpUSB_WriteMultiTxResource(pAd, pTxBlk,frameNum, pFreeNumber)
+
+#define HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx) \
+ RtmpUSB_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, TxIdx)
+
+#define HAL_LastTxIdx(pAd, QueIdx,TxIdx) \
+ /*RtmpUSBDataLastTxIdx(pAd, QueIdx,TxIdx)*/
+
+#define HAL_KickOutTx(pAd, pTxBlk, QueIdx) \
+ RtmpUSBDataKickOut(pAd, pTxBlk, QueIdx)
+
+
+#define HAL_KickOutMgmtTx(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen) \
+ RtmpUSBMgmtKickOut(pAd, QueIdx, pPacket, pSrcBufVA, SrcBufLen)
+
+#define HAL_KickOutNullFrameTx(_pAd, _QueIdx, _pNullFrame, _frameLen) \
+ RtmpUSBNullFrameKickOut(_pAd, _QueIdx, _pNullFrame, _frameLen)
+
+#define RTMP_PKT_TAIL_PADDING 11 // 3(max 4 byte padding) + 4 (last packet padding) + 4 (MaxBulkOutsize align padding)
+
+extern UCHAR EpToQueue[6];
+
+
+#ifdef RT2870
+#define GET_TXRING_FREENO(_pAd, _QueIdx) (_QueIdx) //(_pAd->TxRing[_QueIdx].TxSwFreeIdx)
+#define GET_MGMTRING_FREENO(_pAd) (_pAd->MgmtRing.TxSwFreeIdx)
+#endif // RT2870 //
+
+
+/* ----------------- RX Related MACRO ----------------- */
+//#define RT28XX_RX_ERROR_CHECK RTMPCheckRxWI
+
+#define RT28XX_RV_ALL_BUF_END(bBulkReceive) \
+ /* We return STATUS_MORE_PROCESSING_REQUIRED so that the completion */ \
+ /* routine (IofCompleteRequest) will stop working on the irp. */ \
+ if (bBulkReceive == TRUE) RTUSBBulkReceive(pAd);
+
+
+/* ----------------- ASIC Related MACRO ----------------- */
+// reset MAC of a station entry to 0xFFFFFFFFFFFF
+#define RT28XX_STA_ENTRY_MAC_RESET(pAd, Wcid) \
+ { RT_SET_ASIC_WCID SetAsicWcid; \
+ SetAsicWcid.WCID = Wcid; \
+ SetAsicWcid.SetTid = 0xffffffff; \
+ SetAsicWcid.DeleteTid = 0xffffffff; \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID, \
+ &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); }
+
+// add this entry into ASIC RX WCID search table
+#define RT28XX_STA_ENTRY_ADD(pAd, pEntry) \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_CLIENT_MAC_ENTRY, \
+ pEntry, sizeof(MAC_TABLE_ENTRY));
+
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+// Set MAC register value according operation mode
+#define RT28XX_UPDATE_PROTECT(pAd) \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_UPDATE_PROTECT, NULL, 0);
+// end johnli
+
+// remove Pair-wise key material from ASIC
+// yet implement
+#define RT28XX_STA_ENTRY_KEY_DEL(pAd, BssIdx, Wcid)
+
+// add Client security information into ASIC WCID table and IVEIV table
+#define RT28XX_STA_SECURITY_INFO_ADD(pAd, apidx, KeyID, pEntry) \
+ { RT28XX_STA_ENTRY_MAC_RESET(pAd, pEntry->Aid); \
+ if (pEntry->Aid >= 1) { \
+ RT_SET_ASIC_WCID_ATTRI SetAsicWcidAttri; \
+ SetAsicWcidAttri.WCID = pEntry->Aid; \
+ if ((pEntry->AuthMode <= Ndis802_11AuthModeAutoSwitch) && \
+ (pEntry->WepStatus == Ndis802_11Encryption1Enabled)) \
+ { \
+ SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
+ } \
+ else if (pEntry->AuthMode == Ndis802_11AuthModeWPANone) \
+ { \
+ SetAsicWcidAttri.Cipher = pAd->SharedKey[apidx][KeyID].CipherAlg; \
+ } \
+ else SetAsicWcidAttri.Cipher = 0; \
+ DBGPRINT(RT_DEBUG_TRACE, ("aid cipher = %ld\n",SetAsicWcidAttri.Cipher)); \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_SET_ASIC_WCID_CIPHER, \
+ &SetAsicWcidAttri, sizeof(RT_SET_ASIC_WCID_ATTRI)); } }
+
+// Insert the BA bitmap to ASIC for the Wcid entry
+#define RT28XX_ADD_BA_SESSION_TO_ASIC(_pAd, _Aid, _TID) \
+ do{ \
+ RT_SET_ASIC_WCID SetAsicWcid; \
+ SetAsicWcid.WCID = (_Aid); \
+ SetAsicWcid.SetTid = (0x10000<<(_TID)); \
+ SetAsicWcid.DeleteTid = 0xffffffff; \
+ RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
+ }while(0)
+
+// Remove the BA bitmap from ASIC for the Wcid entry
+#define RT28XX_DEL_BA_SESSION_FROM_ASIC(_pAd, _Wcid, _TID) \
+ do{ \
+ RT_SET_ASIC_WCID SetAsicWcid; \
+ SetAsicWcid.WCID = (_Wcid); \
+ SetAsicWcid.SetTid = (0xffffffff); \
+ SetAsicWcid.DeleteTid = (0x10000<<(_TID) ); \
+ RTUSBEnqueueInternalCmd((_pAd), CMDTHREAD_SET_ASIC_WCID, &SetAsicWcid, sizeof(RT_SET_ASIC_WCID)); \
+ }while(0)
+
+
+/* ----------------- PCI/USB Related MACRO ----------------- */
+#define RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p) \
+ ((POS_COOKIE)handle)->pUsb_Dev = dev_p;
+
+// no use
+#define RT28XX_UNMAP()
+#define RT28XX_IRQ_REQUEST(net_dev)
+#define RT28XX_IRQ_RELEASE(net_dev)
+#define RT28XX_IRQ_INIT(pAd)
+#define RT28XX_IRQ_ENABLE(pAd)
+
+
+/* ----------------- MLME Related MACRO ----------------- */
+#define RT28XX_MLME_HANDLER(pAd) RTUSBMlmeUp(pAd)
+
+#define RT28XX_MLME_PRE_SANITY_CHECK(pAd) \
+ { if ((pAd->CommonCfg.bHardwareRadio == TRUE) && \
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) && \
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))) { \
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_CHECK_GPIO, NULL, 0); } }
+
+#define RT28XX_MLME_STA_QUICK_RSP_WAKE_UP(pAd) \
+ { RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_QKERIODIC_EXECUT, NULL, 0); \
+ RTUSBMlmeUp(pAd); }
+
+#define RT28XX_MLME_RESET_STATE_MACHINE(pAd) \
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_RESET_CONF, 0, NULL); \
+ RTUSBMlmeUp(pAd);
+
+#define RT28XX_HANDLE_COUNTER_MEASURE(_pAd, _pEntry) \
+ { RTUSBEnqueueInternalCmd(_pAd, CMDTHREAD_802_11_COUNTER_MEASURE, _pEntry, sizeof(MAC_TABLE_ENTRY)); \
+ RTUSBMlmeUp(_pAd); \
+ }
+
+
+/* ----------------- Power Save Related MACRO ----------------- */
+#define RT28XX_PS_POLL_ENQUEUE(pAd) \
+ { RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_PSPOLL); \
+ RTUSBKickBulkOut(pAd); }
+
+#define RT28xx_CHIP_NAME "RT2870"
+#define USB_CYC_CFG 0x02a4
+#define NT_SUCCESS(status) (((status) > 0) ? (1):(0))
+#define InterlockedIncrement atomic_inc
+#define NdisInterlockedIncrement atomic_inc
+#define InterlockedDecrement atomic_dec
+#define NdisInterlockedDecrement atomic_dec
+#define InterlockedExchange atomic_set
+//#define NdisMSendComplete RTMP_SendComplete
+#define NdisMCancelTimer RTMPCancelTimer
+#define NdisAllocMemory(_ptr, _size, _flag) \
+ do{_ptr = kmalloc((_size),(_flag));}while(0)
+#define NdisFreeMemory(a, b, c) kfree((a))
+#define NdisMSleep RTMPusecDelay /* unit: microsecond */
+
+
+#define USBD_TRANSFER_DIRECTION_OUT 0
+#define USBD_TRANSFER_DIRECTION_IN 0
+#define USBD_SHORT_TRANSFER_OK 0
+#define PURB purbb_t
+
+#define RTUSB_FREE_URB(pUrb) usb_free_urb(pUrb)
+
+//#undef MlmeAllocateMemory
+//#undef MlmeFreeMemory
+
+typedef struct usb_device * PUSB_DEV;
+
+/* MACRO for linux usb */
+typedef struct urb *purbb_t;
+typedef struct usb_ctrlrequest devctrlrequest;
+#define PIRP PVOID
+#define PMDL PVOID
+#define NDIS_OID UINT
+#ifndef USB_ST_NOERROR
+#define USB_ST_NOERROR 0
+#endif
+
+// vendor-specific control operations
+#define CONTROL_TIMEOUT_JIFFIES ( (100 * HZ) / 1000)
+#define UNLINK_TIMEOUT_MS 3
+
+/* unlink urb */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,7)
+#define RTUSB_UNLINK_URB(pUrb) usb_kill_urb(pUrb)
+#else
+#define RTUSB_UNLINK_URB(pUrb) usb_unlink_urb(pUrb)
+#endif
+
+// Prototypes of completion funuc.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define RTUSBBulkOutDataPacketComplete(purb, pt_regs) RTUSBBulkOutDataPacketComplete(purb)
+#define RTUSBBulkOutMLMEPacketComplete(pUrb, pt_regs) RTUSBBulkOutMLMEPacketComplete(pUrb)
+#define RTUSBBulkOutNullFrameComplete(pUrb, pt_regs) RTUSBBulkOutNullFrameComplete(pUrb)
+#define RTUSBBulkOutRTSFrameComplete(pUrb, pt_regs) RTUSBBulkOutRTSFrameComplete(pUrb)
+#define RTUSBBulkOutPsPollComplete(pUrb, pt_regs) RTUSBBulkOutPsPollComplete(pUrb)
+#define RTUSBBulkRxComplete(pUrb, pt_regs) RTUSBBulkRxComplete(pUrb)
+#endif
+
+
+VOID RTUSBBulkOutDataPacketComplete(purbb_t purb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutMLMEPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutNullFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutRTSFrameComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkOutPsPollComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+VOID RTUSBBulkRxComplete(purbb_t pUrb, struct pt_regs *pt_regs);
+
+
+#define RTUSBMlmeUp(pAd) \
+{ \
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
+ if(pObj->MLMEThr_pid>0) \
+ up(&(pAd->mlme_semaphore)); \
+}
+
+#define RTUSBCMDUp(pAd) \
+{ \
+ POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; \
+ if(pObj->RTUSBCmdThr_pid>0) \
+ up(&(pAd->RTUSBCmd_semaphore)); \
+}
+
+
+static inline NDIS_STATUS RTMPAllocateMemory(
+ OUT PVOID *ptr,
+ IN size_t size)
+{
+ *ptr = kmalloc(size, GFP_ATOMIC);
+ if(*ptr)
+ return NDIS_STATUS_SUCCESS;
+ else
+ return NDIS_STATUS_RESOURCES;
+}
+
+/* rtmp.h */
+#define BEACON_RING_SIZE 2
+#define DEVICE_VENDOR_REQUEST_OUT 0x40
+#define DEVICE_VENDOR_REQUEST_IN 0xc0
+#define INTERFACE_VENDOR_REQUEST_OUT 0x41
+#define INTERFACE_VENDOR_REQUEST_IN 0xc1
+#define MGMTPIPEIDX 0 // EP6 is highest priority
+
+#define BULKOUT_MGMT_RESET_FLAG 0x80
+
+#define RTUSB_SET_BULK_FLAG(_M, _F) ((_M)->BulkFlags |= (_F))
+#define RTUSB_CLEAR_BULK_FLAG(_M, _F) ((_M)->BulkFlags &= ~(_F))
+#define RTUSB_TEST_BULK_FLAG(_M, _F) (((_M)->BulkFlags & (_F)) != 0)
+
+#define EnqueueCmd(cmdq, cmdqelmt) \
+{ \
+ if (cmdq->size == 0) \
+ cmdq->head = cmdqelmt; \
+ else \
+ cmdq->tail->next = cmdqelmt; \
+ cmdq->tail = cmdqelmt; \
+ cmdqelmt->next = NULL; \
+ cmdq->size++; \
+}
+
+typedef struct _RT_SET_ASIC_WCID {
+ ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+ ULONG SetTid; // time-based: seconds, packet-based: kilo-packets
+ ULONG DeleteTid; // time-based: seconds, packet-based: kilo-packets
+} RT_SET_ASIC_WCID,*PRT_SET_ASIC_WCID;
+
+typedef struct _RT_SET_ASIC_WCID_ATTRI {
+ ULONG WCID; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+ ULONG Cipher; // ASIC Cipher definition
+ UCHAR Addr[ETH_LENGTH_OF_ADDRESS];
+} RT_SET_ASIC_WCID_ATTRI,*PRT_SET_ASIC_WCID_ATTRI;
+
+typedef struct _MLME_MEMORY_STRUCT {
+ PVOID AllocVa; //Pointer to the base virtual address of the allocated memory
+ struct _MLME_MEMORY_STRUCT *Next; //Pointer to the next virtual address of the allocated memory
+} MLME_MEMORY_STRUCT, *PMLME_MEMORY_STRUCT;
+
+typedef struct _MLME_MEMORY_HANDLER {
+ BOOLEAN MemRunning; //The flag of the Mlme memory handler's status
+ UINT MemoryCount; //Total nonpaged system-space memory not size
+ UINT InUseCount; //Nonpaged system-space memory in used counts
+ UINT UnUseCount; //Nonpaged system-space memory available counts
+ INT PendingCount; //Nonpaged system-space memory for free counts
+ PMLME_MEMORY_STRUCT pInUseHead; //Pointer to the first nonpaed memory not used
+ PMLME_MEMORY_STRUCT pInUseTail; //Pointer to the last nonpaged memory not used
+ PMLME_MEMORY_STRUCT pUnUseHead; //Pointer to the first nonpaged memory in used
+ PMLME_MEMORY_STRUCT pUnUseTail; //Pointer to the last nonpaged memory in used
+ PULONG MemFreePending[MAX_MLME_HANDLER_MEMORY]; //an array to keep pending free-memory's pointer (32bits)
+} MLME_MEMORY_HANDLER, *PMLME_MEMORY_HANDLER;
+
+typedef struct _CmdQElmt {
+ UINT command;
+ PVOID buffer;
+ ULONG bufferlength;
+ BOOLEAN CmdFromNdis;
+ BOOLEAN SetOperation;
+ struct _CmdQElmt *next;
+} CmdQElmt, *PCmdQElmt;
+
+typedef struct _CmdQ {
+ UINT size;
+ CmdQElmt *head;
+ CmdQElmt *tail;
+ UINT32 CmdQState;
+}CmdQ, *PCmdQ;
+
+//
+// For WPA SUPPLICANT: WIRELESS EXT support wireless events: v14 or newer
+//
+#if WIRELESS_EXT >= 14
+//#define WPA_SUPPLICANT_SUPPORT 1
+#endif
+
+/* oid.h */
+// Cipher suite type for mixed mode group cipher, P802.11i-2004
+typedef enum _RT_802_11_CIPHER_SUITE_TYPE {
+ Cipher_Type_NONE,
+ Cipher_Type_WEP40,
+ Cipher_Type_TKIP,
+ Cipher_Type_RSVD,
+ Cipher_Type_CCMP,
+ Cipher_Type_WEP104
+} RT_802_11_CIPHER_SUITE_TYPE, *PRT_802_11_CIPHER_SUITE_TYPE;
+
+//CMDTHREAD_MULTI_READ_MAC
+//CMDTHREAD_MULTI_WRITE_MAC
+//CMDTHREAD_VENDOR_EEPROM_READ
+//CMDTHREAD_VENDOR_EEPROM_WRITE
+typedef struct _CMDHandler_TLV {
+ USHORT Offset;
+ USHORT Length;
+ UCHAR DataFirst;
+} CMDHandler_TLV, *PCMDHandler_TLV;
+
+// New for MeetingHouse Api support
+#define CMDTHREAD_VENDOR_RESET 0x0D730101 // cmd
+#define CMDTHREAD_VENDOR_UNPLUG 0x0D730102 // cmd
+#define CMDTHREAD_VENDOR_SWITCH_FUNCTION 0x0D730103 // cmd
+#define CMDTHREAD_MULTI_WRITE_MAC 0x0D730107 // cmd
+#define CMDTHREAD_MULTI_READ_MAC 0x0D730108 // cmd
+#define CMDTHREAD_VENDOR_EEPROM_WRITE 0x0D73010A // cmd
+#define CMDTHREAD_VENDOR_EEPROM_READ 0x0D73010B // cmd
+#define CMDTHREAD_VENDOR_ENTER_TESTMODE 0x0D73010C // cmd
+#define CMDTHREAD_VENDOR_EXIT_TESTMODE 0x0D73010D // cmd
+#define CMDTHREAD_VENDOR_WRITE_BBP 0x0D730119 // cmd
+#define CMDTHREAD_VENDOR_READ_BBP 0x0D730118 // cmd
+#define CMDTHREAD_VENDOR_WRITE_RF 0x0D73011A // cmd
+#define CMDTHREAD_VENDOR_FLIP_IQ 0x0D73011D // cmd
+#define CMDTHREAD_RESET_BULK_OUT 0x0D730210 // cmd
+#define CMDTHREAD_RESET_BULK_IN 0x0D730211 // cmd
+#define CMDTHREAD_SET_PSM_BIT_SAVE 0x0D730212 // cmd
+#define CMDTHREAD_SET_RADIO 0x0D730214 // cmd
+#define CMDTHREAD_UPDATE_TX_RATE 0x0D730216 // cmd
+#define CMDTHREAD_802_11_ADD_KEY_WEP 0x0D730218 // cmd
+#define CMDTHREAD_RESET_FROM_ERROR 0x0D73021A // cmd
+#define CMDTHREAD_LINK_DOWN 0x0D73021B // cmd
+#define CMDTHREAD_RESET_FROM_NDIS 0x0D73021C // cmd
+#define CMDTHREAD_CHECK_GPIO 0x0D730215 // cmd
+#define CMDTHREAD_FORCE_WAKE_UP 0x0D730222 // cmd
+#define CMDTHREAD_SET_BW 0x0D730225 // cmd
+#define CMDTHREAD_SET_ASIC_WCID 0x0D730226 // cmd
+#define CMDTHREAD_SET_ASIC_WCID_CIPHER 0x0D730227 // cmd
+#define CMDTHREAD_QKERIODIC_EXECUT 0x0D73023D // cmd
+#define RT_CMD_SET_KEY_TABLE 0x0D730228 // cmd
+#define RT_CMD_SET_RX_WCID_TABLE 0x0D730229 // cmd
+#define CMDTHREAD_SET_CLIENT_MAC_ENTRY 0x0D73023E // cmd
+#define CMDTHREAD_802_11_QUERY_HARDWARE_REGISTER 0x0D710105 // cmd
+#define CMDTHREAD_802_11_SET_PHY_MODE 0x0D79010C // cmd
+#define CMDTHREAD_802_11_SET_STA_CONFIG 0x0D790111 // cmd
+#define CMDTHREAD_802_11_SET_PREAMBLE 0x0D790101 // cmd
+#define CMDTHREAD_802_11_COUNTER_MEASURE 0x0D790102 // cmd
+// add by johnli, fix "in_interrupt" error when call "MacTableDeleteEntry" in Rx tasklet
+#define CMDTHREAD_UPDATE_PROTECT 0x0D790103 // cmd
+// end johnli
+
+#define WPA1AKMBIT 0x01
+#define WPA2AKMBIT 0x02
+#define WPA1PSKAKMBIT 0x04
+#define WPA2PSKAKMBIT 0x08
+#define TKIPBIT 0x01
+#define CCMPBIT 0x02
+
+
+#define RT28XX_STA_FORCE_WAKEUP(pAd, bFromTx) \
+ RT28xxUsbStaAsicForceWakeup(pAd, bFromTx);
+
+#define RT28XX_STA_SLEEP_THEN_AUTO_WAKEUP(pAd, TbttNumToNextWakeUp) \
+ RT28xxUsbStaAsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+
+#define RT28XX_MLME_RADIO_ON(pAd) \
+ RT28xxUsbMlmeRadioOn(pAd);
+
+#define RT28XX_MLME_RADIO_OFF(pAd) \
+ RT28xxUsbMlmeRadioOFF(pAd);
+
+#endif //__RT2870_H__
diff --git a/drivers/staging/rt3070/rt28xx.h b/drivers/staging/rt3070/rt28xx.h
new file mode 100644
index 00000000000..b637c4ee609
--- /dev/null
+++ b/drivers/staging/rt3070/rt28xx.h
@@ -0,0 +1,2725 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rt28xx.h
+
+ Abstract:
+ RT28xx ASIC related definition & structures
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee Jan-3-2006 created for RT2860c
+*/
+
+#ifndef __RT28XX_H__
+#define __RT28XX_H__
+
+
+//
+// PCI registers - base address 0x0000
+//
+#define PCI_CFG 0x0000
+#define PCI_EECTRL 0x0004
+#define PCI_MCUCTRL 0x0008
+
+#define OPT_14 0x114
+
+typedef int NTSTATUS;
+#define RETRY_LIMIT 10
+#define STATUS_SUCCESS 0x00
+#define STATUS_UNSUCCESSFUL 0x01
+
+//
+// SCH/DMA registers - base address 0x0200
+//
+// INT_SOURCE_CSR: Interrupt source register. Write one to clear corresponding bit
+//
+#define DMA_CSR0 0x200
+#define INT_SOURCE_CSR 0x200
+#ifdef RT_BIG_ENDIAN
+typedef union _INT_SOURCE_CSR_STRUC {
+ struct {
+ UINT32 :14;
+ UINT32 TxCoherent:1;
+ UINT32 RxCoherent:1;
+ UINT32 GPTimer:1;
+ UINT32 AutoWakeup:1;//bit14
+ UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
+ UINT32 PreTBTT:1;
+ UINT32 TBTTInt:1;
+ UINT32 RxTxCoherent:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 RxDone:1;
+ UINT32 TxDelayINT:1; //delayed interrupt, not interrupt until several int or time limit hit
+ UINT32 RxDelayINT:1; //dealyed interrupt
+ } field;
+ UINT32 word;
+} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+#else
+typedef union _INT_SOURCE_CSR_STRUC {
+ struct {
+ UINT32 RxDelayINT:1;
+ UINT32 TxDelayINT:1;
+ UINT32 RxDone:1;
+ UINT32 Ac0DmaDone:1;//4
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 HccaDmaDone:1; // bit7
+ UINT32 MgmtDmaDone:1;
+ UINT32 MCUCommandINT:1;//bit 9
+ UINT32 RxTxCoherent:1;
+ UINT32 TBTTInt:1;
+ UINT32 PreTBTT:1;
+ UINT32 TXFifoStatusInt:1;//FIFO Statistics is full, sw should read 0x171c
+ UINT32 AutoWakeup:1;//bit14
+ UINT32 GPTimer:1;
+ UINT32 RxCoherent:1;//bit16
+ UINT32 TxCoherent:1;
+ UINT32 :14;
+ } field;
+ UINT32 word;
+} INT_SOURCE_CSR_STRUC, *PINT_SOURCE_CSR_STRUC;
+#endif
+
+//
+// INT_MASK_CSR: Interrupt MASK register. 1: the interrupt is mask OFF
+//
+#define INT_MASK_CSR 0x204
+#ifdef RT_BIG_ENDIAN
+typedef union _INT_MASK_CSR_STRUC {
+ struct {
+ UINT32 TxCoherent:1;
+ UINT32 RxCoherent:1;
+ UINT32 :20;
+ UINT32 MCUCommandINT:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 RxDone:1;
+ UINT32 TxDelay:1;
+ UINT32 RXDelay_INT_MSK:1;
+ } field;
+ UINT32 word;
+}INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+#else
+typedef union _INT_MASK_CSR_STRUC {
+ struct {
+ UINT32 RXDelay_INT_MSK:1;
+ UINT32 TxDelay:1;
+ UINT32 RxDone:1;
+ UINT32 Ac0DmaDone:1;
+ UINT32 Ac1DmaDone:1;
+ UINT32 Ac2DmaDone:1;
+ UINT32 Ac3DmaDone:1;
+ UINT32 HccaDmaDone:1;
+ UINT32 MgmtDmaDone:1;
+ UINT32 MCUCommandINT:1;
+ UINT32 :20;
+ UINT32 RxCoherent:1;
+ UINT32 TxCoherent:1;
+ } field;
+ UINT32 word;
+} INT_MASK_CSR_STRUC, *PINT_MASK_CSR_STRUC;
+#endif
+#define WPDMA_GLO_CFG 0x208
+#ifdef RT_BIG_ENDIAN
+typedef union _WPDMA_GLO_CFG_STRUC {
+ struct {
+ UINT32 HDR_SEG_LEN:16;
+ UINT32 RXHdrScater:8;
+ UINT32 BigEndian:1;
+ UINT32 EnTXWriteBackDDONE:1;
+ UINT32 WPDMABurstSIZE:2;
+ UINT32 RxDMABusy:1;
+ UINT32 EnableRxDMA:1;
+ UINT32 TxDMABusy:1;
+ UINT32 EnableTxDMA:1;
+ } field;
+ UINT32 word;
+}WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+#else
+typedef union _WPDMA_GLO_CFG_STRUC {
+ struct {
+ UINT32 EnableTxDMA:1;
+ UINT32 TxDMABusy:1;
+ UINT32 EnableRxDMA:1;
+ UINT32 RxDMABusy:1;
+ UINT32 WPDMABurstSIZE:2;
+ UINT32 EnTXWriteBackDDONE:1;
+ UINT32 BigEndian:1;
+ UINT32 RXHdrScater:8;
+ UINT32 HDR_SEG_LEN:16;
+ } field;
+ UINT32 word;
+} WPDMA_GLO_CFG_STRUC, *PWPDMA_GLO_CFG_STRUC;
+#endif
+#define WPDMA_RST_IDX 0x20c
+#ifdef RT_BIG_ENDIAN
+typedef union _WPDMA_RST_IDX_STRUC {
+ struct {
+ UINT32 :15;
+ UINT32 RST_DRX_IDX0:1;
+ UINT32 rsv:10;
+ UINT32 RST_DTX_IDX5:1;
+ UINT32 RST_DTX_IDX4:1;
+ UINT32 RST_DTX_IDX3:1;
+ UINT32 RST_DTX_IDX2:1;
+ UINT32 RST_DTX_IDX1:1;
+ UINT32 RST_DTX_IDX0:1;
+ } field;
+ UINT32 word;
+}WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#else
+typedef union _WPDMA_RST_IDX_STRUC {
+ struct {
+ UINT32 RST_DTX_IDX0:1;
+ UINT32 RST_DTX_IDX1:1;
+ UINT32 RST_DTX_IDX2:1;
+ UINT32 RST_DTX_IDX3:1;
+ UINT32 RST_DTX_IDX4:1;
+ UINT32 RST_DTX_IDX5:1;
+ UINT32 rsv:10;
+ UINT32 RST_DRX_IDX0:1;
+ UINT32 :15;
+ } field;
+ UINT32 word;
+} WPDMA_RST_IDX_STRUC, *PWPDMA_RST_IDX_STRUC;
+#endif
+#define DELAY_INT_CFG 0x0210
+#ifdef RT_BIG_ENDIAN
+typedef union _DELAY_INT_CFG_STRUC {
+ struct {
+ UINT32 TXDLY_INT_EN:1;
+ UINT32 TXMAX_PINT:7;
+ UINT32 TXMAX_PTIME:8;
+ UINT32 RXDLY_INT_EN:1;
+ UINT32 RXMAX_PINT:7;
+ UINT32 RXMAX_PTIME:8;
+ } field;
+ UINT32 word;
+}DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#else
+typedef union _DELAY_INT_CFG_STRUC {
+ struct {
+ UINT32 RXMAX_PTIME:8;
+ UINT32 RXMAX_PINT:7;
+ UINT32 RXDLY_INT_EN:1;
+ UINT32 TXMAX_PTIME:8;
+ UINT32 TXMAX_PINT:7;
+ UINT32 TXDLY_INT_EN:1;
+ } field;
+ UINT32 word;
+} DELAY_INT_CFG_STRUC, *PDELAY_INT_CFG_STRUC;
+#endif
+#define WMM_AIFSN_CFG 0x0214
+#ifdef RT_BIG_ENDIAN
+typedef union _AIFSN_CSR_STRUC {
+ struct {
+ UINT32 Rsv:16;
+ UINT32 Aifsn3:4; // for AC_VO
+ UINT32 Aifsn2:4; // for AC_VI
+ UINT32 Aifsn1:4; // for AC_BK
+ UINT32 Aifsn0:4; // for AC_BE
+ } field;
+ UINT32 word;
+} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+#else
+typedef union _AIFSN_CSR_STRUC {
+ struct {
+ UINT32 Aifsn0:4; // for AC_BE
+ UINT32 Aifsn1:4; // for AC_BK
+ UINT32 Aifsn2:4; // for AC_VI
+ UINT32 Aifsn3:4; // for AC_VO
+ UINT32 Rsv:16;
+ } field;
+ UINT32 word;
+} AIFSN_CSR_STRUC, *PAIFSN_CSR_STRUC;
+#endif
+//
+// CWMIN_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMIN_CFG 0x0218
+#ifdef RT_BIG_ENDIAN
+typedef union _CWMIN_CSR_STRUC {
+ struct {
+ UINT32 Rsv:16;
+ UINT32 Cwmin3:4; // for AC_VO
+ UINT32 Cwmin2:4; // for AC_VI
+ UINT32 Cwmin1:4; // for AC_BK
+ UINT32 Cwmin0:4; // for AC_BE
+ } field;
+ UINT32 word;
+} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+#else
+typedef union _CWMIN_CSR_STRUC {
+ struct {
+ UINT32 Cwmin0:4; // for AC_BE
+ UINT32 Cwmin1:4; // for AC_BK
+ UINT32 Cwmin2:4; // for AC_VI
+ UINT32 Cwmin3:4; // for AC_VO
+ UINT32 Rsv:16;
+ } field;
+ UINT32 word;
+} CWMIN_CSR_STRUC, *PCWMIN_CSR_STRUC;
+#endif
+
+//
+// CWMAX_CSR: CWmin for each EDCA AC
+//
+#define WMM_CWMAX_CFG 0x021c
+#ifdef RT_BIG_ENDIAN
+typedef union _CWMAX_CSR_STRUC {
+ struct {
+ UINT32 Rsv:16;
+ UINT32 Cwmax3:4; // for AC_VO
+ UINT32 Cwmax2:4; // for AC_VI
+ UINT32 Cwmax1:4; // for AC_BK
+ UINT32 Cwmax0:4; // for AC_BE
+ } field;
+ UINT32 word;
+} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+#else
+typedef union _CWMAX_CSR_STRUC {
+ struct {
+ UINT32 Cwmax0:4; // for AC_BE
+ UINT32 Cwmax1:4; // for AC_BK
+ UINT32 Cwmax2:4; // for AC_VI
+ UINT32 Cwmax3:4; // for AC_VO
+ UINT32 Rsv:16;
+ } field;
+ UINT32 word;
+} CWMAX_CSR_STRUC, *PCWMAX_CSR_STRUC;
+#endif
+
+
+//
+// AC_TXOP_CSR0: AC_BK/AC_BE TXOP register
+//
+#define WMM_TXOP0_CFG 0x0220
+#ifdef RT_BIG_ENDIAN
+typedef union _AC_TXOP_CSR0_STRUC {
+ struct {
+ USHORT Ac1Txop; // for AC_BE, in unit of 32us
+ USHORT Ac0Txop; // for AC_BK, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+#else
+typedef union _AC_TXOP_CSR0_STRUC {
+ struct {
+ USHORT Ac0Txop; // for AC_BK, in unit of 32us
+ USHORT Ac1Txop; // for AC_BE, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR0_STRUC, *PAC_TXOP_CSR0_STRUC;
+#endif
+
+//
+// AC_TXOP_CSR1: AC_VO/AC_VI TXOP register
+//
+#define WMM_TXOP1_CFG 0x0224
+#ifdef RT_BIG_ENDIAN
+typedef union _AC_TXOP_CSR1_STRUC {
+ struct {
+ USHORT Ac3Txop; // for AC_VO, in unit of 32us
+ USHORT Ac2Txop; // for AC_VI, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+#else
+typedef union _AC_TXOP_CSR1_STRUC {
+ struct {
+ USHORT Ac2Txop; // for AC_VI, in unit of 32us
+ USHORT Ac3Txop; // for AC_VO, in unit of 32us
+ } field;
+ UINT32 word;
+} AC_TXOP_CSR1_STRUC, *PAC_TXOP_CSR1_STRUC;
+#endif
+#define RINGREG_DIFF 0x10
+#define GPIO_CTRL_CFG 0x0228 //MAC_CSR13
+#define MCU_CMD_CFG 0x022c
+#define TX_BASE_PTR0 0x0230 //AC_BK base address
+#define TX_MAX_CNT0 0x0234
+#define TX_CTX_IDX0 0x0238
+#define TX_DTX_IDX0 0x023c
+#define TX_BASE_PTR1 0x0240 //AC_BE base address
+#define TX_MAX_CNT1 0x0244
+#define TX_CTX_IDX1 0x0248
+#define TX_DTX_IDX1 0x024c
+#define TX_BASE_PTR2 0x0250 //AC_VI base address
+#define TX_MAX_CNT2 0x0254
+#define TX_CTX_IDX2 0x0258
+#define TX_DTX_IDX2 0x025c
+#define TX_BASE_PTR3 0x0260 //AC_VO base address
+#define TX_MAX_CNT3 0x0264
+#define TX_CTX_IDX3 0x0268
+#define TX_DTX_IDX3 0x026c
+#define TX_BASE_PTR4 0x0270 //HCCA base address
+#define TX_MAX_CNT4 0x0274
+#define TX_CTX_IDX4 0x0278
+#define TX_DTX_IDX4 0x027c
+#define TX_BASE_PTR5 0x0280 //MGMT base address
+#define TX_MAX_CNT5 0x0284
+#define TX_CTX_IDX5 0x0288
+#define TX_DTX_IDX5 0x028c
+#define TX_MGMTMAX_CNT TX_MAX_CNT5
+#define TX_MGMTCTX_IDX TX_CTX_IDX5
+#define TX_MGMTDTX_IDX TX_DTX_IDX5
+#define RX_BASE_PTR 0x0290 //RX base address
+#define RX_MAX_CNT 0x0294
+#define RX_CRX_IDX 0x0298
+#define RX_DRX_IDX 0x029c
+#define USB_DMA_CFG 0x02a0
+#ifdef RT_BIG_ENDIAN
+typedef union _USB_DMA_CFG_STRUC {
+ struct {
+ UINT32 TxBusy:1; //USB DMA TX FSM busy . debug only
+ UINT32 RxBusy:1; //USB DMA RX FSM busy . debug only
+ UINT32 EpoutValid:6; //OUT endpoint data valid. debug only
+ UINT32 TxBulkEn:1; //Enable USB DMA Tx
+ UINT32 RxBulkEn:1; //Enable USB DMA Rx
+ UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
+ UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
+ UINT32 TxClear:1; //Clear USB DMA TX path
+ UINT32 rsv:2;
+ UINT32 phyclear:1; //phy watch dog enable. write 1
+ UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 1024 bytes
+ UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
+ } field;
+ UINT32 word;
+} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+#else
+typedef union _USB_DMA_CFG_STRUC {
+ struct {
+ UINT32 RxBulkAggTOut:8; //Rx Bulk Aggregation TimeOut in unit of 33ns
+ UINT32 RxBulkAggLmt:8; //Rx Bulk Aggregation Limit in unit of 256 bytes
+ UINT32 phyclear:1; //phy watch dog enable. write 1
+ UINT32 rsv:2;
+ UINT32 TxClear:1; //Clear USB DMA TX path
+ UINT32 TxopHalt:1; //Halt TXOP count down when TX buffer is full.
+ UINT32 RxBulkAggEn:1; //Enable Rx Bulk Aggregation
+ UINT32 RxBulkEn:1; //Enable USB DMA Rx
+ UINT32 TxBulkEn:1; //Enable USB DMA Tx
+ UINT32 EpoutValid:6; //OUT endpoint data valid
+ UINT32 RxBusy:1; //USB DMA RX FSM busy
+ UINT32 TxBusy:1; //USB DMA TX FSM busy
+ } field;
+ UINT32 word;
+} USB_DMA_CFG_STRUC, *PUSB_DMA_CFG_STRUC;
+#endif
+
+//
+// 3 PBF registers
+//
+//
+// Most are for debug. Driver doesn't touch PBF register.
+#define PBF_SYS_CTRL 0x0400
+#define PBF_CFG 0x0408
+#define PBF_MAX_PCNT 0x040C
+#define PBF_CTRL 0x0410
+#define PBF_INT_STA 0x0414
+#define PBF_INT_ENA 0x0418
+#define TXRXQ_PCNT 0x0438
+#define PBF_DBG 0x043c
+#define PBF_CAP_CTRL 0x0440
+
+
+// eFuse registers
+#define EFUSE_CTRL 0x0580
+#define EFUSE_DATA0 0x0590
+#define EFUSE_DATA1 0x0594
+#define EFUSE_DATA2 0x0598
+#define EFUSE_DATA3 0x059c
+#define EFUSE_USAGE_MAP_START 0x2d0
+#define EFUSE_USAGE_MAP_END 0x2fc
+#define EFUSE_TAG 0x2fe
+#define EFUSE_USAGE_MAP_SIZE 45
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EFUSE_CTRL_STRUC {
+ struct {
+ UINT32 SEL_EFUSE:1;
+ UINT32 EFSROM_KICK:1;
+ UINT32 RESERVED:4;
+ UINT32 EFSROM_AIN:10;
+ UINT32 EFSROM_LDO_ON_TIME:2;
+ UINT32 EFSROM_LDO_OFF_TIME:6;
+ UINT32 EFSROM_MODE:2;
+ UINT32 EFSROM_AOUT:6;
+ } field;
+ UINT32 word;
+} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+#else
+typedef union _EFUSE_CTRL_STRUC {
+ struct {
+ UINT32 EFSROM_AOUT:6;
+ UINT32 EFSROM_MODE:2;
+ UINT32 EFSROM_LDO_OFF_TIME:6;
+ UINT32 EFSROM_LDO_ON_TIME:2;
+ UINT32 EFSROM_AIN:10;
+ UINT32 RESERVED:4;
+ UINT32 EFSROM_KICK:1;
+ UINT32 SEL_EFUSE:1;
+ } field;
+ UINT32 word;
+} EFUSE_CTRL_STRUC, *PEFUSE_CTRL_STRUC;
+#endif // RT_BIG_ENDIAN //
+
+#define LDO_CFG0 0x05d4
+#define GPIO_SWITCH 0x05dc
+
+//
+// 4 MAC registers
+//
+//
+// 4.1 MAC SYSTEM configuration registers (offset:0x1000)
+//
+#define MAC_CSR0 0x1000
+#ifdef RT_BIG_ENDIAN
+typedef union _ASIC_VER_ID_STRUC {
+ struct {
+ USHORT ASICVer; // version : 2860
+ USHORT ASICRev; // reversion : 0
+ } field;
+ UINT32 word;
+} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#else
+typedef union _ASIC_VER_ID_STRUC {
+ struct {
+ USHORT ASICRev; // reversion : 0
+ USHORT ASICVer; // version : 2860
+ } field;
+ UINT32 word;
+} ASIC_VER_ID_STRUC, *PASIC_VER_ID_STRUC;
+#endif
+#define MAC_SYS_CTRL 0x1004 //MAC_CSR1
+#define MAC_ADDR_DW0 0x1008 // MAC ADDR DW0
+#define MAC_ADDR_DW1 0x100c // MAC ADDR DW1
+//
+// MAC_CSR2: STA MAC register 0
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_DW0_STRUC {
+ struct {
+ UCHAR Byte3; // MAC address byte 3
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte0; // MAC address byte 0
+ } field;
+ UINT32 word;
+} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+#else
+typedef union _MAC_DW0_STRUC {
+ struct {
+ UCHAR Byte0; // MAC address byte 0
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte3; // MAC address byte 3
+ } field;
+ UINT32 word;
+} MAC_DW0_STRUC, *PMAC_DW0_STRUC;
+#endif
+
+//
+// MAC_CSR3: STA MAC register 1
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_DW1_STRUC {
+ struct {
+ UCHAR Rsvd1;
+ UCHAR U2MeMask;
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR Byte4; // MAC address byte 4
+ } field;
+ UINT32 word;
+} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+#else
+typedef union _MAC_DW1_STRUC {
+ struct {
+ UCHAR Byte4; // MAC address byte 4
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR U2MeMask;
+ UCHAR Rsvd1;
+ } field;
+ UINT32 word;
+} MAC_DW1_STRUC, *PMAC_DW1_STRUC;
+#endif
+
+#define MAC_BSSID_DW0 0x1010 // MAC BSSID DW0
+#define MAC_BSSID_DW1 0x1014 // MAC BSSID DW1
+
+//
+// MAC_CSR5: BSSID register 1
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MAC_CSR5_STRUC {
+ struct {
+ USHORT Rsvd:11;
+ USHORT MBssBcnNum:3;
+ USHORT BssIdMode:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
+ UCHAR Byte5; // BSSID byte 5
+ UCHAR Byte4; // BSSID byte 4
+ } field;
+ UINT32 word;
+} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+#else
+typedef union _MAC_CSR5_STRUC {
+ struct {
+ UCHAR Byte4; // BSSID byte 4
+ UCHAR Byte5; // BSSID byte 5
+ USHORT BssIdMask:2; // 0: one BSSID, 10: 4 BSSID, 01: 2 BSSID , 11: 8BSSID
+ USHORT MBssBcnNum:3;
+ USHORT Rsvd:11;
+ } field;
+ UINT32 word;
+} MAC_CSR5_STRUC, *PMAC_CSR5_STRUC;
+#endif
+
+#define MAX_LEN_CFG 0x1018 // rt2860b max 16k bytes. bit12:13 Maximum PSDU length (power factor) 0:2^13, 1:2^14, 2:2^15, 3:2^16
+#define BBP_CSR_CFG 0x101c //
+//
+// BBP_CSR_CFG: BBP serial control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _BBP_CSR_CFG_STRUC {
+ struct {
+ UINT32 :12;
+ UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
+ UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
+ UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
+ UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
+ UINT32 RegNum:8; // Selected BBP register
+ UINT32 Value:8; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#else
+typedef union _BBP_CSR_CFG_STRUC {
+ struct {
+ UINT32 Value:8; // Register value to program into BBP
+ UINT32 RegNum:8; // Selected BBP register
+ UINT32 fRead:1; // 0: Write BBP, 1: Read BBP
+ UINT32 Busy:1; // 1: ASIC is busy execute BBP programming.
+ UINT32 BBP_PAR_DUR:1; // 0: 4 MAC clock cycles 1: 8 MAC clock cycles
+ UINT32 BBP_RW_MODE:1; // 0: use serial mode 1:parallel
+ UINT32 :12;
+ } field;
+ UINT32 word;
+} BBP_CSR_CFG_STRUC, *PBBP_CSR_CFG_STRUC;
+#endif
+#define RF_CSR_CFG0 0x1020
+//
+// RF_CSR_CFG: RF control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG0_STRUC {
+ struct {
+ UINT32 Busy:1; // 0: idle 1: 8busy
+ UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
+ UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
+ UINT32 bitwidth:5; // Selected BBP register
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#else
+typedef union _RF_CSR_CFG0_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ UINT32 bitwidth:5; // Selected BBP register
+ UINT32 StandbyMode:1; // 0: high when stand by 1: low when standby
+ UINT32 Sel:1; // 0:RF_LE0 activate 1:RF_LE1 activate
+ UINT32 Busy:1; // 0: idle 1: 8busy
+ } field;
+ UINT32 word;
+} RF_CSR_CFG0_STRUC, *PRF_CSR_CFG0_STRUC;
+#endif
+#define RF_CSR_CFG1 0x1024
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG1_STRUC {
+ struct {
+ UINT32 rsv:7; // 0: idle 1: 8busy
+ UINT32 RFGap:5; // Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#else
+typedef union _RF_CSR_CFG1_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ UINT32 RFGap:5; // Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec)
+ UINT32 rsv:7; // 0: idle 1: 8busy
+ } field;
+ UINT32 word;
+} RF_CSR_CFG1_STRUC, *PRF_CSR_CFG1_STRUC;
+#endif
+#define RF_CSR_CFG2 0x1028 //
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG2_STRUC {
+ struct {
+ UINT32 rsv:8; // 0: idle 1: 8busy
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ } field;
+ UINT32 word;
+} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#else
+typedef union _RF_CSR_CFG2_STRUC {
+ struct {
+ UINT32 RegIdAndContent:24; // Register value to program into BBP
+ UINT32 rsv:8; // 0: idle 1: 8busy
+ } field;
+ UINT32 word;
+} RF_CSR_CFG2_STRUC, *PRF_CSR_CFG2_STRUC;
+#endif
+#define LED_CFG 0x102c // MAC_CSR14
+#ifdef RT_BIG_ENDIAN
+typedef union _LED_CFG_STRUC {
+ struct {
+ UINT32 :1;
+ UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
+ UINT32 YLedMode:2; // yellow Led Mode
+ UINT32 GLedMode:2; // green Led Mode
+ UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
+ UINT32 rsv:2;
+ UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
+ UINT32 OffPeriod:8; // blinking off period unit 1ms
+ UINT32 OnPeriod:8; // blinking on period unit 1ms
+ } field;
+ UINT32 word;
+} LED_CFG_STRUC, *PLED_CFG_STRUC;
+#else
+typedef union _LED_CFG_STRUC {
+ struct {
+ UINT32 OnPeriod:8; // blinking on period unit 1ms
+ UINT32 OffPeriod:8; // blinking off period unit 1ms
+ UINT32 SlowBlinkPeriod:6; // slow blinking period. unit:1ms
+ UINT32 rsv:2;
+ UINT32 RLedMode:2; // red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on
+ UINT32 GLedMode:2; // green Led Mode
+ UINT32 YLedMode:2; // yellow Led Mode
+ UINT32 LedPolar:1; // Led Polarity. 0: active low1: active high
+ UINT32 :1;
+ } field;
+ UINT32 word;
+} LED_CFG_STRUC, *PLED_CFG_STRUC;
+#endif
+//
+// 4.2 MAC TIMING configuration registers (offset:0x1100)
+//
+#define XIFS_TIME_CFG 0x1100 // MAC_CSR8 MAC_CSR9
+#ifdef RT_BIG_ENDIAN
+typedef union _IFS_SLOT_CFG_STRUC {
+ struct {
+ UINT32 rsv:2;
+ UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
+ UINT32 EIFS:9; // unit 1us
+ UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
+ UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
+ UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
+ } field;
+ UINT32 word;
+} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+#else
+typedef union _IFS_SLOT_CFG_STRUC {
+ struct {
+ UINT32 CckmSifsTime:8; // unit 1us. Applied after CCK RX/TX
+ UINT32 OfdmSifsTime:8; // unit 1us. Applied after OFDM RX/TX
+ UINT32 OfdmXifsTime:4; //OFDM SIFS. unit 1us. Applied after OFDM RX when MAC doesn't reference BBP signal BBRXEND
+ UINT32 EIFS:9; // unit 1us
+ UINT32 BBRxendEnable:1; // reference RXEND signal to begin XIFS defer
+ UINT32 rsv:2;
+ } field;
+ UINT32 word;
+} IFS_SLOT_CFG_STRUC, *PIFS_SLOT_CFG_STRUC;
+#endif
+
+#define BKOFF_SLOT_CFG 0x1104 // mac_csr9 last 8 bits
+#define NAV_TIME_CFG 0x1108 // NAV (MAC_CSR15)
+#define CH_TIME_CFG 0x110C // Count as channel busy
+#define PBF_LIFE_TIMER 0x1110 //TX/RX MPDU timestamp timer (free run)Unit: 1us
+#define BCN_TIME_CFG 0x1114 // TXRX_CSR9
+
+#define BCN_OFFSET0 0x042C
+#define BCN_OFFSET1 0x0430
+
+//
+// BCN_TIME_CFG : Synchronization control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _BCN_TIME_CFG_STRUC {
+ struct {
+ UINT32 TxTimestampCompensate:8;
+ UINT32 :3;
+ UINT32 bBeaconGen:1; // Enable beacon generator
+ UINT32 bTBTTEnable:1;
+ UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ UINT32 bTsfTicking:1; // Enable TSF auto counting
+ UINT32 BeaconInterval:16; // in unit of 1/16 TU
+ } field;
+ UINT32 word;
+} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#else
+typedef union _BCN_TIME_CFG_STRUC {
+ struct {
+ UINT32 BeaconInterval:16; // in unit of 1/16 TU
+ UINT32 bTsfTicking:1; // Enable TSF auto counting
+ UINT32 TsfSyncMode:2; // Enable TSF sync, 00: disable, 01: infra mode, 10: ad-hoc mode
+ UINT32 bTBTTEnable:1;
+ UINT32 bBeaconGen:1; // Enable beacon generator
+ UINT32 :3;
+ UINT32 TxTimestampCompensate:8;
+ } field;
+ UINT32 word;
+} BCN_TIME_CFG_STRUC, *PBCN_TIME_CFG_STRUC;
+#endif
+#define TBTT_SYNC_CFG 0x1118 // txrx_csr10
+#define TSF_TIMER_DW0 0x111C // Local TSF timer lsb 32 bits. Read-only
+#define TSF_TIMER_DW1 0x1120 // msb 32 bits. Read-only.
+#define TBTT_TIMER 0x1124 // TImer remains till next TBTT. Read-only. TXRX_CSR14
+#define INT_TIMER_CFG 0x1128 //
+#define INT_TIMER_EN 0x112c // GP-timer and pre-tbtt Int enable
+#define CH_IDLE_STA 0x1130 // channel idle time
+#define CH_BUSY_STA 0x1134 // channle busy time
+//
+// 4.2 MAC POWER configuration registers (offset:0x1200)
+//
+#define MAC_STATUS_CFG 0x1200 // old MAC_CSR12
+#define PWR_PIN_CFG 0x1204 // old MAC_CSR12
+#define AUTO_WAKEUP_CFG 0x1208 // old MAC_CSR10
+//
+// AUTO_WAKEUP_CFG: Manual power control / status register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _AUTO_WAKEUP_STRUC {
+ struct {
+ UINT32 :16;
+ UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
+ UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
+ UINT32 AutoLeadTime:8;
+ } field;
+ UINT32 word;
+} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+#else
+typedef union _AUTO_WAKEUP_STRUC {
+ struct {
+ UINT32 AutoLeadTime:8;
+ UINT32 NumofSleepingTbtt:7; // ForceWake has high privilege than PutToSleep when both set
+ UINT32 EnableAutoWakeup:1; // 0:sleep, 1:awake
+ UINT32 :16;
+ } field;
+ UINT32 word;
+} AUTO_WAKEUP_STRUC, *PAUTO_WAKEUP_STRUC;
+#endif
+//
+// 4.3 MAC TX configuration registers (offset:0x1300)
+//
+
+#define EDCA_AC0_CFG 0x1300 //AC_TXOP_CSR0 0x3474
+#define EDCA_AC1_CFG 0x1304
+#define EDCA_AC2_CFG 0x1308
+#define EDCA_AC3_CFG 0x130c
+#ifdef RT_BIG_ENDIAN
+typedef union _EDCA_AC_CFG_STRUC {
+ struct {
+ UINT32 :12; //
+ UINT32 Cwmax:4; //unit power of 2
+ UINT32 Cwmin:4; //
+ UINT32 Aifsn:4; // # of slot time
+ UINT32 AcTxop:8; // in unit of 32us
+ } field;
+ UINT32 word;
+} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+#else
+typedef union _EDCA_AC_CFG_STRUC {
+ struct {
+ UINT32 AcTxop:8; // in unit of 32us
+ UINT32 Aifsn:4; // # of slot time
+ UINT32 Cwmin:4; //
+ UINT32 Cwmax:4; //unit power of 2
+ UINT32 :12; //
+ } field;
+ UINT32 word;
+} EDCA_AC_CFG_STRUC, *PEDCA_AC_CFG_STRUC;
+#endif
+
+#define EDCA_TID_AC_MAP 0x1310
+#define TX_PWR_CFG_0 0x1314
+#define TX_PWR_CFG_1 0x1318
+#define TX_PWR_CFG_2 0x131C
+#define TX_PWR_CFG_3 0x1320
+#define TX_PWR_CFG_4 0x1324
+#define TX_PIN_CFG 0x1328
+#define TX_BAND_CFG 0x132c // 0x1 use upper 20MHz. 0 juse lower 20MHz
+#define TX_SW_CFG0 0x1330
+#define TX_SW_CFG1 0x1334
+#define TX_SW_CFG2 0x1338
+#define TXOP_THRES_CFG 0x133c
+#define TXOP_CTRL_CFG 0x1340
+#define TX_RTS_CFG 0x1344
+
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_RTS_CFG_STRUC {
+ struct {
+ UINT32 rsv:7;
+ UINT32 RtsFbkEn:1; // enable rts rate fallback
+ UINT32 RtsThres:16; // unit:byte
+ UINT32 AutoRtsRetryLimit:8;
+ } field;
+ UINT32 word;
+} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#else
+typedef union _TX_RTS_CFG_STRUC {
+ struct {
+ UINT32 AutoRtsRetryLimit:8;
+ UINT32 RtsThres:16; // unit:byte
+ UINT32 RtsFbkEn:1; // enable rts rate fallback
+ UINT32 rsv:7; // 1: HT non-STBC control frame enable
+ } field;
+ UINT32 word;
+} TX_RTS_CFG_STRUC, *PTX_RTS_CFG_STRUC;
+#endif
+#define TX_TIMEOUT_CFG 0x1348
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_TIMEOUT_CFG_STRUC {
+ struct {
+ UINT32 rsv2:8;
+ UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
+ UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
+ UINT32 rsv:4;
+ } field;
+ UINT32 word;
+} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#else
+typedef union _TX_TIMEOUT_CFG_STRUC {
+ struct {
+ UINT32 rsv:4;
+ UINT32 MpduLifeTime:4; // expiration time = 2^(9+MPDU LIFE TIME) us
+ UINT32 RxAckTimeout:8; // unit:slot. Used for TX precedure
+ UINT32 TxopTimeout:8; //TXOP timeout value for TXOP truncation. It is recommended that (SLOT_TIME) > (TX_OP_TIMEOUT) > (RX_ACK_TIMEOUT)
+ UINT32 rsv2:8; // 1: HT non-STBC control frame enable
+ } field;
+ UINT32 word;
+} TX_TIMEOUT_CFG_STRUC, *PTX_TIMEOUT_CFG_STRUC;
+#endif
+#define TX_RTY_CFG 0x134c
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _TX_RTY_CFG_STRUC {
+ struct {
+ UINT32 rsv:1;
+ UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
+ UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 LongRtyThre:12; // Long retry threshoold
+ UINT32 LongRtyLimit:8; //long retry limit
+ UINT32 ShortRtyLimit:8; // short retry limit
+
+ } field;
+ UINT32 word;
+} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#else
+typedef union PACKED _TX_RTY_CFG_STRUC {
+ struct {
+ UINT32 ShortRtyLimit:8; // short retry limit
+ UINT32 LongRtyLimit:8; //long retry limit
+ UINT32 LongRtyThre:12; // Long retry threshoold
+ UINT32 NonAggRtyMode:1; // Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 AggRtyMode:1; // Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer
+ UINT32 TxautoFBEnable:1; // Tx retry PHY rate auto fallback enable
+ UINT32 rsv:1; // 1: HT non-STBC control frame enable
+ } field;
+ UINT32 word;
+} TX_RTY_CFG_STRUC, *PTX_RTY_CFG_STRUC;
+#endif
+#define TX_LINK_CFG 0x1350
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _TX_LINK_CFG_STRUC {
+ struct PACKED {
+ UINT32 RemotMFS:8; //remote MCS feedback sequence number
+ UINT32 RemotMFB:8; // remote MCS feedback
+ UINT32 rsv:3; //
+ UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
+ UINT32 TxRDGEn:1; // RDG TX enable
+ UINT32 TxMRQEn:1; // MCS request TX enable
+ UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
+ UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
+ UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
+ } field;
+ UINT32 word;
+} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#else
+typedef union PACKED _TX_LINK_CFG_STRUC {
+ struct PACKED {
+ UINT32 RemoteMFBLifeTime:8; //remote MFB life time. unit : 32us
+ UINT32 MFBEnable:1; // TX apply remote MFB 1:enable
+ UINT32 RemoteUMFSEnable:1; // remote unsolicit MFB enable. 0: not apply remote remote unsolicit (MFS=7)
+ UINT32 TxMRQEn:1; // MCS request TX enable
+ UINT32 TxRDGEn:1; // RDG TX enable
+ UINT32 TxCFAckEn:1; // Piggyback CF-ACK enable
+ UINT32 rsv:3; //
+ UINT32 RemotMFB:8; // remote MCS feedback
+ UINT32 RemotMFS:8; //remote MCS feedback sequence number
+ } field;
+ UINT32 word;
+} TX_LINK_CFG_STRUC, *PTX_LINK_CFG_STRUC;
+#endif
+#define HT_FBK_CFG0 0x1354
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _HT_FBK_CFG0_STRUC {
+ struct {
+ UINT32 HTMCS7FBK:4;
+ UINT32 HTMCS6FBK:4;
+ UINT32 HTMCS5FBK:4;
+ UINT32 HTMCS4FBK:4;
+ UINT32 HTMCS3FBK:4;
+ UINT32 HTMCS2FBK:4;
+ UINT32 HTMCS1FBK:4;
+ UINT32 HTMCS0FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#else
+typedef union PACKED _HT_FBK_CFG0_STRUC {
+ struct {
+ UINT32 HTMCS0FBK:4;
+ UINT32 HTMCS1FBK:4;
+ UINT32 HTMCS2FBK:4;
+ UINT32 HTMCS3FBK:4;
+ UINT32 HTMCS4FBK:4;
+ UINT32 HTMCS5FBK:4;
+ UINT32 HTMCS6FBK:4;
+ UINT32 HTMCS7FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG0_STRUC, *PHT_FBK_CFG0_STRUC;
+#endif
+#define HT_FBK_CFG1 0x1358
+#ifdef RT_BIG_ENDIAN
+typedef union _HT_FBK_CFG1_STRUC {
+ struct {
+ UINT32 HTMCS15FBK:4;
+ UINT32 HTMCS14FBK:4;
+ UINT32 HTMCS13FBK:4;
+ UINT32 HTMCS12FBK:4;
+ UINT32 HTMCS11FBK:4;
+ UINT32 HTMCS10FBK:4;
+ UINT32 HTMCS9FBK:4;
+ UINT32 HTMCS8FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#else
+typedef union _HT_FBK_CFG1_STRUC {
+ struct {
+ UINT32 HTMCS8FBK:4;
+ UINT32 HTMCS9FBK:4;
+ UINT32 HTMCS10FBK:4;
+ UINT32 HTMCS11FBK:4;
+ UINT32 HTMCS12FBK:4;
+ UINT32 HTMCS13FBK:4;
+ UINT32 HTMCS14FBK:4;
+ UINT32 HTMCS15FBK:4;
+ } field;
+ UINT32 word;
+} HT_FBK_CFG1_STRUC, *PHT_FBK_CFG1_STRUC;
+#endif
+#define LG_FBK_CFG0 0x135c
+#ifdef RT_BIG_ENDIAN
+typedef union _LG_FBK_CFG0_STRUC {
+ struct {
+ UINT32 OFDMMCS7FBK:4; //initial value is 6
+ UINT32 OFDMMCS6FBK:4; //initial value is 5
+ UINT32 OFDMMCS5FBK:4; //initial value is 4
+ UINT32 OFDMMCS4FBK:4; //initial value is 3
+ UINT32 OFDMMCS3FBK:4; //initial value is 2
+ UINT32 OFDMMCS2FBK:4; //initial value is 1
+ UINT32 OFDMMCS1FBK:4; //initial value is 0
+ UINT32 OFDMMCS0FBK:4; //initial value is 0
+ } field;
+ UINT32 word;
+} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#else
+typedef union _LG_FBK_CFG0_STRUC {
+ struct {
+ UINT32 OFDMMCS0FBK:4; //initial value is 0
+ UINT32 OFDMMCS1FBK:4; //initial value is 0
+ UINT32 OFDMMCS2FBK:4; //initial value is 1
+ UINT32 OFDMMCS3FBK:4; //initial value is 2
+ UINT32 OFDMMCS4FBK:4; //initial value is 3
+ UINT32 OFDMMCS5FBK:4; //initial value is 4
+ UINT32 OFDMMCS6FBK:4; //initial value is 5
+ UINT32 OFDMMCS7FBK:4; //initial value is 6
+ } field;
+ UINT32 word;
+} LG_FBK_CFG0_STRUC, *PLG_FBK_CFG0_STRUC;
+#endif
+#define LG_FBK_CFG1 0x1360
+#ifdef RT_BIG_ENDIAN
+typedef union _LG_FBK_CFG1_STRUC {
+ struct {
+ UINT32 rsv:16;
+ UINT32 CCKMCS3FBK:4; //initial value is 2
+ UINT32 CCKMCS2FBK:4; //initial value is 1
+ UINT32 CCKMCS1FBK:4; //initial value is 0
+ UINT32 CCKMCS0FBK:4; //initial value is 0
+ } field;
+ UINT32 word;
+} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+#else
+typedef union _LG_FBK_CFG1_STRUC {
+ struct {
+ UINT32 CCKMCS0FBK:4; //initial value is 0
+ UINT32 CCKMCS1FBK:4; //initial value is 0
+ UINT32 CCKMCS2FBK:4; //initial value is 1
+ UINT32 CCKMCS3FBK:4; //initial value is 2
+ UINT32 rsv:16;
+ } field;
+ UINT32 word;
+} LG_FBK_CFG1_STRUC, *PLG_FBK_CFG1_STRUC;
+#endif
+
+//=======================================================
+//================ Protection Paramater================================
+//=======================================================
+#define CCK_PROT_CFG 0x1364 //CCK Protection
+#define ASIC_SHORTNAV 1
+#define ASIC_LONGNAV 2
+#define ASIC_RTS 1
+#define ASIC_CTS 2
+#ifdef RT_BIG_ENDIAN
+typedef union _PROT_CFG_STRUC {
+ struct {
+ UINT32 rsv:5;
+ UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
+ UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
+ UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
+ UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
+ UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
+ UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
+ } field;
+ UINT32 word;
+} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+#else
+typedef union _PROT_CFG_STRUC {
+ struct {
+ UINT32 ProtectRate:16; //Protection control frame rate for CCK TX(RTS/CTS/CFEnd).
+ UINT32 ProtectCtrl:2; //Protection control frame type for CCK TX. 1:RTS/CTS, 2:CTS-to-self, 0:None, 3:rsv
+ UINT32 ProtectNav:2; //TXOP protection type for CCK TX. 0:None, 1:ShortNAVprotect, 2:LongNAVProtect, 3:rsv
+ UINT32 TxopAllowCck:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowOfdm:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowMM20:1; //CCK TXOP allowance. 0:disallow.
+ UINT32 TxopAllowMM40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowGF20:1; //CCK TXOP allowance.0:disallow.
+ UINT32 TxopAllowGF40:1; //CCK TXOP allowance.0:disallow.
+ UINT32 RTSThEn:1; //RTS threshold enable on CCK TX
+ UINT32 rsv:5;
+ } field;
+ UINT32 word;
+} PROT_CFG_STRUC, *PPROT_CFG_STRUC;
+#endif
+
+#define OFDM_PROT_CFG 0x1368 //OFDM Protection
+#define MM20_PROT_CFG 0x136C //MM20 Protection
+#define MM40_PROT_CFG 0x1370 //MM40 Protection
+#define GF20_PROT_CFG 0x1374 //GF20 Protection
+#define GF40_PROT_CFG 0x1378 //GR40 Protection
+#define EXP_CTS_TIME 0x137C //
+#define EXP_ACK_TIME 0x1380 //
+
+//
+// 4.4 MAC RX configuration registers (offset:0x1400)
+//
+#define RX_FILTR_CFG 0x1400 //TXRX_CSR0
+#define AUTO_RSP_CFG 0x1404 //TXRX_CSR4
+//
+// TXRX_CSR4: Auto-Responder/
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+ UINT32 :24;
+ UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
+ UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
+ UINT32 rsv:1; // Power bit value in conrtrol frame
+ UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
+ UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
+ UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
+ UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
+ UINT32 AutoResponderEnable:1;
+ } field;
+ UINT32 word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+#else
+typedef union _AUTO_RSP_CFG_STRUC {
+ struct {
+ UINT32 AutoResponderEnable:1;
+ UINT32 BACAckPolicyEnable:1; // 0:long, 1:short preamble
+ UINT32 CTS40MMode:1; // Response CTS 40MHz duplicate mode
+ UINT32 CTS40MRef:1; // Response CTS 40MHz duplicate mode
+ UINT32 AutoResponderPreamble:1; // 0:long, 1:short preamble
+ UINT32 rsv:1; // Power bit value in conrtrol frame
+ UINT32 DualCTSEn:1; // Power bit value in conrtrol frame
+ UINT32 AckCtsPsmBit:1; // Power bit value in conrtrol frame
+ UINT32 :24;
+ } field;
+ UINT32 word;
+} AUTO_RSP_CFG_STRUC, *PAUTO_RSP_CFG_STRUC;
+#endif
+
+#define LEGACY_BASIC_RATE 0x1408 // TXRX_CSR5 0x3054
+#define HT_BASIC_RATE 0x140c
+#define HT_CTRL_CFG 0x1410
+#define SIFS_COST_CFG 0x1414
+#define RX_PARSER_CFG 0x1418 //Set NAV for all received frames
+
+//
+// 4.5 MAC Security configuration (offset:0x1500)
+//
+#define TX_SEC_CNT0 0x1500 //
+#define RX_SEC_CNT0 0x1504 //
+#define CCMP_FC_MUTE 0x1508 //
+//
+// 4.6 HCCA/PSMP (offset:0x1600)
+//
+#define TXOP_HLDR_ADDR0 0x1600
+#define TXOP_HLDR_ADDR1 0x1604
+#define TXOP_HLDR_ET 0x1608
+#define QOS_CFPOLL_RA_DW0 0x160c
+#define QOS_CFPOLL_A1_DW1 0x1610
+#define QOS_CFPOLL_QC 0x1614
+//
+// 4.7 MAC Statistis registers (offset:0x1700)
+//
+#define RX_STA_CNT0 0x1700 //
+#define RX_STA_CNT1 0x1704 //
+#define RX_STA_CNT2 0x1708 //
+
+//
+// RX_STA_CNT0_STRUC: RX PLCP error count & RX CRC error count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT0_STRUC {
+ struct {
+ USHORT PhyErr;
+ USHORT CrcErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+#else
+typedef union _RX_STA_CNT0_STRUC {
+ struct {
+ USHORT CrcErr;
+ USHORT PhyErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT0_STRUC, *PRX_STA_CNT0_STRUC;
+#endif
+
+//
+// RX_STA_CNT1_STRUC: RX False CCA count & RX LONG frame count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT1_STRUC {
+ struct {
+ USHORT PlcpErr;
+ USHORT FalseCca;
+ } field;
+ UINT32 word;
+} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+#else
+typedef union _RX_STA_CNT1_STRUC {
+ struct {
+ USHORT FalseCca;
+ USHORT PlcpErr;
+ } field;
+ UINT32 word;
+} RX_STA_CNT1_STRUC, *PRX_STA_CNT1_STRUC;
+#endif
+
+//
+// RX_STA_CNT2_STRUC:
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _RX_STA_CNT2_STRUC {
+ struct {
+ USHORT RxFifoOverflowCount;
+ USHORT RxDupliCount;
+ } field;
+ UINT32 word;
+} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#else
+typedef union _RX_STA_CNT2_STRUC {
+ struct {
+ USHORT RxDupliCount;
+ USHORT RxFifoOverflowCount;
+ } field;
+ UINT32 word;
+} RX_STA_CNT2_STRUC, *PRX_STA_CNT2_STRUC;
+#endif
+#define TX_STA_CNT0 0x170C //
+//
+// STA_CSR3: TX Beacon count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT0_STRUC {
+ struct {
+ USHORT TxBeaconCount;
+ USHORT TxFailCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#else
+typedef union _TX_STA_CNT0_STRUC {
+ struct {
+ USHORT TxFailCount;
+ USHORT TxBeaconCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT0_STRUC, *PTX_STA_CNT0_STRUC;
+#endif
+#define TX_STA_CNT1 0x1710 //
+//
+// TX_STA_CNT1: TX tx count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT1_STRUC {
+ struct {
+ USHORT TxRetransmit;
+ USHORT TxSuccess;
+ } field;
+ UINT32 word;
+} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#else
+typedef union _TX_STA_CNT1_STRUC {
+ struct {
+ USHORT TxSuccess;
+ USHORT TxRetransmit;
+ } field;
+ UINT32 word;
+} TX_STA_CNT1_STRUC, *PTX_STA_CNT1_STRUC;
+#endif
+#define TX_STA_CNT2 0x1714 //
+//
+// TX_STA_CNT2: TX tx count
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_STA_CNT2_STRUC {
+ struct {
+ USHORT TxUnderFlowCount;
+ USHORT TxZeroLenCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#else
+typedef union _TX_STA_CNT2_STRUC {
+ struct {
+ USHORT TxZeroLenCount;
+ USHORT TxUnderFlowCount;
+ } field;
+ UINT32 word;
+} TX_STA_CNT2_STRUC, *PTX_STA_CNT2_STRUC;
+#endif
+#define TX_STA_FIFO 0x1718 //
+//
+// TX_STA_FIFO_STRUC: TX Result for specific PID status fifo register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union PACKED _TX_STA_FIFO_STRUC {
+ struct {
+ UINT32 Reserve:2;
+ UINT32 TxBF:1; // 3*3
+ UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+ UINT32 wcid:8; //wireless client index
+ UINT32 TxAckRequired:1; // ack required
+ UINT32 TxAggre:1; // Tx is aggregated
+ UINT32 TxSuccess:1; // Tx success. whether success or not
+ UINT32 PidType:4;
+ UINT32 bValid:1; // 1:This register contains a valid TX result
+ } field;
+ UINT32 word;
+} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+#else
+typedef union PACKED _TX_STA_FIFO_STRUC {
+ struct {
+ UINT32 bValid:1; // 1:This register contains a valid TX result
+ UINT32 PidType:4;
+ UINT32 TxSuccess:1; // Tx No retry success
+ UINT32 TxAggre:1; // Tx Retry Success
+ UINT32 TxAckRequired:1; // Tx fail
+ UINT32 wcid:8; //wireless client index
+// UINT32 SuccessRate:16; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+ UINT32 SuccessRate:13; //include MCS, mode ,shortGI, BW settingSame format as TXWI Word 0 Bit 31-16.
+ UINT32 TxBF:1;
+ UINT32 Reserve:2;
+ } field;
+ UINT32 word;
+} TX_STA_FIFO_STRUC, *PTX_STA_FIFO_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT 0x171c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT_STRUC {
+ struct {
+ USHORT AggTxCount;
+ USHORT NonAggTxCount;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+#else
+typedef union _TX_AGG_CNT_STRUC {
+ struct {
+ USHORT NonAggTxCount;
+ USHORT AggTxCount;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT_STRUC, *PTX_AGG_CNT_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT0 0x1720
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT0_STRUC {
+ struct {
+ USHORT AggSize2Count;
+ USHORT AggSize1Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+#else
+typedef union _TX_AGG_CNT0_STRUC {
+ struct {
+ USHORT AggSize1Count;
+ USHORT AggSize2Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT0_STRUC, *PTX_AGG_CNT0_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT1 0x1724
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT1_STRUC {
+ struct {
+ USHORT AggSize4Count;
+ USHORT AggSize3Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#else
+typedef union _TX_AGG_CNT1_STRUC {
+ struct {
+ USHORT AggSize3Count;
+ USHORT AggSize4Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT1_STRUC, *PTX_AGG_CNT1_STRUC;
+#endif
+#define TX_AGG_CNT2 0x1728
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT2_STRUC {
+ struct {
+ USHORT AggSize6Count;
+ USHORT AggSize5Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+#else
+typedef union _TX_AGG_CNT2_STRUC {
+ struct {
+ USHORT AggSize5Count;
+ USHORT AggSize6Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT2_STRUC, *PTX_AGG_CNT2_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT3 0x172c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT3_STRUC {
+ struct {
+ USHORT AggSize8Count;
+ USHORT AggSize7Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+#else
+typedef union _TX_AGG_CNT3_STRUC {
+ struct {
+ USHORT AggSize7Count;
+ USHORT AggSize8Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT3_STRUC, *PTX_AGG_CNT3_STRUC;
+#endif
+// Debug counter
+#define TX_AGG_CNT4 0x1730
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT4_STRUC {
+ struct {
+ USHORT AggSize10Count;
+ USHORT AggSize9Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#else
+typedef union _TX_AGG_CNT4_STRUC {
+ struct {
+ USHORT AggSize9Count;
+ USHORT AggSize10Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT4_STRUC, *PTX_AGG_CNT4_STRUC;
+#endif
+#define TX_AGG_CNT5 0x1734
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT5_STRUC {
+ struct {
+ USHORT AggSize12Count;
+ USHORT AggSize11Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#else
+typedef union _TX_AGG_CNT5_STRUC {
+ struct {
+ USHORT AggSize11Count;
+ USHORT AggSize12Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT5_STRUC, *PTX_AGG_CNT5_STRUC;
+#endif
+#define TX_AGG_CNT6 0x1738
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT6_STRUC {
+ struct {
+ USHORT AggSize14Count;
+ USHORT AggSize13Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#else
+typedef union _TX_AGG_CNT6_STRUC {
+ struct {
+ USHORT AggSize13Count;
+ USHORT AggSize14Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT6_STRUC, *PTX_AGG_CNT6_STRUC;
+#endif
+#define TX_AGG_CNT7 0x173c
+#ifdef RT_BIG_ENDIAN
+typedef union _TX_AGG_CNT7_STRUC {
+ struct {
+ USHORT AggSize16Count;
+ USHORT AggSize15Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#else
+typedef union _TX_AGG_CNT7_STRUC {
+ struct {
+ USHORT AggSize15Count;
+ USHORT AggSize16Count;
+ } field;
+ UINT32 word;
+} TX_AGG_CNT7_STRUC, *PTX_AGG_CNT7_STRUC;
+#endif
+#define MPDU_DENSITY_CNT 0x1740
+#ifdef RT_BIG_ENDIAN
+typedef union _MPDU_DEN_CNT_STRUC {
+ struct {
+ USHORT RXZeroDelCount; //RX zero length delimiter count
+ USHORT TXZeroDelCount; //TX zero length delimiter count
+ } field;
+ UINT32 word;
+} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+#else
+typedef union _MPDU_DEN_CNT_STRUC {
+ struct {
+ USHORT TXZeroDelCount; //TX zero length delimiter count
+ USHORT RXZeroDelCount; //RX zero length delimiter count
+ } field;
+ UINT32 word;
+} MPDU_DEN_CNT_STRUC, *PMPDU_DEN_CNT_STRUC;
+#endif
+//
+// TXRX control registers - base address 0x3000
+//
+// rt2860b UNKNOWN reg use R/O Reg Addr 0x77d0 first..
+#define TXRX_CSR1 0x77d0
+
+//
+// Security key table memory, base address = 0x1000
+//
+#define MAC_WCID_BASE 0x1800 //8-bytes(use only 6-bytes) * 256 entry =
+#define HW_WCID_ENTRY_SIZE 8
+#define PAIRWISE_KEY_TABLE_BASE 0x4000 // 32-byte * 256-entry = -byte
+#define HW_KEY_ENTRY_SIZE 0x20
+#define PAIRWISE_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
+#define MAC_IVEIV_TABLE_BASE 0x6000 // 8-byte * 256-entry = -byte
+#define HW_IVEIV_ENTRY_SIZE 8
+#define MAC_WCID_ATTRIBUTE_BASE 0x6800 // 4-byte * 256-entry = -byte
+#define HW_WCID_ATTRI_SIZE 4
+#define WCID_RESERVED 0x6bfc
+#define SHARED_KEY_TABLE_BASE 0x6c00 // 32-byte * 16-entry = 512-byte
+#define SHARED_KEY_MODE_BASE 0x7000 // 32-byte * 16-entry = 512-byte
+#define HW_SHARED_KEY_MODE_SIZE 4
+#define SHAREDKEYTABLE 0
+#define PAIRWISEKEYTABLE 1
+
+
+#ifdef RT_BIG_ENDIAN
+typedef union _SHAREDKEY_MODE_STRUC {
+ struct {
+ UINT32 :1;
+ UINT32 Bss1Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key0CipherAlg:3;
+ } field;
+ UINT32 word;
+} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+#else
+typedef union _SHAREDKEY_MODE_STRUC {
+ struct {
+ UINT32 Bss0Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss0Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss1Key3CipherAlg:3;
+ UINT32 :1;
+ } field;
+ UINT32 word;
+} SHAREDKEY_MODE_STRUC, *PSHAREDKEY_MODE_STRUC;
+#endif
+// 64-entry for pairwise key table
+typedef struct _HW_WCID_ENTRY { // 8-byte per entry
+ UCHAR Address[6];
+ UCHAR Rsv[2];
+} HW_WCID_ENTRY, PHW_WCID_ENTRY;
+
+
+
+//
+// Other on-chip shared memory space, base = 0x2000
+//
+
+// CIS space - base address = 0x2000
+#define HW_CIS_BASE 0x2000
+
+// Carrier-sense CTS frame base address. It's where mac stores carrier-sense frame for carrier-sense function.
+#define HW_CS_CTS_BASE 0x7700
+// DFS CTS frame base address. It's where mac stores CTS frame for DFS.
+#define HW_DFS_CTS_BASE 0x7780
+#define HW_CTS_FRAME_SIZE 0x80
+
+// 2004-11-08 john - since NULL frame won't be that long (256 byte). We steal 16 tail bytes
+// to save debugging settings
+#define HW_DEBUG_SETTING_BASE 0x77f0 // 0x77f0~0x77ff total 16 bytes
+#define HW_DEBUG_SETTING_BASE2 0x7770 // 0x77f0~0x77ff total 16 bytes
+
+// In order to support maximum 8 MBSS and its maximum length is 512 for each beacon
+// Three section discontinue memory segments will be used.
+// 1. The original region for BCN 0~3
+// 2. Extract memory from FCE table for BCN 4~5
+// 3. Extract memory from Pair-wise key table for BCN 6~7
+// It occupied those memory of wcid 238~253 for BCN 6
+// and wcid 222~237 for BCN 7
+#define HW_BEACON_MAX_SIZE 0x1000 /* unit: byte */
+#define HW_BEACON_BASE0 0x7800
+#define HW_BEACON_BASE1 0x7A00
+#define HW_BEACON_BASE2 0x7C00
+#define HW_BEACON_BASE3 0x7E00
+#define HW_BEACON_BASE4 0x7200
+#define HW_BEACON_BASE5 0x7400
+#define HW_BEACON_BASE6 0x5DC0
+#define HW_BEACON_BASE7 0x5BC0
+
+#define HW_BEACON_MAX_COUNT 8
+#define HW_BEACON_OFFSET 0x0200
+#define HW_BEACON_CONTENT_LEN (HW_BEACON_OFFSET - TXWI_SIZE)
+
+// HOST-MCU shared memory - base address = 0x2100
+#define HOST_CMD_CSR 0x404
+#define H2M_MAILBOX_CSR 0x7010
+#define H2M_MAILBOX_CID 0x7014
+#define H2M_MAILBOX_STATUS 0x701c
+#define H2M_INT_SRC 0x7024
+#define H2M_BBP_AGENT 0x7028
+#define M2H_CMD_DONE_CSR 0x000c
+#define MCU_TXOP_ARRAY_BASE 0x000c // TODO: to be provided by Albert
+#define MCU_TXOP_ENTRY_SIZE 32 // TODO: to be provided by Albert
+#define MAX_NUM_OF_TXOP_ENTRY 16 // TODO: must be same with 8051 firmware
+#define MCU_MBOX_VERSION 0x01 // TODO: to be confirmed by Albert
+#define MCU_MBOX_VERSION_OFFSET 5 // TODO: to be provided by Albert
+
+//
+// Host DMA registers - base address 0x200 . TX0-3=EDCAQid0-3, TX4=HCCA, TX5=MGMT,
+//
+//
+// DMA RING DESCRIPTOR
+//
+#define E2PROM_CSR 0x0004
+#define IO_CNTL_CSR 0x77d0
+
+#ifdef RT2870
+// 8051 firmware image for usb - use last-half base address = 0x3000
+#define FIRMWARE_IMAGE_BASE 0x3000
+#define MAX_FIRMWARE_IMAGE_SIZE 0x1000 // 4kbyte
+#endif // RT2870 //
+
+// TODO: ????? old RT2560 registers. to keep them or remove them?
+//#define MCAST0 0x0178 // multicast filter register 0
+//#define MCAST1 0x017c // multicast filter register 1
+
+
+// ================================================================
+// Tx / Rx / Mgmt ring descriptor definition
+// ================================================================
+
+// the following PID values are used to mark outgoing frame type in TXD->PID so that
+// proper TX statistics can be collected based on these categories
+// b3-2 of PID field -
+#define PID_MGMT 0x05
+#define PID_BEACON 0x0c
+#define PID_DATA_NORMALUCAST 0x02
+#define PID_DATA_AMPDU 0x04
+#define PID_DATA_NO_ACK 0x08
+#define PID_DATA_NOT_NORM_ACK 0x03
+// value domain of pTxD->HostQId (4-bit: 0~15)
+#define QID_AC_BK 1 // meet ACI definition in 802.11e
+#define QID_AC_BE 0 // meet ACI definition in 802.11e
+#define QID_AC_VI 2
+#define QID_AC_VO 3
+#define QID_HCCA 4
+#define NUM_OF_TX_RING 5
+#define QID_MGMT 13
+#define QID_RX 14
+#define QID_OTHER 15
+
+
+// ------------------------------------------------------
+// BBP & RF definition
+// ------------------------------------------------------
+#define BUSY 1
+#define IDLE 0
+
+#define RF_R00 0
+#define RF_R01 1
+#define RF_R02 2
+#define RF_R03 3
+#define RF_R04 4
+#define RF_R05 5
+#define RF_R06 6
+#define RF_R07 7
+#define RF_R08 8
+#define RF_R09 9
+#define RF_R10 10
+#define RF_R11 11
+#define RF_R12 12
+#define RF_R13 13
+#define RF_R14 14
+#define RF_R15 15
+#define RF_R16 16
+#define RF_R17 17
+#define RF_R18 18
+#define RF_R19 19
+#define RF_R20 20
+#define RF_R21 21
+#define RF_R22 22
+#define RF_R23 23
+#define RF_R24 24
+#define RF_R25 25
+#define RF_R26 26
+#define RF_R27 27
+#define RF_R28 28
+#define RF_R29 29
+#define RF_R30 30
+#define RF_R31 31
+
+#define BBP_R0 0 // version
+#define BBP_R1 1 // TSSI
+#define BBP_R2 2 // TX configure
+#define BBP_R3 3
+#define BBP_R4 4
+#define BBP_R5 5
+#define BBP_R6 6
+#define BBP_R14 14 // RX configure
+#define BBP_R16 16
+#define BBP_R17 17 // RX sensibility
+#define BBP_R18 18
+#define BBP_R21 21
+#define BBP_R22 22
+#define BBP_R24 24
+#define BBP_R25 25
+#define BBP_R31 31
+#define BBP_R49 49 //TSSI
+#define BBP_R50 50
+#define BBP_R51 51
+#define BBP_R52 52
+#define BBP_R55 55
+#define BBP_R62 62 // Rx SQ0 Threshold HIGH
+#define BBP_R63 63
+#define BBP_R64 64
+#define BBP_R65 65
+#define BBP_R66 66
+#define BBP_R67 67
+#define BBP_R68 68
+#define BBP_R69 69
+#define BBP_R70 70 // Rx AGC SQ CCK Xcorr threshold
+#define BBP_R73 73
+#define BBP_R75 75
+#define BBP_R77 77
+#define BBP_R79 79
+#define BBP_R80 80
+#define BBP_R81 81
+#define BBP_R82 82
+#define BBP_R83 83
+#define BBP_R84 84
+#define BBP_R86 86
+#define BBP_R91 91
+#define BBP_R92 92
+#define BBP_R94 94 // Tx Gain Control
+#define BBP_R103 103
+#define BBP_R105 105
+#define BBP_R113 113
+#define BBP_R114 114
+#define BBP_R115 115
+#define BBP_R116 116
+#define BBP_R117 117
+#define BBP_R118 118
+#define BBP_R119 119
+#define BBP_R120 120
+#define BBP_R121 121
+#define BBP_R122 122
+#define BBP_R123 123
+#ifdef RT30xx
+#define BBP_R138 138 // add by johnli, RF power sequence setup, ADC dynamic on/off control
+#endif // RT30xx //
+
+
+#define BBPR94_DEFAULT 0x06 // Add 1 value will gain 1db
+
+//#define PHY_TR_SWITCH_TIME 5 // usec
+
+//#define BBP_R17_LOW_SENSIBILITY 0x50
+//#define BBP_R17_MID_SENSIBILITY 0x41
+//#define BBP_R17_DYNAMIC_UP_BOUND 0x40
+#define RSSI_FOR_VERY_LOW_SENSIBILITY -35
+#define RSSI_FOR_LOW_SENSIBILITY -58
+#define RSSI_FOR_MID_LOW_SENSIBILITY -80
+#define RSSI_FOR_MID_SENSIBILITY -90
+
+//-------------------------------------------------------------------------
+// EEPROM definition
+//-------------------------------------------------------------------------
+#define EEDO 0x08
+#define EEDI 0x04
+#define EECS 0x02
+#define EESK 0x01
+#define EERL 0x80
+
+#define EEPROM_WRITE_OPCODE 0x05
+#define EEPROM_READ_OPCODE 0x06
+#define EEPROM_EWDS_OPCODE 0x10
+#define EEPROM_EWEN_OPCODE 0x13
+
+#define NUM_EEPROM_BBP_PARMS 19 // Include NIC Config 0, 1, CR, TX ALC step, BBPs
+#define NUM_EEPROM_TX_G_PARMS 7
+#define EEPROM_NIC1_OFFSET 0x34 // The address is from NIC config 0, not BBP register ID
+#define EEPROM_NIC2_OFFSET 0x36 // The address is from NIC config 0, not BBP register ID
+#define EEPROM_BBP_BASE_OFFSET 0xf0 // The address is from NIC config 0, not BBP register ID
+#define EEPROM_G_TX_PWR_OFFSET 0x52
+#define EEPROM_G_TX2_PWR_OFFSET 0x60
+#define EEPROM_LED1_OFFSET 0x3c
+#define EEPROM_LED2_OFFSET 0x3e
+#define EEPROM_LED3_OFFSET 0x40
+#define EEPROM_LNA_OFFSET 0x44
+#define EEPROM_RSSI_BG_OFFSET 0x46
+#define EEPROM_RSSI_A_OFFSET 0x4a
+#define EEPROM_DEFINE_MAX_TXPWR 0x4e
+#define EEPROM_TXPOWER_BYRATE_20MHZ_2_4G 0xde // 20MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_2_4G 0xee // 40MHZ 2.4G tx power.
+#define EEPROM_TXPOWER_BYRATE_20MHZ_5G 0xfa // 20MHZ 5G tx power.
+#define EEPROM_TXPOWER_BYRATE_40MHZ_5G 0x10a // 40MHZ 5G tx power.
+#define EEPROM_A_TX_PWR_OFFSET 0x78
+#define EEPROM_A_TX2_PWR_OFFSET 0xa6
+//#define EEPROM_Japan_TX_PWR_OFFSET 0x90 // 802.11j
+//#define EEPROM_Japan_TX2_PWR_OFFSET 0xbe
+//#define EEPROM_TSSI_REF_OFFSET 0x54
+//#define EEPROM_TSSI_DELTA_OFFSET 0x24
+//#define EEPROM_CCK_TX_PWR_OFFSET 0x62
+//#define EEPROM_CALIBRATE_OFFSET 0x7c
+#define EEPROM_VERSION_OFFSET 0x02
+#define EEPROM_FREQ_OFFSET 0x3a
+#define EEPROM_TXPOWER_BYRATE 0xde // 20MHZ power.
+#define EEPROM_TXPOWER_DELTA 0x50 // 20MHZ AND 40 MHZ use different power. This is delta in 40MHZ.
+#define VALID_EEPROM_VERSION 1
+
+// PairKeyMode definition
+#define PKMODE_NONE 0
+#define PKMODE_WEP64 1
+#define PKMODE_WEP128 2
+#define PKMODE_TKIP 3
+#define PKMODE_AES 4
+#define PKMODE_CKIP64 5
+#define PKMODE_CKIP128 6
+#define PKMODE_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
+
+// =================================================================================
+// WCID format
+// =================================================================================
+//7.1 WCID ENTRY format : 8bytes
+typedef struct _WCID_ENTRY_STRUC {
+ UCHAR RXBABitmap7; // bit0 for TID8, bit7 for TID 15
+ UCHAR RXBABitmap0; // bit0 for TID0, bit7 for TID 7
+ UCHAR MAC[6]; // 0 for shared key table. 1 for pairwise key table
+} WCID_ENTRY_STRUC, *PWCID_ENTRY_STRUC;
+
+//8.1.1 SECURITY KEY format : 8DW
+// 32-byte per entry, total 16-entry for shared key table, 64-entry for pairwise key table
+typedef struct _HW_KEY_ENTRY { // 32-byte per entry
+ UCHAR Key[16];
+ UCHAR TxMic[8];
+ UCHAR RxMic[8];
+} HW_KEY_ENTRY, *PHW_KEY_ENTRY;
+
+//8.1.2 IV/EIV format : 2DW
+
+//8.1.3 RX attribute entry format : 1DW
+#ifdef RT_BIG_ENDIAN
+typedef struct _MAC_ATTRIBUTE_STRUC {
+ UINT32 rsv:22;
+ UINT32 RXWIUDF:3;
+ UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
+ UINT32 PairKeyMode:3;
+ UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
+} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
+#else
+typedef struct _MAC_ATTRIBUTE_STRUC {
+ UINT32 KeyTab:1; // 0 for shared key table. 1 for pairwise key table
+ UINT32 PairKeyMode:3;
+ UINT32 BSSIDIdx:3; //multipleBSS index for the WCID
+ UINT32 RXWIUDF:3;
+ UINT32 rsv:22;
+} MAC_ATTRIBUTE_STRUC, *PMAC_ATTRIBUTE_STRUC;
+#endif
+
+
+// =================================================================================
+// TX / RX ring descriptor format
+// =================================================================================
+
+// the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO.
+// MAC block use this TXINFO to control the transmission behavior of this frame.
+#define FIFO_MGMT 0
+#define FIFO_HCCA 1
+#define FIFO_EDCA 2
+
+//
+// TX descriptor format, Tx ring, Mgmt Ring
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _TXD_STRUC {
+ // Word 0
+ UINT32 SDPtr0;
+ // Word 1
+ UINT32 DMADONE:1;
+ UINT32 LastSec0:1;
+ UINT32 SDLen0:14;
+ UINT32 Burst:1;
+ UINT32 LastSec1:1;
+ UINT32 SDLen1:14;
+ // Word 2
+ UINT32 SDPtr1;
+ // Word 3
+ UINT32 ICO:1;
+ UINT32 UCO:1;
+ UINT32 TCO:1;
+ UINT32 rsv:2;
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 rsv2:24;
+} TXD_STRUC, *PTXD_STRUC;
+#else
+typedef struct PACKED _TXD_STRUC {
+ // Word 0
+ UINT32 SDPtr0;
+ // Word 1
+ UINT32 SDLen1:14;
+ UINT32 LastSec1:1;
+ UINT32 Burst:1;
+ UINT32 SDLen0:14;
+ UINT32 LastSec0:1;
+ UINT32 DMADONE:1;
+ //Word2
+ UINT32 SDPtr1;
+ //Word3
+ UINT32 rsv2:24;
+ UINT32 WIV:1; // Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition
+ UINT32 QSEL:2; // select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA
+ UINT32 rsv:2;
+ UINT32 TCO:1; //
+ UINT32 UCO:1; //
+ UINT32 ICO:1; //
+} TXD_STRUC, *PTXD_STRUC;
+#endif
+
+
+//
+// TXD Wireless Information format for Tx ring and Mgmt Ring
+//
+//txop : for txop mode
+// 0:txop for the MPDU frame will be handles by ASIC by register
+// 1/2/3:the MPDU frame is send after PIFS/backoff/SIFS
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _TXWI_STRUC {
+ // Word 0
+ UINT32 PHYMODE:2;
+ UINT32 TxBF:1; // 3*3
+ UINT32 rsv2:1;
+// UINT32 rsv2:2;
+ UINT32 Ifs:1; //
+ UINT32 STBC:2; //channel bandwidth 20MHz or 40 MHz
+ UINT32 ShortGI:1;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 MCS:7;
+
+ UINT32 rsv:6;
+ UINT32 txop:2; //tx back off mode 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
+ UINT32 MpduDensity:3;
+ UINT32 AMPDU:1;
+
+ UINT32 TS:1;
+ UINT32 CFACK:1;
+ UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
+ UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
+ // Word 1
+ UINT32 PacketId:4;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 WirelessCliID:8;
+ UINT32 BAWinSize:6;
+ UINT32 NSEQ:1;
+ UINT32 ACK:1;
+ // Word 2
+ UINT32 IV;
+ // Word 3
+ UINT32 EIV;
+} TXWI_STRUC, *PTXWI_STRUC;
+#else
+typedef struct PACKED _TXWI_STRUC {
+ // Word 0
+ UINT32 FRAG:1; // 1 to inform TKIP engine this is a fragment.
+ UINT32 MIMOps:1; // the remote peer is in dynamic MIMO-PS mode
+ UINT32 CFACK:1;
+ UINT32 TS:1;
+
+ UINT32 AMPDU:1;
+ UINT32 MpduDensity:3;
+ UINT32 txop:2; //FOR "THIS" frame. 0:HT TXOP rule , 1:PIFS TX ,2:Backoff, 3:sifs only when previous frame exchange is successful.
+ UINT32 rsv:6;
+
+ UINT32 MCS:7;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 ShortGI:1;
+ UINT32 STBC:2; // 1: STBC support MCS =0-7, 2,3 : RESERVE
+ UINT32 Ifs:1; //
+// UINT32 rsv2:2; //channel bandwidth 20MHz or 40 MHz
+ UINT32 rsv2:1;
+ UINT32 TxBF:1; // 3*3
+ UINT32 PHYMODE:2;
+ // Word 1
+ UINT32 ACK:1;
+ UINT32 NSEQ:1;
+ UINT32 BAWinSize:6;
+ UINT32 WirelessCliID:8;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 PacketId:4;
+ //Word2
+ UINT32 IV;
+ //Word3
+ UINT32 EIV;
+} TXWI_STRUC, *PTXWI_STRUC;
+#endif
+//
+// Rx descriptor format, Rx Ring
+//
+//
+// RXWI wireless information format, in PBF. invisible in driver.
+//
+#ifdef RT_BIG_ENDIAN
+typedef struct PACKED _RXWI_STRUC {
+ // Word 0
+ UINT32 TID:4;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 UDF:3;
+ UINT32 BSSID:3;
+ UINT32 KeyIndex:2;
+ UINT32 WirelessCliID:8;
+ // Word 1
+ UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
+ UINT32 rsv:3;
+ UINT32 STBC:2;
+ UINT32 ShortGI:1;
+ UINT32 BW:1;
+ UINT32 MCS:7;
+ UINT32 SEQUENCE:12;
+ UINT32 FRAG:4;
+ // Word 2
+ UINT32 rsv1:8;
+ UINT32 RSSI2:8;
+ UINT32 RSSI1:8;
+ UINT32 RSSI0:8;
+ // Word 3
+ UINT32 rsv2:16;
+ UINT32 SNR1:8;
+ UINT32 SNR0:8;
+} RXWI_STRUC, *PRXWI_STRUC;
+#else
+typedef struct PACKED _RXWI_STRUC {
+ // Word 0
+ UINT32 WirelessCliID:8;
+ UINT32 KeyIndex:2;
+ UINT32 BSSID:3;
+ UINT32 UDF:3;
+ UINT32 MPDUtotalByteCount:12;
+ UINT32 TID:4;
+ // Word 1
+ UINT32 FRAG:4;
+ UINT32 SEQUENCE:12;
+ UINT32 MCS:7;
+ UINT32 BW:1;
+ UINT32 ShortGI:1;
+ UINT32 STBC:2;
+ UINT32 rsv:3;
+ UINT32 PHYMODE:2; // 1: this RX frame is unicast to me
+ //Word2
+ UINT32 RSSI0:8;
+ UINT32 RSSI1:8;
+ UINT32 RSSI2:8;
+ UINT32 rsv1:8;
+ //Word3
+ UINT32 SNR0:8;
+ UINT32 SNR1:8;
+ UINT32 rsv2:16;
+} RXWI_STRUC, *PRXWI_STRUC;
+#endif
+
+
+// =================================================================================
+// HOST-MCU communication data structure
+// =================================================================================
+
+//
+// H2M_MAILBOX_CSR: Host-to-MCU Mailbox
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _H2M_MAILBOX_STRUC {
+ struct {
+ UINT32 Owner:8;
+ UINT32 CmdToken:8; // 0xff tells MCU not to report CmdDoneInt after excuting the command
+ UINT32 HighByte:8;
+ UINT32 LowByte:8;
+ } field;
+ UINT32 word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+#else
+typedef union _H2M_MAILBOX_STRUC {
+ struct {
+ UINT32 LowByte:8;
+ UINT32 HighByte:8;
+ UINT32 CmdToken:8;
+ UINT32 Owner:8;
+ } field;
+ UINT32 word;
+} H2M_MAILBOX_STRUC, *PH2M_MAILBOX_STRUC;
+#endif
+
+//
+// M2H_CMD_DONE_CSR: MCU-to-Host command complete indication
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _M2H_CMD_DONE_STRUC {
+ struct {
+ UINT32 CmdToken3;
+ UINT32 CmdToken2;
+ UINT32 CmdToken1;
+ UINT32 CmdToken0;
+ } field;
+ UINT32 word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+#else
+typedef union _M2H_CMD_DONE_STRUC {
+ struct {
+ UINT32 CmdToken0;
+ UINT32 CmdToken1;
+ UINT32 CmdToken2;
+ UINT32 CmdToken3;
+ } field;
+ UINT32 word;
+} M2H_CMD_DONE_STRUC, *PM2H_CMD_DONE_STRUC;
+#endif
+
+
+
+//
+// MCU_LEDCS: MCU LED Control Setting.
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _MCU_LEDCS_STRUC {
+ struct {
+ UCHAR Polarity:1;
+ UCHAR LedMode:7;
+ } field;
+ UCHAR word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+#else
+typedef union _MCU_LEDCS_STRUC {
+ struct {
+ UCHAR LedMode:7;
+ UCHAR Polarity:1;
+ } field;
+ UCHAR word;
+} MCU_LEDCS_STRUC, *PMCU_LEDCS_STRUC;
+#endif
+// =================================================================================
+// Register format
+// =================================================================================
+
+
+
+//NAV_TIME_CFG :NAV
+#ifdef RT_BIG_ENDIAN
+typedef union _NAV_TIME_CFG_STRUC {
+ struct {
+ USHORT rsv:6;
+ USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
+ USHORT Eifs:9; // in unit of 1-us
+ UCHAR SlotTime; // in unit of 1-us
+ UCHAR Sifs; // in unit of 1-us
+ } field;
+ UINT32 word;
+} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+#else
+typedef union _NAV_TIME_CFG_STRUC {
+ struct {
+ UCHAR Sifs; // in unit of 1-us
+ UCHAR SlotTime; // in unit of 1-us
+ USHORT Eifs:9; // in unit of 1-us
+ USHORT ZeroSifs:1; // Applied zero SIFS timer after OFDM RX 0: disable
+ USHORT rsv:6;
+ } field;
+ UINT32 word;
+} NAV_TIME_CFG_STRUC, *PNAV_TIME_CFG_STRUC;
+#endif
+
+
+
+
+
+//
+// RX_FILTR_CFG: /RX configuration register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union RX_FILTR_CFG_STRUC {
+ struct {
+ UINT32 :15;
+ UINT32 DropRsvCntlType:1;
+
+ UINT32 DropBAR:1; //
+ UINT32 DropBA:1; //
+ UINT32 DropPsPoll:1; // Drop Ps-Poll
+ UINT32 DropRts:1; // Drop Ps-Poll
+
+ UINT32 DropCts:1; // Drop Ps-Poll
+ UINT32 DropAck:1; // Drop Ps-Poll
+ UINT32 DropCFEnd:1; // Drop Ps-Poll
+ UINT32 DropCFEndAck:1; // Drop Ps-Poll
+
+ UINT32 DropDuplicate:1; // Drop duplicate frame
+ UINT32 DropBcast:1; // Drop broadcast frames
+ UINT32 DropMcast:1; // Drop multicast frames
+ UINT32 DropVerErr:1; // Drop version error frame
+
+ UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
+ UINT32 DropNotToMe:1; // Drop not to me unicast frame
+ UINT32 DropPhyErr:1; // Drop physical error
+ UINT32 DropCRCErr:1; // Drop CRC error
+ } field;
+ UINT32 word;
+} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+#else
+typedef union _RX_FILTR_CFG_STRUC {
+ struct {
+ UINT32 DropCRCErr:1; // Drop CRC error
+ UINT32 DropPhyErr:1; // Drop physical error
+ UINT32 DropNotToMe:1; // Drop not to me unicast frame
+ UINT32 DropNotMyBSSID:1; // Drop fram ToDs bit is true
+
+ UINT32 DropVerErr:1; // Drop version error frame
+ UINT32 DropMcast:1; // Drop multicast frames
+ UINT32 DropBcast:1; // Drop broadcast frames
+ UINT32 DropDuplicate:1; // Drop duplicate frame
+
+ UINT32 DropCFEndAck:1; // Drop Ps-Poll
+ UINT32 DropCFEnd:1; // Drop Ps-Poll
+ UINT32 DropAck:1; // Drop Ps-Poll
+ UINT32 DropCts:1; // Drop Ps-Poll
+
+ UINT32 DropRts:1; // Drop Ps-Poll
+ UINT32 DropPsPoll:1; // Drop Ps-Poll
+ UINT32 DropBA:1; //
+ UINT32 DropBAR:1; //
+
+ UINT32 DropRsvCntlType:1;
+ UINT32 :15;
+ } field;
+ UINT32 word;
+} RX_FILTR_CFG_STRUC, *PRX_FILTR_CFG_STRUC;
+#endif
+
+
+
+
+//
+// PHY_CSR4: RF serial control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _PHY_CSR4_STRUC {
+ struct {
+ UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
+ UINT32 PLL_LD:1; // RF PLL_LD status
+ UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
+ UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
+ UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
+ } field;
+ UINT32 word;
+} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+#else
+typedef union _PHY_CSR4_STRUC {
+ struct {
+ UINT32 RFRegValue:24; // Register value (include register id) serial out to RF/IF chip.
+ UINT32 NumberOfBits:5; // Number of bits used in RFRegValue (I:20, RFMD:22)
+ UINT32 IFSelect:1; // 1: select IF to program, 0: select RF to program
+ UINT32 PLL_LD:1; // RF PLL_LD status
+ UINT32 Busy:1; // 1: ASIC is busy execute RF programming.
+ } field;
+ UINT32 word;
+} PHY_CSR4_STRUC, *PPHY_CSR4_STRUC;
+#endif
+
+
+//
+// SEC_CSR5: shared key table security mode register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _SEC_CSR5_STRUC {
+ struct {
+ UINT32 :1;
+ UINT32 Bss3Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key0CipherAlg:3;
+ } field;
+ UINT32 word;
+} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+#else
+typedef union _SEC_CSR5_STRUC {
+ struct {
+ UINT32 Bss2Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss2Key3CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key0CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key1CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key2CipherAlg:3;
+ UINT32 :1;
+ UINT32 Bss3Key3CipherAlg:3;
+ UINT32 :1;
+ } field;
+ UINT32 word;
+} SEC_CSR5_STRUC, *PSEC_CSR5_STRUC;
+#endif
+
+
+//
+// HOST_CMD_CSR: For HOST to interrupt embedded processor
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _HOST_CMD_CSR_STRUC {
+ struct {
+ UINT32 Rsv:24;
+ UINT32 HostCommand:8;
+ } field;
+ UINT32 word;
+} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+#else
+typedef union _HOST_CMD_CSR_STRUC {
+ struct {
+ UINT32 HostCommand:8;
+ UINT32 Rsv:24;
+ } field;
+ UINT32 word;
+} HOST_CMD_CSR_STRUC, *PHOST_CMD_CSR_STRUC;
+#endif
+
+
+//
+// AIFSN_CSR: AIFSN for each EDCA AC
+//
+
+
+
+//
+// E2PROM_CSR: EEPROM control register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _E2PROM_CSR_STRUC {
+ struct {
+ UINT32 Rsvd:25;
+ UINT32 LoadStatus:1; // 1:loading, 0:done
+ UINT32 Type:1; // 1: 93C46, 0:93C66
+ UINT32 EepromDO:1;
+ UINT32 EepromDI:1;
+ UINT32 EepromCS:1;
+ UINT32 EepromSK:1;
+ UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
+ } field;
+ UINT32 word;
+} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+#else
+typedef union _E2PROM_CSR_STRUC {
+ struct {
+ UINT32 Reload:1; // Reload EEPROM content, write one to reload, self-cleared.
+ UINT32 EepromSK:1;
+ UINT32 EepromCS:1;
+ UINT32 EepromDI:1;
+ UINT32 EepromDO:1;
+ UINT32 Type:1; // 1: 93C46, 0:93C66
+ UINT32 LoadStatus:1; // 1:loading, 0:done
+ UINT32 Rsvd:25;
+ } field;
+ UINT32 word;
+} E2PROM_CSR_STRUC, *PE2PROM_CSR_STRUC;
+#endif
+
+
+// -------------------------------------------------------------------
+// E2PROM data layout
+// -------------------------------------------------------------------
+
+//
+// EEPROM antenna select format
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_ANTENNA_STRUC {
+ struct {
+ USHORT Rsv:4;
+ USHORT RfIcType:4; // see E2PROM document
+ USHORT TxPath:4; // 1: 1T, 2: 2T
+ USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
+ } field;
+ USHORT word;
+} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+#else
+typedef union _EEPROM_ANTENNA_STRUC {
+ struct {
+ USHORT RxPath:4; // 1: 1R, 2: 2R, 3: 3R
+ USHORT TxPath:4; // 1: 1T, 2: 2T
+ USHORT RfIcType:4; // see E2PROM document
+ USHORT Rsv:4;
+ } field;
+ USHORT word;
+} EEPROM_ANTENNA_STRUC, *PEEPROM_ANTENNA_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_NIC_CINFIG2_STRUC {
+ struct {
+ USHORT DACTestBit:1; // control if driver should patch the DAC issue
+ USHORT Rsv2:3; // must be 0
+ USHORT AntDiversity:1; // Antenna diversity
+ USHORT Rsv1:1; // must be 0
+ USHORT BW40MAvailForA:1; // 0:enable, 1:disable
+ USHORT BW40MAvailForG:1; // 0:enable, 1:disable
+ USHORT EnableWPSPBC:1; // WPS PBC Control bit
+ USHORT BW40MSidebandForA:1;
+ USHORT BW40MSidebandForG:1;
+ USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
+ USHORT ExternalLNAForA:1; // external LNA enable for 5G
+ USHORT ExternalLNAForG:1; // external LNA enable for 2.4G
+ USHORT DynamicTxAgcControl:1; //
+ USHORT HardwareRadioControl:1; // Whether RF is controlled by driver or HW. 1:enable hw control, 0:disable
+ } field;
+ USHORT word;
+} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+#else
+typedef union _EEPROM_NIC_CINFIG2_STRUC {
+ struct {
+ USHORT HardwareRadioControl:1; // 1:enable, 0:disable
+ USHORT DynamicTxAgcControl:1; //
+ USHORT ExternalLNAForG:1; //
+ USHORT ExternalLNAForA:1; // external LNA enable for 2.4G
+ USHORT CardbusAcceleration:1; // !!! NOTE: 0 - enable, 1 - disable
+ USHORT BW40MSidebandForG:1;
+ USHORT BW40MSidebandForA:1;
+ USHORT EnableWPSPBC:1; // WPS PBC Control bit
+ USHORT BW40MAvailForG:1; // 0:enable, 1:disable
+ USHORT BW40MAvailForA:1; // 0:enable, 1:disable
+ USHORT Rsv1:1; // must be 0
+ USHORT AntDiversity:1; // Antenna diversity
+ USHORT Rsv2:3; // must be 0
+ USHORT DACTestBit:1; // control if driver should patch the DAC issue
+ } field;
+ USHORT word;
+} EEPROM_NIC_CONFIG2_STRUC, *PEEPROM_NIC_CONFIG2_STRUC;
+#endif
+
+//
+// TX_PWR Value valid range 0xFA(-6) ~ 0x24(36)
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_TX_PWR_STRUC {
+ struct {
+ CHAR Byte1; // High Byte
+ CHAR Byte0; // Low Byte
+ } field;
+ USHORT word;
+} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+#else
+typedef union _EEPROM_TX_PWR_STRUC {
+ struct {
+ CHAR Byte0; // Low Byte
+ CHAR Byte1; // High Byte
+ } field;
+ USHORT word;
+} EEPROM_TX_PWR_STRUC, *PEEPROM_TX_PWR_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_VERSION_STRUC {
+ struct {
+ UCHAR Version; // High Byte
+ UCHAR FaeReleaseNumber; // Low Byte
+ } field;
+ USHORT word;
+} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+#else
+typedef union _EEPROM_VERSION_STRUC {
+ struct {
+ UCHAR FaeReleaseNumber; // Low Byte
+ UCHAR Version; // High Byte
+ } field;
+ USHORT word;
+} EEPROM_VERSION_STRUC, *PEEPROM_VERSION_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_LED_STRUC {
+ struct {
+ USHORT Rsvd:3; // Reserved
+ USHORT LedMode:5; // Led mode.
+ USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
+ USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
+ USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
+ USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
+ USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
+ USHORT PolarityACT:1; // Polarity ACT setting.
+ USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
+ USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
+ } field;
+ USHORT word;
+} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+#else
+typedef union _EEPROM_LED_STRUC {
+ struct {
+ USHORT PolarityRDY_G:1; // Polarity RDY_G setting.
+ USHORT PolarityRDY_A:1; // Polarity RDY_A setting.
+ USHORT PolarityACT:1; // Polarity ACT setting.
+ USHORT PolarityGPIO_0:1; // Polarity GPIO#0 setting.
+ USHORT PolarityGPIO_1:1; // Polarity GPIO#1 setting.
+ USHORT PolarityGPIO_2:1; // Polarity GPIO#2 setting.
+ USHORT PolarityGPIO_3:1; // Polarity GPIO#3 setting.
+ USHORT PolarityGPIO_4:1; // Polarity GPIO#4 setting.
+ USHORT LedMode:5; // Led mode.
+ USHORT Rsvd:3; // Reserved
+ } field;
+ USHORT word;
+} EEPROM_LED_STRUC, *PEEPROM_LED_STRUC;
+#endif
+
+#ifdef RT_BIG_ENDIAN
+typedef union _EEPROM_TXPOWER_DELTA_STRUC {
+ struct {
+ UCHAR TxPowerEnable:1;// Enable
+ UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
+ UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
+ } field;
+ UCHAR value;
+} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+#else
+typedef union _EEPROM_TXPOWER_DELTA_STRUC {
+ struct {
+ UCHAR DeltaValue:6; // Tx Power dalta value (MAX=4)
+ UCHAR Type:1; // 1: plus the delta value, 0: minus the delta value
+ UCHAR TxPowerEnable:1;// Enable
+ } field;
+ UCHAR value;
+} EEPROM_TXPOWER_DELTA_STRUC, *PEEPROM_TXPOWER_DELTA_STRUC;
+#endif
+
+//
+// QOS_CSR0: TXOP holder address0 register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _QOS_CSR0_STRUC {
+ struct {
+ UCHAR Byte3; // MAC address byte 3
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte0; // MAC address byte 0
+ } field;
+ UINT32 word;
+} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+#else
+typedef union _QOS_CSR0_STRUC {
+ struct {
+ UCHAR Byte0; // MAC address byte 0
+ UCHAR Byte1; // MAC address byte 1
+ UCHAR Byte2; // MAC address byte 2
+ UCHAR Byte3; // MAC address byte 3
+ } field;
+ UINT32 word;
+} QOS_CSR0_STRUC, *PQOS_CSR0_STRUC;
+#endif
+
+//
+// QOS_CSR1: TXOP holder address1 register
+//
+#ifdef RT_BIG_ENDIAN
+typedef union _QOS_CSR1_STRUC {
+ struct {
+ UCHAR Rsvd1;
+ UCHAR Rsvd0;
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR Byte4; // MAC address byte 4
+ } field;
+ UINT32 word;
+} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+#else
+typedef union _QOS_CSR1_STRUC {
+ struct {
+ UCHAR Byte4; // MAC address byte 4
+ UCHAR Byte5; // MAC address byte 5
+ UCHAR Rsvd0;
+ UCHAR Rsvd1;
+ } field;
+ UINT32 word;
+} QOS_CSR1_STRUC, *PQOS_CSR1_STRUC;
+#endif
+
+#define RF_CSR_CFG 0x500
+#ifdef RT_BIG_ENDIAN
+typedef union _RF_CSR_CFG_STRUC {
+ struct {
+ UINT Rsvd1:14; // Reserved
+ UINT RF_CSR_KICK:1; // kick RF register read/write
+ UINT RF_CSR_WR:1; // 0: read 1: write
+ UINT Rsvd2:3; // Reserved
+ UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
+ UINT RF_CSR_DATA:8; // DATA
+ } field;
+ UINT word;
+} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+#else
+typedef union _RF_CSR_CFG_STRUC {
+ struct {
+ UINT RF_CSR_DATA:8; // DATA
+ UINT TESTCSR_RFACC_REGNUM:5; // RF register ID
+ UINT Rsvd2:3; // Reserved
+ UINT RF_CSR_WR:1; // 0: read 1: write
+ UINT RF_CSR_KICK:1; // kick RF register read/write
+ UINT Rsvd1:14; // Reserved
+ } field;
+ UINT word;
+} RF_CSR_CFG_STRUC, *PRF_CSR_CFG_STRUC;
+#endif
+
+#endif // __RT28XX_H__
diff --git a/drivers/staging/rt3070/rt_ate.c b/drivers/staging/rt3070/rt_ate.c
new file mode 100644
index 00000000000..9238d960121
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.c
@@ -0,0 +1,6506 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+#ifdef UCOS
+INT IoctlResponse(PUCHAR payload, PUCHAR msg, INT len);
+#endif // UCOS //
+
+#define ATE_BBP_REG_NUM 168
+UCHAR restore_BBP[ATE_BBP_REG_NUM]={0};
+
+#ifdef RALINK_ATE
+UCHAR TemplateFrame[24] = {0x08/* Data type */,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0xAA,0xBB,0x12,0x34,0x56,0x00,0x11,0x22,0xAA,0xBB,0xCC,0x00,0x00}; // 802.11 MAC Header, Type:Data, Length:24bytes
+extern RTMP_RF_REGS RF2850RegTable[];
+extern UCHAR NUM_OF_2850_CHNL;
+
+#ifdef RT2870
+extern UCHAR EpToQueue[];
+extern VOID RTUSBRejectPendingPackets( IN PRTMP_ADAPTER pAd);
+#endif // RT2870 //
+
+#ifdef RT30xx
+//2008/07/10:KH adds to support 3070 ATE<--
+extern FREQUENCY_ITEM FreqItems3020[];
+extern UCHAR NUM_OF_3020_CHNL;
+//2008/07/10:KH adds to support 3070 ATE-->
+#endif // RT30xx //
+
+#ifdef UCOS
+extern INT ConsoleResponse(IN PUCHAR buff);
+extern int (*remote_display)(char *);
+#endif // UCOS //
+
+static CHAR CCKRateTable[] = {0, 1, 2, 3, 8, 9, 10, 11, -1}; /* CCK Mode. */
+static CHAR OFDMRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, -1}; /* OFDM Mode. */
+static CHAR HTMIXRateTable[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1}; /* HT Mix Mode. */
+
+static INT TxDmaBusy(
+ IN PRTMP_ADAPTER pAd);
+
+static INT RxDmaBusy(
+ IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpDmaEnable(
+ IN PRTMP_ADAPTER pAd,
+ IN INT Enable);
+
+static VOID BbpSoftReset(
+ IN PRTMP_ADAPTER pAd);
+
+static VOID RtmpRfIoWrite(
+ IN PRTMP_ADAPTER pAd);
+
+static INT ATESetUpFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TxIdx);
+
+static INT ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index);
+
+static INT ATECmdHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+static int CheckMCSValid(
+ IN UCHAR Mode,
+ IN UCHAR Mcs);
+
+
+#ifdef RT2870
+static VOID ATEWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst);
+
+static VOID ATEWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR MIMOps,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING Transmit);
+
+#endif // RT2870 //
+
+static VOID SetJapanFilter(
+ IN PRTMP_ADAPTER pAd);
+
+/*=========================end of prototype=========================*/
+
+
+#ifdef RT2870
+static INT TxDmaBusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT result;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+ if (UsbCfg.field.TxBusy)
+ result = 1;
+ else
+ result = 0;
+
+ return result;
+}
+
+static INT RxDmaBusy(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT result;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+ if (UsbCfg.field.RxBusy)
+ result = 1;
+ else
+ result = 0;
+
+ return result;
+}
+
+static VOID RtmpDmaEnable(
+ IN PRTMP_ADAPTER pAd,
+ IN INT Enable)
+{
+ BOOLEAN value;
+ ULONG WaitCnt;
+ USB_DMA_CFG_STRUC UsbCfg;
+
+ value = Enable > 0 ? 1 : 0;
+
+ // check DMA is in busy mode.
+ WaitCnt = 0;
+ while (TxDmaBusy(pAd) || RxDmaBusy(pAd))
+ {
+ RTMPusecDelay(10);
+ if (WaitCnt++ > 100)
+ break;
+ }
+
+ //Why not to clear USB DMA TX path first ???
+ RTMP_IO_READ32(pAd, USB_DMA_CFG, &UsbCfg.word); // disable DMA
+ UsbCfg.field.TxBulkEn = value;
+ UsbCfg.field.RxBulkEn = value;
+ RTMP_IO_WRITE32(pAd, USB_DMA_CFG, UsbCfg.word); // abort all TX rings
+ RTMPusecDelay(5000);
+
+ return;
+}
+#endif // RT2870 //
+
+static VOID BbpSoftReset(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BbpData = 0;
+
+ // Soft reset, set BBP R21 bit0=1->0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+ BbpData |= 0x00000001; //set bit0=1
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R21, &BbpData);
+ BbpData &= ~(0x00000001); //set bit0=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R21, BbpData);
+
+ return;
+}
+
+static VOID RtmpRfIoWrite(
+ IN PRTMP_ADAPTER pAd)
+{
+ // Set RF value 1's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 2's set R3[bit2] = [1]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 | 0x04));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ RTMPusecDelay(200);
+
+ // Set RF value 3's set R3[bit2] = [0]
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAd, (pAd->LatchRfRegs.R3 & (~0x04)));
+ RTMP_RF_IO_WRITE32(pAd, pAd->LatchRfRegs.R4);
+
+ return;
+}
+
+static int CheckMCSValid(
+ UCHAR Mode,
+ UCHAR Mcs)
+{
+ int i;
+ PCHAR pRateTab;
+
+ switch(Mode)
+ {
+ case 0:
+ pRateTab = CCKRateTable;
+ break;
+ case 1:
+ pRateTab = OFDMRateTable;
+ break;
+ case 2:
+ case 3:
+ pRateTab = HTMIXRateTable;
+ break;
+ default:
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("unrecognizable Tx Mode %d\n", Mode));
+ return -1;
+ break;
+ }
+
+ i = 0;
+ while(pRateTab[i] != -1)
+ {
+ if (pRateTab[i] == Mcs)
+ return 0;
+ i++;
+ }
+
+ return -1;
+}
+
+#if 1
+static INT ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index)
+{
+ ULONG R;
+ CHAR TxPower;
+ UCHAR Bbp94 = 0;
+ BOOLEAN bPowerReduce = FALSE;
+#ifdef RT30xx
+ UCHAR RFValue;
+#endif // RT30xx //
+#ifdef RALINK_28xx_QA
+ if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+ {
+ /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+ ** are not synchronized.
+ */
+/*
+ pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+ pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+ return 0;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if (TxPower > 31)
+ {
+ //
+ // R3, R4 can't large than 31 (0x24), 31 ~ 36 used by BBP 94
+ //
+ R = 31;
+ if (TxPower <= 36)
+ Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+ }
+ else if (TxPower < 0)
+ {
+ //
+ // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+ //
+ R = 0;
+ if (TxPower >= -6)
+ Bbp94 = BBPR94_DEFAULT + TxPower;
+ }
+ else
+ {
+ // 0 ~ 31
+ R = (ULONG) TxPower;
+ Bbp94 = BBPR94_DEFAULT;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+ }
+ else// 5.5 GHz
+ {
+ if (TxPower > 15)
+ {
+ //
+ // R3, R4 can't large than 15 (0x0F)
+ //
+ R = 15;
+ }
+ else if (TxPower < 0)
+ {
+ //
+ // R3, R4 can't less than 0
+ //
+ // -1 ~ -7
+ ASSERT((TxPower >= -7));
+ R = (ULONG)(TxPower + 7);
+ bPowerReduce = TRUE;
+ }
+ else
+ {
+ // 0 ~ 15
+ R = (ULONG) TxPower;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R=%lu)\n", __FUNCTION__, TxPower, R));
+ }
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time<--
+#ifdef RT30xx
+ if(IS_RT30xx(pAd))
+ {
+ // Set Tx Power
+
+ RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+ RFValue = (RFValue & 0xE0) | TxPower;
+ RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("3070 or 2070:%s (TxPower=%d, RFValue=%x)\n", __FUNCTION__, TxPower, RFValue));
+
+ }
+ else
+#endif // RT30xx //
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ if (index == 0)
+ {
+ R = R << 9; // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = R << 6; // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+ else// 5.5GHz
+ {
+ if (bPowerReduce == FALSE)
+ {
+ if (index == 0)
+ {
+ R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+ else
+ {
+ if (index == 0)
+ {
+ R = (R << 10); // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+
+ /* Clear bit 9 of R3 to reduce 7dB. */
+ pAd->LatchRfRegs.R3 = (R & (~(1 << 9)));
+ }
+ else
+ {
+ R = (R << 7); // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+
+ /* Clear bit 6 of R4 to reduce 7dB. */
+ pAd->LatchRfRegs.R4 = (R & (~(1 << 6)));
+ }
+ }
+ }
+ RtmpRfIoWrite(pAd);
+ }
+//2008/09/10:KH adds to support 3070 ATE TX Power tunning real time-->
+
+ return 0;
+ }
+}
+#else// 1 //
+static INT ATETxPwrHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN char index)
+{
+ ULONG R;
+ CHAR TxPower;
+ UCHAR Bbp94 = 0;
+
+#ifdef RALINK_28xx_QA
+ if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+ {
+ // TODO: how to get current TxPower0/1 from pAd->LatchRfRegs ?
+ /* When QA is used for Tx, pAd->ate.TxPower0/1 and real tx power
+ ** are not synchronized.
+ */
+/*
+ pAd->ate.TxPower0 = pAd->LatchRfRegs.xxx;
+ pAd->ate.TxPower1 = pAd->LatchRfRegs.xxx;
+*/
+ return 0;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ TxPower = index == 0 ? pAd->ate.TxPower0 : pAd->ate.TxPower1;
+
+ if (TxPower > 31)
+ {
+ //
+ // R3, R4 can't large than 36 (0x24), 31 ~ 36 used by BBP 94
+ //
+ R = 31;
+ if (TxPower <= 36)
+ Bbp94 = BBPR94_DEFAULT + (UCHAR)(TxPower - 31);
+ }
+ else if (TxPower < 0)
+ {
+ //
+ // R3, R4 can't less than 0, -1 ~ -6 used by BBP 94
+ //
+ R = 0;
+ if (TxPower >= -6)
+ Bbp94 = BBPR94_DEFAULT + TxPower;
+ }
+ else
+ {
+ // 0 ~ 31
+ R = (ULONG) TxPower;
+ Bbp94 = BBPR94_DEFAULT;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("%s (TxPower=%d, R3=%ld, BBP_R94=%d)\n", __FUNCTION__, TxPower, R, Bbp94));
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if (index == 0)
+ {
+ R = R << 9; // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = R << 6; // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+ else
+ {
+ if (index == 0)
+ {
+ R = (R << 10) | (1 << 9); // shift TX power control to correct RF(R3) register bit position
+ R |= (pAd->LatchRfRegs.R3 & 0xffffc1ff);
+ pAd->LatchRfRegs.R3 = R;
+ }
+ else
+ {
+ R = (R << 7) | (1 << 6); // shift TX power control to correct RF(R4) register bit position
+ R |= (pAd->LatchRfRegs.R4 & 0xfffff83f);
+ pAd->LatchRfRegs.R4 = R;
+ }
+ }
+
+ RtmpRfIoWrite(pAd);
+
+ return 0;
+ }
+}
+#endif // 1 //
+/*
+ ==========================================================================
+ Description:
+ Set ATE operation mode to
+ 0. ATESTART = Start ATE Mode
+ 1. ATESTOP = Stop ATE Mode
+ 2. TXCONT = Continuous Transmit
+ 3. TXCARR = Transmit Carrier
+ 4. TXFRAME = Transmit Frames
+ 5. RXFRAME = Receive Frames
+#ifdef RALINK_28xx_QA
+ 6. TXSTOP = Stop Any Type of Transmition
+ 7. RXSTOP = Stop Receiving Frames
+#endif // RALINK_28xx_QA //
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+/* */
+/* */
+/*=======================End of RT2860=======================*/
+
+
+/*======================Start of RT2870======================*/
+/* */
+/* */
+
+#ifdef RT2870
+static INT ATECmdHandler(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UINT32 Value;
+ UCHAR BbpData;
+ UINT32 MacData;
+ UINT i=0, atemode;
+ //NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
+ //PUCHAR pDest;
+ UINT32 temp;
+ ULONG IrqFlags;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("===> ATECmdHandler()\n"));
+ ATEAsicSwitchChannel(pAd);
+ /* AsicLockChannel() is empty function so far in fact */
+ AsicLockChannel(pAd, pAd->ate.Channel);
+
+ RTMPusecDelay(5000);
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+
+ /* Enter ATE mode and set Tx/Rx Idle */
+ if (!strcmp(arg, "ATESTART"))
+ {
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN Cancelled;
+#endif // CONFIG_STA_SUPPORT //
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: ATESTART\n"));
+
+ netif_stop_queue(pAd->net_dev);
+
+ atemode = pAd->ate.Mode;
+ pAd->ate.Mode = ATE_START;
+// pAd->ate.TxDoneCount = pAd->ate.TxCount;
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Disable auto responder
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+ temp = temp & 0xFFFFFFFE;
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+ // read MAC_SYS_CTRL and backup MAC_SYS_CTRL value.
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ // clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+ // Stop continuous TX production test.
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);//disable or cancel pending irp first ???
+
+ if (atemode & ATE_TXCARR
+#ifdef RT30xx
+ || atemode & ATE_TXCONT
+#endif // RT30xx //
+)
+ {
+#ifdef RT30xx
+ //Hardware Reset BBP
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp |0x00000002;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp & ~(0x00000002);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ //Restore All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+ // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ else if (atemode & ATE_TXCARRSUPP)
+ {
+#ifdef RT30xx
+ //Hardware Reset BBP
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp |0x00000002;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &temp);
+ temp = temp & ~(0x00000002);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, temp);
+ //Restore All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd,i,restore_BBP[i]);
+#endif // RT30xx //
+
+ // No Cont. TX set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ // No Carrier Suppression set BBP R24 bit0=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+ BbpData &= 0xFFFFFFFE; //clear bit0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+ }
+ // We should free some resource which allocate when ATE_TXFRAME , ATE_STOP, and ATE_TXCONT.
+ // TODO:Should we free some resource which was allocated when LoopBack and ATE_STOP ?
+ else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+ {
+ if (atemode & ATE_TXCONT)
+ {
+ // Not Cont. TX anymore, so set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ // Abort Tx, Rx DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ {
+ // It seems nothing to free,
+ // because we didn't allocate any resource when we entered ATE_TXFRAME mode latestly.
+ }
+
+ // Start Tx, RX DMA
+ RtmpDmaEnable(pAd, 1);
+ }
+
+ RTUSBRejectPendingPackets(pAd);
+ RTUSBCleanUpDataBulkOutQueue(pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ //
+ // It will be called in MlmeSuspend().
+ //
+ // Cancel pending timers
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled);
+#endif // CONFIG_STA_SUPPORT //
+
+ //RTUSBCleanUpMLMEWaitQueue(pAd); /* not used in RT28xx */
+ RTUSBCleanUpMLMEBulkOutQueue(pAd);
+
+ // Sometimes kernel will hang on, so we avoid calling MlmeSuspend().
+// MlmeSuspend(pAd, TRUE);
+ //RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ // Disable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Make sure there are no pending bulk in/out IRPs before we go on.
+/*=========================================================================*/
+ /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ while ((pAd->PendingRx > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+ NdisInterlockedDecrement(&pAd->PendingRx);
+#endif
+ /* delay 0.5 seconds */
+ RTMPusecDelay(500000);
+ pAd->PendingRx = 0;
+ }
+ /* peter : why don't we have to get BulkOutLock first ? */
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ /* pAd->BulkOutPending[y] will be set to FALSE in RTUSBCancelPendingBulkOutIRP(pAd) */
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ /* we have enough time delay in RTUSBCancelPendingBulkOutIRP(pAd)
+ ** so this is not necessary
+ */
+// RTMPusecDelay(500000);
+ }
+
+ /* pAd->PendingRx is not of type atomic_t anymore in 28xx */
+// ASSERT(atomic_read(&pAd->PendingRx) == 0);
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+ // reset Rx statistics.
+ pAd->ate.LastSNR0 = 0;
+ pAd->ate.LastSNR1 = 0;
+ pAd->ate.LastRssi0 = 0;
+ pAd->ate.LastRssi1 = 0;
+ pAd->ate.LastRssi2 = 0;
+ pAd->ate.AvgRssi0 = 0;
+ pAd->ate.AvgRssi1 = 0;
+ pAd->ate.AvgRssi2 = 0;
+ pAd->ate.AvgRssi0X8 = 0;
+ pAd->ate.AvgRssi1X8 = 0;
+ pAd->ate.AvgRssi2X8 = 0;
+ pAd->ate.NumOfAvgRssiSample = 0;
+
+#ifdef RALINK_28xx_QA
+ // Tx frame
+ pAd->ate.bQATxStart = FALSE;
+ pAd->ate.bQARxStart = FALSE;
+ pAd->ate.seq = 0;
+
+ // counters
+ pAd->ate.U2M = 0;
+ pAd->ate.OtherData = 0;
+ pAd->ate.Beacon = 0;
+ pAd->ate.OtherCount = 0;
+ pAd->ate.TxAc0 = 0;
+ pAd->ate.TxAc1 = 0;
+ pAd->ate.TxAc2 = 0;
+ pAd->ate.TxAc3 = 0;
+ pAd->ate.TxHCCA = 0;
+ pAd->ate.TxMgmt = 0;
+ pAd->ate.RSSI0 = 0;
+ pAd->ate.RSSI1 = 0;
+ pAd->ate.RSSI2 = 0;
+ pAd->ate.SNR0 = 0;
+ pAd->ate.SNR1 = 0;
+
+ // control
+ pAd->ate.TxDoneCount = 0;
+ pAd->ate.TxStatus = 0; // task Tx status // 0 --> task is idle, 1 --> task is running
+#endif // RALINK_28xx_QA //
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AsicDisableSync(pAd);
+
+ /*
+ ** If we skip "LinkDown()", we should disable protection
+ ** to prevent from sending out RTS or CTS-to-self.
+ */
+ ATEDisableAsicProtect(pAd);
+ RTMPStationStop(pAd);
+#endif // CONFIG_STA_SUPPORT //
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+ //Clean ATE Bulk in/out counter and continue setup
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+ /* NdisAcquireSpinLock()/NdisReleaseSpinLock() need only one argument in RT28xx */
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = FALSE;
+ pAd->ContinBulkIn = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+ }
+ else if (!strcmp(arg, "ATESTOP"))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE : ATESTOP ===>\n"));
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);//0820
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData); // recover the MAC_SYS_CTRL register back.
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ /*
+ ** Abort Tx, RX DMA.
+ ** Q : How to do the following I/O if Tx, Rx DMA is aborted ?
+ ** Ans : Bulk endpoints are aborted, while the control endpoint is not.
+ */
+ RtmpDmaEnable(pAd, 0);
+
+ // Disable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ /* Make sure there are no pending bulk in/out IRPs before we go on. */
+/*=========================================================================*/
+// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ while (pAd->PendingRx > 0)
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+// NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+#endif
+ RTMPusecDelay(500000);
+ }
+
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ RTMPusecDelay(500000);
+ }
+
+// ASSERT(atomic_read(&pAd->PendingRx) == 0);
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+/* Reset Rx RING */
+/*=========================================================================*/
+// InterlockedExchange(&pAd->PendingRx, 0);
+ pAd->PendingRx = 0;
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
+ pAd->NextRxBulkInPosition = 0;
+ for (i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+ NdisZeroMemory(pRxContext->TransferBuffer, MAX_RXBULK_SIZE);
+ /* peter : why don't we have to get BulkInLock first ? */
+ pRxContext->pAd = pAd;
+ pRxContext->pIrp = NULL;
+ /* peter debug ++ */
+ pRxContext->BulkInOffset = 0;
+ pRxContext->bRxHandling = FALSE;
+ /* peter debug -- */
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+// pRxContext->ReorderInUse = FALSE;
+// pRxContext->ReadPosOffset = 0;
+ }
+
+/*=========================================================================*/
+/* Reset Tx RING */
+/*=========================================================================*/
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+/*=========================================================================*/
+ // Enable auto responder.
+ RTMP_IO_READ32(pAd, AUTO_RSP_CFG, &temp);
+ temp = temp | (0x01);
+ RTMP_IO_WRITE32(pAd, AUTO_RSP_CFG, temp);
+
+/*================================================*/
+ AsicEnableBssSync(pAd);
+
+ /* Soft reset BBP.*/
+ /* In 2870 chipset, ATE_BBP_IO_READ8_BY_REG_ID() == RTMP_BBP_IO_READ8_BY_REG_ID() */
+ /* Both rt2870ap and rt2870sta use BbpSoftReset(pAd) to do BBP soft reset */
+ BbpSoftReset(pAd);
+/*================================================*/
+ {
+#ifdef CONFIG_STA_SUPPORT
+ // Set all state machines back IDLE
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ pAd->Mlme.AuthRspMachine.CurrState = AUTH_RSP_IDLE;
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ pAd->Mlme.ActMachine.CurrState = ACT_IDLE;
+#endif // CONFIG_STA_SUPPORT //
+
+ //
+ // ===> refer to MlmeRestartStateMachine().
+ // When we entered ATE_START mode, PeriodicTimer was not cancelled.
+ // So we don't have to set it here.
+ //
+ //RTMPSetTimer(pAd, &pAd->Mlme.PeriodicTimer, MLME_TASK_EXEC_INTV);
+
+ ASSERT(pAd->CommonCfg.Channel != 0);
+
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ RTMPStationStart(pAd);
+#endif // CONFIG_STA_SUPPORT //
+ }
+//
+// These two steps have been done when entering ATE_STOP mode.
+//
+ // Clean ATE Bulk in/out counter and continue setup.
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = FALSE;
+ pAd->ContinBulkIn = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ /* Wait 50ms to prevent next URB to bulkout during HW reset. */
+ /* todo : remove this if not necessary */
+ NdisMSleep(50000);
+
+ pAd->ate.Mode = ATE_STOP;
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+/*=========================================================================*/
+ /* restore RX_FILTR_CFG */
+#ifdef CONFIG_STA_SUPPORT
+ /* restore RX_FILTR_CFG in order that QA maybe set it to 0x3 */
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL);
+#endif // CONFIG_STA_SUPPORT //
+/*=========================================================================*/
+
+ // Enable Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ // Enable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Wait 10ms to wait all of the bulk-in URBs to complete.
+ /* todo : remove this if not necessary */
+ NdisMSleep(10000);
+
+ // Everything is ready to start normal Tx/Rx.
+ RTUSBBulkReceive(pAd);
+ netif_start_queue(pAd->net_dev);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATE : ATESTOP \n"));
+ }
+ else if (!strcmp(arg, "TXCARR")) // Tx Carrier
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCARR\n"));
+ pAd->ate.Mode |= ATE_TXCARR;
+
+#ifdef RT30xx
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ restore_BBP[i]=0;
+ //Record All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+ // Disable Rx
+ // May be we need not to do this, because these have been done in ATE_START mode ???
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // QA has done the following steps if it is used.
+ if (pAd->ate.bQATxStart == FALSE)
+ {
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Carrier Test set BBP R22 bit7=1, bit6=1, bit[5~0]=0x01
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+ BbpData |= 0x000000C1; //set bit7=1, bit6=1, bit[5~0]=0x01
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ // set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value = Value | 0x00000010;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+ }
+ }
+ else if (!strcmp(arg, "TXCONT")) // Tx Continue
+ {
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ /* set MAC_SYS_CTRL(0x1004) bit4(Continuous Tx Production Test)
+ and bit2(MAC TX enable) back to zero. */
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ MacData &= 0xFFFFFFEB;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+ // set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF7F; //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+
+ /* for TxCont mode.
+ ** Step 1: Send 50 packets first then wait for a moment.
+ ** Step 2: Send more 50 packet then start continue mode.
+ */
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXCONT\n"));
+
+#ifdef RT30xx
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ restore_BBP[i]=0;
+ //Record All BBP Value
+ for(i=0;i<ATE_BBP_REG_NUM;i++)
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd,i,&restore_BBP[i]);
+#endif // RT30xx //
+
+ // Step 1: send 50 packets first.
+ pAd->ate.Mode |= ATE_TXCONT;
+ pAd->ate.TxCount = 50;
+ pAd->ate.TxDoneCount = 0;
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+
+ /* Only needed if we have to send some normal frames. */
+ SetJapanFilter(pAd);
+
+ // Setup frame format.
+ ATESetUpFrame(pAd, 0);
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Start Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pAd->ate.TxStatus = 1;
+ //pAd->ate.Repeat = 0;
+ }
+#endif // RALINK_28xx_QA //
+
+ NdisAcquireSpinLock(&pAd->GenericLock);//0820
+ pAd->ContinBulkOut = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+
+ /* To make sure all the 50 frames have been bulk out before executing step 2 */
+ while (atomic_read(&pAd->BulkOutRemained) > 0)
+ {
+ RTMPusecDelay(5000);
+ }
+
+ // Step 2: send more 50 packets then start continue mode.
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ // Cont. TX set BBP R22 bit7=1
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData |= 0x00000080; //set bit7=1
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ pAd->ate.TxCount = 50;
+ pAd->ate.TxDoneCount = 0;
+
+ SetJapanFilter(pAd);
+
+ // Setup frame format.
+ ATESetUpFrame(pAd, 0);
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+
+ // Start Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pAd->ate.TxStatus = 1;
+ //pAd->ate.Repeat = 0;
+ }
+#endif // RALINK_28xx_QA //
+
+ NdisAcquireSpinLock(&pAd->GenericLock);//0820
+ pAd->ContinBulkOut = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+
+#if 1
+ RTMPusecDelay(500);
+#else
+ while (atomic_read(&pAd->BulkOutRemained) > 0)
+ {
+ RTMPusecDelay(5000);
+ }
+#endif // 1 //
+
+ // Set MAC_SYS_CTRL(0x1004) Continuous Tx Production Test (bit4) = 1.
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ MacData |= 0x00000010;
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+ }
+ else if (!strcmp(arg, "TXFRAME")) // Tx Frames
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXFRAME(Count=0x%08x)\n", pAd->ate.TxCount));
+ pAd->ate.Mode |= ATE_TXFRAME;
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+#ifdef RALINK_28xx_QA
+ // add this for LoopBack mode
+ if (pAd->ate.bQARxStart == FALSE)
+ {
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+ }
+
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pAd->ate.TxStatus = 1;
+ //pAd->ate.Repeat = 0;
+ }
+#else
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+#endif // RALINK_28xx_QA //
+
+ // Enable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ SetJapanFilter(pAd);
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ pAd->ate.TxDoneCount = 0;
+
+ // Setup frame format
+ ATESetUpFrame(pAd, 0);
+
+ // Start Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ // Check count is continuous or not yet.
+ //
+ // Due to the type mismatch between "pAd->BulkOutRemained"(atomic_t) and "pAd->ate.TxCount"(UINT32)
+ //
+ if (pAd->ate.TxCount == 0)
+ {
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+ }
+ else
+ {
+ InterlockedExchange(&pAd->BulkOutRemained, pAd->ate.TxCount);
+ }
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("bulk out count = %d\n", atomic_read(&pAd->BulkOutRemained)));
+ ASSERT((atomic_read(&pAd->BulkOutRemained) >= 0));
+
+ if (atomic_read(&pAd->BulkOutRemained) == 0)
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packet countinuously\n"));
+
+ /* In 28xx, NdisAcquireSpinLock() == spin_lock_bh() */
+ /* NdisAcquireSpinLock only need one argument in 28xx. */
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = TRUE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ /* In 28xx, BULK_OUT_LOCK() == spin_lock_irqsave() */
+ BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+ pAd->BulkOutPending[0] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);// peter : NdisAcquireSpinLock ==> BULK_OUT_LOCK
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Send packets depend on counter\n"));
+
+ NdisAcquireSpinLock(&pAd->GenericLock);
+ pAd->ContinBulkOut = FALSE;
+ NdisReleaseSpinLock(&pAd->GenericLock);
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[0], IrqFlags);
+ pAd->BulkOutPending[0] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[0], IrqFlags);
+ }
+
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+ // Kick bulk out
+ RTUSBKickBulkOut(pAd);
+ }
+#ifdef RALINK_28xx_QA
+ else if (!strcmp(arg, "TXSTOP")) //Enter ATE mode and set Tx/Rx Idle
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: TXSTOP\n"));
+
+ atemode = pAd->ate.Mode;
+ pAd->ate.Mode &= ATE_TXSTOP;
+ pAd->ate.bQATxStart = FALSE;
+// pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+ if (atemode & ATE_TXCARR)
+ {
+ // No Carrier Test set BBP R22 bit7=0, bit6=0, bit[5~0]=0x0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= 0xFFFFFF00; //clear bit7, bit6, bit[5~0]
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ else if (atemode & ATE_TXCARRSUPP)
+ {
+ // No Cont. TX set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+
+ // No Carrier Suppression set BBP R24 bit0=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R24, &BbpData);
+ BbpData &= 0xFFFFFFFE; //clear bit0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R24, BbpData);
+ }
+ else if ((atemode & ATE_TXFRAME) || (atemode == ATE_STOP))
+ {
+ if (atemode & ATE_TXCONT)
+ {
+ // No Cont. TX set BBP R22 bit7=0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R22, &BbpData);
+ BbpData &= ~(1 << 7); //set bit7=0
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ }
+ }
+
+/*=========================================================================*/
+ RTUSBRejectPendingPackets(pAd);
+ RTUSBCleanUpDataBulkOutQueue(pAd);
+
+ /* not used in RT28xx */
+ //RTUSBCleanUpMLMEWaitQueue(pAd);
+ /* empty function so far */
+ RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+
+ /* In 28xx, pAd->PendingRx is not of type atomic_t anymore */
+// while ((atomic_read(&pAd->PendingRx) > 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ /* peter todo : BulkInLock */
+ while (pAd->PendingRx > 0)
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+// NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+#endif
+ RTMPusecDelay(500000);
+ }
+
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ RTMPusecDelay(500000);
+ }
+
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+ // Enable Tx, Rx DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ /* task Tx status : 0 --> task is idle, 1 --> task is running */
+ pAd->ate.TxStatus = 0;
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+
+ // Disable Tx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ MacData &= (0xfffffffb);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+ //Clean ATE Bulk in/out counter and continue setup
+ InterlockedExchange(&pAd->BulkOutRemained, 0);
+
+ pAd->ContinBulkOut = FALSE;
+ }
+ else if (!strcmp(arg, "RXSTOP"))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXSTOP\n"));
+ atemode = pAd->ate.Mode;
+
+ // Disable Rx
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ pAd->ate.Mode &= ATE_RXSTOP;
+ pAd->ate.bQARxStart = FALSE;
+// pAd->ate.TxDoneCount = pAd->ate.TxCount;
+
+/*=========================================================================*/
+ RTUSBRejectPendingPackets(pAd);
+ RTUSBCleanUpDataBulkOutQueue(pAd);
+
+ /* not used in RT28xx */
+ //RTUSBCleanUpMLMEWaitQueue(pAd);
+ RTUSBCleanUpMLMEBulkOutQueue(pAd);
+/*=========================================================================*/
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+/*=========================================================================*/
+// while ((atomic_read(&pAd->PendingRx) > 0))
+ while (pAd->PendingRx > 0)
+ {
+#if 1
+ ATE_RTUSBCancelPendingBulkInIRP(pAd);
+#else
+// NdisInterlockedDecrement(&pAd->PendingRx);
+ pAd->PendingRx--;
+#endif
+ RTMPusecDelay(500000);
+ }
+
+ while (((pAd->BulkOutPending[0] == TRUE) ||
+ (pAd->BulkOutPending[1] == TRUE) ||
+ (pAd->BulkOutPending[2] == TRUE) ||
+ (pAd->BulkOutPending[3] == TRUE)) && (pAd->BulkFlags != 0)) //pAd->BulkFlags != 0 wait bulk out finish
+ {
+ do
+ {
+ RTUSBCancelPendingBulkOutIRP(pAd);
+ } while (FALSE);
+
+ RTMPusecDelay(500000);
+ }
+
+ ASSERT(pAd->PendingRx == 0);
+/*=========================================================================*/
+
+ // Soft reset BBP.
+ BbpSoftReset(pAd);
+ pAd->ContinBulkIn = FALSE;
+ }
+#endif // RALINK_28xx_QA //
+ else if (!strcmp(arg, "RXFRAME")) // Rx Frames
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: RXFRAME\n"));
+
+ // Disable Rx of MAC block
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Default value in BBP R22 is 0x0.
+ BbpData = 0;
+
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &MacData);
+ // Clean bit4 to stop continuous Tx production test.
+ MacData &= 0xFFFFFFEF;
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R22, BbpData);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, MacData);
+
+ pAd->ate.Mode |= ATE_RXFRAME;
+
+ // Abort Tx, RX DMA.
+ RtmpDmaEnable(pAd, 0);
+
+ // Disable TX of MAC block
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value &= ~(1 << 2);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Reset Rx RING.
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ PRX_CONTEXT pRxContext = &(pAd->RxContext[i]);
+
+ pRxContext->InUse = FALSE;
+ pRxContext->IRPPending = FALSE;
+ pRxContext->Readable = FALSE;
+
+ //
+ // Get the urb from kernel back to driver.
+ //
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+
+ /* Sleep 200 microsecs to give cancellation time to work. */
+ NdisMSleep(200);
+ pAd->BulkInReq = 0;
+
+// InterlockedExchange(&pAd->PendingRx, 0);
+ pAd->PendingRx = 0;
+ pAd->NextRxBulkInReadIndex = 0; // Next Rx Read index
+ pAd->NextRxBulkInIndex = RX_RING_SIZE - 1; // Rx Bulk pointer
+ pAd->NextRxBulkInPosition = 0;
+ }
+
+ // read to clear counters
+ RTUSBReadMACRegister(pAd, RX_STA_CNT0, &temp); //RX PHY & RX CRC count
+ RTUSBReadMACRegister(pAd, RX_STA_CNT1, &temp); //RX PLCP error count & CCA false alarm count
+ RTUSBReadMACRegister(pAd, RX_STA_CNT2, &temp); //RX FIFO overflow frame count & RX duplicated filtered frame count
+
+ pAd->ContinBulkIn = TRUE;
+
+ // Enable Tx, RX DMA.
+ RtmpDmaEnable(pAd, 1);
+
+ // Enable RX of MAC block
+ RTMP_IO_READ32(pAd, MAC_SYS_CTRL, &Value);
+ Value |= (1 << 3);
+ RTMP_IO_WRITE32(pAd, MAC_SYS_CTRL, Value);
+
+ // Kick bulk in
+ RTUSBBulkReceive(pAd);
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATE: Invalid arg!\n"));
+ return FALSE;
+ }
+ RTMPusecDelay(5000);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== ATECmdHandler()\n"));
+
+ return TRUE;
+}
+#endif // RT2870 //
+
+INT Set_ATE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ if (ATECmdHandler(pAd, arg))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Success\n"));
+
+
+ return TRUE;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_Proc Failed\n"));
+ return FALSE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE ADDR1=DA for TxFrame(AP : To DS = 0 ; From DS = 1)
+ or
+ Set ATE ADDR3=DA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_DA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *value;
+ INT i;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AtoH(value, &pAd->ate.Addr3[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if(i != 6)
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_DA_Proc (DA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr3[0],
+ pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_DA_Proc Success\n"));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE ADDR3=SA for TxFrame(AP : To DS = 0 ; From DS = 1)
+ or
+ Set ATE ADDR2=SA for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_SA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *value;
+ INT i;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AtoH(value, &pAd->ate.Addr2[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if(i != 6)
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_SA_Proc (SA = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr2[0],
+ pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_SA_Proc Success\n"));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE ADDR2=BSSID for TxFrame(AP : To DS = 0 ; From DS = 1)
+ or
+ Set ATE ADDR1=BSSID for TxFrame(STA : To DS = 1 ; From DS = 0)
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_BSSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *value;
+ INT i;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg, ":"); value; value = rstrtok(NULL, ":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ AtoH(value, &pAd->ate.Addr1[i++], 1);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ if(i != 6)
+ return FALSE; //Invalid
+
+
+#ifdef CONFIG_STA_SUPPORT
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_BSSID_Proc (BSSID = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAd->ate.Addr1[0],
+ pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]));
+#endif // CONFIG_STA_SUPPORT //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_BSSID_Proc Success\n"));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Channel
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_CHANNEL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR channel;
+
+ channel = simple_strtol(arg, 0, 10);
+
+ if ((channel < 1) || (channel > 216))// to allow A band channel : ((channel < 1) || (channel > 14))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_CHANNEL_Proc::Out of range, it should be in range of 1~14.\n"));
+ return FALSE;
+ }
+ pAd->ate.Channel = channel;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_CHANNEL_Proc (ATE Channel = %d)\n", pAd->ate.Channel));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_CHANNEL_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Power0
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_POWER0_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR TxPower;
+
+ TxPower = simple_strtol(arg, 0, 10);
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if ((TxPower > 31) || (TxPower < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+ else// 5.5GHz
+ {
+ if ((TxPower > 15) || (TxPower < -7))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER0_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+
+ pAd->ate.TxPower0 = TxPower;
+ ATETxPwrHandler(pAd, 0);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER0_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Power1
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_POWER1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR TxPower;
+
+ TxPower = simple_strtol(arg, 0, 10);
+
+ if (pAd->ate.Channel <= 14)
+ {
+ if ((TxPower > 31) || (TxPower < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+ else
+ {
+ if ((TxPower > 15) || (TxPower < -7))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_POWER1_Proc::Out of range (Value=%d)\n", TxPower));
+ return FALSE;
+ }
+ }
+
+ pAd->ate.TxPower1 = TxPower;
+ ATETxPwrHandler(pAd, 1);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_POWER1_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx Antenna
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR value;
+
+ value = simple_strtol(arg, 0, 10);
+
+ if ((value > 2) || (value < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_Antenna_Proc::Out of range (Value=%d)\n", value));
+ return FALSE;
+ }
+
+ pAd->ate.TxAntennaSel = value;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_Antenna_Proc (Antenna = %d)\n", pAd->ate.TxAntennaSel));
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Ralink: Set_ATE_TX_Antenna_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Rx Antenna
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_RX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR value;
+
+ value = simple_strtol(arg, 0, 10);
+
+ if ((value > 3) || (value < 0))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_RX_Antenna_Proc::Out of range (Value=%d)\n", value));
+ return FALSE;
+ }
+
+ pAd->ate.RxAntennaSel = value;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_Antenna_Proc (Antenna = %d)\n", pAd->ate.RxAntennaSel));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_Antenna_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE RF frequence offset
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_FREQOFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR RFFreqOffset;
+ ULONG R4;
+
+ RFFreqOffset = simple_strtol(arg, 0, 10);
+#ifndef RT30xx
+ if(RFFreqOffset >= 64)
+#endif // RT30xx //
+#ifdef RT30xx
+//2008/08/06: KH modified the limit of offset value from 65 to 95(0x5F)
+ if(RFFreqOffset >= 95)
+#endif // RT30xx //
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_FREQOFFSET_Proc::Out of range, it should be in range of 0~63.\n"));
+ return FALSE;
+ }
+
+ pAd->ate.RFFreqOffset = RFFreqOffset;
+#ifdef RT30xx
+ if(IS_RT30xx(pAd))
+ {
+ // Set RF offset
+ UCHAR RFValue;
+ RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+ //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+ RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+ RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+ }
+ else
+#endif // RT30xx //
+ {
+
+ R4 = pAd->ate.RFFreqOffset << 15; // shift TX power control to correct RF register bit position
+ R4 |= (pAd->LatchRfRegs.R4 & ((~0x001f8000)));
+ pAd->LatchRfRegs.R4 = R4;
+
+ RtmpRfIoWrite(pAd);
+ }
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_FREQOFFSET_Proc (RFFreqOffset = %d)\n", pAd->ate.RFFreqOffset));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_FREQOFFSET_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE RF BW
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ int i;
+ UCHAR value = 0;
+ UCHAR BBPCurrentBW;
+
+ BBPCurrentBW = simple_strtol(arg, 0, 10);
+
+ if(BBPCurrentBW == 0)
+ pAd->ate.TxWI.BW = BW_20;
+ else
+ pAd->ate.TxWI.BW = BW_40;
+
+ if(pAd->ate.TxWI.BW == BW_20)
+ {
+ if(pAd->ate.Channel <= 14)
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx20MPwrCfgGBand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgGBand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx20MPwrCfgABand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx20MPwrCfgABand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+ }
+
+ //Set BBP R4 bit[4:3]=0:0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+ value &= (~0x18);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+ //Set BBP R66=0x3C
+ value = 0x3C;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+ //Set BBP R68=0x0B
+ //to improve Rx sensitivity.
+ value = 0x0B;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+ //Set BBP R69=0x16
+ value = 0x16;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+ //Set BBP R70=0x08
+ value = 0x08;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+ //Set BBP R73=0x11
+ value = 0x11;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+ // If Channel=14, Bandwidth=20M and Mode=CCK, Set BBP R4 bit5=1
+ // (Japan filter coefficients)
+ // This segment of code will only works when ATETXMODE and ATECHANNEL
+ // were set to MODE_CCK and 14 respectively before ATETXBW is set to 0.
+ //=====================================================================
+ if (pAd->ate.Channel == 14)
+ {
+ int TxMode = pAd->ate.TxWI.PHYMODE;
+ if (TxMode == MODE_CCK)
+ {
+ // when Channel==14 && Mode==CCK && BandWidth==20M, BBP R4 bit5=1
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+ value |= 0x20; //set bit5=1
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+ }
+ }
+
+ //=====================================================================
+ // If bandwidth != 40M, RF Reg4 bit 21 = 0.
+#ifdef RT30xx
+ // Set BW
+ if(IS_RT30xx(pAd))
+ RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW20RfR24);
+ else
+#endif // RT30xx //
+ {
+ pAd->LatchRfRegs.R4 &= ~0x00200000;
+ RtmpRfIoWrite(pAd);
+ }
+
+ }
+ else if(pAd->ate.TxWI.BW == BW_40)
+ {
+ if(pAd->ate.Channel <= 14)
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx40MPwrCfgGBand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgGBand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+ }
+ else
+ {
+ for (i=0; i<5; i++)
+ {
+ if (pAd->Tx40MPwrCfgABand[i] != 0xffffffff)
+ {
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, pAd->Tx40MPwrCfgABand[i]);
+ RTMPusecDelay(5000);
+ }
+ }
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->ate.TxWI.PHYMODE >= MODE_HTMIX) && (pAd->ate.TxWI.MCS == 7))
+ {
+ value = 0x28;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R67, value);
+ }
+#endif // DOT11_N_SUPPORT //
+ }
+
+ //Set BBP R4 bit[4:3]=1:0
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &value);
+ value &= (~0x18);
+ value |= 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, value);
+
+ //Set BBP R66=0x3C
+ value = 0x3C;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, value);
+ //Set BBP R68=0x0C
+ //to improve Rx sensitivity.
+ value = 0x0C;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R68, value);
+ //Set BBP R69=0x1A
+ value = 0x1A;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, value);
+ //Set BBP R70=0x0A
+ value = 0x0A;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, value);
+ //Set BBP R73=0x16
+ value = 0x16;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, value);
+
+ // If bandwidth = 40M, set RF Reg4 bit 21 = 1.
+#ifdef RT30xx
+ // Set BW
+ if(IS_RT30xx(pAd))
+ RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR) pAd->Mlme.CaliBW40RfR24);
+ else
+#endif // RT30xx //
+ {
+ pAd->LatchRfRegs.R4 |= 0x00200000;
+ RtmpRfIoWrite(pAd);
+ }
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_BW_Proc (BBPCurrentBW = %d)\n", pAd->ate.TxWI.BW));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_BW_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame length
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_LENGTH_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxLength = simple_strtol(arg, 0, 10);
+
+ if((pAd->ate.TxLength < 24) || (pAd->ate.TxLength > (MAX_FRAME_SIZE - 34/* == 2312 */)))
+ {
+ pAd->ate.TxLength = (MAX_FRAME_SIZE - 34/* == 2312 */);
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_LENGTH_Proc::Out of range, it should be in range of 24~%d.\n", (MAX_FRAME_SIZE - 34/* == 2312 */)));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_LENGTH_Proc (TxLength = %d)\n", pAd->ate.TxLength));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_LENGTH_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame count
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_COUNT_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxCount = simple_strtol(arg, 0, 10);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_COUNT_Proc (TxCount = %d)\n", pAd->ate.TxCount));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_COUNT_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame MCS
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_MCS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR MCS;
+ int result;
+
+ MCS = simple_strtol(arg, 0, 10);
+ result = CheckMCSValid(pAd->ate.TxWI.PHYMODE, MCS);
+
+ if (result != -1)
+ {
+ pAd->ate.TxWI.MCS = (UCHAR)MCS;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MCS_Proc::Out of range, refer to rate table.\n"));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MCS_Proc (MCS = %d)\n", pAd->ate.TxWI.MCS));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MCS_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame Mode
+ 0: MODE_CCK
+ 1: MODE_OFDM
+ 2: MODE_HTMIX
+ 3: MODE_HTGREENFIELD
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_MODE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxWI.PHYMODE = simple_strtol(arg, 0, 10);
+
+ if(pAd->ate.TxWI.PHYMODE > 3)
+ {
+ pAd->ate.TxWI.PHYMODE = 0;
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_MODE_Proc::Out of range. it should be in range of 0~3\n"));
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("0: CCK, 1: OFDM, 2: HT_MIX, 3: HT_GREEN_FIELD.\n"));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_MODE_Proc (TxMode = %d)\n", pAd->ate.TxWI.PHYMODE));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_MODE_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set ATE Tx frame GI
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_ATE_TX_GI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.TxWI.ShortGI = simple_strtol(arg, 0, 10);
+
+ if(pAd->ate.TxWI.ShortGI > 1)
+ {
+ pAd->ate.TxWI.ShortGI = 0;
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("Set_ATE_TX_GI_Proc::Out of range\n"));
+ return FALSE;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_TX_GI_Proc (GI = %d)\n", pAd->ate.TxWI.ShortGI));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_TX_GI_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+INT Set_ATE_RX_FER_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ pAd->ate.bRxFer = simple_strtol(arg, 0, 10);
+
+ if (pAd->ate.bRxFer == 1)
+ {
+ pAd->ate.RxCntPerSec = 0;
+ pAd->ate.RxTotalCnt = 0;
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Set_ATE_RX_FER_Proc (bRxFer = %d)\n", pAd->ate.bRxFer));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("Ralink: Set_ATE_RX_FER_Proc Success\n"));
+
+
+ return TRUE;
+}
+
+INT Set_ATE_Read_RF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support RT30xx ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ /* modify by WY for Read RF Reg. error */
+ UCHAR RFValue;
+ INT index=0;
+ for (index = 0; index < 32; index++)
+ {
+ RT30xxReadRFRegister(pAd, index, (PUCHAR)&RFValue);
+ printk("R%d=%d\n",index,RFValue);
+ }
+ }
+ else
+//2008/07/10:KH add to support RT30xx ATE-->
+#endif // RT30xx //
+ {
+ ate_print(KERN_EMERG "R1 = %lx\n", pAd->LatchRfRegs.R1);
+ ate_print(KERN_EMERG "R2 = %lx\n", pAd->LatchRfRegs.R2);
+ ate_print(KERN_EMERG "R3 = %lx\n", pAd->LatchRfRegs.R3);
+ ate_print(KERN_EMERG "R4 = %lx\n", pAd->LatchRfRegs.R4);
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Write_RF1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R1 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+
+}
+
+INT Set_ATE_Write_RF2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R2 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Write_RF3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R3 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Write_RF4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+ if(IS_RT30xx(pAd))
+ {
+ printk("Warning!! RT30xx Don't Support\n");
+ return FALSE;
+
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+ {
+ UINT32 value = simple_strtol(arg, 0, 16);
+
+ pAd->LatchRfRegs.R4 = value;
+ RtmpRfIoWrite(pAd);
+ }
+ return TRUE;
+}
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+INT SET_ATE_3070RF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ CHAR *this_char;
+ CHAR *value;
+ UINT32 Reg,RFValue;
+ if(IS_RT30xx(pAd))
+ {
+ printk("SET_ATE_3070RF_Proc=%s\n",arg);
+ this_char =arg;
+ if ((value = strchr(this_char, ':')) != NULL)
+ *value++ = 0;
+ Reg= simple_strtol(this_char, 0, 16);
+ RFValue= simple_strtol(value, 0, 16);
+ printk("RF Reg[%d]=%d\n",Reg,RFValue);
+ RT30xxWriteRFRegister(pAd, Reg,RFValue);
+ }
+ else
+ printk("Warning!! Only 3070 Support\n");
+ return TRUE;
+}
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+/*
+ ==========================================================================
+ Description:
+ Load and Write EEPROM from a binary file prepared in advance.
+
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+#ifndef UCOS
+INT Set_ATE_Load_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ BOOLEAN ret = FALSE;
+ PUCHAR src = EEPROM_BIN_FILE_NAME;
+ struct file *srcf;
+ INT32 retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ USHORT WriteEEPROM[(EEPROM_SIZE/2)];
+ UINT32 FileLength = 0;
+ UINT32 value = simple_strtol(arg, 0, 10);
+
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("===> %s (value=%d)\n\n", __FUNCTION__, value));
+
+ if (value > 0)
+ {
+ /* zero the e2p buffer */
+ NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+ /* save uid and gid used for filesystem access.
+ ** set user and group to 0 (root)
+ */
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ /* as root */
+ current->fsuid = current->fsgid = 0;
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ do
+ {
+ /* open the bin file */
+ srcf = filp_open(src, O_RDONLY, 0);
+
+ if (IS_ERR(srcf))
+ {
+ ate_print("%s - Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(srcf), src);
+ break;
+ }
+
+ /* the object must have a read method */
+ if ((srcf->f_op == NULL) || (srcf->f_op->read == NULL))
+ {
+ ate_print("%s - %s does not have a read method\n", __FUNCTION__, src);
+ break;
+ }
+
+ /* read the firmware from the file *.bin */
+ FileLength = srcf->f_op->read(srcf,
+ (PUCHAR)WriteEEPROM,
+ EEPROM_SIZE,
+ &srcf->f_pos);
+
+ if (FileLength != EEPROM_SIZE)
+ {
+ ate_print("%s: error file length (=%d) in e2p.bin\n",
+ __FUNCTION__, FileLength);
+ break;
+ }
+ else
+ {
+ /* write the content of .bin file to EEPROM */
+ rt_ee_write_all(pAd, WriteEEPROM);
+ ret = TRUE;
+ }
+ break;
+ } while(TRUE);
+
+ /* close firmware file */
+ if (IS_ERR(srcf))
+ {
+ ;
+ }
+ else
+ {
+ retval = filp_close(srcf, NULL);
+ if (retval)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("--> Error %d closing %s\n", -retval, src));
+
+ }
+ }
+
+ /* restore */
+ set_fs(orgfs);
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+ }
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("<=== %s (ret=%d)\n", __FUNCTION__, ret));
+
+ return ret;
+
+}
+#else
+INT Set_ATE_Load_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ USHORT WriteEEPROM[(EEPROM_SIZE/2)];
+ struct iwreq *wrq = (struct iwreq *)arg;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("===> %s (wrq->u.data.length = %d)\n\n", __FUNCTION__, wrq->u.data.length));
+
+ if (wrq->u.data.length != EEPROM_SIZE)
+ {
+ ate_print("%s: error length (=%d) from host\n",
+ __FUNCTION__, wrq->u.data.length);
+ return FALSE;
+ }
+ else/* (wrq->u.data.length == EEPROM_SIZE) */
+ {
+ /* zero the e2p buffer */
+ NdisZeroMemory((PUCHAR)WriteEEPROM, EEPROM_SIZE);
+
+ /* fill the local buffer */
+ NdisMoveMemory((PUCHAR)WriteEEPROM, wrq->u.data.pointer, wrq->u.data.length);
+
+ do
+ {
+ /* write the content of .bin file to EEPROM */
+ rt_ee_write_all(pAd, WriteEEPROM);
+
+ } while(FALSE);
+ }
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<=== %s\n", __FUNCTION__));
+
+ return TRUE;
+
+}
+#endif // !UCOS //
+
+INT Set_ATE_Read_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ USHORT buffer[EEPROM_SIZE/2];
+ USHORT *p;
+ int i;
+
+ rt_ee_read_all(pAd, (USHORT *)buffer);
+ p = buffer;
+ for (i = 0; i < (EEPROM_SIZE/2); i++)
+ {
+ ate_print("%4.4x ", *p);
+ if (((i+1) % 16) == 0)
+ ate_print("\n");
+ p++;
+ }
+ return TRUE;
+}
+
+INT Set_ATE_Show_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ate_print("Mode=%d\n", pAd->ate.Mode);
+ ate_print("TxPower0=%d\n", pAd->ate.TxPower0);
+ ate_print("TxPower1=%d\n", pAd->ate.TxPower1);
+ ate_print("TxAntennaSel=%d\n", pAd->ate.TxAntennaSel);
+ ate_print("RxAntennaSel=%d\n", pAd->ate.RxAntennaSel);
+ ate_print("BBPCurrentBW=%d\n", pAd->ate.TxWI.BW);
+ ate_print("GI=%d\n", pAd->ate.TxWI.ShortGI);
+ ate_print("MCS=%d\n", pAd->ate.TxWI.MCS);
+ ate_print("TxMode=%d\n", pAd->ate.TxWI.PHYMODE);
+ ate_print("Addr1=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->ate.Addr1[0], pAd->ate.Addr1[1], pAd->ate.Addr1[2], pAd->ate.Addr1[3], pAd->ate.Addr1[4], pAd->ate.Addr1[5]);
+ ate_print("Addr2=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->ate.Addr2[0], pAd->ate.Addr2[1], pAd->ate.Addr2[2], pAd->ate.Addr2[3], pAd->ate.Addr2[4], pAd->ate.Addr2[5]);
+ ate_print("Addr3=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ pAd->ate.Addr3[0], pAd->ate.Addr3[1], pAd->ate.Addr3[2], pAd->ate.Addr3[3], pAd->ate.Addr3[4], pAd->ate.Addr3[5]);
+ ate_print("Channel=%d\n", pAd->ate.Channel);
+ ate_print("TxLength=%d\n", pAd->ate.TxLength);
+ ate_print("TxCount=%u\n", pAd->ate.TxCount);
+ ate_print("RFFreqOffset=%d\n", pAd->ate.RFFreqOffset);
+ ate_print(KERN_EMERG "Set_ATE_Show_Proc Success\n");
+ return TRUE;
+}
+
+INT Set_ATE_Help_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ate_print("ATE=ATESTART, ATESTOP, TXCONT, TXCARR, TXFRAME, RXFRAME\n");
+ ate_print("ATEDA\n");
+ ate_print("ATESA\n");
+ ate_print("ATEBSSID\n");
+ ate_print("ATECHANNEL, range:0~14(unless A band !)\n");
+ ate_print("ATETXPOW0, set power level of antenna 1.\n");
+ ate_print("ATETXPOW1, set power level of antenna 2.\n");
+ ate_print("ATETXANT, set TX antenna. 0:all, 1:antenna one, 2:antenna two.\n");
+ ate_print("ATERXANT, set RX antenna.0:all, 1:antenna one, 2:antenna two, 3:antenna three.\n");
+ ate_print("ATETXFREQOFFSET, set frequency offset, range 0~63\n");
+ ate_print("ATETXBW, set BandWidth, 0:20MHz, 1:40MHz.\n");
+ ate_print("ATETXLEN, set Frame length, range 24~%d\n", (MAX_FRAME_SIZE - 34/* == 2312 */));
+ ate_print("ATETXCNT, set how many frame going to transmit.\n");
+ ate_print("ATETXMCS, set MCS, reference to rate table.\n");
+ ate_print("ATETXMODE, set Mode 0:CCK, 1:OFDM, 2:HT-Mix, 3:GreenField, reference to rate table.\n");
+ ate_print("ATETXGI, set GI interval, 0:Long, 1:Short\n");
+ ate_print("ATERXFER, 0:disable Rx Frame error rate. 1:enable Rx Frame error rate.\n");
+ ate_print("ATERRF, show all RF registers.\n");
+ ate_print("ATEWRF1, set RF1 register.\n");
+ ate_print("ATEWRF2, set RF2 register.\n");
+ ate_print("ATEWRF3, set RF3 register.\n");
+ ate_print("ATEWRF4, set RF4 register.\n");
+ ate_print("ATELDE2P, load EEPROM from .bin file.\n");
+ ate_print("ATERE2P, display all EEPROM content.\n");
+ ate_print("ATESHOW, display all parameters of ATE.\n");
+ ate_print("ATEHELP, online help.\n");
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ AsicSwitchChannel() dedicated for ATE.
+
+ ==========================================================================
+*/
+VOID ATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd)
+{
+ UINT32 R2 = 0, R3 = DEFAULT_RF_TX_POWER, R4 = 0, Value = 0;
+ CHAR TxPwer = 0, TxPwer2 = 0;
+ UCHAR index, BbpValue = 0, R66 = 0x30;
+ RTMP_RF_REGS *RFRegTable;
+ UCHAR Channel;
+
+#ifdef RALINK_28xx_QA
+ if ((pAd->ate.bQATxStart == TRUE) || (pAd->ate.bQARxStart == TRUE))
+ {
+ if (pAd->ate.Channel != pAd->LatchRfRegs.Channel)
+ {
+ pAd->ate.Channel = pAd->LatchRfRegs.Channel;
+ }
+ return;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ Channel = pAd->ate.Channel;
+
+ // Select antenna
+ AsicAntennaSelect(pAd, Channel);
+
+ // fill Tx power value
+ TxPwer = pAd->ate.TxPower0;
+ TxPwer2 = pAd->ate.TxPower1;
+#ifdef RT30xx
+//2008/07/10:KH add to support 3070 ATE<--
+
+ // The RF programming sequence is difference between 3xxx and 2xxx
+ // The 3070 is 1T1R. Therefore, we don't need to set the number of Tx/Rx path and the only job is to set the parameters of channels.
+ if (IS_RT30xx(pAd) && ((pAd->RfIcType == RFIC_3020) ||
+(pAd->RfIcType == RFIC_3021) || (pAd->RfIcType == RFIC_3022) ||
+(pAd->RfIcType == RFIC_2020)))
+ {
+ /* modify by WY for Read RF Reg. error */
+ UCHAR RFValue;
+
+ for (index = 0; index < NUM_OF_3020_CHNL; index++)
+ {
+ if (Channel == FreqItems3020[index].Channel)
+ {
+ // Programming channel parameters
+ RT30xxWriteRFRegister(pAd, RF_R02, FreqItems3020[index].N);
+ RT30xxWriteRFRegister(pAd, RF_R03, FreqItems3020[index].K);
+
+ RT30xxReadRFRegister(pAd, RF_R06, (PUCHAR)&RFValue);
+ RFValue = (RFValue & 0xFC) | FreqItems3020[index].R;
+ RT30xxWriteRFRegister(pAd, RF_R06, (UCHAR)RFValue);
+
+ // Set Tx Power
+ RT30xxReadRFRegister(pAd, RF_R12, (PUCHAR)&RFValue);
+ RFValue = (RFValue & 0xE0) | TxPwer;
+ RT30xxWriteRFRegister(pAd, RF_R12, (UCHAR)RFValue);
+
+ // Set RF offset
+ RT30xxReadRFRegister(pAd, RF_R23, (PUCHAR)&RFValue);
+ //2008/08/06: KH modified "pAd->RFFreqOffset" to "pAd->ate.RFFreqOffset"
+ RFValue = (RFValue & 0x80) | pAd->ate.RFFreqOffset;
+ RT30xxWriteRFRegister(pAd, RF_R23, (UCHAR)RFValue);
+
+ // Set BW
+ if (pAd->ate.TxWI.BW == BW_40)
+ {
+ RFValue = pAd->Mlme.CaliBW40RfR24;
+ //DISABLE_11N_CHECK(pAd);
+ }
+ else
+ {
+ RFValue = pAd->Mlme.CaliBW20RfR24;
+ }
+ RT30xxWriteRFRegister(pAd, RF_R24, (UCHAR)RFValue);
+
+ // Enable RF tuning
+ RT30xxReadRFRegister(pAd, RF_R07, (PUCHAR)&RFValue);
+ RFValue = RFValue | 0x1;
+ RT30xxWriteRFRegister(pAd, RF_R07, (UCHAR)RFValue);
+
+ // latch channel for future usage.
+ pAd->LatchRfRegs.Channel = Channel;
+
+ break;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%d, Pwr1=%d, %dT), N=0x%02X, K=0x%02X, R=0x%02X\n",
+ Channel,
+ pAd->RfIcType,
+ TxPwer,
+ TxPwer2,
+ pAd->Antenna.field.TxPath,
+ FreqItems3020[index].N,
+ FreqItems3020[index].K,
+ FreqItems3020[index].R));
+ }
+ else
+//2008/07/10:KH add to support 3070 ATE-->
+#endif // RT30xx //
+{
+ RFRegTable = RF2850RegTable;
+
+ switch (pAd->RfIcType)
+ {
+ /* But only 2850 and 2750 support 5.5GHz band... */
+ case RFIC_2820:
+ case RFIC_2850:
+ case RFIC_2720:
+ case RFIC_2750:
+
+ for (index = 0; index < NUM_OF_2850_CHNL; index++)
+ {
+ if (Channel == RFRegTable[index].Channel)
+ {
+ R2 = RFRegTable[index].R2;
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ R2 |= 0x4000; // If TXpath is 1, bit 14 = 1;
+ }
+
+ if (pAd->Antenna.field.RxPath == 2)
+ {
+ switch (pAd->ate.RxAntennaSel)
+ {
+ case 1:
+ R2 |= 0x20040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x00;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ case 2:
+ R2 |= 0x10040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x01;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ default:
+ R2 |= 0x40;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ /* Only enable two Antenna to receive. */
+ BbpValue |= 0x08;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ }
+ }
+ else if (pAd->Antenna.field.RxPath == 1)
+ {
+ R2 |= 0x20040; // write 1 to off RxPath
+ }
+
+ if (pAd->Antenna.field.TxPath == 2)
+ {
+ if (pAd->ate.TxAntennaSel == 1)
+ {
+ R2 |= 0x4000; // If TX Antenna select is 1 , bit 14 = 1; Disable Ant 2
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+ BbpValue &= 0xE7; //11100111B
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+ }
+ else if (pAd->ate.TxAntennaSel == 2)
+ {
+ R2 |= 0x8000; // If TX Antenna select is 2 , bit 15 = 1; Disable Ant 1
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+ BbpValue &= 0xE7;
+ BbpValue |= 0x08;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+ }
+ else
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &BbpValue);
+ BbpValue &= 0xE7;
+ BbpValue |= 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, BbpValue);
+ }
+ }
+ if (pAd->Antenna.field.RxPath == 3)
+ {
+ switch (pAd->ate.RxAntennaSel)
+ {
+ case 1:
+ R2 |= 0x20040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x00;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ case 2:
+ R2 |= 0x10040;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x01;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ case 3:
+ R2 |= 0x30000;
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x02;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ default:
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &BbpValue);
+ BbpValue &= 0xE4;
+ BbpValue |= 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, BbpValue);
+ break;
+ }
+ }
+
+ if (Channel > 14)
+ {
+ // initialize R3, R4
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff);
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15);
+
+ // According the Rory's suggestion to solve the middle range issue.
+ // 5.5G band power range: 0xF9~0X0F, TX0 Reg3 bit9/TX1 Reg4 bit6="0" means the TX power reduce 7dB
+ // R3
+ if ((TxPwer >= -7) && (TxPwer < 0))
+ {
+ TxPwer = (7+TxPwer);
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer=%d \n", TxPwer));
+ }
+ else
+ {
+ TxPwer = (TxPwer > 0xF) ? (0xF) : (TxPwer);
+ R3 |= (TxPwer << 10) | (1 << 9);
+ }
+
+ // R4
+ if ((TxPwer2 >= -7) && (TxPwer2 < 0))
+ {
+ TxPwer2 = (7+TxPwer2);
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ATEAsicSwitchChannel: TxPwer2=%d \n", TxPwer2));
+ }
+ else
+ {
+ TxPwer2 = (TxPwer2 > 0xF) ? (0xF) : (TxPwer2);
+ R4 |= (TxPwer2 << 7) | (1 << 6);
+ }
+ }
+ else
+ {
+ R3 = (RFRegTable[index].R3 & 0xffffc1ff) | (TxPwer << 9); // set TX power0
+ R4 = (RFRegTable[index].R4 & (~0x001f87c0)) | (pAd->ate.RFFreqOffset << 15) | (TxPwer2 <<6);// Set freq offset & TxPwr1
+ }
+
+ // Based on BBP current mode before changing RF channel.
+ if (pAd->ate.TxWI.BW == BW_40)
+ {
+ R4 |=0x200000;
+ }
+
+ // Update variables
+ pAd->LatchRfRegs.Channel = Channel;
+ pAd->LatchRfRegs.R1 = RFRegTable[index].R1;
+ pAd->LatchRfRegs.R2 = R2;
+ pAd->LatchRfRegs.R3 = R3;
+ pAd->LatchRfRegs.R4 = R4;
+
+ RtmpRfIoWrite(pAd);
+
+ break;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+ // Change BBP setting during switch from a->g, g->a
+ if (Channel <= 14)
+ {
+ ULONG TxPinCfg = 0x00050F0A;// 2007.10.09 by Brian : 0x0005050A ==> 0x00050F0A
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+
+ /* For 1T/2R chip only... */
+ if (pAd->NicConfig2.field.ExternalLNAForG)
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x62);
+ }
+ else
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0x84);
+ }
+
+ // According the Rory's suggestion to solve the middle range issue.
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+ ASSERT((BbpValue == 0x00));
+ if ((BbpValue != 0x00))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+ }
+
+ // 5.5GHz band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x04);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R.
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+ else
+ {
+ ULONG TxPinCfg = 0x00050F05;//2007.10.09 by Brian : 0x00050505 ==> 0x00050F05
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R62, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R63, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R64, (0x37 - GET_LNA_GAIN(pAd)));
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R82, 0xF2);
+
+ // According the Rory's suggestion to solve the middle range issue.
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R86, &BbpValue);
+ ASSERT((BbpValue == 0x00));
+ if ((BbpValue != 0x00))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R86, 0x00);
+ }
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R91, &BbpValue);
+ ASSERT((BbpValue == 0x04));
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R92, &BbpValue);
+ ASSERT((BbpValue == 0x00));
+
+ // 5.5GHz band selection PIN, bit1 and bit2 are complement
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Value);
+ Value &= (~0x6);
+ Value |= (0x02);
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Value);
+
+ // Turn off unused PA or LNA when only 1T or 1R.
+ if (pAd->Antenna.field.TxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFFFF3;
+ }
+ if (pAd->Antenna.field.RxPath == 1)
+ {
+ TxPinCfg &= 0xFFFFF3FF;
+ }
+
+ RTMP_IO_WRITE32(pAd, TX_PIN_CFG, TxPinCfg);
+ }
+
+ // R66 should be set according to Channel and use 20MHz when scanning
+ if (Channel <= 14)
+ {
+ // BG band
+ R66 = 0x2E + GET_LNA_GAIN(pAd);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+ {
+ // 5.5 GHz band
+ if (pAd->ate.TxWI.BW == BW_20)
+ {
+ R66 = (UCHAR)(0x32 + (GET_LNA_GAIN(pAd)*5)/3);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ else
+ {
+ R66 = (UCHAR)(0x3A + (GET_LNA_GAIN(pAd)*5)/3);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, R66);
+ }
+ }
+
+ //
+ // On 11A, We should delay and wait RF/BBP to be stable
+ // and the appropriate time should be 1000 micro seconds
+ // 2005/06/05 - On 11G, We also need this delay time. Otherwise it's difficult to pass the WHQL.
+ //
+ RTMPusecDelay(1000);
+
+ if (Channel > 14)
+ {
+ // When 5.5GHz band the LSB of TxPwr will be used to reduced 7dB or not.
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+ Channel,
+ pAd->RfIcType,
+ pAd->Antenna.field.TxPath,
+ pAd->LatchRfRegs.R1,
+ pAd->LatchRfRegs.R2,
+ pAd->LatchRfRegs.R3,
+ pAd->LatchRfRegs.R4));
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("SwitchChannel#%d(RF=%d, Pwr0=%u, Pwr1=%u, %dT) to , R1=0x%08lx, R2=0x%08lx, R3=0x%08lx, R4=0x%08lx\n",
+ Channel,
+ pAd->RfIcType,
+ (R3 & 0x00003e00) >> 9,
+ (R4 & 0x000007c0) >> 6,
+ pAd->Antenna.field.TxPath,
+ pAd->LatchRfRegs.R1,
+ pAd->LatchRfRegs.R2,
+ pAd->LatchRfRegs.R3,
+ pAd->LatchRfRegs.R4));
+ }
+}
+
+//
+// In fact, no one will call this routine so far !
+//
+/*
+ ==========================================================================
+ Description:
+ Gives CCK TX rate 2 more dB TX power.
+ This routine works only in ATE mode.
+
+ calculate desired Tx power in RF R3.Tx0~5, should consider -
+ 0. if current radio is a noisy environment (pAd->DrsCounters.fNoisyEnvironment)
+ 1. TxPowerPercentage
+ 2. auto calibration based on TSSI feedback
+ 3. extra 2 db for CCK
+ 4. -10 db upon very-short distance (AvgRSSI >= -40db) to AP
+
+ NOTE: Since this routine requires the value of (pAd->DrsCounters.fNoisyEnvironment),
+ it should be called AFTER MlmeDynamicTxRateSwitching()
+ ==========================================================================
+ */
+VOID ATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd)
+{
+ INT i, j;
+ CHAR DeltaPwr = 0;
+ BOOLEAN bAutoTxAgc = FALSE;
+ UCHAR TssiRef, *pTssiMinusBoundary, *pTssiPlusBoundary, TxAgcStep;
+ UCHAR BbpR49 = 0, idx;
+ PCHAR pTxAgcCompensate;
+ ULONG TxPwr[5];
+ CHAR Value;
+
+ /* no one calls this procedure so far */
+ if (pAd->ate.TxWI.BW == BW_40)
+ {
+ if (pAd->ate.Channel > 14)
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx40MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx40MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx40MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx40MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx40MPwrCfgGBand[4];
+ }
+ }
+ else
+ {
+ if (pAd->ate.Channel > 14)
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgABand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgABand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgABand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgABand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgABand[4];
+ }
+ else
+ {
+ TxPwr[0] = pAd->Tx20MPwrCfgGBand[0];
+ TxPwr[1] = pAd->Tx20MPwrCfgGBand[1];
+ TxPwr[2] = pAd->Tx20MPwrCfgGBand[2];
+ TxPwr[3] = pAd->Tx20MPwrCfgGBand[3];
+ TxPwr[4] = pAd->Tx20MPwrCfgGBand[4];
+ }
+ }
+
+ // TX power compensation for temperature variation based on TSSI.
+ // Do it per 4 seconds.
+ if (pAd->Mlme.OneSecPeriodicRound % 4 == 0)
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ /* bg channel */
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ TssiRef = pAd->TssiRefG;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryG[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryG[0];
+ TxAgcStep = pAd->TxAgcStepG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ /* a channel */
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ TssiRef = pAd->TssiRefA;
+ pTssiMinusBoundary = &pAd->TssiMinusBoundaryA[0];
+ pTssiPlusBoundary = &pAd->TssiPlusBoundaryA[0];
+ TxAgcStep = pAd->TxAgcStepA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ {
+ /* BbpR49 is unsigned char */
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R49, &BbpR49);
+
+ /* (p) TssiPlusBoundaryG[0] = 0 = (m) TssiMinusBoundaryG[0] */
+ /* compensate: +4 +3 +2 +1 0 -1 -2 -3 -4 * steps */
+ /* step value is defined in pAd->TxAgcStepG for tx power value */
+
+ /* [4]+1+[4] p4 p3 p2 p1 o1 m1 m2 m3 m4 */
+ /* ex: 0x00 0x15 0x25 0x45 0x88 0xA0 0xB5 0xD0 0xF0
+ above value are examined in mass factory production */
+ /* [4] [3] [2] [1] [0] [1] [2] [3] [4] */
+
+ /* plus is 0x10 ~ 0x40, minus is 0x60 ~ 0x90 */
+ /* if value is between p1 ~ o1 or o1 ~ s1, no need to adjust tx power */
+ /* if value is 0x65, tx power will be -= TxAgcStep*(2-1) */
+
+ if (BbpR49 > pTssiMinusBoundary[1])
+ {
+ // Reading is larger than the reference value.
+ // Check for how large we need to decrease the Tx power.
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 <= pTssiMinusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should decrease, idx = 0 means there is nothing to compensate
+// if (R3 > (ULONG) (TxAgcStep * (idx-1)))
+ *pTxAgcCompensate = -(TxAgcStep * (idx-1));
+// else
+// *pTxAgcCompensate = -((UCHAR)R3);
+
+ DeltaPwr += (*pTxAgcCompensate);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("-- Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = -%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else if (BbpR49 < pTssiPlusBoundary[1])
+ {
+ // Reading is smaller than the reference value
+ // check for how large we need to increase the Tx power
+ for (idx = 1; idx < 5; idx++)
+ {
+ if (BbpR49 >= pTssiPlusBoundary[idx]) // Found the range
+ break;
+ }
+ // The index is the step we should increase, idx = 0 means there is nothing to compensate
+ *pTxAgcCompensate = TxAgcStep * (idx-1);
+ DeltaPwr += (*pTxAgcCompensate);
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("++ Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, idx-1));
+ }
+ else
+ {
+ *pTxAgcCompensate = 0;
+ ATEDBGPRINT(RT_DEBUG_TRACE, (" Tx Power, BBP R1=%x, TssiRef=%x, TxAgcStep=%x, step = +%d\n",
+ BbpR49, TssiRef, TxAgcStep, 0));
+ }
+ }
+ }
+ else
+ {
+ if (pAd->ate.Channel <= 14)
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcG;
+ pTxAgcCompensate = &pAd->TxAgcCompensateG;
+ }
+ else
+ {
+ bAutoTxAgc = pAd->bAutoTxAgcA;
+ pTxAgcCompensate = &pAd->TxAgcCompensateA;
+ }
+
+ if (bAutoTxAgc)
+ DeltaPwr += (*pTxAgcCompensate);
+ }
+
+ /* calculate delta power based on the percentage specified from UI */
+ // E2PROM setting is calibrated for maximum TX power (i.e. 100%)
+ // We lower TX power here according to the percentage specified from UI
+ if (pAd->CommonCfg.TxPowerPercentage == 0xffffffff) // AUTO TX POWER control
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 90) // 91 ~ 100% & AUTO, treat as 100% in terms of mW
+ ;
+ else if (pAd->CommonCfg.TxPowerPercentage > 60) // 61 ~ 90%, treat as 75% in terms of mW
+ {
+ DeltaPwr -= 1;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 30) // 31 ~ 60%, treat as 50% in terms of mW
+ {
+ DeltaPwr -= 3;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 15) // 16 ~ 30%, treat as 25% in terms of mW
+ {
+ DeltaPwr -= 6;
+ }
+ else if (pAd->CommonCfg.TxPowerPercentage > 9) // 10 ~ 15%, treat as 12.5% in terms of mW
+ {
+ DeltaPwr -= 9;
+ }
+ else // 0 ~ 9 %, treat as MIN(~3%) in terms of mW
+ {
+ DeltaPwr -= 12;
+ }
+
+ /* reset different new tx power for different TX rate */
+ for(i=0; i<5; i++)
+ {
+ if (TxPwr[i] != 0xffffffff)
+ {
+ for (j=0; j<8; j++)
+ {
+ Value = (CHAR)((TxPwr[i] >> j*4) & 0x0F); /* 0 ~ 15 */
+
+ if ((Value + DeltaPwr) < 0)
+ {
+ Value = 0; /* min */
+ }
+ else if ((Value + DeltaPwr) > 0xF)
+ {
+ Value = 0xF; /* max */
+ }
+ else
+ {
+ Value += DeltaPwr; /* temperature compensation */
+ }
+
+ /* fill new value to CSR offset */
+ TxPwr[i] = (TxPwr[i] & ~(0x0000000F << j*4)) | (Value << j*4);
+ }
+
+ /* write tx power value to CSR */
+ /* TX_PWR_CFG_0 (8 tx rate) for TX power for OFDM 12M/18M
+ TX power for OFDM 6M/9M
+ TX power for CCK5.5M/11M
+ TX power for CCK1M/2M */
+ /* TX_PWR_CFG_1 ~ TX_PWR_CFG_4 */
+ RTMP_IO_WRITE32(pAd, TX_PWR_CFG_0 + i*4, TxPwr[i]);
+
+
+ }
+ }
+
+}
+
+/*
+ ========================================================================
+ Routine Description:
+ Write TxWI for ATE mode.
+
+ Return Value:
+ None
+ ========================================================================
+*/
+
+#ifdef RT2870
+static VOID ATEWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR MIMOps,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING Transmit)
+{
+ //
+ // Always use Long preamble before verifiation short preamble functionality works well.
+ // Todo: remove the following line if short preamble functionality works
+ //
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED);
+ pTxWI->FRAG= FRAG;
+ pTxWI->TS= InsTimestamp;
+ pTxWI->AMPDU = AMPDU;
+
+ pTxWI->MIMOps = PWR_ACTIVE;
+ pTxWI->MpduDensity = 4;
+ pTxWI->ACK = Ack;
+ pTxWI->txop = Txopmode;
+ pTxWI->NSEQ = NSeq;
+ pTxWI->BAWinSize = BASize;
+
+ pTxWI->WirelessCliID = WCID;
+ pTxWI->MPDUtotalByteCount = Length;
+ pTxWI->PacketId = PID;
+
+ pTxWI->BW = Transmit.field.BW;
+ pTxWI->ShortGI = Transmit.field.ShortGI;
+ pTxWI->STBC= Transmit.field.STBC;
+
+ pTxWI->MCS = Transmit.field.MCS;
+ pTxWI->PHYMODE= Transmit.field.MODE;
+
+#ifdef DOT11_N_SUPPORT
+ //
+ // MMPS is 802.11n features. Because TxWI->MCS > 7 must be HT mode,
+ // so need not check if it's HT rate.
+ //
+ if ((MIMOps == MMPS_STATIC) && (pTxWI->MCS > 7))
+ pTxWI->MCS = 7;
+
+ if ((MIMOps == MMPS_DYNAMIC) && (pTxWI->MCS > 7)) // SMPS protect 2 spatial.
+ pTxWI->MIMOps = 1;
+#endif // DOT11_N_SUPPORT //
+
+ pTxWI->CFACK = CfAck;
+
+ return;
+}
+#endif // RT2870 //
+/*
+ ========================================================================
+
+ Routine Description:
+ Disable protection for ATE.
+ ========================================================================
+*/
+VOID ATEDisableAsicProtect(
+ IN PRTMP_ADAPTER pAd)
+{
+ PROT_CFG_STRUC ProtCfg, ProtCfg4;
+ UINT32 Protect[6];
+ USHORT offset;
+ UCHAR i;
+ UINT32 MacReg = 0;
+
+ // Config ASIC RTS threshold register
+ RTMP_IO_READ32(pAd, TX_RTS_CFG, &MacReg);
+ MacReg &= 0xFF0000FF;
+ MacReg |= (pAd->CommonCfg.RtsThreshold << 8);
+ RTMP_IO_WRITE32(pAd, TX_RTS_CFG, MacReg);
+
+ // Initial common protection settings
+ RTMPZeroMemory(Protect, sizeof(Protect));
+ ProtCfg4.word = 0;
+ ProtCfg.word = 0;
+ ProtCfg.field.TxopAllowGF40 = 1;
+ ProtCfg.field.TxopAllowGF20 = 1;
+ ProtCfg.field.TxopAllowMM40 = 1;
+ ProtCfg.field.TxopAllowMM20 = 1;
+ ProtCfg.field.TxopAllowOfdm = 1;
+ ProtCfg.field.TxopAllowCck = 1;
+ ProtCfg.field.RTSThEn = 1;
+ ProtCfg.field.ProtectNav = ASIC_SHORTNAV;
+
+ // Handle legacy(B/G) protection
+ ProtCfg.field.ProtectRate = pAd->CommonCfg.RtsRate;
+ ProtCfg.field.ProtectCtrl = 0;
+ Protect[0] = ProtCfg.word;
+ Protect[1] = ProtCfg.word;
+
+ // NO PROTECT
+ // 1.All STAs in the BSS are 20/40 MHz HT
+ // 2. in ai 20/40MHz BSS
+ // 3. all STAs are 20MHz in a 20MHz BSS
+ // Pure HT. no protection.
+
+ // MM20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[2] = 0x01744004;
+
+ // MM40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[3] = 0x03f44084;
+
+ // CF20_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 010111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4004 (OFDM 24M)
+ Protect[4] = 0x01744004;
+
+ // CF40_PROT_CFG
+ // Reserved (31:27)
+ // PROT_TXOP(25:20) -- 111111
+ // PROT_NAV(19:18) -- 01 (Short NAV protection)
+ // PROT_CTRL(17:16) -- 00 (None)
+ // PROT_RATE(15:0) -- 0x4084 (duplicate OFDM 24M)
+ Protect[5] = 0x03f44084;
+
+ pAd->CommonCfg.IOTestParm.bRTSLongProtOn = FALSE;
+
+ offset = CCK_PROT_CFG;
+ for (i = 0;i < 6;i++)
+ RTMP_IO_WRITE32(pAd, offset + i*4, Protect[i]);
+
+}
+
+#ifdef RT2870
+/*
+ ========================================================================
+ Routine Description:
+ Write TxInfo for ATE mode.
+
+ Return Value:
+ None
+ ========================================================================
+*/
+static VOID ATEWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst)
+{
+ pTxInfo->USBDMATxPktLen = USBDMApktLen;
+ pTxInfo->QSEL = QueueSel;
+
+ if (QueueSel != FIFO_EDCA)
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("=======> QueueSel != FIFO_EDCA<=======\n"));
+
+ pTxInfo->USBDMANextVLD = NextValid;
+ pTxInfo->USBDMATxburst = TxBurst;
+ pTxInfo->WIV = bWiv;
+ pTxInfo->SwUseLastRound = 0;
+ pTxInfo->rsv = 0;
+ pTxInfo->rsv2 = 0;
+
+ return;
+}
+#endif // RT2870 //
+
+/* There are two ways to convert Rssi */
+#if 1
+//
+// The way used with GET_LNA_GAIN().
+//
+CHAR ATEConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber)
+{
+ UCHAR RssiOffset, LNAGain;
+
+ // Rssi equals to zero should be an invalid value
+ if (Rssi == 0)
+ return -99;
+
+ LNAGain = GET_LNA_GAIN(pAd);
+ if (pAd->LatchRfRegs.Channel > 14)
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->ARssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->ARssiOffset1;
+ else
+ RssiOffset = pAd->ARssiOffset2;
+ }
+ else
+ {
+ if (RssiNumber == 0)
+ RssiOffset = pAd->BGRssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->BGRssiOffset1;
+ else
+ RssiOffset = pAd->BGRssiOffset2;
+ }
+
+ return (-12 - RssiOffset - LNAGain - Rssi);
+}
+#else
+//
+// The way originally used in ATE of rt2860ap.
+//
+CHAR ATEConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber)
+{
+ UCHAR RssiOffset, LNAGain;
+
+ // Rssi equals to zero should be an invalid value
+ if (Rssi == 0)
+ return -99;
+
+ if (pAd->LatchRfRegs.Channel > 14)
+ {
+ LNAGain = pAd->ALNAGain;
+ if (RssiNumber == 0)
+ RssiOffset = pAd->ARssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->ARssiOffset1;
+ else
+ RssiOffset = pAd->ARssiOffset2;
+ }
+ else
+ {
+ LNAGain = pAd->BLNAGain;
+ if (RssiNumber == 0)
+ RssiOffset = pAd->BGRssiOffset0;
+ else if (RssiNumber == 1)
+ RssiOffset = pAd->BGRssiOffset1;
+ else
+ RssiOffset = pAd->BGRssiOffset2;
+ }
+
+ return (-32 - RssiOffset + LNAGain - Rssi);
+}
+#endif /* end of #if 1 */
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Set Japan filter coefficients if needed.
+ Note:
+ This routine should only be called when
+ entering TXFRAME mode or TXCONT mode.
+
+ ========================================================================
+*/
+static VOID SetJapanFilter(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR BbpData = 0;
+
+ //
+ // If Channel=14 and Bandwidth=20M and Mode=CCK, set BBP R4 bit5=1
+ // (Japan Tx filter coefficients)when (TXFRAME or TXCONT).
+ //
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BbpData);
+
+ if ((pAd->ate.TxWI.PHYMODE == MODE_CCK) && (pAd->ate.Channel == 14) && (pAd->ate.TxWI.BW == BW_20))
+ {
+ BbpData |= 0x20; // turn on
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("SetJapanFilter!!!\n"));
+ }
+ else
+ {
+ BbpData &= 0xdf; // turn off
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("ClearJapanFilter!!!\n"));
+ }
+
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BbpData);
+}
+
+VOID ATESampleRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI)
+{
+ /* There are two ways to collect RSSI. */
+#if 1
+ //pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+ if (pRxWI->RSSI0 != 0)
+ {
+ pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+ pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+ pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
+ }
+ if (pRxWI->RSSI1 != 0)
+ {
+ pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+ pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+ pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
+ }
+ if (pRxWI->RSSI2 != 0)
+ {
+ pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+ pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+ pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
+ }
+
+ pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);// CHAR ==> UCHAR ?
+ pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);// CHAR ==> UCHAR ?
+
+ pAd->ate.NumOfAvgRssiSample ++;
+#else
+ pAd->ate.LastSNR0 = (CHAR)(pRxWI->SNR0);
+ pAd->ate.LastSNR1 = (CHAR)(pRxWI->SNR1);
+ pAd->ate.RxCntPerSec++;
+ pAd->ate.LastRssi0 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI0, RSSI_0);
+ pAd->ate.LastRssi1 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI1, RSSI_1);
+ pAd->ate.LastRssi2 = ATEConvertToRssi(pAd, (CHAR) pRxWI->RSSI2, RSSI_2);
+ pAd->ate.AvgRssi0X8 = (pAd->ate.AvgRssi0X8 - pAd->ate.AvgRssi0) + pAd->ate.LastRssi0;
+ pAd->ate.AvgRssi0 = pAd->ate.AvgRssi0X8 >> 3;
+ pAd->ate.AvgRssi1X8 = (pAd->ate.AvgRssi1X8 - pAd->ate.AvgRssi1) + pAd->ate.LastRssi1;
+ pAd->ate.AvgRssi1 = pAd->ate.AvgRssi1X8 >> 3;
+ pAd->ate.AvgRssi2X8 = (pAd->ate.AvgRssi2X8 - pAd->ate.AvgRssi2) + pAd->ate.LastRssi2;
+ pAd->ate.AvgRssi2 = pAd->ate.AvgRssi2X8 >> 3;
+ pAd->ate.NumOfAvgRssiSample ++;
+#endif
+}
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPStationStop(
+ IN PRTMP_ADAPTER pAd)
+{
+// BOOLEAN Cancelled;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStop\n"));
+
+ // For rx statistics, we need to keep this timer running.
+// RTMPCancelTimer(&pAd->Mlme.PeriodicTimer, &Cancelled);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStop\n"));
+}
+
+VOID RTMPStationStart(
+ IN PRTMP_ADAPTER pAd)
+{
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("==> RTMPStationStart\n"));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<== RTMPStationStart\n"));
+}
+#endif // CONFIG_STA_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+ Setup Frame format.
+ NOTE:
+ This routine should only be used in ATE mode.
+ ==========================================================================
+ */
+
+#ifdef RT2870
+/*======================Start of RT2870======================*/
+/* */
+/* */
+static INT ATESetUpFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TxIdx)
+{
+ UINT j;
+ PTX_CONTEXT pNullContext;
+ PUCHAR pDest;
+ HTTRANSMIT_SETTING TxHTPhyMode;
+ PTXWI_STRUC pTxWI;
+ PTXINFO_STRUC pTxInfo;
+ UINT32 TransferBufferLength, OrgBufferLength = 0;
+ UCHAR padLen = 0;
+#ifdef RALINK_28xx_QA
+ PHEADER_802_11 pHeader80211 = NULL;
+#endif // RALINK_28xx_QA //
+
+ if ((RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) ||
+ (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ return -1;
+ }
+
+ /* We always use QID_AC_BE and FIFO_EDCA in ATE mode. */
+
+ pNullContext = &(pAd->NullContext);
+ ASSERT(pNullContext != NULL);
+
+ if (pNullContext->InUse == FALSE)
+ {
+ // Set the in use bit
+ pNullContext->InUse = TRUE;
+ NdisZeroMemory(&(pAd->NullFrame), sizeof(HEADER_802_11));
+
+ // Fill 802.11 header.
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ pHeader80211 = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+// pDest = NdisMoveMemory(&(pAd->NullFrame), pAd->ate.Header, pAd->ate.HLen);
+// pHeader80211 = (PHEADER_802_11)pDest;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ // Fill 802.11 header.
+ NdisMoveMemory(&(pAd->NullFrame), TemplateFrame, sizeof(HEADER_802_11));
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)&(pAd->NullFrame), DIR_READ, FALSE);
+#endif // RT_BIG_ENDIAN //
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ /* modify sequence number.... */
+ if (pAd->ate.TxDoneCount == 0)
+ {
+ pAd->ate.seq = pHeader80211->Sequence;
+ }
+ else
+ {
+ pHeader80211->Sequence = ++pAd->ate.seq;
+ }
+ /* We already got all the addr. fields from QA GUI. */
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->ate.Addr1);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->ate.Addr2);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->ate.Addr3);
+ }
+
+ RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], TX_BUFFER_NORMSIZE);//???
+ pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
+
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ // Avoid to exceed the range of WirelessPacket[].
+ ASSERT(pAd->ate.TxInfo.USBDMATxPktLen <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+ NdisMoveMemory(pTxInfo, &(pAd->ate.TxInfo), sizeof(pAd->ate.TxInfo));
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ // Avoid to exceed the range of WirelessPacket[].
+ ASSERT(pAd->ate.TxLength <= (MAX_FRAME_SIZE - 34/* == 2312 */));
+
+ // pTxInfo->USBDMATxPktLen will be updated to include padding later.
+ ATEWriteTxInfo(pAd, pTxInfo, (USHORT)(TXWI_SIZE + pAd->ate.TxLength), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxInfo->QSEL = FIFO_EDCA;
+ }
+
+ pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+
+ // Fill TxWI.
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+ TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+ TxHTPhyMode.field.STBC = pAd->ate.TxWI.STBC;
+ TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+ TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+ ATEWriteTxWI(pAd, pTxWI, pAd->ate.TxWI.FRAG, pAd->ate.TxWI.TS, pAd->ate.TxWI.AMPDU, pAd->ate.TxWI.ACK, pAd->ate.TxWI.NSEQ,
+ pAd->ate.TxWI.BAWinSize, BSSID_WCID, pAd->ate.TxWI.MPDUtotalByteCount/* include 802.11 header */, pAd->ate.TxWI.PacketId, 0, pAd->ate.TxWI.txop/*IFS_HTTXOP*/, pAd->ate.TxWI.CFACK/*FALSE*/, TxHTPhyMode);
+ }
+ else
+ {
+ TxHTPhyMode.field.BW = pAd->ate.TxWI.BW;
+ TxHTPhyMode.field.ShortGI = pAd->ate.TxWI.ShortGI;
+ TxHTPhyMode.field.STBC = 0;
+ TxHTPhyMode.field.MCS = pAd->ate.TxWI.MCS;
+ TxHTPhyMode.field.MODE = pAd->ate.TxWI.PHYMODE;
+
+ ATEWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE/* No ack required. */, FALSE, 0, BSSID_WCID, pAd->ate.TxLength,
+ 0, 0, IFS_HTTXOP, FALSE, TxHTPhyMode);// "MMPS_STATIC" instead of "MMPS_DYNAMIC" ???
+ }
+
+ RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+
+ pDest = &(pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE+TXWI_SIZE+sizeof(HEADER_802_11)]);
+
+ // Prepare frame payload
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQATxStart == TRUE)
+ {
+ // copy pattern
+ if ((pAd->ate.PLen != 0))
+ {
+ for (j = 0; j < pAd->ate.DLen; j+=pAd->ate.PLen)
+ {
+ RTMPMoveMemory(pDest, pAd->ate.Pattern, pAd->ate.PLen);
+ pDest += pAd->ate.PLen;
+ }
+ }
+ TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxWI.MPDUtotalByteCount;
+ }
+ else
+#endif // RALINK_28xx_QA //
+ {
+ for (j = 0; j < (pAd->ate.TxLength - sizeof(HEADER_802_11)); j++)
+ {
+ *pDest = 0xA5;
+ pDest += 1;
+ }
+ TransferBufferLength = TXINFO_SIZE + TXWI_SIZE + pAd->ate.TxLength;
+ }
+
+#if 1
+ OrgBufferLength = TransferBufferLength;
+ TransferBufferLength = (TransferBufferLength + 3) & (~3);
+
+ // Always add 4 extra bytes at every packet.
+ padLen = TransferBufferLength - OrgBufferLength + 4;/* 4 == last packet padding */
+ ASSERT((padLen <= (RTMP_PKT_TAIL_PADDING - 4/* 4 == MaxBulkOutsize alignment padding */)));
+
+ /* Now memzero all extra padding bytes. */
+ NdisZeroMemory(pDest, padLen);
+ pDest += padLen;
+#else
+ if ((TransferBufferLength % 4) == 1)
+ {
+ NdisZeroMemory(pDest, 7);
+ pDest += 7;
+ TransferBufferLength += 3;
+ }
+ else if ((TransferBufferLength % 4) == 2)
+ {
+ NdisZeroMemory(pDest, 6);
+ pDest += 6;
+ TransferBufferLength += 2;
+ }
+ else if ((TransferBufferLength % 4) == 3)
+ {
+ NdisZeroMemory(pDest, 5);
+ pDest += 5;
+ TransferBufferLength += 1;
+ }
+#endif // 1 //
+
+ // Update pTxInfo->USBDMATxPktLen to include padding.
+ pTxInfo->USBDMATxPktLen = TransferBufferLength - TXINFO_SIZE;
+
+ TransferBufferLength += 4;
+
+ // If TransferBufferLength is multiple of 64, add extra 4 bytes again.
+ if ((TransferBufferLength % pAd->BulkOutMaxPacketSize) == 0)
+ {
+ NdisZeroMemory(pDest, 4);
+ TransferBufferLength += 4;
+ }
+
+ // Fill out frame length information for global Bulk out arbitor
+ pAd->NullContext.BulkOutSize = TransferBufferLength;
+ }
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+ RTMPFrameEndianChange(pAd, (((PUCHAR)pTxInfo)+TXWI_SIZE+TXINFO_SIZE), DIR_WRITE, FALSE);
+ RTMPDescriptorEndianChange((PUCHAR)pTxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+ return 0;
+}
+
+VOID ATE_RTUSBBulkOutDataPacketComplete(purbb_t pUrb, struct pt_regs *pt_regs)
+{
+ PRTMP_ADAPTER pAd;
+ PTX_CONTEXT pNullContext;
+ UCHAR BulkOutPipeId;
+ NTSTATUS Status;
+ unsigned long IrqFlags;
+ ULONG OldValue;
+
+ pNullContext = (PTX_CONTEXT)pUrb->context;
+ pAd = pNullContext->pAd;
+
+
+ // Reset Null frame context flags
+ pNullContext->IRPPending = FALSE;
+ pNullContext->InUse = FALSE;
+ Status = pUrb->status;
+
+ // Store BulkOut PipeId
+ BulkOutPipeId = pNullContext->BulkOutPipeId;
+ pAd->BulkOutDataOneSecCount++;
+
+ if (Status == USB_ST_NOERROR)
+ {
+#ifdef RALINK_28xx_QA
+ if ((ATE_ON(pAd)) && (pAd->ate.bQATxStart == TRUE))
+ {
+ if (pAd->ate.QID == BulkOutPipeId)
+ {
+ // Let Rx can have a chance to break in during Tx process,
+ // especially for loopback mode in QA ATE.
+ // To trade off between tx performance and loopback mode integrity.
+ /* Q : Now Rx is handled by tasklet, do we still need this delay ? */
+ /* Ans : Even tasklet is used, Rx/Tx < 1 if we do not delay for a while right here. */
+ RTMPusecDelay(500);
+ pAd->ate.TxDoneCount++;
+ pAd->RalinkCounters.KickTxCount++;
+ ASSERT(pAd->ate.QID == 0);
+ pAd->ate.TxAc0++;
+ }
+ }
+#endif // RALINK_28xx_QA //
+ pAd->BulkOutComplete++;
+
+ pAd->Counters8023.GoodTransmits++;
+
+ /* Don't worry about the queue is empty or not. This function will check itself. */
+ RTMPDeQueuePacket(pAd, TRUE, BulkOutPipeId, MAX_TX_PROCESS);
+
+ /* In 28xx, SendTxWaitQueue ==> TxSwQueue */
+/*
+ if (pAd->SendTxWaitQueue[BulkOutPipeId].Number > 0)
+ {
+ RTMPDeQueuePacket(pAd, BulkOutPipeId);
+ }
+*/
+ }
+ else // STATUS_OTHER
+ {
+ pAd->BulkOutCompleteOther++;
+
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("BulkOutDataPacket Failed STATUS_OTHER = 0x%x . \n", Status));
+ ATEDBGPRINT(RT_DEBUG_ERROR, (">>BulkOutReq=0x%lx, BulkOutComplete=0x%lx\n", pAd->BulkOutReq, pAd->BulkOutComplete));
+
+ if ((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET)))
+ {
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKOUT_RESET);
+ /* In 28xx, RT_OID_USB_RESET_BULK_OUT ==> CMDTHREAD_RESET_BULK_OUT */
+ RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_OUT, NULL, 0);
+ // Check
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ pAd->bulkResetPipeid = BulkOutPipeId;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+ }
+
+
+
+ if (atomic_read(&pAd->BulkOutRemained) > 0)
+ {
+ atomic_dec(&pAd->BulkOutRemained);
+ }
+
+ // 1st - Transmit Success
+ OldValue = pAd->WlanCounters.TransmittedFragmentCount.u.LowPart;
+ pAd->WlanCounters.TransmittedFragmentCount.u.LowPart++;
+
+ if (pAd->WlanCounters.TransmittedFragmentCount.u.LowPart < OldValue)
+ {
+ pAd->WlanCounters.TransmittedFragmentCount.u.HighPart++;
+ }
+
+ if(((pAd->ContinBulkOut == TRUE ) ||(atomic_read(&pAd->BulkOutRemained) > 0)) && (pAd->ate.Mode & ATE_TXFRAME))
+ {
+ RTUSB_SET_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+ }
+ else
+ {
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+#ifdef RALINK_28xx_QA
+ pAd->ate.TxStatus = 0;
+#endif // RALINK_28xx_QA //
+ }
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ pAd->BulkOutPending[BulkOutPipeId] = FALSE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ // Always call Bulk routine, even reset bulk.
+ // The protection of rest bulk should be in BulkOut routine.
+ RTUSBKickBulkOut(pAd);
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID ATE_RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId)
+{
+ PTX_CONTEXT pNullContext = &(pAd->NullContext);
+ PURB pUrb;
+ int ret = 0;
+ unsigned long IrqFlags;
+
+
+ ASSERT(BulkOutPipeId == 0);
+
+ /* Build up the frame first. */
+// ATESetUpFrame(pAd, 0);
+
+ BULK_OUT_LOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ if (pAd->BulkOutPending[BulkOutPipeId] == TRUE)
+ {
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+ return;
+ }
+
+ pAd->BulkOutPending[BulkOutPipeId] = TRUE;
+ BULK_OUT_UNLOCK(&pAd->BulkOutLock[BulkOutPipeId], IrqFlags);
+
+ // Increase Total transmit byte counter
+ pAd->RalinkCounters.OneSecTransmittedByteCount += pNullContext->BulkOutSize;
+ pAd->RalinkCounters.TransmittedByteCount += pNullContext->BulkOutSize;
+
+ // Clear ATE frame bulk out flag
+ RTUSB_CLEAR_BULK_FLAG(pAd, fRTUSB_BULK_OUT_DATA_ATE);
+
+ // Init Tx context descriptor
+ pNullContext->IRPPending = TRUE;
+ RTUSBInitTxDesc(pAd, pNullContext, BulkOutPipeId, (usb_complete_t)ATE_RTUSBBulkOutDataPacketComplete);
+ pUrb = pNullContext->pUrb;
+
+ if((ret = RTUSB_SUBMIT_URB(pUrb))!=0)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("ATE_RTUSBBulkOutDataPacket: Submit Tx URB failed %d\n", ret));
+ return;
+ }
+
+ pAd->BulkOutReq++;
+ return;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID ATE_RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd)
+{
+ PRX_CONTEXT pRxContext;
+ UINT i;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("--->ATE_RTUSBCancelPendingBulkInIRP\n"));
+#if 1
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ pRxContext = &(pAd->RxContext[i]);
+ if(pRxContext->IRPPending == TRUE)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ pRxContext->IRPPending = FALSE;
+ pRxContext->InUse = FALSE;
+ //NdisInterlockedDecrement(&pAd->PendingRx);
+ //pAd->PendingRx--;
+ }
+ }
+#else
+ for ( i = 0; i < (RX_RING_SIZE); i++)
+ {
+ pRxContext = &(pAd->RxContext[i]);
+ if(atomic_read(&pRxContext->IrpLock) == IRPLOCK_CANCELABLE)
+ {
+ RTUSB_UNLINK_URB(pRxContext->pUrb);
+ }
+ InterlockedExchange(&pRxContext->IrpLock, IRPLOCK_CANCE_START);
+ }
+#endif // 1 //
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("<---ATE_RTUSBCancelPendingBulkInIRP\n"));
+ return;
+}
+#endif // RT2870 //
+
+VOID rt_ee_read_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+ USHORT i;
+ USHORT value;
+
+ for (i = 0 ; i < EEPROM_SIZE/2 ; )
+ {
+ /* "value" is expecially for some compilers... */
+ RT28xx_EEPROM_READ16(pAd, i*2, value);
+ Data[i] = value;
+ i++;
+ }
+}
+
+VOID rt_ee_write_all(PRTMP_ADAPTER pAd, USHORT *Data)
+{
+ USHORT i;
+ USHORT value;
+
+ for (i = 0 ; i < EEPROM_SIZE/2 ; )
+ {
+ /* "value" is expecially for some compilers... */
+ value = Data[i];
+ RT28xx_EEPROM_WRITE16(pAd, i*2, value);
+ i ++;
+ }
+}
+#ifdef RALINK_28xx_QA
+VOID ATE_QA_Statistics(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC pRxD,
+ IN PHEADER_802_11 pHeader)
+{
+ // update counter first
+ if (pHeader != NULL)
+ {
+ if (pHeader->FC.Type == BTYPE_DATA)
+ {
+ if (pRxD->U2M)
+ pAd->ate.U2M++;
+ else
+ pAd->ate.OtherData++;
+ }
+ else if (pHeader->FC.Type == BTYPE_MGMT)
+ {
+ if (pHeader->FC.SubType == SUBTYPE_BEACON)
+ pAd->ate.Beacon++;
+ else
+ pAd->ate.OtherCount++;
+ }
+ else if (pHeader->FC.Type == BTYPE_CNTL)
+ {
+ pAd->ate.OtherCount++;
+ }
+ }
+ pAd->ate.RSSI0 = pRxWI->RSSI0;
+ pAd->ate.RSSI1 = pRxWI->RSSI1;
+ pAd->ate.RSSI2 = pRxWI->RSSI2;
+ pAd->ate.SNR0 = pRxWI->SNR0;
+ pAd->ate.SNR1 = pRxWI->SNR1;
+}
+
+/* command id with Cmd Type == 0x0008(for 28xx)/0x0005(for iNIC) */
+#define RACFG_CMD_RF_WRITE_ALL 0x0000
+#define RACFG_CMD_E2PROM_READ16 0x0001
+#define RACFG_CMD_E2PROM_WRITE16 0x0002
+#define RACFG_CMD_E2PROM_READ_ALL 0x0003
+#define RACFG_CMD_E2PROM_WRITE_ALL 0x0004
+#define RACFG_CMD_IO_READ 0x0005
+#define RACFG_CMD_IO_WRITE 0x0006
+#define RACFG_CMD_IO_READ_BULK 0x0007
+#define RACFG_CMD_BBP_READ8 0x0008
+#define RACFG_CMD_BBP_WRITE8 0x0009
+#define RACFG_CMD_BBP_READ_ALL 0x000a
+#define RACFG_CMD_GET_COUNTER 0x000b
+#define RACFG_CMD_CLEAR_COUNTER 0x000c
+
+#define RACFG_CMD_RSV1 0x000d
+#define RACFG_CMD_RSV2 0x000e
+#define RACFG_CMD_RSV3 0x000f
+
+#define RACFG_CMD_TX_START 0x0010
+#define RACFG_CMD_GET_TX_STATUS 0x0011
+#define RACFG_CMD_TX_STOP 0x0012
+#define RACFG_CMD_RX_START 0x0013
+#define RACFG_CMD_RX_STOP 0x0014
+#define RACFG_CMD_GET_NOISE_LEVEL 0x0015
+
+#define RACFG_CMD_ATE_START 0x0080
+#define RACFG_CMD_ATE_STOP 0x0081
+
+#define RACFG_CMD_ATE_START_TX_CARRIER 0x0100
+#define RACFG_CMD_ATE_START_TX_CONT 0x0101
+#define RACFG_CMD_ATE_START_TX_FRAME 0x0102
+#define RACFG_CMD_ATE_SET_BW 0x0103
+#define RACFG_CMD_ATE_SET_TX_POWER0 0x0104
+#define RACFG_CMD_ATE_SET_TX_POWER1 0x0105
+#define RACFG_CMD_ATE_SET_FREQ_OFFSET 0x0106
+#define RACFG_CMD_ATE_GET_STATISTICS 0x0107
+#define RACFG_CMD_ATE_RESET_COUNTER 0x0108
+#define RACFG_CMD_ATE_SEL_TX_ANTENNA 0x0109
+#define RACFG_CMD_ATE_SEL_RX_ANTENNA 0x010a
+#define RACFG_CMD_ATE_SET_PREAMBLE 0x010b
+#define RACFG_CMD_ATE_SET_CHANNEL 0x010c
+#define RACFG_CMD_ATE_SET_ADDR1 0x010d
+#define RACFG_CMD_ATE_SET_ADDR2 0x010e
+#define RACFG_CMD_ATE_SET_ADDR3 0x010f
+#define RACFG_CMD_ATE_SET_RATE 0x0110
+#define RACFG_CMD_ATE_SET_TX_FRAME_LEN 0x0111
+#define RACFG_CMD_ATE_SET_TX_FRAME_COUNT 0x0112
+#define RACFG_CMD_ATE_START_RX_FRAME 0x0113
+#define RACFG_CMD_ATE_E2PROM_READ_BULK 0x0114
+#define RACFG_CMD_ATE_E2PROM_WRITE_BULK 0x0115
+#define RACFG_CMD_ATE_IO_WRITE_BULK 0x0116
+#define RACFG_CMD_ATE_BBP_READ_BULK 0x0117
+#define RACFG_CMD_ATE_BBP_WRITE_BULK 0x0118
+#define RACFG_CMD_ATE_RF_READ_BULK 0x0119
+#define RACFG_CMD_ATE_RF_WRITE_BULK 0x011a
+
+
+
+#define A2Hex(_X, _p) \
+{ \
+ UCHAR *p; \
+ _X = 0; \
+ p = _p; \
+ while (((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F')) || ((*p >= '0') && (*p <= '9'))) \
+ { \
+ if ((*p >= 'a') && (*p <= 'f')) \
+ _X = _X * 16 + *p - 87; \
+ else if ((*p >= 'A') && (*p <= 'F')) \
+ _X = _X * 16 + *p - 55; \
+ else if ((*p >= '0') && (*p <= '9')) \
+ _X = _X * 16 + *p - 48; \
+ p++; \
+ } \
+}
+
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len);
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len);
+
+#ifdef UCOS
+int ate_copy_to_user(
+ IN PUCHAR payload,
+ IN PUCHAR msg,
+ IN INT len)
+{
+ memmove(payload, msg, len);
+ return 0;
+}
+
+#undef copy_to_user
+#define copy_to_user(x,y,z) ate_copy_to_user((PUCHAR)x, (PUCHAR)y, z)
+#endif // UCOS //
+
+#define LEN_OF_ARG 16
+
+VOID RtmpDoAte(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ unsigned short Command_Id;
+ struct ate_racfghdr *pRaCfg;
+ INT Status = NDIS_STATUS_SUCCESS;
+
+
+
+ if((pRaCfg = kmalloc(sizeof(struct ate_racfghdr), GFP_KERNEL)) == NULL)
+ {
+ Status = -EINVAL;
+ return;
+ }
+
+ NdisZeroMemory(pRaCfg, sizeof(struct ate_racfghdr));
+
+ if (copy_from_user((PUCHAR)pRaCfg, wrq->u.data.pointer, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ kfree(pRaCfg);
+ return;
+ }
+
+
+ Command_Id = ntohs(pRaCfg->command_id);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("\n%s: Command_Id = 0x%04x !\n", __FUNCTION__, Command_Id));
+
+ switch (Command_Id)
+ {
+ // We will get this command when QA starts.
+ case RACFG_CMD_ATE_START:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START\n"));
+
+ // prepare feedback as soon as we can to avoid QA timeout.
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_ATE_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START is done !\n"));
+ }
+ Set_ATE_Proc(pAdapter, "ATESTART");
+ }
+ break;
+
+ // We will get this command either QA is closed or ated is killed by user.
+ case RACFG_CMD_ATE_STOP:
+ {
+#ifndef UCOS
+ INT32 ret;
+#endif // !UCOS //
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_STOP\n"));
+
+ // Distinguish this command came from QA(via ated)
+ // or ate daemon according to the existence of pid in payload.
+ // No need to prepare feedback if this cmd came directly from ate daemon.
+ pRaCfg->length = ntohs(pRaCfg->length);
+
+ if (pRaCfg->length == sizeof(pAdapter->ate.AtePid))
+ {
+ // This command came from QA.
+ // Get the pid of ATE daemon.
+ memcpy((UCHAR *)&pAdapter->ate.AtePid,
+ (&pRaCfg->data[0]) - 2/* == &(pRaCfg->status) */,
+ sizeof(pAdapter->ate.AtePid));
+
+ // prepare feedback as soon as we can to avoid QA timeout.
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_STOP\n"));
+ Status = -EFAULT;
+ }
+
+ //
+ // kill ATE daemon when leaving ATE mode.
+ // We must kill ATE daemon first before setting ATESTOP,
+ // or Microsoft will report sth. wrong.
+#ifndef UCOS
+ ret = kill_proc(pAdapter->ate.AtePid, SIGTERM, 1);
+ if (ret)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("%s: unable to signal thread\n", pAdapter->net_dev->name));
+ }
+#endif // !UCOS //
+ }
+
+#ifdef UCOS
+ // Roger add to avoid error message after close QA
+ if (pAdapter->CSRBaseAddress == RT2860_CSR_ADDR)
+ {
+
+ // prepare feedback as soon as we can to avoid QA timeout.
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_AP_START\n"));
+ Status = -EFAULT;
+ }
+ }
+#endif // UCOS //
+
+ // AP might have in ATE_STOP mode due to cmd from QA.
+ if (ATE_ON(pAdapter))
+ {
+ // Someone has killed ate daemon while QA GUI is still open.
+ Set_ATE_Proc(pAdapter, "ATESTOP");
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_AP_START is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_RF_WRITE_ALL:
+ {
+ UINT32 R1, R2, R3, R4;
+ USHORT channel;
+
+ memcpy(&R1, pRaCfg->data-2, 4);
+ memcpy(&R2, pRaCfg->data+2, 4);
+ memcpy(&R3, pRaCfg->data+6, 4);
+ memcpy(&R4, pRaCfg->data+10, 4);
+ memcpy(&channel, pRaCfg->data+14, 2);
+
+ pAdapter->LatchRfRegs.R1 = ntohl(R1);
+ pAdapter->LatchRfRegs.R2 = ntohl(R2);
+ pAdapter->LatchRfRegs.R3 = ntohl(R3);
+ pAdapter->LatchRfRegs.R4 = ntohl(R4);
+ pAdapter->LatchRfRegs.Channel = ntohs(channel);
+
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R1);
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R2);
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R3);
+ RTMP_RF_IO_WRITE32(pAdapter, pAdapter->LatchRfRegs.R4);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RF_WRITE_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RF_WRITE_ALL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_READ16:
+ {
+ USHORT offset, value, tmp;
+
+ offset = ntohs(pRaCfg->status);
+ /* "tmp" is expecially for some compilers... */
+ RT28xx_EEPROM_READ16(pAdapter, offset, tmp);
+ value = tmp;
+ value = htons(value);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("EEPROM Read offset = 0x%04x, value = 0x%04x\n", offset, value));
+
+ // prepare feedback
+ pRaCfg->length = htons(4);
+ pRaCfg->status = htons(0);
+ memcpy(pRaCfg->data, &value, 2);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("sizeof(struct ate_racfghdr) = %d\n", sizeof(struct ate_racfghdr)));
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ16\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ16 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_WRITE16:
+ {
+ USHORT offset, value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&value, pRaCfg->data, 2);
+ value = ntohs(value);
+ RT28xx_EEPROM_WRITE16(pAdapter, offset, value);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE16\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_WRITE16 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_READ_ALL:
+ {
+ USHORT buffer[EEPROM_SIZE/2];
+
+ rt_ee_read_all(pAdapter,(USHORT *)buffer);
+ memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer, EEPROM_SIZE);
+
+ // prepare feedback
+ pRaCfg->length = htons(2+EEPROM_SIZE);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_READ_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_E2PROM_READ_ALL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_E2PROM_WRITE_ALL:
+ {
+ USHORT buffer[EEPROM_SIZE/2];
+
+ NdisZeroMemory((UCHAR *)buffer, EEPROM_SIZE);
+ memcpy_exs(pAdapter, (UCHAR *)buffer, (UCHAR *)&pRaCfg->status, EEPROM_SIZE);
+ rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_E2PROM_WRITE_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_E2PROM_WRITE_ALL is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_IO_READ:
+ {
+ UINT32 offset;
+ UINT32 value;
+
+ memcpy(&offset, &pRaCfg->status, 4);
+ offset = ntohl(offset);
+
+ // We do not need the base address.
+ // So just extract the offset out.
+ offset &= 0x0000FFFF;
+ RTMP_IO_READ32(pAdapter, offset, &value);
+ value = htonl(value);
+
+ // prepare feedback
+ pRaCfg->length = htons(6);
+ pRaCfg->status = htons(0);
+ memcpy(pRaCfg->data, &value, 4);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_IO_WRITE:
+ {
+ UINT32 offset, value;
+
+ memcpy(&offset, pRaCfg->data-2, 4);
+ memcpy(&value, pRaCfg->data+2, 4);
+
+ offset = ntohl(offset);
+
+ // We do not need the base address.
+ // So just extract out the offset.
+ offset &= 0x0000FFFF;
+ value = ntohl(value);
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_IO_WRITE: offset = %x, value = %x\n", offset, value));
+ RTMP_IO_WRITE32(pAdapter, offset, value);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_WRITE\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_WRITE is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_IO_READ_BULK:
+ {
+ UINT32 offset;
+ USHORT len;
+
+ memcpy(&offset, &pRaCfg->status, 4);
+ offset = ntohl(offset);
+
+ // We do not need the base address.
+ // So just extract the offset.
+ offset &= 0x0000FFFF;
+ memcpy(&len, pRaCfg->data+2, 2);
+ len = ntohs(len);
+
+ if (len > 371)
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("len is too large, make it smaller\n"));
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(1);
+ break;
+ }
+
+ RTMP_IO_READ_BULK(pAdapter, pRaCfg->data, (UCHAR *)offset, len*4);// unit in four bytes
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len*4);// unit in four bytes
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_IO_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_IO_READ_BULK is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_BBP_READ8:
+ {
+ USHORT offset;
+ UCHAR value;
+
+ value = 0;
+ offset = ntohs(pRaCfg->status);
+
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, offset, &value);
+ }
+ // prepare feedback
+ pRaCfg->length = htons(3);
+ pRaCfg->status = htons(0);
+ pRaCfg->data[0] = value;
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("BBP value = %x\n", value));
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ8\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ8 is done !\n"));
+ }
+ }
+ break;
+ case RACFG_CMD_BBP_WRITE8:
+ {
+ USHORT offset;
+ UCHAR value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&value, pRaCfg->data, 1);
+
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
+ }
+ else
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, offset, value);
+ }
+
+ if ((offset == BBP_R1) || (offset == BBP_R3))
+ {
+ SyncTxRxConfig(pAdapter, offset, value);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_WRITE8\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_WRITE8 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_BBP_READ_ALL:
+ {
+ USHORT j;
+
+ for (j = 0; j < 137; j++)
+ {
+ pRaCfg->data[j] = 0;
+
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j]);
+ }
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2+137);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_BBP_READ_ALL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_BBP_READ_ALL is done !\n"));
+ }
+ }
+
+ break;
+
+ case RACFG_CMD_ATE_E2PROM_READ_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT buffer[EEPROM_SIZE/2];
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ rt_ee_read_all(pAdapter,(USHORT *)buffer);
+ if (offset + len <= EEPROM_SIZE)
+ memcpy_exs(pAdapter, pRaCfg->data, (UCHAR *)buffer+offset, len);
+ else
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("exceed EEPROM size\n"));
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_E2PROM_READ_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_E2PROM_WRITE_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT buffer[EEPROM_SIZE/2];
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ rt_ee_read_all(pAdapter,(USHORT *)buffer);
+ memcpy_exs(pAdapter, (UCHAR *)buffer + offset, (UCHAR *)pRaCfg->data + 2, len);
+ rt_ee_write_all(pAdapter,(USHORT *)buffer);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_E2PROM_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_E2PROM_WRITE_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_IO_WRITE_BULK:
+ {
+ UINT32 offset, i, value;
+ USHORT len;
+
+ memcpy(&offset, &pRaCfg->status, 4);
+ offset = ntohl(offset);
+ memcpy(&len, pRaCfg->data+2, 2);
+ len = ntohs(len);
+
+ for (i = 0; i < len; i += 4)
+ {
+ memcpy_exl(pAdapter, (UCHAR *)&value, pRaCfg->data+4+i, 4);
+ printk("Write %x %x\n", offset + i, value);
+ RTMP_IO_WRITE32(pAdapter, (offset +i) & 0xffff, value);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_IO_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("RACFG_CMD_ATE_IO_WRITE_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_BBP_READ_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ pRaCfg->data[j - offset] = 0;
+
+ if (pAdapter->ate.Mode == ATE_STOP)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
+ }
+ else
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, j, &pRaCfg->data[j - offset]);
+ }
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_READ_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_BBP_WRITE_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+ UCHAR *value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ value = pRaCfg->data + 2 + (j - offset);
+ if (pAdapter->ate.Mode == ATE_STOP)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
+ }
+ else
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, j, *value);
+ }
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_BBP_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_BBP_WRITE_BULK is done !\n"));
+ }
+ }
+ break;
+
+#ifdef CONFIG_RALINK_RT3052
+ case RACFG_CMD_ATE_RF_READ_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ pRaCfg->data[j - offset] = 0;
+ RT30xxReadRFRegister(pAdapter, j, &pRaCfg->data[j - offset]);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2+len);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_READ_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_READ_BULK is done !\n"));
+ }
+
+ }
+ break;
+
+ case RACFG_CMD_ATE_RF_WRITE_BULK:
+ {
+ USHORT offset;
+ USHORT len;
+ USHORT j;
+ UCHAR *value;
+
+ offset = ntohs(pRaCfg->status);
+ memcpy(&len, pRaCfg->data, 2);
+ len = ntohs(len);
+
+ for (j = offset; j < (offset+len); j++)
+ {
+ value = pRaCfg->data + 2 + (j - offset);
+ RT30xxWriteRFRegister(pAdapter, j, *value);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RF_WRITE_BULK\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RF_WRITE_BULK is done !\n"));
+ }
+
+ }
+ break;
+#endif
+
+
+ case RACFG_CMD_GET_NOISE_LEVEL:
+ {
+ UCHAR channel;
+ INT32 buffer[3][10];/* 3 : RxPath ; 10 : no. of per rssi samples */
+
+ channel = (ntohs(pRaCfg->status) & 0x00FF);
+ CalNoiseLevel(pAdapter, channel, buffer);
+ memcpy_exl(pAdapter, (UCHAR *)pRaCfg->data, (UCHAR *)&(buffer[0][0]), (sizeof(INT32)*3*10));
+
+ // prepare feedback
+ pRaCfg->length = htons(2 + (sizeof(INT32)*3*10));
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_NOISE_LEVEL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_NOISE_LEVEL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_GET_COUNTER:
+ {
+ memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.U2M, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->ate.OtherData, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->ate.Beacon, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->ate.OtherCount, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->ate.TxAc0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->ate.TxAc1, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->ate.TxAc2, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->ate.TxAc3, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->ate.TxHCCA, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->ate.TxMgmt, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&pAdapter->ate.RSSI0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&pAdapter->ate.RSSI1, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&pAdapter->ate.RSSI2, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[52], (UCHAR *)&pAdapter->ate.SNR0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[56], (UCHAR *)&pAdapter->ate.SNR1, 4);
+
+ pRaCfg->length = htons(2+60);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_COUNTER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_COUNTER is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_CLEAR_COUNTER:
+ {
+ pAdapter->ate.U2M = 0;
+ pAdapter->ate.OtherData = 0;
+ pAdapter->ate.Beacon = 0;
+ pAdapter->ate.OtherCount = 0;
+ pAdapter->ate.TxAc0 = 0;
+ pAdapter->ate.TxAc1 = 0;
+ pAdapter->ate.TxAc2 = 0;
+ pAdapter->ate.TxAc3 = 0;
+ pAdapter->ate.TxHCCA = 0;
+ pAdapter->ate.TxMgmt = 0;
+ pAdapter->ate.TxDoneCount = 0;
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_CLEAR_COUNTER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_CLEAR_COUNTER is done !\n"));
+ }
+ }
+
+ break;
+
+ case RACFG_CMD_TX_START:
+ {
+ USHORT *p;
+ USHORT err = 1;
+ UCHAR Bbp22Value = 0, Bbp24Value = 0;
+
+ if ((pAdapter->ate.TxStatus != 0) && (pAdapter->ate.Mode & ATE_TXFRAME))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Ate Tx is already running, to run next Tx, you must stop it first\n"));
+ err = 2;
+ goto TX_START_ERROR;
+ }
+ else if ((pAdapter->ate.TxStatus != 0) && !(pAdapter->ate.Mode & ATE_TXFRAME))
+ {
+ int i = 0;
+
+ while ((i++ < 10) && (pAdapter->ate.TxStatus != 0))
+ {
+ RTMPusecDelay(5000);
+ }
+
+ // force it to stop
+ pAdapter->ate.TxStatus = 0;
+ pAdapter->ate.TxDoneCount = 0;
+ //pAdapter->ate.Repeat = 0;
+ pAdapter->ate.bQATxStart = FALSE;
+ }
+
+ // If pRaCfg->length == 0, this "RACFG_CMD_TX_START" is for Carrier test or Carrier Suppression.
+ if (ntohs(pRaCfg->length) != 0)
+ {
+ // Get frame info
+#ifdef RT2870
+ NdisMoveMemory(&pAdapter->ate.TxInfo, pRaCfg->data - 2, 4);
+#ifdef RT_BIG_ENDIAN
+ RTMPDescriptorEndianChange((PUCHAR) &pAdapter->ate.TxInfo, TYPE_TXINFO);
+#endif // RT_BIG_ENDIAN //
+#endif // RT2870 //
+
+ NdisMoveMemory(&pAdapter->ate.TxWI, pRaCfg->data + 2, 16);
+#ifdef RT_BIG_ENDIAN
+ RTMPWIEndianChange((PUCHAR)&pAdapter->ate.TxWI, TYPE_TXWI);
+#endif // RT_BIG_ENDIAN //
+
+ NdisMoveMemory(&pAdapter->ate.TxCount, pRaCfg->data + 18, 4);
+ pAdapter->ate.TxCount = ntohl(pAdapter->ate.TxCount);
+
+ p = (USHORT *)(&pRaCfg->data[22]);
+ //p = pRaCfg->data + 22;
+ // always use QID_AC_BE
+ pAdapter->ate.QID = 0;
+ p = (USHORT *)(&pRaCfg->data[24]);
+ //p = pRaCfg->data + 24;
+ pAdapter->ate.HLen = ntohs(*p);
+
+ if (pAdapter->ate.HLen > 32)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.HLen > 32\n"));
+ err = 3;
+ goto TX_START_ERROR;
+ }
+
+ NdisMoveMemory(&pAdapter->ate.Header, pRaCfg->data + 26, pAdapter->ate.HLen);
+
+
+ pAdapter->ate.PLen = ntohs(pRaCfg->length) - (pAdapter->ate.HLen + 28);
+
+ if (pAdapter->ate.PLen > 32)
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("pAdapter->ate.PLen > 32\n"));
+ err = 4;
+ goto TX_START_ERROR;
+ }
+
+ NdisMoveMemory(&pAdapter->ate.Pattern, pRaCfg->data + 26 + pAdapter->ate.HLen, pAdapter->ate.PLen);
+ pAdapter->ate.DLen = pAdapter->ate.TxWI.MPDUtotalByteCount - pAdapter->ate.HLen;
+ }
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R22, &Bbp22Value);
+
+ switch (Bbp22Value)
+ {
+ case BBP22_TXFRAME:
+ {
+ if (pAdapter->ate.TxCount == 0)
+ {
+ }
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXFRAME\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "TXFRAME");
+ }
+ break;
+
+ case BBP22_TXCONT_OR_CARRSUPP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("BBP22_TXCONT_OR_CARRSUPP\n"));
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, 24, &Bbp24Value);
+
+ switch (Bbp24Value)
+ {
+ case BBP24_TXCONT:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCONT\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "TXCONT");
+ }
+ break;
+
+ case BBP24_CARRSUPP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARRSUPP\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ pAdapter->ate.Mode |= ATE_TXCARRSUPP;
+ }
+ break;
+
+ default:
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+ }
+ break;
+ }
+ }
+ break;
+
+ case BBP22_TXCARR:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("START TXCARR\n"));
+ pAdapter->ate.bQATxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "TXCARR");
+ }
+ break;
+
+ default:
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR,("Unknown Start TX subtype !"));
+ }
+ break;
+ }
+
+ if (pAdapter->ate.bQATxStart == TRUE)
+ {
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() was failed in case RACFG_CMD_TX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_START is done !\n"));
+ }
+ break;
+ }
+
+TX_START_ERROR:
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(err);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_TX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("feedback of TX_START_ERROR is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_GET_TX_STATUS:
+ {
+ UINT32 count;
+
+ // prepare feedback
+ pRaCfg->length = htons(6);
+ pRaCfg->status = htons(0);
+ count = htonl(pAdapter->ate.TxDoneCount);
+ NdisMoveMemory(pRaCfg->data, &count, 4);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_GET_TX_STATUS\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_GET_TX_STATUS is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_TX_STOP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_TX_STOP\n"));
+
+ Set_ATE_Proc(pAdapter, "TXSTOP");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("copy_to_user() fail in case RACFG_CMD_TX_STOP\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_TX_STOP is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_RX_START:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+ pAdapter->ate.bQARxStart = TRUE;
+ Set_ATE_Proc(pAdapter, "RXFRAME");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_RX_STOP:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_STOP\n"));
+
+ Set_ATE_Proc(pAdapter, "RXSTOP");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_STOP\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_STOP is done !\n"));
+ }
+ }
+ break;
+
+ /* The following cases are for new ATE GUI(not QA). */
+ /*==================================================*/
+ case RACFG_CMD_ATE_START_TX_CARRIER:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CARRIER\n"));
+
+ Set_ATE_Proc(pAdapter, "TXCARR");
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CARRIER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CARRIER is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_START_TX_CONT:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_CONT\n"));
+
+ Set_ATE_Proc(pAdapter, "TXCONT");
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_CONT\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_CONT is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_START_TX_FRAME:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_START_TX_FRAME\n"));
+
+ Set_ATE_Proc(pAdapter, "TXFRAME");
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("wrq->u.data.length = %d\n", wrq->u.data.length));
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_START_TX_FRAME\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_START_TX_FRAME is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_BW:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_BW\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+
+ Set_ATE_TX_BW_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_BW\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_BW is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_POWER0:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER0\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_POWER0_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER0\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER0 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_POWER1:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_POWER1\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_POWER1_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_POWER1\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_POWER1 is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_FREQ_OFFSET:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_FREQOFFSET_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_FREQ_OFFSET\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_FREQ_OFFSET is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_GET_STATISTICS:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_GET_STATISTICS\n"));
+
+ memcpy_exl(pAdapter, &pRaCfg->data[0], (UCHAR *)&pAdapter->ate.TxDoneCount, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[4], (UCHAR *)&pAdapter->WlanCounters.RetryCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[8], (UCHAR *)&pAdapter->WlanCounters.FailedCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[12], (UCHAR *)&pAdapter->WlanCounters.RTSSuccessCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[16], (UCHAR *)&pAdapter->WlanCounters.RTSFailureCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[20], (UCHAR *)&pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[24], (UCHAR *)&pAdapter->WlanCounters.FCSErrorCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[28], (UCHAR *)&pAdapter->Counters8023.RxNoBuffer, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[32], (UCHAR *)&pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[36], (UCHAR *)&pAdapter->RalinkCounters.OneSecFalseCCACnt, 4);
+
+ if (pAdapter->ate.RxAntennaSel == 0)
+ {
+ INT32 RSSI0 = 0;
+ INT32 RSSI1 = 0;
+ INT32 RSSI2 = 0;
+
+ RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+ RSSI1 = (INT32)(pAdapter->ate.LastRssi1 - pAdapter->BbpRssiToDbmDelta);
+ RSSI2 = (INT32)(pAdapter->ate.LastRssi2 - pAdapter->BbpRssiToDbmDelta);
+ memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[44], (UCHAR *)&RSSI1, 4);
+ memcpy_exl(pAdapter, &pRaCfg->data[48], (UCHAR *)&RSSI2, 4);
+ pRaCfg->length = htons(2+52);
+ }
+ else
+ {
+ INT32 RSSI0 = 0;
+
+ RSSI0 = (INT32)(pAdapter->ate.LastRssi0 - pAdapter->BbpRssiToDbmDelta);
+ memcpy_exl(pAdapter, &pRaCfg->data[40], (UCHAR *)&RSSI0, 4);
+ pRaCfg->length = htons(2+44);
+ }
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_GET_STATISTICS\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_GET_STATISTICS is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_RESET_COUNTER:
+ {
+ SHORT value = 1;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_RESET_COUNTER\n"));
+
+ sprintf((PCHAR)str, "%d", value);
+ Set_ResetStatCounter_Proc(pAdapter, str);
+
+ pAdapter->ate.TxDoneCount = 0;
+
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_RESET_COUNTER\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_RESET_COUNTER is done !\n"));
+ }
+ }
+
+ break;
+
+ case RACFG_CMD_ATE_SEL_TX_ANTENNA:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_Antenna_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_TX_ANTENNA\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_TX_ANTENNA is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SEL_RX_ANTENNA:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_RX_Antenna_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SEL_RX_ANTENNA\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SEL_RX_ANTENNA is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_PREAMBLE:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_PREAMBLE\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_MODE_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_PREAMBLE\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_PREAMBLE is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_CHANNEL:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_CHANNEL\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_CHANNEL_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_CHANNEL\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_CHANNEL is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_ADDR1:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR1\n"));
+
+ // Addr is an array of UCHAR,
+ // so no need to perform endian swap.
+ memcpy(pAdapter->ate.Addr1, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR1\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR1 is done !\n (ADDR1 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr1[0],
+ pAdapter->ate.Addr1[1], pAdapter->ate.Addr1[2], pAdapter->ate.Addr1[3], pAdapter->ate.Addr1[4], pAdapter->ate.Addr1[5]));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_ADDR2:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR2\n"));
+
+ // Addr is an array of UCHAR,
+ // so no need to perform endian swap.
+ memcpy(pAdapter->ate.Addr2, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR2\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR2 is done !\n (ADDR2 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr2[0],
+ pAdapter->ate.Addr2[1], pAdapter->ate.Addr2[2], pAdapter->ate.Addr2[3], pAdapter->ate.Addr2[4], pAdapter->ate.Addr2[5]));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_ADDR3:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_ADDR3\n"));
+
+ // Addr is an array of UCHAR,
+ // so no need to perform endian swap.
+ memcpy(pAdapter->ate.Addr3, (PUCHAR)(pRaCfg->data - 2), MAC_ADDR_LEN);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_ADDR3\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_ADDR3 is done !\n (ADDR3 = %2X:%2X:%2X:%2X:%2X:%2X)\n", pAdapter->ate.Addr3[0],
+ pAdapter->ate.Addr3[1], pAdapter->ate.Addr3[2], pAdapter->ate.Addr3[3], pAdapter->ate.Addr3[4], pAdapter->ate.Addr3[5]));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_RATE:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_RATE\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_MCS_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_RATE\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_RATE is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_FRAME_LEN:
+ {
+ SHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_LENGTH_Proc(pAdapter, str);
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_LEN\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_LEN is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_SET_TX_FRAME_COUNT:
+ {
+ USHORT value = 0;
+ UCHAR str[LEN_OF_ARG];
+
+ NdisZeroMemory(str, LEN_OF_ARG);
+
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+
+ memcpy((PUCHAR)&value, (PUCHAR)&(pRaCfg->status), 2);
+ value = ntohs(value);
+ {
+ sprintf((PCHAR)str, "%d", value);
+ Set_ATE_TX_COUNT_Proc(pAdapter, str);
+ }
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_ATE_SET_TX_FRAME_COUNT\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_ATE_SET_TX_FRAME_COUNT is done !\n"));
+ }
+ }
+ break;
+
+ case RACFG_CMD_ATE_START_RX_FRAME:
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE,("RACFG_CMD_RX_START\n"));
+
+ Set_ATE_Proc(pAdapter, "RXFRAME");
+
+ // prepare feedback
+ pRaCfg->length = htons(2);
+ pRaCfg->status = htons(0);
+ wrq->u.data.length = sizeof(pRaCfg->magic_no) + sizeof(pRaCfg->command_type)
+ + sizeof(pRaCfg->command_id) + sizeof(pRaCfg->length)
+ + sizeof(pRaCfg->sequence) + ntohs(pRaCfg->length);
+
+ if (copy_to_user(wrq->u.data.pointer, pRaCfg, wrq->u.data.length))
+ {
+ ATEDBGPRINT(RT_DEBUG_ERROR, ("copy_to_user() fail in case RACFG_CMD_RX_START\n"));
+ Status = -EFAULT;
+ }
+ else
+ {
+ ATEDBGPRINT(RT_DEBUG_TRACE, ("RACFG_CMD_RX_START is done !\n"));
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ ASSERT(pRaCfg != NULL);
+ if (pRaCfg != NULL)
+ {
+ kfree(pRaCfg);
+ }
+ return;
+}
+
+VOID BubbleSort(INT32 n, INT32 a[])
+{
+ INT32 k, j, temp;
+
+ for (k = n-1; k>0; k--)
+ {
+ for (j = 0; j<k; j++)
+ {
+ if(a[j] > a[j+1])
+ {
+ temp = a[j];
+ a[j]=a[j+1];
+ a[j+1]=temp;
+ }
+ }
+ }
+}
+
+VOID CalNoiseLevel(PRTMP_ADAPTER pAd, UCHAR channel, INT32 RSSI[3][10])
+{
+ INT32 RSSI0, RSSI1, RSSI2;
+ CHAR Rssi0Offset, Rssi1Offset, Rssi2Offset;
+ UCHAR BbpR50Rssi0 = 0, BbpR51Rssi1 = 0, BbpR52Rssi2 = 0;
+ UCHAR Org_BBP66value = 0, Org_BBP69value = 0, Org_BBP70value = 0, data = 0;
+ USHORT LNA_Gain = 0;
+ INT32 j = 0;
+ UCHAR Org_Channel = pAd->ate.Channel;
+ USHORT GainValue = 0, OffsetValue = 0;
+
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &Org_BBP66value);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R69, &Org_BBP69value);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R70, &Org_BBP70value);
+
+ //**********************************************************************
+ // Read the value of LNA gain and Rssi offset
+ //**********************************************************************
+ RT28xx_EEPROM_READ16(pAd, EEPROM_LNA_OFFSET, GainValue);
+
+ // for Noise Level
+ if (channel <= 14)
+ {
+ LNA_Gain = GainValue & 0x00FF;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_BG_OFFSET, OffsetValue);
+ Rssi0Offset = OffsetValue & 0x00FF;
+ Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+ RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_BG_OFFSET + 2)/* 0x48 */, OffsetValue);
+ Rssi2Offset = OffsetValue & 0x00FF;
+ }
+ else
+ {
+ LNA_Gain = (GainValue & 0xFF00) >> 8;
+
+ RT28xx_EEPROM_READ16(pAd, EEPROM_RSSI_A_OFFSET, OffsetValue);
+ Rssi0Offset = OffsetValue & 0x00FF;
+ Rssi1Offset = (OffsetValue & 0xFF00) >> 8;
+ RT28xx_EEPROM_READ16(pAd, (EEPROM_RSSI_A_OFFSET + 2)/* 0x4C */, OffsetValue);
+ Rssi2Offset = OffsetValue & 0x00FF;
+ }
+ //**********************************************************************
+ {
+ pAd->ate.Channel = channel;
+ ATEAsicSwitchChannel(pAd);
+ mdelay(5);
+
+ data = 0x10;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, data);
+ data = 0x40;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, data);
+ data = 0x40;
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, data);
+ mdelay(5);
+
+ // Start Rx
+ pAd->ate.bQARxStart = TRUE;
+ Set_ATE_Proc(pAd, "RXFRAME");
+
+ mdelay(5);
+
+ for (j = 0; j < 10; j++)
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R50, &BbpR50Rssi0);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R51, &BbpR51Rssi1);
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R52, &BbpR52Rssi2);
+
+ mdelay(10);
+
+ // Calculate RSSI 0
+ if (BbpR50Rssi0 == 0)
+ {
+ RSSI0 = -100;
+ }
+ else
+ {
+ RSSI0 = (INT32)(-12 - BbpR50Rssi0 - LNA_Gain - Rssi0Offset);
+ }
+ RSSI[0][j] = RSSI0;
+
+ if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+ {
+ // Calculate RSSI 1
+ if (BbpR51Rssi1 == 0)
+ {
+ RSSI1 = -100;
+ }
+ else
+ {
+ RSSI1 = (INT32)(-12 - BbpR51Rssi1 - LNA_Gain - Rssi1Offset);
+ }
+ RSSI[1][j] = RSSI1;
+ }
+
+ if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+ {
+ // Calculate RSSI 2
+ if (BbpR52Rssi2 == 0)
+ RSSI2 = -100;
+ else
+ RSSI2 = (INT32)(-12 - BbpR52Rssi2 - LNA_Gain - Rssi2Offset);
+
+ RSSI[2][j] = RSSI2;
+ }
+ }
+
+ // Stop Rx
+ Set_ATE_Proc(pAd, "RXSTOP");
+
+ mdelay(5);
+
+ BubbleSort(10, RSSI[0]); // 1R
+
+ if ( pAd->Antenna.field.RxPath >= 2 ) // 2R
+ {
+ BubbleSort(10, RSSI[1]);
+ }
+
+ if ( pAd->Antenna.field.RxPath >= 3 ) // 3R
+ {
+ BubbleSort(10, RSSI[2]);
+ }
+
+ }
+
+ pAd->ate.Channel = Org_Channel;
+ ATEAsicSwitchChannel(pAd);
+
+ // Restore original value
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, Org_BBP66value);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, Org_BBP69value);
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, Org_BBP70value);
+
+ return;
+}
+
+BOOLEAN SyncTxRxConfig(PRTMP_ADAPTER pAd, USHORT offset, UCHAR value)
+{
+ UCHAR tmp = 0, bbp_data = 0;
+
+ if (ATE_ON(pAd))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, offset, &bbp_data);
+ }
+
+ /* confirm again */
+ ASSERT(bbp_data == value);
+
+ switch(offset)
+ {
+ case BBP_R1:
+ /* Need to sync. tx configuration with legacy ATE. */
+ tmp = (bbp_data & ((1 << 4) | (1 << 3))/* 0x18 */) >> 3;
+ switch(tmp)
+ {
+ /* The BBP R1 bit[4:3] = 2 :: Both DACs will be used by QA. */
+ case 2:
+ /* All */
+ pAd->ate.TxAntennaSel = 0;
+ break;
+ /* The BBP R1 bit[4:3] = 0 :: DAC 0 will be used by QA. */
+ case 0:
+ /* Antenna one */
+ pAd->ate.TxAntennaSel = 1;
+ break;
+ /* The BBP R1 bit[4:3] = 1 :: DAC 1 will be used by QA. */
+ case 1:
+ /* Antenna two */
+ pAd->ate.TxAntennaSel = 2;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
+ return FALSE;
+ }
+ break;/* case BBP_R1 */
+
+ case BBP_R3:
+ /* Need to sync. rx configuration with legacy ATE. */
+ tmp = (bbp_data & ((1 << 1) | (1 << 0))/* 0x03 */);
+ switch(tmp)
+ {
+ /* The BBP R3 bit[1:0] = 3 :: All ADCs will be used by QA. */
+ case 3:
+ /* All */
+ pAd->ate.RxAntennaSel = 0;
+ break;
+ /* The BBP R3 bit[1:0] = 0 :: ADC 0 will be used by QA, */
+ /* unless the BBP R3 bit[4:3] = 2 */
+ case 0:
+ /* Antenna one */
+ pAd->ate.RxAntennaSel = 1;
+ tmp = ((bbp_data & ((1 << 4) | (1 << 3))/* 0x03 */) >> 3);
+ if (tmp == 2)// 3R
+ {
+ /* Default : All ADCs will be used by QA */
+ pAd->ate.RxAntennaSel = 0;
+ }
+ break;
+ /* The BBP R3 bit[1:0] = 1 :: ADC 1 will be used by QA. */
+ case 1:
+ /* Antenna two */
+ pAd->ate.RxAntennaSel = 2;
+ break;
+ /* The BBP R3 bit[1:0] = 2 :: ADC 2 will be used by QA. */
+ case 2:
+ /* Antenna three */
+ pAd->ate.RxAntennaSel = 3;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("%s -- Impossible! : return FALSE; \n", __FUNCTION__));
+ return FALSE;
+ }
+ break;/* case BBP_R3 */
+
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("%s -- Sth. wrong! : return FALSE; \n", __FUNCTION__));
+ return FALSE;
+
+ }
+ return TRUE;
+}
+
+static VOID memcpy_exl(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+ ULONG i, Value = 0;
+ ULONG *pDst, *pSrc;
+ UCHAR *p8;
+
+ p8 = src;
+ pDst = (ULONG *) dst;
+ pSrc = (ULONG *) src;
+
+ for (i = 0 ; i < (len/4); i++)
+ {
+ /* For alignment issue, we need a variable "Value". */
+ memmove(&Value, pSrc, 4);
+ Value = htonl(Value);
+ memmove(pDst, &Value, 4);
+ pDst++;
+ pSrc++;
+ }
+ if ((len % 4) != 0)
+ {
+ /* wish that it will never reach here */
+ memmove(&Value, pSrc, (len % 4));
+ Value = htonl(Value);
+ memmove(pDst, &Value, (len % 4));
+ }
+}
+
+static VOID memcpy_exs(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, ULONG len)
+{
+ ULONG i;
+ UCHAR *pDst, *pSrc;
+
+ pDst = dst;
+ pSrc = src;
+
+ for (i = 0; i < (len/2); i++)
+ {
+ memmove(pDst, pSrc, 2);
+ *((USHORT *)pDst) = htons(*((USHORT *)pDst));
+ pDst+=2;
+ pSrc+=2;
+ }
+
+ if ((len % 2) != 0)
+ {
+ memmove(pDst, pSrc, 1);
+ }
+}
+
+static VOID RTMP_IO_READ_BULK(PRTMP_ADAPTER pAd, UCHAR *dst, UCHAR *src, UINT32 len)
+{
+ UINT32 i, Value;
+ UINT32 *pDst, *pSrc;
+
+ pDst = (UINT32 *) dst;
+ pSrc = (UINT32 *) src;
+
+ for (i = 0 ; i < (len/4); i++)
+ {
+ RTMP_IO_READ32(pAd, (ULONG)pSrc, &Value);
+ Value = htonl(Value);
+ memmove(pDst, &Value, 4);
+ pDst++;
+ pSrc++;
+ }
+ return;
+}
+
+INT Set_TxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Set_TxStop_Proc\n"));
+
+ if (Set_ATE_Proc(pAd, "TXSTOP"))
+ {
+ return TRUE;
+}
+ else
+ {
+ return FALSE;
+ }
+}
+
+INT Set_RxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ ATEDBGPRINT(RT_DEBUG_TRACE,("Set_RxStop_Proc\n"));
+
+ if (Set_ATE_Proc(pAd, "RXSTOP"))
+ {
+ return TRUE;
+}
+ else
+ {
+ return FALSE;
+ }
+}
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
diff --git a/drivers/staging/rt3070/rt_ate.h b/drivers/staging/rt3070/rt_ate.h
new file mode 100644
index 00000000000..829ebb5f723
--- /dev/null
+++ b/drivers/staging/rt3070/rt_ate.h
@@ -0,0 +1,294 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __ATE_H__
+#define __ATE_H__
+
+#ifndef UCOS
+#define ate_print printk
+#define ATEDBGPRINT DBGPRINT
+
+#ifdef RT2870
+#define EEPROM_SIZE 0x400
+#ifdef CONFIG_STA_SUPPORT
+#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+#else // !UCOS //
+#define fATE_LOAD_EEPROM 0x0C43
+#ifdef CONFIG_PRINTK
+extern INT ConsoleResponse(IN PUCHAR buff);
+extern int (*remote_display)(char *);
+extern void puts (const char *s);
+
+/* specificly defined to redirect and show ate-related messages to host. */
+/* Try to define ate_print as a macro. */
+#define ate_print(fmt, args...) \
+do{ int (*org_remote_display)(char *) = NULL; \
+ org_remote_display = remote_display;\
+ /* Save original "remote_display" */\
+ remote_display = (int (*)(char *))ConsoleResponse; \
+ printk(fmt, ## args); \
+ /* Restore the remote_display function pointer */ \
+ remote_display = org_remote_display; }while(0)
+
+#define ATEDBGPRINT(Level, Fmt) \
+{ \
+ if ((Level) <= RTDebugLevel) \
+ { \
+ ate_print Fmt; \
+ } \
+}
+#endif // CONFIG_PRINTK //
+#endif // !UCOS //
+
+#define ATE_ON(_p) (((_p)->ate.Mode) != ATE_STOP)
+
+/* RT2880_iNIC will define "RT2860". */
+
+/* RT2880_iNIC will define RT2860. */
+
+#ifdef RT2870
+#define EEPROM_SIZE 0x400
+#ifdef CONFIG_STA_SUPPORT
+#define EEPROM_BIN_FILE_NAME "/etc/Wireless/RT2870STA/e2p.bin"
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT2870 //
+
+#ifdef RT2870
+#define ATE_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV)
+#define ATE_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V)
+
+#define BULK_OUT_LOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_LOCK((pLock), IrqFlags);
+
+#define BULK_OUT_UNLOCK(pLock, IrqFlags) \
+ if(1 /*!(in_interrupt() & 0xffff0000)*/) \
+ RTMP_IRQ_UNLOCK((pLock), IrqFlags);
+
+// Prototypes of completion funuc.
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+#define ATE_RTUSBBulkOutDataPacketComplete(purb, pt_regs) ATE_RTUSBBulkOutDataPacketComplete(purb)
+#endif
+
+VOID ATE_RTUSBBulkOutDataPacketComplete(
+ IN purbb_t purb,
+ OUT struct pt_regs *pt_regs);
+
+VOID ATE_RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId);
+
+VOID ATE_RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT2870 //
+
+#ifdef RT30xx
+#define ATE_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV)
+#define ATE_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V)
+#endif // RT30xx //
+
+
+VOID rt_ee_read_all(
+ IN PRTMP_ADAPTER pAd,
+ OUT USHORT *Data);
+
+
+VOID rt_ee_write_all(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT *Data);
+
+INT Set_ATE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_DA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_SA_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_BSSID_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_CHANNEL_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_POWER0_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_POWER1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_RX_Antenna_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_FREQOFFSET_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_BW_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_LENGTH_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_COUNT_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_MCS_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_MODE_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_TX_GI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
+INT Set_ATE_RX_FER_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Read_RF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF1_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF2_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF3_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Write_RF4_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Load_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Read_E2P_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Show_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ATE_Help_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+VOID ATE_QA_Statistics(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC p28xxRxD,
+ IN PHEADER_802_11 pHeader);
+
+VOID RtmpDoAte(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+VOID BubbleSort(
+ IN INT32 n,
+ IN INT32 a[]);
+
+VOID CalNoiseLevel(
+ IN PRTMP_ADAPTER pAdapter,
+ IN UCHAR channel,
+ OUT INT32 buffer[3][10]);
+
+BOOLEAN SyncTxRxConfig(
+ IN PRTMP_ADAPTER pAdapter,
+ IN USHORT offset,
+ IN UCHAR value);
+
+INT Set_TxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_RxStop_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+VOID ATEAsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ATEAsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ATEDisableAsicProtect(
+ IN PRTMP_ADAPTER pAd);
+
+CHAR ATEConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber);
+
+VOID ATESampleRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN PRXWI_STRUC pRxWI);
+
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPStationStop(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPStationStart(
+ IN PRTMP_ADAPTER pAd);
+#endif // CONFIG_STA_SUPPORT //
+#endif // __ATE_H__ //
diff --git a/drivers/staging/rt3070/rt_config.h b/drivers/staging/rt3070/rt_config.h
new file mode 100644
index 00000000000..9e06417f63d
--- /dev/null
+++ b/drivers/staging/rt3070/rt_config.h
@@ -0,0 +1,121 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rt_config.h
+
+ Abstract:
+ Central header file to maintain all include files for all NDIS
+ miniport driver routines.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+
+*/
+#ifndef __RT_CONFIG_H__
+#define __RT_CONFIG_H__
+
+#include "rtmp_type.h"
+#ifdef UCOS
+#include "includes.h"
+#include <stdio.h>
+#include "rt_ucos.h"
+#endif
+
+#ifdef LINUX
+#include "rt_linux.h"
+#endif
+#include "rtmp_def.h"
+#include "rt28xx.h"
+
+
+#ifdef RT2870
+#include "rt2870.h"
+#endif // RT2870 //
+
+#include "oid.h"
+#include "mlme.h"
+#include "wpa.h"
+#include "md5.h"
+#include "rtmp.h"
+#include "ap.h"
+#include "dfs.h"
+#include "chlist.h"
+#include "spectrum.h"
+#ifdef MLME_EX
+#include "mlme_ex_def.h"
+#include "mlme_ex.h"
+#endif // MLME_EX //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef LEAP_SUPPORT
+#include "leap.h"
+#endif // LEAP_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef BLOCK_NET_IF
+#include "netif_block.h"
+#endif // BLOCK_NET_IF //
+
+#ifdef IGMP_SNOOP_SUPPORT
+#include "igmp_snoop.h"
+#endif // IGMP_SNOOP_SUPPORT //
+
+#ifdef RALINK_ATE
+#include "rt_ate.h"
+#endif // RALINK_ATE //
+
+
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifndef WPA_SUPPLICANT_SUPPORT
+#error "Build for being controlled by NetworkManager or wext, please set HAS_WPA_SUPPLICANT=y and HAS_NATIVE_WPA_SUPPLICANT_SUPPORT=y"
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef IKANOS_VX_1X0
+#include "vr_ikans.h"
+#endif // IKANOS_VX_1X0 //
+
+#endif // __RT_CONFIG_H__
+
diff --git a/drivers/staging/rt3070/rt_linux.c b/drivers/staging/rt3070/rt_linux.c
new file mode 100644
index 00000000000..bf3385365da
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.c
@@ -0,0 +1,1063 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+ULONG RTDebugLevel = RT_DEBUG_ERROR;
+
+BUILD_TIMER_FUNCTION(MlmePeriodicExec);
+//BUILD_TIMER_FUNCTION(MlmeRssiReportExec);
+BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+BUILD_TIMER_FUNCTION(APSDPeriodicExec);
+BUILD_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RT2870
+BUILD_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+BUILD_TIMER_FUNCTION(BeaconTimeout);
+BUILD_TIMER_FUNCTION(ScanTimeout);
+BUILD_TIMER_FUNCTION(AuthTimeout);
+BUILD_TIMER_FUNCTION(AssocTimeout);
+BUILD_TIMER_FUNCTION(ReassocTimeout);
+BUILD_TIMER_FUNCTION(DisassocTimeout);
+BUILD_TIMER_FUNCTION(LinkDownExec);
+#ifdef LEAP_SUPPORT
+BUILD_TIMER_FUNCTION(LeapAuthTimeout);
+#endif
+BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+#ifdef QOS_DLS_SUPPORT
+BUILD_TIMER_FUNCTION(DlsTimeoutAction);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+
+// for wireless system event message
+char const *pWirelessSysEventText[IW_SYS_EVENT_TYPE_NUM] = {
+ // system status event
+ "had associated successfully", /* IW_ASSOC_EVENT_FLAG */
+ "had disassociated", /* IW_DISASSOC_EVENT_FLAG */
+ "had deauthenticated", /* IW_DEAUTH_EVENT_FLAG */
+ "had been aged-out and disassociated", /* IW_AGEOUT_EVENT_FLAG */
+ "occurred CounterMeasures attack", /* IW_COUNTER_MEASURES_EVENT_FLAG */
+ "occurred replay counter different in Key Handshaking", /* IW_REPLAY_COUNTER_DIFF_EVENT_FLAG */
+ "occurred RSNIE different in Key Handshaking", /* IW_RSNIE_DIFF_EVENT_FLAG */
+ "occurred MIC different in Key Handshaking", /* IW_MIC_DIFF_EVENT_FLAG */
+ "occurred ICV error in RX", /* IW_ICV_ERROR_EVENT_FLAG */
+ "occurred MIC error in RX", /* IW_MIC_ERROR_EVENT_FLAG */
+ "Group Key Handshaking timeout", /* IW_GROUP_HS_TIMEOUT_EVENT_FLAG */
+ "Pairwise Key Handshaking timeout", /* IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG */
+ "RSN IE sanity check failure", /* IW_RSNIE_SANITY_FAIL_EVENT_FLAG */
+ "set key done in WPA/WPAPSK", /* IW_SET_KEY_DONE_WPA1_EVENT_FLAG */
+ "set key done in WPA2/WPA2PSK", /* IW_SET_KEY_DONE_WPA2_EVENT_FLAG */
+ "connects with our wireless client", /* IW_STA_LINKUP_EVENT_FLAG */
+ "disconnects with our wireless client", /* IW_STA_LINKDOWN_EVENT_FLAG */
+ "scan completed" /* IW_SCAN_COMPLETED_EVENT_FLAG */
+ "scan terminate!! Busy!! Enqueue fail!!" /* IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG */
+ };
+
+// for wireless IDS_spoof_attack event message
+char const *pWirelessSpoofEventText[IW_SPOOF_EVENT_TYPE_NUM] = {
+ "detected conflict SSID", /* IW_CONFLICT_SSID_EVENT_FLAG */
+ "detected spoofed association response", /* IW_SPOOF_ASSOC_RESP_EVENT_FLAG */
+ "detected spoofed reassociation responses", /* IW_SPOOF_REASSOC_RESP_EVENT_FLAG */
+ "detected spoofed probe response", /* IW_SPOOF_PROBE_RESP_EVENT_FLAG */
+ "detected spoofed beacon", /* IW_SPOOF_BEACON_EVENT_FLAG */
+ "detected spoofed disassociation", /* IW_SPOOF_DISASSOC_EVENT_FLAG */
+ "detected spoofed authentication", /* IW_SPOOF_AUTH_EVENT_FLAG */
+ "detected spoofed deauthentication", /* IW_SPOOF_DEAUTH_EVENT_FLAG */
+ "detected spoofed unknown management frame", /* IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG */
+ "detected replay attack" /* IW_REPLAY_ATTACK_EVENT_FLAG */
+ };
+
+// for wireless IDS_flooding_attack event message
+char const *pWirelessFloodEventText[IW_FLOOD_EVENT_TYPE_NUM] = {
+ "detected authentication flooding", /* IW_FLOOD_AUTH_EVENT_FLAG */
+ "detected association request flooding", /* IW_FLOOD_ASSOC_REQ_EVENT_FLAG */
+ "detected reassociation request flooding", /* IW_FLOOD_REASSOC_REQ_EVENT_FLAG */
+ "detected probe request flooding", /* IW_FLOOD_PROBE_REQ_EVENT_FLAG */
+ "detected disassociation flooding", /* IW_FLOOD_DISASSOC_EVENT_FLAG */
+ "detected deauthentication flooding", /* IW_FLOOD_DEAUTH_EVENT_FLAG */
+ "detected 802.1x eap-request flooding" /* IW_FLOOD_EAP_REQ_EVENT_FLAG */
+ };
+
+
+/* timeout -- ms */
+VOID RTMP_SetPeriodicTimer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout)
+{
+ timeout = ((timeout*HZ) / 1000);
+ pTimer->expires = jiffies + timeout;
+ add_timer(pTimer);
+}
+
+/* convert NdisMInitializeTimer --> RTMP_OS_Init_Timer */
+VOID RTMP_OS_Init_Timer(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN TIMER_FUNCTION function,
+ IN PVOID data)
+{
+ init_timer(pTimer);
+ pTimer->data = (unsigned long)data;
+ pTimer->function = function;
+}
+
+
+VOID RTMP_OS_Add_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout)
+{
+ if (timer_pending(pTimer))
+ return;
+
+ timeout = ((timeout*HZ) / 1000);
+ pTimer->expires = jiffies + timeout;
+ add_timer(pTimer);
+}
+
+VOID RTMP_OS_Mod_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout)
+{
+ timeout = ((timeout*HZ) / 1000);
+ mod_timer(pTimer, jiffies + timeout);
+}
+
+VOID RTMP_OS_Del_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ OUT BOOLEAN *pCancelled)
+{
+ if (timer_pending(pTimer))
+ {
+ *pCancelled = del_timer_sync(pTimer);
+ }
+ else
+ {
+ *pCancelled = TRUE;
+ }
+
+}
+
+VOID RTMP_OS_Release_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_ENTRY pEntry)
+{
+ //RTMPFreeNdisPacket(pAd, (struct sk_buff *)pEntry);
+}
+
+// Unify all delay routine by using udelay
+VOID RTMPusecDelay(
+ IN ULONG usec)
+{
+ ULONG i;
+
+ for (i = 0; i < (usec / 50); i++)
+ udelay(50);
+
+ if (usec % 50)
+ udelay(usec % 50);
+}
+
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time)
+{
+ time->u.LowPart = jiffies;
+}
+
+// pAd MUST allow to be NULL
+NDIS_STATUS os_alloc_mem(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR *mem,
+ IN ULONG size)
+{
+ *mem = (PUCHAR) kmalloc(size, GFP_ATOMIC);
+ if (*mem)
+ return (NDIS_STATUS_SUCCESS);
+ else
+ return (NDIS_STATUS_FAILURE);
+}
+
+// pAd MUST allow to be NULL
+NDIS_STATUS os_free_mem(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mem)
+{
+
+ ASSERT(mem);
+ kfree(mem);
+ return (NDIS_STATUS_SUCCESS);
+}
+
+
+PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length)
+{
+ struct sk_buff *pkt;
+
+ pkt = dev_alloc_skb(Length);
+
+ if (pkt == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("can't allocate frag rx %ld size packet\n",Length));
+ }
+
+ if (pkt)
+ {
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+ }
+
+ return (PNDIS_PACKET) pkt;
+}
+
+
+PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress)
+{
+ struct sk_buff *pkt;
+
+ pkt = dev_alloc_skb(Length);
+
+ if (pkt == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("can't allocate tx %ld size packet\n",Length));
+ }
+
+ if (pkt)
+ {
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+ *VirtualAddress = (PVOID) pkt->data;
+ }
+ else
+ {
+ *VirtualAddress = (PVOID) NULL;
+ }
+
+ return (PNDIS_PACKET) pkt;
+}
+
+
+VOID build_tx_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pFrame,
+ IN ULONG FrameLen)
+{
+
+ struct sk_buff *pTxPkt;
+
+ ASSERT(pPacket);
+ pTxPkt = RTPKT_TO_OSPKT(pPacket);
+
+ NdisMoveMemory(skb_put(pTxPkt, FrameLen), pFrame, FrameLen);
+}
+
+VOID RTMPFreeAdapter(
+ IN PRTMP_ADAPTER pAd)
+{
+ POS_COOKIE os_cookie;
+ int index;
+
+ os_cookie=(POS_COOKIE)pAd->OS_Cookie;
+
+ kfree(pAd->BeaconBuf);
+
+
+ NdisFreeSpinLock(&pAd->MgmtRingLock);
+
+
+ for (index =0 ; index < NUM_OF_TX_RING; index++)
+ {
+ NdisFreeSpinLock(&pAd->TxSwQueueLock[index]);
+ NdisFreeSpinLock(&pAd->DeQueueLock[index]);
+ pAd->DeQueueRunning[index] = FALSE;
+ }
+
+ NdisFreeSpinLock(&pAd->irq_lock);
+
+
+ vfree(pAd); // pci_free_consistent(os_cookie->pci_dev,sizeof(RTMP_ADAPTER),pAd,os_cookie->pAd_pa);
+ kfree(os_cookie);
+}
+
+BOOLEAN OS_Need_Clone_Packet(void)
+{
+ return (FALSE);
+}
+
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ clone an input NDIS PACKET to another one. The new internally created NDIS PACKET
+ must have only one NDIS BUFFER
+ return - byte copied. 0 means can't create NDIS PACKET
+ NOTE: internally created NDIS_PACKET should be destroyed by RTMPFreeNdisPacket
+
+ Arguments:
+ pAd Pointer to our adapter
+ pInsAMSDUHdr EWC A-MSDU format has extra 14-bytes header. if TRUE, insert this 14-byte hdr in front of MSDU.
+ *pSrcTotalLen return total packet length. This lenght is calculated with 802.3 format packet.
+
+ Return Value:
+ NDIS_STATUS_SUCCESS
+ NDIS_STATUS_FAILURE
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS RTMPCloneNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN pInsAMSDUHdr,
+ IN PNDIS_PACKET pInPacket,
+ OUT PNDIS_PACKET *ppOutPacket)
+{
+
+ struct sk_buff *pkt;
+
+ ASSERT(pInPacket);
+ ASSERT(ppOutPacket);
+
+ // 1. Allocate a packet
+ pkt = dev_alloc_skb(2048);
+
+ if (pkt == NULL)
+ {
+ return NDIS_STATUS_FAILURE;
+ }
+
+ skb_put(pkt, GET_OS_PKT_LEN(pInPacket));
+ NdisMoveMemory(pkt->data, GET_OS_PKT_DATAPTR(pInPacket), GET_OS_PKT_LEN(pInPacket));
+ *ppOutPacket = OSPKT_TO_RTPKT(pkt);
+
+
+ RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS);
+
+ printk("###Clone###\n");
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+// the allocated NDIS PACKET must be freed via RTMPFreeNdisPacket()
+NDIS_STATUS RTMPAllocateNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ OUT PNDIS_PACKET *ppPacket,
+ IN PUCHAR pHeader,
+ IN UINT HeaderLen,
+ IN PUCHAR pData,
+ IN UINT DataLen)
+{
+ PNDIS_PACKET pPacket;
+ ASSERT(pData);
+ ASSERT(DataLen);
+
+ // 1. Allocate a packet
+ pPacket = (PNDIS_PACKET *) dev_alloc_skb(HeaderLen + DataLen + TXPADDING_SIZE);
+ if (pPacket == NULL)
+ {
+ *ppPacket = NULL;
+#ifdef DEBUG
+ printk("RTMPAllocateNdisPacket Fail\n\n");
+#endif
+ return NDIS_STATUS_FAILURE;
+ }
+
+ // 2. clone the frame content
+ if (HeaderLen > 0)
+ NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket), pHeader, HeaderLen);
+ if (DataLen > 0)
+ NdisMoveMemory(GET_OS_PKT_DATAPTR(pPacket) + HeaderLen, pData, DataLen);
+
+ // 3. update length of packet
+ skb_put(GET_OS_PKT_TYPE(pPacket), HeaderLen+DataLen);
+
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+// printk("%s : pPacket = %p, len = %d\n", __FUNCTION__, pPacket, GET_OS_PKT_LEN(pPacket));
+ *ppPacket = pPacket;
+ return NDIS_STATUS_SUCCESS;
+}
+
+/*
+ ========================================================================
+ Description:
+ This routine frees a miniport internally allocated NDIS_PACKET and its
+ corresponding NDIS_BUFFER and allocated memory.
+ ========================================================================
+*/
+VOID RTMPFreeNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ dev_kfree_skb_any(RTPKT_TO_OSPKT(pPacket));
+}
+
+
+// IRQL = DISPATCH_LEVEL
+// NOTE: we do have an assumption here, that Byte0 and Byte1 always reasid at the same
+// scatter gather buffer
+NDIS_STATUS Sniff2BytesFromNdisBuffer(
+ IN PNDIS_BUFFER pFirstBuffer,
+ IN UCHAR DesiredOffset,
+ OUT PUCHAR pByte0,
+ OUT PUCHAR pByte1)
+{
+ *pByte0 = *(PUCHAR)(pFirstBuffer + DesiredOffset);
+ *pByte1 = *(PUCHAR)(pFirstBuffer + DesiredOffset + 1);
+
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+void RTMP_QueryPacketInfo(
+ IN PNDIS_PACKET pPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen)
+{
+ pPacketInfo->BufferCount = 1;
+ pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+ pPacketInfo->PhysicalBufferCount = 1;
+ pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
+
+ *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+ *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
+}
+
+void RTMP_QueryNextPacketInfo(
+ IN PNDIS_PACKET *ppPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen)
+{
+ PNDIS_PACKET pPacket = NULL;
+
+ if (*ppPacket)
+ pPacket = GET_OS_PKT_NEXT(*ppPacket);
+
+ if (pPacket)
+ {
+ pPacketInfo->BufferCount = 1;
+ pPacketInfo->pFirstBuffer = GET_OS_PKT_DATAPTR(pPacket);
+ pPacketInfo->PhysicalBufferCount = 1;
+ pPacketInfo->TotalPacketLength = GET_OS_PKT_LEN(pPacket);
+
+ *pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+ *pSrcBufLen = GET_OS_PKT_LEN(pPacket);
+ *ppPacket = GET_OS_PKT_NEXT(pPacket);
+ }
+ else
+ {
+ pPacketInfo->BufferCount = 0;
+ pPacketInfo->pFirstBuffer = NULL;
+ pPacketInfo->PhysicalBufferCount = 0;
+ pPacketInfo->TotalPacketLength = 0;
+
+ *pSrcBufVA = NULL;
+ *pSrcBufLen = 0;
+ *ppPacket = NULL;
+ }
+}
+
+// not yet support MBSS
+PNET_DEV get_netdev_from_bssid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR FromWhichBSSID)
+{
+ PNET_DEV dev_p = NULL;
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ dev_p = pAd->net_dev;
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ ASSERT(dev_p);
+ return dev_p; /* return one of MBSS */
+}
+
+PNDIS_PACKET DuplicatePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *skb;
+ PNDIS_PACKET pRetPacket = NULL;
+ USHORT DataSize;
+ UCHAR *pData;
+
+ DataSize = (USHORT) GET_OS_PKT_LEN(pPacket);
+ pData = (PUCHAR) GET_OS_PKT_DATAPTR(pPacket);
+
+
+ skb = skb_clone(RTPKT_TO_OSPKT(pPacket), MEM_ALLOC_FLAG);
+ if (skb)
+ {
+ skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pRetPacket = OSPKT_TO_RTPKT(skb);
+ }
+
+ return pRetPacket;
+
+}
+
+PNDIS_PACKET duplicate_pkt(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *skb;
+ PNDIS_PACKET pPacket = NULL;
+
+
+ if ((skb = __dev_alloc_skb(HdrLen + DataSize + 2, MEM_ALLOC_FLAG)) != NULL)
+ {
+ skb_reserve(skb, 2);
+ NdisMoveMemory(skb->tail, pHeader802_3, HdrLen);
+ skb_put(skb, HdrLen);
+ NdisMoveMemory(skb->tail, pData, DataSize);
+ skb_put(skb, DataSize);
+ skb->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pPacket = OSPKT_TO_RTPKT(skb);
+ }
+
+ return pPacket;
+}
+
+
+#define TKIP_TX_MIC_SIZE 8
+PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ struct sk_buff *skb, *newskb;
+
+
+ skb = RTPKT_TO_OSPKT(pPacket);
+ if (skb_tailroom(skb) < TKIP_TX_MIC_SIZE)
+ {
+ // alloc a new skb and copy the packet
+ newskb = skb_copy_expand(skb, skb_headroom(skb), TKIP_TX_MIC_SIZE, GFP_ATOMIC);
+ dev_kfree_skb_any(skb);
+ if (newskb == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Extend Tx.MIC for packet failed!, dropping packet!\n"));
+ return NULL;
+ }
+ skb = newskb;
+ }
+
+ return OSPKT_TO_RTPKT(skb);
+}
+
+
+
+
+PNDIS_PACKET ClonePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize)
+{
+ struct sk_buff *pRxPkt;
+ struct sk_buff *pClonedPkt;
+
+ ASSERT(pPacket);
+ pRxPkt = RTPKT_TO_OSPKT(pPacket);
+
+ // clone the packet
+ pClonedPkt = skb_clone(pRxPkt, MEM_ALLOC_FLAG);
+
+ if (pClonedPkt)
+ {
+ // set the correct dataptr and data len
+ pClonedPkt->dev = pRxPkt->dev;
+ pClonedPkt->data = pData;
+ pClonedPkt->len = DataSize;
+ pClonedPkt->tail = pClonedPkt->data + pClonedPkt->len;
+ ASSERT(DataSize < 1530);
+ }
+ return pClonedPkt;
+}
+
+//
+// change OS packet DataPtr and DataLen
+//
+void update_os_packet_info(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *pOSPkt;
+
+ ASSERT(pRxBlk->pRxPacket);
+ pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+ pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pOSPkt->data = pRxBlk->pData;
+ pOSPkt->len = pRxBlk->DataSize;
+ pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+}
+
+
+void wlan_802_11_to_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN PUCHAR pHeader802_3,
+ IN UCHAR FromWhichBSSID)
+{
+ struct sk_buff *pOSPkt;
+
+ ASSERT(pRxBlk->pRxPacket);
+ ASSERT(pHeader802_3);
+
+ pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+
+ pOSPkt->dev = get_netdev_from_bssid(pAd, FromWhichBSSID);
+ pOSPkt->data = pRxBlk->pData;
+ pOSPkt->len = pRxBlk->DataSize;
+ pOSPkt->tail = pOSPkt->data + pOSPkt->len;
+
+ //
+ // copy 802.3 header
+ //
+ //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisMoveMemory(skb_push(pOSPkt, LENGTH_802_3), pHeader802_3, LENGTH_802_3);
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+
+void announce_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+
+ struct sk_buff *pRxPkt;
+
+ ASSERT(pPacket);
+
+ pRxPkt = RTPKT_TO_OSPKT(pPacket);
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ /* Push up the protocol stack */
+#ifdef IKANOS_VX_1X0
+ IKANOS_DataFrameRx(pAd, pRxPkt->dev, pRxPkt, pRxPkt->len);
+#else
+ pRxPkt->protocol = eth_type_trans(pRxPkt, pRxPkt->dev);
+
+//#ifdef CONFIG_5VT_ENHANCE
+// *(int*)(pRxPkt->cb) = BRIDGE_TAG;
+//#endif
+ netif_rx(pRxPkt);
+#endif // IKANOS_VX_1X0 //
+}
+
+
+PRTMP_SCATTER_GATHER_LIST
+rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg)
+{
+ sg->NumberOfElements = 1;
+ sg->Elements[0].Address = GET_OS_PKT_DATAPTR(pPacket);
+ sg->Elements[0].Length = GET_OS_PKT_LEN(pPacket);
+ return (sg);
+}
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen)
+{
+ unsigned char *pt;
+ int x;
+
+ if (RTDebugLevel < RT_DEBUG_TRACE)
+ return;
+
+ pt = pSrcBufVA;
+ printk("%s: %p, len = %d\n",str, pSrcBufVA, SrcBufLen);
+ for (x=0; x<SrcBufLen; x++)
+ {
+ if (x % 16 == 0)
+ printk("0x%04x : ", x);
+ printk("%02x ", ((unsigned char)pt[x]));
+ if (x%16 == 15) printk("\n");
+ }
+ printk("\n");
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Send log message through wireless event
+
+ Support standard iw_event with IWEVCUSTOM. It is used below.
+
+ iwreq_data.data.flags is used to store event_flag that is defined by user.
+ iwreq_data.data.length is the length of the event log.
+
+ The format of the event log is composed of the entry's MAC address and
+ the desired log message (refer to pWirelessEventText).
+
+ ex: 11:22:33:44:55:66 has associated successfully
+
+ p.s. The requirement of Wireless Extension is v15 or newer.
+
+ ========================================================================
+*/
+VOID RTMPSendWirelessEvent(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Event_flag,
+ IN PUCHAR pAddr,
+ IN UCHAR BssIdx,
+ IN CHAR Rssi)
+{
+#if WIRELESS_EXT >= 15
+
+ union iwreq_data wrqu;
+ PUCHAR pBuf = NULL, pBufPtr = NULL;
+ USHORT event, type, BufLen;
+ UCHAR event_table_len = 0;
+
+ type = Event_flag & 0xFF00;
+ event = Event_flag & 0x00FF;
+
+ switch (type)
+ {
+ case IW_SYS_EVENT_FLAG_START:
+ event_table_len = IW_SYS_EVENT_TYPE_NUM;
+ break;
+
+ case IW_SPOOF_EVENT_FLAG_START:
+ event_table_len = IW_SPOOF_EVENT_TYPE_NUM;
+ break;
+
+ case IW_FLOOD_EVENT_FLAG_START:
+ event_table_len = IW_FLOOD_EVENT_TYPE_NUM;
+ break;
+ }
+
+ if (event_table_len == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The type(%0x02x) is not valid.\n", __FUNCTION__, type));
+ return;
+ }
+
+ if (event >= event_table_len)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The event(%0x02x) is not valid.\n", __FUNCTION__, event));
+ return;
+ }
+
+ //Allocate memory and copy the msg.
+ if((pBuf = kmalloc(IW_CUSTOM_MAX_LEN, GFP_ATOMIC)) != NULL)
+ {
+ //Prepare the payload
+ memset(pBuf, 0, IW_CUSTOM_MAX_LEN);
+
+ pBufPtr = pBuf;
+
+ if (pAddr)
+ pBufPtr += sprintf(pBufPtr, "(RT2860) STA(%02x:%02x:%02x:%02x:%02x:%02x) ", PRINT_MAC(pAddr));
+ else if (BssIdx < MAX_MBSSID_NUM)
+ pBufPtr += sprintf(pBufPtr, "(RT2860) BSS(ra%d) ", BssIdx);
+ else
+ pBufPtr += sprintf(pBufPtr, "(RT2860) ");
+
+ if (type == IW_SYS_EVENT_FLAG_START)
+ pBufPtr += sprintf(pBufPtr, "%s", pWirelessSysEventText[event]);
+ else if (type == IW_SPOOF_EVENT_FLAG_START)
+ pBufPtr += sprintf(pBufPtr, "%s (RSSI=%d)", pWirelessSpoofEventText[event], Rssi);
+ else if (type == IW_FLOOD_EVENT_FLAG_START)
+ pBufPtr += sprintf(pBufPtr, "%s", pWirelessFloodEventText[event]);
+ else
+ pBufPtr += sprintf(pBufPtr, "%s", "unknown event");
+
+ pBufPtr[pBufPtr - pBuf] = '\0';
+ BufLen = pBufPtr - pBuf;
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = Event_flag;
+ wrqu.data.length = BufLen;
+
+ //send wireless event
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, pBuf);
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("%s : %s\n", __FUNCTION__, pBuf));
+
+ kfree(pBuf);
+ }
+ else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Can't allocate memory for wireless event.\n", __FUNCTION__));
+#else
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : The Wireless Extension MUST be v15 or newer.\n", __FUNCTION__));
+#endif /* WIRELESS_EXT >= 15 */
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+void send_monitor_packets(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ struct sk_buff *pOSPkt;
+ wlan_ng_prism2_header *ph;
+ int rate_index = 0;
+ USHORT header_len = 0;
+ UCHAR temp_header[40] = {0};
+
+ u_int32_t ralinkrate[256] = {2,4,11,22, 12,18,24,36,48,72,96, 108, 109, 110, 111, 112, 13, 26, 39, 52,78,104, 117, 130, 26, 52, 78,104, 156, 208, 234, 260, 27, 54,81,108,162, 216, 243, 270, // Last 38
+ 54, 108, 162, 216, 324, 432, 486, 540, 14, 29, 43, 57, 87, 115, 130, 144, 29, 59,87,115, 173, 230,260, 288, 30, 60,90,120,180,240,270,300,60,120,180,240,360,480,540,600, 0,1,2,3,4,5,6,7,8,9,10,
+ 11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80};
+
+
+ ASSERT(pRxBlk->pRxPacket);
+ if (pRxBlk->DataSize < 10)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too small! (%d)\n", __FUNCTION__, pRxBlk->DataSize));
+ goto err_free_sk_buff;
+ }
+
+ if (pRxBlk->DataSize + sizeof(wlan_ng_prism2_header) > RX_BUFFER_AGGRESIZE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Size is too large! (%d)\n", __FUNCTION__, pRxBlk->DataSize + sizeof(wlan_ng_prism2_header)));
+ goto err_free_sk_buff;
+ }
+
+ pOSPkt = RTPKT_TO_OSPKT(pRxBlk->pRxPacket);
+ pOSPkt->dev = get_netdev_from_bssid(pAd, BSS0);
+ if (pRxBlk->pHeader->FC.Type == BTYPE_DATA)
+ {
+ pRxBlk->DataSize -= LENGTH_802_11;
+ if ((pRxBlk->pHeader->FC.ToDs == 1) &&
+ (pRxBlk->pHeader->FC.FrDs == 1))
+ header_len = LENGTH_802_11_WITH_ADDR4;
+ else
+ header_len = LENGTH_802_11;
+
+ // QOS
+ if (pRxBlk->pHeader->FC.SubType & 0x08)
+ {
+ header_len += 2;
+ // Data skip QOS contorl field
+ pRxBlk->DataSize -=2;
+ }
+
+ // Order bit: A-Ralink or HTC+
+ if (pRxBlk->pHeader->FC.Order)
+ {
+ header_len += 4;
+ // Data skip HTC contorl field
+ pRxBlk->DataSize -= 4;
+ }
+
+ // Copy Header
+ if (header_len <= 40)
+ NdisMoveMemory(temp_header, pRxBlk->pData, header_len);
+
+ // skip HW padding
+ if (pRxBlk->RxD.L2PAD)
+ pRxBlk->pData += (header_len + 2);
+ else
+ pRxBlk->pData += header_len;
+ } //end if
+
+
+ if (pRxBlk->DataSize < pOSPkt->len) {
+ skb_trim(pOSPkt,pRxBlk->DataSize);
+ } else {
+ skb_put(pOSPkt,(pRxBlk->DataSize - pOSPkt->len));
+ } //end if
+
+ if ((pRxBlk->pData - pOSPkt->data) > 0) {
+ skb_put(pOSPkt,(pRxBlk->pData - pOSPkt->data));
+ skb_pull(pOSPkt,(pRxBlk->pData - pOSPkt->data));
+ } //end if
+
+ if (skb_headroom(pOSPkt) < (sizeof(wlan_ng_prism2_header)+ header_len)) {
+ if (pskb_expand_head(pOSPkt, (sizeof(wlan_ng_prism2_header) + header_len), 0, GFP_ATOMIC)) {
+ DBGPRINT(RT_DEBUG_ERROR, ("%s : Reallocate header size of sk_buff fail!\n", __FUNCTION__));
+ goto err_free_sk_buff;
+ } //end if
+ } //end if
+
+ if (header_len > 0)
+ NdisMoveMemory(skb_push(pOSPkt, header_len), temp_header, header_len);
+
+ ph = (wlan_ng_prism2_header *) skb_push(pOSPkt, sizeof(wlan_ng_prism2_header));
+ NdisZeroMemory(ph, sizeof(wlan_ng_prism2_header));
+
+ ph->msgcode = DIDmsg_lnxind_wlansniffrm;
+ ph->msglen = sizeof(wlan_ng_prism2_header);
+ strcpy(ph->devname, pAd->net_dev->name);
+
+ ph->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
+ ph->hosttime.status = 0;
+ ph->hosttime.len = 4;
+ ph->hosttime.data = jiffies;
+
+ ph->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
+ ph->mactime.status = 0;
+ ph->mactime.len = 0;
+ ph->mactime.data = 0;
+
+ ph->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
+ ph->istx.status = 0;
+ ph->istx.len = 0;
+ ph->istx.data = 0;
+
+ ph->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
+ ph->channel.status = 0;
+ ph->channel.len = 4;
+
+ ph->channel.data = (u_int32_t)pAd->CommonCfg.Channel;
+
+ ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
+ ph->rssi.status = 0;
+ ph->rssi.len = 4;
+ ph->rssi.data = (u_int32_t)RTMPMaxRssi(pAd, ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI0, RSSI_0), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, RSSI_2));;
+
+ ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
+ ph->signal.status = 0;
+ ph->signal.len = 4;
+ ph->signal.data = 0; //rssi + noise;
+
+ ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
+ ph->noise.status = 0;
+ ph->noise.len = 4;
+ ph->noise.data = 0;
+
+#ifdef DOT11_N_SUPPORT
+ if (pRxBlk->pRxWI->PHYMODE >= MODE_HTMIX)
+ {
+ rate_index = 16 + ((UCHAR)pRxBlk->pRxWI->BW *16) + ((UCHAR)pRxBlk->pRxWI->ShortGI *32) + ((UCHAR)pRxBlk->pRxWI->MCS);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if (pRxBlk->pRxWI->PHYMODE == MODE_OFDM)
+ rate_index = (UCHAR)(pRxBlk->pRxWI->MCS) + 4;
+ else
+ rate_index = (UCHAR)(pRxBlk->pRxWI->MCS);
+ if (rate_index < 0)
+ rate_index = 0;
+ if (rate_index > 255)
+ rate_index = 255;
+
+ ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
+ ph->rate.status = 0;
+ ph->rate.len = 4;
+ ph->rate.data = ralinkrate[rate_index];
+
+ ph->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
+ ph->frmlen.status = 0;
+ ph->frmlen.len = 4;
+ ph->frmlen.data = (u_int32_t)pRxBlk->DataSize;
+
+
+ pOSPkt->pkt_type = PACKET_OTHERHOST;
+ pOSPkt->protocol = eth_type_trans(pOSPkt, pOSPkt->dev);
+ pOSPkt->ip_summed = CHECKSUM_NONE;
+ netif_rx(pOSPkt);
+
+ return;
+
+err_free_sk_buff:
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify)
+{
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ daemonize(pThreadName /*"%s",pAd->net_dev->name*/);
+
+ allow_signal(SIGTERM);
+ allow_signal(SIGKILL);
+ current->flags |= PF_NOFREEZE;
+#else
+ unsigned long flags;
+
+ daemonize();
+ reparent_to_init();
+ strcpy(current->comm, pThreadName);
+
+ siginitsetinv(&current->blocked, sigmask(SIGTERM) | sigmask(SIGKILL));
+
+ /* Allow interception of SIGKILL only
+ * Don't allow other signals to interrupt the transmission */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
+ spin_lock_irqsave(&current->sigmask_lock, flags);
+ flush_signals(current);
+ recalc_sigpending(current);
+ spin_unlock_irqrestore(&current->sigmask_lock, flags);
+#endif
+#endif
+
+ /* signal that we've started the thread */
+ complete(pNotify);
+
+}
+
+void RTMP_IndicateMediaState(
+ IN PRTMP_ADAPTER pAd)
+{
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ else
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ }
+}
+
diff --git a/drivers/staging/rt3070/rt_linux.h b/drivers/staging/rt3070/rt_linux.h
new file mode 100644
index 00000000000..0540d02da79
--- /dev/null
+++ b/drivers/staging/rt3070/rt_linux.h
@@ -0,0 +1,887 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+/***********************************************************************/
+/* */
+/* Program: rt_linux.c */
+/* Created: 4/21/2006 1:17:38 PM */
+/* Author: Wu Xi-Kun */
+/* Comments: `description` */
+/* */
+/*---------------------------------------------------------------------*/
+/* */
+/* History: */
+/* Revision 1.1 4/21/2006 1:17:38 PM xsikun */
+/* Initial revision */
+/* */
+/***********************************************************************/
+
+#include "rtmp_type.h"
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/ethtool.h>
+#include <linux/wireless.h>
+#include <linux/proc_fs.h>
+#include <linux/delay.h>
+#include <linux/if_arp.h>
+#include <linux/ctype.h>
+#include <linux/vmalloc.h>
+
+
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+// load firmware
+#define __KERNEL_SYSCALLS__
+#include <linux/unistd.h>
+#include <asm/uaccess.h>
+
+
+#define MEM_ALLOC_FLAG (GFP_ATOMIC) //(GFP_DMA | GFP_ATOMIC)
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+//#define CONFIG_CKIP_SUPPORT
+
+#undef __inline
+#define __inline static inline
+
+typedef int (*HARD_START_XMIT_FUNC)(struct sk_buff *skb, struct net_device *net_dev);
+
+// add by kathy
+
+#ifdef CONFIG_STA_SUPPORT
+
+#ifdef RT2870
+#define STA_PROFILE_PATH "/etc/Wireless/RT2870STA/RT2870STA.dat"
+#define STA_RT2870_IMAGE_FILE_NAME "/etc/Wireless/RT2870STA/rt2870.bin"
+#define STA_NIC_DEVICE_NAME "RT2870STA"
+#define STA_DRIVER_VERSION "2.0.1.0"
+#ifdef MULTIPLE_CARD_SUPPORT
+#define CARD_INFO_PATH "/etc/Wireless/RT2870STA/RT2870STACard.dat"
+#endif // MULTIPLE_CARD_SUPPORT //
+#endif // RT2870 //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+
+#define RTMP_TIME_AFTER(a,b) \
+ (typecheck(unsigned long, (unsigned long)a) && \
+ typecheck(unsigned long, (unsigned long)b) && \
+ ((long)(b) - (long)(a) < 0))
+
+#define RTMP_TIME_AFTER_EQ(a,b) \
+ (typecheck(unsigned long, (unsigned long)a) && \
+ typecheck(unsigned long, (unsigned long)b) && \
+ ((long)(a) - (long)(b) >= 0))
+#define RTMP_TIME_BEFORE(a,b) RTMP_TIME_AFTER_EQ(b,a)
+#else
+#define RTMP_TIME_AFTER(a,b) time_after(a, b)
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#define RT_MOD_INC_USE_COUNT() \
+ if (!try_module_get(THIS_MODULE)) \
+ { \
+ DBGPRINT(RT_DEBUG_ERROR, ("%s: cannot reserve module\n", __FUNCTION__)); \
+ return -1; \
+ }
+
+#define RT_MOD_DEC_USE_COUNT() module_put(THIS_MODULE);
+#else
+#define RT_MOD_INC_USE_COUNT() MOD_INC_USE_COUNT;
+#define RT_MOD_DEC_USE_COUNT() MOD_DEC_USE_COUNT;
+#endif
+
+#define OS_HZ HZ
+
+#define ETH_LENGTH_OF_ADDRESS 6
+
+#define IN
+#define OUT
+
+#define NDIS_STATUS INT
+#define NDIS_STATUS_SUCCESS 0x00
+#define NDIS_STATUS_FAILURE 0x01
+#define NDIS_STATUS_INVALID_DATA 0x02
+#define NDIS_STATUS_RESOURCES 0x03
+
+#define MIN_NET_DEVICE_FOR_AID 0x00 //0x00~0x3f
+#define MIN_NET_DEVICE_FOR_MBSSID 0x00 //0x00,0x10,0x20,0x30
+#define MIN_NET_DEVICE_FOR_WDS 0x10 //0x40,0x50,0x60,0x70
+#define MIN_NET_DEVICE_FOR_APCLI 0x20
+#define MIN_NET_DEVICE_FOR_MESH 0x30
+#ifdef CONFIG_STA_SUPPORT
+#define MIN_NET_DEVICE_FOR_DLS 0x40
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define NDIS_PACKET_TYPE_DIRECTED 0
+#define NDIS_PACKET_TYPE_MULTICAST 1
+#define NDIS_PACKET_TYPE_BROADCAST 2
+#define NDIS_PACKET_TYPE_ALL_MULTICAST 3
+#endif // CONFIG_STA_SUPPORT //
+
+struct os_lock {
+ spinlock_t lock;
+ unsigned long flags;
+};
+
+
+struct os_cookie {
+
+#ifdef RT2870
+ struct usb_device *pUsb_Dev;
+
+ struct pid * MLMEThr_pid;
+ struct pid * RTUSBCmdThr_pid;
+ struct pid * TimerQThr_pid;
+#endif // RT2870 //
+
+ struct tasklet_struct rx_done_task;
+ struct tasklet_struct mgmt_dma_done_task;
+ struct tasklet_struct ac0_dma_done_task;
+ struct tasklet_struct ac1_dma_done_task;
+ struct tasklet_struct ac2_dma_done_task;
+ struct tasklet_struct ac3_dma_done_task;
+ struct tasklet_struct hcca_dma_done_task;
+ struct tasklet_struct tbtt_task;
+#ifdef RT2870
+ struct tasklet_struct null_frame_complete_task;
+ struct tasklet_struct rts_frame_complete_task;
+ struct tasklet_struct pspoll_frame_complete_task;
+#endif // RT2870 //
+
+
+ unsigned long apd_pid; //802.1x daemon pid
+ INT ioctl_if_type;
+ INT ioctl_if;
+};
+
+typedef struct _VIRTUAL_ADAPTER
+{
+ struct net_device *RtmpDev;
+ struct net_device *VirtualDev;
+} VIRTUAL_ADAPTER, PVIRTUAL_ADAPTER;
+
+#undef ASSERT
+#define ASSERT(x) \
+{ \
+ if (!(x)) \
+ { \
+ printk(KERN_WARNING __FILE__ ":%d assert " #x "failed\n", __LINE__); \
+ } \
+}
+
+typedef struct os_cookie * POS_COOKIE;
+typedef struct pci_dev * PPCI_DEV;
+typedef struct net_device * PNET_DEV;
+typedef void * PNDIS_PACKET;
+typedef char NDIS_PACKET;
+typedef PNDIS_PACKET * PPNDIS_PACKET;
+typedef dma_addr_t NDIS_PHYSICAL_ADDRESS;
+typedef dma_addr_t * PNDIS_PHYSICAL_ADDRESS;
+//typedef struct timer_list RALINK_TIMER_STRUCT;
+//typedef struct timer_list * PRALINK_TIMER_STRUCT;
+//typedef struct os_lock NDIS_SPIN_LOCK;
+typedef spinlock_t NDIS_SPIN_LOCK;
+typedef struct timer_list NDIS_MINIPORT_TIMER;
+typedef void * NDIS_HANDLE;
+typedef char * PNDIS_BUFFER;
+
+
+
+void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen);
+
+dma_addr_t linux_pci_map_single(void *handle, void *ptr, size_t size, int sd_idx, int direction);
+void linux_pci_unmap_single(void *handle, dma_addr_t dma_addr, size_t size, int direction);
+
+
+////////////////////////////////////////
+// MOVE TO rtmp.h ?
+/////////////////////////////////////////
+#define PKTSRC_NDIS 0x7f
+#define PKTSRC_DRIVER 0x0f
+#define PRINT_MAC(addr) \
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]
+
+
+#define RT2860_PCI_DEVICE_ID 0x0601
+
+#ifdef RT2870
+#define PCI_MAP_SINGLE(_handle, _ptr, _size, _dir) (ULONG)0
+
+#define PCI_UNMAP_SINGLE(_handle, _ptr, _size, _dir)
+#endif // RT2870 //
+
+
+#define BEACON_FRAME_DMA_CACHE_WBACK(_ptr, _size) \
+ dma_cache_wback(_ptr, _size)
+
+
+//////////////////////////////////////////
+//
+//////////////////////////////////////////
+
+
+#define NdisMIndicateStatus(_w, _x, _y, _z)
+
+
+typedef struct timer_list RTMP_OS_TIMER;
+
+#ifdef RT2870
+/* ----------------- Timer Related MARCO ---------------*/
+// In RT2870, we have a lot of timer functions and will read/write register, it's
+// not allowed in Linux USB sub-system to do it ( because of sleep issue when submit
+// to ctrl pipe). So we need a wrapper function to take care it.
+
+typedef VOID (*RT2870_TIMER_HANDLE)(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif // RT2870 //
+
+
+typedef struct _RALINK_TIMER_STRUCT {
+ RTMP_OS_TIMER TimerObj; // Ndis Timer object
+ BOOLEAN Valid; // Set to True when call RTMPInitTimer
+ BOOLEAN State; // True if timer cancelled
+ BOOLEAN PeriodicType; // True if timer is periodic timer
+ BOOLEAN Repeat; // True if periodic timer
+ ULONG TimerValue; // Timer value in milliseconds
+ ULONG cookie; // os specific object
+#ifdef RT2870
+ RT2870_TIMER_HANDLE handle;
+ void *pAd;
+#endif // RT2870 //
+} RALINK_TIMER_STRUCT, *PRALINK_TIMER_STRUCT;
+
+
+#ifdef RT2870
+
+typedef enum _RT2870_KERNEL_THREAD_STATUS_
+{
+ RT2870_THREAD_UNKNOWN = 0,
+ RT2870_THREAD_INITED = 1,
+ RT2870_THREAD_RUNNING = 2,
+ RT2870_THREAD_STOPED = 4,
+}RT2870_KERNEL_THREAD_STATUS;
+
+#define RT2870_THREAD_CAN_DO_INSERT (RT2870_THREAD_INITED |RT2870_THREAD_RUNNING)
+
+typedef struct _RT2870_TIMER_ENTRY_
+{
+ RALINK_TIMER_STRUCT *pRaTimer;
+ struct _RT2870_TIMER_ENTRY_ *pNext;
+}RT2870_TIMER_ENTRY;
+
+
+#define TIMER_QUEUE_SIZE_MAX 128
+typedef struct _RT2870_TIMER_QUEUE_
+{
+ unsigned int status;
+ //wait_queue_head_t timerWaitQ;
+ //atomic_t count;
+ UCHAR *pTimerQPoll;
+ RT2870_TIMER_ENTRY *pQPollFreeList;
+ RT2870_TIMER_ENTRY *pQHead;
+ RT2870_TIMER_ENTRY *pQTail;
+}RT2870_TIMER_QUEUE;
+#endif // RT2870 //
+
+
+//#define DBG 1
+
+//
+// MACRO for debugging information
+//
+
+#ifdef DBG
+extern ULONG RTDebugLevel;
+
+#define DBGPRINT_RAW(Level, Fmt) \
+{ \
+ if (Level <= RTDebugLevel) \
+ { \
+ printk Fmt; \
+ } \
+}
+
+#define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt)
+
+
+#define DBGPRINT_ERR(Fmt) \
+{ \
+ printk("ERROR!!! "); \
+ printk Fmt; \
+}
+
+#define DBGPRINT_S(Status, Fmt) \
+{ \
+ printk Fmt; \
+}
+
+
+#else
+#define DBGPRINT(Level, Fmt)
+#define DBGPRINT_RAW(Level, Fmt)
+#define DBGPRINT_S(Status, Fmt)
+#define DBGPRINT_ERR(Fmt)
+#endif
+
+
+//
+// spin_lock enhanced for Nested spin lock
+//
+#define NdisAllocateSpinLock(__lock) \
+{ \
+ spin_lock_init((spinlock_t *)(__lock)); \
+}
+
+#define NdisFreeSpinLock(lock) \
+{ \
+}
+
+
+#define RTMP_SEM_LOCK(__lock) \
+{ \
+ spin_lock_bh((spinlock_t *)(__lock)); \
+}
+
+#define RTMP_SEM_UNLOCK(__lock) \
+{ \
+ spin_unlock_bh((spinlock_t *)(__lock)); \
+}
+
+// sample, use semaphore lock to replace IRQ lock, 2007/11/15
+#define RTMP_IRQ_LOCK(__lock, __irqflags) \
+{ \
+ __irqflags = 0; \
+ spin_lock_bh((spinlock_t *)(__lock)); \
+ pAd->irq_disabled |= 1; \
+}
+
+#define RTMP_IRQ_UNLOCK(__lock, __irqflag) \
+{ \
+ pAd->irq_disabled &= 0; \
+ spin_unlock_bh((spinlock_t *)(__lock)); \
+}
+
+#define RTMP_INT_LOCK(__lock, __irqflags) \
+{ \
+ spin_lock_irqsave((spinlock_t *)__lock, __irqflags); \
+}
+
+#define RTMP_INT_UNLOCK(__lock, __irqflag) \
+{ \
+ spin_unlock_irqrestore((spinlock_t *)(__lock), ((unsigned long)__irqflag)); \
+}
+
+#ifdef RT2870
+#define RTMP_IO_READ32(_A, _R, _pV) \
+ RTUSBReadMACRegister(_A, _R, _pV)
+
+#define RTMP_IO_READ8(_A, _R, _pV) \
+{ \
+}
+
+#define RTMP_IO_WRITE32(_A, _R, _V) \
+ RTUSBWriteMACRegister(_A, _R, _V)
+
+
+#define RTMP_IO_WRITE8(_A, _R, _V) \
+{ \
+ USHORT _Val = _V; \
+ RTUSBSingleWrite(_A, _R, _Val); \
+}
+
+
+#define RTMP_IO_WRITE16(_A, _R, _V) \
+{ \
+ RTUSBSingleWrite(_A, _R, _V); \
+}
+#endif // RT2870 //
+
+#ifndef wait_event_interruptible_timeout
+#define __wait_event_interruptible_timeout(wq, condition, ret) \
+do { \
+ wait_queue_t __wait; \
+ init_waitqueue_entry(&__wait, current); \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ set_current_state(TASK_INTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ if (!signal_pending(current)) { \
+ ret = schedule_timeout(ret); \
+ if (!ret) \
+ break; \
+ continue; \
+ } \
+ ret = -ERESTARTSYS; \
+ break; \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event_interruptible_timeout(wq, condition, timeout) \
+({ \
+ long __ret = timeout; \
+ if (!(condition)) \
+ __wait_event_interruptible_timeout(wq, condition, __ret); \
+ __ret; \
+})
+#endif
+#define ONE_TICK 1
+#define OS_WAIT(_time) \
+{ int _i; \
+ long _loop = ((_time)/(1000/OS_HZ)) > 0 ? ((_time)/(1000/OS_HZ)) : 1;\
+ wait_queue_head_t _wait; \
+ init_waitqueue_head(&_wait); \
+ for (_i=0; _i<(_loop); _i++) \
+ wait_event_interruptible_timeout(_wait, 0, ONE_TICK); }
+
+
+/* Modified by Wu Xi-Kun 4/21/2006 */
+typedef void (*TIMER_FUNCTION)(unsigned long);
+
+#define COPY_MAC_ADDR(Addr1, Addr2) memcpy((Addr1), (Addr2), MAC_ADDR_LEN)
+
+#define MlmeAllocateMemory(_pAd, _ppVA) os_alloc_mem(_pAd, _ppVA, MGMT_DMA_BUFFER_SIZE)
+#define MlmeFreeMemory(_pAd, _pVA) os_free_mem(_pAd, _pVA)
+
+
+#ifdef RT2870
+#define BUILD_TIMER_FUNCTION(_func) \
+void linux_##_func(unsigned long data) \
+{ \
+ PRALINK_TIMER_STRUCT _pTimer = (PRALINK_TIMER_STRUCT)data; \
+ RT2870_TIMER_ENTRY *_pQNode; \
+ RTMP_ADAPTER *_pAd; \
+ \
+ _pTimer->handle = _func; \
+ _pAd = (RTMP_ADAPTER *)_pTimer->pAd; \
+ _pQNode = RT2870_TimerQ_Insert(_pAd, _pTimer); \
+ if ((_pQNode == NULL) && (_pAd->TimerQ.status & RT2870_THREAD_CAN_DO_INSERT)) \
+ RTMP_OS_Add_Timer(&_pTimer->TimerObj, HZ); \
+}
+#endif // RT2870 //
+
+
+#define DECLARE_TIMER_FUNCTION(_func) \
+void linux_##_func(unsigned long data)
+
+#define GET_TIMER_FUNCTION(_func) \
+ linux_##_func
+
+DECLARE_TIMER_FUNCTION(MlmePeriodicExec);
+DECLARE_TIMER_FUNCTION(MlmeRssiReportExec);
+DECLARE_TIMER_FUNCTION(AsicRxAntEvalTimeout);
+DECLARE_TIMER_FUNCTION(APSDPeriodicExec);
+DECLARE_TIMER_FUNCTION(AsicRfTuningExec);
+#ifdef RT2870
+DECLARE_TIMER_FUNCTION(BeaconUpdateExec);
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+DECLARE_TIMER_FUNCTION(BeaconTimeout);
+DECLARE_TIMER_FUNCTION(ScanTimeout);
+DECLARE_TIMER_FUNCTION(AuthTimeout);
+DECLARE_TIMER_FUNCTION(AssocTimeout);
+DECLARE_TIMER_FUNCTION(ReassocTimeout);
+DECLARE_TIMER_FUNCTION(DisassocTimeout);
+DECLARE_TIMER_FUNCTION(LinkDownExec);
+#ifdef LEAP_SUPPORT
+DECLARE_TIMER_FUNCTION(LeapAuthTimeout);
+#endif
+DECLARE_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
+DECLARE_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
+DECLARE_TIMER_FUNCTION(PsPollWakeExec);
+DECLARE_TIMER_FUNCTION(RadioOnExec);
+
+#ifdef QOS_DLS_SUPPORT
+DECLARE_TIMER_FUNCTION(DlsTimeoutAction);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+
+void RTMP_GetCurrentSystemTime(LARGE_INTEGER *time);
+
+
+/*
+ * packet helper
+ * - convert internal rt packet to os packet or
+ * os packet to rt packet
+ */
+#define RTPKT_TO_OSPKT(_p) ((struct sk_buff *)(_p))
+#define OSPKT_TO_RTPKT(_p) ((PNDIS_PACKET)(_p))
+
+#define GET_OS_PKT_DATAPTR(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->data)
+
+#define GET_OS_PKT_LEN(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->len)
+
+#define GET_OS_PKT_DATATAIL(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->tail)
+
+#define GET_OS_PKT_HEAD(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->head)
+
+#define GET_OS_PKT_END(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->end)
+
+#define GET_OS_PKT_NETDEV(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->dev)
+
+#define GET_OS_PKT_TYPE(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt))
+
+#define GET_OS_PKT_NEXT(_pkt) \
+ (RTPKT_TO_OSPKT(_pkt)->next)
+
+
+#define OS_NTOHS(_Val) \
+ (ntohs(_Val))
+#define OS_HTONS(_Val) \
+ (htons(_Val))
+#define OS_NTOHL(_Val) \
+ (ntohl(_Val))
+#define OS_HTONL(_Val) \
+ (htonl(_Val))
+
+/* statistics counter */
+#define STATS_INC_RX_PACKETS(_pAd, _dev)
+#define STATS_INC_TX_PACKETS(_pAd, _dev)
+
+#define STATS_INC_RX_BYTESS(_pAd, _dev, len)
+#define STATS_INC_TX_BYTESS(_pAd, _dev, len)
+
+#define STATS_INC_RX_ERRORS(_pAd, _dev)
+#define STATS_INC_TX_ERRORS(_pAd, _dev)
+
+#define STATS_INC_RX_DROPPED(_pAd, _dev)
+#define STATS_INC_TX_DROPPED(_pAd, _dev)
+
+
+#define CB_OFF 10
+
+
+// check DDK NDIS_PACKET data structure and find out only MiniportReservedEx[0..7] can be used by our driver without
+// ambiguity. Fields after pPacket->MiniportReservedEx[8] may be used by other wrapper layer thus crashes the driver
+//
+//#define RTMP_GET_PACKET_MR(_p) (RTPKT_TO_OSPKT(_p))
+
+// User Priority
+#define RTMP_SET_PACKET_UP(_p, _prio) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0] = _prio)
+#define RTMP_GET_PACKET_UP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+0])
+
+// Fragment #
+#define RTMP_SET_PACKET_FRAGMENTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1] = _num)
+#define RTMP_GET_PACKET_FRAGMENTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+1])
+
+// 0x0 ~0x7f: TX to AP's own BSS which has the specified AID. if AID>127, set bit 7 in RTMP_SET_PACKET_EMACTAB too.
+//(this value also as MAC(on-chip WCID) table index)
+// 0x80~0xff: TX to a WDS link. b0~6: WDS index
+#define RTMP_SET_PACKET_WCID(_p, _wdsidx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2] = _wdsidx)
+#define RTMP_GET_PACKET_WCID(_p) ((UCHAR)(RTPKT_TO_OSPKT(_p)->cb[CB_OFF+2]))
+
+// 0xff: PKTSRC_NDIS, others: local TX buffer index. This value affects how to a packet
+#define RTMP_SET_PACKET_SOURCE(_p, _pktsrc) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3] = _pktsrc)
+#define RTMP_GET_PACKET_SOURCE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+3])
+
+// RTS/CTS-to-self protection method
+#define RTMP_SET_PACKET_RTS(_p, _num) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4] = _num)
+#define RTMP_GET_PACKET_RTS(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+4])
+// see RTMP_S(G)ET_PACKET_EMACTAB
+
+// TX rate index
+#define RTMP_SET_PACKET_TXRATE(_p, _rate) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5] = _rate)
+#define RTMP_GET_PACKET_TXRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+5])
+
+// From which Interface
+#define RTMP_SET_PACKET_IF(_p, _ifdx) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6] = _ifdx)
+#define RTMP_GET_PACKET_IF(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+6])
+#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) RTMP_SET_PACKET_IF((_p), (_bss))
+#define RTMP_SET_PACKET_NET_DEVICE_WDS(_p, _bss) RTMP_SET_PACKET_IF((_p), ((_bss) + MIN_NET_DEVICE_FOR_WDS))
+#define RTMP_SET_PACKET_NET_DEVICE_APCLI(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_APCLI))
+#define RTMP_SET_PACKET_NET_DEVICE_MESH(_p, _idx) RTMP_SET_PACKET_IF((_p), ((_idx) + MIN_NET_DEVICE_FOR_MESH))
+#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) RTMP_GET_PACKET_IF((_p))
+#define RTMP_GET_PACKET_NET_DEVICE(_p) RTMP_GET_PACKET_IF((_p))
+
+#define RTMP_SET_PACKET_MOREDATA(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7] = _morebit)
+#define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7])
+
+//#define RTMP_SET_PACKET_NET_DEVICE_MBSSID(_p, _bss) (RTPKT_TO_OSPKT(_p)->cb[8] = _bss)
+//#define RTMP_GET_PACKET_NET_DEVICE_MBSSID(_p) (RTPKT_TO_OSPKT(_p)->cb[8])
+
+//
+// Sepcific Pakcet Type definition
+//
+#define RTMP_PACKET_SPECIFIC_CB_OFFSET 11
+
+#define RTMP_PACKET_SPECIFIC_DHCP 0x01
+#define RTMP_PACKET_SPECIFIC_EAPOL 0x02
+#define RTMP_PACKET_SPECIFIC_IPV4 0x04
+#define RTMP_PACKET_SPECIFIC_WAI 0x08
+#define RTMP_PACKET_SPECIFIC_VLAN 0x10
+#define RTMP_PACKET_SPECIFIC_LLCSNAP 0x20
+
+//Specific
+#define RTMP_SET_PACKET_SPECIFIC(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] = _flg)
+
+//DHCP
+#define RTMP_SET_PACKET_DHCP(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_DHCP); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_DHCP); \
+ }while(0)
+#define RTMP_GET_PACKET_DHCP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_DHCP)
+
+//EAPOL
+#define RTMP_SET_PACKET_EAPOL(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_EAPOL); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_EAPOL); \
+ }while(0)
+#define RTMP_GET_PACKET_EAPOL(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_EAPOL)
+
+//WAI
+#define RTMP_SET_PACKET_WAI(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_WAI); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_WAI); \
+ }while(0)
+#define RTMP_GET_PACKET_WAI(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_WAI)
+
+#define RTMP_GET_PACKET_LOWRATE(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & (RTMP_PACKET_SPECIFIC_EAPOL | RTMP_PACKET_SPECIFIC_DHCP | RTMP_PACKET_SPECIFIC_WAI))
+
+//VLAN
+#define RTMP_SET_PACKET_VLAN(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_VLAN); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_VLAN); \
+ }while(0)
+#define RTMP_GET_PACKET_VLAN(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_VLAN)
+
+//LLC/SNAP
+#define RTMP_SET_PACKET_LLCSNAP(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_LLCSNAP); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_LLCSNAP); \
+ }while(0)
+
+#define RTMP_GET_PACKET_LLCSNAP(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_LLCSNAP)
+
+// IP
+#define RTMP_SET_PACKET_IPV4(_p, _flg) \
+ do{ \
+ if (_flg) \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) |= (RTMP_PACKET_SPECIFIC_IPV4); \
+ else \
+ (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11]) &= (!RTMP_PACKET_SPECIFIC_IPV4); \
+ }while(0)
+
+#define RTMP_GET_PACKET_IPV4(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+11] & RTMP_PACKET_SPECIFIC_IPV4)
+
+// If this flag is set, it indicates that this EAPoL frame MUST be clear.
+#define RTMP_SET_PACKET_CLEAR_EAP_FRAME(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12] = _flg)
+#define RTMP_GET_PACKET_CLEAR_EAP_FRAME(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+12])
+
+#define RTMP_SET_PACKET_5VT(_p, _flg) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22] = _flg)
+#define RTMP_GET_PACKET_5VT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+22])
+
+
+#ifdef INF_AMAZON_SE
+/*Iverson patch for WMM A5-T07 ,WirelessStaToWirelessSta do not bulk out aggregate */
+#define RTMP_SET_PACKET_NOBULKOUT(_p, _morebit) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23] = _morebit)
+#define RTMP_GET_PACKET_NOBULKOUT(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+23])
+#endif // INF_AMAZON_SE //
+
+
+
+#ifdef CONFIG_5VT_ENHANCE
+#define BRIDGE_TAG 0x35564252 // depends on 5VT define in br_input.c
+#endif
+
+
+#define NDIS_SET_PACKET_STATUS(_p, _status)
+
+
+#define GET_SG_LIST_FROM_PACKET(_p, _sc) \
+ rt_get_sg_list_from_packet(_p, _sc)
+
+#define NdisMoveMemory(Destination, Source, Length) memmove(Destination, Source, Length)
+#define NdisZeroMemory(Destination, Length) memset(Destination, 0, Length)
+#define NdisFillMemory(Destination, Length, Fill) memset(Destination, Fill, Length)
+#define NdisEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
+#define RTMPEqualMemory(Source1, Source2, Length) (!memcmp(Source1, Source2, Length))
+
+
+#define RTMP_INC_REF(_A) 0
+#define RTMP_DEC_REF(_A) 0
+#define RTMP_GET_REF(_A) 0
+
+
+
+/*
+ * ULONG
+ * RTMP_GetPhysicalAddressLow(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressLow(PhysicalAddress) (PhysicalAddress)
+
+/*
+ * ULONG
+ * RTMP_GetPhysicalAddressHigh(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress);
+ */
+#define RTMP_GetPhysicalAddressHigh(PhysicalAddress) (0)
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressLow(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ * IN ULONG Value);
+ */
+#define RTMP_SetPhysicalAddressLow(PhysicalAddress, Value) \
+ PhysicalAddress = Value;
+
+/*
+ * VOID
+ * RTMP_SetPhysicalAddressHigh(
+ * IN NDIS_PHYSICAL_ADDRESS PhysicalAddress,
+ * IN ULONG Value);
+ */
+#define RTMP_SetPhysicalAddressHigh(PhysicalAddress, Value)
+
+
+//CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
+#define QUEUE_ENTRY_TO_PACKET(pEntry) \
+ (PNDIS_PACKET)(pEntry)
+
+#define PACKET_TO_QUEUE_ENTRY(pPacket) \
+ (PQUEUE_ENTRY)(pPacket)
+
+
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) \
+((type *)((PCHAR)(address) - offsetof(type, field)))
+#endif
+
+
+#define RELEASE_NDIS_PACKET(_pAd, _pPacket, _Status) \
+{ \
+ RTMPFreeNdisPacket(_pAd, _pPacket); \
+}
+
+
+#define SWITCH_PhyAB(_pAA, _pBB) \
+{ \
+ ULONG AABasePaHigh; \
+ ULONG AABasePaLow; \
+ ULONG BBBasePaHigh; \
+ ULONG BBBasePaLow; \
+ BBBasePaHigh = RTMP_GetPhysicalAddressHigh(_pBB); \
+ BBBasePaLow = RTMP_GetPhysicalAddressLow(_pBB); \
+ AABasePaHigh = RTMP_GetPhysicalAddressHigh(_pAA); \
+ AABasePaLow = RTMP_GetPhysicalAddressLow(_pAA); \
+ RTMP_SetPhysicalAddressHigh(_pAA, BBBasePaHigh); \
+ RTMP_SetPhysicalAddressLow(_pAA, BBBasePaLow); \
+ RTMP_SetPhysicalAddressHigh(_pBB, AABasePaHigh); \
+ RTMP_SetPhysicalAddressLow(_pBB, AABasePaLow); \
+}
+
+
+#define NdisWriteErrorLogEntry(_a, _b, _c, _d)
+#define NdisMAllocateMapRegisters(_a, _b, _c, _d, _e) NDIS_STATUS_SUCCESS
+
+
+#define NdisAcquireSpinLock RTMP_SEM_LOCK
+#define NdisReleaseSpinLock RTMP_SEM_UNLOCK
+
+static inline void NdisGetSystemUpTime(ULONG *time)
+{
+ *time = jiffies;
+}
+
+//pPacket = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReservedEx);
+#define QUEUE_ENTRY_TO_PKT(pEntry) \
+ ((PNDIS_PACKET) (pEntry))
+
+int rt28xx_packet_xmit(struct sk_buff *skb);
+
+
+
+void rtmp_os_thread_init(PUCHAR pThreadName, PVOID pNotify);
+
+
+
diff --git a/drivers/staging/rt3070/rt_main_dev.c b/drivers/staging/rt3070/rt_main_dev.c
new file mode 100644
index 00000000000..c000646286e
--- /dev/null
+++ b/drivers/staging/rt3070/rt_main_dev.c
@@ -0,0 +1,1800 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rt_main_dev.c
+
+ Abstract:
+ Create and register network interface.
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Sample Mar/21/07 Merge RT2870 and RT2860 drivers.
+*/
+
+#include "rt_config.h"
+
+#define FORTY_MHZ_INTOLERANT_INTERVAL (60*1000) // 1 min
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// record whether the card in the card list is used in the card file
+UINT8 MC_CardUsed[MAX_NUM_OF_MULTIPLE_CARD];
+// record used card mac address in the card list
+static UINT8 MC_CardMac[MAX_NUM_OF_MULTIPLE_CARD][6];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+UINT32 CW_MAX_IN_BITS;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+/*---------------------------------------------------------------------*/
+/* Private Variables Used */
+/*---------------------------------------------------------------------*/
+//static RALINK_TIMER_STRUCT PeriodicTimer;
+
+char *mac = ""; // default 00:00:00:00:00:00
+char *hostname = ""; // default CMPC
+#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12)
+MODULE_PARM (mac, "s");
+#else
+module_param (mac, charp, 0);
+#endif
+MODULE_PARM_DESC (mac, "rt28xx: wireless mac addr");
+
+
+/*---------------------------------------------------------------------*/
+/* Prototypes of Functions Used */
+/*---------------------------------------------------------------------*/
+#ifdef DOT11_N_SUPPORT
+extern BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
+extern void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+extern NDIS_STATUS NICLoadRateSwitchingParams(IN PRTMP_ADAPTER pAd);
+
+
+// public function prototype
+INT __devinit rt28xx_probe(IN void *_dev_p, IN void *_dev_id_p,
+ IN UINT argc, OUT PRTMP_ADAPTER *ppAd);
+
+// private function prototype
+static int rt28xx_init(IN struct net_device *net_dev);
+INT rt28xx_send_packets(IN struct sk_buff *skb_p, IN struct net_device *net_dev);
+
+#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
+struct net_device *alloc_netdev(
+ int sizeof_priv,
+ const char *mask,
+ void (*setup)(struct net_device *));
+#endif // LINUX_VERSION_CODE //
+
+static void CfgInitHook(PRTMP_ADAPTER pAd);
+//static BOOLEAN RT28XXAvailRANameAssign(IN CHAR *name_p);
+
+#ifdef CONFIG_STA_SUPPORT
+extern const struct iw_handler_def rt28xx_iw_handler_def;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+extern const struct iw_handler_def rt28xx_ap_iw_handler_def;
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+ IN struct net_device *net_dev);
+#endif
+
+struct net_device_stats *RT28xx_get_ether_stats(
+ IN struct net_device *net_dev);
+
+/*
+========================================================================
+Routine Description:
+ Close raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+ 1. if open fail, kernel will not call the close function.
+ 2. Free memory for
+ (1) Mlme Memory Handler: MlmeHalt()
+ (2) TX & RX: RTMPFreeTxRxRingMemory()
+ (3) BA Reordering: ba_reordering_resource_release()
+========================================================================
+*/
+int MainVirtualIF_close(IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ return 0; // close ok
+
+ netif_carrier_off(pAd->net_dev);
+ netif_stop_queue(pAd->net_dev);
+
+
+
+ VIRTUAL_IF_DOWN(pAd);
+
+ RT_MOD_DEC_USE_COUNT();
+
+ return 0; // close ok
+}
+
+/*
+========================================================================
+Routine Description:
+ Open raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+ 1. if open fail, kernel will not call the close function.
+ 2. Free memory for
+ (1) Mlme Memory Handler: MlmeHalt()
+ (2) TX & RX: RTMPFreeTxRxRingMemory()
+ (3) BA Reordering: ba_reordering_resource_release()
+========================================================================
+*/
+int MainVirtualIF_open(IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ return 0; // close ok
+
+ if (VIRTUAL_IF_UP(pAd) != 0)
+ return -1;
+
+ // increase MODULE use count
+ RT_MOD_INC_USE_COUNT();
+
+ netif_start_queue(net_dev);
+ netif_carrier_on(net_dev);
+ netif_wake_queue(net_dev);
+
+ return 0;
+}
+
+/*
+========================================================================
+Routine Description:
+ Close raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+ 1. if open fail, kernel will not call the close function.
+ 2. Free memory for
+ (1) Mlme Memory Handler: MlmeHalt()
+ (2) TX & RX: RTMPFreeTxRxRingMemory()
+ (3) BA Reordering: ba_reordering_resource_release()
+========================================================================
+*/
+int rt28xx_close(IN PNET_DEV dev)
+{
+ struct net_device * net_dev = (struct net_device *)dev;
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+ BOOLEAN Cancelled = FALSE;
+ UINT32 i = 0;
+#ifdef RT2870
+ DECLARE_WAIT_QUEUE_HEAD(unlink_wakeup);
+ DECLARE_WAITQUEUE(wait, current);
+
+ //RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+#endif // RT2870 //
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("===> rt28xx_close\n"));
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ return 0; // close ok
+
+
+#ifdef WDS_SUPPORT
+ WdsDown(pAd);
+#endif // WDS_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+
+ // If dirver doesn't wake up firmware here,
+ // NICLoadFirmware will hang forever when interface is up again.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ AsicForceWakeup(pAd, TRUE);
+ }
+
+#ifdef QOS_DLS_SUPPORT
+ // send DLS-TEAR_DOWN message,
+ if (pAd->CommonCfg.bDLSCapable)
+ {
+ UCHAR i;
+
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+ RT28XX_MLME_HANDLER(pAd);
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ if (INFRA_ON(pAd) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)))
+ {
+ MLME_DISASSOC_REQ_STRUCT DisReq;
+ MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ COPY_MAC_ADDR(DisReq.Addr, pAd->CommonCfg.Bssid);
+ DisReq.Reason = REASON_DEAUTH_STA_LEAVING;
+
+ MsgElem->Machine = ASSOC_STATE_MACHINE;
+ MsgElem->MsgType = MT2_MLME_DISASSOC_REQ;
+ MsgElem->MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+ NdisMoveMemory(MsgElem->Msg, &DisReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+ // Prevent to connect AP again in STAMlmePeriodicExec
+ pAd->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+ MlmeDisassocReqAction(pAd, MsgElem);
+ kfree(MsgElem);
+
+ RTMPusecDelay(1000);
+ }
+
+#ifdef RT2870
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+#endif // RT2870 //
+
+#ifdef CCX_SUPPORT
+ RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &Cancelled);
+#endif
+
+ RTMPCancelTimer(&pAd->StaCfg.StaQuickResponeForRateUpTimer, &Cancelled);
+ RTMPCancelTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, &Cancelled);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ // send wireless event to wpa_supplicant for infroming interface down.
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_INTERFACE_DOWN;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ MlmeRadioOff(pAd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+ for (i = 0 ; i < NUM_OF_TX_RING; i++)
+ {
+ while (pAd->DeQueueRunning[i] == TRUE)
+ {
+ printk("Waiting for TxQueue[%d] done..........\n", i);
+ RTMPusecDelay(1000);
+ }
+ }
+
+#ifdef RT2870
+ // ensure there are no more active urbs.
+ add_wait_queue (&unlink_wakeup, &wait);
+ pAd->wait = &unlink_wakeup;
+
+ // maybe wait for deletions to finish.
+ i = 0;
+ //while((i < 25) && atomic_read(&pAd->PendingRx) > 0)
+ while(i < 25)
+ {
+ unsigned long IrqFlags;
+
+ RTMP_IRQ_LOCK(&pAd->BulkInLock, IrqFlags);
+ if (pAd->PendingRx == 0)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+ break;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->BulkInLock, IrqFlags);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,9)
+ msleep(UNLINK_TIMEOUT_MS); //Time in millisecond
+#else
+ RTMPusecDelay(UNLINK_TIMEOUT_MS*1000); //Time in microsecond
+#endif
+ i++;
+ }
+ pAd->wait = NULL;
+ remove_wait_queue (&unlink_wakeup, &wait);
+#endif // RT2870 //
+
+ //RTUSBCleanUpMLMEWaitQueue(pAd); /*not used in RT28xx*/
+
+
+#ifdef RT2870
+ // We need clear timerQ related structure before exits of the timer thread.
+ RT2870_TimerQ_Exit(pAd);
+ // Close kernel threads or tasklets
+ RT28xxThreadTerminate(pAd);
+#endif // RT2870 //
+
+ // Stop Mlme state machine
+ MlmeHalt(pAd);
+
+ // Close kernel threads or tasklets
+ kill_thread_task(pAd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ MacTableReset(pAd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+ MeasureReqTabExit(pAd);
+ TpcReqTabExit(pAd);
+
+
+
+
+ // Free Ring or USB buffers
+ RTMPFreeTxRxRingMemory(pAd);
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
+
+#ifdef DOT11_N_SUPPORT
+ // Free BA reorder resource
+ ba_reordering_resource_release(pAd);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef RT2870
+#ifdef INF_AMAZON_SE
+ if (pAd->UsbVendorReqBuf)
+ os_free_mem(pAd, pAd->UsbVendorReqBuf);
+#endif // INF_AMAZON_SE //
+#endif // RT2870 //
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+ return 0; // close ok
+} /* End of rt28xx_close */
+
+static int rt28xx_init(IN struct net_device *net_dev)
+{
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ UINT index;
+ UCHAR TmpPhy;
+// ULONG Value=0;
+ NDIS_STATUS Status;
+// OID_SET_HT_PHYMODE SetHT;
+// WPDMA_GLO_CFG_STRUC GloCfg;
+ UINT32 MacCsr0 = 0;
+ UINT32 MacValue = 0;
+
+#ifdef RT2870
+#ifdef INF_AMAZON_SE
+ init_MUTEX(&(pAd->UsbVendorReq_semaphore));
+ os_alloc_mem(pAd, (PUCHAR)&pAd->UsbVendorReqBuf, MAX_PARAM_BUFFER_SIZE - 1);
+ if (pAd->UsbVendorReqBuf == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Allocate vendor request temp buffer failed!\n"));
+ goto err0;
+ }
+#endif // INF_AMAZON_SE //
+#endif // RT2870 //
+
+#ifdef DOT11_N_SUPPORT
+ // Allocate BA Reordering memory
+ ba_reordering_resource_init(pAd, MAX_REORDERING_MPDU_NUM);
+#endif // DOT11_N_SUPPORT //
+
+ // Make sure MAC gets ready.
+ index = 0;
+ do
+ {
+ RTMP_IO_READ32(pAd, MAC_CSR0, &MacCsr0);
+ pAd->MACVersion = MacCsr0;
+
+ if ((pAd->MACVersion != 0x00) && (pAd->MACVersion != 0xFFFFFFFF))
+ break;
+
+ RTMPusecDelay(10);
+ } while (index++ < 100);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MAC_CSR0 [ Ver:Rev=0x%08x]\n", pAd->MACVersion));
+/*Iverson patch PCIE L1 issue */
+
+ // Disable DMA
+ RT28XXDMADisable(pAd);
+
+
+ // Load 8051 firmware
+ Status = NICLoadFirmware(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", Status));
+ goto err1;
+ }
+
+ NICLoadRateSwitchingParams(pAd);
+
+ // Disable interrupts here which is as soon as possible
+ // This statement should never be true. We might consider to remove it later
+
+ Status = RTMPAllocTxRxRingMemory(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status));
+ goto err1;
+ }
+
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+
+ // initialize MLME
+ //
+
+ Status = MlmeInit(pAd);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status));
+ goto err2;
+ }
+
+ // Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default
+ //
+ UserCfgInit(pAd);
+
+#ifdef RT2870
+ // We need init timerQ related structure before create the timer thread.
+ RT2870_TimerQ_Init(pAd);
+#endif // RT2870 //
+
+ RT28XX_TASK_THREAD_INIT(pAd, Status);
+ if (Status != NDIS_STATUS_SUCCESS)
+ goto err1;
+
+// COPY_MAC_ADDR(pAd->ApCfg.MBSSID[apidx].Bssid, netif->hwaddr);
+// pAd->bForcePrintTX = TRUE;
+
+ CfgInitHook(pAd);
+
+
+#ifdef BLOCK_NET_IF
+ initblockQueueTab(pAd);
+#endif // BLOCK_NET_IF //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisAllocateSpinLock(&pAd->MacTabLock);
+#endif // CONFIG_STA_SUPPORT //
+
+ MeasureReqTabInit(pAd);
+ TpcReqTabInit(pAd);
+
+ //
+ // Init the hardware, we need to init asic before read registry, otherwise mac register will be reset
+ //
+ Status = NICInitializeAdapter(pAd, TRUE);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", Status));
+ if (Status != NDIS_STATUS_SUCCESS)
+ goto err3;
+ }
+
+ // Read parameters from Config File
+ Status = RTMPReadParametersHook(pAd);
+
+ printk("1. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+ if (Status != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT_ERR(("NICReadRegParameters failed, Status[=0x%08x]\n",Status));
+ goto err4;
+ }
+
+#ifdef RT2870
+ pAd->CommonCfg.bMultipleIRP = FALSE;
+
+ if (pAd->CommonCfg.bMultipleIRP)
+ pAd->CommonCfg.NumOfBulkInIRP = RX_RING_SIZE;
+ else
+ pAd->CommonCfg.NumOfBulkInIRP = 1;
+#endif // RT2870 //
+
+
+ //Init Ba Capability parameters.
+// RT28XX_BA_INIT(pAd);
+#ifdef DOT11_N_SUPPORT
+ pAd->CommonCfg.DesiredHtPhy.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+ pAd->CommonCfg.DesiredHtPhy.AmsduEnable = (USHORT)pAd->CommonCfg.BACapability.field.AmsduEnable;
+ pAd->CommonCfg.DesiredHtPhy.AmsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.DesiredHtPhy.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+ // UPdata to HT IE
+ pAd->CommonCfg.HtCapability.HtCapInfo.MimoPs = (USHORT)pAd->CommonCfg.BACapability.field.MMPSmode;
+ pAd->CommonCfg.HtCapability.HtCapInfo.AMsduSize = (USHORT)pAd->CommonCfg.BACapability.field.AmsduSize;
+ pAd->CommonCfg.HtCapability.HtCapParm.MpduDensity = (UCHAR)pAd->CommonCfg.BACapability.field.MpduDensity;
+#endif // DOT11_N_SUPPORT //
+
+ // after reading Registry, we now know if in AP mode or STA mode
+
+ // Load 8051 firmware; crash when FW image not existent
+ // Status = NICLoadFirmware(pAd);
+ // if (Status != NDIS_STATUS_SUCCESS)
+ // break;
+
+ printk("2. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+
+ // We should read EEPROM for all cases. rt2860b
+ NICReadEEPROMParameters(pAd, mac);
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ printk("3. Phy Mode = %d\n", pAd->CommonCfg.PhyMode);
+
+ NICInitAsicFromEEPROM(pAd); //rt2860b
+
+ // Set PHY to appropriate mode
+ TmpPhy = pAd->CommonCfg.PhyMode;
+ pAd->CommonCfg.PhyMode = 0xff;
+ RTMPSetPhyMode(pAd, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+
+ // No valid channels.
+ if (pAd->ChannelListNum == 0)
+ {
+ printk("Wrong configuration. No valid channel found. Check \"ContryCode\" and \"ChannelGeography\" setting.\n");
+ goto err4;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ printk("MCS Set = %02x %02x %02x %02x %02x\n", pAd->CommonCfg.HtCapability.MCSSet[0],
+ pAd->CommonCfg.HtCapability.MCSSet[1], pAd->CommonCfg.HtCapability.MCSSet[2],
+ pAd->CommonCfg.HtCapability.MCSSet[3], pAd->CommonCfg.HtCapability.MCSSet[4]);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef RT30xx
+ //Init RT30xx RFRegisters after read RFIC type from EEPROM
+ NICInitRT30xxRFRegisters(pAd);
+#endif // RT30xx //
+
+// APInitialize(pAd);
+
+#ifdef IKANOS_VX_1X0
+ VR_IKANOS_FP_Init(pAd->ApCfg.BssidNum, pAd->PermanentAddress);
+#endif // IKANOS_VX_1X0 //
+
+ //
+ // Initialize RF register to default value
+ //
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ if (pAd && (Status != NDIS_STATUS_SUCCESS))
+ {
+ //
+ // Undo everything if it failed
+ //
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+// NdisMDeregisterInterrupt(&pAd->Interrupt);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE);
+ }
+// RTMPFreeAdapter(pAd); // we will free it in disconnect()
+ }
+ else if (pAd)
+ {
+ // Microsoft HCT require driver send a disconnect event after driver initialization.
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+// pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_MEDIA_STATE_CHANGE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event B!\n"));
+
+
+#ifdef RT2870
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS);
+
+ //
+ // Support multiple BulkIn IRP,
+ // the value on pAd->CommonCfg.NumOfBulkInIRP may be large than 1.
+ //
+ for(index=0; index<pAd->CommonCfg.NumOfBulkInIRP; index++)
+ {
+ RTUSBBulkReceive(pAd);
+ DBGPRINT(RT_DEBUG_TRACE, ("RTUSBBulkReceive!\n" ));
+ }
+#endif // RT2870 //
+ }// end of else
+
+
+ DBGPRINT_S(Status, ("<==== RTMPInitialize, Status=%x\n", Status));
+
+ return TRUE;
+
+
+err4:
+err3:
+ MlmeHalt(pAd);
+err2:
+ RTMPFreeTxRxRingMemory(pAd);
+// RTMPFreeAdapter(pAd);
+err1:
+
+#ifdef DOT11_N_SUPPORT
+ os_free_mem(pAd, pAd->mpdu_blk_pool.mem); // free BA pool
+#endif // DOT11_N_SUPPORT //
+ RT28XX_IRQ_RELEASE(net_dev);
+
+ // shall not set priv to NULL here because the priv didn't been free yet.
+ //net_dev->ml_priv = 0;
+#ifdef INF_AMAZON_SE
+err0:
+#endif // INF_AMAZON_SE //
+ printk("!!! %s Initialized fail !!!\n", RT28xx_CHIP_NAME);
+ return FALSE;
+} /* End of rt28xx_init */
+
+
+/*
+========================================================================
+Routine Description:
+ Open raxx interface.
+
+Arguments:
+ *net_dev the raxx interface pointer
+
+Return Value:
+ 0 Open OK
+ otherwise Open Fail
+
+Note:
+========================================================================
+*/
+int rt28xx_open(IN PNET_DEV dev)
+{
+ struct net_device * net_dev = (struct net_device *)dev;
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ int retval = 0;
+ POS_COOKIE pObj;
+
+
+ // Sanity check for pAd
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -1;
+ }
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ CW_MAX_IN_BITS = 6;
+ }
+ else if (pAd->OpMode == OPMODE_STA)
+ {
+ CW_MAX_IN_BITS = 10;
+ }
+
+#if WIRELESS_EXT >= 12
+ if (net_dev->ml_priv_flags == INT_MAIN)
+ {
+ if (pAd->OpMode == OPMODE_AP)
+ net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_ap_iw_handler_def;
+ else if (pAd->OpMode == OPMODE_STA)
+ net_dev->wireless_handlers = (struct iw_handler_def *) &rt28xx_iw_handler_def;
+ }
+#endif // WIRELESS_EXT >= 12 //
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ // Init
+ pObj = (POS_COOKIE)pAd->OS_Cookie;
+
+ // reset Adapter flags
+ RTMP_CLEAR_FLAGS(pAd);
+
+ // Request interrupt service routine for PCI device
+ // register the interrupt routine with the os
+ RT28XX_IRQ_REQUEST(net_dev);
+
+
+ // Init BssTab & ChannelInfo tabbles for auto channel select.
+
+
+ // Chip & other init
+ if (rt28xx_init(net_dev) == FALSE)
+ goto err;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ NdisZeroMemory(pAd->StaCfg.dev_name, 16);
+ NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name));
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Set up the Mac address
+ NdisMoveMemory(net_dev->dev_addr, (void *) pAd->CurrentAddress, 6);
+
+ // Init IRQ parameters
+ RT28XX_IRQ_INIT(pAd);
+
+ // Various AP function init
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ // send wireless event to wpa_supplicant for infroming interface down.
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_INTERFACE_UP;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // Enable Interrupt
+ RT28XX_IRQ_ENABLE(pAd);
+
+ // Now Enable RxTx
+ RTMPEnableRxTx(pAd);
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_START_UP);
+
+ {
+ UINT32 reg = 0;
+ RTMP_IO_READ32(pAd, 0x1300, &reg); // clear garbage interrupts
+ printk("0x1300 = %08x\n", reg);
+ }
+
+ {
+// u32 reg;
+// u8 byte;
+// u16 tmp;
+
+// RTMP_IO_READ32(pAd, XIFS_TIME_CFG, &reg);
+
+// tmp = 0x0805;
+// reg = (reg & 0xffff0000) | tmp;
+// RTMP_IO_WRITE32(pAd, XIFS_TIME_CFG, reg);
+
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+ return (retval);
+
+err:
+ return (-1);
+} /* End of rt28xx_open */
+
+
+/* Must not be called for mdev and apdev */
+static NDIS_STATUS rt_ieee80211_if_setup(struct net_device *dev, PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS Status;
+ INT i=0;
+ CHAR slot_name[IFNAMSIZ];
+ struct net_device *device;
+
+
+ //ether_setup(dev);
+ dev->hard_start_xmit = rt28xx_send_packets;
+
+#ifdef IKANOS_VX_1X0
+ dev->hard_start_xmit = IKANOS_DataFramesTx;
+#endif // IKANOS_VX_1X0 //
+
+// dev->set_multicast_list = ieee80211_set_multicast_list;
+// dev->change_mtu = ieee80211_change_mtu;
+#ifdef CONFIG_STA_SUPPORT
+#if WIRELESS_EXT >= 12
+ if (pAd->OpMode == OPMODE_STA)
+ {
+ dev->wireless_handlers = &rt28xx_iw_handler_def;
+ }
+#endif //WIRELESS_EXT >= 12
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+#if WIRELESS_EXT >= 12
+ if (pAd->OpMode == OPMODE_AP)
+ {
+ dev->wireless_handlers = &rt28xx_ap_iw_handler_def;
+ }
+#endif //WIRELESS_EXT >= 12
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+#if WIRELESS_EXT < 21
+ dev->get_wireless_stats = rt28xx_get_wireless_stats;
+#endif
+ dev->get_stats = RT28xx_get_ether_stats;
+ dev->open = MainVirtualIF_open; //rt28xx_open;
+ dev->stop = MainVirtualIF_close; //rt28xx_close;
+// dev->uninit = ieee80211_if_reinit;
+// dev->destructor = ieee80211_if_free;
+ dev->priv_flags = INT_MAIN;
+ dev->do_ioctl = rt28xx_ioctl;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+ dev->validate_addr = NULL;
+#endif
+ // find available device name
+ for (i = 0; i < 8; i++)
+ {
+#ifdef MULTIPLE_CARD_SUPPORT
+ if (pAd->MC_RowID >= 0)
+ sprintf(slot_name, "ra%02d_%d", pAd->MC_RowID, i);
+ else
+#endif // MULTIPLE_CARD_SUPPORT //
+ sprintf(slot_name, "ra%d", i);
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+ device = dev_get_by_name(dev_net(dev), slot_name);
+#else
+ device = dev_get_by_name(dev->nd_net, slot_name);
+#endif
+#else
+ device = dev_get_by_name(slot_name);
+#endif
+ if (device != NULL) dev_put(device);
+#else
+ for (device = dev_base; device != NULL; device = device->next)
+ {
+ if (strncmp(device->name, slot_name, 4) == 0)
+ break;
+ }
+#endif
+ if(device == NULL)
+ break;
+ }
+
+ if(i == 8)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("No available slot name\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+#ifdef MULTIPLE_CARD_SUPPORT
+ if (pAd->MC_RowID >= 0)
+ sprintf(dev->name, "ra%02d_%d", pAd->MC_RowID, i);
+ else
+#endif // MULTIPLE_CARD_SUPPORT //
+ sprintf(dev->name, "ra%d", i);
+ Status = NDIS_STATUS_SUCCESS;
+ }
+
+ return Status;
+
+}
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+/*
+========================================================================
+Routine Description:
+ Get card profile path.
+
+Arguments:
+ pAd
+
+Return Value:
+ TRUE - Find a card profile
+ FALSE - use default profile
+
+Note:
+========================================================================
+*/
+extern INT RTMPGetKeyParameter(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ IN INT destsize,
+ IN PCHAR buffer);
+
+BOOLEAN RTMP_CardInfoRead(
+ IN PRTMP_ADAPTER pAd)
+{
+#define MC_SELECT_CARDID 0 /* use CARD ID (0 ~ 31) to identify different cards */
+#define MC_SELECT_MAC 1 /* use CARD MAC to identify different cards */
+#define MC_SELECT_CARDTYPE 2 /* use CARD type (abgn or bgn) to identify different cards */
+
+#define LETTER_CASE_TRANSLATE(txt_p, card_id) \
+ { UINT32 _len; char _char; \
+ for(_len=0; _len<strlen(card_id); _len++) { \
+ _char = *(txt_p + _len); \
+ if (('A' <= _char) && (_char <= 'Z')) \
+ *(txt_p+_len) = 'a'+(_char-'A'); \
+ } }
+
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ CHAR *buffer, *tmpbuf, card_id_buf[30], RFIC_word[30];
+ BOOLEAN flg_match_ok = FALSE;
+ INT32 card_select_method;
+ INT32 card_free_id, card_nouse_id, card_same_mac_id, card_match_id;
+ EEPROM_ANTENNA_STRUC antenna;
+ USHORT addr01, addr23, addr45;
+ UINT8 mac[6];
+ UINT32 data, card_index;
+ UCHAR *start_ptr;
+
+
+ // init
+ buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if (buffer == NULL)
+ return FALSE;
+
+ tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if(tmpbuf == NULL)
+ {
+ kfree(buffer);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid = current->fsgid = 0;
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ // get RF IC type
+ RTMP_IO_READ32(pAd, E2PROM_CSR, &data);
+
+ if ((data & 0x30) == 0)
+ pAd->EEPROMAddressNum = 6; // 93C46
+ else if ((data & 0x30) == 0x10)
+ pAd->EEPROMAddressNum = 8; // 93C66
+ else
+ pAd->EEPROMAddressNum = 8; // 93C86
+
+ //antenna.word = RTMP_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET);
+ RT28xx_EEPROM_READ16(pAd, EEPROM_NIC1_OFFSET, antenna.word);
+
+ if ((antenna.field.RfIcType == RFIC_2850) ||
+ (antenna.field.RfIcType == RFIC_2750))
+ {
+ /* ABGN card */
+ strcpy(RFIC_word, "abgn");
+ }
+ else
+ {
+ /* BGN card */
+ strcpy(RFIC_word, "bgn");
+ }
+
+ // get MAC address
+ //addr01 = RTMP_EEPROM_READ16(pAd, 0x04);
+ //addr23 = RTMP_EEPROM_READ16(pAd, 0x06);
+ //addr45 = RTMP_EEPROM_READ16(pAd, 0x08);
+ RT28xx_EEPROM_READ16(pAd, 0x04, addr01);
+ RT28xx_EEPROM_READ16(pAd, 0x06, addr23);
+ RT28xx_EEPROM_READ16(pAd, 0x08, addr45);
+
+ mac[0] = (UCHAR)(addr01 & 0xff);
+ mac[1] = (UCHAR)(addr01 >> 8);
+ mac[2] = (UCHAR)(addr23 & 0xff);
+ mac[3] = (UCHAR)(addr23 >> 8);
+ mac[4] = (UCHAR)(addr45 & 0xff);
+ mac[5] = (UCHAR)(addr45 >> 8);
+
+ // open card information file
+ srcf = filp_open(CARD_INFO_PATH, O_RDONLY, 0);
+ if (IS_ERR(srcf))
+ {
+ /* card information file does not exist */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("--> Error %ld opening %s\n", -PTR_ERR(srcf), CARD_INFO_PATH));
+ return FALSE;
+ }
+
+ if (srcf->f_op && srcf->f_op->read)
+ {
+ /* card information file exists so reading the card information */
+ memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+ retval = srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
+ if (retval < 0)
+ {
+ /* read fail */
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("--> Read %s error %d\n", CARD_INFO_PATH, -retval));
+ }
+ else
+ {
+ /* get card selection method */
+ memset(tmpbuf, 0x00, MAX_PARAM_BUFFER_SIZE);
+ card_select_method = MC_SELECT_CARDTYPE; // default
+
+ if (RTMPGetKeyParameter("SELECT", tmpbuf, 256, buffer))
+ {
+ if (strcmp(tmpbuf, "CARDID") == 0)
+ card_select_method = MC_SELECT_CARDID;
+ else if (strcmp(tmpbuf, "MAC") == 0)
+ card_select_method = MC_SELECT_MAC;
+ else if (strcmp(tmpbuf, "CARDTYPE") == 0)
+ card_select_method = MC_SELECT_CARDTYPE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("MC> Card Selection = %d\n", card_select_method));
+
+ // init
+ card_free_id = -1;
+ card_nouse_id = -1;
+ card_same_mac_id = -1;
+ card_match_id = -1;
+
+ // search current card information records
+ for(card_index=0;
+ card_index<MAX_NUM_OF_MULTIPLE_CARD;
+ card_index++)
+ {
+ if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+ (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+ {
+ // MAC is all-0 so the entry is available
+ MC_CardUsed[card_index] = 0;
+
+ if (card_free_id < 0)
+ card_free_id = card_index; // 1st free entry
+ }
+ else
+ {
+ if (memcmp(MC_CardMac[card_index], mac, 6) == 0)
+ {
+ // we find the entry with same MAC
+ if (card_same_mac_id < 0)
+ card_same_mac_id = card_index; // 1st same entry
+ }
+ else
+ {
+ // MAC is not all-0 but used flag == 0
+ if ((MC_CardUsed[card_index] == 0) &&
+ (card_nouse_id < 0))
+ {
+ card_nouse_id = card_index; // 1st available entry
+ }
+ }
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("MC> Free = %d, Same = %d, NOUSE = %d\n",
+ card_free_id, card_same_mac_id, card_nouse_id));
+
+ if ((card_same_mac_id >= 0) &&
+ ((card_select_method == MC_SELECT_CARDID) ||
+ (card_select_method == MC_SELECT_CARDTYPE)))
+ {
+ // same MAC entry is found
+ card_match_id = card_same_mac_id;
+
+ if (card_select_method == MC_SELECT_CARDTYPE)
+ {
+ // for CARDTYPE
+ sprintf(card_id_buf, "%02dCARDTYPE%s",
+ card_match_id, RFIC_word);
+
+ if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
+ {
+ // we found the card ID
+ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+ }
+ }
+ }
+ else
+ {
+ // the card is 1st plug-in, try to find the match card profile
+ switch(card_select_method)
+ {
+ case MC_SELECT_CARDID: // CARDID
+ default:
+ if (card_free_id >= 0)
+ card_match_id = card_free_id;
+ else
+ card_match_id = card_nouse_id;
+ break;
+
+ case MC_SELECT_MAC: // MAC
+ sprintf(card_id_buf, "MAC%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+
+ /* try to find the key word in the card file */
+ if ((start_ptr=rtstrstruncasecmp(buffer, card_id_buf)) != NULL)
+ {
+ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+
+ /* get the row ID (2 ASCII characters) */
+ start_ptr -= 2;
+ card_id_buf[0] = *(start_ptr);
+ card_id_buf[1] = *(start_ptr+1);
+ card_id_buf[2] = 0x00;
+
+ card_match_id = simple_strtol(card_id_buf, 0, 10);
+ }
+ break;
+
+ case MC_SELECT_CARDTYPE: // CARDTYPE
+ card_nouse_id = -1;
+
+ for(card_index=0;
+ card_index<MAX_NUM_OF_MULTIPLE_CARD;
+ card_index++)
+ {
+ sprintf(card_id_buf, "%02dCARDTYPE%s",
+ card_index, RFIC_word);
+
+ if ((start_ptr=rtstrstruncasecmp(buffer,
+ card_id_buf)) != NULL)
+ {
+ LETTER_CASE_TRANSLATE(start_ptr, card_id_buf);
+
+ if (MC_CardUsed[card_index] == 0)
+ {
+ /* current the card profile is not used */
+ if ((*(UINT32 *)&MC_CardMac[card_index][0] == 0) &&
+ (*(UINT16 *)&MC_CardMac[card_index][4] == 0))
+ {
+ // find it and no previous card use it
+ card_match_id = card_index;
+ break;
+ }
+ else
+ {
+ // ever a card use it
+ if (card_nouse_id < 0)
+ card_nouse_id = card_index;
+ }
+ }
+ }
+ }
+
+ // if not find a free one, use the available one
+ if (card_match_id < 0)
+ card_match_id = card_nouse_id;
+ break;
+ }
+ }
+
+ if (card_match_id >= 0)
+ {
+ // make up search keyword
+ switch(card_select_method)
+ {
+ case MC_SELECT_CARDID: // CARDID
+ sprintf(card_id_buf, "%02dCARDID", card_match_id);
+ break;
+
+ case MC_SELECT_MAC: // MAC
+ sprintf(card_id_buf,
+ "%02dmac%02x:%02x:%02x:%02x:%02x:%02x",
+ card_match_id,
+ mac[0], mac[1], mac[2],
+ mac[3], mac[4], mac[5]);
+ break;
+
+ case MC_SELECT_CARDTYPE: // CARDTYPE
+ default:
+ sprintf(card_id_buf, "%02dcardtype%s",
+ card_match_id, RFIC_word);
+ break;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Search Keyword = %s\n", card_id_buf));
+
+ // read card file path
+ if (RTMPGetKeyParameter(card_id_buf, tmpbuf, 256, buffer))
+ {
+ if (strlen(tmpbuf) < sizeof(pAd->MC_FileName))
+ {
+ // backup card information
+ pAd->MC_RowID = card_match_id; /* base 0 */
+ MC_CardUsed[card_match_id] = 1;
+ memcpy(MC_CardMac[card_match_id], mac, sizeof(mac));
+
+ // backup card file path
+ NdisMoveMemory(pAd->MC_FileName, tmpbuf , strlen(tmpbuf));
+ pAd->MC_FileName[strlen(tmpbuf)] = '\0';
+ flg_match_ok = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("Card Profile Name = %s\n", pAd->MC_FileName));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("Card Profile Name length too large!\n"));
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("Can not find search key word in card.dat!\n"));
+ }
+
+ if ((flg_match_ok != TRUE) &&
+ (card_match_id < MAX_NUM_OF_MULTIPLE_CARD))
+ {
+ MC_CardUsed[card_match_id] = 0;
+ memset(MC_CardMac[card_match_id], 0, sizeof(mac));
+ }
+ } // if (card_match_id >= 0)
+ }
+ }
+
+ // close file
+ retval = filp_close(srcf, NULL);
+ set_fs(orgfs);
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+ kfree(buffer);
+ kfree(tmpbuf);
+ return flg_match_ok;
+}
+#endif // MULTIPLE_CARD_SUPPORT //
+
+
+/*
+========================================================================
+Routine Description:
+ Probe RT28XX chipset.
+
+Arguments:
+ _dev_p Point to the PCI or USB device
+ _dev_id_p Point to the PCI or USB device ID
+
+Return Value:
+ 0 Probe OK
+ -ENODEV Probe Fail
+
+Note:
+========================================================================
+*/
+INT __devinit rt28xx_probe(
+ IN void *_dev_p,
+ IN void *_dev_id_p,
+ IN UINT argc,
+ OUT PRTMP_ADAPTER *ppAd)
+{
+ struct net_device *net_dev;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) NULL;
+ INT status;
+ PVOID handle;
+#ifdef RT2870
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* kernel 2.4 series */
+ struct usb_device *dev_p = (struct usb_device *)_dev_p;
+#else
+ struct usb_interface *intf = (struct usb_interface *)_dev_p;
+ struct usb_device *dev_p = interface_to_usbdev(intf);
+
+ dev_p = usb_get_dev(dev_p);
+#endif // LINUX_VERSION_CODE //
+#endif // RT2870 //
+
+
+#ifdef CONFIG_STA_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("STA Driver version-%s\n", STA_DRIVER_VERSION));
+#endif // CONFIG_STA_SUPPORT //
+
+ // Check chipset vendor/product ID
+// if (RT28XXChipsetCheck(_dev_p) == FALSE)
+// goto err_out;
+
+#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
+ net_dev = alloc_netdev(sizeof(PRTMP_ADAPTER), "eth%d", ether_setup);
+#else
+ net_dev = alloc_etherdev(sizeof(PRTMP_ADAPTER));
+#endif
+ if (net_dev == NULL)
+ {
+ printk("alloc_netdev failed\n");
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+ module_put(THIS_MODULE);
+#endif //LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15)
+#else
+ MOD_DEC_USE_COUNT;
+#endif
+ goto err_out;
+ }
+
+// sample
+// if (rt_ieee80211_if_setup(net_dev) != NDIS_STATUS_SUCCESS)
+// goto err_out;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
+ SET_MODULE_OWNER(net_dev);
+#endif
+
+ netif_stop_queue(net_dev);
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+/* for supporting Network Manager */
+/* Set the sysfs physical device reference for the network logical device
+ * if set prior to registration will cause a symlink during initialization.
+ */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+ SET_NETDEV_DEV(net_dev, &(dev_p->dev));
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+ // Allocate RTMP_ADAPTER miniport adapter structure
+ handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
+ RT28XX_HANDLE_DEV_ASSIGN(handle, dev_p);
+
+ status = RTMPAllocAdapterBlock(handle, &pAd);
+ if (status != NDIS_STATUS_SUCCESS)
+ goto err_out_free_netdev;
+
+ net_dev->ml_priv = (PVOID)pAd;
+ pAd->net_dev = net_dev; // must be before RT28XXNetDevInit()
+
+ RT28XXNetDevInit(_dev_p, net_dev, pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+ pAd->StaCfg.OriDevType = net_dev->type;
+#endif // CONFIG_STA_SUPPORT //
+
+ // Find and assign a free interface name, raxx
+// RT28XXAvailRANameAssign(net_dev->name);
+
+ // Post config
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ if (RT28XXProbePostConfig(_dev_p, pAd, argc) == FALSE)
+ goto err_out_unmap;
+#else
+ if (RT28XXProbePostConfig(_dev_p, pAd, 0) == FALSE)
+ goto err_out_unmap;
+#endif // LINUX_VERSION_CODE //
+
+#ifdef CONFIG_STA_SUPPORT
+ pAd->OpMode = OPMODE_STA;
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+ // find its profile path
+ pAd->MC_RowID = -1; // use default profile path
+ RTMP_CardInfoRead(pAd);
+
+ if (pAd->MC_RowID == -1)
+#ifdef CONFIG_STA_SUPPORT
+ strcpy(pAd->MC_FileName, STA_PROFILE_PATH);
+#endif // CONFIG_STA_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE,
+ ("MC> ROW = %d, PATH = %s\n", pAd->MC_RowID, pAd->MC_FileName));
+#endif // MULTIPLE_CARD_SUPPORT //
+
+ // sample move
+ if (rt_ieee80211_if_setup(net_dev, pAd) != NDIS_STATUS_SUCCESS)
+ goto err_out_unmap;
+
+ // Register this device
+ status = register_netdev(net_dev);
+ if (status)
+ goto err_out_unmap;
+
+ // Set driver data
+ RT28XX_DRVDATA_SET(_dev_p);
+
+
+
+ *ppAd = pAd;
+ return 0; // probe ok
+
+
+ /* --------------------------- ERROR HANDLE --------------------------- */
+err_out_unmap:
+ RTMPFreeAdapter(pAd);
+ RT28XX_UNMAP();
+
+err_out_free_netdev:
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
+ free_netdev(net_dev);
+#else
+ kfree(net_dev);
+#endif
+
+err_out:
+ RT28XX_PUT_DEVICE(dev_p);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
+ return (LONG)NULL;
+#else
+ return -ENODEV; /* probe fail */
+#endif // LINUX_VERSION_CODE //
+} /* End of rt28xx_probe */
+
+
+/*
+========================================================================
+Routine Description:
+ The entry point for Linux kernel sent packet to our driver.
+
+Arguments:
+ sk_buff *skb the pointer refer to a sk_buffer.
+
+Return Value:
+ 0
+
+Note:
+ This function is the entry point of Tx Path for Os delivery packet to
+ our driver. You only can put OS-depened & STA/AP common handle procedures
+ in here.
+========================================================================
+*/
+int rt28xx_packet_xmit(struct sk_buff *skb)
+{
+ struct net_device *net_dev = skb->dev;
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+ int status = 0;
+ PNDIS_PACKET pPacket = (PNDIS_PACKET) skb;
+
+ /* RT2870STA does this in RTMPSendPackets() */
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_RESOURCES);
+ return 0;
+ }
+#endif // RALINK_ATE //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ // Drop send request since we are in monitor mode
+ if (MONITOR_ON(pAd))
+ {
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ goto done;
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ // EapolStart size is 18
+ if (skb->len < 14)
+ {
+ //printk("bad packet size: %d\n", pkt->len);
+ hex_dump("bad packet", skb->data, skb->len);
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ goto done;
+ }
+
+ RTMP_SET_PACKET_5VT(pPacket, 0);
+// MiniportMMRequest(pAd, pkt->data, pkt->len);
+#ifdef CONFIG_5VT_ENHANCE
+ if (*(int*)(skb->cb) == BRIDGE_TAG) {
+ RTMP_SET_PACKET_5VT(pPacket, 1);
+ }
+#endif
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+
+ STASendPackets((NDIS_HANDLE)pAd, (PPNDIS_PACKET) &pPacket, 1);
+ }
+
+#endif // CONFIG_STA_SUPPORT //
+
+ status = 0;
+done:
+
+ return status;
+}
+
+
+/*
+========================================================================
+Routine Description:
+ Send a packet to WLAN.
+
+Arguments:
+ skb_p points to our adapter
+ dev_p which WLAN network interface
+
+Return Value:
+ 0: transmit successfully
+ otherwise: transmit fail
+
+Note:
+========================================================================
+*/
+INT rt28xx_send_packets(
+ IN struct sk_buff *skb_p,
+ IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = net_dev->ml_priv;
+
+ if (!(net_dev->flags & IFF_UP))
+ {
+ RELEASE_NDIS_PACKET(pAd, (PNDIS_PACKET)skb_p, NDIS_STATUS_FAILURE);
+ return 0;
+ }
+
+ NdisZeroMemory((PUCHAR)&skb_p->cb[CB_OFF], 15);
+ RTMP_SET_PACKET_NET_DEVICE_MBSSID(skb_p, MAIN_MBSSID);
+
+ return rt28xx_packet_xmit(skb_p);
+} /* End of MBSS_VirtualIF_PacketSend */
+
+
+
+
+#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1
+//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //sample
+struct net_device *alloc_netdev(
+ int sizeof_priv,
+ const char *mask,
+ void (*setup)(struct net_device *))
+{
+ struct net_device *dev;
+ INT alloc_size;
+
+
+ /* ensure 32-byte alignment of the private area */
+ alloc_size = sizeof (*dev) + sizeof_priv + 31;
+
+ dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL);
+ if (dev == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,
+ ("alloc_netdev: Unable to allocate device memory.\n"));
+ return NULL;
+ }
+
+ memset(dev, 0, alloc_size);
+
+ if (sizeof_priv)
+ dev->ml_priv = (void *) (((long)(dev + 1) + 31) & ~31);
+
+ setup(dev);
+ strcpy(dev->name, mask);
+
+ return dev;
+}
+#endif // LINUX_VERSION_CODE //
+
+
+void CfgInitHook(PRTMP_ADAPTER pAd)
+{
+ pAd->bBroadComHT = TRUE;
+} /* End of CfgInitHook */
+
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+ IN struct net_device *net_dev)
+{
+ PRTMP_ADAPTER pAd = net_dev->ml_priv;
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("rt28xx_get_wireless_stats --->\n"));
+
+ pAd->iw_stats.status = 0; // Status - device dependent for now
+
+ // link quality
+ pAd->iw_stats.qual.qual = ((pAd->Mlme.ChannelQuality * 12)/10 + 10);
+ if(pAd->iw_stats.qual.qual > 100)
+ pAd->iw_stats.qual.qual = 100;
+
+#ifdef CONFIG_STA_SUPPORT
+ if (pAd->OpMode == OPMODE_STA)
+ pAd->iw_stats.qual.level = RTMPMaxRssi(pAd, pAd->StaCfg.RssiSample.LastRssi0, pAd->StaCfg.RssiSample.LastRssi1, pAd->StaCfg.RssiSample.LastRssi2);
+#endif // CONFIG_STA_SUPPORT //
+
+ pAd->iw_stats.qual.noise = pAd->BbpWriteLatch[66]; // noise level (dBm)
+
+ pAd->iw_stats.qual.noise += 256 - 143;
+ pAd->iw_stats.qual.updated = 1; // Flags to know if updated
+#ifdef IW_QUAL_DBM
+ pAd->iw_stats.qual.updated |= IW_QUAL_DBM; // Level + Noise are dBm
+#endif // IW_QUAL_DBM //
+
+ pAd->iw_stats.discard.nwid = 0; // Rx : Wrong nwid/essid
+ pAd->iw_stats.miss.beacon = 0; // Missed beacons/superframe
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<--- rt28xx_get_wireless_stats\n"));
+ return &pAd->iw_stats;
+} /* End of rt28xx_get_wireless_stats */
+#endif // WIRELESS_EXT //
+
+
+
+void tbtt_tasklet(unsigned long data)
+{
+#define MAX_TX_IN_TBTT (16)
+
+}
+
+INT rt28xx_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ RTMP_ADAPTER *pAd = NULL;
+ INT ret = 0;
+
+ if (net_dev->priv_flags == INT_MAIN)
+ {
+ pAd = net_dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = net_dev->ml_priv;
+ pAd = pVirtualAd->RtmpDev->ml_priv;
+ }
+
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ ret = rt28xx_sta_ioctl(net_dev, rq, cmd);
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ return ret;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ return ethernet statistics counter
+
+ Arguments:
+ net_dev Pointer to net_device
+
+ Return Value:
+ net_device_stats*
+
+ Note:
+
+ ========================================================================
+*/
+struct net_device_stats *RT28xx_get_ether_stats(
+ IN struct net_device *net_dev)
+{
+ RTMP_ADAPTER *pAd = NULL;
+
+ if (net_dev)
+ pAd = net_dev->ml_priv;
+
+ if (pAd)
+ {
+
+ pAd->stats.rx_packets = pAd->WlanCounters.ReceivedFragmentCount.QuadPart;
+ pAd->stats.tx_packets = pAd->WlanCounters.TransmittedFragmentCount.QuadPart;
+
+ pAd->stats.rx_bytes = pAd->RalinkCounters.ReceivedByteCount;
+ pAd->stats.tx_bytes = pAd->RalinkCounters.TransmittedByteCount;
+
+ pAd->stats.rx_errors = pAd->Counters8023.RxErrors;
+ pAd->stats.tx_errors = pAd->Counters8023.TxErrors;
+
+ pAd->stats.rx_dropped = 0;
+ pAd->stats.tx_dropped = 0;
+
+ pAd->stats.multicast = pAd->WlanCounters.MulticastReceivedFrameCount.QuadPart; // multicast packets received
+ pAd->stats.collisions = pAd->Counters8023.OneCollision + pAd->Counters8023.MoreCollisions; // Collision packets
+
+ pAd->stats.rx_length_errors = 0;
+ pAd->stats.rx_over_errors = pAd->Counters8023.RxNoBuffer; // receiver ring buff overflow
+ pAd->stats.rx_crc_errors = 0;//pAd->WlanCounters.FCSErrorCount; // recved pkt with crc error
+ pAd->stats.rx_frame_errors = pAd->Counters8023.RcvAlignmentErrors; // recv'd frame alignment error
+ pAd->stats.rx_fifo_errors = pAd->Counters8023.RxNoBuffer; // recv'r fifo overrun
+ pAd->stats.rx_missed_errors = 0; // receiver missed packet
+
+ // detailed tx_errors
+ pAd->stats.tx_aborted_errors = 0;
+ pAd->stats.tx_carrier_errors = 0;
+ pAd->stats.tx_fifo_errors = 0;
+ pAd->stats.tx_heartbeat_errors = 0;
+ pAd->stats.tx_window_errors = 0;
+
+ // for cslip etc
+ pAd->stats.rx_compressed = 0;
+ pAd->stats.tx_compressed = 0;
+
+ return &pAd->stats;
+ }
+ else
+ return NULL;
+}
+
diff --git a/drivers/staging/rt3070/rt_profile.c b/drivers/staging/rt3070/rt_profile.c
new file mode 100644
index 00000000000..6eda27e6b8d
--- /dev/null
+++ b/drivers/staging/rt3070/rt_profile.c
@@ -0,0 +1,2041 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#include "rt_config.h"
+
+#ifdef DOT11_N_SUPPORT
+static void HTParametersHook(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR *pValueStr,
+ IN CHAR *pInput);
+#endif // DOT11_N_SUPPORT //
+
+#define ETH_MAC_ADDR_STR_LEN 17 // in format of xx:xx:xx:xx:xx:xx
+
+// We assume the s1 is a sting, s2 is a memory space with 6 bytes. and content of s1 will be changed.
+BOOLEAN rtstrmactohex(char *s1, char *s2)
+{
+ int i = 0;
+ char *ptokS = s1, *ptokE = s1;
+
+ if (strlen(s1) != ETH_MAC_ADDR_STR_LEN)
+ return FALSE;
+
+ while((*ptokS) != '\0')
+ {
+ if((ptokE = strchr(ptokS, ':')) != NULL)
+ *ptokE++ = '\0';
+ if ((strlen(ptokS) != 2) || (!isxdigit(*ptokS)) || (!isxdigit(*(ptokS+1))))
+ break; // fail
+ AtoH(ptokS, &s2[i++], 1);
+ ptokS = ptokE;
+ if (i == 6)
+ break; // parsing finished
+ }
+
+ return ( i == 6 ? TRUE : FALSE);
+
+}
+
+
+// we assume the s1 and s2 both are strings.
+BOOLEAN rtstrcasecmp(char *s1, char *s2)
+{
+ char *p1 = s1, *p2 = s2;
+
+ if (strlen(s1) != strlen(s2))
+ return FALSE;
+
+ while(*p1 != '\0')
+ {
+ if((*p1 != *p2) && ((*p1 ^ *p2) != 0x20))
+ return FALSE;
+ p1++;
+ p2++;
+ }
+
+ return TRUE;
+}
+
+// we assume the s1 (buffer) and s2 (key) both are strings.
+char * rtstrstruncasecmp(char * s1, char * s2)
+{
+ INT l1, l2, i;
+ char temp1, temp2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *) s1;
+
+ l1 = strlen(s1);
+
+ while (l1 >= l2)
+ {
+ l1--;
+
+ for(i=0; i<l2; i++)
+ {
+ temp1 = *(s1+i);
+ temp2 = *(s2+i);
+
+ if (('a' <= temp1) && (temp1 <= 'z'))
+ temp1 = 'A'+(temp1-'a');
+ if (('a' <= temp2) && (temp2 <= 'z'))
+ temp2 = 'A'+(temp2-'a');
+
+ if (temp1 != temp2)
+ break;
+ }
+
+ if (i == l2)
+ return (char *) s1;
+
+ s1++;
+ }
+
+ return NULL; // not found
+}
+
+//add by kathy
+
+ /**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char * rtstrstr(const char * s1,const char * s2)
+{
+ INT l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *) s1;
+
+ l1 = strlen(s1);
+
+ while (l1 >= l2)
+ {
+ l1--;
+ if (!memcmp(s1,s2,l2))
+ return (char *) s1;
+ s1++;
+ }
+
+ return NULL;
+}
+
+/**
+ * rstrtok - Split a string into tokens
+ * @s: The string to be searched
+ * @ct: The characters to search for
+ * * WARNING: strtok is deprecated, use strsep instead. However strsep is not compatible with old architecture.
+ */
+char * __rstrtok;
+char * rstrtok(char * s,const char * ct)
+{
+ char *sbegin, *send;
+
+ sbegin = s ? s : __rstrtok;
+ if (!sbegin)
+ {
+ return NULL;
+ }
+
+ sbegin += strspn(sbegin,ct);
+ if (*sbegin == '\0')
+ {
+ __rstrtok = NULL;
+ return( NULL );
+ }
+
+ send = strpbrk( sbegin, ct);
+ if (send && *send != '\0')
+ *send++ = '\0';
+
+ __rstrtok = send;
+
+ return (sbegin);
+}
+
+/**
+ * delimitcnt - return the count of a given delimiter in a given string.
+ * @s: The string to be searched.
+ * @ct: The delimiter to search for.
+ * Notice : We suppose the delimiter is a single-char string(for example : ";").
+ */
+INT delimitcnt(char * s,const char * ct)
+{
+ INT count = 0;
+ /* point to the beginning of the line */
+ const char *token = s;
+
+ for ( ;; )
+ {
+ token = strpbrk(token, ct); /* search for delimiters */
+
+ if ( token == NULL )
+ {
+ /* advanced to the terminating null character */
+ break;
+ }
+ /* skip the delimiter */
+ ++token;
+
+ /*
+ * Print the found text: use len with %.*s to specify field width.
+ */
+
+ /* accumulate delimiter count */
+ ++count;
+ }
+ return count;
+}
+
+/*
+ * converts the Internet host address from the standard numbers-and-dots notation
+ * into binary data.
+ * returns nonzero if the address is valid, zero if not.
+ */
+int rtinet_aton(const char *cp, unsigned int *addr)
+{
+ unsigned int val;
+ int base, n;
+ char c;
+ unsigned int parts[4];
+ unsigned int *pp = parts;
+
+ for (;;)
+ {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, other=decimal.
+ */
+ val = 0;
+ base = 10;
+ if (*cp == '0')
+ {
+ if (*++cp == 'x' || *cp == 'X')
+ base = 16, cp++;
+ else
+ base = 8;
+ }
+ while ((c = *cp) != '\0')
+ {
+ if (isdigit((unsigned char) c))
+ {
+ val = (val * base) + (c - '0');
+ cp++;
+ continue;
+ }
+ if (base == 16 && isxdigit((unsigned char) c))
+ {
+ val = (val << 4) +
+ (c + 10 - (islower((unsigned char) c) ? 'a' : 'A'));
+ cp++;
+ continue;
+ }
+ break;
+ }
+ if (*cp == '.')
+ {
+ /*
+ * Internet format: a.b.c.d a.b.c (with c treated as 16-bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ return 0;
+ *pp++ = val, cp++;
+ }
+ else
+ break;
+ }
+
+ /*
+ * Check for trailing junk.
+ */
+ while (*cp)
+ if (!isspace((unsigned char) *cp++))
+ return 0;
+
+ /*
+ * Concoct the address according to the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n)
+ {
+
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return 0;
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return 0;
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return 0;
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+
+ *addr = htonl(val);
+ return 1;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Find key section for Get key parameter.
+
+ Arguments:
+ buffer Pointer to the buffer to start find the key section
+ section the key of the secion to be find
+
+ Return Value:
+ NULL Fail
+ Others Success
+ ========================================================================
+*/
+PUCHAR RTMPFindSection(
+ IN PCHAR buffer)
+{
+ CHAR temp_buf[32];
+ PUCHAR ptr;
+
+ strcpy(temp_buf, "Default");
+
+ if((ptr = rtstrstr(buffer, temp_buf)) != NULL)
+ return (ptr+strlen("\n"));
+ else
+ return NULL;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get key parameter.
+
+ Arguments:
+ key Pointer to key string
+ dest Pointer to destination
+ destsize The datasize of the destination
+ buffer Pointer to the buffer to start find the key
+
+ Return Value:
+ TRUE Success
+ FALSE Fail
+
+ Note:
+ This routine get the value with the matched key (case case-sensitive)
+ ========================================================================
+*/
+INT RTMPGetKeyParameter(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ IN INT destsize,
+ IN PCHAR buffer)
+{
+ UCHAR *temp_buf1 = NULL;
+ UCHAR *temp_buf2 = NULL;
+ CHAR *start_ptr;
+ CHAR *end_ptr;
+ CHAR *ptr;
+ CHAR *offset = 0;
+ INT len;
+
+ //temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+ if(temp_buf1 == NULL)
+ return (FALSE);
+
+ //temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+ if(temp_buf2 == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ return (FALSE);
+ }
+
+ //find section
+ if((offset = RTMPFindSection(buffer)) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf1, "\n");
+ strcat(temp_buf1, key);
+ strcat(temp_buf1, "=");
+
+ //search key
+ if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ start_ptr+=strlen("\n");
+ if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+ end_ptr=start_ptr+strlen(start_ptr);
+
+ if (end_ptr<start_ptr)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+ len = strlen(temp_buf2);
+ strcpy(temp_buf1, temp_buf2);
+ if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf2, start_ptr+1);
+ ptr = temp_buf2;
+ //trim space or tab
+ while(*ptr != 0x00)
+ {
+ if( (*ptr == ' ') || (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+
+ len = strlen(ptr);
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, len >= destsize ? destsize: len);
+
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get key parameter.
+
+ Arguments:
+ key Pointer to key string
+ dest Pointer to destination
+ destsize The datasize of the destination
+ buffer Pointer to the buffer to start find the key
+
+ Return Value:
+ TRUE Success
+ FALSE Fail
+
+ Note:
+ This routine get the value with the matched key (case case-sensitive).
+ It is called for parsing SSID and any key string.
+ ========================================================================
+*/
+INT RTMPGetCriticalParameter(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ IN INT destsize,
+ IN PCHAR buffer)
+{
+ UCHAR *temp_buf1 = NULL;
+ UCHAR *temp_buf2 = NULL;
+ CHAR *start_ptr;
+ CHAR *end_ptr;
+ CHAR *ptr;
+ CHAR *offset = 0;
+ INT len;
+
+ //temp_buf1 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+ if(temp_buf1 == NULL)
+ return (FALSE);
+
+ //temp_buf2 = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+ if(temp_buf2 == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ return (FALSE);
+ }
+
+ //find section
+ if((offset = RTMPFindSection(buffer)) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf1, "\n");
+ strcat(temp_buf1, key);
+ strcat(temp_buf1, "=");
+
+ //search key
+ if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ start_ptr+=strlen("\n");
+ if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+ end_ptr=start_ptr+strlen(start_ptr);
+
+ if (end_ptr<start_ptr)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+ len = strlen(temp_buf2);
+ strcpy(temp_buf1, temp_buf2);
+ if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf2, start_ptr+1);
+ ptr = temp_buf2;
+
+ //trim tab
+ /* We cannot trim space(' ') for SSID and key string. */
+ while(*ptr != 0x00)
+ {
+ //if( (*ptr == ' ') || (*ptr == '\t') )
+ if( (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+
+ len = strlen(ptr);
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, len >= destsize ? destsize: len);
+
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return TRUE;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Get multiple key parameter.
+
+ Arguments:
+ key Pointer to key string
+ dest Pointer to destination
+ destsize The datasize of the destination
+ buffer Pointer to the buffer to start find the key
+
+ Return Value:
+ TRUE Success
+ FALSE Fail
+
+ Note:
+ This routine get the value with the matched key (case case-sensitive)
+ ========================================================================
+*/
+INT RTMPGetKeyParameterWithOffset(
+ IN PCHAR key,
+ OUT PCHAR dest,
+ OUT USHORT *end_offset,
+ IN INT destsize,
+ IN PCHAR buffer,
+ IN BOOLEAN bTrimSpace)
+{
+ UCHAR *temp_buf1 = NULL;
+ UCHAR *temp_buf2 = NULL;
+ CHAR *start_ptr;
+ CHAR *end_ptr;
+ CHAR *ptr;
+ CHAR *offset = 0;
+ INT len;
+
+ if (*end_offset >= MAX_INI_BUFFER_SIZE)
+ return (FALSE);
+
+ os_alloc_mem(NULL, &temp_buf1, MAX_PARAM_BUFFER_SIZE);
+
+ if(temp_buf1 == NULL)
+ return (FALSE);
+
+ os_alloc_mem(NULL, &temp_buf2, MAX_PARAM_BUFFER_SIZE);
+ if(temp_buf2 == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ return (FALSE);
+ }
+
+ //find section
+ if(*end_offset == 0)
+ {
+ if ((offset = RTMPFindSection(buffer)) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+ }
+ else
+ offset = buffer + (*end_offset);
+
+ strcpy(temp_buf1, "\n");
+ strcat(temp_buf1, key);
+ strcat(temp_buf1, "=");
+
+ //search key
+ if((start_ptr=rtstrstr(offset, temp_buf1))==NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ start_ptr+=strlen("\n");
+ if((end_ptr=rtstrstr(start_ptr, "\n"))==NULL)
+ end_ptr=start_ptr+strlen(start_ptr);
+
+ if (end_ptr<start_ptr)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ *end_offset = end_ptr - buffer;
+
+ NdisMoveMemory(temp_buf2, start_ptr, end_ptr-start_ptr);
+ temp_buf2[end_ptr-start_ptr]='\0';
+ len = strlen(temp_buf2);
+ strcpy(temp_buf1, temp_buf2);
+ if((start_ptr=rtstrstr(temp_buf1, "=")) == NULL)
+ {
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return (FALSE);
+ }
+
+ strcpy(temp_buf2, start_ptr+1);
+ ptr = temp_buf2;
+ //trim space or tab
+ while(*ptr != 0x00)
+ {
+ if((bTrimSpace && (*ptr == ' ')) || (*ptr == '\t') )
+ ptr++;
+ else
+ break;
+ }
+
+ len = strlen(ptr);
+ memset(dest, 0x00, destsize);
+ strncpy(dest, ptr, len >= destsize ? destsize: len);
+
+ os_free_mem(NULL, temp_buf1);
+ os_free_mem(NULL, temp_buf2);
+ return TRUE;
+}
+
+
+static int rtmp_parse_key_buffer_from_file(IN PRTMP_ADAPTER pAd,IN char *buffer,IN ULONG KeyType,IN INT BSSIdx,IN INT KeyIdx)
+{
+ PUCHAR keybuff;
+ INT i = BSSIdx, idx = KeyIdx;
+ ULONG KeyLen;
+ UCHAR CipherAlg = CIPHER_WEP64;
+
+ keybuff = buffer;
+ KeyLen = strlen(keybuff);
+
+ if (KeyType == 1)
+ {//Ascii
+ if( (KeyLen == 5) || (KeyLen == 13))
+ {
+ pAd->SharedKey[i][idx].KeyLen = KeyLen;
+ NdisMoveMemory(pAd->SharedKey[i][idx].Key, keybuff, KeyLen);
+ if (KeyLen == 5)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+ pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
+ return 1;
+ }
+ else
+ {//Invalid key length
+ DBGPRINT(RT_DEBUG_ERROR, ("Key%dStr is Invalid key length! KeyLen = %ld!\n", idx+1, KeyLen));
+ return 0;
+ }
+ }
+ else
+ {//Hex type
+ if( (KeyLen == 10) || (KeyLen == 26))
+ {
+ pAd->SharedKey[i][idx].KeyLen = KeyLen / 2;
+ AtoH(keybuff, pAd->SharedKey[i][idx].Key, KeyLen / 2);
+ if (KeyLen == 10)
+ CipherAlg = CIPHER_WEP64;
+ else
+ CipherAlg = CIPHER_WEP128;
+ pAd->SharedKey[i][idx].CipherAlg = CipherAlg;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("I/F(ra%d) Key%dStr=%s and type=%s\n", i, idx+1, keybuff, (KeyType == 0) ? "Hex":"Ascii"));
+ return 1;
+ }
+ else
+ {//Invalid key length
+ DBGPRINT(RT_DEBUG_ERROR, ("I/F(ra%d) Key%dStr is Invalid key length! KeyLen = %ld!\n", i, idx+1, KeyLen));
+ return 0;
+ }
+ }
+}
+static void rtmp_read_key_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+ char tok_str[16];
+ PUCHAR macptr;
+ INT i = 0, idx;
+ ULONG KeyType[MAX_MBSSID_NUM];
+ ULONG KeyIdx;
+
+ NdisZeroMemory(KeyType, MAX_MBSSID_NUM);
+
+ //DefaultKeyID
+ if(RTMPGetKeyParameter("DefaultKeyID", tmpbuf, 25, buffer))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ KeyIdx = simple_strtol(tmpbuf, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAd->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1);
+ else
+ pAd->StaCfg.DefaultKeyId = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyID(0~3)=%d\n", pAd->StaCfg.DefaultKeyId));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ for (idx = 0; idx < 4; idx++)
+ {
+ sprintf(tok_str, "Key%dType", idx + 1);
+ //Key1Type
+ if (RTMPGetKeyParameter(tok_str, tmpbuf, 128, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ KeyType[i] = simple_strtol(macptr, 0, 10);
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ sprintf(tok_str, "Key%dStr", idx + 1);
+ if (RTMPGetCriticalParameter(tok_str, tmpbuf, 128, buffer))
+ {
+ rtmp_parse_key_buffer_from_file(pAd, tmpbuf, KeyType[BSS0], BSS0, idx);
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ }
+}
+
+
+#ifdef CONFIG_STA_SUPPORT
+static void rtmp_read_sta_wmm_parms_from_file(IN PRTMP_ADAPTER pAd, char *tmpbuf, char *buffer)
+{
+ PUCHAR macptr;
+ INT i=0;
+ BOOLEAN bWmmEnable = FALSE;
+
+ //WmmCapable
+ if(RTMPGetKeyParameter("WmmCapable", tmpbuf, 32, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ {
+ pAd->CommonCfg.bWmmCapable = TRUE;
+ bWmmEnable = TRUE;
+ }
+ else //Disable
+ {
+ pAd->CommonCfg.bWmmCapable = FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WmmCapable=%d\n", pAd->CommonCfg.bWmmCapable));
+ }
+
+#ifdef QOS_DLS_SUPPORT
+ //DLSCapable
+ if(RTMPGetKeyParameter("DLSCapable", tmpbuf, 32, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ {
+ pAd->CommonCfg.bDLSCapable = TRUE;
+ }
+ else //Disable
+ {
+ pAd->CommonCfg.bDLSCapable = FALSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("bDLSCapable=%d\n", pAd->CommonCfg.bDLSCapable));
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ //AckPolicy for AC_BK, AC_BE, AC_VI, AC_VO
+ if(RTMPGetKeyParameter("AckPolicy", tmpbuf, 32, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ pAd->CommonCfg.AckPolicy[i] = (UCHAR)simple_strtol(macptr, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AckPolicy[%d]=%d\n", i, pAd->CommonCfg.AckPolicy[i]));
+ }
+ }
+
+ if (bWmmEnable)
+ {
+ //APSDCapable
+ if(RTMPGetKeyParameter("APSDCapable", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bAPSDCapable = TRUE;
+ else
+ pAd->CommonCfg.bAPSDCapable = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APSDCapable=%d\n", pAd->CommonCfg.bAPSDCapable));
+ }
+
+ //APSDAC for AC_BE, AC_BK, AC_VI, AC_VO
+ if(RTMPGetKeyParameter("APSDAC", tmpbuf, 32, buffer))
+ {
+ BOOLEAN apsd_ac[4];
+
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ apsd_ac[i] = (BOOLEAN)simple_strtol(macptr, 0, 10);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("APSDAC%d %d\n", i, apsd_ac[i]));
+ }
+
+ pAd->CommonCfg.bAPSDAC_BE = apsd_ac[0];
+ pAd->CommonCfg.bAPSDAC_BK = apsd_ac[1];
+ pAd->CommonCfg.bAPSDAC_VI = apsd_ac[2];
+ pAd->CommonCfg.bAPSDAC_VO = apsd_ac[3];
+ }
+ }
+
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+NDIS_STATUS RTMPReadParametersHook(
+ IN PRTMP_ADAPTER pAd)
+{
+ PUCHAR src = NULL;
+ struct file *srcf;
+ INT retval, orgfsuid, orgfsgid;
+ mm_segment_t orgfs;
+ CHAR *buffer;
+ CHAR *tmpbuf;
+ ULONG RtsThresh;
+ ULONG FragThresh;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR keyMaterial[40];
+#endif // CONFIG_STA_SUPPORT //
+
+
+ PUCHAR macptr;
+ INT i = 0;
+
+ buffer = kmalloc(MAX_INI_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if(buffer == NULL)
+ return NDIS_STATUS_FAILURE;
+
+ tmpbuf = kmalloc(MAX_PARAM_BUFFER_SIZE, MEM_ALLOC_FLAG);
+ if(tmpbuf == NULL)
+ {
+ kfree(buffer);
+ return NDIS_STATUS_FAILURE;
+ }
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ src = STA_PROFILE_PATH;
+#endif // CONFIG_STA_SUPPORT //
+#ifdef MULTIPLE_CARD_SUPPORT
+ src = pAd->MC_FileName;
+#endif // MULTIPLE_CARD_SUPPORT //
+
+ // Save uid and gid used for filesystem access.
+ // Set user and group to 0 (root)
+#if 0
+ orgfsuid = current->fsuid;
+ orgfsgid = current->fsgid;
+ current->fsuid=current->fsgid = 0;
+#endif
+ orgfs = get_fs();
+ set_fs(KERNEL_DS);
+
+ if (src && *src)
+ {
+ srcf = filp_open(src, O_RDONLY, 0);
+ if (IS_ERR(srcf))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("--> Error %ld opening %s\n", -PTR_ERR(srcf),src));
+ }
+ else
+ {
+ // The object must have a read method
+ if (srcf->f_op && srcf->f_op->read)
+ {
+ memset(buffer, 0x00, MAX_INI_BUFFER_SIZE);
+ retval=srcf->f_op->read(srcf, buffer, MAX_INI_BUFFER_SIZE, &srcf->f_pos);
+ if (retval < 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> Read %s error %d\n", src, -retval));
+ }
+ else
+ {
+ // set file parameter to portcfg
+ //CountryRegion
+ if(RTMPGetKeyParameter("CountryRegion", tmpbuf, 25, buffer))
+ {
+ pAd->CommonCfg.CountryRegion = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryRegion=%d\n", pAd->CommonCfg.CountryRegion));
+ }
+ //CountryRegionABand
+ if(RTMPGetKeyParameter("CountryRegionABand", tmpbuf, 25, buffer))
+ {
+ pAd->CommonCfg.CountryRegionForABand= (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryRegionABand=%d\n", pAd->CommonCfg.CountryRegionForABand));
+ }
+ //CountryCode
+ if(RTMPGetKeyParameter("CountryCode", tmpbuf, 25, buffer))
+ {
+ NdisMoveMemory(pAd->CommonCfg.CountryCode, tmpbuf , 2);
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ NdisMoveMemory(pAd->StaCfg.StaOriCountryCode, tmpbuf , 2);
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+ if (strlen(pAd->CommonCfg.CountryCode) != 0)
+ {
+ pAd->CommonCfg.bCountryFlag = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("CountryCode=%s\n", pAd->CommonCfg.CountryCode));
+ }
+ //ChannelGeography
+ if(RTMPGetKeyParameter("ChannelGeography", tmpbuf, 25, buffer))
+ {
+ UCHAR Geography = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ if (Geography <= BOTH)
+ {
+ pAd->CommonCfg.Geography = Geography;
+ pAd->CommonCfg.CountryCode[2] =
+ (pAd->CommonCfg.Geography == BOTH) ? ' ' : ((pAd->CommonCfg.Geography == IDOR) ? 'I' : 'O');
+#ifdef CONFIG_STA_SUPPORT
+#ifdef EXT_BUILD_CHANNEL_LIST
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->StaCfg.StaOriGeography = pAd->CommonCfg.Geography;
+#endif // EXT_BUILD_CHANNEL_LIST //
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelGeography=%d\n", pAd->CommonCfg.Geography));
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.Geography = BOTH;
+ pAd->CommonCfg.CountryCode[2] = ' ';
+ }
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //SSID
+ if (RTMPGetCriticalParameter("SSID", tmpbuf, 256, buffer))
+ {
+ if (strlen(tmpbuf) <= 32)
+ {
+ pAd->CommonCfg.SsidLen = (UCHAR) strlen(tmpbuf);
+ NdisZeroMemory(pAd->CommonCfg.Ssid, NDIS_802_11_LENGTH_SSID);
+ NdisMoveMemory(pAd->CommonCfg.Ssid, tmpbuf, pAd->CommonCfg.SsidLen);
+ pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen;
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID);
+ NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, tmpbuf, pAd->MlmeAux.AutoReconnectSsidLen);
+ pAd->MlmeAux.SsidLen = pAd->CommonCfg.SsidLen;
+ NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID);
+ NdisMoveMemory(pAd->MlmeAux.Ssid, tmpbuf, pAd->MlmeAux.SsidLen);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(SSID=%s)\n", __FUNCTION__, tmpbuf));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //NetworkType
+ if (RTMPGetKeyParameter("NetworkType", tmpbuf, 25, buffer))
+ {
+ pAd->bConfigChanged = TRUE;
+ if (strcmp(tmpbuf, "Adhoc") == 0)
+ pAd->StaCfg.BssType = BSS_ADHOC;
+ else //Default Infrastructure mode
+ pAd->StaCfg.BssType = BSS_INFRA;
+ // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+ pAd->StaCfg.WpaState = SS_NOTUSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(NetworkType=%d)\n", __FUNCTION__, pAd->StaCfg.BssType));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ //Channel
+ if(RTMPGetKeyParameter("Channel", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.Channel = (UCHAR) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("Channel=%d\n", pAd->CommonCfg.Channel));
+ }
+ //WirelessMode
+ if(RTMPGetKeyParameter("WirelessMode", tmpbuf, 10, buffer))
+ {
+ int value = 0, maxPhyMode = PHY_11G;
+
+#ifdef DOT11_N_SUPPORT
+ maxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+ value = simple_strtol(tmpbuf, 0, 10);
+
+ if (value <= maxPhyMode)
+ {
+ pAd->CommonCfg.PhyMode = value;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("PhyMode=%d\n", pAd->CommonCfg.PhyMode));
+ }
+ //BasicRate
+ if(RTMPGetKeyParameter("BasicRate", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.BasicRateBitmap = (ULONG) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("BasicRate=%ld\n", pAd->CommonCfg.BasicRateBitmap));
+ }
+ //BeaconPeriod
+ if(RTMPGetKeyParameter("BeaconPeriod", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.BeaconPeriod = (USHORT) simple_strtol(tmpbuf, 0, 10);
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconPeriod=%d\n", pAd->CommonCfg.BeaconPeriod));
+ }
+ //TxPower
+ if(RTMPGetKeyParameter("TxPower", tmpbuf, 10, buffer))
+ {
+ pAd->CommonCfg.TxPowerPercentage = (ULONG) simple_strtol(tmpbuf, 0, 10);
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ pAd->CommonCfg.TxPowerDefault = pAd->CommonCfg.TxPowerPercentage;
+#endif // CONFIG_STA_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("TxPower=%ld\n", pAd->CommonCfg.TxPowerPercentage));
+ }
+ //BGProtection
+ if(RTMPGetKeyParameter("BGProtection", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: //Always On
+ pAd->CommonCfg.UseBGProtection = 1;
+ break;
+ case 2: //Always OFF
+ pAd->CommonCfg.UseBGProtection = 2;
+ break;
+ case 0: //AUTO
+ default:
+ pAd->CommonCfg.UseBGProtection = 0;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("BGProtection=%ld\n", pAd->CommonCfg.UseBGProtection));
+ }
+ //OLBCDetection
+ if(RTMPGetKeyParameter("DisableOLBC", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: //disable OLBC Detection
+ pAd->CommonCfg.DisableOLBCDetect = 1;
+ break;
+ case 0: //enable OLBC Detection
+ pAd->CommonCfg.DisableOLBCDetect = 0;
+ break;
+ default:
+ pAd->CommonCfg.DisableOLBCDetect= 0;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("OLBCDetection=%ld\n", pAd->CommonCfg.DisableOLBCDetect));
+ }
+ //TxPreamble
+ if(RTMPGetKeyParameter("TxPreamble", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case Rt802_11PreambleShort:
+ pAd->CommonCfg.TxPreamble = Rt802_11PreambleShort;
+ break;
+ case Rt802_11PreambleLong:
+ default:
+ pAd->CommonCfg.TxPreamble = Rt802_11PreambleLong;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("TxPreamble=%ld\n", pAd->CommonCfg.TxPreamble));
+ }
+ //RTSThreshold
+ if(RTMPGetKeyParameter("RTSThreshold", tmpbuf, 10, buffer))
+ {
+ RtsThresh = simple_strtol(tmpbuf, 0, 10);
+ if( (RtsThresh >= 1) && (RtsThresh <= MAX_RTS_THRESHOLD) )
+ pAd->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
+ else
+ pAd->CommonCfg.RtsThreshold = MAX_RTS_THRESHOLD;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTSThreshold=%d\n", pAd->CommonCfg.RtsThreshold));
+ }
+ //FragThreshold
+ if(RTMPGetKeyParameter("FragThreshold", tmpbuf, 10, buffer))
+ {
+ FragThresh = simple_strtol(tmpbuf, 0, 10);
+ pAd->CommonCfg.bUseZeroToDisableFragment = FALSE;
+
+ if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+ { //illegal FragThresh so we set it to default
+ pAd->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+ pAd->CommonCfg.bUseZeroToDisableFragment = TRUE;
+ }
+ else if (FragThresh % 2 == 1)
+ {
+ // The length of each fragment shall always be an even number of octets, except for the last fragment
+ // of an MSDU or MMPDU, which may be either an even or an odd number of octets.
+ pAd->CommonCfg.FragmentThreshold = (USHORT)(FragThresh - 1);
+ }
+ else
+ {
+ pAd->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+ }
+ //pAd->CommonCfg.AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+ DBGPRINT(RT_DEBUG_TRACE, ("FragThreshold=%d\n", pAd->CommonCfg.FragmentThreshold));
+ }
+ //TxBurst
+ if(RTMPGetKeyParameter("TxBurst", tmpbuf, 10, buffer))
+ {
+//#ifdef WIFI_TEST
+// pAd->CommonCfg.bEnableTxBurst = FALSE;
+//#else
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bEnableTxBurst = TRUE;
+ else //Disable
+ pAd->CommonCfg.bEnableTxBurst = FALSE;
+//#endif
+ DBGPRINT(RT_DEBUG_TRACE, ("TxBurst=%d\n", pAd->CommonCfg.bEnableTxBurst));
+ }
+
+#ifdef AGGREGATION_SUPPORT
+ //PktAggregate
+ if(RTMPGetKeyParameter("PktAggregate", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bAggregationCapable = TRUE;
+ else //Disable
+ pAd->CommonCfg.bAggregationCapable = FALSE;
+#ifdef PIGGYBACK_SUPPORT
+ pAd->CommonCfg.bPiggyBackCapable = pAd->CommonCfg.bAggregationCapable;
+#endif // PIGGYBACK_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("PktAggregate=%d\n", pAd->CommonCfg.bAggregationCapable));
+ }
+#else
+ pAd->CommonCfg.bAggregationCapable = FALSE;
+ pAd->CommonCfg.bPiggyBackCapable = FALSE;
+#endif // AGGREGATION_SUPPORT //
+
+ // WmmCapable
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ rtmp_read_sta_wmm_parms_from_file(pAd, tmpbuf, buffer);
+#endif // CONFIG_STA_SUPPORT //
+
+ //ShortSlot
+ if(RTMPGetKeyParameter("ShortSlot", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bUseShortSlotTime = TRUE;
+ else //Disable
+ pAd->CommonCfg.bUseShortSlotTime = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ShortSlot=%d\n", pAd->CommonCfg.bUseShortSlotTime));
+ }
+ //IEEE80211H
+ if(RTMPGetKeyParameter("IEEE80211H", tmpbuf, 10, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if(simple_strtol(macptr, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bIEEE80211H = TRUE;
+ else //Disable
+ pAd->CommonCfg.bIEEE80211H = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IEEE80211H=%d\n", pAd->CommonCfg.bIEEE80211H));
+ }
+ }
+ //CSPeriod
+ if(RTMPGetKeyParameter("CSPeriod", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0)
+ pAd->CommonCfg.RadarDetect.CSPeriod = simple_strtol(tmpbuf, 0, 10);
+ else
+ pAd->CommonCfg.RadarDetect.CSPeriod = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CSPeriod=%d\n", pAd->CommonCfg.RadarDetect.CSPeriod));
+ }
+
+ //RDRegion
+ if(RTMPGetKeyParameter("RDRegion", tmpbuf, 128, buffer))
+ {
+ if ((strncmp(tmpbuf, "JAP_W53", 7) == 0) || (strncmp(tmpbuf, "jap_w53", 7) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W53;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 15;
+ }
+ else if ((strncmp(tmpbuf, "JAP_W56", 7) == 0) || (strncmp(tmpbuf, "jap_w56", 7) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = JAP_W56;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+ else if ((strncmp(tmpbuf, "JAP", 3) == 0) || (strncmp(tmpbuf, "jap", 3) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = JAP;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
+ }
+ else if ((strncmp(tmpbuf, "FCC", 3) == 0) || (strncmp(tmpbuf, "fcc", 3) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = FCC;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 5;
+ }
+ else if ((strncmp(tmpbuf, "CE", 2) == 0) || (strncmp(tmpbuf, "ce", 2) == 0))
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+ else
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RDRegion=%d\n", pAd->CommonCfg.RadarDetect.RDDurRegion));
+ }
+ else
+ {
+ pAd->CommonCfg.RadarDetect.RDDurRegion = CE;
+ pAd->CommonCfg.RadarDetect.DfsSessionTime = 13;
+ }
+
+ //WirelessEvent
+ if(RTMPGetKeyParameter("WirelessEvent", tmpbuf, 10, buffer))
+ {
+#if WIRELESS_EXT >= 15
+ if(simple_strtol(tmpbuf, 0, 10) != 0)
+ pAd->CommonCfg.bWirelessEvent = simple_strtol(tmpbuf, 0, 10);
+ else
+ pAd->CommonCfg.bWirelessEvent = 0; // disable
+#else
+ pAd->CommonCfg.bWirelessEvent = 0; // disable
+#endif
+ DBGPRINT(RT_DEBUG_TRACE, ("WirelessEvent=%d\n", pAd->CommonCfg.bWirelessEvent));
+ }
+ if(RTMPGetKeyParameter("WiFiTest", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) != 0)
+ pAd->CommonCfg.bWiFiTest= simple_strtol(tmpbuf, 0, 10);
+ else
+ pAd->CommonCfg.bWiFiTest = 0; // disable
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WiFiTest=%d\n", pAd->CommonCfg.bWiFiTest));
+ }
+ //AuthMode
+ if(RTMPGetKeyParameter("AuthMode", tmpbuf, 128, buffer))
+ {
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((strcmp(tmpbuf, "WEPAUTO") == 0) || (strcmp(tmpbuf, "wepauto") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strcmp(tmpbuf, "SHARED") == 0) || (strcmp(tmpbuf, "shared") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ else if ((strcmp(tmpbuf, "WPAPSK") == 0) || (strcmp(tmpbuf, "wpapsk") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strcmp(tmpbuf, "WPANONE") == 0) || (strcmp(tmpbuf, "wpanone") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+ else if ((strcmp(tmpbuf, "WPA2PSK") == 0) || (strcmp(tmpbuf, "wpa2psk") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else if ((strcmp(tmpbuf, "WPA") == 0) || (strcmp(tmpbuf, "wpa") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+ else if ((strcmp(tmpbuf, "WPA2") == 0) || (strcmp(tmpbuf, "wpa2") == 0))
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+ //EncrypType
+ if(RTMPGetKeyParameter("EncrypType", tmpbuf, 128, buffer))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if ((strcmp(tmpbuf, "WEP") == 0) || (strcmp(tmpbuf, "wep") == 0))
+ pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ else if ((strcmp(tmpbuf, "TKIP") == 0) || (strcmp(tmpbuf, "tkip") == 0))
+ pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
+ else if ((strcmp(tmpbuf, "AES") == 0) || (strcmp(tmpbuf, "aes") == 0))
+ pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
+ else
+ pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+
+ // Update all wepstatus related
+ pAd->StaCfg.PairCipher = pAd->StaCfg.WepStatus;
+ pAd->StaCfg.GroupCipher = pAd->StaCfg.WepStatus;
+ pAd->StaCfg.OrigWepStatus = pAd->StaCfg.WepStatus;
+ pAd->StaCfg.bMixCipher = FALSE;
+
+ //RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(EncrypType=%d)\n", __FUNCTION__, pAd->StaCfg.WepStatus));
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if(RTMPGetCriticalParameter("WPAPSK", tmpbuf, 512, buffer))
+ {
+ int err=0;
+
+ tmpbuf[strlen(tmpbuf)] = '\0'; // make STA can process .$^& for WPAPSK input
+
+ if ((pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (pAd->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+ )
+ {
+ err = 1;
+ }
+ else if ((strlen(tmpbuf) >= 8) && (strlen(tmpbuf) < 64))
+ {
+ PasswordHash((char *)tmpbuf, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, keyMaterial);
+ NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
+
+ }
+ else if (strlen(tmpbuf) == 64)
+ {
+ AtoH(tmpbuf, keyMaterial, 32);
+ NdisMoveMemory(pAd->StaCfg.PMK, keyMaterial, 32);
+ }
+ else
+ {
+ err = 1;
+ DBGPRINT(RT_DEBUG_ERROR, ("%s::(WPAPSK key-string required 8 ~ 64 characters!)\n", __FUNCTION__));
+ }
+
+ if (err == 0)
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ // Start STA supplicant state machine
+ pAd->StaCfg.WpaState = SS_START;
+ }
+ else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ /*
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+ */
+ pAd->StaCfg.WpaState = SS_NOTUSE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::(WPAPSK=%s)\n", __FUNCTION__, tmpbuf));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+ //DefaultKeyID, KeyType, KeyStr
+ rtmp_read_key_parms_from_file(pAd, tmpbuf, buffer);
+
+
+ //HSCounter
+ /*if(RTMPGetKeyParameter("HSCounter", tmpbuf, 10, buffer))
+ {
+ switch (simple_strtol(tmpbuf, 0, 10))
+ {
+ case 1: //Enable
+ pAd->CommonCfg.bEnableHSCounter = TRUE;
+ break;
+ case 0: //Disable
+ default:
+ pAd->CommonCfg.bEnableHSCounter = FALSE;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, "HSCounter=%d\n", pAd->CommonCfg.bEnableHSCounter);
+ }*/
+
+#ifdef DOT11_N_SUPPORT
+ HTParametersHook(pAd, tmpbuf, buffer);
+#endif // DOT11_N_SUPPORT //
+
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ //CarrierDetect
+ if(RTMPGetKeyParameter("CarrierDetect", tmpbuf, 128, buffer))
+ {
+ if ((strncmp(tmpbuf, "0", 1) == 0))
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+ else if ((strncmp(tmpbuf, "1", 1) == 0))
+ pAd->CommonCfg.CarrierDetect.Enable = TRUE;
+ else
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CarrierDetect.Enable=%d\n", pAd->CommonCfg.CarrierDetect.Enable));
+ }
+ else
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ //PSMode
+ if (RTMPGetKeyParameter("PSMode", tmpbuf, 10, buffer))
+ {
+ if (pAd->StaCfg.BssType == BSS_INFRA)
+ {
+ if ((strcmp(tmpbuf, "MAX_PSP") == 0) || (strcmp(tmpbuf, "max_psp") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ // MlmeSetPsm(pAd, PWR_SAVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
+ pAd->StaCfg.DefaultListenCount = 5;
+ }
+ else if ((strcmp(tmpbuf, "Fast_PSP") == 0) || (strcmp(tmpbuf, "fast_psp") == 0)
+ || (strcmp(tmpbuf, "FAST_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ // MlmeSetPsmBit(pAd, PWR_SAVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAd->StaCfg.DefaultListenCount = 3;
+ }
+ else if ((strcmp(tmpbuf, "Legacy_PSP") == 0) || (strcmp(tmpbuf, "legacy_psp") == 0)
+ || (strcmp(tmpbuf, "LEGACY_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ // MlmeSetPsmBit(pAd, PWR_SAVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAd->StaCfg.DefaultListenCount = 3;
+ }
+ else
+ { //Default Ndis802_11PowerModeCAM
+ // clear PSM bit immediately
+ MlmeSetPsmBit(pAd, PWR_ACTIVE);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM);
+ if (pAd->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAd->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+ pAd->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("PSMode=%ld\n", pAd->StaCfg.WindowsPowerMode));
+ }
+ }
+ // FastRoaming
+ if (RTMPGetKeyParameter("FastRoaming", tmpbuf, 32, buffer))
+ {
+ if (simple_strtol(tmpbuf, 0, 10) == 0)
+ pAd->StaCfg.bFastRoaming = FALSE;
+ else
+ pAd->StaCfg.bFastRoaming = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("FastRoaming=%d\n", pAd->StaCfg.bFastRoaming));
+ }
+ // RoamThreshold
+ if (RTMPGetKeyParameter("RoamThreshold", tmpbuf, 32, buffer))
+ {
+ long lInfo = simple_strtol(tmpbuf, 0, 10);
+
+ if (lInfo > 90 || lInfo < 60)
+ pAd->StaCfg.dBmToRoam = -70;
+ else
+ pAd->StaCfg.dBmToRoam = (CHAR)(-1)*lInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RoamThreshold=%d dBm\n", pAd->StaCfg.dBmToRoam));
+ }
+
+ if(RTMPGetKeyParameter("TGnWifiTest", tmpbuf, 10, buffer))
+ {
+ if(simple_strtol(tmpbuf, 0, 10) == 0)
+ pAd->StaCfg.bTGnWifiTest = FALSE;
+ else
+ pAd->StaCfg.bTGnWifiTest = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("TGnWifiTest=%d\n", pAd->StaCfg.bTGnWifiTest));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+
+
+#ifdef RT30xx
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ if(RTMPGetKeyParameter("AntDiversity", tmpbuf, 10, buffer))
+ {
+ for (i = 0, macptr = rstrtok(tmpbuf,";"); macptr; macptr = rstrtok(NULL,";"), i++)
+ {
+ if(simple_strtol(macptr, 0, 10) != 0) //Enable
+ pAd->CommonCfg.bRxAntDiversity = TRUE;
+ else //Disable
+ pAd->CommonCfg.bRxAntDiversity = FALSE;
+
+ DBGPRINT(RT_DEBUG_ERROR, ("AntDiversity=%d\n", pAd->CommonCfg.bRxAntDiversity));
+ }
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+#endif // RT30xx //
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> %s does not have a write method\n", src));
+ }
+
+ retval=filp_close(srcf,NULL);
+
+ if (retval)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("--> Error %d closing %s\n", -retval, src));
+ }
+ }
+ }
+
+ set_fs(orgfs);
+#if 0
+ current->fsuid = orgfsuid;
+ current->fsgid = orgfsgid;
+#endif
+
+ kfree(buffer);
+ kfree(tmpbuf);
+
+ return (NDIS_STATUS_SUCCESS);
+}
+
+#ifdef DOT11_N_SUPPORT
+static void HTParametersHook(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR *pValueStr,
+ IN CHAR *pInput)
+{
+
+ INT Value;
+
+ if (RTMPGetKeyParameter("HT_PROTECT", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bHTProtect = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bHTProtect = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Protection = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ if (RTMPGetKeyParameter("HT_MIMOPSEnable", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bMIMOPSEnable = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bMIMOPSEnable = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPSEnable = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+
+ if (RTMPGetKeyParameter("HT_MIMOPSMode", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value > MMPS_ENABLE)
+ {
+ pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+ }
+ else
+ {
+ //TODO: add mimo power saving mechanism
+ pAd->CommonCfg.BACapability.field.MMPSmode = MMPS_ENABLE;
+ //pAd->CommonCfg.BACapability.field.MMPSmode = Value;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MIMOPS Mode = %d\n", Value));
+ }
+
+ if (RTMPGetKeyParameter("HT_BADecline", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bBADecline = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bBADecline = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Decline = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+
+ if (RTMPGetKeyParameter("HT_DisableReordering", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bDisableReordering = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bDisableReordering = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: DisableReordering = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ if (RTMPGetKeyParameter("HT_AutoBA", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = FALSE;
+ pAd->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.AutoBA = TRUE;
+ pAd->CommonCfg.BACapability.field.Policy = IMMED_BA;
+ }
+ pAd->CommonCfg.REGBACapability.field.AutoBA = pAd->CommonCfg.BACapability.field.AutoBA;
+ pAd->CommonCfg.REGBACapability.field.Policy = pAd->CommonCfg.BACapability.field.Policy;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Auto BA = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ // Tx_+HTC frame
+ if (RTMPGetKeyParameter("HT_HTC", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->HTCEnable = FALSE;
+ }
+ else
+ {
+ pAd->HTCEnable = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx +HTC frame = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ // Enable HT Link Adaptation Control
+ if (RTMPGetKeyParameter("HT_LinkAdapt", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->bLinkAdapt = FALSE;
+ }
+ else
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->bLinkAdapt = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Link Adaptation Control = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+ }
+
+ // Reverse Direction Mechanism
+ if (RTMPGetKeyParameter("HT_RDG", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bRdg = FALSE;
+ }
+ else
+ {
+ pAd->HTCEnable = TRUE;
+ pAd->CommonCfg.bRdg = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: RDG = %s\n", (Value==0) ? "Disable" : "Enable(+HTC)"));
+ }
+
+
+
+
+ // Tx A-MSUD ?
+ if (RTMPGetKeyParameter("HT_AMSDU", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.BACapability.field.AmsduEnable = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.AmsduEnable = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx A-MSDU = %s\n", (Value==0) ? "Disable" : "Enable"));
+ }
+
+ // MPDU Density
+ if (RTMPGetKeyParameter("HT_MpduDensity", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value <=7 && Value >= 0)
+ {
+ pAd->CommonCfg.BACapability.field.MpduDensity = Value;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d\n", Value));
+ }
+ else
+ {
+ pAd->CommonCfg.BACapability.field.MpduDensity = 4;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MPDU Density = %d (Default)\n", 4));
+ }
+ }
+
+ // Max Rx BA Window Size
+ if (RTMPGetKeyParameter("HT_BAWinSize", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value >=1 && Value <= 64)
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = Value;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = Value;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = %d\n", Value));
+ }
+ else
+ {
+ pAd->CommonCfg.REGBACapability.field.RxBAWinLimit = 64;
+ pAd->CommonCfg.BACapability.field.RxBAWinLimit = 64;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: BA Windw Size = 64 (Defualt)\n"));
+ }
+
+ }
+
+ // Guard Interval
+ if (RTMPGetKeyParameter("HT_GI", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == GI_400)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_400;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.ShortGI = GI_800;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Guard Interval = %s\n", (Value==GI_400) ? "400" : "800" ));
+ }
+
+ // HT Operation Mode : Mixed Mode , Green Field
+ if (RTMPGetKeyParameter("HT_OpMode", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == HTMODE_GF)
+ {
+
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_GF;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.HTMODE = HTMODE_MM;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Operate Mode = %s\n", (Value==HTMODE_GF) ? "Green Field" : "Mixed Mode" ));
+ }
+
+ // Fixed Tx mode : CCK, OFDM
+ if (RTMPGetKeyParameter("FixedTxMode", pValueStr, 25, pInput))
+ {
+ UCHAR fix_tx_mode;
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ fix_tx_mode = FIXED_TXMODE_HT;
+
+ if (strcmp(pValueStr, "OFDM") == 0 || strcmp(pValueStr, "ofdm") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_OFDM;
+ }
+ else if (strcmp(pValueStr, "CCK") == 0 || strcmp(pValueStr, "cck") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_CCK;
+ }
+ else if (strcmp(pValueStr, "HT") == 0 || strcmp(pValueStr, "ht") == 0)
+ {
+ fix_tx_mode = FIXED_TXMODE_HT;
+ }
+ else
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ // 1 : CCK
+ // 2 : OFDM
+ // otherwise : HT
+ if (Value == FIXED_TXMODE_CCK || Value == FIXED_TXMODE_OFDM)
+ fix_tx_mode = Value;
+ else
+ fix_tx_mode = FIXED_TXMODE_HT;
+ }
+
+ pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode = fix_tx_mode;
+ DBGPRINT(RT_DEBUG_TRACE, ("Fixed Tx Mode = %d\n", fix_tx_mode));
+
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+
+ // Channel Width
+ if (RTMPGetKeyParameter("HT_BW", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == BW_40)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_40;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.BW = BW_20;
+ }
+
+#ifdef MCAST_RATE_SPECIFIC
+ pAd->CommonCfg.MCastPhyMode.field.BW = pAd->CommonCfg.RegTransmitSetting.field.BW;
+#endif // MCAST_RATE_SPECIFIC //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Channel Width = %s\n", (Value==BW_40) ? "40 MHz" : "20 MHz" ));
+ }
+
+ if (RTMPGetKeyParameter("HT_EXTCHA", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+ if (Value == 0)
+ {
+
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_BELOW;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.EXTCHA = EXTCHA_ABOVE;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Ext Channel = %s\n", (Value==0) ? "BELOW" : "ABOVE" ));
+ }
+
+ // MSC
+ if (RTMPGetKeyParameter("HT_MCS", pValueStr, 50, pInput))
+ {
+
+#ifdef CONFIG_STA_SUPPORT
+ IF_DEV_CONFIG_OPMODE_ON_STA(pAd)
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+
+// if ((Value >= 0 && Value <= 15) || (Value == 32))
+ if ((Value >= 0 && Value <= 23) || (Value == 32)) // 3*3
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = Value;
+ pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = %d\n", pAd->StaCfg.DesiredTransmitSetting.field.MCS));
+ }
+ else
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: MCS = AUTO\n"));
+ }
+ }
+#endif // CONFIG_STA_SUPPORT //
+ }
+
+ // STBC
+ if (RTMPGetKeyParameter("HT_STBC", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == STBC_USE)
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_USE;
+ }
+ else
+ {
+ pAd->CommonCfg.RegTransmitSetting.field.STBC = STBC_NONE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: STBC = %d\n", pAd->CommonCfg.RegTransmitSetting.field.STBC));
+ }
+
+ // 40_Mhz_Intolerant
+ if (RTMPGetKeyParameter("HT_40MHZ_INTOLERANT", pValueStr, 25, pInput))
+ {
+ Value = simple_strtol(pValueStr, 0, 10);
+ if (Value == 0)
+ {
+ pAd->CommonCfg.bForty_Mhz_Intolerant = FALSE;
+ }
+ else
+ {
+ pAd->CommonCfg.bForty_Mhz_Intolerant = TRUE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: 40MHZ INTOLERANT = %d\n", pAd->CommonCfg.bForty_Mhz_Intolerant));
+ }
+ //HT_TxStream
+ if(RTMPGetKeyParameter("HT_TxStream", pValueStr, 10, pInput))
+ {
+ switch (simple_strtol(pValueStr, 0, 10))
+ {
+ case 1:
+ pAd->CommonCfg.TxStream = 1;
+ break;
+ case 2:
+ pAd->CommonCfg.TxStream = 2;
+ break;
+ case 3: // 3*3
+ default:
+ pAd->CommonCfg.TxStream = 3;
+
+ if (pAd->MACVersion < RALINK_2883_VERSION)
+ pAd->CommonCfg.TxStream = 2; // only 2 tx streams for RT2860 series
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Tx Stream = %d\n", pAd->CommonCfg.TxStream));
+ }
+ //HT_RxStream
+ if(RTMPGetKeyParameter("HT_RxStream", pValueStr, 10, pInput))
+ {
+ switch (simple_strtol(pValueStr, 0, 10))
+ {
+ case 1:
+ pAd->CommonCfg.RxStream = 1;
+ break;
+ case 2:
+ pAd->CommonCfg.RxStream = 2;
+ break;
+ case 3:
+ default:
+ pAd->CommonCfg.RxStream = 3;
+
+ if (pAd->MACVersion < RALINK_2883_VERSION)
+ pAd->CommonCfg.RxStream = 2; // only 2 rx streams for RT2860 series
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("HT: Rx Stream = %d\n", pAd->CommonCfg.RxStream));
+ }
+
+}
+#endif // DOT11_N_SUPPORT //
+
diff --git a/drivers/staging/rt3070/rtmp.h b/drivers/staging/rt3070/rtmp.h
new file mode 100644
index 00000000000..d80d74ffbc8
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp.h
@@ -0,0 +1,7728 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp.h
+
+ Abstract:
+ Miniport generic portion header file
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 2002-08-01 created
+ James Tan 2002-09-06 modified (Revise NTCRegTable)
+ John Chang 2004-09-06 modified for RT2600
+*/
+#ifndef __RTMP_H__
+#define __RTMP_H__
+
+#include "link_list.h"
+#include "spectrum_def.h"
+
+#ifdef MLME_EX
+#include "mlme_ex_def.h"
+#endif // MLME_EX //
+
+#ifdef CONFIG_STA_SUPPORT
+#include "aironet.h"
+#endif // CONFIG_STA_SUPPORT //
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+
+
+
+
+
+//#define DBG 1
+
+//#define DBG_DIAGNOSE 1
+
+#if defined(CONFIG_AP_SUPPORT) && defined(CONFIG_STA_SUPPORT)
+#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd) if(_pAd->OpMode == OPMODE_AP)
+#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd) if(_pAd->OpMode == OPMODE_STA)
+#else
+#define IF_DEV_CONFIG_OPMODE_ON_AP(_pAd)
+#define IF_DEV_CONFIG_OPMODE_ON_STA(_pAd)
+#endif
+
+#define VIRTUAL_IF_INC(__pAd) ((__pAd)->VirtualIfCnt++)
+#define VIRTUAL_IF_DEC(__pAd) ((__pAd)->VirtualIfCnt--)
+#define VIRTUAL_IF_NUM(__pAd) ((__pAd)->VirtualIfCnt)
+
+#ifdef RT2870
+////////////////////////////////////////////////////////////////////////////
+// The TX_BUFFER structure forms the transmitted USB packet to the device
+////////////////////////////////////////////////////////////////////////////
+typedef struct __TX_BUFFER{
+ union {
+ UCHAR WirelessPacket[TX_BUFFER_NORMSIZE];
+ HEADER_802_11 NullFrame;
+ PSPOLL_FRAME PsPollPacket;
+ RTS_FRAME RTSFrame;
+ }field;
+ UCHAR Aggregation[4]; //Buffer for save Aggregation size.
+} TX_BUFFER, *PTX_BUFFER;
+
+typedef struct __HTTX_BUFFER{
+ union {
+ UCHAR WirelessPacket[MAX_TXBULK_SIZE];
+ HEADER_802_11 NullFrame;
+ PSPOLL_FRAME PsPollPacket;
+ RTS_FRAME RTSFrame;
+ }field;
+ UCHAR Aggregation[4]; //Buffer for save Aggregation size.
+} HTTX_BUFFER, *PHTTX_BUFFER;
+
+
+// used to track driver-generated write irps
+typedef struct _TX_CONTEXT
+{
+ PVOID pAd; //Initialized in MiniportInitialize
+ PURB pUrb; //Initialized in MiniportInitialize
+ PIRP pIrp; //used to cancel pending bulk out.
+ //Initialized in MiniportInitialize
+ PTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
+ ULONG BulkOutSize;
+ UCHAR BulkOutPipeId;
+ UCHAR SelfIdx;
+ BOOLEAN InUse;
+ BOOLEAN bWaitingBulkOut; // at least one packet is in this TxContext, ready for making IRP anytime.
+ BOOLEAN bFullForBulkOut; // all tx buffer are full , so waiting for tx bulkout.
+ BOOLEAN IRPPending;
+ BOOLEAN LastOne;
+ BOOLEAN bAggregatible;
+ UCHAR Header_802_3[LENGTH_802_3];
+ UCHAR Rsv[2];
+ ULONG DataOffset;
+ UINT TxRate;
+ dma_addr_t data_dma; // urb dma on linux
+
+} TX_CONTEXT, *PTX_CONTEXT, **PPTX_CONTEXT;
+
+
+// used to track driver-generated write irps
+typedef struct _HT_TX_CONTEXT
+{
+ PVOID pAd; //Initialized in MiniportInitialize
+ PURB pUrb; //Initialized in MiniportInitialize
+ PIRP pIrp; //used to cancel pending bulk out.
+ //Initialized in MiniportInitialize
+ PHTTX_BUFFER TransferBuffer; //Initialized in MiniportInitialize
+ ULONG BulkOutSize; // Indicate the total bulk-out size in bytes in one bulk-transmission
+ UCHAR BulkOutPipeId;
+ BOOLEAN IRPPending;
+ BOOLEAN LastOne;
+ BOOLEAN bCurWriting;
+ BOOLEAN bRingEmpty;
+ BOOLEAN bCopySavePad;
+ UCHAR SavedPad[8];
+ UCHAR Header_802_3[LENGTH_802_3];
+ ULONG CurWritePosition; // Indicate the buffer offset which packet will be inserted start from.
+ ULONG CurWriteRealPos; // Indicate the buffer offset which packet now are writing to.
+ ULONG NextBulkOutPosition; // Indicate the buffer start offset of a bulk-transmission
+ ULONG ENextBulkOutPosition; // Indicate the buffer end offset of a bulk-transmission
+ UINT TxRate;
+ dma_addr_t data_dma; // urb dma on linux
+} HT_TX_CONTEXT, *PHT_TX_CONTEXT, **PPHT_TX_CONTEXT;
+
+
+//
+// Structure to keep track of receive packets and buffers to indicate
+// receive data to the protocol.
+//
+typedef struct _RX_CONTEXT
+{
+ PUCHAR TransferBuffer;
+ PVOID pAd;
+ PIRP pIrp;//used to cancel pending bulk in.
+ PURB pUrb;
+ //These 2 Boolean shouldn't both be 1 at the same time.
+ ULONG BulkInOffset; // number of packets waiting for reordering .
+// BOOLEAN ReorderInUse; // At least one packet in this buffer are in reordering buffer and wait for receive indication
+ BOOLEAN bRxHandling; // Notify this packet is being process now.
+ BOOLEAN InUse; // USB Hardware Occupied. Wait for USB HW to put packet.
+ BOOLEAN Readable; // Receive Complete back. OK for driver to indicate receiving packet.
+ BOOLEAN IRPPending; // TODO: To be removed
+ atomic_t IrpLock;
+ NDIS_SPIN_LOCK RxContextLock;
+ dma_addr_t data_dma; // urb dma on linux
+} RX_CONTEXT, *PRX_CONTEXT;
+#endif // RT2870 //
+
+
+//
+// NDIS Version definitions
+//
+#ifdef NDIS50_MINIPORT
+#define RTMP_NDIS_MAJOR_VERSION 5
+#define RTMP_NDIS_MINOR_VERSION 0
+#endif
+
+#ifdef NDIS51_MINIPORT
+#define RTMP_NDIS_MAJOR_VERSION 5
+#define RTMP_NDIS_MINOR_VERSION 1
+#endif
+
+extern char NIC_VENDOR_DESC[];
+extern int NIC_VENDOR_DESC_LEN;
+
+extern unsigned char SNAP_AIRONET[];
+extern unsigned char CipherSuiteCiscoCCKM[];
+extern unsigned char CipherSuiteCiscoCCKMLen;
+extern unsigned char CipherSuiteCiscoCCKM24[];
+extern unsigned char CipherSuiteCiscoCCKM24Len;
+extern unsigned char CipherSuiteCCXTkip[];
+extern unsigned char CipherSuiteCCXTkipLen;
+extern unsigned char CISCO_OUI[];
+extern UCHAR BaSizeArray[4];
+
+extern UCHAR BROADCAST_ADDR[MAC_ADDR_LEN];
+extern UCHAR MULTICAST_ADDR[MAC_ADDR_LEN];
+extern UCHAR ZERO_MAC_ADDR[MAC_ADDR_LEN];
+extern ULONG BIT32[32];
+extern UCHAR BIT8[8];
+extern char* CipherName[];
+extern char* MCSToMbps[];
+extern UCHAR RxwiMCSToOfdmRate[12];
+extern UCHAR SNAP_802_1H[6];
+extern UCHAR SNAP_BRIDGE_TUNNEL[6];
+extern UCHAR SNAP_AIRONET[8];
+extern UCHAR CKIP_LLC_SNAP[8];
+extern UCHAR EAPOL_LLC_SNAP[8];
+extern UCHAR EAPOL[2];
+extern UCHAR IPX[2];
+extern UCHAR APPLE_TALK[2];
+extern UCHAR RateIdToPlcpSignal[12]; // see IEEE802.11a-1999 p.14
+extern UCHAR OfdmRateToRxwiMCS[];
+extern UCHAR OfdmSignalToRateId[16] ;
+extern UCHAR default_cwmin[4];
+extern UCHAR default_cwmax[4];
+extern UCHAR default_sta_aifsn[4];
+extern UCHAR MapUserPriorityToAccessCategory[8];
+
+extern USHORT RateUpPER[];
+extern USHORT RateDownPER[];
+extern UCHAR Phy11BNextRateDownward[];
+extern UCHAR Phy11BNextRateUpward[];
+extern UCHAR Phy11BGNextRateDownward[];
+extern UCHAR Phy11BGNextRateUpward[];
+extern UCHAR Phy11ANextRateDownward[];
+extern UCHAR Phy11ANextRateUpward[];
+extern CHAR RssiSafeLevelForTxRate[];
+extern UCHAR RateIdToMbps[];
+extern USHORT RateIdTo500Kbps[];
+
+extern UCHAR CipherSuiteWpaNoneTkip[];
+extern UCHAR CipherSuiteWpaNoneTkipLen;
+
+extern UCHAR CipherSuiteWpaNoneAes[];
+extern UCHAR CipherSuiteWpaNoneAesLen;
+
+extern UCHAR SsidIe;
+extern UCHAR SupRateIe;
+extern UCHAR ExtRateIe;
+
+#ifdef DOT11_N_SUPPORT
+extern UCHAR HtCapIe;
+extern UCHAR AddHtInfoIe;
+extern UCHAR NewExtChanIe;
+#ifdef DOT11N_DRAFT3
+extern UCHAR ExtHtCapIe;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+extern UCHAR ErpIe;
+extern UCHAR DsIe;
+extern UCHAR TimIe;
+extern UCHAR WpaIe;
+extern UCHAR Wpa2Ie;
+extern UCHAR IbssIe;
+extern UCHAR Ccx2Ie;
+extern UCHAR WapiIe;
+
+extern UCHAR WPA_OUI[];
+extern UCHAR RSN_OUI[];
+extern UCHAR WAPI_OUI[];
+extern UCHAR WME_INFO_ELEM[];
+extern UCHAR WME_PARM_ELEM[];
+extern UCHAR Ccx2QosInfo[];
+extern UCHAR Ccx2IeInfo[];
+extern UCHAR RALINK_OUI[];
+extern UCHAR PowerConstraintIE[];
+
+
+extern UCHAR RateSwitchTable[];
+extern UCHAR RateSwitchTable11B[];
+extern UCHAR RateSwitchTable11G[];
+extern UCHAR RateSwitchTable11BG[];
+
+#ifdef DOT11_N_SUPPORT
+extern UCHAR RateSwitchTable11BGN1S[];
+extern UCHAR RateSwitchTable11BGN2S[];
+extern UCHAR RateSwitchTable11BGN2SForABand[];
+extern UCHAR RateSwitchTable11N1S[];
+extern UCHAR RateSwitchTable11N2S[];
+extern UCHAR RateSwitchTable11N2SForABand[];
+
+#ifdef CONFIG_STA_SUPPORT
+extern UCHAR PRE_N_HT_OUI[];
+#endif // CONFIG_STA_SUPPORT //
+#endif // DOT11_N_SUPPORT //
+
+#define MAXSEQ (0xFFF)
+
+#ifdef RALINK_ATE
+typedef struct _ATE_INFO {
+ UCHAR Mode;
+ CHAR TxPower0;
+ CHAR TxPower1;
+ CHAR TxAntennaSel;
+ CHAR RxAntennaSel;
+ TXWI_STRUC TxWI; // TXWI
+ USHORT QID;
+ UCHAR Addr1[MAC_ADDR_LEN];
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR Addr3[MAC_ADDR_LEN];
+ UCHAR Channel;
+ UINT32 TxLength;
+ UINT32 TxCount;
+ UINT32 TxDoneCount; // Tx DMA Done
+ UINT32 RFFreqOffset;
+ BOOLEAN bRxFer;
+ BOOLEAN bQATxStart; // Have compiled QA in and use it to ATE tx.
+ BOOLEAN bQARxStart; // Have compiled QA in and use it to ATE rx.
+ UINT32 RxTotalCnt;
+ UINT32 RxCntPerSec;
+
+ CHAR LastSNR0; // last received SNR
+ CHAR LastSNR1; // last received SNR for 2nd antenna
+ CHAR LastRssi0; // last received RSSI
+ CHAR LastRssi1; // last received RSSI for 2nd antenna
+ CHAR LastRssi2; // last received RSSI for 3rd antenna
+ CHAR AvgRssi0; // last 8 frames' average RSSI
+ CHAR AvgRssi1; // last 8 frames' average RSSI
+ CHAR AvgRssi2; // last 8 frames' average RSSI
+ SHORT AvgRssi0X8; // sum of last 8 frames' RSSI
+ SHORT AvgRssi1X8; // sum of last 8 frames' RSSI
+ SHORT AvgRssi2X8; // sum of last 8 frames' RSSI
+
+ UINT32 NumOfAvgRssiSample;
+
+#ifdef RALINK_28xx_QA
+ // Tx frame
+#ifdef RT2870
+ /* not used in RT2860 */
+ TXINFO_STRUC TxInfo; // TxInfo
+#endif // RT2870 //
+ USHORT HLen; // Header Length
+ USHORT PLen; // Pattern Length
+ UCHAR Header[32]; // Header buffer
+ UCHAR Pattern[32]; // Pattern buffer
+ USHORT DLen; // Data Length
+ USHORT seq;
+ UINT32 CID;
+ pid_t AtePid;
+ // counters
+ UINT32 U2M;
+ UINT32 OtherData;
+ UINT32 Beacon;
+ UINT32 OtherCount;
+ UINT32 TxAc0;
+ UINT32 TxAc1;
+ UINT32 TxAc2;
+ UINT32 TxAc3;
+ UINT32 TxHCCA;
+ UINT32 TxMgmt;
+ UINT32 RSSI0;
+ UINT32 RSSI1;
+ UINT32 RSSI2;
+ UINT32 SNR0;
+ UINT32 SNR1;
+ // control
+ //UINT32 Repeat; // Tx Cpu count
+ UCHAR TxStatus; // task Tx status // 0 --> task is idle, 1 --> task is running
+#endif // RALINK_28xx_QA //
+} ATE_INFO, *PATE_INFO;
+
+#ifdef RALINK_28xx_QA
+struct ate_racfghdr {
+ UINT32 magic_no;
+ USHORT command_type;
+ USHORT command_id;
+ USHORT length;
+ USHORT sequence;
+ USHORT status;
+ UCHAR data[2046];
+} __attribute__((packed));
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+struct reordering_mpdu
+{
+ struct reordering_mpdu *next;
+ PNDIS_PACKET pPacket; /* coverted to 802.3 frame */
+ int Sequence; /* sequence number of MPDU */
+ BOOLEAN bAMSDU;
+};
+
+struct reordering_list
+{
+ struct reordering_mpdu *next;
+ int qlen;
+};
+
+struct reordering_mpdu_pool
+{
+ PVOID mem;
+ NDIS_SPIN_LOCK lock;
+ struct reordering_list freelist;
+};
+#endif // DOT11_N_SUPPORT //
+
+typedef struct _RSSI_SAMPLE {
+ CHAR LastRssi0; // last received RSSI
+ CHAR LastRssi1; // last received RSSI
+ CHAR LastRssi2; // last received RSSI
+ CHAR AvgRssi0;
+ CHAR AvgRssi1;
+ CHAR AvgRssi2;
+ SHORT AvgRssi0X8;
+ SHORT AvgRssi1X8;
+ SHORT AvgRssi2X8;
+} RSSI_SAMPLE;
+
+//
+// Queue structure and macros
+//
+typedef struct _QUEUE_ENTRY {
+ struct _QUEUE_ENTRY *Next;
+} QUEUE_ENTRY, *PQUEUE_ENTRY;
+
+// Queue structure
+typedef struct _QUEUE_HEADER {
+ PQUEUE_ENTRY Head;
+ PQUEUE_ENTRY Tail;
+ ULONG Number;
+} QUEUE_HEADER, *PQUEUE_HEADER;
+
+#define InitializeQueueHeader(QueueHeader) \
+{ \
+ (QueueHeader)->Head = (QueueHeader)->Tail = NULL; \
+ (QueueHeader)->Number = 0; \
+}
+
+#define RemoveHeadQueue(QueueHeader) \
+(QueueHeader)->Head; \
+{ \
+ PQUEUE_ENTRY pNext; \
+ if ((QueueHeader)->Head != NULL) \
+ { \
+ pNext = (QueueHeader)->Head->Next; \
+ (QueueHeader)->Head = pNext; \
+ if (pNext == NULL) \
+ (QueueHeader)->Tail = NULL; \
+ (QueueHeader)->Number--; \
+ } \
+}
+
+#define InsertHeadQueue(QueueHeader, QueueEntry) \
+{ \
+ ((PQUEUE_ENTRY)QueueEntry)->Next = (QueueHeader)->Head; \
+ (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
+ if ((QueueHeader)->Tail == NULL) \
+ (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
+ (QueueHeader)->Number++; \
+}
+
+#define InsertTailQueue(QueueHeader, QueueEntry) \
+{ \
+ ((PQUEUE_ENTRY)QueueEntry)->Next = NULL; \
+ if ((QueueHeader)->Tail) \
+ (QueueHeader)->Tail->Next = (PQUEUE_ENTRY)(QueueEntry); \
+ else \
+ (QueueHeader)->Head = (PQUEUE_ENTRY)(QueueEntry); \
+ (QueueHeader)->Tail = (PQUEUE_ENTRY)(QueueEntry); \
+ (QueueHeader)->Number++; \
+}
+
+//
+// Macros for flag and ref count operations
+//
+#define RTMP_SET_FLAG(_M, _F) ((_M)->Flags |= (_F))
+#define RTMP_CLEAR_FLAG(_M, _F) ((_M)->Flags &= ~(_F))
+#define RTMP_CLEAR_FLAGS(_M) ((_M)->Flags = 0)
+#define RTMP_TEST_FLAG(_M, _F) (((_M)->Flags & (_F)) != 0)
+#define RTMP_TEST_FLAGS(_M, _F) (((_M)->Flags & (_F)) == (_F))
+
+#define OPSTATUS_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags |= (_F))
+#define OPSTATUS_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.OpStatusFlags &= ~(_F))
+#define OPSTATUS_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.OpStatusFlags & (_F)) != 0)
+
+#define CLIENT_STATUS_SET_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags |= (_F))
+#define CLIENT_STATUS_CLEAR_FLAG(_pEntry,_F) ((_pEntry)->ClientStatusFlags &= ~(_F))
+#define CLIENT_STATUS_TEST_FLAG(_pEntry,_F) (((_pEntry)->ClientStatusFlags & (_F)) != 0)
+
+#define RX_FILTER_SET_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter |= (_F))
+#define RX_FILTER_CLEAR_FLAG(_pAd, _F) ((_pAd)->CommonCfg.PacketFilter &= ~(_F))
+#define RX_FILTER_TEST_FLAG(_pAd, _F) (((_pAd)->CommonCfg.PacketFilter & (_F)) != 0)
+
+#ifdef CONFIG_STA_SUPPORT
+#define STA_NO_SECURITY_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
+#define STA_WEP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption1Enabled)
+#define STA_TKIP_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+#define STA_AES_ON(_p) (_p->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+
+#define STA_TGN_WIFI_ON(_p) (_p->StaCfg.bTGnWifiTest == TRUE)
+#endif // CONFIG_STA_SUPPORT //
+
+#define CKIP_KP_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x10) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
+#define CKIP_CMIC_ON(_p) ((((_p)->StaCfg.CkipFlag) & 0x08) && ((_p)->StaCfg.bCkipCmicOn == TRUE))
+
+
+#define INC_RING_INDEX(_idx, _RingSize) \
+{ \
+ (_idx) = (_idx+1) % (_RingSize); \
+}
+
+// We will have a cost down version which mac version is 0x3090xxxx
+#define IS_RT3090(_pAd) ((((_pAd)->MACVersion & 0xffff0000) == 0x30710000) || (((_pAd)->MACVersion & 0xffff0000) == 0x30900000))
+
+#define IS_RT3070(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30700000)
+#define IS_RT3071(_pAd) (((_pAd)->MACVersion & 0xffff0000) == 0x30710000)
+#define IS_RT2070(_pAd) (((_pAd)->RfIcType == RFIC_2020) || ((_pAd)->EFuseTag == 0x27))
+
+#define IS_RT30xx(_pAd) (((_pAd)->MACVersion & 0xfff00000) == 0x30700000)
+
+#define RING_PACKET_INIT(_TxRing, _idx) \
+{ \
+ _TxRing->Cell[_idx].pNdisPacket = NULL; \
+ _TxRing->Cell[_idx].pNextNdisPacket = NULL; \
+}
+
+#define TXDT_INIT(_TxD) \
+{ \
+ NdisZeroMemory(_TxD, TXD_SIZE); \
+ _TxD->DMADONE = 1; \
+}
+
+//Set last data segment
+#define RING_SET_LASTDS(_TxD, _IsSD0) \
+{ \
+ if (_IsSD0) {_TxD->LastSec0 = 1;} \
+ else {_TxD->LastSec1 = 1;} \
+}
+
+// Increase TxTsc value for next transmission
+// TODO:
+// When i==6, means TSC has done one full cycle, do re-keying stuff follow specs
+// Should send a special event microsoft defined to request re-key
+#define INC_TX_TSC(_tsc) \
+{ \
+ int i=0; \
+ while (++_tsc[i] == 0x0) \
+ { \
+ i++; \
+ if (i == 6) \
+ break; \
+ } \
+}
+
+#ifdef DOT11_N_SUPPORT
+// StaActive.SupportedHtPhy.MCSSet is copied from AP beacon. Don't need to update here.
+#define COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
+{ \
+ _pAd->StaActive.SupportedHtPhy.ChannelWidth = _pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth; \
+ _pAd->StaActive.SupportedHtPhy.MimoPs = _pAd->MlmeAux.HtCapability.HtCapInfo.MimoPs; \
+ _pAd->StaActive.SupportedHtPhy.GF = _pAd->MlmeAux.HtCapability.HtCapInfo.GF; \
+ _pAd->StaActive.SupportedHtPhy.ShortGIfor20 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor20; \
+ _pAd->StaActive.SupportedHtPhy.ShortGIfor40 = _pAd->MlmeAux.HtCapability.HtCapInfo.ShortGIfor40; \
+ _pAd->StaActive.SupportedHtPhy.TxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.TxSTBC; \
+ _pAd->StaActive.SupportedHtPhy.RxSTBC = _pAd->MlmeAux.HtCapability.HtCapInfo.RxSTBC; \
+ _pAd->StaActive.SupportedHtPhy.ExtChanOffset = _pAd->MlmeAux.AddHtInfo.AddHtInfo.ExtChanOffset; \
+ _pAd->StaActive.SupportedHtPhy.RecomWidth = _pAd->MlmeAux.AddHtInfo.AddHtInfo.RecomWidth; \
+ _pAd->StaActive.SupportedHtPhy.OperaionMode = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode; \
+ _pAd->StaActive.SupportedHtPhy.NonGfPresent = _pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent; \
+ NdisMoveMemory((_pAd)->MacTab.Content[BSSID_WCID].HTCapability.MCSSet, (_pAd)->StaActive.SupportedPhyInfo.MCSSet, sizeof(UCHAR) * 16);\
+}
+
+#define COPY_AP_HTSETTINGS_FROM_BEACON(_pAd, _pHtCapability) \
+{ \
+ _pAd->MacTab.Content[BSSID_WCID].AMsduSize = (UCHAR)(_pHtCapability->HtCapInfo.AMsduSize); \
+ _pAd->MacTab.Content[BSSID_WCID].MmpsMode= (UCHAR)(_pHtCapability->HtCapInfo.MimoPs); \
+ _pAd->MacTab.Content[BSSID_WCID].MaxRAmpduFactor = (UCHAR)(_pHtCapability->HtCapParm.MaxRAmpduFactor); \
+}
+#endif // DOT11_N_SUPPORT //
+
+//
+// MACRO for 32-bit PCI register read / write
+//
+// Usage : RTMP_IO_READ32(
+// PRTMP_ADAPTER pAd,
+// ULONG Register_Offset,
+// PULONG pValue)
+//
+// RTMP_IO_WRITE32(
+// PRTMP_ADAPTER pAd,
+// ULONG Register_Offset,
+// ULONG Value)
+//
+
+//
+// BBP & RF are using indirect access. Before write any value into it.
+// We have to make sure there is no outstanding command pending via checking busy bit.
+//
+#define MAX_BUSY_COUNT 100 // Number of retry before failing access BBP & RF indirect register
+//
+
+#ifdef RT2870
+#define RTMP_RF_IO_WRITE32(_A, _V) RTUSBWriteRFRegister(_A, _V)
+#define RTMP_BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
+#define RTMP_BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
+
+#define BBP_IO_WRITE8_BY_REG_ID(_A, _I, _V) RTUSBWriteBBPRegister(_A, _I, _V)
+#define BBP_IO_READ8_BY_REG_ID(_A, _I, _pV) RTUSBReadBBPRegister(_A, _I, _pV)
+#endif // RT2870 //
+
+#ifdef RT30xx
+#define RTMP_RF_IO_READ8_BY_REG_ID(_A, _I, _pV) RT30xxReadRFRegister(_A, _I, _pV)
+#define RTMP_RF_IO_WRITE8_BY_REG_ID(_A, _I, _V) RT30xxWriteRFRegister(_A, _I, _V)
+#endif // RT30xx //
+
+#define MAP_CHANNEL_ID_TO_KHZ(ch, khz) { \
+ switch (ch) \
+ { \
+ case 1: khz = 2412000; break; \
+ case 2: khz = 2417000; break; \
+ case 3: khz = 2422000; break; \
+ case 4: khz = 2427000; break; \
+ case 5: khz = 2432000; break; \
+ case 6: khz = 2437000; break; \
+ case 7: khz = 2442000; break; \
+ case 8: khz = 2447000; break; \
+ case 9: khz = 2452000; break; \
+ case 10: khz = 2457000; break; \
+ case 11: khz = 2462000; break; \
+ case 12: khz = 2467000; break; \
+ case 13: khz = 2472000; break; \
+ case 14: khz = 2484000; break; \
+ case 36: /* UNII */ khz = 5180000; break; \
+ case 40: /* UNII */ khz = 5200000; break; \
+ case 44: /* UNII */ khz = 5220000; break; \
+ case 48: /* UNII */ khz = 5240000; break; \
+ case 52: /* UNII */ khz = 5260000; break; \
+ case 56: /* UNII */ khz = 5280000; break; \
+ case 60: /* UNII */ khz = 5300000; break; \
+ case 64: /* UNII */ khz = 5320000; break; \
+ case 149: /* UNII */ khz = 5745000; break; \
+ case 153: /* UNII */ khz = 5765000; break; \
+ case 157: /* UNII */ khz = 5785000; break; \
+ case 161: /* UNII */ khz = 5805000; break; \
+ case 165: /* UNII */ khz = 5825000; break; \
+ case 100: /* HiperLAN2 */ khz = 5500000; break; \
+ case 104: /* HiperLAN2 */ khz = 5520000; break; \
+ case 108: /* HiperLAN2 */ khz = 5540000; break; \
+ case 112: /* HiperLAN2 */ khz = 5560000; break; \
+ case 116: /* HiperLAN2 */ khz = 5580000; break; \
+ case 120: /* HiperLAN2 */ khz = 5600000; break; \
+ case 124: /* HiperLAN2 */ khz = 5620000; break; \
+ case 128: /* HiperLAN2 */ khz = 5640000; break; \
+ case 132: /* HiperLAN2 */ khz = 5660000; break; \
+ case 136: /* HiperLAN2 */ khz = 5680000; break; \
+ case 140: /* HiperLAN2 */ khz = 5700000; break; \
+ case 34: /* Japan MMAC */ khz = 5170000; break; \
+ case 38: /* Japan MMAC */ khz = 5190000; break; \
+ case 42: /* Japan MMAC */ khz = 5210000; break; \
+ case 46: /* Japan MMAC */ khz = 5230000; break; \
+ case 184: /* Japan */ khz = 4920000; break; \
+ case 188: /* Japan */ khz = 4940000; break; \
+ case 192: /* Japan */ khz = 4960000; break; \
+ case 196: /* Japan */ khz = 4980000; break; \
+ case 208: /* Japan, means J08 */ khz = 5040000; break; \
+ case 212: /* Japan, means J12 */ khz = 5060000; break; \
+ case 216: /* Japan, means J16 */ khz = 5080000; break; \
+ default: khz = 2412000; break; \
+ } \
+ }
+
+#define MAP_KHZ_TO_CHANNEL_ID(khz, ch) { \
+ switch (khz) \
+ { \
+ case 2412000: ch = 1; break; \
+ case 2417000: ch = 2; break; \
+ case 2422000: ch = 3; break; \
+ case 2427000: ch = 4; break; \
+ case 2432000: ch = 5; break; \
+ case 2437000: ch = 6; break; \
+ case 2442000: ch = 7; break; \
+ case 2447000: ch = 8; break; \
+ case 2452000: ch = 9; break; \
+ case 2457000: ch = 10; break; \
+ case 2462000: ch = 11; break; \
+ case 2467000: ch = 12; break; \
+ case 2472000: ch = 13; break; \
+ case 2484000: ch = 14; break; \
+ case 5180000: ch = 36; /* UNII */ break; \
+ case 5200000: ch = 40; /* UNII */ break; \
+ case 5220000: ch = 44; /* UNII */ break; \
+ case 5240000: ch = 48; /* UNII */ break; \
+ case 5260000: ch = 52; /* UNII */ break; \
+ case 5280000: ch = 56; /* UNII */ break; \
+ case 5300000: ch = 60; /* UNII */ break; \
+ case 5320000: ch = 64; /* UNII */ break; \
+ case 5745000: ch = 149; /* UNII */ break; \
+ case 5765000: ch = 153; /* UNII */ break; \
+ case 5785000: ch = 157; /* UNII */ break; \
+ case 5805000: ch = 161; /* UNII */ break; \
+ case 5825000: ch = 165; /* UNII */ break; \
+ case 5500000: ch = 100; /* HiperLAN2 */ break; \
+ case 5520000: ch = 104; /* HiperLAN2 */ break; \
+ case 5540000: ch = 108; /* HiperLAN2 */ break; \
+ case 5560000: ch = 112; /* HiperLAN2 */ break; \
+ case 5580000: ch = 116; /* HiperLAN2 */ break; \
+ case 5600000: ch = 120; /* HiperLAN2 */ break; \
+ case 5620000: ch = 124; /* HiperLAN2 */ break; \
+ case 5640000: ch = 128; /* HiperLAN2 */ break; \
+ case 5660000: ch = 132; /* HiperLAN2 */ break; \
+ case 5680000: ch = 136; /* HiperLAN2 */ break; \
+ case 5700000: ch = 140; /* HiperLAN2 */ break; \
+ case 5170000: ch = 34; /* Japan MMAC */ break; \
+ case 5190000: ch = 38; /* Japan MMAC */ break; \
+ case 5210000: ch = 42; /* Japan MMAC */ break; \
+ case 5230000: ch = 46; /* Japan MMAC */ break; \
+ case 4920000: ch = 184; /* Japan */ break; \
+ case 4940000: ch = 188; /* Japan */ break; \
+ case 4960000: ch = 192; /* Japan */ break; \
+ case 4980000: ch = 196; /* Japan */ break; \
+ case 5040000: ch = 208; /* Japan, means J08 */ break; \
+ case 5060000: ch = 212; /* Japan, means J12 */ break; \
+ case 5080000: ch = 216; /* Japan, means J16 */ break; \
+ default: ch = 1; break; \
+ } \
+ }
+
+//
+// Common fragment list structure - Identical to the scatter gather frag list structure
+//
+//#define RTMP_SCATTER_GATHER_ELEMENT SCATTER_GATHER_ELEMENT
+//#define PRTMP_SCATTER_GATHER_ELEMENT PSCATTER_GATHER_ELEMENT
+#define NIC_MAX_PHYS_BUF_COUNT 8
+
+typedef struct _RTMP_SCATTER_GATHER_ELEMENT {
+ PVOID Address;
+ ULONG Length;
+ PULONG Reserved;
+} RTMP_SCATTER_GATHER_ELEMENT, *PRTMP_SCATTER_GATHER_ELEMENT;
+
+
+typedef struct _RTMP_SCATTER_GATHER_LIST {
+ ULONG NumberOfElements;
+ PULONG Reserved;
+ RTMP_SCATTER_GATHER_ELEMENT Elements[NIC_MAX_PHYS_BUF_COUNT];
+} RTMP_SCATTER_GATHER_LIST, *PRTMP_SCATTER_GATHER_LIST;
+
+//
+// Some utility macros
+//
+#ifndef min
+#define min(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
+#endif
+
+#ifndef max
+#define max(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
+#endif
+
+#define GET_LNA_GAIN(_pAd) ((_pAd->LatchRfRegs.Channel <= 14) ? (_pAd->BLNAGain) : ((_pAd->LatchRfRegs.Channel <= 64) ? (_pAd->ALNAGain0) : ((_pAd->LatchRfRegs.Channel <= 128) ? (_pAd->ALNAGain1) : (_pAd->ALNAGain2))))
+
+#define INC_COUNTER64(Val) (Val.QuadPart++)
+
+#define INFRA_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_INFRA_ON))
+#define ADHOC_ON(_p) (OPSTATUS_TEST_FLAG(_p, fOP_STATUS_ADHOC_ON))
+#define MONITOR_ON(_p) (((_p)->StaCfg.BssType) == BSS_MONITOR)
+#define IDLE_ON(_p) (!INFRA_ON(_p) && !ADHOC_ON(_p))
+
+// Check LEAP & CCKM flags
+#define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP)
+#define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE))
+
+// if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required
+#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \
+{ \
+ if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_802_1H; \
+ if (NdisEqualMemory(IPX, _pBufVA + 12, 2) || \
+ NdisEqualMemory(APPLE_TALK, _pBufVA + 12, 2)) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
+ } \
+ } \
+ else \
+ { \
+ _pExtraLlcSnapEncap = NULL; \
+ } \
+}
+
+// New Define for new Tx Path.
+#define EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(_pBufVA, _pExtraLlcSnapEncap) \
+{ \
+ if (((*(_pBufVA) << 8) + *(_pBufVA + 1)) > 1500) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_802_1H; \
+ if (NdisEqualMemory(IPX, _pBufVA, 2) || \
+ NdisEqualMemory(APPLE_TALK, _pBufVA, 2)) \
+ { \
+ _pExtraLlcSnapEncap = SNAP_BRIDGE_TUNNEL; \
+ } \
+ } \
+ else \
+ { \
+ _pExtraLlcSnapEncap = NULL; \
+ } \
+}
+
+
+#define MAKE_802_3_HEADER(_p, _pMac1, _pMac2, _pType) \
+{ \
+ NdisMoveMemory(_p, _pMac1, MAC_ADDR_LEN); \
+ NdisMoveMemory((_p + MAC_ADDR_LEN), _pMac2, MAC_ADDR_LEN); \
+ NdisMoveMemory((_p + MAC_ADDR_LEN * 2), _pType, LENGTH_802_3_TYPE); \
+}
+
+// if pData has no LLC/SNAP (neither RFC1042 nor Bridge tunnel), keep it that way.
+// else if the received frame is LLC/SNAP-encaped IPX or APPLETALK, preserve the LLC/SNAP field
+// else remove the LLC/SNAP field from the result Ethernet frame
+// Patch for WHQL only, which did not turn on Netbios but use IPX within its payload
+// Note:
+// _pData & _DataSize may be altered (remove 8-byte LLC/SNAP) by this MACRO
+// _pRemovedLLCSNAP: pointer to removed LLC/SNAP; NULL is not removed
+#define CONVERT_TO_802_3(_p8023hdr, _pDA, _pSA, _pData, _DataSize, _pRemovedLLCSNAP) \
+{ \
+ char LLC_Len[2]; \
+ \
+ _pRemovedLLCSNAP = NULL; \
+ if (NdisEqualMemory(SNAP_802_1H, _pData, 6) || \
+ NdisEqualMemory(SNAP_BRIDGE_TUNNEL, _pData, 6)) \
+ { \
+ PUCHAR pProto = _pData + 6; \
+ \
+ if ((NdisEqualMemory(IPX, pProto, 2) || NdisEqualMemory(APPLE_TALK, pProto, 2)) && \
+ NdisEqualMemory(SNAP_802_1H, _pData, 6)) \
+ { \
+ LLC_Len[0] = (UCHAR)(_DataSize / 256); \
+ LLC_Len[1] = (UCHAR)(_DataSize % 256); \
+ MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
+ } \
+ else \
+ { \
+ MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, pProto); \
+ _pRemovedLLCSNAP = _pData; \
+ _DataSize -= LENGTH_802_1_H; \
+ _pData += LENGTH_802_1_H; \
+ } \
+ } \
+ else \
+ { \
+ LLC_Len[0] = (UCHAR)(_DataSize / 256); \
+ LLC_Len[1] = (UCHAR)(_DataSize % 256); \
+ MAKE_802_3_HEADER(_p8023hdr, _pDA, _pSA, LLC_Len); \
+ } \
+}
+
+#define SWITCH_AB( _pAA, _pBB) \
+{ \
+ PVOID pCC; \
+ pCC = _pBB; \
+ _pBB = _pAA; \
+ _pAA = pCC; \
+}
+
+// Enqueue this frame to MLME engine
+// We need to enqueue the whole frame because MLME need to pass data type
+// information from 802.11 header
+#ifdef RT2870
+#define REPORT_MGMT_FRAME_TO_MLME(_pAd, Wcid, _pFrame, _FrameSize, _Rssi0, _Rssi1, _Rssi2, _PlcpSignal) \
+{ \
+ UINT32 High32TSF=0, Low32TSF=0; \
+ MlmeEnqueueForRecv(_pAd, Wcid, High32TSF, Low32TSF, (UCHAR)_Rssi0, (UCHAR)_Rssi1,(UCHAR)_Rssi2,_FrameSize, _pFrame, (UCHAR)_PlcpSignal); \
+}
+#endif // RT2870 //
+
+#ifdef RT30xx
+//Need to collect each ant's rssi concurrently
+//rssi1 is report to pair2 Ant and rss2 is reprot to pair1 Ant when 4 Ant
+#define COLLECT_RX_ANTENNA_AVERAGE_RSSI(_pAd, _rssi1, _rssi2) \
+{ \
+ SHORT AvgRssi; \
+ UCHAR UsedAnt; \
+ if (_pAd->RxAnt.EvaluatePeriod == 0) \
+ { \
+ UsedAnt = _pAd->RxAnt.Pair1PrimaryRxAnt; \
+ AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
+ if (AvgRssi < 0) \
+ AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
+ else \
+ AvgRssi = _rssi1 << 3; \
+ _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
+ } \
+ else \
+ { \
+ UsedAnt = _pAd->RxAnt.Pair1SecondaryRxAnt; \
+ AvgRssi = _pAd->RxAnt.Pair1AvgRssi[UsedAnt]; \
+ if ((AvgRssi < 0) && (_pAd->RxAnt.FirstPktArrivedWhenEvaluate)) \
+ AvgRssi = AvgRssi - (AvgRssi >> 3) + _rssi1; \
+ else \
+ { \
+ _pAd->RxAnt.FirstPktArrivedWhenEvaluate = TRUE; \
+ AvgRssi = _rssi1 << 3; \
+ } \
+ _pAd->RxAnt.Pair1AvgRssi[UsedAnt] = AvgRssi; \
+ _pAd->RxAnt.RcvPktNumWhenEvaluate++; \
+ } \
+}
+#endif // RT30xx //
+
+
+#define NDIS_QUERY_BUFFER(_NdisBuf, _ppVA, _pBufLen) \
+ NdisQueryBuffer(_NdisBuf, _ppVA, _pBufLen)
+
+#define MAC_ADDR_EQUAL(pAddr1,pAddr2) RTMPEqualMemory((PVOID)(pAddr1), (PVOID)(pAddr2), MAC_ADDR_LEN)
+#define SSID_EQUAL(ssid1, len1, ssid2, len2) ((len1==len2) && (RTMPEqualMemory(ssid1, ssid2, len1)))
+
+//
+// Check if it is Japan W53(ch52,56,60,64) channel.
+//
+#define JapanChannelCheck(channel) ((channel == 52) || (channel == 56) || (channel == 60) || (channel == 64))
+
+#ifdef CONFIG_STA_SUPPORT
+#define STA_PORT_SECURED(_pAd) \
+{ \
+ _pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED; \
+ NdisAcquireSpinLock(&_pAd->MacTabLock); \
+ _pAd->MacTab.Content[BSSID_WCID].PortSecured = _pAd->StaCfg.PortSecured; \
+ NdisReleaseSpinLock(&_pAd->MacTabLock); \
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct _RTMP_REG_PAIR
+{
+ ULONG Register;
+ ULONG Value;
+} RTMP_REG_PAIR, *PRTMP_REG_PAIR;
+
+typedef struct _REG_PAIR
+{
+ UCHAR Register;
+ UCHAR Value;
+} REG_PAIR, *PREG_PAIR;
+
+//
+// Register set pair for initialzation register set definition
+//
+typedef struct _RTMP_RF_REGS
+{
+ UCHAR Channel;
+ ULONG R1;
+ ULONG R2;
+ ULONG R3;
+ ULONG R4;
+} RTMP_RF_REGS, *PRTMP_RF_REGS;
+
+typedef struct _FREQUENCY_ITEM {
+ UCHAR Channel;
+ UCHAR N;
+ UCHAR R;
+ UCHAR K;
+} FREQUENCY_ITEM, *PFREQUENCY_ITEM;
+
+//
+// Data buffer for DMA operation, the buffer must be contiguous physical memory
+// Both DMA to / from CPU use the same structure.
+//
+typedef struct _RTMP_DMABUF
+{
+ ULONG AllocSize;
+ PVOID AllocVa; // TxBuf virtual address
+ NDIS_PHYSICAL_ADDRESS AllocPa; // TxBuf physical address
+} RTMP_DMABUF, *PRTMP_DMABUF;
+
+
+typedef union _HEADER_802_11_SEQ{
+#ifdef RT_BIG_ENDIAN
+ struct {
+ USHORT Sequence:12;
+ USHORT Frag:4;
+ } field;
+#else
+ struct {
+ USHORT Frag:4;
+ USHORT Sequence:12;
+ } field;
+#endif
+ USHORT value;
+} HEADER_802_11_SEQ, *PHEADER_802_11_SEQ;
+
+//
+// Data buffer for DMA operation, the buffer must be contiguous physical memory
+// Both DMA to / from CPU use the same structure.
+//
+typedef struct _RTMP_REORDERBUF
+{
+ BOOLEAN IsFull;
+ PVOID AllocVa; // TxBuf virtual address
+ UCHAR Header802_3[14];
+ HEADER_802_11_SEQ Sequence; //support compressed bitmap BA, so no consider fragment in BA
+ UCHAR DataOffset;
+ USHORT Datasize;
+ ULONG AllocSize;
+#ifdef RT2870
+ PUCHAR AllocPa;
+#endif // RT2870 //
+} RTMP_REORDERBUF, *PRTMP_REORDERBUF;
+
+//
+// Control block (Descriptor) for all ring descriptor DMA operation, buffer must be
+// contiguous physical memory. NDIS_PACKET stored the binding Rx packet descriptor
+// which won't be released, driver has to wait until upper layer return the packet
+// before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair
+// to describe the packet buffer. For Tx, NDIS_PACKET stored the tx packet descriptor
+// which driver should ACK upper layer when the tx is physically done or failed.
+//
+typedef struct _RTMP_DMACB
+{
+ ULONG AllocSize; // Control block size
+ PVOID AllocVa; // Control block virtual address
+ NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
+ PNDIS_PACKET pNdisPacket;
+ PNDIS_PACKET pNextNdisPacket;
+
+ RTMP_DMABUF DmaBuf; // Associated DMA buffer structure
+} RTMP_DMACB, *PRTMP_DMACB;
+
+typedef struct _RTMP_TX_BUF
+{
+ PQUEUE_ENTRY Next;
+ UCHAR Index;
+ ULONG AllocSize; // Control block size
+ PVOID AllocVa; // Control block virtual address
+ NDIS_PHYSICAL_ADDRESS AllocPa; // Control block physical address
+} RTMP_TXBUF, *PRTMP_TXBUF;
+
+typedef struct _RTMP_RX_BUF
+{
+ BOOLEAN InUse;
+ ULONG ByBaRecIndex;
+ RTMP_REORDERBUF MAP_RXBuf[MAX_RX_REORDERBUF];
+} RTMP_RXBUF, *PRTMP_RXBUF;
+typedef struct _RTMP_TX_RING
+{
+ RTMP_DMACB Cell[TX_RING_SIZE];
+ UINT32 TxCpuIdx;
+ UINT32 TxDmaIdx;
+ UINT32 TxSwFreeIdx; // software next free tx index
+} RTMP_TX_RING, *PRTMP_TX_RING;
+
+typedef struct _RTMP_RX_RING
+{
+ RTMP_DMACB Cell[RX_RING_SIZE];
+ UINT32 RxCpuIdx;
+ UINT32 RxDmaIdx;
+ INT32 RxSwReadIdx; // software next read index
+} RTMP_RX_RING, *PRTMP_RX_RING;
+
+typedef struct _RTMP_MGMT_RING
+{
+ RTMP_DMACB Cell[MGMT_RING_SIZE];
+ UINT32 TxCpuIdx;
+ UINT32 TxDmaIdx;
+ UINT32 TxSwFreeIdx; // software next free tx index
+} RTMP_MGMT_RING, *PRTMP_MGMT_RING;
+
+//
+// Statistic counter structure
+//
+typedef struct _COUNTER_802_3
+{
+ // General Stats
+ ULONG GoodTransmits;
+ ULONG GoodReceives;
+ ULONG TxErrors;
+ ULONG RxErrors;
+ ULONG RxNoBuffer;
+
+ // Ethernet Stats
+ ULONG RcvAlignmentErrors;
+ ULONG OneCollision;
+ ULONG MoreCollisions;
+
+} COUNTER_802_3, *PCOUNTER_802_3;
+
+typedef struct _COUNTER_802_11 {
+ ULONG Length;
+ LARGE_INTEGER LastTransmittedFragmentCount;
+ LARGE_INTEGER TransmittedFragmentCount;
+ LARGE_INTEGER MulticastTransmittedFrameCount;
+ LARGE_INTEGER FailedCount;
+ LARGE_INTEGER RetryCount;
+ LARGE_INTEGER MultipleRetryCount;
+ LARGE_INTEGER RTSSuccessCount;
+ LARGE_INTEGER RTSFailureCount;
+ LARGE_INTEGER ACKFailureCount;
+ LARGE_INTEGER FrameDuplicateCount;
+ LARGE_INTEGER ReceivedFragmentCount;
+ LARGE_INTEGER MulticastReceivedFrameCount;
+ LARGE_INTEGER FCSErrorCount;
+} COUNTER_802_11, *PCOUNTER_802_11;
+
+typedef struct _COUNTER_RALINK {
+ ULONG TransmittedByteCount; // both successful and failure, used to calculate TX throughput
+ ULONG ReceivedByteCount; // both CRC okay and CRC error, used to calculate RX throughput
+ ULONG BeenDisassociatedCount;
+ ULONG BadCQIAutoRecoveryCount;
+ ULONG PoorCQIRoamingCount;
+ ULONG MgmtRingFullCount;
+ ULONG RxCountSinceLastNULL;
+ ULONG RxCount;
+ ULONG RxRingErrCount;
+ ULONG KickTxCount;
+ ULONG TxRingErrCount;
+ LARGE_INTEGER RealFcsErrCount;
+ ULONG PendingNdisPacketCount;
+
+ ULONG OneSecOsTxCount[NUM_OF_TX_RING];
+ ULONG OneSecDmaDoneCount[NUM_OF_TX_RING];
+ UINT32 OneSecTxDoneCount;
+ ULONG OneSecRxCount;
+ UINT32 OneSecTxAggregationCount;
+ UINT32 OneSecRxAggregationCount;
+
+ UINT32 OneSecFrameDuplicateCount;
+
+#ifdef RT2870
+ ULONG OneSecTransmittedByteCount; // both successful and failure, used to calculate TX throughput
+#endif // RT2870 //
+
+ UINT32 OneSecTxNoRetryOkCount;
+ UINT32 OneSecTxRetryOkCount;
+ UINT32 OneSecTxFailCount;
+ UINT32 OneSecFalseCCACnt; // CCA error count, for debug purpose, might move to global counter
+ UINT32 OneSecRxOkCnt; // RX without error
+ UINT32 OneSecRxOkDataCnt; // unicast-to-me DATA frame count
+ UINT32 OneSecRxFcsErrCnt; // CRC error
+ UINT32 OneSecBeaconSentCnt;
+ UINT32 LastOneSecTotalTxCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
+ UINT32 LastOneSecRxOkDataCnt; // OneSecRxOkDataCnt
+ ULONG DuplicateRcv;
+ ULONG TxAggCount;
+ ULONG TxNonAggCount;
+ ULONG TxAgg1MPDUCount;
+ ULONG TxAgg2MPDUCount;
+ ULONG TxAgg3MPDUCount;
+ ULONG TxAgg4MPDUCount;
+ ULONG TxAgg5MPDUCount;
+ ULONG TxAgg6MPDUCount;
+ ULONG TxAgg7MPDUCount;
+ ULONG TxAgg8MPDUCount;
+ ULONG TxAgg9MPDUCount;
+ ULONG TxAgg10MPDUCount;
+ ULONG TxAgg11MPDUCount;
+ ULONG TxAgg12MPDUCount;
+ ULONG TxAgg13MPDUCount;
+ ULONG TxAgg14MPDUCount;
+ ULONG TxAgg15MPDUCount;
+ ULONG TxAgg16MPDUCount;
+
+ LARGE_INTEGER TransmittedOctetsInAMSDU;
+ LARGE_INTEGER TransmittedAMSDUCount;
+ LARGE_INTEGER ReceivedOctesInAMSDUCount;
+ LARGE_INTEGER ReceivedAMSDUCount;
+ LARGE_INTEGER TransmittedAMPDUCount;
+ LARGE_INTEGER TransmittedMPDUsInAMPDUCount;
+ LARGE_INTEGER TransmittedOctetsInAMPDUCount;
+ LARGE_INTEGER MPDUInReceivedAMPDUCount;
+} COUNTER_RALINK, *PCOUNTER_RALINK;
+
+typedef struct _PID_COUNTER {
+ ULONG TxAckRequiredCount; // CRC error
+ ULONG TxAggreCount;
+ ULONG TxSuccessCount; // OneSecTxNoRetryOkCount + OneSecTxRetryOkCount + OneSecTxFailCount
+ ULONG LastSuccessRate;
+} PID_COUNTER, *PPID_COUNTER;
+
+typedef struct _COUNTER_DRS {
+ // to record the each TX rate's quality. 0 is best, the bigger the worse.
+ USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+ UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
+ UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
+ ULONG CurrTxRateStableTime; // # of second in current TX rate
+ BOOLEAN fNoisyEnvironment;
+ BOOLEAN fLastSecAccordingRSSI;
+ UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
+ UCHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
+ ULONG LastTxOkCount;
+} COUNTER_DRS, *PCOUNTER_DRS;
+
+//
+// Arcfour Structure Added by PaulWu
+//
+typedef struct _ARCFOUR
+{
+ UINT X;
+ UINT Y;
+ UCHAR STATE[256];
+} ARCFOURCONTEXT, *PARCFOURCONTEXT;
+
+// MIMO Tx parameter, ShortGI, MCS, STBC, etc. these are fields in TXWI too. just copy to TXWI.
+typedef struct _RECEIVE_SETTING {
+#ifdef RT_BIG_ENDIAN
+ USHORT MIMO:1;
+ USHORT OFDM:1;
+ USHORT rsv:3;
+ USHORT STBC:2; //SPACE
+ USHORT ShortGI:1;
+ USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
+ USHORT NumOfRX:2; // MIMO. WE HAVE 3R
+#else
+ USHORT NumOfRX:2; // MIMO. WE HAVE 3R
+ USHORT Mode:2; //channel bandwidth 20MHz or 40 MHz
+ USHORT ShortGI:1;
+ USHORT STBC:2; //SPACE
+ USHORT rsv:3;
+ USHORT OFDM:1;
+ USHORT MIMO:1;
+#endif
+ } RECEIVE_SETTING, *PRECEIVE_SETTING;
+
+// Shared key data structure
+typedef struct _WEP_KEY {
+ UCHAR KeyLen; // Key length for each key, 0: entry is invalid
+ UCHAR Key[MAX_LEN_OF_KEY]; // right now we implement 4 keys, 128 bits max
+} WEP_KEY, *PWEP_KEY;
+
+typedef struct _CIPHER_KEY {
+ UCHAR Key[16]; // right now we implement 4 keys, 128 bits max
+ UCHAR RxMic[8]; // make alignment
+ UCHAR TxMic[8];
+ UCHAR TxTsc[6]; // 48bit TSC value
+ UCHAR RxTsc[6]; // 48bit TSC value
+ UCHAR CipherAlg; // 0-none, 1:WEP64, 2:WEP128, 3:TKIP, 4:AES, 5:CKIP64, 6:CKIP128
+ UCHAR KeyLen;
+#ifdef CONFIG_STA_SUPPORT
+ UCHAR BssId[6];
+#endif // CONFIG_STA_SUPPORT //
+ // Key length for each key, 0: entry is invalid
+ UCHAR Type; // Indicate Pairwise/Group when reporting MIC error
+} CIPHER_KEY, *PCIPHER_KEY;
+
+typedef struct _BBP_TUNING_STRUCT {
+ BOOLEAN Enable;
+ UCHAR FalseCcaCountUpperBound; // 100 per sec
+ UCHAR FalseCcaCountLowerBound; // 10 per sec
+ UCHAR R17LowerBound; // specified in E2PROM
+ UCHAR R17UpperBound; // 0x68 according to David Tung
+ UCHAR CurrentR17Value;
+} BBP_TUNING, *PBBP_TUNING;
+
+typedef struct _SOFT_RX_ANT_DIVERSITY_STRUCT {
+ UCHAR EvaluatePeriod; // 0:not evalute status, 1: evaluate status, 2: switching status
+ UCHAR EvaluateStableCnt;
+ UCHAR Pair1PrimaryRxAnt; // 0:Ant-E1, 1:Ant-E2
+ UCHAR Pair1SecondaryRxAnt; // 0:Ant-E1, 1:Ant-E2
+ UCHAR Pair2PrimaryRxAnt; // 0:Ant-E3, 1:Ant-E4
+ UCHAR Pair2SecondaryRxAnt; // 0:Ant-E3, 1:Ant-E4
+ SHORT Pair1AvgRssi[2]; // AvgRssi[0]:E1, AvgRssi[1]:E2
+ SHORT Pair2AvgRssi[2]; // AvgRssi[0]:E3, AvgRssi[1]:E4
+ SHORT Pair1LastAvgRssi; //
+ SHORT Pair2LastAvgRssi; //
+ ULONG RcvPktNumWhenEvaluate;
+ BOOLEAN FirstPktArrivedWhenEvaluate;
+ RALINK_TIMER_STRUCT RxAntDiversityTimer;
+} SOFT_RX_ANT_DIVERSITY, *PSOFT_RX_ANT_DIVERSITY;
+
+typedef struct _LEAP_AUTH_INFO {
+ BOOLEAN Enabled; //Ture: Enable LEAP Authentication
+ BOOLEAN CCKM; //Ture: Use Fast Reauthentication with CCKM
+ UCHAR Reserve[2];
+ UCHAR UserName[256]; //LEAP, User name
+ ULONG UserNameLen;
+ UCHAR Password[256]; //LEAP, User Password
+ ULONG PasswordLen;
+} LEAP_AUTH_INFO, *PLEAP_AUTH_INFO;
+
+typedef struct {
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR ErrorCode[2]; //00 01-Invalid authentication type
+ //00 02-Authentication timeout
+ //00 03-Challenge from AP failed
+ //00 04-Challenge to AP failed
+ BOOLEAN Reported;
+} ROGUEAP_ENTRY, *PROGUEAP_ENTRY;
+
+typedef struct {
+ UCHAR RogueApNr;
+ ROGUEAP_ENTRY RogueApEntry[MAX_LEN_OF_BSS_TABLE];
+} ROGUEAP_TABLE, *PROGUEAP_TABLE;
+
+typedef struct {
+ BOOLEAN Enable;
+ UCHAR Delta;
+ BOOLEAN PlusSign;
+} CCK_TX_POWER_CALIBRATE, *PCCK_TX_POWER_CALIBRATE;
+
+//
+// Receive Tuple Cache Format
+//
+typedef struct _TUPLE_CACHE {
+ BOOLEAN Valid;
+ UCHAR MacAddress[MAC_ADDR_LEN];
+ USHORT Sequence;
+ USHORT Frag;
+} TUPLE_CACHE, *PTUPLE_CACHE;
+
+//
+// Fragment Frame structure
+//
+typedef struct _FRAGMENT_FRAME {
+ PNDIS_PACKET pFragPacket;
+ ULONG RxSize;
+ USHORT Sequence;
+ USHORT LastFrag;
+ ULONG Flags; // Some extra frame information. bit 0: LLC presented
+} FRAGMENT_FRAME, *PFRAGMENT_FRAME;
+
+
+//
+// Packet information for NdisQueryPacket
+//
+typedef struct _PACKET_INFO {
+ UINT PhysicalBufferCount; // Physical breaks of buffer descripor chained
+ UINT BufferCount ; // Number of Buffer descriptor chained
+ UINT TotalPacketLength ; // Self explained
+ PNDIS_BUFFER pFirstBuffer; // Pointer to first buffer descriptor
+} PACKET_INFO, *PPACKET_INFO;
+
+//
+// Tkip Key structure which RC4 key & MIC calculation
+//
+typedef struct _TKIP_KEY_INFO {
+ UINT nBytesInM; // # bytes in M for MICKEY
+ ULONG IV16;
+ ULONG IV32;
+ ULONG K0; // for MICKEY Low
+ ULONG K1; // for MICKEY Hig
+ ULONG L; // Current state for MICKEY
+ ULONG R; // Current state for MICKEY
+ ULONG M; // Message accumulator for MICKEY
+ UCHAR RC4KEY[16];
+ UCHAR MIC[8];
+} TKIP_KEY_INFO, *PTKIP_KEY_INFO;
+
+//
+// Private / Misc data, counters for driver internal use
+//
+typedef struct __PRIVATE_STRUC {
+ UINT SystemResetCnt; // System reset counter
+ UINT TxRingFullCnt; // Tx ring full occurrance number
+ UINT PhyRxErrCnt; // PHY Rx error count, for debug purpose, might move to global counter
+ // Variables for WEP encryption / decryption in rtmp_wep.c
+ UINT FCSCRC32;
+ ARCFOURCONTEXT WEPCONTEXT;
+ // Tkip stuff
+ TKIP_KEY_INFO Tx;
+ TKIP_KEY_INFO Rx;
+} PRIVATE_STRUC, *PPRIVATE_STRUC;
+
+// structure to tune BBP R66 (BBP TUNING)
+typedef struct _BBP_R66_TUNING {
+ BOOLEAN bEnable;
+ USHORT FalseCcaLowerThreshold; // default 100
+ USHORT FalseCcaUpperThreshold; // default 512
+ UCHAR R66Delta;
+ UCHAR R66CurrentValue;
+ BOOLEAN R66LowerUpperSelect; //Before LinkUp, Used LowerBound or UpperBound as R66 value.
+} BBP_R66_TUNING, *PBBP_R66_TUNING;
+
+// structure to store channel TX power
+typedef struct _CHANNEL_TX_POWER {
+ USHORT RemainingTimeForUse; //unit: sec
+ UCHAR Channel;
+#ifdef DOT11N_DRAFT3
+ BOOLEAN bEffectedChannel; // For BW 40 operating in 2.4GHz , the "effected channel" is the channel that is covered in 40Mhz.
+#endif // DOT11N_DRAFT3 //
+ CHAR Power;
+ CHAR Power2;
+ UCHAR MaxTxPwr;
+ UCHAR DfsReq;
+} CHANNEL_TX_POWER, *PCHANNEL_TX_POWER;
+
+// structure to store 802.11j channel TX power
+typedef struct _CHANNEL_11J_TX_POWER {
+ UCHAR Channel;
+ UCHAR BW; // BW_10 or BW_20
+ CHAR Power;
+ CHAR Power2;
+ USHORT RemainingTimeForUse; //unit: sec
+} CHANNEL_11J_TX_POWER, *PCHANNEL_11J_TX_POWER;
+
+typedef enum _ABGBAND_STATE_ {
+ UNKNOWN_BAND,
+ BG_BAND,
+ A_BAND,
+} ABGBAND_STATE;
+
+typedef struct _MLME_STRUCT {
+#ifdef CONFIG_STA_SUPPORT
+ // STA state machines
+ STATE_MACHINE CntlMachine;
+ STATE_MACHINE AssocMachine;
+ STATE_MACHINE AuthMachine;
+ STATE_MACHINE AuthRspMachine;
+ STATE_MACHINE SyncMachine;
+ STATE_MACHINE WpaPskMachine;
+ STATE_MACHINE LeapMachine;
+ STATE_MACHINE AironetMachine;
+ STATE_MACHINE_FUNC AssocFunc[ASSOC_FUNC_SIZE];
+ STATE_MACHINE_FUNC AuthFunc[AUTH_FUNC_SIZE];
+ STATE_MACHINE_FUNC AuthRspFunc[AUTH_RSP_FUNC_SIZE];
+ STATE_MACHINE_FUNC SyncFunc[SYNC_FUNC_SIZE];
+ STATE_MACHINE_FUNC WpaPskFunc[WPA_PSK_FUNC_SIZE];
+ STATE_MACHINE_FUNC AironetFunc[AIRONET_FUNC_SIZE];
+#endif // CONFIG_STA_SUPPORT //
+ STATE_MACHINE_FUNC ActFunc[ACT_FUNC_SIZE];
+ // Action
+ STATE_MACHINE ActMachine;
+
+
+#ifdef QOS_DLS_SUPPORT
+ STATE_MACHINE DlsMachine;
+ STATE_MACHINE_FUNC DlsFunc[DLS_FUNC_SIZE];
+#endif // QOS_DLS_SUPPORT //
+
+
+
+
+ ULONG ChannelQuality; // 0..100, Channel Quality Indication for Roaming
+ ULONG Now32; // latch the value of NdisGetSystemUpTime()
+ ULONG LastSendNULLpsmTime;
+
+ BOOLEAN bRunning;
+ NDIS_SPIN_LOCK TaskLock;
+ MLME_QUEUE Queue;
+
+ UINT ShiftReg;
+
+ RALINK_TIMER_STRUCT PeriodicTimer;
+ RALINK_TIMER_STRUCT APSDPeriodicTimer;
+ RALINK_TIMER_STRUCT LinkDownTimer;
+ RALINK_TIMER_STRUCT LinkUpTimer;
+ ULONG PeriodicRound;
+ ULONG OneSecPeriodicRound;
+
+ UCHAR RealRxPath;
+ BOOLEAN bLowThroughput;
+ BOOLEAN bEnableAutoAntennaCheck;
+ RALINK_TIMER_STRUCT RxAntEvalTimer;
+
+#ifdef RT30xx
+ UCHAR CaliBW40RfR24;
+ UCHAR CaliBW20RfR24;
+#endif // RT30xx //
+
+} MLME_STRUCT, *PMLME_STRUCT;
+
+// structure for radar detection and channel switch
+typedef struct _RADAR_DETECT_STRUCT {
+ //BOOLEAN IEEE80211H; // 0: disable, 1: enable IEEE802.11h
+ UCHAR CSCount; //Channel switch counter
+ UCHAR CSPeriod; //Channel switch period (beacon count)
+ UCHAR RDCount; //Radar detection counter
+ UCHAR RDMode; //Radar Detection mode
+ UCHAR RDDurRegion; //Radar detection duration region
+ UCHAR BBPR16;
+ UCHAR BBPR17;
+ UCHAR BBPR18;
+ UCHAR BBPR21;
+ UCHAR BBPR22;
+ UCHAR BBPR64;
+ ULONG InServiceMonitorCount; // unit: sec
+ UINT8 DfsSessionTime;
+ BOOLEAN bFastDfs;
+ UINT8 ChMovingTime;
+ UINT8 LongPulseRadarTh;
+} RADAR_DETECT_STRUCT, *PRADAR_DETECT_STRUCT;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+typedef enum CD_STATE_n
+{
+ CD_NORMAL,
+ CD_SILENCE,
+ CD_MAX_STATE
+} CD_STATE;
+
+typedef struct CARRIER_DETECTION_s
+{
+ BOOLEAN Enable;
+ UINT8 CDSessionTime;
+ UINT8 CDPeriod;
+ CD_STATE CD_State;
+} CARRIER_DETECTION, *PCARRIER_DETECTION;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+typedef enum _REC_BLOCKACK_STATUS
+{
+ Recipient_NONE=0,
+ Recipient_USED,
+ Recipient_HandleRes,
+ Recipient_Accept
+} REC_BLOCKACK_STATUS, *PREC_BLOCKACK_STATUS;
+
+typedef enum _ORI_BLOCKACK_STATUS
+{
+ Originator_NONE=0,
+ Originator_USED,
+ Originator_WaitRes,
+ Originator_Done
+} ORI_BLOCKACK_STATUS, *PORI_BLOCKACK_STATUS;
+
+#ifdef DOT11_N_SUPPORT
+typedef struct _BA_ORI_ENTRY{
+ UCHAR Wcid;
+ UCHAR TID;
+ UCHAR BAWinSize;
+ UCHAR Token;
+// Sequence is to fill every outgoing QoS DATA frame's sequence field in 802.11 header.
+ USHORT Sequence;
+ USHORT TimeOutValue;
+ ORI_BLOCKACK_STATUS ORI_BA_Status;
+ RALINK_TIMER_STRUCT ORIBATimer;
+ PVOID pAdapter;
+} BA_ORI_ENTRY, *PBA_ORI_ENTRY;
+
+typedef struct _BA_REC_ENTRY {
+ UCHAR Wcid;
+ UCHAR TID;
+ UCHAR BAWinSize; // 7.3.1.14. each buffer is capable of holding a max AMSDU or MSDU.
+ //UCHAR NumOfRxPkt;
+ //UCHAR Curindidx; // the head in the RX reordering buffer
+ USHORT LastIndSeq;
+// USHORT LastIndSeqAtTimer;
+ USHORT TimeOutValue;
+ RALINK_TIMER_STRUCT RECBATimer;
+ ULONG LastIndSeqAtTimer;
+ ULONG nDropPacket;
+ ULONG rcvSeq;
+ REC_BLOCKACK_STATUS REC_BA_Status;
+// UCHAR RxBufIdxUsed;
+ // corresponding virtual address for RX reordering packet storage.
+ //RTMP_REORDERDMABUF MAP_RXBuf[MAX_RX_REORDERBUF];
+ NDIS_SPIN_LOCK RxReRingLock; // Rx Ring spinlock
+// struct _BA_REC_ENTRY *pNext;
+ PVOID pAdapter;
+ struct reordering_list list;
+} BA_REC_ENTRY, *PBA_REC_ENTRY;
+
+
+typedef struct {
+ ULONG numAsRecipient; // I am recipient of numAsRecipient clients. These client are in the BARecEntry[]
+ ULONG numAsOriginator; // I am originator of numAsOriginator clients. These clients are in the BAOriEntry[]
+ BA_ORI_ENTRY BAOriEntry[MAX_LEN_OF_BA_ORI_TABLE];
+ BA_REC_ENTRY BARecEntry[MAX_LEN_OF_BA_REC_TABLE];
+} BA_TABLE, *PBA_TABLE;
+
+//For QureyBATableOID use;
+typedef struct PACKED _OID_BA_REC_ENTRY{
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize
+ UCHAR rsv;
+ UCHAR BufSize[8];
+ REC_BLOCKACK_STATUS REC_BA_Status[8];
+} OID_BA_REC_ENTRY, *POID_BA_REC_ENTRY;
+
+//For QureyBATableOID use;
+typedef struct PACKED _OID_BA_ORI_ENTRY{
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR BaBitmap; // if (BaBitmap&(1<<TID)), this session with{MACAddr, TID}exists, so read BufSize[TID] for BufferSize, read ORI_BA_Status[TID] for status
+ UCHAR rsv;
+ UCHAR BufSize[8];
+ ORI_BLOCKACK_STATUS ORI_BA_Status[8];
+} OID_BA_ORI_ENTRY, *POID_BA_ORI_ENTRY;
+
+typedef struct _QUERYBA_TABLE{
+ OID_BA_ORI_ENTRY BAOriEntry[32];
+ OID_BA_REC_ENTRY BARecEntry[32];
+ UCHAR OriNum;// Number of below BAOriEntry
+ UCHAR RecNum;// Number of below BARecEntry
+} QUERYBA_TABLE, *PQUERYBA_TABLE;
+
+typedef union _BACAP_STRUC {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ UINT32 :4;
+ UINT32 b2040CoexistScanSup:1; //As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
+ UINT32 bHtAdhoc:1; // adhoc can use ht rate.
+ UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+ UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
+ UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
+ UINT32 MpduDensity:3;
+ UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
+ UINT32 AutoBA:1; // automatically BA
+ UINT32 TxBAWinLimit:8;
+ UINT32 RxBAWinLimit:8;
+ } field;
+#else
+ struct {
+ UINT32 RxBAWinLimit:8;
+ UINT32 TxBAWinLimit:8;
+ UINT32 AutoBA:1; // automatically BA
+ UINT32 Policy:2; // 0: DELAY_BA 1:IMMED_BA (//BA Policy subfiled value in ADDBA frame) 2:BA-not use
+ UINT32 MpduDensity:3;
+ UINT32 AmsduEnable:1; //Enable AMSDU transmisstion
+ UINT32 AmsduSize:1; // 0:3839, 1:7935 bytes. UINT MSDUSizeToBytes[] = { 3839, 7935};
+ UINT32 MMPSmode:2; // MIMO power save more, 0:static, 1:dynamic, 2:rsv, 3:mimo enable
+ UINT32 bHtAdhoc:1; // adhoc can use ht rate.
+ UINT32 b2040CoexistScanSup:1; //As Sta, support do 2040 coexistence scan for AP. As Ap, support monitor trigger event to check if can use BW 40MHz.
+ UINT32 :4;
+ } field;
+#endif
+ UINT32 word;
+} BACAP_STRUC, *PBACAP_STRUC;
+#endif // DOT11_N_SUPPORT //
+
+//This structure is for all 802.11n card InterOptibilityTest action. Reset all Num every n second. (Details see MLMEPeriodic)
+typedef struct _IOT_STRUC {
+ UCHAR Threshold[2];
+ UCHAR ReorderTimeOutNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[0]
+ UCHAR RefreshNum[MAX_LEN_OF_BA_REC_TABLE]; // compare with threshold[1]
+ ULONG OneSecInWindowCount;
+ ULONG OneSecFrameDuplicateCount;
+ ULONG OneSecOutWindowCount;
+ UCHAR DelOriAct;
+ UCHAR DelRecAct;
+ UCHAR RTSShortProt;
+ UCHAR RTSLongProt;
+ BOOLEAN bRTSLongProtOn;
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN bLastAtheros;
+ BOOLEAN bCurrentAtheros;
+ BOOLEAN bNowAtherosBurstOn;
+ BOOLEAN bNextDisableRxBA;
+ BOOLEAN bToggle;
+#endif // CONFIG_STA_SUPPORT //
+} IOT_STRUC, *PIOT_STRUC;
+
+// This is the registry setting for 802.11n transmit setting. Used in advanced page.
+typedef union _REG_TRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ UINT32 rsv:13;
+ UINT32 EXTCHA:2;
+ UINT32 HTMODE:1;
+ UINT32 TRANSNO:2;
+ UINT32 STBC:1; //SPACE
+ UINT32 ShortGI:1;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 TxBF:1; // 3*3
+ UINT32 rsv0:10;
+ //UINT32 MCS:7; // MCS
+ //UINT32 PhyMode:4;
+ } field;
+#else
+ struct {
+ //UINT32 PhyMode:4;
+ //UINT32 MCS:7; // MCS
+ UINT32 rsv0:10;
+ UINT32 TxBF:1;
+ UINT32 BW:1; //channel bandwidth 20MHz or 40 MHz
+ UINT32 ShortGI:1;
+ UINT32 STBC:1; //SPACE
+ UINT32 TRANSNO:2;
+ UINT32 HTMODE:1;
+ UINT32 EXTCHA:2;
+ UINT32 rsv:13;
+ } field;
+#endif
+ UINT32 word;
+} REG_TRANSMIT_SETTING, *PREG_TRANSMIT_SETTING;
+
+typedef union _DESIRED_TRANSMIT_SETTING {
+#ifdef RT_BIG_ENDIAN
+ struct {
+ USHORT rsv:3;
+ USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
+ USHORT PhyMode:4;
+ USHORT MCS:7; // MCS
+ } field;
+#else
+ struct {
+ USHORT MCS:7; // MCS
+ USHORT PhyMode:4;
+ USHORT FixedTxMode:2; // If MCS isn't AUTO, fix rate in CCK, OFDM or HT mode.
+ USHORT rsv:3;
+ } field;
+#endif
+ USHORT word;
+ } DESIRED_TRANSMIT_SETTING, *PDESIRED_TRANSMIT_SETTING;
+
+typedef struct {
+ BOOLEAN IsRecipient;
+ UCHAR MACAddr[MAC_ADDR_LEN];
+ UCHAR TID;
+ UCHAR nMSDU;
+ USHORT TimeOut;
+ BOOLEAN bAllTid; // If True, delete all TID for BA sessions with this MACaddr.
+} OID_ADD_BA_ENTRY, *POID_ADD_BA_ENTRY;
+
+//
+// Multiple SSID structure
+//
+#define WLAN_MAX_NUM_OF_TIM ((MAX_LEN_OF_MAC_TABLE >> 3) + 1) /* /8 + 1 */
+#define WLAN_CT_TIM_BCMC_OFFSET 0 /* unit: 32B */
+
+/* clear bcmc TIM bit */
+#define WLAN_MR_TIM_BCMC_CLEAR(apidx) \
+ pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] &= ~BIT8[0];
+
+/* set bcmc TIM bit */
+#define WLAN_MR_TIM_BCMC_SET(apidx) \
+ pAd->ApCfg.MBSSID[apidx].TimBitmaps[WLAN_CT_TIM_BCMC_OFFSET] |= BIT8[0];
+
+/* clear a station PS TIM bit */
+#define WLAN_MR_TIM_BIT_CLEAR(ad_p, apidx, wcid) \
+ { UCHAR tim_offset = wcid >> 3; \
+ UCHAR bit_offset = wcid & 0x7; \
+ ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] &= (~BIT8[bit_offset]); }
+
+/* set a station PS TIM bit */
+#define WLAN_MR_TIM_BIT_SET(ad_p, apidx, wcid) \
+ { UCHAR tim_offset = wcid >> 3; \
+ UCHAR bit_offset = wcid & 0x7; \
+ ad_p->ApCfg.MBSSID[apidx].TimBitmaps[tim_offset] |= BIT8[bit_offset]; }
+
+#ifdef RT2870
+#define BEACON_BITMAP_MASK 0xff
+typedef struct _BEACON_SYNC_STRUCT_
+{
+ UCHAR BeaconBuf[HW_BEACON_MAX_COUNT][HW_BEACON_OFFSET];
+ UCHAR BeaconTxWI[HW_BEACON_MAX_COUNT][TXWI_SIZE];
+ ULONG TimIELocationInBeacon[HW_BEACON_MAX_COUNT];
+ ULONG CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT];
+ BOOLEAN EnableBeacon; // trigger to enable beacon transmission.
+ UCHAR BeaconBitMap; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
+ UCHAR DtimBitOn; // NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change.
+}BEACON_SYNC_STRUCT;
+#endif // RT2870 //
+
+typedef struct _MULTISSID_STRUCT {
+ UCHAR Bssid[MAC_ADDR_LEN];
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ USHORT CapabilityInfo;
+
+ PNET_DEV MSSIDDev;
+
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
+ WPA_MIX_PAIR_CIPHER WpaMixPairCipher;
+
+ ULONG TxCount;
+ ULONG RxCount;
+ ULONG ReceivedByteCount;
+ ULONG TransmittedByteCount;
+ ULONG RxErrorCount;
+ ULONG RxDropCount;
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting. this is for reading registry setting only. not useful.
+ BOOLEAN bAutoTxRateSwitch;
+
+ //CIPHER_KEY SharedKey[SHARE_KEY_NUM]; // ref pAd->SharedKey[BSS][4]
+ UCHAR DefaultKeyId;
+
+ UCHAR TxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11, ...
+ UCHAR DesiredRates[MAX_LEN_OF_SUPPORTED_RATES];// OID_802_11_DESIRED_RATES
+ UCHAR DesiredRatesIndex;
+ UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
+
+// ULONG TimBitmap; // bit0 for broadcast, 1 for AID1, 2 for AID2, ...so on
+// ULONG TimBitmap2; // b0 for AID32, b1 for AID33, ... and so on
+ UCHAR TimBitmaps[WLAN_MAX_NUM_OF_TIM];
+
+ // WPA
+ UCHAR GMK[32];
+ UCHAR PMK[32];
+ UCHAR GTK[32];
+ BOOLEAN IEEE8021X;
+ BOOLEAN PreAuth;
+ UCHAR GNonce[32];
+ UCHAR PortSecured;
+ NDIS_802_11_PRIVACY_FILTER PrivacyFilter;
+ UCHAR BANClass3Data;
+ ULONG IsolateInterStaTraffic;
+
+ UCHAR RSNIE_Len[2];
+ UCHAR RSN_IE[2][MAX_LEN_OF_RSNIE];
+
+
+ UCHAR TimIELocationInBeacon;
+ UCHAR CapabilityInfoLocationInBeacon;
+ // outgoing BEACON frame buffer and corresponding TXWI
+ // PTXWI_STRUC BeaconTxWI; //
+ CHAR BeaconBuf[MAX_BEACON_SIZE]; // NOTE: BeaconBuf should be 4-byte aligned
+
+ BOOLEAN bHideSsid;
+ UINT16 StationKeepAliveTime; // unit: second
+
+ USHORT VLAN_VID;
+ USHORT VLAN_Priority;
+
+ RT_802_11_ACL AccessControlList;
+
+ // EDCA Qos
+ BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
+ BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
+
+ UCHAR DlsPTK[64]; // Due to windows dirver count on meetinghouse to handle 4-way shake
+
+ // For 802.1x daemon setting per BSS
+ UCHAR radius_srv_num;
+ RADIUS_SRV_INFO radius_srv_info[MAX_RADIUS_SRV_NUM];
+
+#ifdef RTL865X_SOC
+ unsigned int mylinkid;
+#endif
+
+
+ UINT32 RcvdConflictSsidCount;
+ UINT32 RcvdSpoofedAssocRespCount;
+ UINT32 RcvdSpoofedReassocRespCount;
+ UINT32 RcvdSpoofedProbeRespCount;
+ UINT32 RcvdSpoofedBeaconCount;
+ UINT32 RcvdSpoofedDisassocCount;
+ UINT32 RcvdSpoofedAuthCount;
+ UINT32 RcvdSpoofedDeauthCount;
+ UINT32 RcvdSpoofedUnknownMgmtCount;
+ UINT32 RcvdReplayAttackCount;
+
+ CHAR RssiOfRcvdConflictSsid;
+ CHAR RssiOfRcvdSpoofedAssocResp;
+ CHAR RssiOfRcvdSpoofedReassocResp;
+ CHAR RssiOfRcvdSpoofedProbeResp;
+ CHAR RssiOfRcvdSpoofedBeacon;
+ CHAR RssiOfRcvdSpoofedDisassoc;
+ CHAR RssiOfRcvdSpoofedAuth;
+ CHAR RssiOfRcvdSpoofedDeauth;
+ CHAR RssiOfRcvdSpoofedUnknownMgmt;
+ CHAR RssiOfRcvdReplayAttack;
+
+ BOOLEAN bBcnSntReq;
+ UCHAR BcnBufIdx;
+} MULTISSID_STRUCT, *PMULTISSID_STRUCT;
+
+
+
+#ifdef DOT11N_DRAFT3
+typedef enum _BSS2040COEXIST_FLAG{
+ BSS_2040_COEXIST_DISABLE = 0,
+ BSS_2040_COEXIST_TIMER_FIRED = 1,
+ BSS_2040_COEXIST_INFO_SYNC = 2,
+ BSS_2040_COEXIST_INFO_NOTIFY = 4,
+}BSS2040COEXIST_FLAG;
+#endif // DOT11N_DRAFT3 //
+
+// configuration common to OPMODE_AP as well as OPMODE_STA
+typedef struct _COMMON_CONFIG {
+
+ BOOLEAN bCountryFlag;
+ UCHAR CountryCode[3];
+ UCHAR Geography;
+ UCHAR CountryRegion; // Enum of country region, 0:FCC, 1:IC, 2:ETSI, 3:SPAIN, 4:France, 5:MKK, 6:MKK1, 7:Israel
+ UCHAR CountryRegionForABand; // Enum of country region for A band
+ UCHAR PhyMode; // PHY_11A, PHY_11B, PHY_11BG_MIXED, PHY_ABG_MIXED
+ USHORT Dsifs; // in units of usec
+ ULONG PacketFilter; // Packet filter for receiving
+
+ CHAR Ssid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
+ UCHAR SsidLen; // the actual ssid length in used
+ UCHAR LastSsidLen; // the actual ssid length in used
+ CHAR LastSsid[MAX_LEN_OF_SSID]; // NOT NULL-terminated
+ UCHAR LastBssid[MAC_ADDR_LEN];
+
+ UCHAR Bssid[MAC_ADDR_LEN];
+ USHORT BeaconPeriod;
+ UCHAR Channel;
+ UCHAR CentralChannel; // Central Channel when using 40MHz is indicating. not real channel.
+
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRateLen;
+ UCHAR DesireRate[MAX_LEN_OF_SUPPORTED_RATES]; // OID_802_11_DESIRED_RATES
+ UCHAR MaxDesiredRate;
+ UCHAR ExpectedACKRate[MAX_LEN_OF_SUPPORTED_RATES];
+
+ ULONG BasicRateBitmap; // backup basic ratebitmap
+
+ BOOLEAN bAPSDCapable;
+ BOOLEAN bInServicePeriod;
+ BOOLEAN bAPSDAC_BE;
+ BOOLEAN bAPSDAC_BK;
+ BOOLEAN bAPSDAC_VI;
+ BOOLEAN bAPSDAC_VO;
+ BOOLEAN bNeedSendTriggerFrame;
+ BOOLEAN bAPSDForcePowerSave; // Force power save mode, should only use in APSD-STAUT
+ ULONG TriggerTimerCount;
+ UCHAR MaxSPLength;
+ UCHAR BBPCurrentBW; // BW_10, BW_20, BW_40
+ // move to MULTISSID_STRUCT for MBSS
+ //HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+ REG_TRANSMIT_SETTING RegTransmitSetting; //registry transmit setting. this is for reading registry setting only. not useful.
+ //UCHAR FixedTxMode; // Fixed Tx Mode (CCK, OFDM), for HT fixed tx mode (GF, MIX) , refer to RegTransmitSetting.field.HTMode
+ UCHAR TxRate; // Same value to fill in TXD. TxRate is 6-bit
+ UCHAR MaxTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
+ UCHAR TxRateIndex; // Tx rate index in RateSwitchTable
+ UCHAR TxRateTableSize; // Valid Tx rate table size in RateSwitchTable
+ //BOOLEAN bAutoTxRateSwitch;
+ UCHAR MinTxRate; // RATE_1, RATE_2, RATE_5_5, RATE_11
+ UCHAR RtsRate; // RATE_xxx
+ HTTRANSMIT_SETTING MlmeTransmit; // MGMT frame PHY rate setting when operatin at Ht rate.
+ UCHAR MlmeRate; // RATE_xxx, used to send MLME frames
+ UCHAR BasicMlmeRate; // Default Rate for sending MLME frames
+
+ USHORT RtsThreshold; // in unit of BYTE
+ USHORT FragmentThreshold; // in unit of BYTE
+
+ UCHAR TxPower; // in unit of mW
+ ULONG TxPowerPercentage; // 0~100 %
+ ULONG TxPowerDefault; // keep for TxPowerPercentage
+
+#ifdef DOT11_N_SUPPORT
+ BACAP_STRUC BACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
+ BACAP_STRUC REGBACapability; // NO USE = 0XFF ; IMMED_BA =1 ; DELAY_BA=0
+#endif // DOT11_N_SUPPORT //
+ IOT_STRUC IOTestParm; // 802.11n InterOpbility Test Parameter;
+ ULONG TxPreamble; // Rt802_11PreambleLong, Rt802_11PreambleShort, Rt802_11PreambleAuto
+ BOOLEAN bUseZeroToDisableFragment; // Microsoft use 0 as disable
+ ULONG UseBGProtection; // 0: auto, 1: always use, 2: always not use
+ BOOLEAN bUseShortSlotTime; // 0: disable, 1 - use short slot (9us)
+ BOOLEAN bEnableTxBurst; // 1: enble TX PACKET BURST, 0: disable TX PACKET BURST
+ BOOLEAN bAggregationCapable; // 1: enable TX aggregation when the peer supports it
+ BOOLEAN bPiggyBackCapable; // 1: enable TX piggy-back according MAC's version
+ BOOLEAN bIEEE80211H; // 1: enable IEEE802.11h spec.
+ ULONG DisableOLBCDetect; // 0: enable OLBC detect; 1 disable OLBC detect
+
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN bRdg;
+#endif // DOT11_N_SUPPORT //
+ BOOLEAN bWmmCapable; // 0:disable WMM, 1:enable WMM
+ QOS_CAPABILITY_PARM APQosCapability; // QOS capability of the current associated AP
+ EDCA_PARM APEdcaParm; // EDCA parameters of the current associated AP
+ QBSS_LOAD_PARM APQbssLoad; // QBSS load of the current associated AP
+ UCHAR AckPolicy[4]; // ACK policy of the specified AC. see ACK_xxx
+#ifdef CONFIG_STA_SUPPORT
+ BOOLEAN bDLSCapable; // 0:disable DLS, 1:enable DLS
+#endif // CONFIG_STA_SUPPORT //
+ // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
+ // BOOLEAN control, either ON or OFF. These flags should always be accessed via
+ // OPSTATUS_TEST_FLAG(), OPSTATUS_SET_FLAG(), OP_STATUS_CLEAR_FLAG() macros.
+ // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition
+ ULONG OpStatusFlags;
+
+ BOOLEAN NdisRadioStateOff; //For HCT 12.0, set this flag to TRUE instead of called MlmeRadioOff.
+ ABGBAND_STATE BandState; // For setting BBP used on B/G or A mode.
+ BOOLEAN bRxAntDiversity; // 0:disable, 1:enable Software Rx Antenna Diversity.
+
+ // IEEE802.11H--DFS.
+ RADAR_DETECT_STRUCT RadarDetect;
+
+#ifdef CARRIER_DETECTION_SUPPORT
+ CARRIER_DETECTION CarrierDetect;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ // HT
+ UCHAR BASize; // USer desired BAWindowSize. Should not exceed our max capability
+ //RT_HT_CAPABILITY SupportedHtPhy;
+ RT_HT_CAPABILITY DesiredHtPhy;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHTInfo; // Useful as AP.
+ //This IE is used with channel switch announcement element when changing to a new 40MHz.
+ //This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp.
+ NEW_EXT_CHAN_IE NewExtChanOffset; //7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present
+
+#ifdef DOT11N_DRAFT3
+ UCHAR Bss2040CoexistFlag; // bit 0: bBssCoexistTimerRunning, bit 1: NeedSyncAddHtInfo.
+ RALINK_TIMER_STRUCT Bss2040CoexistTimer;
+
+ //This IE is used for 20/40 BSS Coexistence.
+ BSS_2040_COEXIST_IE BSS2040CoexistInfo;
+ // ====== 11n D3.0 =======================>
+ USHORT Dot11OBssScanPassiveDwell; // Unit : TU. 5~1000
+ USHORT Dot11OBssScanActiveDwell; // Unit : TU. 10~1000
+ USHORT Dot11BssWidthTriggerScanInt; // Unit : Second
+ USHORT Dot11OBssScanPassiveTotalPerChannel; // Unit : TU. 200~10000
+ USHORT Dot11OBssScanActiveTotalPerChannel; // Unit : TU. 20~10000
+ USHORT Dot11BssWidthChanTranDelayFactor;
+ USHORT Dot11OBssScanActivityThre; // Unit : percentage
+
+ ULONG Dot11BssWidthChanTranDelay; // multiple of (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
+ ULONG CountDownCtr; // CountDown Counter from (Dot11BssWidthTriggerScanInt * Dot11BssWidthChanTranDelayFactor)
+
+ NDIS_SPIN_LOCK TriggerEventTabLock;
+ BSS_2040_COEXIST_IE LastBSSCoexist2040;
+ BSS_2040_COEXIST_IE BSSCoexist2040;
+ TRIGGER_EVENT_TAB TriggerEventTab;
+ UCHAR ChannelListIdx;
+ // <====== 11n D3.0 =======================
+ BOOLEAN bOverlapScanning;
+#endif // DOT11N_DRAFT3 //
+
+ BOOLEAN bHTProtect;
+ BOOLEAN bMIMOPSEnable;
+ BOOLEAN bBADecline;
+ BOOLEAN bDisableReordering;
+ BOOLEAN bForty_Mhz_Intolerant;
+ BOOLEAN bExtChannelSwitchAnnouncement;
+ BOOLEAN bRcvBSSWidthTriggerEvents;
+ ULONG LastRcvBSSWidthTriggerEventsTime;
+
+ UCHAR TxBASize;
+#endif // DOT11_N_SUPPORT //
+
+ // Enable wireless event
+ BOOLEAN bWirelessEvent;
+ BOOLEAN bWiFiTest; // Enable this parameter for WiFi test
+
+ // Tx & Rx Stream number selection
+ UCHAR TxStream;
+ UCHAR RxStream;
+
+ // transmit phy mode, trasmit rate for Multicast.
+#ifdef MCAST_RATE_SPECIFIC
+ UCHAR McastTransmitMcs;
+ UCHAR McastTransmitPhyMode;
+#endif // MCAST_RATE_SPECIFIC //
+
+ BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
+
+#ifdef RT2870
+ BOOLEAN bMultipleIRP; // Multiple Bulk IN flag
+ UCHAR NumOfBulkInIRP; // if bMultipleIRP == TRUE, NumOfBulkInIRP will be 4 otherwise be 1
+ RT_HT_CAPABILITY SupportedHtPhy;
+ ULONG MaxPktOneTxBulk;
+ UCHAR TxBulkFactor;
+ UCHAR RxBulkFactor;
+
+ BEACON_SYNC_STRUCT *pBeaconSync;
+ RALINK_TIMER_STRUCT BeaconUpdateTimer;
+ UINT32 BeaconAdjust;
+ UINT32 BeaconFactor;
+ UINT32 BeaconRemain;
+#endif // RT2870 //
+
+
+ NDIS_SPIN_LOCK MeasureReqTabLock;
+ PMEASURE_REQ_TAB pMeasureReqTab;
+
+ NDIS_SPIN_LOCK TpcReqTabLock;
+ PTPC_REQ_TAB pTpcReqTab;
+
+ // transmit phy mode, trasmit rate for Multicast.
+#ifdef MCAST_RATE_SPECIFIC
+ HTTRANSMIT_SETTING MCastPhyMode;
+#endif // MCAST_RATE_SPECIFIC //
+
+#ifdef SINGLE_SKU
+ UINT16 DefineMaxTxPwr;
+#endif // SINGLE_SKU //
+
+
+} COMMON_CONFIG, *PCOMMON_CONFIG;
+
+
+#ifdef CONFIG_STA_SUPPORT
+/* Modified by Wu Xi-Kun 4/21/2006 */
+// STA configuration and status
+typedef struct _STA_ADMIN_CONFIG {
+ // GROUP 1 -
+ // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
+ // the user intended configuration, but not necessary fully equal to the final
+ // settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either
+ // AP or IBSS holder).
+ // Once initialized, user configuration can only be changed via OID_xxx
+ UCHAR BssType; // BSS_INFRA or BSS_ADHOC
+ USHORT AtimWin; // used when starting a new IBSS
+
+ // GROUP 2 -
+ // User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe
+ // the user intended configuration, and should be always applied to the final
+ // settings in ACTIVE BSS without compromising with the BSS holder.
+ // Once initialized, user configuration can only be changed via OID_xxx
+ UCHAR RssiTrigger;
+ UCHAR RssiTriggerMode; // RSSI_TRIGGERED_UPON_BELOW_THRESHOLD or RSSI_TRIGGERED_UPON_EXCCEED_THRESHOLD
+ USHORT DefaultListenCount; // default listen count;
+ ULONG WindowsPowerMode; // Power mode for AC power
+ ULONG WindowsBatteryPowerMode; // Power mode for battery if exists
+ BOOLEAN bWindowsACCAMEnable; // Enable CAM power mode when AC on
+ BOOLEAN bAutoReconnect; // Set to TRUE when setting OID_802_11_SSID with no matching BSSID
+ ULONG WindowsPowerProfile; // Windows power profile, for NDIS5.1 PnP
+
+ // MIB:ieee802dot11.dot11smt(1).dot11StationConfigTable(1)
+ USHORT Psm; // power management mode (PWR_ACTIVE|PWR_SAVE)
+ USHORT DisassocReason;
+ UCHAR DisassocSta[MAC_ADDR_LEN];
+ USHORT DeauthReason;
+ UCHAR DeauthSta[MAC_ADDR_LEN];
+ USHORT AuthFailReason;
+ UCHAR AuthFailSta[MAC_ADDR_LEN];
+
+ NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_WEP_STATUS OrigWepStatus; // Original wep status set from OID
+
+ // Add to support different cipher suite for WPA2/WPA mode
+ NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
+ BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
+ USHORT RsnCapability;
+
+ NDIS_802_11_WEP_STATUS GroupKeyWepStatus;
+
+ UCHAR PMK[32]; // WPA PSK mode PMK
+ UCHAR PTK[64]; // WPA PSK mode PTK
+ UCHAR GTK[32]; // GTK from authenticator
+ BSSID_INFO SavedPMK[PMKID_NO];
+ UINT SavedPMKNum; // Saved PMKID number
+
+ UCHAR DefaultKeyId;
+
+
+ // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
+ UCHAR PortSecured;
+
+ // For WPA countermeasures
+ ULONG LastMicErrorTime; // record last MIC error time
+ ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
+ BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
+ // For WPA-PSK supplicant state
+ WPA_STATE WpaState; // Default is SS_NOTUSE and handled by microsoft 802.1x
+ UCHAR ReplayCounter[8];
+ UCHAR ANonce[32]; // ANonce for WPA-PSK from aurhenticator
+ UCHAR SNonce[32]; // SNonce for WPA-PSK
+
+ UCHAR LastSNR0; // last received BEACON's SNR
+ UCHAR LastSNR1; // last received BEACON's SNR for 2nd antenna
+ RSSI_SAMPLE RssiSample;
+ ULONG NumOfAvgRssiSample;
+
+ ULONG LastBeaconRxTime; // OS's timestamp of the last BEACON RX time
+ ULONG Last11bBeaconRxTime; // OS's timestamp of the last 11B BEACON RX time
+ ULONG Last11gBeaconRxTime; // OS's timestamp of the last 11G BEACON RX time
+ ULONG Last20NBeaconRxTime; // OS's timestamp of the last 20MHz N BEACON RX time
+
+ ULONG LastScanTime; // Record last scan time for issue BSSID_SCAN_LIST
+ ULONG ScanCnt; // Scan counts since most recent SSID, BSSID, SCAN OID request
+ BOOLEAN bSwRadio; // Software controlled Radio On/Off, TRUE: On
+ BOOLEAN bHwRadio; // Hardware controlled Radio On/Off, TRUE: On
+ BOOLEAN bRadio; // Radio state, And of Sw & Hw radio state
+ BOOLEAN bHardwareRadio; // Hardware controlled Radio enabled
+ BOOLEAN bShowHiddenSSID; // Show all known SSID in SSID list get operation
+
+ //BOOLEAN AdhocBOnlyJoined; // Indicate Adhoc B Join.
+ //BOOLEAN AdhocBGJoined; // Indicate Adhoc B/G Join.
+ //BOOLEAN Adhoc20NJoined; // Indicate Adhoc 20MHz N Join.
+
+ // New for WPA, windows want us to to keep association information and
+ // Fixed IEs from last association response
+ NDIS_802_11_ASSOCIATION_INFORMATION AssocInfo;
+ USHORT ReqVarIELen; // Length of next VIE include EID & Length
+ UCHAR ReqVarIEs[MAX_VIE_LEN]; // The content saved here should be little-endian format.
+ USHORT ResVarIELen; // Length of next VIE include EID & Length
+ UCHAR ResVarIEs[MAX_VIE_LEN];
+
+ UCHAR RSNIE_Len;
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be little-endian format.
+
+ // New variables used for CCX 1.0
+ BOOLEAN bCkipOn;
+ BOOLEAN bCkipCmicOn;
+ UCHAR CkipFlag;
+ UCHAR GIV[3]; //for CCX iv
+ UCHAR RxSEQ[4];
+ UCHAR TxSEQ[4];
+ UCHAR CKIPMIC[4];
+ UCHAR LeapAuthMode;
+ LEAP_AUTH_INFO LeapAuthInfo;
+ UCHAR HashPwd[16];
+ UCHAR NetworkChallenge[8];
+ UCHAR NetworkChallengeResponse[24];
+ UCHAR PeerChallenge[8];
+
+ UCHAR PeerChallengeResponse[24];
+ UCHAR SessionKey[16]; //Network session keys (NSK)
+ RALINK_TIMER_STRUCT LeapAuthTimer;
+ ROGUEAP_TABLE RogueApTab; //Cisco CCX1 Rogue AP Detection
+
+ // New control flags for CCX
+ CCX_CONTROL CCXControl; // Master administration state
+ BOOLEAN CCXEnable; // Actual CCX state
+ UCHAR CCXScanChannel; // Selected channel for CCX beacon request
+ USHORT CCXScanTime; // Time out to wait for beacon and probe response
+ UCHAR CCXReqType; // Current processing CCX request type
+ BSS_TABLE CCXBssTab; // BSS Table
+ UCHAR FrameReportBuf[2048]; // Buffer for creating frame report
+ USHORT FrameReportLen; // Current Frame report length
+ ULONG CLBusyBytes; // Save the total bytes received durning channel load scan time
+ USHORT RPIDensity[8]; // Array for RPI density collection
+ // Start address of each BSS table within FrameReportBuf
+ // It's important to update the RxPower of the corresponding Bss
+ USHORT BssReportOffset[MAX_LEN_OF_BSS_TABLE];
+ USHORT BeaconToken; // Token for beacon report
+ ULONG LastBssIndex; // Most current reported Bss index
+ RM_REQUEST_ACTION MeasurementRequest[16]; // Saved measurement request
+ UCHAR RMReqCnt; // Number of measurement request saved.
+ UCHAR CurrentRMReqIdx; // Number of measurement request saved.
+ BOOLEAN ParallelReq; // Parallel measurement, only one request performed,
+ // It must be the same channel with maximum duration
+ USHORT ParallelDuration; // Maximum duration for parallel measurement
+ UCHAR ParallelChannel; // Only one channel with parallel measurement
+ USHORT IAPPToken; // IAPP dialog token
+ UCHAR CCXQosECWMin; // Cisco QOS ECWMin for AC 0
+ UCHAR CCXQosECWMax; // Cisco QOS ECWMax for AC 0
+ // Hack for channel load and noise histogram parameters
+ UCHAR NHFactor; // Parameter for Noise histogram
+ UCHAR CLFactor; // Parameter for channel load
+
+ UCHAR KRK[16]; //Key Refresh Key.
+ UCHAR BTK[32]; //Base Transient Key
+ BOOLEAN CCKMLinkUpFlag;
+ ULONG CCKMRN; //(Re)Association request number.
+ LARGE_INTEGER CCKMBeaconAtJoinTimeStamp; //TSF timer for Re-assocaite to the new AP
+ UCHAR AironetCellPowerLimit; //in dBm
+ UCHAR AironetIPAddress[4]; //eg. 192.168.1.1
+ BOOLEAN CCXAdjacentAPReportFlag; //flag for determining report Assoc Lost time
+ CHAR CCXAdjacentAPSsid[MAX_LEN_OF_SSID]; //Adjacent AP's SSID report
+ UCHAR CCXAdjacentAPSsidLen; // the actual ssid length in used
+ UCHAR CCXAdjacentAPBssid[MAC_ADDR_LEN]; //Adjacent AP's BSSID report
+ USHORT CCXAdjacentAPChannel;
+ ULONG CCXAdjacentAPLinkDownTime; //for Spec S32.
+
+ RALINK_TIMER_STRUCT StaQuickResponeForRateUpTimer;
+ BOOLEAN StaQuickResponeForRateUpTimerRunning;
+
+ UCHAR DtimCount; // 0.. DtimPeriod-1
+ UCHAR DtimPeriod; // default = 3
+
+#ifdef QOS_DLS_SUPPORT
+ RT_802_11_DLS DLSEntry[MAX_NUM_OF_DLS_ENTRY];
+ UCHAR DlsReplayCounter[8];
+#endif // QOS_DLS_SUPPORT //
+ ////////////////////////////////////////////////////////////////////////////////////////
+ // This is only for WHQL test.
+ BOOLEAN WhqlTest;
+ ////////////////////////////////////////////////////////////////////////////////////////
+
+ RALINK_TIMER_STRUCT WpaDisassocAndBlockAssocTimer;
+ // Fast Roaming
+ BOOLEAN bFastRoaming; // 0:disable fast roaming, 1:enable fast roaming
+ CHAR dBmToRoam; // the condition to roam when receiving Rssi less than this value. It's negative value.
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ BOOLEAN IEEE8021X;
+ BOOLEAN IEEE8021x_required_keys;
+ CIPHER_KEY DesireSharedKey[4]; // Record user desired WEP keys
+ UCHAR DesireSharedKeyId;
+
+ // 0: driver ignores wpa_supplicant
+ // 1: wpa_supplicant initiates scanning and AP selection
+ // 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters
+ UCHAR WpaSupplicantUP;
+ UCHAR WpaSupplicantScanCount;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ CHAR dev_name[16];
+ USHORT OriDevType;
+
+ BOOLEAN bTGnWifiTest;
+ BOOLEAN bScanReqIsFromWebUI;
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting;
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ UCHAR IEEE80211dClientMode;
+ UCHAR StaOriCountryCode[3];
+ UCHAR StaOriGeography;
+#endif // EXT_BUILD_CHANNEL_LIST //
+} STA_ADMIN_CONFIG, *PSTA_ADMIN_CONFIG;
+
+// This data structure keep the current active BSS/IBSS's configuration that this STA
+// had agreed upon joining the network. Which means these parameters are usually decided
+// by the BSS/IBSS creator instead of user configuration. Data in this data structurre
+// is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE.
+// Normally, after SCAN or failed roaming attempts, we need to recover back to
+// the current active settings.
+typedef struct _STA_ACTIVE_CONFIG {
+ USHORT Aid;
+ USHORT AtimWin; // in kusec; IBSS parameter set element
+ USHORT CapabilityInfo;
+ USHORT CfpMaxDuration;
+ USHORT CfpPeriod;
+
+ // Copy supported rate from desired AP's beacon. We are trying to match
+ // AP's supported and extended rate settings.
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen;
+ UCHAR ExtRateLen;
+ // Copy supported ht from desired AP's beacon. We are trying to match
+ RT_HT_PHY_INFO SupportedPhyInfo;
+ RT_HT_CAPABILITY SupportedHtPhy;
+} STA_ACTIVE_CONFIG, *PSTA_ACTIVE_CONFIG;
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef RT2870
+typedef struct RT_ADD_PAIRWISE_KEY_ENTRY {
+ NDIS_802_11_MAC_ADDRESS MacAddr;
+ USHORT MacTabMatchWCID; // ASIC
+ CIPHER_KEY CipherKey;
+} RT_ADD_PAIRWISE_KEY_ENTRY,*PRT_ADD_PAIRWISE_KEY_ENTRY;
+#endif // RT2870 //
+
+// ----------- start of AP --------------------------
+// AUTH-RSP State Machine Aux data structure
+typedef struct _AP_MLME_AUX {
+ UCHAR Addr[MAC_ADDR_LEN];
+ USHORT Alg;
+ CHAR Challenge[CIPHER_TEXT_LEN];
+} AP_MLME_AUX, *PAP_MLME_AUX;
+
+// structure to define WPA Group Key Rekey Interval
+typedef struct PACKED _RT_802_11_WPA_REKEY {
+ ULONG ReKeyMethod; // mechanism for rekeying: 0:disable, 1: time-based, 2: packet-based
+ ULONG ReKeyInterval; // time-based: seconds, packet-based: kilo-packets
+} RT_WPA_REKEY,*PRT_WPA_REKEY, RT_802_11_WPA_REKEY, *PRT_802_11_WPA_REKEY;
+
+typedef struct _MAC_TABLE_ENTRY {
+ //Choose 1 from ValidAsWDS and ValidAsCLI to validize.
+ BOOLEAN ValidAsCLI; // Sta mode, set this TRUE after Linkup,too.
+ BOOLEAN ValidAsWDS; // This is WDS Entry. only for AP mode.
+ BOOLEAN ValidAsApCli; //This is a AP-Client entry, only for AP mode which enable AP-Client functions.
+ BOOLEAN ValidAsMesh;
+ BOOLEAN ValidAsDls; // This is DLS Entry. only for STA mode.
+ BOOLEAN isCached;
+ BOOLEAN bIAmBadAtheros;
+
+ UCHAR EnqueueEapolStartTimerRunning; // Enqueue EAPoL-Start for triggering EAP SM
+ //jan for wpa
+ // record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB
+ UCHAR CMTimerRunning;
+ UCHAR apidx; // MBSS number
+ UCHAR RSNIE_Len;
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE];
+ UCHAR ANonce[LEN_KEY_DESC_NONCE];
+ UCHAR R_Counter[LEN_KEY_DESC_REPLAY];
+ UCHAR PTK[64];
+ UCHAR ReTryCounter;
+ RALINK_TIMER_STRUCT RetryTimer;
+ RALINK_TIMER_STRUCT EnqueueStartForPSKTimer; // A timer which enqueue EAPoL-Start for triggering PSK SM
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
+ NDIS_802_11_WEP_STATUS WepStatus;
+ AP_WPA_STATE WpaState;
+ GTK_STATE GTKState;
+ USHORT PortSecured;
+ NDIS_802_11_PRIVACY_FILTER PrivacyFilter; // PrivacyFilter enum for 802.1X
+ CIPHER_KEY PairwiseKey;
+ PVOID pAd;
+ INT PMKID_CacheIdx;
+ UCHAR PMKID[LEN_PMKID];
+
+
+ UCHAR Addr[MAC_ADDR_LEN];
+ UCHAR PsMode;
+ SST Sst;
+ AUTH_STATE AuthState; // for SHARED KEY authentication state machine used only
+ BOOLEAN IsReassocSta; // Indicate whether this is a reassociation procedure
+ USHORT Aid;
+ USHORT CapabilityInfo;
+ UCHAR LastRssi;
+ ULONG NoDataIdleCount;
+ UINT16 StationKeepAliveCount; // unit: second
+ ULONG PsQIdleCount;
+ QUEUE_HEADER PsQueue;
+
+ UINT32 StaConnectTime; // the live time of this station since associated with AP
+
+
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN bSendBAR;
+ USHORT NoBADataCountDown;
+
+ UINT32 CachedBuf[16]; // UINT (4 bytes) for alignment
+ UINT TxBFCount; // 3*3
+#endif // DOT11_N_SUPPORT //
+ UINT FIFOCount;
+ UINT DebugFIFOCount;
+ UINT DebugTxCount;
+ BOOLEAN bDlsInit;
+
+
+//====================================================
+//WDS entry needs these
+// rt2860 add this. if ValidAsWDS==TRUE, MatchWDSTabIdx is the index in WdsTab.MacTab
+ UINT MatchWDSTabIdx;
+ UCHAR MaxSupportedRate;
+ UCHAR CurrTxRate;
+ UCHAR CurrTxRateIndex;
+ // to record the each TX rate's quality. 0 is best, the bigger the worse.
+ USHORT TxQuality[MAX_STEP_OF_TX_RATE_SWITCH];
+// USHORT OneSecTxOkCount;
+ UINT32 OneSecTxNoRetryOkCount;
+ UINT32 OneSecTxRetryOkCount;
+ UINT32 OneSecTxFailCount;
+ UINT32 ContinueTxFailCnt;
+ UINT32 CurrTxRateStableTime; // # of second in current TX rate
+ UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
+//====================================================
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+ UINT MatchDlsEntryIdx; // indicate the index in pAd->StaCfg.DLSEntry
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+ BOOLEAN fNoisyEnvironment;
+ BOOLEAN fLastSecAccordingRSSI;
+ UCHAR LastSecTxRateChangeAction; // 0: no change, 1:rate UP, 2:rate down
+ CHAR LastTimeTxRateChangeAction; //Keep last time value of LastSecTxRateChangeAction
+ ULONG LastTxOkCount;
+ UCHAR PER[MAX_STEP_OF_TX_RATE_SWITCH];
+
+ // a bitmap of BOOLEAN flags. each bit represent an operation status of a particular
+ // BOOLEAN control, either ON or OFF. These flags should always be accessed via
+ // CLIENT_STATUS_TEST_FLAG(), CLIENT_STATUS_SET_FLAG(), CLIENT_STATUS_CLEAR_FLAG() macros.
+ // see fOP_STATUS_xxx in RTMP_DEF.C for detail bit definition. fCLIENT_STATUS_AMSDU_INUSED
+ ULONG ClientStatusFlags;
+
+ // TODO: Shall we move that to DOT11_N_SUPPORT???
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;// For transmit phy setting in TXWI.
+
+#ifdef DOT11_N_SUPPORT
+ // HT EWC MIMO-N used parameters
+ USHORT RXBAbitmap; // fill to on-chip RXWI_BA_BITMASK in 8.1.3RX attribute entry format
+ USHORT TXBAbitmap; // This bitmap as originator, only keep in software used to mark AMPDU bit in TXWI
+ USHORT TXAutoBAbitmap;
+ USHORT BADeclineBitmap;
+ USHORT BARecWcidArray[NUM_OF_TID]; // The mapping wcid of recipient session. if RXBAbitmap bit is masked
+ USHORT BAOriWcidArray[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
+ USHORT BAOriSequence[NUM_OF_TID]; // The mapping wcid of originator session. if TXBAbitmap bit is masked
+
+ // 802.11n features.
+ UCHAR MpduDensity;
+ UCHAR MaxRAmpduFactor;
+ UCHAR AMsduSize;
+ UCHAR MmpsMode; // MIMO power save more.
+
+ HT_CAPABILITY_IE HTCapability;
+
+#ifdef DOT11N_DRAFT3
+ UCHAR BSS2040CoexistenceMgmtSupport;
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+ BOOLEAN bAutoTxRateSwitch;
+
+ UCHAR RateLen;
+ struct _MAC_TABLE_ENTRY *pNext;
+ USHORT TxSeq[NUM_OF_TID];
+ USHORT NonQosDataSeq;
+
+ RSSI_SAMPLE RssiSample;
+
+ UINT32 TXMCSExpected[16];
+ UINT32 TXMCSSuccessful[16];
+ UINT32 TXMCSFailed[16];
+ UINT32 TXMCSAutoFallBack[16][16];
+
+#ifdef CONFIG_STA_SUPPORT
+ ULONG LastBeaconRxTime;
+#endif // CONFIG_STA_SUPPORT //
+} MAC_TABLE_ENTRY, *PMAC_TABLE_ENTRY;
+
+typedef struct _MAC_TABLE {
+ USHORT Size;
+ MAC_TABLE_ENTRY *Hash[HASH_TABLE_SIZE];
+ MAC_TABLE_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
+ QUEUE_HEADER McastPsQueue;
+ ULONG PsQIdleCount;
+ BOOLEAN fAnyStationInPsm;
+ BOOLEAN fAnyStationBadAtheros; // Check if any Station is atheros 802.11n Chip. We need to use RTS/CTS with Atheros 802,.11n chip.
+ BOOLEAN fAnyTxOPForceDisable; // Check if it is necessary to disable BE TxOP
+ BOOLEAN fAllStationAsRalink; // Check if all stations are ralink-chipset
+#ifdef DOT11_N_SUPPORT
+ BOOLEAN fAnyStationIsLegacy; // Check if I use legacy rate to transmit to my BSS Station/
+ BOOLEAN fAnyStationNonGF; // Check if any Station can't support GF.
+ BOOLEAN fAnyStation20Only; // Check if any Station can't support GF.
+ BOOLEAN fAnyStationMIMOPSDynamic; // Check if any Station is MIMO Dynamic
+ BOOLEAN fAnyBASession; // Check if there is BA session. Force turn on RTS/CTS
+#endif // DOT11_N_SUPPORT //
+} MAC_TABLE, *PMAC_TABLE;
+
+#ifdef DOT11_N_SUPPORT
+#define IS_HT_STA(_pMacEntry) \
+ (_pMacEntry->MaxHTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define IS_HT_RATE(_pMacEntry) \
+ (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+
+#define PEER_IS_HT_RATE(_pMacEntry) \
+ (_pMacEntry->HTPhyMode.field.MODE >= MODE_HTMIX)
+#endif // DOT11_N_SUPPORT //
+
+typedef struct _WDS_ENTRY {
+ BOOLEAN Valid;
+ UCHAR Addr[MAC_ADDR_LEN];
+ ULONG NoDataIdleCount;
+ struct _WDS_ENTRY *pNext;
+} WDS_ENTRY, *PWDS_ENTRY;
+
+typedef struct _WDS_TABLE_ENTRY {
+ USHORT Size;
+ UCHAR WdsAddr[MAC_ADDR_LEN];
+ WDS_ENTRY *Hash[HASH_TABLE_SIZE];
+ WDS_ENTRY Content[MAX_LEN_OF_MAC_TABLE];
+ UCHAR MaxSupportedRate;
+ UCHAR CurrTxRate;
+ USHORT TxQuality[MAX_LEN_OF_SUPPORTED_RATES];
+ USHORT OneSecTxOkCount;
+ USHORT OneSecTxRetryOkCount;
+ USHORT OneSecTxFailCount;
+ ULONG CurrTxRateStableTime; // # of second in current TX rate
+ UCHAR TxRateUpPenalty; // extra # of second penalty due to last unstable condition
+} WDS_TABLE_ENTRY, *PWDS_TABLE_ENTRY;
+
+typedef struct _RT_802_11_WDS_ENTRY {
+ PNET_DEV dev;
+ UCHAR Valid;
+ UCHAR PhyMode;
+ UCHAR PeerWdsAddr[MAC_ADDR_LEN];
+ UCHAR MacTabMatchWCID; // ASIC
+ NDIS_802_11_WEP_STATUS WepStatus;
+ UCHAR KeyIdx;
+ CIPHER_KEY WdsKey;
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
+} RT_802_11_WDS_ENTRY, *PRT_802_11_WDS_ENTRY;
+
+typedef struct _WDS_TABLE {
+ UCHAR Mode;
+ ULONG Size;
+ RT_802_11_WDS_ENTRY WdsEntry[MAX_WDS_ENTRY];
+} WDS_TABLE, *PWDS_TABLE;
+
+typedef struct _APCLI_STRUCT {
+ PNET_DEV dev;
+#ifdef RTL865X_SOC
+ unsigned int mylinkid;
+#endif
+ BOOLEAN Enable; // Set it as 1 if the apcli interface was configured to "1" or by iwpriv cmd "ApCliEnable"
+ BOOLEAN Valid; // Set it as 1 if the apcli interface associated success to remote AP.
+ UCHAR MacTabWCID; //WCID value, which point to the entry of ASIC Mac table.
+ UCHAR SsidLen;
+ CHAR Ssid[MAX_LEN_OF_SSID];
+
+ UCHAR CfgSsidLen;
+ CHAR CfgSsid[MAX_LEN_OF_SSID];
+ UCHAR CfgApCliBssid[ETH_LENGTH_OF_ADDRESS];
+ UCHAR CurrentAddress[ETH_LENGTH_OF_ADDRESS];
+
+ ULONG ApCliRcvBeaconTime;
+
+ ULONG CtrlCurrState;
+ ULONG SyncCurrState;
+ ULONG AuthCurrState;
+ ULONG AssocCurrState;
+ ULONG WpaPskCurrState;
+
+ USHORT AuthReqCnt;
+ USHORT AssocReqCnt;
+
+ ULONG ClientStatusFlags;
+ UCHAR MpduDensity;
+
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode; // This should match to whatever microsoft defined
+ NDIS_802_11_WEP_STATUS WepStatus;
+
+ // Add to support different cipher suite for WPA2/WPA mode
+ NDIS_802_11_ENCRYPTION_STATUS GroupCipher; // Multicast cipher suite
+ NDIS_802_11_ENCRYPTION_STATUS PairCipher; // Unicast cipher suite
+ BOOLEAN bMixCipher; // Indicate current Pair & Group use different cipher suites
+ USHORT RsnCapability;
+
+ UCHAR PSK[100]; // reserve PSK key material
+ UCHAR PSKLen;
+ UCHAR PMK[32]; // WPA PSK mode PMK
+ //UCHAR PTK[64]; // WPA PSK mode PTK
+ UCHAR GTK[32]; // GTK from authenticator
+
+ //CIPHER_KEY PairwiseKey;
+ CIPHER_KEY SharedKey[SHARE_KEY_NUM];
+ UCHAR DefaultKeyId;
+
+ // WPA 802.1x port control, WPA_802_1X_PORT_SECURED, WPA_802_1X_PORT_NOT_SECURED
+ //UCHAR PortSecured;
+
+ // store RSN_IE built by driver
+ UCHAR RSN_IE[MAX_LEN_OF_RSNIE]; // The content saved here should be convert to little-endian format.
+ UCHAR RSNIE_Len;
+
+ // For WPA countermeasures
+ ULONG LastMicErrorTime; // record last MIC error time
+ //ULONG MicErrCnt; // Should be 0, 1, 2, then reset to zero (after disassoiciation).
+ BOOLEAN bBlockAssoc; // Block associate attempt for 60 seconds after counter measure occurred.
+
+ // For WPA-PSK supplicant state
+ //WPA_STATE WpaState; // Default is SS_NOTUSE
+ //UCHAR ReplayCounter[8];
+ //UCHAR ANonce[32]; // ANonce for WPA-PSK from authenticator
+ UCHAR SNonce[32]; // SNonce for WPA-PSK
+ UCHAR GNonce[32]; // GNonce for WPA-PSK from authenticator
+
+ HTTRANSMIT_SETTING HTPhyMode, MaxHTPhyMode, MinHTPhyMode;
+ RT_HT_PHY_INFO DesiredHtPhyInfo;
+ BOOLEAN bAutoTxRateSwitch;
+ DESIRED_TRANSMIT_SETTING DesiredTransmitSetting; // Desired transmit setting.
+} APCLI_STRUCT, *PAPCLI_STRUCT;
+
+// ----------- end of AP ----------------------------
+
+#ifdef BLOCK_NET_IF
+typedef struct _BLOCK_QUEUE_ENTRY
+{
+ BOOLEAN SwTxQueueBlockFlag;
+ LIST_HEADER NetIfList;
+} BLOCK_QUEUE_ENTRY, *PBLOCK_QUEUE_ENTRY;
+#endif // BLOCK_NET_IF //
+
+
+struct wificonf
+{
+ BOOLEAN bShortGI;
+ BOOLEAN bGreenField;
+};
+
+
+
+
+typedef struct _INF_PCI_CONFIG
+{
+ PUCHAR CSRBaseAddress; // PCI MMIO Base Address, all access will use
+}INF_PCI_CONFIG;
+
+typedef struct _INF_USB_CONFIG
+{
+ UINT BulkInEpAddr; // bulk-in endpoint address
+ UINT BulkOutEpAddr[6]; // bulk-out endpoint address
+
+}INF_USB_CONFIG;
+
+#ifdef IKANOS_VX_1X0
+ typedef void (*IkanosWlanTxCbFuncP)(void *, void *);
+
+ struct IKANOS_TX_INFO
+ {
+ struct net_device *netdev;
+ IkanosWlanTxCbFuncP *fp;
+ };
+#endif // IKANOS_VX_1X0 //
+
+#ifdef NINTENDO_AP
+typedef struct _NINDO_CTRL_BLOCK {
+
+ RT_NINTENDO_TABLE DS_TABLE;
+
+#ifdef CHIP25XX
+ spinlock_t NINTENDO_TABLE_Lock;
+#else
+ NDIS_SPIN_LOCK NINTENDO_TABLE_Lock;
+#endif // CHIP25XX //
+
+ UCHAR NINTENDO_UP_BUFFER[512];
+ UCHAR Local_KeyIdx;
+ CIPHER_KEY Local_SharedKey;
+ UCHAR Local_bHideSsid;
+ UCHAR Local_AuthMode;
+ UCHAR Local_WepStatus;
+ USHORT Local_CapabilityInfo;
+} NINDO_CTRL_BLOCK;
+#endif // NINTENDO_AP //
+
+
+#ifdef DBG_DIAGNOSE
+#define DIAGNOSE_TIME 10 // 10 sec
+typedef struct _RtmpDiagStrcut_
+{ // Diagnosis Related element
+ unsigned char inited;
+ unsigned char qIdx;
+ unsigned char ArrayStartIdx;
+ unsigned char ArrayCurIdx;
+ // Tx Related Count
+ USHORT TxDataCnt[DIAGNOSE_TIME];
+ USHORT TxFailCnt[DIAGNOSE_TIME];
+// USHORT TxDescCnt[DIAGNOSE_TIME][16]; // TxDesc queue length in scale of 0~14, >=15
+ USHORT TxDescCnt[DIAGNOSE_TIME][24]; // 3*3 // TxDesc queue length in scale of 0~14, >=15
+// USHORT TxMcsCnt[DIAGNOSE_TIME][16]; // TxDate MCS Count in range from 0 to 15, step in 1.
+ USHORT TxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
+ USHORT TxSWQueCnt[DIAGNOSE_TIME][9]; // TxSwQueue length in scale of 0, 1, 2, 3, 4, 5, 6, 7, >=8
+
+ USHORT TxAggCnt[DIAGNOSE_TIME];
+ USHORT TxNonAggCnt[DIAGNOSE_TIME];
+// USHORT TxAMPDUCnt[DIAGNOSE_TIME][16]; // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
+ USHORT TxAMPDUCnt[DIAGNOSE_TIME][24]; // 3*3 // 10 sec, TxDMA APMDU Aggregation count in range from 0 to 15, in setp of 1.
+ USHORT TxRalinkCnt[DIAGNOSE_TIME]; // TxRalink Aggregation Count in 1 sec scale.
+ USHORT TxAMSDUCnt[DIAGNOSE_TIME]; // TxAMSUD Aggregation Count in 1 sec scale.
+
+ // Rx Related Count
+ USHORT RxDataCnt[DIAGNOSE_TIME]; // Rx Total Data count.
+ USHORT RxCrcErrCnt[DIAGNOSE_TIME];
+// USHORT RxMcsCnt[DIAGNOSE_TIME][16]; // Rx MCS Count in range from 0 to 15, step in 1.
+ USHORT RxMcsCnt[DIAGNOSE_TIME][24]; // 3*3
+}RtmpDiagStruct;
+#endif // DBG_DIAGNOSE //
+
+
+//
+// The miniport adapter structure
+//
+typedef struct _RTMP_ADAPTER
+{
+ PVOID OS_Cookie; // save specific structure relative to OS
+ PNET_DEV net_dev;
+ ULONG VirtualIfCnt;
+
+
+
+ NDIS_SPIN_LOCK irq_lock;
+ UCHAR irq_disabled;
+
+#ifdef RT2870
+/*****************************************************************************************/
+/* USB related parameters */
+/*****************************************************************************************/
+ struct usb_config_descriptor *config;
+ UINT BulkInEpAddr; // bulk-in endpoint address
+ UINT BulkOutEpAddr[6]; // bulk-out endpoint address
+
+ UINT NumberOfPipes;
+ USHORT BulkOutMaxPacketSize;
+ USHORT BulkInMaxPacketSize;
+
+ //======Control Flags
+ LONG PendingIoCount;
+ ULONG BulkFlags;
+ BOOLEAN bUsbTxBulkAggre; // Flags for bulk out data priority
+
+
+ //======Timer Thread
+ RT2870_TIMER_QUEUE TimerQ;
+ NDIS_SPIN_LOCK TimerQLock;
+
+
+ //======Cmd Thread
+ CmdQ CmdQ;
+ NDIS_SPIN_LOCK CmdQLock; // CmdQLock spinlock
+
+ BOOLEAN TimerFunc_kill;
+ BOOLEAN mlme_kill;
+
+
+ //======Semaphores (event)
+ struct semaphore mlme_semaphore; /* to sleep thread on */
+ struct semaphore RTUSBCmd_semaphore; /* to sleep thread on */
+ struct semaphore RTUSBTimer_semaphore;
+#ifdef INF_AMAZON_SE
+ struct semaphore UsbVendorReq_semaphore;
+ PVOID UsbVendorReqBuf;
+#endif // INF_AMAZON_SE //
+ struct completion TimerQComplete;
+ struct completion mlmeComplete;
+ struct completion CmdQComplete;
+ wait_queue_head_t *wait;
+
+ //======Lock for 2870 ATE
+#ifdef RALINK_ATE
+ NDIS_SPIN_LOCK GenericLock; // ATE Tx/Rx generic spinlock
+#endif // RALINK_ATE //
+
+#endif // RT2870 //
+
+
+/*****************************************************************************************/
+ /* Both PCI/USB related parameters */
+/*****************************************************************************************/
+
+
+/*****************************************************************************************/
+/* Tx related parameters */
+/*****************************************************************************************/
+ BOOLEAN DeQueueRunning[NUM_OF_TX_RING]; // for ensuring RTUSBDeQueuePacket get call once
+ NDIS_SPIN_LOCK DeQueueLock[NUM_OF_TX_RING];
+
+#ifdef RT2870
+ // Data related context and AC specified, 4 AC supported
+ NDIS_SPIN_LOCK BulkOutLock[6]; // BulkOut spinlock for 4 ACs
+ NDIS_SPIN_LOCK MLMEBulkOutLock; // MLME BulkOut lock
+
+ HT_TX_CONTEXT TxContext[NUM_OF_TX_RING];
+ NDIS_SPIN_LOCK TxContextQueueLock[NUM_OF_TX_RING]; // TxContextQueue spinlock
+
+ // 4 sets of Bulk Out index and pending flag
+ UCHAR NextBulkOutIndex[4]; // only used for 4 EDCA bulkout pipe
+
+ BOOLEAN BulkOutPending[6]; // used for total 6 bulkout pipe
+ UCHAR bulkResetPipeid;
+ BOOLEAN MgmtBulkPending;
+ ULONG bulkResetReq[6];
+#endif // RT2870 //
+
+ // resource for software backlog queues
+ QUEUE_HEADER TxSwQueue[NUM_OF_TX_RING]; // 4 AC + 1 HCCA
+ NDIS_SPIN_LOCK TxSwQueueLock[NUM_OF_TX_RING]; // TxSwQueue spinlock
+
+ RTMP_DMABUF MgmtDescRing; // Shared memory for MGMT descriptors
+ RTMP_MGMT_RING MgmtRing;
+ NDIS_SPIN_LOCK MgmtRingLock; // Prio Ring spinlock
+
+
+/*****************************************************************************************/
+/* Rx related parameters */
+/*****************************************************************************************/
+
+
+#ifdef RT2870
+ RX_CONTEXT RxContext[RX_RING_SIZE]; // 1 for redundant multiple IRP bulk in.
+ NDIS_SPIN_LOCK BulkInLock; // BulkIn spinlock for 4 ACs
+ UCHAR PendingRx; // The Maxima pending Rx value should be RX_RING_SIZE.
+ UCHAR NextRxBulkInIndex; // Indicate the current RxContext Index which hold by Host controller.
+ UCHAR NextRxBulkInReadIndex; // Indicate the current RxContext Index which driver can read & process it.
+ ULONG NextRxBulkInPosition; // Want to contatenate 2 URB buffer while 1st is bulkin failed URB. This Position is 1st URB TransferLength.
+ ULONG TransferBufferLength; // current length of the packet buffer
+ ULONG ReadPosition; // current read position in a packet buffer
+#endif // RT2870 //
+
+
+/*****************************************************************************************/
+/* ASIC related parameters */
+/*****************************************************************************************/
+ UINT32 MACVersion; // MAC version. Record rt2860C(0x28600100) or rt2860D (0x28600101)..
+
+ // ---------------------------
+ // E2PROM
+ // ---------------------------
+ ULONG EepromVersion; // byte 0: version, byte 1: revision, byte 2~3: unused
+ UCHAR EEPROMAddressNum; // 93c46=6 93c66=8
+ USHORT EEPROMDefaultValue[NUM_EEPROM_BBP_PARMS];
+ BOOLEAN EepromAccess;
+ UCHAR EFuseTag;
+ ULONG FirmwareVersion; // byte 0: Minor version, byte 1: Major version, otherwise unused.
+
+ // ---------------------------
+ // BBP Control
+ // ---------------------------
+ UCHAR BbpWriteLatch[140]; // record last BBP register value written via BBP_IO_WRITE/BBP_IO_WRITE_VY_REG_ID
+ UCHAR BbpRssiToDbmDelta;
+ BBP_R66_TUNING BbpTuning;
+
+ // ----------------------------
+ // RFIC control
+ // ----------------------------
+ UCHAR RfIcType; // RFIC_xxx
+ ULONG RfFreqOffset; // Frequency offset for channel switching
+ RTMP_RF_REGS LatchRfRegs; // latch th latest RF programming value since RF IC doesn't support READ
+
+ EEPROM_ANTENNA_STRUC Antenna; // Since ANtenna definition is different for a & g. We need to save it for future reference.
+ EEPROM_NIC_CONFIG2_STRUC NicConfig2;
+
+ // This soft Rx Antenna Diversity mechanism is used only when user set
+ // RX Antenna = DIVERSITY ON
+ SOFT_RX_ANT_DIVERSITY RxAnt;
+
+ UCHAR RFProgSeq;
+ CHANNEL_TX_POWER TxPower[MAX_NUM_OF_CHANNELS]; // Store Tx power value for all channels.
+ CHANNEL_TX_POWER ChannelList[MAX_NUM_OF_CHANNELS]; // list all supported channels for site survey
+ CHANNEL_11J_TX_POWER TxPower11J[MAX_NUM_OF_11JCHANNELS]; // 802.11j channel and bw
+ CHANNEL_11J_TX_POWER ChannelList11J[MAX_NUM_OF_11JCHANNELS]; // list all supported channels for site survey
+
+ UCHAR ChannelListNum; // number of channel in ChannelList[]
+ UCHAR Bbp94;
+ BOOLEAN BbpForCCK;
+ ULONG Tx20MPwrCfgABand[5];
+ ULONG Tx20MPwrCfgGBand[5];
+ ULONG Tx40MPwrCfgABand[5];
+ ULONG Tx40MPwrCfgGBand[5];
+
+ BOOLEAN bAutoTxAgcA; // Enable driver auto Tx Agc control
+ UCHAR TssiRefA; // Store Tssi reference value as 25 temperature.
+ UCHAR TssiPlusBoundaryA[5]; // Tssi boundary for increase Tx power to compensate.
+ UCHAR TssiMinusBoundaryA[5]; // Tssi boundary for decrease Tx power to compensate.
+ UCHAR TxAgcStepA; // Store Tx TSSI delta increment / decrement value
+ CHAR TxAgcCompensateA; // Store the compensation (TxAgcStep * (idx-1))
+
+ BOOLEAN bAutoTxAgcG; // Enable driver auto Tx Agc control
+ UCHAR TssiRefG; // Store Tssi reference value as 25 temperature.
+ UCHAR TssiPlusBoundaryG[5]; // Tssi boundary for increase Tx power to compensate.
+ UCHAR TssiMinusBoundaryG[5]; // Tssi boundary for decrease Tx power to compensate.
+ UCHAR TxAgcStepG; // Store Tx TSSI delta increment / decrement value
+ CHAR TxAgcCompensateG; // Store the compensation (TxAgcStep * (idx-1))
+
+ //+++For RT2870, the parameteres is start from BGRssiOffset1 ~ BGRssiOffset3
+ CHAR BGRssiOffset0; // Store B/G RSSI#0 Offset value on EEPROM 0x46h
+ CHAR BGRssiOffset1; // Store B/G RSSI#1 Offset value
+ CHAR BGRssiOffset2; // Store B/G RSSI#2 Offset value
+ //---
+
+ //+++For RT2870, the parameteres is start from ARssiOffset1 ~ ARssiOffset3
+ CHAR ARssiOffset0; // Store A RSSI#0 Offset value on EEPROM 0x4Ah
+ CHAR ARssiOffset1; // Store A RSSI#1 Offset value
+ CHAR ARssiOffset2; // Store A RSSI#2 Offset value
+ //---
+
+ CHAR BLNAGain; // Store B/G external LNA#0 value on EEPROM 0x44h
+ CHAR ALNAGain0; // Store A external LNA#0 value for ch36~64
+ CHAR ALNAGain1; // Store A external LNA#1 value for ch100~128
+ CHAR ALNAGain2; // Store A external LNA#2 value for ch132~165
+
+ // ----------------------------
+ // LED control
+ // ----------------------------
+ MCU_LEDCS_STRUC LedCntl;
+ USHORT Led1; // read from EEPROM 0x3c
+ USHORT Led2; // EEPROM 0x3e
+ USHORT Led3; // EEPROM 0x40
+ UCHAR LedIndicatorStregth;
+ UCHAR RssiSingalstrengthOffet;
+ BOOLEAN bLedOnScanning;
+ UCHAR LedStatus;
+
+/*****************************************************************************************/
+/* 802.11 related parameters */
+/*****************************************************************************************/
+ // outgoing BEACON frame buffer and corresponding TXD
+ TXWI_STRUC BeaconTxWI;
+ PUCHAR BeaconBuf;
+ USHORT BeaconOffset[HW_BEACON_MAX_COUNT];
+
+ // pre-build PS-POLL and NULL frame upon link up. for efficiency purpose.
+ PSPOLL_FRAME PsPollFrame;
+ HEADER_802_11 NullFrame;
+
+#ifdef RT2870
+ TX_CONTEXT BeaconContext[BEACON_RING_SIZE];
+ TX_CONTEXT NullContext;
+ TX_CONTEXT PsPollContext;
+ TX_CONTEXT RTSContext;
+#endif // RT2870 //
+
+
+
+//=========AP===========
+
+
+//=======STA===========
+#ifdef CONFIG_STA_SUPPORT
+/* Modified by Wu Xi-Kun 4/21/2006 */
+ // -----------------------------------------------
+ // STA specific configuration & operation status
+ // used only when pAd->OpMode == OPMODE_STA
+ // -----------------------------------------------
+ STA_ADMIN_CONFIG StaCfg; // user desired settings
+ STA_ACTIVE_CONFIG StaActive; // valid only when ADHOC_ON(pAd) || INFRA_ON(pAd)
+ CHAR nickname[IW_ESSID_MAX_SIZE+1]; // nickname, only used in the iwconfig i/f
+ NDIS_MEDIA_STATE PreMediaState;
+#endif // CONFIG_STA_SUPPORT //
+
+//=======Common===========
+ // OP mode: either AP or STA
+ UCHAR OpMode; // OPMODE_STA, OPMODE_AP
+
+ NDIS_MEDIA_STATE IndicateMediaState; // Base on Indication state, default is NdisMediaStateDisConnected
+
+
+ // MAT related parameters
+
+ // configuration: read from Registry & E2PROM
+ BOOLEAN bLocalAdminMAC; // Use user changed MAC
+ UCHAR PermanentAddress[MAC_ADDR_LEN]; // Factory default MAC address
+ UCHAR CurrentAddress[MAC_ADDR_LEN]; // User changed MAC address
+
+ // ------------------------------------------------------
+ // common configuration to both OPMODE_STA and OPMODE_AP
+ // ------------------------------------------------------
+ COMMON_CONFIG CommonCfg;
+ MLME_STRUCT Mlme;
+
+ // AP needs those vaiables for site survey feature.
+ MLME_AUX MlmeAux; // temporary settings used during MLME state machine
+ BSS_TABLE ScanTab; // store the latest SCAN result
+
+ //About MacTab, the sta driver will use #0 and #1 for multicast and AP.
+ MAC_TABLE MacTab; // ASIC on-chip WCID entry table. At TX, ASIC always use key according to this on-chip table.
+ NDIS_SPIN_LOCK MacTabLock;
+
+#ifdef DOT11_N_SUPPORT
+ BA_TABLE BATable;
+#endif // DOT11_N_SUPPORT //
+ NDIS_SPIN_LOCK BATabLock;
+ RALINK_TIMER_STRUCT RECBATimer;
+
+ // encryption/decryption KEY tables
+ CIPHER_KEY SharedKey[MAX_MBSSID_NUM][4]; // STA always use SharedKey[BSS0][0..3]
+
+ // RX re-assembly buffer for fragmentation
+ FRAGMENT_FRAME FragFrame; // Frame storage for fragment frame
+
+ // various Counters
+ COUNTER_802_3 Counters8023; // 802.3 counters
+ COUNTER_802_11 WlanCounters; // 802.11 MIB counters
+ COUNTER_RALINK RalinkCounters; // Ralink propriety counters
+ COUNTER_DRS DrsCounters; // counters for Dynamic TX Rate Switching
+ PRIVATE_STRUC PrivateInfo; // Private information & counters
+
+ // flags, see fRTMP_ADAPTER_xxx flags
+ ULONG Flags; // Represent current device status
+
+ // current TX sequence #
+ USHORT Sequence;
+
+#ifdef UNDER_CE
+ NDIS_HANDLE hGiISR;
+#endif
+
+
+ // Control disconnect / connect event generation
+ //+++Didn't used anymore
+ ULONG LinkDownTime;
+ //---
+ ULONG LastRxRate;
+ ULONG LastTxRate;
+ //+++Used only for Station
+ BOOLEAN bConfigChanged; // Config Change flag for the same SSID setting
+ //---
+
+ ULONG ExtraInfo; // Extra information for displaying status
+ ULONG SystemErrorBitmap; // b0: E2PROM version error
+
+ //+++Didn't used anymore
+ ULONG MacIcVersion; // MAC/BBP serial interface issue solved after ver.D
+ //---
+
+ // ---------------------------
+ // System event log
+ // ---------------------------
+ RT_802_11_EVENT_TABLE EventTab;
+
+
+ BOOLEAN HTCEnable;
+
+ /*****************************************************************************************/
+ /* Statistic related parameters */
+ /*****************************************************************************************/
+#ifdef RT2870
+ ULONG BulkOutDataOneSecCount;
+ ULONG BulkInDataOneSecCount;
+ ULONG BulkLastOneSecCount; // BulkOutDataOneSecCount + BulkInDataOneSecCount
+ ULONG watchDogRxCnt;
+ ULONG watchDogRxOverFlowCnt;
+ ULONG watchDogTxPendingCnt[NUM_OF_TX_RING];
+#endif // RT2870 //
+
+ BOOLEAN bUpdateBcnCntDone;
+ ULONG watchDogMacDeadlock; // prevent MAC/BBP into deadlock condition
+ // ----------------------------
+ // DEBUG paramerts
+ // ----------------------------
+ //ULONG DebugSetting[4];
+ BOOLEAN bBanAllBaSetup;
+ BOOLEAN bPromiscuous;
+
+ // ----------------------------
+ // rt2860c emulation-use Parameters
+ // ----------------------------
+ ULONG rtsaccu[30];
+ ULONG ctsaccu[30];
+ ULONG cfendaccu[30];
+ ULONG bacontent[16];
+ ULONG rxint[RX_RING_SIZE+1];
+ UCHAR rcvba[60];
+ BOOLEAN bLinkAdapt;
+ BOOLEAN bForcePrintTX;
+ BOOLEAN bForcePrintRX;
+ BOOLEAN bDisablescanning; //defined in RT2870 USB
+ BOOLEAN bStaFifoTest;
+ BOOLEAN bProtectionTest;
+ BOOLEAN bHCCATest;
+ BOOLEAN bGenOneHCCA;
+ BOOLEAN bBroadComHT;
+ //+++Following add from RT2870 USB.
+ ULONG BulkOutReq;
+ ULONG BulkOutComplete;
+ ULONG BulkOutCompleteOther;
+ ULONG BulkOutCompleteCancel; // seems not use now?
+ ULONG BulkInReq;
+ ULONG BulkInComplete;
+ ULONG BulkInCompleteFail;
+ //---
+
+ struct wificonf WIFItestbed;
+
+#ifdef RALINK_ATE
+ ATE_INFO ate;
+#ifdef RT2870
+ BOOLEAN ContinBulkOut; //ATE bulk out control
+ BOOLEAN ContinBulkIn; //ATE bulk in control
+ atomic_t BulkOutRemained;
+ atomic_t BulkInRemained;
+#endif // RT2870 //
+#endif // RALINK_ATE //
+
+#ifdef DOT11_N_SUPPORT
+ struct reordering_mpdu_pool mpdu_blk_pool;
+#endif // DOT11_N_SUPPORT //
+
+ ULONG OneSecondnonBEpackets; // record non BE packets per second
+
+#if WIRELESS_EXT >= 12
+ struct iw_statistics iw_stats;
+#endif
+
+ struct net_device_stats stats;
+
+#ifdef BLOCK_NET_IF
+ BLOCK_QUEUE_ENTRY blockQueueTab[NUM_OF_TX_RING];
+#endif // BLOCK_NET_IF //
+
+
+
+#ifdef MULTIPLE_CARD_SUPPORT
+ INT32 MC_RowID;
+ UCHAR MC_FileName[256];
+#endif // MULTIPLE_CARD_SUPPORT //
+
+ ULONG TbttTickCount;
+#ifdef PCI_MSI_SUPPORT
+ BOOLEAN HaveMsi;
+#endif // PCI_MSI_SUPPORT //
+
+
+ UCHAR is_on;
+
+#define TIME_BASE (1000000/OS_HZ)
+#define TIME_ONE_SECOND (1000000/TIME_BASE)
+ UCHAR flg_be_adjust;
+ ULONG be_adjust_last_time;
+
+#ifdef NINTENDO_AP
+ NINDO_CTRL_BLOCK nindo_ctrl_block;
+#endif // NINTENDO_AP //
+
+
+#ifdef IKANOS_VX_1X0
+ struct IKANOS_TX_INFO IkanosTxInfo;
+ struct IKANOS_TX_INFO IkanosRxInfo[MAX_MBSSID_NUM + MAX_WDS_ENTRY + MAX_APCLI_NUM + MAX_MESH_NUM];
+#endif // IKANOS_VX_1X0 //
+
+
+#ifdef DBG_DIAGNOSE
+ RtmpDiagStruct DiagStruct;
+#endif // DBG_DIAGNOSE //
+
+
+ UINT8 PM_FlgSuspend;
+
+#ifdef RT30xx
+//======efuse
+ BOOLEAN bUseEfuse;
+ BOOLEAN bEEPROMFile;
+#endif // RT30xx //
+
+} RTMP_ADAPTER, *PRTMP_ADAPTER;
+
+//
+// Cisco IAPP format
+//
+typedef struct _CISCO_IAPP_CONTENT_
+{
+ USHORT Length; //IAPP Length
+ UCHAR MessageType; //IAPP type
+ UCHAR FunctionCode; //IAPP function type
+ UCHAR DestinaionMAC[MAC_ADDR_LEN];
+ UCHAR SourceMAC[MAC_ADDR_LEN];
+ USHORT Tag; //Tag(element IE) - Adjacent AP report
+ USHORT TagLength; //Length of element not including 4 byte header
+ UCHAR OUI[4]; //0x00, 0x40, 0x96, 0x00
+ UCHAR PreviousAP[MAC_ADDR_LEN]; //MAC Address of access point
+ USHORT Channel;
+ USHORT SsidLen;
+ UCHAR Ssid[MAX_LEN_OF_SSID];
+ USHORT Seconds; //Seconds that the client has been disassociated.
+} CISCO_IAPP_CONTENT, *PCISCO_IAPP_CONTENT;
+
+#define DELAYINTMASK 0x0003fffb
+#define INTMASK 0x0003fffb
+#define IndMask 0x0003fffc
+#define RxINT 0x00000005 // Delayed Rx or indivi rx
+#define TxDataInt 0x000000fa // Delayed Tx or indivi tx
+#define TxMgmtInt 0x00000102 // Delayed Tx or indivi tx
+#define TxCoherent 0x00020000 // tx coherent
+#define RxCoherent 0x00010000 // rx coherent
+#define McuCommand 0x00000200 // mcu
+#define PreTBTTInt 0x00001000 // Pre-TBTT interrupt
+#define TBTTInt 0x00000800 // TBTT interrupt
+#define GPTimeOutInt 0x00008000 // GPtimeout interrupt
+#define AutoWakeupInt 0x00004000 // AutoWakeupInt interrupt
+#define FifoStaFullInt 0x00002000 // fifo statistics full interrupt
+
+
+typedef struct _RX_BLK_
+{
+// RXD_STRUC RxD; // sample
+ RT28XX_RXD_STRUC RxD;
+ PRXWI_STRUC pRxWI;
+ PHEADER_802_11 pHeader;
+ PNDIS_PACKET pRxPacket;
+ UCHAR *pData;
+ USHORT DataSize;
+ USHORT Flags;
+ UCHAR UserPriority; // for calculate TKIP MIC using
+} RX_BLK;
+
+
+#define RX_BLK_SET_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags |= _flag)
+#define RX_BLK_TEST_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags & _flag)
+#define RX_BLK_CLEAR_FLAG(_pRxBlk, _flag) (_pRxBlk->Flags &= ~(_flag))
+
+
+#define fRX_WDS 0x0001
+#define fRX_AMSDU 0x0002
+#define fRX_ARALINK 0x0004
+#define fRX_HTC 0x0008
+#define fRX_PAD 0x0010
+#define fRX_AMPDU 0x0020
+#define fRX_QOS 0x0040
+#define fRX_INFRA 0x0080
+#define fRX_EAP 0x0100
+#define fRX_MESH 0x0200
+#define fRX_APCLI 0x0400
+#define fRX_DLS 0x0800
+#define fRX_WPI 0x1000
+
+#define LENGTH_AMSDU_SUBFRAMEHEAD 14
+#define LENGTH_ARALINK_SUBFRAMEHEAD 14
+#define LENGTH_ARALINK_HEADER_FIELD 2
+
+#define TX_UNKOWN_FRAME 0x00
+#define TX_MCAST_FRAME 0x01
+#define TX_LEGACY_FRAME 0x02
+#define TX_AMPDU_FRAME 0x04
+#define TX_AMSDU_FRAME 0x08
+#define TX_RALINK_FRAME 0x10
+#define TX_FRAG_FRAME 0x20
+
+
+// Currently the sizeof(TX_BLK) is 148 bytes.
+typedef struct _TX_BLK_
+{
+ UCHAR QueIdx;
+ UCHAR TxFrameType; // Indicate the Transmission type of the all frames in one batch
+ UCHAR TotalFrameNum; // Total frame number want to send-out in one batch
+ USHORT TotalFragNum; // Total frame fragments required in one batch
+ USHORT TotalFrameLen; // Total length of all frames want to send-out in one batch
+
+ QUEUE_HEADER TxPacketList;
+ MAC_TABLE_ENTRY *pMacEntry; // NULL: packet with 802.11 RA field is multicast/broadcast address
+ HTTRANSMIT_SETTING *pTransmit;
+
+ // Following structure used for the characteristics of a specific packet.
+ PNDIS_PACKET pPacket;
+ PUCHAR pSrcBufHeader; // Reference to the head of sk_buff->data
+ PUCHAR pSrcBufData; // Reference to the sk_buff->data, will changed depends on hanlding progresss
+ UINT SrcBufLen; // Length of packet payload which not including Layer 2 header
+ PUCHAR pExtraLlcSnapEncap; // NULL means no extra LLC/SNAP is required
+ UCHAR HeaderBuf[80]; // TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP
+ UCHAR MpduHeaderLen; // 802.11 header length NOT including the padding
+ UCHAR HdrPadLen; // recording Header Padding Length;
+ UCHAR apidx; // The interface associated to this packet
+ UCHAR Wcid; // The MAC entry associated to this packet
+ UCHAR UserPriority; // priority class of packet
+ UCHAR FrameGap; // what kind of IFS this packet use
+ UCHAR MpduReqNum; // number of fragments of this frame
+ UCHAR TxRate; // TODO: Obsoleted? Should change to MCS?
+ UCHAR CipherAlg; // cipher alogrithm
+ PCIPHER_KEY pKey;
+
+
+
+ USHORT Flags; //See following definitions for detail.
+
+ //YOU SHOULD NOT TOUCH IT! Following parameters are used for hardware-depended layer.
+ ULONG Priv; // Hardware specific value saved in here.
+} TX_BLK, *PTX_BLK;
+
+
+#define fTX_bRtsRequired 0x0001 // Indicate if need send RTS frame for protection. Not used in RT2860/RT2870.
+#define fTX_bAckRequired 0x0002 // the packet need ack response
+#define fTX_bPiggyBack 0x0004 // Legacy device use Piggback or not
+#define fTX_bHTRate 0x0008 // allow to use HT rate
+//#define fTX_bForceLowRate 0x0010 // force to use Low Rate
+#define fTX_bForceNonQoS 0x0010 // force to transmit frame without WMM-QoS in HT mode
+#define fTX_bAllowFrag 0x0020 // allow to fragment the packet, A-MPDU, A-MSDU, A-Ralink is not allowed to fragment
+#define fTX_bMoreData 0x0040 // there are more data packets in PowerSave Queue
+#define fTX_bWMM 0x0080 // QOS Data
+
+#define fTX_bClearEAPFrame 0x0100
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#define TX_BLK_ASSIGN_FLAG(_pTxBlk, _flag, value) \
+ do { \
+ if (value) \
+ (_pTxBlk->Flags |= _flag) \
+ else \
+ (_pTxBlk->Flags &= ~(_flag)) \
+ }while(0)
+
+#define TX_BLK_SET_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags |= _flag)
+#define TX_BLK_TEST_FLAG(_pTxBlk, _flag) (((_pTxBlk->Flags & _flag) == _flag) ? 1 : 0)
+#define TX_BLK_CLEAR_FLAG(_pTxBlk, _flag) (_pTxBlk->Flags &= ~(_flag))
+
+
+
+
+
+//------------------------------------------------------------------------------------------
+
+
+
+#ifdef RT_BIG_ENDIAN
+static inline VOID WriteBackToDescriptor(
+ IN PUCHAR Dest,
+ IN PUCHAR Src,
+ IN BOOLEAN DoEncrypt,
+ IN ULONG DescriptorType)
+{
+ UINT32 *p1, *p2;
+
+ p1 = ((UINT32 *)Dest);
+ p2 = ((UINT32 *)Src);
+
+ *p1 = *p2;
+ *(p1+2) = *(p2+2);
+ *(p1+3) = *(p2+3);
+ *(p1+1) = *(p2+1); // Word 1; this must be written back last
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Endian conversion of Tx/Rx descriptor .
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to Tx/Rx descriptor
+ DescriptorType Direction of the frame
+
+ Return Value:
+ None
+
+ Note:
+ Call this function when read or update descriptor
+ ========================================================================
+*/
+static inline VOID RTMPWIEndianChange(
+ IN PUCHAR pData,
+ IN ULONG DescriptorType)
+{
+ int size;
+ int i;
+
+ size = ((DescriptorType == TYPE_TXWI) ? TXWI_SIZE : RXWI_SIZE);
+
+ if(DescriptorType == TYPE_TXWI)
+ {
+ *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData))); // Byte 0~3
+ *((UINT32 *)(pData + 4)) = SWAP32(*((UINT32 *)(pData+4))); // Byte 4~7
+ }
+ else
+ {
+ for(i=0; i < size/4 ; i++)
+ *(((UINT32 *)pData) +i) = SWAP32(*(((UINT32 *)pData)+i));
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Endian conversion of Tx/Rx descriptor .
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to Tx/Rx descriptor
+ DescriptorType Direction of the frame
+
+ Return Value:
+ None
+
+ Note:
+ Call this function when read or update descriptor
+ ========================================================================
+*/
+
+#ifdef RT2870
+static inline VOID RTMPDescriptorEndianChange(
+ IN PUCHAR pData,
+ IN ULONG DescriptorType)
+{
+ *((UINT32 *)(pData)) = SWAP32(*((UINT32 *)(pData)));
+}
+#endif // RT2870 //
+/*
+ ========================================================================
+
+ Routine Description:
+ Endian conversion of all kinds of 802.11 frames .
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Pointer to the 802.11 frame structure
+ Dir Direction of the frame
+ FromRxDoneInt Caller is from RxDone interrupt
+
+ Return Value:
+ None
+
+ Note:
+ Call this function when read or update buffer data
+ ========================================================================
+*/
+static inline VOID RTMPFrameEndianChange(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG Dir,
+ IN BOOLEAN FromRxDoneInt)
+{
+ PHEADER_802_11 pFrame;
+ PUCHAR pMacHdr;
+
+ // swab 16 bit fields - Frame Control field
+ if(Dir == DIR_READ)
+ {
+ *(USHORT *)pData = SWAP16(*(USHORT *)pData);
+ }
+
+ pFrame = (PHEADER_802_11) pData;
+ pMacHdr = (PUCHAR) pFrame;
+
+ // swab 16 bit fields - Duration/ID field
+ *(USHORT *)(pMacHdr + 2) = SWAP16(*(USHORT *)(pMacHdr + 2));
+
+ // swab 16 bit fields - Sequence Control field
+ *(USHORT *)(pMacHdr + 22) = SWAP16(*(USHORT *)(pMacHdr + 22));
+
+ if(pFrame->FC.Type == BTYPE_MGMT)
+ {
+ switch(pFrame->FC.SubType)
+ {
+ case SUBTYPE_ASSOC_REQ:
+ case SUBTYPE_REASSOC_REQ:
+ // swab 16 bit fields - CapabilityInfo field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Listen Interval field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+
+ case SUBTYPE_ASSOC_RSP:
+ case SUBTYPE_REASSOC_RSP:
+ // swab 16 bit fields - CapabilityInfo field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Status Code field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - AID field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+
+ case SUBTYPE_AUTH:
+ // If from APHandleRxDoneInterrupt routine, it is still a encrypt format.
+ // The convertion is delayed to RTMPHandleDecryptionDoneInterrupt.
+ if(!FromRxDoneInt && pFrame->FC.Wep == 1)
+ break;
+ else
+ {
+ // swab 16 bit fields - Auth Alg No. field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Auth Seq No. field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - Status Code field
+ pMacHdr += 2;
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ }
+ break;
+
+ case SUBTYPE_BEACON:
+ case SUBTYPE_PROBE_RSP:
+ // swab 16 bit fields - BeaconInterval field
+ pMacHdr += (sizeof(HEADER_802_11) + TIMESTAMP_LEN);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+
+ // swab 16 bit fields - CapabilityInfo field
+ pMacHdr += sizeof(USHORT);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+
+ case SUBTYPE_DEAUTH:
+ case SUBTYPE_DISASSOC:
+ // swab 16 bit fields - Reason code field
+ pMacHdr += sizeof(HEADER_802_11);
+ *(USHORT *)pMacHdr = SWAP16(*(USHORT *)pMacHdr);
+ break;
+ }
+ }
+ else if( pFrame->FC.Type == BTYPE_DATA )
+ {
+ }
+ else if(pFrame->FC.Type == BTYPE_CNTL)
+ {
+ switch(pFrame->FC.SubType)
+ {
+ case SUBTYPE_BLOCK_ACK_REQ:
+ {
+ PFRAME_BA_REQ pBAReq = (PFRAME_BA_REQ)pFrame;
+ *(USHORT *)(&pBAReq->BARControl) = SWAP16(*(USHORT *)(&pBAReq->BARControl));
+ pBAReq->BAStartingSeq.word = SWAP16(pBAReq->BAStartingSeq.word);
+ }
+ break;
+ case SUBTYPE_BLOCK_ACK:
+ // For Block Ack packet, the HT_CONTROL field is in the same offset with Addr3
+ *(UINT32 *)(&pFrame->Addr3[0]) = SWAP32(*(UINT32 *)(&pFrame->Addr3[0]));
+ break;
+
+ case SUBTYPE_ACK:
+ //For ACK packet, the HT_CONTROL field is in the same offset with Addr2
+ *(UINT32 *)(&pFrame->Addr2[0])= SWAP32(*(UINT32 *)(&pFrame->Addr2[0]));
+ break;
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("Invalid Frame Type!!!\n"));
+ }
+
+ // swab 16 bit fields - Frame Control
+ if(Dir == DIR_WRITE)
+ {
+ *(USHORT *)pData = SWAP16(*(USHORT *)pData);
+ }
+}
+#endif // RT_BIG_ENDIAN //
+
+
+static inline VOID ConvertMulticastIP2MAC(
+ IN PUCHAR pIpAddr,
+ IN PUCHAR *ppMacAddr,
+ IN UINT16 ProtoType)
+{
+ if (pIpAddr == NULL)
+ return;
+
+ if (ppMacAddr == NULL || *ppMacAddr == NULL)
+ return;
+
+ switch (ProtoType)
+ {
+ case ETH_P_IPV6:
+// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
+ *(*ppMacAddr) = 0x33;
+ *(*ppMacAddr + 1) = 0x33;
+ *(*ppMacAddr + 2) = pIpAddr[12];
+ *(*ppMacAddr + 3) = pIpAddr[13];
+ *(*ppMacAddr + 4) = pIpAddr[14];
+ *(*ppMacAddr + 5) = pIpAddr[15];
+ break;
+
+ case ETH_P_IP:
+ default:
+// memset(*ppMacAddr, 0, ETH_LENGTH_OF_ADDRESS);
+ *(*ppMacAddr) = 0x01;
+ *(*ppMacAddr + 1) = 0x00;
+ *(*ppMacAddr + 2) = 0x5e;
+ *(*ppMacAddr + 3) = pIpAddr[1] & 0x7f;
+ *(*ppMacAddr + 4) = pIpAddr[2];
+ *(*ppMacAddr + 5) = pIpAddr[3];
+ break;
+ }
+
+ return;
+}
+
+BOOLEAN RTMPCheckForHang(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+VOID RTMPHalt(
+ IN NDIS_HANDLE MiniportAdapterContext
+ );
+
+//
+// Private routines in rtmp_init.c
+//
+NDIS_STATUS RTMPAllocAdapterBlock(
+ IN PVOID handle,
+ OUT PRTMP_ADAPTER *ppAdapter
+ );
+
+NDIS_STATUS RTMPAllocTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd
+ );
+
+NDIS_STATUS RTMPFindAdapter(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_HANDLE WrapperConfigurationContext
+ );
+
+NDIS_STATUS RTMPReadParametersHook(
+ IN PRTMP_ADAPTER pAd
+ );
+
+VOID RTMPFreeAdapter(
+ IN PRTMP_ADAPTER pAd
+ );
+
+NDIS_STATUS NICReadRegParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_HANDLE WrapperConfigurationContext
+ );
+
+#ifdef RT30xx
+VOID NICInitRT30xxRFRegisters(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT30xx //
+
+VOID NICReadEEPROMParameters(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mac_addr);
+
+VOID NICInitAsicFromEEPROM(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICInitTxRxRingAndBacklogQueue(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS NICInitializeAdapter(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset);
+
+NDIS_STATUS NICInitializeAsic(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bHardReset);
+
+VOID NICIssueReset(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPRingCleanUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RingType);
+
+VOID RxTest(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS DbgSendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+VOID UserCfgInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICResetFromError(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICEraseFirmware(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS NICLoadFirmware(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS NICLoadRateSwitchingParams(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN NICCheckForHang(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICUpdateFifoStaCounters(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NICUpdateRawCounters(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG RTMPNotAllZero(
+ IN PVOID pSrc1,
+ IN ULONG Length);
+
+VOID RTMPZeroMemory(
+ IN PVOID pSrc,
+ IN ULONG Length);
+
+ULONG RTMPCompareMemory(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ IN ULONG Length);
+
+VOID RTMPMoveMemory(
+ OUT PVOID pDest,
+ IN PVOID pSrc,
+ IN ULONG Length);
+
+VOID AtoH(
+ char *src,
+ UCHAR *dest,
+ int destlen);
+
+UCHAR BtoH(
+ char ch);
+
+VOID RTMPPatchMacBbpBug(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPPatchCardBus(
+ IN PRTMP_ADAPTER pAdapter);
+
+VOID RTMPPatchRalinkCardBus(
+ IN PRTMP_ADAPTER pAdapter,
+ IN ULONG Bus);
+
+ULONG RTMPReadCBConfig(
+ IN ULONG Bus,
+ IN ULONG Slot,
+ IN ULONG Func,
+ IN ULONG Offset);
+
+VOID RTMPWriteCBConfig(
+ IN ULONG Bus,
+ IN ULONG Slot,
+ IN ULONG Func,
+ IN ULONG Offset,
+ IN ULONG Value);
+
+VOID RTMPInitTimer(
+ IN PRTMP_ADAPTER pAd,
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN PVOID pTimerFunc,
+ IN PVOID pData,
+ IN BOOLEAN Repeat);
+
+VOID RTMPSetTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value);
+
+
+VOID RTMPModTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ IN ULONG Value);
+
+VOID RTMPCancelTimer(
+ IN PRALINK_TIMER_STRUCT pTimer,
+ OUT BOOLEAN *pCancelled);
+
+VOID RTMPSetLED(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Status);
+
+VOID RTMPSetSignalLED(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_802_11_RSSI Dbm);
+
+VOID RTMPEnableRxTx(
+ IN PRTMP_ADAPTER pAd);
+
+//
+// prototype in action.c
+//
+VOID ActionStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeADDBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDELBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeInvalidAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerAddBAReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAddBARspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDelBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBAAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // DOT11_N_SUPPORT //
+
+VOID SendPSMPAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR Psmp);
+
+
+#ifdef DOT11N_DRAFT3
+VOID SendBSS2040CoexistMgmtAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx,
+ IN UCHAR InfoReq);
+
+VOID SendNotifyBWActionFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR apidx);
+
+BOOLEAN ChannelSwitchSanityCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR NewChannel,
+ IN UCHAR Secondary);
+
+VOID ChannelSwitchAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR Channel,
+ IN UCHAR Secondary);
+
+ULONG BuildIntolerantChannelRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest);
+
+VOID Update2040CoexistFrameAndNotify(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha);
+
+VOID Send2040CoexistAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN BOOLEAN bAddIntolerantCha);
+#endif // DOT11N_DRAFT3 //
+
+VOID PeerRMAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID StaPublicAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Bss2040Coexist);
+#endif // CONFIG_STA_SUPPORT //
+
+
+VOID PeerBSSTranAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef DOT11_N_SUPPORT
+VOID PeerHTAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // DOT11_N_SUPPORT //
+
+VOID PeerQOSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef QOS_DLS_SUPPORT
+VOID PeerDLSAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // QOS_DLS_SUPPORT //
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+VOID DlsParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
+ IN PRT_802_11_DLS pDls,
+ IN USHORT reason);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID RECBATimerTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID ORIBATimerTimeout(
+ IN PRTMP_ADAPTER pAd);
+
+VOID SendRefreshBAR(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+#endif // DOT11_N_SUPPORT //
+
+VOID ActHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN PUCHAR Addr1,
+ IN PUCHAR Addr2,
+ IN PUCHAR Addr3);
+
+VOID BarHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PFRAME_BAR pCntlBar,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA);
+
+VOID InsertActField(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pFrameBuf,
+ OUT PULONG pFrameLen,
+ IN UINT8 Category,
+ IN UINT8 ActCode);
+
+BOOLEAN QosBADataParse(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bAMSDU,
+ IN PUCHAR p8023Header,
+ IN UCHAR WCID,
+ IN UCHAR TID,
+ IN USHORT Sequence,
+ IN UCHAR DataOffset,
+ IN USHORT Datasize,
+ IN UINT CurRxIndex);
+
+#ifdef DOT11_N_SUPPORT
+BOOLEAN CntlEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG MsgLen,
+ IN PFRAME_BA_REQ pMsg);
+
+VOID BaAutoManSwitch(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11_N_SUPPORT //
+
+VOID HTIOTCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BatRecIdx);
+
+//
+// Private routines in rtmp_data.c
+//
+BOOLEAN RTMPHandleRxDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandleTxDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN RTMPHandleTxRingDmaDoneInterrupt(
+ IN PRTMP_ADAPTER pAd,
+ IN INT_SOURCE_CSR_STRUC TxRingBitmap);
+
+VOID RTMPHandleMgmtRingDmaDoneInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandleTBTTInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandlePreTBTTInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+void RTMPHandleTwakeupInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPHandleRxCoherentInterrupt(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN TxFrameIsAggregatible(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pPrevAddr1,
+ IN PUCHAR p8023hdr);
+
+BOOLEAN PeerIsAggreOn(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG TxRate,
+ IN PMAC_TABLE_ENTRY pMacEntry);
+
+NDIS_STATUS Sniff2BytesFromNdisBuffer(
+ IN PNDIS_BUFFER pFirstBuffer,
+ IN UCHAR DesiredOffset,
+ OUT PUCHAR pByte0,
+ OUT PUCHAR pByte1);
+
+NDIS_STATUS STASendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+VOID STASendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET ppPacketArray,
+ IN UINT NumberOfPackets);
+
+VOID RTMPDeQueuePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bIntContext,
+ IN UCHAR QueIdx,
+ IN UCHAR Max_Tx_Packets);
+
+NDIS_STATUS RTMPHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR QueIdx,
+ OUT PULONG pFreeTXDLeft);
+
+NDIS_STATUS STAHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx);
+
+VOID STARxEAPOLFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+NDIS_STATUS RTMPFreeTXDRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RingType,
+ IN UCHAR NumberRequired,
+ IN PUCHAR FreeNumberIs);
+
+NDIS_STATUS MlmeHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+NDIS_STATUS MlmeHardTransmitMgmtRing(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+NDIS_STATUS MlmeHardTransmitTxRing(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket);
+
+USHORT RTMPCalcDuration(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Rate,
+ IN ULONG Size);
+
+VOID RTMPWriteTxWI(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXWI_STRUC pTxWI,
+ IN BOOLEAN FRAG,
+ IN BOOLEAN CFACK,
+ IN BOOLEAN InsTimestamp,
+ IN BOOLEAN AMPDU,
+ IN BOOLEAN Ack,
+ IN BOOLEAN NSeq, // HW new a sequence.
+ IN UCHAR BASize,
+ IN UCHAR WCID,
+ IN ULONG Length,
+ IN UCHAR PID,
+ IN UCHAR TID,
+ IN UCHAR TxRate,
+ IN UCHAR Txopmode,
+ IN BOOLEAN CfAck,
+ IN HTTRANSMIT_SETTING *pTransmit);
+
+
+VOID RTMPWriteTxWI_Data(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk);
+
+
+VOID RTMPWriteTxWI_Cache(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PTXWI_STRUC pTxWI,
+ IN TX_BLK *pTxBlk);
+
+VOID RTMPWriteTxDescriptor(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXD_STRUC pTxD,
+ IN BOOLEAN bWIV,
+ IN UCHAR QSEL);
+
+VOID RTMPSuspendMsduTransmission(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPResumeMsduTransmission(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS MiniportMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length);
+
+NDIS_STATUS MiniportDataMMRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN PUCHAR pData,
+ IN UINT Length);
+
+VOID RTMPSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull);
+
+VOID RTMPSendDisassociationFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPSendRTSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN unsigned int NextMpduSize,
+ IN UCHAR TxRate,
+ IN UCHAR RTSRate,
+ IN USHORT AckDuration,
+ IN UCHAR QueIdx,
+ IN UCHAR FrameGap);
+
+
+NDIS_STATUS RTMPApplyPacketFilter(
+ IN PRTMP_ADAPTER pAd,
+ IN PRT28XX_RXD_STRUC pRxD,
+ IN PHEADER_802_11 pHeader);
+
+PQUEUE_HEADER RTMPCheckTxSwQueue(
+ IN PRTMP_ADAPTER pAd,
+ OUT UCHAR *QueIdx);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPReportMicError(
+ IN PRTMP_ADAPTER pAd,
+ IN PCIPHER_KEY pWpaKey);
+
+VOID WpaMicFailureReportFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaDisassocApAndBlockAssoc(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+#endif // CONFIG_STA_SUPPORT //
+
+NDIS_STATUS RTMPCloneNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN pInsAMSDUHdr,
+ IN PNDIS_PACKET pInPacket,
+ OUT PNDIS_PACKET *ppOutPacket);
+
+NDIS_STATUS RTMPAllocateNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET *pPacket,
+ IN PUCHAR pHeader,
+ IN UINT HeaderLen,
+ IN PUCHAR pData,
+ IN UINT DataLen);
+
+VOID RTMPFreeNdisPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+BOOLEAN RTMPFreeTXDUponTxDmaDone(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx);
+
+BOOLEAN RTMPCheckDHCPFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+BOOLEAN RTMPCheckEtherType(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+VOID RTMPCckBbpTuning(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT TxRate);
+
+//
+// Private routines in rtmp_wep.c
+//
+VOID RTMPInitWepEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN UCHAR KeyId,
+ IN UCHAR KeyLen,
+ IN PUCHAR pDest);
+
+VOID RTMPEncryptData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDest,
+ IN UINT Len);
+
+BOOLEAN RTMPDecryptData(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pSrc,
+ IN UINT Len,
+ IN UINT idx);
+
+BOOLEAN RTMPSoftDecryptWEP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pGroupKey);
+
+VOID RTMPSetICV(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDest);
+
+VOID ARCFOUR_INIT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pKey,
+ IN UINT KeyLen);
+
+UCHAR ARCFOUR_BYTE(
+ IN PARCFOURCONTEXT Ctx);
+
+VOID ARCFOUR_DECRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len);
+
+VOID ARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len);
+
+VOID WPAARCFOUR_ENCRYPT(
+ IN PARCFOURCONTEXT Ctx,
+ IN PUCHAR pDest,
+ IN PUCHAR pSrc,
+ IN UINT Len);
+
+UINT RTMP_CALC_FCS32(
+ IN UINT Fcs,
+ IN PUCHAR Cp,
+ IN INT Len);
+
+//
+// MLME routines
+//
+
+// Asic/RF/BBP related functions
+
+VOID AsicAdjustTxPower(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateProtect(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT OperaionMode,
+ IN UCHAR SetMask,
+ IN BOOLEAN bDisableBGProtect,
+ IN BOOLEAN bNonGFExist);
+
+VOID AsicSwitchChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel,
+ IN BOOLEAN bScan);
+
+VOID AsicLockChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel) ;
+
+VOID AsicAntennaSelect(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel);
+
+VOID AsicAntennaSetting(
+ IN PRTMP_ADAPTER pAd,
+ IN ABGBAND_STATE BandState);
+
+VOID AsicRfTuningExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID AsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp);
+
+VOID AsicForceSleep(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx);
+#endif // CONFIG_STA_SUPPORT //
+
+VOID AsicSetBssid(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid);
+
+VOID AsicSetMcastWC(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicDelWcidTab(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid);
+
+VOID AsicEnableRDG(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicDisableRDG(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicDisableSync(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicEnableBssSync(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicEnableIbssSync(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicSetEdcaParm(
+ IN PRTMP_ADAPTER pAd,
+ IN PEDCA_PARM pEdcaParm);
+
+VOID AsicSetSlotTime(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUseShortSlotTime);
+
+VOID AsicAddSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN PUCHAR pKey,
+ IN PUCHAR pTxMic,
+ IN PUCHAR pRxMic);
+
+VOID AsicRemoveSharedKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx);
+
+VOID AsicUpdateWCIDAttribute(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR CipherAlg,
+ IN BOOLEAN bUsePairewiseKeyTable);
+
+VOID AsicUpdateWCIDIVEIV(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN ULONG uIV,
+ IN ULONG uEIV);
+
+VOID AsicUpdateRxWCIDTable(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN PUCHAR pAddr);
+
+VOID AsicAddKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT WCID,
+ IN UCHAR BssIndex,
+ IN UCHAR KeyIdx,
+ IN PCIPHER_KEY pCipherKey,
+ IN BOOLEAN bUsePairewiseKeyTable,
+ IN BOOLEAN bTxKey);
+
+VOID AsicAddPairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UCHAR WCID,
+ IN CIPHER_KEY *pCipherKey);
+
+VOID AsicRemovePairwiseKeyEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR Wcid);
+
+BOOLEAN AsicSendCommandToMcu(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Command,
+ IN UCHAR Token,
+ IN UCHAR Arg0,
+ IN UCHAR Arg1);
+
+
+VOID MacAddrRandomBssid(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pAddr);
+
+VOID MgtMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR SubType,
+ IN UCHAR ToDs,
+ IN PUCHAR pDA,
+ IN PUCHAR pBssid);
+
+VOID MlmeRadioOff(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeRadioOn(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID BssTableInit(
+ IN BSS_TABLE *Tab);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInit(
+ IN PRTMP_ADAPTER pAd,
+ IN BA_TABLE *Tab);
+#endif // DOT11_N_SUPPORT //
+
+ULONG BssTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel);
+
+ULONG BssSsidTableSearch(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR pBssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel);
+
+ULONG BssTableSearchWithSSID(
+ IN BSS_TABLE *Tab,
+ IN PUCHAR Bssid,
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen,
+ IN UCHAR Channel);
+
+VOID BssTableDeleteEntry(
+ IN OUT PBSS_TABLE pTab,
+ IN PUCHAR pBssid,
+ IN UCHAR Channel);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableDeleteORIEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN BA_ORI_ENTRY *pBAORIEntry);
+
+VOID BATableDeleteRECEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN BA_REC_ENTRY *pBARECEntry);
+
+VOID BATableTearORIEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR TID,
+ IN UCHAR Wcid,
+ IN BOOLEAN bForceDelete,
+ IN BOOLEAN ALL);
+
+VOID BATableTearRECEntry(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR TID,
+ IN UCHAR WCID,
+ IN BOOLEAN ALL);
+#endif // DOT11_N_SUPPORT //
+
+VOID BssEntrySet(
+ IN PRTMP_ADAPTER pAd,
+ OUT PBSS_ENTRY pBss,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN PCF_PARM CfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR Channel,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE);
+
+ULONG BssTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT PBSS_TABLE pTab,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN USHORT BeaconPeriod,
+ IN CF_PARM *CfParm,
+ IN USHORT AtimWin,
+ IN USHORT CapabilityInfo,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR AddHtInfoLen,
+ IN UCHAR NewExtChanOffset,
+ IN UCHAR Channel,
+ IN CHAR Rssi,
+ IN LARGE_INTEGER TimeStamp,
+ IN UCHAR CkipFlag,
+ IN PEDCA_PARM pEdcaParm,
+ IN PQOS_CAPABILITY_PARM pQosCapability,
+ IN PQBSS_LOAD_PARM pQbssLoad,
+ IN USHORT LengthVIE,
+ IN PNDIS_802_11_VARIABLE_IEs pVIE);
+
+#ifdef DOT11_N_SUPPORT
+VOID BATableInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Aid,
+ IN USHORT TimeOutValue,
+ IN USHORT StartingSeq,
+ IN UCHAR TID,
+ IN UCHAR BAWinSize,
+ IN UCHAR OriginatorStatus,
+ IN BOOLEAN IsRecipient);
+
+#ifdef DOT11N_DRAFT3
+VOID Bss2040CoexistTimeOut(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+
+VOID TriEventInit(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG TriEventTableSetEntry(
+ IN PRTMP_ADAPTER pAd,
+ OUT TRIGGER_EVENT_TAB *Tab,
+ IN PUCHAR pBssid,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN UCHAR RegClass,
+ IN UCHAR ChannelNo);
+
+VOID TriEventCounterMaintenance(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+VOID BssTableSsidSort(
+ IN PRTMP_ADAPTER pAd,
+ OUT BSS_TABLE *OutTab,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen);
+
+VOID BssTableSortByRssi(
+ IN OUT BSS_TABLE *OutTab);
+
+VOID BssCipherParse(
+ IN OUT PBSS_ENTRY pBss);
+
+NDIS_STATUS MlmeQueueInit(
+ IN MLME_QUEUE *Queue);
+
+VOID MlmeQueueDestroy(
+ IN MLME_QUEUE *Queue);
+
+BOOLEAN MlmeEnqueue(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Machine,
+ IN ULONG MsgType,
+ IN ULONG MsgLen,
+ IN VOID *Msg);
+
+BOOLEAN MlmeEnqueueForRecv(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid,
+ IN ULONG TimeStampHigh,
+ IN ULONG TimeStampLow,
+ IN UCHAR Rssi0,
+ IN UCHAR Rssi1,
+ IN UCHAR Rssi2,
+ IN ULONG MsgLen,
+ IN PVOID Msg,
+ IN UCHAR Signal);
+
+
+BOOLEAN MlmeDequeue(
+ IN MLME_QUEUE *Queue,
+ OUT MLME_QUEUE_ELEM **Elem);
+
+VOID MlmeRestartStateMachine(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeQueueEmpty(
+ IN MLME_QUEUE *Queue);
+
+BOOLEAN MlmeQueueFull(
+ IN MLME_QUEUE *Queue);
+
+BOOLEAN MsgTypeSubst(
+ IN PRTMP_ADAPTER pAd,
+ IN PFRAME_802_11 pFrame,
+ OUT INT *Machine,
+ OUT INT *MsgType);
+
+VOID StateMachineInit(
+ IN STATE_MACHINE *Sm,
+ IN STATE_MACHINE_FUNC Trans[],
+ IN ULONG StNr,
+ IN ULONG MsgNr,
+ IN STATE_MACHINE_FUNC DefFunc,
+ IN ULONG InitState,
+ IN ULONG Base);
+
+VOID StateMachineSetAction(
+ IN STATE_MACHINE *S,
+ IN ULONG St,
+ ULONG Msg,
+ IN STATE_MACHINE_FUNC F);
+
+VOID StateMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Drop(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID ReassocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID AssocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID DisassocTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+//----------------------------------------------
+VOID MlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeReassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerReassocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDisassocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID DisassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AssocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ReassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Cls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+VOID SwitchBetweenWepAndCkip(
+ IN PRTMP_ADAPTER pAd);
+
+VOID InvalidStateWhenAssoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenReassoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenDisassociate(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef RT2870
+VOID MlmeCntlConfirm(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG MsgType,
+ IN USHORT Msg);
+#endif // RT2870 //
+
+VOID ComposePsPoll(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ComposeNullFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AssocPostProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN USHORT CapabilityInfo,
+ IN USHORT Aid,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN PEDCA_PARM pEdcaParm,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN ADD_HT_INFO_IE *pAddHtInfo);
+
+VOID AuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID AuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID MlmeAuthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthRspAtSeq2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthRspAtSeq4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AuthTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Cls2errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr);
+
+VOID MlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenAuth(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+//=============================================
+
+VOID AuthRspStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE Sm,
+ IN STATE_MACHINE_FUNC Trans[]);
+
+VOID PeerDeauthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr80211,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT Reason,
+ IN USHORT Status);
+
+//
+// Private routines in dls.c
+//
+
+#ifdef CONFIG_STA_SUPPORT
+#ifdef QOS_DLS_SUPPORT
+void DlsStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID RTMPCheckDLSTimeOut(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN RTMPRcvFrameDLSCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN ULONG Len,
+ IN PRT28XX_RXD_STRUC pRxD);
+
+INT RTMPCheckDLSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+VOID RTMPSendDLSTearDownFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+NDIS_STATUS RTMPSendSTAKeyRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+NDIS_STATUS RTMPSendSTAKeyHandShake(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+VOID DlsTimeoutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN MlmeDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PRT_802_11_DLS *pDLS,
+ OUT PUSHORT pReason);
+
+INT Set_DlsEntryInfo_Display_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UINT DlsEntryIdx);
+
+BOOLEAN MacTableDeleteDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr);
+
+MAC_TABLE_ENTRY *DlsEntryTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount);
+
+MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount);
+
+INT Set_DlsAddEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_DlsTearDownEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // QOS_DLS_SUPPORT //
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef QOS_DLS_SUPPORT
+BOOLEAN PeerDlsReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pDlsTimeout,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability);
+
+BOOLEAN PeerDlsRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT UCHAR *pRatesLen,
+ OUT UCHAR Rates[],
+ OUT UCHAR *pHtCapabilityLen,
+ OUT HT_CAPABILITY_IE *pHtCapability);
+
+BOOLEAN PeerDlsTearDownSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pDA,
+ OUT PUCHAR pSA,
+ OUT USHORT *pReason);
+#endif // QOS_DLS_SUPPORT //
+
+//========================================
+
+VOID SyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID BeaconTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID ScanTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID MlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenScan(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenJoin(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID InvalidStateWhenStart(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID EnqueueProbeRequest(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN ScanRunning(
+ IN PRTMP_ADAPTER pAd);
+//=========================================
+
+VOID MlmeCntlInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID MlmeCntlMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlIdleProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlOidScanProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlOidSsidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem);
+
+VOID CntlOidRTBssidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem);
+
+VOID CntlMlmeRoamingProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem);
+
+VOID CntlWaitDisassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitJoinProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitReassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitStartProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAuthProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAuthProc2(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CntlWaitAssocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+#ifdef QOS_DLS_SUPPORT
+VOID CntlOidDLSSetupProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+#endif // QOS_DLS_SUPPORT //
+
+VOID LinkUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssType);
+
+VOID LinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN IsReqFromAP);
+
+VOID IterateOnBssTab(
+ IN PRTMP_ADAPTER pAd);
+
+VOID IterateOnBssTab2(
+ IN PRTMP_ADAPTER pAd);;
+
+VOID JoinParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
+ IN ULONG BssIdx);
+
+VOID AssocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_ASSOC_REQ_STRUCT *AssocReq,
+ IN PUCHAR pAddr,
+ IN USHORT CapabilityInfo,
+ IN ULONG Timeout,
+ IN USHORT ListenIntv);
+
+VOID ScanParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN UCHAR ScanType);
+
+VOID DisassocParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DISASSOC_REQ_STRUCT *DisassocReq,
+ IN PUCHAR pAddr,
+ IN USHORT Reason);
+
+VOID StartParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_START_REQ_STRUCT *StartReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen);
+
+VOID AuthParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
+ IN PUCHAR pAddr,
+ IN USHORT Alg);
+
+VOID EnqueuePsPoll(
+ IN PRTMP_ADAPTER pAd);
+
+VOID EnqueueBeaconFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeJoinReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID MlmeStartReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ScanTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID BeaconTimeoutAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeaconAtScanAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeaconAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ScanNextChannel(
+ IN PRTMP_ADAPTER pAd);
+
+ULONG MakeIbssBeacon(
+ IN PRTMP_ADAPTER pAd);
+
+VOID CCXAdjacentAPReport(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeScanReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT UCHAR *BssType,
+ OUT CHAR ssid[],
+ OUT UCHAR *SsidLen,
+ OUT UCHAR *ScanType);
+
+BOOLEAN PeerBeaconAndProbeRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgChannel,
+ OUT PUCHAR pAddr2,
+ OUT PUCHAR pBssid,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen,
+ OUT UCHAR *pBssType,
+ OUT USHORT *pBeaconPeriod,
+ OUT UCHAR *pChannel,
+ OUT UCHAR *pNewChannel,
+ OUT LARGE_INTEGER *pTimestamp,
+ OUT CF_PARM *pCfParm,
+ OUT USHORT *pAtimWin,
+ OUT USHORT *pCapabilityInfo,
+ OUT UCHAR *pErp,
+ OUT UCHAR *pDtimCount,
+ OUT UCHAR *pDtimPeriod,
+ OUT UCHAR *pBcastFlag,
+ OUT UCHAR *pMessageToMe,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT UCHAR *pCkipFlag,
+ OUT UCHAR *pAironetCellPowerLimit,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT PQBSS_LOAD_PARM pQbssLoad,
+ OUT PQOS_CAPABILITY_PARM pQosCapability,
+ OUT ULONG *pRalinkIe,
+ OUT UCHAR *pHtCapabilityLen,
+#ifdef CONFIG_STA_SUPPORT
+ OUT UCHAR *pPreNHtCapabilityLen,
+#endif // CONFIG_STA_SUPPORT //
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT UCHAR *AddHtInfoLen,
+ OUT ADD_HT_INFO_IE *AddHtInfo,
+ OUT UCHAR *NewExtChannel,
+ OUT USHORT *LengthVIE,
+ OUT PNDIS_802_11_VARIABLE_IEs pVIE);
+
+BOOLEAN PeerAddBAReqActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2);
+
+BOOLEAN PeerAddBARspActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen);
+
+BOOLEAN PeerDelBAActionSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN VOID *pMsg,
+ IN ULONG MsgLen);
+
+BOOLEAN MlmeAssocReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pApAddr,
+ OUT USHORT *CapabilityInfo,
+ OUT ULONG *Timeout,
+ OUT USHORT *ListenIntv);
+
+BOOLEAN MlmeAuthReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT ULONG *Timeout,
+ OUT USHORT *Alg);
+
+BOOLEAN MlmeStartReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT CHAR Ssid[],
+ OUT UCHAR *Ssidlen);
+
+BOOLEAN PeerAuthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr,
+ OUT USHORT *Alg,
+ OUT USHORT *Seq,
+ OUT USHORT *Status,
+ OUT CHAR ChlgText[]);
+
+BOOLEAN PeerAssocRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT USHORT *pAid,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ OUT UCHAR *pHtCapabilityLen,
+ OUT UCHAR *pAddHtInfoLen,
+ OUT UCHAR *pNewExtChannelOffset,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT UCHAR *pCkipFlag);
+
+BOOLEAN PeerDisassocSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerWpaMessageSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN PEAPOL_PACKET pMsg,
+ IN ULONG MsgLen,
+ IN UCHAR MsgType,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN PeerDeauthSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *Reason);
+
+BOOLEAN PeerProbeReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen);
+
+BOOLEAN GetTimBit(
+ IN CHAR *Ptr,
+ IN USHORT Aid,
+ OUT UCHAR *TimLen,
+ OUT UCHAR *BcastFlag,
+ OUT UCHAR *DtimCount,
+ OUT UCHAR *DtimPeriod,
+ OUT UCHAR *MessageToMe);
+
+UCHAR ChannelSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel);
+
+NDIS_802_11_NETWORK_TYPE NetworkTypeInUseSanity(
+ IN PBSS_ENTRY pBss);
+
+BOOLEAN MlmeDelBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen);
+
+BOOLEAN MlmeAddBAReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2);
+
+ULONG MakeOutgoingFrame(
+ OUT CHAR *Buffer,
+ OUT ULONG *Length, ...);
+
+VOID LfsrInit(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Seed);
+
+UCHAR RandomByte(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicUpdateAutoFallBackTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pTxRate);
+
+VOID MlmePeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LinkDownExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID LinkUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID STAMlmePeriodicExec(
+ PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoScan(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeAutoReconnectLastSSID(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN MlmeValidateSSID(
+ IN PUCHAR pSsid,
+ IN UCHAR SsidLen);
+
+VOID MlmeCheckForRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32);
+
+VOID MlmeCheckForFastRoaming(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now);
+
+VOID MlmeDynamicTxRateSwitching(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeSetTxRate(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PRTMP_TX_RATE_SWITCH pTxRate);
+
+VOID MlmeSelectTxRateTable(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR *ppTable,
+ IN PUCHAR pTableSize,
+ IN PUCHAR pInitTxRateIdx);
+
+VOID MlmeCalculateChannelQuality(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now);
+
+VOID MlmeCheckPsmChange(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Now32);
+
+VOID MlmeSetPsmBit(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT psm);
+
+VOID MlmeSetTxPreamble(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TxPreamble);
+
+VOID UpdateBasicRateBitmap(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeUpdateTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bLinkUp,
+ IN UCHAR apidx);
+
+#ifdef DOT11_N_SUPPORT
+VOID MlmeUpdateHtTxRates(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx);
+#endif // DOT11_N_SUPPORT //
+
+VOID RTMPCheckRates(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT UCHAR SupRate[],
+ IN OUT UCHAR *SupRateLen);
+
+#ifdef CONFIG_STA_SUPPORT
+BOOLEAN RTMPCheckChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR CentralChannel,
+ IN UCHAR Channel);
+#endif // CONFIG_STA_SUPPORT //
+
+BOOLEAN RTMPCheckHt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN OUT HT_CAPABILITY_IE *pHtCapability,
+ IN OUT ADD_HT_INFO_IE *pAddHtInfo);
+
+VOID StaQuickResponeForRateUpExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID AsicBbpTuning1(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicBbpTuning2(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPUpdateMlmeRate(
+ IN PRTMP_ADAPTER pAd);
+
+CHAR RTMPMaxRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi0,
+ IN CHAR Rssi1,
+ IN CHAR Rssi2);
+
+VOID AsicSetRxAnt(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Ant);
+
+VOID AsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID AsicRxAntEvalTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID APSDPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+BOOLEAN RTMPCheckEntryEnableAutoRateSwitch(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+UCHAR RTMPStaFixedTxMode(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry);
+
+VOID RTMPUpdateLegacyTxSetting(
+ UCHAR fixed_tx_mode,
+ PMAC_TABLE_ENTRY pEntry);
+
+BOOLEAN RTMPAutoRateSwitchCheck(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS MlmeInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeHandler(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeHalt(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeResetRalinkCounters(
+ IN PRTMP_ADAPTER pAd);
+
+VOID BuildChannelList(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR FirstChannel(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR NextChannel(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR channel);
+
+VOID ChangeToCellPowerLimit(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR AironetCellPowerLimit);
+
+VOID RaiseClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x);
+
+VOID LowerClock(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 *x);
+
+USHORT ShiftInBits(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ShiftOutBits(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT data,
+ IN USHORT count);
+
+VOID EEpromCleanup(
+ IN PRTMP_ADAPTER pAd);
+
+VOID EWDS(
+ IN PRTMP_ADAPTER pAd);
+
+VOID EWEN(
+ IN PRTMP_ADAPTER pAd);
+
+USHORT RTMP_EEPROM_READ16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset);
+
+VOID RTMP_EEPROM_WRITE16(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Data);
+
+//
+// Prototypes of function definition in rtmp_tkip.c
+//
+VOID RTMPInitTkipEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pTKey,
+ IN UCHAR KeyId,
+ IN PUCHAR pTA,
+ IN PUCHAR pMICKey,
+ IN PUCHAR pTSC,
+ OUT PULONG pIV16,
+ OUT PULONG pIV32);
+
+VOID RTMPInitMICEngine(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKey,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN UCHAR UserPriority,
+ IN PUCHAR pMICKey);
+
+BOOLEAN RTMPTkipCompareMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UCHAR UserPriority,
+ IN UINT Len);
+
+VOID RTMPCalculateMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pEncap,
+ IN PCIPHER_KEY pKey,
+ IN UCHAR apidx);
+
+BOOLEAN RTMPTkipCompareMICValueWithLLC(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pLLC,
+ IN PUCHAR pSrc,
+ IN PUCHAR pDA,
+ IN PUCHAR pSA,
+ IN PUCHAR pMICKey,
+ IN UINT Len);
+
+VOID RTMPTkipAppendByte(
+ IN PTKIP_KEY_INFO pTkip,
+ IN UCHAR uChar);
+
+VOID RTMPTkipAppend(
+ IN PTKIP_KEY_INFO pTkip,
+ IN PUCHAR pSrc,
+ IN UINT nBytes);
+
+VOID RTMPTkipGetMIC(
+ IN PTKIP_KEY_INFO pTkip);
+
+BOOLEAN RTMPSoftDecryptTKIP(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN UCHAR UserPriority,
+ IN PCIPHER_KEY pWpaKey);
+
+BOOLEAN RTMPSoftDecryptAES(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataByteCnt,
+ IN PCIPHER_KEY pWpaKey);
+
+//
+// Prototypes of function definition in cmm_info.c
+//
+NDIS_STATUS RTMPWPARemoveKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf);
+
+VOID RTMPWPARemoveAllKeys(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN RTMPCheckStrPrintAble(
+ IN CHAR *pInPutStr,
+ IN UCHAR strLen);
+
+VOID RTMPSetPhyMode(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG phymode);
+
+VOID RTMPUpdateHTIE(
+ IN RT_HT_CAPABILITY *pRtHt,
+ IN UCHAR *pMcsSet,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo);
+
+VOID RTMPAddWcidAttributeEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssIdx,
+ IN UCHAR KeyIdx,
+ IN UCHAR CipherAlg,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+CHAR *GetEncryptType(
+ CHAR enc);
+
+CHAR *GetAuthMode(
+ CHAR auth);
+
+VOID RTMPIoctlGetSiteSurvey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlGetMacTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+VOID RTMPIndicateWPA2Status(
+ IN PRTMP_ADAPTER pAdapter);
+
+VOID RTMPOPModeSwitching(
+ IN PRTMP_ADAPTER pAd);
+
+#ifdef CONFIG_STA_SUPPORT
+VOID RTMPAddBSSIDCipher(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Aid,
+ IN PNDIS_802_11_KEY pKey,
+ IN UCHAR CipherAlg);
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+VOID RTMPSetHT(
+ IN PRTMP_ADAPTER pAd,
+ IN OID_SET_HT_PHYMODE *pHTPhyMode);
+
+VOID RTMPSetIndividualHT(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR apidx);
+#endif // DOT11_N_SUPPORT //
+
+VOID RTMPSendWirelessEvent(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Event_flag,
+ IN PUCHAR pAddr,
+ IN UCHAR BssIdx,
+ IN CHAR Rssi);
+
+VOID NICUpdateCntlCounters(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN UCHAR SubType,
+ IN PRXWI_STRUC pRxWI);
+//
+// prototype in wpa.c
+//
+BOOLEAN WpaMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT INT *MsgType);
+
+VOID WpaPskStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID WpaEAPOLKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaPairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaPairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaGroupMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID WpaMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR wep,
+ IN PUCHAR pAddr1);
+
+VOID Wpa2PairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID Wpa2PairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+BOOLEAN ParseKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR bPairewise);
+
+VOID RTMPToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN BOOLEAN is4wayFrame);
+
+VOID HMAC_SHA1(
+ IN UCHAR *text,
+ IN UINT text_len,
+ IN UCHAR *key,
+ IN UINT key_len,
+ IN UCHAR *digest);
+
+VOID PRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *prefix,
+ IN INT prefix_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len);
+
+VOID CCKMPRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len);
+
+VOID WpaCountPTK(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *PMK,
+ IN UCHAR *ANonce,
+ IN UCHAR *AA,
+ IN UCHAR *SNonce,
+ IN UCHAR *SA,
+ OUT UCHAR *output,
+ IN UINT len);
+
+VOID GenRandom(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR *macAddr,
+ OUT UCHAR *random);
+
+//
+// prototype in aironet.c
+//
+VOID AironetStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[]);
+
+VOID AironetMsgAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID AironetRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ChannelLoadRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID NoiseHistRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID BeaconRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID AironetReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID ChannelLoadReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID NoiseHistReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID AironetFinalReportAction(
+ IN PRTMP_ADAPTER pAd);
+
+VOID BeaconReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID AironetAddBeaconReport(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Index,
+ IN PMLME_QUEUE_ELEM pElem);
+
+VOID AironetCreateBeaconReportFromBssTable(
+ IN PRTMP_ADAPTER pAd);
+
+VOID DBGPRINT_TX_RING(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx);
+
+VOID DBGPRINT_RX_RING(
+ IN PRTMP_ADAPTER pAd);
+
+CHAR ConvertToRssi(
+ IN PRTMP_ADAPTER pAd,
+ IN CHAR Rssi,
+ IN UCHAR RssiNumber);
+
+
+#ifdef DOT11N_DRAFT3
+VOID BuildEffectedChannelList(
+ IN PRTMP_ADAPTER pAd);
+#endif // DOT11N_DRAFT3 //
+
+
+VOID APAsicEvaluateRxAnt(
+ IN PRTMP_ADAPTER pAd);
+
+
+VOID APAsicRxAntEvalTimeout(
+ IN PRTMP_ADAPTER pAd);
+
+//
+// function prototype in cmm_wpa.c
+//
+BOOLEAN RTMPCheckWPAframe(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN PUCHAR pData,
+ IN ULONG DataByteCount,
+ IN UCHAR FromWhichBSSID);
+
+VOID AES_GTK_KEY_UNWRAP(
+ IN UCHAR *key,
+ OUT UCHAR *plaintext,
+ IN UCHAR c_len,
+ IN UCHAR *ciphertext);
+
+BOOLEAN RTMPCheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ IN MAC_TABLE_ENTRY *pEntry,
+ OUT UCHAR *Offset);
+
+BOOLEAN RTMPParseEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR GroupKeyIndex,
+ IN UCHAR MsgType,
+ IN BOOLEAN bWPA2,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID ConstructEapolMsg(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerAuthMode,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR MyGroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN UCHAR *ReplayCounter,
+ IN UCHAR *KeyNonce,
+ IN UCHAR *TxRSC,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_Len,
+ OUT PEAPOL_PACKET pMsg);
+
+VOID CalculateMIC(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR *PTK,
+ OUT PEAPOL_PACKET pMsg);
+
+NDIS_STATUS RTMPSoftDecryptBroadCastData(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN NDIS_802_11_ENCRYPTION_STATUS GroupCipher,
+ IN PCIPHER_KEY pShard_key);
+
+VOID ConstructEapolKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR PeerAuthMode,
+ IN UCHAR PeerWepStatus,
+ IN UCHAR GroupKeyWepStatus,
+ IN UCHAR MsgType,
+ IN UCHAR DefaultKeyIdx,
+ IN BOOLEAN bWPA2Capable,
+ IN UCHAR *PTK,
+ IN UCHAR *GTK,
+ IN UCHAR *RSNIE,
+ IN UCHAR RSNIE_LEN,
+ OUT PEAPOL_PACKET pMsg);
+
+VOID RTMPMakeRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT AuthMode,
+ IN UINT WepStatus,
+ IN UCHAR apidx);
+
+//
+// function prototype in ap_wpa.c
+//
+
+BOOLEAN APWpaMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT INT *MsgType) ;
+
+MAC_TABLE_ENTRY *PACInquiry(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Wcid);
+
+BOOLEAN RTMPCheckMcast(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN RTMPCheckUcast(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+BOOLEAN RTMPCheckAUTH(
+ IN PRTMP_ADAPTER pAd,
+ IN PEID_STRUCT eid_ptr,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID WPAStart4WayHS(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN ULONG TimeInterval);
+
+VOID WPAStart2WayGroupHS(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID APWpaEAPPacketAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLStartAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLLogoffAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID APWpaEAPOLASFAlertAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID HandleCounterMeasure(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+VOID PeerPairMsg2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerPairMsg4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID CMTimerExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID WPARetryExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID EnqueueStartForPSKExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID RTMPHandleSTAKey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN MLME_QUEUE_ELEM *Elem);
+
+VOID PeerGroupMsg2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN VOID *Msg,
+ IN UINT MsgLen);
+
+VOID PairDisAssocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN USHORT Reason);
+
+VOID MlmeDeAuthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN USHORT Reason);
+
+VOID GREKEYPeriodicExec(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3);
+
+VOID CountGTK(
+ IN UCHAR *PMK,
+ IN UCHAR *GNonce,
+ IN UCHAR *AA,
+ OUT UCHAR *output,
+ IN UINT len);
+
+VOID GetSmall(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ OUT PUCHAR out,
+ IN ULONG Length);
+
+VOID GetLarge(
+ IN PVOID pSrc1,
+ IN PVOID pSrc2,
+ OUT PUCHAR out,
+ IN ULONG Length);
+
+VOID APGenRandom(
+ IN PRTMP_ADAPTER pAd,
+ OUT UCHAR *random);
+
+VOID AES_GTK_KEY_WRAP(
+ IN UCHAR *key,
+ IN UCHAR *plaintext,
+ IN UCHAR p_len,
+ OUT UCHAR *ciphertext);
+
+VOID WpaSend(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR pPacket,
+ IN ULONG Len);
+
+VOID APToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN BOOLEAN bClearFrame);
+
+VOID RTMPAddPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PUCHAR pAddr,
+ IN UCHAR *PMKID,
+ IN UCHAR *PMK);
+
+INT RTMPSearchPMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN PUCHAR pAddr);
+
+VOID RTMPDeletePMKIDCache(
+ IN PRTMP_ADAPTER pAd,
+ IN INT apidx,
+ IN INT idx);
+
+VOID RTMPMaintainPMKIDCache(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPSendTriggerFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuffer,
+ IN ULONG Length,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull);
+
+#ifdef RT30xx
+VOID RTMPFilterCalibration(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT30xx //
+
+
+//typedef void (*TIMER_FUNCTION)(unsigned long);
+
+
+/* timeout -- ms */
+VOID RTMP_SetPeriodicTimer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout);
+
+VOID RTMP_OS_Init_Timer(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN TIMER_FUNCTION function,
+ IN PVOID data);
+
+VOID RTMP_OS_Add_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout);
+
+VOID RTMP_OS_Mod_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ IN unsigned long timeout);
+
+
+VOID RTMP_OS_Del_Timer(
+ IN NDIS_MINIPORT_TIMER *pTimer,
+ OUT BOOLEAN *pCancelled);
+
+
+VOID RTMP_OS_Release_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PQUEUE_ENTRY pEntry);
+
+VOID RTMPusecDelay(
+ IN ULONG usec);
+
+NDIS_STATUS os_alloc_mem(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR *mem,
+ IN ULONG size);
+
+NDIS_STATUS os_free_mem(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR mem);
+
+
+void RTMP_AllocateSharedMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+VOID RTMPFreeTxRxRingMemory(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS AdapterBlockAllocateMemory(
+ IN PVOID handle,
+ OUT PVOID *ppAd);
+
+void RTMP_AllocateTxDescMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT Index,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateFirstTxBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT Index,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateMgmtDescMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+void RTMP_AllocateRxDescMemory(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+PNDIS_PACKET RTMP_AllocateRxPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress,
+ OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress);
+
+PNDIS_PACKET RTMP_AllocateTxPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length,
+ IN BOOLEAN Cached,
+ OUT PVOID *VirtualAddress);
+
+PNDIS_PACKET RTMP_AllocateFragPacketBuffer(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Length);
+
+void RTMP_QueryPacketInfo(
+ IN PNDIS_PACKET pPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen);
+
+void RTMP_QueryNextPacketInfo(
+ IN PNDIS_PACKET *ppPacket,
+ OUT PACKET_INFO *pPacketInfo,
+ OUT PUCHAR *pSrcBufVA,
+ OUT UINT *pSrcBufLen);
+
+
+BOOLEAN RTMP_FillTxBlkInfo(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk);
+
+
+PRTMP_SCATTER_GATHER_LIST
+rt_get_sg_list_from_packet(PNDIS_PACKET pPacket, RTMP_SCATTER_GATHER_LIST *sg);
+
+
+ void announce_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+UINT BA_Reorder_AMSDU_Annnounce(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket);
+
+
+UINT Handle_AMSDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+
+void convert_802_11_to_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR p8023hdr,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+
+PNET_DEV get_netdev_from_bssid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR FromWhichBSSID);
+
+
+PNDIS_PACKET duplicate_pkt(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+
+PNDIS_PACKET duplicate_pkt_with_TKIP_MIC(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pOldPkt);
+
+PNDIS_PACKET duplicate_pkt_with_VLAN(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ IN UCHAR FromWhichBSSID);
+
+PNDIS_PACKET duplicate_pkt_with_WPI(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UINT32 ext_head_len,
+ IN UINT32 ext_tail_len);
+
+UCHAR VLAN_8023_Header_Copy(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ OUT PUCHAR pData,
+ IN UCHAR FromWhichBSSID);
+
+#ifdef DOT11_N_SUPPORT
+void ba_flush_reordering_timeout_mpdus(
+ IN PRTMP_ADAPTER pAd,
+ IN PBA_REC_ENTRY pBAEntry,
+ IN ULONG Now32);
+
+
+VOID BAOriSessionSetUp(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN UCHAR TID,
+ IN USHORT TimeOut,
+ IN ULONG DelayTime,
+ IN BOOLEAN isForced);
+
+VOID BASessionTearDownALL(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid);
+#endif // DOT11_N_SUPPORT //
+
+BOOLEAN OS_Need_Clone_Packet(void);
+
+
+VOID build_tx_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pFrame,
+ IN ULONG FrameLen);
+
+
+VOID BAOriSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive,
+ IN BOOLEAN bForceSend);
+
+VOID BARecSessionTearDown(
+ IN OUT PRTMP_ADAPTER pAd,
+ IN UCHAR Wcid,
+ IN UCHAR TID,
+ IN BOOLEAN bPassive);
+
+BOOLEAN ba_reordering_resource_init(PRTMP_ADAPTER pAd, int num);
+void ba_reordering_resource_release(PRTMP_ADAPTER pAd);
+
+ULONG AutoChBssInsertEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pBssid,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR ChannelNo,
+ IN CHAR Rssi);
+
+void AutoChBssTableInit(
+ IN PRTMP_ADAPTER pAd);
+
+void ChannelInfoInit(
+ IN PRTMP_ADAPTER pAd);
+
+void AutoChBssTableDestroy(
+ IN PRTMP_ADAPTER pAd);
+
+void ChannelInfoDestroy(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR New_ApAutoSelectChannel(
+ IN PRTMP_ADAPTER pAd);
+
+
+#ifdef NINTENDO_AP
+VOID InitNINTENDO_TABLE(
+ IN PRTMP_ADAPTER pAd);
+
+UCHAR CheckNINTENDO_TABLE(
+ IN PRTMP_ADAPTER pAd,
+ PCHAR pDS_Ssid,
+ UCHAR DS_SsidLen,
+ PUCHAR pDS_Addr);
+
+UCHAR DelNINTENDO_ENTRY(
+ IN PRTMP_ADAPTER pAd,
+ UCHAR * pDS_Addr);
+
+VOID RTMPIoctlNintendoCapable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlNintendoGetTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlNintendoSetTable(
+ IN PRTMP_ADAPTER pAd,
+ IN struct iwreq *wrq);
+
+#endif // NINTENDO_AP //
+
+BOOLEAN rtstrmactohex(
+ IN char *s1,
+ IN char *s2);
+
+BOOLEAN rtstrcasecmp(
+ IN char *s1,
+ IN char *s2);
+
+char *rtstrstruncasecmp(
+ IN char *s1,
+ IN char *s2);
+
+char *rtstrstr(
+ IN const char * s1,
+ IN const char * s2);
+
+char *rstrtok(
+ IN char * s,
+ IN const char * ct);
+
+int rtinet_aton(
+ const char *cp,
+ unsigned int *addr);
+
+////////// common ioctl functions //////////
+INT Set_DriverVersion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_CountryRegion_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_CountryRegionABand_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_WirelessMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_Channel_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ShortSlot_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TxPower_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BGProtection_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TxPreamble_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_RTSThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_FragThreshold_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TxBurst_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef AGGREGATION_SUPPORT
+INT Set_PktAggregate_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif
+
+INT Set_IEEE80211H_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef DBG
+INT Set_Debug_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif
+
+INT Show_DescInfo_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ResetStatCounter_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef DOT11_N_SUPPORT
+INT Set_BASetup_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BADecline_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BAOriTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_BARecTearDown_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtBw_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMcs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtGi_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtOpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtStbc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtHtc_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtExtcha_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMpduDensity_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtBaWinSize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtRdg_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtLinkAdapt_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtAmsdu_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtAutoBa_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtProtect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMimoPs_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
+INT Set_ForceShortGI_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_ForceGF_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT SetCommonHT(
+ IN PRTMP_ADAPTER pAd);
+
+INT Set_SendPSMPAction_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_HtMIMOPSmode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+
+INT Set_HtTxBASize_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // DOT11_N_SUPPORT //
+
+
+
+#ifdef CONFIG_STA_SUPPORT
+//Dls , kathy
+VOID RTMPSendDLSTearDownFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA);
+
+#ifdef DOT11_N_SUPPORT
+//Block ACK
+VOID QueryBATABLE(
+ IN PRTMP_ADAPTER pAd,
+ OUT PQUERYBA_TABLE pBAT);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+INT WpaCheckEapCode(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFrame,
+ IN USHORT FrameLen,
+ IN USHORT OffSet);
+
+VOID WpaSendMicFailureToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUnicast);
+
+VOID SendAssocIEsToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+int wext_notify_event_assoc(
+ IN RTMP_ADAPTER *pAd);
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#endif // CONFIG_STA_SUPPORT //
+
+
+
+#ifdef DOT11_N_SUPPORT
+VOID Handle_BSS_Width_Trigger_Events(
+ IN PRTMP_ADAPTER pAd);
+
+void build_ext_channel_switch_ie(
+ IN PRTMP_ADAPTER pAd,
+ IN HT_EXT_CHANNEL_SWITCH_ANNOUNCEMENT_IE *pIE);
+#endif // DOT11_N_SUPPORT //
+
+
+BOOLEAN APRxDoneInterruptHandle(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN STARxDoneInterruptHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN argc);
+
+#ifdef DOT11_N_SUPPORT
+// AMPDU packet indication
+VOID Indicate_AMPDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+// AMSDU packet indication
+VOID Indicate_AMSDU_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+#endif // DOT11_N_SUPPORT //
+
+// Normal legacy Rx packet indication
+VOID Indicate_Legacy_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+VOID Indicate_EAPOL_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+void update_os_packet_info(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+void wlan_802_11_to_802_3_packet(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN PUCHAR pHeader802_3,
+ IN UCHAR FromWhichBSSID);
+
+UINT deaggregate_AMSDU_announce(
+ IN PRTMP_ADAPTER pAd,
+ PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize);
+
+
+#ifdef CONFIG_STA_SUPPORT
+// remove LLC and get 802_3 Header
+#define RTMP_802_11_REMOVE_LLC_AND_CONVERT_TO_802_3(_pRxBlk, _pHeader802_3) \
+{ \
+ PUCHAR _pRemovedLLCSNAP = NULL, _pDA, _pSA; \
+ \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_MESH)) \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr3; \
+ _pSA = (PUCHAR)_pRxBlk->pHeader + sizeof(HEADER_802_11); \
+ } \
+ else \
+ { \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_INFRA)) \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr1; \
+ if (RX_BLK_TEST_FLAG(_pRxBlk, fRX_DLS)) \
+ _pSA = _pRxBlk->pHeader->Addr2; \
+ else \
+ _pSA = _pRxBlk->pHeader->Addr3; \
+ } \
+ else \
+ { \
+ _pDA = _pRxBlk->pHeader->Addr1; \
+ _pSA = _pRxBlk->pHeader->Addr2; \
+ } \
+ } \
+ \
+ CONVERT_TO_802_3(_pHeader802_3, _pDA, _pSA, _pRxBlk->pData, \
+ _pRxBlk->DataSize, _pRemovedLLCSNAP); \
+}
+#endif // CONFIG_STA_SUPPORT //
+
+
+BOOLEAN APFowardWirelessStaToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN ULONG FromWhichBSSID);
+
+VOID Announce_or_Forward_802_3_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID);
+
+VOID Sta_Announce_or_Forward_802_3_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID);
+
+
+#ifdef CONFIG_STA_SUPPORT
+#define ANNOUNCE_OR_FORWARD_802_3_PACKET(_pAd, _pPacket, _FromWhichBSS)\
+ Sta_Announce_or_Forward_802_3_Packet(_pAd, _pPacket, _FromWhichBSS);
+ //announce_802_3_packet(_pAd, _pPacket);
+#endif // CONFIG_STA_SUPPORT //
+
+
+PNDIS_PACKET DuplicatePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID);
+
+
+PNDIS_PACKET ClonePacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize);
+
+
+// Normal, AMPDU or AMSDU
+VOID CmmRxnonRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+VOID CmmRxRalinkFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID);
+
+VOID Update_Rssi_Sample(
+ IN PRTMP_ADAPTER pAd,
+ IN RSSI_SAMPLE *pRssi,
+ IN PRXWI_STRUC pRxWI);
+
+PNDIS_PACKET GetPacketFromRxRing(
+ IN PRTMP_ADAPTER pAd,
+ OUT PRT28XX_RXD_STRUC pSaveRxD,
+ OUT BOOLEAN *pbReschedule,
+ IN OUT UINT32 *pRxPending);
+
+PNDIS_PACKET RTMPDeFragmentDataFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk);
+
+////////////////////////////////////////
+
+
+
+
+
+#ifdef SNMP_SUPPORT
+//for snmp , kathy
+typedef struct _DefaultKeyIdxValue
+{
+ UCHAR KeyIdx;
+ UCHAR Value[16];
+} DefaultKeyIdxValue, *PDefaultKeyIdxValue;
+#endif
+
+
+#ifdef CONFIG_STA_SUPPORT
+enum {
+ DIDmsg_lnxind_wlansniffrm = 0x00000044,
+ DIDmsg_lnxind_wlansniffrm_hosttime = 0x00010044,
+ DIDmsg_lnxind_wlansniffrm_mactime = 0x00020044,
+ DIDmsg_lnxind_wlansniffrm_channel = 0x00030044,
+ DIDmsg_lnxind_wlansniffrm_rssi = 0x00040044,
+ DIDmsg_lnxind_wlansniffrm_sq = 0x00050044,
+ DIDmsg_lnxind_wlansniffrm_signal = 0x00060044,
+ DIDmsg_lnxind_wlansniffrm_noise = 0x00070044,
+ DIDmsg_lnxind_wlansniffrm_rate = 0x00080044,
+ DIDmsg_lnxind_wlansniffrm_istx = 0x00090044,
+ DIDmsg_lnxind_wlansniffrm_frmlen = 0x000A0044
+};
+enum {
+ P80211ENUM_msgitem_status_no_value = 0x00
+};
+enum {
+ P80211ENUM_truth_false = 0x00,
+ P80211ENUM_truth_true = 0x01
+};
+
+/* Definition from madwifi */
+typedef struct {
+ UINT32 did;
+ UINT16 status;
+ UINT16 len;
+ UINT32 data;
+} p80211item_uint32_t;
+
+typedef struct {
+ UINT32 msgcode;
+ UINT32 msglen;
+#define WLAN_DEVNAMELEN_MAX 16
+ UINT8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t hosttime;
+ p80211item_uint32_t mactime;
+ p80211item_uint32_t channel;
+ p80211item_uint32_t rssi;
+ p80211item_uint32_t sq;
+ p80211item_uint32_t signal;
+ p80211item_uint32_t noise;
+ p80211item_uint32_t rate;
+ p80211item_uint32_t istx;
+ p80211item_uint32_t frmlen;
+} wlan_ng_prism2_header;
+
+/* The radio capture header precedes the 802.11 header. */
+typedef struct PACKED _ieee80211_radiotap_header {
+ UINT8 it_version; /* Version 0. Only increases
+ * for drastic changes,
+ * introduction of compatible
+ * new fields does not count.
+ */
+ UINT8 it_pad;
+ UINT16 it_len; /* length of the whole
+ * header in bytes, including
+ * it_version, it_pad,
+ * it_len, and data fields.
+ */
+ UINT32 it_present; /* A bitmap telling which
+ * fields are present. Set bit 31
+ * (0x80000000) to extend the
+ * bitmap by another 32 bits.
+ * Additional extensions are made
+ * by setting bit 31.
+ */
+}ieee80211_radiotap_header ;
+
+enum ieee80211_radiotap_type {
+ IEEE80211_RADIOTAP_TSFT = 0,
+ IEEE80211_RADIOTAP_FLAGS = 1,
+ IEEE80211_RADIOTAP_RATE = 2,
+ IEEE80211_RADIOTAP_CHANNEL = 3,
+ IEEE80211_RADIOTAP_FHSS = 4,
+ IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+ IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+ IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+ IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+ IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+ IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+ IEEE80211_RADIOTAP_ANTENNA = 11,
+ IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+ IEEE80211_RADIOTAP_DB_ANTNOISE = 13
+};
+
+#define WLAN_RADIOTAP_PRESENT ( \
+ (1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ 0)
+
+typedef struct _wlan_radiotap_header {
+ ieee80211_radiotap_header wt_ihdr;
+ INT64 wt_tsft;
+ UINT8 wt_flags;
+ UINT8 wt_rate;
+} wlan_radiotap_header;
+/* Definition from madwifi */
+
+void send_monitor_packets(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk);
+
+#if WIRELESS_EXT >= 12
+// This function will be called when query /proc
+struct iw_statistics *rt28xx_get_wireless_stats(
+ IN struct net_device *net_dev);
+#endif
+
+VOID RTMPSetDesiredRates(
+ IN PRTMP_ADAPTER pAdapter,
+ IN LONG Rates);
+#endif // CONFIG_STA_SUPPORT //
+
+INT Set_FixedTxMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+INT Set_OpMode_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+
+static inline char* GetPhyMode(
+ int Mode)
+{
+ switch(Mode)
+ {
+ case MODE_CCK:
+ return "CCK";
+
+ case MODE_OFDM:
+ return "OFDM";
+#ifdef DOT11_N_SUPPORT
+ case MODE_HTMIX:
+ return "HTMIX";
+
+ case MODE_HTGREENFIELD:
+ return "GREEN";
+#endif // DOT11_N_SUPPORT //
+ default:
+ return "N/A";
+ }
+}
+
+
+static inline char* GetBW(
+ int BW)
+{
+ switch(BW)
+ {
+ case BW_10:
+ return "10M";
+
+ case BW_20:
+ return "20M";
+#ifdef DOT11_N_SUPPORT
+ case BW_40:
+ return "40M";
+#endif // DOT11_N_SUPPORT //
+ default:
+ return "N/A";
+ }
+}
+
+
+VOID RT28xxThreadTerminate(
+ IN RTMP_ADAPTER *pAd);
+
+BOOLEAN RT28XXChipsetCheck(
+ IN void *_dev_p);
+
+BOOLEAN RT28XXNetDevInit(
+ IN void *_dev_p,
+ IN struct net_device *net_dev,
+ IN RTMP_ADAPTER *pAd);
+
+BOOLEAN RT28XXProbePostConfig(
+ IN void *_dev_p,
+ IN RTMP_ADAPTER *pAd,
+ IN INT32 argc);
+
+VOID RT28XXDMADisable(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT28XXDMAEnable(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT28xx_UpdateBeaconToAsic(
+ IN RTMP_ADAPTER * pAd,
+ IN INT apidx,
+ IN ULONG BeaconLen,
+ IN ULONG UpdatePos);
+
+INT rt28xx_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd);
+
+
+#ifdef CONFIG_STA_SUPPORT
+INT rt28xx_sta_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd);
+#endif // CONFIG_STA_SUPPORT //
+
+BOOLEAN RT28XXSecurityKeyAdd(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG apidx,
+ IN ULONG KeyIdx,
+ IN MAC_TABLE_ENTRY *pEntry);
+
+////////////////////////////////////////
+PNDIS_PACKET GetPacketFromRxRing(
+ IN PRTMP_ADAPTER pAd,
+ OUT PRT28XX_RXD_STRUC pSaveRxD,
+ OUT BOOLEAN *pbReschedule,
+ IN OUT UINT32 *pRxPending);
+
+
+void kill_thread_task(PRTMP_ADAPTER pAd);
+
+void tbtt_tasklet(unsigned long data);
+
+
+VOID AsicTurnOffRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel);
+
+VOID AsicTurnOnRFClk(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Channel);
+
+#ifdef RT30xx
+NTSTATUS RT30xxWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN UCHAR Value);
+
+NTSTATUS RT30xxReadRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR RegID,
+ IN PUCHAR pValue);
+
+//2008/09/11:KH add to support efuse<--
+UCHAR eFuseReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData);
+
+VOID eFuseReadPhysical(
+ IN PRTMP_ADAPTER pAd,
+ IN PUSHORT lpInBuffer,
+ IN ULONG nInBufferSize,
+ OUT PUSHORT lpOutBuffer,
+ IN ULONG nOutBufferSize
+);
+
+NTSTATUS eFuseRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT Length);
+
+VOID eFusePhysicalWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData);
+
+NTSTATUS eFuseWriteRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData);
+
+VOID eFuseWritePhysical(
+ IN PRTMP_ADAPTER pAd,
+ PUSHORT lpInBuffer,
+ ULONG nInBufferSize,
+ PUCHAR lpOutBuffer,
+ ULONG nOutBufferSize
+);
+
+NTSTATUS eFuseWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length);
+
+INT set_eFuseGetFreeBlockCount_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT set_eFusedump_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT set_eFuseLoadFromBin_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+NTSTATUS eFuseWriteRegistersFromBin(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ IN USHORT* pData);
+
+VOID eFusePhysicalReadRegisters(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN USHORT Length,
+ OUT USHORT* pData);
+
+NDIS_STATUS NICLoadEEPROM(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN bNeedLoadEEPROM(
+ IN PRTMP_ADAPTER pAd);
+//2008/09/11:KH add to support efuse-->
+#endif // RT30xx //
+
+#ifdef RT30xx
+// add by johnli, RF power sequence setup
+VOID RT30xxLoadRFNormalModeSetup(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT30xxLoadRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT30xxReverseRFSleepModeSetup(
+ IN PRTMP_ADAPTER pAd);
+// end johnli
+#endif // RT30xx //
+
+#ifdef RT2870
+//
+// Function Prototype in rtusb_bulk.c
+//
+VOID RTUSBInitTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PTX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN usb_complete_t Func);
+
+VOID RTUSBInitHTTxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PHT_TX_CONTEXT pTxContext,
+ IN UCHAR BulkOutPipeId,
+ IN ULONG BulkOutSize,
+ IN usb_complete_t Func);
+
+VOID RTUSBInitRxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PRX_CONTEXT pRxContext);
+
+VOID RTUSBCleanUpDataBulkOutQueue(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCancelPendingBulkOutIRP(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkOutDataPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UCHAR Index);
+
+VOID RTUSBBulkOutNullFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkOutRTSFrame(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCancelPendingBulkInIRP(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCancelPendingIRPs(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkOutMLMEPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index);
+
+VOID RTUSBBulkOutPsPoll(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBCleanUpMLMEBulkOutQueue(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBKickBulkOut(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBBulkReceive(
+ IN PRTMP_ADAPTER pAd);
+
+VOID DoBulkIn(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RTUSBInitRxDesc(
+ IN PRTMP_ADAPTER pAd,
+ IN PRX_CONTEXT pRxContext);
+
+VOID RTUSBBulkRxHandle(
+ IN unsigned long data);
+
+//
+// Function Prototype in rtusb_io.c
+//
+NTSTATUS RTUSBMultiRead(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length);
+
+NTSTATUS RTUSBMultiWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length);
+
+NTSTATUS RTUSBMultiWrite_OneByte(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData);
+
+NTSTATUS RTUSBReadBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN PUCHAR pValue);
+
+NTSTATUS RTUSBWriteBBPRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Id,
+ IN UCHAR Value);
+
+NTSTATUS RTUSBWriteRFRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 Value);
+
+NTSTATUS RTUSB_VendorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UINT32 TransferFlags,
+ IN UCHAR ReservedBits,
+ IN UCHAR Request,
+ IN USHORT Value,
+ IN USHORT Index,
+ IN PVOID TransferBuffer,
+ IN UINT32 TransferBufferLength);
+
+NTSTATUS RTUSBReadEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUCHAR pData,
+ IN USHORT length);
+
+NTSTATUS RTUSBWriteEEPROM(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN PUCHAR pData,
+ IN USHORT length);
+
+VOID RTUSBPutToSleep(
+ IN PRTMP_ADAPTER pAd);
+
+NTSTATUS RTUSBWakeUp(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTUSBInitializeCmdQ(
+ IN PCmdQ cmdq);
+
+NDIS_STATUS RTUSBEnqueueCmdFromNdis(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN BOOLEAN SetInformation,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength);
+
+NDIS_STATUS RTUSBEnqueueInternalCmd(
+ IN PRTMP_ADAPTER pAd,
+ IN NDIS_OID Oid,
+ IN PVOID pInformationBuffer,
+ IN UINT32 InformationBufferLength);
+
+VOID RTUSBDequeueCmd(
+ IN PCmdQ cmdq,
+ OUT PCmdQElmt *pcmdqelmt);
+
+INT RTUSBCmdThread(
+ IN OUT PVOID Context);
+
+INT TimerQThread(
+ IN OUT PVOID Context);
+
+RT2870_TIMER_ENTRY *RT2870_TimerQ_Insert(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer);
+
+BOOLEAN RT2870_TimerQ_Remove(
+ IN RTMP_ADAPTER *pAd,
+ IN RALINK_TIMER_STRUCT *pTimer);
+
+void RT2870_TimerQ_Exit(
+ IN RTMP_ADAPTER *pAd);
+
+void RT2870_TimerQ_Init(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconExit(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconStop(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_BssBeaconStart(
+ IN RTMP_ADAPTER * pAd);
+
+VOID RT2870_BssBeaconInit(
+ IN RTMP_ADAPTER *pAd);
+
+VOID RT2870_WatchDog(
+ IN RTMP_ADAPTER *pAd);
+
+NTSTATUS RTUSBWriteMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ IN UINT32 Value);
+
+NTSTATUS RTUSBReadMACRegister(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT Offset,
+ OUT PUINT32 pValue);
+
+NTSTATUS RTUSBSingleWrite(
+ IN RTMP_ADAPTER *pAd,
+ IN USHORT Offset,
+ IN USHORT Value);
+
+NTSTATUS RTUSBFirmwareRun(
+ IN PRTMP_ADAPTER pAd);
+
+NTSTATUS RTUSBFirmwareWrite(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFwImage,
+ IN ULONG FwLen);
+
+NTSTATUS RTUSBFirmwareOpmode(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUINT32 pValue);
+
+NTSTATUS RTUSBVenderReset(
+ IN PRTMP_ADAPTER pAd);
+
+NDIS_STATUS RTUSBSetHardWareRegister(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PVOID pBuf);
+
+NDIS_STATUS RTUSBQueryHardWareRegister(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PVOID pBuf);
+
+VOID CMDHandler(
+ IN PRTMP_ADAPTER pAd);
+
+
+NDIS_STATUS CreateThreads(
+ IN struct net_device *net_dev );
+
+
+VOID MacTableInitialize(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MlmeSetPsm(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT psm);
+
+NDIS_STATUS RTMPWPAAddKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf);
+
+VOID AsicRxAntEvalAction(
+ IN PRTMP_ADAPTER pAd);
+
+void append_pkt(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN ULONG DataSize,
+ OUT PNDIS_PACKET *ppPacket);
+
+UINT deaggregate_AMSDU_announce(
+ IN PRTMP_ADAPTER pAd,
+ PNDIS_PACKET pPacket,
+ IN PUCHAR pData,
+ IN ULONG DataSize);
+
+NDIS_STATUS RTMPCheckRxError(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN PRXWI_STRUC pRxWI,
+ IN PRT28XX_RXD_STRUC pRxINFO);
+
+
+VOID RTUSBMlmeHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN PMGMT_STRUC pMgmt);
+
+INT MlmeThread(
+ IN PVOID Context);
+
+//
+// Function Prototype in rtusb_data.c
+//
+NDIS_STATUS RTUSBFreeDescriptorRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BulkOutPipeId,
+ IN UINT32 NumberRequired);
+
+
+BOOLEAN RTUSBNeedQueueBackForAgg(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR BulkOutPipeId);
+
+
+VOID RTMPWriteTxInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PTXINFO_STRUC pTxInfo,
+ IN USHORT USBDMApktLen,
+ IN BOOLEAN bWiv,
+ IN UCHAR QueueSel,
+ IN UCHAR NextValid,
+ IN UCHAR TxBurst);
+
+//
+// Function Prototype in cmm_data_2870.c
+//
+USHORT RtmpUSB_WriteSubTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber);
+
+USHORT RtmpUSB_WriteSingleTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN BOOLEAN bIsLast,
+ OUT USHORT *FreeNumber);
+
+USHORT RtmpUSB_WriteFragTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR fragNum,
+ OUT USHORT *FreeNumber);
+
+USHORT RtmpUSB_WriteMultiTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR frameNum,
+ OUT USHORT *FreeNumber);
+
+VOID RtmpUSB_FinalWriteTxResource(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN USHORT totalMPDUSize,
+ IN USHORT TxIdx);
+
+VOID RtmpUSBDataLastTxIdx(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN USHORT TxIdx);
+
+VOID RtmpUSBDataKickOut(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx);
+
+
+int RtmpUSBMgmtKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN PNDIS_PACKET pPacket,
+ IN PUCHAR pSrcBufVA,
+ IN UINT SrcBufLen);
+
+VOID RtmpUSBNullFrameKickOut(
+ IN RTMP_ADAPTER *pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR *pNullFrame,
+ IN UINT32 frameLen);
+
+VOID RT28xxUsbStaAsicForceWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bFromTx);
+
+VOID RT28xxUsbStaAsicSleepThenAutoWakeup(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT TbttNumToNextWakeUp);
+
+VOID RT28xxUsbMlmeRadioOn(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RT28xxUsbMlmeRadioOFF(
+ IN PRTMP_ADAPTER pAd);
+#endif // RT2870 //
+
+////////////////////////////////////////
+
+VOID QBSS_LoadInit(
+ IN RTMP_ADAPTER *pAd);
+
+UINT32 QBSS_LoadElementAppend(
+ IN RTMP_ADAPTER *pAd,
+ OUT UINT8 *buf_p);
+
+VOID QBSS_LoadUpdate(
+ IN RTMP_ADAPTER *pAd);
+
+///////////////////////////////////////
+INT RTMPShowCfgValue(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pName,
+ IN PUCHAR pBuf);
+
+PCHAR RTMPGetRalinkAuthModeStr(
+ IN NDIS_802_11_AUTHENTICATION_MODE authMode);
+
+PCHAR RTMPGetRalinkEncryModeStr(
+ IN USHORT encryMode);
+//////////////////////////////////////
+
+#ifdef CONFIG_STA_SUPPORT
+VOID AsicStaBbpTuning(
+ IN PRTMP_ADAPTER pAd);
+
+BOOLEAN StaAddMacTableEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN USHORT CapabilityInfo);
+#endif // CONFIG_STA_SUPPORT //
+
+void RTMP_IndicateMediaState(
+ IN PRTMP_ADAPTER pAd);
+
+VOID ReSyncBeaconTime(
+ IN PRTMP_ADAPTER pAd);
+
+VOID RTMPSetAGCInitValue(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BandWidth);
+
+int rt28xx_close(IN PNET_DEV dev);
+int rt28xx_open(IN PNET_DEV dev);
+
+__inline INT VIRTUAL_IF_UP(PRTMP_ADAPTER pAd)
+{
+extern VOID MeshMakeBeacon(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
+extern VOID MeshUpdateBeaconFrame(IN PRTMP_ADAPTER pAd, IN UCHAR idx);
+
+ if (VIRTUAL_IF_NUM(pAd) == 0)
+ {
+ if (rt28xx_open(pAd->net_dev) != 0)
+ return -1;
+ }
+ else
+ {
+ }
+ VIRTUAL_IF_INC(pAd);
+ return 0;
+}
+
+__inline VOID VIRTUAL_IF_DOWN(PRTMP_ADAPTER pAd)
+{
+ VIRTUAL_IF_DEC(pAd);
+ if (VIRTUAL_IF_NUM(pAd) == 0)
+ rt28xx_close(pAd->net_dev);
+ return;
+}
+
+
+#endif // __RTMP_H__
+
diff --git a/drivers/staging/rt3070/rtmp_ckipmic.h b/drivers/staging/rt3070/rtmp_ckipmic.h
new file mode 100644
index 00000000000..a3d949a39d3
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_ckipmic.h
@@ -0,0 +1,113 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_ckipmic.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+#ifndef __RTMP_CKIPMIC_H__
+#define __RTMP_CKIPMIC_H__
+
+typedef struct _MIC_CONTEXT {
+ /* --- MMH context */
+ UCHAR CK[16]; /* the key */
+ UCHAR coefficient[16]; /* current aes counter mode coefficients */
+ ULONGLONG accum; /* accumulated mic, reduced to u32 in final() */
+ UINT position; /* current position (byte offset) in message */
+ UCHAR part[4]; /* for conversion of message to u32 for mmh */
+} MIC_CONTEXT, *PMIC_CONTEXT;
+
+VOID CKIP_key_permute(
+ OUT UCHAR *PK, /* output permuted key */
+ IN UCHAR *CK, /* input CKIP key */
+ IN UCHAR toDsFromDs, /* input toDs/FromDs bits */
+ IN UCHAR *piv); /* input pointer to IV */
+
+VOID RTMPCkipMicInit(
+ IN PMIC_CONTEXT pContext,
+ IN PUCHAR CK);
+
+VOID RTMPMicUpdate(
+ IN PMIC_CONTEXT pContext,
+ IN PUCHAR pOctets,
+ IN INT len);
+
+ULONG RTMPMicGetCoefficient(
+ IN PMIC_CONTEXT pContext);
+
+VOID xor_128(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+UCHAR RTMPCkipSbox(
+ IN UCHAR a);
+
+VOID xor_32(
+ IN PUCHAR a,
+ IN PUCHAR b,
+ OUT PUCHAR out);
+
+VOID next_key(
+ IN PUCHAR key,
+ IN INT round);
+
+VOID byte_sub(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID shift_row(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID mix_column(
+ IN PUCHAR in,
+ OUT PUCHAR out);
+
+VOID RTMPAesEncrypt(
+ IN PUCHAR key,
+ IN PUCHAR data,
+ IN PUCHAR ciphertext);
+
+VOID RTMPMicFinal(
+ IN PMIC_CONTEXT pContext,
+ OUT UCHAR digest[4]);
+
+VOID RTMPCkipInsertCMIC(
+ IN PRTMP_ADAPTER pAd,
+ OUT PUCHAR pMIC,
+ IN PUCHAR p80211hdr,
+ IN PNDIS_PACKET pPacket,
+ IN PCIPHER_KEY pKey,
+ IN PUCHAR mic_snap);
+
+#endif //__RTMP_CKIPMIC_H__
diff --git a/drivers/staging/rt3070/rtmp_def.h b/drivers/staging/rt3070/rtmp_def.h
new file mode 100644
index 00000000000..2599f7c836e
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_def.h
@@ -0,0 +1,1559 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_def.h
+
+ Abstract:
+ Miniport related definition header
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 08-01-2002 created
+ John Chang 08-05-2003 add definition for 11g & other drafts
+*/
+#ifndef __RTMP_DEF_H__
+#define __RTMP_DEF_H__
+
+#include "oid.h"
+
+#undef AP_WSC_INCLUDED
+#undef STA_WSC_INCLUDED
+#undef WSC_INCLUDED
+
+
+#ifdef CONFIG_STA_SUPPORT
+#endif // CONFIG_STA_SUPPORT //
+
+#if defined(AP_WSC_INCLUDED) || defined(STA_WSC_INCLUDED)
+#define WSC_INCLUDED
+#endif
+//
+// Debug information verbosity: lower values indicate higher urgency
+//
+#define RT_DEBUG_OFF 0
+#define RT_DEBUG_ERROR 1
+#define RT_DEBUG_WARN 2
+#define RT_DEBUG_TRACE 3
+#define RT_DEBUG_INFO 4
+#define RT_DEBUG_LOUD 5
+
+#define NIC_TAG ((ULONG)'0682')
+#define NIC_DBG_STRING ("**RT28xx**")
+
+#ifdef SNMP_SUPPORT
+// for snmp
+// to get manufacturer OUI, kathy, 2008_0220
+#define ManufacturerOUI_LEN 3
+#define ManufacturerNAME ("Ralink Technology Company.")
+#define ResourceTypeIdName ("Ralink_ID")
+#endif
+
+
+//#define PACKED
+
+#define RALINK_2883_VERSION ((UINT32)0x28830300)
+#define RALINK_2880E_VERSION ((UINT32)0x28720200)
+#define RALINK_3070_VERSION ((UINT32)0x30700200)
+
+//
+// NDIS version in use by the NIC driver.
+// The high byte is the major version. The low byte is the minor version.
+//
+#ifdef NDIS51_MINIPORT
+#define NIC_DRIVER_VERSION 0x0501
+#else
+#define NIC_DRIVER_VERSION 0x0500
+#endif
+
+//
+// NDIS media type, current is ethernet, change if native wireless supported
+//
+#define NIC_MEDIA_TYPE NdisMedium802_3
+#define NIC_PCI_HDR_LENGTH 0xe2
+#define NIC_MAX_PACKET_SIZE 2304
+#define NIC_HEADER_SIZE 14
+#define MAX_MAP_REGISTERS_NEEDED 32
+#define MIN_MAP_REGISTERS_NEEDED 2 //Todo: should consider fragment issue.
+
+//
+// interface type, we use PCI
+//
+#define NIC_INTERFACE_TYPE NdisInterfacePci
+#define NIC_INTERRUPT_MODE NdisInterruptLevelSensitive
+
+//
+// buffer size passed in NdisMQueryAdapterResources
+// We should only need three adapter resources (IO, interrupt and memory),
+// Some devices get extra resources, so have room for 10 resources
+// UF_SIZE (sizeof(NDIS_RESOURCE_LIST) + (10*sizeof(CM_PARTIAL_RESOURCE_DESCRIPTOR)))
+
+
+#define NIC_RESOURCE_B//
+// IO space length
+//
+#define NIC_MAP_IOSPACE_LENGTH sizeof(CSR_STRUC)
+
+#define MAX_RX_PKT_LEN 1520
+
+//
+// Entry number for each DMA descriptor ring
+//
+
+
+#ifdef RT2870
+#define TX_RING_SIZE 8 // 1
+#define PRIO_RING_SIZE 8
+#define MGMT_RING_SIZE 32 // PRIO_RING_SIZE
+#define RX_RING_SIZE 8
+#define MAX_TX_PROCESS 4
+#define LOCAL_TXBUF_SIZE 2048
+#endif // RT2870 //
+
+#ifdef MULTIPLE_CARD_SUPPORT
+// MC: Multple Cards
+#define MAX_NUM_OF_MULTIPLE_CARD 32
+#endif // MULTIPLE_CARD_SUPPORT //
+
+#define MAX_RX_PROCESS 128 //64 //32
+#define NUM_OF_LOCAL_TXBUF 2
+#define TXD_SIZE 16
+#define TXWI_SIZE 16
+#define RXD_SIZE 16
+#define RXWI_SIZE 16
+// TXINFO_SIZE + TXWI_SIZE + 802.11 Header Size + AMSDU sub frame header
+#define TX_DMA_1ST_BUFFER_SIZE 96 // only the 1st physical buffer is pre-allocated
+#define MGMT_DMA_BUFFER_SIZE 1536 //2048
+#define RX_BUFFER_AGGRESIZE 3840 //3904 //3968 //4096 //2048 //4096
+#define RX_BUFFER_NORMSIZE 3840 //3904 //3968 //4096 //2048 //4096
+#define TX_BUFFER_NORMSIZE RX_BUFFER_NORMSIZE
+#define MAX_FRAME_SIZE 2346 // Maximum 802.11 frame size
+#define MAX_AGGREGATION_SIZE 3840 //3904 //3968 //4096
+#define MAX_NUM_OF_TUPLE_CACHE 2
+#define MAX_MCAST_LIST_SIZE 32
+#define MAX_LEN_OF_VENDOR_DESC 64
+//#define MAX_SIZE_OF_MCAST_PSQ (NUM_OF_LOCAL_TXBUF >> 2) // AP won't spend more than 1/4 of total buffers on M/BCAST PSQ
+#define MAX_SIZE_OF_MCAST_PSQ 32
+
+#define MAX_RX_PROCESS_CNT (RX_RING_SIZE)
+
+
+#define MAX_PACKETS_IN_QUEUE (512) //(512) // to pass WMM A5-WPAPSK
+#define MAX_PACKETS_IN_MCAST_PS_QUEUE 32
+#define MAX_PACKETS_IN_PS_QUEUE 128 //32
+#define WMM_NUM_OF_AC 4 /* AC0, AC1, AC2, and AC3 */
+
+
+//2008/09/11:KH add to support efuse<--
+#define MAX_EEPROM_BIN_FILE_SIZE 1024
+//2008/09/11:KH add to support efuse-->
+
+// RxFilter
+#define STANORMAL 0x17f97
+#define APNORMAL 0x15f97
+//
+// RTMP_ADAPTER flags
+//
+#define fRTMP_ADAPTER_MAP_REGISTER 0x00000001
+#define fRTMP_ADAPTER_INTERRUPT_IN_USE 0x00000002
+#define fRTMP_ADAPTER_HARDWARE_ERROR 0x00000004
+#define fRTMP_ADAPTER_SCATTER_GATHER 0x00000008
+#define fRTMP_ADAPTER_SEND_PACKET_ERROR 0x00000010
+#define fRTMP_ADAPTER_MLME_RESET_IN_PROGRESS 0x00000020
+#define fRTMP_ADAPTER_HALT_IN_PROGRESS 0x00000040
+#define fRTMP_ADAPTER_RESET_IN_PROGRESS 0x00000080
+#define fRTMP_ADAPTER_NIC_NOT_EXIST 0x00000100
+#define fRTMP_ADAPTER_TX_RING_ALLOCATED 0x00000200
+#define fRTMP_ADAPTER_REMOVE_IN_PROGRESS 0x00000400
+#define fRTMP_ADAPTER_MIMORATE_INUSED 0x00000800
+#define fRTMP_ADAPTER_RX_RING_ALLOCATED 0x00001000
+#define fRTMP_ADAPTER_INTERRUPT_ACTIVE 0x00002000
+#define fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS 0x00004000
+#define fRTMP_ADAPTER_REASSOC_IN_PROGRESS 0x00008000
+#define fRTMP_ADAPTER_MEDIA_STATE_PENDING 0x00010000
+#define fRTMP_ADAPTER_RADIO_OFF 0x00020000
+#define fRTMP_ADAPTER_BULKOUT_RESET 0x00040000
+#define fRTMP_ADAPTER_BULKIN_RESET 0x00080000
+#define fRTMP_ADAPTER_RDG_ACTIVE 0x00100000
+#define fRTMP_ADAPTER_DYNAMIC_BE_TXOP_ACTIVE 0x00200000
+#define fRTMP_ADAPTER_SCAN_2040 0x04000000
+#define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000
+
+#define fRTMP_ADAPTER_START_UP 0x10000000 //Devive already initialized and enabled Tx/Rx.
+#define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000
+#define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000
+
+// Lock bit for accessing different ring buffers
+//#define fRTMP_ADAPTER_TX_RING_BUSY 0x80000000
+//#define fRTMP_ADAPTER_MGMT_RING_BUSY 0x40000000
+//#define fRTMP_ADAPTER_ATIM_RING_BUSY 0x20000000
+//#define fRTMP_ADAPTER_RX_RING_BUSY 0x10000000
+
+// Lock bit for accessing different queue
+//#define fRTMP_ADAPTER_TX_QUEUE_BUSY 0x08000000
+//#define fRTMP_ADAPTER_MGMT_QUEUE_BUSY 0x04000000
+
+//
+// STA operation status flags
+//
+#define fOP_STATUS_INFRA_ON 0x00000001
+#define fOP_STATUS_ADHOC_ON 0x00000002
+#define fOP_STATUS_BG_PROTECTION_INUSED 0x00000004
+#define fOP_STATUS_SHORT_SLOT_INUSED 0x00000008
+#define fOP_STATUS_SHORT_PREAMBLE_INUSED 0x00000010
+#define fOP_STATUS_RECEIVE_DTIM 0x00000020
+//#define fOP_STATUS_TX_RATE_SWITCH_ENABLED 0x00000040
+#define fOP_STATUS_MEDIA_STATE_CONNECTED 0x00000080
+#define fOP_STATUS_WMM_INUSED 0x00000100
+#define fOP_STATUS_AGGREGATION_INUSED 0x00000200
+#define fOP_STATUS_DOZE 0x00000400 // debug purpose
+#define fOP_STATUS_PIGGYBACK_INUSED 0x00000800 // piggy-back, and aggregation
+#define fOP_STATUS_APSD_INUSED 0x00001000
+#define fOP_STATUS_TX_AMSDU_INUSED 0x00002000
+#define fOP_STATUS_MAX_RETRY_ENABLED 0x00004000
+#define fOP_STATUS_WAKEUP_NOW 0x00008000
+#define fOP_STATUS_ADVANCE_POWER_SAVE_PCIE_DEVICE 0x00020000
+
+#ifdef DOT11N_DRAFT3
+#define fOP_STATUS_SCAN_2040 0x00040000
+#endif // DOT11N_DRAFT3 //
+
+#define CCKSETPROTECT 0x1
+#define OFDMSETPROTECT 0x2
+#define MM20SETPROTECT 0x4
+#define MM40SETPROTECT 0x8
+#define GF20SETPROTECT 0x10
+#define GR40SETPROTECT 0x20
+#define ALLN_SETPROTECT (GR40SETPROTECT | GF20SETPROTECT | MM40SETPROTECT | MM20SETPROTECT)
+
+//
+// AP's client table operation status flags
+//
+#define fCLIENT_STATUS_WMM_CAPABLE 0x00000001 // CLIENT can parse QOS DATA frame
+#define fCLIENT_STATUS_AGGREGATION_CAPABLE 0x00000002 // CLIENT can receive Ralink's proprietary TX aggregation frame
+#define fCLIENT_STATUS_PIGGYBACK_CAPABLE 0x00000004 // CLIENT support piggy-back
+#define fCLIENT_STATUS_AMSDU_INUSED 0x00000008
+#define fCLIENT_STATUS_SGI20_CAPABLE 0x00000010
+#define fCLIENT_STATUS_SGI40_CAPABLE 0x00000020
+#define fCLIENT_STATUS_TxSTBC_CAPABLE 0x00000040
+#define fCLIENT_STATUS_RxSTBC_CAPABLE 0x00000080
+#define fCLIENT_STATUS_HTC_CAPABLE 0x00000100
+#define fCLIENT_STATUS_RDG_CAPABLE 0x00000200
+#define fCLIENT_STATUS_MCSFEEDBACK_CAPABLE 0x00000400
+#define fCLIENT_STATUS_APSD_CAPABLE 0x00000800 /* UAPSD STATION */
+
+#ifdef DOT11N_DRAFT3
+#define fCLIENT_STATUS_BSSCOEXIST_CAPABLE 0x00001000
+#endif // DOT11N_DRAFT3 //
+
+#define fCLIENT_STATUS_RALINK_CHIPSET 0x00100000
+//
+// STA configuration flags
+//
+//#define fSTA_CFG_ENABLE_TX_BURST 0x00000001
+
+// 802.11n Operating Mode Definition. 0-3 also used in ASICUPdateProtect switch case
+#define HT_NO_PROTECT 0
+#define HT_LEGACY_PROTECT 1
+#define HT_40_PROTECT 2
+#define HT_2040_PROTECT 3
+#define HT_RTSCTS_6M 7
+//following is our own definition in order to turn on our ASIC protection register in INFRASTRUCTURE.
+#define HT_ATHEROS 8
+#define HT_FORCERTSCTS 9 // Force turn on RTS/CTS first. then go to evaluate if this force RTS is necessary.
+
+//
+// RX Packet Filter control flags. Apply on pAd->PacketFilter
+//
+#define fRX_FILTER_ACCEPT_DIRECT NDIS_PACKET_TYPE_DIRECTED
+#define fRX_FILTER_ACCEPT_MULTICAST NDIS_PACKET_TYPE_MULTICAST
+#define fRX_FILTER_ACCEPT_BROADCAST NDIS_PACKET_TYPE_BROADCAST
+#define fRX_FILTER_ACCEPT_ALL_MULTICAST NDIS_PACKET_TYPE_ALL_MULTICAST
+
+//
+// Error code section
+//
+// NDIS_ERROR_CODE_ADAPTER_NOT_FOUND
+#define ERRLOG_READ_PCI_SLOT_FAILED 0x00000101L
+#define ERRLOG_WRITE_PCI_SLOT_FAILED 0x00000102L
+#define ERRLOG_VENDOR_DEVICE_NOMATCH 0x00000103L
+
+// NDIS_ERROR_CODE_ADAPTER_DISABLED
+#define ERRLOG_BUS_MASTER_DISABLED 0x00000201L
+
+// NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION
+#define ERRLOG_INVALID_SPEED_DUPLEX 0x00000301L
+#define ERRLOG_SET_SECONDARY_FAILED 0x00000302L
+
+// NDIS_ERROR_CODE_OUT_OF_RESOURCES
+#define ERRLOG_OUT_OF_MEMORY 0x00000401L
+#define ERRLOG_OUT_OF_SHARED_MEMORY 0x00000402L
+#define ERRLOG_OUT_OF_MAP_REGISTERS 0x00000403L
+#define ERRLOG_OUT_OF_BUFFER_POOL 0x00000404L
+#define ERRLOG_OUT_OF_NDIS_BUFFER 0x00000405L
+#define ERRLOG_OUT_OF_PACKET_POOL 0x00000406L
+#define ERRLOG_OUT_OF_NDIS_PACKET 0x00000407L
+#define ERRLOG_OUT_OF_LOOKASIDE_MEMORY 0x00000408L
+
+// NDIS_ERROR_CODE_HARDWARE_FAILURE
+#define ERRLOG_SELFTEST_FAILED 0x00000501L
+#define ERRLOG_INITIALIZE_ADAPTER 0x00000502L
+#define ERRLOG_REMOVE_MINIPORT 0x00000503L
+
+// NDIS_ERROR_CODE_RESOURCE_CONFLICT
+#define ERRLOG_MAP_IO_SPACE 0x00000601L
+#define ERRLOG_QUERY_ADAPTER_RESOURCES 0x00000602L
+#define ERRLOG_NO_IO_RESOURCE 0x00000603L
+#define ERRLOG_NO_INTERRUPT_RESOURCE 0x00000604L
+#define ERRLOG_NO_MEMORY_RESOURCE 0x00000605L
+
+
+// WDS definition
+#define MAX_WDS_ENTRY 4
+#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
+
+#define WDS_DISABLE_MODE 0
+#define WDS_RESTRICT_MODE 1
+#define WDS_BRIDGE_MODE 2
+#define WDS_REPEATER_MODE 3
+#define WDS_LAZY_MODE 4
+
+
+#define MAX_MESH_NUM 0
+
+#define MAX_APCLI_NUM 0
+
+#define MAX_MBSSID_NUM 1
+#ifdef MBSS_SUPPORT
+#undef MAX_MBSSID_NUM
+#define MAX_MBSSID_NUM (8 - MAX_MESH_NUM - MAX_APCLI_NUM)
+#endif // MBSS_SUPPORT //
+
+/* sanity check for apidx */
+#define MBSS_MR_APIDX_SANITY_CHECK(apidx) \
+ { if (apidx > MAX_MBSSID_NUM) { \
+ printk("%s> Error! apidx = %d > MAX_MBSSID_NUM!\n", __FUNCTION__, apidx); \
+ apidx = MAIN_MBSSID; } }
+
+#define VALID_WCID(_wcid) ((_wcid) > 0 && (_wcid) < MAX_LEN_OF_MAC_TABLE )
+
+#define MAIN_MBSSID 0
+#define FIRST_MBSSID 1
+
+
+#define MAX_BEACON_SIZE 512
+// If the MAX_MBSSID_NUM is larger than 6,
+// it shall reserve some WCID space(wcid 222~253) for beacon frames.
+// - these wcid 238~253 are reserved for beacon#6(ra6).
+// - these wcid 222~237 are reserved for beacon#7(ra7).
+#if defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 8)
+#define HW_RESERVED_WCID 222
+#elif defined(MAX_MBSSID_NUM) && (MAX_MBSSID_NUM == 7)
+#define HW_RESERVED_WCID 238
+#else
+#define HW_RESERVED_WCID 255
+#endif
+
+// Then dedicate wcid of DFS and Carrier-Sense.
+#define DFS_CTS_WCID (HW_RESERVED_WCID - 1)
+#define CS_CTS_WCID (HW_RESERVED_WCID - 2)
+#define LAST_SPECIFIC_WCID (HW_RESERVED_WCID - 2)
+
+// If MAX_MBSSID_NUM is 8, the maximum available wcid for the associated STA is 211.
+// If MAX_MBSSID_NUM is 7, the maximum available wcid for the associated STA is 228.
+#define MAX_AVAILABLE_CLIENT_WCID (LAST_SPECIFIC_WCID - MAX_MBSSID_NUM - 1)
+
+// TX need WCID to find Cipher Key
+// these wcid 212 ~ 219 are reserved for bc/mc packets if MAX_MBSSID_NUM is 8.
+#define GET_GroupKey_WCID(__wcid, __bssidx) \
+ { \
+ __wcid = LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM) + __bssidx; \
+ }
+
+#define IsGroupKeyWCID(__wcid) (((__wcid) < LAST_SPECIFIC_WCID) && ((__wcid) >= (LAST_SPECIFIC_WCID - (MAX_MBSSID_NUM))))
+
+
+// definition to support multiple BSSID
+#define BSS0 0
+#define BSS1 1
+#define BSS2 2
+#define BSS3 3
+#define BSS4 4
+#define BSS5 5
+#define BSS6 6
+#define BSS7 7
+
+
+//============================================================
+// Length definitions
+#define PEER_KEY_NO 2
+#define MAC_ADDR_LEN 6
+#define TIMESTAMP_LEN 8
+#define MAX_LEN_OF_SUPPORTED_RATES MAX_LENGTH_OF_SUPPORT_RATES // 1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54
+#define MAX_LEN_OF_KEY 32 // 32 octets == 256 bits, Redefine for WPA
+#define MAX_NUM_OF_CHANNELS MAX_NUM_OF_CHS // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
+#define MAX_NUM_OF_11JCHANNELS 20 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination
+#define MAX_LEN_OF_SSID 32
+#define CIPHER_TEXT_LEN 128
+#define HASH_TABLE_SIZE 256
+#define MAX_VIE_LEN 1024 // New for WPA cipher suite variable IE sizes.
+#define MAX_SUPPORT_MCS 32
+
+//============================================================
+// ASIC WCID Table definition.
+//============================================================
+#define BSSID_WCID 1 // in infra mode, always put bssid with this WCID
+#define MCAST_WCID 0x0
+#define BSS0Mcast_WCID 0x0
+#define BSS1Mcast_WCID 0xf8
+#define BSS2Mcast_WCID 0xf9
+#define BSS3Mcast_WCID 0xfa
+#define BSS4Mcast_WCID 0xfb
+#define BSS5Mcast_WCID 0xfc
+#define BSS6Mcast_WCID 0xfd
+#define BSS7Mcast_WCID 0xfe
+#define RESERVED_WCID 0xff
+
+#define MAX_NUM_OF_ACL_LIST MAX_NUMBER_OF_ACL
+
+#define MAX_LEN_OF_MAC_TABLE MAX_NUMBER_OF_MAC // if MAX_MBSSID_NUM is 8, this value can't be larger than 211
+
+#if MAX_LEN_OF_MAC_TABLE>MAX_AVAILABLE_CLIENT_WCID
+#error MAX_LEN_OF_MAC_TABLE can not be larger than MAX_AVAILABLE_CLIENT_WCID!!!!
+#endif
+
+#define MAX_NUM_OF_WDS_LINK_PERBSSID 3
+#define MAX_NUM_OF_WDS_LINK (MAX_NUM_OF_WDS_LINK_PERBSSID*MAX_MBSSID_NUM)
+#define MAX_NUM_OF_EVENT MAX_NUMBER_OF_EVENT
+#define WDS_LINK_START_WCID (MAX_LEN_OF_MAC_TABLE-1)
+
+#define NUM_OF_TID 8
+#define MAX_AID_BA 4
+#define MAX_LEN_OF_BA_REC_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)// (NUM_OF_TID*MAX_AID_BA + 32) //Block ACK recipient
+#define MAX_LEN_OF_BA_ORI_TABLE ((NUM_OF_TID * MAX_LEN_OF_MAC_TABLE)/2)// (NUM_OF_TID*MAX_AID_BA + 32) // Block ACK originator
+#define MAX_LEN_OF_BSS_TABLE 64
+#define MAX_REORDERING_MPDU_NUM 512
+
+// key related definitions
+#define SHARE_KEY_NUM 4
+#define MAX_LEN_OF_SHARE_KEY 16 // byte count
+#define MAX_LEN_OF_PEER_KEY 16 // byte count
+#define PAIRWISE_KEY_NUM 64 // in MAC ASIC pairwise key table
+#define GROUP_KEY_NUM 4
+#define PMK_LEN 32
+#define WDS_PAIRWISE_KEY_OFFSET 60 // WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table
+#define PMKID_NO 4 // Number of PMKID saved supported
+#define MAX_LEN_OF_MLME_BUFFER 2048
+
+// power status related definitions
+#define PWR_ACTIVE 0
+#define PWR_SAVE 1
+#define PWR_MMPS 2 //MIMO power save
+//#define PWR_UNKNOWN 2
+
+// Auth and Assoc mode related definitions
+#define AUTH_MODE_OPEN 0x00
+#define AUTH_MODE_KEY 0x01
+//#define AUTH_MODE_AUTO_SWITCH 0x03
+//#define AUTH_MODE_DEAUTH 0x04
+//#define AUTH_MODE_UPLAYER 0x05 // reserved for 802.11i use
+
+// BSS Type definitions
+#define BSS_ADHOC 0 // = Ndis802_11IBSS
+#define BSS_INFRA 1 // = Ndis802_11Infrastructure
+#define BSS_ANY 2 // = Ndis802_11AutoUnknown
+#define BSS_MONITOR 3 // = Ndis802_11Monitor
+
+
+// Reason code definitions
+#define REASON_RESERVED 0
+#define REASON_UNSPECIFY 1
+#define REASON_NO_LONGER_VALID 2
+#define REASON_DEAUTH_STA_LEAVING 3
+#define REASON_DISASSOC_INACTIVE 4
+#define REASON_DISASSPC_AP_UNABLE 5
+#define REASON_CLS2ERR 6
+#define REASON_CLS3ERR 7
+#define REASON_DISASSOC_STA_LEAVING 8
+#define REASON_STA_REQ_ASSOC_NOT_AUTH 9
+#define REASON_INVALID_IE 13
+#define REASON_MIC_FAILURE 14
+#define REASON_4_WAY_TIMEOUT 15
+#define REASON_GROUP_KEY_HS_TIMEOUT 16
+#define REASON_IE_DIFFERENT 17
+#define REASON_MCIPHER_NOT_VALID 18
+#define REASON_UCIPHER_NOT_VALID 19
+#define REASON_AKMP_NOT_VALID 20
+#define REASON_UNSUPPORT_RSNE_VER 21
+#define REASON_INVALID_RSNE_CAP 22
+#define REASON_8021X_AUTH_FAIL 23
+#define REASON_CIPHER_SUITE_REJECTED 24
+#define REASON_DECLINED 37
+
+#define REASON_QOS_UNSPECIFY 32
+#define REASON_QOS_LACK_BANDWIDTH 33
+#define REASON_POOR_CHANNEL_CONDITION 34
+#define REASON_QOS_OUTSIDE_TXOP_LIMITION 35
+#define REASON_QOS_QSTA_LEAVING_QBSS 36
+#define REASON_QOS_UNWANTED_MECHANISM 37
+#define REASON_QOS_MECH_SETUP_REQUIRED 38
+#define REASON_QOS_REQUEST_TIMEOUT 39
+#define REASON_QOS_CIPHER_NOT_SUPPORT 45
+
+// Status code definitions
+#define MLME_SUCCESS 0
+#define MLME_UNSPECIFY_FAIL 1
+#define MLME_CANNOT_SUPPORT_CAP 10
+#define MLME_REASSOC_DENY_ASSOC_EXIST 11
+#define MLME_ASSOC_DENY_OUT_SCOPE 12
+#define MLME_ALG_NOT_SUPPORT 13
+#define MLME_SEQ_NR_OUT_OF_SEQUENCE 14
+#define MLME_REJ_CHALLENGE_FAILURE 15
+#define MLME_REJ_TIMEOUT 16
+#define MLME_ASSOC_REJ_UNABLE_HANDLE_STA 17
+#define MLME_ASSOC_REJ_DATA_RATE 18
+
+#define MLME_ASSOC_REJ_NO_EXT_RATE 22
+#define MLME_ASSOC_REJ_NO_EXT_RATE_PBCC 23
+#define MLME_ASSOC_REJ_NO_CCK_OFDM 24
+
+#define MLME_QOS_UNSPECIFY 32
+#define MLME_REQUEST_DECLINED 37
+#define MLME_REQUEST_WITH_INVALID_PARAM 38
+#define MLME_DLS_NOT_ALLOW_IN_QBSS 48
+#define MLME_DEST_STA_NOT_IN_QBSS 49
+#define MLME_DEST_STA_IS_NOT_A_QSTA 50
+
+#define MLME_INVALID_FORMAT 0x51
+#define MLME_FAIL_NO_RESOURCE 0x52
+#define MLME_STATE_MACHINE_REJECT 0x53
+#define MLME_MAC_TABLE_FAIL 0x54
+
+// IE code
+#define IE_SSID 0
+#define IE_SUPP_RATES 1
+#define IE_FH_PARM 2
+#define IE_DS_PARM 3
+#define IE_CF_PARM 4
+#define IE_TIM 5
+#define IE_IBSS_PARM 6
+#define IE_COUNTRY 7 // 802.11d
+#define IE_802_11D_REQUEST 10 // 802.11d
+#define IE_QBSS_LOAD 11 // 802.11e d9
+#define IE_EDCA_PARAMETER 12 // 802.11e d9
+#define IE_TSPEC 13 // 802.11e d9
+#define IE_TCLAS 14 // 802.11e d9
+#define IE_SCHEDULE 15 // 802.11e d9
+#define IE_CHALLENGE_TEXT 16
+#define IE_POWER_CONSTRAINT 32 // 802.11h d3.3
+#define IE_POWER_CAPABILITY 33 // 802.11h d3.3
+#define IE_TPC_REQUEST 34 // 802.11h d3.3
+#define IE_TPC_REPORT 35 // 802.11h d3.3
+#define IE_SUPP_CHANNELS 36 // 802.11h d3.3
+#define IE_CHANNEL_SWITCH_ANNOUNCEMENT 37 // 802.11h d3.3
+#define IE_MEASUREMENT_REQUEST 38 // 802.11h d3.3
+#define IE_MEASUREMENT_REPORT 39 // 802.11h d3.3
+#define IE_QUIET 40 // 802.11h d3.3
+#define IE_IBSS_DFS 41 // 802.11h d3.3
+#define IE_ERP 42 // 802.11g
+#define IE_TS_DELAY 43 // 802.11e d9
+#define IE_TCLAS_PROCESSING 44 // 802.11e d9
+#define IE_QOS_CAPABILITY 46 // 802.11e d6
+#define IE_HT_CAP 45 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
+#define IE_AP_CHANNEL_REPORT 51 // 802.11k d6
+#define IE_HT_CAP2 52 // 802.11n d1. HT CAPABILITY. ELEMENT ID TBD
+#define IE_RSN 48 // 802.11i d3.0
+#define IE_WPA2 48 // WPA2
+#define IE_EXT_SUPP_RATES 50 // 802.11g
+#define IE_SUPP_REG_CLASS 59 // 802.11y. Supported regulatory classes.
+#define IE_EXT_CHANNEL_SWITCH_ANNOUNCEMENT 60 // 802.11n
+#define IE_ADD_HT 61 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
+#define IE_ADD_HT2 53 // 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD
+
+
+// For 802.11n D3.03
+//#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet
+#define IE_SECONDARY_CH_OFFSET 62 // 802.11n D3.03 Secondary Channel Offset element
+#define IE_WAPI 68 // WAPI information element
+#define IE_2040_BSS_COEXIST 72 // 802.11n D3.0.3
+#define IE_2040_BSS_INTOLERANT_REPORT 73 // 802.11n D3.03
+#define IE_OVERLAPBSS_SCAN_PARM 74 // 802.11n D3.03
+#define IE_EXT_CAPABILITY 127 // 802.11n D3.03
+
+
+#define IE_WPA 221 // WPA
+#define IE_VENDOR_SPECIFIC 221 // Wifi WMM (WME)
+
+#define OUI_BROADCOM_HT 51 //
+#define OUI_BROADCOM_HTADD 52 //
+#define OUI_PREN_HT_CAP 51 //
+#define OUI_PREN_ADD_HT 52 //
+
+// CCX information
+#define IE_AIRONET_CKIP 133 // CCX1.0 ID 85H for CKIP
+#define IE_AP_TX_POWER 150 // CCX 2.0 for AP transmit power
+#define IE_MEASUREMENT_CAPABILITY 221 // CCX 2.0
+#define IE_CCX_V2 221
+#define IE_AIRONET_IPADDRESS 149 // CCX ID 95H for IP Address
+#define IE_AIRONET_CCKMREASSOC 156 // CCX ID 9CH for CCKM Reassociation Request element
+#define CKIP_NEGOTIATION_LENGTH 30
+#define AIRONET_IPADDRESS_LENGTH 10
+#define AIRONET_CCKMREASSOC_LENGTH 24
+
+// ========================================================
+// MLME state machine definition
+// ========================================================
+
+// STA MLME state mahcines
+#define ASSOC_STATE_MACHINE 1
+#define AUTH_STATE_MACHINE 2
+#define AUTH_RSP_STATE_MACHINE 3
+#define SYNC_STATE_MACHINE 4
+#define MLME_CNTL_STATE_MACHINE 5
+#define WPA_PSK_STATE_MACHINE 6
+#define LEAP_STATE_MACHINE 7
+#define AIRONET_STATE_MACHINE 8
+#define ACTION_STATE_MACHINE 9
+
+// AP MLME state machines
+#define AP_ASSOC_STATE_MACHINE 11
+#define AP_AUTH_STATE_MACHINE 12
+#define AP_AUTH_RSP_STATE_MACHINE 13
+#define AP_SYNC_STATE_MACHINE 14
+#define AP_CNTL_STATE_MACHINE 15
+#define AP_WPA_STATE_MACHINE 16
+
+#define WSC_STATE_MACHINE 17
+#define WSC_UPNP_STATE_MACHINE 18
+
+
+
+#ifdef QOS_DLS_SUPPORT
+#define DLS_STATE_MACHINE 26
+#endif // QOS_DLS_SUPPORT //
+
+//
+// STA's CONTROL/CONNECT state machine: states, events, total function #
+//
+#define CNTL_IDLE 0
+#define CNTL_WAIT_DISASSOC 1
+#define CNTL_WAIT_JOIN 2
+#define CNTL_WAIT_REASSOC 3
+#define CNTL_WAIT_START 4
+#define CNTL_WAIT_AUTH 5
+#define CNTL_WAIT_ASSOC 6
+#define CNTL_WAIT_AUTH2 7
+#define CNTL_WAIT_OID_LIST_SCAN 8
+#define CNTL_WAIT_OID_DISASSOC 9
+#ifdef RT2870
+#define CNTL_WAIT_SCAN_FOR_CONNECT 10
+#endif // RT2870 //
+
+#define MT2_ASSOC_CONF 34
+#define MT2_AUTH_CONF 35
+#define MT2_DEAUTH_CONF 36
+#define MT2_DISASSOC_CONF 37
+#define MT2_REASSOC_CONF 38
+#define MT2_PWR_MGMT_CONF 39
+#define MT2_JOIN_CONF 40
+#define MT2_SCAN_CONF 41
+#define MT2_START_CONF 42
+#define MT2_GET_CONF 43
+#define MT2_SET_CONF 44
+#define MT2_RESET_CONF 45
+#define MT2_MLME_ROAMING_REQ 52
+
+#define CNTL_FUNC_SIZE 1
+
+//
+// STA's ASSOC state machine: states, events, total function #
+//
+#define ASSOC_IDLE 0
+#define ASSOC_WAIT_RSP 1
+#define REASSOC_WAIT_RSP 2
+#define DISASSOC_WAIT_RSP 3
+#define MAX_ASSOC_STATE 4
+
+#define ASSOC_MACHINE_BASE 0
+#define MT2_MLME_ASSOC_REQ 0
+#define MT2_MLME_REASSOC_REQ 1
+#define MT2_MLME_DISASSOC_REQ 2
+#define MT2_PEER_DISASSOC_REQ 3
+#define MT2_PEER_ASSOC_REQ 4
+#define MT2_PEER_ASSOC_RSP 5
+#define MT2_PEER_REASSOC_REQ 6
+#define MT2_PEER_REASSOC_RSP 7
+#define MT2_DISASSOC_TIMEOUT 8
+#define MT2_ASSOC_TIMEOUT 9
+#define MT2_REASSOC_TIMEOUT 10
+#define MAX_ASSOC_MSG 11
+
+#define ASSOC_FUNC_SIZE (MAX_ASSOC_STATE * MAX_ASSOC_MSG)
+
+//
+// ACT state machine: states, events, total function #
+//
+#define ACT_IDLE 0
+#define MAX_ACT_STATE 1
+
+#define ACT_MACHINE_BASE 0
+
+//Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self.
+//Category
+#define MT2_PEER_SPECTRUM_CATE 0
+#define MT2_PEER_QOS_CATE 1
+#define MT2_PEER_DLS_CATE 2
+#define MT2_PEER_BA_CATE 3
+#define MT2_PEER_PUBLIC_CATE 4
+#define MT2_PEER_RM_CATE 5
+#define MT2_PEER_HT_CATE 7 // 7.4.7
+#define MAX_PEER_CATE_MSG 7
+#define MT2_MLME_ADD_BA_CATE 8
+#define MT2_MLME_ORI_DELBA_CATE 9
+#define MT2_MLME_REC_DELBA_CATE 10
+#define MT2_MLME_QOS_CATE 11
+#define MT2_MLME_DLS_CATE 12
+#define MT2_ACT_INVALID 13
+#define MAX_ACT_MSG 14
+
+//Category field
+#define CATEGORY_SPECTRUM 0
+#define CATEGORY_QOS 1
+#define CATEGORY_DLS 2
+#define CATEGORY_BA 3
+#define CATEGORY_PUBLIC 4
+#define CATEGORY_RM 5
+#define CATEGORY_HT 7
+
+
+// DLS Action frame definition
+#define ACTION_DLS_REQUEST 0
+#define ACTION_DLS_RESPONSE 1
+#define ACTION_DLS_TEARDOWN 2
+
+//Spectrum Action field value 802.11h 7.4.1
+#define SPEC_MRQ 0 // Request
+#define SPEC_MRP 1 //Report
+#define SPEC_TPCRQ 2
+#define SPEC_TPCRP 3
+#define SPEC_CHANNEL_SWITCH 4
+
+
+//BA Action field value
+#define ADDBA_REQ 0
+#define ADDBA_RESP 1
+#define DELBA 2
+
+//Public's Action field value in Public Category. Some in 802.11y and some in 11n
+#define ACTION_BSS_2040_COEXIST 0 // 11n
+#define ACTION_DSE_ENABLEMENT 1 // 11y D9.0
+#define ACTION_DSE_DEENABLEMENT 2 // 11y D9.0
+#define ACTION_DSE_REG_LOCATION_ANNOUNCE 3 // 11y D9.0
+#define ACTION_EXT_CH_SWITCH_ANNOUNCE 4 // 11y D9.0
+#define ACTION_DSE_MEASUREMENT_REQ 5 // 11y D9.0
+#define ACTION_DSE_MEASUREMENT_REPORT 6 // 11y D9.0
+#define ACTION_MEASUREMENT_PILOT_ACTION 7 // 11y D9.0
+#define ACTION_DSE_POWER_CONSTRAINT 8 // 11y D9.0
+
+
+//HT Action field value
+#define NOTIFY_BW_ACTION 0
+#define SMPS_ACTION 1
+#define PSMP_ACTION 2
+#define SETPCO_ACTION 3
+#define MIMO_CHA_MEASURE_ACTION 4
+#define MIMO_N_BEACONFORM 5
+#define MIMO_BEACONFORM 6
+#define ANTENNA_SELECT 7
+#define HT_INFO_EXCHANGE 8
+
+#define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG)
+//
+// STA's AUTHENTICATION state machine: states, evvents, total function #
+//
+#define AUTH_REQ_IDLE 0
+#define AUTH_WAIT_SEQ2 1
+#define AUTH_WAIT_SEQ4 2
+#define MAX_AUTH_STATE 3
+
+#define AUTH_MACHINE_BASE 0
+#define MT2_MLME_AUTH_REQ 0
+#define MT2_PEER_AUTH_EVEN 1
+#define MT2_AUTH_TIMEOUT 2
+#define MAX_AUTH_MSG 3
+
+#define AUTH_FUNC_SIZE (MAX_AUTH_STATE * MAX_AUTH_MSG)
+
+//
+// STA's AUTH_RSP state machine: states, events, total function #
+//
+#define AUTH_RSP_IDLE 0
+#define AUTH_RSP_WAIT_CHAL 1
+#define MAX_AUTH_RSP_STATE 2
+
+#define AUTH_RSP_MACHINE_BASE 0
+#define MT2_AUTH_CHALLENGE_TIMEOUT 0
+#define MT2_PEER_AUTH_ODD 1
+#define MT2_PEER_DEAUTH 2
+#define MAX_AUTH_RSP_MSG 3
+
+#define AUTH_RSP_FUNC_SIZE (MAX_AUTH_RSP_STATE * MAX_AUTH_RSP_MSG)
+
+//
+// STA's SYNC state machine: states, events, total function #
+//
+#define SYNC_IDLE 0 // merge NO_BSS,IBSS_IDLE,IBSS_ACTIVE and BSS in to 1 state
+#define JOIN_WAIT_BEACON 1
+#define SCAN_LISTEN 2
+#define MAX_SYNC_STATE 3
+
+#define SYNC_MACHINE_BASE 0
+#define MT2_MLME_SCAN_REQ 0
+#define MT2_MLME_JOIN_REQ 1
+#define MT2_MLME_START_REQ 2
+#define MT2_PEER_BEACON 3
+#define MT2_PEER_PROBE_RSP 4
+#define MT2_PEER_ATIM 5
+#define MT2_SCAN_TIMEOUT 6
+#define MT2_BEACON_TIMEOUT 7
+#define MT2_ATIM_TIMEOUT 8
+#define MT2_PEER_PROBE_REQ 9
+#define MAX_SYNC_MSG 10
+
+#define SYNC_FUNC_SIZE (MAX_SYNC_STATE * MAX_SYNC_MSG)
+
+//Messages for the DLS state machine
+#define DLS_IDLE 0
+#define MAX_DLS_STATE 1
+
+#define DLS_MACHINE_BASE 0
+#define MT2_MLME_DLS_REQ 0
+#define MT2_PEER_DLS_REQ 1
+#define MT2_PEER_DLS_RSP 2
+#define MT2_MLME_DLS_TEAR_DOWN 3
+#define MT2_PEER_DLS_TEAR_DOWN 4
+#define MAX_DLS_MSG 5
+
+#define DLS_FUNC_SIZE (MAX_DLS_STATE * MAX_DLS_MSG)
+
+//
+// STA's WPA-PSK State machine: states, events, total function #
+//
+#define WPA_PSK_IDLE 0
+#define MAX_WPA_PSK_STATE 1
+
+#define WPA_MACHINE_BASE 0
+#define MT2_EAPPacket 0
+#define MT2_EAPOLStart 1
+#define MT2_EAPOLLogoff 2
+#define MT2_EAPOLKey 3
+#define MT2_EAPOLASFAlert 4
+#define MAX_WPA_PSK_MSG 5
+
+#define WPA_PSK_FUNC_SIZE (MAX_WPA_PSK_STATE * MAX_WPA_PSK_MSG)
+
+//
+// STA's CISCO-AIRONET State machine: states, events, total function #
+//
+#define AIRONET_IDLE 0
+#define AIRONET_SCANNING 1
+#define MAX_AIRONET_STATE 2
+
+#define AIRONET_MACHINE_BASE 0
+#define MT2_AIRONET_MSG 0
+#define MT2_AIRONET_SCAN_REQ 1
+#define MT2_AIRONET_SCAN_DONE 2
+#define MAX_AIRONET_MSG 3
+
+#define AIRONET_FUNC_SIZE (MAX_AIRONET_STATE * MAX_AIRONET_MSG)
+
+//
+// WSC State machine: states, events, total function #
+//
+
+//
+// AP's CONTROL/CONNECT state machine: states, events, total function #
+//
+#define AP_CNTL_FUNC_SIZE 1
+
+//
+// AP's ASSOC state machine: states, events, total function #
+//
+#define AP_ASSOC_IDLE 0
+#define AP_MAX_ASSOC_STATE 1
+
+#define AP_ASSOC_MACHINE_BASE 0
+#define APMT2_MLME_DISASSOC_REQ 0
+#define APMT2_PEER_DISASSOC_REQ 1
+#define APMT2_PEER_ASSOC_REQ 2
+#define APMT2_PEER_REASSOC_REQ 3
+#define APMT2_CLS3ERR 4
+#define AP_MAX_ASSOC_MSG 5
+
+#define AP_ASSOC_FUNC_SIZE (AP_MAX_ASSOC_STATE * AP_MAX_ASSOC_MSG)
+
+//
+// AP's AUTHENTICATION state machine: states, events, total function #
+//
+#define AP_AUTH_REQ_IDLE 0
+#define AP_MAX_AUTH_STATE 1
+
+#define AP_AUTH_MACHINE_BASE 0
+#define APMT2_MLME_DEAUTH_REQ 0
+#define APMT2_CLS2ERR 1
+#define AP_MAX_AUTH_MSG 2
+
+#define AP_AUTH_FUNC_SIZE (AP_MAX_AUTH_STATE * AP_MAX_AUTH_MSG)
+
+//
+// AP's AUTH-RSP state machine: states, events, total function #
+//
+#define AP_AUTH_RSP_IDLE 0
+#define AP_MAX_AUTH_RSP_STATE 1
+
+#define AP_AUTH_RSP_MACHINE_BASE 0
+#define APMT2_AUTH_CHALLENGE_TIMEOUT 0
+#define APMT2_PEER_AUTH_ODD 1
+#define APMT2_PEER_DEAUTH 2
+#define AP_MAX_AUTH_RSP_MSG 3
+
+#define AP_AUTH_RSP_FUNC_SIZE (AP_MAX_AUTH_RSP_STATE * AP_MAX_AUTH_RSP_MSG)
+
+//
+// AP's SYNC state machine: states, events, total function #
+//
+#define AP_SYNC_IDLE 0
+#define AP_SCAN_LISTEN 1
+#define AP_MAX_SYNC_STATE 2
+
+#define AP_SYNC_MACHINE_BASE 0
+#define APMT2_PEER_PROBE_REQ 0
+#define APMT2_PEER_BEACON 1
+#define APMT2_MLME_SCAN_REQ 2
+#define APMT2_PEER_PROBE_RSP 3
+#define APMT2_SCAN_TIMEOUT 4
+#define APMT2_MLME_SCAN_CNCL 5
+#define AP_MAX_SYNC_MSG 6
+
+#define AP_SYNC_FUNC_SIZE (AP_MAX_SYNC_STATE * AP_MAX_SYNC_MSG)
+
+//
+// AP's WPA state machine: states, events, total function #
+//
+#define AP_WPA_PTK 0
+#define AP_MAX_WPA_PTK_STATE 1
+
+#define AP_WPA_MACHINE_BASE 0
+#define APMT2_EAPPacket 0
+#define APMT2_EAPOLStart 1
+#define APMT2_EAPOLLogoff 2
+#define APMT2_EAPOLKey 3
+#define APMT2_EAPOLASFAlert 4
+#define AP_MAX_WPA_MSG 5
+
+#define AP_WPA_FUNC_SIZE (AP_MAX_WPA_PTK_STATE * AP_MAX_WPA_MSG)
+
+
+
+// =============================================================================
+
+// value domain of 802.11 header FC.Tyte, which is b3..b2 of the 1st-byte of MAC header
+#define BTYPE_MGMT 0
+#define BTYPE_CNTL 1
+#define BTYPE_DATA 2
+
+// value domain of 802.11 MGMT frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_ASSOC_REQ 0
+#define SUBTYPE_ASSOC_RSP 1
+#define SUBTYPE_REASSOC_REQ 2
+#define SUBTYPE_REASSOC_RSP 3
+#define SUBTYPE_PROBE_REQ 4
+#define SUBTYPE_PROBE_RSP 5
+#define SUBTYPE_BEACON 8
+#define SUBTYPE_ATIM 9
+#define SUBTYPE_DISASSOC 10
+#define SUBTYPE_AUTH 11
+#define SUBTYPE_DEAUTH 12
+#define SUBTYPE_ACTION 13
+#define SUBTYPE_ACTION_NO_ACK 14
+
+// value domain of 802.11 CNTL frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_WRAPPER 7
+#define SUBTYPE_BLOCK_ACK_REQ 8
+#define SUBTYPE_BLOCK_ACK 9
+#define SUBTYPE_PS_POLL 10
+#define SUBTYPE_RTS 11
+#define SUBTYPE_CTS 12
+#define SUBTYPE_ACK 13
+#define SUBTYPE_CFEND 14
+#define SUBTYPE_CFEND_CFACK 15
+
+// value domain of 802.11 DATA frame's FC.subtype, which is b7..4 of the 1st-byte of MAC header
+#define SUBTYPE_DATA 0
+#define SUBTYPE_DATA_CFACK 1
+#define SUBTYPE_DATA_CFPOLL 2
+#define SUBTYPE_DATA_CFACK_CFPOLL 3
+#define SUBTYPE_NULL_FUNC 4
+#define SUBTYPE_CFACK 5
+#define SUBTYPE_CFPOLL 6
+#define SUBTYPE_CFACK_CFPOLL 7
+#define SUBTYPE_QDATA 8
+#define SUBTYPE_QDATA_CFACK 9
+#define SUBTYPE_QDATA_CFPOLL 10
+#define SUBTYPE_QDATA_CFACK_CFPOLL 11
+#define SUBTYPE_QOS_NULL 12
+#define SUBTYPE_QOS_CFACK 13
+#define SUBTYPE_QOS_CFPOLL 14
+#define SUBTYPE_QOS_CFACK_CFPOLL 15
+
+// ACK policy of QOS Control field bit 6:5
+#define NORMAL_ACK 0x00 // b6:5 = 00
+#define NO_ACK 0x20 // b6:5 = 01
+#define NO_EXPLICIT_ACK 0x40 // b6:5 = 10
+#define BLOCK_ACK 0x60 // b6:5 = 11
+
+//
+// rtmp_data.c use these definition
+//
+#define LENGTH_802_11 24
+#define LENGTH_802_11_AND_H 30
+#define LENGTH_802_11_CRC_H 34
+#define LENGTH_802_11_CRC 28
+#define LENGTH_802_11_WITH_ADDR4 30
+#define LENGTH_802_3 14
+#define LENGTH_802_3_TYPE 2
+#define LENGTH_802_1_H 8
+#define LENGTH_EAPOL_H 4
+#define LENGTH_WMMQOS_H 2
+#define LENGTH_CRC 4
+#define MAX_SEQ_NUMBER 0x0fff
+#define LENGTH_802_3_NO_TYPE 12
+#define LENGTH_802_1Q 4 /* VLAN related */
+
+// STA_CSR4.field.TxResult
+#define TX_RESULT_SUCCESS 0
+#define TX_RESULT_ZERO_LENGTH 1
+#define TX_RESULT_UNDER_RUN 2
+#define TX_RESULT_OHY_ERROR 4
+#define TX_RESULT_RETRY_FAIL 6
+
+// All PHY rate summary in TXD
+// Preamble MODE in TxD
+#define MODE_CCK 0
+#define MODE_OFDM 1
+#ifdef DOT11_N_SUPPORT
+#define MODE_HTMIX 2
+#define MODE_HTGREENFIELD 3
+#endif // DOT11_N_SUPPORT //
+// MCS for CCK. BW.SGI.STBC are reserved
+#define MCS_LONGP_RATE_1 0 // long preamble CCK 1Mbps
+#define MCS_LONGP_RATE_2 1 // long preamble CCK 1Mbps
+#define MCS_LONGP_RATE_5_5 2
+#define MCS_LONGP_RATE_11 3
+#define MCS_SHORTP_RATE_1 4 // long preamble CCK 1Mbps. short is forbidden in 1Mbps
+#define MCS_SHORTP_RATE_2 5 // short preamble CCK 2Mbps
+#define MCS_SHORTP_RATE_5_5 6
+#define MCS_SHORTP_RATE_11 7
+// To send duplicate legacy OFDM. set BW=BW_40. SGI.STBC are reserved
+#define MCS_RATE_6 0 // legacy OFDM
+#define MCS_RATE_9 1 // OFDM
+#define MCS_RATE_12 2 // OFDM
+#define MCS_RATE_18 3 // OFDM
+#define MCS_RATE_24 4 // OFDM
+#define MCS_RATE_36 5 // OFDM
+#define MCS_RATE_48 6 // OFDM
+#define MCS_RATE_54 7 // OFDM
+// HT
+#define MCS_0 0 // 1S
+#define MCS_1 1
+#define MCS_2 2
+#define MCS_3 3
+#define MCS_4 4
+#define MCS_5 5
+#define MCS_6 6
+#define MCS_7 7
+#define MCS_8 8 // 2S
+#define MCS_9 9
+#define MCS_10 10
+#define MCS_11 11
+#define MCS_12 12
+#define MCS_13 13
+#define MCS_14 14
+#define MCS_15 15
+#define MCS_16 16 // 3*3
+#define MCS_17 17
+#define MCS_18 18
+#define MCS_19 19
+#define MCS_20 20
+#define MCS_21 21
+#define MCS_22 22
+#define MCS_23 23
+#define MCS_32 32
+#define MCS_AUTO 33
+
+#ifdef DOT11_N_SUPPORT
+// OID_HTPHYMODE
+// MODE
+#define HTMODE_MM 0
+#define HTMODE_GF 1
+#endif // DOT11_N_SUPPORT //
+
+// Fixed Tx MODE - HT, CCK or OFDM
+#define FIXED_TXMODE_HT 0
+#define FIXED_TXMODE_CCK 1
+#define FIXED_TXMODE_OFDM 2
+// BW
+#define BW_20 BAND_WIDTH_20
+#define BW_40 BAND_WIDTH_40
+#define BW_BOTH BAND_WIDTH_BOTH
+#define BW_10 BAND_WIDTH_10 // 802.11j has 10MHz. This definition is for internal usage. doesn't fill in the IE or other field.
+
+#ifdef DOT11_N_SUPPORT
+// SHORTGI
+#define GI_400 GAP_INTERVAL_400 // only support in HT mode
+#define GI_BOTH GAP_INTERVAL_BOTH
+#endif // DOT11_N_SUPPORT //
+#define GI_800 GAP_INTERVAL_800
+// STBC
+#define STBC_NONE 0
+#ifdef DOT11_N_SUPPORT
+#define STBC_USE 1 // limited use in rt2860b phy
+#define RXSTBC_ONE 1 // rx support of one spatial stream
+#define RXSTBC_TWO 2 // rx support of 1 and 2 spatial stream
+#define RXSTBC_THR 3 // rx support of 1~3 spatial stream
+// MCS FEEDBACK
+#define MCSFBK_NONE 0 // not support mcs feedback /
+#define MCSFBK_RSV 1 // reserved
+#define MCSFBK_UNSOLICIT 2 // only support unsolict mcs feedback
+#define MCSFBK_MRQ 3 // response to both MRQ and unsolict mcs feedback
+
+// MIMO power safe
+#define MMPS_STATIC 0
+#define MMPS_DYNAMIC 1
+#define MMPS_RSV 2
+#define MMPS_ENABLE 3
+
+
+// A-MSDU size
+#define AMSDU_0 0
+#define AMSDU_1 1
+
+#endif // DOT11_N_SUPPORT //
+
+// MCS use 7 bits
+#define TXRATEMIMO 0x80
+#define TXRATEMCS 0x7F
+#define TXRATEOFDM 0x7F
+#define RATE_1 0
+#define RATE_2 1
+#define RATE_5_5 2
+#define RATE_11 3
+#define RATE_6 4 // OFDM
+#define RATE_9 5 // OFDM
+#define RATE_12 6 // OFDM
+#define RATE_18 7 // OFDM
+#define RATE_24 8 // OFDM
+#define RATE_36 9 // OFDM
+#define RATE_48 10 // OFDM
+#define RATE_54 11 // OFDM
+#define RATE_FIRST_OFDM_RATE RATE_6
+#define RATE_LAST_OFDM_RATE RATE_54
+#define RATE_6_5 12 // HT mix
+#define RATE_13 13 // HT mix
+#define RATE_19_5 14 // HT mix
+#define RATE_26 15 // HT mix
+#define RATE_39 16 // HT mix
+#define RATE_52 17 // HT mix
+#define RATE_58_5 18 // HT mix
+#define RATE_65 19 // HT mix
+#define RATE_78 20 // HT mix
+#define RATE_104 21 // HT mix
+#define RATE_117 22 // HT mix
+#define RATE_130 23 // HT mix
+//#define RATE_AUTO_SWITCH 255 // for StaCfg.FixedTxRate only
+#define HTRATE_0 12
+#define RATE_FIRST_MM_RATE HTRATE_0
+#define RATE_FIRST_HT_RATE HTRATE_0
+#define RATE_LAST_HT_RATE HTRATE_0
+
+// pTxWI->txop
+#define IFS_HTTXOP 0 // The txop will be handles by ASIC.
+#define IFS_PIFS 1
+#define IFS_SIFS 2
+#define IFS_BACKOFF 3
+
+// pTxD->RetryMode
+#define LONG_RETRY 1
+#define SHORT_RETRY 0
+
+// Country Region definition
+#define REGION_MINIMUM_BG_BAND 0
+#define REGION_0_BG_BAND 0 // 1-11
+#define REGION_1_BG_BAND 1 // 1-13
+#define REGION_2_BG_BAND 2 // 10-11
+#define REGION_3_BG_BAND 3 // 10-13
+#define REGION_4_BG_BAND 4 // 14
+#define REGION_5_BG_BAND 5 // 1-14
+#define REGION_6_BG_BAND 6 // 3-9
+#define REGION_7_BG_BAND 7 // 5-13
+#define REGION_31_BG_BAND 31 // 5-13
+#define REGION_MAXIMUM_BG_BAND 7
+
+#define REGION_MINIMUM_A_BAND 0
+#define REGION_0_A_BAND 0 // 36, 40, 44, 48, 52, 56, 60, 64, 149, 153, 157, 161, 165
+#define REGION_1_A_BAND 1 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
+#define REGION_2_A_BAND 2 // 36, 40, 44, 48, 52, 56, 60, 64
+#define REGION_3_A_BAND 3 // 52, 56, 60, 64, 149, 153, 157, 161
+#define REGION_4_A_BAND 4 // 149, 153, 157, 161, 165
+#define REGION_5_A_BAND 5 // 149, 153, 157, 161
+#define REGION_6_A_BAND 6 // 36, 40, 44, 48
+#define REGION_7_A_BAND 7 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 149, 153, 157, 161, 165
+#define REGION_8_A_BAND 8 // 52, 56, 60, 64
+#define REGION_9_A_BAND 9 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 132, 136, 140, 149, 153, 157, 161, 165
+#define REGION_10_A_BAND 10 // 36, 40, 44, 48, 149, 153, 157, 161, 165
+#define REGION_11_A_BAND 11 // 36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 149, 153, 157, 161
+#define REGION_MAXIMUM_A_BAND 11
+
+// pTxD->CipherAlg
+#define CIPHER_NONE 0
+#define CIPHER_WEP64 1
+#define CIPHER_WEP128 2
+#define CIPHER_TKIP 3
+#define CIPHER_AES 4
+#define CIPHER_CKIP64 5
+#define CIPHER_CKIP128 6
+#define CIPHER_TKIP_NO_MIC 7 // MIC appended by driver: not a valid value in hardware key table
+#define CIPHER_SMS4 8
+
+// value domain of pAd->RfIcType
+#define RFIC_2820 1 // 2.4G 2T3R
+#define RFIC_2850 2 // 2.4G/5G 2T3R
+#define RFIC_2720 3 // 2.4G 1T2R
+#define RFIC_2750 4 // 2.4G/5G 1T2R
+#define RFIC_3020 5 // 2.4G 1T1R
+#define RFIC_2020 6 // 2.4G B/G
+#define RFIC_3021 7 // 2.4G 1T2R
+#define RFIC_3022 8 // 2.4G 2T2R
+
+// LED Status.
+#define LED_LINK_DOWN 0
+#define LED_LINK_UP 1
+#define LED_RADIO_OFF 2
+#define LED_RADIO_ON 3
+#define LED_HALT 4
+#define LED_WPS 5
+#define LED_ON_SITE_SURVEY 6
+#define LED_POWER_UP 7
+
+// value domain of pAd->LedCntl.LedMode and E2PROM
+#define LED_MODE_DEFAULT 0
+#define LED_MODE_TWO_LED 1
+#define LED_MODE_SIGNAL_STREGTH 8 // EEPROM define =8
+
+// RC4 init value, used fro WEP & TKIP
+#define PPPINITFCS32 0xffffffff /* Initial FCS value */
+
+// value domain of pAd->StaCfg.PortSecured. 802.1X controlled port definition
+#define WPA_802_1X_PORT_SECURED 1
+#define WPA_802_1X_PORT_NOT_SECURED 2
+
+#define PAIRWISE_KEY 1
+#define GROUP_KEY 2
+
+//definition of DRS
+#define MAX_STEP_OF_TX_RATE_SWITCH 32
+
+
+// pre-allocated free NDIS PACKET/BUFFER poll for internal usage
+#define MAX_NUM_OF_FREE_NDIS_PACKET 128
+
+//Block ACK
+#define MAX_TX_REORDERBUF 64
+#define MAX_RX_REORDERBUF 64
+#define DEFAULT_TX_TIMEOUT 30
+#define DEFAULT_RX_TIMEOUT 30
+
+// definition of Recipient or Originator
+#define I_RECIPIENT TRUE
+#define I_ORIGINATOR FALSE
+
+#define DEFAULT_BBP_TX_POWER 0
+#define DEFAULT_RF_TX_POWER 5
+
+#define MAX_INI_BUFFER_SIZE 4096
+#define MAX_PARAM_BUFFER_SIZE (2048) // enough for ACL (18*64)
+ //18 : the length of Mac address acceptable format "01:02:03:04:05:06;")
+ //64 : MAX_NUM_OF_ACL_LIST
+// definition of pAd->OpMode
+#define OPMODE_STA 0
+#define OPMODE_AP 1
+//#define OPMODE_L3_BRG 2 // as AP and STA at the same time
+
+#ifdef RT_BIG_ENDIAN
+#define DIR_READ 0
+#define DIR_WRITE 1
+#define TYPE_TXD 0
+#define TYPE_RXD 1
+#define TYPE_TXINFO 0
+#define TYPE_RXINFO 1
+#define TYPE_TXWI 0
+#define TYPE_RXWI 1
+#endif
+
+// ========================= AP rtmp_def.h ===========================
+// value domain for pAd->EventTab.Log[].Event
+#define EVENT_RESET_ACCESS_POINT 0 // Log = "hh:mm:ss Restart Access Point"
+#define EVENT_ASSOCIATED 1 // Log = "hh:mm:ss STA 00:01:02:03:04:05 associated"
+#define EVENT_DISASSOCIATED 2 // Log = "hh:mm:ss STA 00:01:02:03:04:05 left this BSS"
+#define EVENT_AGED_OUT 3 // Log = "hh:mm:ss STA 00:01:02:03:04:05 was aged-out and removed from this BSS"
+#define EVENT_COUNTER_M 4
+#define EVENT_INVALID_PSK 5
+#define EVENT_MAX_EVENT_TYPE 6
+// ==== end of AP rtmp_def.h ============
+
+// definition RSSI Number
+#define RSSI_0 0
+#define RSSI_1 1
+#define RSSI_2 2
+
+// definition of radar detection
+#define RD_NORMAL_MODE 0 // Not found radar signal
+#define RD_SWITCHING_MODE 1 // Found radar signal, and doing channel switch
+#define RD_SILENCE_MODE 2 // After channel switch, need to be silence a while to ensure radar not found
+
+//Driver defined cid for mapping status and command.
+#define SLEEPCID 0x11
+#define WAKECID 0x22
+#define QUERYPOWERCID 0x33
+#define OWNERMCU 0x1
+#define OWNERCPU 0x0
+
+// MBSSID definition
+#define ENTRY_NOT_FOUND 0xFF
+
+
+/* After Linux 2.6.9,
+ * VLAN module use Private (from user) interface flags (netdevice->priv_flags).
+ * #define IFF_802_1Q_VLAN 0x1 -- 802.1Q VLAN device. in if.h
+ * ref to ip_sabotage_out() [ out->priv_flags & IFF_802_1Q_VLAN ] in br_netfilter.c
+ *
+ * For this reason, we MUST use EVEN value in priv_flags
+ */
+#define INT_MAIN 0x0100
+#define INT_MBSSID 0x0200
+#define INT_WDS 0x0300
+#define INT_APCLI 0x0400
+#define INT_MESH 0x0500
+
+// Use bitmap to allow coexist of ATE_TXFRAME and ATE_RXFRAME(i.e.,to support LoopBack mode)
+#ifdef RALINK_ATE
+#define ATE_START 0x00 // Start ATE
+#define ATE_STOP 0x80 // Stop ATE
+#define ATE_TXCONT 0x05 // Continuous Transmit
+#define ATE_TXCARR 0x09 // Transmit Carrier
+#define ATE_TXCARRSUPP 0x11 // Transmit Carrier Suppression
+#define ATE_TXFRAME 0x01 // Transmit Frames
+#define ATE_RXFRAME 0x02 // Receive Frames
+#ifdef RALINK_28xx_QA
+#define ATE_TXSTOP 0xe2 // Stop Transmition(i.e., TXCONT, TXCARR, TXCARRSUPP, and TXFRAME)
+#define ATE_RXSTOP 0xfd // Stop receiving Frames
+#define BBP22_TXFRAME 0x00 // Transmit Frames
+#define BBP22_TXCONT_OR_CARRSUPP 0x80 // Continuous Transmit or Carrier Suppression
+#define BBP22_TXCARR 0xc1 // Transmit Carrier
+#define BBP24_TXCONT 0x00 // Continuous Transmit
+#define BBP24_CARRSUPP 0x01 // Carrier Suppression
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+// WEP Key TYPE
+#define WEP_HEXADECIMAL_TYPE 0
+#define WEP_ASCII_TYPE 1
+
+
+
+// WIRELESS EVENTS definition
+/* Max number of char in custom event, refer to wireless_tools.28/wireless.20.h */
+#define IW_CUSTOM_MAX_LEN 255 /* In bytes */
+
+// For system event - start
+#define IW_SYS_EVENT_FLAG_START 0x0200
+#define IW_ASSOC_EVENT_FLAG 0x0200
+#define IW_DISASSOC_EVENT_FLAG 0x0201
+#define IW_DEAUTH_EVENT_FLAG 0x0202
+#define IW_AGEOUT_EVENT_FLAG 0x0203
+#define IW_COUNTER_MEASURES_EVENT_FLAG 0x0204
+#define IW_REPLAY_COUNTER_DIFF_EVENT_FLAG 0x0205
+#define IW_RSNIE_DIFF_EVENT_FLAG 0x0206
+#define IW_MIC_DIFF_EVENT_FLAG 0x0207
+#define IW_ICV_ERROR_EVENT_FLAG 0x0208
+#define IW_MIC_ERROR_EVENT_FLAG 0x0209
+#define IW_GROUP_HS_TIMEOUT_EVENT_FLAG 0x020A
+#define IW_PAIRWISE_HS_TIMEOUT_EVENT_FLAG 0x020B
+#define IW_RSNIE_SANITY_FAIL_EVENT_FLAG 0x020C
+#define IW_SET_KEY_DONE_WPA1_EVENT_FLAG 0x020D
+#define IW_SET_KEY_DONE_WPA2_EVENT_FLAG 0x020E
+#define IW_STA_LINKUP_EVENT_FLAG 0x020F
+#define IW_STA_LINKDOWN_EVENT_FLAG 0x0210
+#define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211
+#define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212
+// if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END
+#define IW_SYS_EVENT_FLAG_END 0x0212
+#define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1)
+// For system event - end
+
+// For spoof attack event - start
+#define IW_SPOOF_EVENT_FLAG_START 0x0300
+#define IW_CONFLICT_SSID_EVENT_FLAG 0x0300
+#define IW_SPOOF_ASSOC_RESP_EVENT_FLAG 0x0301
+#define IW_SPOOF_REASSOC_RESP_EVENT_FLAG 0x0302
+#define IW_SPOOF_PROBE_RESP_EVENT_FLAG 0x0303
+#define IW_SPOOF_BEACON_EVENT_FLAG 0x0304
+#define IW_SPOOF_DISASSOC_EVENT_FLAG 0x0305
+#define IW_SPOOF_AUTH_EVENT_FLAG 0x0306
+#define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307
+#define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308
+#define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309
+// if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END
+#define IW_SPOOF_EVENT_FLAG_END 0x0309
+#define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1)
+// For spoof attack event - end
+
+// For flooding attack event - start
+#define IW_FLOOD_EVENT_FLAG_START 0x0400
+#define IW_FLOOD_AUTH_EVENT_FLAG 0x0400
+#define IW_FLOOD_ASSOC_REQ_EVENT_FLAG 0x0401
+#define IW_FLOOD_REASSOC_REQ_EVENT_FLAG 0x0402
+#define IW_FLOOD_PROBE_REQ_EVENT_FLAG 0x0403
+#define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404
+#define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405
+#define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406
+// if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END
+#define IW_FLOOD_EVENT_FLAG_END 0x0406
+#define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1)
+// For flooding attack - end
+
+// End - WIRELESS EVENTS definition
+
+#ifdef CONFIG_STA_SUPPORT
+// definition for DLS, kathy
+#define MAX_NUM_OF_INIT_DLS_ENTRY 1
+#define MAX_NUM_OF_DLS_ENTRY MAX_NUMBER_OF_DLS_ENTRY
+
+//Block ACK , rt2860, kathy
+#define MAX_TX_REORDERBUF 64
+#define MAX_RX_REORDERBUF 64
+#define DEFAULT_TX_TIMEOUT 30
+#define DEFAULT_RX_TIMEOUT 30
+#ifndef CONFIG_AP_SUPPORT
+#define MAX_BARECI_SESSION 8
+#endif
+
+#ifndef IW_ESSID_MAX_SIZE
+/* Maximum size of the ESSID and pAd->nickname strings */
+#define IW_ESSID_MAX_SIZE 32
+#endif
+#endif // CONFIG_STA_SUPPORT //
+
+#ifdef MCAST_RATE_SPECIFIC
+#define MCAST_DISABLE 0
+#define MCAST_CCK 1
+#define MCAST_OFDM 2
+#define MCAST_HTMIX 3
+#endif // MCAST_RATE_SPECIFIC //
+
+// For AsicRadioOff/AsicRadioOn function
+#define DOT11POWERSAVE 0
+#define GUIRADIO_OFF 1
+#define RTMP_HALT 2
+#define GUI_IDLE_POWER_SAVE 3
+// --
+
+
+// definition for WpaSupport flag
+#define WPA_SUPPLICANT_DISABLE 0
+#define WPA_SUPPLICANT_ENABLE 1
+#define WPA_SUPPLICANT_ENABLE_WITH_WEB_UI 2
+
+// Endian byte swapping codes
+#define SWAP16(x) \
+ ((UINT16)( \
+ (((UINT16)(x) & (UINT16) 0x00ffU) << 8) | \
+ (((UINT16)(x) & (UINT16) 0xff00U) >> 8) ))
+
+#define SWAP32(x) \
+ ((UINT32)( \
+ (((UINT32)(x) & (UINT32) 0x000000ffUL) << 24) | \
+ (((UINT32)(x) & (UINT32) 0x0000ff00UL) << 8) | \
+ (((UINT32)(x) & (UINT32) 0x00ff0000UL) >> 8) | \
+ (((UINT32)(x) & (UINT32) 0xff000000UL) >> 24) ))
+
+#define SWAP64(x) \
+ ((UINT64)( \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x00000000000000ffULL) << 56) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x000000000000ff00ULL) << 40) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x0000000000ff0000ULL) << 24) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x00000000ff000000ULL) << 8) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x000000ff00000000ULL) >> 8) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x0000ff0000000000ULL) >> 24) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0x00ff000000000000ULL) >> 40) | \
+ (UINT64)(((UINT64)(x) & (UINT64) 0xff00000000000000ULL) >> 56) ))
+
+#ifdef RT_BIG_ENDIAN
+
+#define cpu2le64(x) SWAP64((x))
+#define le2cpu64(x) SWAP64((x))
+#define cpu2le32(x) SWAP32((x))
+#define le2cpu32(x) SWAP32((x))
+#define cpu2le16(x) SWAP16((x))
+#define le2cpu16(x) SWAP16((x))
+#define cpu2be64(x) ((UINT64)(x))
+#define be2cpu64(x) ((UINT64)(x))
+#define cpu2be32(x) ((UINT32)(x))
+#define be2cpu32(x) ((UINT32)(x))
+#define cpu2be16(x) ((UINT16)(x))
+#define be2cpu16(x) ((UINT16)(x))
+
+#else // Little_Endian
+
+#define cpu2le64(x) ((UINT64)(x))
+#define le2cpu64(x) ((UINT64)(x))
+#define cpu2le32(x) ((UINT32)(x))
+#define le2cpu32(x) ((UINT32)(x))
+#define cpu2le16(x) ((UINT16)(x))
+#define le2cpu16(x) ((UINT16)(x))
+#define cpu2be64(x) SWAP64((x))
+#define be2cpu64(x) SWAP64((x))
+#define cpu2be32(x) SWAP32((x))
+#define be2cpu32(x) SWAP32((x))
+#define cpu2be16(x) SWAP16((x))
+#define be2cpu16(x) SWAP16((x))
+
+#endif // RT_BIG_ENDIAN
+
+#endif // __RTMP_DEF_H__
+
+
diff --git a/drivers/staging/rt3070/rtmp_type.h b/drivers/staging/rt3070/rtmp_type.h
new file mode 100644
index 00000000000..4e4b168b9e9
--- /dev/null
+++ b/drivers/staging/rt3070/rtmp_type.h
@@ -0,0 +1,95 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_type.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+ Paul Lin 1-2-2004
+*/
+#ifndef __RTMP_TYPE_H__
+#define __RTMP_TYPE_H__
+
+
+#define PACKED __attribute__ ((packed))
+
+// Put platform dependent declaration here
+// For example, linux type definition
+typedef unsigned char UINT8;
+typedef unsigned short UINT16;
+typedef unsigned int UINT32;
+typedef unsigned long long UINT64;
+typedef int INT32;
+typedef long long INT64;
+
+typedef unsigned char * PUINT8;
+typedef unsigned short * PUINT16;
+typedef unsigned int * PUINT32;
+typedef unsigned long long * PUINT64;
+typedef int * PINT32;
+typedef long long * PINT64;
+
+typedef signed char CHAR;
+typedef signed short SHORT;
+typedef signed int INT;
+typedef signed long LONG;
+typedef signed long long LONGLONG;
+
+
+typedef unsigned char UCHAR;
+typedef unsigned short USHORT;
+typedef unsigned int UINT;
+typedef unsigned long ULONG;
+typedef unsigned long long ULONGLONG;
+
+typedef unsigned char BOOLEAN;
+typedef void VOID;
+
+typedef VOID * PVOID;
+typedef CHAR * PCHAR;
+typedef UCHAR * PUCHAR;
+typedef USHORT * PUSHORT;
+typedef LONG * PLONG;
+typedef ULONG * PULONG;
+typedef UINT * PUINT;
+
+typedef unsigned int NDIS_MEDIA_STATE;
+
+typedef union _LARGE_INTEGER {
+ struct {
+ UINT LowPart;
+ INT32 HighPart;
+ } u;
+ INT64 QuadPart;
+} LARGE_INTEGER;
+
+#endif // __RTMP_TYPE_H__
+
diff --git a/drivers/staging/rt3070/spectrum.h b/drivers/staging/rt3070/spectrum.h
new file mode 100644
index 00000000000..94cfa5b174f
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum.h
@@ -0,0 +1,322 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+ */
+
+#ifndef __SPECTRUM_H__
+#define __SPECTRUM_H__
+
+#include "rtmp_type.h"
+#include "spectrum_def.h"
+
+typedef struct PACKED _TPC_REPORT_INFO
+{
+ UINT8 TxPwr;
+ UINT8 LinkMargin;
+} TPC_REPORT_INFO, *PTPC_REPORT_INFO;
+
+typedef struct PACKED _CH_SW_ANN_INFO
+{
+ UINT8 ChSwMode;
+ UINT8 Channel;
+ UINT8 ChSwCnt;
+} CH_SW_ANN_INFO, *PCH_SW_ANN_INFO;
+
+typedef union PACKED _MEASURE_REQ_MODE
+{
+#ifdef RT_BIG_ENDIAN
+ struct PACKED
+ {
+ UINT8 Rev1:4;
+ UINT8 Report:1;
+ UINT8 Request:1;
+ UINT8 Enable:1;
+ UINT8 Rev0:1;
+ } field;
+#else
+ struct PACKED
+ {
+ UINT8 Rev0:1;
+ UINT8 Enable:1;
+ UINT8 Request:1;
+ UINT8 Report:1;
+ UINT8 Rev1:4;
+ } field;
+#endif // RT_BIG_ENDIAN //
+ UINT8 word;
+} MEASURE_REQ_MODE, *PMEASURE_REQ_MODE;
+
+typedef struct PACKED _MEASURE_REQ
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+} MEASURE_REQ, *PMEASURE_REQ;
+
+typedef struct PACKED _MEASURE_REQ_INFO
+{
+ UINT8 Token;
+ MEASURE_REQ_MODE ReqMode;
+ UINT8 ReqType;
+ MEASURE_REQ MeasureReq;
+} MEASURE_REQ_INFO, *PMEASURE_REQ_INFO;
+
+typedef union PACKED _MEASURE_BASIC_REPORT_MAP
+{
+#ifdef RT_BIG_ENDIAN
+ struct PACKED
+ {
+ UINT8 Rev:3;
+ UINT8 Unmeasure:1;
+ UINT8 Radar:1;
+ UINT8 UnidentifiedSignal:1;
+ UINT8 OfdmPreamble:1;
+ UINT8 BSS:1;
+ } field;
+#else
+ struct PACKED
+ {
+ UINT8 BSS:1;
+ UINT8 OfdmPreamble:1;
+ UINT8 UnidentifiedSignal:1;
+ UINT8 Radar:1;
+ UINT8 Unmeasure:1;
+ UINT8 Rev:3;
+ } field;
+#endif // RT_BIG_ENDIAN //
+ UINT8 word;
+} MEASURE_BASIC_REPORT_MAP, *PMEASURE_BASIC_REPORT_MAP;
+
+typedef struct PACKED _MEASURE_BASIC_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ MEASURE_BASIC_REPORT_MAP Map;
+} MEASURE_BASIC_REPORT, *PMEASURE_BASIC_REPORT;
+
+typedef struct PACKED _MEASURE_CCA_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ UINT8 CCA_Busy_Fraction;
+} MEASURE_CCA_REPORT, *PMEASURE_CCA_REPORT;
+
+typedef struct PACKED _MEASURE_RPI_REPORT
+{
+ UINT8 ChNum;
+ UINT64 MeasureStartTime;
+ UINT16 MeasureDuration;
+ UINT8 RPI_Density[8];
+} MEASURE_RPI_REPORT, *PMEASURE_RPI_REPORT;
+
+typedef union PACKED _MEASURE_REPORT_MODE
+{
+ struct PACKED
+ {
+#ifdef RT_BIG_ENDIAN
+ UINT8 Rev:5;
+ UINT8 Refused:1;
+ UINT8 Incapable:1;
+ UINT8 Late:1;
+#else
+ UINT8 Late:1;
+ UINT8 Incapable:1;
+ UINT8 Refused:1;
+ UINT8 Rev:5;
+#endif // RT_BIG_ENDIAN //
+ } field;
+ UINT8 word;
+} MEASURE_REPORT_MODE, *PMEASURE_REPORT_MODE;
+
+typedef struct PACKED _MEASURE_REPORT_INFO
+{
+ UINT8 Token;
+ MEASURE_REPORT_MODE ReportMode;
+ UINT8 ReportType;
+ UINT8 Octect[0];
+} MEASURE_REPORT_INFO, *PMEASURE_REPORT_INFO;
+
+typedef struct PACKED _QUIET_INFO
+{
+ UINT8 QuietCnt;
+ UINT8 QuietPeriod;
+ UINT8 QuietDuration;
+ UINT8 QuietOffset;
+} QUIET_INFO, *PQUIET_INFO;
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 MeasureCh,
+ IN UINT16 MeasureDuration);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Measurement report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueMeasurementRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 MeasureToken,
+ IN UINT8 MeasureReqMode,
+ IN UINT8 MeasureReqType,
+ IN UINT8 ReportInfoLen,
+ IN PUINT8 pReportInfo);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Request action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCReq(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UCHAR DialogToken);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare TPC Report action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueTPCRep(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 DialogToken,
+ IN UINT8 TxPwr,
+ IN UINT8 LinkMargin);
+
+/*
+ ==========================================================================
+ Description:
+ Prepare Channel Switch Announcement action frame and enqueue it into
+ management queue waiting for transmition.
+
+ Parametrs:
+ 1. the destination mac address of the frame.
+ 2. Channel switch announcement mode.
+ 2. a New selected channel.
+
+ Return : None.
+ ==========================================================================
+ */
+VOID EnqueueChSwAnn(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN UINT8 ChSwMode,
+ IN UINT8 NewCh);
+
+/*
+ ==========================================================================
+ Description:
+ Spectrun action frames Handler such as channel switch annoucement,
+ measurement report, measurement request actions frames.
+
+ Parametrs:
+ Elme - MLME message containing the received frame
+
+ Return : None.
+ ==========================================================================
+ */
+VOID PeerSpectrumAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem);
+
+/*
+ ==========================================================================
+ Description:
+
+ Parametrs:
+
+ Return : None.
+ ==========================================================================
+ */
+INT Set_MeasureReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+INT Set_TpcReq_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+
+VOID MeasureReqTabInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID MeasureReqTabExit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID TpcReqTabInit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID TpcReqTabExit(
+ IN PRTMP_ADAPTER pAd);
+
+VOID NotifyChSwAnnToPeerAPs(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pRA,
+ IN PUCHAR pTA,
+ IN UINT8 ChSwMode,
+ IN UINT8 Channel);
+#endif // __SPECTRUM_H__ //
+
diff --git a/drivers/staging/rt3070/spectrum_def.h b/drivers/staging/rt3070/spectrum_def.h
new file mode 100644
index 00000000000..4ca4817bba0
--- /dev/null
+++ b/drivers/staging/rt3070/spectrum_def.h
@@ -0,0 +1,95 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ spectrum_def.h
+
+ Abstract:
+ Handle association related requests either from WSTA or from local MLME
+
+ Revision History:
+ Who When What
+ --------- ---------- ----------------------------------------------
+ Fonchi Wu 2008 created for 802.11h
+ */
+
+#ifndef __SPECTRUM_DEF_H__
+#define __SPECTRUM_DEF_H__
+
+#define MAX_MEASURE_REQ_TAB_SIZE 3
+#define MAX_HASH_MEASURE_REQ_TAB_SIZE MAX_MEASURE_REQ_TAB_SIZE
+
+#define MAX_TPC_REQ_TAB_SIZE 3
+#define MAX_HASH_TPC_REQ_TAB_SIZE MAX_TPC_REQ_TAB_SIZE
+
+#define MIN_RCV_PWR 100 /* Negative value ((dBm) */
+
+#define RM_TPC_REQ 0
+#define RM_MEASURE_REQ 1
+
+#define RM_BASIC 0
+#define RM_CCA 1
+#define RM_RPI_HISTOGRAM 2
+
+#define TPC_REQ_AGE_OUT 500 /* ms */
+#define MQ_REQ_AGE_OUT 500 /* ms */
+
+#define TPC_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_HASH_TPC_REQ_TAB_SIZE)
+#define MQ_DIALOGTOKEN_HASH_INDEX(_DialogToken) ((_DialogToken) % MAX_MEASURE_REQ_TAB_SIZE)
+
+typedef struct _MEASURE_REQ_ENTRY
+{
+ struct _MEASURE_REQ_ENTRY *pNext;
+ ULONG lastTime;
+ BOOLEAN Valid;
+ UINT8 DialogToken;
+ UINT8 MeasureDialogToken[3]; // 0:basic measure, 1: CCA measure, 2: RPI_Histogram measure.
+} MEASURE_REQ_ENTRY, *PMEASURE_REQ_ENTRY;
+
+typedef struct _MEASURE_REQ_TAB
+{
+ UCHAR Size;
+ PMEASURE_REQ_ENTRY Hash[MAX_HASH_MEASURE_REQ_TAB_SIZE];
+ MEASURE_REQ_ENTRY Content[MAX_MEASURE_REQ_TAB_SIZE];
+} MEASURE_REQ_TAB, *PMEASURE_REQ_TAB;
+
+typedef struct _TPC_REQ_ENTRY
+{
+ struct _TPC_REQ_ENTRY *pNext;
+ ULONG lastTime;
+ BOOLEAN Valid;
+ UINT8 DialogToken;
+} TPC_REQ_ENTRY, *PTPC_REQ_ENTRY;
+
+typedef struct _TPC_REQ_TAB
+{
+ UCHAR Size;
+ PTPC_REQ_ENTRY Hash[MAX_HASH_TPC_REQ_TAB_SIZE];
+ TPC_REQ_ENTRY Content[MAX_TPC_REQ_TAB_SIZE];
+} TPC_REQ_TAB, *PTPC_REQ_TAB;
+
+#endif // __SPECTRUM_DEF_H__ //
+
diff --git a/drivers/staging/rt3070/sta/aironet.c b/drivers/staging/rt3070/sta/aironet.c
new file mode 100644
index 00000000000..4af4a190618
--- /dev/null
+++ b/drivers/staging/rt3070/sta/aironet.c
@@ -0,0 +1,1312 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ aironet.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Paul Lin 04-06-15 Initial
+*/
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ ==========================================================================
+ */
+VOID AironetStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, Trans, MAX_AIRONET_STATE, MAX_AIRONET_MSG, (STATE_MACHINE_FUNC)Drop, AIRONET_IDLE, AIRONET_MACHINE_BASE);
+ StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_MSG, (STATE_MACHINE_FUNC)AironetMsgAction);
+ StateMachineSetAction(S, AIRONET_IDLE, MT2_AIRONET_SCAN_REQ, (STATE_MACHINE_FUNC)AironetRequestAction);
+ StateMachineSetAction(S, AIRONET_SCANNING, MT2_AIRONET_SCAN_DONE, (STATE_MACHINE_FUNC)AironetReportAction);
+}
+
+/*
+ ==========================================================================
+ Description:
+ This is state machine function.
+ When receiving EAPOL packets which is for 802.1x key management.
+ Use both in WPA, and WPAPSK case.
+ In this function, further dispatch to different functions according to the received packet. 3 categories are :
+ 1. normal 4-way pairwisekey and 2-way groupkey handshake
+ 2. MIC error (Countermeasures attack) report packet from STA.
+ 3. Request for pairwise/group key update from STA
+ Return:
+ ==========================================================================
+*/
+VOID AironetMsgAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Length;
+ UCHAR Index, i;
+ PUCHAR pData;
+ PAIRONET_RM_REQUEST_FRAME pRMReq;
+ PRM_REQUEST_ACTION pReqElem;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> AironetMsgAction\n"));
+
+ // 0. Get Aironet IAPP header first
+ pRMReq = (PAIRONET_RM_REQUEST_FRAME) &Elem->Msg[LENGTH_802_11];
+ pData = (PUCHAR) &Elem->Msg[LENGTH_802_11];
+
+ // 1. Change endian format form network to little endian
+ Length = be2cpu16(pRMReq->IAPP.Length);
+
+ // 2.0 Sanity check, this should only happen when CCX 2.0 support is enabled
+ if (pAd->StaCfg.CCXEnable != TRUE)
+ return;
+
+ // 2.1 Radio measurement must be on
+ if (pAd->StaCfg.CCXControl.field.RMEnable != 1)
+ return;
+
+ // 2.2. Debug print all bit information
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP ID & Length %d\n", Length));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Type %x\n", pRMReq->IAPP.Type));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP SubType %x\n", pRMReq->IAPP.SubType));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Dialog Token %x\n", pRMReq->IAPP.Token));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Activation Delay %x\n", pRMReq->Delay));
+ DBGPRINT(RT_DEBUG_TRACE, ("IAPP Measurement Offset %x\n", pRMReq->Offset));
+
+ // 3. Check IAPP frame type, it must be 0x32 for Cisco Aironet extension
+ if (pRMReq->IAPP.Type != AIRONET_IAPP_TYPE)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP type for Cisco Aironet extension\n"));
+ return;
+ }
+
+ // 4. Check IAPP frame subtype, it must be 0x01 for Cisco Aironet extension request.
+ // Since we are acting as client only, we will disregards reply subtype.
+ if (pRMReq->IAPP.SubType != AIRONET_IAPP_SUBTYPE_REQUEST)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP subtype for Cisco Aironet extension\n"));
+ return;
+ }
+
+ // 5. Verify Destination MAC and Source MAC, both should be all zeros.
+ if (! MAC_ADDR_EQUAL(pRMReq->IAPP.DA, ZERO_MAC_ADDR))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP DA for Cisco Aironet extension, it's not Zero\n"));
+ return;
+ }
+
+ if (! MAC_ADDR_EQUAL(pRMReq->IAPP.SA, ZERO_MAC_ADDR))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Wrong IAPP SA for Cisco Aironet extension, it's not Zero\n"));
+ return;
+ }
+
+ // 6. Reinit all report related fields
+ NdisZeroMemory(pAd->StaCfg.FrameReportBuf, 2048);
+ NdisZeroMemory(pAd->StaCfg.BssReportOffset, sizeof(USHORT) * MAX_LEN_OF_BSS_TABLE);
+ NdisZeroMemory(pAd->StaCfg.MeasurementRequest, sizeof(RM_REQUEST_ACTION) * 4);
+
+ // 7. Point to the start of first element report element
+ pAd->StaCfg.FrameReportLen = LENGTH_802_11 + sizeof(AIRONET_IAPP_HEADER);
+ DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
+ pAd->StaCfg.LastBssIndex = 0xff;
+ pAd->StaCfg.RMReqCnt = 0;
+ pAd->StaCfg.ParallelReq = FALSE;
+ pAd->StaCfg.ParallelDuration = 0;
+ pAd->StaCfg.ParallelChannel = 0;
+ pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
+ pAd->StaCfg.CurrentRMReqIdx = 0;
+ pAd->StaCfg.CLBusyBytes = 0;
+ // Reset the statistics
+ for (i = 0; i < 8; i++)
+ pAd->StaCfg.RPIDensity[i] = 0;
+
+ Index = 0;
+
+ // 8. Save dialog token for report
+ pAd->StaCfg.IAPPToken = pRMReq->IAPP.Token;
+
+ // Save Activation delay & measurement offset, Not really needed
+
+ // 9. Point to the first request element
+ pData += sizeof(AIRONET_RM_REQUEST_FRAME);
+ // Length should exclude the CISCO Aironet SNAP header
+ Length -= (sizeof(AIRONET_RM_REQUEST_FRAME) - LENGTH_802_1_H);
+
+ // 10. Start Parsing the Measurement elements.
+ // Be careful about multiple MR elements within one frames.
+ while (Length > 0)
+ {
+ pReqElem = (PRM_REQUEST_ACTION) pData;
+ switch (pReqElem->ReqElem.Eid)
+ {
+ case IE_MEASUREMENT_REQUEST:
+ // From the example, it seems we only need to support one request in one frame
+ // There is no multiple request in one frame.
+ // Besides, looks like we need to take care the measurement request only.
+ // The measurement request is always 4 bytes.
+
+ // Start parsing this type of request.
+ // 0. Eid is IE_MEASUREMENT_REQUEST
+ // 1. Length didn't include Eid and Length field, it always be 8.
+ // 2. Measurement Token, we nned to save it for the corresponding report.
+ // 3. Measurement Mode, Although there are definitions, but we din't see value other than
+ // 0 from test specs examples.
+ // 4. Measurement Type, this is what we need to do.
+ switch (pReqElem->ReqElem.Type)
+ {
+ case MSRN_TYPE_CHANNEL_LOAD_REQ:
+ case MSRN_TYPE_NOISE_HIST_REQ:
+ case MSRN_TYPE_BEACON_REQ:
+ // Check the Enable non-serving channel measurement control
+ if (pAd->StaCfg.CCXControl.field.DCRMEnable == 0)
+ {
+ // Check channel before enqueue the action
+ if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
+ break;
+ }
+ else
+ {
+ // If off channel measurement, check the TU duration limit
+ if (pReqElem->Measurement.Channel != pAd->CommonCfg.Channel)
+ if (pReqElem->Measurement.Duration > pAd->StaCfg.CCXControl.field.TuLimit)
+ break;
+ }
+
+ // Save requests and execute actions later
+ NdisMoveMemory(&pAd->StaCfg.MeasurementRequest[Index], pReqElem, sizeof(RM_REQUEST_ACTION));
+ Index += 1;
+ break;
+
+ case MSRN_TYPE_FRAME_REQ:
+ // Since it's option, we will support later
+ // FrameRequestAction(pAd, pData);
+ break;
+
+ default:
+ break;
+ }
+
+ // Point to next Measurement request
+ pData += sizeof(RM_REQUEST_ACTION);
+ Length -= sizeof(RM_REQUEST_ACTION);
+ break;
+
+ // We accept request only, all others are dropped
+ case IE_MEASUREMENT_REPORT:
+ case IE_AP_TX_POWER:
+ case IE_MEASUREMENT_CAPABILITY:
+ default:
+ return;
+ }
+ }
+
+ // 11. Update some flags and index
+ pAd->StaCfg.RMReqCnt = Index;
+
+ if (Index)
+ {
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- AironetMsgAction\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PRM_REQUEST_ACTION pReq;
+
+ // 1. Point to next request element
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ // 2. Parse measurement type and call appropriate functions
+ if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+ // Channel Load measurement request
+ ChannelLoadRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+ // Noise Histogram measurement request
+ NoiseHistRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
+ // Beacon measurement request
+ BeaconRequestAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else
+ // Unknown. Do nothing and return, this should never happen
+ return;
+
+ // 3. Peek into the next request, if it's parallel, we will update the scan time to the largest one
+ if ((pAd->StaCfg.CurrentRMReqIdx + 1) < pAd->StaCfg.RMReqCnt)
+ {
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx + 1];
+ // Check for parallel bit
+ if ((pReq->ReqElem.Mode & 0x01) && (pReq->Measurement.Channel == pAd->StaCfg.CCXScanChannel))
+ {
+ // Update parallel mode request information
+ pAd->StaCfg.ParallelReq = TRUE;
+ pAd->StaCfg.CCXScanTime = ((pReq->Measurement.Duration > pAd->StaCfg.CCXScanTime) ?
+ (pReq->Measurement.Duration) : (pAd->StaCfg.CCXScanTime));
+ }
+ }
+
+ // 4. Call RT28XX_MLME_HANDLER to execute the request mlme commands, Scan request is the only one used
+ RT28XX_MLME_HANDLER(pAd);
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare channel load report action, special scan operation added
+ to support
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Start from element ID
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ChannelLoadRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PRM_REQUEST_ACTION pReq;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ UCHAR ZeroSsid[32];
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ PHEADER_802_11 pNullFrame;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction ----->\n"));
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+ NdisZeroMemory(ZeroSsid, 32);
+
+ // Prepare for special scan request
+ // The scan definition is different with our Active, Passive scan definition.
+ // For CCX2, Active means send out probe request with broadcast BSSID.
+ // Passive means no probe request sent, only listen to the beacons.
+ // The channel scanned is fixed as specified, no need to scan all channels.
+ // The scan wait time is specified in the request too.
+ // Passive scan Mode
+
+ // Control state machine is not idle, reject the request
+ if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_CHANNEL_LOAD);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_CHANNEL_LOAD_REQ;
+ pAd->StaCfg.CLBusyBytes = 0;
+ // Enable Rx with promiscuous reception
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
+
+ // Set channel load measurement flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadRequestAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare noise histogram report action, special scan operation added
+ to support
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Start from element ID
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID NoiseHistRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PRM_REQUEST_ACTION pReq;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ UCHAR ZeroSsid[32], i;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ PHEADER_802_11 pNullFrame;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction ----->\n"));
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+ NdisZeroMemory(ZeroSsid, 32);
+
+ // Prepare for special scan request
+ // The scan definition is different with our Active, Passive scan definition.
+ // For CCX2, Active means send out probe request with broadcast BSSID.
+ // Passive means no probe request sent, only listen to the beacons.
+ // The channel scanned is fixed as specified, no need to scan all channels.
+ // The scan wait time is specified in the request too.
+ // Passive scan Mode
+
+ // Control state machine is not idle, reject the request
+ if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_NOISE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_NOISE_HIST_REQ;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d, Channel %d!\n", pReq->Measurement.Duration, pReq->Measurement.Channel));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ // Reset the statistics
+ for (i = 0; i < 8; i++)
+ pAd->StaCfg.RPIDensity[i] = 0;
+
+ // Enable Rx with promiscuous reception
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, 0x1010);
+
+ // Set channel load measurement flag
+ RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistRequestAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare Beacon report action, special scan operation added
+ to support
+
+ Arguments:
+ pAd Pointer to our adapter
+ pData Start from element ID
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID BeaconRequestAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PRM_REQUEST_ACTION pReq;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ PHEADER_802_11 pNullFrame;
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ UCHAR ZeroSsid[32];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction ----->\n"));
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[Index];
+ NdisZeroMemory(ZeroSsid, 32);
+
+ // Prepare for special scan request
+ // The scan definition is different with our Active, Passive scan definition.
+ // For CCX2, Active means send out probe request with broadcast BSSID.
+ // Passive means no probe request sent, only listen to the beacons.
+ // The channel scanned is fixed as specified, no need to scan all channels.
+ // The scan wait time is specified in the request too.
+ if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_PASSIVE)
+ {
+ // Passive scan Mode
+ DBGPRINT(RT_DEBUG_TRACE, ("Passive Scan Mode!\n"));
+
+ // Control state machine is not idle, reject the request
+ if ((pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) && (Index == 0))
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_PASSIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+ }
+ else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_ACTIVE)
+ {
+ // Active scan Mode
+ DBGPRINT(RT_DEBUG_TRACE, ("Active Scan Mode!\n"));
+
+ // Control state machine is not idle, reject the request
+ if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ return;
+
+ // Fill out stuff for scan request
+ ScanParmFill(pAd, &ScanReq, ZeroSsid, 0, BSS_ANY, SCAN_CISCO_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+
+ // Reset some internal control flags to make sure this scan works.
+ BssTableInit(&pAd->StaCfg.CCXBssTab);
+ pAd->StaCfg.ScanCnt = 0;
+ pAd->StaCfg.CCXScanChannel = pReq->Measurement.Channel;
+ pAd->StaCfg.CCXScanTime = pReq->Measurement.Duration;
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_BEACON_REQ;
+ DBGPRINT(RT_DEBUG_TRACE, ("Duration %d!\n", pReq->Measurement.Duration));
+
+ // If it's non serving channel scan, send out a null frame with PSM bit on.
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ {
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ pNullFrame = (PHEADER_802_11) pOutBuffer;
+ // Make the power save Null frame with PSM bit on
+ MgtMacHeaderInit(pAd, pNullFrame, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pNullFrame->Duration = 0;
+ pNullFrame->FC.Type = BTYPE_DATA;
+ pNullFrame->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ DBGPRINT(RT_DEBUG_TRACE, ("Send PSM Data frame for off channel RM\n"));
+ RTMPusecDelay(5000);
+ }
+
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+ }
+ else if (pReq->Measurement.ScanMode == MSRN_SCAN_MODE_BEACON_TABLE)
+ {
+ // Beacon report Mode, report all the APS in current bss table
+ DBGPRINT(RT_DEBUG_TRACE, ("Beacon Report Mode!\n"));
+
+ // Copy current BSS table to CCX table, we can omit this step later on.
+ NdisMoveMemory(&pAd->StaCfg.CCXBssTab, &pAd->ScanTab, sizeof(BSS_TABLE));
+
+ // Create beacon report from Bss table
+ AironetCreateBeaconReportFromBssTable(pAd);
+
+ // Set state to scanning
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_SCANNING;
+
+ // Enqueue report request
+ // Cisco scan request is finished, prepare beacon report
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+ }
+ else
+ {
+ // Wrong scan Mode
+ DBGPRINT(RT_DEBUG_TRACE, ("Wrong Scan Mode!\n"));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconRequestAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PRM_REQUEST_ACTION pReq;
+ ULONG Now32;
+
+ NdisGetSystemUpTime(&Now32);
+ pAd->StaCfg.LastBeaconRxTime = Now32;
+
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction ----->\n"));
+
+ // 1. Parse measurement type and call appropriate functions
+ if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+ // Channel Load measurement request
+ ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+ // Noise Histogram measurement request
+ NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_BEACON_REQ)
+ // Beacon measurement request
+ BeaconReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else
+ // Unknown. Do nothing and return
+ ;
+
+ // 2. Point to the correct index of action element, start from 0
+ pAd->StaCfg.CurrentRMReqIdx++;
+
+ // 3. Check for parallel actions
+ if (pAd->StaCfg.ParallelReq == TRUE)
+ {
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ // Process next action right away
+ if (pReq->ReqElem.Type == MSRN_TYPE_CHANNEL_LOAD_REQ)
+ // Channel Load measurement request
+ ChannelLoadReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+ else if (pReq->ReqElem.Type == MSRN_TYPE_NOISE_HIST_REQ)
+ // Noise Histogram measurement request
+ NoiseHistReportAction(pAd, pAd->StaCfg.CurrentRMReqIdx);
+
+ pAd->StaCfg.ParallelReq = FALSE;
+ pAd->StaCfg.CurrentRMReqIdx++;
+ }
+
+ if (pAd->StaCfg.CurrentRMReqIdx >= pAd->StaCfg.RMReqCnt)
+ {
+ // 4. There is no more unprocessed measurement request, go for transmit this report
+ AironetFinalReportAction(pAd);
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+ }
+ else
+ {
+ pReq = (PRM_REQUEST_ACTION) &pAd->StaCfg.MeasurementRequest[pAd->StaCfg.CurrentRMReqIdx];
+
+ if (pReq->Measurement.Channel != pAd->CommonCfg.Channel)
+ {
+ RTMPusecDelay(100000);
+ }
+
+ // 5. There are more requests to be measure
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_REQ, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetFinalReportAction(
+ IN PRTMP_ADAPTER pAd)
+{
+ PUCHAR pDest;
+ PAIRONET_IAPP_HEADER pIAPP;
+ PHEADER_802_11 pHeader;
+ UCHAR AckRate = RATE_2;
+ USHORT AckDuration = 0;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction ----->\n"));
+
+ // 0. Set up the frame pointer, Frame was inited at the end of message action
+ pDest = &pAd->StaCfg.FrameReportBuf[LENGTH_802_11];
+
+ // 1. Update report IAPP fields
+ pIAPP = (PAIRONET_IAPP_HEADER) pDest;
+
+ // 2. Copy Cisco SNAP header
+ NdisMoveMemory(pIAPP->CiscoSnapHeader, SNAP_AIRONET, LENGTH_802_1_H);
+
+ // 3. network order for this 16bit length
+ pIAPP->Length = cpu2be16(pAd->StaCfg.FrameReportLen - LENGTH_802_11 - LENGTH_802_1_H);
+
+ // 3.1 sanity check the report length, ignore it if there is nothing to report
+ if (be2cpu16(pIAPP->Length) <= 18)
+ return;
+
+ // 4. Type must be 0x32
+ pIAPP->Type = AIRONET_IAPP_TYPE;
+
+ // 5. SubType for report must be 0x81
+ pIAPP->SubType = AIRONET_IAPP_SUBTYPE_REPORT;
+
+ // 6. DA is not used and must be zero, although the whole frame was cleared at the start of function
+ // We will do it again here. We can use BSSID instead
+ COPY_MAC_ADDR(pIAPP->DA, pAd->CommonCfg.Bssid);
+
+ // 7. SA is the client reporting which must be our MAC
+ COPY_MAC_ADDR(pIAPP->SA, pAd->CurrentAddress);
+
+ // 8. Copy the saved dialog token
+ pIAPP->Token = pAd->StaCfg.IAPPToken;
+
+ // 9. Make the Report frame 802.11 header
+ // Reuse function in wpa.c
+ pHeader = (PHEADER_802_11) pAd->StaCfg.FrameReportBuf;
+ pAd->Sequence ++;
+ WpaMacHeaderInit(pAd, pHeader, 0, pAd->CommonCfg.Bssid);
+
+ // ACK size is 14 include CRC, and its rate is based on real time information
+ AckRate = pAd->CommonCfg.ExpectedACKRate[pAd->CommonCfg.MlmeRate];
+ AckDuration = RTMPCalcDuration(pAd, AckRate, 14);
+ pHeader->Duration = pAd->CommonCfg.Dsifs + AckDuration;
+
+ // Use MLME enqueue method
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ // 10. Prepare report frame with dynamic outbuffer. Just simply copy everything.
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ pAd->StaCfg.FrameReportLen, pAd->StaCfg.FrameReportBuf,
+ END_OF_ARGS);
+
+ // 11. Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.CCXReqType = MSRN_TYPE_UNUSED;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AironetFinalReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID ChannelLoadReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PCHANNEL_LOAD_REPORT pLoad;
+ PUCHAR pDest;
+ UCHAR CCABusyFraction;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction ----->\n"));
+
+ // Disable Rx with promiscuous reception, make it back to normal
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+
+ // 0. Setup pointer for processing beacon & probe response
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+
+ // 1. Fill Measurement report element field.
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ // Fixed Length at 9, not include Eid and length fields
+ pReport->Length = 9;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_CHANNEL_LOAD_REQ;
+
+ // 2. Fill channel report measurement data
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pLoad = (PCHANNEL_LOAD_REPORT) pDest;
+ pLoad->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
+ pLoad->Spare = 0;
+ pLoad->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
+
+ // 3. Calculate the CCA Busy Fraction
+ // (Bytes + ACK size) * 8 / Tx speed * 255 / 1000 / measurement duration, use 24 us Tx speed
+ // = (Bytes + ACK) / 12 / duration
+ // 9 is the good value for pAd->StaCfg.CLFactor
+ // CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 9 / pLoad->Duration);
+ CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / pAd->StaCfg.CLFactor / pLoad->Duration);
+ if (CCABusyFraction < 10)
+ CCABusyFraction = (UCHAR) (pAd->StaCfg.CLBusyBytes / 3 / pLoad->Duration) + 1;
+
+ pLoad->CCABusy = CCABusyFraction;
+ DBGPRINT(RT_DEBUG_TRACE, ("CLBusyByte %ld, Duration %d, Result, %d\n", pAd->StaCfg.CLBusyBytes, pLoad->Duration, CCABusyFraction));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
+ pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(CHANNEL_LOAD_REPORT));
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen %d\n", pAd->StaCfg.FrameReportLen));
+
+ // 4. Clear channel load measurement flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ // 5. reset to idle state
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ChannelLoadReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID NoiseHistReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PNOISE_HIST_REPORT pNoise;
+ PUCHAR pDest;
+ UCHAR i,NoiseCnt;
+ USHORT TotalRPICnt, TotalRPISum;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction ----->\n"));
+
+ // 0. Disable Rx with promiscuous reception, make it back to normal
+ RTMP_IO_WRITE32(pAd, RX_FILTR_CFG, STANORMAL); // Staion not drop control frame will fail WiFi Certification.
+ // 1. Setup pointer for processing beacon & probe response
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+
+ // 2. Fill Measurement report element field.
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ // Fixed Length at 16, not include Eid and length fields
+ pReport->Length = 16;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[Index].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_NOISE_HIST_REQ;
+
+ // 3. Fill noise histogram report measurement data
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pNoise = (PNOISE_HIST_REPORT) pDest;
+ pNoise->Channel = pAd->StaCfg.MeasurementRequest[Index].Measurement.Channel;
+ pNoise->Spare = 0;
+ pNoise->Duration = pAd->StaCfg.MeasurementRequest[Index].Measurement.Duration;
+ // 4. Fill Noise histogram, the total RPI counts should be 0.4 * TU
+ // We estimate 4000 normal packets received durning 10 seconds test.
+ // Adjust it if required.
+ // 3 is a good value for pAd->StaCfg.NHFactor
+ // TotalRPICnt = pNoise->Duration * 3 / 10;
+ TotalRPICnt = pNoise->Duration * pAd->StaCfg.NHFactor / 10;
+ TotalRPISum = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ TotalRPISum += pAd->StaCfg.RPIDensity[i];
+ DBGPRINT(RT_DEBUG_TRACE, ("RPI %d Conuts %d\n", i, pAd->StaCfg.RPIDensity[i]));
+ }
+
+ // Double check if the counter is larger than our expectation.
+ // We will replace it with the total number plus a fraction.
+ if (TotalRPISum > TotalRPICnt)
+ TotalRPICnt = TotalRPISum + pNoise->Duration / 20;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Total RPI Conuts %d\n", TotalRPICnt));
+
+ // 5. Initialize noise count for the total summation of 0xff
+ NoiseCnt = 0;
+ for (i = 1; i < 8; i++)
+ {
+ pNoise->Density[i] = (UCHAR) (pAd->StaCfg.RPIDensity[i] * 255 / TotalRPICnt);
+ if ((pNoise->Density[i] == 0) && (pAd->StaCfg.RPIDensity[i] != 0))
+ pNoise->Density[i]++;
+ NoiseCnt += pNoise->Density[i];
+ DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[%d] = 0x%02x\n", i, pNoise->Density[i]));
+ }
+
+ // 6. RPI[0] represents the rest of counts
+ pNoise->Density[0] = 0xff - NoiseCnt;
+ DBGPRINT(RT_DEBUG_TRACE, ("Reported RPI[0] = 0x%02x\n", pNoise->Density[0]));
+
+ pAd->StaCfg.FrameReportLen += (sizeof(MEASUREMENT_REPORT_ELEMENT) + sizeof(NOISE_HIST_REPORT));
+
+ // 7. Clear channel load measurement flag
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_RADIO_MEASUREMENT);
+
+ // 8. reset to idle state
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NoiseHistReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Prepare Beacon report action,
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID BeaconReportAction(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR Index)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction ----->\n"));
+
+ // Looks like we don't have anything thing need to do here.
+ // All measurement report already finished in AddBeaconReport
+ // The length is in the FrameReportLen
+
+ // reset Beacon index for next beacon request
+ pAd->StaCfg.LastBssIndex = 0xff;
+
+ // reset to idle state
+ pAd->Mlme.AironetMachine.CurrState = AIRONET_IDLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("BeaconReportAction <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+ Index Current BSSID in CCXBsstab entry index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetAddBeaconReport(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG Index,
+ IN PMLME_QUEUE_ELEM pElem)
+{
+ PVOID pMsg;
+ PUCHAR pSrc, pDest;
+ UCHAR ReqIdx;
+ ULONG MsgLen;
+ USHORT Length;
+ PFRAME_802_11 pFrame;
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PEID_STRUCT pEid;
+ PBEACON_REPORT pBeaconReport;
+ PBSS_ENTRY pBss;
+
+ // 0. Setup pointer for processing beacon & probe response
+ pMsg = pElem->Msg;
+ MsgLen = pElem->MsgLen;
+ pFrame = (PFRAME_802_11) pMsg;
+ pSrc = pFrame->Octet; // Start from AP TSF
+ pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
+ ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
+
+ // 1 Check the Index, if we already create this entry, only update the average RSSI
+ if ((Index <= pAd->StaCfg.LastBssIndex) && (pAd->StaCfg.LastBssIndex != 0xff))
+ {
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.BssReportOffset[Index]];
+ // Point to bss report information
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pBeaconReport = (PBEACON_REPORT) pDest;
+
+ // Update Rx power, in dBm
+ // Get the original RSSI readback from BBP
+ pBeaconReport->RxPower += pAd->BbpRssiToDbmDelta;
+ // Average the Rssi reading
+ pBeaconReport->RxPower = (pBeaconReport->RxPower + pBss->Rssi) / 2;
+ // Get to dBm format
+ pBeaconReport->RxPower -= pAd->BbpRssiToDbmDelta;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
+ pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
+ pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+ DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld] Rssi %d, Avg Rssi %d\n", Index, (pBss->Rssi - pAd->BbpRssiToDbmDelta), pBeaconReport->RxPower - 256));
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.BssReportOffset[Index]));
+
+ // Update other information here
+
+ // Done
+ return;
+ }
+
+ // 2. Update reported Index
+ pAd->StaCfg.LastBssIndex = Index;
+
+ // 3. Setup the buffer address for copying this BSSID into reporting frame
+ // The offset should start after 802.11 header and report frame header.
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+
+ // 4. Save the start offset of each Bss in report frame
+ pAd->StaCfg.BssReportOffset[Index] = pAd->StaCfg.FrameReportLen;
+
+ // 5. Fill Measurement report fields
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ pReport->Length = 0;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_BEACON_REQ;
+ Length = sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+
+ // 6. Start thebeacon report format
+ pBeaconReport = (PBEACON_REPORT) pDest;
+ pDest += sizeof(BEACON_REPORT);
+ Length += sizeof(BEACON_REPORT);
+
+ // 7. Copy Channel number
+ pBeaconReport->Channel = pBss->Channel;
+ pBeaconReport->Spare = 0;
+ pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
+ pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
+ // 8. Rx power, in dBm
+ pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Bssid %02x:%02x:%02x:%02x:%02x:%02x ",
+ pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2],
+ pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+ DBGPRINT(RT_DEBUG_TRACE, ("RxPower[%ld], Rssi %d\n", Index, pBeaconReport->RxPower - 256));
+ DBGPRINT(RT_DEBUG_TRACE, ("FrameReportLen = %d\n", pAd->StaCfg.FrameReportLen));
+
+ pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
+ COPY_MAC_ADDR(pBeaconReport->BSSID, pFrame->Hdr.Addr3);
+ NdisMoveMemory(pBeaconReport->ParentTSF, pSrc, 4);
+ NdisMoveMemory(pBeaconReport->TargetTSF, &pElem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pBeaconReport->TargetTSF[4], &pElem->TimeStamp.u.HighPart, 4);
+
+ // 9. Skip the beacon frame and offset to start of capabilityinfo since we already processed capabilityinfo
+ pSrc += (TIMESTAMP_LEN + 2);
+ pBeaconReport->CapabilityInfo = *(USHORT *)pSrc;
+
+ // 10. Point to start of element ID
+ pSrc += 2;
+ pEid = (PEID_STRUCT) pSrc;
+
+ // 11. Start process all variable Eid oayload and add the appropriate to the frame report
+ while (((PUCHAR) pEid + pEid->Len + 1) < ((PUCHAR) pFrame + MsgLen))
+ {
+ // Only limited EID are required to report for CCX 2. It includes SSID, Supported rate,
+ // FH paramenter set, DS parameter set, CF parameter set, IBSS parameter set,
+ // TIM (report first 4 bytes only, radio measurement capability
+ switch (pEid->Eid)
+ {
+ case IE_SSID:
+ case IE_SUPP_RATES:
+ case IE_FH_PARM:
+ case IE_DS_PARM:
+ case IE_CF_PARM:
+ case IE_IBSS_PARM:
+ NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+ pDest += (pEid->Len + 2);
+ Length += (pEid->Len + 2);
+ break;
+
+ case IE_MEASUREMENT_CAPABILITY:
+ // Since this IE is duplicated with WPA security IE, we has to do sanity check before
+ // recognize it.
+ // 1. It also has fixed 6 bytes IE length.
+ if (pEid->Len != 6)
+ break;
+ // 2. Check the Cisco Aironet OUI
+ if (NdisEqualMemory(CISCO_OUI, (pSrc + 2), 3))
+ {
+ // Matched, this is what we want
+ NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+ pDest += (pEid->Len + 2);
+ Length += (pEid->Len + 2);
+ }
+ break;
+
+ case IE_TIM:
+ if (pEid->Len > 4)
+ {
+ // May truncate and report the first 4 bytes only, with the eid & len, total should be 6
+ NdisMoveMemory(pDest, pEid, 6);
+ pDest += 6;
+ Length += 6;
+ }
+ else
+ {
+ NdisMoveMemory(pDest, pEid, pEid->Len + 2);
+ pDest += (pEid->Len + 2);
+ Length += (pEid->Len + 2);
+ }
+ break;
+
+ default:
+ break;
+ }
+ // 12. Move to next element ID
+ pSrc += (2 + pEid->Len);
+ pEid = (PEID_STRUCT) pSrc;
+ }
+
+ // 13. Update the length in the header, not include EID and length
+ pReport->Length = Length - 4;
+
+ // 14. Update the frame report buffer data length
+ pAd->StaCfg.FrameReportLen += Length;
+ DBGPRINT(RT_DEBUG_TRACE, ("FR len = %d\n", pAd->StaCfg.FrameReportLen));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+
+ Arguments:
+ Index Current BSSID in CCXBsstab entry index
+
+ Return Value:
+
+ Note:
+
+ ========================================================================
+*/
+VOID AironetCreateBeaconReportFromBssTable(
+ IN PRTMP_ADAPTER pAd)
+{
+ PMEASUREMENT_REPORT_ELEMENT pReport;
+ PBEACON_REPORT pBeaconReport;
+ UCHAR Index, ReqIdx;
+ USHORT Length;
+ PUCHAR pDest;
+ PBSS_ENTRY pBss;
+
+ // 0. setup base pointer
+ ReqIdx = pAd->StaCfg.CurrentRMReqIdx;
+
+ for (Index = 0; Index < pAd->StaCfg.CCXBssTab.BssNr; Index++)
+ {
+ // 1. Setup the buffer address for copying this BSSID into reporting frame
+ // The offset should start after 802.11 header and report frame header.
+ pDest = (PUCHAR) &pAd->StaCfg.FrameReportBuf[pAd->StaCfg.FrameReportLen];
+ pBss = (PBSS_ENTRY) &pAd->StaCfg.CCXBssTab.BssEntry[Index];
+ Length = 0;
+
+ // 2. Fill Measurement report fields
+ pReport = (PMEASUREMENT_REPORT_ELEMENT) pDest;
+ pReport->Eid = IE_MEASUREMENT_REPORT;
+ pReport->Length = 0;
+ pReport->Token = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Token;
+ pReport->Mode = pAd->StaCfg.MeasurementRequest[ReqIdx].ReqElem.Mode;
+ pReport->Type = MSRN_TYPE_BEACON_REQ;
+ Length = sizeof(MEASUREMENT_REPORT_ELEMENT);
+ pDest += sizeof(MEASUREMENT_REPORT_ELEMENT);
+
+ // 3. Start the beacon report format
+ pBeaconReport = (PBEACON_REPORT) pDest;
+ pDest += sizeof(BEACON_REPORT);
+ Length += sizeof(BEACON_REPORT);
+
+ // 4. Copy Channel number
+ pBeaconReport->Channel = pBss->Channel;
+ pBeaconReport->Spare = 0;
+ pBeaconReport->Duration = pAd->StaCfg.MeasurementRequest[ReqIdx].Measurement.Duration;
+ pBeaconReport->PhyType = ((pBss->SupRateLen+pBss->ExtRateLen > 4) ? PHY_ERP : PHY_DSS);
+ pBeaconReport->RxPower = pBss->Rssi - pAd->BbpRssiToDbmDelta;
+ pBeaconReport->BeaconInterval = pBss->BeaconPeriod;
+ pBeaconReport->CapabilityInfo = pBss->CapabilityInfo;
+ COPY_MAC_ADDR(pBeaconReport->BSSID, pBss->Bssid);
+ NdisMoveMemory(pBeaconReport->ParentTSF, pBss->PTSF, 4);
+ NdisMoveMemory(pBeaconReport->TargetTSF, pBss->TTSF, 8);
+
+ // 5. Create SSID
+ *pDest++ = 0x00;
+ *pDest++ = pBss->SsidLen;
+ NdisMoveMemory(pDest, pBss->Ssid, pBss->SsidLen);
+ pDest += pBss->SsidLen;
+ Length += (2 + pBss->SsidLen);
+
+ // 6. Create SupportRates
+ *pDest++ = 0x01;
+ *pDest++ = pBss->SupRateLen;
+ NdisMoveMemory(pDest, pBss->SupRate, pBss->SupRateLen);
+ pDest += pBss->SupRateLen;
+ Length += (2 + pBss->SupRateLen);
+
+ // 7. DS Parameter
+ *pDest++ = 0x03;
+ *pDest++ = 1;
+ *pDest++ = pBss->Channel;
+ Length += 3;
+
+ // 8. IBSS parameter if presents
+ if (pBss->BssType == BSS_ADHOC)
+ {
+ *pDest++ = 0x06;
+ *pDest++ = 2;
+ *(PUSHORT) pDest = pBss->AtimWin;
+ pDest += 2;
+ Length += 4;
+ }
+
+ // 9. Update length field, not include EID and length
+ pReport->Length = Length - 4;
+
+ // 10. Update total frame size
+ pAd->StaCfg.FrameReportLen += Length;
+ }
+}
diff --git a/drivers/staging/rt3070/sta/assoc.c b/drivers/staging/rt3070/sta/assoc.c
new file mode 100644
index 00000000000..5c33a895bf7
--- /dev/null
+++ b/drivers/staging/rt3070/sta/assoc.c
@@ -0,0 +1,2060 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ assoc.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-9-3 porting from RT2500
+*/
+#include "../rt_config.h"
+
+UCHAR CipherWpaTemplate[] = {
+ 0xdd, // WPA IE
+ 0x16, // Length
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x01 // authentication
+ };
+
+UCHAR CipherWpa2Template[] = {
+ 0x30, // RSN IE
+ 0x14, // Length
+ 0x01, 0x00, // Version
+ 0x00, 0x0f, 0xac, 0x02, // group cipher, TKIP
+ 0x01, 0x00, // number of pairwise
+ 0x00, 0x0f, 0xac, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x0f, 0xac, 0x02, // authentication
+ 0x00, 0x00, // RSN capability
+ };
+
+UCHAR Ccx2IeInfo[] = { 0x00, 0x40, 0x96, 0x03, 0x02};
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, Trans, MAX_ASSOC_STATE, MAX_ASSOC_MSG, (STATE_MACHINE_FUNC)Drop, ASSOC_IDLE, ASSOC_MACHINE_BASE);
+
+ // first column
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)MlmeAssocReqAction);
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)MlmeReassocReqAction);
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)MlmeDisassocReqAction);
+ StateMachineSetAction(S, ASSOC_IDLE, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+
+ // second column
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
+ //
+ // Patch 3Com AP MOde:3CRWE454G72
+ // We send Assoc request frame to this AP, it always send Reassoc Rsp not Associate Rsp.
+ //
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerAssocRspAction);
+ StateMachineSetAction(S, ASSOC_WAIT_RSP, MT2_ASSOC_TIMEOUT, (STATE_MACHINE_FUNC)AssocTimeoutAction);
+
+ // third column
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_REASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
+ //
+ // Patch, AP doesn't send Reassociate Rsp frame to Station.
+ //
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_PEER_ASSOC_RSP, (STATE_MACHINE_FUNC)PeerReassocRspAction);
+ StateMachineSetAction(S, REASSOC_WAIT_RSP, MT2_REASSOC_TIMEOUT, (STATE_MACHINE_FUNC)ReassocTimeoutAction);
+
+ // fourth column
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_ASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAssoc);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_REASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenReassoc);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_MLME_DISASSOC_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenDisassociate);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_PEER_DISASSOC_REQ, (STATE_MACHINE_FUNC)PeerDisassocAction);
+ StateMachineSetAction(S, DISASSOC_WAIT_RSP, MT2_DISASSOC_TIMEOUT, (STATE_MACHINE_FUNC)DisassocTimeoutAction);
+
+ // initialize the timer
+ RTMPInitTimer(pAd, &pAd->MlmeAux.AssocTimer, GET_TIMER_FUNCTION(AssocTimeout), pAd, FALSE);
+ RTMPInitTimer(pAd, &pAd->MlmeAux.ReassocTimer, GET_TIMER_FUNCTION(ReassocTimeout), pAd, FALSE);
+ RTMPInitTimer(pAd, &pAd->MlmeAux.DisassocTimer, GET_TIMER_FUNCTION(DisassocTimeout), pAd, FALSE);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Association timeout procedure. After association timeout, this function
+ will be called and it will put a message into the MLME queue
+ Parameters:
+ Standard timer parameters
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocTimeout(IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_ASSOC_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Reassociation timeout procedure. After reassociation timeout, this
+ function will be called and put a message into the MLME queue
+ Parameters:
+ Standard timer parameters
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID ReassocTimeout(IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_REASSOC_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Disassociation timeout procedure. After disassociation timeout, this
+ function will be called and put a message into the MLME queue
+ Parameters:
+ Standard timer parameters
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID DisassocTimeout(IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_DISASSOC_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ mlme assoc req handling procedure
+ Parameters:
+ Adapter - Adapter pointer
+ Elem - MLME Queue Element
+ Pre:
+ the station has been authenticated and the following information is stored in the config
+ -# SSID
+ -# supported rates and their length
+ -# listen interval (Adapter->StaCfg.default_listen_count)
+ -# Transmit power (Adapter->StaCfg.tx_power)
+ Post :
+ -# An association request frame is generated and sent to the air
+ -# Association timer starts
+ -# Association state -> ASSOC_WAIT_RSP
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeAssocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR ApAddr[6];
+ HEADER_802_11 AssocHdr;
+ UCHAR Ccx2Len = 5;
+ UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+ USHORT ListenIntv;
+ ULONG Timeout;
+ USHORT CapabilityInfo;
+ BOOLEAN TimerCancelled;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ ULONG tmp;
+ USHORT VarIesOffset;
+ UCHAR CkipFlag;
+ UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
+ UCHAR AironetCkipIe = IE_AIRONET_CKIP;
+ UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
+ UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
+ UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
+ UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+ USHORT Status;
+
+ // Block all authentication request durning WPA block period
+ if (pAd->StaCfg.bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block Assoc request durning WPA block period!\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ }
+ // check sanity first
+ else if (MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
+ {
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
+
+ // Get an unused nonpaged memory
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() allocate memory failed \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ return;
+ }
+
+ // Add by James 03/06/27
+ pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+ // Association don't need to report MAC address
+ pAd->StaCfg.AssocInfo.AvailableRequestFixedIEs =
+ NDIS_802_11_AI_REQFI_CAPABILITIES | NDIS_802_11_AI_REQFI_LISTENINTERVAL;
+ pAd->StaCfg.AssocInfo.RequestFixedIEs.Capabilities = CapabilityInfo;
+ pAd->StaCfg.AssocInfo.RequestFixedIEs.ListenInterval = ListenIntv;
+ // Only reassociate need this
+ //COPY_MAC_ADDR(pAd->StaCfg.AssocInfo.RequestFixedIEs.CurrentAPAddress, ApAddr);
+ pAd->StaCfg.AssocInfo.OffsetRequestIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+
+ NdisZeroMemory(pAd->StaCfg.ReqVarIEs, MAX_VIE_LEN);
+ // First add SSID
+ VarIesOffset = 0;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SsidIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SsidLen, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ VarIesOffset += pAd->MlmeAux.SsidLen;
+
+ // Second add Supported rates
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &SupRateIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->MlmeAux.SupRateLen, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->MlmeAux.SupRate, pAd->MlmeAux.SupRateLen);
+ VarIesOffset += pAd->MlmeAux.SupRateLen;
+ // End Add by James
+
+ if ((pAd->CommonCfg.Channel > 14) &&
+ (pAd->CommonCfg.bIEEE80211H == TRUE))
+ CapabilityInfo |= 0x0100;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send ASSOC request...\n"));
+ MgtMacHeaderInit(pAd, &AssocHdr, SUBTYPE_ASSOC_REQ, 0, ApAddr, ApAddr);
+
+ // Build basic frame first
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AssocHdr,
+ 2, &CapabilityInfo,
+ 2, &ListenIntv,
+ 1, &SsidIe,
+ 1, &pAd->MlmeAux.SsidLen,
+ pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // HT
+ if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+ if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
+ {
+ HtLen = SIZE_HT_CAP_IE + 4;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ else
+ {
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &pAd->MlmeAux.HtCapabilityLen,
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+#else
+ NdisZeroMemory(&HtCapabilityTmp, sizeof(HT_CAPABILITY_IE));
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->MlmeAux.HtCapability, pAd->MlmeAux.HtCapabilityLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &pAd->MlmeAux.HtCapabilityLen,
+ pAd->MlmeAux.HtCapabilityLen,&HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+ }
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
+ // Case I: (Aggregation + Piggy-Back)
+ // 1. user enable aggregation, AND
+ // 2. Mac support piggy-back
+ // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
+ // Case II: (Aggregation)
+ // 1. user enable aggregation, AND
+ // 2. AP annouces it's AGGREGATION-capable in BEACON
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ }
+ else
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x06, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+
+ if (pAd->MlmeAux.APEdcaParm.bValid)
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
+ {
+ QBSS_STA_INFO_PARM QosInfo;
+
+ NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+ QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
+ QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
+ QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
+ QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
+ QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
+ WmeIe[8] |= *(PUCHAR)&QosInfo;
+ }
+ else
+ {
+ // The Parameter Set Count is set to ¡§0¡¨ in the association request frames
+ // WmeIe[8] |= (pAd->MlmeAux.APEdcaParm.EdcaUpdateCount & 0x0f);
+ }
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 9, &WmeIe[0],
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ //
+ // Let WPA(#221) Element ID on the end of this association frame.
+ // Otherwise some AP will fail on parsing Element ID and set status fail on Assoc Rsp.
+ // For example: Put Vendor Specific IE on the front of WPA IE.
+ // This happens on AP (Model No:Linksys WRK54G)
+ //
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+ )
+ )
+ {
+ UCHAR RSNIe = IE_WPA;
+
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+ {
+ RSNIe = IE_WPA2;
+ }
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP != 1)
+#endif // SIOCSIWGENIE //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+
+ // Check for WPA PMK cache list
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2)
+ {
+ INT idx;
+ BOOLEAN FoundPMK = FALSE;
+ // Search chched PMKID, append it if existed
+ for (idx = 0; idx < PMKID_NO; idx++)
+ {
+ if (NdisEqualMemory(ApAddr, &pAd->StaCfg.SavedPMK[idx].BSSID, 6))
+ {
+ FoundPMK = TRUE;
+ break;
+ }
+ }
+
+ if (FoundPMK)
+ {
+ // Set PMK number
+ *(PUSHORT) &pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len] = 1;
+ NdisMoveMemory(&pAd->StaCfg.RSN_IE[pAd->StaCfg.RSNIE_Len + 2], &pAd->StaCfg.SavedPMK[idx].PMKID, 16);
+ pAd->StaCfg.RSNIE_Len += 18;
+ }
+ }
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP == 1)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ }
+ else
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &RSNIe,
+ 1, &pAd->StaCfg.RSNIE_Len,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ }
+
+ FrameLen += tmp;
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP != 1)
+#endif
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ {
+ // Append Variable IE
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &RSNIe, 1);
+ VarIesOffset += 1;
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, &pAd->StaCfg.RSNIE_Len, 1);
+ VarIesOffset += 1;
+ }
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+ VarIesOffset += pAd->StaCfg.RSNIE_Len;
+
+ // Set Variable IEs Length
+ pAd->StaCfg.ReqVarIELen = VarIesOffset;
+ }
+
+ // We have update that at PeerBeaconAtJoinRequest()
+ CkipFlag = pAd->StaCfg.CkipFlag;
+ if (CkipFlag != 0)
+ {
+ NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
+ CkipNegotiationBuffer[2] = 0x66;
+ // Make it try KP & MIC, since we have to follow the result from AssocRsp
+ CkipNegotiationBuffer[8] = 0x18;
+ CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
+ CkipFlag = 0x18;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetCkipIe,
+ 1, &AironetCkipLen,
+ AironetCkipLen, CkipNegotiationBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ // Add CCX v2 request if CCX2 admin state is on
+ if (pAd->StaCfg.CCXControl.field.Enable == 1)
+ {
+
+ //
+ // Add AironetIPAddressIE for Cisco CCX 2.X
+ // Add CCX Version
+ //
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetIPAddressIE,
+ 1, &AironetIPAddressLen,
+ AironetIPAddressLen, AironetIPAddressBuffer,
+ 1, &Ccx2Ie,
+ 1, &Ccx2Len,
+ Ccx2Len, Ccx2IeInfo,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ //
+ // Add CipherSuite CCKM or LeapTkip if setting.
+ //
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd))
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ CipherSuiteCiscoCCKMLen, CipherSuiteCiscoCCKM,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ // Third add RSN
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen); //Save CipherSuite
+ VarIesOffset += CipherSuiteCiscoCCKMLen;
+ }
+ else if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled))
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ CipherSuiteCCXTkipLen, CipherSuiteCCXTkip,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ // Third add RSN
+ NdisMoveMemory(pAd->StaCfg.ReqVarIEs + VarIesOffset, CipherSuiteCCXTkip, CipherSuiteCCXTkipLen);
+ VarIesOffset += CipherSuiteCCXTkipLen;
+ }
+#endif // LEAP_SUPPORT //
+
+ // Add by James 03/06/27
+ // Set Variable IEs Length
+ pAd->StaCfg.ReqVarIELen = VarIesOffset;
+ pAd->StaCfg.AssocInfo.RequestIELength = VarIesOffset;
+
+ // OffsetResponseIEs follow ReqVarIE
+ pAd->StaCfg.AssocInfo.OffsetResponseIEs = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION) + pAd->StaCfg.ReqVarIELen;
+ // End Add by James
+ }
+
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.AssocTimer, Timeout);
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_WAIT_RSP;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeAssocReqAction() sanity check failed. BUG!!!!!! \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ }
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ mlme reassoc req handling procedure
+ Parameters:
+ Elem -
+ Pre:
+ -# SSID (Adapter->StaCfg.ssid[])
+ -# BSSID (AP address, Adapter->StaCfg.bssid)
+ -# Supported rates (Adapter->StaCfg.supported_rates[])
+ -# Supported rates length (Adapter->StaCfg.supported_rates_len)
+ -# Tx power (Adapter->StaCfg.tx_power)
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeReassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR ApAddr[6];
+ HEADER_802_11 ReassocHdr;
+ UCHAR Ccx2Len = 5;
+ UCHAR WmeIe[9] = {IE_VENDOR_SPECIFIC, 0x07, 0x00, 0x50, 0xf2, 0x02, 0x00, 0x01, 0x00};
+ USHORT CapabilityInfo, ListenIntv;
+ ULONG Timeout;
+ ULONG FrameLen = 0;
+ BOOLEAN TimerCancelled;
+ NDIS_STATUS NStatus;
+ ULONG tmp;
+ PUCHAR pOutBuffer = NULL;
+//CCX 2.X
+#ifdef LEAP_SUPPORT
+ UCHAR CkipFlag;
+ UCHAR CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH];
+ UCHAR AironetCkipIe = IE_AIRONET_CKIP;
+ UCHAR AironetCkipLen = CKIP_NEGOTIATION_LENGTH;
+ UCHAR AironetIPAddressIE = IE_AIRONET_IPADDRESS;
+ UCHAR AironetIPAddressLen = AIRONET_IPADDRESS_LENGTH;
+ UCHAR AironetIPAddressBuffer[AIRONET_IPADDRESS_LENGTH] = {0x00, 0x40, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00};
+ UCHAR AironetCCKMReassocIE = IE_AIRONET_CCKMREASSOC;
+ UCHAR AironetCCKMReassocLen = AIRONET_CCKMREASSOC_LENGTH;
+ UCHAR AironetCCKMReassocBuffer[AIRONET_CCKMREASSOC_LENGTH];
+ UCHAR AironetOUI[] = {0x00, 0x40, 0x96, 0x00};
+ UCHAR MICMN[16];
+ UCHAR CalcMicBuffer[80];
+ ULONG CalcMicBufferLen = 0;
+#endif // LEAP_SUPPORT //
+ USHORT Status;
+
+ // Block all authentication request durning WPA block period
+ if (pAd->StaCfg.bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Block ReAssoc request durning WPA block period!\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+ // the parameters are the same as the association
+ else if(MlmeAssocReqSanity(pAd, Elem->Msg, Elem->MsgLen, ApAddr, &CapabilityInfo, &Timeout, &ListenIntv))
+ {
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() allocate memory failed \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ return;
+ }
+
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, ApAddr);
+
+ // make frame, use bssid as the AP address??
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send RE-ASSOC request...\n"));
+ MgtMacHeaderInit(pAd, &ReassocHdr, SUBTYPE_REASSOC_REQ, 0, ApAddr, ApAddr);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &ReassocHdr,
+ 2, &CapabilityInfo,
+ 2, &ListenIntv,
+ MAC_ADDR_LEN, ApAddr,
+ 1, &SsidIe,
+ 1, &pAd->MlmeAux.SsidLen,
+ pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ if (pAd->MlmeAux.APEdcaParm.bValid)
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->MlmeAux.APEdcaParm.bAPSDCapable)
+ {
+ QBSS_STA_INFO_PARM QosInfo;
+
+ NdisZeroMemory(&QosInfo, sizeof(QBSS_STA_INFO_PARM));
+ QosInfo.UAPSD_AC_BE = pAd->CommonCfg.bAPSDAC_BE;
+ QosInfo.UAPSD_AC_BK = pAd->CommonCfg.bAPSDAC_BK;
+ QosInfo.UAPSD_AC_VI = pAd->CommonCfg.bAPSDAC_VI;
+ QosInfo.UAPSD_AC_VO = pAd->CommonCfg.bAPSDAC_VO;
+ QosInfo.MaxSPLength = pAd->CommonCfg.MaxSPLength;
+ WmeIe[8] |= *(PUCHAR)&QosInfo;
+ }
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 9, &WmeIe[0],
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // HT
+ if ((pAd->MlmeAux.HtCapabilityLen > 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+ if (pAd->StaActive.SupportedPhyInfo.bPreNHt == TRUE)
+ {
+ HtLen = SIZE_HT_CAP_IE + 4;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 1, &HtLen,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &pAd->MlmeAux.HtCapabilityLen,
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // add Ralink proprietary IE to inform AP this STA is going to use AGGREGATION or PIGGY-BACK+AGGREGATION
+ // Case I: (Aggregation + Piggy-Back)
+ // 1. user enable aggregation, AND
+ // 2. Mac support piggy-back
+ // 3. AP annouces it's PIGGY-BACK+AGGREGATION-capable in BEACON
+ // Case II: (Aggregation)
+ // 1. user enable aggregation, AND
+ // 2. AP annouces it's AGGREGATION-capable in BEACON
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && ((pAd->MlmeAux.APRalinkIe & 0x00000003) == 3))
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x03, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x01, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+ }
+ else
+ {
+ ULONG TmpLen;
+ UCHAR RalinkIe[9] = {IE_VENDOR_SPECIFIC, 7, 0x00, 0x0c, 0x43, 0x04, 0x00, 0x00, 0x00};
+ MakeOutgoingFrame(pOutBuffer+FrameLen, &TmpLen,
+ 9, RalinkIe,
+ END_OF_ARGS);
+ FrameLen += TmpLen;
+ }
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ {
+ CkipFlag = pAd->StaCfg.CkipFlag; // We have update that at PeerBeaconAtJoinRequest()
+ if (CkipFlag != 0)
+ {
+ NdisZeroMemory(CkipNegotiationBuffer, CKIP_NEGOTIATION_LENGTH);
+ CkipNegotiationBuffer[2] = 0x66;
+ // Make it try KP & MIC, since we have to follow the result from AssocRsp
+ CkipNegotiationBuffer[8] = 0x18;
+ CkipNegotiationBuffer[CKIP_NEGOTIATION_LENGTH - 1] = 0x22;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetCkipIe,
+ 1, &AironetCkipLen,
+ AironetCkipLen, CkipNegotiationBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetIPAddressIE,
+ 1, &AironetIPAddressLen,
+ AironetIPAddressLen, AironetIPAddressBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ //
+ // The RN is incremented before each reassociation request.
+ //
+ pAd->StaCfg.CCKMRN++;
+ //
+ // Calculate MIC = hmac-md5(krk, STA-ID|BSSID|RSNIE|TSF|RN);
+ //
+ COPY_MAC_ADDR(CalcMicBuffer, pAd->CurrentAddress);
+ CalcMicBufferLen = MAC_ADDR_LEN;
+ COPY_MAC_ADDR(CalcMicBuffer + CalcMicBufferLen, pAd->MlmeAux.Bssid);
+ CalcMicBufferLen += MAC_ADDR_LEN;
+ NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, CipherSuiteCiscoCCKM, CipherSuiteCiscoCCKMLen);
+ CalcMicBufferLen += CipherSuiteCiscoCCKMLen;
+ NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR) &pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp));
+ CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMBeaconAtJoinTimeStamp);
+ NdisMoveMemory(CalcMicBuffer + CalcMicBufferLen, (PUCHAR)&pAd->StaCfg.CCKMRN, sizeof(pAd->StaCfg.CCKMRN));
+ CalcMicBufferLen += sizeof(pAd->StaCfg.CCKMRN);
+ hmac_md5(pAd->StaCfg.KRK, LEN_EAP_MICK, CalcMicBuffer, CalcMicBufferLen, MICMN);
+
+ //
+ // fill up CCKM reassociation request element
+ //
+ NdisMoveMemory(AironetCCKMReassocBuffer, AironetOUI, 4);
+ NdisMoveMemory(AironetCCKMReassocBuffer + 4, (PUCHAR)&pAd->StaCfg.CCKMBeaconAtJoinTimeStamp, 8);
+ NdisMoveMemory(AironetCCKMReassocBuffer + 12, (PUCHAR) &pAd->StaCfg.CCKMRN, 4);
+ NdisMoveMemory(AironetCCKMReassocBuffer +16, MICMN, 8);
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &AironetCCKMReassocIE,
+ 1, &AironetCCKMReassocLen,
+ AironetCCKMReassocLen, AironetCCKMReassocBuffer,
+ END_OF_ARGS);
+ FrameLen += tmp;
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ CipherSuiteCiscoCCKMLen,CipherSuiteCiscoCCKM,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+#endif // LEAP_SUPPORT //
+
+ // Add CCX v2 request if CCX2 admin state is on
+ if (pAd->StaCfg.CCXControl.field.Enable == 1)
+ {
+ //
+ // Add CCX Version
+ //
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &Ccx2Ie,
+ 1, &Ccx2Len,
+ Ccx2Len, Ccx2IeInfo,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.ReassocTimer, Timeout); /* in mSec */
+ pAd->Mlme.AssocMachine.CurrState = REASSOC_WAIT_RSP;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("ASSOC - MlmeReassocReqAction() sanity check failed. BUG!!!! \n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ Upper layer issues disassoc request
+ Parameters:
+ Elem -
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDisassocReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PMLME_DISASSOC_REQ_STRUCT pDisassocReq;
+ HEADER_802_11 DisassocHdr;
+ PHEADER_802_11 pDisassocHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ BOOLEAN TimerCancelled;
+ ULONG Timeout = 0;
+ USHORT Status;
+
+#ifdef QOS_DLS_SUPPORT
+ // send DLS-TEAR_DOWN message,
+ if (pAd->CommonCfg.bDLSCapable)
+ {
+ UCHAR i;
+
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ }
+ }
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ // skip sanity check
+ pDisassocReq = (PMLME_DISASSOC_REQ_STRUCT)(Elem->Msg);
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - MlmeDisassocReqAction() allocate memory failed\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+ return;
+ }
+
+
+
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &TimerCancelled);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Send DISASSOC request[BSSID::%02x:%02x:%02x:%02x:%02x:%02x (Reason=%d)\n",
+ pDisassocReq->Addr[0], pDisassocReq->Addr[1], pDisassocReq->Addr[2],
+ pDisassocReq->Addr[3], pDisassocReq->Addr[4], pDisassocReq->Addr[5], pDisassocReq->Reason));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pDisassocReq->Addr, pDisassocReq->Addr); // patch peap ttls switching issue
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DisassocHdr,
+ 2, &pDisassocReq->Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ // To patch Instance and Buffalo(N) AP
+ // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
+ // Therefore, we send both of them.
+ pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+ pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DisassocReason = REASON_DISASSOC_STA_LEAVING;
+ COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pDisassocReq->Addr);
+
+ RTMPSetTimer(&pAd->MlmeAux.DisassocTimer, Timeout); /* in mSec */
+ pAd->Mlme.AssocMachine.CurrState = DISASSOC_WAIT_RSP;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ peer sends assoc rsp back
+ Parameters:
+ Elme - MLME message containing the received frame
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerAssocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT CapabilityInfo, Status, Aid;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+ UCHAR Addr2[MAC_ADDR_LEN];
+ BOOLEAN TimerCancelled;
+ UCHAR CkipFlag;
+ EDCA_PARM EdcaParm;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+ if (PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
+ &HtCapability,&AddHtInfo, &HtCapabilityLen,&AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
+ {
+ // The frame is for me ?
+ if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():ASSOC - receive ASSOC_RSP to me (status=%d)\n", Status));
+#ifdef DOT11_N_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspAction():MacTable [%d].AMsduSize = %d. ClientStatusFlags = 0x%lx \n",Elem->Wcid, pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+#endif // DOT11_N_SUPPORT //
+ RTMPCancelTimer(&pAd->MlmeAux.AssocTimer, &TimerCancelled);
+ if(Status == MLME_SUCCESS)
+ {
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR idx;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (idx=0; idx<SupRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
+ }
+
+ for (idx=0; idx<ExtRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
+ }
+ // go to procedure listed on page 376
+ AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
+ &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+
+ StaAddMacTableEntry(pAd, &pAd->MacTab.Content[BSSID_WCID], MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo);
+
+ pAd->StaCfg.CkipFlag = CkipFlag;
+ if (CkipFlag & 0x18)
+ {
+ NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
+ pAd->StaCfg.GIV[0] = RandomByte(pAd);
+ pAd->StaCfg.GIV[1] = RandomByte(pAd);
+ pAd->StaCfg.GIV[2] = RandomByte(pAd);
+ pAd->StaCfg.bCkipOn = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
+ }
+ }
+ else
+ {
+ // Faile on Association, we need to check the status code
+ // Is that a Rogue AP?
+#ifdef LEAP_SUPPORT
+ if ((pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP) && (Status == MLME_ALG_NOT_SUPPORT))
+ { //Possibly Rogue AP
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, pAd->MlmeAux.Bssid, LEAP_REASON_INVALID_AUTH);
+ }
+#endif // LEAP_SUPPORT //
+ }
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerAssocRspAction() sanity check fail\n"));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ peer sends reassoc rsp
+ Parametrs:
+ Elem - MLME message cntaining the received frame
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerReassocRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT CapabilityInfo;
+ USHORT Status;
+ USHORT Aid;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], SupRateLen;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRateLen;
+ UCHAR Addr2[MAC_ADDR_LEN];
+ UCHAR CkipFlag;
+ BOOLEAN TimerCancelled;
+ EDCA_PARM EdcaParm;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+ if(PeerAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &CapabilityInfo, &Status, &Aid, SupRate, &SupRateLen, ExtRate, &ExtRateLen,
+ &HtCapability, &AddHtInfo, &HtCapabilityLen, &AddHtInfoLen,&NewExtChannelOffset, &EdcaParm, &CkipFlag))
+ {
+ if(MAC_ADDR_EQUAL(Addr2, pAd->MlmeAux.Bssid)) // The frame is for me ?
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - receive REASSOC_RSP to me (status=%d)\n", Status));
+ RTMPCancelTimer(&pAd->MlmeAux.ReassocTimer, &TimerCancelled);
+
+ if(Status == MLME_SUCCESS)
+ {
+ // go to procedure listed on page 376
+ AssocPostProc(pAd, Addr2, CapabilityInfo, Aid, SupRate, SupRateLen, ExtRate, ExtRateLen,
+ &EdcaParm, &HtCapability, HtCapabilityLen, &AddHtInfo);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ union iwreq_data wrqu;
+
+ SendAssocIEsToWpaSupplicant(pAd);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ wext_notify_event_assoc(pAd);
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+ }
+
+ //
+ // Cisco Leap CCKM supported Re-association.
+ //
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ {
+ if (CCKMAssocRspSanity(pAd, Elem->Msg, Elem->MsgLen) == TRUE)
+ {
+ pAd->StaCfg.CkipFlag = CkipFlag;
+ if (CkipFlag & 0x18)
+ {
+ NdisZeroMemory(pAd->StaCfg.TxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.RxSEQ, 4);
+ NdisZeroMemory(pAd->StaCfg.CKIPMIC, 4);
+ pAd->StaCfg.GIV[0] = RandomByte(pAd);
+ pAd->StaCfg.GIV[1] = RandomByte(pAd);
+ pAd->StaCfg.GIV[2] = RandomByte(pAd);
+ pAd->StaCfg.bCkipOn = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("<CCX> pAd->StaCfg.CkipFlag = 0x%02x\n", pAd->StaCfg.CkipFlag));
+ }
+
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - CCKMAssocRspSanity() sanity check fail\n"));
+ }
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ // CkipFlag is no use for reassociate
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerReassocRspAction() sanity check fail\n"));
+ }
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ procedures on IEEE 802.11/1999 p.376
+ Parametrs:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocPostProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr2,
+ IN USHORT CapabilityInfo,
+ IN USHORT Aid,
+ IN UCHAR SupRate[],
+ IN UCHAR SupRateLen,
+ IN UCHAR ExtRate[],
+ IN UCHAR ExtRateLen,
+ IN PEDCA_PARM pEdcaParm,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN ADD_HT_INFO_IE *pAddHtInfo) // AP might use this additional ht info IE
+{
+ ULONG Idx;
+
+ pAd->MlmeAux.BssType = BSS_INFRA;
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pAddr2);
+ pAd->MlmeAux.Aid = Aid;
+ pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+#ifdef DOT11_N_SUPPORT
+ // Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on.
+ if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE))
+ {
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->Aifsn[0] = 3;
+ pEdcaParm->Aifsn[1] = 7;
+ pEdcaParm->Aifsn[2] = 2;
+ pEdcaParm->Aifsn[3] = 2;
+
+ pEdcaParm->Cwmin[0] = 4;
+ pEdcaParm->Cwmin[1] = 4;
+ pEdcaParm->Cwmin[2] = 3;
+ pEdcaParm->Cwmin[3] = 2;
+
+ pEdcaParm->Cwmax[0] = 10;
+ pEdcaParm->Cwmax[1] = 10;
+ pEdcaParm->Cwmax[2] = 4;
+ pEdcaParm->Cwmax[3] = 3;
+
+ pEdcaParm->Txop[0] = 0;
+ pEdcaParm->Txop[1] = 0;
+ pEdcaParm->Txop[2] = 96;
+ pEdcaParm->Txop[3] = 48;
+
+ }
+#endif // DOT11_N_SUPPORT //
+
+ NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, pEdcaParm, sizeof(EDCA_PARM));
+
+ // filter out un-supported rates
+ pAd->MlmeAux.SupRateLen = SupRateLen;
+ NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+
+ // filter out un-supported rates
+ pAd->MlmeAux.ExtRateLen = ExtRateLen;
+ NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+
+#ifdef DOT11_N_SUPPORT
+ if (HtCapabilityLen > 0)
+ {
+ RTMPCheckHt(pAd, BSSID_WCID, pHtCapability, pAddHtInfo);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> AP.AMsduSize = %d. ClientStatusFlags = 0x%lx \n", pAd->MacTab.Content[BSSID_WCID].AMsduSize, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> (Mmps=%d, AmsduSize=%d, )\n",
+ pAd->MacTab.Content[BSSID_WCID].MmpsMode, pAd->MacTab.Content[BSSID_WCID].AMsduSize));
+#endif // DOT11_N_SUPPORT //
+
+ // Set New WPA information
+ Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel);
+ if (Idx == BSS_NOT_FOUND)
+ {
+ DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n"));
+ }
+ else
+ {
+ // Init variable
+ pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0;
+ NdisZeroMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, MAX_LEN_OF_RSNIE);
+
+ // Store appropriate RSN_IE for WPA SM negotiation later
+ if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAd->ScanTab.BssEntry[Idx].VarIELen != 0))
+ {
+ PUCHAR pVIE;
+ USHORT len;
+ PEID_STRUCT pEid;
+
+ pVIE = pAd->ScanTab.BssEntry[Idx].VarIEs;
+ len = pAd->ScanTab.BssEntry[Idx].VarIELen;
+
+ while (len > 0)
+ {
+ pEid = (PEID_STRUCT) pVIE;
+ // For WPA/WPAPSK
+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4))
+ && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
+ pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA SM negotiation \n"));
+ }
+ // For WPA2/WPA2PSK
+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3))
+ && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ NdisMoveMemory(pAd->MacTab.Content[BSSID_WCID].RSN_IE, pVIE, (pEid->Len + 2));
+ pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = (pEid->Len + 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> Store RSN_IE for WPA2 SM negotiation \n"));
+ }
+
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+ }
+ }
+
+ if (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AssocPostProc===> no RSN_IE \n"));
+ }
+ else
+ {
+ hex_dump("RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ left part of IEEE 802.11/1999 p.374
+ Parameters:
+ Elem - MLME message containing the received frame
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDisassocAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Reason;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction()\n"));
+ if(PeerDisassocSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() Reason = %d\n", Reason));
+ if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, Addr2))
+ {
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+
+
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ // Cisco_LEAP has start a timer
+ // We should cancel it if using LEAP
+ RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
+ //Check is it mach the LEAP Authentication failed as possible a Rogue AP
+ //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Association.
+ if ((pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE) && (pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
+ {
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
+ }
+ }
+#endif // LEAP_SUPPORT //
+ //
+ // Get Current System time and Turn on AdjacentAPReport
+ //
+ NdisGetSystemUpTime(&pAd->StaCfg.CCXAdjacentAPLinkDownTime);
+ pAd->StaCfg.CCXAdjacentAPReportFlag = TRUE;
+ LinkDown(pAd, TRUE);
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - PeerDisassocAction() sanity check fail\n"));
+ }
+
+}
+
+/*
+ ==========================================================================
+ Description:
+ what the state machine will do after assoc timeout
+ Parameters:
+ Elme -
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AssocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - AssocTimeoutAction\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ what the state machine will do after reassoc timeout
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID ReassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - ReassocTimeoutAction\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ what the state machine will do after disassoc timeout
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID DisassocTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - DisassocTimeoutAction\n"));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenAssoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenAssoc(state=%ld), reset ASSOC state machine\n",
+ pAd->Mlme.AssocMachine.CurrState));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenReassoc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenReassoc(state=%ld), reset ASSOC state machine\n",
+ pAd->Mlme.AssocMachine.CurrState));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, &Status);
+}
+
+VOID InvalidStateWhenDisassociate(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - InvalidStateWhenDisassoc(state=%ld), reset ASSOC state machine\n",
+ pAd->Mlme.AssocMachine.CurrState));
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DISASSOC_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ right part of IEEE 802.11/1999 page 374
+ Note:
+ This event should never cause ASSOC state machine perform state
+ transition, and has no relationship with CNTL machine. So we separate
+ this routine as a service outside of ASSOC state transition table.
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID Cls3errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr)
+{
+ HEADER_802_11 DisassocHdr;
+ PHEADER_802_11 pDisassocHdr;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ NDIS_STATUS NStatus;
+ USHORT Reason = REASON_CLS3ERR;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ASSOC - Class 3 Error, Send DISASSOC frame\n"));
+ MgtMacHeaderInit(pAd, &DisassocHdr, SUBTYPE_DISASSOC, 0, pAddr, pAd->CommonCfg.Bssid); // patch peap ttls switching issue
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DisassocHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ // To patch Instance and Buffalo(N) AP
+ // Driver has to send deauth to Instance AP, but Buffalo(N) needs to send disassoc to reset Authenticator's state machine
+ // Therefore, we send both of them.
+ pDisassocHdr = (PHEADER_802_11)pOutBuffer;
+ pDisassocHdr->FC.SubType = SUBTYPE_DEAUTH;
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DisassocReason = REASON_CLS3ERR;
+ COPY_MAC_ADDR(pAd->StaCfg.DisassocSta, pAddr);
+}
+
+ /*
+ ==========================================================================
+ Description:
+ Switch between WEP and CKIP upon new association up.
+ Parameters:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID SwitchBetweenWepAndCkip(
+ IN PRTMP_ADAPTER pAd)
+{
+ int i;
+ SHAREDKEY_MODE_STRUC csr1;
+
+ // if KP is required. change the CipherAlg in hardware shard key table from WEP
+ // to CKIP. else remain as WEP
+ if (pAd->StaCfg.bCkipOn && (pAd->StaCfg.CkipFlag & 0x10))
+ {
+ // modify hardware key table so that MAC use correct algorithm to decrypt RX
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
+ if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key0CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_CKIP128;
+
+ if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key1CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_CKIP128;
+
+ if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key2CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_CKIP128;
+
+ if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP64)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP64;
+ else if (csr1.field.Bss0Key3CipherAlg == CIPHER_WEP128)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_CKIP128;
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
+
+ // modify software key table so that driver can specify correct algorithm in TXD upon TX
+ for (i=0; i<SHARE_KEY_NUM; i++)
+ {
+ if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP64)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP64;
+ else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_WEP128)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_CKIP128;
+ }
+ }
+
+ // else if KP NOT inused. change the CipherAlg in hardware shard key table from CKIP
+ // to WEP.
+ else
+ {
+ // modify hardware key table so that MAC use correct algorithm to decrypt RX
+ RTMP_IO_READ32(pAd, SHARED_KEY_MODE_BASE, &csr1.word);
+ if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key0CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key0CipherAlg = CIPHER_WEP128;
+
+ if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key1CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key1CipherAlg = CIPHER_WEP128;
+
+ if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key2CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key2CipherAlg = CIPHER_WEP128;
+
+ if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP64)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_WEP64;
+ else if (csr1.field.Bss0Key3CipherAlg == CIPHER_CKIP128)
+ csr1.field.Bss0Key3CipherAlg = CIPHER_WEP128;
+
+ // modify software key table so that driver can specify correct algorithm in TXD upon TX
+ for (i=0; i<SHARE_KEY_NUM; i++)
+ {
+ if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP64)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP64;
+ else if (pAd->SharedKey[BSS0][i].CipherAlg == CIPHER_CKIP128)
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_WEP128;
+ }
+
+ //
+ // On WPA-NONE, must update CipherAlg.
+ // Because the OID_802_11_WEP_STATUS was been set after OID_802_11_ADD_KEY
+ // and CipherAlg will be CIPHER_NONE by Windows ZeroConfig.
+ // So we need to update CipherAlg after connect.
+ //
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ for (i = 0; i < SHARE_KEY_NUM; i++)
+ {
+ if (pAd->SharedKey[BSS0][i].KeyLen != 0)
+ {
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+ {
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_TKIP;
+ }
+ else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_AES;
+ }
+ }
+ else
+ {
+ pAd->SharedKey[BSS0][i].CipherAlg = CIPHER_NONE;
+ }
+ }
+
+ csr1.field.Bss0Key0CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+ csr1.field.Bss0Key1CipherAlg = pAd->SharedKey[BSS0][1].CipherAlg;
+ csr1.field.Bss0Key2CipherAlg = pAd->SharedKey[BSS0][2].CipherAlg;
+ csr1.field.Bss0Key3CipherAlg = pAd->SharedKey[BSS0][3].CipherAlg;
+ }
+ RTMP_IO_WRITE32(pAd, SHARED_KEY_MODE_BASE, csr1.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("SwitchBetweenWepAndCkip: modify BSS0 cipher to %s\n", CipherName[csr1.field.Bss0Key0CipherAlg]));
+ }
+}
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+VOID SendAssocIEsToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd)
+{
+ union iwreq_data wrqu;
+ unsigned char custom[IW_CUSTOM_MAX] = {0};
+
+ if ((pAd->StaCfg.ReqVarIELen + 17) <= IW_CUSTOM_MAX)
+ {
+ sprintf(custom, "ASSOCINFO_ReqIEs=");
+ NdisMoveMemory(custom+17, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.length = pAd->StaCfg.ReqVarIELen + 17;
+ wrqu.data.flags = RT_REQIE_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_ASSOCINFO_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen + 17 > MAX_CUSTOM_LEN\n"));
+
+ return;
+}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+int wext_notify_event_assoc(
+ IN RTMP_ADAPTER *pAd)
+{
+ union iwreq_data wrqu;
+ char custom[IW_CUSTOM_MAX] = {0};
+
+#if WIRELESS_EXT > 17
+ if (pAd->StaCfg.ReqVarIELen <= IW_CUSTOM_MAX)
+ {
+ wrqu.data.length = pAd->StaCfg.ReqVarIELen;
+ memcpy(custom, pAd->StaCfg.ReqVarIEs, pAd->StaCfg.ReqVarIELen);
+ wireless_send_event(pAd->net_dev, IWEVASSOCREQIE, &wrqu, custom);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("pAd->StaCfg.ReqVarIELen > MAX_CUSTOM_LEN\n"));
+#else
+ if (((pAd->StaCfg.ReqVarIELen*2) + 17) <= IW_CUSTOM_MAX)
+ {
+ UCHAR idx;
+ wrqu.data.length = (pAd->StaCfg.ReqVarIELen*2) + 17;
+ sprintf(custom, "ASSOCINFO(ReqIEs=");
+ for (idx=0; idx<pAd->StaCfg.ReqVarIELen; idx++)
+ sprintf(custom, "%s%02x", custom, pAd->StaCfg.ReqVarIEs[idx]);
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("(pAd->StaCfg.ReqVarIELen*2) + 17 > MAX_CUSTOM_LEN\n"));
+#endif
+
+ return 0;
+
+}
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+
+BOOLEAN StaAddMacTableEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PMAC_TABLE_ENTRY pEntry,
+ IN UCHAR MaxSupportedRateIn500Kbps,
+ IN HT_CAPABILITY_IE *pHtCapability,
+ IN UCHAR HtCapabilityLen,
+ IN USHORT CapabilityInfo)
+{
+ UCHAR MaxSupportedRate = RATE_11;
+
+ if (ADHOC_ON(pAd))
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ if ((pAd->CommonCfg.PhyMode == PHY_11G) && (MaxSupportedRate < RATE_FIRST_OFDM_RATE))
+ return FALSE;
+
+#ifdef DOT11_N_SUPPORT
+ // 11n only
+ if (((pAd->CommonCfg.PhyMode == PHY_11N_2_4G) || (pAd->CommonCfg.PhyMode == PHY_11N_5G))&& (HtCapabilityLen == 0))
+ return FALSE;
+#endif // DOT11_N_SUPPORT //
+
+ if (!pEntry)
+ return FALSE;
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ if (pEntry)
+ {
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ if ((MaxSupportedRate < RATE_FIRST_OFDM_RATE) ||
+ (pAd->CommonCfg.PhyMode == PHY_11B))
+ {
+ pEntry->RateLen = 4;
+ if (MaxSupportedRate >= RATE_FIRST_OFDM_RATE)
+ MaxSupportedRate = RATE_11;
+ }
+ else
+ pEntry->RateLen = 12;
+
+ pEntry->MaxHTPhyMode.word = 0;
+ pEntry->MinHTPhyMode.word = 0;
+ pEntry->HTPhyMode.word = 0;
+ pEntry->MaxSupportedRate = MaxSupportedRate;
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+ pEntry->CapabilityInfo = CapabilityInfo;
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_AGGREGATION_CAPABLE);
+ CLIENT_STATUS_CLEAR_FLAG(pEntry, fCLIENT_STATUS_PIGGYBACK_CAPABLE);
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR i;
+
+ if (ADHOC_ON(pAd))
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+ if ((pHtCapability->HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((pHtCapability->HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(pHtCapability->HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(pHtCapability->HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // 3*3
+ if (pAd->MACVersion >= RALINK_2883_VERSION && pAd->MACVersion < RALINK_3070_VERSION)
+ pEntry->MaxHTPhyMode.field.TxBF = pAd->CommonCfg.RegTransmitSetting.field.TxBF;
+
+ // find max fixed rate
+ for (i=23; i>=0; i--) // 3*3
+ {
+ j = i/8;
+ bitmask = (1<<(i-(j*8)));
+ if ((pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j] & bitmask) && (pHtCapability->MCSSet[j] & bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = i;
+ break;
+ }
+ if (i==0)
+ break;
+ }
+
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (pHtCapability->HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = pHtCapability->HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = pHtCapability->HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)pHtCapability->HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)pHtCapability->HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (pAd->CommonCfg.DesiredHtPhy.AmsduEnable && (pAd->CommonCfg.REGBACapability.field.AutoBA == FALSE))
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED);
+ if (pHtCapability->HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (pHtCapability->HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (pHtCapability->HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (pHtCapability->HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (pHtCapability->ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && pHtCapability->ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (pHtCapability->ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+ }
+ else
+ {
+ pAd->MacTab.fAnyStationIsLegacy = TRUE;
+ }
+
+ NdisMoveMemory(&pEntry->HTCapability, pHtCapability, sizeof(HT_CAPABILITY_IE));
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+
+ // Set asic auto fall back
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ // If the legacy mode is set, overwrite the transmit setting of this entry.
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+
+ pEntry->PortSecured = WPA_802_1X_PORT_SECURED;
+ pEntry->Sst = SST_ASSOC;
+ pEntry->AuthState = AS_AUTH_OPEN;
+ pEntry->AuthMode = pAd->StaCfg.AuthMode;
+ pEntry->WepStatus = pAd->StaCfg.WepStatus;
+
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ union iwreq_data wrqu;
+
+ SendAssocIEsToWpaSupplicant(pAd);
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_ASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ wext_notify_event_assoc(pAd);
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ return TRUE;
+}
+
+
diff --git a/drivers/staging/rt3070/sta/auth.c b/drivers/staging/rt3070/sta/auth.c
new file mode 100644
index 00000000000..032b5df058b
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth.c
@@ -0,0 +1,475 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ auth.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-9-3 porting from RT2500
+*/
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ authenticate state machine init, including state transition and timer init
+ Parameters:
+ Sm - pointer to the auth state machine
+ Note:
+ The state machine looks like this
+
+ AUTH_REQ_IDLE AUTH_WAIT_SEQ2 AUTH_WAIT_SEQ4
+ MT2_MLME_AUTH_REQ mlme_auth_req_action invalid_state_when_auth invalid_state_when_auth
+ MT2_PEER_AUTH_EVEN drop peer_auth_even_at_seq2_action peer_auth_even_at_seq4_action
+ MT2_AUTH_TIMEOUT Drop auth_timeout_action auth_timeout_action
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+
+void AuthStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, Trans, MAX_AUTH_STATE, MAX_AUTH_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_REQ_IDLE, AUTH_MACHINE_BASE);
+
+ // the first column
+ StateMachineSetAction(Sm, AUTH_REQ_IDLE, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)MlmeAuthReqAction);
+
+ // the second column
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq2Action);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ2, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+
+ // the third column
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_MLME_AUTH_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenAuth);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_PEER_AUTH_EVEN, (STATE_MACHINE_FUNC)PeerAuthRspAtSeq4Action);
+ StateMachineSetAction(Sm, AUTH_WAIT_SEQ4, MT2_AUTH_TIMEOUT, (STATE_MACHINE_FUNC)AuthTimeoutAction);
+
+ RTMPInitTimer(pAd, &pAd->MlmeAux.AuthTimer, GET_TIMER_FUNCTION(AuthTimeout), pAd, FALSE);
+}
+
+/*
+ ==========================================================================
+ Description:
+ function to be executed at timer thread when auth timer expires
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AuthTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE,("AUTH - AuthTimeout\n"));
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))
+ return;
+
+ // send a de-auth to reset AP's state machine (Patch AP-Dir635)
+ if (pAd->Mlme.AuthMachine.CurrState == AUTH_WAIT_SEQ2)
+ Cls2errAction(pAd, pAd->MlmeAux.Bssid);
+
+
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_AUTH_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeAuthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr[6];
+ USHORT Alg, Seq, Status;
+ ULONG Timeout;
+ HEADER_802_11 AuthHdr;
+ BOOLEAN TimerCancelled;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+
+ // Block all authentication request durning WPA block period
+ if (pAd->StaCfg.bBlockAssoc == TRUE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Block Auth request durning WPA block period!\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ else if(MlmeAuthReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr, &Timeout, &Alg))
+ {
+ // reset timer
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, Addr);
+ pAd->MlmeAux.Alg = Alg;
+ Seq = 1;
+ Status = MLME_SUCCESS;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeAuthReqAction(Alg:%d) allocate memory failed\n", Alg));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#1 (Alg=%d)...\n", Alg));
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&AuthHdr,
+ 2, &Alg,
+ 2, &Seq,
+ 2, &Status,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.AuthTimer, Timeout);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ2;
+ }
+ else
+ {
+ DBGPRINT_ERR(("AUTH - MlmeAuthReqAction() sanity check failed\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerAuthRspAtSeq2Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Seq, Status, RemoteStatus, Alg;
+ UCHAR ChlgText[CIPHER_TEXT_LEN];
+ UCHAR CyperChlgText[CIPHER_TEXT_LEN + 8 + 8];
+ UCHAR Element[2];
+ HEADER_802_11 AuthHdr;
+ BOOLEAN TimerCancelled;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT Status2;
+
+ if (PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+ {
+ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 2)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#2 to me (Alg=%d, Status=%d)\n", Alg, Status));
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+
+ if (Status == MLME_SUCCESS)
+ {
+ // Authentication Mode "LEAP" has allow for CCX 1.X
+ if ((pAd->MlmeAux.Alg == Ndis802_11AuthModeOpen)
+#ifdef LEAP_SUPPORT
+ || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ )
+ {
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+#ifdef LEAP_SUPPORT
+ pAd->Mlme.LeapMachine.CurrState = LEAP_IDLE;
+#endif // LEAP_SUPPORT //
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ else
+ {
+ // 2. shared key, need to be challenged
+ Seq++;
+ RemoteStatus = MLME_SUCCESS;
+
+ // Get an unused nonpaged memory
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if(NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq2Action() allocate memory fail\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status2 = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status2);
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send AUTH request seq#3...\n"));
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, Addr2, pAd->MlmeAux.Bssid);
+ AuthHdr.FC.Wep = 1;
+ // Encrypt challenge text & auth information
+ RTMPInitWepEngine(
+ pAd,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen,
+ CyperChlgText);
+
+ Alg = cpu2le16(*(USHORT *)&Alg);
+ Seq = cpu2le16(*(USHORT *)&Seq);
+ RemoteStatus= cpu2le16(*(USHORT *)&RemoteStatus);
+
+ RTMPEncryptData(pAd, (PUCHAR) &Alg, CyperChlgText + 4, 2);
+ RTMPEncryptData(pAd, (PUCHAR) &Seq, CyperChlgText + 6, 2);
+ RTMPEncryptData(pAd, (PUCHAR) &RemoteStatus, CyperChlgText + 8, 2);
+ Element[0] = 16;
+ Element[1] = 128;
+ RTMPEncryptData(pAd, Element, CyperChlgText + 10, 2);
+ RTMPEncryptData(pAd, ChlgText, CyperChlgText + 12, 128);
+ RTMPSetICV(pAd, CyperChlgText + 140);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AuthHdr,
+ CIPHER_TEXT_LEN + 16, CyperChlgText,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ RTMPSetTimer(&pAd->MlmeAux.AuthTimer, AUTH_TIMEOUT);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_WAIT_SEQ4;
+ }
+ }
+ else
+ {
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ //Invalid Authentication possible rogue AP
+ //Add this Ap to Rogue AP.
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_INVALID_AUTH);
+ }
+#endif // LEAP_SUPPORT //
+ pAd->StaCfg.AuthFailReason = Status;
+ COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthSanity() sanity check fail\n"));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerAuthRspAtSeq4Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Alg, Seq, Status;
+ CHAR ChlgText[CIPHER_TEXT_LEN];
+ BOOLEAN TimerCancelled;
+
+ if(PeerAuthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Alg, &Seq, &Status, ChlgText))
+ {
+ if(MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Addr2) && Seq == 4)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Receive AUTH_RSP seq#4 to me\n"));
+ RTMPCancelTimer(&pAd->MlmeAux.AuthTimer, &TimerCancelled);
+
+ if (Status != MLME_SUCCESS)
+ {
+ pAd->StaCfg.AuthFailReason = Status;
+ COPY_MAC_ADDR(pAd->StaCfg.AuthFailSta, Addr2);
+ }
+
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - PeerAuthRspAtSeq4Action() sanity check fail\n"));
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDeauthReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DEAUTH_REQ_STRUCT *pInfo;
+ HEADER_802_11 DeauthHdr;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT Status;
+
+ pInfo = (MLME_DEAUTH_REQ_STRUCT *)Elem->Msg;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - MlmeDeauthReqAction() allocate memory fail\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_FAIL_NO_RESOURCE;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
+ return;
+ }
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Send DE-AUTH request (Reason=%d)...\n", pInfo->Reason));
+ MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pInfo->Addr, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DeauthHdr,
+ 2, &pInfo->Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DeauthReason = pInfo->Reason;
+ COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pInfo->Addr);
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_DEAUTH_CONF, 2, &Status);
+
+ // send wireless event - for deauthentication
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID AuthTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - AuthTimeoutAction\n"));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID InvalidStateWhenAuth(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - InvalidStateWhenAuth (state=%ld), reset AUTH state machine\n", pAd->Mlme.AuthMachine.CurrState));
+ pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_AUTH_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Some STA/AP
+ Note:
+ This action should never trigger AUTH state transition, therefore we
+ separate it from AUTH state machine, and make it as a standalone service
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID Cls2errAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr)
+{
+ HEADER_802_11 DeauthHdr;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT Reason = REASON_CLS2ERR;
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("AUTH - Class 2 error, Send DEAUTH frame...\n"));
+ MgtMacHeaderInit(pAd, &DeauthHdr, SUBTYPE_DEAUTH, 0, pAddr, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11),&DeauthHdr,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ pAd->StaCfg.DeauthReason = Reason;
+ COPY_MAC_ADDR(pAd->StaCfg.DeauthSta, pAddr);
+}
+
+
diff --git a/drivers/staging/rt3070/sta/auth_rsp.c b/drivers/staging/rt3070/sta/auth_rsp.c
new file mode 100644
index 00000000000..f7aa4b99cf5
--- /dev/null
+++ b/drivers/staging/rt3070/sta/auth_rsp.c
@@ -0,0 +1,167 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ auth_rsp.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-10-1 copy from RT2560
+*/
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ authentication state machine init procedure
+ Parameters:
+ Sm - the state machine
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+VOID AuthRspStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN PSTATE_MACHINE Sm,
+ IN STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, Trans, MAX_AUTH_RSP_STATE, MAX_AUTH_RSP_MSG, (STATE_MACHINE_FUNC)Drop, AUTH_RSP_IDLE, AUTH_RSP_MACHINE_BASE);
+
+ // column 1
+ StateMachineSetAction(Sm, AUTH_RSP_IDLE, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+
+ // column 2
+ StateMachineSetAction(Sm, AUTH_RSP_WAIT_CHAL, MT2_PEER_DEAUTH, (STATE_MACHINE_FUNC)PeerDeauthAction);
+
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID PeerAuthSimpleRspGenAndSend(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHdr80211,
+ IN USHORT Alg,
+ IN USHORT Seq,
+ IN USHORT Reason,
+ IN USHORT Status)
+{
+ HEADER_802_11 AuthHdr;
+ ULONG FrameLen = 0;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+
+ if (Reason != MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Peer AUTH fail...\n"));
+ return;
+ }
+
+ //Get an unused nonpaged memory
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Send AUTH response (seq#2)...\n"));
+ MgtMacHeaderInit(pAd, &AuthHdr, SUBTYPE_AUTH, 0, pHdr80211->Addr2, pAd->MlmeAux.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &AuthHdr,
+ 2, &Alg,
+ 2, &Seq,
+ 2, &Reason,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID PeerDeauthAction(
+ IN PRTMP_ADAPTER pAd,
+ IN PMLME_QUEUE_ELEM Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ USHORT Reason;
+
+ if (PeerDeauthSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, &Reason))
+ {
+ if (INFRA_ON(pAd) && MAC_ADDR_EQUAL(Addr2, pAd->CommonCfg.Bssid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - receive DE-AUTH from our AP (Reason=%d)\n", Reason));
+
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+
+ // send wireless event - for deauthentication
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_DEAUTH_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+ LinkDown(pAd, TRUE);
+
+ // Authentication Mode Cisco_LEAP has start a timer
+ // We should cancel it if using LEAP
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ RTMPCancelTimer(&pAd->StaCfg.LeapAuthTimer, &TimerCancelled);
+ //Check is it mach the LEAP Authentication failed as possible a Rogue AP
+ //on it's PortSecured not equal to WPA_802_1X_PORT_SECURED while process the Authenticaton.
+ if ((pAd->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED) && (pAd->Mlme.LeapMachine.CurrState != LEAP_IDLE))
+ {
+ RogueApTableSetEntry(pAd, &pAd->StaCfg.RogueApTab, Addr2, LEAP_REASON_AUTH_TIMEOUT);
+ }
+ }
+#endif // LEAP_SUPPORT //
+ }
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("AUTH_RSP - PeerDeauthAction() sanity check fail\n"));
+ }
+}
+
diff --git a/drivers/staging/rt3070/sta/connect.c b/drivers/staging/rt3070/sta/connect.c
new file mode 100644
index 00000000000..152c0bd0f82
--- /dev/null
+++ b/drivers/staging/rt3070/sta/connect.c
@@ -0,0 +1,2857 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ connect.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John 2004-08-08 Major modification from RT2560
+*/
+#include "../rt_config.h"
+
+UCHAR CipherSuiteWpaNoneTkip[] = {
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x00 // authentication
+ };
+UCHAR CipherSuiteWpaNoneTkipLen = (sizeof(CipherSuiteWpaNoneTkip) / sizeof(UCHAR));
+
+UCHAR CipherSuiteWpaNoneAes[] = {
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x04, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x04, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x00 // authentication
+ };
+UCHAR CipherSuiteWpaNoneAesLen = (sizeof(CipherSuiteWpaNoneAes) / sizeof(UCHAR));
+
+// The following MACRO is called after 1. starting an new IBSS, 2. succesfully JOIN an IBSS,
+// or 3. succesfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS
+// All settings successfuly negotiated furing MLME state machines become final settings
+// and are copied to pAd->StaActive
+#define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \
+{ \
+ (_pAd)->CommonCfg.SsidLen = (_pAd)->MlmeAux.SsidLen; \
+ NdisMoveMemory((_pAd)->CommonCfg.Ssid, (_pAd)->MlmeAux.Ssid, (_pAd)->MlmeAux.SsidLen); \
+ COPY_MAC_ADDR((_pAd)->CommonCfg.Bssid, (_pAd)->MlmeAux.Bssid); \
+ (_pAd)->CommonCfg.Channel = (_pAd)->MlmeAux.Channel; \
+ (_pAd)->CommonCfg.CentralChannel = (_pAd)->MlmeAux.CentralChannel; \
+ (_pAd)->StaActive.Aid = (_pAd)->MlmeAux.Aid; \
+ (_pAd)->StaActive.AtimWin = (_pAd)->MlmeAux.AtimWin; \
+ (_pAd)->StaActive.CapabilityInfo = (_pAd)->MlmeAux.CapabilityInfo; \
+ (_pAd)->CommonCfg.BeaconPeriod = (_pAd)->MlmeAux.BeaconPeriod; \
+ (_pAd)->StaActive.CfpMaxDuration = (_pAd)->MlmeAux.CfpMaxDuration; \
+ (_pAd)->StaActive.CfpPeriod = (_pAd)->MlmeAux.CfpPeriod; \
+ (_pAd)->StaActive.SupRateLen = (_pAd)->MlmeAux.SupRateLen; \
+ NdisMoveMemory((_pAd)->StaActive.SupRate, (_pAd)->MlmeAux.SupRate, (_pAd)->MlmeAux.SupRateLen);\
+ (_pAd)->StaActive.ExtRateLen = (_pAd)->MlmeAux.ExtRateLen; \
+ NdisMoveMemory((_pAd)->StaActive.ExtRate, (_pAd)->MlmeAux.ExtRate, (_pAd)->MlmeAux.ExtRateLen);\
+ NdisMoveMemory(&(_pAd)->CommonCfg.APEdcaParm, &(_pAd)->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));\
+ NdisMoveMemory(&(_pAd)->CommonCfg.APQosCapability, &(_pAd)->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));\
+ NdisMoveMemory(&(_pAd)->CommonCfg.APQbssLoad, &(_pAd)->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));\
+ COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].Addr, (_pAd)->MlmeAux.Bssid); \
+ (_pAd)->MacTab.Content[BSSID_WCID].Aid = (_pAd)->MlmeAux.Aid; \
+ (_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.CipherAlg = (_pAd)->StaCfg.PairCipher;\
+ COPY_MAC_ADDR((_pAd)->MacTab.Content[BSSID_WCID].PairwiseKey.BssId, (_pAd)->MlmeAux.Bssid);\
+ (_pAd)->MacTab.Content[BSSID_WCID].RateLen = (_pAd)->StaActive.SupRateLen + (_pAd)->StaActive.ExtRateLen;\
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+*/
+VOID MlmeCntlInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ // Control state machine differs from other state machines, the interface
+ // follows the standard interface
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID MlmeCntlMachinePerformAction(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ switch(pAd->Mlme.CntlMachine.CurrState)
+ {
+ case CNTL_IDLE:
+ {
+ CntlIdleProc(pAd, Elem);
+ }
+ break;
+ case CNTL_WAIT_DISASSOC:
+ CntlWaitDisassocProc(pAd, Elem);
+ break;
+ case CNTL_WAIT_JOIN:
+ CntlWaitJoinProc(pAd, Elem);
+ break;
+
+ // CNTL_WAIT_REASSOC is the only state in CNTL machine that does
+ // not triggered directly or indirectly by "RTMPSetInformation(OID_xxx)".
+ // Therefore not protected by NDIS's "only one outstanding OID request"
+ // rule. Which means NDIS may SET OID in the middle of ROAMing attempts.
+ // Current approach is to block new SET request at RTMPSetInformation()
+ // when CntlMachine.CurrState is not CNTL_IDLE
+ case CNTL_WAIT_REASSOC:
+ CntlWaitReassocProc(pAd, Elem);
+ break;
+
+ case CNTL_WAIT_START:
+ CntlWaitStartProc(pAd, Elem);
+ break;
+ case CNTL_WAIT_AUTH:
+ CntlWaitAuthProc(pAd, Elem);
+ break;
+ case CNTL_WAIT_AUTH2:
+ CntlWaitAuthProc2(pAd, Elem);
+ break;
+ case CNTL_WAIT_ASSOC:
+ CntlWaitAssocProc(pAd, Elem);
+ break;
+
+ case CNTL_WAIT_OID_LIST_SCAN:
+ if(Elem->MsgType == MT2_SCAN_CONF)
+ {
+ // Resume TxRing after SCANING complete. We hope the out-of-service time
+ // won't be too long to let upper layer time-out the waiting frames
+ RTMPResumeMsduTransmission(pAd);
+ if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
+ {
+ // Cisco scan request is finished, prepare beacon report
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+ }
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+ //
+ // Set LED status to previous status.
+ //
+ if (pAd->bLedOnScanning)
+ {
+ pAd->bLedOnScanning = FALSE;
+ RTMPSetLED(pAd, pAd->LedStatus);
+ }
+#ifdef DOT11N_DRAFT3
+ // AP sent a 2040Coexistence mgmt frame, then station perform a scan, and then send back the respone.
+ if (pAd->CommonCfg.BSSCoexist2040.field.InfoReq == 1)
+ {
+ Update2040CoexistFrameAndNotify(pAd, BSSID_WCID, TRUE);
+ }
+#endif // DOT11N_DRAFT3 //
+ }
+ break;
+
+ case CNTL_WAIT_OID_DISASSOC:
+ if (Elem->MsgType == MT2_DISASSOC_CONF)
+ {
+ LinkDown(pAd, FALSE);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+ break;
+#ifdef RT2870
+ //
+ // This state is for that we want to connect to an AP but
+ // it didn't find on BSS List table. So we need to scan the air first,
+ // after that we can try to connect to the desired AP if available.
+ //
+ case CNTL_WAIT_SCAN_FOR_CONNECT:
+ if(Elem->MsgType == MT2_SCAN_CONF)
+ {
+ // Resume TxRing after SCANING complete. We hope the out-of-service time
+ // won't be too long to let upper layer time-out the waiting frames
+ RTMPResumeMsduTransmission(pAd);
+#ifdef CCX_SUPPORT
+ if (pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED)
+ {
+ // Cisco scan request is finished, prepare beacon report
+ MlmeEnqueue(pAd, AIRONET_STATE_MACHINE, MT2_AIRONET_SCAN_DONE, 0, NULL);
+ }
+#endif // CCX_SUPPORT //
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+
+ //
+ // Check if we can connect to.
+ //
+ BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+ if (pAd->MlmeAux.SsidBssTab.BssNr > 0)
+ {
+ MlmeAutoReconnectLastSSID(pAd);
+ }
+ }
+ break;
+#endif // RT2870 //
+ default:
+ DBGPRINT_ERR(("!ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType));
+ break;
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlIdleProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ return;
+
+ switch(Elem->MsgType)
+ {
+ case OID_802_11_SSID:
+ CntlOidSsidProc(pAd, Elem);
+ break;
+
+ case OID_802_11_BSSID:
+ CntlOidRTBssidProc(pAd,Elem);
+ break;
+
+ case OID_802_11_BSSID_LIST_SCAN:
+ CntlOidScanProc(pAd,Elem);
+ break;
+
+ case OID_802_11_DISASSOCIATE:
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_ENABLE_WITH_WEB_UI)
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // Set the AutoReconnectSsid to prevent it reconnect to old SSID
+ // Since calling this indicate user don't want to connect to that SSID anymore.
+ pAd->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen);
+ }
+ break;
+
+ case MT2_MLME_ROAMING_REQ:
+ CntlMlmeRoamingProc(pAd, Elem);
+ break;
+
+ case OID_802_11_MIC_FAILURE_REPORT_FRAME:
+ WpaMicFailureReportFrame(pAd, Elem);
+ break;
+
+#ifdef QOS_DLS_SUPPORT
+ case RT_OID_802_11_SET_DLS_PARAM:
+ CntlOidDLSSetupProc(pAd, Elem);
+ break;
+#endif // QOS_DLS_SUPPORT //
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Illegal message in CntlIdleProc(MsgType=%ld)\n",Elem->MsgType));
+ break;
+ }
+}
+
+VOID CntlOidScanProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_SCAN_REQ_STRUCT ScanReq;
+ ULONG BssIdx = BSS_NOT_FOUND;
+ BSS_ENTRY CurrBss;
+
+#ifdef RALINK_ATE
+/* Disable scanning when ATE is running. */
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+
+ // record current BSS if network is connected.
+ // 2003-2-13 do not include current IBSS if this is the only STA in this IBSS.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ BssIdx = BssSsidTableSearch(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->CommonCfg.Channel);
+ if (BssIdx != BSS_NOT_FOUND)
+ {
+ NdisMoveMemory(&CurrBss, &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+ }
+ }
+
+ // clean up previous SCAN result, add current BSS back to table if any
+ BssTableInit(&pAd->ScanTab);
+ if (BssIdx != BSS_NOT_FOUND)
+ {
+ // DDK Note: If the NIC is associated with a particular BSSID and SSID
+ // that are not contained in the list of BSSIDs generated by this scan, the
+ // BSSID description of the currently associated BSSID and SSID should be
+ // appended to the list of BSSIDs in the NIC's database.
+ // To ensure this, we append this BSS as the first entry in SCAN result
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[0], &CurrBss, sizeof(BSS_ENTRY));
+ pAd->ScanTab.BssNr = 1;
+ }
+
+ ScanParmFill(pAd, &ScanReq, "", 0, BSS_ANY, SCAN_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ,
+ sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Before calling this routine, user desired SSID should already been
+ recorded in CommonCfg.Ssid[]
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlOidSsidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem)
+{
+ PNDIS_802_11_SSID pOidSsid = (NDIS_802_11_SSID *)Elem->Msg;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+ ULONG Now;
+
+ // Step 1. record the desired user settings to MlmeAux
+ NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->MlmeAux.Ssid, pOidSsid->Ssid, pOidSsid->SsidLength);
+ pAd->MlmeAux.SsidLen = (UCHAR)pOidSsid->SsidLength;
+ NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
+
+
+ //
+ // Update Reconnect Ssid, that user desired to connect.
+ //
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
+
+ // step 2. find all matching BSS in the lastest SCAN result (inBssTab)
+ // & log them into MlmeAux.SsidBssTab for later-on iteration. Sort by RSSI order
+ BssTableSsidSort(pAd, &pAd->MlmeAux.SsidBssTab, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - %d BSS of %d BSS match the desire (%d)SSID - %s\n",
+ pAd->MlmeAux.SsidBssTab.BssNr, pAd->ScanTab.BssNr, pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid));
+ NdisGetSystemUpTime(&Now);
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
+ (pAd->CommonCfg.SsidLen == pAd->MlmeAux.SsidBssTab.BssEntry[0].SsidLen) &&
+ NdisEqualMemory(pAd->CommonCfg.Ssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Ssid, pAd->CommonCfg.SsidLen) &&
+ MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pAd->MlmeAux.SsidBssTab.BssEntry[0].Bssid))
+ {
+ // Case 1. already connected with an AP who has the desired SSID
+ // with highest RSSI
+
+ // Add checking Mode "LEAP" for CCX 1.0
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef LEAP_SUPPORT
+ || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ ) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ // case 1.1 For WPA, WPA-PSK, if the 1x port is not secured, we have to redo
+ // connection process
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else if (pAd->bConfigChanged == TRUE)
+ {
+ // case 1.2 Important Config has changed, we have to reconnect to the same AP
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP Because config changed...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else
+ {
+ // case 1.3. already connected to the SSID with highest RSSI.
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - already with this BSSID. ignore this SET_SSID request\n"));
+ //
+ // (HCT 12.1) 1c_wlan_mediaevents required
+ // media connect events are indicated when associating with the same AP
+ //
+ if (INFRA_ON(pAd))
+ {
+ //
+ // Since MediaState already is NdisMediaStateConnected
+ // We just indicate the connect event again to meet the WHQL required.
+ //
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
+ }
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ }
+ }
+ else if (INFRA_ON(pAd))
+ {
+ //
+ // For RT61
+ // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
+ // RT61 may lost SSID, and not connect to NDTEST_WEP_AP2 and will connect to NDTEST_WEP_AP2 by Autoreconnect
+ // But media status is connected, so the SSID not report correctly.
+ //
+ if (!SSID_EQUAL(pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen))
+ {
+ //
+ // Different SSID means not Roaming case, so we let LinkDown() to Indicate a disconnect event.
+ //
+ pAd->MlmeAux.CurrReqIsFromNdis = TRUE;
+ }
+ // case 2. active INFRA association existent
+ // roaming is done within miniport driver, nothing to do with configuration
+ // utility. so upon a new SET(OID_802_11_SSID) is received, we just
+ // disassociate with the current associated AP,
+ // then perform a new association with this new SSID, no matter the
+ // new/old SSID are the same or not.
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - disassociate with current AP...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else
+ {
+ if (ADHOC_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - drop current ADHOC\n"));
+ LinkDown(pAd, FALSE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+ }
+
+ if ((pAd->MlmeAux.SsidBssTab.BssNr == 0) &&
+ (pAd->StaCfg.bAutoReconnect == TRUE) &&
+ (pAd->MlmeAux.BssType == BSS_INFRA) &&
+ (MlmeValidateSSID(pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen) == TRUE)
+ )
+ {
+ MLME_SCAN_REQ_STRUCT ScanReq;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CntlOidSsidProc():CNTL - No matching BSS, start a new scan\n"));
+ ScanParmFill(pAd, &ScanReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, BSS_ANY, SCAN_ACTIVE);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_SCAN_REQ, sizeof(MLME_SCAN_REQ_STRUCT), &ScanReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_LIST_SCAN;
+ // Reset Missed scan number
+ pAd->StaCfg.LastScanTime = Now;
+ }
+ else
+ {
+ pAd->MlmeAux.BssIdx = 0;
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlOidRTBssidProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM * Elem)
+{
+ ULONG BssIdx;
+ PUCHAR pOidBssid = (PUCHAR)Elem->Msg;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+ MLME_JOIN_REQ_STRUCT JoinReq;
+
+#ifdef RALINK_ATE
+/* No need to perform this routine when ATE is running. */
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ // record user desired settings
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pOidBssid);
+ pAd->MlmeAux.BssType = pAd->StaCfg.BssType;
+
+ //
+ // Update Reconnect Ssid, that user desired to connect.
+ //
+ NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID);
+ pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen;
+ NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+
+ // find the desired BSS in the latest SCAN result table
+ BssIdx = BssTableSearch(&pAd->ScanTab, pOidBssid, pAd->MlmeAux.Channel);
+ if (BssIdx == BSS_NOT_FOUND)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - BSSID not found. reply NDIS_STATUS_NOT_ACCEPTED\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ return;
+ }
+
+ // copy the matched BSS entry from ScanTab to MlmeAux.SsidBssTab. Why?
+ // Because we need this entry to become the JOIN target in later on SYNC state machine
+ pAd->MlmeAux.BssIdx = 0;
+ pAd->MlmeAux.SsidBssTab.BssNr = 1;
+ NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(BSS_ENTRY));
+
+ //pAd->MlmeAux.AutoReconnectSsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+ //NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->ScanTab.BssEntry[BssIdx].SsidLen);
+
+ // Add SSID into MlmeAux for site surey joining hidden SSID
+ //pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen;
+ //NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen);
+
+ // 2002-11-26 skip the following checking. i.e. if user wants to re-connect to same AP
+ // we just follow normal procedure. The reason of user doing this may because he/she changed
+ // AP to another channel, but we still received BEACON from it thus don't claim Link Down.
+ // Since user knows he's changed AP channel, he'll re-connect again. By skipping the following
+ // checking, we'll disassociate then re-do normal association with this AP at the new channel.
+ // 2003-1-6 Re-enable this feature based on microsoft requirement which prefer not to re-do
+ // connection when setting the same BSSID.
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) &&
+ MAC_ADDR_EQUAL(pAd->CommonCfg.Bssid, pOidBssid))
+ {
+ // already connected to the same BSSID, go back to idle state directly
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - already in this BSSID. ignore this SET_BSSID request\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ memcpy(wrqu.ap_addr.sa_data, pAd->MlmeAux.Bssid, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ }
+ else
+ {
+ if (INFRA_ON(pAd))
+ {
+ // disassoc from current AP first
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - disassociate with current AP ...\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ,
+ sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ }
+ else
+ {
+ if (ADHOC_ON(pAd))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - drop current ADHOC\n"));
+ LinkDown(pAd, FALSE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event C!\n"));
+ }
+
+ // Change the wepstatus to original wepstatus
+ pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
+
+ // Check cipher suite, AP must have more secured cipher than station setting
+ // Set the Pairwise and Group cipher to match the intended AP setting
+ // We can only connect to AP with less secured cipher setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipher;
+ else if (pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipher;
+ else if (pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->ScanTab.BssEntry[BssIdx].WPA2.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+
+ // RSN capability
+ pAd->StaCfg.RsnCapability = pAd->ScanTab.BssEntry[BssIdx].WPA2.RsnCapability;
+ }
+
+ // Set Mix cipher flag
+ pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+ if (pAd->StaCfg.bMixCipher == TRUE)
+ {
+ // If mix cipher, re-build RSNIE
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+ }
+ // No active association, join the BSS immediately
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - joining %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+ pOidBssid[0],pOidBssid[1],pOidBssid[2],pOidBssid[3],pOidBssid[4],pOidBssid[5]));
+
+ JoinParmFill(pAd, &JoinReq, pAd->MlmeAux.BssIdx);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT), &JoinReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
+ }
+ }
+}
+
+// Roaming is the only external request triggering CNTL state machine
+// despite of other "SET OID" operation. All "SET OID" related oerations
+// happen in sequence, because no other SET OID will be sent to this device
+// until the the previous SET operation is complete (successful o failed).
+// So, how do we quarantee this ROAMING request won't corrupt other "SET OID"?
+// or been corrupted by other "SET OID"?
+//
+// IRQL = DISPATCH_LEVEL
+VOID CntlMlmeRoamingProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ // TODO:
+ // AP in different channel may show lower RSSI than actual value??
+ // should we add a weighting factor to compensate it?
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - Roaming in MlmeAux.RoamTab...\n"));
+
+ NdisMoveMemory(&pAd->MlmeAux.SsidBssTab, &pAd->MlmeAux.RoamTab, sizeof(pAd->MlmeAux.RoamTab));
+ pAd->MlmeAux.SsidBssTab.BssNr = pAd->MlmeAux.RoamTab.BssNr;
+
+ BssTableSortByRssi(&pAd->MlmeAux.SsidBssTab);
+ pAd->MlmeAux.BssIdx = 0;
+ IterateOnBssTab(pAd);
+}
+
+#ifdef QOS_DLS_SUPPORT
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlOidDLSSetupProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PRT_802_11_DLS pDLS = (PRT_802_11_DLS)Elem->Msg;
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ INT i;
+ USHORT reason = REASON_UNSPECIFY;
+
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - (OID set %02x:%02x:%02x:%02x:%02x:%02x with Valid=%d, Status=%d, TimeOut=%d, CountDownTimer=%d)\n",
+ pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5],
+ pDLS->Valid, pDLS->Status, pDLS->TimeOut, pDLS->CountDownTimer));
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return;
+
+ // DLS will not be supported when Adhoc mode
+ if (INFRA_ON(pAd))
+ {
+ for (i = 0; i < MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ (pDLS->TimeOut == pAd->StaCfg.DLSEntry[i].TimeOut) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 1. Same setting, just drop it
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - setting unchanged\n"));
+ break;
+ }
+ else if (!pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 2. Disable DLS link case, just tear down DLS link
+ reason = REASON_QOS_UNWANTED_MECHANISM;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - start tear down procedure\n"));
+ break;
+ }
+ else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && !pAd->StaCfg.DLSEntry[i].Valid)
+ {
+ // 3. Enable case, start DLS setup procedure
+ NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
+
+ //Update countdown timer
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS setup case\n"));
+ break;
+ }
+ else if ((i < MAX_NUM_OF_DLS_ENTRY) && pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+ (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) && !MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 4. update mac case, tear down old DLS and setup new DLS
+ reason = REASON_QOS_UNWANTED_MECHANISM;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ NdisMoveMemory(&pAd->StaCfg.DLSEntry[i], pDLS, sizeof(RT_802_11_DLS_UI));
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS tear down and restart case\n"));
+ break;
+ }
+ else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+ MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr) && (pAd->StaCfg.DLSEntry[i].TimeOut != pDLS->TimeOut))
+ {
+ // 5. update timeout case, start DLS setup procedure (no tear down)
+ pAd->StaCfg.DLSEntry[i].TimeOut = pDLS->TimeOut;
+ //Update countdown timer
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS update timeout case\n"));
+ break;
+ }
+ else if (pDLS->Valid && pAd->StaCfg.DLSEntry[i].Valid &&
+ (pAd->StaCfg.DLSEntry[i].Status != DLS_FINISH) && MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ // 6. re-setup case, start DLS setup procedure (no tear down)
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_REQ, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ DBGPRINT(RT_DEBUG_TRACE,("CNTL - DLS retry setup procedure\n"));
+ break;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN,("CNTL - DLS not changed in entry - %d - Valid=%d, Status=%d, TimeOut=%d\n",
+ i, pAd->StaCfg.DLSEntry[i].Valid, pAd->StaCfg.DLSEntry[i].Status, pAd->StaCfg.DLSEntry[i].TimeOut));
+ }
+ }
+ }
+}
+#endif // QOS_DLS_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitDisassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ MLME_START_REQ_STRUCT StartReq;
+
+ if (Elem->MsgType == MT2_DISASSOC_CONF)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Dis-associate successful\n"));
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_DISASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+
+ LinkDown(pAd, FALSE);
+
+ // case 1. no matching BSS, and user wants ADHOC, so we just start a new one
+ if ((pAd->MlmeAux.SsidBssTab.BssNr==0) && (pAd->StaCfg.BssType == BSS_ADHOC))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - No matching BSS, start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
+ StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+ }
+ // case 2. try each matched BSS
+ else
+ {
+ pAd->MlmeAux.BssIdx = 0;
+
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitJoinProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+
+ if (Elem->MsgType == MT2_JOIN_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ // 1. joined an IBSS, we are pretty much done here
+ if (pAd->MlmeAux.BssType == BSS_ADHOC)
+ {
+ //
+ // 5G bands rules of Japan:
+ // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
+ //
+ if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
+ RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
+ )
+ {
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Join adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+ return;
+ }
+
+ LinkUp(pAd, BSS_ADHOC);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - join the IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+ pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
+ pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
+
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ }
+ // 2. joined a new INFRA network, start from authentication
+ else
+ {
+#ifdef LEAP_SUPPORT
+ // Add AuthMode "LEAP" for CCX 1.X
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+ }
+ else
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+ }
+ }
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH;
+ }
+ }
+ else
+ {
+ // 3. failed, try next BSS
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitStartProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Result;
+
+ if (Elem->MsgType == MT2_START_CONF)
+ {
+ NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
+ if (Result == MLME_SUCCESS)
+ {
+ //
+ // 5G bands rules of Japan:
+ // Ad hoc must be disabled in W53(ch52,56,60,64) channels.
+ //
+ if ( (pAd->CommonCfg.bIEEE80211H == 1) &&
+ RadarChannelCheck(pAd, pAd->CommonCfg.Channel)
+ )
+ {
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Channel=%d, Start adhoc on W53(52,56,60,64) Channels are not accepted\n", pAd->CommonCfg.Channel));
+ return;
+ }
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ N_ChannelCheck(pAd);
+ SetCommonHT(pAd);
+ NdisMoveMemory(&pAd->MlmeAux.AddHtInfo, &pAd->CommonCfg.AddHTInfo, sizeof(ADD_HT_INFO_IE));
+ RTMPCheckHt(pAd, BSSID_WCID, &pAd->CommonCfg.HtCapability, &pAd->CommonCfg.AddHTInfo);
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
+ NdisZeroMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], 16);
+ NdisMoveMemory(&pAd->StaActive.SupportedPhyInfo.MCSSet[0], &pAd->CommonCfg.HtCapability.MCSSet[0], 16);
+ COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
+ {
+ pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel + 2;
+ }
+ else if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
+ {
+ pAd->MlmeAux.CentralChannel = pAd->CommonCfg.Channel - 2;
+ }
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+ }
+ LinkUp(pAd, BSS_ADHOC);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ // Before send beacon, driver need do radar detection
+ if ((pAd->CommonCfg.Channel > 14 )
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ pAd->CommonCfg.RadarDetect.RDMode = RD_SILENCE_MODE;
+ pAd->CommonCfg.RadarDetect.RDCount = 0;
+#ifdef DFS_SUPPORT
+ BbpRadarDetectionStart(pAd);
+#endif // DFS_SUPPORT //
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - start a new IBSS = %02x:%02x:%02x:%02x:%02x:%02x ...\n",
+ pAd->CommonCfg.Bssid[0],pAd->CommonCfg.Bssid[1],pAd->CommonCfg.Bssid[2],
+ pAd->CommonCfg.Bssid[3],pAd->CommonCfg.Bssid[4],pAd->CommonCfg.Bssid[5]));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Start IBSS fail. BUG!!!!!\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitAuthProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+ MLME_ASSOC_REQ_STRUCT AssocReq;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+
+ if (Elem->MsgType == MT2_AUTH_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
+ AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
+ ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+
+#ifdef LEAP_SUPPORT
+ //
+ // Cisco Leap CCKM supported Re-association.
+ //
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ {
+ //if CCKM is turn on , that's mean Fast Reauthentication
+ //Use CCKM Reassociation instead of normal association for Fast Roaming.
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
+ }
+ }
+ else
+ {
+ // This fail may because of the AP already keep us in its MAC table without
+ // ageing-out. The previous authentication attempt must have let it remove us.
+ // so try Authentication again may help. For D-Link DWL-900AP+ compatibility.
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try again...\n"));
+#ifdef LEAP_SUPPORT
+ //Add AuthMode "LEAP" for CCX 1.X
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, CISCO_AuthModeLEAP);
+ }
+ else
+#endif // LEAP_SUPPORT //
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeShared) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch))
+ {
+ // either Ndis802_11AuthModeShared or Ndis802_11AuthModeAutoSwitch, try shared key first
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeShared);
+ }
+ else
+ {
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+ }
+ }
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitAuthProc2(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+ MLME_ASSOC_REQ_STRUCT AssocReq;
+ MLME_AUTH_REQ_STRUCT AuthReq;
+
+ if (Elem->MsgType == MT2_AUTH_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH OK\n"));
+ AssocParmFill(pAd, &AssocReq, pAd->MlmeAux.Bssid, pAd->MlmeAux.CapabilityInfo,
+ ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_ASSOC_REQ,
+ sizeof(MLME_ASSOC_REQ_STRUCT), &AssocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_ASSOC;
+ }
+ else
+ {
+#ifdef LEAP_SUPPORT
+ // Process LEAP first, since it use different control variable
+ // We don't want to affect other poven operation
+ if (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+ {
+ // LEAP Auth not success, try next BSS
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - *LEAP* AUTH FAIL, give up; try next BSS\n"));
+ DBGPRINT(RT_DEBUG_TRACE, ("Total match BSSID [=%d]\n", pAd->MlmeAux.SsidBssTab.BssNr));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ else
+#endif // LEAP_SUPPORT //
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeAutoSwitch) &&
+ (pAd->MlmeAux.Alg == Ndis802_11AuthModeShared))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, try OPEN system...\n"));
+ AuthParmFill(pAd, &AuthReq, pAd->MlmeAux.Bssid, Ndis802_11AuthModeOpen);
+ MlmeEnqueue(pAd, AUTH_STATE_MACHINE, MT2_MLME_AUTH_REQ,
+ sizeof(MLME_AUTH_REQ_STRUCT), &AuthReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_AUTH2;
+ }
+ else
+ {
+ // not success, try next BSS
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - AUTH FAIL, give up; try next BSS\n"));
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; //???????
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitAssocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Reason;
+
+ if (Elem->MsgType == MT2_ASSOC_CONF)
+ {
+ NdisMoveMemory(&Reason, Elem->Msg, sizeof(USHORT));
+ if (Reason == MLME_SUCCESS)
+ {
+ LinkUp(pAd, BSS_INFRA);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association successful on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ }
+ else
+ {
+ // not success, try next BSS
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Association fails on BSS #%ld\n",pAd->MlmeAux.BssIdx));
+ pAd->MlmeAux.BssIdx++;
+ IterateOnBssTab(pAd);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID CntlWaitReassocProc(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Result;
+
+ if (Elem->MsgType == MT2_REASSOC_CONF)
+ {
+ NdisMoveMemory(&Result, Elem->Msg, sizeof(USHORT));
+ if (Result == MLME_SUCCESS)
+ {
+ //
+ // NDIS requires a new Link UP indication but no Link Down for RE-ASSOC
+ //
+ LinkUp(pAd, BSS_INFRA);
+
+ // send wireless event - for association
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_ASSOC_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+
+#ifdef LEAP_SUPPORT
+ if (LEAP_CCKM_ON(pAd))
+ {
+ STA_PORT_SECURED(pAd);
+ pAd->StaCfg.WpaState = SS_FINISH;
+ }
+#endif // LEAP_SUPPORT //
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition successful on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
+ }
+ else
+ {
+ // reassoc failed, try to pick next BSS in the BSS Table
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - Re-assocition fails on BSS #%ld\n", pAd->MlmeAux.RoamIdx));
+ pAd->MlmeAux.RoamIdx++;
+ IterateOnBssTab2(pAd);
+ }
+ }
+}
+
+
+VOID AdhocTurnOnQos(
+ IN PRTMP_ADAPTER pAd)
+{
+#define AC0_DEF_TXOP 0
+#define AC1_DEF_TXOP 0
+#define AC2_DEF_TXOP 94
+#define AC3_DEF_TXOP 47
+
+ // Turn on QOs if use HT rate.
+ if (pAd->CommonCfg.APEdcaParm.bValid == FALSE)
+ {
+ pAd->CommonCfg.APEdcaParm.bValid = TRUE;
+ pAd->CommonCfg.APEdcaParm.Aifsn[0] = 3;
+ pAd->CommonCfg.APEdcaParm.Aifsn[1] = 7;
+ pAd->CommonCfg.APEdcaParm.Aifsn[2] = 1;
+ pAd->CommonCfg.APEdcaParm.Aifsn[3] = 1;
+
+ pAd->CommonCfg.APEdcaParm.Cwmin[0] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[1] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmin[2] = 3;
+ pAd->CommonCfg.APEdcaParm.Cwmin[3] = 2;
+
+ pAd->CommonCfg.APEdcaParm.Cwmax[0] = 10;
+ pAd->CommonCfg.APEdcaParm.Cwmax[1] = 6;
+ pAd->CommonCfg.APEdcaParm.Cwmax[2] = 4;
+ pAd->CommonCfg.APEdcaParm.Cwmax[3] = 3;
+
+ pAd->CommonCfg.APEdcaParm.Txop[0] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[1] = 0;
+ pAd->CommonCfg.APEdcaParm.Txop[2] = AC2_DEF_TXOP;
+ pAd->CommonCfg.APEdcaParm.Txop[3] = AC3_DEF_TXOP;
+ }
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID LinkUp(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR BssType)
+{
+ ULONG Now;
+ UINT32 Data;
+ BOOLEAN Cancelled;
+ UCHAR Value = 0, idx;
+ MAC_TABLE_ENTRY *pEntry = NULL, *pCurrEntry;
+
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+
+ //
+ // ASSOC - DisassocTimeoutAction
+ // CNTL - Dis-associate successful
+ // !!! LINK DOWN !!!
+ // [88888] OID_802_11_SSID should have returned NDTEST_WEP_AP2(Returned: )
+ //
+ // To prevent DisassocTimeoutAction to call Link down after we link up,
+ // cancel the DisassocTimer no matter what it start or not.
+ //
+ RTMPCancelTimer(&pAd->MlmeAux.DisassocTimer, &Cancelled);
+
+ COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+
+#ifdef DOT11_N_SUPPORT
+ COPY_HTSETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(pAd);
+#endif // DOT11_N_SUPPORT //
+ // It's quite difficult to tell if a newly added KEY is WEP or CKIP until a new BSS
+ // is formed (either ASSOC/RE-ASSOC done or IBSS started. LinkUP should be a safe place
+ // to examine if cipher algorithm switching is required.
+ //rt2860b. Don't know why need this
+ SwitchBetweenWepAndCkip(pAd);
+
+
+ if (BssType == BSS_ADHOC)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE))
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel + 2;
+ }
+ else if ((pAd->CommonCfg.Channel > 2) &&
+ (pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth == BW_40) &&
+ (pAd->CommonCfg.AddHTInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW))
+ {
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel - 2;
+ }
+#endif // DOT11_N_SUPPORT //
+
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ // No carrier detection when adhoc
+ // CarrierDetectionStop(pAd);
+ pAd->CommonCfg.CarrierDetect.CD_State = CD_NORMAL;
+#endif // CARRIER_DETECTION_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ AdhocTurnOnQos(pAd);
+#endif // DOT11_N_SUPPORT //
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!Adhoc LINK UP !!! \n" ));
+ }
+ else
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_INFRA_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!Infra LINK UP !!! \n" ));
+ }
+
+ // 3*3
+ // reset Tx beamforming bit
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x01);
+ Value |= pAd->CommonCfg.RegTransmitSetting.field.TxBF;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+#ifdef DOT11_N_SUPPORT
+ // Change to AP channel
+ if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ // RX : control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!40MHz Lower LINK UP !!! Control Channel at Below. Central = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ // Must using 40MHz.
+ pAd->CommonCfg.BBPCurrentBW = BW_40;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ Value |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data |= 0x1;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value |= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x1A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x0A);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x16);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! 40MHz Upper LINK UP !!! Control Channel at UpperCentral = %d \n", pAd->CommonCfg.CentralChannel ));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &Value);
+ Value &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, Value);
+
+ RTMP_IO_READ32(pAd, TX_BAND_CFG, &Data);
+ Data &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAd, TX_BAND_CFG, Data);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &Value);
+ Value &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, Value);
+
+ if (pAd->MACVersion == 0x28600100)
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R69, 0x16);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R70, 0x08);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R73, 0x11);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!rt2860C !!! \n" ));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! 20MHz LINK UP !!! \n" ));
+ }
+
+ RTMPSetAGCInitValue(pAd, pAd->CommonCfg.BBPCurrentBW);
+ //
+ // Save BBP_R66 value, it will be used in RTUSBResumeMsduTransmission
+ //
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R66, &pAd->BbpTuning.R66CurrentValue);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (BssType=%d, AID=%d, ssid=%s, Channel=%d, CentralChannel = %d)\n",
+ BssType, pAd->StaActive.Aid, pAd->CommonCfg.Ssid, pAd->CommonCfg.Channel, pAd->CommonCfg.CentralChannel));
+
+#ifdef DOT11_N_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! (Density =%d, )\n", pAd->MacTab.Content[BSSID_WCID].MpduDensity));
+#endif // DOT11_N_SUPPORT //
+
+ AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+
+ AsicSetSlotTime(pAd, TRUE);
+ AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm);
+
+ // Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit
+ AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE);
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE))
+ {
+ // Update HT protectionfor based on AP's operating mode.
+ if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
+ }
+ else
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ NdisZeroMemory(&pAd->DrsCounters, sizeof(COUNTER_DRS));
+
+ NdisGetSystemUpTime(&Now);
+ pAd->StaCfg.LastBeaconRxTime = Now; // last RX timestamp
+
+ if ((pAd->CommonCfg.TxPreamble != Rt802_11PreambleLong) &&
+ CAP_IS_SHORT_PREAMBLE_ON(pAd->StaActive.CapabilityInfo))
+ {
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleShort);
+ }
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+
+ if (pAd->CommonCfg.RadarDetect.RDMode == RD_SILENCE_MODE)
+ {
+#ifdef DFS_SUPPORT
+ RadarDetectionStop(pAd);
+#endif // DFS_SUPPORT //
+ }
+ pAd->CommonCfg.RadarDetect.RDMode = RD_NORMAL_MODE;
+
+ if (BssType == BSS_ADHOC)
+ {
+ MakeIbssBeacon(pAd);
+ if ((pAd->CommonCfg.Channel > 14)
+ && (pAd->CommonCfg.bIEEE80211H == 1)
+ && RadarChannelCheck(pAd, pAd->CommonCfg.Channel))
+ {
+ ; //Do nothing
+ }
+ else
+ {
+ AsicEnableIbssSync(pAd);
+ }
+
+ // In ad hoc mode, use MAC table from index 1.
+ // p.s ASIC use all 0xff as termination of WCID table search.To prevent it's 0xff-ff-ff-ff-ff-ff, Write 0 here.
+ RTMP_IO_WRITE32(pAd, MAC_WCID_BASE, 0x00);
+ RTMP_IO_WRITE32(pAd, 0x1808, 0x00);
+
+ // If WEP is enabled, add key material and cipherAlg into Asic
+ // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
+
+ if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
+ {
+ PUCHAR Key;
+ UCHAR CipherAlg;
+
+ for (idx=0; idx < SHARE_KEY_NUM; idx++)
+ {
+ CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
+ Key = pAd->SharedKey[BSS0][idx].Key;
+
+ if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
+ {
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+
+ if (idx == pAd->StaCfg.DefaultKeyId)
+ {
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+ }
+ }
+
+
+ }
+ }
+ // If WPANone is enabled, add key material and cipherAlg into Asic
+ // Fill in Shared Key Table(offset: 0x6c00) and Shared Key Mode(offset: 0x7000)
+ else if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ pAd->StaCfg.DefaultKeyId = 0; // always be zero
+
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pAd->StaCfg.PMK, LEN_TKIP_EK);
+
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PMK[16], LEN_TKIP_TXMICK);
+ }
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Unknow Cipher (=%d), set Cipher to AES\n", pAd->StaCfg.PairCipher));
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ }
+
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAd, BSS0, 0, pAd->SharedKey[BSS0][0].CipherAlg, NULL);
+
+ }
+
+ }
+ else // BSS_INFRA
+ {
+ // Check the new SSID with last SSID
+ while (Cancelled == TRUE)
+ {
+ if (pAd->CommonCfg.LastSsidLen == pAd->CommonCfg.SsidLen)
+ {
+ if (RTMPCompareMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen) == 0)
+ {
+ // Link to the old one no linkdown is required.
+ break;
+ }
+ }
+ // Send link down event before set to link up
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event AA!\n"));
+ break;
+ }
+
+ //
+ // On WPA mode, Remove All Keys if not connect to the last BSSID
+ // Key will be set after 4-way handshake.
+ //
+ if ((pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ ULONG IV;
+
+ // Remove all WPA keys
+ RTMPWPARemoveAllKeys(pAd);
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+
+ // Fixed connection failed with Range Maximizer - 515 AP (Marvell Chip) when security is WPAPSK/TKIP
+ // If IV related values are too large in GroupMsg2, AP would ignore this message.
+ IV = 0;
+ IV |= (pAd->StaCfg.DefaultKeyId << 30);
+ AsicUpdateWCIDIVEIV(pAd, BSSID_WCID, IV, 0);
+ }
+ // NOTE:
+ // the decision of using "short slot time" or not may change dynamically due to
+ // new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+
+ // NOTE:
+ // the decision to use "RTC/CTS" or "CTS-to-self" protection or not may change dynamically
+ // due to new STA association to the AP. so we have to decide that upon parsing BEACON, not here
+
+ ComposePsPoll(pAd);
+ ComposeNullFrame(pAd);
+
+ AsicEnableBssSync(pAd);
+
+ // Add BSSID to WCID search table
+ AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid);
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ // add this BSSID entry into HASH table
+ {
+ UCHAR HashIdx;
+
+ //pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ HashIdx = MAC_ADDR_HASH_INDEX(pAd->CommonCfg.Bssid);
+ if (pAd->MacTab.Hash[HashIdx] == NULL)
+ {
+ pAd->MacTab.Hash[HashIdx] = pEntry;
+ }
+ else
+ {
+ pCurrEntry = pAd->MacTab.Hash[HashIdx];
+ while (pCurrEntry->pNext != NULL)
+ pCurrEntry = pCurrEntry->pNext;
+ pCurrEntry->pNext = pEntry;
+ }
+ }
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+
+ // If WEP is enabled, add paiewise and shared key
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (((pAd->StaCfg.WpaSupplicantUP)&&
+ (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)&&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) ||
+ ((pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_DISABLE)&&
+ (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)))
+#else
+ if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled)
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ PUCHAR Key;
+ UCHAR CipherAlg;
+
+ for (idx=0; idx < SHARE_KEY_NUM; idx++)
+ {
+ CipherAlg = pAd->SharedKey[BSS0][idx].CipherAlg;
+ Key = pAd->SharedKey[BSS0][idx].Key;
+
+ if (pAd->SharedKey[BSS0][idx].KeyLen > 0)
+ {
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAd, BSS0, idx, CipherAlg, Key, NULL, NULL);
+
+ if (idx == pAd->StaCfg.DefaultKeyId)
+ {
+ // Assign group key info
+ RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, NULL);
+
+ // Assign pairwise key info
+ RTMPAddWcidAttributeEntry(pAd, BSS0, idx, CipherAlg, pEntry);
+ }
+ }
+ }
+ }
+
+ // only INFRASTRUCTURE mode need to indicate connectivity immediately; ADHOC mode
+ // should wait until at least 2 active nodes in this BSSID.
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+ // For GUI ++
+ if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ {
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ RTMP_IndicateMediaState(pAd);
+ }
+ // --
+
+ // Add BSSID in my MAC Table.
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ RTMPMoveMemory(pAd->MacTab.Content[BSSID_WCID].Addr, pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+ pAd->MacTab.Content[BSSID_WCID].Aid = BSSID_WCID;
+ pAd->MacTab.Content[BSSID_WCID].pAd = pAd;
+ pAd->MacTab.Content[BSSID_WCID].ValidAsCLI = TRUE; //Although this is bssid..still set ValidAsCl
+ pAd->MacTab.Size = 1; // infra mode always set MACtab size =1.
+ pAd->MacTab.Content[BSSID_WCID].Sst = SST_ASSOC;
+ pAd->MacTab.Content[BSSID_WCID].AuthState = SST_ASSOC;
+ pAd->MacTab.Content[BSSID_WCID].AuthMode = pAd->StaCfg.AuthMode;
+ pAd->MacTab.Content[BSSID_WCID].WepStatus = pAd->StaCfg.WepStatus;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !!! ClientStatusFlags=%lx)\n",
+ pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+
+ MlmeUpdateTxRates(pAd, TRUE, BSS0);
+#ifdef DOT11_N_SUPPORT
+ MlmeUpdateHtTxRates(pAd, BSS0);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK UP !! (StaActive.bHtEnable =%d, )\n", pAd->StaActive.SupportedPhyInfo.bHtEnable));
+#endif // DOT11_N_SUPPORT //
+
+ //
+ // Report Adjacent AP report.
+ //
+#ifdef LEAP_SUPPORT
+ CCXAdjacentAPReport(pAd);
+#endif // LEAP_SUPPORT //
+
+ if (pAd->CommonCfg.bAggregationCapable)
+ {
+ if ((pAd->CommonCfg.bPiggyBackCapable) && (pAd->MlmeAux.APRalinkIe & 0x00000003) == 3)
+ {
+
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+ RTMPSetPiggyBack(pAd, TRUE);
+ DBGPRINT(RT_DEBUG_TRACE, ("Turn on Piggy-Back\n"));
+ }
+ else if (pAd->MlmeAux.APRalinkIe & 0x00000001)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+ }
+ }
+
+ if (pAd->MlmeAux.APRalinkIe != 0x0)
+ {
+#ifdef DOT11_N_SUPPORT
+ if (CLIENT_STATUS_TEST_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RDG_CAPABLE))
+ {
+ AsicEnableRDG(pAd);
+ }
+#endif // DOT11_N_SUPPORT //
+ OPSTATUS_SET_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
+ CLIENT_STATUS_SET_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
+ }
+ else
+ {
+ OPSTATUS_CLEAR_FLAG(pAd, fCLIENT_STATUS_RALINK_CHIPSET);
+ CLIENT_STATUS_CLEAR_FLAG(&pAd->MacTab.Content[BSSID_WCID], fCLIENT_STATUS_RALINK_CHIPSET);
+ }
+ }
+
+#ifdef DOT11_N_SUPPORT
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_CONNECT Event B!.BACapability = %x. ClientStatusFlags = %lx\n", pAd->CommonCfg.BACapability.word, pAd->MacTab.Content[BSSID_WCID].ClientStatusFlags));
+#endif // DOT11_N_SUPPORT //
+
+ // Set LED
+ RTMPSetLED(pAd, LED_LINK_UP);
+
+ pAd->Mlme.PeriodicRound = 0;
+ pAd->Mlme.OneSecPeriodicRound = 0;
+ pAd->bConfigChanged = FALSE; // Reset config flag
+ pAd->ExtraInfo = GENERAL_LINK_UP; // Update extra information to link is up
+
+ // Set asic auto fall back
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, &pAd->MacTab.Content[BSSID_WCID], &pTable, &TableSize, &pAd->CommonCfg.TxRateIndex);
+ AsicUpdateAutoFallBackTable(pAd, pTable);
+ }
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pEntry->HTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+ pEntry->MaxHTPhyMode.word = pAd->StaCfg.HTPhyMode.word;
+ if (pAd->StaCfg.bAutoTxRateSwitch == FALSE)
+ {
+ pEntry->bAutoTxRateSwitch = FALSE;
+#ifdef DOT11_N_SUPPORT
+ if (pEntry->HTPhyMode.field.MCS == 32)
+ pEntry->HTPhyMode.field.ShortGI = GI_800;
+
+ if ((pEntry->HTPhyMode.field.MCS > MCS_7) || (pEntry->HTPhyMode.field.MCS == 32))
+ pEntry->HTPhyMode.field.STBC = STBC_NONE;
+#endif // DOT11_N_SUPPORT //
+ // If the legacy mode is set, overwrite the transmit setting of this entry.
+ if (pEntry->HTPhyMode.field.MODE <= MODE_OFDM)
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ else
+ pEntry->bAutoTxRateSwitch = TRUE;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ // Let Link Status Page display first initial rate.
+ pAd->LastTxRate = (USHORT)(pEntry->HTPhyMode.word);
+ // Select DAC according to HT or Legacy
+ if (pAd->StaActive.SupportedPhyInfo.MCSSet[0] != 0x00)
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
+ Value &= (~0x18);
+ if (pAd->Antenna.field.TxPath == 2)
+ {
+ Value |= 0x10;
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
+ }
+ else
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &Value);
+ Value &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, Value);
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE)
+ {
+ }
+ else if (pEntry->MaxRAmpduFactor == 0)
+ {
+ // If HT AP doesn't support MaxRAmpduFactor = 1, we need to set max PSDU to 0.
+ // Because our Init value is 1 at MACRegTable.
+ RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x0fff);
+ }
+#endif // DOT11_N_SUPPORT //
+
+ // Patch for Marvel AP to gain high throughput
+ // Need to set as following,
+ // 1. Set txop in register-EDCA_AC0_CFG as 0x60
+ // 2. Set EnTXWriteBackDDONE in register-WPDMA_GLO_CFG as zero
+ // 3. PBF_MAX_PCNT as 0x1F3FBF9F
+ // 4. kick per two packets when dequeue
+ //
+ // Txop can only be modified when RDG is off, WMM is disable and TxBurst is enable
+ //
+ // if 1. Legacy AP WMM on, or 2. 11n AP, AMPDU disable. Force turn off burst no matter what bEnableTxBurst is.
+#ifdef DOT11_N_SUPPORT
+// if ((!IS_RT30xx(pAd)) &&
+ if (!((pAd->CommonCfg.RxStream == 1)&&(pAd->CommonCfg.TxStream == 1)) &&
+ (((pAd->StaActive.SupportedPhyInfo.bHtEnable == FALSE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED))
+ || ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE) && (pAd->CommonCfg.BACapability.field.Policy == BA_NOTUSE))))
+ {
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
+ DBGPRINT(RT_DEBUG_TRACE, ("Txburst 1\n"));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if (pAd->CommonCfg.bEnableTxBurst)
+ {
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ Data |= 0x60;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+ pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = TRUE;
+
+ RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3FBF9F);
+ DBGPRINT(RT_DEBUG_TRACE, ("Txburst 2\n"));
+ }
+ else
+ {
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &Data);
+ Data &= 0xFFFFFF00;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, Data);
+
+ RTMP_IO_WRITE32(pAd, PBF_MAX_PCNT, 0x1F3F7F9F);
+ DBGPRINT(RT_DEBUG_TRACE, ("Txburst 3\n"));
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // Re-check to turn on TX burst or not.
+ if ((pAd->CommonCfg.IOTestParm.bLastAtheros == TRUE) && ((STA_WEP_ON(pAd))||(STA_TKIP_ON(pAd))))
+ {
+ pAd->CommonCfg.IOTestParm.bNextDisableRxBA = TRUE;
+ if (pAd->CommonCfg.bEnableTxBurst)
+ {
+ UINT32 MACValue = 0;
+ // Force disable TXOP value in this case. The same action in MLMEUpdateProtect too.
+ // I didn't change PBF_MAX_PCNT setting.
+ RTMP_IO_READ32(pAd, EDCA_AC0_CFG, &MACValue);
+ MACValue &= 0xFFFFFF00;
+ RTMP_IO_WRITE32(pAd, EDCA_AC0_CFG, MACValue);
+ pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
+ }
+ }
+ else
+ {
+ pAd->CommonCfg.IOTestParm.bNextDisableRxBA = FALSE;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pAd->CommonCfg.IOTestParm.bLastAtheros = FALSE;
+ COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!!pAd->bNextDisableRxBA= %d \n", pAd->CommonCfg.IOTestParm.bNextDisableRxBA));
+ // BSSID add in one MAC entry too. Because in Tx, ASIC need to check Cipher and IV/EIV, BAbitmap
+ // Pther information in MACTab.Content[BSSID_WCID] is not necessary for driver.
+ // Note: As STA, The MACTab.Content[BSSID_WCID]. PairwiseKey and Shared Key for BSS0 are the same.
+
+ if (pAd->StaCfg.WepStatus <= Ndis802_11WEPDisabled)
+ {
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilterAcceptAll;
+ }
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pEntry->PortSecured = pAd->StaCfg.PortSecured;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ //
+ // Patch Atheros AP TX will breakdown issue.
+ // AP Model: DLink DWL-8200AP
+ //
+ if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) && STA_TKIP_ON(pAd))
+ {
+ RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x01);
+ }
+ else
+ {
+ RTMP_IO_WRITE32(pAd, RX_PARSER_CFG, 0x00);
+ }
+
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if ((pAd->CommonCfg.BACapability.field.b2040CoexistScanSup) && (pAd->CommonCfg.Channel <= 11))
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_SCAN_2040);
+ BuildEffectedChannelList(pAd);
+ }
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+}
+
+/*
+ ==========================================================================
+
+ Routine Description:
+ Disconnect current BSSID
+
+ Arguments:
+ pAd - Pointer to our adapter
+ IsReqFromAP - Request from AP
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ We need more information to know it's this requst from AP.
+ If yes! we need to do extra handling, for example, remove the WPA key.
+ Otherwise on 4-way handshaking will faied, since the WPA key didn't be
+ remove while auto reconnect.
+ Disconnect request from AP, it means we will start afresh 4-way handshaking
+ on WPA mode.
+
+ ==========================================================================
+*/
+VOID LinkDown(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN IsReqFromAP)
+{
+ UCHAR i, ByteValue = 0;
+
+ // Do nothing if monitor mode is on
+ if (MONITOR_ON(pAd))
+ return;
+
+#ifdef RALINK_ATE
+ // Nothing to do in ATE mode.
+ if (ATE_ON(pAd))
+ return;
+#endif // RALINK_ATE //
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN !!!\n"));
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED);
+
+ if (ADHOC_ON(pAd)) // Adhoc mode link down
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 1!!!\n"));
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MacTab.Size=%d !!!\n", pAd->MacTab.Size));
+ }
+ else // Infra structure mode
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! LINK DOWN 2!!!\n"));
+
+#ifdef QOS_DLS_SUPPORT
+ // DLS tear down frame must be sent before link down
+ // send DLS-TEAR_DOWN message
+ if (pAd->CommonCfg.bDLSCapable)
+ {
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ RTMPSendDLSTearDownFrame(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_INFRA_ON);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+ // Saved last SSID for linkup comparison
+ pAd->CommonCfg.LastSsidLen = pAd->CommonCfg.SsidLen;
+ NdisMoveMemory(pAd->CommonCfg.LastSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.LastSsidLen);
+ COPY_MAC_ADDR(pAd->CommonCfg.LastBssid, pAd->CommonCfg.Bssid);
+ if (pAd->MlmeAux.CurrReqIsFromNdis == TRUE)
+ {
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event A!\n"));
+ pAd->MlmeAux.CurrReqIsFromNdis = FALSE;
+ }
+ else
+ {
+ //
+ // If disassociation request is from NDIS, then we don't need to delete BSSID from entry.
+ // Otherwise lost beacon or receive De-Authentication from AP,
+ // then we should delete BSSID from BssTable.
+ // If we don't delete from entry, roaming will fail.
+ //
+ BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel);
+ }
+
+ // restore back to -
+ // 1. long slot (20 us) or short slot (9 us) time
+ // 2. turn on/off RTS/CTS and/or CTS-to-self protection
+ // 3. short preamble
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+
+ if (pAd->StaCfg.CCXAdjacentAPReportFlag == TRUE)
+ {
+ //
+ // Record current AP's information.
+ // for later used reporting Adjacent AP report.
+ //
+ pAd->StaCfg.CCXAdjacentAPChannel = pAd->CommonCfg.Channel;
+ pAd->StaCfg.CCXAdjacentAPSsidLen = pAd->CommonCfg.SsidLen;
+ NdisMoveMemory(pAd->StaCfg.CCXAdjacentAPSsid, pAd->CommonCfg.Ssid, pAd->StaCfg.CCXAdjacentAPSsidLen);
+ COPY_MAC_ADDR(pAd->StaCfg.CCXAdjacentAPBssid, pAd->CommonCfg.Bssid);
+ }
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ // Country IE of the AP will be evaluated and will be used.
+ if (pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None)
+ {
+ NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pAd->StaCfg.StaOriCountryCode[0], 2);
+ pAd->CommonCfg.Geography = pAd->StaCfg.StaOriGeography;
+ BuildChannelListEx(pAd);
+ }
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ }
+
+ for (i=1; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ if (pAd->MacTab.Content[i].ValidAsCLI == TRUE)
+ MacTableDeleteEntry(pAd, pAd->MacTab.Content[i].Aid, pAd->MacTab.Content[i].Addr);
+ }
+
+ pAd->StaCfg.CCXQosECWMin = 4;
+ pAd->StaCfg.CCXQosECWMax = 10;
+
+ AsicSetSlotTime(pAd, TRUE); //FALSE);
+ AsicSetEdcaParm(pAd, NULL);
+
+ // Set LED
+ RTMPSetLED(pAd, LED_LINK_DOWN);
+ pAd->LedIndicatorStregth = 0xF0;
+ RTMPSetSignalLED(pAd, -100); // Force signal strength Led to be turned off, firmware is not done it.
+
+ AsicDisableSync(pAd);
+
+ pAd->Mlme.PeriodicRound = 0;
+ pAd->Mlme.OneSecPeriodicRound = 0;
+
+ if (pAd->StaCfg.BssType == BSS_INFRA)
+ {
+ // Remove StaCfg Information after link down
+ NdisZeroMemory(pAd->CommonCfg.Bssid, MAC_ADDR_LEN);
+ NdisZeroMemory(pAd->CommonCfg.Ssid, MAX_LEN_OF_SSID);
+ pAd->CommonCfg.SsidLen = 0;
+ }
+#ifdef DOT11_N_SUPPORT
+ NdisZeroMemory(&pAd->MlmeAux.HtCapability, sizeof(HT_CAPABILITY_IE));
+ NdisZeroMemory(&pAd->MlmeAux.AddHtInfo, sizeof(ADD_HT_INFO_IE));
+ pAd->MlmeAux.HtCapabilityLen = 0;
+ pAd->MlmeAux.NewExtChannelOffset = 0xff;
+#endif // DOT11_N_SUPPORT //
+
+ // Reset WPA-PSK state. Only reset when supplicant enabled
+ if (pAd->StaCfg.WpaState != SS_NOTUSE)
+ {
+ pAd->StaCfg.WpaState = SS_START;
+ // Clear Replay counter
+ NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+
+#ifdef QOS_DLS_SUPPORT
+ if (pAd->CommonCfg.bDLSCapable)
+ NdisZeroMemory(pAd->StaCfg.DlsReplayCounter, 8);
+#endif // QOS_DLS_SUPPORT //
+ }
+
+
+ //
+ // if link down come from AP, we need to remove all WPA keys on WPA mode.
+ // otherwise will cause 4-way handshaking failed, since the WPA key not empty.
+ //
+ if ((IsReqFromAP) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ // Remove all WPA keys
+ RTMPWPARemoveAllKeys(pAd);
+ }
+
+ // 802.1x port control
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // Prevent clear PortSecured here with static WEP
+ // NetworkManger set security policy first then set SSID to connect AP.
+ if (pAd->StaCfg.WpaSupplicantUP &&
+ (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) &&
+ (pAd->StaCfg.IEEE8021X == FALSE))
+ {
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ pAd->StaCfg.PrivacyFilter = Ndis802_11PrivFilter8021xWEP;
+ }
+
+ NdisAcquireSpinLock(&pAd->MacTabLock);
+ pAd->MacTab.Content[BSSID_WCID].PortSecured = pAd->StaCfg.PortSecured;
+ NdisReleaseSpinLock(&pAd->MacTabLock);
+
+ pAd->StaCfg.MicErrCnt = 0;
+
+ // Turn off Ckip control flag
+ pAd->StaCfg.bCkipOn = FALSE;
+ pAd->StaCfg.CCXEnable = FALSE;
+
+ pAd->IndicateMediaState = NdisMediaStateDisconnected;
+ // Update extra information to link is up
+ pAd->ExtraInfo = GENERAL_LINK_DOWN;
+
+ //pAd->StaCfg.AdhocBOnlyJoined = FALSE;
+ //pAd->StaCfg.AdhocBGJoined = FALSE;
+ //pAd->StaCfg.Adhoc20NJoined = FALSE;
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+
+ // Reset the Current AP's IP address
+ NdisZeroMemory(pAd->StaCfg.AironetIPAddress, 4);
+#ifdef RT2870
+ pAd->bUsbTxBulkAggre = FALSE;
+#endif // RT2870 //
+
+ // Clean association information
+ NdisZeroMemory(&pAd->StaCfg.AssocInfo, sizeof(NDIS_802_11_ASSOCIATION_INFORMATION));
+ pAd->StaCfg.AssocInfo.Length = sizeof(NDIS_802_11_ASSOCIATION_INFORMATION);
+ pAd->StaCfg.ReqVarIELen = 0;
+ pAd->StaCfg.ResVarIELen = 0;
+
+ //
+ // Reset RSSI value after link down
+ //
+ pAd->StaCfg.RssiSample.AvgRssi0 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi0X8 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi1 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi1X8 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi2 = 0;
+ pAd->StaCfg.RssiSample.AvgRssi2X8 = 0;
+
+ // Restore MlmeRate
+ pAd->CommonCfg.MlmeRate = pAd->CommonCfg.BasicMlmeRate;
+ pAd->CommonCfg.RtsRate = pAd->CommonCfg.BasicMlmeRate;
+
+#ifdef DOT11_N_SUPPORT
+ //
+ // After Link down, reset piggy-back setting in ASIC. Disable RDG.
+ //
+ if (pAd->CommonCfg.BBPCurrentBW == BW_40)
+ {
+ pAd->CommonCfg.BBPCurrentBW = BW_20;
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &ByteValue);
+ ByteValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, ByteValue);
+ }
+#endif // DOT11_N_SUPPORT //
+ // Reset DAC
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R1, &ByteValue);
+ ByteValue &= (~0x18);
+ if (pAd->Antenna.field.TxPath == 2)
+ {
+ ByteValue |= 0x10;
+ }
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R1, ByteValue);
+
+ RTMPSetPiggyBack(pAd,FALSE);
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_PIGGYBACK_INUSED);
+
+#ifdef DOT11_N_SUPPORT
+ pAd->CommonCfg.BACapability.word = pAd->CommonCfg.REGBACapability.word;
+#endif // DOT11_N_SUPPORT //
+
+ // Restore all settings in the following.
+ AsicUpdateProtect(pAd, 0, (ALLN_SETPROTECT|CCKSETPROTECT|OFDMSETPROTECT), TRUE, FALSE);
+ AsicDisableRDG(pAd);
+ pAd->CommonCfg.IOTestParm.bCurrentAtheros = FALSE;
+ pAd->CommonCfg.IOTestParm.bNowAtherosBurstOn = FALSE;
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_SCAN_2040);
+ pAd->CommonCfg.BSSCoexist2040.word = 0;
+ TriEventInit(pAd);
+ for (i = 0; i < (pAd->ChannelListNum - 1); i++)
+ {
+ pAd->ChannelList[i].bEffectedChannel = FALSE;
+ }
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+ RTMP_IO_WRITE32(pAd, MAX_LEN_CFG, 0x1fff);
+ RTMP_CLEAR_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#ifndef NATIVE_WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP) {
+ union iwreq_data wrqu;
+ //send disassociate event to wpa_supplicant
+ memset(&wrqu, 0, sizeof(wrqu));
+ wrqu.data.flags = RT_DISASSOC_EVENT_FLAG;
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+ {
+ union iwreq_data wrqu;
+ memset(wrqu.ap_addr.sa_data, 0, MAC_ADDR_LEN);
+ wireless_send_event(pAd->net_dev, SIOCGIWAP, &wrqu, NULL);
+ }
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+
+#ifdef RT30xx
+ if (IS_RT3090(pAd))
+ {
+ UINT32 macdata;
+ // disable MMPS BBP control register
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R3, &ByteValue);
+ ByteValue &= ~(0x04); //bit 2
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R3, ByteValue);
+
+ // disable MMPS MAC control register
+ RTMP_IO_READ32(pAd, 0x1210, &macdata);
+ macdata &= ~(0x09); //bit 0, 3
+ RTMP_IO_WRITE32(pAd, 0x1210, macdata);
+ }
+#endif // RT30xx //
+
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID IterateOnBssTab(
+ IN PRTMP_ADAPTER pAd)
+{
+ MLME_START_REQ_STRUCT StartReq;
+ MLME_JOIN_REQ_STRUCT JoinReq;
+ ULONG BssIdx;
+
+ // Change the wepstatus to original wepstatus
+ pAd->StaCfg.WepStatus = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.PairCipher = pAd->StaCfg.OrigWepStatus;
+ pAd->StaCfg.GroupCipher = pAd->StaCfg.OrigWepStatus;
+
+ BssIdx = pAd->MlmeAux.BssIdx;
+ if (BssIdx < pAd->MlmeAux.SsidBssTab.BssNr)
+ {
+ // Check cipher suite, AP must have more secured cipher than station setting
+ // Set the Pairwise and Group cipher to match the intended AP setting
+ // We can only connect to AP with less secured cipher setting
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipher;
+ else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ pAd->StaCfg.GroupCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.GroupCipher;
+
+ if (pAd->StaCfg.WepStatus == pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipher;
+ else if (pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux != Ndis802_11WEPDisabled)
+ pAd->StaCfg.PairCipher = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.PairCipherAux;
+ else // There is no PairCipher Aux, downgrade our capability to TKIP
+ pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+
+ // RSN capability
+ pAd->StaCfg.RsnCapability = pAd->MlmeAux.SsidBssTab.BssEntry[BssIdx].WPA2.RsnCapability;
+ }
+
+ // Set Mix cipher flag
+ pAd->StaCfg.bMixCipher = (pAd->StaCfg.PairCipher == pAd->StaCfg.GroupCipher) ? FALSE : TRUE;
+ if (pAd->StaCfg.bMixCipher == TRUE)
+ {
+ // If mix cipher, re-build RSNIE
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, 0);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.SsidBssTab.BssNr));
+ JoinParmFill(pAd, &JoinReq, BssIdx);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_JOIN_REQ, sizeof(MLME_JOIN_REQ_STRUCT),
+ &JoinReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_JOIN;
+ }
+ else if (pAd->StaCfg.BssType == BSS_ADHOC)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All BSS fail; start a new ADHOC (Ssid=%s)...\n",pAd->MlmeAux.Ssid));
+ StartParmFill(pAd, &StartReq, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen);
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_MLME_START_REQ, sizeof(MLME_START_REQ_STRUCT), &StartReq);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_START;
+ }
+ else // no more BSS
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All roaming failed, stay @ ch #%d\n", pAd->CommonCfg.Channel));
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+}
+
+// for re-association only
+// IRQL = DISPATCH_LEVEL
+VOID IterateOnBssTab2(
+ IN PRTMP_ADAPTER pAd)
+{
+ MLME_REASSOC_REQ_STRUCT ReassocReq;
+ ULONG BssIdx;
+ BSS_ENTRY *pBss;
+
+ BssIdx = pAd->MlmeAux.RoamIdx;
+ pBss = &pAd->MlmeAux.RoamTab.BssEntry[BssIdx];
+
+ if (BssIdx < pAd->MlmeAux.RoamTab.BssNr)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - iterate BSS %ld of %d\n", BssIdx, pAd->MlmeAux.RoamTab.BssNr));
+
+ AsicSwitchChannel(pAd, pBss->Channel, FALSE);
+ AsicLockChannel(pAd, pBss->Channel);
+
+ // reassociate message has the same structure as associate message
+ AssocParmFill(pAd, &ReassocReq, pBss->Bssid, pBss->CapabilityInfo,
+ ASSOC_TIMEOUT, pAd->StaCfg.DefaultListenCount);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_REASSOC_REQ,
+ sizeof(MLME_REASSOC_REQ_STRUCT), &ReassocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_REASSOC;
+ }
+ else // no more BSS
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CNTL - All fast roaming failed, back to ch #%d\n",pAd->CommonCfg.Channel));
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE;
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID JoinParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_JOIN_REQ_STRUCT *JoinReq,
+ IN ULONG BssIdx)
+{
+ JoinReq->BssIdx = BssIdx;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID ScanParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_SCAN_REQ_STRUCT *ScanReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen,
+ IN UCHAR BssType,
+ IN UCHAR ScanType)
+{
+ NdisZeroMemory(ScanReq->Ssid, MAX_LEN_OF_SSID);
+ ScanReq->SsidLen = SsidLen;
+ NdisMoveMemory(ScanReq->Ssid, Ssid, SsidLen);
+ ScanReq->BssType = BssType;
+ ScanReq->ScanType = ScanType;
+}
+
+#ifdef QOS_DLS_SUPPORT
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID DlsParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_DLS_REQ_STRUCT *pDlsReq,
+ IN PRT_802_11_DLS pDls,
+ IN USHORT reason)
+{
+ pDlsReq->pDLS = pDls;
+ pDlsReq->Reason = reason;
+}
+#endif // QOS_DLS_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID StartParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_START_REQ_STRUCT *StartReq,
+ IN CHAR Ssid[],
+ IN UCHAR SsidLen)
+{
+ ASSERT(SsidLen <= MAX_LEN_OF_SSID);
+ NdisMoveMemory(StartReq->Ssid, Ssid, SsidLen);
+ StartReq->SsidLen = SsidLen;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+VOID AuthParmFill(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT MLME_AUTH_REQ_STRUCT *AuthReq,
+ IN PUCHAR pAddr,
+ IN USHORT Alg)
+{
+ COPY_MAC_ADDR(AuthReq->Addr, pAddr);
+ AuthReq->Alg = Alg;
+ AuthReq->Timeout = AUTH_TIMEOUT;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+
+
+#ifdef RT2870
+
+VOID MlmeCntlConfirm(
+ IN PRTMP_ADAPTER pAd,
+ IN ULONG MsgType,
+ IN USHORT Msg)
+{
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MsgType, sizeof(USHORT), &Msg);
+}
+
+VOID ComposePsPoll(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTXINFO_STRUC pTxInfo;
+ PTXWI_STRUC pTxWI;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("ComposePsPoll\n"));
+ NdisZeroMemory(&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+
+ pAd->PsPollFrame.FC.PwrMgmt = 0;
+ pAd->PsPollFrame.FC.Type = BTYPE_CNTL;
+ pAd->PsPollFrame.FC.SubType = SUBTYPE_PS_POLL;
+ pAd->PsPollFrame.Aid = pAd->StaActive.Aid | 0xC000;
+ COPY_MAC_ADDR(pAd->PsPollFrame.Bssid, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pAd->PsPollFrame.Ta, pAd->CurrentAddress);
+
+ RTMPZeroMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0], 100);
+ pTxInfo = (PTXINFO_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[0];
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(PSPOLL_FRAME)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxWI = (PTXWI_STRUC)&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(PSPOLL_FRAME)),
+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ RTMPMoveMemory(&pAd->PsPollContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+ // Append 4 extra zero bytes.
+ pAd->PsPollContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(PSPOLL_FRAME) + 4;
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID ComposeNullFrame(
+ IN PRTMP_ADAPTER pAd)
+{
+ PTXINFO_STRUC pTxInfo;
+ PTXWI_STRUC pTxWI;
+
+ NdisZeroMemory(&pAd->NullFrame, sizeof(HEADER_802_11));
+ pAd->NullFrame.FC.Type = BTYPE_DATA;
+ pAd->NullFrame.FC.SubType = SUBTYPE_NULL_FUNC;
+ pAd->NullFrame.FC.ToDs = 1;
+ COPY_MAC_ADDR(pAd->NullFrame.Addr1, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pAd->NullFrame.Addr3, pAd->CommonCfg.Bssid);
+ RTMPZeroMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[0], 100);
+ pTxInfo = (PTXINFO_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[0];
+ RTMPWriteTxInfo(pAd, pTxInfo, (USHORT)(sizeof(HEADER_802_11)+TXWI_SIZE), TRUE, EpToQueue[MGMTPIPEIDX], FALSE, FALSE);
+ pTxWI = (PTXWI_STRUC)&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXINFO_SIZE];
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, 0, BSSID_WCID, (sizeof(HEADER_802_11)),
+ 0, 0, (UCHAR)pAd->CommonCfg.MlmeTransmit.field.MCS, IFS_BACKOFF, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ RTMPMoveMemory(&pAd->NullContext.TransferBuffer->field.WirelessPacket[TXWI_SIZE+TXINFO_SIZE], &pAd->NullFrame, sizeof(HEADER_802_11));
+ pAd->NullContext.BulkOutSize = TXINFO_SIZE + TXWI_SIZE + sizeof(pAd->NullFrame) + 4;
+}
+#endif // RT2870 //
+
+
+/*
+ ==========================================================================
+ Description:
+ Pre-build a BEACON frame in the shared memory
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+*/
+ULONG MakeIbssBeacon(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR DsLen = 1, IbssLen = 2;
+ UCHAR LocalErpIe[3] = {IE_ERP, 1, 0x04};
+ HEADER_802_11 BcnHdr;
+ USHORT CapabilityInfo;
+ LARGE_INTEGER FakeTimestamp;
+ ULONG FrameLen = 0;
+ PTXWI_STRUC pTxWI = &pAd->BeaconTxWI;
+ CHAR *pBeaconFrame = pAd->BeaconBuf;
+ BOOLEAN Privacy;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen = 0;
+ UCHAR ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR ExtRateLen = 0;
+ UCHAR RSNIe = IE_WPA;
+
+ if ((pAd->CommonCfg.PhyMode == PHY_11B) && (pAd->CommonCfg.Channel <= 14))
+ {
+ SupRate[0] = 0x82; // 1 mbps
+ SupRate[1] = 0x84; // 2 mbps
+ SupRate[2] = 0x8b; // 5.5 mbps
+ SupRate[3] = 0x96; // 11 mbps
+ SupRateLen = 4;
+ ExtRateLen = 0;
+ }
+ else if (pAd->CommonCfg.Channel > 14)
+ {
+ SupRate[0] = 0x8C; // 6 mbps, in units of 0.5 Mbps, basic rate
+ SupRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ SupRate[2] = 0x98; // 12 mbps, in units of 0.5 Mbps, basic rate
+ SupRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ SupRate[4] = 0xb0; // 24 mbps, in units of 0.5 Mbps, basic rate
+ SupRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ SupRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ SupRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ SupRateLen = 8;
+ ExtRateLen = 0;
+
+ //
+ // Also Update MlmeRate & RtsRate for G only & A only
+ //
+ pAd->CommonCfg.MlmeRate = RATE_6;
+ pAd->CommonCfg.RtsRate = RATE_6;
+ pAd->CommonCfg.MlmeTransmit.field.MODE = MODE_OFDM;
+ pAd->CommonCfg.MlmeTransmit.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MODE = MODE_OFDM;
+ pAd->MacTab.Content[BSS0Mcast_WCID].HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pAd->CommonCfg.MlmeRate];
+ }
+ else
+ {
+ SupRate[0] = 0x82; // 1 mbps
+ SupRate[1] = 0x84; // 2 mbps
+ SupRate[2] = 0x8b; // 5.5 mbps
+ SupRate[3] = 0x96; // 11 mbps
+ SupRateLen = 4;
+
+ ExtRate[0] = 0x0C; // 6 mbps, in units of 0.5 Mbps,
+ ExtRate[1] = 0x12; // 9 mbps, in units of 0.5 Mbps
+ ExtRate[2] = 0x18; // 12 mbps, in units of 0.5 Mbps,
+ ExtRate[3] = 0x24; // 18 mbps, in units of 0.5 Mbps
+ ExtRate[4] = 0x30; // 24 mbps, in units of 0.5 Mbps,
+ ExtRate[5] = 0x48; // 36 mbps, in units of 0.5 Mbps
+ ExtRate[6] = 0x60; // 48 mbps, in units of 0.5 Mbps
+ ExtRate[7] = 0x6c; // 54 mbps, in units of 0.5 Mbps
+ ExtRateLen = 8;
+ }
+
+ pAd->StaActive.SupRateLen = SupRateLen;
+ NdisMoveMemory(pAd->StaActive.SupRate, SupRate, SupRateLen);
+ pAd->StaActive.ExtRateLen = ExtRateLen;
+ NdisMoveMemory(pAd->StaActive.ExtRate, ExtRate, ExtRateLen);
+
+ // compose IBSS beacon frame
+ MgtMacHeaderInit(pAd, &BcnHdr, SUBTYPE_BEACON, 0, BROADCAST_ADDR, pAd->CommonCfg.Bssid);
+ Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+ CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+
+ MakeOutgoingFrame(pBeaconFrame, &FrameLen,
+ sizeof(HEADER_802_11), &BcnHdr,
+ TIMESTAMP_LEN, &FakeTimestamp,
+ 2, &pAd->CommonCfg.BeaconPeriod,
+ 2, &CapabilityInfo,
+ 1, &SsidIe,
+ 1, &pAd->CommonCfg.SsidLen,
+ pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, SupRate,
+ 1, &DsIe,
+ 1, &DsLen,
+ 1, &pAd->CommonCfg.Channel,
+ 1, &IbssIe,
+ 1, &IbssLen,
+ 2, &pAd->StaActive.AtimWin,
+ END_OF_ARGS);
+
+ // add ERP_IE and EXT_RAE IE of in 802.11g
+ if (ExtRateLen)
+ {
+ ULONG tmp;
+
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
+ 3, LocalErpIe,
+ 1, &ExtRateIe,
+ 1, &ExtRateLen,
+ ExtRateLen, ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ // If adhoc secruity is set for WPA-None, append the cipher suite IE
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ ULONG tmp;
+ RTMPMakeRSNIE(pAd, pAd->StaCfg.AuthMode, pAd->StaCfg.WepStatus, BSS0);
+
+ MakeOutgoingFrame(pBeaconFrame + FrameLen, &tmp,
+ 1, &RSNIe,
+ 1, &pAd->StaCfg.RSNIE_Len,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ ULONG TmpLen;
+ UCHAR HtLen, HtLen1;
+
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+ ADD_HT_INFO_IE addHTInfoTmp;
+ USHORT b2lTmp, b2lTmp2;
+#endif
+
+ // add HT Capability IE
+ HtLen = sizeof(pAd->CommonCfg.HtCapability);
+ HtLen1 = sizeof(pAd->CommonCfg.AddHTInfo);
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ 1, &AddHtInfoIe,
+ 1, &HtLen1,
+ HtLen1, &pAd->CommonCfg.AddHTInfo,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ NdisMoveMemory(&addHTInfoTmp, &pAd->CommonCfg.AddHTInfo, HtLen1);
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo2) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo2));
+ *(USHORT *)(&addHTInfoTmp.AddHtInfo3) = SWAP16(*(USHORT *)(&addHTInfoTmp.AddHtInfo3));
+
+ MakeOutgoingFrame(pBeaconFrame+FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ 1, &AddHtInfoIe,
+ 1, &HtLen1,
+ HtLen1, &addHTInfoTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ //beacon use reserved WCID 0xff
+ if (pAd->CommonCfg.Channel > 14)
+ {
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
+ PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &pAd->CommonCfg.MlmeTransmit);
+ }
+ else
+ {
+ // Set to use 1Mbps for Adhoc beacon.
+ HTTRANSMIT_SETTING Transmit;
+ Transmit.word = 0;
+ RTMPWriteTxWI(pAd, pTxWI, FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, 0, 0xff, FrameLen,
+ PID_MGMT, PID_BEACON, RATE_1, IFS_HTTXOP, FALSE, &Transmit);
+ }
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, pBeaconFrame, DIR_WRITE, FALSE);
+ RTMPWIEndianChange((PUCHAR)pTxWI, TYPE_TXWI);
+#endif
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MakeIbssBeacon (len=%ld), SupRateLen=%d, ExtRateLen=%d, Channel=%d, PhyMode=%d\n",
+ FrameLen, SupRateLen, ExtRateLen, pAd->CommonCfg.Channel, pAd->CommonCfg.PhyMode));
+ return FrameLen;
+}
+
+
diff --git a/drivers/staging/rt3070/sta/dls.c b/drivers/staging/rt3070/sta/dls.c
new file mode 100644
index 00000000000..8bcd4132934
--- /dev/null
+++ b/drivers/staging/rt3070/sta/dls.c
@@ -0,0 +1,2170 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ dls.c
+
+ Abstract:
+ Handle WMM-DLS state machine
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Rory Chen 02-14-2006
+ Arvin Tai 06-03-2008 Modified for RT28xx
+ */
+
+#include "../rt_config.h"
+
+/*
+ ==========================================================================
+ Description:
+ dls state machine init, including state transition and timer init
+ Parameters:
+ Sm - pointer to the dls state machine
+ Note:
+ The state machine looks like this
+
+ DLS_IDLE
+ MT2_MLME_DLS_REQUEST MlmeDlsReqAction
+ MT2_PEER_DLS_REQUEST PeerDlsReqAction
+ MT2_PEER_DLS_RESPONSE PeerDlsRspAction
+ MT2_MLME_DLS_TEARDOWN MlmeTearDownAction
+ MT2_PEER_DLS_TEARDOWN PeerTearDownAction
+
+ IRQL = PASSIVE_LEVEL
+
+ ==========================================================================
+ */
+void DlsStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ UCHAR i;
+
+ StateMachineInit(Sm, (STATE_MACHINE_FUNC*)Trans, MAX_DLS_STATE, MAX_DLS_MSG, (STATE_MACHINE_FUNC)Drop, DLS_IDLE, DLS_MACHINE_BASE);
+
+ // the first column
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_REQ, (STATE_MACHINE_FUNC)MlmeDlsReqAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_REQ, (STATE_MACHINE_FUNC)PeerDlsReqAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_RSP, (STATE_MACHINE_FUNC)PeerDlsRspAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_MLME_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)MlmeDlsTearDownAction);
+ StateMachineSetAction(Sm, DLS_IDLE, MT2_PEER_DLS_TEAR_DOWN, (STATE_MACHINE_FUNC)PeerDlsTearDownAction);
+
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ pAd->StaCfg.DLSEntry[i].pAd = pAd;
+ RTMPInitTimer(pAd, &pAd->StaCfg.DLSEntry[i].Timer, GET_TIMER_FUNCTION(DlsTimeoutAction), pAd, FALSE);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ HEADER_802_11 DlsReqHdr;
+ PRT_802_11_DLS pDLS = NULL;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_REQUEST;
+ ULONG tmp;
+ USHORT reason;
+ ULONG Timeout;
+ BOOLEAN TimerCancelled;
+
+ if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &reason))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsReqAction() \n"));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsReqAction() allocate memory failed \n"));
+ return;
+ }
+
+ ActHeaderInit(pAd, &DlsReqHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+ // Build basic frame first
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsReqHdr,
+ 1, &Category,
+ 1, &Action,
+ 6, &pDLS->MacAddr,
+ 6, pAd->CurrentAddress,
+ 2, &pAd->StaActive.CapabilityInfo,
+ 2, &pDLS->TimeOut,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR HtLen;
+
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+ // add HT Capability IE
+ HtLen = sizeof(HT_CAPABILITY_IE);
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen = FrameLen + tmp;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+ Timeout = DLS_TIMEOUT;
+ RTMPSetTimer(&pDLS->Timer, Timeout);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDlsReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ USHORT StatusCode = MLME_SUCCESS;
+ HEADER_802_11 DlsRspHdr;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_RESPONSE;
+ ULONG tmp;
+ USHORT CapabilityInfo;
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ USHORT DLSTimeOut;
+ SHORT i;
+ ULONG Timeout;
+ BOOLEAN TimerCancelled;
+ PRT_802_11_DLS pDLS = NULL;
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR SupportedRatesLen;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR HtCapabilityLen;
+ HT_CAPABILITY_IE HtCapability;
+
+ if (!PeerDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &DLSTimeOut,
+ &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
+ return;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (i = 0; i < SupportedRatesLen; i++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() from %02x:%02x:%02x:%02x:%02x:%02x\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() allocate memory failed \n"));
+ return;
+ }
+
+ if (!INFRA_ON(pAd))
+ {
+ StatusCode = MLME_REQUEST_DECLINED;
+ }
+ else if (!pAd->CommonCfg.bWmmCapable)
+ {
+ StatusCode = MLME_DEST_STA_IS_NOT_A_QSTA;
+ }
+ else if (!pAd->CommonCfg.bDLSCapable)
+ {
+ StatusCode = MLME_REQUEST_DECLINED;
+ }
+ else
+ {
+ // find table to update parameters
+ for (i = (MAX_NUM_OF_DLS_ENTRY-1); i >= 0; i--)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ }
+
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ pDLS = &pAd->StaCfg.DLSEntry[i];
+ break;
+ }
+ }
+
+ // can not find in table, create a new one
+ if (i < 0)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() can not find same entry \n"));
+ for (i=(MAX_NUM_OF_DLS_ENTRY - 1); i >= MAX_NUM_OF_INIT_DLS_ENTRY; i--)
+ {
+ if (!pAd->StaCfg.DLSEntry[i].Valid)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR MaxSupportedRate = RATE_11;
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ }
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ }
+
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ pAd->StaCfg.DLSEntry[i].Valid = TRUE;
+ pAd->StaCfg.DLSEntry[i].TimeOut = DLSTimeOut;
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = DLSTimeOut;
+ NdisMoveMemory(pAd->StaCfg.DLSEntry[i].MacAddr, SA, MAC_ADDR_LEN);
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ pDLS = &pAd->StaCfg.DLSEntry[i];
+ pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+ pEntry->HTCapability.MCSSet[0] = 0;
+ pEntry->HTCapability.MCSSet[1] = 0;
+
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR ii;
+
+ if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // find max fixed rate
+ for (ii=15; ii>=0; ii--)
+ {
+ j = ii/8;
+ bitmask = (1<<(ii-(j*8)));
+ if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = ii;
+ break;
+ }
+ if (ii==0)
+ break;
+ }
+
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+
+ printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ pEntry->RateLen = SupportedRatesLen;
+
+ break;
+ }
+ }
+ }
+ StatusCode = MLME_SUCCESS;
+
+ // can not find in table, create a new one
+ if (i < 0)
+ {
+ StatusCode = MLME_QOS_UNSPECIFY;
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsReqAction() DLSEntry table full(only can support %d DLS session) \n", MAX_NUM_OF_DLS_ENTRY - MAX_NUM_OF_INIT_DLS_ENTRY));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsReqAction() use entry(%d) %02x:%02x:%02x:%02x:%02x:%02x\n",
+ i, SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+ }
+ }
+
+ ActHeaderInit(pAd, &DlsRspHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+ // Build basic frame first
+ if (StatusCode == MLME_SUCCESS)
+ {
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsRspHdr,
+ 1, &Category,
+ 1, &Action,
+ 2, &StatusCode,
+ 6, SA,
+ 6, pAd->CurrentAddress,
+ 2, &pAd->StaActive.CapabilityInfo,
+ 1, &SupRateIe,
+ 1, &pAd->MlmeAux.SupRateLen,
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.SupRate,
+ END_OF_ARGS);
+
+ if (pAd->MlmeAux.ExtRateLen != 0)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &ExtRateIe,
+ 1, &pAd->MlmeAux.ExtRateLen,
+ pAd->MlmeAux.ExtRateLen, pAd->MlmeAux.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR HtLen;
+
+#ifdef RT_BIG_ENDIAN
+ HT_CAPABILITY_IE HtCapabilityTmp;
+#endif
+
+ // add HT Capability IE
+ HtLen = sizeof(HT_CAPABILITY_IE);
+#ifndef RT_BIG_ENDIAN
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &pAd->CommonCfg.HtCapability,
+ END_OF_ARGS);
+#else
+ NdisMoveMemory(&HtCapabilityTmp, &pAd->CommonCfg.HtCapability, HtLen);
+ *(USHORT *)(&HtCapabilityTmp.HtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.HtCapInfo));
+ *(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo) = SWAP16(*(USHORT *)(&HtCapabilityTmp.ExtHtCapInfo));
+
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ HtLen, &HtCapabilityTmp,
+ END_OF_ARGS);
+#endif
+ FrameLen = FrameLen + tmp;
+ }
+#endif // DOT11_N_SUPPORT //
+
+ if (pDLS && (pDLS->Status != DLS_FINISH))
+ {
+ RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+ Timeout = DLS_TIMEOUT;
+ RTMPSetTimer(&pDLS->Timer, Timeout);
+ }
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsRspHdr,
+ 1, &Category,
+ 1, &Action,
+ 2, &StatusCode,
+ 6, SA,
+ 6, pAd->CurrentAddress,
+ END_OF_ARGS);
+ }
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDlsRspAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT CapabilityInfo;
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ USHORT StatusCode;
+ SHORT i;
+ BOOLEAN TimerCancelled;
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR SupportedRatesLen;
+ UCHAR SupportedRates[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR HtCapabilityLen;
+ HT_CAPABILITY_IE HtCapability;
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return;
+
+ if (!INFRA_ON(pAd))
+ return;
+
+ if (!PeerDlsRspSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &CapabilityInfo, &StatusCode,
+ &SupportedRatesLen, &SupportedRates[0], &HtCapabilityLen, &HtCapability))
+ return;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (i=0; i<SupportedRatesLen; i++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupportedRates[i] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupportedRates[i] & 0x7f;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x with StatusCode=%d, CapabilityInfo=0x%x\n",
+ SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], StatusCode, CapabilityInfo));
+
+ for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (StatusCode == MLME_SUCCESS)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR MaxSupportedRate = RATE_11;
+
+ pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+ pEntry->HTCapability.MCSSet[0] = 0;
+ pEntry->HTCapability.MCSSet[1] = 0;
+
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR ii;
+
+ if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // find max fixed rate
+ for (ii=15; ii>=0; ii--)
+ {
+ j = ii/8;
+ bitmask = (1<<(ii-(j*8)));
+ if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = ii;
+ break;
+ }
+ if (ii==0)
+ break;
+ }
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+#endif // DOT11_N_SUPPORT //
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ pEntry->RateLen = SupportedRatesLen;
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // If support WPA or WPA2, start STAKey hand shake,
+ // If failed hand shake, just tear down peer DLS
+ if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
+ {
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
+ }
+ else
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
+ }
+ }
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+ }
+
+ //initialize seq no for DLS frames.
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ }
+ else
+ {
+ // DLS setup procedure failed.
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
+ }
+ }
+ }
+
+ if (i >= MAX_NUM_OF_INIT_DLS_ENTRY)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() update timeout value \n"));
+ for (i=(MAX_NUM_OF_DLS_ENTRY-1); i>=MAX_NUM_OF_INIT_DLS_ENTRY; i--)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (StatusCode == MLME_SUCCESS)
+ {
+ MAC_TABLE_ENTRY *pEntry;
+ UCHAR MaxSupportedRate = RATE_11;
+
+ pEntry = MacTableInsertDlsEntry(pAd, SA, i);
+
+ switch (MaxSupportedRateIn500Kbps)
+ {
+ case 108: MaxSupportedRate = RATE_54; break;
+ case 96: MaxSupportedRate = RATE_48; break;
+ case 72: MaxSupportedRate = RATE_36; break;
+ case 48: MaxSupportedRate = RATE_24; break;
+ case 36: MaxSupportedRate = RATE_18; break;
+ case 24: MaxSupportedRate = RATE_12; break;
+ case 18: MaxSupportedRate = RATE_9; break;
+ case 12: MaxSupportedRate = RATE_6; break;
+ case 22: MaxSupportedRate = RATE_11; break;
+ case 11: MaxSupportedRate = RATE_5_5; break;
+ case 4: MaxSupportedRate = RATE_2; break;
+ case 2: MaxSupportedRate = RATE_1; break;
+ default: MaxSupportedRate = RATE_11; break;
+ }
+
+ pEntry->MaxSupportedRate = min(pAd->CommonCfg.MaxTxRate, MaxSupportedRate);
+
+ if (pEntry->MaxSupportedRate < RATE_FIRST_OFDM_RATE)
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MaxHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->MinHTPhyMode.field.MODE = MODE_CCK;
+ pEntry->MinHTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ pEntry->HTPhyMode.field.MODE = MODE_CCK;
+ pEntry->HTPhyMode.field.MCS = pEntry->MaxSupportedRate;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MaxHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->MinHTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->MinHTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ pEntry->HTPhyMode.field.MODE = MODE_OFDM;
+ pEntry->HTPhyMode.field.MCS = OfdmRateToRxwiMCS[pEntry->MaxSupportedRate];
+ }
+
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MinHTPhyMode.field.BW = BW_20;
+
+#ifdef DOT11_N_SUPPORT
+ pEntry->HTCapability.MCSSet[0] = 0;
+ pEntry->HTCapability.MCSSet[1] = 0;
+
+ // If this Entry supports 802.11n, upgrade to HT rate.
+ if ((HtCapabilityLen != 0) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ UCHAR j, bitmask; //k,bitmask;
+ CHAR ii;
+
+ if ((HtCapability.HtCapInfo.GF) && (pAd->CommonCfg.DesiredHtPhy.GF))
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTGREENFIELD;
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pAd->MacTab.fAnyStationNonGF = TRUE;
+ pAd->CommonCfg.AddHTInfo.AddHtInfo2.NonGfPresent = 1;
+ }
+
+ if ((HtCapability.HtCapInfo.ChannelWidth) && (pAd->CommonCfg.DesiredHtPhy.ChannelWidth))
+ {
+ pEntry->MaxHTPhyMode.field.BW= BW_40;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor40)&(HtCapability.HtCapInfo.ShortGIfor40));
+ }
+ else
+ {
+ pEntry->MaxHTPhyMode.field.BW = BW_20;
+ pEntry->MaxHTPhyMode.field.ShortGI = ((pAd->CommonCfg.DesiredHtPhy.ShortGIfor20)&(HtCapability.HtCapInfo.ShortGIfor20));
+ pAd->MacTab.fAnyStation20Only = TRUE;
+ }
+
+ // find max fixed rate
+ for (ii=15; ii>=0; ii--)
+ {
+ j = ii/8;
+ bitmask = (1<<(ii-(j*8)));
+ if ( (pAd->StaCfg.DesiredHtPhyInfo.MCSSet[j]&bitmask) && (HtCapability.MCSSet[j]&bitmask))
+ {
+ pEntry->MaxHTPhyMode.field.MCS = ii;
+ break;
+ }
+ if (ii==0)
+ break;
+ }
+
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS != MCS_AUTO)
+ {
+ printk("@@@ pAd->CommonCfg.RegTransmitSetting.field.MCS = %d\n",
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS);
+ if (pAd->StaCfg.DesiredTransmitSetting.field.MCS == 32)
+ {
+ // Fix MCS as HT Duplicated Mode
+ pEntry->MaxHTPhyMode.field.BW = 1;
+ pEntry->MaxHTPhyMode.field.MODE = MODE_HTMIX;
+ pEntry->MaxHTPhyMode.field.STBC = 0;
+ pEntry->MaxHTPhyMode.field.ShortGI = 0;
+ pEntry->MaxHTPhyMode.field.MCS = 32;
+ }
+ else if (pEntry->MaxHTPhyMode.field.MCS > pAd->StaCfg.HTPhyMode.field.MCS)
+ {
+ // STA supports fixed MCS
+ pEntry->MaxHTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ }
+ }
+
+ pEntry->MaxHTPhyMode.field.STBC = (HtCapability.HtCapInfo.RxSTBC & (pAd->CommonCfg.DesiredHtPhy.TxSTBC));
+ pEntry->MpduDensity = HtCapability.HtCapParm.MpduDensity;
+ pEntry->MaxRAmpduFactor = HtCapability.HtCapParm.MaxRAmpduFactor;
+ pEntry->MmpsMode = (UCHAR)HtCapability.HtCapInfo.MimoPs;
+ pEntry->AMsduSize = (UCHAR)HtCapability.HtCapInfo.AMsduSize;
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+
+ if (HtCapability.HtCapInfo.ShortGIfor20)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI20_CAPABLE);
+ if (HtCapability.HtCapInfo.ShortGIfor40)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_SGI40_CAPABLE);
+ if (HtCapability.HtCapInfo.TxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_TxSTBC_CAPABLE);
+ if (HtCapability.HtCapInfo.RxSTBC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RxSTBC_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.PlusHTC)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_HTC_CAPABLE);
+ if (pAd->CommonCfg.bRdg && HtCapability.ExtHtCapInfo.RDGSupport)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_RDG_CAPABLE);
+ if (HtCapability.ExtHtCapInfo.MCSFeedback == 0x03)
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_MCSFEEDBACK_CAPABLE);
+
+ NdisMoveMemory(&pEntry->HTCapability, &HtCapability, sizeof(HT_CAPABILITY_IE));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pEntry->HTPhyMode.word = pEntry->MaxHTPhyMode.word;
+ pEntry->CurrTxRate = pEntry->MaxSupportedRate;
+ CLIENT_STATUS_SET_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE);
+
+ if (pAd->StaCfg.bAutoTxRateSwitch == TRUE)
+ {
+ PUCHAR pTable;
+ UCHAR TableSize = 0;
+
+ MlmeSelectTxRateTable(pAd, pEntry, &pTable, &TableSize, &pEntry->CurrTxRateIndex);
+ pEntry->bAutoTxRateSwitch = TRUE;
+ }
+ else
+ {
+ pEntry->HTPhyMode.field.MODE = pAd->StaCfg.HTPhyMode.field.MODE;
+ pEntry->HTPhyMode.field.MCS = pAd->StaCfg.HTPhyMode.field.MCS;
+ pEntry->bAutoTxRateSwitch = FALSE;
+
+ RTMPUpdateLegacyTxSetting((UCHAR)pAd->StaCfg.DesiredTransmitSetting.field.FixedTxMode, pEntry);
+ }
+ pEntry->RateLen = SupportedRatesLen;
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ // If support WPA or WPA2, start STAKey hand shake,
+ // If failed hand shake, just tear down peer DLS
+ if (RTMPSendSTAKeyRequest(pAd, pAd->StaCfg.DLSEntry[i].MacAddr) != NDIS_STATUS_SUCCESS)
+ {
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed when call RTMPSendSTAKeyRequest \n"));
+ }
+ else
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_WAIT_KEY;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - waiting for STAKey handshake procedure\n"));
+ }
+ }
+ else
+ {
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsRspAction() from %02x:%02x:%02x:%02x:%02x:%02x Succeed with WEP or no security\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5]));
+ }
+ pAd->StaCfg.DLSEntry[i].Sequence = 0;
+ if (HtCapabilityLen != 0)
+ pAd->StaCfg.DLSEntry[i].bHTCap = TRUE;
+ else
+ pAd->StaCfg.DLSEntry[i].bHTCap = FALSE;
+ }
+ else
+ {
+ // DLS setup procedure failed.
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - PeerDlsRspAction failed with StatusCode=%d \n", StatusCode));
+ }
+ }
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID MlmeDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_TEARDOWN;
+ USHORT ReasonCode = REASON_QOS_UNSPECIFY;
+ HEADER_802_11 DlsTearDownHdr;
+ PRT_802_11_DLS pDLS;
+ BOOLEAN TimerCancelled;
+ UCHAR i;
+
+ if(!MlmeDlsReqSanity(pAd, Elem->Msg, Elem->MsgLen, &pDLS, &ReasonCode))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - MlmeDlsTearDownAction() with ReasonCode=%d \n", ReasonCode));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("DLS - MlmeDlsTearDownAction() allocate memory failed \n"));
+ return;
+ }
+
+ ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+
+ // Build basic frame first
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsTearDownHdr,
+ 1, &Category,
+ 1, &Action,
+ 6, &pDLS->MacAddr,
+ 6, pAd->CurrentAddress,
+ 2, &ReasonCode,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, QID_AC_BE, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ RTMPCancelTimer(&pDLS->Timer, &TimerCancelled);
+
+ // Remove key in local dls table entry
+ for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // clear peer dls table entry
+ for (i = MAX_NUM_OF_INIT_DLS_ENTRY; i < MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (MAC_ADDR_EQUAL(pDLS->MacAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerDlsTearDownAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR DA[MAC_ADDR_LEN], SA[MAC_ADDR_LEN];
+ USHORT ReasonCode;
+ UINT i;
+ BOOLEAN TimerCancelled;
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return;
+
+ if (!INFRA_ON(pAd))
+ return;
+
+ if (!PeerDlsTearDownSanity(pAd, Elem->Msg, Elem->MsgLen, DA, SA, &ReasonCode))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - PeerDlsTearDownAction() from %02x:%02x:%02x:%02x:%02x:%02x with ReasonCode=%d\n", SA[0], SA[1], SA[2], SA[3], SA[4], SA[5], ReasonCode));
+
+ // clear local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // clear peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(SA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+ //AsicDelWcidTab(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ //AsicRemovePairwiseKeyEntry(pAd, BSS0, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID);
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID RTMPCheckDLSTimeOut(
+ IN PRTMP_ADAPTER pAd)
+{
+ ULONG i;
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_UNSPECIFY;
+
+ if (! pAd->CommonCfg.bDLSCapable)
+ return;
+
+ if (! INFRA_ON(pAd))
+ return;
+
+ // If timeout value is equaled to zero, it means always not be timeout.
+
+ // update local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer --;
+
+ if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
+ {
+ reason = REASON_QOS_REQUEST_TIMEOUT;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ }
+ }
+ }
+
+ // update peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && (pAd->StaCfg.DLSEntry[i].TimeOut != 0))
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer --;
+
+ if (pAd->StaCfg.DLSEntry[i].CountDownTimer == 0)
+ {
+ reason = REASON_QOS_REQUEST_TIMEOUT;
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ }
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN RTMPRcvFrameDLSCheck(
+ IN PRTMP_ADAPTER pAd,
+ IN PHEADER_802_11 pHeader,
+ IN ULONG Len,
+ IN PRT28XX_RXD_STRUC pRxD)
+{
+ ULONG i;
+ BOOLEAN bFindEntry = FALSE;
+ BOOLEAN bSTAKeyFrame = FALSE;
+ PEAPOL_PACKET pEap;
+ PUCHAR pProto, pAddr = NULL;
+ PUCHAR pSTAKey = NULL;
+ UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
+ UCHAR Mic[16], OldMic[16];
+ UCHAR digest[80];
+ UCHAR DlsPTK[80];
+ UCHAR temp[64];
+ BOOLEAN TimerCancelled;
+ CIPHER_KEY PairwiseKey;
+
+
+ if (! pAd->CommonCfg.bDLSCapable)
+ return bSTAKeyFrame;
+
+ if (! INFRA_ON(pAd))
+ return bSTAKeyFrame;
+
+ if (! (pHeader->FC.SubType & 0x08))
+ return bSTAKeyFrame;
+
+ if (Len < LENGTH_802_11 + 6 + 2 + 2)
+ return bSTAKeyFrame;
+
+ pProto = (PUCHAR)pHeader + LENGTH_802_11 + 2 + 6; // QOS Control field , 0xAA 0xAA 0xAA 0x00 0x00 0x00
+ pAddr = pHeader->Addr2;
+
+ // L2PAD bit on will pad 2 bytes at LLC
+ if (pRxD->L2PAD)
+ {
+ pProto += 2;
+ }
+
+ if (RTMPEqualMemory(EAPOL, pProto, 2) && (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA))
+ {
+ pEap = (PEAPOL_PACKET) (pProto + 2);
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff Len=%ld, DataLen=%d, KeyMic=%d, Install=%d, KeyAck=%d, Secure=%d, EKD_DL=%d, Error=%d, Request=%d\n", Len,
+ (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16),
+ pEap->KeyDesc.KeyInfo.KeyMic,
+ pEap->KeyDesc.KeyInfo.Install,
+ pEap->KeyDesc.KeyInfo.KeyAck,
+ pEap->KeyDesc.KeyInfo.Secure,
+ pEap->KeyDesc.KeyInfo.EKD_DL,
+ pEap->KeyDesc.KeyInfo.Error,
+ pEap->KeyDesc.KeyInfo.Request));
+
+ if ((Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE + 16)) && pEap->KeyDesc.KeyInfo.KeyMic
+ && pEap->KeyDesc.KeyInfo.Install && pEap->KeyDesc.KeyInfo.KeyAck && pEap->KeyDesc.KeyInfo.Secure
+ && pEap->KeyDesc.KeyInfo.EKD_DL && !pEap->KeyDesc.KeyInfo.Error && !pEap->KeyDesc.KeyInfo.Request)
+ {
+ // First validate replay counter, only accept message with larger replay counter
+ // Let equal pass, some AP start with all zero replay counter
+ NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+ if ((RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
+ (RTMPCompareMemory(pEap->KeyDesc.ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+ return bSTAKeyFrame;
+
+ //RTMPMoveMemory(pAd->StaCfg.ReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter (%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
+ pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
+ pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
+ pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
+
+ // put these code segment to get the replay counter
+ if (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED)
+ return bSTAKeyFrame;
+
+ // Check MIC value
+ // Save the MIC and replace with zero
+ // use proprietary PTK
+ NdisZeroMemory(temp, 64);
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+ WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+ NdisMoveMemory(OldMic, pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pEap->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1((PUCHAR) pEap, pEap->Body_Len[1] + 4, DlsPTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(DlsPTK, LEN_EAP_MICK, (PUCHAR) pEap, pEap->Body_Len[1] + 4, Mic);
+ }
+
+ if (!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("MIC Different in Msg1 of STAKey handshake! \n"));
+ return bSTAKeyFrame;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("MIC VALID in Msg1 of STAKey handshake! \n"));
+#if 1
+ if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0C)
+ && (pEap->KeyDesc.KeyData[4] == 0x43) && (pEap->KeyDesc.KeyData[5] == 0x02))
+ {
+ pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
+ pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%ld, KeyDataLen=%d\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
+
+ bSTAKeyFrame = TRUE;
+ }
+#else
+ if ((pEap->KeyDesc.KeyData[0] == 0xDD) && (pEap->KeyDesc.KeyData[2] == 0x00) && (pEap->KeyDesc.KeyData[3] == 0x0F)
+ && (pEap->KeyDesc.KeyData[4] == 0xAC) && (pEap->KeyDesc.KeyData[5] == 0x02))
+ {
+ pAddr = pEap->KeyDesc.KeyData + 8; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2)
+ pSTAKey = pEap->KeyDesc.KeyData + 14; // Tpe(1), Len(1), OUI(3), DataType(1), Reserved(2), STAKey_Mac_Addr(6)
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 from %02x:%02x:%02x:%02x:%02x:%02x Len=%d, KeyDataLen=%d\n",
+ pAddr[0], pAddr[1], pAddr[2], pAddr[3], pAddr[4], pAddr[5], Len, pEap->KeyDesc.KeyData[1]));
+
+ bSTAKeyFrame = TRUE;
+ }
+#endif
+
+ }
+ else if (Len >= (LENGTH_802_11 + 6 + 2 + 2 + sizeof(EAPOL_PACKET) - MAX_LEN_OF_RSNIE))
+ {
+ RTMPMoveMemory(pAd->StaCfg.DlsReplayCounter, pEap->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Sniff replay counter 2(%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x) Len=%ld, KeyDataLen=%d\n",
+ pAd->StaCfg.ReplayCounter[0], pAd->StaCfg.ReplayCounter[1], pAd->StaCfg.ReplayCounter[2],
+ pAd->StaCfg.ReplayCounter[3], pAd->StaCfg.ReplayCounter[4], pAd->StaCfg.ReplayCounter[5],
+ pAd->StaCfg.ReplayCounter[6], pAd->StaCfg.ReplayCounter[7], Len, pEap->KeyDesc.KeyData[1]));
+
+ }
+ }
+
+ // If timeout value is equaled to zero, it means always not be timeout.
+ // update local dls table entry
+ for (i= 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (bSTAKeyFrame)
+ {
+ PMAC_TABLE_ENTRY pEntry;
+
+ // STAKey frame, add pairwise key table
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+
+ PairwiseKey.KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
+ NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
+
+ PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
+
+ pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
+ //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+ // Add Pair-wise key to Asic
+#ifdef RT2870
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+ {
+ RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+ COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
+ KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
+ NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
+ }
+ {
+ PMAC_TABLE_ENTRY pDLSEntry;
+ pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
+ }
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+#endif // RT2870 //
+ NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Peer STA MAC Address STAKey) \n"));
+
+ RTMPSendSTAKeyHandShake(pAd, pAd->StaCfg.DLSEntry[i].MacAddr);
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Initiator side)\n"));
+ }
+ else
+ {
+ // Data frame, update timeout value
+ if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+ }
+ }
+
+ bFindEntry = TRUE;
+ }
+ }
+
+ // update peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && MAC_ADDR_EQUAL(pAddr, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ if (bSTAKeyFrame)
+ {
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ // STAKey frame, add pairwise key table, and send STAkey Msg-2
+ pAd->StaCfg.DLSEntry[i].Status = DLS_FINISH;
+ RTMPCancelTimer(&pAd->StaCfg.DLSEntry[i].Timer, &TimerCancelled);
+
+ PairwiseKey.KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(PairwiseKey.Key, &pSTAKey[0], LEN_TKIP_EK);
+ NdisMoveMemory(PairwiseKey.TxMic, &pSTAKey[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(PairwiseKey.RxMic, &pSTAKey[24], LEN_TKIP_TXMICK);
+
+ PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg;
+
+ pEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ //AsicAddKeyEntry(pAd, (USHORT)(i + 2), BSS0, 0, &PairwiseKey, TRUE, TRUE); // reserve 0 for multicast, 1 for unicast
+ //AsicUpdateRxWCIDTable(pAd, (USHORT)(i + 2), pAddr);
+ // Add Pair-wise key to Asic
+#ifdef RT2870
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 -->
+ {
+ RT_ADD_PAIRWISE_KEY_ENTRY KeyInfo;
+ COPY_MAC_ADDR(KeyInfo.MacAddr,pAd->StaCfg.DLSEntry[i].MacAddr);
+ KeyInfo.MacTabMatchWCID=pAd->StaCfg.DLSEntry[i].MacTabMatchWCID;
+ NdisMoveMemory(&KeyInfo.CipherKey, &PairwiseKey,sizeof(CIPHER_KEY));
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_KEY_TABLE, &KeyInfo, sizeof(RT_ADD_PAIRWISE_KEY_ENTRY));
+ }
+ {
+ PMAC_TABLE_ENTRY pDLSEntry;
+ pDLSEntry = DlsEntryTableLookup(pAd, pAd->StaCfg.DLSEntry[i].MacAddr, TRUE);
+ pDLSEntry->PairwiseKey.CipherAlg=PairwiseKey.CipherAlg;
+ RTUSBEnqueueInternalCmd(pAd, RT_CMD_SET_RX_WCID_TABLE, pDLSEntry, sizeof(MAC_TABLE_ENTRY));
+ }
+//Benson modified for USB interface, avoid in interrupt when write key, 20080724 <--
+#endif // RT2870 //
+ NdisMoveMemory(&pEntry->PairwiseKey, &PairwiseKey, sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Receive STAKey Message-1 (Initiator STA MAC Address STAKey)\n"));
+
+ // If support WPA or WPA2, start STAKey hand shake,
+ // If failed hand shake, just tear down peer DLS
+ if (RTMPSendSTAKeyHandShake(pAd, pAddr) != NDIS_STATUS_SUCCESS)
+ {
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason = REASON_QOS_CIPHER_NOT_SUPPORT;
+
+ pAd->StaCfg.DLSEntry[i].Valid = FALSE;
+ pAd->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, &pAd->StaCfg.DLSEntry[i], reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - Finish STAKey handshake procedure (Peer side)\n"));
+ }
+ }
+ else
+ {
+ // Data frame, update timeout value
+ if (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ {
+ pAd->StaCfg.DLSEntry[i].CountDownTimer = pAd->StaCfg.DLSEntry[i].TimeOut;
+ }
+ }
+
+ bFindEntry = TRUE;
+ }
+ }
+
+
+ return bSTAKeyFrame;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check if the frame can be sent through DLS direct link interface
+
+ Arguments:
+ pAd Pointer to adapter
+
+ Return Value:
+ DLS entry index
+
+ Note:
+
+ ========================================================================
+*/
+INT RTMPCheckDLSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ INT rval = -1;
+ INT i;
+
+ if (!pAd->CommonCfg.bDLSCapable)
+ return rval;
+
+ if (!INFRA_ON(pAd))
+ return rval;
+
+ do{
+ // check local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ rval = i;
+ break;
+ }
+ }
+
+ // check peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH) &&
+ MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ rval = i;
+ break;
+ }
+ }
+ } while (FALSE);
+
+ return rval;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID RTMPSendDLSTearDownFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+ HEADER_802_11 DlsTearDownHdr;
+ ULONG FrameLen = 0;
+ USHORT Reason = REASON_QOS_QSTA_LEAVING_QBSS;
+ UCHAR Category = CATEGORY_DLS;
+ UCHAR Action = ACTION_DLS_TEARDOWN;
+ UCHAR i = 0;
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ return;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame \n"));
+
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("ASSOC - RTMPSendDLSTearDownFrame() allocate memory failed \n"));
+ return;
+ }
+
+ ActHeaderInit(pAd, &DlsTearDownHdr, pAd->CommonCfg.Bssid, pAd->CurrentAddress, pAd->CommonCfg.Bssid);
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &DlsTearDownHdr,
+ 1, &Category,
+ 1, &Action,
+ 6, pDA,
+ 6, pAd->CurrentAddress,
+ 2, &Reason,
+ END_OF_ARGS);
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ // Remove key in local dls table entry
+ for (i = 0; i < MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // Remove key in peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAd->StaCfg.DLSEntry[i].Valid && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH)
+ && MAC_ADDR_EQUAL(pDA, pAd->StaCfg.DLSEntry[i].MacAddr))
+ {
+ MacTableDeleteDlsEntry(pAd, pAd->StaCfg.DLSEntry[i].MacTabMatchWCID, pAd->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Send DLS TearDown Frame and remove key in (i=%d) \n", i));
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+NDIS_STATUS RTMPSendSTAKeyRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ UCHAR Header802_3[14];
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+ UCHAR digest[80];
+ PUCHAR pOutBuffer = NULL;
+ PNDIS_PACKET pNdisPacket;
+ UCHAR temp[64];
+ UCHAR DlsPTK[80];
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyRequest() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
+
+ pAd->Sequence ++;
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE andPeer MAC address
+
+ // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+ }
+
+ // Key descriptor version
+ Packet.KeyDesc.KeyInfo.KeyDescVer =
+ (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+ Packet.KeyDesc.KeyInfo.Request = 1;
+
+ Packet.KeyDesc.KeyDataLen[1] = 12;
+
+ // use our own OUI to distinguish proprietary with standard.
+ Packet.KeyDesc.KeyData[0] = 0xDD;
+ Packet.KeyDesc.KeyData[1] = 0x0A;
+ Packet.KeyDesc.KeyData[2] = 0x00;
+ Packet.KeyDesc.KeyData[3] = 0x0C;
+ Packet.KeyDesc.KeyData[4] = 0x43;
+ Packet.KeyDesc.KeyData[5] = 0x03;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
+
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // use proprietary PTK
+ NdisZeroMemory(temp, 64);
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+ WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+ // calculate MIC
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ NdisZeroMemory(digest, sizeof(digest));
+ HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ NdisZeroMemory(Mic, sizeof(Mic));
+ hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+ }
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(Header802_3), Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
+ STASendPacket(pAd, pNdisPacket);
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyRequest- Send STAKey request (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
+
+ return NStatus;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+NDIS_STATUS RTMPSendSTAKeyHandShake(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA)
+{
+ UCHAR Header802_3[14];
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+ UCHAR digest[80];
+ PUCHAR pOutBuffer = NULL;
+ PNDIS_PACKET pNdisPacket;
+ UCHAR temp[64];
+ UCHAR DlsPTK[80]; // Due to dirver can not get PTK, use proprietary PTK
+
+ DBGPRINT(RT_DEBUG_TRACE,("DLS - RTMPSendSTAKeyHandShake() to %02x:%02x:%02x:%02x:%02x:%02x\n", pDA[0], pDA[1], pDA[2], pDA[3], pDA[4], pDA[5]));
+
+ pAd->Sequence ++;
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + 6 + MAC_ADDR_LEN; // data field contain KDE and Peer MAC address
+
+ // STAKey Message is as EAPOL-Key(1,1,0,0,G/0,0,0, MIC, 0,Peer MAC KDE)
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK))
+ {
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ }
+ else if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) || (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK))
+ {
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+ }
+
+ // Key descriptor version
+ Packet.KeyDesc.KeyInfo.KeyDescVer =
+ (((pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled) || (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)) ? (DESC_TYPE_AES) : (DESC_TYPE_TKIP));
+
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+
+ Packet.KeyDesc.KeyDataLen[1] = 12;
+
+ // use our own OUI to distinguish proprietary with standard.
+ Packet.KeyDesc.KeyData[0] = 0xDD;
+ Packet.KeyDesc.KeyData[1] = 0x0A;
+ Packet.KeyDesc.KeyData[2] = 0x00;
+ Packet.KeyDesc.KeyData[3] = 0x0C;
+ Packet.KeyDesc.KeyData[4] = 0x43;
+ Packet.KeyDesc.KeyData[5] = 0x03;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[6], pDA, MAC_ADDR_LEN);
+
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.DlsReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Allocate buffer for transmitting message
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return NStatus;
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // use proprietary PTK
+ NdisZeroMemory(temp, 64);
+ NdisMoveMemory(temp, "IEEE802.11 WIRELESS ACCESS POINT", 32);
+ WpaCountPTK(pAd, temp, temp, pAd->CommonCfg.Bssid, temp, pAd->CurrentAddress, DlsPTK, LEN_PTK);
+
+ // calculate MIC
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ NdisZeroMemory(digest, sizeof(digest));
+ HMAC_SHA1(pOutBuffer, FrameLen, DlsPTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ NdisZeroMemory(Mic, sizeof(Mic));
+ hmac_md5(DlsPTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+ }
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(Header802_3), Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ NStatus = RTMPAllocateNdisPacket(pAd, &pNdisPacket, NULL, 0, pOutBuffer, FrameLen);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ RTMP_SET_PACKET_WCID(pNdisPacket, BSSID_WCID);
+ STASendPacket(pAd, pNdisPacket);
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+ }
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPSendSTAKeyHandShake- Send STAKey Message-2 (NStatus=%x, FrameLen=%ld)\n", NStatus, FrameLen));
+
+ return NStatus;
+}
+
+VOID DlsTimeoutAction(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ MLME_DLS_REQ_STRUCT MlmeDlsReq;
+ USHORT reason;
+ PRT_802_11_DLS pDLS = (PRT_802_11_DLS)FunctionContext;
+ PRTMP_ADAPTER pAd = pDLS->pAd;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("DlsTimeout - Tear down DLS links (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+ pDLS->MacAddr[0], pDLS->MacAddr[1], pDLS->MacAddr[2], pDLS->MacAddr[3], pDLS->MacAddr[4], pDLS->MacAddr[5]));
+
+ if ((pDLS) && (pDLS->Valid))
+ {
+ reason = REASON_QOS_REQUEST_TIMEOUT;
+ pDLS->Valid = FALSE;
+ pDLS->Status = DLS_NONE;
+ DlsParmFill(pAd, &MlmeDlsReq, pDLS, reason);
+ MlmeEnqueue(pAd, DLS_STATE_MACHINE, MT2_MLME_DLS_TEAR_DOWN, sizeof(MLME_DLS_REQ_STRUCT), &MlmeDlsReq);
+ RT28XX_MLME_HANDLER(pAd);
+ }
+}
+
+/*
+================================================================
+Description : because DLS and CLI share the same WCID table in ASIC.
+Mesh entry also insert to pAd->MacTab.content[]. Such is marked as ValidAsDls = TRUE.
+Also fills the pairwise key.
+Because front MAX_AID_BA entries have direct mapping to BAEntry, which is only used as CLI. So we insert Dls
+from index MAX_AID_BA.
+================================================================
+*/
+MAC_TABLE_ENTRY *MacTableInsertDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN UINT DlsEntryIdx)
+{
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableInsertDlsEntry\n"));
+ // if FULL, return
+ if (pAd->MacTab.Size >= MAX_LEN_OF_MAC_TABLE)
+ return NULL;
+
+ do
+ {
+ if((pEntry = DlsEntryTableLookup(pAd, pAddr, TRUE)) != NULL)
+ break;
+
+ // allocate one MAC entry
+ pEntry = MacTableInsertEntry(pAd, pAddr, DlsEntryIdx + MIN_NET_DEVICE_FOR_DLS, TRUE);
+ if (pEntry)
+ {
+ pAd->StaCfg.DLSEntry[DlsEntryIdx].MacTabMatchWCID = pEntry->Aid;
+ pEntry->MatchDlsEntryIdx = DlsEntryIdx;
+ pEntry->AuthMode = pAd->StaCfg.AuthMode;
+ pEntry->WepStatus = pAd->StaCfg.WepStatus;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacTableInsertDlsEntry - allocate entry #%d, Total= %d\n",pEntry->Aid, pAd->MacTab.Size));
+
+ // If legacy WEP is used, set pair-wise cipherAlg into WCID attribute table for this entry
+ if ((pEntry->ValidAsDls) && (pEntry->WepStatus == Ndis802_11WEPEnabled))
+ {
+ UCHAR KeyIdx = 0;
+ UCHAR CipherAlg = 0;
+
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+
+ CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pEntry);
+ }
+
+ break;
+ }
+ } while(FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableInsertDlsEntry\n"));
+
+ return pEntry;
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ Delete all Mesh Entry in pAd->MacTab
+ ==========================================================================
+ */
+BOOLEAN MacTableDeleteDlsEntry(
+ IN PRTMP_ADAPTER pAd,
+ IN USHORT wcid,
+ IN PUCHAR pAddr)
+{
+ DBGPRINT(RT_DEBUG_TRACE, ("====> MacTableDeleteDlsEntry\n"));
+
+ if (!VALID_WCID(wcid))
+ return FALSE;
+
+ MacTableDeleteEntry(pAd, wcid, pAddr);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==== MacTableDeleteDlsEntry\n"));
+
+ return TRUE;
+}
+
+MAC_TABLE_ENTRY *DlsEntryTableLookup(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount)
+{
+ ULONG HashIdx;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+
+ RTMP_SEM_LOCK(&pAd->MacTabLock);
+ HashIdx = MAC_ADDR_HASH_INDEX(pAddr);
+ pEntry = pAd->MacTab.Hash[HashIdx];
+
+ while (pEntry)
+ {
+ if ((pEntry->ValidAsDls == TRUE)
+ && MAC_ADDR_EQUAL(pEntry->Addr, pAddr))
+ {
+ if(bResetIdelCount)
+ pEntry->NoDataIdleCount = 0;
+ break;
+ }
+ else
+ pEntry = pEntry->pNext;
+ }
+
+ RTMP_SEM_UNLOCK(&pAd->MacTabLock);
+ return pEntry;
+}
+
+MAC_TABLE_ENTRY *DlsEntryTableLookupByWcid(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR wcid,
+ IN PUCHAR pAddr,
+ IN BOOLEAN bResetIdelCount)
+{
+ ULONG DLsIndex;
+ PMAC_TABLE_ENTRY pCurEntry = NULL;
+ PMAC_TABLE_ENTRY pEntry = NULL;
+
+ if (!VALID_WCID(wcid))
+ return NULL;
+
+ RTMP_SEM_LOCK(&pAd->MacTabLock);
+
+ do
+ {
+ pCurEntry = &pAd->MacTab.Content[wcid];
+
+ DLsIndex = 0xff;
+ if ((pCurEntry) && (pCurEntry->ValidAsDls== TRUE))
+ {
+ DLsIndex = pCurEntry->MatchDlsEntryIdx;
+ }
+
+ if (DLsIndex == 0xff)
+ break;
+
+ if (MAC_ADDR_EQUAL(pCurEntry->Addr, pAddr))
+ {
+ if(bResetIdelCount)
+ pCurEntry->NoDataIdleCount = 0;
+ pEntry = pCurEntry;
+ break;
+ }
+ } while(FALSE);
+
+ RTMP_SEM_UNLOCK(&pAd->MacTabLock);
+
+ return pEntry;
+}
+
+INT Set_DlsEntryInfo_Display_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ INT i;
+
+ printk("\n%-19s%-8s\n", "MAC", "TIMEOUT\n");
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if ((pAd->StaCfg.DLSEntry[i].Valid) && (pAd->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ printk("%02x:%02x:%02x:%02x:%02x:%02x ",
+ pAd->StaCfg.DLSEntry[i].MacAddr[0], pAd->StaCfg.DLSEntry[i].MacAddr[1], pAd->StaCfg.DLSEntry[i].MacAddr[2],
+ pAd->StaCfg.DLSEntry[i].MacAddr[3], pAd->StaCfg.DLSEntry[i].MacAddr[4], pAd->StaCfg.DLSEntry[i].MacAddr[5]);
+ printk("%-8d\n", pAd->StaCfg.DLSEntry[i].TimeOut);
+ }
+ }
+
+ return TRUE;
+}
+
+INT Set_DlsAddEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR mac[MAC_ADDR_LEN];
+ USHORT Timeout;
+ char *token, sepValue[] = ":", DASH = '-';
+ INT i;
+ RT_802_11_DLS Dls;
+
+ if(strlen(arg) < 19) //Mac address acceptable format 01:02:03:04:05:06 length 17 plus the "-" and timeout value in decimal format.
+ return FALSE;
+
+ token = strchr(arg, DASH);
+ if ((token != NULL) && (strlen(token)>1))
+ {
+ Timeout = simple_strtol((token+1), 0, 10);
+
+ *token = '\0';
+ for (i = 0, token = rstrtok(arg, &sepValue[0]); token; token = rstrtok(NULL, &sepValue[0]), i++)
+ {
+ if((strlen(token) != 2) || (!isxdigit(*token)) || (!isxdigit(*(token+1))))
+ return FALSE;
+ AtoH(token, (PUCHAR)(&mac[i]), 1);
+ }
+ if(i != 6)
+ return FALSE;
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x-%d", mac[0], mac[1],
+ mac[2], mac[3], mac[4], mac[5], (int)Timeout);
+
+ NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+ Dls.TimeOut = Timeout;
+ COPY_MAC_ADDR(Dls.MacAddr, mac);
+ Dls.Valid = 1;
+
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ RT_OID_802_11_SET_DLS_PARAM,
+ sizeof(RT_802_11_DLS),
+ &Dls);
+
+ return TRUE;
+ }
+
+ return FALSE;
+
+}
+
+INT Set_DlsTearDownEntry_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ UCHAR macAddr[MAC_ADDR_LEN];
+ CHAR *value;
+ INT i;
+ RT_802_11_DLS Dls;
+
+ if(strlen(arg) != 17) //Mac address acceptable format 01:02:03:04:05:06 length 17
+ return FALSE;
+
+ for (i=0, value = rstrtok(arg,":"); value; value = rstrtok(NULL,":"))
+ {
+ if((strlen(value) != 2) || (!isxdigit(*value)) || (!isxdigit(*(value+1))) )
+ return FALSE; //Invalid
+
+ AtoH(value, &macAddr[i++], 2);
+ }
+
+ printk("\n%02x:%02x:%02x:%02x:%02x:%02x", macAddr[0], macAddr[1],
+ macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
+
+ NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+ COPY_MAC_ADDR(Dls.MacAddr, macAddr);
+ Dls.Valid = 0;
+
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ RT_OID_802_11_SET_DLS_PARAM,
+ sizeof(RT_802_11_DLS),
+ &Dls);
+
+ return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta/rtmp_data.c b/drivers/staging/rt3070/sta/rtmp_data.c
new file mode 100644
index 00000000000..b0f259b35c7
--- /dev/null
+++ b/drivers/staging/rt3070/sta/rtmp_data.c
@@ -0,0 +1,2637 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ rtmp_data.c
+
+ Abstract:
+ Data path subroutines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Aug/17/04 major modification for RT2561/2661
+ Jan Lee Mar/17/06 major modification for RT2860 New Ring Design
+*/
+#include "../rt_config.h"
+
+
+
+VOID STARxEAPOLFrameIndicate(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+ PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+ UCHAR *pTmpBuf;
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ // All EAPoL frames have to pass to upper layer (ex. WPA_SUPPLICANT daemon)
+ // TBD : process fragmented EAPol frames
+ {
+ // In 802.1x mode, if the received frame is EAP-SUCCESS packet, turn on the PortSecured variable
+ if ( pAd->StaCfg.IEEE8021X == TRUE &&
+ (EAP_CODE_SUCCESS == WpaCheckEapCode(pAd, pRxBlk->pData, pRxBlk->DataSize, LENGTH_802_1_H)))
+ {
+ PUCHAR Key;
+ UCHAR CipherAlg;
+ int idx = 0;
+
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("Receive EAP-SUCCESS Packet\n"));
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ if (pAd->StaCfg.IEEE8021x_required_keys == FALSE)
+ {
+ idx = pAd->StaCfg.DesireSharedKeyId;
+ CipherAlg = pAd->StaCfg.DesireSharedKey[idx].CipherAlg;
+ Key = pAd->StaCfg.DesireSharedKey[idx].Key;
+
+ if (pAd->StaCfg.DesireSharedKey[idx].KeyLen > 0)
+ {
+#ifdef RT2870
+ union
+ {
+ char buf[sizeof(NDIS_802_11_WEP)+MAX_LEN_OF_KEY- 1];
+ NDIS_802_11_WEP keyinfo;
+ } WepKey;
+ int len;
+
+
+ NdisZeroMemory(&WepKey, sizeof(WepKey));
+ len =pAd->StaCfg.DesireSharedKey[idx].KeyLen;
+
+ NdisMoveMemory(WepKey.keyinfo.KeyMaterial,
+ pAd->StaCfg.DesireSharedKey[idx].Key,
+ pAd->StaCfg.DesireSharedKey[idx].KeyLen);
+
+ WepKey.keyinfo.KeyIndex = 0x80000000 + idx;
+ WepKey.keyinfo.KeyLength = len;
+ pAd->SharedKey[BSS0][idx].KeyLen =(UCHAR) (len <= 5 ? 5 : 13);
+
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ // need to enqueue cmd to thread
+ RTUSBEnqueueCmdFromNdis(pAd, OID_802_11_ADD_WEP, TRUE, &WepKey, sizeof(WepKey.keyinfo) + len - 1);
+#endif // RT2870 //
+ // For Preventing ShardKey Table is cleared by remove key procedure.
+ pAd->SharedKey[BSS0][idx].CipherAlg = CipherAlg;
+ pAd->SharedKey[BSS0][idx].KeyLen = pAd->StaCfg.DesireSharedKey[idx].KeyLen;
+ NdisMoveMemory(pAd->SharedKey[BSS0][idx].Key,
+ pAd->StaCfg.DesireSharedKey[idx].Key,
+ pAd->StaCfg.DesireSharedKey[idx].KeyLen);
+ }
+ }
+ }
+
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ // Special DATA frame that has to pass to MLME
+ // 1. Cisco Aironet frames for CCX2. We need pass it to MLME for special process
+ // 2. EAPOL handshaking frames when driver supplicant enabled, pass to MLME for special process
+ {
+ pTmpBuf = pRxBlk->pData - LENGTH_802_11;
+ NdisMoveMemory(pTmpBuf, pRxBlk->pHeader, LENGTH_802_11);
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pTmpBuf, pRxBlk->DataSize + LENGTH_802_11, pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("!!! report EAPOL/AIRONET DATA to MLME (len=%d) !!!\n", pRxBlk->DataSize));
+ }
+ }
+
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+
+}
+
+VOID STARxDataFrameAnnounce(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk,
+ IN UCHAR FromWhichBSSID)
+{
+
+ // non-EAP frame
+ if (!RTMPCheckWPAframe(pAd, pEntry, pRxBlk->pData, pRxBlk->DataSize, FromWhichBSSID))
+ {
+
+ {
+ // drop all non-EAP DATA frame before
+ // this client's Port-Access-Control is secured
+ if (pRxBlk->pHeader->FC.Wep)
+ {
+ // unsupported cipher suite
+ if (pAd->StaCfg.WepStatus == Ndis802_11EncryptionDisabled)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+ else
+ {
+ // encryption in-use but receive a non-EAPOL clear text frame, drop it
+ if ((pAd->StaCfg.WepStatus != Ndis802_11EncryptionDisabled) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+ }
+ RX_BLK_CLEAR_FLAG(pRxBlk, fRX_EAP);
+ if (!RX_BLK_TEST_FLAG(pRxBlk, fRX_ARALINK))
+ {
+ // Normal legacy, AMPDU or AMSDU
+ CmmRxnonRalinkFrameIndicate(pAd, pRxBlk, FromWhichBSSID);
+
+ }
+ else
+ {
+ // ARALINK
+ CmmRxRalinkFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+#ifdef QOS_DLS_SUPPORT
+ RX_BLK_CLEAR_FLAG(pRxBlk, fRX_DLS);
+#endif // QOS_DLS_SUPPORT //
+ }
+ else
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_EAP);
+#ifdef DOT11_N_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_AMPDU) && (pAd->CommonCfg.bDisableReordering == 0))
+ {
+ Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ // Determin the destination of the EAP frame
+ // to WPA state machine or upper layer
+ STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ }
+ }
+}
+
+
+// For TKIP frame, calculate the MIC value
+BOOLEAN STACheckTkipMICValue(
+ IN PRTMP_ADAPTER pAd,
+ IN MAC_TABLE_ENTRY *pEntry,
+ IN RX_BLK *pRxBlk)
+{
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ UCHAR *pData = pRxBlk->pData;
+ USHORT DataSize = pRxBlk->DataSize;
+ UCHAR UserPriority = pRxBlk->UserPriority;
+ PCIPHER_KEY pWpaKey;
+ UCHAR *pDA, *pSA;
+
+ pWpaKey = &pAd->SharedKey[BSS0][pRxBlk->pRxWI->KeyIndex];
+
+ pDA = pHeader->Addr1;
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_INFRA))
+ {
+ pSA = pHeader->Addr3;
+ }
+ else
+ {
+ pSA = pHeader->Addr2;
+ }
+
+ if (RTMPTkipCompareMICValue(pAd,
+ pData,
+ pDA,
+ pSA,
+ pWpaKey->RxMic,
+ UserPriority,
+ DataSize) == FALSE)
+ {
+ DBGPRINT_RAW(RT_DEBUG_ERROR,("Rx MIC Value error 2\n"));
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.WpaSupplicantUP)
+ {
+ WpaSendMicFailureToWpaSupplicant(pAd, (pWpaKey->Type == PAIRWISEKEY) ? TRUE : FALSE);
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ RTMPReportMicError(pAd, pWpaKey);
+ }
+
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxBlk->pRxPacket, NDIS_STATUS_FAILURE);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+//
+// All Rx routines use RX_BLK structure to hande rx events
+// It is very important to build pRxBlk attributes
+// 1. pHeader pointer to 802.11 Header
+// 2. pData pointer to payload including LLC (just skip Header)
+// 3. set payload size including LLC to DataSize
+// 4. set some flags with RX_BLK_SET_FLAG()
+//
+VOID STAHandleRxDataFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+ BOOLEAN bFragment = FALSE;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR FromWhichBSSID = BSS0;
+ UCHAR UserPriority = 0;
+
+ {
+ // before LINK UP, all DATA frames are rejected
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+#ifdef QOS_DLS_SUPPORT
+ //if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
+ if (RTMPRcvFrameDLSCheck(pAd, pHeader, pRxWI->MPDUtotalByteCount, pRxD))
+ {
+ return;
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ // Drop not my BSS frames
+ if (pRxD->MyBss == 0)
+ {
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+
+ pAd->RalinkCounters.RxCountSinceLastNULL++;
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable && (pHeader->FC.SubType & 0x08))
+ {
+ UCHAR *pData;
+ DBGPRINT(RT_DEBUG_TRACE,("bAPSDCapable\n"));
+
+ // Qos bit 4
+ pData = (PUCHAR)pHeader + LENGTH_802_11;
+ if ((*pData >> 4) & 0x01)
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("RxDone- Rcv EOSP frame, driver may fall into sleep\n"));
+ pAd->CommonCfg.bInServicePeriod = FALSE;
+
+ // Force driver to fall into sleep mode when rcv EOSP frame
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ USHORT TbttNumToNextWakeUp;
+ USHORT NextDtim = pAd->StaCfg.DtimPeriod;
+ ULONG Now;
+
+ NdisGetSystemUpTime(&Now);
+ NextDtim -= (USHORT)(Now - pAd->StaCfg.LastBeaconRxTime)/pAd->CommonCfg.BeaconPeriod;
+
+ TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
+ TbttNumToNextWakeUp = NextDtim;
+
+ MlmeSetPsmBit(pAd, PWR_SAVE);
+ // if WMM-APSD is failed, try to disable following line
+ AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+ }
+ }
+
+ if ((pHeader->FC.MoreData) && (pAd->CommonCfg.bInServicePeriod))
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("Sending another trigger frame when More Data bit is set to 1\n"));
+ }
+ }
+
+ // Drop NULL, CF-ACK(no data), CF-POLL(no data), and CF-ACK+CF-POLL(no data) data frame
+ if ((pHeader->FC.SubType & 0x04)) // bit 2 : no DATA
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // Drop not my BSS frame (we can not only check the MyBss bit in RxD)
+#ifdef QOS_DLS_SUPPORT
+ if (!pAd->CommonCfg.bDLSCapable)
+ {
+#endif // QOS_DLS_SUPPORT //
+ if (INFRA_ON(pAd))
+ {
+ // Infrastructure mode, check address 2 for BSSID
+ if (!RTMPEqualMemory(&pHeader->Addr2, &pAd->CommonCfg.Bssid, 6))
+ {
+ // Receive frame not my BSSID
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+ else // Ad-Hoc mode or Not associated
+ {
+ // Ad-Hoc mode, check address 3 for BSSID
+ if (!RTMPEqualMemory(&pHeader->Addr3, &pAd->CommonCfg.Bssid, 6))
+ {
+ // Receive frame not my BSSID
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+ }
+#ifdef QOS_DLS_SUPPORT
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ //
+ // find pEntry
+ //
+ if (pRxWI->WirelessCliID < MAX_LEN_OF_MAC_TABLE)
+ {
+ pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
+ }
+ else
+ {
+ // 1. release packet if infra mode
+ // 2. new a pEntry if ad-hoc mode
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // infra or ad-hoc
+ if (INFRA_ON(pAd))
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_INFRA);
+#ifdef QOS_DLS_SUPPORT
+ if ((pHeader->FC.FrDs == 0) && (pHeader->FC.ToDs == 0))
+ RX_BLK_SET_FLAG(pRxBlk, fRX_DLS);
+ else
+#endif // QOS_DLS_SUPPORT //
+ ASSERT(pRxWI->WirelessCliID == BSSID_WCID);
+ }
+
+ // check Atheros Client
+ if ((pEntry->bIAmBadAtheros == FALSE) && (pRxD->AMPDU == 1) && (pHeader->FC.Retry ))
+ {
+ pEntry->bIAmBadAtheros = TRUE;
+ pAd->CommonCfg.IOTestParm.bCurrentAtheros = TRUE;
+ pAd->CommonCfg.IOTestParm.bLastAtheros = TRUE;
+ if (!STA_AES_ON(pAd))
+ {
+ AsicUpdateProtect(pAd, 8, ALLN_SETPROTECT, TRUE, FALSE);
+ }
+ }
+ }
+
+ pRxBlk->pData = (UCHAR *)pHeader;
+
+ //
+ // update RxBlk->pData, DataSize
+ // 802.11 Header, QOS, HTC, Hw Padding
+ //
+
+ // 1. skip 802.11 HEADER
+ {
+ pRxBlk->pData += LENGTH_802_11;
+ pRxBlk->DataSize -= LENGTH_802_11;
+ }
+
+ // 2. QOS
+ if (pHeader->FC.SubType & 0x08)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_QOS);
+ UserPriority = *(pRxBlk->pData) & 0x0f;
+ // bit 7 in QoS Control field signals the HT A-MSDU format
+ if ((*pRxBlk->pData) & 0x80)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMSDU);
+ }
+
+ // skip QOS contorl field
+ pRxBlk->pData += 2;
+ pRxBlk->DataSize -=2;
+ }
+ pRxBlk->UserPriority = UserPriority;
+
+ // 3. Order bit: A-Ralink or HTC+
+ if (pHeader->FC.Order)
+ {
+#ifdef AGGREGATION_SUPPORT
+ if ((pRxWI->PHYMODE <= MODE_OFDM) && (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED)))
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_ARALINK);
+ }
+ else
+#endif
+ {
+#ifdef DOT11_N_SUPPORT
+ RX_BLK_SET_FLAG(pRxBlk, fRX_HTC);
+ // skip HTC contorl field
+ pRxBlk->pData += 4;
+ pRxBlk->DataSize -= 4;
+#endif // DOT11_N_SUPPORT //
+ }
+ }
+
+ // 4. skip HW padding
+ if (pRxD->L2PAD)
+ {
+ // just move pData pointer
+ // because DataSize excluding HW padding
+ RX_BLK_SET_FLAG(pRxBlk, fRX_PAD);
+ pRxBlk->pData += 2;
+ }
+
+#ifdef DOT11_N_SUPPORT
+ if (pRxD->BA)
+ {
+ RX_BLK_SET_FLAG(pRxBlk, fRX_AMPDU);
+ }
+#endif // DOT11_N_SUPPORT //
+
+
+ //
+ // Case I Process Broadcast & Multicast data frame
+ //
+ if (pRxD->Bcast || pRxD->Mcast)
+ {
+ INC_COUNTER64(pAd->WlanCounters.MulticastReceivedFrameCount);
+
+ // Drop Mcast/Bcast frame with fragment bit on
+ if (pHeader->FC.MoreFrag)
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ // Filter out Bcast frame which AP relayed for us
+ if (pHeader->FC.FrDs && MAC_ADDR_EQUAL(pHeader->Addr3, pAd->CurrentAddress))
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ Indicate_Legacy_Packet(pAd, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ else if (pRxD->U2M)
+ {
+ pAd->LastRxRate = (USHORT)((pRxWI->MCS) + (pRxWI->BW <<7) + (pRxWI->ShortGI <<8)+ (pRxWI->PHYMODE <<14)) ;
+
+
+#ifdef QOS_DLS_SUPPORT
+ if (RX_BLK_TEST_FLAG(pRxBlk, fRX_DLS))
+ {
+ MAC_TABLE_ENTRY *pDlsEntry = NULL;
+
+ pDlsEntry = DlsEntryTableLookupByWcid(pAd, pRxWI->WirelessCliID, pHeader->Addr2, TRUE);
+ if(pDlsEntry)
+ Update_Rssi_Sample(pAd, &pDlsEntry->RssiSample, pRxWI);
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ if (ADHOC_ON(pAd))
+ {
+ pEntry = MacTableLookup(pAd, pHeader->Addr2);
+ if (pEntry)
+ Update_Rssi_Sample(pAd, &pEntry->RssiSample, pRxWI);
+ }
+
+
+ Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
+
+ pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
+ pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
+
+ pAd->RalinkCounters.OneSecRxOkDataCnt++;
+
+
+ if (!((pHeader->Frag == 0) && (pHeader->FC.MoreFrag == 0)))
+ {
+ // re-assemble the fragmented packets
+ // return complete frame (pRxPacket) or NULL
+ bFragment = TRUE;
+ pRxPacket = RTMPDeFragmentDataFrame(pAd, pRxBlk);
+ }
+
+ if (pRxPacket)
+ {
+ pEntry = &pAd->MacTab.Content[pRxWI->WirelessCliID];
+
+ // process complete frame
+ if (bFragment && (pRxD->Decrypted) && (pEntry->WepStatus == Ndis802_11Encryption2Enabled))
+ {
+ // Minus MIC length
+ pRxBlk->DataSize -= 8;
+
+ // For TKIP frame, calculate the MIC value
+ if (STACheckTkipMICValue(pAd, pEntry, pRxBlk) == FALSE)
+ {
+ return;
+ }
+ }
+
+ STARxDataFrameAnnounce(pAd, pEntry, pRxBlk, FromWhichBSSID);
+ return;
+ }
+ else
+ {
+ // just return
+ // because RTMPDeFragmentDataFrame() will release rx packet,
+ // if packet is fragmented
+ return;
+ }
+ }
+
+ ASSERT(0);
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+}
+
+VOID STAHandleRxMgmtFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+ PRT28XX_RXD_STRUC pRxD = &(pRxBlk->RxD);
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+
+ do
+ {
+
+ // We should collect RSSI not only U2M data but also my beacon
+ if ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))
+ && (pAd->RxAnt.EvaluatePeriod == 0))
+ {
+ Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, pRxWI);
+
+ pAd->StaCfg.LastSNR0 = (UCHAR)(pRxWI->SNR0);
+ pAd->StaCfg.LastSNR1 = (UCHAR)(pRxWI->SNR1);
+ }
+
+#ifdef RT30xx
+ // collect rssi information for antenna diversity
+ if (pAd->NicConfig2.field.AntDiversity)
+ {
+ if ((pRxD->U2M) || ((pHeader->FC.SubType == SUBTYPE_BEACON) && (MAC_ADDR_EQUAL(&pAd->CommonCfg.Bssid, &pHeader->Addr2))))
+ {
+ COLLECT_RX_ANTENNA_AVERAGE_RSSI(pAd, ConvertToRssi(pAd, (UCHAR)pRxWI->RSSI0, RSSI_0), 0); //Note: RSSI2 not used on RT73
+ pAd->StaCfg.NumOfAvgRssiSample ++;
+ }
+ }
+#endif // RT30xx //
+
+ // First check the size, it MUST not exceed the mlme queue size
+ if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE)
+ {
+ DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount));
+ break;
+ }
+
+ REPORT_MGMT_FRAME_TO_MLME(pAd, pRxWI->WirelessCliID, pHeader, pRxWI->MPDUtotalByteCount,
+ pRxWI->RSSI0, pRxWI->RSSI1, pRxWI->RSSI2, pRxD->PlcpSignal);
+ } while (FALSE);
+
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+}
+
+VOID STAHandleRxControlFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN RX_BLK *pRxBlk)
+{
+#ifdef DOT11_N_SUPPORT
+ PRXWI_STRUC pRxWI = pRxBlk->pRxWI;
+#endif // DOT11_N_SUPPORT //
+ PHEADER_802_11 pHeader = pRxBlk->pHeader;
+ PNDIS_PACKET pRxPacket = pRxBlk->pRxPacket;
+
+ switch (pHeader->FC.SubType)
+ {
+ case SUBTYPE_BLOCK_ACK_REQ:
+#ifdef DOT11_N_SUPPORT
+ {
+ CntlEnqueueForRecv(pAd, pRxWI->WirelessCliID, (pRxWI->MPDUtotalByteCount), (PFRAME_BA_REQ)pHeader);
+ }
+ break;
+#endif // DOT11_N_SUPPORT //
+ case SUBTYPE_BLOCK_ACK:
+ case SUBTYPE_ACK:
+ default:
+ break;
+ }
+
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process RxDone interrupt, running in DPC level
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ This routine has to maintain Rx ring read pointer.
+ Need to consider QOS DATA format when converting to 802.3
+ ========================================================================
+*/
+BOOLEAN STARxDoneInterruptHandle(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN argc)
+{
+ NDIS_STATUS Status;
+ UINT32 RxProcessed, RxPending;
+ BOOLEAN bReschedule = FALSE;
+ RT28XX_RXD_STRUC *pRxD;
+ UCHAR *pData;
+ PRXWI_STRUC pRxWI;
+ PNDIS_PACKET pRxPacket;
+ PHEADER_802_11 pHeader;
+ RX_BLK RxCell;
+
+ RxProcessed = RxPending = 0;
+
+ // process whole rx ring
+ while (1)
+ {
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF |
+ fRTMP_ADAPTER_RESET_IN_PROGRESS |
+ fRTMP_ADAPTER_HALT_IN_PROGRESS |
+ fRTMP_ADAPTER_NIC_NOT_EXIST) ||
+ !RTMP_TEST_FLAG(pAd,fRTMP_ADAPTER_START_UP))
+ {
+ break;
+ }
+
+
+ RxProcessed ++; // test
+
+ // 1. allocate a new data packet into rx ring to replace received packet
+ // then processing the received packet
+ // 2. the callee must take charge of release of packet
+ // 3. As far as driver is concerned ,
+ // the rx packet must
+ // a. be indicated to upper layer or
+ // b. be released if it is discarded
+ pRxPacket = GetPacketFromRxRing(pAd, &(RxCell.RxD), &bReschedule, &RxPending);
+ if (pRxPacket == NULL)
+ {
+ // no more packet to process
+ break;
+ }
+
+ // get rx ring descriptor
+ pRxD = &(RxCell.RxD);
+ // get rx data buffer
+ pData = GET_OS_PKT_DATAPTR(pRxPacket);
+ pRxWI = (PRXWI_STRUC) pData;
+ pHeader = (PHEADER_802_11) (pData+RXWI_SIZE) ;
+
+#ifdef RT_BIG_ENDIAN
+ RTMPFrameEndianChange(pAd, (PUCHAR)pHeader, DIR_READ, TRUE);
+ RTMPWIEndianChange((PUCHAR)pRxWI, TYPE_RXWI);
+#endif
+
+ // build RxCell
+ RxCell.pRxWI = pRxWI;
+ RxCell.pHeader = pHeader;
+ RxCell.pRxPacket = pRxPacket;
+ RxCell.pData = (UCHAR *) pHeader;
+ RxCell.DataSize = pRxWI->MPDUtotalByteCount;
+ RxCell.Flags = 0;
+
+ // Increase Total receive byte counter after real data received no mater any error or not
+ pAd->RalinkCounters.ReceivedByteCount += pRxWI->MPDUtotalByteCount;
+ pAd->RalinkCounters.RxCount ++;
+
+ INC_COUNTER64(pAd->WlanCounters.ReceivedFragmentCount);
+
+ if (pRxWI->MPDUtotalByteCount < 14)
+ Status = NDIS_STATUS_FAILURE;
+
+ if (MONITOR_ON(pAd))
+ {
+ send_monitor_packets(pAd, &RxCell);
+ break;
+ }
+ /* RT2870 invokes STARxDoneInterruptHandle() in rtusb_bulk.c */
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ pAd->ate.RxCntPerSec++;
+ ATESampleRssi(pAd, pRxWI);
+#ifdef RALINK_28xx_QA
+ if (pAd->ate.bQARxStart == TRUE)
+ {
+ /* (*pRxD) has been swapped in GetPacketFromRxRing() */
+ ATE_QA_Statistics(pAd, pRxWI, pRxD, pHeader);
+ }
+#endif // RALINK_28xx_QA //
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_SUCCESS);
+ continue;
+ }
+#endif // RALINK_ATE //
+
+ // Check for all RxD errors
+ Status = RTMPCheckRxError(pAd, pHeader, pRxWI, pRxD);
+
+ // Handle the received frame
+ if (Status == NDIS_STATUS_SUCCESS)
+ {
+ switch (pHeader->FC.Type)
+ {
+ // CASE I, receive a DATA frame
+ case BTYPE_DATA:
+ {
+ // process DATA frame
+ STAHandleRxDataFrame(pAd, &RxCell);
+ }
+ break;
+ // CASE II, receive a MGMT frame
+ case BTYPE_MGMT:
+ {
+ STAHandleRxMgmtFrame(pAd, &RxCell);
+ }
+ break;
+ // CASE III. receive a CNTL frame
+ case BTYPE_CNTL:
+ {
+ STAHandleRxControlFrame(pAd, &RxCell);
+ }
+ break;
+ // discard other type
+ default:
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ break;
+ }
+ }
+ else
+ {
+ pAd->Counters8023.RxErrors++;
+ // discard this frame
+ RELEASE_NDIS_PACKET(pAd, pRxPacket, NDIS_STATUS_FAILURE);
+ }
+ }
+
+ return bReschedule;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Arguments:
+ pAd Pointer to our adapter
+
+ IRQL = DISPATCH_LEVEL
+
+ ========================================================================
+*/
+VOID RTMPHandleTwakeupInterrupt(
+ IN PRTMP_ADAPTER pAd)
+{
+ AsicForceWakeup(pAd, FALSE);
+}
+
+/*
+========================================================================
+Routine Description:
+ Early checking and OS-depened parsing for Tx packet send to our STA driver.
+
+Arguments:
+ NDIS_HANDLE MiniportAdapterContext Pointer refer to the device handle, i.e., the pAd.
+ PPNDIS_PACKET ppPacketArray The packet array need to do transmission.
+ UINT NumberOfPackets Number of packet in packet array.
+
+Return Value:
+ NONE
+
+Note:
+ This function do early checking and classification for send-out packet.
+ You only can put OS-depened & STA related code in here.
+========================================================================
+*/
+VOID STASendPackets(
+ IN NDIS_HANDLE MiniportAdapterContext,
+ IN PPNDIS_PACKET ppPacketArray,
+ IN UINT NumberOfPackets)
+{
+ UINT Index;
+ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) MiniportAdapterContext;
+ PNDIS_PACKET pPacket;
+ BOOLEAN allowToSend = FALSE;
+
+
+ for (Index = 0; Index < NumberOfPackets; Index++)
+ {
+ pPacket = ppPacketArray[Index];
+
+ do
+ {
+
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS) ||
+ RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
+ {
+ // Drop send request since hardware is in reset state
+ break;
+ }
+ else if (!INFRA_ON(pAd) && !ADHOC_ON(pAd))
+ {
+ // Drop send request since there are no physical connection yet
+ break;
+ }
+ else
+ {
+ // Record that orignal packet source is from NDIS layer,so that
+ // later on driver knows how to release this NDIS PACKET
+#ifdef QOS_DLS_SUPPORT
+ MAC_TABLE_ENTRY *pEntry;
+ PUCHAR pSrcBufVA = GET_OS_PKT_DATAPTR(pPacket);
+
+ pEntry = MacTableLookup(pAd, pSrcBufVA);
+ if (pEntry && (pEntry->ValidAsDls == TRUE))
+ {
+ RTMP_SET_PACKET_WCID(pPacket, pEntry->Aid);
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ RTMP_SET_PACKET_WCID(pPacket, 0); // this field is useless when in STA mode
+ RTMP_SET_PACKET_SOURCE(pPacket, PKTSRC_NDIS);
+ NDIS_SET_PACKET_STATUS(pPacket, NDIS_STATUS_PENDING);
+ pAd->RalinkCounters.PendingNdisPacketCount++;
+
+ allowToSend = TRUE;
+ }
+ } while(FALSE);
+
+ if (allowToSend == TRUE)
+ STASendPacket(pAd, pPacket);
+ else
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+
+ // Dequeue outgoing frames from TxSwQueue[] and process it
+ RTMPDeQueuePacket(pAd, FALSE, NUM_OF_TX_RING, MAX_TX_PROCESS);
+
+}
+
+
+/*
+========================================================================
+Routine Description:
+ This routine is used to do packet parsing and classification for Tx packet
+ to STA device, and it will en-queue packets to our TxSwQueue depends on AC
+ class.
+
+Arguments:
+ pAd Pointer to our adapter
+ pPacket Pointer to send packet
+
+Return Value:
+ NDIS_STATUS_SUCCESS If succes to queue the packet into TxSwQueue.
+ NDIS_STATUS_FAILURE If failed to do en-queue.
+
+Note:
+ You only can put OS-indepened & STA related code in here.
+========================================================================
+*/
+NDIS_STATUS STASendPacket(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket)
+{
+ PACKET_INFO PacketInfo;
+ PUCHAR pSrcBufVA;
+ UINT SrcBufLen;
+ UINT AllowFragSize;
+ UCHAR NumberOfFrag;
+// UCHAR RTSRequired;
+ UCHAR QueIdx, UserPriority;
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ unsigned int IrqFlags;
+ UCHAR FlgIsIP = 0;
+ UCHAR Rate;
+
+ // Prepare packet information structure for buffer descriptor
+ // chained within a single NDIS packet.
+ RTMP_QueryPacketInfo(pPacket, &PacketInfo, &pSrcBufVA, &SrcBufLen);
+
+ if (pSrcBufVA == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> pSrcBufVA == NULL !!!SrcBufLen=%x\n",SrcBufLen));
+ // Resourece is low, system did not allocate virtual address
+ // return NDIS_STATUS_FAILURE directly to upper layer
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+
+ if (SrcBufLen < 14)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("STASendPacket --> Ndis Packet buffer error !!!\n"));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return (NDIS_STATUS_FAILURE);
+ }
+
+ // In HT rate adhoc mode, A-MPDU is often used. So need to lookup BA Table and MAC Entry.
+ // Note multicast packets in adhoc also use BSSID_WCID index.
+ {
+ if(INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ USHORT tmpWcid;
+
+ tmpWcid = RTMP_GET_PACKET_WCID(pPacket);
+ if (VALID_WCID(tmpWcid) &&
+ (pAd->MacTab.Content[tmpWcid].ValidAsDls== TRUE))
+ {
+ pEntry = &pAd->MacTab.Content[tmpWcid];
+ Rate = pAd->MacTab.Content[tmpWcid].CurrTxRate;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ {
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ RTMP_SET_PACKET_WCID(pPacket, BSSID_WCID);
+ Rate = pAd->CommonCfg.TxRate;
+ }
+ }
+ else if (ADHOC_ON(pAd))
+ {
+ if (*pSrcBufVA & 0x01)
+ {
+ RTMP_SET_PACKET_WCID(pPacket, MCAST_WCID);
+ pEntry = &pAd->MacTab.Content[MCAST_WCID];
+ }
+ else
+ {
+ pEntry = MacTableLookup(pAd, pSrcBufVA);
+ }
+ Rate = pAd->CommonCfg.TxRate;
+ }
+ }
+
+ if (!pEntry)
+ {
+ DBGPRINT(RT_DEBUG_ERROR,("STASendPacket->Cannot find pEntry(%2x:%2x:%2x:%2x:%2x:%2x) in MacTab!\n", PRINT_MAC(pSrcBufVA)));
+ // Resourece is low, system did not allocate virtual address
+ // return NDIS_STATUS_FAILURE directly to upper layer
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ return NDIS_STATUS_FAILURE;
+ }
+
+ if (ADHOC_ON(pAd)
+ )
+ {
+ RTMP_SET_PACKET_WCID(pPacket, (UCHAR)pEntry->Aid);
+ }
+
+ //
+ // Check the Ethernet Frame type of this packet, and set the RTMP_SET_PACKET_SPECIFIC flags.
+ // Here we set the PACKET_SPECIFIC flags(LLC, VLAN, DHCP/ARP, EAPOL).
+ RTMPCheckEtherType(pAd, pPacket);
+
+
+
+ //
+ // WPA 802.1x secured port control - drop all non-802.1x frame before port secured
+ //
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef WPA_SUPPLICANT_SUPPORT
+ || (pAd->StaCfg.IEEE8021X == TRUE)
+#endif // WPA_SUPPLICANT_SUPPORT //
+#ifdef LEAP_SUPPORT
+ || (pAd->StaCfg.LeapAuthMode == CISCO_AuthModeLEAP)
+#endif // LEAP_SUPPORT //
+ )
+ && ((pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED) || (pAd->StaCfg.MicErrCnt >= 2))
+ && (RTMP_GET_PACKET_EAPOL(pPacket)== FALSE)
+ )
+ {
+ DBGPRINT(RT_DEBUG_TRACE,("STASendPacket --> Drop packet before port secured !!!\n"));
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+ return (NDIS_STATUS_FAILURE);
+ }
+
+
+ // STEP 1. Decide number of fragments required to deliver this MSDU.
+ // The estimation here is not very accurate because difficult to
+ // take encryption overhead into consideration here. The result
+ // "NumberOfFrag" is then just used to pre-check if enough free
+ // TXD are available to hold this MSDU.
+
+
+ if (*pSrcBufVA & 0x01) // fragmentation not allowed on multicast & broadcast
+ NumberOfFrag = 1;
+ else if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_AGGREGATION_INUSED))
+ NumberOfFrag = 1; // Aggregation overwhelms fragmentation
+ else if (CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_AMSDU_INUSED))
+ NumberOfFrag = 1; // Aggregation overwhelms fragmentation
+#ifdef DOT11_N_SUPPORT
+ else if ((pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTMIX) || (pAd->StaCfg.HTPhyMode.field.MODE == MODE_HTGREENFIELD))
+ NumberOfFrag = 1; // MIMO RATE overwhelms fragmentation
+#endif // DOT11_N_SUPPORT //
+ else
+ {
+ // The calculated "NumberOfFrag" is a rough estimation because of various
+ // encryption/encapsulation overhead not taken into consideration. This number is just
+ // used to make sure enough free TXD are available before fragmentation takes place.
+ // In case the actual required number of fragments of an NDIS packet
+ // excceeds "NumberOfFrag"caculated here and not enough free TXD available, the
+ // last fragment (i.e. last MPDU) will be dropped in RTMPHardTransmit() due to out of
+ // resource, and the NDIS packet will be indicated NDIS_STATUS_FAILURE. This should
+ // rarely happen and the penalty is just like a TX RETRY fail. Affordable.
+
+ AllowFragSize = (pAd->CommonCfg.FragmentThreshold) - LENGTH_802_11 - LENGTH_CRC;
+ NumberOfFrag = ((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) / AllowFragSize) + 1;
+ // To get accurate number of fragmentation, Minus 1 if the size just match to allowable fragment size
+ if (((PacketInfo.TotalPacketLength - LENGTH_802_3 + LENGTH_802_1_H) % AllowFragSize) == 0)
+ {
+ NumberOfFrag--;
+ }
+ }
+
+ // Save fragment number to Ndis packet reserved field
+ RTMP_SET_PACKET_FRAGMENTS(pPacket, NumberOfFrag);
+
+
+ // STEP 2. Check the requirement of RTS:
+ // If multiple fragment required, RTS is required only for the first fragment
+ // if the fragment size large than RTS threshold
+ // For RT28xx, Let ASIC send RTS/CTS
+ RTMP_SET_PACKET_RTS(pPacket, 0);
+ RTMP_SET_PACKET_TXRATE(pPacket, pAd->CommonCfg.TxRate);
+
+ //
+ // STEP 3. Traffic classification. outcome = <UserPriority, QueIdx>
+ //
+ UserPriority = 0;
+ QueIdx = QID_AC_BE;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+ CLIENT_STATUS_TEST_FLAG(pEntry, fCLIENT_STATUS_WMM_CAPABLE))
+ {
+ USHORT Protocol;
+ UCHAR LlcSnapLen = 0, Byte0, Byte1;
+ do
+ {
+ // get Ethernet protocol field
+ Protocol = (USHORT)((pSrcBufVA[12] << 8) + pSrcBufVA[13]);
+ if (Protocol <= 1500)
+ {
+ // get Ethernet protocol field from LLC/SNAP
+ if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + 6, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+ break;
+
+ Protocol = (USHORT)((Byte0 << 8) + Byte1);
+ LlcSnapLen = 8;
+ }
+
+ // always AC_BE for non-IP packet
+ if (Protocol != 0x0800)
+ break;
+
+ // get IP header
+ if (Sniff2BytesFromNdisBuffer(PacketInfo.pFirstBuffer, LENGTH_802_3 + LlcSnapLen, &Byte0, &Byte1) != NDIS_STATUS_SUCCESS)
+ break;
+
+ // return AC_BE if packet is not IPv4
+ if ((Byte0 & 0xf0) != 0x40)
+ break;
+
+ FlgIsIP = 1;
+ UserPriority = (Byte1 & 0xe0) >> 5;
+ QueIdx = MapUserPriorityToAccessCategory[UserPriority];
+
+ // TODO: have to check ACM bit. apply TSPEC if ACM is ON
+ // TODO: downgrade UP & QueIdx before passing ACM
+ if (pAd->CommonCfg.APEdcaParm.bACM[QueIdx])
+ {
+ UserPriority = 0;
+ QueIdx = QID_AC_BE;
+ }
+ } while (FALSE);
+ }
+
+ RTMP_SET_PACKET_UP(pPacket, UserPriority);
+
+
+
+ // Make sure SendTxWait queue resource won't be used by other threads
+ RTMP_IRQ_LOCK(&pAd->irq_lock, IrqFlags);
+ if (pAd->TxSwQueue[QueIdx].Number >= MAX_PACKETS_IN_QUEUE)
+ {
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+#ifdef BLOCK_NET_IF
+ StopNetIfQueue(pAd, QueIdx, pPacket);
+#endif // BLOCK_NET_IF //
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+
+ return NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ InsertTailQueue(&pAd->TxSwQueue[QueIdx], PACKET_TO_QUEUE_ENTRY(pPacket));
+ }
+ RTMP_IRQ_UNLOCK(&pAd->irq_lock, IrqFlags);
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.BACapability.field.AutoBA == TRUE)&&
+ IS_HT_STA(pEntry))
+ {
+ //PMAC_TABLE_ENTRY pMacEntry = &pAd->MacTab.Content[BSSID_WCID];
+ if (((pEntry->TXBAbitmap & (1<<UserPriority)) == 0) &&
+ ((pEntry->BADeclineBitmap & (1<<UserPriority)) == 0) &&
+ (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)
+ // For IOT compatibility, if
+ // 1. It is Ralink chip or
+ // 2. It is OPEN or AES mode,
+ // then BA session can be bulit.
+ && ((pEntry->ValidAsCLI && pAd->MlmeAux.APRalinkIe != 0x0) ||
+ (pEntry->WepStatus == Ndis802_11WEPDisabled || pEntry->WepStatus == Ndis802_11Encryption3Enabled))
+ )
+ {
+ BAOriSessionSetUp(pAd, pEntry, 0, 0, 10, FALSE);
+ }
+ }
+#endif // DOT11_N_SUPPORT //
+
+ pAd->RalinkCounters.OneSecOsTxCount[QueIdx]++; // TODO: for debug only. to be removed
+ return NDIS_STATUS_SUCCESS;
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ This subroutine will scan through releative ring descriptor to find
+ out avaliable free ring descriptor and compare with request size.
+
+ Arguments:
+ pAd Pointer to our adapter
+ QueIdx Selected TX Ring
+
+ Return Value:
+ NDIS_STATUS_FAILURE Not enough free descriptor
+ NDIS_STATUS_SUCCESS Enough free descriptor
+
+ IRQL = PASSIVE_LEVEL
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+
+#ifdef RT2870
+/*
+ Actually, this function used to check if the TxHardware Queue still has frame need to send.
+ If no frame need to send, go to sleep, else, still wake up.
+*/
+NDIS_STATUS RTMPFreeTXDRequest(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR QueIdx,
+ IN UCHAR NumberRequired,
+ IN PUCHAR FreeNumberIs)
+{
+ //ULONG FreeNumber = 0;
+ NDIS_STATUS Status = NDIS_STATUS_FAILURE;
+ unsigned long IrqFlags;
+ HT_TX_CONTEXT *pHTTXContext;
+
+ switch (QueIdx)
+ {
+ case QID_AC_BK:
+ case QID_AC_BE:
+ case QID_AC_VI:
+ case QID_AC_VO:
+ case QID_HCCA:
+ {
+ pHTTXContext = &pAd->TxContext[QueIdx];
+ RTMP_IRQ_LOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+ if ((pHTTXContext->CurWritePosition != pHTTXContext->ENextBulkOutPosition) ||
+ (pHTTXContext->IRPPending == TRUE))
+ {
+ Status = NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ Status = NDIS_STATUS_SUCCESS;
+ }
+ RTMP_IRQ_UNLOCK(&pAd->TxContextQueueLock[QueIdx], IrqFlags);
+ }
+ break;
+
+ case QID_MGMT:
+ if (pAd->MgmtRing.TxSwFreeIdx != MGMT_RING_SIZE)
+ Status = NDIS_STATUS_FAILURE;
+ else
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_ERROR,("RTMPFreeTXDRequest::Invalid QueIdx(=%d)\n", QueIdx));
+ break;
+ }
+
+ return (Status);
+
+}
+#endif // RT2870 //
+
+
+VOID RTMPSendDisassociationFrame(
+ IN PRTMP_ADAPTER pAd)
+{
+}
+
+VOID RTMPSendNullFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN UCHAR TxRate,
+ IN BOOLEAN bQosNull)
+{
+ UCHAR NullFrame[48];
+ ULONG Length;
+ PHEADER_802_11 pHeader_802_11;
+
+
+#ifdef RALINK_ATE
+ if(ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+ // WPA 802.1x secured port control
+ if (((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+#ifdef WPA_SUPPLICANT_SUPPORT
+ || (pAd->StaCfg.IEEE8021X == TRUE)
+#endif
+ ) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ return;
+ }
+
+ NdisZeroMemory(NullFrame, 48);
+ Length = sizeof(HEADER_802_11);
+
+ pHeader_802_11 = (PHEADER_802_11) NullFrame;
+
+ pHeader_802_11->FC.Type = BTYPE_DATA;
+ pHeader_802_11->FC.SubType = SUBTYPE_NULL_FUNC;
+ pHeader_802_11->FC.ToDs = 1;
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+
+ if (pAd->CommonCfg.bAPSDForcePowerSave)
+ {
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ }
+ else
+ {
+ pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE) ? 1: 0;
+ }
+ pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + RTMPCalcDuration(pAd, TxRate, 14);
+
+ pAd->Sequence++;
+ pHeader_802_11->Sequence = pAd->Sequence;
+
+ // Prepare QosNull function frame
+ if (bQosNull)
+ {
+ pHeader_802_11->FC.SubType = SUBTYPE_QOS_NULL;
+
+ // copy QOS control bytes
+ NullFrame[Length] = 0;
+ NullFrame[Length+1] = 0;
+ Length += 2;// if pad with 2 bytes for alignment, APSD will fail
+ }
+
+ HAL_KickOutNullFrameTx(pAd, 0, NullFrame, Length);
+
+}
+
+// IRQL = DISPATCH_LEVEL
+VOID RTMPSendRTSFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pDA,
+ IN unsigned int NextMpduSize,
+ IN UCHAR TxRate,
+ IN UCHAR RTSRate,
+ IN USHORT AckDuration,
+ IN UCHAR QueIdx,
+ IN UCHAR FrameGap)
+{
+}
+
+
+
+// --------------------------------------------------------
+// FIND ENCRYPT KEY AND DECIDE CIPHER ALGORITHM
+// Find the WPA key, either Group or Pairwise Key
+// LEAP + TKIP also use WPA key.
+// --------------------------------------------------------
+// Decide WEP bit and cipher suite to be used. Same cipher suite should be used for whole fragment burst
+// In Cisco CCX 2.0 Leap Authentication
+// WepStatus is Ndis802_11Encryption1Enabled but the key will use PairwiseKey
+// Instead of the SharedKey, SharedKey Length may be Zero.
+VOID STAFindCipherAlgorithm(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ NDIS_802_11_ENCRYPTION_STATUS Cipher; // To indicate cipher used for this packet
+ UCHAR CipherAlg = CIPHER_NONE; // cipher alogrithm
+ UCHAR KeyIdx = 0xff;
+ PUCHAR pSrcBufVA;
+ PCIPHER_KEY pKey = NULL;
+
+ pSrcBufVA = GET_OS_PKT_DATAPTR(pTxBlk->pPacket);
+
+ {
+ // Select Cipher
+ if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
+ Cipher = pAd->StaCfg.GroupCipher; // Cipher for Multicast or Broadcast
+ else
+ Cipher = pAd->StaCfg.PairCipher; // Cipher for Unicast
+
+ if (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+ {
+ ASSERT(pAd->SharedKey[BSS0][0].CipherAlg <= CIPHER_CKIP128);
+
+ // 4-way handshaking frame must be clear
+ if (!(TX_BLK_TEST_FLAG(pTxBlk, fTX_bClearEAPFrame)) && (pAd->SharedKey[BSS0][0].CipherAlg) &&
+ (pAd->SharedKey[BSS0][0].KeyLen))
+ {
+ CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+ KeyIdx = 0;
+ }
+ }
+ else if (Cipher == Ndis802_11Encryption1Enabled)
+ {
+#ifdef LEAP_SUPPORT
+ if (pAd->StaCfg.CkipFlag & 0x10) // Cisco CKIP KP is on
+ {
+ if (LEAP_CCKM_ON(pAd))
+ {
+ if (((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))))
+ KeyIdx = 1;
+ else
+ KeyIdx = 0;
+ }
+ else
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ }
+ else if (pAd->StaCfg.CkipFlag & 0x08) // only CKIP CMIC
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ else if (LEAP_CCKM_ON(pAd))
+ {
+ if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd)))
+ KeyIdx = 1;
+ else
+ KeyIdx = 0;
+ }
+ else // standard WEP64 or WEP128
+#endif // LEAP_SUPPORT //
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ }
+ else if ((Cipher == Ndis802_11Encryption2Enabled) ||
+ (Cipher == Ndis802_11Encryption3Enabled))
+ {
+ if ((*pSrcBufVA & 0x01) && (ADHOC_ON(pAd))) // multicast
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ else if (pAd->SharedKey[BSS0][0].KeyLen)
+ KeyIdx = 0;
+ else
+ KeyIdx = pAd->StaCfg.DefaultKeyId;
+ }
+
+ if (KeyIdx == 0xff)
+ CipherAlg = CIPHER_NONE;
+ else if ((Cipher == Ndis802_11EncryptionDisabled) || (pAd->SharedKey[BSS0][KeyIdx].KeyLen == 0))
+ CipherAlg = CIPHER_NONE;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else if ( pAd->StaCfg.WpaSupplicantUP &&
+ (Cipher == Ndis802_11Encryption1Enabled) &&
+ (pAd->StaCfg.IEEE8021X == TRUE) &&
+ (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ CipherAlg = CIPHER_NONE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ {
+ //Header_802_11.FC.Wep = 1;
+ CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+ pKey = &pAd->SharedKey[BSS0][KeyIdx];
+ }
+ }
+
+ pTxBlk->CipherAlg = CipherAlg;
+ pTxBlk->pKey = pKey;
+}
+
+
+VOID STABuildCommon802_11Header(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+
+ HEADER_802_11 *pHeader_802_11;
+#ifdef QOS_DLS_SUPPORT
+ BOOLEAN bDLSFrame = FALSE;
+ INT DlsEntryIndex = 0;
+#endif // QOS_DLS_SUPPORT //
+
+ //
+ // MAKE A COMMON 802.11 HEADER
+ //
+
+ // normal wlan header size : 24 octets
+ pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+
+ pHeader_802_11 = (HEADER_802_11 *) &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+
+ NdisZeroMemory(pHeader_802_11, sizeof(HEADER_802_11));
+
+ pHeader_802_11->FC.FrDs = 0;
+ pHeader_802_11->FC.Type = BTYPE_DATA;
+ pHeader_802_11->FC.SubType = ((TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM)) ? SUBTYPE_QDATA : SUBTYPE_DATA);
+
+#ifdef QOS_DLS_SUPPORT
+ if (INFRA_ON(pAd))
+ {
+ // Check if the frame can be sent through DLS direct link interface
+ // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
+ DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
+ if (DlsEntryIndex >= 0)
+ bDLSFrame = TRUE;
+ else
+ bDLSFrame = FALSE;
+ }
+#endif // QOS_DLS_SUPPORT //
+
+ if (pTxBlk->pMacEntry)
+ {
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bForceNonQoS))
+ {
+ pHeader_802_11->Sequence = pTxBlk->pMacEntry->NonQosDataSeq;
+ pTxBlk->pMacEntry->NonQosDataSeq = (pTxBlk->pMacEntry->NonQosDataSeq+1) & MAXSEQ;
+ }
+ else
+ {
+#ifdef QOS_DLS_SUPPORT
+ if (bDLSFrame)
+ {
+ pHeader_802_11->Sequence = pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence;
+ pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence = (pAd->StaCfg.DLSEntry[DlsEntryIndex].Sequence+1) & MAXSEQ;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ {
+ pHeader_802_11->Sequence = pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority];
+ pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority] = (pTxBlk->pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+ }
+ }
+ }
+ else
+ {
+ pHeader_802_11->Sequence = pAd->Sequence;
+ pAd->Sequence = (pAd->Sequence+1) & MAXSEQ; // next sequence
+ }
+
+ pHeader_802_11->Frag = 0;
+
+ pHeader_802_11->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+ {
+ if (INFRA_ON(pAd))
+ {
+#ifdef QOS_DLS_SUPPORT
+ if (bDLSFrame)
+ {
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+ pHeader_802_11->FC.ToDs = 0;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ {
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pAd->CommonCfg.Bssid);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pTxBlk->pSrcBufHeader);
+ pHeader_802_11->FC.ToDs = 1;
+ }
+ }
+ else if (ADHOC_ON(pAd))
+ {
+ COPY_MAC_ADDR(pHeader_802_11->Addr1, pTxBlk->pSrcBufHeader);
+ COPY_MAC_ADDR(pHeader_802_11->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHeader_802_11->Addr3, pAd->CommonCfg.Bssid);
+ pHeader_802_11->FC.ToDs = 0;
+ }
+ }
+
+ if (pTxBlk->CipherAlg != CIPHER_NONE)
+ pHeader_802_11->FC.Wep = 1;
+
+ // -----------------------------------------------------------------
+ // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
+ // -----------------------------------------------------------------
+ if (pAd->CommonCfg.bAPSDForcePowerSave)
+ pHeader_802_11->FC.PwrMgmt = PWR_SAVE;
+ else
+ pHeader_802_11->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+}
+
+#ifdef DOT11_N_SUPPORT
+VOID STABuildCache802_11Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR *pHeader)
+{
+ MAC_TABLE_ENTRY *pMacEntry;
+ PHEADER_802_11 pHeader80211;
+
+ pHeader80211 = (PHEADER_802_11)pHeader;
+ pMacEntry = pTxBlk->pMacEntry;
+
+ //
+ // Update the cached 802.11 HEADER
+ //
+
+ // normal wlan header size : 24 octets
+ pTxBlk->MpduHeaderLen = sizeof(HEADER_802_11);
+
+ // More Bit
+ pHeader80211->FC.MoreData = TX_BLK_TEST_FLAG(pTxBlk, fTX_bMoreData);
+
+ // Sequence
+ pHeader80211->Sequence = pMacEntry->TxSeq[pTxBlk->UserPriority];
+ pMacEntry->TxSeq[pTxBlk->UserPriority] = (pMacEntry->TxSeq[pTxBlk->UserPriority]+1) & MAXSEQ;
+
+ {
+ // Check if the frame can be sent through DLS direct link interface
+ // If packet can be sent through DLS, then force aggregation disable. (Hard to determine peer STA's capability)
+#ifdef QOS_DLS_SUPPORT
+ BOOLEAN bDLSFrame = FALSE;
+ INT DlsEntryIndex = 0;
+
+ DlsEntryIndex = RTMPCheckDLSFrame(pAd, pTxBlk->pSrcBufHeader);
+ if (DlsEntryIndex >= 0)
+ bDLSFrame = TRUE;
+ else
+ bDLSFrame = FALSE;
+#endif // QOS_DLS_SUPPORT //
+
+ // The addr3 of normal packet send from DS is Dest Mac address.
+#ifdef QOS_DLS_SUPPORT
+ if (bDLSFrame)
+ {
+ COPY_MAC_ADDR(pHeader80211->Addr1, pTxBlk->pSrcBufHeader);
+ COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
+ pHeader80211->FC.ToDs = 0;
+ }
+ else
+#endif // QOS_DLS_SUPPORT //
+ if (ADHOC_ON(pAd))
+ COPY_MAC_ADDR(pHeader80211->Addr3, pAd->CommonCfg.Bssid);
+ else
+ COPY_MAC_ADDR(pHeader80211->Addr3, pTxBlk->pSrcBufHeader);
+ }
+
+ // -----------------------------------------------------------------
+ // STEP 2. MAKE A COMMON 802.11 HEADER SHARED BY ENTIRE FRAGMENT BURST. Fill sequence later.
+ // -----------------------------------------------------------------
+ if (pAd->CommonCfg.bAPSDForcePowerSave)
+ pHeader80211->FC.PwrMgmt = PWR_SAVE;
+ else
+ pHeader80211->FC.PwrMgmt = (pAd->StaCfg.Psm == PWR_SAVE);
+}
+#endif // DOT11_N_SUPPORT //
+
+static inline PUCHAR STA_Build_ARalink_Frame_Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;
+ HEADER_802_11 *pHeader_802_11;
+ PNDIS_PACKET pNextPacket;
+ UINT32 nextBufLen;
+ PQUEUE_ENTRY pQEntry;
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // steal "order" bit to mark "aggregation"
+ pHeader_802_11->FC.Order = 1;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+ {
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+ }
+
+ // padding at front of LLC header. LLC header should at 4-bytes aligment.
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR)ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ // For RA Aggregation,
+ // put the 2nd MSDU length(extra 2-byte field) after QOS_CONTROL in little endian format
+ pQEntry = pTxBlk->TxPacketList.Head;
+ pNextPacket = QUEUE_ENTRY_TO_PKT(pQEntry);
+ nextBufLen = GET_OS_PKT_LEN(pNextPacket);
+ if (RTMP_GET_PACKET_VLAN(pNextPacket))
+ nextBufLen -= LENGTH_802_1Q;
+
+ *pHeaderBufPtr = (UCHAR)nextBufLen & 0xff;
+ *(pHeaderBufPtr+1) = (UCHAR)(nextBufLen >> 8);
+
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += 2;
+
+ return pHeaderBufPtr;
+
+}
+
+#ifdef DOT11_N_SUPPORT
+static inline PUCHAR STA_Build_AMSDU_Frame_Header(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;//, pSaveBufPtr;
+ HEADER_802_11 *pHeader_802_11;
+
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+ //
+ // A-MSDU packet
+ //
+ *pHeaderBufPtr |= 0x80;
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+
+ //pSaveBufPtr = pHeaderBufPtr;
+
+ //
+ // padding at front of LLC header
+ // LLC header should locate at 4-octets aligment
+ //
+ // @@@ MpduHeaderLen excluding padding @@@
+ //
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ return pHeaderBufPtr;
+
+}
+
+
+VOID STA_AMPDU_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ MAC_TABLE_ENTRY *pMacEntry;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+ ASSERT(pTxBlk);
+
+ while(pTxBlk->TxPacketList.Head)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if ( RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ pMacEntry = pTxBlk->pMacEntry;
+ if (pMacEntry->isCached)
+ {
+ // NOTE: Please make sure the size of pMacEntry->CachedBuf[] is smaller than pTxBlk->HeaderBuf[]!!!!
+ NdisMoveMemory((PUCHAR)&pTxBlk->HeaderBuf[TXINFO_SIZE], (PUCHAR)&pMacEntry->CachedBuf[0], TXWI_SIZE + sizeof(HEADER_802_11));
+ pHeaderBufPtr = (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE]);
+ STABuildCache802_11Header(pAd, pTxBlk, pHeaderBufPtr);
+ }
+ else
+ {
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ }
+
+
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+
+ //
+ // build HTC+
+ // HTC control filed following QoS field
+ //
+ if ((pAd->CommonCfg.bRdg == TRUE) && CLIENT_STATUS_TEST_FLAG(pTxBlk->pMacEntry, fCLIENT_STATUS_RDG_CAPABLE))
+ {
+ if (pMacEntry->isCached == FALSE)
+ {
+ // mark HTC bit
+ pHeader_802_11->FC.Order = 1;
+
+ NdisZeroMemory(pHeaderBufPtr, 4);
+ *(pHeaderBufPtr+3) |= 0x80;
+ }
+ pHeaderBufPtr += 4;
+ pTxBlk->MpduHeaderLen += 4;
+ }
+
+ //pTxBlk->MpduHeaderLen = pHeaderBufPtr - pTxBlk->HeaderBuf - TXWI_SIZE - TXINFO_SIZE;
+ ASSERT(pTxBlk->MpduHeaderLen >= 24);
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ //
+ // padding at front of LLC header
+ // LLC header should locate at 4-octets aligment
+ //
+ // @@@ MpduHeaderLen excluding padding @@@
+ //
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ {
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+
+ }
+
+ if (pMacEntry->isCached)
+ {
+ RTMPWriteTxWI_Cache(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+ }
+ else
+ {
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ NdisZeroMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), sizeof(pMacEntry->CachedBuf));
+ NdisMoveMemory((PUCHAR)(&pMacEntry->CachedBuf[0]), (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), (pHeaderBufPtr - (PUCHAR)(&pTxBlk->HeaderBuf[TXINFO_SIZE])));
+ pMacEntry->isCached = TRUE;
+ }
+
+ // calculate Transmitted AMPDU count and ByteCount
+ {
+ pAd->RalinkCounters.TransmittedMPDUsInAMPDUCount.u.LowPart ++;
+ pAd->RalinkCounters.TransmittedOctetsInAMPDUCount.QuadPart += pTxBlk->SrcBufLen;
+ }
+
+ //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+ }
+
+}
+
+
+VOID STA_AMSDU_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ USHORT subFramePayloadLen = 0; // AMSDU Subframe length without AMSDU-Header / Padding.
+ USHORT totalMPDUSize=0;
+ UCHAR *subFrameHeader;
+ UCHAR padding = 0;
+ USHORT FirstTx = 0, LastTxIdx = 0;
+ BOOLEAN bVLANPkt;
+ int frameNum = 0;
+ PQUEUE_ENTRY pQEntry;
+
+
+ ASSERT(pTxBlk);
+
+ ASSERT((pTxBlk->TxPacketList.Number > 1));
+
+ while(pTxBlk->TxPacketList.Head)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ if (frameNum == 0)
+ {
+ pHeaderBufPtr = STA_Build_AMSDU_Frame_Header(pAd, pTxBlk);
+
+ // NOTE: TxWI->MPDUtotalByteCount will be updated after final frame was handled.
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+ }
+ else
+ {
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
+ padding = ROUND_UP(LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen, 4) - (LENGTH_AMSDU_SUBFRAMEHEAD + subFramePayloadLen);
+ NdisZeroMemory(pHeaderBufPtr, padding + LENGTH_AMSDU_SUBFRAMEHEAD);
+ pHeaderBufPtr += padding;
+ pTxBlk->MpduHeaderLen = padding;
+ }
+
+ //
+ // A-MSDU subframe
+ // DA(6)+SA(6)+Length(2) + LLC/SNAP Encap
+ //
+ subFrameHeader = pHeaderBufPtr;
+ subFramePayloadLen = pTxBlk->SrcBufLen;
+
+ NdisMoveMemory(subFrameHeader, pTxBlk->pSrcBufHeader, 12);
+
+
+ pHeaderBufPtr += LENGTH_AMSDU_SUBFRAMEHEAD;
+ pTxBlk->MpduHeaderLen += LENGTH_AMSDU_SUBFRAMEHEAD;
+
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+
+ subFramePayloadLen = pTxBlk->SrcBufLen;
+
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ subFramePayloadLen += LENGTH_802_1_H;
+ }
+
+ // update subFrame Length field
+ subFrameHeader[12] = (subFramePayloadLen & 0xFF00) >> 8;
+ subFrameHeader[13] = subFramePayloadLen & 0xFF;
+
+ totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+ if (frameNum ==0)
+ FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+ else
+ LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+
+ frameNum++;
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ // calculate Transmitted AMSDU Count and ByteCount
+ {
+ pAd->RalinkCounters.TransmittedAMSDUCount.u.LowPart ++;
+ pAd->RalinkCounters.TransmittedOctetsInAMSDU.QuadPart += totalMPDUSize;
+ }
+
+ }
+
+ HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+ HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+#endif // DOT11_N_SUPPORT //
+
+VOID STA_Legacy_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+ ASSERT(pTxBlk);
+
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ if (pTxBlk->TxFrameType == TX_MCAST_FRAME)
+ {
+ INC_COUNTER64(pAd->WlanCounters.MulticastTransmittedFrameCount);
+ }
+
+ if (RTMP_GET_PACKET_RTS(pTxBlk->pPacket))
+ TX_BLK_SET_FLAG(pTxBlk, fTX_bRtsRequired);
+ else
+ TX_BLK_CLEAR_FLAG(pTxBlk, fTX_bRtsRequired);
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ if (pTxBlk->TxRate < pAd->CommonCfg.MinTxRate)
+ pTxBlk->TxRate = pAd->CommonCfg.MinTxRate;
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *) pHeaderBufPtr;
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+ {
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+ }
+
+ // The remaining content of MPDU header should locate at 4-octets aligment
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+ {
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ //
+ // if original Ethernet frame contains no LLC/SNAP,
+ // then an extra LLC/SNAP encap is required
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ UCHAR vlan_size;
+
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // skip vlan tag
+ vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+
+ }
+
+ //
+ // prepare for TXWI
+ // use Wcid as Key Index
+ //
+
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+
+ HAL_WriteTxResource(pAd, pTxBlk, TRUE, &FreeNumber);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+
+
+VOID STA_ARalink_Frame_Tx(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk)
+{
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ USHORT totalMPDUSize=0;
+ USHORT FirstTx, LastTxIdx;
+ int frameNum = 0;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+
+ ASSERT(pTxBlk);
+
+ ASSERT((pTxBlk->TxPacketList.Number== 2));
+
+
+ FirstTx = LastTxIdx = 0; // Is it ok init they as 0?
+ while(pTxBlk->TxPacketList.Head)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ continue;
+ }
+
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ if (frameNum == 0)
+ { // For first frame, we need to create the 802.11 header + padding(optional) + RA-AGG-LEN + SNAP Header
+
+ pHeaderBufPtr = STA_Build_ARalink_Frame_Header(pAd, pTxBlk);
+
+ // It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount
+ // will be updated after final frame was handled.
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_OFFSET(pTxBlk->pSrcBufData-2, pTxBlk->pExtraLlcSnapEncap);
+
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+ }
+ else
+ { // For second aggregated frame, we need create the 802.3 header to headerBuf, because PCI will copy it to SDPtr0.
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[0];
+ pTxBlk->MpduHeaderLen = 0;
+
+ // A-Ralink sub-sequent frame header is the same as 802.3 header.
+ // DA(6)+SA(6)+FrameType(2)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader, 12);
+ pHeaderBufPtr += 12;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufData-2, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen = LENGTH_ARALINK_SUBFRAMEHEAD;
+ }
+
+ totalMPDUSize += pTxBlk->MpduHeaderLen + pTxBlk->SrcBufLen;
+
+ //FreeNumber = GET_TXRING_FREENO(pAd, QueIdx);
+ if (frameNum ==0)
+ FirstTx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+ else
+ LastTxIdx = HAL_WriteMultiTxResource(pAd, pTxBlk, frameNum, &FreeNumber);
+
+ frameNum++;
+
+ pAd->RalinkCounters.OneSecTxAggregationCount++;
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ }
+
+ HAL_FinalWriteTxResource(pAd, pTxBlk, totalMPDUSize, FirstTx);
+ HAL_LastTxIdx(pAd, pTxBlk->QueIdx, LastTxIdx);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+
+}
+
+
+VOID STA_Fragment_Frame_Tx(
+ IN RTMP_ADAPTER *pAd,
+ IN TX_BLK *pTxBlk)
+{
+ HEADER_802_11 *pHeader_802_11;
+ PUCHAR pHeaderBufPtr;
+ USHORT FreeNumber;
+ UCHAR fragNum = 0;
+ PACKET_INFO PacketInfo;
+ USHORT EncryptionOverhead = 0;
+ UINT32 FreeMpduSize, SrcRemainingBytes;
+ USHORT AckDuration;
+ UINT NextMpduSize;
+ BOOLEAN bVLANPkt;
+ PQUEUE_ENTRY pQEntry;
+
+
+ ASSERT(pTxBlk);
+
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pTxBlk->pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (RTMP_FillTxBlkInfo(pAd, pTxBlk) != TRUE)
+ {
+ RELEASE_NDIS_PACKET(pAd, pTxBlk->pPacket, NDIS_STATUS_FAILURE);
+ return;
+ }
+
+ ASSERT(TX_BLK_TEST_FLAG(pTxBlk, fTX_bAllowFrag));
+ bVLANPkt = (RTMP_GET_PACKET_VLAN(pTxBlk->pPacket) ? TRUE : FALSE);
+
+ STAFindCipherAlgorithm(pAd, pTxBlk);
+ STABuildCommon802_11Header(pAd, pTxBlk);
+
+ if (pTxBlk->CipherAlg == CIPHER_TKIP)
+ {
+ pTxBlk->pPacket = duplicate_pkt_with_TKIP_MIC(pAd, pTxBlk->pPacket);
+ if (pTxBlk->pPacket == NULL)
+ return;
+ RTMP_QueryPacketInfo(pTxBlk->pPacket, &PacketInfo, &pTxBlk->pSrcBufHeader, &pTxBlk->SrcBufLen);
+ }
+
+ // skip 802.3 header
+ pTxBlk->pSrcBufData = pTxBlk->pSrcBufHeader + LENGTH_802_3;
+ pTxBlk->SrcBufLen -= LENGTH_802_3;
+
+
+ // skip vlan tag
+ if (bVLANPkt)
+ {
+ pTxBlk->pSrcBufData += LENGTH_802_1Q;
+ pTxBlk->SrcBufLen -= LENGTH_802_1Q;
+ }
+
+ pHeaderBufPtr = &pTxBlk->HeaderBuf[TXINFO_SIZE + TXWI_SIZE];
+ pHeader_802_11 = (HEADER_802_11 *)pHeaderBufPtr;
+
+
+ // skip common header
+ pHeaderBufPtr += pTxBlk->MpduHeaderLen;
+
+ if (TX_BLK_TEST_FLAG(pTxBlk, fTX_bWMM))
+ {
+ //
+ // build QOS Control bytes
+ //
+ *pHeaderBufPtr = (pTxBlk->UserPriority & 0x0F);
+
+ *(pHeaderBufPtr+1) = 0;
+ pHeaderBufPtr +=2;
+ pTxBlk->MpduHeaderLen += 2;
+ }
+
+ //
+ // padding at front of LLC header
+ // LLC header should locate at 4-octets aligment
+ //
+ pTxBlk->HdrPadLen = (ULONG)pHeaderBufPtr;
+ pHeaderBufPtr = (PCHAR) ROUND_UP(pHeaderBufPtr, 4);
+ pTxBlk->HdrPadLen = (ULONG)(pHeaderBufPtr - pTxBlk->HdrPadLen);
+
+
+
+ //
+ // Insert LLC-SNAP encapsulation - 8 octets
+ //
+ //
+ // if original Ethernet frame contains no LLC/SNAP,
+ // then an extra LLC/SNAP encap is required
+ //
+ EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(pTxBlk->pSrcBufHeader, pTxBlk->pExtraLlcSnapEncap);
+ if (pTxBlk->pExtraLlcSnapEncap)
+ {
+ UCHAR vlan_size;
+
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pExtraLlcSnapEncap, 6);
+ pHeaderBufPtr += 6;
+ // skip vlan tag
+ vlan_size = (bVLANPkt) ? LENGTH_802_1Q : 0;
+ // get 2 octets (TypeofLen)
+ NdisMoveMemory(pHeaderBufPtr, pTxBlk->pSrcBufHeader+12+vlan_size, 2);
+ pHeaderBufPtr += 2;
+ pTxBlk->MpduHeaderLen += LENGTH_802_1_H;
+ }
+
+
+ // If TKIP is used and fragmentation is required. Driver has to
+ // append TKIP MIC at tail of the scatter buffer
+ // MAC ASIC will only perform IV/EIV/ICV insertion but no TKIP MIC
+ if (pTxBlk->CipherAlg == CIPHER_TKIP)
+ {
+
+ // NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust
+ // to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress.
+ NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8);
+ //skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8);
+ pTxBlk->SrcBufLen += 8;
+ pTxBlk->TotalFrameLen += 8;
+ pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC;
+ }
+
+ //
+ // calcuate the overhead bytes that encryption algorithm may add. This
+ // affects the calculate of "duration" field
+ //
+ if ((pTxBlk->CipherAlg == CIPHER_WEP64) || (pTxBlk->CipherAlg == CIPHER_WEP128))
+ EncryptionOverhead = 8; //WEP: IV[4] + ICV[4];
+ else if (pTxBlk->CipherAlg == CIPHER_TKIP_NO_MIC)
+ EncryptionOverhead = 12;//TKIP: IV[4] + EIV[4] + ICV[4], MIC will be added to TotalPacketLength
+ else if (pTxBlk->CipherAlg == CIPHER_TKIP)
+ EncryptionOverhead = 20;//TKIP: IV[4] + EIV[4] + ICV[4] + MIC[8]
+ else if (pTxBlk->CipherAlg == CIPHER_AES)
+ EncryptionOverhead = 16; // AES: IV[4] + EIV[4] + MIC[8]
+ else
+ EncryptionOverhead = 0;
+
+ // decide how much time an ACK/CTS frame will consume in the air
+ AckDuration = RTMPCalcDuration(pAd, pAd->CommonCfg.ExpectedACKRate[pTxBlk->TxRate], 14);
+
+ // Init the total payload length of this frame.
+ SrcRemainingBytes = pTxBlk->SrcBufLen;
+
+ pTxBlk->TotalFragNum = 0xff;
+
+ do {
+
+ FreeMpduSize = pAd->CommonCfg.FragmentThreshold - LENGTH_CRC;
+
+ FreeMpduSize -= pTxBlk->MpduHeaderLen;
+
+ if (SrcRemainingBytes <= FreeMpduSize)
+ { // this is the last or only fragment
+
+ pTxBlk->SrcBufLen = SrcRemainingBytes;
+
+ pHeader_802_11->FC.MoreFrag = 0;
+ pHeader_802_11->Duration = pAd->CommonCfg.Dsifs + AckDuration;
+
+ // Indicate the lower layer that this's the last fragment.
+ pTxBlk->TotalFragNum = fragNum;
+ }
+ else
+ { // more fragment is required
+
+ pTxBlk->SrcBufLen = FreeMpduSize;
+
+ NextMpduSize = min(((UINT)SrcRemainingBytes - pTxBlk->SrcBufLen), ((UINT)pAd->CommonCfg.FragmentThreshold));
+ pHeader_802_11->FC.MoreFrag = 1;
+ pHeader_802_11->Duration = (3 * pAd->CommonCfg.Dsifs) + (2 * AckDuration) + RTMPCalcDuration(pAd, pTxBlk->TxRate, NextMpduSize + EncryptionOverhead);
+ }
+
+ if (fragNum == 0)
+ pTxBlk->FrameGap = IFS_HTTXOP;
+ else
+ pTxBlk->FrameGap = IFS_SIFS;
+
+ RTMPWriteTxWI_Data(pAd, (PTXWI_STRUC)(&pTxBlk->HeaderBuf[TXINFO_SIZE]), pTxBlk);
+
+ HAL_WriteFragTxResource(pAd, pTxBlk, fragNum, &FreeNumber);
+
+ pAd->RalinkCounters.KickTxCount++;
+ pAd->RalinkCounters.OneSecTxDoneCount++;
+
+ // Update the frame number, remaining size of the NDIS packet payload.
+
+ // space for 802.11 header.
+ if (fragNum == 0 && pTxBlk->pExtraLlcSnapEncap)
+ pTxBlk->MpduHeaderLen -= LENGTH_802_1_H;
+
+ fragNum++;
+ SrcRemainingBytes -= pTxBlk->SrcBufLen;
+ pTxBlk->pSrcBufData += pTxBlk->SrcBufLen;
+
+ pHeader_802_11->Frag++; // increase Frag #
+
+ }while(SrcRemainingBytes > 0);
+
+ //
+ // Kick out Tx
+ //
+ HAL_KickOutTx(pAd, pTxBlk, pTxBlk->QueIdx);
+}
+
+
+#define RELEASE_FRAMES_OF_TXBLK(_pAd, _pTxBlk, _pQEntry, _Status) \
+ while(_pTxBlk->TxPacketList.Head) \
+ { \
+ _pQEntry = RemoveHeadQueue(&_pTxBlk->TxPacketList); \
+ RELEASE_NDIS_PACKET(_pAd, QUEUE_ENTRY_TO_PACKET(_pQEntry), _Status); \
+ }
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware encryption before really
+ sent out to air.
+
+ Arguments:
+ pAd Pointer to our adapter
+ PNDIS_PACKET Pointer to outgoing Ndis frame
+ NumberOfFrag Number of fragment required
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+NDIS_STATUS STAHardTransmit(
+ IN PRTMP_ADAPTER pAd,
+ IN TX_BLK *pTxBlk,
+ IN UCHAR QueIdx)
+{
+ NDIS_PACKET *pPacket;
+ PQUEUE_ENTRY pQEntry;
+
+ // ---------------------------------------------
+ // STEP 0. DO SANITY CHECK AND SOME EARLY PREPARATION.
+ // ---------------------------------------------
+ //
+ ASSERT(pTxBlk->TxPacketList.Number);
+ if (pTxBlk->TxPacketList.Head == NULL)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("pTxBlk->TotalFrameNum == %ld!\n", pTxBlk->TxPacketList.Number));
+ return NDIS_STATUS_FAILURE;
+ }
+
+ pPacket = QUEUE_ENTRY_TO_PACKET(pTxBlk->TxPacketList.Head);
+
+ // ------------------------------------------------------------------
+ // STEP 1. WAKE UP PHY
+ // outgoing frame always wakeup PHY to prevent frame lost and
+ // turn off PSM bit to improve performance
+ // ------------------------------------------------------------------
+ // not to change PSM bit, just send this frame out?
+ if ((pAd->StaCfg.Psm == PWR_SAVE) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("AsicForceWakeup At HardTx\n"));
+ AsicForceWakeup(pAd, TRUE);
+ }
+
+ // It should not change PSM bit, when APSD turn on.
+ if ((!(pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable) && (pAd->CommonCfg.bAPSDForcePowerSave == FALSE))
+ || (RTMP_GET_PACKET_EAPOL(pTxBlk->pPacket))
+ || (RTMP_GET_PACKET_WAI(pTxBlk->pPacket)))
+ {
+ if ((pAd->StaCfg.Psm == PWR_SAVE) &&
+ (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeFast_PSP))
+ MlmeSetPsmBit(pAd, PWR_ACTIVE);
+ }
+
+ switch (pTxBlk->TxFrameType)
+ {
+#ifdef DOT11_N_SUPPORT
+ case TX_AMPDU_FRAME:
+ STA_AMPDU_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_AMSDU_FRAME:
+ STA_AMSDU_Frame_Tx(pAd, pTxBlk);
+ break;
+#endif // DOT11_N_SUPPORT //
+ case TX_LEGACY_FRAME:
+ STA_Legacy_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_MCAST_FRAME:
+ STA_Legacy_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_RALINK_FRAME:
+ STA_ARalink_Frame_Tx(pAd, pTxBlk);
+ break;
+ case TX_FRAG_FRAME:
+ STA_Fragment_Frame_Tx(pAd, pTxBlk);
+ break;
+ default:
+ {
+ // It should not happened!
+ DBGPRINT(RT_DEBUG_ERROR, ("Send a pacekt was not classified!! It should not happen!\n"));
+ while(pTxBlk->TxPacketList.Number)
+ {
+ pQEntry = RemoveHeadQueue(&pTxBlk->TxPacketList);
+ pPacket = QUEUE_ENTRY_TO_PACKET(pQEntry);
+ if (pPacket)
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+ }
+ break;
+ }
+
+ return (NDIS_STATUS_SUCCESS);
+
+}
+
+ULONG HashBytesPolynomial(UCHAR *value, unsigned int len)
+{
+ unsigned char *word = value;
+ unsigned int ret = 0;
+ unsigned int i;
+
+ for(i=0; i < len; i++)
+ {
+ int mod = i % 32;
+ ret ^=(unsigned int) (word[i]) << mod;
+ ret ^=(unsigned int) (word[i]) >> (32 - mod);
+ }
+ return ret;
+}
+
+VOID Sta_Announce_or_Forward_802_3_Packet(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_PACKET pPacket,
+ IN UCHAR FromWhichBSSID)
+{
+ if (TRUE
+ )
+ {
+ announce_802_3_packet(pAd, pPacket);
+ }
+ else
+ {
+ // release packet
+ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE);
+ }
+}
+
diff --git a/drivers/staging/rt3070/sta/sanity.c b/drivers/staging/rt3070/sta/sanity.c
new file mode 100644
index 00000000000..239872464be
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sanity.c
@@ -0,0 +1,420 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sanity.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 add WMM support
+*/
+#include "../rt_config.h"
+
+extern UCHAR CISCO_OUI[];
+
+extern UCHAR WPA_OUI[];
+extern UCHAR RSN_OUI[];
+extern UCHAR WME_INFO_ELEM[];
+extern UCHAR WME_PARM_ELEM[];
+extern UCHAR Ccx2QosInfo[];
+extern UCHAR RALINK_OUI[];
+extern UCHAR BROADCOM_OUI[];
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+ */
+BOOLEAN MlmeStartReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen)
+{
+ MLME_START_REQ_STRUCT *Info;
+
+ Info = (MLME_START_REQ_STRUCT *)(Msg);
+
+ if (Info->SsidLen > MAX_LEN_OF_SSID)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqSanity fail - wrong SSID length\n"));
+ return FALSE;
+ }
+
+ *pSsidLen = Info->SsidLen;
+ NdisMoveMemory(Ssid, Info->Ssid, *pSsidLen);
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerAssocRspSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *pMsg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT USHORT *pCapabilityInfo,
+ OUT USHORT *pStatus,
+ OUT USHORT *pAid,
+ OUT UCHAR SupRate[],
+ OUT UCHAR *pSupRateLen,
+ OUT UCHAR ExtRate[],
+ OUT UCHAR *pExtRateLen,
+ OUT HT_CAPABILITY_IE *pHtCapability,
+ OUT ADD_HT_INFO_IE *pAddHtInfo, // AP might use this additional ht info IE
+ OUT UCHAR *pHtCapabilityLen,
+ OUT UCHAR *pAddHtInfoLen,
+ OUT UCHAR *pNewExtChannelOffset,
+ OUT PEDCA_PARM pEdcaParm,
+ OUT UCHAR *pCkipFlag)
+{
+ CHAR IeType, *Ptr;
+ PFRAME_802_11 pFrame = (PFRAME_802_11)pMsg;
+ PEID_STRUCT pEid;
+ ULONG Length = 0;
+
+ *pNewExtChannelOffset = 0xff;
+ *pHtCapabilityLen = 0;
+ *pAddHtInfoLen = 0;
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+ Ptr = pFrame->Octet;
+ Length += LENGTH_802_11;
+
+ NdisMoveMemory(pCapabilityInfo, &pFrame->Octet[0], 2);
+ Length += 2;
+ NdisMoveMemory(pStatus, &pFrame->Octet[2], 2);
+ Length += 2;
+ *pCkipFlag = 0;
+ *pExtRateLen = 0;
+ pEdcaParm->bValid = FALSE;
+
+ if (*pStatus != MLME_SUCCESS)
+ return TRUE;
+
+ NdisMoveMemory(pAid, &pFrame->Octet[4], 2);
+ Length += 2;
+
+ // Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform
+ *pAid = (*pAid) & 0x3fff; // AID is low 14-bit
+
+ // -- get supported rates from payload and advance the pointer
+ IeType = pFrame->Octet[6];
+ *pSupRateLen = pFrame->Octet[7];
+ if ((IeType != IE_SUPP_RATES) || (*pSupRateLen > MAX_LEN_OF_SUPPORTED_RATES))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity fail - wrong SupportedRates IE\n"));
+ return FALSE;
+ }
+ else
+ NdisMoveMemory(SupRate, &pFrame->Octet[8], *pSupRateLen);
+
+ Length = Length + 2 + *pSupRateLen;
+
+ // many AP implement proprietary IEs in non-standard order, we'd better
+ // tolerate mis-ordered IEs to get best compatibility
+ pEid = (PEID_STRUCT) &pFrame->Octet[8 + (*pSupRateLen)];
+
+ // get variable fields from payload and advance the pointer
+ while ((Length + 2 + pEid->Len) <= MsgLen)
+ {
+ switch (pEid->Eid)
+ {
+ case IE_EXT_SUPP_RATES:
+ if (pEid->Len <= MAX_LEN_OF_SUPPORTED_RATES)
+ {
+ NdisMoveMemory(ExtRate, pEid->Octet, pEid->Len);
+ *pExtRateLen = pEid->Len;
+ }
+ break;
+
+ case IE_HT_CAP:
+ case IE_HT_CAP2:
+ if (pEid->Len >= SIZE_HT_CAP_IE) //Note: allow extension.!!
+ {
+ NdisMoveMemory(pHtCapability, pEid->Octet, SIZE_HT_CAP_IE);
+
+ *(USHORT *)(&pHtCapability->HtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->HtCapInfo));
+ *(USHORT *)(&pHtCapability->ExtHtCapInfo) = cpu2le16(*(USHORT *)(&pHtCapability->ExtHtCapInfo));
+
+ *pHtCapabilityLen = SIZE_HT_CAP_IE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_HT_CAP. \n"));
+ }
+
+ break;
+#ifdef DOT11_N_SUPPORT
+ case IE_ADD_HT:
+ case IE_ADD_HT2:
+ if (pEid->Len >= sizeof(ADD_HT_INFO_IE))
+ {
+ // This IE allows extension, but we can ignore extra bytes beyond our knowledge , so only
+ // copy first sizeof(ADD_HT_INFO_IE)
+ NdisMoveMemory(pAddHtInfo, pEid->Octet, sizeof(ADD_HT_INFO_IE));
+
+ *(USHORT *)(&pAddHtInfo->AddHtInfo2) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo2));
+ *(USHORT *)(&pAddHtInfo->AddHtInfo3) = cpu2le16(*(USHORT *)(&pAddHtInfo->AddHtInfo3));
+
+ *pAddHtInfoLen = SIZE_ADD_HT_INFO_IE;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_ADD_HT. \n"));
+ }
+
+ break;
+ case IE_SECONDARY_CH_OFFSET:
+ if (pEid->Len == 1)
+ {
+ *pNewExtChannelOffset = pEid->Octet[0];
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_WARN, ("PeerAssocRspSanity - wrong IE_SECONDARY_CH_OFFSET. \n"));
+ }
+#endif // DOT11_N_SUPPORT //
+ break;
+ case IE_AIRONET_CKIP:
+ // 0. Check Aironet IE length, it must be larger or equal to 28
+ // Cisco's AP VxWork version(will not be supported) used this IE length as 28
+ // Cisco's AP IOS version used this IE length as 30
+ if (pEid->Len < (CKIP_NEGOTIATION_LENGTH - 2))
+ break;
+
+ // 1. Copy CKIP flag byte to buffer for process
+ *pCkipFlag = *(pEid->Octet + 8);
+ break;
+
+ case IE_AIRONET_IPADDRESS:
+ if (pEid->Len != 0x0A)
+ break;
+
+ // Get Cisco Aironet IP information
+ if (NdisEqualMemory(pEid->Octet, CISCO_OUI, 3) == 1)
+ NdisMoveMemory(pAd->StaCfg.AironetIPAddress, pEid->Octet + 4, 4);
+ break;
+
+ // CCX2, WMM use the same IE value
+ // case IE_CCX_V2:
+ case IE_VENDOR_SPECIFIC:
+ // handle WME PARAMTER ELEMENT
+ if (NdisEqualMemory(pEid->Octet, WME_PARM_ELEM, 6) && (pEid->Len == 24))
+ {
+ PUCHAR ptr;
+ int i;
+
+ // parsing EDCA parameters
+ pEdcaParm->bValid = TRUE;
+ pEdcaParm->bQAck = FALSE; // pEid->Octet[0] & 0x10;
+ pEdcaParm->bQueueRequest = FALSE; // pEid->Octet[0] & 0x20;
+ pEdcaParm->bTxopRequest = FALSE; // pEid->Octet[0] & 0x40;
+ //pEdcaParm->bMoreDataAck = FALSE; // pEid->Octet[0] & 0x80;
+ pEdcaParm->EdcaUpdateCount = pEid->Octet[6] & 0x0f;
+ pEdcaParm->bAPSDCapable = (pEid->Octet[6] & 0x80) ? 1 : 0;
+ ptr = &pEid->Octet[8];
+ for (i=0; i<4; i++)
+ {
+ UCHAR aci = (*ptr & 0x60) >> 5; // b5~6 is AC INDEX
+ pEdcaParm->bACM[aci] = (((*ptr) & 0x10) == 0x10); // b5 is ACM
+ pEdcaParm->Aifsn[aci] = (*ptr) & 0x0f; // b0~3 is AIFSN
+ pEdcaParm->Cwmin[aci] = *(ptr+1) & 0x0f; // b0~4 is Cwmin
+ pEdcaParm->Cwmax[aci] = *(ptr+1) >> 4; // b5~8 is Cwmax
+ pEdcaParm->Txop[aci] = *(ptr+2) + 256 * (*(ptr+3)); // in unit of 32-us
+ ptr += 4; // point to next AC
+ }
+ }
+
+ // handle CCX IE
+ else
+ {
+ // 0. Check the size and CCX admin control
+ if (pAd->StaCfg.CCXControl.field.Enable == 0)
+ break;
+ if (pEid->Len != 5)
+ break;
+
+ // Turn CCX2 if matched
+ if (NdisEqualMemory(pEid->Octet, Ccx2IeInfo, 5) == 1)
+ pAd->StaCfg.CCXEnable = TRUE;
+ break;
+ }
+ break;
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerAssocRspSanity - ignore unrecognized EID = %d\n", pEid->Eid));
+ break;
+ }
+
+ Length = Length + 2 + pEid->Len;
+ pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
+ }
+
+ // Force CCX2 enable to TRUE for those AP didn't replay CCX v2 IE, we still force it to be on
+ if (pAd->StaCfg.CCXControl.field.Enable == 1)
+ pAd->StaCfg.CCXEnable = TRUE;
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME message sanity check
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN PeerProbeReqSanity(
+ IN PRTMP_ADAPTER pAd,
+ IN VOID *Msg,
+ IN ULONG MsgLen,
+ OUT PUCHAR pAddr2,
+ OUT CHAR Ssid[],
+ OUT UCHAR *pSsidLen)
+{
+ UCHAR Idx;
+ UCHAR RateLen;
+ CHAR IeType;
+ PFRAME_802_11 pFrame = (PFRAME_802_11)Msg;
+
+ COPY_MAC_ADDR(pAddr2, pFrame->Hdr.Addr2);
+
+ if ((pFrame->Octet[0] != IE_SSID) || (pFrame->Octet[1] > MAX_LEN_OF_SSID))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SSID IE(Type=%d,Len=%d)\n",pFrame->Octet[0],pFrame->Octet[1]));
+ return FALSE;
+ }
+
+ *pSsidLen = pFrame->Octet[1];
+ NdisMoveMemory(Ssid, &pFrame->Octet[2], *pSsidLen);
+
+ Idx = *pSsidLen + 2;
+
+ // -- get supported rates from payload and advance the pointer
+ IeType = pFrame->Octet[Idx];
+ RateLen = pFrame->Octet[Idx + 1];
+ if (IeType != IE_SUPP_RATES)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity fail - wrong SupportRates IE(Type=%d,Len=%d)\n",pFrame->Octet[Idx],pFrame->Octet[Idx+1]));
+ return FALSE;
+ }
+ else
+ {
+ if ((pAd->CommonCfg.PhyMode == PHY_11G) && (RateLen < 8))
+ return (FALSE);
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+BOOLEAN GetTimBit(
+ IN CHAR *Ptr,
+ IN USHORT Aid,
+ OUT UCHAR *TimLen,
+ OUT UCHAR *BcastFlag,
+ OUT UCHAR *DtimCount,
+ OUT UCHAR *DtimPeriod,
+ OUT UCHAR *MessageToMe)
+{
+ UCHAR BitCntl, N1, N2, MyByte, MyBit;
+ CHAR *IdxPtr;
+
+ IdxPtr = Ptr;
+
+ IdxPtr ++;
+ *TimLen = *IdxPtr;
+
+ // get DTIM Count from TIM element
+ IdxPtr ++;
+ *DtimCount = *IdxPtr;
+
+ // get DTIM Period from TIM element
+ IdxPtr++;
+ *DtimPeriod = *IdxPtr;
+
+ // get Bitmap Control from TIM element
+ IdxPtr++;
+ BitCntl = *IdxPtr;
+
+ if ((*DtimCount == 0) && (BitCntl & 0x01))
+ *BcastFlag = TRUE;
+ else
+ *BcastFlag = FALSE;
+
+ // Parse Partial Virtual Bitmap from TIM element
+ N1 = BitCntl & 0xfe; // N1 is the first bitmap byte#
+ N2 = *TimLen - 4 + N1; // N2 is the last bitmap byte#
+
+ if ((Aid < (N1 << 3)) || (Aid >= ((N2 + 1) << 3)))
+ *MessageToMe = FALSE;
+ else
+ {
+ MyByte = (Aid >> 3) - N1; // my byte position in the bitmap byte-stream
+ MyBit = Aid % 16 - ((MyByte & 0x01)? 8:0);
+
+ IdxPtr += (MyByte + 1);
+
+ //if (*IdxPtr)
+ // DBGPRINT(RT_DEBUG_WARN, ("TIM bitmap = 0x%02x\n", *IdxPtr));
+
+ if (*IdxPtr & (0x01 << MyBit))
+ *MessageToMe = TRUE;
+ else
+ *MessageToMe = FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta/sync.c b/drivers/staging/rt3070/sta/sync.c
new file mode 100644
index 00000000000..2b5b3b07661
--- /dev/null
+++ b/drivers/staging/rt3070/sta/sync.c
@@ -0,0 +1,1755 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sync.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ John Chang 2004-09-01 modified for rt2561/2661
+ Jan Lee 2006-08-01 modified for rt2860 for 802.11n
+*/
+#include "../rt_config.h"
+
+#define ADHOC_ENTRY_BEACON_LOST_TIME (2*OS_HZ) // 2 sec
+
+/*
+ ==========================================================================
+ Description:
+ The sync state machine,
+ Parameters:
+ Sm - pointer to the state machine
+ Note:
+ the state machine looks like the following
+
+ ==========================================================================
+ */
+VOID SyncStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *Sm,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(Sm, Trans, MAX_SYNC_STATE, MAX_SYNC_MSG, (STATE_MACHINE_FUNC)Drop, SYNC_IDLE, SYNC_MACHINE_BASE);
+
+ // column 1
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)MlmeScanReqAction);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)MlmeJoinReqAction);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)MlmeStartReqAction);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeacon);
+ StateMachineSetAction(Sm, SYNC_IDLE, MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)PeerProbeReqAction);
+
+ //column 2
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtJoinAction);
+ StateMachineSetAction(Sm, JOIN_WAIT_BEACON, MT2_BEACON_TIMEOUT, (STATE_MACHINE_FUNC)BeaconTimeoutAtJoinAction);
+
+ // column 3
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_SCAN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenScan);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_JOIN_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenJoin);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_MLME_START_REQ, (STATE_MACHINE_FUNC)InvalidStateWhenStart);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_BEACON, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)PeerBeaconAtScanAction);
+ StateMachineSetAction(Sm, SCAN_LISTEN, MT2_SCAN_TIMEOUT, (STATE_MACHINE_FUNC)ScanTimeoutAction);
+
+ // timer init
+ RTMPInitTimer(pAd, &pAd->MlmeAux.BeaconTimer, GET_TIMER_FUNCTION(BeaconTimeout), pAd, FALSE);
+ RTMPInitTimer(pAd, &pAd->MlmeAux.ScanTimer, GET_TIMER_FUNCTION(ScanTimeout), pAd, FALSE);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Beacon timeout handler, executed in timer thread
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID BeaconTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+ DBGPRINT(RT_DEBUG_TRACE,("SYNC - BeaconTimeout\n"));
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ return;
+
+#ifdef DOT11_N_SUPPORT
+ if ((pAd->CommonCfg.BBPCurrentBW == BW_40)
+ )
+ {
+ UCHAR BBPValue = 0;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel);
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ BBPValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - End of SCAN, restore to 40MHz channel %d, Total BSS[%02d]\n",pAd->CommonCfg.CentralChannel, pAd->ScanTab.BssNr));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_BEACON_TIMEOUT, 0, NULL);
+ RT28XX_MLME_HANDLER(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan timeout handler, executed in timer thread
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID ScanTimeout(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (RTMP_ADAPTER *)FunctionContext;
+
+
+ // Do nothing if the driver is starting halt state.
+ // This might happen when timer already been fired before cancel timer with mlmehalt
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS))
+ return;
+
+ if (MlmeEnqueue(pAd, SYNC_STATE_MACHINE, MT2_SCAN_TIMEOUT, 0, NULL))
+ {
+ RT28XX_MLME_HANDLER(pAd);
+ }
+ else
+ {
+ // To prevent SyncMachine.CurrState is SCAN_LISTEN forever.
+ pAd->MlmeAux.Channel = 0;
+ ScanNextChannel(pAd);
+ if (pAd->CommonCfg.bWirelessEvent)
+ {
+ RTMPSendWirelessEvent(pAd, IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+ }
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME SCAN req state machine procedure
+ ==========================================================================
+ */
+VOID MlmeScanReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, ScanType, BssType, BBPValue = 0;
+ BOOLEAN TimerCancelled;
+ ULONG Now;
+ USHORT Status;
+ PHEADER_802_11 pHdr80211;
+ PUCHAR pOutBuffer = NULL;
+ NDIS_STATUS NStatus;
+
+ // Check the total scan tries for one single OID command
+ // If this is the CCX 2.0 Case, skip that!
+ if ( !RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_START_UP))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeScanReqAction before Startup\n"));
+ return;
+ }
+
+ // Increase the scan retry counters.
+ pAd->StaCfg.ScanCnt++;
+
+
+ // first check the parameter sanity
+ if (MlmeScanReqSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ &BssType,
+ Ssid,
+ &SsidLen,
+ &ScanType))
+ {
+
+ // Check for channel load and noise hist request
+ // Suspend MSDU only at scan request, not the last two mentioned
+ if ((ScanType == SCAN_CISCO_NOISE) || (ScanType == SCAN_CISCO_CHANNEL_LOAD))
+ {
+ if (pAd->StaCfg.CCXScanChannel != pAd->CommonCfg.Channel)
+ RTMPSuspendMsduTransmission(pAd); // Suspend MSDU transmission here
+ }
+ else
+ {
+ // Suspend MSDU transmission here
+ RTMPSuspendMsduTransmission(pAd);
+ }
+
+ //
+ // To prevent data lost.
+ // Send an NULL data with turned PSM bit on to current associated AP before SCAN progress.
+ // And should send an NULL data with turned PSM bit off to AP, when scan progress done
+ //
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd)))
+ {
+ NStatus = MlmeAllocateMemory(pAd, (PVOID)&pOutBuffer);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ pHdr80211 = (PHEADER_802_11) pOutBuffer;
+ MgtMacHeaderInit(pAd, pHdr80211, SUBTYPE_NULL_FUNC, 1, pAd->CommonCfg.Bssid, pAd->CommonCfg.Bssid);
+ pHdr80211->Duration = 0;
+ pHdr80211->FC.Type = BTYPE_DATA;
+ pHdr80211->FC.PwrMgmt = PWR_SAVE;
+
+ // Send using priority queue
+ MiniportMMRequest(pAd, 0, pOutBuffer, sizeof(HEADER_802_11));
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeScanReqAction -- Send PSM Data frame for off channel RM\n"));
+ MlmeFreeMemory(pAd, pOutBuffer);
+ RTMPusecDelay(5000);
+ }
+ }
+
+ NdisGetSystemUpTime(&Now);
+ pAd->StaCfg.LastScanTime = Now;
+ // reset all the timers
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+
+ // record desired BSS parameters
+ pAd->MlmeAux.BssType = BssType;
+ pAd->MlmeAux.ScanType = ScanType;
+ pAd->MlmeAux.SsidLen = SsidLen;
+ NdisZeroMemory(pAd->MlmeAux.Ssid, MAX_LEN_OF_SSID);
+ NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+
+ // start from the first channel
+ pAd->MlmeAux.Channel = FirstChannel(pAd);
+
+ // Change the scan channel when dealing with CCX beacon report
+ if ((ScanType == SCAN_CISCO_PASSIVE) || (ScanType == SCAN_CISCO_ACTIVE) ||
+ (ScanType == SCAN_CISCO_CHANNEL_LOAD) || (ScanType == SCAN_CISCO_NOISE))
+ pAd->MlmeAux.Channel = pAd->StaCfg.CCXScanChannel;
+
+ // Let BBP register at 20MHz to do scan
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+ ScanNextChannel(pAd);
+ }
+ else
+ {
+ DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n"));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME JOIN req state machine procedure
+ ==========================================================================
+ */
+VOID MlmeJoinReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR BBPValue = 0;
+ BSS_ENTRY *pBss;
+ BOOLEAN TimerCancelled;
+ HEADER_802_11 Hdr80211;
+ NDIS_STATUS NStatus;
+ ULONG FrameLen = 0;
+ PUCHAR pOutBuffer = NULL;
+ PUCHAR pSupRate = NULL;
+ UCHAR SupRateLen;
+ PUCHAR pExtRate = NULL;
+ UCHAR ExtRateLen;
+ UCHAR ASupRate[] = {0x8C, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6C};
+ UCHAR ASupRateLen = sizeof(ASupRate)/sizeof(UCHAR);
+ MLME_JOIN_REQ_STRUCT *pInfo = (MLME_JOIN_REQ_STRUCT *)(Elem->Msg);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeJoinReqAction(BSS #%ld)\n", pInfo->BssIdx));
+
+
+ // reset all the timers
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+ pBss = &pAd->MlmeAux.SsidBssTab.BssEntry[pInfo->BssIdx];
+
+ // record the desired SSID & BSSID we're waiting for
+ COPY_MAC_ADDR(pAd->MlmeAux.Bssid, pBss->Bssid);
+
+ // If AP's SSID is not hidden, it is OK for updating ssid to MlmeAux again.
+ if (pBss->Hidden == 0)
+ {
+ NdisMoveMemory(pAd->MlmeAux.Ssid, pBss->Ssid, pBss->SsidLen);
+ pAd->MlmeAux.SsidLen = pBss->SsidLen;
+ }
+
+ pAd->MlmeAux.BssType = pBss->BssType;
+ pAd->MlmeAux.Channel = pBss->Channel;
+ pAd->MlmeAux.CentralChannel = pBss->CentralChannel;
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+ // Country IE of the AP will be evaluated and will be used.
+ if ((pAd->StaCfg.IEEE80211dClientMode != Rt802_11_D_None) &&
+ (pBss->bHasCountryIE == TRUE))
+ {
+ NdisMoveMemory(&pAd->CommonCfg.CountryCode[0], &pBss->CountryString[0], 2);
+ if (pBss->CountryString[2] == 'I')
+ pAd->CommonCfg.Geography = IDOR;
+ else if (pBss->CountryString[2] == 'O')
+ pAd->CommonCfg.Geography = ODOR;
+ else
+ pAd->CommonCfg.Geography = BOTH;
+ BuildChannelListEx(pAd);
+ }
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+ // Let BBP register at 20MHz to do scan
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAd, BBP_R4, &BBPValue);
+ BBPValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R4, BBPValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n"));
+
+ // switch channel and waiting for beacon timer
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+ RTMPSetTimer(&pAd->MlmeAux.BeaconTimer, JOIN_TIMEOUT);
+
+ do
+ {
+ if (((pAd->CommonCfg.bIEEE80211H == 1) &&
+ (pAd->MlmeAux.Channel > 14) &&
+ RadarChannelCheck(pAd, pAd->MlmeAux.Channel))
+#ifdef CARRIER_DETECTION_SUPPORT // Roger sync Carrier
+ || (pAd->CommonCfg.CarrierDetect.Enable == TRUE)
+#endif // CARRIER_DETECTION_SUPPORT //
+ )
+ {
+ //
+ // We can't send any Probe request frame to meet 802.11h.
+ //
+ if (pBss->Hidden == 0)
+ break;
+ }
+
+ //
+ // send probe request
+ //
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer);
+ if (NStatus == NDIS_STATUS_SUCCESS)
+ {
+ if (pAd->MlmeAux.Channel <= 14)
+ {
+ pSupRate = pAd->CommonCfg.SupRate;
+ SupRateLen = pAd->CommonCfg.SupRateLen;
+ pExtRate = pAd->CommonCfg.ExtRate;
+ ExtRateLen = pAd->CommonCfg.ExtRateLen;
+ }
+ else
+ {
+ //
+ // Overwrite Support Rate, CCK rate are not allowed
+ //
+ pSupRate = ASupRate;
+ SupRateLen = ASupRateLen;
+ ExtRateLen = 0;
+ }
+
+ if (pAd->MlmeAux.BssType == BSS_INFRA)
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, pAd->MlmeAux.Bssid, pAd->MlmeAux.Bssid);
+ else
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr80211,
+ 1, &SsidIe,
+ 1, &pAd->MlmeAux.SsidLen,
+ pAd->MlmeAux.SsidLen, pAd->MlmeAux.Ssid,
+ 1, &SupRateIe,
+ 1, &SupRateLen,
+ SupRateLen, pSupRate,
+ END_OF_ARGS);
+
+ if (ExtRateLen)
+ {
+ ULONG Tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &Tmp,
+ 1, &ExtRateIe,
+ 1, &ExtRateLen,
+ ExtRateLen, pExtRate,
+ END_OF_ARGS);
+ FrameLen += Tmp;
+ }
+
+
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ } while (FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Switch to ch %d, Wait BEACON from %02x:%02x:%02x:%02x:%02x:%02x\n",
+ pBss->Channel, pBss->Bssid[0], pBss->Bssid[1], pBss->Bssid[2], pBss->Bssid[3], pBss->Bssid[4], pBss->Bssid[5]));
+
+ pAd->Mlme.SyncMachine.CurrState = JOIN_WAIT_BEACON;
+}
+
+/*
+ ==========================================================================
+ Description:
+ MLME START Request state machine procedure, starting an IBSS
+ ==========================================================================
+ */
+VOID MlmeStartReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen;
+ BOOLEAN TimerCancelled;
+
+ // New for WPA security suites
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ LARGE_INTEGER TimeStamp;
+ BOOLEAN Privacy;
+ USHORT Status;
+
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+ TimeStamp.u.LowPart = 0;
+ TimeStamp.u.HighPart = 0;
+
+ if (MlmeStartReqSanity(pAd, Elem->Msg, Elem->MsgLen, Ssid, &SsidLen))
+ {
+ // reset all the timers
+ RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &TimerCancelled);
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+ //
+ // Start a new IBSS. All IBSS parameters are decided now....
+ //
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - Start a new IBSS. All IBSS parameters are decided now.... \n"));
+ pAd->MlmeAux.BssType = BSS_ADHOC;
+ NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+ pAd->MlmeAux.SsidLen = SsidLen;
+
+ // generate a radom number as BSSID
+ MacAddrRandomBssid(pAd, pAd->MlmeAux.Bssid);
+ DBGPRINT(RT_DEBUG_TRACE, ("MlmeStartReqAction - generate a radom number as BSSID \n"));
+
+ Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+ pAd->MlmeAux.CapabilityInfo = CAP_GENERATE(0,1,Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 1, 0);
+ pAd->MlmeAux.BeaconPeriod = pAd->CommonCfg.BeaconPeriod;
+ pAd->MlmeAux.AtimWin = pAd->StaCfg.AtimWin;
+ pAd->MlmeAux.Channel = pAd->CommonCfg.Channel;
+
+ pAd->CommonCfg.CentralChannel = pAd->CommonCfg.Channel;
+ pAd->MlmeAux.CentralChannel = pAd->CommonCfg.CentralChannel;
+
+ pAd->MlmeAux.SupRateLen= pAd->CommonCfg.SupRateLen;
+ NdisMoveMemory(pAd->MlmeAux.SupRate, pAd->CommonCfg.SupRate, MAX_LEN_OF_SUPPORTED_RATES);
+ RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+ pAd->MlmeAux.ExtRateLen = pAd->CommonCfg.ExtRateLen;
+ NdisMoveMemory(pAd->MlmeAux.ExtRate, pAd->CommonCfg.ExtRate, MAX_LEN_OF_SUPPORTED_RATES);
+ RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ RTMPUpdateHTIE(&pAd->CommonCfg.DesiredHtPhy, &pAd->StaCfg.DesiredHtPhyInfo.MCSSet[0], &pAd->MlmeAux.HtCapability, &pAd->MlmeAux.AddHtInfo);
+ pAd->MlmeAux.HtCapabilityLen = sizeof(HT_CAPABILITY_IE);
+ // Not turn pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE here.
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC -pAd->StaActive.SupportedHtPhy.bHtEnable = TRUE\n"));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ pAd->MlmeAux.HtCapabilityLen = 0;
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+ }
+ // temporarily not support QOS in IBSS
+ NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+
+ AsicSwitchChannel(pAd, pAd->MlmeAux.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->MlmeAux.Channel);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - MlmeStartReqAction(ch= %d,sup rates= %d, ext rates=%d)\n",
+ pAd->MlmeAux.Channel, pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+ }
+ else
+ {
+ DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n"));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_INVALID_FORMAT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+ }
+}
+
+/*
+ ==========================================================================
+ Description:
+ peer sends beacon back when scanning
+ ==========================================================================
+ */
+VOID PeerBeaconAtScanAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+ UCHAR Ssid[MAX_LEN_OF_SSID], BssType, Channel, NewChannel,
+ SsidLen, DtimCount, DtimPeriod, BcastFlag, MessageToMe;
+ CF_PARM CfParm;
+ USHORT BeaconPeriod, AtimWin, CapabilityInfo;
+ PFRAME_802_11 pFrame;
+ LARGE_INTEGER TimeStamp;
+ UCHAR Erp;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen, ExtRateLen;
+ USHORT LenVIE;
+ UCHAR CkipFlag;
+ UCHAR AironetCellPowerLimit;
+ EDCA_PARM EdcaParm;
+ QBSS_LOAD_PARM QbssLoad;
+ QOS_CAPABILITY_PARM QosCapability;
+ ULONG RalinkIe;
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+
+ // NdisFillMemory(Ssid, MAX_LEN_OF_SSID, 0x00);
+ pFrame = (PFRAME_802_11) Elem->Msg;
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+#ifdef DOT11_N_SUPPORT
+ RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+ RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+#endif // DOT11_N_SUPPORT //
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ Addr2,
+ Bssid,
+ Ssid,
+ &SsidLen,
+ &BssType,
+ &BeaconPeriod,
+ &Channel,
+ &NewChannel,
+ &TimeStamp,
+ &CfParm,
+ &AtimWin,
+ &CapabilityInfo,
+ &Erp,
+ &DtimCount,
+ &DtimPeriod,
+ &BcastFlag,
+ &MessageToMe,
+ SupRate,
+ &SupRateLen,
+ ExtRate,
+ &ExtRateLen,
+ &CkipFlag,
+ &AironetCellPowerLimit,
+ &EdcaParm,
+ &QbssLoad,
+ &QosCapability,
+ &RalinkIe,
+ &HtCapabilityLen,
+ &PreNHtCapabilityLen,
+ &HtCapability,
+ &AddHtInfoLen,
+ &AddHtInfo,
+ &NewExtChannelOffset,
+ &LenVIE,
+ pVIE))
+ {
+ ULONG Idx;
+ CHAR Rssi = 0;
+
+ Idx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+ if (Idx != BSS_NOT_FOUND)
+ Rssi = pAd->ScanTab.BssEntry[Idx].Rssi;
+
+ Rssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+
+#ifdef DOT11_N_SUPPORT
+ if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
+ HtCapabilityLen = SIZE_HT_CAP_IE;
+#endif // DOT11_N_SUPPORT //
+ if ((pAd->StaCfg.CCXReqType != MSRN_TYPE_UNUSED) && (Channel == pAd->StaCfg.CCXScanChannel))
+ {
+ Idx = BssTableSetEntry(pAd, &pAd->StaCfg.CCXBssTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen,ExtRate, ExtRateLen, &HtCapability,
+ &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
+ &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+ if (Idx != BSS_NOT_FOUND)
+ {
+ NdisMoveMemory(pAd->StaCfg.CCXBssTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
+ NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pAd->StaCfg.CCXBssTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+ if (pAd->StaCfg.CCXReqType == MSRN_TYPE_BEACON_REQ)
+ AironetAddBeaconReport(pAd, Idx, Elem);
+ }
+ }
+ else
+ {
+ Idx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
+ &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, Rssi, TimeStamp, CkipFlag,
+ &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+ if (pAd->ChannelList[pAd->CommonCfg.ChannelListIdx].bEffectedChannel == TRUE)
+ {
+ UCHAR RegClass;
+ PeerBeaconAndProbeRspSanity2(pAd, Elem->Msg, Elem->MsgLen, &RegClass);
+ TriEventTableSetEntry(pAd, &pAd->CommonCfg.TriggerEventTab, Bssid, &HtCapability, HtCapabilityLen, RegClass, Channel);
+ }
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+ if (Idx != BSS_NOT_FOUND)
+ {
+ NdisMoveMemory(pAd->ScanTab.BssEntry[Idx].PTSF, &Elem->Msg[24], 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Idx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+ }
+ }
+ }
+ // sanity check fail, ignored
+}
+
+/*
+ ==========================================================================
+ Description:
+ When waiting joining the (I)BSS, beacon received from external
+ ==========================================================================
+ */
+VOID PeerBeaconAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+ UCHAR Ssid[MAX_LEN_OF_SSID], SsidLen, BssType, Channel, MessageToMe,
+ DtimCount, DtimPeriod, BcastFlag, NewChannel;
+ LARGE_INTEGER TimeStamp;
+ USHORT BeaconPeriod, AtimWin, CapabilityInfo;
+ CF_PARM Cf;
+ BOOLEAN TimerCancelled;
+ UCHAR Erp;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen, ExtRateLen;
+ UCHAR CkipFlag;
+ USHORT LenVIE;
+ UCHAR AironetCellPowerLimit;
+ EDCA_PARM EdcaParm;
+ QBSS_LOAD_PARM QbssLoad;
+ QOS_CAPABILITY_PARM QosCapability;
+ USHORT Status;
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ ULONG RalinkIe;
+ ULONG Idx;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen = 0, PreNHtCapabilityLen = 0;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+#ifdef DOT11_N_SUPPORT
+ UCHAR CentralChannel;
+#endif // DOT11_N_SUPPORT //
+
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+ RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+ RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ Addr2,
+ Bssid,
+ Ssid,
+ &SsidLen,
+ &BssType,
+ &BeaconPeriod,
+ &Channel,
+ &NewChannel,
+ &TimeStamp,
+ &Cf,
+ &AtimWin,
+ &CapabilityInfo,
+ &Erp,
+ &DtimCount,
+ &DtimPeriod,
+ &BcastFlag,
+ &MessageToMe,
+ SupRate,
+ &SupRateLen,
+ ExtRate,
+ &ExtRateLen,
+ &CkipFlag,
+ &AironetCellPowerLimit,
+ &EdcaParm,
+ &QbssLoad,
+ &QosCapability,
+ &RalinkIe,
+ &HtCapabilityLen,
+ &PreNHtCapabilityLen,
+ &HtCapability,
+ &AddHtInfoLen,
+ &AddHtInfo,
+ &NewExtChannelOffset,
+ &LenVIE,
+ pVIE))
+ {
+ // Disqualify 11b only adhoc when we are in 11g only adhoc mode
+ if ((BssType == BSS_ADHOC) && (pAd->CommonCfg.PhyMode == PHY_11G) && ((SupRateLen+ExtRateLen)< 12))
+ return;
+
+ // BEACON from desired BSS/IBSS found. We should be able to decide most
+ // BSS parameters here.
+ // Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
+ // Do we need to receover back all parameters belonging to previous BSS?
+ // A. Should be not. There's no back-door recover to previous AP. It still need
+ // a new JOIN-AUTH-ASSOC sequence.
+ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired BEACON at JoinWaitBeacon... Channel = %d\n", Channel));
+ RTMPCancelTimer(&pAd->MlmeAux.BeaconTimer, &TimerCancelled);
+
+ // Update RSSI to prevent No signal display when cards first initialized
+ pAd->StaCfg.RssiSample.LastRssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
+ pAd->StaCfg.RssiSample.LastRssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
+ pAd->StaCfg.RssiSample.LastRssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
+ pAd->StaCfg.RssiSample.AvgRssi0 = pAd->StaCfg.RssiSample.LastRssi0;
+ pAd->StaCfg.RssiSample.AvgRssi0X8 = pAd->StaCfg.RssiSample.AvgRssi0 << 3;
+ pAd->StaCfg.RssiSample.AvgRssi1 = pAd->StaCfg.RssiSample.LastRssi1;
+ pAd->StaCfg.RssiSample.AvgRssi1X8 = pAd->StaCfg.RssiSample.AvgRssi1 << 3;
+ pAd->StaCfg.RssiSample.AvgRssi2 = pAd->StaCfg.RssiSample.LastRssi2;
+ pAd->StaCfg.RssiSample.AvgRssi2X8 = pAd->StaCfg.RssiSample.AvgRssi2 << 3;
+
+ //
+ // We need to check if SSID only set to any, then we can record the current SSID.
+ // Otherwise will cause hidden SSID association failed.
+ //
+ if (pAd->MlmeAux.SsidLen == 0)
+ {
+ NdisMoveMemory(pAd->MlmeAux.Ssid, Ssid, SsidLen);
+ pAd->MlmeAux.SsidLen = SsidLen;
+ }
+ else
+ {
+ Idx = BssSsidTableSearch(&pAd->ScanTab, Bssid, pAd->MlmeAux.Ssid, pAd->MlmeAux.SsidLen, Channel);
+
+ if (Idx != BSS_NOT_FOUND)
+ {
+ //
+ // Multiple SSID case, used correct CapabilityInfo
+ //
+ CapabilityInfo = pAd->ScanTab.BssEntry[Idx].CapabilityInfo;
+ }
+ }
+ NdisMoveMemory(pAd->MlmeAux.Bssid, Bssid, MAC_ADDR_LEN);
+ pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
+ pAd->MlmeAux.BssType = BssType;
+ pAd->MlmeAux.BeaconPeriod = BeaconPeriod;
+ pAd->MlmeAux.Channel = Channel;
+ pAd->MlmeAux.AtimWin = AtimWin;
+ pAd->MlmeAux.CfpPeriod = Cf.CfpPeriod;
+ pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration;
+ pAd->MlmeAux.APRalinkIe = RalinkIe;
+
+ // Copy AP's supported rate to MlmeAux for creating assoication request
+ // Also filter out not supported rate
+ pAd->MlmeAux.SupRateLen = SupRateLen;
+ NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, SupRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.SupRate, &pAd->MlmeAux.SupRateLen);
+ pAd->MlmeAux.ExtRateLen = ExtRateLen;
+ NdisMoveMemory(pAd->MlmeAux.ExtRate, ExtRate, ExtRateLen);
+ RTMPCheckRates(pAd, pAd->MlmeAux.ExtRate, &pAd->MlmeAux.ExtRateLen);
+
+ NdisZeroMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, 16);
+#ifdef DOT11_N_SUPPORT
+ pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+ pAd->MlmeAux.HtCapabilityLen = HtCapabilityLen;
+
+ // filter out un-supported ht rates
+ if (((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0)) && (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED))
+ {
+ RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ RTMPMoveMemory(&pAd->MlmeAux.AddHtInfo, &AddHtInfo, SIZE_ADD_HT_INFO_IE);
+
+ // StaActive.SupportedHtPhy.MCSSet stores Peer AP's 11n Rx capability
+ NdisMoveMemory(pAd->StaActive.SupportedPhyInfo.MCSSet, HtCapability.MCSSet, 16);
+ pAd->MlmeAux.NewExtChannelOffset = NewExtChannelOffset;
+ pAd->MlmeAux.HtCapabilityLen = SIZE_HT_CAP_IE;
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = TRUE;
+ if (PreNHtCapabilityLen > 0)
+ pAd->StaActive.SupportedPhyInfo.bPreNHt = TRUE;
+ RTMPCheckHt(pAd, BSSID_WCID, &HtCapability, &AddHtInfo);
+ // Copy AP Parameter to StaActive. This is also in LinkUp.
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction! (MpduDensity=%d, MaxRAmpduFactor=%d, BW=%d)\n",
+ pAd->StaActive.SupportedHtPhy.MpduDensity, pAd->StaActive.SupportedHtPhy.MaxRAmpduFactor, HtCapability.HtCapInfo.ChannelWidth));
+
+ if (AddHtInfoLen > 0)
+ {
+ CentralChannel = AddHtInfo.ControlChan;
+ // Check again the Bandwidth capability of this AP.
+ if ((AddHtInfo.ControlChan > 2)&& (AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_BELOW) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ CentralChannel = AddHtInfo.ControlChan - 2;
+ }
+ else if ((AddHtInfo.AddHtInfo.ExtChanOffset == EXTCHA_ABOVE) && (HtCapability.HtCapInfo.ChannelWidth == BW_40))
+ {
+ CentralChannel = AddHtInfo.ControlChan + 2;
+ }
+
+ // Check Error .
+ if (pAd->MlmeAux.CentralChannel != CentralChannel)
+ DBGPRINT(RT_DEBUG_ERROR, ("PeerBeaconAtJoinAction HT===>Beacon Central Channel = %d, Control Channel = %d. Mlmeaux CentralChannel = %d\n", CentralChannel, AddHtInfo.ControlChan, pAd->MlmeAux.CentralChannel));
+
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d, .\n", CentralChannel, AddHtInfo.ControlChan));
+
+ }
+
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ // To prevent error, let legacy AP must have same CentralChannel and Channel.
+ if ((HtCapabilityLen == 0) && (PreNHtCapabilityLen == 0))
+ pAd->MlmeAux.CentralChannel = pAd->MlmeAux.Channel;
+
+ pAd->StaActive.SupportedPhyInfo.bHtEnable = FALSE;
+ RTMPZeroMemory(&pAd->MlmeAux.HtCapability, SIZE_HT_CAP_IE);
+ RTMPZeroMemory(&pAd->MlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
+ }
+
+ RTMPUpdateMlmeRate(pAd);
+
+ // copy QOS related information
+ if ((pAd->CommonCfg.bWmmCapable)
+#ifdef DOT11_N_SUPPORT
+ || (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+#endif // DOT11_N_SUPPORT //
+ )
+ {
+ NdisMoveMemory(&pAd->MlmeAux.APEdcaParm, &EdcaParm, sizeof(EDCA_PARM));
+ NdisMoveMemory(&pAd->MlmeAux.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisMoveMemory(&pAd->MlmeAux.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+ else
+ {
+ NdisZeroMemory(&pAd->MlmeAux.APEdcaParm, sizeof(EDCA_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisZeroMemory(&pAd->MlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n",
+ pAd->MlmeAux.SupRateLen, pAd->MlmeAux.ExtRateLen));
+
+#ifdef LEAP_SUPPORT
+ // Update CkipFlag
+ pAd->StaCfg.CkipFlag = CkipFlag;
+
+ // Keep TimeStamp for Re-Association used.
+ if (LEAP_CCKM_ON(pAd) && (pAd->StaCfg.CCKMLinkUpFlag == TRUE))
+ pAd->StaCfg.CCKMBeaconAtJoinTimeStamp = TimeStamp;
+#endif // LEAP_SUPPORT //
+
+ if (AironetCellPowerLimit != 0xFF)
+ {
+ //We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power
+ ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
+ }
+ else //Used the default TX Power Percentage.
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_SUCCESS;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+ }
+ // not to me BEACON, ignored
+ }
+ // sanity check fail, ignore this frame
+}
+
+/*
+ ==========================================================================
+ Description:
+ receive BEACON from peer
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID PeerBeacon(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Bssid[MAC_ADDR_LEN], Addr2[MAC_ADDR_LEN];
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ CF_PARM CfParm;
+ UCHAR SsidLen, MessageToMe=0, BssType, Channel, NewChannel, index=0;
+ UCHAR DtimCount=0, DtimPeriod=0, BcastFlag=0;
+ USHORT CapabilityInfo, AtimWin, BeaconPeriod;
+ LARGE_INTEGER TimeStamp;
+ USHORT TbttNumToNextWakeUp;
+ UCHAR Erp;
+ UCHAR SupRate[MAX_LEN_OF_SUPPORTED_RATES], ExtRate[MAX_LEN_OF_SUPPORTED_RATES];
+ UCHAR SupRateLen, ExtRateLen;
+ UCHAR CkipFlag;
+ USHORT LenVIE;
+ UCHAR AironetCellPowerLimit;
+ EDCA_PARM EdcaParm;
+ QBSS_LOAD_PARM QbssLoad;
+ QOS_CAPABILITY_PARM QosCapability;
+ ULONG RalinkIe;
+ // New for WPA security suites
+ UCHAR VarIE[MAX_VIE_LEN]; // Total VIE length = MAX_VIE_LEN - -5
+ NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
+ HT_CAPABILITY_IE HtCapability;
+ ADD_HT_INFO_IE AddHtInfo; // AP might use this additional ht info IE
+ UCHAR HtCapabilityLen, PreNHtCapabilityLen;
+ UCHAR AddHtInfoLen;
+ UCHAR NewExtChannelOffset = 0xff;
+
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+ if (!(INFRA_ON(pAd) || ADHOC_ON(pAd)
+ ))
+ return;
+
+ // Init Variable IE structure
+ pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
+ pVIE->Length = 0;
+ RTMPZeroMemory(&HtCapability, sizeof(HtCapability));
+ RTMPZeroMemory(&AddHtInfo, sizeof(ADD_HT_INFO_IE));
+
+ if (PeerBeaconAndProbeRspSanity(pAd,
+ Elem->Msg,
+ Elem->MsgLen,
+ Elem->Channel,
+ Addr2,
+ Bssid,
+ Ssid,
+ &SsidLen,
+ &BssType,
+ &BeaconPeriod,
+ &Channel,
+ &NewChannel,
+ &TimeStamp,
+ &CfParm,
+ &AtimWin,
+ &CapabilityInfo,
+ &Erp,
+ &DtimCount,
+ &DtimPeriod,
+ &BcastFlag,
+ &MessageToMe,
+ SupRate,
+ &SupRateLen,
+ ExtRate,
+ &ExtRateLen,
+ &CkipFlag,
+ &AironetCellPowerLimit,
+ &EdcaParm,
+ &QbssLoad,
+ &QosCapability,
+ &RalinkIe,
+ &HtCapabilityLen,
+ &PreNHtCapabilityLen,
+ &HtCapability,
+ &AddHtInfoLen,
+ &AddHtInfo,
+ &NewExtChannelOffset,
+ &LenVIE,
+ pVIE))
+ {
+ BOOLEAN is_my_bssid, is_my_ssid;
+ ULONG Bssidx, Now;
+ BSS_ENTRY *pBss;
+ CHAR RealRssi = RTMPMaxRssi(pAd, ConvertToRssi(pAd, Elem->Rssi0, RSSI_0), ConvertToRssi(pAd, Elem->Rssi1, RSSI_1), ConvertToRssi(pAd, Elem->Rssi2, RSSI_2));
+
+ is_my_bssid = MAC_ADDR_EQUAL(Bssid, pAd->CommonCfg.Bssid)? TRUE : FALSE;
+ is_my_ssid = SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen)? TRUE:FALSE;
+
+
+ // ignore BEACON not for my SSID
+ if ((! is_my_ssid) && (! is_my_bssid))
+ return;
+
+ // It means STA waits disassoc completely from this AP, ignores this beacon.
+ if (pAd->Mlme.CntlMachine.CurrState == CNTL_WAIT_DISASSOC)
+ return;
+
+#ifdef DOT11_N_SUPPORT
+ // Copy Control channel for this BSSID.
+ if (AddHtInfoLen != 0)
+ Channel = AddHtInfo.ControlChan;
+
+ if ((HtCapabilityLen > 0) || (PreNHtCapabilityLen > 0))
+ HtCapabilityLen = SIZE_HT_CAP_IE;
+#endif // DOT11_N_SUPPORT //
+
+ //
+ // Housekeeping "SsidBssTab" table for later-on ROAMing usage.
+ //
+ Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+ if (Bssidx == BSS_NOT_FOUND)
+ {
+ // discover new AP of this network, create BSS entry
+ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen,
+ &HtCapability, &AddHtInfo,HtCapabilityLen,AddHtInfoLen,NewExtChannelOffset, Channel,
+ RealRssi, TimeStamp, CkipFlag, &EdcaParm, &QosCapability,
+ &QbssLoad, LenVIE, pVIE);
+ if (Bssidx == BSS_NOT_FOUND) // return if BSS table full
+ return;
+
+ NdisMoveMemory(pAd->ScanTab.BssEntry[Bssidx].PTSF, &Elem->Msg[24], 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[0], &Elem->TimeStamp.u.LowPart, 4);
+ NdisMoveMemory(&pAd->ScanTab.BssEntry[Bssidx].TTSF[4], &Elem->TimeStamp.u.LowPart, 4);
+
+
+
+ }
+
+ if ((pAd->CommonCfg.bIEEE80211H == 1) && (NewChannel != 0) && (Channel != NewChannel))
+ {
+ // Switching to channel 1 can prevent from rescanning the current channel immediately (by auto reconnection).
+ // In addition, clear the MLME queue and the scan table to discard the RX packets and previous scanning results.
+ AsicSwitchChannel(pAd, 1, FALSE);
+ AsicLockChannel(pAd, 1);
+ LinkDown(pAd, FALSE);
+ MlmeQueueInit(&pAd->Mlme.Queue);
+ BssTableInit(&pAd->ScanTab);
+ RTMPusecDelay(1000000); // use delay to prevent STA do reassoc
+
+ // channel sanity check
+ for (index = 0 ; index < pAd->ChannelListNum; index++)
+ {
+ if (pAd->ChannelList[index].Channel == NewChannel)
+ {
+ pAd->ScanTab.BssEntry[Bssidx].Channel = NewChannel;
+ pAd->CommonCfg.Channel = NewChannel;
+ AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAd, pAd->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("PeerBeacon - STA receive channel switch announcement IE (New Channel =%d)\n", NewChannel));
+ break;
+ }
+ }
+
+ if (index >= pAd->ChannelListNum)
+ {
+ DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum));
+ }
+ }
+
+ // if the ssid matched & bssid unmatched, we should select the bssid with large value.
+ // This might happened when two STA start at the same time
+ if ((! is_my_bssid) && ADHOC_ON(pAd))
+ {
+ INT i;
+
+ // Add the safeguard against the mismatch of adhoc wep status
+ if (pAd->StaCfg.WepStatus != pAd->ScanTab.BssEntry[Bssidx].WepStatus)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - Not matched wep status %d %d\n", pAd->StaCfg.WepStatus, pAd->ScanTab.BssEntry[Bssidx].WepStatus));
+ DBGPRINT(RT_DEBUG_TRACE, ("bssid=%s\n", pAd->ScanTab.BssEntry[Bssidx].Bssid));
+ return;
+ }
+
+ // collapse into the ADHOC network which has bigger BSSID value.
+ for (i = 0; i < 6; i++)
+ {
+ if (Bssid[i] > pAd->CommonCfg.Bssid[i])
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - merge to the IBSS with bigger BSSID=%02x:%02x:%02x:%02x:%02x:%02x\n",
+ Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+ AsicDisableSync(pAd);
+ COPY_MAC_ADDR(pAd->CommonCfg.Bssid, Bssid);
+ AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+ MakeIbssBeacon(pAd); // re-build BEACON frame
+ AsicEnableIbssSync(pAd); // copy BEACON frame to on-chip memory
+ is_my_bssid = TRUE;
+ break;
+ }
+ else if (Bssid[i] < pAd->CommonCfg.Bssid[i])
+ break;
+ }
+ }
+
+
+ NdisGetSystemUpTime(&Now);
+ pBss = &pAd->ScanTab.BssEntry[Bssidx];
+ pBss->Rssi = RealRssi; // lastest RSSI
+ pBss->LastBeaconRxTime = Now; // last RX timestamp
+
+ //
+ // BEACON from my BSSID - either IBSS or INFRA network
+ //
+ if (is_my_bssid)
+ {
+ RXWI_STRUC RxWI;
+
+ pAd->StaCfg.DtimCount = DtimCount;
+ pAd->StaCfg.DtimPeriod = DtimPeriod;
+ pAd->StaCfg.LastBeaconRxTime = Now;
+
+
+ RxWI.RSSI0 = Elem->Rssi0;
+ RxWI.RSSI1 = Elem->Rssi1;
+ RxWI.RSSI2 = Elem->Rssi2;
+
+ Update_Rssi_Sample(pAd, &pAd->StaCfg.RssiSample, &RxWI);
+ if (AironetCellPowerLimit != 0xFF)
+ {
+ //
+ // We get the Cisco (ccx) "TxPower Limit" required
+ // Changed to appropriate TxPower Limit for Ciso Compatible Extensions
+ //
+ ChangeToCellPowerLimit(pAd, AironetCellPowerLimit);
+ }
+ else
+ {
+ //
+ // AironetCellPowerLimit equal to 0xFF means the Cisco (ccx) "TxPower Limit" not exist.
+ // Used the default TX Power Percentage, that set from UI.
+ //
+ pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;
+ }
+
+ if (ADHOC_ON(pAd) && (CAP_IS_IBSS_ON(CapabilityInfo)))
+ {
+ UCHAR MaxSupportedRateIn500Kbps = 0;
+ UCHAR idx;
+ MAC_TABLE_ENTRY *pEntry;
+
+ // supported rates array may not be sorted. sort it and find the maximum rate
+ for (idx=0; idx<SupRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (SupRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = SupRate[idx] & 0x7f;
+ }
+
+ for (idx=0; idx<ExtRateLen; idx++)
+ {
+ if (MaxSupportedRateIn500Kbps < (ExtRate[idx] & 0x7f))
+ MaxSupportedRateIn500Kbps = ExtRate[idx] & 0x7f;
+ }
+
+ // look up the existing table
+ pEntry = MacTableLookup(pAd, Addr2);
+
+ // Ad-hoc mode is using MAC address as BA session. So we need to continuously find newly joined adhoc station by receiving beacon.
+ // To prevent always check this, we use wcid == RESERVED_WCID to recognize it as newly joined adhoc station.
+ if ((ADHOC_ON(pAd) && (Elem->Wcid == RESERVED_WCID)) ||
+ (pEntry && ((pEntry->LastBeaconRxTime + ADHOC_ENTRY_BEACON_LOST_TIME) < Now)))
+ {
+ if (pEntry == NULL)
+ // Another adhoc joining, add to our MAC table.
+ pEntry = MacTableInsertEntry(pAd, Addr2, BSS0, FALSE);
+
+ if (StaAddMacTableEntry(pAd, pEntry, MaxSupportedRateIn500Kbps, &HtCapability, HtCapabilityLen, CapabilityInfo) == FALSE)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("ADHOC - Add Entry failed.\n"));
+ return;
+ }
+
+ if (pEntry &&
+ (Elem->Wcid == RESERVED_WCID))
+ {
+ idx = pAd->StaCfg.DefaultKeyId;
+ RT28XX_STA_SECURITY_INFO_ADD(pAd, BSS0, idx, pEntry);
+ }
+ }
+
+ if (pEntry && pEntry->ValidAsCLI)
+ pEntry->LastBeaconRxTime = Now;
+
+ // At least another peer in this IBSS, declare MediaState as CONNECTED
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED);
+
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ RTMP_IndicateMediaState(pAd);
+ pAd->ExtraInfo = GENERAL_LINK_UP;
+ AsicSetBssid(pAd, pAd->CommonCfg.Bssid);
+
+ // 2003/03/12 - john
+ // Make sure this entry in "ScanTab" table, thus complies to Microsoft's policy that
+ // "site survey" result should always include the current connected network.
+ //
+ Bssidx = BssTableSearch(&pAd->ScanTab, Bssid, Channel);
+ if (Bssidx == BSS_NOT_FOUND)
+ {
+ Bssidx = BssTableSetEntry(pAd, &pAd->ScanTab, Bssid, Ssid, SsidLen, BssType, BeaconPeriod,
+ &CfParm, AtimWin, CapabilityInfo, SupRate, SupRateLen, ExtRate, ExtRateLen, &HtCapability,
+ &AddHtInfo, HtCapabilityLen, AddHtInfoLen, NewExtChannelOffset, Channel, RealRssi, TimeStamp, 0,
+ &EdcaParm, &QosCapability, &QbssLoad, LenVIE, pVIE);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("ADHOC fOP_STATUS_MEDIA_STATE_CONNECTED.\n"));
+ }
+ }
+
+ if (INFRA_ON(pAd))
+ {
+ BOOLEAN bUseShortSlot, bUseBGProtection;
+
+ // decide to use/change to -
+ // 1. long slot (20 us) or short slot (9 us) time
+ // 2. turn on/off RTS/CTS and/or CTS-to-self protection
+ // 3. short preamble
+
+ //bUseShortSlot = pAd->CommonCfg.bUseShortSlotTime && CAP_IS_SHORT_SLOT(CapabilityInfo);
+ bUseShortSlot = CAP_IS_SHORT_SLOT(CapabilityInfo);
+ if (bUseShortSlot != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_SLOT_INUSED))
+ AsicSetSlotTime(pAd, bUseShortSlot);
+
+ bUseBGProtection = (pAd->CommonCfg.UseBGProtection == 1) || // always use
+ ((pAd->CommonCfg.UseBGProtection == 0) && ERP_IS_USE_PROTECTION(Erp));
+
+ if (pAd->CommonCfg.Channel > 14) // always no BG protection in A-band. falsely happened when switching A/G band to a dual-band AP
+ bUseBGProtection = FALSE;
+
+ if (bUseBGProtection != OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED))
+ {
+ if (bUseBGProtection)
+ {
+ OPSTATUS_SET_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),FALSE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
+ }
+ else
+ {
+ OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_BG_PROTECTION_INUSED);
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, (OFDMSETPROTECT|CCKSETPROTECT|ALLN_SETPROTECT),TRUE,(pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1));
+ }
+
+ DBGPRINT(RT_DEBUG_WARN, ("SYNC - AP changed B/G protection to %d\n", bUseBGProtection));
+ }
+
+#ifdef DOT11_N_SUPPORT
+ // check Ht protection mode. and adhere to the Non-GF device indication by AP.
+ if ((AddHtInfoLen != 0) &&
+ ((AddHtInfo.AddHtInfo2.OperaionMode != pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode) ||
+ (AddHtInfo.AddHtInfo2.NonGfPresent != pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent)))
+ {
+ pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent = AddHtInfo.AddHtInfo2.NonGfPresent;
+ pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode = AddHtInfo.AddHtInfo2.OperaionMode;
+ if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1)
+ {
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, TRUE);
+ }
+ else
+ AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode, ALLN_SETPROTECT, FALSE, FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP changed N OperaionMode to %d\n", pAd->MlmeAux.AddHtInfo.AddHtInfo2.OperaionMode));
+ }
+#endif // DOT11_N_SUPPORT //
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_SHORT_PREAMBLE_INUSED) &&
+ ERP_IS_USE_BARKER_PREAMBLE(Erp))
+ {
+ MlmeSetTxPreamble(pAd, Rt802_11PreambleLong);
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP forced to use LONG preamble\n"));
+ }
+
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_WMM_INUSED) &&
+ (EdcaParm.bValid == TRUE) &&
+ (EdcaParm.EdcaUpdateCount != pAd->CommonCfg.APEdcaParm.EdcaUpdateCount))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - AP change EDCA parameters(from %d to %d)\n",
+ pAd->CommonCfg.APEdcaParm.EdcaUpdateCount,
+ EdcaParm.EdcaUpdateCount));
+ AsicSetEdcaParm(pAd, &EdcaParm);
+ }
+
+ // copy QOS related information
+ NdisMoveMemory(&pAd->CommonCfg.APQbssLoad, &QbssLoad, sizeof(QBSS_LOAD_PARM));
+ NdisMoveMemory(&pAd->CommonCfg.APQosCapability, &QosCapability, sizeof(QOS_CAPABILITY_PARM));
+ }
+
+ // only INFRASTRUCTURE mode support power-saving feature
+ if ((INFRA_ON(pAd) && (pAd->StaCfg.Psm == PWR_SAVE)) || (pAd->CommonCfg.bAPSDForcePowerSave))
+ {
+ UCHAR FreeNumber;
+ // 1. AP has backlogged unicast-to-me frame, stay AWAKE, send PSPOLL
+ // 2. AP has backlogged broadcast/multicast frame and we want those frames, stay AWAKE
+ // 3. we have outgoing frames in TxRing or MgmtRing, better stay AWAKE
+ // 4. Psm change to PWR_SAVE, but AP not been informed yet, we better stay AWAKE
+ // 5. otherwise, put PHY back to sleep to save battery.
+ if (MessageToMe)
+ {
+ if (pAd->CommonCfg.bAPSDCapable && pAd->CommonCfg.APEdcaParm.bAPSDCapable &&
+ pAd->CommonCfg.bAPSDAC_BE && pAd->CommonCfg.bAPSDAC_BK && pAd->CommonCfg.bAPSDAC_VI && pAd->CommonCfg.bAPSDAC_VO)
+ {
+ pAd->CommonCfg.bNeedSendTriggerFrame = TRUE;
+ }
+ else
+ RT28XX_PS_POLL_ENQUEUE(pAd);
+ }
+ else if (BcastFlag && (DtimCount == 0) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM))
+ {
+ }
+ else if ((pAd->TxSwQueue[QID_AC_BK].Number != 0) ||
+ (pAd->TxSwQueue[QID_AC_BE].Number != 0) ||
+ (pAd->TxSwQueue[QID_AC_VI].Number != 0) ||
+ (pAd->TxSwQueue[QID_AC_VO].Number != 0) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_BK, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_BE, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_VI, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_AC_VO, TX_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS) ||
+ (RTMPFreeTXDRequest(pAd, QID_MGMT, MGMT_RING_SIZE - 1, &FreeNumber) != NDIS_STATUS_SUCCESS))
+ {
+ // TODO: consider scheduled HCCA. might not be proper to use traditional DTIM-based power-saving scheme
+ // can we cheat here (i.e. just check MGMT & AC_BE) for better performance?
+ }
+ else
+ {
+ USHORT NextDtim = DtimCount;
+
+ if (NextDtim == 0)
+ NextDtim = DtimPeriod;
+
+ TbttNumToNextWakeUp = pAd->StaCfg.DefaultListenCount;
+ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_RECEIVE_DTIM) && (TbttNumToNextWakeUp > NextDtim))
+ TbttNumToNextWakeUp = NextDtim;
+
+ if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE))
+ {
+ AsicSleepThenAutoWakeup(pAd, TbttNumToNextWakeUp);
+ }
+ }
+ }
+ }
+ // not my BSSID, ignore it
+ }
+ // sanity check fail, ignore this frame
+}
+
+/*
+ ==========================================================================
+ Description:
+ Receive PROBE REQ from remote peer when operating in IBSS mode
+ ==========================================================================
+ */
+VOID PeerProbeReqAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ UCHAR Addr2[MAC_ADDR_LEN];
+ CHAR Ssid[MAX_LEN_OF_SSID];
+ UCHAR SsidLen;
+#ifdef DOT11_N_SUPPORT
+ UCHAR HtLen, AddHtLen, NewExtLen;
+#endif // DOT11_N_SUPPORT //
+ HEADER_802_11 ProbeRspHdr;
+ NDIS_STATUS NStatus;
+ PUCHAR pOutBuffer = NULL;
+ ULONG FrameLen = 0;
+ LARGE_INTEGER FakeTimestamp;
+ UCHAR DsLen = 1, IbssLen = 2;
+ UCHAR LocalErpIe[3] = {IE_ERP, 1, 0};
+ BOOLEAN Privacy;
+ USHORT CapabilityInfo;
+ UCHAR RSNIe = IE_WPA;
+
+ if (! ADHOC_ON(pAd))
+ return;
+
+ if (PeerProbeReqSanity(pAd, Elem->Msg, Elem->MsgLen, Addr2, Ssid, &SsidLen))
+ {
+ if ((SsidLen == 0) || SSID_EQUAL(Ssid, SsidLen, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen))
+ {
+ // allocate and send out ProbeRsp frame
+ NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NStatus != NDIS_STATUS_SUCCESS)
+ return;
+
+ //pAd->StaCfg.AtimWin = 0; // ??????
+
+ Privacy = (pAd->StaCfg.WepStatus == Ndis802_11Encryption1Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled);
+ CapabilityInfo = CAP_GENERATE(0, 1, Privacy, (pAd->CommonCfg.TxPreamble == Rt802_11PreambleShort), 0, 0);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &ProbeRspHdr,
+ TIMESTAMP_LEN, &FakeTimestamp,
+ 2, &pAd->CommonCfg.BeaconPeriod,
+ 2, &CapabilityInfo,
+ 1, &SsidIe,
+ 1, &pAd->CommonCfg.SsidLen,
+ pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->StaActive.SupRateLen,
+ pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
+ 1, &DsIe,
+ 1, &DsLen,
+ 1, &pAd->CommonCfg.Channel,
+ 1, &IbssIe,
+ 1, &IbssLen,
+ 2, &pAd->StaActive.AtimWin,
+ END_OF_ARGS);
+
+ if (pAd->StaActive.ExtRateLen)
+ {
+ ULONG tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 3, LocalErpIe,
+ 1, &ExtRateIe,
+ 1, &pAd->StaActive.ExtRateLen,
+ pAd->StaActive.ExtRateLen, &pAd->StaActive.ExtRate,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+
+ // If adhoc secruity is set for WPA-None, append the cipher suite IE
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ ULONG tmp;
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &tmp,
+ 1, &RSNIe,
+ 1, &pAd->StaCfg.RSNIE_Len,
+ pAd->StaCfg.RSNIE_Len, pAd->StaCfg.RSN_IE,
+ END_OF_ARGS);
+ FrameLen += tmp;
+ }
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ {
+ ULONG TmpLen;
+ UCHAR BROADCOM[4] = {0x0, 0x90, 0x4c, 0x33};
+ HtLen = sizeof(pAd->CommonCfg.HtCapability);
+ AddHtLen = sizeof(pAd->CommonCfg.AddHTInfo);
+ NewExtLen = 1;
+ //New extension channel offset IE is included in Beacon, Probe Rsp or channel Switch Announcement Frame
+ if (pAd->bBroadComHT == TRUE)
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &WpaIe,
+ 4, &BROADCOM[0],
+ pAd->MlmeAux.HtCapabilityLen, &pAd->MlmeAux.HtCapability,
+ END_OF_ARGS);
+ }
+ else
+ {
+ MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen,
+ 1, &HtCapIe,
+ 1, &HtLen,
+ sizeof(HT_CAPABILITY_IE), &pAd->CommonCfg.HtCapability,
+ 1, &AddHtInfoIe,
+ 1, &AddHtLen,
+ sizeof(ADD_HT_INFO_IE), &pAd->CommonCfg.AddHTInfo,
+ 1, &NewExtChanIe,
+ 1, &NewExtLen,
+ sizeof(NEW_EXT_CHAN_IE), &pAd->CommonCfg.NewExtChanOffset,
+ END_OF_ARGS);
+ }
+ FrameLen += TmpLen;
+ }
+#endif // DOT11_N_SUPPORT //
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+ }
+}
+
+VOID BeaconTimeoutAtJoinAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BeaconTimeoutAtJoinAction\n"));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_REJ_TIMEOUT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ Scan timeout procedure. basically add channel index by 1 and rescan
+ ==========================================================================
+ */
+VOID ScanTimeoutAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ pAd->MlmeAux.Channel = NextChannel(pAd, pAd->MlmeAux.Channel);
+
+ // Only one channel scanned for CISCO beacon request
+ if ((pAd->MlmeAux.ScanType == SCAN_CISCO_ACTIVE) ||
+ (pAd->MlmeAux.ScanType == SCAN_CISCO_PASSIVE) ||
+ (pAd->MlmeAux.ScanType == SCAN_CISCO_NOISE) ||
+ (pAd->MlmeAux.ScanType == SCAN_CISCO_CHANNEL_LOAD))
+ pAd->MlmeAux.Channel = 0;
+
+ // this routine will stop if pAd->MlmeAux.Channel == 0
+ ScanNextChannel(pAd);
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID InvalidStateWhenScan(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("AYNC - InvalidStateWhenScan(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID InvalidStateWhenJoin(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenJoin(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_JOIN_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID InvalidStateWhenStart(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ USHORT Status;
+ DBGPRINT(RT_DEBUG_TRACE, ("InvalidStateWhenStart(state=%ld). Reset SYNC machine\n", pAd->Mlme.SyncMachine.CurrState));
+ pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE;
+ Status = MLME_STATE_MACHINE_REJECT;
+ MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status);
+}
+
+/*
+ ==========================================================================
+ Description:
+
+ IRQL = DISPATCH_LEVEL
+
+ ==========================================================================
+ */
+VOID EnqueuePsPoll(
+ IN PRTMP_ADAPTER pAd)
+{
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ return;
+ }
+#endif // RALINK_ATE //
+
+
+ if (pAd->StaCfg.WindowsPowerMode == Ndis802_11PowerModeLegacy_PSP)
+ pAd->PsPollFrame.FC.PwrMgmt = PWR_SAVE;
+ MiniportMMRequest(pAd, 0, (PUCHAR)&pAd->PsPollFrame, sizeof(PSPOLL_FRAME));
+}
+
+
+/*
+ ==========================================================================
+ Description:
+ ==========================================================================
+ */
+VOID EnqueueProbeRequest(
+ IN PRTMP_ADAPTER pAd)
+{
+ NDIS_STATUS NState;
+ PUCHAR pOutBuffer;
+ ULONG FrameLen = 0;
+ HEADER_802_11 Hdr80211;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("force out a ProbeRequest ...\n"));
+
+ NState = MlmeAllocateMemory(pAd, &pOutBuffer); //Get an unused nonpaged memory
+ if (NState == NDIS_STATUS_SUCCESS)
+ {
+ MgtMacHeaderInit(pAd, &Hdr80211, SUBTYPE_PROBE_REQ, 0, BROADCAST_ADDR, BROADCAST_ADDR);
+
+ // this ProbeRequest explicitly specify SSID to reduce unwanted ProbeResponse
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ sizeof(HEADER_802_11), &Hdr80211,
+ 1, &SsidIe,
+ 1, &pAd->CommonCfg.SsidLen,
+ pAd->CommonCfg.SsidLen, pAd->CommonCfg.Ssid,
+ 1, &SupRateIe,
+ 1, &pAd->StaActive.SupRateLen,
+ pAd->StaActive.SupRateLen, pAd->StaActive.SupRate,
+ END_OF_ARGS);
+ MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen);
+ MlmeFreeMemory(pAd, pOutBuffer);
+ }
+
+}
+
+#ifdef DOT11_N_SUPPORT
+#ifdef DOT11N_DRAFT3
+VOID BuildEffectedChannelList(
+ IN PRTMP_ADAPTER pAd)
+{
+ UCHAR EChannel[11];
+ UCHAR i, j, k;
+ UCHAR UpperChannel = 0, LowerChannel = 0;
+
+ RTMPZeroMemory(EChannel, 11);
+ i = 0;
+ // Find upper channel and lower channel.
+ if (pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel)
+ {
+ UpperChannel = pAd->CommonCfg.Channel;
+ LowerChannel = pAd->CommonCfg.CentralChannel;
+ }
+ else if (pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel)
+ {
+ UpperChannel = pAd->CommonCfg.CentralChannel;
+ LowerChannel = pAd->CommonCfg.Channel;
+ }
+ else
+ {
+ return;
+ }
+
+ // Record channels that is below lower channel..
+ if (LowerChannel > 1)
+ {
+ EChannel[0] = LowerChannel - 1;
+ i = 1;
+ if (LowerChannel > 2)
+ {
+ EChannel[1] = LowerChannel - 2;
+ i = 2;
+ if (LowerChannel > 3)
+ {
+ EChannel[2] = LowerChannel - 3;
+ i = 3;
+ }
+ }
+ }
+ // Record channels that is between lower channel and upper channel.
+ for (k = LowerChannel;k < UpperChannel;k++)
+ {
+ EChannel[i] = k;
+ i++;
+ }
+ // Record channels that is above upper channel..
+ if (LowerChannel < 11)
+ {
+ EChannel[i] = UpperChannel + 1;
+ i++;
+ if (LowerChannel < 10)
+ {
+ EChannel[i] = LowerChannel + 2;
+ i++;
+ if (LowerChannel < 9)
+ {
+ EChannel[i] = LowerChannel + 3;
+ i++;
+ }
+ }
+ }
+ //
+ for (j = 0;j < i;j++)
+ {
+ for (k = 0;k < pAd->ChannelListNum;k++)
+ {
+ if (pAd->ChannelList[k].Channel == EChannel[j])
+ {
+ pAd->ChannelList[k].bEffectedChannel = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE,(" EffectedChannel( =%d)\n", EChannel[j]));
+ break;
+ }
+ }
+ }
+}
+#endif // DOT11N_DRAFT3 //
+#endif // DOT11_N_SUPPORT //
+
+BOOLEAN ScanRunning(
+ IN PRTMP_ADAPTER pAd)
+{
+ return (pAd->Mlme.SyncMachine.CurrState == SCAN_LISTEN) ? TRUE : FALSE;
+}
+
diff --git a/drivers/staging/rt3070/sta/wpa.c b/drivers/staging/rt3070/sta/wpa.c
new file mode 100644
index 00000000000..63d08306bf6
--- /dev/null
+++ b/drivers/staging/rt3070/sta/wpa.c
@@ -0,0 +1,2099 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ wpa.c
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Jan Lee 03-07-22 Initial
+ Paul Lin 03-11-28 Modify for supplicant
+*/
+#include "../rt_config.h"
+
+#define WPARSNIE 0xdd
+#define WPA2RSNIE 0x30
+
+//extern UCHAR BIT8[];
+UCHAR CipherWpaPskTkip[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x02 // authentication
+ };
+UCHAR CipherWpaPskTkipLen = (sizeof(CipherWpaPskTkip) / sizeof(UCHAR));
+
+UCHAR CipherWpaPskAes[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x04, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x04, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x02 // authentication
+ };
+UCHAR CipherWpaPskAesLen = (sizeof(CipherWpaPskAes) / sizeof(UCHAR));
+
+UCHAR CipherSuiteCiscoCCKM[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x40, 0x96, 0x01, // Multicast
+ 0x01, 0x00, // Number of uicast
+ 0x00, 0x40, 0x96, 0x01, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x40, 0x96, 0x00 // Authentication
+ };
+UCHAR CipherSuiteCiscoCCKMLen = (sizeof(CipherSuiteCiscoCCKM) / sizeof(UCHAR));
+
+UCHAR CipherSuiteCiscoCCKM24[] = {
+ 0xDD, 0x18, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x40, 0x96, 0x01, // Multicast
+ 0x01, 0x00, // Number of uicast
+ 0x00, 0x40, 0x96, 0x01, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x40, 0x96, 0x00,
+ 0x28, 0x00// Authentication
+ };
+
+UCHAR CipherSuiteCiscoCCKM24Len = (sizeof(CipherSuiteCiscoCCKM24) / sizeof(UCHAR));
+
+UCHAR CipherSuiteCCXTkip[] = {
+ 0xDD, 0x16, // RSN IE
+ 0x00, 0x50, 0xf2, 0x01, // oui
+ 0x01, 0x00, // Version
+ 0x00, 0x50, 0xf2, 0x02, // Multicast
+ 0x01, 0x00, // Number of unicast
+ 0x00, 0x50, 0xf2, 0x02, // unicast
+ 0x01, 0x00, // number of authentication method
+ 0x00, 0x50, 0xf2, 0x01 // authentication
+ };
+UCHAR CipherSuiteCCXTkipLen = (sizeof(CipherSuiteCCXTkip) / sizeof(UCHAR));
+
+UCHAR CCX_LLC_HDR[] = {0xAA, 0xAA, 0x03, 0x00, 0x40, 0x96, 0x00, 0x02};
+UCHAR LLC_NORMAL[] = {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00};
+
+UCHAR EAPOL_FRAME[] = {0x88, 0x8E};
+
+BOOLEAN CheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ OUT UCHAR *Offset);
+
+void inc_byte_array(UCHAR *counter, int len);
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Classify WPA EAP message type
+
+ Arguments:
+ EAPType Value of EAP message type
+ MsgType Internal Message definition for MLME state machine
+
+ Return Value:
+ TRUE Found appropriate message type
+ FALSE No appropriate message type
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+ All these constants are defined in wpa.h
+ For supplicant, there is only EAPOL Key message avaliable
+
+ ========================================================================
+*/
+BOOLEAN WpaMsgTypeSubst(
+ IN UCHAR EAPType,
+ OUT INT *MsgType)
+{
+ switch (EAPType)
+ {
+ case EAPPacket:
+ *MsgType = MT2_EAPPacket;
+ break;
+ case EAPOLStart:
+ *MsgType = MT2_EAPOLStart;
+ break;
+ case EAPOLLogoff:
+ *MsgType = MT2_EAPOLLogoff;
+ break;
+ case EAPOLKey:
+ *MsgType = MT2_EAPOLKey;
+ break;
+ case EAPOLASFAlert:
+ *MsgType = MT2_EAPOLASFAlert;
+ break;
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ association state machine init, including state transition and timer init
+ Parameters:
+ S - pointer to the association state machine
+ ==========================================================================
+ */
+VOID WpaPskStateMachineInit(
+ IN PRTMP_ADAPTER pAd,
+ IN STATE_MACHINE *S,
+ OUT STATE_MACHINE_FUNC Trans[])
+{
+ StateMachineInit(S, Trans, MAX_WPA_PSK_STATE, MAX_WPA_PSK_MSG, (STATE_MACHINE_FUNC)Drop, WPA_PSK_IDLE, WPA_MACHINE_BASE);
+ StateMachineSetAction(S, WPA_PSK_IDLE, MT2_EAPOLKey, (STATE_MACHINE_FUNC)WpaEAPOLKeyAction);
+}
+
+/*
+ ==========================================================================
+ Description:
+ This is state machine function.
+ When receiving EAPOL packets which is for 802.1x key management.
+ Use both in WPA, and WPAPSK case.
+ In this function, further dispatch to different functions according to the received packet. 3 categories are :
+ 1. normal 4-way pairwisekey and 2-way groupkey handshake
+ 2. MIC error (Countermeasures attack) report packet from STA.
+ 3. Request for pairwise/group key update from STA
+ Return:
+ ==========================================================================
+*/
+VOID WpaEAPOLKeyAction(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ INT MsgType = EAPOL_MSG_INVALID;
+ PKEY_DESCRIPTER pKeyDesc;
+ PHEADER_802_11 pHeader; //red
+ UCHAR ZeroReplay[LEN_KEY_DESC_REPLAY];
+ UCHAR EapolVr;
+ KEY_INFO peerKeyInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-----> WpaEAPOLKeyAction\n"));
+
+ // Get 802.11 header first
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Get EAPoL-Key Descriptor
+ pKeyDesc = (PKEY_DESCRIPTER) &Elem->Msg[(LENGTH_802_11 + LENGTH_802_1_H + LENGTH_EAPOL_H)];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pKeyDesc->KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT *)&peerKeyInfo) = cpu2le16(*((USHORT *)&peerKeyInfo));
+
+
+ // 1. Check EAPOL frame version and type
+ EapolVr = (UCHAR) Elem->Msg[LENGTH_802_11+LENGTH_802_1_H];
+
+ if (((EapolVr != EAPOL_VER) && (EapolVr != EAPOL_VER2)) || ((pKeyDesc->Type != WPA1_KEY_DESC) && (pKeyDesc->Type != WPA2_KEY_DESC)))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("Key descripter does not match with WPA rule\n"));
+ return;
+ }
+
+ // First validate replay counter, only accept message with larger replay counter
+ // Let equal pass, some AP start with all zero replay counter
+ NdisZeroMemory(ZeroReplay, LEN_KEY_DESC_REPLAY);
+
+ if((RTMPCompareMemory(pKeyDesc->ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1) &&
+ (RTMPCompareMemory(pKeyDesc->ReplayCounter, ZeroReplay, LEN_KEY_DESC_REPLAY) != 0))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" ReplayCounter not match \n"));
+ return;
+ }
+
+ // Process WPA2PSK frame
+ if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+ {
+ if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.EKD_DL == 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 0) &&
+ (peerKeyInfo.Secure == 0) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
+ } else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.EKD_DL == 1) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 1) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_3;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
+ } else if((peerKeyInfo.KeyType == GROUPKEY) &&
+ (peerKeyInfo.EKD_DL == 1) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 1) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_GROUP_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
+ }
+
+ // We will assume link is up (assoc suceess and port not secured).
+ // All state has to be able to process message from previous state
+ switch(pAd->StaCfg.WpaState)
+ {
+ case SS_START:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ Wpa2PairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ break;
+
+ case SS_WAIT_MSG_3:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ Wpa2PairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ Wpa2PairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ }
+ break;
+
+ case SS_WAIT_GROUP: // When doing group key exchange
+ case SS_FINISH: // This happened when update group key
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ Wpa2PairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ Wpa2PairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ }
+ else if(MsgType == EAPOL_GROUP_MSG_1)
+ {
+ WpaGroupMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_FINISH;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ // Process WPAPSK Frame
+ // Classify message Type, either pairwise message 1, 3, or group message 1 for supplicant
+ else if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+ {
+ if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.KeyIndex == 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 0) &&
+ (peerKeyInfo.Secure == 0) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 1\n"));
+ }
+ else if((peerKeyInfo.KeyType == PAIRWISEKEY) &&
+ (peerKeyInfo.KeyIndex == 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 0) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_PAIR_MSG_3;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Pairwise Message 3\n"));
+ }
+ else if((peerKeyInfo.KeyType == GROUPKEY) &&
+ (peerKeyInfo.KeyIndex != 0) &&
+ (peerKeyInfo.KeyAck == 1) &&
+ (peerKeyInfo.KeyMic == 1) &&
+ (peerKeyInfo.Secure == 1) &&
+ (peerKeyInfo.Error == 0) &&
+ (peerKeyInfo.Request == 0))
+ {
+ MsgType = EAPOL_GROUP_MSG_1;
+ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAPOL Key Group Message 1\n"));
+ }
+
+ // We will assume link is up (assoc suceess and port not secured).
+ // All state has to be able to process message from previous state
+ switch(pAd->StaCfg.WpaState)
+ {
+ case SS_START:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ WpaPairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ break;
+
+ case SS_WAIT_MSG_3:
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ WpaPairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ WpaPairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ }
+ break;
+
+ case SS_WAIT_GROUP: // When doing group key exchange
+ case SS_FINISH: // This happened when update group key
+ if(MsgType == EAPOL_PAIR_MSG_1)
+ {
+ WpaPairMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_MSG_3;
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ else if(MsgType == EAPOL_PAIR_MSG_3)
+ {
+ WpaPairMsg3Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_WAIT_GROUP;
+ // Reset port secured variable
+ pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ }
+ else if(MsgType == EAPOL_GROUP_MSG_1)
+ {
+ WpaGroupMsg1Action(pAd, Elem);
+ pAd->StaCfg.WpaState = SS_FINISH;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<----- WpaEAPOLKeyAction\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process Pairwise key 4-way handshaking
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaPairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PHEADER_802_11 pHeader;
+ UCHAR *mpool, *PTK, *digest;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ PEAPOL_PACKET pMsg1;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action ----->\n"));
+
+ // allocate memory pool
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
+
+ if (mpool == NULL)
+ return;
+
+ // PTK Len = 80.
+ PTK = (UCHAR *) ROUND_UP(mpool, 4);
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
+
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Process message 1 from authenticator
+ pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ // 1. Save Replay counter, it will use to verify message 3 and construct message 2
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 2. Save ANonce
+ NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+ // Generate random SNonce
+ GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
+
+ // Calc PTK(ANonce, SNonce)
+ WpaCountPTK(pAd,
+ pAd->StaCfg.PMK,
+ pAd->StaCfg.ANonce,
+ pAd->CommonCfg.Bssid,
+ pAd->StaCfg.SNonce,
+ pAd->CurrentAddress,
+ PTK,
+ LEN_PTK);
+
+ // Save key to PTK entry
+ NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero Message 2 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ //
+ // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+ //
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ // 1. Key descriptor version and appropriate RSN IE
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+ }
+ else // TKIP
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+ }
+
+ // fill in Data Material and its length
+ Packet.KeyDesc.KeyData[0] = IE_WPA;
+ Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
+ Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+
+ // Update packet length after decide Key data payload
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
+
+ // Update Key length
+ Packet.KeyDesc.KeyLength[0] = pMsg1->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
+ // 2. Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // 3. KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ //Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+
+ // 4. Fill SNonce
+ NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
+
+ // 5. Key Replay Count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Send EAPOL(0, 1, 0, 0, 0, P, 0, SNonce, MIC, RSN_IE)
+ // Out buffer for transmitting message 2
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ os_free_mem(pAd, mpool);
+ return;
+ }
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // 6. Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ { // AES
+
+ HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ { // TKIP
+ hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ //hex_dump("MIC", Mic, LEN_KEY_DESC_MIC);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // 5. Copy frame to Tx ring and send Msg 2 to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ os_free_mem(pAd, (PUCHAR)mpool);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg1Action <-----\n"));
+}
+
+VOID Wpa2PairMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PHEADER_802_11 pHeader;
+ UCHAR *mpool, *PTK, *digest;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ PEAPOL_PACKET pMsg1;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action ----->\n"));
+
+ // allocate memory pool
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 256);
+
+ if (mpool == NULL)
+ return;
+
+ // PTK Len = 80.
+ PTK = (UCHAR *) ROUND_UP(mpool, 4);
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(PTK + 80, 4);
+
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Process message 1 from authenticator
+ pMsg1 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ // 1. Save Replay counter, it will use to verify message 3 and construct message 2
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg1->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 2. Save ANonce
+ NdisMoveMemory(pAd->StaCfg.ANonce, pMsg1->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE);
+
+ // Generate random SNonce
+ GenRandom(pAd, pAd->CurrentAddress, pAd->StaCfg.SNonce);
+
+ if(pMsg1->KeyDesc.KeyDataLen[1] > 0 )
+ {
+ // cached PMKID
+ }
+
+ // Calc PTK(ANonce, SNonce)
+ WpaCountPTK(pAd,
+ pAd->StaCfg.PMK,
+ pAd->StaCfg.ANonce,
+ pAd->CommonCfg.Bssid,
+ pAd->StaCfg.SNonce,
+ pAd->CurrentAddress,
+ PTK,
+ LEN_PTK);
+
+ // Save key to PTK entry
+ NdisMoveMemory(pAd->StaCfg.PTK, PTK, LEN_PTK);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message 2 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ //
+ // Message 2 as EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+ //
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+
+ // 1. Key descriptor version and appropriate RSN IE
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+ }
+ else // TKIP
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+ }
+
+ // fill in Data Material and its length
+ Packet.KeyDesc.KeyData[0] = IE_WPA2;
+ Packet.KeyDesc.KeyData[1] = pAd->StaCfg.RSNIE_Len;
+ Packet.KeyDesc.KeyDataLen[1] = pAd->StaCfg.RSNIE_Len + 2;
+ NdisMoveMemory(&Packet.KeyDesc.KeyData[2], pAd->StaCfg.RSN_IE, pAd->StaCfg.RSNIE_Len);
+
+ // Update packet length after decide Key data payload
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE + Packet.KeyDesc.KeyDataLen[1];
+
+ // 2. Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // 3. KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = 0;
+ Packet.KeyDesc.KeyLength[1] = pMsg1->KeyDesc.KeyLength[1];
+
+ // 4. Fill SNonce
+ NdisMoveMemory(Packet.KeyDesc.KeyNonce, pAd->StaCfg.SNonce, LEN_KEY_DESC_NONCE);
+
+ // 5. Key Replay Count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Send EAPOL-Key(0,1,0,0,0,P,0,SNonce,MIC,RSN IE)
+ // Out buffer for transmitting message 2
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ os_free_mem(pAd, mpool);
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // 6. Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1(pOutBuffer, FrameLen, PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+
+ // Make Transmitting frame
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // 5. Copy frame to Tx ring
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ MlmeFreeMemory(pAd, pOutBuffer);
+ os_free_mem(pAd, mpool);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg1Action <-----\n"));
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process Pairwise key 4-way handshaking
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaPairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ PHEADER_802_11 pHeader;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ PEAPOL_PACKET pMsg3;
+ UCHAR Mic[16], OldMic[16];
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ UCHAR skip_offset;
+ KEY_INFO peerKeyInfo;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action ----->\n"));
+
+ // Record 802.11 header & the received EAPOL packet Msg3
+ pHeader = (PHEADER_802_11) Elem->Msg;
+ pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+
+ // 1. Verify cipher type match
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
+ {
+ return;
+ }
+ else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+ {
+ return;
+ }
+
+ // Verify RSN IE
+ //if (!RTMPEqualMemory(pMsg3->KeyDesc.KeyData, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len))
+ if (!CheckRSNIE(pAd, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1], &skip_offset))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("RSN_IE Different in Msg 3 of WPA1 4-way handshake!! \n"));
+ hex_dump("The original RSN_IE", pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len);
+ hex_dump("The received RSN_IE", pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("RSN_IE VALID in Msg 3 of WPA1 4-way handshake!! \n"));
+
+
+ // 2. Check MIC value
+ // Save the MIC and replace with zero
+ NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ UCHAR digest[80];
+
+ HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else // TKIP
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
+ }
+
+ if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+
+ // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+ if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+ return;
+
+ // Update new replay counter
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 4. Double check ANonce
+ if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
+ return;
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero Message 4 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
+
+ //
+ // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
+ //
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+
+ // Key descriptor version and appropriate RSN IE
+ Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
+
+ // Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // In Msg3, KeyInfo.secure =0 if Group Key HS to come. 1 if no group key HS
+ // Station sends Msg4 KeyInfo.secure should be the same as that in Msg.3
+ Packet.KeyDesc.KeyInfo.Secure= peerKeyInfo.Secure;
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Key Replay count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Out buffer for transmitting message 4
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ return;
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ UCHAR digest[80];
+
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ // Update PTK
+ // Prepare pair-wise key information into shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+ // Update these related information to MAC_TABLE_ENTRY
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ NdisMoveMemory(pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+ // Update pairwise key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pEntry);
+
+ // Make transmitting frame
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // Copy frame to Tx ring and Send Message 4 to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaPairMsg3Action <-----\n"));
+}
+
+VOID Wpa2PairMsg3Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ PHEADER_802_11 pHeader;
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ PEAPOL_PACKET pMsg3;
+ UCHAR Mic[16], OldMic[16];
+ UCHAR *mpool, *KEYDATA, *digest;
+ UCHAR Key[32];
+ MAC_TABLE_ENTRY *pEntry = NULL;
+ KEY_INFO peerKeyInfo;
+
+ // allocate memory
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
+
+ if(mpool == NULL)
+ return;
+
+ // KEYDATA Len = 512.
+ KEYDATA = (UCHAR *) ROUND_UP(mpool, 4);
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(KEYDATA + 512, 4);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Wpa2PairMsg3Action ----->\n"));
+
+ pHeader = (PHEADER_802_11) Elem->Msg;
+
+ // Process message 3 frame.
+ pMsg3 = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pMsg3->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+ // 1. Verify cipher type match
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer!= 2))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else if(pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // 2. Check MIC value
+ // Save the MIC and replace with zero
+ NdisMoveMemory(OldMic, pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pMsg3->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1((PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pMsg3, pMsg3->Body_Len[1] + 4, Mic);
+ }
+
+ if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in msg 3 of 4-way handshake!!!!!!!!!! \n"));
+
+ // 3. Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+ if(RTMPCompareMemory(pMsg3->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Update new replay counter
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 4. Double check ANonce
+ if(!NdisEqualMemory(pAd->StaCfg.ANonce, pMsg3->KeyDesc.KeyNonce, LEN_KEY_DESC_NONCE))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Obtain GTK
+ // 5. Decrypt GTK from Key Data
+ DBGPRINT_RAW(RT_DEBUG_TRACE, ("EKD = %d\n", peerKeyInfo.EKD_DL));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // Decrypt AES GTK
+ AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pMsg3->KeyDesc.KeyDataLen[1],pMsg3->KeyDesc.KeyData);
+ }
+ else // TKIP
+ {
+ INT i;
+ // Decrypt TKIP GTK
+ // Construct 32 bytes RC4 Key
+ NdisMoveMemory(Key, pMsg3->KeyDesc.KeyIv, 16);
+ NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+ //discard first 256 bytes
+ for(i = 0; i < 256; i++)
+ ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+ // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pMsg3->KeyDesc.KeyData, pMsg3->KeyDesc.KeyDataLen[1]);
+ }
+
+ if (!ParseKeyData(pAd, KEYDATA, pMsg3->KeyDesc.KeyDataLen[1], 1))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Update GTK to ASIC
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ NULL);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero message 4 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
+
+ //
+ // Message 4 as EAPOL-Key(0,1,0,0,0,P,0,0,MIC,0)
+ //
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+
+ // Key descriptor version and appropriate RSN IE
+ Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = pMsg3->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pMsg3->KeyDesc.KeyLength[1];
+
+ // Key Type PeerKey
+ Packet.KeyDesc.KeyInfo.KeyType = PAIRWISEKEY;
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Key Replay count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pMsg3->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Out buffer for transmitting message 4
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ // Update PTK
+ // Prepare pair-wise key information into shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+ // Update these related information to MAC_TABLE_ENTRY
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ NdisMoveMemory(&pEntry->PairwiseKey.Key, &pAd->StaCfg.PTK[32], LEN_TKIP_EK);
+ NdisMoveMemory(&pEntry->PairwiseKey.RxMic, &pAd->StaCfg.PTK[48], LEN_TKIP_RXMICK);
+ NdisMoveMemory(&pEntry->PairwiseKey.TxMic, &pAd->StaCfg.PTK[48+LEN_TKIP_RXMICK], LEN_TKIP_TXMICK);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+ // Update pairwise key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pEntry);
+
+ // Make Transmitting frame
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // Copy frame to Tx ring and Send Message 4 to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, TRUE);
+
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ os_free_mem(pAd, (PUCHAR)mpool);
+
+
+ // send wireless event - for set key done WPA2
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pEntry->Addr, BSS0, 0);
+
+ DBGPRINT(RT_DEBUG_ERROR, ("Wpa2PairMsg3Action <-----\n"));
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process Group key 2-way handshaking
+
+ Arguments:
+ pAd Pointer to our adapter
+ Elem Message body
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaGroupMsg1Action(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+
+{
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ PEAPOL_PACKET pGroup;
+ UCHAR *mpool, *digest, *KEYDATA;
+ UCHAR Mic[16], OldMic[16];
+ UCHAR GTK[32], Key[32];
+ KEY_INFO peerKeyInfo;
+
+ // allocate memory
+ os_alloc_mem(pAd, (PUCHAR *)&mpool, 1024);
+
+ if(mpool == NULL)
+ return;
+
+ // digest Len = 80.
+ digest = (UCHAR *) ROUND_UP(mpool, 4);
+ // KEYDATA Len = 512.
+ KEYDATA = (UCHAR *) ROUND_UP(digest + 80, 4);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action ----->\n"));
+
+ // Process Group Message 1 frame. skip 802.11 header(24) & LLC_SNAP header(8)
+ pGroup = (PEAPOL_PACKET) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H];
+
+ NdisZeroMemory((PUCHAR)&peerKeyInfo, sizeof(peerKeyInfo));
+ NdisMoveMemory((PUCHAR)&peerKeyInfo, (PUCHAR)&pGroup->KeyDesc.KeyInfo, sizeof(KEY_INFO));
+
+ *((USHORT*)&peerKeyInfo) = cpu2le16(*((USHORT*)&peerKeyInfo));
+
+ // 0. Check cipher type match
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled && (peerKeyInfo.KeyDescVer != 2))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled && (peerKeyInfo.KeyDescVer != 1))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // 1. Verify Replay counter
+ // Check Replay Counter, it has to be larger than last one. No need to be exact one larger
+ if(RTMPCompareMemory(pGroup->KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY) != 1)
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Update new replay counter
+ NdisMoveMemory(pAd->StaCfg.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // 2. Verify MIC is valid
+ // Save the MIC and replace with zero
+ NdisMoveMemory(OldMic, pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+ NdisZeroMemory(pGroup->KeyDesc.KeyMic, LEN_KEY_DESC_MIC);
+
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ { // AES
+ HMAC_SHA1((PUCHAR) pGroup, pGroup->Body_Len[1] + 4, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ { // TKIP
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, (PUCHAR) pGroup, pGroup->Body_Len[1] + 4, Mic);
+ }
+
+ if(!NdisEqualMemory(OldMic, Mic, LEN_KEY_DESC_MIC))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, (" MIC Different in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
+ MlmeFreeMemory(pAd, (PUCHAR)mpool);
+ return;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, (" MIC VALID in group msg 1 of 2-way handshake!!!!!!!!!! \n"));
+
+
+ // 3. Decrypt GTK from Key Data
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // Decrypt AES GTK
+ AES_GTK_KEY_UNWRAP(&pAd->StaCfg.PTK[16], KEYDATA, pGroup->KeyDesc.KeyDataLen[1], pGroup->KeyDesc.KeyData);
+ }
+ else // TKIP
+ {
+ INT i;
+
+ // Decrypt TKIP GTK
+ // Construct 32 bytes RC4 Key
+ NdisMoveMemory(Key, pGroup->KeyDesc.KeyIv, 16);
+ NdisMoveMemory(&Key[16], &pAd->StaCfg.PTK[16], 16);
+ ARCFOUR_INIT(&pAd->PrivateInfo.WEPCONTEXT, Key, 32);
+ //discard first 256 bytes
+ for(i = 0; i < 256; i++)
+ ARCFOUR_BYTE(&pAd->PrivateInfo.WEPCONTEXT);
+ // Decrypt GTK. Becareful, there is no ICV to check the result is correct or not
+ ARCFOUR_DECRYPT(&pAd->PrivateInfo.WEPCONTEXT, KEYDATA, pGroup->KeyDesc.KeyData, pGroup->KeyDesc.KeyDataLen[1]);
+ }
+
+ // Process decrypted key data material
+ // Parse keyData to handle KDE format for WPA2PSK
+ if (peerKeyInfo.EKD_DL)
+ {
+ if (!ParseKeyData(pAd, KEYDATA, pGroup->KeyDesc.KeyDataLen[1], 0))
+ {
+ os_free_mem(pAd, (PUCHAR)mpool);
+ return;
+ }
+ }
+ else // WPAPSK
+ {
+ // set key material, TxMic and RxMic for WPAPSK
+ NdisMoveMemory(GTK, KEYDATA, 32);
+ NdisMoveMemory(pAd->StaCfg.GTK, GTK, 32);
+ pAd->StaCfg.DefaultKeyId = peerKeyInfo.KeyIndex;
+
+ // Prepare pair-wise key information into shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, GTK, LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &GTK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &GTK[24], LEN_TKIP_TXMICK);
+
+ // Update Shared Key CipherAlg
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ //hex_dump("Group Key :", pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, LEN_TKIP_EK);
+ }
+
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ NULL);
+
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+
+ // init header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ // Zero Group message 1 body
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE; // No data field
+
+ //
+ // Group Message 2 as EAPOL-Key(1,0,0,0,G,0,0,MIC,0)
+ //
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+ {
+ Packet.KeyDesc.Type = WPA2_KEY_DESC;
+ }
+ else
+ {
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+ }
+
+ // Key descriptor version and appropriate RSN IE
+ Packet.KeyDesc.KeyInfo.KeyDescVer = peerKeyInfo.KeyDescVer;
+
+ // Update Key Length
+ Packet.KeyDesc.KeyLength[0] = pGroup->KeyDesc.KeyLength[0];
+ Packet.KeyDesc.KeyLength[1] = pGroup->KeyDesc.KeyLength[1];
+
+ // Key Index as G-Msg 1
+ if(pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+ Packet.KeyDesc.KeyInfo.KeyIndex = peerKeyInfo.KeyIndex;
+
+ // Key Type Group key
+ Packet.KeyDesc.KeyInfo.KeyType = GROUPKEY;
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // Secure bit
+ Packet.KeyDesc.KeyInfo.Secure = 1;
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+ // Key Replay count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pGroup->KeyDesc.ReplayCounter, LEN_KEY_DESC_REPLAY);
+
+ // Out buffer for transmitting group message 2
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ MlmeFreeMemory(pAd, (PUCHAR)mpool);
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ // AES
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ {
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+
+ // 5. Copy frame to Tx ring and prepare for encryption
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
+
+ // 6 Free allocated memory
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+ os_free_mem(pAd, (PUCHAR)mpool);
+
+ // send wireless event - for set key done WPA2
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_SET_KEY_DONE_WPA2_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaGroupMsg1Action <-----\n"));
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Init WPA MAC header
+
+ Arguments:
+ pAd Pointer to our adapter
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID WpaMacHeaderInit(
+ IN PRTMP_ADAPTER pAd,
+ IN OUT PHEADER_802_11 pHdr80211,
+ IN UCHAR wep,
+ IN PUCHAR pAddr1)
+{
+ NdisZeroMemory(pHdr80211, sizeof(HEADER_802_11));
+ pHdr80211->FC.Type = BTYPE_DATA;
+ pHdr80211->FC.ToDs = 1;
+ if (wep == 1)
+ pHdr80211->FC.Wep = 1;
+
+ // Addr1: BSSID, Addr2: SA, Addr3: DA
+ COPY_MAC_ADDR(pHdr80211->Addr1, pAddr1);
+ COPY_MAC_ADDR(pHdr80211->Addr2, pAd->CurrentAddress);
+ COPY_MAC_ADDR(pHdr80211->Addr3, pAd->CommonCfg.Bssid);
+ pHdr80211->Sequence = pAd->Sequence;
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Copy frame from waiting queue into relative ring buffer and set
+ appropriate ASIC register to kick hardware encryption before really
+ sent out to air.
+
+ Arguments:
+ pAd Pointer to our adapter
+ PNDIS_PACKET Pointer to outgoing Ndis frame
+ NumberOfFrag Number of fragment required
+
+ Return Value:
+ None
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPToWirelessSta(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pHeader802_3,
+ IN UINT HdrLen,
+ IN PUCHAR pData,
+ IN UINT DataLen,
+ IN BOOLEAN is4wayFrame)
+
+{
+ NDIS_STATUS Status;
+ PNDIS_PACKET pPacket;
+ UCHAR Index;
+
+ do
+ {
+ // 1. build a NDIS packet and call RTMPSendPacket();
+ // be careful about how/when to release this internal allocated NDIS PACKET buffer
+ Status = RTMPAllocateNdisPacket(pAd, &pPacket, pHeader802_3, HdrLen, pData, DataLen);
+ if (Status != NDIS_STATUS_SUCCESS)
+ break;
+
+ if (is4wayFrame)
+ RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 1);
+ else
+ RTMP_SET_PACKET_CLEAR_EAP_FRAME(pPacket, 0);
+
+ // 2. send out the packet
+ Status = STASendPacket(pAd, pPacket);
+ if(Status == NDIS_STATUS_SUCCESS)
+ {
+ // Dequeue one frame from TxSwQueue0..3 queue and process it
+ // There are three place calling dequeue for TX ring.
+ // 1. Here, right after queueing the frame.
+ // 2. At the end of TxRingTxDone service routine.
+ // 3. Upon NDIS call RTMPSendPackets
+ if((!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) &&
+ (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RESET_IN_PROGRESS)))
+ {
+ for(Index = 0; Index < 5; Index ++)
+ if(pAd->TxSwQueue[Index].Number > 0)
+ RTMPDeQueuePacket(pAd, FALSE, Index, MAX_TX_PROCESS);
+ }
+ }
+ } while(FALSE);
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Check Sanity RSN IE form AP
+
+ Arguments:
+
+ Return Value:
+
+
+ ========================================================================
+*/
+BOOLEAN CheckRSNIE(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pData,
+ IN UCHAR DataLen,
+ OUT UCHAR *Offset)
+{
+ PUCHAR pVIE;
+ UCHAR len;
+ PEID_STRUCT pEid;
+ BOOLEAN result = FALSE;
+
+ pVIE = pData;
+ len = DataLen;
+ *Offset = 0;
+
+ while (len > sizeof(RSNIE2))
+ {
+ pEid = (PEID_STRUCT) pVIE;
+ // WPA RSN IE
+ if ((pEid->Eid == IE_WPA) && (NdisEqualMemory(pEid->Octet, WPA_OUI, 4)))
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) &&
+ (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
+ (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA/WPAPSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ // WPA2 RSN IE
+ else if ((pEid->Eid == IE_RSN) && (NdisEqualMemory(pEid->Octet + 2, RSN_OUI, 3)))
+ {
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2 || pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) &&
+ (NdisEqualMemory(pVIE, pAd->MacTab.Content[BSSID_WCID].RSN_IE, pAd->MacTab.Content[BSSID_WCID].RSNIE_Len)) &&
+ (pAd->MacTab.Content[BSSID_WCID].RSNIE_Len == (pEid->Len + 2)))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", (pEid->Len + 2)));
+ result = TRUE;
+ }
+
+ *Offset += (pEid->Len + 2);
+ }
+ else
+ {
+ break;
+ }
+
+ pVIE += (pEid->Len + 2);
+ len -= (pEid->Len + 2);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("CheckRSNIE ==> skip_offset(%d) \n", *Offset));
+
+ return result;
+
+}
+
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Parse KEYDATA field. KEYDATA[] May contain 2 RSN IE and optionally GTK.
+ GTK is encaptulated in KDE format at p.83 802.11i D10
+
+ Arguments:
+
+ Return Value:
+
+ Note:
+ 802.11i D10
+
+ ========================================================================
+*/
+BOOLEAN ParseKeyData(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pKeyData,
+ IN UCHAR KeyDataLen,
+ IN UCHAR bPairewise)
+{
+ PKDE_ENCAP pKDE = NULL;
+ PUCHAR pMyKeyData = pKeyData;
+ UCHAR KeyDataLength = KeyDataLen;
+ UCHAR GTKLEN;
+ UCHAR skip_offset;
+
+ // Verify The RSN IE contained in Pairewise-Msg 3 and skip it
+ if (bPairewise)
+ {
+ // Check RSN IE whether it is WPA2/WPA2PSK
+ if (!CheckRSNIE(pAd, pKeyData, KeyDataLen, &skip_offset))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE mismatched \n"));
+ hex_dump("Get KEYDATA :", pKeyData, KeyDataLen);
+ return FALSE;
+ }
+ else
+ {
+ // skip RSN IE
+ pMyKeyData += skip_offset;
+ KeyDataLength -= skip_offset;
+
+ //DBGPRINT(RT_DEBUG_TRACE, ("ParseKeyData ==> WPA2/WPA2PSK RSN IE matched in Msg 3, Length(%d) \n", skip_offset));
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("ParseKeyData ==> KeyDataLength %d without RSN_IE \n", KeyDataLength));
+
+ // Parse EKD format
+ if (KeyDataLength >= 8)
+ {
+ pKDE = (PKDE_ENCAP) pMyKeyData;
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: KeyDataLength is too short \n"));
+ return FALSE;
+ }
+
+
+ // Sanity check - shared key index should not be 0
+ if (pKDE->GTKEncap.Kid == 0)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key index zero \n"));
+ return FALSE;
+ }
+
+ // Sanity check - KED length
+ if (KeyDataLength < (pKDE->Len + 2))
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The len from KDE is too short \n"));
+ return FALSE;
+ }
+
+ // Get GTK length - refer to IEEE 802.11i-2004 p.82
+ GTKLEN = pKDE->Len -6;
+
+ if (GTKLEN < LEN_AES_KEY)
+ {
+ DBGPRINT(RT_DEBUG_ERROR, ("ERROR: GTK Key length is too short (%d) \n", GTKLEN));
+ return FALSE;
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("GTK Key with KDE formet got index=%d, len=%d \n", pKDE->GTKEncap.Kid, GTKLEN));
+
+ // Update GTK
+ // set key material, TxMic and RxMic for WPAPSK
+ NdisMoveMemory(pAd->StaCfg.GTK, pKDE->GTKEncap.GTK, 32);
+ pAd->StaCfg.DefaultKeyId = pKDE->GTKEncap.Kid;
+
+ // Update shared key table
+ NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKDE->GTKEncap.GTK, LEN_TKIP_EK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, &pKDE->GTKEncap.GTK[16], LEN_TKIP_RXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, &pKDE->GTKEncap.GTK[24], LEN_TKIP_TXMICK);
+
+ // Update Shared Key CipherAlg
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ return TRUE;
+
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Cisco CCKM PRF function
+
+ Arguments:
+ key Cisco Base Transient Key (BTK)
+ key_len The key length of the BTK
+ data Ruquest Number(RN) + BSSID
+ data_len The length of the data
+ output Store for PTK(Pairwise transient keys)
+ len The length of the output
+ Return Value:
+ None
+
+ Note:
+ 802.1i Annex F.9
+
+ ========================================================================
+*/
+VOID CCKMPRF(
+ IN UCHAR *key,
+ IN INT key_len,
+ IN UCHAR *data,
+ IN INT data_len,
+ OUT UCHAR *output,
+ IN INT len)
+{
+ INT i;
+ UCHAR input[1024];
+ INT currentindex = 0;
+ INT total_len;
+
+ NdisMoveMemory(input, data, data_len);
+ total_len = data_len;
+ input[total_len] = 0;
+ total_len++;
+ for (i = 0; i < (len + 19) / 20; i++)
+ {
+ HMAC_SHA1(input, total_len, key, key_len, &output[currentindex]);
+ currentindex += 20;
+ input[total_len - 1]++;
+ }
+}
+
+/*
+ ========================================================================
+
+ Routine Description:
+ Process MIC error indication and record MIC error timer.
+
+ Arguments:
+ pAd Pointer to our adapter
+ pWpaKey Pointer to the WPA key structure
+
+ Return Value:
+ None
+
+ IRQL = DISPATCH_LEVEL
+
+ Note:
+
+ ========================================================================
+*/
+VOID RTMPReportMicError(
+ IN PRTMP_ADAPTER pAd,
+ IN PCIPHER_KEY pWpaKey)
+{
+ ULONG Now;
+ UCHAR unicastKey = (pWpaKey->Type == PAIRWISE_KEY ? 1:0);
+
+ // Record Last MIC error time and count
+ Now = jiffies;
+ if (pAd->StaCfg.MicErrCnt == 0)
+ {
+ pAd->StaCfg.MicErrCnt++;
+ pAd->StaCfg.LastMicErrorTime = Now;
+ NdisZeroMemory(pAd->StaCfg.ReplayCounter, 8);
+ }
+ else if (pAd->StaCfg.MicErrCnt == 1)
+ {
+ if ((pAd->StaCfg.LastMicErrorTime + (60 * OS_HZ)) < Now)
+ {
+ // Update Last MIC error time, this did not violate two MIC errors within 60 seconds
+ pAd->StaCfg.LastMicErrorTime = Now;
+ }
+ else
+ {
+
+ if (pAd->CommonCfg.bWirelessEvent)
+ RTMPSendWirelessEvent(pAd, IW_COUNTER_MEASURES_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0);
+
+ pAd->StaCfg.LastMicErrorTime = Now;
+ // Violate MIC error counts, MIC countermeasures kicks in
+ pAd->StaCfg.MicErrCnt++;
+ // We shall block all reception
+ // We shall clean all Tx ring and disassoicate from AP after next EAPOL frame
+ //
+ // No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets
+ // if pAd->StaCfg.MicErrCnt greater than 2.
+ //
+ // RTMPRingCleanUp(pAd, QID_AC_BK);
+ // RTMPRingCleanUp(pAd, QID_AC_BE);
+ // RTMPRingCleanUp(pAd, QID_AC_VI);
+ // RTMPRingCleanUp(pAd, QID_AC_VO);
+ // RTMPRingCleanUp(pAd, QID_HCCA);
+ }
+ }
+ else
+ {
+ // MIC error count >= 2
+ // This should not happen
+ ;
+ }
+ MlmeEnqueue(pAd,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_MIC_FAILURE_REPORT_FRAME,
+ 1,
+ &unicastKey);
+
+ if (pAd->StaCfg.MicErrCnt == 2)
+ {
+ RTMPSetTimer(&pAd->StaCfg.WpaDisassocAndBlockAssocTimer, 100);
+ }
+}
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+#define LENGTH_EAP_H 4
+// If the received frame is EAP-Packet ,find out its EAP-Code (Request(0x01), Response(0x02), Success(0x03), Failure(0x04)).
+INT WpaCheckEapCode(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pFrame,
+ IN USHORT FrameLen,
+ IN USHORT OffSet)
+{
+
+ PUCHAR pData;
+ INT result = 0;
+
+ if( FrameLen < OffSet + LENGTH_EAPOL_H + LENGTH_EAP_H )
+ return result;
+
+ pData = pFrame + OffSet; // skip offset bytes
+
+ if(*(pData+1) == EAPPacket) // 802.1x header - Packet Type
+ {
+ result = *(pData+4); // EAP header - Code
+ }
+
+ return result;
+}
+
+VOID WpaSendMicFailureToWpaSupplicant(
+ IN PRTMP_ADAPTER pAd,
+ IN BOOLEAN bUnicast)
+{
+ union iwreq_data wrqu;
+ char custom[IW_CUSTOM_MAX] = {0};
+
+ sprintf(custom, "MLME-MICHAELMICFAILURE.indication");
+ if (bUnicast)
+ sprintf(custom, "%s unicast", custom);
+ wrqu.data.length = strlen(custom);
+ wireless_send_event(pAd->net_dev, IWEVCUSTOM, &wrqu, custom);
+
+ return;
+}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+VOID WpaMicFailureReportFrame(
+ IN PRTMP_ADAPTER pAd,
+ IN MLME_QUEUE_ELEM *Elem)
+{
+ PUCHAR pOutBuffer = NULL;
+ UCHAR Header802_3[14];
+ ULONG FrameLen = 0;
+ EAPOL_PACKET Packet;
+ UCHAR Mic[16];
+ BOOLEAN bUnicast;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame ----->\n"));
+
+ bUnicast = (Elem->Msg[0] == 1 ? TRUE:FALSE);
+ pAd->Sequence = ((pAd->Sequence) + 1) & (MAX_SEQ_NUMBER);
+
+ // init 802.3 header and Fill Packet
+ MAKE_802_3_HEADER(Header802_3, pAd->CommonCfg.Bssid, pAd->CurrentAddress, EAPOL);
+
+ NdisZeroMemory(&Packet, sizeof(Packet));
+ Packet.ProVer = EAPOL_VER;
+ Packet.ProType = EAPOLKey;
+
+ Packet.KeyDesc.Type = WPA1_KEY_DESC;
+
+ // Request field presented
+ Packet.KeyDesc.KeyInfo.Request = 1;
+
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 2;
+ }
+ else // TKIP
+ {
+ Packet.KeyDesc.KeyInfo.KeyDescVer = 1;
+ }
+
+ Packet.KeyDesc.KeyInfo.KeyType = (bUnicast ? PAIRWISEKEY : GROUPKEY);
+
+ // KeyMic field presented
+ Packet.KeyDesc.KeyInfo.KeyMic = 1;
+
+ // Error field presented
+ Packet.KeyDesc.KeyInfo.Error = 1;
+
+ // Update packet length after decide Key data payload
+ Packet.Body_Len[1] = sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE;
+
+ // Key Replay Count
+ NdisMoveMemory(Packet.KeyDesc.ReplayCounter, pAd->StaCfg.ReplayCounter, LEN_KEY_DESC_REPLAY);
+ inc_byte_array(pAd->StaCfg.ReplayCounter, 8);
+
+ // Convert to little-endian format.
+ *((USHORT *)&Packet.KeyDesc.KeyInfo) = cpu2le16(*((USHORT *)&Packet.KeyDesc.KeyInfo));
+
+
+ MlmeAllocateMemory(pAd, (PUCHAR *)&pOutBuffer); // allocate memory
+ if(pOutBuffer == NULL)
+ {
+ return;
+ }
+
+ // Prepare EAPOL frame for MIC calculation
+ // Be careful, only EAPOL frame is counted for MIC calculation
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // Prepare and Fill MIC value
+ NdisZeroMemory(Mic, sizeof(Mic));
+ if(pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled)
+ { // AES
+ UCHAR digest[20] = {0};
+ HMAC_SHA1(pOutBuffer, FrameLen, pAd->StaCfg.PTK, LEN_EAP_MICK, digest);
+ NdisMoveMemory(Mic, digest, LEN_KEY_DESC_MIC);
+ }
+ else
+ { // TKIP
+ hmac_md5(pAd->StaCfg.PTK, LEN_EAP_MICK, pOutBuffer, FrameLen, Mic);
+ }
+ NdisMoveMemory(Packet.KeyDesc.KeyMic, Mic, LEN_KEY_DESC_MIC);
+
+ MakeOutgoingFrame(pOutBuffer, &FrameLen,
+ LENGTH_802_3, &Header802_3,
+ Packet.Body_Len[1] + 4, &Packet,
+ END_OF_ARGS);
+
+ // opy frame to Tx ring and send MIC failure report frame to authenticator
+ RTMPToWirelessSta(pAd, Header802_3, LENGTH_802_3, (PUCHAR)&Packet, Packet.Body_Len[1] + 4, FALSE);
+
+ MlmeFreeMemory(pAd, (PUCHAR)pOutBuffer);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("WpaMicFailureReportFrame <-----\n"));
+}
+
+/** from wpa_supplicant
+ * inc_byte_array - Increment arbitrary length byte array by one
+ * @counter: Pointer to byte array
+ * @len: Length of the counter in bytes
+ *
+ * This function increments the last byte of the counter by one and continues
+ * rolling over to more significant bytes if the byte was incremented from
+ * 0xff to 0x00.
+ */
+void inc_byte_array(UCHAR *counter, int len)
+{
+ int pos = len - 1;
+ while (pos >= 0) {
+ counter[pos]++;
+ if (counter[pos] != 0)
+ break;
+ pos--;
+ }
+}
+
+VOID WpaDisassocApAndBlockAssoc(
+ IN PVOID SystemSpecific1,
+ IN PVOID FunctionContext,
+ IN PVOID SystemSpecific2,
+ IN PVOID SystemSpecific3)
+{
+ RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext;
+ MLME_DISASSOC_REQ_STRUCT DisassocReq;
+
+ // disassoc from current AP first
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPReportMicError - disassociate with current AP after sending second continuous EAPOL frame\n"));
+ DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_MIC_FAILURE);
+ MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq);
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC;
+ pAd->StaCfg.bBlockAssoc = TRUE;
+}
+
diff --git a/drivers/staging/rt3070/sta_ioctl.c b/drivers/staging/rt3070/sta_ioctl.c
new file mode 100644
index 00000000000..079454835a4
--- /dev/null
+++ b/drivers/staging/rt3070/sta_ioctl.c
@@ -0,0 +1,7203 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ sta_ioctl.c
+
+ Abstract:
+ IOCTL related subroutines
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Rory Chen 01-03-2003 created
+ Rory Chen 02-14-2005 modify to support RT61
+*/
+
+#include "rt_config.h"
+
+#ifdef DBG
+extern ULONG RTDebugLevel;
+#endif
+
+#define NR_WEP_KEYS 4
+#define WEP_SMALL_KEY_LEN (40/8)
+#define WEP_LARGE_KEY_LEN (104/8)
+
+#define GROUP_KEY_NO 4
+
+extern UCHAR CipherWpa2Template[];
+extern UCHAR CipherWpaPskTkip[];
+extern UCHAR CipherWpaPskTkipLen;
+
+typedef struct PACKED _RT_VERSION_INFO{
+ UCHAR DriverVersionW;
+ UCHAR DriverVersionX;
+ UCHAR DriverVersionY;
+ UCHAR DriverVersionZ;
+ UINT DriverBuildYear;
+ UINT DriverBuildMonth;
+ UINT DriverBuildDay;
+} RT_VERSION_INFO, *PRT_VERSION_INFO;
+
+struct iw_priv_args privtab[] = {
+{ RTPRIV_IOCTL_SET,
+ IW_PRIV_TYPE_CHAR | 1024, 0,
+ "set"},
+
+{ RTPRIV_IOCTL_SHOW, 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ ""},
+{ RTPRIV_IOCTL_SHOW, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ ""},
+/* --- sub-ioctls definitions --- */
+ { SHOW_CONN_STATUS,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "connStatus" },
+ { SHOW_DRVIER_VERION,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "driverVer" },
+ { SHOW_BA_INFO,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bainfo" },
+ { SHOW_DESC_INFO,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "descinfo" },
+ { RAIO_OFF,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_off" },
+ { RAIO_ON,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "radio_on" },
+#ifdef QOS_DLS_SUPPORT
+ { SHOW_DLS_ENTRY_INFO,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "dlsentryinfo" },
+#endif // QOS_DLS_SUPPORT //
+ { SHOW_CFG_VALUE,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "show" },
+/* --- sub-ioctls relations --- */
+
+#ifdef DBG
+{ RTPRIV_IOCTL_BBP,
+ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ "bbp"},
+{ RTPRIV_IOCTL_MAC,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "mac"},
+#ifdef RT30xx
+{ RTPRIV_IOCTL_RF,
+ IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ "rf"},
+#endif // RT30xx //
+{ RTPRIV_IOCTL_E2P,
+ IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024,
+ "e2p"},
+#endif /* DBG */
+
+{ RTPRIV_IOCTL_STATISTICS,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK,
+ "stat"},
+{ RTPRIV_IOCTL_GSITESURVEY,
+ 0, IW_PRIV_TYPE_CHAR | 1024,
+ "get_site_survey"},
+
+
+};
+
+INT Set_SSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef WMM_SUPPORT
+INT Set_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif
+
+INT Set_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key1_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key2_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key3_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_Key4_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+
+INT Set_PSMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+INT Set_Wpa_Support(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef DBG
+
+VOID RTMPIoctlMAC(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+VOID RTMPIoctlE2PROM(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+
+#ifdef RT30xx
+VOID RTMPIoctlRF(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq);
+#endif // RT30xx //
+#endif // DBG //
+
+
+NDIS_STATUS RTMPWPANoneAddKeyProc(
+ IN PRTMP_ADAPTER pAd,
+ IN PVOID pBuf);
+
+INT Set_FragTest_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef DOT11_N_SUPPORT
+INT Set_TGnWifiTest_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // DOT11_N_SUPPORT //
+
+INT Set_LongRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+INT Set_ShortRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg);
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef CARRIER_DETECTION_SUPPORT
+INT Set_CarrierDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg);
+#endif // CARRIER_DETECTION_SUPPORT //
+
+static struct {
+ CHAR *name;
+ INT (*set_proc)(PRTMP_ADAPTER pAdapter, PUCHAR arg);
+} *PRTMP_PRIVATE_SET_PROC, RTMP_PRIVATE_SUPPORT_PROC[] = {
+ {"DriverVersion", Set_DriverVersion_Proc},
+ {"CountryRegion", Set_CountryRegion_Proc},
+ {"CountryRegionABand", Set_CountryRegionABand_Proc},
+ {"SSID", Set_SSID_Proc},
+ {"WirelessMode", Set_WirelessMode_Proc},
+ {"TxBurst", Set_TxBurst_Proc},
+ {"TxPreamble", Set_TxPreamble_Proc},
+ {"TxPower", Set_TxPower_Proc},
+ {"Channel", Set_Channel_Proc},
+ {"BGProtection", Set_BGProtection_Proc},
+ {"RTSThreshold", Set_RTSThreshold_Proc},
+ {"FragThreshold", Set_FragThreshold_Proc},
+#ifdef DOT11_N_SUPPORT
+ {"HtBw", Set_HtBw_Proc},
+ {"HtMcs", Set_HtMcs_Proc},
+ {"HtGi", Set_HtGi_Proc},
+ {"HtOpMode", Set_HtOpMode_Proc},
+ {"HtExtcha", Set_HtExtcha_Proc},
+ {"HtMpduDensity", Set_HtMpduDensity_Proc},
+ {"HtBaWinSize", Set_HtBaWinSize_Proc},
+ {"HtRdg", Set_HtRdg_Proc},
+ {"HtAmsdu", Set_HtAmsdu_Proc},
+ {"HtAutoBa", Set_HtAutoBa_Proc},
+ {"HtBaDecline", Set_BADecline_Proc},
+ {"HtProtect", Set_HtProtect_Proc},
+ {"HtMimoPs", Set_HtMimoPs_Proc},
+#endif // DOT11_N_SUPPORT //
+
+#ifdef AGGREGATION_SUPPORT
+ {"PktAggregate", Set_PktAggregate_Proc},
+#endif
+
+#ifdef WMM_SUPPORT
+ {"WmmCapable", Set_WmmCapable_Proc},
+#endif
+ {"IEEE80211H", Set_IEEE80211H_Proc},
+ {"NetworkType", Set_NetworkType_Proc},
+ {"AuthMode", Set_AuthMode_Proc},
+ {"EncrypType", Set_EncrypType_Proc},
+ {"DefaultKeyID", Set_DefaultKeyID_Proc},
+ {"Key1", Set_Key1_Proc},
+ {"Key2", Set_Key2_Proc},
+ {"Key3", Set_Key3_Proc},
+ {"Key4", Set_Key4_Proc},
+ {"WPAPSK", Set_WPAPSK_Proc},
+ {"ResetCounter", Set_ResetStatCounter_Proc},
+ {"PSMode", Set_PSMode_Proc},
+#ifdef DBG
+ {"Debug", Set_Debug_Proc},
+#endif
+
+#ifdef RALINK_ATE
+ {"ATE", Set_ATE_Proc},
+ {"ATEDA", Set_ATE_DA_Proc},
+ {"ATESA", Set_ATE_SA_Proc},
+ {"ATEBSSID", Set_ATE_BSSID_Proc},
+ {"ATECHANNEL", Set_ATE_CHANNEL_Proc},
+ {"ATETXPOW0", Set_ATE_TX_POWER0_Proc},
+ {"ATETXPOW1", Set_ATE_TX_POWER1_Proc},
+ {"ATETXANT", Set_ATE_TX_Antenna_Proc},
+ {"ATERXANT", Set_ATE_RX_Antenna_Proc},
+ {"ATETXFREQOFFSET", Set_ATE_TX_FREQOFFSET_Proc},
+ {"ATETXBW", Set_ATE_TX_BW_Proc},
+ {"ATETXLEN", Set_ATE_TX_LENGTH_Proc},
+ {"ATETXCNT", Set_ATE_TX_COUNT_Proc},
+ {"ATETXMCS", Set_ATE_TX_MCS_Proc},
+ {"ATETXMODE", Set_ATE_TX_MODE_Proc},
+ {"ATETXGI", Set_ATE_TX_GI_Proc},
+ {"ATERXFER", Set_ATE_RX_FER_Proc},
+ {"ATERRF", Set_ATE_Read_RF_Proc},
+ {"ATEWRF1", Set_ATE_Write_RF1_Proc},
+ {"ATEWRF2", Set_ATE_Write_RF2_Proc},
+ {"ATEWRF3", Set_ATE_Write_RF3_Proc},
+ {"ATEWRF4", Set_ATE_Write_RF4_Proc},
+ {"ATELDE2P", Set_ATE_Load_E2P_Proc},
+ {"ATERE2P", Set_ATE_Read_E2P_Proc},
+ {"ATESHOW", Set_ATE_Show_Proc},
+ {"ATEHELP", Set_ATE_Help_Proc},
+
+#ifdef RALINK_28xx_QA
+ {"TxStop", Set_TxStop_Proc},
+ {"RxStop", Set_RxStop_Proc},
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ {"WpaSupport", Set_Wpa_Support},
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+
+ {"FixedTxMode", Set_FixedTxMode_Proc},
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ {"OpMode", Set_OpMode_Proc},
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+#ifdef DOT11_N_SUPPORT
+ {"TGnWifiTest", Set_TGnWifiTest_Proc},
+ {"ForceGF", Set_ForceGF_Proc},
+#endif // DOT11_N_SUPPORT //
+#ifdef QOS_DLS_SUPPORT
+ {"DlsAddEntry", Set_DlsAddEntry_Proc},
+ {"DlsTearDownEntry", Set_DlsTearDownEntry_Proc},
+#endif // QOS_DLS_SUPPORT //
+ {"LongRetry", Set_LongRetryLimit_Proc},
+ {"ShortRetry", Set_ShortRetryLimit_Proc},
+#ifdef EXT_BUILD_CHANNEL_LIST
+ {"11dClientMode", Set_Ieee80211dClientMode_Proc},
+#endif // EXT_BUILD_CHANNEL_LIST //
+#ifdef CARRIER_DETECTION_SUPPORT
+ {"CarrierDetect", Set_CarrierDetect_Proc},
+#endif // CARRIER_DETECTION_SUPPORT //
+//2008/09/11:KH add to support efuse<--
+#ifdef RT30xx
+ {"efuseFreeNumber", set_eFuseGetFreeBlockCount_Proc},
+ {"efuseDump", set_eFusedump_Proc},
+ {"efuseLoadFromBin", set_eFuseLoadFromBin_Proc},
+#endif // RT30xx //
+//2008/09/11:KH add to support efuse-->
+ {NULL,}
+};
+
+
+VOID RTMPAddKey(
+ IN PRTMP_ADAPTER pAd,
+ IN PNDIS_802_11_KEY pKey)
+{
+ ULONG KeyIdx;
+ MAC_TABLE_ENTRY *pEntry;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey ------>\n"));
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ if (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ NdisZeroMemory(pAd->StaCfg.PMK, 32);
+ NdisMoveMemory(pAd->StaCfg.PMK, pKey->KeyMaterial, pKey->KeyLength);
+ goto end;
+ }
+ // Update PTK
+ NdisZeroMemory(&pAd->SharedKey[BSS0][0], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][0].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][0].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+
+ // Decide its ChiperAlg
+ if (pAd->StaCfg.PairCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.PairCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_AES;
+ else
+ pAd->SharedKey[BSS0][0].CipherAlg = CIPHER_NONE;
+
+ // Update these related information to MAC_TABLE_ENTRY
+ pEntry = &pAd->MacTab.Content[BSSID_WCID];
+ NdisMoveMemory(pEntry->PairwiseKey.Key, pAd->SharedKey[BSS0][0].Key, LEN_TKIP_EK);
+ NdisMoveMemory(pEntry->PairwiseKey.RxMic, pAd->SharedKey[BSS0][0].RxMic, LEN_TKIP_RXMICK);
+ NdisMoveMemory(pEntry->PairwiseKey.TxMic, pAd->SharedKey[BSS0][0].TxMic, LEN_TKIP_TXMICK);
+ pEntry->PairwiseKey.CipherAlg = pAd->SharedKey[BSS0][0].CipherAlg;
+
+ // Update pairwise key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pAd->SharedKey[BSS0][0].Key,
+ pAd->SharedKey[BSS0][0].TxMic,
+ pAd->SharedKey[BSS0][0].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ 0,
+ pAd->SharedKey[BSS0][0].CipherAlg,
+ pEntry);
+
+ if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+ {
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ }
+ }
+ else
+ {
+ // Update GTK
+ pAd->StaCfg.DefaultKeyId = (pKey->KeyIndex & 0xFF);
+ NdisZeroMemory(&pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId], sizeof(CIPHER_KEY));
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key, pKey->KeyMaterial, LEN_TKIP_EK);
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+ else
+#endif // WPA_SUPPLICANT_SUPPORT //
+ {
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic, pKey->KeyMaterial + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic, pKey->KeyMaterial + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ }
+
+ // Update Shared Key CipherAlg
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_NONE;
+ if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption2Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_TKIP;
+ else if (pAd->StaCfg.GroupCipher == Ndis802_11Encryption3Enabled)
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg = CIPHER_AES;
+
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].Key,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].TxMic,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].RxMic);
+
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAd,
+ BSS0,
+ pAd->StaCfg.DefaultKeyId,
+ pAd->SharedKey[BSS0][pAd->StaCfg.DefaultKeyId].CipherAlg,
+ NULL);
+
+ // set 802.1x port control
+ //pAd->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAd);
+
+ // Indicate Connected for GUI
+ pAd->IndicateMediaState = NdisMediaStateConnected;
+ }
+ }
+ else // dynamic WEP from wpa_supplicant
+ {
+ UCHAR CipherAlg;
+ PUCHAR Key;
+
+ if(pKey->KeyLength == 32)
+ goto end;
+
+ KeyIdx = pKey->KeyIndex & 0x0fffffff;
+
+ if (KeyIdx < 4)
+ {
+ // it is a default shared key, for Pairwise key setting
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ pEntry = MacTableLookup(pAd, pKey->BSSID);
+
+ if (pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RTMPAddKey: Set Pair-wise Key\n"));
+
+ // set key material and key length
+ pEntry->PairwiseKey.KeyLen = (UCHAR)pKey->KeyLength;
+ NdisMoveMemory(pEntry->PairwiseKey.Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ // set Cipher type
+ if (pKey->KeyLength == 5)
+ pEntry->PairwiseKey.CipherAlg = CIPHER_WEP64;
+ else
+ pEntry->PairwiseKey.CipherAlg = CIPHER_WEP128;
+
+ // Add Pair-wise key to Asic
+ AsicAddPairwiseKeyEntry(
+ pAd,
+ pEntry->Addr,
+ (UCHAR)pEntry->Aid,
+ &pEntry->PairwiseKey);
+
+ // update WCID attribute table and IVEIV table for this entry
+ RTMPAddWcidAttributeEntry(
+ pAd,
+ BSS0,
+ KeyIdx, // The value may be not zero
+ pEntry->PairwiseKey.CipherAlg,
+ pEntry);
+
+ }
+ }
+ else
+ {
+ // Default key for tx (shared key)
+ pAd->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+
+ // set key material and key length
+ pAd->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pKey->KeyLength;
+ NdisMoveMemory(pAd->SharedKey[BSS0][KeyIdx].Key, &pKey->KeyMaterial, pKey->KeyLength);
+
+ // Set Ciper type
+ if (pKey->KeyLength == 5)
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP64;
+ else
+ pAd->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_WEP128;
+
+ CipherAlg = pAd->SharedKey[BSS0][KeyIdx].CipherAlg;
+ Key = pAd->SharedKey[BSS0][KeyIdx].Key;
+
+ // Set Group key material to Asic
+ AsicAddSharedKeyEntry(pAd, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+ // Update WCID attribute table and IVEIV table for this group key table
+ RTMPAddWcidAttributeEntry(pAd, BSS0, KeyIdx, CipherAlg, NULL);
+
+ }
+ }
+ }
+end:
+ return;
+}
+
+char * rtstrchr(const char * s, int c)
+{
+ for(; *s != (char) c; ++s)
+ if (*s == '\0')
+ return NULL;
+ return (char *) s;
+}
+
+/*
+This is required for LinEX2004/kernel2.6.7 to provide iwlist scanning function
+*/
+
+int
+rt_ioctl_giwname(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+// PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+#ifdef RT2870
+ strncpy(name, "RT2870 Wireless", IFNAMSIZ);
+#endif // RT2870 //
+ return 0;
+}
+
+int rt_ioctl_siwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ int chan = -1;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+
+ if (freq->e > 1)
+ return -EINVAL;
+
+ if((freq->e == 0) && (freq->m <= 1000))
+ chan = freq->m; // Setting by channel number
+ else
+ MAP_KHZ_TO_CHANNEL_ID( (freq->m /100) , chan); // Setting by frequency - search the table , like 2.412G, 2.422G,
+
+ if (ChannelSanity(pAdapter, chan) == TRUE)
+ {
+ pAdapter->CommonCfg.Channel = chan;
+ DBGPRINT(RT_DEBUG_ERROR, ("==>rt_ioctl_siwfreq::SIOCSIWFREQ[cmd=0x%x] (Channel=%d)\n", SIOCSIWFREQ, pAdapter->CommonCfg.Channel));
+ }
+ else
+ return -EINVAL;
+
+ return 0;
+}
+int rt_ioctl_giwfreq(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ PRTMP_ADAPTER pAdapter;
+ UCHAR ch;
+ ULONG m;
+
+ if (dev->priv_flags == INT_MAIN)
+ {
+ pAdapter = dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = dev->ml_priv;
+ pAdapter = pVirtualAd->RtmpDev->ml_priv;
+ }
+
+ if (pAdapter == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ ch = pAdapter->CommonCfg.Channel;
+
+ DBGPRINT(RT_DEBUG_TRACE,("==>rt_ioctl_giwfreq %d\n", ch));
+
+ MAP_CHANNEL_ID_TO_KHZ(ch, m);
+ freq->m = m * 100;
+ freq->e = 1;
+ return 0;
+}
+
+int rt_ioctl_siwmode(struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ switch (*mode)
+ {
+ case IW_MODE_ADHOC:
+ Set_NetworkType_Proc(pAdapter, "Adhoc");
+ break;
+ case IW_MODE_INFRA:
+ Set_NetworkType_Proc(pAdapter, "Infra");
+ break;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
+ case IW_MODE_MONITOR:
+ Set_NetworkType_Proc(pAdapter, "Monitor");
+ break;
+#endif
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_siwmode::SIOCSIWMODE (unknown %d)\n", *mode));
+ return -EINVAL;
+ }
+
+ // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+
+ return 0;
+}
+
+int rt_ioctl_giwmode(struct net_device *dev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ if (ADHOC_ON(pAdapter))
+ *mode = IW_MODE_ADHOC;
+ else if (INFRA_ON(pAdapter))
+ *mode = IW_MODE_INFRA;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20))
+ else if (MONITOR_ON(pAdapter))
+ {
+ *mode = IW_MODE_MONITOR;
+ }
+#endif
+ else
+ *mode = IW_MODE_AUTO;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("==>rt_ioctl_giwmode(mode=%d)\n", *mode));
+ return 0;
+}
+
+int rt_ioctl_siwsens(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ return 0;
+}
+
+int rt_ioctl_giwsens(struct net_device *dev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ return 0;
+}
+
+int rt_ioctl_giwrange(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ struct iw_range *range = (struct iw_range *) extra;
+ u16 val;
+ int i;
+
+ DBGPRINT(RT_DEBUG_TRACE ,("===>rt_ioctl_giwrange\n"));
+ data->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ range->txpower_capa = IW_TXPOW_DBM;
+
+ if (INFRA_ON(pAdapter)||ADHOC_ON(pAdapter))
+ {
+ range->min_pmp = 1 * 1024;
+ range->max_pmp = 65535 * 1024;
+ range->min_pmt = 1 * 1024;
+ range->max_pmt = 1000 * 1024;
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_TIMEOUT;
+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT |
+ IW_POWER_UNICAST_R | IW_POWER_ALL_R;
+ }
+
+ range->we_version_compiled = WIRELESS_EXT;
+ range->we_version_source = 14;
+
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->min_retry = 0;
+ range->max_retry = 255;
+
+ range->num_channels = pAdapter->ChannelListNum;
+
+ val = 0;
+ for (i = 1; i <= range->num_channels; i++)
+ {
+ u32 m;
+ range->freq[val].i = pAdapter->ChannelList[i-1].Channel;
+ MAP_CHANNEL_ID_TO_KHZ(pAdapter->ChannelList[i-1].Channel, m);
+ range->freq[val].m = m * 100; /* HZ */
+
+ range->freq[val].e = 1;
+ val++;
+ if (val == IW_MAX_FREQUENCIES)
+ break;
+ }
+ range->num_frequency = val;
+
+ range->max_qual.qual = 100; /* what is correct max? This was not
+ * documented exactly. At least
+ * 69 has been observed. */
+ range->max_qual.level = 0; /* dB */
+ range->max_qual.noise = 0; /* dB */
+
+ /* What would be suitable values for "average/typical" qual? */
+ range->avg_qual.qual = 20;
+ range->avg_qual.level = -60;
+ range->avg_qual.noise = -95;
+ range->sensitivity = 3;
+
+ range->max_encoding_tokens = NR_WEP_KEYS;
+ range->num_encoding_sizes = 2;
+ range->encoding_size[0] = 5;
+ range->encoding_size[1] = 13;
+
+ range->min_rts = 0;
+ range->max_rts = 2347;
+ range->min_frag = 256;
+ range->max_frag = 2346;
+
+#if WIRELESS_EXT > 17
+ /* IW_ENC_CAPA_* bit field */
+ range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
+ IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+#endif
+
+ return 0;
+}
+
+int rt_ioctl_siwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ NDIS_802_11_MAC_ADDRESS Bssid;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+ // Prevent to connect AP again in STAMlmePeriodicExec
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+
+ memset(Bssid, 0, MAC_ADDR_LEN);
+ memcpy(Bssid, ap_addr->sa_data, MAC_ADDR_LEN);
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID,
+ sizeof(NDIS_802_11_MAC_ADDRESS),
+ (VOID *)&Bssid);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCSIWAP %02x:%02x:%02x:%02x:%02x:%02x\n",
+ Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+
+ return 0;
+}
+
+int rt_ioctl_giwap(struct net_device *dev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+ {
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, &pAdapter->CommonCfg.Bssid, ETH_ALEN);
+ }
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // Add for RT2870
+ else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, &pAdapter->MlmeAux.Bssid, ETH_ALEN);
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIWAP(=EMPTY)\n"));
+ return -ENOTCONN;
+ }
+
+ return 0;
+}
+
+/*
+ * Units are in db above the noise floor. That means the
+ * rssi values reported in the tx/rx descriptors in the
+ * driver are the SNR expressed in db.
+ *
+ * If you assume that the noise floor is -95, which is an
+ * excellent assumption 99.5 % of the time, then you can
+ * derive the absolute signal level (i.e. -95 + rssi).
+ * There are some other slight factors to take into account
+ * depending on whether the rssi measurement is from 11b,
+ * 11g, or 11a. These differences are at most 2db and
+ * can be documented.
+ *
+ * NB: various calculations are based on the orinoco/wavelan
+ * drivers for compatibility
+ */
+static void set_quality(PRTMP_ADAPTER pAdapter,
+ struct iw_quality *iq,
+ signed char rssi)
+{
+ __u8 ChannelQuality;
+
+ // Normalize Rssi
+ if (rssi >= -50)
+ ChannelQuality = 100;
+ else if (rssi >= -80) // between -50 ~ -80dbm
+ ChannelQuality = (__u8)(24 + ((rssi + 80) * 26)/10);
+ else if (rssi >= -90) // between -80 ~ -90dbm
+ ChannelQuality = (__u8)((rssi + 90) * 26)/10;
+ else
+ ChannelQuality = 0;
+
+ iq->qual = (__u8)ChannelQuality;
+
+ iq->level = (__u8)(rssi);
+ iq->noise = (pAdapter->BbpWriteLatch[66] > pAdapter->BbpTuning.FalseCcaUpperThreshold) ? ((__u8)pAdapter->BbpTuning.FalseCcaUpperThreshold) : ((__u8) pAdapter->BbpWriteLatch[66]); // noise level (dBm)
+ iq->noise += 256 - 143;
+ iq->updated = pAdapter->iw_stats.qual.updated;
+}
+
+int rt_ioctl_iwaplist(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ struct sockaddr addr[IW_MAX_AP];
+ struct iw_quality qual[IW_MAX_AP];
+ int i;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ data->length = 0;
+ return 0;
+ //return -ENETDOWN;
+ }
+
+ for (i = 0; i <IW_MAX_AP ; i++)
+ {
+ if (i >= pAdapter->ScanTab.BssNr)
+ break;
+ addr[i].sa_family = ARPHRD_ETHER;
+ memcpy(addr[i].sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
+ set_quality(pAdapter, &qual[i], pAdapter->ScanTab.BssEntry[i].Rssi);
+ }
+ data->length = i;
+ memcpy(extra, &addr, i*sizeof(addr[0]));
+ data->flags = 1; /* signal quality present (sort of) */
+ memcpy(extra + i*sizeof(addr[0]), &qual, i*sizeof(qual[i]));
+
+ return 0;
+}
+
+#ifdef SIOCGIWSCAN
+int rt_ioctl_siwscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ ULONG Now;
+ int Status = NDIS_STATUS_SUCCESS;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (MONITOR_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
+ return -EINVAL;
+ }
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+ {
+ pAdapter->StaCfg.WpaSupplicantScanCount++;
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ return 0;
+ do{
+ Now = jiffies;
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if ((pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE) &&
+ (pAdapter->StaCfg.WpaSupplicantScanCount > 3))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! WpaSupplicantScanCount > 3\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+ ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) &&
+ (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+ // Reset allowed scan retries
+ pAdapter->StaCfg.ScanCnt = 0;
+ pAdapter->StaCfg.LastScanTime = Now;
+
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID_LIST_SCAN,
+ 0,
+ NULL);
+
+ Status = NDIS_STATUS_SUCCESS;
+ RT28XX_MLME_HANDLER(pAdapter);
+ }while(0);
+ return 0;
+}
+
+int rt_ioctl_giwscan(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ int i=0;
+ char *current_ev = extra, *previous_ev = extra;
+ char *end_buf;
+ char *current_val, custom[MAX_CUSTOM_LEN] = {0};
+#ifndef IWEVGENIE
+ char idx;
+#endif // IWEVGENIE //
+ struct iw_event iwe;
+
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ /*
+ * Still scanning, indicate the caller should try again.
+ */
+ return -EAGAIN;
+ }
+
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAdapter->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+ {
+ pAdapter->StaCfg.WpaSupplicantScanCount = 0;
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ if (pAdapter->ScanTab.BssNr == 0)
+ {
+ data->length = 0;
+ return 0;
+ }
+
+#if WIRELESS_EXT >= 17
+ if (data->length > 0)
+ end_buf = extra + data->length;
+ else
+ end_buf = extra + IW_SCAN_MAX_DATA;
+#else
+ end_buf = extra + IW_SCAN_MAX_DATA;
+#endif
+
+ for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+ {
+ if (current_ev >= end_buf)
+ {
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+ //MAC address
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWAP;
+ iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe.u.ap_addr.sa_data, &pAdapter->ScanTab.BssEntry[i].Bssid, ETH_ALEN);
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ /*
+ Protocol:
+ it will show scanned AP's WirelessMode .
+ it might be
+ 802.11a
+ 802.11a/n
+ 802.11g/n
+ 802.11b/g/n
+ 802.11g
+ 802.11b/g
+ */
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWNAME;
+
+
+ {
+ PBSS_ENTRY pBssEntry=&pAdapter->ScanTab.BssEntry[i];
+ BOOLEAN isGonly=FALSE;
+ int rateCnt=0;
+
+ if (pBssEntry->Channel>14)
+ {
+ if (pBssEntry->HtCapabilityLen!=0)
+ strcpy(iwe.u.name,"802.11a/n");
+ else
+ strcpy(iwe.u.name,"802.11a");
+ }
+ else
+ {
+ /*
+ if one of non B mode rate is set supported rate . it mean G only.
+ */
+ for (rateCnt=0;rateCnt<pBssEntry->SupRateLen;rateCnt++)
+ {
+ /*
+ 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only.
+ */
+ if (pBssEntry->SupRate[rateCnt]==140 || pBssEntry->SupRate[rateCnt]==146 || pBssEntry->SupRate[rateCnt]>=152)
+ isGonly=TRUE;
+ }
+
+ for (rateCnt=0;rateCnt<pBssEntry->ExtRateLen;rateCnt++)
+ {
+ if (pBssEntry->ExtRate[rateCnt]==140 || pBssEntry->ExtRate[rateCnt]==146 || pBssEntry->ExtRate[rateCnt]>=152)
+ isGonly=TRUE;
+ }
+
+
+ if (pBssEntry->HtCapabilityLen!=0)
+ {
+ if (isGonly==TRUE)
+ strcpy(iwe.u.name,"802.11g/n");
+ else
+ strcpy(iwe.u.name,"802.11b/g/n");
+ }
+ else
+ {
+ if (isGonly==TRUE)
+ strcpy(iwe.u.name,"802.11g");
+ else
+ {
+ if (pBssEntry->SupRateLen==4 && pBssEntry->ExtRateLen==0)
+ strcpy(iwe.u.name,"802.11b");
+ else
+ strcpy(iwe.u.name,"802.11b/g");
+ }
+ }
+ }
+ }
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //ESSID
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWESSID;
+ iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].SsidLen;
+ iwe.u.data.flags = 1;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, pAdapter->ScanTab.BssEntry[i].Ssid);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Network Type
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWMODE;
+ if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11IBSS)
+ {
+ iwe.u.mode = IW_MODE_ADHOC;
+ }
+ else if (pAdapter->ScanTab.BssEntry[i].BssType == Ndis802_11Infrastructure)
+ {
+ iwe.u.mode = IW_MODE_INFRA;
+ }
+ else
+ {
+ iwe.u.mode = IW_MODE_AUTO;
+ }
+ iwe.len = IW_EV_UINT_LEN;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Channel and Frequency
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWFREQ;
+ if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+ iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+ else
+ iwe.u.freq.m = pAdapter->ScanTab.BssEntry[i].Channel;
+ iwe.u.freq.e = 0;
+ iwe.u.freq.i = 0;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Add quality statistics
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = IWEVQUAL;
+ iwe.u.qual.level = 0;
+ iwe.u.qual.noise = 0;
+ set_quality(pAdapter, &iwe.u.qual, pAdapter->ScanTab.BssEntry[i].Rssi);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Encyption key
+ //================================
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWENCODE;
+ if (CAP_IS_PRIVACY_ON (pAdapter->ScanTab.BssEntry[i].CapabilityInfo ))
+ iwe.u.data.flags =IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe.u.data.flags = IW_ENCODE_DISABLED;
+
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,&iwe, (char *)pAdapter->SharedKey[BSS0][(iwe.u.data.flags & IW_ENCODE_INDEX)-1].Key);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+
+ //Bit Rate
+ //================================
+ if (pAdapter->ScanTab.BssEntry[i].SupRateLen)
+ {
+ UCHAR tmpRate = pAdapter->ScanTab.BssEntry[i].SupRate[pAdapter->ScanTab.BssEntry[i].SupRateLen-1];
+ memset(&iwe, 0, sizeof(iwe));
+ iwe.cmd = SIOCGIWRATE;
+ current_val = current_ev + IW_EV_LCP_LEN;
+ if (tmpRate == 0x82)
+ iwe.u.bitrate.value = 1 * 1000000;
+ else if (tmpRate == 0x84)
+ iwe.u.bitrate.value = 2 * 1000000;
+ else if (tmpRate == 0x8B)
+ iwe.u.bitrate.value = 5.5 * 1000000;
+ else if (tmpRate == 0x96)
+ iwe.u.bitrate.value = 11 * 1000000;
+ else
+ iwe.u.bitrate.value = (tmpRate/2) * 1000000;
+
+ iwe.u.bitrate.disabled = 0;
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf, &iwe,
+ IW_EV_PARAM_LEN);
+
+ if((current_val-current_ev)>IW_EV_LCP_LEN)
+ current_ev = current_val;
+ else
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+#ifdef IWEVGENIE
+ //WPA IE
+ if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
+ {
+ memset(&iwe, 0, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].WpaIE.IE[0]),
+ pAdapter->ScanTab.BssEntry[i].WpaIE.IELen);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].WpaIE.IELen;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+ //WPA2 IE
+ if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
+ {
+ memset(&iwe, 0, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ memcpy(custom, &(pAdapter->ScanTab.BssEntry[i].RsnIE.IE[0]),
+ pAdapter->ScanTab.BssEntry[i].RsnIE.IELen);
+ iwe.cmd = IWEVGENIE;
+ iwe.u.data.length = pAdapter->ScanTab.BssEntry[i].RsnIE.IELen;
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+#else
+ //WPA IE
+ //================================
+ if (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen > 0)
+ {
+ NdisZeroMemory(&iwe, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].WpaIE.IELen * 2) + 7;
+ NdisMoveMemory(custom, "wpa_ie=", 7);
+ for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].WpaIE.IELen; idx++)
+ sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].WpaIE.IE[idx]);
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+
+ //WPA2 IE
+ if (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen > 0)
+ {
+ NdisZeroMemory(&iwe, sizeof(iwe));
+ memset(&custom[0], 0, MAX_CUSTOM_LEN);
+ iwe.cmd = IWEVCUSTOM;
+ iwe.u.data.length = (pAdapter->ScanTab.BssEntry[i].RsnIE.IELen * 2) + 7;
+ NdisMoveMemory(custom, "rsn_ie=", 7);
+ for (idx = 0; idx < pAdapter->ScanTab.BssEntry[i].RsnIE.IELen; idx++)
+ sprintf(custom, "%s%02x", custom, pAdapter->ScanTab.BssEntry[i].RsnIE.IE[idx]);
+ previous_ev = current_ev;
+ current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom);
+ if (current_ev == previous_ev)
+#if WIRELESS_EXT >= 17
+ return -E2BIG;
+#else
+ break;
+#endif
+ }
+#endif // IWEVGENIE //
+ }
+
+ data->length = current_ev - extra;
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+ DBGPRINT(RT_DEBUG_ERROR ,("===>rt_ioctl_giwscan. %d(%d) BSS returned, data->length = %d\n",i , pAdapter->ScanTab.BssNr, data->length));
+ return 0;
+}
+#endif
+
+int rt_ioctl_siwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (data->flags)
+ {
+ PCHAR pSsidString = NULL;
+
+ // Includes null character.
+ if (data->length > (IW_ESSID_MAX_SIZE + 1))
+ return -E2BIG;
+
+ pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
+ if (pSsidString)
+ {
+ NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+ NdisMoveMemory(pSsidString, essid, data->length);
+ if (Set_SSID_Proc(pAdapter, pSsidString) == FALSE)
+ return -EINVAL;
+ }
+ else
+ return -ENOMEM;
+ }
+ else
+ {
+ // ANY ssid
+ if (Set_SSID_Proc(pAdapter, "") == FALSE)
+ return -EINVAL;
+ }
+ return 0;
+}
+
+int rt_ioctl_giwessid(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *essid)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ data->flags = 1;
+ if (MONITOR_ON(pAdapter))
+ {
+ data->length = 0;
+ return 0;
+ }
+
+ if (OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE ,("MediaState is connected\n"));
+ data->length = pAdapter->CommonCfg.SsidLen;
+ memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+ }
+#ifdef RT2870
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // Add for RT2870
+ else if (pAdapter->StaCfg.WpaSupplicantUP != WPA_SUPPLICANT_DISABLE)
+ {
+ data->length = pAdapter->CommonCfg.SsidLen;
+ memcpy(essid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen);
+ }
+#endif // WPA_SUPPLICANT_SUPPORT //
+#endif // RT2870 //
+ else
+ {//the ANY ssid was specified
+ data->length = 0;
+ DBGPRINT(RT_DEBUG_TRACE ,("MediaState is not connected, ess\n"));
+ }
+
+ return 0;
+
+}
+
+int rt_ioctl_siwnickn(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *nickname)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE ,("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (data->length > IW_ESSID_MAX_SIZE)
+ return -EINVAL;
+
+ memset(pAdapter->nickname, 0, IW_ESSID_MAX_SIZE + 1);
+ memcpy(pAdapter->nickname, nickname, data->length);
+
+
+ return 0;
+}
+
+int rt_ioctl_giwnickn(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *nickname)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ if (data->length > strlen(pAdapter->nickname) + 1)
+ data->length = strlen(pAdapter->nickname) + 1;
+ if (data->length > 0) {
+ memcpy(nickname, pAdapter->nickname, data->length-1);
+ nickname[data->length-1] = '\0';
+ }
+ return 0;
+}
+
+int rt_ioctl_siwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ u16 val;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (rts->disabled)
+ val = MAX_RTS_THRESHOLD;
+ else if (rts->value < 0 || rts->value > MAX_RTS_THRESHOLD)
+ return -EINVAL;
+ else if (rts->value == 0)
+ val = MAX_RTS_THRESHOLD;
+ else
+ val = rts->value;
+
+ if (val != pAdapter->CommonCfg.RtsThreshold)
+ pAdapter->CommonCfg.RtsThreshold = val;
+
+ return 0;
+}
+
+int rt_ioctl_giwrts(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ rts->value = pAdapter->CommonCfg.RtsThreshold;
+ rts->disabled = (rts->value == MAX_RTS_THRESHOLD);
+ rts->fixed = 1;
+
+ return 0;
+}
+
+int rt_ioctl_siwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ u16 val;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (frag->disabled)
+ val = MAX_FRAG_THRESHOLD;
+ else if (frag->value >= MIN_FRAG_THRESHOLD || frag->value <= MAX_FRAG_THRESHOLD)
+ val = __cpu_to_le16(frag->value & ~0x1); /* even numbers only */
+ else if (frag->value == 0)
+ val = MAX_FRAG_THRESHOLD;
+ else
+ return -EINVAL;
+
+ pAdapter->CommonCfg.FragmentThreshold = val;
+ return 0;
+}
+
+int rt_ioctl_giwfrag(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ frag->value = pAdapter->CommonCfg.FragmentThreshold;
+ frag->disabled = (frag->value == MAX_FRAG_THRESHOLD);
+ frag->fixed = 1;
+
+ return 0;
+}
+
+#define MAX_WEP_KEY_SIZE 13
+#define MIN_WEP_KEY_SIZE 5
+int rt_ioctl_siwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if ((erq->length == 0) &&
+ (erq->flags & IW_ENCODE_DISABLED))
+ {
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ goto done;
+ }
+ else if (erq->flags & IW_ENCODE_RESTRICTED || erq->flags & IW_ENCODE_OPEN)
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ if (erq->flags & IW_ENCODE_RESTRICTED)
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ else
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ }
+
+ if (erq->length > 0)
+ {
+ int keyIdx = (erq->flags & IW_ENCODE_INDEX) - 1;
+ /* Check the size of the key */
+ if (erq->length > MAX_WEP_KEY_SIZE)
+ {
+ return -EINVAL;
+ }
+ /* Check key index */
+ if ((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
+ {
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::Wrong keyIdx=%d! Using default key instead (%d)\n",
+ keyIdx, pAdapter->StaCfg.DefaultKeyId));
+
+ //Using default key
+ keyIdx = pAdapter->StaCfg.DefaultKeyId;
+ }
+ else
+ {
+ pAdapter->StaCfg.DefaultKeyId=keyIdx;
+ }
+
+ NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
+
+ if (erq->length == MAX_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
+ }
+ else if (erq->length == MIN_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
+ }
+ else
+ /* Disable the key */
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
+
+ /* Check if the key is not marked as invalid */
+ if(!(erq->flags & IW_ENCODE_NOKEY))
+ {
+ /* Copy the key in the driver */
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, extra, erq->length);
+ }
+ }
+ else
+ {
+ /* Do we want to just set the transmit key index ? */
+ int index = (erq->flags & IW_ENCODE_INDEX) - 1;
+ if ((index >= 0) && (index < 4))
+ {
+ pAdapter->StaCfg.DefaultKeyId = index;
+ }
+ else
+ /* Don't complain if only change the mode */
+ if(!erq->flags & IW_ENCODE_MODE)
+ {
+ return -EINVAL;
+ }
+ }
+
+done:
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::erq->flags=%x\n",erq->flags));
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::AuthMode=%x\n",pAdapter->StaCfg.AuthMode));
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::DefaultKeyId=%x, KeyLen = %d\n",pAdapter->StaCfg.DefaultKeyId , pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen));
+ DBGPRINT(RT_DEBUG_TRACE ,("==>rt_ioctl_siwencode::WepStatus=%x\n",pAdapter->StaCfg.WepStatus));
+ return 0;
+}
+
+int
+rt_ioctl_giwencode(struct net_device *dev,
+ struct iw_request_info *info,
+ struct iw_point *erq, char *key)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ int kid;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ kid = erq->flags & IW_ENCODE_INDEX;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_giwencode %d\n", erq->flags & IW_ENCODE_INDEX));
+
+ if (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled)
+ {
+ erq->length = 0;
+ erq->flags = IW_ENCODE_DISABLED;
+ }
+ else if ((kid > 0) && (kid <=4))
+ {
+ // copy wep key
+ erq->flags = kid ; /* NB: base 1 */
+ if (erq->length > pAdapter->SharedKey[BSS0][kid-1].KeyLen)
+ erq->length = pAdapter->SharedKey[BSS0][kid-1].KeyLen;
+ memcpy(key, pAdapter->SharedKey[BSS0][kid-1].Key, erq->length);
+ //if ((kid == pAdapter->PortCfg.DefaultKeyId))
+ //erq->flags |= IW_ENCODE_ENABLED; /* XXX */
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+ erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
+ else
+ erq->flags |= IW_ENCODE_OPEN; /* XXX */
+
+ }
+ else if (kid == 0)
+ {
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+ erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
+ else
+ erq->flags |= IW_ENCODE_OPEN; /* XXX */
+ erq->length = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
+ memcpy(key, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, erq->length);
+ // copy default key ID
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared)
+ erq->flags |= IW_ENCODE_RESTRICTED; /* XXX */
+ else
+ erq->flags |= IW_ENCODE_OPEN; /* XXX */
+ erq->flags = pAdapter->StaCfg.DefaultKeyId + 1; /* NB: base 1 */
+ erq->flags |= IW_ENCODE_ENABLED; /* XXX */
+ }
+
+ return 0;
+
+}
+
+static int
+rt_ioctl_setparam(struct net_device *dev, struct iw_request_info *info,
+ void *w, char *extra)
+{
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ PRTMP_ADAPTER pAdapter;
+ POS_COOKIE pObj;
+ char *this_char = extra;
+ char *value;
+ int Status=0;
+
+ if (dev->priv_flags == INT_MAIN)
+ {
+ pAdapter = dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = dev->ml_priv;
+ pAdapter = pVirtualAd->RtmpDev->ml_priv;
+ }
+ pObj = (POS_COOKIE) pAdapter->OS_Cookie;
+
+ if (pAdapter == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ {
+ pObj->ioctl_if_type = INT_MAIN;
+ pObj->ioctl_if = MAIN_MBSSID;
+ }
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (!*this_char)
+ return -EINVAL;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value)
+ return -EINVAL;
+
+ // reject setting nothing besides ANY ssid(ssidLen=0)
+ if (!*value && (strcmp(this_char, "SSID") != 0))
+ return -EINVAL;
+
+ for (PRTMP_PRIVATE_SET_PROC = RTMP_PRIVATE_SUPPORT_PROC; PRTMP_PRIVATE_SET_PROC->name; PRTMP_PRIVATE_SET_PROC++)
+ {
+ if (strcmp(this_char, PRTMP_PRIVATE_SET_PROC->name) == 0)
+ {
+ if(!PRTMP_PRIVATE_SET_PROC->set_proc(pAdapter, value))
+ { //FALSE:Set private failed then return Invalid argument
+ Status = -EINVAL;
+ }
+ break; //Exit for loop.
+ }
+ }
+
+ if(PRTMP_PRIVATE_SET_PROC->name == NULL)
+ { //Not found argument
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>rt_ioctl_setparam:: (iwpriv) Not Support Set Command [%s=%s]\n", this_char, value));
+ }
+
+ return Status;
+}
+
+
+static int
+rt_private_get_statistics(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *wrq, char *extra)
+{
+ INT Status = 0;
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+
+ if (extra == NULL)
+ {
+ wrq->length = 0;
+ return -EIO;
+ }
+
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+ sprintf(extra, "\n\n");
+
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->ate.TxDoneCount);
+ //sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->ate.TxDoneCount);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ sprintf(extra+strlen(extra), "Tx success = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart);
+ sprintf(extra+strlen(extra), "Tx success without retry = %ld\n", (ULONG)pAd->WlanCounters.TransmittedFragmentCount.QuadPart - (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
+ }
+ sprintf(extra+strlen(extra), "Tx success after retry = %ld\n", (ULONG)pAd->WlanCounters.RetryCount.QuadPart);
+ sprintf(extra+strlen(extra), "Tx fail to Rcv ACK after retry = %ld\n", (ULONG)pAd->WlanCounters.FailedCount.QuadPart);
+ sprintf(extra+strlen(extra), "RTS Success Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSSuccessCount.QuadPart);
+ sprintf(extra+strlen(extra), "RTS Fail Rcv CTS = %ld\n", (ULONG)pAd->WlanCounters.RTSFailureCount.QuadPart);
+
+ sprintf(extra+strlen(extra), "Rx success = %ld\n", (ULONG)pAd->WlanCounters.ReceivedFragmentCount.QuadPart);
+ sprintf(extra+strlen(extra), "Rx with CRC = %ld\n", (ULONG)pAd->WlanCounters.FCSErrorCount.QuadPart);
+ sprintf(extra+strlen(extra), "Rx drop due to out of resource = %ld\n", (ULONG)pAd->Counters8023.RxNoBuffer);
+ sprintf(extra+strlen(extra), "Rx duplicate frame = %ld\n", (ULONG)pAd->WlanCounters.FrameDuplicateCount.QuadPart);
+
+ sprintf(extra+strlen(extra), "False CCA (one second) = %ld\n", (ULONG)pAd->RalinkCounters.OneSecFalseCCACnt);
+#ifdef RALINK_ATE
+ if (ATE_ON(pAd))
+ {
+ if (pAd->ate.RxAntennaSel == 0)
+ {
+ sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->ate.LastRssi1 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->ate.LastRssi2 - pAd->BbpRssiToDbmDelta));
+ }
+ else
+ {
+ sprintf(extra+strlen(extra), "RSSI = %ld\n", (LONG)(pAd->ate.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ }
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ sprintf(extra+strlen(extra), "RSSI-A = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi0 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-B (if available) = %ld\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi1 - pAd->BbpRssiToDbmDelta));
+ sprintf(extra+strlen(extra), "RSSI-C (if available) = %ld\n\n", (LONG)(pAd->StaCfg.RssiSample.LastRssi2 - pAd->BbpRssiToDbmDelta));
+ }
+#ifdef WPA_SUPPLICANT_SUPPORT
+ sprintf(extra+strlen(extra), "WpaSupplicantUP = %d\n\n", pAd->StaCfg.WpaSupplicantUP);
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("<== rt_private_get_statistics, wrq->length = %d\n", wrq->length));
+
+ return Status;
+}
+
+#ifdef DOT11_N_SUPPORT
+void getBaInfo(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR pOutBuf)
+{
+ INT i, j;
+ BA_ORI_ENTRY *pOriBAEntry;
+ BA_REC_ENTRY *pRecBAEntry;
+
+ for (i=0; i<MAX_LEN_OF_MAC_TABLE; i++)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAd->MacTab.Content[i];
+ if (((pEntry->ValidAsCLI || pEntry->ValidAsApCli) && (pEntry->Sst == SST_ASSOC))
+ || (pEntry->ValidAsWDS) || (pEntry->ValidAsMesh))
+ {
+ sprintf(pOutBuf, "%s\n%02X:%02X:%02X:%02X:%02X:%02X (Aid = %d) (AP) -\n",
+ pOutBuf,
+ pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2],
+ pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5], pEntry->Aid);
+
+ sprintf(pOutBuf, "%s[Recipient]\n", pOutBuf);
+ for (j=0; j < NUM_OF_TID; j++)
+ {
+ if (pEntry->BARecWcidArray[j] != 0)
+ {
+ pRecBAEntry =&pAd->BATable.BARecEntry[pEntry->BARecWcidArray[j]];
+ sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, LastIndSeq=%d, ReorderingPkts=%d\n", pOutBuf, j, pRecBAEntry->BAWinSize, pRecBAEntry->LastIndSeq, pRecBAEntry->list.qlen);
+ }
+ }
+ sprintf(pOutBuf, "%s\n", pOutBuf);
+
+ sprintf(pOutBuf, "%s[Originator]\n", pOutBuf);
+ for (j=0; j < NUM_OF_TID; j++)
+ {
+ if (pEntry->BAOriWcidArray[j] != 0)
+ {
+ pOriBAEntry =&pAd->BATable.BAOriEntry[pEntry->BAOriWcidArray[j]];
+ sprintf(pOutBuf, "%sTID=%d, BAWinSize=%d, StartSeq=%d, CurTxSeq=%d\n", pOutBuf, j, pOriBAEntry->BAWinSize, pOriBAEntry->Sequence, pEntry->TxSeq[j]);
+ }
+ }
+ sprintf(pOutBuf, "%s\n\n", pOutBuf);
+ }
+ if (strlen(pOutBuf) > (IW_PRIV_SIZE_MASK - 30))
+ break;
+ }
+
+ return;
+}
+#endif // DOT11_N_SUPPORT //
+
+static int
+rt_private_show(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *wrq, char *extra)
+{
+ INT Status = 0;
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ PRTMP_ADAPTER pAd;
+ POS_COOKIE pObj;
+ u32 subcmd = wrq->flags;
+
+ if (dev->priv_flags == INT_MAIN)
+ pAd = dev->ml_priv;
+ else
+ {
+ pVirtualAd = dev->ml_priv;
+ pAd = pVirtualAd->RtmpDev->ml_priv;
+ }
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ if (extra == NULL)
+ {
+ wrq->length = 0;
+ return -EIO;
+ }
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+
+ {
+ pObj->ioctl_if_type = INT_MAIN;
+ pObj->ioctl_if = MAIN_MBSSID;
+ }
+
+ switch(subcmd)
+ {
+
+ case SHOW_CONN_STATUS:
+ if (MONITOR_ON(pAd))
+ {
+#ifdef DOT11_N_SUPPORT
+ if (pAd->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAd->CommonCfg.RegTransmitSetting.field.BW)
+ sprintf(extra, "Monitor Mode(CentralChannel %d)\n", pAd->CommonCfg.CentralChannel);
+ else
+#endif // DOT11_N_SUPPORT //
+ sprintf(extra, "Monitor Mode(Channel %d)\n", pAd->CommonCfg.Channel);
+ }
+ else
+ {
+ if (pAd->IndicateMediaState == NdisMediaStateConnected)
+ {
+ if (INFRA_ON(pAd))
+ {
+ sprintf(extra, "Connected(AP: %s[%02X:%02X:%02X:%02X:%02X:%02X])\n",
+ pAd->CommonCfg.Ssid,
+ pAd->CommonCfg.Bssid[0],
+ pAd->CommonCfg.Bssid[1],
+ pAd->CommonCfg.Bssid[2],
+ pAd->CommonCfg.Bssid[3],
+ pAd->CommonCfg.Bssid[4],
+ pAd->CommonCfg.Bssid[5]);
+ DBGPRINT(RT_DEBUG_TRACE ,("Ssid=%s ,Ssidlen = %d\n",pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen));
+ }
+ else if (ADHOC_ON(pAd))
+ sprintf(extra, "Connected\n");
+ }
+ else
+ {
+ sprintf(extra, "Disconnected\n");
+ DBGPRINT(RT_DEBUG_TRACE ,("ConnStatus is not connected\n"));
+ }
+ }
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ case SHOW_DRVIER_VERION:
+ sprintf(extra, "Driver version-%s, %s %s\n", STA_DRIVER_VERSION, __DATE__, __TIME__ );
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+#ifdef DOT11_N_SUPPORT
+ case SHOW_BA_INFO:
+ getBaInfo(pAd, extra);
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+#endif // DOT11_N_SUPPORT //
+ case SHOW_DESC_INFO:
+ {
+ Show_DescInfo_Proc(pAd, NULL);
+ wrq->length = 0; // 1: size of '\0'
+ }
+ break;
+ case RAIO_OFF:
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ sprintf(extra, "Scanning\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ }
+ pAd->StaCfg.bSwRadio = FALSE;
+ if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+ {
+ pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+ if (pAd->StaCfg.bRadio == FALSE)
+ {
+ MlmeRadioOff(pAd);
+ // Update extra information
+ pAd->ExtraInfo = SW_RADIO_OFF;
+ }
+ }
+ sprintf(extra, "Radio Off\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ case RAIO_ON:
+ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ sprintf(extra, "Scanning\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+ }
+ pAd->StaCfg.bSwRadio = TRUE;
+ //if (pAd->StaCfg.bRadio != (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio))
+ {
+ pAd->StaCfg.bRadio = (pAd->StaCfg.bHwRadio && pAd->StaCfg.bSwRadio);
+ if (pAd->StaCfg.bRadio == TRUE)
+ {
+ MlmeRadioOn(pAd);
+ // Update extra information
+ pAd->ExtraInfo = EXTRA_INFO_CLEAR;
+ }
+ }
+ sprintf(extra, "Radio On\n");
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ break;
+
+
+#ifdef QOS_DLS_SUPPORT
+ case SHOW_DLS_ENTRY_INFO:
+ {
+ Set_DlsEntryInfo_Display_Proc(pAd, NULL);
+ wrq->length = 0; // 1: size of '\0'
+ }
+ break;
+#endif // QOS_DLS_SUPPORT //
+
+ case SHOW_CFG_VALUE:
+ {
+ Status = RTMPShowCfgValue(pAd, wrq->pointer, extra);
+ if (Status == 0)
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ }
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s - unknow subcmd = %d\n", __FUNCTION__, subcmd));
+ break;
+ }
+
+ return Status;
+}
+
+#ifdef SIOCSIWMLME
+int rt_ioctl_siwmlme(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ struct iw_mlme *pMlme = (struct iw_mlme *)wrqu->data.pointer;
+ MLME_QUEUE_ELEM MsgElem;
+ MLME_DISASSOC_REQ_STRUCT DisAssocReq;
+ MLME_DEAUTH_REQ_STRUCT DeAuthReq;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
+
+ if (pMlme == NULL)
+ return -EINVAL;
+
+ switch(pMlme->cmd)
+ {
+#ifdef IW_MLME_DEAUTH
+ case IW_MLME_DEAUTH:
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DEAUTH\n", __FUNCTION__));
+ COPY_MAC_ADDR(DeAuthReq.Addr, pAd->CommonCfg.Bssid);
+ DeAuthReq.Reason = pMlme->reason_code;
+ MsgElem.MsgLen = sizeof(MLME_DEAUTH_REQ_STRUCT);
+ NdisMoveMemory(MsgElem.Msg, &DeAuthReq, sizeof(MLME_DEAUTH_REQ_STRUCT));
+ MlmeDeauthReqAction(pAd, &MsgElem);
+ if (INFRA_ON(pAd))
+ {
+ LinkDown(pAd, FALSE);
+ pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ }
+ break;
+#endif // IW_MLME_DEAUTH //
+#ifdef IW_MLME_DISASSOC
+ case IW_MLME_DISASSOC:
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s - IW_MLME_DISASSOC\n", __FUNCTION__));
+ COPY_MAC_ADDR(DisAssocReq.Addr, pAd->CommonCfg.Bssid);
+ DisAssocReq.Reason = pMlme->reason_code;
+
+ MsgElem.Machine = ASSOC_STATE_MACHINE;
+ MsgElem.MsgType = MT2_MLME_DISASSOC_REQ;
+ MsgElem.MsgLen = sizeof(MLME_DISASSOC_REQ_STRUCT);
+ NdisMoveMemory(MsgElem.Msg, &DisAssocReq, sizeof(MLME_DISASSOC_REQ_STRUCT));
+
+ pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_OID_DISASSOC;
+ MlmeDisassocReqAction(pAd, &MsgElem);
+ break;
+#endif // IW_MLME_DISASSOC //
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("====> %s - Unknow Command\n", __FUNCTION__));
+ break;
+ }
+
+ return 0;
+}
+#endif // SIOCSIWMLME //
+
+#if WIRELESS_EXT > 17
+int rt_ioctl_siwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_WPA_VERSION:
+ if (param->value == IW_AUTH_WPA_VERSION_WPA)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+ if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+ }
+ else if (param->value == IW_AUTH_WPA_VERSION_WPA2)
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_CIPHER_PAIRWISE:
+ if (param->value == IW_AUTH_CIPHER_NONE)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+ param->value == IW_AUTH_CIPHER_WEP104)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+ else if (param->value == IW_AUTH_CIPHER_TKIP)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_CCMP)
+ {
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_PAIRWISE - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_CIPHER_GROUP:
+ if (param->value == IW_AUTH_CIPHER_NONE)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_WEP40 ||
+ param->value == IW_AUTH_CIPHER_WEP104)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_TKIP)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if (param->value == IW_AUTH_CIPHER_CCMP)
+ {
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_CIPHER_GROUP - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_KEY_MGMT:
+ if (param->value == IW_AUTH_KEY_MGMT_802_1X)
+ {
+ if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+ else if (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ pAdapter->StaCfg.IEEE8021X = FALSE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else
+ // WEP 1x
+ pAdapter->StaCfg.IEEE8021X = TRUE;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ }
+ else if (param->value == 0)
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_KEY_MGMT - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+ break;
+ case IW_AUTH_PRIVACY_INVOKED:
+ /*if (param->value == 0)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ }*/
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_PRIVACY_INVOKED - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_DROP_UNENCRYPTED:
+ if (param->value != 0)
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_VERSION - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ if (param->value & IW_AUTH_ALG_SHARED_KEY)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ }
+ else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM)
+ {
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ }
+ else
+ return -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_80211_AUTH_ALG - param->value = %d!\n", __FUNCTION__, param->value));
+ break;
+ case IW_AUTH_WPA_ENABLED:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_AUTH_WPA_ENABLED - Driver supports WPA!(param->value = %d)\n", __FUNCTION__, param->value));
+ break;
+ default:
+ return -EOPNOTSUPP;
+}
+
+ return 0;
+}
+
+int rt_ioctl_giwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_DROP_UNENCRYPTED:
+ param->value = (pAdapter->StaCfg.WepStatus == Ndis802_11WEPDisabled) ? 0 : 1;
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ param->value = (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeShared) ? IW_AUTH_ALG_SHARED_KEY : IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+
+ case IW_AUTH_WPA_ENABLED:
+ param->value = (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) ? 1 : 0;
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_giwauth::param->value = %d!\n", param->value));
+ return 0;
+}
+
+void fnSetCipherKey(
+ IN PRTMP_ADAPTER pAdapter,
+ IN INT keyIdx,
+ IN UCHAR CipherAlg,
+ IN BOOLEAN bGTK,
+ IN struct iw_encode_ext *ext)
+{
+ NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = LEN_TKIP_EK;
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, LEN_TKIP_EK);
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].TxMic, ext->key + LEN_TKIP_EK, LEN_TKIP_TXMICK);
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].RxMic, ext->key + LEN_TKIP_EK + LEN_TKIP_TXMICK, LEN_TKIP_RXMICK);
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CipherAlg;
+
+ // Update group key information to ASIC Shared Key Table
+ AsicAddSharedKeyEntry(pAdapter,
+ BSS0,
+ keyIdx,
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+ pAdapter->SharedKey[BSS0][keyIdx].Key,
+ pAdapter->SharedKey[BSS0][keyIdx].TxMic,
+ pAdapter->SharedKey[BSS0][keyIdx].RxMic);
+
+ if (bGTK)
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAdapter,
+ BSS0,
+ keyIdx,
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+ NULL);
+ else
+ // Update ASIC WCID attribute table and IVEIV table
+ RTMPAddWcidAttributeEntry(pAdapter,
+ BSS0,
+ keyIdx,
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg,
+ &pAdapter->MacTab.Content[BSSID_WCID]);
+}
+
+int rt_ioctl_siwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+ {
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int keyIdx, alg = ext->alg;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if (encoding->flags & IW_ENCODE_DISABLED)
+ {
+ keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ // set BSSID wcid entry of the Pair-wise Key table as no-security mode
+ AsicRemovePairwiseKeyEntry(pAdapter, BSS0, BSSID_WCID);
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = 0;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)keyIdx);
+ NdisZeroMemory(&pAdapter->SharedKey[BSS0][keyIdx], sizeof(CIPHER_KEY));
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::Remove all keys!(encoding->flags = %x)\n", __FUNCTION__, encoding->flags));
+ }
+ else
+ {
+ // Get Key Index and convet to our own defined key index
+ keyIdx = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ if((keyIdx < 0) || (keyIdx >= NR_WEP_KEYS))
+ return -EINVAL;
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ {
+ pAdapter->StaCfg.DefaultKeyId = keyIdx;
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::DefaultKeyId = %d\n", __FUNCTION__, pAdapter->StaCfg.DefaultKeyId));
+ }
+
+ switch (alg) {
+ case IW_ENCODE_ALG_NONE:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_NONE\n", __FUNCTION__));
+ break;
+ case IW_ENCODE_ALG_WEP:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_WEP - ext->key_len = %d, keyIdx = %d\n", __FUNCTION__, ext->key_len, keyIdx));
+ if (ext->key_len == MAX_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MAX_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP128;
+ }
+ else if (ext->key_len == MIN_WEP_KEY_SIZE)
+ {
+ pAdapter->SharedKey[BSS0][keyIdx].KeyLen = MIN_WEP_KEY_SIZE;
+ pAdapter->SharedKey[BSS0][keyIdx].CipherAlg = CIPHER_WEP64;
+ }
+ else
+ return -EINVAL;
+
+ NdisZeroMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, 16);
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][keyIdx].Key, ext->key, ext->key_len);
+ break;
+ case IW_ENCODE_ALG_TKIP:
+ DBGPRINT(RT_DEBUG_TRACE, ("%s::IW_ENCODE_ALG_TKIP - keyIdx = %d, ext->key_len = %d\n", __FUNCTION__, keyIdx, ext->key_len));
+ if (ext->key_len == 32)
+ {
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, FALSE, ext);
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+ {
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ }
+ else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_TKIP, TRUE, ext);
+
+ // set 802.1x port control
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ }
+ else
+ return -EINVAL;
+ break;
+ case IW_ENCODE_ALG_CCMP:
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, FALSE, ext);
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA2)
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ else if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+ {
+ fnSetCipherKey(pAdapter, keyIdx, CIPHER_AES, TRUE, ext);
+
+ // set 802.1x port control
+ //pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ STA_PORT_SECURED(pAdapter);
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+int
+rt_ioctl_giwencodeext(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ PCHAR pKey = NULL;
+ struct iw_point *encoding = &wrqu->encoding;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ int idx, max_key_len;
+
+ DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_giwencodeext\n"));
+
+ max_key_len = encoding->length - sizeof(*ext);
+ if (max_key_len < 0)
+ return -EINVAL;
+
+ idx = encoding->flags & IW_ENCODE_INDEX;
+ if (idx)
+ {
+ if (idx < 1 || idx > 4)
+ return -EINVAL;
+ idx--;
+
+ if ((pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled) ||
+ (pAd->StaCfg.WepStatus == Ndis802_11Encryption3Enabled))
+ {
+ if (idx != pAd->StaCfg.DefaultKeyId)
+ {
+ ext->key_len = 0;
+ return 0;
+ }
+ }
+ }
+ else
+ idx = pAd->StaCfg.DefaultKeyId;
+
+ encoding->flags = idx + 1;
+ memset(ext, 0, sizeof(*ext));
+
+ ext->key_len = 0;
+ switch(pAd->StaCfg.WepStatus) {
+ case Ndis802_11WEPDisabled:
+ ext->alg = IW_ENCODE_ALG_NONE;
+ encoding->flags |= IW_ENCODE_DISABLED;
+ break;
+ case Ndis802_11WEPEnabled:
+ ext->alg = IW_ENCODE_ALG_WEP;
+ if (pAd->SharedKey[BSS0][idx].KeyLen > max_key_len)
+ return -E2BIG;
+ else
+ {
+ ext->key_len = pAd->SharedKey[BSS0][idx].KeyLen;
+ pKey = &(pAd->SharedKey[BSS0][idx].Key[0]);
+ }
+ break;
+ case Ndis802_11Encryption2Enabled:
+ case Ndis802_11Encryption3Enabled:
+ if (pAd->StaCfg.WepStatus == Ndis802_11Encryption2Enabled)
+ ext->alg = IW_ENCODE_ALG_TKIP;
+ else
+ ext->alg = IW_ENCODE_ALG_CCMP;
+
+ if (max_key_len < 32)
+ return -E2BIG;
+ else
+ {
+ ext->key_len = 32;
+ pKey = &pAd->StaCfg.PMK[0];
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ if (ext->key_len && pKey)
+ {
+ encoding->flags |= IW_ENCODE_ENABLED;
+ memcpy(ext->key, pKey, ext->key_len);
+ }
+
+ return 0;
+}
+
+#ifdef SIOCSIWGENIE
+int rt_ioctl_siwgenie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+
+ if (wrqu->data.length > MAX_LEN_OF_RSNIE ||
+ (wrqu->data.length && extra == NULL))
+ return -EINVAL;
+
+ if (wrqu->data.length)
+ {
+ pAd->StaCfg.RSNIE_Len = wrqu->data.length;
+ NdisMoveMemory(&pAd->StaCfg.RSN_IE[0], extra, pAd->StaCfg.RSNIE_Len);
+ }
+ else
+ {
+ pAd->StaCfg.RSNIE_Len = 0;
+ NdisZeroMemory(&pAd->StaCfg.RSN_IE[0], MAX_LEN_OF_RSNIE);
+ }
+
+ return 0;
+}
+#endif // SIOCSIWGENIE //
+
+int rt_ioctl_giwgenie(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+
+ if ((pAd->StaCfg.RSNIE_Len == 0) ||
+ (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA))
+ {
+ wrqu->data.length = 0;
+ return 0;
+ }
+
+#ifdef NATIVE_WPA_SUPPLICANT_SUPPORT
+#ifdef SIOCSIWGENIE
+ if (pAd->StaCfg.WpaSupplicantUP == WPA_SUPPLICANT_ENABLE)
+ {
+ if (wrqu->data.length < pAd->StaCfg.RSNIE_Len)
+ return -E2BIG;
+
+ wrqu->data.length = pAd->StaCfg.RSNIE_Len;
+ memcpy(extra, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+ }
+ else
+#endif // SIOCSIWGENIE //
+#endif // NATIVE_WPA_SUPPLICANT_SUPPORT //
+ {
+ UCHAR RSNIe = IE_WPA;
+
+ if (wrqu->data.length < (pAd->StaCfg.RSNIE_Len + 2)) // ID, Len
+ return -E2BIG;
+ wrqu->data.length = pAd->StaCfg.RSNIE_Len + 2;
+
+ if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2))
+ RSNIe = IE_RSN;
+
+ extra[0] = (char)RSNIe;
+ extra[1] = pAd->StaCfg.RSNIE_Len;
+ memcpy(extra+2, &pAd->StaCfg.RSN_IE[0], pAd->StaCfg.RSNIE_Len);
+ }
+
+ return 0;
+}
+
+int rt_ioctl_siwpmksa(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu,
+ char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ struct iw_pmksa *pPmksa = (struct iw_pmksa *)wrqu->data.pointer;
+ INT CachedIdx = 0, idx = 0;
+
+ if (pPmksa == NULL)
+ return -EINVAL;
+
+ DBGPRINT(RT_DEBUG_TRACE ,("===> rt_ioctl_siwpmksa\n"));
+ switch(pPmksa->cmd)
+ {
+ case IW_PMKSA_FLUSH:
+ NdisZeroMemory(pAd->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_FLUSH\n"));
+ break;
+ case IW_PMKSA_REMOVE:
+ for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
+ {
+ // compare the BSSID
+ if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
+ {
+ NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN);
+ NdisZeroMemory(pAd->StaCfg.SavedPMK[CachedIdx].PMKID, 16);
+ for (idx = CachedIdx; idx < (pAd->StaCfg.SavedPMKNum - 1); idx++)
+ {
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].BSSID[0], &pAd->StaCfg.SavedPMK[idx+1].BSSID[0], MAC_ADDR_LEN);
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[idx].PMKID[0], &pAd->StaCfg.SavedPMK[idx+1].PMKID[0], 16);
+ }
+ pAd->StaCfg.SavedPMKNum--;
+ break;
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_REMOVE\n"));
+ break;
+ case IW_PMKSA_ADD:
+ for (CachedIdx = 0; CachedIdx < pAd->StaCfg.SavedPMKNum; CachedIdx++)
+ {
+ // compare the BSSID
+ if (NdisEqualMemory(pPmksa->bssid.sa_data, pAd->StaCfg.SavedPMK[CachedIdx].BSSID, MAC_ADDR_LEN))
+ break;
+ }
+
+ // Found, replace it
+ if (CachedIdx < PMKID_NO)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
+ pAd->StaCfg.SavedPMKNum++;
+ }
+ // Not found, replace the last one
+ else
+ {
+ // Randomly replace one
+ CachedIdx = (pPmksa->bssid.sa_data[5] % PMKID_NO);
+ DBGPRINT(RT_DEBUG_OFF, ("Update PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].BSSID[0], pPmksa->bssid.sa_data, MAC_ADDR_LEN);
+ NdisMoveMemory(&pAd->StaCfg.SavedPMK[CachedIdx].PMKID[0], pPmksa->pmkid, 16);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - IW_PMKSA_ADD\n"));
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE ,("rt_ioctl_siwpmksa - Unknow Command!!\n"));
+ break;
+ }
+
+ return 0;
+}
+#endif // #if WIRELESS_EXT > 17
+
+#ifdef DBG
+static int
+rt_private_ioctl_bbp(struct net_device *dev, struct iw_request_info *info,
+ struct iw_point *wrq, char *extra)
+ {
+ CHAR *this_char;
+ CHAR *value = NULL;
+ UCHAR regBBP = 0;
+// CHAR arg[255]={0};
+ UINT32 bbpId;
+ UINT32 bbpValue;
+ BOOLEAN bIsPrintAllBBP = FALSE;
+ INT Status = 0;
+ PRTMP_ADAPTER pAdapter = dev->ml_priv;
+
+
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+
+ if (wrq->length > 1) //No parameters.
+ {
+ sprintf(extra, "\n");
+
+ //Parsing Read or Write
+ this_char = wrq->pointer;
+ DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s\n", this_char));
+ if (!*this_char)
+ goto next;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+ DBGPRINT(RT_DEBUG_TRACE, ("this_char=%s, value=%s\n", this_char, value));
+ if (sscanf(this_char, "%d", &(bbpId)) == 1)
+ {
+#ifndef RT30xx
+ if (bbpId <= 136)
+#endif // RT30xx //
+#ifdef RT30xx
+ if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+ {
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
+ }
+ else
+ {//Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Write
+ if ((sscanf(this_char, "%d", &(bbpId)) == 1) && (sscanf(value, "%x", &(bbpValue)) == 1))
+ {
+#ifndef RT30xx
+ if (bbpId <= 136)
+#endif // RT30xx //
+#ifdef RT30xx
+ if (bbpId <= 138) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+ {
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
+ //Read it back for showing
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, bbpId, bbpValue);
+ //Read it back for showing
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X\n", bbpId, bbpId*2, regBBP);
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("msg=%s\n", extra));
+ }
+ else
+ {//Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all bbp
+ bIsPrintAllBBP = TRUE;
+ goto next;
+ }
+ }
+ }
+ else
+ bIsPrintAllBBP = TRUE;
+
+next:
+ if (bIsPrintAllBBP)
+ {
+ memset(extra, 0x00, IW_PRIV_SIZE_MASK);
+ sprintf(extra, "\n");
+#ifndef RT30xx
+ for (bbpId = 0; bbpId <= 136; bbpId++)
+#endif // RT30xx //
+#ifdef RT30xx
+ for (bbpId = 0; bbpId <= 138; bbpId++) // edit by johnli, RF power sequence setup, add BBP R138 for ADC dynamic on/off control
+#endif // RT30xx //
+ {
+ if (strlen(extra) >= (IW_PRIV_SIZE_MASK - 10))
+ break;
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ }
+ else
+#endif // RALINK_ATE //
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+/*
+ sprintf(extra+strlen(extra), "R%02d[0x%02X]:%02X ", bbpId, bbpId*2, regBBP);
+ if (bbpId%5 == 4)
+ sprintf(extra+strlen(extra), "\n");
+*/
+ sprintf(extra+strlen(extra), "%03d = %02X\n", bbpId, regBBP); // edit by johnli, change display format
+ }
+
+ wrq->length = strlen(extra) + 1; // 1: size of '\0'
+ DBGPRINT(RT_DEBUG_TRACE, ("wrq->length = %d\n", wrq->length));
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==rt_private_ioctl_bbp\n\n"));
+
+ return Status;
+}
+#endif // DBG //
+
+int rt_ioctl_siwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ UINT32 rate = wrqu->bitrate.value, fixed = wrqu->bitrate.fixed;
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(rate = %d, fixed = %d)\n", rate, fixed));
+ /* rate = -1 => auto rate
+ rate = X, fixed = 1 => (fixed rate X)
+ */
+ if (rate == -1)
+ {
+ //Auto Rate
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+ pAd->StaCfg.bAutoTxRateSwitch = TRUE;
+ if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
+ (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
+ RTMPSetDesiredRates(pAd, -1);
+
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ }
+ else
+ {
+ if (fixed)
+ {
+ pAd->StaCfg.bAutoTxRateSwitch = FALSE;
+ if ((pAd->CommonCfg.PhyMode <= PHY_11G) ||
+ (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM))
+ RTMPSetDesiredRates(pAd, rate);
+ else
+ {
+ pAd->StaCfg.DesiredTransmitSetting.field.MCS = MCS_AUTO;
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAd);
+#endif // DOT11_N_SUPPORT //
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("rt_ioctl_siwrate::(HtMcs=%d)\n",pAd->StaCfg.DesiredTransmitSetting.field.MCS));
+ }
+ else
+ {
+ // TODO: rate = X, fixed = 0 => (rates <= X)
+ return -EOPNOTSUPP;
+ }
+ }
+
+ return 0;
+}
+
+int rt_ioctl_giwrate(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ PRTMP_ADAPTER pAd = dev->ml_priv;
+ int rate_index = 0, rate_count = 0;
+ HTTRANSMIT_SETTING ht_setting;
+ __s32 ralinkrate[] =
+ {2, 4, 11, 22, // CCK
+ 12, 18, 24, 36, 48, 72, 96, 108, // OFDM
+ 13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, 260, // 20MHz, 800ns GI, MCS: 0 ~ 15
+ 39, 78, 117, 156, 234, 312, 351, 390, // 20MHz, 800ns GI, MCS: 16 ~ 23
+ 27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, // 40MHz, 800ns GI, MCS: 0 ~ 15
+ 81, 162, 243, 324, 486, 648, 729, 810, // 40MHz, 800ns GI, MCS: 16 ~ 23
+ 14, 29, 43, 57, 87, 115, 130, 144, 29, 59, 87, 115, 173, 230, 260, 288, // 20MHz, 400ns GI, MCS: 0 ~ 15
+ 43, 87, 130, 173, 260, 317, 390, 433, // 20MHz, 400ns GI, MCS: 16 ~ 23
+ 30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, // 40MHz, 400ns GI, MCS: 0 ~ 15
+ 90, 180, 270, 360, 540, 720, 810, 900}; // 40MHz, 400ns GI, MCS: 16 ~ 23
+
+ rate_count = sizeof(ralinkrate)/sizeof(__s32);
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+
+ if ((pAd->StaCfg.bAutoTxRateSwitch == FALSE) &&
+ (INFRA_ON(pAd)) &&
+ ((pAd->CommonCfg.PhyMode <= PHY_11G) || (pAd->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE <= MODE_OFDM)))
+ ht_setting.word = pAd->StaCfg.HTPhyMode.word;
+ else
+ ht_setting.word = pAd->MacTab.Content[BSSID_WCID].HTPhyMode.word;
+
+#ifdef DOT11_N_SUPPORT
+ if (ht_setting.field.MODE >= MODE_HTMIX)
+ {
+// rate_index = 12 + ((UCHAR)ht_setting.field.BW *16) + ((UCHAR)ht_setting.field.ShortGI *32) + ((UCHAR)ht_setting.field.MCS);
+ rate_index = 12 + ((UCHAR)ht_setting.field.BW *24) + ((UCHAR)ht_setting.field.ShortGI *48) + ((UCHAR)ht_setting.field.MCS);
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ if (ht_setting.field.MODE == MODE_OFDM)
+ rate_index = (UCHAR)(ht_setting.field.MCS) + 4;
+ else if (ht_setting.field.MODE == MODE_CCK)
+ rate_index = (UCHAR)(ht_setting.field.MCS);
+
+ if (rate_index < 0)
+ rate_index = 0;
+
+ if (rate_index > rate_count)
+ rate_index = rate_count;
+
+ wrqu->bitrate.value = ralinkrate[rate_index] * 500000;
+ wrqu->bitrate.disabled = 0;
+
+ return 0;
+}
+
+static const iw_handler rt_handler[] =
+{
+ (iw_handler) NULL, /* SIOCSIWCOMMIT */
+ (iw_handler) rt_ioctl_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) rt_ioctl_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) rt_ioctl_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) rt_ioctl_siwmode, /* SIOCSIWMODE */
+ (iw_handler) rt_ioctl_giwmode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
+ (iw_handler) rt_ioctl_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
+ (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
+ (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
+ (iw_handler) rt28xx_get_wireless_stats /* kernel code */, /* SIOCGIWSTATS */
+ (iw_handler) NULL, /* SIOCSIWSPY */
+ (iw_handler) NULL, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* SIOCSIWTHRSPY */
+ (iw_handler) NULL, /* SIOCGIWTHRSPY */
+ (iw_handler) rt_ioctl_siwap, /* SIOCSIWAP */
+ (iw_handler) rt_ioctl_giwap, /* SIOCGIWAP */
+#ifdef SIOCSIWMLME
+ (iw_handler) rt_ioctl_siwmlme, /* SIOCSIWMLME */
+#else
+ (iw_handler) NULL, /* SIOCSIWMLME */
+#endif // SIOCSIWMLME //
+ (iw_handler) rt_ioctl_iwaplist, /* SIOCGIWAPLIST */
+#ifdef SIOCGIWSCAN
+ (iw_handler) rt_ioctl_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) rt_ioctl_giwscan, /* SIOCGIWSCAN */
+#else
+ (iw_handler) NULL, /* SIOCSIWSCAN */
+ (iw_handler) NULL, /* SIOCGIWSCAN */
+#endif /* SIOCGIWSCAN */
+ (iw_handler) rt_ioctl_siwessid, /* SIOCSIWESSID */
+ (iw_handler) rt_ioctl_giwessid, /* SIOCGIWESSID */
+ (iw_handler) rt_ioctl_siwnickn, /* SIOCSIWNICKN */
+ (iw_handler) rt_ioctl_giwnickn, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) rt_ioctl_siwrate, /* SIOCSIWRATE */
+ (iw_handler) rt_ioctl_giwrate, /* SIOCGIWRATE */
+ (iw_handler) rt_ioctl_siwrts, /* SIOCSIWRTS */
+ (iw_handler) rt_ioctl_giwrts, /* SIOCGIWRTS */
+ (iw_handler) rt_ioctl_siwfrag, /* SIOCSIWFRAG */
+ (iw_handler) rt_ioctl_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) NULL, /* SIOCSIWTXPOW */
+ (iw_handler) NULL, /* SIOCGIWTXPOW */
+ (iw_handler) NULL, /* SIOCSIWRETRY */
+ (iw_handler) NULL, /* SIOCGIWRETRY */
+ (iw_handler) rt_ioctl_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) rt_ioctl_giwencode, /* SIOCGIWENCODE */
+ (iw_handler) NULL, /* SIOCSIWPOWER */
+ (iw_handler) NULL, /* SIOCGIWPOWER */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+#if WIRELESS_EXT > 17
+ (iw_handler) rt_ioctl_siwgenie, /* SIOCSIWGENIE */
+ (iw_handler) rt_ioctl_giwgenie, /* SIOCGIWGENIE */
+ (iw_handler) rt_ioctl_siwauth, /* SIOCSIWAUTH */
+ (iw_handler) rt_ioctl_giwauth, /* SIOCGIWAUTH */
+ (iw_handler) rt_ioctl_siwencodeext, /* SIOCSIWENCODEEXT */
+ (iw_handler) rt_ioctl_giwencodeext, /* SIOCGIWENCODEEXT */
+ (iw_handler) rt_ioctl_siwpmksa, /* SIOCSIWPMKSA */
+#endif
+};
+
+static const iw_handler rt_priv_handlers[] = {
+ (iw_handler) NULL, /* + 0x00 */
+ (iw_handler) NULL, /* + 0x01 */
+#ifndef CONFIG_AP_SUPPORT
+ (iw_handler) rt_ioctl_setparam, /* + 0x02 */
+#else
+ (iw_handler) NULL, /* + 0x02 */
+#endif // CONFIG_AP_SUPPORT //
+#ifdef DBG
+ (iw_handler) rt_private_ioctl_bbp, /* + 0x03 */
+#else
+ (iw_handler) NULL, /* + 0x03 */
+#endif
+ (iw_handler) NULL, /* + 0x04 */
+ (iw_handler) NULL, /* + 0x05 */
+ (iw_handler) NULL, /* + 0x06 */
+ (iw_handler) NULL, /* + 0x07 */
+ (iw_handler) NULL, /* + 0x08 */
+ (iw_handler) rt_private_get_statistics, /* + 0x09 */
+ (iw_handler) NULL, /* + 0x0A */
+ (iw_handler) NULL, /* + 0x0B */
+ (iw_handler) NULL, /* + 0x0C */
+ (iw_handler) NULL, /* + 0x0D */
+ (iw_handler) NULL, /* + 0x0E */
+ (iw_handler) NULL, /* + 0x0F */
+ (iw_handler) NULL, /* + 0x10 */
+ (iw_handler) rt_private_show, /* + 0x11 */
+ (iw_handler) NULL, /* + 0x12 */
+ (iw_handler) NULL, /* + 0x13 */
+ (iw_handler) NULL, /* + 0x15 */
+ (iw_handler) NULL, /* + 0x17 */
+ (iw_handler) NULL, /* + 0x18 */
+};
+
+const struct iw_handler_def rt28xx_iw_handler_def =
+{
+#define N(a) (sizeof (a) / sizeof (a[0]))
+ .standard = (iw_handler *) rt_handler,
+ .num_standard = sizeof(rt_handler) / sizeof(iw_handler),
+ .private = (iw_handler *) rt_priv_handlers,
+ .num_private = N(rt_priv_handlers),
+ .private_args = (struct iw_priv_args *) privtab,
+ .num_private_args = N(privtab),
+#if IW_HANDLER_VERSION >= 7
+ .get_wireless_stats = rt28xx_get_wireless_stats,
+#endif
+};
+
+INT RTMPSetInformation(
+ IN PRTMP_ADAPTER pAdapter,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ struct iwreq *wrq = (struct iwreq *) rq;
+ NDIS_802_11_SSID Ssid;
+ NDIS_802_11_MAC_ADDRESS Bssid;
+ RT_802_11_PHY_MODE PhyMode;
+ RT_802_11_STA_CONFIG StaConfig;
+ NDIS_802_11_RATES aryRates;
+ RT_802_11_PREAMBLE Preamble;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode = Ndis802_11AuthModeMax;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
+ NDIS_802_11_RTS_THRESHOLD RtsThresh;
+ NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+ NDIS_802_11_POWER_MODE PowerMode;
+ PNDIS_802_11_KEY pKey = NULL;
+ PNDIS_802_11_WEP pWepKey =NULL;
+ PNDIS_802_11_REMOVE_KEY pRemoveKey = NULL;
+ NDIS_802_11_CONFIGURATION Config, *pConfig = NULL;
+ NDIS_802_11_NETWORK_TYPE NetType;
+ ULONG Now;
+ UINT KeyIdx = 0;
+ INT Status = NDIS_STATUS_SUCCESS, MaxPhyMode = PHY_11G;
+ ULONG PowerTemp;
+ BOOLEAN RadioState;
+ BOOLEAN StateMachineTouched = FALSE;
+#ifdef DOT11_N_SUPPORT
+ OID_SET_HT_PHYMODE HT_PhyMode; //11n ,kathy
+#endif // DOT11_N_SUPPORT //
+#ifdef WPA_SUPPLICANT_SUPPORT
+ PNDIS_802_11_PMKID pPmkId = NULL;
+ BOOLEAN IEEE8021xState = FALSE;
+ BOOLEAN IEEE8021x_required_keys = FALSE;
+ UCHAR wpa_supplicant_enable = 0;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef SNMP_SUPPORT
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ ULONG ShortRetryLimit, LongRetryLimit;
+ UCHAR ctmp;
+#endif // SNMP_SUPPORT //
+
+
+#ifdef DOT11_N_SUPPORT
+ MaxPhyMode = PHY_11N_5G;
+#endif // DOT11_N_SUPPORT //
+
+
+ DBGPRINT(RT_DEBUG_TRACE, ("-->RTMPSetInformation(), 0x%08x\n", cmd&0x7FFF));
+ switch(cmd & 0x7FFF) {
+ case RT_OID_802_11_COUNTRY_REGION:
+ if (wrq->u.data.length < sizeof(UCHAR))
+ Status = -EINVAL;
+ // Only avaliable when EEPROM not programming
+ else if (!(pAdapter->CommonCfg.CountryRegion & 0x80) && !(pAdapter->CommonCfg.CountryRegionForABand & 0x80))
+ {
+ ULONG Country;
+ UCHAR TmpPhy;
+
+ Status = copy_from_user(&Country, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->CommonCfg.CountryRegion = (UCHAR)(Country & 0x000000FF);
+ pAdapter->CommonCfg.CountryRegionForABand = (UCHAR)((Country >> 8) & 0x000000FF);
+ TmpPhy = pAdapter->CommonCfg.PhyMode;
+ pAdapter->CommonCfg.PhyMode = 0xff;
+ // Build all corresponding channel information
+ RTMPSetPhyMode(pAdapter, TmpPhy);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_COUNTRY_REGION (A:%d B/G:%d)\n", pAdapter->CommonCfg.CountryRegionForABand,
+ pAdapter->CommonCfg.CountryRegion));
+ }
+ break;
+ case OID_802_11_BSSID_LIST_SCAN:
+ #ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ Now = jiffies;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID_LIST_SCAN, TxCnt = %d \n", pAdapter->RalinkCounters.LastOneSecTotalTxCount));
+
+ if (MONITOR_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is in Monitor Mode now !!!\n"));
+ break;
+ }
+
+ //Benson add 20080527, when radio off, sta don't need to scan
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_RADIO_OFF))
+ break;
+
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Driver is scanning now !!!\n"));
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ Status = NDIS_STATUS_SUCCESS;
+ break;
+ }
+
+ if (pAdapter->RalinkCounters.LastOneSecTotalTxCount > 100)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
+ break;
+ }
+
+ if ((OPSTATUS_TEST_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED)) &&
+ ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK)) &&
+ (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_NOT_SECURED))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! Link UP, Port Not Secured! ignore this set::OID_802_11_BSSID_LIST_SCAN\n"));
+ Status = NDIS_STATUS_SUCCESS;
+ pAdapter->StaCfg.ScanCnt = 99; // Prevent auto scan triggered by this OID
+ break;
+ }
+
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+ // Reset allowed scan retries
+ pAdapter->StaCfg.ScanCnt = 0;
+ pAdapter->StaCfg.LastScanTime = Now;
+
+ pAdapter->StaCfg.bScanReqIsFromWebUI = TRUE;
+ RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS);
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID_LIST_SCAN,
+ 0,
+ NULL);
+
+ Status = NDIS_STATUS_SUCCESS;
+ StateMachineTouched = TRUE;
+ break;
+ case OID_802_11_SSID:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_SSID))
+ Status = -EINVAL;
+ else
+ {
+ PCHAR pSsidString = NULL;
+ Status = copy_from_user(&Ssid, wrq->u.data.pointer, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SSID (Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
+ if (Ssid.SsidLength > MAX_LEN_OF_SSID)
+ Status = -EINVAL;
+ else
+ {
+ if (Ssid.SsidLength == 0)
+ {
+ Set_SSID_Proc(pAdapter, "");
+ }
+ else
+ {
+ pSsidString = (CHAR *) kmalloc(MAX_LEN_OF_SSID+1, MEM_ALLOC_FLAG);
+ if (pSsidString)
+ {
+ NdisZeroMemory(pSsidString, MAX_LEN_OF_SSID+1);
+ NdisMoveMemory(pSsidString, Ssid.Ssid, Ssid.SsidLength);
+ Set_SSID_Proc(pAdapter, pSsidString);
+ kfree(pSsidString);
+ }
+ else
+ Status = -ENOMEM;
+ }
+ }
+ }
+ break;
+ case OID_802_11_BSSID:
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ if (wrq->u.data.length != sizeof(NDIS_802_11_MAC_ADDRESS))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&Bssid, wrq->u.data.pointer, wrq->u.data.length);
+
+ // tell CNTL state machine to call NdisMSetInformationComplete() after completing
+ // this request, because this request is initiated by NDIS.
+ pAdapter->MlmeAux.CurrReqIsFromNdis = FALSE;
+
+ // Prevent to connect AP again in STAMlmePeriodicExec
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+
+ // Reset allowed scan retries
+ pAdapter->StaCfg.ScanCnt = 0;
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_BSSID,
+ sizeof(NDIS_802_11_MAC_ADDRESS),
+ (VOID *)&Bssid);
+ Status = NDIS_STATUS_SUCCESS;
+ StateMachineTouched = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_BSSID %02x:%02x:%02x:%02x:%02x:%02x\n",
+ Bssid[0], Bssid[1], Bssid[2], Bssid[3], Bssid[4], Bssid[5]));
+ }
+ break;
+ case RT_OID_802_11_RADIO:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&RadioState, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RADIO (=%d)\n", RadioState));
+ if (pAdapter->StaCfg.bSwRadio != RadioState)
+ {
+ pAdapter->StaCfg.bSwRadio = RadioState;
+ if (pAdapter->StaCfg.bRadio != (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio))
+ {
+ pAdapter->StaCfg.bRadio = (pAdapter->StaCfg.bHwRadio && pAdapter->StaCfg.bSwRadio);
+ if (pAdapter->StaCfg.bRadio == TRUE)
+ {
+ MlmeRadioOn(pAdapter);
+ // Update extra information
+ pAdapter->ExtraInfo = EXTRA_INFO_CLEAR;
+ }
+ else
+ {
+ MlmeRadioOff(pAdapter);
+ // Update extra information
+ pAdapter->ExtraInfo = SW_RADIO_OFF;
+ }
+ }
+ }
+ }
+ break;
+ case RT_OID_802_11_PHY_MODE:
+ if (wrq->u.data.length != sizeof(RT_802_11_PHY_MODE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&PhyMode, wrq->u.data.pointer, wrq->u.data.length);
+ if (PhyMode <= MaxPhyMode)
+ {
+ RTMPSetPhyMode(pAdapter, PhyMode);
+#ifdef DOT11_N_SUPPORT
+ SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PHY_MODE (=%d)\n", PhyMode));
+ }
+ break;
+ case RT_OID_802_11_STA_CONFIG:
+ if (wrq->u.data.length != sizeof(RT_802_11_STA_CONFIG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&StaConfig, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->CommonCfg.bEnableTxBurst = StaConfig.EnableTxBurst;
+ pAdapter->CommonCfg.UseBGProtection = StaConfig.UseBGProtection;
+ pAdapter->CommonCfg.bUseShortSlotTime = 1; // 2003-10-30 always SHORT SLOT capable
+ if ((pAdapter->CommonCfg.PhyMode != StaConfig.AdhocMode) &&
+ (StaConfig.AdhocMode <= MaxPhyMode))
+ {
+ // allow dynamic change of "USE OFDM rate or not" in ADHOC mode
+ // if setting changed, need to reset current TX rate as well as BEACON frame format
+ pAdapter->CommonCfg.PhyMode = StaConfig.AdhocMode;
+ if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+ {
+ RTMPSetPhyMode(pAdapter, PhyMode);
+ MlmeUpdateTxRates(pAdapter, FALSE, 0);
+ MakeIbssBeacon(pAdapter); // re-build BEACON frame
+ AsicEnableIbssSync(pAdapter); // copy to on-chip memory
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_STA_CONFIG (Burst=%d, Protection=%ld,ShortSlot=%d\n",
+ pAdapter->CommonCfg.bEnableTxBurst,
+ pAdapter->CommonCfg.UseBGProtection,
+ pAdapter->CommonCfg.bUseShortSlotTime));
+ }
+ break;
+ case OID_802_11_DESIRED_RATES:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_RATES))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&aryRates, wrq->u.data.pointer, wrq->u.data.length);
+ NdisZeroMemory(pAdapter->CommonCfg.DesireRate, MAX_LEN_OF_SUPPORTED_RATES);
+ NdisMoveMemory(pAdapter->CommonCfg.DesireRate, &aryRates, sizeof(NDIS_802_11_RATES));
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DESIRED_RATES (%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x)\n",
+ pAdapter->CommonCfg.DesireRate[0],pAdapter->CommonCfg.DesireRate[1],
+ pAdapter->CommonCfg.DesireRate[2],pAdapter->CommonCfg.DesireRate[3],
+ pAdapter->CommonCfg.DesireRate[4],pAdapter->CommonCfg.DesireRate[5],
+ pAdapter->CommonCfg.DesireRate[6],pAdapter->CommonCfg.DesireRate[7] ));
+ // Changing DesiredRate may affect the MAX TX rate we used to TX frames out
+ MlmeUpdateTxRates(pAdapter, FALSE, 0);
+ }
+ break;
+ case RT_OID_802_11_PREAMBLE:
+ if (wrq->u.data.length != sizeof(RT_802_11_PREAMBLE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&Preamble, wrq->u.data.pointer, wrq->u.data.length);
+ if (Preamble == Rt802_11PreambleShort)
+ {
+ pAdapter->CommonCfg.TxPreamble = Preamble;
+ MlmeSetTxPreamble(pAdapter, Rt802_11PreambleShort);
+ }
+ else if ((Preamble == Rt802_11PreambleLong) || (Preamble == Rt802_11PreambleAuto))
+ {
+ // if user wants AUTO, initialize to LONG here, then change according to AP's
+ // capability upon association.
+ pAdapter->CommonCfg.TxPreamble = Preamble;
+ MlmeSetTxPreamble(pAdapter, Rt802_11PreambleLong);
+ }
+ else
+ {
+ Status = -EINVAL;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_PREAMBLE (=%d)\n", Preamble));
+ }
+ break;
+ case OID_802_11_WEP_STATUS:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_WEP_STATUS))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&WepStatus, wrq->u.data.pointer, wrq->u.data.length);
+ // Since TKIP, AES, WEP are all supported. It should not have any invalid setting
+ if (WepStatus <= Ndis802_11Encryption3KeyAbsent)
+ {
+ if (pAdapter->StaCfg.WepStatus != WepStatus)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ }
+ pAdapter->StaCfg.WepStatus = WepStatus;
+ pAdapter->StaCfg.OrigWepStatus = WepStatus;
+ pAdapter->StaCfg.PairCipher = WepStatus;
+ pAdapter->StaCfg.GroupCipher = WepStatus;
+ }
+ else
+ {
+ Status = -EINVAL;
+ break;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEP_STATUS (=%d)\n",WepStatus));
+ }
+ break;
+ case OID_802_11_AUTHENTICATION_MODE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_AUTHENTICATION_MODE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&AuthMode, wrq->u.data.pointer, wrq->u.data.length);
+ if (AuthMode > Ndis802_11AuthModeMax)
+ {
+ Status = -EINVAL;
+ break;
+ }
+ else
+ {
+ if (pAdapter->StaCfg.AuthMode != AuthMode)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ }
+ pAdapter->StaCfg.AuthMode = AuthMode;
+ }
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_AUTHENTICATION_MODE (=%d) \n",pAdapter->StaCfg.AuthMode));
+ }
+ break;
+ case OID_802_11_INFRASTRUCTURE_MODE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_INFRASTRUCTURE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&BssType, wrq->u.data.pointer, wrq->u.data.length);
+
+ if (BssType == Ndis802_11IBSS)
+ Set_NetworkType_Proc(pAdapter, "Adhoc");
+ else if (BssType == Ndis802_11Infrastructure)
+ Set_NetworkType_Proc(pAdapter, "Infra");
+ else if (BssType == Ndis802_11Monitor)
+ Set_NetworkType_Proc(pAdapter, "Monitor");
+ else
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_INFRASTRUCTURE_MODE (unknown)\n"));
+ }
+ }
+ break;
+ case OID_802_11_REMOVE_WEP:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_WEP\n"));
+ if (wrq->u.data.length != sizeof(NDIS_802_11_KEY_INDEX))
+ {
+ Status = -EINVAL;
+ }
+ else
+ {
+ KeyIdx = *(NDIS_802_11_KEY_INDEX *) wrq->u.data.pointer;
+
+ if (KeyIdx & 0x80000000)
+ {
+ // Should never set default bit when remove key
+ Status = -EINVAL;
+ }
+ else
+ {
+ KeyIdx = KeyIdx & 0x0fffffff;
+ if (KeyIdx >= 4){
+ Status = -EINVAL;
+ }
+ else
+ {
+ pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+ pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
+ }
+ }
+ }
+ break;
+ case RT_OID_802_11_RESET_COUNTERS:
+ NdisZeroMemory(&pAdapter->WlanCounters, sizeof(COUNTER_802_11));
+ NdisZeroMemory(&pAdapter->Counters8023, sizeof(COUNTER_802_3));
+ NdisZeroMemory(&pAdapter->RalinkCounters, sizeof(COUNTER_RALINK));
+ pAdapter->Counters8023.RxNoBuffer = 0;
+ pAdapter->Counters8023.GoodReceives = 0;
+ pAdapter->Counters8023.RxNoBuffer = 0;
+#ifdef RT2870
+ pAdapter->BulkOutComplete = 0;
+ pAdapter->BulkOutCompleteOther= 0;
+ pAdapter->BulkOutCompleteCancel = 0;
+ pAdapter->BulkOutReq = 0;
+ pAdapter->BulkInReq= 0;
+ pAdapter->BulkInComplete = 0;
+ pAdapter->BulkInCompleteFail = 0;
+#endif // RT2870 //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_RESET_COUNTERS \n"));
+ break;
+ case OID_802_11_RTS_THRESHOLD:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_RTS_THRESHOLD))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&RtsThresh, wrq->u.data.pointer, wrq->u.data.length);
+ if (RtsThresh > MAX_RTS_THRESHOLD)
+ Status = -EINVAL;
+ else
+ pAdapter->CommonCfg.RtsThreshold = (USHORT)RtsThresh;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_RTS_THRESHOLD (=%ld)\n",RtsThresh));
+ break;
+ case OID_802_11_FRAGMENTATION_THRESHOLD:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_FRAGMENTATION_THRESHOLD))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&FragThresh, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->CommonCfg.bUseZeroToDisableFragment = FALSE;
+ if (FragThresh > MAX_FRAG_THRESHOLD || FragThresh < MIN_FRAG_THRESHOLD)
+ {
+ if (FragThresh == 0)
+ {
+ pAdapter->CommonCfg.FragmentThreshold = MAX_FRAG_THRESHOLD;
+ pAdapter->CommonCfg.bUseZeroToDisableFragment = TRUE;
+ }
+ else
+ Status = -EINVAL;
+ }
+ else
+ pAdapter->CommonCfg.FragmentThreshold = (USHORT)FragThresh;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_FRAGMENTATION_THRESHOLD (=%ld) \n",FragThresh));
+ break;
+ case OID_802_11_POWER_MODE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_POWER_MODE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&PowerMode, wrq->u.data.pointer, wrq->u.data.length);
+ if (PowerMode == Ndis802_11PowerModeCAM)
+ Set_PSMode_Proc(pAdapter, "CAM");
+ else if (PowerMode == Ndis802_11PowerModeMAX_PSP)
+ Set_PSMode_Proc(pAdapter, "Max_PSP");
+ else if (PowerMode == Ndis802_11PowerModeFast_PSP)
+ Set_PSMode_Proc(pAdapter, "Fast_PSP");
+ else if (PowerMode == Ndis802_11PowerModeLegacy_PSP)
+ Set_PSMode_Proc(pAdapter, "Legacy_PSP");
+ else
+ Status = -EINVAL;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_POWER_MODE (=%d)\n",PowerMode));
+ break;
+ case RT_OID_802_11_TX_POWER_LEVEL_1:
+ if (wrq->u.data.length < sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&PowerTemp, wrq->u.data.pointer, wrq->u.data.length);
+ if (PowerTemp > 100)
+ PowerTemp = 0xffffffff; // AUTO
+ pAdapter->CommonCfg.TxPowerDefault = PowerTemp; //keep current setting.
+ pAdapter->CommonCfg.TxPowerPercentage = pAdapter->CommonCfg.TxPowerDefault;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
+ }
+ break;
+ case OID_802_11_NETWORK_TYPE_IN_USE:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_NETWORK_TYPE))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&NetType, wrq->u.data.pointer, wrq->u.data.length);
+
+ if (NetType == Ndis802_11DS)
+ RTMPSetPhyMode(pAdapter, PHY_11B);
+ else if (NetType == Ndis802_11OFDM24)
+ RTMPSetPhyMode(pAdapter, PHY_11BG_MIXED);
+ else if (NetType == Ndis802_11OFDM5)
+ RTMPSetPhyMode(pAdapter, PHY_11A);
+ else
+ Status = -EINVAL;
+#ifdef DOT11_N_SUPPORT
+ if (Status == NDIS_STATUS_SUCCESS)
+ SetCommonHT(pAdapter);
+#endif // DOT11_N_SUPPORT //
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_NETWORK_TYPE_IN_USE (=%d)\n",NetType));
+ }
+ break;
+ // For WPA PSK PMK key
+ case RT_OID_802_11_ADD_WPA:
+ pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+ if(pKey == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+
+ Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (pKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!!\n"));
+ }
+ else
+ {
+ if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone) )
+ {
+ Status = -EOPNOTSUPP;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA, Failed!! [AuthMode != WPAPSK/WPA2PSK/WPANONE]\n"));
+ }
+ else if ((pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) ||
+ (pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone) ) // Only for WPA PSK mode
+ {
+ NdisMoveMemory(pAdapter->StaCfg.PMK, &pKey->KeyMaterial, pKey->KeyLength);
+ // Use RaConfig as PSK agent.
+ // Start STA supplicant state machine
+ if (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+ pAdapter->StaCfg.WpaState = SS_START;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+ }
+ else
+ {
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_WPA (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+ }
+ }
+ kfree(pKey);
+ break;
+ case OID_802_11_REMOVE_KEY:
+ pRemoveKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+ if(pRemoveKey == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+
+ Status = copy_from_user(pRemoveKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (pRemoveKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!\n"));
+ }
+ else
+ {
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ {
+ RTMPWPARemoveKeyProc(pAdapter, pRemoveKey);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Remove WPA Key!!\n"));
+ }
+ else
+ {
+ KeyIdx = pRemoveKey->KeyIndex;
+
+ if (KeyIdx & 0x80000000)
+ {
+ // Should never set default bit when remove key
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(Should never set default bit when remove key)\n"));
+ }
+ else
+ {
+ KeyIdx = KeyIdx & 0x0fffffff;
+ if (KeyIdx > 3)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY, Failed!!(KeyId[%d] out of range)\n", KeyIdx));
+ }
+ else
+ {
+ pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = 0;
+ pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CIPHER_NONE;
+ AsicRemoveSharedKeyEntry(pAdapter, 0, (UCHAR)KeyIdx);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_REMOVE_KEY (id=0x%x, Len=%d-byte)\n", pRemoveKey->KeyIndex, pRemoveKey->Length));
+ }
+ }
+ }
+ }
+ kfree(pRemoveKey);
+ break;
+ // New for WPA
+ case OID_802_11_ADD_KEY:
+ pKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+ if(pKey == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+ Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (pKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY, Failed!!\n"));
+ }
+ else
+ {
+ RTMPAddKey(pAdapter, pKey);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_KEY (id=0x%x, Len=%d-byte)\n", pKey->KeyIndex, pKey->KeyLength));
+ }
+ kfree(pKey);
+ break;
+ case OID_802_11_CONFIGURATION:
+ if (wrq->u.data.length != sizeof(NDIS_802_11_CONFIGURATION))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&Config, wrq->u.data.pointer, wrq->u.data.length);
+ pConfig = &Config;
+
+ if ((pConfig->BeaconPeriod >= 20) && (pConfig->BeaconPeriod <=400))
+ pAdapter->CommonCfg.BeaconPeriod = (USHORT) pConfig->BeaconPeriod;
+
+ pAdapter->StaActive.AtimWin = (USHORT) pConfig->ATIMWindow;
+ MAP_KHZ_TO_CHANNEL_ID(pConfig->DSConfig, pAdapter->CommonCfg.Channel);
+ //
+ // Save the channel on MlmeAux for CntlOidRTBssidProc used.
+ //
+ pAdapter->MlmeAux.Channel = pAdapter->CommonCfg.Channel;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CONFIGURATION (BeacnPeriod=%ld,AtimW=%ld,Ch=%d)\n",
+ pConfig->BeaconPeriod, pConfig->ATIMWindow, pAdapter->CommonCfg.Channel));
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ }
+ break;
+#ifdef DOT11_N_SUPPORT
+ case RT_OID_802_11_SET_HT_PHYMODE:
+ if (wrq->u.data.length != sizeof(OID_SET_HT_PHYMODE))
+ Status = -EINVAL;
+ else
+ {
+ POID_SET_HT_PHYMODE pHTPhyMode = &HT_PhyMode;
+
+ Status = copy_from_user(&HT_PhyMode, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::pHTPhyMode (PhyMode = %d,TransmitNo = %d, HtMode = %d, ExtOffset = %d , MCS = %d, BW = %d, STBC = %d, SHORTGI = %d) \n",
+ pHTPhyMode->PhyMode, pHTPhyMode->TransmitNo,pHTPhyMode->HtMode,pHTPhyMode->ExtOffset,
+ pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->SHORTGI));
+ if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED)
+ RTMPSetHT(pAdapter, pHTPhyMode);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_HT_PHYMODE(MCS=%d,BW=%d,SGI=%d,STBC=%d)\n",
+ pAdapter->StaCfg.HTPhyMode.field.MCS, pAdapter->StaCfg.HTPhyMode.field.BW, pAdapter->StaCfg.HTPhyMode.field.ShortGI,
+ pAdapter->StaCfg.HTPhyMode.field.STBC));
+ break;
+#endif // DOT11_N_SUPPORT //
+ case RT_OID_802_11_SET_APSD_SETTING:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ ULONG apsd ;
+ Status = copy_from_user(&apsd, wrq->u.data.pointer, wrq->u.data.length);
+
+ /*-------------------------------------------------------------------
+ |B31~B7 | B6~B5 | B4 | B3 | B2 | B1 | B0 |
+ ---------------------------------------------------------------------
+ | Rsvd | Max SP Len | AC_VO | AC_VI | AC_BK | AC_BE | APSD Capable |
+ ---------------------------------------------------------------------*/
+ pAdapter->CommonCfg.bAPSDCapable = (apsd & 0x00000001) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_BE = ((apsd & 0x00000002) >> 1) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_BK = ((apsd & 0x00000004) >> 2) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_VI = ((apsd & 0x00000008) >> 3) ? TRUE : FALSE;
+ pAdapter->CommonCfg.bAPSDAC_VO = ((apsd & 0x00000010) >> 4) ? TRUE : FALSE;
+ pAdapter->CommonCfg.MaxSPLength = (UCHAR)((apsd & 0x00000060) >> 5);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_SETTING (apsd=0x%lx, APSDCap=%d, [BE,BK,VI,VO]=[%d/%d/%d/%d], MaxSPLen=%d)\n", apsd, pAdapter->CommonCfg.bAPSDCapable,
+ pAdapter->CommonCfg.bAPSDAC_BE, pAdapter->CommonCfg.bAPSDAC_BK, pAdapter->CommonCfg.bAPSDAC_VI, pAdapter->CommonCfg.bAPSDAC_VO, pAdapter->CommonCfg.MaxSPLength));
+ }
+ break;
+
+ case RT_OID_802_11_SET_APSD_PSM:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ // Driver needs to notify AP when PSM changes
+ Status = copy_from_user(&pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.pointer, wrq->u.data.length);
+ if (pAdapter->CommonCfg.bAPSDForcePowerSave != pAdapter->StaCfg.Psm)
+ {
+ MlmeSetPsmBit(pAdapter, pAdapter->CommonCfg.bAPSDForcePowerSave);
+ RTMPSendNullFrame(pAdapter, pAdapter->CommonCfg.TxRate, TRUE);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_APSD_PSM (bAPSDForcePowerSave:%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
+ }
+ break;
+#ifdef QOS_DLS_SUPPORT
+ case RT_OID_802_11_SET_DLS:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ BOOLEAN oldvalue = pAdapter->CommonCfg.bDLSCapable;
+ Status = copy_from_user(&pAdapter->CommonCfg.bDLSCapable, wrq->u.data.pointer, wrq->u.data.length);
+ if (oldvalue && !pAdapter->CommonCfg.bDLSCapable)
+ {
+ int i;
+ // tear down local dls table entry
+ for (i=0; i<MAX_NUM_OF_INIT_DLS_ENTRY; i++)
+ {
+ if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+
+ // tear down peer dls table entry
+ for (i=MAX_NUM_OF_INIT_DLS_ENTRY; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ if (pAdapter->StaCfg.DLSEntry[i].Valid && (pAdapter->StaCfg.DLSEntry[i].Status == DLS_FINISH))
+ {
+ pAdapter->StaCfg.DLSEntry[i].Status = DLS_NONE;
+ pAdapter->StaCfg.DLSEntry[i].Valid = FALSE;
+ RTMPSendDLSTearDownFrame(pAdapter, pAdapter->StaCfg.DLSEntry[i].MacAddr);
+ }
+ }
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS (=%d)\n", pAdapter->CommonCfg.bDLSCapable));
+ }
+ break;
+
+ case RT_OID_802_11_SET_DLS_PARAM:
+ if (wrq->u.data.length != sizeof(RT_802_11_DLS_UI))
+ Status = -EINVAL;
+ else
+ {
+ RT_802_11_DLS Dls;
+
+ NdisZeroMemory(&Dls, sizeof(RT_802_11_DLS));
+ RTMPMoveMemory(&Dls, wrq->u.data.pointer, sizeof(RT_802_11_DLS_UI));
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ RT_OID_802_11_SET_DLS_PARAM,
+ sizeof(RT_802_11_DLS),
+ &Dls);
+ DBGPRINT(RT_DEBUG_TRACE,("Set::RT_OID_802_11_SET_DLS_PARAM \n"));
+ }
+ break;
+#endif // QOS_DLS_SUPPORT //
+ case RT_OID_802_11_SET_WMM:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&pAdapter->CommonCfg.bWmmCapable, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_SET_WMM (=%d) \n", pAdapter->CommonCfg.bWmmCapable));
+ }
+ break;
+
+ case OID_802_11_DISASSOCIATE:
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ break;
+ }
+#endif // RALINK_ATE //
+ //
+ // Set NdisRadioStateOff to TRUE, instead of called MlmeRadioOff.
+ // Later on, NDIS_802_11_BSSID_LIST_EX->NumberOfItems should be 0
+ // when query OID_802_11_BSSID_LIST.
+ //
+ // TRUE: NumberOfItems will set to 0.
+ // FALSE: NumberOfItems no change.
+ //
+ pAdapter->CommonCfg.NdisRadioStateOff = TRUE;
+ // Set to immediately send the media disconnect event
+ pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DISASSOCIATE \n"));
+
+ if (INFRA_ON(pAdapter))
+ {
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_DISASSOCIATE,
+ 0,
+ NULL);
+
+ StateMachineTouched = TRUE;
+ }
+ break;
+
+#ifdef DOT11_N_SUPPORT
+ case RT_OID_802_11_SET_IMME_BA_CAP:
+ if (wrq->u.data.length != sizeof(OID_BACAP_STRUC))
+ Status = -EINVAL;
+ else
+ {
+ OID_BACAP_STRUC Orde ;
+ Status = copy_from_user(&Orde, wrq->u.data.pointer, wrq->u.data.length);
+ if (Orde.Policy > BA_NOTUSE)
+ {
+ Status = NDIS_STATUS_INVALID_DATA;
+ }
+ else if (Orde.Policy == BA_NOTUSE)
+ {
+ pAdapter->CommonCfg.BACapability.field.Policy = BA_NOTUSE;
+ pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+ pAdapter->CommonCfg.DesiredHtPhy.MimoPs= Orde.MMPSmode;
+ pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+ // UPdata to HT IE
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+ pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+ }
+ else
+ {
+ pAdapter->CommonCfg.BACapability.field.AutoBA = Orde.AutoBA;
+ pAdapter->CommonCfg.BACapability.field.Policy = IMMED_BA; // we only support immediate BA.
+ pAdapter->CommonCfg.BACapability.field.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.MpduDensity = Orde.MpduDensity;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable = Orde.AmsduEnable;
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduSize= Orde.AmsduSize;
+ pAdapter->CommonCfg.DesiredHtPhy.MimoPs = Orde.MMPSmode;
+ pAdapter->CommonCfg.BACapability.field.MMPSmode = Orde.MMPSmode;
+
+ // UPdata to HT IE
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.MimoPs = Orde.MMPSmode;
+ pAdapter->CommonCfg.HtCapability.HtCapInfo.AMsduSize = Orde.AmsduSize;
+ pAdapter->CommonCfg.HtCapability.HtCapParm.MpduDensity = Orde.MpduDensity;
+
+ if (pAdapter->CommonCfg.BACapability.field.RxBAWinLimit > MAX_RX_REORDERBUF)
+ pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = MAX_RX_REORDERBUF;
+
+ }
+
+ pAdapter->CommonCfg.REGBACapability.word = pAdapter->CommonCfg.BACapability.word;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::(Orde.AutoBA = %d) (Policy=%d)(ReBAWinLimit=%d)(TxBAWinLimit=%d)(AutoMode=%d)\n",Orde.AutoBA, pAdapter->CommonCfg.BACapability.field.Policy,
+ pAdapter->CommonCfg.BACapability.field.RxBAWinLimit,pAdapter->CommonCfg.BACapability.field.TxBAWinLimit, pAdapter->CommonCfg.BACapability.field.AutoBA));
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::(MimoPs = %d)(AmsduEnable = %d) (AmsduSize=%d)(MpduDensity=%d)\n",pAdapter->CommonCfg.DesiredHtPhy.MimoPs, pAdapter->CommonCfg.DesiredHtPhy.AmsduEnable,
+ pAdapter->CommonCfg.DesiredHtPhy.AmsduSize, pAdapter->CommonCfg.DesiredHtPhy.MpduDensity));
+ }
+
+ break;
+ case RT_OID_802_11_ADD_IMME_BA:
+ DBGPRINT(RT_DEBUG_TRACE, (" Set :: RT_OID_802_11_ADD_IMME_BA \n"));
+ if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
+ Status = -EINVAL;
+ else
+ {
+ UCHAR index;
+ OID_ADD_BA_ENTRY BA;
+ MAC_TABLE_ENTRY *pEntry;
+
+ Status = copy_from_user(&BA, wrq->u.data.pointer, wrq->u.data.length);
+ if (BA.TID > 15)
+ {
+ Status = NDIS_STATUS_INVALID_DATA;
+ break;
+ }
+ else
+ {
+ //BATableInsertEntry
+ //As ad-hoc mode, BA pair is not limited to only BSSID. so add via OID.
+ index = BA.TID;
+ // in ad hoc mode, when adding BA pair, we should insert this entry into MACEntry too
+ pEntry = MacTableLookup(pAdapter, BA.MACAddr);
+ if (!pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("RT_OID_802_11_ADD_IMME_BA. break on no connection.----:%x:%x\n", BA.MACAddr[4], BA.MACAddr[5]));
+ break;
+ }
+ if (BA.IsRecipient == FALSE)
+ {
+ if (pEntry->bIAmBadAtheros == TRUE)
+ pAdapter->CommonCfg.BACapability.field.RxBAWinLimit = 0x10;
+
+ BAOriSessionSetUp(pAdapter, pEntry, index, 0, 100, TRUE);
+ }
+ else
+ {
+ //BATableInsertEntry(pAdapter, pEntry->Aid, BA.MACAddr, 0, 0xffff, BA.TID, BA.nMSDU, BA.IsRecipient);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_802_11_ADD_IMME_BA. Rec = %d. Mac = %x:%x:%x:%x:%x:%x . \n",
+ BA.IsRecipient, BA.MACAddr[0], BA.MACAddr[1], BA.MACAddr[2], BA.MACAddr[2]
+ , BA.MACAddr[4], BA.MACAddr[5]));
+ }
+ }
+ break;
+
+ case RT_OID_802_11_TEAR_IMME_BA:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA \n"));
+ if (wrq->u.data.length != sizeof(OID_ADD_BA_ENTRY))
+ Status = -EINVAL;
+ else
+ {
+ POID_ADD_BA_ENTRY pBA;
+ MAC_TABLE_ENTRY *pEntry;
+
+ pBA = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+ if (pBA == NULL)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA kmalloc() can't allocate enough memory\n"));
+ Status = NDIS_STATUS_FAILURE;
+ }
+ else
+ {
+ Status = copy_from_user(pBA, wrq->u.data.pointer, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: RT_OID_802_11_TEAR_IMME_BA(TID=%d, bAllTid=%d)\n", pBA->TID, pBA->bAllTid));
+
+ if (!pBA->bAllTid && (pBA->TID > NUM_OF_TID))
+ {
+ Status = NDIS_STATUS_INVALID_DATA;
+ break;
+ }
+
+ if (pBA->IsRecipient == FALSE)
+ {
+ pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
+ DBGPRINT(RT_DEBUG_TRACE, (" pBA->IsRecipient == FALSE\n"));
+ if (pEntry)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, (" pBA->pEntry\n"));
+ BAOriSessionTearDown(pAdapter, pEntry->Aid, pBA->TID, FALSE, TRUE);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
+ }
+ else
+ {
+ pEntry = MacTableLookup(pAdapter, pBA->MACAddr);
+ if (pEntry)
+ {
+ BARecSessionTearDown( pAdapter, (UCHAR)pEntry->Aid, pBA->TID, TRUE);
+ }
+ else
+ DBGPRINT(RT_DEBUG_TRACE, ("Set :: Not found pEntry \n"));
+ }
+ kfree(pBA);
+ }
+ }
+ break;
+#endif // DOT11_N_SUPPORT //
+
+ // For WPA_SUPPLICANT to set static wep key
+ case OID_802_11_ADD_WEP:
+ pWepKey = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+ if(pWepKey == NULL)
+ {
+ Status = -ENOMEM;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed!!\n"));
+ break;
+ }
+ Status = copy_from_user(pWepKey, wrq->u.data.pointer, wrq->u.data.length);
+ if (Status)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (length mismatch)!!\n"));
+ }
+ else
+ {
+ KeyIdx = pWepKey->KeyIndex & 0x0fffffff;
+ // KeyIdx must be 0 ~ 3
+ if (KeyIdx > 4)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, Failed (KeyIdx must be smaller than 4)!!\n"));
+ }
+ else
+ {
+ UCHAR CipherAlg = 0;
+ PUCHAR Key;
+
+ // set key material and key length
+ NdisZeroMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, 16);
+ pAdapter->SharedKey[BSS0][KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAdapter->SharedKey[BSS0][KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+
+ switch(pWepKey->KeyLength)
+ {
+ case 5:
+ CipherAlg = CIPHER_WEP64;
+ break;
+ case 13:
+ CipherAlg = CIPHER_WEP128;
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP, only support CIPHER_WEP64(len:5) & CIPHER_WEP128(len:13)!!\n"));
+ Status = -EINVAL;
+ break;
+ }
+ pAdapter->SharedKey[BSS0][KeyIdx].CipherAlg = CipherAlg;
+
+ // Default key for tx (shared key)
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+#ifdef WPA_SUPPLICANT_SUPPORT
+ // set key material and key length
+ NdisZeroMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, 16);
+ pAdapter->StaCfg.DesireSharedKey[KeyIdx].KeyLen = (UCHAR) pWepKey->KeyLength;
+ NdisMoveMemory(pAdapter->StaCfg.DesireSharedKey[KeyIdx].Key, &pWepKey->KeyMaterial, pWepKey->KeyLength);
+ pAdapter->StaCfg.DesireSharedKeyId = KeyIdx;
+ pAdapter->StaCfg.DesireSharedKey[KeyIdx].CipherAlg = CipherAlg;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+ }
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+ if (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)
+#endif // WPA_SUPPLICANT_SUPPORT
+ {
+ Key = pAdapter->SharedKey[BSS0][KeyIdx].Key;
+
+ // Set key material and cipherAlg to Asic
+ AsicAddSharedKeyEntry(pAdapter, BSS0, KeyIdx, CipherAlg, Key, NULL, NULL);
+
+ if (pWepKey->KeyIndex & 0x80000000)
+ {
+ PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.Content[BSSID_WCID];
+ // Assign group key info
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, NULL);
+ // Assign pairwise key info
+ RTMPAddWcidAttributeEntry(pAdapter, BSS0, KeyIdx, CipherAlg, pEntry);
+ }
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_ADD_WEP (id=0x%x, Len=%d-byte), %s\n", pWepKey->KeyIndex, pWepKey->KeyLength, (pAdapter->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED) ? "Port Secured":"Port NOT Secured"));
+ }
+ }
+ kfree(pWepKey);
+ break;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ case OID_SET_COUNTERMEASURES:
+ if (wrq->u.data.length != sizeof(int))
+ Status = -EINVAL;
+ else
+ {
+ int enabled = 0;
+ Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
+ if (enabled == 1)
+ pAdapter->StaCfg.bBlockAssoc = TRUE;
+ else
+ // WPA MIC error should block association attempt for 60 seconds
+ pAdapter->StaCfg.bBlockAssoc = FALSE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_SET_COUNTERMEASURES bBlockAssoc=%s\n", pAdapter->StaCfg.bBlockAssoc ? "TRUE":"FALSE"));
+ }
+ break;
+ case RT_OID_WPA_SUPPLICANT_SUPPORT:
+ if (wrq->u.data.length != sizeof(UCHAR))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&wpa_supplicant_enable, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->StaCfg.WpaSupplicantUP = wpa_supplicant_enable;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
+ }
+ break;
+ case OID_802_11_DEAUTHENTICATION:
+ if (wrq->u.data.length != sizeof(MLME_DEAUTH_REQ_STRUCT))
+ Status = -EINVAL;
+ else
+ {
+ MLME_DEAUTH_REQ_STRUCT *pInfo;
+ MLME_QUEUE_ELEM *MsgElem = (MLME_QUEUE_ELEM *) kmalloc(sizeof(MLME_QUEUE_ELEM), MEM_ALLOC_FLAG);
+
+ pInfo = (MLME_DEAUTH_REQ_STRUCT *) MsgElem->Msg;
+ Status = copy_from_user(pInfo, wrq->u.data.pointer, wrq->u.data.length);
+ MlmeDeauthReqAction(pAdapter, MsgElem);
+ kfree(MsgElem);
+
+ if (INFRA_ON(pAdapter))
+ {
+ LinkDown(pAdapter, FALSE);
+ pAdapter->Mlme.AssocMachine.CurrState = ASSOC_IDLE;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DEAUTHENTICATION (Reason=%d)\n", pInfo->Reason));
+ }
+ break;
+ case OID_802_11_DROP_UNENCRYPTED:
+ if (wrq->u.data.length != sizeof(int))
+ Status = -EINVAL;
+ else
+ {
+ int enabled = 0;
+ Status = copy_from_user(&enabled, wrq->u.data.pointer, wrq->u.data.length);
+ if (enabled == 1)
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+ else
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_SECURED;
+ NdisAcquireSpinLock(&pAdapter->MacTabLock);
+ pAdapter->MacTab.Content[BSSID_WCID].PortSecured = pAdapter->StaCfg.PortSecured;
+ NdisReleaseSpinLock(&pAdapter->MacTabLock);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_DROP_UNENCRYPTED (=%d)\n", enabled));
+ }
+ break;
+ case OID_802_11_SET_IEEE8021X:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&IEEE8021xState, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->StaCfg.IEEE8021X = IEEE8021xState;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X (=%d)\n", IEEE8021xState));
+ }
+ break;
+ case OID_802_11_SET_IEEE8021X_REQUIRE_KEY:
+ if (wrq->u.data.length != sizeof(BOOLEAN))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&IEEE8021x_required_keys, wrq->u.data.pointer, wrq->u.data.length);
+ pAdapter->StaCfg.IEEE8021x_required_keys = IEEE8021x_required_keys;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SET_IEEE8021X_REQUIRE_KEY (%d)\n", IEEE8021x_required_keys));
+ }
+ break;
+ case OID_802_11_PMKID:
+ pPmkId = kmalloc(wrq->u.data.length, MEM_ALLOC_FLAG);
+
+ if(pPmkId == NULL) {
+ Status = -ENOMEM;
+ break;
+ }
+ Status = copy_from_user(pPmkId, wrq->u.data.pointer, wrq->u.data.length);
+
+ // check the PMKID information
+ if (pPmkId->BSSIDInfoCount == 0)
+ NdisZeroMemory(pAdapter->StaCfg.SavedPMK, sizeof(BSSID_INFO)*PMKID_NO);
+ else
+ {
+ PBSSID_INFO pBssIdInfo;
+ UINT BssIdx;
+ UINT CachedIdx;
+
+ for (BssIdx = 0; BssIdx < pPmkId->BSSIDInfoCount; BssIdx++)
+ {
+ // point to the indexed BSSID_INFO structure
+ pBssIdInfo = (PBSSID_INFO) ((PUCHAR) pPmkId + 2 * sizeof(UINT) + BssIdx * sizeof(BSSID_INFO));
+ // Find the entry in the saved data base.
+ for (CachedIdx = 0; CachedIdx < pAdapter->StaCfg.SavedPMKNum; CachedIdx++)
+ {
+ // compare the BSSID
+ if (NdisEqualMemory(pBssIdInfo->BSSID, pAdapter->StaCfg.SavedPMK[CachedIdx].BSSID, sizeof(NDIS_802_11_MAC_ADDRESS)))
+ break;
+ }
+
+ // Found, replace it
+ if (CachedIdx < PMKID_NO)
+ {
+ DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+ pAdapter->StaCfg.SavedPMKNum++;
+ }
+ // Not found, replace the last one
+ else
+ {
+ // Randomly replace one
+ CachedIdx = (pBssIdInfo->BSSID[5] % PMKID_NO);
+ DBGPRINT(RT_DEBUG_OFF, ("Update OID_802_11_PMKID, idx = %d\n", CachedIdx));
+ NdisMoveMemory(&pAdapter->StaCfg.SavedPMK[CachedIdx], pBssIdInfo, sizeof(BSSID_INFO));
+ }
+ }
+ }
+ if(pPmkId)
+ kfree(pPmkId);
+ break;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+
+
+#ifdef SNMP_SUPPORT
+ case OID_802_11_SHORTRETRYLIMIT:
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&ShortRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_SHORTRETRYLIMIT (tx_rty_cfg.field.ShortRetryLimit=%d, ShortRetryLimit=%ld)\n", tx_rty_cfg.field.ShortRtyLimit, ShortRetryLimit));
+ }
+ break;
+
+ case OID_802_11_LONGRETRYLIMIT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT \n"));
+ if (wrq->u.data.length != sizeof(ULONG))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&LongRetryLimit, wrq->u.data.pointer, wrq->u.data.length);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_LONGRETRYLIMIT (tx_rty_cfg.field.LongRetryLimit= %d,LongRetryLimit=%ld)\n", tx_rty_cfg.field.LongRtyLimit, LongRetryLimit));
+ }
+ break;
+
+ case OID_802_11_WEPDEFAULTKEYVALUE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE\n"));
+ pKey = kmalloc(wrq->u.data.length, GFP_KERNEL);
+ Status = copy_from_user(pKey, wrq->u.data.pointer, wrq->u.data.length);
+ //pKey = &WepKey;
+
+ if ( pKey->Length != wrq->u.data.length)
+ {
+ Status = -EINVAL;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYVALUE, Failed!!\n"));
+ }
+ KeyIdx = pKey->KeyIndex & 0x0fffffff;
+ DBGPRINT(RT_DEBUG_TRACE,("pKey->KeyIndex =%d, pKey->KeyLength=%d\n", pKey->KeyIndex, pKey->KeyLength));
+
+ // it is a shared key
+ if (KeyIdx > 4)
+ Status = -EINVAL;
+ else
+ {
+ pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen = (UCHAR) pKey->KeyLength;
+ NdisMoveMemory(&pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key, &pKey->KeyMaterial, pKey->KeyLength);
+ if (pKey->KeyIndex & 0x80000000)
+ {
+ // Default key for tx (shared key)
+ pAdapter->StaCfg.DefaultKeyId = (UCHAR) KeyIdx;
+ }
+ //RestartAPIsRequired = TRUE;
+ }
+ break;
+
+
+ case OID_802_11_WEPDEFAULTKEYID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_WEPDEFAULTKEYID \n"));
+
+ if (wrq->u.data.length != sizeof(UCHAR))
+ Status = -EINVAL;
+ else
+ Status = copy_from_user(&pAdapter->StaCfg.DefaultKeyId, wrq->u.data.pointer, wrq->u.data.length);
+
+ break;
+
+
+ case OID_802_11_CURRENTCHANNEL:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::OID_802_11_CURRENTCHANNEL \n"));
+ if (wrq->u.data.length != sizeof(UCHAR))
+ Status = -EINVAL;
+ else
+ {
+ Status = copy_from_user(&ctmp, wrq->u.data.pointer, wrq->u.data.length);
+ sprintf(&ctmp,"%d", ctmp);
+ Set_Channel_Proc(pAdapter, &ctmp);
+ }
+ break;
+#endif
+
+
+
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Set::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+
+
+ return Status;
+}
+
+INT RTMPQueryInformation(
+ IN PRTMP_ADAPTER pAdapter,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ struct iwreq *wrq = (struct iwreq *) rq;
+ NDIS_802_11_BSSID_LIST_EX *pBssidList = NULL;
+ PNDIS_WLAN_BSSID_EX pBss;
+ NDIS_802_11_SSID Ssid;
+ NDIS_802_11_CONFIGURATION *pConfiguration = NULL;
+ RT_802_11_LINK_STATUS *pLinkStatus = NULL;
+ RT_802_11_STA_CONFIG *pStaConfig = NULL;
+ NDIS_802_11_STATISTICS *pStatistics = NULL;
+ NDIS_802_11_RTS_THRESHOLD RtsThresh;
+ NDIS_802_11_FRAGMENTATION_THRESHOLD FragThresh;
+ NDIS_802_11_POWER_MODE PowerMode;
+ NDIS_802_11_NETWORK_INFRASTRUCTURE BssType;
+ RT_802_11_PREAMBLE PreamType;
+ NDIS_802_11_AUTHENTICATION_MODE AuthMode;
+ NDIS_802_11_WEP_STATUS WepStatus;
+ NDIS_MEDIA_STATE MediaState;
+ ULONG BssBufSize, ulInfo=0, NetworkTypeList[4], apsd = 0;
+ USHORT BssLen = 0;
+ PUCHAR pBuf = NULL, pPtr;
+ INT Status = NDIS_STATUS_SUCCESS;
+ UINT we_version_compiled;
+ UCHAR i, Padding = 0;
+ BOOLEAN RadioState;
+ UCHAR driverVersion[8];
+ OID_SET_HT_PHYMODE *pHTPhyMode = NULL;
+
+
+#ifdef SNMP_SUPPORT
+ //for snmp, kathy
+ DefaultKeyIdxValue *pKeyIdxValue;
+ INT valueLen;
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ ULONG ShortRetryLimit, LongRetryLimit;
+ UCHAR tmp[64];
+#endif //SNMP
+
+ switch(cmd)
+ {
+ case RT_OID_DEVICE_NAME:
+ wrq->u.data.length = sizeof(STA_NIC_DEVICE_NAME);
+ Status = copy_to_user(wrq->u.data.pointer, STA_NIC_DEVICE_NAME, wrq->u.data.length);
+ break;
+ case RT_OID_VERSION_INFO:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_VERSION_INFO \n"));
+ wrq->u.data.length = 8*sizeof(UCHAR);
+ sprintf(&driverVersion[0], "%s", STA_DRIVER_VERSION);
+ driverVersion[7] = '\0';
+ if (copy_to_user(wrq->u.data.pointer, &driverVersion, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+#ifdef RALINK_ATE
+ case RT_QUERY_ATE_TXDONE_COUNT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_QUERY_ATE_TXDONE_COUNT \n"));
+ wrq->u.data.length = sizeof(UINT32);
+ if (copy_to_user(wrq->u.data.pointer, &pAdapter->ate.TxDoneCount, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+#endif // RALINK_ATE //
+ case OID_802_11_BSSID_LIST:
+ if (RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS))
+ {
+ /*
+ * Still scanning, indicate the caller should try again.
+ */
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (Still scanning)\n"));
+ return -EAGAIN;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID_LIST (%d BSS returned)\n",pAdapter->ScanTab.BssNr));
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+ // Claculate total buffer size required
+ BssBufSize = sizeof(ULONG);
+
+ for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+ {
+ // Align pointer to 4 bytes boundary.
+ //Padding = 4 - (pAdapter->ScanTab.BssEntry[i].VarIELen & 0x0003);
+ //if (Padding == 4)
+ // Padding = 0;
+ BssBufSize += (sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
+ }
+
+ // For safety issue, we add 256 bytes just in case
+ BssBufSize += 256;
+ // Allocate the same size as passed from higher layer
+ pBuf = kmalloc(BssBufSize, MEM_ALLOC_FLAG);
+ if(pBuf == NULL)
+ {
+ Status = -ENOMEM;
+ break;
+ }
+ // Init 802_11_BSSID_LIST_EX structure
+ NdisZeroMemory(pBuf, BssBufSize);
+ pBssidList = (PNDIS_802_11_BSSID_LIST_EX) pBuf;
+ pBssidList->NumberOfItems = pAdapter->ScanTab.BssNr;
+
+ // Calculate total buffer length
+ BssLen = 4; // Consist of NumberOfItems
+ // Point to start of NDIS_WLAN_BSSID_EX
+ // pPtr = pBuf + sizeof(ULONG);
+ pPtr = (PUCHAR) &pBssidList->Bssid[0];
+ for (i = 0; i < pAdapter->ScanTab.BssNr; i++)
+ {
+ pBss = (PNDIS_WLAN_BSSID_EX) pPtr;
+ NdisMoveMemory(&pBss->MacAddress, &pAdapter->ScanTab.BssEntry[i].Bssid, MAC_ADDR_LEN);
+ if ((pAdapter->ScanTab.BssEntry[i].Hidden == 1) && (pAdapter->StaCfg.bShowHiddenSSID == FALSE))
+ {
+ //
+ // We must return this SSID during 4way handshaking, otherwise Aegis will failed to parse WPA infomation
+ // and then failed to send EAPOl farame.
+ //
+ if ((pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) && (pAdapter->StaCfg.PortSecured != WPA_802_1X_PORT_SECURED))
+ {
+ pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
+ NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+ }
+ else
+ pBss->Ssid.SsidLength = 0;
+ }
+ else
+ {
+ pBss->Ssid.SsidLength = pAdapter->ScanTab.BssEntry[i].SsidLen;
+ NdisMoveMemory(pBss->Ssid.Ssid, pAdapter->ScanTab.BssEntry[i].Ssid, pAdapter->ScanTab.BssEntry[i].SsidLen);
+ }
+ pBss->Privacy = pAdapter->ScanTab.BssEntry[i].Privacy;
+ pBss->Rssi = pAdapter->ScanTab.BssEntry[i].Rssi - pAdapter->BbpRssiToDbmDelta;
+ pBss->NetworkTypeInUse = NetworkTypeInUseSanity(&pAdapter->ScanTab.BssEntry[i]);
+ pBss->Configuration.Length = sizeof(NDIS_802_11_CONFIGURATION);
+ pBss->Configuration.BeaconPeriod = pAdapter->ScanTab.BssEntry[i].BeaconPeriod;
+ pBss->Configuration.ATIMWindow = pAdapter->ScanTab.BssEntry[i].AtimWin;
+
+ MAP_CHANNEL_ID_TO_KHZ(pAdapter->ScanTab.BssEntry[i].Channel, pBss->Configuration.DSConfig);
+
+ if (pAdapter->ScanTab.BssEntry[i].BssType == BSS_INFRA)
+ pBss->InfrastructureMode = Ndis802_11Infrastructure;
+ else
+ pBss->InfrastructureMode = Ndis802_11IBSS;
+
+ NdisMoveMemory(pBss->SupportedRates, pAdapter->ScanTab.BssEntry[i].SupRate, pAdapter->ScanTab.BssEntry[i].SupRateLen);
+ NdisMoveMemory(pBss->SupportedRates + pAdapter->ScanTab.BssEntry[i].SupRateLen,
+ pAdapter->ScanTab.BssEntry[i].ExtRate,
+ pAdapter->ScanTab.BssEntry[i].ExtRateLen);
+
+ if (pAdapter->ScanTab.BssEntry[i].VarIELen == 0)
+ {
+ pBss->IELength = sizeof(NDIS_802_11_FIXED_IEs);
+ NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
+ pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
+ }
+ else
+ {
+ pBss->IELength = (ULONG)(sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen);
+ pPtr = pPtr + sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs);
+ NdisMoveMemory(pBss->IEs, &pAdapter->ScanTab.BssEntry[i].FixIEs, sizeof(NDIS_802_11_FIXED_IEs));
+ NdisMoveMemory(pBss->IEs + sizeof(NDIS_802_11_FIXED_IEs), pAdapter->ScanTab.BssEntry[i].VarIEs, pAdapter->ScanTab.BssEntry[i].VarIELen);
+ pPtr += pAdapter->ScanTab.BssEntry[i].VarIELen;
+ }
+ pBss->Length = (ULONG)(sizeof(NDIS_WLAN_BSSID_EX) - 1 + sizeof(NDIS_802_11_FIXED_IEs) + pAdapter->ScanTab.BssEntry[i].VarIELen + Padding);
+
+#if WIRELESS_EXT < 17
+ if ((BssLen + pBss->Length) < wrq->u.data.length)
+ BssLen += pBss->Length;
+ else
+ {
+ pBssidList->NumberOfItems = i;
+ break;
+ }
+#else
+ BssLen += pBss->Length;
+#endif
+ }
+
+#if WIRELESS_EXT < 17
+ wrq->u.data.length = BssLen;
+#else
+ if (BssLen > wrq->u.data.length)
+ {
+ kfree(pBssidList);
+ return -E2BIG;
+ }
+ else
+ wrq->u.data.length = BssLen;
+#endif
+ Status = copy_to_user(wrq->u.data.pointer, pBssidList, BssLen);
+ kfree(pBssidList);
+ break;
+ case OID_802_3_CURRENT_ADDRESS:
+ wrq->u.data.length = MAC_ADDR_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+ break;
+ case OID_GEN_MEDIA_CONNECT_STATUS:
+ if (pAdapter->IndicateMediaState == NdisMediaStateConnected)
+ MediaState = NdisMediaStateConnected;
+ else
+ MediaState = NdisMediaStateDisconnected;
+
+ wrq->u.data.length = sizeof(NDIS_MEDIA_STATE);
+ Status = copy_to_user(wrq->u.data.pointer, &MediaState, wrq->u.data.length);
+ break;
+ case OID_802_11_BSSID:
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("The driver is in ATE mode now\n"));
+ Status = NDIS_STATUS_RESOURCES;
+ break;
+ }
+#endif // RALINK_ATE //
+ if (INFRA_ON(pAdapter) || ADHOC_ON(pAdapter))
+ {
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Bssid, sizeof(NDIS_802_11_MAC_ADDRESS));
+
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BSSID(=EMPTY)\n"));
+ Status = -ENOTCONN;
+ }
+ break;
+ case OID_802_11_SSID:
+ NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+ NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID);
+ Ssid.SsidLength = pAdapter->CommonCfg.SsidLen;
+ memcpy(Ssid.Ssid, pAdapter->CommonCfg.Ssid, Ssid.SsidLength);
+ wrq->u.data.length = sizeof(NDIS_802_11_SSID);
+ Status = copy_to_user(wrq->u.data.pointer, &Ssid, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SSID (Len=%d, ssid=%s)\n", Ssid.SsidLength,Ssid.Ssid));
+ break;
+ case RT_OID_802_11_QUERY_LINK_STATUS:
+ pLinkStatus = (RT_802_11_LINK_STATUS *) kmalloc(sizeof(RT_802_11_LINK_STATUS), MEM_ALLOC_FLAG);
+ if (pLinkStatus)
+ {
+ pLinkStatus->CurrTxRate = RateIdTo500Kbps[pAdapter->CommonCfg.TxRate]; // unit : 500 kbps
+ pLinkStatus->ChannelQuality = pAdapter->Mlme.ChannelQuality;
+ pLinkStatus->RxByteCount = pAdapter->RalinkCounters.ReceivedByteCount;
+ pLinkStatus->TxByteCount = pAdapter->RalinkCounters.TransmittedByteCount;
+ pLinkStatus->CentralChannel = pAdapter->CommonCfg.CentralChannel;
+ wrq->u.data.length = sizeof(RT_802_11_LINK_STATUS);
+ Status = copy_to_user(wrq->u.data.pointer, pLinkStatus, wrq->u.data.length);
+ kfree(pLinkStatus);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS\n"));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LINK_STATUS(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case OID_802_11_CONFIGURATION:
+ pConfiguration = (NDIS_802_11_CONFIGURATION *) kmalloc(sizeof(NDIS_802_11_CONFIGURATION), MEM_ALLOC_FLAG);
+ if (pConfiguration)
+ {
+ pConfiguration->Length = sizeof(NDIS_802_11_CONFIGURATION);
+ pConfiguration->BeaconPeriod = pAdapter->CommonCfg.BeaconPeriod;
+ pConfiguration->ATIMWindow = pAdapter->StaActive.AtimWin;
+ MAP_CHANNEL_ID_TO_KHZ(pAdapter->CommonCfg.Channel, pConfiguration->DSConfig);
+ wrq->u.data.length = sizeof(NDIS_802_11_CONFIGURATION);
+ Status = copy_to_user(wrq->u.data.pointer, pConfiguration, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(BeaconPeriod=%ld,AtimW=%ld,Channel=%d) \n",
+ pConfiguration->BeaconPeriod, pConfiguration->ATIMWindow, pAdapter->CommonCfg.Channel));
+ kfree(pConfiguration);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CONFIGURATION(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_SNR_0:
+ if ((pAdapter->StaCfg.LastSNR0 > 0))
+ {
+ ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR0) * 3) / 16 ;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_SNR_0(0x=%lx)\n", ulInfo));
+ }
+ else
+ Status = -EFAULT;
+ break;
+ case RT_OID_802_11_SNR_1:
+ if ((pAdapter->Antenna.field.RxPath > 1) &&
+ (pAdapter->StaCfg.LastSNR1 > 0))
+ {
+ ulInfo = ((0xeb - pAdapter->StaCfg.LastSNR1) * 3) / 16 ;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(0x=%lx)\n",ulInfo));
+ }
+ else
+ Status = -EFAULT;
+ DBGPRINT(RT_DEBUG_TRACE,("Query::RT_OID_802_11_SNR_1(pAdapter->StaCfg.LastSNR1=%d)\n",pAdapter->StaCfg.LastSNR1));
+ break;
+ case OID_802_11_RSSI_TRIGGER:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0 - pAdapter->BbpRssiToDbmDelta;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RSSI_TRIGGER(=%ld)\n", ulInfo));
+ break;
+ case OID_802_11_RSSI:
+ case RT_OID_802_11_RSSI:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi0;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_RSSI_1:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi1;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_RSSI_2:
+ ulInfo = pAdapter->StaCfg.RssiSample.LastRssi2;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case OID_802_11_STATISTICS:
+ pStatistics = (NDIS_802_11_STATISTICS *) kmalloc(sizeof(NDIS_802_11_STATISTICS), MEM_ALLOC_FLAG);
+ if (pStatistics)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS \n"));
+ // add the most up-to-date h/w raw counters into software counters
+ NICUpdateRawCounters(pAdapter);
+
+ // Sanity check for calculation of sucessful count
+ if (pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart < pAdapter->WlanCounters.RetryCount.QuadPart)
+ pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
+
+ pStatistics->TransmittedFragmentCount.QuadPart = pAdapter->WlanCounters.TransmittedFragmentCount.QuadPart;
+ pStatistics->MulticastTransmittedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastTransmittedFrameCount.QuadPart;
+ pStatistics->FailedCount.QuadPart = pAdapter->WlanCounters.FailedCount.QuadPart;
+ pStatistics->RetryCount.QuadPart = pAdapter->WlanCounters.RetryCount.QuadPart;
+ pStatistics->MultipleRetryCount.QuadPart = pAdapter->WlanCounters.MultipleRetryCount.QuadPart;
+ pStatistics->RTSSuccessCount.QuadPart = pAdapter->WlanCounters.RTSSuccessCount.QuadPart;
+ pStatistics->RTSFailureCount.QuadPart = pAdapter->WlanCounters.RTSFailureCount.QuadPart;
+ pStatistics->ACKFailureCount.QuadPart = pAdapter->WlanCounters.ACKFailureCount.QuadPart;
+ pStatistics->FrameDuplicateCount.QuadPart = pAdapter->WlanCounters.FrameDuplicateCount.QuadPart;
+ pStatistics->ReceivedFragmentCount.QuadPart = pAdapter->WlanCounters.ReceivedFragmentCount.QuadPart;
+ pStatistics->MulticastReceivedFrameCount.QuadPart = pAdapter->WlanCounters.MulticastReceivedFrameCount.QuadPart;
+#ifdef DBG
+ pStatistics->FCSErrorCount = pAdapter->RalinkCounters.RealFcsErrCount;
+#else
+ pStatistics->FCSErrorCount.QuadPart = pAdapter->WlanCounters.FCSErrorCount.QuadPart;
+ pStatistics->FrameDuplicateCount.u.LowPart = pAdapter->WlanCounters.FrameDuplicateCount.u.LowPart / 100;
+#endif
+ wrq->u.data.length = sizeof(NDIS_802_11_STATISTICS);
+ Status = copy_to_user(wrq->u.data.pointer, pStatistics, wrq->u.data.length);
+ kfree(pStatistics);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_STATISTICS(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case OID_GEN_RCV_OK:
+ ulInfo = pAdapter->Counters8023.GoodReceives;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case OID_GEN_RCV_NO_BUFFER:
+ ulInfo = pAdapter->Counters8023.RxNoBuffer;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_PHY_MODE:
+ ulInfo = (ULONG)pAdapter->CommonCfg.PhyMode;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PHY_MODE (=%ld)\n", ulInfo));
+ break;
+ case RT_OID_802_11_STA_CONFIG:
+ pStaConfig = (RT_802_11_STA_CONFIG *) kmalloc(sizeof(RT_802_11_STA_CONFIG), MEM_ALLOC_FLAG);
+ if (pStaConfig)
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG\n"));
+ pStaConfig->EnableTxBurst = pAdapter->CommonCfg.bEnableTxBurst;
+ pStaConfig->EnableTurboRate = 0;
+ pStaConfig->UseBGProtection = pAdapter->CommonCfg.UseBGProtection;
+ pStaConfig->UseShortSlotTime = pAdapter->CommonCfg.bUseShortSlotTime;
+ //pStaConfig->AdhocMode = pAdapter->StaCfg.AdhocMode;
+ pStaConfig->HwRadioStatus = (pAdapter->StaCfg.bHwRadio == TRUE) ? 1 : 0;
+ pStaConfig->Rsv1 = 0;
+ pStaConfig->SystemErrorBitmap = pAdapter->SystemErrorBitmap;
+ wrq->u.data.length = sizeof(RT_802_11_STA_CONFIG);
+ Status = copy_to_user(wrq->u.data.pointer, pStaConfig, wrq->u.data.length);
+ kfree(pStaConfig);
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case OID_802_11_RTS_THRESHOLD:
+ RtsThresh = pAdapter->CommonCfg.RtsThreshold;
+ wrq->u.data.length = sizeof(RtsThresh);
+ Status = copy_to_user(wrq->u.data.pointer, &RtsThresh, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_RTS_THRESHOLD(=%ld)\n", RtsThresh));
+ break;
+ case OID_802_11_FRAGMENTATION_THRESHOLD:
+ FragThresh = pAdapter->CommonCfg.FragmentThreshold;
+ if (pAdapter->CommonCfg.bUseZeroToDisableFragment == TRUE)
+ FragThresh = 0;
+ wrq->u.data.length = sizeof(FragThresh);
+ Status = copy_to_user(wrq->u.data.pointer, &FragThresh, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_FRAGMENTATION_THRESHOLD(=%ld)\n", FragThresh));
+ break;
+ case OID_802_11_POWER_MODE:
+ PowerMode = pAdapter->StaCfg.WindowsPowerMode;
+ wrq->u.data.length = sizeof(PowerMode);
+ Status = copy_to_user(wrq->u.data.pointer, &PowerMode, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_POWER_MODE(=%d)\n", PowerMode));
+ break;
+ case RT_OID_802_11_RADIO:
+ RadioState = (BOOLEAN) pAdapter->StaCfg.bSwRadio;
+ wrq->u.data.length = sizeof(RadioState);
+ Status = copy_to_user(wrq->u.data.pointer, &RadioState, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_RADIO (=%d)\n", RadioState));
+ break;
+ case OID_802_11_INFRASTRUCTURE_MODE:
+ if (pAdapter->StaCfg.BssType == BSS_ADHOC)
+ BssType = Ndis802_11IBSS;
+ else if (pAdapter->StaCfg.BssType == BSS_INFRA)
+ BssType = Ndis802_11Infrastructure;
+ else if (pAdapter->StaCfg.BssType == BSS_MONITOR)
+ BssType = Ndis802_11Monitor;
+ else
+ BssType = Ndis802_11AutoUnknown;
+
+ wrq->u.data.length = sizeof(BssType);
+ Status = copy_to_user(wrq->u.data.pointer, &BssType, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_INFRASTRUCTURE_MODE(=%d)\n", BssType));
+ break;
+ case RT_OID_802_11_PREAMBLE:
+ PreamType = pAdapter->CommonCfg.TxPreamble;
+ wrq->u.data.length = sizeof(PreamType);
+ Status = copy_to_user(wrq->u.data.pointer, &PreamType, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PREAMBLE(=%d)\n", PreamType));
+ break;
+ case OID_802_11_AUTHENTICATION_MODE:
+ AuthMode = pAdapter->StaCfg.AuthMode;
+ wrq->u.data.length = sizeof(AuthMode);
+ Status = copy_to_user(wrq->u.data.pointer, &AuthMode, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_AUTHENTICATION_MODE(=%d)\n", AuthMode));
+ break;
+ case OID_802_11_WEP_STATUS:
+ WepStatus = pAdapter->StaCfg.WepStatus;
+ wrq->u.data.length = sizeof(WepStatus);
+ Status = copy_to_user(wrq->u.data.pointer, &WepStatus, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEP_STATUS(=%d)\n", WepStatus));
+ break;
+ case OID_802_11_TX_POWER_LEVEL:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPower, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_TX_POWER_LEVEL %x\n",pAdapter->CommonCfg.TxPower));
+ break;
+ case RT_OID_802_11_TX_POWER_LEVEL_1:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.TxPowerPercentage, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_TX_POWER_LEVEL_1 (=%ld)\n", pAdapter->CommonCfg.TxPowerPercentage));
+ break;
+ case OID_802_11_NETWORK_TYPES_SUPPORTED:
+ if ((pAdapter->RfIcType == RFIC_2850) || (pAdapter->RfIcType == RFIC_2750))
+ {
+ NetworkTypeList[0] = 3; // NumberOfItems = 3
+ NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
+ NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
+ NetworkTypeList[3] = Ndis802_11OFDM5; // NetworkType[3] = 11a
+ wrq->u.data.length = 16;
+ Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
+ }
+ else
+ {
+ NetworkTypeList[0] = 2; // NumberOfItems = 2
+ NetworkTypeList[1] = Ndis802_11DS; // NetworkType[1] = 11b
+ NetworkTypeList[2] = Ndis802_11OFDM24; // NetworkType[2] = 11g
+ wrq->u.data.length = 12;
+ Status = copy_to_user(wrq->u.data.pointer, &NetworkTypeList[0], wrq->u.data.length);
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_NETWORK_TYPES_SUPPORTED\n"));
+ break;
+ case OID_802_11_NETWORK_TYPE_IN_USE:
+ wrq->u.data.length = sizeof(ULONG);
+ if (pAdapter->CommonCfg.PhyMode == PHY_11A)
+ ulInfo = Ndis802_11OFDM5;
+ else if ((pAdapter->CommonCfg.PhyMode == PHY_11BG_MIXED) || (pAdapter->CommonCfg.PhyMode == PHY_11G))
+ ulInfo = Ndis802_11OFDM24;
+ else
+ ulInfo = Ndis802_11DS;
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_LAST_RX_RATE:
+ ulInfo = (ULONG)pAdapter->LastRxRate;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_RX_RATE (=%ld)\n", ulInfo));
+ break;
+ case RT_OID_802_11_QUERY_LAST_TX_RATE:
+ //ulInfo = (ULONG)pAdapter->LastTxRate;
+ ulInfo = (ULONG)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word;
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_LAST_TX_RATE (=%lx)\n", ulInfo));
+ break;
+ case RT_OID_802_11_QUERY_EEPROM_VERSION:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->EepromVersion, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_FIRMWARE_VERSION:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->FirmwareVersion, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_NOISE_LEVEL:
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->BbpWriteLatch[66], wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_NOISE_LEVEL (=%d)\n", pAdapter->BbpWriteLatch[66]));
+ break;
+ case RT_OID_802_11_EXTRA_INFO:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->ExtraInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_EXTRA_INFO (=%ld)\n", pAdapter->ExtraInfo));
+ break;
+ case RT_OID_WE_VERSION_COMPILED:
+ wrq->u.data.length = sizeof(UINT);
+ we_version_compiled = WIRELESS_EXT;
+ Status = copy_to_user(wrq->u.data.pointer, &we_version_compiled, wrq->u.data.length);
+ break;
+ case RT_OID_802_11_QUERY_APSD_SETTING:
+ apsd = (pAdapter->CommonCfg.bAPSDCapable | (pAdapter->CommonCfg.bAPSDAC_BE << 1) | (pAdapter->CommonCfg.bAPSDAC_BK << 2)
+ | (pAdapter->CommonCfg.bAPSDAC_VI << 3) | (pAdapter->CommonCfg.bAPSDAC_VO << 4) | (pAdapter->CommonCfg.MaxSPLength << 5));
+
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &apsd, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_SETTING (=0x%lx,APSDCap=%d,AC_BE=%d,AC_BK=%d,AC_VI=%d,AC_VO=%d,MAXSPLen=%d)\n",
+ apsd,pAdapter->CommonCfg.bAPSDCapable,pAdapter->CommonCfg.bAPSDAC_BE,pAdapter->CommonCfg.bAPSDAC_BK,pAdapter->CommonCfg.bAPSDAC_VI,pAdapter->CommonCfg.bAPSDAC_VO,pAdapter->CommonCfg.MaxSPLength));
+ break;
+ case RT_OID_802_11_QUERY_APSD_PSM:
+ wrq->u.data.length = sizeof(ULONG);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bAPSDForcePowerSave, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_APSD_PSM (=%d)\n", pAdapter->CommonCfg.bAPSDForcePowerSave));
+ break;
+ case RT_OID_802_11_QUERY_WMM:
+ wrq->u.data.length = sizeof(BOOLEAN);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bWmmCapable, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_WMM (=%d)\n", pAdapter->CommonCfg.bWmmCapable));
+ break;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ case RT_OID_NEW_DRIVER:
+ {
+ UCHAR enabled = 1;
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &enabled, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_NEW_DRIVER (=%d)\n", enabled));
+ }
+ break;
+ case RT_OID_WPA_SUPPLICANT_SUPPORT:
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.WpaSupplicantUP, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_WPA_SUPPLICANT_SUPPORT (=%d)\n", pAdapter->StaCfg.WpaSupplicantUP));
+ break;
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+ case RT_OID_DRIVER_DEVICE_NAME:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_DRIVER_DEVICE_NAME \n"));
+ wrq->u.data.length = 16;
+ if (copy_to_user(wrq->u.data.pointer, pAdapter->StaCfg.dev_name, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_QUERY_HT_PHYMODE:
+ pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
+ if (pHTPhyMode)
+ {
+ pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
+ pHTPhyMode->HtMode = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MODE;
+ pHTPhyMode->BW = (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.BW;
+ pHTPhyMode->MCS= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.MCS;
+ pHTPhyMode->SHORTGI= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.ShortGI;
+ pHTPhyMode->STBC= (UCHAR)pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.field.STBC;
+
+ pHTPhyMode->ExtOffset = ((pAdapter->CommonCfg.CentralChannel < pAdapter->CommonCfg.Channel) ? (EXTCHA_BELOW) : (EXTCHA_ABOVE));
+ wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
+ if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
+ pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_COUNTRY_REGION:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_COUNTRY_REGION \n"));
+ wrq->u.data.length = sizeof(ulInfo);
+ ulInfo = pAdapter->CommonCfg.CountryRegionForABand;
+ ulInfo = (ulInfo << 8)|(pAdapter->CommonCfg.CountryRegion);
+ if (copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_802_11_QUERY_DAT_HT_PHYMODE:
+ pHTPhyMode = (OID_SET_HT_PHYMODE *) kmalloc(sizeof(OID_SET_HT_PHYMODE), MEM_ALLOC_FLAG);
+ if (pHTPhyMode)
+ {
+ pHTPhyMode->PhyMode = pAdapter->CommonCfg.PhyMode;
+ pHTPhyMode->HtMode = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.HTMODE;
+ pHTPhyMode->BW = (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.BW;
+ pHTPhyMode->MCS= (UCHAR)pAdapter->StaCfg.DesiredTransmitSetting.field.MCS;
+ pHTPhyMode->SHORTGI= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.ShortGI;
+ pHTPhyMode->STBC= (UCHAR)pAdapter->CommonCfg.RegTransmitSetting.field.STBC;
+
+ wrq->u.data.length = sizeof(OID_SET_HT_PHYMODE);
+ if (copy_to_user(wrq->u.data.pointer, pHTPhyMode, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_HT_PHYMODE (PhyMode = %d, MCS =%d, BW = %d, STBC = %d, ExtOffset=%d)\n",
+ pHTPhyMode->HtMode, pHTPhyMode->MCS, pHTPhyMode->BW, pHTPhyMode->STBC, pHTPhyMode->ExtOffset));
+ DBGPRINT(RT_DEBUG_TRACE, (" MlmeUpdateTxRates (.word = %x )\n", pAdapter->MacTab.Content[BSSID_WCID].HTPhyMode.word));
+ }
+ else
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_STA_CONFIG(kmalloc failed)\n"));
+ Status = -EFAULT;
+ }
+ break;
+ case RT_OID_QUERY_MULTIPLE_CARD_SUPPORT:
+ wrq->u.data.length = sizeof(UCHAR);
+ i = 0;
+#ifdef MULTIPLE_CARD_SUPPORT
+ i = 1;
+#endif // MULTIPLE_CARD_SUPPORT //
+ if (copy_to_user(wrq->u.data.pointer, &i, wrq->u.data.length))
+ {
+ Status = -EFAULT;
+ }
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_QUERY_MULTIPLE_CARD_SUPPORT(=%d) \n", i));
+ break;
+#ifdef SNMP_SUPPORT
+ case RT_OID_802_11_MAC_ADDRESS:
+ wrq->u.data.length = MAC_ADDR_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_MANUFACTUREROUI:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREROUI \n"));
+ wrq->u.data.length = ManufacturerOUI_LEN;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CurrentAddress, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_MANUFACTURERNAME:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTURERNAME \n"));
+ wrq->u.data.length = strlen(ManufacturerNAME);
+ Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_RESOURCETYPEIDNAME:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_RESOURCETYPEIDNAME \n"));
+ wrq->u.data.length = strlen(ResourceTypeIdName);
+ Status = copy_to_user(wrq->u.data.pointer, ResourceTypeIdName, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRIVACYOPTIONIMPLEMENTED \n"));
+ ulInfo = 1; // 1 is support wep else 2 is not support.
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_POWERMANAGEMENTMODE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_POWERMANAGEMENTMODE \n"));
+ if (pAdapter->StaCfg.Psm == PSMP_ACTION)
+ ulInfo = 1; // 1 is power active else 2 is power save.
+ else
+ ulInfo = 2;
+
+ wrq->u.data.length = sizeof(ulInfo);
+ Status = copy_to_user(wrq->u.data.pointer, &ulInfo, wrq->u.data.length);
+ break;
+
+ case OID_802_11_WEPDEFAULTKEYVALUE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_WEPDEFAULTKEYVALUE \n"));
+ //KeyIdxValue.KeyIdx = pAd->PortCfg.MBSSID[pAd->IoctlIF].DefaultKeyId;
+ pKeyIdxValue = wrq->u.data.pointer;
+ DBGPRINT(RT_DEBUG_TRACE,("KeyIdxValue.KeyIdx = %d, \n",pKeyIdxValue->KeyIdx));
+ valueLen = pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen;
+ NdisMoveMemory(pKeyIdxValue->Value,
+ &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].Key,
+ valueLen);
+ pKeyIdxValue->Value[valueLen]='\0';
+
+ wrq->u.data.length = sizeof(DefaultKeyIdxValue);
+
+ Status = copy_to_user(wrq->u.data.pointer, pKeyIdxValue, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE,("DefaultKeyId = %d, total len = %d, str len=%d, KeyValue= %02x %02x %02x %02x \n", pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length, pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
+ pAdapter->SharedKey[BSS0][0].Key[0],
+ pAdapter->SharedKey[BSS0][1].Key[0],
+ pAdapter->SharedKey[BSS0][2].Key[0],
+ pAdapter->SharedKey[BSS0][3].Key[0]));
+ break;
+
+ case OID_802_11_WEPDEFAULTKEYID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPDEFAULTKEYID \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->StaCfg.DefaultKeyId, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("DefaultKeyId =%d \n", pAdapter->StaCfg.DefaultKeyId));
+ break;
+
+ case RT_OID_802_11_WEPKEYMAPPINGLENGTH:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_WEPKEYMAPPINGLENGTH \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ Status = copy_to_user(wrq->u.data.pointer,
+ &pAdapter->SharedKey[BSS0][pAdapter->StaCfg.DefaultKeyId].KeyLen,
+ wrq->u.data.length);
+ break;
+
+ case OID_802_11_SHORTRETRYLIMIT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_SHORTRETRYLIMIT \n"));
+ wrq->u.data.length = sizeof(ULONG);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ ShortRetryLimit = tx_rty_cfg.field.ShortRtyLimit;
+ DBGPRINT(RT_DEBUG_TRACE, ("ShortRetryLimit =%ld, tx_rty_cfg.field.ShortRetryLimit=%d\n", ShortRetryLimit, tx_rty_cfg.field.ShortRtyLimit));
+ Status = copy_to_user(wrq->u.data.pointer, &ShortRetryLimit, wrq->u.data.length);
+ break;
+
+ case OID_802_11_LONGRETRYLIMIT:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_LONGRETRYLIMIT \n"));
+ wrq->u.data.length = sizeof(ULONG);
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ LongRetryLimit = tx_rty_cfg.field.LongRtyLimit;
+ DBGPRINT(RT_DEBUG_TRACE, ("LongRetryLimit =%ld, tx_rty_cfg.field.LongRtyLimit=%d\n", LongRetryLimit, tx_rty_cfg.field.LongRtyLimit));
+ Status = copy_to_user(wrq->u.data.pointer, &LongRetryLimit, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_PRODUCTID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_PRODUCTID \n"));
+
+#ifdef RT2870
+ sprintf(tmp, "%04x %04x\n", ((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idVendor ,((POS_COOKIE)pAdapter->OS_Cookie)->pUsb_Dev->descriptor.idProduct);
+
+#endif // RT2870 //
+ wrq->u.data.length = strlen(tmp);
+ Status = copy_to_user(wrq->u.data.pointer, tmp, wrq->u.data.length);
+ break;
+
+ case RT_OID_802_11_MANUFACTUREID:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_MANUFACTUREID \n"));
+ wrq->u.data.length = strlen(ManufacturerNAME);
+ Status = copy_to_user(wrq->u.data.pointer, ManufacturerNAME, wrq->u.data.length);
+ break;
+
+ case OID_802_11_CURRENTCHANNEL:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_CURRENTCHANNEL \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+ DBGPRINT(RT_DEBUG_TRACE, ("sizeof UCHAR=%d, channel=%d \n", sizeof(UCHAR), pAdapter->CommonCfg.Channel));
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Channel, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ break;
+#endif //SNMP_SUPPORT
+
+ case OID_802_11_BUILD_CHANNEL_EX:
+ {
+ UCHAR value;
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_BUILD_CHANNEL_EX \n"));
+ wrq->u.data.length = sizeof(UCHAR);
+#ifdef EXT_BUILD_CHANNEL_LIST
+ DBGPRINT(RT_DEBUG_TRACE, ("Support EXT_BUILD_CHANNEL_LIST.\n"));
+ value = 1;
+#else
+ DBGPRINT(RT_DEBUG_TRACE, ("Doesn't support EXT_BUILD_CHANNEL_LIST.\n"));
+ value = 0;
+#endif // EXT_BUILD_CHANNEL_LIST //
+ Status = copy_to_user(wrq->u.data.pointer, &value, 1);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ }
+ break;
+
+ case OID_802_11_GET_CH_LIST:
+ {
+ PRT_CHANNEL_LIST_INFO pChListBuf;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CH_LIST \n"));
+ if (pAdapter->ChannelListNum == 0)
+ {
+ wrq->u.data.length = 0;
+ break;
+ }
+
+ pChListBuf = (RT_CHANNEL_LIST_INFO *) kmalloc(sizeof(RT_CHANNEL_LIST_INFO), MEM_ALLOC_FLAG);
+ if (pChListBuf == NULL)
+ {
+ wrq->u.data.length = 0;
+ break;
+ }
+
+ pChListBuf->ChannelListNum = pAdapter->ChannelListNum;
+ for (i = 0; i < pChListBuf->ChannelListNum; i++)
+ pChListBuf->ChannelList[i] = pAdapter->ChannelList[i].Channel;
+
+ wrq->u.data.length = sizeof(RT_CHANNEL_LIST_INFO);
+ Status = copy_to_user(wrq->u.data.pointer, pChListBuf, sizeof(RT_CHANNEL_LIST_INFO));
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+
+ if (pChListBuf)
+ kfree(pChListBuf);
+ }
+ break;
+
+ case OID_802_11_GET_COUNTRY_CODE:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_COUNTRY_CODE \n"));
+ wrq->u.data.length = 2;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.CountryCode, 2);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ break;
+
+ case OID_802_11_GET_CHANNEL_GEOGRAPHY:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::OID_802_11_GET_CHANNEL_GEOGRAPHY \n"));
+ wrq->u.data.length = 1;
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.Geography, 1);
+ DBGPRINT(RT_DEBUG_TRACE, ("Status=%d\n", Status));
+ break;
+
+
+#ifdef QOS_DLS_SUPPORT
+ case RT_OID_802_11_QUERY_DLS:
+ wrq->u.data.length = sizeof(BOOLEAN);
+ Status = copy_to_user(wrq->u.data.pointer, &pAdapter->CommonCfg.bDLSCapable, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS(=%d)\n", pAdapter->CommonCfg.bDLSCapable));
+ break;
+
+ case RT_OID_802_11_QUERY_DLS_PARAM:
+ {
+ PRT_802_11_DLS_INFO pDlsInfo = kmalloc(sizeof(RT_802_11_DLS_INFO), GFP_ATOMIC);
+ if (pDlsInfo == NULL)
+ break;
+
+ for (i=0; i<MAX_NUM_OF_DLS_ENTRY; i++)
+ {
+ RTMPMoveMemory(&pDlsInfo->Entry[i], &pAdapter->StaCfg.DLSEntry[i], sizeof(RT_802_11_DLS_UI));
+ }
+
+ pDlsInfo->num = MAX_NUM_OF_DLS_ENTRY;
+ wrq->u.data.length = sizeof(RT_802_11_DLS_INFO);
+ Status = copy_to_user(wrq->u.data.pointer, pDlsInfo, wrq->u.data.length);
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::RT_OID_802_11_QUERY_DLS_PARAM\n"));
+
+ if (pDlsInfo)
+ kfree(pDlsInfo);
+ }
+ break;
+#endif // QOS_DLS_SUPPORT //
+ default:
+ DBGPRINT(RT_DEBUG_TRACE, ("Query::unknown IOCTL's subcmd = 0x%08x\n", cmd));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+ return Status;
+}
+
+INT rt28xx_sta_ioctl(
+ IN struct net_device *net_dev,
+ IN OUT struct ifreq *rq,
+ IN INT cmd)
+{
+ POS_COOKIE pObj;
+ VIRTUAL_ADAPTER *pVirtualAd = NULL;
+ RTMP_ADAPTER *pAd = NULL;
+ struct iwreq *wrq = (struct iwreq *) rq;
+ BOOLEAN StateMachineTouched = FALSE;
+ INT Status = NDIS_STATUS_SUCCESS;
+ USHORT subcmd;
+
+ if (net_dev->priv_flags == INT_MAIN)
+ {
+ pAd = net_dev->ml_priv;
+ }
+ else
+ {
+ pVirtualAd = net_dev->ml_priv;
+ pAd = pVirtualAd->RtmpDev->ml_priv;
+ }
+ pObj = (POS_COOKIE) pAd->OS_Cookie;
+
+ if (pAd == NULL)
+ {
+ /* if 1st open fail, pAd will be free;
+ So the net_dev->ml_priv will be NULL in 2rd open */
+ return -ENETDOWN;
+ }
+
+ //check if the interface is down
+ if(!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_INTERRUPT_IN_USE))
+ {
+#ifdef CONFIG_APSTA_MIXED_SUPPORT
+ if (wrq->u.data.pointer == NULL)
+ {
+ return Status;
+ }
+
+ if (strstr(wrq->u.data.pointer, "OpMode") == NULL)
+#endif // CONFIG_APSTA_MIXED_SUPPORT //
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("INFO::Network is down!\n"));
+ return -ENETDOWN;
+ }
+ }
+
+ { // determine this ioctl command is comming from which interface.
+ pObj->ioctl_if_type = INT_MAIN;
+ pObj->ioctl_if = MAIN_MBSSID;
+ }
+
+ switch(cmd)
+ {
+#ifdef RALINK_ATE
+#ifdef RALINK_28xx_QA
+ case RTPRIV_IOCTL_ATE:
+ {
+ RtmpDoAte(pAd, wrq);
+ }
+ break;
+#endif // RALINK_28xx_QA //
+#endif // RALINK_ATE //
+ case SIOCGIFHWADDR:
+ DBGPRINT(RT_DEBUG_TRACE, ("IOCTL::SIOCGIFHWADDR\n"));
+ memcpy(wrq->u.name, pAd->CurrentAddress, ETH_ALEN);
+ break;
+ case SIOCGIWNAME:
+ {
+ char *name=&wrq->u.name[0];
+ rt_ioctl_giwname(net_dev, NULL, name, NULL);
+ break;
+ }
+ case SIOCGIWESSID: //Get ESSID
+ {
+ struct iw_point *essid=&wrq->u.essid;
+ rt_ioctl_giwessid(net_dev, NULL, essid, essid->pointer);
+ break;
+ }
+ case SIOCSIWESSID: //Set ESSID
+ {
+ struct iw_point *essid=&wrq->u.essid;
+ rt_ioctl_siwessid(net_dev, NULL, essid, essid->pointer);
+ break;
+ }
+ case SIOCSIWNWID: // set network id (the cell)
+ case SIOCGIWNWID: // get network id
+ Status = -EOPNOTSUPP;
+ break;
+ case SIOCSIWFREQ: //set channel/frequency (Hz)
+ {
+ struct iw_freq *freq=&wrq->u.freq;
+ rt_ioctl_siwfreq(net_dev, NULL, freq, NULL);
+ break;
+ }
+ case SIOCGIWFREQ: // get channel/frequency (Hz)
+ {
+ struct iw_freq *freq=&wrq->u.freq;
+ rt_ioctl_giwfreq(net_dev, NULL, freq, NULL);
+ break;
+ }
+ case SIOCSIWNICKN: //set node name/nickname
+ {
+ struct iw_point *data=&wrq->u.data;
+ rt_ioctl_siwnickn(net_dev, NULL, data, NULL);
+ break;
+ }
+ case SIOCGIWNICKN: //get node name/nickname
+ {
+ struct iw_point *data=&wrq->u.data;
+ rt_ioctl_giwnickn(net_dev, NULL, data, NULL);
+ break;
+ }
+ case SIOCGIWRATE: //get default bit rate (bps)
+ rt_ioctl_giwrate(net_dev, NULL, &wrq->u, NULL);
+ break;
+ case SIOCSIWRATE: //set default bit rate (bps)
+ rt_ioctl_siwrate(net_dev, NULL, &wrq->u, NULL);
+ break;
+ case SIOCGIWRTS: // get RTS/CTS threshold (bytes)
+ {
+ struct iw_param *rts=&wrq->u.rts;
+ rt_ioctl_giwrts(net_dev, NULL, rts, NULL);
+ break;
+ }
+ case SIOCSIWRTS: //set RTS/CTS threshold (bytes)
+ {
+ struct iw_param *rts=&wrq->u.rts;
+ rt_ioctl_siwrts(net_dev, NULL, rts, NULL);
+ break;
+ }
+ case SIOCGIWFRAG: //get fragmentation thr (bytes)
+ {
+ struct iw_param *frag=&wrq->u.frag;
+ rt_ioctl_giwfrag(net_dev, NULL, frag, NULL);
+ break;
+ }
+ case SIOCSIWFRAG: //set fragmentation thr (bytes)
+ {
+ struct iw_param *frag=&wrq->u.frag;
+ rt_ioctl_siwfrag(net_dev, NULL, frag, NULL);
+ break;
+ }
+ case SIOCGIWENCODE: //get encoding token & mode
+ {
+ struct iw_point *erq=&wrq->u.encoding;
+ if(erq->pointer)
+ rt_ioctl_giwencode(net_dev, NULL, erq, erq->pointer);
+ break;
+ }
+ case SIOCSIWENCODE: //set encoding token & mode
+ {
+ struct iw_point *erq=&wrq->u.encoding;
+ if(erq->pointer)
+ rt_ioctl_siwencode(net_dev, NULL, erq, erq->pointer);
+ break;
+ }
+ case SIOCGIWAP: //get access point MAC addresses
+ {
+ struct sockaddr *ap_addr=&wrq->u.ap_addr;
+ rt_ioctl_giwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+ break;
+ }
+ case SIOCSIWAP: //set access point MAC addresses
+ {
+ struct sockaddr *ap_addr=&wrq->u.ap_addr;
+ rt_ioctl_siwap(net_dev, NULL, ap_addr, ap_addr->sa_data);
+ break;
+ }
+ case SIOCGIWMODE: //get operation mode
+ {
+ __u32 *mode=&wrq->u.mode;
+ rt_ioctl_giwmode(net_dev, NULL, mode, NULL);
+ break;
+ }
+ case SIOCSIWMODE: //set operation mode
+ {
+ __u32 *mode=&wrq->u.mode;
+ rt_ioctl_siwmode(net_dev, NULL, mode, NULL);
+ break;
+ }
+ case SIOCGIWSENS: //get sensitivity (dBm)
+ case SIOCSIWSENS: //set sensitivity (dBm)
+ case SIOCGIWPOWER: //get Power Management settings
+ case SIOCSIWPOWER: //set Power Management settings
+ case SIOCGIWTXPOW: //get transmit power (dBm)
+ case SIOCSIWTXPOW: //set transmit power (dBm)
+ case SIOCGIWRANGE: //Get range of parameters
+ case SIOCGIWRETRY: //get retry limits and lifetime
+ case SIOCSIWRETRY: //set retry limits and lifetime
+ Status = -EOPNOTSUPP;
+ break;
+ case RT_PRIV_IOCTL:
+ case RT_PRIV_IOCTL_EXT:
+ subcmd = wrq->u.data.flags;
+ if( subcmd & OID_GET_SET_TOGGLE)
+ Status = RTMPSetInformation(pAd, rq, subcmd);
+ else
+ Status = RTMPQueryInformation(pAd, rq, subcmd);
+ break;
+ case SIOCGIWPRIV:
+ if (wrq->u.data.pointer)
+ {
+ if ( access_ok(VERIFY_WRITE, wrq->u.data.pointer, sizeof(privtab)) != TRUE)
+ break;
+ wrq->u.data.length = sizeof(privtab) / sizeof(privtab[0]);
+ if (copy_to_user(wrq->u.data.pointer, privtab, sizeof(privtab)))
+ Status = -EFAULT;
+ }
+ break;
+ case RTPRIV_IOCTL_SET:
+ if(access_ok(VERIFY_READ, wrq->u.data.pointer, wrq->u.data.length) != TRUE)
+ break;
+ rt_ioctl_setparam(net_dev, NULL, NULL, wrq->u.data.pointer);
+ break;
+ case RTPRIV_IOCTL_GSITESURVEY:
+ RTMPIoctlGetSiteSurvey(pAd, wrq);
+ break;
+#ifdef DBG
+ case RTPRIV_IOCTL_MAC:
+ RTMPIoctlMAC(pAd, wrq);
+ break;
+ case RTPRIV_IOCTL_E2P:
+ RTMPIoctlE2PROM(pAd, wrq);
+ break;
+#ifdef RT30xx
+ case RTPRIV_IOCTL_RF:
+ RTMPIoctlRF(pAd, wrq);
+ break;
+#endif // RT30xx //
+#endif // DBG //
+ case SIOCETHTOOL:
+ break;
+ default:
+ DBGPRINT(RT_DEBUG_ERROR, ("IOCTL::unknown IOCTL's cmd = 0x%08x\n", cmd));
+ Status = -EOPNOTSUPP;
+ break;
+ }
+
+ if(StateMachineTouched) // Upper layer sent a MLME-related operations
+ RT28XX_MLME_HANDLER(pAd);
+
+ return Status;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set SSID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_SSID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ NDIS_802_11_SSID Ssid, *pSsid=NULL;
+ BOOLEAN StateMachineTouched = FALSE;
+ int success = TRUE;
+
+ if( strlen(arg) <= MAX_LEN_OF_SSID)
+ {
+ NdisZeroMemory(&Ssid, sizeof(NDIS_802_11_SSID));
+ if (strlen(arg) != 0)
+ {
+ NdisMoveMemory(Ssid.Ssid, arg, strlen(arg));
+ Ssid.SsidLength = strlen(arg);
+ }
+ else //ANY ssid
+ {
+ Ssid.SsidLength = 0;
+ memcpy(Ssid.Ssid, "", 0);
+ pAdapter->StaCfg.BssType = BSS_INFRA;
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ pAdapter->StaCfg.WepStatus = Ndis802_11EncryptionDisabled;
+ }
+ pSsid = &Ssid;
+
+ if (pAdapter->Mlme.CntlMachine.CurrState != CNTL_IDLE)
+ {
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("!!! MLME busy, reset MLME state machine !!!\n"));
+ }
+
+ pAdapter->MlmeAux.CurrReqIsFromNdis = TRUE;
+ pAdapter->StaCfg.bScanReqIsFromWebUI = FALSE;
+ pAdapter->bConfigChanged = TRUE;
+
+ MlmeEnqueue(pAdapter,
+ MLME_CNTL_STATE_MACHINE,
+ OID_802_11_SSID,
+ sizeof(NDIS_802_11_SSID),
+ (VOID *)pSsid);
+
+ StateMachineTouched = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_SSID_Proc::(Len=%d,Ssid=%s)\n", Ssid.SsidLength, Ssid.Ssid));
+ }
+ else
+ success = FALSE;
+
+ if (StateMachineTouched) // Upper layer sent a MLME-related operations
+ RT28XX_MLME_HANDLER(pAdapter);
+
+ return success;
+}
+
+#ifdef WMM_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set WmmCapable Enable or Disable
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_WmmCapable_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ BOOLEAN bWmmCapable;
+
+ bWmmCapable = simple_strtol(arg, 0, 10);
+
+ if ((bWmmCapable == 1)
+#ifdef RT2870
+ && (pAd->NumberOfPipes >= 5)
+#endif // RT2870 //
+ )
+ pAd->CommonCfg.bWmmCapable = TRUE;
+ else if (bWmmCapable == 0)
+ pAd->CommonCfg.bWmmCapable = FALSE;
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WmmCapable_Proc::(bWmmCapable=%d)\n",
+ pAd->CommonCfg.bWmmCapable));
+
+ return TRUE;
+}
+#endif // WMM_SUPPORT //
+
+/*
+ ==========================================================================
+ Description:
+ Set Network Type(Infrastructure/Adhoc mode)
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_NetworkType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ UINT32 Value = 0;
+
+ if (strcmp(arg, "Adhoc") == 0)
+ {
+ if (pAdapter->StaCfg.BssType != BSS_ADHOC)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ if (MONITOR_ON(pAdapter))
+ {
+ RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
+ RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+ Value &= (~0x80);
+ RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAdapter->StaCfg.bAutoReconnect = TRUE;
+ LinkDown(pAdapter, FALSE);
+ }
+ if (INFRA_ON(pAdapter))
+ {
+ //BOOLEAN Cancelled;
+ // Set the AutoReconnectSsid to prevent it reconnect to old SSID
+ // Since calling this indicate user don't want to connect to that SSID anymore.
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+
+ LinkDown(pAdapter, FALSE);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("NDIS_STATUS_MEDIA_DISCONNECT Event BB!\n"));
+ }
+ }
+ pAdapter->StaCfg.BssType = BSS_ADHOC;
+ pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(AD-HOC)\n"));
+ }
+ else if (strcmp(arg, "Infra") == 0)
+ {
+ if (pAdapter->StaCfg.BssType != BSS_INFRA)
+ {
+ // Config has changed
+ pAdapter->bConfigChanged = TRUE;
+ if (MONITOR_ON(pAdapter))
+ {
+ RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, STANORMAL);
+ RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+ Value &= (~0x80);
+ RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ pAdapter->StaCfg.bAutoReconnect = TRUE;
+ LinkDown(pAdapter, FALSE);
+ }
+ if (ADHOC_ON(pAdapter))
+ {
+ // Set the AutoReconnectSsid to prevent it reconnect to old SSID
+ // Since calling this indicate user don't want to connect to that SSID anymore.
+ pAdapter->MlmeAux.AutoReconnectSsidLen= 32;
+ NdisZeroMemory(pAdapter->MlmeAux.AutoReconnectSsid, pAdapter->MlmeAux.AutoReconnectSsidLen);
+
+ LinkDown(pAdapter, FALSE);
+ }
+ }
+ pAdapter->StaCfg.BssType = BSS_INFRA;
+ pAdapter->net_dev->type = pAdapter->StaCfg.OriDevType;
+ DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(INFRA)\n"));
+
+ pAdapter->StaCfg.BssType = BSS_INFRA;
+ }
+ else if (strcmp(arg, "Monitor") == 0)
+ {
+ UCHAR bbpValue = 0;
+ BCN_TIME_CFG_STRUC csr;
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_INFRA_ON);
+ OPSTATUS_CLEAR_FLAG(pAdapter, fOP_STATUS_ADHOC_ON);
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_MEDIA_STATE_CONNECTED);
+ // disable all periodic state machine
+ pAdapter->StaCfg.bAutoReconnect = FALSE;
+ // reset all mlme state machine
+ RT28XX_MLME_RESET_STATE_MACHINE(pAdapter);
+ DBGPRINT(RT_DEBUG_TRACE, ("fOP_STATUS_MEDIA_STATE_CONNECTED \n"));
+ if (pAdapter->CommonCfg.CentralChannel == 0)
+ {
+#ifdef DOT11_N_SUPPORT
+ if (pAdapter->CommonCfg.PhyMode == PHY_11AN_MIXED)
+ pAdapter->CommonCfg.CentralChannel = 36;
+ else
+#endif // DOT11_N_SUPPORT //
+ pAdapter->CommonCfg.CentralChannel = 6;
+ }
+#ifdef DOT11_N_SUPPORT
+ else
+ N_ChannelCheck(pAdapter);
+#endif // DOT11_N_SUPPORT //
+
+#ifdef DOT11_N_SUPPORT
+ if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_ABOVE)
+ {
+ // 40MHz ,control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+ bbpValue &= (~0x18);
+ bbpValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+ pAdapter->CommonCfg.BBPCurrentBW = BW_40;
+ // RX : control channel at lower
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+ bbpValue &= (~0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
+
+ RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
+ Value &= 0xfffffffe;
+ RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
+ pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel + 2;
+ AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+ pAdapter->CommonCfg.Channel,
+ pAdapter->CommonCfg.CentralChannel));
+ }
+ else if (pAdapter->CommonCfg.PhyMode >= PHY_11ABGN_MIXED &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.BW == BW_40 &&
+ pAdapter->CommonCfg.RegTransmitSetting.field.EXTCHA == EXTCHA_BELOW)
+ {
+ // 40MHz ,control channel at upper
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+ bbpValue &= (~0x18);
+ bbpValue |= 0x10;
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+ pAdapter->CommonCfg.BBPCurrentBW = BW_40;
+ RTMP_IO_READ32(pAdapter, TX_BAND_CFG, &Value);
+ Value |= 0x1;
+ RTMP_IO_WRITE32(pAdapter, TX_BAND_CFG, Value);
+
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R3, &bbpValue);
+ bbpValue |= (0x20);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R3, bbpValue);
+ pAdapter->CommonCfg.CentralChannel = pAdapter->CommonCfg.Channel - 2;
+ AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.CentralChannel, FALSE);
+ AsicLockChannel(pAdapter, pAdapter->CommonCfg.CentralChannel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_40 ,control_channel(%d), CentralChannel(%d) \n",
+ pAdapter->CommonCfg.Channel,
+ pAdapter->CommonCfg.CentralChannel));
+ }
+ else
+#endif // DOT11_N_SUPPORT //
+ {
+ // 20MHz
+ RTMP_BBP_IO_READ8_BY_REG_ID(pAdapter, BBP_R4, &bbpValue);
+ bbpValue &= (~0x18);
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R4, bbpValue);
+ pAdapter->CommonCfg.BBPCurrentBW = BW_20;
+ AsicSwitchChannel(pAdapter, pAdapter->CommonCfg.Channel, FALSE);
+ AsicLockChannel(pAdapter, pAdapter->CommonCfg.Channel);
+ DBGPRINT(RT_DEBUG_TRACE, ("BW_20, Channel(%d)\n", pAdapter->CommonCfg.Channel));
+ }
+ // Enable Rx with promiscuous reception
+ RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3);
+ // ASIC supporsts sniffer function with replacing RSSI with timestamp.
+ //RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value);
+ //Value |= (0x80);
+ //RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value);
+ // disable sync
+ RTMP_IO_READ32(pAdapter, BCN_TIME_CFG, &csr.word);
+ csr.field.bBeaconGen = 0;
+ csr.field.bTBTTEnable = 0;
+ csr.field.TsfSyncMode = 0;
+ RTMP_IO_WRITE32(pAdapter, BCN_TIME_CFG, csr.word);
+
+ pAdapter->StaCfg.BssType = BSS_MONITOR;
+ pAdapter->net_dev->type = ARPHRD_IEEE80211_PRISM; //ARPHRD_IEEE80211; // IEEE80211
+ DBGPRINT(RT_DEBUG_TRACE, ("===>Set_NetworkType_Proc::(MONITOR)\n"));
+ }
+
+ // Reset Ralink supplicant to not use, it will be set to start when UI set PMK key
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_NetworkType_Proc::(NetworkType=%d)\n", pAdapter->StaCfg.BssType));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Authentication mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_AuthMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch;
+ else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeOpen;
+ else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeShared;
+ else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK;
+ else if ((strcmp(arg, "WPANONE") == 0) || (strcmp(arg, "wpanone") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPANone;
+ else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK;
+#ifdef WPA_SUPPLICANT_SUPPORT
+ else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA;
+ else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0))
+ pAdapter->StaCfg.AuthMode = Ndis802_11AuthModeWPA2;
+#endif // WPA_SUPPLICANT_SUPPORT //
+ else
+ return FALSE;
+
+ pAdapter->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_AuthMode_Proc::(AuthMode=%d)\n", pAdapter->StaCfg.AuthMode));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Encryption Type
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_EncrypType_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPDisabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPDisabled;
+ }
+ else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11WEPEnabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11WEPEnabled;
+ }
+ else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption2Enabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption2Enabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled;
+ }
+ else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0))
+ {
+ if (pAdapter->StaCfg.AuthMode < Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ pAdapter->StaCfg.WepStatus = Ndis802_11Encryption3Enabled;
+ pAdapter->StaCfg.PairCipher = Ndis802_11Encryption3Enabled;
+ pAdapter->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled;
+ }
+ else
+ return FALSE;
+
+ pAdapter->StaCfg.OrigWepStatus = pAdapter->StaCfg.WepStatus;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_EncrypType_Proc::(EncrypType=%d)\n", pAdapter->StaCfg.WepStatus));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Default Key ID
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_DefaultKeyID_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ ULONG KeyIdx;
+
+ KeyIdx = simple_strtol(arg, 0, 10);
+ if((KeyIdx >= 1 ) && (KeyIdx <= 4))
+ pAdapter->StaCfg.DefaultKeyId = (UCHAR) (KeyIdx - 1 );
+ else
+ return FALSE; //Invalid argument
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_DefaultKeyID_Proc::(DefaultKeyID=%d)\n", pAdapter->StaCfg.DefaultKeyId));
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY1
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key1_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][0].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][0].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][0].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::(Key1=%s and type=%s)\n", arg, "Hex"));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key1_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+
+ pAdapter->SharedKey[BSS0][0].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 0,
+ pAdapter->SharedKey[BSS0][0].CipherAlg,
+ pAdapter->SharedKey[BSS0][0].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+/*
+ ==========================================================================
+
+ Description:
+ Set WEP KEY2
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key2_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][1].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][1].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][1].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::(Key2=%s and type=%s)\n", arg, "Hex"));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key2_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+ pAdapter->SharedKey[BSS0][1].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 1,
+ pAdapter->SharedKey[BSS0][1].CipherAlg,
+ pAdapter->SharedKey[BSS0][1].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY3
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key3_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][2].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Ascii)\n", arg));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][2].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][2].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::(Key3=%s and type=Hex)\n", arg));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key3_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+ pAdapter->SharedKey[BSS0][2].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 2,
+ pAdapter->SharedKey[BSS0][2].CipherAlg,
+ pAdapter->SharedKey[BSS0][2].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+/*
+ ==========================================================================
+ Description:
+ Set WEP KEY4
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Key4_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ int KeyLen;
+ int i;
+ UCHAR CipherAlg=CIPHER_WEP64;
+
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ return TRUE; // do nothing
+
+ KeyLen = strlen(arg);
+
+ switch (KeyLen)
+ {
+ case 5: //wep 40 Ascii type
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 10: //wep 40 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP64;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
+ break;
+ case 13: //wep 104 Ascii type
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen;
+ memcpy(pAdapter->SharedKey[BSS0][3].Key, arg, KeyLen);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Ascii"));
+ break;
+ case 26: //wep 104 Hex type
+ for(i=0; i < KeyLen; i++)
+ {
+ if( !isxdigit(*(arg+i)) )
+ return FALSE; //Not Hex value;
+ }
+ pAdapter->SharedKey[BSS0][3].KeyLen = KeyLen / 2 ;
+ AtoH(arg, pAdapter->SharedKey[BSS0][3].Key, KeyLen / 2);
+ CipherAlg = CIPHER_WEP128;
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::(Key4=%s and type=%s)\n", arg, "Hex"));
+ break;
+ default: //Invalid argument
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Key4_Proc::Invalid argument (=%s)\n", arg));
+ return FALSE;
+ }
+ pAdapter->SharedKey[BSS0][3].CipherAlg = CipherAlg;
+
+ // Set keys (into ASIC)
+ if (pAdapter->StaCfg.AuthMode >= Ndis802_11AuthModeWPA)
+ ; // not support
+ else // Old WEP stuff
+ {
+ AsicAddSharedKeyEntry(pAdapter,
+ 0,
+ 3,
+ pAdapter->SharedKey[BSS0][3].CipherAlg,
+ pAdapter->SharedKey[BSS0][3].Key,
+ NULL,
+ NULL);
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set WPA PSK key
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_WPAPSK_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ UCHAR keyMaterial[40];
+
+ if ((pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPAPSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPA2PSK) &&
+ (pAdapter->StaCfg.AuthMode != Ndis802_11AuthModeWPANone)
+ )
+ return TRUE; // do nothing
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_WPAPSK_Proc::(WPAPSK=%s)\n", arg));
+
+ NdisZeroMemory(keyMaterial, 40);
+
+ if ((strlen(arg) < 8) || (strlen(arg) > 64))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("Set failed!!(WPAPSK=%s), WPAPSK key-string required 8 ~ 64 characters \n", arg));
+ return FALSE;
+ }
+
+ if (strlen(arg) == 64)
+ {
+ AtoH(arg, keyMaterial, 32);
+ NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
+
+ }
+ else
+ {
+ PasswordHash((char *)arg, pAdapter->MlmeAux.Ssid, pAdapter->MlmeAux.SsidLen, keyMaterial);
+ NdisMoveMemory(pAdapter->StaCfg.PMK, keyMaterial, 32);
+ }
+
+
+
+ if(pAdapter->StaCfg.BssType == BSS_ADHOC &&
+ pAdapter->StaCfg.AuthMode == Ndis802_11AuthModeWPANone)
+ {
+ pAdapter->StaCfg.WpaState = SS_NOTUSE;
+ }
+ else
+ {
+ // Start STA supplicant state machine
+ pAdapter->StaCfg.WpaState = SS_START;
+ }
+
+ return TRUE;
+}
+
+/*
+ ==========================================================================
+ Description:
+ Set Power Saving mode
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_PSMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if (pAdapter->StaCfg.BssType == BSS_INFRA)
+ {
+ if ((strcmp(arg, "Max_PSP") == 0) ||
+ (strcmp(arg, "max_psp") == 0) ||
+ (strcmp(arg, "MAX_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeMAX_PSP;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeMAX_PSP;
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ pAdapter->StaCfg.DefaultListenCount = 5;
+
+ }
+ else if ((strcmp(arg, "Fast_PSP") == 0) ||
+ (strcmp(arg, "fast_psp") == 0) ||
+ (strcmp(arg, "FAST_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeFast_PSP;
+ pAdapter->StaCfg.DefaultListenCount = 3;
+ }
+ else if ((strcmp(arg, "Legacy_PSP") == 0) ||
+ (strcmp(arg, "legacy_psp") == 0) ||
+ (strcmp(arg, "LEGACY_PSP") == 0))
+ {
+ // do NOT turn on PSM bit here, wait until MlmeCheckForPsmChange()
+ // to exclude certain situations.
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeLegacy_PSP;
+ pAdapter->StaCfg.DefaultListenCount = 3;
+ }
+ else
+ {
+ //Default Ndis802_11PowerModeCAM
+ // clear PSM bit immediately
+ MlmeSetPsmBit(pAdapter, PWR_ACTIVE);
+ OPSTATUS_SET_FLAG(pAdapter, fOP_STATUS_RECEIVE_DTIM);
+ if (pAdapter->StaCfg.bWindowsACCAMEnable == FALSE)
+ pAdapter->StaCfg.WindowsPowerMode = Ndis802_11PowerModeCAM;
+ pAdapter->StaCfg.WindowsBatteryPowerMode = Ndis802_11PowerModeCAM;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_PSMode_Proc::(PSMode=%ld)\n", pAdapter->StaCfg.WindowsPowerMode));
+ }
+ else
+ return FALSE;
+
+
+ return TRUE;
+}
+
+#ifdef WPA_SUPPLICANT_SUPPORT
+/*
+ ==========================================================================
+ Description:
+ Set WpaSupport flag.
+ Value:
+ 0: Driver ignore wpa_supplicant.
+ 1: wpa_supplicant initiates scanning and AP selection.
+ 2: driver takes care of scanning, AP selection, and IEEE 802.11 association parameters.
+ Return:
+ TRUE if all parameters are OK, FALSE otherwise
+ ==========================================================================
+*/
+INT Set_Wpa_Support(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+
+ if ( simple_strtol(arg, 0, 10) == 0)
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+ else if ( simple_strtol(arg, 0, 10) == 1)
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE;
+ else if ( simple_strtol(arg, 0, 10) == 2)
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_ENABLE_WITH_WEB_UI;
+ else
+ pAd->StaCfg.WpaSupplicantUP = WPA_SUPPLICANT_DISABLE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Wpa_Support::(WpaSupplicantUP=%d)\n", pAd->StaCfg.WpaSupplicantUP));
+
+ return TRUE;
+}
+#endif // WPA_SUPPLICANT_SUPPORT //
+
+#ifdef DBG
+/*
+ ==========================================================================
+ Description:
+ Read / Write MAC
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 mac 0 ==> read MAC where Addr=0x0
+ 2.) iwpriv ra0 mac 0=12 ==> write MAC where Addr=0x0, value=12
+ ==========================================================================
+*/
+VOID RTMPIoctlMAC(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *this_char;
+ CHAR *value;
+ INT j = 0, k = 0;
+ CHAR msg[1024];
+ CHAR arg[255];
+ ULONG macAddr = 0;
+ UCHAR temp[16], temp2[16];
+ UINT32 macValue = 0;
+ INT Status;
+ BOOLEAN bIsPrintAllMAC = FALSE;
+
+
+ memset(msg, 0x00, 1024);
+ if (wrq->u.data.length > 1) //No parameters.
+ {
+ Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ sprintf(msg, "\n");
+
+ //Parsing Read or Write
+ this_char = arg;
+ if (!*this_char)
+ goto next;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+ // Sanity check
+ if(strlen(this_char) > 4)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+
+ // Mac Addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ if(strlen(this_char) == 4)
+ {
+ AtoH(this_char, temp, 2);
+ macAddr = *temp*256 + temp[1];
+ if (macAddr < 0xFFFF)
+ {
+ RTMP_IO_READ32(pAdapter, macAddr, &macValue);
+ DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%lx, MacValue=%x\n", macAddr, macValue));
+ sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr , macValue);
+ }
+ else
+ {//Invalid parametes, so default printk all mac
+ bIsPrintAllMAC = TRUE;
+ goto next;
+ }
+ }
+ }
+ else
+ { //Write
+ memcpy(&temp2, value, strlen(value));
+ temp2[strlen(value)] = '\0';
+
+ // Sanity check
+ if((strlen(this_char) > 4) || strlen(temp2) > 8)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+
+ j = strlen(temp2);
+ while(j-- > 0)
+ {
+ if(temp2[j] > 'f' || temp2[j] < '0')
+ return;
+ }
+
+ //MAC Addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ //MAC value
+ k = j = strlen(temp2);
+ while(j-- > 0)
+ {
+ temp2[8-k+j] = temp2[j];
+ }
+
+ while(k < 8)
+ temp2[7-k++]='0';
+ temp2[8]='\0';
+
+ {
+ AtoH(this_char, temp, 2);
+ macAddr = *temp*256 + temp[1];
+
+ AtoH(temp2, temp, 4);
+ macValue = *temp*256*256*256 + temp[1]*256*256 + temp[2]*256 + temp[3];
+
+ // debug mode
+ if (macAddr == (HW_DEBUG_SETTING_BASE + 4))
+ {
+ // 0x2bf4: byte0 non-zero: enable R17 tuning, 0: disable R17 tuning
+ if (macValue & 0x000000ff)
+ {
+ pAdapter->BbpTuning.bEnable = TRUE;
+ DBGPRINT(RT_DEBUG_TRACE,("turn on R17 tuning\n"));
+ }
+ else
+ {
+ UCHAR R66;
+ pAdapter->BbpTuning.bEnable = FALSE;
+ R66 = 0x26 + GET_LNA_GAIN(pAdapter);
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
+ }
+ else
+#endif // RALINK_ATE //
+ RTMP_BBP_IO_WRITE8_BY_REG_ID(pAdapter, BBP_R66, (0x26 + GET_LNA_GAIN(pAdapter)));
+ DBGPRINT(RT_DEBUG_TRACE,("turn off R17 tuning, restore to 0x%02x\n", R66));
+ }
+ return;
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("MacAddr=%02lx, MacValue=0x%x\n", macAddr, macValue));
+
+ RTMP_IO_WRITE32(pAdapter, macAddr, macValue);
+ sprintf(msg+strlen(msg), "[0x%08lX]:%08X ", macAddr, macValue);
+ }
+ }
+ }
+ else
+ bIsPrintAllMAC = TRUE;
+next:
+ if (bIsPrintAllMAC)
+ {
+ struct file *file_w;
+ PCHAR fileName = "MacDump.txt";
+ mm_segment_t orig_fs;
+
+ orig_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ // open file
+ file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
+ if (IS_ERR(file_w))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
+ }
+ else
+ {
+ if (file_w->f_op && file_w->f_op->write)
+ {
+ file_w->f_pos = 0;
+ macAddr = 0x1000;
+
+ while (macAddr <= 0x1800)
+ {
+ RTMP_IO_READ32(pAdapter, macAddr, &macValue);
+ sprintf(msg, "%08lx = %08X\n", macAddr, macValue);
+
+ // write data to file
+ file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
+
+ printk("%s", msg);
+ macAddr += 4;
+ }
+ sprintf(msg, "\nDump all MAC values to %s\n", fileName);
+ }
+ filp_close(file_w, NULL);
+ }
+ set_fs(orig_fs);
+ }
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+ // Copy the information into the user buffer
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlMAC\n\n"));
+}
+
+/*
+ ==========================================================================
+ Description:
+ Read / Write E2PROM
+ Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 e2p 0 ==> read E2PROM where Addr=0x0
+ 2.) iwpriv ra0 e2p 0=1234 ==> write E2PROM where Addr=0x0, value=1234
+ ==========================================================================
+*/
+VOID RTMPIoctlE2PROM(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *this_char;
+ CHAR *value;
+ INT j = 0, k = 0;
+ CHAR msg[1024];
+ CHAR arg[255];
+ USHORT eepAddr = 0;
+ UCHAR temp[16], temp2[16];
+ USHORT eepValue;
+ int Status;
+ BOOLEAN bIsPrintAllE2P = FALSE;
+
+
+ memset(msg, 0x00, 1024);
+ if (wrq->u.data.length > 1) //No parameters.
+ {
+ Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ sprintf(msg, "\n");
+
+ //Parsing Read or Write
+ this_char = arg;
+
+
+ if (!*this_char)
+ goto next;
+
+ if ((value = rtstrchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+
+ // Sanity check
+ if(strlen(this_char) > 4)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+
+ // E2PROM addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ if(strlen(this_char) == 4)
+ {
+ AtoH(this_char, temp, 2);
+ eepAddr = *temp*256 + temp[1];
+ if (eepAddr < 0xFFFF)
+ {
+ RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
+ sprintf(msg+strlen(msg), "[0x%04X]:0x%04X ", eepAddr , eepValue);
+ }
+ else
+ {//Invalid parametes, so default printk all bbp
+ bIsPrintAllE2P = TRUE;
+ goto next;
+ }
+ }
+ }
+ else
+ { //Write
+ memcpy(&temp2, value, strlen(value));
+ temp2[strlen(value)] = '\0';
+
+ // Sanity check
+ if((strlen(this_char) > 4) || strlen(temp2) > 8)
+ goto next;
+
+ j = strlen(this_char);
+ while(j-- > 0)
+ {
+ if(this_char[j] > 'f' || this_char[j] < '0')
+ return;
+ }
+ j = strlen(temp2);
+ while(j-- > 0)
+ {
+ if(temp2[j] > 'f' || temp2[j] < '0')
+ return;
+ }
+
+ //MAC Addr
+ k = j = strlen(this_char);
+ while(j-- > 0)
+ {
+ this_char[4-k+j] = this_char[j];
+ }
+
+ while(k < 4)
+ this_char[3-k++]='0';
+ this_char[4]='\0';
+
+ //MAC value
+ k = j = strlen(temp2);
+ while(j-- > 0)
+ {
+ temp2[4-k+j] = temp2[j];
+ }
+
+ while(k < 4)
+ temp2[3-k++]='0';
+ temp2[4]='\0';
+
+ AtoH(this_char, temp, 2);
+ eepAddr = *temp*256 + temp[1];
+
+ AtoH(temp2, temp, 2);
+ eepValue = *temp*256 + temp[1];
+
+ RT28xx_EEPROM_WRITE16(pAdapter, eepAddr, eepValue);
+ sprintf(msg+strlen(msg), "[0x%02X]:%02X ", eepAddr, eepValue);
+ }
+ }
+ else
+ bIsPrintAllE2P = TRUE;
+next:
+ if (bIsPrintAllE2P)
+ {
+ struct file *file_w;
+ PCHAR fileName = "EEPROMDump.txt";
+ mm_segment_t orig_fs;
+
+ orig_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ // open file
+ file_w = filp_open(fileName, O_WRONLY|O_CREAT, 0);
+ if (IS_ERR(file_w))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("-->2) %s: Error %ld opening %s\n", __FUNCTION__, -PTR_ERR(file_w), fileName));
+ }
+ else
+ {
+ if (file_w->f_op && file_w->f_op->write)
+ {
+ file_w->f_pos = 0;
+ eepAddr = 0x00;
+
+ while (eepAddr <= 0xFE)
+ {
+ RT28xx_EEPROM_READ16(pAdapter, eepAddr, eepValue);
+ sprintf(msg, "%08x = %04x\n", eepAddr , eepValue);
+
+ // write data to file
+ file_w->f_op->write(file_w, msg, strlen(msg), &file_w->f_pos);
+
+ printk("%s", msg);
+ eepAddr += 2;
+ }
+ sprintf(msg, "\nDump all EEPROM values to %s\n", fileName);
+ }
+ filp_close(file_w, NULL);
+ }
+ set_fs(orig_fs);
+ }
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+
+ // Copy the information into the user buffer
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlE2PROM\n"));
+}
+#ifdef RT30xx
+/*
+ ==========================================================================
+ Description:
+ Read / Write RF register
+Arguments:
+ pAdapter Pointer to our adapter
+ wrq Pointer to the ioctl argument
+
+ Return Value:
+ None
+
+ Note:
+ Usage:
+ 1.) iwpriv ra0 rf ==> read all RF registers
+ 2.) iwpriv ra0 rf 1 ==> read RF where RegID=1
+ 3.) iwpriv ra0 rf 1=10 ==> write RF R1=0x10
+ ==========================================================================
+*/
+VOID RTMPIoctlRF(
+ IN PRTMP_ADAPTER pAdapter,
+ IN struct iwreq *wrq)
+{
+ CHAR *this_char;
+ CHAR *value;
+ UCHAR regRF = 0;
+ CHAR msg[2048];
+ CHAR arg[255];
+ INT rfId;
+ LONG rfValue;
+ int Status;
+ BOOLEAN bIsPrintAllRF = FALSE;
+
+
+ memset(msg, 0x00, 2048);
+ if (wrq->u.data.length > 1) //No parameters.
+ {
+ Status = copy_from_user(arg, wrq->u.data.pointer, (wrq->u.data.length > 255) ? 255 : wrq->u.data.length);
+ sprintf(msg, "\n");
+
+ //Parsing Read or Write
+ this_char = arg;
+ if (!*this_char)
+ goto next;
+
+ if ((value = strchr(this_char, '=')) != NULL)
+ *value++ = 0;
+
+ if (!value || !*value)
+ { //Read
+ if (sscanf(this_char, "%d", &(rfId)) == 1)
+ {
+ if (rfId <= 31)
+ {
+ // In RT2860 ATE mode, we do not load 8051 firmware.
+ //We must access RF directly.
+ // For RT2870 ATE mode, ATE_RF_IO_WRITE8(/READ8)_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ }
+ else
+#endif // RALINK_ATE //
+ // according to Andy, Gary, David require.
+ // the command rf shall read rf register directly for dubug.
+ // BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+
+ sprintf(msg+strlen(msg), "R%02d[0x%02x]:%02X ", rfId, rfId*2, regRF);
+ }
+ else
+ {//Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ goto next;
+ }
+ }
+ else
+ { //Write
+ if ((sscanf(this_char, "%d", &(rfId)) == 1) && (sscanf(value, "%lx", &(rfValue)) == 1))
+ {
+ if (rfId <= 31)
+ {
+ // In RT2860 ATE mode, we do not load 8051 firmware.
+ // We should access RF registers directly.
+ // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ ATE_RF_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
+ //Read it back for showing
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
+ }
+ else
+#endif // RALINK_ATE //
+ {
+ // according to Andy, Gary, David require.
+ // the command RF shall read/write RF register directly for dubug.
+ //BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ //BBP_IO_WRITE8_BY_REG_ID(pAdapter, (UCHAR)bbpId,(UCHAR) bbpValue);
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+ RT30xxWriteRFRegister(pAdapter, (UCHAR)rfId,(UCHAR) rfValue);
+ //Read it back for showing
+ //BBP_IO_READ8_BY_REG_ID(pAdapter, bbpId, &regBBP);
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+ sprintf(msg+strlen(msg), "R%02d[0x%02X]:%02X\n", rfId, rfId*2, regRF);
+ }
+ }
+ else
+ {//Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ }
+ }
+ else
+ { //Invalid parametes, so default printk all RF
+ bIsPrintAllRF = TRUE;
+ }
+ }
+ }
+ else
+ bIsPrintAllRF = TRUE;
+next:
+ if (bIsPrintAllRF)
+ {
+ memset(msg, 0x00, 2048);
+ sprintf(msg, "\n");
+ for (rfId = 0; rfId <= 31; rfId++)
+ {
+ // In RT2860 ATE mode, we do not load 8051 firmware.
+ // We should access RF registers directly.
+ // For RT2870 ATE mode, ATE_RF_IO_WRITE8/READ8_BY_REG_ID are redefined.
+#ifdef RALINK_ATE
+ if (ATE_ON(pAdapter))
+ {
+ ATE_RF_IO_READ8_BY_REG_ID(pAdapter, rfId, &regRF);
+ }
+ else
+#endif // RALINK_ATE //
+
+ // according to Andy, Gary, David require.
+ // the command RF shall read/write RF register directly for dubug.
+ RT30xxReadRFRegister(pAdapter, rfId, &regRF);
+ sprintf(msg+strlen(msg), "%03d = %02X\n", rfId, regRF);
+ }
+ // Copy the information into the user buffer
+ DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg)=%d\n", (UINT32)strlen(msg)));
+ wrq->u.data.length = strlen(msg);
+ if (copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length))
+ {
+ DBGPRINT(RT_DEBUG_TRACE, ("%s: copy_to_user() fail\n", __FUNCTION__));
+ }
+ }
+ else
+ {
+ if(strlen(msg) == 1)
+ sprintf(msg+strlen(msg), "===>Error command format!");
+
+ DBGPRINT(RT_DEBUG_TRACE, ("copy to user [msg=%s]\n", msg));
+ // Copy the information into the user buffer
+ DBGPRINT(RT_DEBUG_TRACE, ("strlen(msg) =%d\n", (UINT32)strlen(msg)));
+
+ // Copy the information into the user buffer
+ wrq->u.data.length = strlen(msg);
+ Status = copy_to_user(wrq->u.data.pointer, msg, wrq->u.data.length);
+ }
+
+ DBGPRINT(RT_DEBUG_TRACE, ("<==RTMPIoctlRF\n\n"));
+}
+#endif // RT30xx //
+#endif // DBG //
+
+
+
+
+INT Set_TGnWifiTest_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAd->StaCfg.bTGnWifiTest = FALSE;
+ else
+ pAd->StaCfg.bTGnWifiTest = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_TGnWifiTest_Proc::(bTGnWifiTest=%d)\n", pAd->StaCfg.bTGnWifiTest));
+ return TRUE;
+}
+
+INT Set_LongRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ UCHAR LongRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.LongRtyLimit = LongRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_LongRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+ return TRUE;
+}
+
+INT Set_ShortRetryLimit_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ TX_RTY_CFG_STRUC tx_rty_cfg;
+ UCHAR ShortRetryLimit = (UCHAR)simple_strtol(arg, 0, 10);
+
+ RTMP_IO_READ32(pAdapter, TX_RTY_CFG, &tx_rty_cfg.word);
+ tx_rty_cfg.field.ShortRtyLimit = ShortRetryLimit;
+ RTMP_IO_WRITE32(pAdapter, TX_RTY_CFG, tx_rty_cfg.word);
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_ShortRetryLimit_Proc::(tx_rty_cfg=0x%x)\n", tx_rty_cfg.word));
+ return TRUE;
+}
+
+#ifdef EXT_BUILD_CHANNEL_LIST
+INT Set_Ieee80211dClientMode_Proc(
+ IN PRTMP_ADAPTER pAdapter,
+ IN PUCHAR arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_None;
+ else if (simple_strtol(arg, 0, 10) == 1)
+ pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Flexible;
+ else if (simple_strtol(arg, 0, 10) == 2)
+ pAdapter->StaCfg.IEEE80211dClientMode = Rt802_11_D_Strict;
+ else
+ return FALSE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("Set_Ieee802dMode_Proc::(IEEEE0211dMode=%d)\n", pAdapter->StaCfg.IEEE80211dClientMode));
+ return TRUE;
+}
+#endif // EXT_BUILD_CHANNEL_LIST //
+
+#ifdef CARRIER_DETECTION_SUPPORT
+INT Set_CarrierDetect_Proc(
+ IN PRTMP_ADAPTER pAd,
+ IN PUCHAR arg)
+{
+ if (simple_strtol(arg, 0, 10) == 0)
+ pAd->CommonCfg.CarrierDetect.Enable = FALSE;
+ else
+ pAd->CommonCfg.CarrierDetect.Enable = TRUE;
+
+ DBGPRINT(RT_DEBUG_TRACE, ("IF Set_CarrierDetect_Proc::(CarrierDetect.Enable=%d)\n", pAd->CommonCfg.CarrierDetect.Enable));
+ return TRUE;
+}
+#endif // CARRIER_DETECTION_SUPPORT //
+
diff --git a/drivers/staging/rt3070/wpa.h b/drivers/staging/rt3070/wpa.h
new file mode 100644
index 00000000000..88c7c8bf3fc
--- /dev/null
+++ b/drivers/staging/rt3070/wpa.h
@@ -0,0 +1,356 @@
+/*
+ *************************************************************************
+ * Ralink Tech Inc.
+ * 5F., No.36, Taiyuan St., Jhubei City,
+ * Hsinchu County 302,
+ * Taiwan, R.O.C.
+ *
+ * (c) Copyright 2002-2007, Ralink Technology, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * *
+ *************************************************************************
+
+ Module Name:
+ wpa.h
+
+ Abstract:
+
+ Revision History:
+ Who When What
+ -------- ---------- ----------------------------------------------
+ Name Date Modification logs
+*/
+
+#ifndef __WPA_H__
+#define __WPA_H__
+
+// EAPOL Key descripter frame format related length
+#define LEN_KEY_DESC_NONCE 32
+#define LEN_KEY_DESC_IV 16
+#define LEN_KEY_DESC_RSC 8
+#define LEN_KEY_DESC_ID 8
+#define LEN_KEY_DESC_REPLAY 8
+#define LEN_KEY_DESC_MIC 16
+
+// The length is the EAPoL-Key frame except key data field.
+// Please refer to 802.11i-2004 ,Figure 43u in p.78
+#define LEN_EAPOL_KEY_MSG (sizeof(KEY_DESCRIPTER) - MAX_LEN_OF_RSNIE)
+
+// EAP Code Type.
+#define EAP_CODE_REQUEST 1
+#define EAP_CODE_RESPONSE 2
+#define EAP_CODE_SUCCESS 3
+#define EAP_CODE_FAILURE 4
+
+// EAPOL frame Protocol Version
+#define EAPOL_VER 1
+#define EAPOL_VER2 2
+
+// EAPOL-KEY Descriptor Type
+#define WPA1_KEY_DESC 0xfe
+#define WPA2_KEY_DESC 0x02
+
+// Key Descriptor Version of Key Information
+#define DESC_TYPE_TKIP 1
+#define DESC_TYPE_AES 2
+#define DESC_TYPE_MESH 3
+
+#define LEN_MSG1_2WAY 0x7f
+#define MAX_LEN_OF_EAP_HS 256
+
+#define LEN_MASTER_KEY 32
+
+// EAPOL EK, MK
+#define LEN_EAP_EK 16
+#define LEN_EAP_MICK 16
+#define LEN_EAP_KEY ((LEN_EAP_EK)+(LEN_EAP_MICK))
+// TKIP key related
+#define LEN_PMKID 16
+#define LEN_TKIP_EK 16
+#define LEN_TKIP_RXMICK 8
+#define LEN_TKIP_TXMICK 8
+#define LEN_AES_EK 16
+#define LEN_AES_KEY LEN_AES_EK
+#define LEN_TKIP_KEY ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
+#define TKIP_AP_TXMICK_OFFSET ((LEN_EAP_KEY)+(LEN_TKIP_EK))
+#define TKIP_AP_RXMICK_OFFSET (TKIP_AP_TXMICK_OFFSET+LEN_TKIP_TXMICK)
+#define TKIP_GTK_LENGTH ((LEN_TKIP_EK)+(LEN_TKIP_RXMICK)+(LEN_TKIP_TXMICK))
+#define LEN_PTK ((LEN_EAP_KEY)+(LEN_TKIP_KEY))
+
+// RSN IE Length definition
+#define MAX_LEN_OF_RSNIE 90
+#define MIN_LEN_OF_RSNIE 8
+
+//EAP Packet Type
+#define EAPPacket 0
+#define EAPOLStart 1
+#define EAPOLLogoff 2
+#define EAPOLKey 3
+#define EAPOLASFAlert 4
+#define EAPTtypeMax 5
+
+#define EAPOL_MSG_INVALID 0
+#define EAPOL_PAIR_MSG_1 1
+#define EAPOL_PAIR_MSG_2 2
+#define EAPOL_PAIR_MSG_3 3
+#define EAPOL_PAIR_MSG_4 4
+#define EAPOL_GROUP_MSG_1 5
+#define EAPOL_GROUP_MSG_2 6
+
+#define PAIRWISEKEY 1
+#define GROUPKEY 0
+
+// Retry timer counter initial value
+#define PEER_MSG1_RETRY_TIMER_CTR 0
+#define PEER_MSG3_RETRY_TIMER_CTR 10
+#define GROUP_MSG1_RETRY_TIMER_CTR 20
+
+
+#define EAPOL_START_DISABLE 0
+#define EAPOL_START_PSK 1
+#define EAPOL_START_1X 2
+
+#define MIX_CIPHER_WPA_TKIP_ON(x) (((x) & 0x08) != 0)
+#define MIX_CIPHER_WPA_AES_ON(x) (((x) & 0x04) != 0)
+#define MIX_CIPHER_WPA2_TKIP_ON(x) (((x) & 0x02) != 0)
+#define MIX_CIPHER_WPA2_AES_ON(x) (((x) & 0x01) != 0)
+
+#define ROUND_UP(__x, __y) \
+ (((ULONG)((__x)+((__y)-1))) & ((ULONG)~((__y)-1)))
+
+#define ADD_ONE_To_64BIT_VAR(_V) \
+{ \
+ UCHAR cnt = LEN_KEY_DESC_REPLAY; \
+ do \
+ { \
+ cnt--; \
+ _V[cnt]++; \
+ if (cnt == 0) \
+ break; \
+ }while (_V[cnt] == 0); \
+}
+
+#define IS_WPA_CAPABILITY(a) (((a) >= Ndis802_11AuthModeWPA) && ((a) <= Ndis802_11AuthModeWPA1PSKWPA2PSK))
+
+// EAPOL Key Information definition within Key descriptor format
+typedef struct PACKED _KEY_INFO
+{
+#ifdef RT_BIG_ENDIAN
+ UCHAR KeyAck:1;
+ UCHAR Install:1;
+ UCHAR KeyIndex:2;
+ UCHAR KeyType:1;
+ UCHAR KeyDescVer:3;
+ UCHAR Rsvd:3;
+ UCHAR EKD_DL:1; // EKD for AP; DL for STA
+ UCHAR Request:1;
+ UCHAR Error:1;
+ UCHAR Secure:1;
+ UCHAR KeyMic:1;
+#else
+ UCHAR KeyMic:1;
+ UCHAR Secure:1;
+ UCHAR Error:1;
+ UCHAR Request:1;
+ UCHAR EKD_DL:1; // EKD for AP; DL for STA
+ UCHAR Rsvd:3;
+ UCHAR KeyDescVer:3;
+ UCHAR KeyType:1;
+ UCHAR KeyIndex:2;
+ UCHAR Install:1;
+ UCHAR KeyAck:1;
+#endif
+} KEY_INFO, *PKEY_INFO;
+
+// EAPOL Key descriptor format
+typedef struct PACKED _KEY_DESCRIPTER
+{
+ UCHAR Type;
+ KEY_INFO KeyInfo;
+ UCHAR KeyLength[2];
+ UCHAR ReplayCounter[LEN_KEY_DESC_REPLAY];
+ UCHAR KeyNonce[LEN_KEY_DESC_NONCE];
+ UCHAR KeyIv[LEN_KEY_DESC_IV];
+ UCHAR KeyRsc[LEN_KEY_DESC_RSC];
+ UCHAR KeyId[LEN_KEY_DESC_ID];
+ UCHAR KeyMic[LEN_KEY_DESC_MIC];
+ UCHAR KeyDataLen[2];
+ UCHAR KeyData[MAX_LEN_OF_RSNIE];
+} KEY_DESCRIPTER, *PKEY_DESCRIPTER;
+
+typedef struct PACKED _EAPOL_PACKET
+{
+ UCHAR ProVer;
+ UCHAR ProType;
+ UCHAR Body_Len[2];
+ KEY_DESCRIPTER KeyDesc;
+} EAPOL_PACKET, *PEAPOL_PACKET;
+
+//802.11i D10 page 83
+typedef struct PACKED _GTK_ENCAP
+{
+#ifndef RT_BIG_ENDIAN
+ UCHAR Kid:2;
+ UCHAR tx:1;
+ UCHAR rsv:5;
+ UCHAR rsv1;
+#else
+ UCHAR rsv:5;
+ UCHAR tx:1;
+ UCHAR Kid:2;
+ UCHAR rsv1;
+#endif
+ UCHAR GTK[TKIP_GTK_LENGTH];
+} GTK_ENCAP, *PGTK_ENCAP;
+
+typedef struct PACKED _KDE_ENCAP
+{
+ UCHAR Type;
+ UCHAR Len;
+ UCHAR OUI[3];
+ UCHAR DataType;
+ GTK_ENCAP GTKEncap;
+} KDE_ENCAP, *PKDE_ENCAP;
+
+// For WPA1
+typedef struct PACKED _RSNIE {
+ UCHAR oui[4];
+ USHORT version;
+ UCHAR mcast[4];
+ USHORT ucount;
+ struct PACKED {
+ UCHAR oui[4];
+ }ucast[1];
+} RSNIE, *PRSNIE;
+
+// For WPA2
+typedef struct PACKED _RSNIE2 {
+ USHORT version;
+ UCHAR mcast[4];
+ USHORT ucount;
+ struct PACKED {
+ UCHAR oui[4];
+ }ucast[1];
+} RSNIE2, *PRSNIE2;
+
+// AKM Suite
+typedef struct PACKED _RSNIE_AUTH {
+ USHORT acount;
+ struct PACKED {
+ UCHAR oui[4];
+ }auth[1];
+} RSNIE_AUTH,*PRSNIE_AUTH;
+
+typedef union PACKED _RSN_CAPABILITIES {
+ struct PACKED {
+#ifdef RT_BIG_ENDIAN
+ USHORT Rsvd:10;
+ USHORT GTKSA_R_Counter:2;
+ USHORT PTKSA_R_Counter:2;
+ USHORT No_Pairwise:1;
+ USHORT PreAuth:1;
+#else
+ USHORT PreAuth:1;
+ USHORT No_Pairwise:1;
+ USHORT PTKSA_R_Counter:2;
+ USHORT GTKSA_R_Counter:2;
+ USHORT Rsvd:10;
+#endif
+ } field;
+ USHORT word;
+} RSN_CAPABILITIES, *PRSN_CAPABILITIES;
+
+typedef struct PACKED _EAP_HDR {
+ UCHAR ProVer;
+ UCHAR ProType;
+ UCHAR Body_Len[2];
+ UCHAR code;
+ UCHAR identifier;
+ UCHAR length[2]; // including code and identifier, followed by length-2 octets of data
+} EAP_HDR, *PEAP_HDR;
+
+// For supplicant state machine states. 802.11i Draft 4.1, p. 97
+// We simplified it
+typedef enum _WpaState
+{
+ SS_NOTUSE, // 0
+ SS_START, // 1
+ SS_WAIT_MSG_3, // 2
+ SS_WAIT_GROUP, // 3
+ SS_FINISH, // 4
+ SS_KEYUPDATE, // 5
+} WPA_STATE;
+
+//
+// The definition of the cipher combination
+//
+// bit3 bit2 bit1 bit0
+// +------------+------------+
+// | WPA | WPA2 |
+// +------+-----+------+-----+
+// | TKIP | AES | TKIP | AES |
+// | 0 | 1 | 1 | 0 | -> 0x06
+// | 0 | 1 | 1 | 1 | -> 0x07
+// | 1 | 0 | 0 | 1 | -> 0x09
+// | 1 | 0 | 1 | 1 | -> 0x0B
+// | 1 | 1 | 0 | 1 | -> 0x0D
+// | 1 | 1 | 1 | 0 | -> 0x0E
+// | 1 | 1 | 1 | 1 | -> 0x0F
+// +------+-----+------+-----+
+//
+typedef enum _WpaMixPairCipher
+{
+ MIX_CIPHER_NOTUSE = 0x00,
+ WPA_NONE_WPA2_TKIPAES = 0x03, // WPA2-TKIPAES
+ WPA_AES_WPA2_TKIP = 0x06,
+ WPA_AES_WPA2_TKIPAES = 0x07,
+ WPA_TKIP_WPA2_AES = 0x09,
+ WPA_TKIP_WPA2_TKIPAES = 0x0B,
+ WPA_TKIPAES_WPA2_NONE = 0x0C, // WPA-TKIPAES
+ WPA_TKIPAES_WPA2_AES = 0x0D,
+ WPA_TKIPAES_WPA2_TKIP = 0x0E,
+ WPA_TKIPAES_WPA2_TKIPAES = 0x0F,
+} WPA_MIX_PAIR_CIPHER;
+
+typedef struct PACKED _RSN_IE_HEADER_STRUCT {
+ UCHAR Eid;
+ UCHAR Length;
+ USHORT Version; // Little endian format
+} RSN_IE_HEADER_STRUCT, *PRSN_IE_HEADER_STRUCT;
+
+// Cipher suite selector types
+typedef struct PACKED _CIPHER_SUITE_STRUCT {
+ UCHAR Oui[3];
+ UCHAR Type;
+} CIPHER_SUITE_STRUCT, *PCIPHER_SUITE_STRUCT;
+
+// Authentication and Key Management suite selector
+typedef struct PACKED _AKM_SUITE_STRUCT {
+ UCHAR Oui[3];
+ UCHAR Type;
+} AKM_SUITE_STRUCT, *PAKM_SUITE_STRUCT;
+
+// RSN capability
+typedef struct PACKED _RSN_CAPABILITY {
+ USHORT Rsv:10;
+ USHORT GTKSAReplayCnt:2;
+ USHORT PTKSAReplayCnt:2;
+ USHORT NoPairwise:1;
+ USHORT PreAuth:1;
+} RSN_CAPABILITY, *PRSN_CAPABILITY;
+
+#endif
diff --git a/drivers/staging/rtl8187se/dot11d.h b/drivers/staging/rtl8187se/dot11d.h
index 49f53fe52af..2417da99529 100644
--- a/drivers/staging/rtl8187se/dot11d.h
+++ b/drivers/staging/rtl8187se/dot11d.h
@@ -1,101 +1,101 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-//#define ENABLE_DOT11D
-
-//#define DOT11D_MAX_CHNL_NUM 83
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
- u8 FirstChnl;
- u8 NumChnls;
- u8 MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
- DOT11D_STATE_NONE = 0,
- DOT11D_STATE_LEARNED,
- DOT11D_STATE_DONE,
-}DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
- //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
-
- bool bEnabled; // dot11MultiDomainCapabilityEnabled
-
- u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- //u8 ChnlListLen; // #Bytes valid in ChnlList[].
- //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
- DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-
-void
-Dot11d_Init(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_Reset(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- );
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- );
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-#endif // #ifndef __INC_DOT11D_H
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#include "ieee80211.h"
+
+//#define ENABLE_DOT11D
+
+//#define DOT11D_MAX_CHNL_NUM 83
+
+typedef struct _CHNL_TXPOWER_TRIPLE {
+ u8 FirstChnl;
+ u8 NumChnls;
+ u8 MaxTxPowerInDbm;
+}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+
+typedef enum _DOT11D_STATE {
+ DOT11D_STATE_NONE = 0,
+ DOT11D_STATE_LEARNED,
+ DOT11D_STATE_DONE,
+}DOT11D_STATE;
+
+typedef struct _RT_DOT11D_INFO {
+ //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+
+ bool bEnabled; // dot11MultiDomainCapabilityEnabled
+
+ u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+ u8 CountryIeBuf[MAX_IE_LEN];
+ u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
+ u8 CountryIeWatchdog;
+
+ u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
+ //u8 ChnlListLen; // #Bytes valid in ChnlList[].
+ //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
+ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+
+ DOT11D_STATE State;
+}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
+#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+
+#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
+ (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
+ FALSE : \
+ (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+
+#define CIE_WATCHDOG_TH 1
+#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+
+
+void
+Dot11d_Init(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_Reset(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_UpdateCountryIe(
+ struct ieee80211_device *dev,
+ u8 * pTaddr,
+ u16 CoutryIeLen,
+ u8 * pCoutryIe
+ );
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+ struct ieee80211_device *dev,
+ u8 Channel
+ );
+
+void
+DOT11D_ScanComplete(
+ struct ieee80211_device * dev
+ );
+
+int IsLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+int ToLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c
index 5d8b752fc0f..54bcdcf1d33 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.c
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c
@@ -1,246 +1,246 @@
-#ifdef ENABLE_DOT11D
-//-----------------------------------------------------------------------------
-// File:
-// Dot11d.c
-//
-// Description:
-// Implement 802.11d.
-//
-//-----------------------------------------------------------------------------
-
-#include "dot11d.h"
-
-void
-Dot11d_Init(struct ieee80211_device *ieee)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- pDot11dInfo->bEnabled = 0;
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- RESET_CIE_WATCHDOG(ieee);
-
- printk("Dot11d_Init()\n");
-}
-
-//
-// Description:
-// Reset to the state as we are just entering a regulatory domain.
-//
-void
-Dot11d_Reset(struct ieee80211_device *ieee)
-{
- u32 i;
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- // Clear old channel map
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- // Set new channel map
- for (i=1; i<=11; i++) {
- (pDot11dInfo->channel_map)[i] = 1;
- }
- for (i=12; i<=14; i++) {
- (pDot11dInfo->channel_map)[i] = 2;
- }
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- RESET_CIE_WATCHDOG(ieee);
-
- //printk("Dot11d_Reset()\n");
-}
-
-//
-// Description:
-// Update country IE from Beacon or Probe Resopnse
-// and configure PHY for operation in the regulatory domain.
-//
-// TODO:
-// Configure Tx power.
-//
-// Assumption:
-// 1. IS_DOT11D_ENABLE() is TRUE.
-// 2. Input IE is an valid one.
-//
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 i, j, NumTriples, MaxChnlNum;
- PCHNL_TXPOWER_TRIPLE pTriple;
-
- if((CoutryIeLen - 3)%3 != 0)
- {
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
-
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- MaxChnlNum = 0;
- NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
- pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
- for(i = 0; i < NumTriples; i++)
- {
- if(MaxChnlNum >= pTriple->FirstChnl)
- { // It is not in a monotonically increasing order, so stop processing.
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
- if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
- { // It is not a valid set of channel id, so stop processing.
- printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
- Dot11d_Reset(dev);
- return;
- }
-
- for(j = 0 ; j < pTriple->NumChnls; j++)
- {
- pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
- pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
- MaxChnlNum = pTriple->FirstChnl + j;
- }
-
- pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
- }
-#if 1
- //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
- printk("Channel List:");
- for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
- if(pDot11dInfo->channel_map[i] > 0)
- printk(" %d", i);
- printk("\n");
-#endif
-
- UPDATE_CIE_SRC(dev, pTaddr);
-
- pDot11dInfo->CountryIeLen = CoutryIeLen;
- memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
- pDot11dInfo->State = DOT11D_STATE_LEARNED;
-}
-
-void dump_chnl_map(u8 * channel_map)
-{
- int i;
- printk("Channel List:");
- for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
- if(channel_map[i] > 0)
- printk(" %d(%d)", i, channel_map[i]);
- printk("\n");
-}
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 MaxTxPwrInDbm = 255;
-
- if(MAX_CHANNEL_NUMBER < Channel)
- {
- printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
- return MaxTxPwrInDbm;
- }
- if(pDot11dInfo->channel_map[Channel])
- {
- MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
- }
-
- return MaxTxPwrInDbm;
-}
-
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- )
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- switch(pDot11dInfo->State)
- {
- case DOT11D_STATE_LEARNED:
- pDot11dInfo->State = DOT11D_STATE_DONE;
- break;
-
- case DOT11D_STATE_DONE:
- if( GET_CIE_WATCHDOG(dev) == 0 )
- { // Reset country IE if previous one is gone.
- Dot11d_Reset(dev);
- }
- break;
- case DOT11D_STATE_NONE:
- break;
- }
-}
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- if(MAX_CHANNEL_NUMBER < channel)
- {
- printk("IsLegalChannel(): Invalid Channel\n");
- return 0;
- }
- if(pDot11dInfo->channel_map[channel] > 0)
- return 1;
- return 0;
-}
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 default_chn = 0;
- u32 i = 0;
-
- for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
- {
- if(pDot11dInfo->channel_map[i] > 0)
- {
- default_chn = i;
- break;
- }
- }
-
- if(MAX_CHANNEL_NUMBER < channel)
- {
- printk("IsLegalChannel(): Invalid Channel\n");
- return default_chn;
- }
-
- if(pDot11dInfo->channel_map[channel] > 0)
- return channel;
-
- return default_chn;
-}
-
-#if 0
-EXPORT_SYMBOL(Dot11d_Init);
-EXPORT_SYMBOL(Dot11d_Reset);
-EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
-EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
-EXPORT_SYMBOL(DOT11D_ScanComplete);
-EXPORT_SYMBOL(IsLegalChannel);
-EXPORT_SYMBOL(ToLegalChannel);
-#endif
-#endif
+#ifdef ENABLE_DOT11D
+//-----------------------------------------------------------------------------
+// File:
+// Dot11d.c
+//
+// Description:
+// Implement 802.11d.
+//
+//-----------------------------------------------------------------------------
+
+#include "dot11d.h"
+
+void
+Dot11d_Init(struct ieee80211_device *ieee)
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
+
+ pDot11dInfo->bEnabled = 0;
+
+ pDot11dInfo->State = DOT11D_STATE_NONE;
+ pDot11dInfo->CountryIeLen = 0;
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ RESET_CIE_WATCHDOG(ieee);
+
+ printk("Dot11d_Init()\n");
+}
+
+//
+// Description:
+// Reset to the state as we are just entering a regulatory domain.
+//
+void
+Dot11d_Reset(struct ieee80211_device *ieee)
+{
+ u32 i;
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
+
+ // Clear old channel map
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ // Set new channel map
+ for (i=1; i<=11; i++) {
+ (pDot11dInfo->channel_map)[i] = 1;
+ }
+ for (i=12; i<=14; i++) {
+ (pDot11dInfo->channel_map)[i] = 2;
+ }
+
+ pDot11dInfo->State = DOT11D_STATE_NONE;
+ pDot11dInfo->CountryIeLen = 0;
+ RESET_CIE_WATCHDOG(ieee);
+
+ //printk("Dot11d_Reset()\n");
+}
+
+//
+// Description:
+// Update country IE from Beacon or Probe Resopnse
+// and configure PHY for operation in the regulatory domain.
+//
+// TODO:
+// Configure Tx power.
+//
+// Assumption:
+// 1. IS_DOT11D_ENABLE() is TRUE.
+// 2. Input IE is an valid one.
+//
+void
+Dot11d_UpdateCountryIe(
+ struct ieee80211_device *dev,
+ u8 * pTaddr,
+ u16 CoutryIeLen,
+ u8 * pCoutryIe
+ )
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+ u8 i, j, NumTriples, MaxChnlNum;
+ PCHNL_TXPOWER_TRIPLE pTriple;
+
+ if((CoutryIeLen - 3)%3 != 0)
+ {
+ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+ Dot11d_Reset(dev);
+ return;
+ }
+
+ memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
+ memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
+ MaxChnlNum = 0;
+ NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
+ pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
+ for(i = 0; i < NumTriples; i++)
+ {
+ if(MaxChnlNum >= pTriple->FirstChnl)
+ { // It is not in a monotonically increasing order, so stop processing.
+ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
+ Dot11d_Reset(dev);
+ return;
+ }
+ if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
+ { // It is not a valid set of channel id, so stop processing.
+ printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
+ Dot11d_Reset(dev);
+ return;
+ }
+
+ for(j = 0 ; j < pTriple->NumChnls; j++)
+ {
+ pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
+ pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
+ MaxChnlNum = pTriple->FirstChnl + j;
+ }
+
+ pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
+ }
+#if 1
+ //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
+ printk("Channel List:");
+ for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
+ if(pDot11dInfo->channel_map[i] > 0)
+ printk(" %d", i);
+ printk("\n");
+#endif
+
+ UPDATE_CIE_SRC(dev, pTaddr);
+
+ pDot11dInfo->CountryIeLen = CoutryIeLen;
+ memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
+ pDot11dInfo->State = DOT11D_STATE_LEARNED;
+}
+
+void dump_chnl_map(u8 * channel_map)
+{
+ int i;
+ printk("Channel List:");
+ for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
+ if(channel_map[i] > 0)
+ printk(" %d(%d)", i, channel_map[i]);
+ printk("\n");
+}
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+ struct ieee80211_device *dev,
+ u8 Channel
+ )
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+ u8 MaxTxPwrInDbm = 255;
+
+ if(MAX_CHANNEL_NUMBER < Channel)
+ {
+ printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
+ return MaxTxPwrInDbm;
+ }
+ if(pDot11dInfo->channel_map[Channel])
+ {
+ MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
+ }
+
+ return MaxTxPwrInDbm;
+}
+
+
+void
+DOT11D_ScanComplete(
+ struct ieee80211_device * dev
+ )
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+
+ switch(pDot11dInfo->State)
+ {
+ case DOT11D_STATE_LEARNED:
+ pDot11dInfo->State = DOT11D_STATE_DONE;
+ break;
+
+ case DOT11D_STATE_DONE:
+ if( GET_CIE_WATCHDOG(dev) == 0 )
+ { // Reset country IE if previous one is gone.
+ Dot11d_Reset(dev);
+ }
+ break;
+ case DOT11D_STATE_NONE:
+ break;
+ }
+}
+
+int IsLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+)
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+
+ if(MAX_CHANNEL_NUMBER < channel)
+ {
+ printk("IsLegalChannel(): Invalid Channel\n");
+ return 0;
+ }
+ if(pDot11dInfo->channel_map[channel] > 0)
+ return 1;
+ return 0;
+}
+
+int ToLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+)
+{
+ PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
+ u8 default_chn = 0;
+ u32 i = 0;
+
+ for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
+ {
+ if(pDot11dInfo->channel_map[i] > 0)
+ {
+ default_chn = i;
+ break;
+ }
+ }
+
+ if(MAX_CHANNEL_NUMBER < channel)
+ {
+ printk("IsLegalChannel(): Invalid Channel\n");
+ return default_chn;
+ }
+
+ if(pDot11dInfo->channel_map[channel] > 0)
+ return channel;
+
+ return default_chn;
+}
+
+#if 0
+EXPORT_SYMBOL(Dot11d_Init);
+EXPORT_SYMBOL(Dot11d_Reset);
+EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
+EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
+EXPORT_SYMBOL(DOT11D_ScanComplete);
+EXPORT_SYMBOL(IsLegalChannel);
+EXPORT_SYMBOL(ToLegalChannel);
+#endif
+#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h
index 64bcf15bd21..82576b519cc 100644
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.h
+++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h
@@ -1,102 +1,102 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-//#define ENABLE_DOT11D
-
-//#define DOT11D_MAX_CHNL_NUM 83
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
- u8 FirstChnl;
- u8 NumChnls;
- u8 MaxTxPowerInDbm;
-}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
- DOT11D_STATE_NONE = 0,
- DOT11D_STATE_LEARNED,
- DOT11D_STATE_DONE,
-}DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
- //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
-
- bool bEnabled; // dot11MultiDomainCapabilityEnabled
-
- u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
- //u8 ChnlListLen; // #Bytes valid in ChnlList[].
- //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
- DOT11D_STATE State;
-}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
-#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-
-void
-Dot11d_Init(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_Reset(
- struct ieee80211_device *dev
- );
-
-void
-Dot11d_UpdateCountryIe(
- struct ieee80211_device *dev,
- u8 * pTaddr,
- u16 CoutryIeLen,
- u8 * pCoutryIe
- );
-
-u8
-DOT11D_GetMaxTxPwrInDbm(
- struct ieee80211_device *dev,
- u8 Channel
- );
-
-void
-DOT11D_ScanComplete(
- struct ieee80211_device * dev
- );
-
-int IsLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-int ToLegalChannel(
- struct ieee80211_device * dev,
- u8 channel
-);
-
-void dump_chnl_map(u8 * channel_map);
-#endif // #ifndef __INC_DOT11D_H
+#ifndef __INC_DOT11D_H
+#define __INC_DOT11D_H
+
+#include "ieee80211.h"
+
+//#define ENABLE_DOT11D
+
+//#define DOT11D_MAX_CHNL_NUM 83
+
+typedef struct _CHNL_TXPOWER_TRIPLE {
+ u8 FirstChnl;
+ u8 NumChnls;
+ u8 MaxTxPowerInDbm;
+}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
+
+typedef enum _DOT11D_STATE {
+ DOT11D_STATE_NONE = 0,
+ DOT11D_STATE_LEARNED,
+ DOT11D_STATE_DONE,
+}DOT11D_STATE;
+
+typedef struct _RT_DOT11D_INFO {
+ //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
+
+ bool bEnabled; // dot11MultiDomainCapabilityEnabled
+
+ u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
+ u8 CountryIeBuf[MAX_IE_LEN];
+ u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
+ u8 CountryIeWatchdog;
+
+ u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
+ //u8 ChnlListLen; // #Bytes valid in ChnlList[].
+ //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
+ u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
+
+ DOT11D_STATE State;
+}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
+#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
+#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
+#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
+
+#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
+#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
+
+#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
+
+#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
+ (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
+ FALSE : \
+ (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
+
+#define CIE_WATCHDOG_TH 1
+#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
+#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
+#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
+
+#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
+
+
+void
+Dot11d_Init(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_Reset(
+ struct ieee80211_device *dev
+ );
+
+void
+Dot11d_UpdateCountryIe(
+ struct ieee80211_device *dev,
+ u8 * pTaddr,
+ u16 CoutryIeLen,
+ u8 * pCoutryIe
+ );
+
+u8
+DOT11D_GetMaxTxPwrInDbm(
+ struct ieee80211_device *dev,
+ u8 Channel
+ );
+
+void
+DOT11D_ScanComplete(
+ struct ieee80211_device * dev
+ );
+
+int IsLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+int ToLegalChannel(
+ struct ieee80211_device * dev,
+ u8 channel
+);
+
+void dump_chnl_map(u8 * channel_map);
+#endif // #ifndef __INC_DOT11D_H
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index e5752f615e0..80f9cc7137c 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -719,7 +719,7 @@ void ieee80211_softmac_scan(struct ieee80211_device *ieee)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
void ieee80211_softmac_scan_wq(struct work_struct *work)
{
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
#else
void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
@@ -777,7 +777,7 @@ out:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
void ieee80211_softmac_scan_wq(struct work_struct *work)
{
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, softmac_scan_wq);
#else
void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
@@ -2980,7 +2980,7 @@ void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
void ieee80211_start_ibss_wq(struct work_struct *work)
{
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
#else
void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
@@ -3162,7 +3162,7 @@ void ieee80211_disassociate(struct ieee80211_device *ieee)
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
void ieee80211_associate_retry_wq(struct work_struct *work)
{
- struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
#else
void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
index 6aad61e7804..d1295e56fd4 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
@@ -842,14 +842,14 @@ int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
{
- printk("return error out, len:%d\n", len);
+ printk("return error out, len:%zu\n", len);
return -EINVAL;
}
if (len)
{
if (len != ie[1]+2){
- printk("len:%d, ie:%d\n", len, ie[1]);
+ printk("len:%zu, ie:%d\n", len, ie[1]);
return -EINVAL;
}
buf = kmalloc(len, GFP_KERNEL);
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 66de5cc8ddf..6ecd12de429 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -3161,7 +3161,7 @@ void rtl8180_prepare_beacon(struct net_device *dev)
return ;
}
- //while(! *tail & (1<<31)){
+ //while(! (*tail & (1<<31))){
*tail= 0; // zeroes header
*tail = *tail| (1<<29) ; //fist segment of the packet
@@ -5438,7 +5438,7 @@ void rtl8180_hw_wakeup_wq (struct work_struct *work)
// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
// struct ieee80211_device * ieee = (struct ieee80211_device*)
// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
struct net_device *dev = ieee->dev;
#else
@@ -5459,7 +5459,7 @@ void rtl8180_hw_sleep_wq (struct work_struct *work)
// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
// struct ieee80211_device * ieee = (struct ieee80211_device*)
// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
struct net_device *dev = ieee->dev;
#else
@@ -6407,7 +6407,7 @@ priv->txnpring)/8);
void rtl8180_tx_irq_wq(struct work_struct *work)
{
//struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device * ieee = (struct ieee80211_device*)
container_of(dwork, struct ieee80211_device, watch_dog_wq);
struct net_device *dev = ieee->dev;
@@ -6691,7 +6691,7 @@ lizhaoming--------------------------- RF power on/power off -----------------
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
{
- //struct delayed_work *dwork = container_of(work, struct delayed_work, work);
+ //struct delayed_work *dwork = to_delayed_work(work);
struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, GPIOChangeRFWorkItem.work);
struct net_device *dev = ieee->dev;
struct r8180_priv *priv = ieee80211_priv(dev);
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
index 742dc11fcac..93b5a7bb255 100644
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ b/drivers/staging/rtl8187se/r8180_dm.c
@@ -1,1725 +1,1725 @@
-//#include "r8180.h"
-#include "r8180_dm.h"
-#include "r8180_hw.h"
-#include "r8180_93cx6.h"
-//{by amy 080312
-
-//
-// Description:
-// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
-//
-//+by amy 080312
-#define RATE_ADAPTIVE_TIMER_PERIOD 300
-
-bool CheckHighPower(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if(!priv->bRegHighPowerMechanism)
- {
- return false;
- }
-
- if(ieee->state == IEEE80211_LINKED_SCANNING)
- {
- return false;
- }
-
- return true;
-}
-
-//
-// Description:
-// Update Tx power level if necessary.
-// See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
-//
-// Note:
-// The reason why we udpate Tx power level here instead of DoRxHighPower()
-// is the number of IO to change Tx power is much more than chane TR switch
-// and they are related to OFDM and MAC registers.
-// So, we don't want to update it so frequently in per-Rx packet base.
-//
-void
-DoTxHighPower(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 HiPwrUpperTh = 0;
- u16 HiPwrLowerTh = 0;
- u8 RSSIHiPwrUpperTh;
- u8 RSSIHiPwrLowerTh;
- u8 u1bTmp;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- //printk("----> DoTxHighPower()\n");
-
- HiPwrUpperTh = priv->RegHiPwrUpperTh;
- HiPwrLowerTh = priv->RegHiPwrLowerTh;
-
- HiPwrUpperTh = HiPwrUpperTh * 10;
- HiPwrLowerTh = HiPwrLowerTh * 10;
- RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
- RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
-
- //lzm add 080826
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
-
- if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
- (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
- {
- // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
-
- // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
- priv->bToUpdateTxPwr = true;
- u1bTmp= read_nic_byte(dev, CCK_TXAGC);
-
- // If it never enter High Power.
- if( CckTxPwrIdx == u1bTmp)
- {
- u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
- write_nic_byte(dev, CCK_TXAGC, u1bTmp);
-
- u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
- u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
- write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
- }
-
- }
- else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
- (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
- {
- // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
- if(priv->bToUpdateTxPwr)
- {
- priv->bToUpdateTxPwr = false;
- //SD3 required.
- u1bTmp= read_nic_byte(dev, CCK_TXAGC);
- if(u1bTmp < CckTxPwrIdx)
- {
- //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
- //write_nic_byte(dev, CCK_TXAGC, u1bTmp);
- write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
- }
-
- u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
- if(u1bTmp < OfdmTxPwrIdx)
- {
- //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
- //write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- }
- }
- }
-
- //printk("<---- DoTxHighPower()\n");
-}
-
-
-//
-// Description:
-// Callback function of UpdateTxPowerWorkItem.
-// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
-// We update Tx power of current channel again.
-//
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_tx_pw_wq (struct work_struct *work)
-{
-// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-// struct ieee80211_device * ieee = (struct ieee80211_device*)
-// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
- struct net_device *dev = ieee->dev;
-#else
-void rtl8180_tx_pw_wq(struct net_device *dev)
-{
- // struct r8180_priv *priv = ieee80211_priv(dev);
-#endif
-
-// printk("----> UpdateTxPowerWorkItemCallback()\n");
-
- DoTxHighPower(dev);
-
-// printk("<---- UpdateTxPowerWorkItemCallback()\n");
-}
-
-
-//
-// Description:
-// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
-//
-bool
-CheckDig(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if(!priv->bDigMechanism)
- return false;
-
- if(ieee->state != IEEE80211_LINKED)
- return false;
-
- //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
- if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
- return false;
- return true;
-}
-//
-// Description:
-// Implementation of DIG for Zebra and Zebra2.
-//
-void
-DIG_Zebra(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 CCKFalseAlarm, OFDMFalseAlarm;
- u16 OfdmFA1, OfdmFA2;
- int InitialGainStep = 7; // The number of initial gain stages.
- int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
- u32 AwakePeriodIn2Sec=0;
-
- //printk("---------> DIG_Zebra()\n");
-
- CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
- OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
- OfdmFA1 = 0x15;
- OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
-
-// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
-// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
-
- // The number of initial gain steps is different, by Bruce, 2007-04-13.
- if (priv->InitialGain == 0 ) //autoDIG
- { // Advised from SD3 DZ
- priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
- }
- //if(pHalData->VersionID != VERSION_8187B_B)
- { // Advised from SD3 DZ
- OfdmFA1 = 0x20;
- }
-
-#if 1 //lzm reserved 080826
- AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
- //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
- priv ->DozePeriodInPast2Sec=0;
-
- if(AwakePeriodIn2Sec)
- {
- //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
- // adjuest DIG threshold.
- OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
- OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
- //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
- }
- else
- {
- ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
- }
-#endif
-
- InitialGainStep = 8;
- LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
-
- if (OFDMFalseAlarm > OfdmFA1)
- {
- if (OFDMFalseAlarm > OfdmFA2)
- {
- priv->DIG_NumberFallbackVote++;
- if (priv->DIG_NumberFallbackVote >1)
- {
- //serious OFDM False Alarm, need fallback
- if (priv->InitialGain < InitialGainStep)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain + 1);
-// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
-// printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote=0;
- }
- }
- else
- {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- }
- priv->DIG_NumberUpgradeVote=0;
- }
- else
- {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- priv->DIG_NumberUpgradeVote++;
-
- if (priv->DIG_NumberUpgradeVote>9)
- {
- if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain - 1);
-// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
-// printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote=0;
- }
- }
-
-// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
- //printk("<--------- DIG_Zebra()\n");
-}
-
-//
-// Description:
-// Dispatch DIG implementation according to RF.
-//
-void
-DynamicInitGain(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
- case RF_ZEBRA4:
- DIG_Zebra( dev );
- break;
-
- default:
- printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
- break;
- }
-}
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_hw_dig_wq (struct work_struct *work)
-{
-// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
-// struct ieee80211_device * ieee = (struct ieee80211_device*)
-// container_of(work, struct ieee80211_device, watch_dog_wq);
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
- struct net_device *dev = ieee->dev;
-#else
-void rtl8180_hw_dig_wq(struct net_device *dev)
-{
-
-#endif
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- // Read CCK and OFDM False Alarm.
- priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
-
-
- // Adjust Initial Gain dynamically.
- DynamicInitGain(dev);
-
-}
-
-int
-IncludedInSupportedRates(
- struct r8180_priv *priv,
- u8 TxRate )
-{
- u8 rate_len;
- u8 rate_ex_len;
- u8 RateMask = 0x7F;
- u8 idx;
- unsigned short Found = 0;
- u8 NaiveTxRate = TxRate&RateMask;
-
- rate_len = priv->ieee80211->current_network.rates_len;
- rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
- for( idx=0; idx< rate_len; idx++ )
- {
- if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
- {
- Found = 1;
- goto found_rate;
- }
- }
- for( idx=0; idx< rate_ex_len; idx++ )
- {
- if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
- {
- Found = 1;
- goto found_rate;
- }
- }
- return Found;
- found_rate:
- return Found;
-}
-
-//
-// Description:
-// Get the Tx rate one degree up form the input rate in the supported rates.
-// Return the upgrade rate if it is successed, otherwise return the input rate.
-// By Bruce, 2007-06-05.
-//
-u8
-GetUpgradeTxRate(
- struct net_device *dev,
- u8 rate
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 UpRate;
-
- // Upgrade 1 degree.
- switch(rate)
- {
- case 108: // Up to 54Mbps.
- UpRate = 108;
- break;
-
- case 96: // Up to 54Mbps.
- UpRate = 108;
- break;
-
- case 72: // Up to 48Mbps.
- UpRate = 96;
- break;
-
- case 48: // Up to 36Mbps.
- UpRate = 72;
- break;
-
- case 36: // Up to 24Mbps.
- UpRate = 48;
- break;
-
- case 22: // Up to 18Mbps.
- UpRate = 36;
- break;
-
- case 11: // Up to 11Mbps.
- UpRate = 22;
- break;
-
- case 4: // Up to 5.5Mbps.
- UpRate = 11;
- break;
-
- case 2: // Up to 2Mbps.
- UpRate = 4;
- break;
-
- default:
- printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- // Check if the rate is valid.
- if(IncludedInSupportedRates(priv, UpRate))
- {
-// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
- return UpRate;
- }
- else
- {
- //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
- return rate;
- }
- return rate;
-}
-//
-// Description:
-// Get the Tx rate one degree down form the input rate in the supported rates.
-// Return the degrade rate if it is successed, otherwise return the input rate.
-// By Bruce, 2007-06-05.
-//
-u8
-GetDegradeTxRate(
- struct net_device *dev,
- u8 rate
- )
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 DownRate;
-
- // Upgrade 1 degree.
- switch(rate)
- {
- case 108: // Down to 48Mbps.
- DownRate = 96;
- break;
-
- case 96: // Down to 36Mbps.
- DownRate = 72;
- break;
-
- case 72: // Down to 24Mbps.
- DownRate = 48;
- break;
-
- case 48: // Down to 18Mbps.
- DownRate = 36;
- break;
-
- case 36: // Down to 11Mbps.
- DownRate = 22;
- break;
-
- case 22: // Down to 5.5Mbps.
- DownRate = 11;
- break;
-
- case 11: // Down to 2Mbps.
- DownRate = 4;
- break;
-
- case 4: // Down to 1Mbps.
- DownRate = 2;
- break;
-
- case 2: // Down to 1Mbps.
- DownRate = 2;
- break;
-
- default:
- printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- // Check if the rate is valid.
- if(IncludedInSupportedRates(priv, DownRate))
- {
-// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
- return DownRate;
- }
- else
- {
- //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
- return rate;
- }
- return rate;
-}
-//
-// Helper function to determine if specified data rate is
-// CCK rate.
-// 2005.01.25, by rcnjko.
-//
-bool
-MgntIsCckRate(
- u16 rate
- )
-{
- bool bReturn = false;
-
- if((rate <= 22) && (rate != 12) && (rate != 18))
- {
- bReturn = true;
- }
-
- return bReturn;
-}
-#ifdef CONFIG_RTL818X_S
-//
-// Description:
-// Tx Power tracking mechanism routine on 87SE.
-// Created by Roger, 2007.12.11.
-//
-void
-TxPwrTracking87SE(
- struct net_device *dev
-)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 tmpu1Byte, CurrentThermal, Idx;
- char CckTxPwrIdx, OfdmTxPwrIdx;
- //u32 u4bRfReg;
-
- tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
- CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
- CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
-
- //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
-
- if( CurrentThermal != priv->ThermalMeter)
- {
-// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
-
- // Update Tx Power level on each channel.
- for(Idx = 1; Idx<15; Idx++)
- {
- CckTxPwrIdx = priv->chtxpwr[Idx];
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
-
- if( CurrentThermal > priv->ThermalMeter )
- { // higher thermal meter.
- CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
- OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
-
- if(CckTxPwrIdx >35)
- CckTxPwrIdx = 35; // Force TxPower to maximal index.
- if(OfdmTxPwrIdx >35)
- OfdmTxPwrIdx = 35;
- }
- else
- { // lower thermal meter.
- CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
- OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
-
- if(CckTxPwrIdx <0)
- CckTxPwrIdx = 0;
- if(OfdmTxPwrIdx <0)
- OfdmTxPwrIdx = 0;
- }
-
- // Update TxPower level on CCK and OFDM resp.
- priv->chtxpwr[Idx] = CckTxPwrIdx;
- priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
- }
-
- // Update TxPower level immediately.
- rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
- }
- priv->ThermalMeter = CurrentThermal;
-}
-void
-StaRateAdaptive87SE(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long CurrTxokCnt;
- u16 CurrRetryCnt;
- u16 CurrRetryRate;
- //u16 i,idx;
- unsigned long CurrRxokCnt;
- bool bTryUp = false;
- bool bTryDown = false;
- u8 TryUpTh = 1;
- u8 TryDownTh = 2;
- u32 TxThroughput;
- long CurrSignalStrength;
- bool bUpdateInitialGain = false;
- u8 u1bOfdm=0, u1bCck = 0;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
-
-
- CurrRetryCnt = priv->CurrRetryCnt;
- CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
- CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
- CurrSignalStrength = priv->Stats_RecvSignalPower;
- TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
- priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
- priv->CurrentOperaRate = priv->ieee80211->rate/5;
- //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
- //2 Compute retry ratio.
- if (CurrTxokCnt>0)
- {
- CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
- }
- else
- { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
- CurrRetryRate = (u16)(CurrRetryCnt*100/1);
- }
-
-
- //
- // Added by Roger, 2007.01.02.
- // For debug information.
- //
- //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
- //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
- //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
- //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
- //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
- //printk("(6) TxThroughput is %d\n",TxThroughput);
- //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
-
- priv->LastRetryCnt = priv->CurrRetryCnt;
- priv->LastTxokCnt = priv->NumTxOkTotal;
- priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
- priv->CurrRetryCnt = 0;
-
- //2No Tx packets, return to init_rate or not?
- if (CurrRetryRate==0 && CurrTxokCnt == 0)
- {
- //
- //After 9 (30*300ms) seconds in this condition, we try to raise rate.
- //
- priv->TryupingCountNoData++;
-
-// printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
- //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
- if (priv->TryupingCountNoData>30)
- {
- priv->TryupingCountNoData = 0;
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
- // Reset Fail Record
- priv->LastFailTxRate = 0;
- priv->LastFailTxRateSS = -200;
- priv->FailTxRateCount = 0;
- }
- goto SetInitialGain;
- }
- else
- {
- priv->TryupingCountNoData=0; //Reset trying up times.
- }
-
-
- //
- // For Netgear case, I comment out the following signal strength estimation,
- // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
- // 2007.04.09, by Roger.
- //
-
- //
- // Restructure rate adaptive as the following main stages:
- // (1) Add retry threshold in 54M upgrading condition with signal strength.
- // (2) Add the mechanism to degrade to CCK rate according to signal strength
- // and retry rate.
- // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
- // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
- // (4) Add the mehanism of trying to upgrade tx rate.
- // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
- // By Bruce, 2007-06-05.
- //
- //
-
- // 11Mbps or 36Mbps
- // Check more times in these rate(key rates).
- //
- if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
- {
- TryUpTh += 9;
- }
- //
- // Let these rates down more difficult.
- //
- if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
- {
- TryDownTh += 1;
- }
-
- //1 Adjust Rate.
- if (priv->bTryuping == true)
- {
- //2 For Test Upgrading mechanism
- // Note:
- // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
- // thus the low data rate does not improve the performance.
- // We randomly upgrade the data rate and check if the retry rate is improved.
-
- // Upgrading rate did not improve the retry rate, fallback to the original rate.
- if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
- {
- //Not necessary raising rate, fall back rate.
- bTryDown = true;
- //printk("case1-1: Not necessary raising rate, fall back rate....\n");
- //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
- // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
- }
- else
- {
- priv->bTryuping = false;
- }
- }
- else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
- {
- //2For High Power
- //
- // Added by Roger, 2007.04.09.
- // Return to highest data rate, if signal strength is good enough.
- // SignalStrength threshold(-50dbm) is for RTL8186.
- // Revise SignalStrength threshold to -51dbm.
- //
- // Also need to check retry rate for safety, by Bruce, 2007-06-05.
- if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
- {
- bTryUp = true;
- // Upgrade Tx Rate directly.
- priv->TryupingCount += TryUpTh;
- }
-// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
-
- }
- else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
- {
- //2 For Serious Retry
- //
- // Traffic is not busy but our Tx retry is serious.
- //
- bTryDown = true;
- // Let Rate Mechanism to degrade tx rate directly.
- priv->TryDownCountLowData += TryDownTh;
-// printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
- }
- else if ( priv->CurrentOperaRate == 108 )
- {
- //2For 54Mbps
- // Air Link
- if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
-// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
- {
- //Down to rate 48Mbps.
- bTryDown = true;
- }
- // Cable Link
- else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
-// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
- {
- //Down to rate 48Mbps.
- bTryDown = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -75)) //cable link
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case4---54M \n");
-
- }
- else if ( priv->CurrentOperaRate == 96 )
- {
- //2For 48Mbps
- //Air Link
- if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
-// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
-
- {
- //Down to rate 36Mbps.
- bTryDown = true;
- }
- //Cable Link
- else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
- {
- //Down to rate 36Mbps.
- bTryDown = true;
- }
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
- {
- bTryUp = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -75))
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case5---48M \n");
- }
- else if ( priv->CurrentOperaRate == 72 )
- {
- //2For 36Mbps
- if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
-// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
- {
- //Down to rate 24Mbps.
- bTryDown = true;
- }
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
- {
- bTryUp = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -80))
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case6---36M \n");
- }
- else if ( priv->CurrentOperaRate == 48 )
- {
- //2For 24Mbps
- // Air Link
- if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
-// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
- {
- //Down to rate 18Mbps.
- bTryDown = true;
- }
- //Cable Link
- else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
-// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
- {
- //Down to rate 18Mbps.
- bTryDown = true;
- }
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
-
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
- {
- bTryUp = true;
- }
-
- if(bTryDown && (CurrSignalStrength < -82))
- {
- priv->TryDownCountLowData += TryDownTh;
- }
- //printk("case7---24M \n");
- }
- else if ( priv->CurrentOperaRate == 36 )
- {
- //2For 18Mbps
- // original (109, 109)
- //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
- // (85, 86), Isaiah 2008-02-18 24:00
- if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
-// if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
- {
- //Down to rate 11Mbps.
- bTryDown = true;
- }
- //[TRC Dell Lab] Isaiah 2008-02-18 23:24
- else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
-// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
- {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- }
- else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
- {
- bTryUp = true;
- }
- //printk("case8---18M \n");
- }
- else if ( priv->CurrentOperaRate == 22 )
- {
- //2For 11Mbps
- if (CurrRetryRate>95)
-// if (CurrRetryRate>155)
- {
- bTryDown = true;
- }
- else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
-// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
- {
- bTryUp = true;
- }
- //printk("case9---11M \n");
- }
- else if ( priv->CurrentOperaRate == 11 )
- {
- //2For 5.5Mbps
- if (CurrRetryRate>149)
-// if (CurrRetryRate>189)
- {
- bTryDown = true;
- }
- else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
-// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
-
- {
- bTryUp = true;
- }
- //printk("case10---5.5M \n");
- }
- else if ( priv->CurrentOperaRate == 4 )
- {
- //2For 2 Mbps
- if((CurrRetryRate>99) && (priv->LastRetryRate>99))
-// if((CurrRetryRate>199) && (priv->LastRetryRate>199))
- {
- bTryDown = true;
- }
- else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
-// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
- {
- bTryUp = true;
- }
- //printk("case11---2M \n");
- }
- else if ( priv->CurrentOperaRate == 2 )
- {
- //2For 1 Mbps
- if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
-// if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
- {
- bTryUp = true;
- }
- //printk("case12---1M \n");
- }
-
- if(bTryUp && bTryDown)
- printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
-
- //1 Test Upgrading Tx Rate
- // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
- // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
- if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
- && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
- {
- if(jiffies% (CurrRetryRate + 101) == 0)
- {
- bTryUp = true;
- priv->bTryuping = true;
- //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
- }
- }
-
- //1 Rate Mechanism
- if(bTryUp)
- {
- priv->TryupingCount++;
- priv->TryDownCountLowData = 0;
-
- {
-// printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
-// printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
-// TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
-// printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);
-
- }
-
- //
- // Check more times if we need to upgrade indeed.
- // Because the largest value of pHalData->TryupingCount is 0xFFFF and
- // the largest value of pHalData->FailTxRateCount is 0x14,
- // this condition will be satisfied at most every 2 min.
- //
-
- if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
- (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
- {
- priv->TryupingCount = 0;
- //
- // When transfering from CCK to OFDM, DIG is an important issue.
- //
- if(priv->CurrentOperaRate == 22)
- bUpdateInitialGain = true;
-
- // The difference in throughput between 48Mbps and 36Mbps is 8M.
- // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
- //
- if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
- (priv->FailTxRateCount > 2) )
- priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
-
- // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
- // (2)If the signal strength is increased, it may be able to upgrade.
-
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
-// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
-
- //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
- if(priv->CurrentOperaRate ==36)
- {
- priv->bUpdateARFR=true;
- write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
-// printk("UP: ARFR=0xF8F\n");
- }
- else if(priv->bUpdateARFR)
- {
- priv->bUpdateARFR=false;
- write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
-// printk("UP: ARFR=0xFFF\n");
- }
-
- // Update Fail Tx rate and count.
- if(priv->LastFailTxRate != priv->CurrentOperaRate)
- {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 0;
- priv->LastFailTxRateSS = -200; // Set lowest power.
- }
- }
- }
- else
- {
- if(priv->TryupingCount > 0)
- priv->TryupingCount --;
- }
-
- if(bTryDown)
- {
- priv->TryDownCountLowData++;
- priv->TryupingCount = 0;
- {
-// printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
-// printk("DN: TryDownTh =%d\n", TryDownTh);
-// printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
- }
-
- //Check if Tx rate can be degraded or Test trying upgrading should fallback.
- if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
- {
- priv->TryDownCountLowData = 0;
- priv->bTryuping = false;
- // Update fail information.
- if(priv->LastFailTxRate == priv->CurrentOperaRate)
- {
- priv->FailTxRateCount ++;
- // Record the Tx fail rate signal strength.
- if(CurrSignalStrength > priv->LastFailTxRateSS)
- {
- priv->LastFailTxRateSS = CurrSignalStrength;
- }
- }
- else
- {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 1;
- priv->LastFailTxRateSS = CurrSignalStrength;
- }
- priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
-
- // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
- //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
- if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
- {
- priv->CurrentOperaRate = 72;
-// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
- }
-
- //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
- if(priv->CurrentOperaRate ==36)
- {
- priv->bUpdateARFR=true;
- write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
-// printk("DN: ARFR=0xF8F\n");
- }
- else if(priv->bUpdateARFR)
- {
- priv->bUpdateARFR=false;
- write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
-// printk("DN: ARFR=0xFFF\n");
- }
-
- //
- // When it is CCK rate, it may need to update initial gain to receive lower power packets.
- //
- if(MgntIsCckRate(priv->CurrentOperaRate))
- {
- bUpdateInitialGain = true;
- }
-// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
- }
- }
- else
- {
- if(priv->TryDownCountLowData > 0)
- priv->TryDownCountLowData --;
- }
-
- // Keep the Tx fail rate count to equal to 0x15 at most.
- // Reduce the fail count at least to 10 sec if tx rate is tending stable.
- if(priv->FailTxRateCount >= 0x15 ||
- (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
- {
- priv->FailTxRateCount --;
- }
-
-
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
- if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
- {
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- // case 1: Never enter High power
- if(u1bCck == CckTxPwrIdx )
- {
- if(u1bOfdm != (OfdmTxPwrIdx+2) )
- {
- priv->bEnhanceTxPwr= true;
- u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
-// printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
- }
- }
- // case 2: enter high power
- else if(u1bCck < CckTxPwrIdx)
- {
- if(!priv->bEnhanceTxPwr)
- {
- priv->bEnhanceTxPwr= true;
- u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
- }
- }
- }
- else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
- {
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- // case 1: Never enter High power
- if(u1bCck == CckTxPwrIdx )
- {
- priv->bEnhanceTxPwr= false;
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
- }
- // case 2: enter high power
- else if(u1bCck < CckTxPwrIdx)
- {
- priv->bEnhanceTxPwr= false;
- u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
-
- }
- }
-
- //
- // We need update initial gain when we set tx rate "from OFDM to CCK" or
- // "from CCK to OFDM".
- //
-SetInitialGain:
- if(bUpdateInitialGain)
- {
- if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
- {
- if(priv->InitialGain > priv->RegBModeGainStage)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
- {
- //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
- priv->InitialGain = priv->RegBModeGainStage;
- }
- else if(priv->InitialGain > priv->RegBModeGainStage + 1)
- {
- priv->InitialGain -= 2;
- }
- else
- {
- priv->InitialGain --;
- }
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- }
- else // OFDM
- {
- if(priv->InitialGain < 4)
- {
- priv->InitialGainBackUp= priv->InitialGain;
-
- priv->InitialGain ++;
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- }
- }
-
- //Record the related info
- priv->LastRetryRate = CurrRetryRate;
- priv->LastTxThroughput = TxThroughput;
- priv->ieee80211->rate = priv->CurrentOperaRate * 5;
-}
-
-#endif
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
-void rtl8180_rate_adapter(struct work_struct * work)
-{
- struct delayed_work *dwork = container_of(work,struct delayed_work,work);
- struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
- struct net_device *dev = ieee->dev;
-#else
-void rtl8180_rate_adapter(struct net_device *dev)
-{
-
-#endif
- //struct r8180_priv *priv = ieee80211_priv(dev);
-// DMESG("---->rtl8180_rate_adapter");
- StaRateAdaptive87SE(dev);
-// DMESG("<----rtl8180_rate_adapter");
-}
-void timer_rate_adaptive(unsigned long data)
-{
- struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
- //DMESG("---->timer_rate_adaptive()\n");
- if(!priv->up)
- {
-// DMESG("<----timer_rate_adaptive():driver is not up!\n");
- return;
- }
- if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
- && (priv->ieee80211->state == IEEE80211_LINKED) &&
- (priv->ForcedDataRate == 0) )
- {
-// DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
-#ifdef CONFIG_RTL818X_S
- queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
-// StaRateAdaptive87SE((struct net_device *)data);
-#endif
- }
- priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
- add_timer(&priv->rateadapter_timer);
- //DMESG("<----timer_rate_adaptive()\n");
-}
-//by amy 080312}
-void
-SwAntennaDiversityRxOk8185(
- struct net_device *dev,
- u8 SignalStrength
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
-
- priv->AdRxOkCnt++;
-
- if( priv->AdRxSignalStrength != -1)
- {
- priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
- }
- else
- { // Initialization case.
- priv->AdRxSignalStrength = SignalStrength;
- }
-//{+by amy 080312
- if( priv->LastRxPktAntenna ) //Main antenna.
- priv->AdMainAntennaRxOkCnt++;
- else // Aux antenna.
- priv->AdAuxAntennaRxOkCnt++;
-//+by amy 080312
-// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
-}
-//
-// Description:
-// Change Antenna Switch.
-//
-bool
-SetAntenna8185(
- struct net_device *dev,
- u8 u1bAntennaIndex
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bAntennaSwitched = false;
-
-// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
-
- switch(u1bAntennaIndex)
- {
- case 0:
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
- // Mac register, main antenna
- write_nic_byte(dev, ANTSEL, 0x03);
- //base band
- write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
-
-#else
- // Mac register, main antenna
- write_nic_byte(dev, ANTSEL, 0x03);
- //base band
- write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
-#endif
-#endif
-
- bAntennaSwitched = true;
- break;
-
- default:
- printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
- break;
- }
- break;
-
- case 1:
- switch(priv->rf_chip)
- {
- case RF_ZEBRA2:
- case RF_ZEBRA4:
-#ifdef CONFIG_RTL8185B
-#ifdef CONFIG_RTL818X_S
- // Mac register, aux antenna
- write_nic_byte(dev, ANTSEL, 0x00);
- //base band
- write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
-#else
- // Mac register, aux antenna
- write_nic_byte(dev, ANTSEL, 0x00);
- //base band
- write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
- write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
-#endif
-#endif
-
- bAntennaSwitched = true;
- break;
-
- default:
- printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
- break;
- }
- break;
-
- default:
- printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
- break;
- }
-
- if(bAntennaSwitched)
- {
- priv->CurrAntennaIndex = u1bAntennaIndex;
- }
-
-// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
-
- return bAntennaSwitched;
-}
-//
-// Description:
-// Toggle Antenna switch.
-//
-bool
-SwitchAntenna(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- bool bResult;
-
- if(priv->CurrAntennaIndex == 0)
- {
-#if 0//lzm del 080826
-//by amy 080312
-#ifdef CONFIG_RTL818X_S
- if(priv->bSwAntennaDiverity)
- bResult = SetAntennaConfig87SE(dev, 1, true);
- else
-#endif
-#endif
- bResult = SetAntenna8185(dev, 1);
-//by amy 080312
-// printk("SwitchAntenna(): switching to antenna 1 ......\n");
-// bResult = SetAntenna8185(dev, 1);//-by amy 080312
- }
- else
- {
-#if 0//lzm del 080826
-//by amy 080312
-#ifdef CONFIG_RTL818X_S
- if(priv->bSwAntennaDiverity)
- bResult = SetAntennaConfig87SE(dev, 0, true);
- else
-#endif
-#endif
- bResult = SetAntenna8185(dev, 0);
-//by amy 080312
-// printk("SwitchAntenna(): switching to antenna 0 ......\n");
-// bResult = SetAntenna8185(dev, 0);//-by amy 080312
- }
-
- return bResult;
-}
-//
-// Description:
-// Engine of SW Antenna Diversity mechanism.
-// Since 8187 has no Tx part information,
-// this implementation is only dependend on Rx part information.
-//
-// 2006.04.17, by rcnjko.
-//
-void
-SwAntennaDiversity(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bSwCheckSS=false;
-// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
-// printk("AdTickCount is %d\n",priv->AdTickCount);
-//by amy 080312
- if(bSwCheckSS)
- {
- priv->AdTickCount++;
-
- printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
- priv->AdTickCount, priv->AdCheckPeriod);
- printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
- priv->AdRxSignalStrength, priv->AdRxSsThreshold);
- }
-// priv->AdTickCount++;//-by amy 080312
-
- // Case 1. No Link.
- if(priv->ieee80211->state != IEEE80211_LINKED)
- {
- // printk("SwAntennaDiversity(): Case 1. No Link.\n");
-
- priv->bAdSwitchedChecking = false;
- // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
- SwitchAntenna(dev);
- }
- // Case 2. Linked but no packet received.
- else if(priv->AdRxOkCnt == 0)
- {
- // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
-
- priv->bAdSwitchedChecking = false;
- SwitchAntenna(dev);
- }
- // Case 3. Evaluate last antenna switch action and undo it if necessary.
- else if(priv->bAdSwitchedChecking == true)
- {
- // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
-
- priv->bAdSwitchedChecking = false;
-
- // Adjust Rx signal strength threashold.
- priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
-
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
- if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
- { // Rx signal strength is not improved after we swtiched antenna. => Swich back.
-// printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
-//by amy 080312
- // Increase Antenna Diversity checking period due to bad decision.
- priv->AdCheckPeriod *= 2;
-//by amy 080312
- // Increase Antenna Diversity checking period.
- if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
- priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
-
- // Wrong deceision => switch back.
- SwitchAntenna(dev);
- }
- else
- { // Rx Signal Strength is improved.
-// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
-
- // Reset Antenna Diversity checking period to its min value.
- priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- }
-
-// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
-// priv->AdRxSsThreshold, priv->AdCheckPeriod);
- }
- // Case 4. Evaluate if we shall switch antenna now.
- // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
- else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
- {
-// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
-
- priv->AdTickCount = 0;
-
- //
- // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
- // evaluate signal strength.
- // The following operation can overcome the disability of CCA on both two antennas
- // When signal strength was extremely low or high.
- // 2008.01.30.
- //
-
- //
- // Evaluate RxOk count from each antenna if we shall switch default antenna now.
- // Added by Roger, 2008.02.21.
-//{by amy 080312
- if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 0))
- { // We set Main antenna as default but RxOk count was less than Aux ones.
-
- // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
- // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
-
- // Switch to Aux antenna.
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- }
- else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 1))
- { // We set Aux antenna as default but RxOk count was less than Main ones.
-
- // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
- // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
-
- // Switch to Main antenna.
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- }
- else
- {// Default antenna is better.
-
- // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
- // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
-
- // Still need to check current signal strength.
- priv->bHWAdSwitched = false;
- }
- //
- // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
- // didn't changed by HW evaluation.
- // 2008.02.27.
- //
- // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
- // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
- // but AdRxSignalStrength is less than main.
- // Our guess is that main antenna have lower throughput and get many change
- // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
- //
- if( (!priv->bHWAdSwitched) && (bSwCheckSS))
- {
-//by amy 080312}
- // Evaluate Rx signal strength if we shall switch antenna now.
- if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
- { // Rx signal strength is weak => Switch Antenna.
-// printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
-
- priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
- priv->bAdSwitchedChecking = true;
-
- SwitchAntenna(dev);
- }
- else
- { // Rx signal strength is OK.
-// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
-// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
-
- priv->bAdSwitchedChecking = false;
- // Increase Rx signal strength threashold if necessary.
- if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
- priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
- {
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
- }
-
- // Reduce Antenna Diversity checking period if possible.
- if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
- {
- priv->AdCheckPeriod /= 2;
- }
- }
- }
- }
-//by amy 080312
- // Reset antenna diversity Rx related statistics.
- priv->AdRxOkCnt = 0;
- priv->AdMainAntennaRxOkCnt = 0;
- priv->AdAuxAntennaRxOkCnt = 0;
-//by amy 080312
-
-// priv->AdRxOkCnt = 0;//-by amy 080312
-
-// printk("-SwAntennaDiversity()\n");
-}
-
-//
-// Description:
-// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
-//
-bool
-CheckTxPwrTracking( struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- if(!priv->bTxPowerTrack)
- {
- return false;
- }
-
-//lzm reserved 080826
- //if(priv->bScanInProgress)
- //{
- // return false;
- //}
-
- //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
- if(priv->bToUpdateTxPwr)
- {
- return false;
- }
-
- return true;
-}
-
-
-//
-// Description:
-// Timer callback function of SW Antenna Diversity.
-//
-void
-SwAntennaDiversityTimerCallback(
- struct net_device *dev
- )
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- RT_RF_POWER_STATE rtState;
-
- //printk("+SwAntennaDiversityTimerCallback()\n");
-
- //
- // We do NOT need to switch antenna while RF is off.
- // 2007.05.09, added by Roger.
- //
- rtState = priv->eRFPowerState;
- do{
- if (rtState == eRfOff)
- {
-// printk("SwAntennaDiversityTimer - RF is OFF.\n");
- break;
- }
- else if (rtState == eRfSleep)
- {
- // Don't access BB/RF under Disable PLL situation.
- //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
- break;
- }
- SwAntennaDiversity(dev);
-
- }while(false);
-
- if(priv->up)
- {
- priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
- add_timer(&priv->SwAntennaDiversityTimer);
- }
-
- //printk("-SwAntennaDiversityTimerCallback()\n");
-}
-
+//#include "r8180.h"
+#include "r8180_dm.h"
+#include "r8180_hw.h"
+#include "r8180_93cx6.h"
+//{by amy 080312
+
+//
+// Description:
+// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
+//
+//+by amy 080312
+#define RATE_ADAPTIVE_TIMER_PERIOD 300
+
+bool CheckHighPower(struct net_device *dev)
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee80211;
+
+ if(!priv->bRegHighPowerMechanism)
+ {
+ return false;
+ }
+
+ if(ieee->state == IEEE80211_LINKED_SCANNING)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+//
+// Description:
+// Update Tx power level if necessary.
+// See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
+//
+// Note:
+// The reason why we udpate Tx power level here instead of DoRxHighPower()
+// is the number of IO to change Tx power is much more than chane TR switch
+// and they are related to OFDM and MAC registers.
+// So, we don't want to update it so frequently in per-Rx packet base.
+//
+void
+DoTxHighPower(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u16 HiPwrUpperTh = 0;
+ u16 HiPwrLowerTh = 0;
+ u8 RSSIHiPwrUpperTh;
+ u8 RSSIHiPwrLowerTh;
+ u8 u1bTmp;
+ char OfdmTxPwrIdx, CckTxPwrIdx;
+
+ //printk("----> DoTxHighPower()\n");
+
+ HiPwrUpperTh = priv->RegHiPwrUpperTh;
+ HiPwrLowerTh = priv->RegHiPwrLowerTh;
+
+ HiPwrUpperTh = HiPwrUpperTh * 10;
+ HiPwrLowerTh = HiPwrLowerTh * 10;
+ RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
+ RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
+
+ //lzm add 080826
+ OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
+ CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
+
+ // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
+
+ if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
+ (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
+ {
+ // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
+
+ // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
+ priv->bToUpdateTxPwr = true;
+ u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+
+ // If it never enter High Power.
+ if( CckTxPwrIdx == u1bTmp)
+ {
+ u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
+ write_nic_byte(dev, CCK_TXAGC, u1bTmp);
+
+ u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+ u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
+ write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
+ }
+
+ }
+ else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
+ (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
+ {
+ // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
+ if(priv->bToUpdateTxPwr)
+ {
+ priv->bToUpdateTxPwr = false;
+ //SD3 required.
+ u1bTmp= read_nic_byte(dev, CCK_TXAGC);
+ if(u1bTmp < CckTxPwrIdx)
+ {
+ //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
+ //write_nic_byte(dev, CCK_TXAGC, u1bTmp);
+ write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
+ }
+
+ u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
+ if(u1bTmp < OfdmTxPwrIdx)
+ {
+ //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
+ //write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
+ write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
+ }
+ }
+ }
+
+ //printk("<---- DoTxHighPower()\n");
+}
+
+
+//
+// Description:
+// Callback function of UpdateTxPowerWorkItem.
+// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
+// We update Tx power of current channel again.
+//
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_tx_pw_wq (struct work_struct *work)
+{
+// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
+// struct ieee80211_device * ieee = (struct ieee80211_device*)
+// container_of(work, struct ieee80211_device, watch_dog_wq);
+ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
+ struct net_device *dev = ieee->dev;
+#else
+void rtl8180_tx_pw_wq(struct net_device *dev)
+{
+ // struct r8180_priv *priv = ieee80211_priv(dev);
+#endif
+
+// printk("----> UpdateTxPowerWorkItemCallback()\n");
+
+ DoTxHighPower(dev);
+
+// printk("<---- UpdateTxPowerWorkItemCallback()\n");
+}
+
+
+//
+// Description:
+// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
+//
+bool
+CheckDig(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ struct ieee80211_device *ieee = priv->ieee80211;
+
+ if(!priv->bDigMechanism)
+ return false;
+
+ if(ieee->state != IEEE80211_LINKED)
+ return false;
+
+ //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
+ if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
+ return false;
+ return true;
+}
+//
+// Description:
+// Implementation of DIG for Zebra and Zebra2.
+//
+void
+DIG_Zebra(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u16 CCKFalseAlarm, OFDMFalseAlarm;
+ u16 OfdmFA1, OfdmFA2;
+ int InitialGainStep = 7; // The number of initial gain stages.
+ int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
+ u32 AwakePeriodIn2Sec=0;
+
+ //printk("---------> DIG_Zebra()\n");
+
+ CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
+ OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
+ OfdmFA1 = 0x15;
+ OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
+
+// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
+// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
+
+ // The number of initial gain steps is different, by Bruce, 2007-04-13.
+ if (priv->InitialGain == 0 ) //autoDIG
+ { // Advised from SD3 DZ
+ priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
+ }
+ //if(pHalData->VersionID != VERSION_8187B_B)
+ { // Advised from SD3 DZ
+ OfdmFA1 = 0x20;
+ }
+
+#if 1 //lzm reserved 080826
+ AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
+ //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
+ priv ->DozePeriodInPast2Sec=0;
+
+ if(AwakePeriodIn2Sec)
+ {
+ //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
+ // adjuest DIG threshold.
+ OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
+ OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
+ //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
+ }
+ else
+ {
+ ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
+ }
+#endif
+
+ InitialGainStep = 8;
+ LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
+
+ if (OFDMFalseAlarm > OfdmFA1)
+ {
+ if (OFDMFalseAlarm > OfdmFA2)
+ {
+ priv->DIG_NumberFallbackVote++;
+ if (priv->DIG_NumberFallbackVote >1)
+ {
+ //serious OFDM False Alarm, need fallback
+ if (priv->InitialGain < InitialGainStep)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ priv->InitialGain = (priv->InitialGain + 1);
+// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
+// printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
+ UpdateInitialGain(dev);
+ }
+ priv->DIG_NumberFallbackVote = 0;
+ priv->DIG_NumberUpgradeVote=0;
+ }
+ }
+ else
+ {
+ if (priv->DIG_NumberFallbackVote)
+ priv->DIG_NumberFallbackVote--;
+ }
+ priv->DIG_NumberUpgradeVote=0;
+ }
+ else
+ {
+ if (priv->DIG_NumberFallbackVote)
+ priv->DIG_NumberFallbackVote--;
+ priv->DIG_NumberUpgradeVote++;
+
+ if (priv->DIG_NumberUpgradeVote>9)
+ {
+ if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ priv->InitialGain = (priv->InitialGain - 1);
+// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
+// printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
+ UpdateInitialGain(dev);
+ }
+ priv->DIG_NumberFallbackVote = 0;
+ priv->DIG_NumberUpgradeVote=0;
+ }
+ }
+
+// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
+ //printk("<--------- DIG_Zebra()\n");
+}
+
+//
+// Description:
+// Dispatch DIG implementation according to RF.
+//
+void
+DynamicInitGain(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+
+ switch(priv->rf_chip)
+ {
+ case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
+ case RF_ZEBRA4:
+ DIG_Zebra( dev );
+ break;
+
+ default:
+ printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
+ break;
+ }
+}
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_dig_wq (struct work_struct *work)
+{
+// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
+// struct ieee80211_device * ieee = (struct ieee80211_device*)
+// container_of(work, struct ieee80211_device, watch_dog_wq);
+ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
+ struct net_device *dev = ieee->dev;
+#else
+void rtl8180_hw_dig_wq(struct net_device *dev)
+{
+
+#endif
+ struct r8180_priv *priv = ieee80211_priv(dev);
+
+ // Read CCK and OFDM False Alarm.
+ priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
+
+
+ // Adjust Initial Gain dynamically.
+ DynamicInitGain(dev);
+
+}
+
+int
+IncludedInSupportedRates(
+ struct r8180_priv *priv,
+ u8 TxRate )
+{
+ u8 rate_len;
+ u8 rate_ex_len;
+ u8 RateMask = 0x7F;
+ u8 idx;
+ unsigned short Found = 0;
+ u8 NaiveTxRate = TxRate&RateMask;
+
+ rate_len = priv->ieee80211->current_network.rates_len;
+ rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
+ for( idx=0; idx< rate_len; idx++ )
+ {
+ if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
+ {
+ Found = 1;
+ goto found_rate;
+ }
+ }
+ for( idx=0; idx< rate_ex_len; idx++ )
+ {
+ if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
+ {
+ Found = 1;
+ goto found_rate;
+ }
+ }
+ return Found;
+ found_rate:
+ return Found;
+}
+
+//
+// Description:
+// Get the Tx rate one degree up form the input rate in the supported rates.
+// Return the upgrade rate if it is successed, otherwise return the input rate.
+// By Bruce, 2007-06-05.
+//
+u8
+GetUpgradeTxRate(
+ struct net_device *dev,
+ u8 rate
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u8 UpRate;
+
+ // Upgrade 1 degree.
+ switch(rate)
+ {
+ case 108: // Up to 54Mbps.
+ UpRate = 108;
+ break;
+
+ case 96: // Up to 54Mbps.
+ UpRate = 108;
+ break;
+
+ case 72: // Up to 48Mbps.
+ UpRate = 96;
+ break;
+
+ case 48: // Up to 36Mbps.
+ UpRate = 72;
+ break;
+
+ case 36: // Up to 24Mbps.
+ UpRate = 48;
+ break;
+
+ case 22: // Up to 18Mbps.
+ UpRate = 36;
+ break;
+
+ case 11: // Up to 11Mbps.
+ UpRate = 22;
+ break;
+
+ case 4: // Up to 5.5Mbps.
+ UpRate = 11;
+ break;
+
+ case 2: // Up to 2Mbps.
+ UpRate = 4;
+ break;
+
+ default:
+ printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
+ return rate;
+ }
+ // Check if the rate is valid.
+ if(IncludedInSupportedRates(priv, UpRate))
+ {
+// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
+ return UpRate;
+ }
+ else
+ {
+ //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
+ return rate;
+ }
+ return rate;
+}
+//
+// Description:
+// Get the Tx rate one degree down form the input rate in the supported rates.
+// Return the degrade rate if it is successed, otherwise return the input rate.
+// By Bruce, 2007-06-05.
+//
+u8
+GetDegradeTxRate(
+ struct net_device *dev,
+ u8 rate
+ )
+{
+ struct r8180_priv *priv = ieee80211_priv(dev);
+ u8 DownRate;
+
+ // Upgrade 1 degree.
+ switch(rate)
+ {
+ case 108: // Down to 48Mbps.
+ DownRate = 96;
+ break;
+
+ case 96: // Down to 36Mbps.
+ DownRate = 72;
+ break;
+
+ case 72: // Down to 24Mbps.
+ DownRate = 48;
+ break;
+
+ case 48: // Down to 18Mbps.
+ DownRate = 36;
+ break;
+
+ case 36: // Down to 11Mbps.
+ DownRate = 22;
+ break;
+
+ case 22: // Down to 5.5Mbps.
+ DownRate = 11;
+ break;
+
+ case 11: // Down to 2Mbps.
+ DownRate = 4;
+ break;
+
+ case 4: // Down to 1Mbps.
+ DownRate = 2;
+ break;
+
+ case 2: // Down to 1Mbps.
+ DownRate = 2;
+ break;
+
+ default:
+ printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
+ return rate;
+ }
+ // Check if the rate is valid.
+ if(IncludedInSupportedRates(priv, DownRate))
+ {
+// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
+ return DownRate;
+ }
+ else
+ {
+ //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
+ return rate;
+ }
+ return rate;
+}
+//
+// Helper function to determine if specified data rate is
+// CCK rate.
+// 2005.01.25, by rcnjko.
+//
+bool
+MgntIsCckRate(
+ u16 rate
+ )
+{
+ bool bReturn = false;
+
+ if((rate <= 22) && (rate != 12) && (rate != 18))
+ {
+ bReturn = true;
+ }
+
+ return bReturn;
+}
+#ifdef CONFIG_RTL818X_S
+//
+// Description:
+// Tx Power tracking mechanism routine on 87SE.
+// Created by Roger, 2007.12.11.
+//
+void
+TxPwrTracking87SE(
+ struct net_device *dev
+)
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ u8 tmpu1Byte, CurrentThermal, Idx;
+ char CckTxPwrIdx, OfdmTxPwrIdx;
+ //u32 u4bRfReg;
+
+ tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
+ CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
+ CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
+
+ //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
+
+ if( CurrentThermal != priv->ThermalMeter)
+ {
+// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
+
+ // Update Tx Power level on each channel.
+ for(Idx = 1; Idx<15; Idx++)
+ {
+ CckTxPwrIdx = priv->chtxpwr[Idx];
+ OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
+
+ if( CurrentThermal > priv->ThermalMeter )
+ { // higher thermal meter.
+ CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
+ OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
+
+ if(CckTxPwrIdx >35)
+ CckTxPwrIdx = 35; // Force TxPower to maximal index.
+ if(OfdmTxPwrIdx >35)
+ OfdmTxPwrIdx = 35;
+ }
+ else
+ { // lower thermal meter.
+ CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
+ OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
+
+ if(CckTxPwrIdx <0)
+ CckTxPwrIdx = 0;
+ if(OfdmTxPwrIdx <0)
+ OfdmTxPwrIdx = 0;
+ }
+
+ // Update TxPower level on CCK and OFDM resp.
+ priv->chtxpwr[Idx] = CckTxPwrIdx;
+ priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
+ }
+
+ // Update TxPower level immediately.
+ rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
+ }
+ priv->ThermalMeter = CurrentThermal;
+}
+void
+StaRateAdaptive87SE(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ unsigned long CurrTxokCnt;
+ u16 CurrRetryCnt;
+ u16 CurrRetryRate;
+ //u16 i,idx;
+ unsigned long CurrRxokCnt;
+ bool bTryUp = false;
+ bool bTryDown = false;
+ u8 TryUpTh = 1;
+ u8 TryDownTh = 2;
+ u32 TxThroughput;
+ long CurrSignalStrength;
+ bool bUpdateInitialGain = false;
+ u8 u1bOfdm=0, u1bCck = 0;
+ char OfdmTxPwrIdx, CckTxPwrIdx;
+
+ priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
+
+
+ CurrRetryCnt = priv->CurrRetryCnt;
+ CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
+ CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
+ CurrSignalStrength = priv->Stats_RecvSignalPower;
+ TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
+ priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
+ priv->CurrentOperaRate = priv->ieee80211->rate/5;
+ //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
+ //2 Compute retry ratio.
+ if (CurrTxokCnt>0)
+ {
+ CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
+ }
+ else
+ { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
+ CurrRetryRate = (u16)(CurrRetryCnt*100/1);
+ }
+
+
+ //
+ // Added by Roger, 2007.01.02.
+ // For debug information.
+ //
+ //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
+ //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
+ //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
+ //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
+ //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
+ //printk("(6) TxThroughput is %d\n",TxThroughput);
+ //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
+
+ priv->LastRetryCnt = priv->CurrRetryCnt;
+ priv->LastTxokCnt = priv->NumTxOkTotal;
+ priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
+ priv->CurrRetryCnt = 0;
+
+ //2No Tx packets, return to init_rate or not?
+ if (CurrRetryRate==0 && CurrTxokCnt == 0)
+ {
+ //
+ //After 9 (30*300ms) seconds in this condition, we try to raise rate.
+ //
+ priv->TryupingCountNoData++;
+
+// printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
+ //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
+ if (priv->TryupingCountNoData>30)
+ {
+ priv->TryupingCountNoData = 0;
+ priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
+ // Reset Fail Record
+ priv->LastFailTxRate = 0;
+ priv->LastFailTxRateSS = -200;
+ priv->FailTxRateCount = 0;
+ }
+ goto SetInitialGain;
+ }
+ else
+ {
+ priv->TryupingCountNoData=0; //Reset trying up times.
+ }
+
+
+ //
+ // For Netgear case, I comment out the following signal strength estimation,
+ // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
+ // 2007.04.09, by Roger.
+ //
+
+ //
+ // Restructure rate adaptive as the following main stages:
+ // (1) Add retry threshold in 54M upgrading condition with signal strength.
+ // (2) Add the mechanism to degrade to CCK rate according to signal strength
+ // and retry rate.
+ // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
+ // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
+ // (4) Add the mehanism of trying to upgrade tx rate.
+ // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
+ // By Bruce, 2007-06-05.
+ //
+ //
+
+ // 11Mbps or 36Mbps
+ // Check more times in these rate(key rates).
+ //
+ if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
+ {
+ TryUpTh += 9;
+ }
+ //
+ // Let these rates down more difficult.
+ //
+ if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
+ {
+ TryDownTh += 1;
+ }
+
+ //1 Adjust Rate.
+ if (priv->bTryuping == true)
+ {
+ //2 For Test Upgrading mechanism
+ // Note:
+ // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
+ // thus the low data rate does not improve the performance.
+ // We randomly upgrade the data rate and check if the retry rate is improved.
+
+ // Upgrading rate did not improve the retry rate, fallback to the original rate.
+ if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
+ {
+ //Not necessary raising rate, fall back rate.
+ bTryDown = true;
+ //printk("case1-1: Not necessary raising rate, fall back rate....\n");
+ //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
+ // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
+ }
+ else
+ {
+ priv->bTryuping = false;
+ }
+ }
+ else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
+ {
+ //2For High Power
+ //
+ // Added by Roger, 2007.04.09.
+ // Return to highest data rate, if signal strength is good enough.
+ // SignalStrength threshold(-50dbm) is for RTL8186.
+ // Revise SignalStrength threshold to -51dbm.
+ //
+ // Also need to check retry rate for safety, by Bruce, 2007-06-05.
+ if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
+ {
+ bTryUp = true;
+ // Upgrade Tx Rate directly.
+ priv->TryupingCount += TryUpTh;
+ }
+// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
+
+ }
+ else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
+ {
+ //2 For Serious Retry
+ //
+ // Traffic is not busy but our Tx retry is serious.
+ //
+ bTryDown = true;
+ // Let Rate Mechanism to degrade tx rate directly.
+ priv->TryDownCountLowData += TryDownTh;
+// printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
+ }
+ else if ( priv->CurrentOperaRate == 108 )
+ {
+ //2For 54Mbps
+ // Air Link
+ if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
+// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
+ {
+ //Down to rate 48Mbps.
+ bTryDown = true;
+ }
+ // Cable Link
+ else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
+// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
+ {
+ //Down to rate 48Mbps.
+ bTryDown = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -75)) //cable link
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case4---54M \n");
+
+ }
+ else if ( priv->CurrentOperaRate == 96 )
+ {
+ //2For 48Mbps
+ //Air Link
+ if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
+// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
+
+ {
+ //Down to rate 36Mbps.
+ bTryDown = true;
+ }
+ //Cable Link
+ else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
+ {
+ //Down to rate 36Mbps.
+ bTryDown = true;
+ }
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
+ {
+ bTryUp = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -75))
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case5---48M \n");
+ }
+ else if ( priv->CurrentOperaRate == 72 )
+ {
+ //2For 36Mbps
+ if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
+// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
+ {
+ //Down to rate 24Mbps.
+ bTryDown = true;
+ }
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
+ {
+ bTryUp = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -80))
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case6---36M \n");
+ }
+ else if ( priv->CurrentOperaRate == 48 )
+ {
+ //2For 24Mbps
+ // Air Link
+ if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
+// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
+ {
+ //Down to rate 18Mbps.
+ bTryDown = true;
+ }
+ //Cable Link
+ else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
+// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
+ {
+ //Down to rate 18Mbps.
+ bTryDown = true;
+ }
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
+ {
+ bTryUp = true;
+ }
+
+ if(bTryDown && (CurrSignalStrength < -82))
+ {
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ //printk("case7---24M \n");
+ }
+ else if ( priv->CurrentOperaRate == 36 )
+ {
+ //2For 18Mbps
+ // original (109, 109)
+ //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
+ // (85, 86), Isaiah 2008-02-18 24:00
+ if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
+// if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
+ {
+ //Down to rate 11Mbps.
+ bTryDown = true;
+ }
+ //[TRC Dell Lab] Isaiah 2008-02-18 23:24
+ else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
+// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
+ {
+ bTryDown = true;
+ priv->TryDownCountLowData += TryDownTh;
+ }
+ else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
+ {
+ bTryUp = true;
+ }
+ //printk("case8---18M \n");
+ }
+ else if ( priv->CurrentOperaRate == 22 )
+ {
+ //2For 11Mbps
+ if (CurrRetryRate>95)
+// if (CurrRetryRate>155)
+ {
+ bTryDown = true;
+ }
+ else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
+// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
+ {
+ bTryUp = true;
+ }
+ //printk("case9---11M \n");
+ }
+ else if ( priv->CurrentOperaRate == 11 )
+ {
+ //2For 5.5Mbps
+ if (CurrRetryRate>149)
+// if (CurrRetryRate>189)
+ {
+ bTryDown = true;
+ }
+ else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
+// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
+
+ {
+ bTryUp = true;
+ }
+ //printk("case10---5.5M \n");
+ }
+ else if ( priv->CurrentOperaRate == 4 )
+ {
+ //2For 2 Mbps
+ if((CurrRetryRate>99) && (priv->LastRetryRate>99))
+// if((CurrRetryRate>199) && (priv->LastRetryRate>199))
+ {
+ bTryDown = true;
+ }
+ else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
+// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
+ {
+ bTryUp = true;
+ }
+ //printk("case11---2M \n");
+ }
+ else if ( priv->CurrentOperaRate == 2 )
+ {
+ //2For 1 Mbps
+ if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
+// if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
+ {
+ bTryUp = true;
+ }
+ //printk("case12---1M \n");
+ }
+
+ if(bTryUp && bTryDown)
+ printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
+
+ //1 Test Upgrading Tx Rate
+ // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
+ // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
+ if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
+ && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
+ {
+ if(jiffies% (CurrRetryRate + 101) == 0)
+ {
+ bTryUp = true;
+ priv->bTryuping = true;
+ //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
+ }
+ }
+
+ //1 Rate Mechanism
+ if(bTryUp)
+ {
+ priv->TryupingCount++;
+ priv->TryDownCountLowData = 0;
+
+ {
+// printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
+// printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
+// TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
+// printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);
+
+ }
+
+ //
+ // Check more times if we need to upgrade indeed.
+ // Because the largest value of pHalData->TryupingCount is 0xFFFF and
+ // the largest value of pHalData->FailTxRateCount is 0x14,
+ // this condition will be satisfied at most every 2 min.
+ //
+
+ if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
+ (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
+ {
+ priv->TryupingCount = 0;
+ //
+ // When transfering from CCK to OFDM, DIG is an important issue.
+ //
+ if(priv->CurrentOperaRate == 22)
+ bUpdateInitialGain = true;
+
+ // The difference in throughput between 48Mbps and 36Mbps is 8M.
+ // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
+ //
+ if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
+ (priv->FailTxRateCount > 2) )
+ priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
+
+ // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
+ // (2)If the signal strength is increased, it may be able to upgrade.
+
+ priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
+// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
+
+ //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
+ if(priv->CurrentOperaRate ==36)
+ {
+ priv->bUpdateARFR=true;
+ write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
+// printk("UP: ARFR=0xF8F\n");
+ }
+ else if(priv->bUpdateARFR)
+ {
+ priv->bUpdateARFR=false;
+ write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
+// printk("UP: ARFR=0xFFF\n");
+ }
+
+ // Update Fail Tx rate and count.
+ if(priv->LastFailTxRate != priv->CurrentOperaRate)
+ {
+ priv->LastFailTxRate = priv->CurrentOperaRate;
+ priv->FailTxRateCount = 0;
+ priv->LastFailTxRateSS = -200; // Set lowest power.
+ }
+ }
+ }
+ else
+ {
+ if(priv->TryupingCount > 0)
+ priv->TryupingCount --;
+ }
+
+ if(bTryDown)
+ {
+ priv->TryDownCountLowData++;
+ priv->TryupingCount = 0;
+ {
+// printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
+// printk("DN: TryDownTh =%d\n", TryDownTh);
+// printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
+ }
+
+ //Check if Tx rate can be degraded or Test trying upgrading should fallback.
+ if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
+ {
+ priv->TryDownCountLowData = 0;
+ priv->bTryuping = false;
+ // Update fail information.
+ if(priv->LastFailTxRate == priv->CurrentOperaRate)
+ {
+ priv->FailTxRateCount ++;
+ // Record the Tx fail rate signal strength.
+ if(CurrSignalStrength > priv->LastFailTxRateSS)
+ {
+ priv->LastFailTxRateSS = CurrSignalStrength;
+ }
+ }
+ else
+ {
+ priv->LastFailTxRate = priv->CurrentOperaRate;
+ priv->FailTxRateCount = 1;
+ priv->LastFailTxRateSS = CurrSignalStrength;
+ }
+ priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
+
+ // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
+ //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
+ if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
+ {
+ priv->CurrentOperaRate = 72;
+// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
+ }
+
+ //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
+ if(priv->CurrentOperaRate ==36)
+ {
+ priv->bUpdateARFR=true;
+ write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
+// printk("DN: ARFR=0xF8F\n");
+ }
+ else if(priv->bUpdateARFR)
+ {
+ priv->bUpdateARFR=false;
+ write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
+// printk("DN: ARFR=0xFFF\n");
+ }
+
+ //
+ // When it is CCK rate, it may need to update initial gain to receive lower power packets.
+ //
+ if(MgntIsCckRate(priv->CurrentOperaRate))
+ {
+ bUpdateInitialGain = true;
+ }
+// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
+ }
+ }
+ else
+ {
+ if(priv->TryDownCountLowData > 0)
+ priv->TryDownCountLowData --;
+ }
+
+ // Keep the Tx fail rate count to equal to 0x15 at most.
+ // Reduce the fail count at least to 10 sec if tx rate is tending stable.
+ if(priv->FailTxRateCount >= 0x15 ||
+ (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
+ {
+ priv->FailTxRateCount --;
+ }
+
+
+ OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
+ CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
+
+ //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
+ if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
+ {
+ u1bCck = read_nic_byte(dev, CCK_TXAGC);
+ u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
+
+ // case 1: Never enter High power
+ if(u1bCck == CckTxPwrIdx )
+ {
+ if(u1bOfdm != (OfdmTxPwrIdx+2) )
+ {
+ priv->bEnhanceTxPwr= true;
+ u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
+ write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+// printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
+ }
+ }
+ // case 2: enter high power
+ else if(u1bCck < CckTxPwrIdx)
+ {
+ if(!priv->bEnhanceTxPwr)
+ {
+ priv->bEnhanceTxPwr= true;
+ u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
+ write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+ //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
+ }
+ }
+ }
+ else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
+ {
+ u1bCck = read_nic_byte(dev, CCK_TXAGC);
+ u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
+
+ // case 1: Never enter High power
+ if(u1bCck == CckTxPwrIdx )
+ {
+ priv->bEnhanceTxPwr= false;
+ write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
+ //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
+ }
+ // case 2: enter high power
+ else if(u1bCck < CckTxPwrIdx)
+ {
+ priv->bEnhanceTxPwr= false;
+ u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
+ write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
+ //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
+
+ }
+ }
+
+ //
+ // We need update initial gain when we set tx rate "from OFDM to CCK" or
+ // "from CCK to OFDM".
+ //
+SetInitialGain:
+ if(bUpdateInitialGain)
+ {
+ if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
+ {
+ if(priv->InitialGain > priv->RegBModeGainStage)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
+ {
+ //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
+ priv->InitialGain = priv->RegBModeGainStage;
+ }
+ else if(priv->InitialGain > priv->RegBModeGainStage + 1)
+ {
+ priv->InitialGain -= 2;
+ }
+ else
+ {
+ priv->InitialGain --;
+ }
+ printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+ UpdateInitialGain(dev);
+ }
+ }
+ else // OFDM
+ {
+ if(priv->InitialGain < 4)
+ {
+ priv->InitialGainBackUp= priv->InitialGain;
+
+ priv->InitialGain ++;
+ printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
+ UpdateInitialGain(dev);
+ }
+ }
+ }
+
+ //Record the related info
+ priv->LastRetryRate = CurrRetryRate;
+ priv->LastTxThroughput = TxThroughput;
+ priv->ieee80211->rate = priv->CurrentOperaRate * 5;
+}
+
+#endif
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work)
+{
+ struct delayed_work *dwork = container_of(work,struct delayed_work,work);
+ struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
+ struct net_device *dev = ieee->dev;
+#else
+void rtl8180_rate_adapter(struct net_device *dev)
+{
+
+#endif
+ //struct r8180_priv *priv = ieee80211_priv(dev);
+// DMESG("---->rtl8180_rate_adapter");
+ StaRateAdaptive87SE(dev);
+// DMESG("<----rtl8180_rate_adapter");
+}
+void timer_rate_adaptive(unsigned long data)
+{
+ struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
+ //DMESG("---->timer_rate_adaptive()\n");
+ if(!priv->up)
+ {
+// DMESG("<----timer_rate_adaptive():driver is not up!\n");
+ return;
+ }
+ if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
+ && (priv->ieee80211->state == IEEE80211_LINKED) &&
+ (priv->ForcedDataRate == 0) )
+ {
+// DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
+#ifdef CONFIG_RTL818X_S
+ queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
+// StaRateAdaptive87SE((struct net_device *)data);
+#endif
+ }
+ priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
+ add_timer(&priv->rateadapter_timer);
+ //DMESG("<----timer_rate_adaptive()\n");
+}
+//by amy 080312}
+void
+SwAntennaDiversityRxOk8185(
+ struct net_device *dev,
+ u8 SignalStrength
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
+
+ priv->AdRxOkCnt++;
+
+ if( priv->AdRxSignalStrength != -1)
+ {
+ priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
+ }
+ else
+ { // Initialization case.
+ priv->AdRxSignalStrength = SignalStrength;
+ }
+//{+by amy 080312
+ if( priv->LastRxPktAntenna ) //Main antenna.
+ priv->AdMainAntennaRxOkCnt++;
+ else // Aux antenna.
+ priv->AdAuxAntennaRxOkCnt++;
+//+by amy 080312
+// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
+}
+//
+// Description:
+// Change Antenna Switch.
+//
+bool
+SetAntenna8185(
+ struct net_device *dev,
+ u8 u1bAntennaIndex
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ bool bAntennaSwitched = false;
+
+// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
+
+ switch(u1bAntennaIndex)
+ {
+ case 0:
+ switch(priv->rf_chip)
+ {
+ case RF_ZEBRA2:
+ case RF_ZEBRA4:
+#ifdef CONFIG_RTL8185B
+#ifdef CONFIG_RTL818X_S
+ // Mac register, main antenna
+ write_nic_byte(dev, ANTSEL, 0x03);
+ //base band
+ write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
+
+#else
+ // Mac register, main antenna
+ write_nic_byte(dev, ANTSEL, 0x03);
+ //base band
+ write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
+#endif
+#endif
+
+ bAntennaSwitched = true;
+ break;
+
+ default:
+ printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+ break;
+ }
+ break;
+
+ case 1:
+ switch(priv->rf_chip)
+ {
+ case RF_ZEBRA2:
+ case RF_ZEBRA4:
+#ifdef CONFIG_RTL8185B
+#ifdef CONFIG_RTL818X_S
+ // Mac register, aux antenna
+ write_nic_byte(dev, ANTSEL, 0x00);
+ //base band
+ write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
+#else
+ // Mac register, aux antenna
+ write_nic_byte(dev, ANTSEL, 0x00);
+ //base band
+ write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
+ write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
+#endif
+#endif
+
+ bAntennaSwitched = true;
+ break;
+
+ default:
+ printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
+ break;
+ }
+ break;
+
+ default:
+ printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
+ break;
+ }
+
+ if(bAntennaSwitched)
+ {
+ priv->CurrAntennaIndex = u1bAntennaIndex;
+ }
+
+// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
+
+ return bAntennaSwitched;
+}
+//
+// Description:
+// Toggle Antenna switch.
+//
+bool
+SwitchAntenna(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+ bool bResult;
+
+ if(priv->CurrAntennaIndex == 0)
+ {
+#if 0//lzm del 080826
+//by amy 080312
+#ifdef CONFIG_RTL818X_S
+ if(priv->bSwAntennaDiverity)
+ bResult = SetAntennaConfig87SE(dev, 1, true);
+ else
+#endif
+#endif
+ bResult = SetAntenna8185(dev, 1);
+//by amy 080312
+// printk("SwitchAntenna(): switching to antenna 1 ......\n");
+// bResult = SetAntenna8185(dev, 1);//-by amy 080312
+ }
+ else
+ {
+#if 0//lzm del 080826
+//by amy 080312
+#ifdef CONFIG_RTL818X_S
+ if(priv->bSwAntennaDiverity)
+ bResult = SetAntennaConfig87SE(dev, 0, true);
+ else
+#endif
+#endif
+ bResult = SetAntenna8185(dev, 0);
+//by amy 080312
+// printk("SwitchAntenna(): switching to antenna 0 ......\n");
+// bResult = SetAntenna8185(dev, 0);//-by amy 080312
+ }
+
+ return bResult;
+}
+//
+// Description:
+// Engine of SW Antenna Diversity mechanism.
+// Since 8187 has no Tx part information,
+// this implementation is only dependend on Rx part information.
+//
+// 2006.04.17, by rcnjko.
+//
+void
+SwAntennaDiversity(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ bool bSwCheckSS=false;
+// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
+// printk("AdTickCount is %d\n",priv->AdTickCount);
+//by amy 080312
+ if(bSwCheckSS)
+ {
+ priv->AdTickCount++;
+
+ printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
+ priv->AdTickCount, priv->AdCheckPeriod);
+ printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
+ priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+ }
+// priv->AdTickCount++;//-by amy 080312
+
+ // Case 1. No Link.
+ if(priv->ieee80211->state != IEEE80211_LINKED)
+ {
+ // printk("SwAntennaDiversity(): Case 1. No Link.\n");
+
+ priv->bAdSwitchedChecking = false;
+ // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
+ SwitchAntenna(dev);
+ }
+ // Case 2. Linked but no packet received.
+ else if(priv->AdRxOkCnt == 0)
+ {
+ // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
+
+ priv->bAdSwitchedChecking = false;
+ SwitchAntenna(dev);
+ }
+ // Case 3. Evaluate last antenna switch action and undo it if necessary.
+ else if(priv->bAdSwitchedChecking == true)
+ {
+ // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
+
+ priv->bAdSwitchedChecking = false;
+
+ // Adjust Rx signal strength threashold.
+ priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
+
+ priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
+ priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
+ if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
+ { // Rx signal strength is not improved after we swtiched antenna. => Swich back.
+// printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
+//by amy 080312
+ // Increase Antenna Diversity checking period due to bad decision.
+ priv->AdCheckPeriod *= 2;
+//by amy 080312
+ // Increase Antenna Diversity checking period.
+ if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
+ priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
+
+ // Wrong deceision => switch back.
+ SwitchAntenna(dev);
+ }
+ else
+ { // Rx Signal Strength is improved.
+// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
+
+ // Reset Antenna Diversity checking period to its min value.
+ priv->AdCheckPeriod = priv->AdMinCheckPeriod;
+ }
+
+// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
+// priv->AdRxSsThreshold, priv->AdCheckPeriod);
+ }
+ // Case 4. Evaluate if we shall switch antenna now.
+ // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
+ else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
+ {
+// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
+
+ priv->AdTickCount = 0;
+
+ //
+ // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
+ // evaluate signal strength.
+ // The following operation can overcome the disability of CCA on both two antennas
+ // When signal strength was extremely low or high.
+ // 2008.01.30.
+ //
+
+ //
+ // Evaluate RxOk count from each antenna if we shall switch default antenna now.
+ // Added by Roger, 2008.02.21.
+//{by amy 080312
+ if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
+ && (priv->CurrAntennaIndex == 0))
+ { // We set Main antenna as default but RxOk count was less than Aux ones.
+
+ // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+ // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+ // Switch to Aux antenna.
+ SwitchAntenna(dev);
+ priv->bHWAdSwitched = true;
+ }
+ else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
+ && (priv->CurrAntennaIndex == 1))
+ { // We set Aux antenna as default but RxOk count was less than Main ones.
+
+ // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+ // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+ // Switch to Main antenna.
+ SwitchAntenna(dev);
+ priv->bHWAdSwitched = true;
+ }
+ else
+ {// Default antenna is better.
+
+ // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
+ // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
+
+ // Still need to check current signal strength.
+ priv->bHWAdSwitched = false;
+ }
+ //
+ // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
+ // didn't changed by HW evaluation.
+ // 2008.02.27.
+ //
+ // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
+ // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
+ // but AdRxSignalStrength is less than main.
+ // Our guess is that main antenna have lower throughput and get many change
+ // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
+ //
+ if( (!priv->bHWAdSwitched) && (bSwCheckSS))
+ {
+//by amy 080312}
+ // Evaluate Rx signal strength if we shall switch antenna now.
+ if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
+ { // Rx signal strength is weak => Switch Antenna.
+// printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+
+ priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
+ priv->bAdSwitchedChecking = true;
+
+ SwitchAntenna(dev);
+ }
+ else
+ { // Rx signal strength is OK.
+// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
+// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
+
+ priv->bAdSwitchedChecking = false;
+ // Increase Rx signal strength threashold if necessary.
+ if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
+ priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
+ {
+ priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
+ priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
+ priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
+ }
+
+ // Reduce Antenna Diversity checking period if possible.
+ if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
+ {
+ priv->AdCheckPeriod /= 2;
+ }
+ }
+ }
+ }
+//by amy 080312
+ // Reset antenna diversity Rx related statistics.
+ priv->AdRxOkCnt = 0;
+ priv->AdMainAntennaRxOkCnt = 0;
+ priv->AdAuxAntennaRxOkCnt = 0;
+//by amy 080312
+
+// priv->AdRxOkCnt = 0;//-by amy 080312
+
+// printk("-SwAntennaDiversity()\n");
+}
+
+//
+// Description:
+// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
+//
+bool
+CheckTxPwrTracking( struct net_device *dev)
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+
+ if(!priv->bTxPowerTrack)
+ {
+ return false;
+ }
+
+//lzm reserved 080826
+ //if(priv->bScanInProgress)
+ //{
+ // return false;
+ //}
+
+ //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
+ if(priv->bToUpdateTxPwr)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+//
+// Description:
+// Timer callback function of SW Antenna Diversity.
+//
+void
+SwAntennaDiversityTimerCallback(
+ struct net_device *dev
+ )
+{
+ struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
+ RT_RF_POWER_STATE rtState;
+
+ //printk("+SwAntennaDiversityTimerCallback()\n");
+
+ //
+ // We do NOT need to switch antenna while RF is off.
+ // 2007.05.09, added by Roger.
+ //
+ rtState = priv->eRFPowerState;
+ do{
+ if (rtState == eRfOff)
+ {
+// printk("SwAntennaDiversityTimer - RF is OFF.\n");
+ break;
+ }
+ else if (rtState == eRfSleep)
+ {
+ // Don't access BB/RF under Disable PLL situation.
+ //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
+ break;
+ }
+ SwAntennaDiversity(dev);
+
+ }while(false);
+
+ if(priv->up)
+ {
+ priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
+ add_timer(&priv->SwAntennaDiversityTimer);
+ }
+
+ //printk("-SwAntennaDiversityTimerCallback()\n");
+}
+
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
index 3de92f040f9..b2736c8e521 100644
--- a/drivers/staging/rtl8187se/r8180_dm.h
+++ b/drivers/staging/rtl8187se/r8180_dm.h
@@ -1,41 +1,41 @@
-#ifndef R8180_DM_H
-#define R8180_DM_H
-
-#include "r8180.h"
-//#include "r8180_hw.h"
-//#include "r8180_93cx6.h"
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
-bool SwitchAntenna( struct net_device *dev);
-void SwAntennaDiversity(struct net_device *dev );
-void SwAntennaDiversityTimerCallback(struct net_device *dev);
-bool CheckDig(struct net_device *dev);
-bool CheckHighPower(struct net_device *dev);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_hw_dig_wq (struct work_struct *work);
-#else
-void rtl8180_hw_dig_wq(struct net_device *dev);
-#endif
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
-void rtl8180_tx_pw_wq (struct work_struct *work);
-#else
-void rtl8180_tx_pw_wq(struct net_device *dev);
-#endif
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
-void rtl8180_rate_adapter(struct work_struct * work);
-
-#else
-void rtl8180_rate_adapter(struct net_device *dev);
-
-#endif
-void TxPwrTracking87SE(struct net_device *dev);
-bool CheckTxPwrTracking(struct net_device *dev);
-#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
-void rtl8180_rate_adapter(struct work_struct * work);
-#else
-void rtl8180_rate_adapter(struct net_device *dev);
-#endif
-void timer_rate_adaptive(unsigned long data);
-
-
-#endif
+#ifndef R8180_DM_H
+#define R8180_DM_H
+
+#include "r8180.h"
+//#include "r8180_hw.h"
+//#include "r8180_93cx6.h"
+void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
+bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
+bool SwitchAntenna( struct net_device *dev);
+void SwAntennaDiversity(struct net_device *dev );
+void SwAntennaDiversityTimerCallback(struct net_device *dev);
+bool CheckDig(struct net_device *dev);
+bool CheckHighPower(struct net_device *dev);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_hw_dig_wq (struct work_struct *work);
+#else
+void rtl8180_hw_dig_wq(struct net_device *dev);
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
+void rtl8180_tx_pw_wq (struct work_struct *work);
+#else
+void rtl8180_tx_pw_wq(struct net_device *dev);
+#endif
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work);
+
+#else
+void rtl8180_rate_adapter(struct net_device *dev);
+
+#endif
+void TxPwrTracking87SE(struct net_device *dev);
+bool CheckTxPwrTracking(struct net_device *dev);
+#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
+void rtl8180_rate_adapter(struct work_struct * work);
+#else
+void rtl8180_rate_adapter(struct net_device *dev);
+#endif
+void timer_rate_adaptive(unsigned long data);
+
+
+#endif
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
index 8b3901d87f8..979ba0b5f33 100644
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ b/drivers/staging/rtl8187se/r8180_wx.c
@@ -1274,8 +1274,8 @@ static int r8180_wx_set_enc_ext(struct net_device *dev,
}
static int r8180_wx_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_param *data, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
//printk("====>%s()\n", __func__);
struct r8180_priv *priv = ieee80211_priv(dev);
@@ -1285,7 +1285,7 @@ static int r8180_wx_set_auth(struct net_device *dev,
return 0;
down(&priv->wx_sem);
- ret = ieee80211_wx_set_auth(priv->ieee80211, info, data, extra);
+ ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
up(&priv->wx_sem);
return ret;
}
@@ -1312,8 +1312,8 @@ static int r8180_wx_set_mlme(struct net_device *dev,
return ret;
}
static int r8180_wx_set_gen_ie(struct net_device *dev,
- struct iw_request_info *info,
- struct iw_point *data, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
// printk("====>%s(), len:%d\n", __func__, data->length);
int ret=0;
@@ -1325,7 +1325,7 @@ static int r8180_wx_set_gen_ie(struct net_device *dev,
down(&priv->wx_sem);
#if 1
- ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->length);
+ ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
#endif
up(&priv->wx_sem);
//printk("<======%s(), ret:%d\n", __func__, ret);
diff --git a/drivers/staging/serqt_usb/Kconfig b/drivers/staging/serqt_usb/Kconfig
new file mode 100644
index 00000000000..cc1af5df40d
--- /dev/null
+++ b/drivers/staging/serqt_usb/Kconfig
@@ -0,0 +1,9 @@
+config USB_SERIAL_QUATECH_ESU100
+ tristate "USB Quatech ESU-100 8 Port Serial Driver"
+ depends on USB_SERIAL
+ help
+ Say Y here if you want to use the Quatech ESU-100 8 port usb to
+ serial adapter.
+
+ To compile this driver as a module, choose M here: the
+ module will be called serqt_usb.
diff --git a/drivers/staging/serqt_usb/Makefile b/drivers/staging/serqt_usb/Makefile
new file mode 100644
index 00000000000..4fd1da275e8
--- /dev/null
+++ b/drivers/staging/serqt_usb/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SERIAL_QUATECH_ESU100) += serqt_usb.o
diff --git a/drivers/staging/serqt_usb/TODO b/drivers/staging/serqt_usb/TODO
new file mode 100644
index 00000000000..34ecca8992d
--- /dev/null
+++ b/drivers/staging/serqt_usb/TODO
@@ -0,0 +1,8 @@
+Things to do for this driver to get merged into the main portion of the
+kernel:
+ - checkpatch cleanups
+ - sparse clean
+ - port to the usb-serial layer instead of doing it all on its
+ own.
+
+Send patches to Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/serqt_usb/serqt_usb.c b/drivers/staging/serqt_usb/serqt_usb.c
new file mode 100644
index 00000000000..1781510c53f
--- /dev/null
+++ b/drivers/staging/serqt_usb/serqt_usb.c
@@ -0,0 +1,2779 @@
+/*
+ * This code was developed for the Quatech USB line for linux, it used
+ * much of the code developed by Greg Kroah-Hartman for USB serial devices
+ *
+ */
+
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+#include <linux/wait.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <linux/uaccess.h>
+
+/* Use our own dbg macro */
+/* #define DEBUG_ON */
+/* #undef dbg */
+#ifdef DEBUG_ON
+#define mydbg(const...) printk(const)
+#else
+#define mydbg(const...)
+#endif
+
+/* parity check flag */
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+#define SERIAL_TTY_MAJOR 0 /* Nice legal number now */
+#define SERIAL_TTY_MINORS 255 /* loads of devices :) */
+#define MAX_NUM_PORTS 8 /* The maximum number of ports one device can grab at once */
+#define PREFUFF_LEVEL_CONSERVATIVE 128
+#define ATC_DISABLED 0x00
+
+#define RR_BITS 0x03 /* for clearing clock bits */
+#define DUPMODE_BITS 0xc0
+
+#define RS232_MODE 0x00
+#define RTSCTS_TO_CONNECTOR 0x40
+#define CLKS_X4 0x02
+
+#define LOOPMODE_BITS 0x41 /* LOOP1 = b6, LOOP0 = b0 (PORT B) */
+#define ALL_LOOPBACK 0x01
+#define MODEM_CTRL 0x40
+
+#define THISCHAR data[i]
+#define NEXTCHAR data[i + 1]
+#define THIRDCHAR data[i + 2]
+#define FOURTHCHAR data[i + 3]
+
+/*
+ * Useful defintions for port A, Port B and Port C
+ */
+#define FULLPWRBIT 0x00000080
+#define NEXT_BOARD_POWER_BIT 0x00000004
+
+#define SERIAL_LSR_OE 0x02
+#define SERIAL_LSR_PE 0x04
+#define SERIAL_LSR_FE 0x08
+#define SERIAL_LSR_BI 0x10
+
+#define SERIAL_LSR_TEMT 0x40
+
+#define DIV_LATCH_LS 0x00
+#define XMT_HOLD_REGISTER 0x00
+#define XVR_BUFFER_REGISTER 0x00
+#define DIV_LATCH_MS 0x01
+#define FIFO_CONTROL_REGISTER 0x02
+#define LINE_CONTROL_REGISTER 0x03
+#define MODEM_CONTROL_REGISTER 0x04
+#define LINE_STATUS_REGISTER 0x05
+#define MODEM_STATUS_REGISTER 0x06
+
+#define SERIAL_MCR_DTR 0x01
+#define SERIAL_MCR_RTS 0x02
+#define SERIAL_MCR_LOOP 0x10
+
+#define SERIAL_MSR_CTS 0x10
+#define SERIAL_MSR_CD 0x80
+#define SERIAL_MSR_RI 0x40
+#define SERIAL_MSR_DSR 0x20
+#define SERIAL_MSR_MASK 0xf0
+
+#define SERIAL_8_DATA 0x03
+#define SERIAL_7_DATA 0x02
+#define SERIAL_6_DATA 0x01
+#define SERIAL_5_DATA 0x00
+
+#define SERIAL_ODD_PARITY 0X08
+#define SERIAL_EVEN_PARITY 0X18
+#define SERIAL_TWO_STOPB 0x04
+#define SERIAL_ONE_STOPB 0x00
+
+#define MAX_BAUD_RATE 460800
+#define MAX_BAUD_REMAINDER 4608
+
+#define QT_SET_GET_DEVICE 0xc2
+#define QT_OPEN_CLOSE_CHANNEL 0xca
+#define QT_GET_SET_PREBUF_TRIG_LVL 0xcc
+#define QT_SET_ATF 0xcd
+#define QT_GET_SET_REGISTER 0xc0
+#define QT_GET_SET_UART 0xc1
+#define QT_HW_FLOW_CONTROL_MASK 0xc5
+#define QT_SW_FLOW_CONTROL_MASK 0xc6
+#define QT_SW_FLOW_CONTROL_DISABLE 0xc7
+#define QT_BREAK_CONTROL 0xc8
+
+#define SERIALQT_PCI_IOC_MAGIC 'k'
+#define SERIALQT_WRITE_QOPR _IOW(SERIALQT_PCI_IOC_MAGIC, 0, int)
+#define SERIALQT_WRITE_QMCR _IOW(SERIALQT_PCI_IOC_MAGIC, 1, int)
+#define SERIALQT_GET_NUMOF_UNITS _IOR(SERIALQT_PCI_IOC_MAGIC, 2, void *)
+#define SERIALQT_GET_THIS_UNIT _IOR(SERIALQT_PCI_IOC_MAGIC, 3, void *)
+#define SERIALQT_READ_QOPR _IOR(SERIALQT_PCI_IOC_MAGIC, 4, int)
+#define SERIALQT_READ_QMCR _IOR(SERIALQT_PCI_IOC_MAGIC, 5, int)
+#define SERIALQT_IS422_EXTENDED _IOR(SERIALQT_PCI_IOC_MAGIC, 6, int) /* returns successful if 422 extended */
+
+#define USBD_TRANSFER_DIRECTION_IN 0xc0
+#define USBD_TRANSFER_DIRECTION_OUT 0x40
+
+#define ATC_DISABLED 0x00
+#define ATC_RTS_ENABLED 0x02
+#define ATC_DTR_ENABLED 0x01
+
+#define RR_BITS 0x03 /* for clearing clock bits */
+#define DUPMODE_BITS 0xc0
+
+#define FULL_DUPLEX 0x00
+#define HALF_DUPLEX_RTS 0x40
+#define HALF_DUPLEX_DTR 0x80
+
+#define QMCR_FULL_DUPLEX 0x00
+#define QMCR_HALF_DUPLEX_RTS 0x02
+#define QMCR_HALF_DUPLEX_DTR 0x01
+#define QMCR_HALF_DUPLEX_MASK 0x03
+#define QMCR_CONNECTOR_MASK 0x1C
+
+#define QMCR_RX_EN_MASK 0x20
+
+#define QMCR_ALL_LOOPBACK 0x10
+#define QMCR_MODEM_CONTROL 0X00
+
+#define SERIALQT_IOC_MAXNR 6
+
+struct usb_serial_port {
+ struct usb_serial *serial; /* pointer back to the owner of this port */
+ struct tty_struct *tty; /* the coresponding tty for this port */
+ unsigned char number;
+ char active; /* someone has this device open */
+
+ unsigned char *interrupt_in_buffer;
+ struct urb *interrupt_in_urb;
+ __u8 interrupt_in_endpointAddress;
+
+ unsigned char *bulk_in_buffer;
+ unsigned char *xfer_to_tty_buffer;
+ struct urb *read_urb;
+ __u8 bulk_in_endpointAddress;
+
+ unsigned char *bulk_out_buffer;
+ int bulk_out_size;
+ struct urb *write_urb;
+ __u8 bulk_out_endpointAddress;
+
+ wait_queue_head_t write_wait;
+ wait_queue_head_t wait;
+ struct work_struct work;
+
+ int open_count; /* number of times this port has been opened */
+ struct semaphore sem; /* locks this structure */
+
+ __u8 shadowLCR; /* last LCR value received */
+ __u8 shadowMCR; /* last MCR value received */
+ __u8 shadowMSR; /* last MSR value received */
+ __u8 shadowLSR; /* last LSR value received */
+ int RxHolding;
+ char closePending;
+ int ReadBulkStopped;
+
+ void *private; /* data private to the specific port */
+};
+
+struct identity {
+ int index;
+ int n_identity;
+};
+
+struct usb_serial {
+ struct usb_device *dev;
+ struct usb_interface *interface; /* the interface for this device */
+ struct tty_driver *tty_driver; /* the tty_driver for this device */
+ unsigned char minor; /* the starting minor number for this device */
+ unsigned char num_ports; /* the number of ports this device has */
+ char num_interrupt_in; /* number of interrupt in endpoints we have */
+ char num_bulk_in; /* number of bulk in endpoints we have */
+ char num_bulk_out; /* number of bulk out endpoints we have */
+ unsigned char num_OpenCount; /* the number of ports this device has */
+
+ __u16 vendor; /* vendor id of this device */
+ __u16 product; /* product id of this device */
+ struct usb_serial_port port[MAX_NUM_PORTS];
+
+ void *private; /* data private to the specific driver */
+};
+
+static inline int port_paranoia_check(struct usb_serial_port *port,
+ const char *function)
+{
+ if (!port) {
+ dbg("%s - port == NULL", function);
+ return -1;
+ }
+ if (!port->serial) {
+ dbg("%s - port->serial == NULL\n", function);
+ return -1;
+ }
+ if (!port->tty) {
+ dbg("%s - port->tty == NULL\n", function);
+ return -1;
+ }
+
+ return 0;
+}
+
+/* Inline functions to check the sanity of a pointer that is passed to us */
+static inline int serial_paranoia_check(struct usb_serial *serial,
+ const char *function)
+{
+ if (!serial) {
+ dbg("%s - serial == NULL\n", function);
+ return -1;
+ }
+
+ return 0;
+}
+
+static inline struct usb_serial *get_usb_serial(struct usb_serial_port *port,
+ const char *function)
+{
+ /* if no port was specified, or it fails a paranoia check */
+ if (!port ||
+ port_paranoia_check(port, function) ||
+ serial_paranoia_check(port->serial, function)) {
+ /* then say that we dont have a valid usb_serial thing, which will
+ * end up genrating -ENODEV return values */
+ return NULL;
+ }
+
+ return port->serial;
+}
+
+struct qt_get_device_data {
+ __u8 porta;
+ __u8 portb;
+ __u8 portc;
+};
+
+struct qt_open_channel_data {
+ __u8 line_status;
+ __u8 modem_status;
+};
+
+static void ProcessLineStatus(struct usb_serial_port *port,
+ unsigned char line_status);
+static void ProcessModemStatus(struct usb_serial_port *port,
+ unsigned char modem_status);
+static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data);
+static struct usb_serial *get_free_serial(int num_ports, int *minor);
+
+static int serqt_probe(struct usb_interface *interface,
+ const struct usb_device_id *id);
+
+static void serqt_usb_disconnect(struct usb_interface *interface);
+static int box_set_device(struct usb_serial *serial,
+ struct qt_get_device_data *pDeviceData);
+static int box_get_device(struct usb_serial *serial,
+ struct qt_get_device_data *pDeviceData);
+static int serial_open(struct tty_struct *tty, struct file *filp);
+static void serial_close(struct tty_struct *tty, struct file *filp);
+static int serial_write_room(struct tty_struct *tty);
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old);
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+ int count);
+
+static void serial_throttle(struct tty_struct *tty);
+static void serial_unthrottle(struct tty_struct *tty);
+static int serial_break(struct tty_struct *tty, int break_state);
+static int serial_chars_in_buffer(struct tty_struct *tty);
+
+static int qt_open(struct usb_serial_port *port, struct file *filp);
+static int BoxSetPrebufferLevel(struct usb_serial *serial);
+
+static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode);
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short default_divisor,
+ unsigned char default_LCR);
+
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
+ __u16 OpenClose,
+ struct qt_open_channel_data *pDeviceData);
+static void qt_close(struct usb_serial_port *port, struct file *filp);
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, __u8 *pValue);
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, unsigned short Value);
+static void qt_write_bulk_callback(struct urb *urb);
+static int qt_write(struct usb_serial_port *port, int from_user,
+ const unsigned char *buf, int count);
+static void port_softint(struct work_struct *work);
+static int qt_write_room(struct usb_serial_port *port);
+static int qt_chars_in_buffer(struct usb_serial_port *port);
+static int qt_ioctl(struct usb_serial_port *port, struct file *file,
+ unsigned int cmd, unsigned long arg);
+static void qt_set_termios(struct usb_serial_port *port,
+ struct ktermios *old_termios);
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber,
+ int bSet);
+static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber);
+static int EmulateWriteQMCR_Reg(int index, unsigned uc_value);
+static int EmulateReadQMCR_Reg(int index, unsigned *uc_value);
+static struct usb_serial *find_the_box(unsigned int index);
+static int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
+ unsigned long arg);
+
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 Uart,
+ unsigned char stop_char, unsigned char start_char);
+static void qt_read_bulk_callback(struct urb *urb);
+
+static void port_sofrint(void *private);
+
+static void return_serial(struct usb_serial *serial);
+
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear);
+static int serial_tiocmget(struct tty_struct *tty, struct file *file);
+
+static int qt_tiocmset(struct usb_serial_port *port, struct file *file,
+ unsigned int value);
+
+static int qt_tiocmget(struct usb_serial_port *port, struct file *file);
+
+/* Version Information */
+#define DRIVER_VERSION "v2.14"
+#define DRIVER_AUTHOR "Tim Gobeli, Quatech, Inc"
+#define DRIVER_DESC "Quatech USB to Serial Driver"
+
+#define USB_VENDOR_ID_QUATECH 0x061d /* Quatech VID */
+#define DEVICE_ID_QUATECH_RS232_SINGLE_PORT 0xC020 /* SSU100 */
+#define DEVICE_ID_QUATECH_RS422_SINGLE_PORT 0xC030 /* SSU200 */
+#define DEVICE_ID_QUATECH_RS232_DUAL_PORT 0xC040 /* DSU100 */
+#define DEVICE_ID_QUATECH_RS422_DUAL_PORT 0xC050 /* DSU200 */
+#define DEVICE_ID_QUATECH_RS232_FOUR_PORT 0xC060 /* QSU100 */
+#define DEVICE_ID_QUATECH_RS422_FOUR_PORT 0xC070 /* QSU200 */
+#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A 0xC080 /* ESU100A */
+#define DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B 0xC081 /* ESU100B */
+#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A 0xC0A0 /* ESU200A */
+#define DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B 0xC0A1 /* ESU200B */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_A 0xC090 /* HSU100A */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_B 0xC091 /* HSU100B */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_C 0xC092 /* HSU100C */
+#define DEVICE_ID_QUATECH_RS232_16_PORT_D 0xC093 /* HSU100D */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_A 0xC0B0 /* HSU200A */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_B 0xC0B1 /* HSU200B */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_C 0xC0B2 /* HSU200C */
+#define DEVICE_ID_QUATECH_RS422_16_PORT_D 0xC0B3 /* HSU200D */
+
+/* table of Quatech devices */
+static struct usb_device_id serqt_table[] = {
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_SINGLE_PORT)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_SINGLE_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_DUAL_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_DUAL_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_FOUR_PORT)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_FOUR_PORT)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A)},
+ {USB_DEVICE
+ (USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_A)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_B)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_C)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS232_16_PORT_D)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_A)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_B)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_C)},
+ {USB_DEVICE(USB_VENDOR_ID_QUATECH, DEVICE_ID_QUATECH_RS422_16_PORT_D)},
+ {} /* Terminating entry */
+};
+
+MODULE_DEVICE_TABLE(usb, serqt_table);
+
+static int major_number;
+static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */
+
+/* table of Quatech 422devices */
+static unsigned int serqt_422_table[] = {
+ DEVICE_ID_QUATECH_RS422_SINGLE_PORT,
+ DEVICE_ID_QUATECH_RS422_DUAL_PORT,
+ DEVICE_ID_QUATECH_RS422_FOUR_PORT,
+ DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A,
+ DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B,
+ DEVICE_ID_QUATECH_RS422_16_PORT_A,
+ DEVICE_ID_QUATECH_RS422_16_PORT_B,
+ DEVICE_ID_QUATECH_RS422_16_PORT_C,
+ DEVICE_ID_QUATECH_RS422_16_PORT_D,
+ 0 /* terminate with zero */
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver serqt_usb_driver = {
+ .name = "quatech-usb-serial",
+ .probe = serqt_probe,
+ .disconnect = serqt_usb_disconnect,
+ .id_table = serqt_table,
+};
+
+static struct ktermios *serial_termios[SERIAL_TTY_MINORS];
+static struct ktermios *serial_termios_locked[SERIAL_TTY_MINORS];
+
+static const struct tty_operations serial_ops = {
+ .open = serial_open,
+ .close = serial_close,
+ .write = serial_write,
+ .write_room = serial_write_room,
+ .ioctl = serial_ioctl,
+ .set_termios = serial_set_termios,
+ .throttle = serial_throttle,
+ .unthrottle = serial_unthrottle,
+ .break_ctl = serial_break,
+ .chars_in_buffer = serial_chars_in_buffer,
+ .tiocmset = serial_tiocmset,
+ .tiocmget = serial_tiocmget,
+};
+
+static struct tty_driver serial_tty_driver = {
+ .magic = TTY_DRIVER_MAGIC,
+ .driver_name = "Quatech usb-serial",
+ .name = "ttyQT_USB",
+ .major = SERIAL_TTY_MAJOR,
+ .minor_start = 0,
+ .num = SERIAL_TTY_MINORS,
+ .type = TTY_DRIVER_TYPE_SERIAL,
+ .subtype = SERIAL_TYPE_NORMAL,
+ .flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
+
+ .termios = serial_termios,
+ .termios_locked = serial_termios_locked,
+ .init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL,
+
+ .init_termios.c_iflag = ICRNL | IXON,
+ .init_termios.c_oflag = OPOST,
+
+ .init_termios.c_lflag =
+ ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN,
+};
+
+/* fops for parent device */
+static const struct file_operations serialqt_usb_fops = {
+ .ioctl = ioctl_serial_usb,
+};
+
+ /**
+ * serqt_probe
+ *
+ * Called by the usb core when a new device is connected that it thinks
+ * this driver might be interested in.
+ *
+ */
+static int serqt_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ struct usb_device *dev = interface_to_usbdev(interface);
+ struct usb_serial *serial = NULL;
+ struct usb_serial_port *port;
+ struct usb_endpoint_descriptor *endpoint;
+ struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
+ struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
+ struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
+ int minor;
+ int buffer_size;
+ int i;
+ struct usb_host_interface *iface_desc;
+ int num_interrupt_in = 0;
+ int num_bulk_in = 0;
+ int num_bulk_out = 0;
+ int num_ports;
+ struct qt_get_device_data DeviceData;
+ int status;
+
+ mydbg("In %s\n", __func__);
+
+ /* let's find the endpoints needed */
+ /* check out the endpoints */
+ iface_desc = interface->cur_altsetting;;
+ for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+ endpoint = &iface_desc->endpoint[i].desc;
+
+ if ((endpoint->bEndpointAddress & 0x80) &&
+ ((endpoint->bmAttributes & 3) == 0x02)) {
+ /* we found a bulk in endpoint */
+ mydbg("found bulk in");
+ bulk_in_endpoint[num_bulk_in] = endpoint;
+ ++num_bulk_in;
+ }
+
+ if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
+ ((endpoint->bmAttributes & 3) == 0x02)) {
+ /* we found a bulk out endpoint */
+ mydbg("found bulk out\n");
+ bulk_out_endpoint[num_bulk_out] = endpoint;
+ ++num_bulk_out;
+ }
+
+ if ((endpoint->bEndpointAddress & 0x80) &&
+ ((endpoint->bmAttributes & 3) == 0x03)) {
+ /* we found a interrupt in endpoint */
+ mydbg("found interrupt in\n");
+ interrupt_in_endpoint[num_interrupt_in] = endpoint;
+ ++num_interrupt_in;
+ }
+ }
+
+ /* found all that we need */
+ dev_info(&interface->dev, "Quatech converter detected\n");
+ num_ports = num_bulk_out;
+ if (num_ports == 0) {
+ err("Quatech device with no bulk out, not allowed.");
+ return -ENODEV;
+
+ }
+
+ serial = get_free_serial(num_ports, &minor);
+ if (serial == NULL) {
+ err("No more free serial devices");
+ return -ENODEV;
+ }
+
+ serial->dev = dev;
+ serial->interface = interface;
+ serial->minor = minor;
+ serial->num_ports = num_ports;
+ serial->num_bulk_in = num_bulk_in;
+ serial->num_bulk_out = num_bulk_out;
+ serial->num_interrupt_in = num_interrupt_in;
+ serial->vendor = dev->descriptor.idVendor;
+ serial->product = dev->descriptor.idProduct;
+
+ /* set up the endpoint information */
+ for (i = 0; i < num_bulk_in; ++i) {
+ endpoint = bulk_in_endpoint[i];
+ port = &serial->port[i];
+ port->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!port->read_urb) {
+ err("No free urbs available");
+ goto probe_error;
+ }
+ buffer_size = endpoint->wMaxPacketSize;
+ port->bulk_in_endpointAddress = endpoint->bEndpointAddress;
+ port->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ port->xfer_to_tty_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!port->bulk_in_buffer) {
+ err("Couldn't allocate bulk_in_buffer");
+ goto probe_error;
+ }
+ usb_fill_bulk_urb(port->read_urb, dev,
+ usb_rcvbulkpipe(dev,
+ endpoint->bEndpointAddress),
+ port->bulk_in_buffer, buffer_size,
+ qt_read_bulk_callback, port);
+ }
+
+ for (i = 0; i < num_bulk_out; ++i) {
+ endpoint = bulk_out_endpoint[i];
+ port = &serial->port[i];
+ port->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!port->write_urb) {
+ err("No free urbs available");
+ goto probe_error;
+ }
+ buffer_size = endpoint->wMaxPacketSize;
+ port->bulk_out_size = buffer_size;
+ port->bulk_out_endpointAddress = endpoint->bEndpointAddress;
+ port->bulk_out_buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (!port->bulk_out_buffer) {
+ err("Couldn't allocate bulk_out_buffer");
+ goto probe_error;
+ }
+ usb_fill_bulk_urb(port->write_urb, dev,
+ usb_sndbulkpipe(dev,
+ endpoint->bEndpointAddress),
+ port->bulk_out_buffer, buffer_size,
+ qt_write_bulk_callback, port);
+
+ }
+
+ /* For us numb of bulkin or out = number of ports */
+ mydbg("%s - setting up %d port structures for this device\n",
+ __func__, num_bulk_in);
+ for (i = 0; i < num_bulk_in; ++i) {
+ port = &serial->port[i];
+ port->number = i + serial->minor;
+ port->serial = serial;
+
+ INIT_WORK(&port->work, port_softint);
+
+ init_MUTEX(&port->sem);
+
+ }
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed");
+ goto probe_error;
+ }
+
+ mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
+
+ DeviceData.portb &= ~FULLPWRBIT;
+ mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
+
+ status = box_set_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ goto probe_error;
+ }
+
+ /* initialize the devfs nodes for this device and let the user know what ports we are bound to */
+ for (i = 0; i < serial->num_ports; ++i) {
+ dev_info(&interface->dev,
+ "Converter now attached to ttyUSB%d (or usb/tts/%d for devfs)",
+ serial->port[i].number, serial->port[i].number);
+ }
+
+ /* usb_serial_console_init (debug, minor); */
+
+ /***********TAG add start next board here ****/
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed");
+ goto probe_error;
+ }
+ /*
+ * and before we power up lets initialiaze parnent device stuff here before
+ * we set thmem via any other method such as the property pages
+ */
+ switch (serial->product) {
+ case DEVICE_ID_QUATECH_RS232_SINGLE_PORT:
+ case DEVICE_ID_QUATECH_RS232_DUAL_PORT:
+ case DEVICE_ID_QUATECH_RS232_FOUR_PORT:
+ case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_A:
+ case DEVICE_ID_QUATECH_RS232_EIGHT_PORT_B:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_A:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_B:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_C:
+ case DEVICE_ID_QUATECH_RS232_16_PORT_D:
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+ DeviceData.porta |= CLKS_X4;
+ DeviceData.portb &= ~(LOOPMODE_BITS);
+ DeviceData.portb |= RS232_MODE;
+ break;
+
+ case DEVICE_ID_QUATECH_RS422_SINGLE_PORT:
+ case DEVICE_ID_QUATECH_RS422_DUAL_PORT:
+ case DEVICE_ID_QUATECH_RS422_FOUR_PORT:
+ case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_A:
+ case DEVICE_ID_QUATECH_RS422_EIGHT_PORT_B:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_A:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_B:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_C:
+ case DEVICE_ID_QUATECH_RS422_16_PORT_D:
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+ DeviceData.porta |= CLKS_X4;
+ DeviceData.portb &= ~(LOOPMODE_BITS);
+ DeviceData.portb |= ALL_LOOPBACK;
+ break;
+ default:
+ DeviceData.porta &= ~(RR_BITS | DUPMODE_BITS);
+ DeviceData.porta |= CLKS_X4;
+ DeviceData.portb &= ~(LOOPMODE_BITS);
+ DeviceData.portb |= RS232_MODE;
+ break;
+
+ }
+ status = BoxSetPrebufferLevel(serial); /* sets to default vaue */
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetPrebufferLevel failed\n");
+ goto probe_error;
+ }
+
+ status = BoxSetATC(serial, ATC_DISABLED);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetATC failed\n");
+ goto probe_error;
+ }
+ /**********************************************************/
+ mydbg(__FILE__ "DeviceData.portb = 0x%x", DeviceData.portb);
+
+ DeviceData.portb |= NEXT_BOARD_POWER_BIT;
+ mydbg(__FILE__ "Changing DeviceData.portb to 0x%x", DeviceData.portb);
+
+ status = box_set_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ goto probe_error;
+ }
+
+ mydbg("Exit Success %s\n", __func__);
+
+ usb_set_intfdata(interface, serial);
+ return 0;
+
+probe_error:
+
+ for (i = 0; i < num_bulk_in; ++i) {
+ port = &serial->port[i];
+ usb_free_urb(port->read_urb);
+ kfree(port->bulk_in_buffer);
+ }
+ for (i = 0; i < num_bulk_out; ++i) {
+ port = &serial->port[i];
+ usb_free_urb(port->write_urb);
+ kfree(port->bulk_out_buffer);
+ kfree(port->xfer_to_tty_buffer);
+ }
+ for (i = 0; i < num_interrupt_in; ++i) {
+ port = &serial->port[i];
+ usb_free_urb(port->interrupt_in_urb);
+ kfree(port->interrupt_in_buffer);
+ }
+
+ /* return the minor range that this device had */
+ return_serial(serial);
+ mydbg("Exit fail %s\n", __func__);
+
+ /* free up any memory that we allocated */
+ kfree(serial);
+ return -EIO;
+}
+
+/*
+ * returns the serial_table array pointers that are taken
+ * up in consecutive positions for each port to a common usb_serial structure
+ * back to NULL
+ */
+static void return_serial(struct usb_serial *serial)
+{
+ int i;
+
+ mydbg("%s\n", __func__);
+
+ if (serial == NULL)
+ return;
+
+ for (i = 0; i < serial->num_ports; ++i)
+ serial_table[serial->minor + i] = NULL;
+
+ return;
+}
+
+/*
+ * Finds the first locatio int the serial_table array where it can fit
+ * num_ports number of consecutive points to a common usb_serial
+ * structure,allocates a stucture points to it in all the structures, and
+ * returns the index to the first location in the array in the "minor"
+ * variable.
+ */
+static struct usb_serial *get_free_serial(int num_ports, int *minor)
+{
+ struct usb_serial *serial = NULL;
+ int i, j;
+ int good_spot;
+
+ mydbg("%s %d\n", __func__, num_ports);
+
+ *minor = 0;
+ for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
+ if (serial_table[i])
+ continue;
+
+ good_spot = 1;
+ /*
+ * find a spot in the array where you can fit consecutive
+ * positions to put the pointers to the usb_serail allocated
+ * structure for all the minor numbers (ie. ports)
+ */
+ for (j = 1; j <= num_ports - 1; ++j)
+ if (serial_table[i + j])
+ good_spot = 0;
+ if (good_spot == 0)
+ continue;
+
+ serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL);
+ if (!serial) {
+ err("%s - Out of memory", __func__);
+ return NULL;
+ }
+ memset(serial, 0, sizeof(struct usb_serial));
+ serial_table[i] = serial;
+ *minor = i;
+ mydbg("%s - minor base = %d\n", __func__, *minor);
+
+ /*
+ * copy in the pointer into the array starting a the *minor
+ * position minor is the index into the array.
+ */
+ for (i = *minor + 1;
+ (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i)
+ serial_table[i] = serial;
+ return serial;
+ }
+ return NULL;
+}
+
+static int flip_that(struct tty_struct *tty, __u16 UartNumber,
+ struct usb_serial *serial)
+{
+ tty_flip_buffer_push(tty);
+ tty_schedule_flip(tty);
+ return 0;
+}
+
+/* Handles processing and moving data to the tty layer */
+static void port_sofrint(void *private)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *)private;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ struct tty_struct *tty = port->tty;
+ unsigned char *data = port->read_urb->transfer_buffer;
+ unsigned int UartNumber;
+ struct urb *urb = port->read_urb;
+ unsigned int RxCount = urb->actual_length;
+ int i, result;
+ int flag, flag_data;
+
+ /* UartNumber = MINOR(port->tty->device) - serial->minor; */
+ UartNumber = tty->index - serial->minor;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (port_paranoia_check(port, __func__) != 0) {
+ mydbg("%s - port_paranoia_check, exiting\n", __func__);
+ port->ReadBulkStopped = 1;
+ return;
+ }
+
+ if (!serial) {
+ mydbg("%s - bad serial pointer, exiting\n", __func__);
+ return;
+ }
+ if (port->closePending == 1) {
+ /* Were closing , stop reading */
+ mydbg("%s - (port->closepending == 1\n", __func__);
+ port->ReadBulkStopped = 1;
+ return;
+ }
+
+ /*
+ * RxHolding is asserted by throttle, if we assert it, we're not
+ * receiving any more characters and let the box handle the flow
+ * control
+ */
+ if (port->RxHolding == 1) {
+ port->ReadBulkStopped = 1;
+ return;
+ }
+
+ if (urb->status) {
+ port->ReadBulkStopped = 1;
+
+ mydbg("%s - nonzero read bulk status received: %d\n",
+ __func__, urb->status);
+ return;
+ }
+
+ tty = port->tty;
+ mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+ if (tty && RxCount) {
+ flag_data = 0;
+ for (i = 0; i < RxCount; ++i) {
+ /* Look ahead code here */
+ if ((i <= (RxCount - 3)) && (THISCHAR == 0x1b)
+ && (NEXTCHAR == 0x1b)) {
+ flag = 0;
+ switch (THIRDCHAR) {
+ case 0x00:
+ /* Line status change 4th byte must follow */
+ if (i > (RxCount - 4)) {
+ mydbg("Illegal escape sequences in received data\n");
+ break;
+ }
+ ProcessLineStatus(port, FOURTHCHAR);
+ i += 3;
+ flag = 1;
+ break;
+
+ case 0x01:
+ /* Modem status status change 4th byte must follow */
+ mydbg("Modem status status. \n");
+ if (i > (RxCount - 4)) {
+ mydbg
+ ("Illegal escape sequences in received data\n");
+ break;
+ }
+ ProcessModemStatus(port, FOURTHCHAR);
+ i += 3;
+ flag = 1;
+ break;
+ case 0xff:
+ mydbg("No status sequence. \n");
+
+ ProcessRxChar(port, THISCHAR);
+ ProcessRxChar(port, NEXTCHAR);
+ i += 2;
+ break;
+ }
+ if (flag == 1)
+ continue;
+ }
+
+ if (tty && urb->actual_length) {
+ tty_buffer_request_room(tty, 1);
+ tty_insert_flip_string(tty, (data + i), 1);
+ }
+
+ }
+ tty_flip_buffer_push(tty);
+ }
+
+ /* Continue trying to always read */
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ qt_read_bulk_callback, port);
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+ if (result)
+ mydbg("%s - failed resubmitting read urb, error %d",
+ __func__, result);
+ else {
+ if (tty && RxCount)
+ flip_that(tty, UartNumber, serial);
+ }
+
+ return;
+
+}
+
+static void qt_read_bulk_callback(struct urb *urb)
+{
+
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+
+ if (urb->status) {
+ port->ReadBulkStopped = 1;
+ mydbg("%s - nonzero write bulk status received: %d\n",
+ __func__, urb->status);
+ return;
+ }
+
+ port_sofrint((void *)port);
+ schedule_work(&port->work);
+}
+
+static void ProcessRxChar(struct usb_serial_port *port, unsigned char Data)
+{
+ struct tty_struct *tty;
+ struct urb *urb = port->read_urb;
+ tty = port->tty;
+ /* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
+
+ if (tty && urb->actual_length) {
+ tty_buffer_request_room(tty, 1);
+ tty_insert_flip_string(tty, &Data, 1);
+ /* tty_flip_buffer_push(tty); */
+ }
+
+ return;
+}
+
+static void ProcessLineStatus(struct usb_serial_port *port,
+ unsigned char line_status)
+{
+
+ port->shadowLSR =
+ line_status & (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE |
+ SERIAL_LSR_BI);
+ return;
+}
+
+static void ProcessModemStatus(struct usb_serial_port *port,
+ unsigned char modem_status)
+{
+
+ port->shadowMSR = modem_status;
+ wake_up_interruptible(&port->wait);
+ return;
+}
+
+static void serqt_usb_disconnect(struct usb_interface *interface)
+{
+ struct usb_serial *serial = usb_get_intfdata(interface);
+ /* struct device *dev = &interface->dev; */
+ struct usb_serial_port *port;
+ int i;
+
+ mydbg("%s\n", __func__);
+ if (serial) {
+
+ serial->dev = NULL;
+
+ for (i = 0; i < serial->num_ports; ++i)
+ serial->port[i].open_count = 0;
+
+ for (i = 0; i < serial->num_bulk_in; ++i) {
+ port = &serial->port[i];
+ usb_unlink_urb(port->read_urb);
+ usb_free_urb(port->read_urb);
+ kfree(port->bulk_in_buffer);
+ }
+ for (i = 0; i < serial->num_bulk_out; ++i) {
+ port = &serial->port[i];
+ usb_unlink_urb(port->write_urb);
+ usb_free_urb(port->write_urb);
+ kfree(port->bulk_out_buffer);
+ }
+ for (i = 0; i < serial->num_interrupt_in; ++i) {
+ port = &serial->port[i];
+ usb_unlink_urb(port->interrupt_in_urb);
+ usb_free_urb(port->interrupt_in_urb);
+ kfree(port->interrupt_in_buffer);
+ }
+
+ /* return the minor range that this device had */
+ return_serial(serial);
+
+ /* free up any memory that we allocated */
+ kfree(serial);
+
+ } else {
+ dev_info(&interface->dev, "device disconnected");
+ }
+
+}
+
+static struct usb_serial *get_serial_by_minor(unsigned int minor)
+{
+ return serial_table[minor];
+}
+
+/*****************************************************************************
+ * Driver tty interface functions
+ *****************************************************************************/
+static int serial_open(struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ unsigned int portNumber;
+ int retval = 0;
+
+ mydbg("%s\n", __func__);
+
+ /* initialize the pointer incase something fails */
+ tty->driver_data = NULL;
+
+ /* get the serial object associated with this tty pointer */
+ /* serial = get_serial_by_minor (MINOR(tty->device)); */
+
+ /* get the serial object associated with this tty pointer */
+ serial = get_serial_by_minor(tty->index);
+
+ if (serial_paranoia_check(serial, __func__))
+ return -ENODEV;
+
+ /* set up our port structure making the tty driver remember our port object, and us it */
+ portNumber = tty->index - serial->minor;
+ port = &serial->port[portNumber];
+ tty->driver_data = port;
+
+ down(&port->sem);
+ port->tty = tty;
+
+ ++port->open_count;
+ if (port->open_count == 1) {
+ port->closePending = 0;
+ mydbg("%s port->closepending = 0\n", __func__);
+
+ port->RxHolding = 0;
+ mydbg("%s port->RxHolding = 0\n", __func__);
+
+ retval = qt_open(port, filp);
+ }
+
+ if (retval)
+ port->open_count = 0;
+ mydbg("%s returning port->closePending = %d\n", __func__,
+ port->closePending);
+
+ up(&port->sem);
+ return retval;
+}
+
+/*****************************************************************************
+ *device's specific driver functions
+ *****************************************************************************/
+static int qt_open(struct usb_serial_port *port, struct file *filp)
+{
+ struct usb_serial *serial = port->serial;
+ int result = 0;
+ unsigned int UartNumber;
+ struct qt_get_device_data DeviceData;
+ struct qt_open_channel_data ChannelData;
+ unsigned short default_divisor = 0x30; /* gives 9600 baud rate */
+ unsigned char default_LCR = SERIAL_8_DATA; /* 8, none , 1 */
+ int status = 0;
+
+ if (port_paranoia_check(port, __func__))
+ return -ENODEV;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ /* force low_latency on so that our tty_push actually forces the data through,
+ otherwise it is scheduled, and with high data rates (like with OHCI) data
+ can get lost. */
+ if (port->tty)
+ port->tty->low_latency = 0;
+
+ UartNumber = port->tty->index - serial->minor;
+
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed\n");
+ return status;
+ }
+ serial->num_OpenCount++;
+ mydbg("%s serial->num_OpenCount = %d\n", __func__,
+ serial->num_OpenCount);
+ /* Open uart channel */
+
+ /* Port specific setups */
+ status = BoxOPenCloseChannel(serial, UartNumber, 1, &ChannelData);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxOPenCloseChannel failed\n");
+ return status;
+ }
+ mydbg(__FILE__ "BoxOPenCloseChannel completed.\n");
+
+ port->shadowLSR = ChannelData.line_status &
+ (SERIAL_LSR_OE | SERIAL_LSR_PE | SERIAL_LSR_FE | SERIAL_LSR_BI);
+
+ port->shadowMSR = ChannelData.modem_status &
+ (SERIAL_MSR_CTS | SERIAL_MSR_DSR | SERIAL_MSR_RI | SERIAL_MSR_CD);
+
+ /* Set Baud rate to default and turn off (default)flow control here */
+ status = BoxSetUart(serial, UartNumber, default_divisor, default_LCR);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetUart failed\n");
+ return status;
+ }
+ mydbg(__FILE__ "BoxSetUart completed.\n");
+
+ /* Put this here to make it responsive to stty and defauls set by the tty layer */
+ qt_set_termios(port, NULL);
+
+ /* Initialize the wait que head */
+ init_waitqueue_head(&(port->wait));
+
+ /* if we have a bulk endpoint, start reading from it */
+ if (serial->num_bulk_in) {
+ /* Start reading from the device */
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->
+ bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->transfer_buffer_length,
+ qt_read_bulk_callback, port);
+
+ port->ReadBulkStopped = 0;
+
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+
+ if (result) {
+ err("%s - failed resubmitting read urb, error %d\n",
+ __func__, result);
+ port->ReadBulkStopped = 1;
+ }
+
+ }
+
+ return result;
+}
+
+static void serial_close(struct tty_struct *tty, struct file *filp)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ if (!serial)
+ return;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ /* if disconnect beat us to the punch here, there's nothing to do */
+ if (tty->driver_data) {
+ if (!port->open_count) {
+ mydbg("%s - port not opened\n", __func__);
+ goto exit;
+ }
+
+ --port->open_count;
+ if (port->open_count <= 0) {
+ port->closePending = 1;
+ mydbg("%s - port->closePending = 1\n", __func__);
+
+ if (serial->dev) {
+ qt_close(port, filp);
+ port->open_count = 0;
+ }
+ }
+
+ }
+
+exit:
+ up(&port->sem);
+
+ mydbg("%s - %d return\n", __func__, port->number);
+
+}
+
+static void qt_close(struct usb_serial_port *port, struct file *filp)
+{
+ unsigned long jift = jiffies + 10 * HZ;
+ __u8 LSR_Value, MCR_Value;
+ struct usb_serial *serial = port->serial;
+ int status;
+ unsigned int UartNumber;
+
+ struct qt_open_channel_data ChannelData;
+ status = 0;
+ LSR_Value = 0;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+ UartNumber = port->tty->index - serial->minor;
+
+ /* shutdown any bulk reads that might be going on */
+ if (serial->num_bulk_out)
+ usb_unlink_urb(port->write_urb);
+ if (serial->num_bulk_in)
+ usb_unlink_urb(port->read_urb);
+
+ /* wait up to 30 seconds for transmitter to empty */
+ do {
+ status = BoxGetRegister(serial, UartNumber, LINE_STATUS_REGISTER, &LSR_Value);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed\n");
+ break;
+ }
+
+ if ((LSR_Value & SERIAL_LSR_TEMT)
+ && (port->ReadBulkStopped == 1))
+ break;
+ schedule();
+
+ }
+ while (jiffies <= jift)
+ ;
+
+ if (jiffies > jift)
+ mydbg("%s - port %d timout of checking transmitter empty\n",
+ __func__, port->number);
+ else
+ mydbg("%s - port %d checking transmitter empty succeded\n",
+ __func__, port->number);
+
+ status =
+ BoxGetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER,
+ &MCR_Value);
+ mydbg(__FILE__ "BoxGetRegister MCR = 0x%x.\n", MCR_Value);
+
+ if (status >= 0) {
+ MCR_Value &= ~(SERIAL_MCR_DTR | SERIAL_MCR_RTS);
+ /* status = BoxSetRegister(serial, UartNumber, MODEM_CONTROL_REGISTER, MCR_Value); */
+ }
+
+ /* Close uart channel */
+ status = BoxOPenCloseChannel(serial, UartNumber, 0, &ChannelData);
+ if (status < 0)
+ mydbg("%s - port %d BoxOPenCloseChannel failed.\n",
+ __func__, port->number);
+
+ serial->num_OpenCount--;
+
+}
+
+static int serial_write(struct tty_struct *tty, const unsigned char *buf,
+ int count)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial;
+ int retval = -EINVAL;
+ unsigned int UartNumber;
+ int from_user = 0;
+
+ serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+ /* This can happen if we get disconnected a */
+ if (port->open_count == 0)
+ return -ENODEV;
+ UartNumber = port->tty->index - serial->minor;
+
+ mydbg("%s - port %d, %d byte(s)\n", __func__, port->number, count);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not opened\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_write(port, from_user, buf, count);
+
+exit:
+ return retval;
+}
+
+static int qt_write(struct usb_serial_port *port, int from_user,
+ const unsigned char *buf, int count)
+{
+ int result;
+ unsigned int UartNumber;
+
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (count == 0) {
+ mydbg("%s - write request of 0 bytes\n", __func__);
+ return 0;
+ }
+
+ UartNumber = port->tty->index - serial->minor;
+ /* only do something if we have a bulk out endpoint */
+ if (serial->num_bulk_out) {
+ if (port->write_urb->status == -EINPROGRESS) {
+ mydbg("%s - already writing\n", __func__);
+ return 0;
+ }
+
+ count =
+ (count > port->bulk_out_size) ? port->bulk_out_size : count;
+
+ if (from_user) {
+ if (copy_from_user
+ (port->write_urb->transfer_buffer, buf, count))
+ return -EFAULT;
+ } else {
+ memcpy(port->write_urb->transfer_buffer, buf, count);
+ }
+
+ /* usb_serial_debug_data(__FILE__, __func__, count, port->write_urb->transfer_buffer); */
+
+ /* set up our urb */
+
+ usb_fill_bulk_urb(port->write_urb, serial->dev,
+ usb_sndbulkpipe(serial->dev,
+ port->
+ bulk_out_endpointAddress),
+ port->write_urb->transfer_buffer, count,
+ qt_write_bulk_callback, port);
+
+ /* send the data out the bulk port */
+ result = usb_submit_urb(port->write_urb, GFP_ATOMIC);
+ if (result)
+ mydbg("%s - failed submitting write urb, error %d\n",
+ __func__, result);
+ else
+ result = count;
+
+ return result;
+ }
+
+ /* no bulk out, so return 0 bytes written */
+ return 0;
+}
+
+static void qt_write_bulk_callback(struct urb *urb)
+{
+ struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!serial) {
+ mydbg("%s - bad serial pointer, exiting\n", __func__);
+ return;
+ }
+
+ if (urb->status) {
+ mydbg("%s - nonzero write bulk status received: %d\n",
+ __func__, urb->status);
+ return;
+ }
+ port_softint(&port->work);
+ schedule_work(&port->work);
+
+ return;
+}
+
+static void port_softint(struct work_struct *work)
+{
+ struct usb_serial_port *port =
+ container_of(work, struct usb_serial_port, work);
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ struct tty_struct *tty;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!serial)
+ return;
+
+ tty = port->tty;
+ if (!tty)
+ return;
+#if 0
+ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
+ && tty->ldisc.write_wakeup) {
+ mydbg("%s - write wakeup call.\n", __func__);
+ (tty->ldisc.write_wakeup) (tty);
+ }
+#endif
+
+ wake_up_interruptible(&tty->write_wait);
+}
+static int serial_write_room(struct tty_struct *tty)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -EINVAL;
+
+ if (!serial)
+ return -ENODEV;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_write_room(port);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+static int qt_write_room(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ int room = 0;
+ if (port->closePending == 1) {
+ mydbg("%s - port->closePending == 1\n", __func__);
+ return -ENODEV;
+ }
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (serial->num_bulk_out) {
+ if (port->write_urb->status != -EINPROGRESS)
+ room = port->bulk_out_size;
+ }
+
+ mydbg("%s - returns %d\n", __func__, room);
+ return room;
+}
+static int serial_chars_in_buffer(struct tty_struct *tty)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -EINVAL;
+
+ if (!serial)
+ return -ENODEV;
+
+ down(&port->sem);
+
+ mydbg("%s = port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_chars_in_buffer(port);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+
+static int qt_chars_in_buffer(struct usb_serial_port *port)
+{
+ struct usb_serial *serial = port->serial;
+ int chars = 0;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (serial->num_bulk_out) {
+ if (port->write_urb->status == -EINPROGRESS)
+ chars = port->write_urb->transfer_buffer_length;
+ }
+
+ mydbg("%s - returns %d\n", __func__, chars);
+ return chars;
+}
+
+static int serial_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -ENODEV;
+ unsigned int UartNumber;
+ mydbg("In %s \n", __func__);
+
+ if (!serial)
+ return -ENODEV;
+
+ UartNumber = port->tty->index - serial->minor;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d \n", __func__, port->number);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_tiocmset(port, file, set);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+
+static int qt_tiocmset(struct usb_serial_port *port, struct file *file,
+ unsigned int value)
+{
+
+ __u8 MCR_Value;
+ int status;
+ unsigned int UartNumber;
+
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ /**************************************************************************************/
+ /** TIOCMGET
+ */
+ UartNumber = port->tty->index - serial->minor;
+ status =
+ BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
+ &MCR_Value);
+ if (status < 0)
+ return -ESPIPE;
+
+ /*
+ * Turn off the RTS and DTR and loopbcck and then only turn on what was
+ * asked for
+ */
+ MCR_Value &= ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR | SERIAL_MCR_LOOP);
+ if (value & TIOCM_RTS)
+ MCR_Value |= SERIAL_MCR_RTS;
+ if (value & TIOCM_DTR)
+ MCR_Value |= SERIAL_MCR_DTR;
+ if (value & TIOCM_LOOP)
+ MCR_Value |= SERIAL_MCR_LOOP;
+
+ status =
+ BoxSetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
+ MCR_Value);
+ if (status < 0)
+ return -ESPIPE;
+ else
+ return 0;
+}
+
+static int serial_tiocmget(struct tty_struct *tty, struct file *file)
+{
+
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -ENODEV;
+ unsigned int UartNumber;
+ mydbg("In %s \n", __func__);
+
+ if (!serial)
+ return -ENODEV;
+
+ UartNumber = port->tty->index - serial->minor;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_tiocmget(port, file);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+
+static int qt_tiocmget(struct usb_serial_port *port, struct file *file)
+{
+
+ __u8 MCR_Value;
+ __u8 MSR_Value;
+ unsigned int result = 0;
+ int status;
+ unsigned int UartNumber;
+ struct tty_struct *tty;
+
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+ tty = port->tty;
+
+ mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+ /**************************************************************************************/
+ /** TIOCMGET
+ */
+ UartNumber = port->tty->index - serial->minor;
+ status =
+ BoxGetRegister(port->serial, UartNumber, MODEM_CONTROL_REGISTER,
+ &MCR_Value);
+ if (status >= 0) {
+ status =
+ BoxGetRegister(port->serial, UartNumber,
+ MODEM_STATUS_REGISTER, &MSR_Value);
+
+ }
+
+ if (status >= 0) {
+ result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
+ /* DTR IS SET */
+ | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
+ /* RTS IS SET */
+ | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
+ /* CTS is set */
+ | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
+ /* Carrier detect is set */
+ | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI : 0)
+ /* Ring indicator set */
+ | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
+ /* DSR is set */
+ return result;
+
+ } else
+ return -ESPIPE;
+}
+
+static int serial_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ int retval = -ENODEV;
+ unsigned int UartNumber;
+ mydbg("In %s \n", __func__);
+
+ if (!serial)
+ return -ENODEV;
+
+ UartNumber = port->tty->index - serial->minor;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d, cmd 0x%.4x\n", __func__, port->number, cmd);
+ mydbg("%s - port->RxHolding = %d\n", __func__, port->RxHolding);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ retval = qt_ioctl(port, file, cmd, arg);
+
+exit:
+ up(&port->sem);
+ return retval;
+}
+static int qt_ioctl(struct usb_serial_port *port, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ __u8 MCR_Value;
+ __u8 MSR_Value;
+ unsigned short Prev_MSR_Value;
+ unsigned int value, result = 0;
+ int status;
+ unsigned int UartNumber;
+ struct tty_struct *tty;
+
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ if (serial == NULL)
+ return -ENODEV;
+ tty = port->tty;
+
+ mydbg("%s - port %d, tty =0x%p\n", __func__, port->number, tty);
+
+ /* TIOCMGET */
+ UartNumber = port->tty->index - serial->minor;
+
+ if (cmd == TIOCMGET) {
+ MCR_Value = port->shadowMCR;
+ MSR_Value = port->shadowMSR;
+
+ {
+ result = ((MCR_Value & SERIAL_MCR_DTR) ? TIOCM_DTR : 0)
+ /* DTR IS SET */
+ | ((MCR_Value & SERIAL_MCR_RTS) ? TIOCM_RTS : 0)
+ /* RTS IS SET */
+ | ((MSR_Value & SERIAL_MSR_CTS) ? TIOCM_CTS : 0)
+ /* CTS is set */
+ | ((MSR_Value & SERIAL_MSR_CD) ? TIOCM_CAR : 0)
+ /* Carrier detect is set */
+ | ((MSR_Value & SERIAL_MSR_RI) ? TIOCM_RI : 0)
+ /* Ring indicator set */
+ | ((MSR_Value & SERIAL_MSR_DSR) ? TIOCM_DSR : 0);
+ /* DSR is set */
+ if (copy_to_user
+ ((unsigned int *)arg, &result,
+ sizeof(unsigned int)))
+ return -EFAULT;
+ return 0;
+
+ }
+ }
+
+ /* TIOCMBIS, TIOCMBIC, AND TIOCMSET */
+ if (cmd == TIOCMBIS || cmd == TIOCMBIC || cmd == TIOCMSET) {
+ status =
+ BoxGetRegister(port->serial, UartNumber,
+ MODEM_CONTROL_REGISTER, &MCR_Value);
+ if (status < 0)
+ return -ESPIPE;
+ if (copy_from_user
+ (&value, (unsigned int *)arg, sizeof(unsigned int)))
+ return -EFAULT;
+
+ switch (cmd) {
+ case TIOCMBIS:
+ if (value & TIOCM_RTS)
+ MCR_Value |= SERIAL_MCR_RTS;
+ if (value & TIOCM_DTR)
+ MCR_Value |= SERIAL_MCR_DTR;
+ if (value & TIOCM_LOOP)
+ MCR_Value |= SERIAL_MCR_LOOP;
+ break;
+ case TIOCMBIC:
+ if (value & TIOCM_RTS)
+ MCR_Value &= ~SERIAL_MCR_RTS;
+ if (value & TIOCM_DTR)
+ MCR_Value &= ~SERIAL_MCR_DTR;
+ if (value & TIOCM_LOOP)
+ MCR_Value &= ~SERIAL_MCR_LOOP;
+ break;
+ case TIOCMSET:
+ /*
+ * Turn off the RTS and DTR and loopbcck and then only
+ * turn on what was asked for
+ */
+ MCR_Value &=
+ ~(SERIAL_MCR_RTS | SERIAL_MCR_DTR |
+ SERIAL_MCR_LOOP);
+ if (value & TIOCM_RTS)
+ MCR_Value |= SERIAL_MCR_RTS;
+ if (value & TIOCM_DTR)
+ MCR_Value |= SERIAL_MCR_DTR;
+ if (value & TIOCM_LOOP)
+ MCR_Value |= SERIAL_MCR_LOOP;
+ break;
+ default:
+ break;
+
+ }
+ status =
+ BoxSetRegister(port->serial, UartNumber,
+ MODEM_CONTROL_REGISTER, MCR_Value);
+ if (status < 0)
+ return -ESPIPE;
+ else {
+ port->shadowMCR = MCR_Value;
+ return 0;
+ }
+
+ }
+ /**************************************************************************************/
+ /** TIOCMBIS, TIOCMBIC, AND TIOCMSET end
+ */
+ /**************************************************************************************/
+
+ if (cmd == TIOCMIWAIT) {
+ DECLARE_WAITQUEUE(wait, current);
+ Prev_MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
+ while (1) {
+ add_wait_queue(&port->wait, &wait);
+ set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ remove_wait_queue(&port->wait, &wait);
+ /* see if a signal woke us up */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ MSR_Value = port->shadowMSR & SERIAL_MSR_MASK;
+ if (MSR_Value == Prev_MSR_Value)
+ return -EIO; /* no change error */
+
+ if ((arg & TIOCM_RNG
+ && ((Prev_MSR_Value & SERIAL_MSR_RI) ==
+ (MSR_Value & SERIAL_MSR_RI)))
+ || (arg & TIOCM_DSR
+ && ((Prev_MSR_Value & SERIAL_MSR_DSR) ==
+ (MSR_Value & SERIAL_MSR_DSR)))
+ || (arg & TIOCM_CD
+ && ((Prev_MSR_Value & SERIAL_MSR_CD) ==
+ (MSR_Value & SERIAL_MSR_CD)))
+ || (arg & TIOCM_CTS
+ && ((Prev_MSR_Value & SERIAL_MSR_CTS) ==
+ (MSR_Value & SERIAL_MSR_CTS)))) {
+ return 0;
+ }
+
+ }
+
+ }
+ mydbg("%s -No ioctl for that one. port = %d\n", __func__,
+ port->number);
+
+ return -ENOIOCTLCMD;
+}
+
+static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+
+ if (!serial)
+ return;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ /* pass on to the driver specific version of this function if it is available */
+ qt_set_termios(port, old);
+
+exit:
+ up(&port->sem);
+}
+
+static void qt_set_termios(struct usb_serial_port *port,
+ struct ktermios *old_termios)
+{
+ unsigned int cflag;
+ int baud, divisor, remainder;
+ unsigned char LCR_change_to = 0;
+ struct tty_struct *tty;
+ int status;
+ struct usb_serial *serial;
+ __u16 UartNumber;
+ __u16 tmp, tmp2;
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ tmp = port->tty->index;
+ mydbg("%s - MINOR(port->tty->index) = %d\n", __func__, tmp);
+
+ serial = port->serial;
+ tmp2 = serial->minor;
+ mydbg("%s - serial->minor = %d\n", __func__, tmp2);
+
+ UartNumber = port->tty->index - serial->minor;
+
+ tty = port->tty;
+
+ cflag = tty->termios->c_cflag;
+
+ if (old_termios) {
+ if ((cflag == old_termios->c_cflag)
+ && (RELEVANT_IFLAG(tty->termios->c_iflag) ==
+ RELEVANT_IFLAG(old_termios->c_iflag))) {
+ mydbg("%s - Nothing to change\n", __func__);
+ return;
+ }
+
+ }
+
+ mydbg("%s - 3\n", __func__);
+
+ switch (cflag) {
+ case CS5:
+ LCR_change_to |= SERIAL_5_DATA;
+ break;
+ case CS6:
+ LCR_change_to |= SERIAL_6_DATA;
+ break;
+ case CS7:
+ LCR_change_to |= SERIAL_7_DATA;
+ break;
+ default:
+ case CS8:
+ LCR_change_to |= SERIAL_8_DATA;
+ break;
+ }
+
+ /* Parity stuff */
+ if (cflag & PARENB) {
+ if (cflag & PARODD)
+ LCR_change_to |= SERIAL_ODD_PARITY;
+ else
+ LCR_change_to |= SERIAL_EVEN_PARITY;
+ }
+ if (cflag & CSTOPB)
+ LCR_change_to |= SERIAL_TWO_STOPB;
+ else
+ LCR_change_to |= SERIAL_TWO_STOPB;
+
+ mydbg("%s - 4\n", __func__);
+ /* Thats the LCR stuff, go ahead and set it */
+ baud = tty_get_baud_rate(tty);
+ if (!baud) {
+ /* pick a default, any default... */
+ baud = 9600;
+ }
+
+ mydbg("%s - got baud = %d\n", __func__, baud);
+
+ divisor = MAX_BAUD_RATE / baud;
+ remainder = MAX_BAUD_RATE % baud;
+ /* Round to nearest divisor */
+ if (((remainder * 2) >= baud) && (baud != 110))
+ divisor++;
+
+ /*
+ * Set Baud rate to default and turn off (default)flow control here
+ */
+ status =
+ BoxSetUart(serial, UartNumber, (unsigned short)divisor,
+ LCR_change_to);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetUart failed\n");
+ return;
+ }
+
+ /* Now determine flow control */
+ if (cflag & CRTSCTS) {
+ mydbg("%s - Enabling HW flow control port %d\n", __func__,
+ port->number);
+
+ /* Enable RTS/CTS flow control */
+ status = BoxSetHW_FlowCtrl(serial, UartNumber, 1);
+
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
+ return;
+ }
+ } else {
+ /* Disable RTS/CTS flow control */
+ mydbg("%s - disabling HW flow control port %d\n", __func__,
+ port->number);
+
+ status = BoxSetHW_FlowCtrl(serial, UartNumber, 0);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetHW_FlowCtrl failed\n");
+ return;
+ }
+
+ }
+
+ /* if we are implementing XON/XOFF, set the start and stop character in
+ * the device */
+ if (I_IXOFF(tty) || I_IXON(tty)) {
+ unsigned char stop_char = STOP_CHAR(tty);
+ unsigned char start_char = START_CHAR(tty);
+ status =
+ BoxSetSW_FlowCtrl(serial, UartNumber, stop_char,
+ start_char);
+ if (status < 0)
+ mydbg(__FILE__ "BoxSetSW_FlowCtrl (enabled) failed\n");
+
+ } else {
+ /* disable SW flow control */
+ status = BoxDisable_SW_FlowCtrl(serial, UartNumber);
+ if (status < 0)
+ mydbg(__FILE__ "BoxSetSW_FlowCtrl (diabling) failed\n");
+
+ }
+
+}
+
+/****************************************************************************
+* BoxGetRegister
+* issuse a GET_REGISTER vendor-spcific request on the default control pipe
+* If successful, fills in the pValue with the register value asked for
+****************************************************************************/
+static int BoxGetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, __u8 *pValue)
+{
+ int result;
+ __u16 current_length;
+
+ current_length = sizeof(struct qt_get_device_data);
+
+ result =
+ usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ QT_GET_SET_REGISTER, 0xC0, Register_Num,
+ Uart_Number, (void *)pValue, sizeof(*pValue), 300);
+
+ return result;
+}
+
+/****************************************************************************
+* BoxSetRegister
+* issuse a GET_REGISTER vendor-spcific request on the default control pipe
+* If successful, fills in the pValue with the register value asked for
+****************************************************************************/
+static int BoxSetRegister(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short Register_Num, unsigned short Value)
+{
+ int result;
+ unsigned short RegAndByte;
+
+ RegAndByte = Value;
+ RegAndByte = RegAndByte << 8;
+ RegAndByte = RegAndByte + Register_Num;
+
+/*
+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_REGISTER, 0xC0, Register_Num,
+ Uart_Number, NULL, 0, 300);
+*/
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_REGISTER, 0x40, RegAndByte, Uart_Number,
+ NULL, 0, 300);
+
+ return result;
+}
+
+/**
+ * box_get_device
+ * Issue a GET_DEVICE vendor-specific request on the default control pipe If
+ * successful, fills in the qt_get_device_data structure pointed to by
+ * device_data, otherwise return a negative error number of the problem.
+ */
+static int box_get_device(struct usb_serial *serial,
+ struct qt_get_device_data *device_data)
+{
+ int result;
+ __u16 current_length;
+ unsigned char *transfer_buffer;
+
+ current_length = sizeof(struct qt_get_device_data);
+ transfer_buffer = kmalloc(current_length, GFP_KERNEL);
+ if (!transfer_buffer)
+ return -ENOMEM;
+
+ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ QT_SET_GET_DEVICE, 0xc0, 0, 0,
+ transfer_buffer, current_length, 300);
+ if (result > 0)
+ memcpy(device_data, transfer_buffer, current_length);
+ kfree(transfer_buffer);
+
+ return result;
+}
+
+/**
+ * box_set_device
+ * Issue a SET_DEVICE vendor-specific request on the default control pipe If
+ * successful returns the number of bytes written, otherwise it returns a
+ * negative error number of the problem.
+ */
+static int box_set_device(struct usb_serial *serial,
+ struct qt_get_device_data *device_data)
+{
+ int result;
+ __u16 length;
+ __u16 PortSettings;
+
+ PortSettings = ((__u16) (device_data->portb));
+ PortSettings = (PortSettings << 8);
+ PortSettings += ((__u16) (device_data->porta));
+
+ length = sizeof(struct qt_get_device_data);
+ mydbg("%s - PortSettings = 0x%x\n", __func__, PortSettings);
+
+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SET_GET_DEVICE, 0x40, PortSettings,
+ 0, NULL, 0, 300);
+ return result;
+}
+
+/****************************************************************************
+ * BoxOPenCloseChannel
+ * This funciotn notifies the device that the device driver wishes to open a particular UART channel. its
+ * purpose is to allow the device driver and the device to synchronize state information.
+ * OpenClose = 1 for open , 0 for close
+ ****************************************************************************/
+static int BoxOPenCloseChannel(struct usb_serial *serial, __u16 Uart_Number,
+ __u16 OpenClose,
+ struct qt_open_channel_data *pDeviceData)
+{
+ int result;
+ __u16 length;
+ __u8 Direcion;
+ unsigned int pipe;
+ length = sizeof(struct qt_open_channel_data);
+
+ /* if opening... */
+ if (OpenClose == 1) {
+ Direcion = USBD_TRANSFER_DIRECTION_IN;
+ pipe = usb_rcvctrlpipe(serial->dev, 0);
+ result =
+ usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+ Direcion, OpenClose, Uart_Number,
+ pDeviceData, length, 300);
+
+ } else {
+ Direcion = USBD_TRANSFER_DIRECTION_OUT;
+ pipe = usb_sndctrlpipe(serial->dev, 0);
+ result =
+ usb_control_msg(serial->dev, pipe, QT_OPEN_CLOSE_CHANNEL,
+ Direcion, OpenClose, Uart_Number, NULL, 0,
+ 300);
+
+ }
+
+ return result;
+}
+
+/****************************************************************************
+ * BoxSetPrebufferLevel
+ TELLS BOX WHEN TO ASSERT FLOW CONTROL
+ ****************************************************************************/
+static int BoxSetPrebufferLevel(struct usb_serial *serial)
+{
+ int result;
+ __u16 buffer_length;
+
+ buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
+ result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_PREBUF_TRIG_LVL, 0x40,
+ buffer_length, 0, NULL, 0, 300);
+ return result;
+}
+
+/****************************************************************************
+ * BoxSetATC
+ TELLS BOX WHEN TO ASSERT automatic transmitter control
+ ****************************************************************************/
+static int BoxSetATC(struct usb_serial *serial, __u16 n_Mode)
+{
+ int result;
+ __u16 buffer_length;
+
+ buffer_length = PREFUFF_LEVEL_CONSERVATIVE;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SET_ATF, 0x40, n_Mode, 0, NULL, 0, 300);
+
+ return result;
+}
+
+/****************************************************************************
+* BoxSetUart
+* issuse a SET_UART vendor-spcific request on the default control pipe
+* If successful sets baud rate divisor and LCR value
+****************************************************************************/
+static int BoxSetUart(struct usb_serial *serial, unsigned short Uart_Number,
+ unsigned short default_divisor, unsigned char default_LCR)
+{
+ int result;
+ unsigned short UartNumandLCR;
+
+ UartNumandLCR = (default_LCR << 8) + Uart_Number;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_GET_SET_UART, 0x40, default_divisor,
+ UartNumandLCR, NULL, 0, 300);
+
+ return result;
+}
+
+static int BoxSetHW_FlowCtrl(struct usb_serial *serial, unsigned int UartNumber,
+ int bSet)
+{
+ __u8 MCR_Value = 0;
+ __u8 MSR_Value = 0, MOUT_Value = 0;
+ struct usb_serial_port *port;
+ unsigned int status;
+
+ port = serial->port;
+
+ if (bSet == 1) {
+ /* flow control, box will clear RTS line to prevent remote */
+ MCR_Value = SERIAL_MCR_RTS;
+ } /* device from xmitting more chars */
+ else {
+ /* no flow control to remote device */
+ MCR_Value = 0;
+
+ }
+ MOUT_Value = MCR_Value << 8;
+
+ if (bSet == 1) {
+ /* flow control, box will inhibit xmit data if CTS line is
+ * asserted */
+ MSR_Value = SERIAL_MSR_CTS;
+ } else {
+ /* Box will not inhimbe xmit data due to CTS line */
+ MSR_Value = 0;
+ }
+ MOUT_Value |= MSR_Value;
+
+ status =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_HW_FLOW_CONTROL_MASK, 0x40, MOUT_Value,
+ UartNumber, NULL, 0, 300);
+ return status;
+
+}
+
+static int BoxSetSW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber,
+ unsigned char stop_char, unsigned char start_char)
+{
+ __u16 nSWflowout;
+ int result;
+
+ nSWflowout = start_char << 8;
+ nSWflowout = (unsigned short)stop_char;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SW_FLOW_CONTROL_MASK, 0x40, nSWflowout,
+ UartNumber, NULL, 0, 300);
+ return result;
+
+}
+static int BoxDisable_SW_FlowCtrl(struct usb_serial *serial, __u16 UartNumber)
+{
+ int result;
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_SW_FLOW_CONTROL_DISABLE, 0x40, 0, UartNumber,
+ NULL, 0, 300);
+ return result;
+
+}
+
+static void serial_throttle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!serial)
+ return;
+
+ down(&port->sem);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+ /* shut down any bulk reads that may be going on */
+/* usb_unlink_urb (port->read_urb); */
+ /* pass on to the driver specific version of this function */
+ port->RxHolding = 1;
+ mydbg("%s - port->RxHolding = 1\n", __func__);
+
+exit:
+ up(&port->sem);
+ return;
+}
+
+static void serial_unthrottle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ unsigned int result;
+
+ if (!serial)
+ return;
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ if (port->RxHolding == 1) {
+ mydbg("%s -port->RxHolding == 1\n", __func__);
+
+ port->RxHolding = 0;
+ mydbg("%s - port->RxHolding = 0\n", __func__);
+
+ /* if we have a bulk endpoint, start it up */
+ if ((serial->num_bulk_in) && (port->ReadBulkStopped == 1)) {
+ /* Start reading from the device */
+ usb_fill_bulk_urb(port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->
+ bulk_in_endpointAddress),
+ port->read_urb->transfer_buffer,
+ port->read_urb->
+ transfer_buffer_length,
+ qt_read_bulk_callback, port);
+ result = usb_submit_urb(port->read_urb, GFP_ATOMIC);
+ if (result)
+ err("%s - failed restarting read urb, error %d",
+ __func__, result);
+ }
+ }
+exit:
+ up(&port->sem);
+ return;
+
+}
+
+static int serial_break(struct tty_struct *tty, int break_state)
+{
+ struct usb_serial_port *port =
+ (struct usb_serial_port *)tty->driver_data;
+ struct usb_serial *serial = get_usb_serial(port, __func__);
+ __u16 UartNumber, Break_Value;
+ unsigned int result;
+
+ UartNumber = port->tty->index - serial->minor;
+ if (!serial)
+ return -ENODEV;
+
+ if (break_state == -1)
+ Break_Value = 1;
+ else
+ Break_Value = 0;
+
+ down(&port->sem);
+
+ mydbg("%s - port %d\n", __func__, port->number);
+
+ if (!port->open_count) {
+ mydbg("%s - port not open\n", __func__);
+ goto exit;
+ }
+
+ result =
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ QT_BREAK_CONTROL, 0x40, Break_Value, UartNumber,
+ NULL, 0, 300);
+
+exit:
+ up(&port->sem);
+ return 0;
+}
+
+static int ioctl_serial_usb(struct inode *innod, struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+
+ unsigned err;
+ unsigned ucOPR_NewValue, uc_Value;
+ int *p_Num_of_adapters, counts, index, *p_QMCR_Value;
+ struct identity *p_Identity_of;
+ struct identity Identity_of;
+ struct usb_serial *lastserial, *serial;
+
+ mydbg(KERN_DEBUG "ioctl_serial_usb cmd =\n");
+ if (_IOC_TYPE(cmd) != SERIALQT_PCI_IOC_MAGIC)
+ return -ENOTTY;
+ if (_IOC_NR(cmd) > SERIALQT_IOC_MAXNR)
+ return -ENOTTY;
+ mydbg(KERN_DEBUG "ioctl_serial_usb cmd = 0x%x\n", cmd);
+ err = 0;
+ switch (cmd) {
+
+ case SERIALQT_WRITE_QMCR:
+ err = -ENOTTY;
+ index = arg >> 16;
+ counts = 0;
+
+ ucOPR_NewValue = arg;
+
+ err = EmulateWriteQMCR_Reg(index, ucOPR_NewValue);
+ break;
+
+ case SERIALQT_READ_QMCR:
+ err = -ENOTTY;
+ p_QMCR_Value = (int *)arg;
+ index = arg >> 16;
+ counts = 0;
+
+ err = EmulateReadQMCR_Reg(index, &uc_Value);
+ if (err == 0)
+ err = put_user(uc_Value, p_QMCR_Value);
+ break;
+
+ case SERIALQT_GET_NUMOF_UNITS:
+ p_Num_of_adapters = (int *)arg;
+ counts = 0; /* Initialize counts to zero */
+ /* struct usb_serial *lastserial = serial_table[0], *serial; */
+ lastserial = serial_table[0];
+
+ mydbg(KERN_DEBUG "SERIALQT_GET_NUMOF_UNITS \n");
+ /* if first pointer is nonull, we at least have one box */
+ if (lastserial)
+ counts = 1; /* we at least have one box */
+
+ for (index = 1; index < SERIAL_TTY_MINORS; index++) {
+ serial = serial_table[index];
+ if (serial) {
+ if (serial != lastserial) {
+ /* we had a change in the array, hence
+ * another box is there */
+ lastserial = serial;
+ counts++;
+ }
+ } else
+ break;
+ }
+
+ mydbg(KERN_DEBUG "ioctl_serial_usb writting counts = %d",
+ counts);
+
+ err = put_user(counts, p_Num_of_adapters);
+
+ break;
+ case SERIALQT_GET_THIS_UNIT:
+ counts = 0;
+ p_Identity_of = (struct identity *)arg;
+ /* copy user structure to local variable */
+ get_user(Identity_of.index, &p_Identity_of->index);
+ mydbg(KERN_DEBUG "SERIALQT_GET_THIS_UNIT Identity_of.index\n");
+ mydbg(KERN_DEBUG
+ "SERIALQT_GET_THIS_UNIT Identity_of.index= 0x%x\n",
+ Identity_of.index);
+
+ err = -ENOTTY;
+ serial = find_the_box(Identity_of.index);
+ if (serial) {
+ err =
+ put_user(serial->product,
+ &p_Identity_of->n_identity);
+
+ }
+ break;
+
+ case SERIALQT_IS422_EXTENDED:
+ err = -ENOTTY;
+ mydbg(KERN_DEBUG "SERIALQT_IS422_EXTENDED \n");
+ index = arg >> 16;
+
+ counts = 0;
+
+ mydbg(KERN_DEBUG
+ "SERIALQT_IS422_EXTENDED, looking Identity_of.indext = 0x%x\n",
+ index);
+ serial = find_the_box(index);
+ if (serial) {
+ mydbg("%s index = 0x%x, serial = 0x%p\n", __func__,
+ index, serial);
+ for (counts = 0; serqt_422_table[counts] != 0; counts++) {
+
+ mydbg
+ ("%s serial->product = = 0x%x, serqt_422_table[counts] = 0x%x\n",
+ __func__, serial->product,
+ serqt_422_table[counts]);
+ if (serial->product == serqt_422_table[counts]) {
+ err = 0;
+
+ mydbg
+ ("%s found match for 422extended\n",
+ __func__);
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ err = -ENOTTY;
+ }
+
+ mydbg("%s returning err = 0x%x\n", __func__, err);
+ return err;
+}
+
+static struct usb_serial *find_the_box(unsigned int index)
+{
+ struct usb_serial *lastserial, *foundserial, *serial;
+ int counts = 0, index2;
+ lastserial = serial_table[0];
+ foundserial = NULL;
+ for (index2 = 0; index2 < SERIAL_TTY_MINORS; index2++) {
+ serial = serial_table[index2];
+
+ mydbg("%s index = 0x%x, index2 = 0x%x, serial = 0x%p\n",
+ __func__, index, index2, serial);
+
+ if (serial) {
+ /* first see if this is the unit we'er looking for */
+ mydbg
+ ("%s inside if(serial) counts = 0x%x , index = 0x%x\n",
+ __func__, counts, index);
+ if (counts == index) {
+ /* we found the one we're looking for, copythe
+ * product Id to user */
+ mydbg("%s we found the one we're looking for serial = 0x%p\n",
+ __func__, serial);
+ foundserial = serial;
+ break;
+ }
+
+ if (serial != lastserial) {
+ /* when we have a change in the pointer */
+ lastserial = serial;
+ counts++;
+ }
+ } else
+ break; /* no matches */
+ }
+
+ mydbg("%s returning foundserial = 0x%p\n", __func__, foundserial);
+ return foundserial;
+}
+
+static int EmulateWriteQMCR_Reg(int index, unsigned uc_value)
+{
+
+ __u16 ATC_Mode = 0;
+ struct usb_serial *serial;
+ int status;
+ struct qt_get_device_data DeviceData;
+ unsigned uc_temp = 0;
+ mydbg("Inside %s, uc_value = 0x%x\n", __func__, uc_value);
+
+ DeviceData.porta = 0;
+ DeviceData.portb = 0;
+ serial = find_the_box(index);
+ /* Determine Duplex mode */
+ if (!(serial))
+ return -ENOTTY;
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ return status;
+ }
+
+ uc_temp = uc_value & QMCR_HALF_DUPLEX_MASK;
+ switch (uc_temp) {
+ case QMCR_FULL_DUPLEX:
+ DeviceData.porta &= ~DUPMODE_BITS;
+ DeviceData.porta |= FULL_DUPLEX;
+ ATC_Mode = ATC_DISABLED;
+ break;
+ case QMCR_HALF_DUPLEX_RTS:
+ DeviceData.porta &= ~DUPMODE_BITS;
+ DeviceData.porta |= HALF_DUPLEX_RTS;
+ ATC_Mode = ATC_RTS_ENABLED;
+ break;
+ case QMCR_HALF_DUPLEX_DTR:
+ DeviceData.porta &= ~DUPMODE_BITS;
+ DeviceData.porta |= HALF_DUPLEX_DTR;
+ ATC_Mode = ATC_DTR_ENABLED;
+ break;
+ default:
+ break;
+ }
+
+ uc_temp = uc_value & QMCR_CONNECTOR_MASK;
+ switch (uc_temp) {
+ case QMCR_MODEM_CONTROL:
+ DeviceData.portb &= ~LOOPMODE_BITS; /* reset connection bits */
+ DeviceData.portb |= MODEM_CTRL;
+ break;
+ case QMCR_ALL_LOOPBACK:
+ DeviceData.portb &= ~LOOPMODE_BITS; /* reset connection bits */
+ DeviceData.portb |= ALL_LOOPBACK;
+ break;
+ }
+
+ mydbg(__FILE__ "Calling box_set_device with failed\n");
+ status = box_set_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_set_device failed\n");
+ return status;
+ }
+
+ /* This bit (otherwise unused) i'll used to detect whether ATC is
+ * selected */
+ if (uc_value & QMCR_RX_EN_MASK) {
+
+ mydbg(__FILE__
+ "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
+ DeviceData.porta, DeviceData.portb);
+ status = BoxSetATC(serial, ATC_Mode);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetATC failed\n");
+ return status;
+ }
+ } else {
+
+ mydbg(__FILE__
+ "calling BoxsetATC with DeviceData.porta = 0x%x and DeviceData.portb = 0x%x\n",
+ DeviceData.porta, DeviceData.portb);
+ status = BoxSetATC(serial, ATC_DISABLED);
+ if (status < 0) {
+ mydbg(__FILE__ "BoxSetATC failed\n");
+ return status;
+ }
+ }
+
+ return 0;
+
+}
+
+static int EmulateReadQMCR_Reg(int index, unsigned *uc_value)
+{
+ struct usb_serial *serial;
+ int status;
+ struct qt_get_device_data DeviceData;
+ __u8 uc_temp;
+
+ *uc_value = 0;
+
+ serial = find_the_box(index);
+ if (!(serial))
+ return -ENOTTY;
+
+ status = box_get_device(serial, &DeviceData);
+ if (status < 0) {
+ mydbg(__FILE__ "box_get_device failed\n");
+ return status;
+ }
+ uc_temp = DeviceData.porta & DUPMODE_BITS;
+ switch (uc_temp) {
+ case FULL_DUPLEX:
+ *uc_value |= QMCR_FULL_DUPLEX;
+ break;
+ case HALF_DUPLEX_RTS:
+ *uc_value |= QMCR_HALF_DUPLEX_RTS;
+ break;
+ case HALF_DUPLEX_DTR:
+ *uc_value |= QMCR_HALF_DUPLEX_DTR;
+ break;
+ default:
+ break;
+ }
+
+ /* I use this for ATC control se */
+ uc_temp = DeviceData.portb & LOOPMODE_BITS;
+
+ switch (uc_temp) {
+ case ALL_LOOPBACK:
+ *uc_value |= QMCR_ALL_LOOPBACK;
+ break;
+ case MODEM_CTRL:
+ *uc_value |= QMCR_MODEM_CONTROL;
+ break;
+ default:
+ break;
+
+ }
+ return 0;
+
+}
+
+static int __init serqt_usb_init(void)
+{
+ int i, result;
+ int status = 0;
+
+ mydbg("%s\n", __func__);
+ tty_set_operations(&serial_tty_driver, &serial_ops);
+ result = tty_register_driver(&serial_tty_driver);
+ if (result) {
+ mydbg("tty_register_driver failed error = 0x%x", result);
+ return result;
+ }
+
+ /* Initalize our global data */
+ for (i = 0; i < SERIAL_TTY_MINORS; ++i)
+ serial_table[i] = NULL;
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&serqt_usb_driver);
+ if (result < 0) {
+ err("usb_register failed for the " __FILE__
+ " driver. Error number %d", result);
+ return result;
+ }
+ status = 0; /* Dynamic assignment of major number */
+ major_number =
+ register_chrdev(status, "SerialQT_USB", &serialqt_usb_fops);
+ if (major_number < 0) {
+ mydbg(KERN_DEBUG "No devices found \n\n");
+ return -EBUSY;
+ } else
+ mydbg(KERN_DEBUG "SerQT_USB major number assignment = %d \n\n",
+ major_number);
+
+ printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION);
+ return 0;
+}
+
+static void __exit serqt_usb_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&serqt_usb_driver);
+ tty_unregister_driver(&serial_tty_driver);
+ unregister_chrdev(major_number, "SerialQT_USB");
+}
+
+module_init(serqt_usb_init);
+module_exit(serqt_usb_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff --git a/drivers/staging/slicoss/gbdownload.h b/drivers/staging/slicoss/gbdownload.h
deleted file mode 100644
index 794432bd1d7..00000000000
--- a/drivers/staging/slicoss/gbdownload.h
+++ /dev/null
@@ -1,8215 +0,0 @@
-#define MOJAVE_UCODE_VERS_STRING "1.2"
-#define MOJAVE_UCODE_VERS_DATE "2006/03/27 15:12:22"
-#define MOJAVE_UCODE_HOSTIF_ID 3
-
-static s32 MNumSections = 0x2;
-static u32 MSectionSize[] =
-{
- 0x00008000, 0x00010000,
-};
-
-static u32 MSectionStart[] =
-{
- 0x00000000, 0x00008000,
-};
-
-static u8 MojaveUCode[2][65536] =
-{
- {
- 0x12, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
- 0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
- 0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x80, 0x1f, 0xe9, 0x18, 0x31, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe9,
- 0x80, 0xb2, 0x01, 0x00, 0x0f, 0x00, 0x40, 0xe9, 0x80, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x16, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x16, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x0f, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1c, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1c, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x11, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x22, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x22, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xdd, 0x81, 0x01, 0x00, 0x2b, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x3c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x27, 0x00, 0x14, 0xbc,
- 0x80, 0x32, 0x00, 0x00, 0x14, 0x01, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0xb7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xb5, 0xb3, 0x01, 0x00,
- 0xd9, 0x00, 0x00, 0x40, 0xb3, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xb6, 0xd3, 0x01, 0x00, 0x32, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0xe8, 0x80, 0x88, 0x01, 0x00, 0xb8, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00, 0x3c, 0x00, 0x22, 0x50,
- 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00,
- 0xa5, 0xa5, 0x00, 0xa6, 0xb4, 0xa7, 0x01, 0x00, 0x3c, 0x00, 0xa2, 0x50,
- 0xb5, 0x73, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x3c, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0xfd, 0x93, 0x01, 0x00, 0x41, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x7f, 0x00, 0x00, 0x20, 0xf5, 0xcf, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfa,
- 0xb3, 0x33, 0x01, 0x00, 0xa5, 0xa5, 0x00, 0xda, 0xb5, 0xab, 0x01, 0x00,
- 0x99, 0x00, 0xa2, 0x50, 0xb5, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xfd, 0x93, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x44, 0xb3, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xd7, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xed, 0x8b, 0x01, 0x00,
- 0xd5, 0x00, 0x00, 0x46, 0xb3, 0x33, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0xb1, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xda, 0xef, 0x8b, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
- 0xe3, 0x8f, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x48, 0xb3, 0x33, 0x01, 0x00,
- 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
- 0xd7, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xf1, 0xdb, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xda, 0xe9, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xe9, 0xe3, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4b, 0xb3, 0x33, 0x01, 0x00,
- 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xd7, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4c, 0xb3, 0x33, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0xda, 0xeb, 0xdb, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x4e,
- 0xb3, 0x33, 0x01, 0x00, 0x03, 0x00, 0x00, 0xda, 0x81, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x81, 0xe0, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda,
- 0xb5, 0xdb, 0x01, 0x00, 0x5c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0xda, 0xb5, 0xcf, 0x01, 0x00, 0x00, 0xf0, 0x00, 0xa7,
- 0xb4, 0x87, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x81, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd8, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x50,
- 0xb3, 0x33, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda, 0xb5, 0x8b, 0x01, 0x00,
- 0x62, 0x00, 0x26, 0x4c, 0xb5, 0x63, 0x00, 0x00, 0x01, 0x00, 0x00, 0xda,
- 0xb5, 0xcf, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xdf, 0xb1, 0x01, 0x00,
- 0xd5, 0x00, 0x00, 0x52, 0xb3, 0x33, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda,
- 0x4b, 0x89, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xdf, 0xf7, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xef, 0xdf, 0x8b, 0x01, 0x00, 0x69, 0x00, 0x22, 0x40,
- 0xdf, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xfd, 0x93, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xda, 0xd7, 0xe5, 0x01, 0x00, 0xf8, 0x00, 0x00, 0xda,
- 0xb3, 0x8b, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd9, 0xd7, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd9,
- 0xd5, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0xb1, 0x01, 0x00,
- 0x22, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb5, 0xf3, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0xda, 0x7b, 0x89, 0x01, 0x00, 0x00, 0x01, 0x00, 0x40,
- 0xdd, 0x9b, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x5d, 0xb3, 0x33, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0xda, 0xe7, 0x8b, 0x01, 0x00, 0x8a, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xfd, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xe7, 0xe3, 0x01, 0x00, 0x00, 0x01, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xe7, 0x97, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0xd7, 0xb1, 0x01, 0x00, 0xd5, 0x00, 0x00, 0x5e,
- 0xb3, 0x33, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda, 0xe5, 0x8b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xe5, 0xe3, 0x01, 0x00, 0x08, 0x01, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xda, 0xb5, 0x8f, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf7, 0xb5, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xd7, 0xb1, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0xe5, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0xd7, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0xdd, 0x9b, 0x01, 0x00,
- 0x96, 0x00, 0x22, 0xf5, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee, 0xd5, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf6, 0xeb, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5,
- 0xd7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xea, 0xd4, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf7, 0xe3, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1,
- 0xd7, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x00, 0xee, 0xdd, 0xcb, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xee, 0xd5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xe9, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0xd7, 0xb1, 0x01, 0x00,
- 0xd5, 0x00, 0x00, 0x4a, 0xb3, 0x33, 0x01, 0x00, 0xff, 0xff, 0x00, 0xda,
- 0xdd, 0x89, 0x01, 0x00, 0xb7, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0xa6,
- 0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa6,
- 0xd6, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
- 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0xa6,
- 0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
- 0x3c, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
- 0xd7, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0x93, 0x01, 0x00,
- 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa6,
- 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x01, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
- 0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa6,
- 0xd6, 0xb1, 0x01, 0x00, 0x9a, 0x13, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
- 0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa6,
- 0xd6, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xeb, 0xd6, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xdf, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa6, 0xd6, 0xb1, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
- 0x4b, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0x99, 0x01, 0x00,
- 0x02, 0x04, 0x00, 0x40, 0xdd, 0x99, 0x01, 0x00, 0xb7, 0x00, 0x13, 0xbc,
- 0x80, 0x32, 0x00, 0x00, 0x02, 0x08, 0x00, 0x40, 0xdd, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x01, 0x00, 0xb8, 0x00, 0x95, 0xe8,
- 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
- 0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0xb8, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0xb8, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x81, 0xb0, 0x01, 0x00, 0xca, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
- 0xc8, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0xd4, 0x00, 0x1f, 0xfd,
- 0xf9, 0x33, 0x00, 0x00, 0xc7, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
- 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x19, 0xb1, 0x01, 0x00, 0xcf, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
- 0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0xd3, 0x00, 0xa2, 0xff,
- 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0xd8, 0x00, 0x06, 0xfe, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xb3, 0xe3, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfa, 0xb3, 0xc3, 0x00, 0x00,
- 0xda, 0x00, 0x00, 0x42, 0x8d, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0xeb, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x84, 0x96, 0x80, 0xb2, 0x00, 0x00,
- 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
- 0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0x81, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xb5, 0xeb, 0x01, 0x00, 0xe4, 0x00, 0x84, 0x96,
- 0x80, 0x32, 0x00, 0x00, 0xe5, 0x00, 0x00, 0x40, 0xb5, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xb5, 0x83, 0x01, 0x00, 0xde, 0x00, 0xa2, 0x41,
- 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2d, 0x81, 0x01, 0x00,
- 0x26, 0x01, 0x00, 0x41, 0x2d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xb3, 0xc3, 0x01, 0x00, 0xda, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0xda, 0xb5, 0xbf, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x81, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd9, 0xb9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xb8, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xb9, 0xeb, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xb8, 0x97, 0x01, 0x00, 0x15, 0x00, 0x00, 0xdc,
- 0xb9, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2d, 0x81, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xdb, 0x81, 0xb0, 0x01, 0x00, 0x27, 0x01, 0x00, 0x42,
- 0x2d, 0x11, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40, 0x2d, 0x11, 0x01, 0x00,
- 0x28, 0x01, 0x00, 0x40, 0x2d, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x2d, 0x91, 0x01, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x25, 0x01, 0x00, 0x40, 0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x2d, 0x81, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x81, 0xd0, 0x00, 0x00,
- 0x00, 0x00, 0x84, 0x96, 0x80, 0x32, 0x01, 0x00, 0xff, 0x00, 0xa0, 0xdc,
- 0xb9, 0x6b, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x41, 0x2d, 0x91, 0x00, 0x00,
- 0xf8, 0x00, 0x00, 0x41, 0x2d, 0x81, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x40,
- 0xb3, 0x33, 0x01, 0x00, 0x00, 0x00, 0x90, 0xda, 0x8b, 0xb0, 0x00, 0x00,
- 0x11, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x40, 0x00, 0x00, 0x44,
- 0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0xa3, 0x44, 0x89, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x89, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0xb0, 0x01, 0x00,
- 0xd9, 0x00, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xb5, 0xf3, 0x01, 0x00, 0x0c, 0x01, 0xa0, 0xda, 0x8b, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x87, 0xc0, 0x01, 0x00, 0x08, 0x01, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00, 0x10, 0x00, 0x00, 0x45,
- 0x8a, 0xf4, 0x01, 0x00, 0x12, 0x01, 0x90, 0x44, 0x8a, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x45,
- 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50, 0x8b, 0xe0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x40, 0xf9, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x40,
- 0xb3, 0xcf, 0x01, 0x00, 0x1c, 0x01, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
- 0x1c, 0x01, 0x40, 0xda, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x41, 0xda,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00,
- 0x16, 0x01, 0x9f, 0xda, 0x81, 0x32, 0x00, 0x00, 0x02, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x91, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x1e, 0x01, 0x9f, 0x94,
- 0x80, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0x94, 0x92, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xb5, 0xf3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xb4, 0x97, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xb3, 0xc3, 0x01, 0x00,
- 0x1d, 0x01, 0xa2, 0x41, 0x91, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x2b, 0xb1, 0x01, 0x00, 0x29, 0x01, 0x00, 0x51, 0x93, 0xb0, 0x00, 0x00,
- 0x29, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00, 0x29, 0x01, 0x00, 0x49,
- 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x93, 0xb0, 0x01, 0x00,
- 0x29, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x12, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x15, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x18, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x01, 0xb0, 0x01, 0x00, 0x44, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x50, 0x01, 0x22, 0x4b,
- 0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
- 0x7e, 0xb1, 0x01, 0x00, 0x51, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x4e, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x80, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00,
- 0xf3, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xa5, 0xb3, 0x01, 0x00, 0xaf, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00,
- 0x5f, 0x01, 0x22, 0xcc, 0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
- 0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
- 0xa3, 0xc9, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
- 0xe1, 0xb1, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0x68, 0x01, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00,
- 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xbc, 0xb3, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
- 0xa9, 0xb3, 0x01, 0x00, 0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x40, 0x80, 0xf4, 0x01, 0x00, 0x78, 0x01, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x88, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x91, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd2, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xe1, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x80, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf1, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf2, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x77, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x1a, 0x00,
- 0x5a, 0x01, 0x51, 0x40, 0x81, 0xb2, 0x1a, 0x00, 0x5a, 0x01, 0x52, 0x40,
- 0x81, 0xb2, 0x1a, 0x00, 0x5a, 0x01, 0x55, 0x40, 0x81, 0xb2, 0x1a, 0x00,
- 0x5a, 0x01, 0x56, 0x40, 0x81, 0xb2, 0x1a, 0x00, 0x55, 0x01, 0x91, 0x81,
- 0x80, 0x30, 0x1a, 0x00, 0x5a, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x1a, 0x00,
- 0x55, 0x01, 0x91, 0x82, 0x80, 0x30, 0x1a, 0x00, 0x5a, 0x01, 0x46, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0xb5, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x81, 0xc0, 0x01, 0x00, 0x94, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x49, 0xd1, 0x01, 0x00, 0x9c, 0x01, 0x22, 0x40,
- 0xe1, 0x6d, 0x00, 0x00, 0x98, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x55, 0x01, 0x00, 0x41, 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xbf, 0xb3, 0x01, 0x00, 0x55, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xde, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x49, 0xc1, 0x01, 0x00, 0xb7, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x42, 0xff, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0xff, 0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4,
- 0x80, 0xcc, 0x01, 0x00, 0xac, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00, 0xaa, 0x01, 0xa2, 0x4c,
- 0x81, 0x50, 0x00, 0x00, 0xb6, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00,
- 0xb1, 0x01, 0x22, 0x41, 0xa5, 0x6f, 0x00, 0x00, 0x55, 0x01, 0xa2, 0xe0,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42,
- 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x88, 0x94, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x44,
- 0xe0, 0xb1, 0x00, 0x00, 0xb3, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00,
- 0xb1, 0x01, 0x00, 0x5b, 0x89, 0x90, 0x00, 0x00, 0xb0, 0x9f, 0x00, 0xa0,
- 0x9e, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xba, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xc4, 0x01, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40,
- 0x80, 0xce, 0x01, 0x00, 0xc3, 0x01, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xc4, 0x01, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
- 0x6f, 0x93, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x52, 0x6f, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xc7, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xd1, 0x01, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
- 0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0xd0, 0x01, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd1, 0x01, 0x55, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x6f, 0x93, 0x01, 0x00,
- 0xf3, 0x9f, 0x00, 0x53, 0x6f, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00, 0xda, 0x01, 0x22, 0xde,
- 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xd5, 0x01, 0xa2, 0x44,
- 0x81, 0x6c, 0x00, 0x00, 0x55, 0x01, 0x00, 0x43, 0xbf, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf8,
- 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x40, 0xe1, 0xb1, 0x00, 0x00,
- 0xe2, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x08, 0x00, 0x00, 0xdd,
- 0x81, 0xf4, 0x01, 0x00, 0xe7, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00, 0xed, 0x01, 0x00, 0x40,
- 0x81, 0xb0, 0x00, 0x00, 0x58, 0x01, 0x00, 0xde, 0xa1, 0xb3, 0x00, 0x00,
- 0xff, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x02, 0x00, 0x40,
- 0x81, 0xb0, 0x00, 0x00, 0x07, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x57, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
- 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
- 0xf7, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00, 0xf6, 0x01, 0x84, 0x41,
- 0x81, 0x40, 0x00, 0x00, 0xfa, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00, 0xf1, 0x01, 0x00, 0x41,
- 0xa1, 0xc1, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x5a, 0x01, 0x00, 0xdd,
- 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00, 0xb1, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00,
- 0xc5, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x40,
- 0xa3, 0x9b, 0x01, 0x00, 0x58, 0x01, 0x00, 0xde, 0xa1, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0x81, 0x90, 0x01, 0x00, 0x55, 0x01, 0xa2, 0xba, 0x80, 0x04, 0x00, 0x00,
- 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00, 0x04, 0x02, 0xa8, 0xb1,
- 0x80, 0x30, 0x00, 0x00, 0x57, 0x01, 0x00, 0x40, 0xe0, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x68, 0x02, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0x4d, 0x83, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe5, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf5, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf9, 0xb3, 0x01, 0x00, 0x15, 0x02, 0x22, 0x40, 0x8f, 0x6f, 0x00, 0x00,
- 0x75, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0xc7,
- 0x83, 0x30, 0x01, 0x00, 0x7d, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x5d, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xed,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2, 0xf0, 0xb1, 0x01, 0x00,
- 0xe0, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xab, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xba, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb,
- 0xf0, 0xb1, 0x01, 0x00, 0x29, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0x90, 0x01, 0x00, 0x2b, 0x02, 0xb9, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00,
- 0x2d, 0x02, 0xba, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x81, 0x90, 0x01, 0x00, 0x2f, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x81, 0x90, 0x01, 0x00, 0x31, 0x02, 0xbc, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00,
- 0x33, 0x02, 0xbd, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x81, 0x90, 0x01, 0x00, 0x35, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x81, 0x90, 0x01, 0x00, 0x37, 0x02, 0xbf, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00,
- 0x39, 0x02, 0xc8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x81, 0x90, 0x01, 0x00, 0x3b, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x81, 0x90, 0x01, 0x00, 0x3d, 0x02, 0xca, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00,
- 0x3f, 0x02, 0xcb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x81, 0x90, 0x01, 0x00, 0x41, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x81, 0x90, 0x01, 0x00, 0x43, 0x02, 0xcd, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00,
- 0x45, 0x02, 0xce, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x81, 0x90, 0x01, 0x00, 0x47, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
- 0xaf, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
- 0xf7, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x63, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x60, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5c, 0x02, 0x49, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x65, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x5c, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
- 0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
- 0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
- 0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
- 0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
- 0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
- 0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
- 0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
- 0x81, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x85, 0x02, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
- 0x8a, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x95, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x95, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
- 0x98, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9e, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xbc, 0x02, 0x00, 0x42,
- 0xa5, 0x63, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x94, 0x02, 0x22, 0x44,
- 0xa5, 0x53, 0x00, 0x00, 0x91, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
- 0x5a, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xbc, 0x02, 0x00, 0xde,
- 0xa1, 0x33, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xbf, 0xb3, 0x01, 0x00, 0x55, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0x63, 0xb1, 0x01, 0x00, 0x9b, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbc, 0x02, 0x00, 0x54,
- 0xa5, 0x33, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
- 0xa9, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x5d, 0x02, 0x00, 0x46,
- 0x83, 0x30, 0x01, 0x00, 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
- 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
- 0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
- 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xe1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
- 0x62, 0xdd, 0x01, 0x00, 0xb9, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
- 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
- 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
- 0xb8, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
- 0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
- 0xc7, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xc6, 0x02, 0xa2, 0xf2,
- 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0xcb, 0x02, 0x80, 0xa5,
- 0x80, 0x32, 0x00, 0x00, 0xcc, 0x02, 0x00, 0xa5, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xcd, 0x02, 0x80, 0xa5,
- 0x80, 0x32, 0x00, 0x00, 0x80, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0xd6, 0x02, 0x20, 0x4f, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0xd6, 0x02, 0x20, 0x4b, 0x81, 0x6c, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xd6, 0x02, 0x20, 0x47,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x03, 0x90, 0x00, 0x41,
- 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x00, 0x14, 0x2f, 0x4c, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xda, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0xa5, 0x80, 0xc8, 0x01, 0x00, 0xdd, 0x02, 0xa2, 0xa5,
- 0x80, 0x6c, 0x00, 0x00, 0x20, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe0, 0x02, 0x1f, 0x91,
- 0x80, 0x32, 0x00, 0x00, 0x30, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe3, 0x02, 0x1f, 0x91,
- 0x80, 0x32, 0x00, 0x00, 0x70, 0x00, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xe6, 0x02, 0x1f, 0x91,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00,
- 0xe8, 0x02, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00, 0x40, 0x68, 0x00, 0x90,
- 0x20, 0xa9, 0x01, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x21, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x22, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x23, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x24, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x25, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x26, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x27, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x02, 0x01, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0x04, 0x03, 0x00, 0x40,
- 0x80, 0x98, 0x01, 0x00, 0x06, 0x05, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x08, 0x07, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe0, 0xb1, 0x01, 0x00,
- 0x30, 0x03, 0x00, 0x40, 0x85, 0x30, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xff, 0x02, 0xa2, 0xf8, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x22, 0xf0,
- 0x82, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x21, 0x91, 0x01, 0x00,
- 0xd0, 0x14, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x0c,
- 0x85, 0x30, 0x01, 0x00, 0x30, 0x03, 0x00, 0x4d, 0x85, 0x10, 0x01, 0x00,
- 0x30, 0x03, 0x00, 0x4e, 0x85, 0x10, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x4f,
- 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x4f, 0x85, 0x10, 0x01, 0x00,
- 0x39, 0x03, 0x00, 0x0c, 0x85, 0x30, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x43,
- 0x81, 0xb0, 0x01, 0x00, 0x0f, 0x03, 0x22, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
- 0x39, 0x03, 0x00, 0x4d, 0x85, 0x10, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x42,
- 0x81, 0xb0, 0x01, 0x00, 0x0f, 0x03, 0x22, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
- 0x39, 0x03, 0x00, 0x4e, 0x85, 0x10, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x41,
- 0x81, 0xb0, 0x01, 0x00, 0x11, 0x03, 0xa2, 0xf0, 0x9e, 0x6e, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x20, 0x95, 0x01, 0x00, 0x03, 0x00, 0x00, 0x90, 0x20, 0x8d, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x21, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x89, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x30, 0x03, 0x00, 0x17, 0x85, 0x30, 0x01, 0x00, 0x30, 0x03, 0x00, 0x58,
- 0x85, 0x10, 0x01, 0x00, 0x30, 0x03, 0x00, 0x59, 0x85, 0x10, 0x01, 0x00,
- 0xd0, 0x14, 0x20, 0x4f, 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x03, 0x00, 0x5a,
- 0x85, 0x10, 0x01, 0x00, 0x39, 0x03, 0x00, 0x17, 0x85, 0x30, 0x01, 0x00,
- 0xd8, 0x14, 0x20, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x23, 0x03, 0x22, 0xf0,
- 0x9e, 0x6e, 0x00, 0x00, 0x39, 0x03, 0x00, 0x58, 0x85, 0x10, 0x01, 0x00,
- 0xd8, 0x14, 0x20, 0x41, 0x81, 0xb0, 0x01, 0x00, 0x23, 0x03, 0x22, 0xf0,
- 0x9e, 0x6e, 0x00, 0x00, 0x39, 0x03, 0x00, 0x59, 0x85, 0x10, 0x01, 0x00,
- 0xd8, 0x14, 0x20, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x27, 0x03, 0xa2, 0xf0,
- 0x9e, 0x6e, 0x00, 0x00, 0x03, 0x00, 0x00, 0x90, 0x20, 0x8d, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x20, 0x95, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x88, 0xe0, 0x01, 0x00,
- 0x2f, 0x03, 0xa2, 0x42, 0x21, 0x7d, 0x00, 0x00, 0xa5, 0xa5, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0xd0, 0x14, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00,
- 0x30, 0x03, 0x00, 0x44, 0x84, 0x30, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x20, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x2f, 0x03, 0xa2, 0xf0, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x89, 0xe0, 0x01, 0x00, 0xe0, 0x00, 0x80, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x70, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0xd0, 0x14, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x87, 0xb4, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00, 0x36, 0x03, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x41, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x70, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xf1, 0xb1, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x87, 0xb4, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00, 0x3f, 0x03, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x87, 0xb0, 0x01, 0x00,
- 0x42, 0x03, 0xa2, 0x41, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf2,
- 0x86, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf1, 0x86, 0xf4, 0x01, 0x00,
- 0x41, 0x03, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x84, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x8f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00, 0x49, 0x03, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xf5, 0x9f, 0x00, 0x47, 0x98, 0x30, 0x01, 0x00,
- 0x00, 0x08, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00, 0x47, 0x03, 0x00, 0x5c,
- 0x8f, 0x80, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x58, 0x15, 0x2d, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0,
- 0x88, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45,
- 0x82, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x82, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00, 0x64, 0x03, 0x22, 0x5f,
- 0x8d, 0x6c, 0x00, 0x00, 0x55, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x53, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40,
- 0x85, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43,
- 0x86, 0xd8, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00,
- 0x60, 0x03, 0x00, 0x41, 0x83, 0xe0, 0x00, 0x00, 0x5e, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00,
- 0xd0, 0x14, 0x2f, 0x46, 0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42,
- 0x60, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45,
- 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00,
- 0x00, 0x04, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0x6f, 0x03, 0xa0, 0x41,
- 0x81, 0x50, 0x00, 0x00, 0x6d, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x41, 0x8e, 0xc0, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40,
- 0xa3, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0xb0, 0x01, 0x00,
- 0x60, 0x15, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
- 0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x41, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x40, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0xa3, 0x55, 0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xa3, 0xc1, 0x01, 0x00, 0x73, 0x03, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x7e, 0x03, 0xa2, 0x41,
- 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0x44, 0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x08, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x16, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43,
- 0x62, 0x99, 0x01, 0x00, 0x88, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x8a, 0x03, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x8b, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x83, 0x03, 0xa2, 0x41,
- 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf7, 0x0f, 0x00, 0xbc,
- 0x80, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- },
- {
- 0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
- 0x80, 0x32, 0x00, 0x00, 0xe6, 0x89, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
- 0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
- 0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
- 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xe6, 0x89, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
- 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
- 0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
- 0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
- 0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
- 0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
- 0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x1b, 0x84, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x1b, 0x84, 0x05, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0xe1, 0x80, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0xde, 0xb2, 0x01, 0x00, 0x77, 0x00, 0x00, 0x40, 0x4b, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x9b, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00, 0xde, 0x99, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x06, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x05, 0x18, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x09, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x50, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7b, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xe0, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x10, 0x84, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x84, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x1a, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x71, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x00, 0x00, 0x97,
- 0x80, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2e, 0xb1, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x40, 0x2e, 0xdd, 0x01, 0x00, 0x90, 0x01, 0x00, 0x40,
- 0x93, 0x98, 0x01, 0x00, 0x29, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x5c, 0x81, 0x00, 0x40, 0xaf, 0x33, 0x01, 0x00, 0x61, 0x99, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x49, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x77, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x00, 0x00,
- 0x71, 0x80, 0x51, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x80, 0x52, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x73, 0x80, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x74, 0x80, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x01, 0x91, 0x81,
- 0x80, 0x30, 0x00, 0x00, 0x5a, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x55, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00, 0x5a, 0x01, 0x46, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
- 0x5a, 0x01, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x49,
- 0xfd, 0x83, 0x00, 0x00, 0x5a, 0x01, 0x00, 0x4a, 0xfd, 0x83, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
- 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00,
- 0x7c, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
- 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x84, 0x80, 0xa2, 0x41,
- 0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04,
- 0x80, 0x94, 0x00, 0x00, 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03,
- 0x02, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xcb, 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc,
- 0xf3, 0x83, 0x01, 0x00, 0x8e, 0x80, 0xa2, 0x41, 0x97, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xcb, 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
- 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa1, 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
- 0x95, 0x80, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc6, 0x02, 0x00, 0x20,
- 0x42, 0x31, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0xcb, 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41,
- 0x8b, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x9b, 0x80, 0xa8, 0xb1, 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x9d, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00,
- 0xa3, 0x80, 0x14, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6,
- 0x83, 0xf4, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00,
- 0x7f, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6,
- 0x81, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00,
- 0x7f, 0x80, 0x1f, 0x5c, 0x97, 0x53, 0x00, 0x00, 0x9e, 0x83, 0x1d, 0xc6,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x43, 0x81, 0xf0, 0x01, 0x00,
- 0xa9, 0x80, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00, 0x05, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xda, 0x81, 0x00, 0xca, 0x63, 0xb3, 0x00, 0x00, 0x2d, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x14, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00,
- 0x1e, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00, 0x0d, 0x81, 0x00, 0x40,
- 0x85, 0xb0, 0x00, 0x00, 0x14, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00,
- 0xf0, 0x80, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0x91, 0x81, 0x00, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0x3d, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
- 0x8d, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0d, 0x81, 0x00, 0x40,
- 0x85, 0xb0, 0x00, 0x00, 0xdd, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
- 0x6a, 0x84, 0x00, 0xca, 0x9b, 0xb3, 0x00, 0x00, 0x46, 0x81, 0x00, 0x40,
- 0xc1, 0xb1, 0x00, 0x00, 0x4e, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
- 0x55, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x56, 0x81, 0x00, 0x40,
- 0xc1, 0xb1, 0x00, 0x00, 0x57, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
- 0x58, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x59, 0x81, 0x00, 0x40,
- 0x81, 0xb0, 0x00, 0x00, 0x59, 0x81, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00,
- 0xce, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x83, 0x00, 0xbb,
- 0xab, 0xb3, 0x00, 0x00, 0xdb, 0x81, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
- 0xd3, 0x80, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xdf, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xdc, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xda, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0x77, 0xb3, 0x00, 0x00,
- 0x15, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00, 0x1c, 0x81, 0x00, 0x4e,
- 0x61, 0xb1, 0x00, 0x00, 0x0d, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
- 0x15, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00, 0x0d, 0x81, 0x00, 0xbb,
- 0x85, 0xb0, 0x00, 0x00, 0xf0, 0x80, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
- 0xe2, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca,
- 0x4d, 0xb3, 0x00, 0x00, 0x64, 0x82, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
- 0x8f, 0x82, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xc8, 0x14, 0x2e, 0xbb,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2,
- 0xa0, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
- 0x75, 0x80, 0x00, 0xca, 0xa7, 0x33, 0x01, 0x00, 0x02, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x4e, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
- 0x4e, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x4e, 0x01, 0x00, 0x4c,
- 0x93, 0x30, 0x01, 0x00, 0x08, 0x84, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xe8, 0x80, 0x22, 0x42,
- 0x8f, 0x6f, 0x00, 0x00, 0xea, 0x80, 0x22, 0x41, 0x8f, 0x6f, 0x00, 0x00,
- 0xec, 0x80, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xee, 0x80, 0x1f, 0xca,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
- 0x6a, 0x84, 0x00, 0x42, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xcd, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x41, 0x8f, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40,
- 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
- 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
- 0xc6, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00,
- 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0x10, 0x00, 0x2f, 0x9c,
- 0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40, 0x39, 0x33, 0x01, 0x00,
- 0x18, 0x00, 0x2f, 0x9b, 0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40,
- 0x37, 0x33, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x9a, 0x89, 0xb0, 0x01, 0x00,
- 0x07, 0x81, 0x00, 0x40, 0x35, 0x33, 0x01, 0x00, 0x08, 0x00, 0x2f, 0x99,
- 0x89, 0xb0, 0x01, 0x00, 0x07, 0x81, 0x00, 0x40, 0x33, 0x33, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0xae, 0x47, 0xc9, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40,
- 0xe1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0xae, 0x63, 0xdd, 0x01, 0x00, 0x02, 0x81, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xff, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x02, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x69, 0x93, 0x01, 0x00, 0x6a, 0x84, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00,
- 0x05, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x81, 0xa2, 0x40,
- 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0xe1, 0xd1, 0x01, 0x00, 0x0d, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x11, 0x81, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x0e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0x11, 0x81, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x6a, 0x84, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x16, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x16, 0x81, 0x00, 0xbb,
- 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x60, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x17, 0x81, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
- 0x6a, 0x84, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x19, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x1f, 0x81, 0x00, 0xbb, 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40,
- 0x87, 0xb0, 0x01, 0x00, 0x21, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00,
- 0x6a, 0x84, 0x60, 0x40, 0x95, 0x83, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xf0,
- 0x84, 0xb0, 0x01, 0x00, 0x22, 0x81, 0x36, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x23, 0x81, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00,
- 0x25, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0x63, 0xb1, 0x01, 0x00, 0x27, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x41,
- 0x43, 0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0xca, 0x95, 0xcb, 0x01, 0x00,
- 0x22, 0x81, 0x00, 0x41, 0x85, 0xc0, 0x00, 0x00, 0x2f, 0x81, 0xa2, 0x42,
- 0x67, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00,
- 0x2f, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x65, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0xca, 0x69, 0x97, 0x01, 0x00, 0x6a, 0x84, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x34, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x6a, 0x84, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0x6a, 0x84, 0x20, 0x43,
- 0x95, 0x6f, 0x00, 0x00, 0x6a, 0x84, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00,
- 0x6a, 0x84, 0x22, 0x40, 0x65, 0x6f, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x6f,
- 0xdb, 0x91, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x35, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x93, 0x01, 0x00,
- 0x42, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x95, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xc3, 0xb1, 0x01, 0x00, 0x45, 0x81, 0x22, 0x5b, 0x95, 0x7f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x49, 0x81, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
- 0x1b, 0xf5, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00, 0x4a, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0x7f, 0xb3, 0x01, 0x00, 0x26, 0x01, 0x00, 0xca,
- 0xc5, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00,
- 0x6a, 0x84, 0x00, 0xca, 0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca,
- 0x95, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xc7, 0xb1, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x5f,
- 0x95, 0x7f, 0x00, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca,
- 0xc7, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00,
- 0x6a, 0x84, 0x00, 0xca, 0xcb, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca,
- 0xcd, 0xb1, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x42, 0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40,
- 0x48, 0xc9, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x5e, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x60, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00,
- 0x62, 0x81, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x61, 0x81, 0xa2, 0x4f,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
- 0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
- 0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
- 0x75, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x72, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
- 0x7e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
- 0x7a, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x21, 0xb3, 0x01, 0x00, 0x7e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
- 0x86, 0x98, 0x01, 0x00, 0x7e, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x7f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x87, 0x81, 0x22, 0x43,
- 0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x84, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
- 0x8c, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
- 0x89, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0x8c, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00,
- 0x8f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
- 0x08, 0xb1, 0x00, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
- 0x92, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x87, 0xb0, 0x01, 0x00, 0xa1, 0x81, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00,
- 0xb0, 0x81, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb8, 0x81, 0x22, 0x4a, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x87, 0x90, 0x01, 0x00, 0x9c, 0x81, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00, 0x9e, 0x81, 0x22, 0x4f,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00,
- 0xa0, 0x81, 0x22, 0x4e, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x87, 0x90, 0x01, 0x00, 0xb8, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x81, 0x22, 0x42,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
- 0x1c, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xab, 0x81, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00, 0xad, 0x81, 0x22, 0x44,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00,
- 0xaf, 0x81, 0x22, 0x43, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x87, 0x90, 0x01, 0x00, 0xb8, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0xc9, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x81, 0x22, 0x42,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x87, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0xc9, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbc, 0x81, 0x22, 0x4b,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xaf, 0xb3, 0x01, 0x00, 0xc5, 0x81, 0x22, 0x40, 0x87, 0x7c, 0x00, 0x00,
- 0xc5, 0x81, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xae, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb3, 0x01, 0x00,
- 0xc4, 0x81, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00, 0xc5, 0x81, 0x00, 0x0b,
- 0x7d, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x7d, 0xb3, 0x01, 0x00,
- 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xa5, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xca, 0xa7, 0x33, 0x01, 0x00,
- 0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0x41,
- 0x82, 0xdc, 0x01, 0x00, 0xca, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0xcc, 0x81, 0x9f, 0x85,
- 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xd1, 0x81, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00, 0xd1, 0x81, 0xa2, 0x49,
- 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00,
- 0xd4, 0x81, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00, 0xd4, 0x81, 0xa2, 0x4a,
- 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00,
- 0xd6, 0x81, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00, 0xd8, 0x81, 0x42, 0x40,
- 0xf1, 0x33, 0x00, 0x00, 0x04, 0x81, 0x00, 0x40, 0x68, 0x97, 0x00, 0x00,
- 0x6a, 0x84, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xbb,
- 0xb1, 0xb3, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2,
- 0xa0, 0x8b, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
- 0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
- 0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x43,
- 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xa5, 0xc3, 0x01, 0x00, 0xf8, 0x81, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
- 0xf8, 0x81, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xe7, 0x81, 0xa2, 0x50,
- 0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb,
- 0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
- 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
- 0xf5, 0x81, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf4, 0x81, 0xa2, 0xf2,
- 0x80, 0x30, 0x00, 0x00, 0xe7, 0x81, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
- 0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd9, 0x00, 0x00, 0x41,
- 0xb3, 0x73, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50, 0xb5, 0xf3, 0x01, 0x00,
- 0xd8, 0x00, 0x00, 0x41, 0xb3, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9,
- 0xb3, 0xfb, 0x01, 0x00, 0x00, 0x30, 0x00, 0xa6, 0xb8, 0xb3, 0x01, 0x00,
- 0xf2, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x42,
- 0x2d, 0x01, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0xeb, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x81, 0xb0, 0x01, 0x00, 0x26, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x09, 0x82, 0x10, 0xda, 0xb5, 0x6b, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x41,
- 0x2d, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2d, 0x91, 0x01, 0x00,
- 0x28, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
- 0x2d, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0x81, 0x01, 0x00,
- 0x06, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x26, 0x01, 0x00, 0x42,
- 0x2d, 0x01, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x26, 0x01, 0x00, 0x42, 0x2d, 0x11, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
- 0x2d, 0x11, 0x01, 0x00, 0x15, 0x82, 0x04, 0x40, 0x2d, 0x01, 0x00, 0x00,
- 0x25, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x11, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x28, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x25, 0x01, 0x00, 0x42, 0x2d, 0x01, 0x01, 0x00, 0xf2, 0x00, 0x00, 0x40,
- 0xb9, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x2d, 0x81, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x41, 0x2d, 0x81, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x18, 0xb1, 0x01, 0x00, 0x1f, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x29, 0x82, 0xa2, 0x54,
- 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x30, 0x82, 0xa2, 0x06,
- 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x07, 0x91, 0xb0, 0x01, 0x00, 0xe1, 0x80, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x39, 0x82, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x3a, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xf5, 0xb1, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x42,
- 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
- 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
- 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x8f, 0xb0, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x48, 0xb2, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
- 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x91, 0xc0, 0x01, 0x00,
- 0x45, 0x82, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x16, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x91, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda, 0x8f, 0xb0, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda, 0xfd, 0xb1, 0x01, 0x00,
- 0x6f, 0x82, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x82, 0x22, 0x45,
- 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x08, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xfe, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6d, 0x82, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0x72, 0x82, 0x22, 0x20,
- 0xb5, 0x6f, 0x00, 0x00, 0x6f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xdb, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x72, 0x82, 0x22, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x6f, 0x82, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x04, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x46, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x48, 0x00, 0x00, 0x40,
- 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x97, 0xb0, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00, 0x85, 0x82, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
- 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xa7, 0xb3, 0x01, 0x00, 0x75, 0x80, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
- 0x02, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa7, 0x82, 0x22, 0x45,
- 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
- 0x96, 0x82, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x83, 0xb0, 0x01, 0x00, 0x99, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x98, 0x82, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00, 0xe1, 0x80, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x9f, 0x82, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0xa0, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xa7, 0x82, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
- 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0xa7, 0x82, 0xa2, 0xfa,
- 0xb4, 0x6f, 0x00, 0x00, 0xfc, 0x81, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
- 0xaa, 0x82, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0xa7, 0x82, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00,
- 0x04, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
- 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb4, 0xb3, 0x01, 0x00,
- 0xb8, 0x82, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0xfc, 0x15, 0x20, 0x20,
- 0xe1, 0xb1, 0x01, 0x00, 0xbd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xdb, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbd, 0x82, 0x22, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0xba, 0x82, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x04, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xc2, 0x82, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xff, 0x81, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00, 0x08, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
- 0xb4, 0x8b, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
- 0xb4, 0xf7, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd8, 0x82, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00, 0xd9, 0x82, 0x00, 0x50,
- 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xb5, 0xb3, 0x01, 0x00,
- 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
- 0xe7, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
- 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0xea, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
- 0xed, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
- 0x95, 0x98, 0x01, 0x00, 0x00, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0xf3, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x83, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
- 0xff, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
- 0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
- 0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
- 0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
- 0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
- 0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
- 0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf7, 0xb1, 0x01, 0x00, 0x0d, 0x83, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
- 0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
- 0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
- 0x16, 0x83, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
- 0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
- 0x33, 0x83, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
- 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
- 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
- 0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
- 0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
- 0x3d, 0x83, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x4c, 0x83, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
- 0x80, 0xce, 0x01, 0x00, 0x42, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x89, 0xa4, 0x01, 0x00, 0x4c, 0x83, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
- 0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x3f, 0x83, 0xaa, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
- 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x4c, 0x83, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x53, 0x83, 0xa3, 0x53,
- 0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
- 0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
- 0x58, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
- 0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
- 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
- 0x80, 0xce, 0x01, 0x00, 0x5d, 0x83, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x60, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
- 0x1f, 0x83, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
- 0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
- 0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
- 0x13, 0x83, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x9d, 0x83, 0xa2, 0x4b, 0xb7, 0x6f, 0x00, 0x00,
- 0x9d, 0x83, 0xa2, 0x41, 0x2f, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x35, 0x82, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x9c, 0x83, 0x22, 0x40,
- 0x8f, 0x6c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0xfe, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xdb, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x9c, 0x83, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x7c, 0x16, 0x20, 0xf6,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x31, 0xb3, 0x01, 0x00,
- 0x80, 0x83, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51,
- 0xfd, 0x93, 0x01, 0x00, 0x82, 0x83, 0x22, 0x40, 0x8f, 0x7c, 0x00, 0x00,
- 0x86, 0x83, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00, 0x84, 0x83, 0x22, 0x42,
- 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0xfd, 0x93, 0x01, 0x00,
- 0x86, 0x83, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53,
- 0xfd, 0x93, 0x01, 0x00, 0x9a, 0x83, 0x22, 0x51, 0xfd, 0x7f, 0x00, 0x00,
- 0x34, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x95, 0x83, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x48, 0x96, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x4b,
- 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x99, 0x83, 0x22, 0x40,
- 0xb5, 0x6f, 0x00, 0x00, 0x9d, 0x83, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xfe,
- 0x7f, 0xd9, 0x01, 0x00, 0x9d, 0x83, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0x41, 0x99, 0xb3, 0x01, 0x00, 0xa8, 0x83, 0x22, 0x44,
- 0x81, 0x6c, 0x00, 0x00, 0xb0, 0x83, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00,
- 0xaa, 0x83, 0x22, 0x4c, 0x81, 0x6c, 0x00, 0x00, 0xb4, 0x83, 0x22, 0x50,
- 0x81, 0x6c, 0x00, 0x00, 0xb5, 0x83, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00,
- 0xb7, 0x83, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00, 0xbc, 0x83, 0x22, 0x5c,
- 0x81, 0x6c, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xbc, 0x09, 0xb0, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca,
- 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xf3, 0x83, 0x01, 0x00, 0xae, 0x83, 0xa2, 0x42,
- 0x05, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00,
- 0x6a, 0x84, 0x22, 0xca, 0x07, 0x14, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x45,
- 0xf3, 0x93, 0x00, 0x00, 0x6a, 0x84, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00,
- 0x6a, 0x84, 0x80, 0xca, 0x05, 0x30, 0x00, 0x00, 0x6a, 0x84, 0x22, 0x01,
- 0x80, 0x30, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00,
- 0x5c, 0x01, 0x00, 0xbc, 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
- 0xb1, 0xb3, 0x01, 0x00, 0x6a, 0x84, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xca, 0x81, 0x88, 0x01, 0x00, 0x6a, 0x84, 0xa2, 0x40,
- 0x74, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00,
- 0xb9, 0x83, 0xa8, 0xb1, 0x82, 0x30, 0x00, 0x00, 0xb8, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xbf, 0x83, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xca, 0x83, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
- 0x80, 0xb0, 0x01, 0x00, 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0xc8, 0x83, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xca, 0x83, 0x56, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
- 0xf3, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00,
- 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xcf, 0x83, 0xa2, 0x41,
- 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xda, 0x83, 0x91, 0x81,
- 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00,
- 0xb6, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0xd8, 0x83, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xda, 0x83, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xf3, 0x9f, 0x00, 0x41,
- 0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00, 0x5c, 0x01, 0x00, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40, 0x8d, 0xb0, 0x01, 0x00,
- 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x90, 0xb0, 0x01, 0x00,
- 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00,
- 0x6a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa6,
- 0x80, 0xb0, 0x01, 0x00, 0xec, 0x83, 0x22, 0x40, 0x82, 0x6c, 0x00, 0x00,
- 0xf0, 0x83, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x47, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
- 0xf5, 0x83, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00, 0xe7, 0x83, 0xa2, 0x41,
- 0x93, 0x50, 0x00, 0x00, 0xe5, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xf5, 0x9f, 0x00, 0x47, 0x80, 0x30, 0x01, 0x00,
- 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00, 0xf0, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x50, 0xb3, 0x01, 0x00,
- 0xfb, 0x83, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
- 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0xfe, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
- 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x50, 0xd3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x4e, 0xd3, 0x01, 0x00, 0x5e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6c, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00, 0xf0, 0x83, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x07, 0x84, 0x22, 0xa7, 0x8f, 0x6c, 0x00, 0x00,
- 0x49, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x09, 0x84, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xac, 0x94, 0x2e, 0x43,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x0d, 0x84, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40, 0xa3, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x60, 0x15, 0x00, 0x40,
- 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x40, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x40, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x41,
- 0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
- 0x13, 0x84, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00, 0x49, 0x84, 0xa2, 0x41,
- 0x01, 0x7d, 0x00, 0x00, 0x21, 0x84, 0x22, 0x58, 0x73, 0x7d, 0x00, 0x00,
- 0x78, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x1c, 0x84, 0xa8, 0xb1,
- 0x9c, 0x30, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x0e, 0x10, 0xc9, 0x00, 0x00, 0x21, 0x84, 0x33, 0xc4,
- 0x81, 0x30, 0x00, 0x00, 0x24, 0x84, 0xa1, 0xad, 0x9d, 0x20, 0x00, 0x00,
- 0x1b, 0x84, 0x13, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4e,
- 0x5a, 0x83, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
- 0x2c, 0x84, 0x22, 0xab, 0x80, 0x04, 0x00, 0x00, 0x2a, 0x84, 0xa2, 0x40,
- 0x01, 0x7d, 0x00, 0x00, 0x2c, 0x84, 0x22, 0x5f, 0x57, 0x7d, 0x00, 0x00,
- 0x21, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x84, 0x22, 0x5e,
- 0x57, 0x7d, 0x00, 0x00, 0x84, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x31, 0x84, 0x22, 0x54, 0x73, 0x7d, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x2c, 0x84, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00,
- 0xfa, 0x85, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00, 0x5c, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x33, 0x84, 0xa2, 0x5f, 0x59, 0x27, 0x00, 0x00,
- 0x35, 0x84, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00, 0x3c, 0x84, 0xa2, 0x5e,
- 0x73, 0x7d, 0x00, 0x00, 0x46, 0x84, 0x22, 0x5c, 0x73, 0x7d, 0x00, 0x00,
- 0x47, 0x84, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x36, 0x84, 0xa8, 0xb1, 0x36, 0x30, 0x00, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x38, 0x84, 0xa8, 0xb1,
- 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x02, 0x88, 0x01, 0x00,
- 0x29, 0x86, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x47, 0x84, 0x34, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x3d, 0x84, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00, 0x44, 0x84, 0x52, 0x21,
- 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41, 0x2f, 0xc3, 0x01, 0x00,
- 0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x01, 0xf0, 0x01, 0x00, 0x87, 0x84, 0x00, 0x34, 0x13, 0x84, 0x00, 0x00,
- 0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00, 0xe5, 0x84, 0x00, 0x43,
- 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x47, 0x84, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x13, 0x4e,
- 0x5a, 0x93, 0x00, 0x00, 0xe6, 0x89, 0xa2, 0x48, 0xfd, 0x7f, 0x00, 0x00,
- 0x4e, 0x84, 0x22, 0x59, 0x73, 0x7d, 0x00, 0x00, 0x79, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x4a, 0x84, 0x28, 0xb1, 0x7e, 0x31, 0x00, 0x00,
- 0x4b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x52, 0x84, 0x21, 0xac,
- 0x9c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x1f, 0xc3, 0x01, 0x00,
- 0x04, 0x00, 0xa0, 0x5f, 0x9d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x58, 0x91, 0x01, 0x00, 0x56, 0x84, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00,
- 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x53, 0x84, 0xa8, 0xb1,
- 0x7e, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0xcf, 0x11, 0xc9, 0x00, 0x00,
- 0x5c, 0x84, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00, 0x5c, 0x84, 0x22, 0x44,
- 0x93, 0x7f, 0x00, 0x00, 0x58, 0x84, 0x42, 0xa5, 0x80, 0x30, 0x00, 0x00,
- 0x5b, 0x84, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00, 0x71, 0x84, 0x1a, 0x40,
- 0x93, 0x93, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x9a, 0x80, 0xa2, 0x40, 0x73, 0x7d, 0x00, 0x00, 0x9b, 0x89, 0x22, 0x44,
- 0x21, 0x6f, 0x00, 0x00, 0x92, 0x89, 0x22, 0x40, 0x65, 0x7d, 0x00, 0x00,
- 0xa0, 0x89, 0xa2, 0x5b, 0x73, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49,
- 0x33, 0x7d, 0x00, 0x00, 0x66, 0x84, 0x22, 0x48, 0x33, 0x7d, 0x00, 0x00,
- 0xff, 0x01, 0x00, 0x99, 0x80, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x98, 0x2f, 0x40, 0x33, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe0, 0xc1, 0x01, 0x00, 0x69, 0x84, 0x22, 0x40,
- 0xaf, 0x6f, 0x00, 0x00, 0x69, 0x84, 0x22, 0x40, 0x81, 0x6f, 0x00, 0x00,
- 0xef, 0x89, 0x1f, 0xa5, 0x82, 0x6f, 0x00, 0x00, 0x49, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x62, 0xb1, 0x01, 0x00, 0x1b, 0x84, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x6c, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6f, 0x84, 0x33, 0x40,
- 0x1f, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00,
- 0x73, 0x84, 0xa0, 0xce, 0x81, 0x50, 0x00, 0x00, 0x85, 0x84, 0xa0, 0xcd,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xb1, 0x81, 0xb0, 0x01, 0x00, 0x85, 0x84, 0x22, 0xb5,
- 0x81, 0x14, 0x00, 0x00, 0x80, 0x15, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x77, 0x84, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb4,
- 0x65, 0x97, 0x01, 0x00, 0xd0, 0x15, 0x2e, 0x40, 0x69, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0x44, 0x93, 0x83, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2,
- 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xb1, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5,
- 0xf1, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x80, 0x84, 0xa8, 0xa1,
- 0xe0, 0x31, 0x00, 0x00, 0x5c, 0x84, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00,
- 0x5c, 0x84, 0xa2, 0x41, 0x67, 0x6f, 0x00, 0x00, 0x5c, 0x84, 0x00, 0x6f,
- 0xdb, 0x91, 0x00, 0x00, 0x85, 0x84, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x5c, 0x84, 0x1a, 0x40, 0x93, 0x83, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09,
- 0x46, 0xc9, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00,
- 0x90, 0x84, 0xa6, 0x42, 0x13, 0x60, 0x00, 0x00, 0x3f, 0x97, 0x00, 0x95,
- 0x03, 0x30, 0x01, 0x00, 0x8b, 0x84, 0x45, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x75, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x8c, 0x84, 0xa8, 0xb1,
- 0x0c, 0x30, 0x00, 0x00, 0x46, 0x97, 0x1d, 0x10, 0x94, 0x30, 0x01, 0x00,
- 0x91, 0x84, 0x00, 0x58, 0x1f, 0x90, 0x00, 0x00, 0x38, 0x97, 0x00, 0x95,
- 0x03, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0,
- 0x2e, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x98, 0x84, 0x23, 0x4b, 0xe4, 0x6d, 0x00, 0x00, 0x98, 0x84, 0x22, 0x4b,
- 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
- 0x22, 0x00, 0x2f, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x9b, 0x84, 0x83, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x9d, 0x84, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x47, 0xc1, 0x01, 0x00, 0xa2, 0x84, 0x22, 0x55, 0x2f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x43, 0xd1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x97, 0xe0, 0x01, 0x00,
- 0xa3, 0x84, 0x00, 0x4b, 0x44, 0xc1, 0x00, 0x00, 0x12, 0x00, 0x00, 0xa2,
- 0x44, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x28, 0xf0, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
- 0x2a, 0xb0, 0x01, 0x00, 0xc0, 0x28, 0x3c, 0x46, 0x0d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x44, 0x95, 0xb0, 0x01, 0x00, 0xaf, 0x84, 0xa2, 0xf8,
- 0x0e, 0x30, 0x00, 0x00, 0xbf, 0x84, 0x22, 0x41, 0x95, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xab, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xac, 0x84, 0xa2, 0xf8, 0x16, 0x6c, 0x00, 0x00,
- 0xac, 0x84, 0xa2, 0xf8, 0x10, 0x6c, 0x00, 0x00, 0xac, 0x84, 0xa2, 0xf0,
- 0x1a, 0x6c, 0x00, 0x00, 0xbd, 0x84, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0xb4, 0x84, 0x47, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xb8, 0x84, 0xa2, 0xf3, 0x74, 0x06, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0xe6, 0x95, 0x01, 0x00, 0xbd, 0x84, 0x1f, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x96, 0xb0, 0x01, 0x00,
- 0x3f, 0x00, 0x1f, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0xbb, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xbd, 0x84, 0x47, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xc5, 0x84, 0x1f, 0x41, 0x2d, 0xc3, 0x00, 0x00,
- 0xc3, 0x84, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x62, 0xb1, 0x01, 0x00,
- 0xc1, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc3, 0x84, 0x47, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xec, 0x84, 0x1f, 0x41, 0x2d, 0xc3, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07,
- 0x16, 0x30, 0x01, 0x00, 0xd3, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
- 0xcb, 0x84, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xd2, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
- 0xff, 0x96, 0x00, 0x5f, 0x01, 0x10, 0x01, 0x00, 0xd1, 0x84, 0x22, 0x40,
- 0x95, 0x6c, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xdb, 0x84, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xdb, 0x84, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0xd8, 0x84, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
- 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xde, 0x84, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00,
- 0x66, 0x8b, 0x00, 0x45, 0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6,
- 0x96, 0xb0, 0x01, 0x00, 0xe2, 0x84, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
- 0xf5, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x4b,
- 0x8f, 0xb0, 0x00, 0x00, 0x0b, 0x97, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00,
- 0xe7, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x50, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xe9, 0x84, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x17, 0xb0, 0x01, 0x00, 0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
- 0xee, 0x07, 0x2e, 0x47, 0x97, 0x90, 0x01, 0x00, 0xff, 0x84, 0x22, 0x17,
- 0x96, 0x04, 0x00, 0x00, 0xfd, 0x84, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
- 0xfd, 0x84, 0x23, 0xa2, 0x02, 0x6c, 0x00, 0x00, 0x74, 0x96, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x0c, 0x00, 0x2d, 0x00, 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x00, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00,
- 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0x00, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00,
- 0x1c, 0x85, 0x00, 0x5c, 0x17, 0x90, 0x00, 0x00, 0x11, 0x85, 0x22, 0x43,
- 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00,
- 0x0a, 0x85, 0x22, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0xe0, 0xc9, 0x01, 0x00, 0x06, 0x85, 0x45, 0x42, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x07, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x1d, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6,
- 0x80, 0x88, 0x01, 0x00, 0x0e, 0x85, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00,
- 0x11, 0x85, 0x00, 0xf2, 0x3a, 0xb0, 0x00, 0x00, 0xf7, 0x85, 0xa2, 0x4b,
- 0xfd, 0x7f, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1c, 0x85, 0x22, 0x4a,
- 0x2f, 0x7c, 0x00, 0x00, 0x1c, 0x85, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00,
- 0x0a, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2,
- 0x86, 0x88, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00,
- 0x05, 0x00, 0x00, 0x43, 0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42,
- 0x81, 0xe0, 0x01, 0x00, 0x1c, 0x85, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00,
- 0xf7, 0x85, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x1c, 0x85, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3,
- 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x41, 0x47, 0xc3, 0x01, 0x00,
- 0x22, 0x85, 0x22, 0xa1, 0x09, 0x6c, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x1f, 0x85, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00,
- 0x5b, 0x85, 0xa3, 0x92, 0x03, 0x6c, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x40,
- 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
- 0x15, 0x8a, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x28, 0x85, 0x22, 0x5c,
- 0x17, 0x7c, 0x00, 0x00, 0x29, 0x85, 0x00, 0x00, 0x2a, 0xb0, 0x00, 0x00,
- 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x02, 0x00, 0x00, 0x08,
- 0x80, 0xc8, 0x01, 0x00, 0x2d, 0x85, 0xa2, 0x43, 0x2f, 0x7c, 0x00, 0x00,
- 0xf8, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x49, 0x85, 0x00, 0x5e,
- 0x17, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00,
- 0xf8, 0x97, 0x00, 0x4c, 0x03, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
- 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x36, 0x85, 0xa8, 0x54, 0x17, 0x10, 0x00, 0x00, 0x49, 0x85, 0x00, 0x5e,
- 0x17, 0x90, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00,
- 0x48, 0x85, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
- 0x8c, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x03, 0xb0, 0x01, 0x00,
- 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
- 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x09,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x49, 0x85, 0x28, 0x54, 0x17, 0x10, 0x00, 0x00, 0x45, 0x85, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
- 0x4b, 0x85, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
- 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
- 0x4e, 0x85, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x17, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x56, 0x85, 0x22, 0x43,
- 0x2f, 0x7c, 0x00, 0x00, 0x16, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0xe4, 0xb1, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0x59, 0x85, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00,
- 0xb9, 0x94, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x5d, 0x85, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xf4, 0x85, 0x00, 0x41,
- 0x43, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x5f, 0x85, 0x35, 0x01,
- 0x86, 0x30, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x66, 0x85, 0x28, 0xb1, 0x30, 0x30, 0x00, 0x00, 0x60, 0x85, 0x22, 0x4d,
- 0x75, 0x7d, 0x00, 0x00, 0xe4, 0x85, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0xf3, 0x85, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x66, 0x85, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00, 0x6f, 0x85, 0xa2, 0x40,
- 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x2c, 0xb0, 0x01, 0x00, 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
- 0x60, 0x85, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x74, 0x85, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00,
- 0x60, 0x85, 0xa3, 0x0b, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
- 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40,
- 0x39, 0xb0, 0x01, 0x00, 0x7c, 0x85, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00,
- 0x22, 0x00, 0x00, 0x08, 0x12, 0xc8, 0x01, 0x00, 0xde, 0x07, 0x00, 0x40,
- 0x25, 0x98, 0x01, 0x00, 0x7f, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x30, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x20, 0x01,
- 0xe0, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00,
- 0x84, 0x85, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x36, 0xb0, 0x01, 0x00, 0x8f, 0x85, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x8b, 0x85, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x88, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xeb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x44, 0xc9, 0x01, 0x00, 0x9e, 0x85, 0x22, 0x45, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19,
- 0x62, 0xdd, 0x01, 0x00, 0x95, 0x85, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x33, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00,
- 0x0c, 0x00, 0x2d, 0x4c, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x37, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00,
- 0x84, 0x85, 0x00, 0x45, 0x1f, 0x80, 0x00, 0x00, 0xa0, 0x85, 0xa3, 0x12,
- 0x36, 0x6c, 0x00, 0x00, 0xa1, 0x85, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x12, 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19,
- 0x62, 0xdd, 0x01, 0x00, 0xa4, 0x85, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00,
- 0xca, 0x85, 0x22, 0x14, 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x33, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
- 0x0c, 0x00, 0x2d, 0x14, 0x12, 0xc0, 0x01, 0x00, 0xc3, 0x85, 0xa2, 0x14,
- 0x36, 0x50, 0x00, 0x00, 0xb4, 0x85, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xb2, 0x85, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xaf, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x2b, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x37, 0x98, 0x01, 0x00, 0xb9, 0x85, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00, 0xc4, 0x85, 0x22, 0x1b,
- 0x02, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x15, 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0xc0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc4, 0x85, 0x00, 0x03,
- 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x2a, 0xc0, 0x01, 0x00,
- 0x84, 0x85, 0xa2, 0x40, 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x39, 0xc0, 0x01, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x12, 0xb0, 0x01, 0x00, 0x84, 0x85, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0xd0, 0x85, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0xcd, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xeb, 0x95, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0xd4, 0x85, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17,
- 0x98, 0x88, 0x01, 0x00, 0xd7, 0x85, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00, 0xda, 0x85, 0x22, 0x43,
- 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00,
- 0x16, 0x00, 0x20, 0x1d, 0xe4, 0xb1, 0x01, 0x00, 0xdc, 0x85, 0xa3, 0x40,
- 0x27, 0x6c, 0x00, 0x00, 0xde, 0x85, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00,
- 0x00, 0x84, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13,
- 0x16, 0x94, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
- 0x15, 0x8a, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
- 0xb9, 0x94, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00, 0xe8, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xf3, 0x85, 0x22, 0x13, 0x82, 0x6c, 0x00, 0x00,
- 0x40, 0x00, 0x3d, 0x43, 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00, 0xee, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00,
- 0xf0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xea, 0x85, 0x00, 0x41,
- 0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
- 0x74, 0x96, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x15, 0x8a, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x01, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x0e, 0xf4, 0x01, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07,
- 0x16, 0x30, 0x01, 0x00, 0x05, 0x86, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
- 0x03, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x04, 0x86, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x0d, 0x86, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0d, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0x0a, 0x86, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
- 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
- 0x13, 0x86, 0x22, 0x3a, 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x8e, 0xb0, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x17, 0x86, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00,
- 0x0a, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
- 0x01, 0xb0, 0x00, 0x00, 0x51, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x38, 0x97, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x22, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00, 0x28, 0x20, 0x00, 0xa6,
- 0x96, 0xb0, 0x01, 0x00, 0x20, 0x86, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
- 0xf5, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x4c,
- 0x8f, 0xb0, 0x00, 0x00, 0x22, 0x86, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x43, 0xc1, 0x01, 0x00, 0x24, 0x86, 0x85, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1,
- 0x2a, 0xc8, 0x01, 0x00, 0x0b, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xe7, 0x94, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x2e, 0x86, 0x46, 0x47,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0x2f, 0x86, 0xa8, 0x1b, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x1e, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00,
- 0x08, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x54, 0x86, 0x01, 0xfb,
- 0x08, 0x30, 0x00, 0x00, 0xa7, 0x86, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x14, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
- 0x0b, 0x96, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x4a, 0x86, 0x22, 0x41,
- 0x81, 0x6c, 0x00, 0x00, 0x3e, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x49, 0x86, 0x22, 0x5f,
- 0x0f, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00,
- 0x42, 0x86, 0xa6, 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x5f, 0x95, 0x00, 0x40,
- 0x05, 0x30, 0x01, 0x00, 0x47, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
- 0x05, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x52, 0x86, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x52, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0x4f, 0x86, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42,
- 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
- 0x56, 0x86, 0x21, 0x04, 0x80, 0x20, 0x00, 0x00, 0x57, 0x86, 0x00, 0x40,
- 0x10, 0xc9, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00,
- 0x76, 0x86, 0x00, 0x43, 0x81, 0xb0, 0x00, 0x00, 0x7a, 0x86, 0x00, 0xfb,
- 0x22, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00,
- 0x66, 0x8b, 0x00, 0x4e, 0x8f, 0xb0, 0x00, 0x00, 0x72, 0x86, 0x00, 0x5a,
- 0x8f, 0xb0, 0x00, 0x00, 0x5f, 0x86, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00,
- 0xa8, 0x8a, 0x00, 0x53, 0x81, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x56,
- 0x81, 0xb0, 0x00, 0x00, 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x66, 0x8b, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x65, 0x86, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x64, 0x86, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
- 0x66, 0x8b, 0x00, 0x53, 0x8f, 0xb0, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x54,
- 0x8f, 0xb0, 0x00, 0x00, 0x6e, 0x86, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
- 0x68, 0x86, 0xa2, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x5d,
- 0x8f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x80, 0xd0, 0x01, 0x00, 0x6c, 0x86, 0xa0, 0x91,
- 0x81, 0x6c, 0x00, 0x00, 0x66, 0x8b, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00,
- 0x25, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x70, 0x86, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00,
- 0x66, 0x8b, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x66, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x66, 0x8b, 0xa0, 0x0a,
- 0xe4, 0x6d, 0x00, 0x00, 0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x66, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00,
- 0xa8, 0x8a, 0xa0, 0x42, 0x83, 0x6c, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x54,
- 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
- 0x83, 0x86, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0x95, 0x86, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
- 0x90, 0x86, 0xa2, 0x54, 0xfd, 0x7f, 0x00, 0x00, 0x88, 0x86, 0x22, 0x55,
- 0xfd, 0x7f, 0x00, 0x00, 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x80, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x86, 0x22, 0x53,
- 0xfd, 0x7f, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b,
- 0x80, 0xf4, 0x01, 0x00, 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x90, 0x86, 0x22, 0x43, 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
- 0x80, 0x88, 0x01, 0x00, 0x80, 0x86, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00,
- 0x7c, 0x96, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x91, 0x86, 0x43, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x94, 0x86, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00,
- 0x86, 0x86, 0x1b, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x41,
- 0x31, 0xc3, 0x01, 0x00, 0x90, 0x95, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00,
- 0x99, 0x86, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
- 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x07, 0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c,
- 0xe0, 0x99, 0x01, 0x00, 0xce, 0x99, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xa0, 0x86, 0x30, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
- 0x00, 0x02, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe6, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xa8, 0x8a, 0x00, 0x40,
- 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x14, 0xb0, 0x01, 0x00, 0xb1, 0x86, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00,
- 0xad, 0x86, 0x22, 0x40, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x1f, 0x90, 0x01, 0x00, 0xaf, 0x86, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x1f, 0x90, 0x01, 0x00, 0xb1, 0x86, 0x22, 0x42,
- 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00,
- 0xb1, 0x86, 0x47, 0x1b, 0x2c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x41, 0x41, 0xc3, 0x01, 0x00,
- 0xe0, 0x86, 0x23, 0x92, 0x15, 0x6c, 0x00, 0x00, 0xe0, 0x86, 0xa2, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0xe4, 0x86, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
- 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x27, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x0a, 0x24, 0xc8, 0x01, 0x00,
- 0xc7, 0x95, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0xde, 0x86, 0x22, 0x08,
- 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
- 0xf0, 0x07, 0x00, 0x12, 0x24, 0xcc, 0x01, 0x00, 0xba, 0x86, 0xaa, 0x41,
- 0x27, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00,
- 0xda, 0x86, 0x26, 0x40, 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x10, 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
- 0xa2, 0xc9, 0x01, 0x00, 0xc7, 0x86, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00,
- 0xd3, 0x86, 0x00, 0x41, 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xcc, 0x86, 0xa2, 0x44,
- 0x23, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xcf, 0x86, 0xa8, 0x42,
- 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xa3, 0xc1, 0x01, 0x00, 0xc5, 0x86, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0xda, 0x86, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xd7, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0xee, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
- 0x2a, 0xc8, 0x01, 0x00, 0xed, 0x86, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00,
- 0xaa, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe4, 0x86, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x92, 0x25, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x31, 0xb0, 0x01, 0x00, 0xe4, 0x86, 0x22, 0x08,
- 0x2e, 0x30, 0x00, 0x00, 0xed, 0x86, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00,
- 0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x90, 0x01, 0x00, 0xec, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0x6b, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xff, 0x89, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01,
- 0x80, 0xce, 0x01, 0x00, 0x01, 0x87, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0xf6, 0x86, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
- 0xf6, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xf6, 0x86, 0xa3, 0x07,
- 0x03, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0xf9, 0x86, 0xa3, 0x40, 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01,
- 0xf0, 0xcd, 0x01, 0x00, 0xfb, 0x86, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x0e, 0xcc, 0x01, 0x00, 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0x00, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xff, 0x86, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x08, 0xb0, 0x01, 0x00, 0xa0, 0x01, 0x2d, 0x40,
- 0x00, 0xc0, 0x01, 0x00, 0xe7, 0x88, 0x22, 0x0f, 0x42, 0x05, 0x00, 0x00,
- 0x12, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x0d, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x0a, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x12, 0x87, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0xd1, 0x87, 0xa2, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x54, 0x29, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x42, 0x00, 0x00, 0x03,
- 0x0a, 0xc8, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08,
- 0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0xfe, 0x7f, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x23, 0x87, 0x20, 0x94,
- 0x15, 0x6c, 0x00, 0x00, 0x24, 0x87, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00, 0x3d, 0x87, 0x22, 0x01,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0x2a, 0x87, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
- 0x2b, 0x87, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
- 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0x37, 0x87, 0x22, 0x40,
- 0x03, 0x6c, 0x00, 0x00, 0x37, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x5f, 0x87, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x34, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0x39, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5f, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0x42, 0x87, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
- 0x43, 0x87, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
- 0x1a, 0xb0, 0x01, 0x00, 0x46, 0x87, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x11, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x4a, 0x87, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x7d, 0x87, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
- 0x50, 0x87, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x10, 0xc0, 0x01, 0x00, 0x54, 0x87, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00,
- 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x56, 0x87, 0x22, 0x42,
- 0x23, 0x6c, 0x00, 0x00, 0x5f, 0x87, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x57, 0x87, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x5d, 0x87, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00,
- 0xfb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x7d, 0x87, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x7c, 0x87, 0xa2, 0x0d,
- 0x0e, 0x50, 0x00, 0x00, 0x6b, 0x87, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x69, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x66, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x70, 0x87, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x24, 0x87, 0x00, 0x4c,
- 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00,
- 0x24, 0x87, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
- 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x79, 0x87, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0x24, 0x87, 0x00, 0x03,
- 0x0c, 0xb0, 0x00, 0x00, 0x24, 0x87, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00,
- 0x04, 0x00, 0x2e, 0x14, 0x0a, 0xd0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05,
- 0x48, 0xcd, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00,
- 0x0c, 0x00, 0x2a, 0xf2, 0xe0, 0xb1, 0x01, 0x00, 0x83, 0x87, 0x22, 0x40,
- 0x31, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00,
- 0x1e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6,
- 0x80, 0xce, 0x01, 0x00, 0x87, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x43, 0xc1, 0x01, 0x00, 0x89, 0x87, 0x22, 0x0b,
- 0xed, 0x6d, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa,
- 0x94, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf6, 0x0e, 0xb0, 0x01, 0x00, 0x91, 0x87, 0x22, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00,
- 0x91, 0x87, 0xa0, 0x46, 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xc0, 0x01, 0x00, 0x95, 0x87, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2,
- 0x42, 0x31, 0x00, 0x00, 0x98, 0x87, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00,
- 0x0c, 0x00, 0x00, 0xa2, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x82, 0xb0, 0x01, 0x00, 0x9b, 0x87, 0xa0, 0x41,
- 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
- 0xa0, 0x87, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xa0, 0x87, 0xa0, 0x43,
- 0x89, 0x6c, 0x00, 0x00, 0xa0, 0x87, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00,
- 0xa0, 0x87, 0xa0, 0x41, 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00,
- 0x98, 0x87, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0xa9, 0x87, 0x22, 0x48,
- 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x48, 0x90, 0x88, 0x01, 0x00, 0xa7, 0x87, 0x90, 0x48,
- 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
- 0x93, 0xa4, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x14, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
- 0xf0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05, 0xe0, 0xcd, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
- 0xaf, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xbc, 0x87, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xb9, 0x87, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xb6, 0x87, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xbc, 0x87, 0x87, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0xfb, 0x95, 0x00, 0x41, 0x23, 0x40, 0x01, 0x00,
- 0xbe, 0x87, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x52, 0x89, 0x00, 0x17,
- 0x10, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0xc1, 0x87, 0xa0, 0x07, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xc5, 0x87, 0x90, 0xf2,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
- 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xcf, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xcc, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17,
- 0x10, 0xdc, 0x01, 0x00, 0x52, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x90, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd5, 0x87, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x66, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x80, 0x00, 0x05,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
- 0x0c, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x1b, 0x88, 0x22, 0x01,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0xea, 0x87, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
- 0xeb, 0x87, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
- 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xfd, 0x87, 0x22, 0x40,
- 0x03, 0x6c, 0x00, 0x00, 0xf7, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x37, 0x88, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0xf9, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x37, 0x88, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0xff, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0x0b, 0x88, 0x23, 0x1a,
- 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
- 0x37, 0x88, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
- 0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x13, 0x88, 0x22, 0x1a,
- 0x02, 0x50, 0x00, 0x00, 0x37, 0x88, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
- 0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
- 0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x37, 0x88, 0x00, 0x1a,
- 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0x20, 0x88, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
- 0x21, 0x88, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
- 0x1a, 0xb0, 0x01, 0x00, 0x24, 0x88, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x11, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x28, 0x88, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x54, 0x88, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
- 0x54, 0x88, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x10, 0xc0, 0x01, 0x00, 0x2f, 0x88, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x37, 0x88, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x30, 0x88, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0xfb, 0x95, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x53, 0x88, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x42, 0x88, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x40, 0x88, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x3d, 0x88, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x04, 0xb0, 0x01, 0x00, 0x47, 0x88, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
- 0xe4, 0x87, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
- 0x0f, 0x80, 0x01, 0x00, 0xe4, 0x87, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x50, 0x88, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0xe4, 0x87, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xe4, 0x87, 0x00, 0x0d,
- 0x18, 0xc0, 0x00, 0x00, 0x71, 0x88, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
- 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
- 0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
- 0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
- 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
- 0x66, 0x88, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x91, 0xc0, 0x01, 0x00, 0x64, 0x88, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
- 0x04, 0x80, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x48, 0xc1, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x18,
- 0x90, 0xb0, 0x01, 0x00, 0x6e, 0x88, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00, 0x6c, 0x88, 0xa2, 0x41,
- 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xe0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
- 0x76, 0x88, 0x42, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x41, 0x3d, 0xc3, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
- 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d, 0x82, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x80, 0xc0, 0x01, 0x00, 0x80, 0x88, 0xa0, 0x41, 0x80, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
- 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30, 0x81, 0x84, 0x01, 0x00,
- 0x84, 0x88, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x93, 0xa4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x19,
- 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x16, 0xc0, 0x01, 0x00,
- 0x8a, 0x88, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e, 0x32, 0xc0, 0x01, 0x00,
- 0x8f, 0x88, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00, 0x8e, 0x88, 0xa0, 0x1c,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05,
- 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e, 0x98, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00, 0x0c, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x9d, 0x88, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x9b, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x98, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x1a,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0xa3, 0x88, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xb1, 0x88, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0xad, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xaa, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0xfb, 0x95, 0x00, 0x41, 0x23, 0x40, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x17, 0xf0, 0x01, 0x00, 0xb6, 0x88, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
- 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xc1, 0x88, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xbe, 0x88, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00, 0xde, 0x88, 0x22, 0x40,
- 0x15, 0x6c, 0x00, 0x00, 0xc9, 0x88, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00, 0xc8, 0x88, 0x22, 0x9f,
- 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00,
- 0x6b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x3f, 0xc3, 0x01, 0x00, 0x4e, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xcc, 0x88, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e,
- 0x3e, 0xc0, 0x01, 0x00, 0xde, 0x88, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00,
- 0xcf, 0x88, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x3c, 0xb0, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x1e, 0x24, 0x30, 0x01, 0x00,
- 0xd4, 0x88, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x10, 0xc0, 0x01, 0x00,
- 0x37, 0x88, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd1, 0x88, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
- 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04,
- 0xe0, 0x31, 0x00, 0x00, 0x3d, 0x99, 0x00, 0x1f, 0x8c, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0x4e, 0x99, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xe3, 0x88, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
- 0xe4, 0x88, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f,
- 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x3d, 0x99, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0xef, 0x88, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xef, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xec, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf4, 0x88, 0x22, 0x07,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xf7, 0x88, 0x20, 0x94,
- 0x15, 0x6c, 0x00, 0x00, 0xf8, 0x88, 0x00, 0x94, 0xe1, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xfb, 0x88, 0x22, 0x40,
- 0x31, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x89, 0xa8, 0x40,
- 0x23, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
- 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00,
- 0x0e, 0x89, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00, 0x0f, 0x89, 0x68, 0x07,
- 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x1a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x01, 0x1f, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
- 0x14, 0x89, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x45, 0x89, 0x22, 0x0d,
- 0x14, 0x6c, 0x00, 0x00, 0x1a, 0x89, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0x1e, 0x89, 0x00, 0x0d,
- 0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
- 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
- 0x20, 0x89, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0x27, 0x89, 0x00, 0x41,
- 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x21, 0x89, 0xa8, 0x5c,
- 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x43,
- 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x44, 0x89, 0xa2, 0x0d,
- 0x0e, 0x50, 0x00, 0x00, 0x33, 0x89, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x31, 0x89, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x2e, 0x89, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x38, 0x89, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x09, 0x89, 0x00, 0x4c,
- 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00,
- 0x09, 0x89, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
- 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x41, 0x89, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0x09, 0x89, 0x00, 0x03,
- 0x0c, 0xb0, 0x00, 0x00, 0x09, 0x89, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00,
- 0x4e, 0x89, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x4e, 0x89, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4b, 0x89, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x41,
- 0x23, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0x10, 0xb0, 0x01, 0x00,
- 0x52, 0x89, 0x00, 0x40, 0x2b, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xe0, 0xb1, 0x01, 0x00,
- 0x57, 0x89, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
- 0x1c, 0xcc, 0x01, 0x00, 0x6b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x4e, 0x99, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x3d, 0x99, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0x15, 0x8a, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0x0b, 0x96, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
- 0x66, 0x89, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x64, 0x89, 0x22, 0x42,
- 0x81, 0x6c, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x65, 0x89, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0xff, 0x89, 0x00, 0x40,
- 0x0f, 0xb0, 0x00, 0x00, 0x6e, 0x89, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
- 0x86, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x6e, 0x89, 0x22, 0x20,
- 0x85, 0x6c, 0x00, 0x00, 0x6b, 0x89, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x66, 0x96, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0x85, 0x98, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xce, 0x99, 0x00, 0x07,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0xb0, 0x01, 0x00, 0xa8, 0x8a, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00,
- 0xa8, 0x00, 0x2d, 0x43, 0x19, 0x80, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf0,
- 0x24, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x8e, 0xf4, 0x01, 0x00,
- 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00, 0x7d, 0x89, 0x22, 0x48,
- 0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x7d, 0x89, 0x1f, 0xf0,
- 0x24, 0x6c, 0x00, 0x00, 0x7c, 0x89, 0x23, 0x41, 0x8f, 0x6c, 0x00, 0x00,
- 0xa8, 0x8a, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x48,
- 0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0x82, 0x89, 0x22, 0x0a,
- 0x90, 0x40, 0x00, 0x00, 0x21, 0x99, 0x00, 0x40, 0x91, 0x30, 0x01, 0x00,
- 0xa8, 0x8a, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0xb0, 0x00, 0x2d, 0x45,
- 0x81, 0xb0, 0x01, 0x00, 0x8e, 0x89, 0x22, 0xf0, 0x2c, 0x30, 0x00, 0x00,
- 0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf3,
- 0x82, 0xe0, 0x01, 0x00, 0x88, 0x89, 0xa3, 0x41, 0x2c, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0xf0,
- 0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x82, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00, 0xa8, 0x8a, 0x20, 0x4c,
- 0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41, 0x98, 0xe8, 0x01, 0x00,
- 0xa8, 0x8a, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00, 0xff, 0x89, 0x22, 0x0a,
- 0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
- 0xff, 0x89, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa8, 0x8a, 0x00, 0x49,
- 0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
- 0x96, 0x89, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x13, 0x80, 0x00, 0x40,
- 0x80, 0xdc, 0x01, 0x00, 0x97, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x97, 0x89, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xb1, 0x01, 0x00,
- 0x99, 0x89, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00, 0x9d, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x5f, 0x84, 0x22, 0x40, 0x57, 0x7d, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00, 0x9d, 0x89, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x49, 0x84, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xa0, 0x89, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00,
- 0xc9, 0x89, 0x1d, 0x40, 0x80, 0x32, 0x00, 0x00, 0xba, 0x89, 0x22, 0x40,
- 0xaf, 0x6f, 0x00, 0x00, 0xba, 0x89, 0x22, 0x5b, 0x81, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x5d, 0x73, 0x7d, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xa6, 0x89, 0xa8, 0xb1, 0x94, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x62, 0xb1, 0x01, 0x00, 0xa9, 0x89, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xab, 0x89, 0x43, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb9, 0x89, 0x22, 0x57,
- 0x73, 0x7d, 0x00, 0x00, 0x77, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xad, 0x89, 0xa8, 0xb1, 0x94, 0x30, 0x00, 0x00, 0x77, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xaf, 0x89, 0xa8, 0xb1, 0x96, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x62, 0xb1, 0x01, 0x00, 0xb2, 0x89, 0xa8, 0x4a, 0x80, 0x33, 0x00, 0x00,
- 0xb7, 0x89, 0x22, 0x5f, 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0xb5, 0x89, 0xa8, 0x4b, 0xac, 0x33, 0x00, 0x00,
- 0x00, 0x00, 0x1b, 0xa5, 0x82, 0xb3, 0x01, 0x00, 0xba, 0x89, 0x00, 0xbe,
- 0x83, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x40, 0x81, 0xb3, 0x01, 0x00,
- 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0xc7, 0x89, 0xa2, 0x40, 0x86, 0x04, 0x00, 0x00,
- 0x1b, 0x84, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x40,
- 0x88, 0x88, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
- 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0xc3, 0x89, 0x52, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xe3, 0x89, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x48,
- 0x47, 0x31, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x05, 0x47, 0x31, 0x01, 0x00,
- 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00,
- 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xd0, 0x89, 0x22, 0x54,
- 0x81, 0x7c, 0x00, 0x00, 0xcb, 0x89, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x82, 0x00, 0xb4, 0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0xde, 0x89, 0x0f, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00,
- 0xe3, 0x89, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44,
- 0x88, 0xcc, 0x01, 0x00, 0xd6, 0x89, 0x99, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00, 0xd8, 0x89, 0x9b, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xd0, 0x01, 0x00,
- 0xda, 0x89, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00, 0xe3, 0x89, 0x00, 0x40,
- 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
- 0xe3, 0x89, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x58,
- 0x47, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x43,
- 0x86, 0x88, 0x01, 0x00, 0x1b, 0x84, 0x26, 0x05, 0x47, 0x31, 0x00, 0x00,
- 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb, 0x81, 0xc8, 0x01, 0x00,
- 0xe9, 0x89, 0x22, 0x40, 0xf2, 0x7f, 0x00, 0x00, 0x81, 0x80, 0x00, 0x6f,
- 0x97, 0x33, 0x01, 0x00, 0xeb, 0x89, 0x22, 0x40, 0x73, 0x7d, 0x00, 0x00,
- 0x9b, 0x80, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xe6, 0x89, 0x22, 0x59,
- 0x73, 0x7d, 0x00, 0x00, 0x79, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xe6, 0x89, 0x28, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xec, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0xc0, 0x95, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd6, 0x97, 0xb0, 0x01, 0x00, 0xf4, 0x89, 0x22, 0x5d,
- 0x73, 0x7d, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xf2, 0x89, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
- 0x7f, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xc5, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x25, 0x01, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf7, 0x89, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0xf9, 0x89, 0x43, 0x5f, 0x7f, 0x13, 0x00, 0x00, 0x26, 0x01, 0x00, 0xbf,
- 0xc5, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x7f, 0x83, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0x7f, 0x93, 0x01, 0x00, 0x75, 0x98, 0x00, 0xbf,
- 0xc5, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x06, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x06, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x03, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x62, 0x95, 0x22, 0x02,
- 0x80, 0x32, 0x00, 0x00, 0x07, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x62, 0x95, 0x1a, 0x02,
- 0x68, 0x97, 0x00, 0x00, 0x11, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x11, 0x8a, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0e, 0x8a, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x6c, 0x95, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x12, 0x8a, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x6c, 0x95, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00, 0x1c, 0x8a, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x1c, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x19, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x6f, 0x84, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0x1d, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
- 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
- 0x56, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x6d, 0x8a, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41,
- 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x29, 0x00, 0x00, 0x40,
- 0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x51, 0x8a, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x32, 0x8a, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
- 0x84, 0x89, 0x01, 0x00, 0x39, 0x8a, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
- 0x51, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x6e, 0x8a, 0x1c, 0xf0, 0x18, 0x30, 0x01, 0x00,
- 0x51, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x48, 0x8a, 0xa0, 0x48, 0x23, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a,
- 0x42, 0xc9, 0x01, 0x00, 0x42, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a,
- 0x62, 0xdd, 0x01, 0x00, 0x3f, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x6e, 0x8a, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00,
- 0x43, 0x8a, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x10,
- 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00,
- 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x1a,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
- 0x4c, 0x8a, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00, 0x5d, 0x8a, 0x22, 0x41,
- 0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
- 0x59, 0x8a, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1b, 0xb0, 0x01, 0x00, 0x30, 0x8a, 0x00, 0x41, 0x17, 0xb0, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00, 0x30, 0x8a, 0x83, 0x41,
- 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x30, 0x8a, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00, 0x68, 0x8a, 0x23, 0x40,
- 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x65, 0x8a, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x62, 0x8a, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x6e, 0x8a, 0x00, 0xf8,
- 0x18, 0x30, 0x01, 0x00, 0x66, 0x8a, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00, 0x6b, 0x8a, 0xa0, 0xaa,
- 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00,
- 0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x0c,
- 0x7e, 0x89, 0x01, 0x00, 0x80, 0x8a, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
- 0x76, 0x8a, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x40,
- 0x62, 0x99, 0x01, 0x00, 0x76, 0x8a, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x76, 0x8a, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x72, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x7b, 0x8a, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
- 0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
- 0x77, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x8a, 0x22, 0x49,
- 0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54,
- 0x77, 0x7d, 0x01, 0x00, 0x7b, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
- 0x80, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
- 0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
- 0x6f, 0x84, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x88, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x8b, 0x8a, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0xab, 0x27, 0xb3, 0x01, 0x00,
- 0x6f, 0x84, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x84, 0x22, 0x51,
- 0xfd, 0x7f, 0x00, 0x00, 0x6f, 0x84, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
- 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x34, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x97, 0x8a, 0x22, 0x40,
- 0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0xff, 0x81, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
- 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x35, 0x82, 0x00, 0x40,
- 0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0xfc, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0xff, 0x81, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xdb, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
- 0xb4, 0x8b, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
- 0xb4, 0xf7, 0x01, 0x00, 0xff, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6f, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x40, 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
- 0xae, 0x8a, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xd1, 0x8d, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x05, 0x8e, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x37, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x37, 0x8e, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x76, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x9f, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xaf, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xae, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x6f, 0x8f, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x6f, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x6f, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x9b, 0x8f, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xb9, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb9, 0x8f, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xb9, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe1, 0x8f, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0xf2, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xf2, 0x8f, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xf4, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xf4, 0x8f, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xfc, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x0d, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0xfd, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x0d, 0x90, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x0e, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
- 0x6d, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x6d, 0x8f, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x6d, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0x0f, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x0f, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x0f, 0x90, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x16, 0x90, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x18, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x24, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x8d, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x95, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xa3, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xa6, 0x90, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xcf, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x73, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x91, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xa3, 0x8e, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x20, 0x47,
- 0xe6, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
- 0x6e, 0x8b, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xbe, 0x90, 0x00, 0x49,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf7, 0x90, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xfd, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x0b, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x27, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x86, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x00, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x00, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x00, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
- 0x00, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0x00, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x00, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xe6, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xe6, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xfe, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x27, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x87, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x86, 0x91, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x1b, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x1b, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x1b, 0x92, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x00, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x26, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x26, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x26, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x26, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x4d, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x4d, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xaf, 0x92, 0x00, 0x40, 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x1e, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xd3, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xc0, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xe6, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe6, 0x91, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x3d, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x31, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x3d, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x31, 0x92, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x31, 0x92, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xd5, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xd5, 0x92, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xd5, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0xd5, 0x92, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xef, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xef, 0x92, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xf6, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x19, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x18, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x19, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x18, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x92, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xec, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xec, 0x92, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xec, 0x92, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0xec, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xec, 0x92, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xec, 0x92, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xfe, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xf2, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xb8, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x5f, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5f, 0x94, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x5f, 0x94, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5f, 0x94, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x5f, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x5f, 0x94, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xf2, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x6a, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6e, 0x94, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x6e, 0x94, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7f, 0x94, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7f, 0x94, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x90, 0x94, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xae, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x0b, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xae, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xb0, 0x94, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x6b, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x15, 0x92, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x6b, 0x94, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xb6, 0x94, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xb6, 0x94, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5d, 0x94, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x25, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x25, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x0a, 0x8a, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
- 0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0x21, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xca, 0x8d, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xca, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xc7, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x13, 0x86, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0xcb, 0x8d, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
- 0x13, 0x86, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x05, 0x00, 0x2e, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x0a, 0x8a, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xe0, 0xb1, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x06, 0x07, 0x40, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
- 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
- 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
- 0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
- 0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
- 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0xf4, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0xfc, 0x8d, 0x20, 0x4b,
- 0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0xf9, 0x8d, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x03, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xff, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x08, 0x8e, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x0b, 0x8e, 0xa2, 0x4c, 0xfd, 0x7f, 0x00, 0x00,
- 0x0c, 0x8e, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00, 0x0d, 0x8e, 0x20, 0xf0,
- 0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x56, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x70, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x13, 0x8e, 0xa8, 0x44,
- 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
- 0x64, 0x00, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x62, 0xb1, 0x01, 0x00,
- 0x1b, 0x8e, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07, 0x86, 0xe4, 0x01, 0x00,
- 0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x23, 0x8e, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x26, 0x8e, 0x22, 0x44,
- 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x45, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00, 0x68, 0x01, 0x20, 0xa2,
- 0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x2a, 0x8e, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43,
- 0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x2f, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5c, 0x00, 0x2e, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x41,
- 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x3a, 0x8e, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x3e, 0x8e, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00,
- 0x86, 0x00, 0x2f, 0x49, 0x19, 0x80, 0x01, 0x00, 0x3e, 0x8e, 0xa2, 0xf2,
- 0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xe7, 0x91, 0x01, 0x00, 0x41, 0x8e, 0xa2, 0x46,
- 0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x45, 0x8e, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46,
- 0x19, 0x80, 0x01, 0x00, 0x45, 0x8e, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe7, 0x91, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x34, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
- 0x16, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00,
- 0x70, 0x8e, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x58, 0x8e, 0x22, 0x0a,
- 0x16, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0,
- 0x84, 0x30, 0x00, 0x00, 0xe7, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00,
- 0x57, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x13, 0xb0, 0x01, 0x00, 0x4d, 0x8e, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00,
- 0x70, 0x8e, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
- 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00, 0xe7, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x70, 0x8e, 0x22, 0x41, 0x15, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00, 0x64, 0x8e, 0xa0, 0x43,
- 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xee, 0x97, 0x00, 0x47,
- 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x5f, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x6c, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x60, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x20, 0x98, 0x00, 0x51,
- 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x78, 0x8e, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
- 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x7d, 0x8e, 0x22, 0x45,
- 0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
- 0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x82, 0x8e, 0x22, 0x48,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
- 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
- 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
- 0x02, 0x30, 0x00, 0x00, 0x90, 0x8e, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
- 0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
- 0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x21, 0x99, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0x99, 0x8e, 0xa2, 0x44,
- 0x81, 0x6c, 0x00, 0x00, 0x97, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x8a, 0x96, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xbd, 0x8e, 0xa2, 0x08,
- 0x3c, 0x30, 0x00, 0x00, 0x99, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbd, 0x8e, 0xa2, 0x08,
- 0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
- 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
- 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x78, 0x8e, 0x22, 0x4a,
- 0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x69, 0x96, 0x00, 0xf3,
- 0x94, 0x30, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00,
- 0x00, 0x8c, 0x01, 0x00, 0xcf, 0x8d, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
- 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
- 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xaf, 0x8e, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00,
- 0xb4, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x8a, 0x96, 0x00, 0x40,
- 0x3b, 0x30, 0x01, 0x00, 0xb8, 0x8e, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb8, 0x8e, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x5f,
- 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x50, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0,
- 0x38, 0xb0, 0x01, 0x00, 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
- 0x40, 0x00, 0x2d, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x14, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40,
- 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x52, 0x81, 0xd0, 0x01, 0x00, 0xcb, 0x8e, 0x20, 0x94,
- 0x81, 0x6c, 0x00, 0x00, 0xb5, 0x97, 0x00, 0x94, 0xe5, 0x31, 0x01, 0x00,
- 0xcc, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x97, 0x00, 0x40,
- 0xe4, 0x31, 0x01, 0x00, 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00,
- 0xcc, 0x8e, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0xdc, 0x8e, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xd6, 0x8e, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xd3, 0x8e, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x48, 0xb1, 0x01, 0x00, 0xfb, 0x95, 0x00, 0x43,
- 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xb0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0xe4, 0x8e, 0x22, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0xe0, 0x8e, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00,
- 0xe1, 0x8e, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x04, 0xb0, 0x01, 0x00, 0xe3, 0x8e, 0x20, 0x02, 0x36, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x01, 0x00, 0xe7, 0x8e, 0x00, 0x02,
- 0xf0, 0xb1, 0x00, 0x00, 0xe6, 0x8e, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00,
- 0xe7, 0x8e, 0x68, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01,
- 0x04, 0xb0, 0x01, 0x00, 0xe9, 0x8e, 0x80, 0x08, 0xf0, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x11, 0x1e, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x01, 0x1f, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0xeb, 0x8e, 0xa8, 0x13,
- 0xe0, 0x31, 0x00, 0x00, 0x22, 0x8f, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
- 0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00, 0x12, 0x8f, 0xa2, 0x02,
- 0x02, 0x50, 0x00, 0x00, 0xf9, 0x8e, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xf8, 0x8e, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xf4, 0x8e, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x2d, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
- 0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2f, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x13, 0x8f, 0x22, 0x01, 0x14, 0x6c, 0x00, 0x00,
- 0x06, 0x8f, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x1f, 0x80, 0x01, 0x00, 0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x05, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x02, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x38, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2d, 0xf0,
- 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0xe1, 0xc1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x4a,
- 0xf1, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x8f, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x38, 0xc0, 0x01, 0x00, 0x1d, 0x8f, 0x22, 0x06,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x1b, 0x8f, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x8f, 0x0d,
- 0x42, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8, 0x10, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x37, 0x98, 0x01, 0x00, 0xcf, 0x8e, 0x00, 0xa1, 0x1a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0xcf, 0x8e, 0x00, 0x02,
- 0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
- 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
- 0x27, 0x8f, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x46,
- 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00,
- 0x26, 0x8f, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x8f, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x2a, 0x8f, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xfb, 0x95, 0x00, 0x10, 0x48, 0x31, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x34, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x31, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x60, 0x01, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x39, 0x8f, 0x90, 0xf2,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x32, 0x00, 0x00, 0xa6,
- 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
- 0x42, 0x8f, 0x22, 0x49, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x00, 0xf0, 0x00, 0x0c, 0x18, 0x8c, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x4c,
- 0x95, 0x30, 0x01, 0x00, 0x52, 0x8f, 0x00, 0x00, 0x92, 0xb0, 0x00, 0x00,
- 0x49, 0x8f, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x1e,
- 0x94, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x96, 0xb0, 0x01, 0x00,
- 0x72, 0x98, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00, 0x48, 0x8f, 0xa2, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x5b, 0x8f, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00,
- 0x52, 0x8f, 0x00, 0x00, 0x92, 0xb0, 0x00, 0x00, 0x49, 0x8f, 0x43, 0x48,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00,
- 0x4e, 0x8f, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0x4a, 0x8f, 0x22, 0x48,
- 0x77, 0x7d, 0x00, 0x00, 0x51, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x62, 0xb1, 0x01, 0x00, 0x5a, 0x8f, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x4e, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x1b, 0x00, 0x92, 0xb0, 0x01, 0x00, 0x57, 0x8f, 0x22, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0xcc, 0x95, 0x00, 0xf8, 0x00, 0x30, 0x01, 0x00, 0x54, 0x8f, 0xa2, 0x41,
- 0x3b, 0x50, 0x00, 0x00, 0x5b, 0x8f, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
- 0xff, 0x07, 0x00, 0x1e, 0x00, 0x8c, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x5b, 0x8f, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x1b, 0x47, 0x19, 0x80, 0x01, 0x00, 0x5e, 0x8f, 0x22, 0x5f,
- 0x01, 0x6c, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xaa, 0x8a, 0x00, 0x00, 0x80, 0xb0, 0x00, 0x00, 0x65, 0x8f, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x65, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x62, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x65, 0x8f, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x07, 0x94, 0x89, 0x01, 0x00, 0x6b, 0x8f, 0x85, 0xca,
- 0x94, 0x30, 0x00, 0x00, 0x4b, 0x99, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00,
- 0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00, 0x72, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x20, 0x98, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x19, 0x80, 0x01, 0x00, 0xcf, 0x8d, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
- 0xc7, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x72, 0x8f, 0xa2, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb5, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00,
- 0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x78, 0x8f, 0x90, 0x4c,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x7a, 0x8f, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
- 0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2,
- 0x80, 0xb0, 0x01, 0x00, 0x3e, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0x81, 0x8f, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x81, 0xc0, 0x01, 0x00, 0x82, 0x8f, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00,
- 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
- 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x88, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x94, 0x8f, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
- 0x00, 0x40, 0x00, 0x08, 0x94, 0xdc, 0x01, 0x00, 0x72, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x92, 0x8f, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x08, 0x00, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x94, 0x8f, 0x43, 0x48,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00,
- 0x9a, 0x8f, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0x95, 0x8f, 0x22, 0x48,
- 0x77, 0x7d, 0x00, 0x00, 0xcc, 0x95, 0x1b, 0x08, 0x00, 0x30, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x1b, 0x47,
- 0x19, 0x80, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x63, 0xf3, 0x84, 0xc8, 0x01, 0x00, 0x9f, 0x8f, 0xa0, 0x43,
- 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
- 0x24, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
- 0xaa, 0x8f, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x44,
- 0x83, 0x70, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xcf, 0x8d, 0x1f, 0xf0,
- 0x24, 0x6c, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00,
- 0xaa, 0x8a, 0x23, 0x41, 0x83, 0x6c, 0x00, 0x00, 0xaa, 0x8a, 0x00, 0x47,
- 0x81, 0xb0, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x00, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0xee, 0x97, 0x00, 0x47, 0x61, 0x31, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x08, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x8e, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x7e, 0x8e, 0xa2, 0x40,
- 0x8f, 0x7c, 0x00, 0x00, 0xb8, 0x8f, 0x22, 0x47, 0x8f, 0x7c, 0x00, 0x00,
- 0x7e, 0x8e, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00, 0x27, 0x90, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x5d, 0x05, 0xb4, 0x01, 0x00,
- 0x37, 0x00, 0x2d, 0xf3, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x8e, 0xb0, 0x01, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00,
- 0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x24, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x86, 0xdc, 0x01, 0x00,
- 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0xce, 0x94, 0x00, 0x4a,
- 0xf0, 0x31, 0x01, 0x00, 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0xc6, 0x8f, 0xa2, 0x50, 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x41, 0x81, 0xc0, 0x01, 0x00, 0xc9, 0x8f, 0xa0, 0x43,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x37, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x22, 0x47,
- 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47, 0x0c, 0xf4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x8f, 0x84, 0x01, 0x00, 0xde, 0x8f, 0x22, 0x47,
- 0x0c, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00,
- 0xde, 0x8f, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xd7, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xd4, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xd7, 0x8f, 0x42, 0x40, 0x05, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d,
- 0x69, 0x93, 0x01, 0x00, 0xdc, 0x8f, 0x23, 0x41, 0x0d, 0x6c, 0x00, 0x00,
- 0xb9, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x4b, 0x99, 0x00, 0x05,
- 0x48, 0x31, 0x01, 0x00, 0xaa, 0x8a, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00,
- 0xcf, 0x8d, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00, 0x20, 0x98, 0x00, 0x5f,
- 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xa2, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x84, 0xb0, 0x01, 0x00, 0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0xf2, 0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0xed, 0x8f, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00,
- 0x2c, 0x01, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0xed, 0x8f, 0xa3, 0x40,
- 0x82, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00,
- 0xef, 0x8f, 0x20, 0x4c, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x85, 0xc0, 0x01, 0x00, 0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00,
- 0xa2, 0x00, 0x20, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40,
- 0x87, 0x30, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xf0, 0x80, 0xc0, 0x01, 0x00, 0x20, 0x98, 0x00, 0x5f,
- 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x46,
- 0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x62, 0xf2, 0x96, 0xcc, 0x01, 0x00, 0xcf, 0x8d, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x20, 0x98, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00,
- 0xf5, 0x97, 0x00, 0x46, 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xcf, 0x8d, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00,
- 0x86, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
- 0x80, 0xcc, 0x01, 0x00, 0xcf, 0x8d, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x47,
- 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x5f, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8d, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00,
- 0x13, 0x90, 0x90, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xcf, 0x8d, 0x22, 0x40, 0xe5, 0x6d, 0x00, 0x00, 0xcf, 0x8d, 0x00, 0x41,
- 0xe5, 0xc1, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40,
- 0x87, 0x30, 0x01, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x23, 0x90, 0x80, 0xf3, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe7, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x38, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00,
- 0x34, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x84, 0xcc, 0x01, 0x00, 0x30, 0x90, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x42, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
- 0x32, 0x90, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x62, 0xb1, 0x01, 0x00, 0x33, 0x90, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x35, 0x90, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00,
- 0x35, 0x00, 0x2d, 0xf0, 0x28, 0xb0, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43,
- 0xe7, 0xe1, 0x01, 0x00, 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00,
- 0xe0, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x2b, 0xb0, 0x01, 0x00, 0x04, 0x98, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x16, 0xc0, 0x01, 0x00, 0x47, 0x90, 0xa0, 0x14,
- 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xf8, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00,
- 0x10, 0x50, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x50, 0x90, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
- 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x50, 0x90, 0xa4, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x01, 0x00, 0x6e, 0x43, 0x86, 0x98, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30,
- 0x81, 0x30, 0x01, 0x00, 0x54, 0x90, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x5b, 0x90, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
- 0x17, 0xc0, 0x01, 0x00, 0x5a, 0x90, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x41, 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x61, 0x90, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00,
- 0xa0, 0x00, 0x20, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46,
- 0x19, 0x10, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
- 0x17, 0xf0, 0x01, 0x00, 0x66, 0x90, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x68, 0x90, 0x22, 0x43,
- 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
- 0x3e, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0x6f, 0x90, 0x24, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x81, 0xc0, 0x01, 0x00,
- 0x70, 0x90, 0x00, 0x94, 0xe5, 0xb1, 0x00, 0x00, 0x02, 0x00, 0x62, 0x40,
- 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
- 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
- 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0x76, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x80, 0x90, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00, 0x00, 0x40, 0x00, 0x08,
- 0x94, 0xdc, 0x01, 0x00, 0x72, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x7b, 0x90, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x84, 0x90, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x80, 0x90, 0x43, 0x48, 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08,
- 0x62, 0xdd, 0x01, 0x00, 0x81, 0x90, 0xa8, 0x40, 0x05, 0x30, 0x00, 0x00,
- 0x35, 0x00, 0x1b, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x84, 0xc8, 0x01, 0x00, 0x87, 0x90, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xe7, 0x91, 0x01, 0x00, 0x20, 0x98, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
- 0xcf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
- 0x27, 0x90, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x69, 0x96, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x75, 0x8e, 0x22, 0x4a,
- 0x80, 0x32, 0x00, 0x00, 0xa5, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00, 0x9f, 0x8e, 0x22, 0x06,
- 0x90, 0x6c, 0x00, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
- 0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
- 0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50, 0xe7, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00, 0xa1, 0x90, 0xa0, 0x43,
- 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xcc, 0x94, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xa3, 0x90, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x9f, 0x8e, 0x1a, 0x5d,
- 0x69, 0x93, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
- 0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
- 0x01, 0x00, 0x6b, 0xfb, 0x84, 0xc8, 0x01, 0x00, 0xae, 0x90, 0xa0, 0x43,
- 0x85, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x12, 0xc8, 0x01, 0x00, 0xb1, 0x90, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0xce, 0x94, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb4, 0x90, 0x42, 0x05,
- 0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x11, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
- 0xa3, 0x8f, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xad, 0x8f, 0x00, 0xf0,
- 0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xbf, 0x90, 0x47, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
- 0x13, 0xf0, 0x01, 0x00, 0xc4, 0x90, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
- 0x6b, 0x84, 0x1f, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xbe, 0x90, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x1f, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xc6, 0x90, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
- 0x46, 0x97, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0xd0, 0x90, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
- 0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0xcd, 0x90, 0x00, 0x50,
- 0x43, 0xc1, 0x00, 0x00, 0xdc, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
- 0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0xda, 0x90, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
- 0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0xe2, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
- 0xe6, 0x90, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x1f, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x62, 0xb1, 0x01, 0x00, 0xea, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xef, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0xed, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
- 0x97, 0xb0, 0x01, 0x00, 0xf5, 0x90, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
- 0xf5, 0x90, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0x6b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xf0, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xaf, 0x97, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xfb, 0x90, 0x22, 0xf3, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x42,
- 0x81, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x42,
- 0x19, 0x80, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
- 0x20, 0x98, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xc9, 0x96, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x40,
- 0x95, 0x6c, 0x00, 0x00, 0x06, 0x91, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x40,
- 0x95, 0x30, 0x01, 0x00, 0x11, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0xff, 0x89, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x23, 0x00, 0xa6,
- 0x16, 0xb0, 0x01, 0x00, 0x14, 0x91, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0xc0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
- 0x18, 0x91, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x19, 0x98, 0x00, 0x43,
- 0x61, 0x31, 0x01, 0x00, 0xda, 0x94, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00,
- 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x20, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x1d, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa1, 0x97, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x24, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
- 0x2b, 0x91, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
- 0x2c, 0x91, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45,
- 0x1f, 0x90, 0x01, 0x00, 0x87, 0x91, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
- 0x87, 0x91, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x3f, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x3b, 0x91, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x38, 0x91, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x96, 0x00, 0x15,
- 0x94, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xff, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x42, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x43, 0x91, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6f, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15,
- 0x98, 0xc8, 0x01, 0x00, 0x6f, 0x91, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00,
- 0x4b, 0x91, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b,
- 0x99, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00,
- 0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0, 0x22, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41, 0xe7, 0xe1, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x47,
- 0xe7, 0xb5, 0x01, 0x00, 0x5c, 0x91, 0x23, 0x0b, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x02, 0xd0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x00,
- 0x2a, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x61, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
- 0x80, 0xce, 0x01, 0x00, 0x6d, 0x91, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x98, 0xd0, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x74, 0x91, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x15, 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
- 0xe4, 0xcd, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00,
- 0xf8, 0x97, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00, 0x79, 0x91, 0x22, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x7a, 0x91, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00,
- 0xda, 0x94, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6,
- 0x16, 0xb0, 0x01, 0x00, 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x82, 0x91, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x7f, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x85, 0x91, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xba, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a,
- 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00,
- 0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
- 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
- 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
- 0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00, 0x5b, 0x97, 0x00, 0x40,
- 0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xcb, 0x91, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
- 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
- 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0xa1, 0x91, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xa1, 0x91, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9d, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0xc4, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0xb2, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x21, 0x97, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x74, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xbf, 0x91, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xa8, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xae, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xe2, 0x95, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0xaf, 0x91, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb1, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x21, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x70, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xb5, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xbb, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
- 0x11, 0x30, 0x01, 0x00, 0xbc, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbe, 0x91, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xc0, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc7, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
- 0x11, 0x30, 0x01, 0x00, 0xc8, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xca, 0x91, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xbf, 0x8d, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0xd2, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xce, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xd6, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x40,
- 0x11, 0x30, 0x01, 0x00, 0xd7, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a,
- 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xdc, 0x91, 0x03, 0x1e,
- 0x80, 0x32, 0x00, 0x00, 0xdd, 0x91, 0x00, 0x41, 0x87, 0xb0, 0x00, 0x00,
- 0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0xe1, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xe4, 0x91, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x80, 0x01, 0x00, 0xba, 0x8d, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
- 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xea, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfb, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbf, 0x8d, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xf6, 0x91, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
- 0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xfe, 0x91, 0xa2, 0x40,
- 0xe5, 0x6d, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13,
- 0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00,
- 0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0c, 0x92, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15, 0x98, 0x50, 0x00, 0x00,
- 0x0c, 0x92, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x09, 0x92, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15, 0x10, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
- 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
- 0x8e, 0x91, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0x20, 0x98, 0x00, 0x09,
- 0x80, 0x30, 0x01, 0x00, 0x8e, 0x91, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0xea, 0x96, 0x00, 0xf0,
- 0x84, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0x2c, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
- 0xdc, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf5, 0x97, 0x00, 0x48,
- 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x21, 0x92, 0xa8, 0x40,
- 0x13, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x27, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x26, 0x92, 0x00, 0x40,
- 0x13, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xea, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x3f, 0x92, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0xba, 0x8d, 0x87, 0x42,
- 0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00,
- 0xba, 0x8d, 0x00, 0x40, 0xe7, 0x91, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x3d, 0x92, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
- 0x51, 0x95, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0x3d, 0x92, 0x22, 0x00,
- 0x80, 0x32, 0x00, 0x00, 0x38, 0x92, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x3d, 0x92, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0xf2,
- 0x02, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x3e, 0x92, 0x00, 0x40,
- 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x44, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x43, 0x92, 0xa2, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x44, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xce, 0x92, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x4c, 0x92, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x49, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xce, 0x92, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x52, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x4d,
- 0x81, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x96, 0xb0, 0x01, 0x00, 0x60, 0x92, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x92, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x61, 0x92, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x65, 0x92, 0x47, 0xf2, 0x12, 0x30, 0x00, 0x00,
- 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x6a, 0x92, 0x22, 0x47,
- 0xe7, 0x7d, 0x00, 0x00, 0x6b, 0x84, 0x1f, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x64, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0xe7, 0x91, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x09, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x72, 0x92, 0xa8, 0x40,
- 0xe1, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x76, 0x92, 0x47, 0x05,
- 0x48, 0x31, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x7e, 0x92, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x7c, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b,
- 0x16, 0xdc, 0x01, 0x00, 0x51, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x96, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xff, 0x96, 0x00, 0x5f,
- 0x01, 0x10, 0x01, 0x00, 0x80, 0x92, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x88, 0x92, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x74, 0x96, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x80, 0x92, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x80, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x00, 0x98, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0xe1, 0xb1, 0x01, 0x00,
- 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xa0, 0x92, 0x30, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
- 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe6, 0x81, 0x01, 0x00, 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00,
- 0xd1, 0x99, 0x00, 0x5f, 0x95, 0x04, 0x01, 0x00, 0x55, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xaa, 0x92, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
- 0xa8, 0x92, 0x43, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x41,
- 0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0f, 0xb0, 0x01, 0x00, 0xb8, 0x95, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xbb, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
- 0xb4, 0x92, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x62, 0xb1, 0x01, 0x00, 0xb8, 0x92, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xb5, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x62, 0xb1, 0x01, 0x00, 0xb8, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x22, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0xf5, 0x97, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00, 0xdc, 0x96, 0x00, 0x5c,
- 0x1f, 0x10, 0x01, 0x00, 0x52, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xcc, 0x92, 0x22, 0x47,
- 0xe7, 0x7d, 0x00, 0x00, 0x51, 0x95, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00,
- 0xcc, 0x92, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xc7, 0x92, 0xa2, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xcc, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00,
- 0x74, 0x96, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xf5, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00, 0xdc, 0x96, 0x00, 0x5c,
- 0x1f, 0x10, 0x01, 0x00, 0xd1, 0x92, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
- 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe7, 0x91, 0x01, 0x00, 0x20, 0x98, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
- 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdc, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0,
- 0x84, 0x30, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x20, 0x98, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
- 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xe5, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xaf, 0x97, 0x00, 0x47,
- 0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07, 0x84, 0x94, 0x01, 0x00,
- 0xa1, 0x97, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xcc, 0x95, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
- 0x2c, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00, 0x01, 0x93, 0x26, 0x47,
- 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
- 0x01, 0x93, 0x23, 0x4b, 0x0c, 0x6c, 0x00, 0x00, 0x33, 0x98, 0x00, 0x4b,
- 0x04, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x16, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0xb0, 0x01, 0x00,
- 0x33, 0x98, 0x00, 0x4b, 0x04, 0x50, 0x01, 0x00, 0x02, 0x93, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x33, 0x98, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
- 0x08, 0x93, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x06, 0x93, 0x84, 0x48,
- 0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x08, 0x93, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x02, 0xb0, 0x01, 0x00, 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x09, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
- 0x16, 0x93, 0x22, 0x06, 0x14, 0x50, 0x00, 0x00, 0x24, 0x97, 0x00, 0x45,
- 0x1f, 0x00, 0x01, 0x00, 0xf5, 0x92, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x12, 0x93, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf5, 0x92, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x1c, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x22, 0x93, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x26, 0x93, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x26, 0x93, 0xa2, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x34, 0x93, 0x22, 0x4a,
- 0x1f, 0x7c, 0x00, 0x00, 0x2c, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x30, 0x93, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x31, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
- 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x16,
- 0xe4, 0xb1, 0x00, 0x00, 0x46, 0x93, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xf4, 0x98, 0x00, 0x40,
- 0x95, 0x30, 0x01, 0x00, 0x47, 0x93, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
- 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01,
- 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0xf8, 0x97, 0x00, 0x08,
- 0x80, 0x30, 0x01, 0x00, 0x3f, 0x93, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
- 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x40, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x54, 0x93, 0x20, 0x16,
- 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x51, 0x93, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x2c, 0xd0, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x5b, 0x93, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00, 0x5c, 0x93, 0x00, 0x0a,
- 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00,
- 0x5b, 0x97, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0x64, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x60, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x73, 0x93, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
- 0x74, 0x93, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
- 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x6b, 0x93, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
- 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x74, 0x93, 0x00, 0x5c,
- 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
- 0xe2, 0x95, 0x00, 0x40, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x78, 0x93, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x80, 0x93, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x80, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x7c, 0x93, 0xa8, 0x46, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x85, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x8b, 0x93, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x8f, 0x93, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x8f, 0x93, 0xa2, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0xa4, 0x93, 0x22, 0x4a,
- 0x1f, 0x7c, 0x00, 0x00, 0x95, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xa0, 0x93, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0x99, 0x93, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00,
- 0x9d, 0x93, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
- 0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00,
- 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa1, 0x93, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
- 0xe4, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
- 0xa7, 0x93, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf4, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xb4, 0x93, 0x22, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0xb1, 0x93, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0xac, 0x93, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
- 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0xb0, 0x93, 0x22, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x58, 0x01, 0x2d, 0x00,
- 0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0, 0x10, 0xb0, 0x01, 0x00,
- 0x3f, 0x91, 0x00, 0xf0, 0x2c, 0xb0, 0x00, 0x00, 0xf4, 0x98, 0x00, 0x41,
- 0x95, 0x30, 0x01, 0x00, 0xbb, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0xb9, 0x93, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
- 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xf4, 0x93, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
- 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
- 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00,
- 0xcb, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0xc4, 0x93, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0,
- 0x22, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x84, 0xb0, 0x01, 0x00, 0xce, 0x93, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xd3, 0x93, 0x22, 0x40,
- 0x1b, 0x6c, 0x00, 0x00, 0xf8, 0x97, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00,
- 0xdb, 0x93, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x80, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
- 0xd9, 0x93, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0xea, 0x93, 0x00, 0x5e,
- 0x17, 0x90, 0x00, 0x00, 0xde, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x84, 0xd0, 0x01, 0x00, 0xe3, 0x93, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
- 0x19, 0x98, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xea, 0x93, 0x22, 0x40,
- 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0xc0, 0x01, 0x00,
- 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
- 0xe8, 0x93, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xeb, 0x93, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
- 0xf2, 0x93, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x11,
- 0x00, 0x8c, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x98, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0xa1, 0x97, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xbf, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x8e, 0xb0, 0x01, 0x00, 0xb3, 0x96, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x41,
- 0x87, 0x30, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x05, 0x94, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x01, 0x94, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x94, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x1a, 0xd0, 0x01, 0x00, 0x0d, 0x94, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xf4, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0x15, 0x94, 0x22, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x38, 0x93, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
- 0xf4, 0x98, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0x10, 0x94, 0x22, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0xbb, 0x93, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0x13, 0x94, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
- 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x19, 0x94, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00,
- 0xf4, 0x95, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00, 0x27, 0x94, 0x26, 0x47,
- 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
- 0x27, 0x94, 0x23, 0x4b, 0x0c, 0x6c, 0x00, 0x00, 0x33, 0x98, 0x00, 0x4b,
- 0x04, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x16, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x04, 0xb0, 0x01, 0x00,
- 0x33, 0x98, 0x00, 0x4b, 0x04, 0x50, 0x01, 0x00, 0x28, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x33, 0x98, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
- 0x2d, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00, 0xda, 0x94, 0x00, 0x01,
- 0x8c, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
- 0x34, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x30, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0x3d, 0x94, 0x22, 0x06,
- 0x14, 0x50, 0x00, 0x00, 0x24, 0x97, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00,
- 0x1b, 0x94, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x39, 0x94, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x1b, 0x94, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x42, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x48, 0x94, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x4b, 0x94, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00,
- 0x59, 0x94, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x51, 0x94, 0xa2, 0x16,
- 0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
- 0x55, 0x94, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xf9, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x56, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00,
- 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00,
- 0xba, 0x8d, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00, 0x35, 0x93, 0xa2, 0x16,
- 0x02, 0x30, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbf, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x95, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
- 0x49, 0x93, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x63, 0x94, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x66, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x74, 0x96, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00,
- 0x7b, 0x96, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x68, 0x94, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x20, 0x98, 0x00, 0x45,
- 0x81, 0x30, 0x01, 0x00, 0xba, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xfe, 0x91, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x7a, 0x94, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
- 0x73, 0x94, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x62, 0xb1, 0x01, 0x00, 0x77, 0x94, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x74, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x62, 0xb1, 0x01, 0x00, 0x77, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xff, 0x89, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08,
- 0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00,
- 0xb6, 0x96, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
- 0xbf, 0x95, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00, 0x8c, 0x94, 0xa2, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x88, 0x94, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
- 0x74, 0x96, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0x7b, 0x96, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf9, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0xaf, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
- 0xff, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08,
- 0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00,
- 0xf4, 0x95, 0x00, 0x10, 0x32, 0x30, 0x01, 0x00, 0x49, 0x93, 0x00, 0x40,
- 0x13, 0xb0, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x9c, 0x94, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x95, 0x94, 0x37, 0x5c,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
- 0x99, 0x94, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x96, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
- 0x99, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0x89, 0x17, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00,
- 0xb3, 0x96, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0xea, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
- 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xab, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xa7, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x3f, 0x91, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00,
- 0x87, 0x91, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0xb3, 0x94, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
- 0xef, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x96, 0x00, 0x4a,
- 0x1f, 0x10, 0x01, 0x00, 0x6f, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x49, 0x93, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0xf4, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x49, 0x93, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00,
- 0xfe, 0x91, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x37, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x33, 0xc3, 0x01, 0x00,
- 0x36, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x94, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x9f, 0x48, 0x03, 0xd0, 0x00, 0x00, 0xc1, 0x94, 0x9c, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x4c, 0x03, 0xd0, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x01, 0x34, 0xc3, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x11,
- 0x10, 0xc1, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x40, 0x43, 0xc1, 0x00, 0x00,
- 0xc6, 0x94, 0x00, 0x50, 0x43, 0xc1, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa1,
- 0x42, 0xc9, 0x01, 0x00, 0xca, 0x94, 0x22, 0x40, 0xe5, 0x6d, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x40, 0xe5, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x41, 0x23, 0xd0, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x50,
- 0x43, 0xd1, 0x00, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0, 0xb1, 0x01, 0x00,
- 0xd0, 0x95, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00, 0x00, 0x80, 0x00, 0x43,
- 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd7, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40,
- 0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01, 0xe0, 0xc1, 0x01, 0x00,
- 0xe1, 0x94, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xfb, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xe3, 0x94, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0x8d, 0x98, 0x00, 0x47,
- 0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
- 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xd8, 0x98, 0x00, 0xf0,
- 0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xf8, 0x94, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x4b, 0x95, 0xa2, 0x4c,
- 0x1f, 0x7c, 0x00, 0x00, 0xf8, 0x94, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
- 0xfb, 0x94, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
- 0x8f, 0xb0, 0x01, 0x00, 0xf1, 0x94, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
- 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xf3, 0x94, 0x22, 0xf0,
- 0x3a, 0x6c, 0x00, 0x00, 0x48, 0x95, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
- 0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x49, 0x95, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xf7, 0x94, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xfa, 0x94, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0xff, 0x94, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x08, 0x95, 0x23, 0xf0,
- 0x02, 0x6c, 0x00, 0x00, 0x05, 0x95, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
- 0x4a, 0x95, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x4a, 0x95, 0xa2, 0x41,
- 0x03, 0x6c, 0x00, 0x00, 0x04, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x52,
- 0x8f, 0xb0, 0x01, 0x00, 0x4a, 0x95, 0x1f, 0x12, 0x84, 0x50, 0x00, 0x00,
- 0x4a, 0x95, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00, 0xf8, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x33, 0x95, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x25, 0x95, 0x22, 0xf0, 0x14, 0x30, 0x00, 0x00,
- 0x11, 0x95, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x22, 0x95, 0x03, 0x1e,
- 0x80, 0x32, 0x00, 0x00, 0x10, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
- 0x8f, 0xb0, 0x01, 0x00, 0x16, 0x95, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00,
- 0x19, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x15, 0x95, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00, 0x18, 0x95, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xd0, 0x01, 0x00,
- 0x1f, 0x95, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00, 0x1e, 0x95, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x21, 0x95, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x24, 0x95, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
- 0x8f, 0xb0, 0x01, 0x00, 0x2e, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x2b, 0x95, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x2b, 0x95, 0xa2, 0xf2,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x2d, 0x95, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x2b, 0x95, 0xa0, 0x91,
- 0x03, 0x6c, 0x00, 0x00, 0x29, 0x95, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00,
- 0x32, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x28, 0x00, 0x80, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x3c, 0x95, 0xa2, 0xf0,
- 0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00,
- 0x39, 0x95, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
- 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
- 0x2b, 0x95, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x29, 0x95, 0x20, 0x91,
- 0x03, 0x6c, 0x00, 0x00, 0x2b, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x40, 0x95, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x3f, 0x95, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x45, 0x95, 0x22, 0x0a,
- 0x02, 0x6c, 0x00, 0x00, 0x19, 0x95, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x44, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
- 0x47, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
- 0x4d, 0x95, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x41,
- 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x42, 0x95, 0xb0, 0x00, 0x00,
- 0x4d, 0x95, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00, 0x4d, 0x95, 0x00, 0x4c,
- 0x95, 0xb0, 0x00, 0x00, 0xf5, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x50, 0x95, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00,
- 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
- 0x84, 0xb0, 0x01, 0x00, 0x55, 0x95, 0xa2, 0xf3, 0x96, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x2a, 0x41,
- 0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41, 0x85, 0xe0, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00, 0x5b, 0x95, 0x22, 0x5a,
- 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
- 0x5c, 0x95, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x85, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0xa0, 0xa5, 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x3d, 0x99, 0x00, 0xf0,
- 0x8c, 0xb0, 0x00, 0x00, 0x69, 0x95, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x66, 0x95, 0xa2, 0x4b,
- 0x19, 0x7c, 0x00, 0x00, 0x67, 0x95, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x32, 0x96, 0x00, 0x07,
- 0x10, 0x30, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x6b, 0x95, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0xb8, 0x95, 0x00, 0x40,
- 0x81, 0x30, 0x01, 0x00, 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x32, 0x96, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
- 0x6f, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x32, 0x96, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0x74, 0x95, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x77, 0x95, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x85, 0x95, 0x13, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
- 0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x0f,
- 0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x4e, 0xb0, 0x01, 0x00, 0x12, 0x86, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00,
- 0x82, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0x86, 0x95, 0x44, 0x07, 0x96, 0x30, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xc2,
- 0x24, 0xb0, 0x01, 0x00, 0x90, 0x95, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
- 0x8a, 0x95, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x91, 0x95, 0x22, 0x12,
- 0x48, 0x7f, 0x00, 0x00, 0x51, 0x98, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x1e, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
- 0x90, 0x95, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
- 0x24, 0xb0, 0x01, 0x00, 0x91, 0x95, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
- 0x51, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x9e, 0x95, 0x0b, 0xf0, 0x84, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00, 0x9b, 0x95, 0x22, 0x50,
- 0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x51, 0x97, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00, 0xd1, 0x99, 0x00, 0x12,
- 0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x1f, 0x90, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
- 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42, 0x10, 0xf4, 0x01, 0x00,
- 0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
- 0x8a, 0x88, 0x01, 0x00, 0xa1, 0x95, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
- 0xa4, 0x95, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x91, 0x95, 0x10, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00,
- 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x51, 0x97, 0x00, 0xf2,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xaf, 0x95, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0xb3, 0x95, 0xa8, 0x05, 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0f,
- 0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42, 0x84, 0x88, 0x01, 0x00,
- 0xbc, 0x95, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0xbd, 0x95, 0x00, 0x42,
- 0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6a, 0xb1, 0x01, 0x00,
- 0xbd, 0x95, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
- 0x48, 0x93, 0x01, 0x00, 0xbf, 0x95, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc4, 0x95, 0x28, 0xb1,
- 0x2c, 0x30, 0x00, 0x00, 0xc0, 0x95, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x95, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xc4, 0x95, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xcb, 0x95, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
- 0xc7, 0x95, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x11, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x24, 0x11, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcd, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xd1, 0x95, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xd7, 0x95, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf8,
- 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x92, 0x48,
- 0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xdb, 0x95, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00, 0xd7, 0x95, 0x22, 0x4c,
- 0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40, 0x91, 0xb0, 0x00, 0x00,
- 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xdb, 0x95, 0xa8, 0xb1,
- 0x90, 0x30, 0x00, 0x00, 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b,
- 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x92, 0x49, 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
- 0x00, 0xec, 0x00, 0x00, 0xe8, 0x95, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x00, 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0xe4, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
- 0x00, 0xec, 0x00, 0x00, 0xf1, 0x95, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00,
- 0xcc, 0x95, 0x00, 0x00, 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0xed, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xf6, 0x95, 0x83, 0x1e,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00,
- 0x24, 0x00, 0x2d, 0x01, 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
- 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
- 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x11, 0x10, 0xc1, 0x00, 0x00,
- 0xff, 0x95, 0x00, 0x40, 0x43, 0xc1, 0x00, 0x00, 0xff, 0x95, 0x00, 0x50,
- 0x43, 0xc1, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x96, 0x22, 0x40, 0xf5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x43, 0xd1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0xe5, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
- 0x1f, 0x90, 0x01, 0x00, 0x07, 0x96, 0x22, 0x11, 0x1e, 0x7c, 0x00, 0x00,
- 0x09, 0x96, 0xa0, 0xf0, 0x16, 0x40, 0x00, 0x00, 0x09, 0x96, 0x00, 0x41,
- 0x17, 0xc0, 0x00, 0x00, 0x09, 0x96, 0xa0, 0xf4, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
- 0x23, 0xd0, 0x00, 0x00, 0xff, 0x95, 0x00, 0x52, 0x43, 0xd1, 0x00, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x0c, 0x96, 0x30, 0x47,
- 0x17, 0x04, 0x00, 0x00, 0x0f, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
- 0x46, 0xc9, 0x01, 0x00, 0x13, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x14, 0x96, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0xdb, 0x99, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x1e, 0x96, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00,
- 0x01, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
- 0x40, 0x97, 0x3e, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
- 0x31, 0x96, 0x00, 0x3b, 0xe7, 0xb1, 0x00, 0x00, 0x1e, 0x96, 0x30, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x28, 0x96, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x24, 0x96, 0xa2, 0x0b,
- 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x98, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
- 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41,
- 0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x4a, 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41,
- 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
- 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07,
- 0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
- 0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
- 0x35, 0x96, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00, 0xdb, 0x99, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x41, 0x96, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
- 0x3d, 0x96, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f,
- 0x96, 0xf4, 0x01, 0x00, 0x3a, 0x96, 0x31, 0x5f, 0x97, 0x04, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x6a, 0xb1, 0x01, 0x00, 0x3d, 0x96, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x49, 0x96, 0xa2, 0x3b,
- 0x89, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0x4a, 0x96, 0x18, 0x4a,
- 0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00, 0x4f, 0x96, 0x22, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x51, 0x96, 0x00, 0x05,
- 0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x52, 0x96, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x55, 0x96, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00,
- 0xdb, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x59, 0x96, 0x22, 0x45,
- 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xd9, 0x99, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
- 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
- 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
- 0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0x61, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5a, 0x96, 0xa2, 0x3b,
- 0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd1, 0x99, 0x00, 0x12,
- 0x94, 0x30, 0x01, 0x00, 0x32, 0x96, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a,
- 0xe6, 0xc9, 0x01, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
- 0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
- 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
- 0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf2, 0x02, 0x30, 0x00, 0x00, 0x51, 0x95, 0x00, 0x10,
- 0x32, 0x30, 0x01, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
- 0x78, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x36, 0xb0, 0x01, 0x00, 0x88, 0x96, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x81, 0x96, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x7c, 0x96, 0x00, 0x5c,
- 0x01, 0x80, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x46, 0xc9, 0x01, 0x00, 0xc7, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xaf, 0x96, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x08, 0x38, 0x96, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
- 0x82, 0xcc, 0x01, 0x00, 0x8d, 0x96, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x11, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00,
- 0xae, 0x96, 0x26, 0x46, 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,
- 0x12, 0xc8, 0x01, 0x00, 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00,
- 0xad, 0x96, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x22, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x9f, 0x96, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0xac, 0x96, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0xaa, 0x96, 0xa2, 0x41,
- 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xa5, 0x96, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x13, 0xc0, 0x01, 0x00, 0x9a, 0x96, 0x00, 0x50,
- 0x49, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x1a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xae, 0x96, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x5c,
- 0x01, 0x00, 0x01, 0x00, 0xaf, 0x96, 0x00, 0x41, 0x3b, 0xd0, 0x00, 0x00,
- 0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5f,
- 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
- 0xbb, 0x96, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8, 0x14, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8, 0x0c, 0xb0, 0x01, 0x00,
- 0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
- 0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
- 0xc8, 0x96, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x96, 0xb0, 0x01, 0x00,
- 0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x20, 0x4a,
- 0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
- 0xb3, 0x96, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
- 0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0xce, 0x96, 0xa2, 0xa5,
- 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
- 0xd1, 0x96, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
- 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
- 0xd6, 0x96, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
- 0xdb, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
- 0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x0b, 0x00, 0x80, 0x00,
- 0xe4, 0xf5, 0x01, 0x00, 0xd0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
- 0xe7, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd0, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
- 0xf6, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00,
- 0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00, 0xfe, 0x96, 0x9f, 0x41,
- 0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5, 0x85, 0xcc, 0x01, 0x00,
- 0x2d, 0x00, 0xa0, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0x5e, 0x01, 0x2d, 0x00,
- 0x80, 0xb0, 0x01, 0x00, 0x03, 0x97, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0x04, 0x97, 0x00, 0x41,
- 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
- 0x05, 0x97, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x0a, 0x97, 0xa2, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0x1f, 0x97, 0x9c, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x14, 0x97, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
- 0x98, 0xf4, 0x01, 0x00, 0x13, 0x97, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0x13, 0x97, 0xa2, 0x8a,
- 0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
- 0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x1e, 0x97, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
- 0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
- 0x3a, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
- 0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
- 0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0x2b, 0x97, 0x22, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x35, 0x97, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x01, 0x96, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x3b, 0x97, 0x45, 0x42,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0x3c, 0x97, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x01, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x42, 0x97, 0x45, 0x42, 0x61, 0x31, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x43, 0x97, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00,
- 0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00, 0x02, 0x00, 0x00, 0x09,
- 0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x4d, 0x97, 0x46, 0x42,
- 0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a, 0x62, 0xc9, 0x01, 0x00,
- 0x4e, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x97, 0xf0, 0x01, 0x00,
- 0x52, 0x97, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5a, 0x97, 0x22, 0xf3,
- 0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x94, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x55,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x57, 0x97, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00, 0x6a, 0x97, 0x82, 0x41,
- 0x23, 0x40, 0x00, 0x00, 0x5f, 0x97, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x20, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x65, 0x97, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x62, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x6a, 0x97, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x95, 0x00, 0x43,
- 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
- 0x6c, 0x97, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00, 0x6d, 0x97, 0x00, 0x06,
- 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x04, 0xb0, 0x01, 0x00,
- 0x6f, 0x97, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x04, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x0b, 0x96, 0x88, 0x01, 0x00,
- 0x74, 0x97, 0x26, 0x47, 0x97, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x97, 0xc0, 0x01, 0x00, 0x74, 0x97, 0x23, 0x4b, 0x04, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x04, 0xb0, 0x01, 0x00, 0x33, 0x98, 0x00, 0x05,
- 0x48, 0x31, 0x01, 0x00, 0x9e, 0x97, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
- 0x78, 0x97, 0xa2, 0x02, 0x2a, 0x50, 0x00, 0x00, 0x9e, 0x97, 0xa2, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x7a, 0x97, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00,
- 0x83, 0x97, 0x00, 0x02, 0x16, 0xc0, 0x00, 0x00, 0x82, 0x97, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x82, 0x97, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x7e, 0x97, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x24, 0x97, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x9e, 0x97, 0x22, 0x15,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x9d, 0x97, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00, 0x8f, 0x97, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x8f, 0x97, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x97, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1b, 0x84, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
- 0x2f, 0x00, 0x2f, 0x5c, 0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0xe7, 0x91, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00,
- 0x5c, 0x97, 0x20, 0x15, 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
- 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x9a, 0x97, 0xa8, 0x46,
- 0x1f, 0x10, 0x00, 0x00, 0x5c, 0x97, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x5c, 0x97, 0x00, 0x02, 0x10, 0xc0, 0x00, 0x00, 0xa0, 0x97, 0xa2, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0xda, 0x94, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x08, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0xa7, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x27, 0xec, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x00, 0xb0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x41,
- 0xa3, 0x41, 0x01, 0x00, 0xab, 0x97, 0x00, 0x41, 0x27, 0xd0, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb2, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x98, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06,
- 0x16, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00,
- 0xba, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x6c, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40,
- 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00,
- 0xc3, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43,
- 0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00,
- 0xc3, 0x97, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0xe4, 0x97, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00,
- 0xd0, 0x97, 0xa2, 0x06, 0x14, 0x6c, 0x00, 0x00, 0xcd, 0x97, 0x22, 0x48,
- 0x19, 0x7c, 0x00, 0x00, 0xc8, 0x97, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x31, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
- 0x8b, 0x00, 0x2d, 0x48, 0x19, 0x80, 0x01, 0x00, 0x8b, 0x00, 0x20, 0x45,
- 0xe7, 0x91, 0x01, 0x00, 0xd0, 0x97, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00, 0xd0, 0x97, 0xa0, 0x48,
- 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43,
- 0xfc, 0xc9, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0xdb, 0x97, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
- 0x17, 0xc0, 0x01, 0x00, 0xda, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xdf, 0x97, 0x64, 0xf0,
- 0x82, 0xb0, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xdf, 0x97, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe5, 0xb1, 0x01, 0x00, 0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
- 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06,
- 0x30, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00,
- 0xbc, 0x00, 0x2d, 0x46, 0x19, 0x90, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2,
- 0xe4, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00, 0x3b, 0x98, 0x00, 0x30,
- 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x4a, 0x19, 0xfc, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
- 0xed, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xe4, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x1b, 0xe0, 0xb1, 0x00, 0x00,
- 0xf2, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c,
- 0x7e, 0x89, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x4c, 0x95, 0x60, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x4a, 0x18, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15,
- 0xe0, 0xb1, 0x00, 0x00, 0xfd, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0xe8, 0x5f, 0x17, 0x90, 0x01, 0x00, 0x70, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x7a, 0x01, 0x2e, 0xfe, 0x92, 0xb0, 0x01, 0x00,
- 0x8b, 0x00, 0x2d, 0xf6, 0x16, 0xb0, 0x01, 0x00, 0x0a, 0x98, 0x22, 0x43,
- 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xa6, 0x2a, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x6e, 0x06,
- 0x82, 0xc8, 0x01, 0x00, 0x0e, 0x98, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x6e, 0x4c,
- 0x83, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00,
- 0x0f, 0x98, 0x42, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x66, 0x9e,
- 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x41, 0x3d, 0xc3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa2,
- 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x49, 0x98, 0xf4, 0x01, 0x00,
- 0x18, 0x98, 0x26, 0x30, 0x93, 0x04, 0x00, 0x00, 0x18, 0x98, 0x90, 0x4c,
- 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
- 0xff, 0xff, 0x80, 0x49, 0xec, 0xa9, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00, 0x1d, 0x98, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x2a, 0x98, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00,
- 0x29, 0x98, 0xa2, 0x40, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x97, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0x29, 0x98, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x26, 0x98, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00,
- 0x2d, 0x98, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43,
- 0x19, 0x7c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x30, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02,
- 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x13, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x08, 0xe0, 0xb1, 0x00, 0x00, 0x38, 0x98, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0xf0, 0x98, 0xf4, 0x01, 0x00, 0x41, 0x98, 0x20, 0x4c,
- 0x84, 0x6c, 0x00, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x41, 0x98, 0x20, 0xf2, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14,
- 0x98, 0xd0, 0x01, 0x00, 0x46, 0x98, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x80, 0xe0, 0x01, 0x00, 0x49, 0x98, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14,
- 0xe0, 0xb1, 0x01, 0x00, 0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x6e, 0xf3, 0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42,
- 0x82, 0xc0, 0x00, 0x00, 0x4f, 0x98, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
- 0x82, 0xec, 0x00, 0x00, 0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00,
- 0x52, 0x98, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x80, 0x4b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x50, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x56, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x5b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x80, 0x60, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x65, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x6b, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x70, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x80, 0x75, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x7a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x72, 0x98, 0x43, 0x57, 0x61, 0x31, 0x00, 0x00, 0x7e, 0x98, 0xa2, 0x57,
- 0x73, 0x7d, 0x00, 0x00, 0x7e, 0x98, 0xa2, 0x40, 0x81, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x4a,
- 0x62, 0xdd, 0x01, 0x00, 0x76, 0x98, 0xa8, 0x4a, 0x80, 0x33, 0x00, 0x00,
- 0x7b, 0x98, 0x22, 0x5f, 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x79, 0x98, 0xa8, 0x4b, 0xac, 0x33, 0x00, 0x00,
- 0x00, 0x00, 0x1b, 0xa5, 0x82, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbe,
- 0x83, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x10, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0x82, 0x98, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x7e, 0x98, 0x22, 0x57, 0x77, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x9b, 0x20, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x82, 0x98, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x9b, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xa8, 0x00, 0x2d, 0x1c, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
- 0x8a, 0xd0, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00,
- 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00,
- 0x97, 0x98, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xbe, 0x00, 0x2f, 0xab,
- 0x83, 0xb0, 0x01, 0x00, 0xff, 0x98, 0x00, 0x14, 0x82, 0x50, 0x01, 0x00,
- 0x9c, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9c, 0x98, 0x22, 0xf2,
- 0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x9c, 0x98, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xff, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0x30,
- 0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00, 0xc6, 0x98, 0x23, 0xf0,
- 0x84, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x42, 0x88, 0xf4, 0x01, 0x00,
- 0xc6, 0x98, 0x20, 0x50, 0x89, 0x6c, 0x00, 0x00, 0xb5, 0x98, 0xa3, 0x92,
- 0x87, 0x6c, 0x00, 0x00, 0xa5, 0x98, 0x00, 0x44, 0x10, 0xc9, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x0a, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x09,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x08, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x07, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x07,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x07, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x06, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x06,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x05, 0x87, 0xb0, 0x00, 0x00, 0xb6, 0x98, 0x00, 0x44,
- 0x10, 0xc9, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0f, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x0e, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0d,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x0c, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0c,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
- 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b,
- 0x87, 0xb0, 0x00, 0x00, 0xc6, 0x98, 0x00, 0x0b, 0x87, 0xb0, 0x00, 0x00,
- 0xbf, 0x00, 0x2d, 0x43, 0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
- 0x80, 0xe0, 0x01, 0x00, 0xcb, 0x98, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00,
- 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x84, 0xb0, 0x01, 0x00, 0xcf, 0x98, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00,
- 0x9c, 0x00, 0x20, 0x42, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00,
- 0x9c, 0x00, 0x20, 0x42, 0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00,
- 0x0f, 0x00, 0x00, 0xf3, 0x82, 0x88, 0x01, 0x00, 0xd5, 0x98, 0x23, 0x41,
- 0x80, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x89, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x9f, 0x41, 0x24, 0xec, 0x00, 0x00, 0xdf, 0x98, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x42, 0x38, 0xec, 0x00, 0x00,
- 0xdf, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xe1, 0x98, 0xa3, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xe5, 0x98, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0xb4, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f,
- 0x13, 0x94, 0x01, 0x00, 0xe5, 0x98, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0x80, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12,
- 0xe0, 0xb1, 0x01, 0x00, 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xe0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0xee, 0x98, 0x9f, 0x41, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00,
- 0xef, 0x98, 0x00, 0x41, 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x3d, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf1, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xbf, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x08, 0x80, 0x32, 0x01, 0x00,
- 0xf8, 0x98, 0xa2, 0x40, 0x95, 0x6c, 0x00, 0x00, 0xcc, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
- 0xa0, 0x98, 0x2f, 0x40, 0x11, 0xb0, 0x01, 0x00, 0xe3, 0x89, 0x00, 0x41,
- 0x89, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xf8, 0x3e, 0xec, 0x00, 0x00,
- 0x00, 0x00, 0x9f, 0x12, 0xe0, 0xed, 0x00, 0x00, 0xc8, 0x00, 0x20, 0xab,
- 0xe1, 0xb1, 0x01, 0x00, 0xcc, 0x00, 0xa0, 0x1f, 0xe0, 0xb1, 0x01, 0x00,
- 0x01, 0x99, 0xa3, 0x5f, 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe7, 0xc1, 0x01, 0x00, 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x15, 0x99, 0x22, 0xf2, 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43,
- 0x84, 0xf4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00,
- 0xb8, 0x00, 0x2d, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
- 0x86, 0xc0, 0x01, 0x00, 0x09, 0x99, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00,
- 0x0a, 0x99, 0xa2, 0x40, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41,
- 0x87, 0xb0, 0x01, 0x00, 0x0e, 0x99, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x84, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44,
- 0x84, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x62, 0x40, 0x88, 0xc0, 0x01, 0x00, 0x14, 0x99, 0x1f, 0x44,
- 0x80, 0x32, 0x00, 0x00, 0x18, 0x99, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00,
- 0x18, 0x99, 0x62, 0x41, 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41,
- 0x86, 0xe4, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x62, 0x41, 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xbc, 0x00, 0x2e, 0x43, 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x86, 0xc0, 0x01, 0x00, 0x1e, 0x99, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x43, 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43,
- 0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00,
- 0x40, 0x01, 0xe2, 0x40, 0x87, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
- 0x81, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf2, 0x2e, 0xb0, 0x01, 0x00,
- 0x9c, 0x00, 0x2d, 0xf0, 0x86, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0xba, 0x00, 0x2d, 0xf0, 0x98, 0xb0, 0x01, 0x00,
- 0x2b, 0x99, 0xa2, 0x12, 0x98, 0x6c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0xf2,
- 0x98, 0xb0, 0x01, 0x00, 0x2b, 0x99, 0xa0, 0xf2, 0x98, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x17, 0x82, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x41,
- 0xe0, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x2d, 0x12, 0x86, 0xd0, 0x01, 0x00,
- 0x2e, 0x99, 0xa3, 0x41, 0xe0, 0x6d, 0x00, 0x00, 0x2f, 0x99, 0x00, 0xf0,
- 0x84, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x84, 0xb0, 0x01, 0x00,
- 0x80, 0x00, 0x2d, 0x43, 0x84, 0xd0, 0x01, 0x00, 0x32, 0x99, 0x9f, 0x42,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0x34, 0x99, 0xa3, 0x42, 0x14, 0x6c, 0x00, 0x00, 0x35, 0x99, 0x00, 0x0a,
- 0x0c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x0c, 0xb0, 0x01, 0x00,
- 0x37, 0x99, 0xa0, 0x17, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x17,
- 0x0c, 0xb0, 0x01, 0x00, 0x3c, 0x99, 0x22, 0x40, 0x0d, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0xa0, 0x0a, 0x0c, 0xec, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf0,
- 0x82, 0xf4, 0x01, 0x00, 0x3c, 0x99, 0xa0, 0x41, 0x0c, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb0, 0x01, 0x00, 0xd0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x41, 0x87, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
- 0x48, 0x99, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x05, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x04, 0xe6, 0xb1, 0x01, 0x00, 0x52, 0x99, 0x22, 0x49,
- 0x1f, 0x7c, 0x00, 0x00, 0x42, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x1f, 0x80, 0x01, 0x00, 0xaa, 0x97, 0x00, 0x40,
- 0x8d, 0xb0, 0x00, 0x00, 0x58, 0x99, 0x22, 0x40, 0xaf, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x96, 0xb0, 0x01, 0x00, 0x72, 0x98, 0x00, 0x08,
- 0x94, 0x30, 0x01, 0x00, 0x57, 0x99, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0xaa, 0x97, 0x00, 0x46, 0x87, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x87, 0xb0, 0x01, 0x00, 0x58, 0x99, 0x43, 0x48, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x99, 0x28, 0x40,
- 0x87, 0x30, 0x00, 0x00, 0x59, 0x99, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
- 0xaa, 0x97, 0x1b, 0x46, 0x87, 0xb0, 0x00, 0x00, 0x60, 0x99, 0x22, 0x5f,
- 0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00,
- 0x5e, 0x99, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9b, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0xb0, 0x01, 0x00,
- 0xb1, 0x99, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00, 0x07, 0x00, 0x00, 0x49,
- 0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03, 0x06, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xd0,
- 0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
- 0x65, 0x99, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x05,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x48, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xc0, 0x01, 0x00, 0xa2,
- 0x44, 0xc9, 0x01, 0x00, 0x6e, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00, 0xb6, 0x99, 0x00, 0x40,
- 0x49, 0x31, 0x01, 0x00, 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x74, 0x99, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x00, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x78, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x7c, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x64, 0x00, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00,
- 0xba, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x86, 0x99, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x68, 0xb1, 0x01, 0x00, 0x8a, 0x99, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
- 0xc3, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x39, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x33, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x3f, 0xb3, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40,
- 0x29, 0x9b, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40, 0x25, 0x9b, 0x01, 0x00,
- 0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x2b, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5, 0x3c, 0x8b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c,
- 0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x59, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x53, 0xb3, 0x01, 0x00,
- 0xa7, 0x99, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xa7, 0x99, 0xa2, 0x51,
- 0xfd, 0x7f, 0x00, 0x00, 0xa8, 0x99, 0x00, 0x40, 0x1d, 0xb3, 0x00, 0x00,
- 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6,
- 0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6, 0x3a, 0xb3, 0x01, 0x00,
- 0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00, 0xb4, 0x05, 0x00, 0x40,
- 0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0xb3, 0x01, 0x00,
- 0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00, 0x01, 0x01, 0x00, 0x8a,
- 0x15, 0x9b, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x5e, 0x57, 0xb5, 0x01, 0x00, 0x18, 0x00, 0x00, 0x4b,
- 0x20, 0xe4, 0x01, 0x00, 0x06, 0x00, 0x00, 0x4b, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x43, 0x00, 0x4b, 0x96, 0xc8, 0x01, 0x00, 0x18, 0x00, 0x00, 0x10,
- 0x20, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b, 0x20, 0x94, 0x01, 0x00,
- 0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xb7, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0xa9, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0xbb, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0xbf, 0x99, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xbf, 0x99, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
- 0x82, 0xb1, 0x01, 0x00, 0xc5, 0x99, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x90, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0xca, 0x99, 0x85, 0x41,
- 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xce, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12,
- 0x80, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x9c, 0x4b, 0x82, 0x89, 0x01, 0x00,
- 0xd1, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x80, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x9c, 0xa6, 0x82, 0xb1, 0x01, 0x00,
- 0xd4, 0x99, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
- 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x9c, 0xc2, 0x24, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b,
- 0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0x80, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b,
- 0x94, 0x89, 0x01, 0x00, 0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb0, 0x01, 0x00, 0xdf, 0x99, 0x80, 0xa5, 0x80, 0x32, 0x00, 0x00,
- 0xe0, 0x99, 0x00, 0xa5, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x81, 0xc0, 0x01, 0x00, 0xe1, 0x99, 0x80, 0xa5, 0x80, 0x32, 0x00, 0x00,
- 0x80, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xea, 0x99, 0x20, 0x4f,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0xea, 0x99, 0x20, 0x4b, 0x81, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0xea, 0x99, 0x20, 0x47, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x82, 0xdc, 0x01, 0x00, 0x03, 0x90, 0x00, 0x41, 0x20, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x4c,
- 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0xee, 0x99, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x64, 0x00, 0x00, 0xa5,
- 0x80, 0xc8, 0x01, 0x00, 0xf1, 0x99, 0xa2, 0xa5, 0x80, 0x6c, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0xf4, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x90, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0xf7, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x70, 0x00, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0xfa, 0x99, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0xfc, 0x99, 0x1f, 0x91,
- 0x80, 0x32, 0x00, 0x00, 0x40, 0x68, 0x00, 0x90, 0x20, 0xa9, 0x01, 0x00,
- 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x21, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x22, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x23, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x25, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x26, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x27, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xd0, 0x14, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x30, 0x03, 0x00, 0x40, 0x85, 0x30, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x02, 0x01, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
- 0x04, 0x03, 0x00, 0x40, 0x80, 0x98, 0x01, 0x00, 0x06, 0x05, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x08, 0x07, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe0, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
- 0x30, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x39, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd8, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xff, 0x02, 0xa2, 0xf8, 0x80, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x22, 0xf0,
- 0x82, 0x6c, 0x00, 0x00, 0xff, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x1e, 0x9a, 0x00, 0x40,
- 0x10, 0xc9, 0x00, 0x00, 0x24, 0x9a, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
- 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x9a, 0x00, 0x05,
- 0x81, 0xb0, 0x00, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x31, 0x9a, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0x33, 0x9a, 0x00, 0x44,
- 0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
- 0xf0, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x25, 0x9a, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xb1, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xc5, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x5a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
- 0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x22, 0x41,
- 0x81, 0x50, 0x00, 0x00, 0x2d, 0x9a, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0x29, 0x9a, 0x00, 0xc2,
- 0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
- 0x29, 0x9a, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
- 0x81, 0xc8, 0x01, 0x00, 0x6a, 0x84, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88,
- 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
- 0xb6, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xb6, 0x9f, 0x00, 0x88,
- 0x9a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00,
- 0xb6, 0x9f, 0x41, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb9, 0x9f, 0x22, 0x40,
- 0x7b, 0x6f, 0x00, 0x00, 0xb6, 0x9f, 0x19, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
- 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1, 0xc6, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00, 0x08, 0x14, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0xb0, 0x9f, 0x00, 0x4d, 0x9a, 0xcc, 0x01, 0x00,
- 0xc2, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x49, 0xc1, 0x01, 0x00, 0xc0, 0x9f, 0xa2, 0x41, 0x9b, 0x50, 0x00, 0x00,
- 0xc6, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x52, 0x49,
- 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xfd, 0x93, 0x01, 0x00,
- 0xc9, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x51, 0x4a,
- 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0xfd, 0x93, 0x01, 0x00,
- 0xc9, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xd9, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00, 0xd1, 0x9f, 0x00, 0x40,
- 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x10, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe3,
- 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x45, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x48, 0x4f,
- 0x40, 0xb1, 0x01, 0x00, 0xd9, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6a, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x19, 0x9a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x35, 0x9a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x10, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00,
- },
-};
diff --git a/drivers/staging/slicoss/gbrcvucode.h b/drivers/staging/slicoss/gbrcvucode.h
deleted file mode 100644
index 4fa5a4c23e5..00000000000
--- a/drivers/staging/slicoss/gbrcvucode.h
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 1997-2002 Alacritech, Inc. All rights reserved
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-#define GB_RCVUCODE_VERS_STRING "1.2"
-#define GB_RCVUCODE_VERS_DATE "2006/03/27 15:12:15"
-
-static u32 GBRcvUCodeLen = 512;
-
-static u8 GBRcvUCode[2560] =
-{
-0x47, 0x75, 0x01, 0x00, 0x04, 0xa0, 0x13, 0x01, 0x00, 0x1c, 0xb7, 0x5b, 0x09,
-0x30, 0x00, 0xb6, 0x5f, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x18, 0x3b,
-0x78, 0x3a, 0x00, 0x1c, 0xa2, 0x77, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x70,
-0x18, 0xb3, 0x7b, 0xa9, 0xaa, 0x1e, 0xb4, 0x7b, 0x01, 0x0c, 0x1c, 0xb5, 0x7b,
-0x1d, 0x06, 0x1c, 0x00, 0x00, 0x40, 0x64, 0x08, 0x0c, 0x31, 0x56, 0x70, 0x04,
-0x0c, 0x31, 0x56, 0x80, 0x04, 0x0c, 0x31, 0x4a, 0x90, 0x04, 0x0c, 0x31, 0x46,
-0xa0, 0x00, 0x09, 0x25, 0x51, 0xc0, 0x04, 0x0c, 0x31, 0x4e, 0xb0, 0x00, 0xe9,
-0x24, 0x51, 0xc0, 0x04, 0xcc, 0xb3, 0x00, 0x1c, 0x1c, 0xeb, 0x2d, 0x01, 0x00,
-0x1c, 0x06, 0x56, 0x42, 0xd4, 0x08, 0x07, 0x9d, 0x00, 0x00, 0x1c, 0x7b, 0xb7,
-0x02, 0x00, 0x10, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x06, 0x56, 0x5a, 0xc0, 0x04,
-0xa0, 0x30, 0x6c, 0x03, 0x00, 0xac, 0x30, 0x6d, 0x03, 0x00, 0xcd, 0x03, 0x3a,
-0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0x60, 0x8e, 0x41, 0x54, 0x09, 0x29,
-0x25, 0x6d, 0x03, 0x00, 0x80, 0x8e, 0x41, 0x54, 0x09, 0x8c, 0x30, 0x8d, 0x00,
-0x04, 0x47, 0x1c, 0x01, 0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x00, 0x00,
-0x60, 0x00, 0x04, 0x47, 0x1c, 0x61, 0xc0, 0x04, 0x47, 0x1c, 0x6d, 0x03, 0x00,
-0x6c, 0x30, 0x01, 0x00, 0x1c, 0x4d, 0x34, 0x02, 0x00, 0x1c, 0x7b, 0xb7, 0x02,
-0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xc8, 0x83, 0x37, 0x00, 0x1c, 0x80,
-0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x60, 0x00, 0x04, 0xa0, 0x0f, 0x40, 0x54,
-0x09, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x7b, 0xfb, 0xf2, 0x00, 0x1c, 0xcc, 0x33,
-0x0d, 0x00, 0x1c, 0xb4, 0x7b, 0xfd, 0x03, 0x1c, 0x80, 0x0e, 0x40, 0x54, 0x09,
-0xe0, 0xfb, 0x05, 0x00, 0x1c, 0x00, 0x00, 0xa0, 0x03, 0x00, 0xb3, 0x0f, 0x41,
-0x54, 0x09, 0x00, 0x00, 0xe8, 0x70, 0x04, 0x00, 0x00, 0xe8, 0x80, 0x04, 0x00,
-0x00, 0xa0, 0x93, 0x00, 0x61, 0x76, 0xa1, 0xc3, 0x04, 0xc0, 0x8d, 0x41, 0x54,
-0x09, 0xe0, 0x7b, 0x00, 0xc0, 0x1f, 0xa0, 0xfd, 0xc1, 0x01, 0x00, 0xcc, 0x33,
-0x05, 0x00, 0x1c, 0xd4, 0x03, 0x00, 0x3c, 0x1c, 0xd4, 0xd3, 0x1b, 0x00, 0x1c,
-0xc0, 0xd3, 0x52, 0x00, 0x1c, 0x00, 0x00, 0x74, 0x13, 0x04, 0x8e, 0x8e, 0x42,
-0x54, 0x09, 0x5b, 0x80, 0x76, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
-0x00, 0x90, 0x01, 0x00, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54,
-0x09, 0xc0, 0x03, 0xfc, 0x7f, 0x1c, 0xa0, 0x01, 0x9c, 0x01, 0x00, 0x00, 0x00,
-0xa0, 0x01, 0x00, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xc0, 0x03, 0xfc, 0x03, 0x1c,
-0xf5, 0x77, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0xf6, 0x05, 0x1c, 0xa0, 0x0f, 0x41,
-0x54, 0x09, 0xb3, 0x0f, 0x41, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0xa0,
-0x0f, 0x41, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00, 0x1c, 0xb5, 0x02, 0x02, 0x00,
-0x1c, 0x53, 0x0f, 0x42, 0x54, 0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e,
-0x42, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x02, 0x00, 0x1c,
-0xa0, 0x3d, 0xa6, 0x11, 0x04, 0x00, 0x00, 0xa8, 0x11, 0x04, 0xd4, 0xd3, 0x52,
-0x00, 0x1c, 0xb5, 0x3e, 0xae, 0x01, 0x00, 0x20, 0xfb, 0xfd, 0xff, 0x1f, 0x80,
-0x2c, 0x84, 0x03, 0x00, 0xb9, 0x3a, 0x9a, 0x01, 0x00, 0x75, 0x3b, 0x02, 0x00,
-0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xdb, 0x83, 0x16, 0x00, 0x1c, 0xc7, 0x1d,
-0x1d, 0xc1, 0x04, 0xb9, 0x3b, 0x89, 0xc1, 0x04, 0x8b, 0x2c, 0x01, 0x00, 0x1c,
-0x6b, 0x2c, 0x31, 0xc1, 0x04, 0x00, 0x00, 0x74, 0x11, 0x00, 0xcb, 0x2c, 0x75,
-0xc1, 0x04, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x54,
-0xd0, 0x02, 0x00, 0x1c, 0x49, 0x25, 0xad, 0x01, 0x00, 0xab, 0x2c, 0x7d, 0xc1,
-0x04, 0xa7, 0x1d, 0x6d, 0x03, 0x00, 0xcc, 0x33, 0x09, 0x00, 0x1c, 0xeb, 0x2d,
-0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09,
-0xae, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xd4, 0x07, 0xfc,
-0x03, 0x1c, 0x99, 0x3a, 0x02, 0x00, 0x1c, 0xbb, 0x38, 0x02, 0x00, 0x1c, 0x00,
-0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xf8, 0x01, 0x04, 0xdb, 0x3b, 0x7e, 0x00,
-0x1c, 0xc7, 0x1d, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0x0a, 0x06, 0x1c, 0x27, 0x1d,
-0x01, 0x00, 0x1c, 0xb3, 0x0f, 0x41, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09,
-0x53, 0x0f, 0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42,
-0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09, 0xa0,
-0x0f, 0x41, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00, 0x1c, 0x53, 0x0f, 0x42, 0x54,
-0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f,
-0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09,
-0x7a, 0x0e, 0x42, 0x54, 0x09, 0x53, 0x0f, 0x42, 0x54, 0x09, 0x7a, 0x0e, 0x42,
-0x54, 0x09, 0x00, 0x3d, 0x02, 0x00, 0x1c, 0x00, 0x00, 0x54, 0x12, 0x00, 0xcb,
-0x2c, 0x01, 0x00, 0x1c, 0x75, 0x3b, 0x02, 0x00, 0x1c, 0xa7, 0x1c, 0x01, 0x00,
-0x10, 0xa6, 0x7b, 0xf1, 0x05, 0x1c, 0x00, 0x00, 0x88, 0xc2, 0x04, 0xa6, 0x7b,
-0xf1, 0x05, 0x1c, 0x00, 0x00, 0xa0, 0xc2, 0x04, 0xcb, 0x2f, 0x05, 0x00, 0x1c,
-0x60, 0x2c, 0x00, 0x00, 0x1c, 0xc7, 0x1c, 0xe1, 0x02, 0x00, 0x53, 0x0f, 0x42,
-0x54, 0x09, 0xc0, 0x83, 0xf1, 0x32, 0x1c, 0x00, 0x00, 0x5c, 0x02, 0x04, 0x46,
-0x7a, 0xda, 0x05, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0xc0, 0x83, 0xf1, 0x32,
-0x1c, 0x00, 0x00, 0x64, 0x02, 0x04, 0x40, 0xfa, 0x15, 0x00, 0x1c, 0x00, 0x00,
-0xa0, 0x02, 0x04, 0x46, 0x7a, 0xda, 0x05, 0x1c, 0xa0, 0x0f, 0x41, 0x54, 0x09,
-0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xa0, 0x0f, 0x41,
-0x54, 0x09, 0xb3, 0x7b, 0x01, 0xc0, 0x1f, 0x74, 0x0e, 0x40, 0x54, 0x09, 0xc0,
-0x03, 0x9c, 0x00, 0x1c, 0x80, 0x00, 0xf0, 0x02, 0x00, 0x00, 0x00, 0xf0, 0x02,
-0x04, 0x00, 0x00, 0xc4, 0x12, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xd4, 0xd3,
-0x2b, 0x00, 0x1c, 0xd4, 0xd3, 0x52, 0x00, 0x1c, 0x80, 0x76, 0x95, 0x13, 0x04,
-0x00, 0x00, 0xf8, 0x02, 0x00, 0xa6, 0x7b, 0xa9, 0x03, 0x10, 0xc7, 0x9c, 0x00,
-0x00, 0x1c, 0x80, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x78, 0x02, 0x04, 0x00,
-0x00, 0x6c, 0xc3, 0x04, 0xab, 0x2d, 0xf1, 0x12, 0x05, 0x07, 0x1d, 0xcd, 0xc2,
-0x04, 0x8b, 0x2d, 0x01, 0x00, 0x1c, 0x69, 0x25, 0x01, 0x00, 0x1c, 0xa6, 0x7b,
-0xa9, 0x03, 0x10, 0xcb, 0x2f, 0x09, 0x00, 0x1c, 0x60, 0x2c, 0x00, 0x00, 0x1c,
-0x00, 0x00, 0x60, 0x03, 0x00, 0x53, 0x0f, 0x42, 0x54, 0x09, 0x46, 0x7a, 0xda,
-0x05, 0x1c, 0x7a, 0x0e, 0x42, 0x54, 0x09, 0x40, 0xfa, 0x15, 0x00, 0x1c, 0x00,
-0x00, 0x28, 0x03, 0x04, 0x46, 0x7a, 0xda, 0x05, 0x1c, 0xb5, 0x0f, 0x41, 0x54,
-0x09, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0x73, 0xec, 0x42, 0x03, 0x04, 0x60, 0x2c,
-0x00, 0x00, 0x1c, 0x00, 0x00, 0x40, 0x03, 0x00, 0xc7, 0x1c, 0x01, 0x00, 0x1c,
-0x00, 0x00, 0x40, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xc0, 0xd7, 0x22,
-0x00, 0x1c, 0x75, 0x56, 0x96, 0x13, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0xe7,
-0x1c, 0x5d, 0x03, 0x04, 0xe7, 0x9c, 0x00, 0x00, 0x1c, 0xa6, 0x7b, 0xa9, 0x03,
-0x10, 0x80, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x10, 0x03, 0x04, 0x00, 0x00,
-0x6c, 0xc3, 0x04, 0xb9, 0x7b, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xa0, 0xc3, 0x04,
-0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x01, 0x04, 0x1c, 0xc7, 0x9f, 0x80,
-0x03, 0x1c, 0x00, 0x00, 0xa0, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb,
-0x2f, 0x0d, 0x04, 0x1c, 0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00, 0xa0, 0xc3,
-0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x00, 0x1d, 0x00, 0x00,
-0xa0, 0xc3, 0x04, 0x00, 0x00, 0xa0, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c,
-0xc0, 0x1d, 0xf0, 0xd3, 0x08, 0x27, 0x9d, 0xf8, 0x03, 0x00, 0xa0, 0xee, 0x56,
-0xd4, 0x00, 0xfb, 0x75, 0x19, 0x14, 0x04, 0x20, 0x7b, 0x06, 0x00, 0x1c, 0xc0,
-0x1c, 0x2c, 0x04, 0x00, 0x00, 0x00, 0xc4, 0xd3, 0x08, 0x00, 0x00, 0x10, 0xf4,
-0x00, 0xc0, 0xef, 0xf2, 0x00, 0x1c, 0x20, 0x25, 0x6c, 0x14, 0x04, 0x60, 0xb7,
-0xe6, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x15, 0x00, 0xcc, 0xb3, 0xfc, 0x03, 0x1c,
-0xcc, 0x33, 0x05, 0x02, 0x1c, 0x00, 0x00, 0x1c, 0xc5, 0x04, 0x60, 0xb7, 0x1e,
-0x05, 0x04, 0x00, 0x00, 0x1c, 0x15, 0x04, 0x00, 0x00, 0x6c, 0xc4, 0x04, 0xc0,
-0x1d, 0xac, 0xf3, 0x04, 0x00, 0x00, 0x78, 0xc4, 0x04, 0x07, 0x9d, 0x00, 0x00,
-0x1c, 0x1b, 0x74, 0x0d, 0xf4, 0x04, 0xa0, 0x0f, 0x41, 0x54, 0x09, 0xe0, 0x7b,
-0x00, 0xfc, 0x1f, 0x39, 0x7f, 0x02, 0x00, 0x1c, 0x07, 0x1d, 0xb1, 0xc3, 0x04,
-0xa6, 0x7b, 0xc1, 0x03, 0x1c, 0x00, 0x00, 0x78, 0xc4, 0x04, 0xe0, 0x1c, 0x00,
-0x00, 0x1c, 0x00, 0x00, 0xb8, 0x03, 0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb,
-0x2f, 0x01, 0x10, 0x1d, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0x00, 0x00, 0xc0, 0x03,
-0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x18, 0x1d, 0xc7, 0x9f,
-0x00, 0x0b, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xfb, 0x75, 0x01, 0x00, 0x1c,
-0x07, 0x1d, 0x01, 0x00, 0x1c, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01,
-0x02, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xa0, 0x1c, 0x00, 0x00, 0x1c, 0xa0,
-0xee, 0xb6, 0x03, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x09, 0x04,
-0x1c, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xc0, 0xc3, 0x04, 0xcc, 0xb3,
-0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02, 0x1c, 0x00, 0x00, 0x1c, 0xc5, 0x04,
-0x00, 0x00, 0x88, 0x34, 0x05, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x15,
-0x02, 0x1c, 0x47, 0x9d, 0x64, 0xc4, 0x04, 0x00, 0x00, 0x88, 0x44, 0x00, 0x80,
-0x1d, 0x8c, 0x54, 0x04, 0x87, 0x1d, 0x9d, 0x04, 0x00, 0xce, 0x76, 0x01, 0x00,
-0x1c, 0xef, 0x76, 0xad, 0xc4, 0x04, 0xa4, 0x77, 0x9d, 0x24, 0x09, 0xe4, 0x76,
-0x01, 0x00, 0x1c, 0xc4, 0x76, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xa8, 0x54, 0x04,
-0xd7, 0x76, 0x01, 0x50, 0x18, 0xf6, 0x76, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00,
-0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcc, 0x30, 0x51, 0xc5, 0x04, 0xeb,
-0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c, 0xc0, 0x59, 0x01, 0x00,
-0x1c, 0xf5, 0x77, 0x39, 0xc5, 0x04, 0xe0, 0x30, 0xec, 0x04, 0x00, 0x00, 0x4c,
-0xc0, 0x04, 0x00, 0x20, 0x4c, 0x04, 0x05, 0x00, 0x00, 0x00, 0xf8, 0x04, 0x00,
-0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x09, 0x02, 0x1c, 0xeb, 0x2d, 0xc5,
-0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x19, 0x02, 0x1c, 0xeb,
-0x2d, 0xc5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x0d, 0x02,
-0x1c, 0xeb, 0x2d, 0xc5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33,
-0x11, 0x02, 0x1c, 0xeb, 0x2d, 0xc5, 0xc4, 0x04, 0x00, 0x7b, 0x00, 0x80, 0x1c,
-0xae, 0x77, 0x51, 0x05, 0x00, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xd3, 0x8b, 0x00,
-0xfc, 0x1f, 0x60, 0x7a, 0x3c, 0x00, 0x1c, 0x60, 0x4c, 0xd0, 0x04, 0x00, 0xc0,
-0x2f, 0x20, 0x05, 0x1f, 0xe0, 0x30, 0xc0, 0x04, 0x00, 0x80, 0x25, 0xc0, 0x04,
-0x00, 0xb5, 0x5b, 0xc1, 0x04, 0x04, 0x69, 0x26, 0x01, 0x00, 0x1c, 0x6a, 0x2b,
-0x01, 0x00, 0x1c, 0x80, 0x1d, 0x00, 0x00, 0x1c, 0xa9, 0x25, 0x51, 0x05, 0x00,
-0xee, 0x30, 0x00, 0x00, 0x1c, 0xaf, 0x77, 0x11, 0x05, 0x00, 0xb4, 0x5f, 0x01,
-0x40, 0x18, 0x07, 0x9d, 0x54, 0x55, 0x04, 0xb7, 0x76, 0x01, 0x00, 0x1c, 0x96,
-0x76, 0x01, 0x00, 0x1c, 0x47, 0x1d, 0x01, 0x00, 0x1c, 0xa4, 0x33, 0x01, 0x60,
-0x18, 0xa4, 0x2f, 0x01, 0x60, 0x18, 0x64, 0x77, 0x01, 0x60, 0x18, 0x24, 0x77,
-0x01, 0x60, 0x18, 0x44, 0x77, 0x01, 0x00, 0x1c, 0x64, 0x88, 0x03, 0x00, 0x1c,
-0xa4, 0x3f, 0x01, 0x00, 0x1c, 0xa4, 0x3b, 0x01, 0x00, 0x1c, 0x53, 0x77, 0x01,
-0x00, 0x1c, 0xd3, 0xcf, 0x3b, 0x00, 0x1c, 0x53, 0x4f, 0x02, 0x00, 0x1c, 0xd3,
-0xcf, 0x00, 0x00, 0x1f, 0xda, 0xcf, 0x0b, 0x00, 0x1c, 0xd5, 0x57, 0x0f, 0x00,
-0x1c, 0xd3, 0xd3, 0x37, 0x00, 0x1c, 0xd4, 0x53, 0x0f, 0x00, 0x1c, 0xe0, 0x29,
-0x00, 0x00, 0x1c, 0xf5, 0xd5, 0xc0, 0x05, 0x00, 0x00, 0x00, 0xac, 0x55, 0x04,
-0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00,
-0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xf5, 0x55, 0x01, 0x00, 0x1c, 0x00,
-0x00, 0xc4, 0x55, 0x04, 0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53, 0x01, 0x00,
-0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04, 0xcb, 0x2f,
-0x01, 0x18, 0x10, 0xcb, 0x2f, 0x01, 0x10, 0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10,
-0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f, 0x01, 0x20, 0x10, 0xcb, 0x2f, 0x01,
-0x00, 0x10, 0xcb, 0x2f, 0x01, 0x28, 0x10, 0x89, 0x25, 0x6d, 0xc2, 0x04, 0x00,
-0x00, 0x04, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3,
-0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc2, 0x04, 0x00, 0x00,
-0x04, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04,
-0x00, 0x00, 0x6c, 0xc3, 0x04, 0x40, 0x1c, 0x68, 0xc0, 0x04, 0x40, 0x1c, 0x98,
-0xc0, 0x04, 0xa7, 0x77, 0x6d, 0xc3, 0x04, 0x00, 0x00, 0xc0, 0xc0, 0x04, 0x27,
-0x1d, 0xed, 0xc0, 0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x6c, 0xc3,
-0x04, 0x00, 0x00, 0x6c, 0xc3, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00,
-0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6,
-0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00,
-0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c,
-0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04, 0x00, 0x00, 0x3c, 0xc6, 0x04,
-};
diff --git a/drivers/staging/slicoss/oasisdbgdownload.h b/drivers/staging/slicoss/oasisdbgdownload.h
deleted file mode 100644
index 519e00797d4..00000000000
--- a/drivers/staging/slicoss/oasisdbgdownload.h
+++ /dev/null
@@ -1,6850 +0,0 @@
-#define OASIS_UCODE_VERS_STRING "1.2"
-#define OASIS_UCODE_VERS_DATE "2006/03/27 15:11:22"
-#define OASIS_UCODE_HOSTIF_ID 3
-
-static s32 ONumSections = 0x2;
-static u32 OSectionSize[] =
-{
- 0x00004000, 0x00010000,
-};
-
-static u32 OSectionStart[] =
-{
- 0x00000000, 0x00008000,
-};
-
-static u8 OasisUCode[2][65536] =
-{
- {
- 0x15, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
- 0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
- 0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x98, 0x18, 0x31, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x41, 0x98,
- 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x0e, 0x00, 0x40, 0x98,
- 0x80, 0x94, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x19, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x19, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1f, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x12, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x25, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x25, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x14, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xdd, 0x81, 0x01, 0x00, 0x12, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x33, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x00, 0x14, 0xbc,
- 0x80, 0x32, 0x00, 0x00, 0xfe, 0x00, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xfd, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00,
- 0x33, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x89, 0xb0, 0x01, 0x00, 0x32, 0x00, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
- 0x99, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x20, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xe0, 0xb3, 0x01, 0x00, 0x39, 0x00, 0x98, 0xee,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x80, 0xb0, 0x01, 0x00,
- 0x3b, 0x00, 0x80, 0xf3, 0xde, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0xfd, 0x93, 0x01, 0x00, 0x3e, 0x00, 0x83, 0xf3, 0x80, 0x32, 0x00, 0x00,
- 0xf0, 0x00, 0x00, 0xf3, 0x80, 0x88, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40,
- 0x2e, 0xdd, 0x01, 0x00, 0x00, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x43, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0x24, 0xb1, 0x01, 0x00, 0x7c, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00,
- 0x45, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8,
- 0x80, 0x88, 0x01, 0x00, 0x7c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xee, 0x8b, 0x01, 0x00,
- 0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf0,
- 0x80, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x81, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8,
- 0x80, 0x88, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xf0, 0xd6, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xf0,
- 0xf0, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xf8, 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00,
- 0x3c, 0x02, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xd6, 0xb1, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00, 0x1e, 0x00, 0x00, 0xf0,
- 0x82, 0xf4, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xf8, 0x80, 0xd8, 0x01, 0x00,
- 0x64, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x81, 0xd0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40, 0x80, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xd8, 0xb1, 0x01, 0x00, 0x68, 0x00, 0x22, 0xfa, 0x80, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x81, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40,
- 0x80, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xde, 0xb1, 0x01, 0x00,
- 0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
- 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa, 0x80, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xd6, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x18, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00,
- 0x48, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
- 0xd6, 0xe5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x03, 0x00, 0x00, 0xfb,
- 0x7a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0xb1, 0x01, 0x00,
- 0x7c, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x00, 0x00, 0x7c, 0x00, 0x95, 0xe8,
- 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
- 0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0x7c, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x85, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x81, 0xb0, 0x01, 0x00, 0x8e, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
- 0x8c, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0x98, 0x00, 0x1f, 0xfd,
- 0xf9, 0x33, 0x00, 0x00, 0x8b, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
- 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x19, 0xb1, 0x01, 0x00, 0x93, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
- 0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0x97, 0x00, 0xa2, 0xff,
- 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbb, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0xfd, 0x7f, 0x01, 0x00,
- 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xce, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0xfd, 0x7f, 0x01, 0x00,
- 0x00, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x9a, 0x13, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x02, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x01, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x9a, 0x13, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x29, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x67, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xfd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfd, 0x83, 0x01, 0x00,
- 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0x80, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00, 0xe2, 0x00, 0x00, 0x40,
- 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x46, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x40, 0x2b, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x46, 0x88, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x94, 0x8c, 0xb0, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x46, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
- 0x80, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0xf0, 0x01, 0x00,
- 0xc9, 0x00, 0x82, 0x41, 0x89, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfd, 0x83, 0x01, 0x00,
- 0xd4, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44,
- 0x80, 0xb2, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x08, 0x83, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x44,
- 0xfd, 0x93, 0x01, 0x00, 0x00, 0x30, 0x00, 0x08, 0x83, 0x98, 0x01, 0x00,
- 0x80, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
- 0x89, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0x80, 0xb2, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x94, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
- 0x80, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x80, 0x43, 0x89, 0xb0, 0x01, 0x00,
- 0x03, 0x84, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x88, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x96,
- 0x80, 0xb2, 0x00, 0x00, 0xdf, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40,
- 0x25, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xe0, 0x01, 0x00,
- 0xdd, 0x00, 0x00, 0x44, 0x82, 0x14, 0x01, 0x00, 0x00, 0x00, 0x90, 0x94,
- 0x8a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x89, 0xd0, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
- 0xec, 0x00, 0x08, 0x41, 0x80, 0x32, 0x00, 0x00, 0xed, 0x00, 0x00, 0x94,
- 0x24, 0xb1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x94, 0x24, 0xf5, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xf2, 0x00, 0xa0, 0x44,
- 0x89, 0x50, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xef, 0x00, 0x20, 0x44,
- 0x89, 0x50, 0x00, 0x00, 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
- 0x89, 0xd0, 0x00, 0x00, 0xf7, 0x00, 0xa0, 0xfa, 0x8a, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xf5, 0x00, 0xa3, 0x42,
- 0x89, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x45, 0x8a, 0xf4, 0x01, 0x00, 0xfc, 0x00, 0x90, 0x44,
- 0x8a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x45, 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50,
- 0x8b, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0x00, 0x30, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x08, 0x83, 0x14, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x94, 0x2a, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
- 0xf9, 0x9b, 0x01, 0x00, 0xdd, 0x00, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0x40, 0x94, 0x80, 0xb2, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44,
- 0x2b, 0x41, 0x01, 0x00, 0x00, 0x00, 0x41, 0x94, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x2b, 0xc1, 0x01, 0x00, 0x04, 0x01, 0x9f, 0x94, 0x80, 0x32, 0x00, 0x00,
- 0x02, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x01, 0x00, 0x51,
- 0x93, 0xb0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00,
- 0x10, 0x01, 0x00, 0x49, 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x93, 0xb0, 0x01, 0x00, 0x10, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x12, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x1b, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x71, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x72, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x73, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x74, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x76, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x77, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x78, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x79, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x7a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7b, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x7d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7e, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x01, 0xb0, 0x01, 0x00, 0x3b, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x47, 0x01, 0x22, 0x4b,
- 0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
- 0x7e, 0xb1, 0x01, 0x00, 0x48, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x45, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x80, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x18, 0x00, 0x00, 0xaa, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x43, 0x97, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0xaa,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
- 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x07, 0x90, 0x01, 0x00,
- 0xd8, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00, 0x5a, 0x01, 0x22, 0xcc,
- 0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x07, 0x90, 0x01, 0x00,
- 0xd8, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
- 0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe1, 0xb1, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
- 0x62, 0xdd, 0x01, 0x00, 0x63, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbc, 0xb3, 0x01, 0x00,
- 0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
- 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
- 0x80, 0xf4, 0x01, 0x00, 0x73, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
- 0x86, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x10, 0xb1, 0x00, 0x00, 0x87, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x88, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc4, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x82, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x83, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xb8, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x28, 0x00, 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
- 0xd5, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xd6, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x28, 0x00, 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
- 0x72, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x28, 0x00, 0x55, 0x01, 0x51, 0x49,
- 0xfd, 0x93, 0x28, 0x00, 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x2a, 0x00,
- 0x55, 0x01, 0x55, 0x49, 0xfd, 0x83, 0x2a, 0x00, 0x55, 0x01, 0x56, 0x4a,
- 0xfd, 0x83, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x2a, 0x00,
- 0x55, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x82,
- 0x80, 0x30, 0x2a, 0x00, 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x2a, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x40,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0xb3, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0x92, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x49, 0xd1, 0x01, 0x00, 0x9a, 0x01, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
- 0x96, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x50, 0x01, 0x00, 0x41,
- 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0xb3, 0x01, 0x00,
- 0x50, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
- 0xb5, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x42, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0x85, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x42, 0xff,
- 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0xe1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xff,
- 0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4, 0x80, 0xcc, 0x01, 0x00,
- 0xaa, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x85, 0xc0, 0x01, 0x00, 0xa8, 0x01, 0xa2, 0x4c, 0x81, 0x50, 0x00, 0x00,
- 0xb4, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x01, 0x22, 0x41,
- 0xa5, 0x6f, 0x00, 0x00, 0x50, 0x01, 0xa2, 0xe0, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x88, 0x94, 0x01, 0x00, 0x55, 0x01, 0x00, 0x44, 0xe0, 0xb1, 0x00, 0x00,
- 0xb1, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00, 0xaf, 0x01, 0x00, 0x5b,
- 0x89, 0x90, 0x00, 0x00, 0xa8, 0x9f, 0x00, 0xa0, 0x9e, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0xbe, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0xb9, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x43,
- 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x40, 0xf8, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0,
- 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40,
- 0xe1, 0xb1, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xcb, 0x01, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
- 0xd1, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x53, 0x01, 0x00, 0xde,
- 0xa1, 0xb3, 0x00, 0x00, 0xe3, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xe5, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x52, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0xa1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0xdb, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00,
- 0xda, 0x01, 0x84, 0x41, 0x81, 0x40, 0x00, 0x00, 0xde, 0x01, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00,
- 0xd5, 0x01, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
- 0xda, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3,
- 0xa7, 0xcb, 0x01, 0x00, 0xf8, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x53, 0x01, 0x00, 0xde,
- 0xa1, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xde, 0x81, 0x90, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xba,
- 0x80, 0x04, 0x00, 0x00, 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00,
- 0xe8, 0x01, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x52, 0x01, 0x00, 0x40,
- 0xe0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00,
- 0x6b, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x4d,
- 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xe5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf9, 0xb3, 0x01, 0x00, 0xf9, 0x01, 0x22, 0x40,
- 0x8f, 0x6f, 0x00, 0x00, 0x78, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x60, 0x02, 0x00, 0xc7, 0x83, 0x30, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe8, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xed, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xac, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xba,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xf0, 0xb1, 0x01, 0x00,
- 0x0c, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0x90, 0x01, 0x00, 0x0e, 0x02, 0xb9, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00, 0x10, 0x02, 0xba, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x81, 0x90, 0x01, 0x00,
- 0x12, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x81, 0x90, 0x01, 0x00, 0x14, 0x02, 0xbc, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00, 0x16, 0x02, 0xbd, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x81, 0x90, 0x01, 0x00,
- 0x18, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x81, 0x90, 0x01, 0x00, 0x1a, 0x02, 0xbf, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00, 0x1c, 0x02, 0xc8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0x90, 0x01, 0x00,
- 0x1e, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x81, 0x90, 0x01, 0x00, 0x20, 0x02, 0xca, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00, 0x22, 0x02, 0xcb, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x81, 0x90, 0x01, 0x00,
- 0x24, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x81, 0x90, 0x01, 0x00, 0x26, 0x02, 0xcd, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00, 0x28, 0x02, 0xce, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0x90, 0x01, 0x00,
- 0x2a, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x81, 0x90, 0x01, 0x00, 0x2c, 0x02, 0xf0, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x81, 0x90, 0x01, 0x00, 0x2e, 0x02, 0xf1, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x81, 0x90, 0x01, 0x00,
- 0x30, 0x02, 0xf2, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x81, 0x90, 0x01, 0x00, 0x32, 0x02, 0xf3, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x81, 0x90, 0x01, 0x00, 0x34, 0x02, 0xf4, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0x90, 0x01, 0x00,
- 0x36, 0x02, 0xf5, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x81, 0x90, 0x01, 0x00, 0x38, 0x02, 0xf6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x56, 0x81, 0x90, 0x01, 0x00, 0x3a, 0x02, 0xf7, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0x90, 0x01, 0x00,
- 0x3c, 0x02, 0xf8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x81, 0x90, 0x01, 0x00, 0x3e, 0x02, 0xf9, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x59, 0x81, 0x90, 0x01, 0x00, 0x40, 0x02, 0xfa, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0x90, 0x01, 0x00,
- 0x42, 0x02, 0xfb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
- 0x81, 0x90, 0x01, 0x00, 0x44, 0x02, 0xfc, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x81, 0x90, 0x01, 0x00, 0x46, 0x02, 0xfd, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x81, 0x90, 0x01, 0x00,
- 0x48, 0x02, 0xfe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
- 0x81, 0x90, 0x01, 0x00, 0x4a, 0x02, 0xff, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
- 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
- 0xdb, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x66, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x63, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5f, 0x02, 0x49, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x68, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x5f, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
- 0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
- 0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
- 0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
- 0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
- 0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
- 0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
- 0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
- 0x84, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x88, 0x02, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
- 0x8d, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
- 0x9b, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa1, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x42,
- 0xa5, 0x63, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x97, 0x02, 0x22, 0x44,
- 0xa5, 0x53, 0x00, 0x00, 0x94, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
- 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xe8, 0x02, 0x00, 0xde,
- 0xa1, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xbf, 0xb3, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0x63, 0xb1, 0x01, 0x00, 0x9e, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x54,
- 0xa5, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
- 0xac, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x46,
- 0x83, 0x30, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
- 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
- 0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xbd, 0x02, 0x00, 0x40,
- 0x10, 0xc9, 0x00, 0x00, 0xc3, 0x02, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
- 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcb, 0x02, 0x00, 0x05,
- 0x81, 0xb0, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd0, 0x02, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0xd2, 0x02, 0x00, 0x44,
- 0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
- 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0xc4, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
- 0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41,
- 0x81, 0x50, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x00, 0xc2,
- 0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
- 0xc8, 0x02, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd4, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xe2, 0x02, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
- 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
- 0xf1, 0xb1, 0x01, 0x00, 0xe1, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
- 0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
- 0xfa, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf9, 0x02, 0xa2, 0xf2,
- 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x41,
- 0x99, 0xb3, 0x01, 0x00, 0x0a, 0x03, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
- 0x12, 0x03, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x0c, 0x03, 0x22, 0x4c,
- 0x81, 0x6c, 0x00, 0x00, 0x16, 0x03, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
- 0x17, 0x03, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x19, 0x03, 0x22, 0x58,
- 0x81, 0x6c, 0x00, 0x00, 0x1e, 0x03, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
- 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
- 0x09, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xf3, 0x83, 0x01, 0x00, 0x10, 0x03, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x22, 0xca,
- 0x07, 0x14, 0x00, 0x00, 0xdd, 0x9f, 0x00, 0x45, 0xf3, 0x93, 0x00, 0x00,
- 0xdd, 0x9f, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xdd, 0x9f, 0x80, 0xca,
- 0x05, 0x30, 0x00, 0x00, 0xdd, 0x9f, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
- 0xdd, 0x9f, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
- 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
- 0x81, 0x88, 0x01, 0x00, 0xdd, 0x9f, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
- 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x1b, 0x03, 0xa8, 0xb1,
- 0x82, 0x30, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xdd, 0x9f, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x22, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x2d, 0x03, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
- 0x80, 0xce, 0x01, 0x00, 0x2b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x2d, 0x03, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
- 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x32, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x3d, 0x03, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
- 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0x3b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3d, 0x03, 0x55, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xb5, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
- 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00,
- 0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x30, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x90, 0x00, 0xf8,
- 0x80, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf2, 0x88, 0xe4, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0x4d, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0x50, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x40, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0x53, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0x55, 0x03, 0x1f, 0x91,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x80, 0x40, 0x20, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x8f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00,
- 0x5a, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x47,
- 0x8e, 0xc8, 0x01, 0x00, 0x58, 0x03, 0x00, 0x5c, 0x8f, 0x80, 0x00, 0x00,
- 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x58, 0x15, 0x2d, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45, 0x82, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x94, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x8d, 0xc0, 0x01, 0x00, 0x74, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
- 0x65, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x63, 0x03, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43, 0x86, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00, 0x70, 0x03, 0x00, 0x41,
- 0x83, 0xe0, 0x00, 0x00, 0x6e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00, 0xd0, 0x14, 0x2f, 0x46,
- 0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42, 0x60, 0x99, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x07, 0x00, 0x00, 0x45, 0x80, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x85, 0x03, 0xa0, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x83, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0x8e, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0x00, 0x39, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x8b, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x44,
- 0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
- 0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x08, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x39, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00,
- 0x95, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x97, 0x03, 0x22, 0x5a,
- 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x98, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x90, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
- 0x90, 0xb0, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0x8a, 0xb0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0xac, 0x03, 0x22, 0x40,
- 0x82, 0x6c, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x58, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x8d, 0xc0, 0x01, 0x00, 0xb5, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
- 0xa7, 0x03, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0xa5, 0x03, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0xa6, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x9f, 0x00, 0x47,
- 0x80, 0x30, 0x01, 0x00, 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00,
- 0xb0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x50, 0xb3, 0x01, 0x00, 0xbb, 0x03, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00,
- 0xbe, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
- 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x50, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x4e, 0xd3, 0x01, 0x00, 0x6e, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x82, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00,
- 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc7, 0x03, 0x22, 0xa7,
- 0x8f, 0x6c, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xc4, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa0, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xca,
- 0xa7, 0x33, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x03, 0x22, 0x42,
- 0x75, 0x6f, 0x00, 0x00, 0xd8, 0x03, 0x22, 0x41, 0x75, 0x6f, 0x00, 0x00,
- 0xda, 0x03, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xdc, 0x03, 0x1f, 0xca,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0x42, 0x75, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xcd, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x41, 0x75, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40,
- 0x75, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
- 0xc6, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40, 0x75, 0xb3, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x45, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
- 0x45, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x45, 0x01, 0x00, 0x4c,
- 0x93, 0x30, 0x01, 0x00, 0xec, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
- 0xa0, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
- 0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
- 0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43,
- 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xa5, 0xc3, 0x01, 0x00, 0x0b, 0x04, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
- 0x0b, 0x04, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xfa, 0x03, 0xa2, 0x50,
- 0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
- 0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
- 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
- 0x08, 0x04, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x07, 0x04, 0xa2, 0xf2,
- 0x80, 0x30, 0x00, 0x00, 0xfa, 0x03, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
- 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00,
- 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xff, 0xff, 0x00, 0x94, 0xb4, 0x8b, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd9,
- 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0xdd, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x94,
- 0xb4, 0xb3, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0x27, 0xb1, 0x01, 0x00, 0x06, 0xc0, 0x00, 0x40, 0x2d, 0x99, 0x01, 0x00,
- 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x02, 0xc4, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
- 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x40, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x05, 0x82, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
- 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2d, 0x04, 0x80, 0x94,
- 0x80, 0x32, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x28, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x40,
- 0x2d, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x31, 0x04, 0x00, 0x12,
- 0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x4b, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x50, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x56, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x5b, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x60, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x65, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x6b, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x70, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x75, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x7a, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x59, 0x04, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00,
- 0x00, 0x80, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x82, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x84, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x86, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x88, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x8c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8e, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x90, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x92, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x94, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x96, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x98, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9a, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x9e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa0, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa2, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xa4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa6, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa8, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xaa, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xac, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xae, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xb0, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb2, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xb6, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb8, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xba, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xbc, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xbe, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x82, 0x04, 0x85, 0x41,
- 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00,
- 0x87, 0x04, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x90, 0x04, 0x60, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xb1, 0x01, 0x00,
- 0xff, 0xff, 0xf0, 0x4b, 0x82, 0x89, 0x01, 0x00, 0x93, 0x04, 0x60, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x80, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0xf0, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x96, 0x04, 0x60, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0xf0, 0xc2, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b, 0x92, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x80, 0xa6,
- 0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x94, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x88, 0x94, 0x01, 0x00, 0xa6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xad, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xa6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xb0, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x62, 0xb1, 0x01, 0x00, 0xb1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xb8, 0x04, 0x22, 0x4b, 0x89, 0x7c, 0x00, 0x00, 0xb6, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xb6, 0x04, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xc1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xc6, 0x04, 0x22, 0x4b,
- 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xc4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xc1, 0x04, 0xa2, 0x41,
- 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x99, 0xe0, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x4c,
- 0x88, 0x94, 0x00, 0x00, 0xd6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xdd, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xe0, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x62, 0xb1, 0x01, 0x00, 0xe1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xe8, 0x04, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0xe6, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x04, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xf1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xf6, 0x04, 0x22, 0x4a,
- 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xf4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xf1, 0x04, 0xa2, 0x41,
- 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x00, 0x05, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x12, 0x05, 0x1d, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x10, 0x05, 0xa2, 0x40,
- 0x86, 0x04, 0x00, 0x00, 0xde, 0x9f, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50,
- 0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00,
- 0x0c, 0x05, 0x52, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x05, 0x00, 0x40,
- 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
- 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0x30, 0x05, 0x00, 0x05,
- 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x1b, 0x00, 0xde, 0x9f, 0x00, 0x41,
- 0xe1, 0xc1, 0x1a, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x1b, 0x00,
- 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x1a, 0x00, 0x14, 0x05, 0x42, 0x40,
- 0x81, 0x32, 0x1a, 0x00, 0x00, 0x82, 0x00, 0xb3, 0x67, 0xdf, 0x1b, 0x00,
- 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x1b, 0x00, 0x28, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x1b, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
- 0x27, 0x05, 0x0f, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40,
- 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
- 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0x1f, 0x05, 0x99, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00,
- 0x21, 0x05, 0x9b, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x89, 0xd0, 0x01, 0x00, 0x23, 0x05, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
- 0x30, 0x05, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x89, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00,
- 0x30, 0x05, 0x00, 0x58, 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00,
- 0x6f, 0x00, 0x00, 0x43, 0x86, 0x88, 0x01, 0x00, 0xde, 0x9f, 0x26, 0x05,
- 0x47, 0x31, 0x00, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
- 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x07,
- 0x91, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x97, 0xec, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x05, 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x44, 0x05, 0xa2, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0x45, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0x10, 0x04, 0x00, 0x42,
- 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xf5, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
- 0xf7, 0xf5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x8f, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
- 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x91, 0xc0, 0x01, 0x00, 0x50, 0x05, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda,
- 0x8f, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x7a, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x78, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
- 0x7d, 0x05, 0x22, 0x20, 0xb5, 0x6f, 0x00, 0x00, 0x7a, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x1f, 0x00,
- 0x7d, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x1e, 0x00, 0x7a, 0x05, 0x42, 0x40,
- 0x81, 0x32, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x1f, 0x00,
- 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x1e, 0x00, 0x54, 0x16, 0x00, 0x40,
- 0x47, 0x99, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x1f, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x46, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
- 0x48, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x97, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
- 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00,
- 0x90, 0x05, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40,
- 0xa5, 0x9b, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
- 0x85, 0x30, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb8, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
- 0x62, 0xdd, 0x01, 0x00, 0xa7, 0x05, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xaa, 0x05, 0xa2, 0x41,
- 0x83, 0x50, 0x00, 0x00, 0xa9, 0x05, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00,
- 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb0, 0x05, 0xa2, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xb1, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x05, 0xa2, 0xfa,
- 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
- 0xb8, 0x05, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42,
- 0xb3, 0x43, 0x01, 0x00, 0xbb, 0x05, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
- 0xb8, 0x05, 0x42, 0x40, 0x81, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x67, 0x93, 0x21, 0x00, 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x20, 0x00,
- 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0xdb, 0x9f, 0x00, 0x40,
- 0x49, 0x31, 0x21, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x21, 0x00,
- 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0x00, 0x00, 0x6e, 0xfa,
- 0x8e, 0xb0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xb4, 0xb3, 0x01, 0x00, 0xc9, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
- 0xfc, 0x15, 0x20, 0x20, 0xe1, 0xb1, 0x01, 0x00, 0xce, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x24, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x25, 0x00,
- 0xce, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x24, 0x00, 0xcb, 0x05, 0x42, 0x40,
- 0x81, 0x32, 0x24, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x25, 0x00,
- 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x24, 0x00, 0x38, 0x05, 0x00, 0x40,
- 0x81, 0x32, 0x25, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x25, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd3, 0x05, 0x22, 0x50,
- 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x4a, 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x4a, 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xe9, 0x05, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
- 0xea, 0x05, 0x00, 0x50, 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xb5, 0xb3, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
- 0xfc, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
- 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0xff, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
- 0x02, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
- 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0x08, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
- 0x14, 0x06, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
- 0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
- 0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
- 0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
- 0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
- 0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
- 0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf7, 0xb1, 0x01, 0x00, 0x25, 0x06, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
- 0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
- 0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
- 0x2e, 0x06, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
- 0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
- 0x4b, 0x06, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
- 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
- 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
- 0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
- 0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
- 0x55, 0x06, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
- 0x80, 0xce, 0x01, 0x00, 0x5a, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x89, 0xa4, 0x01, 0x00, 0x64, 0x06, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
- 0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x57, 0x06, 0xaa, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
- 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x6b, 0x06, 0xa3, 0x53,
- 0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
- 0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
- 0x70, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
- 0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
- 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
- 0x80, 0xce, 0x01, 0x00, 0x75, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
- 0x37, 0x06, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
- 0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
- 0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
- 0x2b, 0x06, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
- 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0xa2, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x7c, 0x16, 0x20, 0xf6, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x31, 0xb3, 0x01, 0x00, 0x9d, 0x06, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0xfd, 0x93, 0x01, 0x00, 0x9f, 0x06, 0x22, 0x40,
- 0x8f, 0x7c, 0x00, 0x00, 0xa3, 0x06, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
- 0xa1, 0x06, 0x22, 0x42, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0xfd, 0x93, 0x01, 0x00, 0xa3, 0x06, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0xfd, 0x93, 0x01, 0x00, 0xb7, 0x06, 0x22, 0x51,
- 0xfd, 0x7f, 0x00, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb2, 0x06, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00,
- 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x4b, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb6, 0x06, 0x22, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0xba, 0x06, 0x00, 0x54,
- 0xfd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
- 0x1c, 0x00, 0x00, 0xfe, 0x7f, 0xd9, 0x01, 0x00, 0xba, 0x06, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xe7, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc4, 0x06, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xe9, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
- 0x0c, 0xc8, 0x01, 0x00, 0xea, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x0a, 0x07, 0x22, 0x01,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0xd9, 0x06, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
- 0xda, 0x06, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
- 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xec, 0x06, 0x22, 0x40,
- 0x03, 0x6c, 0x00, 0x00, 0xe6, 0x06, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x23, 0x07, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x06, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0xe8, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x23, 0x07, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0xee, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0xfa, 0x06, 0x23, 0x1a,
- 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
- 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
- 0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x02, 0x07, 0x22, 0x1a,
- 0x02, 0x50, 0x00, 0x00, 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
- 0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
- 0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x23, 0x07, 0x00, 0x1a,
- 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0x0f, 0x07, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
- 0x10, 0x07, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x12,
- 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d, 0x16, 0x94, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x17, 0x07, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x40, 0x07, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
- 0x40, 0x07, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x10, 0xc0, 0x01, 0x00, 0x1e, 0x07, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x23, 0x07, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x1f, 0x07, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x3f, 0x07, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x2e, 0x07, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x2c, 0x07, 0x22, 0xf2,
- 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x29, 0x07, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x04, 0xb0, 0x01, 0x00, 0x33, 0x07, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
- 0xd3, 0x06, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
- 0x0f, 0x80, 0x01, 0x00, 0xd3, 0x06, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x3c, 0x07, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0xd3, 0x06, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x0d,
- 0x18, 0xc0, 0x00, 0x00, 0x5f, 0x07, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
- 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
- 0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
- 0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
- 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
- 0x52, 0x07, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x91, 0xc0, 0x01, 0x00, 0x50, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x96, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x18, 0x90, 0xb0, 0x01, 0x00, 0x5c, 0x07, 0xa0, 0xfc,
- 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
- 0x5a, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x80, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x2d, 0x00,
- 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x48, 0xc1, 0x2d, 0x00, 0x64, 0x07, 0x43, 0x30, 0x3d, 0x07, 0x2c, 0x00,
- 0x00, 0x00, 0x00, 0x9e, 0x85, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x1b, 0x41,
- 0x3d, 0xc3, 0x2d, 0x00, 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x2d, 0x00,
- 0x00, 0x00, 0x00, 0x1e, 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d,
- 0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x80, 0xc0, 0x01, 0x00, 0x6e, 0x07, 0xa0, 0x41,
- 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30,
- 0x81, 0x84, 0x01, 0x00, 0x72, 0x07, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
- 0x93, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x19, 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
- 0x16, 0xc0, 0x01, 0x00, 0x78, 0x07, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e,
- 0x32, 0xc0, 0x01, 0x00, 0x7d, 0x07, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00,
- 0x7c, 0x07, 0xa0, 0x1c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e,
- 0x98, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00,
- 0x0c, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x8b, 0x07, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x89, 0x07, 0x22, 0xf2,
- 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x86, 0x07, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0xe1, 0x91, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x1a, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
- 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
- 0x91, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x07, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x9b, 0x07, 0x22, 0xf2,
- 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x98, 0x07, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xeb, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xa1, 0x07, 0x90, 0xf2,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
- 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xac, 0x07, 0x22, 0xf2, 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xa9, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
- 0xc9, 0x07, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00, 0xb4, 0x07, 0xa2, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00,
- 0xb3, 0x07, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
- 0x1c, 0xcc, 0x01, 0x00, 0xe4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x3f, 0xc3, 0x01, 0x00, 0xe6, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb7, 0x07, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1e, 0x3e, 0xc0, 0x01, 0x00, 0xc9, 0x07, 0x22, 0x40,
- 0x15, 0x6c, 0x00, 0x00, 0xba, 0x07, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x3c, 0xb0, 0x01, 0x00, 0xe5, 0x9f, 0x00, 0x1e,
- 0x24, 0x30, 0x01, 0x00, 0xbf, 0x07, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a,
- 0x10, 0xc0, 0x01, 0x00, 0x23, 0x07, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00,
- 0xe4, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe5, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xbc, 0x07, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00,
- 0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0xe8, 0x9f, 0x00, 0x1f,
- 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
- 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00,
- 0xe6, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x07, 0xa2, 0x41,
- 0x87, 0x7c, 0x00, 0x00, 0xcf, 0x07, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1f, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0xe8, 0x9f, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
- 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xf7, 0x07, 0x00, 0xbc, 0x80, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00,
- },
- {
- 0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
- 0x80, 0x32, 0x00, 0x00, 0xe4, 0x87, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
- 0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
- 0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
- 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xe4, 0x87, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
- 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
- 0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
- 0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
- 0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
- 0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
- 0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xc6, 0x82, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xc6, 0x82, 0x05, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0xde, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
- 0x9b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
- 0x48, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44,
- 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x24, 0xb1, 0x01, 0x00, 0x00, 0x0c, 0x00, 0xee,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x97, 0xf0, 0x01, 0x00,
- 0x44, 0x80, 0xa2, 0x43, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xfd, 0x93, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00,
- 0xd0, 0x14, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x06, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x05, 0x10, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x02, 0x09, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x60, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x88, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa0, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb9, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb1, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x91, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
- 0x99, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x3c, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x90, 0x06, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x2f, 0x81, 0x01, 0x00,
- 0xa2, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x9e, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xc6, 0x82, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x00, 0x00,
- 0x6c, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0xb4,
- 0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x18, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x55, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7d, 0x80, 0x22, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x7a, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x80, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x80, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x40, 0x05, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00, 0xc1, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x96, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x96, 0x80, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0x93, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x69, 0x93, 0x01, 0x00, 0x43, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
- 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xd0, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd5, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x01, 0x00, 0x41,
- 0x81, 0xc0, 0x00, 0x00, 0x55, 0x01, 0x51, 0x49, 0xfd, 0x93, 0x00, 0x00,
- 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x00, 0x00, 0x55, 0x01, 0x55, 0x49,
- 0xfd, 0x83, 0x00, 0x00, 0x55, 0x01, 0x56, 0x4a, 0xfd, 0x83, 0x00, 0x00,
- 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x00, 0x00, 0x55, 0x01, 0x45, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00,
- 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0xb4, 0x80, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40,
- 0x91, 0x6f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x46, 0xb1, 0x01, 0x00, 0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00,
- 0xc1, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00,
- 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0xc9, 0x80, 0xa2, 0x42,
- 0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04,
- 0x80, 0x94, 0x00, 0x00, 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03,
- 0x02, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xcb, 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc,
- 0xf3, 0x83, 0x01, 0x00, 0xd3, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xcb, 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb,
- 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa1, 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
- 0xda, 0x80, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf9, 0x02, 0x00, 0x20,
- 0x42, 0x31, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0xcb, 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41,
- 0x8b, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xe0, 0x80, 0xa8, 0xb1, 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xe2, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00,
- 0xe8, 0x80, 0x14, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6,
- 0x83, 0xf4, 0x01, 0x00, 0x22, 0x83, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00,
- 0xc4, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6,
- 0x81, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00,
- 0xc4, 0x80, 0x1f, 0x5c, 0x97, 0x53, 0x00, 0x00, 0x6d, 0x82, 0x1e, 0xc6,
- 0x81, 0x32, 0x00, 0x00, 0xf2, 0x80, 0x22, 0x48, 0xfd, 0x7f, 0x00, 0x00,
- 0xf2, 0x80, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00, 0xf2, 0x80, 0x22, 0x48,
- 0x81, 0x6c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x84, 0xcc, 0x01, 0x00,
- 0xf2, 0x80, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0xc6, 0x8f, 0x06, 0x00, 0x00,
- 0xc4, 0x80, 0x1e, 0xc6, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x43,
- 0x81, 0xf0, 0x01, 0x00, 0xf6, 0x80, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
- 0x44, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7e, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x39, 0x82, 0x00, 0xca, 0x63, 0xb3, 0x00, 0x00,
- 0x75, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x81, 0x00, 0x4d,
- 0x83, 0xb0, 0x00, 0x00, 0x60, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00,
- 0x4c, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0x55, 0x81, 0x00, 0x4c,
- 0x83, 0xb0, 0x00, 0x00, 0x2e, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
- 0xf8, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x86, 0x81, 0x00, 0x40,
- 0xc1, 0xb1, 0x00, 0x00, 0xf4, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x4c, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0x9b, 0xb3, 0x00, 0x00,
- 0x90, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x94, 0x81, 0x00, 0x40,
- 0xc1, 0xb1, 0x00, 0x00, 0x9b, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
- 0x9c, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x9d, 0x81, 0x00, 0x40,
- 0xc1, 0xb1, 0x00, 0x00, 0x9e, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
- 0x9f, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x9f, 0x81, 0x00, 0x41,
- 0x81, 0xb0, 0x00, 0x00, 0x2d, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xae, 0x82, 0x00, 0xbb, 0xab, 0xb3, 0x00, 0x00, 0x3a, 0x82, 0x00, 0xca,
- 0xcf, 0xb3, 0x00, 0x00, 0xc8, 0x03, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
- 0xe8, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc4, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xe0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca,
- 0x77, 0xb3, 0x00, 0x00, 0x56, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00,
- 0x5e, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00, 0x4c, 0x81, 0x00, 0xbb,
- 0x85, 0xb0, 0x00, 0x00, 0x56, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00,
- 0x4c, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x2e, 0x81, 0x00, 0xbb,
- 0x85, 0xb0, 0x00, 0x00, 0x20, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x22, 0x83, 0x00, 0xca, 0x4d, 0xb3, 0x00, 0x00, 0x70, 0x05, 0x00, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
- 0x26, 0x81, 0x22, 0x42, 0x8f, 0x6f, 0x00, 0x00, 0x28, 0x81, 0x22, 0x41,
- 0x8f, 0x6f, 0x00, 0x00, 0x2a, 0x81, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00,
- 0x2c, 0x81, 0x1f, 0xca, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xc9, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x42, 0x8f, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xcd, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x41,
- 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00,
- 0x22, 0x83, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6,
- 0xc6, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40,
- 0x8f, 0xb3, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0x10, 0x00, 0x2f, 0x9c, 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40,
- 0x39, 0x33, 0x01, 0x00, 0x18, 0x00, 0x2f, 0x9b, 0x89, 0xb0, 0x01, 0x00,
- 0x46, 0x81, 0x00, 0x40, 0x37, 0x33, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x9a,
- 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40, 0x35, 0x33, 0x01, 0x00,
- 0x08, 0x00, 0x2f, 0x99, 0x89, 0xb0, 0x01, 0x00, 0x46, 0x81, 0x00, 0x40,
- 0x33, 0x33, 0x01, 0x00, 0x00, 0x80, 0x00, 0xae, 0x47, 0xc9, 0x01, 0x00,
- 0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40,
- 0xe1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0xae, 0x63, 0xdd, 0x01, 0x00, 0x41, 0x81, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x3e, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x41, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x69, 0x93, 0x01, 0x00, 0x22, 0x83, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00,
- 0x44, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x43, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0xa4, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4b, 0x81, 0xa2, 0x40,
- 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0xe1, 0xd1, 0x01, 0x00, 0x4c, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00, 0x52, 0x81, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x4d, 0x81, 0x22, 0x5c, 0x77, 0x7d, 0x00, 0x00,
- 0xc4, 0x80, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4d, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
- 0x52, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x22, 0x83, 0x17, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x57, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
- 0x57, 0x81, 0x00, 0xbb, 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x60, 0xb1, 0x01, 0x00, 0xc4, 0x80, 0xa2, 0x41, 0x76, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x59, 0x81, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
- 0x22, 0x83, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x5b, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x61, 0x81, 0x00, 0xbb, 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40,
- 0x87, 0xb0, 0x01, 0x00, 0x65, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00,
- 0xc4, 0x80, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0xc4, 0x80, 0x22, 0x40,
- 0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x60, 0x40, 0x95, 0x83, 0x00, 0x00,
- 0x02, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0xc4, 0x80, 0x22, 0x40,
- 0x85, 0x6c, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x40, 0x85, 0x7c, 0x00, 0x00,
- 0xc4, 0x80, 0xa2, 0x4e, 0x77, 0x7d, 0x00, 0x00, 0x69, 0x81, 0x36, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x62, 0xb1, 0x01, 0x00,
- 0x6a, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x62, 0xb1, 0x01, 0x00, 0x6c, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0x6e, 0x81, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x16, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x74, 0x81, 0x22, 0x41, 0x43, 0x51, 0x00, 0x00, 0x00, 0x08, 0x00, 0xca,
- 0x95, 0xcb, 0x01, 0x00, 0x68, 0x81, 0x00, 0x41, 0x85, 0xc0, 0x00, 0x00,
- 0x22, 0x83, 0x00, 0x40, 0xe1, 0xb1, 0x00, 0x00, 0x77, 0x81, 0xa2, 0x42,
- 0x67, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00,
- 0x77, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x65, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0xca, 0x69, 0x97, 0x01, 0x00, 0x22, 0x83, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x7c, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x22, 0x83, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0xc4, 0x80, 0x20, 0x43,
- 0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00,
- 0x22, 0x83, 0x22, 0x40, 0x65, 0x6f, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x48,
- 0xdb, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
- 0x85, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x35, 0x80, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x95, 0x93, 0x01, 0x00, 0x8c, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
- 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xc3, 0xb1, 0x01, 0x00, 0x8f, 0x81, 0x22, 0x5b,
- 0x95, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00,
- 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca,
- 0x95, 0x9b, 0x01, 0x00, 0x0d, 0x01, 0x00, 0xca, 0xc5, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca,
- 0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xc7, 0xb1, 0x01, 0x00, 0x22, 0x83, 0x22, 0x5f, 0x95, 0x7f, 0x00, 0x00,
- 0x0d, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x95, 0x83, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca, 0xc7, 0xb1, 0x00, 0x00,
- 0x22, 0x83, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca,
- 0xcb, 0xb1, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0xcd, 0xb1, 0x00, 0x00,
- 0x22, 0x83, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x42,
- 0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40, 0x48, 0xc9, 0x01, 0x00,
- 0x22, 0x83, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0xa4, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0xa6, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00, 0xa8, 0x81, 0x9f, 0x85,
- 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x83, 0x84, 0x01, 0x00,
- 0xdd, 0x81, 0x22, 0x30, 0x83, 0x6c, 0x00, 0x00, 0xa7, 0x81, 0xa2, 0x4f,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
- 0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
- 0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
- 0xbd, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xba, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
- 0xcf, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
- 0xc2, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x21, 0xb3, 0x01, 0x00, 0xcf, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
- 0x86, 0x98, 0x01, 0x00, 0xcf, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x18, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x41, 0x82, 0x88, 0x01, 0x00, 0x00, 0x77, 0x00, 0x41,
- 0x82, 0x8c, 0x01, 0x00, 0x01, 0x02, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x18, 0x00, 0x00, 0x41,
- 0x82, 0xdc, 0x01, 0x00, 0xcd, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0xd0, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0xd8, 0x81, 0x22, 0x43,
- 0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xd5, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
- 0xf3, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
- 0xda, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0xf3, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x21, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x83, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
- 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
- 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x83, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
- 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x11, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
- 0xec, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0xef, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x40, 0x13, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x41, 0x2e, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00, 0xf6, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40, 0x08, 0xb1, 0x00, 0x00,
- 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00, 0xf9, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
- 0x08, 0x82, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x17, 0x82, 0x22, 0x44,
- 0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x4a,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
- 0x03, 0x82, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x87, 0x90, 0x01, 0x00, 0x05, 0x82, 0x22, 0x4f, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x07, 0x82, 0x22, 0x4e,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
- 0x1f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x1c, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x12, 0x82, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x87, 0x90, 0x01, 0x00, 0x14, 0x82, 0x22, 0x44, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x16, 0x82, 0x22, 0x43,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
- 0x1f, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x1f, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x28, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x23, 0x82, 0x22, 0x4b, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xb8, 0x80, 0x00, 0xca,
- 0xa7, 0x33, 0x01, 0x00, 0x41, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x29, 0x82, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00,
- 0x2b, 0x82, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x30, 0x82, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00,
- 0x30, 0x82, 0xa2, 0x49, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xfd, 0x93, 0x01, 0x00, 0x33, 0x82, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00,
- 0x33, 0x82, 0xa2, 0x4a, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xfd, 0x93, 0x01, 0x00, 0x35, 0x82, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00,
- 0x40, 0x00, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
- 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00,
- 0x37, 0x82, 0x42, 0x40, 0xf1, 0x33, 0x00, 0x00, 0x43, 0x81, 0x00, 0x40,
- 0x68, 0x97, 0x00, 0x00, 0x22, 0x83, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00,
- 0x22, 0x83, 0x00, 0xbb, 0xb1, 0xb3, 0x00, 0x00, 0x22, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x18, 0xb1, 0x01, 0x00, 0x40, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x4a, 0x82, 0xa2, 0x54,
- 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x51, 0x82, 0xa2, 0x06,
- 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x80, 0x16, 0x2e, 0x06,
- 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0x57, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
- 0x5a, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
- 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0x60, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
- 0x6c, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0xc4, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x42, 0x99, 0xb3, 0x01, 0x00,
- 0x78, 0x82, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x80, 0x82, 0x22, 0x48,
- 0x81, 0x6c, 0x00, 0x00, 0x7a, 0x82, 0x22, 0x4c, 0x81, 0x6c, 0x00, 0x00,
- 0x85, 0x82, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00, 0x86, 0x82, 0x22, 0x54,
- 0x81, 0x6c, 0x00, 0x00, 0x88, 0x82, 0x22, 0x58, 0x81, 0x6c, 0x00, 0x00,
- 0x8d, 0x82, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x09, 0xb0, 0x01, 0x00,
- 0x22, 0x83, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf3, 0x83, 0x01, 0x00,
- 0x7e, 0x82, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x05, 0xb0, 0x01, 0x00, 0x22, 0x83, 0x22, 0xca, 0x07, 0x14, 0x00, 0x00,
- 0x22, 0x83, 0x00, 0x46, 0xf3, 0x93, 0x00, 0x00, 0x22, 0x83, 0x20, 0x43,
- 0x95, 0x6f, 0x00, 0x00, 0x22, 0x83, 0x80, 0xca, 0x05, 0x30, 0x00, 0x00,
- 0x22, 0x83, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00, 0xc4, 0x80, 0xa2, 0x48,
- 0xdb, 0x7d, 0x00, 0x00, 0x22, 0x83, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00,
- 0x57, 0x01, 0x00, 0xbc, 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
- 0xb1, 0xb3, 0x01, 0x00, 0x22, 0x83, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0xca, 0x81, 0x88, 0x01, 0x00, 0x22, 0x83, 0xa2, 0x40,
- 0x74, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00,
- 0x8a, 0x82, 0xa8, 0xb1, 0x82, 0x30, 0x00, 0x00, 0x89, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x22, 0x83, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x90, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x9b, 0x82, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a,
- 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0x99, 0x82, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x82, 0x56, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
- 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00,
- 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xa0, 0x82, 0xa2, 0x41,
- 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xab, 0x82, 0x91, 0x81,
- 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00,
- 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0xa9, 0x82, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xab, 0x82, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41,
- 0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00, 0x57, 0x01, 0x00, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xb2, 0x82, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0xac, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xb6, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40,
- 0xa3, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x60, 0x15, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
- 0x40, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x40, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
- 0x81, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
- 0xbc, 0x82, 0xa0, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xbc, 0x82, 0x00, 0x50,
- 0x85, 0xc0, 0x00, 0x00, 0x01, 0x83, 0xa2, 0x41, 0x01, 0x7d, 0x00, 0x00,
- 0xcf, 0x82, 0x22, 0x58, 0x73, 0x7d, 0x00, 0x00, 0x78, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xc7, 0x82, 0xa8, 0xb1, 0x9c, 0x30, 0x00, 0x00,
- 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0xc0, 0x00, 0xa6, 0x1e, 0xa4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e,
- 0x10, 0xc9, 0x00, 0x00, 0xcf, 0x82, 0x33, 0xc4, 0x81, 0x30, 0x00, 0x00,
- 0xd2, 0x82, 0xa1, 0xad, 0x9d, 0x20, 0x00, 0x00, 0xc6, 0x82, 0x13, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4e, 0x5a, 0x83, 0x01, 0x00,
- 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x40, 0x05, 0x6c, 0x00, 0x00, 0xdd, 0x82, 0x22, 0xab,
- 0x80, 0x04, 0x00, 0x00, 0xdb, 0x82, 0xa2, 0x40, 0x01, 0x7d, 0x00, 0x00,
- 0xdd, 0x82, 0x22, 0x5f, 0x57, 0x7d, 0x00, 0x00, 0x0f, 0x88, 0x00, 0x5f,
- 0x1f, 0xb4, 0x00, 0x00, 0xdd, 0x82, 0x22, 0x5e, 0x57, 0x7d, 0x00, 0x00,
- 0x7d, 0x88, 0x00, 0x5f, 0x1f, 0xb4, 0x00, 0x00, 0xe3, 0x82, 0x22, 0x54,
- 0x73, 0x7d, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xdd, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x1f, 0xb4, 0x01, 0x00, 0xf4, 0x84, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00,
- 0x92, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe5, 0x82, 0xa2, 0x5f,
- 0x59, 0x27, 0x00, 0x00, 0xe7, 0x82, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00,
- 0xee, 0x82, 0xa2, 0x5e, 0x73, 0x7d, 0x00, 0x00, 0xfa, 0x82, 0x22, 0x5c,
- 0x73, 0x7d, 0x00, 0x00, 0xfb, 0x82, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xe8, 0x82, 0xa8, 0xb1,
- 0x36, 0x30, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xea, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
- 0x02, 0x88, 0x01, 0x00, 0x34, 0x85, 0x17, 0x5f, 0x1f, 0xb4, 0x00, 0x00,
- 0xfb, 0x82, 0x34, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xef, 0x82, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
- 0xf7, 0x82, 0x52, 0x21, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41,
- 0x2f, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x1f, 0xb4, 0x01, 0x00,
- 0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x01, 0xf0, 0x01, 0x00, 0x4f, 0x83, 0x00, 0x34, 0x13, 0x84, 0x00, 0x00,
- 0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x1f, 0xb4, 0x01, 0x00, 0xc2, 0x83, 0x00, 0x43, 0x01, 0xf0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xfb, 0x82, 0x33, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4e, 0x5a, 0x7f, 0x00, 0x00,
- 0x07, 0x00, 0x00, 0x4e, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00,
- 0xc6, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0xe4, 0x87, 0xa2, 0x48,
- 0xfd, 0x7f, 0x00, 0x00, 0x05, 0x83, 0x02, 0xe6, 0x81, 0x32, 0x00, 0x00,
- 0x06, 0x83, 0x83, 0xe5, 0x81, 0x32, 0x00, 0x00, 0x8e, 0x82, 0x00, 0x42,
- 0x97, 0xb3, 0x00, 0x00, 0x9e, 0x82, 0x00, 0x42, 0x97, 0xb3, 0x00, 0x00,
- 0x09, 0x83, 0x22, 0x46, 0xf3, 0x7f, 0x00, 0x00, 0x0c, 0x83, 0xa2, 0x41,
- 0xf3, 0x7f, 0x00, 0x00, 0xc6, 0x80, 0x00, 0x42, 0x97, 0x33, 0x01, 0x00,
- 0x0c, 0x83, 0x22, 0x44, 0xf3, 0x7f, 0x00, 0x00, 0x0c, 0x83, 0xa2, 0x41,
- 0xf3, 0x7f, 0x00, 0x00, 0xc6, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0xac, 0x80, 0x32, 0x00, 0x00, 0x11, 0x83, 0x22, 0x5a,
- 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x0e, 0x83, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x01, 0x00, 0x00, 0xcf,
- 0x11, 0xc9, 0x00, 0x00, 0x17, 0x83, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00,
- 0x17, 0x83, 0x22, 0x44, 0x93, 0x7f, 0x00, 0x00, 0x13, 0x83, 0x42, 0xa5,
- 0x80, 0x30, 0x00, 0x00, 0x16, 0x83, 0xa2, 0x40, 0x93, 0x7f, 0x00, 0x00,
- 0x38, 0x83, 0x1a, 0x40, 0x93, 0x93, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xdf, 0x80, 0xa2, 0x40, 0x73, 0x7d, 0x00, 0x00,
- 0xdf, 0x87, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00, 0xd6, 0x87, 0x22, 0x40,
- 0x65, 0x7d, 0x00, 0x00, 0x00, 0x05, 0xa2, 0x5b, 0x73, 0x7d, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x49, 0x33, 0x7d, 0x00, 0x00, 0x21, 0x83, 0x22, 0x48,
- 0x33, 0x7d, 0x00, 0x00, 0xff, 0x01, 0x00, 0x99, 0x80, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x98, 0x2f, 0x40,
- 0x33, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe0, 0xc1, 0x01, 0x00,
- 0x01, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x82, 0x00, 0x40,
- 0x8b, 0xb3, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
- 0x1f, 0x90, 0x01, 0x00, 0xc6, 0x82, 0x00, 0x5f, 0x1f, 0x80, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x62, 0xb1, 0x01, 0x00,
- 0xc6, 0x82, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x2c, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
- 0x1f, 0x7c, 0x00, 0x00, 0x32, 0x83, 0x33, 0x40, 0x1f, 0x30, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x4e, 0x5a, 0x7f, 0x00, 0x00, 0x07, 0x00, 0x00, 0x4e,
- 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00, 0xc6, 0x82, 0x13, 0x4e,
- 0x5a, 0x93, 0x00, 0x00, 0x3a, 0x83, 0xa0, 0xce, 0x81, 0x50, 0x00, 0x00,
- 0x4d, 0x83, 0xa0, 0xcd, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
- 0x9c, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x81, 0xb0, 0x01, 0x00,
- 0x4d, 0x83, 0x22, 0xb5, 0x81, 0x14, 0x00, 0x00, 0x80, 0x15, 0x2f, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x3e, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0xb4, 0x65, 0x97, 0x01, 0x00, 0xd0, 0x15, 0x2e, 0x40,
- 0x69, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x83, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x1a, 0x00, 0x00, 0xa2,
- 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xb1, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5,
- 0xf1, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x80, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x48, 0x83, 0xa8, 0xa1,
- 0xe0, 0x31, 0x00, 0x00, 0x17, 0x83, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00,
- 0x17, 0x83, 0xa2, 0x41, 0x67, 0x6f, 0x00, 0x00, 0x17, 0x83, 0x00, 0x6f,
- 0xdb, 0x91, 0x00, 0x00, 0x4d, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x17, 0x83, 0x1a, 0x40, 0x93, 0x83, 0x00, 0x00, 0x00, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x01, 0x6c, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09, 0x46, 0xc9, 0x01, 0x00,
- 0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x5c, 0x83, 0xa6, 0x42,
- 0x13, 0x60, 0x00, 0x00, 0x95, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
- 0x57, 0x83, 0x61, 0x40, 0x81, 0x32, 0x00, 0x00, 0x75, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x58, 0x83, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
- 0xa3, 0x96, 0x71, 0x10, 0x94, 0x30, 0x01, 0x00, 0x5d, 0x83, 0x00, 0x58,
- 0x1f, 0x90, 0x00, 0x00, 0x87, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00,
- 0x80, 0x04, 0x00, 0x17, 0x96, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x4a, 0xc1, 0x00, 0x17, 0x96, 0xd8, 0x01, 0x00,
- 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xee, 0x07, 0x00, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x68, 0x83, 0x23, 0x4b, 0xe4, 0x6d, 0x00, 0x00,
- 0x68, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1f, 0x90, 0x01, 0x00, 0x22, 0x00, 0x2f, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x6b, 0x83, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x6d, 0x83, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x47, 0xc1, 0x01, 0x00, 0x72, 0x83, 0x22, 0x55,
- 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x43, 0xd1, 0x01, 0x00,
- 0x0f, 0x00, 0x00, 0xfa, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x97, 0xe0, 0x01, 0x00, 0x73, 0x83, 0x00, 0x4b, 0x44, 0xc1, 0x00, 0x00,
- 0x12, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
- 0x02, 0xcc, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x28, 0xf0,
- 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x1a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa2, 0x2a, 0xb0, 0x01, 0x00, 0xc0, 0x28, 0x3c, 0x46,
- 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x44, 0x95, 0xb0, 0x01, 0x00,
- 0x7f, 0x83, 0xa2, 0xf8, 0x0e, 0x30, 0x00, 0x00, 0x8f, 0x83, 0x22, 0x41,
- 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x50, 0x49, 0xc1, 0x01, 0x00,
- 0x7b, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7c, 0x83, 0xa2, 0xf8,
- 0x16, 0x6c, 0x00, 0x00, 0x7c, 0x83, 0xa2, 0xf8, 0x10, 0x6c, 0x00, 0x00,
- 0x7c, 0x83, 0xa2, 0xf0, 0x1a, 0x6c, 0x00, 0x00, 0x8d, 0x83, 0x22, 0x58,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
- 0x84, 0x83, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x88, 0x83, 0xa2, 0xf3,
- 0x74, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xe6, 0x95, 0x01, 0x00,
- 0x8d, 0x83, 0x75, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x96, 0xb0, 0x01, 0x00, 0x3f, 0x00, 0x75, 0xf3, 0x0c, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x8b, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x8d, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00, 0x95, 0x83, 0x77, 0x41,
- 0x2d, 0xc3, 0x00, 0x00, 0x93, 0x83, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x62, 0xb1, 0x01, 0x00, 0x91, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x93, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd3, 0x83, 0x77, 0x41,
- 0x2d, 0xc3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
- 0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0xa6, 0x83, 0x22, 0x41,
- 0x81, 0x6c, 0x00, 0x00, 0x9b, 0x83, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa5, 0x83, 0x22, 0x5f,
- 0x0f, 0x7c, 0x00, 0x00, 0x48, 0x96, 0x00, 0x5f, 0x01, 0x10, 0x01, 0x00,
- 0xa1, 0x83, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
- 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00,
- 0x01, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
- 0x8a, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0xb5, 0x83, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb5, 0x83, 0x22, 0x20,
- 0x85, 0x6c, 0x00, 0x00, 0xb0, 0x83, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x4b, 0xe1, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xb9, 0x83, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00, 0x69, 0x89, 0x00, 0x45,
- 0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
- 0xbf, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0x34, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x55, 0x97, 0x00, 0x4b, 0x95, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x4b,
- 0x8f, 0xb0, 0x00, 0x00, 0x57, 0x96, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00,
- 0xa9, 0x93, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
- 0x00, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
- 0x8a, 0x30, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x01, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x50,
- 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xce, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
- 0x62, 0xc9, 0x01, 0x00, 0xd0, 0x83, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x2e, 0x47,
- 0x97, 0x90, 0x01, 0x00, 0xe6, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
- 0xe4, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xe4, 0x83, 0x23, 0xa2,
- 0x02, 0x6c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x00,
- 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00, 0x03, 0x84, 0x00, 0x5c,
- 0x17, 0x90, 0x00, 0x00, 0xf8, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0xf1, 0x83, 0x22, 0x5f,
- 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
- 0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
- 0xed, 0x83, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0xee, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x72, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6, 0x80, 0x88, 0x01, 0x00,
- 0xf5, 0x83, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00, 0xf8, 0x83, 0x00, 0xf2,
- 0x3a, 0xb0, 0x00, 0x00, 0xf1, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x03, 0x88, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x84, 0x22, 0x4a, 0x2f, 0x7c, 0x00, 0x00,
- 0x03, 0x84, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2, 0x86, 0x88, 0x01, 0x00,
- 0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00, 0x05, 0x00, 0x00, 0x43,
- 0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42, 0x81, 0xe0, 0x01, 0x00,
- 0x03, 0x84, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00, 0xf1, 0x84, 0xa2, 0x4b,
- 0xfd, 0x7f, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x03, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x05, 0x84, 0x69, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3,
- 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x79, 0x41, 0x47, 0xc3, 0x01, 0x00,
- 0x04, 0x00, 0xa0, 0xa1, 0x09, 0x6c, 0x00, 0x00, 0x0c, 0x84, 0x22, 0xa1,
- 0x09, 0x6c, 0x00, 0x00, 0x27, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x08, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0x46, 0x84, 0xa3, 0x92,
- 0x03, 0x6c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0x80, 0xb2, 0x01, 0x00, 0x03, 0x88, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x13, 0x84, 0x22, 0x5c, 0x17, 0x7c, 0x00, 0x00, 0x14, 0x84, 0x00, 0x00,
- 0x2a, 0xb0, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x08, 0x80, 0xc8, 0x01, 0x00, 0x18, 0x84, 0xa2, 0x43,
- 0x2f, 0x7c, 0x00, 0x00, 0x58, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x34, 0x84, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01,
- 0x8c, 0xcc, 0x01, 0x00, 0x58, 0x97, 0x00, 0x4c, 0x03, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
- 0x2c, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x21, 0x84, 0xa8, 0x54, 0x17, 0x10, 0x00, 0x00,
- 0x34, 0x84, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x2a, 0xc8, 0x01, 0x00, 0x33, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x03, 0xb0, 0x01, 0x00, 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0x09, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x34, 0x84, 0x28, 0x54, 0x17, 0x10, 0x00, 0x00,
- 0x30, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43,
- 0x61, 0x31, 0x01, 0x00, 0x36, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17,
- 0x98, 0x88, 0x01, 0x00, 0x39, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x3a, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x60, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x41, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0x16, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0xe4, 0xb1, 0x01, 0x00,
- 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x44, 0x84, 0xa2, 0x5f,
- 0x2f, 0x7c, 0x00, 0x00, 0x80, 0x93, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x03, 0x88, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x48, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
- 0xee, 0x84, 0x00, 0x41, 0x43, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x27, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x4b, 0x84, 0x35, 0x01,
- 0x86, 0x30, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x54, 0x84, 0x28, 0xb1, 0x30, 0x30, 0x00, 0x00, 0x4c, 0x84, 0x22, 0x4d,
- 0x75, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00,
- 0xdb, 0x84, 0xa7, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x43, 0xc3, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00,
- 0xed, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x54, 0x84, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0x5e, 0x84, 0xa7, 0x40,
- 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x2c, 0xb0, 0x01, 0x00, 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
- 0x4c, 0x84, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x63, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00,
- 0x4c, 0x84, 0xa3, 0x0b, 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
- 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x03, 0x48, 0x6d, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40, 0x39, 0xb0, 0x01, 0x00,
- 0x6d, 0x84, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x22, 0x00, 0x00, 0x08,
- 0x12, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x16, 0x30, 0x6c, 0x00, 0x00,
- 0xde, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00, 0x70, 0x84, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x14, 0x00, 0x20, 0x01, 0xe0, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40,
- 0x37, 0x98, 0x01, 0x00, 0x75, 0x84, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00, 0x80, 0x84, 0x82, 0x41,
- 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x7c, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x79, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xed, 0x94, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x91, 0x84, 0x22, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x23, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x0b, 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x88, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x4c,
- 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x37, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00, 0x75, 0x84, 0x00, 0x45,
- 0x1f, 0x80, 0x00, 0x00, 0x93, 0x84, 0xa3, 0x12, 0x36, 0x6c, 0x00, 0x00,
- 0x94, 0x84, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
- 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x97, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0xbf, 0x84, 0x22, 0x14,
- 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x14,
- 0x12, 0xc0, 0x01, 0x00, 0xb7, 0x84, 0xa2, 0x14, 0x36, 0x50, 0x00, 0x00,
- 0xa7, 0x84, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xa5, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xa2, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x2b, 0x80, 0x01, 0x00, 0x04, 0x00, 0x22, 0x50, 0x2b, 0x6c, 0x00, 0x00,
- 0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0xad, 0x84, 0x23, 0x01,
- 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00,
- 0xb8, 0x84, 0x22, 0x1b, 0x02, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0xe0, 0x8d, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0xb4, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xb8, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x2a, 0xc0, 0x01, 0x00, 0x75, 0x84, 0xa2, 0x40, 0x25, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x39, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x13,
- 0x38, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x12, 0xb0, 0x01, 0x00, 0x75, 0x84, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0xc6, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19,
- 0x62, 0xdd, 0x01, 0x00, 0xc3, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xed, 0x94, 0x00, 0x40,
- 0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0xca, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
- 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
- 0xcd, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x17, 0x90, 0x01, 0x00, 0xd0, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00, 0x16, 0x00, 0x20, 0x1d,
- 0xe4, 0xb1, 0x01, 0x00, 0xd2, 0x84, 0xa3, 0x40, 0x27, 0x6c, 0x00, 0x00,
- 0xd4, 0x84, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00, 0x00, 0x84, 0x00, 0x0b,
- 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13, 0x16, 0x94, 0x01, 0x00,
- 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
- 0x0f, 0x6c, 0x00, 0x00, 0x03, 0x88, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00,
- 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x01, 0x38, 0x43, 0x01, 0x00,
- 0x03, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x03,
- 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x61, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00, 0xe0, 0x84, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00,
- 0xe2, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xed, 0x84, 0x22, 0x13,
- 0x82, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43, 0x83, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00,
- 0xe8, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x62, 0xb1, 0x01, 0x00, 0xea, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xe4, 0x84, 0x00, 0x41, 0x83, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
- 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
- 0x89, 0x30, 0x01, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
- 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x03, 0x88, 0x00, 0x40,
- 0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x01, 0x80, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00,
- 0x05, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
- 0x8a, 0x30, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
- 0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x05, 0x85, 0x22, 0x41,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x85, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x04, 0x85, 0x22, 0x5f,
- 0x0f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00,
- 0x06, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
- 0x8a, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0x14, 0x85, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x14, 0x85, 0x22, 0x20,
- 0x85, 0x6c, 0x00, 0x00, 0x0f, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x4b, 0xe1, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
- 0x19, 0x85, 0x22, 0x3a, 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x8e, 0xb0, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x1e, 0x85, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00,
- 0x0a, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
- 0x01, 0xb0, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x35, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x87, 0x96, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x22, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
- 0x2b, 0x85, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0x55, 0x97, 0x00, 0x4b,
- 0x95, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x4c, 0x8f, 0xb0, 0x00, 0x00,
- 0x2d, 0x85, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x43, 0xc1, 0x01, 0x00, 0x2f, 0x85, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
- 0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1, 0x2a, 0xc8, 0x01, 0x00,
- 0x57, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x41,
- 0x81, 0x30, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0x39, 0x85, 0x64, 0x47, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x3a, 0x85, 0xa8, 0x1b,
- 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x74, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa0, 0x05,
- 0x03, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x09, 0x03, 0x6c, 0x00, 0x00,
- 0x08, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x6b, 0x85, 0x01, 0xfb,
- 0x08, 0x30, 0x00, 0x00, 0xd5, 0x85, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x14, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
- 0x12, 0x95, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00, 0x5c, 0x85, 0x22, 0x41,
- 0x81, 0x6c, 0x00, 0x00, 0x4b, 0x85, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5b, 0x85, 0x22, 0x5f,
- 0x0f, 0x7c, 0x00, 0x00, 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00,
- 0x51, 0x85, 0xa6, 0x5f, 0x0f, 0x00, 0x00, 0x00, 0x2b, 0x94, 0x00, 0x40,
- 0x05, 0x30, 0x01, 0x00, 0x0a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x58, 0x85, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0x26, 0x96, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00, 0x08, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x90, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0x69, 0x85, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x6a, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x69, 0x85, 0x22, 0x20,
- 0x85, 0x6c, 0x00, 0x00, 0x66, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0x6d, 0x85, 0x21, 0x04,
- 0x80, 0x20, 0x00, 0x00, 0x6e, 0x85, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
- 0xa1, 0x88, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00, 0x9c, 0x85, 0x00, 0x43,
- 0x81, 0xb0, 0x00, 0x00, 0xa0, 0x85, 0x00, 0xfb, 0x22, 0xb0, 0x00, 0x00,
- 0xa1, 0x88, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x69, 0x89, 0x00, 0x4e,
- 0x8f, 0xb0, 0x00, 0x00, 0x91, 0x85, 0x00, 0x5a, 0x8f, 0xb0, 0x00, 0x00,
- 0x76, 0x85, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x53,
- 0x81, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x56, 0x81, 0xb0, 0x00, 0x00,
- 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x3c, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0a,
- 0x8a, 0x30, 0x01, 0x00, 0x3d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x18, 0x00, 0x00, 0x11, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0xf2,
- 0x8a, 0x14, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x69, 0x89, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x84, 0x85, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x83, 0x85, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
- 0x69, 0x89, 0x00, 0x53, 0x8f, 0xb0, 0x00, 0x00, 0x69, 0x89, 0x00, 0x54,
- 0x8f, 0xb0, 0x00, 0x00, 0x8d, 0x85, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
- 0x87, 0x85, 0xa2, 0x0a, 0xe4, 0x6d, 0x00, 0x00, 0x69, 0x89, 0x00, 0x5d,
- 0x8f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x80, 0xd0, 0x01, 0x00, 0x8b, 0x85, 0xa0, 0x91,
- 0x81, 0x6c, 0x00, 0x00, 0x69, 0x89, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00,
- 0x25, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x85, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00,
- 0x69, 0x89, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x07, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x3c, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0a,
- 0x8a, 0x30, 0x01, 0x00, 0x3d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0xf2, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x69, 0x89, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00,
- 0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x69, 0x89, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00, 0xa1, 0x88, 0xa0, 0x42,
- 0x83, 0x6c, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x54, 0x81, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x23, 0x40,
- 0x0f, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x20, 0xaa, 0x0f, 0x6c, 0x00, 0x00,
- 0x09, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
- 0x8a, 0x30, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
- 0x16, 0x88, 0x01, 0x00, 0xae, 0x85, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x0a, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x1c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0xed, 0x87, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0xc0, 0x85, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
- 0xbb, 0x85, 0xa2, 0x54, 0xfd, 0x7f, 0x00, 0x00, 0xb3, 0x85, 0x22, 0x55,
- 0xfd, 0x7f, 0x00, 0x00, 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0xaa, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x53,
- 0xfd, 0x7f, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b,
- 0x80, 0xf4, 0x01, 0x00, 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0xbb, 0x85, 0x22, 0x43, 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b,
- 0x80, 0x88, 0x01, 0x00, 0xaa, 0x85, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00,
- 0x7c, 0x96, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbc, 0x85, 0x46, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xbf, 0x85, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00,
- 0xb1, 0x85, 0x1e, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
- 0x31, 0xc3, 0x01, 0x00, 0x79, 0x94, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00,
- 0xc4, 0x85, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
- 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c, 0xe0, 0x99, 0x01, 0x00,
- 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x46, 0xc9, 0x01, 0x00, 0xcc, 0x85, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe6, 0x91, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa1, 0x46, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe6, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xa1, 0x88, 0x00, 0x40,
- 0x81, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x14, 0xb0, 0x01, 0x00, 0xe0, 0x85, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x40, 0x87, 0x6c, 0x00, 0x00, 0xdc, 0x85, 0x22, 0x40,
- 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1f, 0x90, 0x01, 0x00,
- 0xde, 0x85, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x1f, 0x90, 0x01, 0x00, 0xe0, 0x85, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x09, 0x7c, 0x00, 0x00, 0xe1, 0x85, 0x66, 0x1b, 0x2c, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa0, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x76, 0x41,
- 0x41, 0xc3, 0x01, 0x00, 0x13, 0x86, 0x23, 0x92, 0x15, 0x6c, 0x00, 0x00,
- 0x13, 0x86, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x19, 0x86, 0x22, 0x4b,
- 0xfd, 0x7f, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x0a,
- 0x24, 0xc8, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
- 0x11, 0x86, 0x22, 0x08, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xa3, 0xc1, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x12, 0x24, 0xcc, 0x01, 0x00,
- 0xea, 0x85, 0xaa, 0x41, 0x27, 0x40, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x49,
- 0x27, 0x6c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00,
- 0x0b, 0x86, 0x26, 0x40, 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x10, 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0,
- 0xa2, 0xc9, 0x01, 0x00, 0xf8, 0x85, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00,
- 0x04, 0x86, 0x00, 0x41, 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0xfd, 0x85, 0xa2, 0x44,
- 0x23, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x86, 0xa8, 0x42,
- 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xa3, 0xc1, 0x01, 0x00, 0xf6, 0x85, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x0b, 0x86, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x08, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x0b, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
- 0x17, 0x00, 0x00, 0xd0, 0x2a, 0xc8, 0x01, 0x00, 0x24, 0x86, 0x00, 0x17,
- 0x10, 0xb0, 0x00, 0x00, 0x04, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x19, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb9, 0x94, 0x00, 0x92,
- 0x25, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x31, 0xb0, 0x01, 0x00,
- 0x0b, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00,
- 0x8a, 0x30, 0x01, 0x00, 0x19, 0x86, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
- 0x24, 0x86, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
- 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x78, 0x98, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00, 0x04, 0x00, 0x1c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa0, 0x9f,
- 0x13, 0x6c, 0x00, 0x00, 0x23, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0x27, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xed, 0x87, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01,
- 0x80, 0xce, 0x01, 0x00, 0x38, 0x86, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0x2d, 0x86, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
- 0x2d, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x2d, 0x86, 0xa3, 0x07,
- 0x03, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x30, 0x86, 0xa3, 0x40, 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01,
- 0xf0, 0xcd, 0x01, 0x00, 0x32, 0x86, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x0e, 0xcc, 0x01, 0x00, 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0x00, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x36, 0x86, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x03, 0x48, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x08, 0xb0, 0x01, 0x00,
- 0xa0, 0x01, 0x2d, 0x40, 0x00, 0xc0, 0x01, 0x00, 0x19, 0x87, 0x22, 0x0f,
- 0x42, 0x05, 0x00, 0x00, 0x4b, 0x86, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x46, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x43, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x4b, 0x86, 0x22, 0x07,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0xc0, 0x06, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x54, 0x29, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5f,
- 0x0f, 0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x14, 0x80, 0xce, 0x01, 0x00,
- 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0x42, 0x00, 0x00, 0x03,
- 0x0a, 0xc8, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
- 0x10, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08,
- 0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0xfe, 0x7f, 0x00, 0x05, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa2,
- 0x86, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00,
- 0x79, 0x86, 0x22, 0x01, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
- 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x66, 0x86, 0xa3, 0x07,
- 0x02, 0x6c, 0x00, 0x00, 0x67, 0x86, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x07, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x02, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00,
- 0x73, 0x86, 0x22, 0x40, 0x03, 0x6c, 0x00, 0x00, 0x73, 0x86, 0x22, 0x42,
- 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x99, 0x86, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x70, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x75, 0x86, 0xa8, 0x40,
- 0x23, 0x30, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x99, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
- 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x7e, 0x86, 0xa3, 0x12,
- 0x0e, 0x6c, 0x00, 0x00, 0x7f, 0x86, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x12, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d,
- 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
- 0x14, 0x99, 0x00, 0x08, 0x98, 0x30, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08,
- 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x87, 0x86, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0xb9, 0x86, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
- 0x8d, 0x86, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x10, 0xc0, 0x01, 0x00, 0x92, 0x86, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x25, 0x98, 0x01, 0x00, 0x94, 0x86, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x99, 0x86, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x95, 0x86, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0xb9, 0x86, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0xb8, 0x86, 0xa2, 0x0d,
- 0x0e, 0x50, 0x00, 0x00, 0xa5, 0x86, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xa3, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xa0, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0xab, 0x86, 0xa2, 0x5f,
- 0x0f, 0x7c, 0x00, 0x00, 0x60, 0x86, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x60, 0x86, 0x23, 0x07,
- 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0xb5, 0x86, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0x60, 0x86, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0x60, 0x86, 0x00, 0x0d,
- 0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x2e, 0x14, 0x0a, 0xd0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x05, 0x48, 0xcd, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05,
- 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa4, 0x86, 0x06, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00, 0x0c, 0x00, 0x2a, 0xf2,
- 0xe0, 0xb1, 0x01, 0x00, 0xc1, 0x86, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6, 0x80, 0xce, 0x01, 0x00,
- 0xc5, 0x86, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x43, 0xc1, 0x01, 0x00, 0xc7, 0x86, 0x22, 0x0b, 0xed, 0x6d, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa1,
- 0x46, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00,
- 0x0f, 0x00, 0x00, 0xfa, 0x94, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45,
- 0x95, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf6, 0x0e, 0xb0, 0x01, 0x00, 0xd1, 0x86, 0x22, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00,
- 0xd1, 0x86, 0xa0, 0x46, 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xc0, 0x01, 0x00, 0xd5, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2,
- 0x42, 0x31, 0x00, 0x00, 0xd8, 0x86, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00,
- 0x0c, 0x00, 0x00, 0xa2, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x82, 0xb0, 0x01, 0x00, 0xdb, 0x86, 0xa0, 0x41,
- 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
- 0xe0, 0x86, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xe0, 0x86, 0xa0, 0x43,
- 0x89, 0x6c, 0x00, 0x00, 0xe0, 0x86, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00,
- 0xe0, 0x86, 0xa0, 0x41, 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00,
- 0xd8, 0x86, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0xed, 0x86, 0x22, 0x48,
- 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x48, 0x90, 0x88, 0x01, 0x00, 0xe7, 0x86, 0x90, 0x48,
- 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
- 0x93, 0xa4, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x43, 0x80, 0xcc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa2, 0x80, 0xc0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
- 0x42, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x86, 0x06, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x14, 0x99, 0x00, 0x17,
- 0x98, 0x30, 0x01, 0x00, 0xff, 0x07, 0x00, 0x17, 0x7e, 0x89, 0x01, 0x00,
- 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x14, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05,
- 0xe0, 0xcd, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
- 0x62, 0xdd, 0x01, 0x00, 0xf7, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x02, 0x87, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
- 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00,
- 0x01, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xfe, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x05, 0x87, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x06, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x85, 0x87, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00,
- 0x0d, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x09, 0x87, 0xa0, 0x07, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
- 0x0d, 0x87, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2a, 0x94, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x17, 0x87, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x14, 0x87, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00, 0x85, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x21, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x21, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x1e, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x26, 0x87, 0x22, 0x07,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x42, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa1,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0xe0, 0xb1, 0x01, 0x00, 0x2b, 0x87, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
- 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x18,
- 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x30, 0x87, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x52,
- 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x15, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0x3f, 0x87, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
- 0x40, 0x87, 0x68, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
- 0x1a, 0xb0, 0x01, 0x00, 0x14, 0x99, 0x00, 0x08, 0x98, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x47, 0x87, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x79, 0x87, 0x22, 0x0d, 0x14, 0x6c, 0x00, 0x00,
- 0x4d, 0x87, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x10, 0xc0, 0x01, 0x00, 0x52, 0x87, 0x00, 0x0d, 0x24, 0xd0, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x2b, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x20, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x25, 0x98, 0x01, 0x00, 0x54, 0x87, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x59, 0x87, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x55, 0x87, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00, 0x78, 0x87, 0xa2, 0x0d,
- 0x0e, 0x50, 0x00, 0x00, 0x65, 0x87, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x63, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x60, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03,
- 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x0e, 0x30, 0x00, 0x00, 0x6b, 0x87, 0xa2, 0x5f,
- 0x0f, 0x7c, 0x00, 0x00, 0x39, 0x87, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x39, 0x87, 0x23, 0x07,
- 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x75, 0x87, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0x39, 0x87, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0x39, 0x87, 0x00, 0x0d,
- 0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x83, 0x87, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x83, 0x87, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x80, 0x87, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x17, 0x10, 0xb0, 0x01, 0x00, 0x85, 0x87, 0x00, 0x40,
- 0x2b, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x9f, 0x13, 0x6c, 0x00, 0x00,
- 0x8c, 0x87, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
- 0x1c, 0xcc, 0x01, 0x00, 0x27, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x8d, 0x98, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x78, 0x98, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x03, 0x88, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00,
- 0x98, 0x87, 0x22, 0x50, 0x01, 0x6c, 0x00, 0x00, 0x0d, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x12, 0x95, 0x00, 0x07,
- 0x16, 0x30, 0x01, 0x00, 0xa3, 0x87, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
- 0x9e, 0x87, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xa2, 0x87, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x0e, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0xed, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xb0, 0x87, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b,
- 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x6a, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb0, 0x87, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00,
- 0xad, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x87, 0x95, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00,
- 0xc2, 0x97, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00,
- 0xa1, 0x88, 0xa2, 0x5f, 0x81, 0x6c, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x43,
- 0x19, 0x80, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x8e, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
- 0x90, 0x88, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x43, 0x8f, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0xa3, 0x43, 0x91, 0x6c, 0x00, 0x00, 0xc1, 0x87, 0x22, 0x48,
- 0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xc1, 0x87, 0x1f, 0xf0,
- 0x24, 0x6c, 0x00, 0x00, 0xc0, 0x87, 0x23, 0x41, 0x8f, 0x6c, 0x00, 0x00,
- 0xa1, 0x88, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x48,
- 0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0xc6, 0x87, 0x22, 0x0a,
- 0x90, 0x40, 0x00, 0x00, 0x58, 0x98, 0x00, 0x40, 0x91, 0x30, 0x01, 0x00,
- 0xa1, 0x88, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0xb0, 0x00, 0x2d, 0x45,
- 0x81, 0xb0, 0x01, 0x00, 0xd2, 0x87, 0x22, 0xf0, 0x2c, 0x30, 0x00, 0x00,
- 0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0xf3,
- 0x82, 0xe0, 0x01, 0x00, 0xcc, 0x87, 0xa3, 0x41, 0x2c, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0xf0,
- 0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x82, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00, 0xa1, 0x88, 0x20, 0x4c,
- 0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41, 0x98, 0xe8, 0x01, 0x00,
- 0xa1, 0x88, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00, 0xed, 0x87, 0x22, 0x0a,
- 0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
- 0xed, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa1, 0x88, 0x00, 0x49,
- 0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
- 0xda, 0x87, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x13, 0x80, 0x00, 0x40,
- 0x80, 0xdc, 0x01, 0x00, 0xdb, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0xdb, 0x87, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0xb1, 0x01, 0x00,
- 0xdd, 0x87, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00, 0xe1, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x1a, 0x83, 0x22, 0x40, 0x57, 0x7d, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00, 0xe1, 0x87, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x01, 0x83, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00, 0xe7, 0x87, 0x22, 0x46,
- 0xf3, 0x7f, 0x00, 0x00, 0xe7, 0x87, 0xa2, 0x41, 0xf3, 0x7f, 0x00, 0x00,
- 0xc6, 0x80, 0x00, 0x42, 0x97, 0x33, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb,
- 0x81, 0xc8, 0x01, 0x00, 0xea, 0x87, 0x22, 0x40, 0xf2, 0x7f, 0x00, 0x00,
- 0xc6, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00, 0xec, 0x87, 0x22, 0x40,
- 0x73, 0x7d, 0x00, 0x00, 0xe0, 0x80, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
- 0xe4, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x87, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xf4, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xf1, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x2e, 0x94, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0xf5, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x2e, 0x94, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00,
- 0xff, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xff, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xfc, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x3e, 0x94, 0x22, 0x02,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x88, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x3e, 0x94, 0x1a, 0x02,
- 0x68, 0x97, 0x00, 0x00, 0x0a, 0x88, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x0a, 0x88, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x07, 0x88, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x2f, 0x83, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x0b, 0x88, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
- 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
- 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40,
- 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x0e, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0c, 0x55, 0x6f, 0x00, 0x00,
- 0x29, 0x00, 0x00, 0x40, 0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x12, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
- 0x16, 0x88, 0x01, 0x00, 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x23, 0xb0, 0x01, 0x00, 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x43, 0x88, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x22, 0x88, 0x60, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
- 0x84, 0x89, 0x01, 0x00, 0x2b, 0x88, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
- 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x60, 0x88, 0x70, 0xf0, 0x18, 0x30, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x0c, 0x82, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x41,
- 0x0e, 0x6c, 0x00, 0x00, 0x43, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x3a, 0x88, 0xa0, 0x48,
- 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x34, 0x88, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x31, 0x88, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x60, 0x88, 0x00, 0xf8,
- 0x18, 0x30, 0x01, 0x00, 0x35, 0x88, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x34, 0x94, 0x01, 0x00, 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x1a, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a,
- 0x62, 0xdd, 0x01, 0x00, 0x3e, 0x88, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x35, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00,
- 0x4f, 0x88, 0x22, 0x41, 0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xc0, 0x01, 0x00, 0x4b, 0x88, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x12, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x1f, 0x88, 0x00, 0x41,
- 0x17, 0xb0, 0x00, 0x00, 0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00,
- 0x1f, 0x88, 0x83, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x17, 0xb0, 0x01, 0x00, 0x1f, 0x88, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00,
- 0x5a, 0x88, 0x23, 0x40, 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00,
- 0x57, 0x88, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
- 0x54, 0x88, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x60, 0x88, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00, 0x58, 0x88, 0xa2, 0x41,
- 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
- 0x5d, 0x88, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xb0, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00,
- 0x56, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
- 0x0f, 0xb0, 0x00, 0x00, 0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00,
- 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x0c,
- 0x7e, 0x89, 0x01, 0x00, 0x79, 0x88, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
- 0x6c, 0x88, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0c, 0x8a, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x40,
- 0x62, 0x99, 0x01, 0x00, 0x6c, 0x88, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x68, 0x88, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x74, 0x88, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
- 0x2a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x0c,
- 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00,
- 0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
- 0x6d, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x88, 0x22, 0x49,
- 0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54,
- 0x77, 0x7d, 0x00, 0x00, 0x74, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
- 0x79, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
- 0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
- 0x2f, 0x83, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x81, 0x88, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x84, 0x88, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xab, 0x27, 0xb3, 0x01, 0x00,
- 0x2f, 0x83, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x2f, 0x83, 0x22, 0x51,
- 0xfd, 0x7f, 0x00, 0x00, 0x2f, 0x83, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
- 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0x90, 0x88, 0x22, 0x40,
- 0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
- 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x40, 0x05, 0x00, 0x40,
- 0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0x55, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
- 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
- 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2f, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0xf2, 0x0e, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02,
- 0x80, 0x32, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0xab, 0x88, 0x22, 0x50,
- 0x81, 0x6c, 0x00, 0x00, 0x0f, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x04,
- 0x8a, 0x14, 0x01, 0x00, 0x04, 0x00, 0x20, 0x48, 0x09, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x20, 0x57, 0x81, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x20, 0x40,
- 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00, 0xb1, 0x88, 0x00, 0x4b,
- 0x10, 0xc9, 0x00, 0x00, 0xe1, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x16, 0x8c, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x52, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x99, 0x8c, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xc8, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8e, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdc, 0x8c, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xda, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x95, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x95, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x95, 0x8d, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xb5, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xdd, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x0c, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8e, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x21, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x21, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x2c, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x3e, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x2d, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x3e, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x40, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x34, 0x8e, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x93, 0x8d, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x93, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x93, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
- 0x42, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x42, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x49, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x4b, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x58, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xbe, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xc6, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xda, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x93, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xc2, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xcc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x3b, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x02, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf2,
- 0x0e, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0x07, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x08, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x47, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x04,
- 0x8a, 0x14, 0x01, 0x00, 0x04, 0x00, 0x20, 0x4e, 0x09, 0x6c, 0x00, 0x00,
- 0x2a, 0x00, 0x00, 0x47, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x06, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00, 0x7a, 0x89, 0x00, 0x4b,
- 0x10, 0xc9, 0x00, 0x00, 0xf6, 0x8e, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2f, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x36, 0x8f, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x47, 0x8f, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x6a, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x64, 0x8f, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x71, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xda, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x3a, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x3a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x3a, 0x8f, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
- 0x3a, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x4d,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x45, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x47, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x64, 0x8f, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x71, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x81, 0x90, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x81, 0x90, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xc6, 0x8b, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x81, 0x90, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3a, 0x8f, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0xac, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xac, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xbb, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xbb, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x91, 0x00, 0x40,
- 0x09, 0xb0, 0x00, 0x00, 0x4e, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x40, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x4e, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x57, 0x91, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x57, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x40, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x87, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x40, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x45, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x45, 0x90, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xab, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xab, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xc6, 0x8b, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x8e, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x8e, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x5a, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x5a, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x5a, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x5a, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x77, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x96, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x96, 0x92, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x96, 0x92, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xbf, 0x92, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xbd, 0x92, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xbf, 0x92, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xbd, 0x92, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x67, 0x91, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x74, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x74, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x74, 0x91, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x91, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x62, 0x90, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7d, 0x93, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x93, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x93, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x93, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x53, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x0f, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x53, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x0f, 0x93, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x16, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x16, 0x93, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2c, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x44, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x44, 0x93, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x44, 0x93, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x47, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x67, 0x93, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x6a, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x47, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x67, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x7a, 0x90, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x6e, 0x93, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x7a, 0x90, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x10, 0x93, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x93, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x77, 0x93, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x62, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xfd, 0x92, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x71, 0x8f, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x71, 0x8f, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x62, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0xf8, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
- 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd8, 0x8b, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xd8, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xd5, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x1a, 0x85, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0xd9, 0x8b, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
- 0x1a, 0x85, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00,
- 0x05, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00, 0xf8, 0x87, 0x00, 0x04,
- 0xe6, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb1, 0x01, 0x00, 0x78, 0x98, 0x00, 0x06,
- 0x07, 0x40, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
- 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
- 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
- 0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
- 0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
- 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x05, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0x0d, 0x8c, 0x20, 0x4b,
- 0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x0a, 0x8c, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x14, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x10, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x09, 0x97, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
- 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x14, 0x80, 0x00, 0x03,
- 0x98, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xa1, 0x98, 0x6c, 0x00, 0x00,
- 0x1b, 0x8c, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00, 0x1e, 0x8c, 0xa2, 0x4c,
- 0xfd, 0x7f, 0x00, 0x00, 0x1f, 0x8c, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00,
- 0x20, 0x8c, 0x20, 0xf0, 0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x56, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x64, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
- 0x80, 0xcc, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x43,
- 0x81, 0x04, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x2b, 0x8c, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x46,
- 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x43,
- 0xf0, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x62, 0xb1, 0x01, 0x00, 0x34, 0x8c, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x86, 0xe4, 0x01, 0x00, 0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
- 0x8b, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x3c, 0x8c, 0x22, 0x43,
- 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
- 0x3f, 0x8c, 0x22, 0x44, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00,
- 0x68, 0x01, 0x20, 0xa2, 0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x43, 0x8c, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x48, 0x8c, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x5c, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf2,
- 0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
- 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x55, 0x8c, 0xa2, 0x49,
- 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x59, 0x8c, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0x86, 0x00, 0x2f, 0x49,
- 0x19, 0x80, 0x01, 0x00, 0x59, 0x8c, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xe7, 0x91, 0x01, 0x00, 0x5c, 0x8c, 0xa2, 0x46, 0x19, 0x7c, 0x00, 0x00,
- 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x60, 0x8c, 0x00, 0x40,
- 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46, 0x19, 0x80, 0x01, 0x00,
- 0x60, 0x8c, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe7, 0x91, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x4e, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x06, 0x6c, 0x00, 0x00,
- 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf0,
- 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x0c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x16, 0x88, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00, 0x90, 0x8c, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x76, 0x8c, 0x22, 0x0a, 0x16, 0x6c, 0x00, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
- 0x15, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00, 0x75, 0x8c, 0xa0, 0x43,
- 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x13, 0xb0, 0x01, 0x00,
- 0x6b, 0x8c, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00, 0x90, 0x8c, 0x22, 0x0a,
- 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x08, 0x12, 0x6c, 0x00, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
- 0x15, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x90, 0x8c, 0x22, 0x41,
- 0x15, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00,
- 0x83, 0x8c, 0xa0, 0x43, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x11, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x06, 0x10, 0x6c, 0x00, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0x4e, 0x97, 0x00, 0x47,
- 0x61, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x2b, 0x94, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x8c, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x7f, 0x8c, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x80, 0x97, 0x00, 0x51,
- 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
- 0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00,
- 0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x48,
- 0x19, 0x7c, 0x00, 0x00, 0x9d, 0x8c, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
- 0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00,
- 0x00, 0x11, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00,
- 0xa4, 0x8c, 0x22, 0x45, 0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
- 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0,
- 0x8c, 0x6c, 0x00, 0x00, 0x90, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf3,
- 0x84, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf3, 0x84, 0x6c, 0x00, 0x00,
- 0x58, 0x00, 0x3e, 0x43, 0x85, 0xe0, 0x01, 0x00, 0xab, 0x8c, 0x22, 0x48,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
- 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
- 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
- 0x02, 0x30, 0x00, 0x00, 0xb9, 0x8c, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
- 0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
- 0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x58, 0x98, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0xc2, 0x8c, 0xa2, 0x44,
- 0x81, 0x6c, 0x00, 0x00, 0xc0, 0x8c, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xb6, 0x95, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xea, 0x8c, 0xa2, 0x08,
- 0x3c, 0x30, 0x00, 0x00, 0xc2, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xea, 0x8c, 0xa2, 0x08,
- 0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
- 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
- 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x8f, 0x95, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x9d, 0x8c, 0x22, 0x4a,
- 0x80, 0x32, 0x00, 0x00, 0xce, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3,
- 0x94, 0x30, 0x01, 0x00, 0x04, 0x00, 0x20, 0x43, 0x97, 0x6c, 0x00, 0x00,
- 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00, 0x00, 0x8c, 0x01, 0x00,
- 0xdd, 0x8b, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0, 0x8c, 0x6c, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00,
- 0xdc, 0x8c, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00, 0xe1, 0x8c, 0x22, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0xb6, 0x95, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00,
- 0xe5, 0x8c, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f,
- 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe5, 0x8c, 0xa2, 0x08,
- 0x3c, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
- 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x50, 0x00, 0x2d, 0x10,
- 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
- 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x2d, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x14, 0xb0, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x46,
- 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40, 0x10, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x81, 0xd0, 0x01, 0x00, 0x12, 0x97, 0x00, 0x40, 0xe4, 0x31, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00, 0xf6, 0x8c, 0xa8, 0x40,
- 0x23, 0x30, 0x00, 0x00, 0x08, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x10, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x8d, 0x82, 0x41,
- 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x01, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xfe, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00,
- 0x0c, 0x8d, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x08, 0x8d, 0xa3, 0x01,
- 0x0c, 0x6c, 0x00, 0x00, 0x09, 0x8d, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00, 0x0b, 0x8d, 0x20, 0x02,
- 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x04, 0xb0, 0x01, 0x00,
- 0x0f, 0x8d, 0x00, 0x02, 0xe0, 0xb1, 0x00, 0x00, 0x0e, 0x8d, 0xa3, 0x01,
- 0x0c, 0x6c, 0x00, 0x00, 0x0f, 0x8d, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x02,
- 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x14, 0x8d, 0xa8, 0x13,
- 0xe0, 0x31, 0x00, 0x00, 0x51, 0x8d, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
- 0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00, 0x3c, 0x8d, 0xa2, 0x02,
- 0x02, 0x50, 0x00, 0x00, 0x22, 0x8d, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x21, 0x8d, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x1d, 0x8d, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x2d, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0, 0x38, 0xb0, 0x01, 0x00,
- 0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2f, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x3e, 0x8d, 0x22, 0x01, 0x14, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x8d, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
- 0x20, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x2f, 0x8d, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x2c, 0x8d, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x38, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x94, 0xb0, 0x01, 0x00, 0x38, 0x00, 0x2d, 0xf0, 0x96, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x4a, 0xf1, 0xb1, 0x01, 0x00,
- 0x44, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x39, 0x8d, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
- 0x3e, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x38, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x4c, 0x8d, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x33, 0xc0, 0x01, 0x00, 0x4a, 0x8d, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x8f, 0x0d,
- 0x42, 0x31, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x5c, 0xe1, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xf0,
- 0x6a, 0x06, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8, 0x10, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x37, 0x98, 0x01, 0x00, 0xfa, 0x8c, 0x00, 0xa1, 0x1a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00, 0xfa, 0x8c, 0x00, 0x02,
- 0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
- 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
- 0x58, 0x8d, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02,
- 0x02, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x02, 0x0c, 0x6c, 0x00, 0x00,
- 0x37, 0x00, 0x2d, 0x46, 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
- 0x80, 0xf4, 0x01, 0x00, 0x57, 0x8d, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
- 0x5e, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x5b, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x0d, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x65, 0x8d, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x62, 0x8d, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x60, 0x01, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
- 0x6a, 0x8d, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
- 0x32, 0x00, 0x00, 0xa6, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x2a, 0x94, 0x01, 0x00, 0x6d, 0x8d, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00, 0x72, 0x8d, 0x28, 0x40,
- 0x05, 0x30, 0x00, 0x00, 0x6e, 0x8d, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
- 0x75, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x62, 0xb1, 0x01, 0x00, 0x80, 0x8d, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x72, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00,
- 0x92, 0xb0, 0x01, 0x00, 0x7d, 0x8d, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa3, 0x48,
- 0x3b, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0xc3, 0x94, 0x00, 0xf8, 0x00, 0x30, 0x01, 0x00, 0x7a, 0x8d, 0xa2, 0x41,
- 0x3b, 0x50, 0x00, 0x00, 0x81, 0x8d, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
- 0xff, 0x07, 0x00, 0x1e, 0x00, 0x8c, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x81, 0x8d, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x1d, 0x47, 0x19, 0x80, 0x01, 0x00, 0x84, 0x8d, 0x22, 0x5f,
- 0x01, 0x6c, 0x00, 0x00, 0x87, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xa7, 0x88, 0x00, 0x00, 0x80, 0xb0, 0x00, 0x00, 0x8b, 0x8d, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x8b, 0x8d, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x88, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x8b, 0x8d, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x07, 0x94, 0x89, 0x01, 0x00, 0x91, 0x8d, 0x85, 0xca,
- 0x94, 0x30, 0x00, 0x00, 0x87, 0x98, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00,
- 0x0e, 0x00, 0x00, 0x0f, 0x1e, 0x8c, 0x01, 0x00, 0xb4, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x80, 0x97, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00,
- 0xdd, 0x8b, 0x00, 0x47, 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x19, 0x80, 0x01, 0x00, 0xdd, 0x8b, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
- 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x98, 0x8d, 0xa2, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x12, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00,
- 0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00, 0x9e, 0x8d, 0x90, 0x4c,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0xa0, 0x8d, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
- 0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2,
- 0x80, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xaa, 0x8d, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xae, 0x8d, 0x45, 0x48,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00,
- 0xb4, 0x8d, 0x28, 0x40, 0x05, 0x30, 0x00, 0x00, 0xaf, 0x8d, 0x22, 0x48,
- 0x77, 0x7d, 0x00, 0x00, 0xc3, 0x94, 0x1d, 0x08, 0x00, 0x30, 0x01, 0x00,
- 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x8b, 0x1d, 0x47,
- 0x19, 0x80, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x84, 0xc8, 0x01, 0x00, 0xba, 0x8d, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf3, 0x9e, 0x06, 0x00, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x82, 0xcc, 0x01, 0x00, 0xc8, 0x8d, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00,
- 0xdd, 0x8b, 0x22, 0x44, 0x83, 0x70, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x24, 0x6c, 0x00, 0x00,
- 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43,
- 0xe7, 0xe1, 0x01, 0x00, 0xdd, 0x8b, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
- 0x87, 0x98, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00, 0xa7, 0x88, 0x23, 0x41,
- 0x83, 0x6c, 0x00, 0x00, 0xa7, 0x88, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
- 0x34, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42,
- 0xe6, 0x6d, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x00, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x00, 0xbe, 0x06, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x4e, 0x97, 0x00, 0x47, 0x61, 0x31, 0x01, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x8e, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0,
- 0x14, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xa5, 0x8c, 0xa2, 0x40, 0x8f, 0x7c, 0x00, 0x00, 0xdb, 0x8d, 0x22, 0x47,
- 0x8f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x48, 0x19, 0x7c, 0x00, 0x00,
- 0xa5, 0x8c, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00, 0x04, 0x00, 0x22, 0x46,
- 0x8f, 0x7c, 0x00, 0x00, 0x5d, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x5d,
- 0x05, 0xb4, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf3, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x8e, 0xb0, 0x01, 0x00, 0xf0, 0x00, 0x00, 0x47,
- 0x7e, 0x89, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x86, 0xdc, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x8c, 0x93, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0xef, 0x8d, 0xa2, 0x50, 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf0, 0x00, 0x00, 0x47, 0x7e, 0x89, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0xf4, 0x8d, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40,
- 0x81, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x20, 0x47, 0xe6, 0xb1, 0x01, 0x00,
- 0xdd, 0x8b, 0x22, 0x47, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x00, 0x47,
- 0x0c, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x8f, 0x84, 0x01, 0x00,
- 0x09, 0x8e, 0x22, 0x47, 0x0c, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
- 0x81, 0xe0, 0x01, 0x00, 0x09, 0x8e, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x02, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xff, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x02, 0x8e, 0x42, 0x40,
- 0x05, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x07, 0x8e, 0x23, 0x41,
- 0x0d, 0x6c, 0x00, 0x00, 0xdd, 0x8d, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x87, 0x98, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xa7, 0x88, 0x00, 0x48,
- 0x81, 0xb0, 0x00, 0x00, 0xdd, 0x8b, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
- 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x84, 0xb0, 0x01, 0x00,
- 0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf2,
- 0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x1a, 0x8e, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0x1a, 0x8e, 0xa3, 0x40, 0x82, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00, 0x1c, 0x8e, 0x20, 0x4c,
- 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00,
- 0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x42,
- 0xe6, 0xb1, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x09, 0x97, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0x5c,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x80, 0xc0, 0x01, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa3, 0xf0,
- 0x80, 0x6c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
- 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xdd, 0x8b, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
- 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
- 0x96, 0xcc, 0x01, 0x00, 0xdd, 0x8b, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0x55, 0x97, 0x00, 0x46,
- 0x95, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xdd, 0x8b, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xcc, 0x01, 0x00,
- 0xdd, 0x8b, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4a,
- 0x81, 0x30, 0x01, 0x00, 0x55, 0x97, 0x00, 0x47, 0x95, 0x30, 0x01, 0x00,
- 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2b, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0xdd, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x46,
- 0x19, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x46, 0x8e, 0x90, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xdd, 0x8b, 0x22, 0x40,
- 0xe5, 0x6d, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x41, 0xe5, 0xc1, 0x00, 0x00,
- 0x09, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x56, 0x8e, 0x80, 0xf3,
- 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x81, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0xdd, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
- 0x80, 0x32, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6e, 0x8e, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x84, 0xcc, 0x01, 0x00,
- 0x66, 0x8e, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x42,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x68, 0x8e, 0x37, 0x5c,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
- 0x69, 0x8e, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x62, 0xb1, 0x01, 0x00, 0x6b, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
- 0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0,
- 0x28, 0xb0, 0x01, 0x00, 0x34, 0x00, 0x2d, 0xf3, 0x84, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf3, 0x84, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3e, 0x43,
- 0x85, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00,
- 0xe0, 0xb1, 0x01, 0x00, 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x2b, 0xb0, 0x01, 0x00, 0x64, 0x97, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x16, 0xc0, 0x01, 0x00, 0x7f, 0x8e, 0xa0, 0x14,
- 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xf8, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00,
- 0x10, 0x50, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x88, 0x8e, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
- 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x88, 0x8e, 0xa4, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x01, 0x00, 0x6e, 0x43, 0x86, 0x98, 0x01, 0x00, 0xa8, 0x97, 0x00, 0x30,
- 0x81, 0x30, 0x01, 0x00, 0x8c, 0x8e, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x93, 0x8e, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
- 0x17, 0xc0, 0x01, 0x00, 0x92, 0x8e, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x41, 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x99, 0x8e, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00,
- 0xa0, 0x00, 0x20, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46,
- 0x19, 0x10, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
- 0x17, 0xf0, 0x01, 0x00, 0x9e, 0x8e, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xa0, 0x8e, 0x22, 0x43,
- 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
- 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
- 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0xaa, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xae, 0x8e, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0xaf, 0x8e, 0xa8, 0x40,
- 0x05, 0x30, 0x00, 0x00, 0x35, 0x00, 0x1d, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x63, 0xf3, 0x84, 0xc8, 0x01, 0x00, 0xb5, 0x8e, 0xa0, 0x43,
- 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf3,
- 0x9e, 0x06, 0x00, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45, 0xe7, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0xe7, 0x91, 0x01, 0x00, 0x80, 0x97, 0x00, 0x5f,
- 0x81, 0x30, 0x01, 0x00, 0xdd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3,
- 0x94, 0x30, 0x01, 0x00, 0x5d, 0x8e, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
- 0xce, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x8f, 0x95, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
- 0x97, 0x8c, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xce, 0x8c, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
- 0x90, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00,
- 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc8, 0x8c, 0x22, 0x06,
- 0x90, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
- 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50,
- 0xe7, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00,
- 0xd5, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x89, 0x93, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd7, 0x8e, 0x42, 0x05,
- 0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0xc8, 0x8c, 0x1a, 0x5d, 0x69, 0x93, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
- 0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00,
- 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x6b, 0xfb,
- 0x84, 0xc8, 0x01, 0x00, 0xe4, 0x8e, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
- 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x12, 0xc8, 0x01, 0x00,
- 0xe7, 0x8e, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x8c, 0x93, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xea, 0x8e, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d,
- 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf3, 0x9e, 0x06, 0x00, 0x00, 0x11, 0x00, 0x63, 0xf3,
- 0x82, 0xcc, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x41, 0x80, 0x32, 0x00, 0x00,
- 0xbf, 0x8d, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xcd, 0x8d, 0x00, 0xf0,
- 0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xf7, 0x8e, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
- 0x13, 0xf0, 0x01, 0x00, 0xfc, 0x8e, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
- 0x27, 0x83, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xf6, 0x8e, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x75, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xfe, 0x8e, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
- 0xa3, 0x96, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0x08, 0x8f, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
- 0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0x05, 0x8f, 0x00, 0x50,
- 0x43, 0xc1, 0x00, 0x00, 0x14, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
- 0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0x12, 0x8f, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
- 0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0x1a, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
- 0x1e, 0x8f, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x62, 0xb1, 0x01, 0x00, 0x22, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x27, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x25, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
- 0x97, 0xb0, 0x01, 0x00, 0x2d, 0x8f, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
- 0x2d, 0x8f, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0x27, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x28, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x09, 0x97, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x34, 0x8f, 0x22, 0xf3,
- 0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
- 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x80, 0x97, 0x00, 0x52,
- 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0x80, 0x97, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00,
- 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0xff, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
- 0xc6, 0x8b, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00, 0x24, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x42, 0x8f, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
- 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
- 0x4e, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x4e, 0x8f, 0xa2, 0x16,
- 0x80, 0x32, 0x00, 0x00, 0xed, 0x87, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x09, 0x97, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x23, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00, 0x51, 0x8f, 0x83, 0x1e,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x2a, 0xc0, 0x01, 0x00, 0x58, 0x97, 0x00, 0x08,
- 0x80, 0x30, 0x01, 0x00, 0x55, 0x8f, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
- 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x98, 0x93, 0x00, 0x40,
- 0x8d, 0x30, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x5d, 0x8f, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x5a, 0x8f, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x61, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
- 0x69, 0x8f, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
- 0x6a, 0x8f, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
- 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
- 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
- 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x01, 0x14, 0x6c, 0x00, 0x00,
- 0xdc, 0x8f, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44,
- 0x19, 0x90, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x47, 0xe7, 0x7d, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x84, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x84, 0x8f, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x80, 0x8f, 0xa2, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
- 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
- 0x89, 0x30, 0x01, 0x00, 0x7d, 0x8f, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00,
- 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x09, 0x97, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x87, 0x8f, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x88, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc0, 0x8f, 0x22, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00,
- 0xc0, 0x8f, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x7e, 0x89, 0x01, 0x00,
- 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x44, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0x93, 0x8f, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x15,
- 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b, 0x99, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x0b,
- 0x99, 0x6c, 0x00, 0x00, 0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00,
- 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0,
- 0x22, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41,
- 0xe7, 0xe1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x0b, 0x00, 0x00, 0xf2, 0x98, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
- 0x99, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x00, 0x98, 0x6c, 0x00, 0x00,
- 0x20, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x11,
- 0x8a, 0x30, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00,
- 0x2f, 0x00, 0x20, 0x47, 0xe7, 0xb5, 0x01, 0x00, 0xab, 0x8f, 0x23, 0x0b,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xc1, 0x00, 0x00, 0x01,
- 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x02, 0xd0, 0x01, 0x00, 0x58, 0x97, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xb2, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x05,
- 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00,
- 0xbe, 0x8f, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
- 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x98, 0xd0, 0x01, 0x00,
- 0x58, 0x97, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40,
- 0x03, 0x98, 0x01, 0x00, 0xc8, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x15,
- 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01, 0xe4, 0xcd, 0x01, 0x00,
- 0xc1, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa4, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x20, 0x0b, 0xe5, 0x6d, 0x00, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x58, 0x97, 0x00, 0x00,
- 0x2a, 0x40, 0x01, 0x00, 0xcd, 0x8f, 0x22, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xce, 0x8f, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00, 0x98, 0x93, 0x00, 0x40,
- 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
- 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xd6, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xd3, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xfa, 0x96, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0xd9, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
- 0xdc, 0x8f, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
- 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0xb0, 0x01, 0x00, 0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00,
- 0x28, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0,
- 0x26, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x32, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00,
- 0xb8, 0x96, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x26, 0x90, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
- 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
- 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0xfa, 0x8f, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xfa, 0x8f, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xf6, 0x8f, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x14, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x1f, 0x90, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x0d, 0x90, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x54, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x1a, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x03, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x90, 0x22, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00,
- 0x0a, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0c, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40,
- 0x05, 0xb0, 0x00, 0x00, 0x6d, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x49, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x10, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x16, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x17, 0x90, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x19, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x1b, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x22, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x23, 0x90, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x25, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
- 0x14, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
- 0x2f, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x2b, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x33, 0x90, 0x22, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00,
- 0x34, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a, 0x84, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x3a, 0x90, 0x03, 0x1e, 0x80, 0x32, 0x00, 0x00, 0x3b, 0x90, 0x00, 0x41,
- 0x87, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x26, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x40, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x43, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x80, 0x01, 0x00, 0xc6, 0x8b, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
- 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0x4b, 0x90, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x2f, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x97, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0,
- 0x84, 0x30, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xcd, 0x8b, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x57, 0x90, 0x22, 0x40,
- 0xe7, 0x6d, 0x00, 0x00, 0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x62, 0x90, 0xa2, 0x40, 0xe5, 0x6d, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00,
- 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06,
- 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0,
- 0x80, 0x32, 0x00, 0x00, 0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
- 0xcd, 0x8b, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xec, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x97, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x70, 0x90, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
- 0x98, 0x50, 0x00, 0x00, 0x70, 0x90, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00,
- 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x6d, 0x90, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15,
- 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
- 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
- 0xe6, 0x8f, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0x80, 0x97, 0x00, 0x09,
- 0x80, 0x30, 0x01, 0x00, 0xe6, 0x8f, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0x26, 0x96, 0x00, 0xf0,
- 0x84, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0xc6, 0x8b, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x2c, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf3,
- 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0xc6, 0x8b, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00, 0x16, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x55, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x8a, 0x90, 0xa8, 0x40, 0x13, 0x30, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x90, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x8f, 0x90, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf0,
- 0x84, 0x30, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x26, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0xad, 0x90, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0xc6, 0x8b, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
- 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
- 0xe7, 0x91, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
- 0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xab, 0x90, 0x22, 0x47,
- 0xe7, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x17, 0x94, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0xab, 0x90, 0x22, 0x00,
- 0x80, 0x32, 0x00, 0x00, 0xa6, 0x90, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xab, 0x90, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0xf2,
- 0x02, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xac, 0x90, 0x00, 0x40,
- 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xb2, 0x90, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xb1, 0x90, 0xa2, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb2, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x51, 0x91, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xba, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xb7, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x51, 0x91, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xc1, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0xc1, 0x90, 0xa2, 0x16,
- 0x80, 0x32, 0x00, 0x00, 0x09, 0x97, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00,
- 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x96, 0xb0, 0x01, 0x00,
- 0xd2, 0x90, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x64, 0x00, 0x00, 0x4b, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xce, 0x90, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xd3, 0x90, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xd7, 0x90, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
- 0x13, 0xf0, 0x01, 0x00, 0xdc, 0x90, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
- 0x27, 0x83, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd6, 0x90, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
- 0x04, 0x00, 0x75, 0x09, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0xe4, 0x90, 0xa8, 0x40, 0xe1, 0x31, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
- 0x13, 0xf0, 0x01, 0x00, 0xe8, 0x90, 0x65, 0x05, 0x48, 0x31, 0x00, 0x00,
- 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xf0, 0x90, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0xee, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00,
- 0x2f, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x47,
- 0xe7, 0x7d, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0d, 0x91, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x48, 0x96, 0x00, 0x5f,
- 0x01, 0x10, 0x01, 0x00, 0xf4, 0x90, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xfe, 0x90, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x31, 0x03, 0x6c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xf4, 0x90, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0xf4, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x60, 0x97, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x4d,
- 0x97, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
- 0xe1, 0xb1, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07,
- 0x16, 0x88, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
- 0x19, 0x91, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0b,
- 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
- 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0b,
- 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
- 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00, 0x93, 0x04, 0x00, 0x5f,
- 0x95, 0x04, 0x01, 0x00, 0x70, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x27, 0x91, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x23, 0x91, 0x46, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x26, 0x91, 0xa2, 0x40, 0x31, 0x6f, 0x00, 0x00,
- 0x04, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
- 0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0f, 0xb0, 0x01, 0x00, 0xa5, 0x94, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
- 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x3a, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x3a, 0x91, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x32, 0x91, 0x37, 0x5c,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
- 0x37, 0x91, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x77, 0x7d, 0x00, 0x00, 0x33, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x37, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x74, 0x00, 0x22, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x55, 0x97, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x16, 0x96, 0x00, 0x5c,
- 0x1f, 0x10, 0x01, 0x00, 0xc1, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x4e, 0x91, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x17, 0x94, 0x00, 0x40,
- 0xe7, 0x31, 0x01, 0x00, 0x4e, 0x91, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00,
- 0x49, 0x91, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x4e, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2,
- 0x94, 0xb0, 0x01, 0x00, 0x9f, 0x95, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00,
- 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x55, 0x97, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x16, 0x96, 0x00, 0x5c,
- 0x1f, 0x10, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x55, 0x91, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47,
- 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x91, 0x01, 0x00,
- 0x80, 0x97, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x16, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0xc6, 0x8b, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xce, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x80, 0x97, 0x00, 0x45,
- 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x09, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x6d, 0x91, 0xa2, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x6d, 0x91, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00,
- 0x09, 0x97, 0x00, 0x47, 0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6,
- 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07,
- 0x84, 0x94, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
- 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00,
- 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
- 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
- 0x2c, 0x50, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0x9b, 0x97, 0x00, 0x06,
- 0x04, 0x30, 0x01, 0x00, 0x8a, 0x91, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00,
- 0x88, 0x91, 0x84, 0x48, 0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x8a, 0x91, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00, 0x98, 0x93, 0x00, 0x01,
- 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x10, 0xc0, 0x01, 0x00, 0x98, 0x91, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
- 0x73, 0x96, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0x83, 0x91, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x94, 0x91, 0xa8, 0x5c,
- 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x83, 0x91, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x1b, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x9e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xa4, 0x91, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0xa8, 0x91, 0x22, 0x44,
- 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00,
- 0xa8, 0x91, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00,
- 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0xb7, 0x91, 0x22, 0x4a,
- 0x1f, 0x7c, 0x00, 0x00, 0xaf, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0xb3, 0x91, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb4, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
- 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16,
- 0xe4, 0xb1, 0x00, 0x00, 0xcd, 0x91, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x2a, 0xb0, 0x01, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
- 0xbd, 0x91, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00, 0xce, 0x91, 0x22, 0x40,
- 0x2d, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00,
- 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xe0, 0xd1, 0x01, 0x00, 0x58, 0x97, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
- 0xc6, 0x91, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43,
- 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xc7, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07,
- 0x16, 0x14, 0x01, 0x00, 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
- 0x1a, 0x50, 0x00, 0x00, 0xdc, 0x91, 0x20, 0x16, 0x1a, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xd9, 0x91, 0xa8, 0x46,
- 0x1f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x16,
- 0x80, 0x32, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40,
- 0x23, 0xb0, 0x01, 0x00, 0xe6, 0x91, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00,
- 0xe7, 0x91, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x02, 0xb0, 0x01, 0x00, 0xb8, 0x96, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0xf0, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xec, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x92, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
- 0x05, 0x92, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0xf8, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x1b, 0x98, 0x01, 0x00, 0x05, 0x92, 0x00, 0x5c, 0x11, 0x80, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x5f, 0x1b, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x08,
- 0x98, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x98, 0xc0, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x0b, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0xa3, 0x43, 0x23, 0x6c, 0x00, 0x00, 0xe1, 0x94, 0x00, 0x40,
- 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x0b, 0x92, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1f, 0x90, 0x01, 0x00, 0x13, 0x92, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x13, 0x92, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x92, 0xa8, 0x46,
- 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
- 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x18, 0x92, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x1e, 0x92, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0x22, 0x92, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f,
- 0x81, 0x30, 0x01, 0x00, 0x22, 0x92, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
- 0x00, 0x8c, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x38, 0x92, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x29, 0x92, 0xa2, 0x16,
- 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
- 0x34, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x2d, 0x92, 0xa2, 0xf3,
- 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
- 0x85, 0xe0, 0x01, 0x00, 0x31, 0x92, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08,
- 0xe4, 0xf5, 0x01, 0x00, 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x35, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
- 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16,
- 0xe4, 0xb1, 0x00, 0x00, 0x3b, 0x92, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00,
- 0x4e, 0x92, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x91,
- 0x03, 0x6c, 0x00, 0x00, 0x48, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x41, 0x92, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
- 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0x45, 0x92, 0x22, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
- 0x58, 0x01, 0x2d, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0,
- 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x40,
- 0x11, 0x6c, 0x00, 0x00, 0x84, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0xa3, 0x91, 0x03, 0x6c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x41,
- 0x95, 0x30, 0x01, 0x00, 0x57, 0x92, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x57, 0x92, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x97, 0xb0, 0x01, 0x00, 0x55, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x94, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
- 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
- 0x16, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0x6a, 0x92, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x63, 0x92, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x22, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x84, 0xb0, 0x01, 0x00, 0x6d, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x80, 0xb0, 0x01, 0x00, 0x72, 0x92, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
- 0x58, 0x97, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00, 0x7b, 0x92, 0x22, 0x40,
- 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
- 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00, 0x78, 0x92, 0xa8, 0x11,
- 0xe0, 0x31, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x23, 0x6c, 0x00, 0x00,
- 0x8a, 0x92, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0x7e, 0x92, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x84, 0xd0, 0x01, 0x00, 0x83, 0x92, 0x22, 0x40,
- 0x1b, 0x6c, 0x00, 0x00, 0x79, 0x97, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00,
- 0x8a, 0x92, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x12, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1,
- 0x62, 0xdd, 0x01, 0x00, 0x88, 0x92, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x92, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x05,
- 0x48, 0x31, 0x01, 0x00, 0x92, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
- 0xff, 0x07, 0x00, 0x11, 0x00, 0x8c, 0x01, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x60, 0x97, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
- 0xfa, 0x96, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x8e, 0xb0, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0x0c, 0x47, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00,
- 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x20, 0x91,
- 0x03, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xa8, 0x92, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xa4, 0x92, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xaa, 0x92, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x1a, 0xd0, 0x01, 0x00, 0xb1, 0x92, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x25, 0x98, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00, 0xba, 0x92, 0x27, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0xbd, 0x91, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
- 0x25, 0x98, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0x80, 0xb2, 0x01, 0x00, 0xb5, 0x92, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x57, 0x92, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x97, 0xb0, 0x01, 0x00, 0xb8, 0x92, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc6, 0x8b, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0xbf, 0x92, 0x00, 0x4a,
- 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
- 0xf9, 0x94, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x9b, 0x97, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00, 0xcc, 0x92, 0xa2, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x02, 0xb0, 0x01, 0x00, 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0xd3, 0x92, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xcf, 0x92, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x10, 0xc0, 0x01, 0x00, 0xdc, 0x92, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
- 0x73, 0x96, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0xc5, 0x92, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xd8, 0x92, 0xa8, 0x5c,
- 0x1f, 0x00, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xc5, 0x92, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
- 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe1, 0x92, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xe7, 0x92, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xea, 0x92, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0x80, 0x97, 0x00, 0x4f,
- 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xf9, 0x92, 0x22, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
- 0xf1, 0x92, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x2d, 0x08,
- 0x2a, 0xb0, 0x01, 0x00, 0xf5, 0x92, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x36, 0x96, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf6, 0x92, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xff, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
- 0xe4, 0xb1, 0x01, 0x00, 0xc6, 0x8b, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
- 0xb8, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xcd, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
- 0xf9, 0x94, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x10,
- 0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x08, 0x93, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0b, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x9f, 0x95, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x0d, 0x93, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x09, 0x97, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0x80, 0x97, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00,
- 0xc6, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45,
- 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
- 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01,
- 0x2c, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x26, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x26, 0x93, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x1e, 0x93, 0x37, 0x5c,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
- 0x23, 0x93, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x77, 0x7d, 0x00, 0x00, 0x1f, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x23, 0x93, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00, 0x60, 0x01, 0x20, 0x16,
- 0xe0, 0xb1, 0x01, 0x00, 0xec, 0x95, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00,
- 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x97, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0xae, 0x94, 0x00, 0x47, 0x1f, 0x10, 0x01, 0x00,
- 0x3d, 0x93, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x3d, 0x93, 0xa2, 0x16,
- 0x80, 0x32, 0x00, 0x00, 0x39, 0x93, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x9f, 0x95, 0x00, 0x15,
- 0x94, 0x30, 0x01, 0x00, 0xa6, 0x95, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x96, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x09, 0x97, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xed, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
- 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4f,
- 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0xf9, 0x94, 0x00, 0x10,
- 0x32, 0x30, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
- 0xae, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x52, 0x93, 0xa2, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x52, 0x93, 0xa2, 0x16, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
- 0x4a, 0x93, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x62, 0xb1, 0x01, 0x00, 0x4f, 0x93, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x77, 0x7d, 0x00, 0x00, 0x4b, 0x93, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
- 0x4f, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xed, 0x87, 0x17, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x04, 0x00, 0x0c, 0x47, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x26, 0x96, 0x00, 0x41,
- 0x87, 0x30, 0x01, 0x00, 0x97, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x04, 0x00, 0xa0, 0x91, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x64, 0x93, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x60, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x84, 0x8f, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00,
- 0x80, 0x97, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00, 0x84, 0x8f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x4f, 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa0, 0x01,
- 0x14, 0x6c, 0x00, 0x00, 0xdc, 0x8f, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00, 0x72, 0x93, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
- 0x77, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x48,
- 0x1f, 0x7c, 0x00, 0x00, 0xec, 0x95, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
- 0x04, 0x00, 0xa3, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x97, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4f,
- 0x2b, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0xf9, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x91, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x46,
- 0xe7, 0x7d, 0x00, 0x00, 0x62, 0x90, 0x00, 0x45, 0x1f, 0x90, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x37, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x33, 0xc3, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
- 0x00, 0x00, 0xd2, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x86, 0x93, 0x85, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x48, 0x03, 0xd0, 0x00, 0x00,
- 0x88, 0x93, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x4c,
- 0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01, 0x34, 0xc3, 0x01, 0x00,
- 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xf0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12,
- 0xf0, 0xb1, 0x01, 0x00, 0xcb, 0x94, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x43, 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x95, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0xa5,
- 0x8a, 0x30, 0x01, 0x00, 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0xf0,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00,
- 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01,
- 0xe0, 0xc1, 0x01, 0x00, 0xa3, 0x93, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x2f, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xa5, 0x93, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0xce, 0x97, 0x00, 0x47,
- 0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
- 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x05, 0x98, 0x00, 0xf0,
- 0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xba, 0x93, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x0f, 0x94, 0xa2, 0x4c,
- 0x1f, 0x7c, 0x00, 0x00, 0xba, 0x93, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
- 0xbd, 0x93, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
- 0x8f, 0xb0, 0x01, 0x00, 0xb3, 0x93, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
- 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xb5, 0x93, 0x22, 0xf0,
- 0x3a, 0x6c, 0x00, 0x00, 0x0c, 0x94, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
- 0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x0d, 0x94, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xb9, 0x93, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xbc, 0x93, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0xc1, 0x93, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0xcc, 0x93, 0x23, 0xf0,
- 0x02, 0x6c, 0x00, 0x00, 0xb0, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00,
- 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xc9, 0x93, 0xa2, 0xf0,
- 0x80, 0x32, 0x00, 0x00, 0x0e, 0x94, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00,
- 0x0e, 0x94, 0xa2, 0x41, 0x03, 0x6c, 0x00, 0x00, 0xc8, 0x93, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x52, 0x8f, 0xb0, 0x01, 0x00, 0x0e, 0x94, 0x1f, 0x12,
- 0x84, 0x50, 0x00, 0x00, 0x0e, 0x94, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00,
- 0xba, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xf7, 0x93, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00,
- 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xe9, 0x93, 0x22, 0xf0,
- 0x14, 0x30, 0x00, 0x00, 0xd5, 0x93, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00,
- 0xe6, 0x93, 0x03, 0x1e, 0x80, 0x32, 0x00, 0x00, 0xd4, 0x93, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0xda, 0x93, 0x22, 0x0a,
- 0x02, 0x6c, 0x00, 0x00, 0xdd, 0x93, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xd9, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
- 0xdc, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x82, 0xd0, 0x01, 0x00, 0xe3, 0x93, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00,
- 0xe2, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0xe5, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0xe8, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0xf2, 0x93, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0xef, 0x93, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00,
- 0xef, 0x93, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
- 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
- 0xf1, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
- 0xef, 0x93, 0xa0, 0x91, 0x03, 0x6c, 0x00, 0x00, 0xed, 0x93, 0x22, 0x43,
- 0x3d, 0x7c, 0x00, 0x00, 0xf6, 0x93, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x28, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x94, 0xa2, 0xf0, 0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44,
- 0x8f, 0xb0, 0x01, 0x00, 0xfd, 0x93, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49,
- 0x8f, 0xb0, 0x01, 0x00, 0xef, 0x93, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xed, 0x93, 0x20, 0x91, 0x03, 0x6c, 0x00, 0x00, 0xef, 0x93, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x94, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00,
- 0x03, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
- 0x09, 0x94, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0xdd, 0x93, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x08, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56,
- 0x8f, 0xb0, 0x01, 0x00, 0x0b, 0x94, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
- 0x8f, 0xb0, 0x01, 0x00, 0x11, 0x94, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00,
- 0x11, 0x94, 0x00, 0x41, 0x95, 0xb0, 0x00, 0x00, 0x11, 0x94, 0x00, 0x42,
- 0x95, 0xb0, 0x00, 0x00, 0x11, 0x94, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00,
- 0x11, 0x94, 0x00, 0x4c, 0x95, 0xb0, 0x00, 0x00, 0x30, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x4a, 0x8a, 0x30, 0x01, 0x00,
- 0x55, 0x97, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x16, 0x94, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00, 0x1c, 0x94, 0xa2, 0xf3,
- 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00,
- 0x2d, 0x00, 0x2a, 0x41, 0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41,
- 0x85, 0xe0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00,
- 0x22, 0x94, 0x22, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1f, 0x90, 0x01, 0x00, 0x23, 0x94, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41,
- 0x85, 0xc0, 0x01, 0x00, 0x26, 0x94, 0xa0, 0xa5, 0x85, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x12, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0xa0, 0xa5,
- 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x78, 0x98, 0x00, 0xf0, 0x8c, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x3b, 0x94, 0x22, 0x40,
- 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf0,
- 0x98, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x98, 0x6c, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x0c, 0x98, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
- 0x98, 0x6c, 0x00, 0x00, 0x38, 0x94, 0xa2, 0x4b, 0x19, 0x7c, 0x00, 0x00,
- 0x39, 0x94, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x60, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x3d, 0x95, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
- 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x3d, 0x94, 0x22, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0xa5, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
- 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5f,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0xf0, 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
- 0x96, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c, 0x96, 0xf4, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00, 0x3d, 0x95, 0x00, 0x07,
- 0x10, 0x30, 0x01, 0x00, 0x2f, 0x83, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x5f, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x0f, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x96, 0xf4, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c,
- 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00,
- 0x3d, 0x95, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0x54, 0x94, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x57, 0x94, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x69, 0x94, 0x13, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
- 0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f,
- 0x5f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5e, 0x5f, 0x7c, 0x00, 0x00,
- 0x1f, 0x00, 0x00, 0x0f, 0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
- 0x5f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x5f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x4e, 0xb0, 0x01, 0x00, 0x19, 0x85, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x44, 0x5f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00, 0x66, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x40, 0x05, 0x6c, 0x00, 0x00, 0x15, 0x99, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x6c, 0x94, 0x60, 0x07, 0x96, 0x30, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x70, 0xc2,
- 0x24, 0xb0, 0x01, 0x00, 0x79, 0x94, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
- 0x70, 0x94, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x7a, 0x94, 0x22, 0x12,
- 0x48, 0x7f, 0x00, 0x00, 0x58, 0x04, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x1e, 0x94, 0x01, 0x00, 0x17, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x12, 0x8a, 0xb0, 0x01, 0x00, 0x02, 0x99, 0x00, 0x5f,
- 0x8b, 0x10, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
- 0x79, 0x94, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
- 0x24, 0xb0, 0x01, 0x00, 0x7a, 0x94, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
- 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x17, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x12, 0x8a, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x89, 0x94, 0x0b, 0xf0,
- 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00,
- 0x86, 0x94, 0x22, 0x50, 0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xae, 0x96, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00,
- 0x93, 0x04, 0x00, 0x12, 0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a,
- 0x1f, 0x90, 0x01, 0x00, 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42,
- 0x10, 0xf4, 0x01, 0x00, 0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
- 0x8a, 0x88, 0x01, 0x00, 0x8d, 0x94, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
- 0x90, 0x94, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x7a, 0x94, 0x10, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xae, 0x96, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0xd8, 0x00, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x9c, 0x94, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
- 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa7,
- 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xa0, 0x94, 0xa8, 0x05,
- 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
- 0x1e, 0x94, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x0f, 0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42,
- 0x84, 0x88, 0x01, 0x00, 0xaa, 0x94, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0xab, 0x94, 0x00, 0x42, 0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x6a, 0xb1, 0x01, 0x00, 0xab, 0x94, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x42, 0x48, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
- 0x48, 0x93, 0x01, 0x00, 0xae, 0x94, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xb4, 0x94, 0x28, 0xb1,
- 0x2c, 0x30, 0x00, 0x00, 0xaf, 0x94, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x95, 0x40,
- 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xb4, 0x94, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xbf, 0x94, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
- 0xb9, 0x94, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x15, 0x00, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x5c,
- 0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x5a, 0x11, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x08, 0x48, 0x06, 0x00, 0x00, 0x00, 0x00, 0x80, 0x24,
- 0x11, 0x84, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x5a, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x00,
- 0x48, 0x06, 0x00, 0x00, 0x04, 0x00, 0x1f, 0xbb, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc8, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xcc, 0x94, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xd4, 0x94, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x90, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x49,
- 0x80, 0x32, 0x00, 0x00, 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00,
- 0x20, 0x00, 0x92, 0x48, 0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xd8, 0x94, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00,
- 0xd4, 0x94, 0x22, 0x4c, 0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40,
- 0x91, 0xb0, 0x00, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xd8, 0x94, 0xa8, 0xb1, 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x80, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x27, 0x48, 0x80, 0x32, 0x00, 0x00,
- 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x92, 0x49,
- 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x83, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x00, 0xec, 0x00, 0x00,
- 0xea, 0x94, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x00,
- 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x49, 0xc1, 0x01, 0x00,
- 0xe4, 0x94, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x83, 0x7c, 0x00, 0x00, 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5c, 0x01, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x41, 0x00, 0xec, 0x00, 0x00,
- 0xf6, 0x94, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x00,
- 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x49, 0xc1, 0x01, 0x00,
- 0xf0, 0x94, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xfb, 0x94, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00, 0x24, 0x00, 0x2d, 0x01,
- 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00,
- 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x2f, 0xf2,
- 0x0c, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0xf0, 0x14, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x20, 0x01, 0x14, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x60, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x95, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x0b, 0xe8, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
- 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
- 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x16, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x60, 0x17, 0x3d, 0x43,
- 0x9d, 0xe0, 0x01, 0x00, 0x10, 0x00, 0x80, 0xa1, 0x16, 0xe4, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x07, 0x16, 0x6c, 0x00, 0x00, 0x1a, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0b, 0x8a, 0xe4, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0x0d, 0x8a, 0x14, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x17, 0x95, 0x30, 0x47, 0x17, 0x04, 0x00, 0x00,
- 0x1a, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x90, 0x42,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
- 0x1e, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x1f, 0x95, 0x40, 0x07,
- 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x29, 0x95, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00, 0x01, 0x97, 0x3f, 0x41,
- 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
- 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
- 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00, 0x3c, 0x95, 0x00, 0x3b,
- 0xe7, 0xb1, 0x00, 0x00, 0x29, 0x95, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x33, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x46, 0xc9, 0x01, 0x00, 0x2f, 0x95, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x42,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41, 0x81, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10, 0x4a,
- 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41, 0x95, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07, 0x92, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x11, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
- 0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x41,
- 0xe6, 0x7d, 0x00, 0x00, 0x44, 0x95, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00,
- 0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x52, 0x95, 0x22, 0x45,
- 0x95, 0x7c, 0x00, 0x00, 0x4d, 0x95, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x0f, 0x96, 0xf4, 0x01, 0x00, 0x49, 0x95, 0x31, 0x5f,
- 0x97, 0x04, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x4b, 0x48, 0x7f, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x6a, 0xb1, 0x01, 0x00, 0x4d, 0x95, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
- 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
- 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
- 0x88, 0xb0, 0x01, 0x00, 0x5b, 0x95, 0xa2, 0x3b, 0x89, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
- 0x92, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4a, 0x44, 0x7f, 0x00, 0x00,
- 0x5c, 0x95, 0x18, 0x4a, 0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x3f, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x16, 0x00, 0x00, 0x12, 0x8a, 0xe4, 0x01, 0x00, 0x02, 0x99, 0x00, 0x4b,
- 0x8a, 0x14, 0x01, 0x00, 0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5f, 0x5f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5e,
- 0x5f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x2f, 0x7e, 0xd9, 0x01, 0x00,
- 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x68, 0x95, 0x22, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x6a, 0x95, 0x00, 0x05,
- 0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
- 0x5f, 0x90, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x08, 0x4e, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x6d, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x33, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x07, 0x8a, 0x30, 0x01, 0x00,
- 0x72, 0x95, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x76, 0x95, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4a,
- 0x44, 0x7f, 0x00, 0x00, 0x9b, 0x04, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00,
- 0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45,
- 0x97, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5f, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x5e, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x20, 0xaa,
- 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x82, 0x95, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x78, 0x95, 0xa2, 0x3b, 0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45,
- 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x08, 0x80, 0x32, 0x00, 0x00, 0x03, 0x00, 0x00, 0x08,
- 0x94, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x4a, 0x46, 0xc9, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x08, 0x96, 0x88, 0x01, 0x00, 0x04, 0x00, 0x22, 0x4b,
- 0xe6, 0x7d, 0x00, 0x00, 0x93, 0x04, 0x00, 0x12, 0x94, 0x30, 0x01, 0x00,
- 0x3d, 0x95, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a,
- 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a, 0xe6, 0xc9, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x4a, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0x24, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
- 0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
- 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
- 0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf2,
- 0x02, 0x30, 0x00, 0x00, 0x17, 0x94, 0x00, 0x10, 0x32, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
- 0xa3, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x36, 0xb0, 0x01, 0x00, 0xb4, 0x95, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0xac, 0x95, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x00, 0xb0, 0x01, 0x00, 0xa7, 0x95, 0x00, 0x5c, 0x01, 0x80, 0x00, 0x00,
- 0xc3, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x46, 0xc9, 0x01, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xe2, 0x95, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x68, 0x08,
- 0x38, 0x96, 0x01, 0x00, 0x3a, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
- 0x82, 0xcc, 0x01, 0x00, 0xb9, 0x95, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x11, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa3, 0x48, 0x3b, 0x6c, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00, 0xe0, 0x95, 0x26, 0x46,
- 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x12, 0xc8, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x98, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x4c,
- 0x42, 0x6d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00, 0xdf, 0x95, 0x22, 0x41,
- 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x22, 0x44,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0xd1, 0x95, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00, 0xde, 0x95, 0x22, 0x41,
- 0x05, 0x50, 0x00, 0x00, 0xdc, 0x95, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xd7, 0x95, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x13, 0xc0, 0x01, 0x00, 0xcc, 0x95, 0x00, 0x50, 0x49, 0xc1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
- 0x1a, 0xc8, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xe0, 0x95, 0x22, 0x40,
- 0x3b, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00,
- 0xc3, 0x94, 0x00, 0x5c, 0x01, 0x00, 0x01, 0x00, 0xe2, 0x95, 0x00, 0x41,
- 0x3b, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00,
- 0xb0, 0x00, 0x2f, 0x5f, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0,
- 0x8c, 0xc0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0xa3, 0xf0, 0x8c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x8c, 0xb0, 0x01, 0x00, 0xf1, 0x95, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
- 0x14, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8,
- 0x0c, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b,
- 0xe0, 0xb1, 0x01, 0x00, 0xfe, 0x95, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x96, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
- 0x18, 0x00, 0x20, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b,
- 0xe0, 0xb1, 0x01, 0x00, 0xe6, 0x95, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
- 0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x05, 0x96, 0xa2, 0xa5,
- 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
- 0x08, 0x96, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
- 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
- 0x0d, 0x96, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
- 0x12, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
- 0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
- 0x13, 0x96, 0x00, 0x40, 0x1f, 0x80, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00,
- 0xe4, 0xf5, 0x01, 0x00, 0x1e, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0xe1, 0x6d, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d,
- 0x05, 0x90, 0x00, 0x00, 0x23, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
- 0x33, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x82, 0x0c, 0x80, 0x32, 0x00, 0x00,
- 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
- 0x84, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00,
- 0x3d, 0x96, 0x9f, 0x41, 0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5,
- 0x85, 0xcc, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x42, 0xe6, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0xa3, 0xa5, 0x97, 0x6c, 0x00, 0x00, 0xd4, 0x00, 0x3d, 0x41,
- 0x85, 0xe0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0xf2, 0x98, 0xe4, 0x01, 0x00,
- 0x44, 0x96, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x5a,
- 0x99, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x99, 0x80, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x00, 0x98, 0x6c, 0x00, 0x00, 0x20, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x21, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x00, 0x8a, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x00, 0x6a, 0x06, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x00,
- 0x80, 0xb0, 0x01, 0x00, 0x4f, 0x96, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0x50, 0x96, 0x00, 0x41,
- 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
- 0x51, 0x96, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x56, 0x96, 0xa2, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0x6b, 0x96, 0x9c, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x60, 0x96, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
- 0x98, 0xf4, 0x01, 0x00, 0x5f, 0x96, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0x5f, 0x96, 0xa2, 0x8a,
- 0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
- 0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x6a, 0x96, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
- 0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
- 0x3a, 0xe0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x0c, 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07,
- 0x96, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
- 0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
- 0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0x7a, 0x96, 0x22, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x84, 0x96, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x95,
- 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
- 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x8f, 0x96, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x90, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x10, 0x62, 0xc9, 0x01, 0x00, 0x92, 0x96, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x95, 0x03, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x9d, 0x96, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9e, 0x96, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0xa0, 0x96, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46,
- 0x0d, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x09, 0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00,
- 0xaa, 0x96, 0x63, 0x42, 0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a,
- 0x62, 0xc9, 0x01, 0x00, 0xab, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0xf3, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42,
- 0x97, 0xf0, 0x01, 0x00, 0xaf, 0x96, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xb7, 0x96, 0x22, 0xf3, 0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
- 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00,
- 0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb4, 0x96, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00,
- 0xc7, 0x96, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0xbc, 0x96, 0xa2, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
- 0x20, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xc2, 0x96, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xbf, 0x96, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x32, 0xb0, 0x01, 0x00, 0xc7, 0x96, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xe1, 0x94, 0x00, 0x43, 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xb0, 0x01, 0x00, 0xc9, 0x96, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00,
- 0xca, 0x96, 0x00, 0x06, 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x04, 0xb0, 0x01, 0x00, 0xcc, 0x96, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x04, 0xb0, 0x01, 0x00, 0x9b, 0x97, 0x00, 0x05,
- 0x48, 0x31, 0x01, 0x00, 0xf7, 0x96, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
- 0xd0, 0x96, 0xa2, 0x02, 0x2a, 0x50, 0x00, 0x00, 0xf7, 0x96, 0xa2, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0xd2, 0x96, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00,
- 0xdb, 0x96, 0x00, 0x02, 0x16, 0xc0, 0x00, 0x00, 0xda, 0x96, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xda, 0x96, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xd6, 0x96, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x73, 0x96, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0xf7, 0x96, 0x22, 0x15,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0xf6, 0x96, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00, 0xe7, 0x96, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0xe7, 0x96, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe3, 0x96, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x23, 0x83, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x80, 0x32, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0x2f, 0x00, 0x2f, 0x5c,
- 0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
- 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0xb9, 0x96, 0x20, 0x15,
- 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0xf3, 0x96, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0xb9, 0x96, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0xb9, 0x96, 0x00, 0x02,
- 0x10, 0xc0, 0x00, 0x00, 0xf9, 0x96, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0x98, 0x93, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0x01, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40,
- 0x27, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xb0, 0x01, 0x00,
- 0xc3, 0x94, 0x00, 0x41, 0xa3, 0x41, 0x01, 0x00, 0x05, 0x97, 0x00, 0x41,
- 0x27, 0xd0, 0x00, 0x00, 0x36, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x14, 0xbb, 0x80, 0x32, 0x00, 0x00, 0x0e, 0x97, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x64, 0x97, 0x00, 0x40, 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06,
- 0x16, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00,
- 0x18, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x6c, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40,
- 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00,
- 0x21, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43,
- 0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00,
- 0x21, 0x97, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x44, 0x97, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00,
- 0x2f, 0x97, 0xa2, 0x06, 0x14, 0x6c, 0x00, 0x00, 0x2c, 0x97, 0x22, 0x48,
- 0x19, 0x7c, 0x00, 0x00, 0x26, 0x97, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x31, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00,
- 0x8b, 0x00, 0x2d, 0x48, 0x19, 0x80, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x45,
- 0xe7, 0x7d, 0x00, 0x00, 0x8b, 0x00, 0x20, 0x45, 0xe7, 0x91, 0x01, 0x00,
- 0x2f, 0x97, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00, 0x08, 0x00, 0x00, 0x43,
- 0x86, 0x98, 0x01, 0x00, 0x2f, 0x97, 0xa0, 0x48, 0x17, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
- 0xa8, 0x97, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0x3a, 0x97, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
- 0x39, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x3e, 0x97, 0x64, 0xf0, 0x82, 0xb0, 0x00, 0x00,
- 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x3e, 0x97, 0xa2, 0xf2,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe5, 0xb1, 0x01, 0x00,
- 0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06, 0x30, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49,
- 0x19, 0x7c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0x46, 0x19, 0x90, 0x01, 0x00,
- 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
- 0xa8, 0x97, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x4a,
- 0x19, 0xfc, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
- 0x17, 0xc0, 0x01, 0x00, 0x4d, 0x97, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xe4, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x1b,
- 0xe0, 0xb1, 0x00, 0x00, 0x52, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0xf0, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x4c,
- 0x95, 0x60, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4a, 0x18, 0x94, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01,
- 0xf0, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00, 0x5d, 0x97, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x5f, 0x17, 0x90, 0x01, 0x00,
- 0x70, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x7a, 0x01, 0x2e, 0xfe,
- 0x92, 0xb0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0xf6, 0x16, 0xb0, 0x01, 0x00,
- 0x6a, 0x97, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x45, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6, 0x2a, 0xb0, 0x01, 0x00,
- 0x28, 0x00, 0x6e, 0x06, 0x82, 0xc8, 0x01, 0x00, 0x6e, 0x97, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x45, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x6e, 0x4c, 0x83, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x92, 0xc0, 0x01, 0x00, 0x6f, 0x97, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00,
- 0x00, 0x00, 0x66, 0x9e, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41,
- 0x3d, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00,
- 0x06, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x49,
- 0x98, 0xf4, 0x01, 0x00, 0x78, 0x97, 0x26, 0x30, 0x93, 0x04, 0x00, 0x00,
- 0x78, 0x97, 0x90, 0x4c, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x93, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x80, 0x49, 0xec, 0xa9, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x01,
- 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00,
- 0x7d, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x20,
- 0x81, 0x6c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40, 0x81, 0x6c, 0x00, 0x00,
- 0x8f, 0x97, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00, 0x8c, 0x97, 0xa2, 0x40,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x97, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x8c, 0x97, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
- 0x88, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x25, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00, 0x92, 0x97, 0xa2, 0x5f,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43, 0x19, 0x7c, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00, 0x25, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40, 0x8a, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00,
- 0x97, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x22, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0xa0, 0x97, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0xb4, 0x05, 0x00, 0x02,
- 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02,
- 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x13, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x08, 0xe0, 0xb1, 0x00, 0x00, 0xa5, 0x97, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0xb0, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00, 0x04, 0x00, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0xf0, 0x98, 0xf4, 0x01, 0x00, 0xb1, 0x97, 0x20, 0x4c,
- 0x84, 0x6c, 0x00, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xb1, 0x97, 0x20, 0xf2, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14,
- 0x98, 0xd0, 0x01, 0x00, 0xb6, 0x97, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x84, 0xb0, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x30,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x80, 0xe0, 0x01, 0x00,
- 0xba, 0x97, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14, 0xe0, 0xb1, 0x01, 0x00,
- 0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xf3,
- 0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42, 0x82, 0xc0, 0x00, 0x00,
- 0xc0, 0x97, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x82, 0xec, 0x00, 0x00,
- 0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x37, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00,
- 0x02, 0x99, 0x00, 0x05, 0x8a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcb, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x1c,
- 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x8a, 0xd0, 0x00, 0x00,
- 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00, 0xd9, 0x97, 0x9c, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0xbe, 0x00, 0x2f, 0xab, 0x83, 0xb0, 0x01, 0x00, 0x35, 0x98, 0x00, 0x14,
- 0x82, 0x50, 0x01, 0x00, 0xde, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xde, 0x97, 0x22, 0xf2, 0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xde, 0x97, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
- 0xbe, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x35, 0x98, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x9c, 0x00, 0x2d, 0x30, 0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0,
- 0x84, 0xb0, 0x01, 0x00, 0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00,
- 0xf2, 0x97, 0x23, 0xf0, 0x84, 0x6c, 0x00, 0x00, 0xe6, 0x97, 0x23, 0x92,
- 0x87, 0x6c, 0x00, 0x00, 0xc9, 0x04, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00,
- 0xe8, 0x97, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x94, 0xb0, 0x01, 0x00, 0x60, 0x89, 0x00, 0x4a, 0x94, 0x98, 0x01, 0x00,
- 0xe8, 0x97, 0x68, 0x40, 0x81, 0x32, 0x00, 0x00, 0x04, 0x00, 0x22, 0x40,
- 0xbd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xb0, 0xb1, 0x01, 0x00,
- 0xbf, 0x00, 0x2d, 0x42, 0xb2, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
- 0x80, 0xe0, 0x01, 0x00, 0xed, 0x97, 0xd4, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0xda, 0x84, 0xc0, 0x01, 0x00, 0xf7, 0x97, 0x23, 0x40,
- 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00,
- 0xf7, 0x97, 0x00, 0x40, 0x84, 0xb0, 0x00, 0x00, 0xbf, 0x00, 0x2d, 0x43,
- 0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3, 0x80, 0xe0, 0x01, 0x00,
- 0xf7, 0x97, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00,
- 0xfb, 0x97, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00, 0x9c, 0x00, 0x20, 0x42,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x42,
- 0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
- 0x82, 0x88, 0x01, 0x00, 0x01, 0x98, 0x23, 0x41, 0x80, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x89, 0x0c,
- 0x80, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x86, 0x0c, 0x80, 0x32, 0x00, 0x00,
- 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x41, 0x24, 0xec, 0x00, 0x00,
- 0x0d, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x42,
- 0x38, 0xec, 0x00, 0x00, 0x0d, 0x98, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x0f, 0x98, 0xa3, 0xf0,
- 0x3a, 0x6c, 0x00, 0x00, 0x04, 0x00, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x13, 0x98, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0xb4, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f,
- 0x13, 0x94, 0x01, 0x00, 0x13, 0x98, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0x80, 0x00, 0x20, 0x1d, 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12,
- 0xe0, 0xb1, 0x01, 0x00, 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x27, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x42,
- 0x8a, 0x30, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xe0, 0xb1, 0x01, 0x00, 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x1f, 0x98, 0x9f, 0x41, 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00,
- 0x20, 0x98, 0x00, 0x41, 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x78, 0x98, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x22, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0xa7, 0x08, 0x80, 0x32, 0x01, 0x00, 0x32, 0x04, 0x00, 0x40,
- 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08, 0x8a, 0x30, 0x01, 0x00,
- 0x2c, 0x98, 0xa2, 0x40, 0x95, 0x6c, 0x00, 0x00, 0xc3, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00,
- 0xa0, 0x98, 0x2f, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41,
- 0x89, 0xb0, 0x00, 0x00, 0xcc, 0x00, 0x00, 0xa1, 0x80, 0xce, 0x01, 0x00,
- 0x04, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0xf8,
- 0x3e, 0xec, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x12, 0xe0, 0xed, 0x00, 0x00,
- 0xc8, 0x00, 0x20, 0xab, 0xe1, 0xb1, 0x01, 0x00, 0xcc, 0x00, 0xa0, 0x1f,
- 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00,
- 0x38, 0x98, 0xa3, 0x5f, 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe7, 0xc1, 0x01, 0x00, 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x4c, 0x98, 0x22, 0xf2, 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43,
- 0x84, 0xf4, 0x01, 0x00, 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00,
- 0xb8, 0x00, 0x2d, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
- 0x86, 0xc0, 0x01, 0x00, 0x40, 0x98, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00,
- 0x41, 0x98, 0xa2, 0x40, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41,
- 0x87, 0xb0, 0x01, 0x00, 0x45, 0x98, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x84, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44,
- 0x84, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x62, 0x40, 0x88, 0xc0, 0x01, 0x00, 0x4b, 0x98, 0x1f, 0x44,
- 0x80, 0x32, 0x00, 0x00, 0x4f, 0x98, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00,
- 0x4f, 0x98, 0x62, 0x41, 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41,
- 0x86, 0xe4, 0x01, 0x00, 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x62, 0x41, 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xbc, 0x00, 0x2e, 0x43, 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x86, 0xc0, 0x01, 0x00, 0x55, 0x98, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x43, 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43,
- 0x80, 0xce, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00,
- 0x40, 0x01, 0xe2, 0x40, 0x87, 0x98, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x05,
- 0x48, 0x6d, 0x00, 0x00, 0x04, 0x00, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00,
- 0x88, 0x00, 0x2d, 0x44, 0x81, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf2,
- 0x2e, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0xf0, 0x86, 0xb0, 0x01, 0x00,
- 0x90, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0xba, 0x00, 0x2d, 0xf0,
- 0x98, 0xb0, 0x01, 0x00, 0x64, 0x98, 0xa2, 0x12, 0x98, 0x6c, 0x00, 0x00,
- 0xbc, 0x00, 0x2d, 0xf2, 0x98, 0xb0, 0x01, 0x00, 0x64, 0x98, 0xa0, 0xf2,
- 0x98, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x82, 0xb0, 0x01, 0x00,
- 0x9c, 0x00, 0x20, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x2d, 0x12,
- 0x86, 0xd0, 0x01, 0x00, 0x67, 0x98, 0xa3, 0x41, 0xe0, 0x6d, 0x00, 0x00,
- 0x68, 0x98, 0x00, 0xf0, 0x84, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x84, 0xb0, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x43, 0x84, 0xd0, 0x01, 0x00,
- 0x6b, 0x98, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x6d, 0x98, 0xa3, 0x42, 0x14, 0x6c, 0x00, 0x00,
- 0x6e, 0x98, 0x00, 0x0a, 0x0c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x0c, 0xb0, 0x01, 0x00, 0x70, 0x98, 0xa0, 0x17, 0x0c, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x17, 0x0c, 0xb0, 0x01, 0x00, 0x75, 0x98, 0x22, 0x40,
- 0x0d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a, 0x0c, 0xec, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0xf0, 0x82, 0xf4, 0x01, 0x00, 0x75, 0x98, 0xa0, 0x41,
- 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf0, 0x80, 0x32, 0x01, 0x00,
- 0x29, 0x00, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0xcb, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x00, 0x22, 0x03,
- 0x80, 0x32, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41, 0x87, 0x94, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d,
- 0x05, 0x90, 0x00, 0x00, 0x84, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0xa2, 0x05, 0x48, 0x6d, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0c,
- 0x96, 0xf4, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x07, 0x96, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00, 0x05, 0x00, 0x2a, 0x0c,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04, 0xe6, 0xb1, 0x01, 0x00,
- 0x3e, 0x04, 0x00, 0x40, 0x89, 0x98, 0x01, 0x00, 0x02, 0x99, 0x00, 0x08,
- 0x8a, 0x30, 0x01, 0x00, 0x8f, 0x98, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x95, 0x98, 0x28, 0x40,
- 0x87, 0x30, 0x00, 0x00, 0x90, 0x98, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x04, 0x97, 0x1d, 0x46,
- 0x87, 0xb0, 0x00, 0x00, 0x98, 0x98, 0x22, 0x5f, 0x11, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00, 0x96, 0x98, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x14, 0x2f, 0x4c,
- 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x9b, 0x98, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0xb0, 0x01, 0x00,
- 0xef, 0x98, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00, 0x07, 0x00, 0x00, 0x49,
- 0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03, 0x06, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xd0,
- 0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00,
- 0xa2, 0x98, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x05,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa2,
- 0x44, 0xc9, 0x01, 0x00, 0xab, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00, 0xf5, 0x98, 0x00, 0x40,
- 0x49, 0x31, 0x01, 0x00, 0x02, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xb2, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x97, 0x2e, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0xb6, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xba, 0x98, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0xba, 0x94, 0x20, 0x41,
- 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xc4, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x68, 0xb1, 0x01, 0x00,
- 0xc8, 0x98, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x80, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x39, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x33, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x3f, 0xb3, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40, 0x25, 0x9b, 0x01, 0x00,
- 0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2d, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40, 0x2b, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5, 0x3c, 0x8b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c,
- 0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x59, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x53, 0xb3, 0x01, 0x00,
- 0xe4, 0x98, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xe4, 0x98, 0xa2, 0x51,
- 0xfd, 0x7f, 0x00, 0x00, 0xe5, 0x98, 0x00, 0x40, 0x1d, 0xb3, 0x00, 0x00,
- 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6,
- 0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6, 0x3a, 0xb3, 0x01, 0x00,
- 0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00, 0xb4, 0x05, 0x00, 0x40,
- 0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x4d, 0xb3, 0x01, 0x00,
- 0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00, 0x01, 0x01, 0x00, 0x8a,
- 0x15, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x87, 0xb3, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5e,
- 0x57, 0xb5, 0x01, 0x00, 0x18, 0x00, 0x00, 0x4b, 0x20, 0xe4, 0x01, 0x00,
- 0x06, 0x00, 0x00, 0x4b, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x43, 0x00, 0x4b,
- 0x96, 0xc8, 0x01, 0x00, 0x18, 0x00, 0x00, 0x10, 0x20, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x20, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x57,
- 0x21, 0x90, 0x01, 0x00, 0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xf6, 0x98, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x00, 0xa9, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xfa, 0x98, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0xfe, 0x98, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xfe, 0x98, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x99, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x88, 0x94, 0x01, 0x00,
- 0x08, 0x99, 0x6a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x0b, 0x99, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x62, 0xb1, 0x01, 0x00, 0x0c, 0x99, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x13, 0x99, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0x11, 0x99, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0x11, 0x99, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f, 0x98, 0xf4, 0x01, 0x00,
- 0x04, 0x00, 0xa2, 0x5f, 0x99, 0x04, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
- 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
- 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
- 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x41, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xb2, 0x9f, 0x22, 0x40, 0x7b, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
- 0xc6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00,
- 0x08, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xa8, 0x9f, 0x00, 0x4d,
- 0x9a, 0xcc, 0x01, 0x00, 0xbb, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0xb9, 0x9f, 0xa2, 0x41,
- 0x9b, 0x50, 0x00, 0x00, 0xbf, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x52, 0x49, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x51, 0x4a, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x50, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
- 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0,
- 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00,
- 0xca, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x10, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe3, 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4,
- 0x45, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x48, 0x4f, 0x40, 0xb1, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
- 0x81, 0xc8, 0x01, 0x00, 0x22, 0x83, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
- 0x55, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x22, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x43, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x41, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xed, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x23, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x27, 0x83, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb9, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x8d, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x79, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x78, 0x98, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x87, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x95, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x0a, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb1, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x19, 0x99, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00,
- },
-};
diff --git a/drivers/staging/slicoss/oasisdownload.h b/drivers/staging/slicoss/oasisdownload.h
deleted file mode 100644
index 6438c23d754..00000000000
--- a/drivers/staging/slicoss/oasisdownload.h
+++ /dev/null
@@ -1,6848 +0,0 @@
-#define OASIS_UCODE_VERS_STRING "1.2"
-#define OASIS_UCODE_VERS_DATE "2006/03/27 15:10:37"
-#define OASIS_UCODE_HOSTIF_ID 3
-
-static s32 ONumSections = 0x2;
-static u32 OSectionSize[] = {
- 0x00004000, 0x00010000,
-};
-
-static u32 OSectionStart[] = {
- 0x00000000, 0x00008000,
-};
-
-static u8 OasisUCode[2][65536] =
-{
- {
- 0x15, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x98, 0xb0, 0x01, 0x00, 0x04, 0x80, 0xa2, 0x40, 0xfd, 0x7f, 0x00, 0x00,
- 0x09, 0x00, 0xa2, 0x49, 0xdd, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x80, 0xb2, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x80, 0xb2, 0x01, 0x00, 0x09, 0x00, 0xa2, 0x40,
- 0x75, 0x7d, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x0b, 0x00, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x8f, 0x98, 0x18, 0x31, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x41, 0x98,
- 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x98, 0x80, 0xe4, 0x01, 0x00, 0x0e, 0x00, 0x40, 0x98,
- 0x80, 0x94, 0x00, 0x00, 0x11, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x19, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x19, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x0e, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x1f, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x12, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x50, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0xa5, 0x99, 0x01, 0x00, 0x25, 0x00, 0x29, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x25, 0x00, 0x14, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x14, 0x00, 0x93, 0xbc, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xdd, 0x81, 0x01, 0x00, 0x12, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x33, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x00, 0x14, 0xbc,
- 0x80, 0x32, 0x00, 0x00, 0xfe, 0x00, 0x13, 0xbc, 0x80, 0x32, 0x00, 0x00,
- 0x54, 0x95, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xfd, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xff, 0xb3, 0x01, 0x00,
- 0x33, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x89, 0xb0, 0x01, 0x00, 0x32, 0x00, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00,
- 0x99, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x20, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xe0, 0xb3, 0x01, 0x00, 0x39, 0x00, 0x98, 0xee,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x80, 0xb0, 0x01, 0x00,
- 0x3b, 0x00, 0x80, 0xf3, 0xde, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0xfd, 0x93, 0x01, 0x00, 0x3e, 0x00, 0x83, 0xf3, 0x80, 0x32, 0x00, 0x00,
- 0xf0, 0x00, 0x00, 0xf3, 0x80, 0x88, 0x01, 0x00, 0x01, 0x80, 0x00, 0x40,
- 0x2e, 0xdd, 0x01, 0x00, 0x00, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x43, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0x24, 0xb1, 0x01, 0x00, 0x7c, 0x00, 0x18, 0xee, 0x80, 0x32, 0x00, 0x00,
- 0x45, 0x00, 0x95, 0xe8, 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0xe8,
- 0x80, 0x88, 0x01, 0x00, 0x7c, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8, 0xee, 0x8b, 0x01, 0x00,
- 0x08, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf0,
- 0x80, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x81, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0xf8,
- 0x80, 0x88, 0x01, 0x00, 0x3c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xf0, 0xd6, 0x8d, 0x01, 0x00, 0xff, 0xff, 0x00, 0xf0,
- 0xf0, 0xdb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00, 0x3c, 0x01, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xf8, 0x80, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x81, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x81, 0x94, 0x01, 0x00,
- 0x3c, 0x02, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xd6, 0xb1, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0xd6, 0xb1, 0x01, 0x00, 0x1e, 0x00, 0x00, 0xf0,
- 0x82, 0xf4, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xf8, 0x80, 0xd8, 0x01, 0x00,
- 0x64, 0x00, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x81, 0xd0, 0x01, 0x00, 0xff, 0xff, 0x00, 0x40, 0x80, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x80, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xd8, 0xb1, 0x01, 0x00, 0x68, 0x00, 0x22, 0xfa, 0x80, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x81, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x40,
- 0x80, 0xcc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xde, 0xb1, 0x01, 0x00,
- 0x00, 0x01, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
- 0x80, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd6, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa, 0x80, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf6, 0x81, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xd6, 0xb1, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40,
- 0xd5, 0x99, 0x01, 0x00, 0x18, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00,
- 0x48, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0xfa,
- 0xd6, 0xe5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0xd5, 0x99, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xfb, 0xd6, 0xe5, 0x01, 0x00, 0x03, 0x00, 0x00, 0xfb,
- 0x7a, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xdc, 0xb1, 0x01, 0x00,
- 0x7c, 0x00, 0x00, 0x4c, 0xdd, 0x91, 0x00, 0x00, 0x7c, 0x00, 0x95, 0xe8,
- 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x2f, 0xe9, 0xfa, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xd1, 0xb1, 0x01, 0x00, 0xff, 0x00, 0x00, 0x42,
- 0x80, 0x88, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0x7c, 0x00, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x85, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x02, 0x80, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x81, 0xb0, 0x01, 0x00, 0x8e, 0x00, 0x09, 0xf9, 0x81, 0x32, 0x00, 0x00,
- 0x8c, 0x00, 0x08, 0xf9, 0x81, 0x32, 0x00, 0x00, 0x98, 0x00, 0x1f, 0xfd,
- 0xf9, 0x33, 0x00, 0x00, 0x8b, 0x00, 0x9e, 0xfd, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48,
- 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf7, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0xf3, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x19, 0xb1, 0x01, 0x00, 0x93, 0x00, 0x0a, 0xf9, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x40, 0xfb, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xfd,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x07, 0x80, 0xf9, 0xf3, 0x8f, 0x01, 0x00,
- 0x00, 0x07, 0x42, 0xf9, 0xf3, 0x8f, 0x01, 0x00, 0x97, 0x00, 0xa2, 0xff,
- 0xf7, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0xff, 0xfb, 0xef, 0x00, 0x00, 0x00, 0x00, 0x80, 0xfc,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xbb, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0xfd, 0x7f, 0x01, 0x00,
- 0x00, 0x94, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xce, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0xfd, 0x7f, 0x01, 0x00,
- 0x00, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0xff, 0x7f, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x9a, 0x13, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x02, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x03, 0x01, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x9a, 0x13, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x02, 0x29, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x67, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xfd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xfd, 0x83, 0x01, 0x00,
- 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44, 0x80, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0xfd, 0x93, 0x01, 0x00, 0xe2, 0x00, 0x00, 0x40,
- 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x46, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x40, 0x2b, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x46, 0x88, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x94, 0x8c, 0xb0, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x46, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
- 0x80, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0xf0, 0x01, 0x00,
- 0xc9, 0x00, 0x82, 0x41, 0x89, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xfd, 0x83, 0x01, 0x00,
- 0xd4, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x44,
- 0x80, 0xb2, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x08, 0x83, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x45, 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x44,
- 0xfd, 0x93, 0x01, 0x00, 0x00, 0x30, 0x00, 0x08, 0x83, 0x98, 0x01, 0x00,
- 0x80, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
- 0x89, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x46, 0x80, 0xb2, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x94, 0x80, 0x88, 0x01, 0x00, 0xa5, 0xa5, 0xa2, 0x40,
- 0x80, 0x4e, 0x01, 0x00, 0x00, 0x00, 0x80, 0x43, 0x89, 0xb0, 0x01, 0x00,
- 0x03, 0x84, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x88, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x96,
- 0x80, 0xb2, 0x00, 0x00, 0xdf, 0x00, 0xa2, 0x41, 0x8d, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40,
- 0x25, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x89, 0xe0, 0x01, 0x00,
- 0xdd, 0x00, 0x00, 0x44, 0x82, 0x14, 0x01, 0x00, 0x00, 0x00, 0x90, 0x94,
- 0x8a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0xf0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x89, 0xd0, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
- 0xec, 0x00, 0x08, 0x41, 0x80, 0x32, 0x00, 0x00, 0xed, 0x00, 0x00, 0x94,
- 0x24, 0xb1, 0x00, 0x00, 0x10, 0x00, 0x00, 0x94, 0x24, 0xf5, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xf2, 0x00, 0xa0, 0x44,
- 0x89, 0x50, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x44, 0x2b, 0x41, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x94, 0xf0, 0xb1, 0x01, 0x00, 0xef, 0x00, 0x20, 0x44,
- 0x89, 0x50, 0x00, 0x00, 0x10, 0x00, 0x00, 0x45, 0x88, 0xf4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42,
- 0x89, 0xd0, 0x00, 0x00, 0xf7, 0x00, 0xa0, 0xfa, 0x8a, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00, 0xf5, 0x00, 0xa3, 0x42,
- 0x89, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x45, 0x88, 0x88, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x45, 0x8a, 0xf4, 0x01, 0x00, 0xfc, 0x00, 0x90, 0x44,
- 0x8a, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8b, 0xc0, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x45, 0x8a, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x50,
- 0x8b, 0xe0, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x40, 0x25, 0x99, 0x01, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x2b, 0x99, 0x01, 0x00, 0x00, 0x30, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x08, 0x83, 0x14, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x94, 0x2a, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
- 0xf9, 0x9b, 0x01, 0x00, 0xdd, 0x00, 0x00, 0xfc, 0x19, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0x40, 0x94, 0x80, 0xb2, 0x01, 0x00, 0xdd, 0x00, 0x00, 0x44,
- 0x2b, 0x41, 0x01, 0x00, 0x00, 0x00, 0x41, 0x94, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xf9, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x2b, 0xc1, 0x01, 0x00, 0x04, 0x01, 0x9f, 0x94, 0x80, 0x32, 0x00, 0x00,
- 0x02, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x01, 0x00, 0x51,
- 0x93, 0xb0, 0x00, 0x00, 0x10, 0x01, 0x00, 0x4d, 0x93, 0xb0, 0x00, 0x00,
- 0x10, 0x01, 0x00, 0x49, 0x93, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x93, 0xb0, 0x01, 0x00, 0x10, 0x01, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x12, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x13, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x16, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x17, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x19, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x1b, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1c, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x1e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x70, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x71, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x72, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x73, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x74, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x76, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x77, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x78, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x79, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x7a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7b, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x7d, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7e, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x7f, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa1, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x19, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x15, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0b, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x09, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x07, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x01, 0xb0, 0x01, 0x00, 0x3b, 0x01, 0x20, 0x48, 0xa1, 0x51, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x47, 0x01, 0x22, 0x4b,
- 0x74, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x60, 0x00, 0x00, 0x4b, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
- 0x7e, 0xb1, 0x01, 0x00, 0x48, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x45, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x80, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x18, 0x00, 0x00, 0xaa, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x43, 0x97, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0xaa,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00,
- 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x07, 0x90, 0x01, 0x00,
- 0xd8, 0x9f, 0x00, 0x40, 0xbf, 0xb3, 0x00, 0x00, 0x5a, 0x01, 0x22, 0xcc,
- 0x85, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x07, 0x90, 0x01, 0x00,
- 0xd8, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
- 0xd0, 0x14, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe1, 0xb1, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20,
- 0x62, 0xdd, 0x01, 0x00, 0x63, 0x01, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xcc, 0x85, 0x93, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0xa4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xbc, 0xb3, 0x01, 0x00,
- 0x00, 0x14, 0x2f, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe7,
- 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0xdd, 0x81, 0x88, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
- 0x80, 0xf4, 0x01, 0x00, 0x73, 0x01, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00,
- 0x86, 0x01, 0x00, 0xdd, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x10, 0xb1, 0x00, 0x00, 0x87, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x88, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x8b, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8d, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc4, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x82, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x83, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xb8, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x28, 0x00, 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
- 0xd5, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00, 0xd6, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x28, 0x00, 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x28, 0x00,
- 0x72, 0x01, 0x00, 0x41, 0x81, 0xc0, 0x28, 0x00, 0x55, 0x01, 0x51, 0x49,
- 0xfd, 0x93, 0x28, 0x00, 0x55, 0x01, 0x52, 0x4a, 0xfd, 0x93, 0x2a, 0x00,
- 0x55, 0x01, 0x55, 0x49, 0xfd, 0x83, 0x2a, 0x00, 0x55, 0x01, 0x56, 0x4a,
- 0xfd, 0x83, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x2a, 0x00,
- 0x55, 0x01, 0x45, 0x40, 0x81, 0xb2, 0x2a, 0x00, 0x50, 0x01, 0x91, 0x82,
- 0x80, 0x30, 0x2a, 0x00, 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x2a, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x89, 0xb0, 0x2b, 0x00, 0x00, 0x00, 0x2f, 0x40,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0xb3, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0x92, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x49, 0xd1, 0x01, 0x00, 0x9a, 0x01, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
- 0x96, 0x01, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x50, 0x01, 0x00, 0x41,
- 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0xb3, 0x01, 0x00,
- 0x50, 0x01, 0xa0, 0x0f, 0xbd, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00,
- 0xb5, 0x01, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x42, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0x85, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xde, 0x19, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x42, 0xff,
- 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff, 0xe1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xff,
- 0xe1, 0xb1, 0x01, 0x00, 0x08, 0x14, 0x00, 0xa4, 0x80, 0xcc, 0x01, 0x00,
- 0xaa, 0x01, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x85, 0xc0, 0x01, 0x00, 0xa8, 0x01, 0xa2, 0x4c, 0x81, 0x50, 0x00, 0x00,
- 0xb4, 0x01, 0x22, 0xd2, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x01, 0x22, 0x41,
- 0xa5, 0x6f, 0x00, 0x00, 0x50, 0x01, 0xa2, 0xe0, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x89, 0x90, 0x01, 0x00, 0x00, 0x00, 0x40, 0x42, 0x80, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x41, 0x43, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x88, 0x94, 0x01, 0x00, 0x55, 0x01, 0x00, 0x44, 0xe0, 0xb1, 0x00, 0x00,
- 0xb1, 0x01, 0x00, 0x48, 0x49, 0xc1, 0x00, 0x00, 0xaf, 0x01, 0x00, 0x5b,
- 0x89, 0x90, 0x00, 0x00, 0xa8, 0x9f, 0x00, 0xa0, 0x9e, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x14, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x23, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0xbe, 0x01, 0x22, 0xde, 0xe1, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0xb9, 0x01, 0xa2, 0x44, 0x81, 0x6c, 0x00, 0x00, 0x50, 0x01, 0x00, 0x43,
- 0xbf, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x40, 0xf8, 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0xf0,
- 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40,
- 0xe1, 0xb1, 0x00, 0x00, 0xc6, 0x01, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x91, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xcb, 0x01, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
- 0xd1, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0x53, 0x01, 0x00, 0xde,
- 0xa1, 0xb3, 0x00, 0x00, 0xe3, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xe5, 0x01, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x52, 0x01, 0x00, 0xdf, 0xe1, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0xa1, 0xb1, 0x01, 0x00, 0x02, 0x00, 0x00, 0xd2, 0xa5, 0xe7, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xc1, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0xdb, 0x01, 0x22, 0x44, 0xc1, 0x53, 0x00, 0x00,
- 0xda, 0x01, 0x84, 0x41, 0x81, 0x40, 0x00, 0x00, 0xde, 0x01, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x45, 0xb1, 0x01, 0x00,
- 0xd5, 0x01, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
- 0xda, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x00, 0xd3,
- 0xa7, 0xcb, 0x01, 0x00, 0xf8, 0x02, 0x00, 0xe0, 0xa5, 0xb3, 0x00, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00, 0x53, 0x01, 0x00, 0xde,
- 0xa1, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0xbf, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xde, 0x81, 0x90, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xba,
- 0x80, 0x04, 0x00, 0x00, 0x60, 0x00, 0x00, 0xde, 0x61, 0x99, 0x01, 0x00,
- 0xe8, 0x01, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x52, 0x01, 0x00, 0x40,
- 0xe0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xba, 0xb3, 0x01, 0x00,
- 0x6b, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x4d,
- 0x83, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe1, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xe3, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xe5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xe9, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xeb, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf5, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf7, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf9, 0xb3, 0x01, 0x00, 0xf9, 0x01, 0x22, 0x40,
- 0x8f, 0x6f, 0x00, 0x00, 0x78, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x60, 0x02, 0x00, 0xc7, 0x83, 0x30, 0x01, 0x00, 0x80, 0x02, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x42, 0x83, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe8, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xea, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x85,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xec, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xed, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb2,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xac, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb8, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xb9, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xba,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xbb, 0xf0, 0xb1, 0x01, 0x00,
- 0x0c, 0x02, 0xb8, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0x90, 0x01, 0x00, 0x0e, 0x02, 0xb9, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0x90, 0x01, 0x00, 0x10, 0x02, 0xba, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x81, 0x90, 0x01, 0x00,
- 0x12, 0x02, 0xbb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x81, 0x90, 0x01, 0x00, 0x14, 0x02, 0xbc, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x81, 0x90, 0x01, 0x00, 0x16, 0x02, 0xbd, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x81, 0x90, 0x01, 0x00,
- 0x18, 0x02, 0xbe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x81, 0x90, 0x01, 0x00, 0x1a, 0x02, 0xbf, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x81, 0x90, 0x01, 0x00, 0x1c, 0x02, 0xc8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x81, 0x90, 0x01, 0x00,
- 0x1e, 0x02, 0xc9, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0x81, 0x90, 0x01, 0x00, 0x20, 0x02, 0xca, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x81, 0x90, 0x01, 0x00, 0x22, 0x02, 0xcb, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x81, 0x90, 0x01, 0x00,
- 0x24, 0x02, 0xcc, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x81, 0x90, 0x01, 0x00, 0x26, 0x02, 0xcd, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4d, 0x81, 0x90, 0x01, 0x00, 0x28, 0x02, 0xce, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0x90, 0x01, 0x00,
- 0x2a, 0x02, 0xcf, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x81, 0x90, 0x01, 0x00, 0x2c, 0x02, 0xf0, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x81, 0x90, 0x01, 0x00, 0x2e, 0x02, 0xf1, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x81, 0x90, 0x01, 0x00,
- 0x30, 0x02, 0xf2, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x81, 0x90, 0x01, 0x00, 0x32, 0x02, 0xf3, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0x81, 0x90, 0x01, 0x00, 0x34, 0x02, 0xf4, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x81, 0x90, 0x01, 0x00,
- 0x36, 0x02, 0xf5, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x81, 0x90, 0x01, 0x00, 0x38, 0x02, 0xf6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x56, 0x81, 0x90, 0x01, 0x00, 0x3a, 0x02, 0xf7, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0x90, 0x01, 0x00,
- 0x3c, 0x02, 0xf8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x81, 0x90, 0x01, 0x00, 0x3e, 0x02, 0xf9, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x59, 0x81, 0x90, 0x01, 0x00, 0x40, 0x02, 0xfa, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x81, 0x90, 0x01, 0x00,
- 0x42, 0x02, 0xfb, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b,
- 0x81, 0x90, 0x01, 0x00, 0x44, 0x02, 0xfc, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x81, 0x90, 0x01, 0x00, 0x46, 0x02, 0xfd, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, 0x81, 0x90, 0x01, 0x00,
- 0x48, 0x02, 0xfe, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e,
- 0x81, 0x90, 0x01, 0x00, 0x4a, 0x02, 0xff, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0xa5, 0x9b, 0x01, 0x00,
- 0xd8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd0, 0x14, 0x2e, 0x06, 0xa5, 0xb3, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0xd3, 0xa7, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf1, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf5, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xeb, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xef, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xf1, 0xb1, 0x01, 0x00,
- 0xdb, 0x01, 0x00, 0xc7, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x66, 0x02, 0x00, 0x48, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x51, 0x40, 0x1a, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x4d, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x63, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x5f, 0x02, 0x49, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40, 0x1c, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x4e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x68, 0x02, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x5f, 0x02, 0x4a, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0,
- 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0xd8, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa1, 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
- 0xd2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xd4, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1,
- 0xdc, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xde, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x88, 0xda, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4,
- 0x8e, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xe6, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xac, 0xec, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x99,
- 0xfa, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe0, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xe2, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
- 0xe4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xe8, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xea, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5,
- 0xf4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd5, 0xf6, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd5, 0xf8, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xc7,
- 0xa9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
- 0x84, 0x02, 0x00, 0x40, 0x91, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x91, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x40, 0xa3, 0x9b, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0x88, 0x02, 0x00, 0x40,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x10, 0xb1, 0x00, 0x00,
- 0x8d, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x98, 0x02, 0x00, 0x46, 0xa3, 0xb3, 0x00, 0x00,
- 0x9b, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa1, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8f, 0x02, 0x23, 0x50, 0xa5, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xa5, 0xb3, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x42,
- 0xa5, 0x63, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xba, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde, 0xa1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x97, 0x02, 0x22, 0x44,
- 0xa5, 0x53, 0x00, 0x00, 0x94, 0x02, 0x00, 0x41, 0xa1, 0xc1, 0x00, 0x00,
- 0x55, 0x01, 0x00, 0xdd, 0xa1, 0xb1, 0x00, 0x00, 0xe8, 0x02, 0x00, 0xde,
- 0xa1, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xbf, 0xb3, 0x01, 0x00, 0x50, 0x01, 0xa2, 0xd2, 0x77, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xde,
- 0x63, 0xb1, 0x01, 0x00, 0x9e, 0x02, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x54,
- 0xa5, 0x33, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd0, 0x14, 0x2d, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xd0, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0xd4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0xd6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0xb1, 0x01, 0x00,
- 0xac, 0x02, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x60, 0x02, 0x00, 0x46,
- 0x83, 0x30, 0x01, 0x00, 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa0, 0x9e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe8,
- 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x45, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xea, 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xeb,
- 0xa1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x40, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd0, 0x14, 0x2e, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0xa3, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc1, 0xb3, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xdd, 0x81, 0xf4, 0x01, 0x00, 0xbd, 0x02, 0x00, 0x40,
- 0x10, 0xc9, 0x00, 0x00, 0xc3, 0x02, 0x00, 0x05, 0x81, 0xb0, 0x00, 0x00,
- 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xcb, 0x02, 0x00, 0x05,
- 0x81, 0xb0, 0x00, 0x00, 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd0, 0x02, 0x00, 0x44, 0xa5, 0xb3, 0x00, 0x00, 0xd2, 0x02, 0x00, 0x44,
- 0xa5, 0xb3, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40, 0xa4, 0xe7, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe0, 0x81, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0xc1,
- 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0xc4, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00, 0xda, 0x02, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf8, 0x02, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x55, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x02, 0x00, 0x00, 0x40,
- 0xa4, 0xe7, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x91, 0xb1, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0xc9, 0xf0, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x22, 0x41,
- 0x81, 0x50, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x41, 0xc1, 0xc3, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0xde, 0x85, 0x89, 0x01, 0x00, 0xc8, 0x02, 0x00, 0xc2,
- 0xe0, 0xb1, 0x00, 0x00, 0xff, 0xff, 0x00, 0xde, 0x95, 0x89, 0x01, 0x00,
- 0xc8, 0x02, 0x00, 0xca, 0xe0, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd8, 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd4, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xe2, 0x02, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x93, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xe7, 0xa7, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd8,
- 0xa9, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd0, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3,
- 0xf1, 0xb1, 0x01, 0x00, 0xe1, 0x02, 0x00, 0xd4, 0xe1, 0xb1, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xcc,
- 0x85, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
- 0xfa, 0x02, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0xf9, 0x02, 0xa2, 0xf2,
- 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0xcc, 0x85, 0x83, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x41,
- 0x99, 0xb3, 0x01, 0x00, 0x0a, 0x03, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
- 0x12, 0x03, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x0c, 0x03, 0x22, 0x4c,
- 0x81, 0x6c, 0x00, 0x00, 0x16, 0x03, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
- 0x17, 0x03, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x19, 0x03, 0x22, 0x58,
- 0x81, 0x6c, 0x00, 0x00, 0x1e, 0x03, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
- 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
- 0x09, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xf3, 0x83, 0x01, 0x00, 0x10, 0x03, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xdd, 0x9f, 0x22, 0xca,
- 0x07, 0x14, 0x00, 0x00, 0xdd, 0x9f, 0x00, 0x45, 0xf3, 0x93, 0x00, 0x00,
- 0xdd, 0x9f, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xdd, 0x9f, 0x80, 0xca,
- 0x05, 0x30, 0x00, 0x00, 0xdd, 0x9f, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
- 0xdd, 0x9f, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
- 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
- 0x81, 0x88, 0x01, 0x00, 0xdd, 0x9f, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
- 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x1b, 0x03, 0xa8, 0xb1,
- 0x82, 0x30, 0x00, 0x00, 0x1a, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xdd, 0x9f, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x22, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x2d, 0x03, 0x91, 0x82, 0x82, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
- 0x80, 0xce, 0x01, 0x00, 0x2b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x2d, 0x03, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
- 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x32, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x3d, 0x03, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89,
- 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00,
- 0x3b, 0x03, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3d, 0x03, 0x55, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb5, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xb5, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
- 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40, 0x99, 0xb3, 0x01, 0x00,
- 0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x30, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x90, 0x00, 0xf8,
- 0x80, 0x98, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf2, 0x88, 0xe4, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0x4d, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0x50, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x40, 0x00, 0x00, 0x40, 0x20, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x23, 0x91, 0x01, 0x00, 0x53, 0x03, 0x1f, 0x91, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x23, 0x91, 0x01, 0x00, 0x55, 0x03, 0x1f, 0x91,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x08, 0x80, 0x40, 0x20, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x48, 0x84, 0x84, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x8f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x62, 0xb1, 0x01, 0x00,
- 0x5a, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x08, 0x00, 0x47,
- 0x8e, 0xc8, 0x01, 0x00, 0x58, 0x03, 0x00, 0x5c, 0x8f, 0x80, 0x00, 0x00,
- 0xe0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x58, 0x15, 0x2d, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfa, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x81, 0xb0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x45, 0x82, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x82, 0x94, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x60, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x8d, 0xc0, 0x01, 0x00, 0x74, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
- 0x65, 0x03, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x63, 0x03, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x08, 0x00, 0x00, 0x40, 0x85, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x86, 0xb0, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x43, 0x86, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0xa6, 0x41, 0x85, 0x50, 0x01, 0x00, 0x70, 0x03, 0x00, 0x41,
- 0x83, 0xe0, 0x00, 0x00, 0x6e, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x85, 0xe0, 0x01, 0x00, 0xd0, 0x14, 0x2f, 0x46,
- 0x84, 0x94, 0x01, 0x00, 0x20, 0x00, 0x00, 0x42, 0x60, 0x99, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x07, 0x00, 0x00, 0x45, 0x80, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x8b, 0xf0, 0x01, 0x00, 0x00, 0x04, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x85, 0x03, 0xa0, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x83, 0x03, 0x00, 0x41, 0x82, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0x8e, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x00, 0x02, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0x00, 0x39, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x8b, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x44,
- 0x82, 0xf4, 0x01, 0x00, 0x1a, 0x15, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
- 0x70, 0x15, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x08, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x39, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x70, 0x15, 0x00, 0x43, 0x62, 0x99, 0x01, 0x00,
- 0x95, 0x03, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x97, 0x03, 0x22, 0x5a,
- 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x98, 0x03, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0x00, 0x08, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x90, 0x03, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x58, 0x15, 0x2d, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0xd0, 0x14, 0x2d, 0xf0, 0x88, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8f, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6,
- 0x90, 0xb0, 0x01, 0x00, 0x00, 0xf8, 0x00, 0x48, 0x90, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0x8a, 0xb0, 0x01, 0x00, 0x80, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00, 0xac, 0x03, 0x22, 0x40,
- 0x82, 0x6c, 0x00, 0x00, 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x58, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x8d, 0xc0, 0x01, 0x00, 0xb5, 0x03, 0x22, 0x5f, 0x8d, 0x6c, 0x00, 0x00,
- 0xa7, 0x03, 0xa2, 0x41, 0x93, 0x50, 0x00, 0x00, 0xa5, 0x03, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xff, 0x07, 0x00, 0x47, 0x84, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0xa6, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x9f, 0x00, 0x47,
- 0x80, 0x30, 0x01, 0x00, 0x00, 0x02, 0x00, 0x47, 0x8e, 0xc8, 0x01, 0x00,
- 0xb0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x50, 0xb3, 0x01, 0x00, 0xbb, 0x03, 0x20, 0x18, 0x89, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00,
- 0xbe, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xa6,
- 0x84, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x10, 0x00, 0x40, 0x55, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x50, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x4f, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x4e, 0xd3, 0x01, 0x00, 0x6e, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x82, 0x03, 0x00, 0x42, 0x80, 0x30, 0x01, 0x00,
- 0xb0, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc7, 0x03, 0x22, 0xa7,
- 0x8f, 0x6c, 0x00, 0x00, 0x5a, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xc4, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xee, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa0, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xca,
- 0xa7, 0x33, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x03, 0x22, 0x42,
- 0x75, 0x6f, 0x00, 0x00, 0xd8, 0x03, 0x22, 0x41, 0x75, 0x6f, 0x00, 0x00,
- 0xda, 0x03, 0x1e, 0xca, 0x81, 0x32, 0x00, 0x00, 0xdc, 0x03, 0x1f, 0xca,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0x42, 0x75, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xcd, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x41, 0x75, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xcf, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40,
- 0x75, 0xb3, 0x00, 0x00, 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
- 0xc6, 0xb1, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0x40, 0x75, 0xb3, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x45, 0x01, 0x00, 0x4d, 0x93, 0x30, 0x01, 0x00,
- 0x45, 0x01, 0x00, 0x4e, 0x93, 0x30, 0x01, 0x00, 0x45, 0x01, 0x00, 0x4c,
- 0x93, 0x30, 0x01, 0x00, 0xec, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xdd, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x54, 0x95, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xdd, 0x9f, 0x00, 0xca, 0xe5, 0xb1, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcc, 0x14, 0x2e, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2,
- 0xa0, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43, 0xb2, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0xda, 0x89, 0xb0, 0x01, 0x00, 0x7c, 0x00, 0x00, 0x40,
- 0x8b, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x89, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x89, 0xd0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x44,
- 0x88, 0x8c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xa5, 0xb3, 0x01, 0x00, 0x15, 0x04, 0x00, 0x43,
- 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xa5, 0xc3, 0x01, 0x00, 0x0b, 0x04, 0x22, 0x44, 0x89, 0x50, 0x00, 0x00,
- 0x0b, 0x04, 0x22, 0x44, 0x8b, 0x50, 0x00, 0x00, 0xfa, 0x03, 0xa2, 0x50,
- 0xa5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
- 0x85, 0x30, 0x01, 0x00, 0xcc, 0x14, 0x2e, 0xd2, 0x95, 0xc3, 0x01, 0x00,
- 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xb0, 0x01, 0x00,
- 0x08, 0x04, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x07, 0x04, 0xa2, 0xf2,
- 0x80, 0x30, 0x00, 0x00, 0xfa, 0x03, 0x00, 0x40, 0xa5, 0xb3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xa5, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb, 0x85, 0x30, 0x01, 0x00,
- 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00,
- 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xdb, 0x00, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xff, 0xff, 0x00, 0x94, 0xb4, 0x8b, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd9,
- 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00,
- 0xdd, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x94,
- 0xb4, 0xb3, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xd9, 0x2b, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0x27, 0xb1, 0x01, 0x00, 0x06, 0xc0, 0x00, 0x40, 0x2d, 0x99, 0x01, 0x00,
- 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x02, 0xc4, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
- 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x40, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x05, 0x82, 0x00, 0x41, 0x2c, 0x99, 0x01, 0x00,
- 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2d, 0x04, 0x80, 0x94,
- 0x80, 0x32, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x28, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x40,
- 0x2d, 0x99, 0x01, 0x00, 0xde, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x31, 0x04, 0x00, 0x12,
- 0x10, 0xc9, 0x00, 0x00, 0x00, 0x48, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x49, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x4b, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x4d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x4f, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x50, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x52, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x54, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x56, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x57, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x80, 0x59, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x5b, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x5d, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x5e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x60, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x62, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x64, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x65, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x67, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x69, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x6b, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x6c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x80, 0x6e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x40, 0x70, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x72, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0xc0, 0x73, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x80, 0x75, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x40, 0x77, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x79, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0xc0, 0x7a, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x80, 0x7c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x40, 0x7e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x59, 0x04, 0x00, 0x12, 0x10, 0xc9, 0x00, 0x00,
- 0x00, 0x80, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x82, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x84, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x86, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x88, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8a, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x8c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x8e, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x90, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x92, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x94, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x96, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x98, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9a, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0x9c, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0x9e, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa0, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa2, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xa4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa6, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xa8, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xaa, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xac, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xae, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xb0, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb2, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb4, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xb6, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xb8, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x00, 0xba, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00,
- 0x00, 0xbc, 0x80, 0x40, 0x0b, 0x98, 0x01, 0x00, 0x00, 0xbe, 0x80, 0x40,
- 0x0b, 0x98, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x82, 0x04, 0x85, 0x41,
- 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00,
- 0x87, 0x04, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x90, 0x04, 0x60, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x80, 0xb1, 0x01, 0x00,
- 0xff, 0xff, 0xf0, 0x4b, 0x82, 0x89, 0x01, 0x00, 0x93, 0x04, 0x60, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x80, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0xf0, 0xa6, 0x82, 0xb1, 0x01, 0x00, 0x96, 0x04, 0x60, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0xf0, 0xc2, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x80, 0x4b, 0x92, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0x01, 0x00, 0x80, 0xa6,
- 0x92, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x94, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0xca, 0x94, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x88, 0x94, 0x01, 0x00, 0xa6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xad, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xa6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xb0, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x62, 0xb1, 0x01, 0x00, 0xb1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xb8, 0x04, 0x22, 0x4b, 0x89, 0x7c, 0x00, 0x00, 0xb6, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xc0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xb6, 0x04, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xc1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xc6, 0x04, 0x22, 0x4b,
- 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xc4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xc1, 0x04, 0xa2, 0x41,
- 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x4e, 0x98, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x98, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x99, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x80, 0x98, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x99, 0xe0, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x4c,
- 0x88, 0x94, 0x00, 0x00, 0xd6, 0x04, 0x47, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xdd, 0x04, 0x22, 0x20, 0x87, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xd6, 0x04, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x1f, 0x80, 0x86, 0xb3, 0x01, 0x00, 0xe0, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x62, 0xb1, 0x01, 0x00, 0xe1, 0x04, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xe8, 0x04, 0x22, 0x4a, 0x89, 0x7c, 0x00, 0x00, 0xe6, 0x04, 0x22, 0x4f,
- 0x77, 0x7d, 0x00, 0x00, 0xf0, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x62, 0xb1, 0x01, 0x00, 0xe6, 0x04, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20, 0x87, 0xb3, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x99, 0xb0, 0x01, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xf1, 0x04, 0xa8, 0xb1, 0x52, 0x33, 0x00, 0x00, 0xf6, 0x04, 0x22, 0x4a,
- 0x53, 0x7f, 0x00, 0x00, 0x6f, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xf4, 0x04, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00, 0xf1, 0x04, 0xa2, 0x41,
- 0x99, 0x50, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x4f, 0x77, 0xfd, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x00, 0x05, 0xa8, 0xb1, 0x80, 0x30, 0x00, 0x00, 0x12, 0x05, 0x1d, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x40, 0x18, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x10, 0x05, 0xa2, 0x40,
- 0x86, 0x04, 0x00, 0x00, 0xde, 0x9f, 0x9c, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x40, 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50,
- 0x47, 0x31, 0x01, 0x00, 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00,
- 0x0c, 0x05, 0x52, 0x40, 0x81, 0x32, 0x00, 0x00, 0x30, 0x05, 0x00, 0x40,
- 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x89, 0xb0, 0x01, 0x00,
- 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00, 0x30, 0x05, 0x00, 0x05,
- 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x1b, 0x00, 0xde, 0x9f, 0x00, 0x41,
- 0xe1, 0xc1, 0x1a, 0x00, 0x78, 0x18, 0x00, 0x40, 0x49, 0x99, 0x1b, 0x00,
- 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x1a, 0x00, 0x14, 0x05, 0x42, 0x40,
- 0x81, 0x32, 0x1a, 0x00, 0x00, 0x82, 0x00, 0xb3, 0x67, 0xdf, 0x1b, 0x00,
- 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x1b, 0x00, 0x28, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x1b, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
- 0x27, 0x05, 0x0f, 0x40, 0x80, 0x32, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x40,
- 0x88, 0x88, 0x01, 0x00, 0x30, 0x05, 0x00, 0x50, 0x47, 0x31, 0x01, 0x00,
- 0x36, 0x00, 0x00, 0x44, 0x88, 0xcc, 0x01, 0x00, 0x1f, 0x05, 0x99, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x89, 0xd0, 0x01, 0x00,
- 0x21, 0x05, 0x9b, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x89, 0xd0, 0x01, 0x00, 0x23, 0x05, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
- 0x30, 0x05, 0x00, 0x40, 0x47, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x89, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x48, 0x47, 0x31, 0x01, 0x00,
- 0x30, 0x05, 0x00, 0x58, 0x47, 0x31, 0x01, 0x00, 0xde, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x00, 0x00, 0x40, 0x86, 0xf4, 0x01, 0x00,
- 0x6f, 0x00, 0x00, 0x43, 0x86, 0x88, 0x01, 0x00, 0xde, 0x9f, 0x26, 0x05,
- 0x47, 0x31, 0x00, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00,
- 0xde, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x44, 0xf0, 0x41, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0xe1, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x07,
- 0x91, 0x30, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x97, 0xec, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x05, 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x44, 0x05, 0xa2, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0x45, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00, 0x10, 0x04, 0x00, 0x42,
- 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf5, 0xb1, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xf5, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
- 0xf7, 0xf5, 0x01, 0x00, 0x50, 0x00, 0x00, 0x40, 0x91, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x8f, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
- 0xb2, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x91, 0xc0, 0x01, 0x00, 0x50, 0x05, 0xa2, 0x41, 0x8f, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x45, 0xd1, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xfd, 0xb1, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0x91, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xda,
- 0x8f, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0xda,
- 0xfd, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x7a, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x78, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
- 0x7d, 0x05, 0x22, 0x20, 0xb5, 0x6f, 0x00, 0x00, 0x7a, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x1f, 0x00,
- 0x7d, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x1e, 0x00, 0x7a, 0x05, 0x42, 0x40,
- 0x81, 0x32, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x1f, 0x00,
- 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x1e, 0x00, 0x54, 0x16, 0x00, 0x40,
- 0x47, 0x99, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x1f, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x46, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda, 0xf7, 0xf5, 0x01, 0x00,
- 0x48, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x97, 0xb0, 0x01, 0x00, 0x10, 0x04, 0x00, 0x4a, 0xb2, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xda, 0xf7, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x00, 0xda,
- 0xf7, 0xf5, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x95, 0xc0, 0x01, 0x00,
- 0x90, 0x05, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x40,
- 0xa5, 0x9b, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40, 0xa1, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xa7, 0xb3, 0x01, 0x00, 0xe1, 0x9f, 0x00, 0xbb,
- 0x85, 0x30, 0x01, 0x00, 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb8, 0x05, 0x22, 0x45, 0xfd, 0x7f, 0x00, 0x00, 0xe0, 0x15, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40,
- 0x62, 0xdd, 0x01, 0x00, 0xa7, 0x05, 0xa8, 0xbb, 0xe1, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xaa, 0x05, 0xa2, 0x41,
- 0x83, 0x50, 0x00, 0x00, 0xa9, 0x05, 0xa2, 0xf2, 0x82, 0x30, 0x00, 0x00,
- 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb0, 0x05, 0xa2, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x40, 0xb3, 0x9b, 0x01, 0x00,
- 0xb1, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0xb3, 0x9b, 0x01, 0x00, 0xf0, 0x15, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x05, 0xa2, 0xfa,
- 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42, 0xb3, 0x43, 0x01, 0x00,
- 0xb8, 0x05, 0xa2, 0xfa, 0xb4, 0x6f, 0x00, 0x00, 0x10, 0x04, 0x00, 0x42,
- 0xb3, 0x43, 0x01, 0x00, 0xbb, 0x05, 0x22, 0xfa, 0xb4, 0x6f, 0x00, 0x00,
- 0xb8, 0x05, 0x42, 0x40, 0x81, 0x32, 0x20, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x67, 0x93, 0x21, 0x00, 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x20, 0x00,
- 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0xdb, 0x9f, 0x00, 0x40,
- 0x49, 0x31, 0x21, 0x00, 0xf6, 0x15, 0x00, 0x40, 0x43, 0x99, 0x21, 0x00,
- 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x21, 0x00, 0x00, 0x00, 0x6e, 0xfa,
- 0x8e, 0xb0, 0x21, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xb4, 0xb3, 0x01, 0x00, 0xc9, 0x05, 0xa2, 0x40, 0x8f, 0x6c, 0x00, 0x00,
- 0xfc, 0x15, 0x20, 0x20, 0xe1, 0xb1, 0x01, 0x00, 0xce, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x24, 0x00, 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x25, 0x00,
- 0xce, 0x05, 0x22, 0x40, 0x97, 0x6c, 0x24, 0x00, 0xcb, 0x05, 0x42, 0x40,
- 0x81, 0x32, 0x24, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x67, 0x93, 0x25, 0x00,
- 0xdf, 0x9f, 0x00, 0x58, 0x67, 0x93, 0x24, 0x00, 0x38, 0x05, 0x00, 0x40,
- 0x81, 0x32, 0x25, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x25, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd3, 0x05, 0x22, 0x50,
- 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x91, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xf8, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfa, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x20, 0x04, 0x00, 0xf2, 0xb4, 0x33, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xfc, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x94, 0xb0, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x4a, 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x4a, 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xe9, 0x05, 0x22, 0x50, 0xb5, 0x6f, 0x00, 0x00,
- 0xea, 0x05, 0x00, 0x50, 0xb5, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xb5, 0xb3, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xe0, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x30, 0x31, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x32, 0x33, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x34, 0x35, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x36, 0x37, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x38, 0x39, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x41, 0x42, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x43, 0x44, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x45, 0x46, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x47, 0x48, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x49, 0x4a, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
- 0xfc, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x80, 0x16, 0x2e, 0x06,
- 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0xff, 0x05, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
- 0x02, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
- 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0x08, 0x06, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
- 0x14, 0x06, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x45, 0x67, 0x00, 0xa6, 0xe0, 0xb2, 0x01, 0x00, 0x01, 0x23, 0x00, 0x70,
- 0xe1, 0x9a, 0x01, 0x00, 0xcd, 0xef, 0x00, 0xa6, 0xe2, 0xb2, 0x01, 0x00,
- 0x89, 0xab, 0x00, 0x71, 0xe3, 0x9a, 0x01, 0x00, 0xba, 0x98, 0x00, 0xa6,
- 0xe4, 0xb2, 0x01, 0x00, 0xfe, 0xdc, 0x00, 0x72, 0xe5, 0x9a, 0x01, 0x00,
- 0x32, 0x10, 0x00, 0xa6, 0xe6, 0xb2, 0x01, 0x00, 0x76, 0x54, 0x00, 0x73,
- 0xe7, 0x9a, 0x01, 0x00, 0xd2, 0xc3, 0x00, 0xa6, 0xe8, 0xb2, 0x01, 0x00,
- 0xf0, 0xe1, 0x00, 0x74, 0xe9, 0x9a, 0x01, 0x00, 0x80, 0x16, 0x00, 0x4a,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf7, 0xb1, 0x01, 0x00, 0x25, 0x06, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x80, 0x16, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0xfc, 0x16, 0x2a, 0x47,
- 0xe7, 0xb5, 0x01, 0x00, 0x03, 0x00, 0x00, 0x4a, 0xe8, 0xe5, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
- 0xa3, 0x99, 0x01, 0x00, 0x80, 0x16, 0x3d, 0x46, 0x8d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x40, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
- 0x2e, 0x06, 0xa2, 0x41, 0x89, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xeb, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xed, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xef, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf1, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf3, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0x41,
- 0x80, 0x88, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40, 0xa2, 0xc9, 0x01, 0x00,
- 0x4b, 0x06, 0xa0, 0x50, 0x83, 0x6c, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x40,
- 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00,
- 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x86, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x40, 0x98, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x99, 0x84, 0x01, 0x00, 0x50, 0x03, 0x00, 0x4c, 0xa2, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x86, 0xa4, 0x01, 0x00, 0x50, 0x03, 0x00, 0x40,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x40, 0xa4, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x20, 0x88, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x41, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x40, 0x94, 0x01, 0x00,
- 0x05, 0x00, 0x00, 0x75, 0x89, 0xe4, 0x01, 0x00, 0x1b, 0x00, 0x00, 0x75,
- 0x85, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x84, 0x94, 0x01, 0x00,
- 0x55, 0x06, 0xa3, 0x53, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x76, 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x8b, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41,
- 0x80, 0xce, 0x01, 0x00, 0x5a, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x89, 0xa4, 0x01, 0x00, 0x64, 0x06, 0x00, 0x78, 0x89, 0xa4, 0x00, 0x00,
- 0x3b, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00, 0x57, 0x06, 0xaa, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x89, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x77, 0x89, 0x84, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76,
- 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x88, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0x8b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8b, 0x84, 0x01, 0x00,
- 0x64, 0x06, 0x00, 0x45, 0x88, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x84, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0x85, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x84, 0xc0, 0x01, 0x00, 0x6b, 0x06, 0xa3, 0x53,
- 0x83, 0x6c, 0x00, 0x00, 0x82, 0x5a, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00,
- 0x99, 0x79, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x27, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
- 0x70, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00, 0xd9, 0x6e, 0x00, 0xa6,
- 0x84, 0xc0, 0x01, 0x00, 0xa1, 0xeb, 0x00, 0x42, 0x84, 0xc8, 0x01, 0x00,
- 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x41,
- 0x80, 0xce, 0x01, 0x00, 0x75, 0x06, 0xaa, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x1b, 0x8f, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xdc, 0xbc, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x62, 0xca, 0x00, 0xa6, 0x84, 0xc0, 0x01, 0x00, 0xd6, 0xc1, 0x00, 0x42,
- 0x84, 0xc8, 0x01, 0x00, 0x78, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x78, 0xf3, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x77,
- 0xf1, 0xb2, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x76, 0x89, 0xe4, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x76, 0xef, 0xf6, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xee, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x75, 0xed, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xea, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x83, 0xc0, 0x01, 0x00, 0x4f, 0x00, 0x00, 0x41, 0x80, 0xce, 0x01, 0x00,
- 0x37, 0x06, 0x2a, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75,
- 0xe1, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x76, 0xe3, 0xc2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x77, 0xe5, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x78,
- 0xe7, 0xc2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x79, 0xe9, 0xc2, 0x01, 0x00,
- 0x2b, 0x06, 0x81, 0x41, 0x8d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xfd, 0x93, 0x01, 0x00, 0x40, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0xdb, 0x9f, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x15, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0x22, 0x40, 0x8f, 0x6c, 0x00, 0x00,
- 0xda, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb9, 0x06, 0xa2, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x5e, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x7c, 0x16, 0x20, 0xf6, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x31, 0xb3, 0x01, 0x00, 0x9d, 0x06, 0x22, 0x4f, 0x8f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x51, 0xfd, 0x93, 0x01, 0x00, 0x9f, 0x06, 0x22, 0x40,
- 0x8f, 0x7c, 0x00, 0x00, 0xa3, 0x06, 0x00, 0x54, 0xfd, 0x93, 0x00, 0x00,
- 0xa1, 0x06, 0x22, 0x42, 0x8f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52,
- 0xfd, 0x93, 0x01, 0x00, 0xa3, 0x06, 0x22, 0x41, 0x8f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x53, 0xfd, 0x93, 0x01, 0x00, 0xb7, 0x06, 0x22, 0x51,
- 0xfd, 0x7f, 0x00, 0x00, 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb2, 0x06, 0xa2, 0x40, 0xb5, 0x6f, 0x00, 0x00,
- 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x48,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda, 0x97, 0xc0, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0x4b, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xb5, 0xb3, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xb6, 0x06, 0x22, 0x40, 0xb5, 0x6f, 0x00, 0x00, 0xba, 0x06, 0x00, 0x54,
- 0xfd, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
- 0x1c, 0x00, 0x00, 0xfe, 0x7f, 0xd9, 0x01, 0x00, 0xba, 0x06, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0xfd, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xe7, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc4, 0x06, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xe9, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x3c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x34, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x32, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x0a, 0xc8, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4,
- 0x0c, 0xc8, 0x01, 0x00, 0xea, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x0a, 0x07, 0x22, 0x01,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0xd9, 0x06, 0xa3, 0x07, 0x02, 0x6c, 0x00, 0x00,
- 0xda, 0x06, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x07,
- 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00, 0xec, 0x06, 0x22, 0x40,
- 0x03, 0x6c, 0x00, 0x00, 0xe6, 0x06, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x23, 0x07, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x06, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0xe8, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x23, 0x07, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0xee, 0x06, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00,
- 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x22, 0x00, 0x00, 0x19,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0x0f, 0x00, 0x00, 0xf2, 0x3a, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x3b, 0xe0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x14, 0x02, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00, 0xfa, 0x06, 0x23, 0x1a,
- 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x03, 0xc0, 0x01, 0x00,
- 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x1d,
- 0x48, 0xc1, 0x01, 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x30, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x31, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x02, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0x02, 0xc0, 0x01, 0x00, 0x02, 0x07, 0x22, 0x1a,
- 0x02, 0x50, 0x00, 0x00, 0x23, 0x07, 0x00, 0x01, 0x34, 0xc0, 0x00, 0x00,
- 0x22, 0x00, 0x00, 0x19, 0x48, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x2d, 0x14,
- 0x48, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x14, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1d, 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x14, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x24, 0xb0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x17, 0x10, 0xc8, 0x01, 0x00, 0x23, 0x07, 0x00, 0x1a,
- 0x10, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0x0f, 0x07, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00,
- 0x10, 0x07, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x60, 0x12,
- 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d, 0x16, 0x94, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00, 0x17, 0x07, 0xa8, 0x5c,
- 0x1f, 0x10, 0x00, 0x00, 0x40, 0x07, 0x22, 0x0d, 0x14, 0x50, 0x00, 0x00,
- 0x40, 0x07, 0x22, 0x0d, 0x24, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x10, 0xc0, 0x01, 0x00, 0x1e, 0x07, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00,
- 0x23, 0x07, 0x00, 0x41, 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x1f, 0x07, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x3f, 0x07, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00, 0x2e, 0x07, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x2c, 0x07, 0x22, 0xf2,
- 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x29, 0x07, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x04, 0xb0, 0x01, 0x00, 0x33, 0x07, 0x1f, 0xf0, 0x0e, 0x30, 0x00, 0x00,
- 0xd3, 0x06, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x5f,
- 0x0f, 0x80, 0x01, 0x00, 0xd3, 0x06, 0x23, 0x07, 0x14, 0x6c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x24, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x3c, 0x07, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0xd3, 0x06, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00, 0xd3, 0x06, 0x00, 0x0d,
- 0x18, 0xc0, 0x00, 0x00, 0x5f, 0x07, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x19, 0x0a, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
- 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0x02, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0x0d, 0x00, 0x2d, 0x1d, 0x48, 0xc1, 0x01, 0x00,
- 0x09, 0x00, 0x00, 0xf3, 0x38, 0x88, 0x01, 0x00, 0x0d, 0x00, 0x20, 0x50,
- 0xe7, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0x40, 0x3f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf4, 0x32, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x14, 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x1d,
- 0x94, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x91, 0xb0, 0x01, 0x00,
- 0x52, 0x07, 0xa0, 0xfc, 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x91, 0xc0, 0x01, 0x00, 0x50, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0x96, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x48, 0xc1, 0x01, 0x00, 0x02, 0x00, 0x00, 0x18, 0x94, 0xf4, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x18, 0x90, 0xb0, 0x01, 0x00, 0x5c, 0x07, 0xa0, 0xfc,
- 0x90, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00,
- 0x5a, 0x07, 0xa2, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x80, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x2d, 0x00,
- 0x22, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x48, 0xc1, 0x2d, 0x00, 0x64, 0x07, 0x43, 0x30, 0x3d, 0x07, 0x2c, 0x00,
- 0x00, 0x00, 0x00, 0x9e, 0x85, 0xb0, 0x2d, 0x00, 0x00, 0x00, 0x1b, 0x41,
- 0x3d, 0xc3, 0x2d, 0x00, 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x2d, 0x00,
- 0x00, 0x00, 0x00, 0x1e, 0x82, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x2e, 0x1d,
- 0x82, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x18, 0x82, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x80, 0xc0, 0x01, 0x00, 0x6e, 0x07, 0xa0, 0x41,
- 0x80, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0x92, 0xf4, 0x01, 0x00, 0x0a, 0x00, 0x2e, 0x30,
- 0x81, 0x84, 0x01, 0x00, 0x72, 0x07, 0x90, 0x40, 0x92, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
- 0x93, 0xa4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x48, 0xc1, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x19, 0xe8, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1e,
- 0x16, 0xc0, 0x01, 0x00, 0x78, 0x07, 0xa0, 0x19, 0x16, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0d, 0x00, 0x2f, 0x1e,
- 0x32, 0xc0, 0x01, 0x00, 0x7d, 0x07, 0xa2, 0x40, 0x15, 0x6c, 0x00, 0x00,
- 0x7c, 0x07, 0xa0, 0x1c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3, 0x38, 0x94, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x05, 0x48, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x1e,
- 0x98, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x1a, 0x98, 0xc0, 0x01, 0x00,
- 0x0c, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x8b, 0x07, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x89, 0x07, 0x22, 0xf2,
- 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x86, 0x07, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0xe1, 0x91, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x1a, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17,
- 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00,
- 0x91, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x9b, 0x07, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x2d, 0x10, 0x48, 0xc1, 0x01, 0x00, 0x9b, 0x07, 0x22, 0xf2,
- 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x98, 0x07, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xeb, 0x9f, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x20, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00, 0xa1, 0x07, 0x90, 0xf2,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14,
- 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x2a, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xac, 0x07, 0x22, 0xf2, 0x64, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xa9, 0x07, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe3, 0x9f, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
- 0xc9, 0x07, 0x22, 0x40, 0x15, 0x6c, 0x00, 0x00, 0xb4, 0x07, 0xa2, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x1f, 0x90, 0x01, 0x00,
- 0xb3, 0x07, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
- 0x1c, 0xcc, 0x01, 0x00, 0xe4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x3f, 0xc3, 0x01, 0x00, 0xe6, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb7, 0x07, 0xa2, 0x41, 0x87, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1e, 0x3e, 0xc0, 0x01, 0x00, 0xc9, 0x07, 0x22, 0x40,
- 0x15, 0x6c, 0x00, 0x00, 0xba, 0x07, 0x20, 0x1e, 0x14, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x3c, 0xb0, 0x01, 0x00, 0xe5, 0x9f, 0x00, 0x1e,
- 0x24, 0x30, 0x01, 0x00, 0xbf, 0x07, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1a,
- 0x10, 0xc0, 0x01, 0x00, 0x23, 0x07, 0x00, 0x40, 0x17, 0xb0, 0x00, 0x00,
- 0xe4, 0x9f, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe5, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xbc, 0x07, 0xa2, 0x08, 0x2e, 0x30, 0x00, 0x00,
- 0x80, 0x80, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00, 0xe8, 0x9f, 0x00, 0x1f,
- 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
- 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0x99, 0x01, 0x00, 0x04, 0x00, 0x22, 0x04, 0xe0, 0x31, 0x00, 0x00,
- 0xe6, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xce, 0x07, 0xa2, 0x41,
- 0x87, 0x7c, 0x00, 0x00, 0xcf, 0x07, 0x00, 0x1e, 0x3e, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1f, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0xe8, 0x9f, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
- 0xe2, 0x9f, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xf7, 0x07, 0x00, 0xbc, 0x80, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x03, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x03, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00,
- },
- {
- 0x31, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x34, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x35, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0x80, 0x81, 0x80,
- 0x80, 0x32, 0x00, 0x00, 0x0e, 0x87, 0xa2, 0x40, 0x91, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x90, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2,
- 0x80, 0xb0, 0x01, 0x00, 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00,
- 0x90, 0x95, 0x2a, 0xc8, 0xe5, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd0,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd2, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xd3, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xee,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x44, 0xb1, 0x01, 0x00, 0x18, 0x80, 0x11, 0x81,
- 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x51, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x1a, 0x80, 0x11, 0x82, 0x98, 0x30, 0x00, 0x00, 0x00, 0x00, 0x52, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x0e, 0x87, 0x00, 0x48, 0xfd, 0x93, 0x00, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x23, 0x80, 0xa2, 0x42,
- 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x22, 0x80, 0x11, 0x81, 0x82, 0x30, 0x00, 0x00, 0x22, 0x80, 0x51, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x22, 0x80, 0x11, 0x82, 0x82, 0x30, 0x00, 0x00,
- 0x22, 0x80, 0x52, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x80, 0x00, 0x48,
- 0xfd, 0x93, 0x00, 0x00, 0x27, 0x80, 0x00, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x26, 0x80, 0xa2, 0x53, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x51, 0x53,
- 0x07, 0x90, 0x01, 0x00, 0x2a, 0x80, 0x00, 0x52, 0x07, 0x90, 0x00, 0x00,
- 0x29, 0x80, 0xa2, 0x52, 0x07, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x52, 0x52,
- 0x07, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x07, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0xf3, 0x93, 0x01, 0x00, 0x5c, 0x95, 0x2e, 0xa2, 0x52, 0xb3, 0x01, 0x00,
- 0xff, 0x00, 0x00, 0x80, 0xf4, 0x89, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x45, 0xb1, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x4c, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xaf, 0x82, 0x05, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xaf, 0x82, 0x05, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x05, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x4c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0xde, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xfd, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xfd, 0x83, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40,
- 0x9b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00,
- 0x48, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x58, 0x95, 0x20, 0x44,
- 0xe0, 0xb1, 0x01, 0x00, 0x04, 0x94, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x24, 0xb1, 0x01, 0x00, 0x00, 0x0c, 0x00, 0xee,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x97, 0xf0, 0x01, 0x00,
- 0x44, 0x80, 0xa2, 0x43, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xfd, 0x93, 0x01, 0x00, 0x00, 0xc0, 0x00, 0xa6, 0x36, 0xb1, 0x01, 0x00,
- 0xd0, 0x14, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x00, 0x38, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x00, 0x06, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x05, 0x10, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00,
- 0x02, 0x09, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0xf5, 0x99, 0x01, 0x00, 0x60, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x88, 0x03, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xa0, 0x03, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xa2, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x9a, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x60, 0x95, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x70, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x49, 0xdd, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x91, 0xb3, 0x01, 0x00, 0xe0, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb3, 0x01, 0x00, 0x5c, 0x95, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x27, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x90, 0x06, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x2f, 0x81, 0x01, 0x00, 0x8d, 0x81, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xe5, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x45, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x55, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xdd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x41, 0xe1, 0xc1, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0x19, 0x05, 0x22, 0x54, 0x81, 0x7c, 0x00, 0x00,
- 0x6c, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0xb4,
- 0x69, 0xdf, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x18, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x40, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x7d, 0x80, 0x22, 0x40,
- 0x97, 0x6c, 0x00, 0x00, 0x7a, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x54, 0x16, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0xf4, 0xb1, 0x01, 0x00, 0x80, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x80, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58,
- 0x69, 0x93, 0x00, 0x00, 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x40, 0x05, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xf6, 0x15, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x5c, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x6e, 0xfa, 0x8e, 0xb0, 0x01, 0x00, 0xc1, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x96, 0x80, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x96, 0x80, 0x22, 0x40, 0x97, 0x6c, 0x00, 0x00,
- 0x93, 0x80, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x69, 0x93, 0x01, 0x00, 0x38, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
- 0x38, 0x05, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48,
- 0xb2, 0xcb, 0x01, 0x00, 0xd0, 0x05, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x02, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x02, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd4, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd5, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd7, 0x9f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x72, 0x01, 0x00, 0x41,
- 0x81, 0xc0, 0x00, 0x00, 0x55, 0x01, 0x51, 0x48, 0xfd, 0x93, 0x00, 0x00,
- 0x55, 0x01, 0x52, 0x48, 0xfd, 0x93, 0x00, 0x00, 0x55, 0x01, 0x55, 0x49,
- 0xfd, 0x83, 0x00, 0x00, 0x55, 0x01, 0x56, 0x4a, 0xfd, 0x83, 0x00, 0x00,
- 0x50, 0x01, 0x91, 0x81, 0x80, 0x30, 0x00, 0x00, 0x55, 0x01, 0x45, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x50, 0x01, 0x91, 0x82, 0x80, 0x30, 0x00, 0x00,
- 0x55, 0x01, 0x46, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x89, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x00, 0x05,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x48, 0xc1, 0x01, 0x00,
- 0xb4, 0x80, 0x43, 0x30, 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x42, 0xec, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x46, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd2,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0xd0, 0xe1, 0xb1, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x98, 0xb0, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00, 0xb1, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0xc7, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0xa1, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x04, 0x80, 0x94, 0x00, 0x00,
- 0x80, 0x15, 0x3f, 0x42, 0x97, 0xe3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x03, 0x02, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x07, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xcb,
- 0x99, 0xcb, 0x01, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xf3, 0x83, 0x01, 0x00,
- 0xd1, 0x80, 0xa2, 0x42, 0x97, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcb,
- 0xf3, 0x93, 0x01, 0x00, 0xae, 0x03, 0x00, 0xcb, 0xa3, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x20, 0x44, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x04, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
- 0xe0, 0xb1, 0x01, 0x00, 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x20, 0x62, 0xdd, 0x01, 0x00, 0xd8, 0x80, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xf9, 0x02, 0x00, 0x20, 0x42, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x41, 0x05, 0x6c, 0x01, 0x00, 0x00, 0x00, 0x80, 0xcb,
- 0xdb, 0x91, 0x01, 0x00, 0x00, 0x00, 0x19, 0x41, 0x8b, 0xb3, 0x01, 0x00,
- 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xde, 0x80, 0xa8, 0xb1,
- 0x8c, 0x33, 0x00, 0x00, 0x60, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xe0, 0x80, 0xa8, 0xb1, 0x94, 0x33, 0x00, 0x00, 0xe6, 0x80, 0x14, 0xc6,
- 0x81, 0x32, 0x00, 0x00, 0x18, 0x00, 0x00, 0xc6, 0x83, 0xf4, 0x01, 0x00,
- 0xf4, 0x82, 0x22, 0x4f, 0x83, 0x04, 0x00, 0x00, 0xc2, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xff, 0x01, 0x00, 0xc6, 0x81, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xc6, 0x97, 0xa3, 0x01, 0x00, 0xc2, 0x80, 0x1f, 0x5c,
- 0x97, 0x53, 0x00, 0x00, 0x58, 0x82, 0x1e, 0xc6, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x2f, 0x43, 0x81, 0xf0, 0x01, 0x00, 0xec, 0x80, 0x00, 0x40,
- 0x10, 0xc9, 0x00, 0x00, 0x39, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x6a, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x24, 0x82, 0x00, 0xca,
- 0x63, 0xb3, 0x00, 0x00, 0x61, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x48, 0x81, 0x00, 0x4d, 0x83, 0xb0, 0x00, 0x00, 0x52, 0x81, 0x00, 0x4e,
- 0x61, 0xb1, 0x00, 0x00, 0x41, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
- 0x48, 0x81, 0x00, 0x4c, 0x83, 0xb0, 0x00, 0x00, 0x24, 0x81, 0x00, 0x40,
- 0x85, 0xb0, 0x00, 0x00, 0xe3, 0x81, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
- 0x71, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0xdf, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x41, 0x81, 0x00, 0x40, 0x85, 0xb0, 0x00, 0x00,
- 0xf0, 0x03, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca,
- 0x9b, 0xb3, 0x00, 0x00, 0x7b, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
- 0x7f, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x86, 0x81, 0x00, 0x40,
- 0xc1, 0xb1, 0x00, 0x00, 0x87, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00,
- 0x88, 0x81, 0x00, 0x40, 0xc1, 0xb1, 0x00, 0x00, 0x89, 0x81, 0x00, 0x40,
- 0xc1, 0xb1, 0x00, 0x00, 0x8a, 0x81, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
- 0x8a, 0x81, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x18, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x97, 0x82, 0x00, 0xbb, 0xab, 0xb3, 0x00, 0x00,
- 0x25, 0x82, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xc8, 0x03, 0x00, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x26, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf4, 0x82, 0x00, 0xca, 0x77, 0xb3, 0x00, 0x00, 0x49, 0x81, 0x00, 0x4d,
- 0x83, 0xb0, 0x00, 0x00, 0x50, 0x81, 0x00, 0x4e, 0x61, 0xb1, 0x00, 0x00,
- 0x41, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x49, 0x81, 0x00, 0x4c,
- 0x83, 0xb0, 0x00, 0x00, 0x41, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00,
- 0x24, 0x81, 0x00, 0xbb, 0x85, 0xb0, 0x00, 0x00, 0x16, 0x81, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca, 0x4d, 0xb3, 0x00, 0x00,
- 0x70, 0x05, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x40,
- 0x49, 0xb1, 0x00, 0x00, 0x1c, 0x81, 0x22, 0x42, 0x8f, 0x6f, 0x00, 0x00,
- 0x1e, 0x81, 0x22, 0x41, 0x8f, 0x6f, 0x00, 0x00, 0x20, 0x81, 0x1e, 0xca,
- 0x81, 0x32, 0x00, 0x00, 0x22, 0x81, 0x1f, 0xca, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xc9, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x42,
- 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0xcd, 0xb1, 0x01, 0x00,
- 0xf4, 0x82, 0x00, 0x41, 0x8f, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xcf, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00,
- 0x00, 0x81, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6, 0xc6, 0xb1, 0x01, 0x00,
- 0xf4, 0x82, 0x00, 0x40, 0x8f, 0xb3, 0x00, 0x00, 0x78, 0x18, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0x10, 0x00, 0x2f, 0x9c, 0x89, 0xb0, 0x01, 0x00,
- 0x3b, 0x81, 0x00, 0x40, 0x39, 0x33, 0x01, 0x00, 0x18, 0x00, 0x2f, 0x9b,
- 0x89, 0xb0, 0x01, 0x00, 0x3b, 0x81, 0x00, 0x40, 0x37, 0x33, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0x9a, 0x89, 0xb0, 0x01, 0x00, 0x3b, 0x81, 0x00, 0x40,
- 0x35, 0x33, 0x01, 0x00, 0x08, 0x00, 0x2f, 0x99, 0x89, 0xb0, 0x01, 0x00,
- 0x3b, 0x81, 0x00, 0x40, 0x33, 0x33, 0x01, 0x00, 0x00, 0x80, 0x00, 0xae,
- 0x47, 0xc9, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x00, 0x40, 0xe1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xae,
- 0x63, 0xdd, 0x01, 0x00, 0x36, 0x81, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x33, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x36, 0x81, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x69, 0x93, 0x01, 0x00,
- 0xf4, 0x82, 0x1a, 0x44, 0x93, 0x93, 0x00, 0x00, 0x39, 0x81, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x38, 0x81, 0x00, 0x58, 0x69, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x40, 0x81, 0xa2, 0x40, 0xe1, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x41, 0xe1, 0xd1, 0x01, 0x00,
- 0x41, 0x81, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x62, 0xb1, 0x01, 0x00, 0x45, 0x81, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x42, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0x63, 0xb1, 0x01, 0x00, 0x45, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xf4, 0x82, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x4a, 0x81, 0x00, 0x40,
- 0x81, 0xb0, 0x00, 0x00, 0x4a, 0x81, 0x00, 0xbb, 0x81, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x60, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0x4b, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x4d, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x50, 0x95, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x53, 0x81, 0x00, 0xbb,
- 0x87, 0xb0, 0x00, 0x00, 0x50, 0x95, 0x2f, 0x40, 0x87, 0xb0, 0x01, 0x00,
- 0x55, 0x81, 0x22, 0x40, 0x95, 0x7f, 0x00, 0x00, 0xf4, 0x82, 0x60, 0x40,
- 0x95, 0x83, 0x00, 0x00, 0x02, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0x56, 0x81, 0x36, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x62, 0xb1, 0x01, 0x00, 0x57, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x62, 0xb1, 0x01, 0x00, 0x59, 0x81, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xca, 0x63, 0xb1, 0x01, 0x00,
- 0x5b, 0x81, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x16, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xf4, 0x82, 0x22, 0x41, 0x43, 0x51, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0xca, 0x95, 0xcb, 0x01, 0x00, 0x56, 0x81, 0x00, 0x41,
- 0x85, 0xc0, 0x00, 0x00, 0x63, 0x81, 0xa2, 0x42, 0x67, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x67, 0xb3, 0x01, 0x00, 0x63, 0x81, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x65, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x93, 0x83, 0x01, 0x00, 0x00, 0x00, 0x1a, 0xca,
- 0x69, 0x97, 0x01, 0x00, 0xf4, 0x82, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x68, 0x81, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x82, 0x1a, 0x44,
- 0x93, 0x93, 0x00, 0x00, 0xf4, 0x82, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00,
- 0xf4, 0x82, 0x80, 0xca, 0x67, 0x33, 0x00, 0x00, 0xf4, 0x82, 0x22, 0x40,
- 0x65, 0x6f, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
- 0x85, 0x00, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x35, 0x80, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x95, 0x93, 0x01, 0x00, 0x77, 0x81, 0xa2, 0x44, 0x21, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5e,
- 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x95, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0xc3, 0xb1, 0x01, 0x00, 0x7a, 0x81, 0x22, 0x5b,
- 0x95, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xfd, 0x93, 0x01, 0x00,
- 0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1b, 0xfd, 0x00, 0xca,
- 0x95, 0x9b, 0x01, 0x00, 0x0d, 0x01, 0x00, 0xca, 0xc5, 0x31, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x95, 0x83, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca,
- 0xc5, 0xb1, 0x00, 0x00, 0xdf, 0x6f, 0x00, 0xca, 0x95, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x95, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0xca,
- 0xc7, 0xb1, 0x01, 0x00, 0xf4, 0x82, 0x22, 0x5f, 0x95, 0x7f, 0x00, 0x00,
- 0x0d, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x95, 0x83, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca, 0xc7, 0xb1, 0x00, 0x00,
- 0xf4, 0x82, 0x00, 0xca, 0xc9, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca,
- 0xcb, 0xb1, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xca, 0xcd, 0xb1, 0x00, 0x00,
- 0xf4, 0x82, 0x00, 0xca, 0xcf, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x42,
- 0x81, 0xe0, 0x01, 0x00, 0x98, 0x14, 0x00, 0x40, 0x48, 0xc9, 0x01, 0x00,
- 0xf4, 0x82, 0x00, 0xca, 0xe1, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x09, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x8f, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x80, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0x91, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0xa6, 0x08, 0xb1, 0x01, 0x00, 0x93, 0x81, 0x9f, 0x85,
- 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x83, 0x84, 0x01, 0x00,
- 0xc8, 0x81, 0x22, 0x30, 0x83, 0x6c, 0x00, 0x00, 0x92, 0x81, 0xa2, 0x4f,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x21, 0xb3, 0x01, 0x00,
- 0x02, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x10, 0x00, 0x00, 0x41, 0x84, 0xe4, 0x01, 0x00,
- 0x03, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x41, 0x86, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x84, 0x94, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x10, 0xc4, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
- 0xa8, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x21, 0xb3, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x1c, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xa5, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
- 0xba, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x01, 0x00, 0xa6,
- 0x86, 0xb0, 0x01, 0x00, 0x50, 0x0c, 0x00, 0x43, 0x86, 0x98, 0x01, 0x00,
- 0xad, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x21, 0xb3, 0x01, 0x00, 0xba, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x41, 0x01, 0x00, 0xa6, 0x86, 0xb0, 0x01, 0x00, 0x60, 0x0c, 0x00, 0x43,
- 0x86, 0x98, 0x01, 0x00, 0xba, 0x81, 0xa2, 0x43, 0x84, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x21, 0xb3, 0x01, 0x00, 0x18, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x41, 0x82, 0x88, 0x01, 0x00, 0x00, 0x77, 0x00, 0x41,
- 0x82, 0x8c, 0x01, 0x00, 0x01, 0x02, 0x00, 0x41, 0x82, 0x98, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x18, 0x00, 0x00, 0x41,
- 0x82, 0xdc, 0x01, 0x00, 0xb8, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0xbb, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00,
- 0x40, 0x13, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0xc3, 0x81, 0x22, 0x43,
- 0x21, 0x6f, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0xc0, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x04, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00,
- 0xde, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x19, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
- 0xc5, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0xde, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x21, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x83, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
- 0x83, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
- 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x83, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xc2, 0xb1, 0x01, 0x00,
- 0x0c, 0x01, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x11, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00,
- 0xd7, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0xda, 0x81, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x40, 0x13, 0x00, 0x41,
- 0x08, 0x99, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x41, 0x2e, 0x99, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xca, 0x81, 0x94, 0x01, 0x00, 0xe1, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40, 0x08, 0xb1, 0x00, 0x00,
- 0xc8, 0x14, 0x2e, 0xbb, 0x85, 0xb0, 0x01, 0x00, 0xe4, 0x81, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00,
- 0xf3, 0x81, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00, 0x02, 0x82, 0x22, 0x44,
- 0x21, 0x6f, 0x00, 0x00, 0x11, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00,
- 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x4a,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00,
- 0xee, 0x81, 0x22, 0x4d, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x87, 0x90, 0x01, 0x00, 0xf0, 0x81, 0x22, 0x4f, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0xf2, 0x81, 0x22, 0x4e,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
- 0x0a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x1c, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xfd, 0x81, 0x22, 0x45, 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x87, 0x90, 0x01, 0x00, 0xff, 0x81, 0x22, 0x44, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x87, 0x90, 0x01, 0x00, 0x01, 0x82, 0x22, 0x43,
- 0x83, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x87, 0x90, 0x01, 0x00,
- 0x0a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x01, 0x80, 0x00, 0xa6,
- 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x01, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0a, 0x82, 0x22, 0x42, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x87, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x87, 0x90, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0xa6, 0x82, 0xb0, 0x01, 0x00, 0x13, 0x82, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x82, 0x22, 0x4b, 0x83, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xe0, 0xb1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0xa2, 0xa0, 0x8b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xa5, 0xb3, 0x01, 0x00, 0xb8, 0x80, 0x00, 0xca,
- 0xa7, 0x33, 0x01, 0x00, 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x41, 0x82, 0xdc, 0x01, 0x00, 0x14, 0x82, 0xa2, 0x5e,
- 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x08, 0xb1, 0x01, 0x00,
- 0x16, 0x82, 0x9f, 0x85, 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x1b, 0x82, 0x14, 0xf7, 0x81, 0x30, 0x00, 0x00,
- 0x1b, 0x82, 0xa2, 0x49, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xfd, 0x93, 0x01, 0x00, 0x1e, 0x82, 0x15, 0xf8, 0x81, 0x14, 0x00, 0x00,
- 0x1e, 0x82, 0xa2, 0x4a, 0xfd, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xfd, 0x93, 0x01, 0x00, 0x20, 0x82, 0xa2, 0xc8, 0x81, 0x32, 0x00, 0x00,
- 0x40, 0x00, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x00, 0x10, 0x00, 0x40,
- 0x80, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xef, 0xb3, 0x01, 0x00,
- 0x22, 0x82, 0x42, 0x40, 0xf1, 0x33, 0x00, 0x00, 0x38, 0x81, 0x00, 0x40,
- 0x68, 0x97, 0x00, 0x00, 0xf4, 0x82, 0x00, 0xbb, 0x6b, 0xb3, 0x00, 0x00,
- 0xf4, 0x82, 0x00, 0xbb, 0xb1, 0xb3, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x03, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x18, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x42, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x43, 0xff,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x18, 0xb1, 0x01, 0x00, 0x2b, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x19, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x43, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x81, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf6, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x43, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x35, 0x82, 0xa2, 0x54,
- 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00, 0x3c, 0x82, 0xa2, 0x06,
- 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x16, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x80, 0x16, 0x2e, 0x06,
- 0x83, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0x42, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x22, 0x00, 0x00, 0x40,
- 0x83, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0xf6, 0xb1, 0x01, 0x00,
- 0x45, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x62, 0x00, 0x00, 0x40,
- 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x16, 0x2d, 0x06, 0x83, 0xb0, 0x01, 0x00, 0x80, 0x16, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x5c, 0x00, 0x00, 0xfb, 0xf6, 0xa9, 0x01, 0x00,
- 0x4b, 0x82, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x71, 0xf9, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x72, 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x73,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x74, 0xf9, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x00, 0x40, 0x95, 0x98, 0x01, 0x00, 0xdc, 0x9f, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xb0, 0x01, 0x00,
- 0x57, 0x82, 0x22, 0x70, 0xb5, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x42,
- 0x99, 0xb3, 0x01, 0x00, 0x62, 0x82, 0x22, 0x44, 0x81, 0x6c, 0x00, 0x00,
- 0x6a, 0x82, 0x22, 0x48, 0x81, 0x6c, 0x00, 0x00, 0x64, 0x82, 0x22, 0x4c,
- 0x81, 0x6c, 0x00, 0x00, 0x6e, 0x82, 0x22, 0x50, 0x81, 0x6c, 0x00, 0x00,
- 0x6f, 0x82, 0x22, 0x54, 0x81, 0x6c, 0x00, 0x00, 0x71, 0x82, 0x22, 0x58,
- 0x81, 0x6c, 0x00, 0x00, 0x76, 0x82, 0x22, 0x5c, 0x81, 0x6c, 0x00, 0x00,
- 0x50, 0x01, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc,
- 0x09, 0xb0, 0x01, 0x00, 0xf4, 0x82, 0x00, 0xca, 0x01, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xf3, 0x83, 0x01, 0x00, 0x68, 0x82, 0xa2, 0x42, 0x05, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x05, 0xb0, 0x01, 0x00, 0xf4, 0x82, 0x22, 0xca,
- 0x07, 0x14, 0x00, 0x00, 0xf4, 0x82, 0x00, 0x46, 0xf3, 0x93, 0x00, 0x00,
- 0xf4, 0x82, 0x20, 0x43, 0x95, 0x6f, 0x00, 0x00, 0xf4, 0x82, 0x80, 0xca,
- 0x05, 0x30, 0x00, 0x00, 0xf4, 0x82, 0x22, 0x01, 0x80, 0x30, 0x00, 0x00,
- 0xf4, 0x82, 0x00, 0xcb, 0xdb, 0x91, 0x00, 0x00, 0x57, 0x01, 0x00, 0xbc,
- 0xab, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0xb1, 0xb3, 0x01, 0x00,
- 0xf4, 0x82, 0x00, 0xca, 0xcf, 0xb3, 0x00, 0x00, 0xff, 0x00, 0x00, 0xca,
- 0x81, 0x88, 0x01, 0x00, 0xf4, 0x82, 0xa2, 0x40, 0x74, 0x7d, 0x00, 0x00,
- 0x60, 0x00, 0x20, 0x40, 0x60, 0x99, 0x01, 0x00, 0x73, 0x82, 0xa8, 0xb1,
- 0x82, 0x30, 0x00, 0x00, 0x72, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf4, 0x82, 0x00, 0xca, 0x79, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0xcb, 0x83, 0x01, 0x00,
- 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x79, 0x82, 0xa2, 0x41,
- 0x81, 0x50, 0x00, 0x00, 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x45, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x84, 0x82, 0x91, 0x82,
- 0x82, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x80, 0xb0, 0x01, 0x00,
- 0xae, 0x9f, 0x00, 0x40, 0x80, 0xce, 0x01, 0x00, 0x82, 0x82, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x84, 0x82, 0x56, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53,
- 0x07, 0x90, 0x01, 0x00, 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41,
- 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x81, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xcd, 0x83, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x89, 0x82, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x46, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x46, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x94, 0x82, 0x91, 0x81, 0x82, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x89, 0x80, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
- 0x80, 0xce, 0x01, 0x00, 0x92, 0x82, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x94, 0x82, 0x55, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb6, 0x03, 0x00, 0x40,
- 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x52, 0x07, 0x90, 0x01, 0x00,
- 0xb6, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53,
- 0x07, 0x90, 0x01, 0x00, 0xd8, 0x9f, 0x00, 0x41, 0x8b, 0xb3, 0x00, 0x00,
- 0xb1, 0x03, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00, 0xc4, 0x14, 0x2f, 0x40,
- 0x99, 0xb3, 0x01, 0x00, 0x57, 0x01, 0x00, 0x40, 0x49, 0xb1, 0x00, 0x00,
- 0xa0, 0x94, 0x2e, 0x43, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x9b, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x50, 0x95, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xac, 0x94, 0x2e, 0x43,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x9f, 0x82, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xae, 0x03, 0x00, 0x40, 0xa3, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x60, 0x15, 0x00, 0x40,
- 0x85, 0x98, 0x01, 0x00, 0x08, 0x00, 0x00, 0x40, 0x40, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x59, 0x41, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x41, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x40, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x57, 0x41, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x42, 0x81, 0x6c, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00, 0xa5, 0x82, 0xa0, 0x42,
- 0x81, 0x6c, 0x00, 0x00, 0xa5, 0x82, 0x00, 0x50, 0x85, 0xc0, 0x00, 0x00,
- 0xdd, 0x82, 0xa2, 0x41, 0x01, 0x7d, 0x00, 0x00, 0xb5, 0x82, 0x22, 0x58,
- 0x73, 0x7d, 0x00, 0x00, 0x78, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xb0, 0x82, 0xa8, 0xb1, 0x9c, 0x30, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45,
- 0x9d, 0xe0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0e, 0x10, 0xc9, 0x00, 0x00,
- 0xb5, 0x82, 0x33, 0xc4, 0x81, 0x30, 0x00, 0x00, 0xb8, 0x82, 0xa1, 0xad,
- 0x9d, 0x20, 0x00, 0x00, 0xaf, 0x82, 0x13, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x13, 0x4e, 0x5a, 0x83, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45,
- 0x9d, 0xe0, 0x01, 0x00, 0xc0, 0x82, 0x22, 0xab, 0x80, 0x04, 0x00, 0x00,
- 0xbe, 0x82, 0xa2, 0x40, 0x01, 0x7d, 0x00, 0x00, 0xc0, 0x82, 0x22, 0x5f,
- 0x57, 0x7d, 0x00, 0x00, 0x36, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc0, 0x82, 0x22, 0x5e, 0x57, 0x7d, 0x00, 0x00, 0x99, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc5, 0x82, 0x22, 0x54, 0x73, 0x7d, 0x00, 0x00,
- 0x74, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xc0, 0x82, 0xa8, 0xb1,
- 0x00, 0x30, 0x00, 0x00, 0x8a, 0x84, 0xa2, 0x5f, 0x01, 0x7c, 0x00, 0x00,
- 0xca, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc7, 0x82, 0xa2, 0x5f,
- 0x59, 0x27, 0x00, 0x00, 0xc9, 0x82, 0xa2, 0x5c, 0x73, 0x7d, 0x00, 0x00,
- 0xd0, 0x82, 0xa2, 0x5e, 0x73, 0x7d, 0x00, 0x00, 0xda, 0x82, 0x22, 0x5c,
- 0x73, 0x7d, 0x00, 0x00, 0xdb, 0x82, 0x37, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xca, 0x82, 0xa8, 0xb1,
- 0x36, 0x30, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xcc, 0x82, 0xa8, 0xb1, 0x00, 0x30, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00,
- 0x02, 0x88, 0x01, 0x00, 0xb9, 0x84, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xdb, 0x82, 0x34, 0x40, 0x81, 0x32, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xd1, 0x82, 0xa8, 0xb1, 0x12, 0x30, 0x00, 0x00,
- 0xd8, 0x82, 0x52, 0x21, 0x13, 0x04, 0x00, 0x00, 0x00, 0x00, 0x14, 0x41,
- 0x2f, 0xc3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0x09, 0x00, 0x8c, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x01, 0xf0, 0x01, 0x00, 0x11, 0x83, 0x00, 0x34,
- 0x13, 0x84, 0x00, 0x00, 0xff, 0x3f, 0x14, 0x09, 0x00, 0x8c, 0x01, 0x00,
- 0x6f, 0x83, 0x00, 0x43, 0x01, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xdb, 0x82, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0x0e, 0x87, 0xa2, 0x48,
- 0xfd, 0x7f, 0x00, 0x00, 0x04, 0x00, 0xa2, 0xac, 0x80, 0x32, 0x00, 0x00,
- 0xe3, 0x82, 0x22, 0x5a, 0x73, 0x7d, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xe0, 0x82, 0xa8, 0xb1, 0x7e, 0x31, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0xcf, 0x11, 0xc9, 0x00, 0x00, 0xe9, 0x82, 0xa2, 0x40,
- 0x93, 0x7f, 0x00, 0x00, 0xe9, 0x82, 0x22, 0x44, 0x93, 0x7f, 0x00, 0x00,
- 0xe5, 0x82, 0x42, 0xa5, 0x80, 0x30, 0x00, 0x00, 0xe8, 0x82, 0xa2, 0x40,
- 0x93, 0x7f, 0x00, 0x00, 0xfb, 0x82, 0x1a, 0x40, 0x93, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x1a, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xdd, 0x80, 0xa2, 0x40,
- 0x73, 0x7d, 0x00, 0x00, 0x09, 0x87, 0x22, 0x44, 0x21, 0x6f, 0x00, 0x00,
- 0x00, 0x87, 0x22, 0x40, 0x65, 0x7d, 0x00, 0x00, 0x00, 0x05, 0xa2, 0x5b,
- 0x73, 0x7d, 0x00, 0x00, 0x04, 0x00, 0xa2, 0x49, 0x33, 0x7d, 0x00, 0x00,
- 0xf3, 0x82, 0x22, 0x48, 0x33, 0x7d, 0x00, 0x00, 0xff, 0x01, 0x00, 0x99,
- 0x80, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x81, 0xe0, 0x01, 0x00,
- 0xa8, 0x98, 0x2f, 0x40, 0x33, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe0, 0xc1, 0x01, 0x00, 0xdd, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x40, 0x8b, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x62, 0xb1, 0x01, 0x00,
- 0xaf, 0x82, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf6, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xf9, 0x82, 0x33, 0x40, 0x1f, 0x30, 0x00, 0x00,
- 0xaf, 0x82, 0x13, 0x4e, 0x5a, 0x93, 0x00, 0x00, 0xfd, 0x82, 0xa0, 0xce,
- 0x81, 0x50, 0x00, 0x00, 0x0f, 0x83, 0xa0, 0xcd, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa5, 0x9c, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
- 0x81, 0xb0, 0x01, 0x00, 0x0f, 0x83, 0x22, 0xb5, 0x81, 0x14, 0x00, 0x00,
- 0x80, 0x15, 0x2f, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x01, 0x83, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x60, 0xb4, 0x65, 0x97, 0x01, 0x00,
- 0xd0, 0x15, 0x2e, 0x40, 0x69, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x44,
- 0x93, 0x83, 0x01, 0x00, 0x1a, 0x00, 0x00, 0xa2, 0x80, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb1,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xf1, 0xb1, 0x01, 0x00,
- 0x05, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x80, 0x00, 0x00, 0x40,
- 0x62, 0xdd, 0x01, 0x00, 0x0a, 0x83, 0xa8, 0xa1, 0xe0, 0x31, 0x00, 0x00,
- 0xe9, 0x82, 0x00, 0x88, 0x9e, 0xb3, 0x00, 0x00, 0xe9, 0x82, 0xa2, 0x41,
- 0x67, 0x6f, 0x00, 0x00, 0xe9, 0x82, 0x00, 0x6f, 0xdb, 0x91, 0x00, 0x00,
- 0x0f, 0x83, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0xe9, 0x82, 0x1a, 0x40,
- 0x93, 0x83, 0x00, 0x00, 0x00, 0x99, 0x00, 0x09, 0x46, 0xc9, 0x01, 0x00,
- 0x3f, 0x00, 0x00, 0xf3, 0x0c, 0x88, 0x01, 0x00, 0x1a, 0x83, 0xa6, 0x42,
- 0x13, 0x60, 0x00, 0x00, 0x12, 0x94, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
- 0x15, 0x83, 0x61, 0x40, 0x81, 0x32, 0x00, 0x00, 0x75, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x16, 0x83, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
- 0x1f, 0x94, 0x71, 0x10, 0x94, 0x30, 0x01, 0x00, 0x1b, 0x83, 0x00, 0x58,
- 0x1f, 0x90, 0x00, 0x00, 0x05, 0x94, 0x00, 0x95, 0x03, 0x30, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x2d, 0xf0, 0x2e, 0xb0, 0x01, 0x00,
- 0xee, 0x07, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x22, 0x83, 0x23, 0x4b,
- 0xe4, 0x6d, 0x00, 0x00, 0x22, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x22, 0x00, 0x2f, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x25, 0x83, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x26, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x27, 0x83, 0x85, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x47, 0xc1, 0x01, 0x00,
- 0x2c, 0x83, 0x22, 0x55, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x43, 0xd1, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x97, 0xe0, 0x01, 0x00, 0x2d, 0x83, 0x00, 0x4b,
- 0x44, 0xc1, 0x00, 0x00, 0x12, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0xf6, 0x02, 0xcc, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa1,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x28, 0xf0, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x2a, 0xb0, 0x01, 0x00,
- 0xc0, 0x28, 0x3c, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x44,
- 0x95, 0xb0, 0x01, 0x00, 0x39, 0x83, 0xa2, 0xf8, 0x0e, 0x30, 0x00, 0x00,
- 0x49, 0x83, 0x22, 0x41, 0x95, 0x50, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0x35, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x36, 0x83, 0xa2, 0xf8, 0x16, 0x6c, 0x00, 0x00, 0x36, 0x83, 0xa2, 0xf8,
- 0x10, 0x6c, 0x00, 0x00, 0x36, 0x83, 0xa2, 0xf0, 0x1a, 0x6c, 0x00, 0x00,
- 0x47, 0x83, 0x22, 0x58, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
- 0x13, 0xf0, 0x01, 0x00, 0x3e, 0x83, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x42, 0x83, 0xa2, 0xf3, 0x74, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0xe6, 0x95, 0x01, 0x00, 0x47, 0x83, 0x75, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x96, 0xb0, 0x01, 0x00, 0x3f, 0x00, 0x75, 0xf3,
- 0x0c, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x45, 0x83, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x47, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x4f, 0x83, 0x77, 0x41, 0x2d, 0xc3, 0x00, 0x00, 0x4d, 0x83, 0x22, 0x58,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x62, 0xb1, 0x01, 0x00, 0x4b, 0x83, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x4d, 0x83, 0x67, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x7c, 0x83, 0x77, 0x41, 0x2d, 0xc3, 0x00, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
- 0x5d, 0x83, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x55, 0x83, 0x22, 0x42,
- 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x5c, 0x83, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0xcc, 0x93, 0x00, 0x5f,
- 0x01, 0x10, 0x01, 0x00, 0x5b, 0x83, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
- 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40,
- 0x0f, 0xb0, 0x00, 0x00, 0x65, 0x83, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
- 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x65, 0x83, 0x22, 0x20,
- 0x85, 0x6c, 0x00, 0x00, 0x62, 0x83, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x68, 0x83, 0x82, 0xf0, 0x18, 0x30, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x45,
- 0x8f, 0xb0, 0x00, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
- 0x6c, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x4b,
- 0x95, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x4b, 0x8f, 0xb0, 0x00, 0x00,
- 0xd8, 0x93, 0x00, 0x03, 0x48, 0x31, 0x01, 0x00, 0xb4, 0x91, 0x00, 0x40,
- 0x81, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0x50,
- 0x03, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x77, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10,
- 0x62, 0xc9, 0x01, 0x00, 0x79, 0x83, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x0f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x2e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x00, 0x41, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00, 0xee, 0x07, 0x2e, 0x47,
- 0x97, 0x90, 0x01, 0x00, 0x8f, 0x83, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00,
- 0x8d, 0x83, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x8d, 0x83, 0x23, 0xa2,
- 0x02, 0x6c, 0x00, 0x00, 0x41, 0x93, 0x00, 0x52, 0x95, 0x30, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x00, 0x2d, 0x00,
- 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x03, 0xb0, 0x01, 0x00, 0xac, 0x83, 0x00, 0x5c,
- 0x17, 0x90, 0x00, 0x00, 0xa1, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x9a, 0x83, 0x22, 0x5f,
- 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0xf1, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
- 0xf0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
- 0x96, 0x83, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x97, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x72, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0xff, 0x0f, 0x00, 0xf6, 0x80, 0x88, 0x01, 0x00,
- 0x9e, 0x83, 0xa2, 0xa6, 0x81, 0x6c, 0x00, 0x00, 0xa1, 0x83, 0x00, 0xf2,
- 0x3a, 0xb0, 0x00, 0x00, 0x87, 0x84, 0xa2, 0x4b, 0xfd, 0x7f, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2a, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xac, 0x83, 0x22, 0x4a, 0x2f, 0x7c, 0x00, 0x00,
- 0xac, 0x83, 0x22, 0x48, 0x2f, 0x7c, 0x00, 0x00, 0x0a, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x3f, 0x00, 0x00, 0xf2, 0x86, 0x88, 0x01, 0x00,
- 0x1f, 0x00, 0x00, 0x43, 0x84, 0x88, 0x01, 0x00, 0x05, 0x00, 0x00, 0x43,
- 0x80, 0xf4, 0x01, 0x00, 0x98, 0x94, 0x3d, 0x42, 0x81, 0xe0, 0x01, 0x00,
- 0xac, 0x83, 0xa2, 0x42, 0xe0, 0x7d, 0x00, 0x00, 0x87, 0x84, 0xa2, 0x4b,
- 0xfd, 0x7f, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x83, 0x69, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x09, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x79, 0x41, 0x47, 0xc3, 0x01, 0x00, 0xb2, 0x83, 0x22, 0xa1,
- 0x09, 0x6c, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xaf, 0x83, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00, 0xeb, 0x83, 0xa3, 0x92,
- 0x03, 0x6c, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x2a, 0x87, 0x22, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0xb8, 0x83, 0x22, 0x5c, 0x17, 0x7c, 0x00, 0x00,
- 0xb9, 0x83, 0x00, 0x00, 0x2a, 0xb0, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x2a, 0xc8, 0x01, 0x00, 0x02, 0x00, 0x00, 0x08, 0x80, 0xc8, 0x01, 0x00,
- 0xbd, 0x83, 0xa2, 0x43, 0x2f, 0x7c, 0x00, 0x00, 0xcc, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd9, 0x83, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x4c,
- 0x03, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00,
- 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01,
- 0xf0, 0xcd, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xc6, 0x83, 0xa8, 0x54,
- 0x17, 0x10, 0x00, 0x00, 0xd9, 0x83, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
- 0x12, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0xd8, 0x83, 0x22, 0x43,
- 0x2f, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x01, 0x8c, 0xcc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x03, 0xb0, 0x01, 0x00, 0xed, 0x94, 0x00, 0x43,
- 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x02, 0xb0, 0x01, 0x00,
- 0x10, 0x80, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x01,
- 0xf0, 0xcd, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x09, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x15,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xd9, 0x83, 0x28, 0x54,
- 0x17, 0x10, 0x00, 0x00, 0xd5, 0x83, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xdb, 0x83, 0x22, 0x50,
- 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x17, 0x90, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00, 0xde, 0x83, 0xa2, 0x41,
- 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x17, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xdf, 0x83, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xd4, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xe6, 0x83, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
- 0x16, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1d,
- 0xe4, 0xb1, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00,
- 0xe9, 0x83, 0xa2, 0x5f, 0x2f, 0x7c, 0x00, 0x00, 0x90, 0x91, 0x00, 0x01,
- 0x38, 0x43, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xed, 0x83, 0xa2, 0x4b,
- 0xfd, 0x7f, 0x00, 0x00, 0x84, 0x84, 0x00, 0x41, 0x43, 0xc3, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x11, 0xb0, 0x01, 0x00, 0xef, 0x83, 0x35, 0x01, 0x86, 0x30, 0x00, 0x00,
- 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xf6, 0x83, 0x28, 0xb1,
- 0x30, 0x30, 0x00, 0x00, 0xf0, 0x83, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
- 0x74, 0x84, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x43, 0xc3, 0x01, 0x00, 0x83, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xf6, 0x83, 0xa8, 0xb1,
- 0x12, 0x30, 0x00, 0x00, 0xff, 0x83, 0xa2, 0x40, 0x11, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x43, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0x2c, 0xb0, 0x01, 0x00,
- 0xde, 0x07, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00, 0xf0, 0x83, 0xaa, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x04, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x40, 0x00, 0x3e, 0x43, 0x27, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x27, 0xc0, 0x01, 0x00, 0xf0, 0x83, 0xa3, 0x0b,
- 0x87, 0x50, 0x00, 0x00, 0x00, 0x00, 0x15, 0x40, 0x1b, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x00,
- 0x2a, 0xc8, 0x01, 0x00, 0x40, 0x00, 0x2d, 0x40, 0x39, 0xb0, 0x01, 0x00,
- 0x0c, 0x84, 0xa2, 0x40, 0x27, 0x6c, 0x00, 0x00, 0x22, 0x00, 0x00, 0x08,
- 0x12, 0xc8, 0x01, 0x00, 0xde, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
- 0x0f, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x12, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x30, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x32, 0xb0, 0x01, 0x00, 0x14, 0x00, 0x20, 0x01, 0xe0, 0xb1, 0x01, 0x00,
- 0xee, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0x14, 0x84, 0x23, 0x01,
- 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x36, 0xb0, 0x01, 0x00,
- 0x1f, 0x84, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x1b, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x18, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb8, 0x92, 0x00, 0x43,
- 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x44, 0xc9, 0x01, 0x00,
- 0x2e, 0x84, 0x22, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x25, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x25, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x4c,
- 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x37, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x2b, 0xc0, 0x01, 0x00, 0x14, 0x84, 0x00, 0x45,
- 0x1f, 0x80, 0x00, 0x00, 0x30, 0x84, 0xa3, 0x12, 0x36, 0x6c, 0x00, 0x00,
- 0x31, 0x84, 0x68, 0x1b, 0x28, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12,
- 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x34, 0x84, 0xa8, 0x15, 0xe0, 0x31, 0x00, 0x00, 0x5a, 0x84, 0x22, 0x14,
- 0x02, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x14,
- 0x12, 0xc0, 0x01, 0x00, 0x53, 0x84, 0xa2, 0x14, 0x36, 0x50, 0x00, 0x00,
- 0x44, 0x84, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00, 0x30, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x42, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x3f, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xf0, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x2b, 0x80, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00,
- 0x49, 0x84, 0x23, 0x01, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x36, 0xb0, 0x01, 0x00, 0x54, 0x84, 0x22, 0x1b, 0x02, 0x6c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x5c,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15,
- 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x50, 0x84, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x54, 0x84, 0x00, 0x03, 0x48, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x2a, 0xc0, 0x01, 0x00, 0x14, 0x84, 0xa2, 0x40,
- 0x25, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x39, 0xc0, 0x01, 0x00,
- 0x40, 0x00, 0x3d, 0x43, 0x39, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x25, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0xb0, 0x01, 0x00,
- 0x14, 0x84, 0x00, 0xf0, 0x30, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0x60, 0x84, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19,
- 0x62, 0xdd, 0x01, 0x00, 0x5d, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xb8, 0x92, 0x00, 0x40,
- 0x2b, 0x30, 0x01, 0x00, 0x18, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x64, 0x84, 0x22, 0x50, 0x2f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56,
- 0x17, 0x90, 0x01, 0x00, 0x07, 0x00, 0x00, 0x17, 0x98, 0x88, 0x01, 0x00,
- 0x67, 0x84, 0xa2, 0x41, 0x99, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55,
- 0x17, 0x90, 0x01, 0x00, 0x6a, 0x84, 0x22, 0x43, 0x2f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x17, 0x90, 0x01, 0x00, 0x16, 0x00, 0x20, 0x1d,
- 0xe4, 0xb1, 0x01, 0x00, 0x6c, 0x84, 0xa3, 0x40, 0x27, 0x6c, 0x00, 0x00,
- 0x6e, 0x84, 0x60, 0x5f, 0x17, 0x90, 0x00, 0x00, 0x00, 0x84, 0x00, 0x0b,
- 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x60, 0x13, 0x16, 0x94, 0x01, 0x00,
- 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x2a, 0x87, 0xa2, 0x5f,
- 0x2f, 0x7c, 0x00, 0x00, 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x90, 0x91, 0x00, 0x01,
- 0x38, 0x43, 0x01, 0x00, 0x2a, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0x62, 0xb1, 0x01, 0x00,
- 0x76, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x62, 0xb1, 0x01, 0x00, 0x78, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x83, 0x84, 0x22, 0x13, 0x82, 0x6c, 0x00, 0x00, 0x40, 0x00, 0x3d, 0x43,
- 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16,
- 0x62, 0xb1, 0x01, 0x00, 0x7e, 0x84, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x62, 0xb1, 0x01, 0x00, 0x80, 0x84, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x7a, 0x84, 0x00, 0x41, 0x83, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x15, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x82, 0x00, 0xa6,
- 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0x2a, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0x01, 0x80, 0x01, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0e, 0xf4, 0x01, 0x00,
- 0x3f, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07, 0x16, 0x30, 0x01, 0x00,
- 0x95, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00, 0x93, 0x84, 0x22, 0x42,
- 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x94, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40,
- 0x0f, 0xb0, 0x00, 0x00, 0x9d, 0x84, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
- 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x9d, 0x84, 0x22, 0x20,
- 0x85, 0x6c, 0x00, 0x00, 0x9a, 0x84, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0xa3, 0x84, 0x22, 0x3a,
- 0x01, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0xb0, 0x01, 0x00,
- 0x7b, 0x88, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xa7, 0x84, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x01, 0xb0, 0x00, 0x00,
- 0x1e, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x05, 0x94, 0x00, 0x95,
- 0x03, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0,
- 0x2e, 0xb0, 0x01, 0x00, 0x28, 0x20, 0x00, 0xa6, 0x96, 0xb0, 0x01, 0x00,
- 0xb0, 0x84, 0x22, 0x17, 0x96, 0x04, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x4b,
- 0x95, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x4c, 0x8f, 0xb0, 0x00, 0x00,
- 0xb2, 0x84, 0x83, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x43, 0xc1, 0x01, 0x00, 0xb4, 0x84, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0x43, 0xc1, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf6,
- 0x02, 0xcc, 0x01, 0x00, 0x12, 0x00, 0x00, 0xa1, 0x2a, 0xc8, 0x01, 0x00,
- 0xd8, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb4, 0x91, 0x00, 0x41,
- 0x81, 0x30, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0xbe, 0x84, 0x64, 0x47, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0xbf, 0x84, 0xa8, 0x1b,
- 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x74, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x03, 0xe0, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0xe4, 0x84, 0x01, 0xfb, 0x08, 0x30, 0x00, 0x00,
- 0x37, 0x85, 0x87, 0xfb, 0x22, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa,
- 0x0e, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x14, 0xb0, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07,
- 0x16, 0x30, 0x01, 0x00, 0xda, 0x84, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
- 0xce, 0x84, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xd9, 0x84, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
- 0x38, 0x00, 0x00, 0x04, 0x7e, 0x89, 0x01, 0x00, 0xd2, 0x84, 0xa6, 0x5f,
- 0x0f, 0x00, 0x00, 0x00, 0x2c, 0x92, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00,
- 0xd7, 0x84, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x13, 0x00, 0x00, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x0c, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x84, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40, 0x05, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
- 0x0f, 0xb0, 0x00, 0x00, 0xe2, 0x84, 0xa2, 0x5a, 0x1f, 0x7c, 0x00, 0x00,
- 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xe2, 0x84, 0x22, 0x20,
- 0x85, 0x6c, 0x00, 0x00, 0xdf, 0x84, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x33, 0x93, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42, 0x61, 0x31, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x90, 0x04, 0x00, 0x07,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00, 0xe6, 0x84, 0x21, 0x04,
- 0x80, 0x20, 0x00, 0x00, 0xe7, 0x84, 0x00, 0x40, 0x10, 0xc9, 0x00, 0x00,
- 0xbd, 0x87, 0x00, 0x4b, 0x81, 0xb0, 0x00, 0x00, 0x06, 0x85, 0x00, 0x43,
- 0x81, 0xb0, 0x00, 0x00, 0x0a, 0x85, 0x00, 0xfb, 0x22, 0xb0, 0x00, 0x00,
- 0xbd, 0x87, 0x00, 0x41, 0x81, 0xb0, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x4e,
- 0x8f, 0xb0, 0x00, 0x00, 0x02, 0x85, 0x00, 0x5a, 0x8f, 0xb0, 0x00, 0x00,
- 0xef, 0x84, 0x00, 0x47, 0x8f, 0xb0, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x53,
- 0x81, 0xb0, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x56, 0x81, 0xb0, 0x00, 0x00,
- 0x32, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x7b, 0x88, 0xa0, 0x0a,
- 0xe4, 0x6d, 0x00, 0x00, 0xf5, 0x84, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xf4, 0x84, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x53,
- 0x8f, 0xb0, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x54, 0x8f, 0xb0, 0x00, 0x00,
- 0xfe, 0x84, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0xf8, 0x84, 0xa2, 0x0a,
- 0xe4, 0x6d, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x5d, 0x8f, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x80, 0xd0, 0x01, 0x00, 0xfc, 0x84, 0xa0, 0x91, 0x81, 0x6c, 0x00, 0x00,
- 0x7b, 0x88, 0x00, 0x5e, 0x8f, 0xb0, 0x00, 0x00, 0x25, 0x00, 0x00, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x85, 0x20, 0x91, 0xe5, 0x6d, 0x00, 0x00, 0x7b, 0x88, 0x00, 0x54,
- 0x8f, 0xb0, 0x00, 0x00, 0x21, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x7b, 0x88, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x32, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x7b, 0x88, 0xa0, 0x0a, 0xe4, 0x6d, 0x00, 0x00,
- 0x24, 0x00, 0x00, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x7b, 0x88, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x82, 0xf4, 0x01, 0x00, 0xbd, 0x87, 0xa0, 0x42,
- 0x83, 0x6c, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x54, 0x81, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00, 0x13, 0x85, 0x22, 0x0b,
- 0xe6, 0x7d, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0xc6, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0f, 0xb0, 0x01, 0x00, 0x14, 0x87, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0x25, 0x85, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0x20, 0x85, 0xa2, 0x54,
- 0xfd, 0x7f, 0x00, 0x00, 0x18, 0x85, 0x22, 0x55, 0xfd, 0x7f, 0x00, 0x00,
- 0x82, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x10, 0x85, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x10, 0x85, 0x22, 0x53, 0xfd, 0x7f, 0x00, 0x00,
- 0x14, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x96, 0xb0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4b, 0x80, 0xf4, 0x01, 0x00,
- 0x0c, 0xbc, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x20, 0x85, 0x22, 0x43,
- 0x80, 0x6c, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4b, 0x80, 0x88, 0x01, 0x00,
- 0x10, 0x85, 0xa2, 0x43, 0x80, 0x6c, 0x00, 0x00, 0x7c, 0x96, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x21, 0x85, 0x46, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x24, 0x85, 0xa0, 0xf0, 0x30, 0x6f, 0x00, 0x00, 0x16, 0x85, 0x1e, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41, 0x31, 0xc3, 0x01, 0x00,
- 0x5d, 0x92, 0x00, 0x40, 0x25, 0x30, 0x01, 0x00, 0x29, 0x85, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x33, 0x93, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x14, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x96, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x18, 0xe4, 0x01, 0x00, 0x00, 0x08, 0x00, 0x0c, 0xe0, 0x99, 0x01, 0x00,
- 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x46, 0xc9, 0x01, 0x00, 0x30, 0x85, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x02, 0x00, 0xa1,
- 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
- 0x04, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0xbd, 0x87, 0x00, 0x40, 0x81, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x28, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x14, 0xb0, 0x01, 0x00,
- 0x41, 0x85, 0x22, 0x46, 0x23, 0x7c, 0x00, 0x00, 0x3d, 0x85, 0x22, 0x40,
- 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x1f, 0x90, 0x01, 0x00,
- 0x3f, 0x85, 0x22, 0x41, 0x87, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x1f, 0x90, 0x01, 0x00, 0x41, 0x85, 0x22, 0x42, 0x87, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x41, 0x85, 0x66, 0x1b,
- 0x2c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x13, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x76, 0x41, 0x41, 0xc3, 0x01, 0x00, 0x70, 0x85, 0x23, 0x92,
- 0x15, 0x6c, 0x00, 0x00, 0x70, 0x85, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
- 0x74, 0x85, 0x22, 0x4b, 0xfd, 0x7f, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0,
- 0xa2, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x27, 0xb0, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x0a, 0x24, 0xc8, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
- 0x0f, 0x30, 0x01, 0x00, 0x6e, 0x85, 0x22, 0x08, 0x40, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x12,
- 0x24, 0xcc, 0x01, 0x00, 0x4a, 0x85, 0xaa, 0x41, 0x27, 0x40, 0x00, 0x00,
- 0x01, 0x00, 0x00, 0x13, 0x80, 0xcc, 0x01, 0x00, 0x6a, 0x85, 0x26, 0x40,
- 0x23, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x83, 0xb0, 0x01, 0x00,
- 0x60, 0x00, 0x00, 0x03, 0x84, 0xc8, 0x01, 0x00, 0x10, 0x00, 0x00, 0x10,
- 0x48, 0xcd, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
- 0x57, 0x85, 0xa2, 0x40, 0x83, 0x6c, 0x00, 0x00, 0x63, 0x85, 0x00, 0x41,
- 0x83, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x42, 0x44, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x21, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0x5c, 0x85, 0xa2, 0x44, 0x23, 0x6c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf1, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x20, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x5f, 0x85, 0xa8, 0x42, 0xe0, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x85, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xa3, 0xc1, 0x01, 0x00,
- 0x55, 0x85, 0xa2, 0x41, 0x81, 0x50, 0x00, 0x00, 0x6a, 0x85, 0x22, 0x40,
- 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x67, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0x48, 0xb1, 0x01, 0x00, 0xee, 0x07, 0x00, 0x40,
- 0x25, 0x98, 0x01, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x2a, 0xc8, 0x01, 0x00,
- 0x7d, 0x85, 0x00, 0x17, 0x10, 0xb0, 0x00, 0x00, 0x7e, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x74, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x94, 0x92, 0x00, 0x92, 0x25, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x31, 0xb0, 0x01, 0x00, 0x74, 0x85, 0x22, 0x08, 0x2e, 0x30, 0x00, 0x00,
- 0x7d, 0x85, 0x00, 0x41, 0x27, 0xb0, 0x00, 0x00, 0x80, 0x80, 0x00, 0xa6,
- 0x04, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0xc6, 0x95, 0x00, 0x0a, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x7c, 0x85, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00, 0x02, 0x00, 0x00, 0x88,
- 0x1c, 0xcc, 0x01, 0x00, 0xf5, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x14, 0x87, 0x00, 0x41, 0x3f, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0f, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x00, 0x01, 0x80, 0xce, 0x01, 0x00,
- 0x91, 0x85, 0x2a, 0x40, 0x81, 0x30, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0x86, 0x85, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x85, 0xa2, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x86, 0x85, 0xa3, 0x07, 0x03, 0x6c, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x89, 0x85, 0xa3, 0x40,
- 0x02, 0x6c, 0x00, 0x00, 0x28, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
- 0x8b, 0x85, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0x28, 0x00, 0x00, 0x40,
- 0xf0, 0xcd, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x0e, 0xcc, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x8f, 0x85, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x08, 0xb0, 0x01, 0x00, 0xa0, 0x01, 0x2d, 0x40, 0x00, 0xc0, 0x01, 0x00,
- 0x5b, 0x86, 0x22, 0x0f, 0x42, 0x05, 0x00, 0x00, 0xa2, 0x85, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x9d, 0x85, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x9a, 0x85, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xa2, 0x85, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0xe1, 0x91, 0x01, 0x00, 0xc0, 0x06, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x54,
- 0x29, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x0e, 0xb0, 0x01, 0x00, 0x42, 0x00, 0x00, 0x03, 0x0a, 0xc8, 0x01, 0x00,
- 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00, 0xd6, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x14, 0x24, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x14,
- 0x10, 0xc0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x08, 0x10, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0xfe, 0x7f, 0x00, 0x05,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0xe4, 0xb1, 0x01, 0x00,
- 0xcb, 0x85, 0x22, 0x01, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
- 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa4, 0x80, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xb8, 0x85, 0xa3, 0x07,
- 0x02, 0x6c, 0x00, 0x00, 0xb9, 0x85, 0x68, 0x01, 0x1a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x07, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x02, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0xc0, 0x01, 0x00,
- 0xc5, 0x85, 0x22, 0x40, 0x03, 0x6c, 0x00, 0x00, 0xc5, 0x85, 0x22, 0x42,
- 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0xe9, 0x85, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xc2, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00, 0xc7, 0x85, 0xa8, 0x40,
- 0x23, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xe9, 0x85, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x44,
- 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00, 0xd0, 0x85, 0xa3, 0x12,
- 0x0e, 0x6c, 0x00, 0x00, 0xd1, 0x85, 0x60, 0x07, 0x1a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x12, 0x1a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x0d,
- 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b, 0x16, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
- 0xd8, 0x85, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x07, 0x86, 0x22, 0x0d,
- 0x14, 0x6c, 0x00, 0x00, 0xde, 0x85, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0xe2, 0x85, 0x00, 0x0d,
- 0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
- 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
- 0xe4, 0x85, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0xe9, 0x85, 0x00, 0x41,
- 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe5, 0x85, 0xa8, 0x5c,
- 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x07, 0x86, 0x22, 0x0d,
- 0x14, 0x50, 0x00, 0x00, 0x06, 0x86, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00,
- 0xf5, 0x85, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xf3, 0x85, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xf0, 0x85, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0xfa, 0x85, 0x1f, 0xf0,
- 0x0e, 0x30, 0x00, 0x00, 0xb2, 0x85, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0xb2, 0x85, 0x23, 0x07,
- 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
- 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00,
- 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x03, 0x86, 0xa8, 0x46,
- 0x1f, 0x10, 0x00, 0x00, 0xb2, 0x85, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00,
- 0xb2, 0x85, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00, 0x04, 0x00, 0x2e, 0x14,
- 0x0a, 0xd0, 0x01, 0x00, 0x12, 0x00, 0x00, 0x05, 0x48, 0xcd, 0x01, 0x00,
- 0xfe, 0x7f, 0x00, 0x05, 0x42, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x2a, 0xf2,
- 0xe0, 0xb1, 0x01, 0x00, 0x0d, 0x86, 0x22, 0x40, 0x31, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x81, 0x00, 0xf6, 0x80, 0xce, 0x01, 0x00,
- 0x11, 0x86, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x43, 0xc1, 0x01, 0x00, 0x13, 0x86, 0x22, 0x0b, 0xed, 0x6d, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0xa1, 0x42, 0xc9, 0x01, 0x00, 0x02, 0x00, 0x00, 0xa1,
- 0x46, 0xc9, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xfa, 0x94, 0x88, 0x01, 0x00,
- 0x02, 0x00, 0x00, 0x4a, 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf6,
- 0x0e, 0xb0, 0x01, 0x00, 0x1b, 0x86, 0x22, 0x47, 0x1f, 0x7c, 0x00, 0x00,
- 0x04, 0x00, 0x1f, 0x43, 0x0e, 0x50, 0x00, 0x00, 0x1b, 0x86, 0xa0, 0x46,
- 0x0f, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
- 0x1f, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x91, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x0f, 0xa2, 0x42, 0x31, 0x00, 0x00,
- 0x22, 0x86, 0x00, 0x40, 0x89, 0xb0, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa2,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x89, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x95, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x82, 0xb0, 0x01, 0x00, 0x25, 0x86, 0xa0, 0x41, 0x90, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x91, 0xc0, 0x01, 0x00, 0x2a, 0x86, 0x22, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x2a, 0x86, 0xa0, 0x43, 0x89, 0x6c, 0x00, 0x00,
- 0x2a, 0x86, 0x20, 0x45, 0x89, 0x6c, 0x00, 0x00, 0x2a, 0x86, 0xa0, 0x41,
- 0x0e, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x89, 0xc0, 0x01, 0x00, 0x22, 0x86, 0xa2, 0x41,
- 0x95, 0x50, 0x00, 0x00, 0x33, 0x86, 0x22, 0x48, 0x1f, 0x7c, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x48, 0x92, 0xf4, 0x01, 0x00, 0xff, 0xff, 0x00, 0x48,
- 0x90, 0x88, 0x01, 0x00, 0x31, 0x86, 0x90, 0x48, 0x92, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0x0a, 0x00, 0x00, 0xa2,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x93, 0xa4, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x12, 0x00, 0x00, 0x14,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x17, 0xf0, 0xb1, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x05, 0xe0, 0xcd, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x40, 0x62, 0xdd, 0x01, 0x00, 0x39, 0x86, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x44, 0x86, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0x43, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x40, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x47, 0x86, 0xa2, 0x47, 0x1f, 0x7c, 0x00, 0x00,
- 0xcc, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc0, 0x86, 0x00, 0x17,
- 0x10, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x2f, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x4b, 0x86, 0xa0, 0x07,
- 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x17, 0xf0, 0x01, 0x00, 0x4f, 0x86, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
- 0x17, 0xa4, 0x01, 0x00, 0x10, 0x00, 0x00, 0x14, 0x2a, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x2b, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x2a, 0x94, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x59, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x56, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x17, 0x10, 0xdc, 0x01, 0x00,
- 0xc0, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x63, 0x86, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x63, 0x86, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x60, 0x86, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x68, 0x86, 0x22, 0x07, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x42, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x42, 0xc1, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0xa1, 0x46, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f,
- 0xe1, 0x91, 0x01, 0x00, 0x04, 0x00, 0x2e, 0x03, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0x6d, 0x86, 0x22, 0x40,
- 0x31, 0x6c, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x18, 0x38, 0x96, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x72, 0x86, 0xa8, 0x40,
- 0x23, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x52, 0x11, 0xc0, 0x01, 0x00, 0x10, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x0e, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xa4, 0x0c, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa4,
- 0x86, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xc1, 0x01, 0x00,
- 0x80, 0x86, 0xa3, 0x12, 0x0e, 0x6c, 0x00, 0x00, 0x81, 0x86, 0x68, 0x07,
- 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x68, 0x12, 0x1a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x86, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08,
- 0x3e, 0x96, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x02, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x43, 0x62, 0xdd, 0x01, 0x00,
- 0x86, 0x86, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0xb5, 0x86, 0x22, 0x0d,
- 0x14, 0x6c, 0x00, 0x00, 0x8c, 0x86, 0x22, 0x0d, 0x24, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x10, 0xc0, 0x01, 0x00, 0x90, 0x86, 0x00, 0x0d,
- 0x24, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x2b, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0xa2, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x20,
- 0x10, 0xc8, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40, 0x25, 0x98, 0x01, 0x00,
- 0x92, 0x86, 0x22, 0x42, 0x23, 0x6c, 0x00, 0x00, 0x97, 0x86, 0x00, 0x41,
- 0x23, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x93, 0x86, 0xa8, 0x5c,
- 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0x0d,
- 0x14, 0x50, 0x00, 0x00, 0xb4, 0x86, 0xa2, 0x0d, 0x0e, 0x50, 0x00, 0x00,
- 0xa3, 0x86, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x1f, 0x80, 0x01, 0x00, 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xa1, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x9e, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x46, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0xe1, 0x91, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x06,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x04, 0xb0, 0x01, 0x00, 0xa8, 0x86, 0x1f, 0xf0,
- 0x0e, 0x30, 0x00, 0x00, 0x7b, 0x86, 0x00, 0x4c, 0x0d, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x5f, 0x0f, 0x80, 0x01, 0x00, 0x7b, 0x86, 0x23, 0x07,
- 0x14, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00,
- 0x24, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x24, 0x00, 0x00, 0x00,
- 0x00, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xb1, 0x86, 0xa8, 0x46,
- 0x1f, 0x10, 0x00, 0x00, 0x7b, 0x86, 0x00, 0x03, 0x0c, 0xb0, 0x00, 0x00,
- 0x7b, 0x86, 0x00, 0x0d, 0x18, 0xc0, 0x00, 0x00, 0xbe, 0x86, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x00, 0x00, 0x3c, 0x44, 0x23, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x10,
- 0x48, 0xc1, 0x01, 0x00, 0xbe, 0x86, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xbb, 0x86, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
- 0x10, 0xb0, 0x01, 0x00, 0xc0, 0x86, 0x00, 0x40, 0x2b, 0xb0, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0xe0, 0xb1, 0x01, 0x00, 0xc5, 0x86, 0x22, 0x9f, 0x13, 0x6c, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0x88, 0x1c, 0xcc, 0x01, 0x00, 0xf5, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xd7, 0x95, 0x00, 0x41, 0x3f, 0x43, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x0f, 0x30, 0x01, 0x00,
- 0x2a, 0x87, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
- 0x0e, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x01, 0x84, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x07, 0x1a, 0xf4, 0x01, 0x00, 0xd8, 0x92, 0x00, 0x07,
- 0x16, 0x30, 0x01, 0x00, 0xd4, 0x86, 0x22, 0x41, 0x81, 0x6c, 0x00, 0x00,
- 0xd2, 0x86, 0x22, 0x42, 0x81, 0x6c, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xd3, 0x86, 0x22, 0x5f, 0x0f, 0x7c, 0x00, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00, 0xdc, 0x86, 0xa2, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x53, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xdc, 0x86, 0x22, 0x20, 0x85, 0x6c, 0x00, 0x00, 0xd9, 0x86, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x33, 0x93, 0x00, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x25, 0x95, 0x00, 0x42,
- 0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x90, 0x04, 0x00, 0x07, 0x96, 0x30, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x18, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x80, 0xb0, 0x01, 0x00, 0xbd, 0x87, 0xa2, 0x5f,
- 0x81, 0x6c, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x43, 0x19, 0x80, 0x01, 0x00,
- 0x37, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
- 0x8e, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
- 0xeb, 0x86, 0x22, 0x48, 0x8e, 0x6c, 0x00, 0x00, 0x36, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
- 0xeb, 0x86, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00, 0xea, 0x86, 0x23, 0x41,
- 0x8f, 0x6c, 0x00, 0x00, 0xbd, 0x87, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
- 0xbd, 0x87, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00,
- 0xf0, 0x86, 0x22, 0x0a, 0x90, 0x40, 0x00, 0x00, 0xaa, 0x95, 0x00, 0x40,
- 0x91, 0x30, 0x01, 0x00, 0xbd, 0x87, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0xb0, 0x00, 0x2d, 0x45, 0x81, 0xb0, 0x01, 0x00, 0xfc, 0x86, 0x22, 0xf0,
- 0x2c, 0x30, 0x00, 0x00, 0xa3, 0x00, 0x2d, 0x30, 0x83, 0xb0, 0x01, 0x00,
- 0xac, 0x00, 0x2d, 0xf3, 0x82, 0xe0, 0x01, 0x00, 0xf6, 0x86, 0xa3, 0x41,
- 0x2c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x82, 0xb0, 0x01, 0x00,
- 0x98, 0x00, 0x2d, 0xf0, 0x82, 0xc0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0,
- 0x82, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x98, 0xe8, 0x01, 0x00,
- 0xbd, 0x87, 0x20, 0x4c, 0x82, 0x6c, 0x00, 0x00, 0x7c, 0x00, 0x2d, 0x41,
- 0x98, 0xe8, 0x01, 0x00, 0xbd, 0x87, 0x20, 0xf0, 0x98, 0x6c, 0x00, 0x00,
- 0x14, 0x87, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x40, 0x02, 0x00, 0x0c,
- 0x7e, 0x89, 0x01, 0x00, 0x14, 0x87, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xbd, 0x87, 0x00, 0x49, 0x81, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6,
- 0x80, 0xb0, 0x01, 0x00, 0x04, 0x87, 0x22, 0x43, 0x21, 0x6f, 0x00, 0x00,
- 0x13, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00, 0x05, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x1a, 0x80, 0x00, 0x40, 0x80, 0xdc, 0x01, 0x00,
- 0x05, 0x87, 0xa2, 0x5e, 0x0b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x08, 0xb1, 0x01, 0x00, 0x07, 0x87, 0x9f, 0x85, 0x80, 0x32, 0x00, 0x00,
- 0x0b, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xec, 0x82, 0x22, 0x40,
- 0x57, 0x7d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x57, 0x99, 0x01, 0x00,
- 0x0b, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0xdd, 0x82, 0x1a, 0x5b, 0x69, 0x93, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0xcb, 0x81, 0xc8, 0x01, 0x00, 0x11, 0x87, 0x22, 0x40,
- 0xf2, 0x7f, 0x00, 0x00, 0xc4, 0x80, 0x00, 0x6f, 0x97, 0x33, 0x01, 0x00,
- 0x13, 0x87, 0x22, 0x40, 0x73, 0x7d, 0x00, 0x00, 0xde, 0x80, 0x00, 0x41,
- 0x8b, 0xb3, 0x00, 0x00, 0x0e, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x1b, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x1b, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x18, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x2f, 0x92, 0x22, 0x02,
- 0x80, 0x32, 0x00, 0x00, 0x1c, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0x2f, 0x92, 0x1a, 0x02,
- 0x68, 0x97, 0x00, 0x00, 0x26, 0x87, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x26, 0x87, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x23, 0x87, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x39, 0x92, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00, 0x27, 0x87, 0x42, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x39, 0x92, 0x1a, 0x02, 0x68, 0x97, 0x00, 0x00, 0x31, 0x87, 0x9c, 0x0f,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x31, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x2e, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xf9, 0x82, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0x32, 0x87, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
- 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0xa6,
- 0x56, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x2f, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x82, 0x87, 0xa2, 0x40, 0xe7, 0x6d, 0x00, 0x00, 0xb8, 0x94, 0x29, 0x41,
- 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xb0, 0x01, 0x00, 0x29, 0x00, 0x00, 0x40,
- 0x0d, 0x98, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x10, 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0x34, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0xb5, 0x00, 0x0d,
- 0x42, 0xc9, 0x01, 0x00, 0x66, 0x87, 0x22, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x47, 0x87, 0x60, 0x40, 0x81, 0x32, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
- 0x84, 0x89, 0x01, 0x00, 0x4e, 0x87, 0x05, 0xc2, 0x24, 0x30, 0x00, 0x00,
- 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x83, 0x87, 0x70, 0xf0, 0x18, 0x30, 0x01, 0x00,
- 0x66, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x70, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x5d, 0x87, 0xa0, 0x48, 0x23, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x1a,
- 0x42, 0xc9, 0x01, 0x00, 0x57, 0x87, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x1a,
- 0x62, 0xdd, 0x01, 0x00, 0x54, 0x87, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x20, 0x98, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x83, 0x87, 0x00, 0xf8, 0x18, 0x30, 0x01, 0x00,
- 0x58, 0x87, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00, 0xff, 0xff, 0x00, 0x10,
- 0x34, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x34, 0x94, 0x01, 0x00,
- 0x20, 0x18, 0x00, 0x40, 0x11, 0x98, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x1a,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00,
- 0x61, 0x87, 0xa8, 0x09, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x11, 0xc0, 0x01, 0x00, 0x72, 0x87, 0x22, 0x41,
- 0x0d, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00,
- 0x6e, 0x87, 0xa0, 0xaa, 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x0f, 0xb0, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07, 0x12, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa7, 0x13, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1b, 0xb0, 0x01, 0x00, 0x45, 0x87, 0x00, 0x41, 0x17, 0xb0, 0x00, 0x00,
- 0x00, 0x02, 0x00, 0x09, 0x12, 0xc8, 0x01, 0x00, 0x45, 0x87, 0x83, 0x41,
- 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x17, 0xb0, 0x01, 0x00,
- 0x45, 0x87, 0x00, 0x41, 0x1b, 0xc0, 0x00, 0x00, 0x7d, 0x87, 0x23, 0x40,
- 0x23, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x35, 0xd0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x1a, 0x42, 0xc9, 0x01, 0x00, 0x7a, 0x87, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x1a, 0x62, 0xdd, 0x01, 0x00, 0x77, 0x87, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x20, 0x98, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x83, 0x87, 0x00, 0xf8,
- 0x18, 0x30, 0x01, 0x00, 0x7b, 0x87, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x0f, 0xc0, 0x01, 0x00, 0x80, 0x87, 0xa0, 0xaa,
- 0x0f, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0f, 0xb0, 0x01, 0x00,
- 0xb8, 0x94, 0x20, 0x07, 0xe4, 0xb1, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40, 0x0f, 0xb0, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x0c, 0x80, 0xd8, 0x01, 0x00, 0xc0, 0x02, 0x00, 0x0c,
- 0x7e, 0x89, 0x01, 0x00, 0x95, 0x87, 0x26, 0x54, 0x61, 0x31, 0x00, 0x00,
- 0x8b, 0x87, 0x87, 0x0c, 0x80, 0x32, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x40,
- 0x62, 0x99, 0x01, 0x00, 0x8b, 0x87, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x8b, 0x87, 0xa2, 0x54, 0x77, 0x7d, 0x00, 0x00, 0x87, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x90, 0x87, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
- 0x0d, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
- 0x8c, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x95, 0x87, 0x22, 0x49,
- 0x19, 0x7c, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54,
- 0x77, 0x7d, 0x01, 0x00, 0x90, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0x62, 0x99, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x54, 0x77, 0x7d, 0x01, 0x00,
- 0x95, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x2f, 0x55,
- 0xf1, 0x93, 0x01, 0x00, 0x00, 0x40, 0x00, 0xa6, 0x56, 0xb1, 0x01, 0x00,
- 0xf9, 0x82, 0xa2, 0x41, 0xe5, 0x51, 0x00, 0x00, 0x64, 0x00, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x9d, 0x87, 0x44, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xa0, 0x87, 0xa2, 0x93, 0x57, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x57, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x1c, 0xab, 0x27, 0xb3, 0x01, 0x00,
- 0xf9, 0x82, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00, 0xf9, 0x82, 0x22, 0x51,
- 0xfd, 0x7f, 0x00, 0x00, 0xf9, 0x82, 0xa2, 0x41, 0x1d, 0x53, 0x00, 0x00,
- 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00, 0x38, 0x05, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xac, 0x87, 0x22, 0x40,
- 0xb5, 0x6f, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x41, 0xb5, 0x53, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0xfd, 0x83, 0x01, 0x00,
- 0x40, 0x16, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x40, 0x05, 0x00, 0x40,
- 0x49, 0x31, 0x01, 0x00, 0x1e, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x10, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0xda,
- 0x91, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00,
- 0x20, 0x04, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00, 0x60, 0x16, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x82, 0x00, 0x40, 0xb5, 0x33, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0xff, 0xff, 0x00, 0x4a,
- 0xb4, 0x8b, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x0a, 0x00, 0x00, 0x48, 0xb2, 0xcb, 0x01, 0x00, 0x10, 0x00, 0x00, 0x4a,
- 0xb4, 0xf7, 0x01, 0x00, 0x20, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xf9, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x05, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x20, 0x40, 0xe6, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
- 0xc3, 0x87, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xe6, 0x8a, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x1a, 0x8b, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x4c, 0x8b, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x4c, 0x8b, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x8b, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb4, 0x8b, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xc4, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8b, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x73, 0x8c, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x73, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x73, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x93, 0x8c, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xb1, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xd9, 0x8c, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0xea, 0x8c, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xea, 0x8c, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xec, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xec, 0x8c, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xf4, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x05, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0xf5, 0x8c, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x05, 0x8d, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x06, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xfc, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
- 0x71, 0x8c, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x71, 0x8c, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x71, 0x8c, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41,
- 0x09, 0xb0, 0x00, 0x00, 0x07, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x07, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x07, 0x8d, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x0e, 0x8d, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x10, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x1c, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x7b, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x83, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xb8, 0x8b, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x94, 0x8d, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0xe4, 0x8a, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x88, 0x8b, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x7f, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0xb8, 0x8b, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x03, 0x8d, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x8f, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x8f, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x08, 0xb0, 0x01, 0x00, 0x06, 0x00, 0x20, 0x47,
- 0xe6, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x47, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x96, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x96, 0xc0, 0x01, 0x00,
- 0x83, 0x88, 0x00, 0x4b, 0x10, 0xc9, 0x00, 0x00, 0xac, 0x8d, 0x00, 0x49,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe5, 0x8d, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xeb, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xf9, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x15, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x75, 0x8e, 0x00, 0x44,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x74, 0x8e, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xee, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0xee, 0x8d, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0xee, 0x8d, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x49, 0x09, 0xb0, 0x00, 0x00,
- 0xee, 0x8d, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0xee, 0x8d, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0xee, 0x8d, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xd4, 0x8e, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xd4, 0x8e, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xec, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x45,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x41, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x15, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x75, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x74, 0x8e, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x09, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x09, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x09, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xee, 0x8d, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00, 0x2c, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x14, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x14, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x2c, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x3b, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x3b, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x9d, 0x8f, 0x00, 0x40, 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x0c, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xba, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xc1, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xc1, 0x8f, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x0c, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xae, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xd4, 0x8e, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xd4, 0x8e, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x2b, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x1f, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x2b, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1f, 0x8f, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x1f, 0x8f, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xc3, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4b,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xc3, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0xc3, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4c,
- 0x09, 0xb0, 0x00, 0x00, 0xc3, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xdd, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xdd, 0x8f, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xd8, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xfa, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xfa, 0x90, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xce, 0x8f, 0x00, 0x41, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xda, 0x8f, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xda, 0x8f, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xda, 0x8f, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0xda, 0x8f, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0xda, 0x8f, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xda, 0x8f, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0xe0, 0x8e, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x8f, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x36, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x36, 0x91, 0x00, 0x44, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x36, 0x91, 0x00, 0x4b, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x36, 0x91, 0x00, 0x45, 0x09, 0xb0, 0x00, 0x00,
- 0x36, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x36, 0x91, 0x00, 0x4c, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xe0, 0x8e, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x41, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x45, 0x91, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x45, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x56, 0x91, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x56, 0x91, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x43,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x43, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x67, 0x91, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x42,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x85, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x1a, 0x8e, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0xf9, 0x8d, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x85, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x87, 0x91, 0x00, 0x4a, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x42, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x03, 0x8f, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x42, 0x91, 0x00, 0x46,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x8d, 0x91, 0x00, 0x42, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x8d, 0x91, 0x00, 0x46, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x48, 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x34, 0x91, 0x00, 0x4a,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x1d, 0x8e, 0x00, 0x4d, 0x09, 0xb0, 0x00, 0x00,
- 0x13, 0x8e, 0x00, 0x47, 0x09, 0xb0, 0x00, 0x00, 0x13, 0x8e, 0x00, 0x48,
- 0x09, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20,
- 0x85, 0xb0, 0x00, 0x00, 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x20, 0x85, 0xb0, 0x00, 0x00, 0x07, 0x00, 0x2e, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x1f, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
- 0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0xee, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xdf, 0x8a, 0x9c, 0x0f, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0xdf, 0x8a, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xdc, 0x8a, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xa3, 0x84, 0x22, 0x02, 0x80, 0x32, 0x00, 0x00,
- 0xe0, 0x8a, 0x42, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x02, 0x68, 0x97, 0x01, 0x00,
- 0xa3, 0x84, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x05, 0x00, 0x2e, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x1f, 0x87, 0x00, 0x04, 0xe6, 0xb1, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0xa1, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xe0, 0xb1, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x06, 0x07, 0x40, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0x07, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x2e, 0x5c,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0xf0, 0xb1, 0x01, 0x00,
- 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe,
- 0x96, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfa, 0x96, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x96, 0xc0, 0x01, 0x00, 0x00, 0x30, 0x00, 0x4b,
- 0x94, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x95, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x96, 0xc0, 0x01, 0x00, 0x5e, 0x01, 0x2e, 0x34,
- 0x97, 0x84, 0x01, 0x00, 0x02, 0x00, 0x00, 0x4b, 0xe4, 0xe5, 0x01, 0x00,
- 0x64, 0x01, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x86, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x10, 0x48, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00,
- 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x09, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x08, 0x00, 0x2e, 0x40, 0x95, 0xb0, 0x01, 0x00, 0x11, 0x8b, 0x20, 0x4b,
- 0x94, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x0e, 0x8b, 0x00, 0x41, 0x95, 0xc0, 0x00, 0x00, 0x10, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x18, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x14, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x83, 0x94, 0x00, 0x40, 0x81, 0x30, 0x01, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x86, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x88, 0xb0, 0x01, 0x00, 0x1d, 0x8b, 0x44, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x20, 0x8b, 0xa2, 0x4c, 0xfd, 0x7f, 0x00, 0x00,
- 0x21, 0x8b, 0x00, 0x4c, 0xfd, 0x93, 0x00, 0x00, 0x22, 0x8b, 0x20, 0xf0,
- 0x56, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x56, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x1c, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x70, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x28, 0x8b, 0xa8, 0x44,
- 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x40,
- 0xf1, 0x99, 0x01, 0x00, 0x68, 0x01, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00,
- 0x64, 0x00, 0x00, 0x43, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x62, 0xb1, 0x01, 0x00,
- 0x30, 0x8b, 0xa8, 0x44, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x09, 0x00, 0x00, 0x07, 0x86, 0xe4, 0x01, 0x00,
- 0x38, 0x00, 0x2e, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x38, 0x8b, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x3b, 0x8b, 0x22, 0x44,
- 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x45, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x19, 0x90, 0x01, 0x00, 0x68, 0x01, 0x20, 0xa2,
- 0xe4, 0xb1, 0x01, 0x00, 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x3f, 0x8b, 0x23, 0x0b, 0xe5, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x19, 0x90, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x50, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x58, 0x01, 0x00, 0x43,
- 0xf0, 0xc9, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x44, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5c, 0x00, 0x2e, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x83, 0x94, 0x00, 0x41,
- 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x4f, 0x8b, 0xa2, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x53, 0x8b, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00,
- 0x86, 0x00, 0x2f, 0x49, 0x19, 0x80, 0x01, 0x00, 0x53, 0x8b, 0xa2, 0xf2,
- 0x80, 0x32, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xe7, 0x91, 0x01, 0x00, 0x56, 0x8b, 0xa2, 0x46,
- 0x19, 0x7c, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x5a, 0x8b, 0x00, 0x40, 0xe5, 0xb1, 0x00, 0x00, 0xa0, 0x00, 0x2f, 0x46,
- 0x19, 0x80, 0x01, 0x00, 0x5a, 0x8b, 0xa2, 0xf2, 0x80, 0x32, 0x00, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0xe7, 0x91, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x34, 0x00, 0x2d, 0xf0, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfb, 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
- 0x16, 0x88, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3, 0x14, 0xf4, 0x01, 0x00,
- 0x85, 0x8b, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00, 0x6d, 0x8b, 0x22, 0x0a,
- 0x16, 0x6c, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0,
- 0x84, 0x30, 0x00, 0x00, 0x70, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x13, 0xc0, 0x01, 0x00,
- 0x6c, 0x8b, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x13, 0xb0, 0x01, 0x00, 0x62, 0x8b, 0x00, 0x41, 0x15, 0xd0, 0x00, 0x00,
- 0x85, 0x8b, 0x22, 0x0a, 0x80, 0x32, 0x00, 0x00, 0x58, 0x00, 0x3d, 0x43,
- 0x13, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00, 0x70, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x85, 0x8b, 0x22, 0x41, 0x15, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x11, 0xc0, 0x01, 0x00, 0x79, 0x8b, 0xa0, 0x43,
- 0x11, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x11, 0xb0, 0x01, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0x11, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x36, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x00, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x83, 0xb0, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x47,
- 0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x2c, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x81, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x75, 0x8b, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x37, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x51,
- 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x8d, 0x8b, 0x00, 0x48, 0x19, 0x90, 0x00, 0x00,
- 0x34, 0x00, 0x2e, 0x41, 0xf5, 0xb1, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x92, 0x8b, 0x22, 0x45,
- 0x23, 0x7c, 0x00, 0x00, 0xb0, 0x00, 0x2f, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0, 0x8c, 0xb0, 0x01, 0x00,
- 0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0x97, 0x8b, 0x22, 0x48,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8d, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x0a, 0x8c, 0xc0, 0x01, 0x00, 0x38, 0x00, 0x2a, 0x4a,
- 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
- 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x38, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x26, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8,
- 0x02, 0x30, 0x00, 0x00, 0xa5, 0x8b, 0x23, 0x01, 0x14, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x82, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00,
- 0x44, 0x00, 0x20, 0x40, 0xe0, 0xb1, 0x01, 0x00, 0x48, 0x00, 0x20, 0x41,
- 0xe0, 0xb1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0xaa, 0x95, 0x00, 0xf0, 0x24, 0x30, 0x01, 0x00, 0xae, 0x8b, 0xa2, 0x44,
- 0x81, 0x6c, 0x00, 0x00, 0xac, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x57, 0x93, 0x00, 0x40, 0x3b, 0x30, 0x01, 0x00, 0xd2, 0x8b, 0xa2, 0x08,
- 0x3c, 0x30, 0x00, 0x00, 0xae, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd2, 0x8b, 0xa2, 0x08,
- 0x3c, 0x30, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00,
- 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00, 0x4e, 0x00, 0x20, 0x01,
- 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00,
- 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x8d, 0x8b, 0x22, 0x4a,
- 0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x36, 0x93, 0x00, 0xf3,
- 0x94, 0x30, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0xf0, 0xb1, 0x01, 0x00, 0x1f, 0x00, 0x60, 0x00,
- 0x00, 0x8c, 0x01, 0x00, 0xe4, 0x8a, 0x85, 0x11, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0xf0,
- 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
- 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc4, 0x8b, 0x00, 0x49, 0x19, 0x80, 0x00, 0x00,
- 0xc9, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x57, 0x93, 0x00, 0x40,
- 0x3b, 0x30, 0x01, 0x00, 0xcd, 0x8b, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00,
- 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xcd, 0x8b, 0xa2, 0x08, 0x3c, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x5f,
- 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x50, 0x00, 0x2d, 0x10, 0x32, 0xb0, 0x01, 0x00, 0x54, 0x00, 0x2d, 0xf0,
- 0x38, 0xb0, 0x01, 0x00, 0x4e, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
- 0x40, 0x00, 0x2d, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x14, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10, 0x8c, 0xc8, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x46, 0x44, 0xc9, 0x01, 0x00, 0x68, 0x01, 0x2d, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x68, 0xf2, 0x80, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x37, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x36, 0xd0, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0x40,
- 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x52, 0x81, 0xd0, 0x01, 0x00, 0x89, 0x94, 0x00, 0x40,
- 0xe4, 0x31, 0x01, 0x00, 0x20, 0x00, 0x00, 0x46, 0x62, 0xdd, 0x01, 0x00,
- 0xde, 0x8b, 0xa8, 0x40, 0x23, 0x30, 0x00, 0x00, 0xce, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd6, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xec, 0x8b, 0x82, 0x41, 0x23, 0x40, 0x00, 0x00, 0x20, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0xe9, 0x8b, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xe6, 0x8b, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x44, 0xc9, 0x01, 0x00, 0xf4, 0x8b, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xf0, 0x8b, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00, 0xf1, 0x8b, 0x00, 0x06,
- 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00,
- 0xf3, 0x8b, 0x20, 0x02, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x04, 0xb0, 0x01, 0x00, 0xf7, 0x8b, 0x00, 0x02, 0xe0, 0xb1, 0x00, 0x00,
- 0xf6, 0x8b, 0xa3, 0x01, 0x0c, 0x6c, 0x00, 0x00, 0xf7, 0x8b, 0x00, 0x06,
- 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x04, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0x02, 0x16, 0x94, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b,
- 0x16, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x68, 0x08, 0x3e, 0x96, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1c, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0xfc, 0x8b, 0xa8, 0x13, 0xe0, 0x31, 0x00, 0x00, 0x33, 0x8c, 0x22, 0x02,
- 0x14, 0x50, 0x00, 0x00, 0x44, 0x00, 0x2d, 0x02, 0x0c, 0xd0, 0x01, 0x00,
- 0x23, 0x8c, 0xa2, 0x02, 0x02, 0x50, 0x00, 0x00, 0x0a, 0x8c, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x09, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x05, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x44, 0x00, 0x2d, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x48, 0x00, 0x2d, 0xf0,
- 0x38, 0xb0, 0x01, 0x00, 0x4c, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
- 0x38, 0x00, 0x2f, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x24, 0x8c, 0x22, 0x01,
- 0x14, 0x6c, 0x00, 0x00, 0x17, 0x8c, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0x1f, 0x80, 0x01, 0x00, 0x20, 0x00, 0x2d, 0x03,
- 0x48, 0xb1, 0x01, 0x00, 0x16, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x13, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x38, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00,
- 0x38, 0x00, 0x2d, 0xf0, 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0xe1, 0xc1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x22, 0x4a, 0xf1, 0xb1, 0x01, 0x00, 0x44, 0x00, 0x00, 0x05,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00,
- 0x20, 0x8c, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00, 0x24, 0x8c, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0xc0, 0x01, 0x00,
- 0x2e, 0x8c, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x33, 0xc0, 0x01, 0x00, 0x2c, 0x8c, 0xa2, 0x02, 0x36, 0x6c, 0x00, 0x00,
- 0x04, 0x00, 0x8f, 0x0d, 0x42, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0xf8,
- 0x10, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x11, 0x80, 0x01, 0x00,
- 0xf0, 0x07, 0x00, 0x40, 0x37, 0x98, 0x01, 0x00, 0xe2, 0x8b, 0x00, 0xa1,
- 0x1a, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
- 0xe2, 0x8b, 0x00, 0x02, 0x36, 0xd0, 0x00, 0x00, 0x50, 0x00, 0x20, 0x1c,
- 0xe0, 0xb1, 0x01, 0x00, 0x54, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
- 0x4e, 0x00, 0x20, 0x01, 0xe4, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x0a,
- 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x8c, 0x00, 0x5f, 0x01, 0xb0, 0x00, 0x00,
- 0x37, 0x00, 0x2d, 0x46, 0x01, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0xf3,
- 0x80, 0xf4, 0x01, 0x00, 0x37, 0x8c, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x01, 0xb0, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00,
- 0x3e, 0x8c, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00,
- 0x3b, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xd3, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x45, 0x8c, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x42, 0x8c, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x60, 0x01, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x17, 0xf0, 0x01, 0x00,
- 0x4a, 0x8c, 0x90, 0xf2, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00,
- 0x32, 0x00, 0x00, 0xa6, 0x2a, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x2a, 0x94, 0x01, 0x00, 0x4d, 0x8c, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0xd0, 0x00, 0x1e, 0x62, 0xdd, 0x01, 0x00, 0x52, 0x8c, 0x28, 0x40,
- 0x05, 0x30, 0x00, 0x00, 0x4e, 0x8c, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
- 0x55, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x62, 0xb1, 0x01, 0x00, 0x5e, 0x8c, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x52, 0x8c, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00,
- 0x92, 0xb0, 0x01, 0x00, 0x5b, 0x8c, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x99, 0x92, 0x00, 0xf8,
- 0x00, 0x30, 0x01, 0x00, 0x58, 0x8c, 0xa2, 0x41, 0x3b, 0x50, 0x00, 0x00,
- 0x5f, 0x8c, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00, 0xff, 0x07, 0x00, 0x1e,
- 0x00, 0x8c, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x5f, 0x8c, 0x00, 0x49, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x1d, 0x47,
- 0x19, 0x80, 0x01, 0x00, 0x62, 0x8c, 0x22, 0x5f, 0x01, 0x6c, 0x00, 0x00,
- 0xd4, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xbf, 0x87, 0x00, 0x00,
- 0x80, 0xb0, 0x00, 0x00, 0x69, 0x8c, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x20, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x69, 0x8c, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x66, 0x8c, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x69, 0x8c, 0x40, 0x05, 0x48, 0x31, 0x00, 0x00, 0xff, 0xff, 0x00, 0x07,
- 0x94, 0x89, 0x01, 0x00, 0x6f, 0x8c, 0x85, 0xca, 0x94, 0x30, 0x00, 0x00,
- 0xd4, 0x95, 0x18, 0x5c, 0x1f, 0x00, 0x01, 0x00, 0x0e, 0x00, 0x00, 0x0f,
- 0x1e, 0x8c, 0x01, 0x00, 0xe0, 0x86, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf4, 0x94, 0x18, 0x00, 0x80, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x47,
- 0x19, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x80, 0x01, 0x00,
- 0xe4, 0x8a, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x76, 0x8c, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x89, 0x94, 0x00, 0x40,
- 0x0d, 0x30, 0x01, 0x00, 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0xff, 0xff, 0x00, 0x0b, 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50,
- 0x17, 0xf0, 0x01, 0x00, 0x7c, 0x8c, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x7e, 0x8c, 0x22, 0x43,
- 0xe7, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x66, 0x20, 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00,
- 0x02, 0x00, 0x62, 0x40, 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57,
- 0x81, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x40, 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0xf0, 0xb1, 0x01, 0x00, 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x88, 0x8c, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x8c, 0x8c, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x50, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0x92, 0x8c, 0x28, 0x40,
- 0x05, 0x30, 0x00, 0x00, 0x8d, 0x8c, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
- 0x99, 0x92, 0x1d, 0x08, 0x00, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x1d, 0x47, 0x19, 0x80, 0x00, 0x00,
- 0x35, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x84, 0xc8, 0x01, 0x00, 0x97, 0x8c, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xa8, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
- 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00, 0xa2, 0x8c, 0xa2, 0x41,
- 0x9e, 0x06, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x44, 0x83, 0x70, 0x00, 0x00,
- 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43,
- 0xe7, 0xe1, 0x01, 0x00, 0xe4, 0x8a, 0x1f, 0xf0, 0x24, 0x6c, 0x00, 0x00,
- 0xd4, 0x95, 0x00, 0x48, 0x81, 0x30, 0x01, 0x00, 0xbf, 0x87, 0x23, 0x41,
- 0x83, 0x6c, 0x00, 0x00, 0xbf, 0x87, 0x00, 0x47, 0x81, 0xb0, 0x00, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0x85, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x36, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
- 0x28, 0x00, 0x00, 0x40, 0x83, 0x98, 0x01, 0x00, 0xc2, 0x94, 0x00, 0x47,
- 0x61, 0x31, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2d, 0x03, 0x48, 0xb1, 0x01, 0x00, 0x08, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8e, 0xb0, 0x01, 0x00,
- 0x90, 0x00, 0x2d, 0xf0, 0x14, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x93, 0x8b, 0xa2, 0x40, 0x8f, 0x7c, 0x00, 0x00,
- 0xb0, 0x8c, 0x22, 0x47, 0x8f, 0x7c, 0x00, 0x00, 0x93, 0x8b, 0x00, 0x48,
- 0x19, 0x90, 0x00, 0x00, 0x1f, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x36, 0x00, 0x2d, 0x5d, 0x05, 0xb4, 0x01, 0x00, 0x37, 0x00, 0x2d, 0xf3,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x8e, 0xb0, 0x01, 0x00,
- 0x5c, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x24, 0xb0, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x86, 0xdc, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x9b, 0x91, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
- 0x36, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0xbe, 0x8c, 0xa2, 0x50,
- 0x8f, 0x50, 0x00, 0x00, 0x34, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x63, 0x41,
- 0x81, 0xc0, 0x01, 0x00, 0xc1, 0x8c, 0xa0, 0x43, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x40, 0x81, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x20, 0x47,
- 0xe6, 0xb1, 0x01, 0x00, 0xe4, 0x8a, 0x22, 0x47, 0x80, 0x32, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x47, 0x0c, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x8f, 0x84, 0x01, 0x00, 0xd6, 0x8c, 0x22, 0x47, 0x0c, 0x6c, 0x00, 0x00,
- 0x58, 0x00, 0x3d, 0x43, 0x81, 0xe0, 0x01, 0x00, 0xd6, 0x8c, 0x1f, 0xf0,
- 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xcf, 0x8c, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xcc, 0x8c, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xcf, 0x8c, 0x42, 0x40, 0x05, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x93, 0x93, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00,
- 0xd4, 0x8c, 0x23, 0x41, 0x0d, 0x6c, 0x00, 0x00, 0xb1, 0x8c, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xd4, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
- 0xbf, 0x87, 0x00, 0x48, 0x81, 0xb0, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x40,
- 0x8f, 0x6c, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x84, 0xb0, 0x01, 0x00,
- 0xa6, 0x00, 0x2d, 0x49, 0x19, 0x90, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf2,
- 0x80, 0xf4, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x82, 0xf8, 0x01, 0x00, 0x19, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0xe5, 0x8c, 0xa0, 0x40, 0x82, 0x6c, 0x00, 0x00, 0x2c, 0x01, 0x00, 0x40,
- 0x81, 0x98, 0x01, 0x00, 0xe5, 0x8c, 0xa3, 0x40, 0x82, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x80, 0xb0, 0x01, 0x00, 0xe7, 0x8c, 0x20, 0x4c,
- 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xc0, 0x01, 0x00,
- 0x86, 0x00, 0x20, 0x40, 0xe4, 0xb1, 0x01, 0x00, 0xa2, 0x00, 0x20, 0x42,
- 0xe6, 0xb1, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x83, 0x94, 0x00, 0x50, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
- 0xb0, 0x00, 0x2f, 0x5c, 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x60, 0xf0,
- 0x80, 0xc0, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x22, 0x46, 0x19, 0x7c, 0x00, 0x00,
- 0xa0, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2,
- 0x96, 0xcc, 0x01, 0x00, 0xe4, 0x8a, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xf4, 0x94, 0x00, 0x4a, 0x81, 0x30, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x46,
- 0x95, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xe4, 0x8a, 0x22, 0x49, 0x19, 0x7c, 0x00, 0x00, 0x86, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0xf2, 0x80, 0xcc, 0x01, 0x00,
- 0xe4, 0x8a, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x4a,
- 0x81, 0x30, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x47, 0x95, 0x30, 0x01, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2c, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x62, 0xf2, 0x80, 0xc8, 0x01, 0x00, 0x0b, 0x8d, 0x90, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0xff, 0xff, 0x62, 0x40, 0x81, 0x98, 0x01, 0x00,
- 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xe4, 0x8a, 0x22, 0x40,
- 0xe5, 0x6d, 0x00, 0x00, 0xe4, 0x8a, 0x00, 0x41, 0xe5, 0xc1, 0x00, 0x00,
- 0x83, 0x94, 0x00, 0x4d, 0x81, 0x30, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf0, 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x8d, 0xb0, 0x01, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x87, 0x30, 0x01, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x1b, 0x8d, 0x80, 0xf3,
- 0x96, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0x81, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00, 0xe4, 0x8a, 0x00, 0x5c,
- 0x1f, 0x90, 0x00, 0x00, 0x34, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x40, 0xf5, 0x99, 0x01, 0x00, 0x00, 0x11, 0x00, 0x40,
- 0xe5, 0x99, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x30, 0x8d, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x51, 0x83, 0xd0, 0x01, 0x00, 0x34, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x84, 0xcc, 0x01, 0x00,
- 0x28, 0x8d, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x63, 0x42,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x2a, 0x8d, 0x37, 0x5c,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
- 0x2b, 0x8d, 0xa8, 0x4b, 0x19, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x62, 0xb1, 0x01, 0x00, 0x2d, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00,
- 0xac, 0x00, 0x2d, 0xf0, 0x30, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2d, 0xf0,
- 0x28, 0xb0, 0x01, 0x00, 0x58, 0x00, 0x3e, 0x43, 0xe7, 0xe1, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x18, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xe0, 0xb1, 0x01, 0x00, 0x38, 0x00, 0x20, 0x00, 0xe0, 0xb1, 0x01, 0x00,
- 0x3c, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x20, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x2b, 0xb0, 0x01, 0x00,
- 0xd8, 0x94, 0x00, 0x40, 0x0d, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0x16, 0xc0, 0x01, 0x00, 0x3f, 0x8d, 0xa0, 0x14, 0x16, 0x44, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x0e, 0x00, 0x00, 0xa2,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf8, 0xb1, 0x01, 0x00,
- 0xb0, 0x00, 0x2d, 0x14, 0xf8, 0xb1, 0x01, 0x00, 0x10, 0x50, 0x00, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x48, 0x8d, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00, 0x00, 0x30, 0x00, 0x0b,
- 0x16, 0xc8, 0x01, 0x00, 0x48, 0x8d, 0xa4, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0x01, 0x00, 0x6e, 0x43,
- 0x86, 0x98, 0x01, 0x00, 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
- 0x4c, 0x8d, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x53, 0x8d, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
- 0x52, 0x8d, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x64, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x90, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41,
- 0x31, 0xc0, 0x01, 0x00, 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x59, 0x8d, 0x06, 0x0c, 0x80, 0x32, 0x00, 0x00, 0xa0, 0x00, 0x20, 0xf2,
- 0xe4, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x09, 0x46, 0x19, 0x10, 0x00, 0x00,
- 0x9c, 0x01, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0xff, 0xff, 0x00, 0x0b,
- 0x98, 0x88, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x50, 0x17, 0xf0, 0x01, 0x00,
- 0x5e, 0x8d, 0x90, 0x4c, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x60, 0x8d, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x66, 0x20,
- 0x17, 0xa4, 0x01, 0x00, 0x68, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x5c, 0x01, 0x2e, 0xf2, 0x80, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x62, 0x40,
- 0x7e, 0xcd, 0x01, 0x00, 0x00, 0x00, 0x00, 0x57, 0x81, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00, 0x03, 0x00, 0x00, 0x40,
- 0xf0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf0, 0xb1, 0x01, 0x00,
- 0x58, 0x01, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0x6a, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x6e, 0x8d, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00, 0x00, 0x50, 0x00, 0x08,
- 0x62, 0xdd, 0x01, 0x00, 0x6f, 0x8d, 0xa8, 0x40, 0x05, 0x30, 0x00, 0x00,
- 0x35, 0x00, 0x1d, 0x40, 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x84, 0xc8, 0x01, 0x00, 0x75, 0x8d, 0xa0, 0x43, 0x85, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x63, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
- 0x8b, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0xe7, 0x91, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x5f, 0x81, 0x30, 0x01, 0x00,
- 0xe4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00,
- 0x1f, 0x8d, 0x22, 0x4a, 0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x37, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x36, 0x93, 0x00, 0xf3, 0x94, 0x30, 0x01, 0x00, 0x8a, 0x8b, 0x22, 0x4a,
- 0x80, 0x32, 0x00, 0x00, 0xba, 0x8b, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x36, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfb,
- 0x12, 0xb0, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3, 0x90, 0x88, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x0c, 0xf4, 0x01, 0x00, 0xb4, 0x8b, 0x22, 0x06,
- 0x90, 0x6c, 0x00, 0x00, 0x5c, 0x00, 0x3d, 0x43, 0x13, 0xe0, 0x01, 0x00,
- 0xa8, 0x00, 0x2d, 0xf0, 0x94, 0xb0, 0x01, 0x00, 0x37, 0x00, 0x2f, 0xf0,
- 0x24, 0xb0, 0x01, 0x00, 0x36, 0x00, 0x2a, 0x50, 0xe7, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x41, 0x13, 0xc0, 0x01, 0x00, 0x8f, 0x8d, 0xa0, 0x43,
- 0x13, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x99, 0x91, 0x00, 0x10, 0x86, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x91, 0x8d, 0x42, 0x05, 0x48, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00, 0xb4, 0x8b, 0x1a, 0x5d,
- 0x69, 0x93, 0x00, 0x00, 0x36, 0x00, 0x2d, 0x10, 0x86, 0xb0, 0x01, 0x00,
- 0x5c, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00, 0xa8, 0x00, 0x2d, 0xf0,
- 0x94, 0xb0, 0x01, 0x00, 0x35, 0x00, 0x2f, 0xf0, 0x24, 0xb0, 0x01, 0x00,
- 0x01, 0x00, 0x6b, 0xfb, 0x84, 0xc8, 0x01, 0x00, 0x9c, 0x8d, 0xa0, 0x43,
- 0x85, 0x6c, 0x00, 0x00, 0x35, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x01, 0x00, 0x63, 0xf3,
- 0x12, 0xc8, 0x01, 0x00, 0x9f, 0x8d, 0xa0, 0x43, 0x13, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x9b, 0x91, 0x00, 0x4a, 0xf0, 0x31, 0x01, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xa2, 0x8d, 0x42, 0x05,
- 0x48, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x93, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x1a, 0x5d, 0x69, 0x93, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x11, 0x00, 0x63, 0xf3, 0x82, 0xcc, 0x01, 0x00,
- 0x9b, 0x8c, 0x22, 0x41, 0x9e, 0x06, 0x00, 0x00, 0x35, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x58, 0x00, 0x3d, 0x43, 0xe7, 0xe1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x36, 0xb0, 0x01, 0x00, 0xa5, 0x8c, 0x00, 0xf0,
- 0x00, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xad, 0x8d, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42,
- 0x13, 0xf0, 0x01, 0x00, 0xb2, 0x8d, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
- 0xf5, 0x82, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xac, 0x8d, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x75, 0x42, 0x19, 0x90, 0x01, 0x00, 0x75, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0xb4, 0x8d, 0xa8, 0xb1, 0x0c, 0x30, 0x00, 0x00,
- 0x1f, 0x94, 0x00, 0x10, 0x94, 0x30, 0x01, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0xbe, 0x8d, 0x22, 0x40, 0xe1, 0x6d, 0x00, 0x00,
- 0x04, 0x00, 0x02, 0x41, 0x97, 0x40, 0x00, 0x00, 0xbb, 0x8d, 0x00, 0x50,
- 0x43, 0xc1, 0x00, 0x00, 0xca, 0x8d, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x62, 0x4b, 0x12, 0x94, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x97, 0xc0, 0x01, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x94, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x4a,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf1, 0xb1, 0x01, 0x00,
- 0x5e, 0x01, 0x00, 0x4b, 0xf0, 0xc9, 0x01, 0x00, 0x5e, 0x01, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x4a, 0x62, 0xdd, 0x01, 0x00, 0xc8, 0x8d, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x04, 0x00, 0x00, 0x09,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
- 0xd4, 0x00, 0x00, 0x05, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0xd0, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00,
- 0xd4, 0x8d, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3,
- 0x96, 0x88, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x75, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0x62, 0xb1, 0x01, 0x00, 0xd8, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xdd, 0x8d, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0xdb, 0x8d, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x97, 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x96,
- 0x97, 0xb0, 0x01, 0x00, 0xe3, 0x8d, 0x20, 0x09, 0x96, 0x6c, 0x00, 0x00,
- 0xe3, 0x8d, 0x1f, 0x09, 0x96, 0x24, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0xde, 0x8d, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x83, 0x94, 0x00, 0x57, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xe9, 0x8d, 0x22, 0xf3, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x42,
- 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf4, 0x94, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x42,
- 0x19, 0x80, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
- 0xf4, 0x94, 0x00, 0x52, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x96, 0x93, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x40,
- 0x95, 0x6c, 0x00, 0x00, 0xf4, 0x8d, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x40,
- 0x95, 0x30, 0x01, 0x00, 0xff, 0x8d, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x14, 0x87, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x23, 0x00, 0xa6,
- 0x16, 0xb0, 0x01, 0x00, 0x02, 0x8e, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x08, 0x00, 0x0b, 0x16, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x2a, 0xc0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x08, 0x80, 0x30, 0x01, 0x00,
- 0x06, 0x8e, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00, 0xed, 0x94, 0x00, 0x43,
- 0x61, 0x31, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00,
- 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x0e, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x0b, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x75, 0x94, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x12, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00,
- 0x19, 0x8e, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x3d, 0x80, 0x01, 0x00,
- 0x1a, 0x8e, 0x00, 0x42, 0x19, 0x90, 0x00, 0x00, 0x14, 0x00, 0x2d, 0x45,
- 0x1f, 0x90, 0x01, 0x00, 0x75, 0x8e, 0x83, 0x1e, 0x80, 0x32, 0x00, 0x00,
- 0x75, 0x8e, 0x00, 0x44, 0x19, 0x90, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x2d, 0x8e, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x29, 0x8e, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x26, 0x8e, 0xa2, 0x41,
- 0x19, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x41, 0x93, 0x00, 0x15,
- 0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x30, 0x8e, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x31, 0x8e, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x5d, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x15,
- 0x98, 0xc8, 0x01, 0x00, 0x5d, 0x8e, 0xa0, 0x0b, 0x99, 0x6c, 0x00, 0x00,
- 0x30, 0x00, 0x00, 0x10, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x62, 0xb1, 0x01, 0x00,
- 0x39, 0x8e, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x15, 0x98, 0xc8, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x0b,
- 0x99, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x6a, 0x50, 0x99, 0xc0, 0x01, 0x00,
- 0xc0, 0x00, 0x62, 0x01, 0x80, 0xcc, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x2d, 0x00, 0x2d, 0xf0, 0x22, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x80, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x23, 0x80, 0x01, 0x00, 0xd4, 0x00, 0x3f, 0x41, 0xe7, 0xe1, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0x11, 0xe4, 0xf5, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x47,
- 0xe7, 0xb5, 0x01, 0x00, 0x4a, 0x8e, 0x23, 0x0b, 0x81, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0xe5, 0x91, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x03, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x02, 0xd0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x00,
- 0x2a, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x8e, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
- 0x80, 0xce, 0x01, 0x00, 0x5b, 0x8e, 0x26, 0x11, 0x00, 0x30, 0x00, 0x00,
- 0x10, 0x00, 0x00, 0x00, 0x2a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08,
- 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x98, 0xd0, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x4c, 0x02, 0x30, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00, 0x62, 0x8e, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x2f, 0x08, 0x80, 0xb0, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x15, 0xf4, 0xc9, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x01,
- 0xe4, 0xcd, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x03, 0x98, 0x01, 0x00,
- 0xcc, 0x94, 0x00, 0x00, 0x2a, 0x40, 0x01, 0x00, 0x67, 0x8e, 0x22, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x13, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x68, 0x8e, 0x00, 0x01, 0xe0, 0xd1, 0x00, 0x00,
- 0xa7, 0x91, 0x00, 0x40, 0x8d, 0x30, 0x01, 0x00, 0x80, 0x63, 0x00, 0xa6,
- 0x16, 0xb0, 0x01, 0x00, 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x70, 0x8e, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x6d, 0x8e, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x73, 0x8e, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xcf, 0x8a, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x75, 0x8e, 0x00, 0x4a,
- 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xb0, 0x01, 0x00,
- 0x24, 0x00, 0x2d, 0x15, 0x10, 0xc0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
- 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
- 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xe0, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15,
- 0x1a, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x2a, 0xb0, 0x01, 0x00, 0x34, 0x94, 0x00, 0x40,
- 0x35, 0xb0, 0x00, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xb9, 0x8e, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00, 0x24, 0x00, 0x20, 0x0b,
- 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13, 0xe0, 0xb1, 0x01, 0x00,
- 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00, 0x8f, 0x8e, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x8f, 0x8e, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x8b, 0x8e, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0xb2, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0xa0, 0x8e, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0xee, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x41, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xad, 0x8e, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x96, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x9c, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xaf, 0x92, 0x00, 0x40, 0x11, 0x30, 0x01, 0x00, 0x9d, 0x8e, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x9f, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0xee, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x3d, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xa3, 0x8e, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xa9, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
- 0x11, 0x30, 0x01, 0x00, 0xaa, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xac, 0x8e, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xae, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xb5, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
- 0x11, 0x30, 0x01, 0x00, 0xb6, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xb8, 0x8e, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xd4, 0x8a, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0xc0, 0x8e, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xbc, 0x8e, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xc4, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x40,
- 0x11, 0x30, 0x01, 0x00, 0xc5, 0x8e, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x08, 0x00, 0x2d, 0x0a,
- 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x14, 0x00, 0x20, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0xca, 0x8e, 0x03, 0x1e,
- 0x80, 0x32, 0x00, 0x00, 0xcb, 0x8e, 0x00, 0x41, 0x87, 0xb0, 0x00, 0x00,
- 0x21, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0xcf, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0xd2, 0x8e, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x80, 0x01, 0x00, 0xcf, 0x8a, 0xa2, 0x4a, 0x1f, 0x7c, 0x00, 0x00,
- 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xd8, 0x8e, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0xcc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x84, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc4, 0x00, 0x2d, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0, 0x84, 0x30, 0x01, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xd4, 0x8a, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xe4, 0x8e, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
- 0x32, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xec, 0x8e, 0xa2, 0x40,
- 0xe5, 0x6d, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x24, 0x00, 0x20, 0x0b, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x20, 0x13,
- 0xe0, 0xb1, 0x01, 0x00, 0x22, 0x00, 0x20, 0x06, 0xe4, 0xb1, 0x01, 0x00,
- 0x14, 0x00, 0x20, 0x0a, 0xe0, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xfa, 0x8e, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0x99, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x15, 0x98, 0x50, 0x00, 0x00,
- 0xfa, 0x8e, 0x20, 0x01, 0x98, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x46, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0xf7, 0x8e, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xac, 0x00, 0x2f, 0x00, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0xe0, 0xc1, 0x01, 0x00, 0x14, 0x00, 0x2f, 0x15, 0x10, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x60, 0x01,
- 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0x19, 0x90, 0x01, 0x00,
- 0x7c, 0x8e, 0x22, 0x09, 0x80, 0x32, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x09,
- 0x80, 0x30, 0x01, 0x00, 0x7c, 0x8e, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x43, 0xc1, 0x01, 0x00, 0xb7, 0x93, 0x00, 0xf0,
- 0x84, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0x2c, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x42, 0x19, 0x80, 0x00, 0x00,
- 0xa9, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0xc9, 0x94, 0x00, 0x48,
- 0x95, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0f, 0x8f, 0xa8, 0x40,
- 0x13, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x15, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x14, 0x8f, 0x00, 0x40,
- 0x13, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xb0, 0x01, 0x00,
- 0x08, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x14, 0x00, 0x2d, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf0, 0x84, 0x30, 0x00, 0x00,
- 0x13, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x2d, 0x8f, 0x00, 0x09, 0x00, 0xb0, 0x00, 0x00, 0xcf, 0x8a, 0x87, 0x42,
- 0x19, 0x10, 0x00, 0x00, 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00,
- 0xcf, 0x8a, 0x00, 0x40, 0xe7, 0x91, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x2b, 0x8f, 0x22, 0x47, 0xe7, 0x7d, 0x00, 0x00,
- 0x1e, 0x92, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00, 0x2b, 0x8f, 0x22, 0x00,
- 0x80, 0x32, 0x00, 0x00, 0x26, 0x8f, 0xa2, 0x40, 0x1f, 0x7c, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x8f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0xf2,
- 0x02, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x2c, 0x8f, 0x00, 0x40,
- 0x01, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x32, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0x31, 0x8f, 0xa2, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x32, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xbc, 0x8f, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x80, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x3a, 0x8f, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x37, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xbc, 0x8f, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x40, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x4d,
- 0x81, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x96, 0xb0, 0x01, 0x00, 0x4e, 0x8f, 0x22, 0x42, 0x96, 0x14, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x64, 0x00, 0x68, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x05,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x4b, 0x8f, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x4f, 0x8f, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x5e, 0x01, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x53, 0x8f, 0x65, 0xf2, 0x12, 0x30, 0x00, 0x00,
- 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x58, 0x8f, 0x22, 0x47,
- 0xe7, 0x7d, 0x00, 0x00, 0xf5, 0x82, 0x75, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x52, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47,
- 0xe7, 0x91, 0x01, 0x00, 0x04, 0x00, 0x75, 0x09, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x97, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x60, 0x8f, 0xa8, 0x40,
- 0xe1, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x99, 0x3f, 0x42, 0x13, 0xf0, 0x01, 0x00, 0x64, 0x8f, 0x65, 0x05,
- 0x48, 0x31, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x75, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x6c, 0x8f, 0x22, 0x4b, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x6a, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x62, 0x00, 0x0b,
- 0x16, 0xdc, 0x01, 0x00, 0x1e, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x84, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xcc, 0x93, 0x00, 0x5f,
- 0x01, 0x10, 0x01, 0x00, 0x6e, 0x8f, 0x22, 0x40, 0x95, 0x6c, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x76, 0x8f, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf2, 0x02, 0xb0, 0x01, 0x00, 0x41, 0x93, 0x00, 0x52,
- 0x95, 0x30, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x6e, 0x8f, 0x22, 0x41, 0x97, 0x50, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5c, 0x01, 0x80, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x6e, 0x8f, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00,
- 0xd4, 0x94, 0x00, 0x40, 0x03, 0x30, 0x01, 0x00, 0x17, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x4c, 0x97, 0xf0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0xe1, 0xb1, 0x01, 0x00,
- 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0x03, 0x00, 0x00, 0x07,
- 0x1a, 0xf4, 0x01, 0x00, 0x07, 0x00, 0x00, 0x07, 0x16, 0x88, 0x01, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x8e, 0x8f, 0x30, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x81, 0x01, 0x00,
- 0x00, 0xb7, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b,
- 0xe6, 0x81, 0x01, 0x00, 0x10, 0x00, 0x10, 0x0f, 0x94, 0xf4, 0x01, 0x00,
- 0x93, 0x04, 0x00, 0x5f, 0x95, 0x04, 0x01, 0x00, 0x22, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x98, 0x8f, 0x22, 0x50, 0xfd, 0x7f, 0x00, 0x00,
- 0x96, 0x8f, 0x46, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x41,
- 0x31, 0xd3, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x0f, 0xb0, 0x01, 0x00, 0x85, 0x92, 0x00, 0x41, 0x81, 0x30, 0x01, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xa9, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00,
- 0xa2, 0x8f, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x62, 0xb1, 0x01, 0x00, 0xa6, 0x8f, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xa3, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x62, 0xb1, 0x01, 0x00, 0xa6, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x74, 0x00, 0x22, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0xc9, 0x94, 0x00, 0x4a, 0x95, 0x30, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x5c,
- 0x1f, 0x10, 0x01, 0x00, 0x40, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2f, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xba, 0x8f, 0x22, 0x47,
- 0xe7, 0x7d, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x40, 0xe7, 0x31, 0x01, 0x00,
- 0xba, 0x8f, 0x22, 0x00, 0x80, 0x32, 0x00, 0x00, 0xb5, 0x8f, 0xa2, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xba, 0x8f, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x94, 0xb0, 0x01, 0x00,
- 0x41, 0x93, 0x00, 0xf2, 0x02, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc9, 0x94, 0x00, 0x48, 0x95, 0x30, 0x01, 0x00, 0xa9, 0x93, 0x00, 0x5c,
- 0x1f, 0x10, 0x01, 0x00, 0xbf, 0x8f, 0x87, 0x42, 0x19, 0x10, 0x00, 0x00,
- 0x8b, 0x00, 0x2f, 0x47, 0x19, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe7, 0x91, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x42, 0x81, 0x30, 0x01, 0x00,
- 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xa9, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x5c, 0x1f, 0x90, 0x00, 0x00,
- 0xba, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xc0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0,
- 0x84, 0x30, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xf4, 0x94, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00,
- 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd3, 0x8f, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x83, 0x94, 0x00, 0x47,
- 0x80, 0x30, 0x01, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0xe1, 0x00, 0xa6, 0x84, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x07, 0x84, 0x94, 0x01, 0x00,
- 0x75, 0x94, 0x00, 0x5e, 0x05, 0x10, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x99, 0x92, 0x00, 0x41, 0xe7, 0x41, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x2c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x10, 0xc0, 0x01, 0x00, 0x04, 0x00, 0x1f, 0x0a,
- 0x2c, 0x50, 0x00, 0x00, 0x07, 0x95, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00,
- 0xea, 0x8f, 0xa2, 0x48, 0x1f, 0x7c, 0x00, 0x00, 0xe8, 0x8f, 0x84, 0x48,
- 0x1f, 0x10, 0x00, 0x00, 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0xea, 0x8f, 0x00, 0x0a, 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x02, 0xb0, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xeb, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
- 0xf8, 0x8f, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00, 0xf1, 0x93, 0x00, 0x45,
- 0x1f, 0x00, 0x01, 0x00, 0xe3, 0x8f, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0xf4, 0x8f, 0xa8, 0x5c, 0x1f, 0x00, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0xe3, 0x8f, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xfe, 0x8f, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x08, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x08, 0x90, 0xa2, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x16, 0x90, 0x22, 0x4a,
- 0x1f, 0x7c, 0x00, 0x00, 0x0e, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x12, 0x90, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x13, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
- 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16,
- 0xe4, 0xb1, 0x00, 0x00, 0x28, 0x90, 0x22, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x7d, 0x95, 0x00, 0x40,
- 0x95, 0x30, 0x01, 0x00, 0x29, 0x90, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
- 0xac, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2b, 0x01,
- 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6, 0x16, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00, 0xcc, 0x94, 0x00, 0x08,
- 0x80, 0x30, 0x01, 0x00, 0x21, 0x90, 0x00, 0x5e, 0x17, 0x90, 0x00, 0x00,
- 0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x22, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x1f, 0x15, 0x1a, 0x50, 0x00, 0x00, 0x36, 0x90, 0x20, 0x16,
- 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x33, 0x90, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15, 0x10, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x2a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x2c, 0xd0, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40, 0x23, 0xb0, 0x01, 0x00,
- 0x3d, 0x90, 0x84, 0x45, 0x1f, 0x10, 0x00, 0x00, 0x3e, 0x90, 0x00, 0x0a,
- 0xe0, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0xb0, 0x01, 0x00,
- 0x34, 0x94, 0x00, 0x40, 0x35, 0xb0, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x42, 0xc9, 0x01, 0x00, 0x46, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x42, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x55, 0x90, 0xa2, 0x02, 0x1a, 0x50, 0x00, 0x00,
- 0x56, 0x90, 0x22, 0x40, 0x2d, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08,
- 0xe0, 0x8d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x4d, 0x90, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00,
- 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x56, 0x90, 0x00, 0x5c,
- 0x11, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x10, 0xc0, 0x01, 0x00,
- 0xaf, 0x92, 0x00, 0x40, 0x1f, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x5a, 0x90, 0x23, 0x0d, 0x2c, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00, 0x62, 0x90, 0x22, 0x46,
- 0x1f, 0x7c, 0x00, 0x00, 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x62, 0x90, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x5e, 0x90, 0xa8, 0x46, 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x08, 0x00, 0x2d, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x67, 0x90, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x6d, 0x90, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x71, 0x90, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00,
- 0xf4, 0x94, 0x00, 0x4f, 0x81, 0x30, 0x01, 0x00, 0x71, 0x90, 0xa2, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x86, 0x90, 0x22, 0x4a,
- 0x1f, 0x7c, 0x00, 0x00, 0x77, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x82, 0x90, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0x7b, 0x90, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xa5, 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x85, 0xd0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00,
- 0x7f, 0x90, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a,
- 0x11, 0x90, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00,
- 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x83, 0x90, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00, 0x32, 0x00, 0x2a, 0x15,
- 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16, 0xe4, 0xb1, 0x00, 0x00,
- 0x89, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xd6, 0x90, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x96, 0x90, 0x22, 0x47,
- 0x1f, 0x7c, 0x00, 0x00, 0x93, 0x90, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x8e, 0x90, 0xa2, 0xf3, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa5,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x85, 0xd0, 0x01, 0x00,
- 0xd4, 0x00, 0x3e, 0x41, 0x85, 0xe0, 0x01, 0x00, 0x92, 0x90, 0x22, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x11, 0x90, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0x08, 0xe4, 0xf5, 0x01, 0x00, 0x58, 0x01, 0x2d, 0x00,
- 0x2a, 0xd0, 0x01, 0x00, 0x60, 0x01, 0x2d, 0xf0, 0x10, 0xb0, 0x01, 0x00,
- 0x2d, 0x8e, 0x00, 0xf0, 0x2c, 0xb0, 0x00, 0x00, 0x7d, 0x95, 0x00, 0x41,
- 0x95, 0x30, 0x01, 0x00, 0x9d, 0x90, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0x9b, 0x90, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
- 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0xd6, 0x90, 0x00, 0x05,
- 0x48, 0xb1, 0x00, 0x00, 0xac, 0x00, 0x2f, 0x01, 0x14, 0xb0, 0x01, 0x00,
- 0xb0, 0x00, 0x2b, 0x01, 0xe0, 0xc1, 0x01, 0x00, 0x00, 0x2b, 0x00, 0xa6,
- 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0xd1, 0x01, 0x00,
- 0xad, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0xa6, 0x90, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0xf0,
- 0x22, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x23, 0x80, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x84, 0xb0, 0x01, 0x00, 0xb0, 0x90, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x08, 0x80, 0xb0, 0x01, 0x00, 0xb5, 0x90, 0x22, 0x40,
- 0x1b, 0x6c, 0x00, 0x00, 0xcc, 0x94, 0x00, 0x01, 0x84, 0x50, 0x01, 0x00,
- 0xbd, 0x90, 0x22, 0x40, 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x80, 0xc0, 0x01, 0x00, 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4f, 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x40, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
- 0xbb, 0x90, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0xcc, 0x90, 0x00, 0x5e,
- 0x17, 0x90, 0x00, 0x00, 0xc0, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0d, 0x02, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x84, 0xd0, 0x01, 0x00, 0xc5, 0x90, 0x22, 0x40, 0x1b, 0x6c, 0x00, 0x00,
- 0xed, 0x94, 0x00, 0x43, 0x61, 0x31, 0x01, 0x00, 0xcc, 0x90, 0x22, 0x40,
- 0x85, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x12, 0xc0, 0x01, 0x00,
- 0x10, 0x80, 0x00, 0x10, 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f,
- 0x43, 0x81, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x09, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18,
- 0xf0, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa1, 0x62, 0xdd, 0x01, 0x00,
- 0xca, 0x90, 0xa8, 0x11, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0xcd, 0x90, 0xa8, 0x0a, 0x02, 0x30, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x99, 0x92, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
- 0xd4, 0x90, 0x23, 0x0d, 0x02, 0x6c, 0x00, 0x00, 0xff, 0x07, 0x00, 0x11,
- 0x00, 0x8c, 0x01, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xd4, 0x94, 0x00, 0x07, 0x16, 0x14, 0x01, 0x00, 0x75, 0x94, 0x00, 0x5e,
- 0x05, 0x10, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x8e, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x41,
- 0x87, 0x30, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0xe7, 0x90, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0xe3, 0x90, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xe9, 0x90, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x1a, 0xd0, 0x01, 0x00, 0xef, 0x90, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x7d, 0x95, 0x00, 0x40, 0x95, 0x30, 0x01, 0x00, 0xf7, 0x90, 0x22, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x1a, 0x90, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
- 0x7d, 0x95, 0x00, 0x41, 0x95, 0x30, 0x01, 0x00, 0xf2, 0x90, 0x22, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x9d, 0x90, 0x00, 0x00, 0x2a, 0xc0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x97, 0xb0, 0x01, 0x00, 0xf5, 0x90, 0x23, 0x0d,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x97, 0xc0, 0x01, 0x00,
- 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00,
- 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xfb, 0x90, 0x00, 0x4a, 0x1f, 0x90, 0x00, 0x00,
- 0xc1, 0x92, 0x00, 0x00, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x15,
- 0x10, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x07, 0x95, 0x00, 0x06, 0x04, 0x30, 0x01, 0x00, 0x04, 0x91, 0xa2, 0x44,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x1b, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0a, 0x2c, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a,
- 0x02, 0xb0, 0x01, 0x00, 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x19, 0x42, 0xc9, 0x01, 0x00, 0x0b, 0x91, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x07, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02,
- 0x10, 0xc0, 0x01, 0x00, 0x14, 0x91, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00,
- 0xf1, 0x93, 0x00, 0x45, 0x1f, 0x00, 0x01, 0x00, 0xfd, 0x90, 0x22, 0x5c,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x10, 0x91, 0xa8, 0x5c,
- 0x1f, 0x00, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0xfd, 0x90, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x08, 0x00, 0x2d, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00, 0xb7, 0x93, 0x00, 0x41,
- 0x87, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x19, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x1f, 0x91, 0x22, 0x09,
- 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40, 0x13, 0x30, 0x01, 0x00,
- 0x22, 0x91, 0x22, 0x44, 0x19, 0x7c, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x4f,
- 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x80, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0x08, 0x00, 0x8c, 0x01, 0x00, 0x30, 0x91, 0x22, 0x4a,
- 0x1f, 0x7c, 0x00, 0x00, 0x28, 0x91, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x2d, 0x00, 0x2d, 0x08, 0x2a, 0xb0, 0x01, 0x00, 0x2c, 0x91, 0x22, 0x42,
- 0x19, 0x7c, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x96, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x30, 0x00, 0x2e, 0x00, 0x2a, 0xd0, 0x01, 0x00,
- 0x32, 0x00, 0x2a, 0x15, 0xe4, 0xb1, 0x01, 0x00, 0xcf, 0x8a, 0x00, 0x16,
- 0xe4, 0xb1, 0x00, 0x00, 0x17, 0x90, 0xa2, 0x16, 0x02, 0x30, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2f, 0x00, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xd4, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xc1, 0x92, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x10,
- 0x32, 0xb0, 0x00, 0x00, 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x3a, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x3d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x41, 0x93, 0x00, 0x15, 0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b,
- 0x02, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x3f, 0x91, 0x22, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x83, 0x94, 0x00, 0x3a,
- 0x81, 0x30, 0x01, 0x00, 0xf4, 0x94, 0x00, 0x45, 0x81, 0x30, 0x01, 0x00,
- 0xcf, 0x8a, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x45,
- 0x1f, 0x90, 0x00, 0x00, 0x83, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x01,
- 0x2c, 0xb0, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x51, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0xc0, 0x01, 0x00, 0x4a, 0x91, 0x37, 0x5c,
- 0x61, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00,
- 0x4e, 0x91, 0x28, 0x40, 0x81, 0x32, 0x00, 0x00, 0x4b, 0x91, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00,
- 0x4e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x14, 0x87, 0x17, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
- 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0x83, 0x93, 0x00, 0x47,
- 0x1f, 0x10, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2b, 0x90, 0x00, 0x01, 0x2c, 0xb0, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x47,
- 0x1f, 0x10, 0x01, 0x00, 0x63, 0x91, 0xa2, 0x08, 0x80, 0x32, 0x00, 0x00,
- 0x5f, 0x91, 0xa2, 0x42, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02,
- 0x04, 0xdc, 0x01, 0x00, 0xa0, 0x98, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00,
- 0x30, 0x05, 0x00, 0x41, 0x89, 0x30, 0x01, 0x00, 0x41, 0x93, 0x00, 0x15,
- 0x94, 0x30, 0x01, 0x00, 0x48, 0x93, 0x00, 0x4b, 0x02, 0xb0, 0x00, 0x00,
- 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x83, 0x94, 0x00, 0x3a, 0x81, 0x30, 0x01, 0x00, 0x14, 0x87, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x58, 0x01, 0x20, 0x08, 0xe0, 0xb1, 0x01, 0x00,
- 0x60, 0x01, 0x20, 0x16, 0xe0, 0xb1, 0x01, 0x00, 0xc1, 0x92, 0x00, 0x10,
- 0x32, 0x30, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00,
- 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x73, 0x91, 0xa2, 0x08,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x82, 0x00, 0x02, 0x04, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x03, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x00, 0xc0, 0x01, 0x00, 0x6c, 0x91, 0x37, 0x5c, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x62, 0xb1, 0x01, 0x00, 0x70, 0x91, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x6d, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x62, 0xb1, 0x01, 0x00, 0x70, 0x91, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x14, 0x87, 0x17, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x8e, 0xb0, 0x01, 0x00, 0x80, 0x93, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0xb7, 0x93, 0x00, 0x41, 0x87, 0x30, 0x01, 0x00, 0x3c, 0x93, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00,
- 0x82, 0x91, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x7e, 0x91, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88,
- 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x2d, 0x8e, 0x22, 0x09, 0x80, 0x30, 0x00, 0x00, 0xf4, 0x94, 0x00, 0x40,
- 0x13, 0x30, 0x01, 0x00, 0x2d, 0x8e, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x14, 0x00, 0x2d, 0x45, 0x1f, 0x90, 0x01, 0x00, 0x75, 0x8e, 0x00, 0x44,
- 0x19, 0x90, 0x00, 0x00, 0x8a, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x1f, 0x90, 0x01, 0x00, 0xdd, 0x8f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x83, 0x93, 0x00, 0x4a, 0x1f, 0x10, 0x01, 0x00,
- 0x3c, 0x93, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x2b, 0x90, 0x00, 0x01,
- 0x2c, 0xb0, 0x00, 0x00, 0xc1, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x2b, 0x90, 0x00, 0x10, 0x32, 0xb0, 0x00, 0x00, 0xec, 0x8e, 0x00, 0x45,
- 0x1f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x37, 0xc3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x33, 0xc3, 0x01, 0x00, 0x36, 0x00, 0x00, 0x01,
- 0x02, 0xcc, 0x01, 0x00, 0x00, 0x00, 0xd2, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x96, 0x91, 0x85, 0x17, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x48,
- 0x03, 0xd0, 0x00, 0x00, 0x98, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x9f, 0x4c, 0x03, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x01,
- 0x34, 0xc3, 0x01, 0x00, 0x40, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x12, 0xf0, 0xb1, 0x01, 0x00,
- 0x9d, 0x92, 0x00, 0x41, 0xe1, 0x31, 0x01, 0x00, 0x00, 0x80, 0x00, 0x43,
- 0x44, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xa4, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xba, 0x00, 0x20, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x01, 0x8c, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x46, 0xe0, 0xc1, 0x01, 0x00, 0xac, 0x00, 0x2f, 0x40,
- 0x13, 0xb0, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x01, 0xe0, 0xc1, 0x01, 0x00,
- 0xae, 0x91, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0x84, 0x95, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xb0, 0x91, 0x22, 0x47, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x13, 0x90, 0x01, 0x00, 0x2d, 0x95, 0x00, 0x47,
- 0x19, 0x10, 0x01, 0x00, 0xc0, 0x00, 0x2d, 0x44, 0x1f, 0x90, 0x01, 0x00,
- 0xc4, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x61, 0x95, 0x00, 0xf0,
- 0x84, 0xb0, 0x00, 0x00, 0x90, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xc5, 0x91, 0xa2, 0x4b, 0x1f, 0x7c, 0x00, 0x00, 0x18, 0x92, 0xa2, 0x4c,
- 0x1f, 0x7c, 0x00, 0x00, 0xc5, 0x91, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
- 0xc8, 0x91, 0xa2, 0x01, 0x80, 0x32, 0x00, 0x00, 0xa8, 0x00, 0x2d, 0x46,
- 0x8f, 0xb0, 0x01, 0x00, 0xbe, 0x91, 0x1f, 0x1c, 0xe0, 0x6d, 0x00, 0x00,
- 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0xc0, 0x91, 0x22, 0xf0,
- 0x3a, 0x6c, 0x00, 0x00, 0x15, 0x92, 0x1f, 0xf0, 0x3a, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4f,
- 0x8f, 0xb0, 0x01, 0x00, 0x8a, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x16, 0x92, 0x20, 0x42, 0xe7, 0x6d, 0x00, 0x00, 0xc4, 0x91, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x59, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x58, 0x8f, 0xb0, 0x01, 0x00, 0xc7, 0x91, 0x22, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x5c, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x5b, 0x8f, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xb0, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0xcc, 0x91, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0xd5, 0x91, 0x23, 0xf0,
- 0x02, 0x6c, 0x00, 0x00, 0xd2, 0x91, 0xa2, 0xf0, 0x80, 0x32, 0x00, 0x00,
- 0x17, 0x92, 0xa2, 0x42, 0x24, 0x6c, 0x00, 0x00, 0x17, 0x92, 0xa2, 0x41,
- 0x03, 0x6c, 0x00, 0x00, 0xd1, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x51, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x52,
- 0x8f, 0xb0, 0x01, 0x00, 0x17, 0x92, 0x1f, 0x12, 0x84, 0x50, 0x00, 0x00,
- 0x17, 0x92, 0xa0, 0x01, 0x84, 0x6c, 0x00, 0x00, 0xc5, 0x91, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x00, 0x92, 0xa2, 0x46, 0xe7, 0x7d, 0x00, 0x00, 0x14, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0xf2, 0x91, 0x22, 0xf0, 0x14, 0x30, 0x00, 0x00,
- 0xde, 0x91, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0xef, 0x91, 0x03, 0x1e,
- 0x80, 0x32, 0x00, 0x00, 0xdd, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x49,
- 0x8f, 0xb0, 0x01, 0x00, 0xe3, 0x91, 0x22, 0x0a, 0x02, 0x6c, 0x00, 0x00,
- 0xe6, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xe2, 0x91, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00, 0xe5, 0x91, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x82, 0xd0, 0x01, 0x00,
- 0xec, 0x91, 0x20, 0x91, 0x83, 0x6c, 0x00, 0x00, 0xeb, 0x91, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x26, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x27, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0xee, 0x91, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x1f, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x20, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0xf1, 0x91, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x22, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x23, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44,
- 0x8f, 0xb0, 0x01, 0x00, 0xfb, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0xf8, 0x91, 0xa2, 0x43, 0x3d, 0x7c, 0x00, 0x00, 0xf8, 0x91, 0xa2, 0xf2,
- 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x80, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0xfa, 0x91, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00, 0xf8, 0x91, 0xa0, 0x91,
- 0x03, 0x6c, 0x00, 0x00, 0xf6, 0x91, 0x22, 0x43, 0x3d, 0x7c, 0x00, 0x00,
- 0xff, 0x91, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x28, 0x00, 0x80, 0x40,
- 0x8f, 0x98, 0x01, 0x00, 0x29, 0x00, 0x80, 0x40, 0x8f, 0x98, 0x01, 0x00,
- 0x14, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x09, 0x92, 0xa2, 0xf0,
- 0x14, 0x30, 0x00, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x8f, 0xb0, 0x01, 0x00,
- 0x06, 0x92, 0xa2, 0xf2, 0x02, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40,
- 0x80, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00,
- 0xf8, 0x91, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xf6, 0x91, 0x20, 0x91,
- 0x03, 0x6c, 0x00, 0x00, 0xf8, 0x91, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x0d, 0x92, 0x20, 0x0a, 0x02, 0x6c, 0x00, 0x00, 0x0c, 0x92, 0xa2, 0x40,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x44, 0x8f, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x49, 0x8f, 0xb0, 0x01, 0x00, 0x12, 0x92, 0x22, 0x0a,
- 0x02, 0x6c, 0x00, 0x00, 0xe6, 0x91, 0xa2, 0x41, 0x19, 0x7c, 0x00, 0x00,
- 0x11, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x55,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x56, 0x8f, 0xb0, 0x01, 0x00,
- 0x14, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x48, 0x8f, 0xb0, 0x01, 0x00,
- 0x1a, 0x92, 0x00, 0x43, 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x41,
- 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x42, 0x95, 0xb0, 0x00, 0x00,
- 0x1a, 0x92, 0x00, 0x44, 0x95, 0xb0, 0x00, 0x00, 0x1a, 0x92, 0x00, 0x4c,
- 0x95, 0xb0, 0x00, 0x00, 0xc9, 0x94, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x1d, 0x92, 0xa2, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x4b,
- 0x8f, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4c, 0x8f, 0xb0, 0x01, 0x00,
- 0x2d, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3,
- 0x84, 0xb0, 0x01, 0x00, 0x22, 0x92, 0xa2, 0xf3, 0x96, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x01, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x2a, 0x41,
- 0xe7, 0xd1, 0x01, 0x00, 0xd4, 0x00, 0x3d, 0x41, 0x85, 0xe0, 0x01, 0x00,
- 0x0b, 0x00, 0x00, 0xf2, 0x00, 0xe4, 0x01, 0x00, 0x28, 0x92, 0x22, 0x5a,
- 0x01, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x90, 0x01, 0x00,
- 0x29, 0x92, 0x00, 0x5a, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1f, 0x80, 0x01, 0x00, 0x00, 0x00, 0x63, 0x41, 0x85, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0xa0, 0xa5, 0x85, 0x6c, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0xc6, 0x95, 0x00, 0xf0,
- 0x8c, 0xb0, 0x00, 0x00, 0x36, 0x92, 0x22, 0x40, 0x0f, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x33, 0x92, 0xa2, 0x4b,
- 0x19, 0x7c, 0x00, 0x00, 0x34, 0x92, 0x22, 0xf0, 0x18, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00, 0xff, 0x92, 0x00, 0x07,
- 0x10, 0x30, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x38, 0x92, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x85, 0x92, 0x00, 0x40,
- 0x81, 0x30, 0x01, 0x00, 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x2f, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b,
- 0x19, 0x90, 0x01, 0x00, 0xff, 0x92, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00,
- 0xf9, 0x82, 0x00, 0x40, 0x05, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0xff, 0x92, 0x00, 0x07, 0x10, 0x30, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x05, 0xb0, 0x01, 0x00, 0x41, 0x92, 0x33, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x44, 0x92, 0xa1, 0xad, 0x95, 0x20, 0x00, 0x00, 0x52, 0x92, 0x13, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x13, 0x4a, 0x5a, 0x83, 0x01, 0x00,
- 0x30, 0x00, 0x39, 0x45, 0x95, 0xe0, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x0f,
- 0x5e, 0xd8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5f, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x45, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04,
- 0x48, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x05, 0x4a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x0c, 0x58, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x4e, 0xb0, 0x01, 0x00, 0xa2, 0x84, 0x00, 0x40, 0x5d, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x58, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x41, 0x97, 0xb0, 0x00, 0x00,
- 0x4f, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x97, 0xb0, 0x01, 0x00, 0x53, 0x92, 0x60, 0x07, 0x96, 0x30, 0x00, 0x00,
- 0xff, 0xff, 0x00, 0x4b, 0x84, 0x89, 0x01, 0x00, 0x00, 0x00, 0x70, 0xc2,
- 0x24, 0xb0, 0x01, 0x00, 0x5d, 0x92, 0xa2, 0x45, 0x25, 0x7c, 0x00, 0x00,
- 0x57, 0x92, 0x31, 0x20, 0x85, 0x30, 0x00, 0x00, 0x5e, 0x92, 0x22, 0x12,
- 0x48, 0x7f, 0x00, 0x00, 0x58, 0x04, 0x11, 0x12, 0x48, 0x03, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x1e, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00,
- 0x5d, 0x92, 0x31, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4,
- 0x24, 0xb0, 0x01, 0x00, 0x5e, 0x92, 0x22, 0x12, 0x48, 0x7f, 0x00, 0x00,
- 0x58, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x6b, 0x92, 0x0b, 0xf0, 0x84, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x12, 0x48, 0x83, 0x01, 0x00, 0x68, 0x92, 0x22, 0x50,
- 0x85, 0x70, 0x00, 0x00, 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x2a, 0x94, 0x00, 0xf2, 0x96, 0x30, 0x01, 0x00, 0x93, 0x04, 0x00, 0x12,
- 0x94, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x1f, 0x90, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x12, 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4b,
- 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x42, 0x10, 0xf4, 0x01, 0x00,
- 0x00, 0xb7, 0x3f, 0x43, 0x11, 0xf0, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08,
- 0x8a, 0x88, 0x01, 0x00, 0x6e, 0x92, 0x30, 0xa1, 0x0c, 0x30, 0x00, 0x00,
- 0x71, 0x92, 0x22, 0x45, 0xe6, 0x7d, 0x00, 0x00, 0x5e, 0x92, 0x10, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x45, 0xe6, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x12, 0x48, 0x83, 0x01, 0x00, 0x00, 0x00, 0x11, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x60, 0x4b, 0x85, 0x80, 0x01, 0x00,
- 0x5e, 0x01, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x2a, 0x94, 0x00, 0xf2,
- 0x96, 0x30, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0xd8, 0x00, 0x00, 0x40, 0x81, 0x98, 0x01, 0x00, 0x2e, 0x00, 0x2d, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x7c, 0x92, 0x22, 0x40, 0xe7, 0x6d, 0x00, 0x00,
- 0x80, 0x00, 0x00, 0x40, 0x80, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x08, 0x86, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x68, 0xa7, 0x87, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0x80, 0x92, 0xa8, 0x05, 0xe0, 0x31, 0x00, 0x00, 0x10, 0x00, 0x00, 0x12,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x14, 0x00, 0x4b, 0x96, 0xdc, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x4b, 0x1e, 0x94, 0x01, 0x00, 0x10, 0x00, 0x00, 0x0f,
- 0x84, 0xf4, 0x01, 0x00, 0x1f, 0x00, 0x00, 0x42, 0x84, 0x88, 0x01, 0x00,
- 0x89, 0x92, 0x22, 0x40, 0x80, 0x32, 0x00, 0x00, 0x8a, 0x92, 0x00, 0x42,
- 0x68, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x6a, 0xb1, 0x01, 0x00,
- 0x8a, 0x92, 0x31, 0x5a, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x42,
- 0x48, 0x93, 0x01, 0x00, 0x8c, 0x92, 0x35, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x6d, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0x91, 0x92, 0x28, 0xb1,
- 0x2c, 0x30, 0x00, 0x00, 0x8d, 0x92, 0x22, 0x4d, 0x75, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x95, 0x40, 0x11, 0xb0, 0x01, 0x00, 0x6d, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x91, 0x92, 0xa8, 0xb1, 0x10, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x95, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x7f, 0x00, 0x00, 0x40,
- 0x61, 0x99, 0x01, 0x00, 0x98, 0x92, 0x28, 0xb1, 0x10, 0x30, 0x00, 0x00,
- 0x94, 0x92, 0x9f, 0xba, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x11, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x24, 0x11, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x9a, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xac, 0x94, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x9e, 0x92, 0x32, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xa4, 0x92, 0x22, 0xf8, 0x96, 0x30, 0x00, 0x00, 0x04, 0x00, 0x22, 0xf8,
- 0x90, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x92, 0xb0, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x4b, 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x92, 0x48,
- 0xe0, 0xc9, 0x01, 0x00, 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00,
- 0xa8, 0x92, 0x28, 0xb1, 0x92, 0x30, 0x00, 0x00, 0xa4, 0x92, 0x22, 0x4c,
- 0x75, 0x7d, 0x00, 0x00, 0x04, 0x00, 0x12, 0x40, 0x91, 0xb0, 0x00, 0x00,
- 0x6c, 0x00, 0x00, 0x40, 0x61, 0x99, 0x01, 0x00, 0xa8, 0x92, 0xa8, 0xb1,
- 0x90, 0x30, 0x00, 0x00, 0xff, 0x00, 0x00, 0x48, 0x96, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x90, 0xd0, 0x01, 0x00, 0x01, 0x00, 0x00, 0x4b,
- 0xf0, 0xcd, 0x01, 0x00, 0x20, 0x00, 0x00, 0x48, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x92, 0x49, 0xe0, 0xb1, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0x82, 0x8c, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
- 0x00, 0xec, 0x00, 0x00, 0xb5, 0x92, 0x22, 0x1a, 0x00, 0x6c, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x00, 0x34, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0xb1, 0x92, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x15, 0x82, 0x8c, 0x01, 0x00,
- 0xff, 0x07, 0x00, 0xf0, 0x00, 0x8c, 0x01, 0x00, 0x00, 0x00, 0xa2, 0x41,
- 0x00, 0xec, 0x00, 0x00, 0xbe, 0x92, 0x22, 0x0d, 0x00, 0x6c, 0x00, 0x00,
- 0x99, 0x92, 0x00, 0x00, 0x1a, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0x49, 0xc1, 0x01, 0x00, 0xba, 0x92, 0xa2, 0x41, 0x23, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xc3, 0x92, 0x83, 0x1e,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x19, 0x90, 0x01, 0x00,
- 0x24, 0x00, 0x2d, 0x01, 0x2c, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x2d, 0xf0,
- 0x16, 0xb0, 0x01, 0x00, 0x22, 0x00, 0x2d, 0xf0, 0x26, 0xb0, 0x01, 0x00,
- 0x14, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x60, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xca, 0x92, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3e, 0x43, 0x9d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x0b, 0xe8, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
- 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x16, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x64, 0x97, 0x3f, 0x43,
- 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x16, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0xe1, 0xb1, 0x01, 0x00, 0x60, 0x17, 0x3d, 0x43,
- 0x9d, 0xe0, 0x01, 0x00, 0x10, 0x00, 0x80, 0xa1, 0x16, 0xe4, 0x01, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x42, 0xc9, 0x01, 0x00, 0xd9, 0x92, 0x30, 0x47,
- 0x17, 0x04, 0x00, 0x00, 0xdc, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x90, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
- 0x46, 0xc9, 0x01, 0x00, 0xe0, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00, 0x00, 0x00, 0x90, 0x41,
- 0x81, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0xe1, 0x92, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0xeb, 0x92, 0xa2, 0x45, 0x95, 0x7c, 0x00, 0x00,
- 0x01, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x96, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00,
- 0x40, 0x97, 0x3e, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e,
- 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40, 0x9d, 0xe0, 0x01, 0x00,
- 0xfe, 0x92, 0x00, 0x3b, 0xe7, 0xb1, 0x00, 0x00, 0xeb, 0x92, 0x30, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xf5, 0x92, 0xa2, 0x0b, 0xe6, 0x7d, 0x00, 0x00,
- 0x00, 0xb5, 0x00, 0x0d, 0x46, 0xc9, 0x01, 0x00, 0xf1, 0x92, 0xa2, 0x0b,
- 0xe6, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x98, 0x42, 0x81, 0xb0, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x0d,
- 0x46, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0b, 0xe6, 0x91, 0x01, 0x00,
- 0x00, 0x00, 0x10, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x41,
- 0x81, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x21, 0xa2, 0x95, 0x20, 0x00, 0x00,
- 0x00, 0x00, 0x10, 0x4a, 0x44, 0x83, 0x01, 0x00, 0x00, 0x97, 0x3e, 0x41,
- 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4e, 0xf6, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4e, 0xe6, 0xb1, 0x01, 0x00, 0x40, 0x97, 0x3e, 0x40,
- 0x9d, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x3b, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00, 0xff, 0xff, 0x00, 0x07,
- 0x92, 0x89, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x03, 0x00, 0x00, 0x08, 0x86, 0xf4, 0x01, 0x00, 0x00, 0xb7, 0x00, 0x43,
- 0x46, 0xc9, 0x01, 0x00, 0x07, 0x00, 0x00, 0x08, 0x82, 0x88, 0x01, 0x00,
- 0x02, 0x93, 0x40, 0x08, 0x96, 0x30, 0x00, 0x00, 0x9d, 0x04, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x0e, 0x93, 0x22, 0x45, 0x95, 0x7c, 0x00, 0x00,
- 0x0a, 0x93, 0x22, 0x5a, 0x1f, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x00, 0x0f,
- 0x96, 0xf4, 0x01, 0x00, 0x07, 0x93, 0x31, 0x5f, 0x97, 0x04, 0x00, 0x00,
- 0x00, 0x00, 0x11, 0x4b, 0x48, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x6a, 0xb1, 0x01, 0x00, 0x0a, 0x93, 0x30, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xe6, 0x81, 0x01, 0x00, 0x00, 0x00, 0x10, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x97, 0x3f, 0x41, 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3,
- 0x96, 0xb0, 0x01, 0x00, 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0xf3, 0x88, 0xb0, 0x01, 0x00, 0x16, 0x93, 0xa2, 0x3b,
- 0x89, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x90, 0xb1, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0xa6, 0x92, 0xb1, 0x01, 0x00, 0x17, 0x93, 0x18, 0x4a,
- 0x44, 0x93, 0x00, 0x00, 0x00, 0x00, 0x18, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x30, 0x00, 0x39, 0x45, 0x97, 0xe0, 0x01, 0x00, 0x1c, 0x93, 0x22, 0x5a,
- 0x1f, 0x7c, 0x00, 0x00, 0x1f, 0x04, 0x00, 0x0f, 0x98, 0xd8, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x5e, 0x94, 0x01, 0x00, 0x1e, 0x93, 0x00, 0x05,
- 0x4a, 0xb0, 0x00, 0x00, 0x1f, 0x04, 0x00, 0xa7, 0x5e, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x4b, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x1f, 0x93, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x22, 0x93, 0x40, 0x07, 0x96, 0x30, 0x00, 0x00,
- 0x9d, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x26, 0x93, 0x22, 0x45,
- 0x95, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x9b, 0x04, 0x00, 0x4a, 0x44, 0x13, 0x01, 0x00, 0x00, 0x97, 0x3f, 0x41,
- 0x95, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00,
- 0x40, 0x97, 0x3d, 0x40, 0x97, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x63, 0xf3,
- 0x88, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x38, 0x45, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x0f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x58,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00,
- 0x2e, 0x93, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x27, 0x93, 0xa2, 0x3b,
- 0x89, 0x6c, 0x00, 0x00, 0x30, 0x00, 0x38, 0x45, 0x9d, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x98, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x93, 0x04, 0x00, 0x12,
- 0x94, 0x30, 0x01, 0x00, 0xff, 0x92, 0x00, 0x5a, 0x1f, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x5a, 0x1f, 0x90, 0x01, 0x00, 0x11, 0x00, 0x00, 0x4a,
- 0xe6, 0xc9, 0x01, 0x00, 0x34, 0x00, 0x2f, 0x4f, 0x95, 0x84, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x63, 0x4b,
- 0x84, 0xc8, 0x01, 0x00, 0x00, 0x00, 0xa0, 0x43, 0x85, 0x6c, 0x01, 0x00,
- 0x00, 0x00, 0xe3, 0x40, 0x85, 0xb0, 0x01, 0x00, 0x30, 0x00, 0x2d, 0x44,
- 0x1f, 0x90, 0x01, 0x00, 0x32, 0x00, 0x2d, 0xf2, 0x2a, 0xb0, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0xf2, 0x02, 0x30, 0x00, 0x00, 0x1e, 0x92, 0x00, 0x10,
- 0x32, 0x30, 0x01, 0x00, 0x32, 0x00, 0xa0, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x40,
- 0x99, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x02, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x03, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x97, 0xc0, 0x01, 0x00, 0x00, 0x00, 0xa3, 0x4c, 0x02, 0xd0, 0x00, 0x00,
- 0x45, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8,
- 0x36, 0xb0, 0x01, 0x00, 0x55, 0x93, 0x22, 0x41, 0x03, 0x50, 0x00, 0x00,
- 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50,
- 0xf1, 0xb1, 0x01, 0x00, 0x70, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x62, 0xb1, 0x01, 0x00, 0x4e, 0x93, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x7c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x00, 0xb0, 0x01, 0x00, 0x49, 0x93, 0x00, 0x5c,
- 0x01, 0x80, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x1b, 0x10, 0xb1, 0x00, 0x00, 0x68, 0x01, 0x2d, 0x06,
- 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x82, 0xc0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x46, 0xc9, 0x01, 0x00, 0x94, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x7c, 0x93, 0x22, 0x40, 0x11, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x68, 0x08, 0x38, 0x96, 0x01, 0x00, 0xf0, 0x07, 0x00, 0x41,
- 0x82, 0xcc, 0x01, 0x00, 0x5a, 0x93, 0xaa, 0x41, 0x3b, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x10, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5c,
- 0x11, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x1d, 0x04, 0xcc, 0x01, 0x00,
- 0x7b, 0x93, 0x26, 0x46, 0x23, 0x30, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03,
- 0x12, 0xc8, 0x01, 0x00, 0x64, 0x01, 0x20, 0xf0, 0xe0, 0xb1, 0x01, 0x00,
- 0x7a, 0x93, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x20, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x0c, 0x00, 0x00, 0xf8, 0x86, 0xc8, 0x01, 0x00,
- 0x00, 0x00, 0x22, 0x44, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x09, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x6c, 0x93, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0x79, 0x93, 0x22, 0x41, 0x05, 0x50, 0x00, 0x00, 0x77, 0x93, 0xa2, 0x41,
- 0x23, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x1a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x72, 0x93, 0xa8, 0x46, 0x23, 0x30, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x03,
- 0x48, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x42, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x13, 0xc0, 0x01, 0x00, 0x67, 0x93, 0x00, 0x50,
- 0x49, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x1a, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x7b, 0x93, 0x22, 0x40, 0x3b, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x00, 0xb0, 0x01, 0x00, 0x99, 0x92, 0x00, 0x5c,
- 0x01, 0x00, 0x01, 0x00, 0x7c, 0x93, 0x00, 0x41, 0x3b, 0xd0, 0x00, 0x00,
- 0x00, 0x00, 0x8d, 0x47, 0x80, 0x32, 0x01, 0x00, 0xb0, 0x00, 0x2f, 0x5f,
- 0x13, 0xb0, 0x01, 0x00, 0x00, 0x00, 0xe0, 0xf0, 0x8c, 0xc0, 0x01, 0x00,
- 0x00, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x8c, 0xb0, 0x01, 0x00,
- 0x88, 0x93, 0x8c, 0xf8, 0x8e, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
- 0x19, 0x90, 0x01, 0x00, 0x04, 0x00, 0x22, 0xf8, 0x14, 0x30, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x16, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x26, 0xb0, 0x01, 0x00, 0x08, 0x00, 0x2e, 0xf8, 0x0c, 0xb0, 0x01, 0x00,
- 0x0c, 0x00, 0x2a, 0x4a, 0xe0, 0xb1, 0x01, 0x00, 0x28, 0x00, 0x00, 0x00,
- 0xe0, 0xc9, 0x01, 0x00, 0x10, 0x00, 0x20, 0x1b, 0xe0, 0xb1, 0x01, 0x00,
- 0x95, 0x93, 0x20, 0x0a, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8,
- 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x96, 0xb0, 0x01, 0x00,
- 0x20, 0x00, 0x20, 0xf0, 0xe4, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x20, 0x4a,
- 0xe0, 0xb1, 0x01, 0x00, 0x1c, 0x00, 0x20, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
- 0x80, 0x93, 0x00, 0x40, 0x13, 0xb0, 0x00, 0x00, 0x2c, 0x00, 0x2d, 0x42,
- 0x19, 0x90, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x82, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf3, 0x96, 0xb0, 0x01, 0x00, 0x9b, 0x93, 0xa2, 0xa5,
- 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00,
- 0x9e, 0x93, 0xa2, 0x40, 0x97, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x2d, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x63, 0x41, 0x97, 0xc0, 0x01, 0x00, 0xd4, 0x00, 0x3e, 0x41,
- 0x83, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x83, 0xc0, 0x01, 0x00,
- 0xa3, 0x93, 0xa0, 0xa5, 0x83, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x83, 0xb0, 0x01, 0x00, 0x2c, 0x00, 0x20, 0x41, 0xe6, 0xb1, 0x01, 0x00,
- 0xa8, 0x93, 0x22, 0x40, 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
- 0x98, 0xdc, 0x01, 0x00, 0x0b, 0x00, 0x00, 0x4c, 0xe4, 0xf5, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x1f, 0x80, 0x01, 0x00, 0x0b, 0x00, 0x80, 0x00,
- 0xe4, 0xf5, 0x01, 0x00, 0x9d, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x04, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0x41, 0x87, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
- 0xb4, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x9d, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x48, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x45, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00,
- 0xc3, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x2e, 0x00, 0x2f, 0xf3, 0x84, 0xb0, 0x01, 0x00,
- 0x01, 0x00, 0x63, 0xf3, 0x96, 0xc8, 0x01, 0x00, 0xcb, 0x93, 0x9f, 0x41,
- 0x85, 0x50, 0x00, 0x00, 0x01, 0x00, 0x00, 0xa5, 0x85, 0xcc, 0x01, 0x00,
- 0x2d, 0x00, 0xa0, 0x42, 0xe6, 0xb1, 0x01, 0x00, 0x5e, 0x01, 0x2d, 0x00,
- 0x80, 0xb0, 0x01, 0x00, 0xd0, 0x93, 0x52, 0x43, 0x81, 0x60, 0x00, 0x00,
- 0x02, 0x00, 0x00, 0xf2, 0x82, 0xf4, 0x01, 0x00, 0xd1, 0x93, 0x00, 0x41,
- 0x80, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x81, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x5e, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x95, 0xb0, 0x00, 0x00,
- 0xd2, 0x93, 0x9e, 0xbb, 0x80, 0x32, 0x00, 0x00, 0xd7, 0x93, 0xa2, 0x40,
- 0x1f, 0x7c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x41, 0x95, 0xb0, 0x01, 0x00, 0x04, 0x00, 0x00, 0x15,
- 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0x2b, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x24, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfc,
- 0x38, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfe, 0x3a, 0xb0, 0x01, 0x00, 0xec, 0x93, 0x9c, 0x17,
- 0x80, 0x32, 0x00, 0x00, 0xe1, 0x93, 0xa2, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x4c, 0x1f, 0x90, 0x01, 0x00, 0x0c, 0x00, 0x00, 0x1e,
- 0x98, 0xf4, 0x01, 0x00, 0xe0, 0x93, 0xa2, 0x48, 0x99, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x15, 0x42, 0xb1, 0x01, 0x00, 0xe0, 0x93, 0xa2, 0x8a,
- 0xf1, 0x6d, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0x02, 0xcc, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xfc, 0x3e, 0xb0, 0x01, 0x00, 0x01, 0x00, 0x00, 0xf4,
- 0x28, 0xcc, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00,
- 0xeb, 0x93, 0x20, 0xf0, 0x3e, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x1f, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x2b, 0xc0, 0x01, 0x00,
- 0xbf, 0x00, 0x2d, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0xf3,
- 0x3a, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x07, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
- 0xe6, 0xb1, 0x01, 0x00, 0x18, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x1c, 0x00, 0x2d, 0xf0, 0x16, 0xb0, 0x01, 0x00, 0x20, 0x00, 0x2d, 0xf0,
- 0x26, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2f, 0xf2, 0x0c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x06, 0x14, 0xec, 0x00, 0x00, 0xf8, 0x93, 0x22, 0x45,
- 0x1f, 0x7c, 0x00, 0x00, 0x00, 0x00, 0xa3, 0x06, 0x2a, 0xec, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xf8, 0x94, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x96, 0xb0, 0x01, 0x00, 0x0c, 0x00, 0x2d, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x2a, 0x4c, 0xe1, 0xc1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x10,
- 0x48, 0xc9, 0x01, 0x00, 0x0a, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x18, 0x00, 0x00, 0x05, 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0xe0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x02, 0x94, 0xa8, 0x5c, 0x1f, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x05, 0x48, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x03, 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00,
- 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x06, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0x0c, 0x94, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x0d, 0x94, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x62, 0xc9, 0x01, 0x00,
- 0x0f, 0x94, 0xa8, 0x00, 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10, 0x48, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x01, 0xf0, 0xcd, 0x01, 0x00, 0x40, 0x00, 0x00, 0x03,
- 0xf0, 0xc9, 0x01, 0x00, 0x40, 0x00, 0x00, 0x00, 0xe0, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x2e, 0x50, 0x49, 0xc1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00,
- 0x19, 0x94, 0x62, 0x42, 0x61, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x1a, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xa0, 0x00, 0x00, 0xa4, 0x62, 0xdd, 0x01, 0x00, 0x1c, 0x94, 0xa8, 0x00,
- 0xe0, 0x31, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x30, 0x80, 0x00, 0x4a, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06,
- 0xf1, 0xb1, 0x01, 0x00, 0xc0, 0xa8, 0x3d, 0x46, 0x0d, 0xe0, 0x01, 0x00,
- 0xff, 0x7f, 0x00, 0xa1, 0xf0, 0x89, 0x01, 0x00, 0x02, 0x00, 0x00, 0x09,
- 0x96, 0xf4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0x97, 0xe0, 0x01, 0x00,
- 0x00, 0x00, 0x60, 0xa8, 0x97, 0xc0, 0x01, 0x00, 0x26, 0x94, 0x63, 0x42,
- 0x61, 0x31, 0x00, 0x00, 0x30, 0x00, 0x00, 0x4a, 0x62, 0xc9, 0x01, 0x00,
- 0x27, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x99, 0x3f, 0x42, 0x97, 0xf0, 0x01, 0x00,
- 0x2b, 0x94, 0x65, 0x40, 0x81, 0x32, 0x00, 0x00, 0x33, 0x94, 0x22, 0xf3,
- 0x74, 0x06, 0x00, 0x00, 0x3f, 0x00, 0x00, 0xf3, 0x94, 0x88, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x07, 0xe7, 0x85, 0x01, 0x00, 0x00, 0x00, 0x75, 0x55,
- 0x61, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a, 0x62, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x30, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x40, 0x81, 0xb2, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa8, 0x36, 0xb0, 0x01, 0x00, 0x43, 0x94, 0x82, 0x41,
- 0x23, 0x40, 0x00, 0x00, 0x38, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x20, 0x80, 0x00, 0x10,
- 0x42, 0xc9, 0x01, 0x00, 0x3e, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x3b, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x23, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x32, 0xb0, 0x01, 0x00,
- 0x43, 0x94, 0x22, 0x41, 0x19, 0x7c, 0x00, 0x00, 0xaf, 0x92, 0x00, 0x43,
- 0x23, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x23, 0xb0, 0x01, 0x00,
- 0x45, 0x94, 0xa3, 0x15, 0x0c, 0x6c, 0x00, 0x00, 0x46, 0x94, 0x00, 0x06,
- 0x04, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x04, 0xb0, 0x01, 0x00,
- 0x48, 0x94, 0x20, 0x02, 0x1a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d,
- 0x04, 0xb0, 0x01, 0x00, 0x07, 0x95, 0x00, 0x05, 0x48, 0x31, 0x01, 0x00,
- 0x72, 0x94, 0x22, 0x02, 0x14, 0x50, 0x00, 0x00, 0x4c, 0x94, 0xa2, 0x02,
- 0x2a, 0x50, 0x00, 0x00, 0x72, 0x94, 0xa2, 0x45, 0x1f, 0x7c, 0x00, 0x00,
- 0x4e, 0x94, 0x22, 0x02, 0x0c, 0x50, 0x00, 0x00, 0x57, 0x94, 0x00, 0x02,
- 0x16, 0xc0, 0x00, 0x00, 0x56, 0x94, 0x22, 0x5c, 0x1f, 0x7c, 0x00, 0x00,
- 0x30, 0x80, 0x00, 0x10, 0x42, 0xc9, 0x01, 0x00, 0x56, 0x94, 0x22, 0x40,
- 0xe3, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x61, 0xb1, 0x01, 0x00,
- 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x52, 0x94, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0x48, 0xb1, 0x01, 0x00, 0xf1, 0x93, 0x00, 0x5c,
- 0x1f, 0x00, 0x01, 0x00, 0x72, 0x94, 0x22, 0x15, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0x33, 0xc0, 0x01, 0x00, 0x71, 0x94, 0xa2, 0x02,
- 0x1a, 0x50, 0x00, 0x00, 0x63, 0x94, 0x22, 0x46, 0x1f, 0x7c, 0x00, 0x00,
- 0x70, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46,
- 0x1f, 0x80, 0x01, 0x00, 0x63, 0x94, 0x22, 0x40, 0xe3, 0x6d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x5f, 0x94, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x88, 0x1c, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05,
- 0x48, 0xb1, 0x01, 0x00, 0x0c, 0x80, 0x00, 0x03, 0x42, 0xc9, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0xf0, 0x10, 0xc8, 0x01, 0x00, 0x2f, 0x00, 0x2f, 0x5c,
- 0x11, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x47, 0xe7, 0x91, 0x01, 0x00,
- 0xf0, 0x07, 0x00, 0x40, 0x1b, 0x98, 0x01, 0x00, 0x35, 0x94, 0x20, 0x15,
- 0x1a, 0x6c, 0x00, 0x00, 0x70, 0x00, 0x00, 0x03, 0x48, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x22, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03,
- 0xf0, 0xb1, 0x01, 0x00, 0xff, 0x07, 0x00, 0x08, 0xe0, 0x8d, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x61, 0xb1, 0x01, 0x00, 0xa0, 0x00, 0x00, 0xa4,
- 0x62, 0xdd, 0x01, 0x00, 0x6e, 0x94, 0xa8, 0x46, 0x1f, 0x10, 0x00, 0x00,
- 0x35, 0x94, 0x00, 0x05, 0x48, 0xb1, 0x00, 0x00, 0x35, 0x94, 0x00, 0x02,
- 0x10, 0xc0, 0x00, 0x00, 0x74, 0x94, 0xa2, 0x44, 0x1f, 0x7c, 0x00, 0x00,
- 0xa7, 0x91, 0x00, 0x01, 0x8c, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x1b,
- 0x10, 0xb1, 0x00, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00, 0x10, 0x00, 0x00, 0x08,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x03, 0xe0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x5c, 0x1f, 0x90, 0x00, 0x00, 0x7b, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0xa2, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x40, 0x27, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
- 0x00, 0xb0, 0x01, 0x00, 0x99, 0x92, 0x00, 0x41, 0xa3, 0x41, 0x01, 0x00,
- 0x7f, 0x94, 0x00, 0x41, 0x27, 0xd0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b, 0x80, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x86, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd8, 0x94, 0x00, 0x40,
- 0x2b, 0x30, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x06, 0x16, 0xc0, 0x01, 0x00,
- 0x90, 0x00, 0x2d, 0xf0, 0x16, 0xc4, 0x01, 0x00, 0x8e, 0x94, 0xa0, 0xf0,
- 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x0e, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xf0,
- 0x30, 0xb0, 0x01, 0x00, 0xac, 0x00, 0x2d, 0x40, 0x87, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x6c, 0xf0, 0x28, 0xb0, 0x01, 0x00, 0x97, 0x94, 0x22, 0x4a,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x43, 0x86, 0xc8, 0x01, 0x00,
- 0x00, 0x30, 0x00, 0x0b, 0x16, 0xc8, 0x01, 0x00, 0x97, 0x94, 0xa4, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0xb8, 0x94, 0x22, 0x06, 0x80, 0x32, 0x00, 0x00, 0xa4, 0x94, 0xa2, 0x06,
- 0x14, 0x6c, 0x00, 0x00, 0xa1, 0x94, 0x22, 0x48, 0x19, 0x7c, 0x00, 0x00,
- 0x9c, 0x94, 0xa0, 0x41, 0x17, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0x31, 0xc0, 0x01, 0x00,
- 0x90, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0x48,
- 0x19, 0x80, 0x01, 0x00, 0x8b, 0x00, 0x20, 0x45, 0xe7, 0x91, 0x01, 0x00,
- 0xa4, 0x94, 0x00, 0x40, 0x87, 0x90, 0x00, 0x00, 0x08, 0x00, 0x00, 0x43,
- 0x86, 0x98, 0x01, 0x00, 0xa4, 0x94, 0xa0, 0x48, 0x17, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00, 0xb0, 0x00, 0x00, 0x40,
- 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43, 0xfc, 0xc9, 0x01, 0x00,
- 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xe5, 0xb1, 0x01, 0x00, 0xaf, 0x94, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00,
- 0x08, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab,
- 0xf9, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00,
- 0xae, 0x94, 0xa0, 0xf0, 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0xb3, 0x94, 0x64, 0xf0, 0x82, 0xb0, 0x00, 0x00,
- 0xa4, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0xb3, 0x94, 0xa2, 0xf2,
- 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe5, 0xb1, 0x01, 0x00,
- 0x8c, 0x00, 0x20, 0x18, 0xe0, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x60, 0x06, 0x30, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x86, 0x0c, 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0x46,
- 0x19, 0x90, 0x01, 0x00, 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00,
- 0xb0, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x10, 0x50, 0x00, 0x43,
- 0xfc, 0xc9, 0x01, 0x00, 0x0f, 0x95, 0x00, 0x30, 0x81, 0x30, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x4a, 0x19, 0xfc, 0x00, 0x00, 0x08, 0x00, 0x00, 0xa2,
- 0x44, 0xc9, 0x01, 0x00, 0xcc, 0x00, 0x2d, 0xab, 0xf9, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xab, 0x17, 0xc0, 0x01, 0x00, 0xc1, 0x94, 0xa0, 0xf0,
- 0x16, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x17, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0xe4, 0xf0, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x1b, 0xe0, 0xb1, 0x00, 0x00, 0xc6, 0x94, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x0c, 0x7e, 0x89, 0x01, 0x00,
- 0x00, 0x00, 0xa6, 0x4c, 0x95, 0x60, 0x01, 0x00, 0x00, 0x00, 0x80, 0x4a,
- 0x18, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00, 0x20, 0x00, 0x00, 0x40,
- 0xf0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x16, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10,
- 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15, 0xe0, 0xb1, 0x00, 0x00,
- 0xd1, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x10, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x01, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x5f,
- 0x17, 0x90, 0x01, 0x00, 0x70, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x7a, 0x01, 0x2e, 0xfe, 0x92, 0xb0, 0x01, 0x00, 0x8b, 0x00, 0x2d, 0xf6,
- 0x16, 0xb0, 0x01, 0x00, 0xde, 0x94, 0x22, 0x43, 0xe7, 0x7d, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x45, 0xc1, 0x01, 0x00, 0x04, 0x00, 0x00, 0xa6,
- 0x2a, 0xb0, 0x01, 0x00, 0x28, 0x00, 0x6e, 0x06, 0x82, 0xc8, 0x01, 0x00,
- 0xe2, 0x94, 0x22, 0x4a, 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42,
- 0x45, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x6e, 0x4c, 0x83, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x92, 0xc0, 0x01, 0x00, 0xe3, 0x94, 0x43, 0x30,
- 0x3d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x66, 0x9e, 0x83, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x1b, 0x41, 0x3d, 0xc3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x92, 0xc0, 0x01, 0x00, 0x06, 0x00, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00,
- 0x10, 0x00, 0x00, 0x49, 0x98, 0xf4, 0x01, 0x00, 0xec, 0x94, 0x26, 0x30,
- 0x93, 0x04, 0x00, 0x00, 0xec, 0x94, 0x90, 0x4c, 0x92, 0x40, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x93, 0xc0, 0x01, 0x00, 0xff, 0xff, 0x80, 0x49,
- 0xec, 0xa9, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x04, 0x00, 0x22, 0x01, 0xf0, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf0, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x15,
- 0xe0, 0xb1, 0x00, 0x00, 0xf1, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xfe, 0x94, 0x22, 0x5f, 0x81, 0x7c, 0x00, 0x00, 0xfd, 0x94, 0xa2, 0x40,
- 0x19, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x19, 0x90, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x54, 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x97, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0xfd, 0x94, 0x28, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xfa, 0x94, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x00, 0x00, 0xa2, 0x21, 0x81, 0x84, 0x00, 0x00, 0x01, 0x95, 0xa2, 0x5f,
- 0x81, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x43, 0x19, 0x7c, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x43, 0x19, 0x90, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54,
- 0x61, 0xb1, 0x01, 0x00, 0x10, 0x00, 0x00, 0x07, 0x96, 0xe4, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x96, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x80, 0x00, 0x19,
- 0x44, 0xc9, 0x01, 0x00, 0x04, 0x00, 0x22, 0x02, 0xf0, 0x31, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x0b, 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x13,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x43, 0x61, 0xb1, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0x19, 0x62, 0xdd, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x08,
- 0xe0, 0xb1, 0x00, 0x00, 0x0c, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x7c, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0xf0,
- 0x98, 0xf4, 0x01, 0x00, 0x15, 0x95, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00,
- 0x88, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00, 0x15, 0x95, 0x20, 0xf2,
- 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00,
- 0x98, 0x00, 0x2d, 0x14, 0x82, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0,
- 0x98, 0xb0, 0x01, 0x00, 0xa3, 0x00, 0x2d, 0x14, 0x98, 0xd0, 0x01, 0x00,
- 0x1a, 0x95, 0x20, 0x4c, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c,
- 0x84, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x80, 0xe0, 0x01, 0x00,
- 0x1d, 0x95, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x84, 0xb0, 0x01, 0x00, 0xd0, 0x00, 0x20, 0x14, 0xe0, 0xb1, 0x01, 0x00,
- 0x98, 0x00, 0x25, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x6e, 0xf3,
- 0x80, 0xf0, 0x01, 0x00, 0x00, 0x00, 0xa6, 0x42, 0x82, 0xc0, 0x00, 0x00,
- 0x23, 0x95, 0xa0, 0x40, 0x16, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x17, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0, 0x82, 0xec, 0x00, 0x00,
- 0x98, 0x00, 0xa0, 0x41, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x10,
- 0x48, 0xb1, 0x01, 0x00, 0xa8, 0x01, 0x00, 0x40, 0xf1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x05, 0xf0, 0xb1, 0x01, 0x00, 0x09, 0x00, 0x00, 0x07,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x00, 0x60, 0xa7, 0x97, 0xc0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x10, 0x62, 0xb1, 0x01, 0x00, 0x00, 0x00, 0xa8, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x2a, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xa8, 0x00, 0x2d, 0x1c, 0x8a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x9f, 0xf0,
- 0x8a, 0xd0, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x40, 0x8b, 0xec, 0x00, 0x00,
- 0x8a, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0xa4, 0x00, 0x2d, 0x45, 0xe0, 0xd1, 0x01, 0x00,
- 0x37, 0x95, 0x9c, 0x17, 0x80, 0x32, 0x00, 0x00, 0xbe, 0x00, 0x2f, 0xab,
- 0x83, 0xb0, 0x01, 0x00, 0x88, 0x95, 0x00, 0x14, 0x82, 0x50, 0x01, 0x00,
- 0x3c, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x3c, 0x95, 0x22, 0xf2,
- 0x82, 0x30, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x3c, 0x95, 0x9f, 0x1c, 0xe0, 0x6d, 0x00, 0x00, 0xbe, 0x00, 0x00, 0x40,
- 0x47, 0x99, 0x01, 0x00, 0x88, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0xa8, 0x00, 0x20, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0x30,
- 0x81, 0xb0, 0x01, 0x00, 0x88, 0x00, 0x2d, 0xf0, 0x84, 0xb0, 0x01, 0x00,
- 0x94, 0x00, 0x2d, 0xf2, 0x86, 0xb0, 0x01, 0x00, 0x4f, 0x95, 0x23, 0xf0,
- 0x84, 0x6c, 0x00, 0x00, 0x44, 0x95, 0x23, 0x92, 0x87, 0x6c, 0x00, 0x00,
- 0xc9, 0x04, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00, 0x46, 0x95, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x20, 0x00, 0x00, 0xa6, 0x94, 0xb0, 0x01, 0x00,
- 0x60, 0x89, 0x00, 0x4a, 0x94, 0x98, 0x01, 0x00, 0x46, 0x95, 0x68, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a, 0xb0, 0xb1, 0x01, 0x00,
- 0xbf, 0x00, 0x2d, 0x42, 0xb2, 0xb1, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3,
- 0x80, 0xe0, 0x01, 0x00, 0x4a, 0x95, 0xd4, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x78, 0xda, 0x84, 0xc0, 0x01, 0x00, 0x54, 0x95, 0x23, 0x40,
- 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d, 0xe1, 0xb1, 0x01, 0x00,
- 0x54, 0x95, 0x00, 0x40, 0x84, 0xb0, 0x00, 0x00, 0xbf, 0x00, 0x2d, 0x43,
- 0x84, 0xc0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf3, 0x80, 0xe0, 0x01, 0x00,
- 0x54, 0x95, 0x23, 0x40, 0x84, 0x6c, 0x00, 0x00, 0x94, 0x00, 0x20, 0x9d,
- 0xe1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xb0, 0x01, 0x00,
- 0x58, 0x95, 0xa2, 0xf0, 0x38, 0x6c, 0x00, 0x00, 0x9c, 0x00, 0x20, 0x42,
- 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00,
- 0x00, 0x00, 0x80, 0x46, 0x19, 0x80, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x42,
- 0xe0, 0xb1, 0x01, 0x00, 0x37, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x04, 0x00, 0x00, 0xf3, 0x80, 0xf4, 0x01, 0x00, 0x0f, 0x00, 0x00, 0xf3,
- 0x82, 0x88, 0x01, 0x00, 0x5e, 0x95, 0x23, 0x41, 0x80, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x5f, 0x13, 0x94, 0x01, 0x00, 0x00, 0x00, 0x89, 0x0c,
- 0x80, 0xb2, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0xa0, 0x00, 0xa0, 0xf2, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x9f, 0x41,
- 0x24, 0xec, 0x00, 0x00, 0x68, 0x95, 0xa6, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x9f, 0x42, 0x38, 0xec, 0x00, 0x00, 0x68, 0x95, 0xa6, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x6a, 0x95, 0xa3, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0xb4, 0x00, 0x00, 0x40, 0x43, 0x99, 0x01, 0x00,
- 0x6e, 0x95, 0x22, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0xb4, 0x00, 0x20, 0x1d,
- 0xe0, 0xb1, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x5f, 0x13, 0x94, 0x01, 0x00,
- 0x6e, 0x95, 0x23, 0xf0, 0x3a, 0x6c, 0x00, 0x00, 0x80, 0x00, 0x20, 0x1d,
- 0xe0, 0xb1, 0x01, 0x00, 0xc0, 0x00, 0x20, 0x12, 0xe0, 0xb1, 0x01, 0x00,
- 0xc4, 0x00, 0xa0, 0x1c, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x42, 0xe0, 0xb1, 0x01, 0x00,
- 0x12, 0x00, 0x00, 0x40, 0x87, 0x98, 0x01, 0x00, 0x77, 0x95, 0x9f, 0x41,
- 0x24, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8c, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x12, 0x8c, 0xd0, 0x01, 0x00, 0x78, 0x95, 0x00, 0x41,
- 0x24, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8d, 0xb0, 0x01, 0x00,
- 0xc6, 0x95, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x40, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x7a, 0x95, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x8c, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x00, 0xa2, 0x08, 0x80, 0x32, 0x01, 0x00, 0x81, 0x95, 0xa2, 0x40,
- 0x95, 0x6c, 0x00, 0x00, 0x99, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00,
- 0x00, 0x82, 0x00, 0xa6, 0x04, 0xb0, 0x01, 0x00, 0xa0, 0x98, 0x2f, 0x40,
- 0x11, 0xb0, 0x01, 0x00, 0x30, 0x05, 0x00, 0x41, 0x89, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x9f, 0xf8, 0x3e, 0xec, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x12,
- 0xe0, 0xed, 0x00, 0x00, 0xc8, 0x00, 0x20, 0xab, 0xe1, 0xb1, 0x01, 0x00,
- 0xcc, 0x00, 0xa0, 0x1f, 0xe0, 0xb1, 0x01, 0x00, 0x8a, 0x95, 0xa3, 0x5f,
- 0xe7, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0xe7, 0xc1, 0x01, 0x00,
- 0xa6, 0x00, 0x00, 0x40, 0x47, 0x99, 0x01, 0x00, 0x9e, 0x95, 0x22, 0xf2,
- 0x86, 0x30, 0x00, 0x00, 0x03, 0x00, 0x00, 0x43, 0x84, 0xf4, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x41, 0x80, 0xcc, 0x01, 0x00, 0xb8, 0x00, 0x2d, 0x42,
- 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40, 0x86, 0xc0, 0x01, 0x00,
- 0x92, 0x95, 0x1f, 0x43, 0x80, 0x32, 0x00, 0x00, 0x93, 0x95, 0xa2, 0x40,
- 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x62, 0x41, 0x87, 0xb0, 0x01, 0x00,
- 0x97, 0x95, 0x9f, 0x40, 0x80, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x85, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x84, 0xd0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x80, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf2,
- 0x88, 0xb0, 0x01, 0x00, 0x02, 0x00, 0x00, 0x44, 0x84, 0xf4, 0x01, 0x00,
- 0xb8, 0x00, 0x2e, 0x42, 0x80, 0xd0, 0x01, 0x00, 0x00, 0x00, 0x62, 0x40,
- 0x88, 0xc0, 0x01, 0x00, 0x9d, 0x95, 0x1f, 0x44, 0x80, 0x32, 0x00, 0x00,
- 0xa1, 0x95, 0xa2, 0x40, 0x89, 0x6c, 0x00, 0x00, 0xa1, 0x95, 0x62, 0x41,
- 0x89, 0xb0, 0x00, 0x00, 0x03, 0x00, 0x62, 0x41, 0x86, 0xe4, 0x01, 0x00,
- 0xb8, 0x00, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00, 0x01, 0x00, 0x62, 0x41,
- 0x88, 0xe4, 0x01, 0x00, 0xa4, 0x00, 0x20, 0x40, 0xe5, 0xb1, 0x01, 0x00,
- 0xa2, 0x00, 0x20, 0x40, 0xe7, 0xb1, 0x01, 0x00, 0xbc, 0x00, 0x2e, 0x43,
- 0x87, 0xf0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x86, 0xc0, 0x01, 0x00,
- 0xa7, 0x95, 0x20, 0x43, 0x87, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x43,
- 0xe5, 0xb1, 0x01, 0x00, 0x40, 0x01, 0x00, 0x43, 0x80, 0xce, 0x01, 0x00,
- 0x00, 0x00, 0xa4, 0x43, 0xe4, 0x31, 0x01, 0x00, 0x40, 0x01, 0xe2, 0x40,
- 0x87, 0x98, 0x01, 0x00, 0x88, 0x00, 0x2d, 0x44, 0x81, 0xb0, 0x01, 0x00,
- 0x90, 0x00, 0x2d, 0xf2, 0x2e, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x2d, 0xf0,
- 0x86, 0xb0, 0x01, 0x00, 0x90, 0x00, 0x2d, 0xf0, 0x82, 0xb0, 0x01, 0x00,
- 0xba, 0x00, 0x2d, 0xf0, 0x98, 0xb0, 0x01, 0x00, 0xb4, 0x95, 0xa2, 0x12,
- 0x98, 0x6c, 0x00, 0x00, 0xbc, 0x00, 0x2d, 0xf2, 0x98, 0xb0, 0x01, 0x00,
- 0xb4, 0x95, 0xa0, 0xf2, 0x98, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
- 0x82, 0xb0, 0x01, 0x00, 0x9c, 0x00, 0x20, 0x41, 0xe0, 0xb1, 0x01, 0x00,
- 0xb4, 0x00, 0x2d, 0x12, 0x86, 0xd0, 0x01, 0x00, 0xb7, 0x95, 0xa3, 0x41,
- 0xe0, 0x6d, 0x00, 0x00, 0xb8, 0x95, 0x00, 0xf0, 0x84, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x41, 0x84, 0xb0, 0x01, 0x00, 0x80, 0x00, 0x2d, 0x43,
- 0x84, 0xd0, 0x01, 0x00, 0xbb, 0x95, 0x9f, 0x42, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x85, 0xb0, 0x01, 0x00, 0xbd, 0x95, 0xa3, 0x42,
- 0x14, 0x6c, 0x00, 0x00, 0xbe, 0x95, 0x00, 0x0a, 0x0c, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x42, 0x0c, 0xb0, 0x01, 0x00, 0xc0, 0x95, 0xa0, 0x17,
- 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x80, 0x17, 0x0c, 0xb0, 0x01, 0x00,
- 0xc5, 0x95, 0x22, 0x40, 0x0d, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0a,
- 0x0c, 0xec, 0x00, 0x00, 0x01, 0x00, 0x00, 0xf0, 0x82, 0xf4, 0x01, 0x00,
- 0xc5, 0x95, 0xa0, 0x41, 0x0c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xf0,
- 0x80, 0x32, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40, 0x81, 0xb0, 0x01, 0x00,
- 0x9d, 0x92, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x04, 0x80, 0x00, 0x03,
- 0x44, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x46, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x60, 0x41,
- 0x87, 0x94, 0x01, 0x00, 0x00, 0x80, 0x00, 0x10, 0x44, 0xc9, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x50, 0xf1, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x48,
- 0xf0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0xf0, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x03, 0xe0, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x45,
- 0x61, 0xb1, 0x01, 0x00, 0x20, 0x00, 0x00, 0x10, 0x62, 0xdd, 0x01, 0x00,
- 0x00, 0x00, 0xa8, 0x5d, 0x05, 0x90, 0x00, 0x00, 0xd1, 0x95, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x2e, 0x4b, 0x19, 0x90, 0x01, 0x00,
- 0x05, 0x00, 0x2a, 0x0c, 0xe4, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x04,
- 0xe6, 0xb1, 0x01, 0x00, 0xd7, 0x95, 0x45, 0x48, 0x61, 0x31, 0x00, 0x00,
- 0x00, 0x10, 0x00, 0x08, 0x62, 0xdd, 0x01, 0x00, 0xdc, 0x95, 0x28, 0x40,
- 0x87, 0x30, 0x00, 0x00, 0xd8, 0x95, 0x22, 0x48, 0x77, 0x7d, 0x00, 0x00,
- 0x7e, 0x94, 0x1d, 0x46, 0x87, 0xb0, 0x00, 0x00, 0xdf, 0x95, 0x22, 0x5f,
- 0x11, 0x7c, 0x00, 0x00, 0x04, 0x00, 0x22, 0x15, 0x62, 0x31, 0x00, 0x00,
- 0xdd, 0x95, 0xa8, 0x40, 0x81, 0x32, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00,
- 0x00, 0x14, 0x2f, 0x4c, 0x83, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xe2, 0x95, 0xa2, 0x41, 0x83, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x49, 0xb1, 0x01, 0x00, 0x30, 0x00, 0x00, 0x40, 0xa1, 0x99, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x93, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x1f, 0xb0, 0x01, 0x00, 0x35, 0x96, 0x00, 0x49, 0x96, 0x30, 0x01, 0x00,
- 0x07, 0x00, 0x00, 0x49, 0x06, 0xe4, 0x01, 0x00, 0x00, 0x39, 0x00, 0x03,
- 0x06, 0xc8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0xb0, 0x01, 0x00,
- 0x20, 0x00, 0x00, 0xd0, 0xa0, 0xc9, 0x01, 0x00, 0x00, 0x00, 0x00, 0x41,
- 0x93, 0xc0, 0x01, 0x00, 0xe9, 0x95, 0xa0, 0x54, 0x93, 0x6c, 0x00, 0x00,
- 0x00, 0x00, 0x2e, 0x05, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x80, 0x00, 0x40,
- 0x49, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xe1, 0xb1, 0x01, 0x00,
- 0x00, 0x02, 0x00, 0xa2, 0x44, 0xc9, 0x01, 0x00, 0xf2, 0x95, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0xb3, 0x01, 0x00,
- 0x3b, 0x96, 0x00, 0x40, 0x49, 0x31, 0x01, 0x00, 0xc8, 0x92, 0x00, 0x40,
- 0x81, 0x32, 0x01, 0x00, 0x00, 0xb5, 0x2e, 0x08, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0xf9, 0x95, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x18, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x00, 0x97, 0x2e, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0xfd, 0x95, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x49, 0xb1, 0x01, 0x00, 0x40, 0x18, 0x2e, 0x05,
- 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x01, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x57, 0x95, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0x30, 0x94, 0x00, 0x40, 0x45, 0x99, 0x01, 0x00,
- 0x64, 0x00, 0x00, 0x40, 0xe5, 0x99, 0x01, 0x00, 0x56, 0x95, 0x20, 0x40,
- 0xe7, 0xb1, 0x01, 0x00, 0xb8, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00,
- 0xba, 0x94, 0x20, 0x41, 0xe5, 0xb1, 0x01, 0x00, 0x98, 0x94, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x02, 0x00, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00, 0x0b, 0x96, 0xa2, 0x41,
- 0x97, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x97, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x6f, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x68, 0xb1, 0x01, 0x00, 0x0f, 0x96, 0x85, 0x41, 0x97, 0x40, 0x00, 0x00,
- 0x80, 0x04, 0x00, 0x40, 0x81, 0x32, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x39, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x37, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x35, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x33, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x41, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x3f, 0xb3, 0x01, 0x00, 0xee, 0x05, 0x00, 0x40,
- 0x25, 0x9b, 0x01, 0x00, 0x42, 0x00, 0x00, 0x40, 0x4b, 0x9b, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x2f, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x2d, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x47, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x43, 0xb3, 0x01, 0x00, 0x60, 0x00, 0x00, 0x40,
- 0x2b, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x54, 0xef, 0x93, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x55, 0xf1, 0x93, 0x01, 0x00, 0xff, 0xff, 0x00, 0xa5,
- 0x3c, 0x8b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x5b, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x2c, 0x45, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x59, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x57, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x40, 0x27, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x53, 0xb3, 0x01, 0x00, 0x2b, 0x96, 0xa2, 0x50, 0xfd, 0x7f, 0x00, 0x00,
- 0x2b, 0x96, 0xa2, 0x51, 0xfd, 0x7f, 0x00, 0x00, 0x2c, 0x96, 0x00, 0x40,
- 0x1d, 0xb3, 0x00, 0x00, 0x50, 0x46, 0x00, 0x40, 0x1d, 0x9b, 0x01, 0x00,
- 0x00, 0xc0, 0x00, 0xa6, 0x88, 0xb3, 0x01, 0x00, 0xff, 0x3f, 0x00, 0xa6,
- 0x3a, 0xb3, 0x01, 0x00, 0x00, 0xc0, 0x00, 0x9d, 0x3b, 0x9b, 0x01, 0x00,
- 0xb4, 0x05, 0x00, 0x40, 0x23, 0x9b, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0x4d, 0xb3, 0x01, 0x00, 0x08, 0x0a, 0x00, 0xa6, 0x14, 0xb3, 0x01, 0x00,
- 0x01, 0x01, 0x00, 0x8a, 0x15, 0x9b, 0x01, 0x00, 0x00, 0x80, 0x00, 0xa6,
- 0x56, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x80, 0x5e, 0x57, 0xb5, 0x01, 0x00,
- 0x18, 0x00, 0x00, 0x4b, 0x20, 0xe4, 0x01, 0x00, 0x06, 0x00, 0x00, 0x4b,
- 0x96, 0xe4, 0x01, 0x00, 0x00, 0x43, 0x00, 0x4b, 0x96, 0xc8, 0x01, 0x00,
- 0x18, 0x00, 0x00, 0x10, 0x20, 0xdc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4b,
- 0x20, 0x94, 0x01, 0x00, 0x00, 0x00, 0x80, 0x57, 0x21, 0x90, 0x01, 0x00,
- 0x00, 0x99, 0x2e, 0x0a, 0x97, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40,
- 0xf1, 0xb1, 0x01, 0x00, 0x3c, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x03, 0x00, 0x40, 0x97, 0x98, 0x01, 0x00, 0x00, 0xa9, 0x00, 0x40,
- 0x45, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0xf1, 0xb1, 0x01, 0x00,
- 0x40, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40,
- 0x97, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x55, 0x61, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x4b, 0x62, 0xb1, 0x01, 0x00, 0x44, 0x96, 0xa8, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0x44, 0x96, 0xa2, 0x41, 0x97, 0x50, 0x00, 0x00,
- 0x00, 0x00, 0x80, 0x40, 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
- 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
- 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88,
- 0x9a, 0xb0, 0x00, 0x00, 0xae, 0x9f, 0x00, 0x88, 0x9a, 0xb0, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x88, 0x9a, 0xb0, 0x01, 0x00, 0xae, 0x9f, 0x41, 0x40,
- 0x81, 0x32, 0x00, 0x00, 0xb2, 0x9f, 0x22, 0x40, 0x7b, 0x6f, 0x00, 0x00,
- 0x00, 0x00, 0x19, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xae, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x19, 0x41, 0x7b, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xa4, 0xc4, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x00, 0xa1,
- 0xc6, 0xb3, 0x01, 0x00, 0x00, 0x00, 0x2f, 0xa2, 0xc8, 0xb3, 0x01, 0x00,
- 0x08, 0x14, 0x00, 0x40, 0x49, 0x99, 0x01, 0x00, 0xa8, 0x9f, 0x00, 0x4d,
- 0x9a, 0xcc, 0x01, 0x00, 0xbb, 0x9f, 0x26, 0x40, 0x81, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x4c, 0x49, 0xc1, 0x01, 0x00, 0xb9, 0x9f, 0xa2, 0x41,
- 0x9b, 0x50, 0x00, 0x00, 0xbf, 0x9f, 0x80, 0x80, 0x80, 0x32, 0x00, 0x00,
- 0x00, 0x00, 0x52, 0x49, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4a,
- 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x42, 0xcd, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x51, 0x4a, 0xfd, 0x93, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49,
- 0xfd, 0x93, 0x01, 0x00, 0xc2, 0x9f, 0x00, 0x43, 0xcb, 0x93, 0x00, 0x00,
- 0x00, 0x00, 0x50, 0x40, 0x81, 0xb2, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
- 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00, 0x00, 0x00, 0x40, 0xf0,
- 0x80, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x41, 0x4d, 0x80, 0xb2, 0x01, 0x00,
- 0xca, 0x9f, 0x00, 0x40, 0x19, 0x99, 0x01, 0x00, 0x00, 0x00, 0x4c, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x00, 0x00, 0x00, 0x44, 0x49, 0xd1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xf0, 0x9a, 0xb0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x4d,
- 0x10, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe2, 0x49, 0xb1, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0xe3, 0x43, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0xe4,
- 0x45, 0xb1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x40, 0x7b, 0xb3, 0x01, 0x00,
- 0x00, 0x00, 0x48, 0x4f, 0x40, 0xb1, 0x01, 0x00, 0xd2, 0x9f, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0xcb,
- 0x81, 0xc8, 0x01, 0x00, 0xf4, 0x82, 0x00, 0x40, 0xf2, 0x93, 0x00, 0x00,
- 0x40, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x40, 0x05, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x18, 0x06, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xf4, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xaf, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x38, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x36, 0x81, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xb8, 0x80, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x14, 0x87, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xaf, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xf5, 0x82, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x94, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0xd7, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x5d, 0x92, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xc6, 0x95, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x33, 0x93, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0xd6, 0x92, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0xd0, 0x92, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x9a, 0x82, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40,
- 0x81, 0xb2, 0x01, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00,
- 0x04, 0x00, 0x00, 0x40, 0x81, 0xb2, 0x00, 0x00, 0x04, 0x00, 0x00, 0x40,
- 0x81, 0xb2, 0x00, 0x00,
- },
-};
diff --git a/drivers/staging/slicoss/oasisrcvucode.h b/drivers/staging/slicoss/oasisrcvucode.h
deleted file mode 100644
index 5b3531f04cb..00000000000
--- a/drivers/staging/slicoss/oasisrcvucode.h
+++ /dev/null
@@ -1,205 +0,0 @@
-#define OASIS_RCVUCODE_VERS_STRING "1.2"
-#define OASIS_RCVUCODE_VERS_DATE "2006/03/27 15:10:28"
-
-static u32 OasisRcvUCodeLen = 512;
-
-static u8 OasisRcvUCode[2560] =
-{
-0x47, 0x75, 0x01, 0x00, 0x04, 0xa0, 0x13, 0x01, 0x00, 0x1c, 0xb7, 0x5b, 0x09,
-0x30, 0x00, 0xb6, 0x5f, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x20, 0x18, 0x3b,
-0x78, 0x3a, 0x00, 0x1c, 0xa2, 0x77, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x70,
-0x18, 0xad, 0x7b, 0xf1, 0xff, 0x1c, 0xb3, 0x7b, 0xa9, 0xaa, 0x1e, 0xb4, 0x7b,
-0x01, 0x0c, 0x1c, 0xb5, 0x7b, 0x0d, 0x06, 0x1c, 0x00, 0x00, 0x30, 0x64, 0x08,
-0x0c, 0x31, 0x5a, 0x70, 0x04, 0x0c, 0x31, 0x5a, 0x80, 0x04, 0x0c, 0x31, 0x4e,
-0x90, 0x04, 0x0c, 0x31, 0x4a, 0xa0, 0x00, 0x09, 0x25, 0x55, 0xc0, 0x04, 0x0c,
-0x31, 0x52, 0xb0, 0x00, 0xe9, 0x24, 0x55, 0xc0, 0x04, 0xcc, 0xb3, 0x00, 0x1c,
-0x1c, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0x06, 0x56, 0x32, 0xd4, 0x08, 0x07, 0x9d,
-0x00, 0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x10, 0xa0, 0x0f, 0x31, 0x54, 0x09,
-0x06, 0x56, 0x5e, 0xc0, 0x04, 0xa0, 0x30, 0x54, 0x03, 0x00, 0xac, 0x30, 0x55,
-0x03, 0x00, 0xcd, 0x03, 0x3a, 0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0x60,
-0x8e, 0x31, 0x54, 0x09, 0x29, 0x25, 0x55, 0x03, 0x00, 0x80, 0x8e, 0x31, 0x54,
-0x09, 0x8c, 0x30, 0x91, 0x00, 0x04, 0x47, 0x1c, 0x01, 0x00, 0x1c, 0xa0, 0x0f,
-0x31, 0x54, 0x09, 0x00, 0x00, 0x64, 0x00, 0x04, 0x47, 0x1c, 0x65, 0xc0, 0x04,
-0x47, 0x1c, 0x55, 0x03, 0x00, 0x6c, 0x30, 0x01, 0x00, 0x1c, 0x4d, 0x34, 0x02,
-0x00, 0x1c, 0x7b, 0xb7, 0x02, 0x00, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xc8,
-0x83, 0x37, 0x00, 0x1c, 0x80, 0x01, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x64, 0x00,
-0x04, 0xa0, 0x0f, 0x30, 0x54, 0x09, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x7b, 0xfb,
-0xf2, 0x00, 0x1c, 0xcc, 0x33, 0x0d, 0x00, 0x1c, 0xb4, 0x7b, 0xfd, 0x03, 0x1c,
-0x80, 0x0e, 0x30, 0x54, 0x09, 0xe0, 0xfb, 0x05, 0x00, 0x1c, 0x00, 0x00, 0x8c,
-0x03, 0x00, 0xb3, 0x0f, 0x31, 0x54, 0x09, 0x00, 0x00, 0xec, 0x70, 0x04, 0x00,
-0x00, 0xec, 0x80, 0x04, 0x00, 0x00, 0x8c, 0x93, 0x00, 0x61, 0x76, 0x8d, 0xc3,
-0x04, 0xc0, 0x8d, 0x31, 0x54, 0x09, 0xe0, 0x7b, 0x00, 0xc0, 0x1f, 0xa0, 0xfd,
-0xc5, 0x01, 0x00, 0xcc, 0x33, 0x05, 0x00, 0x1c, 0xd4, 0x03, 0x00, 0x3c, 0x1c,
-0xd4, 0xd3, 0x1b, 0x00, 0x1c, 0xc0, 0xd3, 0x52, 0x00, 0x1c, 0x00, 0x00, 0x5c,
-0x13, 0x04, 0x8e, 0x8e, 0x32, 0x54, 0x09, 0x5b, 0x80, 0x5e, 0x13, 0x04, 0x00,
-0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x94, 0x01, 0x00, 0xa0, 0x0f, 0x31, 0x54,
-0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xc0, 0x03, 0xfc, 0x7f, 0x1c, 0xa0, 0x01,
-0xa0, 0x01, 0x00, 0x00, 0x00, 0xa4, 0x01, 0x00, 0xa0, 0x0f, 0x31, 0x54, 0x09,
-0xc0, 0x03, 0xfc, 0x03, 0x1c, 0xf5, 0x77, 0x01, 0x00, 0x1c, 0x26, 0x7a, 0xe6,
-0x05, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xb3, 0x0f, 0x31, 0x54, 0x09, 0xb5,
-0x02, 0x02, 0x00, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0x7a, 0x7e, 0x02, 0x00,
-0x1c, 0xb5, 0x02, 0x02, 0x00, 0x1c, 0x53, 0x0f, 0x32, 0x54, 0x09, 0xaf, 0x03,
-0x01, 0x00, 0x1c, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0xb5, 0x02, 0x02, 0x00, 0x1c,
-0x00, 0x00, 0x02, 0x00, 0x1c, 0xa0, 0x3d, 0xaa, 0x11, 0x04, 0x00, 0x00, 0xac,
-0x11, 0x04, 0xd4, 0xd3, 0x52, 0x00, 0x1c, 0xb5, 0x3e, 0xb2, 0x01, 0x00, 0x20,
-0xfb, 0xfd, 0xff, 0x1f, 0x80, 0x2c, 0x6c, 0x03, 0x00, 0xb9, 0x3a, 0x9e, 0x01,
-0x00, 0x75, 0x3b, 0x02, 0x00, 0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xdb, 0x83,
-0x16, 0x00, 0x1c, 0xc7, 0x1d, 0x21, 0xc1, 0x04, 0xb9, 0x3b, 0x8d, 0xc1, 0x04,
-0x8b, 0x2c, 0x01, 0x00, 0x1c, 0x6b, 0x2c, 0x35, 0xc1, 0x04, 0x00, 0x00, 0x78,
-0x11, 0x00, 0xcb, 0x2c, 0x79, 0xc1, 0x04, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0,
-0x0f, 0x31, 0x54, 0x09, 0x54, 0xd0, 0x02, 0x00, 0x1c, 0x49, 0x25, 0xb1, 0x01,
-0x00, 0xab, 0x2c, 0x81, 0xc1, 0x04, 0xa7, 0x1d, 0x55, 0x03, 0x00, 0xcc, 0x33,
-0x09, 0x00, 0x1c, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01, 0x00, 0x1c,
-0xa0, 0x0f, 0x31, 0x54, 0x09, 0xae, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31,
-0x54, 0x09, 0xd4, 0x07, 0xfc, 0x03, 0x1c, 0x99, 0x3a, 0x02, 0x00, 0x1c, 0xbb,
-0x38, 0x02, 0x00, 0x1c, 0x00, 0x38, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xfc, 0x01,
-0x04, 0xdb, 0x3b, 0x7e, 0x00, 0x1c, 0xc7, 0x1d, 0x01, 0x00, 0x1c, 0x26, 0x7a,
-0xfa, 0x05, 0x1c, 0x27, 0x1d, 0x01, 0x00, 0x1c, 0xb3, 0x0f, 0x31, 0x54, 0x09,
-0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32,
-0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53,
-0x0f, 0x32, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0x7a, 0x06, 0x02, 0x00,
-0x1c, 0x53, 0x0f, 0x32, 0x54, 0x09, 0xaf, 0x03, 0x01, 0x00, 0x1c, 0x7a, 0x0e,
-0x32, 0x54, 0x09, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09,
-0x53, 0x0f, 0x32, 0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x53, 0x0f, 0x32,
-0x54, 0x09, 0x7a, 0x0e, 0x32, 0x54, 0x09, 0x00, 0x3d, 0x02, 0x00, 0x1c, 0x00,
-0x00, 0x58, 0x12, 0x00, 0xcb, 0x2c, 0x01, 0x00, 0x1c, 0x75, 0x3b, 0x02, 0x00,
-0x1c, 0xa7, 0x1c, 0x01, 0x00, 0x10, 0xcb, 0x2f, 0x05, 0x00, 0x1c, 0x60, 0x2c,
-0x00, 0x00, 0x1c, 0xc7, 0x1c, 0xc9, 0x02, 0x00, 0xa0, 0x0f, 0x31, 0x54, 0x09,
-0x53, 0x07, 0x02, 0x00, 0x1c, 0x46, 0x7a, 0xca, 0x05, 0x1c, 0x7a, 0x0e, 0x32,
-0x54, 0x09, 0x40, 0xfa, 0x19, 0x00, 0x1c, 0x00, 0x00, 0x88, 0x02, 0x04, 0x46,
-0x7a, 0xca, 0x05, 0x1c, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54,
-0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31, 0x54, 0x09, 0xb3, 0x7b,
-0x01, 0xc0, 0x1f, 0x74, 0x0e, 0x30, 0x54, 0x09, 0xc0, 0x03, 0x9c, 0x00, 0x1c,
-0x80, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x04, 0x00, 0x00, 0xac,
-0x12, 0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xd4, 0xd3, 0x2b, 0x00, 0x1c, 0xd4,
-0xd3, 0x52, 0x00, 0x1c, 0x80, 0x76, 0x7d, 0x13, 0x04, 0x00, 0x00, 0xe0, 0x02,
-0x00, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0xc7, 0x9c, 0x00, 0x00, 0x1c, 0x80, 0x2c,
-0x00, 0x00, 0x1c, 0x00, 0x00, 0x6c, 0x02, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04,
-0xab, 0x2d, 0xd9, 0x12, 0x05, 0x07, 0x1d, 0xb5, 0xc2, 0x04, 0x8b, 0x2d, 0x01,
-0x00, 0x1c, 0x69, 0x25, 0x01, 0x00, 0x1c, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0xcb,
-0x2f, 0x09, 0x00, 0x1c, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x48, 0x03,
-0x00, 0x53, 0x0f, 0x32, 0x54, 0x09, 0x46, 0x7a, 0xca, 0x05, 0x1c, 0x7a, 0x0e,
-0x32, 0x54, 0x09, 0x40, 0xfa, 0x19, 0x00, 0x1c, 0x00, 0x00, 0x10, 0x03, 0x04,
-0x46, 0x7a, 0xca, 0x05, 0x1c, 0xb5, 0x0f, 0x31, 0x54, 0x09, 0xa0, 0x0f, 0x31,
-0x54, 0x09, 0x73, 0xec, 0x2a, 0x03, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0x00,
-0x00, 0x28, 0x03, 0x00, 0xc7, 0x1c, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x28, 0x13,
-0x05, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xc0, 0xd7, 0x22, 0x00, 0x1c, 0x75, 0x56,
-0x7e, 0x13, 0x04, 0x60, 0x2c, 0x00, 0x00, 0x1c, 0xe7, 0x1c, 0x45, 0x03, 0x04,
-0xe7, 0x9c, 0x00, 0x00, 0x1c, 0xa6, 0x7b, 0x95, 0x03, 0x10, 0x80, 0x2c, 0x00,
-0x00, 0x1c, 0x00, 0x00, 0xf8, 0x02, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0xb9,
-0x7b, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07,
-0x1c, 0xcb, 0x2f, 0x01, 0x04, 0x1c, 0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00,
-0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0xfc, 0x07, 0x1c, 0xcb, 0x2f, 0x0d, 0x04, 0x1c,
-0xc7, 0x9f, 0x80, 0x03, 0x1c, 0x00, 0x00, 0x8c, 0xc3, 0x04, 0xcb, 0xaf, 0x00,
-0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x00, 0x1d, 0xa6, 0x7b, 0x95, 0x03, 0x1c, 0xc7,
-0x9c, 0x8c, 0xc3, 0x04, 0x00, 0x00, 0x8c, 0x13, 0x05, 0x07, 0x1d, 0x01, 0x00,
-0x1c, 0xc0, 0x1d, 0xdc, 0xd3, 0x08, 0x27, 0x9d, 0xe4, 0x03, 0x00, 0xa0, 0xee,
-0x46, 0xd4, 0x00, 0xfb, 0x75, 0x09, 0x14, 0x04, 0x20, 0x7b, 0x06, 0x00, 0x1c,
-0xc0, 0x1c, 0x1c, 0x04, 0x00, 0x00, 0x00, 0xb0, 0xd3, 0x08, 0x00, 0x00, 0x00,
-0xf4, 0x00, 0xc0, 0xef, 0xf2, 0x00, 0x1c, 0x20, 0x25, 0x5c, 0x14, 0x04, 0x60,
-0xb7, 0xd2, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x15, 0x00, 0xcc, 0xb3, 0xfc, 0x03,
-0x1c, 0xcc, 0x33, 0x05, 0x02, 0x1c, 0x00, 0x00, 0x0c, 0xc5, 0x04, 0x60, 0xb7,
-0x0e, 0x05, 0x04, 0x00, 0x00, 0x0c, 0x15, 0x04, 0x00, 0x00, 0x5c, 0xc4, 0x04,
-0xc0, 0x1d, 0x98, 0xf3, 0x04, 0x00, 0x00, 0x68, 0xc4, 0x04, 0x07, 0x9d, 0x00,
-0x00, 0x1c, 0x1b, 0x74, 0xfd, 0xf3, 0x04, 0xa6, 0x7b, 0xf1, 0x03, 0x1c, 0xa0,
-0x0f, 0x69, 0x54, 0x09, 0xe0, 0x7b, 0x00, 0xfc, 0x1f, 0x39, 0x7f, 0x02, 0x00,
-0x1c, 0x07, 0x1d, 0x9d, 0xc3, 0x04, 0xa6, 0x7b, 0xad, 0x03, 0x1c, 0x00, 0x00,
-0x68, 0xc4, 0x04, 0xe0, 0x1c, 0x00, 0x00, 0x1c, 0x00, 0x00, 0xa4, 0x03, 0x04,
-0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb, 0x2f, 0x01, 0x10, 0x1d, 0x00, 0x00, 0xac,
-0xc3, 0x04, 0x00, 0x00, 0xac, 0x03, 0x04, 0xcb, 0xaf, 0x00, 0xf8, 0x1d, 0xcb,
-0x2f, 0x01, 0x18, 0x1d, 0xc7, 0x9f, 0x00, 0x0b, 0x1c, 0x00, 0x00, 0xac, 0xc3,
-0x04, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x07, 0x1d, 0x01, 0x00, 0x1c, 0xcc, 0xb3,
-0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02, 0x1c, 0x00, 0x00, 0xac, 0xc3, 0x04,
-0xa0, 0x1c, 0x00, 0x00, 0x1c, 0xa0, 0xee, 0xa2, 0x03, 0x04, 0xcb, 0xaf, 0xfc,
-0x07, 0x1c, 0xcb, 0x2f, 0x09, 0x04, 0x1c, 0xfb, 0x75, 0x01, 0x00, 0x1c, 0x00,
-0x00, 0xac, 0xc3, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x01, 0x02,
-0x1c, 0x00, 0x00, 0x0c, 0xc5, 0x04, 0x00, 0x00, 0x78, 0x34, 0x05, 0xcc, 0xb3,
-0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x15, 0x02, 0x1c, 0x47, 0x9d, 0x54, 0xc4, 0x04,
-0x00, 0x00, 0x78, 0x44, 0x00, 0x80, 0x1d, 0x7c, 0x54, 0x04, 0x87, 0x1d, 0x8d,
-0x04, 0x00, 0xce, 0x76, 0x01, 0x00, 0x1c, 0xef, 0x76, 0x9d, 0xc4, 0x04, 0xa4,
-0x77, 0x8d, 0x24, 0x09, 0xe4, 0x76, 0x01, 0x00, 0x1c, 0xc4, 0x76, 0x01, 0x00,
-0x1c, 0x00, 0x00, 0x98, 0x54, 0x04, 0xd7, 0x76, 0x01, 0x50, 0x18, 0xf6, 0x76,
-0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10,
-0xcc, 0x30, 0x45, 0xc5, 0x04, 0xeb, 0x2d, 0x01, 0x00, 0x1c, 0xea, 0x29, 0x01,
-0x00, 0x1c, 0xc0, 0x59, 0x01, 0x00, 0x1c, 0xf5, 0x77, 0x29, 0xc5, 0x04, 0xe0,
-0x30, 0xdc, 0x04, 0x00, 0x00, 0x4c, 0xb0, 0x04, 0x00, 0x20, 0x4c, 0xf4, 0x04,
-0x00, 0x00, 0x00, 0xe8, 0x04, 0x00, 0xcc, 0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33,
-0x09, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc, 0x03, 0x1c,
-0xcc, 0x33, 0x19, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc, 0xb3, 0xfc,
-0x03, 0x1c, 0xcc, 0x33, 0x0d, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4, 0x04, 0xcc,
-0xb3, 0xfc, 0x03, 0x1c, 0xcc, 0x33, 0x11, 0x02, 0x1c, 0xeb, 0x2d, 0xb5, 0xc4,
-0x04, 0x00, 0x7b, 0x00, 0x80, 0x1c, 0xae, 0x77, 0x45, 0x05, 0x00, 0x00, 0x00,
-0x04, 0xc0, 0x04, 0xd3, 0x8b, 0x00, 0xfc, 0x1f, 0x60, 0x7a, 0x3c, 0x00, 0x1c,
-0x60, 0x4c, 0xc0, 0x04, 0x00, 0xc0, 0x2f, 0x20, 0x05, 0x1f, 0xe0, 0x30, 0xb0,
-0x04, 0x00, 0x80, 0x25, 0xb0, 0x04, 0x00, 0xb5, 0x5b, 0xb1, 0x04, 0x04, 0x69,
-0x26, 0x01, 0x00, 0x1c, 0x6a, 0x2b, 0x01, 0x00, 0x1c, 0x80, 0x1d, 0x00, 0x00,
-0x1c, 0xa9, 0x25, 0x45, 0x05, 0x00, 0xee, 0x30, 0x00, 0x00, 0x1c, 0xaf, 0x77,
-0x01, 0x05, 0x00, 0x00, 0x00, 0xac, 0x24, 0x04, 0xb4, 0x5f, 0x01, 0x40, 0x18,
-0x07, 0x9d, 0x48, 0x55, 0x04, 0xb7, 0x76, 0x01, 0x00, 0x1c, 0x96, 0x76, 0x01,
-0x00, 0x1c, 0x47, 0x1d, 0x01, 0x00, 0x1c, 0xa4, 0x33, 0x01, 0x60, 0x18, 0xa4,
-0x2f, 0x01, 0x60, 0x18, 0x64, 0x77, 0x01, 0x60, 0x18, 0x24, 0x77, 0x01, 0x60,
-0x18, 0x44, 0x77, 0x01, 0x00, 0x1c, 0x64, 0x88, 0x03, 0x00, 0x1c, 0xa4, 0x3f,
-0x01, 0x00, 0x1c, 0xa4, 0x3b, 0x01, 0x00, 0x1c, 0x53, 0x7b, 0x00, 0xc0, 0x1c,
-0xd3, 0xcf, 0x1b, 0x00, 0x1c, 0x53, 0x4f, 0x02, 0x00, 0x1c, 0xda, 0xcf, 0x00,
-0xc0, 0x1f, 0xd5, 0x57, 0x0f, 0x00, 0x1c, 0xd3, 0xd3, 0x37, 0x00, 0x1c, 0xd4,
-0x53, 0x0f, 0x00, 0x1c, 0xe0, 0x29, 0x00, 0x00, 0x1c, 0xf5, 0xd5, 0xb0, 0x05,
-0x00, 0x00, 0x00, 0x9c, 0x55, 0x04, 0x77, 0x56, 0x01, 0x00, 0x1c, 0x56, 0x53,
-0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00, 0x00, 0x04, 0xc0, 0x04,
-0xf5, 0x55, 0x01, 0x00, 0x1c, 0x00, 0x00, 0xb4, 0x55, 0x04, 0x77, 0x56, 0x01,
-0x00, 0x1c, 0x56, 0x53, 0x01, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x18, 0x00,
-0x00, 0x04, 0xc0, 0x04, 0xcb, 0x2f, 0x01, 0x18, 0x10, 0xcb, 0x2f, 0x01, 0x10,
-0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f, 0x01, 0x08, 0x10, 0xcb, 0x2f,
-0x01, 0x20, 0x10, 0xcb, 0x2f, 0x01, 0x28, 0x10, 0xcb, 0x2f, 0x01, 0x00, 0x10,
-0x89, 0x25, 0x61, 0xc2, 0x04, 0x00, 0x00, 0xec, 0xc2, 0x04, 0x00, 0x00, 0x54,
-0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00,
-0x00, 0x60, 0xc2, 0x04, 0x00, 0x00, 0xec, 0xc2, 0x04, 0x00, 0x00, 0x54, 0xc3,
-0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x40, 0x1c,
-0x6c, 0xc0, 0x04, 0x40, 0x1c, 0x9c, 0xc0, 0x04, 0xa7, 0x77, 0x55, 0xc3, 0x04,
-0x00, 0x00, 0xc4, 0xc0, 0x04, 0x27, 0x1d, 0xf1, 0xc0, 0x04, 0x00, 0x00, 0x54,
-0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00, 0x00, 0x54, 0xc3, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00,
-0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6,
-0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00,
-0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c,
-0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04, 0x00, 0x00, 0x2c, 0xc6, 0x04,
-};
diff --git a/drivers/staging/slicoss/slic.h b/drivers/staging/slicoss/slic.h
index a8ea59d7ea1..ccf7625b8bb 100644
--- a/drivers/staging/slicoss/slic.h
+++ b/drivers/staging/slicoss/slic.h
@@ -46,30 +46,10 @@
#define OASIS_UCODE_VERS_DATE "2006/03/27 15:10:37"
#define OASIS_UCODE_HOSTIF_ID 3
-static s32 ONumSections = 0x2;
-static u32 OSectionSize[] = {
- 0x00004000, 0x00010000,
-};
-
-static u32 OSectionStart[] = {
- 0x00000000, 0x00008000,
-};
-
#define MOJAVE_UCODE_VERS_STRING "1.2"
#define MOJAVE_UCODE_VERS_DATE "2006/03/27 15:12:22"
#define MOJAVE_UCODE_HOSTIF_ID 3
-static s32 MNumSections = 0x2;
-static u32 MSectionSize[] =
-{
- 0x00008000, 0x00010000,
-};
-
-static u32 MSectionStart[] =
-{
- 0x00000000, 0x00008000,
-};
-
#define GB_RCVUCODE_VERS_STRING "1.2"
#define GB_RCVUCODE_VERS_DATE "2006/03/27 15:12:15"
static u32 OasisRcvUCodeLen = 512;
@@ -201,17 +181,6 @@ struct slic_cmdqueue {
#define SLIC_MAX_CARDS 32
#define SLIC_MAX_PORTS 4 /* Max # of ports per card */
-#if SLIC_DUMP_ENABLED
-/*
-Dump buffer size
-
-This cannot be bigger than the max DMA size the card supports,
-given the current code structure in the host and ucode.
-Mojave supports 16K, Oasis supports 16K-1, so
-just set this at 15K, shouldnt make that much of a diff.
-*/
-#define DUMP_BUF_SIZE 0x3C00
-#endif
struct mcast_address {
@@ -367,30 +336,6 @@ struct sliccard {
u32 max_isr_xmits;
u32 rcv_interrupt_yields;
u32 tx_packets;
-#if SLIC_DUMP_ENABLED
- u32 dumpstatus; /* Result of dump UPR */
- void *cmdbuffer;
-
- ulong cmdbuffer_phys;
- u32 cmdbuffer_physl;
- u32 cmdbuffer_physh;
-
- u32 dump_count;
- struct task_struct *dump_task_id;
- u32 dump_wait_count;
- uint dumpthread_running; /* has a dump thread been init'd */
- uint dump_requested; /* 0 no, 1 = reqstd 2=curr 3=done */
- u32 dumptime_start;
- u32 dumptime_complete;
- u32 dumptime_delta;
- void *dumpbuffer;
- ulong dumpbuffer_phys;
- u32 dumpbuffer_physl;
- u32 dumpbuffer_physh;
- wait_queue_head_t dump_wq;
- struct file *dumphandle;
- mm_segment_t dumpfile_fs;
-#endif
u32 debug_ix;
ushort reg_type[32];
ushort reg_offset[32];
@@ -516,8 +461,6 @@ struct adapter {
uint upr_busy;
struct timer_list pingtimer;
u32 pingtimerset;
- struct timer_list statstimer;
- u32 statstimerset;
struct timer_list loadtimer;
u32 loadtimerset;
struct dentry *debugfs_entry;
@@ -570,25 +513,6 @@ struct adapter {
struct net_device_stats stats;
};
-#if SLIC_DUMP_ENABLED
-#define SLIC_DUMP_REQUESTED 1
-#define SLIC_DUMP_IN_PROGRESS 2
-#define SLIC_DUMP_DONE 3
-
-/****************************************************************************
- *
- * Microcode crash information structure. This
- * structure is written out to the card's SRAM when the microcode panic's.
- *
- ****************************************************************************/
-struct slic_crash_info {
- ushort cpu_id;
- ushort crash_pc;
-};
-
-#define CRASH_INFO_OFFSET 0x155C
-
-#endif
#define UPDATE_STATS(largestat, newstat, oldstat) \
{ \
@@ -605,11 +529,11 @@ struct slic_crash_info {
#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
{ \
- _Result = TRUE; \
+ _Result = true; \
if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
- _Result = FALSE; \
+ _Result = false; \
if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
- _Result = FALSE; \
+ _Result = false; \
}
#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
@@ -622,8 +546,8 @@ struct slic_crash_info {
#define SLIC_GET_ADDR_HIGH(_addr) (u32)0
#endif
-#define FLUSH TRUE
-#define DONT_FLUSH FALSE
+#define FLUSH true
+#define DONT_FLUSH false
#define SIOCSLICDUMPCARD (SIOCDEVPRIVATE+9)
#define SIOCSLICSETINTAGG (SIOCDEVPRIVATE+10)
diff --git a/drivers/staging/slicoss/slic_os.h b/drivers/staging/slicoss/slic_os.h
deleted file mode 100644
index 46c678440d2..00000000000
--- a/drivers/staging/slicoss/slic_os.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c)2000-2002 Alacritech, Inc. All rights reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slic_os.h
- *
- * These are the Linux-specific definitions required for the SLICOSS
- * driver, which should allow for greater portability to other OSes.
- */
-#ifndef _SLIC_OS_SPECIFIC_H_
-#define _SLIC_OS_SPECIFIC_H_
-
-#define FALSE (0)
-#define TRUE (1)
-
-#define SLIC_SECS_TO_JIFFS(x) ((x) * HZ)
-#define SLIC_MS_TO_JIFFIES(x) (SLIC_SECS_TO_JIFFS((x)) / 1000)
-
-#ifdef DEBUG_REGISTER_TRACE
-#define WRITE_REG(reg, value, flush) \
- { \
- adapter->card->reg_type[adapter->card->debug_ix] = 0; \
- adapter->card->reg_offset[adapter->card->debug_ix] = \
- ((unsigned char *)(&reg)) - \
- ((unsigned char *)adapter->slic_regs); \
- adapter->card->reg_value[adapter->card->debug_ix++] = value; \
- if (adapter->card->debug_ix == 32) \
- adapter->card->debug_ix = 0; \
- slic_reg32_write((&reg), (value), (flush)); \
- }
-#define WRITE_REG64(a, reg, value, regh, valh, flush) \
- { \
- adapter->card->reg_type[adapter->card->debug_ix] = 1; \
- adapter->card->reg_offset[adapter->card->debug_ix] = \
- ((unsigned char *)(&reg)) - \
- ((unsigned char *)adapter->slic_regs); \
- adapter->card->reg_value[adapter->card->debug_ix] = value; \
- adapter->card->reg_valueh[adapter->card->debug_ix++] = valh; \
- if (adapter->card->debug_ix == 32) \
- adapter->card->debug_ix = 0; \
- slic_reg64_write((a), (&reg), (value), (&regh), (valh), \
- (flush));\
- }
-#else
-#define WRITE_REG(reg, value, flush) \
- slic_reg32_write((&reg), (value), (flush))
-#define WRITE_REG64(a, reg, value, regh, valh, flush) \
- slic_reg64_write((a), (&reg), (value), (&regh), (valh), (flush))
-#endif
-
-#endif /* _SLIC_OS_SPECIFIC_H_ */
-
diff --git a/drivers/staging/slicoss/slicbuild.h b/drivers/staging/slicoss/slicbuild.h
deleted file mode 100644
index ae05e043d07..00000000000
--- a/drivers/staging/slicoss/slicbuild.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slicbuild.h
- *
- * The following contains the compiler directive switches used for
- * different SLIC build options. They can all be set in the Makefile
- * but the defaults are defined here.
- */
-#ifndef _SLIC_BUILD_H_
-#define _SLIC_BUILD_H_
-
-#ifndef SLIC_PRODUCTION_BUILD
-#define SLIC_PRODUCTION_BUILD 1
-#endif
-#ifndef SLIC_FAILURE_RESET
-#define SLIC_FAILURE_RESET 1
-#endif
-#define DBG 1
-#ifndef SLIC_ASSERT_ENABLED
-#define SLIC_ASSERT_ENABLED 1
-#endif
-#ifndef SLIC_MCAST_ENABLED
-#define SLIC_MCAST_ENABLED 1
-#endif
-#ifndef SLIC_GET_STATS_ENABLED
-#define SLIC_GET_STATS_ENABLED 1
-#endif
-#ifndef SLIC_GET_STATS_TIMER_ENABLED
-#define SLIC_GET_STATS_TIMER_ENABLED 0
-#endif
-#ifndef SLIC_PING_TIMER_ENABLED
-#define SLIC_PING_TIMER_ENABLED 1
-#endif
-#ifndef SLIC_IOCTL_SUPPORT_ENABLED
-#define SLIC_IOCTL_SUPPORT_ENABLED 1
-#endif
-#ifndef ATK_DEBUG
-#define ATK_DEBUG 1
-#endif
-#ifndef SLIC_POWER_MANAGEMENT_ENABLED
-#define SLIC_POWER_MANAGEMENT_ENABLED 0
-#endif
-#ifndef SLIC_INTERRUPT_PROCESS_LIMIT
-#define SLIC_INTERRUPT_PROCESS_LIMIT 1
-#endif
-#ifndef LINUX_FREES_ADAPTER_RESOURCES
-#define LINUX_FREES_ADAPTER_RESOURCES 1
-#endif
-#ifndef SLIC_OFFLOAD_IP_CHECKSUM
-#define SLIC_OFFLOAD_IP_CHECKSUM 1
-#endif
-#ifndef SLIC_POWER_MANAGEMENT_ENABLED
-#define SLIC_POWER_MANAGEMENT_ENABLED 0
-#endif
-#ifndef STATS_TIMER_INTERVAL
-#define STATS_TIMER_INTERVAL 2
-#endif
-#ifndef PING_TIMER_INTERVAL
-#define PING_TIMER_INTERVAL 1
-#endif
-
-#endif /* _SLIC_BUILD_H_ */
diff --git a/drivers/staging/slicoss/slicdbg.h b/drivers/staging/slicoss/slicdbg.h
deleted file mode 100644
index c54e44fb1f6..00000000000
--- a/drivers/staging/slicoss/slicdbg.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slicdbg.h
- *
- * All debug and assertion-based definitions and macros are included
- * in this file for the SLICOSS driver.
- */
-#ifndef _SLIC_DEBUG_H_
-#define _SLIC_DEBUG_H_
-
-#ifdef SLIC_DEFAULT_LOG_LEVEL
-#else
-#define SLICLEVEL KERN_DEBUG
-#endif
-#define SLIC_DISPLAY printk
-#define DBG_ERROR(n, args...) SLIC_DISPLAY(KERN_EMERG n, ##args)
-
-#define SLIC_DEBUG_MESSAGE 1
-#if SLIC_DEBUG_MESSAGE
-/*#define DBG_MSG(n, args...) SLIC_DISPLAY(SLICLEVEL n, ##args)*/
-#define DBG_MSG(n, args...)
-#else
-#define DBG_MSG(n, args...)
-#endif
-
-#ifdef ASSERT
-#undef ASSERT
-#endif
-
-#if SLIC_ASSERT_ENABLED
-#ifdef CONFIG_X86_64
-#define VALID_ADDRESS(p) (1)
-#else
-#define VALID_ADDRESS(p) (((u32)(p) & 0x80000000) || ((u32)(p) == 0))
-#endif
-#ifndef ASSERT
-#define ASSERT(a) \
- { \
- if (!(a)) { \
- DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n",\
- __FILE__, __func__, __LINE__); \
- slic_assert_fail(); \
- } \
- }
-#endif
-#ifndef ASSERTMSG
-#define ASSERTMSG(a,msg) \
- { \
- if (!(a)) { \
- DBG_ERROR("ASSERT() Failure: file %s, function %s"\
- "line %d: %s\n",\
- __FILE__, __func__, __LINE__, (msg)); \
- slic_assert_fail(); \
- } \
- }
-#endif
-#else
-#ifndef ASSERT
-#define ASSERT(a)
-#endif
-#ifndef ASSERTMSG
-#define ASSERTMSG(a, msg)
-#endif
-#endif /* SLIC_ASSERT_ENABLED */
-
-#endif /* _SLIC_DEBUG_H_ */
diff --git a/drivers/staging/slicoss/slicdump.h b/drivers/staging/slicoss/slicdump.h
deleted file mode 100644
index 92a9b44bcad..00000000000
--- a/drivers/staging/slicoss/slicdump.h
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- *
- * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * NO LICENSE TO ANY ALACRITECH PATENT CLAIM IS GRANTED BY ANY COPYRIGHT
- * LICENSE TO THIS OR OTHER SOFTWARE. THIS SOFTWARE MAY BE COVERED BY
- * ALACRITECH PATENTS INCLUDING BUT NOT LIMITED TO U.S. PATENT NOS. 6,226,680,
- * 6,247,060, 6,334,153, 6,389,479, 6,393,487, 6,427,171, 6,427,173
- * and 6,434,620.
- * THIS SOFTWARE IS NOT SUBJECT TO THE GNU GENERAL PUBLIC LICENSE (GPL).
- *
- * The views and conclusions contained in the software and
- * documentation are those of the authors and should not be
- * interpreted as representing official policies, either
- * expressed or implied, of Alacritech, Inc.
- */
-#ifndef _SLIC_DUMP_H_
-#define _SLIC_DUMP_H_
-
-#define DEBUG_SUCCESS 0
-
-/***********************************************************************
- *
- * Utility processor register locations
- *
- **********************************************************************/
-#define UTILITY_RESET 0x0
-#define UTILITY_ISP_ADDR 0x4 /* Interrupt status Pointer */
-#define UTILITY_ISR_ADDR 0x8 /* Interrupt status Register */
-#define UTILITY_ICR_ADDR 0xc /* Interrupt Control Register */
-#define UTILITY_CPR_ADDR 0x10 /* Command Pointer Register */
-#define UTILITY_DPR_ADDR 0x14 /* Data Pointer Register */
-#define UTILITY_DMP_TRQ 0x18 /* Dump queue onto ALU for analyser */
-#define UTILITY_UPP_ADDR 0x1c /* Bits 63-32 of cmd/data pointer */
-
-/***********************************************************************
- *
- * INIC status register bits
- *
- ***********************************************************************/
-#define SLIC_ISR_CC 0x10000000 /* Command complete - synchronous */
-#define SLIC_ISR_ERR 0x01000000 /* Command Error - synchronous */
-#define SLIC_ISR_CMD_MASK 0x11000000 /* Command status mask */
-#define SLIC_ISR_TPH 0x00080000 /* Transmit processor halted - async */
-#define SLIC_ISR_RPH 0x00040000 /* Receive processor halted - async */
-
-/***********************************************************************
- *
- * INIC Control register values
- *
- ***********************************************************************/
-#define SLIC_ICR_OFF 0 /* Interrupts disabled */
-#define SLIC_ICR_ON 1 /* Interrupts enabled */
-#define SLIC_ICR_MASK 2 /* Interrupts masked */
-
-#define WRITE_DREG(reg, value, flush) \
-{ \
- writel((value), (reg)); \
- if ((flush)) { \
- mb(); \
- } \
-}
-
-/************************************************************************
- *
- * Command Format
- *
- * Each command contains a command byte which is defined as follows:
- *
- * bits: 7-3 2 1-0
- * ----------------------------------------------
- * command Alt. Proc Processor
- *
- ************************************************************************/
-
-/*
- * Macro to create the command byte given the command, Alt. Proc, and
- * Processor values. Note that the macro assumes that the values are
- * preshifted. That is, the values for alt. proc are 0 for transmit and
- * 4 for receive.
- */
-#define COMMAND_BYTE(command, alt_proc, proc) ((command) | (alt_proc) | (proc))
-
-/*
- * Command values
- */
-#define CMD_HALT 0x0 /* Send a halt to the INIC */
-#define CMD_RUN 0x8 /* Start the halted INIC */
-#define CMD_STEP 0x10 /* Single step the inic */
-#define CMD_BREAK 0x18 /* Set a breakpoint - 8 byte command */
-#define CMD_RESET_BREAK 0x20 /* Reset a breakpoint - 8 byte cmd */
-#define CMD_DUMP 0x28 /* Dump INIC memory - 8 byte command */
-#define CMD_LOAD 0x30 /* Load INIC memory - 8 byte command */
-#define CMD_MAP 0x38 /* Map out a ROM instruction - 8 BC */
-#define CMD_CAM_OPS 0x38 /* perform ops on specific CAM */
-#define CMD_XMT 0x40 /* Transmit frame */
-#define CMD_RCV 0x48 /* Receive frame */
-
-/*
- * Alt. Proc values
- *
- * When the proc value is set to the utility processor, the Alt. Proc
- * specifies which processor handles the debugging.
- */
-#define ALT_PROC_TRANSMIT 0x0
-#define ALT_PROC_RECEIVE 0x4
-
-/*
- * Proc values
- */
-#define PROC_INVALID 0x0
-#define PROC_NONE 0x0 /* Gigabit use */
-#define PROC_TRANSMIT 0x1
-#define PROC_RECEIVE 0x2
-#define PROC_UTILITY 0x3
-
-/******************************************************************
- *
- * 8 byte command structure definitions
- *
- ******************************************************************/
-
-/*
- * Break and Reset Break command structure
- */
-struct BREAK {
- unsigned char command; /* Command word defined above */
- unsigned char resvd;
- ushort count; /* Number of executions before break */
- u32 addr; /* Address of break point */
-};
-
-/*
- * Dump and Load command structure
- */
-struct dump_cmd {
- unsigned char cmd; /* Command word defined above */
- unsigned char desc; /* Descriptor values - defined below */
- ushort count; /* number of 4 byte words to be transferred */
- u32 addr; /* start address of dump or load */
-};
-
-/*
- * Receive or Transmit a frame.
- */
-struct RCV_OR_XMT_FRAME {
- unsigned char command; /* Command word defined above */
- unsigned char MacId; /* Mac ID of interface - transmit only */
- ushort count; /* Length of frame in bytes */
- u32 pad; /* not used */
-};
-
-/*
- * Values of desc field in DUMP_OR_LOAD structure
- */
-#define DESC_RFILE 0x0 /* Register file */
-#define DESC_SRAM 0x1 /* SRAM */
-#define DESC_DRAM 0x2 /* DRAM */
-#define DESC_QUEUE 0x3 /* queues */
-#define DESC_REG 0x4 /* General registers (pc, status, etc) */
-#define DESC_SENSE 0x5 /* Sense register */
-
-/* Descriptor field definitions for CMD_DUMP_CAM */
-#define DUMP_CAM_A 0
-#define DUMP_CAM_B 1 /* unused at present */
-#define DUMP_CAM_C 2
-#define DUMP_CAM_D 3
-#define SEARCH_CAM_A 4
-#define SEARCH_CAM_C 5
-
-/*
- * Map command to replace a command in ROM with a command in WCS
- */
-struct MAP {
- unsigned char command; /* Command word defined above */
- unsigned char not_used[3];
- ushort map_to; /* Instruction address in WCS */
- ushort map_out; /* Instruction address in ROM */
-};
-
-/*
- * Misc definitions
- */
-#define SLIC_MAX_QUEUE 32 /* Total # of queues on the INIC (0-31)*/
-#define SLIC_4MAX_REG 512 /* Total # of 4-port file-registers */
-#define SLIC_1MAX_REG 384 /* Total # of file-registers */
-#define SLIC_GBMAX_REG 1024 /* Total # of Gbit file-registers */
-#define SLIC_NUM_REG 32 /* non-file-registers = NUM_REG in tm-simba.h */
-#define SLIC_GB_CAMA_SZE 32
-#define SLIC_GB_CAMB_SZE 16
-#define SLIC_GB_CAMAB_SZE 32
-#define SLIC_GB_CAMC_SZE 16
-#define SLIC_GB_CAMD_SZE 16
-#define SLIC_GB_CAMCD_SZE 32
-
-/*
- * Coredump header structure
- */
-struct CORE_Q {
- u32 queueOff; /* Offset of queue */
- u32 queuesize; /* size of queue */
-};
-
-#define DRIVER_NAME_SIZE 32
-
-struct sliccore_hdr {
- unsigned char driver_version[DRIVER_NAME_SIZE]; /* Driver version string */
- u32 RcvRegOff; /* Offset of receive registers */
- u32 RcvRegsize; /* size of receive registers */
- u32 XmtRegOff; /* Offset of transmit registers */
- u32 XmtRegsize; /* size of transmit registers */
- u32 FileRegOff; /* Offset of register file */
- u32 FileRegsize; /* size of register file */
- u32 SramOff; /* Offset of Sram */
- u32 Sramsize; /* size of Sram */
- u32 DramOff; /* Offset of Dram */
- u32 Dramsize; /* size of Dram */
- CORE_Q queues[SLIC_MAX_QUEUE]; /* size and offsets of queues */
- u32 CamAMOff; /* Offset of CAM A contents */
- u32 CamASize; /* Size of Cam A */
- u32 CamBMOff; /* Offset of CAM B contents */
- u32 CamBSize; /* Size of Cam B */
- u32 CamCMOff; /* Offset of CAM C contents */
- u32 CamCSize; /* Size of Cam C */
- u32 CamDMOff; /* Offset of CAM D contents */
- u32 CamDSize; /* Size of Cam D */
-};
-
-/*
- * definitions needed for our kernel-mode gdb stub.
- */
-/***********************************************************************
- *
- * Definitions & Typedefs
- *
- **********************************************************************/
-#define BUFMAX 0x20000 /* 128k - size of input/output buffer */
-#define BUFMAXP2 5 /* 2**5 (32) 4K pages */
-
-#define IOCTL_SIMBA_BREAK _IOW('s', 0, unsigned long)
-/* #define IOCTL_SIMBA_INIT _IOW('s', 1, unsigned long) */
-#define IOCTL_SIMBA_KILL_TGT_PROC _IOW('s', 2, unsigned long)
-
-/***********************************************************************
- *
- * Global variables
- *
- ***********************************************************************/
-
-#define THREADRECEIVE 1 /* bit 0 of StoppedThreads */
-#define THREADTRANSMIT 2 /* bit 1 of StoppedThreads */
-#define THREADBOTH 3 /* bit 0 and 1.. */
-
-#endif /* _SLIC_DUMP_H */
diff --git a/drivers/staging/slicoss/slichw.h b/drivers/staging/slicoss/slichw.h
index d03e90b0675..6275d452967 100644
--- a/drivers/staging/slicoss/slichw.h
+++ b/drivers/staging/slicoss/slichw.h
@@ -41,300 +41,286 @@
#ifndef __SLICHW_H__
#define __SLICHW_H__
-#define PCI_VENDOR_ID_ALACRITECH 0x139A
-#define SLIC_1GB_DEVICE_ID 0x0005
-#define SLIC_2GB_DEVICE_ID 0x0007 /*Oasis Device ID */
-
-#define SLIC_1GB_CICADA_SUBSYS_ID 0x0008
-
-#define SLIC_NBR_MACS 4
-
-#define SLIC_RCVBUF_SIZE 2048
-#define SLIC_RCVBUF_HEADSIZE 34
-#define SLIC_RCVBUF_TAILSIZE 0
-#define SLIC_RCVBUF_DATASIZE (SLIC_RCVBUF_SIZE - (SLIC_RCVBUF_HEADSIZE +\
- SLIC_RCVBUF_TAILSIZE))
-
-#define VGBSTAT_XPERR 0x40000000
-#define VGBSTAT_XERRSHFT 25
-#define VGBSTAT_XCSERR 0x23
-#define VGBSTAT_XUFLOW 0x22
-#define VGBSTAT_XHLEN 0x20
-#define VGBSTAT_NETERR 0x01000000
-#define VGBSTAT_NERRSHFT 16
-#define VGBSTAT_NERRMSK 0x1ff
-#define VGBSTAT_NCSERR 0x103
-#define VGBSTAT_NUFLOW 0x102
-#define VGBSTAT_NHLEN 0x100
-#define VGBSTAT_LNKERR 0x00000080
-#define VGBSTAT_LERRMSK 0xff
-#define VGBSTAT_LDEARLY 0x86
-#define VGBSTAT_LBOFLO 0x85
-#define VGBSTAT_LCODERR 0x84
-#define VGBSTAT_LDBLNBL 0x83
-#define VGBSTAT_LCRCERR 0x82
-#define VGBSTAT_LOFLO 0x81
-#define VGBSTAT_LUFLO 0x80
-#define IRHDDR_FLEN_MSK 0x0000ffff
-#define IRHDDR_SVALID 0x80000000
-#define IRHDDR_ERR 0x10000000
-#define VRHSTAT_802OE 0x80000000
-#define VRHSTAT_TPOFLO 0x10000000
-#define VRHSTATB_802UE 0x80000000
-#define VRHSTATB_RCVE 0x40000000
-#define VRHSTATB_BUFF 0x20000000
-#define VRHSTATB_CARRE 0x08000000
-#define VRHSTATB_LONGE 0x02000000
-#define VRHSTATB_PREA 0x01000000
-#define VRHSTATB_CRC 0x00800000
-#define VRHSTATB_DRBL 0x00400000
-#define VRHSTATB_CODE 0x00200000
-#define VRHSTATB_TPCSUM 0x00100000
-#define VRHSTATB_TPHLEN 0x00080000
-#define VRHSTATB_IPCSUM 0x00040000
-#define VRHSTATB_IPLERR 0x00020000
-#define VRHSTATB_IPHERR 0x00010000
-#define SLIC_MAX64_BCNT 23
-#define SLIC_MAX32_BCNT 26
-#define IHCMD_XMT_REQ 0x01
-#define IHFLG_IFSHFT 2
-#define SLIC_RSPBUF_SIZE 32
-
-#define SLIC_RESET_MAGIC 0xDEAD
-#define ICR_INT_OFF 0
-#define ICR_INT_ON 1
-#define ICR_INT_MASK 2
-
-#define ISR_ERR 0x80000000
-#define ISR_RCV 0x40000000
-#define ISR_CMD 0x20000000
-#define ISR_IO 0x60000000
-#define ISR_UPC 0x10000000
-#define ISR_LEVENT 0x08000000
-#define ISR_RMISS 0x02000000
-#define ISR_UPCERR 0x01000000
-#define ISR_XDROP 0x00800000
-#define ISR_UPCBSY 0x00020000
-#define ISR_EVMSK 0xffff0000
-#define ISR_PINGMASK 0x00700000
-#define ISR_PINGDSMASK 0x00710000
-#define ISR_UPCMASK 0x11000000
-#define SLIC_WCS_START 0x80000000
-#define SLIC_WCS_COMPARE 0x40000000
-#define SLIC_RCVWCS_BEGIN 0x40000000
-#define SLIC_RCVWCS_FINISH 0x80000000
-#define SLIC_PM_MAXPATTERNS 6
-#define SLIC_PM_PATTERNSIZE 128
-#define SLIC_PMCAPS_WAKEONLAN 0x00000001
-#define MIICR_REG_PCR 0x00000000
-#define MIICR_REG_4 0x00040000
-#define MIICR_REG_9 0x00090000
-#define MIICR_REG_16 0x00100000
-#define PCR_RESET 0x8000
-#define PCR_POWERDOWN 0x0800
-#define PCR_SPEED_100 0x2000
-#define PCR_SPEED_1000 0x0040
-#define PCR_AUTONEG 0x1000
-#define PCR_AUTONEG_RST 0x0200
-#define PCR_DUPLEX_FULL 0x0100
-#define PSR_LINKUP 0x0004
-
-#define PAR_ADV100FD 0x0100
-#define PAR_ADV100HD 0x0080
-#define PAR_ADV10FD 0x0040
-#define PAR_ADV10HD 0x0020
-#define PAR_ASYMPAUSE 0x0C00
-#define PAR_802_3 0x0001
-
-#define PAR_ADV1000XFD 0x0020
-#define PAR_ADV1000XHD 0x0040
-#define PAR_ASYMPAUSE_FIBER 0x0180
-
-#define PGC_ADV1000FD 0x0200
-#define PGC_ADV1000HD 0x0100
-#define SEEQ_LINKFAIL 0x4000
-#define SEEQ_SPEED 0x0080
-#define SEEQ_DUPLEX 0x0040
-#define TDK_DUPLEX 0x0800
-#define TDK_SPEED 0x0400
-#define MRV_REG16_XOVERON 0x0068
-#define MRV_REG16_XOVEROFF 0x0008
-#define MRV_SPEED_1000 0x8000
-#define MRV_SPEED_100 0x4000
-#define MRV_SPEED_10 0x0000
-#define MRV_FULLDUPLEX 0x2000
-#define MRV_LINKUP 0x0400
-
-#define GIG_LINKUP 0x0001
-#define GIG_FULLDUPLEX 0x0002
-#define GIG_SPEED_MASK 0x000C
-#define GIG_SPEED_1000 0x0008
-#define GIG_SPEED_100 0x0004
-#define GIG_SPEED_10 0x0000
-
-#define MCR_RESET 0x80000000
-#define MCR_CRCEN 0x40000000
-#define MCR_FULLD 0x10000000
-#define MCR_PAD 0x02000000
-#define MCR_RETRYLATE 0x01000000
-#define MCR_BOL_SHIFT 21
-#define MCR_IPG1_SHIFT 14
-#define MCR_IPG2_SHIFT 7
-#define MCR_IPG3_SHIFT 0
-#define GMCR_RESET 0x80000000
-#define GMCR_GBIT 0x20000000
-#define GMCR_FULLD 0x10000000
-#define GMCR_GAPBB_SHIFT 14
-#define GMCR_GAPR1_SHIFT 7
-#define GMCR_GAPR2_SHIFT 0
-#define GMCR_GAPBB_1000 0x60
-#define GMCR_GAPR1_1000 0x2C
-#define GMCR_GAPR2_1000 0x40
-#define GMCR_GAPBB_100 0x70
-#define GMCR_GAPR1_100 0x2C
-#define GMCR_GAPR2_100 0x40
-#define XCR_RESET 0x80000000
-#define XCR_XMTEN 0x40000000
-#define XCR_PAUSEEN 0x20000000
-#define XCR_LOADRNG 0x10000000
-#define RCR_RESET 0x80000000
-#define RCR_RCVEN 0x40000000
-#define RCR_RCVALL 0x20000000
-#define RCR_RCVBAD 0x10000000
-#define RCR_CTLEN 0x08000000
-#define RCR_ADDRAEN 0x02000000
-#define GXCR_RESET 0x80000000
-#define GXCR_XMTEN 0x40000000
-#define GXCR_PAUSEEN 0x20000000
-#define GRCR_RESET 0x80000000
-#define GRCR_RCVEN 0x40000000
-#define GRCR_RCVALL 0x20000000
-#define GRCR_RCVBAD 0x10000000
-#define GRCR_CTLEN 0x08000000
-#define GRCR_ADDRAEN 0x02000000
-#define GRCR_HASHSIZE_SHIFT 17
-#define GRCR_HASHSIZE 14
-
-#define SLIC_EEPROM_ID 0xA5A5
-#define SLIC_SRAM_SIZE2GB (64 * 1024)
-#define SLIC_SRAM_SIZE1GB (32 * 1024)
-#define SLIC_HOSTID_DEFAULT 0xFFFF /* uninitialized hostid */
-#define SLIC_NBR_MACS 4
-
-#ifndef FALSE
-#define FALSE 0
-#else
-#undef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#else
-#undef TRUE
-#define TRUE 1
-#endif
+#define PCI_VENDOR_ID_ALACRITECH 0x139A
+#define SLIC_1GB_DEVICE_ID 0x0005
+#define SLIC_2GB_DEVICE_ID 0x0007 /* Oasis Device ID */
+
+#define SLIC_1GB_CICADA_SUBSYS_ID 0x0008
+
+#define SLIC_NBR_MACS 4
+
+#define SLIC_RCVBUF_SIZE 2048
+#define SLIC_RCVBUF_HEADSIZE 34
+#define SLIC_RCVBUF_TAILSIZE 0
+#define SLIC_RCVBUF_DATASIZE (SLIC_RCVBUF_SIZE - \
+ (SLIC_RCVBUF_HEADSIZE + \
+ SLIC_RCVBUF_TAILSIZE))
+
+#define VGBSTAT_XPERR 0x40000000
+#define VGBSTAT_XERRSHFT 25
+#define VGBSTAT_XCSERR 0x23
+#define VGBSTAT_XUFLOW 0x22
+#define VGBSTAT_XHLEN 0x20
+#define VGBSTAT_NETERR 0x01000000
+#define VGBSTAT_NERRSHFT 16
+#define VGBSTAT_NERRMSK 0x1ff
+#define VGBSTAT_NCSERR 0x103
+#define VGBSTAT_NUFLOW 0x102
+#define VGBSTAT_NHLEN 0x100
+#define VGBSTAT_LNKERR 0x00000080
+#define VGBSTAT_LERRMSK 0xff
+#define VGBSTAT_LDEARLY 0x86
+#define VGBSTAT_LBOFLO 0x85
+#define VGBSTAT_LCODERR 0x84
+#define VGBSTAT_LDBLNBL 0x83
+#define VGBSTAT_LCRCERR 0x82
+#define VGBSTAT_LOFLO 0x81
+#define VGBSTAT_LUFLO 0x80
+#define IRHDDR_FLEN_MSK 0x0000ffff
+#define IRHDDR_SVALID 0x80000000
+#define IRHDDR_ERR 0x10000000
+#define VRHSTAT_802OE 0x80000000
+#define VRHSTAT_TPOFLO 0x10000000
+#define VRHSTATB_802UE 0x80000000
+#define VRHSTATB_RCVE 0x40000000
+#define VRHSTATB_BUFF 0x20000000
+#define VRHSTATB_CARRE 0x08000000
+#define VRHSTATB_LONGE 0x02000000
+#define VRHSTATB_PREA 0x01000000
+#define VRHSTATB_CRC 0x00800000
+#define VRHSTATB_DRBL 0x00400000
+#define VRHSTATB_CODE 0x00200000
+#define VRHSTATB_TPCSUM 0x00100000
+#define VRHSTATB_TPHLEN 0x00080000
+#define VRHSTATB_IPCSUM 0x00040000
+#define VRHSTATB_IPLERR 0x00020000
+#define VRHSTATB_IPHERR 0x00010000
+#define SLIC_MAX64_BCNT 23
+#define SLIC_MAX32_BCNT 26
+#define IHCMD_XMT_REQ 0x01
+#define IHFLG_IFSHFT 2
+#define SLIC_RSPBUF_SIZE 32
+
+#define SLIC_RESET_MAGIC 0xDEAD
+#define ICR_INT_OFF 0
+#define ICR_INT_ON 1
+#define ICR_INT_MASK 2
+
+#define ISR_ERR 0x80000000
+#define ISR_RCV 0x40000000
+#define ISR_CMD 0x20000000
+#define ISR_IO 0x60000000
+#define ISR_UPC 0x10000000
+#define ISR_LEVENT 0x08000000
+#define ISR_RMISS 0x02000000
+#define ISR_UPCERR 0x01000000
+#define ISR_XDROP 0x00800000
+#define ISR_UPCBSY 0x00020000
+#define ISR_EVMSK 0xffff0000
+#define ISR_PINGMASK 0x00700000
+#define ISR_PINGDSMASK 0x00710000
+#define ISR_UPCMASK 0x11000000
+#define SLIC_WCS_START 0x80000000
+#define SLIC_WCS_COMPARE 0x40000000
+#define SLIC_RCVWCS_BEGIN 0x40000000
+#define SLIC_RCVWCS_FINISH 0x80000000
+#define SLIC_PM_MAXPATTERNS 6
+#define SLIC_PM_PATTERNSIZE 128
+#define SLIC_PMCAPS_WAKEONLAN 0x00000001
+#define MIICR_REG_PCR 0x00000000
+#define MIICR_REG_4 0x00040000
+#define MIICR_REG_9 0x00090000
+#define MIICR_REG_16 0x00100000
+#define PCR_RESET 0x8000
+#define PCR_POWERDOWN 0x0800
+#define PCR_SPEED_100 0x2000
+#define PCR_SPEED_1000 0x0040
+#define PCR_AUTONEG 0x1000
+#define PCR_AUTONEG_RST 0x0200
+#define PCR_DUPLEX_FULL 0x0100
+#define PSR_LINKUP 0x0004
+
+#define PAR_ADV100FD 0x0100
+#define PAR_ADV100HD 0x0080
+#define PAR_ADV10FD 0x0040
+#define PAR_ADV10HD 0x0020
+#define PAR_ASYMPAUSE 0x0C00
+#define PAR_802_3 0x0001
+
+#define PAR_ADV1000XFD 0x0020
+#define PAR_ADV1000XHD 0x0040
+#define PAR_ASYMPAUSE_FIBER 0x0180
+
+#define PGC_ADV1000FD 0x0200
+#define PGC_ADV1000HD 0x0100
+#define SEEQ_LINKFAIL 0x4000
+#define SEEQ_SPEED 0x0080
+#define SEEQ_DUPLEX 0x0040
+#define TDK_DUPLEX 0x0800
+#define TDK_SPEED 0x0400
+#define MRV_REG16_XOVERON 0x0068
+#define MRV_REG16_XOVEROFF 0x0008
+#define MRV_SPEED_1000 0x8000
+#define MRV_SPEED_100 0x4000
+#define MRV_SPEED_10 0x0000
+#define MRV_FULLDUPLEX 0x2000
+#define MRV_LINKUP 0x0400
+
+#define GIG_LINKUP 0x0001
+#define GIG_FULLDUPLEX 0x0002
+#define GIG_SPEED_MASK 0x000C
+#define GIG_SPEED_1000 0x0008
+#define GIG_SPEED_100 0x0004
+#define GIG_SPEED_10 0x0000
+
+#define MCR_RESET 0x80000000
+#define MCR_CRCEN 0x40000000
+#define MCR_FULLD 0x10000000
+#define MCR_PAD 0x02000000
+#define MCR_RETRYLATE 0x01000000
+#define MCR_BOL_SHIFT 21
+#define MCR_IPG1_SHIFT 14
+#define MCR_IPG2_SHIFT 7
+#define MCR_IPG3_SHIFT 0
+#define GMCR_RESET 0x80000000
+#define GMCR_GBIT 0x20000000
+#define GMCR_FULLD 0x10000000
+#define GMCR_GAPBB_SHIFT 14
+#define GMCR_GAPR1_SHIFT 7
+#define GMCR_GAPR2_SHIFT 0
+#define GMCR_GAPBB_1000 0x60
+#define GMCR_GAPR1_1000 0x2C
+#define GMCR_GAPR2_1000 0x40
+#define GMCR_GAPBB_100 0x70
+#define GMCR_GAPR1_100 0x2C
+#define GMCR_GAPR2_100 0x40
+#define XCR_RESET 0x80000000
+#define XCR_XMTEN 0x40000000
+#define XCR_PAUSEEN 0x20000000
+#define XCR_LOADRNG 0x10000000
+#define RCR_RESET 0x80000000
+#define RCR_RCVEN 0x40000000
+#define RCR_RCVALL 0x20000000
+#define RCR_RCVBAD 0x10000000
+#define RCR_CTLEN 0x08000000
+#define RCR_ADDRAEN 0x02000000
+#define GXCR_RESET 0x80000000
+#define GXCR_XMTEN 0x40000000
+#define GXCR_PAUSEEN 0x20000000
+#define GRCR_RESET 0x80000000
+#define GRCR_RCVEN 0x40000000
+#define GRCR_RCVALL 0x20000000
+#define GRCR_RCVBAD 0x10000000
+#define GRCR_CTLEN 0x08000000
+#define GRCR_ADDRAEN 0x02000000
+#define GRCR_HASHSIZE_SHIFT 17
+#define GRCR_HASHSIZE 14
+
+#define SLIC_EEPROM_ID 0xA5A5
+#define SLIC_SRAM_SIZE2GB (64 * 1024)
+#define SLIC_SRAM_SIZE1GB (32 * 1024)
+#define SLIC_HOSTID_DEFAULT 0xFFFF /* uninitialized hostid */
+#define SLIC_NBR_MACS 4
struct slic_rcvbuf {
- unsigned char pad1[6];
- ushort pad2;
- u32 pad3;
- u32 pad4;
- u32 buffer;
- u32 length;
- u32 status;
- u32 pad5;
- ushort pad6;
- unsigned char data[SLIC_RCVBUF_DATASIZE];
+ u8 pad1[6];
+ u16 pad2;
+ u32 pad3;
+ u32 pad4;
+ u32 buffer;
+ u32 length;
+ u32 status;
+ u32 pad5;
+ u16 pad6;
+ u8 data[SLIC_RCVBUF_DATASIZE];
};
- struct slic_hddr_wds {
- union {
- struct {
- u32 frame_status;
- u32 frame_status_b;
- u32 time_stamp;
- u32 checksum;
- } hdrs_14port;
- struct {
- u32 frame_status;
- ushort ByteCnt;
- ushort TpChksum;
- ushort CtxHash;
- ushort MacHash;
- u32 BufLnk;
- } hdrs_gbit;
- } u0;
+struct slic_hddr_wds {
+ union {
+ struct {
+ u32 frame_status;
+ u32 frame_status_b;
+ u32 time_stamp;
+ u32 checksum;
+ } hdrs_14port;
+ struct {
+ u32 frame_status;
+ u16 ByteCnt;
+ u16 TpChksum;
+ u16 CtxHash;
+ u16 MacHash;
+ u32 BufLnk;
+ } hdrs_gbit;
+ } u0;
};
-#define frame_status14 u0.hdrs_14port.frame_status
-#define frame_status_b14 u0.hdrs_14port.frame_status_b
-#define frame_statusGB u0.hdrs_gbit.frame_status
+#define frame_status14 u0.hdrs_14port.frame_status
+#define frame_status_b14 u0.hdrs_14port.frame_status_b
+#define frame_statusGB u0.hdrs_gbit.frame_status
struct slic_host64sg {
- u32 paddrl;
- u32 paddrh;
- u32 length;
+ u32 paddrl;
+ u32 paddrh;
+ u32 length;
};
struct slic_host64_cmd {
- u32 hosthandle;
- u32 RSVD;
- unsigned char command;
- unsigned char flags;
- union {
- ushort rsv1;
- ushort rsv2;
- } u0;
- union {
- struct {
- u32 totlen;
- struct slic_host64sg bufs[SLIC_MAX64_BCNT];
- } slic_buffers;
- } u;
+ u32 hosthandle;
+ u32 RSVD;
+ u8 command;
+ u8 flags;
+ union {
+ u16 rsv1;
+ u16 rsv2;
+ } u0;
+ union {
+ struct {
+ u32 totlen;
+ struct slic_host64sg bufs[SLIC_MAX64_BCNT];
+ } slic_buffers;
+ } u;
};
struct slic_rspbuf {
- u32 hosthandle;
- u32 pad0;
- u32 pad1;
- u32 status;
- u32 pad2[4];
-
+ u32 hosthandle;
+ u32 pad0;
+ u32 pad1;
+ u32 status;
+ u32 pad2[4];
};
struct slic_regs {
- u32 slic_reset; /* Reset Register */
+ u32 slic_reset; /* Reset Register */
u32 pad0;
- u32 slic_icr; /* Interrupt Control Register */
+ u32 slic_icr; /* Interrupt Control Register */
u32 pad2;
#define SLIC_ICR 0x0008
- u32 slic_isp; /* Interrupt status pointer */
+ u32 slic_isp; /* Interrupt status pointer */
u32 pad1;
#define SLIC_ISP 0x0010
- u32 slic_isr; /* Interrupt status */
+ u32 slic_isr; /* Interrupt status */
u32 pad3;
#define SLIC_ISR 0x0018
- u32 slic_hbar; /* Header buffer address reg */
- u32 pad4;
+ u32 slic_hbar; /* Header buffer address reg */
+ u32 pad4;
/* 31-8 - phy addr of set of contiguous hdr buffers
7-0 - number of buffers passed
Buffers are 256 bytes long on 256-byte boundaries. */
#define SLIC_HBAR 0x0020
#define SLIC_HBAR_CNT_MSK 0x000000FF
- u32 slic_dbar; /* Data buffer handle & address reg */
- u32 pad5;
+ u32 slic_dbar; /* Data buffer handle & address reg */
+ u32 pad5;
/* 4 sets of registers; Buffers are 2K bytes long 2 per 4K page. */
#define SLIC_DBAR 0x0028
#define SLIC_DBAR_SIZE 2048
- u32 slic_cbar; /* Xmt Cmd buf addr regs.*/
+ u32 slic_cbar; /* Xmt Cmd buf addr regs.*/
/* 1 per XMT interface
31-5 - phy addr of host command buffer
4-0 - length of cmd in multiples of 32 bytes
@@ -343,13 +329,13 @@ struct slic_regs {
#define SLIC_CBAR_LEN_MSK 0x0000001F
#define SLIC_CBAR_ALIGN 0x00000020
- u32 slic_wcs; /* write control store*/
+ u32 slic_wcs; /* write control store*/
#define SLIC_WCS 0x0034
#define SLIC_WCS_START 0x80000000 /*Start the SLIC (Jump to WCS)*/
#define SLIC_WCS_COMPARE 0x40000000 /* Compare with value in WCS*/
- u32 slic_rbar; /* Response buffer address reg.*/
- u32 pad7;
+ u32 slic_rbar; /* Response buffer address reg.*/
+ u32 pad7;
/*31-8 - phy addr of set of contiguous response buffers
7-0 - number of buffers passed
Buffers are 32 bytes long on 32-byte boundaries.*/
@@ -357,215 +343,214 @@ struct slic_regs {
#define SLIC_RBAR_CNT_MSK 0x000000FF
#define SLIC_RBAR_SIZE 32
- u32 slic_stats; /* read statistics (UPR) */
- u32 pad8;
+ u32 slic_stats; /* read statistics (UPR) */
+ u32 pad8;
#define SLIC_RSTAT 0x0040
- u32 slic_rlsr; /* read link status */
- u32 pad9;
+ u32 slic_rlsr; /* read link status */
+ u32 pad9;
#define SLIC_LSTAT 0x0048
- u32 slic_wmcfg; /* Write Mac Config */
- u32 pad10;
+ u32 slic_wmcfg; /* Write Mac Config */
+ u32 pad10;
#define SLIC_WMCFG 0x0050
- u32 slic_wphy; /* Write phy register */
- u32 pad11;
+ u32 slic_wphy; /* Write phy register */
+ u32 pad11;
#define SLIC_WPHY 0x0058
- u32 slic_rcbar; /*Rcv Cmd buf addr reg*/
- u32 pad12;
+ u32 slic_rcbar; /* Rcv Cmd buf addr reg */
+ u32 pad12;
#define SLIC_RCBAR 0x0060
- u32 slic_rconfig; /* Read SLIC Config*/
- u32 pad13;
+ u32 slic_rconfig; /* Read SLIC Config*/
+ u32 pad13;
#define SLIC_RCONFIG 0x0068
- u32 slic_intagg; /* Interrupt aggregation time*/
- u32 pad14;
+ u32 slic_intagg; /* Interrupt aggregation time */
+ u32 pad14;
#define SLIC_INTAGG 0x0070
- u32 slic_wxcfg; /* Write XMIT config reg*/
- u32 pad16;
+ u32 slic_wxcfg; /* Write XMIT config reg*/
+ u32 pad16;
#define SLIC_WXCFG 0x0078
- u32 slic_wrcfg; /* Write RCV config reg*/
- u32 pad17;
+ u32 slic_wrcfg; /* Write RCV config reg*/
+ u32 pad17;
#define SLIC_WRCFG 0x0080
- u32 slic_wraddral; /* Write rcv addr a low*/
- u32 pad18;
+ u32 slic_wraddral; /* Write rcv addr a low*/
+ u32 pad18;
#define SLIC_WRADDRAL 0x0088
- u32 slic_wraddrah; /* Write rcv addr a high*/
- u32 pad19;
+ u32 slic_wraddrah; /* Write rcv addr a high*/
+ u32 pad19;
#define SLIC_WRADDRAH 0x0090
- u32 slic_wraddrbl; /* Write rcv addr b low*/
- u32 pad20;
+ u32 slic_wraddrbl; /* Write rcv addr b low*/
+ u32 pad20;
#define SLIC_WRADDRBL 0x0098
- u32 slic_wraddrbh; /* Write rcv addr b high*/
+ u32 slic_wraddrbh; /* Write rcv addr b high*/
u32 pad21;
#define SLIC_WRADDRBH 0x00a0
- u32 slic_mcastlow; /* Low bits of mcast mask*/
+ u32 slic_mcastlow; /* Low bits of mcast mask*/
u32 pad22;
#define SLIC_MCASTLOW 0x00a8
- u32 slic_mcasthigh; /* High bits of mcast mask*/
+ u32 slic_mcasthigh; /* High bits of mcast mask*/
u32 pad23;
#define SLIC_MCASTHIGH 0x00b0
- u32 slic_ping; /* Ping the card*/
- u32 pad24;
+ u32 slic_ping; /* Ping the card*/
+ u32 pad24;
#define SLIC_PING 0x00b8
- u32 slic_dump_cmd; /* Dump command */
- u32 pad25;
+ u32 slic_dump_cmd; /* Dump command */
+ u32 pad25;
#define SLIC_DUMP_CMD 0x00c0
- u32 slic_dump_data; /* Dump data pointer */
- u32 pad26;
+ u32 slic_dump_data; /* Dump data pointer */
+ u32 pad26;
#define SLIC_DUMP_DATA 0x00c8
u32 slic_pcistatus; /* Read card's pci_status register */
- u32 pad27;
+ u32 pad27;
#define SLIC_PCISTATUS 0x00d0
- u32 slic_wrhostid; /* Write hostid field */
+ u32 slic_wrhostid; /* Write hostid field */
u32 pad28;
#define SLIC_WRHOSTID 0x00d8
#define SLIC_RDHOSTID_1GB 0x1554
#define SLIC_RDHOSTID_2GB 0x1554
u32 slic_low_power; /* Put card in a low power state */
- u32 pad29;
+ u32 pad29;
#define SLIC_LOW_POWER 0x00e0
u32 slic_quiesce; /* force slic into quiescent state
- before soft reset */
- u32 pad30;
+ before soft reset */
+ u32 pad30;
#define SLIC_QUIESCE 0x00e8
- u32 slic_reset_iface; /* reset interface queues */
- u32 pad31;
+ u32 slic_reset_iface;/* reset interface queues */
+ u32 pad31;
#define SLIC_RESET_IFACE 0x00f0
- u32 slic_addr_upper; /* Bits 63-32 for host i/f addrs */
- u32 pad32;
+ u32 slic_addr_upper;/* Bits 63-32 for host i/f addrs */
+ u32 pad32;
#define SLIC_ADDR_UPPER 0x00f8 /*Register is only written when it has changed*/
- u32 slic_hbar64; /* 64 bit Header buffer address reg */
- u32 pad33;
+ u32 slic_hbar64; /* 64 bit Header buffer address reg */
+ u32 pad33;
#define SLIC_HBAR64 0x0100
- u32 slic_dbar64; /* 64 bit Data buffer handle & address reg */
- u32 pad34;
+ u32 slic_dbar64; /* 64 bit Data buffer handle & address reg */
+ u32 pad34;
#define SLIC_DBAR64 0x0108
- u32 slic_cbar64; /* 64 bit Xmt Cmd buf addr regs. */
- u32 pad35;
+ u32 slic_cbar64; /* 64 bit Xmt Cmd buf addr regs. */
+ u32 pad35;
#define SLIC_CBAR64 0x0110
- u32 slic_rbar64; /* 64 bit Response buffer address reg.*/
- u32 pad36;
+ u32 slic_rbar64; /* 64 bit Response buffer address reg.*/
+ u32 pad36;
#define SLIC_RBAR64 0x0118
- u32 slic_rcbar64; /* 64 bit Rcv Cmd buf addr reg*/
- u32 pad37;
+ u32 slic_rcbar64; /* 64 bit Rcv Cmd buf addr reg*/
+ u32 pad37;
#define SLIC_RCBAR64 0x0120
- u32 slic_stats64; /*read statistics (64 bit UPR)*/
- u32 pad38;
+ u32 slic_stats64; /* read statistics (64 bit UPR) */
+ u32 pad38;
#define SLIC_RSTAT64 0x0128
u32 slic_rcv_wcs; /*Download Gigabit RCV sequencer ucode*/
- u32 pad39;
+ u32 pad39;
#define SLIC_RCV_WCS 0x0130
#define SLIC_RCVWCS_BEGIN 0x40000000
#define SLIC_RCVWCS_FINISH 0x80000000
- u32 slic_wrvlanid; /* Write VlanId field */
- u32 pad40;
+ u32 slic_wrvlanid; /* Write VlanId field */
+ u32 pad40;
#define SLIC_WRVLANID 0x0138
- u32 slic_read_xf_info; /* Read Transformer info */
- u32 pad41;
+ u32 slic_read_xf_info; /* Read Transformer info */
+ u32 pad41;
#define SLIC_READ_XF_INFO 0x0140
- u32 slic_write_xf_info; /* Write Transformer info */
- u32 pad42;
+ u32 slic_write_xf_info; /* Write Transformer info */
+ u32 pad42;
#define SLIC_WRITE_XF_INFO 0x0148
- u32 RSVD1; /* TOE Only */
- u32 pad43;
+ u32 RSVD1; /* TOE Only */
+ u32 pad43;
- u32 RSVD2; /* TOE Only */
- u32 pad44;
+ u32 RSVD2; /* TOE Only */
+ u32 pad44;
- u32 RSVD3; /* TOE Only */
- u32 pad45;
+ u32 RSVD3; /* TOE Only */
+ u32 pad45;
- u32 RSVD4; /* TOE Only */
- u32 pad46;
+ u32 RSVD4; /* TOE Only */
+ u32 pad46;
u32 slic_ticks_per_sec; /* Write card ticks per second */
- u32 pad47;
+ u32 pad47;
#define SLIC_TICKS_PER_SEC 0x0170
-
};
enum UPR_REQUEST {
- SLIC_UPR_STATS,
- SLIC_UPR_RLSR,
- SLIC_UPR_WCFG,
- SLIC_UPR_RCONFIG,
- SLIC_UPR_RPHY,
- SLIC_UPR_ENLB,
- SLIC_UPR_ENCT,
- SLIC_UPR_PDWN,
- SLIC_UPR_PING,
- SLIC_UPR_DUMP,
+ SLIC_UPR_STATS,
+ SLIC_UPR_RLSR,
+ SLIC_UPR_WCFG,
+ SLIC_UPR_RCONFIG,
+ SLIC_UPR_RPHY,
+ SLIC_UPR_ENLB,
+ SLIC_UPR_ENCT,
+ SLIC_UPR_PDWN,
+ SLIC_UPR_PING,
+ SLIC_UPR_DUMP,
};
struct inicpm_wakepattern {
- u32 patternlength;
- unsigned char pattern[SLIC_PM_PATTERNSIZE];
- unsigned char mask[SLIC_PM_PATTERNSIZE];
+ u32 patternlength;
+ u8 pattern[SLIC_PM_PATTERNSIZE];
+ u8 mask[SLIC_PM_PATTERNSIZE];
};
struct inicpm_state {
- u32 powercaps;
- u32 powerstate;
- u32 wake_linkstatus;
- u32 wake_magicpacket;
- u32 wake_framepattern;
- struct inicpm_wakepattern wakepattern[SLIC_PM_MAXPATTERNS];
+ u32 powercaps;
+ u32 powerstate;
+ u32 wake_linkstatus;
+ u32 wake_magicpacket;
+ u32 wake_framepattern;
+ struct inicpm_wakepattern wakepattern[SLIC_PM_MAXPATTERNS];
};
struct slicpm_packet_pattern {
- u32 priority;
- u32 reserved;
- u32 masksize;
- u32 patternoffset;
- u32 patternsize;
- u32 patternflags;
+ u32 priority;
+ u32 reserved;
+ u32 masksize;
+ u32 patternoffset;
+ u32 patternsize;
+ u32 patternflags;
};
enum slicpm_power_state {
- slicpm_state_unspecified = 0,
- slicpm_state_d0,
- slicpm_state_d1,
- slicpm_state_d2,
- slicpm_state_d3,
- slicpm_state_maximum
+ slicpm_state_unspecified = 0,
+ slicpm_state_d0,
+ slicpm_state_d1,
+ slicpm_state_d2,
+ slicpm_state_d3,
+ slicpm_state_maximum
};
struct slicpm_wakeup_capabilities {
- enum slicpm_power_state min_magic_packet_wakeup;
- enum slicpm_power_state min_pattern_wakeup;
- enum slicpm_power_state min_link_change_wakeup;
+ enum slicpm_power_state min_magic_packet_wakeup;
+ enum slicpm_power_state min_pattern_wakeup;
+ enum slicpm_power_state min_link_change_wakeup;
};
struct slic_pnp_capabilities {
@@ -612,136 +597,135 @@ struct rcv_statsgb {
};
struct slic_stats {
- union {
- struct {
- struct xmt_stats xmt100;
- struct rcv_stats rcv100;
- } stats_100;
- struct {
- struct xmt_statsgb xmtGB;
- struct rcv_statsgb rcvGB;
- } stats_GB;
- } u;
+ union {
+ struct {
+ struct xmt_stats xmt100;
+ struct rcv_stats rcv100;
+ } stats_100;
+ struct {
+ struct xmt_statsgb xmtGB;
+ struct rcv_statsgb rcvGB;
+ } stats_GB;
+ } u;
};
-#define xmit_tcp_segs100 u.stats_100.xmt100.xmit_tcp_segs
-#define xmit_tcp_bytes100 u.stats_100.xmt100.xmit_tcp_bytes
-#define xmit_bytes100 u.stats_100.xmt100.xmit_bytes
-#define xmit_collisions100 u.stats_100.xmt100.xmit_collisions
-#define xmit_unicasts100 u.stats_100.xmt100.xmit_unicasts
-#define xmit_other_error100 u.stats_100.xmt100.xmit_other_error
-#define xmit_excess_collisions100 u.stats_100.xmt100.xmit_excess_collisions
-#define rcv_tcp_segs100 u.stats_100.rcv100.rcv_tcp_segs
-#define rcv_tcp_bytes100 u.stats_100.rcv100.rcv_tcp_bytes
-#define rcv_bytes100 u.stats_100.rcv100.rcv_bytes
-#define rcv_unicasts100 u.stats_100.rcv100.rcv_unicasts
-#define rcv_other_error100 u.stats_100.rcv100.rcv_other_error
-#define rcv_drops100 u.stats_100.rcv100.rcv_drops
-#define xmit_tcp_segs_gb u.stats_GB.xmtGB.xmit_tcp_segs
-#define xmit_tcp_bytes_gb u.stats_GB.xmtGB.xmit_tcp_bytes
-#define xmit_bytes_gb u.stats_GB.xmtGB.xmit_bytes
-#define xmit_collisions_gb u.stats_GB.xmtGB.xmit_collisions
-#define xmit_unicasts_gb u.stats_GB.xmtGB.xmit_unicasts
-#define xmit_other_error_gb u.stats_GB.xmtGB.xmit_other_error
-#define xmit_excess_collisions_gb u.stats_GB.xmtGB.xmit_excess_collisions
-
-#define rcv_tcp_segs_gb u.stats_GB.rcvGB.rcv_tcp_segs
-#define rcv_tcp_bytes_gb u.stats_GB.rcvGB.rcv_tcp_bytes
-#define rcv_bytes_gb u.stats_GB.rcvGB.rcv_bytes
-#define rcv_unicasts_gb u.stats_GB.rcvGB.rcv_unicasts
-#define rcv_other_error_gb u.stats_GB.rcvGB.rcv_other_error
-#define rcv_drops_gb u.stats_GB.rcvGB.rcv_drops
+#define xmit_tcp_segs100 u.stats_100.xmt100.xmit_tcp_segs
+#define xmit_tcp_bytes100 u.stats_100.xmt100.xmit_tcp_bytes
+#define xmit_bytes100 u.stats_100.xmt100.xmit_bytes
+#define xmit_collisions100 u.stats_100.xmt100.xmit_collisions
+#define xmit_unicasts100 u.stats_100.xmt100.xmit_unicasts
+#define xmit_other_error100 u.stats_100.xmt100.xmit_other_error
+#define xmit_excess_collisions100 u.stats_100.xmt100.xmit_excess_collisions
+#define rcv_tcp_segs100 u.stats_100.rcv100.rcv_tcp_segs
+#define rcv_tcp_bytes100 u.stats_100.rcv100.rcv_tcp_bytes
+#define rcv_bytes100 u.stats_100.rcv100.rcv_bytes
+#define rcv_unicasts100 u.stats_100.rcv100.rcv_unicasts
+#define rcv_other_error100 u.stats_100.rcv100.rcv_other_error
+#define rcv_drops100 u.stats_100.rcv100.rcv_drops
+#define xmit_tcp_segs_gb u.stats_GB.xmtGB.xmit_tcp_segs
+#define xmit_tcp_bytes_gb u.stats_GB.xmtGB.xmit_tcp_bytes
+#define xmit_bytes_gb u.stats_GB.xmtGB.xmit_bytes
+#define xmit_collisions_gb u.stats_GB.xmtGB.xmit_collisions
+#define xmit_unicasts_gb u.stats_GB.xmtGB.xmit_unicasts
+#define xmit_other_error_gb u.stats_GB.xmtGB.xmit_other_error
+#define xmit_excess_collisions_gb u.stats_GB.xmtGB.xmit_excess_collisions
+
+#define rcv_tcp_segs_gb u.stats_GB.rcvGB.rcv_tcp_segs
+#define rcv_tcp_bytes_gb u.stats_GB.rcvGB.rcv_tcp_bytes
+#define rcv_bytes_gb u.stats_GB.rcvGB.rcv_bytes
+#define rcv_unicasts_gb u.stats_GB.rcvGB.rcv_unicasts
+#define rcv_other_error_gb u.stats_GB.rcvGB.rcv_other_error
+#define rcv_drops_gb u.stats_GB.rcvGB.rcv_drops
struct slic_config_mac {
- unsigned char macaddrA[6];
+ u8 macaddrA[6];
};
-#define ATK_FRU_FORMAT 0x00
-#define VENDOR1_FRU_FORMAT 0x01
-#define VENDOR2_FRU_FORMAT 0x02
-#define VENDOR3_FRU_FORMAT 0x03
-#define VENDOR4_FRU_FORMAT 0x04
-#define NO_FRU_FORMAT 0xFF
+#define ATK_FRU_FORMAT 0x00
+#define VENDOR1_FRU_FORMAT 0x01
+#define VENDOR2_FRU_FORMAT 0x02
+#define VENDOR3_FRU_FORMAT 0x03
+#define VENDOR4_FRU_FORMAT 0x04
+#define NO_FRU_FORMAT 0xFF
struct atk_fru {
- unsigned char assembly[6];
- unsigned char revision[2];
- unsigned char serial[14];
- unsigned char pad[3];
+ u8 assembly[6];
+ u8 revision[2];
+ u8 serial[14];
+ u8 pad[3];
};
struct vendor1_fru {
- unsigned char commodity;
- unsigned char assembly[4];
- unsigned char revision[2];
- unsigned char supplier[2];
- unsigned char date[2];
- unsigned char sequence[3];
- unsigned char pad[13];
+ u8 commodity;
+ u8 assembly[4];
+ u8 revision[2];
+ u8 supplier[2];
+ u8 date[2];
+ u8 sequence[3];
+ u8 pad[13];
};
struct vendor2_fru {
- unsigned char part[8];
- unsigned char supplier[5];
- unsigned char date[3];
- unsigned char sequence[4];
- unsigned char pad[7];
+ u8 part[8];
+ u8 supplier[5];
+ u8 date[3];
+ u8 sequence[4];
+ u8 pad[7];
};
struct vendor3_fru {
- unsigned char assembly[6];
- unsigned char revision[2];
- unsigned char serial[14];
- unsigned char pad[3];
+ u8 assembly[6];
+ u8 revision[2];
+ u8 serial[14];
+ u8 pad[3];
};
struct vendor4_fru {
- unsigned char number[8];
- unsigned char part[8];
- unsigned char version[8];
- unsigned char pad[3];
+ u8 number[8];
+ u8 part[8];
+ u8 version[8];
+ u8 pad[3];
};
union oemfru {
- struct vendor1_fru vendor1_fru;
- struct vendor2_fru vendor2_fru;
- struct vendor3_fru vendor3_fru;
- struct vendor4_fru vendor4_fru;
+ struct vendor1_fru vendor1_fru;
+ struct vendor2_fru vendor2_fru;
+ struct vendor3_fru vendor3_fru;
+ struct vendor4_fru vendor4_fru;
};
/*
- SLIC EEPROM structure for Mojave
-*/
+ * SLIC EEPROM structure for Mojave
+ */
struct slic_eeprom {
- ushort Id; /* 00 EEPROM/FLASH Magic code 'A5A5'*/
- ushort EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
- ushort FlashSize; /* 02 Flash size */
- ushort EepromSize; /* 03 EEPROM Size */
- ushort VendorId; /* 04 Vendor ID */
- ushort DeviceId; /* 05 Device ID */
- unsigned char RevisionId; /* 06 Revision ID */
- unsigned char ClassCode[3]; /* 07 Class Code */
- unsigned char DbgIntPin; /* 08 Debug Interrupt pin */
- unsigned char NetIntPin0; /* Network Interrupt Pin */
- unsigned char MinGrant; /* 09 Minimum grant */
- unsigned char MaxLat; /* Maximum Latency */
- ushort PciStatus; /* 10 PCI Status */
- ushort SubSysVId; /* 11 Subsystem Vendor Id */
- ushort SubSysId; /* 12 Subsystem ID */
- ushort DbgDevId; /* 13 Debug Device Id */
- ushort DramRomFn; /* 14 Dram/Rom function */
- ushort DSize2Pci; /* 15 DRAM size to PCI (bytes * 64K) */
- ushort RSize2Pci; /* 16 ROM extension size to PCI (bytes * 4k) */
- unsigned char NetIntPin1;/* 17 Network Interface Pin 1
+ u16 Id; /* 00 EEPROM/FLASH Magic code 'A5A5'*/
+ u16 EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
+ u16 FlashSize; /* 02 Flash size */
+ u16 EepromSize; /* 03 EEPROM Size */
+ u16 VendorId; /* 04 Vendor ID */
+ u16 DeviceId; /* 05 Device ID */
+ u8 RevisionId; /* 06 Revision ID */
+ u8 ClassCode[3]; /* 07 Class Code */
+ u8 DbgIntPin; /* 08 Debug Interrupt pin */
+ u8 NetIntPin0; /* Network Interrupt Pin */
+ u8 MinGrant; /* 09 Minimum grant */
+ u8 MaxLat; /* Maximum Latency */
+ u16 PciStatus; /* 10 PCI Status */
+ u16 SubSysVId; /* 11 Subsystem Vendor Id */
+ u16 SubSysId; /* 12 Subsystem ID */
+ u16 DbgDevId; /* 13 Debug Device Id */
+ u16 DramRomFn; /* 14 Dram/Rom function */
+ u16 DSize2Pci; /* 15 DRAM size to PCI (bytes * 64K) */
+ u16 RSize2Pci; /* 16 ROM extension size to PCI (bytes * 4k) */
+ u8 NetIntPin1; /* 17 Network Interface Pin 1
(simba/leone only) */
- unsigned char NetIntPin2; /*Network Interface Pin 2 (simba/leone only)*/
+ u8 NetIntPin2; /* Network Interface Pin 2 (simba/leone only)*/
union {
- unsigned char NetIntPin3;/*18 Network Interface Pin 3
- (simba only)*/
- unsigned char FreeTime;/*FreeTime setting (leone/mojave only) */
+ u8 NetIntPin3; /* 18 Network Interface Pin 3 (simba only) */
+ u8 FreeTime; /* FreeTime setting (leone/mojave only) */
} u1;
- unsigned char TBIctl; /* 10-bit interface control (Mojave only) */
- ushort DramSize; /* 19 DRAM size (bytes * 64k) */
+ u8 TBIctl; /* 10-bit interface control (Mojave only) */
+ u16 DramSize; /* 19 DRAM size (bytes * 64k) */
union {
struct {
/* Mac Interface Specific portions */
@@ -750,67 +734,64 @@ struct slic_eeprom {
struct {
/* use above struct for MAC access */
struct slic_config_mac pad[SLIC_NBR_MACS - 1];
- ushort DeviceId2; /* Device ID for 2nd
- PCI function */
- unsigned char IntPin2; /* Interrupt pin for
- 2nd PCI function */
- unsigned char ClassCode2[3]; /* Class Code for 2nd
- PCI function */
+ u16 DeviceId2; /* Device ID for 2nd PCI function */
+ u8 IntPin2; /* Interrupt pin for 2nd PCI function */
+ u8 ClassCode2[3]; /* Class Code for 2nd PCI function */
} mojave; /* 2nd function access for gigabit board */
} u2;
- ushort CfgByte6; /* Config Byte 6 */
- ushort PMECapab; /* Power Mgment capabilities */
- ushort NwClkCtrls; /* NetworkClockControls */
- unsigned char FruFormat; /* Alacritech FRU format type */
- struct atk_fru AtkFru; /* Alacritech FRU information */
- unsigned char OemFruFormat; /* optional OEM FRU format type */
- union oemfru OemFru; /* optional OEM FRU information */
- unsigned char Pad[4]; /* Pad to 128 bytes - includes 2 cksum bytes
- *(if OEM FRU info exists) and two unusable
+ u16 CfgByte6; /* Config Byte 6 */
+ u16 PMECapab; /* Power Mgment capabilities */
+ u16 NwClkCtrls; /* NetworkClockControls */
+ u8 FruFormat; /* Alacritech FRU format type */
+ struct atk_fru AtkFru; /* Alacritech FRU information */
+ u8 OemFruFormat; /* optional OEM FRU format type */
+ union oemfru OemFru; /* optional OEM FRU information */
+ u8 Pad[4]; /* Pad to 128 bytes - includes 2 cksum bytes
+ * (if OEM FRU info exists) and two unusable
* bytes at the end */
};
/* SLIC EEPROM structure for Oasis */
struct oslic_eeprom {
- ushort Id; /* 00 EEPROM/FLASH Magic code 'A5A5' */
- ushort EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
- ushort FlashConfig0; /* 02 Flash Config for SPI device 0 */
- ushort FlashConfig1; /* 03 Flash Config for SPI device 1 */
- ushort VendorId; /* 04 Vendor ID */
- ushort DeviceId; /* 05 Device ID (function 0) */
- unsigned char RevisionId; /* 06 Revision ID */
- unsigned char ClassCode[3]; /* 07 Class Code for PCI function 0 */
- unsigned char IntPin1; /* 08 Interrupt pin for PCI function 1*/
- unsigned char ClassCode2[3]; /* 09 Class Code for PCI function 1 */
- unsigned char IntPin2; /* 10 Interrupt pin for PCI function 2*/
- unsigned char IntPin0; /* Interrupt pin for PCI function 0*/
- unsigned char MinGrant; /* 11 Minimum grant */
- unsigned char MaxLat; /* Maximum Latency */
- ushort SubSysVId; /* 12 Subsystem Vendor Id */
- ushort SubSysId; /* 13 Subsystem ID */
- ushort FlashSize; /* 14 Flash size (bytes / 4K) */
- ushort DSize2Pci; /* 15 DRAM size to PCI (bytes / 64K) */
- ushort RSize2Pci; /* 16 Flash (ROM extension) size to
- PCI (bytes / 4K) */
- ushort DeviceId1; /* 17 Device Id (function 1) */
- ushort DeviceId2; /* 18 Device Id (function 2) */
- ushort CfgByte6; /* 19 Device Status Config Bytes 6-7 */
- ushort PMECapab; /* 20 Power Mgment capabilities */
- unsigned char MSICapab; /* 21 MSI capabilities */
- unsigned char ClockDivider; /* Clock divider */
- ushort PciStatusLow; /* 22 PCI Status bits 15:0 */
- ushort PciStatusHigh; /* 23 PCI Status bits 31:16 */
- ushort DramConfigLow; /* 24 DRAM Configuration bits 15:0 */
- ushort DramConfigHigh; /* 25 DRAM Configuration bits 31:16 */
- ushort DramSize; /* 26 DRAM size (bytes / 64K) */
- ushort GpioTbiCtl;/* 27 GPIO/TBI controls for functions 1/0 */
- ushort EepromSize; /* 28 EEPROM Size */
+ u16 Id; /* 00 EEPROM/FLASH Magic code 'A5A5' */
+ u16 EecodeSize; /* 01 Size of EEPROM Codes (bytes * 4)*/
+ u16 FlashConfig0; /* 02 Flash Config for SPI device 0 */
+ u16 FlashConfig1; /* 03 Flash Config for SPI device 1 */
+ u16 VendorId; /* 04 Vendor ID */
+ u16 DeviceId; /* 05 Device ID (function 0) */
+ u8 RevisionId; /* 06 Revision ID */
+ u8 ClassCode[3]; /* 07 Class Code for PCI function 0 */
+ u8 IntPin1; /* 08 Interrupt pin for PCI function 1*/
+ u8 ClassCode2[3]; /* 09 Class Code for PCI function 1 */
+ u8 IntPin2; /* 10 Interrupt pin for PCI function 2*/
+ u8 IntPin0; /* Interrupt pin for PCI function 0*/
+ u8 MinGrant; /* 11 Minimum grant */
+ u8 MaxLat; /* Maximum Latency */
+ u16 SubSysVId; /* 12 Subsystem Vendor Id */
+ u16 SubSysId; /* 13 Subsystem ID */
+ u16 FlashSize; /* 14 Flash size (bytes / 4K) */
+ u16 DSize2Pci; /* 15 DRAM size to PCI (bytes / 64K) */
+ u16 RSize2Pci; /* 16 Flash (ROM extension) size to PCI
+ (bytes / 4K) */
+ u16 DeviceId1; /* 17 Device Id (function 1) */
+ u16 DeviceId2; /* 18 Device Id (function 2) */
+ u16 CfgByte6; /* 19 Device Status Config Bytes 6-7 */
+ u16 PMECapab; /* 20 Power Mgment capabilities */
+ u8 MSICapab; /* 21 MSI capabilities */
+ u8 ClockDivider; /* Clock divider */
+ u16 PciStatusLow; /* 22 PCI Status bits 15:0 */
+ u16 PciStatusHigh; /* 23 PCI Status bits 31:16 */
+ u16 DramConfigLow; /* 24 DRAM Configuration bits 15:0 */
+ u16 DramConfigHigh; /* 25 DRAM Configuration bits 31:16 */
+ u16 DramSize; /* 26 DRAM size (bytes / 64K) */
+ u16 GpioTbiCtl; /* 27 GPIO/TBI controls for functions 1/0 */
+ u16 EepromSize; /* 28 EEPROM Size */
struct slic_config_mac MacInfo[2]; /* 29 MAC addresses (2 ports) */
- unsigned char FruFormat; /* 35 Alacritech FRU format type */
+ u8 FruFormat; /* 35 Alacritech FRU format type */
struct atk_fru AtkFru; /* Alacritech FRU information */
- unsigned char OemFruFormat; /* optional OEM FRU format type */
- union oemfru OemFru; /* optional OEM FRU information */
- unsigned char Pad[4]; /* Pad to 128 bytes - includes 2 checksum bytes
+ u8 OemFruFormat; /* optional OEM FRU format type */
+ union oemfru OemFru; /* optional OEM FRU information */
+ u8 Pad[4]; /* Pad to 128 bytes - includes 2 checksum bytes
* (if OEM FRU info exists) and two unusable
* bytes at the end
*/
@@ -819,24 +800,25 @@ struct oslic_eeprom {
#define MAX_EECODE_SIZE sizeof(struct slic_eeprom)
#define MIN_EECODE_SIZE 0x62 /* code size without optional OEM FRU stuff */
-/* SLIC CONFIG structure
-
- This structure lives in the CARD structure and is valid for all
- board types. It is filled in from the appropriate EEPROM structure
- by SlicGetConfigData().
-*/
+/*
+ * SLIC CONFIG structure
+ *
+ * This structure lives in the CARD structure and is valid for all board types.
+ * It is filled in from the appropriate EEPROM structure by
+ * SlicGetConfigData()
+ */
struct slic_config {
bool EepromValid; /* Valid EEPROM flag (checksum good?) */
- ushort DramSize; /* DRAM size (bytes / 64K) */
+ u16 DramSize; /* DRAM size (bytes / 64K) */
struct slic_config_mac MacInfo[SLIC_NBR_MACS]; /* MAC addresses */
- unsigned char FruFormat; /* Alacritech FRU format type */
+ u8 FruFormat; /* Alacritech FRU format type */
struct atk_fru AtkFru; /* Alacritech FRU information */
- unsigned char OemFruFormat; /* optional OEM FRU format type */
+ u8 OemFruFormat; /* optional OEM FRU format type */
union {
- struct vendor1_fru vendor1_fru;
- struct vendor2_fru vendor2_fru;
- struct vendor3_fru vendor3_fru;
- struct vendor4_fru vendor4_fru;
+ struct vendor1_fru vendor1_fru;
+ struct vendor2_fru vendor2_fru;
+ struct vendor3_fru vendor3_fru;
+ struct vendor4_fru vendor4_fru;
} OemFru;
};
diff --git a/drivers/staging/slicoss/slicinc.h b/drivers/staging/slicoss/slicinc.h
deleted file mode 100644
index 71288c4f7be..00000000000
--- a/drivers/staging/slicoss/slicinc.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/**************************************************************************
- *
- * Copyright (c) 2000-2002 Alacritech, Inc. All rights reserved.
- *
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials provided
- * with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The views and conclusions contained in the software and documentation
- * are those of the authors and should not be interpreted as representing
- * official policies, either expressed or implied, of Alacritech, Inc.
- *
- **************************************************************************/
-
-/*
- * FILENAME: slicinc.h
- *
- * This file contains all other include files and prototype definitions
- * for the SLICOSS driver.
- */
-#ifndef _SLIC_INCLUDE_H_
-#define _SLIC_INCLUDE_H_
-
-#include "slic_os.h"
-#include "slicdbg.h"
-#include "slichw.h"
-#include "slic.h"
-
-static int slic_entry_probe(struct pci_dev *pcidev,
- const struct pci_device_id *ent);
-static void slic_entry_remove(struct pci_dev *pcidev);
-
-static void slic_init_driver(void);
-static int slic_entry_open(struct net_device *dev);
-static int slic_entry_halt(struct net_device *dev);
-static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
-static void slic_xmit_fail(struct adapter *adapter,
- struct sk_buff *skb,
- void *cmd,
- u32 skbtype,
- u32 status);
-static void slic_config_pci(struct pci_dev *pcidev);
-static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter);
-
-static inline void slic_reg32_write(void __iomem *reg, u32 value, uint flush);
-static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
- u32 value, void __iomem *regh, u32 paddrh, uint flush);
-
-#if SLIC_GET_STATS_ENABLED
-static struct net_device_stats *slic_get_stats(struct net_device *dev);
-#endif
-
-static int slic_mac_set_address(struct net_device *dev, void *ptr);
-static void slic_rcv_handler(struct adapter *adapter);
-static void slic_link_event_handler(struct adapter *adapter);
-static void slic_xmit_complete(struct adapter *adapter);
-static void slic_upr_request_complete(struct adapter *adapter, u32 isr);
-static int slic_rspqueue_init(struct adapter *adapter);
-static int slic_rspqueue_reset(struct adapter *adapter);
-static void slic_rspqueue_free(struct adapter *adapter);
-static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter);
-static void slic_cmdqmem_init(struct adapter *adapter);
-static void slic_cmdqmem_free(struct adapter *adapter);
-static u32 *slic_cmdqmem_addpage(struct adapter *adapter);
-static int slic_cmdq_init(struct adapter *adapter);
-static void slic_cmdq_free(struct adapter *adapter);
-static void slic_cmdq_reset(struct adapter *adapter);
-static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page);
-static void slic_cmdq_getdone(struct adapter *adapter);
-static void slic_cmdq_putdone_irq(struct adapter *adapter,
- struct slic_hostcmd *cmd);
-static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter);
-static int slic_rcvqueue_init(struct adapter *adapter);
-static int slic_rcvqueue_reset(struct adapter *adapter);
-static int slic_rcvqueue_fill(struct adapter *adapter);
-static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb);
-static void slic_rcvqueue_free(struct adapter *adapter);
-static void slic_rcv_handle_error(struct adapter *adapter,
- struct slic_rcvbuf *rcvbuf);
-static void slic_adapter_set_hwaddr(struct adapter *adapter);
-static int slic_card_init(struct sliccard *card, struct adapter *adapter);
-static void slic_intagg_set(struct adapter *adapter, u32 value);
-static int slic_card_download(struct adapter *adapter);
-static u32 slic_card_locate(struct adapter *adapter);
-
-static void slic_if_stop_queue(struct adapter *adapter);
-static void slic_if_start_queue(struct adapter *adapter);
-static int slic_if_init(struct adapter *adapter);
-static int slic_adapter_allocresources(struct adapter *adapter);
-static void slic_adapter_freeresources(struct adapter *adapter);
-static void slic_link_config(struct adapter *adapter, u32 linkspeed,
- u32 linkduplex);
-static void slic_unmap_mmio_space(struct adapter *adapter);
-static void slic_card_cleanup(struct sliccard *card);
-static void slic_init_cleanup(struct adapter *adapter);
-static void slic_soft_reset(struct adapter *adapter);
-static bool slic_mac_filter(struct adapter *adapter,
- struct ether_header *ether_frame);
-static void slic_mac_address_config(struct adapter *adapter);
-static void slic_mac_config(struct adapter *adapter);
-static void slic_mcast_set_mask(struct adapter *adapter);
-static int slic_mcast_add_list(struct adapter *adapter, char *address);
-static unsigned char slic_mcast_get_mac_hash(char *macaddr);
-static void slic_mcast_set_bit(struct adapter *adapter, char *address);
-static void slic_config_set(struct adapter *adapter, bool linkchange);
-static void slic_config_clear(struct adapter *adapter);
-static void slic_config_get(struct adapter *adapter, u32 config,
- u32 configh);
-static void slic_timer_load_check(ulong context);
-static void slic_timer_ping(ulong dev);
-static void slic_assert_fail(void);
-static ushort slic_eeprom_cksum(char *m, int len);
-/* upr */
-static void slic_upr_start(struct adapter *adapter);
-static void slic_link_upr_complete(struct adapter *adapter, u32 Isr);
-static int slic_upr_request(struct adapter *adapter,
- u32 upr_request,
- u32 upr_data,
- u32 upr_data_h,
- u32 upr_buffer,
- u32 upr_buffer_h);
-static int slic_upr_queue_request(struct adapter *adapter,
- u32 upr_request,
- u32 upr_data,
- u32 upr_data_h,
- u32 upr_buffer,
- u32 upr_buffer_h);
-static void slic_mcast_set_list(struct net_device *dev);
-static void slic_mcast_init_crc32(void);
-
-#if SLIC_DUMP_ENABLED
-static int slic_dump_thread(void *context);
-static uint slic_init_dump_thread(struct sliccard *card);
-static unsigned char slic_get_dump_index(char *path);
-static u32 slic_dump_card(struct sliccard *card, bool resume);
-static u32 slic_dump_halt(struct sliccard *card, unsigned char proc);
-static u32 slic_dump_reg(struct sliccard *card, unsigned char proc);
-static u32 slic_dump_data(struct sliccard *card, u32 addr,
- ushort count, unsigned char desc);
-static u32 slic_dump_queue(struct sliccard *card, u32 buf_phys,
- u32 buf_physh, u32 queue);
-static u32 slic_dump_load_queue(struct sliccard *card, u32 data,
- u32 queue);
-static u32 slic_dump_cam(struct sliccard *card, u32 addr,
- u32 count, unsigned char desc);
-
-static u32 slic_dump_resume(struct sliccard *card, unsigned char proc);
-static u32 slic_dump_send_cmd(struct sliccard *card, u32 cmd_phys,
- u32 cmd_physh, u32 buf_phys,
- u32 buf_physh);
-
-#define create_file(x) STATUS_SUCCESS
-#define write_file(w, x, y, z) STATUS_SUCCESS
-#define close_file(x) STATUS_SUCCESS
-#define read_file(w, x, y, z) STATUS_SUCCESS
-#define open_file(x) STATUS_SUCCESS
-
-/* PAGE_SIZE * 16 */
-#define DUMP_PAGE_SIZE 0xFFFF
-#define DUMP_PAGE_SIZE_HALF 0x7FFE
-#endif
-
-#endif /* _SLIC_INCLUDE_H_ */
diff --git a/drivers/staging/slicoss/slicoss.c b/drivers/staging/slicoss/slicoss.c
index bf7da8f898a..953684f729d 100644
--- a/drivers/staging/slicoss/slicoss.c
+++ b/drivers/staging/slicoss/slicoss.c
@@ -55,19 +55,10 @@
*/
-#define SLIC_DUMP_ENABLED 0
#define KLUDGE_FOR_4GB_BOUNDARY 1
#define DEBUG_MICROCODE 1
-#define SLIC_PRODUCTION_BUILD 1
-#define SLIC_FAILURE_RESET 1
#define DBG 1
-#define SLIC_ASSERT_ENABLED 1
-#define SLIC_GET_STATS_ENABLED 1
-#define SLIC_GET_STATS_TIMER_ENABLED 0
-#define SLIC_PING_TIMER_ENABLED 1
-#define SLIC_POWER_MANAGEMENT_ENABLED 0
#define SLIC_INTERRUPT_PROCESS_LIMIT 1
-#define LINUX_FREES_ADAPTER_RESOURCES 1
#define SLIC_OFFLOAD_IP_CHECKSUM 1
#define STATS_TIMER_INTERVAL 2
#define PING_TIMER_INTERVAL 1
@@ -102,20 +93,73 @@
#include <asm/unaligned.h>
#include <linux/ethtool.h>
-#define SLIC_ETHTOOL_SUPPORT 1
-
#include <linux/uaccess.h>
-#include "slicinc.h"
-
-#if SLIC_DUMP_ENABLED
-#include "slicdump.h"
-#endif
+#include "slichw.h"
+#include "slic.h"
+
+static struct net_device_stats *slic_get_stats(struct net_device *dev);
+static int slic_entry_open(struct net_device *dev);
+static int slic_entry_halt(struct net_device *dev);
+static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static void slic_xmit_fail(struct adapter *adapter, struct sk_buff *skb,
+ void *cmd, u32 skbtype, u32 status);
+static void slic_config_pci(struct pci_dev *pcidev);
+static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter);
+static int slic_mac_set_address(struct net_device *dev, void *ptr);
+static void slic_link_event_handler(struct adapter *adapter);
+static void slic_upr_request_complete(struct adapter *adapter, u32 isr);
+static int slic_rspqueue_init(struct adapter *adapter);
+static void slic_rspqueue_free(struct adapter *adapter);
+static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter);
+static int slic_cmdq_init(struct adapter *adapter);
+static void slic_cmdq_free(struct adapter *adapter);
+static void slic_cmdq_reset(struct adapter *adapter);
+static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page);
+static void slic_cmdq_getdone(struct adapter *adapter);
+static void slic_cmdq_putdone_irq(struct adapter *adapter,
+ struct slic_hostcmd *cmd);
+static struct slic_hostcmd *slic_cmdq_getfree(struct adapter *adapter);
+static int slic_rcvqueue_init(struct adapter *adapter);
+static int slic_rcvqueue_fill(struct adapter *adapter);
+static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb);
+static void slic_rcvqueue_free(struct adapter *adapter);
+static void slic_adapter_set_hwaddr(struct adapter *adapter);
+static int slic_card_init(struct sliccard *card, struct adapter *adapter);
+static void slic_intagg_set(struct adapter *adapter, u32 value);
+static int slic_card_download(struct adapter *adapter);
+static u32 slic_card_locate(struct adapter *adapter);
+static int slic_if_init(struct adapter *adapter);
+static int slic_adapter_allocresources(struct adapter *adapter);
+static void slic_adapter_freeresources(struct adapter *adapter);
+static void slic_link_config(struct adapter *adapter, u32 linkspeed,
+ u32 linkduplex);
+static void slic_unmap_mmio_space(struct adapter *adapter);
+static void slic_card_cleanup(struct sliccard *card);
+static void slic_soft_reset(struct adapter *adapter);
+static bool slic_mac_filter(struct adapter *adapter,
+ struct ether_header *ether_frame);
+static void slic_mac_address_config(struct adapter *adapter);
+static void slic_mac_config(struct adapter *adapter);
+static void slic_mcast_set_mask(struct adapter *adapter);
+static void slic_config_set(struct adapter *adapter, bool linkchange);
+static void slic_config_clear(struct adapter *adapter);
+static void slic_config_get(struct adapter *adapter, u32 config,
+ u32 configh);
+static void slic_timer_load_check(ulong context);
+static void slic_assert_fail(void);
+static ushort slic_eeprom_cksum(char *m, int len);
+static void slic_upr_start(struct adapter *adapter);
+static void slic_link_upr_complete(struct adapter *adapter, u32 Isr);
+static int slic_upr_request(struct adapter *adapter, u32 upr_request,
+ u32 upr_data, u32 upr_data_h, u32 upr_buffer,
+ u32 upr_buffer_h);
+static void slic_mcast_set_list(struct net_device *dev);
-#define SLIC_POWER_MANAGEMENT 0
static uint slic_first_init = 1;
static char *slic_banner = "Alacritech SLIC Technology(tm) Server "\
- "and Storage Accelerator (Non-Accelerated)\n";
+ "and Storage Accelerator (Non-Accelerated)";
static char *slic_proc_version = "2.0.351 2006/07/14 12:26:00";
static char *slic_product_name = "SLIC Technology(tm) Server "\
@@ -129,8 +173,6 @@ static struct net_device *head_netdevice;
static struct base_driver slic_global = { {}, 0, 0, 0, 1, NULL, NULL };
static int intagg_delay = 100;
static u32 dynamic_intagg;
-static int errormsg;
-static int goodmsg;
static unsigned int rcv_count;
static struct dentry *slic_debugfs;
@@ -164,6 +206,21 @@ static struct pci_device_id slic_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, slic_pci_tbl);
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#ifndef ASSERT
+#define ASSERT(a) do { \
+ if (!(a)) { \
+ printk(KERN_ERR "slicoss ASSERT() Failure: function %s" \
+ "line %d\n", __func__, __LINE__); \
+ slic_assert_fail(); \
+ } \
+} while (0)
+#endif
+
+
#define SLIC_GET_SLIC_HANDLE(_adapter, _pslic_handle) \
{ \
spin_lock_irqsave(&_adapter->handle_lock.lock, \
@@ -195,17 +252,16 @@ static void slic_debug_adapter_destroy(struct adapter *adapter);
static void slic_debug_card_create(struct sliccard *card);
static void slic_debug_card_destroy(struct sliccard *card);
-static inline void slic_reg32_write(void __iomem *reg, u32 value, uint flush)
+static inline void slic_reg32_write(void __iomem *reg, u32 value, bool flush)
{
writel(value, reg);
if (flush)
mb();
}
-static inline void slic_reg64_write(struct adapter *adapter,
- void __iomem *reg,
- u32 value,
- void __iomem *regh, u32 paddrh, uint flush)
+static inline void slic_reg64_write(struct adapter *adapter, void __iomem *reg,
+ u32 value, void __iomem *regh, u32 paddrh,
+ bool flush)
{
spin_lock_irqsave(&adapter->bit64reglock.lock,
adapter->bit64reglock.flags);
@@ -223,43 +279,12 @@ static inline void slic_reg64_write(struct adapter *adapter,
static void slic_init_driver(void)
{
if (slic_first_init) {
- DBG_MSG("slicoss: %s slic_first_init set jiffies[%lx]\n",
- __func__, jiffies);
slic_first_init = 0;
spin_lock_init(&slic_global.driver_lock.lock);
slic_debug_init();
}
}
-static void slic_dbg_macaddrs(struct adapter *adapter)
-{
- DBG_MSG(" (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
- adapter->netdev->name, adapter->currmacaddr[0],
- adapter->currmacaddr[1], adapter->currmacaddr[2],
- adapter->currmacaddr[3], adapter->currmacaddr[4],
- adapter->currmacaddr[5]);
- DBG_MSG(" (%s) mac %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
- adapter->netdev->name, adapter->macaddr[0],
- adapter->macaddr[1], adapter->macaddr[2],
- adapter->macaddr[3], adapter->macaddr[4], adapter->macaddr[5]);
- return;
-}
-
-#ifdef DEBUG_REGISTER_TRACE
-static void slic_dbg_register_trace(struct adapter *adapter,
- struct sliccard *card)
-{
- uint i;
-
- DBG_ERROR("Dump Register Write Trace: curr_ix == %d\n", card->debug_ix);
- for (i = 0; i < 32; i++) {
- DBG_ERROR("%2d %d %4x %x %x\n",
- i, card->reg_type[i], card->reg_offset[i],
- card->reg_value[i], card->reg_valueh[i]);
- }
-}
-#endif
-
static void slic_init_adapter(struct net_device *netdev,
struct pci_dev *pcidev,
const struct pci_device_id *pci_tbl_entry,
@@ -268,9 +293,7 @@ static void slic_init_adapter(struct net_device *netdev,
ushort index;
struct slic_handle *pslic_handle;
struct adapter *adapter = (struct adapter *)netdev_priv(netdev);
-/*
- DBG_MSG("slicoss: %s (%s)\n netdev [%p]\n adapter[%p]\n "
- "pcidev [%p]\n", __func__, netdev->name, netdev, adapter, pcidev);*/
+
/* adapter->pcidev = pcidev;*/
adapter->vendid = pci_tbl_entry->vendor;
adapter->devid = pci_tbl_entry->device;
@@ -310,19 +333,11 @@ static void slic_init_adapter(struct net_device *netdev,
pslic_handle->next = adapter->pfree_slic_handles;
adapter->pfree_slic_handles = pslic_handle;
}
-/*
- DBG_MSG(".........\nix[%d] phandle[%p] pfree[%p] next[%p]\n",
- index, pslic_handle, adapter->pfree_slic_handles, pslic_handle->next);*/
adapter->pshmem = (struct slic_shmem *)
pci_alloc_consistent(adapter->pcidev,
sizeof(struct slic_shmem),
&adapter->
phys_shmem);
-/*
- DBG_MSG("slicoss: %s (%s)\n pshmem [%p]\n phys_shmem[%p]\n"\
- "slic_regs [%p]\n", __func__, netdev->name, adapter->pshmem,
- (void *)adapter->phys_shmem, adapter->slic_regs);
-*/
ASSERT(adapter->pshmem);
memset(adapter->pshmem, 0, sizeof(struct slic_shmem));
@@ -335,7 +350,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
{
static int cards_found;
static int did_version;
- int err;
+ int err = -ENODEV;
struct net_device *netdev;
struct adapter *adapter;
void __iomem *memmapped_ioaddr = NULL;
@@ -344,54 +359,36 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
ulong mmio_len = 0;
struct sliccard *card = NULL;
- DBG_MSG("slicoss: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
- __func__, jiffies, smp_processor_id());
-
slic_global.dynamic_intagg = dynamic_intagg;
err = pci_enable_device(pcidev);
- DBG_MSG("Call pci_enable_device(%p) status[%x]\n", pcidev, err);
if (err)
return err;
if (slic_debug > 0 && did_version++ == 0) {
- printk(slic_banner);
- printk(slic_proc_version);
+ printk(KERN_DEBUG "%s\n", slic_banner);
+ printk(KERN_DEBUG "%s\n", slic_proc_version);
}
err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK);
- if (!err) {
- DBG_MSG("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
- } else {
+ if (err) {
err = pci_set_dma_mask(pcidev, DMA_32BIT_MASK);
- if (err) {
- DBG_MSG
- ("No usable DMA configuration, aborting err[%x]\n",
- err);
- return err;
- }
- DBG_MSG("pci_set_dma_mask(DMA_32BIT_MASK) successful\n");
+ if (err)
+ goto err_out_disable_pci;
}
- DBG_MSG("Call pci_request_regions\n");
-
err = pci_request_regions(pcidev, DRV_NAME);
- if (err) {
- DBG_MSG("pci_request_regions FAILED err[%x]\n", err);
- return err;
- }
+ if (err)
+ goto err_out_disable_pci;
- DBG_MSG("call pci_set_master\n");
pci_set_master(pcidev);
- DBG_MSG("call alloc_etherdev\n");
netdev = alloc_etherdev(sizeof(struct adapter));
if (!netdev) {
err = -ENOMEM;
goto err_out_exit_slic_probe;
}
- DBG_MSG("alloc_etherdev for slic netdev[%p]\n", netdev);
SET_NETDEV_DEV(netdev, &pcidev->dev);
@@ -403,24 +400,15 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
mmio_start = pci_resource_start(pcidev, 0);
mmio_len = pci_resource_len(pcidev, 0);
- DBG_MSG("slicoss: call ioremap(mmio_start[%lx], mmio_len[%lx])\n",
- mmio_start, mmio_len);
-/* memmapped_ioaddr = (u32)ioremap_nocache(mmio_start, mmio_len);*/
+/* memmapped_ioaddr = (u32)ioremap_nocache(mmio_start, mmio_len);*/
memmapped_ioaddr = ioremap(mmio_start, mmio_len);
- DBG_MSG("slicoss: %s MEMMAPPED_IOADDR [%p]\n", __func__,
- memmapped_ioaddr);
if (!memmapped_ioaddr) {
- DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
- __func__, mmio_len, mmio_start);
- goto err_out_free_mmio_region;
+ dev_err(&pcidev->dev, "cannot remap MMIO region %lx @ %lx\n",
+ mmio_len, mmio_start);
+ goto err_out_free_netdev;
}
- DBG_MSG
- ("slicoss: %s found Alacritech SLICOSS PCI, MMIO at %p, "\
- "start[%lx] len[%lx], IRQ %d.\n",
- __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
-
slic_config_pci(pcidev);
slic_init_driver();
@@ -430,7 +418,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
status = slic_card_locate(adapter);
if (status) {
- DBG_ERROR("%s cannot locate card\n", __func__);
+ dev_err(&pcidev->dev, "cannot locate card\n");
goto err_out_free_mmio_region;
}
@@ -441,22 +429,13 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
adapter->allocated = 1;
}
- DBG_MSG("slicoss: %s card: %p\n", __func__,
- adapter->card);
- DBG_MSG("slicoss: %s card->adapter[%d] == [%p]\n", __func__,
- (uint) adapter->port, adapter);
- DBG_MSG("slicoss: %s card->adapters_allocated [%d]\n", __func__,
- card->adapters_allocated);
- DBG_MSG("slicoss: %s card->adapters_activated [%d]\n", __func__,
- card->adapters_activated);
-
status = slic_card_init(card, adapter);
if (status != STATUS_SUCCESS) {
card->state = CARD_FAIL;
adapter->state = ADAPT_FAIL;
adapter->linkstate = LINK_DOWN;
- DBG_ERROR("slic_card_init FAILED status[%x]\n", status);
+ dev_err(&pcidev->dev, "FAILED status[%x]\n", status);
} else {
slic_adapter_set_hwaddr(adapter);
}
@@ -468,9 +447,7 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
netdev->hard_start_xmit = slic_xmit_start;
netdev->do_ioctl = slic_ioctl;
netdev->set_mac_address = slic_mac_set_address;
-#if SLIC_GET_STATS_ENABLED
netdev->get_stats = slic_get_stats;
-#endif
netdev->set_multicast_list = slic_mcast_set_list;
slic_debug_adapter_create(adapter);
@@ -478,35 +455,25 @@ static int __devinit slic_entry_probe(struct pci_dev *pcidev,
strcpy(netdev->name, "eth%d");
err = register_netdev(netdev);
if (err) {
- DBG_ERROR("Cannot register net device, aborting.\n");
+ dev_err(&pcidev->dev, "Cannot register net device, aborting.\n");
goto err_out_unmap;
}
- DBG_MSG
- ("slicoss: addr 0x%lx, irq %d, MAC addr "\
- "%02X:%02X:%02X:%02X:%02X:%02X\n",
- mmio_start, /*pci_resource_start(pcidev, 0), */ pcidev->irq,
- netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2],
- netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]);
-
cards_found++;
- DBG_MSG("slicoss: %s EXIT status[%x] jiffies[%lx] cpu %d\n",
- __func__, status, jiffies, smp_processor_id());
return status;
err_out_unmap:
iounmap(memmapped_ioaddr);
-
err_out_free_mmio_region:
release_mem_region(mmio_start, mmio_len);
-
+err_out_free_netdev:
+ free_netdev(netdev);
err_out_exit_slic_probe:
pci_release_regions(pcidev);
- DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
- smp_processor_id());
-
- return -ENODEV;
+err_out_disable_pci:
+ pci_disable_device(pcidev);
+ return err;
}
static int slic_entry_open(struct net_device *dev)
@@ -518,16 +485,6 @@ static int slic_entry_open(struct net_device *dev)
ASSERT(adapter);
ASSERT(card);
- DBG_MSG
- ("slicoss: %s adapter->activated[%d] card->adapters[%x] "\
- "allocd[%x]\n", __func__, adapter->activated,
- card->adapters_activated,
- card->adapters_allocated);
- DBG_MSG
- ("slicoss: %s (%s): [jiffies[%lx] cpu %d] dev[%p] adapt[%p] "\
- "port[%d] card[%p]\n",
- __func__, adapter->netdev->name, jiffies, smp_processor_id(),
- adapter->netdev, adapter, adapter->port, card);
netif_stop_queue(adapter->netdev);
@@ -554,29 +511,14 @@ static int slic_entry_open(struct net_device *dev)
}
return status;
}
- DBG_MSG("slicoss: %s set card->master[%p] adapter[%p]\n", __func__,
- card->master, adapter);
if (!card->master)
card->master = adapter;
-#if SLIC_DUMP_ENABLED
- if (!(card->dumpthread_running))
- init_waitqueue_head(&card->dump_wq);
-#endif
if (locked) {
spin_unlock_irqrestore(&slic_global.driver_lock.lock,
slic_global.driver_lock.flags);
locked = 0;
}
-#if SLIC_DUMP_ENABLED
- if (!(card->dumpthread_running)) {
- DBG_MSG("attempt to initialize dump thread\n");
- status = slic_init_dump_thread(card);
- /*
- Even if the dump thread fails, we will continue at this point
- */
- }
-#endif
return STATUS_SUCCESS;
}
@@ -591,22 +533,15 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
struct mcast_address *mcaddr, *mlist;
ASSERT(adapter);
- DBG_MSG("slicoss: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
- adapter);
slic_adapter_freeresources(adapter);
slic_unmap_mmio_space(adapter);
- DBG_MSG("slicoss: %s unregister_netdev\n", __func__);
unregister_netdev(dev);
mmio_start = pci_resource_start(pcidev, 0);
mmio_len = pci_resource_len(pcidev, 0);
- DBG_MSG("slicoss: %s rel_region(0) start[%x] len[%x]\n", __func__,
- mmio_start, mmio_len);
release_mem_region(mmio_start, mmio_len);
- DBG_MSG("slicoss: %s iounmap dev->base_addr[%x]\n", __func__,
- (uint) dev->base_addr);
iounmap((void __iomem *)dev->base_addr);
/* free multicast addresses */
mlist = adapter->mcastaddrs;
@@ -620,10 +555,6 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
ASSERT(card->adapters_allocated);
card->adapters_allocated--;
adapter->allocated = 0;
- DBG_MSG
- ("slicoss: %s init[%x] alloc[%x] card[%p] adapter[%p]\n",
- __func__, card->adapters_activated, card->adapters_allocated,
- card, adapter);
if (!card->adapters_allocated) {
struct sliccard *curr_card = slic_global.slic_card;
if (curr_card == card) {
@@ -638,10 +569,8 @@ static void __devexit slic_entry_remove(struct pci_dev *pcidev)
slic_global.num_slic_cards--;
slic_card_cleanup(card);
}
- DBG_MSG("slicoss: %s deallocate device\n", __func__);
kfree(dev);
pci_release_regions(pcidev);
- DBG_MSG("slicoss: %s EXIT\n", __func__);
}
static int slic_entry_halt(struct net_device *dev)
@@ -653,75 +582,35 @@ static int slic_entry_halt(struct net_device *dev)
spin_lock_irqsave(&slic_global.driver_lock.lock,
slic_global.driver_lock.flags);
ASSERT(card);
- DBG_MSG("slicoss: %s (%s) ENTER\n", __func__, dev->name);
- DBG_MSG("slicoss: %s (%s) actvtd[%d] alloc[%d] state[%x] adapt[%p]\n",
- __func__, dev->name, card->adapters_activated,
- card->adapters_allocated, card->state, adapter);
- slic_if_stop_queue(adapter);
+ netif_stop_queue(adapter->netdev);
adapter->state = ADAPT_DOWN;
adapter->linkstate = LINK_DOWN;
adapter->upr_list = NULL;
adapter->upr_busy = 0;
adapter->devflags_prev = 0;
- DBG_MSG("slicoss: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
- __func__, dev->name, adapter, adapter->state);
ASSERT(card->adapter[adapter->cardindex] == adapter);
- WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
adapter->all_reg_writes++;
adapter->icr_reg_writes++;
slic_config_clear(adapter);
- DBG_MSG("slicoss: %s (%s) dev[%p] adapt[%p] card[%p]\n",
- __func__, dev->name, dev, adapter, card);
if (adapter->activated) {
card->adapters_activated--;
slic_global.num_slic_ports_active--;
adapter->activated = 0;
}
#ifdef AUTOMATIC_RESET
- WRITE_REG(slic_regs->slic_reset_iface, 0, FLUSH);
+ slic_reg32_write(&slic_regs->slic_reset_iface, 0, FLUSH);
#endif
/*
- * Reset the adapter's rsp, cmd, and rcv queues
+ * Reset the adapter's cmd queues
*/
slic_cmdq_reset(adapter);
- slic_rspqueue_reset(adapter);
- slic_rcvqueue_reset(adapter);
#ifdef AUTOMATIC_RESET
- if (!card->adapters_activated) {
-
-#if SLIC_DUMP_ENABLED
- if (card->dumpthread_running) {
- uint status;
- DBG_MSG("attempt to terminate dump thread pid[%x]\n",
- card->dump_task_id);
- status = kill_proc(card->dump_task_id->pid, SIGKILL, 1);
-
- if (!status) {
- int count = 10 * 100;
- while (card->dumpthread_running && --count) {
- current->state = TASK_INTERRUPTIBLE;
- schedule_timeout(1);
- }
-
- if (!count) {
- DBG_MSG
- ("slicmon thread cleanup FAILED \
- pid[%x]\n",
- card->dump_task_id->pid);
- }
- }
- }
-#endif
- DBG_MSG("slicoss: %s (%s) initiate CARD_HALT\n", __func__,
- dev->name);
-
+ if (!card->adapters_activated)
slic_card_init(card, adapter);
- }
#endif
- DBG_MSG("slicoss: %s (%s) EXIT\n", __func__, dev->name);
- DBG_MSG("slicoss: %s EXIT\n", __func__);
spin_unlock_irqrestore(&slic_global.driver_lock.lock,
slic_global.driver_lock.flags);
return STATUS_SUCCESS;
@@ -729,69 +618,27 @@ static int slic_entry_halt(struct net_device *dev)
static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
+ struct adapter *adapter = (struct adapter *)netdev_priv(dev);
+ struct ethtool_cmd edata;
+ struct ethtool_cmd ecmd;
+ u32 data[7];
+ u32 intagg;
+
ASSERT(rq);
-/*
- DBG_MSG("slicoss: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);
-*/
switch (cmd) {
case SIOCSLICSETINTAGG:
- {
- struct adapter *adapter = (struct adapter *)
- netdev_priv(dev);
- u32 data[7];
- u32 intagg;
-
- if (copy_from_user(data, rq->ifr_data, 28)) {
- DBG_ERROR
- ("copy_from_user FAILED getting initial \
- params\n");
- return -EFAULT;
- }
- intagg = data[0];
- printk(KERN_EMERG
- "%s: set interrupt aggregation to %d\n",
- __func__, intagg);
- slic_intagg_set(adapter, intagg);
- return 0;
- }
-#ifdef SLIC_USER_REQUEST_DUMP_ENABLED
- case SIOCSLICDUMPCARD:
- {
- struct adapter *adapter = netdev_priv(dev);
- struct sliccard *card;
-
- ASSERT(adapter);
- ASSERT(adapter->card)
- card = adapter->card;
-
- DBG_IOCTL("slic_ioctl SIOCSLIC_DUMP_CARD\n");
-
- if (card->dump_requested == SLIC_DUMP_DONE) {
- printk(SLICLEVEL
- "SLIC Card dump to be overwritten\n");
- card->dump_requested = SLIC_DUMP_REQUESTED;
- } else if ((card->dump_requested == SLIC_DUMP_REQUESTED)
- || (card->dump_requested ==
- SLIC_DUMP_IN_PROGRESS)) {
- printk(SLICLEVEL
- "SLIC Card dump Requested but already \
- in progress... ignore\n");
- } else {
- printk(SLICLEVEL
- "SLIC Card #%d Dump Requested\n",
- card->cardnum);
- card->dump_requested = SLIC_DUMP_REQUESTED;
- }
- return 0;
- }
-#endif
+ if (copy_from_user(data, rq->ifr_data, 28))
+ return -EFAULT;
+ intagg = data[0];
+ dev_err(&dev->dev, "%s: set interrupt aggregation to %d\n",
+ __func__, intagg);
+ slic_intagg_set(adapter, intagg);
+ return 0;
#ifdef SLIC_TRACE_DUMP_ENABLED
case SIOCSLICTRACEDUMP:
{
- ulong data[7];
- ulong value;
-
+ u32 value;
DBG_IOCTL("slic_ioctl SIOCSLIC_TRACE_DUMP\n");
if (copy_from_user(data, rq->ifr_data, 28)) {
@@ -824,104 +671,76 @@ static int slic_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
return 0;
}
#endif
-#if SLIC_ETHTOOL_SUPPORT
case SIOCETHTOOL:
- {
- struct adapter *adapter = (struct adapter *)
- netdev_priv(dev);
- struct ethtool_cmd data;
- struct ethtool_cmd ecmd;
-
- ASSERT(adapter);
-/* DBG_MSG("slicoss: %s SIOCETHTOOL\n", __func__); */
- if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+ ASSERT(adapter);
+ if (copy_from_user(&ecmd, rq->ifr_data, sizeof(ecmd)))
+ return -EFAULT;
+
+ if (ecmd.cmd == ETHTOOL_GSET) {
+ edata.supported = (SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg | SUPPORTED_MII);
+ edata.port = PORT_MII;
+ edata.transceiver = XCVR_INTERNAL;
+ edata.phy_address = 0;
+ if (adapter->linkspeed == LINK_100MB)
+ edata.speed = SPEED_100;
+ else if (adapter->linkspeed == LINK_10MB)
+ edata.speed = SPEED_10;
+ else
+ edata.speed = 0;
+
+ if (adapter->linkduplex == LINK_FULLD)
+ edata.duplex = DUPLEX_FULL;
+ else
+ edata.duplex = DUPLEX_HALF;
+
+ edata.autoneg = AUTONEG_ENABLE;
+ edata.maxtxpkt = 1;
+ edata.maxrxpkt = 1;
+ if (copy_to_user(rq->ifr_data, &edata, sizeof(edata)))
return -EFAULT;
- if (ecmd.cmd == ETHTOOL_GSET) {
- data.supported =
- (SUPPORTED_10baseT_Half |
- SUPPORTED_10baseT_Full |
- SUPPORTED_100baseT_Half |
- SUPPORTED_100baseT_Full |
- SUPPORTED_Autoneg | SUPPORTED_MII);
- data.port = PORT_MII;
- data.transceiver = XCVR_INTERNAL;
- data.phy_address = 0;
- if (adapter->linkspeed == LINK_100MB)
- data.speed = SPEED_100;
- else if (adapter->linkspeed == LINK_10MB)
- data.speed = SPEED_10;
- else
- data.speed = 0;
+ } else if (ecmd.cmd == ETHTOOL_SSET) {
+ if (!capable(CAP_NET_ADMIN))
+ return -EPERM;
- if (adapter->linkduplex == LINK_FULLD)
- data.duplex = DUPLEX_FULL;
- else
- data.duplex = DUPLEX_HALF;
-
- data.autoneg = AUTONEG_ENABLE;
- data.maxtxpkt = 1;
- data.maxrxpkt = 1;
- if (copy_to_user
- (rq->ifr_data, &data, sizeof(data)))
- return -EFAULT;
-
- } else if (ecmd.cmd == ETHTOOL_SSET) {
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- if (adapter->linkspeed == LINK_100MB)
- data.speed = SPEED_100;
- else if (adapter->linkspeed == LINK_10MB)
- data.speed = SPEED_10;
- else
- data.speed = 0;
+ if (adapter->linkspeed == LINK_100MB)
+ edata.speed = SPEED_100;
+ else if (adapter->linkspeed == LINK_10MB)
+ edata.speed = SPEED_10;
+ else
+ edata.speed = 0;
- if (adapter->linkduplex == LINK_FULLD)
- data.duplex = DUPLEX_FULL;
+ if (adapter->linkduplex == LINK_FULLD)
+ edata.duplex = DUPLEX_FULL;
+ else
+ edata.duplex = DUPLEX_HALF;
+
+ edata.autoneg = AUTONEG_ENABLE;
+ edata.maxtxpkt = 1;
+ edata.maxrxpkt = 1;
+ if ((ecmd.speed != edata.speed) ||
+ (ecmd.duplex != edata.duplex)) {
+ u32 speed;
+ u32 duplex;
+
+ if (ecmd.speed == SPEED_10)
+ speed = 0;
else
- data.duplex = DUPLEX_HALF;
-
- data.autoneg = AUTONEG_ENABLE;
- data.maxtxpkt = 1;
- data.maxrxpkt = 1;
- if ((ecmd.speed != data.speed) ||
- (ecmd.duplex != data.duplex)) {
- u32 speed;
- u32 duplex;
-
- if (ecmd.speed == SPEED_10) {
- speed = 0;
- SLIC_DISPLAY
- ("%s: slic ETHTOOL set \
- link speed==10MB",
- dev->name);
- } else {
- speed = PCR_SPEED_100;
- SLIC_DISPLAY
- ("%s: slic ETHTOOL set \
- link speed==100MB",
- dev->name);
- }
- if (ecmd.duplex == DUPLEX_FULL) {
- duplex = PCR_DUPLEX_FULL;
- SLIC_DISPLAY
- (": duplex==FULL\n");
- } else {
- duplex = 0;
- SLIC_DISPLAY
- (": duplex==HALF\n");
- }
- slic_link_config(adapter,
- speed, duplex);
- slic_link_event_handler(adapter);
- }
+ speed = PCR_SPEED_100;
+ if (ecmd.duplex == DUPLEX_FULL)
+ duplex = PCR_DUPLEX_FULL;
+ else
+ duplex = 0;
+ slic_link_config(adapter, speed, duplex);
+ slic_link_event_handler(adapter);
}
- return 0;
}
-#endif
+ return 0;
default:
-/* DBG_MSG("slicoss: %s UNSUPPORTED[%x]\n", __func__, cmd); */
return -EOPNOTSUPP;
}
}
@@ -970,11 +789,6 @@ static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
card = adapter->card;
ASSERT(card);
-/*
- DBG_ERROR("xmit_start (%s) ENTER skb[%p] len[%d] linkstate[%x] state[%x]\n",
- adapter->netdev->name, skb, skb->len, adapter->linkstate,
- adapter->state);
-*/
if ((adapter->linkstate != LINK_UP) ||
(adapter->state != ADAPT_UP) || (card->state != CARD_UP)) {
status = XMIT_FAIL_LINK_STATE;
@@ -1015,14 +829,13 @@ static int slic_xmit_start(struct sk_buff *skb, struct net_device *dev)
}
#endif
if (hcmd->paddrh == 0) {
- WRITE_REG(adapter->slic_regs->slic_cbar,
- (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_cbar,
+ (hcmd->paddrl | hcmd->cmdsize), DONT_FLUSH);
} else {
- WRITE_REG64(adapter,
- adapter->slic_regs->slic_cbar64,
- (hcmd->paddrl | hcmd->cmdsize),
- adapter->slic_regs->slic_addr_upper,
- hcmd->paddrh, DONT_FLUSH);
+ slic_reg64_write(adapter, &adapter->slic_regs->slic_cbar64,
+ (hcmd->paddrl | hcmd->cmdsize),
+ &adapter->slic_regs->slic_addr_upper,
+ hcmd->paddrh, DONT_FLUSH);
}
xmit_done:
return 0;
@@ -1036,29 +849,29 @@ static void slic_xmit_fail(struct adapter *adapter,
void *cmd, u32 skbtype, u32 status)
{
if (adapter->xmitq_full)
- slic_if_stop_queue(adapter);
+ netif_stop_queue(adapter->netdev);
if ((cmd == NULL) && (status <= XMIT_FAIL_HOSTCMD_FAIL)) {
switch (status) {
case XMIT_FAIL_LINK_STATE:
- DBG_ERROR
- ("(%s) reject xmit skb[%p: %x] linkstate[%s] \
- adapter[%s:%d] card[%s:%d]\n",
- adapter->netdev->name, skb, skb->pkt_type,
- SLIC_LINKSTATE(adapter->linkstate),
- SLIC_ADAPTER_STATE(adapter->state), adapter->state,
- SLIC_CARD_STATE(adapter->card->state),
- adapter->card->state);
+ dev_err(&adapter->netdev->dev,
+ "reject xmit skb[%p: %x] linkstate[%s] "
+ "adapter[%s:%d] card[%s:%d]\n",
+ skb, skb->pkt_type,
+ SLIC_LINKSTATE(adapter->linkstate),
+ SLIC_ADAPTER_STATE(adapter->state),
+ adapter->state,
+ SLIC_CARD_STATE(adapter->card->state),
+ adapter->card->state);
break;
case XMIT_FAIL_ZERO_LENGTH:
- DBG_ERROR
- ("xmit_start skb->len == 0 skb[%p] type[%x]!!!! \n",
- skb, skb->pkt_type);
+ dev_err(&adapter->netdev->dev,
+ "xmit_start skb->len == 0 skb[%p] type[%x]\n",
+ skb, skb->pkt_type);
break;
case XMIT_FAIL_HOSTCMD_FAIL:
- DBG_ERROR
- ("xmit_start skb[%p] type[%x] No host commands \
- available !!!! \n",
- skb, skb->pkt_type);
+ dev_err(&adapter->netdev->dev,
+ "xmit_start skb[%p] type[%x] No host commands "
+ "available\n", skb, skb->pkt_type);
break;
default:
ASSERT(0);
@@ -1183,11 +996,6 @@ static void slic_rcv_handler(struct adapter *adapter)
if (!slic_mac_filter(adapter, (struct ether_header *)
rcvbuf->data)) {
-#if 0
- DBG_MSG
- ("slicoss: %s (%s) drop frame due to mac filter\n",
- __func__, adapter->netdev->name);
-#endif
slic_rcvqueue_reinsert(adapter, skb);
continue;
}
@@ -1242,12 +1050,6 @@ static void slic_xmit_complete(struct adapter *adapter)
ASSERT(hcmd);
ASSERT(hcmd->pslic_handle ==
&adapter->slic_handles[slic_handle_word.handle_index]);
-/*
- DBG_ERROR("xmit_complete (%s) hcmd[%p] hosthandle[%x]\n",
- adapter->netdev->name, hcmd, hcmd->cmd64.hosthandle);
- DBG_ERROR(" skb[%p] len %d hcmdtype[%x]\n", hcmd->skb,
- hcmd->skb->len, hcmd->type);
-*/
if (hcmd->type == SLIC_CMD_DUMB) {
if (hcmd->skb)
dev_kfree_skb_irq(hcmd->skb);
@@ -1267,7 +1069,8 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
u32 isr;
if ((adapter->pshmem) && (adapter->pshmem->isr)) {
- WRITE_REG(adapter->slic_regs->slic_icr, ICR_INT_MASK, FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_icr,
+ ICR_INT_MASK, FLUSH);
isr = adapter->isrcopy = adapter->pshmem->isr;
adapter->pshmem->isr = 0;
adapter->num_isrs++;
@@ -1299,29 +1102,18 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
if (!count)
break;
}
- DBG_MSG
- ("(%s): [%x] ISR_RMISS \
- initial[%x] pre[%x] \
- errors[%x] \
- post_count[%x]\n",
- adapter->netdev->name,
- isr, rcv_count, pre_count,
- errors, rcvq->count);
} else if (isr & ISR_XDROP) {
- DBG_ERROR
- ("isr & ISR_ERR [%x] \
- ISR_XDROP \n",
- isr);
+ dev_err(&dev->dev,
+ "isr & ISR_ERR [%x] "
+ "ISR_XDROP \n", isr);
} else {
- DBG_ERROR
- ("isr & ISR_ERR [%x]\n",
- isr);
+ dev_err(&dev->dev,
+ "isr & ISR_ERR [%x]\n",
+ isr);
}
}
if (isr & ISR_LEVENT) {
- /*DBG_MSG("%s (%s) ISR_LEVENT \n",
- __func__, adapter->netdev->name);*/
adapter->linkevent_interrupts++;
slic_link_event_handler(adapter);
}
@@ -1359,7 +1151,7 @@ static irqreturn_t slic_interrupt(int irq, void *dev_id)
adapter->isrcopy = 0;
adapter->all_reg_writes += 2;
adapter->isr_reg_writes++;
- WRITE_REG(adapter->slic_regs->slic_isr, 0, FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_isr, 0, FLUSH);
} else {
adapter->false_interrupts++;
}
@@ -1389,11 +1181,6 @@ static void slic_link_event_handler(struct adapter *adapter)
pshmem = (struct slic_shmem *)adapter->phys_shmem;
#if defined(CONFIG_X86_64)
-/*
- DBG_MSG("slic_event_handler pshmem->linkstatus[%x] pshmem[%p]\n \
- &linkstatus[%p] &isr[%p]\n", adapter->pshmem->linkstatus, pshmem,
- &pshmem->linkstatus, &pshmem->isr);
-*/
status = slic_upr_request(adapter,
SLIC_UPR_RLSR,
SLIC_GET_ADDR_LOW(&pshmem->linkstatus),
@@ -1411,46 +1198,29 @@ static void slic_link_event_handler(struct adapter *adapter)
static void slic_init_cleanup(struct adapter *adapter)
{
- DBG_MSG("slicoss: %s ENTER adapter[%p] ", __func__, adapter);
if (adapter->intrregistered) {
- DBG_MSG("FREE_IRQ ");
adapter->intrregistered = 0;
free_irq(adapter->netdev->irq, adapter->netdev);
}
if (adapter->pshmem) {
- DBG_MSG("FREE_SHMEM ");
- DBG_MSG("adapter[%p] port %d pshmem[%p] FreeShmem ",
- adapter, adapter->port, (void *) adapter->pshmem);
pci_free_consistent(adapter->pcidev,
sizeof(struct slic_shmem),
adapter->pshmem, adapter->phys_shmem);
adapter->pshmem = NULL;
adapter->phys_shmem = (dma_addr_t) NULL;
}
-#if SLIC_GET_STATS_TIMER_ENABLED
- if (adapter->statstimerset) {
- DBG_MSG("statstimer ");
- adapter->statstimerset = 0;
- del_timer(&adapter->statstimer);
- }
-#endif
-#if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
-/*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
+
if (adapter->pingtimerset) {
- DBG_MSG("pingtimer ");
adapter->pingtimerset = 0;
del_timer(&adapter->pingtimer);
}
-#endif
+
slic_rspqueue_free(adapter);
slic_cmdq_free(adapter);
slic_rcvqueue_free(adapter);
-
- DBG_MSG("\n");
}
-#if SLIC_GET_STATS_ENABLED
static struct net_device_stats *slic_get_stats(struct net_device *dev)
{
struct adapter *adapter = (struct adapter *)netdev_priv(dev);
@@ -1470,7 +1240,6 @@ static struct net_device_stats *slic_get_stats(struct net_device *dev)
stats->rx_length_errors = 0;
return &adapter->stats;
}
-#endif
/*
* Allocate a mcast_address structure to hold the multicast address.
@@ -1491,7 +1260,7 @@ static int slic_mcast_add_list(struct adapter *adapter, char *address)
}
/* Doesn't already exist. Allocate a structure to hold it */
- mcaddr = kmalloc(sizeof(struct mcast_address), GFP_ATOMIC);
+ mcaddr = kmalloc(sizeof(struct mcast_address), GFP_KERNEL);
if (mcaddr == NULL)
return 1;
@@ -1608,8 +1377,6 @@ static void slic_mcast_set_list(struct net_device *dev)
mc_list = mc_list->next;
}
- DBG_MSG("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
- __func__, adapter->devflags_prev, dev->flags, status);
if (adapter->devflags_prev != dev->flags) {
adapter->macopts = MAC_DIRECTED;
if (dev->flags) {
@@ -1623,9 +1390,7 @@ static void slic_mcast_set_list(struct net_device *dev)
adapter->macopts |= MAC_MCAST;
}
adapter->devflags_prev = dev->flags;
- DBG_MSG("%s call slic_config_set adapter->macopts[%x]\n",
- __func__, adapter->macopts);
- slic_config_set(adapter, TRUE);
+ slic_config_set(adapter, true);
} else {
if (status == STATUS_SUCCESS)
slic_mcast_set_mask(adapter);
@@ -1637,36 +1402,23 @@ static void slic_mcast_set_mask(struct adapter *adapter)
{
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
- DBG_MSG("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
- adapter->netdev->name, (uint) adapter->macopts,
- adapter->mcastmask);
-
if (adapter->macopts & (MAC_ALLMCAST | MAC_PROMISC)) {
/* Turn on all multicast addresses. We have to do this for
* promiscuous mode as well as ALLMCAST mode. It saves the
* Microcode from having to keep state about the MAC
* configuration.
*/
-/* DBG_MSG("slicoss: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n\
- SLUT MODE!!!\n",__func__); */
- WRITE_REG(slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
- WRITE_REG(slic_regs->slic_mcasthigh, 0xFFFFFFFF, FLUSH);
-/* DBG_MSG("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",
- _func__, adapter->netdev->name); */
+ slic_reg32_write(&slic_regs->slic_mcastlow, 0xFFFFFFFF, FLUSH);
+ slic_reg32_write(&slic_regs->slic_mcasthigh, 0xFFFFFFFF,
+ FLUSH);
} else {
/* Commit our multicast mast to the SLIC by writing to the
* multicast address mask registers
*/
- DBG_MSG("%s (%s) WRITE mcastlow[%x] mcasthigh[%x]\n",
- __func__, adapter->netdev->name,
- ((ulong) (adapter->mcastmask & 0xFFFFFFFF)),
- ((ulong) ((adapter->mcastmask >> 32) & 0xFFFFFFFF)));
-
- WRITE_REG(slic_regs->slic_mcastlow,
- (u32) (adapter->mcastmask & 0xFFFFFFFF), FLUSH);
- WRITE_REG(slic_regs->slic_mcasthigh,
- (u32) ((adapter->mcastmask >> 32) & 0xFFFFFFFF),
- FLUSH);
+ slic_reg32_write(&slic_regs->slic_mcastlow,
+ (u32)(adapter->mcastmask & 0xFFFFFFFF), FLUSH);
+ slic_reg32_write(&slic_regs->slic_mcasthigh,
+ (u32)((adapter->mcastmask >> 32) & 0xFFFFFFFF), FLUSH);
}
}
@@ -1680,53 +1432,11 @@ static void slic_timer_ping(ulong dev)
ASSERT(adapter);
card = adapter->card;
ASSERT(card);
-#if !SLIC_DUMP_ENABLED
-/*#if SLIC_DUMP_ENABLED*/
- if ((adapter->state == ADAPT_UP) && (card->state == CARD_UP)) {
- int status;
-
- if (card->pingstatus != ISR_PINGMASK) {
- if (errormsg++ < 5) {
- DBG_MSG
- ("%s (%s) CARD HAS CRASHED PING_status == \
- %x ERRORMSG# %d\n",
- __func__, adapter->netdev->name,
- card->pingstatus, errormsg);
- }
- /* ASSERT(card->pingstatus == ISR_PINGMASK); */
- } else {
- if (goodmsg++ < 5) {
- DBG_MSG
- ("slicoss: %s (%s) PING_status == %x \
- GOOD!!!!!!!! msg# %d\n",
- __func__, adapter->netdev->name,
- card->pingstatus, errormsg);
- }
- }
- card->pingstatus = 0;
- status = slic_upr_request(adapter, SLIC_UPR_PING, 0, 0, 0, 0);
- ASSERT(status == 0);
- } else {
- DBG_MSG("slicoss %s (%s) adapter[%p] NOT UP!!!!\n",
- __func__, adapter->netdev->name, adapter);
- }
-#endif
- adapter->pingtimer.expires =
- jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
+ adapter->pingtimer.expires = jiffies + (PING_TIMER_INTERVAL * HZ);
add_timer(&adapter->pingtimer);
}
-static void slic_if_stop_queue(struct adapter *adapter)
-{
- netif_stop_queue(adapter->netdev);
-}
-
-static void slic_if_start_queue(struct adapter *adapter)
-{
- netif_start_queue(adapter->netdev);
-}
-
/*
* slic_if_init
*
@@ -1742,14 +1452,11 @@ static int slic_if_init(struct adapter *adapter)
int status = 0;
ASSERT(card);
- DBG_MSG("slicoss: %s (%s) ENTER states[%d:%d:%d:%d] flags[%x]\n",
- __func__, adapter->netdev->name,
- adapter->queues_initialized, adapter->state, adapter->linkstate,
- card->state, dev->flags);
/* adapter should be down at this point */
if (adapter->state != ADAPT_DOWN) {
- DBG_ERROR("slic_if_init adapter->state != ADAPT_DOWN\n");
+ dev_err(&dev->dev, "%s: adapter->state != ADAPT_DOWN\n",
+ __func__);
return -EIO;
}
ASSERT(adapter->linkstate == LINK_DOWN);
@@ -1757,54 +1464,35 @@ static int slic_if_init(struct adapter *adapter)
adapter->devflags_prev = dev->flags;
adapter->macopts = MAC_DIRECTED;
if (dev->flags) {
- DBG_MSG("slicoss: %s (%s) Set MAC options: ", __func__,
- adapter->netdev->name);
- if (dev->flags & IFF_BROADCAST) {
+ if (dev->flags & IFF_BROADCAST)
adapter->macopts |= MAC_BCAST;
- DBG_MSG("BCAST ");
- }
- if (dev->flags & IFF_PROMISC) {
+ if (dev->flags & IFF_PROMISC)
adapter->macopts |= MAC_PROMISC;
- DBG_MSG("PROMISC ");
- }
- if (dev->flags & IFF_ALLMULTI) {
+ if (dev->flags & IFF_ALLMULTI)
adapter->macopts |= MAC_ALLMCAST;
- DBG_MSG("ALL_MCAST ");
- }
- if (dev->flags & IFF_MULTICAST) {
+ if (dev->flags & IFF_MULTICAST)
adapter->macopts |= MAC_MCAST;
- DBG_MSG("MCAST ");
- }
- DBG_MSG("\n");
}
status = slic_adapter_allocresources(adapter);
if (status != STATUS_SUCCESS) {
- DBG_ERROR
- ("slic_if_init: slic_adapter_allocresources FAILED %x\n",
- status);
+ dev_err(&dev->dev,
+ "%s: slic_adapter_allocresources FAILED %x\n",
+ __func__, status);
slic_adapter_freeresources(adapter);
return status;
}
if (!adapter->queues_initialized) {
- DBG_MSG("slicoss: %s call slic_rspqueue_init\n", __func__);
if (slic_rspqueue_init(adapter))
return -ENOMEM;
- DBG_MSG
- ("slicoss: %s call slic_cmdq_init adapter[%p] port %d \n",
- __func__, adapter, adapter->port);
if (slic_cmdq_init(adapter))
return -ENOMEM;
- DBG_MSG
- ("slicoss: %s call slic_rcvqueue_init adapter[%p] \
- port %d \n", __func__, adapter, adapter->port);
if (slic_rcvqueue_init(adapter))
return -ENOMEM;
adapter->queues_initialized = 1;
}
- DBG_MSG("slicoss: %s disable interrupts(slic)\n", __func__);
- WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
mdelay(1);
if (!adapter->isp_initialized) {
@@ -1814,13 +1502,13 @@ static int slic_if_init(struct adapter *adapter)
adapter->bit64reglock.flags);
#if defined(CONFIG_X86_64)
- WRITE_REG(slic_regs->slic_addr_upper,
- SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
- WRITE_REG(slic_regs->slic_isp,
- SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+ slic_reg32_write(&slic_regs->slic_addr_upper,
+ SLIC_GET_ADDR_HIGH(&pshmem->isr), DONT_FLUSH);
+ slic_reg32_write(&slic_regs->slic_isp,
+ SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
#elif defined(CONFIG_X86)
- WRITE_REG(slic_regs->slic_addr_upper, (u32) 0, DONT_FLUSH);
- WRITE_REG(slic_regs->slic_isp, (u32) &pshmem->isr, FLUSH);
+ slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ slic_reg32_write(&slic_regs->slic_isp, (u32)&pshmem->isr, FLUSH);
#else
Stop Compilations
#endif
@@ -1833,66 +1521,44 @@ static int slic_if_init(struct adapter *adapter)
if (!card->loadtimerset) {
init_timer(&card->loadtimer);
card->loadtimer.expires =
- jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+ jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
card->loadtimer.data = (ulong) card;
card->loadtimer.function = &slic_timer_load_check;
add_timer(&card->loadtimer);
card->loadtimerset = 1;
}
-#if SLIC_GET_STATS_TIMER_ENABLED
- if (!adapter->statstimerset) {
- DBG_MSG("slicoss: %s start getstats_timer(slic)\n",
- __func__);
- init_timer(&adapter->statstimer);
- adapter->statstimer.expires =
- jiffies + SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
- adapter->statstimer.data = (ulong) adapter->netdev;
- adapter->statstimer.function = &slic_timer_get_stats;
- add_timer(&adapter->statstimer);
- adapter->statstimerset = 1;
- }
-#endif
-#if !SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED
-/*#if SLIC_DUMP_ENABLED && SLIC_PING_TIMER_ENABLED*/
+
if (!adapter->pingtimerset) {
- DBG_MSG("slicoss: %s start card_ping_timer(slic)\n",
- __func__);
init_timer(&adapter->pingtimer);
adapter->pingtimer.expires =
- jiffies + SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
+ jiffies + (PING_TIMER_INTERVAL * HZ);
adapter->pingtimer.data = (ulong) dev;
adapter->pingtimer.function = &slic_timer_ping;
add_timer(&adapter->pingtimer);
adapter->pingtimerset = 1;
adapter->card->pingstatus = ISR_PINGMASK;
}
-#endif
/*
* clear any pending events, then enable interrupts
*/
- DBG_MSG("slicoss: %s ENABLE interrupts(slic)\n", __func__);
adapter->isrcopy = 0;
adapter->pshmem->isr = 0;
- WRITE_REG(slic_regs->slic_isr, 0, FLUSH);
- WRITE_REG(slic_regs->slic_icr, ICR_INT_ON, FLUSH);
+ slic_reg32_write(&slic_regs->slic_isr, 0, FLUSH);
+ slic_reg32_write(&slic_regs->slic_icr, ICR_INT_ON, FLUSH);
- DBG_MSG("slicoss: %s call slic_link_config(slic)\n", __func__);
slic_link_config(adapter, LINK_AUTOSPEED, LINK_AUTOD);
slic_link_event_handler(adapter);
- DBG_MSG("slicoss: %s EXIT\n", __func__);
return STATUS_SUCCESS;
}
static void slic_unmap_mmio_space(struct adapter *adapter)
{
-#if LINUX_FREES_ADAPTER_RESOURCES
if (adapter->slic_regs)
iounmap(adapter->slic_regs);
adapter->slic_regs = NULL;
-#endif
}
static int slic_adapter_allocresources(struct adapter *adapter)
@@ -1900,13 +1566,6 @@ static int slic_adapter_allocresources(struct adapter *adapter)
if (!adapter->intrregistered) {
int retval;
- DBG_MSG
- ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
- phys_shmem[%p] dev->irq[%x] %x\n",
- __func__, adapter, adapter->pshmem,
- (void *)adapter->phys_shmem, adapter->netdev->irq,
- NR_IRQS);
-
spin_unlock_irqrestore(&slic_global.driver_lock.lock,
slic_global.driver_lock.flags);
@@ -1919,16 +1578,12 @@ static int slic_adapter_allocresources(struct adapter *adapter)
slic_global.driver_lock.flags);
if (retval) {
- DBG_ERROR("slicoss: request_irq (%s) FAILED [%x]\n",
- adapter->netdev->name, retval);
+ dev_err(&adapter->netdev->dev,
+ "request_irq (%s) FAILED [%x]\n",
+ adapter->netdev->name, retval);
return retval;
}
adapter->intrregistered = 1;
- DBG_MSG
- ("slicoss: %s AllocAdaptRsrcs adapter[%p] shmem[%p] \
- pshmem[%p] dev->irq[%x]\n",
- __func__, adapter, adapter->pshmem,
- (void *)adapter->pshmem, adapter->netdev->irq);
}
return STATUS_SUCCESS;
}
@@ -1939,22 +1594,17 @@ static void slic_config_pci(struct pci_dev *pcidev)
u16 new_command;
pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
- DBG_MSG("slicoss: %s PCI command[%4.4x]\n", __func__, pci_command);
new_command = pci_command | PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
| PCI_COMMAND_INVALIDATE
| PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK;
- if (pci_command != new_command) {
- DBG_MSG("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
- __func__, pci_command, new_command);
+ if (pci_command != new_command)
pci_write_config_word(pcidev, PCI_COMMAND, new_command);
- }
}
static void slic_adapter_freeresources(struct adapter *adapter)
{
- DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
slic_init_cleanup(adapter);
memset(&adapter->stats, 0, sizeof(struct net_device_stats));
adapter->error_interrupts = 0;
@@ -1967,7 +1617,6 @@ static void slic_adapter_freeresources(struct adapter *adapter)
adapter->rcv_broadcasts = 0;
adapter->rcv_multicasts = 0;
adapter->rcv_unicasts = 0;
- DBG_MSG("slicoss: %s EXIT\n", __func__);
}
/*
@@ -1979,21 +1628,15 @@ static void slic_adapter_freeresources(struct adapter *adapter)
static void slic_link_config(struct adapter *adapter,
u32 linkspeed, u32 linkduplex)
{
+ u32 __iomem *wphy;
u32 speed;
u32 duplex;
u32 phy_config;
u32 phy_advreg;
u32 phy_gctlreg;
- if (adapter->state != ADAPT_UP) {
- DBG_MSG
- ("%s (%s) ADAPT Not up yet, Return! speed[%x] duplex[%x]\n",
- __func__, adapter->netdev->name, linkspeed,
- linkduplex);
+ if (adapter->state != ADAPT_UP)
return;
- }
- DBG_MSG("slicoss: %s (%s) slic_link_config: speed[%x] duplex[%x]\n",
- __func__, adapter->netdev->name, linkspeed, linkduplex);
ASSERT((adapter->devid == SLIC_1GB_DEVICE_ID)
|| (adapter->devid == SLIC_2GB_DEVICE_ID));
@@ -2003,6 +1646,8 @@ static void slic_link_config(struct adapter *adapter,
if (linkduplex > LINK_AUTOD)
linkduplex = LINK_AUTOD;
+ wphy = &adapter->slic_regs->slic_wphy;
+
if ((linkspeed == LINK_AUTOSPEED) || (linkspeed == LINK_1000MB)) {
if (adapter->flags & ADAPT_FLAGS_FIBERMEDIA) {
/* We've got a fiber gigabit interface, and register
@@ -2013,8 +1658,7 @@ static void slic_link_config(struct adapter *adapter,
phy_advreg = (MIICR_REG_4 | (PAR_ADV1000XFD));
/* enable PAUSE frames */
phy_advreg |= PAR_ASYMPAUSE_FIBER;
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
- FLUSH);
+ slic_reg32_write(wphy, phy_advreg, FLUSH);
if (linkspeed == LINK_AUTOSPEED) {
/* reset phy, enable auto-neg */
@@ -2022,14 +1666,12 @@ static void slic_link_config(struct adapter *adapter,
(MIICR_REG_PCR |
(PCR_RESET | PCR_AUTONEG |
PCR_AUTONEG_RST));
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
} else { /* forced 1000 Mb FD*/
/* power down phy to break link
this may not work) */
phy_config = (MIICR_REG_PCR | PCR_POWERDOWN);
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
/* wait, Marvell says 1 sec,
try to get away with 10 ms */
mdelay(10);
@@ -2040,8 +1682,7 @@ static void slic_link_config(struct adapter *adapter,
(MIICR_REG_PCR |
(PCR_RESET | PCR_SPEED_1000 |
PCR_DUPLEX_FULL));
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
}
} else { /* copper gigabit */
@@ -2065,35 +1706,30 @@ static void slic_link_config(struct adapter *adapter,
phy_advreg |= PAR_ASYMPAUSE;
/* required by the Cicada PHY */
phy_advreg |= PAR_802_3;
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_advreg,
- FLUSH);
+ slic_reg32_write(wphy, phy_advreg, FLUSH);
/* advertise FD only @1000 Mb */
phy_gctlreg = (MIICR_REG_9 | (PGC_ADV1000FD));
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_gctlreg,
- FLUSH);
+ slic_reg32_write(wphy, phy_gctlreg, FLUSH);
if (adapter->subsysid != SLIC_1GB_CICADA_SUBSYS_ID) {
/* if a Marvell PHY
enable auto crossover */
phy_config =
(MIICR_REG_16 | (MRV_REG16_XOVERON));
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
/* reset phy, enable auto-neg */
phy_config =
(MIICR_REG_PCR |
(PCR_RESET | PCR_AUTONEG |
PCR_AUTONEG_RST));
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
} else { /* it's a Cicada PHY */
/* enable and restart auto-neg (don't reset) */
phy_config =
(MIICR_REG_PCR |
(PCR_AUTONEG | PCR_AUTONEG_RST));
- WRITE_REG(adapter->slic_regs->slic_wphy,
- phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
}
}
} else {
@@ -2111,13 +1747,12 @@ static void slic_link_config(struct adapter *adapter,
/* if a Marvell PHY
disable auto crossover */
phy_config = (MIICR_REG_16 | (MRV_REG16_XOVEROFF));
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
- FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
}
/* power down phy to break link (this may not work) */
phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN | speed | duplex));
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_config, FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
/* wait, Marvell says 1 sec, try to get away with 10 ms */
mdelay(10);
@@ -2128,43 +1763,17 @@ static void slic_link_config(struct adapter *adapter,
soft reset phy, powerup */
phy_config =
(MIICR_REG_PCR | (PCR_RESET | speed | duplex));
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
- FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
} else { /* it's a Cicada PHY */
/* disable auto-neg, set speed, powerup */
phy_config = (MIICR_REG_PCR | (speed | duplex));
- WRITE_REG(adapter->slic_regs->slic_wphy, phy_config,
- FLUSH);
+ slic_reg32_write(wphy, phy_config, FLUSH);
}
}
-
- DBG_MSG
- ("slicoss: %s (%s) EXIT slic_link_config : state[%d] \
- phy_config[%x]\n", __func__, adapter->netdev->name, adapter->state,
- phy_config);
}
static void slic_card_cleanup(struct sliccard *card)
{
- DBG_MSG("slicoss: %s ENTER\n", __func__);
-
-#if SLIC_DUMP_ENABLED
- if (card->dumpbuffer) {
- card->dumpbuffer_phys = 0;
- card->dumpbuffer_physl = 0;
- card->dumpbuffer_physh = 0;
- kfree(card->dumpbuffer);
- card->dumpbuffer = NULL;
- }
- if (card->cmdbuffer) {
- card->cmdbuffer_phys = 0;
- card->cmdbuffer_physl = 0;
- card->cmdbuffer_physh = 0;
- kfree(card->cmdbuffer);
- card->cmdbuffer = NULL;
- }
-#endif
-
if (card->loadtimerset) {
card->loadtimerset = 0;
del_timer(&card->loadtimer);
@@ -2173,7 +1782,6 @@ static void slic_card_cleanup(struct sliccard *card)
slic_debug_card_destroy(card);
kfree(card);
- DBG_MSG("slicoss: %s EXIT\n", __func__);
}
static int slic_card_download_gbrcv(struct adapter *adapter)
@@ -2183,15 +1791,16 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
int ret;
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
u32 codeaddr;
- unsigned char *instruction = NULL;
+ u32 instruction;
+ int index = 0;
u32 rcvucodelen = 0;
switch (adapter->devid) {
case SLIC_2GB_DEVICE_ID:
- file = "oasis_rcv.bin";
+ file = "slicoss/oasisrcvucode.sys";
break;
case SLIC_1GB_DEVICE_ID:
- file = "gb_rcv.bin";
+ file = "slicoss/gbrcvucode.sys";
break;
default:
ASSERT(0);
@@ -2200,12 +1809,13 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
ret = request_firmware(&fw, file, &adapter->pcidev->dev);
if (ret) {
- printk(KERN_ERR "SLICOSS: Failed to load firmware %s\n", file);
+ dev_err(&adapter->pcidev->dev,
+ "SLICOSS: Failed to load firmware %s\n", file);
return ret;
}
- instruction = (unsigned char *)fw->data;
- rcvucodelen = fw->size;
+ rcvucodelen = *(u32 *)(fw->data + index);
+ index += 4;
switch (adapter->devid) {
case SLIC_2GB_DEVICE_ID:
if (rcvucodelen != OasisRcvUCodeLen)
@@ -2219,29 +1829,28 @@ static int slic_card_download_gbrcv(struct adapter *adapter)
ASSERT(0);
break;
}
-
/* start download */
- WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
-
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_BEGIN, FLUSH);
/* download the rcv sequencer ucode */
for (codeaddr = 0; codeaddr < rcvucodelen; codeaddr++) {
/* write out instruction address */
- WRITE_REG(slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, codeaddr, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
/* write out the instruction data low addr */
- WRITE_REG(slic_regs->slic_rcv_wcs,
- (u32) *(u32 *) instruction, FLUSH);
- instruction += 4;
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, instruction, FLUSH);
+ instruction = *(u8 *)(fw->data + index);
+ index++;
/* write out the instruction data high addr */
- WRITE_REG(slic_regs->slic_rcv_wcs, (u32) *instruction,
- FLUSH);
- instruction += 1;
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, (u8)instruction,
+ FLUSH);
}
/* download finished */
release_firmware(fw);
- WRITE_REG(slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
+ slic_reg32_write(&slic_regs->slic_rcv_wcs, SLIC_RCVWCS_FINISH, FLUSH);
return 0;
}
@@ -2254,41 +1863,21 @@ static int slic_card_download(struct adapter *adapter)
int thissectionsize;
int codeaddr;
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
- u32 *instruction = NULL;
- u32 *lastinstruct = NULL;
- u32 *startinstruct = NULL;
- unsigned char *nextinstruct;
+ u32 instruction;
u32 baseaddress;
u32 failure;
u32 i;
u32 numsects = 0;
u32 sectsize[3];
u32 sectstart[3];
-
-/* DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x] \
- jiffies[%lx] cpu %d\n", __func__, adapter->netdev->name, adapter,
- adapter->card, adapter->devid,jiffies, smp_processor_id()); */
+ int ucode_start, index = 0;
switch (adapter->devid) {
case SLIC_2GB_DEVICE_ID:
-/* DBG_MSG ("slicoss: %s devid==SLIC_2GB_DEVICE_ID sections[%x]\n",
- __func__, (uint) ONumSections); */
- file = "slic_oasis.bin";
- numsects = ONumSections;
- for (i = 0; i < numsects; i++) {
- sectsize[i] = OSectionSize[i];
- sectstart[i] = OSectionStart[i];
- }
+ file = "slicoss/oasisdownload.sys";
break;
case SLIC_1GB_DEVICE_ID:
-/* DBG_MSG ("slicoss: %s devid==SLIC_1GB_DEVICE_ID sections[%x]\n",
- __func__, (uint) MNumSections); */
- file = "slic_mojave.bin";
- numsects = MNumSections;
- for (i = 0; i < numsects; i++) {
- sectsize[i] = MSectionSize[i];
- sectstart[i] = MSectionStart[i];
- }
+ file = "slicoss/gbdownload.sys";
break;
default:
ASSERT(0);
@@ -2296,131 +1885,84 @@ static int slic_card_download(struct adapter *adapter)
}
ret = request_firmware(&fw, file, &adapter->pcidev->dev);
if (ret) {
- printk(KERN_ERR "SLICOSS: Failed to load firmware %s\n", file);
+ dev_err(&adapter->pcidev->dev,
+ "SLICOSS: Failed to load firmware %s\n", file);
return ret;
}
-
+ numsects = *(u32 *)(fw->data + index);
+ index += 4;
ASSERT(numsects <= 3);
-
+ for (i = 0; i < numsects; i++) {
+ sectsize[i] = *(u32 *)(fw->data + index);
+ index += 4;
+ }
+ for (i = 0; i < numsects; i++) {
+ sectstart[i] = *(u32 *)(fw->data + index);
+ index += 4;
+ }
+ ucode_start = index;
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
for (section = 0; section < numsects; section++) {
- switch (adapter->devid) {
- case SLIC_2GB_DEVICE_ID:
- instruction = (u32 *)(fw->data + (SECTION_SIZE *
- section));
- baseaddress = sectstart[section];
- thissectionsize = sectsize[section] >> 3;
- lastinstruct =
- (u32 *)(fw->data + (SECTION_SIZE * section) +
- sectsize[section] - 8);
- break;
- case SLIC_1GB_DEVICE_ID:
- instruction = (u32 *)(fw->data + (SECTION_SIZE *
- section));
- baseaddress = sectstart[section];
- thissectionsize = sectsize[section] >> 3;
- lastinstruct =
- (u32 *)(fw->data + (SECTION_SIZE * section) +
- sectsize[section] - 8);
- break;
- default:
- ASSERT(0);
- break;
- }
-
baseaddress = sectstart[section];
thissectionsize = sectsize[section] >> 3;
for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
- startinstruct = instruction;
- nextinstruct = ((unsigned char *)instruction) + 8;
/* Write out instruction address */
- WRITE_REG(slic_regs->slic_wcs, baseaddress + codeaddr,
- FLUSH);
+ slic_reg32_write(&slic_regs->slic_wcs,
+ baseaddress + codeaddr, FLUSH);
/* Write out instruction to low addr */
- WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
- instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
- instruction++;
-#endif
+ slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
+
/* Write out instruction to high addr */
- WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
- instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
- instruction++;
-#endif
+ slic_reg32_write(&slic_regs->slic_wcs, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
}
}
-
+ index = ucode_start;
for (section = 0; section < numsects; section++) {
- switch (adapter->devid) {
- case SLIC_2GB_DEVICE_ID:
- instruction = (u32 *)fw->data + (SECTION_SIZE *
- section);
- break;
- case SLIC_1GB_DEVICE_ID:
- instruction = (u32 *)fw->data + (SECTION_SIZE *
- section);
- break;
- default:
- ASSERT(0);
- break;
- }
-
+ instruction = *(u32 *)(fw->data + index);
baseaddress = sectstart[section];
if (baseaddress < 0x8000)
continue;
thissectionsize = sectsize[section] >> 3;
-/* DBG_MSG ("slicoss: COMPARE secton[%x] baseaddr[%x] sectnsize[%x]\n",
- (uint)section,baseaddress,thissectionsize);*/
-
for (codeaddr = 0; codeaddr < thissectionsize; codeaddr++) {
/* Write out instruction address */
- WRITE_REG(slic_regs->slic_wcs,
- SLIC_WCS_COMPARE | (baseaddress + codeaddr),
- FLUSH);
+ slic_reg32_write(&slic_regs->slic_wcs,
+ SLIC_WCS_COMPARE | (baseaddress + codeaddr),
+ FLUSH);
/* Write out instruction to low addr */
- WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
- instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
- instruction++;
-#endif
+ slic_reg32_write(&slic_regs->slic_wcs, instruction,
+ FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
/* Write out instruction to high addr */
- WRITE_REG(slic_regs->slic_wcs, *instruction, FLUSH);
-#ifdef CONFIG_X86_64
- instruction = (u32 *)((unsigned char *)instruction + 4);
-#else
- instruction++;
-#endif
+ slic_reg32_write(&slic_regs->slic_wcs, instruction,
+ FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
+
/* Check SRAM location zero. If it is non-zero. Abort.*/
- failure = readl((u32 __iomem *)&slic_regs->slic_reset);
+/* failure = readl((u32 __iomem *)&slic_regs->slic_reset);
if (failure) {
- DBG_MSG
- ("slicoss: %s FAILURE EXIT codeaddr[%x] \
- thissectionsize[%x] failure[%x]\n",
- __func__, codeaddr, thissectionsize,
- failure);
release_firmware(fw);
return -EIO;
- }
+ }*/
}
}
-/* DBG_MSG ("slicoss: Compare done\n");*/
release_firmware(fw);
/* Everything OK, kick off the card */
mdelay(10);
- WRITE_REG(slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wcs, SLIC_WCS_START, FLUSH);
/* stall for 20 ms, long enough for ucode to init card
and reach mainloop */
mdelay(20);
- DBG_MSG("slicoss: %s (%s) EXIT adapter[%p] card[%p]\n",
- __func__, adapter->netdev->name, adapter, adapter->card);
-
return STATUS_SUCCESS;
}
@@ -2428,19 +1970,10 @@ static void slic_adapter_set_hwaddr(struct adapter *adapter)
{
struct sliccard *card = adapter->card;
-/* DBG_MSG ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n",
- __func__, card->config_set, adapter->port, adapter->physport,
- adapter->functionnumber);
-
- slic_dbg_macaddrs(adapter); */
-
if ((adapter->card) && (card->config_set)) {
memcpy(adapter->macaddr,
card->config.MacInfo[adapter->functionnumber].macaddrA,
sizeof(struct slic_config_mac));
-/* DBG_MSG ("%s AFTER copying from config.macinfo into currmacaddr\n",
- __func__);
- slic_dbg_macaddrs(adapter);*/
if (!(adapter->currmacaddr[0] || adapter->currmacaddr[1] ||
adapter->currmacaddr[2] || adapter->currmacaddr[3] ||
adapter->currmacaddr[4] || adapter->currmacaddr[5])) {
@@ -2451,15 +1984,11 @@ static void slic_adapter_set_hwaddr(struct adapter *adapter)
6);
}
}
-/* DBG_MSG ("%s EXIT port %d\n", __func__, adapter->port);
- slic_dbg_macaddrs(adapter); */
}
static void slic_intagg_set(struct adapter *adapter, u32 value)
{
- __iomem struct slic_regs *slic_regs = adapter->slic_regs;
-
- WRITE_REG(slic_regs->slic_intagg, value, FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_intagg, value, FLUSH);
adapter->card->loadlevel_current = value;
}
@@ -2485,10 +2014,6 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
struct atk_fru *patkfru;
union oemfru *poemfru;
- DBG_MSG
- ("slicoss: %s ENTER card[%p] adapter[%p] card->state[%x] \
- size[%d]\n", __func__, card, adapter, card->state, card->card_size);
-
/* Reset everything except PCI configuration space */
slic_soft_reset(adapter);
@@ -2496,9 +2021,9 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
status = slic_card_download(adapter);
if (status != STATUS_SUCCESS) {
- DBG_ERROR("SLIC download failed bus %d slot %d\n",
- (uint) adapter->busnumber,
- (uint) adapter->slotnumber);
+ dev_err(&adapter->pcidev->dev,
+ "download failed bus %d slot %d\n",
+ adapter->busnumber, adapter->slotnumber);
return status;
}
@@ -2510,33 +2035,24 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
phys_configl = SLIC_GET_ADDR_LOW(phys_config);
phys_configh = SLIC_GET_ADDR_HIGH(phys_config);
- DBG_MSG("slicoss: %s Eeprom info adapter [%p]\n "
- "size [%x]\n peeprom [%p]\n "
- "phys_config [%p]\n phys_configl[%x]\n "
- "phys_configh[%x]\n",
- __func__, adapter,
- (u32)sizeof(struct slic_eeprom),
- peeprom, (void *) phys_config, phys_configl,
- phys_configh);
if (!peeprom) {
- DBG_ERROR
- ("SLIC eeprom read failed to get memory bus %d \
- slot %d\n",
- (uint) adapter->busnumber,
- (uint) adapter->slotnumber);
+ dev_err(&adapter->pcidev->dev,
+ "eeprom read failed to get memory "
+ "bus %d slot %d\n", adapter->busnumber,
+ adapter->slotnumber);
return -ENOMEM;
} else {
memset(peeprom, 0, sizeof(struct slic_eeprom));
}
- WRITE_REG(slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
+ slic_reg32_write(&slic_regs->slic_icr, ICR_INT_OFF, FLUSH);
mdelay(1);
pshmem = (struct slic_shmem *)adapter->phys_shmem;
spin_lock_irqsave(&adapter->bit64reglock.lock,
adapter->bit64reglock.flags);
- WRITE_REG(slic_regs->slic_addr_upper, 0, DONT_FLUSH);
- WRITE_REG(slic_regs->slic_isp,
- SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
+ slic_reg32_write(&slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ slic_reg32_write(&slic_regs->slic_isp,
+ SLIC_GET_ADDR_LOW(&pshmem->isr), FLUSH);
spin_unlock_irqrestore(&adapter->bit64reglock.lock,
adapter->bit64reglock.flags);
@@ -2544,41 +2060,33 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
for (;;) {
if (adapter->pshmem->isr) {
- DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
- __func__, adapter->pshmem,
- adapter->pshmem->isr);
-
if (adapter->pshmem->isr & ISR_UPC) {
adapter->pshmem->isr = 0;
- WRITE_REG64(adapter,
- slic_regs->slic_isp,
- 0,
- slic_regs->slic_addr_upper,
- 0, FLUSH);
- WRITE_REG(slic_regs->slic_isr, 0,
- FLUSH);
+ slic_reg64_write(adapter,
+ &slic_regs->slic_isp, 0,
+ &slic_regs->slic_addr_upper,
+ 0, FLUSH);
+ slic_reg32_write(&slic_regs->slic_isr,
+ 0, FLUSH);
slic_upr_request_complete(adapter, 0);
break;
} else {
adapter->pshmem->isr = 0;
- WRITE_REG(slic_regs->slic_isr, 0,
- FLUSH);
+ slic_reg32_write(&slic_regs->slic_isr,
+ 0, FLUSH);
}
} else {
mdelay(1);
i++;
if (i > 5000) {
- DBG_ERROR
- ("SLIC: %d config data fetch timed\
- out!\n", adapter->port);
- DBG_MSG("%s shmem[%p] shmem->isr[%x]\n",
- __func__, adapter->pshmem,
- adapter->pshmem->isr);
- WRITE_REG64(adapter,
- slic_regs->slic_isp, 0,
- slic_regs->slic_addr_upper,
- 0, FLUSH);
+ dev_err(&adapter->pcidev->dev,
+ "%d config data fetch timed out!\n",
+ adapter->port);
+ slic_reg64_write(adapter,
+ &slic_regs->slic_isp, 0,
+ &slic_regs->slic_addr_upper,
+ 0, FLUSH);
return -EINVAL;
}
}
@@ -2614,7 +2122,7 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
break;
}
- card->config.EepromValid = FALSE;
+ card->config.EepromValid = false;
/* see if the EEPROM is valid by checking it's checksum */
if ((eecodesize <= MAX_EECODE_SIZE) &&
@@ -2633,7 +2141,7 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
we wouldn't need this shit
*/
if (ee_chksum == calc_chksum)
- card->config.EepromValid = TRUE;
+ card->config.EepromValid = true;
}
/* copy in the DRAM size */
card->config.DramSize = dramsize;
@@ -2643,8 +2151,6 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
memcpy(&card->config.MacInfo[i],
&pmac[i], sizeof(struct slic_config_mac));
}
-/* DBG_MSG ("%s EEPROM Checksum Good? %d MacAddress\n",__func__,
- card->config.EepromValid); */
/* copy the Alacritech FRU information */
card->config.FruFormat = fruformat;
@@ -2654,20 +2160,14 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
pci_free_consistent(adapter->pcidev,
sizeof(struct slic_eeprom),
peeprom, phys_config);
- DBG_MSG
- ("slicoss: %s adapter%d [%p] size[%x] FREE peeprom[%p] \
- phys_config[%p]\n",
- __func__, adapter->port, adapter,
- (u32) sizeof(struct slic_eeprom), peeprom,
- (void *) phys_config);
if ((!card->config.EepromValid) &&
(adapter->reg_params.fail_on_bad_eeprom)) {
- WRITE_REG64(adapter,
- slic_regs->slic_isp,
- 0, slic_regs->slic_addr_upper, 0, FLUSH);
- DBG_ERROR
- ("unsupported CONFIGURATION EEPROM invalid\n");
+ slic_reg64_write(adapter, &slic_regs->slic_isp, 0,
+ &slic_regs->slic_addr_upper,
+ 0, FLUSH);
+ dev_err(&adapter->pcidev->dev,
+ "unsupported CONFIGURATION EEPROM invalid\n");
return -EINVAL;
}
@@ -2675,74 +2175,26 @@ static int slic_card_init(struct sliccard *card, struct adapter *adapter)
}
if (slic_card_download_gbrcv(adapter)) {
- DBG_ERROR("%s unable to download GB receive microcode\n",
- __func__);
+ dev_err(&adapter->pcidev->dev,
+ "unable to download GB receive microcode\n");
return -EINVAL;
}
- if (slic_global.dynamic_intagg) {
- DBG_MSG
- ("Dynamic Interrupt Aggregation[ENABLED]: slic%d \
- SET intagg to %d\n",
- card->cardnum, 0);
+ if (slic_global.dynamic_intagg)
slic_intagg_set(adapter, 0);
- } else {
+ else
slic_intagg_set(adapter, intagg_delay);
- DBG_MSG
- ("Dynamic Interrupt Aggregation[DISABLED]: slic%d \
- SET intagg to %d\n",
- card->cardnum, intagg_delay);
- }
/*
* Initialize ping status to "ok"
*/
card->pingstatus = ISR_PINGMASK;
-#if SLIC_DUMP_ENABLED
- if (!card->dumpbuffer) {
- card->dumpbuffer = kmalloc(DUMP_PAGE_SIZE, GFP_ATOMIC);
-
- ASSERT(card->dumpbuffer);
- if (card->dumpbuffer == NULL)
- return -ENOMEM;
- }
- /*
- * Smear the shared memory structure and then obtain
- * the PHYSICAL address of this structure
- */
- memset(card->dumpbuffer, 0, DUMP_PAGE_SIZE);
- card->dumpbuffer_phys = virt_to_bus(card->dumpbuffer);
- card->dumpbuffer_physh = SLIC_GET_ADDR_HIGH(card->dumpbuffer_phys);
- card->dumpbuffer_physl = SLIC_GET_ADDR_LOW(card->dumpbuffer_phys);
-
- /*
- * Allocate COMMAND BUFFER
- */
- if (!card->cmdbuffer) {
- card->cmdbuffer = kmalloc(sizeof(struct dump_cmd), GFP_ATOMIC);
-
- ASSERT(card->cmdbuffer);
- if (card->cmdbuffer == NULL)
- return -ENOMEM;
- }
- /*
- * Smear the shared memory structure and then obtain
- * the PHYSICAL address of this structure
- */
- memset(card->cmdbuffer, 0, sizeof(struct dump_cmd));
- card->cmdbuffer_phys = virt_to_bus(card->cmdbuffer);
- card->cmdbuffer_physh = SLIC_GET_ADDR_HIGH(card->cmdbuffer_phys);
- card->cmdbuffer_physl = SLIC_GET_ADDR_LOW(card->cmdbuffer_phys);
-#endif
-
/*
* Lastly, mark our card state as up and return success
*/
card->state = CARD_UP;
card->reset_in_progress = 0;
- DBG_MSG("slicoss: %s EXIT card[%p] adapter[%p] card->state[%x]\n",
- __func__, card, adapter, card->state);
return STATUS_SUCCESS;
}
@@ -2756,10 +2208,6 @@ static u32 slic_card_locate(struct adapter *adapter)
uint i;
uint rdhostid_offset = 0;
- DBG_MSG("slicoss: %s adapter[%p] slot[%x] bus[%x] port[%x]\n",
- __func__, adapter, adapter->slotnumber, adapter->busnumber,
- adapter->port);
-
switch (adapter->devid) {
case SLIC_2GB_DEVICE_ID:
rdhostid_offset = SLIC_RDHOSTID_2GB;
@@ -2775,11 +2223,9 @@ static u32 slic_card_locate(struct adapter *adapter)
hostid_reg =
(u16 __iomem *) (((u8 __iomem *) (adapter->slic_regs)) +
rdhostid_offset);
- DBG_MSG("slicoss: %s *hostid_reg[%p] == ", __func__, hostid_reg);
/* read the 16 bit hostid from SRAM */
card_hostid = (ushort) readw(hostid_reg);
- DBG_MSG(" card_hostid[%x]\n", card_hostid);
/* Initialize a new card structure if need be */
if (card_hostid == SLIC_HOSTID_DEFAULT) {
@@ -2789,17 +2235,6 @@ static u32 slic_card_locate(struct adapter *adapter)
card->next = slic_global.slic_card;
slic_global.slic_card = card;
-#if DBG
- if (adapter->devid == SLIC_2GB_DEVICE_ID) {
- DBG_MSG
- ("SLICOSS ==> Initialize 2 Port Gigabit Server \
- and Storage Accelerator\n");
- } else {
- DBG_MSG
- ("SLICOSS ==> Initialize 1 Port Gigabit Server \
- and Storage Accelerator\n");
- }
-#endif
card->busnumber = adapter->busnumber;
card->slotnumber = adapter->slotnumber;
@@ -2812,23 +2247,11 @@ static u32 slic_card_locate(struct adapter *adapter)
}
}
slic_global.num_slic_cards++;
- DBG_MSG("\nCARDNUM == %d Total %d Card[%p]\n\n",
- card->cardnum, slic_global.num_slic_cards, card);
slic_debug_card_create(card);
} else {
- DBG_MSG
- ("slicoss: %s CARD already allocated, find the \
- correct card\n", __func__);
/* Card exists, find the card this adapter belongs to */
while (card) {
- DBG_MSG
- ("slicoss: %s card[%p] slot[%x] bus[%x] \
- adaptport[%p] hostid[%x] cardnum[%x]\n",
- __func__, card, card->slotnumber,
- card->busnumber, card->adapter[adapter->port],
- card_hostid, card->cardnum);
-
if (card->cardnum == card_hostid)
break;
card = card->next;
@@ -2861,14 +2284,9 @@ static u32 slic_card_locate(struct adapter *adapter)
}
if (!physcard) {
/* no structure allocated for this physical card yet */
- physcard = kzalloc(sizeof(struct physcard), GFP_ATOMIC);
+ physcard = kzalloc(sizeof(struct physcard), GFP_KERNEL);
ASSERT(physcard);
- DBG_MSG
- ("\n%s Allocate a PHYSICALcard:\n PHYSICAL_Card[%p]\n\
- LogicalCard [%p]\n adapter [%p]\n",
- __func__, physcard, card, adapter);
-
physcard->next = slic_global.phys_card;
slic_global.phys_card = physcard;
physcard->adapters_allocd = 1;
@@ -2881,8 +2299,6 @@ static u32 slic_card_locate(struct adapter *adapter)
ASSERT(physcard->adapter[adapter->physport] == NULL);
physcard->adapter[adapter->physport] = adapter;
adapter->physcard = physcard;
- DBG_MSG(" PHYSICAL_Port %d Logical_Port %d\n", adapter->physport,
- adapter->port);
return 0;
}
@@ -2890,16 +2306,12 @@ static u32 slic_card_locate(struct adapter *adapter)
static void slic_soft_reset(struct adapter *adapter)
{
if (adapter->card->state == CARD_UP) {
- DBG_MSG("slicoss: %s QUIESCE adapter[%p] card[%p] devid[%x]\n",
- __func__, adapter, adapter->card, adapter->devid);
- WRITE_REG(adapter->slic_regs->slic_quiesce, 0, FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_quiesce, 0, FLUSH);
mdelay(1);
}
-/* DBG_MSG ("slicoss: %s (%s) adapter[%p] card[%p] devid[%x]\n",
- __func__, adapter->netdev->name, adapter, adapter->card,
- adapter->devid); */
- WRITE_REG(adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC, FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_reset, SLIC_RESET_MAGIC,
+ FLUSH);
mdelay(1);
}
@@ -2909,10 +2321,6 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
u32 RcrReset;
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
- DBG_MSG("slicoss: %s (%s) slic_interface_enable[%p](%d)\n",
- __func__, adapter->netdev->name, adapter,
- adapter->cardindex);
-
if (linkchange) {
/* Setup MAC */
slic_mac_config(adapter);
@@ -2928,9 +2336,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
GXCR_XMTEN | /* Enable transmit */
GXCR_PAUSEEN); /* Enable pause */
- DBG_MSG("slicoss: FDX adapt[%p] set xmtcfg to [%x]\n", adapter,
- value);
- WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
/* Setup rcvcfg last */
value = (RcrReset | /* Reset, if linkchange */
@@ -2943,9 +2349,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
value = (GXCR_RESET | /* Always reset */
GXCR_XMTEN); /* Enable transmit */
- DBG_MSG("slicoss: HDX adapt[%p] set xmtcfg to [%x]\n", adapter,
- value);
- WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
/* Setup rcvcfg last */
value = (RcrReset | /* Reset, if linkchange */
@@ -2962,8 +2366,7 @@ static void slic_config_set(struct adapter *adapter, bool linkchange)
if (adapter->macopts & MAC_PROMISC)
value |= GRCR_RCVALL;
- DBG_MSG("slicoss: adapt[%p] set rcvcfg to [%x]\n", adapter, value);
- WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
}
/*
@@ -2979,18 +2382,18 @@ static void slic_config_clear(struct adapter *adapter)
value = (GXCR_RESET | /* Always reset */
GXCR_PAUSEEN); /* Enable pause */
- WRITE_REG(slic_regs->slic_wxcfg, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wxcfg, value, FLUSH);
value = (GRCR_RESET | /* Always reset */
GRCR_CTLEN | /* Enable CTL frames */
GRCR_ADDRAEN | /* Address A enable */
(GRCR_HASHSIZE << GRCR_HASHSIZE_SHIFT));
- WRITE_REG(slic_regs->slic_wrcfg, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wrcfg, value, FLUSH);
/* power down phy */
phy_config = (MIICR_REG_PCR | (PCR_POWERDOWN));
- WRITE_REG(slic_regs->slic_wphy, phy_config, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wphy, phy_config, FLUSH);
}
static void slic_config_get(struct adapter *adapter, u32 config,
@@ -3012,18 +2415,14 @@ static void slic_mac_address_config(struct adapter *adapter)
value = *(u32 *) &adapter->currmacaddr[2];
value = ntohl(value);
- WRITE_REG(slic_regs->slic_wraddral, value, FLUSH);
- WRITE_REG(slic_regs->slic_wraddrbl, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wraddral, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wraddrbl, value, FLUSH);
value2 = (u32) ((adapter->currmacaddr[0] << 8 |
adapter->currmacaddr[1]) & 0xFFFF);
- WRITE_REG(slic_regs->slic_wraddrah, value2, FLUSH);
- WRITE_REG(slic_regs->slic_wraddrbh, value2, FLUSH);
-
- DBG_MSG("%s value1[%x] value2[%x] Call slic_mcast_set_mask\n",
- __func__, value, value2);
- slic_dbg_macaddrs(adapter);
+ slic_reg32_write(&slic_regs->slic_wraddrah, value2, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wraddrbh, value2, FLUSH);
/* Write our multicast mask out to the card. This is done */
/* here in addition to the slic_mcast_addr_set routine */
@@ -3058,7 +2457,7 @@ static void slic_mac_config(struct adapter *adapter)
}
/* write mac config */
- WRITE_REG(slic_regs->slic_wmcfg, value, FLUSH);
+ slic_reg32_write(&slic_regs->slic_wmcfg, value, FLUSH);
/* setup mac addresses */
slic_mac_address_config(adapter);
@@ -3072,18 +2471,15 @@ static bool slic_mac_filter(struct adapter *adapter,
u16 *dhost2 = (u16 *)&ether_frame->ether_dhost[4];
bool equaladdr;
- if (opts & MAC_PROMISC) {
- DBG_MSG("slicoss: %s (%s) PROMISCUOUS. Accept frame\n",
- __func__, adapter->netdev->name);
- return TRUE;
- }
+ if (opts & MAC_PROMISC)
+ return true;
if ((*dhost4 == 0xFFFFFFFF) && (*dhost2 == 0xFFFF)) {
if (opts & MAC_BCAST) {
adapter->rcv_broadcasts++;
- return TRUE;
+ return true;
} else {
- return FALSE;
+ return false;
}
}
@@ -3091,7 +2487,7 @@ static bool slic_mac_filter(struct adapter *adapter,
if (opts & MAC_ALLMCAST) {
adapter->rcv_multicasts++;
adapter->stats.multicast++;
- return TRUE;
+ return true;
}
if (opts & MAC_MCAST) {
struct mcast_address *mcaddr = adapter->mcastaddrs;
@@ -3103,20 +2499,20 @@ static bool slic_mac_filter(struct adapter *adapter,
if (equaladdr) {
adapter->rcv_multicasts++;
adapter->stats.multicast++;
- return TRUE;
+ return true;
}
mcaddr = mcaddr->next;
}
- return FALSE;
+ return false;
} else {
- return FALSE;
+ return false;
}
}
if (opts & MAC_DIRECTED) {
adapter->rcv_unicasts++;
- return TRUE;
+ return true;
}
- return FALSE;
+ return false;
}
@@ -3125,80 +2521,28 @@ static int slic_mac_set_address(struct net_device *dev, void *ptr)
struct adapter *adapter = (struct adapter *)netdev_priv(dev);
struct sockaddr *addr = ptr;
- DBG_MSG("%s ENTER (%s)\n", __func__, adapter->netdev->name);
-
if (netif_running(dev))
return -EBUSY;
if (!adapter)
return -EBUSY;
- DBG_MSG("slicoss: %s (%s) curr %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
- __func__, adapter->netdev->name, adapter->currmacaddr[0],
- adapter->currmacaddr[1], adapter->currmacaddr[2],
- adapter->currmacaddr[3], adapter->currmacaddr[4],
- adapter->currmacaddr[5]);
+
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
memcpy(adapter->currmacaddr, addr->sa_data, dev->addr_len);
- DBG_MSG("slicoss: %s (%s) new %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
- __func__, adapter->netdev->name, adapter->currmacaddr[0],
- adapter->currmacaddr[1], adapter->currmacaddr[2],
- adapter->currmacaddr[3], adapter->currmacaddr[4],
- adapter->currmacaddr[5]);
- slic_config_set(adapter, TRUE);
+ slic_config_set(adapter, true);
return 0;
}
-/*
- * slic_timer_get_stats
- *
- * Timer function used to suck the statistics out of the card every
- * 50 seconds or whatever STATS_TIMER_INTERVAL is set to.
- *
- */
-#if SLIC_GET_STATS_TIMER_ENABLED
-static void slic_timer_get_stats(ulong dev)
-{
- struct adapter *adapter;
- struct sliccard *card;
- struct slic_shmem *pshmem;
-
- ASSERT(dev);
- adapter = netdev_priv((struct net_device *)dev);
- ASSERT(adapter);
- card = adapter->card;
- ASSERT(card);
-
- if ((card->state == CARD_UP) &&
- (adapter->state == ADAPT_UP) && (adapter->linkstate == LINK_UP)) {
- pshmem = (struct slic_shmem *)adapter->phys_shmem;
-#ifdef CONFIG_X86_64
- slic_upr_request(adapter,
- SLIC_UPR_STATS,
- SLIC_GET_ADDR_LOW(&pshmem->inicstats),
- SLIC_GET_ADDR_HIGH(&pshmem->inicstats), 0, 0);
-#elif defined(CONFIG_X86)
- slic_upr_request(adapter,
- SLIC_UPR_STATS,
- (u32) &pshmem->inicstats, 0, 0, 0);
-#else
- Stop compilation;
-#endif
- } else {
-/* DBG_MSG ("slicoss: %s adapter[%p] linkstate[%x] NOT UP!\n",
- __func__, adapter, adapter->linkstate); */
- }
- adapter->statstimer.expires = jiffies +
- SLIC_SECS_TO_JIFFS(STATS_TIMER_INTERVAL);
- add_timer(&adapter->statstimer);
-}
-#endif
static void slic_timer_load_check(ulong cardaddr)
{
struct sliccard *card = (struct sliccard *)cardaddr;
struct adapter *adapter = card->master;
+ u32 __iomem *intagg;
u32 load = card->events;
u32 level = 0;
+ intagg = &adapter->slic_regs->slic_intagg;
+
if ((adapter) && (adapter->state == ADAPT_UP) &&
(card->state == CARD_UP) && (slic_global.dynamic_intagg)) {
if (adapter->devid == SLIC_1GB_DEVICE_ID) {
@@ -3220,8 +2564,7 @@ static void slic_timer_load_check(ulong cardaddr)
}
if (card->loadlevel_current != level) {
card->loadlevel_current = level;
- WRITE_REG(adapter->slic_regs->slic_intagg,
- level, FLUSH);
+ slic_reg32_write(intagg, level, FLUSH);
}
} else {
if (load > SLIC_LOAD_5)
@@ -3238,14 +2581,12 @@ static void slic_timer_load_check(ulong cardaddr)
level = SLIC_INTAGG_0;
if (card->loadlevel_current != level) {
card->loadlevel_current = level;
- WRITE_REG(adapter->slic_regs->slic_intagg,
- level, FLUSH);
+ slic_reg32_write(intagg, level, FLUSH);
}
}
}
card->events = 0;
- card->loadtimer.expires =
- jiffies + SLIC_SECS_TO_JIFFS(SLIC_LOADTIMER_PERIOD);
+ card->loadtimer.expires = jiffies + (SLIC_LOADTIMER_PERIOD * HZ);
add_timer(&card->loadtimer);
}
@@ -3256,7 +2597,8 @@ static void slic_assert_fail(void)
cpuid = smp_processor_id();
curr_pid = current->pid;
- DBG_ERROR("%s CPU # %d ---- PID # %d\n", __func__, cpuid, curr_pid);
+ printk(KERN_ERR "%s CPU # %d ---- PID # %d\n",
+ __func__, cpuid, curr_pid);
}
static int slic_upr_queue_request(struct adapter *adapter,
@@ -3269,11 +2611,9 @@ static int slic_upr_queue_request(struct adapter *adapter,
struct slic_upr *uprqueue;
upr = kmalloc(sizeof(struct slic_upr), GFP_ATOMIC);
- if (!upr) {
- DBG_MSG("%s COULD NOT ALLOCATE UPR MEM\n", __func__);
-
+ if (!upr)
return -ENOMEM;
- }
+
upr->adapter = adapter->port;
upr->upr_request = upr_request;
upr->upr_data = upr_data;
@@ -3322,10 +2662,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
struct sliccard *card = adapter->card;
struct slic_upr *upr;
-/* if (card->dump_requested) {
- DBG_MSG("ENTER slic_upr_request_complete Dump in progress ISR[%x]\n",
- isr);
- } */
spin_lock_irqsave(&adapter->upr_lock.lock, adapter->upr_lock.flags);
upr = adapter->upr_list;
if (!upr) {
@@ -3341,38 +2677,19 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
switch (upr->upr_request) {
case SLIC_UPR_STATS:
{
-#if SLIC_GET_STATS_ENABLED
struct slic_stats *slicstats =
(struct slic_stats *) &adapter->pshmem->inicstats;
struct slic_stats *newstats = slicstats;
struct slic_stats *old = &adapter->inicstats_prev;
struct slicnet_stats *stst = &adapter->slic_stats;
-#endif
+
if (isr & ISR_UPCERR) {
- DBG_ERROR
- ("SLIC_UPR_STATS command failed isr[%x]\n",
- isr);
+ dev_err(&adapter->netdev->dev,
+ "SLIC_UPR_STATS command failed isr[%x]\n",
+ isr);
break;
}
-#if SLIC_GET_STATS_ENABLED
-/* DBG_MSG ("slicoss: %s rcv %lx:%lx:%lx:%lx:%lx %lx %lx "
- "xmt %lx:%lx:%lx:%lx:%lx %lx %lx\n",
- __func__,
- slicstats->rcv_unicasts100,
- slicstats->rcv_bytes100,
- slicstats->rcv_bytes100,
- slicstats->rcv_tcp_bytes100,
- slicstats->rcv_tcp_segs100,
- slicstats->rcv_other_error100,
- slicstats->rcv_drops100,
- slicstats->xmit_unicasts100,
- slicstats->xmit_bytes100,
- slicstats->xmit_bytes100,
- slicstats->xmit_tcp_bytes100,
- slicstats->xmit_tcp_segs100,
- slicstats->xmit_other_error100,
- slicstats->xmit_collisions100);*/
UPDATE_STATS_GB(stst->tcp.xmit_tcp_segs,
newstats->xmit_tcp_segs_gb,
old->xmit_tcp_segs_gb);
@@ -3431,7 +2748,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
old->rcv_drops_gb);
}
memcpy(old, newstats, sizeof(struct slic_stats));
-#endif
break;
}
case SLIC_UPR_RLSR:
@@ -3454,11 +2770,6 @@ static void slic_upr_request_complete(struct adapter *adapter, u32 isr)
case SLIC_UPR_PING:
card->pingstatus |= (isr & ISR_PINGDSMASK);
break;
-#if SLIC_DUMP_ENABLED
- case SLIC_UPR_DUMP:
- card->dumpstatus |= (isr & ISR_UPCMASK);
- break;
-#endif
default:
ASSERT(0);
}
@@ -3487,74 +2798,29 @@ static void slic_upr_start(struct adapter *adapter)
switch (upr->upr_request) {
case SLIC_UPR_STATS:
if (upr->upr_data_h == 0) {
- WRITE_REG(slic_regs->slic_stats, upr->upr_data, FLUSH);
+ slic_reg32_write(&slic_regs->slic_stats, upr->upr_data,
+ FLUSH);
} else {
- WRITE_REG64(adapter,
- slic_regs->slic_stats64,
- upr->upr_data,
- slic_regs->slic_addr_upper,
- upr->upr_data_h, FLUSH);
+ slic_reg64_write(adapter, &slic_regs->slic_stats64,
+ upr->upr_data,
+ &slic_regs->slic_addr_upper,
+ upr->upr_data_h, FLUSH);
}
break;
case SLIC_UPR_RLSR:
- WRITE_REG64(adapter,
- slic_regs->slic_rlsr,
- upr->upr_data,
- slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
+ slic_reg64_write(adapter, &slic_regs->slic_rlsr, upr->upr_data,
+ &slic_regs->slic_addr_upper, upr->upr_data_h,
+ FLUSH);
break;
case SLIC_UPR_RCONFIG:
- DBG_MSG("%s SLIC_UPR_RCONFIG!!!!\n", __func__);
- DBG_MSG("WRITE_REG64 adapter[%p]\n"
- " a->slic_regs[%p] slic_regs[%p]\n"
- " &slic_rconfig[%p] &slic_addr_upper[%p]\n"
- " upr[%p]\n"
- " uprdata[%x] uprdatah[%x]\n",
- adapter, adapter->slic_regs, slic_regs,
- &slic_regs->slic_rconfig, &slic_regs->slic_addr_upper,
- upr, upr->upr_data, upr->upr_data_h);
- WRITE_REG64(adapter,
- slic_regs->slic_rconfig,
- upr->upr_data,
- slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
+ slic_reg64_write(adapter, &slic_regs->slic_rconfig,
+ upr->upr_data, &slic_regs->slic_addr_upper,
+ upr->upr_data_h, FLUSH);
break;
-#if SLIC_DUMP_ENABLED
- case SLIC_UPR_DUMP:
-#if 0
- DBG_MSG("%s SLIC_UPR_DUMP!!!!\n", __func__);
- DBG_MSG("WRITE_REG64 adapter[%p]\n"
- " upr_buffer[%x] upr_bufferh[%x]\n"
- " upr_data[%x] upr_datah[%x]\n"
- " cmdbuff[%p] cmdbuffP[%p]\n"
- " dumpbuff[%p] dumpbuffP[%p]\n",
- adapter, upr->upr_buffer, upr->upr_buffer_h,
- upr->upr_data, upr->upr_data_h,
- adapter->card->cmdbuffer,
- (void *)adapter->card->cmdbuffer_phys,
- adapter->card->dumpbuffer, (
- void *)adapter->card->dumpbuffer_phys);
-
- ptr1 = (char *)slic_regs;
- ptr2 = (char *)(&slic_regs->slic_dump_cmd);
- cmdoffset = ptr2 - ptr1;
- DBG_MSG("slic_dump_cmd register offset [%x]\n", cmdoffset);
-#endif
- if (upr->upr_buffer || upr->upr_buffer_h) {
- WRITE_REG64(adapter,
- slic_regs->slic_dump_data,
- upr->upr_buffer,
- slic_regs->slic_addr_upper,
- upr->upr_buffer_h, FLUSH);
- }
- WRITE_REG64(adapter,
- slic_regs->slic_dump_cmd,
- upr->upr_data,
- slic_regs->slic_addr_upper, upr->upr_data_h, FLUSH);
- break;
-#endif
case SLIC_UPR_PING:
- WRITE_REG(slic_regs->slic_ping, 1, FLUSH);
+ slic_reg32_write(&slic_regs->slic_ping, 1, FLUSH);
break;
default:
ASSERT(0);
@@ -3568,10 +2834,6 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
unsigned char linkspeed;
unsigned char linkduplex;
- DBG_MSG("%s: %s ISR[%x] linkstatus[%x]\n adapter[%p](%d)\n",
- __func__, adapter->netdev->name, isr, linkstatus, adapter,
- adapter->cardindex);
-
if ((isr & ISR_UPCERR) || (isr & ISR_UPCBSY)) {
struct slic_shmem *pshmem;
@@ -3599,50 +2861,33 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
|| (adapter->devid == SLIC_2GB_DEVICE_ID));
linkup = linkstatus & GIG_LINKUP ? LINK_UP : LINK_DOWN;
- if (linkstatus & GIG_SPEED_1000) {
+ if (linkstatus & GIG_SPEED_1000)
linkspeed = LINK_1000MB;
- DBG_MSG("slicoss: %s (%s) GIGABIT Speed==1000MB ",
- __func__, adapter->netdev->name);
- } else if (linkstatus & GIG_SPEED_100) {
+ else if (linkstatus & GIG_SPEED_100)
linkspeed = LINK_100MB;
- DBG_MSG("slicoss: %s (%s) GIGABIT Speed==100MB ", __func__,
- adapter->netdev->name);
- } else {
+ else
linkspeed = LINK_10MB;
- DBG_MSG("slicoss: %s (%s) GIGABIT Speed==10MB ", __func__,
- adapter->netdev->name);
- }
- if (linkstatus & GIG_FULLDUPLEX) {
+
+ if (linkstatus & GIG_FULLDUPLEX)
linkduplex = LINK_FULLD;
- DBG_MSG(" Duplex == FULL\n");
- } else {
+ else
linkduplex = LINK_HALFD;
- DBG_MSG(" Duplex == HALF\n");
- }
- if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN)) {
- DBG_MSG("slicoss: %s (%s) physport(%d) link still down\n",
- __func__, adapter->netdev->name, adapter->physport);
+ if ((adapter->linkstate == LINK_DOWN) && (linkup == LINK_DOWN))
return;
- }
/* link up event, but nothing has changed */
if ((adapter->linkstate == LINK_UP) &&
(linkup == LINK_UP) &&
(adapter->linkspeed == linkspeed) &&
- (adapter->linkduplex == linkduplex)) {
- DBG_MSG("slicoss: %s (%s) port(%d) link still up\n",
- __func__, adapter->netdev->name, adapter->physport);
+ (adapter->linkduplex == linkduplex))
return;
- }
/* link has changed at this point */
/* link has gone from up to down */
if (linkup == LINK_DOWN) {
adapter->linkstate = LINK_DOWN;
- DBG_MSG("slicoss: %s %d LinkDown!\n", __func__,
- adapter->physport);
return;
}
@@ -3652,30 +2897,10 @@ static void slic_link_upr_complete(struct adapter *adapter, u32 isr)
if (adapter->linkstate != LINK_UP) {
/* setup the mac */
- DBG_MSG("%s call slic_config_set\n", __func__);
- slic_config_set(adapter, TRUE);
+ slic_config_set(adapter, true);
adapter->linkstate = LINK_UP;
- DBG_MSG("\n(%s) Link UP: CALL slic_if_start_queue",
- adapter->netdev->name);
- slic_if_start_queue(adapter);
- }
-#if 1
- switch (linkspeed) {
- case LINK_1000MB:
- DBG_MSG
- ("\n(%s) LINK UP!: GIGABIT SPEED == 1000MB duplex[%x]\n",
- adapter->netdev->name, adapter->linkduplex);
- break;
- case LINK_100MB:
- DBG_MSG("\n(%s) LINK UP!: SPEED == 100MB duplex[%x]\n",
- adapter->netdev->name, adapter->linkduplex);
- break;
- default:
- DBG_MSG("\n(%s) LINK UP!: SPEED == 10MB duplex[%x]\n",
- adapter->netdev->name, adapter->linkduplex);
- break;
+ netif_start_queue(adapter->netdev);
}
-#endif
}
/*
@@ -3787,20 +3012,18 @@ static int slic_rspqueue_init(struct adapter *adapter)
__iomem struct slic_regs *slic_regs = adapter->slic_regs;
u32 paddrh = 0;
- DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
- adapter->netdev->name, adapter);
ASSERT(adapter->state == ADAPT_DOWN);
memset(rspq, 0, sizeof(struct slic_rspqueue));
rspq->num_pages = SLIC_RSPQ_PAGES_GB;
for (i = 0; i < rspq->num_pages; i++) {
- rspq->vaddr[i] =
- pci_alloc_consistent(adapter->pcidev, PAGE_SIZE,
- &rspq->paddr[i]);
+ rspq->vaddr[i] = pci_alloc_consistent(adapter->pcidev,
+ PAGE_SIZE,
+ &rspq->paddr[i]);
if (!rspq->vaddr[i]) {
- DBG_ERROR
- ("rspqueue_init_failed pci_alloc_consistent\n");
+ dev_err(&adapter->pcidev->dev,
+ "pci_alloc_consistent failed\n");
slic_rspqueue_free(adapter);
return STATUS_FAILURE;
}
@@ -3811,47 +3034,21 @@ static int slic_rspqueue_init(struct adapter *adapter)
(u32) rspq->paddr[i]);
#endif
memset(rspq->vaddr[i], 0, PAGE_SIZE);
-/* DBG_MSG("slicoss: %s UPLOAD RSPBUFF Page pageix[%x] paddr[%p] "
- "vaddr[%p]\n",
- __func__, i, (void *)rspq->paddr[i], rspq->vaddr[i]); */
if (paddrh == 0) {
- WRITE_REG(slic_regs->slic_rbar,
- (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
- DONT_FLUSH);
+ slic_reg32_write(&slic_regs->slic_rbar,
+ (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+ DONT_FLUSH);
} else {
- WRITE_REG64(adapter,
- slic_regs->slic_rbar64,
- (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
- slic_regs->slic_addr_upper,
- paddrh, DONT_FLUSH);
+ slic_reg64_write(adapter, &slic_regs->slic_rbar64,
+ (rspq->paddr[i] | SLIC_RSPQ_BUFSINPAGE),
+ &slic_regs->slic_addr_upper,
+ paddrh, DONT_FLUSH);
}
}
rspq->offset = 0;
rspq->pageindex = 0;
rspq->rspbuf = (struct slic_rspbuf *)rspq->vaddr[0];
- DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
- adapter->netdev->name, adapter);
- return STATUS_SUCCESS;
-}
-
-static int slic_rspqueue_reset(struct adapter *adapter)
-{
- struct slic_rspqueue *rspq = &adapter->rspqueue;
-
- DBG_MSG("slicoss: %s (%s) ENTER adapter[%p]\n", __func__,
- adapter->netdev->name, adapter);
- ASSERT(adapter->state == ADAPT_DOWN);
- ASSERT(rspq);
-
- DBG_MSG("slicoss: Nothing to do. rspq[%p]\n"
- " offset[%x]\n"
- " pageix[%x]\n"
- " rspbuf[%p]\n",
- rspq, rspq->offset, rspq->pageindex, rspq->rspbuf);
-
- DBG_MSG("slicoss: %s (%s) EXIT adapter[%p]\n", __func__,
- adapter->netdev->name, adapter);
return STATUS_SUCCESS;
}
@@ -3860,14 +3057,8 @@ static void slic_rspqueue_free(struct adapter *adapter)
int i;
struct slic_rspqueue *rspq = &adapter->rspqueue;
- DBG_MSG("slicoss: %s adapter[%p] port %d rspq[%p] FreeRSPQ\n",
- __func__, adapter, adapter->physport, rspq);
for (i = 0; i < rspq->num_pages; i++) {
if (rspq->vaddr[i]) {
- DBG_MSG
- ("slicoss: pci_free_consistent rspq->vaddr[%p] \
- paddr[%p]\n",
- rspq->vaddr[i], (void *) rspq->paddr[i]);
pci_free_consistent(adapter->pcidev, PAGE_SIZE,
rspq->vaddr[i], rspq->paddr[i]);
}
@@ -3900,11 +3091,9 @@ static struct slic_rspbuf *slic_rspqueue_getnext(struct adapter *adapter)
#endif
} else {
ASSERT(rspq->offset == SLIC_RSPQ_BUFSINPAGE);
- WRITE_REG64(adapter,
- adapter->slic_regs->slic_rbar64,
- (rspq->
- paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
- adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
+ slic_reg64_write(adapter, &adapter->slic_regs->slic_rbar64,
+ (rspq->paddr[rspq->pageindex] | SLIC_RSPQ_BUFSINPAGE),
+ &adapter->slic_regs->slic_addr_upper, 0, DONT_FLUSH);
rspq->pageindex = (++rspq->pageindex) % rspq->num_pages;
rspq->offset = 0;
rspq->rspbuf = (struct slic_rspbuf *)
@@ -3932,12 +3121,8 @@ static void slic_cmdqmem_free(struct adapter *adapter)
struct slic_cmdqmem *cmdqmem = &adapter->cmdqmem;
int i;
- DBG_MSG("slicoss: (%s) adapter[%p] port %d rspq[%p] Free CMDQ Memory\n",
- __func__, adapter, adapter->physport, cmdqmem);
for (i = 0; i < SLIC_CMDQ_MAXPAGES; i++) {
if (cmdqmem->pages[i]) {
- DBG_MSG("slicoss: %s Deallocate page CmdQPage[%p]\n",
- __func__, (void *) cmdqmem->pages[i]);
pci_free_consistent(adapter->pcidev,
PAGE_SIZE,
(void *) cmdqmem->pages[i],
@@ -3972,7 +3157,6 @@ static int slic_cmdq_init(struct adapter *adapter)
int i;
u32 *pageaddr;
- DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
ASSERT(adapter->state == ADAPT_DOWN);
memset(&adapter->cmdq_all, 0, sizeof(struct slic_cmdqueue));
memset(&adapter->cmdq_free, 0, sizeof(struct slic_cmdqueue));
@@ -3994,7 +3178,6 @@ static int slic_cmdq_init(struct adapter *adapter)
slic_cmdq_addcmdpage(adapter, pageaddr);
}
adapter->slic_handle_ix = 1;
- DBG_MSG("slicoss: %s reset slic_handle_ix to ONE\n", __func__);
return STATUS_SUCCESS;
}
@@ -4003,8 +3186,6 @@ static void slic_cmdq_free(struct adapter *adapter)
{
struct slic_hostcmd *cmd;
- DBG_MSG("slicoss: %s adapter[%p] port %d FreeCommandsFrom CMDQ\n",
- __func__, adapter, adapter->physport);
cmd = adapter->cmdq_all.head;
while (cmd) {
if (cmd->busy) {
@@ -4030,7 +3211,6 @@ static void slic_cmdq_reset(struct adapter *adapter)
struct sk_buff *skb;
u32 outstanding;
- DBG_MSG("%s ENTER adapter[%p]\n", __func__, adapter);
spin_lock_irqsave(&adapter->cmdq_free.lock.lock,
adapter->cmdq_free.lock.flags);
spin_lock_irqsave(&adapter->cmdq_done.lock.lock,
@@ -4042,11 +3222,8 @@ static void slic_cmdq_reset(struct adapter *adapter)
if (hcmd->busy) {
skb = hcmd->skb;
ASSERT(skb);
- DBG_MSG("slicoss: %s hcmd[%p] skb[%p] ", __func__,
- hcmd, skb);
hcmd->busy = 0;
hcmd->skb = NULL;
- DBG_MSG(" Free SKB\n");
dev_kfree_skb_irq(skb);
}
hcmd = hcmd->next_all;
@@ -4065,14 +3242,14 @@ static void slic_cmdq_reset(struct adapter *adapter)
hcmd = hcmd->next_all;
}
if (adapter->cmdq_free.count != adapter->cmdq_all.count) {
- DBG_ERROR("%s free_count %d != all count %d\n", __func__,
- adapter->cmdq_free.count, adapter->cmdq_all.count);
+ dev_err(&adapter->netdev->dev,
+ "free_count %d != all count %d\n",
+ adapter->cmdq_free.count, adapter->cmdq_all.count);
}
spin_unlock_irqrestore(&adapter->cmdq_done.lock.lock,
adapter->cmdq_done.lock.flags);
spin_unlock_irqrestore(&adapter->cmdq_free.lock.lock,
adapter->cmdq_free.lock.flags);
- DBG_MSG("%s EXIT adapter[%p]\n", __func__, adapter);
}
static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
@@ -4090,8 +3267,6 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
cmdaddr = page;
cmd = (struct slic_hostcmd *)cmdaddr;
-/* DBG_MSG("CMDQ Page addr[%p] ix[%d] pfree[%p]\n", cmdaddr, slic_handle_ix,
- adapter->pfree_slic_handles); */
cmdcnt = 0;
phys_addr = virt_to_bus((void *)page);
@@ -4117,7 +3292,7 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
cmd->pslic_handle = pslic_handle;
cmd->cmd64.hosthandle = pslic_handle->token.handle_token;
- cmd->busy = FALSE;
+ cmd->busy = false;
cmd->paddrl = phys_addrl;
cmd->paddrh = phys_addrh;
cmd->next_all = prev;
@@ -4133,13 +3308,11 @@ static void slic_cmdq_addcmdpage(struct adapter *adapter, u32 *page)
cmdq = &adapter->cmdq_all;
cmdq->count += cmdcnt; /* SLIC_CMDQ_CMDSINPAGE; mooktodo */
tail->next_all = cmdq->head;
- ASSERT(VALID_ADDRESS(prev));
cmdq->head = prev;
cmdq = &adapter->cmdq_free;
spin_lock_irqsave(&cmdq->lock.lock, cmdq->lock.flags);
cmdq->count += cmdcnt; /* SLIC_CMDQ_CMDSINPAGE; mooktodo */
tail->next = cmdq->head;
- ASSERT(VALID_ADDRESS(prev));
cmdq->head = prev;
spin_unlock_irqrestore(&cmdq->lock.lock, cmdq->lock.flags);
}
@@ -4184,7 +3357,6 @@ static void slic_cmdq_getdone(struct adapter *adapter)
ASSERT(free_cmdq->head == NULL);
spin_lock_irqsave(&done_cmdq->lock.lock, done_cmdq->lock.flags);
- ASSERT(VALID_ADDRESS(done_cmdq->head));
free_cmdq->head = done_cmdq->head;
free_cmdq->count = done_cmdq->count;
@@ -4201,9 +3373,7 @@ static void slic_cmdq_putdone_irq(struct adapter *adapter,
spin_lock(&cmdq->lock.lock);
cmd->busy = 0;
- ASSERT(VALID_ADDRESS(cmdq->head));
cmd->next = cmdq->head;
- ASSERT(VALID_ADDRESS(cmd));
cmdq->head = cmd;
cmdq->count++;
if ((adapter->xmitq_full) && (cmdq->count > 10))
@@ -4216,7 +3386,6 @@ static int slic_rcvqueue_init(struct adapter *adapter)
int i, count;
struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
- DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
ASSERT(adapter->state == ADAPT_DOWN);
rcvq->tail = NULL;
rcvq->head = NULL;
@@ -4233,25 +3402,6 @@ static int slic_rcvqueue_init(struct adapter *adapter)
slic_rcvqueue_free(adapter);
return STATUS_FAILURE;
}
- DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
- return STATUS_SUCCESS;
-}
-
-static int slic_rcvqueue_reset(struct adapter *adapter)
-{
- struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
-
- DBG_MSG("slicoss: %s ENTER adapter[%p]\n", __func__, adapter);
- ASSERT(adapter->state == ADAPT_DOWN);
- ASSERT(rcvq);
-
- DBG_MSG("slicoss: Nothing to do. rcvq[%p]\n"
- " count[%x]\n"
- " head[%p]\n"
- " tail[%p]\n",
- rcvq, rcvq->count, rcvq->head, rcvq->tail);
-
- DBG_MSG("slicoss: %s EXIT adapter[%p]\n", __func__, adapter);
return STATUS_SUCCESS;
}
@@ -4290,8 +3440,8 @@ static struct sk_buff *slic_rcvqueue_getnext(struct adapter *adapter)
skb = NULL;
}
} else {
- DBG_ERROR("RcvQ Empty!! adapter[%p] rcvq[%p] count[%x]\n",
- adapter, rcvq, rcvq->count);
+ dev_err(&adapter->netdev->dev,
+ "RcvQ Empty!! rcvq[%p] count[%x]\n", rcvq, rcvq->count);
skb = NULL;
}
while (rcvq->count < SLIC_RCVQ_FILLTHRESH) {
@@ -4311,6 +3461,7 @@ static int slic_rcvqueue_fill(struct adapter *adapter)
u32 paddrh;
struct slic_rcvqueue *rcvq = &adapter->rcvqueue;
int i = 0;
+ struct device *dev = &adapter->netdev->dev;
while (i < SLIC_RCVQ_FILLENTRIES) {
struct slic_rcvbuf *rcvbuf;
@@ -4333,44 +3484,45 @@ retry_rcvqfill:
skb->next = NULL;
#ifdef KLUDGE_FOR_4GB_BOUNDARY
if (paddrl == 0) {
- DBG_ERROR
- ("%s: LOW 32bits PHYSICAL ADDRESS == 0 "
- "skb[%p] PROBLEM\n"
- " skbdata[%p]\n"
- " skblen[%x]\n"
- " paddr[%p]\n"
- " paddrl[%x]\n"
- " paddrh[%x]\n", __func__, skb,
- skb->data, skb->len, paddr, paddrl,
- paddrh);
- DBG_ERROR(" rcvq->head[%p]\n"
- " rcvq->tail[%p]\n"
- " rcvq->count[%x]\n",
- rcvq->head, rcvq->tail, rcvq->count);
- DBG_ERROR("SKIP THIS SKB!!!!!!!!\n");
+ dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+ __func__);
+ dev_err(dev, "skb[%p] PROBLEM\n", skb);
+ dev_err(dev, " skbdata[%p]\n", skb->data);
+ dev_err(dev, " skblen[%x]\n", skb->len);
+ dev_err(dev, " paddr[%p]\n", paddr);
+ dev_err(dev, " paddrl[%x]\n", paddrl);
+ dev_err(dev, " paddrh[%x]\n", paddrh);
+ dev_err(dev, " rcvq->head[%p]\n", rcvq->head);
+ dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail);
+ dev_err(dev, " rcvq->count[%x]\n", rcvq->count);
+ dev_err(dev, "SKIP THIS SKB!!!!!!!!\n");
goto retry_rcvqfill;
}
#else
if (paddrl == 0) {
- DBG_ERROR
- ("\n\n%s: LOW 32bits PHYSICAL ADDRESS == 0 "
- "skb[%p] GIVE TO CARD ANYWAY\n"
- " skbdata[%p]\n"
- " paddr[%p]\n"
- " paddrl[%x]\n"
- " paddrh[%x]\n", __func__, skb,
- skb->data, paddr, paddrl, paddrh);
+ dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+ __func__);
+ dev_err(dev, "skb[%p] PROBLEM\n", skb);
+ dev_err(dev, " skbdata[%p]\n", skb->data);
+ dev_err(dev, " skblen[%x]\n", skb->len);
+ dev_err(dev, " paddr[%p]\n", paddr);
+ dev_err(dev, " paddrl[%x]\n", paddrl);
+ dev_err(dev, " paddrh[%x]\n", paddrh);
+ dev_err(dev, " rcvq->head[%p]\n", rcvq->head);
+ dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail);
+ dev_err(dev, " rcvq->count[%x]\n", rcvq->count);
+ dev_err(dev, "GIVE TO CARD ANYWAY\n");
}
#endif
if (paddrh == 0) {
- WRITE_REG(adapter->slic_regs->slic_hbar,
- (u32) paddrl, DONT_FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_hbar,
+ (u32)paddrl, DONT_FLUSH);
} else {
- WRITE_REG64(adapter,
- adapter->slic_regs->slic_hbar64,
- (u32) paddrl,
- adapter->slic_regs->slic_addr_upper,
- (u32) paddrh, DONT_FLUSH);
+ slic_reg64_write(adapter,
+ &adapter->slic_regs->slic_hbar64,
+ paddrl,
+ &adapter->slic_regs->slic_addr_upper,
+ paddrh, DONT_FLUSH);
}
if (rcvq->head)
rcvq->tail->next = skb;
@@ -4380,10 +3532,9 @@ retry_rcvqfill:
rcvq->count++;
i++;
} else {
- DBG_ERROR
- ("%s slic_rcvqueue_fill could only get [%d] "
- "skbuffs\n",
- adapter->netdev->name, i);
+ dev_err(&adapter->netdev->dev,
+ "slic_rcvqueue_fill could only get [%d] skbuffs\n",
+ i);
break;
}
}
@@ -4397,6 +3548,7 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
u32 paddrl;
u32 paddrh;
struct slic_rcvbuf *rcvbuf = (struct slic_rcvbuf *)skb->head;
+ struct device *dev;
ASSERT(skb->len == SLIC_RCVBUF_HEADSIZE);
@@ -4409,26 +3561,26 @@ static u32 slic_rcvqueue_reinsert(struct adapter *adapter, struct sk_buff *skb)
paddrh = SLIC_GET_ADDR_HIGH(paddr);
if (paddrl == 0) {
- DBG_ERROR
- ("%s: LOW 32bits PHYSICAL ADDRESS == 0 skb[%p] PROBLEM\n"
- " skbdata[%p]\n" " skblen[%x]\n"
- " paddr[%p]\n" " paddrl[%x]\n"
- " paddrh[%x]\n", __func__, skb, skb->data,
- skb->len, paddr, paddrl, paddrh);
- DBG_ERROR(" rcvq->head[%p]\n"
- " rcvq->tail[%p]\n"
- " rcvq->count[%x]\n", rcvq->head, rcvq->tail,
- rcvq->count);
+ dev = &adapter->netdev->dev;
+ dev_err(dev, "%s: LOW 32bits PHYSICAL ADDRESS == 0\n",
+ __func__);
+ dev_err(dev, "skb[%p] PROBLEM\n", skb);
+ dev_err(dev, " skbdata[%p]\n", skb->data);
+ dev_err(dev, " skblen[%x]\n", skb->len);
+ dev_err(dev, " paddr[%p]\n", paddr);
+ dev_err(dev, " paddrl[%x]\n", paddrl);
+ dev_err(dev, " paddrh[%x]\n", paddrh);
+ dev_err(dev, " rcvq->head[%p]\n", rcvq->head);
+ dev_err(dev, " rcvq->tail[%p]\n", rcvq->tail);
+ dev_err(dev, " rcvq->count[%x]\n", rcvq->count);
}
if (paddrh == 0) {
- WRITE_REG(adapter->slic_regs->slic_hbar, (u32) paddrl,
- DONT_FLUSH);
+ slic_reg32_write(&adapter->slic_regs->slic_hbar, (u32)paddrl,
+ DONT_FLUSH);
} else {
- WRITE_REG64(adapter,
- adapter->slic_regs->slic_hbar64,
- paddrl,
- adapter->slic_regs->slic_addr_upper,
- paddrh, DONT_FLUSH);
+ slic_reg64_write(adapter, &adapter->slic_regs->slic_hbar64,
+ paddrl, &adapter->slic_regs->slic_addr_upper,
+ paddrh, DONT_FLUSH);
}
if (rcvq->head)
rcvq->tail->next = skb;
@@ -4449,7 +3601,7 @@ static int slic_debug_card_show(struct seq_file *seq, void *v)
unsigned char *oemfru = (unsigned char *)(&card->config.OemFru);
#endif
- seq_printf(seq, "driver_version : %s", slic_proc_version);
+ seq_printf(seq, "driver_version : %s\n", slic_proc_version);
seq_printf(seq, "Microcode versions: \n");
seq_printf(seq, " Gigabit (gb) : %s %s\n",
MOJAVE_UCODE_VERS_STRING, MOJAVE_UCODE_VERS_DATE);
@@ -4882,1030 +4034,6 @@ static void slic_debug_cleanup(void)
}
}
-/*=============================================================================
- =============================================================================
- === ===
- === SLIC DUMP MANAGEMENT SECTION ===
- === ===
- === ===
- === Dump routines ===
- === ===
- === ===
- =============================================================================
- ============================================================================*/
-
-#if SLIC_DUMP_ENABLED
-
-#include <stdarg.h>
-
-void *slic_dump_handle; /* thread handle */
-
-/*
- * These are the only things you should do on a core-file: use only these
- * functions to write out all the necessary info.
- */
-static int slic_dump_seek(struct file *SLIChandle, u32 file_offset)
-{
- if (SLIChandle->f_pos != file_offset) {
- /*DBG_MSG("slic_dump_seek now needed [%x : %x]\n",
- (u32)SLIChandle->f_pos, (u32)file_offset); */
- if (SLIChandle->f_op->llseek) {
- if (SLIChandle->f_op->
- llseek(SLIChandle, file_offset, 0) != file_offset)
- return 0;
- } else {
- SLIChandle->f_pos = file_offset;
- }
- }
- return 1;
-}
-
-static int slic_dump_write(struct sliccard *card,
- const void *addr, int size, u32 file_offset)
-{
- int r = 1;
- u32 result = 0;
- struct file *SLIChandle = card->dumphandle;
-
-#ifdef HISTORICAL /* legacy */
- down(&SLIChandle->f_dentry->d_inode->i_sem);
-#endif
- if (size) {
- slic_dump_seek(SLIChandle, file_offset);
-
- result =
- SLIChandle->f_op->write(SLIChandle, addr, size,
- &SLIChandle->f_pos);
-
- r = result == size;
- }
-
- card->dumptime_complete = jiffies;
- card->dumptime_delta = card->dumptime_complete - card->dumptime_start;
- card->dumptime_start = jiffies;
-
-#ifdef HISTORICAL
- up(&SLIChandle->f_dentry->d_inode->i_sem);
-#endif
- if (!r) {
- DBG_ERROR("%s: addr[%p] size[%x] result[%x] file_offset[%x]\n",
- __func__, addr, size, result, file_offset);
- }
- return r;
-}
-
-static uint slic_init_dump_thread(struct sliccard *card)
-{
- card->dump_task_id = kthread_run(slic_dump_thread, (void *)card, 0);
-
-/* DBG_MSG("create slic_dump_thread dump_pid[%x]\n", card->dump_pid); */
- if (IS_ERR(card->dump_task_id)) {
- DBG_MSG("create slic_dump_thread FAILED \n");
- return STATUS_FAILURE;
- }
-
- return STATUS_SUCCESS;
-}
-
-static int slic_dump_thread(void *context)
-{
- struct sliccard *card = (struct sliccard *)context;
- struct adapter *adapter;
- struct adapter *dump_adapter = NULL;
- u32 dump_complete = 0;
- u32 delay = SLIC_SECS_TO_JIFFS(PING_TIMER_INTERVAL);
- struct slic_regs *pregs;
- u32 i;
- struct slic_upr *upr, *uprnext;
- u32 dump_card;
-
- ASSERT(card);
-
- card->dumpthread_running = 1;
-
-#ifdef HISTORICAL
- lock_kernel();
- /*
- * This thread doesn't need any user-level access,
- * so get rid of all our resources
- */
- exit_files(current); /* daemonize doesn't do exit_files */
- current->files = init_task.files;
- atomic_inc(&current->files->count);
-#endif
-
- daemonize("%s", "slicmon");
-
- /* Setup a nice name */
- strcpy(current->comm, "slicmon");
- DBG_ERROR
- ("slic_dump_thread[slicmon] daemon is alive card[%p] pid[%x]\n",
- card, card->dump_task_id->pid);
-
- /*
- * Send me a signal to get me to die (for debugging)
- */
- do {
- /*
- * If card state is not set to up, skip
- */
- if (card->state != CARD_UP) {
- if (card->adapters_activated)
- goto wait;
- else
- goto end_thread;
- }
- /*
- * Check the results of our last ping.
- */
- dump_card = 0;
-#ifdef SLIC_FAILURE_DUMP
- if (card->pingstatus != ISR_PINGMASK) {
- DBG_MSG
- ("\n[slicmon] CARD #%d TIMED OUT - status "
- "%x: DUMP THE CARD!\n",
- card->cardnum, card->pingstatus);
- dump_card = 1;
- }
-#else
- /*
- * Cause a card RESET instead?
- */
- if (card->pingstatus != ISR_PINGMASK) {
- /* todo. do we want to reset the card in production */
- /* DBG_MSG("\n[slicmon] CARD #%d TIMED OUT - "
- status %x: RESET THE CARD!\n", card->cardnum,
- card->pingstatus); */
- DBG_ERROR
- ("\n[slicmon] CARD #%d TIMED OUT - status %x: "
- "DUMP THE CARD!\n",
- card->cardnum, card->pingstatus);
- dump_card = 1;
- }
-#endif
- if ((dump_card)
- || (card->dump_requested == SLIC_DUMP_REQUESTED)) {
- if (card->dump_requested == SLIC_DUMP_REQUESTED) {
- DBG_ERROR
- ("[slicmon]: Dump card Requested: Card %x\n",
- card->cardnum);
- }
- if (card->pingstatus != ISR_PINGMASK) {
- ushort cpuid = 0;
- ushort crashpc = 0;
-
- if (card->adapter[0]) {
- if ((card->adapter[0])->memorylength >=
- CRASH_INFO_OFFSET +
- sizeof(slic_crash_info)) {
- char *crashptr;
- p_slic_crash_info crashinfo;
-
- crashptr =
- ((char *)card->adapter[0]->
- slic_regs) +
- CRASH_INFO_OFFSET;
- crashinfo =
- (p_slic_crash_info)
- crashptr;
- cpuid = crashinfo->cpu_id;
- crashpc = crashinfo->crash_pc;
- }
- }
- DBG_ERROR
- ("[slicmon]: Dump card: Card %x crashed "
- "and failed to answer PING. "
- "CPUID[%x] PC[%x]\n ",
- card->cardnum, cpuid, crashpc);
- }
-
- card->dump_requested = SLIC_DUMP_IN_PROGRESS;
-
- /*
- * Set the card state to DOWN and the adapter states
- * to RESET.They will check this in SimbaCheckForHang
- * and initiate interface reset (which in turn will
- * reinitialize the card).
- */
- card->state = CARD_DOWN;
-
- for (i = 0; i < card->card_size; i++) {
- adapter = card->adapter[i];
- if (adapter) {
- slic_if_stop_queue(adapter);
-
- if (adapter->state == ADAPT_UP) {
- adapter->state = ADAPT_RESET;
- adapter->linkstate = LINK_DOWN;
- DBG_ERROR
- ("[slicmon]: SLIC Card[%d] "
- "Port[%d] adapter[%p] "
- "down\n",
- (uint) card->cardnum,
- (uint) i, adapter);
- }
-#if SLIC_GET_STATS_TIMER_ENABLED
- /* free stats timer */
- if (adapter->statstimerset) {
- adapter->statstimerset = 0;
- del_timer(&adapter->statstimer);
- }
-#endif
- }
- }
-
- for (i = 0; i < card->card_size; i++) {
- adapter = card->adapter[i];
- if ((adapter) && (adapter->activated)) {
- pregs = adapter->slic_regs;
- dump_adapter = adapter;
-
- /*
- * If the dump status is zero, then
- * the utility processor has crashed.
- * If this is the case, any pending
- * utilityprocessor requests will not
- * complete and our dump commands will
- * not be issued.
- *
- * To avoid this we will clear any
- * pending utility processor requests
- * now.
- */
- if (!card->pingstatus) {
- spin_lock_irqsave(
- &adapter->upr_lock.lock,
- adapter->upr_lock.flags);
- upr = adapter->upr_list;
- while (upr) {
- uprnext = upr->next;
- kfree(upr);
- upr = uprnext;
- }
- adapter->upr_list = 0;
- adapter->upr_busy = 0;
- spin_unlock_irqrestore(
- &adapter->upr_lock.lock,
- adapter->upr_lock.flags);
- }
-
- slic_dump_card(card, FALSE);
- dump_complete = 1;
- }
-
- if (dump_complete) {
- DBG_ERROR("SLIC Dump Complete\n");
- /* Only dump the card one time */
- break;
- }
- }
-
- if (dump_adapter) {
- DBG_ERROR
- ("slic dump completed. "
- "Reenable interfaces\n");
- slic_card_init(card, dump_adapter);
-
- /*
- * Reenable the adapters that were reset
- */
- for (i = 0; i < card->card_size; i++) {
- adapter = card->adapter[i];
- if (adapter) {
- if (adapter->state ==
- ADAPT_RESET) {
- DBG_ERROR
- ("slicdump: SLIC "
- "Card[%d] Port[%d] adapter[%p] "
- "bring UP\n",
- (uint) card->
- cardnum, (uint) i,
- adapter);
- adapter->state =
- ADAPT_DOWN;
- adapter->linkstate =
- LINK_DOWN;
- slic_entry_open
- (adapter->netdev);
- }
- }
- }
-
- card->dump_requested = SLIC_DUMP_DONE;
- }
- } else {
- /* if pingstatus != ISR_PINGMASK) || dump_requested...ELSE
- * We received a valid ping response.
- * Clear the Pingstatus field, find a valid adapter
- * structure and send another ping.
- */
- for (i = 0; i < card->card_size; i++) {
- adapter = card->adapter[i];
- if (adapter && (adapter->state == ADAPT_UP)) {
- card->pingstatus = 0;
- slic_upr_request(adapter, SLIC_UPR_PING,
- 0, 0, 0, 0);
- break; /* Only issue one per card */
- }
- }
- }
-wait:
- SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq, delay);
- } while (!signal_pending(current));
-
-end_thread:
-/* DBG_MSG("[slicmon] slic_dump_thread card[%p] pid[%x] ENDING\n",
- card, card->dump_pid); */
- card->dumpthread_running = 0;
-
- return 0;
-}
-
-/*
- * Read a single byte from our dump index file. This
- * value is used as our suffix for our dump path. The
- * value is incremented and written back to the file
- */
-static unsigned char slic_get_dump_index(char *path)
-{
- unsigned char index = 0;
-#ifdef SLIC_DUMP_INDEX_SUPPORT
- u32 status;
- void *FileHandle;
- u32 offset;
-
- offset = 0;
-
- /*
- * Open the index file. If one doesn't exist, create it
- */
- status = create_file(&FileHandle);
-
- if (status != STATUS_SUCCESS)
- return (unsigned char) 0;
-
- status = read_file(FileHandle, &index, 1, &offset);
-
- index++;
-
- status = write_file(FileHandle, &index, 1, &offset);
-
- close_file(FileHandle);
-#else
- index = 0;
-#endif
- return index;
-}
-
-static struct file *slic_dump_open_file(struct sliccard *card)
-{
- struct file *SLIChandle = NULL;
- struct dentry *dentry = NULL;
- struct inode *inode = NULL;
- char SLICfile[50];
-
- card->dumpfile_fs = get_fs();
-
- set_fs(KERNEL_DS);
-
- memset(SLICfile, 0, sizeof(SLICfile));
- sprintf(SLICfile, "/var/tmp/slic%d-dump-%d", card->cardnum,
- (uint) card->dump_count);
- card->dump_count++;
-
- SLIChandle =
- filp_open(SLICfile, O_CREAT | O_RDWR | O_SYNC | O_LARGEFILE, 0666);
-
- DBG_MSG("[slicmon]: Dump Card #%d to file: %s \n", card->cardnum,
- SLICfile);
-
-/* DBG_MSG("[slicmon] filp_open %s SLIChandle[%p]\n", SLICfile, SLIChandle);*/
-
- if (IS_ERR(SLIChandle))
- goto end_slicdump;
-
- dentry = SLIChandle->f_dentry;
- inode = dentry->d_inode;
-
-/* DBG_MSG("[slicmon] inode[%p] i_nlink[%x] i_mode[%x] i_op[%p] i_fop[%p]\n"
- "f_op->write[%p]\n",
- inode, inode->i_nlink, inode->i_mode, inode->i_op,
- inode->i_fop, SLIChandle->f_op->write); */
- if (inode->i_nlink > 1)
- goto close_slicdump; /* multiple links - don't dump */
-#ifdef HISTORICAL
- if (!S_ISREG(inode->i_mode))
- goto close_slicdump;
-#endif
- if (!inode->i_op || !inode->i_fop)
- goto close_slicdump;
-
- if (!SLIChandle->f_op->write)
- goto close_slicdump;
-
- /*
- * If we got here we have SUCCESSFULLY OPENED the dump file
- */
-/* DBG_MSG("opened %s SLIChandle[%p]\n", SLICfile, SLIChandle); */
- return SLIChandle;
-
-close_slicdump:
- DBG_MSG("[slicmon] slic_dump_open_file failed close SLIChandle[%p]\n",
- SLIChandle);
- filp_close(SLIChandle, NULL);
-
-end_slicdump:
- set_fs(card->dumpfile_fs);
-
- return NULL;
-}
-
-static void slic_dump_close_file(struct sliccard *card)
-{
-
-/* DBG_MSG("[slicmon] slic_dump_CLOSE_file close SLIChandle[%p]\n",
- card->dumphandle); */
-
- filp_close(card->dumphandle, NULL);
-
- set_fs(card->dumpfile_fs);
-}
-
-static u32 slic_dump_card(struct sliccard *card, bool resume)
-{
- struct adapter *adapter = card->master;
- u32 status;
- u32 queue;
- u32 len, offset;
- u32 sram_size, dram_size, regs;
- struct sliccore_hdr corehdr;
- u32 file_offset;
- char *namestr;
- u32 i;
- u32 max_queues = 0;
- u32 result;
-
- card->dumphandle = slic_dump_open_file(card);
-
- if (card->dumphandle == NULL) {
- DBG_MSG("[slicmon] Cant create Dump file - dump failed\n");
- return -ENOMEM;
- }
- if (!card->dumpbuffer) {
- DBG_MSG("[slicmon] Insufficient memory for dump\n");
- return -ENOMEM;
- }
- if (!card->cmdbuffer) {
- DBG_MSG("[slicmon] Insufficient cmd memory for dump\n");
- return -ENOMEM;
- }
-
- /*
- * Write the file version to the core header.
- */
- namestr = slic_proc_version;
- for (i = 0; i < (DRIVER_NAME_SIZE - 1); i++, namestr++) {
- if (!namestr)
- break;
- corehdr.driver_version[i] = *namestr;
- }
- corehdr.driver_version[i] = 0;
-
- file_offset = sizeof(struct sliccore_hdr);
-
- /*
- * Issue the following debug commands to the SLIC:
- * - Halt both receive and transmit
- * - Dump receive registers
- * - Dump transmit registers
- * - Dump sram
- * - Dump dram
- * - Dump queues
- */
- DBG_MSG("slicDump HALT Receive Processor\n");
- card->dumptime_start = jiffies;
-
- status = slic_dump_halt(card, PROC_RECEIVE);
- if (status != STATUS_SUCCESS) {
- DBG_ERROR
- ("Cant halt receive sequencer - dump failed status[%x]\n",
- status);
- goto done;
- }
-
- DBG_MSG("slicDump HALT Transmit Processor\n");
- status = slic_dump_halt(card, PROC_TRANSMIT);
- if (status != STATUS_SUCCESS) {
- DBG_ERROR("Cant halt transmit sequencer - dump failed\n");
- goto done;
- }
-
- /* Dump receive regs */
- status = slic_dump_reg(card, PROC_RECEIVE);
- if (status != STATUS_SUCCESS) {
- DBG_ERROR("Cant dump receive registers - dump failed\n");
- goto done;
- }
-
- DBG_MSG("slicDump Write Receive REGS len[%x] offset[%x]\n",
- (SLIC_NUM_REG * 4), file_offset);
-
- result =
- slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
- file_offset);
- if (!result) {
- DBG_ERROR
- ("Cant write rcv registers to dump file - dump failed\n");
- goto done;
- }
-
- corehdr.RcvRegOff = file_offset;
- corehdr.RcvRegsize = SLIC_NUM_REG * 4;
- file_offset += SLIC_NUM_REG * 4;
-
- /* Dump transmit regs */
- status = slic_dump_reg(card, PROC_TRANSMIT);
- if (status != STATUS_SUCCESS) {
- DBG_ERROR("Cant dump transmit registers - dump failed\n");
- goto done;
- }
-
- DBG_MSG("slicDump Write XMIT REGS len[%x] offset[%x]\n",
- (SLIC_NUM_REG * 4), file_offset);
-
- result =
- slic_dump_write(card, card->dumpbuffer, SLIC_NUM_REG * 4,
- file_offset);
- if (!result) {
- DBG_ERROR
- ("Cant write xmt registers to dump file - dump failed\n");
- goto done;
- }
-
- corehdr.XmtRegOff = file_offset;
- corehdr.XmtRegsize = SLIC_NUM_REG * 4;
- file_offset += SLIC_NUM_REG * 4;
-
- regs = SLIC_GBMAX_REG;
-
- corehdr.FileRegOff = file_offset;
- corehdr.FileRegsize = regs * 4;
-
- for (offset = 0; regs;) {
- len = MIN(regs, 16); /* Can only xfr 16 regs at a time */
-
- status = slic_dump_data(card, offset, (ushort) len, DESC_RFILE);
-
- if (status != STATUS_SUCCESS) {
- DBG_ERROR("Cant dump register file - dump failed\n");
- goto done;
- }
-
- DBG_MSG("slicDump Write RegisterFile len[%x] offset[%x]\n",
- (len * 4), file_offset);
-
- result =
- slic_dump_write(card, card->dumpbuffer, len * 4,
- file_offset);
- if (!result) {
- DBG_ERROR
- ("Cant write register file to dump file - "
- "dump failed\n");
- goto done;
- }
-
- file_offset += len * 4;
- offset += len;
- regs -= len;
- }
-
- dram_size = card->config.DramSize * 0x10000;
-
- switch (adapter->devid) {
- case SLIC_2GB_DEVICE_ID:
- sram_size = SLIC_SRAM_SIZE2GB;
- break;
- case SLIC_1GB_DEVICE_ID:
- sram_size = SLIC_SRAM_SIZE1GB;
- break;
- default:
- sram_size = 0;
- ASSERT(0);
- break;
- }
-
- corehdr.SramOff = file_offset;
- corehdr.Sramsize = sram_size;
-
- for (offset = 0; sram_size;) {
- len = MIN(sram_size, DUMP_BUF_SIZE);
- status = slic_dump_data(card, offset, (ushort) len, DESC_SRAM);
- if (status != STATUS_SUCCESS) {
- DBG_ERROR
- ("[slicmon] Cant dump SRAM at offset %x - "
- "dump failed\n", (uint) offset);
- goto done;
- }
-
- DBG_MSG("[slicmon] slicDump Write SRAM len[%x] offset[%x]\n",
- len, file_offset);
-
- result =
- slic_dump_write(card, card->dumpbuffer, len, file_offset);
- if (!result) {
- DBG_ERROR
- ("[slicmon] Cant write SRAM to dump file - "
- "dump failed\n");
- goto done;
- }
-
- file_offset += len;
- offset += len;
- sram_size -= len;
- }
-
- corehdr.DramOff = file_offset;
- corehdr.Dramsize = dram_size;
-
- for (offset = 0; dram_size;) {
- len = MIN(dram_size, DUMP_BUF_SIZE);
-
- status = slic_dump_data(card, offset, (ushort) len, DESC_DRAM);
- if (status != STATUS_SUCCESS) {
- DBG_ERROR
- ("[slicmon] Cant dump dram at offset %x - "
- "dump failed\n", (uint) offset);
- goto done;
- }
-
- DBG_MSG("slicDump Write DRAM len[%x] offset[%x]\n", len,
- file_offset);
-
- result =
- slic_dump_write(card, card->dumpbuffer, len, file_offset);
- if (!result) {
- DBG_ERROR
- ("[slicmon] Cant write DRAM to dump file - "
- "dump failed\n");
- goto done;
- }
-
- file_offset += len;
- offset += len;
- dram_size -= len;
- }
-
- max_queues = SLIC_MAX_QUEUE;
-
- for (queue = 0; queue < max_queues; queue++) {
- u32 *qarray = (u32 *) card->dumpbuffer;
- u32 qarray_physl = card->dumpbuffer_physl;
- u32 qarray_physh = card->dumpbuffer_physh;
- u32 qstart;
- u32 qdelta;
- u32 qtotal = 0;
-
- DBG_MSG("[slicmon] Start Dump of QUEUE #0x%x\n", (uint) queue);
-
- for (offset = 0; offset < (DUMP_BUF_SIZE >> 2); offset++) {
- qstart = jiffies;
- qdelta = 0;
-
- status = slic_dump_queue(card,
- qarray_physl,
- qarray_physh, queue);
- qarray_physl += 4;
-
- if (status != STATUS_SUCCESS)
- break;
-
- if (jiffies > qstart) {
- qdelta = jiffies - qstart;
- qtotal += qdelta;
- }
- }
-
- if (offset)
- qdelta = qtotal / offset;
- else
- qdelta = 0;
-
-/* DBG_MSG(" slicDump Write QUEUE #0x%x len[%x] offset[%x] "
- "avgjiffs[%x]\n", queue, (offset*4), file_offset, qdelta); */
-
- result =
- slic_dump_write(card, card->dumpbuffer, offset * 4,
- file_offset);
-
- if (!result) {
- DBG_ERROR
- ("[slicmon] Cant write QUEUES to dump file - "
- "dump failed\n");
- goto done;
- }
-
- corehdr.queues[queue].queueOff = file_offset;
- corehdr.queues[queue].queuesize = offset * 4;
- file_offset += offset * 4;
-
-/* DBG_MSG(" Reload QUEUE #0x%x elements[%x]\n", (uint)queue, offset);*/
- /*
- * Fill the queue back up
- */
- for (i = 0; i < offset; i++) {
- qstart = jiffies;
- qdelta = 0;
-
- status = slic_dump_load_queue(card, qarray[i], queue);
- if (status != STATUS_SUCCESS)
- break;
-
- if (jiffies > qstart) {
- qdelta = jiffies - qstart;
- qtotal += qdelta;
- }
- }
-
- if (offset)
- qdelta = qtotal / offset;
- else
- qdelta = 0;
-
-/* DBG_MSG(" Reload DONE avgjiffs[%x]\n", qdelta); */
-
- resume = 1;
- }
-
- len = SLIC_GB_CAMAB_SZE * 4;
- status = slic_dump_cam(card, 0, len, DUMP_CAM_A);
- if (status != STATUS_SUCCESS) {
- DBG_ERROR("[slicmon] Can't dump CAM_A - dump failed\n");
- goto done;
- }
-
- result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
- if (result) {
- DBG_ERROR
- ("[slicmon] Can't write CAM_A data to dump file - "
- "dump failed\n");
- goto done;
- }
- corehdr.CamAMOff = file_offset;
- corehdr.CamASize = len;
- file_offset += len;
-
- len = SLIC_GB_CAMCD_SZE * 4;
- status = slic_dump_cam(card, 0, len, DUMP_CAM_C);
- if (status) {
- DBG_ERROR("[slicmon] Can't dump CAM_C - dump failed\n");
- goto done;
- }
-
- result = slic_dump_write(card, card->dumpbuffer, len, file_offset);
- if (result) {
- DBG_ERROR
- ("[slicmon] Can't write CAM_C data to dump file - "
- "dump failed\n");
- goto done;
- }
- corehdr.CamCMOff = file_offset;
- corehdr.CamCSize = len;
- file_offset += len;
-
-done:
- /*
- * Write out the core header
- */
- file_offset = 0;
- DBG_MSG("[slicmon] Write CoreHeader len[%x] offset[%x]\n",
- (uint) sizeof(struct sliccore_hdr), file_offset);
-
- result =
- slic_dump_write(card, &corehdr, sizeof(struct sliccore_hdr),
- file_offset);
- DBG_MSG("[slicmon] corehdr xoff[%x] xsz[%x]\n"
- " roff[%x] rsz[%x] fileoff[%x] filesz[%x]\n"
- " sramoff[%x] sramsz[%x], dramoff[%x] dramsz[%x]\n"
- " corehdr_offset[%x]\n", corehdr.XmtRegOff,
- corehdr.XmtRegsize, corehdr.RcvRegOff, corehdr.RcvRegsize,
- corehdr.FileRegOff, corehdr.FileRegsize, corehdr.SramOff,
- corehdr.Sramsize, corehdr.DramOff, corehdr.Dramsize,
- (uint) sizeof(struct sliccore_hdr));
- for (i = 0; i < max_queues; i++) {
- DBG_MSG("[slicmon] QUEUE 0x%x offset[%x] size[%x]\n",
- (uint) i, corehdr.queues[i].queueOff,
- corehdr.queues[i].queuesize);
-
- }
-
- slic_dump_close_file(card);
-
- if (resume) {
- DBG_MSG("slicDump RESTART RECEIVE and XMIT PROCESSORS\n\n");
- slic_dump_resume(card, PROC_RECEIVE);
- slic_dump_resume(card, PROC_TRANSMIT);
- }
-
- return status;
-}
-
-static u32 slic_dump_halt(struct sliccard *card, unsigned char proc)
-{
- unsigned char *cmd = card->cmdbuffer;
-
- *cmd = COMMAND_BYTE(CMD_HALT, 0, proc);
-
- return slic_dump_send_cmd(card,
- card->cmdbuffer_physl,
- card->cmdbuffer_physh, 0, 0);
-}
-
-static u32 slic_dump_resume(struct sliccard *card, unsigned char proc)
-{
- unsigned char *cmd = card->cmdbuffer;
-
- *cmd = COMMAND_BYTE(CMD_RUN, 0, proc);
-
- return slic_dump_send_cmd(card,
- card->cmdbuffer_physl,
- card->cmdbuffer_physh, 0, 0);
-}
-
-static u32 slic_dump_reg(struct sliccard *card, unsigned char proc)
-{
- struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
- dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, proc);
- dump->desc = DESC_REG;
- dump->count = 0;
- dump->addr = 0;
-
- return slic_dump_send_cmd(card,
- card->cmdbuffer_physl,
- card->cmdbuffer_physh,
- card->dumpbuffer_physl,
- card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_data(struct sliccard *card,
- u32 addr, ushort count, unsigned char desc)
-{
- struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
- dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
- dump->desc = desc;
- dump->count = count;
- dump->addr = addr;
-
- return slic_dump_send_cmd(card,
- card->cmdbuffer_physl,
- card->cmdbuffer_physh,
- card->dumpbuffer_physl,
- card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_queue(struct sliccard *card,
- u32 addr, u32 buf_physh, u32 queue)
-{
- struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
- dump->cmd = COMMAND_BYTE(CMD_DUMP, 0, PROC_RECEIVE);
- dump->desc = DESC_QUEUE;
- dump->count = 1;
- dump->addr = queue;
-
- return slic_dump_send_cmd(card,
- card->cmdbuffer_physl,
- card->cmdbuffer_physh,
- addr, card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_load_queue(struct sliccard *card, u32 data,
- u32 queue)
-{
- struct dump_cmd *load = (struct dump_cmd *) card->cmdbuffer;
-
- load->cmd = COMMAND_BYTE(CMD_LOAD, 0, PROC_RECEIVE);
- load->desc = DESC_QUEUE;
- load->count = (ushort) queue;
- load->addr = data;
-
- return slic_dump_send_cmd(card,
- card->cmdbuffer_physl,
- card->cmdbuffer_physh, 0, 0);
-}
-
-static u32 slic_dump_cam(struct sliccard *card,
- u32 addr, u32 count, unsigned char desc)
-{
- struct dump_cmd *dump = (struct dump_cmd *)card->cmdbuffer;
-
- dump->cmd = COMMAND_BYTE(CMD_CAM_OPS, 0, PROC_NONE);
- dump->desc = desc;
- dump->count = count;
- dump->addr = 0;
-
- return slic_dump_send_cmd(card,
- card->cmdbuffer_physl,
- card->cmdbuffer_physh,
- addr, card->dumpbuffer_physh);
-}
-
-static u32 slic_dump_send_cmd(struct sliccard *card,
- u32 cmd_physl,
- u32 cmd_physh,
- u32 buf_physl, u32 buf_physh)
-{
- ulong timeout = SLIC_MS_TO_JIFFIES(500); /* 500 msec */
- u32 attempts = 5;
- u32 delay = SLIC_MS_TO_JIFFIES(10); /* 10 msec */
- struct adapter *adapter = card->master;
-
- ASSERT(adapter);
- do {
- /*
- * Zero the Dumpstatus field of the adapter structure
- */
- card->dumpstatus = 0;
- /*
- * Issue the dump command via a utility processor request.
- *
- * Kludge: We use the Informationbuffer parameter to hold
- * the buffer address
- */
- slic_upr_request(adapter, SLIC_UPR_DUMP, cmd_physl, cmd_physh,
- buf_physl, buf_physh);
-
- timeout += jiffies;
- /*
- * Spin until completion or timeout.
- */
- while (!card->dumpstatus) {
- int num_sleeps = 0;
-
- if (jiffies > timeout) {
- /*
- * Complete the timed-out DUMP UPR request.
- */
- slic_upr_request_complete(adapter, 0);
- DBG_ERROR
- ("%s: TIMED OUT num_sleeps[%x] "
- "status[%x]\n",
- __func__, num_sleeps, STATUS_FAILURE);
-
- return STATUS_FAILURE;
- }
- num_sleeps++;
- SLIC_INTERRUPTIBLE_SLEEP_ON_TIMEOUT(card->dump_wq,
- delay);
- }
-
- if (card->dumpstatus & ISR_UPCERR) {
- /*
- * Error (or queue empty)
- */
-/* DBG_ERROR("[slicmon] %s: DUMP_STATUS & ISR_UPCERR status[%x]\n",
- __func__, STATUS_FAILURE); */
-
- return STATUS_FAILURE;
- } else if (card->dumpstatus & ISR_UPCBSY) {
- /*
- * Retry
- */
- DBG_ERROR("%s: ISR_UPCBUSY attempt[%x]\n", __func__,
- attempts);
-
- attempts--;
- } else {
- /*
- * success
- */
- return STATUS_SUCCESS;
- }
-
- } while (attempts);
-
- DBG_ERROR("%s: GAVE UP AFTER SEVERAL ATTEMPTS status[%x]\n",
- __func__, STATUS_FAILURE);
-
- /*
- * Gave up after several attempts
- */
- return STATUS_FAILURE;
-}
-
-#endif
-/*=============================================================================
- =============================================================================
- === ===
- === *** END **** END **** END **** END *** ===
- === SLIC DUMP MANAGEMENT SECTION ===
- === ===
- === ===
- === ===
- =============================================================================
- ============================================================================*/
-
/******************************************************************************/
/**************** MODULE INITIATION / TERMINATION FUNCTIONS ***************/
/******************************************************************************/
@@ -5915,46 +4043,25 @@ static struct pci_driver slic_driver = {
.id_table = slic_pci_tbl,
.probe = slic_entry_probe,
.remove = slic_entry_remove,
-#if SLIC_POWER_MANAGEMENT_ENABLED
- .suspend = slicpm_suspend,
- .resume = slicpm_resume,
-#endif
-/* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
};
static int __init slic_module_init(void)
{
- struct pci_device_id *pcidev;
- int ret;
-
-/* DBG_MSG("slicoss: %s ENTER cpu %d\n", __func__, smp_processor_id()); */
-
slic_init_driver();
if (debug >= 0 && slic_debug != debug)
- printk(SLICLEVEL "slicoss: debug level is %d.\n", debug);
+ printk(KERN_DEBUG KBUILD_MODNAME ": debug level is %d.\n",
+ debug);
if (debug >= 0)
slic_debug = debug;
- pcidev = (struct pci_device_id *)slic_driver.id_table;
-/* DBG_MSG("slicoss: %s call pci_module_init jiffies[%lx] cpu #%d\n",
- __func__, jiffies, smp_processor_id()); */
-
- ret = pci_register_driver(&slic_driver);
-
-/* DBG_MSG("slicoss: %s EXIT after call pci_module_init jiffies[%lx] "
- "cpu #%d status[%x]\n",__func__, jiffies,
- smp_processor_id(), ret); */
-
- return ret;
+ return pci_register_driver(&slic_driver);
}
static void __exit slic_module_cleanup(void)
{
-/* DBG_MSG("slicoss: %s ENTER\n", __func__); */
pci_unregister_driver(&slic_driver);
slic_debug_cleanup();
-/* DBG_MSG("slicoss: %s EXIT\n", __func__); */
}
module_init(slic_module_init);
diff --git a/drivers/staging/stlc45xx/Kconfig b/drivers/staging/stlc45xx/Kconfig
new file mode 100644
index 00000000000..8d3f46f190e
--- /dev/null
+++ b/drivers/staging/stlc45xx/Kconfig
@@ -0,0 +1,8 @@
+config STLC45XX
+ tristate "stlc4550/4560 support"
+ depends on MAC80211 && WLAN_80211 && SPI_MASTER
+ ---help---
+ This is a driver for stlc4550 and stlc4560 chipsets.
+
+ To compile this driver as a module, choose M here: the module will be
+ called stlc45xx. If unsure, say N.
diff --git a/drivers/staging/stlc45xx/Makefile b/drivers/staging/stlc45xx/Makefile
new file mode 100644
index 00000000000..7ee32903055
--- /dev/null
+++ b/drivers/staging/stlc45xx/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_STLC45XX) += stlc45xx.o
diff --git a/drivers/staging/stlc45xx/stlc45xx.c b/drivers/staging/stlc45xx/stlc45xx.c
new file mode 100644
index 00000000000..3eced5520c5
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx.c
@@ -0,0 +1,2606 @@
+/*
+ * This file is part of stlc45xx
+ *
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include "stlc45xx.h"
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/spi/spi.h>
+#include <linux/etherdevice.h>
+#include <linux/gpio.h>
+#include <linux/moduleparam.h>
+
+#include "stlc45xx_lmac.h"
+
+/*
+ * gpios should be handled in board files and provided via platform data,
+ * but because it's currently impossible for stlc45xx to have a header file
+ * in include/linux, let's use module paramaters for now
+ */
+static int stlc45xx_gpio_power = 97;
+module_param(stlc45xx_gpio_power, int, 0444);
+MODULE_PARM_DESC(stlc45xx_gpio_power, "stlc45xx gpio number for power line");
+
+static int stlc45xx_gpio_irq = 87;
+module_param(stlc45xx_gpio_irq, int, 0444);
+MODULE_PARM_DESC(stlc45xx_gpio_irq, "stlc45xx gpio number for irq line");
+
+static const u8 default_cal_channels[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x09,
+ 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xe0, 0x00, 0xe0, 0x00,
+ 0xe0, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
+ 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
+ 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9,
+ 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
+ 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d,
+ 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17,
+ 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00,
+ 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x71, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8,
+ 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0,
+ 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6,
+ 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
+ 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca,
+ 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21,
+ 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00,
+ 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0,
+ 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
+ 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0,
+ 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+ 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
+ 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37,
+ 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b,
+ 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00,
+ 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0,
+ 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a,
+ 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x09, 0x00, 0x00, 0xc9, 0xff,
+ 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
+ 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab,
+ 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33,
+ 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00,
+ 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0,
+ 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7,
+ 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d,
+ 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x80, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
+ 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42,
+ 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01,
+ 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0,
+ 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0,
+ 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17,
+ 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
+ 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x09, 0x00, 0x00, 0xc9,
+ 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+ 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01,
+ 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0,
+ 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb,
+ 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21,
+ 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
+ 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0,
+ 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
+ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x8a, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00,
+ 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0,
+ 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0,
+ 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22,
+ 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b,
+ 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
+ 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0,
+ 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
+ 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x09, 0x00, 0x00,
+ 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10,
+ 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
+ 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54,
+ 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33,
+ 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
+ 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0,
+ 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
+ 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c,
+ 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00,
+ 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
+ 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0,
+ 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42,
+ 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
+ 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0,
+ 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
+ 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d,
+ 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
+ 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x09, 0x00,
+ 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01,
+ 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
+ 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
+ 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
+ 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0,
+ 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc,
+ 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
+ 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54,
+ 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00,
+ 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
+ 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06,
+ 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96,
+ 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x9e, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff,
+ 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
+ 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00,
+ 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0,
+ 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb,
+ 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
+ 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
+ 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
+ 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79,
+ 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00,
+ 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
+ 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
+ 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
+ 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9,
+ 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0,
+ 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
+ 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d,
+ 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
+ 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00 };
+
+static const u8 default_cal_rssi[] = {
+ 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72,
+ 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00,
+ 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a,
+ 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe,
+ 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00,
+ 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01,
+ 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a,
+ 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00 };
+
+static void stlc45xx_tx_edcf(struct stlc45xx *stlc);
+static void stlc45xx_tx_setup(struct stlc45xx *stlc);
+static void stlc45xx_tx_scan(struct stlc45xx *stlc);
+static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable);
+static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave);
+static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave);
+
+static ssize_t stlc45xx_sysfs_show_cal_rssi(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+ ssize_t len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ len = PAGE_SIZE;
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->cal_rssi)
+ hex_dump_to_buffer(stlc->cal_rssi, RSSI_CAL_ARRAY_LEN, 16,
+ 2, buf, len, 0);
+ mutex_unlock(&stlc->mutex);
+
+ len = strlen(buf);
+
+ return len;
+}
+
+static ssize_t stlc45xx_sysfs_store_cal_rssi(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ if (count != RSSI_CAL_ARRAY_LEN) {
+ stlc45xx_error("invalid cal_rssi length: %zu", count);
+ count = 0;
+ goto out_unlock;
+ }
+
+ kfree(stlc->cal_rssi);
+
+ stlc->cal_rssi = kmemdup(buf, RSSI_CAL_ARRAY_LEN, GFP_KERNEL);
+
+ if (!stlc->cal_rssi) {
+ stlc45xx_error("failed to allocate memory for cal_rssi");
+ count = 0;
+ goto out_unlock;
+ }
+
+ out_unlock:
+ mutex_unlock(&stlc->mutex);
+
+ return count;
+}
+
+static ssize_t stlc45xx_sysfs_show_cal_channels(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+ ssize_t len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ len = PAGE_SIZE;
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->cal_channels)
+ hex_dump_to_buffer(stlc->cal_channels, CHANNEL_CAL_ARRAY_LEN,
+ 16, 2, buf, len, 0);
+
+ mutex_unlock(&stlc->mutex);
+
+ len = strlen(buf);
+
+ return len;
+}
+
+static ssize_t stlc45xx_sysfs_store_cal_channels(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ if (count != CHANNEL_CAL_ARRAY_LEN) {
+ stlc45xx_error("invalid cal_channels size: %zu ", count);
+ count = 0;
+ goto out_unlock;
+ }
+
+ kfree(stlc->cal_channels);
+
+ stlc->cal_channels = kmemdup(buf, count, GFP_KERNEL);
+
+ if (!stlc->cal_channels) {
+ stlc45xx_error("failed to allocate memory for cal_channels");
+ count = 0;
+ goto out_unlock;
+ }
+
+out_unlock:
+ mutex_unlock(&stlc->mutex);
+
+ return count;
+}
+
+static ssize_t stlc45xx_sysfs_show_tx_buf(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(dev);
+ struct txbuffer *entry;
+ ssize_t len = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
+ len += sprintf(buf + len, "0x%x: 0x%x-0x%x\n",
+ entry->handle, entry->start,
+ entry->end);
+ }
+
+ mutex_unlock(&stlc->mutex);
+
+ return len;
+}
+
+static DEVICE_ATTR(cal_rssi, S_IRUGO | S_IWUSR,
+ stlc45xx_sysfs_show_cal_rssi,
+ stlc45xx_sysfs_store_cal_rssi);
+static DEVICE_ATTR(cal_channels, S_IRUGO | S_IWUSR,
+ stlc45xx_sysfs_show_cal_channels,
+ stlc45xx_sysfs_store_cal_channels);
+static DEVICE_ATTR(tx_buf, S_IRUGO, stlc45xx_sysfs_show_tx_buf, NULL);
+
+static void stlc45xx_spi_read(struct stlc45xx *stlc, unsigned long addr,
+ void *buf, size_t len)
+{
+ struct spi_transfer t[2];
+ struct spi_message m;
+
+ /* We first push the address */
+ addr = (addr << 8) | ADDR_READ_BIT_15;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = 2;
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].rx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ spi_sync(stlc->spi, &m);
+}
+
+
+static void stlc45xx_spi_write(struct stlc45xx *stlc, unsigned long addr,
+ void *buf, size_t len)
+{
+ struct spi_transfer t[3];
+ struct spi_message m;
+ u16 last_word;
+
+ /* We first push the address */
+ addr = addr << 8;
+
+ spi_message_init(&m);
+ memset(t, 0, sizeof(t));
+
+ t[0].tx_buf = &addr;
+ t[0].len = 2;
+ spi_message_add_tail(&t[0], &m);
+
+ t[1].tx_buf = buf;
+ t[1].len = len;
+ spi_message_add_tail(&t[1], &m);
+
+ if (len % 2) {
+ last_word = ((u8 *)buf)[len - 1];
+
+ t[2].tx_buf = &last_word;
+ t[2].len = 2;
+ spi_message_add_tail(&t[2], &m);
+ }
+
+ spi_sync(stlc->spi, &m);
+}
+
+static u16 stlc45xx_read16(struct stlc45xx *stlc, unsigned long addr)
+{
+ u16 val;
+
+ stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
+
+ return val;
+}
+
+static u32 stlc45xx_read32(struct stlc45xx *stlc, unsigned long addr)
+{
+ u32 val;
+
+ stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
+
+ return val;
+}
+
+static void stlc45xx_write16(struct stlc45xx *stlc, unsigned long addr, u16 val)
+{
+ stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
+}
+
+static void stlc45xx_write32(struct stlc45xx *stlc, unsigned long addr, u32 val)
+{
+ stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
+}
+
+struct stlc45xx_spi_reg {
+ u16 address;
+ u16 length;
+ char *name;
+};
+
+/* caller must hold tx_lock */
+static void stlc45xx_txbuffer_dump(struct stlc45xx *stlc)
+{
+ struct txbuffer *txbuffer;
+ char *buf, *pos;
+ int buf_len, l, count;
+
+ if (!(DEBUG_LEVEL & DEBUG_TXBUFFER))
+ return;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ buf_len = 500;
+ buf = kmalloc(buf_len, GFP_ATOMIC);
+ if (!buf)
+ return;
+
+ pos = buf;
+ count = 0;
+
+ list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
+ l = snprintf(pos, buf_len, "0x%x-0x%x,",
+ txbuffer->start, txbuffer->end);
+ /* drop the null byte */
+ pos += l;
+ buf_len -= l;
+ count++;
+ }
+
+ if (count == 0)
+ *pos = '\0';
+ else
+ *--pos = '\0';
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: in buffer %d regions: %s",
+ count, buf);
+
+ kfree(buf);
+}
+
+/* caller must hold tx_lock */
+static int stlc45xx_txbuffer_find(struct stlc45xx *stlc, size_t len)
+{
+ struct txbuffer *txbuffer;
+ int pos;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ pos = FIRMWARE_TXBUFFER_START;
+
+ if (list_empty(&stlc->txbuffer))
+ goto out;
+
+ /*
+ * the entries in txbuffer must be in the same order as they are in
+ * the real buffer
+ */
+ list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
+ if (pos + len < txbuffer->start)
+ break;
+ pos = ALIGN(txbuffer->end + 1, 4);
+ }
+
+ if (pos + len > FIRMWARE_TXBUFFER_END)
+ /* not enough room */
+ pos = -1;
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: find %zu B: 0x%x", len, pos);
+
+out:
+ return pos;
+}
+
+static int stlc45xx_txbuffer_add(struct stlc45xx *stlc,
+ struct txbuffer *txbuffer)
+{
+ struct txbuffer *r, *prev = NULL;
+
+ if (list_empty(&stlc->txbuffer)) {
+ list_add(&txbuffer->buffer_list, &stlc->txbuffer);
+ return 0;
+ }
+
+ r = list_first_entry(&stlc->txbuffer, struct txbuffer, buffer_list);
+
+ if (txbuffer->start < r->start) {
+ /* add to the beginning of the list */
+ list_add(&txbuffer->buffer_list, &stlc->txbuffer);
+ return 0;
+ }
+
+ prev = NULL;
+ list_for_each_entry(r, &stlc->txbuffer, buffer_list) {
+ /* skip first entry, we checked for that above */
+ if (!prev) {
+ prev = r;
+ continue;
+ }
+
+ /* double-check overlaps */
+ WARN_ON_ONCE(txbuffer->start >= r->start &&
+ txbuffer->start <= r->end);
+ WARN_ON_ONCE(txbuffer->end >= r->start &&
+ txbuffer->end <= r->end);
+
+ if (prev->end < txbuffer->start &&
+ txbuffer->end < r->start) {
+ /* insert at this spot */
+ list_add_tail(&txbuffer->buffer_list, &r->buffer_list);
+ return 0;
+ }
+
+ prev = r;
+ }
+
+ /* not found */
+ list_add_tail(&txbuffer->buffer_list, &stlc->txbuffer);
+
+ return 0;
+
+}
+
+/* caller must hold tx_lock */
+static struct txbuffer *stlc45xx_txbuffer_alloc(struct stlc45xx *stlc,
+ size_t frame_len)
+{
+ struct txbuffer *entry = NULL;
+ size_t len;
+ int pos;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ len = FIRMWARE_TXBUFFER_HEADER + frame_len + FIRMWARE_TXBUFFER_TRAILER;
+ pos = stlc45xx_txbuffer_find(stlc, len);
+
+ if (pos < 0)
+ return NULL;
+
+ WARN_ON_ONCE(pos + len > FIRMWARE_TXBUFFER_END);
+ WARN_ON_ONCE(pos < FIRMWARE_TXBUFFER_START);
+
+ entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+ entry->start = pos;
+ entry->frame_start = pos + FIRMWARE_TXBUFFER_HEADER;
+ entry->end = entry->start + len - 1;
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: allocated 0x%x-0x%x",
+ entry->start, entry->end);
+
+ stlc45xx_txbuffer_add(stlc, entry);
+
+ stlc45xx_txbuffer_dump(stlc);
+
+ return entry;
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_txbuffer_free(struct stlc45xx *stlc,
+ struct txbuffer *txbuffer)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
+
+ stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: freed 0x%x-0x%x",
+ txbuffer->start, txbuffer->end);
+
+ list_del(&txbuffer->buffer_list);
+ kfree(txbuffer);
+}
+
+
+static int stlc45xx_wait_bit(struct stlc45xx *stlc, u16 reg, u32 mask,
+ u32 expected)
+{
+ int i;
+ char buffer[4];
+
+ for (i = 0; i < 2000; i++) {
+ stlc45xx_spi_read(stlc, reg, buffer, sizeof(buffer));
+ if (((*(u32 *)buffer) & mask) == expected)
+ return 1;
+ msleep(1);
+ }
+
+ return 0;
+}
+
+static int stlc45xx_request_firmware(struct stlc45xx *stlc)
+{
+ const struct firmware *fw;
+ int ret;
+
+ /* FIXME: should driver use it's own struct device? */
+ ret = request_firmware(&fw, "3826.arm", &stlc->spi->dev);
+
+ if (ret < 0) {
+ stlc45xx_error("request_firmware() failed: %d", ret);
+ return ret;
+ }
+
+ if (fw->size % 4) {
+ stlc45xx_error("firmware size is not multiple of 32bit: %zu",
+ fw->size);
+ return -EILSEQ; /* Illegal byte sequence */;
+ }
+
+ if (fw->size < 1000) {
+ stlc45xx_error("firmware is too small: %zu", fw->size);
+ return -EILSEQ;
+ }
+
+ stlc->fw = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ if (!stlc->fw) {
+ stlc45xx_error("could not allocate memory for firmware");
+ return -ENOMEM;
+ }
+
+ stlc->fw_len = fw->size;
+
+ release_firmware(fw);
+
+ return 0;
+}
+
+static int stlc45xx_upload_firmware(struct stlc45xx *stlc)
+{
+ struct s_dma_regs dma_regs;
+ unsigned long fw_len, fw_addr;
+ long _fw_len;
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ if (!stlc->fw) {
+ ret = stlc45xx_request_firmware(stlc);
+ if (ret < 0)
+ return ret;
+ }
+
+ /* stop the device */
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
+ | SPI_CTRL_STAT_START_HALTED);
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE
+ | SPI_CTRL_STAT_START_HALTED);
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ fw_addr = FIRMWARE_ADDRESS;
+ fw_len = stlc->fw_len;
+
+ while (fw_len > 0) {
+ _fw_len = (fw_len > SPI_MAX_PACKET_SIZE)
+ ? SPI_MAX_PACKET_SIZE : fw_len;
+ dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
+ dma_regs.len = cpu_to_le16(_fw_len);
+ dma_regs.addr = cpu_to_le32(fw_addr);
+
+ fw_len -= _fw_len;
+ fw_addr += _fw_len;
+
+ stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_CTRL, dma_regs.cmd);
+
+ if (stlc45xx_wait_bit(stlc, SPI_ADRS_DMA_WRITE_CTRL,
+ HOST_ALLOWED, HOST_ALLOWED) == 0) {
+ stlc45xx_error("fw_upload not allowed to DMA write");
+ return -EAGAIN;
+ }
+
+ stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_LEN, dma_regs.len);
+ stlc45xx_write32(stlc, SPI_ADRS_DMA_WRITE_BASE, dma_regs.addr);
+
+ stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, stlc->fw, _fw_len);
+
+ /* FIXME: I think this doesn't work if firmware is large,
+ * this loop goes to second round. fw->data is not
+ * increased at all! */
+ }
+
+ BUG_ON(fw_len != 0);
+
+ /* enable host interrupts */
+ stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
+
+ /* boot the device */
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
+ | SPI_CTRL_STAT_RAM_BOOT);
+
+ msleep(TARGET_BOOT_SLEEP);
+
+ stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
+ SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT);
+ msleep(TARGET_BOOT_SLEEP);
+
+ return 0;
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_check_txsent(struct stlc45xx *stlc)
+{
+ struct txbuffer *entry, *n;
+
+ list_for_each_entry_safe(entry, n, &stlc->tx_sent, tx_list) {
+ if (time_after(jiffies, entry->lifetime)) {
+ if (net_ratelimit())
+ stlc45xx_warning("frame 0x%x lifetime exceeded",
+ entry->start);
+ list_del(&entry->tx_list);
+ skb_pull(entry->skb, entry->header_len);
+ ieee80211_tx_status(stlc->hw, entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ }
+ }
+}
+
+static void stlc45xx_power_off(struct stlc45xx *stlc)
+{
+ disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+ gpio_set_value(stlc45xx_gpio_power, 0);
+}
+
+static void stlc45xx_power_on(struct stlc45xx *stlc)
+{
+ gpio_set_value(stlc45xx_gpio_power, 1);
+ enable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+
+ /*
+ * need to wait a while before device can be accessed, the length
+ * is just a guess
+ */
+ msleep(10);
+}
+
+/* caller must hold tx_lock */
+static void stlc45xx_flush_queues(struct stlc45xx *stlc)
+{
+ struct txbuffer *entry;
+
+ while (!list_empty(&stlc->tx_sent)) {
+ entry = list_first_entry(&stlc->tx_sent,
+ struct txbuffer, tx_list);
+ list_del(&entry->tx_list);
+ dev_kfree_skb(entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ }
+
+ WARN_ON(!list_empty(&stlc->tx_sent));
+
+ while (!list_empty(&stlc->tx_pending)) {
+ entry = list_first_entry(&stlc->tx_pending,
+ struct txbuffer, tx_list);
+ list_del(&entry->tx_list);
+ dev_kfree_skb(entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ }
+
+ WARN_ON(!list_empty(&stlc->tx_pending));
+ WARN_ON(!list_empty(&stlc->txbuffer));
+}
+
+static void stlc45xx_work_reset(struct work_struct *work)
+{
+ struct stlc45xx *stlc = container_of(work, struct stlc45xx,
+ work_reset);
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->fw_state != FW_STATE_RESET)
+ goto out;
+
+ stlc45xx_power_off(stlc);
+
+ mutex_unlock(&stlc->mutex);
+
+ /* wait that all work_structs have finished, we can't hold
+ * stlc->mutex to avoid deadlock */
+ cancel_work_sync(&stlc->work);
+
+ /* FIXME: find out good value to wait for chip power down */
+ msleep(100);
+
+ mutex_lock(&stlc->mutex);
+
+ /* FIXME: we should gracefully handle if the state has changed
+ * after re-acquiring mutex */
+ WARN_ON(stlc->fw_state != FW_STATE_RESET);
+
+ spin_lock_bh(&stlc->tx_lock);
+ stlc45xx_flush_queues(stlc);
+ spin_unlock_bh(&stlc->tx_lock);
+
+ stlc->fw_state = FW_STATE_RESETTING;
+
+ stlc45xx_power_on(stlc);
+ stlc45xx_upload_firmware(stlc);
+
+out:
+ mutex_unlock(&stlc->mutex);
+}
+
+/* caller must hold mutex */
+static void stlc45xx_reset(struct stlc45xx *stlc)
+{
+ stlc45xx_warning("resetting firmware");
+ stlc->fw_state = FW_STATE_RESET;
+ ieee80211_stop_queues(stlc->hw);
+ queue_work(stlc->hw->workqueue, &stlc->work_reset);
+}
+
+static void stlc45xx_work_tx_timeout(struct work_struct *work)
+{
+ struct stlc45xx *stlc = container_of(work, struct stlc45xx,
+ work_tx_timeout.work);
+
+ stlc45xx_warning("tx timeout");
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->fw_state != FW_STATE_READY)
+ goto out;
+
+ stlc45xx_reset(stlc);
+
+out:
+ mutex_unlock(&stlc->mutex);
+}
+
+static void stlc45xx_int_ack(struct stlc45xx *stlc, u32 val)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_ACK, val);
+}
+
+static void stlc45xx_wakeup(struct stlc45xx *stlc)
+{
+ unsigned long timeout;
+ u32 ints;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ /* wake the chip */
+ stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_WAKEUP);
+
+ /* And wait for the READY interrupt */
+ timeout = jiffies + HZ;
+
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ while (!(ints & SPI_HOST_INT_READY)) {
+ if (time_after(jiffies, timeout))
+ goto out;
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ }
+
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
+
+out:
+ return;
+}
+
+static void stlc45xx_sleep(struct stlc45xx *stlc)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_SLEEP);
+}
+
+static void stlc45xx_int_ready(struct stlc45xx *stlc)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN,
+ SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE);
+
+ switch (stlc->fw_state) {
+ case FW_STATE_BOOTING:
+ stlc->fw_state = FW_STATE_READY;
+ complete(&stlc->fw_comp);
+ break;
+ case FW_STATE_RESETTING:
+ stlc->fw_state = FW_STATE_READY;
+
+ stlc45xx_tx_scan(stlc);
+ stlc45xx_tx_setup(stlc);
+ stlc45xx_tx_edcf(stlc);
+
+ ieee80211_wake_queues(stlc->hw);
+ break;
+ default:
+ break;
+ }
+}
+
+static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info;
+ struct s_lm_control *control;
+ struct s_lmo_tx *tx;
+ struct txbuffer *entry;
+ int found = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ control = (struct s_lm_control *) skb->data;
+ tx = (struct s_lmo_tx *) (control + 1);
+
+ if (list_empty(&stlc->tx_sent)) {
+ if (net_ratelimit())
+ stlc45xx_warning("no frames waiting for "
+ "acknowledgement");
+ return -1;
+ }
+
+ list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
+ if (control->handle == entry->handle) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (!found) {
+ if (net_ratelimit())
+ stlc45xx_warning("couldn't find frame for tx ack 0x%x",
+ control->handle);
+ return -1;
+ }
+
+ stlc45xx_debug(DEBUG_TX, "TX ACK 0x%x", entry->handle);
+
+ if (entry->status_needed) {
+ info = IEEE80211_SKB_CB(entry->skb);
+
+ if (!(tx->flags & LM_TX_FAILED)) {
+ /* frame was acked */
+ info->flags |= IEEE80211_TX_STAT_ACK;
+ info->status.ack_signal = tx->rcpi / 2 - 110;
+ }
+
+ skb_pull(entry->skb, entry->header_len);
+
+ ieee80211_tx_status(stlc->hw, entry->skb);
+ }
+
+ list_del(&entry->tx_list);
+
+ stlc45xx_check_txsent(stlc);
+ if (list_empty(&stlc->tx_sent))
+ /* there are no pending frames, we can stop the tx timeout
+ * timer */
+ cancel_delayed_work(&stlc->work_tx_timeout);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ stlc45xx_txbuffer_free(stlc, entry);
+
+ if (stlc->tx_queue_stopped &&
+ stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) != -1) {
+ stlc45xx_debug(DEBUG_QUEUE, "room in tx buffer, waking queues");
+ ieee80211_wake_queues(stlc->hw);
+ stlc->tx_queue_stopped = 0;
+ }
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ return 0;
+}
+
+static int stlc45xx_rx_control(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct s_lm_control *control;
+ int ret = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ control = (struct s_lm_control *) skb->data;
+
+ switch (control->oid) {
+ case LM_OID_TX:
+ ret = stlc45xx_rx_txack(stlc, skb);
+ break;
+ case LM_OID_SETUP:
+ case LM_OID_SCAN:
+ case LM_OID_TRAP:
+ case LM_OID_EDCF:
+ case LM_OID_KEYCACHE:
+ case LM_OID_PSM:
+ case LM_OID_STATS:
+ case LM_OID_LED:
+ default:
+ stlc45xx_warning("unhandled rx control oid %d\n",
+ control->oid);
+ break;
+ }
+
+ dev_kfree_skb(skb);
+
+ return ret;
+}
+
+/* copied from mac80211 */
+static void stlc45xx_parse_elems(u8 *start, size_t len,
+ struct stlc45xx_ie_tim **tim,
+ size_t *tim_len)
+{
+ size_t left = len;
+ u8 *pos = start;
+
+ while (left >= 2) {
+ u8 id, elen;
+
+ id = *pos++;
+ elen = *pos++;
+ left -= 2;
+
+ if (elen > left)
+ return;
+
+ switch (id) {
+ case WLAN_EID_TIM:
+ *tim = (struct stlc45xx_ie_tim *) pos;
+ *tim_len = elen;
+ break;
+ default:
+ break;
+ }
+
+ left -= elen;
+ pos += elen;
+ }
+}
+
+/*
+ * mac80211 doesn't have support for asking frames with PS-Poll, so let's
+ * implement in the driver for now. We have to add support to mac80211
+ * later.
+ */
+static int stlc45xx_check_more_data(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+ struct ieee80211_hdr *hdr;
+ size_t len;
+ u16 fc;
+
+ hdr = (void *) skb->data + sizeof(*data);
+ len = skb->len - sizeof(*data);
+
+ /* minimum frame length is the null frame length 24 bytes */
+ if (len < 24) {
+ stlc45xx_warning("invalid frame length when checking for "
+ "more data");
+ return -EINVAL;
+ }
+
+ fc = le16_to_cpu(hdr->frame_control);
+ if (!(fc & IEEE80211_FCTL_FROMDS))
+ /* this is not from DS */
+ return 0;
+
+ if (compare_ether_addr(hdr->addr1, stlc->mac_addr) != 0)
+ /* the frame was not for us */
+ return 0;
+
+ if (!(fc & IEEE80211_FCTL_MOREDATA)) {
+ /* AP has no more frames buffered for us */
+ stlc45xx_debug(DEBUG_PSM, "all buffered frames retrieved");
+ stlc->pspolling = false;
+ return 0;
+ }
+
+ /* MOREDATA bit is set, let's ask for a new frame from the AP */
+ stlc45xx_tx_pspoll(stlc, stlc->psm);
+
+ return 0;
+}
+
+/*
+ * mac80211 cannot read TIM from beacons, so let's add a hack to the
+ * driver. We have to add support to mac80211 later.
+ */
+static int stlc45xx_rx_data_beacon(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+ size_t len = skb->len, tim_len = 0, baselen, pvbmap_len;
+ struct ieee80211_mgmt *mgmt;
+ struct stlc45xx_ie_tim *tim = NULL;
+ int bmap_offset, index, aid_bit;
+
+ mgmt = (void *) skb->data + sizeof(*data);
+
+ baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
+ if (baselen > len) {
+ stlc45xx_warning("invalid baselen in beacon");
+ return -EINVAL;
+ }
+
+ stlc45xx_parse_elems(mgmt->u.beacon.variable, len - baselen, &tim,
+ &tim_len);
+
+ if (!tim) {
+ stlc45xx_warning("didn't find tim from a beacon");
+ return -EINVAL;
+ }
+
+ bmap_offset = tim->bmap_control & 0xfe;
+ index = stlc->aid / 8 - bmap_offset;
+
+ pvbmap_len = tim_len - 3;
+ if (index > pvbmap_len)
+ return -EINVAL;
+
+ aid_bit = !!(tim->pvbmap[index] & (1 << stlc->aid % 8));
+
+ stlc45xx_debug(DEBUG_PSM, "fc 0x%x duration %d seq %d dtim %u "
+ "bmap_control 0x%x aid_bit %d",
+ mgmt->frame_control, mgmt->duration, mgmt->seq_ctrl >> 4,
+ tim->dtim_count, tim->bmap_control, aid_bit);
+
+ if (!aid_bit)
+ return 0;
+
+ stlc->pspolling = true;
+ stlc45xx_tx_pspoll(stlc, stlc->psm);
+
+ return 0;
+}
+
+static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
+{
+ struct ieee80211_rx_status status;
+ struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
+ int align = 0;
+ u8 *p, align_len;
+ u16 len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ if (stlc->psm) {
+ if (data->flags & LM_IN_BEACON)
+ stlc45xx_rx_data_beacon(stlc, skb);
+ else if (stlc->pspolling && (data->flags & LM_IN_DATA))
+ stlc45xx_check_more_data(stlc, skb);
+ }
+
+ memset(&status, 0, sizeof(status));
+
+ status.freq = data->frequency;
+ status.signal = data->rcpi / 2 - 110;
+
+ /* let's assume that maximum rcpi value is 140 (= 35 dBm) */
+ status.qual = data->rcpi * 100 / 140;
+
+ status.band = IEEE80211_BAND_2GHZ;
+
+ /*
+ * FIXME: this gives warning from __ieee80211_rx()
+ *
+ * status.rate_idx = data->rate;
+ */
+
+ len = data->length;
+
+ if (data->flags & LM_FLAG_ALIGN)
+ align = 1;
+
+ skb_pull(skb, sizeof(*data));
+
+ if (align) {
+ p = skb->data;
+ align_len = *p;
+ skb_pull(skb, align_len);
+ }
+
+ skb_trim(skb, len);
+
+ stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
+ stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
+
+ ieee80211_rx(stlc->hw, skb, &status);
+
+ return 0;
+}
+
+
+
+static int stlc45xx_rx(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct sk_buff *skb;
+ int ret;
+ u16 len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_wakeup(stlc);
+
+ /* dummy read to flush SPI DMA controller bug */
+ stlc45xx_read16(stlc, SPI_ADRS_GEN_PURP_1);
+
+ len = stlc45xx_read16(stlc, SPI_ADRS_DMA_DATA);
+
+ if (len == 0) {
+ stlc45xx_warning("rx request of zero bytes");
+ return 0;
+ }
+
+ skb = dev_alloc_skb(len);
+ if (!skb) {
+ stlc45xx_warning("could not alloc skb");
+ return 0;
+ }
+
+ stlc45xx_spi_read(stlc, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
+
+ stlc45xx_sleep(stlc);
+
+ stlc45xx_debug(DEBUG_RX, "rx frame 0x%p %d B", skb->data, skb->len);
+ stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
+
+ control = (struct s_lm_control *) skb->data;
+
+ if (control->flags & LM_FLAG_CONTROL)
+ ret = stlc45xx_rx_control(stlc, skb);
+ else
+ ret = stlc45xx_rx_data(stlc, skb);
+
+ return ret;
+}
+
+
+static irqreturn_t stlc45xx_interrupt(int irq, void *config)
+{
+ struct spi_device *spi = config;
+ struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
+
+ stlc45xx_debug(DEBUG_IRQ, "IRQ");
+
+ queue_work(stlc->hw->workqueue, &stlc->work);
+
+ return IRQ_HANDLED;
+}
+
+static int stlc45xx_tx_frame(struct stlc45xx *stlc, u32 address,
+ void *buf, size_t len)
+{
+ struct s_dma_regs dma_regs;
+ unsigned long timeout;
+ int ret = 0;
+ u32 ints;
+
+ stlc->tx_frames++;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ stlc45xx_debug(DEBUG_TX, "tx frame 0x%p %zu B", buf, len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, buf, len);
+
+ stlc45xx_wakeup(stlc);
+
+ dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
+ dma_regs.len = cpu_to_le16(len);
+ dma_regs.addr = cpu_to_le32(address);
+
+ stlc45xx_spi_write(stlc, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
+ sizeof(dma_regs));
+
+ stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, buf, len);
+
+ timeout = jiffies + 2 * HZ;
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ while (!(ints & SPI_HOST_INT_WR_READY)) {
+ if (time_after(jiffies, timeout)) {
+ stlc45xx_warning("WR_READY timeout");
+ ret = -1;
+ goto out;
+ }
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ }
+
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_WR_READY);
+
+ stlc45xx_sleep(stlc);
+
+out:
+ return ret;
+}
+
+static int stlc45xx_wq_tx(struct stlc45xx *stlc)
+{
+ struct txbuffer *entry;
+ int ret = 0;
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ while (!list_empty(&stlc->tx_pending)) {
+ entry = list_entry(stlc->tx_pending.next,
+ struct txbuffer, tx_list);
+
+ list_del_init(&entry->tx_list);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ ret = stlc45xx_tx_frame(stlc, entry->frame_start,
+ entry->skb->data, entry->skb->len);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ if (ret < 0) {
+ /* frame transfer to firmware buffer failed */
+ /* FIXME: report this to mac80211 */
+ dev_kfree_skb(entry->skb);
+ stlc45xx_txbuffer_free(stlc, entry);
+ goto out;
+ }
+
+ list_add(&entry->tx_list, &stlc->tx_sent);
+ queue_delayed_work(stlc->hw->workqueue,
+ &stlc->work_tx_timeout,
+ msecs_to_jiffies(TX_TIMEOUT));
+ }
+
+out:
+ spin_unlock_bh(&stlc->tx_lock);
+ return ret;
+}
+
+static void stlc45xx_work(struct work_struct *work)
+{
+ struct stlc45xx *stlc = container_of(work, struct stlc45xx, work);
+ u32 ints;
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ if (stlc->fw_state == FW_STATE_OFF &&
+ stlc->fw_state == FW_STATE_RESET)
+ goto out;
+
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ stlc45xx_debug(DEBUG_BH, "begin host_ints 0x%08x", ints);
+
+ if (ints & SPI_HOST_INT_READY) {
+ stlc45xx_int_ready(stlc);
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
+ }
+
+ if (stlc->fw_state != FW_STATE_READY)
+ goto out;
+
+ if (ints & SPI_HOST_INT_UPDATE) {
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_UPDATE);
+ ret = stlc45xx_rx(stlc);
+ if (ret < 0) {
+ stlc45xx_reset(stlc);
+ goto out;
+ }
+ }
+ if (ints & SPI_HOST_INT_SW_UPDATE) {
+ stlc45xx_int_ack(stlc, SPI_HOST_INT_SW_UPDATE);
+ ret = stlc45xx_rx(stlc);
+ if (ret < 0) {
+ stlc45xx_reset(stlc);
+ goto out;
+ }
+ }
+
+ ret = stlc45xx_wq_tx(stlc);
+ if (ret < 0) {
+ stlc45xx_reset(stlc);
+ goto out;
+ }
+
+ ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
+ stlc45xx_debug(DEBUG_BH, "end host_ints 0x%08x", ints);
+
+out:
+ mutex_unlock(&stlc->mutex);
+}
+
+static void stlc45xx_tx_edcf(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct s_lmo_edcf *edcf;
+ size_t len, edcf_len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ edcf_len = sizeof(*edcf);
+ len = sizeof(*control) + edcf_len;
+ control = kzalloc(len, GFP_KERNEL);
+ edcf = (struct s_lmo_edcf *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = edcf_len;
+ control->oid = LM_OID_EDCF;
+
+ edcf->slottime = 0x14;
+ edcf->sifs = 10;
+ edcf->eofpad = 6;
+ edcf->maxburst = 1500;
+
+ edcf->queues[0].aifs = 2;
+ edcf->queues[0].pad0 = 1;
+ edcf->queues[0].cwmin = 3;
+ edcf->queues[0].cwmax = 7;
+ edcf->queues[0].txop = 47;
+ edcf->queues[1].aifs = 2;
+ edcf->queues[1].pad0 = 0;
+ edcf->queues[1].cwmin = 7;
+ edcf->queues[1].cwmax = 15;
+ edcf->queues[1].txop = 94;
+ edcf->queues[2].aifs = 3;
+ edcf->queues[2].pad0 = 0;
+ edcf->queues[2].cwmin = 15;
+ edcf->queues[2].cwmax = 1023;
+ edcf->queues[2].txop = 0;
+ edcf->queues[3].aifs = 7;
+ edcf->queues[3].pad0 = 0;
+ edcf->queues[3].cwmin = 15;
+ edcf->queues[3].cwmax = 1023;
+ edcf->queues[3].txop = 0;
+ edcf->queues[4].aifs = 13;
+ edcf->queues[4].pad0 = 99;
+ edcf->queues[4].cwmin = 3437;
+ edcf->queues[4].cwmax = 512;
+ edcf->queues[4].txop = 12;
+ edcf->queues[5].aifs = 142;
+ edcf->queues[5].pad0 = 109;
+ edcf->queues[5].cwmin = 8756;
+ edcf->queues[5].cwmax = 6;
+ edcf->queues[5].txop = 0;
+ edcf->queues[6].aifs = 4;
+ edcf->queues[6].pad0 = 0;
+ edcf->queues[6].cwmin = 0;
+ edcf->queues[6].cwmax = 58705;
+ edcf->queues[6].txop = 25716;
+ edcf->queues[7].aifs = 0;
+ edcf->queues[7].pad0 = 0;
+ edcf->queues[7].cwmin = 0;
+ edcf->queues[7].cwmax = 0;
+ edcf->queues[7].txop = 0;
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+static void stlc45xx_tx_setup(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct s_lmo_setup *setup;
+ size_t len, setup_len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ setup_len = sizeof(*setup);
+ len = sizeof(*control) + setup_len;
+ control = kzalloc(len, GFP_KERNEL);
+ setup = (struct s_lmo_setup *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = setup_len;
+ control->oid = LM_OID_SETUP;
+
+ setup->flags = LM_SETUP_INFRA;
+ setup->antenna = 2;
+ setup->rx_align = 0;
+ setup->rx_buffer = FIRMWARE_RXBUFFER_START;
+ setup->rx_mtu = FIRMWARE_MTU;
+ setup->frontend = 5;
+ setup->timeout = 0;
+ setup->truncate = 48896;
+ setup->bratemask = 0xffffffff;
+ setup->ref_clock = 644245094;
+ setup->lpf_bandwidth = 65535;
+ setup->osc_start_delay = 65535;
+
+ memcpy(setup->macaddr, stlc->mac_addr, ETH_ALEN);
+ memcpy(setup->bssid, stlc->bssid, ETH_ALEN);
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+static void stlc45xx_tx_scan(struct stlc45xx *stlc)
+{
+ struct s_lm_control *control;
+ struct s_lmo_scan *scan;
+ size_t len, scan_len;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ scan_len = sizeof(*scan);
+ len = sizeof(*control) + scan_len;
+ control = kzalloc(len, GFP_KERNEL);
+ scan = (struct s_lmo_scan *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = scan_len;
+ control->oid = LM_OID_SCAN;
+
+ scan->flags = LM_SCAN_EXIT;
+ scan->bratemask = 0x15f;
+ scan->aloft[0] = 3;
+ scan->aloft[1] = 3;
+ scan->aloft[2] = 1;
+ scan->aloft[3] = 0;
+ scan->aloft[4] = 0;
+ scan->aloft[5] = 0;
+ scan->aloft[6] = 0;
+ scan->aloft[7] = 0;
+
+ memcpy(&scan->rssical, &stlc->cal_rssi[(stlc->channel - 1) *
+ RSSI_CAL_LEN],
+ RSSI_CAL_LEN);
+ memcpy(&scan->channel, &stlc->cal_channels[(stlc->channel - 1) *
+ CHANNEL_CAL_LEN],
+ CHANNEL_CAL_LEN);
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+/*
+ * caller must hold mutex
+ */
+static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave)
+{
+ struct ieee80211_hdr *pspoll;
+ int payload_len, padding, i;
+ struct s_lm_data_out *data;
+ struct txbuffer *entry;
+ DECLARE_MAC_BUF(mac);
+ struct sk_buff *skb;
+ char *payload;
+ u16 fc;
+
+ skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 16);
+ if (!skb) {
+ stlc45xx_warning("failed to allocate pspoll frame");
+ return -ENOMEM;
+ }
+ skb_reserve(skb, stlc->hw->extra_tx_headroom);
+
+ pspoll = (struct ieee80211_hdr *) skb_put(skb, 16);
+ memset(pspoll, 0, 16);
+ fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL;
+ if (powersave)
+ fc |= IEEE80211_FCTL_PM;
+ pspoll->frame_control = cpu_to_le16(fc);
+ pspoll->duration_id = cpu_to_le16(stlc->aid);
+
+ /* aid in PS-Poll has its two MSBs each set to 1 */
+ pspoll->duration_id |= cpu_to_le16(1 << 15) | cpu_to_le16(1 << 14);
+
+ memcpy(pspoll->addr1, stlc->bssid, ETH_ALEN);
+ memcpy(pspoll->addr2, stlc->mac_addr, ETH_ALEN);
+
+ stlc45xx_debug(DEBUG_PSM, "sending PS-Poll frame to %s (powersave %d, "
+ "fc 0x%x, aid %d)", print_mac(mac, pspoll->addr1),
+ powersave, fc, stlc->aid);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ if (!entry) {
+ /*
+ * The queue should be stopped before the firmware buffer
+ * is full, so firmware buffer should always have enough
+ * space.
+ *
+ * But I'm too lazy and omit it for now.
+ */
+ if (net_ratelimit())
+ stlc45xx_warning("firmware tx buffer full is full "
+ "for null frame");
+ return -ENOSPC;
+ }
+
+ payload = skb->data;
+ payload_len = skb->len;
+ padding = (int) (skb->data - sizeof(*data)) & 3;
+ entry->header_len = sizeof(*data) + padding;
+
+ entry->skb = skb;
+ entry->status_needed = false;
+ entry->handle = (u32) skb;
+ entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+ stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+ "padding %d header_len %d)",
+ entry->handle, payload, payload_len, padding,
+ entry->header_len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+ data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+ memset(data, 0, entry->header_len);
+
+ if (padding)
+ data->flags = LM_FLAG_ALIGN;
+
+ data->flags = LM_OUT_BURST;
+ data->length = payload_len;
+ data->handle = entry->handle;
+ data->aid = 1;
+ data->rts_retries = 7;
+ data->retries = 7;
+ data->aloft_ctrl = 0;
+ data->crypt_offset = 58;
+ data->keytype = 0;
+ data->keylen = 0;
+ data->queue = LM_QUEUE_DATA3;
+ data->backlog = 32;
+ data->antenna = 2;
+ data->cts = 3;
+ data->power = 127;
+
+ for (i = 0; i < 8; i++)
+ data->aloft[i] = 0;
+
+ /*
+ * check if there's enough space in tx buffer
+ *
+ * FIXME: ignored for now
+ */
+
+ stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
+
+ list_add(&entry->tx_list, &stlc->tx_sent);
+
+ return 0;
+}
+
+/*
+ * caller must hold mutex
+ *
+ * shamelessly stolen from mac80211/ieee80211_send_nullfunc
+ */
+static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave)
+{
+ struct ieee80211_hdr *nullfunc;
+ int payload_len, padding, i;
+ struct s_lm_data_out *data;
+ struct txbuffer *entry;
+ DECLARE_MAC_BUF(mac);
+ struct sk_buff *skb;
+ char *payload;
+ u16 fc;
+
+ skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 24);
+ if (!skb) {
+ stlc45xx_warning("failed to allocate buffer for null frame\n");
+ return -ENOMEM;
+ }
+ skb_reserve(skb, stlc->hw->extra_tx_headroom);
+
+ nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
+ memset(nullfunc, 0, 24);
+ fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
+ IEEE80211_FCTL_TODS;
+
+ if (powersave)
+ fc |= IEEE80211_FCTL_PM;
+
+ nullfunc->frame_control = cpu_to_le16(fc);
+ memcpy(nullfunc->addr1, stlc->bssid, ETH_ALEN);
+ memcpy(nullfunc->addr2, stlc->mac_addr, ETH_ALEN);
+ memcpy(nullfunc->addr3, stlc->bssid, ETH_ALEN);
+
+ stlc45xx_debug(DEBUG_PSM, "sending Null frame to %s (powersave %d, "
+ "fc 0x%x)",
+ print_mac(mac, nullfunc->addr1), powersave, fc);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ if (!entry) {
+ /*
+ * The queue should be stopped before the firmware buffer
+ * is full, so firmware buffer should always have enough
+ * space.
+ *
+ * But I'm too lazy and omit it for now.
+ */
+ if (net_ratelimit())
+ stlc45xx_warning("firmware tx buffer full is full "
+ "for null frame");
+ return -ENOSPC;
+ }
+
+ payload = skb->data;
+ payload_len = skb->len;
+ padding = (int) (skb->data - sizeof(*data)) & 3;
+ entry->header_len = sizeof(*data) + padding;
+
+ entry->skb = skb;
+ entry->status_needed = false;
+ entry->handle = (u32) skb;
+ entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+ stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+ "padding %d header_len %d)",
+ entry->handle, payload, payload_len, padding,
+ entry->header_len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+ data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+ memset(data, 0, entry->header_len);
+
+ if (padding)
+ data->flags = LM_FLAG_ALIGN;
+
+ data->flags = LM_OUT_BURST;
+ data->length = payload_len;
+ data->handle = entry->handle;
+ data->aid = 1;
+ data->rts_retries = 7;
+ data->retries = 7;
+ data->aloft_ctrl = 0;
+ data->crypt_offset = 58;
+ data->keytype = 0;
+ data->keylen = 0;
+ data->queue = LM_QUEUE_DATA3;
+ data->backlog = 32;
+ data->antenna = 2;
+ data->cts = 3;
+ data->power = 127;
+
+ for (i = 0; i < 8; i++)
+ data->aloft[i] = 0;
+
+ /*
+ * check if there's enough space in tx buffer
+ *
+ * FIXME: ignored for now
+ */
+
+ stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
+
+ list_add(&entry->tx_list, &stlc->tx_sent);
+
+ return 0;
+}
+
+/* caller must hold mutex */
+static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable)
+{
+ struct s_lm_control *control;
+ struct s_lmo_psm *psm;
+ size_t len, psm_len;
+
+ WARN_ON(!stlc->associated);
+ WARN_ON(stlc->aid < 1);
+ WARN_ON(stlc->aid > 2007);
+
+ psm_len = sizeof(*psm);
+ len = sizeof(*control) + psm_len;
+ control = kzalloc(len, GFP_KERNEL);
+ psm = (struct s_lmo_psm *) (control + 1);
+
+ control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
+ control->length = psm_len;
+ control->oid = LM_OID_PSM;
+
+ if (enable)
+ psm->flags |= LM_PSM;
+
+ psm->aid = stlc->aid;
+
+ psm->beacon_rcpi_skip_max = 60;
+
+ psm->intervals[0].interval = 1;
+ psm->intervals[0].periods = 1;
+ psm->intervals[1].interval = 1;
+ psm->intervals[1].periods = 1;
+ psm->intervals[2].interval = 1;
+ psm->intervals[2].periods = 1;
+ psm->intervals[3].interval = 1;
+ psm->intervals[3].periods = 1;
+
+ psm->nr = 0;
+ psm->exclude[0] = 0;
+
+ stlc45xx_debug(DEBUG_PSM, "sending LM_OID_PSM (aid %d, interval %d)",
+ psm->aid, psm->intervals[0].interval);
+
+ stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
+
+ kfree(control);
+}
+
+static int stlc45xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct stlc45xx *stlc = hw->priv;
+ struct ieee80211_tx_info *info;
+ struct ieee80211_rate *rate;
+ int payload_len, padding, i;
+ struct s_lm_data_out *data;
+ struct txbuffer *entry;
+ char *payload;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ spin_lock_bh(&stlc->tx_lock);
+
+ entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
+ if (!entry) {
+ /* the queue should be stopped before the firmware buffer
+ * is full, so firmware buffer should always have enough
+ * space */
+ if (net_ratelimit())
+ stlc45xx_warning("firmware buffer full");
+ spin_unlock_bh(&stlc->tx_lock);
+ return NETDEV_TX_BUSY;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+
+ payload = skb->data;
+ payload_len = skb->len;
+ padding = (int) (skb->data - sizeof(*data)) & 3;
+ entry->header_len = sizeof(*data) + padding;
+
+ entry->skb = skb;
+ entry->status_needed = true;
+ entry->handle = (u32) skb;
+ entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
+
+ stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
+ "padding %d header_len %d)",
+ entry->handle, payload, payload_len, padding,
+ entry->header_len);
+ stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
+
+ data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
+
+ memset(data, 0, entry->header_len);
+
+ if (padding)
+ data->flags = LM_FLAG_ALIGN;
+
+ data->flags = LM_OUT_BURST;
+ data->length = payload_len;
+ data->handle = entry->handle;
+ data->aid = 1;
+ data->rts_retries = 7;
+ data->retries = 7;
+ data->aloft_ctrl = 0;
+ data->crypt_offset = 58;
+ data->keytype = 0;
+ data->keylen = 0;
+ data->queue = 2;
+ data->backlog = 32;
+ data->antenna = 2;
+ data->cts = 3;
+ data->power = 127;
+
+ for (i = 0; i < 8; i++) {
+ rate = ieee80211_get_tx_rate(stlc->hw, info);
+ data->aloft[i] = rate->hw_value;
+ }
+
+ list_add_tail(&entry->tx_list, &stlc->tx_pending);
+
+ /* check if there's enough space in tx buffer */
+ if (stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) == -1) {
+ stlc45xx_debug(DEBUG_QUEUE, "tx buffer full, stopping queues");
+ stlc->tx_queue_stopped = 1;
+ ieee80211_stop_queues(stlc->hw);
+ }
+
+ queue_work(stlc->hw->workqueue, &stlc->work);
+
+ spin_unlock_bh(&stlc->tx_lock);
+
+ return NETDEV_TX_OK;
+}
+
+static int stlc45xx_op_start(struct ieee80211_hw *hw)
+{
+ struct stlc45xx *stlc = hw->priv;
+ unsigned long timeout;
+ int ret = 0;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ stlc->fw_state = FW_STATE_BOOTING;
+ stlc->channel = 1;
+
+ stlc45xx_power_on(stlc);
+
+ ret = stlc45xx_upload_firmware(stlc);
+ if (ret < 0) {
+ stlc45xx_power_off(stlc);
+ goto out_unlock;
+ }
+
+ stlc->tx_queue_stopped = 0;
+
+ mutex_unlock(&stlc->mutex);
+
+ timeout = msecs_to_jiffies(2000);
+ timeout = wait_for_completion_interruptible_timeout(&stlc->fw_comp,
+ timeout);
+ if (!timeout) {
+ stlc45xx_error("firmware boot failed");
+ stlc45xx_power_off(stlc);
+ ret = -1;
+ goto out;
+ }
+
+ stlc45xx_debug(DEBUG_BOOT, "firmware booted");
+
+ /* FIXME: should we take mutex just after wait_for_completion()? */
+ mutex_lock(&stlc->mutex);
+
+ WARN_ON(stlc->fw_state != FW_STATE_READY);
+
+out_unlock:
+ mutex_unlock(&stlc->mutex);
+
+out:
+ return ret;
+}
+
+static void stlc45xx_op_stop(struct ieee80211_hw *hw)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ WARN_ON(stlc->fw_state != FW_STATE_READY);
+
+ stlc45xx_power_off(stlc);
+
+ /* FIXME: make sure that all work_structs have completed */
+
+ spin_lock_bh(&stlc->tx_lock);
+ stlc45xx_flush_queues(stlc);
+ spin_unlock_bh(&stlc->tx_lock);
+
+ stlc->fw_state = FW_STATE_OFF;
+
+ mutex_unlock(&stlc->mutex);
+}
+
+static int stlc45xx_op_add_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ switch (conf->type) {
+ case NL80211_IFTYPE_STATION:
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ memcpy(stlc->mac_addr, conf->mac_addr, ETH_ALEN);
+
+ return 0;
+}
+
+static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw,
+ struct ieee80211_if_init_conf *conf)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+}
+
+static int stlc45xx_op_config_interface(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_if_conf *conf)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ memcpy(stlc->bssid, conf->bssid, ETH_ALEN);
+ stlc45xx_tx_setup(stlc);
+
+ mutex_unlock(&stlc->mutex);
+
+ return 0;
+}
+
+static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ mutex_lock(&stlc->mutex);
+
+ stlc->channel = hw->conf.channel->hw_value;
+ stlc45xx_tx_scan(stlc);
+ stlc45xx_tx_setup(stlc);
+ stlc45xx_tx_edcf(stlc);
+
+ if ((hw->conf.flags & IEEE80211_CONF_PS) != stlc->psm) {
+ stlc->psm = hw->conf.flags & IEEE80211_CONF_PS;
+ if (stlc->associated) {
+ stlc45xx_tx_psm(stlc, stlc->psm);
+ stlc45xx_tx_nullfunc(stlc, stlc->psm);
+ }
+ }
+
+ mutex_unlock(&stlc->mutex);
+
+ return 0;
+}
+
+static void stlc45xx_op_configure_filter(struct ieee80211_hw *hw,
+ unsigned int changed_flags,
+ unsigned int *total_flags,
+ int mc_count,
+ struct dev_addr_list *mc_list)
+{
+ *total_flags = 0;
+}
+
+static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *info,
+ u32 changed)
+{
+ struct stlc45xx *stlc = hw->priv;
+
+ if (changed & BSS_CHANGED_ASSOC) {
+ stlc->associated = info->assoc;
+ if (info->assoc)
+ stlc->aid = info->aid;
+ else
+ stlc->aid = -1;
+
+ if (stlc->psm) {
+ stlc45xx_tx_psm(stlc, stlc->psm);
+ stlc45xx_tx_nullfunc(stlc, stlc->psm);
+ }
+ }
+}
+
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_rate stlc45xx_rates[] = {
+ { .bitrate = 10, .hw_value = 0, .hw_value_short = 0, },
+ { .bitrate = 20, .hw_value = 1, .hw_value_short = 1, },
+ { .bitrate = 55, .hw_value = 2, .hw_value_short = 2, },
+ { .bitrate = 110, .hw_value = 3, .hw_value_short = 3, },
+ { .bitrate = 60, .hw_value = 4, .hw_value_short = 4, },
+ { .bitrate = 90, .hw_value = 5, .hw_value_short = 5, },
+ { .bitrate = 120, .hw_value = 6, .hw_value_short = 6, },
+ { .bitrate = 180, .hw_value = 7, .hw_value_short = 7, },
+ { .bitrate = 240, .hw_value = 8, .hw_value_short = 8, },
+ { .bitrate = 360, .hw_value = 9, .hw_value_short = 9, },
+ { .bitrate = 480, .hw_value = 10, .hw_value_short = 10, },
+ { .bitrate = 540, .hw_value = 11, .hw_value_short = 11, },
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_channel stlc45xx_channels[] = {
+ { .hw_value = 1, .center_freq = 2412},
+ { .hw_value = 2, .center_freq = 2417},
+ { .hw_value = 3, .center_freq = 2422},
+ { .hw_value = 4, .center_freq = 2427},
+ { .hw_value = 5, .center_freq = 2432},
+ { .hw_value = 6, .center_freq = 2437},
+ { .hw_value = 7, .center_freq = 2442},
+ { .hw_value = 8, .center_freq = 2447},
+ { .hw_value = 9, .center_freq = 2452},
+ { .hw_value = 10, .center_freq = 2457},
+ { .hw_value = 11, .center_freq = 2462},
+ { .hw_value = 12, .center_freq = 2467},
+ { .hw_value = 13, .center_freq = 2472},
+};
+
+/* can't be const, mac80211 writes to this */
+static struct ieee80211_supported_band stlc45xx_band_2ghz = {
+ .channels = stlc45xx_channels,
+ .n_channels = ARRAY_SIZE(stlc45xx_channels),
+ .bitrates = stlc45xx_rates,
+ .n_bitrates = ARRAY_SIZE(stlc45xx_rates),
+};
+
+static const struct ieee80211_ops stlc45xx_ops = {
+ .start = stlc45xx_op_start,
+ .stop = stlc45xx_op_stop,
+ .add_interface = stlc45xx_op_add_interface,
+ .remove_interface = stlc45xx_op_remove_interface,
+ .config = stlc45xx_op_config,
+ .config_interface = stlc45xx_op_config_interface,
+ .configure_filter = stlc45xx_op_configure_filter,
+ .tx = stlc45xx_op_tx,
+ .bss_info_changed = stlc45xx_op_bss_info_changed,
+};
+
+static int stlc45xx_register_mac80211(struct stlc45xx *stlc)
+{
+ /* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr
+ to be non-const for some strange reason */
+ static u8 default_mac_addr[ETH_ALEN] = {
+ 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee
+ };
+ int ret;
+
+ SET_IEEE80211_PERM_ADDR(stlc->hw, default_mac_addr);
+
+ ret = ieee80211_register_hw(stlc->hw);
+ if (ret) {
+ stlc45xx_error("unable to register mac80211 hw: %d", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void stlc45xx_device_release(struct device *dev)
+{
+
+}
+
+static struct platform_device stlc45xx_device = {
+ .name = "stlc45xx",
+ .id = -1,
+
+ /* device model insists to have a release function */
+ .dev = {
+ .release = stlc45xx_device_release,
+ },
+};
+
+static int __devinit stlc45xx_probe(struct spi_device *spi)
+{
+ struct stlc45xx *stlc;
+ struct ieee80211_hw *hw;
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ /* mac80211 alloc */
+ hw = ieee80211_alloc_hw(sizeof(*stlc), &stlc45xx_ops);
+ if (!hw) {
+ stlc45xx_error("could not alloc ieee80211_hw");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* mac80211 clears hw->priv */
+ stlc = hw->priv;
+
+ stlc->hw = hw;
+ dev_set_drvdata(&spi->dev, stlc);
+ stlc->spi = spi;
+
+ spi->bits_per_word = 16;
+ spi->max_speed_hz = 24000000;
+
+ ret = spi_setup(spi);
+ if (ret < 0)
+ stlc45xx_error("spi_setup failed");
+
+ ret = gpio_request(stlc45xx_gpio_power, "stlc45xx power");
+ if (ret < 0) {
+ stlc45xx_error("power GPIO request failed: %d", ret);
+ return ret;
+ }
+
+ ret = gpio_request(stlc45xx_gpio_irq, "stlc45xx irq");
+ if (ret < 0) {
+ stlc45xx_error("irq GPIO request failed: %d", ret);
+ goto out;
+ }
+
+ gpio_direction_output(stlc45xx_gpio_power, 0);
+ gpio_direction_input(stlc45xx_gpio_irq);
+
+ ret = request_irq(gpio_to_irq(stlc45xx_gpio_irq),
+ stlc45xx_interrupt, IRQF_DISABLED, "stlc45xx",
+ stlc->spi);
+ if (ret < 0)
+ /* FIXME: handle the error */
+ stlc45xx_error("request_irq() failed");
+
+ set_irq_type(gpio_to_irq(stlc45xx_gpio_irq),
+ IRQ_TYPE_EDGE_RISING);
+
+ disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
+
+ ret = platform_device_register(&stlc45xx_device);
+ if (ret) {
+ stlc45xx_error("Couldn't register wlan_omap device.");
+ return ret;
+ }
+ dev_set_drvdata(&stlc45xx_device.dev, stlc);
+
+ INIT_WORK(&stlc->work, stlc45xx_work);
+ INIT_WORK(&stlc->work_reset, stlc45xx_work_reset);
+ INIT_DELAYED_WORK(&stlc->work_tx_timeout, stlc45xx_work_tx_timeout);
+ mutex_init(&stlc->mutex);
+ init_completion(&stlc->fw_comp);
+ spin_lock_init(&stlc->tx_lock);
+ INIT_LIST_HEAD(&stlc->txbuffer);
+ INIT_LIST_HEAD(&stlc->tx_pending);
+ INIT_LIST_HEAD(&stlc->tx_sent);
+
+ hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
+ IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_NOISE_DBM;
+ /* four bytes for padding */
+ hw->extra_tx_headroom = sizeof(struct s_lm_data_out) + 4;
+
+ /* unit us */
+ hw->channel_change_time = 1000;
+
+ hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &stlc45xx_band_2ghz;
+
+ SET_IEEE80211_DEV(hw, &spi->dev);
+
+ BUILD_BUG_ON(sizeof(default_cal_rssi) != RSSI_CAL_ARRAY_LEN);
+ BUILD_BUG_ON(sizeof(default_cal_channels) != CHANNEL_CAL_ARRAY_LEN);
+
+ stlc->cal_rssi = kmemdup(default_cal_rssi, RSSI_CAL_ARRAY_LEN,
+ GFP_KERNEL);
+ stlc->cal_channels = kmemdup(default_cal_channels,
+ CHANNEL_CAL_ARRAY_LEN,
+ GFP_KERNEL);
+
+ ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_rssi);
+ if (ret < 0) {
+ stlc45xx_error("failed to create sysfs file cal_rssi");
+ goto out;
+ }
+
+ ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_channels);
+ if (ret < 0) {
+ stlc45xx_error("failed to create sysfs file cal_channels");
+ goto out;
+ }
+
+ ret = device_create_file(&stlc45xx_device.dev, &dev_attr_tx_buf);
+ if (ret < 0) {
+ stlc45xx_error("failed to create sysfs file tx_buf");
+ goto out;
+ }
+
+ ret = stlc45xx_register_mac80211(stlc);
+ if (ret < 0)
+ goto out;
+
+ stlc45xx_info("v" DRIVER_VERSION " loaded");
+
+ stlc45xx_info("config buffer 0x%x-0x%x",
+ FIRMWARE_CONFIG_START, FIRMWARE_CONFIG_END);
+ stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x",
+ FIRMWARE_TXBUFFER_START, FIRMWARE_TXBUFFER_END,
+ FIRMWARE_RXBUFFER_START, FIRMWARE_RXBUFFER_END);
+
+out:
+ return ret;
+}
+
+static int __devexit stlc45xx_remove(struct spi_device *spi)
+{
+ struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ platform_device_unregister(&stlc45xx_device);
+
+ ieee80211_unregister_hw(stlc->hw);
+
+ free_irq(gpio_to_irq(stlc45xx_gpio_irq), spi);
+
+ gpio_free(stlc45xx_gpio_power);
+ gpio_free(stlc45xx_gpio_irq);
+
+ /* FIXME: free cal_channels and cal_rssi? */
+
+ kfree(stlc->fw);
+
+ mutex_destroy(&stlc->mutex);
+
+ /* frees also stlc */
+ ieee80211_free_hw(stlc->hw);
+ stlc = NULL;
+
+ return 0;
+}
+
+
+static struct spi_driver stlc45xx_spi_driver = {
+ .driver = {
+ /* use cx3110x name because board-n800.c uses that for the
+ * SPI port */
+ .name = "cx3110x",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+
+ .probe = stlc45xx_probe,
+ .remove = __devexit_p(stlc45xx_remove),
+};
+
+static int __init stlc45xx_init(void)
+{
+ int ret;
+
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ ret = spi_register_driver(&stlc45xx_spi_driver);
+ if (ret < 0) {
+ stlc45xx_error("failed to register SPI driver: %d", ret);
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
+static void __exit stlc45xx_exit(void)
+{
+ stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
+
+ spi_unregister_driver(&stlc45xx_spi_driver);
+
+ stlc45xx_info("unloaded");
+}
+
+module_init(stlc45xx_init);
+module_exit(stlc45xx_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");
diff --git a/drivers/staging/stlc45xx/stlc45xx.h b/drivers/staging/stlc45xx/stlc45xx.h
new file mode 100644
index 00000000000..ac96bbbde79
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx.h
@@ -0,0 +1,283 @@
+/*
+ * This file is part of stlc45xx
+ *
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
+ *
+ * Contact: Kalle Valo <kalle.valo@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <net/mac80211.h>
+
+#include "stlc45xx_lmac.h"
+
+#define DRIVER_NAME "stlc45xx"
+#define DRIVER_VERSION "0.1.3"
+
+#define DRIVER_PREFIX DRIVER_NAME ": "
+
+enum {
+ DEBUG_NONE = 0,
+ DEBUG_FUNC = 1 << 0,
+ DEBUG_IRQ = 1 << 1,
+ DEBUG_BH = 1 << 2,
+ DEBUG_RX = 1 << 3,
+ DEBUG_RX_CONTENT = 1 << 5,
+ DEBUG_TX = 1 << 6,
+ DEBUG_TX_CONTENT = 1 << 8,
+ DEBUG_TXBUFFER = 1 << 9,
+ DEBUG_QUEUE = 1 << 10,
+ DEBUG_BOOT = 1 << 11,
+ DEBUG_PSM = 1 << 12,
+ DEBUG_ALL = ~0,
+};
+
+#define DEBUG_LEVEL DEBUG_NONE
+/* #define DEBUG_LEVEL DEBUG_ALL */
+/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_RX | DEBUG_IRQ) */
+/* #define DEBUG_LEVEL (DEBUG_TX | DEBUG_MEMREGION | DEBUG_QUEUE) */
+/* #define DEBUG_LEVEL (DEBUG_MEMREGION | DEBUG_QUEUE) */
+
+#define stlc45xx_error(fmt, arg...) \
+ printk(KERN_ERR DRIVER_PREFIX "ERROR " fmt "\n", ##arg)
+
+#define stlc45xx_warning(fmt, arg...) \
+ printk(KERN_WARNING DRIVER_PREFIX "WARNING " fmt "\n", ##arg)
+
+#define stlc45xx_info(fmt, arg...) \
+ printk(KERN_INFO DRIVER_PREFIX fmt "\n", ##arg)
+
+#define stlc45xx_debug(level, fmt, arg...) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ printk(KERN_DEBUG DRIVER_PREFIX fmt "\n", ##arg); \
+ } while (0)
+
+#define stlc45xx_dump(level, buf, len) \
+ do { \
+ if (level & DEBUG_LEVEL) \
+ print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, \
+ 16, 1, buf, len, 1); \
+ } while (0)
+
+#define MAC2STR(a) ((a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5])
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
+
+/* Bit 15 is read/write bit; ON = READ, OFF = WRITE */
+#define ADDR_READ_BIT_15 0x8000
+
+#define SPI_ADRS_ARM_INTERRUPTS 0x00
+#define SPI_ADRS_ARM_INT_EN 0x04
+
+#define SPI_ADRS_HOST_INTERRUPTS 0x08
+#define SPI_ADRS_HOST_INT_EN 0x0c
+#define SPI_ADRS_HOST_INT_ACK 0x10
+
+#define SPI_ADRS_GEN_PURP_1 0x14
+#define SPI_ADRS_GEN_PURP_2 0x18
+
+/* high word */
+#define SPI_ADRS_DEV_CTRL_STAT 0x26
+
+#define SPI_ADRS_DMA_DATA 0x28
+
+#define SPI_ADRS_DMA_WRITE_CTRL 0x2c
+#define SPI_ADRS_DMA_WRITE_LEN 0x2e
+#define SPI_ADRS_DMA_WRITE_BASE 0x30
+
+#define SPI_ADRS_DMA_READ_CTRL 0x34
+#define SPI_ADRS_DMA_READ_LEN 0x36
+#define SPI_ADRS_DMA_READ_BASE 0x38
+
+#define SPI_CTRL_STAT_HOST_OVERRIDE 0x8000
+#define SPI_CTRL_STAT_START_HALTED 0x4000
+#define SPI_CTRL_STAT_RAM_BOOT 0x2000
+#define SPI_CTRL_STAT_HOST_RESET 0x1000
+#define SPI_CTRL_STAT_HOST_CPU_EN 0x0800
+
+#define SPI_DMA_WRITE_CTRL_ENABLE 0x0001
+#define SPI_DMA_READ_CTRL_ENABLE 0x0001
+#define HOST_ALLOWED (1 << 7)
+
+#define FIRMWARE_ADDRESS 0x20000
+
+#define SPI_TIMEOUT 100 /* msec */
+
+#define SPI_MAX_TX_PACKETS 32
+
+#define SPI_MAX_PACKET_SIZE 32767
+
+#define SPI_TARGET_INT_WAKEUP 0x00000001
+#define SPI_TARGET_INT_SLEEP 0x00000002
+#define SPI_TARGET_INT_RDDONE 0x00000004
+
+#define SPI_TARGET_INT_CTS 0x00004000
+#define SPI_TARGET_INT_DR 0x00008000
+
+#define SPI_HOST_INT_READY 0x00000001
+#define SPI_HOST_INT_WR_READY 0x00000002
+#define SPI_HOST_INT_SW_UPDATE 0x00000004
+#define SPI_HOST_INT_UPDATE 0x10000000
+
+/* clear to send */
+#define SPI_HOST_INT_CTS 0x00004000
+
+/* data ready */
+#define SPI_HOST_INT_DR 0x00008000
+
+#define SPI_HOST_INTS_DEFAULT \
+ (SPI_HOST_INT_READY | SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE)
+
+#define TARGET_BOOT_SLEEP 50
+
+/* The firmware buffer is divided into three areas:
+ *
+ * o config area (for control commands)
+ * o tx buffer
+ * o rx buffer
+ */
+#define FIRMWARE_BUFFER_START 0x20200
+#define FIRMWARE_BUFFER_END 0x27c60
+#define FIRMWARE_BUFFER_LEN (FIRMWARE_BUFFER_END - FIRMWARE_BUFFER_START)
+#define FIRMWARE_MTU 3240
+#define FIRMWARE_CONFIG_PAYLOAD_LEN 1024
+#define FIRMWARE_CONFIG_START FIRMWARE_BUFFER_START
+#define FIRMWARE_CONFIG_LEN (sizeof(struct s_lm_control) + \
+ FIRMWARE_CONFIG_PAYLOAD_LEN)
+#define FIRMWARE_CONFIG_END (FIRMWARE_CONFIG_START + FIRMWARE_CONFIG_LEN - 1)
+#define FIRMWARE_RXBUFFER_LEN (5 * FIRMWARE_MTU + 1024)
+#define FIRMWARE_RXBUFFER_START (FIRMWARE_BUFFER_END - FIRMWARE_RXBUFFER_LEN)
+#define FIRMWARE_RXBUFFER_END (FIRMWARE_RXBUFFER_START + \
+ FIRMWARE_RXBUFFER_LEN - 1)
+#define FIRMWARE_TXBUFFER_START (FIRMWARE_BUFFER_START + FIRMWARE_CONFIG_LEN)
+#define FIRMWARE_TXBUFFER_LEN (FIRMWARE_BUFFER_LEN - FIRMWARE_CONFIG_LEN - \
+ FIRMWARE_RXBUFFER_LEN)
+#define FIRMWARE_TXBUFFER_END (FIRMWARE_TXBUFFER_START + \
+ FIRMWARE_TXBUFFER_LEN - 1)
+
+#define FIRMWARE_TXBUFFER_HEADER 100
+#define FIRMWARE_TXBUFFER_TRAILER 4
+
+/* FIXME: come up with a proper value */
+#define MAX_FRAME_LEN 2500
+
+/* unit is ms */
+#define TX_FRAME_LIFETIME 2000
+#define TX_TIMEOUT 4000
+
+#define SUPPORTED_CHANNELS 13
+
+/* FIXME */
+/* #define CHANNEL_CAL_LEN offsetof(struct s_lmo_scan, bratemask) - \ */
+/* offsetof(struct s_lmo_scan, channel) */
+#define CHANNEL_CAL_LEN 292
+#define CHANNEL_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * CHANNEL_CAL_LEN)
+/* FIXME */
+/* #define RSSI_CAL_LEN sizeof(struct s_lmo_scan) - \ */
+/* offsetof(struct s_lmo_scan, rssical) */
+#define RSSI_CAL_LEN 8
+#define RSSI_CAL_ARRAY_LEN (SUPPORTED_CHANNELS * RSSI_CAL_LEN)
+
+struct s_dma_regs {
+ unsigned short cmd;
+ unsigned short len;
+ unsigned long addr;
+};
+
+struct stlc45xx_ie_tim {
+ u8 dtim_count;
+ u8 dtim_period;
+ u8 bmap_control;
+ u8 pvbmap[251];
+};
+
+struct txbuffer {
+ /* can be removed when switched to skb queue */
+ struct list_head tx_list;
+
+ struct list_head buffer_list;
+
+ int start;
+ int frame_start;
+ int end;
+
+ struct sk_buff *skb;
+ u32 handle;
+
+ bool status_needed;
+
+ int header_len;
+
+ /* unit jiffies */
+ unsigned long lifetime;
+};
+
+enum fw_state {
+ FW_STATE_OFF,
+ FW_STATE_BOOTING,
+ FW_STATE_READY,
+ FW_STATE_RESET,
+ FW_STATE_RESETTING,
+};
+
+struct stlc45xx {
+ struct ieee80211_hw *hw;
+ struct spi_device *spi;
+ struct work_struct work;
+ struct work_struct work_reset;
+ struct delayed_work work_tx_timeout;
+ struct mutex mutex;
+ struct completion fw_comp;
+
+
+ u8 bssid[ETH_ALEN];
+ u8 mac_addr[ETH_ALEN];
+ int channel;
+
+ u8 *cal_rssi;
+ u8 *cal_channels;
+
+ enum fw_state fw_state;
+
+ spinlock_t tx_lock;
+
+ /* protected by tx_lock */
+ struct list_head txbuffer;
+
+ /* protected by tx_lock */
+ struct list_head tx_pending;
+
+ /* protected by tx_lock */
+ int tx_queue_stopped;
+
+ /* protected by mutex */
+ struct list_head tx_sent;
+
+ int tx_frames;
+
+ u8 *fw;
+ int fw_len;
+
+ bool psm;
+ bool associated;
+ int aid;
+ bool pspolling;
+};
+
+
diff --git a/drivers/staging/stlc45xx/stlc45xx_lmac.h b/drivers/staging/stlc45xx/stlc45xx_lmac.h
new file mode 100644
index 00000000000..af5db801347
--- /dev/null
+++ b/drivers/staging/stlc45xx/stlc45xx_lmac.h
@@ -0,0 +1,434 @@
+/************************************************************************
+* This is the LMAC API interface header file for STLC4560. *
+* Copyright (C) 2007 Conexant Systems, Inc. *
+* This program is free software; you can redistribute it and/or *
+* modify it under the terms of the GNU General Public License *
+* as published by the Free Software Foundation; either version 2 *
+* of the License, or (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program. If not, see <http://www.gnu.org/licenses/>.*
+*************************************************************************/
+
+#ifndef __lmac_h__
+#define __lmac_h__
+
+#define LM_TOP_VARIANT 0x0506
+#define LM_BOTTOM_VARIANT 0x0506
+
+/*
+ * LMAC - UMAC interface definition:
+ */
+
+#define LM_FLAG_CONTROL 0x8000
+#define LM_FLAG_ALIGN 0x4000
+
+#define LM_CTRL_OPSET 0x0001
+
+#define LM_OUT_PROMISC 0x0001
+#define LM_OUT_TIMESTAMP 0x0002
+#define LM_OUT_SEQNR 0x0004
+#define LM_OUT_BURST 0x0010
+#define LM_OUT_NOCANCEL 0x0020
+#define LM_OUT_CLEARTIM 0x0040
+#define LM_OUT_HITCHHIKE 0x0080
+#define LM_OUT_COMPRESS 0x0100
+#define LM_OUT_CONCAT 0x0200
+#define LM_OUT_PCS_ACCEPT 0x0400
+#define LM_OUT_WAITEOSP 0x0800
+
+
+#define LM_ALOFT_SP 0x10
+#define LM_ALOFT_CTS 0x20
+#define LM_ALOFT_RTS 0x40
+#define LM_ALOFT_MASK 0x1f
+#define LM_ALOFT_RATE 0x0f
+
+#define LM_IN_FCS_GOOD 0x0001
+#define LM_IN_MATCH_MAC 0x0002
+#define LM_IN_MCBC 0x0004
+#define LM_IN_BEACON 0x0008
+#define LM_IN_MATCH_BSS 0x0010
+#define LM_IN_BCAST_BSS 0x0020
+#define LM_IN_DATA 0x0040
+#define LM_IN_TRUNCATED 0x0080
+
+#define LM_IN_TRANSPARENT 0x0200
+
+#define LM_QUEUE_BEACON 0
+#define LM_QUEUE_SCAN 1
+#define LM_QUEUE_MGT 2
+#define LM_QUEUE_MCBC 3
+#define LM_QUEUE_DATA 4
+#define LM_QUEUE_DATA0 4
+#define LM_QUEUE_DATA1 5
+#define LM_QUEUE_DATA2 6
+#define LM_QUEUE_DATA3 7
+
+#define LM_SETUP_INFRA 0x0001
+#define LM_SETUP_IBSS 0x0002
+#define LM_SETUP_TRANSPARENT 0x0008
+#define LM_SETUP_PROMISCUOUS 0x0010
+#define LM_SETUP_HIBERNATE 0x0020
+#define LM_SETUP_NOACK 0x0040
+#define LM_SETUP_RX_DISABLED 0x0080
+
+#define LM_ANTENNA_0 0
+#define LM_ANTENNA_1 1
+#define LM_ANTENNA_DIVERSITY 2
+
+#define LM_TX_FAILED 0x0001
+#define LM_TX_PSM 0x0002
+#define LM_TX_PSM_CANCELLED 0x0004
+
+#define LM_SCAN_EXIT 0x0001
+#define LM_SCAN_TRAP 0x0002
+#define LM_SCAN_ACTIVE 0x0004
+#define LM_SCAN_FILTER 0x0008
+
+#define LM_PSM 0x0001
+#define LM_PSM_DTIM 0x0002
+#define LM_PSM_MCBC 0x0004
+#define LM_PSM_CHECKSUM 0x0008
+#define LM_PSM_SKIP_MORE_DATA 0x0010
+#define LM_PSM_BEACON_TIMEOUT 0x0020
+#define LM_PSM_HFOSLEEP 0x0040
+#define LM_PSM_AUTOSWITCH_SLEEP 0x0080
+#define LM_PSM_LPIT 0x0100
+#define LM_PSM_BF_UCAST_SKIP 0x0200
+#define LM_PSM_BF_MCAST_SKIP 0x0400
+
+/* hfosleep */
+#define LM_PSM_SLEEP_OPTION_MASK (LM_PSM_AUTOSWITCH_SLEEP | LM_PSM_HFOSLEEP)
+#define LM_PSM_SLEEP_OPTION_SHIFT 6
+/* hfosleepend */
+#define LM_PSM_BF_OPTION_MASK (LM_PSM_BF_MCAST_SKIP | LM_PSM_BF_UCAST_SKIP)
+#define LM_PSM_BF_OPTION_SHIFT 9
+
+
+#define LM_PRIVACC_WEP 0x01
+#define LM_PRIVACC_TKIP 0x02
+#define LM_PRIVACC_MICHAEL 0x04
+#define LM_PRIVACC_CCX_KP 0x08
+#define LM_PRIVACC_CCX_MIC 0x10
+#define LM_PRIVACC_AES_CCMP 0x20
+
+/* size of s_lm_descr in words */
+#define LM_DESCR_SIZE_WORDS 11
+
+#ifndef __ASSEMBLER__
+
+enum {
+ LM_MODE_CLIENT = 0,
+ LM_MODE_AP
+};
+
+struct s_lm_descr {
+ uint16_t modes;
+ uint16_t flags;
+ uint32_t buffer_start;
+ uint32_t buffer_end;
+ uint8_t header;
+ uint8_t trailer;
+ uint8_t tx_queues;
+ uint8_t tx_depth;
+ uint8_t privacy;
+ uint8_t rx_keycache;
+ uint8_t tim_size;
+ uint8_t pad1;
+ uint8_t rates[16];
+ uint32_t link;
+ uint16_t mtu;
+};
+
+
+struct s_lm_control {
+ uint16_t flags;
+ uint16_t length;
+ uint32_t handle;
+ uint16_t oid;
+ uint16_t pad;
+ /* uint8_t data[]; */
+};
+
+enum {
+ LM_PRIV_NONE = 0,
+ LM_PRIV_WEP,
+ LM_PRIV_TKIP,
+ LM_PRIV_TKIPMICHAEL,
+ LM_PRIV_CCX_WEPMIC,
+ LM_PRIV_CCX_KPMIC,
+ LM_PRIV_CCX_KP,
+ LM_PRIV_AES_CCMP
+};
+
+enum {
+ LM_DECRYPT_NONE,
+ LM_DECRYPT_OK,
+ LM_DECRYPT_NOKEY,
+ LM_DECRYPT_NOMICHAEL,
+ LM_DECRYPT_NOCKIPMIC,
+ LM_DECRYPT_FAIL_WEP,
+ LM_DECRYPT_FAIL_TKIP,
+ LM_DECRYPT_FAIL_MICHAEL,
+ LM_DECRYPT_FAIL_CKIPKP,
+ LM_DECRYPT_FAIL_CKIPMIC,
+ LM_DECRYPT_FAIL_AESCCMP
+};
+
+struct s_lm_data_out {
+ uint16_t flags;
+ uint16_t length;
+ uint32_t handle;
+ uint16_t aid;
+ uint8_t rts_retries;
+ uint8_t retries;
+ uint8_t aloft[8];
+ uint8_t aloft_ctrl;
+ uint8_t crypt_offset;
+ uint8_t keytype;
+ uint8_t keylen;
+ uint8_t key[16];
+ uint8_t queue;
+ uint8_t backlog;
+ uint16_t durations[4];
+ uint8_t antenna;
+ uint8_t cts;
+ int16_t power;
+ uint8_t pad[2];
+ /*uint8_t data[];*/
+};
+
+#define LM_RCPI_INVALID (0xff)
+
+struct s_lm_data_in {
+ uint16_t flags;
+ uint16_t length;
+ uint16_t frequency;
+ uint8_t antenna;
+ uint8_t rate;
+ uint8_t rcpi;
+ uint8_t sq;
+ uint8_t decrypt;
+ uint8_t rssi_raw;
+ uint32_t clock[2];
+ /*uint8_t data[];*/
+};
+
+union u_lm_data {
+ struct s_lm_data_out out;
+ struct s_lm_data_in in;
+};
+
+enum {
+ LM_OID_SETUP = 0,
+ LM_OID_SCAN = 1,
+ LM_OID_TRAP = 2,
+ LM_OID_EDCF = 3,
+ LM_OID_KEYCACHE = 4,
+ LM_OID_PSM = 6,
+ LM_OID_TXCANCEL = 7,
+ LM_OID_TX = 8,
+ LM_OID_BURST = 9,
+ LM_OID_STATS = 10,
+ LM_OID_LED = 13,
+ LM_OID_TIMER = 15,
+ LM_OID_NAV = 20,
+ LM_OID_PCS = 22,
+ LM_OID_BT_BALANCER = 28,
+ LM_OID_GROUP_ADDRESS_TABLE = 30,
+ LM_OID_ARPTABLE = 31,
+ LM_OID_BT_OPTIONS = 35
+};
+
+enum {
+ LM_FRONTEND_UNKNOWN = 0,
+ LM_FRONTEND_DUETTE3,
+ LM_FRONTEND_DUETTE2,
+ LM_FRONTEND_FRISBEE,
+ LM_FRONTEND_CROSSBOW,
+ LM_FRONTEND_LONGBOW
+};
+
+
+#define INVALID_LPF_BANDWIDTH 0xffff
+#define INVALID_OSC_START_DELAY 0xffff
+
+struct s_lmo_setup {
+ uint16_t flags;
+ uint8_t macaddr[6];
+ uint8_t bssid[6];
+ uint8_t antenna;
+ uint8_t rx_align;
+ uint32_t rx_buffer;
+ uint16_t rx_mtu;
+ uint16_t frontend;
+ uint16_t timeout;
+ uint16_t truncate;
+ uint32_t bratemask;
+ uint8_t sbss_offset;
+ uint8_t mcast_window;
+ uint8_t rx_rssi_threshold;
+ uint8_t rx_ed_threshold;
+ uint32_t ref_clock;
+ uint16_t lpf_bandwidth;
+ uint16_t osc_start_delay;
+};
+
+
+struct s_lmo_scan {
+ uint16_t flags;
+ uint16_t dwell;
+ uint8_t channel[292];
+ uint32_t bratemask;
+ uint8_t aloft[8];
+ uint8_t rssical[8];
+};
+
+
+enum {
+ LM_TRAP_SCAN = 0,
+ LM_TRAP_TIMER,
+ LM_TRAP_BEACON_TX,
+ LM_TRAP_FAA_RADIO_ON,
+ LM_TRAP_FAA_RADIO_OFF,
+ LM_TRAP_RADAR,
+ LM_TRAP_NO_BEACON,
+ LM_TRAP_TBTT,
+ LM_TRAP_SCO_ENTER,
+ LM_TRAP_SCO_EXIT
+};
+
+struct s_lmo_trap {
+ uint16_t event;
+ uint16_t frequency;
+};
+
+struct s_lmo_timer {
+ uint32_t interval;
+};
+
+struct s_lmo_nav {
+ uint32_t period;
+};
+
+
+struct s_lmo_edcf_queue;
+
+struct s_lmo_edcf {
+ uint8_t flags;
+ uint8_t slottime;
+ uint8_t sifs;
+ uint8_t eofpad;
+ struct s_lmo_edcf_queue {
+ uint8_t aifs;
+ uint8_t pad0;
+ uint16_t cwmin;
+ uint16_t cwmax;
+ uint16_t txop;
+ } queues[8];
+ uint8_t mapping[4];
+ uint16_t maxburst;
+ uint16_t round_trip_delay;
+};
+
+struct s_lmo_keycache {
+ uint8_t entry;
+ uint8_t keyid;
+ uint8_t address[6];
+ uint8_t pad[2];
+ uint8_t keytype;
+ uint8_t keylen;
+ uint8_t key[24];
+};
+
+
+struct s_lm_interval;
+
+struct s_lmo_psm {
+ uint16_t flags;
+ uint16_t aid;
+ struct s_lm_interval {
+ uint16_t interval;
+ uint16_t periods;
+ } intervals[4];
+ /* uint16_t pad; */
+ uint8_t beacon_rcpi_skip_max;
+ uint8_t rcpi_delta_threshold;
+ uint8_t nr;
+ uint8_t exclude[1];
+};
+
+#define MC_FILTER_ADDRESS_NUM 4
+
+struct s_lmo_group_address_table {
+ uint16_t filter_enable;
+ uint16_t num_address;
+ uint8_t macaddr_list[MC_FILTER_ADDRESS_NUM][6];
+};
+
+struct s_lmo_txcancel {
+ uint32_t address[1];
+};
+
+
+struct s_lmo_tx {
+ uint8_t flags;
+ uint8_t retries;
+ uint8_t rcpi;
+ uint8_t sq;
+ uint16_t seqctrl;
+ uint8_t antenna;
+ uint8_t pad;
+};
+
+struct s_lmo_burst {
+ uint8_t flags;
+ uint8_t queue;
+ uint8_t backlog;
+ uint8_t pad;
+ uint16_t durations[32];
+};
+
+struct s_lmo_stats {
+ uint32_t valid;
+ uint32_t fcs;
+ uint32_t abort;
+ uint32_t phyabort;
+ uint32_t rts_success;
+ uint32_t rts_fail;
+ uint32_t timestamp;
+ uint32_t time_tx;
+ uint32_t noisefloor;
+ uint32_t sample_noise[8];
+ uint32_t sample_cca;
+ uint32_t sample_tx;
+};
+
+
+struct s_lmo_led {
+ uint16_t flags;
+ uint16_t mask[2];
+ uint16_t delay/*[2]*/;
+};
+
+
+struct s_lmo_bt_balancer {
+ uint16_t prio_thresh;
+ uint16_t acl_thresh;
+};
+
+
+struct s_lmo_arp_table {
+ uint16_t filter_enable;
+ uint32_t ipaddr;
+};
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* __lmac_h__ */
diff --git a/drivers/staging/sxg/Kconfig b/drivers/staging/sxg/Kconfig
index 6e6cf0b9ef9..c5cbdafee4d 100644
--- a/drivers/staging/sxg/Kconfig
+++ b/drivers/staging/sxg/Kconfig
@@ -8,4 +8,4 @@ config SXG
10Gbe network cards.
To compile this driver as a module, choose
- M here: the module will be called sxg.
+ M here: the module will be called sxg_nic.
diff --git a/drivers/staging/sxg/Makefile b/drivers/staging/sxg/Makefile
index ec48faa7b3e..8e053222c2a 100644
--- a/drivers/staging/sxg/Makefile
+++ b/drivers/staging/sxg/Makefile
@@ -1 +1,3 @@
-obj-$(CONFIG_SXG) += sxg.o
+obj-$(CONFIG_SXG) += sxg_nic.o
+
+sxg_nic-y := sxg.o sxg_ethtool.o
diff --git a/drivers/staging/sxg/saharadbgdownload.h b/drivers/staging/sxg/saharadbgdownload.h
deleted file mode 100644
index d8865ba0504..00000000000
--- a/drivers/staging/sxg/saharadbgdownload.h
+++ /dev/null
@@ -1,4854 +0,0 @@
-#define SAHARA_UCODE_VERS_STRING "$Revision: 1.1 $"
-#define SAHARA_UCODE_VERS_DATE "$Date: 2008/06/27 12:58:27 $"
-#define SAHARA_UCODE_HOSTIF_ID 3
-
-static u32 SNumSections = 0x2;
-static u32 SSectionSize[] =
-{
- 0x0000e274, 0x0000000c,
-};
-
-static u32 SSectionStart[] =
-{
- 0x00000000, 0x00001fff,
-};
-
-static unsigned char SaharaUCode[2][57972] =
-{
-{
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x4d, 0x29, 0x3a,
- 0x00, 0x00, 0xb2, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x40, 0x2b, 0x92,
- 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x25, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x98, 0x1e, 0x80, 0xe9, 0x9a,
- 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x0f, 0x80, 0x28, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x01, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x02, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x02, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x03, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x40, 0x03, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0x80, 0x03, 0x92,
- 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x0f, 0xc0, 0x03, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x5f, 0x3f, 0x00, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x42, 0xff, 0xfc, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x80, 0xfd, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x8a, 0x11, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0xfd, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x80, 0xfd, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xc0, 0x01, 0x32,
- 0x38, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x84, 0x82, 0x4d, 0x28, 0x1a,
- 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x60, 0x5f, 0x0a, 0xf6, 0x94,
- 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x49, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0e, 0x80, 0x18, 0x92,
- 0x00, 0x00, 0xd2, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0xc0, 0x20, 0x92,
- 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x21, 0x92,
- 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x08, 0x40, 0x21, 0x92,
- 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x85, 0x21, 0x90,
- 0x00, 0x00, 0x4b, 0x03, 0x00, 0x00, 0x00, 0xec, 0x02, 0xc0, 0x22, 0x92,
- 0x00, 0x00, 0x43, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x40, 0x18, 0x9d,
- 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x8b, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe8, 0x02, 0x00, 0x90, 0x72,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x00, 0xe9, 0xb6,
- 0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x7c, 0x1e, 0xc0, 0xe7, 0x9a,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x13, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x08, 0xb8, 0x01, 0x00, 0x94,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb3, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0xb0, 0x03, 0xb2, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x17, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x69, 0x05, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x0a, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0xb2,
- 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x18, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x01, 0x00, 0x2b, 0x32,
- 0x00, 0x00, 0x57, 0x00, 0x80, 0x01, 0x00, 0x80, 0x12, 0x81, 0xfc, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2b, 0xbc,
- 0x02, 0x00, 0x57, 0x00, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
- 0x00, 0x00, 0x5a, 0x00, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc0, 0xb0, 0xbc,
- 0x00, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x5c, 0x00, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
- 0x00, 0x00, 0x60, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x34,
- 0x00, 0x00, 0xfa, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x54, 0x00, 0x03, 0x01, 0x00, 0xb0, 0x02, 0x40, 0x18, 0xbd,
- 0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xa3, 0x40, 0x01, 0x99,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x16, 0x32,
- 0x00, 0x00, 0x67, 0x00, 0x03, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x80, 0xbd,
- 0x00, 0x00, 0x76, 0x00, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
- 0x76, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x6b, 0x00, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x22, 0xb2,
- 0x00, 0x00, 0x65, 0x00, 0x04, 0x01, 0x00, 0x80, 0x82, 0x85, 0x80, 0xbc,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0x63, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x68, 0x8b, 0x80, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xb8, 0xff, 0x85, 0x30,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x21, 0xff, 0x38,
- 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0x4d, 0x80, 0x3a,
- 0x2c, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x0d, 0x80, 0x3a,
- 0x00, 0xc4, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x80, 0x2d, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x48, 0x41, 0x80, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x86, 0x98, 0x67, 0xc0, 0x82, 0x3a,
- 0x00, 0x00, 0x63, 0x00, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x62, 0x8b, 0x80, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x12, 0x80, 0x2d, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x80, 0x70, 0x32,
- 0x00, 0x00, 0x7c, 0x00, 0x90, 0x99, 0x86, 0x2c, 0x28, 0xde, 0x82, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x18, 0xc0, 0x82, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x08, 0xc5, 0x82, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc5, 0x82, 0xbc,
- 0x00, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x08, 0x68, 0x8b, 0x80, 0x94,
- 0x08, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x40, 0x01, 0x99,
- 0x08, 0x00, 0x38, 0x03, 0x0c, 0x00, 0x00, 0xf8, 0x53, 0x40, 0x01, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x05, 0x80, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x3d, 0x32,
- 0x00, 0x00, 0x7e, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x62, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0x3a, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0x3a, 0x80, 0xbc,
- 0x00, 0x90, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x0d, 0x80, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
- 0x02, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa9, 0x0d, 0x80, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
- 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2c, 0x08, 0x00, 0x37, 0x32,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x08, 0x80, 0x72, 0x32,
- 0x00, 0x00, 0x96, 0x00, 0x9f, 0x00, 0x00, 0x5c, 0x08, 0x00, 0x72, 0xb2,
- 0x87, 0x00, 0x95, 0x00, 0x80, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x85, 0xb0,
- 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd8, 0xc1, 0x82, 0x94,
- 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x88, 0xc1, 0x82, 0x94,
- 0x00, 0x00, 0x9e, 0x00, 0x06, 0x00, 0x00, 0x80, 0x52, 0x7d, 0x80, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
- 0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0x9a, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x0f, 0x97, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x85, 0xb0,
- 0x10, 0x00, 0xa5, 0x00, 0x87, 0x00, 0x00, 0x78, 0x79, 0x21, 0x16, 0xb8,
- 0x01, 0x00, 0xa5, 0x00, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
- 0x87, 0x00, 0xaf, 0x00, 0x87, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0xb0,
- 0x00, 0x00, 0xa4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x12, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xd8, 0xc1, 0x82, 0x94,
- 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x88, 0xc1, 0x82, 0x94,
- 0x00, 0x00, 0xaf, 0x00, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc0, 0x85, 0xb6,
- 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x98, 0xc1, 0x82, 0x94,
- 0x00, 0x00, 0xad, 0x00, 0x80, 0x01, 0x00, 0x80, 0xd2, 0xc1, 0x82, 0xb6,
- 0x00, 0x00, 0xaf, 0x00, 0x80, 0x01, 0x00, 0x80, 0x72, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0xa8, 0x42, 0x3d, 0x72, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x18, 0x99, 0xb1, 0xf2, 0xc0, 0x7c, 0x30,
- 0x00, 0x00, 0xd6, 0x00, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0xc1, 0x82, 0xb6,
- 0x00, 0x00, 0xa9, 0x00, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
- 0x80, 0x00, 0x80, 0x20, 0x00, 0x00, 0x00, 0x80, 0xc2, 0xcd, 0x85, 0x30,
- 0x00, 0x00, 0xc6, 0x00, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0x30,
- 0x80, 0x00, 0xc6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
- 0xa0, 0x00, 0xc6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
- 0x00, 0x00, 0xbd, 0x00, 0x80, 0x01, 0x00, 0x80, 0x62, 0x80, 0xfc, 0xb6,
- 0x87, 0x00, 0xbd, 0x00, 0x87, 0x00, 0x00, 0x78, 0x89, 0xcd, 0x85, 0xb0,
- 0x00, 0x00, 0xb9, 0x00, 0x04, 0x00, 0x00, 0x80, 0x12, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0xbd, 0x00, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0xbd, 0x00, 0x80, 0x01, 0x00, 0x80, 0x72, 0xc1, 0x85, 0xb6,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x61, 0x16, 0x38,
- 0x00, 0x00, 0xc4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xb8, 0xc1, 0x82, 0x94,
- 0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0x52, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0xc4, 0x00, 0x80, 0x00, 0x00, 0x80, 0x72, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0x02, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0xc4, 0x00, 0x80, 0x01, 0x00, 0x80, 0xd2, 0xc1, 0x85, 0xb6,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0xe1, 0x16, 0x38,
- 0x00, 0x00, 0xc4, 0x00, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xc8, 0xc1, 0x82, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x04, 0x32,
- 0x00, 0x00, 0xd6, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xa8, 0xc1, 0x82, 0x94,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x17, 0x38,
- 0x00, 0x00, 0xd6, 0x00, 0x04, 0x00, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0xd6, 0x00, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
- 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x08, 0x89, 0x8d, 0x72, 0x30,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0xa9, 0xdc, 0x17, 0x38,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x90, 0x37,
- 0x00, 0x00, 0xd6, 0x00, 0x80, 0x00, 0x86, 0x80, 0x22, 0x24, 0x7c, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
- 0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0xd2, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
- 0x00, 0x00, 0xdd, 0x00, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
- 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
- 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
- 0x00, 0x00, 0xe4, 0x00, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0xe0, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0xc0, 0xf4, 0x00, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
- 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x78, 0x09, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x29, 0xc1, 0x72, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0x20, 0x90, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xc0, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0xff, 0x00, 0x80, 0x01, 0x00, 0x80, 0xa2, 0xc1, 0x82, 0xb6,
- 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x57, 0x00, 0x80, 0x97,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0xa0, 0x04, 0x39,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x80, 0xb0,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x80, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x81, 0x80, 0x34,
- 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x45, 0x90, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x12, 0x00, 0x28, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x11, 0x01, 0xf0, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x59, 0xc0, 0x6e, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x78, 0x19, 0xc0, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x4e, 0x04, 0x01, 0xec, 0x06, 0xbd, 0x97, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf4, 0x1e, 0x40, 0xef, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x09, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0xc0, 0x29, 0x37,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x17, 0x3d, 0x90, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0xf4, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x83, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x2b, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x3d, 0x32,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0xa4, 0x01, 0x80, 0x38, 0x00, 0x80, 0x22, 0xc0, 0x72, 0xb6,
- 0x00, 0x00, 0x27, 0x01, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
- 0x00, 0x00, 0x2c, 0x01, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x85, 0x30,
- 0x00, 0x00, 0x89, 0x01, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0x28, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xcd, 0x85, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x72, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x72, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x52, 0xbd, 0x82, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x30, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x08, 0x80, 0x82, 0x32,
- 0x00, 0x00, 0x3d, 0x01, 0x06, 0x00, 0x00, 0x80, 0x62, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x28, 0x80, 0x72, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x64, 0x01, 0x04, 0x38, 0x00, 0x78, 0xd9, 0xc5, 0x72, 0xb0,
- 0x00, 0x00, 0x41, 0x01, 0x80, 0x01, 0x00, 0x80, 0x02, 0x80, 0x97, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x43, 0x01, 0x80, 0x01, 0x00, 0x80, 0x12, 0x80, 0x97, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x92, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x3c, 0xb8, 0x1c, 0x17, 0x38,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x28, 0xc0, 0x83, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x2c, 0x08, 0xc0, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xb8, 0xe0, 0x83, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0xcb, 0x29, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x63, 0x01, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x78, 0xa0, 0x81, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0x3c,
- 0x00, 0x00, 0x51, 0x01, 0x06, 0x3a, 0x00, 0x80, 0xb2, 0x5c, 0x83, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x89, 0xc1, 0x72, 0x37,
- 0x07, 0x00, 0x50, 0x01, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x04, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0x54, 0x01, 0x00, 0x3a, 0x00, 0x2c, 0x07, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x2c, 0xd7, 0xe0, 0x72, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x64, 0x83, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0x73, 0x01, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
- 0x00, 0x00, 0x5e, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
- 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0xd7, 0x10, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0xf4,
- 0x00, 0x00, 0x61, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
- 0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
- 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
- 0x00, 0x00, 0x49, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0xcb, 0x19, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
- 0x07, 0x00, 0x66, 0x01, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x02, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0xa7, 0xa0, 0x81, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0x73, 0x01, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x60, 0x83, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
- 0x00, 0x00, 0x70, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
- 0x00, 0x00, 0x71, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0xd7, 0x10, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0xf4,
- 0x00, 0x00, 0x84, 0x10, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
- 0x00, 0x00, 0x64, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x04, 0x09, 0x80, 0x73, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x08, 0x89, 0x80, 0x73, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x86, 0x32,
- 0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x8c, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x7f, 0x01, 0x29, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0xb2,
- 0x00, 0x00, 0x82, 0x01, 0x28, 0x10, 0x00, 0x8c, 0x07, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x83, 0x01, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8c, 0xf7, 0xe0, 0x82, 0x3a,
- 0x00, 0x00, 0x82, 0x01, 0x28, 0x18, 0x00, 0x80, 0x07, 0x40, 0x90, 0xb2,
- 0x00, 0x00, 0x83, 0x01, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x84, 0x27, 0xe4, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x72, 0x00, 0x85, 0x30,
- 0x00, 0x00, 0x87, 0x01, 0x04, 0x00, 0x00, 0xdc, 0x43, 0x60, 0x3d, 0xb3,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0x83, 0x01, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2c, 0xb4,
- 0x00, 0x00, 0x89, 0x01, 0xf2, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x8a, 0x01, 0xf0, 0x01, 0x00, 0x08, 0x38, 0x81, 0x80, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0xf4, 0x1e, 0x40, 0xef, 0x3c,
- 0x00, 0x00, 0x93, 0x01, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x3b, 0x32,
- 0x00, 0x00, 0x8e, 0x01, 0xb9, 0x00, 0x00, 0x78, 0xc9, 0x3b, 0x3a, 0xbc,
- 0x00, 0x00, 0x92, 0x01, 0x02, 0x00, 0x00, 0x80, 0x82, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xa4, 0x03, 0xe2, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x3a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xba, 0x83, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xbd, 0x97, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x03, 0x00, 0x00, 0x00, 0x09, 0x00, 0xf4, 0xbd,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x97, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0e, 0x80, 0x83, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x22, 0x7a, 0xe8, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xe8, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0xc0, 0x29, 0x37,
- 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x90, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0xe8, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0xe8, 0x32,
- 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x08, 0x80, 0x72, 0x32,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x54, 0xa8, 0x5c, 0x16, 0x38,
- 0x0b, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x2c, 0xa8, 0xdc, 0x16, 0x38,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x88, 0x4d, 0x85, 0x3a,
- 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x38, 0x00, 0x14, 0xa9, 0x9c, 0x87, 0xd9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x24, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x72, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x30, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x18, 0x80, 0x72, 0xbc,
- 0x00, 0x00, 0xbb, 0x01, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x78, 0xc0, 0x29, 0x37,
- 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x88, 0x4d, 0x86, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x77, 0xa0, 0x81, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0x86, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0xd6, 0x01, 0x04, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xd8, 0x60, 0x86, 0x3a,
- 0x00, 0x00, 0xca, 0x01, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0x02, 0xc0, 0x38, 0xb2,
- 0x00, 0x00, 0xd2, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xd0, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xcb, 0x01, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0xd4, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
- 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
- 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
- 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xdc, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xd7, 0x01, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0xe8, 0x01, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x84, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0x40, 0x85, 0x3a,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x40, 0x88, 0xcd, 0x74, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x28, 0x00, 0x84, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
- 0x14, 0x00, 0xe8, 0x01, 0x04, 0x00, 0x00, 0x1c, 0x88, 0x0d, 0x84, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x61, 0x85, 0x3a,
- 0x80, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xd8, 0x60, 0x86, 0x3a,
- 0x00, 0x00, 0xd2, 0x01, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0xea, 0x01, 0x04, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
- 0x00, 0x00, 0xec, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
- 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0xc0, 0x82, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xb8, 0x60, 0x85, 0x3c,
- 0x04, 0x00, 0xf2, 0x01, 0x81, 0x00, 0x00, 0x60, 0x88, 0xcd, 0x74, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x28, 0xf8, 0xa0, 0x75, 0x3c,
- 0x00, 0x00, 0xf3, 0x01, 0x00, 0x08, 0x00, 0x74, 0x08, 0x80, 0x75, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x28, 0xf8, 0xa0, 0x75, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x08, 0xa1, 0x82, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xf2, 0x60, 0x2a, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x08, 0x00, 0x75, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x7c, 0x08, 0x80, 0x75, 0x32,
- 0x09, 0x00, 0xf9, 0x01, 0x04, 0x1a, 0x00, 0x70, 0x88, 0xcd, 0x74, 0xb0,
- 0x09, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x4c, 0x87, 0xcd, 0x74, 0x31,
- 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x88, 0x4d, 0x86, 0x31,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x28, 0x40, 0x86, 0x3a,
- 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x82, 0xd2,
- 0x00, 0x00, 0x00, 0x02, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
- 0x00, 0x00, 0x01, 0x02, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
- 0x00, 0x00, 0x27, 0x01, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x40, 0x00, 0x32,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xcd, 0x85, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xe8, 0xa1, 0x82, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0xc0, 0x82, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x08, 0xe1, 0x81, 0x3a,
- 0x00, 0x00, 0x0b, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x58, 0x07, 0x40, 0x87, 0x32,
- 0x00, 0x00, 0x0a, 0x02, 0x8f, 0x01, 0x00, 0x74, 0x18, 0x40, 0x87, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x0d, 0x02, 0x00, 0x04, 0x00, 0x58, 0xf7, 0xa0, 0x86, 0x9a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0xa0, 0x86, 0x3a,
- 0x28, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x58, 0x87, 0x8d, 0x97, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x22, 0x40, 0x85, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x50, 0x07, 0x80, 0x84, 0x32,
- 0x00, 0x00, 0x11, 0x02, 0x04, 0x01, 0x00, 0x80, 0x72, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x4c, 0xc7, 0xe1, 0x74, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x78, 0xa0, 0x84, 0x3a,
- 0x00, 0x00, 0x14, 0x02, 0x90, 0x01, 0x00, 0x78, 0xf9, 0xa1, 0x86, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x80, 0x97, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x58, 0x07, 0x80, 0x97, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x58, 0xa1, 0x86, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x60, 0x85, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x86, 0x32,
- 0x00, 0x00, 0x1a, 0x02, 0x12, 0x00, 0x00, 0x4c, 0x02, 0xc0, 0x38, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x84, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x57, 0x21, 0x80, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x57, 0x61, 0x86, 0x3a,
- 0x00, 0x00, 0x1f, 0x02, 0x12, 0x00, 0x00, 0x4c, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x80, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0xc0, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xcb, 0x19, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x80, 0x3a,
- 0x07, 0x00, 0x27, 0x02, 0x2b, 0x01, 0x00, 0x04, 0x79, 0x0a, 0x02, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0xcb, 0x00, 0x00, 0x04, 0x19, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x77, 0xa0, 0x81, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0x3c,
- 0x00, 0x00, 0x41, 0x02, 0x04, 0x00, 0x00, 0x1c, 0xd8, 0xe0, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x60, 0x83, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0x3a,
- 0x00, 0x00, 0x32, 0x02, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
- 0x00, 0x00, 0x3f, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x3d, 0x02, 0x06, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x3a, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x34, 0x02, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x34, 0x02, 0x67, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
- 0x00, 0x00, 0x35, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0xc0, 0x00, 0x32,
- 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
- 0x00, 0x00, 0x25, 0x02, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xf9, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x48, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x43, 0x02, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x44, 0x02, 0x00, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0x92,
- 0x00, 0x00, 0x4b, 0x02, 0x04, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
- 0x00, 0x00, 0x43, 0x02, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x44, 0x02, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
- 0x00, 0x00, 0x4f, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x89, 0x80, 0x71, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x71, 0x32,
- 0x00, 0x00, 0x53, 0x02, 0x90, 0x19, 0x00, 0x04, 0xe9, 0x5c, 0x90, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19, 0x40, 0x90, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x80, 0x86, 0x32,
- 0x41, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x8c, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x8c, 0x07, 0x40, 0x85, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x07, 0x45, 0x90, 0x30,
- 0x00, 0x00, 0x5a, 0x02, 0x04, 0x01, 0x00, 0x80, 0x42, 0x00, 0x86, 0xbc,
- 0x00, 0x00, 0x5b, 0x02, 0x00, 0x12, 0x00, 0x84, 0x27, 0xe4, 0x82, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x84, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x5f, 0x02, 0x27, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
- 0x00, 0x00, 0x5f, 0x02, 0x04, 0x00, 0x00, 0x80, 0x42, 0x60, 0x3d, 0xb3,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0x5b, 0x02, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2c, 0xb4,
- 0x00, 0x00, 0x64, 0x02, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x03, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x89, 0x01, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x67, 0x02, 0x04, 0x01, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0xbc,
- 0x00, 0x00, 0x32, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x08, 0x80, 0x2d, 0xf2,
- 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x30, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0x9a,
- 0x08, 0x00, 0x00, 0x00, 0xc6, 0x01, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x81, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x45, 0x81, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xa4, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x72, 0x02, 0x04, 0x06, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x06, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x9a,
- 0x00, 0x00, 0x00, 0x00, 0xc4, 0x07, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x3a,
- 0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x03, 0xb8, 0x00, 0x00, 0x09, 0xc0, 0x6e, 0xbd,
- 0x77, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x0d, 0x90, 0x3a,
- 0x2e, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x2b, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x37, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x38, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x86, 0x02, 0x04, 0x00, 0x00, 0x80, 0x52, 0x40, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x40, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x05, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
- 0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x04, 0x01, 0x14, 0x59, 0xc0, 0x6e, 0xd7,
- 0x02, 0x00, 0x8f, 0x02, 0x04, 0xb8, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
- 0x08, 0x00, 0x8a, 0x11, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0xec, 0x06, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x91, 0x02, 0xb5, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x80, 0xa0, 0x36, 0x0b, 0x6a, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x85, 0x2f, 0x30,
- 0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x81, 0xd2,
- 0x00, 0x00, 0xa1, 0x02, 0x80, 0x00, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
- 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0xb8, 0x00, 0x14, 0x09, 0xc0, 0x6e, 0xd2,
- 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0xa4, 0x02, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x02, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x9a,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x01, 0xec, 0x56, 0xe0, 0x6e, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2f, 0xb6,
- 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x20, 0x00, 0x8a, 0x11, 0x04, 0x39, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x00, 0x14, 0x09, 0x00, 0x6e, 0xd2,
- 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x20, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
- 0x1b, 0x00, 0xaf, 0x02, 0x38, 0x01, 0x00, 0x10, 0x09, 0x00, 0x36, 0xb2,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x79, 0x0b, 0x14, 0x38,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x50, 0x01, 0x14, 0xa9, 0x5b, 0x91, 0xd9,
- 0x00, 0x00, 0xbe, 0x02, 0x38, 0x28, 0x00, 0x18, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0xb6, 0x02, 0x04, 0x21, 0x01, 0x08, 0x69, 0x24, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x03, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xba, 0x02, 0x02, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
- 0x00, 0x00, 0xb9, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x04, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x05, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0xbd, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x0a, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x0b, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xc1, 0x02, 0x04, 0x21, 0x01, 0x08, 0x69, 0x24, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x03, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xc3, 0x02, 0x02, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
- 0x04, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xc5, 0x02, 0x9f, 0x31, 0x01, 0x0c, 0x69, 0x24, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xc9, 0x02, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x90, 0xbc,
- 0x00, 0x00, 0xc8, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x20, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x21, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xcd, 0x02, 0x04, 0x00, 0x00, 0x80, 0x32, 0xa4, 0x90, 0xbc,
- 0x00, 0x00, 0xcc, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x22, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x23, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xcf, 0x02, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x20, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x21, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0x8a, 0x11, 0x0c, 0x00, 0x00, 0xf8, 0x63, 0x40, 0x01, 0xb9,
- 0x10, 0x00, 0xd4, 0x02, 0xc5, 0x01, 0x00, 0xcc, 0x02, 0x20, 0x15, 0x98,
- 0x08, 0x00, 0x38, 0x03, 0x0c, 0x00, 0x00, 0xf8, 0x43, 0x40, 0x01, 0xb9,
- 0x10, 0x00, 0x00, 0x00, 0xc5, 0x01, 0x00, 0xcc, 0x02, 0x20, 0x15, 0x38,
- 0x00, 0x00, 0x7e, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0x00, 0x80, 0xd7,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x08, 0x05, 0x80, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xfa, 0x85, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xfa, 0x85, 0xbc,
- 0x00, 0x00, 0xdf, 0x02, 0x36, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x0e, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x02, 0x00, 0xa9, 0xdb, 0x85, 0x39,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x02, 0x8c, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0x94, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x98, 0x28, 0x80, 0x6e, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x38, 0x22, 0x14, 0x37,
- 0x00, 0x00, 0xeb, 0x02, 0x04, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x14, 0x08, 0x80, 0x6e, 0x32,
- 0x05, 0x00, 0xee, 0x02, 0x00, 0x30, 0x02, 0x00, 0x78, 0xe1, 0x6e, 0x99,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x78, 0x09, 0xc0, 0x6e, 0x32,
- 0x05, 0x00, 0x00, 0x00, 0x68, 0x08, 0x00, 0x00, 0x77, 0xa1, 0x97, 0x39,
- 0x00, 0x00, 0xf0, 0x02, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x14, 0x10, 0xf4, 0x02, 0x04, 0x00, 0x00, 0x80, 0xa2, 0x0d, 0x72, 0xb0,
- 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x02, 0xf2,
- 0x0d, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x09, 0x00, 0x80, 0x52, 0xbd, 0x72, 0xbc,
- 0x00, 0x00, 0xfb, 0x02, 0x33, 0x15, 0x00, 0xa4, 0x02, 0xc0, 0x72, 0xb2,
- 0x00, 0x00, 0x33, 0x03, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
- 0x01, 0x01, 0x08, 0x0a, 0x00, 0x28, 0x00, 0x80, 0xc2, 0x0d, 0x74, 0x3c,
- 0x00, 0x00, 0x33, 0x03, 0x0b, 0x31, 0x00, 0x7c, 0x08, 0x00, 0x75, 0xb2,
- 0x00, 0x00, 0x33, 0x03, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
- 0x00, 0x00, 0xfc, 0x02, 0x00, 0x38, 0x00, 0x88, 0x18, 0x00, 0x75, 0x9c,
- 0x00, 0x00, 0x33, 0x03, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x48, 0x08, 0x00, 0x75, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x70, 0x08, 0x00, 0x75, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x74, 0x38, 0xa2, 0x75, 0x37,
- 0x00, 0x00, 0x01, 0x03, 0x83, 0x1b, 0x00, 0x78, 0x08, 0xc0, 0x74, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0xf2, 0x02, 0x80, 0x01, 0x00, 0x80, 0x42, 0x80, 0x87, 0xb6,
- 0x2f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x84, 0xd2,
- 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x87, 0xd2,
- 0x00, 0x00, 0x15, 0x03, 0x9f, 0x78, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x0a, 0x03, 0x9f, 0x99, 0x01, 0x64, 0x88, 0x1b, 0x87, 0xbc,
- 0x00, 0x00, 0x16, 0x03, 0x9f, 0x68, 0x01, 0x64, 0x88, 0x5b, 0x86, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0xa4, 0x02, 0xc0, 0x72, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xa4, 0xb2, 0x5b, 0x2a, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x02, 0x78, 0x09, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x17, 0x03, 0x08, 0x01, 0x00, 0x04, 0xe8, 0xa5, 0x75, 0xbc,
- 0x0f, 0x00, 0x33, 0x03, 0x0b, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
- 0x00, 0x00, 0x15, 0x03, 0x04, 0xa1, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
- 0x00, 0x00, 0x9d, 0x05, 0x9f, 0x98, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x9d, 0x05, 0x06, 0xb1, 0x01, 0x80, 0x82, 0x5b, 0x87, 0xbc,
- 0x00, 0x00, 0x32, 0x03, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x30, 0x03, 0x02, 0xd4, 0x01, 0x80, 0x92, 0xfb, 0x6e, 0xbc,
- 0x15, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x16, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x1c, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x28, 0x72, 0x61, 0x80, 0xb9,
- 0x00, 0x00, 0x1a, 0x03, 0x04, 0xa1, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
- 0x00, 0x00, 0x21, 0x03, 0x06, 0xa8, 0x01, 0x80, 0x82, 0x5b, 0x80, 0xbc,
- 0x00, 0x00, 0x1e, 0x03, 0x04, 0xa9, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x31, 0x03, 0x04, 0xa9, 0x01, 0x80, 0x82, 0x9b, 0x84, 0xbc,
- 0x00, 0x00, 0x31, 0x03, 0x04, 0x01, 0x00, 0x80, 0x12, 0x40, 0x80, 0xbc,
- 0x13, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x31, 0x03, 0x9f, 0xa0, 0x01, 0x78, 0x29, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x31, 0x03, 0x02, 0x01, 0x00, 0x80, 0x12, 0xa0, 0x97, 0xbc,
- 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x2c, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x27, 0x03, 0x02, 0x00, 0x00, 0x80, 0xa2, 0x60, 0x80, 0xbc,
- 0x06, 0x00, 0x9d, 0x05, 0x2c, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
- 0x00, 0xc0, 0x29, 0x03, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
- 0x06, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x29, 0x03, 0x04, 0x00, 0x00, 0x80, 0xa2, 0x60, 0x80, 0xbc,
- 0x09, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x2b, 0x03, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x07, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x02, 0x00, 0x9d, 0x05, 0x38, 0x01, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xb2,
- 0x00, 0x00, 0x2f, 0x03, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0xbc,
- 0x1f, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x1e, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x01, 0x92,
- 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x92, 0xd2,
- 0x0d, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0xf2,
- 0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x10, 0x00, 0x8a, 0x11, 0x2a, 0x00, 0x00, 0xcc, 0x02, 0x20, 0x15, 0xb8,
- 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x3c, 0x03, 0x00, 0x38, 0xf2,
- 0x1d, 0x00, 0x49, 0x03, 0x80, 0x01, 0x00, 0x78, 0x09, 0xe0, 0x00, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x1d, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
- 0x14, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xa8, 0x05, 0x28, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x83, 0x40, 0x01, 0x39,
- 0x35, 0x00, 0x54, 0x03, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x81, 0xd2,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
- 0x2b, 0x00, 0x9d, 0x05, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x00, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x5a, 0x03, 0x1d, 0x41, 0x02, 0x5c, 0xf8, 0x01, 0x68, 0xb4,
- 0x41, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x91,
- 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0xc0, 0x85, 0xd7,
- 0x10, 0x00, 0x00, 0x00, 0xd0, 0x2c, 0x02, 0x00, 0xa9, 0xdb, 0x85, 0x39,
- 0x00, 0x00, 0xe1, 0x02, 0x12, 0x01, 0x00, 0x54, 0x02, 0xa4, 0x38, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x64, 0x03, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
- 0x2f, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x65, 0x03, 0x06, 0xa9, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x6d, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x70, 0x03, 0x04, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x08, 0x89, 0x9b, 0x90, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x08, 0x89, 0x9b, 0x90, 0x3a,
- 0x00, 0x00, 0x70, 0x03, 0x9f, 0x88, 0x01, 0x08, 0x89, 0x9b, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x04, 0xf9, 0xba, 0x6e, 0x37,
- 0x00, 0x00, 0x6c, 0x03, 0x02, 0x00, 0x00, 0x80, 0x12, 0xa4, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x19, 0x80, 0x90, 0x37,
- 0x00, 0x00, 0x70, 0x03, 0x02, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x90, 0xbc,
- 0x30, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x70, 0x03, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x12, 0x70, 0x03, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
- 0x31, 0x00, 0x93, 0x05, 0xd7, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
- 0x08, 0xc0, 0x74, 0x02, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x81, 0xd2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
- 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
- 0x2b, 0x00, 0x9d, 0x05, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x00, 0x00, 0x93, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x89, 0x4d, 0x81, 0xd7,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2c, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb0,
- 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
- 0x00, 0x00, 0xdc, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x8a, 0x03, 0x04, 0x20, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x25, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x24, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x93, 0x03, 0x04, 0x01, 0x00, 0xd8, 0x1e, 0x80, 0xed, 0xbc,
- 0x00, 0x00, 0x8c, 0x03, 0xb7, 0x00, 0x00, 0xd8, 0x0e, 0xc0, 0xed, 0xb2,
- 0x00, 0x00, 0x8f, 0x03, 0x04, 0x01, 0x00, 0x80, 0x42, 0x3b, 0xee, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x1e, 0x00, 0xee, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0xd0, 0x0e, 0x00, 0xee, 0x32,
- 0x00, 0x00, 0x93, 0x03, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0x93, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0x93, 0x03, 0x04, 0x01, 0x00, 0xb0, 0x1e, 0x00, 0xeb, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xcc, 0x02, 0x80, 0x6c, 0x32,
- 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x97, 0x03, 0x80, 0x01, 0x80, 0x80, 0x32, 0x0b, 0x6a, 0xb6,
- 0x35, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x99, 0x03, 0x04, 0x01, 0x00, 0x80, 0x42, 0xc5, 0x2c, 0xbc,
- 0x00, 0x00, 0x9a, 0x03, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x12, 0xc0, 0x2c, 0x3a,
- 0x00, 0x00, 0x95, 0x03, 0x04, 0x01, 0x00, 0x00, 0x19, 0x00, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x86, 0xc8, 0x06, 0xc0, 0x2c, 0x32,
- 0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0xc3, 0x40, 0x01, 0x99,
- 0x00, 0x00, 0x9f, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x55, 0x01, 0x80, 0xb2, 0x1b, 0x2b, 0xbc,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa3, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x55, 0x01, 0x80, 0xb2, 0x1b, 0x2b, 0xbc,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xad, 0x03, 0x04, 0x00, 0x00, 0x28, 0x09, 0x80, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xd2,
- 0x00, 0x00, 0xad, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xb0, 0x03, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
- 0xb0, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xb0, 0x03, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x99,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x09, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x0f, 0x00, 0x00, 0x32,
- 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xc2, 0x03, 0x8b, 0x01, 0x00, 0xa0, 0x12, 0x00, 0x2a, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xc5, 0x03, 0x06, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2a, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xc8, 0x03, 0x85, 0x01, 0x00, 0x9c, 0x12, 0xc0, 0x29, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x0b, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x13, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x06, 0x32,
- 0x0f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x0d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x14, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x15, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x18, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x1d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x04, 0x32,
- 0x1e, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x1f, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
- 0x20, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x17, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x1b, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x1c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x00, 0x32,
- 0x16, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x1a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x19, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x0b, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x0c, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x64, 0x02, 0x39,
- 0x00, 0x00, 0xfb, 0x03, 0x85, 0x01, 0x00, 0x00, 0x19, 0x00, 0x90, 0xba,
- 0x25, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x32,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf3, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe3, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc3, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb3, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa3, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x83, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x63, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x53, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x43, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x33, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x13, 0x40, 0x01, 0x39,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x23, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x80, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x3f, 0x80, 0xfc, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x32,
- 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x03, 0x40, 0x38, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xd2, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0x13, 0x04, 0x04, 0x01, 0x00, 0xd0, 0x12, 0x00, 0x2d, 0xbc,
- 0x50, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xe4, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x12, 0x00, 0x2d, 0x3a,
- 0x4c, 0x00, 0x1a, 0x04, 0x02, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x2d, 0xbc,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xae, 0x0d, 0x02, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x88, 0x86, 0xcc, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x86, 0xcc, 0x07, 0x80, 0x00, 0x3a,
- 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x40, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x29, 0x40, 0x90, 0x3a,
- 0x00, 0x00, 0x26, 0x04, 0x12, 0x00, 0x00, 0x78, 0x09, 0xc0, 0x20, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x97, 0xb6,
- 0x1d, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x78, 0xe9, 0xe5, 0x00, 0xb8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x45, 0x90, 0x30,
- 0x00, 0x00, 0x24, 0x04, 0x02, 0x01, 0x00, 0x80, 0xc2, 0x82, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x2c, 0x04, 0x8e, 0x01, 0x00, 0x80, 0x02, 0x40, 0x28, 0xb2,
- 0x00, 0x00, 0x26, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
- 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x36, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x80, 0x97, 0x34,
- 0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
- 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x80, 0x97, 0x34,
- 0x09, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0xfe, 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x36, 0x32,
- 0x0a, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x3b, 0x04, 0x12, 0x01, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0x39, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x3b, 0x04, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0x3e, 0x04, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x3d, 0x04, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
- 0x02, 0x00, 0x39, 0x04, 0x04, 0x01, 0x00, 0x78, 0x09, 0x24, 0x17, 0xb8,
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x64, 0x16, 0x38,
- 0x00, 0x00, 0x39, 0x04, 0x04, 0x01, 0x00, 0x80, 0x02, 0x81, 0x97, 0xbc,
- 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x36, 0x32,
- 0xfe, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x48, 0x03, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0x44, 0x04, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0x47, 0x04, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x46, 0x04, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x02, 0x00, 0x90, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x06, 0x00, 0x59, 0x04, 0x00, 0x00, 0x00, 0x0c, 0x09, 0x64, 0x16, 0x98,
- 0x00, 0x00, 0x68, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0x97, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
- 0x33, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x11, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x39, 0x00, 0x74, 0x03, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0x7f, 0x03, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x90, 0x92,
- 0x5a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x90, 0x3a,
- 0x0d, 0x00, 0x7c, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
- 0x0d, 0x00, 0x8e, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
- 0x0d, 0x00, 0x97, 0x04, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
- 0x00, 0x00, 0xa3, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xad, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
- 0x00, 0x00, 0xb3, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xbd, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc7, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xd1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
- 0x00, 0x00, 0xd8, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe1, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x90, 0x9d,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xf3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0xf3, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x40, 0x00, 0x92,
- 0xd8, 0x00, 0xf5, 0x04, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xff, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xdc, 0x0f, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0xe8, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xed, 0x04, 0x00, 0x00, 0x00, 0x78, 0x39, 0x40, 0x90, 0x97,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xec, 0x0e, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0xef, 0x04, 0x00, 0x00, 0x00, 0xe8, 0x0e, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xd4, 0x0e, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x85, 0x05, 0x00, 0x00, 0x00, 0xdc, 0x0e, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x08, 0x00, 0x15, 0x05, 0x00, 0x00, 0x00, 0x50, 0x1f, 0x24, 0x16, 0x98,
- 0x00, 0x00, 0x27, 0x05, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x92,
- 0x0d, 0x00, 0x32, 0x05, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x98,
- 0x00, 0x00, 0x33, 0x05, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x89, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x45, 0x90, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x22, 0x80, 0x97, 0xbc,
- 0x3f, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x00, 0xb0,
- 0x02, 0x00, 0x80, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x6b, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0xb0, 0x03, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0xb0, 0x03, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0xb0, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x01, 0x00, 0x34,
- 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
- 0xb0, 0x03, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x99,
- 0x00, 0x00, 0x91, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x02, 0x00, 0x91, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x31,
- 0x00, 0x00, 0x8d, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x2b, 0xbc,
- 0xf1, 0x0f, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x92,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x02, 0x00, 0x98, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
- 0x00, 0x00, 0x9b, 0x04, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x0b, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x1b, 0xe4, 0xb0, 0x32,
- 0x00, 0x00, 0xb0, 0x03, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xa1, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb2,
- 0x1f, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x80, 0x11, 0x40, 0x00, 0x99,
- 0x00, 0x00, 0xa0, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
- 0x00, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0xfc, 0xb6,
- 0x00, 0x00, 0xa7, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
- 0x09, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
- 0x0a, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xc8, 0x0f, 0x81, 0xfc, 0x94,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x72, 0x42, 0x90, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0xe2, 0x42, 0x90, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x73, 0x00, 0x90, 0x3c,
- 0x10, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xb6, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
- 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x0f, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
- 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xe4, 0x0f, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0xc0, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
- 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0e, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
- 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xac, 0x0e, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0xca, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
- 0x05, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
- 0x06, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x0f, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x48, 0x0f, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
- 0x00, 0x00, 0xd5, 0x04, 0x04, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x90, 0x32,
- 0x12, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x40, 0x1f, 0x40, 0x90, 0x9c,
- 0x00, 0x00, 0xdb, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x85, 0x90, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x80, 0x90, 0x32,
- 0x07, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x40, 0x90, 0x32,
- 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0x09, 0x64, 0x90, 0xb5,
- 0x00, 0x00, 0xe5, 0x04, 0x04, 0x01, 0x00, 0x80, 0x82, 0x42, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x90, 0x32,
- 0x11, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x40, 0x90, 0x9c,
- 0x00, 0x00, 0xeb, 0x04, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x0e, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x88, 0x0e, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x40, 0x90, 0x37,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x0f, 0xa4, 0x97, 0x9a,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xbc, 0x0e, 0x80, 0xee, 0x9d,
- 0x00, 0x00, 0xf2, 0x04, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0x00, 0x32,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xe4, 0x1e, 0x40, 0x90, 0x9c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x90, 0x37,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x86, 0xc0, 0x07, 0x40, 0x90, 0x92,
- 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x38,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xfa, 0x04, 0x04, 0x00, 0x00, 0x80, 0x02, 0x24, 0xf6, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x3f, 0x80, 0xfc, 0x34,
- 0x40, 0x80, 0xfc, 0x04, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x0f, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x79, 0x01, 0x00, 0x34,
- 0x02, 0x00, 0xfc, 0x04, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
- 0x1f, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x40, 0x00, 0x99,
- 0xea, 0x05, 0x05, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x0f, 0x00, 0x15, 0x32,
- 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x37, 0x32,
- 0xf0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x0f, 0x00, 0x36, 0x32,
- 0x98, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x0b, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x4f, 0x80, 0xfc, 0x95,
- 0x36, 0x23, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x0f, 0x80, 0x14, 0x32,
- 0x00, 0xf8, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x37, 0x32,
- 0xc0, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x0f, 0x00, 0x36, 0x32,
- 0x98, 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x4f, 0x80, 0xfc, 0x34,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x8f, 0x4d, 0x90, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x60, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x7a, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xa9, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x12, 0x05, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x6f, 0x80, 0xfc, 0x34,
- 0x00, 0x00, 0x14, 0x05, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0x90, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x5f, 0x80, 0xfc, 0x34,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x17, 0x05, 0x04, 0x01, 0x00, 0x80, 0x32, 0x40, 0x90, 0xb0,
- 0x80, 0x01, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x8d, 0xfc, 0x91,
- 0x00, 0x00, 0x19, 0x05, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0x90, 0xb6,
- 0x00, 0x00, 0x1a, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x7f, 0x80, 0xfc, 0x95,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x7f, 0x80, 0xfc, 0x34,
- 0x00, 0x00, 0x1c, 0x05, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xb6,
- 0x00, 0x00, 0x1d, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x80, 0xfc, 0x95,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x8f, 0x80, 0xfc, 0x34,
- 0x00, 0x00, 0x20, 0x05, 0x80, 0x00, 0x00, 0x80, 0x22, 0x40, 0x90, 0xb6,
- 0xf1, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x22, 0x05, 0x00, 0x00, 0x00, 0xc8, 0x1f, 0x81, 0xfc, 0x95,
- 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8c, 0x0e, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x1f, 0x81, 0xfc, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x82, 0x02, 0xf5, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x03, 0x00, 0x00, 0x78, 0x09, 0x00, 0xf5, 0xbd,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xe2, 0x25, 0xf5, 0xb5,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x1f, 0x24, 0x16, 0x38,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x50, 0x1f, 0x00, 0xf5, 0x9c,
- 0x80, 0x01, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0xfc, 0xb0,
- 0x00, 0x00, 0x2b, 0x05, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0xfd, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0xf5, 0x3a,
- 0x8c, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x80, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xec, 0x03, 0x40, 0x90, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
- 0x00, 0x00, 0x34, 0x05, 0xb2, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xe4, 0x6e, 0x3a,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0x69, 0x05, 0x17, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0xb2,
- 0x06, 0x00, 0x3f, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x32,
- 0x00, 0xc0, 0xd3, 0x0e, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x40, 0x05, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x46, 0x05, 0x04, 0x19, 0x86, 0x80, 0x02, 0x80, 0x6c, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x12, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xc1, 0x08, 0x00, 0x04, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x15, 0x86, 0x2c, 0x09, 0xc0, 0x6c, 0x32,
- 0x00, 0x00, 0x4c, 0x05, 0x22, 0x1d, 0x86, 0xc8, 0x06, 0xc0, 0x92, 0xb2,
- 0x00, 0x00, 0x4c, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xc2, 0x48, 0x00, 0x04, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x16, 0x86, 0x2c, 0x09, 0xc0, 0x6c, 0x32,
- 0x00, 0x00, 0x4c, 0x05, 0x21, 0x1d, 0x86, 0xc8, 0x06, 0xc0, 0x92, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x54, 0x05, 0x04, 0x02, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0xd3, 0x0e, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xdc,
- 0x00, 0x00, 0x52, 0x05, 0x80, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x54, 0x05, 0x81, 0x00, 0x00, 0xf8, 0x22, 0x80, 0x2f, 0xb4,
- 0x00, 0x00, 0x54, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0x54, 0x05, 0x82, 0x00, 0x00, 0xf8, 0x12, 0x80, 0x2f, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xc0, 0x0a, 0x32,
- 0x00, 0x38, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x00, 0x07, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x17, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0xc0, 0x69, 0x05, 0x18, 0x00, 0x00, 0x00, 0xa9, 0xcd, 0x3e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x86, 0x04, 0x19, 0x80, 0x6c, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x01, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x0c, 0xf7, 0x7f, 0x90, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x86, 0x80, 0x72, 0x82, 0x6c, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xa8, 0x42, 0x80, 0x6c, 0x37,
- 0x00, 0x00, 0x78, 0x05, 0x12, 0x00, 0x70, 0x38, 0x02, 0x00, 0x7c, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xe0, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x3c, 0x02, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x30, 0x02, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x34, 0x02, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x6b, 0x05, 0x02, 0x01, 0x00, 0x80, 0xb2, 0x82, 0x2a, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0xd0, 0x02, 0x00, 0x00, 0x32,
- 0x06, 0x00, 0x3f, 0x05, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
- 0x00, 0x00, 0x39, 0x05, 0x04, 0x03, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x80, 0x2f, 0x32,
- 0x00, 0x00, 0xa4, 0x03, 0xa2, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x7a, 0x05, 0x04, 0x03, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x83, 0x05, 0x00, 0x10, 0x86, 0xc8, 0x46, 0x80, 0x2a, 0x96,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x86, 0xc8, 0x46, 0x80, 0x2a, 0x36,
- 0x00, 0x00, 0x7e, 0x05, 0x80, 0x00, 0x00, 0x80, 0x12, 0x80, 0x2f, 0xb6,
- 0x03, 0x00, 0x80, 0x05, 0x22, 0x00, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0xb2,
- 0x00, 0x00, 0x80, 0x05, 0x00, 0x18, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x83, 0x05, 0x80, 0x00, 0x00, 0x80, 0x22, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xc2, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
- 0x00, 0xc0, 0xd3, 0x0e, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x36, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3c,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x06, 0x80, 0x2f, 0x32,
- 0x00, 0x00, 0xa4, 0x03, 0xa2, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x05, 0x04, 0x01, 0x00, 0x80, 0xa2, 0xc0, 0xed, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0e, 0x80, 0x02, 0x32,
- 0x40, 0x7e, 0x05, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x0e, 0x80, 0x07, 0x32,
- 0x64, 0x00, 0x8f, 0x05, 0x00, 0x00, 0x00, 0xcc, 0x0e, 0x00, 0x36, 0x92,
- 0x64, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xed, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x0e, 0x40, 0x00, 0x32,
- 0xa0, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0e, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x0e, 0xc0, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x0e, 0x80, 0x02, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x33, 0x7b, 0xec, 0x39,
- 0x1e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x6e, 0xc0, 0xec, 0x37,
- 0x00, 0x00, 0x8d, 0x04, 0x00, 0x00, 0x00, 0xd8, 0x0e, 0xc0, 0xed, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x1c, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xbc,
- 0x2b, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x3d, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x35, 0x00, 0x9c, 0x05, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x89, 0xcd, 0x81, 0x3c,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x1c, 0x01, 0x14, 0x59, 0xe4, 0x6e, 0xd9,
- 0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x81, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x18, 0x01, 0x80, 0x92, 0xc0, 0x6e, 0xbc,
- 0x2b, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x18, 0x01, 0x14, 0x79, 0xe0, 0x6e, 0xd9,
- 0xa4, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0x81, 0x3a,
- 0xe1, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xea, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xf3, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xfc, 0x05, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x05, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x0e, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x17, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x20, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x29, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x32, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x3b, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x44, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x4d, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x56, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x5f, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x68, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x71, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x7a, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x83, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x8c, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x95, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x9e, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xa7, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xb0, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xb9, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xc2, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xcb, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xd4, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xdd, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xe6, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xef, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0xf8, 0x06, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x01, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x0a, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x13, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x1c, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x25, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x2e, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x37, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x40, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x49, 0x07, 0x00, 0x00, 0x00, 0x18, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x00, 0x00, 0x57, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x52, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x57, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x5c, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x61, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x66, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x6b, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x70, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x75, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x7a, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x7f, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x84, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x89, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x8e, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x93, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x98, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x9d, 0x07, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x88, 0x82, 0xcd, 0x6e, 0x3a,
- 0x00, 0x00, 0x5f, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x71, 0x03, 0x00, 0x00, 0x00, 0xd4, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x3b, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x79, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xda, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xea, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x86, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7d, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7d, 0x0a, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd7, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe9, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xb8, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc1, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x86, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x01, 0x92,
- 0x00, 0x00, 0x81, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x76, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc9, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x47, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xb0, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x4b, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xa3, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xb0, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x51, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x68, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x64, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7e, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8f, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xa0, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xa0, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xb5, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x75, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xcc, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x02, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x88, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xd4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc4, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xa2, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa8, 0x0b, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x2a, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x2a, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x31, 0x0d, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xab, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xf3, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xb6, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x0a, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xb4, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc3, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xc3, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe5, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xe8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xea, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xc2, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x40, 0x00, 0x92,
- 0x00, 0x00, 0xf8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xf8, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x2e, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x22, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0x22, 0x09, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xef, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0x80, 0x00, 0x92,
- 0x00, 0x00, 0xef, 0x08, 0x00, 0x00, 0x00, 0x10, 0x08, 0xc0, 0x00, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x01, 0x92,
- 0x08, 0x00, 0xa1, 0x03, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
- 0x08, 0x00, 0x9d, 0x03, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
- 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x08, 0x00, 0xa7, 0x07, 0x1d, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xa1, 0x03, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
- 0x08, 0x00, 0xa1, 0x03, 0x00, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x99,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x0f, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x35,
- 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
- 0xb4, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
- 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0xb7, 0x07, 0xb7, 0x10, 0x02, 0xe0, 0x06, 0x80, 0x97, 0xb2,
- 0x00, 0x00, 0xba, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0xbb, 0x07, 0x00, 0x00, 0x00, 0xc8, 0xff, 0x80, 0xfc, 0x94,
- 0x00, 0x00, 0xbc, 0x07, 0x9f, 0x99, 0x00, 0x80, 0x82, 0x1b, 0xee, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0xe0, 0x0e, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x1c, 0x09, 0x00, 0x6e, 0x32,
- 0x40, 0x00, 0xc1, 0x07, 0x06, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x91, 0xbc,
- 0x00, 0x40, 0xc2, 0x07, 0x00, 0x18, 0x02, 0xe0, 0xa6, 0xcd, 0x2c, 0x92,
- 0x00, 0x60, 0x00, 0x00, 0x00, 0x18, 0x02, 0xe0, 0xa6, 0xcd, 0x2c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x09, 0x80, 0x03, 0x32,
- 0x00, 0x00, 0xc5, 0x07, 0x80, 0xd7, 0x01, 0x80, 0x32, 0xc0, 0x6e, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x49, 0x00, 0x92, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x18, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x24, 0x09, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x28, 0x09, 0x80, 0x6e, 0x32,
- 0x00, 0x00, 0xd3, 0x07, 0x80, 0x0e, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xb6,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xec, 0x06, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x01, 0x92, 0x3a,
- 0x00, 0x00, 0xcf, 0x07, 0x80, 0xd6, 0x01, 0x80, 0x42, 0xc0, 0x6e, 0xb6,
- 0x00, 0x82, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
- 0x00, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
- 0x28, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0xd3, 0x01, 0x00, 0x1c, 0xd9, 0xc1, 0x91, 0x34,
- 0x00, 0x82, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
- 0x00, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
- 0x34, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
- 0x04, 0x00, 0x00, 0x00, 0x00, 0x34, 0x02, 0xec, 0x06, 0x00, 0x36, 0x32,
- 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x0d, 0x92, 0x3a,
- 0x00, 0x00, 0xd9, 0x07, 0x80, 0xd6, 0x01, 0x80, 0x42, 0xc0, 0x6e, 0xb6,
- 0x00, 0x86, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
- 0x04, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
- 0x14, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0xd3, 0x01, 0x00, 0x1c, 0xd9, 0xc1, 0x91, 0x34,
- 0x00, 0x86, 0x00, 0x00, 0x00, 0x10, 0x02, 0xe0, 0xa6, 0xcd, 0x91, 0x32,
- 0x04, 0xa0, 0x00, 0x00, 0x00, 0x2c, 0x02, 0xe8, 0x06, 0x00, 0x36, 0x32,
- 0x20, 0x00, 0xdd, 0x07, 0x00, 0x32, 0x02, 0xec, 0x06, 0x00, 0x36, 0x92,
- 0x12, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0xec, 0x86, 0xcd, 0x91, 0x3a,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x28, 0x02, 0xe8, 0x86, 0x24, 0x90, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0xe0, 0x96, 0x24, 0x14, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x80, 0x91, 0x32,
- 0x00, 0x00, 0xe3, 0x07, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
- 0x00, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xc9, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0xec, 0x06, 0x80, 0x83, 0x32,
- 0x01, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0xf9, 0x07, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x2c, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xff, 0x07, 0x80, 0xd7, 0x01, 0x2c, 0x09, 0xc0, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xda, 0xd7, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0xec, 0x06, 0x40, 0xed, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
- 0x00, 0x00, 0x02, 0x08, 0x80, 0x01, 0x00, 0x80, 0x62, 0xc0, 0x92, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x82, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0xaa, 0x07, 0x04, 0x06, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0xaa, 0x07, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
- 0x3b, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x0a, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x0f, 0x08, 0x12, 0x01, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
- 0x00, 0x00, 0x12, 0x08, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x1e, 0x08, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
- 0x00, 0x00, 0x12, 0x08, 0x12, 0x01, 0x00, 0x60, 0x02, 0x80, 0x2c, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x14, 0x08, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x80, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
- 0x00, 0x00, 0x17, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0xaa, 0x07, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
- 0x3b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0x14, 0x08, 0x80, 0x6e, 0x32,
- 0x00, 0x00, 0x12, 0x08, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
- 0x00, 0x00, 0x10, 0x08, 0x12, 0x00, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x78, 0xe1, 0x6e, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x20, 0x07, 0x00, 0x00, 0x32,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x78, 0xca, 0xe9, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x32,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
- 0x00, 0x00, 0x82, 0x08, 0x04, 0xb0, 0x00, 0xe0, 0xd6, 0x20, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x50, 0x08, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
- 0x00, 0x00, 0x34, 0x08, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe0, 0x38, 0xb2,
- 0x00, 0x00, 0x41, 0x08, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
- 0x00, 0x00, 0x39, 0x08, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x5c, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
- 0x00, 0x00, 0x3b, 0x08, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x3f, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x3a, 0x08, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x46, 0x08, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
- 0x00, 0x00, 0x45, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0xe0, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xf0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x81, 0x83, 0x35,
- 0x00, 0x00, 0x28, 0x08, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
- 0x08, 0xa0, 0x28, 0x08, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
- 0x00, 0x00, 0x58, 0x08, 0x28, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
- 0x00, 0x00, 0x5b, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x58, 0x08, 0x1d, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0xb2,
- 0x00, 0x00, 0x58, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0x5c, 0x08, 0x04, 0xa0, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x6e, 0x08, 0x00, 0x98, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x92,
- 0x00, 0x00, 0x62, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x5f, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x62, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x5e, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xe0, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0xe8, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xf0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x6a, 0x08, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
- 0x08, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x90, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
- 0x00, 0x00, 0x74, 0x08, 0x2a, 0x5d, 0x01, 0xec, 0x06, 0x80, 0xee, 0xb2,
- 0x00, 0x00, 0x71, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x74, 0x08, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
- 0x10, 0x04, 0x77, 0x08, 0x37, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0xb1,
- 0x3b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
- 0x08, 0x00, 0x00, 0x00, 0xca, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x7d, 0x08, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x7c, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xc2, 0x00, 0x03, 0xbc,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x67, 0xa1, 0x73, 0x39,
- 0x30, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xd2, 0xe0, 0x83, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x2a, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x83, 0xb4,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0xe2, 0xe5, 0x38, 0xb2,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x8a, 0x08, 0x1d, 0x00, 0x00, 0x38, 0x18, 0x81, 0x83, 0xb5,
- 0x00, 0x00, 0x8a, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0x8d, 0x08, 0x04, 0x06, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x34,
- 0x08, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0xb2,
- 0x00, 0x00, 0x90, 0x08, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x5c, 0x10, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
- 0x00, 0x00, 0x92, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xae, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x95, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x35,
- 0x00, 0x00, 0xac, 0x08, 0x04, 0x00, 0x00, 0x80, 0x02, 0x61, 0x80, 0xbc,
- 0x00, 0x00, 0xa4, 0x08, 0x80, 0xb8, 0x00, 0x00, 0x09, 0xc0, 0x6e, 0xb2,
- 0x40, 0x00, 0x9c, 0x08, 0x04, 0x00, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
- 0x80, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
- 0x00, 0x00, 0x9c, 0x08, 0x02, 0xb0, 0x00, 0x80, 0x82, 0x1b, 0x84, 0xbc,
- 0x00, 0x00, 0xa4, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xb2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0xd6, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x56, 0xc0, 0x6e, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x18, 0x00, 0x86, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xb7, 0x01, 0x78, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0xe0, 0x06, 0x00, 0x86, 0x32,
- 0x40, 0x00, 0xae, 0x08, 0x04, 0x00, 0x00, 0x80, 0x82, 0x0d, 0x90, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa0, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xfa,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x00, 0x00, 0x3c, 0x18, 0x20, 0x84, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xb0, 0x00, 0x3c, 0x88, 0xdb, 0x83, 0xbe,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x01, 0x78, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf7, 0x20, 0x78, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x58, 0x78, 0x01, 0xe0, 0xf6, 0x20, 0x86, 0x3a,
- 0x00, 0x00, 0x25, 0x08, 0x00, 0x00, 0x00, 0x04, 0xf8, 0x60, 0x80, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
- 0x2e, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xc2, 0x00, 0x03, 0xbc,
- 0x10, 0x00, 0x00, 0x00, 0xd4, 0x18, 0x00, 0x80, 0x67, 0xa1, 0x73, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
- 0x30, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xb8, 0x08, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xbb, 0x08, 0x00, 0xd0, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc2, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0xbb, 0x08, 0x04, 0xd1, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x26, 0xc0, 0x6e, 0x34,
- 0x00, 0x00, 0xbd, 0x08, 0x80, 0x00, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xc0, 0x08, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x92, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0xc0, 0x08, 0x04, 0xc9, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x34,
- 0x10, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x9a, 0x01, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0xb5,
- 0x00, 0x00, 0xaa, 0x07, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
- 0x00, 0x00, 0xc7, 0x08, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x9a,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x97, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x0c, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x77, 0x10, 0x00, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x32,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0xd4, 0x08, 0x23, 0x29, 0x02, 0x04, 0x09, 0x80, 0x6e, 0xb2,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x08, 0x00, 0xd8, 0x08, 0x1d, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
- 0x00, 0x00, 0xd8, 0x08, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xdc, 0x08, 0x9d, 0x01, 0x00, 0x80, 0x07, 0xc0, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x07, 0xc0, 0x91, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x80, 0x07, 0x00, 0xee, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x07, 0x40, 0x90, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x80, 0x87, 0x8d, 0x85, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x80, 0x07, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x80, 0x07, 0x00, 0x85, 0x32,
- 0x00, 0x00, 0xe3, 0x08, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x30, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x12, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x01, 0x78, 0x09, 0x80, 0x6e, 0x32,
- 0x00, 0x00, 0xaa, 0x07, 0xdc, 0xd1, 0x01, 0xe8, 0x06, 0x80, 0x97, 0x92,
- 0x12, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x18, 0x09, 0x40, 0x81, 0xf2,
- 0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xaa, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x80, 0x2f, 0xb6,
- 0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0xaa, 0x07, 0x35, 0x01, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0xb5,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0xc0, 0xf6, 0x08, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x47, 0x10, 0x00, 0x98, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0x08, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xff, 0x08, 0x80, 0x00, 0x00, 0x80, 0x42, 0x81, 0x2f, 0xb6,
- 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x2f, 0xd2,
- 0x00, 0x00, 0xff, 0x08, 0x08, 0x5b, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x5a, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
- 0x34, 0x00, 0x00, 0x00, 0xd4, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0x32,
- 0x00, 0x00, 0x06, 0x09, 0x80, 0x01, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x0d, 0x09, 0x08, 0xc9, 0x01, 0xe8, 0x06, 0xbb, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
- 0x32, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x01, 0xf2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x0d, 0x09, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x0d, 0x09, 0x08, 0xd1, 0x01, 0xe8, 0x06, 0xbb, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
- 0x32, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x01, 0xf2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
- 0x17, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x13, 0x09, 0x12, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x20, 0xb2,
- 0x00, 0x00, 0x16, 0x09, 0x12, 0x01, 0x00, 0x5c, 0x08, 0x80, 0x20, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x02, 0x80, 0x2c, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1f, 0x80, 0xff, 0x3a,
- 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x79, 0x21, 0x2f, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xf9, 0x81, 0x97, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x02, 0x44, 0xe2, 0x25, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xd4, 0xa0, 0x01, 0x50, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xdb, 0x79, 0x01, 0x60, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x5c, 0x10, 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x06, 0x00, 0x85, 0x32,
- 0x00, 0x00, 0x1f, 0x09, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0xa2, 0x8d, 0x2c, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0xaa, 0x07, 0xda, 0x5c, 0x01, 0xec, 0x06, 0x80, 0xee, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x9f, 0x41, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
- 0x00, 0x00, 0x2d, 0x09, 0x9f, 0x98, 0x01, 0x80, 0x52, 0x20, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0xc0, 0x2b, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0xaa, 0x07, 0x31, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0x34,
- 0x3a, 0x00, 0xaa, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x47, 0x10, 0x00, 0x98, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0xd5, 0x41, 0x01, 0xe0, 0x06, 0x40, 0x81, 0x92,
- 0x00, 0x00, 0xaa, 0x07, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0x00, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x60, 0x11, 0x00, 0x78, 0x01, 0x60, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x78, 0x09, 0x80, 0x6e, 0x32,
- 0x00, 0x00, 0x35, 0x09, 0x04, 0xd4, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x19, 0x80, 0x97, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0xe6, 0x25, 0x6e, 0x3a,
- 0x00, 0x00, 0x60, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x39, 0x09, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xaa, 0x07, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x00, 0x80, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x1a, 0x08, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
- 0x02, 0x00, 0x3f, 0x09, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
- 0x00, 0x00, 0x41, 0x09, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0x44, 0x09, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x41, 0x09, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0xfc, 0xb6,
- 0x00, 0x00, 0x44, 0x09, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf5, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x42, 0xbd, 0x97, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x99, 0xb1, 0xf2, 0xc0, 0x7c, 0x30,
- 0x00, 0xc0, 0x48, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x08, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x50, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x07, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xa2, 0x00, 0x2d, 0x37,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x99, 0xe1, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x4d, 0x09, 0x04, 0x01, 0x00, 0x78, 0x19, 0x80, 0x97, 0xbc,
- 0x02, 0x00, 0x59, 0x09, 0x04, 0xb9, 0x00, 0x80, 0x82, 0xcd, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x48, 0xd6, 0x01, 0x00, 0x78, 0xc9, 0xcd, 0x2c, 0x32,
- 0x00, 0x00, 0x51, 0x09, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x80, 0x97, 0xb2,
- 0x00, 0x00, 0x53, 0x09, 0x12, 0x08, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x54, 0x09, 0x12, 0x18, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x55, 0x09, 0x12, 0x10, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xa6, 0x54, 0x01, 0xec, 0x06, 0x00, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x94,
- 0x00, 0x20, 0x00, 0x4c, 0xd6, 0x01, 0x00, 0x78, 0xc9, 0xcd, 0x2c, 0x32,
- 0x00, 0x00, 0x5a, 0x09, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0x02, 0x80, 0x97, 0xb2,
- 0x00, 0x00, 0x5c, 0x09, 0x12, 0x08, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x5d, 0x09, 0x12, 0x30, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x5e, 0x09, 0x12, 0x38, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x5f, 0x09, 0x12, 0x40, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x60, 0x09, 0x12, 0x48, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x61, 0x09, 0x12, 0x10, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x62, 0x09, 0x12, 0x18, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x63, 0x09, 0x12, 0x20, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x64, 0x09, 0x12, 0x28, 0x00, 0x64, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xa6, 0x54, 0x01, 0xec, 0x06, 0x00, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x01, 0xe8, 0x06, 0xc0, 0x2c, 0x32,
- 0x03, 0x00, 0xa2, 0x07, 0x00, 0x0e, 0x01, 0xec, 0x06, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
- 0x00, 0x00, 0x6b, 0x09, 0x00, 0x00, 0x00, 0x14, 0x08, 0x80, 0x3d, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x02, 0x32,
- 0x00, 0x00, 0x6e, 0x09, 0x04, 0x00, 0x00, 0xdc, 0x53, 0x60, 0x3d, 0xb3,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x03, 0x39,
- 0x6a, 0x09, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0x74, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x14, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
- 0x00, 0x10, 0x00, 0x82, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0xa2, 0x07, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x94,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
- 0x2c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x7d, 0x09, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x29, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0xa1, 0x03, 0x23, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x3c, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0x8c, 0x09, 0x38, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
- 0x00, 0x00, 0x8c, 0x09, 0x1e, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8f, 0x09, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
- 0x00, 0x82, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
- 0x00, 0xc0, 0x99, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
- 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x01, 0x0e, 0x00, 0x30, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xfa,
- 0x00, 0x00, 0xa2, 0x09, 0x38, 0x01, 0x00, 0x2c, 0xf8, 0x01, 0x0b, 0xb4,
- 0x00, 0x00, 0xa2, 0x09, 0x02, 0x0d, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xc8, 0xc1, 0x82, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
- 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xa7, 0x09, 0x27, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x2c, 0xe8, 0xc0, 0x82, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0xd5, 0x40, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
- 0x08, 0x00, 0xb0, 0x10, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xf9,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0xab, 0x09, 0x23, 0x19, 0x00, 0x00, 0x07, 0x80, 0x81, 0xb2,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xad, 0x09, 0x1d, 0x21, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0xb0, 0x09, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xb0, 0x09, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x80, 0x2d, 0xbc,
- 0x10, 0x00, 0xb6, 0x09, 0x2c, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0xb9,
- 0x00, 0x00, 0xb8, 0x09, 0x8e, 0x39, 0x00, 0x00, 0x07, 0xc0, 0x82, 0xb2,
- 0x00, 0x00, 0xb8, 0x09, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x92,
- 0x00, 0x00, 0xb8, 0x09, 0x8e, 0x39, 0x00, 0x00, 0xb7, 0xc1, 0x82, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x32,
- 0x00, 0x00, 0xba, 0x09, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xc0, 0x09, 0x04, 0x01, 0x00, 0x80, 0x12, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0xb8, 0x09, 0x9f, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
- 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xc8, 0x09, 0x1e, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
- 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xa4, 0x07, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0xce, 0x09, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x1c, 0x40, 0x02, 0x80, 0x06, 0xc0, 0x85, 0xb2,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x2c, 0x10, 0xd6, 0x01, 0x00, 0x2c, 0x09, 0xc0, 0x85, 0xd2,
- 0x00, 0x00, 0xa1, 0x03, 0xd2, 0x01, 0x00, 0x94, 0x1e, 0x40, 0xe9, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xee, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x51, 0x01, 0x80, 0x02, 0x80, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x21, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
- 0x00, 0x00, 0xe4, 0x09, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xe1, 0x09, 0x9e, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa4, 0x07, 0x2a, 0x31, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xb2,
- 0x18, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0x39,
- 0xa4, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x0c, 0x00, 0xeb, 0x09, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0xeb, 0x09, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x00, 0x92,
- 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x08, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xee, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x25, 0x0a, 0x38, 0x00, 0x00, 0xa4, 0x08, 0x80, 0x82, 0xb2,
- 0x00, 0x00, 0x25, 0x0a, 0x04, 0x28, 0x01, 0x04, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x01, 0x04, 0xa8, 0x5b, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x08, 0x20, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x0a, 0x0a, 0x08, 0x01, 0x00, 0x28, 0x18, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0xa6, 0x20, 0x00, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0xfb, 0x09, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x97, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
- 0x00, 0x20, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x3d, 0x00, 0x0c, 0x07, 0x80, 0x83, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x08, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
- 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0x66, 0x0a, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x6c, 0x18, 0x20, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x0f, 0x0a, 0x00, 0x38, 0x01, 0xe0, 0x06, 0x40, 0x80, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x6c, 0x18, 0x20, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x11, 0x0a, 0x9f, 0x01, 0x00, 0x04, 0x68, 0x60, 0x80, 0xbc,
- 0x00, 0x00, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x18, 0x18, 0x20, 0x00, 0x9c,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x14, 0x0a, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x70, 0x00, 0x18, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x0d, 0x0a, 0x02, 0x01, 0x00, 0x80, 0x62, 0x60, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
- 0x00, 0xa0, 0x0d, 0x0a, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x1f, 0x0a, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x1f, 0x0a, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xa0, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
- 0x00, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x80, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x27, 0x0a, 0x00, 0x18, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0x2a, 0x0a, 0x00, 0x50, 0x01, 0x3c, 0xa8, 0x5b, 0x80, 0x9c,
- 0x00, 0x00, 0xa4, 0x07, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x2f, 0x0a, 0x3e, 0x51, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0xf8, 0xf2, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
- 0x00, 0x00, 0x2f, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x4c, 0x0f, 0x60, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0x7b, 0x0a, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x3a, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x0f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0xc0, 0x3e, 0x0a, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xdf, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x0f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xde, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
- 0x00, 0x00, 0x42, 0x0a, 0x2f, 0x20, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
- 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x4a, 0x0a, 0x1f, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x45, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x83, 0xbc,
- 0x00, 0x00, 0x4a, 0x0a, 0x00, 0x50, 0x01, 0xe8, 0xf6, 0x60, 0x80, 0x9c,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0x38,
- 0x00, 0x00, 0x4f, 0x0a, 0x2a, 0xa9, 0x01, 0xe0, 0x06, 0x00, 0x92, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x4f, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x4b, 0x0a, 0x04, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x52, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x32,
- 0x00, 0xc0, 0x61, 0x0a, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x18, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x82, 0xb6,
- 0x00, 0x00, 0x58, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x18, 0x00, 0x5a, 0x0a, 0x2e, 0x49, 0x01, 0xe0, 0xe6, 0xa0, 0x82, 0xb9,
- 0x00, 0x00, 0x5b, 0x0a, 0x00, 0x5e, 0x01, 0xec, 0x76, 0x00, 0x00, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
- 0x20, 0x80, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
- 0x1b, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x0c, 0x00, 0xa1, 0x03, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x85, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x9e, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x80, 0x85, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
- 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x67, 0x0a, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x6e, 0x0a, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
- 0x00, 0x00, 0x6e, 0x0a, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x72, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0x2f, 0xb6,
- 0x2a, 0x00, 0x78, 0x0a, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x75, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x78, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x78, 0x0a, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0xa2, 0x07, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x85, 0xbc,
- 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x9e, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x80, 0x85, 0x92,
- 0x00, 0x00, 0xa4, 0x07, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x80, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x12, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xce, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0x86, 0x0a, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x8f, 0x0a, 0x3f, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0xb2,
- 0x00, 0x00, 0x8f, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xde, 0x00, 0x00, 0xf8, 0xf2, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0xda, 0x0a, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
- 0x00, 0x00, 0xb0, 0x0a, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
- 0x00, 0x00, 0x9b, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
- 0x00, 0x00, 0xae, 0x0a, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0xa7, 0x0a, 0x28, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0xa5, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0xa1, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0xa5, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0xa5, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xa3, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
- 0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xac, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xa7, 0x0a, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xfa,
- 0x00, 0x00, 0x90, 0x0a, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0xbc, 0x0a, 0x28, 0x00, 0x00, 0x80, 0x08, 0x40, 0x00, 0xb2,
- 0x00, 0x00, 0xba, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0xb6, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0xba, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0xba, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xb8, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
- 0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
- 0x00, 0x00, 0xe0, 0x0a, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xc0, 0x0a, 0x04, 0x21, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x34, 0x08, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
- 0x00, 0x00, 0xc6, 0x0a, 0x2a, 0x11, 0x00, 0xe0, 0xd6, 0xe0, 0x86, 0xba,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0xc6, 0x0a, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xc2, 0x0a, 0x9f, 0x01, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x08, 0x00, 0xca, 0x0a, 0x23, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xce, 0x0a, 0x1d, 0x18, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0xb2,
- 0x00, 0x00, 0xce, 0x0a, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xd3, 0x0a, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x88, 0xbc,
- 0x00, 0x00, 0xd2, 0x0a, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x78, 0x19, 0x20, 0x6e, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xe2, 0xa5, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x88, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0xe4, 0x0a, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0xe5, 0x0a, 0xc9, 0x01, 0x00, 0x14, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xef, 0x0a, 0x28, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0xee, 0x0a, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0xea, 0x0a, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0xee, 0x0a, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0xee, 0x0a, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xec, 0x0a, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x3c, 0x0e, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0xf2,
- 0x00, 0x20, 0x00, 0x80, 0xdf, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0xf3, 0x0a, 0x3d, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
- 0x00, 0x00, 0xf3, 0x0a, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x81, 0x2f, 0xf5,
- 0x08, 0x00, 0xb0, 0x10, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xf9,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0xf8, 0x0a, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xfd, 0x0a, 0x29, 0x08, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0xb2,
- 0x00, 0x00, 0x02, 0x0b, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x02, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0xff, 0x0a, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x01, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xfe, 0x0a, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x9c,
- 0x2a, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x05, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x81, 0xbc,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0xa4, 0x03, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x00, 0x80, 0x82, 0x9b, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x80, 0x12, 0xa0, 0x82, 0xbc,
- 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0xa9, 0x60, 0x80, 0xd9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0x15, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x20, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0xa8, 0x60, 0x80, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0x3b, 0x0e, 0x00, 0x00, 0x00, 0x04, 0x08, 0x80, 0x82, 0xf2,
- 0x00, 0x00, 0x21, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x20, 0x80, 0x3a,
- 0x00, 0x00, 0x26, 0x0b, 0x04, 0x00, 0x00, 0x28, 0x68, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xaf, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x17, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x81, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x2e, 0x0b, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
- 0x00, 0x00, 0x2e, 0x0b, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x04, 0x08, 0x80, 0x86, 0xb2,
- 0x00, 0x00, 0x3c, 0x0b, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x28, 0x09, 0x80, 0x80, 0xb2,
- 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
- 0x00, 0x00, 0x34, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x3a, 0x10, 0x00, 0x00, 0x00, 0x78, 0x38, 0x80, 0x87, 0xf5,
- 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0xa5, 0x02, 0x23, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x32, 0x80, 0x2f, 0x35,
- 0x3c, 0x00, 0xa5, 0x02, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x3f, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x41, 0x0b, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
- 0x00, 0x82, 0x4b, 0x0b, 0x00, 0x00, 0x00, 0x08, 0xa8, 0x8d, 0x80, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0x5c, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xa8, 0x8d, 0x80, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
- 0x00, 0x00, 0x53, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x4f, 0x0b, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x53, 0x0b, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0x53, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x51, 0x0b, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
- 0x00, 0x00, 0xa4, 0x07, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x39, 0x10, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
- 0x00, 0x10, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0xb0, 0x10, 0x00, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x6a, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x2f, 0xb6,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xc3, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x6e, 0x0b, 0x1d, 0x21, 0x00, 0x00, 0x07, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x71, 0x0b, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x71, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x74, 0x0b, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0xa4, 0x03, 0xca, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x7e, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x7a, 0x0b, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x7e, 0x0b, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0x7e, 0x0b, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x7c, 0x0b, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x80, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x86, 0xbc,
- 0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x87, 0x0b, 0x33, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
- 0x00, 0x00, 0x87, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x01, 0x72, 0xb6,
- 0x00, 0x00, 0x87, 0x0b, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
- 0x00, 0x00, 0x87, 0x0b, 0x9f, 0xf8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xe0, 0x06, 0xc0, 0x87, 0x32,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
- 0x00, 0x00, 0x8d, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8d, 0x0b, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xcd, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
- 0x3b, 0x00, 0x8d, 0x0b, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x9d, 0x0b, 0x27, 0x09, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0xb2,
- 0x00, 0xc0, 0x95, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x20, 0x80, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x92,
- 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x98, 0x01, 0x14, 0x09, 0x00, 0x6e, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x40, 0x88, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x40, 0x88, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
- 0x00, 0x40, 0x00, 0x80, 0xca, 0x39, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
- 0x00, 0x00, 0xa1, 0x0b, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xa1, 0x0b, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0xa4, 0x03, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0xae, 0x0b, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xee, 0x10, 0x00, 0x20, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x08, 0x80, 0x82, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x18, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xb6, 0x0b, 0x00, 0x50, 0x01, 0x3c, 0xa8, 0x5b, 0x80, 0x9c,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0xee, 0x0b, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
- 0x00, 0x00, 0xd4, 0x0b, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
- 0x00, 0x00, 0xc5, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
- 0x00, 0x00, 0xcd, 0x0b, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xcb, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xc6, 0x0b, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xd2, 0x0b, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
- 0x00, 0x00, 0xd1, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xba, 0x0b, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0xdb, 0x0b, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xd5, 0x0b, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
- 0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
- 0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0xe6, 0x0b, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xb9, 0x0b, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
- 0x00, 0x00, 0xec, 0x0b, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xeb, 0x0b, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xba, 0x0b, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0xf6, 0x0b, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
- 0x00, 0xc0, 0xf7, 0x0b, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
- 0x00, 0x00, 0xfb, 0x0b, 0x2f, 0x20, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
- 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xff, 0x0b, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
- 0x00, 0x00, 0xfe, 0x0b, 0x9f, 0x31, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x07, 0x0c, 0x00, 0x50, 0x01, 0xe8, 0xf6, 0x60, 0x80, 0x9c,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x08, 0x00, 0x73, 0x11, 0x00, 0x40, 0x02, 0x14, 0x39, 0x9a, 0xfe, 0xd8,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0x38,
- 0x00, 0x00, 0x06, 0x0c, 0x9f, 0x31, 0x01, 0xe0, 0x96, 0x22, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x06, 0x00, 0x92, 0x32,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x0c, 0x0c, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x08, 0x0c, 0x04, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x14, 0x0c, 0x23, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xba,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x15, 0x0c, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x1c, 0x0c, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
- 0x00, 0x00, 0x1c, 0x0c, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x20, 0x0c, 0x29, 0x31, 0x01, 0x0c, 0x09, 0x00, 0x6e, 0xb2,
- 0x2a, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x27, 0x0e, 0x00, 0x0c, 0x02, 0x00, 0x09, 0x80, 0x6e, 0xf2,
- 0x00, 0x00, 0x24, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x02, 0xe4, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x27, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xa2, 0x07, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x18, 0x09, 0x40, 0x81, 0xb2,
- 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x0c, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x27, 0x0e, 0x00, 0x0c, 0x02, 0x00, 0x09, 0x80, 0x6e, 0xf2,
- 0x00, 0x00, 0xa4, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xb0, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x90, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x78, 0x0b, 0x16, 0x38,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x78, 0x0b, 0x16, 0x38,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xa8, 0x00, 0x2d, 0x37,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x88, 0x0d, 0x8b, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xb4, 0x08, 0x80, 0x6e, 0x32,
- 0x00, 0x00, 0x45, 0x0c, 0x04, 0x31, 0x01, 0x90, 0x08, 0x00, 0x6e, 0xb2,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
- 0x18, 0x00, 0x43, 0x0c, 0x86, 0x41, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0x3f, 0x78, 0xb0,
- 0x00, 0x00, 0x3c, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
- 0xb7, 0x00, 0x3c, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0x30,
- 0x00, 0x00, 0x58, 0x0c, 0x00, 0x00, 0x00, 0x04, 0xd8, 0x62, 0x80, 0x9c,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x1b, 0x89, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x80, 0x2f, 0xb6,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
- 0x18, 0x00, 0x4e, 0x0c, 0x86, 0x41, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0x3f, 0x78, 0xb0,
- 0x00, 0x00, 0x47, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
- 0xb7, 0x00, 0x47, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x51, 0x0c, 0x28, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x04, 0xd8, 0x62, 0x80, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x40, 0x80, 0xb2,
- 0x00, 0x00, 0x55, 0x0c, 0x02, 0x01, 0x00, 0x90, 0x18, 0x20, 0x89, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x47, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
- 0xb7, 0x00, 0x47, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x58, 0x0c, 0x04, 0x00, 0x00, 0x90, 0x18, 0x20, 0x89, 0xba,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x04, 0x48, 0x62, 0x80, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x90, 0x00, 0x00, 0xb4, 0x48, 0x62, 0x8b, 0xba,
- 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x08, 0x1e, 0xff, 0xb8,
- 0x00, 0x00, 0x60, 0x0c, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x22, 0x80, 0x9a,
- 0x00, 0x00, 0x89, 0x0c, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xe2, 0x8a, 0xbc,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x8d, 0x8a, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xc2, 0xa2, 0x2c, 0x3a,
- 0x18, 0x00, 0x87, 0x0c, 0x86, 0x40, 0x02, 0x78, 0x88, 0x0d, 0x78, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x04, 0xb8, 0x3f, 0x78, 0xb0,
- 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x08, 0x1e, 0xff, 0xb8,
- 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
- 0x00, 0x00, 0x67, 0x0c, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
- 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0x72, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
- 0x20, 0x80, 0x64, 0x0c, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb8, 0x1b, 0x80, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x64, 0x30, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xf7, 0x01, 0x0b, 0x34,
- 0x00, 0x00, 0x81, 0x0c, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xb7, 0x01, 0x70, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
- 0x00, 0x00, 0x93, 0x0c, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x1b, 0x89, 0xbc,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x5a, 0x0c, 0x9f, 0x01, 0x00, 0xa8, 0x18, 0x80, 0x8a, 0xbc,
- 0xb7, 0x00, 0x5a, 0x0c, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x36, 0x92,
- 0x27, 0x00, 0x8c, 0x0c, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x78, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0xa2, 0x97, 0xbc,
- 0x00, 0x00, 0x8e, 0x0c, 0x23, 0x55, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0xb2,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x90, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc7, 0x01, 0x70, 0x34,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x08, 0x00, 0x97, 0x0c, 0x23, 0x19, 0x01, 0xe8, 0x76, 0x20, 0x81, 0xb9,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x99, 0x0c, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x9c, 0x0c, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x9c, 0x0c, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xc6, 0x0e, 0x00, 0x00, 0x00, 0x2c, 0xf9, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xa0, 0x0c, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0xa4, 0x03, 0xca, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0xc0, 0xad, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x18, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x82, 0xb6,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x01, 0xec, 0x66, 0x00, 0x00, 0x34,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0xe0, 0xe6, 0xa0, 0x82, 0x39,
- 0x1b, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x20, 0x00, 0x84, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0xc0, 0xb6, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x02, 0xf2,
- 0x00, 0x00, 0xbd, 0x0c, 0x00, 0x00, 0x00, 0x5c, 0x08, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0xc0, 0xbd, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x9c, 0x10, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0xf2,
- 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x20, 0x00, 0x84, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xc2, 0x0c, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xc6, 0x0c, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x85, 0xb2,
- 0x00, 0x00, 0xc6, 0x0c, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x80, 0x06, 0xc0, 0x85, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1c, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x4c, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x4c, 0x0d, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x85, 0x92,
- 0x00, 0x00, 0x1a, 0x0d, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x22, 0x0d, 0x1f, 0x20, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x1a, 0x0d, 0x04, 0x30, 0x01, 0x08, 0x89, 0x9b, 0x90, 0xbc,
- 0x00, 0x00, 0xd2, 0x0c, 0x04, 0x31, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xd0, 0x0c, 0x00, 0x50, 0x01, 0x48, 0x08, 0x80, 0x6e, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x61, 0x80, 0x3c,
- 0x00, 0x00, 0xeb, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x28, 0x21, 0x80, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x80, 0x90, 0xb2,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x30, 0x01, 0x48, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0xd6, 0x0c, 0x00, 0x50, 0x01, 0x04, 0xa8, 0x5b, 0x80, 0x9c,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x3a,
- 0x00, 0x00, 0xe8, 0x0c, 0x07, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x38,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xe1, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe8, 0x0c, 0x07, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
- 0x05, 0x00, 0xde, 0x0c, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x98,
- 0x00, 0x00, 0xeb, 0x0c, 0x04, 0x00, 0x00, 0x48, 0x18, 0xa0, 0x84, 0xba,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x04, 0x28, 0x61, 0x80, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x21, 0x80, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0xf4, 0x0c, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
- 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x38, 0x1a, 0xff, 0xb8,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x60, 0x80, 0x39,
- 0x18, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x8c, 0xe6, 0xa1, 0x97, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x80, 0x84, 0x32,
- 0x00, 0x82, 0x00, 0x00, 0xd6, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x28, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0xfe, 0x0c, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
- 0x00, 0x00, 0xed, 0x0c, 0x12, 0x01, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x17, 0xe0, 0x2c, 0x39,
- 0x00, 0x00, 0x0d, 0x0d, 0x80, 0x00, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
- 0x00, 0x10, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x0e, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x10, 0x00, 0x88, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x38,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0xeb, 0x0c, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x22, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x05, 0x00, 0x1d, 0x0d, 0x00, 0x00, 0x00, 0x68, 0x02, 0xa0, 0xfe, 0x98,
- 0x00, 0x00, 0x22, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x05, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xa0, 0xfe, 0xd8,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa0, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x1a, 0x0d, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
- 0xb4, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xc0, 0x2c, 0x37,
- 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x2b, 0x0d, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x20, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0xa2, 0xcd, 0x2c, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x30, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xa2, 0x07, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x62, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x39, 0x0d, 0x12, 0x01, 0x00, 0x60, 0x08, 0x40, 0x23, 0xb2,
- 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x28, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x24, 0x08, 0x00, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x20, 0x08, 0xc0, 0x23, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x18, 0x08, 0x80, 0x23, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0x43, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x38, 0x02, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x3c, 0x02, 0x00, 0x82, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x30, 0x02, 0x40, 0x82, 0xb2,
- 0x00, 0x00, 0xed, 0x0c, 0x12, 0x01, 0x00, 0x34, 0x02, 0x00, 0x86, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x00, 0x00, 0x48, 0x08, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0x46, 0x0d, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x0d, 0x00, 0x50, 0x01, 0x00, 0xa8, 0x1b, 0x80, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x80, 0x02, 0xf2,
- 0x00, 0x00, 0x2b, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x58, 0x10, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x02, 0xf2,
- 0x00, 0x00, 0x4f, 0x0d, 0x9a, 0x01, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0xb4,
- 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x06, 0xc0, 0x6e, 0x34,
- 0x2d, 0x00, 0xa2, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa9, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x5a, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x56, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x5a, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0x5a, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x58, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x5c, 0x0d, 0x04, 0x98, 0x01, 0x64, 0x88, 0x1b, 0x87, 0xbc,
- 0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x80, 0x6e, 0xf2,
- 0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x30, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x6c, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x68, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x6c, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0x6c, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x6a, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0xa4, 0x07, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x36, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7d, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x79, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x7d, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0x7d, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x7b, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x88, 0x0d, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x86, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x82, 0x0d, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x86, 0x0d, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0x86, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0x84, 0x0d, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x30, 0x00, 0x88, 0x0d, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd5, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xa2, 0x07, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xa2, 0x07, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x93, 0x0d, 0x80, 0x00, 0x00, 0x80, 0x02, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x58, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0xa2, 0x07, 0x08, 0x59, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0xc0, 0x9c, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xfb, 0x6e, 0x3a,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x81, 0x2f, 0xf4,
- 0x00, 0x00, 0x9f, 0x0d, 0x06, 0x03, 0x01, 0x80, 0x12, 0xc0, 0x6e, 0xbc,
- 0x18, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x19, 0x00, 0x9d, 0x05, 0x00, 0x00, 0x00, 0x1c, 0x08, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x81, 0x2f, 0xb6,
- 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0x31,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x20, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x28, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x45, 0x30, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xc7, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xad, 0x0d, 0x04, 0x02, 0x01, 0xec, 0x16, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xc9, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x34,
- 0x00, 0xc0, 0xad, 0x0d, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x18, 0x00, 0x36, 0x00, 0xca, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xad, 0x0d, 0x9f, 0x01, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0xb2, 0x0d, 0x3d, 0x01, 0x00, 0xb0, 0x02, 0x00, 0x85, 0xb2,
- 0x00, 0x00, 0xb2, 0x0d, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
- 0x34, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xa4, 0x07, 0x80, 0x01, 0x00, 0x80, 0x92, 0x80, 0x2f, 0xb6,
- 0x2a, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x54, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0xc0, 0xbc, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x20, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x00, 0x00, 0x9d, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x72, 0xe0, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x20, 0x00, 0x80, 0xdf, 0x00, 0x00, 0x28, 0x09, 0x00, 0x37, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x48, 0x01, 0x38, 0x88, 0x1b, 0x16, 0x38,
- 0x00, 0x00, 0x00, 0x00, 0xde, 0x48, 0x01, 0x28, 0x88, 0x04, 0x6e, 0x30,
- 0x00, 0x00, 0xc1, 0x0d, 0x80, 0x5f, 0x01, 0x80, 0x72, 0xc0, 0x6e, 0xb6,
- 0x00, 0x00, 0xc3, 0x0d, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x94,
- 0x00, 0x00, 0xc3, 0x0d, 0x80, 0x5f, 0x01, 0x80, 0x62, 0xc0, 0x6e, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xa9, 0x81, 0x92, 0x34,
- 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x00, 0x08, 0xe8, 0x01, 0x00, 0xf4,
- 0x00, 0x00, 0xc6, 0x0d, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc9, 0x0d, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xc9, 0x0d, 0x34, 0x00, 0x00, 0xf8, 0xd2, 0x81, 0x2f, 0xb5,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0xa4, 0x07, 0x04, 0x30, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x2a, 0x00, 0xa4, 0x07, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x80, 0x01, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0xc0, 0xd2, 0x0d, 0x18, 0x01, 0x00, 0x0c, 0xa8, 0xcd, 0x3e, 0xb2,
- 0x00, 0x82, 0x00, 0x00, 0xd6, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x32,
- 0x1d, 0x00, 0xa1, 0x03, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xc2, 0x10, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x80, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x01, 0x78, 0x09, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
- 0x00, 0x10, 0x00, 0xa0, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x07, 0x00, 0xee, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x0c, 0x07, 0x80, 0x97, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0xf0, 0xe1, 0x0d, 0x1d, 0x40, 0x02, 0x00, 0xa8, 0x0d, 0x68, 0xb1,
- 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x1e, 0x40, 0x02, 0x84, 0x06, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x80, 0xd0,
- 0x00, 0x00, 0xde, 0x0d, 0xb6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0xc0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x64, 0xa2, 0x0d, 0x80, 0xb2,
- 0x00, 0x00, 0xda, 0x0d, 0xa6, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xe1, 0x0d, 0xb5, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x80, 0xa0, 0x36, 0x0b, 0x6a, 0x35,
- 0x00, 0x00, 0xe6, 0x0d, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x80, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xe9, 0x01, 0x00, 0x34,
- 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xd2,
- 0x00, 0x00, 0xeb, 0x0d, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x39, 0x0b, 0x2e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xf3, 0x81, 0x97, 0x34,
- 0x00, 0x00, 0xf1, 0x0d, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x05, 0x30, 0x30,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xa4, 0x03, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x33, 0x0b, 0x2f, 0x32,
- 0x00, 0x00, 0xa4, 0x03, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x97, 0x32,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x29, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xff, 0x0d, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x2f, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x2c, 0x32,
- 0xd9, 0x02, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
- 0x46, 0x03, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xf1, 0x0d, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x18, 0x0e, 0x02, 0x00, 0x00, 0x80, 0xa2, 0x42, 0x80, 0xbc,
- 0x00, 0x00, 0x18, 0x0e, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0x18, 0x0e, 0x1f, 0x40, 0x02, 0x08, 0xb9, 0xbf, 0x68, 0xb0,
- 0x00, 0x00, 0x08, 0x0e, 0x80, 0x41, 0x02, 0x80, 0xe2, 0x81, 0x68, 0xb6,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x61, 0x80, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0xd2, 0x21, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x41, 0x02, 0x88, 0xe6, 0x21, 0x91, 0x79,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x19, 0xa0, 0x90, 0x3a,
- 0x00, 0x00, 0x18, 0x0e, 0x06, 0x01, 0x00, 0x80, 0xd2, 0xff, 0x90, 0xbc,
- 0x00, 0x00, 0x0c, 0x0e, 0x2c, 0x41, 0x02, 0x78, 0xf9, 0x81, 0x68, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x81, 0x97, 0x34,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x59, 0xc0, 0x85, 0xd7,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x29, 0x1a, 0xff, 0x38,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb9, 0x1b, 0x90, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0xd2, 0x41, 0x02, 0x88, 0x16, 0xa0, 0x97, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x27, 0x24, 0x90, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x8a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x58, 0xf2, 0xc1, 0x38, 0x74,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x08, 0x00, 0x23, 0x0e, 0x1e, 0x01, 0x00, 0x34, 0x79, 0x61, 0x80, 0xb9,
- 0x00, 0x00, 0x8a, 0x11, 0x38, 0x00, 0x00, 0x54, 0x1f, 0x40, 0xf5, 0xba,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x40, 0x02, 0x00, 0x09, 0x40, 0x68, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0x3f, 0x90, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x26, 0x24, 0x6e, 0x3a,
- 0x08, 0x00, 0x8a, 0x11, 0x1e, 0x00, 0x00, 0x00, 0x09, 0xa4, 0xfe, 0xb8,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x05, 0x90, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x05, 0x90, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x05, 0x90, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xd2, 0x21, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
- 0x18, 0x00, 0x00, 0x00, 0x1e, 0x41, 0x02, 0x84, 0xe6, 0x61, 0x93, 0x79,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x20, 0x01, 0x80, 0x82, 0xdb, 0x90, 0x7c,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x20, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0xdb, 0x90, 0x7c,
- 0x00, 0x00, 0x2d, 0x0e, 0x06, 0x21, 0x01, 0x80, 0x82, 0x1b, 0x90, 0xbc,
- 0x26, 0x00, 0x2e, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x92,
- 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x92, 0xd2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x92, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x2f, 0xa0, 0x01, 0x78, 0x89, 0x1b, 0x92, 0x7a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x78, 0x89, 0x9b, 0x97, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0xf9, 0xba, 0x6e, 0x37,
- 0x00, 0x00, 0x39, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x97, 0xbc,
- 0x00, 0x00, 0x39, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x97, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x97, 0x7c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xf2, 0x80, 0x2f, 0x74,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xda, 0x5b, 0x01, 0xec, 0x06, 0x40, 0xed, 0x32,
- 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x89, 0xd2,
- 0x00, 0x00, 0x42, 0x0e, 0x08, 0x5d, 0x01, 0xec, 0x16, 0x40, 0x89, 0xbc,
- 0x00, 0x00, 0x42, 0x0e, 0x0b, 0x5d, 0x01, 0xec, 0x06, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x42, 0x0e, 0x80, 0x00, 0x00, 0x80, 0x42, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x78, 0x89, 0x1b, 0x87, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x92, 0xa1, 0x97, 0xbc,
- 0x00, 0x00, 0x47, 0x0e, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x86, 0xbc,
- 0x00, 0x00, 0x0a, 0x11, 0x00, 0x90, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
- 0x00, 0x00, 0x3f, 0x11, 0x33, 0x01, 0x00, 0xf8, 0x82, 0x80, 0x2f, 0xb4,
- 0x00, 0x00, 0x3f, 0x11, 0x9f, 0xf0, 0x01, 0x80, 0x82, 0xdb, 0x87, 0xbc,
- 0x00, 0x00, 0x3f, 0x11, 0x9f, 0xf8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xe0, 0x06, 0xc0, 0x87, 0x32,
- 0x00, 0x00, 0x3f, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x08, 0x00, 0x00, 0x80, 0x02, 0x80, 0x91, 0xbc,
- 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x50, 0x01, 0x14, 0xa9, 0x9b, 0x91, 0xd9,
- 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x14, 0x89, 0x0d, 0x6e, 0x37,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x30, 0x01, 0x14, 0x89, 0x5b, 0x91, 0xd2,
- 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x2d, 0xd2,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x21, 0x01, 0x80, 0x82, 0x9b, 0x91, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x78, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x9b, 0x97, 0xbc,
- 0x00, 0x00, 0x71, 0x0e, 0x04, 0x21, 0x01, 0x30, 0x69, 0x24, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0xa9, 0x9b, 0x91, 0x3a,
- 0x00, 0x00, 0x66, 0x0e, 0x1f, 0x40, 0x02, 0x24, 0x09, 0x40, 0x68, 0xb2,
- 0x00, 0x00, 0x5c, 0x0e, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x41, 0x92, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xb9, 0x7f, 0x92, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3c,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xa4, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x08, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x99, 0xa4, 0xfe, 0xd8,
- 0x08, 0x00, 0x5c, 0x0e, 0x12, 0x01, 0x00, 0x68, 0x92, 0xa4, 0xfe, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xbc,
- 0x00, 0x00, 0x6b, 0x0e, 0x38, 0x50, 0x01, 0x78, 0x09, 0x80, 0x6e, 0xb2,
- 0x00, 0x00, 0x6b, 0x0e, 0x04, 0x28, 0x01, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x28, 0x01, 0x78, 0xe9, 0x25, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x08, 0x01, 0x00, 0x78, 0x69, 0xa4, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
- 0x00, 0x00, 0x6e, 0x0e, 0x38, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0xb2,
- 0x00, 0x00, 0x6f, 0x0e, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0x77, 0x0e, 0x38, 0x51, 0x01, 0x00, 0xa9, 0x9b, 0x91, 0xba,
- 0x00, 0x00, 0x75, 0x0e, 0x04, 0x41, 0x02, 0x08, 0xb9, 0xff, 0x68, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x41, 0x02, 0x80, 0xe2, 0xc1, 0x68, 0xb6,
- 0x00, 0x00, 0x72, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
- 0x00, 0x00, 0x84, 0x0e, 0x9f, 0x31, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0xbc,
- 0x00, 0x00, 0x84, 0x0e, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x92,
- 0x00, 0x00, 0x81, 0x0e, 0x04, 0x28, 0x01, 0x04, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x50, 0x01, 0x80, 0xa2, 0x5b, 0x90, 0xbc,
- 0x00, 0x00, 0x7f, 0x0e, 0x9f, 0x01, 0x00, 0x00, 0x19, 0x24, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x24, 0x00, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x8e, 0x0e, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xbc,
- 0x00, 0x00, 0x84, 0x0e, 0x04, 0x41, 0x02, 0x08, 0xb9, 0xff, 0x68, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x41, 0x02, 0x80, 0xe2, 0xc1, 0x68, 0xb6,
- 0x00, 0x00, 0x81, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
- 0x00, 0x00, 0x88, 0x0e, 0x02, 0x00, 0x00, 0x80, 0x22, 0x24, 0x90, 0xbc,
- 0x00, 0x00, 0x8e, 0x0e, 0x80, 0x40, 0x02, 0x80, 0xf2, 0xc1, 0x68, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x8c, 0xb6, 0xc1, 0x68, 0x35,
- 0x00, 0x00, 0x8e, 0x0e, 0x00, 0x00, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0x94,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
- 0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
- 0x00, 0x00, 0x81, 0x0e, 0x04, 0x01, 0x00, 0x00, 0x29, 0x24, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x0b, 0x16, 0x38,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x79, 0x0b, 0x16, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x42, 0xe4, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xa9, 0x00, 0x2d, 0x37,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x4d, 0x90, 0x3a,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x82, 0x0d, 0x91, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x12, 0xa4, 0x2a, 0x3a,
- 0x00, 0x00, 0x99, 0x0e, 0x80, 0x40, 0x02, 0x80, 0xe2, 0x01, 0x7c, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x78, 0xb9, 0x3f, 0x7c, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3a,
- 0x00, 0x00, 0x9b, 0x0e, 0x9f, 0x01, 0x00, 0x10, 0x19, 0x00, 0x91, 0xbc,
- 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x94, 0x0e, 0x04, 0x01, 0x00, 0x80, 0x42, 0xe4, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xc9, 0x24, 0x90, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0xa4, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x66, 0x24, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0xe0, 0x06, 0x00, 0x93, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x18, 0x00, 0xa5, 0x0e, 0x1f, 0x41, 0x02, 0x78, 0x88, 0xcd, 0x68, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
- 0x00, 0x00, 0xa8, 0x0e, 0x80, 0x01, 0x00, 0x80, 0x62, 0x80, 0x87, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x41, 0x02, 0x80, 0xb2, 0xff, 0x68, 0xb0,
- 0x00, 0x00, 0xa3, 0x0e, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x92,
- 0x03, 0x00, 0x8a, 0x11, 0x04, 0x40, 0x02, 0x00, 0x38, 0x1a, 0xff, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x40, 0x02, 0x04, 0xb8, 0xff, 0x68, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x02, 0x00, 0xb8, 0x1b, 0x80, 0x3a,
- 0x2e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x00, 0x80, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xb6, 0x0e, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xb3, 0x0e, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x1d, 0x00, 0xb6, 0x0e, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xb0, 0x0e, 0x9f, 0x01, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x68, 0x00, 0x4c, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x70, 0x00, 0x18, 0x08, 0x00, 0x6e, 0xb2,
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0xa9, 0x60, 0x81, 0xd9,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0xa2, 0xa0, 0x81, 0x7c,
- 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xc1, 0x0e, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xc1, 0x0e, 0x1b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x62, 0xe0, 0x83, 0x7c,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
- 0x00, 0xa0, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0x72,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xe4, 0x06, 0xc0, 0x2d, 0x32,
- 0xee, 0xff, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x86, 0x8d, 0x2f, 0x31,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0xb3, 0xe4, 0x39, 0x32,
- 0x00, 0x00, 0xcd, 0x0e, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe3, 0xa5, 0x03, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x33, 0x0b, 0x2f, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0x76,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xb9, 0x05, 0x30, 0x30,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xe3, 0xa5, 0x03, 0x79,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xd8, 0x0e, 0x20, 0x00, 0x01, 0x2c, 0x09, 0xc0, 0x6e, 0xb2,
- 0x00, 0x00, 0xd9, 0x0e, 0x00, 0x16, 0x86, 0xcc, 0x06, 0xc0, 0x92, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x86, 0xcc, 0x06, 0xc0, 0x92, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0x62, 0x8e, 0x92, 0x52,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xdf, 0x0e, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x42, 0x80, 0x97, 0xbc,
- 0xdf, 0x0e, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x60, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb1,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x38, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x30, 0x32,
- 0x00, 0x00, 0x22, 0x0f, 0x04, 0x00, 0x00, 0x24, 0xd8, 0x01, 0x30, 0xb6,
- 0xe4, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0x4d, 0x82, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0xdf, 0x0e, 0x36, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x02, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xec, 0x0e, 0x00, 0x00, 0x00, 0x20, 0x48, 0x05, 0x30, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xf7, 0x0e, 0x32, 0x0f, 0x01, 0xbc, 0x08, 0xc0, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x32,
- 0x00, 0x00, 0xf0, 0x0e, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0xf6, 0x0e, 0x1d, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
- 0x20, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x87, 0xa0, 0xea, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0xea, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x38, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xe0, 0x26, 0x01, 0x6e, 0x35,
- 0x00, 0x00, 0xfb, 0x0e, 0x80, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x8b, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0e, 0x82, 0x32,
- 0x00, 0xe0, 0x03, 0x0f, 0x12, 0x01, 0x00, 0x48, 0xa2, 0x0d, 0x90, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x32,
- 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0x00, 0x82, 0x37,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x10, 0x00, 0x00, 0x87, 0xbf, 0x97, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x40, 0xfe, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x60, 0x38, 0x32,
- 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa4, 0x17, 0x38,
- 0x00, 0x00, 0x09, 0x0f, 0x80, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x8b, 0xb6,
- 0x00, 0x00, 0x0a, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xf3, 0x41, 0x90, 0x34,
- 0x00, 0x00, 0x0f, 0x0f, 0x04, 0x00, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x05, 0x30, 0x30,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0xa4, 0x03, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0xce, 0x2c, 0x32,
- 0x00, 0xe0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x0d, 0x90, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x32,
- 0x1d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xa4, 0x17, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x32, 0x80, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x10, 0x01, 0x80, 0x22, 0x01, 0x6e, 0xb6,
- 0x00, 0x00, 0x18, 0x0f, 0x1f, 0x01, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x20, 0x0f, 0x1d, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0xb2,
- 0xe0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x00, 0x2d, 0x37,
- 0x20, 0xcd, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x97, 0x3a,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x37, 0x8b, 0xea, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0xea, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x32,
- 0xee, 0xff, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0xee, 0xff, 0x8a, 0x11, 0x04, 0x11, 0x01, 0x80, 0x82, 0x0d, 0x6e, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x01, 0xf8, 0x02, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x01, 0xdc, 0x02, 0x40, 0x6e, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
- 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x89, 0x4d, 0x0d, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x80, 0x0b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x2b, 0x0f, 0x12, 0x00, 0x00, 0x4c, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x2c, 0x0f, 0x12, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe9, 0x02, 0x90, 0x3a,
- 0x00, 0x00, 0x28, 0x0f, 0x04, 0x01, 0x00, 0x04, 0x19, 0x40, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x3b, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x35, 0x0f, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x3a, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x22, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x80, 0x18, 0x00, 0x88, 0xbc,
- 0x00, 0x00, 0x35, 0x0f, 0x12, 0x01, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x34, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x6c, 0x88, 0x1c, 0x83, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x00, 0x18, 0xc8, 0x20, 0x72, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x81, 0x7c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x20, 0x88, 0x01, 0x82, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x00, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0xc0, 0x86, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0xc0, 0x84, 0x32,
- 0x00, 0x00, 0xa3, 0x0f, 0x04, 0x00, 0x00, 0x28, 0xd8, 0xa0, 0x82, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x09, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0xd8, 0xa0, 0x81, 0x3c,
- 0x00, 0x00, 0x67, 0x0f, 0x04, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
- 0x00, 0x00, 0x58, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0x02, 0xc0, 0x38, 0xb2,
- 0x00, 0x00, 0x60, 0x0f, 0x51, 0x00, 0x00, 0xd8, 0x12, 0x80, 0x2d, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x5e, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x59, 0x0f, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x65, 0x0f, 0x2a, 0x01, 0x00, 0x00, 0xd8, 0x20, 0x80, 0xba,
- 0x00, 0x00, 0x64, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x4d, 0x0f, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x6e, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x68, 0x0f, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x78, 0x39, 0x9a, 0xfe, 0x38,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
- 0x08, 0x00, 0x8a, 0x11, 0x12, 0x40, 0x02, 0x68, 0x12, 0x9a, 0xfe, 0xb8,
- 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x00, 0x00, 0x86, 0x0f, 0x1f, 0x00, 0x00, 0x6c, 0xd8, 0xe0, 0x86, 0xba,
- 0x00, 0x00, 0xa3, 0x0e, 0x51, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0xf2,
- 0x00, 0x00, 0x79, 0x0f, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x40, 0x80, 0x92,
- 0x00, 0x00, 0x86, 0x0f, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7e, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x7e, 0x0f, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x7e, 0x0f, 0x80, 0x01, 0x00, 0x80, 0x32, 0x80, 0x87, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xe2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x4c, 0x0f, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x81, 0xbc,
- 0x00, 0x00, 0x84, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x83, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x4d, 0x0f, 0x4d, 0x00, 0x00, 0x00, 0x67, 0xe0, 0x83, 0x9e,
- 0x00, 0x00, 0x89, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xa7, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0xa8, 0x60, 0x8a, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x21, 0x01, 0x80, 0x82, 0x5b, 0x8a, 0xbc,
- 0x00, 0x00, 0x8d, 0x0f, 0x2f, 0xa8, 0x01, 0x20, 0x99, 0x22, 0x6e, 0xba,
- 0x00, 0x00, 0x2f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x02, 0x80, 0x82, 0x1b, 0x92, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x06, 0x00, 0x92, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x01, 0xe8, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x92, 0x0f, 0x23, 0x21, 0x01, 0xe0, 0x06, 0x00, 0x00, 0xb2,
- 0x3c, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x30, 0x00, 0xe0, 0x06, 0x80, 0x82, 0xb2,
- 0x00, 0x00, 0x9c, 0x0f, 0x04, 0x21, 0x00, 0xe0, 0x06, 0x80, 0x81, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xe2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x9a, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x99, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x32,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0xb7, 0x0e, 0x00, 0x60, 0x00, 0x6c, 0x08, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0xe0, 0x06, 0x80, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0xe8, 0x06, 0x40, 0x81, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x10, 0x00, 0xe0, 0x06, 0xc0, 0x86, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x2a, 0x19, 0x00, 0xe0, 0x06, 0xc0, 0x84, 0x72,
- 0x00, 0x00, 0xa1, 0x0f, 0x12, 0x01, 0x00, 0x00, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x1d, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xa4, 0x17, 0xb8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x75,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0xd8, 0xe0, 0x83, 0x3c,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0x32,
- 0xee, 0x05, 0xaf, 0x0f, 0x04, 0x01, 0x00, 0x80, 0x82, 0x4d, 0xf5, 0xbc,
- 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xb1, 0x0f, 0x00, 0x00, 0x00, 0x04, 0x09, 0xc0, 0x09, 0x92,
- 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x80, 0x09, 0x32,
- 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xc0, 0x87, 0xcd, 0x00, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x60, 0xc0, 0x07, 0x80, 0x97, 0x32,
- 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x8d, 0x2a, 0x3a,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x97, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x19, 0x40, 0x90, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x52, 0x82, 0x2a, 0x3a,
- 0x00, 0x08, 0xb1, 0x0f, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2a, 0xbc,
- 0x00, 0x00, 0xc2, 0x0f, 0x06, 0x00, 0x00, 0x80, 0x02, 0x40, 0x90, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x20, 0xb2,
- 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x87, 0xcd, 0x00, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0xc0, 0x07, 0x80, 0x97, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x5c, 0x52, 0x81, 0x2a, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
- 0x00, 0x00, 0xbb, 0x0f, 0x04, 0x01, 0x00, 0x04, 0x19, 0x40, 0x90, 0xbc,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x89, 0x0d, 0x90, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0e, 0x80, 0x97, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0x80, 0x97, 0xb2,
- 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x89, 0x0d, 0x90, 0x36,
- 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x89, 0x4d, 0x92, 0x3c,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0x4d, 0x92, 0x36,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x89, 0x4d, 0x92, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x18, 0x9b, 0x81, 0xb2, 0xe4, 0x78, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x9b, 0x8d, 0xb7, 0xe4, 0x78, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0e, 0x80, 0x97, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x24, 0x90, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x59, 0x00, 0x90, 0x36,
- 0x00, 0x00, 0xc4, 0x0f, 0x95, 0x01, 0x00, 0x80, 0x22, 0x24, 0x90, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xec, 0x0f, 0x04, 0x01, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0x29, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xb2, 0x45, 0x28, 0x30,
- 0x00, 0x00, 0xdd, 0x0f, 0x86, 0x01, 0x00, 0x08, 0x09, 0x80, 0x2f, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x40, 0x81, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x92, 0x32,
- 0x00, 0x00, 0xdc, 0x0f, 0x04, 0x07, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0xbc,
- 0x00, 0x00, 0xe7, 0x0f, 0xc3, 0x07, 0x01, 0xec, 0xb6, 0xe4, 0x6e, 0x9a,
- 0x00, 0x00, 0xe7, 0x0f, 0x00, 0x06, 0x01, 0xec, 0xb6, 0xe4, 0x6e, 0x9a,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x52, 0x80, 0x90, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x09, 0x05, 0x80, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf4, 0x02, 0x00, 0x00, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x80, 0x92, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xf2, 0xc1, 0x92, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xfa, 0x92, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xfa, 0x92, 0xbc,
- 0x44, 0x00, 0x2c, 0x10, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x8d, 0x2f, 0xd2,
- 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x92, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0x32,
- 0x00, 0x00, 0xec, 0x0f, 0x04, 0x01, 0x00, 0x78, 0xd9, 0x01, 0x30, 0xb6,
- 0x00, 0x00, 0xd4, 0x0f, 0x00, 0x00, 0x00, 0x9c, 0xb2, 0x45, 0x28, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x22, 0x80, 0x97, 0x7c,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0xe8, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0xc0, 0xe8, 0x32,
- 0x02, 0x00, 0xf1, 0x0f, 0xb0, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0xb9,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
- 0x00, 0x00, 0xf6, 0x0f, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0xf9, 0x0f, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
- 0x00, 0x00, 0x00, 0x10, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xc2, 0x4a, 0xd0, 0xb6,
- 0x00, 0x00, 0xfd, 0x0f, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
- 0x00, 0x00, 0x00, 0x10, 0xb0, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0xb7,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
- 0x00, 0x00, 0x08, 0x10, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x69, 0x81, 0x97, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0b, 0x00, 0x7c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
- 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x0e, 0x10, 0xb0, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xe4, 0xb0, 0x32,
- 0x00, 0x00, 0x13, 0x10, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x28, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x16, 0x10, 0x04, 0x00, 0x00, 0x80, 0x02, 0x00, 0xf8, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x80, 0x01, 0x00, 0xf8, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0d, 0x40, 0xd0, 0x34,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
- 0x00, 0x00, 0x1d, 0x10, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x02, 0x40, 0xd0, 0xb6,
- 0x00, 0x00, 0x1a, 0x10, 0xb0, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x04, 0x0d, 0x40, 0xd0, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
- 0x00, 0x00, 0x1d, 0x10, 0xb0, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x00, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
- 0x00, 0x00, 0x25, 0x10, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x69, 0x81, 0x97, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x08, 0x0b, 0x00, 0x7c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
- 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x1c, 0x41, 0x02, 0x80, 0x06, 0xc0, 0x92, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x92, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x97, 0xd2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x92, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x0b, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x3a,
- 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x92, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x01, 0xb0, 0x02, 0xc0, 0x6e, 0x32,
- 0x00, 0x82, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x08, 0x80, 0x36, 0x52,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x38, 0x80, 0x87, 0x35,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x80, 0x87, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0xe0, 0x16, 0x20, 0x6e, 0x3c,
- 0x08, 0x00, 0x00, 0x00, 0xd2, 0x01, 0x00, 0x78, 0xe9, 0xe5, 0x83, 0x39,
- 0x18, 0x00, 0x8a, 0x11, 0x1f, 0x41, 0x02, 0x84, 0xe6, 0xa1, 0x97, 0xb9,
- 0x00, 0x00, 0x43, 0x10, 0x36, 0x51, 0x01, 0xe8, 0x16, 0xe0, 0x83, 0xbc,
- 0x00, 0x00, 0x43, 0x10, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x45, 0x10, 0x38, 0x21, 0x01, 0xe0, 0x06, 0x40, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0xe0, 0x06, 0x40, 0x80, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, 0xe0, 0x06, 0x00, 0x00, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x92, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x80, 0x92, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
- 0x00, 0x40, 0x00, 0x80, 0x00, 0x38, 0x00, 0x00, 0x07, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x41, 0x01, 0xe0, 0x06, 0x80, 0x92, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x48, 0x02, 0xc0, 0x80, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0xe8, 0x01, 0x00, 0x74,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x62, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x80, 0x92, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x3d, 0x00, 0x0c, 0x07, 0x80, 0x83, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0x72,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x57, 0x01, 0x80, 0x02, 0xc0, 0x6e, 0x7c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x01, 0xec, 0x06, 0x80, 0x92, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xd1, 0x0f, 0x00, 0x00, 0x00, 0x30, 0x03, 0x00, 0x38, 0xf2,
- 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x10, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x19, 0xa0, 0x2c, 0xd9,
- 0x00, 0x00, 0x60, 0x10, 0x9d, 0x11, 0x02, 0x0c, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x61, 0x10, 0x00, 0xf0, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x01, 0x1c, 0x09, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x63, 0x10, 0x2c, 0xcd, 0x01, 0x18, 0x09, 0x80, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xc9, 0xc1, 0x90, 0x34,
- 0x00, 0x00, 0x67, 0x10, 0x3b, 0x29, 0x02, 0x04, 0x09, 0x80, 0x6e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0xd6, 0x01, 0x80, 0x52, 0xc0, 0x6e, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0x01, 0xec, 0x56, 0xc0, 0x6e, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xb9, 0xc1, 0x90, 0x34,
- 0x00, 0x00, 0x77, 0x10, 0x00, 0xa8, 0x01, 0x08, 0x09, 0x00, 0x6e, 0xf2,
- 0x00, 0x00, 0x6b, 0x10, 0x9d, 0x01, 0x00, 0x80, 0x17, 0xe0, 0x90, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x80, 0x07, 0xc0, 0x91, 0x32,
- 0x00, 0x00, 0x6e, 0x10, 0x00, 0x38, 0x00, 0x80, 0x07, 0x00, 0xee, 0x92,
- 0x00, 0x00, 0x6e, 0x10, 0x04, 0x01, 0x00, 0x80, 0x02, 0xc0, 0x91, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x01, 0xe0, 0x06, 0x00, 0xee, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x01, 0xe0, 0x06, 0x00, 0x86, 0x32,
- 0x00, 0x00, 0x71, 0x10, 0x39, 0x08, 0x00, 0x80, 0x07, 0xc0, 0x85, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xc2, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xd9, 0xc9, 0x01, 0xe8, 0x06, 0x80, 0x91, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xc8, 0x11, 0x00, 0x80, 0x07, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x74, 0x10, 0x3b, 0x21, 0x00, 0x80, 0x07, 0x00, 0x86, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x60, 0x18, 0x00, 0x86, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x58, 0x78, 0x01, 0xe0, 0x16, 0x20, 0x86, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0x00, 0x80, 0x07, 0x00, 0x85, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x7b, 0x10, 0x02, 0x0c, 0x02, 0x80, 0xa2, 0x9b, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x78, 0x29, 0x00, 0x6e, 0x36,
- 0x00, 0x00, 0x7b, 0x10, 0x02, 0x00, 0x00, 0x80, 0xe2, 0xa5, 0x90, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x01, 0x78, 0x49, 0x21, 0x6e, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3f,
- 0x00, 0x00, 0x82, 0x10, 0x04, 0x20, 0x02, 0x08, 0x89, 0x9b, 0x90, 0xbe,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x02, 0x58, 0xb8, 0x9b, 0x90, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x49, 0xa1, 0x90, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x9f, 0x88, 0x01, 0x80, 0x82, 0x9b, 0x97, 0x7c,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x01, 0xe0, 0x06, 0x80, 0x97, 0x72,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x02, 0x58, 0xb8, 0x9b, 0x90, 0x76,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8b, 0x10, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x89, 0x10, 0x12, 0x01, 0x00, 0x78, 0x09, 0xc0, 0x21, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8b, 0x10, 0xca, 0x00, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x92,
- 0x15, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x78, 0xe9, 0x65, 0x17, 0xb8,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0x35,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x6c, 0x88, 0x1c, 0x83, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x4c, 0x08, 0x00, 0x72, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x08, 0x50, 0x00, 0x18, 0xc8, 0x20, 0x72, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x80, 0x62, 0xa0, 0x82, 0x7c,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x00, 0x00, 0x14, 0x18, 0x40, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x00, 0x00, 0x20, 0x88, 0x01, 0x82, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x02, 0x00, 0x36, 0xbc,
- 0x07, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x77, 0x4a, 0x09, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0x82, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x19, 0x00, 0x00, 0x07, 0x40, 0x82, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0xc1, 0x38, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x84, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x85, 0xd2,
- 0x00, 0x00, 0xa6, 0x10, 0x80, 0x01, 0x00, 0x80, 0xf2, 0xc1, 0x85, 0xb6,
- 0x00, 0x00, 0xa2, 0x10, 0x1f, 0x40, 0x02, 0x84, 0xe6, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0xa6, 0x10, 0x1d, 0x01, 0x00, 0xf8, 0x22, 0x81, 0x2f, 0xb4,
- 0x00, 0x00, 0xa6, 0x10, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x95,
- 0x00, 0x00, 0xa4, 0x10, 0x1d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x62, 0x81, 0x2f, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x80, 0x02, 0x40, 0x68, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x1f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x73, 0x11, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc5, 0x85, 0xd0,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x68, 0x02, 0xc5, 0x85, 0xb0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x09, 0xc5, 0x85, 0x30,
- 0x00, 0x00, 0x8a, 0x11, 0x02, 0x01, 0x00, 0x80, 0x82, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x06, 0x01, 0x00, 0x80, 0x92, 0xba, 0x97, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x5c, 0x1f, 0xc0, 0xf5, 0x7a,
- 0x01, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0x70,
- 0x29, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x02, 0x81, 0x2f, 0x74,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x80, 0xa8, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0x70,
- 0x00, 0x00, 0xb7, 0x10, 0x80, 0x01, 0x00, 0x80, 0xd2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x72, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0xba, 0x10, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x72, 0x81, 0x2f, 0x34,
- 0x3b, 0x00, 0xba, 0x10, 0x12, 0x01, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xba, 0x10, 0x80, 0x01, 0x00, 0x80, 0xf2, 0x80, 0x2f, 0xb6,
- 0x30, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0xbd, 0x10, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x94,
- 0x00, 0x00, 0xbd, 0x10, 0x80, 0x01, 0x00, 0x80, 0xb2, 0x80, 0x2f, 0xb6,
- 0x34, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x42, 0x81, 0x2f, 0x34,
- 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x80, 0x82, 0x8d, 0x2f, 0x70,
- 0x02, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0x70,
- 0x3a, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x2c, 0x82, 0xcd, 0x2e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x12, 0x81, 0x2f, 0x74,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x18, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
- 0xee, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x71,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xcb, 0x10, 0x00, 0x00, 0x01, 0x38, 0x08, 0xc0, 0x6e, 0xf2,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0x02, 0xc0, 0x80, 0x72,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xcd, 0x10, 0x04, 0x38, 0x01, 0x78, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x11, 0x00, 0x00, 0x07, 0x80, 0x82, 0x32,
- 0x00, 0x00, 0xd1, 0x10, 0x2e, 0x19, 0x00, 0x00, 0x07, 0x80, 0x97, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xe9, 0x81, 0x92, 0x34,
- 0x00, 0x00, 0xd5, 0x10, 0x27, 0x31, 0x00, 0x00, 0x07, 0xc0, 0x2c, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0xd5, 0x08, 0x00, 0x00, 0x07, 0x00, 0x87, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x28, 0xe9, 0x80, 0x92, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0xe7, 0xa0, 0x92, 0x79,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x90, 0xd2,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x44, 0x12, 0xe4, 0x38, 0xb2,
- 0x18, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x03, 0xf9,
- 0x00, 0x00, 0xdf, 0x10, 0x04, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0xda, 0x10, 0x67, 0x00, 0x00, 0xf8, 0xa2, 0x80, 0x2f, 0xb5,
- 0x00, 0x00, 0x8a, 0x11, 0x12, 0x00, 0x00, 0xe8, 0x02, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0x72, 0x80, 0x2d, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xd8, 0x02, 0x40, 0x00, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x79, 0x0a, 0x91, 0x39,
- 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x39, 0x0b, 0x91, 0x39,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x59, 0x0a, 0x91, 0x39,
- 0x09, 0x00, 0xe5, 0x10, 0xf1, 0x01, 0x00, 0x10, 0x69, 0x0b, 0x91, 0xb9,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x24, 0x86, 0xa8, 0x82, 0x8d, 0x6c, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe0, 0x07, 0x00, 0x91, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0xe0, 0x07, 0x40, 0x91, 0x32,
- 0x00, 0x80, 0xeb, 0x10, 0x02, 0x01, 0x00, 0x80, 0x82, 0x8d, 0x2a, 0xbc,
- 0x00, 0x00, 0xec, 0x10, 0xe1, 0x24, 0x86, 0xc8, 0x06, 0x00, 0x00, 0x92,
- 0x03, 0x00, 0x00, 0x00, 0xe1, 0x24, 0x86, 0xc8, 0x86, 0x8d, 0x2a, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xf4, 0x10, 0x04, 0x30, 0x00, 0x80, 0x82, 0x9b, 0x81, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0x3c, 0x00, 0x14, 0x28, 0x80, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x02, 0x80, 0x2f, 0x35,
- 0x00, 0xa0, 0x8a, 0x11, 0x12, 0x00, 0x00, 0x40, 0xa2, 0x8d, 0x39, 0xb2,
- 0x00, 0x00, 0xf6, 0x10, 0x80, 0x39, 0x00, 0x80, 0xe2, 0x80, 0x6e, 0xb6,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x38, 0x00, 0x80, 0xf2, 0x80, 0x6e, 0xb6,
- 0x00, 0xe0, 0x8a, 0x11, 0x04, 0x01, 0x00, 0x80, 0xa2, 0x8d, 0x2f, 0xb0,
- 0x00, 0xe0, 0xfd, 0x10, 0x04, 0x38, 0x00, 0x78, 0x89, 0x8d, 0x6e, 0xb0,
- 0x10, 0x00, 0xfd, 0x10, 0x9f, 0x01, 0x00, 0xf8, 0xe2, 0xa5, 0x2f, 0xb9,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0xee, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0x82, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x01, 0xec, 0x06, 0xc0, 0xee, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x28, 0x00, 0x18, 0x09, 0x00, 0x6e, 0x72,
- 0x00, 0x00, 0x4f, 0x0e, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xf0,
- 0x00, 0x00, 0x2f, 0x0e, 0x00, 0xa8, 0x01, 0x20, 0x09, 0x00, 0x6e, 0x92,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xa9, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0xb0, 0x00, 0x80, 0x82, 0x9b, 0x81, 0x7c,
- 0x00, 0x00, 0x8a, 0x11, 0x0d, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x9f, 0xbc, 0x00, 0x14, 0x28, 0x80, 0x6e, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xca, 0x01, 0x00, 0xf8, 0x42, 0x80, 0x2f, 0x35,
- 0x08, 0xa0, 0x00, 0x00, 0x12, 0x01, 0x00, 0x40, 0xa2, 0xcd, 0x39, 0x72,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x80, 0x90, 0xd2,
- 0x00, 0x00, 0x0f, 0x11, 0x33, 0xcd, 0x01, 0xbc, 0x08, 0x80, 0x6e, 0xb2,
- 0x00, 0x00, 0x4e, 0x11, 0x00, 0x00, 0x00, 0x28, 0x29, 0x22, 0xee, 0xdc,
- 0x00, 0x00, 0x14, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x14, 0x11, 0x04, 0xb8, 0x01, 0x28, 0x09, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x14, 0x11, 0x9f, 0x71, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0xa9, 0x24, 0xee, 0x3c,
- 0x00, 0x00, 0x4e, 0x11, 0x00, 0x00, 0x00, 0x28, 0x19, 0x80, 0x92, 0xdf,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x00, 0x00, 0x28, 0x11, 0x06, 0x80, 0x01, 0x80, 0x82, 0x9b, 0x90, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x90, 0xbc,
- 0xee, 0x05, 0x20, 0x11, 0x06, 0x0c, 0x02, 0x80, 0x82, 0x8d, 0x6e, 0xbc,
- 0x00, 0x90, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x1a, 0x11, 0xb8, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x18, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x03, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x78, 0x49, 0x40, 0x3c, 0x37,
- 0x00, 0x00, 0x2d, 0x11, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x9a,
- 0x60, 0x89, 0x20, 0x00, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x23, 0x11, 0xb8, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0xb0,
- 0x00, 0x00, 0x21, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x03, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x2d, 0x11, 0xa8, 0x00, 0x00, 0x08, 0x19, 0x8f, 0x90, 0x9a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x99, 0xa1, 0x89, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xe9, 0xa5, 0x90, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xe0, 0x96, 0x21, 0x6e, 0x3c,
- 0x00, 0x00, 0x00, 0x00, 0x61, 0x98, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x01, 0xec, 0x06, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x30, 0x11, 0x06, 0x00, 0x00, 0x80, 0x72, 0xa2, 0x90, 0xbc,
- 0x00, 0xc0, 0xff, 0x3f, 0x00, 0x80, 0x01, 0xe0, 0x06, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0xc0, 0x89, 0x32,
- 0x00, 0x00, 0x36, 0x11, 0x04, 0x79, 0x01, 0x80, 0x82, 0x1b, 0x87, 0xbc,
- 0x00, 0x00, 0x34, 0x11, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x92, 0x81, 0x2f, 0x75,
- 0x00, 0x00, 0x3c, 0x11, 0x80, 0x00, 0x00, 0x80, 0x52, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x3c, 0x11, 0xd5, 0x41, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x92,
- 0x00, 0x00, 0x39, 0x11, 0x3c, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0xb2,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x01, 0x00, 0x80, 0x92, 0x81, 0x2f, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x01, 0xe8, 0x06, 0xc0, 0x8b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x95, 0x01, 0x00, 0x80, 0x02, 0x80, 0x2f, 0x72,
- 0x00, 0x00, 0x3d, 0x11, 0x9f, 0x41, 0x01, 0x80, 0x82, 0x1b, 0x87, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0x00, 0x00, 0xd9, 0x90, 0x01, 0xe0, 0x06, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x72, 0x80, 0x2f, 0x74,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x27, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0x40, 0x87, 0xd2,
- 0x00, 0x00, 0x47, 0x11, 0x9f, 0xd8, 0x01, 0x80, 0x22, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0x47, 0x11, 0x9f, 0xe0, 0x01, 0x80, 0xc2, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x0b, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0x47, 0x11, 0x9f, 0xb0, 0x01, 0x80, 0xd2, 0x21, 0x6e, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x70,
- 0x00, 0x00, 0x49, 0x11, 0x06, 0x68, 0x01, 0x80, 0x82, 0x5b, 0x87, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x01, 0xe0, 0x06, 0x40, 0x87, 0x32,
- 0x00, 0x00, 0x4b, 0x11, 0x37, 0xb0, 0x01, 0xe0, 0x06, 0x40, 0x87, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd2, 0x80, 0x2f, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x01, 0xe0, 0x06, 0x80, 0x84, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, 0x01, 0xe0, 0x06, 0x00, 0x87, 0x72,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x08, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xbc,
- 0x00, 0x00, 0x5b, 0x11, 0x04, 0xc1, 0x01, 0x84, 0x02, 0x00, 0x6e, 0xb2,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe8, 0x86, 0x8d, 0x92, 0x37,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x01, 0xe8, 0x86, 0x8d, 0x92, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x30,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x2c, 0x89, 0x8d, 0x6e, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x01, 0x2c, 0xa9, 0xdb, 0x92, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x29, 0xc0, 0x92, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x19, 0xfb, 0x92, 0x3f,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x29, 0x80, 0x92, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0xa9, 0xe4, 0x92, 0x3f,
- 0x00, 0x00, 0x00, 0x00, 0x6f, 0xcc, 0x01, 0xe8, 0x26, 0xfb, 0x92, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x02, 0x80, 0x92, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x01, 0xe0, 0x06, 0x40, 0x28, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x6f, 0xcc, 0x01, 0xe8, 0x86, 0xcd, 0x2a, 0x36,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x01, 0xe0, 0x06, 0x00, 0x00, 0x52,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0xb0, 0x00, 0x80, 0x02, 0x00, 0x6e, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x01, 0xbc, 0x08, 0x00, 0x6e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x01, 0xbc, 0x88, 0xdb, 0x8b, 0x3e,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0xbc, 0x88, 0xdb, 0x8b, 0x3a,
- 0x00, 0x00, 0x6a, 0x11, 0x9f, 0x00, 0x00, 0xbc, 0x88, 0xe1, 0x8b, 0xbc,
- 0x00, 0x00, 0x6a, 0x11, 0x04, 0x0c, 0x02, 0x40, 0xa8, 0xdb, 0x8b, 0xbe,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x04, 0x88, 0x1b, 0x84, 0x3e,
- 0x00, 0x00, 0x69, 0x11, 0x04, 0xb1, 0x00, 0x80, 0x82, 0x5b, 0x80, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0xc2, 0x80, 0x2f, 0x74,
- 0x00, 0x00, 0x00, 0x00, 0x04, 0x0c, 0x02, 0x80, 0xa2, 0x5b, 0x80, 0x7c,
- 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x14, 0x09, 0xc0, 0x8b, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x12, 0x00, 0x2c, 0x3a,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x04, 0x65, 0x01, 0x80, 0xa2, 0xdb, 0x2c, 0xbc,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x00, 0x00, 0x80, 0xa2, 0x80, 0x2f, 0xb6,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x01, 0xe8, 0x76, 0x20, 0x81, 0x39,
- 0xee, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0xf8, 0x82, 0x8d, 0x2f, 0x71,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xd9, 0x4a, 0x91, 0x39,
- 0x39, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x45, 0x91, 0x30,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0x4d, 0x91, 0x36,
- 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0xcd, 0x93, 0x3c,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0xcd, 0x93, 0x36,
- 0x07, 0x00, 0x79, 0x11, 0xf3, 0x01, 0x00, 0x40, 0x89, 0xcd, 0x93, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x18, 0x9b, 0x81, 0x02, 0xe5, 0x78, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0x9b, 0x8d, 0x07, 0xe5, 0x78, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0xd9, 0x4a, 0x91, 0x39,
- 0x3a, 0x00, 0xe2, 0x10, 0x00, 0x00, 0x00, 0x10, 0x09, 0x00, 0x36, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x09, 0x45, 0x91, 0x30,
- 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0x4d, 0x91, 0x36,
- 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x89, 0xcd, 0x93, 0x3c,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x82, 0xcd, 0x93, 0x36,
- 0x07, 0x00, 0x84, 0x11, 0xf3, 0x01, 0x00, 0x40, 0x89, 0xcd, 0x93, 0xb0,
- 0x00, 0x00, 0x8a, 0x11, 0x80, 0x19, 0x9b, 0x81, 0x02, 0xe5, 0x78, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0xe3, 0x18, 0x9b, 0x8d, 0x07, 0xe5, 0x78, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x8a, 0x11, 0x00, 0x00, 0x00, 0xb4, 0x0f, 0x40, 0xfb, 0x94,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x0f, 0x40, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x28, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x29, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x0f, 0x40, 0x18, 0x32,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x5f, 0xca, 0xf9, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0xc0, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
- 0x41, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x32,
- 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0f, 0x80, 0x2a, 0x32,
- 0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x98, 0x11, 0x97, 0x12, 0x00, 0x00, 0x00, 0xb0, 0x0f, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x01, 0x84, 0x12, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x36, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x80, 0x2a, 0x32,
- 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0f, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0xc0, 0xfa, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfa, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0xfa, 0x32,
- 0x00, 0x00, 0xac, 0x11, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xfa, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xfb, 0x32,
- 0x01, 0x00, 0xcf, 0x11, 0x04, 0x01, 0x00, 0xb4, 0x8f, 0x4d, 0xfb, 0xb0,
- 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xab, 0xcd, 0xb0, 0x32,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5b, 0xca, 0xb0, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x2b, 0xfe, 0xb0, 0x32,
- 0x00, 0x00, 0xaa, 0x11, 0x12, 0x01, 0x00, 0x80, 0x02, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0xbe, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x01, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe0, 0x07, 0x80, 0x3f, 0x52,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x8a, 0x02, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x16, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x80, 0x90, 0x32,
- 0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
- 0xb9, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0x0d, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0x0d, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
- 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xc0, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x09, 0x00, 0xfa, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x09, 0x40, 0xfa, 0x32,
- 0x00, 0x00, 0xc9, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
- 0x00, 0x00, 0xc0, 0x11, 0x80, 0x01, 0x00, 0x80, 0x12, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
- 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x40, 0x90, 0x92,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
- 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x04, 0x6b, 0x41, 0x90, 0x94,
- 0x00, 0x00, 0xc4, 0x11, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0xc5, 0x11, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
- 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0xe4, 0x16, 0x38,
- 0x00, 0x00, 0xc9, 0x11, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0xc8, 0x11, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x02, 0x00, 0xc4, 0x11, 0x04, 0x01, 0x00, 0xbc, 0x0f, 0x24, 0x17, 0xb8,
- 0x06, 0x00, 0xc2, 0x11, 0x04, 0x00, 0x00, 0xbc, 0x0f, 0x64, 0x16, 0xb8,
- 0x00, 0x00, 0xbd, 0x11, 0x04, 0x00, 0x00, 0x80, 0x22, 0xc0, 0xfb, 0xbc,
- 0x20, 0x00, 0xc4, 0x11, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfb, 0xbc,
- 0x00, 0x00, 0xd7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0xd1, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x82, 0xcd, 0xf9, 0x3a,
- 0x00, 0x00, 0xb7, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xf8, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xfc, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x04, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x03, 0x32,
- 0x40, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x40, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xde, 0x11, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0xde, 0x11, 0x12, 0x00, 0x00, 0x40, 0xf2, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0x32,
- 0x00, 0x00, 0xe0, 0x11, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x7e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x07, 0x00, 0xfa, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
- 0x00, 0x00, 0xad, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0xb3, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcb, 0xc1, 0xb0, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xef, 0x0f, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0xb0, 0xd2,
- 0x00, 0x00, 0xeb, 0x11, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xb2,
- 0x00, 0x00, 0xef, 0x11, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
- 0x02, 0x00, 0xf2, 0x11, 0x04, 0x01, 0x00, 0xb4, 0x8f, 0x4d, 0xfb, 0xb0,
- 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x93, 0x40, 0x01, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x1f, 0x40, 0xfb, 0x35,
- 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x03, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x00, 0x34,
- 0x00, 0x00, 0xeb, 0x11, 0x00, 0x00, 0x00, 0x0c, 0x8b, 0xc1, 0xb0, 0x94,
- 0x00, 0x00, 0xbb, 0x12, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0xfa, 0x92,
- 0x00, 0x00, 0xad, 0x12, 0x00, 0x08, 0x00, 0x00, 0x07, 0x40, 0xfa, 0xd2,
- 0x00, 0x00, 0xf9, 0x11, 0x12, 0x00, 0x00, 0x50, 0xf2, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0xb4, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0xbd, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xb0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x12, 0x00, 0x2a, 0x3a,
- 0x00, 0x00, 0xff, 0x11, 0x04, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xba, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x0c, 0x12, 0x04, 0x01, 0x00, 0x80, 0x02, 0x40, 0xfa, 0xb2,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x0e, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x1b, 0x12, 0x00, 0x00, 0x00, 0x84, 0x02, 0x00, 0x00, 0xd2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x3c, 0x32,
- 0x00, 0x00, 0x08, 0x12, 0x8e, 0x01, 0x00, 0x80, 0x02, 0x40, 0x28, 0xb2,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x8f, 0x4d, 0xfa, 0x3a,
- 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
- 0x10, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x08, 0x00, 0x10, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
- 0x0e, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x0b, 0x00, 0x14, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
- 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
- 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x27, 0x00, 0x18, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
- 0x0f, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x20, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x20, 0x00, 0x1d, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe4, 0x03, 0xc0, 0xf9, 0x32,
- 0x0d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0xfa, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x5a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0xc0, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x3a,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xac, 0x8f, 0xcd, 0xf9, 0x50,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x12, 0x00, 0x2b, 0x3a,
- 0x0f, 0x00, 0x2b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0x0d, 0x2b, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3e, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x02, 0xc0, 0xf9, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x3a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x3a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x3a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x3d, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x3d, 0x32,
- 0x00, 0x00, 0x36, 0x12, 0x84, 0x01, 0x00, 0xb0, 0x12, 0x00, 0x2b, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xb0, 0x02, 0xc0, 0xf9, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
- 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x73, 0x3e, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x3a,
- 0x70, 0x00, 0x3b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xf9, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0xc0, 0x29, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0xc0, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0xc0, 0x2c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0xfa, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x73, 0x7e, 0xfa, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x30, 0x32,
- 0x00, 0x00, 0x44, 0x12, 0x85, 0x01, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x0e, 0x00, 0x53, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x4d, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x3f, 0xc0, 0xf9, 0x9a,
- 0x1c, 0x00, 0x4d, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
- 0x02, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x8f, 0xcd, 0xf9, 0xda,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x37, 0x32,
- 0x00, 0x00, 0x25, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x0e, 0x00, 0x5b, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x57, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0x9a,
- 0x26, 0x00, 0x57, 0x12, 0x04, 0x01, 0x00, 0x80, 0x82, 0xcd, 0xfa, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x0f, 0x40, 0x29, 0x32,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x4c, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x56, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x29, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x18, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0x00, 0x00, 0x32,
- 0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
- 0x6b, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x80, 0x2a, 0x32,
- 0x00, 0x00, 0x6b, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x29, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x83, 0x3e, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x83, 0x3e, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
- 0x00, 0x00, 0x6c, 0x12, 0x00, 0x00, 0x00, 0x88, 0x0f, 0x40, 0x2b, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x0f, 0x00, 0x28, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x0f, 0x00, 0x29, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x0f, 0x80, 0x2a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0xc0, 0xf9, 0x32,
- 0x71, 0x12, 0x97, 0x12, 0x00, 0x00, 0x00, 0xb0, 0x0f, 0x00, 0x36, 0x92,
- 0x07, 0x00, 0x74, 0x12, 0x04, 0x00, 0x00, 0x80, 0x82, 0x4d, 0x29, 0xbc,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x1f, 0x00, 0xfa, 0x3a,
- 0x00, 0x00, 0x68, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x80, 0x2a, 0x92,
- 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x0f, 0x00, 0x36, 0x32,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x84, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x1f, 0x00, 0x7a, 0x12, 0x04, 0x00, 0x00, 0x80, 0x82, 0xcd, 0x29, 0xbc,
- 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x8f, 0xcd, 0xfa, 0x3a,
- 0x00, 0x00, 0x76, 0x12, 0x00, 0x00, 0x00, 0x9c, 0x12, 0xc0, 0x29, 0x9a,
- 0x00, 0x00, 0x3a, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x30, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x82, 0x12, 0x04, 0x00, 0x00, 0x80, 0x52, 0x8a, 0xfa, 0xbc,
- 0xa2, 0x60, 0x03, 0x00, 0x00, 0x00, 0x00, 0x58, 0x03, 0x00, 0x37, 0x32,
- 0x82, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x03, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0xa3, 0x3e, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xa3, 0x3e, 0x00, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x53, 0x0a, 0x00, 0x34,
- 0x00, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0xf7, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x02, 0xc0, 0xfa, 0x32,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0x40, 0x2f, 0x32,
- 0x00, 0x00, 0x8b, 0x12, 0x04, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
- 0x00, 0x00, 0x8a, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x40, 0x2f, 0xb2,
- 0x00, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2c, 0x92,
- 0x00, 0x00, 0x87, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2c, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2d, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2d, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2d, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2d, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xfb, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2f, 0x32,
- 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x73, 0x0a, 0x02, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xe0, 0x07, 0x80, 0x3f, 0x52,
- 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x03, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x28, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xf8, 0x32,
- 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x0f, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0xc0, 0x2b, 0x32,
- 0x00, 0x00, 0xa0, 0x12, 0x04, 0x00, 0x00, 0x9c, 0x1f, 0xc0, 0xf9, 0xbc,
- 0x00, 0x00, 0x9f, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0xc0, 0x2b, 0xb2,
- 0x00, 0x00, 0x9c, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x28, 0x92,
- 0x00, 0x00, 0x9c, 0x12, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x36, 0x92,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x29, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x29, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x29, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0xf9, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0x2a, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x40, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x80, 0x2b, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xc0, 0xfb, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x02, 0x00, 0xfb, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xb1, 0x12, 0x9f, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x40, 0x90, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x80, 0x90, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x07, 0x40, 0x90, 0x52,
- 0x00, 0x00, 0xb3, 0x12, 0x12, 0x00, 0x00, 0x48, 0xf2, 0x01, 0x00, 0xb4,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x90, 0x32,
- 0x00, 0x00, 0xb5, 0x12, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, 0x02, 0x00, 0x00, 0x50,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x0f, 0x40, 0xfb, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x4c, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x02, 0x00, 0x36, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x07, 0x80, 0x2a, 0x32,
- 0x00, 0x00, 0xad, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0xb3, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0xd0,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xcb, 0xc1, 0xb0, 0x34,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x02, 0x00, 0x00, 0x32,
- 0x00, 0x00, 0xc4, 0x12, 0x00, 0x00, 0x00, 0x28, 0x09, 0xc0, 0xb0, 0xd2,
- 0x00, 0x00, 0xbe, 0x12, 0x04, 0x00, 0x00, 0x80, 0x02, 0x80, 0x92, 0xb2,
- 0x00, 0x00, 0xc2, 0x12, 0x12, 0x00, 0x00, 0x9c, 0x0f, 0xc0, 0x21, 0xb2,
- 0x00, 0x00, 0xc4, 0x11, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0x02, 0x00, 0x00, 0x32,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
- 0x00, 0x00, 0xc8, 0x12, 0x04, 0x01, 0x00, 0x28, 0x09, 0x34, 0xb0, 0xba,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x28, 0x09, 0x00, 0x00, 0x52,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x22, 0x00, 0x2b, 0x37,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xc0, 0x37, 0xac, 0xb0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0b, 0x00, 0x00, 0x32,
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xa9, 0x4d, 0xb0, 0x30,
- 0x00, 0x00, 0xd8, 0x12, 0x80, 0x00, 0x00, 0x80, 0x02, 0x40, 0xb0, 0xb6,
- 0x00, 0x00, 0xcd, 0x12, 0x12, 0x00, 0x00, 0x00, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0xce, 0x12, 0x12, 0x00, 0x00, 0x04, 0x09, 0x40, 0x20, 0xb2,
- 0x00, 0x00, 0xd1, 0x12, 0x9f, 0x01, 0x00, 0x80, 0x02, 0x00, 0x90, 0xb2,
- 0x00, 0x00, 0xd0, 0x12, 0x12, 0x00, 0x00, 0x08, 0x09, 0x40, 0x20, 0xb2,
- 0x0d, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0x80, 0x02, 0xe4, 0x16, 0xb8,
- 0x02, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0xbc, 0x0f, 0x24, 0x17, 0xb8,
- 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0f, 0x64, 0x16, 0x38,
- 0x00, 0x00, 0xcd, 0x12, 0x04, 0x01, 0x00, 0x80, 0x22, 0xc0, 0xfb, 0xbc,
- 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0xc2, 0x0a, 0x00, 0x39,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x3b, 0x40, 0xb0, 0x33,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xcd, 0x4a, 0xd0, 0x35,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe7, 0x25, 0x01, 0x32,
- 0x00, 0x42, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x87, 0x8d, 0x2a, 0x3a,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x07, 0x00, 0xb0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, 0xd0, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x12, 0x01, 0x00, 0x48, 0xf2, 0xc1, 0x38, 0x54,
- 0x00, 0x00, 0xdc, 0x12, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
- 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-},
-{
- 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0x00, 0x00, 0x90,
-},
-};
diff --git a/drivers/staging/sxg/sxg.c b/drivers/staging/sxg/sxg.c
index 1e0cfcd7f0f..0050a022010 100644
--- a/drivers/staging/sxg/sxg.c
+++ b/drivers/staging/sxg/sxg.c
@@ -30,6 +30,8 @@
* are those of the authors and should not be interpreted as representing
* official policies, either expressed or implied, of Alacritech, Inc.
*
+ * Parts developed by LinSysSoft Sahara team
+ *
**************************************************************************/
/*
@@ -46,6 +48,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/firmware.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
@@ -61,101 +64,122 @@
#include <linux/types.h>
#include <linux/dma-mapping.h>
#include <linux/mii.h>
+#include <linux/ip.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <linux/ipv6.h>
-#define SLIC_DUMP_ENABLED 0
#define SLIC_GET_STATS_ENABLED 0
#define LINUX_FREES_ADAPTER_RESOURCES 1
#define SXG_OFFLOAD_IP_CHECKSUM 0
#define SXG_POWER_MANAGEMENT_ENABLED 0
#define VPCI 0
-#define DBG 1
#define ATK_DEBUG 1
+#define SXG_UCODE_DEBUG 0
+
#include "sxg_os.h"
#include "sxghw.h"
#include "sxghif.h"
#include "sxg.h"
#include "sxgdbg.h"
-
-#include "sxgphycode.h"
-#include "saharadbgdownload.h"
+#include "sxgphycode-1.2.h"
static int sxg_allocate_buffer_memory(struct adapter_t *adapter, u32 Size,
- enum SXG_BUFFER_TYPE BufferType);
-static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter, void *RcvBlock,
- dma_addr_t PhysicalAddress,
- u32 Length);
+ enum sxg_buffer_type BufferType);
+static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
+ void *RcvBlock,
+ dma_addr_t PhysicalAddress,
+ u32 Length);
static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
- struct SXG_SCATTER_GATHER *SxgSgl,
+ struct sxg_scatter_gather *SxgSgl,
dma_addr_t PhysicalAddress,
u32 Length);
static void sxg_mcast_init_crc32(void);
-
-static int sxg_entry_open(p_net_device dev);
-static int sxg_entry_halt(p_net_device dev);
-static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd);
-static int sxg_send_packets(struct sk_buff *skb, p_net_device dev);
+static int sxg_entry_open(struct net_device *dev);
+static int sxg_second_open(struct net_device * dev);
+static int sxg_entry_halt(struct net_device *dev);
+static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev);
static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb);
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl);
+static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
+ struct sxg_scatter_gather *SxgSgl);
-static void sxg_handle_interrupt(struct adapter_t *adapter);
+static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done,
+ int budget);
+static void sxg_interrupt(struct adapter_t *adapter);
+static int sxg_poll(struct napi_struct *napi, int budget);
static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId);
-static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId);
+static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId,
+ int *sxg_napi_continue, int *work_done, int budget);
static void sxg_complete_slow_send(struct adapter_t *adapter);
-static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EVENT *Event);
+static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
+ struct sxg_event *Event);
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus);
static bool sxg_mac_filter(struct adapter_t *adapter,
struct ether_header *EtherHdr, ushort length);
-
-#if SLIC_GET_STATS_ENABLED
-static struct net_device_stats *sxg_get_stats(p_net_device dev);
-#endif
+static struct net_device_stats *sxg_get_stats(struct net_device * dev);
+void sxg_free_resources(struct adapter_t *adapter);
+void sxg_free_rcvblocks(struct adapter_t *adapter);
+void sxg_free_sgl_buffers(struct adapter_t *adapter);
+void sxg_unmap_resources(struct adapter_t *adapter);
+void sxg_free_mcast_addrs(struct adapter_t *adapter);
+void sxg_collect_statistics(struct adapter_t *adapter);
+static int sxg_register_interrupt(struct adapter_t *adapter);
+static void sxg_remove_isr(struct adapter_t *adapter);
+static irqreturn_t sxg_isr(int irq, void *dev_id);
+
+static void sxg_watchdog(unsigned long data);
+static void sxg_update_link_status (struct work_struct *work);
#define XXXTODO 0
#if XXXTODO
-static int sxg_mac_set_address(p_net_device dev, void *ptr);
-static void sxg_mcast_set_list(p_net_device dev);
+static int sxg_mac_set_address(struct net_device *dev, void *ptr);
#endif
+static void sxg_mcast_set_list(struct net_device *dev);
-static void sxg_adapter_set_hwaddr(struct adapter_t *adapter);
-
-static void sxg_unmap_mmio_space(struct adapter_t *adapter);
+static int sxg_adapter_set_hwaddr(struct adapter_t *adapter);
static int sxg_initialize_adapter(struct adapter_t *adapter);
static void sxg_stock_rcv_buffers(struct adapter_t *adapter);
static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
unsigned char Index);
+int sxg_change_mtu (struct net_device *netdev, int new_mtu);
static int sxg_initialize_link(struct adapter_t *adapter);
static int sxg_phy_init(struct adapter_t *adapter);
static void sxg_link_event(struct adapter_t *adapter);
static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter);
-static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkState);
+static void sxg_link_state(struct adapter_t *adapter,
+ enum SXG_LINK_STATE LinkState);
static int sxg_write_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 Value);
static int sxg_read_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 *pValue);
+static void sxg_set_mcast_addr(struct adapter_t *adapter);
static unsigned int sxg_first_init = 1;
static char *sxg_banner =
- "Alacritech SLIC Technology(tm) Server and Storage 10Gbe Accelerator (Non-Accelerated)\n";
+ "Alacritech SLIC Technology(tm) Server and Storage \
+ 10Gbe Accelerator (Non-Accelerated)\n";
static int sxg_debug = 1;
static int debug = -1;
-static p_net_device head_netdevice = NULL;
+static struct net_device *head_netdevice = NULL;
-static struct sxgbase_driver_t sxg_global = {
+static struct sxgbase_driver sxg_global = {
.dynamic_intagg = 1,
};
static int intagg_delay = 100;
static u32 dynamic_intagg = 0;
-#define DRV_NAME "sxg"
-#define DRV_VERSION "1.0.1"
+char sxg_driver_name[] = "sxg_nic";
#define DRV_AUTHOR "Alacritech, Inc. Engineering"
-#define DRV_DESCRIPTION "Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver"
-#define DRV_COPYRIGHT "Copyright 2000-2008 Alacritech, Inc. All rights reserved."
+#define DRV_DESCRIPTION \
+ "Alacritech SLIC Techonology(tm) Non-Accelerated 10Gbe Driver"
+#define DRV_COPYRIGHT \
+ "Copyright 2000-2008 Alacritech, Inc. All rights reserved."
MODULE_AUTHOR(DRV_AUTHOR);
MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -173,12 +197,6 @@ static struct pci_device_id sxg_pci_tbl[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, sxg_pci_tbl);
-/***********************************************************************
-************************************************************************
-************************************************************************
-************************************************************************
-************************************************************************/
-
static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush)
{
writel(value, reg);
@@ -225,17 +243,143 @@ static void sxg_dbg_macaddrs(struct adapter_t *adapter)
}
/* SXG Globals */
-static struct SXG_DRIVER SxgDriver;
+static struct sxg_driver SxgDriver;
#ifdef ATKDBG
-static struct sxg_trace_buffer_t LSxgTraceBuffer;
+static struct sxg_trace_buffer LSxgTraceBuffer;
#endif /* ATKDBG */
-static struct sxg_trace_buffer_t *SxgTraceBuffer = NULL;
+static struct sxg_trace_buffer *SxgTraceBuffer = NULL;
+
+/*
+ * MSI Related API's
+ */
+int sxg_register_intr(struct adapter_t *adapter);
+int sxg_enable_msi_x(struct adapter_t *adapter);
+int sxg_add_msi_isr(struct adapter_t *adapter);
+void sxg_remove_msix_isr(struct adapter_t *adapter);
+int sxg_set_interrupt_capability(struct adapter_t *adapter);
+
+int sxg_set_interrupt_capability(struct adapter_t *adapter)
+{
+ int ret;
+
+ ret = sxg_enable_msi_x(adapter);
+ if (ret != STATUS_SUCCESS) {
+ adapter->msi_enabled = FALSE;
+ DBG_ERROR("sxg_set_interrupt_capability MSI-X Disable\n");
+ } else {
+ adapter->msi_enabled = TRUE;
+ DBG_ERROR("sxg_set_interrupt_capability MSI-X Enable\n");
+ }
+ return ret;
+}
+
+int sxg_register_intr(struct adapter_t *adapter)
+{
+ int ret = 0;
+
+ if (adapter->msi_enabled) {
+ ret = sxg_add_msi_isr(adapter);
+ }
+ else {
+ DBG_ERROR("MSI-X Enable Failed. Using Pin INT\n");
+ ret = sxg_register_interrupt(adapter);
+ if (ret != STATUS_SUCCESS) {
+ DBG_ERROR("sxg_register_interrupt Failed\n");
+ }
+ }
+ return ret;
+}
+
+int sxg_enable_msi_x(struct adapter_t *adapter)
+{
+ int ret;
+
+ adapter->nr_msix_entries = 1;
+ adapter->msi_entries = kmalloc(adapter->nr_msix_entries *
+ sizeof(struct msix_entry),GFP_KERNEL);
+ if (!adapter->msi_entries) {
+ DBG_ERROR("%s:MSI Entries memory allocation Failed\n",__func__);
+ return -ENOMEM;
+ }
+ memset(adapter->msi_entries, 0, adapter->nr_msix_entries *
+ sizeof(struct msix_entry));
+
+ ret = pci_enable_msix(adapter->pcidev, adapter->msi_entries,
+ adapter->nr_msix_entries);
+ if (ret) {
+ DBG_ERROR("Enabling MSI-X with %d vectors failed\n",
+ adapter->nr_msix_entries);
+ /*Should try with less vector returned.*/
+ kfree(adapter->msi_entries);
+ return STATUS_FAILURE; /*MSI-X Enable failed.*/
+ }
+ return (STATUS_SUCCESS);
+}
+
+int sxg_add_msi_isr(struct adapter_t *adapter)
+{
+ int ret,i;
+
+ if (!adapter->intrregistered) {
+ for (i=0; i<adapter->nr_msix_entries; i++) {
+ ret = request_irq (adapter->msi_entries[i].vector,
+ sxg_isr,
+ IRQF_SHARED,
+ adapter->netdev->name,
+ adapter->netdev);
+ if (ret) {
+ DBG_ERROR("sxg: MSI-X request_irq (%s) "
+ "FAILED [%x]\n", adapter->netdev->name,
+ ret);
+ return (ret);
+ }
+ }
+ }
+ adapter->msi_enabled = TRUE;
+ adapter->intrregistered = 1;
+ adapter->IntRegistered = TRUE;
+ return (STATUS_SUCCESS);
+}
+
+void sxg_remove_msix_isr(struct adapter_t *adapter)
+{
+ int i,vector;
+ struct net_device *netdev = adapter->netdev;
+
+ for(i=0; i< adapter->nr_msix_entries;i++)
+ {
+ vector = adapter->msi_entries[i].vector;
+ DBG_ERROR("%s : Freeing IRQ vector#%d\n",__FUNCTION__,vector);
+ free_irq(vector,netdev);
+ }
+}
+
+
+static void sxg_remove_isr(struct adapter_t *adapter)
+{
+ struct net_device *netdev = adapter->netdev;
+ if (adapter->msi_enabled)
+ sxg_remove_msix_isr(adapter);
+ else
+ free_irq(adapter->netdev->irq, netdev);
+}
+
+void sxg_reset_interrupt_capability(struct adapter_t *adapter)
+{
+ if (adapter->msi_enabled) {
+ pci_disable_msix(adapter->pcidev);
+ kfree(adapter->msi_entries);
+ adapter->msi_entries = NULL;
+ }
+ return;
+}
/*
* sxg_download_microcode
*
- * Download Microcode to Sahara adapter
+ * Download Microcode to Sahara adapter using the Linux
+ * Firmware module to get the ucode.sys file.
*
* Arguments -
* adapter - A pointer to our adapter structure
@@ -244,98 +388,141 @@ static struct sxg_trace_buffer_t *SxgTraceBuffer = NULL;
* Return
* int
*/
-static bool sxg_download_microcode(struct adapter_t *adapter, enum SXG_UCODE_SEL UcodeSel)
+static bool sxg_download_microcode(struct adapter_t *adapter,
+ enum SXG_UCODE_SEL UcodeSel)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+ const struct firmware *fw;
+ const char *file = "";
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ int ret;
+ int ucode_start;
u32 Section;
u32 ThisSectionSize;
- u32 *Instruction = NULL;
+ u32 instruction = 0;
u32 BaseAddress, AddressOffset, Address;
-/* u32 Failure; */
+ /* u32 Failure; */
u32 ValueRead;
u32 i;
- u32 numSections = 0;
+ u32 index = 0;
+ u32 num_sections = 0;
u32 sectionSize[16];
u32 sectionStart[16];
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DnldUcod",
adapter, 0, 0, 0);
- DBG_ERROR("sxg: %s ENTER\n", __func__);
-
- switch (UcodeSel) {
- case SXG_UCODE_SAHARA: /* Sahara operational ucode */
- numSections = SNumSections;
- for (i = 0; i < numSections; i++) {
- sectionSize[i] = SSectionSize[i];
- sectionStart[i] = SSectionStart[i];
- }
- break;
- default:
- printk(KERN_ERR KBUILD_MODNAME
- ": Woah, big error with the microcode!\n");
- break;
+
+ /*
+ * This routine is only implemented to download the microcode
+ * for the Revision B Sahara chip. Rev A and Diagnostic
+ * microcode is not supported at this time. If Rev A or
+ * diagnostic ucode is required, this routine will obviously
+ * need to change. Also, eventually need to add support for
+ * Rev B checked version of ucode. That's easy enough once
+ * the free version of Rev B works.
+ */
+ ASSERT(UcodeSel == SXG_UCODE_SYSTEM);
+ ASSERT(adapter->asictype == SAHARA_REV_B);
+#if SXG_UCODE_DEBUG
+ file = "sxg/saharadbgdownloadB.sys";
+#else
+ file = "sxg/saharadownloadB.sys";
+#endif
+ ret = request_firmware(&fw, file, &adapter->pcidev->dev);
+ if (ret) {
+ DBG_ERROR("%s SXG_NIC: Failed to load firmware %s\n", __func__,file);
+ return ret;
+ }
+
+ /*
+ * The microcode .sys file contains starts with a 4 byte word containing
+ * the number of sections. That is followed by "num_sections" 4 byte
+ * words containing each "section" size. That is followed num_sections
+ * 4 byte words containing each section "start" address.
+ *
+ * Following the above header, the .sys file contains num_sections,
+ * where each section size is specified, newline delineatetd 12 byte
+ * microcode instructions.
+ */
+ num_sections = *(u32 *)(fw->data + index);
+ index += 4;
+ ASSERT(num_sections <= 3);
+ for (i = 0; i < num_sections; i++) {
+ sectionSize[i] = *(u32 *)(fw->data + index);
+ index += 4;
+ }
+ for (i = 0; i < num_sections; i++) {
+ sectionStart[i] = *(u32 *)(fw->data + index);
+ index += 4;
}
- DBG_ERROR("sxg: RESET THE CARD\n");
/* First, reset the card */
WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+ udelay(50);
+ HwRegs = adapter->HwRegs;
- /* Download each section of the microcode as specified in */
- /* its download file. The *download.c file is generated using */
- /* the saharaobjtoc facility which converts the metastep .obj */
- /* file to a .c file which contains a two dimentional array. */
- for (Section = 0; Section < numSections; Section++) {
- DBG_ERROR("sxg: SECTION # %d\n", Section);
- switch (UcodeSel) {
- case SXG_UCODE_SAHARA:
- Instruction = (u32 *) & SaharaUCode[Section][0];
- break;
- default:
- ASSERT(0);
- break;
- }
+ /*
+ * Download each section of the microcode as specified in
+ * sectionSize[index] to sectionStart[index] address. As
+ * described above, the .sys file contains 12 byte word
+ * microcode instructions. The *download.sys file is generated
+ * using the objtosys.exe utility that was built for Sahara
+ * microcode.
+ */
+ /* See usage of this below when we read back for parity */
+ ucode_start = index;
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
+
+ for (Section = 0; Section < num_sections; Section++) {
BaseAddress = sectionStart[Section];
- ThisSectionSize = sectionSize[Section] / 12; /* Size in instructions */
+ /* Size in instructions */
+ ThisSectionSize = sectionSize[Section] / 12;
for (AddressOffset = 0; AddressOffset < ThisSectionSize;
AddressOffset++) {
+ u32 first_instr = 0; /* See comment below */
+
Address = BaseAddress + AddressOffset;
ASSERT((Address & ~MICROCODE_ADDRESS_MASK) == 0);
- /* Write instruction bits 31 - 0 */
- WRITE_REG(HwRegs->UcodeDataLow, *Instruction, FLUSH);
- /* Write instruction bits 63-32 */
- WRITE_REG(HwRegs->UcodeDataMiddle, *(Instruction + 1),
- FLUSH);
- /* Write instruction bits 95-64 */
- WRITE_REG(HwRegs->UcodeDataHigh, *(Instruction + 2),
- FLUSH);
+ /* Write instruction bits 31 - 0 (low) */
+ first_instr = instruction;
+ WRITE_REG(HwRegs->UcodeDataLow, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4; /* Advance to the "next" instruction */
+
+ /* Write instruction bits 63-32 (middle) */
+ WRITE_REG(HwRegs->UcodeDataMiddle, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4; /* Advance to the "next" instruction */
+
+ /* Write instruction bits 95-64 (high) */
+ WRITE_REG(HwRegs->UcodeDataHigh, instruction, FLUSH);
+ instruction = *(u32 *)(fw->data + index);
+ index += 4; /* Advance to the "next" instruction */
+
/* Write instruction address with the WRITE bit set */
WRITE_REG(HwRegs->UcodeAddr,
(Address | MICROCODE_ADDRESS_WRITE), FLUSH);
- /* Sahara bug in the ucode download logic - the write to DataLow */
- /* for the next instruction could get corrupted. To avoid this, */
- /* write to DataLow again for this instruction (which may get */
- /* corrupted, but it doesn't matter), then increment the address */
- /* and write the data for the next instruction to DataLow. That */
- /* write should succeed. */
- WRITE_REG(HwRegs->UcodeDataLow, *Instruction, TRUE);
- /* Advance 3 u32S to start of next instruction */
- Instruction += 3;
+ /*
+ * Sahara bug in the ucode download logic - the write to DataLow
+ * for the next instruction could get corrupted. To avoid this,
+ * write to DataLow again for this instruction (which may get
+ * corrupted, but it doesn't matter), then increment the address
+ * and write the data for the next instruction to DataLow. That
+ * write should succeed.
+ */
+ WRITE_REG(HwRegs->UcodeDataLow, first_instr, FLUSH);
}
}
- /* Now repeat the entire operation reading the instruction back and */
- /* checking for parity errors */
- for (Section = 0; Section < numSections; Section++) {
- DBG_ERROR("sxg: check SECTION # %d\n", Section);
- switch (UcodeSel) {
- case SXG_UCODE_SAHARA:
- Instruction = (u32 *) & SaharaUCode[Section][0];
- break;
- default:
- ASSERT(0);
- break;
- }
+ /*
+ * Now repeat the entire operation reading the instruction back and
+ * checking for parity errors
+ */
+ index = ucode_start;
+
+ for (Section = 0; Section < num_sections; Section++) {
BaseAddress = sectionStart[Section];
- ThisSectionSize = sectionSize[Section] / 12; /* Size in instructions */
+ /* Size in instructions */
+ ThisSectionSize = sectionSize[Section] / 12;
for (AddressOffset = 0; AddressOffset < ThisSectionSize;
AddressOffset++) {
Address = BaseAddress + AddressOffset;
@@ -348,62 +535,70 @@ static bool sxg_download_microcode(struct adapter_t *adapter, enum SXG_UCODE_SEL
DBG_ERROR("sxg: %s PARITY ERROR\n",
__func__);
- return (FALSE); /* Parity error */
+ return FALSE; /* Parity error */
}
ASSERT((ValueRead & MICROCODE_ADDRESS_MASK) == Address);
/* Read the instruction back and compare */
+ /* First instruction */
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
READ_REG(HwRegs->UcodeDataLow, ValueRead);
- if (ValueRead != *Instruction) {
+ if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE LOW\n",
__func__);
- return (FALSE); /* Miscompare */
+ return FALSE; /* Miscompare */
}
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
READ_REG(HwRegs->UcodeDataMiddle, ValueRead);
- if (ValueRead != *(Instruction + 1)) {
+ if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE MIDDLE\n",
__func__);
- return (FALSE); /* Miscompare */
+ return FALSE; /* Miscompare */
}
+ instruction = *(u32 *)(fw->data + index);
+ index += 4;
READ_REG(HwRegs->UcodeDataHigh, ValueRead);
- if (ValueRead != *(Instruction + 2)) {
+ if (ValueRead != instruction) {
DBG_ERROR("sxg: %s MISCOMPARE HIGH\n",
__func__);
- return (FALSE); /* Miscompare */
+ return FALSE; /* Miscompare */
}
- /* Advance 3 u32S to start of next instruction */
- Instruction += 3;
}
}
+ /* download finished */
+ release_firmware(fw);
/* Everything OK, Go. */
WRITE_REG(HwRegs->UcodeAddr, MICROCODE_ADDRESS_GO, FLUSH);
- /* Poll the CardUp register to wait for microcode to initialize */
- /* Give up after 10,000 attemps (500ms). */
+ /*
+ * Poll the CardUp register to wait for microcode to initialize
+ * Give up after 10,000 attemps (500ms).
+ */
for (i = 0; i < 10000; i++) {
udelay(50);
READ_REG(adapter->UcodeRegs[0].CardUp, ValueRead);
if (ValueRead == 0xCAFE) {
- DBG_ERROR("sxg: %s BOO YA 0xCAFE\n", __func__);
break;
}
}
if (i == 10000) {
- DBG_ERROR("sxg: %s TIMEOUT\n", __func__);
+ DBG_ERROR("sxg: %s TIMEOUT bringing up card - verify MICROCODE\n", __func__);
- return (FALSE); /* Timeout */
+ return FALSE; /* Timeout */
}
- /* Now write the LoadSync register. This is used to */
- /* synchronize with the card so it can scribble on the memory */
- /* that contained 0xCAFE from the "CardUp" step above */
- if (UcodeSel == SXG_UCODE_SAHARA) {
+ /*
+ * Now write the LoadSync register. This is used to
+ * synchronize with the card so it can scribble on the memory
+ * that contained 0xCAFE from the "CardUp" step above
+ */
+ if (UcodeSel == SXG_UCODE_SYSTEM) {
WRITE_REG(adapter->UcodeRegs[0].LoadSync, 0, FLUSH);
}
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDnldUcd",
adapter, 0, 0, 0);
- DBG_ERROR("sxg: %s EXIT\n", __func__);
-
return (TRUE);
}
@@ -411,18 +606,16 @@ static bool sxg_download_microcode(struct adapter_t *adapter, enum SXG_UCODE_SEL
* sxg_allocate_resources - Allocate memory and locks
*
* Arguments -
- * adapter - A pointer to our adapter structure
+ * adapter - A pointer to our adapter structure
*
- * Return
- * int
+ * Return - int
*/
static int sxg_allocate_resources(struct adapter_t *adapter)
{
- int status;
- u32 i;
+ int status = STATUS_SUCCESS;
u32 RssIds, IsrCount;
-/* struct SXG_XMT_RING *XmtRing; */
-/* struct SXG_RCV_RING *RcvRing; */
+ /* struct sxg_xmt_ring *XmtRing; */
+ /* struct sxg_rcv_ring *RcvRing; */
DBG_ERROR("%s ENTER\n", __func__);
@@ -432,7 +625,7 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
/* Windows tells us how many CPUs it plans to use for */
/* RSS */
RssIds = SXG_RSS_CPU_COUNT(adapter);
- IsrCount = adapter->MsiEnabled ? RssIds : 1;
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
DBG_ERROR("%s Setup the spinlocks\n", __func__);
@@ -442,6 +635,7 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
spin_lock_init(&adapter->XmtZeroLock);
spin_lock_init(&adapter->Bit64RegLock);
spin_lock_init(&adapter->AdapterLock);
+ atomic_set(&adapter->pending_allocations, 0);
DBG_ERROR("%s Setup the lists\n", __func__);
@@ -451,62 +645,82 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
InitializeListHead(&adapter->FreeSglBuffers);
InitializeListHead(&adapter->AllSglBuffers);
- /* Mark these basic allocations done. This flags essentially */
- /* tells the SxgFreeResources routine that it can grab spinlocks */
- /* and reference listheads. */
+ /*
+ * Mark these basic allocations done. This flags essentially
+ * tells the SxgFreeResources routine that it can grab spinlocks
+ * and reference listheads.
+ */
adapter->BasicAllocations = TRUE;
- /* Main allocation loop. Start with the maximum supported by */
- /* the microcode and back off if memory allocation */
- /* fails. If we hit a minimum, fail. */
+ /*
+ * Main allocation loop. Start with the maximum supported by
+ * the microcode and back off if memory allocation
+ * fails. If we hit a minimum, fail.
+ */
for (;;) {
DBG_ERROR("%s Allocate XmtRings size[%x]\n", __func__,
- (unsigned int)(sizeof(struct SXG_XMT_RING) * 1));
+ (unsigned int)(sizeof(struct sxg_xmt_ring) * 1));
- /* Start with big items first - receive and transmit rings. At the moment */
- /* I'm going to keep the ring size fixed and adjust the number of */
- /* TCBs if we fail. Later we might consider reducing the ring size as well.. */
+ /*
+ * Start with big items first - receive and transmit rings.
+ * At the moment I'm going to keep the ring size fixed and
+ * adjust the TCBs if we fail. Later we might
+ * consider reducing the ring size as well..
+ */
adapter->XmtRings = pci_alloc_consistent(adapter->pcidev,
- sizeof(struct SXG_XMT_RING) *
- 1,
- &adapter->PXmtRings);
+ sizeof(struct sxg_xmt_ring) *
+ 1,
+ &adapter->PXmtRings);
DBG_ERROR("%s XmtRings[%p]\n", __func__, adapter->XmtRings);
if (!adapter->XmtRings) {
goto per_tcb_allocation_failed;
}
- memset(adapter->XmtRings, 0, sizeof(struct SXG_XMT_RING) * 1);
+ memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1);
DBG_ERROR("%s Allocate RcvRings size[%x]\n", __func__,
- (unsigned int)(sizeof(struct SXG_RCV_RING) * 1));
+ (unsigned int)(sizeof(struct sxg_rcv_ring) * 1));
adapter->RcvRings =
pci_alloc_consistent(adapter->pcidev,
- sizeof(struct SXG_RCV_RING) * 1,
+ sizeof(struct sxg_rcv_ring) * 1,
&adapter->PRcvRings);
DBG_ERROR("%s RcvRings[%p]\n", __func__, adapter->RcvRings);
if (!adapter->RcvRings) {
goto per_tcb_allocation_failed;
}
- memset(adapter->RcvRings, 0, sizeof(struct SXG_RCV_RING) * 1);
+ memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1);
+ adapter->ucode_stats = kzalloc(sizeof(struct sxg_ucode_stats), GFP_ATOMIC);
+ adapter->pucode_stats = pci_map_single(adapter->pcidev,
+ adapter->ucode_stats,
+ sizeof(struct sxg_ucode_stats),
+ PCI_DMA_FROMDEVICE);
+// memset(adapter->ucode_stats, 0, sizeof(struct sxg_ucode_stats));
break;
per_tcb_allocation_failed:
/* an allocation failed. Free any successful allocations. */
if (adapter->XmtRings) {
pci_free_consistent(adapter->pcidev,
- sizeof(struct SXG_XMT_RING) * 4096,
+ sizeof(struct sxg_xmt_ring) * 1,
adapter->XmtRings,
adapter->PXmtRings);
adapter->XmtRings = NULL;
}
if (adapter->RcvRings) {
pci_free_consistent(adapter->pcidev,
- sizeof(struct SXG_RCV_RING) * 4096,
+ sizeof(struct sxg_rcv_ring) * 1,
adapter->RcvRings,
adapter->PRcvRings);
adapter->RcvRings = NULL;
}
/* Loop around and try again.... */
+ if (adapter->ucode_stats) {
+ pci_unmap_single(adapter->pcidev,
+ sizeof(struct sxg_ucode_stats),
+ adapter->pucode_stats, PCI_DMA_FROMDEVICE);
+ adapter->ucode_stats = NULL;
+ }
+
}
DBG_ERROR("%s Initialize RCV ZERO and XMT ZERO rings\n", __func__);
@@ -515,53 +729,37 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
/* Sanity check receive data structure format */
- ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
- (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
- ASSERT(sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK) ==
+ /* ASSERT((adapter->ReceiveBufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
+ (adapter->ReceiveBufferSize == SXG_RCV_JUMBO_BUFFER_SIZE)); */
+ ASSERT(sizeof(struct sxg_rcv_descriptor_block) ==
SXG_RCV_DESCRIPTOR_BLOCK_SIZE);
- /* Allocate receive data buffers. We allocate a block of buffers and */
- /* a corresponding descriptor block at once. See sxghw.h:SXG_RCV_BLOCK */
- for (i = 0; i < SXG_INITIAL_RCV_DATA_BUFFERS;
- i += SXG_RCV_DESCRIPTORS_PER_BLOCK) {
- sxg_allocate_buffer_memory(adapter,
- SXG_RCV_BLOCK_SIZE(adapter->
- ReceiveBufferSize),
- SXG_BUFFER_TYPE_RCV);
- }
- /* NBL resource allocation can fail in the 'AllocateComplete' routine, which */
- /* doesn't return status. Make sure we got the number of buffers we requested */
- if (adapter->FreeRcvBufferCount < SXG_INITIAL_RCV_DATA_BUFFERS) {
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6",
- adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES,
- 0);
- return (STATUS_RESOURCES);
- }
-
DBG_ERROR("%s Allocate EventRings size[%x]\n", __func__,
- (unsigned int)(sizeof(struct SXG_EVENT_RING) * RssIds));
+ (unsigned int)(sizeof(struct sxg_event_ring) * RssIds));
/* Allocate event queues. */
adapter->EventRings = pci_alloc_consistent(adapter->pcidev,
- sizeof(struct SXG_EVENT_RING) *
- RssIds,
- &adapter->PEventRings);
+ sizeof(struct sxg_event_ring) *
+ RssIds,
+ &adapter->PEventRings);
if (!adapter->EventRings) {
- /* Caller will call SxgFreeAdapter to clean up above allocations */
+ /* Caller will call SxgFreeAdapter to clean up above
+ * allocations */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF8",
adapter, SXG_MAX_ENTRIES, 0, 0);
status = STATUS_RESOURCES;
goto per_tcb_allocation_failed;
}
- memset(adapter->EventRings, 0, sizeof(struct SXG_EVENT_RING) * RssIds);
+ memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds);
DBG_ERROR("%s Allocate ISR size[%x]\n", __func__, IsrCount);
/* Allocate ISR */
adapter->Isr = pci_alloc_consistent(adapter->pcidev,
IsrCount, &adapter->PIsr);
if (!adapter->Isr) {
- /* Caller will call SxgFreeAdapter to clean up above allocations */
+ /* Caller will call SxgFreeAdapter to clean up above
+ * allocations */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF9",
adapter, SXG_MAX_ENTRIES, 0, 0);
status = STATUS_RESOURCES;
@@ -588,8 +786,7 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlcResS",
adapter, SXG_MAX_ENTRIES, 0, 0);
- DBG_ERROR("%s EXIT\n", __func__);
- return (STATUS_SUCCESS);
+ return status;
}
/*
@@ -599,7 +796,6 @@ static int sxg_allocate_resources(struct adapter_t *adapter)
*
* Arguments -
* pcidev - A pointer to our adapter structure
- *
*/
static void sxg_config_pci(struct pci_dev *pcidev)
{
@@ -609,12 +805,19 @@ static void sxg_config_pci(struct pci_dev *pcidev)
pci_read_config_word(pcidev, PCI_COMMAND, &pci_command);
DBG_ERROR("sxg: %s PCI command[%4.4x]\n", __func__, pci_command);
/* Set the command register */
- new_command = pci_command | (PCI_COMMAND_MEMORY | /* Memory Space Enable */
- PCI_COMMAND_MASTER | /* Bus master enable */
- PCI_COMMAND_INVALIDATE | /* Memory write and invalidate */
- PCI_COMMAND_PARITY | /* Parity error response */
- PCI_COMMAND_SERR | /* System ERR */
- PCI_COMMAND_FAST_BACK); /* Fast back-to-back */
+ new_command = pci_command | (
+ /* Memory Space Enable */
+ PCI_COMMAND_MEMORY |
+ /* Bus master enable */
+ PCI_COMMAND_MASTER |
+ /* Memory write and invalidate */
+ PCI_COMMAND_INVALIDATE |
+ /* Parity error response */
+ PCI_COMMAND_PARITY |
+ /* System ERR */
+ PCI_COMMAND_SERR |
+ /* Fast back-to-back */
+ PCI_COMMAND_FAST_BACK);
if (pci_command != new_command) {
DBG_ERROR("%s -- Updating PCI COMMAND register %4.4x->%4.4x.\n",
__func__, pci_command, new_command);
@@ -622,6 +825,77 @@ static void sxg_config_pci(struct pci_dev *pcidev)
}
}
+/*
+ * sxg_read_config
+ * @adapter : Pointer to the adapter structure for the card
+ * This function will read the configuration data from EEPROM/FLASH
+ */
+static inline int sxg_read_config(struct adapter_t *adapter)
+{
+ /* struct sxg_config data; */
+ struct sxg_config *config;
+ struct sw_cfg_data *data;
+ dma_addr_t p_addr;
+ unsigned long status;
+ unsigned long i;
+ config = pci_alloc_consistent(adapter->pcidev,
+ sizeof(struct sxg_config), &p_addr);
+
+ if(!config) {
+ /*
+ * We cant get even this much memory. Raise a hell
+ * Get out of here
+ */
+ printk(KERN_ERR"%s : Could not allocate memory for reading \
+ EEPROM\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ data = &config->SwCfg;
+
+ /* Initialize (reflective memory) status register */
+ WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE);
+
+ /* Send request to fetch configuration data */
+ WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0);
+ for(i=0; i<1000; i++) {
+ READ_REG(adapter->UcodeRegs[0].ConfigStat, status);
+ if (status != SXG_CFG_TIMEOUT)
+ break;
+ mdelay(1); /* Do we really need this */
+ }
+
+ switch(status) {
+ /* Config read from EEPROM succeeded */
+ case SXG_CFG_LOAD_EEPROM:
+ /* Config read from Flash succeeded */
+ case SXG_CFG_LOAD_FLASH:
+ /*
+ * Copy the MAC address to adapter structure
+ * TODO: We are not doing the remaining part : FRU, etc
+ */
+ memcpy(adapter->macaddr, data->MacAddr[0].MacAddr,
+ sizeof(struct sxg_config_mac));
+ break;
+ case SXG_CFG_TIMEOUT:
+ case SXG_CFG_LOAD_INVALID:
+ case SXG_CFG_LOAD_ERROR:
+ default: /* Fix default handler later */
+ printk(KERN_WARNING"%s : We could not read the config \
+ word. Status = %ld\n", __FUNCTION__, status);
+ break;
+ }
+ pci_free_consistent(adapter->pcidev, sizeof(struct sw_cfg_data), data,
+ p_addr);
+ if (adapter->netdev) {
+ memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
+ memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6);
+ }
+ sxg_dbg_macaddrs(adapter);
+
+ return status;
+}
+
static int sxg_entry_probe(struct pci_dev *pcidev,
const struct pci_device_id *pci_tbl_entry)
{
@@ -633,6 +907,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
u32 status = 0;
ulong mmio_start = 0;
ulong mmio_len = 0;
+ unsigned char revision_id;
DBG_ERROR("sxg: %s 2.6 VERSION ENTER jiffies[%lx] cpu %d\n",
__func__, jiffies, smp_processor_id());
@@ -654,9 +929,11 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
if (sxg_debug > 0 && did_version++ == 0) {
printk(KERN_INFO "%s\n", sxg_banner);
- printk(KERN_INFO "%s\n", DRV_VERSION);
+ printk(KERN_INFO "%s\n", SXG_DRV_VERSION);
}
+ pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision_id);
+
if (!(err = pci_set_dma_mask(pcidev, DMA_64BIT_MASK))) {
DBG_ERROR("pci_set_dma_mask(DMA_64BIT_MASK) successful\n");
} else {
@@ -671,7 +948,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
DBG_ERROR("Call pci_request_regions\n");
- err = pci_request_regions(pcidev, DRV_NAME);
+ err = pci_request_regions(pcidev, sxg_driver_name);
if (err) {
DBG_ERROR("pci_request_regions FAILED err[%x]\n", err);
return err;
@@ -692,6 +969,15 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
pci_set_drvdata(pcidev, netdev);
adapter = netdev_priv(netdev);
+ if (revision_id == 1) {
+ adapter->asictype = SAHARA_REV_A;
+ } else if (revision_id == 2) {
+ adapter->asictype = SAHARA_REV_B;
+ } else {
+ ASSERT(0);
+ DBG_ERROR("%s Unexpected revision ID %x\n", __FUNCTION__, revision_id);
+ goto err_out_exit_sxg_probe;
+ }
adapter->netdev = netdev;
adapter->pcidev = pcidev;
@@ -707,12 +993,12 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
if (!memmapped_ioaddr) {
DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
__func__, mmio_len, mmio_start);
- goto err_out_free_mmio_region;
+ goto err_out_free_mmio_region_0;
}
- DBG_ERROR
- ("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] len[%lx], IRQ %d.\n",
- __func__, memmapped_ioaddr, mmio_start, mmio_len, pcidev->irq);
+ DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, start[%lx] \
+ len[%lx], IRQ %d.\n", __func__, memmapped_ioaddr, mmio_start,
+ mmio_len, pcidev->irq);
adapter->HwRegs = (void *)memmapped_ioaddr;
adapter->base_addr = memmapped_ioaddr;
@@ -729,7 +1015,7 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
if (!memmapped_ioaddr) {
DBG_ERROR("%s cannot remap MMIO region %lx @ %lx\n",
__func__, mmio_len, mmio_start);
- goto err_out_free_mmio_region;
+ goto err_out_free_mmio_region_2;
}
DBG_ERROR("sxg: %s found Alacritech SXG PCI, MMIO at %p, "
@@ -739,8 +1025,10 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
adapter->UcodeRegs = (void *)memmapped_ioaddr;
adapter->State = SXG_STATE_INITIALIZING;
- /* Maintain a list of all adapters anchored by */
- /* the global SxgDriver structure. */
+ /*
+ * Maintain a list of all adapters anchored by
+ * the global SxgDriver structure.
+ */
adapter->Next = SxgDriver.Adapters;
SxgDriver.Adapters = adapter;
adapter->AdapterID = ++SxgDriver.AdapterID;
@@ -758,10 +1046,12 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
}
-/* status = SXG_READ_EEPROM(adapter); */
-/* if (!status) { */
-/* goto sxg_init_bad; */
-/* } */
+ /*
+ * status = SXG_READ_EEPROM(adapter);
+ * if (!status) {
+ * goto sxg_init_bad;
+ * }
+ */
DBG_ERROR("sxg: %s ENTER sxg_config_pci\n", __func__);
sxg_config_pci(pcidev);
@@ -774,16 +1064,13 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
adapter->vendid = pci_tbl_entry->vendor;
adapter->devid = pci_tbl_entry->device;
adapter->subsysid = pci_tbl_entry->subdevice;
- adapter->busnumber = pcidev->bus->number;
adapter->slotnumber = ((pcidev->devfn >> 3) & 0x1F);
adapter->functionnumber = (pcidev->devfn & 0x7);
adapter->memorylength = pci_resource_len(pcidev, 0);
adapter->irq = pcidev->irq;
adapter->next_netdevice = head_netdevice;
head_netdevice = netdev;
-/* adapter->chipid = chip_idx; */
adapter->port = 0; /*adapter->functionnumber; */
- adapter->cardindex = adapter->port;
/* Allocate memory and other resources */
DBG_ERROR("sxg: %s ENTER sxg_allocate_resources\n", __func__);
@@ -795,10 +1082,11 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
}
DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __func__);
- if (sxg_download_microcode(adapter, SXG_UCODE_SAHARA)) {
+ if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
__func__);
- sxg_adapter_set_hwaddr(adapter);
+ sxg_read_config(adapter);
+ status = sxg_adapter_set_hwaddr(adapter);
} else {
adapter->state = ADAPT_FAIL;
adapter->linkstate = LINK_DOWN;
@@ -811,40 +1099,63 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
netdev->stop = sxg_entry_halt;
netdev->hard_start_xmit = sxg_send_packets;
netdev->do_ioctl = sxg_ioctl;
+ netdev->change_mtu = sxg_change_mtu;
#if XXXTODO
netdev->set_mac_address = sxg_mac_set_address;
-#if SLIC_GET_STATS_ENABLED
- netdev->get_stats = sxg_get_stats;
#endif
+ netdev->get_stats = sxg_get_stats;
netdev->set_multicast_list = sxg_mcast_set_list;
-#endif
+ SET_ETHTOOL_OPS(netdev, &sxg_nic_ethtool_ops);
+ netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+ err = sxg_set_interrupt_capability(adapter);
+ if (err != STATUS_SUCCESS)
+ DBG_ERROR("Cannot enable MSI-X capability\n");
strcpy(netdev->name, "eth%d");
-/* strcpy(netdev->name, pci_name(pcidev)); */
+ /* strcpy(netdev->name, pci_name(pcidev)); */
if ((err = register_netdev(netdev))) {
DBG_ERROR("Cannot register net device, aborting. %s\n",
netdev->name);
goto err_out_unmap;
}
+ netif_napi_add(netdev, &adapter->napi,
+ sxg_poll, SXG_NETDEV_WEIGHT);
+ netdev->watchdog_timeo = 2 * HZ;
+ init_timer(&adapter->watchdog_timer);
+ adapter->watchdog_timer.function = &sxg_watchdog;
+ adapter->watchdog_timer.data = (unsigned long) adapter;
+ INIT_WORK(&adapter->update_link_status, sxg_update_link_status);
+
DBG_ERROR
- ("sxg: %s addr 0x%lx, irq %d, MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n",
+ ("sxg: %s addr 0x%lx, irq %d, MAC addr \
+ %02X:%02X:%02X:%02X:%02X:%02X\n",
netdev->name, netdev->base_addr, pcidev->irq, netdev->dev_addr[0],
netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3],
netdev->dev_addr[4], netdev->dev_addr[5]);
-/*sxg_init_bad: */
+ /* sxg_init_bad: */
ASSERT(status == FALSE);
-/* sxg_free_adapter(adapter); */
+ /* sxg_free_adapter(adapter); */
DBG_ERROR("sxg: %s EXIT status[%x] jiffies[%lx] cpu %d\n", __func__,
status, jiffies, smp_processor_id());
return status;
err_out_unmap:
- iounmap((void *)memmapped_ioaddr);
+ sxg_free_resources(adapter);
+
+ err_out_free_mmio_region_2:
+
+ mmio_start = pci_resource_start(pcidev, 2);
+ mmio_len = pci_resource_len(pcidev, 2);
+ release_mem_region(mmio_start, mmio_len);
+
+ err_out_free_mmio_region_0:
+
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
- err_out_free_mmio_region:
release_mem_region(mmio_start, mmio_len);
err_out_exit_sxg_probe:
@@ -852,13 +1163,16 @@ static int sxg_entry_probe(struct pci_dev *pcidev,
DBG_ERROR("%s EXIT jiffies[%lx] cpu %d\n", __func__, jiffies,
smp_processor_id());
+ pci_disable_device(pcidev);
+ DBG_ERROR("sxg: %s deallocate device\n", __FUNCTION__);
+ kfree(netdev);
+ printk("Exit %s, Sxg driver loading failed..\n", __FUNCTION__);
+
return -ENODEV;
}
-/***********************************************************************
- * LINE BASE Interrupt routines..
- ***********************************************************************/
/*
+ * LINE BASE Interrupt routines..
*
* sxg_disable_interrupt
*
@@ -877,10 +1191,7 @@ static void sxg_disable_interrupt(struct adapter_t *adapter)
adapter, adapter->InterruptsEnabled, 0, 0);
/* For now, RSS is disabled with line based interrupts */
ASSERT(adapter->RssEnabled == FALSE);
- ASSERT(adapter->MsiEnabled == FALSE);
- /* */
/* Turn off interrupts by writing to the icr register. */
- /* */
WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_DISABLE), TRUE);
adapter->InterruptsEnabled = 0;
@@ -890,7 +1201,6 @@ static void sxg_disable_interrupt(struct adapter_t *adapter)
}
/*
- *
* sxg_enable_interrupt
*
* EnableInterrupt Handler
@@ -908,10 +1218,7 @@ static void sxg_enable_interrupt(struct adapter_t *adapter)
adapter, adapter->InterruptsEnabled, 0, 0);
/* For now, RSS is disabled with line based interrupts */
ASSERT(adapter->RssEnabled == FALSE);
- ASSERT(adapter->MsiEnabled == FALSE);
- /* */
/* Turn on interrupts by writing to the icr register. */
- /* */
WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_ENABLE), TRUE);
adapter->InterruptsEnabled = 1;
@@ -921,50 +1228,51 @@ static void sxg_enable_interrupt(struct adapter_t *adapter)
}
/*
- *
* sxg_isr - Process an line-based interrupt
*
* Arguments:
- * Context - Our adapter structure
+ * Context - Our adapter structure
* QueueDefault - Output parameter to queue to default CPU
- * TargetCpus - Output bitmap to schedule DPC's
+ * TargetCpus - Output bitmap to schedule DPC's
*
- * Return Value:
- * TRUE if our interrupt
+ * Return Value: TRUE if our interrupt
*/
static irqreturn_t sxg_isr(int irq, void *dev_id)
{
- p_net_device dev = (p_net_device) dev_id;
+ struct net_device *dev = (struct net_device *) dev_id;
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
-/* u32 CpuMask = 0, i; */
+ if(adapter->state != ADAPT_UP)
+ return IRQ_NONE;
adapter->Stats.NumInts++;
if (adapter->Isr[0] == 0) {
- /* The SLIC driver used to experience a number of spurious interrupts */
- /* due to the delay associated with the masking of the interrupt */
- /* (we'd bounce back in here). If we see that again with Sahara, */
- /* add a READ_REG of the Icr register after the WRITE_REG below. */
+ /*
+ * The SLIC driver used to experience a number of spurious
+ * interrupts due to the delay associated with the masking of
+ * the interrupt (we'd bounce back in here). If we see that
+ * again with Sahara,add a READ_REG of the Icr register after
+ * the WRITE_REG below.
+ */
adapter->Stats.FalseInts++;
return IRQ_NONE;
}
- /* */
- /* Move the Isr contents and clear the value in */
- /* shared memory, and mask interrupts */
- /* */
- adapter->IsrCopy[0] = adapter->Isr[0];
- adapter->Isr[0] = 0;
- WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
-/* ASSERT(adapter->IsrDpcsPending == 0); */
+ /*
+ * Move the Isr contents and clear the value in
+ * shared memory, and mask interrupts
+ */
+ /* ASSERT(adapter->IsrDpcsPending == 0); */
#if XXXTODO /* RSS Stuff */
- /* If RSS is enabled and the ISR specifies */
- /* SXG_ISR_EVENT, then schedule DPC's */
- /* based on event queues. */
+ /*
+ * If RSS is enabled and the ISR specifies SXG_ISR_EVENT, then
+ * schedule DPC's based on event queues.
+ */
if (adapter->RssEnabled && (adapter->IsrCopy[0] & SXG_ISR_EVENT)) {
for (i = 0;
i < adapter->RssSystemInfo->ProcessorInfo.RssCpuCount;
i++) {
- struct XG_EVENT_RING *EventRing = &adapter->EventRings[i];
- struct SXG_EVENT *Event =
+ struct sxg_event_ring *EventRing =
+ &adapter->EventRings[i];
+ struct sxg_event *Event =
&EventRing->Ring[adapter->NextEvent[i]];
unsigned char Cpu =
adapter->RssSystemInfo->RssIdToCpu[i];
@@ -974,8 +1282,10 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
}
}
}
- /* Now, either schedule the CPUs specified by the CpuMask, */
- /* or queue default */
+ /*
+ * Now, either schedule the CPUs specified by the CpuMask,
+ * or queue default
+ */
if (CpuMask) {
*QueueDefault = FALSE;
} else {
@@ -984,34 +1294,41 @@ static irqreturn_t sxg_isr(int irq, void *dev_id)
}
*TargetCpus = CpuMask;
#endif
- /* */
- /* There are no DPCs in Linux, so call the handler now */
- /* */
- sxg_handle_interrupt(adapter);
+ sxg_interrupt(adapter);
return IRQ_HANDLED;
}
-static void sxg_handle_interrupt(struct adapter_t *adapter)
+static void sxg_interrupt(struct adapter_t *adapter)
{
-/* unsigned char RssId = 0; */
- u32 NewIsr;
+ WRITE_REG(adapter->UcodeRegs[0].Icr, SXG_ICR(0, SXG_ICR_MASK), TRUE);
- if (adapter->Stats.RcvNoBuffer < 5) {
- DBG_ERROR("Enter sxg_handle_interrupt ISR[%x]\n",
- adapter->IsrCopy[0]);
+ if (napi_schedule_prep(&adapter->napi)) {
+ __napi_schedule(&adapter->napi);
}
+}
+
+static void sxg_handle_interrupt(struct adapter_t *adapter, int *work_done,
+ int budget)
+{
+ /* unsigned char RssId = 0; */
+ u32 NewIsr;
+ int sxg_napi_continue = 1;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "HndlIntr",
adapter, adapter->IsrCopy[0], 0, 0);
/* For now, RSS is disabled with line based interrupts */
ASSERT(adapter->RssEnabled == FALSE);
- ASSERT(adapter->MsiEnabled == FALSE);
- ASSERT(adapter->IsrCopy[0]);
-/*/////////////////////////// */
+
+ adapter->IsrCopy[0] = adapter->Isr[0];
+ adapter->Isr[0] = 0;
/* Always process the event queue. */
- sxg_process_event_queue(adapter,
- (adapter->RssEnabled ? /*RssId */ 0 : 0));
+ while (sxg_napi_continue)
+ {
+ sxg_process_event_queue(adapter,
+ (adapter->RssEnabled ? /*RssId */ 0 : 0),
+ &sxg_napi_continue, work_done, budget);
+ }
#if XXXTODO /* RSS stuff */
if (--adapter->IsrDpcsPending) {
@@ -1022,30 +1339,31 @@ static void sxg_handle_interrupt(struct adapter_t *adapter)
return;
}
#endif
- /* */
/* Last (or only) DPC processes the ISR and clears the interrupt. */
- /* */
NewIsr = sxg_process_isr(adapter, 0);
- /* */
/* Reenable interrupts */
- /* */
adapter->IsrCopy[0] = 0;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "ClearIsr",
adapter, NewIsr, 0, 0);
- if (adapter->Stats.RcvNoBuffer < 5) {
- DBG_ERROR
- ("Exit sxg_handle_interrupt2 after enabling interrupt\n");
- }
-
- WRITE_REG(adapter->UcodeRegs[0].Isr, NewIsr, TRUE);
-
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XHndlInt",
adapter, 0, 0, 0);
}
+static int sxg_poll(struct napi_struct *napi, int budget)
+{
+ struct adapter_t *adapter = container_of(napi, struct adapter_t, napi);
+ int work_done = 0;
+
+ sxg_handle_interrupt(adapter, &work_done, budget);
+
+ if (work_done < budget) {
+ napi_complete(napi);
+ WRITE_REG(adapter->UcodeRegs[0].Isr, 0, TRUE);
+ }
+ return work_done;
+}
/*
- *
* sxg_process_isr - Process an interrupt. Called from the line-based and
* message based interrupt DPC routines
*
@@ -1072,24 +1390,28 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/* No host buffer */
if (Isr & SXG_ISR_RMISS) {
- /* There is a bunch of code in the SLIC driver which */
- /* attempts to process more receive events per DPC */
- /* if we start to fall behind. We'll probably */
- /* need to do something similar here, but hold */
- /* off for now. I don't want to make the code more */
- /* complicated than strictly needed. */
- adapter->Stats.RcvNoBuffer++;
- if (adapter->Stats.RcvNoBuffer < 5) {
+ /*
+ * There is a bunch of code in the SLIC driver which
+ * attempts to process more receive events per DPC
+ * if we start to fall behind. We'll probablyd
+ * need to do something similar here, but hold
+ * off for now. I don't want to make the code more
+ * complicated than strictly needed.
+ */
+ adapter->stats.rx_missed_errors++;
+ if (adapter->stats.rx_missed_errors< 5) {
DBG_ERROR("%s: SXG_ISR_ERR RMISS!!\n",
__func__);
}
}
/* Card crash */
if (Isr & SXG_ISR_DEAD) {
- /* Set aside the crash info and set the adapter state to RESET */
- adapter->CrashCpu =
- (unsigned char)((Isr & SXG_ISR_CPU) >>
- SXG_ISR_CPU_SHIFT);
+ /*
+ * Set aside the crash info and set the adapter state
+ * to RESET
+ */
+ adapter->CrashCpu = (unsigned char)
+ ((Isr & SXG_ISR_CPU) >> SXG_ISR_CPU_SHIFT);
adapter->CrashLocation = (ushort) (Isr & SXG_ISR_CRASH);
adapter->Dead = TRUE;
DBG_ERROR("%s: ISR_DEAD %x, CPU: %d\n", __func__,
@@ -1097,18 +1419,18 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/* Event ring full */
if (Isr & SXG_ISR_ERFULL) {
- /* Same issue as RMISS, really. This means the */
- /* host is falling behind the card. Need to increase */
- /* event ring size, process more events per interrupt, */
- /* and/or reduce/remove interrupt aggregation. */
+ /*
+ * Same issue as RMISS, really. This means the
+ * host is falling behind the card. Need to increase
+ * event ring size, process more events per interrupt,
+ * and/or reduce/remove interrupt aggregation.
+ */
adapter->Stats.EventRingFull++;
DBG_ERROR("%s: SXG_ISR_ERR EVENT RING FULL!!\n",
__func__);
}
/* Transmit drop - no DRAM buffers or XMT error */
if (Isr & SXG_ISR_XDROP) {
- adapter->Stats.XmtDrops++;
- adapter->Stats.XmtErrors++;
DBG_ERROR("%s: SXG_ISR_ERR XDROP!!\n", __func__);
}
}
@@ -1118,18 +1440,24 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/* Dump */
if (Isr & SXG_ISR_UPC) {
- ASSERT(adapter->DumpCmdRunning); /* Maybe change when debug is added.. */
+ /* Maybe change when debug is added.. */
+// ASSERT(adapter->DumpCmdRunning);
adapter->DumpCmdRunning = FALSE;
}
/* Link event */
if (Isr & SXG_ISR_LINK) {
- sxg_link_event(adapter);
+ if (adapter->state != ADAPT_DOWN) {
+ adapter->link_status_changed = 1;
+ schedule_work(&adapter->update_link_status);
+ }
}
/* Debug - breakpoint hit */
if (Isr & SXG_ISR_BREAK) {
- /* At the moment AGDB isn't written to support interactive */
- /* debug sessions. When it is, this interrupt will be used */
- /* to signal AGDB that it has hit a breakpoint. For now, ASSERT. */
+ /*
+ * At the moment AGDB isn't written to support interactive
+ * debug sessions. When it is, this interrupt will be used to
+ * signal AGDB that it has hit a breakpoint. For now, ASSERT.
+ */
ASSERT(0);
}
/* Heartbeat response */
@@ -1143,7 +1471,33 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
}
/*
+ * sxg_rcv_checksum - Set the checksum for received packet
*
+ * Arguements:
+ * @adapter - Adapter structure on which packet is received
+ * @skb - Packet which is receieved
+ * @Event - Event read from hardware
+ */
+
+void sxg_rcv_checksum(struct adapter_t *adapter, struct sk_buff *skb,
+ struct sxg_event *Event)
+{
+ skb->ip_summed = CHECKSUM_NONE;
+ if (likely(adapter->flags & SXG_RCV_IP_CSUM_ENABLED)) {
+ if (likely(adapter->flags & SXG_RCV_TCP_CSUM_ENABLED)
+ && (Event->Status & EVENT_STATUS_TCPIP)) {
+ if(!(Event->Status & EVENT_STATUS_TCPBAD))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ if(!(Event->Status & EVENT_STATUS_IPBAD))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ } else if(Event->Status & EVENT_STATUS_IPONLY) {
+ if(!(Event->Status & EVENT_STATUS_IPBAD))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
+ }
+}
+
+/*
* sxg_process_event_queue - Process our event queue
*
* Arguments:
@@ -1153,46 +1507,52 @@ static int sxg_process_isr(struct adapter_t *adapter, u32 MessageId)
* Return Value:
* None.
*/
-static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
+static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId,
+ int *sxg_napi_continue, int *work_done, int budget)
{
- struct SXG_EVENT_RING *EventRing = &adapter->EventRings[RssId];
- struct SXG_EVENT *Event = &EventRing->Ring[adapter->NextEvent[RssId]];
+ struct sxg_event_ring *EventRing = &adapter->EventRings[RssId];
+ struct sxg_event *Event = &EventRing->Ring[adapter->NextEvent[RssId]];
u32 EventsProcessed = 0, Batches = 0;
- u32 num_skbs = 0;
struct sk_buff *skb;
#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
struct sk_buff *prev_skb = NULL;
struct sk_buff *IndicationList[SXG_RCV_ARRAYSIZE];
u32 Index;
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
#endif
u32 ReturnStatus = 0;
+ int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS;
ASSERT((adapter->State == SXG_STATE_RUNNING) ||
(adapter->State == SXG_STATE_PAUSING) ||
(adapter->State == SXG_STATE_PAUSED) ||
(adapter->State == SXG_STATE_HALTING));
- /* We may still have unprocessed events on the queue if */
- /* the card crashed. Don't process them. */
+ /*
+ * We may still have unprocessed events on the queue if
+ * the card crashed. Don't process them.
+ */
if (adapter->Dead) {
return (0);
}
- /* In theory there should only be a single processor that */
- /* accesses this queue, and only at interrupt-DPC time. So */
- /* we shouldn't need a lock for any of this. */
+ /*
+ * In theory there should only be a single processor that
+ * accesses this queue, and only at interrupt-DPC time. So/
+ * we shouldn't need a lock for any of this.
+ */
while (Event->Status & EVENT_STATUS_VALID) {
+ (*sxg_napi_continue) = 1;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "Event",
Event, Event->Code, Event->Status,
adapter->NextEvent);
switch (Event->Code) {
case EVENT_CODE_BUFFERS:
- ASSERT(!(Event->CommandIndex & 0xFF00)); /* SXG_RING_INFO Head & Tail == unsigned char */
- /* */
+ /* struct sxg_ring_info Head & Tail == unsigned char */
+ ASSERT(!(Event->CommandIndex & 0xFF00));
sxg_complete_descriptor_blocks(adapter,
Event->CommandIndex);
- /* */
break;
case EVENT_CODE_SLOWRCV:
+ (*work_done)++;
--adapter->RcvBuffersOnCard;
if ((skb = sxg_slow_receive(adapter, Event))) {
u32 rx_bytes;
@@ -1200,51 +1560,61 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
/* Add it to our indication list */
SXG_ADD_RCV_PACKET(adapter, skb, prev_skb,
IndicationList, num_skbs);
- /* In Linux, we just pass up each skb to the protocol above at this point, */
- /* there is no capability of an indication list. */
+ /*
+ * Linux, we just pass up each skb to the
+ * protocol above at this point, there is no
+ * capability of an indication list.
+ */
#else
-/* CHECK skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
- rx_bytes = Event->Length; /* (rcvbuf->length & IRHDDR_FLEN_MSK); */
- skb_put(skb, rx_bytes);
+ /* CHECK skb_pull(skb, INIC_RCVBUF_HEADSIZE); */
+ /* (rcvbuf->length & IRHDDR_FLEN_MSK); */
+ rx_bytes = Event->Length;
adapter->stats.rx_packets++;
adapter->stats.rx_bytes += rx_bytes;
-#if SXG_OFFLOAD_IP_CHECKSUM
- skb->ip_summed = CHECKSUM_UNNECESSARY;
-#endif
+ sxg_rcv_checksum(adapter, skb, Event);
skb->dev = adapter->netdev;
- skb->protocol = eth_type_trans(skb, skb->dev);
- netif_rx(skb);
+ netif_receive_skb(skb);
#endif
}
break;
default:
DBG_ERROR("%s: ERROR Invalid EventCode %d\n",
__func__, Event->Code);
-/* ASSERT(0); */
+ /* ASSERT(0); */
}
- /* See if we need to restock card receive buffers. */
- /* There are two things to note here: */
- /* First - This test is not SMP safe. The */
- /* adapter->BuffersOnCard field is protected via atomic interlocked calls, but */
- /* we do not protect it with respect to these tests. The only way to do that */
- /* is with a lock, and I don't want to grab a lock every time we adjust the */
- /* BuffersOnCard count. Instead, we allow the buffer replenishment to be off */
- /* once in a while. The worst that can happen is the card is given one */
- /* more-or-less descriptor block than the arbitrary value we've chosen. */
- /* No big deal */
- /* In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard is adjusted. */
- /* Second - We expect this test to rarely evaluate to true. We attempt to */
- /* refill descriptor blocks as they are returned to us */
- /* (sxg_complete_descriptor_blocks), so The only time this should evaluate */
- /* to true is when sxg_complete_descriptor_blocks failed to allocate */
- /* receive buffers. */
- if (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
+ /*
+ * See if we need to restock card receive buffers.
+ * There are two things to note here:
+ * First - This test is not SMP safe. The
+ * adapter->BuffersOnCard field is protected via atomic
+ * interlocked calls, but we do not protect it with respect
+ * to these tests. The only way to do that is with a lock,
+ * and I don't want to grab a lock every time we adjust the
+ * BuffersOnCard count. Instead, we allow the buffer
+ * replenishment to be off once in a while. The worst that
+ * can happen is the card is given on more-or-less descriptor
+ * block than the arbitrary value we've chosen. No big deal
+ * In short DO NOT ADD A LOCK HERE, OR WHERE RcvBuffersOnCard
+ * is adjusted.
+ * Second - We expect this test to rarely
+ * evaluate to true. We attempt to refill descriptor blocks
+ * as they are returned to us (sxg_complete_descriptor_blocks)
+ * so The only time this should evaluate to true is when
+ * sxg_complete_descriptor_blocks failed to allocate
+ * receive buffers.
+ */
+ if (adapter->JumboEnabled)
+ sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS;
+
+ if (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) {
sxg_stock_rcv_buffers(adapter);
}
- /* It's more efficient to just set this to zero. */
- /* But clearing the top bit saves potential debug info... */
+ /*
+ * It's more efficient to just set this to zero.
+ * But clearing the top bit saves potential debug info...
+ */
Event->Status &= ~EVENT_STATUS_VALID;
- /* Advanct to the next event */
+ /* Advance to the next event */
SXG_ADVANCE_INDEX(adapter->NextEvent[RssId], EVENT_RING_SIZE);
Event = &EventRing->Ring[adapter->NextEvent[RssId]];
EventsProcessed++;
@@ -1253,9 +1623,11 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
EVENT_RING_BATCH, FALSE);
EventsProcessed = 0;
- /* If we've processed our batch limit, break out of the */
- /* loop and return SXG_ISR_EVENT to arrange for us to */
- /* be called again */
+ /*
+ * If we've processed our batch limit, break out of the
+ * loop and return SXG_ISR_EVENT to arrange for us to
+ * be called again
+ */
if (Batches++ == EVENT_BATCH_LIMIT) {
SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
TRACE_NOISY, "EvtLimit", Batches,
@@ -1264,16 +1636,22 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
break;
}
}
+ if (*work_done >= budget) {
+ WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
+ EventsProcessed, FALSE);
+ EventsProcessed = 0;
+ (*sxg_napi_continue) = 0;
+ break;
+ }
}
+ if (!(Event->Status & EVENT_STATUS_VALID))
+ (*sxg_napi_continue) = 0;
+
#ifdef LINUX_HANDLES_RCV_INDICATION_LISTS
- /* */
/* Indicate any received dumb-nic frames */
- /* */
SXG_INDICATE_PACKETS(adapter, IndicationList, num_skbs);
#endif
- /* */
/* Release events back to the card. */
- /* */
if (EventsProcessed) {
WRITE_REG(adapter->UcodeRegs[RssId].EventRelease,
EventsProcessed, FALSE);
@@ -1289,27 +1667,35 @@ static u32 sxg_process_event_queue(struct adapter_t *adapter, u32 RssId)
*
* Arguments -
* adapter - A pointer to our adapter structure
-
* Return
* None
*/
static void sxg_complete_slow_send(struct adapter_t *adapter)
{
- struct SXG_XMT_RING *XmtRing = &adapter->XmtRings[0];
- struct SXG_RING_INFO *XmtRingInfo = &adapter->XmtRingZeroInfo;
+ struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
+ struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
u32 *ContextType;
- struct SXG_CMD *XmtCmd;
+ struct sxg_cmd *XmtCmd;
+ unsigned long flags = 0;
+ unsigned long sgl_flags = 0;
+ unsigned int processed_count = 0;
+
+ /*
+ * NOTE - This lock is dropped and regrabbed in this loop.
+ * This means two different processors can both be running/
+ * through this loop. Be *very* careful.
+ */
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
- /* NOTE - This lock is dropped and regrabbed in this loop. */
- /* This means two different processors can both be running */
- /* through this loop. Be *very* careful. */
- spin_lock(&adapter->XmtZeroLock);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnds",
adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
- while (XmtRingInfo->Tail != *adapter->XmtRingZeroIndex) {
- /* Locate the current Cmd (ring descriptor entry), and */
- /* associated SGL, and advance the tail */
+ while ((XmtRingInfo->Tail != *adapter->XmtRingZeroIndex)
+ && processed_count++ < SXG_COMPLETE_SLOW_SEND_LIMIT) {
+ /*
+ * Locate the current Cmd (ring descriptor entry), and
+ * associated SGL, and advance the tail
+ */
SXG_RETURN_CMD(XmtRing, XmtRingInfo, XmtCmd, ContextType);
ASSERT(ContextType);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
@@ -1321,30 +1707,45 @@ static void sxg_complete_slow_send(struct adapter_t *adapter)
case SXG_SGL_DUMB:
{
struct sk_buff *skb;
+ struct sxg_scatter_gather *SxgSgl =
+ (struct sxg_scatter_gather *)ContextType;
+ dma64_addr_t FirstSgeAddress;
+ u32 FirstSgeLength;
+
/* Dumb-nic send. Command context is the dumb-nic SGL */
skb = (struct sk_buff *)ContextType;
+ skb = SxgSgl->DumbPacket;
+ FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress;
+ FirstSgeLength = XmtCmd->Buffer.FirstSgeLength;
/* Complete the send */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer,
TRACE_IMPORTANT, "DmSndCmp", skb, 0,
0, 0);
ASSERT(adapter->Stats.XmtQLen);
- adapter->Stats.XmtQLen--; /* within XmtZeroLock */
- adapter->Stats.XmtOk++;
- /* Now drop the lock and complete the send back to */
- /* Microsoft. We need to drop the lock because */
- /* Microsoft can come back with a chimney send, which */
- /* results in a double trip in SxgTcpOuput */
- spin_unlock(&adapter->XmtZeroLock);
- SXG_COMPLETE_DUMB_SEND(adapter, skb);
+ /*
+ * Now drop the lock and complete the send
+ * back to Microsoft. We need to drop the lock
+ * because Microsoft can come back with a
+ * chimney send, which results in a double trip
+ * in SxgTcpOuput
+ */
+ spin_unlock_irqrestore(
+ &adapter->XmtZeroLock, flags);
+
+ SxgSgl->DumbPacket = NULL;
+ SXG_COMPLETE_DUMB_SEND(adapter, skb,
+ FirstSgeAddress,
+ FirstSgeLength);
+ SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
/* and reacquire.. */
- spin_lock(&adapter->XmtZeroLock);
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
}
break;
default:
ASSERT(0);
}
}
- spin_unlock(&adapter->XmtZeroLock);
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpSnd",
adapter, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
}
@@ -1356,22 +1757,27 @@ static void sxg_complete_slow_send(struct adapter_t *adapter)
* adapter - A pointer to our adapter structure
* Event - Receive event
*
- * Return
- * skb
+ * Return - skb
*/
-static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EVENT *Event)
+static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter,
+ struct sxg_event *Event)
{
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
+ u32 BufferSize = adapter->ReceiveBufferSize;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
struct sk_buff *Packet;
+ static int read_counter = 0;
- RcvDataBufferHdr = (struct SXG_RCV_DATA_BUFFER_HDR*) Event->HostHandle;
+ RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *) Event->HostHandle;
+ if(read_counter++ & 0x100)
+ {
+ sxg_collect_statistics(adapter);
+ read_counter = 0;
+ }
ASSERT(RcvDataBufferHdr);
ASSERT(RcvDataBufferHdr->State == SXG_BUFFER_ONCARD);
- ASSERT(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr) ==
- RcvDataBufferHdr->VirtualAddress);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "SlowRcv", Event,
RcvDataBufferHdr, RcvDataBufferHdr->State,
- RcvDataBufferHdr->VirtualAddress);
+ /*RcvDataBufferHdr->VirtualAddress*/ 0);
/* Drop rcv frames in non-running state */
switch (adapter->State) {
case SXG_STATE_RUNNING:
@@ -1385,14 +1791,16 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
goto drop;
}
+ /*
+ * memcpy(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+ * RcvDataBufferHdr->VirtualAddress, Event->Length);
+ */
+
/* Change buffer state to UPSTREAM */
RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
if (Event->Status & EVENT_STATUS_RCVERR) {
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvError",
Event, Event->Status, Event->HostHandle, 0);
- /* XXXTODO - Remove this print later */
- DBG_ERROR("SXG: Receive error %x\n", *(u32 *)
- SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr));
sxg_process_rcv_error(adapter, *(u32 *)
SXG_RECEIVE_DATA_LOCATION
(RcvDataBufferHdr));
@@ -1400,8 +1808,9 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
}
#if XXXTODO /* VLAN stuff */
/* If there's a VLAN tag, extract it and validate it */
- if (((struct ether_header*) (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->
- EtherType == ETHERTYPE_VLAN) {
+ if (((struct ether_header *)
+ (SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)))->EtherType
+ == ETHERTYPE_VLAN) {
if (SxgExtractVlanHeader(adapter, RcvDataBufferHdr, Event) !=
STATUS_SUCCESS) {
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY,
@@ -1412,33 +1821,41 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
}
}
#endif
- /* */
/* Dumb-nic frame. See if it passes our mac filter and update stats */
- /* */
- if (!sxg_mac_filter(adapter, (struct ether_header*)
- SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
- Event->Length)) {
+
+ if (!sxg_mac_filter(adapter,
+ (struct ether_header *)(SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr)),
+ Event->Length)) {
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RcvFiltr",
- Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
- Event->Length, 0);
- goto drop;
+ Event, SXG_RECEIVE_DATA_LOCATION(RcvDataBufferHdr),
+ Event->Length, 0);
+ goto drop;
}
Packet = RcvDataBufferHdr->SxgDumbRcvPacket;
+ SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
+ Packet->protocol = eth_type_trans(Packet, adapter->netdev);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumbRcv",
RcvDataBufferHdr, Packet, Event->Length, 0);
- /* */
/* Lastly adjust the receive packet length. */
- /* */
- SXG_ADJUST_RCV_PACKET(Packet, RcvDataBufferHdr, Event);
-
+ RcvDataBufferHdr->SxgDumbRcvPacket = NULL;
+ RcvDataBufferHdr->PhysicalAddress = (dma_addr_t)NULL;
+ SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
+ if (RcvDataBufferHdr->skb)
+ {
+ spin_lock(&adapter->RcvQLock);
+ SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+ // adapter->RcvBuffersOnCard ++;
+ spin_unlock(&adapter->RcvQLock);
+ }
return (Packet);
drop:
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DropRcv",
RcvDataBufferHdr, Event->Length, 0, 0);
- adapter->Stats.RcvDiscards++;
+ adapter->stats.rx_dropped++;
+// adapter->Stats.RcvDiscards++;
spin_lock(&adapter->RcvQLock);
SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
spin_unlock(&adapter->RcvQLock);
@@ -1453,14 +1870,13 @@ static struct sk_buff *sxg_slow_receive(struct adapter_t *adapter, struct SXG_EV
* adapter - Adapter structure
* ErrorStatus - 4-byte receive error status
*
- * Return Value:
- * None
+ * Return Value : None
*/
static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus)
{
u32 Error;
- adapter->Stats.RcvErrors++;
+ adapter->stats.rx_errors++;
if (ErrorStatus & SXG_RCV_STATUS_TRANSPORT_ERROR) {
Error = ErrorStatus & SXG_RCV_STATUS_TRANSPORT_MASK;
@@ -1532,13 +1948,13 @@ static void sxg_process_rcv_error(struct adapter_t *adapter, u32 ErrorStatus)
* pether - Ethernet header
* length - Frame length
*
- * Return Value:
- * TRUE if the frame is to be allowed
+ * Return Value : TRUE if the frame is to be allowed
*/
-static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *EtherHdr,
- ushort length)
+static bool sxg_mac_filter(struct adapter_t *adapter,
+ struct ether_header *EtherHdr, ushort length)
{
bool EqualAddr;
+ struct net_device *dev = adapter->netdev;
if (SXG_MULTICAST_PACKET(EtherHdr)) {
if (SXG_BROADCAST_PACKET(EtherHdr)) {
@@ -1546,8 +1962,6 @@ static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *Ether
if (adapter->MacFilter & MAC_BCAST) {
adapter->Stats.DumbRcvBcastPkts++;
adapter->Stats.DumbRcvBcastBytes += length;
- adapter->Stats.DumbRcvPkts++;
- adapter->Stats.DumbRcvBytes += length;
return (TRUE);
}
} else {
@@ -1555,15 +1969,12 @@ static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *Ether
if (adapter->MacFilter & MAC_ALLMCAST) {
adapter->Stats.DumbRcvMcastPkts++;
adapter->Stats.DumbRcvMcastBytes += length;
- adapter->Stats.DumbRcvPkts++;
- adapter->Stats.DumbRcvBytes += length;
return (TRUE);
}
if (adapter->MacFilter & MAC_MCAST) {
- struct SXG_MULTICAST_ADDRESS *MulticastAddrs =
- adapter->MulticastAddrs;
- while (MulticastAddrs) {
- ETHER_EQ_ADDR(MulticastAddrs->Address,
+ struct dev_mc_list *mclist = dev->mc_list;
+ while (mclist) {
+ ETHER_EQ_ADDR(mclist->da_addr,
EtherHdr->ether_dhost,
EqualAddr);
if (EqualAddr) {
@@ -1571,32 +1982,26 @@ static bool sxg_mac_filter(struct adapter_t *adapter, struct ether_header *Ether
DumbRcvMcastPkts++;
adapter->Stats.
DumbRcvMcastBytes += length;
- adapter->Stats.DumbRcvPkts++;
- adapter->Stats.DumbRcvBytes +=
- length;
return (TRUE);
}
- MulticastAddrs = MulticastAddrs->Next;
+ mclist = mclist->next;
}
}
}
} else if (adapter->MacFilter & MAC_DIRECTED) {
- /* Not broadcast or multicast. Must be directed at us or */
- /* the card is in promiscuous mode. Either way, consider it */
- /* ours if MAC_DIRECTED is set */
+ /*
+ * Not broadcast or multicast. Must be directed at us or
+ * the card is in promiscuous mode. Either way, consider it
+ * ours if MAC_DIRECTED is set
+ */
adapter->Stats.DumbRcvUcastPkts++;
adapter->Stats.DumbRcvUcastBytes += length;
- adapter->Stats.DumbRcvPkts++;
- adapter->Stats.DumbRcvBytes += length;
return (TRUE);
}
if (adapter->MacFilter & MAC_PROMISC) {
/* Whatever it is, keep it. */
- adapter->Stats.DumbRcvPkts++;
- adapter->Stats.DumbRcvBytes += length;
return (TRUE);
}
- adapter->Stats.RcvDiscards++;
return (FALSE);
}
@@ -1627,7 +2032,6 @@ static int sxg_register_interrupt(struct adapter_t *adapter)
adapter->intrregistered = 1;
adapter->IntRegistered = TRUE;
/* Disable RSS with line-based interrupts */
- adapter->MsiEnabled = FALSE;
adapter->RssEnabled = FALSE;
DBG_ERROR("sxg: %s AllocAdaptRsrcs adapter[%p] dev->irq[%x]\n",
__func__, adapter, adapter->netdev->irq);
@@ -1663,12 +2067,12 @@ static void sxg_deregister_interrupt(struct adapter_t *adapter)
*/
static int sxg_if_init(struct adapter_t *adapter)
{
- p_net_device dev = adapter->netdev;
+ struct net_device *dev = adapter->netdev;
int status = 0;
- DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d:%d] flags[%x]\n",
+ DBG_ERROR("sxg: %s (%s) ENTER states[%d:%d] flags[%x]\n",
__func__, adapter->netdev->name,
- adapter->queues_initialized, adapter->state,
+ adapter->state,
adapter->linkstate, dev->flags);
/* adapter should be down at this point */
@@ -1679,31 +2083,31 @@ static int sxg_if_init(struct adapter_t *adapter)
ASSERT(adapter->linkstate == LINK_DOWN);
adapter->devflags_prev = dev->flags;
- adapter->macopts = MAC_DIRECTED;
+ adapter->MacFilter = MAC_DIRECTED;
if (dev->flags) {
DBG_ERROR("sxg: %s (%s) Set MAC options: ", __func__,
adapter->netdev->name);
if (dev->flags & IFF_BROADCAST) {
- adapter->macopts |= MAC_BCAST;
+ adapter->MacFilter |= MAC_BCAST;
DBG_ERROR("BCAST ");
}
if (dev->flags & IFF_PROMISC) {
- adapter->macopts |= MAC_PROMISC;
+ adapter->MacFilter |= MAC_PROMISC;
DBG_ERROR("PROMISC ");
}
if (dev->flags & IFF_ALLMULTI) {
- adapter->macopts |= MAC_ALLMCAST;
+ adapter->MacFilter |= MAC_ALLMCAST;
DBG_ERROR("ALL_MCAST ");
}
if (dev->flags & IFF_MULTICAST) {
- adapter->macopts |= MAC_MCAST;
+ adapter->MacFilter |= MAC_MCAST;
DBG_ERROR("MCAST ");
}
DBG_ERROR("\n");
}
- status = sxg_register_interrupt(adapter);
+ status = sxg_register_intr(adapter);
if (status != STATUS_SUCCESS) {
- DBG_ERROR("sxg_if_init: sxg_register_interrupt FAILED %x\n",
+ DBG_ERROR("sxg_if_init: sxg_register_intr FAILED %x\n",
status);
sxg_deregister_interrupt(adapter);
return (status);
@@ -1711,18 +2115,90 @@ static int sxg_if_init(struct adapter_t *adapter)
adapter->state = ADAPT_UP;
- /*
- * clear any pending events, then enable interrupts
- */
+ /* clear any pending events, then enable interrupts */
DBG_ERROR("sxg: %s ENABLE interrupts(slic)\n", __func__);
return (STATUS_SUCCESS);
}
-static int sxg_entry_open(p_net_device dev)
+void sxg_set_interrupt_aggregation(struct adapter_t *adapter)
+{
+ /*
+ * Top bit disables aggregation on xmt (SXG_AGG_XMT_DISABLE).
+ * Make sure Max is less than 0x8000.
+ */
+ adapter->max_aggregation = SXG_MAX_AGG_DEFAULT;
+ adapter->min_aggregation = SXG_MIN_AGG_DEFAULT;
+ WRITE_REG(adapter->UcodeRegs[0].Aggregation,
+ ((adapter->max_aggregation << SXG_MAX_AGG_SHIFT) |
+ adapter->min_aggregation),
+ TRUE);
+}
+
+static int sxg_entry_open(struct net_device *dev)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
int status;
+ static int turn;
+ int sxg_initial_rcv_data_buffers = SXG_INITIAL_RCV_DATA_BUFFERS;
+ int i;
+
+ if (adapter->JumboEnabled == TRUE) {
+ sxg_initial_rcv_data_buffers =
+ SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS;
+ SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo,
+ SXG_JUMBO_RCV_RING_SIZE);
+ }
+
+ /*
+ * Allocate receive data buffers. We allocate a block of buffers and
+ * a corresponding descriptor block at once. See sxghw.h:SXG_RCV_BLOCK
+ */
+
+ for (i = 0; i < sxg_initial_rcv_data_buffers;
+ i += SXG_RCV_DESCRIPTORS_PER_BLOCK)
+ {
+ status = sxg_allocate_buffer_memory(adapter,
+ SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE),
+ SXG_BUFFER_TYPE_RCV);
+ if (status != STATUS_SUCCESS)
+ return status;
+ }
+ /*
+ * NBL resource allocation can fail in the 'AllocateComplete' routine,
+ * which doesn't return status. Make sure we got the number of buffers
+ * we requested
+ */
+
+ if (adapter->FreeRcvBufferCount < sxg_initial_rcv_data_buffers) {
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAResF6",
+ adapter, adapter->FreeRcvBufferCount, SXG_MAX_ENTRIES,
+ 0);
+ return (STATUS_RESOURCES);
+ }
+ /*
+ * The microcode expects it to be downloaded on every open.
+ */
+ DBG_ERROR("sxg: %s ENTER sxg_download_microcode\n", __FUNCTION__);
+ if (sxg_download_microcode(adapter, SXG_UCODE_SYSTEM)) {
+ DBG_ERROR("sxg: %s ENTER sxg_adapter_set_hwaddr\n",
+ __FUNCTION__);
+ sxg_read_config(adapter);
+ } else {
+ adapter->state = ADAPT_FAIL;
+ adapter->linkstate = LINK_DOWN;
+ DBG_ERROR("sxg_download_microcode FAILED status[%x]\n",
+ status);
+ }
+ msleep(5);
+
+ if (turn) {
+ sxg_second_open(adapter->netdev);
+
+ return STATUS_SUCCESS;
+ }
+
+ turn++;
ASSERT(adapter);
DBG_ERROR("sxg: %s adapter->activated[%d]\n", __func__,
@@ -1762,6 +2238,8 @@ static int sxg_entry_open(p_net_device dev)
return (status);
}
DBG_ERROR("sxg: %s ENABLE ALL INTERRUPTS\n", __func__);
+ sxg_set_interrupt_aggregation(adapter);
+ napi_enable(&adapter->napi);
/* Enable interrupts */
SXG_ENABLE_ALL_INTERRUPTS(adapter);
@@ -1772,71 +2250,162 @@ static int sxg_entry_open(p_net_device dev)
return STATUS_SUCCESS;
}
+int sxg_second_open(struct net_device * dev)
+{
+ struct adapter_t *adapter = (struct adapter_t*) netdev_priv(dev);
+ int status = 0;
+
+ spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
+ netif_start_queue(adapter->netdev);
+ adapter->state = ADAPT_UP;
+ adapter->linkstate = LINK_UP;
+
+ status = sxg_initialize_adapter(adapter);
+ sxg_set_interrupt_aggregation(adapter);
+ napi_enable(&adapter->napi);
+ /* Re-enable interrupts */
+ SXG_ENABLE_ALL_INTERRUPTS(adapter);
+
+ sxg_register_intr(adapter);
+ spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ mod_timer(&adapter->watchdog_timer, jiffies);
+ return (STATUS_SUCCESS);
+
+}
+
static void __devexit sxg_entry_remove(struct pci_dev *pcidev)
{
- p_net_device dev = pci_get_drvdata(pcidev);
- u32 mmio_start = 0;
- unsigned int mmio_len = 0;
+ u32 mmio_start = 0;
+ u32 mmio_len = 0;
+
+ struct net_device *dev = pci_get_drvdata(pcidev);
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
- ASSERT(adapter);
- DBG_ERROR("sxg: %s ENTER dev[%p] adapter[%p]\n", __func__, dev,
- adapter);
- sxg_deregister_interrupt(adapter);
- sxg_unmap_mmio_space(adapter);
- DBG_ERROR("sxg: %s unregister_netdev\n", __func__);
+ flush_scheduled_work();
+
+ /* Deallocate Resources */
unregister_netdev(dev);
+ sxg_reset_interrupt_capability(adapter);
+ sxg_free_resources(adapter);
- mmio_start = pci_resource_start(pcidev, 0);
- mmio_len = pci_resource_len(pcidev, 0);
+ ASSERT(adapter);
- DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __func__,
- mmio_start, mmio_len);
- release_mem_region(mmio_start, mmio_len);
+ mmio_start = pci_resource_start(pcidev, 0);
+ mmio_len = pci_resource_len(pcidev, 0);
- DBG_ERROR("sxg: %s iounmap dev->base_addr[%x]\n", __func__,
- (unsigned int)dev->base_addr);
- iounmap((char *)dev->base_addr);
+ DBG_ERROR("sxg: %s rel_region(0) start[%x] len[%x]\n", __FUNCTION__,
+ mmio_start, mmio_len);
+ release_mem_region(mmio_start, mmio_len);
+
+ mmio_start = pci_resource_start(pcidev, 2);
+ mmio_len = pci_resource_len(pcidev, 2);
+
+ DBG_ERROR("sxg: %s rel_region(2) start[%x] len[%x]\n", __FUNCTION__,
+ mmio_start, mmio_len);
+ release_mem_region(mmio_start, mmio_len);
+
+ pci_disable_device(pcidev);
DBG_ERROR("sxg: %s deallocate device\n", __func__);
kfree(dev);
DBG_ERROR("sxg: %s EXIT\n", __func__);
}
-static int sxg_entry_halt(p_net_device dev)
+static int sxg_entry_halt(struct net_device *dev)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ int i;
+ u32 RssIds, IsrCount;
+ unsigned long flags;
+ RssIds = SXG_RSS_CPU_COUNT(adapter);
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
+ /* Disable interrupts */
spin_lock_irqsave(&sxg_global.driver_lock, sxg_global.flags);
- DBG_ERROR("sxg: %s (%s) ENTER\n", __func__, dev->name);
-
- netif_stop_queue(adapter->netdev);
+ SXG_DISABLE_ALL_INTERRUPTS(adapter);
adapter->state = ADAPT_DOWN;
adapter->linkstate = LINK_DOWN;
+
+ spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ sxg_deregister_interrupt(adapter);
+ WRITE_REG(HwRegs->Reset, 0xDEAD, FLUSH);
+ mdelay(5000);
+
+ del_timer_sync(&adapter->watchdog_timer);
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
+
+ napi_disable(&adapter->napi);
+
+ WRITE_REG(adapter->UcodeRegs[0].RcvCmd, 0, true);
adapter->devflags_prev = 0;
DBG_ERROR("sxg: %s (%s) set adapter[%p] state to ADAPT_DOWN(%d)\n",
__func__, dev->name, adapter, adapter->state);
- DBG_ERROR("sxg: %s (%s) EXIT\n", __func__, dev->name);
- DBG_ERROR("sxg: %s EXIT\n", __func__);
- spin_unlock_irqrestore(&sxg_global.driver_lock, sxg_global.flags);
+ spin_lock(&adapter->RcvQLock);
+ /* Free all the blocks and the buffers, moved from remove() routine */
+ if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
+ sxg_free_rcvblocks(adapter);
+ }
+
+
+ InitializeListHead(&adapter->FreeRcvBuffers);
+ InitializeListHead(&adapter->FreeRcvBlocks);
+ InitializeListHead(&adapter->AllRcvBlocks);
+ InitializeListHead(&adapter->FreeSglBuffers);
+ InitializeListHead(&adapter->AllSglBuffers);
+
+ adapter->FreeRcvBufferCount = 0;
+ adapter->FreeRcvBlockCount = 0;
+ adapter->AllRcvBlockCount = 0;
+ adapter->RcvBuffersOnCard = 0;
+ adapter->PendingRcvCount = 0;
+
+ memset(adapter->RcvRings, 0, sizeof(struct sxg_rcv_ring) * 1);
+ memset(adapter->EventRings, 0, sizeof(struct sxg_event_ring) * RssIds);
+ memset(adapter->Isr, 0, sizeof(u32) * IsrCount);
+ for (i = 0; i < SXG_MAX_RING_SIZE; i++)
+ adapter->RcvRingZeroInfo.Context[i] = NULL;
+ SXG_INITIALIZE_RING(adapter->RcvRingZeroInfo, SXG_RCV_RING_SIZE);
+ SXG_INITIALIZE_RING(adapter->XmtRingZeroInfo, SXG_XMT_RING_SIZE);
+
+ spin_unlock(&adapter->RcvQLock);
+
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
+ adapter->AllSglBufferCount = 0;
+ adapter->FreeSglBufferCount = 0;
+ adapter->PendingXmtCount = 0;
+ memset(adapter->XmtRings, 0, sizeof(struct sxg_xmt_ring) * 1);
+ memset(adapter->XmtRingZeroIndex, 0, sizeof(u32));
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
+
+ for (i = 0; i < SXG_MAX_RSS; i++) {
+ adapter->NextEvent[i] = 0;
+ }
+ atomic_set(&adapter->pending_allocations, 0);
+ adapter->intrregistered = 0;
+ sxg_remove_isr(adapter);
+ DBG_ERROR("sxg: %s (%s) EXIT\n", __FUNCTION__, dev->name);
return (STATUS_SUCCESS);
}
-static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
+static int sxg_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
ASSERT(rq);
-/* DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev); */
+/* DBG_ERROR("sxg: %s cmd[%x] rq[%p] dev[%p]\n", __func__, cmd, rq, dev);*/
switch (cmd) {
case SIOCSLICSETINTAGG:
{
-/* struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev); */
+ /* struct adapter_t *adapter = (struct adapter_t *)
+ * netdev_priv(dev);
+ */
u32 data[7];
u32 intagg;
if (copy_from_user(data, rq->ifr_data, 28)) {
- DBG_ERROR
- ("copy_from_user FAILED getting initial params\n");
+ DBG_ERROR("copy_from_user FAILED getting \
+ initial params\n");
return -EFAULT;
}
intagg = data[0];
@@ -1847,7 +2416,7 @@ static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
}
default:
-/* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
+ /* DBG_ERROR("sxg: %s UNSUPPORTED[%x]\n", __func__, cmd); */
return -EOPNOTSUPP;
}
return 0;
@@ -1856,23 +2425,25 @@ static int sxg_ioctl(p_net_device dev, struct ifreq *rq, int cmd)
#define NORMAL_ETHFRAME 0
/*
- *
* sxg_send_packets - Send a skb packet
*
* Arguments:
- * skb - The packet to send
- * dev - Our linux net device that refs our adapter
+ * skb - The packet to send
+ * dev - Our linux net device that refs our adapter
*
* Return:
* 0 regardless of outcome XXXTODO refer to e1000 driver
*/
-static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
+static int sxg_send_packets(struct sk_buff *skb, struct net_device *dev)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
u32 status = STATUS_SUCCESS;
- DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __func__,
- skb);
+ /*
+ * DBG_ERROR("sxg: %s ENTER sxg_send_packets skb[%p]\n", __FUNCTION__,
+ * skb);
+ */
+
/* Check the adapter state */
switch (adapter->State) {
case SXG_STATE_INITIALIZING:
@@ -1909,17 +2480,18 @@ static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
/* reject & complete all the packets if they cant be sent */
if (status != STATUS_SUCCESS) {
#if XXXTODO
-/* sxg_send_packets_fail(adapter, skb, status); */
+ /* sxg_send_packets_fail(adapter, skb, status); */
#else
SXG_DROP_DUMB_SEND(adapter, skb);
adapter->stats.tx_dropped++;
+ return NETDEV_TX_BUSY;
#endif
}
DBG_ERROR("sxg: %s EXIT sxg_send_packets status[%x]\n", __func__,
status);
xmit_done:
- return 0;
+ return NETDEV_TX_OK;
}
/*
@@ -1931,33 +2503,35 @@ static int sxg_send_packets(struct sk_buff *skb, p_net_device dev)
* adapter - Pointer to our adapter structure
* skb - The packet to be sent
*
- * Return -
- * STATUS of send
+ * Return - STATUS of send
*/
static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
{
- struct SCATTER_GATHER_LIST *pSgl;
- struct SXG_SCATTER_GATHER *SxgSgl;
- void *SglBuffer;
- u32 SglBufferLength;
+ struct sxg_x64_sgl *pSgl;
+ struct sxg_scatter_gather *SxgSgl;
+ unsigned long sgl_flags;
+ /* void *SglBuffer; */
+ /* u32 SglBufferLength; */
- /* The vast majority of work is done in the shared */
- /* sxg_dumb_sgl routine. */
+ /*
+ * The vast majority of work is done in the shared
+ * sxg_dumb_sgl routine.
+ */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSend",
adapter, skb, 0, 0);
/* Allocate a SGL buffer */
- SXG_GET_SGL_BUFFER(adapter, SxgSgl);
+ SXG_GET_SGL_BUFFER(adapter, SxgSgl, 0);
if (!SxgSgl) {
adapter->Stats.NoSglBuf++;
- adapter->Stats.XmtErrors++;
+ adapter->stats.tx_errors++;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "SndPktF1",
adapter, skb, 0, 0);
return (STATUS_RESOURCES);
}
ASSERT(SxgSgl->adapter == adapter);
- SglBuffer = SXG_SGL_BUFFER(SxgSgl);
- SglBufferLength = SXG_SGL_BUF_SIZE;
+ /*SglBuffer = SXG_SGL_BUFFER(SxgSgl);
+ SglBufferLength = SXG_SGL_BUF_SIZE; */
SxgSgl->VlanTag.VlanTci = 0;
SxgSgl->VlanTag.VlanTpid = 0;
SxgSgl->Type = SXG_SGL_DUMB;
@@ -1965,9 +2539,7 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
pSgl = NULL;
/* Call the common sxg_dumb_sgl routine to complete the send. */
- sxg_dumb_sgl(pSgl, SxgSgl);
- /* Return success sxg_dumb_sgl (or something later) will complete it. */
- return (STATUS_SUCCESS);
+ return (sxg_dumb_sgl(pSgl, SxgSgl));
}
/*
@@ -1975,24 +2547,27 @@ static int sxg_transmit_packet(struct adapter_t *adapter, struct sk_buff *skb)
*
* Arguments:
* pSgl -
- * SxgSgl - SXG_SCATTER_GATHER
+ * SxgSgl - struct sxg_scatter_gather
*
* Return Value:
- * None.
+ * Status of send operation.
*/
-static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GATHER *SxgSgl)
+static int sxg_dumb_sgl(struct sxg_x64_sgl *pSgl,
+ struct sxg_scatter_gather *SxgSgl)
{
struct adapter_t *adapter = SxgSgl->adapter;
struct sk_buff *skb = SxgSgl->DumbPacket;
/* For now, all dumb-nic sends go on RSS queue zero */
- struct SXG_XMT_RING *XmtRing = &adapter->XmtRings[0];
- struct SXG_RING_INFO *XmtRingInfo = &adapter->XmtRingZeroInfo;
- struct SXG_CMD *XmtCmd = NULL;
-/* u32 Index = 0; */
+ struct sxg_xmt_ring *XmtRing = &adapter->XmtRings[0];
+ struct sxg_ring_info *XmtRingInfo = &adapter->XmtRingZeroInfo;
+ struct sxg_cmd *XmtCmd = NULL;
+ /* u32 Index = 0; */
u32 DataLength = skb->len;
-/* unsigned int BufLen; */
-/* u32 SglOffset; */
+ /* unsigned int BufLen; */
+ /* u32 SglOffset; */
u64 phys_addr;
+ unsigned long flags;
+ unsigned long queue_id=0;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbSgl",
pSgl, SxgSgl, 0, 0);
@@ -2001,25 +2576,67 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
SxgSgl->pSgl = pSgl;
/* Sanity check that our SGL format is as we expect. */
- ASSERT(sizeof(SXG_X64_SGE) == sizeof(SCATTER_GATHER_ELEMENT));
+ ASSERT(sizeof(struct sxg_x64_sge) == sizeof(struct sxg_x64_sge));
/* Shouldn't be a vlan tag on this frame */
ASSERT(SxgSgl->VlanTag.VlanTci == 0);
ASSERT(SxgSgl->VlanTag.VlanTpid == 0);
- /* From here below we work with the SGL placed in our */
- /* buffer. */
+ /*
+ * From here below we work with the SGL placed in our
+ * buffer.
+ */
SxgSgl->Sgl.NumberOfElements = 1;
+ /*
+ * Set ucode Queue ID based on bottom bits of destination TCP port.
+ * This Queue ID splits slowpath/dumb-nic packet processing across
+ * multiple threads on the card to improve performance. It is split
+ * using the TCP port to avoid out-of-order packets that can result
+ * from multithreaded processing. We use the destination port because
+ * we expect to be run on a server, so in nearly all cases the local
+ * port is likely to be constant (well-known server port) and the
+ * remote port is likely to be random. The exception to this is iSCSI,
+ * in which case we use the sport instead. Note
+ * that original attempt at XOR'ing source and dest port resulted in
+ * poor balance on NTTTCP/iometer applications since they tend to
+ * line up (even-even, odd-odd..).
+ */
+
+ if (skb->protocol == htons(ETH_P_IP)) {
+ struct iphdr *ip;
+
+ ip = ip_hdr(skb);
+ if ((ip->protocol == IPPROTO_TCP)&&(DataLength >= sizeof(
+ struct tcphdr))){
+ queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
+ (ntohs (tcp_hdr(skb)->source) &
+ SXG_LARGE_SEND_QUEUE_MASK):
+ (ntohs(tcp_hdr(skb)->dest) &
+ SXG_LARGE_SEND_QUEUE_MASK));
+ }
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
+ if ((ipv6_hdr(skb)->nexthdr == IPPROTO_TCP) && (DataLength >=
+ sizeof(struct tcphdr)) ) {
+ queue_id = ((ntohs(tcp_hdr(skb)->dest) == ISCSI_PORT) ?
+ (ntohs (tcp_hdr(skb)->source) &
+ SXG_LARGE_SEND_QUEUE_MASK):
+ (ntohs(tcp_hdr(skb)->dest) &
+ SXG_LARGE_SEND_QUEUE_MASK));
+ }
+ }
/* Grab the spinlock and acquire a command */
- spin_lock(&adapter->XmtZeroLock);
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
if (XmtCmd == NULL) {
- /* Call sxg_complete_slow_send to see if we can */
- /* free up any XmtRingZero entries and then try again */
- spin_unlock(&adapter->XmtZeroLock);
+ /*
+ * Call sxg_complete_slow_send to see if we can
+ * free up any XmtRingZero entries and then try again
+ */
+
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
sxg_complete_slow_send(adapter);
- spin_lock(&adapter->XmtZeroLock);
+ spin_lock_irqsave(&adapter->XmtZeroLock, flags);
SXG_GET_CMD(XmtRing, XmtRingInfo, XmtCmd, SxgSgl);
if (XmtCmd == NULL) {
adapter->Stats.XmtZeroFull++;
@@ -2029,8 +2646,8 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbCmd",
XmtCmd, XmtRingInfo->Head, XmtRingInfo->Tail, 0);
/* Update stats */
- adapter->Stats.DumbXmtPkts++;
- adapter->Stats.DumbXmtBytes += DataLength;
+ adapter->stats.tx_packets++;
+ adapter->stats.tx_bytes += DataLength;
#if XXXTODO /* Stats stuff */
if (SXG_MULTICAST_PACKET(EtherHdr)) {
if (SXG_BROADCAST_PACKET(EtherHdr)) {
@@ -2045,70 +2662,92 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
adapter->Stats.DumbXmtUcastBytes += DataLength;
}
#endif
- /* Fill in the command */
- /* Copy out the first SGE to the command and adjust for offset */
- phys_addr =
- pci_map_single(adapter->pcidev, skb->data, skb->len,
+ /*
+ * Fill in the command
+ * Copy out the first SGE to the command and adjust for offset
+ */
+ phys_addr = pci_map_single(adapter->pcidev, skb->data, skb->len,
PCI_DMA_TODEVICE);
- XmtCmd->Buffer.FirstSgeAddress = SXG_GET_ADDR_HIGH(phys_addr);
- XmtCmd->Buffer.FirstSgeAddress = XmtCmd->Buffer.FirstSgeAddress << 32;
- XmtCmd->Buffer.FirstSgeAddress =
- XmtCmd->Buffer.FirstSgeAddress | SXG_GET_ADDR_LOW(phys_addr);
-/* XmtCmd->Buffer.FirstSgeAddress = SxgSgl->Sgl.Elements[Index].Address; */
-/* XmtCmd->Buffer.FirstSgeAddress.LowPart += MdlOffset; */
+
+ /*
+ * SAHARA SGL WORKAROUND
+ * See if the SGL straddles a 64k boundary. If so, skip to
+ * the start of the next 64k boundary and continue
+ */
+
+ if ((adapter->asictype == SAHARA_REV_A) &&
+ (SXG_INVALID_SGL(phys_addr,skb->data_len)))
+ {
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
+ /* Silently drop this packet */
+ printk(KERN_EMERG"Dropped a packet for 64k boundary problem\n");
+ return STATUS_SUCCESS;
+ }
+ memset(XmtCmd, '\0', sizeof(*XmtCmd));
+ XmtCmd->Buffer.FirstSgeAddress = phys_addr;
XmtCmd->Buffer.FirstSgeLength = DataLength;
- /* Set a pointer to the remaining SGL entries */
-/* XmtCmd->Sgl = SxgSgl->PhysicalAddress; */
- /* Advance the physical address of the SxgSgl structure to */
- /* the second SGE */
-/* SglOffset = (u32)((u32 *)(&SxgSgl->Sgl.Elements[Index+1]) - */
-/* (u32 *)SxgSgl); */
-/* XmtCmd->Sgl.LowPart += SglOffset; */
XmtCmd->Buffer.SgeOffset = 0;
- /* Note - TotalLength might be overwritten with MSS below.. */
XmtCmd->Buffer.TotalLength = DataLength;
- XmtCmd->SgEntries = 1; /*(ushort)(SxgSgl->Sgl.NumberOfElements - Index); */
+ XmtCmd->SgEntries = 1;
XmtCmd->Flags = 0;
- /* */
- /* Advance transmit cmd descripter by 1. */
- /* NOTE - See comments in SxgTcpOutput where we write */
- /* to the XmtCmd register regarding CPU ID values and/or */
- /* multiple commands. */
- /* */
- /* */
- WRITE_REG(adapter->UcodeRegs[0].XmtCmd, 1, TRUE);
- /* */
- /* */
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ /*
+ * We need to set the Checkum in IP header to 0. This is
+ * required by hardware.
+ */
+ ip_hdr(skb)->check = 0x0;
+ XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_IP;
+ XmtCmd->CsumFlags.Flags |= SXG_SLOWCMD_CSUM_TCP;
+ /* Dont know if length will require a change in case of VLAN */
+ XmtCmd->CsumFlags.MacLen = ETH_HLEN;
+ XmtCmd->CsumFlags.IpHl = skb_network_header_len(skb) >>
+ SXG_NW_HDR_LEN_SHIFT;
+ }
+ /*
+ * Advance transmit cmd descripter by 1.
+ * NOTE - See comments in SxgTcpOutput where we write
+ * to the XmtCmd register regarding CPU ID values and/or
+ * multiple commands.
+ * Top 16 bits specify queue_id. See comments about queue_id above
+ */
+ /* Four queues at the moment */
+ ASSERT((queue_id & ~SXG_LARGE_SEND_QUEUE_MASK) == 0);
+ WRITE_REG(adapter->UcodeRegs[0].XmtCmd, ((queue_id << 16) | 1), TRUE);
adapter->Stats.XmtQLen++; /* Stats within lock */
- spin_unlock(&adapter->XmtZeroLock);
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XDumSgl2",
XmtCmd, pSgl, SxgSgl, 0);
- return;
+ return STATUS_SUCCESS;
abortcmd:
- /* NOTE - Only jump to this label AFTER grabbing the */
- /* XmtZeroLock, and DO NOT DROP IT between the */
- /* command allocation and the following abort. */
+ /*
+ * NOTE - Only jump to this label AFTER grabbing the
+ * XmtZeroLock, and DO NOT DROP IT between the
+ * command allocation and the following abort.
+ */
if (XmtCmd) {
SXG_ABORT_CMD(XmtRingInfo);
}
- spin_unlock(&adapter->XmtZeroLock);
+ spin_unlock_irqrestore(&adapter->XmtZeroLock, flags);
-/* failsgl: */
- /* Jump to this label if failure occurs before the */
- /* XmtZeroLock is grabbed */
- adapter->Stats.XmtErrors++;
+/*
+ * failsgl:
+ * Jump to this label if failure occurs before the
+ * XmtZeroLock is grabbed
+ */
+ adapter->stats.tx_errors++;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "DumSGFal",
pSgl, SxgSgl, XmtRingInfo->Head, XmtRingInfo->Tail);
+ /* SxgSgl->DumbPacket is the skb */
+ // SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket);
- SXG_COMPLETE_DUMB_SEND(adapter, SxgSgl->DumbPacket); /* SxgSgl->DumbPacket is the skb */
+ return STATUS_FAILURE;
}
-/***************************************************************
- * Link management functions
- ***************************************************************/
-
/*
+ * Link management functions
+ *
* sxg_initialize_link - Initialize the link stuff
*
* Arguments -
@@ -2119,10 +2758,11 @@ static void sxg_dumb_sgl(struct SCATTER_GATHER_LIST *pSgl, struct SXG_SCATTER_GA
*/
static int sxg_initialize_link(struct adapter_t *adapter)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
u32 Value;
u32 ConfigData;
u32 MaxFrame;
+ u32 AxgMacReg1;
int status;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitLink",
@@ -2140,15 +2780,17 @@ static int sxg_initialize_link(struct adapter_t *adapter)
/* Reset all MAC modules */
WRITE_REG(HwRegs->MacConfig0, AXGMAC_CFG0_SUB_RESET, TRUE);
- /* Link address 0 */
- /* XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f) */
- /* is stored with the first nibble (0a) in the byte 0 */
- /* of the Mac address. Possibly reverse? */
- Value = *(u32 *) adapter->MacAddr;
+ /*
+ * Link address 0
+ * XXXTODO - This assumes the MAC address (0a:0b:0c:0d:0e:0f)
+ * is stored with the first nibble (0a) in the byte 0
+ * of the Mac address. Possibly reverse?
+ */
+ Value = *(u32 *) adapter->macaddr;
WRITE_REG(HwRegs->LinkAddress0Low, Value, TRUE);
/* also write the MAC address to the MAC. Endian is reversed. */
WRITE_REG(HwRegs->MacAddressLow, ntohl(Value), TRUE);
- Value = (*(u16 *) & adapter->MacAddr[4] & 0x0000FFFF);
+ Value = (*(u16 *) & adapter->macaddr[4] & 0x0000FFFF);
WRITE_REG(HwRegs->LinkAddress0High, Value | LINK_ADDRESS_ENABLE, TRUE);
/* endian swap for the MAC (put high bytes in bits [31:16], swapped) */
Value = ntohl(Value);
@@ -2167,47 +2809,76 @@ static int sxg_initialize_link(struct adapter_t *adapter)
WRITE_REG(HwRegs->MacConfig0, 0, TRUE);
/* Configure MAC */
- WRITE_REG(HwRegs->MacConfig1, (AXGMAC_CFG1_XMT_PAUSE | /* Allow sending of pause */
- AXGMAC_CFG1_XMT_EN | /* Enable XMT */
- AXGMAC_CFG1_RCV_PAUSE | /* Enable detection of pause */
- AXGMAC_CFG1_RCV_EN | /* Enable receive */
- AXGMAC_CFG1_SHORT_ASSERT | /* short frame detection */
- AXGMAC_CFG1_CHECK_LEN | /* Verify frame length */
- AXGMAC_CFG1_GEN_FCS | /* Generate FCS */
- AXGMAC_CFG1_PAD_64), /* Pad frames to 64 bytes */
- TRUE);
+ AxgMacReg1 = ( /* Enable XMT */
+ AXGMAC_CFG1_XMT_EN |
+ /* Enable receive */
+ AXGMAC_CFG1_RCV_EN |
+ /* short frame detection */
+ AXGMAC_CFG1_SHORT_ASSERT |
+ /* Verify frame length */
+ AXGMAC_CFG1_CHECK_LEN |
+ /* Generate FCS */
+ AXGMAC_CFG1_GEN_FCS |
+ /* Pad frames to 64 bytes */
+ AXGMAC_CFG1_PAD_64);
+
+ if (adapter->XmtFcEnabled) {
+ AxgMacReg1 |= AXGMAC_CFG1_XMT_PAUSE; /* Allow sending of pause */
+ }
+ if (adapter->RcvFcEnabled) {
+ AxgMacReg1 |= AXGMAC_CFG1_RCV_PAUSE; /* Enable detection of pause */
+ }
+
+ WRITE_REG(HwRegs->MacConfig1, AxgMacReg1, TRUE);
/* Set AXGMAC max frame length if jumbo. Not needed for standard MTU */
if (adapter->JumboEnabled) {
WRITE_REG(HwRegs->MacMaxFrameLen, AXGMAC_MAXFRAME_JUMBO, TRUE);
}
- /* AMIIM Configuration Register - */
- /* The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion */
- /* (bottom bits) of this register is used to determine the */
- /* MDC frequency as specified in the A-XGMAC Design Document. */
- /* This value must not be zero. The following value (62 or 0x3E) */
- /* is based on our MAC transmit clock frequency (MTCLK) of 312.5 MHz. */
- /* Given a maximum MDIO clock frequency of 2.5 MHz (see the PHY spec), */
- /* we get: 312.5/(2*(X+1)) < 2.5 ==> X = 62. */
- /* This value happens to be the default value for this register, */
- /* so we really don't have to do this. */
- WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
+ /*
+ * AMIIM Configuration Register -
+ * The value placed in the AXGMAC_AMIIM_CFG_HALF_CLOCK portion
+ * (bottom bits) of this register is used to determine the MDC frequency
+ * as specified in the A-XGMAC Design Document. This value must not be
+ * zero. The following value (62 or 0x3E) is based on our MAC transmit
+ * clock frequency (MTCLK) of 312.5 MHz. Given a maximum MDIO clock
+ * frequency of 2.5 MHz (see the PHY spec), we get:
+ * 312.5/(2*(X+1)) < 2.5 ==> X = 62.
+ * This value happens to be the default value for this register, so we
+ * really don't have to do this.
+ */
+ if (adapter->asictype == SAHARA_REV_B) {
+ WRITE_REG(HwRegs->MacAmiimConfig, 0x0000001F, TRUE);
+ } else {
+ WRITE_REG(HwRegs->MacAmiimConfig, 0x0000003E, TRUE);
+ }
/* Power up and enable PHY and XAUI/XGXS/Serdes logic */
WRITE_REG(HwRegs->LinkStatus,
- (LS_PHY_CLR_RESET |
- LS_XGXS_ENABLE |
- LS_XGXS_CTL | LS_PHY_CLK_EN | LS_ATTN_ALARM), TRUE);
+ (LS_PHY_CLR_RESET |
+ LS_XGXS_ENABLE |
+ LS_XGXS_CTL |
+ LS_PHY_CLK_EN |
+ LS_ATTN_ALARM),
+ TRUE);
DBG_ERROR("After Power Up and enable PHY in sxg_initialize_link\n");
- /* Per information given by Aeluros, wait 100 ms after removing reset. */
- /* It's not enough to wait for the self-clearing reset bit in reg 0 to clear. */
+ /*
+ * Per information given by Aeluros, wait 100 ms after removing reset.
+ * It's not enough to wait for the self-clearing reset bit in reg 0 to
+ * clear.
+ */
mdelay(100);
- /* Verify the PHY has come up by checking that the Reset bit has cleared. */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- PHY_PMA_CONTROL1, /* PMA/PMD control register */
- &Value);
+ /* Verify the PHY has come up by checking that the Reset bit has
+ * cleared.
+ */
+ status = sxg_read_mdio_reg(adapter,
+ MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
+ PHY_PMA_CONTROL1, /* PMA/PMD control register */
+ &Value);
+ DBG_ERROR("After sxg_read_mdio_reg Value[%x] fail=%x\n", Value,
+ (Value & PMA_CONTROL1_RESET));
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
if (Value & PMA_CONTROL1_RESET) /* reset complete if bit is 0 */
@@ -2228,16 +2899,26 @@ static int sxg_initialize_link(struct adapter_t *adapter)
return (STATUS_FAILURE);
/* Enable the Link Alarm */
- status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- LASI_CONTROL, /* LASI control register */
- LASI_CTL_LS_ALARM_ENABLE); /* enable link alarm bit */
+
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module
+ * LASI_CONTROL - LASI control register
+ * LASI_CTL_LS_ALARM_ENABLE - enable link alarm bit
+ */
+ status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ LASI_CONTROL,
+ LASI_CTL_LS_ALARM_ENABLE);
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
/* XXXTODO - temporary - verify bit is set */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- LASI_CONTROL, /* LASI control register */
+
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module
+ * LASI_CONTROL - LASI control register
+ */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ LASI_CONTROL,
&Value);
+
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
if (!(Value & LASI_CTL_LS_ALARM_ENABLE)) {
@@ -2253,6 +2934,11 @@ static int sxg_initialize_link(struct adapter_t *adapter)
RCV_CONFIG_TZIPV4 |
RCV_CONFIG_HASH_16 |
RCV_CONFIG_SOCKET | RCV_CONFIG_BUFSIZE(MaxFrame));
+
+ if (adapter->asictype == SAHARA_REV_B) {
+ ConfigData |= (RCV_CONFIG_HIPRICTL |
+ RCV_CONFIG_NEWSTATUSFMT);
+ }
WRITE_REG(HwRegs->RcvConfig, ConfigData, TRUE);
WRITE_REG(HwRegs->XmtConfig, XMT_CONFIG_ENABLE, TRUE);
@@ -2277,21 +2963,25 @@ static int sxg_initialize_link(struct adapter_t *adapter)
static int sxg_phy_init(struct adapter_t *adapter)
{
u32 Value;
- struct PHY_UCODE *p;
+ struct phy_ucode *p;
int status;
DBG_ERROR("ENTER %s\n", __func__);
- /* Read a register to identify the PHY type */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- 0xC205, /* PHY ID register (?) */
- &Value); /* XXXTODO - add def */
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module
+ * 0xC205 - PHY ID register (?)
+ * &Value - XXXTODO - add def
+ */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ 0xC205,
+ &Value);
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
- if (Value == 0x0012) { /* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */
- DBG_ERROR
- ("AEL2005C PHY detected. Downloading PHY microcode.\n");
+ if (Value == 0x0012) {
+ /* 0x0012 == AEL2005C PHY(?) - XXXTODO - add def */
+ DBG_ERROR("AEL2005C PHY detected. Downloading PHY \
+ microcode.\n");
/* Initialize AEL2005C PHY and download PHY microcode */
for (p = PhyUcode; p->Addr != 0xFFFF; p++) {
@@ -2299,10 +2989,13 @@ static int sxg_phy_init(struct adapter_t *adapter)
/* if address == 0, data == sleep time in ms */
mdelay(p->Data);
} else {
- /* write the given data to the specified address */
- status = sxg_write_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- p->Addr, /* PHY address */
- p->Data); /* PHY data */
+ /* write the given data to the specified address */
+ status = sxg_write_mdio_reg(adapter,
+ MIIM_DEV_PHY_PMA,
+ /* PHY address */
+ p->Addr,
+ /* PHY data */
+ p->Data);
if (status != STATUS_SUCCESS)
return (STATUS_FAILURE);
}
@@ -2324,11 +3017,14 @@ static int sxg_phy_init(struct adapter_t *adapter)
*/
static void sxg_link_event(struct adapter_t *adapter)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ struct net_device *netdev = adapter->netdev;
enum SXG_LINK_STATE LinkState;
int status;
u32 Value;
+ if (adapter->state == ADAPT_DOWN)
+ return;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "LinkEvnt",
adapter, 0, 0, 0);
DBG_ERROR("ENTER %s\n", __func__);
@@ -2336,35 +3032,57 @@ static void sxg_link_event(struct adapter_t *adapter)
/* Check the Link Status register. We should have a Link Alarm. */
READ_REG(HwRegs->LinkStatus, Value);
if (Value & LS_LINK_ALARM) {
- /* We got a Link Status alarm. First, pause to let the */
- /* link state settle (it can bounce a number of times) */
+ /*
+ * We got a Link Status alarm. First, pause to let the
+ * link state settle (it can bounce a number of times)
+ */
mdelay(10);
/* Now clear the alarm by reading the LASI status register. */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- LASI_STATUS, /* LASI status register */
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ /* LASI status register */
+ LASI_STATUS,
&Value);
if (status != STATUS_SUCCESS) {
DBG_ERROR("Error reading LASI Status MDIO register!\n");
sxg_link_state(adapter, SXG_LINK_DOWN);
-/* ASSERT(0); */
+ /* ASSERT(0); */
}
- ASSERT(Value & LASI_STATUS_LS_ALARM);
+ /*
+ * We used to assert that the LASI_LS_ALARM bit was set, as
+ * it should be. But there appears to be cases during
+ * initialization (when the PHY is reset and re-initialized)
+ * when we get a link alarm, but the status bit is 0 when we
+ * read it. Rather than trying to assure this never happens
+ * (and nver being certain), just ignore it.
+
+ * ASSERT(Value & LASI_STATUS_LS_ALARM);
+ */
/* Now get and set the link state */
LinkState = sxg_get_link_state(adapter);
sxg_link_state(adapter, LinkState);
DBG_ERROR("SXG: Link Alarm occurred. Link is %s\n",
((LinkState == SXG_LINK_UP) ? "UP" : "DOWN"));
+ if (LinkState == SXG_LINK_UP) {
+ netif_carrier_on(netdev);
+ netif_tx_start_all_queues(netdev);
+ } else {
+ netif_tx_stop_all_queues(netdev);
+ netif_carrier_off(netdev);
+ }
} else {
- /* XXXTODO - Assuming Link Attention is only being generated for the */
- /* Link Alarm pin (and not for a XAUI Link Status change), then it's */
- /* impossible to get here. Yet we've gotten here twice (under extreme */
- /* conditions - bouncing the link up and down many times a second). */
- /* Needs further investigation. */
+ /*
+ * XXXTODO - Assuming Link Attention is only being generated
+ * for the Link Alarm pin (and not for a XAUI Link Status change)
+ * , then it's impossible to get here. Yet we've gotten here
+ * twice (under extreme conditions - bouncing the link up and
+ * down many times a second). Needs further investigation.
+ */
DBG_ERROR("SXG: sxg_link_event: Can't get here!\n");
DBG_ERROR("SXG: Link Status == 0x%08X.\n", Value);
-/* ASSERT(0); */
+ /* ASSERT(0); */
}
DBG_ERROR("EXIT %s\n", __func__);
@@ -2389,10 +3107,15 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "GetLink",
adapter, 0, 0, 0);
- /* Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if */
- /* the following 3 bits (from 3 different MDIO registers) are all true. */
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA, /* PHY PMA/PMD module */
- PHY_PMA_RCV_DET, /* PMA/PMD Receive Signal Detect register */
+ /*
+ * Per the Xenpak spec (and the IEEE 10Gb spec?), the link is up if
+ * the following 3 bits (from 3 different MDIO registers) are all true.
+ */
+
+ /* MIIM_DEV_PHY_PMA - PHY PMA/PMD module */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PMA,
+ /* PMA/PMD Receive Signal Detect register */
+ PHY_PMA_RCV_DET,
&Value);
if (status != STATUS_SUCCESS)
goto bad;
@@ -2401,8 +3124,10 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
if (!(Value & PMA_RCV_DETECT))
return (SXG_LINK_DOWN);
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS, /* PHY PCS module */
- PHY_PCS_10G_STATUS1, /* PCS 10GBASE-R Status 1 register */
+ /* MIIM_DEV_PHY_PCS - PHY PCS module */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_PCS,
+ /* PCS 10GBASE-R Status 1 register */
+ PHY_PCS_10G_STATUS1,
&Value);
if (status != STATUS_SUCCESS)
goto bad;
@@ -2411,8 +3136,9 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
if (!(Value & PCS_10B_BLOCK_LOCK))
return (SXG_LINK_DOWN);
- status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS, /* PHY XS module */
- PHY_XS_LANE_STATUS, /* XS Lane Status register */
+ status = sxg_read_mdio_reg(adapter, MIIM_DEV_PHY_XS,/* PHY XS module */
+ /* XS Lane Status register */
+ PHY_XS_LANE_STATUS,
&Value);
if (status != STATUS_SUCCESS)
goto bad;
@@ -2427,7 +3153,7 @@ static enum SXG_LINK_STATE sxg_get_link_state(struct adapter_t *adapter)
return (SXG_LINK_UP);
bad:
- /* An error occurred reading an MDIO register. This shouldn't happen. */
+ /* An error occurred reading an MDIO register. This shouldn't happen. */
DBG_ERROR("Error reading an MDIO register!\n");
ASSERT(0);
return (SXG_LINK_DOWN);
@@ -2448,6 +3174,37 @@ static void sxg_indicate_link_state(struct adapter_t *adapter,
}
/*
+ * sxg_change_mtu - Change the Maximum Transfer Unit
+ * * @returns 0 on success, negative on failure
+ */
+int sxg_change_mtu (struct net_device *netdev, int new_mtu)
+{
+ struct adapter_t *adapter = (struct adapter_t *) netdev_priv(netdev);
+
+ if (!((new_mtu == SXG_DEFAULT_MTU) || (new_mtu == SXG_JUMBO_MTU)))
+ return -EINVAL;
+
+ if(new_mtu == netdev->mtu)
+ return 0;
+
+ netdev->mtu = new_mtu;
+
+ if (new_mtu == SXG_JUMBO_MTU) {
+ adapter->JumboEnabled = TRUE;
+ adapter->FrameSize = JUMBOMAXFRAME;
+ adapter->ReceiveBufferSize = SXG_RCV_JUMBO_BUFFER_SIZE;
+ } else {
+ adapter->JumboEnabled = FALSE;
+ adapter->FrameSize = ETHERMAXFRAME;
+ adapter->ReceiveBufferSize = SXG_RCV_DATA_BUFFER_SIZE;
+ }
+
+ sxg_entry_halt(netdev);
+ sxg_entry_open(netdev);
+ return 0;
+}
+
+/*
* sxg_link_state - Set the link state and if necessary, indicate.
* This routine the central point of processing for all link state changes.
* Nothing else in the driver should alter the link state or perform
@@ -2460,27 +3217,32 @@ static void sxg_indicate_link_state(struct adapter_t *adapter,
* Return
* None
*/
-static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkState)
+static void sxg_link_state(struct adapter_t *adapter,
+ enum SXG_LINK_STATE LinkState)
{
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_IMPORTANT, "LnkINDCT",
adapter, LinkState, adapter->LinkState, adapter->State);
DBG_ERROR("ENTER %s\n", __func__);
- /* Hold the adapter lock during this routine. Maybe move */
- /* the lock to the caller. */
- spin_lock(&adapter->AdapterLock);
+ /*
+ * Hold the adapter lock during this routine. Maybe move
+ * the lock to the caller.
+ */
+ /* IMP TODO : Check if we can survive without taking this lock */
+// spin_lock(&adapter->AdapterLock);
if (LinkState == adapter->LinkState) {
/* Nothing changed.. */
- spin_unlock(&adapter->AdapterLock);
- DBG_ERROR("EXIT #0 %s\n", __func__);
+// spin_unlock(&adapter->AdapterLock);
+ DBG_ERROR("EXIT #0 %s. Link status = %d\n",
+ __func__, LinkState);
return;
}
/* Save the adapter state */
adapter->LinkState = LinkState;
/* Drop the lock and indicate link state */
- spin_unlock(&adapter->AdapterLock);
+// spin_unlock(&adapter->AdapterLock);
DBG_ERROR("EXIT #1 %s\n", __func__);
sxg_indicate_link_state(adapter, LinkState);
@@ -2501,14 +3263,16 @@ static void sxg_link_state(struct adapter_t *adapter, enum SXG_LINK_STATE LinkSt
static int sxg_write_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 Value)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
- u32 AddrOp; /* Address operation (written to MIIM field reg) */
- u32 WriteOp; /* Write operation (written to MIIM field reg) */
- u32 Cmd; /* Command (written to MIIM command reg) */
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ /* Address operation (written to MIIM field reg) */
+ u32 AddrOp;
+ /* Write operation (written to MIIM field reg) */
+ u32 WriteOp;
+ u32 Cmd;/* Command (written to MIIM command reg) */
u32 ValueRead;
u32 Timeout;
-/* DBG_ERROR("ENTER %s\n", __func__); */
+ /* DBG_ERROR("ENTER %s\n", __func__); */
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
adapter, 0, 0, 0);
@@ -2571,7 +3335,7 @@ static int sxg_write_mdio_reg(struct adapter_t *adapter,
}
} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
-/* DBG_ERROR("EXIT %s\n", __func__); */
+ /* DBG_ERROR("EXIT %s\n", __func__); */
return (STATUS_SUCCESS);
}
@@ -2583,7 +3347,7 @@ static int sxg_write_mdio_reg(struct adapter_t *adapter,
* adapter - A pointer to our adapter structure
* DevAddr - MDIO device number being addressed
* RegAddr - register address for the specified MDIO device
- * pValue - pointer to where to put data read from the MDIO register
+ * pValue - pointer to where to put data read from the MDIO register
*
* Return
* status
@@ -2591,16 +3355,16 @@ static int sxg_write_mdio_reg(struct adapter_t *adapter,
static int sxg_read_mdio_reg(struct adapter_t *adapter,
u32 DevAddr, u32 RegAddr, u32 *pValue)
{
- struct SXG_HW_REGS *HwRegs = adapter->HwRegs;
- u32 AddrOp; /* Address operation (written to MIIM field reg) */
- u32 ReadOp; /* Read operation (written to MIIM field reg) */
- u32 Cmd; /* Command (written to MIIM command reg) */
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ u32 AddrOp; /* Address operation (written to MIIM field reg) */
+ u32 ReadOp; /* Read operation (written to MIIM field reg) */
+ u32 Cmd; /* Command (written to MIIM command reg) */
u32 ValueRead;
u32 Timeout;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "WrtMDIO",
adapter, 0, 0, 0);
-/* DBG_ERROR("ENTER %s\n", __func__); */
+ DBG_ERROR("ENTER %s\n", __FUNCTION__);
/* Ensure values don't exceed field width */
DevAddr &= 0x001F; /* 5-bit field */
@@ -2636,6 +3400,8 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
udelay(100); /* Timeout in 100us units */
READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
if (--Timeout == 0) {
+ DBG_ERROR("EXIT %s with STATUS_FAILURE 1\n", __FUNCTION__);
+
return (STATUS_FAILURE);
}
} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2655,6 +3421,8 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
udelay(100); /* Timeout in 100us units */
READ_REG(HwRegs->MacAmiimIndicator, ValueRead);
if (--Timeout == 0) {
+ DBG_ERROR("EXIT %s with STATUS_FAILURE 2\n", __FUNCTION__);
+
return (STATUS_FAILURE);
}
} while (ValueRead & AXGMAC_AMIIM_INDC_BUSY);
@@ -2663,7 +3431,7 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
READ_REG(HwRegs->MacAmiimField, *pValue);
*pValue &= 0xFFFF; /* data is in the lower 16 bits */
-/* DBG_ERROR("EXIT %s\n", __func__); */
+ DBG_ERROR("EXIT %s\n", __FUNCTION__);
return (STATUS_SUCCESS);
}
@@ -2672,22 +3440,21 @@ static int sxg_read_mdio_reg(struct adapter_t *adapter,
* Functions to obtain the CRC corresponding to the destination mac address.
* This is a standard ethernet CRC in that it is a 32-bit, reflected CRC using
* the polynomial:
- * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1.
- *
- * After the CRC for the 6 bytes is generated (but before the value is complemented),
- * we must then transpose the value and return bits 30-23.
+ * x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5
+ * + x^4 + x^2 + x^1.
*
+ * After the CRC for the 6 bytes is generated (but before the value is
+ * complemented), we must then transpose the value and return bits 30-23.
*/
-static u32 sxg_crc_table[256]; /* Table of CRC's for all possible byte values */
+static u32 sxg_crc_table[256];/* Table of CRC's for all possible byte values */
+static u32 sxg_crc_init; /* Is table initialized */
-/*
- * Contruct the CRC32 table
- */
+/* Contruct the CRC32 table */
static void sxg_mcast_init_crc32(void)
{
- u32 c; /* CRC shit reg */
- u32 e = 0; /* Poly X-or pattern */
- int i; /* counter */
+ u32 c; /* CRC shit reg */
+ u32 e = 0; /* Poly X-or pattern */
+ int i; /* counter */
int k; /* byte being shifted into crc */
static int p[] = { 0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26 };
@@ -2705,8 +3472,6 @@ static void sxg_mcast_init_crc32(void)
}
}
-#if XXXTODO
-static u32 sxg_crc_init; /* Is table initialized */
/*
* Return the MAC hast as described above.
*/
@@ -2737,25 +3502,31 @@ static unsigned char sxg_mcast_get_mac_hash(char *macaddr)
static void sxg_mcast_set_mask(struct adapter_t *adapter)
{
- struct SXG_UCODE_REGS *sxg_regs = adapter->UcodeRegs;
+ struct sxg_ucode_regs *sxg_regs = adapter->UcodeRegs;
- DBG_ERROR("%s ENTER (%s) macopts[%x] mask[%llx]\n", __func__,
+ DBG_ERROR("%s ENTER (%s) MacFilter[%x] mask[%llx]\n", __FUNCTION__,
adapter->netdev->name, (unsigned int)adapter->MacFilter,
adapter->MulticastMask);
if (adapter->MacFilter & (MAC_ALLMCAST | MAC_PROMISC)) {
- /* Turn on all multicast addresses. We have to do this for promiscuous
- * mode as well as ALLMCAST mode. It saves the Microcode from having
- * to keep state about the MAC configuration.
+ /*
+ * Turn on all multicast addresses. We have to do this for
+ * promiscuous mode as well as ALLMCAST mode. It saves the
+ * Microcode from having keep state about the MAC configuration
+ */
+ /* DBG_ERROR("sxg: %s MacFilter = MAC_ALLMCAST | MAC_PROMISC\n \
+ * SLUT MODE!!!\n",__func__);
*/
-/* DBG_ERROR("sxg: %s macopts = MAC_ALLMCAST | MAC_PROMISC\n SLUT MODE!!!\n",__func__); */
WRITE_REG(sxg_regs->McastLow, 0xFFFFFFFF, FLUSH);
WRITE_REG(sxg_regs->McastHigh, 0xFFFFFFFF, FLUSH);
-/* DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high 0xFFFFFFFF\n",__func__, adapter->netdev->name); */
+ /* DBG_ERROR("%s (%s) WRITE to slic_regs slic_mcastlow&high \
+ * 0xFFFFFFFF\n",__func__, adapter->netdev->name);
+ */
} else {
- /* Commit our multicast mast to the SLIC by writing to the multicast
- * address mask registers
+ /*
+ * Commit our multicast mast to the SLIC by writing to the
+ * multicast address mask registers
*/
DBG_ERROR("%s (%s) WRITE mcastlow[%lx] mcasthigh[%lx]\n",
__func__, adapter->netdev->name,
@@ -2771,38 +3542,6 @@ static void sxg_mcast_set_mask(struct adapter_t *adapter)
}
}
-/*
- * Allocate a mcast_address structure to hold the multicast address.
- * Link it in.
- */
-static int sxg_mcast_add_list(struct adapter_t *adapter, char *address)
-{
- p_mcast_address_t mcaddr, mlist;
- bool equaladdr;
-
- /* Check to see if it already exists */
- mlist = adapter->mcastaddrs;
- while (mlist) {
- ETHER_EQ_ADDR(mlist->address, address, equaladdr);
- if (equaladdr) {
- return (STATUS_SUCCESS);
- }
- mlist = mlist->next;
- }
-
- /* Doesn't already exist. Allocate a structure to hold it */
- mcaddr = kmalloc(sizeof(mcast_address_t), GFP_ATOMIC);
- if (mcaddr == NULL)
- return 1;
-
- memcpy(mcaddr->address, address, 6);
-
- mcaddr->next = adapter->mcastaddrs;
- adapter->mcastaddrs = mcaddr;
-
- return (STATUS_SUCCESS);
-}
-
static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
{
unsigned char crcpoly;
@@ -2810,7 +3549,8 @@ static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
/* Get the CRC polynomial for the mac address */
crcpoly = sxg_mcast_get_mac_hash(address);
- /* We only have space on the SLIC for 64 entries. Lop
+ /*
+ * We only have space on the SLIC for 64 entries. Lop
* off the top two bits. (2^6 = 64)
*/
crcpoly &= 0x3F;
@@ -2819,76 +3559,119 @@ static void sxg_mcast_set_bit(struct adapter_t *adapter, char *address)
adapter->MulticastMask |= (u64) 1 << crcpoly;
}
-static void sxg_mcast_set_list(p_net_device dev)
+/*
+ * Function takes MAC addresses from dev_mc_list and generates the Mask
+ */
+
+static void sxg_set_mcast_addr(struct adapter_t *adapter)
+{
+ struct dev_mc_list *mclist;
+ struct net_device *dev = adapter->netdev;
+ int i;
+
+ if (adapter->MacFilter & (MAC_ALLMCAST | MAC_MCAST)) {
+ for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
+ i++, mclist = mclist->next) {
+ sxg_mcast_set_bit(adapter,mclist->da_addr);
+ }
+ }
+ sxg_mcast_set_mask(adapter);
+}
+
+static void sxg_mcast_set_list(struct net_device *dev)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
- int status = STATUS_SUCCESS;
- int i;
- char *addresses;
- struct dev_mc_list *mc_list = dev->mc_list;
- int mc_count = dev->mc_count;
ASSERT(adapter);
+ if (dev->flags & IFF_PROMISC)
+ adapter->MacFilter |= MAC_PROMISC;
+ if (dev->flags & IFF_MULTICAST)
+ adapter->MacFilter |= MAC_MCAST;
+ if (dev->flags & IFF_ALLMULTI)
+ adapter->MacFilter |= MAC_ALLMCAST;
+
+ //XXX handle other flags as well
+ sxg_set_mcast_addr(adapter);
+}
- for (i = 1; i <= mc_count; i++) {
- addresses = (char *)&mc_list->dmi_addr;
- if (mc_list->dmi_addrlen == 6) {
- status = sxg_mcast_add_list(adapter, addresses);
- if (status != STATUS_SUCCESS) {
- break;
- }
- } else {
- status = -EINVAL;
- break;
- }
- sxg_mcast_set_bit(adapter, addresses);
- mc_list = mc_list->next;
- }
+void sxg_free_sgl_buffers(struct adapter_t *adapter)
+{
+ struct list_entry *ple;
+ struct sxg_scatter_gather *Sgl;
+
+ while(!(IsListEmpty(&adapter->AllSglBuffers))) {
+ ple = RemoveHeadList(&adapter->AllSglBuffers);
+ Sgl = container_of(ple, struct sxg_scatter_gather, AllList);
+ kfree(Sgl);
+ adapter->AllSglBufferCount--;
+ }
+}
- DBG_ERROR("%s a->devflags_prev[%x] dev->flags[%x] status[%x]\n",
- __func__, adapter->devflags_prev, dev->flags, status);
- if (adapter->devflags_prev != dev->flags) {
- adapter->macopts = MAC_DIRECTED;
- if (dev->flags) {
- if (dev->flags & IFF_BROADCAST) {
- adapter->macopts |= MAC_BCAST;
- }
- if (dev->flags & IFF_PROMISC) {
- adapter->macopts |= MAC_PROMISC;
- }
- if (dev->flags & IFF_ALLMULTI) {
- adapter->macopts |= MAC_ALLMCAST;
- }
- if (dev->flags & IFF_MULTICAST) {
- adapter->macopts |= MAC_MCAST;
- }
- }
- adapter->devflags_prev = dev->flags;
- DBG_ERROR("%s call sxg_config_set adapter->macopts[%x]\n",
- __func__, adapter->macopts);
- sxg_config_set(adapter, TRUE);
- } else {
- if (status == STATUS_SUCCESS) {
- sxg_mcast_set_mask(adapter);
- }
+void sxg_free_rcvblocks(struct adapter_t *adapter)
+{
+ u32 i;
+ void *temp_RcvBlock;
+ struct list_entry *ple;
+ struct sxg_rcv_block_hdr *RcvBlockHdr;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+ ASSERT((adapter->state == SXG_STATE_INITIALIZING) ||
+ (adapter->state == SXG_STATE_HALTING));
+ while(!(IsListEmpty(&adapter->AllRcvBlocks))) {
+
+ ple = RemoveHeadList(&adapter->AllRcvBlocks);
+ RcvBlockHdr = container_of(ple, struct sxg_rcv_block_hdr, AllList);
+
+ if(RcvBlockHdr->VirtualAddress) {
+ temp_RcvBlock = RcvBlockHdr->VirtualAddress;
+
+ for(i=0; i< SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+ RcvDataBufferHdr =
+ (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
+ SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
+ }
+ }
+
+ pci_free_consistent(adapter->pcidev,
+ SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE),
+ RcvBlockHdr->VirtualAddress,
+ RcvBlockHdr->PhysicalAddress);
+ adapter->AllRcvBlockCount--;
}
- return;
+ ASSERT(adapter->AllRcvBlockCount == 0);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk",
+ adapter, 0, 0, 0);
+}
+void sxg_free_mcast_addrs(struct adapter_t *adapter)
+{
+ struct sxg_multicast_address *address;
+ while(adapter->MulticastAddrs) {
+ address = adapter->MulticastAddrs;
+ adapter->MulticastAddrs = address->Next;
+ kfree(address);
+ }
+
+ adapter->MulticastMask= 0;
}
-#endif
-static void sxg_unmap_mmio_space(struct adapter_t *adapter)
+void sxg_unmap_resources(struct adapter_t *adapter)
{
-#if LINUX_FREES_ADAPTER_RESOURCES
-/* if (adapter->Regs) { */
-/* iounmap(adapter->Regs); */
-/* } */
-/* adapter->slic_regs = NULL; */
-#endif
+ if(adapter->HwRegs) {
+ iounmap((void *)adapter->HwRegs);
+ }
+ if(adapter->UcodeRegs) {
+ iounmap((void *)adapter->UcodeRegs);
+ }
+
+ ASSERT(adapter->AllRcvBlockCount == 0);
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFrRBlk",
+ adapter, 0, 0, 0);
}
-#if XXXTODO
+
+
/*
- * SxgFreeResources - Free everything allocated in SxgAllocateResources
+ * sxg_free_resources - Free everything allocated in SxgAllocateResources
*
* Arguments -
* adapter - A pointer to our adapter structure
@@ -2896,94 +3679,76 @@ static void sxg_unmap_mmio_space(struct adapter_t *adapter)
* Return
* none
*/
-void SxgFreeResources(struct adapter_t *adapter)
+void sxg_free_resources(struct adapter_t *adapter)
{
u32 RssIds, IsrCount;
- PTCP_OBJECT TcpObject;
- u32 i;
- BOOLEAN TimerCancelled;
-
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FreeRes",
- adapter, adapter->MaxTcbs, 0, 0);
-
RssIds = SXG_RSS_CPU_COUNT(adapter);
- IsrCount = adapter->MsiEnabled ? RssIds : 1;
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
if (adapter->BasicAllocations == FALSE) {
- /* No allocations have been made, including spinlocks, */
- /* or listhead initializations. Return. */
+ /*
+ * No allocations have been made, including spinlocks,
+ * or listhead initializations. Return.
+ */
return;
}
if (!(IsListEmpty(&adapter->AllRcvBlocks))) {
- SxgFreeRcvBlocks(adapter);
+ sxg_free_rcvblocks(adapter);
}
if (!(IsListEmpty(&adapter->AllSglBuffers))) {
- SxgFreeSglBuffers(adapter);
- }
- /* Free event queues. */
- if (adapter->EventRings) {
- pci_free_consistent(adapter->pcidev,
- sizeof(struct SXG_EVENT_RING) * RssIds,
- adapter->EventRings, adapter->PEventRings);
- }
- if (adapter->Isr) {
- pci_free_consistent(adapter->pcidev,
- sizeof(u32) * IsrCount,
- adapter->Isr, adapter->PIsr);
+ sxg_free_sgl_buffers(adapter);
}
+
if (adapter->XmtRingZeroIndex) {
pci_free_consistent(adapter->pcidev,
sizeof(u32),
adapter->XmtRingZeroIndex,
adapter->PXmtRingZeroIndex);
}
- if (adapter->IndirectionTable) {
- pci_free_consistent(adapter->pcidev,
- SXG_MAX_RSS_TABLE_SIZE,
- adapter->IndirectionTable,
- adapter->PIndirectionTable);
+ if (adapter->Isr) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(u32) * IsrCount,
+ adapter->Isr, adapter->PIsr);
+ }
+
+ if (adapter->EventRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct sxg_event_ring) * RssIds,
+ adapter->EventRings, adapter->PEventRings);
+ }
+ if (adapter->RcvRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct sxg_rcv_ring) * 1,
+ adapter->RcvRings,
+ adapter->PRcvRings);
+ adapter->RcvRings = NULL;
+ }
+
+ if(adapter->XmtRings) {
+ pci_free_consistent(adapter->pcidev,
+ sizeof(struct sxg_xmt_ring) * 1,
+ adapter->XmtRings,
+ adapter->PXmtRings);
+ adapter->XmtRings = NULL;
+ }
+
+ if (adapter->ucode_stats) {
+ pci_unmap_single(adapter->pcidev,
+ sizeof(struct sxg_ucode_stats),
+ adapter->pucode_stats, PCI_DMA_FROMDEVICE);
+ adapter->ucode_stats = NULL;
}
- SXG_FREE_PACKET_POOL(adapter->PacketPoolHandle);
- SXG_FREE_BUFFER_POOL(adapter->BufferPoolHandle);
/* Unmap register spaces */
- SxgUnmapResources(adapter);
-
- /* Deregister DMA */
- if (adapter->DmaHandle) {
- SXG_DEREGISTER_DMA(adapter->DmaHandle);
- }
- /* Deregister interrupt */
- SxgDeregisterInterrupt(adapter);
-
- /* Possibly free system info (5.2 only) */
- SXG_RELEASE_SYSTEM_INFO(adapter);
-
- SxgDiagFreeResources(adapter);
+ sxg_unmap_resources(adapter);
- SxgFreeMCastAddrs(adapter);
-
- if (SXG_TIMER_ALLOCATED(adapter->ResetTimer)) {
- SXG_CANCEL_TIMER(adapter->ResetTimer, TimerCancelled);
- SXG_FREE_TIMER(adapter->ResetTimer);
- }
- if (SXG_TIMER_ALLOCATED(adapter->RssTimer)) {
- SXG_CANCEL_TIMER(adapter->RssTimer, TimerCancelled);
- SXG_FREE_TIMER(adapter->RssTimer);
- }
- if (SXG_TIMER_ALLOCATED(adapter->OffloadTimer)) {
- SXG_CANCEL_TIMER(adapter->OffloadTimer, TimerCancelled);
- SXG_FREE_TIMER(adapter->OffloadTimer);
- }
+ sxg_free_mcast_addrs(adapter);
adapter->BasicAllocations = FALSE;
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XFreeRes",
- adapter, adapter->MaxTcbs, 0, 0);
}
-#endif
/*
* sxg_allocate_complete -
@@ -3000,31 +3765,34 @@ void SxgFreeResources(struct adapter_t *adapter)
* Return
* None.
*/
-static void sxg_allocate_complete(struct adapter_t *adapter,
+static int sxg_allocate_complete(struct adapter_t *adapter,
void *VirtualAddress,
dma_addr_t PhysicalAddress,
- u32 Length, enum SXG_BUFFER_TYPE Context)
+ u32 Length, enum sxg_buffer_type Context)
{
+ int status = 0;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocCmp",
adapter, VirtualAddress, Length, Context);
- ASSERT(adapter->AllocationsPending);
- --adapter->AllocationsPending;
+ ASSERT(atomic_read(&adapter->pending_allocations));
+ atomic_dec(&adapter->pending_allocations);
switch (Context) {
case SXG_BUFFER_TYPE_RCV:
- sxg_allocate_rcvblock_complete(adapter,
+ status = sxg_allocate_rcvblock_complete(adapter,
VirtualAddress,
PhysicalAddress, Length);
break;
case SXG_BUFFER_TYPE_SGL:
- sxg_allocate_sgl_buffer_complete(adapter, (struct SXG_SCATTER_GATHER*)
+ sxg_allocate_sgl_buffer_complete(adapter, (struct sxg_scatter_gather *)
VirtualAddress,
PhysicalAddress, Length);
break;
}
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocCmp",
adapter, VirtualAddress, Length, Context);
+
+ return status;
}
/*
@@ -3040,7 +3808,7 @@ static void sxg_allocate_complete(struct adapter_t *adapter,
* int
*/
static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
- u32 Size, enum SXG_BUFFER_TYPE BufferType)
+ u32 Size, enum sxg_buffer_type BufferType)
{
int status;
void *Buffer;
@@ -3048,39 +3816,40 @@ static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AllocMem",
adapter, Size, BufferType, 0);
- /* Grab the adapter lock and check the state. */
- /* If we're in anything other than INITIALIZING or */
- /* RUNNING state, fail. This is to prevent */
- /* allocations in an improper driver state */
- spin_lock(&adapter->AdapterLock);
-
- /* Increment the AllocationsPending count while holding */
- /* the lock. Pause processing relies on this */
- ++adapter->AllocationsPending;
- spin_unlock(&adapter->AdapterLock);
-
- /* At initialization time allocate resources synchronously. */
- Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
+ /*
+ * Grab the adapter lock and check the state. If we're in anything other
+ * than INITIALIZING or RUNNING state, fail. This is to prevent
+ * allocations in an improper driver state
+ */
+
+ atomic_inc(&adapter->pending_allocations);
+
+ if(BufferType != SXG_BUFFER_TYPE_SGL)
+ Buffer = pci_alloc_consistent(adapter->pcidev, Size, &pBuffer);
+ else {
+ Buffer = kzalloc(Size, GFP_ATOMIC);
+ pBuffer = (dma_addr_t)NULL;
+ }
if (Buffer == NULL) {
- spin_lock(&adapter->AdapterLock);
- /* Decrement the AllocationsPending count while holding */
- /* the lock. Pause processing relies on this */
- --adapter->AllocationsPending;
- spin_unlock(&adapter->AdapterLock);
+ /*
+ * Decrement the AllocationsPending count while holding
+ * the lock. Pause processing relies on this
+ */
+ atomic_dec(&adapter->pending_allocations);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlcMemF1",
adapter, Size, BufferType, 0);
return (STATUS_RESOURCES);
}
- sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
- status = STATUS_SUCCESS;
+ status = sxg_allocate_complete(adapter, Buffer, pBuffer, Size, BufferType);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlocMem",
adapter, Size, BufferType, status);
- return (status);
+ return status;
}
/*
- * sxg_allocate_rcvblock_complete - Complete a receive descriptor block allocation
+ * sxg_allocate_rcvblock_complete - Complete a receive descriptor
+ * block allocation
*
* Arguments -
* adapter - A pointer to our adapter structure
@@ -3089,9 +3858,8 @@ static int sxg_allocate_buffer_memory(struct adapter_t *adapter,
* Length - Memory length
*
* Return
- *
*/
-static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
+static int sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
void *RcvBlock,
dma_addr_t PhysicalAddress,
u32 Length)
@@ -3099,11 +3867,11 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
u32 i;
u32 BufferSize = adapter->ReceiveBufferSize;
u64 Paddr;
- struct SXG_RCV_BLOCK_HDR *RcvBlockHdr;
- unsigned char *RcvDataBuffer;
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
- struct SXG_RCV_DESCRIPTOR_BLOCK *RcvDescriptorBlock;
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
+ void *temp_RcvBlock;
+ struct sxg_rcv_block_hdr *RcvBlockHdr;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+ struct sxg_rcv_descriptor_block *RcvDescriptorBlock;
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlRcvBlk",
adapter, RcvBlock, Length, 0);
@@ -3113,42 +3881,33 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
memset(RcvBlock, 0, Length);
ASSERT((BufferSize == SXG_RCV_DATA_BUFFER_SIZE) ||
(BufferSize == SXG_RCV_JUMBO_BUFFER_SIZE));
- ASSERT(Length == SXG_RCV_BLOCK_SIZE(BufferSize));
- /* First, initialize the contained pool of receive data */
- /* buffers. This initialization requires NBL/NB/MDL allocations, */
- /* If any of them fail, free the block and return without */
- /* queueing the shared memory */
- RcvDataBuffer = RcvBlock;
-#if 0
- for (i = 0, Paddr = *PhysicalAddress;
- i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
- i++, Paddr.LowPart += BufferSize, RcvDataBuffer += BufferSize)
-#endif
- for (i = 0, Paddr = PhysicalAddress;
- i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
- i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
- /* */
- RcvDataBufferHdr =
- (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
- SXG_RCV_DATA_BUFFER_HDR_OFFSET
- (BufferSize));
- RcvDataBufferHdr->VirtualAddress = RcvDataBuffer;
- RcvDataBufferHdr->PhysicalAddress = Paddr;
- RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM; /* For FREE macro assertion */
- RcvDataBufferHdr->Size =
- SXG_RCV_BUFFER_DATA_SIZE(BufferSize);
-
- SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr);
- if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
- goto fail;
+ ASSERT(Length == SXG_RCV_BLOCK_SIZE(SXG_RCV_DATA_HDR_SIZE));
+ /*
+ * First, initialize the contained pool of receive data buffers.
+ * This initialization requires NBL/NB/MDL allocations, if any of them
+ * fail, free the block and return without queueing the shared memory
+ */
+ //RcvDataBuffer = RcvBlock;
+ temp_RcvBlock = RcvBlock;
+ for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
+ i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+ RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *)
+ temp_RcvBlock;
+ /* For FREE macro assertion */
+ RcvDataBufferHdr->State = SXG_BUFFER_UPSTREAM;
+ SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr, BufferSize);
+ if (RcvDataBufferHdr->SxgDumbRcvPacket == NULL)
+ goto fail;
- }
+ }
- /* Place this entire block of memory on the AllRcvBlocks queue so it can be */
- /* free later */
- RcvBlockHdr =
- (struct SXG_RCV_BLOCK_HDR*) ((unsigned char *)RcvBlock +
- SXG_RCV_BLOCK_HDR_OFFSET(BufferSize));
+ /*
+ * Place this entire block of memory on the AllRcvBlocks queue so it
+ * can be free later
+ */
+
+ RcvBlockHdr = (struct sxg_rcv_block_hdr *) ((unsigned char *)RcvBlock +
+ SXG_RCV_BLOCK_HDR_OFFSET(SXG_RCV_DATA_HDR_SIZE));
RcvBlockHdr->VirtualAddress = RcvBlock;
RcvBlockHdr->PhysicalAddress = PhysicalAddress;
spin_lock(&adapter->RcvQLock);
@@ -3156,14 +3915,15 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
InsertTailList(&adapter->AllRcvBlocks, &RcvBlockHdr->AllList);
spin_unlock(&adapter->RcvQLock);
- /* Now free the contained receive data buffers that we initialized above */
- RcvDataBuffer = RcvBlock;
+ /* Now free the contained receive data buffers that we
+ * initialized above */
+ temp_RcvBlock = RcvBlock;
for (i = 0, Paddr = PhysicalAddress;
i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
- i++, Paddr += BufferSize, RcvDataBuffer += BufferSize) {
- RcvDataBufferHdr = (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
- SXG_RCV_DATA_BUFFER_HDR_OFFSET
- (BufferSize));
+ i++, Paddr += SXG_RCV_DATA_HDR_SIZE,
+ temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
+ RcvDataBufferHdr =
+ (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
spin_lock(&adapter->RcvQLock);
SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
spin_unlock(&adapter->RcvQLock);
@@ -3171,13 +3931,13 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
/* Locate the descriptor block and put it on a separate free queue */
RcvDescriptorBlock =
- (struct SXG_RCV_DESCRIPTOR_BLOCK*) ((unsigned char *)RcvBlock +
+ (struct sxg_rcv_descriptor_block *) ((unsigned char *)RcvBlock +
SXG_RCV_DESCRIPTOR_BLOCK_OFFSET
- (BufferSize));
+ (SXG_RCV_DATA_HDR_SIZE));
RcvDescriptorBlockHdr =
- (struct SXG_RCV_DESCRIPTOR_BLOCK_HDR*) ((unsigned char *)RcvBlock +
+ (struct sxg_rcv_descriptor_block_hdr *) ((unsigned char *)RcvBlock +
SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET
- (BufferSize));
+ (SXG_RCV_DATA_HDR_SIZE));
RcvDescriptorBlockHdr->VirtualAddress = RcvDescriptorBlock;
RcvDescriptorBlockHdr->PhysicalAddress = Paddr;
spin_lock(&adapter->RcvQLock);
@@ -3185,17 +3945,15 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
spin_unlock(&adapter->RcvQLock);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlRBlk",
adapter, RcvBlock, Length, 0);
- return;
- fail:
+ return STATUS_SUCCESS;
+fail:
/* Free any allocated resources */
if (RcvBlock) {
- RcvDataBuffer = RcvBlock;
+ temp_RcvBlock = RcvBlock;
for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK;
- i++, RcvDataBuffer += BufferSize) {
+ i++, temp_RcvBlock += SXG_RCV_DATA_HDR_SIZE) {
RcvDataBufferHdr =
- (struct SXG_RCV_DATA_BUFFER_HDR*) (RcvDataBuffer +
- SXG_RCV_DATA_BUFFER_HDR_OFFSET
- (BufferSize));
+ (struct sxg_rcv_data_buffer_hdr *)temp_RcvBlock;
SXG_FREE_RCV_PACKET(RcvDataBufferHdr);
}
pci_free_consistent(adapter->pcidev,
@@ -3206,6 +3964,10 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
adapter, adapter->FreeRcvBufferCount,
adapter->FreeRcvBlockCount, adapter->AllRcvBlockCount);
adapter->Stats.NoMem++;
+ /* As allocation failed, free all previously allocated blocks..*/
+ //sxg_free_rcvblocks(adapter);
+
+ return STATUS_RESOURCES;
}
/*
@@ -3213,46 +3975,65 @@ static void sxg_allocate_rcvblock_complete(struct adapter_t *adapter,
*
* Arguments -
* adapter - A pointer to our adapter structure
- * SxgSgl - SXG_SCATTER_GATHER buffer
+ * SxgSgl - struct sxg_scatter_gather buffer
* PhysicalAddress - Physical address
* Length - Memory length
*
* Return
- *
*/
static void sxg_allocate_sgl_buffer_complete(struct adapter_t *adapter,
- struct SXG_SCATTER_GATHER *SxgSgl,
+ struct sxg_scatter_gather *SxgSgl,
dma_addr_t PhysicalAddress,
u32 Length)
{
+ unsigned long sgl_flags;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "AlSglCmp",
adapter, SxgSgl, Length, 0);
- spin_lock(&adapter->SglQLock);
+ spin_lock_irqsave(&adapter->SglQLock, sgl_flags);
adapter->AllSglBufferCount++;
- memset(SxgSgl, 0, sizeof(struct SXG_SCATTER_GATHER*));
- SxgSgl->PhysicalAddress = PhysicalAddress; /* *PhysicalAddress; */
- SxgSgl->adapter = adapter; /* Initialize backpointer once */
+ /* PhysicalAddress; */
+ SxgSgl->PhysicalAddress = PhysicalAddress;
+ /* Initialize backpointer once */
+ SxgSgl->adapter = adapter;
InsertTailList(&adapter->AllSglBuffers, &SxgSgl->AllList);
- spin_unlock(&adapter->SglQLock);
+ spin_unlock_irqrestore(&adapter->SglQLock, sgl_flags);
SxgSgl->State = SXG_BUFFER_BUSY;
SXG_FREE_SGL_BUFFER(adapter, SxgSgl, NULL);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XAlSgl",
adapter, SxgSgl, Length, 0);
}
-static unsigned char temp_mac_address[6] =
- { 0x00, 0xab, 0xcd, 0xef, 0x12, 0x69 };
-static void sxg_adapter_set_hwaddr(struct adapter_t *adapter)
+static int sxg_adapter_set_hwaddr(struct adapter_t *adapter)
{
-/* DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] funct#[%d]\n", __func__, */
-/* card->config_set, adapter->port, adapter->physport, adapter->functionnumber); */
-/* */
-/* sxg_dbg_macaddrs(adapter); */
+ /*
+ * DBG_ERROR ("%s ENTER card->config_set[%x] port[%d] physport[%d] \
+ * funct#[%d]\n", __func__, card->config_set,
+ * adapter->port, adapter->physport, adapter->functionnumber);
+ *
+ * sxg_dbg_macaddrs(adapter);
+ */
+ /* DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n",
+ * __FUNCTION__);
+ */
+
+ /* sxg_dbg_macaddrs(adapter); */
+
+ struct net_device * dev = adapter->netdev;
+ if(!dev)
+ {
+ printk("sxg: Dev is Null\n");
+ }
+
+ DBG_ERROR("%s ENTER (%s)\n", __FUNCTION__, adapter->netdev->name);
+
+ if (netif_running(dev)) {
+ return -EBUSY;
+ }
+ if (!adapter) {
+ return -EBUSY;
+ }
- memcpy(adapter->macaddr, temp_mac_address, sizeof(struct SXG_CONFIG_MAC));
-/* DBG_ERROR ("%s AFTER copying from config.macinfo into currmacaddr\n", __func__); */
-/* sxg_dbg_macaddrs(adapter); */
if (!(adapter->currmacaddr[0] ||
adapter->currmacaddr[1] ||
adapter->currmacaddr[2] ||
@@ -3262,14 +4043,16 @@ static void sxg_adapter_set_hwaddr(struct adapter_t *adapter)
}
if (adapter->netdev) {
memcpy(adapter->netdev->dev_addr, adapter->currmacaddr, 6);
+ memcpy(adapter->netdev->perm_addr, adapter->currmacaddr, 6);
}
-/* DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
+ /* DBG_ERROR ("%s EXIT port %d\n", __func__, adapter->port); */
sxg_dbg_macaddrs(adapter);
+ return 0;
}
#if XXXTODO
-static int sxg_mac_set_address(p_net_device dev, void *ptr)
+static int sxg_mac_set_address(struct net_device *dev, void *ptr)
{
struct adapter_t *adapter = (struct adapter_t *) netdev_priv(dev);
struct sockaddr *addr = ptr;
@@ -3300,34 +4083,34 @@ static int sxg_mac_set_address(p_net_device dev, void *ptr)
}
#endif
-/*****************************************************************************/
-/************* SXG DRIVER FUNCTIONS (below) ********************************/
-/*****************************************************************************/
-
/*
+ * SXG DRIVER FUNCTIONS (below)
+ *
* sxg_initialize_adapter - Initialize adapter
*
* Arguments -
* adapter - A pointer to our adapter structure
*
- * Return
- * int
+ * Return - int
*/
static int sxg_initialize_adapter(struct adapter_t *adapter)
{
u32 RssIds, IsrCount;
u32 i;
int status;
+ int sxg_rcv_ring_size = SXG_RCV_RING_SIZE;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "InitAdpt",
adapter, 0, 0, 0);
RssIds = 1; /* XXXTODO SXG_RSS_CPU_COUNT(adapter); */
- IsrCount = adapter->MsiEnabled ? RssIds : 1;
+ IsrCount = adapter->msi_enabled ? RssIds : 1;
- /* Sanity check SXG_UCODE_REGS structure definition to */
- /* make sure the length is correct */
- ASSERT(sizeof(struct SXG_UCODE_REGS) == SXG_REGISTER_SIZE_PER_CPU);
+ /*
+ * Sanity check SXG_UCODE_REGS structure definition to
+ * make sure the length is correct
+ */
+ ASSERT(sizeof(struct sxg_ucode_regs) == SXG_REGISTER_SIZE_PER_CPU);
/* Disable interrupts */
SXG_DISABLE_ALL_INTERRUPTS(adapter);
@@ -3370,19 +4153,24 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
/* Receive ring base and size */
WRITE_REG64(adapter,
adapter->UcodeRegs[0].RcvBase, adapter->PRcvRings, 0);
- WRITE_REG(adapter->UcodeRegs[0].RcvSize, SXG_RCV_RING_SIZE, TRUE);
+ if (adapter->JumboEnabled == TRUE)
+ sxg_rcv_ring_size = SXG_JUMBO_RCV_RING_SIZE;
+ WRITE_REG(adapter->UcodeRegs[0].RcvSize, sxg_rcv_ring_size, TRUE);
/* Populate the card with receive buffers */
sxg_stock_rcv_buffers(adapter);
- /* Initialize checksum offload capabilities. At the moment */
- /* we always enable IP and TCP receive checksums on the card. */
- /* Depending on the checksum configuration specified by the */
- /* user, we can choose to report or ignore the checksum */
- /* information provided by the card. */
+ /*
+ * Initialize checksum offload capabilities. At the moment we always
+ * enable IP and TCP receive checksums on the card. Depending on the
+ * checksum configuration specified by the user, we can choose to
+ * report or ignore the checksum information provided by the card.
+ */
WRITE_REG(adapter->UcodeRegs[0].ReceiveChecksum,
SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED, TRUE);
+ adapter->flags |= (SXG_RCV_TCP_CSUM_ENABLED | SXG_RCV_IP_CSUM_ENABLED );
+
/* Initialize the MAC, XAUI */
DBG_ERROR("sxg: %s ENTER sxg_initialize_link\n", __func__);
status = sxg_initialize_link(adapter);
@@ -3391,10 +4179,16 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
if (status != STATUS_SUCCESS) {
return (status);
}
- /* Initialize Dead to FALSE. */
- /* SlicCheckForHang or SlicDumpThread will take it from here. */
+ /*
+ * Initialize Dead to FALSE.
+ * SlicCheckForHang or SlicDumpThread will take it from here.
+ */
adapter->Dead = FALSE;
adapter->PingOutstanding = FALSE;
+ adapter->XmtFcEnabled = TRUE;
+ adapter->RcvFcEnabled = TRUE;
+
+ adapter->State = SXG_STATE_RUNNING;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XInit",
adapter, 0, 0, 0);
@@ -3413,15 +4207,14 @@ static int sxg_initialize_adapter(struct adapter_t *adapter)
* status
*/
static int sxg_fill_descriptor_block(struct adapter_t *adapter,
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR
- *RcvDescriptorBlockHdr)
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr)
{
u32 i;
- struct SXG_RING_INFO *RcvRingInfo = &adapter->RcvRingZeroInfo;
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
- struct SXG_RCV_DESCRIPTOR_BLOCK *RcvDescriptorBlock;
- struct SXG_CMD *RingDescriptorCmd;
- struct SXG_RCV_RING *RingZero = &adapter->RcvRings[0];
+ struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo;
+ struct sxg_rcv_data_buffer_hdr *RcvDataBufferHdr;
+ struct sxg_rcv_descriptor_block *RcvDescriptorBlock;
+ struct sxg_cmd *RingDescriptorCmd;
+ struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0];
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "FilBlk",
adapter, adapter->RcvBuffersOnCard,
@@ -3429,8 +4222,10 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
ASSERT(RcvDescriptorBlockHdr);
- /* If we don't have the resources to fill the descriptor block, */
- /* return failure */
+ /*
+ * If we don't have the resources to fill the descriptor block,
+ * return failure
+ */
if ((adapter->FreeRcvBufferCount < SXG_RCV_DESCRIPTORS_PER_BLOCK) ||
SXG_RING_FULL(RcvRingInfo)) {
adapter->Stats.NoMem++;
@@ -3441,27 +4236,40 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
RcvRingInfo, RingDescriptorCmd, RcvDescriptorBlockHdr);
ASSERT(RingDescriptorCmd);
RcvDescriptorBlockHdr->State = SXG_BUFFER_ONCARD;
- RcvDescriptorBlock =
- (struct SXG_RCV_DESCRIPTOR_BLOCK*) RcvDescriptorBlockHdr->VirtualAddress;
+ RcvDescriptorBlock = (struct sxg_rcv_descriptor_block *)
+ RcvDescriptorBlockHdr->VirtualAddress;
/* Fill in the descriptor block */
for (i = 0; i < SXG_RCV_DESCRIPTORS_PER_BLOCK; i++) {
SXG_GET_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
ASSERT(RcvDataBufferHdr);
+// ASSERT(RcvDataBufferHdr->SxgDumbRcvPacket);
+ if (!RcvDataBufferHdr->SxgDumbRcvPacket) {
+ SXG_ALLOCATE_RCV_PACKET(adapter, RcvDataBufferHdr,
+ adapter->ReceiveBufferSize);
+ if(RcvDataBufferHdr->skb)
+ RcvDataBufferHdr->SxgDumbRcvPacket =
+ RcvDataBufferHdr->skb;
+ else
+ goto no_memory;
+ }
SXG_REINIATIALIZE_PACKET(RcvDataBufferHdr->SxgDumbRcvPacket);
RcvDataBufferHdr->State = SXG_BUFFER_ONCARD;
RcvDescriptorBlock->Descriptors[i].VirtualAddress =
- (void *)RcvDataBufferHdr;
+ (void *)RcvDataBufferHdr;
+
RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
RcvDataBufferHdr->PhysicalAddress;
}
/* Add the descriptor block to receive descriptor ring 0 */
RingDescriptorCmd->Sgl = RcvDescriptorBlockHdr->PhysicalAddress;
- /* RcvBuffersOnCard is not protected via the receive lock (see */
- /* sxg_process_event_queue) We don't want to grap a lock every time a */
- /* buffer is returned to us, so we use atomic interlocked functions */
- /* instead. */
+ /*
+ * RcvBuffersOnCard is not protected via the receive lock (see
+ * sxg_process_event_queue) We don't want to grap a lock every time a
+ * buffer is returned to us, so we use atomic interlocked functions
+ * instead.
+ */
adapter->RcvBuffersOnCard += SXG_RCV_DESCRIPTORS_PER_BLOCK;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DscBlk",
@@ -3473,6 +4281,23 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
adapter, adapter->RcvBuffersOnCard,
adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
return (STATUS_SUCCESS);
+no_memory:
+ for (; i >= 0 ; i--) {
+ if (RcvDescriptorBlock->Descriptors[i].VirtualAddress) {
+ RcvDataBufferHdr = (struct sxg_rcv_data_buffer_hdr *)
+ RcvDescriptorBlock->Descriptors[i].
+ VirtualAddress;
+ RcvDescriptorBlock->Descriptors[i].PhysicalAddress =
+ (dma_addr_t)NULL;
+ RcvDescriptorBlock->Descriptors[i].VirtualAddress=NULL;
+ }
+ SXG_FREE_RCV_DATA_BUFFER(adapter, RcvDataBufferHdr);
+ }
+ RcvDescriptorBlockHdr->State = SXG_BUFFER_FREE;
+ SXG_RETURN_CMD(RingZero, RcvRingInfo, RingDescriptorCmd,
+ RcvDescriptorBlockHdr);
+
+ return (-ENOMEM);
}
/*
@@ -3486,34 +4311,42 @@ static int sxg_fill_descriptor_block(struct adapter_t *adapter,
*/
static void sxg_stock_rcv_buffers(struct adapter_t *adapter)
{
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
+ int sxg_rcv_data_buffers = SXG_RCV_DATA_BUFFERS;
+ int sxg_min_rcv_data_buffers = SXG_MIN_RCV_DATA_BUFFERS;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "StockBuf",
adapter, adapter->RcvBuffersOnCard,
adapter->FreeRcvBufferCount, adapter->AllRcvBlockCount);
- /* First, see if we've got less than our minimum threshold of */
- /* receive buffers, there isn't an allocation in progress, and */
- /* we haven't exceeded our maximum.. get another block of buffers */
- /* None of this needs to be SMP safe. It's round numbers. */
- if ((adapter->FreeRcvBufferCount < SXG_MIN_RCV_DATA_BUFFERS) &&
+ /*
+ * First, see if we've got less than our minimum threshold of
+ * receive buffers, there isn't an allocation in progress, and
+ * we haven't exceeded our maximum.. get another block of buffers
+ * None of this needs to be SMP safe. It's round numbers.
+ */
+ if (adapter->JumboEnabled == TRUE)
+ sxg_min_rcv_data_buffers = SXG_MIN_JUMBO_RCV_DATA_BUFFERS;
+ if ((adapter->FreeRcvBufferCount < sxg_min_rcv_data_buffers) &&
(adapter->AllRcvBlockCount < SXG_MAX_RCV_BLOCKS) &&
- (adapter->AllocationsPending == 0)) {
+ (atomic_read(&adapter->pending_allocations) == 0)) {
sxg_allocate_buffer_memory(adapter,
- SXG_RCV_BLOCK_SIZE(adapter->
- ReceiveBufferSize),
+ SXG_RCV_BLOCK_SIZE
+ (SXG_RCV_DATA_HDR_SIZE),
SXG_BUFFER_TYPE_RCV);
}
/* Now grab the RcvQLock lock and proceed */
spin_lock(&adapter->RcvQLock);
- while (adapter->RcvBuffersOnCard < SXG_RCV_DATA_BUFFERS) {
- struct LIST_ENTRY *_ple;
+ if (adapter->JumboEnabled)
+ sxg_rcv_data_buffers = SXG_JUMBO_RCV_DATA_BUFFERS;
+ while (adapter->RcvBuffersOnCard < sxg_rcv_data_buffers) {
+ struct list_entry *_ple;
/* Get a descriptor block */
RcvDescriptorBlockHdr = NULL;
if (adapter->FreeRcvBlockCount) {
_ple = RemoveHeadList(&adapter->FreeRcvBlocks);
RcvDescriptorBlockHdr =
- container_of(_ple, struct SXG_RCV_DESCRIPTOR_BLOCK_HDR,
+ container_of(_ple, struct sxg_rcv_descriptor_block_hdr,
FreeList);
adapter->FreeRcvBlockCount--;
RcvDescriptorBlockHdr->State = SXG_BUFFER_BUSY;
@@ -3553,10 +4386,10 @@ static void sxg_stock_rcv_buffers(struct adapter_t *adapter)
static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
unsigned char Index)
{
- struct SXG_RCV_RING *RingZero = &adapter->RcvRings[0];
- struct SXG_RING_INFO *RcvRingInfo = &adapter->RcvRingZeroInfo;
- struct SXG_RCV_DESCRIPTOR_BLOCK_HDR *RcvDescriptorBlockHdr;
- struct SXG_CMD *RingDescriptorCmd;
+ struct sxg_rcv_ring *RingZero = &adapter->RcvRings[0];
+ struct sxg_ring_info *RcvRingInfo = &adapter->RcvRingZeroInfo;
+ struct sxg_rcv_descriptor_block_hdr *RcvDescriptorBlockHdr;
+ struct sxg_cmd *RingDescriptorCmd;
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "CmpRBlks",
adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
@@ -3564,12 +4397,13 @@ static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
/* Now grab the RcvQLock lock and proceed */
spin_lock(&adapter->RcvQLock);
ASSERT(Index != RcvRingInfo->Tail);
- while (RcvRingInfo->Tail != Index) {
- /* */
- /* Locate the current Cmd (ring descriptor entry), and */
- /* associated receive descriptor block, and advance */
- /* the tail */
- /* */
+ while (sxg_ring_get_forward_diff(RcvRingInfo, Index,
+ RcvRingInfo->Tail) > 3) {
+ /*
+ * Locate the current Cmd (ring descriptor entry), and
+ * associated receive descriptor block, and advance
+ * the tail
+ */
SXG_RETURN_CMD(RingZero,
RcvRingInfo,
RingDescriptorCmd, RcvDescriptorBlockHdr);
@@ -3579,23 +4413,66 @@ static void sxg_complete_descriptor_blocks(struct adapter_t *adapter,
/* Clear the SGL field */
RingDescriptorCmd->Sgl = 0;
- /* Attempt to refill it and hand it right back to the */
- /* card. If we fail to refill it, free the descriptor block */
- /* header. The card will be restocked later via the */
- /* RcvBuffersOnCard test */
- if (sxg_fill_descriptor_block(adapter, RcvDescriptorBlockHdr) ==
- STATUS_FAILURE) {
+ /*
+ * Attempt to refill it and hand it right back to the
+ * card. If we fail to refill it, free the descriptor block
+ * header. The card will be restocked later via the
+ * RcvBuffersOnCard test
+ */
+ if (sxg_fill_descriptor_block(adapter,
+ RcvDescriptorBlockHdr) == STATUS_FAILURE)
SXG_FREE_RCV_DESCRIPTOR_BLOCK(adapter,
RcvDescriptorBlockHdr);
- }
}
spin_unlock(&adapter->RcvQLock);
SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "XCRBlks",
adapter, Index, RcvRingInfo->Head, RcvRingInfo->Tail);
}
+/*
+ * Read the statistics which the card has been maintaining.
+ */
+void sxg_collect_statistics(struct adapter_t *adapter)
+{
+ if(adapter->ucode_stats)
+ WRITE_REG64(adapter, adapter->UcodeRegs[0].GetUcodeStats,
+ adapter->pucode_stats, 0);
+ adapter->stats.rx_fifo_errors = adapter->ucode_stats->ERDrops;
+ adapter->stats.rx_over_errors = adapter->ucode_stats->NBDrops;
+ adapter->stats.tx_fifo_errors = adapter->ucode_stats->XDrops;
+}
+
+static struct net_device_stats *sxg_get_stats(struct net_device * dev)
+{
+ struct adapter_t *adapter = netdev_priv(dev);
+
+ sxg_collect_statistics(adapter);
+ return (&adapter->stats);
+}
+
+static void sxg_watchdog(unsigned long data)
+{
+ struct adapter_t *adapter = (struct adapter_t *) data;
+
+ if (adapter->state != ADAPT_DOWN) {
+ sxg_link_event(adapter);
+ /* Reset the timer */
+ mod_timer(&adapter->watchdog_timer, round_jiffies(jiffies + 2 * HZ));
+ }
+}
+
+static void sxg_update_link_status (struct work_struct *work)
+{
+ struct adapter_t *adapter = (struct adapter_t *)container_of
+ (work, struct adapter_t, update_link_status);
+ if (likely(adapter->link_status_changed)) {
+ sxg_link_event(adapter);
+ adapter->link_status_changed = 0;
+ }
+}
+
static struct pci_driver sxg_driver = {
- .name = DRV_NAME,
+ .name = sxg_driver_name,
.id_table = sxg_pci_tbl,
.probe = sxg_entry_probe,
.remove = sxg_entry_remove,
@@ -3603,7 +4480,7 @@ static struct pci_driver sxg_driver = {
.suspend = sxgpm_suspend,
.resume = sxgpm_resume,
#endif
-/* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
+ /* .shutdown = slic_shutdown, MOOK_INVESTIGATE */
};
static int __init sxg_module_init(void)
diff --git a/drivers/staging/sxg/sxg.h b/drivers/staging/sxg/sxg.h
index 653cf3ba0c4..f07aa708d86 100644
--- a/drivers/staging/sxg/sxg.h
+++ b/drivers/staging/sxg/sxg.h
@@ -42,357 +42,369 @@
#ifndef __SXG_DRIVER_H__
#define __SXG_DRIVER_H__
-#define p_net_device struct net_device *
-// SXG_STATS - Probably move these to someplace where
-// the slicstat (sxgstat?) program can get them.
-struct SXG_STATS {
- // Xmt
- u32 XmtNBL; // Offload send NBL count
- u64 DumbXmtBytes; // Dumbnic send bytes
- u64 SlowXmtBytes; // Slowpath send bytes
- u64 FastXmtBytes; // Fastpath send bytes
- u64 DumbXmtPkts; // Dumbnic send packets
- u64 SlowXmtPkts; // Slowpath send packets
- u64 FastXmtPkts; // Fastpath send packets
- u64 DumbXmtUcastPkts; // directed packets
- u64 DumbXmtMcastPkts; // Multicast packets
- u64 DumbXmtBcastPkts; // OID_GEN_BROADCAST_FRAMES_RCV
- u64 DumbXmtUcastBytes; // OID_GEN_DIRECTED_BYTES_XMIT
- u64 DumbXmtMcastBytes; // OID_GEN_MULTICAST_BYTES_XMIT
- u64 DumbXmtBcastBytes; // OID_GEN_BROADCAST_BYTES_XMIT
- u64 XmtErrors; // OID_GEN_XMIT_ERROR
- u64 XmtDiscards; // OID_GEN_XMIT_DISCARDS
- u64 XmtOk; // OID_GEN_XMIT_OK
- u64 XmtQLen; // OID_GEN_TRANSMIT_QUEUE_LENGTH
- u64 XmtZeroFull; // Transmit ring zero full
- // Rcv
- u32 RcvNBL; // Offload recieve NBL count
- u64 DumbRcvBytes; // dumbnic recv bytes
- u64 DumbRcvUcastBytes; // OID_GEN_DIRECTED_BYTES_RCV
- u64 DumbRcvMcastBytes; // OID_GEN_MULTICAST_BYTES_RCV
- u64 DumbRcvBcastBytes; // OID_GEN_BROADCAST_BYTES_RCV
- u64 SlowRcvBytes; // Slowpath recv bytes
- u64 FastRcvBytes; // Fastpath recv bytes
- u64 DumbRcvPkts; // OID_GEN_DIRECTED_FRAMES_RCV
- u64 DumbRcvTcpPkts; // See SxgCollectStats
- u64 DumbRcvUcastPkts; // directed packets
- u64 DumbRcvMcastPkts; // Multicast packets
- u64 DumbRcvBcastPkts; // OID_GEN_BROADCAST_FRAMES_RCV
- u64 SlowRcvPkts; // OID_GEN_DIRECTED_FRAMES_RCV
- u64 RcvErrors; // OID_GEN_RCV_ERROR
- u64 RcvDiscards; // OID_GEN_RCV_DISCARDS
- u64 RcvNoBuffer; // OID_GEN_RCV_NO_BUFFER
- u64 PdqFull; // Processed Data Queue Full
- u64 EventRingFull; // Event ring full
- // Verbose stats
- u64 MaxSends; // Max sends outstanding
- u64 NoSglBuf; // SGL buffer allocation failure
- u64 SglFail; // NDIS SGL failure
- u64 SglAsync; // NDIS SGL failure
- u64 NoMem; // Memory allocation failure
- u64 NumInts; // Interrupts
- u64 FalseInts; // Interrupt with ISR == 0
- u64 XmtDrops; // No sahara DRAM buffer for xmt
- // Sahara receive status
- u64 TransportCsum; // SXG_RCV_STATUS_TRANSPORT_CSUM
- u64 TransportUflow; // SXG_RCV_STATUS_TRANSPORT_UFLOW
- u64 TransportHdrLen; // SXG_RCV_STATUS_TRANSPORT_HDRLEN
- u64 NetworkCsum; // SXG_RCV_STATUS_NETWORK_CSUM:
- u64 NetworkUflow; // SXG_RCV_STATUS_NETWORK_UFLOW:
- u64 NetworkHdrLen; // SXG_RCV_STATUS_NETWORK_HDRLEN:
- u64 Parity; // SXG_RCV_STATUS_PARITY
- u64 LinkParity; // SXG_RCV_STATUS_LINK_PARITY:
- u64 LinkEarly; // SXG_RCV_STATUS_LINK_EARLY:
- u64 LinkBufOflow; // SXG_RCV_STATUS_LINK_BUFOFLOW:
- u64 LinkCode; // SXG_RCV_STATUS_LINK_CODE:
- u64 LinkDribble; // SXG_RCV_STATUS_LINK_DRIBBLE:
- u64 LinkCrc; // SXG_RCV_STATUS_LINK_CRC:
- u64 LinkOflow; // SXG_RCV_STATUS_LINK_OFLOW:
- u64 LinkUflow; // SXG_RCV_STATUS_LINK_UFLOW:
+#define SLIC_DUMP_ENABLED 0
+
+#define SXG_DRV_NAME "sxg" /* TBD: This might be removed eventually */
+#define SXG_DRV_VERSION "1.0.1"
+
+extern char sxg_driver_name[];
+
+#define SXG_NETDEV_WEIGHT 64
+
+/*
+ * struct sxg_stats - Probably move these to someplace where
+ * the slicstat (sxgstat?) program can get them.
+ */
+struct sxg_stats {
+ /* Xmt */
+ u64 DumbXmtUcastPkts; /* directed packets */
+ u64 DumbXmtMcastPkts; /* Multicast packets */
+ u64 DumbXmtBcastPkts; /* OID_GEN_BROADCAST_FRAMES_RCV */
+ u64 DumbXmtUcastBytes; /* OID_GEN_DIRECTED_BYTES_XMIT */
+ u64 DumbXmtMcastBytes; /* OID_GEN_MULTICAST_BYTES_XMIT */
+ u64 DumbXmtBcastBytes; /* OID_GEN_BROADCAST_BYTES_XMIT */
+ u64 XmtQLen; /* OID_GEN_TRANSMIT_QUEUE_LENGTH */
+ u64 XmtZeroFull; /* Transmit ring zero full */
+ /* Rcv */
+ u64 DumbRcvUcastBytes; /* OID_GEN_DIRECTED_BYTES_RCV */
+ u64 DumbRcvMcastBytes; /* OID_GEN_MULTICAST_BYTES_RCV */
+ u64 DumbRcvBcastBytes; /* OID_GEN_BROADCAST_BYTES_RCV */
+ u64 DumbRcvUcastPkts; /* directed packets */
+ u64 DumbRcvMcastPkts; /* Multicast packets */
+ u64 DumbRcvBcastPkts; /* OID_GEN_BROADCAST_FRAMES_RCV */
+ u64 PdqFull; /* Processed Data Queue Full */
+ u64 EventRingFull; /* Event ring full */
+ /* Verbose stats */
+ u64 NoSglBuf; /* SGL buffer allocation failure */
+ u64 NoMem; /* Memory allocation failure */
+ u64 NumInts; /* Interrupts */
+ u64 FalseInts; /* Interrupt with ISR == 0 */
+ /* Sahara receive status */
+ u64 TransportCsum; /* SXG_RCV_STATUS_TRANSPORT_CSUM */
+ u64 TransportUflow; /* SXG_RCV_STATUS_TRANSPORT_UFLOW */
+ u64 TransportHdrLen; /* SXG_RCV_STATUS_TRANSPORT_HDRLEN */
+ u64 NetworkCsum; /* SXG_RCV_STATUS_NETWORK_CSUM: */
+ u64 NetworkUflow; /* SXG_RCV_STATUS_NETWORK_UFLOW: */
+ u64 NetworkHdrLen; /* SXG_RCV_STATUS_NETWORK_HDRLEN: */
+ u64 Parity; /* SXG_RCV_STATUS_PARITY */
+ u64 LinkParity; /* SXG_RCV_STATUS_LINK_PARITY: */
+ u64 LinkEarly; /* SXG_RCV_STATUS_LINK_EARLY: */
+ u64 LinkBufOflow; /* SXG_RCV_STATUS_LINK_BUFOFLOW: */
+ u64 LinkCode; /* SXG_RCV_STATUS_LINK_CODE: */
+ u64 LinkDribble; /* SXG_RCV_STATUS_LINK_DRIBBLE: */
+ u64 LinkCrc; /* SXG_RCV_STATUS_LINK_CRC: */
+ u64 LinkOflow; /* SXG_RCV_STATUS_LINK_OFLOW: */
+ u64 LinkUflow; /* SXG_RCV_STATUS_LINK_UFLOW: */
};
-/****************************************************************************
- * DUMB-NIC Send path definitions
- ****************************************************************************/
+/* DUMB-NIC Send path definitions */
-#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb) { \
- ASSERT(_skb); \
- dev_kfree_skb_irq(_skb); \
+#define SXG_COMPLETE_DUMB_SEND(_pAdapt, _skb, _phys_addr, _size) { \
+ ASSERT(_skb); \
+ pci_unmap_single(_pAdapt->pcidev, _size, _phys_addr, PCI_DMA_TODEVICE); \
+ dev_kfree_skb_irq(_skb); \
}
-#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \
- ASSERT(_skb); \
- dev_kfree_skb(_skb); \
+#define SXG_DROP_DUMB_SEND(_pAdapt, _skb) { \
+ ASSERT(_skb); \
}
-// Locate current receive header buffer location. Use this
-// instead of RcvDataHdr->VirtualAddress since the data
-// may have been offset by SXG_ADVANCE_MDL_OFFSET
+/*
+ * Locate current receive header buffer location. Use this
+ * instead of RcvDataHdr->VirtualAddress since the data
+ * may have been offset by SXG_ADVANCE_MDL_OFFSET
+ */
#define SXG_RECEIVE_DATA_LOCATION(_RcvDataHdr) (_RcvDataHdr)->skb->data
-/************************************************************************
- * Dumb-NIC receive processing
- ************************************************************************/
-// Define an SXG_PACKET as an NDIS_PACKET
+/* Dumb-NIC receive processing */
+/* Define an SXG_PACKET as an NDIS_PACKET */
#define PSXG_PACKET struct sk_buff *
-// Indications array size
+/* Indications array size */
#define SXG_RCV_ARRAYSIZE 64
-#define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr) { \
- struct sk_buff * skb; \
- skb = alloc_skb(2048, GFP_ATOMIC); \
- if (skb) { \
- (_RcvDataBufferHdr)->skb = skb; \
- skb->next = NULL; \
- } else { \
- (_RcvDataBufferHdr)->skb = NULL; \
- } \
+#define SXG_ALLOCATE_RCV_PACKET(_pAdapt, _RcvDataBufferHdr, BufferSize) {\
+ struct sk_buff * skb; \
+ skb = netdev_alloc_skb(_pAdapt->netdev, BufferSize); \
+ if (skb) { \
+ (_RcvDataBufferHdr)->skb = skb; \
+ skb->next = NULL; \
+ _RcvDataBufferHdr->PhysicalAddress = pci_map_single(adapter->pcidev,\
+ _RcvDataBufferHdr->skb->data, BufferSize, PCI_DMA_FROMDEVICE); \
+ if (SXG_INVALID_SGL(_RcvDataBufferHdr->PhysicalAddress,BufferSize)) \
+ printk(KERN_EMERG "SXG_ALLOCATE_RCV_PACKET: RCV packet" \
+ "non-64k boundary aligned\n"); \
+ } else { \
+ (_RcvDataBufferHdr)->skb = NULL; \
+ } \
}
-#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) { \
- if((_RcvDataBufferHdr)->skb) { \
- dev_kfree_skb((_RcvDataBufferHdr)->skb); \
- } \
+#define SXG_FREE_RCV_PACKET(_RcvDataBufferHdr) { \
+ if((_RcvDataBufferHdr)->skb) { \
+ dev_kfree_skb((_RcvDataBufferHdr)->skb); \
+ } \
}
-// Macro to add a NDIS_PACKET to an indication array
-// If we fill up our array of packet pointers, then indicate this
-// block up now and start on a new one.
-#define SXG_ADD_RCV_PACKET(_pAdapt, _Packet, _PrevPacket, _IndicationList, _NumPackets) { \
- (_IndicationList)[_NumPackets] = (_Packet); \
- (_NumPackets)++; \
- if((_NumPackets) == SXG_RCV_ARRAYSIZE) { \
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \
- (_NumPackets), 0, 0, 0); \
- netif_rx((_IndicationList),(_NumPackets)); \
- (_NumPackets) = 0; \
- } \
+/*
+ * Macro to add a NDIS_PACKET to an indication array
+ * If we fill up our array of packet pointers, then indicate this
+ * block up now and start on a new one.
+ */
+#define SXG_ADD_RCV_PACKET(_pAdapt, _Packet, _PrevPacket, _IndicationList, \
+ _NumPackets) { \
+ (_IndicationList)[_NumPackets] = (_Packet); \
+ (_NumPackets)++; \
+ if((_NumPackets) == SXG_RCV_ARRAYSIZE) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \
+ (_NumPackets), 0, 0, 0); \
+ netif_rx((_IndicationList),(_NumPackets)); \
+ (_NumPackets) = 0; \
+ } \
}
-#define SXG_INDICATE_PACKETS(_pAdapt, _IndicationList, _NumPackets) { \
- if(_NumPackets) { \
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \
- (_NumPackets), 0, 0, 0); \
- netif_rx((_IndicationList),(_NumPackets)); \
- (_NumPackets) = 0; \
- } \
+#define SXG_INDICATE_PACKETS(_pAdapt, _IndicationList, _NumPackets) { \
+ if(_NumPackets) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "IndicRcv", \
+ (_NumPackets), 0, 0, 0); \
+ netif_rx((_IndicationList),(_NumPackets)); \
+ (_NumPackets) = 0; \
+ } \
}
-#define SXG_REINIATIALIZE_PACKET(_Packet) \
- {} /*_NdisReinitializePacket(_Packet)*/ /* this is not necessary with an skb */
+#define SXG_REINIATIALIZE_PACKET(_Packet) \
+ {} /*_NdisReinitializePacket(_Packet)*/
+ /* this is not necessary with an skb */
-// Definitions to initialize Dumb-nic Receive NBLs
-#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((PSXG_RCV_NBL_RESERVED)((_Packet)->MiniportReservedEx))->RcvDataBufferHdr)
+/* Definitions to initialize Dumb-nic Receive NBLs */
+#define SXG_RCV_PACKET_BUFFER_HDR(_Packet) (((struct sxg_rcv_nbl_reserved *)\
+ ((_Packet)->MiniportReservedEx))->RcvDataBufferHdr)
-#define SXG_RCV_SET_CHECKSUM_INFO(_Packet, _Cpi) \
- NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), TcpIpChecksumPacketInfo) = (PVOID)(_Cpi)
+#define SXG_RCV_SET_CHECKSUM_INFO(_Packet, _Cpi) \
+ NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), \
+ TcpIpChecksumPacketInfo) = (PVOID)(_Cpi)
#define SXG_RCV_SET_TOEPLITZ(_Packet, _Toeplitz, _Type, _Function) { \
- NDIS_PACKET_SET_HASH_VALUE((_Packet), (_Toeplitz)); \
- NDIS_PACKET_SET_HASH_TYPE((_Packet), (_Type)); \
- NDIS_PACKET_SET_HASH_FUNCTION((_Packet), (_Function)); \
+ NDIS_PACKET_SET_HASH_VALUE((_Packet), (_Toeplitz)); \
+ NDIS_PACKET_SET_HASH_TYPE((_Packet), (_Type)); \
+ NDIS_PACKET_SET_HASH_FUNCTION((_Packet), (_Function)); \
}
-#define SXG_RCV_SET_VLAN_INFO(_Packet, _VlanId, _Priority) { \
- NDIS_PACKET_8021Q_INFO _Packet8021qInfo; \
- _Packet8021qInfo.TagHeader.VlanId = (_VlanId); \
- _Packet8021qInfo.TagHeader.UserPriority = (_Priority); \
+#define SXG_RCV_SET_VLAN_INFO(_Packet, _VlanId, _Priority) { \
+ NDIS_PACKET_8021Q_INFO _Packet8021qInfo; \
+ _Packet8021qInfo.TagHeader.VlanId = (_VlanId); \
+ _Packet8021qInfo.TagHeader.UserPriority = (_Priority); \
NDIS_PER_PACKET_INFO_FROM_PACKET((_Packet), Ieee8021QNetBufferListInfo) = \
- _Packet8021qInfo.Value; \
+ _Packet8021qInfo.Value; \
}
-#define SXG_ADJUST_RCV_PACKET(_Packet, _RcvDataBufferHdr, _Event) { \
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbRcv", \
- (_RcvDataBufferHdr), (_Packet), \
- (_Event)->Status, 0); \
- ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size); \
- Packet->len = (_Event)->Length; \
+#define SXG_ADJUST_RCV_PACKET(_Packet, _RcvDataBufferHdr, _Event) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "DumbRcv", \
+ (_RcvDataBufferHdr), (_Packet), \
+ (_Event)->Status, 0); \
+ /* ASSERT((_Event)->Length <= (_RcvDataBufferHdr)->Size); */ \
+ skb_put(Packet, (_Event)->Length); \
}
-///////////////////////////////////////////////////////////////////////////////
-// Macros to free a receive data buffer and receive data descriptor block
-///////////////////////////////////////////////////////////////////////////////
-// NOTE - Lock must be held with RCV macros
-#define SXG_GET_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \
- struct LIST_ENTRY *_ple; \
- _Hdr = NULL; \
- if((_pAdapt)->FreeRcvBufferCount) { \
- ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers))); \
- _ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers); \
- (_Hdr) = container_of(_ple, struct SXG_RCV_DATA_BUFFER_HDR, FreeList); \
- (_pAdapt)->FreeRcvBufferCount--; \
- ASSERT((_Hdr)->State == SXG_BUFFER_FREE); \
- } \
+/*
+ * Macros to free a receive data buffer and receive data descriptor block
+ * NOTE - Lock must be held with RCV macros
+ */
+#define SXG_GET_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \
+ struct list_entry *_ple; \
+ _Hdr = NULL; \
+ if((_pAdapt)->FreeRcvBufferCount) { \
+ ASSERT(!(IsListEmpty(&(_pAdapt)->FreeRcvBuffers))); \
+ _ple = RemoveHeadList(&(_pAdapt)->FreeRcvBuffers); \
+ (_Hdr) = container_of(_ple, struct sxg_rcv_data_buffer_hdr, \
+ FreeList); \
+ (_pAdapt)->FreeRcvBufferCount--; \
+ ASSERT((_Hdr)->State == SXG_BUFFER_FREE); \
+ } \
}
-#define SXG_FREE_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \
- SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr", \
- (_Hdr), (_pAdapt)->FreeRcvBufferCount, \
- (_Hdr)->State, (_Hdr)->VirtualAddress); \
-/* SXG_RESTORE_MDL_OFFSET(_Hdr); */ \
- (_pAdapt)->FreeRcvBufferCount++; \
- ASSERT(((_pAdapt)->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK) >= (_pAdapt)->FreeRcvBufferCount); \
- ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \
- (_Hdr)->State = SXG_BUFFER_FREE; \
- InsertTailList(&(_pAdapt)->FreeRcvBuffers, &((_Hdr)->FreeList)); \
+#define SXG_FREE_RCV_DATA_BUFFER(_pAdapt, _Hdr) { \
+ SXG_TRACE(TRACE_SXG, SxgTraceBuffer, TRACE_NOISY, "RtnDHdr", \
+ (_Hdr), (_pAdapt)->FreeRcvBufferCount, \
+ (_Hdr)->State, 0/*(_Hdr)->VirtualAddress*/); \
+/* SXG_RESTORE_MDL_OFFSET(_Hdr); */ \
+ (_pAdapt)->FreeRcvBufferCount++; \
+ ASSERT(((_pAdapt)->AllRcvBlockCount * SXG_RCV_DESCRIPTORS_PER_BLOCK) \
+ >= (_pAdapt)->FreeRcvBufferCount); \
+ ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \
+ (_Hdr)->State = SXG_BUFFER_FREE; \
+ InsertTailList(&(_pAdapt)->FreeRcvBuffers, &((_Hdr)->FreeList)); \
}
-#define SXG_FREE_RCV_DESCRIPTOR_BLOCK(_pAdapt, _Hdr) { \
- ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \
- (_Hdr)->State = SXG_BUFFER_FREE; \
- (_pAdapt)->FreeRcvBlockCount++; \
+#define SXG_FREE_RCV_DESCRIPTOR_BLOCK(_pAdapt, _Hdr) { \
+ ASSERT((_Hdr)->State != SXG_BUFFER_FREE); \
+ (_Hdr)->State = SXG_BUFFER_FREE; \
+ (_pAdapt)->FreeRcvBlockCount++; \
ASSERT((_pAdapt)->AllRcvBlockCount >= (_pAdapt)->FreeRcvBlockCount); \
- InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList); \
+ InsertTailList(&(_pAdapt)->FreeRcvBlocks, &(_Hdr)->FreeList); \
}
-// SGL macros
-#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) { \
- spin_lock(&(_pAdapt)->SglQLock); \
- (_pAdapt)->FreeSglBufferCount++; \
- ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount);\
- ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE)); \
- (_Sgl)->State = SXG_BUFFER_FREE; \
- InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList); \
- spin_unlock(&(_pAdapt)->SglQLock); \
+/* SGL macros */
+#define SXG_FREE_SGL_BUFFER(_pAdapt, _Sgl, _NB) { \
+ spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
+ (_pAdapt)->FreeSglBufferCount++; \
+ ASSERT((_pAdapt)->AllSglBufferCount >= (_pAdapt)->FreeSglBufferCount); \
+ ASSERT(!((_Sgl)->State & SXG_BUFFER_FREE)); \
+ (_Sgl)->State = SXG_BUFFER_FREE; \
+ InsertTailList(&(_pAdapt)->FreeSglBuffers, &(_Sgl)->FreeList); \
+ spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags); \
}
-// Get an SGL buffer from the free queue. The first part of this macro
-// attempts to keep ahead of buffer depletion by allocating more when
-// we hit a minimum threshold. Note that we don't grab the lock
-// until after that. We're dealing with round numbers here, so we don't need to,
-// and not grabbing it avoids a possible double-trip.
-#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl) { \
- struct LIST_ENTRY *_ple; \
+/*
+ * Get an SGL buffer from the free queue. The first part of this macro
+ * attempts to keep ahead of buffer depletion by allocating more when
+ * we hit a minimum threshold. Note that we don't grab the lock
+ * until after that. We're dealing with round numbers here, so we don't need to,
+ * and not grabbing it avoids a possible double-trip.
+ */
+#define SXG_GET_SGL_BUFFER(_pAdapt, _Sgl, _irq) { \
+ struct list_entry *_ple; \
if ((_pAdapt->FreeSglBufferCount < SXG_MIN_SGL_BUFFERS) && \
(_pAdapt->AllSglBufferCount < SXG_MAX_SGL_BUFFERS) && \
- (_pAdapt->AllocationsPending == 0)) { \
+ (atomic_read(&_pAdapt->pending_allocations) == 0)) { \
sxg_allocate_buffer_memory(_pAdapt, \
- (sizeof(struct SXG_SCATTER_GATHER) + SXG_SGL_BUF_SIZE),\
+ (sizeof(struct sxg_scatter_gather) + SXG_SGL_BUF_SIZE),\
SXG_BUFFER_TYPE_SGL); \
} \
_Sgl = NULL; \
- spin_lock(&(_pAdapt)->SglQLock); \
+ if(!_irq) \
+ spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
+ else \
+ spin_lock_irqsave(&(_pAdapt)->SglQLock, sgl_flags); \
if((_pAdapt)->FreeSglBufferCount) { \
ASSERT(!(IsListEmpty(&(_pAdapt)->FreeSglBuffers))); \
_ple = RemoveHeadList(&(_pAdapt)->FreeSglBuffers); \
- (_Sgl) = container_of(_ple, struct SXG_SCATTER_GATHER, FreeList); \
+ (_Sgl) = container_of(_ple, struct sxg_scatter_gather, \
+ FreeList); \
(_pAdapt)->FreeSglBufferCount--; \
ASSERT((_Sgl)->State == SXG_BUFFER_FREE); \
(_Sgl)->State = SXG_BUFFER_BUSY; \
(_Sgl)->pSgl = NULL; \
} \
- spin_unlock(&(_pAdapt)->SglQLock); \
+ if(!_irq) \
+ spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
+ else \
+ spin_unlock_irqrestore(&(_pAdapt)->SglQLock, sgl_flags);\
}
-//
-// SXG_MULTICAST_ADDRESS
-//
-// Linked list of multicast addresses.
-struct SXG_MULTICAST_ADDRESS {
- unsigned char Address[6];
- struct SXG_MULTICAST_ADDRESS *Next;
+/*
+ * struct sxg_multicast_address
+ * Linked list of multicast addresses.
+ */
+struct sxg_multicast_address {
+ unsigned char Address[6];
+ struct sxg_multicast_address *Next;
};
-// Structure to maintain chimney send and receive buffer queues.
-// This structure maintains NET_BUFFER_LIST queues that are
-// given to us via the Chimney MiniportTcpOffloadSend and
-// MiniportTcpOffloadReceive routines. This structure DOES NOT
-// manage our data buffer queue
-struct SXG_BUFFER_QUEUE {
- u32 Type; // Slow or fast - See below
- u32 Direction; // Xmt or Rcv
- u32 Bytes; // Byte count
- u32 * Head; // Send queue head
- u32 * Tail; // Send queue tail
-// PNET_BUFFER_LIST NextNBL; // Short cut - next NBL
-// PNET_BUFFER NextNB; // Short cut - next NB
+/*
+ * Structure to maintain chimney send and receive buffer queues.
+ * This structure maintains NET_BUFFER_LIST queues that are
+ * given to us via the Chimney MiniportTcpOffloadSend and
+ * MiniportTcpOffloadReceive routines. This structure DOES NOT
+ * manage our data buffer queue
+ */
+struct sxg_buffer_queue {
+ u32 Type; /* Slow or fast - See below */
+ u32 Direction; /* Xmt or Rcv */
+ u32 Bytes; /* Byte count */
+ u32 * Head; /* Send queue head */
+ u32 * Tail; /* Send queue tail */
+/* PNET_BUFFER_LIST NextNBL;*/ /* Short cut - next NBL */
+/* PNET_BUFFER NextNB; */ /* Short cut - next NB */
};
#define SXG_SLOW_SEND_BUFFER 0
#define SXG_FAST_SEND_BUFFER 1
#define SXG_RECEIVE_BUFFER 2
-#define SXG_INIT_BUFFER(_Buffer, _Type) { \
- (_Buffer)->Type = (_Type); \
- if((_Type) == SXG_RECEIVE_BUFFER) { \
- (_Buffer)->Direction = 0; \
- } else { \
+#define SXG_INIT_BUFFER(_Buffer, _Type) { \
+ (_Buffer)->Type = (_Type); \
+ if((_Type) == SXG_RECEIVE_BUFFER) { \
+ (_Buffer)->Direction = 0; \
+ } else { \
(_Buffer)->Direction = NDIS_SG_LIST_WRITE_TO_DEVICE; \
- } \
- (_Buffer)->Bytes = 0; \
- (_Buffer)->Head = NULL; \
- (_Buffer)->Tail = NULL; \
+ } \
+ (_Buffer)->Bytes = 0; \
+ (_Buffer)->Head = NULL; \
+ (_Buffer)->Tail = NULL; \
}
-#define SXG_RSS_CPU_COUNT(_pAdapt) \
+#define SXG_RSS_CPU_COUNT(_pAdapt) \
((_pAdapt)->RssEnabled ? NR_CPUS : 1)
-/****************************************************************************
- * DRIVER and ADAPTER structures
- ****************************************************************************/
+/* DRIVER and ADAPTER structures */
-// Adapter states - These states closely match the adapter states
-// documented in the DDK (with a few exceptions).
+/*
+ * Adapter states - These states closely match the adapter states
+ * documented in the DDK (with a few exceptions).
+ */
enum SXG_STATE {
- SXG_STATE_INITIALIZING, // Initializing
- SXG_STATE_BOOTDIAG, // Boot-Diagnostic mode
- SXG_STATE_PAUSING, // Pausing
- SXG_STATE_PAUSED, // Paused
- SXG_STATE_RUNNING, // Running
- SXG_STATE_RESETTING, // Reset in progress
- SXG_STATE_SLEEP, // Sleeping
- SXG_STATE_DIAG, // Diagnostic mode
- SXG_STATE_HALTING, // Halting
- SXG_STATE_HALTED, // Down or not-initialized
- SXG_STATE_SHUTDOWN // shutdown
+ SXG_STATE_INITIALIZING, /* Initializing */
+ SXG_STATE_BOOTDIAG, /* Boot-Diagnostic mode */
+ SXG_STATE_PAUSING, /* Pausing */
+ SXG_STATE_PAUSED, /* Paused */
+ SXG_STATE_RUNNING, /* Running */
+ SXG_STATE_RESETTING, /* Reset in progress */
+ SXG_STATE_SLEEP, /* Sleeping */
+ SXG_STATE_DIAG, /* Diagnostic mode */
+ SXG_STATE_HALTING, /* Halting */
+ SXG_STATE_HALTED, /* Down or not-initialized */
+ SXG_STATE_SHUTDOWN /* shutdown */
};
-// Link state
+/* Link state */
enum SXG_LINK_STATE {
SXG_LINK_DOWN,
SXG_LINK_UP
};
-// Link initialization timeout in 100us units
-#define SXG_LINK_TIMEOUT 100000 // 10 Seconds - REDUCE!
+/* Link initialization timeout in 100us units */
+#define SXG_LINK_TIMEOUT 100000 /* 10 Seconds - REDUCE! */
-// Microcode file selection codes
+/* Microcode file selection codes */
enum SXG_UCODE_SEL {
- SXG_UCODE_SAHARA, // Sahara ucode
- SXG_UCODE_SDIAGCPU, // Sahara CPU diagnostic ucode
- SXG_UCODE_SDIAGSYS // Sahara system diagnostic ucode
+ SXG_UCODE_SYSTEM, /* System (operational) uucode */
+ SXG_UCODE_SDIAGCPU, /* System CPU diagnostic ucode */
+ SXG_UCODE_SDIAGSYS /* System diagnostic ucode */
};
#define SXG_DISABLE_ALL_INTERRUPTS(_padapt) sxg_disable_interrupt(_padapt)
#define SXG_ENABLE_ALL_INTERRUPTS(_padapt) sxg_enable_interrupt(_padapt)
-// This probably lives in a proto.h file. Move later
+/* This probably lives in a proto.h file. Move later */
#define SXG_MULTICAST_PACKET(_pether) ((_pether)->ether_dhost[0] & 0x01)
-#define SXG_BROADCAST_PACKET(_pether) ((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && \
- (*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF))
+#define SXG_BROADCAST_PACKET(_pether) \
+ ((*(u32 *)(_pether)->ether_dhost == 0xFFFFFFFF) && \
+ (*(u16 *)&(_pether)->ether_dhost[4] == 0xFFFF))
-// For DbgPrints
+/* For DbgPrints */
#define SXG_ID DPFLTR_IHVNETWORK_ID
#define SXG_ERROR DPFLTR_ERROR_LEVEL
-//
-// SXG_DRIVER structure -
-//
-// contains information about the sxg driver. There is only
-// one of these, and it is defined as a global.
-struct SXG_DRIVER {
- struct adapter_t *Adapters; // Linked list of adapters
- ushort AdapterID; // Maintain unique adapter ID
+/*
+ * struct sxg_driver structure -
+ *
+ * contains information about the sxg driver. There is only
+ * one of these, and it is defined as a global.
+ */
+
+struct sxg_driver {
+ struct adapter_t *Adapters; /* Linked list of adapters */
+ ushort AdapterID; /* Maintain unique adapter ID */
};
#ifdef STATUS_SUCCESS
#undef STATUS_SUCCESS
#endif
+/* TODO: We need to try and use NETDEV_TX_* before posting this out */
#define STATUS_SUCCESS 0
#define STATUS_PENDING 0
#define STATUS_FAILURE -1
@@ -404,34 +416,36 @@ struct SXG_DRIVER {
#define SLIC_MAX_CARDS 32
#define SLIC_MAX_PORTS 4 /* Max # of ports per card */
#if SLIC_DUMP_ENABLED
-// Dump buffer size
-//
-// This cannot be bigger than the max DMA size the card supports,
-// given the current code structure in the host and ucode.
-// Mojave supports 16K, Oasis supports 16K-1, so
-// just set this at 15K, shouldnt make that much of a diff.
-#define DUMP_BUF_SIZE 0x3C00
+
+/*
+ * Dump buffer size
+ * This cannot be bigger than the max DMA size the card supports,
+ * given the current code structure in the host and ucode.
+ * Mojave supports 16K, Oasis supports 16K-1, so
+ * just set this at 15K, shouldnt make that much of a diff.
+ */
+#define DUMP_BUF_SIZE 0x3C00
#endif
#define MIN(a, b) ((u32)(a) < (u32)(b) ? (a) : (b))
#define MAX(a, b) ((u32)(a) > (u32)(b) ? (a) : (b))
-struct mcast_address_t {
- unsigned char address[6];
- struct mcast_address_t *next;
+struct mcast_address {
+ unsigned char address[6];
+ struct mcast_address *next;
};
-#define CARD_DOWN 0x00000000
-#define CARD_UP 0x00000001
-#define CARD_FAIL 0x00000002
-#define CARD_DIAG 0x00000003
-#define CARD_SLEEP 0x00000004
+#define CARD_DOWN 0x00000000
+#define CARD_UP 0x00000001
+#define CARD_FAIL 0x00000002
+#define CARD_DIAG 0x00000003
+#define CARD_SLEEP 0x00000004
-#define ADAPT_DOWN 0x00
-#define ADAPT_UP 0x01
-#define ADAPT_FAIL 0x02
-#define ADAPT_RESET 0x03
-#define ADAPT_SLEEP 0x04
+#define ADAPT_DOWN 0x00
+#define ADAPT_UP 0x01
+#define ADAPT_FAIL 0x02
+#define ADAPT_RESET 0x03
+#define ADAPT_SLEEP 0x04
#define ADAPT_FLAGS_BOOTTIME 0x0001
#define ADAPT_FLAGS_IS64BIT 0x0002
@@ -443,29 +457,30 @@ struct mcast_address_t {
#define ADAPT_FLAGS_STATS_TIMER_SET 0x0080
#define ADAPT_FLAGS_RESET_TIMER_SET 0x0100
-#define LINK_DOWN 0x00
-#define LINK_CONFIG 0x01
-#define LINK_UP 0x02
+#define LINK_DOWN 0x00
+#define LINK_CONFIG 0x01
+#define LINK_UP 0x02
-#define LINK_10MB 0x00
-#define LINK_100MB 0x01
-#define LINK_AUTOSPEED 0x02
-#define LINK_1000MB 0x03
-#define LINK_10000MB 0x04
+#define LINK_10MB 0x00
+#define LINK_100MB 0x01
+#define LINK_AUTOSPEED 0x02
+#define LINK_1000MB 0x03
+#define LINK_10000MB 0x04
-#define LINK_HALFD 0x00
-#define LINK_FULLD 0x01
-#define LINK_AUTOD 0x02
+#define LINK_HALFD 0x00
+#define LINK_FULLD 0x01
+#define LINK_AUTOD 0x02
-#define MAC_DIRECTED 0x00000001
-#define MAC_BCAST 0x00000002
-#define MAC_MCAST 0x00000004
-#define MAC_PROMISC 0x00000008
-#define MAC_LOOPBACK 0x00000010
-#define MAC_ALLMCAST 0x00000020
+#define MAC_DIRECTED 0x00000001
+#define MAC_BCAST 0x00000002
+#define MAC_MCAST 0x00000004
+#define MAC_PROMISC 0x00000008
+#define MAC_LOOPBACK 0x00000010
+#define MAC_ALLMCAST 0x00000020
#define SLIC_DUPLEX(x) ((x==LINK_FULLD) ? "FDX" : "HDX")
-#define SLIC_SPEED(x) ((x==LINK_100MB) ? "100Mb" : ((x==LINK_1000MB) ? "1000Mb" : " 10Mb"))
+#define SLIC_SPEED(x) ((x==LINK_100MB) ? "100Mb" : \
+ ((x==LINK_1000MB) ? "1000Mb" : " 10Mb"))
#define SLIC_LINKSTATE(x) ((x==LINK_DOWN) ? "Down" : "Up ")
#define SLIC_ADAPTER_STATE(x) ((x==ADAPT_UP) ? "UP" : "Down")
#define SLIC_CARD_STATE(x) ((x==CARD_UP) ? "UP" : "Down")
@@ -481,32 +496,36 @@ struct ether_header {
#define NUM_CFG_SPACES 2
#define NUM_CFG_REGS 64
-struct physcard_t {
- struct adapter_t *adapter[SLIC_MAX_PORTS];
- struct physcard_t *next;
+/*
+ * We split LSS sends across four microcode queues derived from
+ * destination TCP port (if TCP/IP).
+ */
+#define SXG_LARGE_SEND_QUEUE_MASK 0x3
+#define ISCSI_PORT 0xbc0c /* 3260 */
+
+struct physcard {
+ struct adapter_t *adapter[SLIC_MAX_PORTS];
+ struct physcard *next;
unsigned int adapters_allocd;
};
-struct sxgbase_driver_t {
+struct sxgbase_driver {
spinlock_t driver_lock;
unsigned long flags; /* irqsave for spinlock */
u32 num_sxg_cards;
u32 num_sxg_ports;
u32 num_sxg_ports_active;
u32 dynamic_intagg;
- struct physcard_t *phys_card;
+ struct physcard *phys_card;
};
struct adapter_t {
void * ifp;
unsigned int port;
- struct physcard_t *physcard;
+ struct napi_struct napi;
+ struct physcard *physcard;
unsigned int physport;
- unsigned int cardindex;
- unsigned int card_size;
- unsigned int chipid;
- unsigned int busnumber;
unsigned int slotnumber;
unsigned int functionnumber;
ushort vendid;
@@ -514,32 +533,23 @@ struct adapter_t {
ushort subsysid;
u32 irq;
- void * sxg_adapter;
- u32 nBusySend;
-
void __iomem * base_addr;
u32 memorylength;
u32 drambase;
u32 dramlength;
- unsigned int queues_initialized;
- unsigned int allocated;
+ enum asic_type asictype; /* type of ASIC (chip) */
unsigned int activated;
u32 intrregistered;
unsigned int isp_initialized;
- unsigned int gennumber;
- u32 curaddrupper;
- u32 isrcopy;
unsigned char state;
unsigned char linkstate;
- unsigned char linkspeed;
- unsigned char linkduplex;
unsigned int flags;
unsigned char macaddr[6];
unsigned char currmacaddr[6];
u32 macopts;
ushort devflags_prev;
u64 mcastmask;
- struct mcast_address_t *mcastaddrs;
+ struct mcast_address *mcastaddrs;
struct timer_list pingtimer;
u32 pingtimerset;
struct timer_list statstimer;
@@ -574,135 +584,140 @@ struct adapter_t {
u32 rcv_interrupt_yields;
u32 intagg_period;
struct net_device_stats stats;
- u32 * MiniportHandle; // Our miniport handle
- enum SXG_STATE State; // Adapter state
- enum SXG_LINK_STATE LinkState; // Link state
- u64 LinkSpeed; // Link Speed
- u32 PowerState; // NDIS power state
- struct adapter_t *Next; // Linked list
- ushort AdapterID; // 1..n
- unsigned char MacAddr[6]; // Our permanent HW mac address
- unsigned char CurrMacAddr[6]; // Our Current mac address
- p_net_device netdev;
- p_net_device next_netdevice;
- struct pci_dev * pcidev;
-
- struct SXG_MULTICAST_ADDRESS *MulticastAddrs; // Multicast list
- u64 MulticastMask; // Multicast mask
- u32 * InterruptHandle; // Register Interrupt handle
- u32 InterruptLevel; // From Resource list
- u32 InterruptVector; // From Resource list
- spinlock_t AdapterLock; /* Serialize access adapter routines */
- spinlock_t Bit64RegLock; /* For writing 64-bit addresses */
- struct SXG_HW_REGS *HwRegs; // Sahara HW Register Memory (BAR0/1)
- struct SXG_UCODE_REGS *UcodeRegs; // Microcode Register Memory (BAR2/3)
- struct SXG_TCB_REGS *TcbRegs; // Same as Ucode regs - See sxghw.h
- ushort ResetDpcCount; // For timeout
- ushort RssDpcCount; // For timeout
- ushort VendorID; // Vendor ID
- ushort DeviceID; // Device ID
- ushort SubSystemID; // Sub-System ID
- ushort FrameSize; // Maximum frame size
- u32 * DmaHandle; // NDIS DMA handle
- u32 * PacketPoolHandle; // Used with NDIS 5.2 only. Don't ifdef out
- u32 * BufferPoolHandle; // Used with NDIS 5.2 only. Don't ifdef out
- u32 MacFilter; // NDIS MAC Filter
- ushort IpId; // For slowpath
- struct SXG_EVENT_RING *EventRings; // Host event rings. 1/CPU to 16 max
- dma_addr_t PEventRings; // Physical address
- u32 NextEvent[SXG_MAX_RSS]; // Current location in ring
- dma_addr_t PTcbBuffers; // TCB Buffers - physical address
- dma_addr_t PTcbCompBuffers; // TCB Composite Buffers - phys addr
- struct SXG_XMT_RING *XmtRings; // Transmit rings
- dma_addr_t PXmtRings; // Transmit rings - physical address
- struct SXG_RING_INFO XmtRingZeroInfo; // Transmit ring 0 info
+ u32 * MiniportHandle; /* Our miniport handle */
+ enum SXG_STATE State; /* Adapter state */
+ enum SXG_LINK_STATE LinkState; /* Link state */
+ u64 LinkSpeed; /* Link Speed */
+ u32 PowerState; /* NDIS power state */
+ struct adapter_t *Next; /* Linked list */
+ ushort AdapterID; /* 1..n */
+ struct net_device * netdev;
+ struct net_device * next_netdevice;
+ struct pci_dev *pcidev;
+
+ struct sxg_multicast_address *MulticastAddrs; /* Multicast list */
+ u64 MulticastMask; /* Multicast mask */
+ u32 *InterruptHandle; /* Register Interrupt handle */
+ u32 InterruptLevel; /* From Resource list */
+ u32 InterruptVector; /* From Resource list */
+ spinlock_t AdapterLock; /* Serialize access adapter routines */
+ spinlock_t Bit64RegLock; /* For writing 64-bit addresses */
+ struct sxg_hw_regs *HwRegs; /* Sahara HW Register Memory (BAR0/1) */
+ struct sxg_ucode_regs *UcodeRegs; /* Microcode Register Memory (BAR2/3) */
+ struct sxg_tcb_regs *TcbRegs; /* Same as Ucode regs - See sxghw.h */
+ ushort FrameSize; /* Maximum frame size */
+ u32 * DmaHandle; /* NDIS DMA handle */
+ u32 * PacketPoolHandle; /* Used with NDIS 5.2 only. Don't ifdef out */
+ u32 * BufferPoolHandle; /* Used with NDIS 5.2 only. Don't ifdef out */
+ u32 MacFilter; /* NDIS MAC Filter */
+ struct sxg_event_ring *EventRings; /* Host event rings. 1/CPU to 16 max */
+ dma_addr_t PEventRings; /* Physical address */
+ u32 NextEvent[SXG_MAX_RSS]; /* Current location in ring */
+ dma_addr_t PTcbBuffers; /* TCB Buffers - physical address */
+ dma_addr_t PTcbCompBuffers; /* TCB Composite Buffers - phys addr */
+ struct sxg_xmt_ring *XmtRings; /* Transmit rings */
+ dma_addr_t PXmtRings; /* Transmit rings - physical address */
+ struct sxg_ring_info XmtRingZeroInfo; /* Transmit ring 0 info */
+
spinlock_t XmtZeroLock; /* Transmit ring 0 lock */
- u32 * XmtRingZeroIndex; // Shared XMT ring 0 index
- dma_addr_t PXmtRingZeroIndex; // Shared XMT ring 0 index - physical
- struct LIST_ENTRY FreeProtocolHeaders;// Free protocol headers
- u32 FreeProtoHdrCount; // Count
- void * ProtocolHeaders; // Block of protocol header
- dma_addr_t PProtocolHeaders; // Block of protocol headers - phys
-
- struct SXG_RCV_RING *RcvRings; // Receive rings
- dma_addr_t PRcvRings; // Receive rings - physical address
- struct SXG_RING_INFO RcvRingZeroInfo; // Receive ring 0 info
-
- u32 * Isr; // Interrupt status register
- dma_addr_t PIsr; // ISR - physical address
- u32 IsrCopy[SXG_MAX_RSS]; // Copy of ISR
- ushort InterruptsEnabled; // Bitmask of enabled vectors
- unsigned char * IndirectionTable; // RSS indirection table
- dma_addr_t PIndirectionTable; // Physical address
- ushort RssTableSize; // From NDIS_RECEIVE_SCALE_PARAMETERS
- ushort HashKeySize; // From NDIS_RECEIVE_SCALE_PARAMETERS
- unsigned char HashSecretKey[40]; // rss key
- u32 HashInformation;
- // Receive buffer queues
- spinlock_t RcvQLock; /* Receive Queue Lock */
- struct LIST_ENTRY FreeRcvBuffers; // Free SXG_DATA_BUFFER queue
- struct LIST_ENTRY FreeRcvBlocks; // Free SXG_RCV_DESCRIPTOR_BLOCK Q
- struct LIST_ENTRY AllRcvBlocks; // All SXG_RCV_BLOCKs
- ushort FreeRcvBufferCount; // Number of free rcv data buffers
- ushort FreeRcvBlockCount; // # of free rcv descriptor blocks
- ushort AllRcvBlockCount; // Number of total receive blocks
- ushort ReceiveBufferSize; // SXG_RCV_DATA/JUMBO_BUFFER_SIZE only
- u32 AllocationsPending; // Receive allocation pending
- u32 RcvBuffersOnCard; // SXG_DATA_BUFFERS owned by card
- // SGL buffers
+ u32 * XmtRingZeroIndex; /* Shared XMT ring 0 index */
+ dma_addr_t PXmtRingZeroIndex; /* Shared XMT ring 0 index - physical */
+ struct list_entry FreeProtocolHeaders;/* Free protocol headers */
+ u32 FreeProtoHdrCount; /* Count */
+ void * ProtocolHeaders; /* Block of protocol header */
+ dma_addr_t PProtocolHeaders; /* Block of protocol headers - phys */
+
+ struct sxg_rcv_ring *RcvRings; /* Receive rings */
+ dma_addr_t PRcvRings; /* Receive rings - physical address */
+ struct sxg_ucode_stats *ucode_stats; /* Ucode Stats */
+ /* Ucode Stats - physical address */
+ dma_addr_t pucode_stats;
+
+ struct sxg_ring_info RcvRingZeroInfo; /* Receive ring 0 info */
+
+ u32 * Isr; /* Interrupt status register */
+ dma_addr_t PIsr; /* ISR - physical address */
+ u32 IsrCopy[SXG_MAX_RSS]; /* Copy of ISR */
+ ushort InterruptsEnabled; /* Bitmask of enabled vectors */
+ unsigned char *IndirectionTable; /* RSS indirection table */
+ dma_addr_t PIndirectionTable; /* Physical address */
+ ushort RssTableSize; /* From NDIS_RECEIVE_SCALE_PARAMETERS */
+ ushort HashKeySize; /* From NDIS_RECEIVE_SCALE_PARAMETERS */
+ unsigned char HashSecretKey[40]; /* rss key */
+ u32 HashInformation;
+ /* Receive buffer queues */
+ spinlock_t RcvQLock; /* Receive Queue Lock */
+ struct list_entry FreeRcvBuffers; /* Free SXG_DATA_BUFFER queue */
+ struct list_entry FreeRcvBlocks; /* Free SXG_RCV_DESCRIPTOR_BLOCK Q */
+ struct list_entry AllRcvBlocks; /* All SXG_RCV_BLOCKs */
+ ushort FreeRcvBufferCount; /* Number of free rcv data buffers */
+ ushort FreeRcvBlockCount; /* # of free rcv descriptor blocks */
+ ushort AllRcvBlockCount; /* Number of total receive blocks */
+ ushort ReceiveBufferSize; /* SXG_RCV_DATA/JUMBO_BUFFER_SIZE only */
+ /* Converted this to a atomic variable
+ u32 AllocationsPending; */
+ atomic_t pending_allocations;
+ u32 AllocationsPending; /* Receive allocation pending */
+ u32 RcvBuffersOnCard; /* SXG_DATA_BUFFERS owned by card */
+ /* SGL buffers */
spinlock_t SglQLock; /* SGL Queue Lock */
- struct LIST_ENTRY FreeSglBuffers; // Free SXG_SCATTER_GATHER
- struct LIST_ENTRY AllSglBuffers; // All SXG_SCATTER_GATHER
- ushort FreeSglBufferCount; // Number of free SGL buffers
- ushort AllSglBufferCount; // Number of total SGL buffers
- u32 CurrentTime; // Tick count
- u32 FastpathConnections;// # of fastpath connections
- // Various single-bit flags:
- u32 BasicAllocations:1; // Locks and listheads
- u32 IntRegistered:1; // Interrupt registered
- u32 PingOutstanding:1; // Ping outstanding to card
- u32 Dead:1; // Card dead
- u32 DumpDriver:1; // OID_SLIC_DRIVER_DUMP request
- u32 DumpCard:1; // OID_SLIC_CARD_DUMP request
- u32 DumpCmdRunning:1; // Dump command in progress
- u32 DebugRunning:1; // AGDB debug in progress
- u32 JumboEnabled:1; // Jumbo frames enabled
- u32 MsiEnabled:1; // MSI interrupt enabled
- u32 RssEnabled:1; // RSS Enabled
- u32 FailOnBadEeprom:1; // Fail on Bad Eeprom
- u32 DiagStart:1; // Init adapter for diagnostic start
- // Stats
- u32 PendingRcvCount; // Outstanding rcv indications
- u32 PendingXmtCount; // Outstanding send requests
- struct SXG_STATS Stats; // Statistics
- u32 ReassBufs; // Number of reassembly buffers
- // Card Crash Info
- ushort CrashLocation; // Microcode crash location
- unsigned char CrashCpu; // Sahara CPU ID
- // Diagnostics
- // PDIAG_CMD DiagCmds; // List of free diagnostic commands
- // PDIAG_BUFFER DiagBuffers; // List of free diagnostic buffers
- // PDIAG_REQ DiagReqQ; // List of outstanding (asynchronous) diag requests
- // u32 DiagCmdTimeout; // Time out for diag cmds (seconds) XXXTODO - replace with SXG_PARAM var?
- // unsigned char DiagDmaDesc[DMA_CPU_CTXS]; // Free DMA descriptors bit field (32 CPU ctx * 8 DMA ctx)
-
- /////////////////////////////////////////////////////////////////////
- // Put preprocessor-conditional fields at the end so we don't
- // have to recompile sxgdbg everytime we reconfigure the driver
- /////////////////////////////////////////////////////////////////////
- void * PendingSetRss; // Pending RSS parameter change
- u32 IPv4HdrSize; // Shared 5.2/6.0 encap param
- unsigned char * InterruptInfo; // Allocated by us during AddDevice
+ struct list_entry FreeSglBuffers; /* Free struct sxg_scatter_gather */
+ struct list_entry AllSglBuffers; /* All struct sxg_scatter_gather */
+ ushort FreeSglBufferCount; /* Number of free SGL buffers */
+ ushort AllSglBufferCount; /* Number of total SGL buffers */
+ u32 CurrentTime; /* Tick count */
+ u32 FastpathConnections;/* # of fastpath connections */
+ /* Various single-bit flags: */
+ u32 BasicAllocations:1; /* Locks and listheads */
+ u32 IntRegistered:1; /* Interrupt registered */
+ u32 PingOutstanding:1; /* Ping outstanding to card */
+ u32 Dead:1; /* Card dead */
+ u32 DumpDriver:1; /* OID_SLIC_DRIVER_DUMP request */
+ u32 DumpCard:1; /* OID_SLIC_CARD_DUMP request */
+ u32 DumpCmdRunning:1; /* Dump command in progress */
+ u32 DebugRunning:1; /* AGDB debug in progress */
+ u32 JumboEnabled:1; /* Jumbo frames enabled */
+ u32 msi_enabled:1; /* MSI interrupt enabled */
+ u32 RssEnabled:1; /* RSS Enabled */
+ u32 FailOnBadEeprom:1; /* Fail on Bad Eeprom */
+ u32 DiagStart:1; /* Init adapter for diagnostic start */
+ u32 XmtFcEnabled:1;
+ u32 RcvFcEnabled:1;
+ /* Stats */
+ u32 PendingRcvCount; /* Outstanding rcv indications */
+ u32 PendingXmtCount; /* Outstanding send requests */
+ struct sxg_stats Stats; /* Statistics */
+ u32 ReassBufs; /* Number of reassembly buffers */
+ /* Card Crash Info */
+ ushort CrashLocation; /* Microcode crash location */
+ unsigned char CrashCpu; /* Sahara CPU ID */
+ /* Diagnostics */
+ /* PDIAG_CMD DiagCmds; */ /* List of free diagnostic commands */
+ /* PDIAG_BUFFER DiagBuffers; */ /* List of free diagnostic buffers */
+ /* PDIAG_REQ DiagReqQ; */ /* List of outstanding (asynchronous) diag requests */
+ /* u32 DiagCmdTimeout; */ /* Time out for diag cmds (seconds) XXXTODO - replace with SXG_PARAM var? */
+ /* unsigned char DiagDmaDesc[DMA_CPU_CTXS]; */ /* Free DMA descriptors bit field (32 CPU ctx * 8 DMA ctx) */
+ /*
+ * Put preprocessor-conditional fields at the end so we don't
+ * have to recompile sxgdbg everytime we reconfigure the driver
+ */
#if defined(CONFIG_X86)
- u32 AddrUpper; // Upper 32 bits of 64-bit register
+ u32 AddrUpper; /* Upper 32 bits of 64-bit register */
#endif
- //#if SXG_FAILURE_DUMP
- // NDIS_EVENT DumpThreadEvent; // syncronize dump thread
- // BOOLEAN DumpThreadRunning; // termination flag
- // PSXG_DUMP_CMD DumpBuffer; // 68k - Cmd and Buffer
- // dma_addr_t PDumpBuffer; // Physical address
- //#endif // SXG_FAILURE_DUMP
-
+ unsigned short max_aggregation;
+ unsigned short min_aggregation;
+ /*#if SXG_FAILURE_DUMP */
+ /* NDIS_EVENT DumpThreadEvent; */ /* syncronize dump thread */
+ /* BOOLEAN DumpThreadRunning; */ /* termination flag */
+ /* PSXG_DUMP_CMD DumpBuffer; */ /* 68k - Cmd and Buffer */
+ /* dma_addr_t PDumpBuffer; */ /* Physical address */
+ /*#endif */ /* SXG_FAILURE_DUMP */
+ /*MSI-X related data elements*/
+ u32 nr_msix_entries;
+ struct msix_entry *msi_entries;
+ struct timer_list watchdog_timer;
+ struct work_struct update_link_status;
+ u32 link_status_changed;
};
#if SLIC_DUMP_ENABLED
@@ -710,12 +725,10 @@ struct adapter_t {
#define SLIC_DUMP_IN_PROGRESS 2
#define SLIC_DUMP_DONE 3
-/****************************************************************************
- *
+/*
* Microcode crash information structure. This
* structure is written out to the card's SRAM when the microcode panic's.
- *
- ****************************************************************************/
+ */
struct slic_crash_info {
ushort cpu_id;
ushort crash_pc;
@@ -738,21 +751,25 @@ struct slic_crash_info {
(largestat) += ((newstat) - (oldstat)); \
}
-#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
-{ \
- _Result = TRUE; \
- if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
- _Result = FALSE; \
- if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
- _Result = FALSE; \
+#define ETHER_EQ_ADDR(_AddrA, _AddrB, _Result) \
+{ \
+ _Result = TRUE; \
+ if (*(u32 *)(_AddrA) != *(u32 *)(_AddrB)) \
+ _Result = FALSE; \
+ if (*(u16 *)(&((_AddrA)[4])) != *(u16 *)(&((_AddrB)[4]))) \
+ _Result = FALSE; \
}
#define ETHERMAXFRAME 1514
#define JUMBOMAXFRAME 9014
+#define SXG_JUMBO_MTU 9000
+#define SXG_DEFAULT_MTU 1500
+
#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
#define SXG_GET_ADDR_LOW(_addr) (u32)((u64)(_addr) & 0x00000000FFFFFFFF)
-#define SXG_GET_ADDR_HIGH(_addr) (u32)(((u64)(_addr) >> 32) & 0x00000000FFFFFFFF)
+#define SXG_GET_ADDR_HIGH(_addr) \
+ (u32)(((u64)(_addr) >> 32) & 0x00000000FFFFFFFF)
#else
#define SXG_GET_ADDR_LOW(_addr) (u32)_addr
#define SXG_GET_ADDR_HIGH(_addr) (u32)0
@@ -761,8 +778,10 @@ struct slic_crash_info {
#define FLUSH TRUE
#define DONT_FLUSH FALSE
-#define SIOCSLICDUMPCARD SIOCDEVPRIVATE+9
-#define SIOCSLICSETINTAGG SIOCDEVPRIVATE+10
-#define SIOCSLICTRACEDUMP SIOCDEVPRIVATE+11
+#define SIOCSLICDUMPCARD (SIOCDEVPRIVATE+9)
+#define SIOCSLICSETINTAGG (SIOCDEVPRIVATE+10)
+#define SIOCSLICTRACEDUMP (SIOCDEVPRIVATE+11)
+extern struct ethtool_ops sxg_nic_ethtool_ops;
+#define SXG_COMPLETE_SLOW_SEND_LIMIT 128
#endif /* __SXG_DRIVER_H__ */
diff --git a/drivers/staging/sxg/sxg_ethtool.c b/drivers/staging/sxg/sxg_ethtool.c
new file mode 100644
index 00000000000..97f765d1250
--- /dev/null
+++ b/drivers/staging/sxg/sxg_ethtool.c
@@ -0,0 +1,328 @@
+/**************************************************************************
+ *
+ * Copyright (C) 2000-2008 Alacritech, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ALACRITECH, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALACRITECH, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation
+ * are those of the authors and should not be interpreted as representing
+ * official policies, either expressed or implied, of Alacritech, Inc.
+ *
+ **************************************************************************/
+
+/*
+ * FILENAME: sxg_ethtool.c
+ *
+ * The ethtool support for SXG driver for Alacritech's 10Gbe products.
+ *
+ * NOTE: This is the standard, non-accelerated version of Alacritech's
+ * IS-NIC driver.
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/pci.h>
+
+#include "sxg_os.h"
+#include "sxghw.h"
+#include "sxghif.h"
+#include "sxg.h"
+
+struct sxg_nic_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int sizeof_stat;
+ int stat_offset;
+};
+
+#define SXG_NIC_STATS(m) sizeof(((struct adapter_t *)0)->m), \
+ offsetof(struct adapter_t, m)
+
+#define USER_VIEWABLE_EEPROM_SIZE 28
+
+static struct sxg_nic_stats sxg_nic_gstrings_stats[] = {
+ {"xmit_ring_0_full", SXG_NIC_STATS(Stats.XmtZeroFull)},
+
+ /* May be will need in future */
+/* {"dumb_xmit_broadcast_packets", SXG_NIC_STATS(Stats.DumbXmtBcastPkts)},
+ {"dumb_xmit_broadcast_bytes", SXG_NIC_STATS(Stats.DumbXmtBcastBytes)},
+ {"dumb_xmit_unicast_packets", SXG_NIC_STATS(Stats.DumbXmtUcastPkts)},
+ {"dumb_xmit_unicast_bytes", SXG_NIC_STATS(Stats.DumbXmtUcastBytes)},
+*/
+ {"xmit_queue_length", SXG_NIC_STATS(Stats.XmtQLen)},
+ {"memory_allocation_failure", SXG_NIC_STATS(Stats.NoMem)},
+ {"Interrupts", SXG_NIC_STATS(Stats.NumInts)},
+ {"false_interrupts", SXG_NIC_STATS(Stats.FalseInts)},
+ {"processed_data_queue_full", SXG_NIC_STATS(Stats.PdqFull)},
+ {"event_ring_full", SXG_NIC_STATS(Stats.EventRingFull)},
+ {"transport_checksum_error", SXG_NIC_STATS(Stats.TransportCsum)},
+ {"transport_underflow_error", SXG_NIC_STATS(Stats.TransportUflow)},
+ {"transport_header_length_error", SXG_NIC_STATS(Stats.TransportHdrLen)},
+ {"network_checksum_error", SXG_NIC_STATS(Stats.NetworkCsum)},
+ {"network_underflow_error", SXG_NIC_STATS(Stats.NetworkUflow)},
+ {"network_header_length_error", SXG_NIC_STATS(Stats.NetworkHdrLen)},
+ {"receive_parity_error", SXG_NIC_STATS(Stats.Parity)},
+ {"link_parity_error", SXG_NIC_STATS(Stats.LinkParity)},
+ {"link/data early_error", SXG_NIC_STATS(Stats.LinkEarly)},
+ {"buffer_overflow_error", SXG_NIC_STATS(Stats.LinkBufOflow)},
+ {"link_code_error", SXG_NIC_STATS(Stats.LinkCode)},
+ {"dribble nibble", SXG_NIC_STATS(Stats.LinkDribble)},
+ {"CRC_error", SXG_NIC_STATS(Stats.LinkCrc)},
+ {"link_overflow_error", SXG_NIC_STATS(Stats.LinkOflow)},
+ {"link_underflow_error", SXG_NIC_STATS(Stats.LinkUflow)},
+
+ /* May be need in future */
+/* {"dumb_rcv_broadcast_packets", SXG_NIC_STATS(Stats.DumbRcvBcastPkts)},
+ {"dumb_rcv_broadcast_bytes", SXG_NIC_STATS(Stats.DumbRcvBcastBytes)},
+*/ {"dumb_rcv_multicast_packets", SXG_NIC_STATS(Stats.DumbRcvMcastPkts)},
+ {"dumb_rcv_multicast_bytes", SXG_NIC_STATS(Stats.DumbRcvMcastBytes)},
+/* {"dumb_rcv_unicast_packets", SXG_NIC_STATS(Stats.DumbRcvUcastPkts)},
+ {"dumb_rcv_unicast_bytes", SXG_NIC_STATS(Stats.DumbRcvUcastBytes)},
+*/
+ {"no_sgl_buffer", SXG_NIC_STATS(Stats.NoSglBuf)},
+};
+
+#define SXG_NIC_STATS_LEN ARRAY_SIZE(sxg_nic_gstrings_stats)
+
+static inline void sxg_reg32_write(void __iomem *reg, u32 value, bool flush)
+{
+ writel(value, reg);
+ if (flush)
+ mb();
+}
+
+static inline void sxg_reg64_write(struct adapter_t *adapter, void __iomem *reg,
+ u64 value, u32 cpu)
+{
+ u32 value_high = (u32) (value >> 32);
+ u32 value_low = (u32) (value & 0x00000000FFFFFFFF);
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->Bit64RegLock, flags);
+ writel(value_high, (void __iomem *)(&adapter->UcodeRegs[cpu].Upper));
+ writel(value_low, reg);
+ spin_unlock_irqrestore(&adapter->Bit64RegLock, flags);
+}
+
+static void
+sxg_nic_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *drvinfo)
+{
+ struct adapter_t *adapter = netdev_priv(dev);
+ strncpy(drvinfo->driver, sxg_driver_name, 32);
+ strncpy(drvinfo->version, SXG_DRV_VERSION, 32);
+// strncpy(drvinfo->fw_version, SAHARA_UCODE_VERS_STRING, 32);
+ strncpy(drvinfo->bus_info, pci_name(adapter->pcidev), 32);
+ /* TODO : Read the major and minor number of firmware. Is this
+ * from the FLASH/EEPROM or download file ?
+ */
+ /* LINSYS : Check if this is correct or if not find the right value
+ * Also check what is the right EEPROM length : EEPROM_SIZE_XFMR or EEPROM_SIZE_NO_XFMR
+ */
+}
+
+static int sxg_nic_set_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ /* No settings are applicable as we support only 10Gb/FIBRE_media */
+ return -EOPNOTSUPP;
+}
+
+static void
+sxg_nic_get_strings(struct net_device *netdev, u32 stringset, u8 * data)
+{
+ int index;
+
+ switch(stringset) {
+ case ETH_SS_TEST:
+ break;
+ case ETH_SS_STATS:
+ for (index = 0; index < SXG_NIC_STATS_LEN; index++) {
+ memcpy(data + index * ETH_GSTRING_LEN,
+ sxg_nic_gstrings_stats[index].stat_string,
+ ETH_GSTRING_LEN);
+ }
+ break;
+ }
+}
+
+static void
+sxg_nic_get_ethtool_stats(struct net_device *netdev,
+ struct ethtool_stats *stats, u64 * data)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ int index;
+ for (index = 0; index < SXG_NIC_STATS_LEN; index++) {
+ char *p = (char *)adapter +
+ sxg_nic_gstrings_stats[index].stat_offset;
+ data[index] = (sxg_nic_gstrings_stats[index].sizeof_stat ==
+ sizeof(u64)) ? *(u64 *) p : *(u32 *) p;
+ }
+}
+
+static int sxg_nic_get_sset_count(struct net_device *netdev, int sset)
+{
+ switch (sset) {
+ case ETH_SS_STATS:
+ return SXG_NIC_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int sxg_nic_get_settings(struct net_device *netdev,
+ struct ethtool_cmd *ecmd)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+
+ ecmd->supported = SUPPORTED_10000baseT_Full;
+ ecmd->autoneg = AUTONEG_ENABLE; //VSS check This
+ ecmd->transceiver = XCVR_EXTERNAL; //VSS check This
+
+ /* For Fibre Channel */
+ ecmd->supported |= SUPPORTED_FIBRE;
+ ecmd->advertising = (ADVERTISED_10000baseT_Full |
+ ADVERTISED_FIBRE);
+ ecmd->port = PORT_FIBRE;
+
+
+ /* Link Speed */
+ if(adapter->LinkState & SXG_LINK_UP) {
+ ecmd->speed = SPEED_10000; //adapter->LinkSpeed;
+ ecmd->duplex = DUPLEX_FULL;
+ }
+ return 0;
+}
+
+static u32 sxg_nic_get_rx_csum(struct net_device *netdev)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ return ((adapter->flags & SXG_RCV_IP_CSUM_ENABLED) &&
+ (adapter->flags & SXG_RCV_TCP_CSUM_ENABLED));
+}
+
+static int sxg_nic_set_rx_csum(struct net_device *netdev, u32 data)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ if (data)
+ adapter->flags |= SXG_RCV_IP_CSUM_ENABLED;
+ else
+ adapter->flags &= ~SXG_RCV_IP_CSUM_ENABLED;
+ /*
+ * We dont need to write to the card to do checksums.
+ * It does it anyways.
+ */
+ return 0;
+}
+
+static int sxg_nic_get_regs_len(struct net_device *dev)
+{
+ return (SXG_HWREG_MEMSIZE + SXG_UCODEREG_MEMSIZE);
+}
+
+static void sxg_nic_get_regs(struct net_device *netdev,
+ struct ethtool_regs *regs, void *p)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ struct sxg_hw_regs *HwRegs = adapter->HwRegs;
+ struct sxg_ucode_regs *UcodeRegs = adapter->UcodeRegs;
+ u32 *buff = p;
+
+ memset(p, 0, (sizeof(struct sxg_hw_regs)+sizeof(struct sxg_ucode_regs)));
+ memcpy(buff, HwRegs, sizeof(struct sxg_hw_regs));
+ memcpy((buff+sizeof(struct sxg_hw_regs)), UcodeRegs, sizeof(struct sxg_ucode_regs));
+}
+
+static int sxg_nic_get_eeprom_len(struct net_device *netdev)
+{
+ return (USER_VIEWABLE_EEPROM_SIZE);
+}
+
+static int sxg_nic_get_eeprom(struct net_device *netdev,
+ struct ethtool_eeprom *eeprom, u8 *bytes)
+{
+ struct adapter_t *adapter = netdev_priv(netdev);
+ struct sw_cfg_data *data;
+ unsigned long i, status;
+ dma_addr_t p_addr;
+
+ data = pci_alloc_consistent(adapter->pcidev, sizeof(struct sw_cfg_data),
+ &p_addr);
+ if(!data) {
+ /*
+ * We cant get even this much memory. Raise a hell
+ * Get out of here
+ */
+ printk(KERN_ERR"%s : Could not allocate memory for reading \
+ EEPROM\n", __FUNCTION__);
+ return -ENOMEM;
+ }
+
+ WRITE_REG(adapter->UcodeRegs[0].ConfigStat, SXG_CFG_TIMEOUT, TRUE);
+ WRITE_REG64(adapter, adapter->UcodeRegs[0].Config, p_addr, 0);
+ for(i=0; i<1000; i++) {
+ READ_REG(adapter->UcodeRegs[0].ConfigStat, status);
+ if (status != SXG_CFG_TIMEOUT)
+ break;
+ mdelay(1); /* Do we really need this */
+ }
+
+ memset(bytes, 0, eeprom->len);
+ memcpy(bytes, data->MacAddr[0].MacAddr, sizeof(struct sxg_config_mac));
+ memcpy(bytes+6, data->AtkFru.PartNum, 6);
+ memcpy(bytes+12, data->AtkFru.Revision, 2);
+ memcpy(bytes+14, data->AtkFru.Serial, 14);
+
+ return 0;
+}
+
+struct ethtool_ops sxg_nic_ethtool_ops = {
+ .get_settings = sxg_nic_get_settings,
+ .set_settings = sxg_nic_set_settings,
+ .get_drvinfo = sxg_nic_get_drvinfo,
+ .get_regs_len = sxg_nic_get_regs_len,
+ .get_regs = sxg_nic_get_regs,
+ .get_link = ethtool_op_get_link,
+// .get_wol = sxg_nic_get_wol,
+ .get_eeprom_len = sxg_nic_get_eeprom_len,
+ .get_eeprom = sxg_nic_get_eeprom,
+// .get_pauseparam = sxg_nic_get_pauseparam,
+// .set_pauseparam = sxg_nic_set_pauseparam,
+ .set_tx_csum = ethtool_op_set_tx_csum,
+ .get_sg = ethtool_op_get_sg,
+ .set_sg = ethtool_op_set_sg,
+// .get_tso = sxg_nic_get_tso,
+// .set_tso = sxg_nic_set_tso,
+// .self_test = sxg_nic_diag_test,
+ .get_strings = sxg_nic_get_strings,
+ .get_ethtool_stats = sxg_nic_get_ethtool_stats,
+ .get_sset_count = sxg_nic_get_sset_count,
+ .get_rx_csum = sxg_nic_get_rx_csum,
+ .set_rx_csum = sxg_nic_set_rx_csum,
+// .get_coalesce = sxg_nic_get_intr_coalesce,
+// .set_coalesce = sxg_nic_set_intr_coalesce,
+};
diff --git a/drivers/staging/sxg/sxg_os.h b/drivers/staging/sxg/sxg_os.h
index 6d3f23fb5e1..68e1a04b61f 100644
--- a/drivers/staging/sxg/sxg_os.h
+++ b/drivers/staging/sxg/sxg_os.h
@@ -44,34 +44,34 @@
#define FALSE (0)
#define TRUE (1)
-struct LIST_ENTRY {
- struct LIST_ENTRY *nle_flink;
- struct LIST_ENTRY *nle_blink;
+struct list_entry {
+ struct list_entry *nle_flink;
+ struct list_entry *nle_blink;
};
-#define InitializeListHead(l) \
+#define InitializeListHead(l) \
(l)->nle_flink = (l)->nle_blink = (l)
-#define IsListEmpty(h) \
+#define IsListEmpty(h) \
((h)->nle_flink == (h))
-#define RemoveEntryList(e) \
- do { \
- list_entry *b; \
- list_entry *f; \
- \
- f = (e)->nle_flink; \
- b = (e)->nle_blink; \
- b->nle_flink = f; \
- f->nle_blink = b; \
+#define RemoveEntryList(e) \
+ do { \
+ list_entry *b; \
+ list_entry *f; \
+ \
+ f = (e)->nle_flink; \
+ b = (e)->nle_blink; \
+ b->nle_flink = f; \
+ f->nle_blink = b; \
} while (0)
/* These two have to be inlined since they return things. */
-static __inline struct LIST_ENTRY *RemoveHeadList(struct LIST_ENTRY *l)
+static inline struct list_entry *RemoveHeadList(struct list_entry *l)
{
- struct LIST_ENTRY *f;
- struct LIST_ENTRY *e;
+ struct list_entry *f;
+ struct list_entry *e;
e = l->nle_flink;
f = e->nle_flink;
@@ -81,10 +81,10 @@ static __inline struct LIST_ENTRY *RemoveHeadList(struct LIST_ENTRY *l)
return (e);
}
-static __inline struct LIST_ENTRY *RemoveTailList(struct LIST_ENTRY *l)
+static inline struct list_entry *RemoveTailList(struct list_entry *l)
{
- struct LIST_ENTRY *b;
- struct LIST_ENTRY *e;
+ struct list_entry *b;
+ struct list_entry *e;
e = l->nle_blink;
b = e->nle_blink;
@@ -94,54 +94,56 @@ static __inline struct LIST_ENTRY *RemoveTailList(struct LIST_ENTRY *l)
return (e);
}
-#define InsertTailList(l, e) \
- do { \
- struct LIST_ENTRY *b; \
- \
- b = (l)->nle_blink; \
- (e)->nle_flink = (l); \
- (e)->nle_blink = b; \
- b->nle_flink = (e); \
- (l)->nle_blink = (e); \
+#define InsertTailList(l, e) \
+ do { \
+ struct list_entry *b; \
+ \
+ b = (l)->nle_blink; \
+ (e)->nle_flink = (l); \
+ (e)->nle_blink = b; \
+ b->nle_flink = (e); \
+ (l)->nle_blink = (e); \
} while (0)
-#define InsertHeadList(l, e) \
- do { \
- struct LIST_ENTRY *f; \
- \
- f = (l)->nle_flink; \
- (e)->nle_flink = f; \
- (e)->nle_blink = l; \
- f->nle_blink = (e); \
- (l)->nle_flink = (e); \
+#define InsertHeadList(l, e) \
+ do { \
+ struct list_entry *f; \
+ \
+ f = (l)->nle_flink; \
+ (e)->nle_flink = f; \
+ (e)->nle_blink = l; \
+ f->nle_blink = (e); \
+ (l)->nle_flink = (e); \
} while (0)
#define ATK_DEBUG 1
#if ATK_DEBUG
-#define SLIC_TIMESTAMP(value) { \
- struct timeval timev; \
- do_gettimeofday(&timev); \
- value = timev.tv_sec*1000000 + timev.tv_usec; \
+#define SLIC_TIMESTAMP(value) { \
+ struct timeval timev; \
+ do_gettimeofday(&timev); \
+ value = timev.tv_sec*1000000 + timev.tv_usec; \
}
#else
#define SLIC_TIMESTAMP(value)
#endif
-/****************** SXG DEFINES *****************************************/
+/* SXG DEFINES */
#ifdef ATKDBG
-#define SXG_TIMESTAMP(value) { \
- struct timeval timev; \
- do_gettimeofday(&timev); \
- value = timev.tv_sec*1000000 + timev.tv_usec; \
+#define SXG_TIMESTAMP(value) { \
+ struct timeval timev; \
+ do_gettimeofday(&timev); \
+ value = timev.tv_sec*1000000 + timev.tv_usec; \
}
#else
#define SXG_TIMESTAMP(value)
#endif
-#define WRITE_REG(reg,value,flush) sxg_reg32_write((&reg), (value), (flush))
-#define WRITE_REG64(a,reg,value,cpu) sxg_reg64_write((a),(&reg),(value),(cpu))
+#define WRITE_REG(reg,value,flush) \
+ sxg_reg32_write((&reg), (value), (flush))
+#define WRITE_REG64(a,reg,value,cpu) \
+ sxg_reg64_write((a),(&reg),(value),(cpu))
#define READ_REG(reg,value) (value) = readl((void __iomem *)(&reg))
#endif /* _SLIC_OS_SPECIFIC_H_ */
diff --git a/drivers/staging/sxg/sxgdbg.h b/drivers/staging/sxg/sxgdbg.h
index bb58ddf39f3..e613a972b3d 100644
--- a/drivers/staging/sxg/sxgdbg.h
+++ b/drivers/staging/sxg/sxgdbg.h
@@ -44,22 +44,23 @@
#define _SXG_DEBUG_H_
#define ATKDBG 1
-#define ATK_TRACE_ENABLED 1
+#define ATK_TRACE_ENABLED 0
-#define DBG_ERROR(n, args...) printk(KERN_EMERG n, ##args)
+#define DBG_ERROR(n, args...) printk(KERN_WARNING n, ##args)
#ifdef ASSERT
#undef ASSERT
#endif
+#define SXG_ASSERT_ENABLED
#ifdef SXG_ASSERT_ENABLED
#ifndef ASSERT
-#define ASSERT(a) \
- { \
- if (!(a)) { \
- DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n",\
- __FILE__, __func__, __LINE__); \
- } \
+#define ASSERT(a) \
+ { \
+ if (!(a)) { \
+ DBG_ERROR("ASSERT() Failure: file %s, function %s line %d\n", \
+ __FILE__, __func__, __LINE__); \
+ } \
}
#endif
#else
@@ -78,7 +79,7 @@
extern ulong ATKTimerDiv;
/*
- * trace_entry_t -
+ * trace_entry -
*
* This structure defines an entry in the trace buffer. The
* first few fields mean the same from entry to entry, while
@@ -86,34 +87,34 @@ extern ulong ATKTimerDiv;
* needs of the trace entry. Typically they are function call
* parameters.
*/
-struct trace_entry_t {
- char name[8]; /* 8 character name - like 's'i'm'b'a'r'c'v' */
- u32 time; /* Current clock tic */
- unsigned char cpu; /* Current CPU */
- unsigned char irql; /* Current IRQL */
- unsigned char driver; /* The driver which added the trace call */
- unsigned char pad2; /* pad to 4 byte boundary - will probably get used */
- u32 arg1; /* Caller arg1 */
- u32 arg2; /* Caller arg2 */
- u32 arg3; /* Caller arg3 */
- u32 arg4; /* Caller arg4 */
+struct trace_entry {
+ char name[8];/* 8 character name - like 's'i'm'b'a'r'c'v' */
+ u32 time; /* Current clock tic */
+ unsigned char cpu; /* Current CPU */
+ unsigned char irql; /* Current IRQL */
+ unsigned char driver;/* The driver which added the trace call */
+ /* pad to 4 byte boundary - will probably get used */
+ unsigned char pad2;
+ u32 arg1; /* Caller arg1 */
+ u32 arg2; /* Caller arg2 */
+ u32 arg3; /* Caller arg3 */
+ u32 arg4; /* Caller arg4 */
};
-/*
- * Driver types for driver field in trace_entry_t
- */
+/* Driver types for driver field in struct trace_entry */
#define TRACE_SXG 1
#define TRACE_VPCI 2
#define TRACE_SLIC 3
#define TRACE_ENTRIES 1024
-struct sxg_trace_buffer_t {
- unsigned int size; /* aid for windbg extension */
- unsigned int in; /* Where to add */
- unsigned int level; /* Current Trace level */
- spinlock_t lock; /* For MP tracing */
- struct trace_entry_t entries[TRACE_ENTRIES];/* The circular buffer */
+struct sxg_trace_buffer {
+ /* aid for windbg extension */
+ unsigned int size;
+ unsigned int in; /* Where to add */
+ unsigned int level; /* Current Trace level */
+ spinlock_t lock; /* For MP tracing */
+ struct trace_entry entries[TRACE_ENTRIES];/* The circular buffer */
};
/*
@@ -128,15 +129,11 @@ struct sxg_trace_buffer_t {
#define TRACE_NOISY 10 /* Everything in the world */
-/**********************************************************************
- *
- * The macros themselves -
- *
- *********************************************************************/
+/* The macros themselves */
#if ATK_TRACE_ENABLED
#define SXG_TRACE_INIT(buffer, tlevel) \
{ \
- memset((buffer), 0, sizeof(struct sxg_trace_buffer_t)); \
+ memset((buffer), 0, sizeof(struct sxg_trace_buffer)); \
(buffer)->level = (tlevel); \
(buffer)->size = TRACE_ENTRIES; \
spin_lock_init(&(buffer)->lock); \
@@ -145,40 +142,38 @@ struct sxg_trace_buffer_t {
#define SXG_TRACE_INIT(buffer, tlevel)
#endif
-/*
- * The trace macro. This is active only if ATK_TRACE_ENABLED is set.
- */
+/*The trace macro. This is active only if ATK_TRACE_ENABLED is set. */
#if ATK_TRACE_ENABLED
#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4) { \
- if ((buffer) && ((buffer)->level >= (tlevel))) { \
- unsigned int trace_irql = 0; /* ?????? FIX THIS */ \
- unsigned int trace_len; \
- struct trace_entry_t *trace_entry; \
- struct timeval timev; \
- \
- spin_lock(&(buffer)->lock); \
- trace_entry = &(buffer)->entries[(buffer)->in]; \
- do_gettimeofday(&timev); \
- \
- memset(trace_entry->name, 0, 8); \
- trace_len = strlen(tname); \
- trace_len = trace_len > 8 ? 8 : trace_len; \
- memcpy(trace_entry->name, (tname), trace_len); \
- trace_entry->time = timev.tv_usec; \
- trace_entry->cpu = (unsigned char)(smp_processor_id() & 0xFF); \
- trace_entry->driver = (tdriver); \
- trace_entry->irql = trace_irql; \
- trace_entry->arg1 = (ulong)(a1); \
- trace_entry->arg2 = (ulong)(a2); \
- trace_entry->arg3 = (ulong)(a3); \
- trace_entry->arg4 = (ulong)(a4); \
- \
- (buffer)->in++; \
- if ((buffer)->in == TRACE_ENTRIES) \
- (buffer)->in = 0; \
- \
- spin_unlock(&(buffer)->lock); \
- } \
+ if ((buffer) && ((buffer)->level >= (tlevel))) { \
+ unsigned int trace_irql = 0;/* ?????? FIX THIS */\
+ unsigned int trace_len; \
+ struct trace_entry *trace_entry; \
+ struct timeval timev; \
+ if(spin_trylock(&(buffer)->lock)) { \
+ trace_entry = &(buffer)->entries[(buffer)->in]; \
+ do_gettimeofday(&timev); \
+ \
+ memset(trace_entry->name, 0, 8); \
+ trace_len = strlen(tname); \
+ trace_len = trace_len > 8 ? 8 : trace_len; \
+ memcpy(trace_entry->name, (tname), trace_len); \
+ trace_entry->time = timev.tv_usec; \
+ trace_entry->cpu = (unsigned char)(smp_processor_id() & 0xFF);\
+ trace_entry->driver = (tdriver); \
+ trace_entry->irql = trace_irql; \
+ trace_entry->arg1 = (ulong)(a1); \
+ trace_entry->arg2 = (ulong)(a2); \
+ trace_entry->arg3 = (ulong)(a3); \
+ trace_entry->arg4 = (ulong)(a4); \
+ \
+ (buffer)->in++; \
+ if ((buffer)->in == TRACE_ENTRIES) \
+ (buffer)->in = 0; \
+ \
+ spin_unlock(&(buffer)->lock); \
+ } \
+ } \
}
#else
#define SXG_TRACE(tdriver, buffer, tlevel, tname, a1, a2, a3, a4)
diff --git a/drivers/staging/sxg/sxghif.h b/drivers/staging/sxg/sxghif.h
index a4e94685c54..e190d6add29 100644
--- a/drivers/staging/sxg/sxghif.h
+++ b/drivers/staging/sxg/sxghif.h
@@ -1,4 +1,4 @@
-/*
+/*******************************************************************
* Copyright © 1997-2007 Alacritech, Inc. All rights reserved
*
* $Id: sxghif.h,v 1.5 2008/07/24 19:18:22 chris Exp $
@@ -7,129 +7,134 @@
*
* This file contains structures and definitions for the
* Alacritech Sahara host interface
- */
-
-/*******************************************************************************
- * UCODE Registers
- *******************************************************************************/
-struct SXG_UCODE_REGS {
- // Address 0 - 0x3F = Command codes 0-15 for TCB 0. Excode 0
- u32 Icr; // Code = 0 (extended), ExCode = 0 - Int control
- u32 RsvdReg1; // Code = 1 - TOE -NA
- u32 RsvdReg2; // Code = 2 - TOE -NA
- u32 RsvdReg3; // Code = 3 - TOE -NA
- u32 RsvdReg4; // Code = 4 - TOE -NA
- u32 RsvdReg5; // Code = 5 - TOE -NA
- u32 CardUp; // Code = 6 - Microcode initialized when 1
- u32 RsvdReg7; // Code = 7 - TOE -NA
- u32 CodeNotUsed[8]; // Codes 8-15 not used. ExCode = 0
- // This brings us to ExCode 1 at address 0x40 = Interrupt status pointer
- u32 Isp; // Code = 0 (extended), ExCode = 1
- u32 PadEx1[15]; // Codes 1-15 not used with extended codes
- // ExCode 2 = Interrupt Status Register
- u32 Isr; // Code = 0 (extended), ExCode = 2
+ ******************************************************************/
+
+#define DBG 1
+
+/* UCODE Registers */
+struct sxg_ucode_regs {
+ /* Address 0 - 0x3F = Command codes 0-15 for TCB 0. Excode 0 */
+ u32 Icr; /* Code = 0 (extended), ExCode = 0 - Int control */
+ u32 RsvdReg1; /* Code = 1 - TOE -NA */
+ u32 RsvdReg2; /* Code = 2 - TOE -NA */
+ u32 RsvdReg3; /* Code = 3 - TOE -NA */
+ u32 RsvdReg4; /* Code = 4 - TOE -NA */
+ u32 RsvdReg5; /* Code = 5 - TOE -NA */
+ u32 CardUp; /* Code = 6 - Microcode initialized when 1 */
+ u32 RsvdReg7; /* Code = 7 - TOE -NA */
+ u32 ConfigStat; /* Code = 8 - Configuration data load status */
+ u32 RsvdReg9; /* Code = 9 - TOE -NA */
+ u32 CodeNotUsed[6]; /* Codes 10-15 not used. ExCode = 0 */
+ /* This brings us to ExCode 1 at address 0x40 = Interrupt status pointer */
+ u32 Isp; /* Code = 0 (extended), ExCode = 1 */
+ u32 PadEx1[15]; /* Codes 1-15 not used with extended codes */
+ /* ExCode 2 = Interrupt Status Register */
+ u32 Isr; /* Code = 0 (extended), ExCode = 2 */
u32 PadEx2[15];
- // ExCode 3 = Event base register. Location of event rings
- u32 EventBase; // Code = 0 (extended), ExCode = 3
+ /* ExCode 3 = Event base register. Location of event rings */
+ u32 EventBase; /* Code = 0 (extended), ExCode = 3 */
u32 PadEx3[15];
- // ExCode 4 = Event ring size
- u32 EventSize; // Code = 0 (extended), ExCode = 4
+ /* ExCode 4 = Event ring size */
+ u32 EventSize; /* Code = 0 (extended), ExCode = 4 */
u32 PadEx4[15];
- // ExCode 5 = TCB Buffers base address
- u32 TcbBase; // Code = 0 (extended), ExCode = 5
+ /* ExCode 5 = TCB Buffers base address */
+ u32 TcbBase; /* Code = 0 (extended), ExCode = 5 */
u32 PadEx5[15];
- // ExCode 6 = TCB Composite Buffers base address
- u32 TcbCompBase; // Code = 0 (extended), ExCode = 6
+ /* ExCode 6 = TCB Composite Buffers base address */
+ u32 TcbCompBase; /* Code = 0 (extended), ExCode = 6 */
u32 PadEx6[15];
- // ExCode 7 = Transmit ring base address
- u32 XmtBase; // Code = 0 (extended), ExCode = 7
+ /* ExCode 7 = Transmit ring base address */
+ u32 XmtBase; /* Code = 0 (extended), ExCode = 7 */
u32 PadEx7[15];
- // ExCode 8 = Transmit ring size
- u32 XmtSize; // Code = 0 (extended), ExCode = 8
+ /* ExCode 8 = Transmit ring size */
+ u32 XmtSize; /* Code = 0 (extended), ExCode = 8 */
u32 PadEx8[15];
- // ExCode 9 = Receive ring base address
- u32 RcvBase; // Code = 0 (extended), ExCode = 9
+ /* ExCode 9 = Receive ring base address */
+ u32 RcvBase; /* Code = 0 (extended), ExCode = 9 */
u32 PadEx9[15];
- // ExCode 10 = Receive ring size
- u32 RcvSize; // Code = 0 (extended), ExCode = 10
+ /* ExCode 10 = Receive ring size */
+ u32 RcvSize; /* Code = 0 (extended), ExCode = 10 */
u32 PadEx10[15];
- // ExCode 11 = Read EEPROM Config
- u32 Config; // Code = 0 (extended), ExCode = 11
+ /* ExCode 11 = Read EEPROM/Flash Config */
+ u32 Config; /* Code = 0 (extended), ExCode = 11 */
u32 PadEx11[15];
- // ExCode 12 = Multicast bits 31:0
- u32 McastLow; // Code = 0 (extended), ExCode = 12
+ /* ExCode 12 = Multicast bits 31:0 */
+ u32 McastLow; /* Code = 0 (extended), ExCode = 12 */
u32 PadEx12[15];
- // ExCode 13 = Multicast bits 63:32
- u32 McastHigh; // Code = 0 (extended), ExCode = 13
+ /* ExCode 13 = Multicast bits 63:32 */
+ u32 McastHigh; /* Code = 0 (extended), ExCode = 13 */
u32 PadEx13[15];
- // ExCode 14 = Ping
- u32 Ping; // Code = 0 (extended), ExCode = 14
+ /* ExCode 14 = Ping */
+ u32 Ping; /* Code = 0 (extended), ExCode = 14 */
u32 PadEx14[15];
- // ExCode 15 = Link MTU
- u32 LinkMtu; // Code = 0 (extended), ExCode = 15
+ /* ExCode 15 = Link MTU */
+ u32 LinkMtu; /* Code = 0 (extended), ExCode = 15 */
u32 PadEx15[15];
- // ExCode 16 = Download synchronization
- u32 LoadSync; // Code = 0 (extended), ExCode = 16
+ /* ExCode 16 = Download synchronization */
+ u32 LoadSync; /* Code = 0 (extended), ExCode = 16 */
u32 PadEx16[15];
- // ExCode 17 = Upper DRAM address bits on 32-bit systems
- u32 Upper; // Code = 0 (extended), ExCode = 17
+ /* ExCode 17 = Upper DRAM address bits on 32-bit systems */
+ u32 Upper; /* Code = 0 (extended), ExCode = 17 */
u32 PadEx17[15];
- // ExCode 18 = Slowpath Send Index Address
- u32 SPSendIndex; // Code = 0 (extended), ExCode = 18
+ /* ExCode 18 = Slowpath Send Index Address */
+ u32 SPSendIndex; /* Code = 0 (extended), ExCode = 18 */
u32 PadEx18[15];
- u32 RsvdXF; // Code = 0 (extended), ExCode = 19
+ /* ExCode 19 = Get ucode statistics */
+ u32 GetUcodeStats; /* Code = 0 (extended), ExCode = 19 */
u32 PadEx19[15];
- // ExCode 20 = Aggregation
- u32 Aggregation; // Code = 0 (extended), ExCode = 20
+ /* ExCode 20 = Aggregation - See sxgmisc.c:SxgSetInterruptAggregation */
+ u32 Aggregation; /* Code = 0 (extended), ExCode = 20 */
u32 PadEx20[15];
- // ExCode 21 = Receive MDL push timer
- u32 PushTicks; // Code = 0 (extended), ExCode = 21
+ /* ExCode 21 = Receive MDL push timer */
+ u32 PushTicks; /* Code = 0 (extended), ExCode = 21 */
u32 PadEx21[15];
- // ExCode 22 = TOE NA
- u32 AckFrequency; // Code = 0 (extended), ExCode = 22
+ /* ExCode 22 = ACK Frequency */
+ u32 AckFrequency; /* Code = 0 (extended), ExCode = 22 */
u32 PadEx22[15];
- // ExCode 23 = TOE NA
+ /* ExCode 23 = TOE NA */
u32 RsvdReg23;
u32 PadEx23[15];
- // ExCode 24 = TOE NA
+ /* ExCode 24 = TOE NA */
u32 RsvdReg24;
u32 PadEx24[15];
- // ExCode 25 = TOE NA
- u32 RsvdReg25; // Code = 0 (extended), ExCode = 25
+ /* ExCode 25 = TOE NA */
+ u32 RsvdReg25; /* Code = 0 (extended), ExCode = 25 */
u32 PadEx25[15];
- // ExCode 26 = Receive checksum requirements
- u32 ReceiveChecksum; // Code = 0 (extended), ExCode = 26
+ /* ExCode 26 = Receive checksum requirements */
+ u32 ReceiveChecksum; /* Code = 0 (extended), ExCode = 26 */
u32 PadEx26[15];
- // ExCode 27 = RSS Requirements
- u32 Rss; // Code = 0 (extended), ExCode = 27
+ /* ExCode 27 = RSS Requirements */
+ u32 Rss; /* Code = 0 (extended), ExCode = 27 */
u32 PadEx27[15];
- // ExCode 28 = RSS Table
- u32 RssTable; // Code = 0 (extended), ExCode = 28
+ /* ExCode 28 = RSS Table */
+ u32 RssTable; /* Code = 0 (extended), ExCode = 28 */
u32 PadEx28[15];
- // ExCode 29 = Event ring release entries
- u32 EventRelease; // Code = 0 (extended), ExCode = 29
+ /* ExCode 29 = Event ring release entries */
+ u32 EventRelease; /* Code = 0 (extended), ExCode = 29 */
u32 PadEx29[15];
- // ExCode 30 = Number of receive bufferlist commands on ring 0
- u32 RcvCmd; // Code = 0 (extended), ExCode = 30
+ /* ExCode 30 = Number of receive bufferlist commands on ring 0 */
+ u32 RcvCmd; /* Code = 0 (extended), ExCode = 30 */
u32 PadEx30[15];
- // ExCode 31 = slowpath transmit command - Data[31:0] = 1
- u32 XmtCmd; // Code = 0 (extended), ExCode = 31
+ /* ExCode 31 = slowpath transmit command - Data[31:0] = 1 */
+ u32 XmtCmd; /* Code = 0 (extended), ExCode = 31 */
u32 PadEx31[15];
- // ExCode 32 = Dump command
- u32 DumpCmd; // Code = 0 (extended), ExCode = 32
+ /* ExCode 32 = Dump command */
+ u32 DumpCmd; /* Code = 0 (extended), ExCode = 32 */
u32 PadEx32[15];
- // ExCode 33 = Debug command
- u32 DebugCmd; // Code = 0 (extended), ExCode = 33
+ /* ExCode 33 = Debug command */
+ u32 DebugCmd; /* Code = 0 (extended), ExCode = 33 */
u32 PadEx33[15];
- // There are 128 possible extended commands - each of account for 16
- // words (including the non-relevent base command codes 1-15).
- // Pad for the remainder of these here to bring us to the next CPU
- // base. As extended codes are added, reduce the first array value in
- // the following field
- u32 PadToNextCpu[94][16]; // 94 = 128 - 34 (34 = Excodes 0 - 33)
+ /*
+ * There are 128 possible extended commands - each of account for 16
+ * words (including the non-relevent base command codes 1-15).
+ * Pad for the remainder of these here to bring us to the next CPU
+ * base. As extended codes are added, reduce the first array value in
+ * the following field
+ */
+ u32 PadToNextCpu[94][16]; /* 94 = 128 - 34 (34 = Excodes 0 - 33)*/
};
-// Interrupt control register (0) values
+/* Interrupt control register (0) values */
#define SXG_ICR_DISABLE 0x00000000
#define SXG_ICR_ENABLE 0x00000001
#define SXG_ICR_MASK 0x00000002
@@ -139,47 +144,65 @@ struct SXG_UCODE_REGS {
((((_MessageId) << SXG_ICR_MSGID_SHIFT) & \
SXG_ICR_MSGID_MASK) | (_Data))
-// The Microcode supports up to 16 RSS queues
-#define SXG_MAX_RSS 16
-#define SXG_MAX_RSS_TABLE_SIZE 256 // 256-byte max
+#define SXG_MIN_AGG_DEFAULT 0x0010 /* Minimum aggregation default */
+#define SXG_MAX_AGG_DEFAULT 0x0040 /* Maximum aggregation default */
+#define SXG_MAX_AGG_SHIFT 16 /* Maximum in top 16 bits of register */
+/* Disable interrupt aggregation on xmt */
+#define SXG_AGG_XMT_DISABLE 0x80000000
+
+/* The Microcode supports up to 16 RSS queues (RevB) */
+#define SXG_MAX_RSS 16
+#define SXG_MAX_RSS_REVA 8
+
+#define SXG_MAX_RSS_TABLE_SIZE 256 /* 256-byte max */
+
+#define SXG_RSS_REVA_TCP6 0x00000001 /* RSS TCP over IPv6 */
+#define SXG_RSS_REVA_TCP4 0x00000002 /* RSS TCP over IPv4 */
+#define SXG_RSS_IP 0x00000001 /* RSS TCP over IPv6 */
+#define SXG_RSS_TCP 0x00000002 /* RSS TCP over IPv4 */
+#define SXG_RSS_LEGACY 0x00000004 /* Line-base interrupts */
+#define SXG_RSS_TABLE_SIZE 0x0000FF00 /* Table size mask */
-#define SXG_RSS_TCP6 0x00000001 // RSS TCP over IPv6
-#define SXG_RSS_TCP4 0x00000002 // RSS TCP over IPv4
-#define SXG_RSS_LEGACY 0x00000004 // Line-base interrupts
-#define SXG_RSS_TABLE_SIZE 0x0000FF00 // Table size mask
#define SXG_RSS_TABLE_SHIFT 8
-#define SXG_RSS_BASE_CPU 0x00FF0000 // Base CPU (not used)
+#define SXG_RSS_BASE_CPU 0x00FF0000 /* Base CPU (not used) */
#define SXG_RSS_BASE_SHIFT 16
-#define SXG_RCV_IP_CSUM_ENABLED 0x00000001 // ExCode 26 (ReceiveChecksum)
-#define SXG_RCV_TCP_CSUM_ENABLED 0x00000002 // ExCode 26 (ReceiveChecksum)
+#define SXG_RCV_IP_CSUM_ENABLED 0x00000001 /* ExCode 26 (ReceiveChecksum) */
+#define SXG_RCV_TCP_CSUM_ENABLED 0x00000002 /* ExCode 26 (ReceiveChecksum) */
#define SXG_XMT_CPUID_SHIFT 16
-#if VPCI
-#define SXG_CHECK_FOR_HANG_TIME 3000
-#else
+/*
+ * Status returned by ucode in the ConfigStat reg (see above) when attempted
+ * to load configuration data from the EEPROM/Flash.
+ */
+#define SXG_CFG_TIMEOUT 1 /* init value - timeout if unchanged */
+#define SXG_CFG_LOAD_EEPROM 2 /* config data loaded from EEPROM */
+#define SXG_CFG_LOAD_FLASH 3 /* config data loaded from flash */
+#define SXG_CFG_LOAD_INVALID 4 /* no valid config data found */
+#define SXG_CFG_LOAD_ERROR 5 /* hardware error */
+
#define SXG_CHECK_FOR_HANG_TIME 5
-#endif
/*
* TCB registers - This is really the same register memory area as UCODE_REGS
* above, but defined differently. Bits 17:06 of the address define the TCB,
* which means each TCB area occupies 0x40 (64) bytes, or 16 u32S. What really
* is happening is that these registers occupy the "PadEx[15]" areas in the
- * SXG_UCODE_REGS definition above
+ * struct sxg_ucode_regs definition above
*/
-struct SXG_TCB_REGS {
- u32 ExCode; /* Extended codes - see SXG_UCODE_REGS */
- u32 Xmt; /* Code = 1 - # of Xmt descriptors added to ring */
- u32 Rcv; /* Code = 2 - # of Rcv descriptors added to ring */
- u32 Rsvd1; /* Code = 3 - TOE NA */
- u32 Rsvd2; /* Code = 4 - TOE NA */
- u32 Rsvd3; /* Code = 5 - TOE NA */
- u32 Invalid; /* Code = 6 - Reserved for "CardUp" see above */
- u32 Rsvd4; /* Code = 7 - TOE NA */
- u32 Rsvd5; /* Code = 8 - TOE NA */
- u32 Pad[7]; /* Codes 8-15 - Not used. */
+struct sxg_tcb_regs {
+ u32 ExCode; /* Extended codes - see SXG_UCODE_REGS */
+ u32 Xmt; /* Code = 1 - # of Xmt descriptors added to ring */
+ u32 Rcv; /* Code = 2 - # of Rcv descriptors added to ring */
+ u32 Rsvd1; /* Code = 3 - TOE NA */
+ u32 Rsvd2; /* Code = 4 - TOE NA */
+ u32 Rsvd3; /* Code = 5 - TOE NA */
+ u32 Invalid1; /* Code = 6 - Reserved for "CardUp" see above */
+ u32 Rsvd4; /* Code = 7 - TOE NA */
+ u32 Invalid2; /* Code = 8 - Reserved for "ConfigStat" see above */
+ u32 Rsvd5; /* Code = 9 - TOE NA */
+ u32 Pad[6]; /* Codes 10-15 - Not used. */
};
/***************************************************************************
@@ -206,29 +229,26 @@ struct SXG_TCB_REGS {
* ||---|-CpuId of crash
* |----/
***************************************************************************/
-#define SXG_ISR_ERR 0x80000000 // Error
-#define SXG_ISR_EVENT 0x40000000 // Event ring event
-#define SXG_ISR_NONE1 0x20000000 // Not used
-#define SXG_ISR_UPC 0x10000000 // Dump/debug command complete
-#define SXG_ISR_LINK 0x08000000 // Link event
-#define SXG_ISR_PDQF 0x04000000 // Processed data queue full
-#define SXG_ISR_RMISS 0x02000000 // Drop - no host buf
-#define SXG_ISR_BREAK 0x01000000 // Breakpoint hit
-#define SXG_ISR_PING 0x00800000 // Heartbeat response
-#define SXG_ISR_DEAD 0x00400000 // Card crash
-#define SXG_ISR_ERFULL 0x00200000 // Event ring full
-#define SXG_ISR_XDROP 0x00100000 // XMT Drop - no DRAM bufs or XMT err
-#define SXG_ISR_SPSEND 0x00080000 // Slow send complete
-#define SXG_ISR_CPU 0x00070000 // Dead CPU mask
-#define SXG_ISR_CPU_SHIFT 16 // Dead CPU shift
-#define SXG_ISR_CRASH 0x0000FFFF // Crash address mask
+#define SXG_ISR_ERR 0x80000000 /* Error */
+#define SXG_ISR_EVENT 0x40000000 /* Event ring event */
+#define SXG_ISR_NONE1 0x20000000 /* Not used */
+#define SXG_ISR_UPC 0x10000000 /* Dump/debug command complete*/
+#define SXG_ISR_LINK 0x08000000 /* Link event */
+#define SXG_ISR_PDQF 0x04000000 /* Processed data queue full */
+#define SXG_ISR_RMISS 0x02000000 /* Drop - no host buf */
+#define SXG_ISR_BREAK 0x01000000 /* Breakpoint hit */
+#define SXG_ISR_PING 0x00800000 /* Heartbeat response */
+#define SXG_ISR_DEAD 0x00400000 /* Card crash */
+#define SXG_ISR_ERFULL 0x00200000 /* Event ring full */
+#define SXG_ISR_XDROP 0x00100000 /* XMT Drop - no DRAM bufs or XMT err */
+#define SXG_ISR_SPSEND 0x00080000 /* Slow send complete */
+#define SXG_ISR_CPU 0x00070000 /* Dead CPU mask */
+#define SXG_ISR_CPU_SHIFT 16 /* Dead CPU shift */
+#define SXG_ISR_CRASH 0x0000FFFF /* Crash address mask */
/***************************************************************************
- *
* Event Ring entry
*
- ***************************************************************************/
-/*
* 31 15 0
* .___________________.___________________.
* |<------------ Pad 0 ------------>|
@@ -270,196 +290,223 @@ struct SXG_TCB_REGS {
* ||------- ISTCPIP
* |-------- SCERR
*
- */
+ ************************************************************************/
#pragma pack(push, 1)
-struct SXG_EVENT {
- u32 Pad[1]; // not used
- u32 SndUna; // SndUna value
- u32 Resid; // receive MDL resid
+struct sxg_event {
+ u32 Pad[1]; /* not used */
+ u32 SndUna; /* SndUna value */
+ u32 Resid; /* receive MDL resid */
union {
- void *HostHandle; // Receive host handle
- u32 Rsvd1; // TOE NA
+ void * HostHandle; /* Receive host handle */
+ u32 Rsvd1; /* TOE NA */
struct {
u32 NotUsed;
- u32 Rsvd2; // TOE NA
+ u32 Rsvd2; /* TOE NA */
} Flush;
};
- u32 Toeplitz; // RSS Toeplitz hash
+ u32 Toeplitz; /* RSS Toeplitz hash */
union {
- ushort Rsvd3; // TOE NA
- ushort HdrOffset; // Slowpath
+ ushort Rsvd3; /* TOE NA */
+ ushort HdrOffset; /* Slowpath */
};
- ushort Length; //
- unsigned char Rsvd4; // TOE NA
- unsigned char Code; // Event code
- unsigned char CommandIndex; // New ring index
- unsigned char Status; // Event status
+ ushort Length;
+ unsigned char Rsvd4; /* TOE NA */
+ unsigned char Code; /* Event code */
+ unsigned char CommandIndex; /* New ring index */
+ unsigned char Status; /* Event status */
};
#pragma pack(pop)
-// Event code definitions
-#define EVENT_CODE_BUFFERS 0x01 // Receive buffer list command (ring 0)
-#define EVENT_CODE_SLOWRCV 0x02 // Slowpath receive
-#define EVENT_CODE_UNUSED 0x04 // Was slowpath commands complete
-
-// Status values
-#define EVENT_STATUS_VALID 0x80 // Entry valid
-
-// Slowpath status
-#define EVENT_STATUS_ERROR 0x40 // Completed with error. Index in next byte
-#define EVENT_STATUS_TCPIP4 0x20 // TCPIPv4 frame
-#define EVENT_STATUS_TCPBAD 0x10 // Bad TCP checksum
-#define EVENT_STATUS_IPBAD 0x08 // Bad IP checksum
-#define EVENT_STATUS_RCVERR 0x04 // Slowpath receive error
-#define EVENT_STATUS_IPONLY 0x02 // IP frame
-#define EVENT_STATUS_TCPIP6 0x01 // TCPIPv6 frame
-#define EVENT_STATUS_TCPIP 0x21 // Combination of v4 and v6
-
-// Event ring
-// Size must be power of 2, between 128 and 16k
-#define EVENT_RING_SIZE 4096 // ??
-#define EVENT_RING_BATCH 16 // Hand entries back 16 at a time.
-#define EVENT_BATCH_LIMIT 256 // Stop processing events after 256 (16 * 16)
-
-struct SXG_EVENT_RING {
- struct SXG_EVENT Ring[EVENT_RING_SIZE];
+/* Event code definitions */
+#define EVENT_CODE_BUFFERS 0x01 /* Receive buffer list command (ring 0) */
+#define EVENT_CODE_SLOWRCV 0x02 /* Slowpath receive */
+#define EVENT_CODE_UNUSED 0x04 /* Was slowpath commands complete */
+
+/* Status values */
+#define EVENT_STATUS_VALID 0x80 /* Entry valid */
+
+/* Slowpath status */
+#define EVENT_STATUS_ERROR 0x40 /* Completed with error. Index in next byte */
+#define EVENT_STATUS_TCPIP4 0x20 /* TCPIPv4 frame */
+#define EVENT_STATUS_TCPBAD 0x10 /* Bad TCP checksum */
+#define EVENT_STATUS_IPBAD 0x08 /* Bad IP checksum */
+#define EVENT_STATUS_RCVERR 0x04 /* Slowpath receive error */
+#define EVENT_STATUS_IPONLY 0x02 /* IP frame */
+#define EVENT_STATUS_TCPIP6 0x01 /* TCPIPv6 frame */
+#define EVENT_STATUS_TCPIP 0x21 /* Combination of v4 and v6 */
+
+/*
+ * Event ring
+ * Size must be power of 2, between 128 and 16k
+ */
+#define EVENT_RING_SIZE 4096
+#define EVENT_RING_BATCH 16 /* Hand entries back 16 at a time. */
+/* Stop processing events after 4096 (256 * 16) */
+#define EVENT_BATCH_LIMIT 256
+
+struct sxg_event_ring {
+ struct sxg_event Ring[EVENT_RING_SIZE];
};
-/***************************************************************************
- *
- * TCB Buffers
- *
- ***************************************************************************/
-// Maximum number of TCBS supported by hardware/microcode
+/* TCB Buffers */
+/* Maximum number of TCBS supported by hardware/microcode */
#define SXG_MAX_TCB 4096
-// Minimum TCBs before we fail initialization
+/* Minimum TCBs before we fail initialization */
#define SXG_MIN_TCB 512
-// TCB Hash
-// The bucket is determined by bits 11:4 of the toeplitz if we support 4k
-// offloaded connections, 10:4 if we support 2k and so on.
+/*
+ * TCB Hash
+ * The bucket is determined by bits 11:4 of the toeplitz if we support 4k
+ * offloaded connections, 10:4 if we support 2k and so on.
+ */
#define SXG_TCB_BUCKET_SHIFT 4
-#define SXG_TCB_PER_BUCKET 16
-#define SXG_TCB_BUCKET_MASK 0xFF0 // Bucket portion of TCB ID
-#define SXG_TCB_ELEMENT_MASK 0x00F // Element within bucket
-#define SXG_TCB_BUCKETS 256 // 256 * 16 = 4k
+#define SXG_TCB_PER_BUCKET 16
+#define SXG_TCB_BUCKET_MASK 0xFF0 /* Bucket portion of TCB ID */
+#define SXG_TCB_ELEMENT_MASK 0x00F /* Element within bucket */
+#define SXG_TCB_BUCKETS 256 /* 256 * 16 = 4k */
-#define SXG_TCB_BUFFER_SIZE 512 // ASSERT format is correct
+#define SXG_TCB_BUFFER_SIZE 512 /* ASSERT format is correct */
-#define SXG_TCB_RCVQ_SIZE 736
+#define SXG_TCB_RCVQ_SIZE 736
#define SXG_TCB_COMPOSITE_BUFFER_SIZE 1024
-#define SXG_LOCATE_TCP_FRAME_HDR(_TcpObject, _IPv6) \
- (((_TcpObject)->VlanId) ? \
- ((_IPv6) ? /* Vlan frame header = yes */ \
- &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.SxgTcp : \
- &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.SxgTcp) : \
- ((_IPv6) ? /* Vlan frame header = No */ \
- &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.SxgTcp : \
+#define SXG_LOCATE_TCP_FRAME_HDR(_TcpObject, _IPv6) \
+ (((_TcpObject)->VlanId) ? \
+ ((_IPv6) ? /* Vlan frame header = yes */ \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.SxgTcp: \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.SxgTcp): \
+ ((_IPv6) ? /* Vlan frame header = No */ \
+ &(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.SxgTcp : \
&(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.SxgTcp))
-#define SXG_LOCATE_IP_FRAME_HDR(_TcpObject) \
- (_TcpObject)->VlanId ? \
- &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.Ip : \
+#define SXG_LOCATE_IP_FRAME_HDR(_TcpObject) \
+ (_TcpObject)->VlanId ? \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp.Ip: \
&(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp.Ip
-#define SXG_LOCATE_IP6_FRAME_HDR(_TcpObject) \
- (_TcpObject)->VlanId ? \
- &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip : \
+#define SXG_LOCATE_IP6_FRAME_HDR(TcpObject) \
+ (_TcpObject)->VlanId ? \
+ &(_TcpObject)->CompBuffer->Frame.HasVlan.TcpIp6.Ip: \
&(_TcpObject)->CompBuffer->Frame.NoVlan.TcpIp6.Ip
#if DBG
-// Horrible kludge to distinguish dumb-nic, slowpath, and
-// fastpath traffic. Decrement the HopLimit by one
-// for slowpath, two for fastpath. This assumes the limit is measurably
-// greater than two, which I think is reasonable.
-// Obviously this is DBG only. Maybe remove later, or #if 0 so we
-// can set it when needed
-#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) { \
- PIPV6_HDR _Ip6FrameHdr; \
- if((_TcpObject)->IPv6) { \
- _Ip6FrameHdr = SXG_LOCATE_IP6_FRAME_HDR((_TcpObject)); \
- if(_FastPath) { \
- _Ip6FrameHdr->HopLimit = (_TcpObject)->Cached.TtlOrHopLimit - 2; \
- } else { \
- _Ip6FrameHdr->HopLimit = (_TcpObject)->Cached.TtlOrHopLimit - 1; \
- } \
- } \
+/*
+ * Horrible kludge to distinguish dumb-nic, slowpath, and
+ * fastpath traffic. Decrement the HopLimit by one
+ * for slowpath, two for fastpath. This assumes the limit is measurably
+ * greater than two, which I think is reasonable.
+ * Obviously this is DBG only. Maybe remove later, or #if 0 so we
+ * can set it when needed
+ */
+#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath) { \
+ PIPV6_HDR _Ip6FrameHdr; \
+ if ((_TcpObject)->IPv6) { \
+ _Ip6FrameHdr = SXG_LOCATE_IP6_FRAME_HDR((_TcpObject)); \
+ if (_FastPath) { \
+ _Ip6FrameHdr->HopLimit = \
+ (_TcpObject)->Cached.TtlOrHopLimit - 2; \
+ } else { \
+ _Ip6FrameHdr->HopLimit = \
+ (_TcpObject)->Cached.TtlOrHopLimit - 1; \
+ } \
+ } \
}
#else
-// Do nothing with free build
+/* Do nothing with free build */
#define SXG_DBG_HOP_LIMIT(_TcpObject, _FastPath)
#endif
-/***************************************************************************
- * Receive and transmit rings
- ***************************************************************************/
+/* Receive and transmit rings */
#define SXG_MAX_RING_SIZE 256
-#define SXG_XMT_RING_SIZE 128 // Start with 128
-#define SXG_RCV_RING_SIZE 128 // Start with 128
+#define SXG_XMT_RING_SIZE 128 /* Start with 128 */
+#define SXG_RCV_RING_SIZE 128 /* Start with 128 */
#define SXG_MAX_ENTRIES 4096
-
-// Structure and macros to manage a ring
-struct SXG_RING_INFO {
- unsigned char Head; // Where we add entries - Note unsigned char:RING_SIZE
- unsigned char Tail; // Where we pull off completed entries
- ushort Size; // Ring size - Must be multiple of 2
- void *Context[SXG_MAX_RING_SIZE]; // Shadow ring
+#define SXG_JUMBO_RCV_RING_SIZE 32
+
+/* Structure and macros to manage a ring */
+struct sxg_ring_info {
+ /* Where we add entries - Note unsigned char:RING_SIZE */
+ unsigned char Head;
+ unsigned char Tail; /* Where we pull off completed entries */
+ ushort Size; /* Ring size - Must be multiple of 2 */
+ void * Context[SXG_MAX_RING_SIZE]; /* Shadow ring */
};
-#define SXG_INITIALIZE_RING(_ring, _size) { \
- (_ring).Head = 0; \
- (_ring).Tail = 0; \
- (_ring).Size = (_size); \
+#define SXG_INITIALIZE_RING(_ring, _size) { \
+ (_ring).Head = 0; \
+ (_ring).Tail = 0; \
+ (_ring).Size = (_size); \
}
-#define SXG_ADVANCE_INDEX(_index, _size) ((_index) = ((_index) + 1) & ((_size) - 1))
-#define SXG_PREVIOUS_INDEX(_index, _size) (((_index) - 1) &((_size) - 1))
+
+#define SXG_ADVANCE_INDEX(_index, _size) \
+ ((_index) = ((_index) + 1) & ((_size) - 1))
+#define SXG_PREVIOUS_INDEX(_index, _size) \
+ (((_index) - 1) &((_size) - 1))
#define SXG_RING_EMPTY(_ring) ((_ring)->Head == (_ring)->Tail)
-#define SXG_RING_FULL(_ring) ((((_ring)->Head + 1) & ((_ring)->Size - 1)) == (_ring)->Tail)
-#define SXG_RING_ADVANCE_HEAD(_ring) SXG_ADVANCE_INDEX((_ring)->Head, ((_ring)->Size))
-#define SXG_RING_RETREAT_HEAD(_ring) ((_ring)->Head = \
- SXG_PREVIOUS_INDEX((_ring)->Head, (_ring)->Size))
-#define SXG_RING_ADVANCE_TAIL(_ring) { \
- ASSERT((_ring)->Tail != (_ring)->Head); \
- SXG_ADVANCE_INDEX((_ring)->Tail, ((_ring)->Size)); \
+#define SXG_RING_FULL(_ring) \
+ ((((_ring)->Head + 1) & ((_ring)->Size - 1)) == (_ring)->Tail)
+#define SXG_RING_ADVANCE_HEAD(_ring) \
+ SXG_ADVANCE_INDEX((_ring)->Head, ((_ring)->Size))
+#define SXG_RING_RETREAT_HEAD(_ring) ((_ring)->Head = \
+ SXG_PREVIOUS_INDEX((_ring)->Head, (_ring)->Size))
+#define SXG_RING_ADVANCE_TAIL(_ring) { \
+ ASSERT((_ring)->Tail != (_ring)->Head); \
+ SXG_ADVANCE_INDEX((_ring)->Tail, ((_ring)->Size)); \
}
-// Set cmd to the next available ring entry, set the shadow context
-// entry and advance the ring.
-// The appropriate lock must be held when calling this macro
-#define SXG_GET_CMD(_ring, _ringinfo, _cmd, _context) { \
- if(SXG_RING_FULL(_ringinfo)) { \
- (_cmd) = NULL; \
- } else { \
- (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Head]; \
+/*
+ * Set cmd to the next available ring entry, set the shadow context
+ * entry and advance the ring.
+ * The appropriate lock must be held when calling this macro
+ */
+#define SXG_GET_CMD(_ring, _ringinfo, _cmd, _context) { \
+ if(SXG_RING_FULL(_ringinfo)) { \
+ (_cmd) = NULL; \
+ } else { \
+ (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Head]; \
(_ringinfo)->Context[(_ringinfo)->Head] = (void *)(_context);\
- SXG_RING_ADVANCE_HEAD(_ringinfo); \
- } \
+ SXG_RING_ADVANCE_HEAD(_ringinfo); \
+ } \
}
-// Abort the previously allocated command by retreating the head.
-// NOTE - The appopriate lock MUST NOT BE DROPPED between the SXG_GET_CMD
-// and SXG_ABORT_CMD calls.
-#define SXG_ABORT_CMD(_ringinfo) { \
- ASSERT(!(SXG_RING_EMPTY(_ringinfo))); \
- SXG_RING_RETREAT_HEAD(_ringinfo); \
- (_ringinfo)->Context[(_ringinfo)->Head] = NULL; \
+/*
+ * Abort the previously allocated command by retreating the head.
+ * NOTE - The appopriate lock MUST NOT BE DROPPED between the SXG_GET_CMD
+ * and SXG_ABORT_CMD calls.
+ */
+#define SXG_ABORT_CMD(_ringinfo) { \
+ ASSERT(!(SXG_RING_EMPTY(_ringinfo))); \
+ SXG_RING_RETREAT_HEAD(_ringinfo); \
+ (_ringinfo)->Context[(_ringinfo)->Head] = NULL; \
}
-// For the given ring, return a pointer to the tail cmd and context,
-// clear the context and advance the tail
-#define SXG_RETURN_CMD(_ring, _ringinfo, _cmd, _context) { \
- (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Tail]; \
+/*
+ * For the given ring, return a pointer to the tail cmd and context,
+ * clear the context and advance the tail
+ */
+#define SXG_RETURN_CMD(_ring, _ringinfo, _cmd, _context) { \
+ (_cmd) = &(_ring)->Descriptors[(_ringinfo)->Tail]; \
(_context) = (_ringinfo)->Context[(_ringinfo)->Tail]; \
- (_ringinfo)->Context[(_ringinfo)->Tail] = NULL; \
- SXG_RING_ADVANCE_TAIL(_ringinfo); \
+ (_ringinfo)->Context[(_ringinfo)->Tail] = NULL; \
+ SXG_RING_ADVANCE_TAIL(_ringinfo); \
}
-/***************************************************************************
- *
+/*
+ * For a given ring find out how much the first pointer is ahead of
+ * the second pointer. "ahead" recognises the fact that the ring can wrap
+ */
+static inline int sxg_ring_get_forward_diff (struct sxg_ring_info *ringinfo,
+ int a, int b) {
+ if ((a < 0 || a > ringinfo->Size ) || (b < 0 || b > ringinfo->Size))
+ return -1;
+ if (a > b) /* _a is lagging _b and _b has not wrapped around */
+ return (a - b);
+ else
+ return ((ringinfo->Size - (b - a)));
+}
+
+/***************************************************************
* Host Command Buffer - commands to INIC via the Cmd Rings
*
- ***************************************************************************/
-/*
* 31 15 0
* .___________________.___________________.
* |<-------------- Sgl Low -------------->|
@@ -479,42 +526,43 @@ struct SXG_RING_INFO {
* |_________|_________|_________|_________|24 0x18
* |<----- LCnt ------>|<----- Flags ----->|
* |_________|_________|_________|_________|28 0x1c
- */
+ ****************************************************************/
#pragma pack(push, 1)
-struct SXG_CMD {
- dma_addr_t Sgl; // Physical address of SGL
+struct sxg_cmd {
+ dma64_addr_t Sgl; /* Physical address of SGL */
union {
struct {
- dma64_addr_t FirstSgeAddress; // Address of first SGE
- u32 FirstSgeLength; // Length of first SGE
+ dma64_addr_t FirstSgeAddress; /* Address of first SGE */
+ u32 FirstSgeLength; /* Length of first SGE */
union {
- u32 Rsvd1; // TOE NA
- u32 SgeOffset; // Slowpath - 2nd SGE offset
- u32 Resid; // MDL completion - clobbers update
+ u32 Rsvd1; /* TOE NA */
+ u32 SgeOffset; /* Slowpath - 2nd SGE offset */
+ /* MDL completion - clobbers update */
+ u32 Resid;
};
union {
- u32 TotalLength; // Total transfer length
- u32 Mss; // LSO MSS
+ u32 TotalLength; /* Total transfer length */
+ u32 Mss; /* LSO MSS */
};
} Buffer;
};
union {
struct {
- unsigned char Flags:4; // slowpath flags
- unsigned char IpHl:4; // Ip header length (>>2)
- unsigned char MacLen; // Mac header len
+ unsigned char Flags:4; /* slowpath flags */
+ unsigned char IpHl:4; /* Ip header length (>>2) */
+ unsigned char MacLen; /* Mac header len */
} CsumFlags;
struct {
- ushort Flags:4; // slowpath flags
- ushort TcpHdrOff:7; // TCP
- ushort MacLen:5; // Mac header len
+ ushort Flags:4; /* slowpath flags */
+ ushort TcpHdrOff:7; /* TCP */
+ ushort MacLen:5; /* Mac header len */
} LsoFlags;
- ushort Flags; // flags
+ ushort Flags; /* flags */
};
union {
- ushort SgEntries; // SG entry count including first sge
+ ushort SgEntries; /* SG entry count including first sge */
struct {
- unsigned char Status; // Copied from event status
+ unsigned char Status; /* Copied from event status */
unsigned char NotUsed;
} Status;
};
@@ -522,13 +570,13 @@ struct SXG_CMD {
#pragma pack(pop)
#pragma pack(push, 1)
-struct VLAN_HDR {
+struct vlan_hdr {
ushort VlanTci;
ushort VlanTpid;
};
#pragma pack(pop)
-/*
+/********************************************************************
* Slowpath Flags:
*
*
@@ -558,36 +606,36 @@ struct VLAN_HDR {
* | LCnt |MAC hlen |Hlen|Flgs|
* |___________________|____|____|____|____|
*
- */
-// Slowpath CMD flags
-#define SXG_SLOWCMD_CSUM_IP 0x01 // Checksum IP
-#define SXG_SLOWCMD_CSUM_TCP 0x02 // Checksum TCP
-#define SXG_SLOWCMD_LSO 0x04 // Large segment send
-
-struct SXG_XMT_RING {
- struct SXG_CMD Descriptors[SXG_XMT_RING_SIZE];
+ *****************************************************************/
+/* Slowpath CMD flags */
+#define SXG_SLOWCMD_CSUM_IP 0x01 /* Checksum IP */
+#define SXG_SLOWCMD_CSUM_TCP 0x02 /* Checksum TCP */
+#define SXG_SLOWCMD_LSO 0x04 /* Large segment send */
+
+struct sxg_xmt_ring {
+ struct sxg_cmd Descriptors[SXG_XMT_RING_SIZE];
};
-struct SXG_RCV_RING {
- struct SXG_CMD Descriptors[SXG_RCV_RING_SIZE];
+struct sxg_rcv_ring {
+ struct sxg_cmd Descriptors[SXG_RCV_RING_SIZE];
};
-/***************************************************************************
+/*
* Share memory buffer types - Used to identify asynchronous
* shared memory allocation
- ***************************************************************************/
-enum SXG_BUFFER_TYPE {
- SXG_BUFFER_TYPE_RCV, // Receive buffer
- SXG_BUFFER_TYPE_SGL // SGL buffer
+ */
+enum sxg_buffer_type {
+ SXG_BUFFER_TYPE_RCV, /* Receive buffer */
+ SXG_BUFFER_TYPE_SGL /* SGL buffer */
};
-// State for SXG buffers
+/* State for SXG buffers */
#define SXG_BUFFER_FREE 0x01
#define SXG_BUFFER_BUSY 0x02
#define SXG_BUFFER_ONCARD 0x04
#define SXG_BUFFER_UPSTREAM 0x08
-/***************************************************************************
+/*
* Receive data buffers
*
* Receive data buffers are given to the Sahara card 128 at a time.
@@ -597,262 +645,370 @@ enum SXG_BUFFER_TYPE {
* DMA data into, and a virtual address, which is given back
* to the host in the "HostHandle" portion of an event.
* The receive descriptor data structure is defined below
- * as SXG_RCV_DATA_DESCRIPTOR, and the corresponding block
- * is defined as SXG_RCV_DESCRIPTOR_BLOCK.
+ * as sxg_rcv_data_descriptor, and the corresponding block
+ * is defined as sxg_rcv_descriptor_block.
*
* This receive descriptor block is given to the card by filling
- * in the Sgl field of a SXG_CMD entry from pAdapt->RcvRings[0]
+ * in the Sgl field of a sxg_cmd entry from pAdapt->RcvRings[0]
* with the physical address of the receive descriptor block.
*
* Both the receive buffers and the receive descriptor blocks
* require additional data structures to maintain them
* on a free queue and contain other information associated with them.
- * Those data structures are defined as the SXG_RCV_DATA_BUFFER_HDR
- * and SXG_RCV_DESCRIPTOR_BLOCK_HDR respectively.
+ * Those data structures are defined as the sxg_rcv_data_buffer_hdr
+ * and sxg_rcv_descriptor_block_hdr respectively.
*
* Since both the receive buffers and the receive descriptor block
* must be accessible by the card, both must be allocated out of
* shared memory. To ensure that we always have a descriptor
* block available for every 128 buffers, we allocate all of
* these resources together in a single block. This entire
- * block is managed by a SXG_RCV_BLOCK_HDR, who's sole purpose
+ * block is managed by a struct sxg_rcv_block_hdr, who's sole purpose
* is to maintain address information so that the entire block
* can be free later.
*
* Further complicating matters is the fact that the receive
* buffers must be variable in length in order to accomodate
* jumbo frame configurations. We configure the buffer
- * length so that the buffer and it's corresponding SXG_RCV_DATA_BUFFER_HDR
- * structure add up to an even boundary. Then we place the
- * remaining data structures after 128 of them as shown in
- * the following diagram:
+ * length so that the buffer and it's corresponding struct
+ * sxg_rcv_data_buffer_hdr structure add up to an even
+ * boundary. Then we place the remaining data structures after 128
+ * of them as shown in the following diagram:
*
* _________________________________________
* | |
* | Variable length receive buffer #1 |
* |_________________________________________|
* | |
- * | SXG_RCV_DATA_BUFFER_HDR #1 |
+ * | sxg_rcv_data_buffer_hdr #1 |
* |_________________________________________| <== Even 2k or 10k boundary
* | |
* | ... repeat 2-128 .. |
* |_________________________________________|
* | |
- * | SXG_RCV_DESCRIPTOR_BLOCK |
- * | Contains SXG_RCV_DATA_DESCRIPTOR * 128 |
+ * | struct sxg_rcv_descriptor_block |
+ * | Contains sxg_rcv_data_descriptor * 128 |
* |_________________________________________|
* | |
- * | SXG_RCV_DESCRIPTOR_BLOCK_HDR |
+ * | struct sxg_rcv_descriptor_block_hdr |
* |_________________________________________|
* | |
- * | SXG_RCV_BLOCK_HDR |
+ * | struct sxg_rcv_block_hdr |
* |_________________________________________|
*
* Memory consumption:
* Non-jumbo:
- * Buffers and SXG_RCV_DATA_BUFFER_HDR = 2k * 128 = 256k
- * + SXG_RCV_DESCRIPTOR_BLOCK = 2k
- * + SXG_RCV_DESCRIPTOR_BLOCK_HDR = ~32
- * + SXG_RCV_BLOCK_HDR = ~32
+ * Buffers and sxg_rcv_data_buffer_hdr = 2k * 128 = 256k
+ * + struct sxg_rcv_descriptor_block = 2k
+ * + struct sxg_rcv_descriptor_block_hdr = ~32
+ * + struct sxg_rcv_block_hdr = ~32
* => Total = ~258k/block
*
* Jumbo:
- * Buffers and SXG_RCV_DATA_BUFFER_HDR = 10k * 128 = 1280k
- * + SXG_RCV_DESCRIPTOR_BLOCK = 2k
- * + SXG_RCV_DESCRIPTOR_BLOCK_HDR = ~32
- * + SXG_RCV_BLOCK_HDR = ~32
+ * Buffers and sxg_rcv_data_buffer_hdr = 10k * 128 = 1280k
+ * + struct sxg_rcv_descriptor_block = 2k
+ * + struct sxg_rcv_descriptor_block_hdr = ~32
+ * + struct sxg_rcv_block_hdr = ~32
* => Total = ~1282k/block
*
- ***************************************************************************/
-#define SXG_RCV_DATA_BUFFERS 4096 // Amount to give to the card
-#define SXG_INITIAL_RCV_DATA_BUFFERS 8192 // Initial pool of buffers
-#define SXG_MIN_RCV_DATA_BUFFERS 2048 // Minimum amount and when to get more
-#define SXG_MAX_RCV_BLOCKS 128 // = 16384 receive buffers
-
-// Receive buffer header
-struct SXG_RCV_DATA_BUFFER_HDR {
- dma_addr_t PhysicalAddress; // Buffer physical address
- // Note - DO NOT USE the VirtualAddress field to locate data.
- // Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead.
- void *VirtualAddress; // Start of buffer
- struct LIST_ENTRY FreeList; // Free queue of buffers
- struct SXG_RCV_DATA_BUFFER_HDR *Next; // Fastpath data buffer queue
- u32 Size; // Buffer size
- u32 ByteOffset; // See SXG_RESTORE_MDL_OFFSET
- unsigned char State; // See SXG_BUFFER state above
- unsigned char Status; // Event status (to log PUSH)
- struct sk_buff *skb; // Double mapped (nbl and pkt)
+ */
+#define SXG_RCV_DATA_BUFFERS 8192 /* Amount to give to the card */
+#define SXG_INITIAL_RCV_DATA_BUFFERS 16384 /* Initial pool of buffers */
+/* Minimum amount and when to get more */
+#define SXG_MIN_RCV_DATA_BUFFERS 4096
+#define SXG_MAX_RCV_BLOCKS 256 /* = 32k receive buffers */
+/* Amount to give to the card in case of jumbo frames */
+#define SXG_JUMBO_RCV_DATA_BUFFERS 2048
+/* Initial pool of buffers in case of jumbo buffers */
+#define SXG_INITIAL_JUMBO_RCV_DATA_BUFFERS 4096
+#define SXG_MIN_JUMBO_RCV_DATA_BUFFERS 1024
+
+/* Receive buffer header */
+struct sxg_rcv_data_buffer_hdr {
+ dma64_addr_t PhysicalAddress; /* Buffer physical address */
+ /*
+ * Note - DO NOT USE the VirtualAddress field to locate data.
+ * Use the sxg.h:SXG_RECEIVE_DATA_LOCATION macro instead.
+ */
+ struct list_entry FreeList; /* Free queue of buffers */
+ unsigned char State; /* See SXG_BUFFER state above */
+ struct sk_buff * skb; /* Double mapped (nbl and pkt)*/
};
-// SxgSlowReceive uses the PACKET (skb) contained
-// in the SXG_RCV_DATA_BUFFER_HDR when indicating dumb-nic data
+/*
+ * SxgSlowReceive uses the PACKET (skb) contained
+ * in the struct sxg_rcv_data_buffer_hdr when indicating dumb-nic data
+ */
#define SxgDumbRcvPacket skb
-#define SXG_RCV_DATA_HDR_SIZE 256 // Space for SXG_RCV_DATA_BUFFER_HDR
-#define SXG_RCV_DATA_BUFFER_SIZE 2048 // Non jumbo = 2k including HDR
-#define SXG_RCV_JUMBO_BUFFER_SIZE 10240 // jumbo = 10k including HDR
+/* Space for struct sxg_rcv_data_buffer_hdr */
+#define SXG_RCV_DATA_HDR_SIZE sizeof(struct sxg_rcv_data_buffer_hdr)
+/* Non jumbo = 2k including HDR */
+#define SXG_RCV_DATA_BUFFER_SIZE 2048
+/* jumbo = 10k including HDR */
+#define SXG_RCV_JUMBO_BUFFER_SIZE 10240
-// Receive data descriptor
-struct SXG_RCV_DATA_DESCRIPTOR {
+/* Receive data descriptor */
+struct sxg_rcv_data_descriptor {
union {
- struct sk_buff *VirtualAddress; // Host handle
- u64 ForceTo8Bytes; // Force x86 to 8-byte boundary
+ struct sk_buff *VirtualAddress; /* Host handle */
+ u64 ForceTo8Bytes; /*Force x86 to 8-byte boundary*/
};
- dma_addr_t PhysicalAddress;
+ dma64_addr_t PhysicalAddress;
};
-// Receive descriptor block
+/* Receive descriptor block */
#define SXG_RCV_DESCRIPTORS_PER_BLOCK 128
-#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE 2048 // For sanity check
+#define SXG_RCV_DESCRIPTOR_BLOCK_SIZE 2048 /* For sanity check */
-struct SXG_RCV_DESCRIPTOR_BLOCK {
- struct SXG_RCV_DATA_DESCRIPTOR Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
+struct sxg_rcv_descriptor_block {
+ struct sxg_rcv_data_descriptor Descriptors[SXG_RCV_DESCRIPTORS_PER_BLOCK];
};
-// Receive descriptor block header
-struct SXG_RCV_DESCRIPTOR_BLOCK_HDR {
- void *VirtualAddress; // Start of 2k buffer
- dma_addr_t PhysicalAddress; // ..and it's physical address
- struct LIST_ENTRY FreeList; // Free queue of descriptor blocks
- unsigned char State; // See SXG_BUFFER state above
+/* Receive descriptor block header */
+struct sxg_rcv_descriptor_block_hdr {
+ void *VirtualAddress; /* start of 2k buffer */
+ dma64_addr_t PhysicalAddress;/* and it's physical address */
+ struct list_entry FreeList;/* free queue of descriptor blocks */
+ unsigned char State; /* see sxg_buffer state above */
};
-// Receive block header
-struct SXG_RCV_BLOCK_HDR {
- void *VirtualAddress; // Start of virtual memory
- dma_addr_t PhysicalAddress; // ..and it's physical address
- struct LIST_ENTRY AllList; // Queue of all SXG_RCV_BLOCKS
+/* Receive block header */
+struct sxg_rcv_block_hdr {
+ void *VirtualAddress; /* Start of virtual memory */
+ dma64_addr_t PhysicalAddress;/* ..and it's physical address*/
+ struct list_entry AllList; /* Queue of all SXG_RCV_BLOCKS*/
};
-// Macros to determine data structure offsets into receive block
-#define SXG_RCV_BLOCK_SIZE(_Buffersize) \
+/* Macros to determine data structure offsets into receive block */
+#define SXG_RCV_BLOCK_SIZE(_Buffersize) \
(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK)) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK_HDR)) + \
- (sizeof(struct SXG_RCV_BLOCK_HDR)))
+ (sizeof(struct sxg_rcv_descriptor_block)) + \
+ (sizeof(struct sxg_rcv_descriptor_block_hdr)) + \
+ (sizeof(struct sxg_rcv_block_hdr)))
#define SXG_RCV_BUFFER_DATA_SIZE(_Buffersize) \
((_Buffersize) - SXG_RCV_DATA_HDR_SIZE)
#define SXG_RCV_DATA_BUFFER_HDR_OFFSET(_Buffersize) \
((_Buffersize) - SXG_RCV_DATA_HDR_SIZE)
-#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize) \
+#define SXG_RCV_DESCRIPTOR_BLOCK_OFFSET(_Buffersize) \
((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK)
-#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize) \
+#define SXG_RCV_DESCRIPTOR_BLOCK_HDR_OFFSET(_Buffersize) \
(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK)))
+ (sizeof(struct sxg_rcv_descriptor_block)))
#define SXG_RCV_BLOCK_HDR_OFFSET(_Buffersize) \
(((_Buffersize) * SXG_RCV_DESCRIPTORS_PER_BLOCK) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK)) + \
- (sizeof(struct SXG_RCV_DESCRIPTOR_BLOCK_HDR)))
-
-// Use the miniport reserved portion of the NBL to locate
-// our SXG_RCV_DATA_BUFFER_HDR structure.
-struct SXG_RCV_NBL_RESERVED {
- struct SXG_RCV_DATA_BUFFER_HDR *RcvDataBufferHdr;
- void *Available;
-};
+ (sizeof(struct sxg_rcv_descriptor_block)) + \
+ (sizeof(struct sxg_rcv_descriptor_block_hdr)))
-#define SXG_RCV_NBL_BUFFER_HDR(_NBL) (((PSXG_RCV_NBL_RESERVED)NET_BUFFER_LIST_MINIPORT_RESERVED(_NBL))->RcvDataBufferHdr)
+/* Scatter gather list buffer */
+#define SXG_INITIAL_SGL_BUFFERS 8192 /* Initial pool of SGL buffers */
+#define SXG_MIN_SGL_BUFFERS 2048 /* Minimum amount and when to get more*/
+/* Maximum to allocate (note ADAPT:ushort) */
+#define SXG_MAX_SGL_BUFFERS 16384
-/***************************************************************************
- * Scatter gather list buffer
- ***************************************************************************/
-#define SXG_INITIAL_SGL_BUFFERS 8192 // Initial pool of SGL buffers
-#define SXG_MIN_SGL_BUFFERS 2048 // Minimum amount and when to get more
-#define SXG_MAX_SGL_BUFFERS 16384 // Maximum to allocate (note ADAPT:ushort)
+/*
+ * SXG_SGL_POOL_PROPERTIES - This structure is used to define a pool of SGL
+ * buffers. These buffers are allocated out of shared memory and used to
+ * contain a physical scatter gather list structure that is shared
+ * with the card.
+ *
+ * We split our SGL buffers into multiple pools based on size. The motivation
+ * is that some applications perform very large I/Os (1MB for example), so
+ * we need to be able to allocate an SGL to accommodate such a request.
+ * But such an SGL would require 256 24-byte SG entries - ~6k.
+ * Given that the vast majority of I/Os are much smaller than 1M, allocating
+ * a single pool of SGL buffers would be a horribly inefficient use of
+ * memory.
+ *
+ * The following structure includes two fields relating to its size.
+ * The NBSize field specifies the largest NET_BUFFER that can be handled
+ * by the particular pool. The SGEntries field defines the size, in
+ * entries, of the SGL for that pool. The SGEntries is determined by
+ * dividing the NBSize by the expected page size (4k), and then padding
+ * it by some appropriate amount as insurance (20% or so..??).
+ */
+struct sxg_sgl_pool_properties {
+ u32 NBSize; /* Largest NET_BUFFER size for this pool */
+ ushort SGEntries; /* Number of entries in SGL */
+ ushort InitialBuffers; /* Number to allocate at initializationtime */
+ ushort MinBuffers; /* When to get more */
+ ushort MaxBuffers; /* When to stop */
+ ushort PerCpuThreshold;/* See sxgh.h:SXG_RESOURCES */
+};
-// Self identifying structure type
-enum SXG_SGL_TYPE {
- SXG_SGL_DUMB, // Dumb NIC SGL
- SXG_SGL_SLOW, // Slowpath protocol header - see below
- SXG_SGL_CHIMNEY // Chimney offload SGL
+/*
+ * At the moment I'm going to statically initialize 4 pools:
+ * 100k buffer pool: The vast majority of the expected buffers are expected
+ * to be less than or equal to 100k. At 30 entries per and
+ * 8k initial buffers amounts to ~4MB of memory
+ * NOTE - This used to be 64K with 20 entries, but during
+ * WHQL NDIS 6.0 Testing (2c_mini6stress) MS does their
+ * best to send absurd NBL's with ridiculous SGLs, we
+ * have received 400byte sends contained in SGL's that
+ * have 28 entries
+ * 1M buffer pool: Buffers between 64k and 1M. Allocate 256 initial
+ * buffers with 300 entries each => ~2MB of memory
+ * 5M buffer pool: Not expected often, if at all. 32 initial buffers
+ * at 1500 entries each => ~1MB of memory
+ * 10M buffer pool: Not expected at all, except under pathelogical conditions.
+ * Allocate one at initialization time.
+ * Note - 10M is the current limit of what we can realistically
+ * support due to the sahara SGL bug described in the
+ * SAHARA SGL WORKAROUND below. We will likely adjust the
+ * number of pools and/or pool properties over time.
+ */
+#define SXG_NUM_SGL_POOLS 4
+#define INITIALIZE_SGL_POOL_PROPERTIES \
+struct sxg_sgl_pool_properties SxgSglPoolProperties[SXG_NUM_SGL_POOLS] =\
+{ \
+ { 102400, 30, 8192, 2048, 16384, 256}, \
+ { 1048576, 300, 256, 128, 1024, 16}, \
+ { 5252880, 1500, 32, 16, 512, 0}, \
+ {10485760, 2700, 2, 4, 32, 0}, \
};
-// Note - the description below is Microsoft specific
-//
-// The following definition specifies the amount of shared memory to allocate
-// for the SCATTER_GATHER_LIST portion of the SXG_SCATTER_GATHER data structure.
-// The following considerations apply when setting this value:
-// - First, the Sahara card is designed to read the Microsoft SGL structure
-// straight out of host memory. This means that the SGL must reside in
-// shared memory. If the length here is smaller than the SGL for the
-// NET_BUFFER, then NDIS will allocate its own buffer. The buffer
-// that NDIS allocates is not in shared memory, so when this happens,
-// the SGL will need to be copied to a set of SXG_SCATTER_GATHER buffers.
-// In other words.. we don't want this value to be too small.
-// - On the other hand.. we're allocating up to 16k of these things. If
-// we make this too big, we start to consume a ton of memory..
-// At the moment, I'm going to limit the number of SG entries to 150.
-// If each entry maps roughly 4k, then this should cover roughly 600kB
-// NET_BUFFERs. Furthermore, since each entry is 24 bytes, the total
-// SGE portion of the structure consumes 3600 bytes, which should allow
-// the entire SXG_SCATTER_GATHER structure to reside comfortably within
-// a 4k block, providing the remaining fields stay under 500 bytes.
-//
-// So with 150 entries, the SXG_SCATTER_GATHER structure becomes roughly
-// 4k. At 16k of them, that amounts to 64M of shared memory. A ton, but
-// manageable.
-#define SXG_SGL_ENTRIES 150
-
-// The ucode expects an NDIS SGL structure that
-// is formatted for an x64 system. When running
-// on an x64 system, we can simply hand the NDIS SGL
-// to the card directly. For x86 systems we must reconstruct
-// the SGL. The following structure defines an x64
-// formatted SGL entry
-struct SXG_X64_SGE {
- dma64_addr_t Address; // same as wdm.h
- u32 Length; // same as wdm.h
- u32 CompilerPad; // The compiler pads to 8-bytes
- u64 Reserved; // u32 * in wdm.h. Force to 8 bytes
+extern struct sxg_sgl_pool_properties SxgSglPoolProperties[];
+
+#define SXG_MAX_SGL_BUFFER_SIZE \
+ SxgSglPoolProperties[SXG_NUM_SGL_POOLS - 1].NBSize
+
+/*
+ * SAHARA SGL WORKAROUND!!
+ * The current Sahara card uses a 16-bit counter when advancing
+ * SGL address locations. This means that if an SGL crosses
+ * a 64k boundary, the hardware will actually skip back to
+ * the start of the previous 64k boundary, with obviously
+ * undesirable results.
+ *
+ * We currently workaround this issue by allocating SGL buffers
+ * in 64k blocks and skipping over buffers that straddle the boundary.
+ */
+#define SXG_INVALID_SGL(phys_addr,len) \
+ (((phys_addr >> 16) != ( (phys_addr + len) >> 16 )))
+
+/*
+ * Allocate SGLs in blocks so we can skip over invalid entries.
+ * We allocation 64k worth of SGL buffers, including the
+ * struct sxg_sgl_block_hdr, plus one for padding
+ */
+#define SXG_SGL_BLOCK_SIZE 65536
+#define SXG_SGL_ALLOCATION_SIZE(_Pool) \
+ SXG_SGL_BLOCK_SIZE + SXG_SGL_SIZE(_Pool)
+
+struct sxg_sgl_block_hdr {
+ ushort Pool; /* Associated SGL pool */
+ /* struct sxg_scatter_gather blocks */
+ struct list_entry List;
+ dma64_addr_t PhysicalAddress;/* physical address */
};
-struct SCATTER_GATHER_ELEMENT {
- dma64_addr_t Address; // same as wdm.h
- u32 Length; // same as wdm.h
- u32 CompilerPad; // The compiler pads to 8-bytes
- u64 Reserved; // u32 * in wdm.h. Force to 8 bytes
+/*
+ * The following definition denotes the maximum block of memory that the
+ * card can DMA to.It is specified in the call to NdisMRegisterScatterGatherDma.
+ * For now, use the same value as used in the Slic/Oasis driver, which
+ * is 128M. That should cover any expected MDL that I can think of.
+ */
+#define SXG_MAX_PHYS_MAP (1024 * 1024 * 128)
+
+/* Self identifying structure type */
+enum SXG_SGL_TYPE {
+ SXG_SGL_DUMB, /* Dumb NIC SGL */
+ SXG_SGL_SLOW, /* Slowpath protocol header - see below */
+ SXG_SGL_CHIMNEY /* Chimney offload SGL */
};
-struct SCATTER_GATHER_LIST {
- u32 NumberOfElements;
- u32 *Reserved;
- struct SCATTER_GATHER_ELEMENT Elements[];
+/*
+ * The ucode expects an NDIS SGL structure that
+ * is formatted for an x64 system. When running
+ * on an x64 system, we can simply hand the NDIS SGL
+ * to the card directly. For x86 systems we must reconstruct
+ * the SGL. The following structure defines an x64
+ * formatted SGL entry
+ */
+struct sxg_x64_sge {
+ dma64_addr_t Address; /* same as wdm.h */
+ u32 Length; /* same as wdm.h */
+ u32 CompilerPad; /* The compiler pads to 8-bytes */
+ u64 Reserved; /* u32 * in wdm.h. Force to 8 bytes */
};
-// The card doesn't care about anything except elements, so
-// we can leave the u32 * reserved field alone in the following
-// SGL structure. But redefine from wdm.h:SCATTER_GATHER_LIST so
-// we can specify SXG_X64_SGE and define a fixed number of elements
-struct SXG_X64_SGL {
+/*
+ * Our SGL structure - Essentially the same as
+ * wdm.h:SCATTER_GATHER_LIST. Note the variable number of
+ * elements based on the pool specified above
+ */
+struct sxg_x64_sgl {
u32 NumberOfElements;
u32 *Reserved;
- struct SXG_X64_SGE Elements[SXG_SGL_ENTRIES];
+ struct sxg_x64_sge Elements[1]; /* Variable */
};
-struct SXG_SCATTER_GATHER {
- enum SXG_SGL_TYPE Type; // FIRST! Dumb-nic or offload
- void *adapter; // Back pointer to adapter
- struct LIST_ENTRY FreeList; // Free SXG_SCATTER_GATHER blocks
- struct LIST_ENTRY AllList; // All SXG_SCATTER_GATHER blocks
- dma_addr_t PhysicalAddress; // physical address
- unsigned char State; // See SXG_BUFFER state above
- unsigned char CmdIndex; // Command ring index
- struct sk_buff *DumbPacket; // Associated Packet
- u32 Direction; // For asynchronous completions
- u32 CurOffset; // Current SGL offset
- u32 SglRef; // SGL reference count
- struct VLAN_HDR VlanTag; // VLAN tag to be inserted into SGL
- struct SCATTER_GATHER_LIST *pSgl; // SGL Addr. Possibly &Sgl
- struct SXG_X64_SGL Sgl; // SGL handed to card
+struct sxg_scatter_gather {
+ enum SXG_SGL_TYPE Type; /* FIRST! Dumb-nic or offload */
+ ushort Pool; /* Associated SGL pool */
+ ushort Entries; /* SGL total entries */
+ void * adapter; /* Back pointer to adapter */
+ /* Free struct sxg_scatter_gather blocks */
+ struct list_entry FreeList;
+ /* All struct sxg_scatter_gather blocks */
+ struct list_entry AllList;
+ dma64_addr_t PhysicalAddress;/* physical address */
+ unsigned char State; /* See SXG_BUFFER state above */
+ unsigned char CmdIndex; /* Command ring index */
+ struct sk_buff *DumbPacket; /* Associated Packet */
+ /* For asynchronous completions */
+ u32 Direction;
+ u32 CurOffset; /* Current SGL offset */
+ u32 SglRef; /* SGL reference count */
+ struct vlan_hdr VlanTag; /* VLAN tag to be inserted into SGL */
+ struct sxg_x64_sgl *pSgl; /* SGL Addr. Possibly &Sgl */
+ struct sxg_x64_sgl Sgl; /* SGL handed to card */
};
+/*
+ * Note - the "- 1" is because struct sxg_scatter_gather=>struct sxg_x64_sgl
+ * includes 1 SGE..
+ */
+#define SXG_SGL_SIZE(_Pool) \
+ (sizeof(struct sxg_scatter_gather) + \
+ ((SxgSglPoolProperties[_Pool].SGEntries - 1) * \
+ sizeof(struct sxg_x64_sge)))
+
+/* Force NDIS to give us it's own buffer so we can reformat to our own */
+#define SXG_SGL_BUFFER(_SxgSgl) NULL
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) 0
+#define SXG_SGL_BUF_SIZE 0
+
+/*
#if defined(CONFIG_X86_64)
-#define SXG_SGL_BUFFER(_SxgSgl) (&_SxgSgl->Sgl)
-#define SXG_SGL_BUF_SIZE sizeof(struct SXG_X64_SGL)
+#define SXG_SGL_BUFFER(_SxgSgl) (&_SxgSgl->Sgl)
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) ((_SxgSgl)->Entries * \
+ sizeof(struct sxg_x64_sge))
+#define SXG_SGL_BUF_SIZE sizeof(struct sxg_x64_sgl)
#elif defined(CONFIG_X86)
// Force NDIS to give us it's own buffer so we can reformat to our own
-#define SXG_SGL_BUFFER(_SxgSgl) NULL
+#define SXG_SGL_BUFFER(_SxgSgl) NULL
+#define SXG_SGL_BUFFER_LENGTH(_SxgSgl) 0
#define SXG_SGL_BUF_SIZE 0
#else
#error staging: sxg: driver is for X86 only!
#endif
+*/
+/* Microcode statistics */
+struct sxg_ucode_stats {
+ u32 RPDQOflow; /* PDQ overflow (unframed ie dq & drop 1st) */
+ u32 XDrops; /* Xmt drops due to no xmt buffer */
+ u32 ERDrops; /* Rcv drops due to ER full */
+ u32 NBDrops; /* Rcv drops due to out of host buffers */
+ u32 PQDrops; /* Rcv drops due to PDQ full */
+ /* Rcv drops due to bad frame: no link addr match, frlen > max */
+ u32 BFDrops;
+ u32 UPDrops; /* Rcv drops due to UPFq full */
+ u32 XNoBufs; /* Xmt drop due to no DRAM Xmit buffer or PxyBuf */
+};
+
+/*
+ * Macros for handling the Offload engine values
+ */
+/* Number of positions to shift Network Header Length before passing to card */
+#define SXG_NW_HDR_LEN_SHIFT 2
diff --git a/drivers/staging/sxg/sxghw.h b/drivers/staging/sxg/sxghw.h
index b0efff9ff11..81f81d4b0ad 100644
--- a/drivers/staging/sxg/sxghw.h
+++ b/drivers/staging/sxg/sxghw.h
@@ -1,4 +1,4 @@
-/*
+/*************************************************************
* Copyright © 1997-2007 Alacritech, Inc. All rights reserved
*
* $Id: sxghw.h,v 1.2 2008/07/24 17:24:23 chris Exp $
@@ -7,682 +7,894 @@
*
* This file contains structures and definitions for the
* Alacritech Sahara hardware
- */
+ *
+ **********************************************************/
-/*******************************************************************************
- * Configuration space
- *******************************************************************************/
+/* PCI Configuration space */
/* PCI Vendor ID */
#define SXG_VENDOR_ID 0x139A /* Alacritech's Vendor ID */
-// PCI Device ID
+/* PCI Device ID */
#define SXG_DEVICE_ID 0x0009 /* Sahara Device ID */
-//
-// Subsystem IDs.
-//
-// The subsystem ID value is broken into bit fields as follows:
-// Bits [15:12] - Function
-// Bits [11:8] - OEM and/or operating system.
-// Bits [7:0] - Base SID.
-//
-// SSID field (bit) masks
-#define SSID_BASE_MASK 0x00FF // Base subsystem ID mask
-#define SSID_OEM_MASK 0x0F00 // Subsystem OEM mask
-#define SSID_FUNC_MASK 0xF000 // Subsystem function mask
-
-// Base SSID's
-#define SSID_SAHARA_PROTO 0x0018 // 100022 Sahara prototype (XenPak) board
-#define SSID_SAHARA_FIBER 0x0019 // 100023 Sahara 1-port fiber board
-#define SSID_SAHARA_COPPER 0x001A // 100024 Sahara 1-port copper board
-
-// Useful SSID macros
-#define SSID_BASE(ssid) ((ssid) & SSID_BASE_MASK) // isolate base SSID bits
-#define SSID_OEM(ssid) ((ssid) & SSID_OEM_MASK) // isolate SSID OEM bits
-#define SSID_FUNC(ssid) ((ssid) & SSID_FUNC_MASK) // isolate SSID function bits
-
-/*******************************************************************************
- * HW Register Space
- *******************************************************************************/
-#define SXG_HWREG_MEMSIZE 0x4000 // 16k
+
+/* Type of ASIC in use */
+enum asic_type {
+ SAHARA_REV_A,
+ SAHARA_REV_B
+};
+
+/* Type of Xcvr in fiber card */
+enum xcvr_type {
+ XCVR_UNKNOWN,
+ XCVR_NONE,
+ XCVR_SR,
+ XCVR_LR,
+ XCVR_LRM,
+ XCVR_CR
+};
+/*
+ * Subsystem IDs.
+ *
+ * The subsystem ID value is broken into bit fields as follows:
+ * Bits [15:12] - Function
+ * Bits [11:8] - OEM and/or operating system.
+ * Bits [7:0] - Base SID.
+ */
+
+/* SSID field (bit) masks */
+#define SSID_BASE_MASK 0x00FF /* Base subsystem ID mask */
+#define SSID_OEM_MASK 0x0F00 /* Subsystem OEM mask */
+#define SSID_FUNC_MASK 0xF000 /* Subsystem function mask */
+
+/* Base SSID's */
+/* 100022 Sahara prototype (XenPak) board */
+#define SSID_SAHARA_PROTO 0x0018
+#define SSID_SAHARA_FIBER 0x0019 /* 100023 Sahara 1-port fiber board */
+#define SSID_SAHARA_COPPER 0x001A /* 100024 Sahara 1-port copper board */
+
+/* Useful SSID macros */
+/* isolate base SSID bits */
+#define SSID_BASE(ssid) ((ssid) & SSID_BASE_MASK)
+/* isolate SSID OEM bits */
+#define SSID_OEM(ssid) ((ssid) & SSID_OEM_MASK)
+/* isolate SSID function bits */
+#define SSID_FUNC(ssid) ((ssid) & SSID_FUNC_MASK)
+
+
+/* HW Register Space */
+#define SXG_HWREG_MEMSIZE 0x4000 /* 16k */
#pragma pack(push, 1)
-struct SXG_HW_REGS {
- u32 Reset; // Write 0xdead to invoke soft reset
- u32 Pad1; // No register defined at offset 4
- u32 InterruptMask0; // Deassert legacy interrupt on function 0
- u32 InterruptMask1; // Deassert legacy interrupt on function 1
- u32 UcodeDataLow; // Store microcode instruction bits 31-0
- u32 UcodeDataMiddle; // Store microcode instruction bits 63-32
- u32 UcodeDataHigh; // Store microcode instruction bits 95-64
- u32 UcodeAddr; // Store microcode address - See flags below
- u32 PadTo0x80[24]; // Pad to Xcv configuration registers
- u32 MacConfig0; // 0x80 - AXGMAC Configuration Register 0
- u32 MacConfig1; // 0x84 - AXGMAC Configuration Register 1
- u32 MacConfig2; // 0x88 - AXGMAC Configuration Register 2
- u32 MacConfig3; // 0x8C - AXGMAC Configuration Register 3
- u32 MacAddressLow; // 0x90 - AXGMAC MAC Station Address - octets 1-4
- u32 MacAddressHigh; // 0x94 - AXGMAC MAC Station Address - octets 5-6
- u32 MacReserved1[2]; // 0x98 - AXGMAC Reserved
- u32 MacMaxFrameLen; // 0xA0 - AXGMAC Maximum Frame Length
- u32 MacReserved2[2]; // 0xA4 - AXGMAC Reserved
- u32 MacRevision; // 0xAC - AXGMAC Revision Level Register
- u32 MacReserved3[4]; // 0xB0 - AXGMAC Reserved
- u32 MacAmiimCmd; // 0xC0 - AXGMAC AMIIM Command Register
- u32 MacAmiimField; // 0xC4 - AXGMAC AMIIM Field Register
- u32 MacAmiimConfig; // 0xC8 - AXGMAC AMIIM Configuration Register
- u32 MacAmiimLink; // 0xCC - AXGMAC AMIIM Link Fail Vector Register
- u32 MacAmiimIndicator; // 0xD0 - AXGMAC AMIIM Indicator Registor
- u32 PadTo0x100[11]; // 0xD4 - 0x100 - Pad
- u32 XmtConfig; // 0x100 - Transmit Configuration Register
- u32 RcvConfig; // 0x104 - Receive Configuration Register 1
- u32 LinkAddress0Low; // 0x108 - Link address 0
- u32 LinkAddress0High; // 0x10C - Link address 0
- u32 LinkAddress1Low; // 0x110 - Link address 1
- u32 LinkAddress1High; // 0x114 - Link address 1
- u32 LinkAddress2Low; // 0x118 - Link address 2
- u32 LinkAddress2High; // 0x11C - Link address 2
- u32 LinkAddress3Low; // 0x120 - Link address 3
- u32 LinkAddress3High; // 0x124 - Link address 3
- u32 ToeplitzKey[10]; // 0x128 - 0x150 - Toeplitz key
- u32 SocketKey[10]; // 0x150 - 0x178 - Socket Key
- u32 LinkStatus; // 0x178 - Link status
- u32 ClearStats; // 0x17C - Clear Stats
- u32 XmtErrorsLow; // 0x180 - Transmit stats - errors
- u32 XmtErrorsHigh; // 0x184 - Transmit stats - errors
- u32 XmtFramesLow; // 0x188 - Transmit stats - frame count
- u32 XmtFramesHigh; // 0x18C - Transmit stats - frame count
- u32 XmtBytesLow; // 0x190 - Transmit stats - byte count
- u32 XmtBytesHigh; // 0x194 - Transmit stats - byte count
- u32 XmtTcpSegmentsLow; // 0x198 - Transmit stats - TCP segments
- u32 XmtTcpSegmentsHigh; // 0x19C - Transmit stats - TCP segments
- u32 XmtTcpBytesLow; // 0x1A0 - Transmit stats - TCP bytes
- u32 XmtTcpBytesHigh; // 0x1A4 - Transmit stats - TCP bytes
- u32 RcvErrorsLow; // 0x1A8 - Receive stats - errors
- u32 RcvErrorsHigh; // 0x1AC - Receive stats - errors
- u32 RcvFramesLow; // 0x1B0 - Receive stats - frame count
- u32 RcvFramesHigh; // 0x1B4 - Receive stats - frame count
- u32 RcvBytesLow; // 0x1B8 - Receive stats - byte count
- u32 RcvBytesHigh; // 0x1BC - Receive stats - byte count
- u32 RcvTcpSegmentsLow; // 0x1C0 - Receive stats - TCP segments
- u32 RcvTcpSegmentsHigh; // 0x1C4 - Receive stats - TCP segments
- u32 RcvTcpBytesLow; // 0x1C8 - Receive stats - TCP bytes
- u32 RcvTcpBytesHigh; // 0x1CC - Receive stats - TCP bytes
- u32 PadTo0x200[12]; // 0x1D0 - 0x200 - Pad
- u32 Software[1920]; // 0x200 - 0x2000 - Software defined (not used)
- u32 MsixTable[1024]; // 0x2000 - 0x3000 - MSIX Table
- u32 MsixBitArray[1024]; // 0x3000 - 0x4000 - MSIX Pending Bit Array
+struct sxg_hw_regs {
+ u32 Reset; /* Write 0xdead to invoke soft reset */
+ u32 Pad1; /* No register defined at offset 4 */
+ u32 InterruptMask0; /* Deassert legacy interrupt on function 0 */
+ u32 InterruptMask1; /* Deassert legacy interrupt on function 1 */
+ u32 UcodeDataLow; /* Store microcode instruction bits 31-0 */
+ u32 UcodeDataMiddle; /* Store microcode instruction bits 63-32 */
+ u32 UcodeDataHigh; /* Store microcode instruction bits 95-64 */
+ u32 UcodeAddr; /* Store microcode address - See flags below */
+ u32 PadTo0x80[24]; /* Pad to Xcv configuration registers */
+ u32 MacConfig0; /* 0x80 - AXGMAC Configuration Register 0 */
+ u32 MacConfig1; /* 0x84 - AXGMAC Configuration Register 1 */
+ u32 MacConfig2; /* 0x88 - AXGMAC Configuration Register 2 */
+ u32 MacConfig3; /* 0x8C - AXGMAC Configuration Register 3 */
+ u32 MacAddressLow; /* 0x90 - AXGMAC MAC Station Address - octets 1-4 */
+ u32 MacAddressHigh; /* 0x94 - AXGMAC MAC Station Address - octets 5-6 */
+ u32 MacReserved1[2]; /* 0x98 - AXGMAC Reserved */
+ u32 MacMaxFrameLen; /* 0xA0 - AXGMAC Maximum Frame Length */
+ u32 MacReserved2[2]; /* 0xA4 - AXGMAC Reserved */
+ u32 MacRevision; /* 0xAC - AXGMAC Revision Level Register */
+ u32 MacReserved3[4]; /* 0xB0 - AXGMAC Reserved */
+ u32 MacAmiimCmd; /* 0xC0 - AXGMAC AMIIM Command Register */
+ u32 MacAmiimField; /* 0xC4 - AXGMAC AMIIM Field Register */
+ u32 MacAmiimConfig; /* 0xC8 - AXGMAC AMIIM Configuration Register */
+ u32 MacAmiimLink; /* 0xCC - AXGMAC AMIIM Link Fail Vector Register */
+ u32 MacAmiimIndicator; /* 0xD0 - AXGMAC AMIIM Indicator Registor */
+ u32 PadTo0x100[11]; /* 0xD4 - 0x100 - Pad */
+ u32 XmtConfig; /* 0x100 - Transmit Configuration Register */
+ u32 RcvConfig; /* 0x104 - Receive Configuration Register 1 */
+ u32 LinkAddress0Low; /* 0x108 - Link address 0 */
+ u32 LinkAddress0High; /* 0x10C - Link address 0 */
+ u32 LinkAddress1Low; /* 0x110 - Link address 1 */
+ u32 LinkAddress1High; /* 0x114 - Link address 1 */
+ u32 LinkAddress2Low; /* 0x118 - Link address 2 */
+ u32 LinkAddress2High; /* 0x11C - Link address 2 */
+ u32 LinkAddress3Low; /* 0x120 - Link address 3 */
+ u32 LinkAddress3High; /* 0x124 - Link address 3 */
+ u32 ToeplitzKey[10]; /* 0x128 - 0x150 - Toeplitz key */
+ u32 SocketKey[10]; /* 0x150 - 0x178 - Socket Key */
+ u32 LinkStatus; /* 0x178 - Link status */
+ u32 ClearStats; /* 0x17C - Clear Stats */
+ u32 XmtErrorsLow; /* 0x180 - Transmit stats - errors */
+ u32 XmtErrorsHigh; /* 0x184 - Transmit stats - errors */
+ u32 XmtFramesLow; /* 0x188 - Transmit stats - frame count */
+ u32 XmtFramesHigh; /* 0x18C - Transmit stats - frame count */
+ u32 XmtBytesLow; /* 0x190 - Transmit stats - byte count */
+ u32 XmtBytesHigh; /* 0x194 - Transmit stats - byte count */
+ u32 XmtTcpSegmentsLow; /* 0x198 - Transmit stats - TCP segments */
+ u32 XmtTcpSegmentsHigh; /* 0x19C - Transmit stats - TCP segments */
+ u32 XmtTcpBytesLow; /* 0x1A0 - Transmit stats - TCP bytes */
+ u32 XmtTcpBytesHigh; /* 0x1A4 - Transmit stats - TCP bytes */
+ u32 RcvErrorsLow; /* 0x1A8 - Receive stats - errors */
+ u32 RcvErrorsHigh; /* 0x1AC - Receive stats - errors */
+ u32 RcvFramesLow; /* 0x1B0 - Receive stats - frame count */
+ u32 RcvFramesHigh; /* 0x1B4 - Receive stats - frame count */
+ u32 RcvBytesLow; /* 0x1B8 - Receive stats - byte count */
+ u32 RcvBytesHigh; /* 0x1BC - Receive stats - byte count */
+ u32 RcvTcpSegmentsLow; /* 0x1C0 - Receive stats - TCP segments */
+ u32 RcvTcpSegmentsHigh; /* 0x1C4 - Receive stats - TCP segments */
+ u32 RcvTcpBytesLow; /* 0x1C8 - Receive stats - TCP bytes */
+ u32 RcvTcpBytesHigh; /* 0x1CC - Receive stats - TCP bytes */
+ u32 PadTo0x200[12]; /* 0x1D0 - 0x200 - Pad */
+ u32 Software[1920]; /* 0x200 - 0x2000 - Software defined (not used) */
+ u32 MsixTable[1024]; /* 0x2000 - 0x3000 - MSIX Table */
+ u32 MsixBitArray[1024]; /* 0x3000 - 0x4000 - MSIX Pending Bit Array */
};
#pragma pack(pop)
-// Microcode Address Flags
-#define MICROCODE_ADDRESS_GO 0x80000000 // Start microcode
-#define MICROCODE_ADDRESS_WRITE 0x40000000 // Store microcode
-#define MICROCODE_ADDRESS_READ 0x20000000 // Read microcode
-#define MICROCODE_ADDRESS_PARITY 0x10000000 // Parity error detected
-#define MICROCODE_ADDRESS_MASK 0x00001FFF // Address bits
+/* Microcode Address Flags */
+#define MICROCODE_ADDRESS_GO 0x80000000 /* Start microcode */
+#define MICROCODE_ADDRESS_WRITE 0x40000000 /* Store microcode */
+#define MICROCODE_ADDRESS_READ 0x20000000 /* Read microcode */
+#define MICROCODE_ADDRESS_PARITY 0x10000000/* Parity error detected */
+#define MICROCODE_ADDRESS_MASK 0x00001FFF /* Address bits */
-// Link Address Registers
-#define LINK_ADDRESS_ENABLE 0x80000000 // Applied to link address high
+/* Link Address Registers */
+/* Applied to link address high */
+#define LINK_ADDRESS_ENABLE 0x80000000
-// Microsoft register space size
-#define SXG_UCODEREG_MEMSIZE 0x40000 // 256k
+/* Microsoft register space size */
+#define SXG_UCODEREG_MEMSIZE 0x40000 /* 256k */
-// Sahara microcode register address format. The command code,
-// extended command code, and associated processor are encoded in
-// the address bits as follows
-#define SXG_ADDRESS_CODE_SHIFT 2 // Base command code
+/*
+ * Sahara microcode register address format. The command code,
+ * extended command code, and associated processor are encoded in
+ * the address bits as follows
+ */
+#define SXG_ADDRESS_CODE_SHIFT 2 /* Base command code */
#define SXG_ADDRESS_CODE_MASK 0x0000003C
-#define SXG_ADDRESS_EXCODE_SHIFT 6 // Extended (or sub) command code
+/* Extended (or sub) command code */
+#define SXG_ADDRESS_EXCODE_SHIFT 6
#define SXG_ADDRESS_EXCODE_MASK 0x00001FC0
-#define SXG_ADDRESS_CPUID_SHIFT 13 // CPU
+#define SXG_ADDRESS_CPUID_SHIFT 13 /* CPU */
#define SXG_ADDRESS_CPUID_MASK 0x0003E000
-#define SXG_REGISTER_SIZE_PER_CPU 0x00002000 // Used to sanity check UCODE_REGS structure
-
-// Sahara receive sequencer status values
-#define SXG_RCV_STATUS_ATTN 0x80000000 // Attention
-#define SXG_RCV_STATUS_TRANSPORT_MASK 0x3F000000 // Transport mask
-#define SXG_RCV_STATUS_TRANSPORT_ERROR 0x20000000 // Transport error
-#define SXG_RCV_STATUS_TRANSPORT_CSUM 0x23000000 // Transport cksum error
-#define SXG_RCV_STATUS_TRANSPORT_UFLOW 0x22000000 // Transport underflow
-#define SXG_RCV_STATUS_TRANSPORT_HDRLEN 0x20000000 // Transport header length
-#define SXG_RCV_STATUS_TRANSPORT_FLAGS 0x10000000 // Transport flags detected
-#define SXG_RCV_STATUS_TRANSPORT_OPTS 0x08000000 // Transport options detected
-#define SXG_RCV_STATUS_TRANSPORT_SESS_MASK 0x07000000 // Transport DDP
-#define SXG_RCV_STATUS_TRANSPORT_DDP 0x06000000 // Transport DDP
-#define SXG_RCV_STATUS_TRANSPORT_iSCSI 0x05000000 // Transport iSCSI
-#define SXG_RCV_STATUS_TRANSPORT_NFS 0x04000000 // Transport NFS
-#define SXG_RCV_STATUS_TRANSPORT_FTP 0x03000000 // Transport FTP
-#define SXG_RCV_STATUS_TRANSPORT_HTTP 0x02000000 // Transport HTTP
-#define SXG_RCV_STATUS_TRANSPORT_SMB 0x01000000 // Transport SMB
-#define SXG_RCV_STATUS_NETWORK_MASK 0x00FF0000 // Network mask
-#define SXG_RCV_STATUS_NETWORK_ERROR 0x00800000 // Network error
-#define SXG_RCV_STATUS_NETWORK_CSUM 0x00830000 // Network cksum error
-#define SXG_RCV_STATUS_NETWORK_UFLOW 0x00820000 // Network underflow error
-#define SXG_RCV_STATUS_NETWORK_HDRLEN 0x00800000 // Network header length
-#define SXG_RCV_STATUS_NETWORK_OFLOW 0x00400000 // Network overflow detected
-#define SXG_RCV_STATUS_NETWORK_MCAST 0x00200000 // Network multicast detected
-#define SXG_RCV_STATUS_NETWORK_OPTIONS 0x00100000 // Network options detected
-#define SXG_RCV_STATUS_NETWORK_OFFSET 0x00080000 // Network offset detected
-#define SXG_RCV_STATUS_NETWORK_FRAGMENT 0x00040000 // Network fragment detected
-#define SXG_RCV_STATUS_NETWORK_TRANS_MASK 0x00030000 // Network transport type mask
-#define SXG_RCV_STATUS_NETWORK_UDP 0x00020000 // UDP
-#define SXG_RCV_STATUS_NETWORK_TCP 0x00010000 // TCP
-#define SXG_RCV_STATUS_IPONLY 0x00008000 // IP-only not TCP
-#define SXG_RCV_STATUS_PKT_PRI 0x00006000 // Receive priority
-#define SXG_RCV_STATUS_PKT_PRI_SHFT 13 // Receive priority shift
-#define SXG_RCV_STATUS_PARITY 0x00001000 // MAC Receive RAM parity error
-#define SXG_RCV_STATUS_ADDRESS_MASK 0x00000F00 // Link address detection mask
-#define SXG_RCV_STATUS_ADDRESS_D 0x00000B00 // Link address D
-#define SXG_RCV_STATUS_ADDRESS_C 0x00000A00 // Link address C
-#define SXG_RCV_STATUS_ADDRESS_B 0x00000900 // Link address B
-#define SXG_RCV_STATUS_ADDRESS_A 0x00000800 // Link address A
-#define SXG_RCV_STATUS_ADDRESS_BCAST 0x00000300 // Link address broadcast
-#define SXG_RCV_STATUS_ADDRESS_MCAST 0x00000200 // Link address multicast
-#define SXG_RCV_STATUS_ADDRESS_CMCAST 0x00000100 // Link control multicast
-#define SXG_RCV_STATUS_LINK_MASK 0x000000FF // Link status mask
-#define SXG_RCV_STATUS_LINK_ERROR 0x00000080 // Link error
-#define SXG_RCV_STATUS_LINK_MASK 0x000000FF // Link status mask
-#define SXG_RCV_STATUS_LINK_PARITY 0x00000087 // RcvMacQ parity error
-#define SXG_RCV_STATUS_LINK_EARLY 0x00000086 // Data early
-#define SXG_RCV_STATUS_LINK_BUFOFLOW 0x00000085 // Buffer overflow
-#define SXG_RCV_STATUS_LINK_CODE 0x00000084 // Link code error
-#define SXG_RCV_STATUS_LINK_DRIBBLE 0x00000083 // Dribble nibble
-#define SXG_RCV_STATUS_LINK_CRC 0x00000082 // CRC error
-#define SXG_RCV_STATUS_LINK_OFLOW 0x00000081 // Link overflow
-#define SXG_RCV_STATUS_LINK_UFLOW 0x00000080 // Link underflow
-#define SXG_RCV_STATUS_LINK_8023 0x00000020 // 802.3
-#define SXG_RCV_STATUS_LINK_SNAP 0x00000010 // Snap
-#define SXG_RCV_STATUS_LINK_VLAN 0x00000008 // VLAN
-#define SXG_RCV_STATUS_LINK_TYPE_MASK 0x00000007 // Network type mask
-#define SXG_RCV_STATUS_LINK_CONTROL 0x00000003 // Control packet
-#define SXG_RCV_STATUS_LINK_IPV6 0x00000002 // IPv6 packet
-#define SXG_RCV_STATUS_LINK_IPV4 0x00000001 // IPv4 packet
-
-/***************************************************************************
- * Sahara receive and transmit configuration registers
- ***************************************************************************/
-#define RCV_CONFIG_RESET 0x80000000 // RcvConfig register reset
-#define RCV_CONFIG_ENABLE 0x40000000 // Enable the receive logic
-#define RCV_CONFIG_ENPARSE 0x20000000 // Enable the receive parser
-#define RCV_CONFIG_SOCKET 0x10000000 // Enable the socket detector
-#define RCV_CONFIG_RCVBAD 0x08000000 // Receive all bad frames
-#define RCV_CONFIG_CONTROL 0x04000000 // Receive all control frames
-#define RCV_CONFIG_RCVPAUSE 0x02000000 // Enable pause transmit when attn
-#define RCV_CONFIG_TZIPV6 0x01000000 // Include TCP port w/ IPv6 toeplitz
-#define RCV_CONFIG_TZIPV4 0x00800000 // Include TCP port w/ IPv4 toeplitz
-#define RCV_CONFIG_FLUSH 0x00400000 // Flush buffers
-#define RCV_CONFIG_PRIORITY_MASK 0x00300000 // Priority level
-#define RCV_CONFIG_HASH_MASK 0x00030000 // Hash depth
-#define RCV_CONFIG_HASH_8 0x00000000 // Hash depth 8
-#define RCV_CONFIG_HASH_16 0x00010000 // Hash depth 16
-#define RCV_CONFIG_HASH_4 0x00020000 // Hash depth 4
-#define RCV_CONFIG_HASH_2 0x00030000 // Hash depth 2
-#define RCV_CONFIG_BUFLEN_MASK 0x0000FFF0 // Buffer length bits 15:4. ie multiple of 16.
-#define RCV_CONFIG_SKT_DIS 0x00000008 // Disable socket detection on attn
-// Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size.
-// We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC,
-// and round up to nearest 16 byte boundary
-#define RCV_CONFIG_BUFSIZE(_MaxFrame) ((((_MaxFrame) + 22) + 15) & RCV_CONFIG_BUFLEN_MASK)
-
-#define XMT_CONFIG_RESET 0x80000000 // XmtConfig register reset
-#define XMT_CONFIG_ENABLE 0x40000000 // Enable transmit logic
-#define XMT_CONFIG_MAC_PARITY 0x20000000 // Inhibit MAC RAM parity error
-#define XMT_CONFIG_BUF_PARITY 0x10000000 // Inhibit D2F buffer parity error
-#define XMT_CONFIG_MEM_PARITY 0x08000000 // Inhibit 1T SRAM parity error
-#define XMT_CONFIG_INVERT_PARITY 0x04000000 // Invert MAC RAM parity
-#define XMT_CONFIG_INITIAL_IPID 0x0000FFFF // Initial IPID
-
-/***************************************************************************
- * A-XGMAC Registers - Occupy 0x80 - 0xD4 of the SXG_HW_REGS
+/* Used to sanity check UCODE_REGS structure */
+#define SXG_REGISTER_SIZE_PER_CPU 0x00002000
+
+/* Sahara receive sequencer status values */
+#define SXG_RCV_STATUS_ATTN 0x80000000 /* Attention */
+#define SXG_RCV_STATUS_TRANSPORT_MASK 0x3F000000 /* Transport mask */
+#define SXG_RCV_STATUS_TRANSPORT_ERROR 0x20000000 /* Transport error */
+/* Transport cksum error */
+#define SXG_RCV_STATUS_TRANSPORT_CSUM 0x23000000
+/* Transport underflow */
+#define SXG_RCV_STATUS_TRANSPORT_UFLOW 0x22000000
+ /* Transport header length */
+#define SXG_RCV_STATUS_TRANSPORT_HDRLEN 0x20000000
+/* Transport flags detected */
+#define SXG_RCV_STATUS_TRANSPORT_FLAGS 0x10000000
+ /* Transport options detected */
+#define SXG_RCV_STATUS_TRANSPORT_OPTS 0x08000000
+#define SXG_RCV_STATUS_TRANSPORT_SESS_MASK 0x07000000 /* Transport DDP */
+#define SXG_RCV_STATUS_TRANSPORT_DDP 0x06000000 /* Transport DDP */
+#define SXG_RCV_STATUS_TRANSPORT_iSCSI 0x05000000 /* Transport iSCSI */
+#define SXG_RCV_STATUS_TRANSPORT_NFS 0x04000000 /* Transport NFS */
+#define SXG_RCV_STATUS_TRANSPORT_FTP 0x03000000 /* Transport FTP */
+#define SXG_RCV_STATUS_TRANSPORT_HTTP 0x02000000 /* Transport HTTP */
+#define SXG_RCV_STATUS_TRANSPORT_SMB 0x01000000 /* Transport SMB */
+#define SXG_RCV_STATUS_NETWORK_MASK 0x00FF0000 /* Network mask */
+#define SXG_RCV_STATUS_NETWORK_ERROR 0x00800000 /* Network error */
+/* Network cksum error */
+#define SXG_RCV_STATUS_NETWORK_CSUM 0x00830000
+/* Network underflow error */
+#define SXG_RCV_STATUS_NETWORK_UFLOW 0x00820000
+ /* Network header length */
+#define SXG_RCV_STATUS_NETWORK_HDRLEN 0x00800000
+ /* Network overflow detected */
+#define SXG_RCV_STATUS_NETWORK_OFLOW 0x00400000
+/* Network multicast detected */
+#define SXG_RCV_STATUS_NETWORK_MCAST 0x00200000
+/* Network options detected */
+#define SXG_RCV_STATUS_NETWORK_OPTIONS 0x00100000
+/* Network offset detected */
+#define SXG_RCV_STATUS_NETWORK_OFFSET 0x00080000
+/* Network fragment detected */
+#define SXG_RCV_STATUS_NETWORK_FRAGMENT 0x00040000
+/* Network transport type mask */
+#define SXG_RCV_STATUS_NETWORK_TRANS_MASK 0x00030000
+#define SXG_RCV_STATUS_NETWORK_UDP 0x00020000 /* UDP */
+#define SXG_RCV_STATUS_NETWORK_TCP 0x00010000 /* TCP */
+#define SXG_RCV_STATUS_IPONLY 0x00008000 /* IP-only not TCP */
+/* Receive priority */
+#define SXG_RCV_STATUS_PKT_PRI 0x00006000
+/* Receive priority shift */
+#define SXG_RCV_STATUS_PKT_PRI_SHFT 13
+/* MAC Receive RAM parity error */
+#define SXG_RCV_STATUS_PARITY 0x00001000
+/* Link address detection mask */
+#define SXG_RCV_STATUS_ADDRESS_MASK 0x00000F00
+
+#define SXG_RCV_STATUS_ADDRESS_D 0x00000B00 /* Link address D */
+#define SXG_RCV_STATUS_ADDRESS_C 0x00000A00 /* Link address C */
+#define SXG_RCV_STATUS_ADDRESS_B 0x00000900 /* Link address B */
+#define SXG_RCV_STATUS_ADDRESS_A 0x00000800 /* Link address A */
+/* Link address broadcast */
+#define SXG_RCV_STATUS_ADDRESS_BCAST 0x00000300
+ /* Link address multicast */
+#define SXG_RCV_STATUS_ADDRESS_MCAST 0x00000200
+/* Link control multicast */
+#define SXG_RCV_STATUS_ADDRESS_CMCAST 0x00000100
+/* Link status mask */
+#define SXG_RCV_STATUS_LINK_MASK 0x000000FF
+#define SXG_RCV_STATUS_LINK_ERROR 0x00000080 /* Link error */
+/* Link status mask */
+#define SXG_RCV_STATUS_LINK_MASK 0x000000FF
+/* RcvMacQ parity error */
+#define SXG_RCV_STATUS_LINK_PARITY 0x00000087
+#define SXG_RCV_STATUS_LINK_EARLY 0x00000086 /* Data early */
+#define SXG_RCV_STATUS_LINK_BUFOFLOW 0x00000085 /* Buffer overflow */
+#define SXG_RCV_STATUS_LINK_CODE 0x00000084 /* Link code error */
+#define SXG_RCV_STATUS_LINK_DRIBBLE 0x00000083 /* Dribble nibble */
+#define SXG_RCV_STATUS_LINK_CRC 0x00000082 /* CRC error */
+#define SXG_RCV_STATUS_LINK_OFLOW 0x00000081 /* Link overflow */
+#define SXG_RCV_STATUS_LINK_UFLOW 0x00000080 /* Link underflow */
+#define SXG_RCV_STATUS_LINK_8023 0x00000020 /* 802.3 */
+#define SXG_RCV_STATUS_LINK_SNAP 0x00000010 /* Snap */
+#define SXG_RCV_STATUS_LINK_VLAN 0x00000008 /* VLAN */
+/* Network type mask */
+#define SXG_RCV_STATUS_LINK_TYPE_MASK 0x00000007
+#define SXG_RCV_STATUS_LINK_CONTROL 0x00000003 /* Control packet */
+#define SXG_RCV_STATUS_LINK_IPV6 0x00000002 /* IPv6 packet */
+#define SXG_RCV_STATUS_LINK_IPV4 0x00000001 /* IPv4 packet */
+
+/* Sahara receive and transmit configuration registers */
+/* RcvConfig register reset */
+#define RCV_CONFIG_RESET 0x80000000
+/* Enable the receive logic */
+#define RCV_CONFIG_ENABLE 0x40000000
+/* Enable the receive parser */
+#define RCV_CONFIG_ENPARSE 0x20000000
+/* Enable the socket detector */
+#define RCV_CONFIG_SOCKET 0x10000000
+#define RCV_CONFIG_RCVBAD 0x08000000 /* Receive all bad frames */
+/* Receive all control frames */
+#define RCV_CONFIG_CONTROL 0x04000000
+/* Enable pause transmit when attn */
+#define RCV_CONFIG_RCVPAUSE 0x02000000
+/* Include TCP port w/ IPv6 toeplitz */
+#define RCV_CONFIG_TZIPV6 0x01000000
+/* Include TCP port w/ IPv4 toeplitz */
+#define RCV_CONFIG_TZIPV4 0x00800000
+#define RCV_CONFIG_FLUSH 0x00400000 /* Flush buffers */
+#define RCV_CONFIG_PRIORITY_MASK 0x00300000 /* Priority level */
+#define RCV_CONFIG_CONN_MASK 0x000C0000 /* Number of connections */
+#define RCV_CONFIG_CONN_4K 0x00000000 /* 4k connections */
+#define RCV_CONFIG_CONN_2K 0x00040000 /* 2k connections */
+#define RCV_CONFIG_CONN_1K 0x00080000 /* 1k connections */
+#define RCV_CONFIG_CONN_512 0x000C0000 /* 512 connections */
+#define RCV_CONFIG_HASH_MASK 0x00030000 /* Hash depth */
+#define RCV_CONFIG_HASH_8 0x00000000 /* Hash depth 8 */
+#define RCV_CONFIG_HASH_16 0x00010000 /* Hash depth 16 */
+#define RCV_CONFIG_HASH_4 0x00020000 /* Hash depth 4 */
+#define RCV_CONFIG_HASH_2 0x00030000 /* Hash depth 2 */
+/* Buffer length bits 15:4. ie multiple of 16. */
+#define RCV_CONFIG_BUFLEN_MASK 0x0000FFE0
+/* Disable socket detection on attn */
+#define RCV_CONFIG_SKT_DIS 0x00000008
+#define RCV_CONFIG_HIPRICTL 0x00000002 /* Ctrl frames on high-prioirty RcvQ */
+#define RCV_CONFIG_NEWSTATUSFMT 0x00000001 /* Use RevB status format */
+/*
+ * Macro to determine RCV_CONFIG_BUFLEN based on maximum frame size.
+ * We add 18 bytes for Sahara receive status and padding, plus 4 bytes for CRC,
+ * and round up to nearest 32 byte boundary
+ */
+#define RCV_CONFIG_BUFSIZE(_MaxFrame) \
+ ((((_MaxFrame) + 22) + 31) & RCV_CONFIG_BUFLEN_MASK)
+
+/* XmtConfig register reset */
+#define XMT_CONFIG_RESET 0x80000000
+#define XMT_CONFIG_ENABLE 0x40000000 /* Enable transmit logic */
+/* Inhibit MAC RAM parity error */
+#define XMT_CONFIG_MAC_PARITY 0x20000000
+/* Inhibit D2F buffer parity error */
+#define XMT_CONFIG_BUF_PARITY 0x10000000
+/* Inhibit 1T SRAM parity error */
+#define XMT_CONFIG_MEM_PARITY 0x08000000
+#define XMT_CONFIG_INVERT_PARITY 0x04000000 /* Invert MAC RAM parity */
+#define XMT_CONFIG_INITIAL_IPID 0x0000FFFF /* Initial IPID */
+
+/*
+ * A-XGMAC Registers - Occupy 0x80 - 0xD4 of the struct sxg_hw_regs
*
* Full register descriptions can be found in axgmac.pdf
- ***************************************************************************/
-// A-XGMAC Configuration Register 0
-#define AXGMAC_CFG0_SUB_RESET 0x80000000 // Sub module reset
-#define AXGMAC_CFG0_RCNTRL_RESET 0x00400000 // Receive control reset
-#define AXGMAC_CFG0_RFUNC_RESET 0x00200000 // Receive function reset
-#define AXGMAC_CFG0_TCNTRL_RESET 0x00040000 // Transmit control reset
-#define AXGMAC_CFG0_TFUNC_RESET 0x00020000 // Transmit function reset
-#define AXGMAC_CFG0_MII_RESET 0x00010000 // MII Management reset
-
-// A-XGMAC Configuration Register 1
-#define AXGMAC_CFG1_XMT_PAUSE 0x80000000 // Allow the sending of Pause frames
-#define AXGMAC_CFG1_XMT_EN 0x40000000 // Enable transmit
-#define AXGMAC_CFG1_RCV_PAUSE 0x20000000 // Allow the detection of Pause frames
-#define AXGMAC_CFG1_RCV_EN 0x10000000 // Enable receive
-#define AXGMAC_CFG1_XMT_STATE 0x04000000 // Current transmit state - READ ONLY
-#define AXGMAC_CFG1_RCV_STATE 0x01000000 // Current receive state - READ ONLY
-#define AXGMAC_CFG1_XOFF_SHORT 0x00001000 // Only pause for 64 slot on XOFF
-#define AXGMAC_CFG1_XMG_FCS1 0x00000400 // Delay transmit FCS 1 4-byte word
-#define AXGMAC_CFG1_XMG_FCS2 0x00000800 // Delay transmit FCS 2 4-byte words
-#define AXGMAC_CFG1_XMG_FCS3 0x00000C00 // Delay transmit FCS 3 4-byte words
-#define AXGMAC_CFG1_RCV_FCS1 0x00000100 // Delay receive FCS 1 4-byte word
-#define AXGMAC_CFG1_RCV_FCS2 0x00000200 // Delay receive FCS 2 4-byte words
-#define AXGMAC_CFG1_RCV_FCS3 0x00000300 // Delay receive FCS 3 4-byte words
-#define AXGMAC_CFG1_PKT_OVERRIDE 0x00000080 // Per-packet override enable
-#define AXGMAC_CFG1_SWAP 0x00000040 // Byte swap enable
-#define AXGMAC_CFG1_SHORT_ASSERT 0x00000020 // ASSERT srdrpfrm on short frame (<64)
-#define AXGMAC_CFG1_RCV_STRICT 0x00000010 // RCV only 802.3AE when CLEAR
-#define AXGMAC_CFG1_CHECK_LEN 0x00000008 // Verify frame length
-#define AXGMAC_CFG1_GEN_FCS 0x00000004 // Generate FCS
-#define AXGMAC_CFG1_PAD_MASK 0x00000003 // Mask for pad bits
-#define AXGMAC_CFG1_PAD_64 0x00000001 // Pad frames to 64 bytes
-#define AXGMAC_CFG1_PAD_VLAN 0x00000002 // Detect VLAN and pad to 68 bytes
-#define AXGMAC_CFG1_PAD_68 0x00000003 // Pad to 68 bytes
-
-// A-XGMAC Configuration Register 2
-#define AXGMAC_CFG2_GEN_PAUSE 0x80000000 // Generate single pause frame (test)
-#define AXGMAC_CFG2_LF_MANUAL 0x08000000 // Manual link fault sequence
-#define AXGMAC_CFG2_LF_AUTO 0x04000000 // Auto link fault sequence
-#define AXGMAC_CFG2_LF_REMOTE 0x02000000 // Remote link fault (READ ONLY)
-#define AXGMAC_CFG2_LF_LOCAL 0x01000000 // Local link fault (READ ONLY)
-#define AXGMAC_CFG2_IPG_MASK 0x001F0000 // Inter packet gap
+ */
+/* A-XGMAC Configuration Register 0 */
+#define AXGMAC_CFG0_SUB_RESET 0x80000000 /* Sub module reset */
+#define AXGMAC_CFG0_RCNTRL_RESET 0x00400000 /* Receive control reset */
+#define AXGMAC_CFG0_RFUNC_RESET 0x00200000 /* Receive function reset */
+#define AXGMAC_CFG0_TCNTRL_RESET 0x00040000 /* Transmit control reset */
+#define AXGMAC_CFG0_TFUNC_RESET 0x00020000 /* Transmit function reset */
+#define AXGMAC_CFG0_MII_RESET 0x00010000 /* MII Management reset */
+
+/* A-XGMAC Configuration Register 1 */
+/* Allow the sending of Pause frames */
+#define AXGMAC_CFG1_XMT_PAUSE 0x80000000
+#define AXGMAC_CFG1_XMT_EN 0x40000000 /* Enable transmit */
+/* Allow the detection of Pause frames */
+#define AXGMAC_CFG1_RCV_PAUSE 0x20000000
+#define AXGMAC_CFG1_RCV_EN 0x10000000 /* Enable receive */
+/* Current transmit state - READ ONLY */
+#define AXGMAC_CFG1_XMT_STATE 0x04000000
+/* Current receive state - READ ONLY */
+#define AXGMAC_CFG1_RCV_STATE 0x01000000
+/* Only pause for 64 slot on XOFF */
+#define AXGMAC_CFG1_XOFF_SHORT 0x00001000
+/* Delay transmit FCS 1 4-byte word */
+#define AXGMAC_CFG1_XMG_FCS1 0x00000400
+/* Delay transmit FCS 2 4-byte words */
+#define AXGMAC_CFG1_XMG_FCS2 0x00000800
+/* Delay transmit FCS 3 4-byte words */
+#define AXGMAC_CFG1_XMG_FCS3 0x00000C00
+/* Delay receive FCS 1 4-byte word */
+#define AXGMAC_CFG1_RCV_FCS1 0x00000100
+/* Delay receive FCS 2 4-byte words */
+#define AXGMAC_CFG1_RCV_FCS2 0x00000200
+/* Delay receive FCS 3 4-byte words */
+#define AXGMAC_CFG1_RCV_FCS3 0x00000300
+/* Per-packet override enable */
+#define AXGMAC_CFG1_PKT_OVERRIDE 0x00000080
+#define AXGMAC_CFG1_SWAP 0x00000040 /* Byte swap enable */
+/* ASSERT srdrpfrm on short frame (<64) */
+#define AXGMAC_CFG1_SHORT_ASSERT 0x00000020
+/* RCV only 802.3AE when CLEAR */
+#define AXGMAC_CFG1_RCV_STRICT 0x00000010
+#define AXGMAC_CFG1_CHECK_LEN 0x00000008 /* Verify frame length */
+#define AXGMAC_CFG1_GEN_FCS 0x00000004 /* Generate FCS */
+#define AXGMAC_CFG1_PAD_MASK 0x00000003 /* Mask for pad bits */
+#define AXGMAC_CFG1_PAD_64 0x00000001 /* Pad frames to 64 bytes */
+/* Detect VLAN and pad to 68 bytes */
+#define AXGMAC_CFG1_PAD_VLAN 0x00000002
+#define AXGMAC_CFG1_PAD_68 0x00000003 /* Pad to 68 bytes */
+
+/* A-XGMAC Configuration Register 2 */
+/* Generate single pause frame (test) */
+#define AXGMAC_CFG2_GEN_PAUSE 0x80000000
+/* Manual link fault sequence */
+#define AXGMAC_CFG2_LF_MANUAL 0x08000000
+/* Auto link fault sequence */
+#define AXGMAC_CFG2_LF_AUTO 0x04000000
+/* Remote link fault (READ ONLY) */
+#define AXGMAC_CFG2_LF_REMOTE 0x02000000
+/* Local link fault (READ ONLY) */
+#define AXGMAC_CFG2_LF_LOCAL 0x01000000
+#define AXGMAC_CFG2_IPG_MASK 0x001F0000 /* Inter packet gap */
#define AXGMAC_CFG2_IPG_SHIFT 16
-#define AXGMAC_CFG2_PAUSE_XMT 0x00008000 // Pause transmit module
-#define AXGMAC_CFG2_IPG_EXTEN 0x00000020 // Enable IPG extension algorithm
-#define AXGMAC_CFG2_IPGEX_MASK 0x0000001F // IPG extension
-
-// A-XGMAC Configuration Register 3
-#define AXGMAC_CFG3_RCV_DROP 0xFFFF0000 // Receive frame drop filter
-#define AXGMAC_CFG3_RCV_DONT_CARE 0x0000FFFF // Receive frame don't care filter
-
-// A-XGMAC Station Address Register - Octets 1-4
-#define AXGMAC_SARLOW_OCTET_ONE 0xFF000000 // First octet
-#define AXGMAC_SARLOW_OCTET_TWO 0x00FF0000 // Second octet
-#define AXGMAC_SARLOW_OCTET_THREE 0x0000FF00 // Third octet
-#define AXGMAC_SARLOW_OCTET_FOUR 0x000000FF // Fourth octet
-
-// A-XGMAC Station Address Register - Octets 5-6
-#define AXGMAC_SARHIGH_OCTET_FIVE 0xFF000000 // Fifth octet
-#define AXGMAC_SARHIGH_OCTET_SIX 0x00FF0000 // Sixth octet
-
-// A-XGMAC Maximum frame length register
-#define AXGMAC_MAXFRAME_XMT 0x3FFF0000 // Maximum transmit frame length
+#define AXGMAC_CFG2_PAUSE_XMT 0x00008000 /* Pause transmit module */
+/* Enable IPG extension algorithm */
+#define AXGMAC_CFG2_IPG_EXTEN 0x00000020
+#define AXGMAC_CFG2_IPGEX_MASK 0x0000001F /* IPG extension */
+
+/* A-XGMAC Configuration Register 3 */
+/* Receive frame drop filter */
+#define AXGMAC_CFG3_RCV_DROP 0xFFFF0000
+/* Receive frame don't care filter */
+#define AXGMAC_CFG3_RCV_DONT_CARE 0x0000FFFF
+
+/* A-XGMAC Station Address Register - Octets 1-4 */
+#define AXGMAC_SARLOW_OCTET_ONE 0xFF000000 /* First octet */
+#define AXGMAC_SARLOW_OCTET_TWO 0x00FF0000 /* Second octet */
+#define AXGMAC_SARLOW_OCTET_THREE 0x0000FF00 /* Third octet */
+#define AXGMAC_SARLOW_OCTET_FOUR 0x000000FF /* Fourth octet */
+
+/* A-XGMAC Station Address Register - Octets 5-6 */
+#define AXGMAC_SARHIGH_OCTET_FIVE 0xFF000000 /* Fifth octet */
+#define AXGMAC_SARHIGH_OCTET_SIX 0x00FF0000 /* Sixth octet */
+
+/* A-XGMAC Maximum frame length register */
+/* Maximum transmit frame length */
+#define AXGMAC_MAXFRAME_XMT 0x3FFF0000
#define AXGMAC_MAXFRAME_XMT_SHIFT 16
-#define AXGMAC_MAXFRAME_RCV 0x0000FFFF // Maximum receive frame length
-// This register doesn't need to be written for standard MTU.
-// For jumbo, I'll just statically define the value here. This
-// value sets the receive byte count to 9036 (0x234C) and the
-// transmit WORD count to 2259 (0x8D3). These values include 22
-// bytes of padding beyond the jumbo MTU of 9014
+/* Maximum receive frame length */
+#define AXGMAC_MAXFRAME_RCV 0x0000FFFF
+/*
+ * This register doesn't need to be written for standard MTU.
+ * For jumbo, I'll just statically define the value here. This
+ * value sets the receive byte count to 9036 (0x234C) and the
+ * transmit WORD count to 2259 (0x8D3). These values include 22
+ * bytes of padding beyond the jumbo MTU of 9014
+ */
#define AXGMAC_MAXFRAME_JUMBO 0x08D3234C
-// A-XGMAC Revision level
-#define AXGMAC_REVISION_MASK 0x0000FFFF // Revision level
-
-// A-XGMAC AMIIM Command Register
-#define AXGMAC_AMIIM_CMD_START 0x00000008 // Command start
-#define AXGMAC_AMIIM_CMD_MASK 0x00000007 // Command
-#define AXGMAC_AMIIM_CMD_LEGACY_WRITE 1 // 10/100/1000 Mbps Phy Write
-#define AXGMAC_AMIIM_CMD_LEGACY_READ 2 // 10/100/1000 Mbps Phy Read
-#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE 3 // Monitor single PHY
-#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE 4 // Monitor multiple contiguous PHYs
-#define AXGMAC_AMIIM_CMD_10G_OPERATION 5 // Present AMIIM Field Reg
-#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL 6 // Clear Link Fail Bit in MIIM
-
-// A-XGMAC AMIIM Field Register
-#define AXGMAC_AMIIM_FIELD_ST 0xC0000000 // 2-bit ST field
+/* A-XGMAC Revision level */
+#define AXGMAC_REVISION_MASK 0x0000FFFF /* Revision level */
+
+/* A-XGMAC AMIIM Command Register */
+#define AXGMAC_AMIIM_CMD_START 0x00000008 /* Command start */
+#define AXGMAC_AMIIM_CMD_MASK 0x00000007 /* Command */
+/* 10/100/1000 Mbps Phy Write */
+#define AXGMAC_AMIIM_CMD_LEGACY_WRITE 1
+/* 10/100/1000 Mbps Phy Read */
+#define AXGMAC_AMIIM_CMD_LEGACY_READ 2
+#define AXGMAC_AMIIM_CMD_MONITOR_SINGLE 3 /* Monitor single PHY */
+/* Monitor multiple contiguous PHYs */
+#define AXGMAC_AMIIM_CMD_MONITOR_MULTIPLE 4
+/* Present AMIIM Field Reg */
+#define AXGMAC_AMIIM_CMD_10G_OPERATION 5
+/* Clear Link Fail Bit in MIIM */
+#define AXGMAC_AMIIM_CMD_CLEAR_LINK_FAIL 6
+
+/* A-XGMAC AMIIM Field Register */
+#define AXGMAC_AMIIM_FIELD_ST 0xC0000000 /* 2-bit ST field */
#define AXGMAC_AMIIM_FIELD_ST_SHIFT 30
-#define AXGMAC_AMIIM_FIELD_OP 0x30000000 // 2-bit OP field
+#define AXGMAC_AMIIM_FIELD_OP 0x30000000 /* 2-bit OP field */
#define AXGMAC_AMIIM_FIELD_OP_SHIFT 28
-#define AXGMAC_AMIIM_FIELD_PORT_ADDR 0x0F800000 // Port address field (hstphyadx in spec)
+/* Port address field (hstphyadx in spec) */
+#define AXGMAC_AMIIM_FIELD_PORT_ADDR 0x0F800000
#define AXGMAC_AMIIM_FIELD_PORT_SHIFT 23
-#define AXGMAC_AMIIM_FIELD_DEV_ADDR 0x007C0000 // Device address field (hstregadx in spec)
+/* Device address field (hstregadx in spec) */
+#define AXGMAC_AMIIM_FIELD_DEV_ADDR 0x007C0000
#define AXGMAC_AMIIM_FIELD_DEV_SHIFT 18
-#define AXGMAC_AMIIM_FIELD_TA 0x00030000 // 2-bit TA field
+#define AXGMAC_AMIIM_FIELD_TA 0x00030000 /* 2-bit TA field */
#define AXGMAC_AMIIM_FIELD_TA_SHIFT 16
-#define AXGMAC_AMIIM_FIELD_DATA 0x0000FFFF // Data field
+#define AXGMAC_AMIIM_FIELD_DATA 0x0000FFFF /* Data field */
-// Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register
-#define MIIM_OP_ADDR 0 // MIIM Address set operation
-#define MIIM_OP_WRITE 1 // MIIM Write register operation
-#define MIIM_OP_READ 2 // MIIM Read register operation
+/* Values for the AXGMAC_AMIIM_FIELD_OP field in the A-XGMAC AMIIM Field Register */
+#define MIIM_OP_ADDR 0 /* MIIM Address set operation */
+#define MIIM_OP_WRITE 1 /* MIIM Write register operation */
+#define MIIM_OP_READ 2 /* MIIM Read register operation */
#define MIIM_OP_ADDR_SHIFT (MIIM_OP_ADDR << AXGMAC_AMIIM_FIELD_OP_SHIFT)
-// Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM Field Register
-#define MIIM_PORT_NUM 1 // All Sahara MIIM modules use port 1
-
-// Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM Field Register
-#define MIIM_DEV_PHY_PMA 1 // PHY PMA/PMD module MIIM device number
-#define MIIM_DEV_PHY_PCS 3 // PHY PCS module MIIM device number
-#define MIIM_DEV_PHY_XS 4 // PHY XS module MIIM device number
-#define MIIM_DEV_XGXS 5 // XGXS MIIM device number
-
-// Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field Register
-#define MIIM_TA_10GB 2 // set to 2 for 10 GB operation
-
-// A-XGMAC AMIIM Configuration Register
-#define AXGMAC_AMIIM_CFG_NOPREAM 0x00000080 // Bypass preamble of mngmt frame
-#define AXGMAC_AMIIM_CFG_HALF_CLOCK 0x0000007F // half-clock duration of MDC output
-
-// A-XGMAC AMIIM Indicator Register
-#define AXGMAC_AMIIM_INDC_LINK 0x00000010 // Link status from legacy PHY or MMD
-#define AXGMAC_AMIIM_INDC_MPHY 0x00000008 // Multiple phy operation in progress
-#define AXGMAC_AMIIM_INDC_SPHY 0x00000004 // Single phy operation in progress
-#define AXGMAC_AMIIM_INDC_MON 0x00000002 // Single or multiple monitor cmd
-#define AXGMAC_AMIIM_INDC_BUSY 0x00000001 // Set until cmd operation complete
-
-// Link Status and Control Register
-#define LS_PHY_CLR_RESET 0x80000000 // Clear reset signal to PHY
-#define LS_SERDES_POWER_DOWN 0x40000000 // Power down the Sahara Serdes
-#define LS_XGXS_ENABLE 0x20000000 // Enable the XAUI XGXS logic
-#define LS_XGXS_CTL 0x10000000 // Hold XAUI XGXS logic reset until Serdes is up
-#define LS_SERDES_DOWN 0x08000000 // When 0, XAUI Serdes is up and initialization is complete
-#define LS_TRACE_DOWN 0x04000000 // When 0, Trace Serdes is up and initialization is complete
-#define LS_PHY_CLK_25MHZ 0x02000000 // Set PHY clock to 25 MHz (else 156.125 MHz)
-#define LS_PHY_CLK_EN 0x01000000 // Enable clock to PHY
-#define LS_XAUI_LINK_UP 0x00000010 // XAUI link is up
-#define LS_XAUI_LINK_CHNG 0x00000008 // XAUI link status has changed
-#define LS_LINK_ALARM 0x00000004 // Link alarm pin
-#define LS_ATTN_CTRL_MASK 0x00000003 // Mask link attention control bits
-#define LS_ATTN_ALARM 0x00000000 // 00 => Attn on link alarm
-#define LS_ATTN_ALARM_OR_STAT_CHNG 0x00000001 // 01 => Attn on link alarm or status change
-#define LS_ATTN_STAT_CHNG 0x00000002 // 10 => Attn on link status change
-#define LS_ATTN_NONE 0x00000003 // 11 => no Attn
-
-// Link Address High Registers
-#define LINK_ADDR_ENABLE 0x80000000 // Enable this link address
-
-
-/***************************************************************************
+/*
+ * Values for the AXGMAC_AMIIM_FIELD_PORT_ADDR field in the A-XGMAC AMIIM
+ * Field Register
+ */
+#define MIIM_PORT_NUM 1 /* All Sahara MIIM modules use port 1 */
+
+/*
+ * Values for the AXGMAC_AMIIM_FIELD_DEV_ADDR field in the A-XGMAC AMIIM
+ * Field Register
+ */
+/* PHY PMA/PMD module MIIM device number */
+#define MIIM_DEV_PHY_PMA 1
+/* PHY PCS module MIIM device number */
+#define MIIM_DEV_PHY_PCS 3
+/* PHY XS module MIIM device number */
+#define MIIM_DEV_PHY_XS 4
+#define MIIM_DEV_XGXS 5 /* XGXS MIIM device number */
+
+/*
+ * Values for the AXGMAC_AMIIM_FIELD_TA field in the A-XGMAC AMIIM Field
+ * Register
+ */
+#define MIIM_TA_10GB 2 /* set to 2 for 10 GB operation */
+
+/* A-XGMAC AMIIM Configuration Register */
+/* Bypass preamble of mngmt frame */
+#define AXGMAC_AMIIM_CFG_NOPREAM 0x00000080
+/* half-clock duration of MDC output */
+#define AXGMAC_AMIIM_CFG_HALF_CLOCK 0x0000007F
+
+/* A-XGMAC AMIIM Indicator Register */
+/* Link status from legacy PHY or MMD */
+#define AXGMAC_AMIIM_INDC_LINK 0x00000010
+/* Multiple phy operation in progress */
+#define AXGMAC_AMIIM_INDC_MPHY 0x00000008
+/* Single phy operation in progress */
+#define AXGMAC_AMIIM_INDC_SPHY 0x00000004
+/* Single or multiple monitor cmd */
+#define AXGMAC_AMIIM_INDC_MON 0x00000002
+/* Set until cmd operation complete */
+#define AXGMAC_AMIIM_INDC_BUSY 0x00000001
+
+/* Link Status and Control Register */
+#define LS_PHY_CLR_RESET 0x80000000 /* Clear reset signal to PHY */
+#define LS_SERDES_POWER_DOWN 0x40000000 /* Power down the Sahara Serdes */
+#define LS_XGXS_ENABLE 0x20000000 /* Enable the XAUI XGXS logic */
+/* Hold XAUI XGXS logic reset until Serdes is up */
+#define LS_XGXS_CTL 0x10000000
+/* When 0, XAUI Serdes is up and initialization is complete */
+#define LS_SERDES_DOWN 0x08000000
+/* When 0, Trace Serdes is up and initialization is complete */
+#define LS_TRACE_DOWN 0x04000000
+/* Set PHY clock to 25 MHz (else 156.125 MHz) */
+#define LS_PHY_CLK_25MHZ 0x02000000
+#define LS_PHY_CLK_EN 0x01000000 /* Enable clock to PHY */
+#define LS_XAUI_LINK_UP 0x00000010 /* XAUI link is up */
+/* XAUI link status has changed */
+#define LS_XAUI_LINK_CHNG 0x00000008
+#define LS_LINK_ALARM 0x00000004 /* Link alarm pin */
+/* Mask link attention control bits */
+#define LS_ATTN_CTRL_MASK 0x00000003
+#define LS_ATTN_ALARM 0x00000000 /* 00 => Attn on link alarm */
+/* 01 => Attn on link alarm or status change */
+#define LS_ATTN_ALARM_OR_STAT_CHNG 0x00000001
+/* 10 => Attn on link status change */
+#define LS_ATTN_STAT_CHNG 0x00000002
+#define LS_ATTN_NONE 0x00000003 /* 11 => no Attn */
+
+/* Link Address High Registers */
+#define LINK_ADDR_ENABLE 0x80000000 /* Enable this link address */
+
+
+/*
* XGXS XAUI XGMII Extender registers
*
* Full register descriptions can be found in mxgxs.pdf
- ***************************************************************************/
-// XGXS Register Map
-#define XGXS_ADDRESS_CONTROL1 0x0000 // XS Control 1
-#define XGXS_ADDRESS_STATUS1 0x0001 // XS Status 1
-#define XGXS_ADDRESS_DEVID_LOW 0x0002 // XS Device ID (low)
-#define XGXS_ADDRESS_DEVID_HIGH 0x0003 // XS Device ID (high)
-#define XGXS_ADDRESS_SPEED 0x0004 // XS Speed ability
-#define XGXS_ADDRESS_DEV_LOW 0x0005 // XS Devices in package
-#define XGXS_ADDRESS_DEV_HIGH 0x0006 // XS Devices in package
-#define XGXS_ADDRESS_STATUS2 0x0008 // XS Status 2
-#define XGXS_ADDRESS_PKGID_lOW 0x000E // XS Package Identifier
-#define XGXS_ADDRESS_PKGID_HIGH 0x000F // XS Package Identifier
-#define XGXS_ADDRESS_LANE_STATUS 0x0018 // 10G XGXS Lane Status
-#define XGXS_ADDRESS_TEST_CTRL 0x0019 // 10G XGXS Test Control
-#define XGXS_ADDRESS_RESET_LO1 0x8000 // Vendor-Specific Reset Lo 1
-#define XGXS_ADDRESS_RESET_LO2 0x8001 // Vendor-Specific Reset Lo 2
-#define XGXS_ADDRESS_RESET_HI1 0x8002 // Vendor-Specific Reset Hi 1
-#define XGXS_ADDRESS_RESET_HI2 0x8003 // Vendor-Specific Reset Hi 2
-
-// XS Control 1 register bit definitions
-#define XGXS_CONTROL1_RESET 0x8000 // Reset - self clearing
-#define XGXS_CONTROL1_LOOPBACK 0x4000 // Enable loopback
-#define XGXS_CONTROL1_SPEED1 0x2000 // 0 = unspecified, 1 = 10Gb+
-#define XGXS_CONTROL1_LOWPOWER 0x0400 // 1 = Low power mode
-#define XGXS_CONTROL1_SPEED2 0x0040 // Same as SPEED1 (?)
-#define XGXS_CONTROL1_SPEED 0x003C // Everything reserved except zero (?)
-
-// XS Status 1 register bit definitions
-#define XGXS_STATUS1_FAULT 0x0080 // Fault detected
-#define XGXS_STATUS1_LINK 0x0004 // 1 = Link up
-#define XGXS_STATUS1_LOWPOWER 0x0002 // 1 = Low power supported
-
-// XS Speed register bit definitions
-#define XGXS_SPEED_10G 0x0001 // 1 = 10G capable
-
-// XS Devices register bit definitions
-#define XGXS_DEVICES_DTE 0x0020 // DTE XS Present
-#define XGXS_DEVICES_PHY 0x0010 // PHY XS Present
-#define XGXS_DEVICES_PCS 0x0008 // PCS Present
-#define XGXS_DEVICES_WIS 0x0004 // WIS Present
-#define XGXS_DEVICES_PMD 0x0002 // PMD/PMA Present
-#define XGXS_DEVICES_CLAUSE22 0x0001 // Clause 22 registers present
-
-// XS Devices High register bit definitions
-#define XGXS_DEVICES_VENDOR2 0x8000 // Vendor specific device 2
-#define XGXS_DEVICES_VENDOR1 0x4000 // Vendor specific device 1
-
-// XS Status 2 register bit definitions
-#define XGXS_STATUS2_DEV_MASK 0xC000 // Device present mask
-#define XGXS_STATUS2_DEV_RESPOND 0x8000 // Device responding
-#define XGXS_STATUS2_XMT_FAULT 0x0800 // Transmit fault
-#define XGXS_STATUS2_RCV_FAULT 0x0400 // Receive fault
-
-// XS Package ID High register bit definitions
-#define XGXS_PKGID_HIGH_ORG 0xFC00 // Organizationally Unique
-#define XGXS_PKGID_HIGH_MFG 0x03F0 // Manufacturer Model
-#define XGXS_PKGID_HIGH_REV 0x000F // Revision Number
-
-// XS Lane Status register bit definitions
-#define XGXS_LANE_PHY 0x1000 // PHY/DTE lane alignment status
-#define XGXS_LANE_PATTERN 0x0800 // Pattern testing ability
-#define XGXS_LANE_LOOPBACK 0x0400 // PHY loopback ability
-#define XGXS_LANE_SYNC3 0x0008 // Lane 3 sync
-#define XGXS_LANE_SYNC2 0x0004 // Lane 2 sync
-#define XGXS_LANE_SYNC1 0x0002 // Lane 1 sync
-#define XGXS_LANE_SYNC0 0x0001 // Lane 0 sync
-
-// XS Test Control register bit definitions
-#define XGXS_TEST_PATTERN_ENABLE 0x0004 // Test pattern enabled
-#define XGXS_TEST_PATTERN_MASK 0x0003 // Test patterns
-#define XGXS_TEST_PATTERN_RSVD 0x0003 // Test pattern - reserved
-#define XGXS_TEST_PATTERN_MIX 0x0002 // Test pattern - mixed
-#define XGXS_TEST_PATTERN_LOW 0x0001 // Test pattern - low
-#define XGXS_TEST_PATTERN_HIGH 0x0001 // Test pattern - high
-
-/***************************************************************************
+ */
+/* XGXS Register Map */
+#define XGXS_ADDRESS_CONTROL1 0x0000 /* XS Control 1 */
+#define XGXS_ADDRESS_STATUS1 0x0001 /* XS Status 1 */
+#define XGXS_ADDRESS_DEVID_LOW 0x0002 /* XS Device ID (low) */
+#define XGXS_ADDRESS_DEVID_HIGH 0x0003 /* XS Device ID (high) */
+#define XGXS_ADDRESS_SPEED 0x0004 /* XS Speed ability */
+#define XGXS_ADDRESS_DEV_LOW 0x0005 /* XS Devices in package */
+#define XGXS_ADDRESS_DEV_HIGH 0x0006 /* XS Devices in package */
+#define XGXS_ADDRESS_STATUS2 0x0008 /* XS Status 2 */
+#define XGXS_ADDRESS_PKGID_lOW 0x000E /* XS Package Identifier */
+#define XGXS_ADDRESS_PKGID_HIGH 0x000F /* XS Package Identifier */
+#define XGXS_ADDRESS_LANE_STATUS 0x0018 /* 10G XGXS Lane Status */
+#define XGXS_ADDRESS_TEST_CTRL 0x0019 /* 10G XGXS Test Control */
+#define XGXS_ADDRESS_RESET_LO1 0x8000 /* Vendor-Specific Reset Lo 1 */
+#define XGXS_ADDRESS_RESET_LO2 0x8001 /* Vendor-Specific Reset Lo 2 */
+#define XGXS_ADDRESS_RESET_HI1 0x8002 /* Vendor-Specific Reset Hi 1 */
+#define XGXS_ADDRESS_RESET_HI2 0x8003 /* Vendor-Specific Reset Hi 2 */
+
+/* XS Control 1 register bit definitions */
+#define XGXS_CONTROL1_RESET 0x8000 /* Reset - self clearing */
+#define XGXS_CONTROL1_LOOPBACK 0x4000 /* Enable loopback */
+#define XGXS_CONTROL1_SPEED1 0x2000 /* 0 = unspecified, 1 = 10Gb+ */
+#define XGXS_CONTROL1_LOWPOWER 0x0400 /* 1 = Low power mode */
+#define XGXS_CONTROL1_SPEED2 0x0040 /* Same as SPEED1 (?) */
+/* Everything reserved except zero (?) */
+#define XGXS_CONTROL1_SPEED 0x003C
+
+/* XS Status 1 register bit definitions */
+#define XGXS_STATUS1_FAULT 0x0080 /* Fault detected */
+#define XGXS_STATUS1_LINK 0x0004 /* 1 = Link up */
+#define XGXS_STATUS1_LOWPOWER 0x0002 /* 1 = Low power supported */
+
+/* XS Speed register bit definitions */
+#define XGXS_SPEED_10G 0x0001 /* 1 = 10G capable */
+
+/* XS Devices register bit definitions */
+#define XGXS_DEVICES_DTE 0x0020 /* DTE XS Present */
+#define XGXS_DEVICES_PHY 0x0010 /* PHY XS Present */
+#define XGXS_DEVICES_PCS 0x0008 /* PCS Present */
+#define XGXS_DEVICES_WIS 0x0004 /* WIS Present */
+#define XGXS_DEVICES_PMD 0x0002 /* PMD/PMA Present */
+#define XGXS_DEVICES_CLAUSE22 0x0001 /* Clause 22 registers present*/
+
+/* XS Devices High register bit definitions */
+#define XGXS_DEVICES_VENDOR2 0x8000 /* Vendor specific device 2 */
+#define XGXS_DEVICES_VENDOR1 0x4000 /* Vendor specific device 1 */
+
+/* XS Status 2 register bit definitions */
+#define XGXS_STATUS2_DEV_MASK 0xC000 /* Device present mask */
+#define XGXS_STATUS2_DEV_RESPOND 0x8000 /* Device responding */
+#define XGXS_STATUS2_XMT_FAULT 0x0800 /* Transmit fault */
+#define XGXS_STATUS2_RCV_FAULT 0x0400 /* Receive fault */
+
+/* XS Package ID High register bit definitions */
+#define XGXS_PKGID_HIGH_ORG 0xFC00 /* Organizationally Unique */
+#define XGXS_PKGID_HIGH_MFG 0x03F0 /* Manufacturer Model */
+#define XGXS_PKGID_HIGH_REV 0x000F /* Revision Number */
+
+/* XS Lane Status register bit definitions */
+#define XGXS_LANE_PHY 0x1000 /* PHY/DTE lane alignment status */
+#define XGXS_LANE_PATTERN 0x0800 /* Pattern testing ability */
+#define XGXS_LANE_LOOPBACK 0x0400 /* PHY loopback ability */
+#define XGXS_LANE_SYNC3 0x0008 /* Lane 3 sync */
+#define XGXS_LANE_SYNC2 0x0004 /* Lane 2 sync */
+#define XGXS_LANE_SYNC1 0x0002 /* Lane 1 sync */
+#define XGXS_LANE_SYNC0 0x0001 /* Lane 0 sync */
+
+/* XS Test Control register bit definitions */
+#define XGXS_TEST_PATTERN_ENABLE 0x0004 /* Test pattern enabled */
+#define XGXS_TEST_PATTERN_MASK 0x0003 /* Test patterns */
+#define XGXS_TEST_PATTERN_RSVD 0x0003 /* Test pattern - reserved */
+#define XGXS_TEST_PATTERN_MIX 0x0002 /* Test pattern - mixed */
+#define XGXS_TEST_PATTERN_LOW 0x0001 /* Test pattern - low */
+#define XGXS_TEST_PATTERN_HIGH 0x0001 /* Test pattern - high */
+
+/*
* External MDIO Bus Registers
*
* Full register descriptions can be found in PHY/XENPAK/IEEE specs
- ***************************************************************************/
-// LASI (Link Alarm Status Interrupt) Registers (located in MIIM_DEV_PHY_PMA device)
-#define LASI_RX_ALARM_CONTROL 0x9000 // LASI RX_ALARM Control
-#define LASI_TX_ALARM_CONTROL 0x9001 // LASI TX_ALARM Control
-#define LASI_CONTROL 0x9002 // LASI Control
-#define LASI_RX_ALARM_STATUS 0x9003 // LASI RX_ALARM Status
-#define LASI_TX_ALARM_STATUS 0x9004 // LASI TX_ALARM Status
-#define LASI_STATUS 0x9005 // LASI Status
-
-// LASI_CONTROL bit definitions
-#define LASI_CTL_RX_ALARM_ENABLE 0x0004 // Enable RX_ALARM interrupts
-#define LASI_CTL_TX_ALARM_ENABLE 0x0002 // Enable TX_ALARM interrupts
-#define LASI_CTL_LS_ALARM_ENABLE 0x0001 // Enable Link Status interrupts
-
-// LASI_STATUS bit definitions
-#define LASI_STATUS_RX_ALARM 0x0004 // RX_ALARM status
-#define LASI_STATUS_TX_ALARM 0x0002 // TX_ALARM status
-#define LASI_STATUS_LS_ALARM 0x0001 // Link Status
-
-// PHY registers - PMA/PMD (device 1)
-#define PHY_PMA_CONTROL1 0x0000 // PMA/PMD Control 1
-#define PHY_PMA_STATUS1 0x0001 // PMA/PMD Status 1
-#define PHY_PMA_RCV_DET 0x000A // PMA/PMD Receive Signal Detect
- // other PMA/PMD registers exist and can be defined as needed
-
-// PHY registers - PCS (device 3)
-#define PHY_PCS_CONTROL1 0x0000 // PCS Control 1
-#define PHY_PCS_STATUS1 0x0001 // PCS Status 1
-#define PHY_PCS_10G_STATUS1 0x0020 // PCS 10GBASE-R Status 1
- // other PCS registers exist and can be defined as needed
-
-// PHY registers - XS (device 4)
-#define PHY_XS_CONTROL1 0x0000 // XS Control 1
-#define PHY_XS_STATUS1 0x0001 // XS Status 1
-#define PHY_XS_LANE_STATUS 0x0018 // XS Lane Status
- // other XS registers exist and can be defined as needed
-
-// PHY_PMA_CONTROL1 register bit definitions
-#define PMA_CONTROL1_RESET 0x8000 // PMA/PMD reset
-
-// PHY_PMA_RCV_DET register bit definitions
-#define PMA_RCV_DETECT 0x0001 // PMA/PMD receive signal detect
-
-// PHY_PCS_10G_STATUS1 register bit definitions
-#define PCS_10B_BLOCK_LOCK 0x0001 // PCS 10GBASE-R locked to receive blocks
-
-// PHY_XS_LANE_STATUS register bit definitions
-#define XS_LANE_ALIGN 0x1000 // XS transmit lanes aligned
-
-// PHY Microcode download data structure
-struct PHY_UCODE {
+ */
+/*
+ * LASI (Link Alarm Status Interrupt) Registers (located in
+ * MIIM_DEV_PHY_PMA device)
+ */
+#define LASI_RX_ALARM_CONTROL 0x9000 /* LASI RX_ALARM Control */
+#define LASI_TX_ALARM_CONTROL 0x9001 /* LASI TX_ALARM Control */
+#define LASI_CONTROL 0x9002 /* LASI Control */
+#define LASI_RX_ALARM_STATUS 0x9003 /* LASI RX_ALARM Status */
+#define LASI_TX_ALARM_STATUS 0x9004 /* LASI TX_ALARM Status */
+#define LASI_STATUS 0x9005 /* LASI Status */
+
+/* LASI_CONTROL bit definitions */
+/* Enable RX_ALARM interrupts */
+#define LASI_CTL_RX_ALARM_ENABLE 0x0004
+/* Enable TX_ALARM interrupts */
+#define LASI_CTL_TX_ALARM_ENABLE 0x0002
+/* Enable Link Status interrupts */
+#define LASI_CTL_LS_ALARM_ENABLE 0x0001
+
+/* LASI_STATUS bit definitions */
+#define LASI_STATUS_RX_ALARM 0x0004 /* RX_ALARM status */
+#define LASI_STATUS_TX_ALARM 0x0002 /* TX_ALARM status */
+#define LASI_STATUS_LS_ALARM 0x0001 /* Link Status */
+
+/* PHY registers - PMA/PMD (device 1) */
+#define PHY_PMA_CONTROL1 0x0000 /* PMA/PMD Control 1 */
+#define PHY_PMA_STATUS1 0x0001 /* PMA/PMD Status 1 */
+#define PHY_PMA_RCV_DET 0x000A /* PMA/PMD Receive Signal Detect */
+ /* other PMA/PMD registers exist and can be defined as needed */
+
+/* PHY registers - PCS (device 3) */
+#define PHY_PCS_CONTROL1 0x0000 /* PCS Control 1 */
+#define PHY_PCS_STATUS1 0x0001 /* PCS Status 1 */
+#define PHY_PCS_10G_STATUS1 0x0020 /* PCS 10GBASE-R Status 1 */
+ /* other PCS registers exist and can be defined as needed */
+
+/* PHY registers - XS (device 4) */
+#define PHY_XS_CONTROL1 0x0000 /* XS Control 1 */
+#define PHY_XS_STATUS1 0x0001 /* XS Status 1 */
+#define PHY_XS_LANE_STATUS 0x0018 /* XS Lane Status */
+ /* other XS registers exist and can be defined as needed */
+
+/* PHY_PMA_CONTROL1 register bit definitions */
+#define PMA_CONTROL1_RESET 0x8000 /* PMA/PMD reset */
+
+/* PHY_PMA_RCV_DET register bit definitions */
+#define PMA_RCV_DETECT 0x0001 /* PMA/PMD receive signal detect */
+
+/* PHY_PCS_10G_STATUS1 register bit definitions */
+#define PCS_10B_BLOCK_LOCK 0x0001 /* PCS 10GBASE-R locked to receive blocks */
+
+/* PHY_XS_LANE_STATUS register bit definitions */
+#define XS_LANE_ALIGN 0x1000 /* XS transmit lanes aligned */
+
+#define XCVR_VENDOR_LEN 16 /* xcvr vendor len */
+#define XCVR_MODEL_LEN 16 /* xcvr model len */
+
+/* PHY Microcode download data structure */
+struct phy_ucode {
ushort Addr;
ushort Data;
};
+/* Slow Bus Register Definitions */
+
+/* Module 0 registers */
+#define GPIO_L_IN 0x15 /* GPIO input (low) */
+#define GPIO_L_OUT 0x16 /* GPIO output (low) */
+#define GPIO_L_DIR 0x17 /* GPIO direction (low) */
+#define GPIO_H_IN 0x19 /* GPIO input (high) */
+#define GPIO_H_OUT 0x1A /* GPIO output (high) */
+#define GPIO_H_DIR 0x1B /* GPIO direction (high) */
-/*****************************************************************************
+/* Definitions for other slow bus registers can be added as needed */
+
+
+/*
* Transmit Sequencer Command Descriptor definitions
- *****************************************************************************/
-
-// This descriptor must be placed in GRAM. The address of this descriptor
-// (along with a couple of control bits) is pushed onto the PxhCmdQ or PxlCmdQ
-// (Proxy high or low command queue). This data is read by the Proxy Sequencer,
-// which pushes it onto the XmtCmdQ, which is (eventually) read by the Transmit
-// Sequencer, causing a packet to be transmitted. Not all fields are valid for
-// all commands - see the Sahara spec for details. Note that this structure is
-// only valid when compiled on a little endian machine.
+ *
+ * This descriptor must be placed in GRAM. The address of this descriptor
+ * (along with a couple of control bits) is pushed onto the PxhCmdQ or PxlCmdQ
+ * (Proxy high or low command queue). This data is read by the Proxy Sequencer,
+ * which pushes it onto the XmtCmdQ, which is (eventually) read by the Transmit
+ * Sequencer, causing a packet to be transmitted. Not all fields are valid for
+ * all commands - see the Sahara spec for details. Note that this structure is
+ * only valid when compiled on a little endian machine.
+ */
#pragma pack(push, 1)
-struct XMT_DESC {
- ushort XmtLen; // word 0, bits [15:0] - transmit length
- unsigned char XmtCtl; // word 0, bits [23:16] - transmit control byte
- unsigned char Cmd; // word 0, bits [31:24] - transmit command plus misc.
- u32 XmtBufId; // word 1, bits [31:0] - transmit buffer ID
- unsigned char TcpStrt; // word 2, bits [7:0] - byte address of TCP header
- unsigned char IpStrt; // word 2, bits [15:8] - byte address of IP header
- ushort IpCkSum; // word 2, bits [31:16] - partial IP checksum
- ushort TcpCkSum; // word 3, bits [15:0] - partial TCP checksum
- ushort Rsvd1; // word 3, bits [31:16] - PAD
- u32 Rsvd2; // word 4, bits [31:0] - PAD
- u32 Rsvd3; // word 5, bits [31:0] - PAD
- u32 Rsvd4; // word 6, bits [31:0] - PAD
- u32 Rsvd5; // word 7, bits [31:0] - PAD
+struct xmt_desc {
+ ushort XmtLen; /* word 0, bits [15:0] - transmit length */
+ /* word 0, bits [23:16] - transmit control byte */
+ unsigned char XmtCtl;
+ /* word 0, bits [31:24] - transmit command plus misc. */
+ unsigned char Cmd;
+ /* word 1, bits [31:0] - transmit buffer ID */
+ u32 XmtBufId;
+ /* word 2, bits [7:0] - byte address of TCP header */
+ unsigned char TcpStrt;
+ /* word 2, bits [15:8] - byte address of IP header */
+ unsigned char IpStrt;
+ /* word 2, bits [31:16] - partial IP checksum */
+ ushort IpCkSum;
+ /* word 3, bits [15:0] - partial TCP checksum */
+ ushort TcpCkSum;
+ ushort Rsvd1; /* word 3, bits [31:16] - PAD */
+ u32 Rsvd2; /* word 4, bits [31:0] - PAD */
+ u32 Rsvd3; /* word 5, bits [31:0] - PAD */
+ u32 Rsvd4; /* word 6, bits [31:0] - PAD */
+ u32 Rsvd5; /* word 7, bits [31:0] - PAD */
};
#pragma pack(pop)
-// XMT_DESC Cmd byte definitions
- // command codes
-#define XMT_DESC_CMD_RAW_SEND 0 // raw send descriptor
-#define XMT_DESC_CMD_CSUM_INSERT 1 // checksum insert descriptor
-#define XMT_DESC_CMD_FORMAT 2 // format descriptor
-#define XMT_DESC_CMD_PRIME 3 // prime descriptor
-#define XMT_DESC_CMD_CODE_SHFT 6 // comand code shift (shift to bits [31:30] in word 0)
- // shifted command codes
-#define XMT_RAW_SEND (XMT_DESC_CMD_RAW_SEND << XMT_DESC_CMD_CODE_SHFT)
-#define XMT_CSUM_INSERT (XMT_DESC_CMD_CSUM_INSERT << XMT_DESC_CMD_CODE_SHFT)
-#define XMT_FORMAT (XMT_DESC_CMD_FORMAT << XMT_DESC_CMD_CODE_SHFT)
-#define XMT_PRIME (XMT_DESC_CMD_PRIME << XMT_DESC_CMD_CODE_SHFT)
-
-// XMT_DESC Control Byte (XmtCtl) definitions
-// NOTE: These bits do not work on Sahara (Rev A)!
-#define XMT_CTL_PAUSE_FRAME 0x80 // current frame is a pause control frame (for statistics)
-#define XMT_CTL_CONTROL_FRAME 0x40 // current frame is a control frame (for statistics)
-#define XMT_CTL_PER_PKT_QUAL 0x20 // per packet qualifier
-#define XMT_CTL_PAD_MODE_NONE 0x00 // do not pad frame
-#define XMT_CTL_PAD_MODE_64 0x08 // pad frame to 64 bytes
-#define XMT_CTL_PAD_MODE_VLAN_68 0x10 // pad frame to 64 bytes, and VLAN frames to 68 bytes
-#define XMT_CTL_PAD_MODE_68 0x18 // pad frame to 68 bytes
-#define XMT_CTL_GEN_FCS 0x04 // generate FCS (CRC) for this frame
-#define XMT_CTL_DELAY_FCS_0 0x00 // do not delay FCS calcution
-#define XMT_CTL_DELAY_FCS_1 0x01 // delay FCS calculation by 1 (4-byte) word
-#define XMT_CTL_DELAY_FCS_2 0x02 // delay FCS calculation by 2 (4-byte) words
-#define XMT_CTL_DELAY_FCS_3 0x03 // delay FCS calculation by 3 (4-byte) words
-
-// XMT_DESC XmtBufId definition
-#define XMT_BUF_ID_SHFT 8 // The Xmt buffer ID is formed by dividing
- // the buffer (DRAM) address by 256 (or << 8)
-
-/*****************************************************************************
- * Receiver Sequencer Definitions
- *****************************************************************************/
-
-// Receive Event Queue (queues 3 - 6) bit definitions
-#define RCV_EVTQ_RBFID_MASK 0x0000FFFF // bit mask for the Receive Buffer ID
-
-// Receive Buffer ID definition
-#define RCV_BUF_ID_SHFT 5 // The Rcv buffer ID is formed by dividing
- // the buffer (DRAM) address by 32 (or << 5)
-
-// Format of the 18 byte Receive Buffer returned by the
-// Receive Sequencer for received packets
+/* struct xmt_desc Cmd byte definitions */
+ /* command codes */
+#define XMT_DESC_CMD_RAW_SEND 0 /* raw send descriptor */
+#define XMT_DESC_CMD_CSUM_INSERT 1 /* checksum insert descriptor */
+#define XMT_DESC_CMD_FORMAT 2 /* format descriptor */
+#define XMT_DESC_CMD_PRIME 3 /* prime descriptor */
+/* comand code shift (shift to bits [31:30] in word 0) */
+#define XMT_DESC_CMD_CODE_SHFT 6
+ /* shifted command codes */
+#define XMT_RAW_SEND (XMT_DESC_CMD_RAW_SEND << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_CSUM_INSERT (XMT_DESC_CMD_CSUM_INSERT << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_FORMAT (XMT_DESC_CMD_FORMAT << XMT_DESC_CMD_CODE_SHFT)
+#define XMT_PRIME (XMT_DESC_CMD_PRIME << XMT_DESC_CMD_CODE_SHFT)
+
+/*
+ * struct xmt_desc Control Byte (XmtCtl) definitions
+ * NOTE: These bits do not work on Sahara (Rev A)!
+ */
+/* current frame is a pause control frame (for statistics) */
+#define XMT_CTL_PAUSE_FRAME 0x80
+/* current frame is a control frame (for statistics) */
+#define XMT_CTL_CONTROL_FRAME 0x40
+#define XMT_CTL_PER_PKT_QUAL 0x20 /* per packet qualifier */
+#define XMT_CTL_PAD_MODE_NONE 0x00 /* do not pad frame */
+#define XMT_CTL_PAD_MODE_64 0x08 /* pad frame to 64 bytes */
+/* pad frame to 64 bytes, and VLAN frames to 68 bytes */
+#define XMT_CTL_PAD_MODE_VLAN_68 0x10
+#define XMT_CTL_PAD_MODE_68 0x18 /* pad frame to 68 bytes */
+/* generate FCS (CRC) for this frame */
+#define XMT_CTL_GEN_FCS 0x04
+#define XMT_CTL_DELAY_FCS_0 0x00 /* do not delay FCS calcution */
+/* delay FCS calculation by 1 (4-byte) word */
+#define XMT_CTL_DELAY_FCS_1 0x01
+/* delay FCS calculation by 2 (4-byte) words */
+#define XMT_CTL_DELAY_FCS_2 0x02
+/* delay FCS calculation by 3 (4-byte) words */
+#define XMT_CTL_DELAY_FCS_3 0x03
+
+/* struct xmt_desc XmtBufId definition */
+/*
+ * The Xmt buffer ID is formed by dividing the buffer (DRAM) address
+ * by 256 (or << 8)
+ */
+
+#define XMT_BUF_ID_SHFT 8
+
+/* Receiver Sequencer Definitions */
+
+/* Receive Event Queue (queues 3 - 6) bit definitions */
+/* bit mask for the Receive Buffer ID */
+#define RCV_EVTQ_RBFID_MASK 0x0000FFFF
+
+/* Receive Buffer ID definition */
+/*
+ * The Rcv buffer ID is formed by dividing the buffer (DRAM) address
+ * by 32 (or << 5)
+ */
+#define RCV_BUF_ID_SHFT 5
+
+/*
+ * Format of the 18 byte Receive Buffer returned by the
+ * Receive Sequencer for received packets
+ */
#pragma pack(push, 1)
-struct RCV_BUF_HDR {
- u32 Status; // Status word from Rcv Seq Parser
- ushort Length; // Rcv packet byte count
+struct rcv_buf_hdr {
+ u32 Status; /* Status word from Rcv Seq Parser */
+ ushort Length; /* Rcv packet byte count */
union {
- ushort TcpCsum; // TCP checksum
+ ushort TcpCsum; /* TCP checksum */
struct {
- unsigned char TcpCsumL; // lower 8 bits of the TCP checksum
- unsigned char LinkHash; // Link hash (multicast frames only)
+ /* lower 8 bits of the TCP checksum */
+ unsigned char TcpCsumL;
+ /* Link hash (multicast frames only) */
+ unsigned char LinkHash;
};
};
- ushort SktHash; // Socket hash
- unsigned char TcpHdrOffset; // TCP header offset into packet
- unsigned char IpHdrOffset; // IP header offset into packet
- u32 TpzHash; // Toeplitz hash
- ushort Reserved; // Reserved
+ ushort SktHash; /* Socket hash */
+ unsigned char TcpHdrOffset; /* TCP header offset into packet */
+ unsigned char IpHdrOffset; /* IP header offset into packet */
+ u32 TpzHash; /* Toeplitz hash */
+ ushort Reserved; /* Reserved */
};
#pragma pack(pop)
-
-/*****************************************************************************
- * Queue definitions
- *****************************************************************************/
+/* Queue definitions */
/* Ingress (read only) queue numbers */
-#define PXY_BUF_Q 0 /* Proxy Buffer Queue */
-#define HST_EVT_Q 1 /* Host Event Queue */
-#define XMT_BUF_Q 2 /* Transmit Buffer Queue */
-#define SKT_EVL_Q 3 /* RcvSqr Socket Event Low Priority Queue */
-#define RCV_EVL_Q 4 /* RcvSqr Rcv Event Low Priority Queue */
-#define SKT_EVH_Q 5 /* RcvSqr Socket Event High Priority Queue */
-#define RCV_EVH_Q 6 /* RcvSqr Rcv Event High Priority Queue */
-#define DMA_RSP_Q 7 /* Dma Response Queue - one per CPU context */
+#define PXY_BUF_Q 0 /* Proxy Buffer Queue */
+#define HST_EVT_Q 1 /* Host Event Queue */
+#define XMT_BUF_Q 2 /* Transmit Buffer Queue */
+#define SKT_EVL_Q 3 /* RcvSqr Socket Event Low Priority Queue */
+#define RCV_EVL_Q 4 /* RcvSqr Rcv Event Low Priority Queue */
+#define SKT_EVH_Q 5 /* RcvSqr Socket Event High Priority Queue */
+#define RCV_EVH_Q 6 /* RcvSqr Rcv Event High Priority Queue */
+#define DMA_RSP_Q 7 /* Dma Response Queue - one per CPU context */
/* Local (read/write) queue numbers */
-#define LOCAL_A_Q 8 /* Spare local Queue */
-#define LOCAL_B_Q 9 /* Spare local Queue */
-#define LOCAL_C_Q 10 /* Spare local Queue */
-#define FSM_EVT_Q 11 /* Finite-State-Machine Event Queue */
-#define SBF_PAL_Q 12 /* System Buffer Physical Address (low) Queue */
-#define SBF_PAH_Q 13 /* System Buffer Physical Address (high) Queue */
-#define SBF_VAL_Q 14 /* System Buffer Virtual Address (low) Queue */
-#define SBF_VAH_Q 15 /* System Buffer Virtual Address (high) Queue */
+#define LOCAL_A_Q 8 /* Spare local Queue */
+#define LOCAL_B_Q 9 /* Spare local Queue */
+#define LOCAL_C_Q 10 /* Spare local Queue */
+#define FSM_EVT_Q 11 /* Finite-State-Machine Event Queue */
+#define SBF_PAL_Q 12 /* System Buffer Physical Address (low) Queue */
+#define SBF_PAH_Q 13 /* System Buffer Physical Address (high) Queue*/
+#define SBF_VAL_Q 14 /* System Buffer Virtual Address (low) Queue */
+#define SBF_VAH_Q 15 /* System Buffer Virtual Address (high) Queue */
/* Egress (write only) queue numbers */
-#define H2G_CMD_Q 16 /* Host to GlbRam DMA Command Queue */
-#define H2D_CMD_Q 17 /* Host to DRAM DMA Command Queue */
-#define G2H_CMD_Q 18 /* GlbRam to Host DMA Command Queue */
-#define G2D_CMD_Q 19 /* GlbRam to DRAM DMA Command Queue */
-#define D2H_CMD_Q 20 /* DRAM to Host DMA Command Queue */
-#define D2G_CMD_Q 21 /* DRAM to GlbRam DMA Command Queue */
-#define D2D_CMD_Q 22 /* DRAM to DRAM DMA Command Queue */
-#define PXL_CMD_Q 23 /* Low Priority Proxy Command Queue */
-#define PXH_CMD_Q 24 /* High Priority Proxy Command Queue */
-#define RSQ_CMD_Q 25 /* Receive Sequencer Command Queue */
-#define RCV_BUF_Q 26 /* Receive Buffer Queue */
+#define H2G_CMD_Q 16 /* Host to GlbRam DMA Command Queue */
+#define H2D_CMD_Q 17 /* Host to DRAM DMA Command Queue */
+#define G2H_CMD_Q 18 /* GlbRam to Host DMA Command Queue */
+#define G2D_CMD_Q 19 /* GlbRam to DRAM DMA Command Queue */
+#define D2H_CMD_Q 20 /* DRAM to Host DMA Command Queue */
+#define D2G_CMD_Q 21 /* DRAM to GlbRam DMA Command Queue */
+#define D2D_CMD_Q 22 /* DRAM to DRAM DMA Command Queue */
+#define PXL_CMD_Q 23 /* Low Priority Proxy Command Queue */
+#define PXH_CMD_Q 24 /* High Priority Proxy Command Queue */
+#define RSQ_CMD_Q 25 /* Receive Sequencer Command Queue */
+#define RCV_BUF_Q 26 /* Receive Buffer Queue */
/* Bit definitions for the Proxy Command queues (PXL_CMD_Q and PXH_CMD_Q) */
-#define PXY_COPY_EN 0x00200000 /* enable copy of xmt descriptor to xmt command queue */
-#define PXY_SIZE_16 0x00000000 /* copy 16 bytes */
-#define PXY_SIZE_32 0x00100000 /* copy 32 bytes */
+/* enable copy of xmt descriptor to xmt command queue */
+#define PXY_COPY_EN 0x00200000
+#define PXY_SIZE_16 0x00000000 /* copy 16 bytes */
+#define PXY_SIZE_32 0x00100000 /* copy 32 bytes */
+
+/* SXG EEPROM/Flash Configuration Definitions */
+
+/* Location of configuration data in EEPROM or Flash */
+/* start addr for config info in EEPROM */
+#define EEPROM_CONFIG_START_ADDR 0x00
+/* start addr for config info in Flash */
+#define FLASH_CONFIG_START_ADDR 0x80
+
+/* Configuration data section defines */
+#define HW_CFG_SECTION_SIZE 512 /* size of H/W section */
+#define HW_CFG_SECTION_SIZE_A 256 /* size of H/W section (Sahara rev A) */
+/* starting location (offset) of S/W section */
+#define SW_CFG_SECTION_START 512
+/* starting location (offset) of S/W section (Sahara rev A) */
+#define SW_CFG_SECTION_START_A 256
+#define SW_CFG_SECTION_SIZE 128 /* size of S/W section */
+/*
+ * H/W configuration data magic word Goes in Addr field of first
+ * struct hw_cfg_data entry
+ */
+#define HW_CFG_MAGIC_WORD 0xA5A5
+/*
+ * H/W configuration data terminator Goes in Addr field of last
+ * struct hw_cfg_data entry
+ */
+#define HW_CFG_TERMINATOR 0xFFFF
-/*****************************************************************************
- * SXG EEPROM/Flash Configuration Definitions
- *****************************************************************************/
-#pragma pack(push, 1)
+#define SW_CFG_MAGIC_WORD 0x5A5A /* S/W configuration data magic word */
-/* */
-struct HW_CFG_DATA {
- ushort Addr;
- union {
- ushort Data;
- ushort Checksum;
- };
+#pragma pack(push, 1)
+/*
+ * Structure for an element of H/W configuration data.
+ * Read by the Sahara hardware
+ */
+struct hw_cfg_data {
+ ushort Addr;
+ ushort Data;
};
-/* */
-#define NUM_HW_CFG_ENTRIES ((128/sizeof(struct HW_CFG_DATA)) - 4)
-
-/* MAC address */
-struct SXG_CONFIG_MAC {
- unsigned char MacAddr[6]; /* MAC Address */
+/*
+ * Number of struct hw_cfg_data structures to put in the configuration data
+ * data structure (struct sxg_config or struct sxg_config_a). The number is
+ * computed to fill the entire H/W config section of the structure.
+ */
+#define NUM_HW_CFG_ENTRIES \
+ (HW_CFG_SECTION_SIZE / sizeof(struct hw_cfg_data))
+#define NUM_HW_CFG_ENTRIES_A \
+ (HW_CFG_SECTION_SIZE_A / sizeof(struct hw_cfg_data))
+
+/* MAC address structure */
+struct sxg_config_mac {
+ unsigned char MacAddr[6]; /* MAC Address */
};
-/* */
-struct ATK_FRU {
+/* FRU data structure */
+struct atk_fru {
unsigned char PartNum[6];
unsigned char Revision[2];
unsigned char Serial[14];
@@ -697,38 +909,112 @@ struct ATK_FRU {
#define EMC_FRU_FORMAT 0x0005
#define NO_FRU_FORMAT 0xFFFF
+#define ATK_OEM_ASSY_SIZE 10 /* assy num is 9 chars plus \0 */
+
+/* OEM FRU structure for Alacritech */
+struct atk_oem {
+ unsigned char Assy[ATK_OEM_ASSY_SIZE];
+};
+
+#define OEM_EEPROM_FRUSIZE 74 /* size of OEM fru info - size */
+/* chosen to fill out the S/W section */
+
+union oem_fru { /* OEM FRU information */
+ unsigned char OemFru[OEM_EEPROM_FRUSIZE];
+ struct atk_oem AtkOem;
+};
+
+/* Structure to hold the S/W configuration data. */
+struct sw_cfg_data {
+ ushort MagicWord; /* Magic word for section 2 */
+ ushort Version; /* Format version */
+ struct sxg_config_mac MacAddr[4]; /* space for 4 MAC addresses */
+ struct atk_fru AtkFru; /* FRU information */
+ ushort OemFruFormat; /* OEM FRU format type */
+ union oem_fru OemFru; /* OEM FRU information */
+ ushort Checksum; /* Checksum of section 2 */
+};
+
+
/* EEPROM/Flash Format */
-struct SXG_CONFIG {
- /* */
- /* Section 1 (128 bytes) */
- /* */
- ushort MagicWord; /* EEPROM/FLASH Magic code 'A5A5' */
- ushort SpiClks; /* SPI bus clock dividers */
- struct HW_CFG_DATA HwCfg[NUM_HW_CFG_ENTRIES];
- /* */
- /* */
- /* */
- ushort Version; /* EEPROM format version */
- struct SXG_CONFIG_MAC MacAddr[4]; /* space for 4 MAC addresses */
- struct ATK_FRU AtkFru; /* FRU information */
- ushort OemFruFormat; /* OEM FRU format type */
- unsigned char OemFru[76]; /* OEM FRU information (optional) */
- ushort Checksum; /* Checksum of section 2 */
- /* CS info XXXTODO */
+struct sxg_config {
+ /* H/W Section - Read by Sahara hardware (512 bytes) */
+ struct hw_cfg_data HwCfg[NUM_HW_CFG_ENTRIES];
+ /* S/W Section - Other configuration data (128 bytes) */
+ struct sw_cfg_data SwCfg;
};
-#pragma pack(pop)
-/*****************************************************************************
- * Miscellaneous Hardware definitions
- *****************************************************************************/
+#ifdef WINDOWS_COMPILER
+/*
+ * The following macro is something of a kludge, but it is the only way
+ * that I could find to catch certain programming errors at compile time.
+ * If the asserted condition is true, then nothing happens. If false, then
+ * the compiler tries to typedef an array with -1 members, which generates
+ * an error. Unfortunately, the error message is meaningless, but at least
+ * it catches the problem. This macro would be unnecessary if the compiler
+ * allowed the sizeof and offsetof macros to be used in the #if directive.
+ */
+#define compile_time_assert(cond) \
+ typedef char comp_error[(cond) ? 1 : -1]
+
+/*
+ * A compiler error on either of the next two lines indicates that the struct sxg_config
+ * structure was built incorrectly. Unfortunately, the error message produced
+ * is meaningless. But this is apparently the only way to catch this problem
+ * at compile time.
+ */
+compile_time_assert (offsetof(struct sxg_config, SwCfg) == SW_CFG_SECTION_START);
+compile_time_assert (sizeof(struct sxg_config) == HW_CFG_SECTION_SIZE
+ + SW_CFG_SECTION_SIZE);
+
+compile_time_assert (offsetof(struct sxg_config_a, SwCfg)
+ == SW_CFG_SECTION_START_A);
+compile_time_assert (sizeof(struct sxg_config_a) == HW_CFG_SECTION_SIZE_A
+ + SW_CFG_SECTION_SIZE);
+#endif
+/*
+ * Structure used to pass information between driver and user-mode
+ * control application
+ */
+struct adapt_userinfo {
+ bool LinkUp;
+ /* use LinkUp - any need for other states? */
+ /* u32 LinkState; */
+ u32 LinkSpeed; /* not currently needed */
+ u32 LinkDuplex; /* not currently needed */
+ enum xcvr_type XcvrType; /* type of xcvr on fiber card */
+ /* fiber card xcvr vendor */
+ unsigned char XcvrVendor[XCVR_VENDOR_LEN];
+ unsigned char XcvrMode[XCVR_MODEL_LEN];
+ u32 Port; /* not currently needed */
+ u32 PhysPort; /* not currently needed */
+ ushort PciLanes;
+ unsigned char MacAddr[6];
+ unsigned char CurrMacAddr[6];
+ struct atk_fru AtkFru;
+ ushort OemFruFormat;
+ union oem_fru OemFru;
+};
-// Sahara (ASIC level) defines
-#define SAHARA_GRAM_SIZE 0x020000 // GRAM size - 128 KB
-#define SAHARA_DRAM_SIZE 0x200000 // DRAM size - 2 MB
-#define SAHARA_QRAM_SIZE 0x004000 // QRAM size - 16K entries (64 KB)
-#define SAHARA_WCS_SIZE 0x002000 // WCS - 8K instructions (x 108 bits)
+#pragma pack(pop)
-// Arabia (board level) defines
-#define FLASH_SIZE 0x080000 // 512 KB (4 Mb)
-#define EEPROM_SIZE_XFMR 512 // true EEPROM size (bytes), including xfmr area
-#define EEPROM_SIZE_NO_XFMR 256 // EEPROM size excluding xfmr area
+/* Miscellaneous Hardware definitions */
+
+/* Hardware Type definitions */
+
+/* Sahara (ASIC level) defines */
+#define SAHARA_GRAM_SIZE 0x020000 /* GRAM size - 128 KB */
+#define SAHARA_DRAM_SIZE 0x200000 /* DRAM size - 2 MB */
+/* QRAM size - 16K entries (64 KB) */
+#define SAHARA_QRAM_SIZE 0x004000
+/* WCS - 8K instructions (x 108 bits) */
+#define SAHARA_WCS_SIZE 0x002000
+
+/* Arabia (board level) defines */
+#define FLASH_SIZE 0x080000 /* 512 KB (4 Mb) */
+/* EEPROM size (bytes), including xfmr area */
+#define EEPROM_SIZE_XFMR 1024
+/* EEPROM size excluding xfmr area (512 + 128) */
+#define EEPROM_SIZE_NO_XFMR 640
+/* EEPROM size for Sahara rev A */
+#define EEPROM_SIZE_REV_A 512
diff --git a/drivers/staging/sxg/sxgphycode-1.2.h b/drivers/staging/sxg/sxgphycode-1.2.h
new file mode 100644
index 00000000000..b5448b9b278
--- /dev/null
+++ b/drivers/staging/sxg/sxgphycode-1.2.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright ? 1997-2008 Alacritech, Inc. All rights reserved
+ *
+ * $Id: sxgphycode.h,v 1.2 2008/10/02 01:44:07 Exp $
+ *
+ * sxgphycode.h:
+ *
+ * This file PHY microcode and register initialization data.
+ */
+
+/**********************************************************************
+ * PHY Microcode
+ **********************************************************************/
+//
+// The following contains both PHY microcode and PHY register
+// initialization data. It is specific to both the PHY and the
+// type of transceiver.
+//
+
+// Download for AEL2005C PHY with SR/LR transceiver (10GBASE-SR or 10GBASE-LR)
+// AEL2005 SR firmware rev 18 (microInit_mdio_SR_AEL2005C_18.tx).
+static struct phy_ucode PhyUcode[] = {
+ // NOTE: An address of 0 is a special case. When the download routine
+ // sees an address of 0, it does not write to the PHY. Instead, it delays
+ // the download. The length of the delay (in ms) is given in the data field.
+ // Delays are required at certain points.
+
+ // Platform-specific MDIO Patches:
+ // (include patches for 10G RX polarity flip, 50Mhz Synth, etc)
+ // Addr Data
+ {0xc017, 0xfeb0}, // flip RX_LOS polarity (mandatory patch for SFP+ applications)
+ {0xC001, 0x0428}, // flip RX serial polarity
+
+ {0xc013, 0xf341}, // invert lxmit clock (mandatory patch)
+ {0xc210, 0x8000}, // reset datapath (mandatory patch)
+ {0xc210, 0x8100}, // reset datapath (mandatory patch)
+ {0xc210, 0x8000}, // reset datapath (mandatory patch)
+ {0xc210, 0x0000}, // reset datapath (mandatory patch)
+ {0x0000, 0x0032}, // wait for 50ms for datapath reset to complete. (mandatory patch)
+
+ // Transceiver-specific MDIO Patches:
+ {0xc003, 0x0181}, // (bit 7) enable the CDR inc setting in 1.C005 (mandatory patch for SR code)
+ {0xc010, 0x448a}, // (bit 14) mask out high BER input from the LOS signal in 1.000A (mandatory patch for SR code)
+
+ // Transceiver-specific Microcontroller Initialization:
+ {0xc04a, 0x5200}, // activate microcontroller and pause
+ {0x0000, 0x0032}, // wait 50ms for microcontroller before writing in code.
+
+ // code block starts here:
+ {0xcc00, 0x2ff4}, {0xcc01, 0x3cd4}, {0xcc02, 0x2015}, {0xcc03, 0x3125},
+ {0xcc04, 0x6524}, {0xcc05, 0x27ff}, {0xcc06, 0x300f}, {0xcc07, 0x2c8b},
+ {0xcc08, 0x300b}, {0xcc09, 0x4009}, {0xcc0a, 0x400e}, {0xcc0b, 0x2f12},
+ {0xcc0c, 0x3002}, {0xcc0d, 0x1002}, {0xcc0e, 0x2112}, {0xcc0f, 0x3012},
+ {0xcc10, 0x1002}, {0xcc11, 0x2572}, {0xcc12, 0x3012}, {0xcc13, 0x1002},
+ {0xcc14, 0xd01e}, {0xcc15, 0x2772}, {0xcc16, 0x3012}, {0xcc17, 0x1002},
+ {0xcc18, 0x2004}, {0xcc19, 0x3c84}, {0xcc1a, 0x6436}, {0xcc1b, 0x2007},
+ {0xcc1c, 0x3f87}, {0xcc1d, 0x8676}, {0xcc1e, 0x40b7}, {0xcc1f, 0xa746},
+ {0xcc20, 0x4047}, {0xcc21, 0x5673}, {0xcc22, 0x2982}, {0xcc23, 0x3002},
+ {0xcc24, 0x13d2}, {0xcc25, 0x8bbd}, {0xcc26, 0x2802}, {0xcc27, 0x3012},
+ {0xcc28, 0x1002}, {0xcc29, 0x2032}, {0xcc2a, 0x3012}, {0xcc2b, 0x1002},
+ {0xcc2c, 0x5cc3}, {0xcc2d, 0x0314}, {0xcc2e, 0x2942}, {0xcc2f, 0x3002},
+ {0xcc30, 0x1002}, {0xcc31, 0xd019}, {0xcc32, 0x2fd2}, {0xcc33, 0x3002},
+ {0xcc34, 0x1002}, {0xcc35, 0x2a04}, {0xcc36, 0x3c74}, {0xcc37, 0x6435},
+ {0xcc38, 0x2fa4}, {0xcc39, 0x3cd4}, {0xcc3a, 0x6624}, {0xcc3b, 0x5563},
+ {0xcc3c, 0x2d42}, {0xcc3d, 0x3002}, {0xcc3e, 0x13d2}, {0xcc3f, 0x464d},
+ {0xcc40, 0x2802}, {0xcc41, 0x3012}, {0xcc42, 0x1002}, {0xcc43, 0x2fd2},
+ {0xcc44, 0x3002}, {0xcc45, 0x1002}, {0xcc46, 0x2fb4}, {0xcc47, 0x3cd4},
+ {0xcc48, 0x6624}, {0xcc49, 0x5563}, {0xcc4a, 0x2d42}, {0xcc4b, 0x3002},
+ {0xcc4c, 0x13d2}, {0xcc4d, 0x2e72}, {0xcc4e, 0x3002}, {0xcc4f, 0x1002},
+ {0xcc50, 0x2f72}, {0xcc51, 0x3002}, {0xcc52, 0x1002}, {0xcc53, 0x0004},
+ {0xcc54, 0x2942}, {0xcc55, 0x3002}, {0xcc56, 0x1002}, {0xcc57, 0x2032},
+ {0xcc58, 0x3012}, {0xcc59, 0x1002}, {0xcc5a, 0x5cc3}, {0xcc5b, 0x0317},
+ {0xcc5c, 0x2f12}, {0xcc5d, 0x3002}, {0xcc5e, 0x1002}, {0xcc5f, 0x2942},
+ {0xcc60, 0x3002}, {0xcc61, 0x1002}, {0xcc62, 0x22cd}, {0xcc63, 0x301d},
+ {0xcc64, 0x2802}, {0xcc65, 0x3012}, {0xcc66, 0x1002}, {0xcc67, 0x20b2},
+ {0xcc68, 0x3012}, {0xcc69, 0x1002}, {0xcc6a, 0x5aa3}, {0xcc6b, 0x2dc2},
+ {0xcc6c, 0x3002}, {0xcc6d, 0x1312}, {0xcc6e, 0x2d02}, {0xcc6f, 0x3002},
+ {0xcc70, 0x1002}, {0xcc71, 0x2807}, {0xcc72, 0x31a7}, {0xcc73, 0x20c4},
+ {0xcc74, 0x3c24}, {0xcc75, 0x6724}, {0xcc76, 0x1002}, {0xcc77, 0x2807},
+ {0xcc78, 0x3187}, {0xcc79, 0x20c4}, {0xcc7a, 0x3c24}, {0xcc7b, 0x6724},
+ {0xcc7c, 0x1002}, {0xcc7d, 0x2514}, {0xcc7e, 0x3c64}, {0xcc7f, 0x6436},
+ {0xcc80, 0xdff4}, {0xcc81, 0x6436}, {0xcc82, 0x1002}, {0xcc83, 0x40a4},
+ {0xcc84, 0x643c}, {0xcc85, 0x4016}, {0xcc86, 0x8c6c}, {0xcc87, 0x2b24},
+ {0xcc88, 0x3c24}, {0xcc89, 0x6435}, {0xcc8a, 0x1002}, {0xcc8b, 0x2b24},
+ {0xcc8c, 0x3c24}, {0xcc8d, 0x643a}, {0xcc8e, 0x4025}, {0xcc8f, 0x8a5a},
+ {0xcc90, 0x1002}, {0xcc91, 0x26d1}, {0xcc92, 0x3011}, {0xcc93, 0x1001},
+ {0xcc94, 0xc7a0}, {0xcc95, 0x0100}, {0xcc96, 0xc502}, {0xcc97, 0x53ac},
+ {0xcc98, 0xc503}, {0xcc99, 0xd5d5}, {0xcc9a, 0xc600}, {0xcc9b, 0x2a6d},
+ {0xcc9c, 0xc601}, {0xcc9d, 0x2a4c}, {0xcc9e, 0xc602}, {0xcc9f, 0x0111},
+ {0xcca0, 0xc60c}, {0xcca1, 0x5900}, {0xcca2, 0xc710}, {0xcca3, 0x0700},
+ {0xcca4, 0xc718}, {0xcca5, 0x0700}, {0xcca6, 0xc720}, {0xcca7, 0x4700},
+ {0xcca8, 0xc801}, {0xcca9, 0x7f50}, {0xccaa, 0xc802}, {0xccab, 0x7760},
+ {0xccac, 0xc803}, {0xccad, 0x7fce}, {0xccae, 0xc804}, {0xccaf, 0x5700},
+ {0xccb0, 0xc805}, {0xccb1, 0x5f11}, {0xccb2, 0xc806}, {0xccb3, 0x4751},
+ {0xccb4, 0xc807}, {0xccb5, 0x57e1}, {0xccb6, 0xc808}, {0xccb7, 0x2700},
+ {0xccb8, 0xc809}, {0xccb9, 0x0000}, {0xccba, 0xc821}, {0xccbb, 0x0002},
+ {0xccbc, 0xc822}, {0xccbd, 0x0014}, {0xccbe, 0xc832}, {0xccbf, 0x1186},
+ {0xccc0, 0xc847}, {0xccc1, 0x1e02}, {0xccc2, 0xc013}, {0xccc3, 0xf341},
+ {0xccc4, 0xc01a}, {0xccc5, 0x0446}, {0xccc6, 0xc024}, {0xccc7, 0x1000},
+ {0xccc8, 0xc025}, {0xccc9, 0x0a00}, {0xccca, 0xc026}, {0xcccb, 0x0c0c},
+ {0xcccc, 0xc027}, {0xcccd, 0x0c0c}, {0xccce, 0xc029}, {0xcccf, 0x00a0},
+ {0xccd0, 0xc030}, {0xccd1, 0x0a00}, {0xccd2, 0xc03c}, {0xccd3, 0x001c},
+ {0xccd4, 0xc005}, {0xccd5, 0x7a06}, {0xccd6, 0x0000}, {0xccd7, 0x26d1},
+ {0xccd8, 0x3011}, {0xccd9, 0x1001}, {0xccda, 0xc620}, {0xccdb, 0x0000},
+ {0xccdc, 0xc621}, {0xccdd, 0x003f}, {0xccde, 0xc622}, {0xccdf, 0x0000},
+ {0xcce0, 0xc623}, {0xcce1, 0x0000}, {0xcce2, 0xc624}, {0xcce3, 0x0000},
+ {0xcce4, 0xc625}, {0xcce5, 0x0000}, {0xcce6, 0xc627}, {0xcce7, 0x0000},
+ {0xcce8, 0xc628}, {0xcce9, 0x0000}, {0xccea, 0xc62c}, {0xcceb, 0x0000},
+ {0xccec, 0x0000}, {0xcced, 0x2806}, {0xccee, 0x3cb6}, {0xccef, 0xc161},
+ {0xccf0, 0x6134}, {0xccf1, 0x6135}, {0xccf2, 0x5443}, {0xccf3, 0x0303},
+ {0xccf4, 0x6524}, {0xccf5, 0x000b}, {0xccf6, 0x1002}, {0xccf7, 0x2104},
+ {0xccf8, 0x3c24}, {0xccf9, 0x2105}, {0xccfa, 0x3805}, {0xccfb, 0x6524},
+ {0xccfc, 0xdff4}, {0xccfd, 0x4005}, {0xccfe, 0x6524}, {0xccff, 0x1002},
+ {0xcd00, 0x5dd3}, {0xcd01, 0x0306}, {0xcd02, 0x2ff7}, {0xcd03, 0x38f7},
+ {0xcd04, 0x60b7}, {0xcd05, 0xdffd}, {0xcd06, 0x000a}, {0xcd07, 0x1002},
+ {0xcd08, 0x0000},
+ // end of code block
+
+ // Unpause the microcontroller to start program
+ {0xca00, 0x0080},
+ {0xca12, 0x0000},
+ {0x0000, 0x000A}, // wait 10ms just to be safe
+
+ // Configure the LED's
+ {0xc214, 0x0099}, // configure the LED drivers (for Sahara rev B)
+ {0xc216, 0x0400}, // configure the one LED
+ {0xc217, 0x0000}, // don't drive the 2nd LED (if it exists)
+
+ {0xffff, 0xffff} // table terminator
+};
diff --git a/drivers/staging/sxg/sxgphycode.h b/drivers/staging/sxg/sxgphycode.h
deleted file mode 100644
index 167f356ef86..00000000000
--- a/drivers/staging/sxg/sxgphycode.h
+++ /dev/null
@@ -1,349 +0,0 @@
-/*
- * Copyright (C) 1997-2008 Alacritech, Inc. All rights reserved
- *
- * sxgphycode.h:
- *
- * This file PHY microcode and register initialization data.
- */
-
-/**********************************************************************
- * PHY Microcode
- *
- * The following contains both PHY microcode and PHY register
- * initialization data. It is specific to both the PHY and the
- * type of transceiver.
- *
- **********************************************************************/
-
-/*
- * Download for AEL2005C PHY with SR/LR transceiver (10GBASE-SR or 10GBASE-LR)
- */
-static struct PHY_UCODE PhyUcode[] = {
- /*
- * NOTE: An address of 0 is a special case. When the download routine
- * sees an address of 0, it does not write to the PHY. Instead, it
- * delays the download. The length of the delay (in ms) is given in
- * the data field.
- *
- * Delays are required at certain points.
- */
-
- /*
- * Platform-specific MDIO Patches:
- * (include patches for 10G RX polarity flip, 50Mhz Synth, etc)
- */
- /* Addr, Data */
- {0xc017, 0xfeb0}, /* flip RX_LOS polarity (mandatory */
- /* patch for SFP+ applications) */
- {0xC001, 0x0428}, /* flip RX serial polarity */
-
- {0xc013, 0xf341}, /* invert lxmit clock (mandatory patch) */
- {0xc210, 0x8000}, /* reset datapath (mandatory patch) */
- {0xc210, 0x8100}, /* reset datapath (mandatory patch) */
- {0xc210, 0x8000}, /* reset datapath (mandatory patch) */
- {0xc210, 0x0000}, /* reset datapath (mandatory patch) */
- {0x0000, 0x0032}, /* wait for 50ms for datapath reset to */
- /* complete. (mandatory patch) */
-
- /* Configure the LED's */
- {0xc214, 0x0099}, /* configure the LED drivers */
- {0xc216, 0x5f5f}, /* configure the Activity LED */
- {0xc217, 0x33ff}, /* configure the Link LED */
-
- /* Transceiver-specific MDIO Patches: */
- {0xc010, 0x448a}, /* (bit 14) mask out high BER input from the */
- /* LOS signal in 1.000A */
- /* (mandatory patch for SR code) */
- {0xc003, 0x0181}, /* (bit 7) enable the CDR inc setting in */
- /* 1.C005 (mandatory patch for SR code) */
-
- /* Transceiver-specific Microcontroller Initialization: */
- {0xc04a, 0x5200}, /* activate microcontroller and pause */
- {0x0000, 0x0032}, /* wait 50ms for microcontroller before */
- /* writing in code. */
-
- /* code block starts here: */
- {0xcc00, 0x2009},
- {0xcc01, 0x3009},
- {0xcc02, 0x27ff},
- {0xcc03, 0x300f},
- {0xcc04, 0x200c},
- {0xcc05, 0x300c},
- {0xcc06, 0x20c4},
- {0xcc07, 0x3c04},
- {0xcc08, 0x6437},
- {0xcc09, 0x20c4},
- {0xcc0a, 0x3c04},
- {0xcc0b, 0x6437},
- {0xcc0c, 0x25c4},
- {0xcc0d, 0x3c54},
- {0xcc0e, 0x6724},
- {0xcc0f, 0x25c4},
- {0xcc10, 0x3c54},
- {0xcc11, 0x6724},
- {0xcc12, 0x2042},
- {0xcc13, 0x3012},
- {0xcc14, 0x1002},
- {0xcc15, 0x2482},
- {0xcc16, 0x3012},
- {0xcc17, 0x1002},
- {0xcc18, 0x2a32},
- {0xcc19, 0x3002},
- {0xcc1a, 0x1002},
- {0xcc1b, 0x200d},
- {0xcc1c, 0x304d},
- {0xcc1d, 0x2862},
- {0xcc1e, 0x3012},
- {0xcc1f, 0x1002},
- {0xcc20, 0x2982},
- {0xcc21, 0x3002},
- {0xcc22, 0x1002},
- {0xcc23, 0x628f},
- {0xcc24, 0x20a4},
- {0xcc25, 0x3004},
- {0xcc26, 0x6438},
- {0xcc27, 0x20a4},
- {0xcc28, 0x3004},
- {0xcc29, 0x6438},
- {0xcc2a, 0x2015},
- {0xcc2b, 0x3005},
- {0xcc2c, 0x5853},
- {0xcc2d, 0x2bd2},
- {0xcc2e, 0x3002},
- {0xcc2f, 0x1342},
- {0xcc30, 0x200c},
- {0xcc31, 0x300c},
- {0xcc32, 0x2ff7},
- {0xcc33, 0x30f7},
- {0xcc34, 0x20c4},
- {0xcc35, 0x3c04},
- {0xcc36, 0x6724},
- {0xcc37, 0x20c4},
- {0xcc38, 0x3c04},
- {0xcc39, 0x6724},
- {0xcc3a, 0x2d32},
- {0xcc3b, 0x3002},
- {0xcc3c, 0x1002},
- {0xcc3d, 0x2008},
- {0xcc3e, 0x3008},
- {0xcc3f, 0x5c83},
- {0xcc40, 0x2d52},
- {0xcc41, 0x3002},
- {0xcc42, 0x1352},
- {0xcc43, 0x2008},
- {0xcc44, 0x3008},
- {0xcc45, 0x5c83},
- {0xcc46, 0x2d32},
- {0xcc47, 0x3002},
- {0xcc48, 0x1352},
- {0xcc49, 0x201c},
- {0xcc4a, 0x300c},
- {0xcc4b, 0x200d},
- {0xcc4c, 0x310d},
- {0xcc4d, 0x2862},
- {0xcc4e, 0x3012},
- {0xcc4f, 0x1002},
- {0xcc50, 0x2ed2},
- {0xcc51, 0x3002},
- {0xcc52, 0x1342},
- {0xcc53, 0x6f72},
- {0xcc54, 0x1002},
- {0xcc55, 0x628f},
- {0xcc56, 0x2514},
- {0xcc57, 0x3c64},
- {0xcc58, 0x6436},
- {0xcc59, 0x2514},
- {0xcc5a, 0x3c64},
- {0xcc5b, 0x6436},
- {0xcc5c, 0x2fa4},
- {0xcc5d, 0x3cd4},
- {0xcc5e, 0x6624},
- {0xcc5f, 0x2fa4},
- {0xcc60, 0x3cd4},
- {0xcc61, 0x6624},
- {0xcc62, 0x2f45},
- {0xcc63, 0x3015},
- {0xcc64, 0x5653},
- {0xcc65, 0x2eb2},
- {0xcc66, 0x3002},
- {0xcc67, 0x13d2},
- {0xcc68, 0x2ed2},
- {0xcc69, 0x3002},
- {0xcc6a, 0x1002},
- {0xcc6b, 0x6f72},
- {0xcc6c, 0x1002},
- {0xcc6d, 0x628f},
- {0xcc6e, 0x2602},
- {0xcc6f, 0x3012},
- {0xcc70, 0x1002},
- {0xcc71, 0x200d},
- {0xcc72, 0x320d},
- {0xcc73, 0x2862},
- {0xcc74, 0x3012},
- {0xcc75, 0x1002},
- {0xcc76, 0x25c4},
- {0xcc77, 0x3c54},
- {0xcc78, 0x6437},
- {0xcc79, 0x25c4},
- {0xcc7a, 0x3c54},
- {0xcc7b, 0x6437},
- {0xcc7c, 0x20c4},
- {0xcc7d, 0x3c04},
- {0xcc7e, 0x6724},
- {0xcc7f, 0x20c4},
- {0xcc80, 0x3c04},
- {0xcc81, 0x6724},
- {0xcc82, 0x6f72},
- {0xcc83, 0x1002},
- {0xcc84, 0x628f},
- {0xcc85, 0x26f2},
- {0xcc86, 0x3012},
- {0xcc87, 0x1002},
- {0xcc88, 0xc503},
- {0xcc89, 0xd5d5},
- {0xcc8a, 0xc600},
- {0xcc8b, 0x2a6d},
- {0xcc8c, 0xc601},
- {0xcc8d, 0x2a4c},
- {0xcc8e, 0xc602},
- {0xcc8f, 0x0111},
- {0xcc90, 0xc60c},
- {0xcc91, 0x5900},
- {0xcc92, 0xc710},
- {0xcc93, 0x0700},
- {0xcc94, 0xc718},
- {0xcc95, 0x0700},
- {0xcc96, 0xc720},
- {0xcc97, 0x4700},
- {0xcc98, 0xc801},
- {0xcc99, 0x7f50},
- {0xcc9a, 0xc802},
- {0xcc9b, 0x7760},
- {0xcc9c, 0xc803},
- {0xcc9d, 0x7fce},
- {0xcc9e, 0xc804},
- {0xcc9f, 0x5700},
- {0xcca0, 0xc805},
- {0xcca1, 0x5f11},
- {0xcca2, 0xc806},
- {0xcca3, 0x4751},
- {0xcca4, 0xc807},
- {0xcca5, 0x57e1},
- {0xcca6, 0xc808},
- {0xcca7, 0x2700},
- {0xcca8, 0xc809},
- {0xcca9, 0x0000},
- {0xccaa, 0xc821},
- {0xccab, 0x0002},
- {0xccac, 0xc822},
- {0xccad, 0x0014},
- {0xccae, 0xc832},
- {0xccaf, 0x1186},
- {0xccb0, 0xc847},
- {0xccb1, 0x1e02},
- {0xccb2, 0xc013},
- {0xccb3, 0xf341},
- {0xccb4, 0xc01a},
- {0xccb5, 0x0446},
- {0xccb6, 0xc024},
- {0xccb7, 0x1000},
- {0xccb8, 0xc025},
- {0xccb9, 0x0a00},
- {0xccba, 0xc026},
- {0xccbb, 0x0c0c},
- {0xccbc, 0xc027},
- {0xccbd, 0x0c0c},
- {0xccbe, 0xc029},
- {0xccbf, 0x00a0},
- {0xccc0, 0xc030},
- {0xccc1, 0x0a00},
- {0xccc2, 0xc03c},
- {0xccc3, 0x001c},
- {0xccc4, 0xc005},
- {0xccc5, 0x7a06},
- {0xccc6, 0x0000},
- {0xccc7, 0x0000},
- {0xccc8, 0x628f},
- {0xccc9, 0x26f2},
- {0xccca, 0x3012},
- {0xcccb, 0x1002},
- {0xcccc, 0xc620},
- {0xcccd, 0x0000},
- {0xccce, 0xc621},
- {0xcccf, 0x003f},
- {0xccd0, 0xc622},
- {0xccd1, 0x0000},
- {0xccd2, 0xc623},
- {0xccd3, 0x0000},
- {0xccd4, 0xc624},
- {0xccd5, 0x0000},
- {0xccd6, 0xc625},
- {0xccd7, 0x0000},
- {0xccd8, 0xc627},
- {0xccd9, 0x0000},
- {0xccda, 0xc628},
- {0xccdb, 0x0000},
- {0xccdc, 0xc62c},
- {0xccdd, 0x0000},
- {0xccde, 0x0000},
- {0xccdf, 0x0000},
- {0xcce0, 0x628f},
- {0xcce1, 0xd019},
- {0xcce2, 0x26f2},
- {0xcce3, 0x3012},
- {0xcce4, 0x1002},
- {0xcce5, 0xc210},
- {0xcce6, 0x8000},
- {0xcce7, 0xc210},
- {0xcce8, 0x8010},
- {0xcce9, 0xc210},
- {0xccea, 0x8000},
- {0xcceb, 0xc210},
- {0xccec, 0x0000},
- {0xcced, 0x0000},
- {0xccee, 0x0000},
- {0xccef, 0x8221},
- {0xccf0, 0x2752},
- {0xccf1, 0x3012},
- {0xccf2, 0x1002},
- {0xccf3, 0x6f72},
- {0xccf4, 0x1002},
- {0xccf5, 0x2806},
- {0xccf6, 0x3006},
- {0xccf7, 0x2007},
- {0xccf8, 0x3cc7},
- {0xccf9, 0xe161},
- {0xccfa, 0xc171},
- {0xccfb, 0x6134},
- {0xccfc, 0x6135},
- {0xccfd, 0x5453},
- {0xccfe, 0x2858},
- {0xccff, 0x3018},
- {0xcd00, 0x1348},
- {0xcd01, 0x6524},
- {0xcd02, 0x27b8},
- {0xcd03, 0x3018},
- {0xcd04, 0x1008},
- {0xcd05, 0x1002},
- {0xcd06, 0x628f},
- {0xcd07, 0x5dd3},
- {0xcd08, 0x2906},
- {0xcd09, 0x3016},
- {0xcd0a, 0x1306},
- {0xcd0b, 0x2ff7},
- {0xcd0c, 0x30f7},
- {0xcd0d, 0x60b7},
- {0xcd0e, 0xdffd},
- {0xcd0f, 0x0008},
- {0xcd10, 0x6f72},
- {0xcd11, 0x1002},
- {0xcd12, 0x0000},
- {0xcdff, 0x0a01},
- /* end of code block */
-
- /* Unpause the microcontroller to start program */
- {0xca00, 0x0080},
- {0xca12, 0x0000},
- {0x0000, 0x000A}, /* wait 10ms just to be safe */
- {0xffff, 0xffff} /* table terminator */
-};
diff --git a/drivers/staging/uc2322/Kconfig b/drivers/staging/uc2322/Kconfig
new file mode 100644
index 00000000000..2e0c6e79df2
--- /dev/null
+++ b/drivers/staging/uc2322/Kconfig
@@ -0,0 +1,10 @@
+config USB_SERIAL_ATEN2011
+ tristate "ATEN 2011 USB to serial device support"
+ depends on USB_SERIAL
+ default N
+ ---help---
+ Say Y here if you want to use a ATEN 2011 dual port USB to serial
+ adapter.
+
+ To compile this driver as a module, choose M here: the module will be
+ called aten2011.
diff --git a/drivers/staging/uc2322/Makefile b/drivers/staging/uc2322/Makefile
new file mode 100644
index 00000000000..49c18d6e579
--- /dev/null
+++ b/drivers/staging/uc2322/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_USB_SERIAL_ATEN2011) += aten2011.o
diff --git a/drivers/staging/uc2322/TODO b/drivers/staging/uc2322/TODO
new file mode 100644
index 00000000000..c189a64c418
--- /dev/null
+++ b/drivers/staging/uc2322/TODO
@@ -0,0 +1,7 @@
+TODO:
+ - checkpatch.pl cleanups
+ - remove dead and useless code (auditing the tty ioctls to
+ verify that they really are correct and needed.)
+
+Please send any patches to Greg Kroah-Hartman <greg@kroah.com> and
+Russell Lang <gsview@ghostgum.com.au>.
diff --git a/drivers/staging/uc2322/aten2011.c b/drivers/staging/uc2322/aten2011.c
new file mode 100644
index 00000000000..85b70545306
--- /dev/null
+++ b/drivers/staging/uc2322/aten2011.c
@@ -0,0 +1,2452 @@
+/*
+ * Aten 2011 USB serial driver for 4 port devices
+ *
+ * Copyright (C) 2000 Inside Out Networks
+ * Copyright (C) 2001-2002, 2009 Greg Kroah-Hartman <greg@kroah.com>
+ * Copyright (C) 2009 Novell Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/tty.h>
+#include <linux/tty_driver.h>
+#include <linux/tty_flip.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/uaccess.h>
+#include <linux/usb.h>
+#include <linux/usb/serial.h>
+
+
+#define ZLP_REG1 0x3A /* Zero_Flag_Reg1 58 */
+#define ZLP_REG2 0x3B /* Zero_Flag_Reg2 59 */
+#define ZLP_REG3 0x3C /* Zero_Flag_Reg3 60 */
+#define ZLP_REG4 0x3D /* Zero_Flag_Reg4 61 */
+#define ZLP_REG5 0x3E /* Zero_Flag_Reg5 62 */
+
+/* Interrupt Rotinue Defines */
+#define SERIAL_IIR_RLS 0x06
+#define SERIAL_IIR_RDA 0x04
+#define SERIAL_IIR_CTI 0x0c
+#define SERIAL_IIR_THR 0x02
+#define SERIAL_IIR_MS 0x00
+
+/* Emulation of the bit mask on the LINE STATUS REGISTER. */
+#define SERIAL_LSR_DR 0x0001
+#define SERIAL_LSR_OE 0x0002
+#define SERIAL_LSR_PE 0x0004
+#define SERIAL_LSR_FE 0x0008
+#define SERIAL_LSR_BI 0x0010
+#define SERIAL_LSR_THRE 0x0020
+#define SERIAL_LSR_TEMT 0x0040
+#define SERIAL_LSR_FIFOERR 0x0080
+
+/* MSR bit defines(place holders) */
+#define ATEN_MSR_DELTA_CTS 0x10
+#define ATEN_MSR_DELTA_DSR 0x20
+#define ATEN_MSR_DELTA_RI 0x40
+#define ATEN_MSR_DELTA_CD 0x80
+
+/* Serial Port register Address */
+#define RECEIVE_BUFFER_REGISTER ((__u16)(0x00))
+#define TRANSMIT_HOLDING_REGISTER ((__u16)(0x00))
+#define INTERRUPT_ENABLE_REGISTER ((__u16)(0x01))
+#define INTERRUPT_IDENT_REGISTER ((__u16)(0x02))
+#define FIFO_CONTROL_REGISTER ((__u16)(0x02))
+#define LINE_CONTROL_REGISTER ((__u16)(0x03))
+#define MODEM_CONTROL_REGISTER ((__u16)(0x04))
+#define LINE_STATUS_REGISTER ((__u16)(0x05))
+#define MODEM_STATUS_REGISTER ((__u16)(0x06))
+#define SCRATCH_PAD_REGISTER ((__u16)(0x07))
+#define DIVISOR_LATCH_LSB ((__u16)(0x00))
+#define DIVISOR_LATCH_MSB ((__u16)(0x01))
+
+#define SP1_REGISTER ((__u16)(0x00))
+#define CONTROL1_REGISTER ((__u16)(0x01))
+#define CLK_MULTI_REGISTER ((__u16)(0x02))
+#define CLK_START_VALUE_REGISTER ((__u16)(0x03))
+#define DCR1_REGISTER ((__u16)(0x04))
+#define GPIO_REGISTER ((__u16)(0x07))
+
+#define SERIAL_LCR_DLAB ((__u16)(0x0080))
+
+/*
+ * URB POOL related defines
+ */
+#define NUM_URBS 16 /* URB Count */
+#define URB_TRANSFER_BUFFER_SIZE 32 /* URB Size */
+
+#define USB_VENDOR_ID_ATENINTL 0x0557
+#define ATENINTL_DEVICE_ID_2011 0x2011
+#define ATENINTL_DEVICE_ID_7820 0x7820
+
+static struct usb_device_id id_table[] = {
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_2011) },
+ { USB_DEVICE(USB_VENDOR_ID_ATENINTL, ATENINTL_DEVICE_ID_7820) },
+ { } /* terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, id_table);
+
+/* This structure holds all of the local port information */
+struct ATENINTL_port {
+ int port_num; /*Actual port number in the device(1,2,etc)*/
+ __u8 bulk_out_endpoint; /* the bulk out endpoint handle */
+ unsigned char *bulk_out_buffer; /* buffer used for the bulk out endpoint */
+ struct urb *write_urb; /* write URB for this port */
+ __u8 bulk_in_endpoint; /* the bulk in endpoint handle */
+ unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
+ struct urb *read_urb; /* read URB for this port */
+ __u8 shadowLCR; /* last LCR value received */
+ __u8 shadowMCR; /* last MCR value received */
+ char open;
+ char chaseResponsePending;
+ wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
+ wait_queue_head_t wait_command; /* for handling sleeping while waiting for command to finish */
+ struct async_icount icount;
+ struct usb_serial_port *port; /* loop back to the owner of this object */
+ /*Offsets*/
+ __u8 SpRegOffset;
+ __u8 ControlRegOffset;
+ __u8 DcrRegOffset;
+ /* for processing control URBS in interrupt context */
+ struct urb *control_urb;
+ char *ctrl_buf;
+ int MsrLsr;
+
+ struct urb *write_urb_pool[NUM_URBS];
+ /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */
+ struct ktermios tmp_termios; /* stores the old termios settings */
+ spinlock_t lock; /* private lock */
+};
+
+/* This structure holds all of the individual serial device information */
+struct ATENINTL_serial {
+ __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */
+ unsigned char *interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */
+ struct urb *interrupt_read_urb; /* our interrupt urb */
+ __u8 bulk_in_endpoint; /* the bulk in endpoint handle */
+ unsigned char *bulk_in_buffer; /* the buffer we use for the bulk in endpoint */
+ struct urb *read_urb; /* our bulk read urb */
+ __u8 bulk_out_endpoint; /* the bulk out endpoint handle */
+ struct usb_serial *serial; /* loop back to the owner of this object */
+ int ATEN2011_spectrum_2or4ports; /* this says the number of ports in the device */
+ /* Indicates about the no.of opened ports of an individual USB-serial adapater. */
+ unsigned int NoOfOpenPorts;
+ /* a flag for Status endpoint polling */
+ unsigned char status_polling_started;
+};
+
+static void ATEN2011_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios);
+static void ATEN2011_change_port_settings(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ struct ktermios *old_termios);
+
+/*************************************
+ * Bit definitions for each register *
+ *************************************/
+#define LCR_BITS_5 0x00 /* 5 bits/char */
+#define LCR_BITS_6 0x01 /* 6 bits/char */
+#define LCR_BITS_7 0x02 /* 7 bits/char */
+#define LCR_BITS_8 0x03 /* 8 bits/char */
+#define LCR_BITS_MASK 0x03 /* Mask for bits/char field */
+
+#define LCR_STOP_1 0x00 /* 1 stop bit */
+#define LCR_STOP_1_5 0x04 /* 1.5 stop bits (if 5 bits/char) */
+#define LCR_STOP_2 0x04 /* 2 stop bits (if 6-8 bits/char) */
+#define LCR_STOP_MASK 0x04 /* Mask for stop bits field */
+
+#define LCR_PAR_NONE 0x00 /* No parity */
+#define LCR_PAR_ODD 0x08 /* Odd parity */
+#define LCR_PAR_EVEN 0x18 /* Even parity */
+#define LCR_PAR_MARK 0x28 /* Force parity bit to 1 */
+#define LCR_PAR_SPACE 0x38 /* Force parity bit to 0 */
+#define LCR_PAR_MASK 0x38 /* Mask for parity field */
+
+#define LCR_SET_BREAK 0x40 /* Set Break condition */
+#define LCR_DL_ENABLE 0x80 /* Enable access to divisor latch */
+
+#define MCR_DTR 0x01 /* Assert DTR */
+#define MCR_RTS 0x02 /* Assert RTS */
+#define MCR_OUT1 0x04 /* Loopback only: Sets state of RI */
+#define MCR_MASTER_IE 0x08 /* Enable interrupt outputs */
+#define MCR_LOOPBACK 0x10 /* Set internal (digital) loopback mode */
+#define MCR_XON_ANY 0x20 /* Enable any char to exit XOFF mode */
+
+#define ATEN2011_MSR_CTS 0x10 /* Current state of CTS */
+#define ATEN2011_MSR_DSR 0x20 /* Current state of DSR */
+#define ATEN2011_MSR_RI 0x40 /* Current state of RI */
+#define ATEN2011_MSR_CD 0x80 /* Current state of CD */
+
+
+static int debug;
+
+/*
+ * Version Information
+ */
+#define DRIVER_VERSION "2.0"
+#define DRIVER_DESC "ATENINTL 2011 USB Serial Adapter"
+
+/*
+ * Defines used for sending commands to port
+ */
+
+#define ATEN_WDR_TIMEOUT (50) /* default urb timeout */
+
+/* Requests */
+#define ATEN_RD_RTYPE 0xC0
+#define ATEN_WR_RTYPE 0x40
+#define ATEN_RDREQ 0x0D
+#define ATEN_WRREQ 0x0E
+#define ATEN_CTRL_TIMEOUT 500
+#define VENDOR_READ_LENGTH (0x01)
+
+/* set to 1 for RS485 mode and 0 for RS232 mode */
+/* FIXME make this somehow dynamic and not build time specific */
+static int RS485mode;
+
+static int set_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 val)
+{
+ struct usb_device *dev = port->serial->dev;
+ val = val & 0x00ff;
+
+ dbg("%s: is %x, value %x", __func__, reg, val);
+
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ,
+ ATEN_WR_RTYPE, val, reg, NULL, 0,
+ ATEN_WDR_TIMEOUT);
+}
+
+static int get_reg_sync(struct usb_serial_port *port, __u16 reg, __u16 *val)
+{
+ struct usb_device *dev = port->serial->dev;
+ int ret;
+
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ,
+ ATEN_RD_RTYPE, 0, reg, val, VENDOR_READ_LENGTH,
+ ATEN_WDR_TIMEOUT);
+ dbg("%s: offset is %x, return val %x", __func__, reg, *val);
+ *val = (*val) & 0x00ff;
+ return ret;
+}
+
+static int set_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 val)
+{
+ struct usb_device *dev = port->serial->dev;
+ struct ATENINTL_serial *a_serial;
+ __u16 minor;
+
+ a_serial = usb_get_serial_data(port->serial);
+ minor = port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ val = val & 0x00ff;
+
+ /*
+ * For the UART control registers,
+ * the application number need to be Or'ed
+ */
+ if (a_serial->ATEN2011_spectrum_2or4ports == 4)
+ val |= (((__u16)port->number - minor) + 1) << 8;
+ else {
+ if (((__u16) port->number - minor) == 0)
+ val |= (((__u16)port->number - minor) + 1) << 8;
+ else
+ val |= (((__u16)port->number - minor) + 2) << 8;
+ }
+ dbg("%s: application number is %x", __func__, val);
+
+ return usb_control_msg(dev, usb_sndctrlpipe(dev, 0), ATEN_WRREQ,
+ ATEN_WR_RTYPE, val, reg, NULL, 0,
+ ATEN_WDR_TIMEOUT);
+}
+
+static int get_uart_reg(struct usb_serial_port *port, __u16 reg, __u16 *val)
+{
+ struct usb_device *dev = port->serial->dev;
+ int ret = 0;
+ __u16 wval;
+ struct ATENINTL_serial *a_serial;
+ __u16 minor = port->serial->minor;
+
+ a_serial = usb_get_serial_data(port->serial);
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+
+ /* wval is same as application number */
+ if (a_serial->ATEN2011_spectrum_2or4ports == 4)
+ wval = (((__u16)port->number - minor) + 1) << 8;
+ else {
+ if (((__u16) port->number - minor) == 0)
+ wval = (((__u16) port->number - minor) + 1) << 8;
+ else
+ wval = (((__u16) port->number - minor) + 2) << 8;
+ }
+ dbg("%s: application number is %x", __func__, wval);
+ ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), ATEN_RDREQ,
+ ATEN_RD_RTYPE, wval, reg, val, VENDOR_READ_LENGTH,
+ ATEN_WDR_TIMEOUT);
+ *val = (*val) & 0x00ff;
+ return ret;
+}
+
+static int handle_newMsr(struct ATENINTL_port *port, __u8 newMsr)
+{
+ struct ATENINTL_port *ATEN2011_port;
+ struct async_icount *icount;
+ ATEN2011_port = port;
+ icount = &ATEN2011_port->icount;
+ if (newMsr &
+ (ATEN_MSR_DELTA_CTS | ATEN_MSR_DELTA_DSR | ATEN_MSR_DELTA_RI |
+ ATEN_MSR_DELTA_CD)) {
+ icount = &ATEN2011_port->icount;
+
+ /* update input line counters */
+ if (newMsr & ATEN_MSR_DELTA_CTS)
+ icount->cts++;
+ if (newMsr & ATEN_MSR_DELTA_DSR)
+ icount->dsr++;
+ if (newMsr & ATEN_MSR_DELTA_CD)
+ icount->dcd++;
+ if (newMsr & ATEN_MSR_DELTA_RI)
+ icount->rng++;
+ }
+
+ return 0;
+}
+
+static int handle_newLsr(struct ATENINTL_port *port, __u8 newLsr)
+{
+ struct async_icount *icount;
+
+ dbg("%s - %02x", __func__, newLsr);
+
+ if (newLsr & SERIAL_LSR_BI) {
+ /*
+ * Parity and Framing errors only count if they occur exclusive
+ * of a break being received.
+ */
+ newLsr &= (__u8) (SERIAL_LSR_OE | SERIAL_LSR_BI);
+ }
+
+ /* update input line counters */
+ icount = &port->icount;
+ if (newLsr & SERIAL_LSR_BI)
+ icount->brk++;
+ if (newLsr & SERIAL_LSR_OE)
+ icount->overrun++;
+ if (newLsr & SERIAL_LSR_PE)
+ icount->parity++;
+ if (newLsr & SERIAL_LSR_FE)
+ icount->frame++;
+
+ return 0;
+}
+
+static void ATEN2011_control_callback(struct urb *urb)
+{
+ unsigned char *data;
+ struct ATENINTL_port *ATEN2011_port;
+ __u8 regval = 0x0;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
+ goto exit;
+ }
+
+ ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+ dbg("%s urb buffer size is %d", __func__, urb->actual_length);
+ dbg("%s ATEN2011_port->MsrLsr is %d port %d", __func__,
+ ATEN2011_port->MsrLsr, ATEN2011_port->port_num);
+ data = urb->transfer_buffer;
+ regval = (__u8) data[0];
+ dbg("%s data is %x", __func__, regval);
+ if (ATEN2011_port->MsrLsr == 0)
+ handle_newMsr(ATEN2011_port, regval);
+ else if (ATEN2011_port->MsrLsr == 1)
+ handle_newLsr(ATEN2011_port, regval);
+
+exit:
+ return;
+}
+
+static int ATEN2011_get_reg(struct ATENINTL_port *ATEN, __u16 Wval, __u16 reg,
+ __u16 *val)
+{
+ struct usb_device *dev = ATEN->port->serial->dev;
+ struct usb_ctrlrequest *dr = NULL;
+ unsigned char *buffer = NULL;
+ int ret = 0;
+ buffer = (__u8 *) ATEN->ctrl_buf;
+
+ dr = (void *)(buffer + 2);
+ dr->bRequestType = ATEN_RD_RTYPE;
+ dr->bRequest = ATEN_RDREQ;
+ dr->wValue = cpu_to_le16(Wval);
+ dr->wIndex = cpu_to_le16(reg);
+ dr->wLength = cpu_to_le16(2);
+
+ usb_fill_control_urb(ATEN->control_urb, dev, usb_rcvctrlpipe(dev, 0),
+ (unsigned char *)dr, buffer, 2,
+ ATEN2011_control_callback, ATEN);
+ ATEN->control_urb->transfer_buffer_length = 2;
+ ret = usb_submit_urb(ATEN->control_urb, GFP_ATOMIC);
+ return ret;
+}
+
+static void ATEN2011_interrupt_callback(struct urb *urb)
+{
+ int result;
+ int length;
+ struct ATENINTL_port *ATEN2011_port;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct usb_serial *serial;
+ __u16 Data;
+ unsigned char *data;
+ __u8 sp[5], st;
+ int i;
+ __u16 wval;
+ int minor;
+
+ dbg("%s", " : Entering");
+
+ ATEN2011_serial = (struct ATENINTL_serial *)urb->context;
+
+ switch (urb->status) {
+ case 0:
+ /* success */
+ break;
+ case -ECONNRESET:
+ case -ENOENT:
+ case -ESHUTDOWN:
+ /* this urb is terminated, clean up */
+ dbg("%s - urb shutting down with status: %d", __func__,
+ urb->status);
+ return;
+ default:
+ dbg("%s - nonzero urb status received: %d", __func__,
+ urb->status);
+ goto exit;
+ }
+ length = urb->actual_length;
+ data = urb->transfer_buffer;
+
+ serial = ATEN2011_serial->serial;
+
+ /* ATENINTL get 5 bytes
+ * Byte 1 IIR Port 1 (port.number is 0)
+ * Byte 2 IIR Port 2 (port.number is 1)
+ * Byte 3 IIR Port 3 (port.number is 2)
+ * Byte 4 IIR Port 4 (port.number is 3)
+ * Byte 5 FIFO status for both */
+
+ if (length && length > 5) {
+ dbg("%s", "Wrong data !!!");
+ return;
+ }
+
+ /* MATRIX */
+ if (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 4) {
+ sp[0] = (__u8) data[0];
+ sp[1] = (__u8) data[1];
+ sp[2] = (__u8) data[2];
+ sp[3] = (__u8) data[3];
+ st = (__u8) data[4];
+ } else {
+ sp[0] = (__u8) data[0];
+ sp[1] = (__u8) data[2];
+ /* sp[2]=(__u8)data[2]; */
+ /* sp[3]=(__u8)data[3]; */
+ st = (__u8) data[4];
+
+ }
+ for (i = 0; i < serial->num_ports; i++) {
+ ATEN2011_port = usb_get_serial_port_data(serial->port[i]);
+ minor = serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+ && (i != 0))
+ wval =
+ (((__u16) serial->port[i]->number -
+ (__u16) (minor)) + 2) << 8;
+ else
+ wval =
+ (((__u16) serial->port[i]->number -
+ (__u16) (minor)) + 1) << 8;
+ if (ATEN2011_port->open != 0) {
+ if (sp[i] & 0x01) {
+ dbg("SP%d No Interrupt !!!", i);
+ } else {
+ switch (sp[i] & 0x0f) {
+ case SERIAL_IIR_RLS:
+ dbg("Serial Port %d: Receiver status error or address bit detected in 9-bit mode", i);
+ ATEN2011_port->MsrLsr = 1;
+ ATEN2011_get_reg(ATEN2011_port, wval,
+ LINE_STATUS_REGISTER,
+ &Data);
+ break;
+ case SERIAL_IIR_MS:
+ dbg("Serial Port %d: Modem status change", i);
+ ATEN2011_port->MsrLsr = 0;
+ ATEN2011_get_reg(ATEN2011_port, wval,
+ MODEM_STATUS_REGISTER,
+ &Data);
+ break;
+ }
+ }
+ }
+
+ }
+exit:
+ if (ATEN2011_serial->status_polling_started == 0)
+ return;
+
+ result = usb_submit_urb(urb, GFP_ATOMIC);
+ if (result) {
+ dev_err(&urb->dev->dev,
+ "%s - Error %d submitting interrupt urb\n",
+ __func__, result);
+ }
+
+ return;
+}
+
+static void ATEN2011_bulk_in_callback(struct urb *urb)
+{
+ int status;
+ unsigned char *data;
+ struct usb_serial *serial;
+ struct usb_serial_port *port;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ struct tty_struct *tty;
+
+ if (urb->status) {
+ dbg("nonzero read bulk status received: %d", urb->status);
+ return;
+ }
+
+ ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+ serial = port->serial;
+
+ dbg("%s", "Entering...");
+
+ data = urb->transfer_buffer;
+ ATEN2011_serial = usb_get_serial_data(serial);
+
+ if (urb->actual_length) {
+ tty = tty_port_tty_get(&ATEN2011_port->port->port);
+ if (tty) {
+ tty_buffer_request_room(tty, urb->actual_length);
+ tty_insert_flip_string(tty, data, urb->actual_length);
+ tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
+ }
+
+ ATEN2011_port->icount.rx += urb->actual_length;
+ dbg("ATEN2011_port->icount.rx is %d:",
+ ATEN2011_port->icount.rx);
+ }
+
+ if (!ATEN2011_port->read_urb) {
+ dbg("%s", "URB KILLED !!!");
+ return;
+ }
+
+ if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+ ATEN2011_port->read_urb->dev = serial->dev;
+
+ status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+ if (status)
+ dbg("usb_submit_urb(read bulk) failed, status = %d", status);
+ }
+}
+
+static void ATEN2011_bulk_out_data_callback(struct urb *urb)
+{
+ struct ATENINTL_port *ATEN2011_port;
+ struct tty_struct *tty;
+
+ if (urb->status) {
+ dbg("nonzero write bulk status received:%d", urb->status);
+ return;
+ }
+
+ ATEN2011_port = (struct ATENINTL_port *)urb->context;
+
+ dbg("%s", "Entering .........");
+
+ tty = tty_port_tty_get(&ATEN2011_port->port->port);
+
+ if (tty && ATEN2011_port->open) {
+ /* tell the tty driver that something has changed */
+ wake_up_interruptible(&tty->write_wait);
+ }
+
+ /* schedule_work(&ATEN2011_port->port->work); */
+ tty_kref_put(tty);
+
+}
+
+#ifdef ATENSerialProbe
+static int ATEN2011_serial_probe(struct usb_serial *serial,
+ const struct usb_device_id *id)
+{
+
+ /*need to implement the mode_reg reading and updating\
+ structures usb_serial_ device_type\
+ (i.e num_ports, num_bulkin,bulkout etc) */
+ /* Also we can update the changes attach */
+ return 1;
+}
+#endif
+
+static int ATEN2011_open(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ int response;
+ int j;
+ struct usb_serial *serial;
+ struct urb *urb;
+ __u16 Data;
+ int status;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ struct ktermios tmp_termios;
+ int minor;
+
+ serial = port->serial;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return -ENODEV;
+
+ ATEN2011_serial = usb_get_serial_data(serial);
+ if (ATEN2011_serial == NULL)
+ return -ENODEV;
+
+ /* increment the number of opened ports counter here */
+ ATEN2011_serial->NoOfOpenPorts++;
+
+ usb_clear_halt(serial->dev, port->write_urb->pipe);
+ usb_clear_halt(serial->dev, port->read_urb->pipe);
+
+ /* Initialising the write urb pool */
+ for (j = 0; j < NUM_URBS; ++j) {
+ urb = usb_alloc_urb(0, GFP_ATOMIC);
+ ATEN2011_port->write_urb_pool[j] = urb;
+
+ if (urb == NULL) {
+ err("No more urbs???");
+ continue;
+ }
+
+ urb->transfer_buffer = NULL;
+ urb->transfer_buffer =
+ kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+ if (!urb->transfer_buffer) {
+ err("%s-out of memory for urb buffers.", __func__);
+ continue;
+ }
+ }
+
+/*****************************************************************************
+ * Initialize ATEN2011 -- Write Init values to corresponding Registers
+ *
+ * Register Index
+ * 1 : IER
+ * 2 : FCR
+ * 3 : LCR
+ * 4 : MCR
+ *
+ * 0x08 : SP1/2 Control Reg
+ *****************************************************************************/
+
+/* NEED to check the fallowing Block */
+
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+ if (status < 0) {
+ dbg("Reading Spreg failed");
+ return -1;
+ }
+ Data |= 0x80;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ if (status < 0) {
+ dbg("writing Spreg failed");
+ return -1;
+ }
+
+ Data &= ~0x80;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ if (status < 0) {
+ dbg("writing Spreg failed");
+ return -1;
+ }
+
+/* End of block to be checked */
+/**************************CHECK***************************/
+
+ if (RS485mode == 0)
+ Data = 0xC0;
+ else
+ Data = 0x00;
+ status = set_uart_reg(port, SCRATCH_PAD_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing SCRATCH_PAD_REGISTER failed status-0x%x", status);
+ return -1;
+ } else
+ dbg("SCRATCH_PAD_REGISTER Writing success status%d", status);
+
+/**************************CHECK***************************/
+
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+ if (status < 0) {
+ dbg("Reading Controlreg failed");
+ return -1;
+ }
+ Data |= 0x08; /* Driver done bit */
+ Data |= 0x20; /* rx_disable */
+ status = 0;
+ status =
+ set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+ if (status < 0) {
+ dbg("writing Controlreg failed");
+ return -1;
+ }
+ /*
+ * do register settings here
+ * Set all regs to the device default values.
+ * First Disable all interrupts.
+ */
+
+ Data = 0x00;
+ status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+ if (status < 0) {
+ dbg("disableing interrupts failed");
+ return -1;
+ }
+ /* Set FIFO_CONTROL_REGISTER to the default value */
+ Data = 0x00;
+ status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing FIFO_CONTROL_REGISTER failed");
+ return -1;
+ }
+
+ Data = 0xcf; /* chk */
+ status = set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing FIFO_CONTROL_REGISTER failed");
+ return -1;
+ }
+
+ Data = 0x03; /* LCR_BITS_8 */
+ status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+ ATEN2011_port->shadowLCR = Data;
+
+ Data = 0x0b; /* MCR_DTR|MCR_RTS|MCR_MASTER_IE */
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ ATEN2011_port->shadowMCR = Data;
+
+#ifdef Check
+ Data = 0x00;
+ status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
+ ATEN2011_port->shadowLCR = Data;
+
+ Data |= SERIAL_LCR_DLAB; /* data latch enable in LCR 0x80 */
+ status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ Data = 0x0c;
+ status = set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
+
+ Data = 0x0;
+ status = set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
+
+ Data = 0x00;
+ status = get_uart_reg(port, LINE_CONTROL_REGISTER, &Data);
+
+/* Data = ATEN2011_port->shadowLCR; */ /* data latch disable */
+ Data = Data & ~SERIAL_LCR_DLAB;
+ status = set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+ ATEN2011_port->shadowLCR = Data;
+#endif
+ /* clearing Bulkin and Bulkout Fifo */
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+
+ Data = Data | 0x0c;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+
+ Data = Data & ~0x0c;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ /* Finally enable all interrupts */
+ Data = 0x0;
+ Data = 0x0c;
+ status = set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ /* clearing rx_disable */
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+ Data = Data & ~0x20;
+ status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+
+ /* rx_negate */
+ Data = 0x0;
+ status = get_reg_sync(port, ATEN2011_port->ControlRegOffset, &Data);
+ Data = Data | 0x10;
+ status = 0;
+ status = set_reg_sync(port, ATEN2011_port->ControlRegOffset, Data);
+
+ /* force low_latency on so that our tty_push actually forces *
+ * the data through,otherwise it is scheduled, and with *
+ * high data rates (like with OHCI) data can get lost. */
+
+ if (tty)
+ tty->low_latency = 1;
+ /*
+ * Check to see if we've set up our endpoint info yet
+ * (can't set it up in ATEN2011_startup as the structures
+ * were not set up at that time.)
+ */
+ if (ATEN2011_serial->NoOfOpenPorts == 1) {
+ /* start the status polling here */
+ ATEN2011_serial->status_polling_started = 1;
+ /* If not yet set, Set here */
+ ATEN2011_serial->interrupt_in_buffer =
+ serial->port[0]->interrupt_in_buffer;
+ ATEN2011_serial->interrupt_in_endpoint =
+ serial->port[0]->interrupt_in_endpointAddress;
+ ATEN2011_serial->interrupt_read_urb =
+ serial->port[0]->interrupt_in_urb;
+
+ /* set up interrupt urb */
+ usb_fill_int_urb(ATEN2011_serial->interrupt_read_urb,
+ serial->dev,
+ usb_rcvintpipe(serial->dev,
+ ATEN2011_serial->
+ interrupt_in_endpoint),
+ ATEN2011_serial->interrupt_in_buffer,
+ ATEN2011_serial->interrupt_read_urb->
+ transfer_buffer_length,
+ ATEN2011_interrupt_callback, ATEN2011_serial,
+ ATEN2011_serial->interrupt_read_urb->interval);
+
+ /* start interrupt read for ATEN2011 *
+ * will continue as long as ATEN2011 is connected */
+
+ response =
+ usb_submit_urb(ATEN2011_serial->interrupt_read_urb,
+ GFP_KERNEL);
+ if (response) {
+ dbg("%s - Error %d submitting interrupt urb",
+ __func__, response);
+ }
+
+ }
+
+ /*
+ * See if we've set up our endpoint info yet
+ * (can't set it up in ATEN2011_startup as the
+ * structures were not set up at that time.)
+ */
+
+ dbg("port number is %d", port->number);
+ dbg("serial number is %d", port->serial->minor);
+ dbg("Bulkin endpoint is %d", port->bulk_in_endpointAddress);
+ dbg("BulkOut endpoint is %d", port->bulk_out_endpointAddress);
+ dbg("Interrupt endpoint is %d",
+ port->interrupt_in_endpointAddress);
+ dbg("port's number in the device is %d", ATEN2011_port->port_num);
+ ATEN2011_port->bulk_in_buffer = port->bulk_in_buffer;
+ ATEN2011_port->bulk_in_endpoint = port->bulk_in_endpointAddress;
+ ATEN2011_port->read_urb = port->read_urb;
+ ATEN2011_port->bulk_out_endpoint = port->bulk_out_endpointAddress;
+
+ minor = port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+
+ /* set up our bulk in urb */
+ if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+ && (((__u16) port->number - (__u16) (minor)) != 0)) {
+ usb_fill_bulk_urb(ATEN2011_port->read_urb, serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ (port->
+ bulk_in_endpointAddress +
+ 2)), port->bulk_in_buffer,
+ ATEN2011_port->read_urb->
+ transfer_buffer_length,
+ ATEN2011_bulk_in_callback, ATEN2011_port);
+ } else
+ usb_fill_bulk_urb(ATEN2011_port->read_urb,
+ serial->dev,
+ usb_rcvbulkpipe(serial->dev,
+ port->
+ bulk_in_endpointAddress),
+ port->bulk_in_buffer,
+ ATEN2011_port->read_urb->
+ transfer_buffer_length,
+ ATEN2011_bulk_in_callback, ATEN2011_port);
+
+ dbg("ATEN2011_open: bulkin endpoint is %d",
+ port->bulk_in_endpointAddress);
+ response = usb_submit_urb(ATEN2011_port->read_urb, GFP_KERNEL);
+ if (response) {
+ err("%s - Error %d submitting control urb", __func__,
+ response);
+ }
+
+ /* initialize our wait queues */
+ init_waitqueue_head(&ATEN2011_port->wait_chase);
+ init_waitqueue_head(&ATEN2011_port->wait_command);
+
+ /* initialize our icount structure */
+ memset(&(ATEN2011_port->icount), 0x00, sizeof(ATEN2011_port->icount));
+
+ /* initialize our port settings */
+ ATEN2011_port->shadowMCR = MCR_MASTER_IE; /* Must set to enable ints! */
+ ATEN2011_port->chaseResponsePending = 0;
+ /* send a open port command */
+ ATEN2011_port->open = 1;
+ /* ATEN2011_change_port_settings(ATEN2011_port,old_termios); */
+ /* Setup termios */
+ ATEN2011_set_termios(tty, port, &tmp_termios);
+ ATEN2011_port->icount.tx = 0;
+ ATEN2011_port->icount.rx = 0;
+
+ dbg("usb_serial serial:%x ATEN2011_port:%x\nATEN2011_serial:%x usb_serial_port port:%x",
+ (unsigned int)serial, (unsigned int)ATEN2011_port,
+ (unsigned int)ATEN2011_serial, (unsigned int)port);
+
+ return 0;
+
+}
+
+static int ATEN2011_chars_in_buffer(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ int i;
+ int chars = 0;
+ struct ATENINTL_port *ATEN2011_port;
+
+ /* dbg("%s"," ATEN2011_chars_in_buffer:entering ..........."); */
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if (ATEN2011_port == NULL) {
+ dbg("%s", "ATEN2011_break:leaving ...........");
+ return -1;
+ }
+
+ for (i = 0; i < NUM_URBS; ++i)
+ if (ATEN2011_port->write_urb_pool[i]->status == -EINPROGRESS)
+ chars += URB_TRANSFER_BUFFER_SIZE;
+
+ dbg("%s - returns %d", __func__, chars);
+ return chars;
+
+}
+
+static void ATEN2011_block_until_tx_empty(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port)
+{
+ int timeout = HZ / 10;
+ int wait = 30;
+ int count;
+
+ while (1) {
+ count = ATEN2011_chars_in_buffer(tty);
+
+ /* Check for Buffer status */
+ if (count <= 0)
+ return;
+
+ /* Block the thread for a while */
+ interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase,
+ timeout);
+
+ /* No activity.. count down section */
+ wait--;
+ if (wait == 0) {
+ dbg("%s - TIMEOUT", __func__);
+ return;
+ } else {
+ /* Reset timout value back to seconds */
+ wait = 30;
+ }
+ }
+}
+
+static void ATEN2011_close(struct tty_struct *tty, struct usb_serial_port *port,
+ struct file *filp)
+{
+ struct usb_serial *serial;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ int no_urbs;
+ __u16 Data;
+
+ dbg("%s", "ATEN2011_close:entering...");
+ serial = port->serial;
+
+ /* take the Adpater and port's private data */
+ ATEN2011_serial = usb_get_serial_data(serial);
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL))
+ return;
+
+ if (serial->dev) {
+ /* flush and block(wait) until tx is empty */
+ ATEN2011_block_until_tx_empty(tty, ATEN2011_port);
+ }
+ /* kill the ports URB's */
+ for (no_urbs = 0; no_urbs < NUM_URBS; no_urbs++)
+ usb_kill_urb(ATEN2011_port->write_urb_pool[no_urbs]);
+ /* Freeing Write URBs */
+ for (no_urbs = 0; no_urbs < NUM_URBS; ++no_urbs) {
+ kfree(ATEN2011_port->write_urb_pool[no_urbs]->transfer_buffer);
+ usb_free_urb(ATEN2011_port->write_urb_pool[no_urbs]);
+ }
+ /* While closing port, shutdown all bulk read, write *
+ * and interrupt read if they exists */
+ if (serial->dev) {
+ if (ATEN2011_port->write_urb) {
+ dbg("%s", "Shutdown bulk write");
+ usb_kill_urb(ATEN2011_port->write_urb);
+ }
+ if (ATEN2011_port->read_urb) {
+ dbg("%s", "Shutdown bulk read");
+ usb_kill_urb(ATEN2011_port->read_urb);
+ }
+ if ((&ATEN2011_port->control_urb)) {
+ dbg("%s", "Shutdown control read");
+ /* usb_kill_urb (ATEN2011_port->control_urb); */
+
+ }
+ }
+ /* if(ATEN2011_port->ctrl_buf != NULL) */
+ /* kfree(ATEN2011_port->ctrl_buf); */
+ /* decrement the no.of open ports counter of an individual USB-serial adapter. */
+ ATEN2011_serial->NoOfOpenPorts--;
+ dbg("NoOfOpenPorts in close%d:in port%d",
+ ATEN2011_serial->NoOfOpenPorts, port->number);
+ if (ATEN2011_serial->NoOfOpenPorts == 0) {
+ /* stop the stus polling here */
+ ATEN2011_serial->status_polling_started = 0;
+ if (ATEN2011_serial->interrupt_read_urb) {
+ dbg("%s", "Shutdown interrupt_read_urb");
+ /* ATEN2011_serial->interrupt_in_buffer=NULL; */
+ /* usb_kill_urb (ATEN2011_serial->interrupt_read_urb); */
+ }
+ }
+ if (ATEN2011_port->write_urb) {
+ /* if this urb had a transfer buffer already (old tx) free it */
+ kfree(ATEN2011_port->write_urb->transfer_buffer);
+ usb_free_urb(ATEN2011_port->write_urb);
+ }
+
+ /* clear the MCR & IER */
+ Data = 0x00;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ Data = 0x00;
+ set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ ATEN2011_port->open = 0;
+ dbg("%s", "Leaving ............");
+
+}
+
+static void ATEN2011_block_until_chase_response(struct tty_struct *tty,
+ struct ATENINTL_port
+ *ATEN2011_port)
+{
+ int timeout = 1 * HZ;
+ int wait = 10;
+ int count;
+
+ while (1) {
+ count = ATEN2011_chars_in_buffer(tty);
+
+ /* Check for Buffer status */
+ if (count <= 0) {
+ ATEN2011_port->chaseResponsePending = 0;
+ return;
+ }
+
+ /* Block the thread for a while */
+ interruptible_sleep_on_timeout(&ATEN2011_port->wait_chase,
+ timeout);
+ /* No activity.. count down section */
+ wait--;
+ if (wait == 0) {
+ dbg("%s - TIMEOUT", __func__);
+ return;
+ } else {
+ /* Reset timout value back to seconds */
+ wait = 10;
+ }
+ }
+
+}
+
+static void ATEN2011_break(struct tty_struct *tty, int break_state)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ unsigned char data;
+ struct usb_serial *serial;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+
+ dbg("%s", "Entering ...........");
+ dbg("ATEN2011_break: Start");
+
+ serial = port->serial;
+
+ ATEN2011_serial = usb_get_serial_data(serial);
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if ((ATEN2011_serial == NULL) || (ATEN2011_port == NULL))
+ return;
+
+ /* flush and chase */
+ ATEN2011_port->chaseResponsePending = 1;
+
+ if (serial->dev) {
+ /* flush and block until tx is empty */
+ ATEN2011_block_until_chase_response(tty, ATEN2011_port);
+ }
+
+ if (break_state == -1)
+ data = ATEN2011_port->shadowLCR | LCR_SET_BREAK;
+ else
+ data = ATEN2011_port->shadowLCR & ~LCR_SET_BREAK;
+
+ ATEN2011_port->shadowLCR = data;
+ dbg("ATEN2011_break ATEN2011_port->shadowLCR is %x",
+ ATEN2011_port->shadowLCR);
+ set_uart_reg(port, LINE_CONTROL_REGISTER, ATEN2011_port->shadowLCR);
+
+ return;
+}
+
+static int ATEN2011_write_room(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ int i;
+ int room = 0;
+ struct ATENINTL_port *ATEN2011_port;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if (ATEN2011_port == NULL) {
+ dbg("%s", "ATEN2011_break:leaving ...........");
+ return -1;
+ }
+
+ for (i = 0; i < NUM_URBS; ++i)
+ if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS)
+ room += URB_TRANSFER_BUFFER_SIZE;
+
+ dbg("%s - returns %d", __func__, room);
+ return room;
+
+}
+
+static int ATEN2011_write(struct tty_struct *tty, struct usb_serial_port *port,
+ const unsigned char *data, int count)
+{
+ int status;
+ int i;
+ int bytes_sent = 0;
+ int transfer_size;
+ int minor;
+
+ struct ATENINTL_port *ATEN2011_port;
+ struct usb_serial *serial;
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct urb *urb;
+ const unsigned char *current_position = data;
+ unsigned char *data1;
+ dbg("%s", "entering ...........");
+
+ serial = port->serial;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+ if (ATEN2011_port == NULL) {
+ dbg("%s", "ATEN2011_port is NULL");
+ return -1;
+ }
+
+ ATEN2011_serial = usb_get_serial_data(serial);
+ if (ATEN2011_serial == NULL) {
+ dbg("%s", "ATEN2011_serial is NULL");
+ return -1;
+ }
+
+ /* try to find a free urb in the list */
+ urb = NULL;
+
+ for (i = 0; i < NUM_URBS; ++i) {
+ if (ATEN2011_port->write_urb_pool[i]->status != -EINPROGRESS) {
+ urb = ATEN2011_port->write_urb_pool[i];
+ dbg("URB:%d", i);
+ break;
+ }
+ }
+
+ if (urb == NULL) {
+ dbg("%s - no more free urbs", __func__);
+ goto exit;
+ }
+
+ if (urb->transfer_buffer == NULL) {
+ urb->transfer_buffer =
+ kmalloc(URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
+
+ if (urb->transfer_buffer == NULL) {
+ err("%s no more kernel memory...", __func__);
+ goto exit;
+ }
+ }
+ transfer_size = min(count, URB_TRANSFER_BUFFER_SIZE);
+
+ memcpy(urb->transfer_buffer, current_position, transfer_size);
+ /* usb_serial_debug_data (__FILE__, __func__, transfer_size, urb->transfer_buffer); */
+
+ /* fill urb with data and submit */
+ minor = port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ if ((ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)
+ && (((__u16) port->number - (__u16) (minor)) != 0)) {
+ usb_fill_bulk_urb(urb, ATEN2011_serial->serial->dev,
+ usb_sndbulkpipe(ATEN2011_serial->serial->dev,
+ (port->
+ bulk_out_endpointAddress) +
+ 2), urb->transfer_buffer,
+ transfer_size,
+ ATEN2011_bulk_out_data_callback,
+ ATEN2011_port);
+ } else
+
+ usb_fill_bulk_urb(urb,
+ ATEN2011_serial->serial->dev,
+ usb_sndbulkpipe(ATEN2011_serial->serial->dev,
+ port->
+ bulk_out_endpointAddress),
+ urb->transfer_buffer, transfer_size,
+ ATEN2011_bulk_out_data_callback,
+ ATEN2011_port);
+
+ data1 = urb->transfer_buffer;
+ dbg("bulkout endpoint is %d", port->bulk_out_endpointAddress);
+ /* for(i=0;i < urb->actual_length;i++) */
+ /* dbg("Data is %c ",data1[i]); */
+
+ /* send it down the pipe */
+ status = usb_submit_urb(urb, GFP_ATOMIC);
+
+ if (status) {
+ err("%s - usb_submit_urb(write bulk) failed with status = %d",
+ __func__, status);
+ bytes_sent = status;
+ goto exit;
+ }
+ bytes_sent = transfer_size;
+ ATEN2011_port->icount.tx += transfer_size;
+ dbg("ATEN2011_port->icount.tx is %d:", ATEN2011_port->icount.tx);
+
+exit:
+ return bytes_sent;
+}
+
+static void ATEN2011_throttle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ int status;
+
+ dbg("- port %d", port->number);
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ if (!ATEN2011_port->open) {
+ dbg("%s", "port not opened");
+ return;
+ }
+
+ dbg("%s", "Entering .......... ");
+
+ if (!tty) {
+ dbg("%s - no tty available", __func__);
+ return;
+ }
+
+ /* if we are implementing XON/XOFF, send the stop character */
+ if (I_IXOFF(tty)) {
+ unsigned char stop_char = STOP_CHAR(tty);
+ status = ATEN2011_write(tty, port, &stop_char, 1);
+ if (status <= 0)
+ return;
+ }
+
+ /* if we are implementing RTS/CTS, toggle that line */
+ if (tty->termios->c_cflag & CRTSCTS) {
+ ATEN2011_port->shadowMCR &= ~MCR_RTS;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ ATEN2011_port->shadowMCR);
+ if (status < 0)
+ return;
+ }
+
+ return;
+}
+
+static void ATEN2011_unthrottle(struct tty_struct *tty)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ int status;
+ struct ATENINTL_port *ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ if (!ATEN2011_port->open) {
+ dbg("%s - port not opened", __func__);
+ return;
+ }
+
+ dbg("%s", "Entering .......... ");
+
+ if (!tty) {
+ dbg("%s - no tty available", __func__);
+ return;
+ }
+
+ /* if we are implementing XON/XOFF, send the start character */
+ if (I_IXOFF(tty)) {
+ unsigned char start_char = START_CHAR(tty);
+ status = ATEN2011_write(tty, port, &start_char, 1);
+ if (status <= 0)
+ return;
+ }
+
+ /* if we are implementing RTS/CTS, toggle that line */
+ if (tty->termios->c_cflag & CRTSCTS) {
+ ATEN2011_port->shadowMCR |= MCR_RTS;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER,
+ ATEN2011_port->shadowMCR);
+ if (status < 0)
+ return;
+ }
+
+ return;
+}
+
+static int ATEN2011_tiocmget(struct tty_struct *tty, struct file *file)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ unsigned int result;
+ __u16 msr;
+ __u16 mcr;
+ /* unsigned int mcr; */
+ int status = 0;
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ dbg("%s - port %d", __func__, port->number);
+
+ if (ATEN2011_port == NULL)
+ return -ENODEV;
+
+ status = get_uart_reg(port, MODEM_STATUS_REGISTER, &msr);
+ status = get_uart_reg(port, MODEM_CONTROL_REGISTER, &mcr);
+ /* mcr = ATEN2011_port->shadowMCR; */
+ /* COMMENT2: the Fallowing three line are commented for updating only MSR values */
+ result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0)
+ | ((mcr & MCR_RTS) ? TIOCM_RTS : 0)
+ | ((mcr & MCR_LOOPBACK) ? TIOCM_LOOP : 0)
+ | ((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0)
+ | ((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0)
+ | ((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0)
+ | ((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0);
+
+ dbg("%s - 0x%04X", __func__, result);
+
+ return result;
+}
+
+static int ATEN2011_tiocmset(struct tty_struct *tty, struct file *file,
+ unsigned int set, unsigned int clear)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ unsigned int mcr;
+ unsigned int status;
+
+ dbg("%s - port %d", __func__, port->number);
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return -ENODEV;
+
+ mcr = ATEN2011_port->shadowMCR;
+ if (clear & TIOCM_RTS)
+ mcr &= ~MCR_RTS;
+ if (clear & TIOCM_DTR)
+ mcr &= ~MCR_DTR;
+ if (clear & TIOCM_LOOP)
+ mcr &= ~MCR_LOOPBACK;
+
+ if (set & TIOCM_RTS)
+ mcr |= MCR_RTS;
+ if (set & TIOCM_DTR)
+ mcr |= MCR_DTR;
+ if (set & TIOCM_LOOP)
+ mcr |= MCR_LOOPBACK;
+
+ ATEN2011_port->shadowMCR = mcr;
+
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, mcr);
+ if (status < 0) {
+ dbg("setting MODEM_CONTROL_REGISTER Failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void ATEN2011_set_termios(struct tty_struct *tty,
+ struct usb_serial_port *port,
+ struct ktermios *old_termios)
+{
+ int status;
+ unsigned int cflag;
+ struct usb_serial *serial;
+ struct ATENINTL_port *ATEN2011_port;
+
+ dbg("ATEN2011_set_termios: START");
+
+ serial = port->serial;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ if (!ATEN2011_port->open) {
+ dbg("%s - port not opened", __func__);
+ return;
+ }
+
+ dbg("%s", "setting termios - ");
+
+ cflag = tty->termios->c_cflag;
+
+ if (!cflag) {
+ dbg("%s %s", __func__, "cflag is NULL");
+ return;
+ }
+
+ /* check that they really want us to change something */
+ if (old_termios) {
+ if ((cflag == old_termios->c_cflag) &&
+ (RELEVANT_IFLAG(tty->termios->c_iflag) ==
+ RELEVANT_IFLAG(old_termios->c_iflag))) {
+ dbg("%s", "Nothing to change");
+ return;
+ }
+ }
+
+ dbg("%s - clfag %08x iflag %08x", __func__,
+ tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
+
+ if (old_termios) {
+ dbg("%s - old clfag %08x old iflag %08x", __func__,
+ old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
+ }
+
+ dbg("%s - port %d", __func__, port->number);
+
+ /* change the port settings to the new ones specified */
+
+ ATEN2011_change_port_settings(tty, ATEN2011_port, old_termios);
+
+ if (!ATEN2011_port->read_urb) {
+ dbg("%s", "URB KILLED !!!!!");
+ return;
+ }
+
+ if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+ ATEN2011_port->read_urb->dev = serial->dev;
+ status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+ if (status) {
+ dbg
+ (" usb_submit_urb(read bulk) failed, status = %d",
+ status);
+ }
+ }
+ return;
+}
+
+static int get_lsr_info(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ unsigned int __user *value)
+{
+ int count;
+ unsigned int result = 0;
+
+ count = ATEN2011_chars_in_buffer(tty);
+ if (count == 0) {
+ dbg("%s -- Empty", __func__);
+ result = TIOCSER_TEMT;
+ }
+
+ if (copy_to_user(value, &result, sizeof(int)))
+ return -EFAULT;
+ return 0;
+}
+
+static int get_number_bytes_avail(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ unsigned int __user *value)
+{
+ unsigned int result = 0;
+
+ if (!tty)
+ return -ENOIOCTLCMD;
+
+ result = tty->read_cnt;
+
+ dbg("%s(%d) = %d", __func__, ATEN2011_port->port->number, result);
+ if (copy_to_user(value, &result, sizeof(int)))
+ return -EFAULT;
+
+ return -ENOIOCTLCMD;
+}
+
+static int set_modem_info(struct ATENINTL_port *ATEN2011_port, unsigned int cmd,
+ unsigned int __user *value)
+{
+ unsigned int mcr;
+ unsigned int arg;
+ __u16 Data;
+ int status;
+ struct usb_serial_port *port;
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+
+ mcr = ATEN2011_port->shadowMCR;
+
+ if (copy_from_user(&arg, value, sizeof(int)))
+ return -EFAULT;
+
+ switch (cmd) {
+ case TIOCMBIS:
+ if (arg & TIOCM_RTS)
+ mcr |= MCR_RTS;
+ if (arg & TIOCM_DTR)
+ mcr |= MCR_RTS;
+ if (arg & TIOCM_LOOP)
+ mcr |= MCR_LOOPBACK;
+ break;
+
+ case TIOCMBIC:
+ if (arg & TIOCM_RTS)
+ mcr &= ~MCR_RTS;
+ if (arg & TIOCM_DTR)
+ mcr &= ~MCR_RTS;
+ if (arg & TIOCM_LOOP)
+ mcr &= ~MCR_LOOPBACK;
+ break;
+
+ case TIOCMSET:
+ /* turn off the RTS and DTR and LOOPBACK
+ * and then only turn on what was asked to */
+ mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK);
+ mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0);
+ mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0);
+ mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0);
+ break;
+ }
+
+ ATEN2011_port->shadowMCR = mcr;
+
+ Data = ATEN2011_port->shadowMCR;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("setting MODEM_CONTROL_REGISTER Failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int get_modem_info(struct ATENINTL_port *ATEN2011_port,
+ unsigned int __user *value)
+{
+ unsigned int result = 0;
+ __u16 msr;
+ unsigned int mcr = ATEN2011_port->shadowMCR;
+ int status;
+
+ status = get_uart_reg(ATEN2011_port->port, MODEM_STATUS_REGISTER, &msr);
+ result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) /* 0x002 */
+ |((mcr & MCR_RTS) ? TIOCM_RTS : 0) /* 0x004 */
+ |((msr & ATEN2011_MSR_CTS) ? TIOCM_CTS : 0) /* 0x020 */
+ |((msr & ATEN2011_MSR_CD) ? TIOCM_CAR : 0) /* 0x040 */
+ |((msr & ATEN2011_MSR_RI) ? TIOCM_RI : 0) /* 0x080 */
+ |((msr & ATEN2011_MSR_DSR) ? TIOCM_DSR : 0); /* 0x100 */
+
+ dbg("%s -- %x", __func__, result);
+
+ if (copy_to_user(value, &result, sizeof(int)))
+ return -EFAULT;
+ return 0;
+}
+
+static int get_serial_info(struct ATENINTL_port *ATEN2011_port,
+ struct serial_struct __user *retinfo)
+{
+ struct serial_struct tmp;
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ if (!retinfo)
+ return -EFAULT;
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ tmp.type = PORT_16550A;
+ tmp.line = ATEN2011_port->port->serial->minor;
+ if (tmp.line == SERIAL_TTY_NO_MINOR)
+ tmp.line = 0;
+ tmp.port = ATEN2011_port->port->number;
+ tmp.irq = 0;
+ tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
+ tmp.xmit_fifo_size = NUM_URBS * URB_TRANSFER_BUFFER_SIZE;
+ tmp.baud_base = 9600;
+ tmp.close_delay = 5 * HZ;
+ tmp.closing_wait = 30 * HZ;
+
+ if (copy_to_user(retinfo, &tmp, sizeof(*retinfo)))
+ return -EFAULT;
+ return 0;
+}
+
+static int ATEN2011_ioctl(struct tty_struct *tty, struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ struct usb_serial_port *port = tty->driver_data;
+ struct ATENINTL_port *ATEN2011_port;
+ struct async_icount cnow;
+ struct async_icount cprev;
+ struct serial_icounter_struct icount;
+ int ATENret = 0;
+ unsigned int __user *user_arg = (unsigned int __user *)arg;
+
+ ATEN2011_port = usb_get_serial_port_data(port);
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd);
+
+ switch (cmd) {
+ /* return number of bytes available */
+
+ case TIOCINQ:
+ dbg("%s (%d) TIOCINQ", __func__, port->number);
+ return get_number_bytes_avail(tty, ATEN2011_port, user_arg);
+ break;
+
+ case TIOCOUTQ:
+ dbg("%s (%d) TIOCOUTQ", __func__, port->number);
+ return put_user(ATEN2011_chars_in_buffer(tty), user_arg);
+ break;
+
+ case TIOCSERGETLSR:
+ dbg("%s (%d) TIOCSERGETLSR", __func__, port->number);
+ return get_lsr_info(tty, ATEN2011_port, user_arg);
+ return 0;
+
+ case TIOCMBIS:
+ case TIOCMBIC:
+ case TIOCMSET:
+ dbg("%s (%d) TIOCMSET/TIOCMBIC/TIOCMSET", __func__,
+ port->number);
+ ATENret = set_modem_info(ATEN2011_port, cmd, user_arg);
+ return ATENret;
+
+ case TIOCMGET:
+ dbg("%s (%d) TIOCMGET", __func__, port->number);
+ return get_modem_info(ATEN2011_port, user_arg);
+
+ case TIOCGSERIAL:
+ dbg("%s (%d) TIOCGSERIAL", __func__, port->number);
+ return get_serial_info(ATEN2011_port,
+ (struct serial_struct __user *)arg);
+
+ case TIOCSSERIAL:
+ dbg("%s (%d) TIOCSSERIAL", __func__, port->number);
+ break;
+
+ case TIOCMIWAIT:
+ dbg("%s (%d) TIOCMIWAIT", __func__, port->number);
+ cprev = ATEN2011_port->icount;
+ while (1) {
+ /* see if a signal did it */
+ if (signal_pending(current))
+ return -ERESTARTSYS;
+ cnow = ATEN2011_port->icount;
+ if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
+ cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
+ return -EIO; /* no change => error */
+ if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
+ ((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
+ ((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
+ ((arg & TIOCM_CTS) && (cnow.cts != cprev.cts))) {
+ return 0;
+ }
+ cprev = cnow;
+ }
+ /* NOTREACHED */
+ break;
+
+ case TIOCGICOUNT:
+ cnow = ATEN2011_port->icount;
+ icount.cts = cnow.cts;
+ icount.dsr = cnow.dsr;
+ icount.rng = cnow.rng;
+ icount.dcd = cnow.dcd;
+ icount.rx = cnow.rx;
+ icount.tx = cnow.tx;
+ icount.frame = cnow.frame;
+ icount.overrun = cnow.overrun;
+ icount.parity = cnow.parity;
+ icount.brk = cnow.brk;
+ icount.buf_overrun = cnow.buf_overrun;
+
+ dbg("%s (%d) TIOCGICOUNT RX=%d, TX=%d", __func__,
+ port->number, icount.rx, icount.tx);
+ if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
+ return -EFAULT;
+ return 0;
+
+ default:
+ break;
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+static int ATEN2011_calc_baud_rate_divisor(int baudRate, int *divisor,
+ __u16 *clk_sel_val)
+{
+ dbg("%s - %d", __func__, baudRate);
+
+ if (baudRate <= 115200) {
+ *divisor = 115200 / baudRate;
+ *clk_sel_val = 0x0;
+ }
+ if ((baudRate > 115200) && (baudRate <= 230400)) {
+ *divisor = 230400 / baudRate;
+ *clk_sel_val = 0x10;
+ } else if ((baudRate > 230400) && (baudRate <= 403200)) {
+ *divisor = 403200 / baudRate;
+ *clk_sel_val = 0x20;
+ } else if ((baudRate > 403200) && (baudRate <= 460800)) {
+ *divisor = 460800 / baudRate;
+ *clk_sel_val = 0x30;
+ } else if ((baudRate > 460800) && (baudRate <= 806400)) {
+ *divisor = 806400 / baudRate;
+ *clk_sel_val = 0x40;
+ } else if ((baudRate > 806400) && (baudRate <= 921600)) {
+ *divisor = 921600 / baudRate;
+ *clk_sel_val = 0x50;
+ } else if ((baudRate > 921600) && (baudRate <= 1572864)) {
+ *divisor = 1572864 / baudRate;
+ *clk_sel_val = 0x60;
+ } else if ((baudRate > 1572864) && (baudRate <= 3145728)) {
+ *divisor = 3145728 / baudRate;
+ *clk_sel_val = 0x70;
+ }
+ return 0;
+}
+
+static int ATEN2011_send_cmd_write_baud_rate(struct ATENINTL_port
+ *ATEN2011_port, int baudRate)
+{
+ int divisor = 0;
+ int status;
+ __u16 Data;
+ unsigned char number;
+ __u16 clk_sel_val;
+ struct usb_serial_port *port;
+ int minor;
+
+ if (ATEN2011_port == NULL)
+ return -1;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+
+ dbg("%s", "Entering .......... ");
+
+ minor = ATEN2011_port->port->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ number = ATEN2011_port->port->number - minor;
+
+ dbg("%s - port = %d, baud = %d", __func__,
+ ATEN2011_port->port->number, baudRate);
+ /* reset clk_uart_sel in spregOffset */
+ if (baudRate > 115200) {
+#ifdef HW_flow_control
+ /*
+ * NOTE: need to see the pther register to modify
+ * setting h/w flow control bit to 1;
+ */
+ /* Data = ATEN2011_port->shadowMCR; */
+ Data = 0x2b;
+ ATEN2011_port->shadowMCR = Data;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing spreg failed in set_serial_baud");
+ return -1;
+ }
+#endif
+
+ } else {
+#ifdef HW_flow_control
+ /* setting h/w flow control bit to 0; */
+ /* Data = ATEN2011_port->shadowMCR; */
+ Data = 0xb;
+ ATEN2011_port->shadowMCR = Data;
+ status = set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ if (status < 0) {
+ dbg("Writing spreg failed in set_serial_baud");
+ return -1;
+ }
+#endif
+
+ }
+
+ if (1) /* baudRate <= 115200) */ {
+ clk_sel_val = 0x0;
+ Data = 0x0;
+ status =
+ ATEN2011_calc_baud_rate_divisor(baudRate, &divisor,
+ &clk_sel_val);
+ status = get_reg_sync(port, ATEN2011_port->SpRegOffset, &Data);
+ if (status < 0) {
+ dbg("reading spreg failed in set_serial_baud");
+ return -1;
+ }
+ Data = (Data & 0x8f) | clk_sel_val;
+ status = set_reg_sync(port, ATEN2011_port->SpRegOffset, Data);
+ if (status < 0) {
+ dbg("Writing spreg failed in set_serial_baud");
+ return -1;
+ }
+ /* Calculate the Divisor */
+
+ if (status) {
+ err("%s - bad baud rate", __func__);
+ dbg("%s", "bad baud rate");
+ return status;
+ }
+ /* Enable access to divisor latch */
+ Data = ATEN2011_port->shadowLCR | SERIAL_LCR_DLAB;
+ ATEN2011_port->shadowLCR = Data;
+ set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ /* Write the divisor */
+ Data = (unsigned char)(divisor & 0xff);
+ dbg("set_serial_baud Value to write DLL is %x", Data);
+ set_uart_reg(port, DIVISOR_LATCH_LSB, Data);
+
+ Data = (unsigned char)((divisor & 0xff00) >> 8);
+ dbg("set_serial_baud Value to write DLM is %x", Data);
+ set_uart_reg(port, DIVISOR_LATCH_MSB, Data);
+
+ /* Disable access to divisor latch */
+ Data = ATEN2011_port->shadowLCR & ~SERIAL_LCR_DLAB;
+ ATEN2011_port->shadowLCR = Data;
+ set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ }
+
+ return status;
+}
+
+static void ATEN2011_change_port_settings(struct tty_struct *tty,
+ struct ATENINTL_port *ATEN2011_port,
+ struct ktermios *old_termios)
+{
+ int baud;
+ unsigned cflag;
+ unsigned iflag;
+ __u8 lData;
+ __u8 lParity;
+ __u8 lStop;
+ int status;
+ __u16 Data;
+ struct usb_serial_port *port;
+ struct usb_serial *serial;
+
+ if (ATEN2011_port == NULL)
+ return;
+
+ port = (struct usb_serial_port *)ATEN2011_port->port;
+
+ serial = port->serial;
+
+ dbg("%s - port %d", __func__, ATEN2011_port->port->number);
+
+ if (!ATEN2011_port->open) {
+ dbg("%s - port not opened", __func__);
+ return;
+ }
+
+ if ((!tty) || (!tty->termios)) {
+ dbg("%s - no tty structures", __func__);
+ return;
+ }
+
+ dbg("%s", "Entering .......... ");
+
+ lData = LCR_BITS_8;
+ lStop = LCR_STOP_1;
+ lParity = LCR_PAR_NONE;
+
+ cflag = tty->termios->c_cflag;
+ iflag = tty->termios->c_iflag;
+
+ /* Change the number of bits */
+
+ /* COMMENT1: the below Line"if(cflag & CSIZE)" is added for the errors we get for serial loop data test i.e serial_loopback.pl -v */
+ /* if(cflag & CSIZE) */
+ {
+ switch (cflag & CSIZE) {
+ case CS5:
+ lData = LCR_BITS_5;
+ break;
+
+ case CS6:
+ lData = LCR_BITS_6;
+ break;
+
+ case CS7:
+ lData = LCR_BITS_7;
+ break;
+ default:
+ case CS8:
+ lData = LCR_BITS_8;
+ break;
+ }
+ }
+ /* Change the Parity bit */
+ if (cflag & PARENB) {
+ if (cflag & PARODD) {
+ lParity = LCR_PAR_ODD;
+ dbg("%s - parity = odd", __func__);
+ } else {
+ lParity = LCR_PAR_EVEN;
+ dbg("%s - parity = even", __func__);
+ }
+
+ } else {
+ dbg("%s - parity = none", __func__);
+ }
+
+ if (cflag & CMSPAR)
+ lParity = lParity | 0x20;
+
+ /* Change the Stop bit */
+ if (cflag & CSTOPB) {
+ lStop = LCR_STOP_2;
+ dbg("%s - stop bits = 2", __func__);
+ } else {
+ lStop = LCR_STOP_1;
+ dbg("%s - stop bits = 1", __func__);
+ }
+
+ /* Update the LCR with the correct value */
+ ATEN2011_port->shadowLCR &=
+ ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK);
+ ATEN2011_port->shadowLCR |= (lData | lParity | lStop);
+
+ dbg
+ ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is %x",
+ ATEN2011_port->shadowLCR);
+ /* Disable Interrupts */
+ Data = 0x00;
+ set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ Data = 0x00;
+ set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+
+ Data = 0xcf;
+ set_uart_reg(port, FIFO_CONTROL_REGISTER, Data);
+
+ /* Send the updated LCR value to the ATEN2011 */
+ Data = ATEN2011_port->shadowLCR;
+
+ set_uart_reg(port, LINE_CONTROL_REGISTER, Data);
+
+ Data = 0x00b;
+ ATEN2011_port->shadowMCR = Data;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+ Data = 0x00b;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+
+ /* set up the MCR register and send it to the ATEN2011 */
+
+ ATEN2011_port->shadowMCR = MCR_MASTER_IE;
+ if (cflag & CBAUD)
+ ATEN2011_port->shadowMCR |= (MCR_DTR | MCR_RTS);
+
+ if (cflag & CRTSCTS)
+ ATEN2011_port->shadowMCR |= (MCR_XON_ANY);
+ else
+ ATEN2011_port->shadowMCR &= ~(MCR_XON_ANY);
+
+ Data = ATEN2011_port->shadowMCR;
+ set_uart_reg(port, MODEM_CONTROL_REGISTER, Data);
+
+ /* Determine divisor based on baud rate */
+ baud = tty_get_baud_rate(tty);
+
+ if (!baud) {
+ /* pick a default, any default... */
+ dbg("%s", "Picked default baud...");
+ baud = 9600;
+ }
+
+ dbg("%s - baud rate = %d", __func__, baud);
+ status = ATEN2011_send_cmd_write_baud_rate(ATEN2011_port, baud);
+
+ /* Enable Interrupts */
+ Data = 0x0c;
+ set_uart_reg(port, INTERRUPT_ENABLE_REGISTER, Data);
+
+ if (ATEN2011_port->read_urb->status != -EINPROGRESS) {
+ ATEN2011_port->read_urb->dev = serial->dev;
+
+ status = usb_submit_urb(ATEN2011_port->read_urb, GFP_ATOMIC);
+
+ if (status) {
+ dbg
+ (" usb_submit_urb(read bulk) failed, status = %d",
+ status);
+ }
+ }
+ dbg
+ ("ATEN2011_change_port_settings ATEN2011_port->shadowLCR is End %x",
+ ATEN2011_port->shadowLCR);
+
+ return;
+}
+
+static int ATEN2011_calc_num_ports(struct usb_serial *serial)
+{
+
+ __u16 Data = 0x00;
+ int ret = 0;
+ int ATEN2011_2or4ports;
+ ret = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
+ ATEN_RDREQ, ATEN_RD_RTYPE, 0, GPIO_REGISTER,
+ &Data, VENDOR_READ_LENGTH, ATEN_WDR_TIMEOUT);
+
+/* ghostgum: here is where the problem appears to bet */
+/* Which of the following are needed? */
+/* Greg used the serial->type->num_ports=2 */
+/* But the code in the ATEN2011_open relies on serial->num_ports=2 */
+ if ((Data & 0x01) == 0) {
+ ATEN2011_2or4ports = 2;
+ serial->type->num_ports = 2;
+ serial->num_ports = 2;
+ }
+ /* else if(serial->interface->cur_altsetting->desc.bNumEndpoints == 9) */
+ else {
+ ATEN2011_2or4ports = 4;
+ serial->type->num_ports = 4;
+ serial->num_ports = 4;
+
+ }
+
+ return ATEN2011_2or4ports;
+}
+
+static int ATEN2011_startup(struct usb_serial *serial)
+{
+ struct ATENINTL_serial *ATEN2011_serial;
+ struct ATENINTL_port *ATEN2011_port;
+ struct usb_device *dev;
+ int i, status;
+ int minor;
+
+ __u16 Data;
+ dbg("%s", " ATEN2011_startup :entering..........");
+
+ if (!serial) {
+ dbg("%s", "Invalid Handler");
+ return -1;
+ }
+
+ dev = serial->dev;
+
+ dbg("%s", "Entering...");
+
+ /* create our private serial structure */
+ ATEN2011_serial = kzalloc(sizeof(struct ATENINTL_serial), GFP_KERNEL);
+ if (ATEN2011_serial == NULL) {
+ err("%s - Out of memory", __func__);
+ return -ENOMEM;
+ }
+
+ /* resetting the private structure field values to zero */
+ memset(ATEN2011_serial, 0, sizeof(struct ATENINTL_serial));
+
+ ATEN2011_serial->serial = serial;
+ /* initilize status polling flag to 0 */
+ ATEN2011_serial->status_polling_started = 0;
+
+ usb_set_serial_data(serial, ATEN2011_serial);
+ ATEN2011_serial->ATEN2011_spectrum_2or4ports =
+ ATEN2011_calc_num_ports(serial);
+ /* we set up the pointers to the endpoints in the ATEN2011_open *
+ * function, as the structures aren't created yet. */
+
+ /* set up port private structures */
+ for (i = 0; i < serial->num_ports; ++i) {
+ ATEN2011_port =
+ kmalloc(sizeof(struct ATENINTL_port), GFP_KERNEL);
+ if (ATEN2011_port == NULL) {
+ err("%s - Out of memory", __func__);
+ usb_set_serial_data(serial, NULL);
+ kfree(ATEN2011_serial);
+ return -ENOMEM;
+ }
+ memset(ATEN2011_port, 0, sizeof(struct ATENINTL_port));
+
+ /*
+ * Initialize all port interrupt end point to port 0
+ * int endpoint. Our device has only one interrupt end point
+ * comman to all port
+ */
+ /* serial->port[i]->interrupt_in_endpointAddress = serial->port[0]->interrupt_in_endpointAddress; */
+
+ ATEN2011_port->port = serial->port[i];
+ usb_set_serial_port_data(serial->port[i], ATEN2011_port);
+
+ minor = serial->port[i]->serial->minor;
+ if (minor == SERIAL_TTY_NO_MINOR)
+ minor = 0;
+ ATEN2011_port->port_num =
+ ((serial->port[i]->number - minor) + 1);
+
+ if (ATEN2011_port->port_num == 1) {
+ ATEN2011_port->SpRegOffset = 0x0;
+ ATEN2011_port->ControlRegOffset = 0x1;
+ ATEN2011_port->DcrRegOffset = 0x4;
+ } else if ((ATEN2011_port->port_num == 2)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 4)) {
+ ATEN2011_port->SpRegOffset = 0x8;
+ ATEN2011_port->ControlRegOffset = 0x9;
+ ATEN2011_port->DcrRegOffset = 0x16;
+ } else if ((ATEN2011_port->port_num == 2)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 2)) {
+ ATEN2011_port->SpRegOffset = 0xa;
+ ATEN2011_port->ControlRegOffset = 0xb;
+ ATEN2011_port->DcrRegOffset = 0x19;
+ } else if ((ATEN2011_port->port_num == 3)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 4)) {
+ ATEN2011_port->SpRegOffset = 0xa;
+ ATEN2011_port->ControlRegOffset = 0xb;
+ ATEN2011_port->DcrRegOffset = 0x19;
+ } else if ((ATEN2011_port->port_num == 4)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports ==
+ 4)) {
+ ATEN2011_port->SpRegOffset = 0xc;
+ ATEN2011_port->ControlRegOffset = 0xd;
+ ATEN2011_port->DcrRegOffset = 0x1c;
+ }
+
+ usb_set_serial_port_data(serial->port[i], ATEN2011_port);
+
+ /* enable rx_disable bit in control register */
+
+ status = get_reg_sync(serial->port[i],
+ ATEN2011_port->ControlRegOffset, &Data);
+ if (status < 0) {
+ dbg("Reading ControlReg failed status-0x%x",
+ status);
+ break;
+ } else
+ dbg
+ ("ControlReg Reading success val is %x, status%d",
+ Data, status);
+ Data |= 0x08; /* setting driver done bit */
+ Data |= 0x04; /* sp1_bit to have cts change reflect in modem status reg */
+
+ /* Data |= 0x20; */ /* rx_disable bit */
+ status = set_reg_sync(serial->port[i],
+ ATEN2011_port->ControlRegOffset, Data);
+ if (status < 0) {
+ dbg
+ ("Writing ControlReg failed(rx_disable) status-0x%x",
+ status);
+ break;
+ } else
+ dbg
+ ("ControlReg Writing success(rx_disable) status%d",
+ status);
+
+ /*
+ * Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
+ * and 0x24 in DCR3
+ */
+ Data = 0x01;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ATEN2011_port->DcrRegOffset + 0),
+ Data);
+ if (status < 0) {
+ dbg("Writing DCR0 failed status-0x%x", status);
+ break;
+ } else
+ dbg("DCR0 Writing success status%d", status);
+
+ Data = 0x05;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ATEN2011_port->DcrRegOffset + 1),
+ Data);
+ if (status < 0) {
+ dbg("Writing DCR1 failed status-0x%x", status);
+ break;
+ } else
+ dbg("DCR1 Writing success status%d", status);
+
+ Data = 0x24;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ATEN2011_port->DcrRegOffset + 2),
+ Data);
+ if (status < 0) {
+ dbg("Writing DCR2 failed status-0x%x", status);
+ break;
+ } else
+ dbg("DCR2 Writing success status%d", status);
+
+ /* write values in clkstart0x0 and clkmulti 0x20 */
+ Data = 0x0;
+ status = set_reg_sync(serial->port[i], CLK_START_VALUE_REGISTER,
+ Data);
+ if (status < 0) {
+ dbg
+ ("Writing CLK_START_VALUE_REGISTER failed status-0x%x",
+ status);
+ break;
+ } else
+ dbg
+ ("CLK_START_VALUE_REGISTER Writing success status%d",
+ status);
+
+ Data = 0x20;
+ status = set_reg_sync(serial->port[i], CLK_MULTI_REGISTER,
+ Data);
+ if (status < 0) {
+ dbg
+ ("Writing CLK_MULTI_REGISTER failed status-0x%x",
+ status);
+ break;
+ } else
+ dbg("CLK_MULTI_REGISTER Writing success status%d",
+ status);
+
+ /* Zero Length flag register */
+ if ((ATEN2011_port->port_num != 1)
+ && (ATEN2011_serial->ATEN2011_spectrum_2or4ports == 2)) {
+
+ Data = 0xff;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num)),
+ Data);
+ dbg("ZLIP offset%x",
+ (__u16) (ZLP_REG1 +
+ ((__u16) ATEN2011_port->port_num)));
+ if (status < 0) {
+ dbg
+ ("Writing ZLP_REG%d failed status-0x%x",
+ i + 2, status);
+ break;
+ } else
+ dbg("ZLP_REG%d Writing success status%d",
+ i + 2, status);
+ } else {
+ Data = 0xff;
+ status = set_reg_sync(serial->port[i],
+ (__u16)(ZLP_REG1 + ((__u16)ATEN2011_port->port_num) - 0x1),
+ Data);
+ dbg("ZLIP offset%x",
+ (__u16) (ZLP_REG1 +
+ ((__u16) ATEN2011_port->port_num) -
+ 0x1));
+ if (status < 0) {
+ dbg
+ ("Writing ZLP_REG%d failed status-0x%x",
+ i + 1, status);
+ break;
+ } else
+ dbg("ZLP_REG%d Writing success status%d",
+ i + 1, status);
+
+ }
+ ATEN2011_port->control_urb = usb_alloc_urb(0, GFP_ATOMIC);
+ ATEN2011_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
+
+ }
+
+ /* Zero Length flag enable */
+ Data = 0x0f;
+ status = set_reg_sync(serial->port[0], ZLP_REG5, Data);
+ if (status < 0) {
+ dbg("Writing ZLP_REG5 failed status-0x%x", status);
+ return -1;
+ } else
+ dbg("ZLP_REG5 Writing success status%d", status);
+
+ /* setting configuration feature to one */
+ usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
+ (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ);
+ return 0;
+}
+
+static void ATEN2011_shutdown(struct usb_serial *serial)
+{
+ int i;
+ struct ATENINTL_port *ATEN2011_port;
+
+ /* check for the ports to be closed,close the ports and disconnect */
+
+ /* free private structure allocated for serial port *
+ * stop reads and writes on all ports */
+
+ for (i = 0; i < serial->num_ports; ++i) {
+ ATEN2011_port = usb_get_serial_port_data(serial->port[i]);
+ kfree(ATEN2011_port->ctrl_buf);
+ usb_kill_urb(ATEN2011_port->control_urb);
+ kfree(ATEN2011_port);
+ usb_set_serial_port_data(serial->port[i], NULL);
+ }
+
+ /* free private structure allocated for serial device */
+
+ kfree(usb_get_serial_data(serial));
+ usb_set_serial_data(serial, NULL);
+}
+
+static struct usb_serial_driver aten_serial_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "aten2011",
+ },
+ .description = DRIVER_DESC,
+ .id_table = id_table,
+ .open = ATEN2011_open,
+ .close = ATEN2011_close,
+ .write = ATEN2011_write,
+ .write_room = ATEN2011_write_room,
+ .chars_in_buffer = ATEN2011_chars_in_buffer,
+ .throttle = ATEN2011_throttle,
+ .unthrottle = ATEN2011_unthrottle,
+ .calc_num_ports = ATEN2011_calc_num_ports,
+
+ .ioctl = ATEN2011_ioctl,
+ .set_termios = ATEN2011_set_termios,
+ .break_ctl = ATEN2011_break,
+ .tiocmget = ATEN2011_tiocmget,
+ .tiocmset = ATEN2011_tiocmset,
+ .attach = ATEN2011_startup,
+ .shutdown = ATEN2011_shutdown,
+ .read_bulk_callback = ATEN2011_bulk_in_callback,
+ .read_int_callback = ATEN2011_interrupt_callback,
+};
+
+static struct usb_driver aten_driver = {
+ .name = "aten2011",
+ .probe = usb_serial_probe,
+ .disconnect = usb_serial_disconnect,
+ .id_table = id_table,
+};
+
+static int __init aten_init(void)
+{
+ int retval;
+
+ /* Register with the usb serial */
+ retval = usb_serial_register(&aten_serial_driver);
+ if (retval)
+ return retval;
+
+ printk(KERN_INFO KBUILD_MODNAME ":"
+ DRIVER_DESC " " DRIVER_VERSION "\n");
+
+ /* Register with the usb */
+ retval = usb_register(&aten_driver);
+ if (retval)
+ usb_serial_deregister(&aten_serial_driver);
+
+ return retval;
+}
+
+static void __exit aten_exit(void)
+{
+ usb_deregister(&aten_driver);
+ usb_serial_deregister(&aten_serial_driver);
+}
+
+module_init(aten_init);
+module_exit(aten_exit);
+
+/* Module information */
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
+MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c
index 2eb61372fe0..1c710628df0 100644
--- a/drivers/staging/usbip/stub_rx.c
+++ b/drivers/staging/usbip/stub_rx.c
@@ -334,7 +334,7 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
spin_lock_irqsave(&sdev->priv_lock, flags);
- priv = kmem_cache_alloc(stub_priv_cache, GFP_ATOMIC);
+ priv = kmem_cache_zalloc(stub_priv_cache, GFP_ATOMIC);
if (!priv) {
dev_err(&sdev->interface->dev, "alloc stub_priv\n");
spin_unlock_irqrestore(&sdev->priv_lock, flags);
@@ -342,8 +342,6 @@ static struct stub_priv *stub_priv_alloc(struct stub_device *sdev,
return NULL;
}
- memset(priv, 0, sizeof(struct stub_priv));
-
priv->seqnum = pdu->base.seqnum;
priv->sdev = sdev;
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index 0fd33a62d93..e4c71435aa1 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -31,8 +31,7 @@ static ssize_t show_status(struct device *dev, struct device_attribute *attr,
char *s = out;
int i = 0;
- if (!the_controller || !out)
- BUG();
+ BUG_ON(!the_controller || !out);
spin_lock(&the_controller->lock);
diff --git a/drivers/staging/winbond/bss_f.h b/drivers/staging/winbond/bss_f.h
deleted file mode 100644
index a433b5a8592..00000000000
--- a/drivers/staging/winbond/bss_f.h
+++ /dev/null
@@ -1,63 +0,0 @@
-#ifndef __WINBOND_BSS_F_H
-#define __WINBOND_BSS_F_H
-
-#include "core.h"
-
-struct PMKID_Information_Element;
-
-//
-// BSS descriptor DataBase management global function
-//
-
-void vBSSdescriptionInit(struct wbsoft_priv * adapter);
-void vBSSfoundList(struct wbsoft_priv * adapter);
-u8 boChanFilter(struct wbsoft_priv * adapter, u8 ChanNo);
-u16 wBSSallocateEntry(struct wbsoft_priv * adapter);
-u16 wBSSGetEntry(struct wbsoft_priv * adapter);
-void vSimpleHouseKeeping(struct wbsoft_priv * adapter);
-u16 wBSShouseKeeping(struct wbsoft_priv * adapter);
-void ClearBSSdescpt(struct wbsoft_priv * adapter, u16 i);
-u16 wBSSfindBssID(struct wbsoft_priv * adapter, u8 *pbBssid);
-u16 wBSSfindDedicateCandidate(struct wbsoft_priv * adapter, struct SSID_Element *psSsid, u8 *pbBssid);
-u16 wBSSfindMACaddr(struct wbsoft_priv * adapter, u8 *pbMacAddr);
-u16 wBSSsearchMACaddr(struct wbsoft_priv * adapter, u8 *pbMacAddr, u8 band);
-u16 wBSSaddScanData(struct wbsoft_priv *, u16, psRXDATA);
-u16 wBSSUpdateScanData(struct wbsoft_priv * adapter, u16 wBssIdx, psRXDATA psRcvData);
-u16 wBSScreateIBSSdata(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData);
-void DesiredRate2BSSdescriptor(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData,
- u8 *pBasicRateSet, u8 BasicRateCount,
- u8 *pOperationRateSet, u8 OperationRateCount);
-void DesiredRate2InfoElement(struct wbsoft_priv * adapter, u8 *addr, u16 *iFildOffset,
- u8 *pBasicRateSet, u8 BasicRateCount,
- u8 *pOperationRateSet, u8 OperationRateCount);
-void BSSAddIBSSdata(struct wbsoft_priv * adapter, PWB_BSSDESCRIPTION psDesData);
-unsigned char boCmpMacAddr( u8 *, u8 *);
-unsigned char boCmpSSID(struct SSID_Element *psSSID1, struct SSID_Element *psSSID2);
-u16 wBSSfindSSID(struct wbsoft_priv * adapter, struct SSID_Element *psSsid);
-u16 wRoamingQuery(struct wbsoft_priv * adapter);
-void vRateToBitmap(struct wbsoft_priv * adapter, u16 index);
-u8 bRateToBitmapIndex(struct wbsoft_priv * adapter, u8 bRate);
-u8 bBitmapToRate(u8 i);
-unsigned char boIsERPsta(struct wbsoft_priv * adapter, u16 i);
-unsigned char boCheckConnect(struct wbsoft_priv * adapter);
-unsigned char boCheckSignal(struct wbsoft_priv * adapter);
-void AddIBSSIe(struct wbsoft_priv * adapter,PWB_BSSDESCRIPTION psDesData );//added by ws for WPA_None06/01/04
-void BssScanUpToDate(struct wbsoft_priv * adapter);
-void BssUpToDate(struct wbsoft_priv * adapter);
-void RateSort(u8 *RateArray, u8 num, u8 mode);
-void RateReSortForSRate(struct wbsoft_priv * adapter, u8 *RateArray, u8 num);
-void Assemble_IE(struct wbsoft_priv * adapter, u16 wBssIdx);
-void SetMaxTxRate(struct wbsoft_priv * adapter);
-
-void CreateWpaIE(struct wbsoft_priv * adapter, u16* iFildOffset, u8 *msg, struct Management_Frame* msgHeader,
- struct Association_Request_Frame_Body* msgBody, u16 iMSindex); //added by WS 05/14/05
-
-#ifdef _WPA2_
-void CreateRsnIE(struct wbsoft_priv * adapter, u16* iFildOffset, u8 *msg, struct Management_Frame* msgHeader,
- struct Association_Request_Frame_Body* msgBody, u16 iMSindex);//added by WS 05/14/05
-
-u16 SearchPmkid(struct wbsoft_priv * adapter, struct Management_Frame* msgHeader,
- struct PMKID_Information_Element * AssoReq_PMKID );
-#endif
-
-#endif
diff --git a/drivers/staging/winbond/bssdscpt.h b/drivers/staging/winbond/bssdscpt.h
deleted file mode 100644
index 3a71d4efb89..00000000000
--- a/drivers/staging/winbond/bssdscpt.h
+++ /dev/null
@@ -1,164 +0,0 @@
-#ifndef __WINBOND_BSSDSCPT_H
-#define __WINBOND_BSSDSCPT_H
-
-#include <linux/types.h>
-
-#include "mds_s.h"
-#include "mlme_s.h"
-
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-// bssdscpt.c
-// BSS descriptor data base
-// history :
-//
-// Description:
-// BSS descriptor data base will store the information of the stations at the
-// surrounding environment. The first entry( psBSS(0) ) will not be used and the
-// second one( psBSS(1) ) will be used for the broadcast address.
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-//#define MAX_ACC_RSSI_COUNT 10
-#define MAX_ACC_RSSI_COUNT 6
-
-///////////////////////////////////////////////////////////////////////////
-//
-// BSS Description set Element , to store scan received Beacon information
-//
-// Our's differs slightly from the specs. The specify a PHY_Parameter_Set.
-// Since we're only doing a DS design right now, we just have a DS structure.
-//////////////////////////////////////////////////////////////////////////////
-typedef struct BSSDescriptionElement
-{
- u32 SlotValid;
- u32 PowerSaveMode;
- RXLAYER1 RxLayer1;
-
- u8 abPeerAddress[ MAC_ADDR_LENGTH + 2 ]; // peer MAC Address associated with this session. 6-OCTET value
- u32 dwBgScanStamp; // BgScan Sequence Counter stamp, record psROAM->dwScanCounter.
-
- u16 Beacon_Period;
- u16 wATIM_Window;
-
- u8 abBssID[ MAC_ADDR_LENGTH + 2 ]; // 6B
-
- u8 bBssType;
- u8 DTIM_Period; // 1 octet usually from TIM element, if present
- u8 boInTimerHandler;
- u8 boERP; // analysis ERP or (extended) supported rate element
-
- u8 Timestamp[8];
- u8 BasicRate[32];
- u8 OperationalRate[32];
- u32 dwBasicRateBitmap; //bit map, retrieve from SupportedRateSet
- u32 dwOperationalRateBitmap; //bit map, retrieve from SupportedRateSet and
- // ExtendedSupportedRateSet
- // For RSSI calculating
- u32 HalRssi[MAX_ACC_RSSI_COUNT]; // Encode. It must use MACRO of HAL to get the LNA and AGC data
- u32 HalRssiIndex;
-
- ////From beacon/probe response
- struct SSID_Element SSID; // 34B
- u8 reserved_1[ 2 ];
-
- struct Capability_Information_Element CapabilityInformation; // 2B
- u8 reserved_2[ 2 ];
-
- struct CF_Parameter_Set_Element CF_Parameter_Set; // 8B
- struct IBSS_Parameter_Set_Element IBSS_Parameter_Set; // 4B
- struct TIM_Element TIM_Element_Set; // 256B
-
- struct DS_Parameter_Set_Element DS_Parameter_Set; // 3B
- u8 reserved_3;
-
- struct ERP_Information_Element ERP_Information_Set; // 3B
- u8 reserved_4;
-
- struct Supported_Rates_Element SupportedRateSet; // 10B
- u8 reserved_5[2];
-
- struct Extended_Supported_Rates_Element ExtendedSupportedRateSet; // 257B
- u8 reserved_6[3];
-
- u8 band;
- u8 reserved_7[3];
-
- // for MLME module
- u16 wState; // the current state of the system
- u16 wIndex; // THIS BSS element entry index
-
- void* psadapter; // pointer to THIS adapter
- struct timer_list timer; // MLME timer
-
- // Authentication
- u16 wAuthAlgo; // peer MAC MLME use Auth algorithm, default OPEN_AUTH
- u16 wAuthSeqNum; // current local MAC sendout AuthReq sequence number
-
- u8 auth_challengeText[128];
-
- ////For XP:
- u32 ies_len; // information element length
- u8 ies[256]; // information element
-
- ////For WPA
- u8 RsnIe_Type[2]; //added by ws for distinguish WPA and WPA2 05/14/04
- u8 RsnIe_len;
- u8 Rsn_Num;
-
- // to record the rsn cipher suites,addded by ws 09/05/04
- SUITE_SELECTOR group_cipher; // 4B
- SUITE_SELECTOR pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
- SUITE_SELECTOR auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
-
- u16 pairwise_key_cipher_suite_count;
- u16 auth_key_mgt_suite_count;
-
- u8 pairwise_key_cipher_suite_selected;
- u8 auth_key_mgt_suite_selected;
- u8 reserved_8[2];
-
- struct RSN_Capability_Element rsn_capabilities; // 2B
- u8 reserved_9[2];
-
- //to record the rsn cipher suites for WPA2
- #ifdef _WPA2_
- u32 pre_auth; //added by WS for distinguish for 05/04/04
- SUITE_SELECTOR wpa2_group_cipher; // 4B
- SUITE_SELECTOR wpa2_pairwise_key_cipher_suites[WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT];
- SUITE_SELECTOR wpa2_auth_key_mgt_suites[WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT];
-
- u16 wpa2_pairwise_key_cipher_suite_count;
- u16 wpa2_auth_key_mgt_suite_count;
-
- u8 wpa2_pairwise_key_cipher_suite_selected;
- u8 wpa2_auth_key_mgt_suite_selected;
- u8 reserved_10[2];
-
- struct RSN_Capability_Element wpa2_rsn_capabilities; // 2B
- u8 reserved_11[2];
- #endif //endif _WPA2_
-
- //For Replay protection
-// u8 PairwiseTSC[6];
-// u8 GroupTSC[6];
-
- ////For up-to-date
- u32 ScanTimeStamp; //for the decision whether the station/AP(may exist at
- //different channels) has left. It must be detected by
- //scanning. Local device may connected or disconnected.
- u32 BssTimeStamp; //Only for the decision whether the station/AP(exist in
- //the same channel, and no scanning) if local device has
- //connected successfully.
-
- // 20061108 Add for storing WPS_IE. [E id][Length][OUI][Data]
- u8 WPS_IE_Data[MAX_IE_APPEND_SIZE];
- u16 WPS_IE_length;
- u16 WPS_IE_length_tmp; // For verify there is an WPS_IE in Beacon or probe response
-
-} WB_BSSDESCRIPTION, *PWB_BSSDESCRIPTION;
-
-#define wBSSConnectedSTA(adapter) \
- ((u16)(adapter)->sLocalPara.wConnectedSTAindex)
-
-#define psBSS(i) (&(adapter->asBSSDescriptElement[(i)]))
-
-#endif
diff --git a/drivers/staging/winbond/common.h b/drivers/staging/winbond/common.h
deleted file mode 100644
index c4d96041e9a..00000000000
--- a/drivers/staging/winbond/common.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// common.h
-//
-// This file contains the OS dependant definition and function.
-// Every OS has this file individual.
-//
-
-#define DebugUsbdStatusInformation( _A )
-
-#ifndef COMMON_DEF
-#define COMMON_DEF
-
-//#define DEBUG_ENABLED 1
-
-//==================================================================================================
-// Common function definition
-//==================================================================================================
-#define DEBUG_ENABLED
-#define ETH_LENGTH_OF_ADDRESS 6
-#ifdef DEBUG_ENABLED
-#define WBDEBUG( _M ) printk _M
-#else
-#define WBDEBUG( _M ) 0
-#endif
-
-#endif // COMMON_DEF
-
diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h
index fe142a10ea8..eb4c090972c 100644
--- a/drivers/staging/winbond/core.h
+++ b/drivers/staging/winbond/core.h
@@ -3,9 +3,9 @@
#include <linux/wireless.h>
-#include "bssdscpt.h"
-#include "mto.h"
+#include "mlme_s.h"
#include "wbhal_s.h"
+#include "mto.h"
#define WBLINUX_PACKET_ARRAY_SIZE (ETHERNET_TX_DESCRIPTORS*4)
@@ -15,12 +15,11 @@ struct wbsoft_priv {
u32 adapterIndex; // 20060703.4 Add for using padapterContext global adapter point
WB_LOCALDESCRIPT sLocalPara; // Myself connected parameters
- PWB_BSSDESCRIPTION asBSSDescriptElement;
MLME_FRAME sMlmeFrame; // connect to peerSTA parameters
MTO_PARAMETERS sMtoPara; // MTO_struct ...
- hw_data_t sHwData; //For HAL
+ struct hw_data sHwData; //For HAL
MDS Mds;
spinlock_t SpinLock;
diff --git a/drivers/staging/winbond/ds_tkip.h b/drivers/staging/winbond/ds_tkip.h
deleted file mode 100644
index 9c5c4e73f2c..00000000000
--- a/drivers/staging/winbond/ds_tkip.h
+++ /dev/null
@@ -1,37 +0,0 @@
-#ifndef __WINBOND_DS_TKIP_H
-#define __WINBOND_DS_TKIP_H
-
-#include <linux/types.h>
-
-// Rotation functions on 32 bit values
-#define ROL32( A, n ) \
- ( ((A) << (n)) | ( ((A)>>(32-(n))) & ( (1UL << (n)) - 1 ) ) )
-
-#define ROR32( A, n ) ROL32( (A), 32-(n) )
-
-
-typedef struct tkip
-{
- u32 K0, K1; // Key
- union
- {
- struct // Current state
- {
- u32 L;
- u32 R;
- };
- u8 LR[8];
- };
- union
- {
- u32 M; // Message accumulator (single word)
- u8 Mb[4];
- };
- s32 bytes_in_M; // # bytes in M
-} tkip_t;
-
-//void _append_data( u8 *pData, u16 size, tkip_t *p );
-void Mds_MicGet( void* adapter, void* pRxLayer1, u8 *pKey, u8 *pMic );
-void Mds_MicFill( void* adapter, void* pDes, u8 *XmitBufAddress );
-
-#endif
diff --git a/drivers/staging/winbond/gl_80211.h b/drivers/staging/winbond/gl_80211.h
deleted file mode 100644
index 5a244c44a61..00000000000
--- a/drivers/staging/winbond/gl_80211.h
+++ /dev/null
@@ -1,126 +0,0 @@
-#ifndef __GL_80211_H__
-#define __GL_80211_H__
-
-#include <linux/types.h>
-
-/****************** CONSTANT AND MACRO SECTION ******************************/
-
-/* BSS Type */
-enum {
- WLAN_BSSTYPE_INFRASTRUCTURE = 0,
- WLAN_BSSTYPE_INDEPENDENT,
- WLAN_BSSTYPE_ANY_BSS,
-};
-
-
-
-/* Preamble_Type, see <SFS-802.11G-MIB-203> */
-typedef enum preamble_type {
- WLAN_PREAMBLE_TYPE_SHORT,
- WLAN_PREAMBLE_TYPE_LONG,
-} preamble_type_e;
-
-
-/* Slot_Time_Type, see <SFS-802.11G-MIB-208> */
-typedef enum slot_time_type {
- WLAN_SLOT_TIME_TYPE_LONG,
- WLAN_SLOT_TIME_TYPE_SHORT,
-} slot_time_type_e;
-
-/*--------------------------------------------------------------------------*/
-/* Encryption Mode */
-typedef enum {
- WEP_DISABLE = 0,
- WEP_64,
- WEP_128,
-
- ENCRYPT_DISABLE,
- ENCRYPT_WEP,
- ENCRYPT_WEP_NOKEY,
- ENCRYPT_TKIP,
- ENCRYPT_TKIP_NOKEY,
- ENCRYPT_CCMP,
- ENCRYPT_CCMP_NOKEY,
-} encryption_mode_e;
-
-typedef enum _WLAN_RADIO {
- WLAN_RADIO_ON,
- WLAN_RADIO_OFF,
- WLAN_RADIO_MAX, // not a real type, defined as an upper bound
-} WLAN_RADIO;
-
-typedef struct _WLAN_RADIO_STATUS {
- WLAN_RADIO HWStatus;
- WLAN_RADIO SWStatus;
-} WLAN_RADIO_STATUS;
-
-//----------------------------------------------------------------------------
-// 20041021 1.1.81.1000 ybjiang
-// add for radio notification
-typedef
-void (*RADIO_NOTIFICATION_HANDLER)(
- void *Data,
- void *RadioStatusBuffer,
- u32 RadioStatusBufferLen
- );
-
-typedef struct _WLAN_RADIO_NOTIFICATION
-{
- RADIO_NOTIFICATION_HANDLER RadioChangeHandler;
- void *Data;
-} WLAN_RADIO_NOTIFICATION;
-
-//----------------------------------------------------------------------------
-// 20041102 1.1.91.1000 ybjiang
-// add for OID_802_11_CUST_REGION_CAPABILITIES and OID_802_11_OID_REGION
-typedef enum _WLAN_REGION_CODE
-{
- WLAN_REGION_UNKNOWN,
- WLAN_REGION_EUROPE,
- WLAN_REGION_JAPAN,
- WLAN_REGION_USA,
- WLAN_REGION_FRANCE,
- WLAN_REGION_SPAIN,
- WLAN_REGION_ISRAEL,
- WLAN_REGION_MAX, // not a real type, defined as an upper bound
-} WLAN_REGION_CODE;
-
-#define REGION_NAME_MAX_LENGTH 256
-
-typedef struct _WLAN_REGION_CHANNELS
-{
- u32 Length;
- u32 NameLength;
- u8 Name[REGION_NAME_MAX_LENGTH];
- WLAN_REGION_CODE Code;
- u32 Frequency[1];
-} WLAN_REGION_CHANNELS;
-
-typedef struct _WLAN_REGION_CAPABILITIES
-{
- u32 NumberOfItems;
- WLAN_REGION_CHANNELS Region[1];
-} WLAN_REGION_CAPABILITIES;
-
-typedef struct _region_name_map {
- WLAN_REGION_CODE region;
- u8 *name;
- u32 *channels;
-} region_name_map;
-
-/*--------------------------------------------------------------------------*/
-#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
-#define MACSTR "%02X:%02X:%02X:%02X:%02X:%02X"
-
-// TODO: 0627 kevin
-#define MIC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5], (a)[6], (a)[7]
-#define MICSTR "%02X %02X %02X %02X %02X %02X %02X %02X"
-
-#define MICKEY2STR(a) MIC2STR(a)
-#define MICKEYSTR MICSTR
-
-
-#endif /* __GL_80211_H__ */
-/*** end of file ***/
-
-
diff --git a/drivers/staging/winbond/ioctls.h b/drivers/staging/winbond/ioctls.h
deleted file mode 100644
index e8b35dc7e32..00000000000
--- a/drivers/staging/winbond/ioctls.h
+++ /dev/null
@@ -1,678 +0,0 @@
-//============================================================================
-// IOCTLS.H -
-//
-// Description:
-// Define the IOCTL codes.
-//
-// Revision history:
-// --------------------------------------------------------------------------
-//
-// Copyright (c) 2002-2004 Winbond Electronics Corp. All rights reserved.
-//=============================================================================
-
-#ifndef _IOCTLS_H
-#define _IOCTLS_H
-
-// PD43 Keep it - Used with the Win33 application
-// #include <winioctl.h>
-
-//========================================================
-// 20040108 ADD the follow for test
-//========================================================
-#define INFORMATION_LENGTH sizeof(unsigned int)
-
-#define WB32_IOCTL_INDEX 0x0900 //­×§ÄĽHŤKŹŰŽe//
-
-#define Wb32_RegisterRead CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 0, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb32_RegisterWrite CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 1, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb32_SendPacket CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 2, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb32_QuerySendResult CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 3, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb32_SetFragmentThreshold CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 4, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb32_SetLinkStatus CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 5, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb32_SetBulkIn CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 6, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb32_LoopbackTest CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 7, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_EEPromRead CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 8, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_EEPromWrite CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 9, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_FlashReadData CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 10, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_FlashWrite CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 11, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_FlashWriteBurst CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 12, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_TxBurstStart CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 13, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_TxBurstStop CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 14, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define Wb35_TxBurstStatus CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB32_IOCTL_INDEX + 15, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// For IOCTL interface
-//================================================
-#define LINKNAME_STRING "\\DosDevices\\W35UND"
-#define NTDEVICE_STRING "\\Device\\W35UND"
-#define APPLICATION_LINK "\\\\.\\W35UND"
-
-#define WB_IOCTL_INDEX 0x0800
-#define WB_IOCTL_TS_INDEX WB_IOCTL_INDEX + 60
-#define WB_IOCTL_DUT_INDEX WB_IOCTL_TS_INDEX + 40
-
-//=============================================================================
-// IOCTLS defined for DUT (Device Under Test)
-
-// IOCTL_WB_802_11_DUT_MAC_ADDRESS
-// Query: Return the dot11StationID
-// Set : Set the dot11StationID. Demo only.
-//
-#define IOCTL_WB_802_11_DUT_MAC_ADDRESS CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 1, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_BSS_DESCRIPTION
-// Query: Return the info. of the current connected BSS.
-// Set : None.
-//
-#define IOCTL_WB_802_11_DUT_BSS_DESCRIPTION CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 2, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_TX_RATE
-// Query: Return the current transmission rate.
-// Set : Set the transmission rate of the Tx packets.
-//
-#define IOCTL_WB_802_11_DUT_TX_RATE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 3, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_CURRENT_STA_STATE
-// Query: Return the current STA state. (WB_STASTATE type)
-// Set : None.
-//
-#define IOCTL_WB_802_11_DUT_CURRENT_STA_STATE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 4, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-/////////// 10/31/02' Added /////////////////////
-
-// IOCTL_WB_802_11_DUT_START_IBSS_REQUEST
-// Query: None.
-// Set : Start a new IBSS
-//
-#define IOCTL_WB_802_11_DUT_START_IBSS_REQUEST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 5, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_JOIN_REQUEST
-// Query: None.
-// Set : Synchronize with the selected BSS
-//
-#define IOCTL_WB_802_11_DUT_JOIN_REQUEST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 6, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_AUTHEN_REQUEST
-// Query: None.
-// Set : Authenticate with the BSS
-//
-#define IOCTL_WB_802_11_DUT_AUTHEN_REQUEST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 7, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST
-// Query: None.
-// Set : DeAuthenticate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_DEAUTHEN_REQUEST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 8, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ASSOC_REQUEST
-// Query: None.
-// Set : Associate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_ASSOC_REQUEST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 9, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_REASSOC_REQUEST
-// Query: None.
-// Set : ReAssociate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_REASSOC_REQUEST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 10, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-
-// IOCTL_WB_802_11_DUT_DISASSOC_REQUEST
-// Query: None.
-// Set : DisAssociate withe the BSS
-//
-#define IOCTL_WB_802_11_DUT_DISASSOC_REQUEST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 11, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_FRAG_THRESHOLD
-// Query: Return the dot11FragmentThreshold
-// Set : Set the dot11FragmentThreshold
-//
-#define IOCTL_WB_802_11_DUT_FRAG_THRESHOLD CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 12, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_RTS_THRESHOLD
-// Query: Return the dot11RTSThreshold
-// Set : Set the dot11RTSThresold
-//
-#define IOCTL_WB_802_11_DUT_RTS_THRESHOLD CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 13, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_WEP_KEYMODE
-// Query: Get the WEP key mode.
-// Set : Set the WEP key mode: disable/64 bits/128 bits
-//
-#define IOCTL_WB_802_11_DUT_WEP_KEYMODE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 14, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_WEP_KEYVALUE
-// Query: None.
-// Set : fill in the WEP key value
-//
-#define IOCTL_WB_802_11_DUT_WEP_KEYVALUE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 15, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_RESET
-// Query: None.
-// Set : Reset S/W and H/W
-//
-#define IOCTL_WB_802_11_DUT_RESET CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 16, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_POWER_SAVE
-// Query: None.
-// Set : Set Power Save Mode
-//
-#define IOCTL_WB_802_11_DUT_POWER_SAVE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 17, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN
-// Query: None.
-// Set :
-//
-#define IOCTL_WB_802_11_DUT_BSSID_LIST_SCAN CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 18, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_BSSID_LIST
-// Query: Return the BSS info of BSSs in the last scanning process
-// Set : None.
-//
-#define IOCTL_WB_802_11_DUT_BSSID_LIST CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 19, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_STATISTICS
-// Query: Return the statistics of Tx/Rx.
-// Set : None.
-//
-#define IOCTL_WB_802_11_DUT_STATISTICS CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 20, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ACCEPT_BEACON
-// Query: Return the current mode to accept beacon or not.
-// Set : Enable or disable allowing the HW-MAC to pass the beacon to the SW-MAC
-// Arguments: unsigned char
-//
-#define IOCTL_WB_802_11_DUT_ACCEPT_BEACON CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 21, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ROAMING
-// Query: Return the roaming function status
-// Set : Enable/Disable the roaming function.
-#define IOCTL_WB_802_11_DUT_ROAMING CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 22, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_DTO
-// Query: Return the DTO(Data Throughput Optimization)
-// function status (TRUE or FALSE)
-// Set : Enable/Disable the DTO function.
-//
-#define IOCTL_WB_802_11_DUT_DTO CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 23, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY
-// Query: Return the antenna diversity status. (TRUE/ON or FALSE/OFF)
-// Set : Enable/Disable the antenna diversity.
-//
-#define IOCTL_WB_802_11_DUT_ANTENNA_DIVERSITY CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 24, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-//-------------- new added for a+b+g ---------------------
-// IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE
-// Query: Return the MAC operation mode. (MODE_802_11_BG, MODE_802_11_A,
-// MODE_802_11_ABG, MODE_802_11_BG_IBSS)
-// Set : Set the MAC operation mode.
-//
-#define IOCTL_WB_802_11_DUT_MAC_OPERATION_MODE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 25, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED
-// Query: Return the current tx rate which follows the definition in spec. (for
-// example, 5.5M => 0x0b)
-// Set : None
-//
-#define IOCTL_WB_802_11_DUT_TX_RATE_REDEFINED CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 26, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_PREAMBLE_MODE
-// Query: Return the preamble mode. (auto or long)
-// Set : Set the preamble mode.
-//
-#define IOCTL_WB_802_11_DUT_PREAMBLE_MODE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 27, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_SLOT_TIME_MODE
-// Query: Return the slot time mode. (auto or long)
-// Set : Set the slot time mode.
-//
-#define IOCTL_WB_802_11_DUT_SLOT_TIME_MODE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 28, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-//------------------------------------------------------------------
-
-// IOCTL_WB_802_11_DUT_ADVANCE_STATUS
-// Query:
-// Set : NONE
-//
-#define IOCTL_WB_802_11_DUT_ADVANCE_STATUS CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 29, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_TX_RATE_MODE
-// Query: Return the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
-// Set : Set the tx rate mode. (RATE_AUTO, RATE_1M, .., RATE_54M, RATE_MAX)
-//
-#define IOCTL_WB_802_11_DUT_TX_RATE_MODE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 30, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_DTO_PARA
-// Query: Return the DTO parameters
-// Set : Set the DTO parameters
-//
-#define IOCTL_WB_802_11_DUT_DTO_PARA CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 31, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_EVENT_LOG
-// Query: Return event log
-// Set : Reset event log
-//
-#define IOCTL_WB_802_11_DUT_EVENT_LOG CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 32, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_CWMIN
-// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
-// Set : Set CWMin value
-//
-#define IOCTL_WB_802_11_DUT_CWMIN CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 33, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_DUT_CWMAX
-// Query: NONE(It will be obtained by IOCTL_WB_802_11_DUT_ADVANCE_STATUS)
-// Set : Set CWMax value
-//
-#define IOCTL_WB_802_11_DUT_CWMAX CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_DUT_INDEX + 34, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-
-//==========================================================
-// IOCTLs for Testing
-
-// IOCTL_WB_802_11_TS_SET_CXX_REG
-// Query: None
-// Set : Write the value to one of Cxx register.
-//
-#define IOCTL_WB_802_11_TS_SET_CXX_REG CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 0, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_TS_GET_CXX_REG
-// Query: Return the value of the Cxx register.
-// Set : Write the reg no. (0x00, 0x04, 0x08 etc)
-//
-#define IOCTL_WB_802_11_TS_GET_CXX_REG CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 1, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_TS_SET_DXX_REG
-// Query: None
-// Set : Write the value to one of Dxx register.
-//
-#define IOCTL_WB_802_11_TS_SET_DXX_REG CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 2, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// IOCTL_WB_802_11_TS_GET_DXX_REG
-// Query: Return the value of the Dxx register.
-// Set : Write the reg no. (0x00, 0x04, 0x08 etc)
-//
-#define IOCTL_WB_802_11_TS_GET_DXX_REG CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 3, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-//============================================================
-// [TS]
-
-#define IOCTL_WB_802_11_TS_TX_RATE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 4, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_CURRENT_CHANNEL CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 5, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ENABLE_SEQNO CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 6, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ENALBE_ACKEDPACKET CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 7, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_INHIBIT_CRC CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 8, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_RESET_RCV_COUNTER CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 9, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_SET_TX_TRIGGER CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 10, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_FAILED_TX_COUNT CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 11, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// [TS1]
-#define IOCTL_WB_802_11_TS_TX_POWER CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 12, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_MODE_ENABLE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 13, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_MODE_DISABLE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 14, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ANTENNA CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 15, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_ADAPTER_INFO CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 16, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_MAC_ADDRESS CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 17, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_BSSID CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 18, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_RF_PARAMETER CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 19, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_FILTER CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 20, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_CALIBRATION CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 21, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_BSS_MODE CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 22, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_SET_SSID CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 23, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_IBSS_CHANNEL CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 24, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-// set/query the slot time value(short or long slot time)
-#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 25, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_SLOT_TIME CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 25, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#define IOCTL_WB_802_11_TS_RX_STATISTICS CTL_CODE( \
- FILE_DEVICE_UNKNOWN, \
- WB_IOCTL_TS_INDEX + 26, \
- METHOD_BUFFERED, \
- FILE_ANY_ACCESS)
-
-#endif // #ifndef _IOCTLS_H
-
-
diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c
index e431406e25a..c7af09257e6 100644
--- a/drivers/staging/winbond/mds.c
+++ b/drivers/staging/winbond/mds.c
@@ -1,9 +1,7 @@
-#include "ds_tkip.h"
-#include "gl_80211.h"
#include "mds_f.h"
#include "mlmetxrx_f.h"
-#include "mto_f.h"
-#include "os_common.h"
+#include "mto.h"
+#include "sysdef.h"
#include "wbhal_f.h"
#include "wblinux_f.h"
@@ -374,7 +372,7 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, PDESCRIPTOR pDes, u8 *T
pDes->TxRate = ctmp1;
#ifdef _PE_TX_DUMP_
- WBDEBUG(("Tx rate =%x\n", ctmp1));
+ printk("Tx rate =%x\n", ctmp1);
#endif
pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1;
@@ -418,14 +416,14 @@ static void Mds_HeaderCopy(struct wbsoft_priv * adapter, PDESCRIPTOR pDes, u8 *T
void
Mds_Tx(struct wbsoft_priv * adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
PMDS pMds = &adapter->Mds;
DESCRIPTOR TxDes;
PDESCRIPTOR pTxDes = &TxDes;
u8 *XmitBufAddress;
u16 XmitBufSize, PacketSize, stmp, CurrentSize, FragmentThreshold;
u8 FillIndex, TxDesIndex, FragmentCount, FillCount;
- unsigned char BufferFilled = false, MICAdd = 0;
+ unsigned char BufferFilled = false;
if (pMds->TxPause)
@@ -442,7 +440,7 @@ Mds_Tx(struct wbsoft_priv * adapter)
FillIndex = pMds->TxFillIndex;
if (pMds->TxOwner[FillIndex]) { // Is owned by software 0:Yes 1:No
#ifdef _PE_TX_DUMP_
- WBDEBUG(("[Mds_Tx] Tx Owner is H/W.\n"));
+ printk("[Mds_Tx] Tx Owner is H/W.\n");
#endif
break;
}
@@ -488,7 +486,7 @@ Mds_Tx(struct wbsoft_priv * adapter)
// For speed up Key setting
if (pTxDes->EapFix) {
#ifdef _PE_TX_DUMP_
- WBDEBUG(("35: EPA 4th frame detected. Size = %d\n", PacketSize));
+ printk("35: EPA 4th frame detected. Size = %d\n", PacketSize);
#endif
pHwData->IsKeyPreSet = 1;
}
@@ -499,12 +497,6 @@ Mds_Tx(struct wbsoft_priv * adapter)
// Set RTS/CTS and Normal duration field into buffer
Mds_DurationSet(adapter, pTxDes, XmitBufAddress);
- //
- // Calculation MIC from buffer which maybe fragment, then fill into temporary address 8 byte
- // 931130.5.e
- if (MICAdd)
- Mds_MicFill( adapter, pTxDes, XmitBufAddress );
-
//Shift to the next address
XmitBufSize += CurrentSize;
XmitBufAddress += CurrentSize;
@@ -561,7 +553,7 @@ void
Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02)
{
PMDS pMds = &adapter->Mds;
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
u8 PacketId = (u8)pT02->T02_Tx_PktID;
unsigned char SendOK = true;
u8 RetryCount, TxRate;
@@ -585,7 +577,7 @@ Mds_SendComplete(struct wbsoft_priv * adapter, PT02_DESCRIPTOR pT02)
else
pHwData->tx_retry_count[7] += RetryCount;
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count));
+ printk("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count);
#endif
MTO_SetTxCount(adapter, TxRate, RetryCount);
}
diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h
index ebf61e3ce1d..9ffec1764d6 100644
--- a/drivers/staging/winbond/mds_s.h
+++ b/drivers/staging/winbond/mds_s.h
@@ -9,6 +9,12 @@
#include "mac_structures.h"
#include "scan_s.h"
+/* Preamble_Type, see <SFS-802.11G-MIB-203> */
+enum {
+ WLAN_PREAMBLE_TYPE_SHORT,
+ WLAN_PREAMBLE_TYPE_LONG,
+};
+
////////////////////////////////////////////////////////////////////////////////////////////////////////
#define MAX_USB_TX_DESCRIPTOR 15 // IS89C35 ability
#define MAX_USB_TX_BUFFER_NUMBER 4 // Virtual pre-buffer number of MAX_USB_TX_BUFFER
@@ -17,26 +23,8 @@
#define AUTH_REQUEST_PAIRWISE_ERROR 0 // _F flag setting
#define AUTH_REQUEST_GROUP_ERROR 1 // _F flag setting
-// For variable setting
-#define CURRENT_BSS_TYPE psBSS(psLOCAL->wConnectedSTAindex)->bBssType
-#define CURRENT_WEP_MODE psSME->_dot11PrivacyInvoked
-#define CURRENT_BSSID psBSS(psLOCAL->wConnectedSTAindex)->abBssID
-#define CURRENT_DESIRED_WPA_ENABLE ((psSME->bDesiredAuthMode==WPA_AUTH)||(psSME->bDesiredAuthMode==WPAPSK_AUTH))
-#ifdef _WPA2_
-#define CURRENT_DESIRED_WPA2_ENABLE ((psSME->bDesiredAuthMode==WPA2_AUTH)||(psSME->bDesiredAuthMode==WPA2PSK_AUTH))
-#endif //end def _WPA2_
-#define CURRENT_PAIRWISE_KEY_OK psSME->pairwise_key_ok
-//[20040712 WS]
-#define CURRENT_GROUP_KEY_OK psSME->group_key_ok
-#define CURRENT_PAIRWISE_KEY psSME->tx_mic_key
-#define CURRENT_GROUP_KEY psSME->group_tx_mic_key
-#define CURRENT_ENCRYPT_STATUS psSME->encrypt_status
-#define CURRENT_WEP_ID adapter->sSmePara._dot11WEPDefaultKeyID
-#define CURRENT_CONTROL_PORT_BLOCK ( psSME->wpa_ok!=1 || (adapter->Mds.boCounterMeasureBlock==1 && (CURRENT_ENCRYPT_STATUS==ENCRYPT_TKIP)) )
#define CURRENT_FRAGMENT_THRESHOLD (adapter->Mds.TxFragmentThreshold & ~0x1)
#define CURRENT_PREAMBLE_MODE psLOCAL->boShortPreamble?WLAN_PREAMBLE_TYPE_SHORT:WLAN_PREAMBLE_TYPE_LONG
-#define CURRENT_TX_RATE adapter->sLocalPara.CurrentTxRate
-#define CURRENT_FALL_BACK_TX_RATE adapter->sLocalPara.CurrentTxFallbackRate
#define CURRENT_TX_RATE_FOR_MNG adapter->sLocalPara.CurrentTxRateForMng
#define CURRENT_PROTECT_MECHANISM psLOCAL->boProtectMechanism
#define CURRENT_RTS_THRESHOLD adapter->Mds.TxRTSThreshold
diff --git a/drivers/staging/winbond/mlme_mib.h b/drivers/staging/winbond/mlme_mib.h
deleted file mode 100644
index ca8922ec633..00000000000
--- a/drivers/staging/winbond/mlme_mib.h
+++ /dev/null
@@ -1,84 +0,0 @@
-//============================================================================
-// MLMEMIB.H -
-//
-// Description:
-// Get and Set some of MLME MIB attributes.
-//
-// Revision history:
-// --------------------------------------------------------------------------
-// 20030117 PD43 Austin Liu
-// Initial release
-//
-// Copyright (c) 2003 Winbond Electronics Corp. All rights reserved.
-//============================================================================
-
-#ifndef _MLME_MIB_H
-#define _MLME_MIB_H
-
-//============================================================================
-// MLMESetExcludeUnencrypted --
-//
-// Description:
-// Set the dot11ExcludeUnencrypted value.
-//
-// Arguments:
-// adapter - The pointer to the miniport adapter context.
-// ExUnencrypted - unsigned char type. The value to be set.
-//
-// Return values:
-// None.
-//============================================================================
-#define MLMESetExcludeUnencrypted(adapter, ExUnencrypted) \
-{ \
- (adapter)->sLocalPara.ExcludeUnencrypted = ExUnencrypted; \
-}
-
-//============================================================================
-// MLMEGetExcludeUnencrypted --
-//
-// Description:
-// Get the dot11ExcludeUnencrypted value.
-//
-// Arguments:
-// adapter - The pointer to the miniport adapter context.
-//
-// Return values:
-// unsigned char type. The current dot11ExcludeUnencrypted value.
-//============================================================================
-#define MLMEGetExcludeUnencrypted(adapter) ((unsigned char) (adapter)->sLocalPara.ExcludeUnencrypted)
-
-//============================================================================
-// MLMESetMaxReceiveLifeTime --
-//
-// Description:
-// Set the dot11MaxReceiveLifeTime value.
-//
-// Arguments:
-// adapter - The pointer to the miniport adapter context.
-// ReceiveLifeTime- u32 type. The value to be set.
-//
-// Return values:
-// None.
-//============================================================================
-#define MLMESetMaxReceiveLifeTime(adapter, ReceiveLifeTime) \
-{ \
- (adapter)->Mds.MaxReceiveTime = ReceiveLifeTime; \
-}
-
-//============================================================================
-// MLMESetMaxReceiveLifeTime --
-//
-// Description:
-// Get the dot11MaxReceiveLifeTime value.
-//
-// Arguments:
-// adapter - The pointer to the miniport adapter context.
-//
-// Return values:
-// u32 type. The current dot11MaxReceiveLifeTime value.
-//============================================================================
-#define MLMEGetMaxReceiveLifeTime(adapter) ((u32) (adapter)->Mds.MaxReceiveTime)
-
-#endif
-
-
diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c
index 07802afd2b8..643ceb060d5 100644
--- a/drivers/staging/winbond/mlmetxrx.c
+++ b/drivers/staging/winbond/mlmetxrx.c
@@ -15,7 +15,7 @@
//
// Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved.
//============================================================================
-#include "os_common.h"
+#include "sysdef.h"
#include "mds_f.h"
diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c
index de11a05efae..94a060bcc62 100644
--- a/drivers/staging/winbond/mto.c
+++ b/drivers/staging/winbond/mto.c
@@ -22,9 +22,8 @@
//============================================================================
// LA20040210_DTO kevin
-#include "os_common.h"
+#include "sysdef.h"
#include "sme_api.h"
-#include "gl_80211.h"
#include "wbhal_f.h"
// Declare SQ3 to rate and fragmentation threshold table
@@ -51,20 +50,14 @@ static int retryrate_rec[MTO_MAX_DATA_RATE_LEVELS];//this record the retry rate
static int PeriodTotalTxPkt = 0;
static int PeriodTotalTxPktRetry = 0;
-typedef struct
-{
- s32 RSSI;
- u8 TxRate;
-}RSSI2RATE;
-
static u8 boSparseTxTraffic = false;
-void MTO_Init(MTO_FUNC_INPUT);
-void TxRateReductionCtrl(MTO_FUNC_INPUT);
+void MTO_Init(struct wbsoft_priv *adapter);
+void TxRateReductionCtrl(struct wbsoft_priv *adapter);
/** 1.1.31.1000 Turbo modify */
-void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
-void MTO_TxFailed(MTO_FUNC_INPUT);
-void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+void MTO_TxFailed(struct wbsoft_priv *adapter);
+void hal_get_dto_para(struct wbsoft_priv *adapter, char *buffer);
//===========================================================================
// MTO_Init --
@@ -80,10 +73,9 @@ void hal_get_dto_para(MTO_FUNC_INPUT, char *buffer);
// Return Value:
// None
//============================================================================
-void MTO_Init(MTO_FUNC_INPUT)
+void MTO_Init(struct wbsoft_priv *adapter)
{
int i;
- //WBDEBUG(("[MTO] -> MTO_Init()\n"));
//[WKCHEN]pMTOcore_data = pcore_data;
// 20040510 Turbo add for global variable
MTO_TMR_CNT() = 0;
@@ -196,7 +188,7 @@ void MTO_Init(MTO_FUNC_INPUT)
// If we enable DTO, we will ignore the tx count with different tx rate from
// DTO rate. This is because when we adjust DTO tx rate, there could be some
// packets in the tx queue with previous tx rate
-void MTO_SetTxCount(MTO_FUNC_INPUT, u8 tx_rate, u8 index)
+void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 tx_rate, u8 index)
{
MTO_TXFLOWCOUNT()++;
if ((MTO_ENABLE==1) && (MTO_RATE_CHANGE_ENABLE()==1))
diff --git a/drivers/staging/winbond/mto.h b/drivers/staging/winbond/mto.h
index 0d3775eb257..56f2465723b 100644
--- a/drivers/staging/winbond/mto.h
+++ b/drivers/staging/winbond/mto.h
@@ -13,6 +13,8 @@
#include <linux/types.h>
+struct wbsoft_priv;
+
#define MTO_DEFAULT_TH_CNT 5
#define MTO_DEFAULT_TH_SQ3 112 //OLD IS 13 reference JohnXu
#define MTO_DEFAULT_TH_IDLE_SLOT 15
@@ -131,8 +133,6 @@ typedef struct _MTO_PARAMETERS
} MTO_PARAMETERS, *PMTO_PARAMETERS;
-#define MTO_FUNC_INPUT struct wbsoft_priv * adapter
-#define MTO_FUNC_INPUT_DATA adapter
#define MTO_DATA() (adapter->sMtoPara)
#define MTO_HAL() (&adapter->sHwData)
#define MTO_SET_PREAMBLE_TYPE(x) // 20040511 Turbo mark LM_PREAMBLE_TYPE(&pcore_data->lm_data) = (x)
@@ -140,7 +140,6 @@ typedef struct _MTO_PARAMETERS
#define MTO_TXPOWER_FROM_EEPROM (adapter->sHwData.PowerIndexFromEEPROM)
#define LOCAL_ANTENNA_NO() (adapter->sLocalPara.bAntennaNo)
#define LOCAL_IS_CONNECTED() (adapter->sLocalPara.wConnectedSTAindex != 0)
-#define LOCAL_IS_IBSS_MODE() (adapter->asBSSDescriptElement[adapter->sLocalPara.wConnectedSTAindex].bBssType == IBSS_NET)
#define MTO_INITTXRATE_MODE (adapter->sHwData.SoftwareSet&0x2) //bit 1
// 20040510 Turbo add
#define MTO_TMR_CNT() MTO_DATA().TmrCnt
@@ -259,6 +258,13 @@ typedef struct _STATISTICS_INFO {
s32 Antenna;
} STATISTICS_INFO, *PSTATISTICS_INFO;
+extern void MTO_Init(struct wbsoft_priv *);
+extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
+extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
+extern u8 MTO_GetTxRate(struct wbsoft_priv *adapter, u32 fpdu_len);
+extern u8 MTO_GetTxFallbackRate(struct wbsoft_priv *adapter);
+extern void MTO_SetTxCount(struct wbsoft_priv *adapter, u8 t0, u8 index);
+
#endif //__MTO_H__
diff --git a/drivers/staging/winbond/mto_f.h b/drivers/staging/winbond/mto_f.h
deleted file mode 100644
index 81f59137c6d..00000000000
--- a/drivers/staging/winbond/mto_f.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef __WINBOND_MTO_F_H
-#define __WINBOND_MTO_F_H
-
-#include "core.h"
-
-extern void MTO_Init(struct wbsoft_priv *);
-extern void MTO_PeriodicTimerExpired(struct wbsoft_priv *);
-extern void MTO_SetDTORateRange(struct wbsoft_priv *, u8 *, u8);
-extern u8 MTO_GetTxRate(MTO_FUNC_INPUT, u32 fpdu_len);
-extern u8 MTO_GetTxFallbackRate(MTO_FUNC_INPUT);
-extern void MTO_SetTxCount(MTO_FUNC_INPUT, u8 t0, u8 index);
-
-#endif
diff --git a/drivers/staging/winbond/os_common.h b/drivers/staging/winbond/os_common.h
deleted file mode 100644
index 2c276e3ab51..00000000000
--- a/drivers/staging/winbond/os_common.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "sysdef.h"
-
diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c
index 6782552d366..af8c01e313b 100644
--- a/drivers/staging/winbond/phy_calibration.c
+++ b/drivers/staging/winbond/phy_calibration.c
@@ -10,7 +10,7 @@
*/
/****************** INCLUDE FILES SECTION ***********************************/
-#include "os_common.h"
+#include "sysdef.h"
#include "phy_calibration.h"
#include "wbhal_f.h"
@@ -37,8 +37,8 @@ static const fixed Angles[]=
};
/****************** LOCAL FUNCTION DECLARATION SECTION **********************/
-//void _phy_rf_write_delay(hw_data_t *phw_data);
-//void phy_init_rf(hw_data_t *phw_data);
+//void _phy_rf_write_delay(struct hw_data *phw_data);
+//void phy_init_rf(struct hw_data *phw_data);
/****************** FUNCTION DEFINITION SECTION *****************************/
@@ -341,7 +341,7 @@ void _sin_cos(s32 angle, s32 *sin, s32 *cos)
}
-void _reset_rx_cal(hw_data_t *phw_data)
+void _reset_rx_cal(struct hw_data *phw_data)
{
u32 val;
@@ -366,7 +366,7 @@ void _reset_rx_cal(hw_data_t *phw_data)
//
//
// *********************************************
-void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
+void _rxadc_dc_offset_cancellation_winbond(struct hw_data *phw_data, u32 frequency)
{
u32 reg_agc_ctrl3;
u32 reg_a_acq_ctrl;
@@ -465,7 +465,7 @@ void _rxadc_dc_offset_cancellation_winbond(hw_data_t *phw_data, u32 frequency)
}
////////////////////////////////////////////////////////
-void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
+void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data)
{
u32 reg_agc_ctrl3;
u32 reg_mode_ctrl;
@@ -600,7 +600,7 @@ void _txidac_dc_offset_cancellation_winbond(hw_data_t *phw_data)
}
///////////////////////////////////////////////////////
-void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
+void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data)
{
u32 reg_agc_ctrl3;
u32 reg_mode_ctrl;
@@ -726,7 +726,7 @@ void _txqdac_dc_offset_cacellation_winbond(hw_data_t *phw_data)
}
//20060612.1.a 20060718.1 Modify
-u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
+u8 _tx_iq_calibration_loop_winbond(struct hw_data *phw_data,
s32 a_2_threshold,
s32 b_2_threshold)
{
@@ -1032,7 +1032,7 @@ u8 _tx_iq_calibration_loop_winbond(hw_data_t *phw_data,
return 1;
}
-void _tx_iq_calibration_winbond(hw_data_t *phw_data)
+void _tx_iq_calibration_winbond(struct hw_data *phw_data)
{
u32 reg_agc_ctrl3;
#ifdef _DEBUG
@@ -1195,7 +1195,7 @@ void _tx_iq_calibration_winbond(hw_data_t *phw_data)
}
/////////////////////////////////////////////////////////////////////////////////////////
-u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequency)
+u8 _rx_iq_calibration_loop_winbond(struct hw_data *phw_data, u16 factor, u32 frequency)
{
u32 reg_mode_ctrl;
s32 iqcal_tone_i;
@@ -1501,7 +1501,7 @@ u8 _rx_iq_calibration_loop_winbond(hw_data_t *phw_data, u16 factor, u32 frequenc
//////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
-void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+void _rx_iq_calibration_winbond(struct hw_data *phw_data, u32 frequency)
{
// figo 20050523 marked thsi flag for can't compile for relesase
#ifdef _DEBUG
@@ -1579,7 +1579,7 @@ void _rx_iq_calibration_winbond(hw_data_t *phw_data, u32 frequency)
}
////////////////////////////////////////////////////////////////////////
-void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
+void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency)
{
u32 reg_mode_ctrl;
u32 iq_alpha;
@@ -1618,7 +1618,7 @@ void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency)
}
//===========================
-void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value )
+void phy_set_rf_data( struct hw_data * pHwData, u32 index, u32 value )
{
u32 ltmp=0;
@@ -1660,7 +1660,7 @@ void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value )
}
// 20060717 modify as Bruce's mail
-unsigned char adjust_TXVGA_for_iq_mag(hw_data_t *phw_data)
+unsigned char adjust_TXVGA_for_iq_mag(struct hw_data *phw_data)
{
int init_txvga = 0;
u32 reg_mode_ctrl;
diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h
index 03b820c6181..51c8fde81e2 100644
--- a/drivers/staging/winbond/phy_calibration.h
+++ b/drivers/staging/winbond/phy_calibration.h
@@ -101,7 +101,7 @@
//#define MASK_IQCAL_IMAGE_Q 0x03FFE000
//#define SHIFT_IQCAL_IMAGE_Q(x) ((x)>>13)
-void phy_set_rf_data( phw_data_t pHwData, u32 index, u32 value );
+void phy_set_rf_data( struct hw_data * pHwData, u32 index, u32 value );
#define phy_init_rf( _A ) //RFSynthesizer_initial( _A )
#endif
diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c
index cd21272d7a9..d915cbdd38e 100644
--- a/drivers/staging/winbond/reg.c
+++ b/drivers/staging/winbond/reg.c
@@ -1,4 +1,4 @@
-#include "os_common.h"
+#include "sysdef.h"
#include "wbhal_f.h"
///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -915,7 +915,7 @@ u32 w89rf242_txvga_data[][5] =
// The address is stored in EthernetIDAddr.
//=============================================================================================================
void
-Uxx_ReadEthernetAddress( phw_data_t pHwData )
+Uxx_ReadEthernetAddress( struct hw_data * pHwData )
{
u32 ltmp;
@@ -948,14 +948,13 @@ Uxx_ReadEthernetAddress( phw_data_t pHwData )
// Return Value:
// None.
//==============================================================================================================
-void CardGetMulticastBit( u8 Address[ETH_LENGTH_OF_ADDRESS],
- u8 *Byte, u8 *Value )
+void CardGetMulticastBit( u8 Address[ETH_ALEN], u8 *Byte, u8 *Value )
{
u32 Crc;
u32 BitNumber;
// First compute the CRC.
- Crc = CardComputeCrc(Address, ETH_LENGTH_OF_ADDRESS);
+ Crc = CardComputeCrc(Address, ETH_ALEN);
// The computed CRC is bit0~31 from left to right
//At first we should do right shift 25bits, and read 7bits by using '&', 2^7=128
@@ -965,7 +964,7 @@ void CardGetMulticastBit( u8 Address[ETH_LENGTH_OF_ADDRESS],
*Value = (u8) ((u8)1 << (BitNumber % 8));
}
-void Uxx_power_on_procedure( phw_data_t pHwData )
+void Uxx_power_on_procedure( struct hw_data * pHwData )
{
u32 ltmp, loop;
@@ -1009,7 +1008,7 @@ void Uxx_power_on_procedure( phw_data_t pHwData )
Wb35Reg_WriteSync( pHwData, 0x03f8, 0x7ff );
}
-void Set_ChanIndep_RfData_al7230_24( phw_data_t pHwData, u32 *pltmp ,char number)
+void Set_ChanIndep_RfData_al7230_24( struct hw_data * pHwData, u32 *pltmp ,char number)
{
u8 i;
@@ -1020,7 +1019,7 @@ void Set_ChanIndep_RfData_al7230_24( phw_data_t pHwData, u32 *pltmp ,char numbe
}
}
-void Set_ChanIndep_RfData_al7230_50( phw_data_t pHwData, u32 *pltmp, char number)
+void Set_ChanIndep_RfData_al7230_50( struct hw_data * pHwData, u32 *pltmp, char number)
{
u8 i;
@@ -1036,7 +1035,7 @@ void Set_ChanIndep_RfData_al7230_50( phw_data_t pHwData, u32 *pltmp, char numbe
// RFSynthesizer_initial --
//=============================================================================================================
void
-RFSynthesizer_initial(phw_data_t pHwData)
+RFSynthesizer_initial(struct hw_data * pHwData)
{
u32 altmp[32];
u32 * pltmp = altmp;
@@ -1115,7 +1114,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
//Start to fill RF parameters, PLL_ON should be pulled low.
Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("* PLL_ON low\n"));
+ printk("* PLL_ON low\n");
#endif
number = sizeof(al7230_rf_data_24)/sizeof(al7230_rf_data_24[0]);
@@ -1224,7 +1223,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
//pulled high
Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("* PLL_ON high\n"));
+ printk("* PLL_ON high\n");
#endif
//2.4GHz
@@ -1244,7 +1243,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
//5GHz
Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000000 );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("* PLL_ON low\n"));
+ printk("* PLL_ON low\n");
#endif
number = sizeof(al7230_rf_data_50)/sizeof(al7230_rf_data_50[0]);
@@ -1256,7 +1255,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("* PLL_ON high\n"));
+ printk("* PLL_ON high\n");
#endif
//ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x12BACF;
@@ -1272,7 +1271,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
msleep(5);
//Wb35Reg_WriteSync( pHwData, 0x03dc, 0x00000080 );
- //WBDEBUG(("* PLL_ON high\n"));
+ //printk("* PLL_ON high\n");
break;
case RF_WB_242:
@@ -1414,7 +1413,7 @@ RFSynthesizer_initial(phw_data_t pHwData)
}
}
-void BBProcessor_AL7230_2400( phw_data_t pHwData)
+void BBProcessor_AL7230_2400( struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
u32 pltmp[12];
@@ -1456,7 +1455,7 @@ void BBProcessor_AL7230_2400( phw_data_t pHwData)
}
-void BBProcessor_AL7230_5000( phw_data_t pHwData)
+void BBProcessor_AL7230_5000( struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
u32 pltmp[12];
@@ -1510,7 +1509,7 @@ void BBProcessor_AL7230_5000( phw_data_t pHwData)
// None.
//=============================================================================================================
void
-BBProcessor_initial( phw_data_t pHwData )
+BBProcessor_initial( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
u32 i, pltmp[12];
@@ -1824,12 +1823,12 @@ BBProcessor_initial( phw_data_t pHwData )
reg->SQ3_filter[i] = 0x2f; // half of Bit 0 ~ 6
}
-void set_tx_power_per_channel_max2829( phw_data_t pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_max2829( struct hw_data * pHwData, ChanInfo Channel)
{
RFSynthesizer_SetPowerIndex( pHwData, 100 ); // 20060620.1 Modify
}
-void set_tx_power_per_channel_al2230( phw_data_t pHwData, ChanInfo Channel )
+void set_tx_power_per_channel_al2230( struct hw_data * pHwData, ChanInfo Channel )
{
u8 index = 100;
@@ -1839,7 +1838,7 @@ void set_tx_power_per_channel_al2230( phw_data_t pHwData, ChanInfo Channel )
RFSynthesizer_SetPowerIndex( pHwData, index );
}
-void set_tx_power_per_channel_al7230( phw_data_t pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_al7230( struct hw_data * pHwData, ChanInfo Channel)
{
u8 i, index = 100;
@@ -1869,7 +1868,7 @@ void set_tx_power_per_channel_al7230( phw_data_t pHwData, ChanInfo Channel)
RFSynthesizer_SetPowerIndex( pHwData, index );
}
-void set_tx_power_per_channel_wb242( phw_data_t pHwData, ChanInfo Channel)
+void set_tx_power_per_channel_wb242( struct hw_data * pHwData, ChanInfo Channel)
{
u8 index = 100;
@@ -1902,7 +1901,7 @@ void set_tx_power_per_channel_wb242( phw_data_t pHwData, ChanInfo Channel)
// None.
//=============================================================================================================
void
-RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
+RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel )
{
struct wb35_reg *reg = &pHwData->reg;
u32 pltmp[16]; // The 16 is the maximum capability of hardware
@@ -2012,7 +2011,7 @@ RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
//Start to fill RF parameters, PLL_ON should be pulled low.
//Wb35Reg_Write( pHwData, 0x03dc, 0x00000000 );
- //WBDEBUG(("* PLL_ON low\n"));
+ //printk("* PLL_ON low\n");
//Channel independent registers
if( Channel.band != pHwData->band)
@@ -2037,7 +2036,7 @@ RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
// Write to register. number must less and equal than 16
Wb35Reg_BurstWrite( pHwData, 0x0864, pltmp, number, NO_INCREMENT );
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("Band changed\n"));
+ printk("Band changed\n");
#endif
}
@@ -2130,7 +2129,7 @@ RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel )
}
//Set the tx power directly from DUT GUI, not from the EEPROM. Return the current setting
-u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex )
+u8 RFSynthesizer_SetPowerIndex( struct hw_data * pHwData, u8 PowerIndex )
{
u32 Band = pHwData->band;
u8 index=0;
@@ -2188,7 +2187,7 @@ u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex )
}
//-- Sub function
-u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2828_24Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2197,7 +2196,7 @@ u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2828_50Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2206,7 +2205,7 @@ u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2827_24Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2215,7 +2214,7 @@ u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2827_50Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2224,7 +2223,7 @@ u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetMaxim2825Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetMaxim2825Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
if( index > 1 ) index = 1;
@@ -2233,7 +2232,7 @@ u8 RFSynthesizer_SetMaxim2825Power( phw_data_t pHwData, u8 index )
return index;
}
//--
-u8 RFSynthesizer_SetAiroha2230Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetAiroha2230Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
u8 i,count;
@@ -2252,7 +2251,7 @@ u8 RFSynthesizer_SetAiroha2230Power( phw_data_t pHwData, u8 index )
return i;
}
//--
-u8 RFSynthesizer_SetAiroha7230Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetAiroha7230Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
u8 i,count;
@@ -2271,7 +2270,7 @@ u8 RFSynthesizer_SetAiroha7230Power( phw_data_t pHwData, u8 index )
return i;
}
-u8 RFSynthesizer_SetWinbond242Power( phw_data_t pHwData, u8 index )
+u8 RFSynthesizer_SetWinbond242Power( struct hw_data * pHwData, u8 index )
{
u32 PowerData;
u8 i,count;
@@ -2312,7 +2311,7 @@ u8 RFSynthesizer_SetWinbond242Power( phw_data_t pHwData, u8 index )
// Initial the hardware setting and module variable
//
//===========================================================================================================
-void Dxx_initial( phw_data_t pHwData )
+void Dxx_initial( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -2326,7 +2325,7 @@ void Dxx_initial( phw_data_t pHwData )
Wb35Reg_WriteSync( pHwData, 0x0400, reg->D00_DmaControl );
}
-void Mxx_initial( phw_data_t pHwData )
+void Mxx_initial( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
u32 tmp;
@@ -2417,7 +2416,7 @@ void Mxx_initial( phw_data_t pHwData )
}
-void Uxx_power_off_procedure( phw_data_t pHwData )
+void Uxx_power_off_procedure( struct hw_data * pHwData )
{
// SW, PMU reset and turn off clock
Wb35Reg_WriteSync( pHwData, 0x03b0, 3 );
@@ -2425,7 +2424,7 @@ void Uxx_power_off_procedure( phw_data_t pHwData )
}
//Decide the TxVga of every channel
-void GetTxVgaFromEEPROM( phw_data_t pHwData )
+void GetTxVgaFromEEPROM( struct hw_data * pHwData )
{
u32 i, j, ltmp;
u16 Value[MAX_TXVGA_EEPROM];
@@ -2479,7 +2478,7 @@ void GetTxVgaFromEEPROM( phw_data_t pHwData )
// or RFSynthesizer_SetPowerIndex be called, new TxVga will take effect.
// TxVgaSettingInEEPROM of sHwData is an u8 array point to EEPROM contain for IS89C35
// This function will use default TxVgaSettingInEEPROM data to calculate new TxVga.
-void EEPROMTxVgaAdjust( phw_data_t pHwData ) // 20060619.5 Add
+void EEPROMTxVgaAdjust( struct hw_data * pHwData ) // 20060619.5 Add
{
u8 * pTxVga = pHwData->TxVgaSettingInEEPROM;
s16 i, stmp;
@@ -2612,14 +2611,14 @@ void EEPROMTxVgaAdjust( phw_data_t pHwData ) // 20060619.5 Add
}
#ifdef _PE_STATE_DUMP_
- WBDEBUG((" TxVgaFor24 : \n"));
+ printk(" TxVgaFor24 : \n");
DataDmp((u8 *)pHwData->TxVgaFor24, 14 ,0);
- WBDEBUG((" TxVgaFor50 : \n"));
+ printk(" TxVgaFor50 : \n");
DataDmp((u8 *)pHwData->TxVgaFor50, 70 ,0);
#endif
}
-void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ) // 20060613.1
+void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ) // 20060613.1
{
struct wb35_reg *reg = &pHwData->reg;
unsigned char Is11bRate;
diff --git a/drivers/staging/winbond/sme_api.h b/drivers/staging/winbond/sme_api.h
index 188a2532bbf..54987830228 100644
--- a/drivers/staging/winbond/sme_api.h
+++ b/drivers/staging/winbond/sme_api.h
@@ -17,9 +17,6 @@
#include "localpara.h"
-/****************** INCLUDE FILES SECTION ***********************************/
-//#include "GL\gl_core.h"
-
/****************** CONSTANT AND MACRO SECTION ******************************/
#define _INLINE __inline
diff --git a/drivers/staging/winbond/sme_s.h b/drivers/staging/winbond/sme_s.h
deleted file mode 100644
index 1bd118f83d2..00000000000
--- a/drivers/staging/winbond/sme_s.h
+++ /dev/null
@@ -1,236 +0,0 @@
-#ifndef __WINBOND_SME_S_H
-#define __WINBOND_SME_S_H
-
-#include <linux/types.h>
-
-#include "mac_structures.h"
-#include "localpara.h"
-
-//
-// SME_S.H -
-// SME task global CONSTANTS, STRUCTURES, variables
-//
-
-//////////////////////////////////////////////////////////////////////////
-//define the msg type of SME module
-// 0x00~0x1F : MSG from GUI dispatch
-// 0x20~0x3F : MSG from MLME
-// 0x40~0x5F : MSG from SCAN
-// 0x60~0x6F : MSG from TX/RX
-// 0x70~0x7F : MSG from ROAMING
-// 0x80~0x8F : MSG from ISR
-// 0x90 : MSG TimeOut
-
-// from GUI
-#define SMEMSG_SCAN_REQ 0x01
-//#define SMEMSG_PASSIVE_SCAN_REQ 0x02
-#define SMEMSG_JOIN_REQ 0x03
-#define SMEMSG_START_IBSS 0x04
-#define SMEMSG_DISCONNECT_REQ 0x05
-#define SMEMSG_AUTHEN_REQ 0x06
-#define SMEMSG_DEAUTHEN_REQ 0x07
-#define SMEMSG_ASSOC_REQ 0x08
-#define SMEMSG_REASSOC_REQ 0x09
-#define SMEMSG_DISASSOC_REQ 0x0a
-#define SMEMSG_POWERSAVE_REQ 0x0b
-
-
-// from MLME
-#define SMEMSG_AUTHEN_CFM 0x21
-#define SMEMSG_AUTHEN_IND 0x22
-#define SMEMSG_ASSOC_CFM 0x23
-#define SMEMSG_DEAUTHEN_IND 0x24
-#define SMEMSG_DISASSOC_IND 0x25
-// from SCAN
-#define SMEMSG_SCAN_CFM 0x41
-#define SMEMSG_START_IBSS_CFM 0x42
-// from MTO, function call to set SME parameters
-
-// 0x60~0x6F : MSG from TX/RX
-//#define SMEMSG_IBSS_JOIN_UPDATE_BSSID 0x61
-#define SMEMSG_COUNTERMEASURE_MICFAIL_TIMEOUT 0x62
-#define SMEMSG_COUNTERMEASURE_BLOCK_TIMEOUT 0x63
-// from ROAMING
-#define SMEMSG_HANDOVER_JOIN_REQ 0x71
-#define SMEMSG_END_ROAMING 0x72
-#define SMEMSG_SCAN_JOIN_REQ 0x73
-// from ISR
-#define SMEMSG_TSF_SYNC_IND 0x81
-// from TimeOut
-#define SMEMSG_TIMEOUT 0x91
-
-
-
-#define MAX_PMKID_Accunt 16
-//@added by ws 04/22/05
-#define Cipher_Disabled 0
-#define Cipher_Wep 1
-#define Cipher_Tkip 2
-#define Cipher_Ccmp 4
-
-
-///////////////////////////////////////////////////////////////////////////
-//Constants
-
-///////////////////////////////////////////////////////////////////////////
-//Global data structures
-
-#define NUMOFWEPENTRIES 64
-
-typedef enum _WEPKeyMode
-{
- WEPKEY_DISABLED = 0,
- WEPKEY_64 = 1,
- WEPKEY_128 = 2
-
-} WEPKEYMODE, *pWEPKEYMODE;
-
-#ifdef _WPA2_
-
-typedef struct _BSSInfo
-{
- u8 PreAuthBssID[6];
- PMKID pmkid_value;
-}BSSID_Info;
-
-typedef struct _PMKID_Table //added by ws 05/05/04
-{
- u32 Length;
- u32 BSSIDInfoCount;
- BSSID_Info BSSIDInfo[16];
-
-} PMKID_Table;
-
-#endif //end def _WPA2_
-
-#define MAX_BASIC_RATE_SET 15
-#define MAX_OPT_RATE_SET MAX_BASIC_RATE_SET
-
-
-typedef struct _SME_PARAMETERS
-{
- u16 wState;
- u8 boDUTmode;
- u8 bDesiredPowerSave;
-
- // SME timer and timeout value
- struct timer_list timer;
-
- u8 boInTimerHandler;
- u8 boAuthRetryActive;
- u8 reserved_0[2];
-
- u32 AuthenRetryTimerVal; // NOTE: Assoc don't fail timeout
- u32 JoinFailTimerVal; // 10*Beacon-Interval
-
- //Rates
- u8 BSSBasicRateSet[(MAX_BASIC_RATE_SET + 3) & ~0x03 ]; // BSS basic rate set
- u8 OperationalRateSet[(MAX_OPT_RATE_SET + 3) & ~0x03 ]; // Operational rate set
-
- u8 NumOfBSSBasicRate;
- u8 NumOfOperationalRate;
- u8 reserved_1[2];
-
- u32 BasicRateBitmap;
- u32 OpRateBitmap;
-
- // System parameters Set by GUI
- //-------------------- start IBSS parameter ---------------------------//
- u32 boStartIBSS; //Start IBSS toggle
-
- u16 wBeaconPeriod;
- u16 wATIM_Window;
-
- ChanInfo IbssChan; // 2B //channel setting when start IBSS
- u8 reserved_2[2];
-
- // Join related
- u16 wDesiredJoinBSS; // BSS index which desire to join
- u8 boJoinReq; //Join request toggle
- u8 bDesiredBSSType; //for Join request
-
- u16 wCapabilityInfo; // Used when invoking the MLME_Associate_request().
- u16 wNonERPcapabilityInfo;
-
- struct SSID_Element sDesiredSSID; // 34 B
- u8 reserved_3[2];
-
- u8 abDesiredBSSID[MAC_ADDR_LENGTH + 2];
-
- u8 bJoinScanCount; // the time of scan-join action need to do
- u8 bDesiredAuthMode; // AUTH_OPEN_SYSTEM or AUTH_SHARED_KEY
- u8 reserved_4[2];
-
- // Encryption parameters
- u8 _dot11PrivacyInvoked;
- u8 _dot11PrivacyOptionImplemented;
- u8 reserved_5[2];
-
- //@ ws added
- u8 DesiredEncrypt;
- u8 encrypt_status; //ENCRYPT_DISABLE, ENCRYPT_WEP, ENCRYPT_WEP_NOKEY, ENCRYPT_TKIP, ...
- u8 key_length;
- u8 pairwise_key_ok;
-
- u8 group_key_ok;
- u8 wpa_ok; // indicate the control port of 802.1x is open or close
- u8 pairwise_key_type;
- u8 group_key_type;
-
- u32 _dot11WEPDefaultKeyID;
-
- u8 tx_mic_key[8]; // TODO: 0627 kevin-TKIP
- u8 rx_mic_key[8]; // TODO: 0627 kevin-TKIP
- u8 group_tx_mic_key[8];
- u8 group_rx_mic_key[8];
-
-// #ifdef _WPA_
- u8 AssocReqVarIE[200];
- u8 AssocRespVarIE[200];
-
- u16 AssocReqVarLen;
- u16 AssocRespVarLen;
- u8 boReassoc; //use assoc. or reassoc.
- u8 reserved_6[3];
- u16 AssocRespCapability;
- u16 AssocRespStatus;
-// #endif
-
- #ifdef _WPA2_
- u8 PmkIdTable[256];
- u32 PmkidTableIndex;
- #endif //end def _WPA2_
-
-} SME_PARAMETERS, *PSME_PARAMETERS;
-
-#define psSME (&(adapter->sSmePara))
-
-#define wSMEGetCurrentSTAState(adapter) ((u16)(adapter)->sSmePara.wState)
-
-
-
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-// SmeModule.h
-// Define the related definitions of SME module
-// history -- 01/14/03' created
-//
-//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-//Define the state of SME module
-#define DISABLED 0
-#define INIT_SCAN 1
-#define SCAN_READY 2
-#define START_IBSS 3
-#define JOIN_PENDING 4
-#define JOIN_CFM 5
-#define AUTHENTICATE_PENDING 6
-#define AUTHENTICATED 7
-#define CONNECTED 8
-//#define EAP_STARTING 9
-//#define EAPOL_AUTHEN_PENDING 10
-//#define SECURE_CONNECTED 11
-
-
-// Static function
-
-#endif
diff --git a/drivers/staging/winbond/wb35_ver.h b/drivers/staging/winbond/wb35_ver.h
deleted file mode 100644
index 2433bc07300..00000000000
--- a/drivers/staging/winbond/wb35_ver.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Only define one of follow
-//
-
-#ifdef WB_WIN
- #define VER_FILEVERSION 1,00,47,00
- #define VER_FILEVERSION_STR "1.00.47.00"
- #define WB32_DRIVER_MAJOR_VERSION 0x0100
- #define WB32_DRIVER_MINOR_VERSION 0x4700
-#endif
-
-#ifdef WB_CE
- #define VER_FILEVERSION 2,00,47,00
- #define VER_FILEVERSION_STR "2.00.47.00"
- #define WB32_DRIVER_MAJOR_VERSION 0x0200
- #define WB32_DRIVER_MINOR_VERSION 0x4700
-#endif
-
-#ifdef WB_LINUX
- #define VER_FILEVERSION 3,00,47,00
- #define VER_FILEVERSION_STR "3.00.47.00"
- #define WB32_DRIVER_MAJOR_VERSION 0x0300
- #define WB32_DRIVER_MINOR_VERSION 0x4700
-#endif
-
-
-
-
-
-
diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c
index c74b3fdcbda..f5608ad9ed0 100644
--- a/drivers/staging/winbond/wb35reg.c
+++ b/drivers/staging/winbond/wb35reg.c
@@ -3,7 +3,7 @@
#include <linux/usb.h>
-extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
+extern void phy_calibration_winbond(struct hw_data *phw_data, u32 frequency);
// true : read command process successfully
// false : register not support
@@ -13,7 +13,7 @@ extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
// Flag : AUTO_INCREMENT - RegisterNo will auto increment 4
// NO_INCREMENT - Function will write data into the same register
unsigned char
-Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
+Wb35Reg_BurstWrite(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
{
struct wb35_reg *reg = &pHwData->reg;
struct urb *urb = NULL;
@@ -73,7 +73,7 @@ Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 N
}
void
-Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue)
+Wb35Reg_Update(struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue)
{
struct wb35_reg *reg = &pHwData->reg;
switch (RegisterNo) {
@@ -118,7 +118,7 @@ Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue)
// true : read command process successfully
// false : register not support
unsigned char
-Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
+Wb35Reg_WriteSync( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
int ret = -1;
@@ -149,7 +149,7 @@ Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
if (ret < 0) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 Write register usb message sending error\n"));
+ printk("EP0 Write register usb message sending error\n");
#endif
pHwData->SurpriseRemove = 1; // 20060704.2
@@ -162,7 +162,7 @@ Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
// true : read command process successfully
// false : register not support
unsigned char
-Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
+Wb35Reg_Write( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
struct usb_ctrlrequest *dr;
@@ -222,7 +222,7 @@ Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
// true : read command process successfully
// false : register not support
unsigned char
-Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue,
+Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue,
s8 *pValue, s8 Len)
{
struct wb35_reg *reg = &pHwData->reg;
@@ -281,7 +281,7 @@ Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 Register
// false : register not support
// pRegisterValue : It must be a resident buffer due to asynchronous read register.
unsigned char
-Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
+Wb35Reg_ReadSync( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
u32 * pltmp = pRegisterValue;
@@ -316,7 +316,7 @@ Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
if (ret < 0) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 Read register usb message sending error\n"));
+ printk("EP0 Read register usb message sending error\n");
#endif
pHwData->SurpriseRemove = 1; // 20060704.2
@@ -330,7 +330,7 @@ Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
// false : register not support
// pRegisterValue : It must be a resident buffer due to asynchronous read register.
unsigned char
-Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
+Wb35Reg_Read(struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue )
{
struct wb35_reg *reg = &pHwData->reg;
struct usb_ctrlrequest * dr;
@@ -385,7 +385,7 @@ Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
void
-Wb35Reg_EP0VM_start( phw_data_t pHwData )
+Wb35Reg_EP0VM_start( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -397,7 +397,7 @@ Wb35Reg_EP0VM_start( phw_data_t pHwData )
}
void
-Wb35Reg_EP0VM(phw_data_t pHwData )
+Wb35Reg_EP0VM(struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
struct urb *urb;
@@ -441,7 +441,7 @@ Wb35Reg_EP0VM(phw_data_t pHwData )
if (ret < 0) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 Irp sending error\n"));
+ printk("EP0 Irp sending error\n");
#endif
goto cleanup;
}
@@ -457,7 +457,7 @@ Wb35Reg_EP0VM(phw_data_t pHwData )
void
Wb35Reg_EP0VM_complete(struct urb *urb)
{
- phw_data_t pHwData = (phw_data_t)urb->context;
+ struct hw_data * pHwData = (struct hw_data *)urb->context;
struct wb35_reg *reg = &pHwData->reg;
struct wb35_reg_queue *reg_queue;
@@ -480,8 +480,7 @@ Wb35Reg_EP0VM_complete(struct urb *urb)
if (reg->EP0VM_status) {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 IoCompleteRoutine return error\n"));
- DebugUsbdStatusInformation( reg->EP0VM_status );
+ printk("EP0 IoCompleteRoutine return error\n");
#endif
reg->EP0vm_state = VM_STOP;
pHwData->SurpriseRemove = 1;
@@ -500,7 +499,7 @@ Wb35Reg_EP0VM_complete(struct urb *urb)
void
-Wb35Reg_destroy(phw_data_t pHwData)
+Wb35Reg_destroy(struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
struct urb *urb;
@@ -530,7 +529,7 @@ Wb35Reg_destroy(phw_data_t pHwData)
kfree(reg_queue);
} else {
#ifdef _PE_REG_DUMP_
- WBDEBUG(("EP0 queue release error\n"));
+ printk("EP0 queue release error\n");
#endif
}
spin_lock_irq( &reg->EP0VM_spin_lock );
@@ -543,7 +542,7 @@ Wb35Reg_destroy(phw_data_t pHwData)
//====================================================================================
// The function can be run in passive-level only.
//====================================================================================
-unsigned char Wb35Reg_initial(phw_data_t pHwData)
+unsigned char Wb35Reg_initial(struct hw_data * pHwData)
{
struct wb35_reg *reg=&pHwData->reg;
u32 ltmp;
@@ -599,7 +598,7 @@ unsigned char Wb35Reg_initial(phw_data_t pHwData)
Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval );
// Update Ethernet address
- memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_LENGTH_OF_ADDRESS );
+ memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_ALEN );
// Update software variable
pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff);
@@ -723,7 +722,7 @@ u32 BitReverse( u32 dwData, u32 DataLength)
return dwData;
}
-void Wb35Reg_phy_calibration( phw_data_t pHwData )
+void Wb35Reg_phy_calibration( struct hw_data * pHwData )
{
u32 BB3c, BB54;
diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h
index d97215a1eba..30f5b5ad63a 100644
--- a/drivers/staging/winbond/wb35reg_f.h
+++ b/drivers/staging/winbond/wb35reg_f.h
@@ -6,47 +6,47 @@
//====================================
// Interface function declare
//====================================
-unsigned char Wb35Reg_initial( phw_data_t pHwData );
-void Uxx_power_on_procedure( phw_data_t pHwData );
-void Uxx_power_off_procedure( phw_data_t pHwData );
-void Uxx_ReadEthernetAddress( phw_data_t pHwData );
-void Dxx_initial( phw_data_t pHwData );
-void Mxx_initial( phw_data_t pHwData );
-void RFSynthesizer_initial( phw_data_t pHwData );
-//void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, s8 Channel );
-void RFSynthesizer_SwitchingChannel( phw_data_t pHwData, ChanInfo Channel );
-void BBProcessor_initial( phw_data_t pHwData );
-void BBProcessor_RateChanging( phw_data_t pHwData, u8 rate ); // 20060613.1
-//void RF_RateChanging( phw_data_t pHwData, u8 rate ); // 20060626.5.c Add
-u8 RFSynthesizer_SetPowerIndex( phw_data_t pHwData, u8 PowerIndex );
-u8 RFSynthesizer_SetMaxim2828_24Power( phw_data_t, u8 index );
-u8 RFSynthesizer_SetMaxim2828_50Power( phw_data_t, u8 index );
-u8 RFSynthesizer_SetMaxim2827_24Power( phw_data_t, u8 index );
-u8 RFSynthesizer_SetMaxim2827_50Power( phw_data_t, u8 index );
-u8 RFSynthesizer_SetMaxim2825Power( phw_data_t, u8 index );
-u8 RFSynthesizer_SetAiroha2230Power( phw_data_t, u8 index );
-u8 RFSynthesizer_SetAiroha7230Power( phw_data_t, u8 index );
-u8 RFSynthesizer_SetWinbond242Power( phw_data_t, u8 index );
-void GetTxVgaFromEEPROM( phw_data_t pHwData );
-void EEPROMTxVgaAdjust( phw_data_t pHwData ); // 20060619.5 Add
+unsigned char Wb35Reg_initial( struct hw_data * pHwData );
+void Uxx_power_on_procedure( struct hw_data * pHwData );
+void Uxx_power_off_procedure( struct hw_data * pHwData );
+void Uxx_ReadEthernetAddress( struct hw_data * pHwData );
+void Dxx_initial( struct hw_data * pHwData );
+void Mxx_initial( struct hw_data * pHwData );
+void RFSynthesizer_initial( struct hw_data * pHwData );
+//void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, s8 Channel );
+void RFSynthesizer_SwitchingChannel( struct hw_data * pHwData, ChanInfo Channel );
+void BBProcessor_initial( struct hw_data * pHwData );
+void BBProcessor_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060613.1
+//void RF_RateChanging( struct hw_data * pHwData, u8 rate ); // 20060626.5.c Add
+u8 RFSynthesizer_SetPowerIndex( struct hw_data * pHwData, u8 PowerIndex );
+u8 RFSynthesizer_SetMaxim2828_24Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2828_50Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2827_24Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2827_50Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetMaxim2825Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetAiroha2230Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetAiroha7230Power( struct hw_data *, u8 index );
+u8 RFSynthesizer_SetWinbond242Power( struct hw_data *, u8 index );
+void GetTxVgaFromEEPROM( struct hw_data * pHwData );
+void EEPROMTxVgaAdjust( struct hw_data * pHwData ); // 20060619.5 Add
#define RFWriteControlData( _A, _V ) Wb35Reg_Write( _A, 0x0864, _V )
-void Wb35Reg_destroy( phw_data_t pHwData );
+void Wb35Reg_destroy( struct hw_data * pHwData );
-unsigned char Wb35Reg_Read( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue );
-unsigned char Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue );
-unsigned char Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
-unsigned char Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
-unsigned char Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData,
+unsigned char Wb35Reg_Read( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue );
+unsigned char Wb35Reg_ReadSync( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterValue );
+unsigned char Wb35Reg_Write( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char Wb35Reg_WriteSync( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char Wb35Reg_WriteWithCallbackValue( struct hw_data * pHwData,
u16 RegisterNo,
u32 RegisterValue,
s8 *pValue,
s8 Len);
-unsigned char Wb35Reg_BurstWrite( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag );
+unsigned char Wb35Reg_BurstWrite( struct hw_data * pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag );
-void Wb35Reg_EP0VM( phw_data_t pHwData );
-void Wb35Reg_EP0VM_start( phw_data_t pHwData );
+void Wb35Reg_EP0VM( struct hw_data * pHwData );
+void Wb35Reg_EP0VM_start( struct hw_data * pHwData );
void Wb35Reg_EP0VM_complete(struct urb *urb);
u32 BitReverse( u32 dwData, u32 DataLength);
@@ -54,8 +54,8 @@ u32 BitReverse( u32 dwData, u32 DataLength);
void CardGetMulticastBit( u8 Address[MAC_ADDR_LENGTH], u8 *Byte, u8 *Value );
u32 CardComputeCrc( u8 * Buffer, u32 Length );
-void Wb35Reg_phy_calibration( phw_data_t pHwData );
-void Wb35Reg_Update( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue );
-unsigned char adjust_TXVGA_for_iq_mag( phw_data_t pHwData );
+void Wb35Reg_phy_calibration( struct hw_data * pHwData );
+void Wb35Reg_Update( struct hw_data * pHwData, u16 RegisterNo, u32 RegisterValue );
+unsigned char adjust_TXVGA_for_iq_mag( struct hw_data * pHwData );
#endif
diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c
index 7f8b6d749a4..3e8cf08b87e 100644
--- a/drivers/staging/winbond/wb35rx.c
+++ b/drivers/staging/winbond/wb35rx.c
@@ -82,9 +82,9 @@ static void Wb35Rx_adjust(PDESCRIPTOR pRxDes)
static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
+ struct hw_data * pHwData = &priv->sHwData;
DESCRIPTOR RxDes;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u8 * pRxBufferAddress;
u16 PacketSize;
u16 stmp, BufferSize, stmp2 = 0;
@@ -118,7 +118,7 @@ static u16 Wb35Rx_indicate(struct ieee80211_hw *hw)
// Basic check for Rx length. Is length valid?
if (PacketSize > MAX_PACKET_SIZE) {
#ifdef _PE_RX_DUMP_
- WBDEBUG(("Serious ERROR : Rx data size too long, size =%d\n", PacketSize));
+ printk("Serious ERROR : Rx data size too long, size =%d\n", PacketSize);
#endif
pWb35Rx->EP3vm_state = VM_STOP;
@@ -161,8 +161,8 @@ static void Wb35Rx_Complete(struct urb *urb)
{
struct ieee80211_hw *hw = urb->context;
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct hw_data * pHwData = &priv->sHwData;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u8 * pRxBufferAddress;
u32 SizeCheck;
u16 BulkLength;
@@ -194,8 +194,7 @@ static void Wb35Rx_Complete(struct urb *urb)
// The URB is completed, check the result
if (pWb35Rx->EP3VM_status != 0) {
#ifdef _PE_USB_STATE_DUMP_
- WBDEBUG(("EP3 IoCompleteRoutine return error\n"));
- DebugUsbdStatusInformation( pWb35Rx->EP3VM_status );
+ printk("EP3 IoCompleteRoutine return error\n");
#endif
pWb35Rx->EP3vm_state = VM_STOP;
goto error;
@@ -239,8 +238,8 @@ error:
static void Wb35Rx(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct hw_data * pHwData = &priv->sHwData;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u8 * pRxBufferAddress;
struct urb *urb = pWb35Rx->RxUrb;
int retv;
@@ -260,7 +259,7 @@ static void Wb35Rx(struct ieee80211_hw *hw)
if (!pWb35Rx->RxOwner[RxBufferId]) {
// It's impossible to run here.
#ifdef _PE_RX_DUMP_
- WBDEBUG(("Rx driver fifo unavailable\n"));
+ printk("Rx driver fifo unavailable\n");
#endif
goto error;
}
@@ -302,8 +301,8 @@ error:
void Wb35Rx_start(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct hw_data * pHwData = &priv->sHwData;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
// Allow only one thread to run into the Wb35Rx() function
if (atomic_inc_return(&pWb35Rx->RxFireCounter) == 1) {
@@ -314,9 +313,9 @@ void Wb35Rx_start(struct ieee80211_hw *hw)
}
//=====================================================================================
-static void Wb35Rx_reset_descriptor( phw_data_t pHwData )
+static void Wb35Rx_reset_descriptor( struct hw_data * pHwData )
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
u32 i;
pWb35Rx->ByteReceived = 0;
@@ -330,9 +329,9 @@ static void Wb35Rx_reset_descriptor( phw_data_t pHwData )
pWb35Rx->RxOwner[i] = 1;
}
-unsigned char Wb35Rx_initial(phw_data_t pHwData)
+unsigned char Wb35Rx_initial(struct hw_data * pHwData)
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
// Initial the Buffer Queue
Wb35Rx_reset_descriptor( pHwData );
@@ -341,23 +340,23 @@ unsigned char Wb35Rx_initial(phw_data_t pHwData)
return (!!pWb35Rx->RxUrb);
}
-void Wb35Rx_stop(phw_data_t pHwData)
+void Wb35Rx_stop(struct hw_data * pHwData)
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
// Canceling the Irp if already sends it out.
if (pWb35Rx->EP3vm_state == VM_RUNNING) {
usb_unlink_urb( pWb35Rx->RxUrb ); // Only use unlink, let Wb35Rx_destroy to free them
#ifdef _PE_RX_DUMP_
- WBDEBUG(("EP3 Rx stop\n"));
+ printk("EP3 Rx stop\n");
#endif
}
}
// Needs process context
-void Wb35Rx_destroy(phw_data_t pHwData)
+void Wb35Rx_destroy(struct hw_data * pHwData)
{
- PWB35RX pWb35Rx = &pHwData->Wb35Rx;
+ struct wb35_rx *pWb35Rx = &pHwData->Wb35Rx;
do {
msleep(10); // Delay for waiting function enter 940623.1.a
@@ -367,7 +366,7 @@ void Wb35Rx_destroy(phw_data_t pHwData)
if (pWb35Rx->RxUrb)
usb_free_urb( pWb35Rx->RxUrb );
#ifdef _PE_RX_DUMP_
- WBDEBUG(("Wb35Rx_destroy OK\n"));
+ printk("Wb35Rx_destroy OK\n");
#endif
}
diff --git a/drivers/staging/winbond/wb35rx_f.h b/drivers/staging/winbond/wb35rx_f.h
index d993041e0cd..98acce517d9 100644
--- a/drivers/staging/winbond/wb35rx_f.h
+++ b/drivers/staging/winbond/wb35rx_f.h
@@ -7,9 +7,9 @@
//====================================
// Interface function declare
//====================================
-unsigned char Wb35Rx_initial( phw_data_t pHwData );
-void Wb35Rx_destroy( phw_data_t pHwData );
-void Wb35Rx_stop( phw_data_t pHwData );
+unsigned char Wb35Rx_initial( struct hw_data * pHwData );
+void Wb35Rx_destroy( struct hw_data * pHwData );
+void Wb35Rx_stop( struct hw_data * pHwData );
void Wb35Rx_start(struct ieee80211_hw *hw);
#endif
diff --git a/drivers/staging/winbond/wb35rx_s.h b/drivers/staging/winbond/wb35rx_s.h
index f18350b41c4..4b03274a7d2 100644
--- a/drivers/staging/winbond/wb35rx_s.h
+++ b/drivers/staging/winbond/wb35rx_s.h
@@ -15,8 +15,7 @@
//====================================
// Internal variable for module
//====================================
-typedef struct _WB35RX
-{
+struct wb35_rx {
u32 ByteReceived;// For calculating throughput of BulkIn
atomic_t RxFireCounter;// Does Wb35Rx module fire?
@@ -42,7 +41,4 @@ typedef struct _WB35RX
int EP3VM_status;
u8 * pDRx;
-
-} WB35RX, *PWB35RX;
-
-
+};
diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c
index b9b4456c808..1e4169d9a11 100644
--- a/drivers/staging/winbond/wb35tx.c
+++ b/drivers/staging/winbond/wb35tx.c
@@ -15,9 +15,9 @@
#include "sysdef.h"
unsigned char
-Wb35Tx_get_tx_buffer(phw_data_t pHwData, u8 **pBuffer)
+Wb35Tx_get_tx_buffer(struct hw_data * pHwData, u8 **pBuffer)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
*pBuffer = pWb35Tx->TxBuffer[0];
return true;
@@ -28,8 +28,8 @@ static void Wb35Tx(struct wbsoft_priv *adapter);
static void Wb35Tx_complete(struct urb * pUrb)
{
struct wbsoft_priv *adapter = pUrb->context;
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
PMDS pMds = &adapter->Mds;
printk("wb35: tx complete\n");
@@ -64,8 +64,8 @@ error:
static void Wb35Tx(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
u8 *pTxBufferAddress;
PMDS pMds = &adapter->Mds;
struct urb * pUrb = (struct urb *)pWb35Tx->Tx4Urb;
@@ -115,8 +115,8 @@ static void Wb35Tx(struct wbsoft_priv *adapter)
void Wb35Tx_start(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
// Allow only one thread to run into function
if (atomic_inc_return(&pWb35Tx->TxFireCounter) == 1) {
@@ -126,9 +126,9 @@ void Wb35Tx_start(struct wbsoft_priv *adapter)
atomic_dec(&pWb35Tx->TxFireCounter);
}
-unsigned char Wb35Tx_initial(phw_data_t pHwData)
+unsigned char Wb35Tx_initial(struct hw_data * pHwData)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
pWb35Tx->Tx4Urb = usb_alloc_urb(0, GFP_ATOMIC);
if (!pWb35Tx->Tx4Urb)
@@ -145,29 +145,29 @@ unsigned char Wb35Tx_initial(phw_data_t pHwData)
}
//======================================================
-void Wb35Tx_stop(phw_data_t pHwData)
+void Wb35Tx_stop(struct hw_data * pHwData)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
// Trying to canceling the Trp of EP2
if (pWb35Tx->EP2vm_state == VM_RUNNING)
usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them
#ifdef _PE_TX_DUMP_
- WBDEBUG(("EP2 Tx stop\n"));
+ printk("EP2 Tx stop\n");
#endif
// Trying to canceling the Irp of EP4
if (pWb35Tx->EP4vm_state == VM_RUNNING)
usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them
#ifdef _PE_TX_DUMP_
- WBDEBUG(("EP4 Tx stop\n"));
+ printk("EP4 Tx stop\n");
#endif
}
//======================================================
-void Wb35Tx_destroy(phw_data_t pHwData)
+void Wb35Tx_destroy(struct hw_data * pHwData)
{
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
// Wait for VM stop
do {
@@ -182,14 +182,14 @@ void Wb35Tx_destroy(phw_data_t pHwData)
usb_free_urb( pWb35Tx->Tx2Urb );
#ifdef _PE_TX_DUMP_
- WBDEBUG(("Wb35Tx_destroy OK\n"));
+ printk("Wb35Tx_destroy OK\n");
#endif
}
void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
unsigned char Trigger = false;
if (pWb35Tx->TxTimer > TimeCount)
@@ -208,9 +208,9 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter);
static void Wb35Tx_EP2VM_complete(struct urb * pUrb)
{
struct wbsoft_priv *adapter = pUrb->context;
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
T02_DESCRIPTOR T02, TSTATUS;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
u32 * pltmp = (u32 *)pWb35Tx->EP2_buf;
u32 i;
u16 InterruptInLength;
@@ -229,7 +229,7 @@ static void Wb35Tx_EP2VM_complete(struct urb * pUrb)
//The Urb is completed, check the result
if (pWb35Tx->EP2VM_status != 0) {
- WBDEBUG(("EP2 IoCompleteRoutine return error\n"));
+ printk("EP2 IoCompleteRoutine return error\n");
pWb35Tx->EP2vm_state= VM_STOP;
goto error;
}
@@ -256,8 +256,8 @@ error:
static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
struct urb * pUrb = (struct urb *)pWb35Tx->Tx2Urb;
u32 * pltmp = (u32 *)pWb35Tx->EP2_buf;
int retv;
@@ -279,7 +279,7 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter)
if (retv < 0) {
#ifdef _PE_TX_DUMP_
- WBDEBUG(("EP2 Tx Irp sending error\n"));
+ printk("EP2 Tx Irp sending error\n");
#endif
goto error;
}
@@ -292,8 +292,8 @@ error:
void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter)
{
- phw_data_t pHwData = &adapter->sHwData;
- PWB35TX pWb35Tx = &pHwData->Wb35Tx;
+ struct hw_data * pHwData = &adapter->sHwData;
+ struct wb35_tx *pWb35Tx = &pHwData->Wb35Tx;
// Allow only one thread to run into function
if (atomic_inc_return(&pWb35Tx->TxResultCount) == 1) {
diff --git a/drivers/staging/winbond/wb35tx_f.h b/drivers/staging/winbond/wb35tx_f.h
index 4222fa80c7b..a7af9cbe202 100644
--- a/drivers/staging/winbond/wb35tx_f.h
+++ b/drivers/staging/winbond/wb35tx_f.h
@@ -7,14 +7,14 @@
//====================================
// Interface function declare
//====================================
-unsigned char Wb35Tx_initial( phw_data_t pHwData );
-void Wb35Tx_destroy( phw_data_t pHwData );
-unsigned char Wb35Tx_get_tx_buffer( phw_data_t pHwData, u8 **pBuffer );
+unsigned char Wb35Tx_initial( struct hw_data * pHwData );
+void Wb35Tx_destroy( struct hw_data * pHwData );
+unsigned char Wb35Tx_get_tx_buffer( struct hw_data * pHwData, u8 **pBuffer );
void Wb35Tx_EP2VM_start(struct wbsoft_priv *adapter);
void Wb35Tx_start(struct wbsoft_priv *adapter);
-void Wb35Tx_stop( phw_data_t pHwData );
+void Wb35Tx_stop( struct hw_data * pHwData );
void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount);
diff --git a/drivers/staging/winbond/wb35tx_s.h b/drivers/staging/winbond/wb35tx_s.h
index 3960276cae6..f70f4339559 100644
--- a/drivers/staging/winbond/wb35tx_s.h
+++ b/drivers/staging/winbond/wb35tx_s.h
@@ -18,8 +18,7 @@
//====================================
-typedef struct _WB35TX
-{
+struct wb35_tx {
// For Tx buffer
u8 TxBuffer[ MAX_USB_TX_BUFFER_NUMBER ][ MAX_USB_TX_BUFFER ];
@@ -43,7 +42,6 @@ typedef struct _WB35TX
u32 TxFillCount; // 20060928
u32 TxTimer; // 20060928 Add if sending packet not great than 13
-
-} WB35TX, *PWB35TX;
+};
#endif
diff --git a/drivers/staging/winbond/wbhal.c b/drivers/staging/winbond/wbhal.c
index 8a9d21cbb0c..c985ad06523 100644
--- a/drivers/staging/winbond/wbhal.c
+++ b/drivers/staging/winbond/wbhal.c
@@ -1,14 +1,14 @@
-#include "os_common.h"
+#include "sysdef.h"
#include "wbhal_f.h"
#include "wblinux_f.h"
-void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address )
+void hal_set_ethernet_address( struct hw_data * pHwData, u8 *current_address )
{
u32 ltmp[2];
if( pHwData->SurpriseRemove ) return;
- memcpy( pHwData->CurrentMacAddress, current_address, ETH_LENGTH_OF_ADDRESS );
+ memcpy( pHwData->CurrentMacAddress, current_address, ETH_ALEN );
ltmp[0]= cpu_to_le32( *(u32 *)pHwData->CurrentMacAddress );
ltmp[1]= cpu_to_le32( *(u32 *)(pHwData->CurrentMacAddress + 4) ) & 0xffff;
@@ -16,7 +16,7 @@ void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address )
Wb35Reg_BurstWrite( pHwData, 0x03e8, ltmp, 2, AUTO_INCREMENT );
}
-void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address )
+void hal_get_permanent_address( struct hw_data * pHwData, u8 *pethernet_address )
{
if( pHwData->SurpriseRemove ) return;
@@ -26,7 +26,7 @@ void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address )
static void hal_led_control(unsigned long data)
{
struct wbsoft_priv *adapter = (struct wbsoft_priv *) data;
- phw_data_t pHwData = &adapter->sHwData;
+ struct hw_data * pHwData = &adapter->sHwData;
struct wb35_reg *reg = &pHwData->reg;
u32 LEDSet = (pHwData->SoftwareSet & HAL_LED_SET_MASK) >> HAL_LED_SET_SHIFT;
u8 LEDgray[20] = { 0,3,4,6,8,10,11,12,13,14,15,14,13,12,11,10,8,6,4,2 };
@@ -311,7 +311,7 @@ static void hal_led_control(unsigned long data)
u8 hal_init_hardware(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData = &priv->sHwData;
+ struct hw_data * pHwData = &priv->sHwData;
u16 SoftwareSet;
// Initial the variable
@@ -356,7 +356,7 @@ u8 hal_init_hardware(struct ieee80211_hw *hw)
}
-void hal_halt(phw_data_t pHwData, void *ppa_data)
+void hal_halt(struct hw_data * pHwData, void *ppa_data)
{
switch( pHwData->InitialResource )
{
@@ -370,7 +370,7 @@ void hal_halt(phw_data_t pHwData, void *ppa_data)
}
//---------------------------------------------------------------------------------------------------
-void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period )
+void hal_set_beacon_period( struct hw_data * pHwData, u16 beacon_period )
{
u32 tmp;
@@ -383,7 +383,7 @@ void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period )
}
-static void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel )
+static void hal_set_current_channel_ex( struct hw_data * pHwData, ChanInfo channel )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -396,7 +396,7 @@ static void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel )
pHwData->Channel = channel.ChanNo;
pHwData->band = channel.band;
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band));
+ printk("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band);
#endif
reg->M28_MacControl &= ~0xff; // Clean channel information field
reg->M28_MacControl |= channel.ChanNo;
@@ -404,12 +404,12 @@ static void hal_set_current_channel_ex( phw_data_t pHwData, ChanInfo channel )
(s8 *)&channel, sizeof(ChanInfo));
}
//---------------------------------------------------------------------------------------------------
-void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel )
+void hal_set_current_channel( struct hw_data * pHwData, ChanInfo channel )
{
hal_set_current_channel_ex( pHwData, channel );
}
//---------------------------------------------------------------------------------------------------
-void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable )
+void hal_set_accept_broadcast( struct hw_data * pHwData, u8 enable )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -424,7 +424,7 @@ void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable )
}
//for wep key error detection, we need to accept broadcast packets to be received temporary.
-void hal_set_accept_promiscuous( phw_data_t pHwData, u8 enable)
+void hal_set_accept_promiscuous( struct hw_data * pHwData, u8 enable)
{
struct wb35_reg *reg = &pHwData->reg;
@@ -438,7 +438,7 @@ void hal_set_accept_promiscuous( phw_data_t pHwData, u8 enable)
}
}
-void hal_set_accept_multicast( phw_data_t pHwData, u8 enable )
+void hal_set_accept_multicast( struct hw_data * pHwData, u8 enable )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -449,7 +449,7 @@ void hal_set_accept_multicast( phw_data_t pHwData, u8 enable )
Wb35Reg_Write( pHwData, 0x0800, reg->M00_MacControl );
}
-void hal_set_accept_beacon( phw_data_t pHwData, u8 enable )
+void hal_set_accept_beacon( struct hw_data * pHwData, u8 enable )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -467,7 +467,7 @@ void hal_set_accept_beacon( phw_data_t pHwData, u8 enable )
}
//---------------------------------------------------------------------------------------------------
-void hal_stop( phw_data_t pHwData )
+void hal_stop( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -481,10 +481,10 @@ void hal_stop( phw_data_t pHwData )
Wb35Reg_Write( pHwData, 0x0400, reg->D00_DmaControl );
}
-unsigned char hal_idle(phw_data_t pHwData)
+unsigned char hal_idle(struct hw_data * pHwData)
{
struct wb35_reg *reg = &pHwData->reg;
- PWBUSB pWbUsb = &pHwData->WbUsb;
+ struct wb_usb *pWbUsb = &pHwData->WbUsb;
if( !pHwData->SurpriseRemove && ( pWbUsb->DetectCount || reg->EP0vm_state!=VM_STOP ) )
return false;
@@ -492,12 +492,12 @@ unsigned char hal_idle(phw_data_t pHwData)
return true;
}
//---------------------------------------------------------------------------------------------------
-void hal_set_phy_type( phw_data_t pHwData, u8 PhyType )
+void hal_set_phy_type( struct hw_data * pHwData, u8 PhyType )
{
pHwData->phy_type = PhyType;
}
-void hal_set_radio_mode( phw_data_t pHwData, unsigned char radio_off)
+void hal_set_radio_mode( struct hw_data * pHwData, unsigned char radio_off)
{
struct wb35_reg *reg = &pHwData->reg;
@@ -516,7 +516,7 @@ void hal_set_radio_mode( phw_data_t pHwData, unsigned char radio_off)
Wb35Reg_Write( pHwData, 0x0824, reg->M24_MacControl );
}
-u8 hal_get_antenna_number( phw_data_t pHwData )
+u8 hal_get_antenna_number( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -528,7 +528,7 @@ u8 hal_get_antenna_number( phw_data_t pHwData )
//----------------------------------------------------------------------------------------------------
//0 : radio on; 1: radio off
-u8 hal_get_hw_radio_off( phw_data_t pHwData )
+u8 hal_get_hw_radio_off( struct hw_data * pHwData )
{
struct wb35_reg *reg = &pHwData->reg;
@@ -545,14 +545,14 @@ u8 hal_get_hw_radio_off( phw_data_t pHwData )
}
}
-unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, u32 * pValue )
+unsigned char hal_get_dxx_reg( struct hw_data * pHwData, u16 number, u32 * pValue )
{
if( number < 0x1000 )
number += 0x1000;
return Wb35Reg_ReadSync( pHwData, number, pValue );
}
-unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value )
+unsigned char hal_set_dxx_reg( struct hw_data * pHwData, u16 number, u32 value )
{
unsigned char ret;
@@ -562,7 +562,7 @@ unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value )
return ret;
}
-void hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+void hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex)
{
RFSynthesizer_SetPowerIndex( pHwData, PowerIndex );
}
diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h
index e805f40f635..efcaefb6aa5 100644
--- a/drivers/staging/winbond/wbhal_f.h
+++ b/drivers/staging/winbond/wbhal_f.h
@@ -10,56 +10,56 @@
//====================================================================================
// Function declaration
//====================================================================================
-void hal_remove_mapping_key( phw_data_t pHwData, u8 *pmac_addr );
-void hal_remove_default_key( phw_data_t pHwData, u32 index );
-unsigned char hal_set_mapping_key( phw_data_t adapter, u8 *pmac_addr, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
-unsigned char hal_set_default_key( phw_data_t adapter, u8 index, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
-void hal_clear_all_default_key( phw_data_t pHwData );
-void hal_clear_all_group_key( phw_data_t pHwData );
-void hal_clear_all_mapping_key( phw_data_t pHwData );
-void hal_clear_all_key( phw_data_t pHwData );
-void hal_get_ethernet_address( phw_data_t pHwData, u8 *current_address );
-void hal_set_ethernet_address( phw_data_t pHwData, u8 *current_address );
-void hal_get_permanent_address( phw_data_t pHwData, u8 *pethernet_address );
+void hal_remove_mapping_key( struct hw_data * pHwData, u8 *pmac_addr );
+void hal_remove_default_key( struct hw_data * pHwData, u32 index );
+unsigned char hal_set_mapping_key( struct hw_data * adapter, u8 *pmac_addr, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
+unsigned char hal_set_default_key( struct hw_data * adapter, u8 index, u8 null_key, u8 wep_on, u8 *ptx_tsc, u8 *prx_tsc, u8 key_type, u8 key_len, u8 *pkey_data );
+void hal_clear_all_default_key( struct hw_data * pHwData );
+void hal_clear_all_group_key( struct hw_data * pHwData );
+void hal_clear_all_mapping_key( struct hw_data * pHwData );
+void hal_clear_all_key( struct hw_data * pHwData );
+void hal_get_ethernet_address( struct hw_data * pHwData, u8 *current_address );
+void hal_set_ethernet_address( struct hw_data * pHwData, u8 *current_address );
+void hal_get_permanent_address( struct hw_data * pHwData, u8 *pethernet_address );
u8 hal_init_hardware(struct ieee80211_hw *hw);
-void hal_set_power_save_mode( phw_data_t pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim );
-void hal_get_power_save_mode( phw_data_t pHwData, u8 *pin_pwr_save );
-void hal_set_slot_time( phw_data_t pHwData, u8 type );
+void hal_set_power_save_mode( struct hw_data * pHwData, unsigned char power_save, unsigned char wakeup, unsigned char dtim );
+void hal_get_power_save_mode( struct hw_data * pHwData, u8 *pin_pwr_save );
+void hal_set_slot_time( struct hw_data * pHwData, u8 type );
#define hal_set_atim_window( _A, _ATM )
-void hal_start_bss( phw_data_t pHwData, u8 mac_op_mode );
-void hal_join_request( phw_data_t pHwData, u8 bss_type ); // 0:BSS STA 1:IBSS STA//
-void hal_stop_sync_bss( phw_data_t pHwData );
-void hal_resume_sync_bss( phw_data_t pHwData);
-void hal_set_aid( phw_data_t pHwData, u16 aid );
-void hal_set_bssid( phw_data_t pHwData, u8 *pbssid );
-void hal_get_bssid( phw_data_t pHwData, u8 *pbssid );
-void hal_set_beacon_period( phw_data_t pHwData, u16 beacon_period );
-void hal_set_listen_interval( phw_data_t pHwData, u16 listen_interval );
-void hal_set_cap_info( phw_data_t pHwData, u16 capability_info );
-void hal_set_ssid( phw_data_t pHwData, u8 *pssid, u8 ssid_len );
-void hal_set_current_channel( phw_data_t pHwData, ChanInfo channel );
-void hal_set_accept_broadcast( phw_data_t pHwData, u8 enable );
-void hal_set_accept_multicast( phw_data_t pHwData, u8 enable );
-void hal_set_accept_beacon( phw_data_t pHwData, u8 enable );
-void hal_stop( phw_data_t pHwData );
-void hal_halt( phw_data_t pHwData, void *ppa_data );
-void hal_start_tx0( phw_data_t pHwData );
-void hal_set_phy_type( phw_data_t pHwData, u8 PhyType );
+void hal_start_bss( struct hw_data * pHwData, u8 mac_op_mode );
+void hal_join_request( struct hw_data * pHwData, u8 bss_type ); // 0:BSS STA 1:IBSS STA//
+void hal_stop_sync_bss( struct hw_data * pHwData );
+void hal_resume_sync_bss( struct hw_data * pHwData);
+void hal_set_aid( struct hw_data * pHwData, u16 aid );
+void hal_set_bssid( struct hw_data * pHwData, u8 *pbssid );
+void hal_get_bssid( struct hw_data * pHwData, u8 *pbssid );
+void hal_set_beacon_period( struct hw_data * pHwData, u16 beacon_period );
+void hal_set_listen_interval( struct hw_data * pHwData, u16 listen_interval );
+void hal_set_cap_info( struct hw_data * pHwData, u16 capability_info );
+void hal_set_ssid( struct hw_data * pHwData, u8 *pssid, u8 ssid_len );
+void hal_set_current_channel( struct hw_data * pHwData, ChanInfo channel );
+void hal_set_accept_broadcast( struct hw_data * pHwData, u8 enable );
+void hal_set_accept_multicast( struct hw_data * pHwData, u8 enable );
+void hal_set_accept_beacon( struct hw_data * pHwData, u8 enable );
+void hal_stop( struct hw_data * pHwData );
+void hal_halt( struct hw_data * pHwData, void *ppa_data );
+void hal_start_tx0( struct hw_data * pHwData );
+void hal_set_phy_type( struct hw_data * pHwData, u8 PhyType );
#define hal_get_cwmin( _A ) ( (_A)->cwmin )
-void hal_set_cwmax( phw_data_t pHwData, u16 cwin_max );
+void hal_set_cwmax( struct hw_data * pHwData, u16 cwin_max );
#define hal_get_cwmax( _A ) ( (_A)->cwmax )
-void hal_set_rsn_wpa( phw_data_t pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode);
-void hal_set_connect_info( phw_data_t pHwData, unsigned char boConnect );
-u8 hal_get_est_sq3( phw_data_t pHwData, u8 Count );
-void hal_set_rf_power( phw_data_t pHwData, u8 PowerIndex ); // 20060621 Modify
-void hal_set_radio_mode( phw_data_t pHwData, unsigned char boValue);
-void hal_descriptor_indicate( phw_data_t pHwData, PDESCRIPTOR pDes );
-u8 hal_get_antenna_number( phw_data_t pHwData );
-u32 hal_get_bss_pk_cnt( phw_data_t pHwData );
+void hal_set_rsn_wpa( struct hw_data * pHwData, u32 * RSN_IE_Bitmap , u32 * RSN_OUI_type , unsigned char bDesiredAuthMode);
+void hal_set_connect_info( struct hw_data * pHwData, unsigned char boConnect );
+u8 hal_get_est_sq3( struct hw_data * pHwData, u8 Count );
+void hal_set_rf_power( struct hw_data * pHwData, u8 PowerIndex ); // 20060621 Modify
+void hal_set_radio_mode( struct hw_data * pHwData, unsigned char boValue);
+void hal_descriptor_indicate( struct hw_data * pHwData, PDESCRIPTOR pDes );
+u8 hal_get_antenna_number( struct hw_data * pHwData );
+u32 hal_get_bss_pk_cnt( struct hw_data * pHwData );
#define hal_get_region_from_EEPROM( _A ) ( (_A)->reg.EEPROMRegion )
-void hal_set_accept_promiscuous ( phw_data_t pHwData, u8 enable);
+void hal_set_accept_promiscuous ( struct hw_data * pHwData, u8 enable);
#define hal_get_tx_buffer( _A, _B ) Wb35Tx_get_tx_buffer( _A, _B )
-u8 hal_get_hw_radio_off ( phw_data_t pHwData );
+u8 hal_get_hw_radio_off ( struct hw_data * pHwData );
#define hal_software_set( _A ) (_A->SoftwareSet)
#define hal_driver_init_OK( _A ) (_A->IsInitOK)
#define hal_rssi_boundary_high( _A ) (_A->RSSI_high)
@@ -68,8 +68,8 @@ u8 hal_get_hw_radio_off ( phw_data_t pHwData );
#define PHY_DEBUG( msg, args... )
-unsigned char hal_get_dxx_reg( phw_data_t pHwData, u16 number, u32 * pValue );
-unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value );
+unsigned char hal_get_dxx_reg( struct hw_data * pHwData, u16 number, u32 * pValue );
+unsigned char hal_set_dxx_reg( struct hw_data * pHwData, u16 number, u32 value );
#define hal_get_time_count( _P ) (_P->time_count/10) // return 100ms count
#define hal_detect_error( _P ) (_P->WbUsb.DetectCount)
@@ -82,7 +82,7 @@ unsigned char hal_set_dxx_reg( phw_data_t pHwData, u16 number, u32 value );
#define hal_get_clear_interrupt(_A)
#define hal_ibss_disconnect(_A) hal_stop_sync_bss(_A)
#define hal_join_request_stop(_A)
-unsigned char hal_idle( phw_data_t pHwData );
+unsigned char hal_idle( struct hw_data * pHwData );
#define hw_get_cxx_reg( _A, _B, _C )
#define hw_set_cxx_reg( _A, _B, _C )
#define hw_get_dxx_reg( _A, _B, _C ) hal_get_dxx_reg( _A, _B, (u32 *)_C )
diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h
index 276d2b12632..acfebf05d9d 100644
--- a/drivers/staging/winbond/wbhal_s.h
+++ b/drivers/staging/winbond/wbhal_s.h
@@ -2,8 +2,7 @@
#define __WINBOND_WBHAL_S_H
#include <linux/types.h>
-
-#include "common.h"
+#include <linux/if_ether.h> /* for ETH_ALEN */
//[20040722 WK]
#define HAL_LED_SET_MASK 0x001c //20060901 Extend
@@ -86,19 +85,6 @@ enum {
VM_COMPLETED
};
-// Be used for 802.11 mac header
-typedef struct _MAC_FRAME_CONTROL {
- u8 mac_frame_info; // this is a combination of the protovl version, type and subtype
- u8 to_ds:1;
- u8 from_ds:1;
- u8 more_frag:1;
- u8 retry:1;
- u8 pwr_mgt:1;
- u8 more_data:1;
- u8 WEP:1;
- u8 order:1;
-} MAC_FRAME_CONTROL, *PMAC_FRAME_CONTROL;
-
//-----------------------------------------------------
// Normal Key table format
//-----------------------------------------------------
@@ -106,28 +92,6 @@ typedef struct _MAC_FRAME_CONTROL {
#define MAX_KEY_TABLE 24 // 24 entry for storing key data
#define GROUP_KEY_START_INDEX 4
#define MAPPING_KEY_START_INDEX 8
-typedef struct _KEY_TABLE
-{
- u32 DW0_Valid:1;
- u32 DW0_NullKey:1;
- u32 DW0_Security_Mode:2;//0:WEP 40 bit 1:WEP 104 bit 2:TKIP 128 bit 3:CCMP 128 bit
- u32 DW0_WEPON:1;
- u32 DW0_RESERVED:11;
- u32 DW0_Address1:16;
-
- u32 DW1_Address2;
-
- u32 DW2_RxSequenceCount1;
-
- u32 DW3_RxSequenceCount2:16;
- u32 DW3_RESERVED:16;
-
- u32 DW4_TxSequenceCount1;
-
- u32 DW5_TxSequenceCount2:16;
- u32 DW5_RESERVED:16;
-
-} KEY_TABLE, *PKEY_TABLE;
//--------------------------------------------------------
// Descriptor
@@ -413,8 +377,8 @@ typedef struct _DESCRIPTOR { // Skip length = 8 DWORD
#define MAX_RF_PARAMETER 32
typedef struct _TXVGA_FOR_50 {
- u8 ChanNo;
- u8 TxVgaValue;
+ u8 ChanNo;
+ u8 TxVgaValue;
} TXVGA_FOR_50;
@@ -427,10 +391,8 @@ typedef struct _TXVGA_FOR_50 {
#include "wb35tx_s.h"
#include "wb35rx_s.h"
-
// For Hal using ==================================================================
-typedef struct _HW_DATA_T
-{
+struct hw_data {
// For compatible with 33
u32 revision;
u32 BB3c_cal; // The value for Tx calibration comes from EEPROM
@@ -452,8 +414,8 @@ typedef struct _HW_DATA_T
//===============================================
// Definition for MAC address
//===============================================
- u8 PermanentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are stored in EEPROM. + 2 to 8-byte alignment
- u8 CurrentMacAddress[ETH_LENGTH_OF_ADDRESS + 2]; // The Enthernet addr that are in used. + 2 to 8-byte alignment
+ u8 PermanentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are stored in EEPROM. + 2 to 8-byte alignment
+ u8 CurrentMacAddress[ETH_ALEN + 2]; // The Enthernet addr that are in used. + 2 to 8-byte alignment
//=====================================================================
// Definition for 802.11
@@ -502,10 +464,10 @@ typedef struct _HW_DATA_T
//========================================================================
// Variable for each module
//========================================================================
- WBUSB WbUsb; // Need WbUsb.h
+ struct wb_usb WbUsb; // Need WbUsb.h
struct wb35_reg reg; // Need Wb35Reg.h
- WB35TX Wb35Tx; // Need Wb35Tx.h
- WB35RX Wb35Rx; // Need Wb35Rx.h
+ struct wb35_tx Wb35Tx; // Need Wb35Tx.h
+ struct wb35_rx Wb35Rx; // Need Wb35Rx.h
struct timer_list LEDTimer;// For LED
@@ -578,35 +540,6 @@ typedef struct _HW_DATA_T
// 20060828.1 for avoid AP disconnect
u32 NullPacketCount;
-} hw_data_t, *phw_data_t;
-
-// The mapping of Rx and Tx descriptor field
-typedef struct _HAL_RATE
-{
- // DSSS
- u32 RESERVED_0;
- u32 NumRate2MS;
- u32 NumRate55MS;
- u32 NumRate11MS;
-
- u32 RESERVED_1[4];
-
- u32 NumRate1M;
- u32 NumRate2ML;
- u32 NumRate55ML;
- u32 NumRate11ML;
-
- u32 RESERVED_2[4];
-
- // OFDM
- u32 NumRate6M;
- u32 NumRate9M;
- u32 NumRate12M;
- u32 NumRate18M;
- u32 NumRate24M;
- u32 NumRate36M;
- u32 NumRate48M;
- u32 NumRate54M;
-} HAL_RATE, *PHAL_RATE;
+};
#endif
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index f716b2e92b6..9c3f9439f35 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -9,7 +9,7 @@
#include "core.h"
#include "mds_f.h"
#include "mlmetxrx_f.h"
-#include "mto_f.h"
+#include "mto.h"
#include "wbhal_f.h"
#include "wblinux_f.h"
@@ -149,19 +149,19 @@ static int wbsoft_config(struct ieee80211_hw *dev, u32 changed)
hal_set_current_channel(&priv->sHwData, ch);
hal_set_beacon_period(&priv->sHwData, conf->beacon_int);
// hal_set_cap_info(&priv->sHwData, ?? );
-// hal_set_ssid(phw_data_t pHwData, u8 * pssid, u8 ssid_len); ??
+// hal_set_ssid(struct hw_data * pHwData, u8 * pssid, u8 ssid_len); ??
hal_set_accept_broadcast(&priv->sHwData, 1);
hal_set_accept_promiscuous(&priv->sHwData, 1);
hal_set_accept_multicast(&priv->sHwData, 1);
hal_set_accept_beacon(&priv->sHwData, 1);
hal_set_radio_mode(&priv->sHwData, 0);
- //hal_set_antenna_number( phw_data_t pHwData, u8 number )
- //hal_set_rf_power(phw_data_t pHwData, u8 PowerIndex)
+ //hal_set_antenna_number( struct hw_data * pHwData, u8 number )
+ //hal_set_rf_power(struct hw_data * pHwData, u8 PowerIndex)
// hal_start_bss(&priv->sHwData, WLAN_BSSTYPE_INFRASTRUCTURE); ??
-//void hal_set_rates(phw_data_t pHwData, u8 * pbss_rates,
+//void hal_set_rates(struct hw_data * pHwData, u8 * pbss_rates,
// u8 length, unsigned char basic_rate_set)
return 0;
@@ -199,7 +199,7 @@ static const struct ieee80211_ops wbsoft_ops = {
static unsigned char wb35_hw_init(struct ieee80211_hw *hw)
{
struct wbsoft_priv *priv = hw->priv;
- phw_data_t pHwData;
+ struct hw_data * pHwData;
u8 *pMacAddr;
u8 *pMacAddr2;
u32 InitStep = 0;
@@ -277,7 +277,7 @@ static unsigned char wb35_hw_init(struct ieee80211_hw *hw)
//get current antenna
priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData);
#ifdef _PE_STATE_DUMP_
- WBDEBUG(("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo));
+ printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo);
#endif
hal_get_hw_radio_off( pHwData );
@@ -312,7 +312,7 @@ error:
static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id_table)
{
- PWBUSB pWbUsb;
+ struct wb_usb *pWbUsb;
struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint;
u32 ltmp;
@@ -366,7 +366,7 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
SET_IEEE80211_DEV(dev, &udev->dev);
{
- phw_data_t pHwData = &priv->sHwData;
+ struct hw_data * pHwData = &priv->sHwData;
unsigned char dev_addr[MAX_ADDR_LEN];
hal_get_permanent_address(pHwData, dev_addr);
SET_IEEE80211_PERM_ADDR(dev, dev_addr);
@@ -404,7 +404,7 @@ static void wb35_hw_halt(struct wbsoft_priv *adapter)
// Turn off Rx and Tx hardware ability
hal_stop( &adapter->sHwData );
#ifdef _PE_USB_INI_DUMP_
- WBDEBUG(("[w35und] Hal_stop O.K.\n"));
+ printk("[w35und] Hal_stop O.K.\n");
#endif
msleep(100);// Waiting Irp completed
diff --git a/drivers/staging/winbond/wbusb_s.h b/drivers/staging/winbond/wbusb_s.h
index 1de93600d84..0c7e6a383f2 100644
--- a/drivers/staging/winbond/wbusb_s.h
+++ b/drivers/staging/winbond/wbusb_s.h
@@ -16,22 +16,10 @@
#include <linux/types.h>
-//---------------------------------------------------------------------------
-// RW_CONTEXT --
-//
-// Used to track driver-generated io irps
-//---------------------------------------------------------------------------
-typedef struct _RW_CONTEXT
-{
- void* pHwData;
- struct urb *urb;
- void* pCallBackFunctionParameter;
-} RW_CONTEXT, *PRW_CONTEXT;
-
-typedef struct _WBUSB {
+struct wb_usb {
u32 IsUsb20;
struct usb_device *udev;
u32 DetectCount;
-} WBUSB, *PWBUSB;
+};
#endif
diff --git a/drivers/staging/wlan-ng/README b/drivers/staging/wlan-ng/README
index 9c10dbb000d..028c299b613 100644
--- a/drivers/staging/wlan-ng/README
+++ b/drivers/staging/wlan-ng/README
@@ -4,4 +4,6 @@ TODO:
- Lindent cleanups
- move to use the in-kernel wireless stack
-Please send all patches to Greg Kroah-Hartman <greg@kroah.com>
+Please send any patches or complaints about this driver to Greg
+Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless
+kernel developers about it, they want nothing to do with it.
diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h
index 9b746654a39..f3e87173471 100644
--- a/drivers/staging/wlan-ng/hfa384x.h
+++ b/drivers/staging/wlan-ng/hfa384x.h
@@ -56,75 +56,37 @@
#ifndef _HFA384x_H
#define _HFA384x_H
-/*=============================================================*/
-#define HFA384x_FIRMWARE_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#define HFA384x_FIRMWARE_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
-#define HFA384x_LEVEL_TO_dBm(v) (0x100 + (v) * 100 / 255 - 100)
+#include <linux/if_ether.h>
-/*------ Constants --------------------------------------------*/
/*--- Mins & Maxs -----------------------------------*/
-#define HFA384x_CMD_ALLOC_LEN_MIN ((u16)4)
-#define HFA384x_CMD_ALLOC_LEN_MAX ((u16)2400)
-#define HFA384x_BAP_DATALEN_MAX ((u16)4096)
-#define HFA384x_BAP_OFFSET_MAX ((u16)4096)
#define HFA384x_PORTID_MAX ((u16)7)
#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX+1))
-#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
-#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */
-#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK */
+#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */
+#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK */
#define HFA384x_SCANRESULT_MAX ((u16)31)
#define HFA384x_HSCANRESULT_MAX ((u16)31)
#define HFA384x_CHINFORESULT_MAX ((u16)16)
-#define HFA384x_DRVR_FIDSTACKLEN_MAX (10)
-#define HFA384x_DRVR_TXBUF_MAX (sizeof(hfa384x_tx_frame_t) + \
- WLAN_DATA_MAXLEN - \
- WLAN_WEP_IV_LEN - \
- WLAN_WEP_ICV_LEN + 2)
-#define HFA384x_DRVR_MAGIC (0x4a2d)
-#define HFA384x_INFODATA_MAXLEN (sizeof(hfa384x_infodata_t))
-#define HFA384x_INFOFRM_MAXLEN (sizeof(hfa384x_InfFrame_t))
-#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
+#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */
#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN
#define HFA384x_USB_RWMEM_MAXLEN 2048
/*--- Support Constants -----------------------------*/
-#define HFA384x_BAP_PROC ((u16)0)
-#define HFA384x_BAP_int ((u16)1)
#define HFA384x_PORTTYPE_IBSS ((u16)0)
#define HFA384x_PORTTYPE_BSS ((u16)1)
-#define HFA384x_PORTTYPE_WDS ((u16)2)
#define HFA384x_PORTTYPE_PSUEDOIBSS ((u16)3)
-#define HFA384x_PORTTYPE_HOSTAP ((u16)6)
-#define HFA384x_WEPFLAGS_PRIVINVOKED ((u16)BIT0)
-#define HFA384x_WEPFLAGS_EXCLUDE ((u16)BIT1)
-#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((u16)BIT4)
-#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((u16)BIT7)
-#define HFA384x_WEPFLAGS_DISALLOW_MIXED ((u16)BIT11)
-#define HFA384x_WEPFLAGS_IV_intERVAL1 ((u16)0)
-#define HFA384x_WEPFLAGS_IV_intERVAL10 ((u16)BIT5)
-#define HFA384x_WEPFLAGS_IV_intERVAL50 ((u16)BIT6)
-#define HFA384x_WEPFLAGS_IV_intERVAL100 ((u16)(BIT5 | BIT6))
-#define HFA384x_WEPFLAGS_FIRMWARE_WPA ((u16)BIT8)
-#define HFA384x_WEPFLAGS_HOST_MIC ((u16)BIT9)
-#define HFA384x_ROAMMODE_FWSCAN_FWROAM ((u16)1)
-#define HFA384x_ROAMMODE_FWSCAN_HOSTROAM ((u16)2)
+#define HFA384x_WEPFLAGS_PRIVINVOKED ((u16)BIT(0))
+#define HFA384x_WEPFLAGS_EXCLUDE ((u16)BIT(1))
+#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((u16)BIT(4))
+#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((u16)BIT(7))
#define HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM ((u16)3)
#define HFA384x_PORTSTATUS_DISABLED ((u16)1)
-#define HFA384x_PORTSTATUS_INITSRCH ((u16)2)
-#define HFA384x_PORTSTATUS_CONN_IBSS ((u16)3)
-#define HFA384x_PORTSTATUS_CONN_ESS ((u16)4)
-#define HFA384x_PORTSTATUS_OOR_ESS ((u16)5)
-#define HFA384x_PORTSTATUS_CONN_WDS ((u16)6)
-#define HFA384x_PORTSTATUS_HOSTAP ((u16)8)
#define HFA384x_RATEBIT_1 ((u16)1)
#define HFA384x_RATEBIT_2 ((u16)2)
#define HFA384x_RATEBIT_5dot5 ((u16)4)
#define HFA384x_RATEBIT_11 ((u16)8)
-/*--- Just some symbolic names for legibility -------*/
-#define HFA384x_TXCMD_NORECL ((u16)0)
-#define HFA384x_TXCMD_RECL ((u16)1)
-
/*--- MAC Internal memory constants and macros ------*/
/* masks and macros used to manipulate MAC internal memory addresses. */
/* MAC internal memory addresses are 23 bit quantities. The MAC uses
@@ -139,59 +101,28 @@
* macros below help handle some of this.
*/
-/* Handy constant */
-#define HFA384x_ADDR_AUX_OFF_MAX ((u16)0x007f)
-
/* Mask bits for discarding unwanted pieces in a flat address */
#define HFA384x_ADDR_FLAT_AUX_PAGE_MASK (0x007fff80)
#define HFA384x_ADDR_FLAT_AUX_OFF_MASK (0x0000007f)
#define HFA384x_ADDR_FLAT_CMD_PAGE_MASK (0xffff0000)
#define HFA384x_ADDR_FLAT_CMD_OFF_MASK (0x0000ffff)
-/* Mask bits for discarding unwanted pieces in AUX format 16-bit address parts */
+/* Mask bits for discarding unwanted pieces in AUX format
+ 16-bit address parts */
#define HFA384x_ADDR_AUX_PAGE_MASK (0xffff)
#define HFA384x_ADDR_AUX_OFF_MASK (0x007f)
-/* Mask bits for discarding unwanted pieces in CMD format 16-bit address parts */
-#define HFA384x_ADDR_CMD_PAGE_MASK (0x007f)
-#define HFA384x_ADDR_CMD_OFF_MASK (0xffff)
-
/* Make a 32-bit flat address from AUX format 16-bit page and offset */
-#define HFA384x_ADDR_AUX_MKFLAT(p,o) \
- (((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) <<7) | \
+#define HFA384x_ADDR_AUX_MKFLAT(p, o) \
+ (((u32)(((u16)(p))&HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \
((u32)(((u16)(o))&HFA384x_ADDR_AUX_OFF_MASK))
-/* Make a 32-bit flat address from CMD format 16-bit page and offset */
-#define HFA384x_ADDR_CMD_MKFLAT(p,o) \
- (((u32)(((u16)(p))&HFA384x_ADDR_CMD_PAGE_MASK)) <<16) | \
- ((u32)(((u16)(o))&HFA384x_ADDR_CMD_OFF_MASK))
-
-/* Make AUX format offset and page from a 32-bit flat address */
-#define HFA384x_ADDR_AUX_MKPAGE(f) \
- ((u16)((((u32)(f))&HFA384x_ADDR_FLAT_AUX_PAGE_MASK)>>7))
-#define HFA384x_ADDR_AUX_MKOFF(f) \
- ((u16)(((u32)(f))&HFA384x_ADDR_FLAT_AUX_OFF_MASK))
-
/* Make CMD format offset and page from a 32-bit flat address */
#define HFA384x_ADDR_CMD_MKPAGE(f) \
((u16)((((u32)(f))&HFA384x_ADDR_FLAT_CMD_PAGE_MASK)>>16))
#define HFA384x_ADDR_CMD_MKOFF(f) \
((u16)(((u32)(f))&HFA384x_ADDR_FLAT_CMD_OFF_MASK))
-/*--- Aux register masks/tests ----------------------*/
-/* Some of the upper bits of the AUX offset register are used to */
-/* select address space. */
-#define HFA384x_AUX_CTL_EXTDS (0x00)
-#define HFA384x_AUX_CTL_NV (0x01)
-#define HFA384x_AUX_CTL_PHY (0x02)
-#define HFA384x_AUX_CTL_ICSRAM (0x03)
-
-/* Make AUX register offset and page values from a flat address */
-#define HFA384x_AUX_MKOFF(f, c) \
- (HFA384x_ADDR_AUX_MKOFF(f) | (((u16)(c))<<12))
-#define HFA384x_AUX_MKPAGE(f) HFA384x_ADDR_AUX_MKPAGE(f)
-
-
/*--- Controller Memory addresses -------------------*/
#define HFA3842_PDA_BASE (0x007f0000UL)
#define HFA3841_PDA_BASE (0x003f0000UL)
@@ -201,124 +132,25 @@
#define HFA384x_DLSTATE_DISABLED 0
#define HFA384x_DLSTATE_RAMENABLED 1
#define HFA384x_DLSTATE_FLASHENABLED 2
-#define HFA384x_DLSTATE_FLASHWRITTEN 3
-#define HFA384x_DLSTATE_FLASHWRITEPENDING 4
-#define HFA384x_DLSTATE_GENESIS 5
-
-#define HFA384x_CMD_OFF (0x00)
-#define HFA384x_PARAM0_OFF (0x04)
-#define HFA384x_PARAM1_OFF (0x08)
-#define HFA384x_PARAM2_OFF (0x0c)
-#define HFA384x_STATUS_OFF (0x10)
-#define HFA384x_RESP0_OFF (0x14)
-#define HFA384x_RESP1_OFF (0x18)
-#define HFA384x_RESP2_OFF (0x1c)
-#define HFA384x_INFOFID_OFF (0x20)
-#define HFA384x_RXFID_OFF (0x40)
-#define HFA384x_ALLOCFID_OFF (0x44)
-#define HFA384x_TXCOMPLFID_OFF (0x48)
-#define HFA384x_SELECT0_OFF (0x30)
-#define HFA384x_OFFSET0_OFF (0x38)
-#define HFA384x_DATA0_OFF (0x6c)
-#define HFA384x_SELECT1_OFF (0x34)
-#define HFA384x_OFFSET1_OFF (0x3c)
-#define HFA384x_DATA1_OFF (0x70)
-#define HFA384x_EVSTAT_OFF (0x60)
-#define HFA384x_intEN_OFF (0x64)
-#define HFA384x_EVACK_OFF (0x68)
-#define HFA384x_CONTROL_OFF (0x28)
-#define HFA384x_SWSUPPORT0_OFF (0x50)
-#define HFA384x_SWSUPPORT1_OFF (0x54)
-#define HFA384x_SWSUPPORT2_OFF (0x58)
-#define HFA384x_AUXPAGE_OFF (0x74)
-#define HFA384x_AUXOFFSET_OFF (0x78)
-#define HFA384x_AUXDATA_OFF (0x7c)
-#define HFA384x_PCICOR_OFF (0x4c)
-#define HFA384x_PCIHCR_OFF (0x5c)
-#define HFA384x_PCI_M0_ADDRH_OFF (0x80)
-#define HFA384x_PCI_M0_ADDRL_OFF (0x84)
-#define HFA384x_PCI_M0_LEN_OFF (0x88)
-#define HFA384x_PCI_M0_CTL_OFF (0x8c)
-#define HFA384x_PCI_STATUS_OFF (0x98)
-#define HFA384x_PCI_M1_ADDRH_OFF (0xa0)
-#define HFA384x_PCI_M1_ADDRL_OFF (0xa4)
-#define HFA384x_PCI_M1_LEN_OFF (0xa8)
-#define HFA384x_PCI_M1_CTL_OFF (0xac)
/*--- Register Field Masks --------------------------*/
-#define HFA384x_CMD_BUSY ((u16)BIT15)
-#define HFA384x_CMD_AINFO ((u16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
-#define HFA384x_CMD_MACPORT ((u16)(BIT10 | BIT9 | BIT8))
-#define HFA384x_CMD_RECL ((u16)BIT8)
-#define HFA384x_CMD_WRITE ((u16)BIT8)
-#define HFA384x_CMD_PROGMODE ((u16)(BIT9 | BIT8))
-#define HFA384x_CMD_CMDCODE ((u16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
-
-#define HFA384x_STATUS_RESULT ((u16)(BIT14 | BIT13 | BIT12 | BIT11 | BIT10 | BIT9 | BIT8))
-#define HFA384x_STATUS_CMDCODE ((u16)(BIT5 | BIT4 | BIT3 | BIT2 | BIT1 | BIT0))
-
-#define HFA384x_OFFSET_BUSY ((u16)BIT15)
-#define HFA384x_OFFSET_ERR ((u16)BIT14)
-#define HFA384x_OFFSET_DATAOFF ((u16)(BIT11 | BIT10 | BIT9 | BIT8 | BIT7 | BIT6 | BIT5 | BIT4 | BIT3 | BIT2 | BIT1))
-
-#define HFA384x_EVSTAT_TICK ((u16)BIT15)
-#define HFA384x_EVSTAT_WTERR ((u16)BIT14)
-#define HFA384x_EVSTAT_INFDROP ((u16)BIT13)
-#define HFA384x_EVSTAT_INFO ((u16)BIT7)
-#define HFA384x_EVSTAT_DTIM ((u16)BIT5)
-#define HFA384x_EVSTAT_CMD ((u16)BIT4)
-#define HFA384x_EVSTAT_ALLOC ((u16)BIT3)
-#define HFA384x_EVSTAT_TXEXC ((u16)BIT2)
-#define HFA384x_EVSTAT_TX ((u16)BIT1)
-#define HFA384x_EVSTAT_RX ((u16)BIT0)
-
-#define HFA384x_int_BAP_OP (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC)
-
-#define HFA384x_int_NORMAL (HFA384x_EVSTAT_INFO|HFA384x_EVSTAT_RX|HFA384x_EVSTAT_TX|HFA384x_EVSTAT_TXEXC|HFA384x_EVSTAT_INFDROP|HFA384x_EVSTAT_ALLOC|HFA384x_EVSTAT_DTIM)
-
-#define HFA384x_intEN_TICK ((u16)BIT15)
-#define HFA384x_intEN_WTERR ((u16)BIT14)
-#define HFA384x_intEN_INFDROP ((u16)BIT13)
-#define HFA384x_intEN_INFO ((u16)BIT7)
-#define HFA384x_intEN_DTIM ((u16)BIT5)
-#define HFA384x_intEN_CMD ((u16)BIT4)
-#define HFA384x_intEN_ALLOC ((u16)BIT3)
-#define HFA384x_intEN_TXEXC ((u16)BIT2)
-#define HFA384x_intEN_TX ((u16)BIT1)
-#define HFA384x_intEN_RX ((u16)BIT0)
-
-#define HFA384x_EVACK_TICK ((u16)BIT15)
-#define HFA384x_EVACK_WTERR ((u16)BIT14)
-#define HFA384x_EVACK_INFDROP ((u16)BIT13)
-#define HFA384x_EVACK_INFO ((u16)BIT7)
-#define HFA384x_EVACK_DTIM ((u16)BIT5)
-#define HFA384x_EVACK_CMD ((u16)BIT4)
-#define HFA384x_EVACK_ALLOC ((u16)BIT3)
-#define HFA384x_EVACK_TXEXC ((u16)BIT2)
-#define HFA384x_EVACK_TX ((u16)BIT1)
-#define HFA384x_EVACK_RX ((u16)BIT0)
-
-#define HFA384x_CONTROL_AUXEN ((u16)(BIT15 | BIT14))
+#define HFA384x_CMD_AINFO ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_CMD_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_CMD_PROGMODE ((u16)(BIT(9) | BIT(8)))
+#define HFA384x_CMD_CMDCODE ((u16)(BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)))
+#define HFA384x_STATUS_RESULT ((u16)(BIT(14) | BIT(13) | BIT(12) | BIT(11) | BIT(10) | BIT(9) | BIT(8)))
/*--- Command Code Constants --------------------------*/
/*--- Controller Commands --------------------------*/
#define HFA384x_CMDCODE_INIT ((u16)0x00)
#define HFA384x_CMDCODE_ENABLE ((u16)0x01)
#define HFA384x_CMDCODE_DISABLE ((u16)0x02)
-#define HFA384x_CMDCODE_DIAG ((u16)0x03)
-
-/*--- Buffer Mgmt Commands --------------------------*/
-#define HFA384x_CMDCODE_ALLOC ((u16)0x0A)
-#define HFA384x_CMDCODE_TX ((u16)0x0B)
-#define HFA384x_CMDCODE_CLRPRST ((u16)0x12)
/*--- Regulate Commands --------------------------*/
-#define HFA384x_CMDCODE_NOTIFY ((u16)0x10)
#define HFA384x_CMDCODE_INQ ((u16)0x11)
/*--- Configure Commands --------------------------*/
-#define HFA384x_CMDCODE_ACCESS ((u16)0x21)
#define HFA384x_CMDCODE_DOWNLD ((u16)0x22)
/*--- Debugging Commands -----------------------------*/
@@ -327,9 +159,6 @@
#define HFA384x_MONITOR_DISABLE ((u16)(0x0f))
/*--- Result Codes --------------------------*/
-#define HFA384x_SUCCESS ((u16)(0x00))
-#define HFA384x_CARD_FAIL ((u16)(0x01))
-#define HFA384x_NO_BUFF ((u16)(0x05))
#define HFA384x_CMD_ERR ((u16)(0x7F))
/*--- Programming Modes --------------------------
@@ -343,16 +172,6 @@
#define HFA384x_PROGMODE_NV ((u16)0x02)
#define HFA384x_PROGMODE_NVWRITE ((u16)0x03)
-/*--- AUX register enable --------------------------*/
-#define HFA384x_AUXPW0 ((u16)0xfe01)
-#define HFA384x_AUXPW1 ((u16)0xdc23)
-#define HFA384x_AUXPW2 ((u16)0xba45)
-
-#define HFA384x_CONTROL_AUX_ISDISABLED ((u16)0x0000)
-#define HFA384x_CONTROL_AUX_ISENABLED ((u16)0xc000)
-#define HFA384x_CONTROL_AUX_DOENABLE ((u16)0x8000)
-#define HFA384x_CONTROL_AUX_DODISABLE ((u16)0x4000)
-
/*--- Record ID Constants --------------------------*/
/*--------------------------------------------------------------------
Configuration RIDs: Network Parameters, Static Configuration Entities
@@ -362,133 +181,25 @@ Configuration RIDs: Network Parameters, Static Configuration Entities
#define HFA384x_RID_CNFDESIREDSSID ((u16)0xFC02)
#define HFA384x_RID_CNFOWNCHANNEL ((u16)0xFC03)
#define HFA384x_RID_CNFOWNSSID ((u16)0xFC04)
-#define HFA384x_RID_CNFOWNATIMWIN ((u16)0xFC05)
-#define HFA384x_RID_CNFSYSSCALE ((u16)0xFC06)
#define HFA384x_RID_CNFMAXDATALEN ((u16)0xFC07)
-#define HFA384x_RID_CNFWDSADDR ((u16)0xFC08)
-#define HFA384x_RID_CNFPMENABLED ((u16)0xFC09)
-#define HFA384x_RID_CNFPMEPS ((u16)0xFC0A)
-#define HFA384x_RID_CNFMULTICASTRX ((u16)0xFC0B)
-#define HFA384x_RID_CNFMAXSLEEPDUR ((u16)0xFC0C)
-#define HFA384x_RID_CNFPMHOLDDUR ((u16)0xFC0D)
-#define HFA384x_RID_CNFOWNNAME ((u16)0xFC0E)
-#define HFA384x_RID_CNFOWNDTIMPER ((u16)0xFC10)
-#define HFA384x_RID_CNFWDSADDR1 ((u16)0xFC11)
-#define HFA384x_RID_CNFWDSADDR2 ((u16)0xFC12)
-#define HFA384x_RID_CNFWDSADDR3 ((u16)0xFC13)
-#define HFA384x_RID_CNFWDSADDR4 ((u16)0xFC14)
-#define HFA384x_RID_CNFWDSADDR5 ((u16)0xFC15)
-#define HFA384x_RID_CNFWDSADDR6 ((u16)0xFC16)
-#define HFA384x_RID_CNFMCASTPMBUFF ((u16)0xFC17)
/*--------------------------------------------------------------------
Configuration RID lengths: Network Params, Static Config Entities
This is the length of JUST the DATA part of the RID (does not
include the len or code fields)
--------------------------------------------------------------------*/
-/* TODO: fill in the rest of these */
-#define HFA384x_RID_CNFPORTTYPE_LEN ((u16)2)
#define HFA384x_RID_CNFOWNMACADDR_LEN ((u16)6)
#define HFA384x_RID_CNFDESIREDSSID_LEN ((u16)34)
-#define HFA384x_RID_CNFOWNCHANNEL_LEN ((u16)2)
#define HFA384x_RID_CNFOWNSSID_LEN ((u16)34)
-#define HFA384x_RID_CNFOWNATIMWIN_LEN ((u16)2)
-#define HFA384x_RID_CNFSYSSCALE_LEN ((u16)0)
-#define HFA384x_RID_CNFMAXDATALEN_LEN ((u16)0)
-#define HFA384x_RID_CNFWDSADDR_LEN ((u16)6)
-#define HFA384x_RID_CNFPMENABLED_LEN ((u16)0)
-#define HFA384x_RID_CNFPMEPS_LEN ((u16)0)
-#define HFA384x_RID_CNFMULTICASTRX_LEN ((u16)0)
-#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((u16)0)
-#define HFA384x_RID_CNFPMHOLDDUR_LEN ((u16)0)
-#define HFA384x_RID_CNFOWNNAME_LEN ((u16)34)
-#define HFA384x_RID_CNFOWNDTIMPER_LEN ((u16)0)
-#define HFA384x_RID_CNFWDSADDR1_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR2_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR3_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR4_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR5_LEN ((u16)6)
-#define HFA384x_RID_CNFWDSADDR6_LEN ((u16)6)
-#define HFA384x_RID_CNFMCASTPMBUFF_LEN ((u16)0)
-#define HFA384x_RID_CNFAUTHENTICATION_LEN ((u16)sizeof(u16))
-#define HFA384x_RID_CNFMAXSLEEPDUR_LEN ((u16)0)
/*--------------------------------------------------------------------
Configuration RIDs: Network Parameters, Dynamic Configuration Entities
--------------------------------------------------------------------*/
-#define HFA384x_RID_GROUPADDR ((u16)0xFC80)
#define HFA384x_RID_CREATEIBSS ((u16)0xFC81)
#define HFA384x_RID_FRAGTHRESH ((u16)0xFC82)
#define HFA384x_RID_RTSTHRESH ((u16)0xFC83)
#define HFA384x_RID_TXRATECNTL ((u16)0xFC84)
#define HFA384x_RID_PROMISCMODE ((u16)0xFC85)
-#define HFA384x_RID_FRAGTHRESH0 ((u16)0xFC90)
-#define HFA384x_RID_FRAGTHRESH1 ((u16)0xFC91)
-#define HFA384x_RID_FRAGTHRESH2 ((u16)0xFC92)
-#define HFA384x_RID_FRAGTHRESH3 ((u16)0xFC93)
-#define HFA384x_RID_FRAGTHRESH4 ((u16)0xFC94)
-#define HFA384x_RID_FRAGTHRESH5 ((u16)0xFC95)
-#define HFA384x_RID_FRAGTHRESH6 ((u16)0xFC96)
-#define HFA384x_RID_RTSTHRESH0 ((u16)0xFC97)
-#define HFA384x_RID_RTSTHRESH1 ((u16)0xFC98)
-#define HFA384x_RID_RTSTHRESH2 ((u16)0xFC99)
-#define HFA384x_RID_RTSTHRESH3 ((u16)0xFC9A)
-#define HFA384x_RID_RTSTHRESH4 ((u16)0xFC9B)
-#define HFA384x_RID_RTSTHRESH5 ((u16)0xFC9C)
-#define HFA384x_RID_RTSTHRESH6 ((u16)0xFC9D)
-#define HFA384x_RID_TXRATECNTL0 ((u16)0xFC9E)
-#define HFA384x_RID_TXRATECNTL1 ((u16)0xFC9F)
-#define HFA384x_RID_TXRATECNTL2 ((u16)0xFCA0)
-#define HFA384x_RID_TXRATECNTL3 ((u16)0xFCA1)
-#define HFA384x_RID_TXRATECNTL4 ((u16)0xFCA2)
-#define HFA384x_RID_TXRATECNTL5 ((u16)0xFCA3)
-#define HFA384x_RID_TXRATECNTL6 ((u16)0xFCA4)
-
-/*--------------------------------------------------------------------
-Configuration RID Lengths: Network Param, Dynamic Config Entities
- This is the length of JUST the DATA part of the RID (does not
- include the len or code fields)
---------------------------------------------------------------------*/
-/* TODO: fill in the rest of these */
-#define HFA384x_RID_GROUPADDR_LEN ((u16)16 * WLAN_ADDR_LEN)
-#define HFA384x_RID_CREATEIBSS_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL_LEN ((u16)4)
-#define HFA384x_RID_PROMISCMODE_LEN ((u16)2)
-#define HFA384x_RID_FRAGTHRESH0_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH1_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH2_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH3_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH4_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH5_LEN ((u16)0)
-#define HFA384x_RID_FRAGTHRESH6_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH0_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH1_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH2_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH3_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH4_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH5_LEN ((u16)0)
-#define HFA384x_RID_RTSTHRESH6_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL0_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL1_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL2_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL3_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL4_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL5_LEN ((u16)0)
-#define HFA384x_RID_TXRATECNTL6_LEN ((u16)0)
-
-/*--------------------------------------------------------------------
-Configuration RIDs: Behavior Parameters
---------------------------------------------------------------------*/
-#define HFA384x_RID_ITICKTIME ((u16)0xFCE0)
-
-/*--------------------------------------------------------------------
-Configuration RID Lengths: Behavior Parameters
- This is the length of JUST the DATA part of the RID (does not
- include the len or code fields)
---------------------------------------------------------------------*/
-#define HFA384x_RID_ITICKTIME_LEN ((u16)2)
/*----------------------------------------------------------------------
Information RIDs: NIC Information
@@ -502,41 +213,17 @@ Information RIDs: NIC Information
#define HFA384x_RID_NICIDENTITY ((u16)0xFD0B)
#define HFA384x_RID_MFISUPRANGE ((u16)0xFD0C)
#define HFA384x_RID_CFISUPRANGE ((u16)0xFD0D)
-#define HFA384x_RID_CHANNELLIST ((u16)0xFD10)
-#define HFA384x_RID_REGULATORYDOMAINS ((u16)0xFD11)
-#define HFA384x_RID_TEMPTYPE ((u16)0xFD12)
-#define HFA384x_RID_CIS ((u16)0xFD13)
#define HFA384x_RID_STAIDENTITY ((u16)0xFD20)
#define HFA384x_RID_STASUPRANGE ((u16)0xFD21)
#define HFA384x_RID_STA_MFIACTRANGES ((u16)0xFD22)
#define HFA384x_RID_STA_CFIACTRANGES ((u16)0xFD23)
-#define HFA384x_RID_BUILDSEQ ((u16)0xFFFE)
-#define HFA384x_RID_FWID ((u16)0xFFFF)
/*----------------------------------------------------------------------
Information RID Lengths: NIC Information
This is the length of JUST the DATA part of the RID (does not
include the len or code fields)
--------------------------------------------------------------------*/
-#define HFA384x_RID_MAXLOADTIME_LEN ((u16)0)
-#define HFA384x_RID_DOWNLOADBUFFER_LEN ((u16)sizeof(hfa384x_downloadbuffer_t))
-#define HFA384x_RID_PRIIDENTITY_LEN ((u16)8)
-#define HFA384x_RID_PRISUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_CFIACTRANGES_LEN ((u16)10)
#define HFA384x_RID_NICSERIALNUMBER_LEN ((u16)12)
-#define HFA384x_RID_NICIDENTITY_LEN ((u16)8)
-#define HFA384x_RID_MFISUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_CFISUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_CHANNELLIST_LEN ((u16)0)
-#define HFA384x_RID_REGULATORYDOMAINS_LEN ((u16)12)
-#define HFA384x_RID_TEMPTYPE_LEN ((u16)0)
-#define HFA384x_RID_CIS_LEN ((u16)480)
-#define HFA384x_RID_STAIDENTITY_LEN ((u16)8)
-#define HFA384x_RID_STASUPRANGE_LEN ((u16)10)
-#define HFA384x_RID_MFIACTRANGES_LEN ((u16)10)
-#define HFA384x_RID_CFIACTRANGES2_LEN ((u16)10)
-#define HFA384x_RID_BUILDSEQ_LEN ((u16)sizeof(hfa384x_BuildSeq_t))
-#define HFA384x_RID_FWID_LEN ((u16)sizeof(hfa384x_FWID_t))
/*--------------------------------------------------------------------
Information RIDs: MAC Information
@@ -544,87 +231,25 @@ Information RIDs: MAC Information
#define HFA384x_RID_PORTSTATUS ((u16)0xFD40)
#define HFA384x_RID_CURRENTSSID ((u16)0xFD41)
#define HFA384x_RID_CURRENTBSSID ((u16)0xFD42)
-#define HFA384x_RID_COMMSQUALITY ((u16)0xFD43)
#define HFA384x_RID_CURRENTTXRATE ((u16)0xFD44)
-#define HFA384x_RID_CURRENTBCNint ((u16)0xFD45)
-#define HFA384x_RID_CURRENTSCALETHRESH ((u16)0xFD46)
-#define HFA384x_RID_PROTOCOLRSPTIME ((u16)0xFD47)
#define HFA384x_RID_SHORTRETRYLIMIT ((u16)0xFD48)
#define HFA384x_RID_LONGRETRYLIMIT ((u16)0xFD49)
#define HFA384x_RID_MAXTXLIFETIME ((u16)0xFD4A)
-#define HFA384x_RID_MAXRXLIFETIME ((u16)0xFD4B)
-#define HFA384x_RID_CFPOLLABLE ((u16)0xFD4C)
-#define HFA384x_RID_AUTHALGORITHMS ((u16)0xFD4D)
#define HFA384x_RID_PRIVACYOPTIMP ((u16)0xFD4F)
#define HFA384x_RID_DBMCOMMSQUALITY ((u16)0xFD51)
-#define HFA384x_RID_CURRENTTXRATE1 ((u16)0xFD80)
-#define HFA384x_RID_CURRENTTXRATE2 ((u16)0xFD81)
-#define HFA384x_RID_CURRENTTXRATE3 ((u16)0xFD82)
-#define HFA384x_RID_CURRENTTXRATE4 ((u16)0xFD83)
-#define HFA384x_RID_CURRENTTXRATE5 ((u16)0xFD84)
-#define HFA384x_RID_CURRENTTXRATE6 ((u16)0xFD85)
-#define HFA384x_RID_OWNMACADDRESS ((u16)0xFD86)
-// #define HFA384x_RID_PCFINFO ((u16)0xFD87)
-#define HFA384x_RID_SCANRESULTS ((u16)0xFD88) // NEW
-#define HFA384x_RID_HOSTSCANRESULTS ((u16)0xFD89) // NEW
-#define HFA384x_RID_AUTHENTICATIONUSED ((u16)0xFD8A) // NEW
-#define HFA384x_RID_ASSOCIATEFAILURE ((u16)0xFD8D) // 1.8.0
/*--------------------------------------------------------------------
Information RID Lengths: MAC Information
This is the length of JUST the DATA part of the RID (does not
include the len or code fields)
--------------------------------------------------------------------*/
-#define HFA384x_RID_PORTSTATUS_LEN ((u16)0)
-#define HFA384x_RID_CURRENTSSID_LEN ((u16)34)
-#define HFA384x_RID_CURRENTBSSID_LEN ((u16)WLAN_BSSID_LEN)
-#define HFA384x_RID_COMMSQUALITY_LEN ((u16)sizeof(hfa384x_commsquality_t))
#define HFA384x_RID_DBMCOMMSQUALITY_LEN ((u16)sizeof(hfa384x_dbmcommsquality_t))
-#define HFA384x_RID_CURRENTTXRATE_LEN ((u16)0)
-#define HFA384x_RID_CURRENTBCNint_LEN ((u16)0)
-#define HFA384x_RID_STACURSCALETHRESH_LEN ((u16)12)
-#define HFA384x_RID_APCURSCALETHRESH_LEN ((u16)6)
-#define HFA384x_RID_PROTOCOLRSPTIME_LEN ((u16)0)
-#define HFA384x_RID_SHORTRETRYLIMIT_LEN ((u16)0)
-#define HFA384x_RID_LONGRETRYLIMIT_LEN ((u16)0)
-#define HFA384x_RID_MAXTXLIFETIME_LEN ((u16)0)
-#define HFA384x_RID_MAXRXLIFETIME_LEN ((u16)0)
-#define HFA384x_RID_CFPOLLABLE_LEN ((u16)0)
-#define HFA384x_RID_AUTHALGORITHMS_LEN ((u16)4)
-#define HFA384x_RID_PRIVACYOPTIMP_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE1_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE2_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE3_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE4_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE5_LEN ((u16)0)
-#define HFA384x_RID_CURRENTTXRATE6_LEN ((u16)0)
-#define HFA384x_RID_OWNMACADDRESS_LEN ((u16)6)
-#define HFA384x_RID_PCFINFO_LEN ((u16)6)
-#define HFA384x_RID_CNFAPPCFINFO_LEN ((u16)sizeof(hfa384x_PCFInfo_data_t))
-#define HFA384x_RID_SCANREQUEST_LEN ((u16)sizeof(hfa384x_ScanRequest_data_t))
#define HFA384x_RID_JOINREQUEST_LEN ((u16)sizeof(hfa384x_JoinRequest_data_t))
-#define HFA384x_RID_AUTHENTICATESTA_LEN ((u16)sizeof(hfa384x_authenticateStation_data_t))
-#define HFA384x_RID_CHANNELINFOREQUEST_LEN ((u16)sizeof(hfa384x_ChannelInfoRequest_data_t))
+
/*--------------------------------------------------------------------
Information RIDs: Modem Information
--------------------------------------------------------------------*/
-#define HFA384x_RID_PHYTYPE ((u16)0xFDC0)
#define HFA384x_RID_CURRENTCHANNEL ((u16)0xFDC1)
-#define HFA384x_RID_CURRENTPOWERSTATE ((u16)0xFDC2)
-#define HFA384x_RID_CCAMODE ((u16)0xFDC3)
-#define HFA384x_RID_SUPPORTEDDATARATES ((u16)0xFDC6)
-#define HFA384x_RID_LFOSTATUS ((u16)0xFDC7) // 1.7.1
-
-/*--------------------------------------------------------------------
-Information RID Lengths: Modem Information
- This is the length of JUST the DATA part of the RID (does not
- include the len or code fields)
---------------------------------------------------------------------*/
-#define HFA384x_RID_PHYTYPE_LEN ((u16)0)
-#define HFA384x_RID_CURRENTCHANNEL_LEN ((u16)0)
-#define HFA384x_RID_CURRENTPOWERSTATE_LEN ((u16)0)
-#define HFA384x_RID_CCAMODE_LEN ((u16)0)
-#define HFA384x_RID_SUPPORTEDDATARATES_LEN ((u16)10)
/*--------------------------------------------------------------------
API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
@@ -635,57 +260,22 @@ API ENHANCEMENTS (NOT ALREADY IMPLEMENTED)
#define HFA384x_RID_CNFWEPDEFAULTKEY2 ((u16)0xFC26)
#define HFA384x_RID_CNFWEPDEFAULTKEY3 ((u16)0xFC27)
#define HFA384x_RID_CNFWEPFLAGS ((u16)0xFC28)
-#define HFA384x_RID_CNFWEPKEYMAPTABLE ((u16)0xFC29)
#define HFA384x_RID_CNFAUTHENTICATION ((u16)0xFC2A)
-#define HFA384x_RID_CNFMAXASSOCSTATIONS ((u16)0xFC2B)
-#define HFA384x_RID_CNFTXCONTROL ((u16)0xFC2C)
#define HFA384x_RID_CNFROAMINGMODE ((u16)0xFC2D)
-#define HFA384x_RID_CNFHOSTAUTHASSOC ((u16)0xFC2E)
-#define HFA384x_RID_CNFRCVCRCERROR ((u16)0xFC30)
-// #define HFA384x_RID_CNFMMLIFE ((u16)0xFC31)
-#define HFA384x_RID_CNFALTRETRYCNT ((u16)0xFC32)
#define HFA384x_RID_CNFAPBCNint ((u16)0xFC33)
-#define HFA384x_RID_CNFAPPCFINFO ((u16)0xFC34)
-#define HFA384x_RID_CNFSTAPCFINFO ((u16)0xFC35)
-#define HFA384x_RID_CNFPRIORITYQUSAGE ((u16)0xFC37)
-#define HFA384x_RID_CNFTIMCTRL ((u16)0xFC40)
-#define HFA384x_RID_CNFTHIRTY2TALLY ((u16)0xFC42)
-#define HFA384x_RID_CNFENHSECURITY ((u16)0xFC43)
-#define HFA384x_RID_CNFDBMADJUST ((u16)0xFC46) // NEW
-#define HFA384x_RID_CNFWPADATA ((u16)0xFC48) // 1.7.0
-#define HFA384x_RID_CNFPROPOGATIONDELAY ((u16)0xFC49) // 1.7.6
-#define HFA384x_RID_CNFSHORTPREAMBLE ((u16)0xFCB0)
-#define HFA384x_RID_CNFEXCLONGPREAMBLE ((u16)0xFCB1)
-#define HFA384x_RID_CNFAUTHRSPTIMEOUT ((u16)0xFCB2)
+#define HFA384x_RID_CNFDBMADJUST ((u16)0xFC46)
+#define HFA384x_RID_CNFWPADATA ((u16)0xFC48)
#define HFA384x_RID_CNFBASICRATES ((u16)0xFCB3)
#define HFA384x_RID_CNFSUPPRATES ((u16)0xFCB4)
-#define HFA384x_RID_CNFFALLBACKCTRL ((u16)0xFCB5) // NEW
-#define HFA384x_RID_WEPKEYSTATUS ((u16)0xFCB6) // NEW
-#define HFA384x_RID_WEPKEYMAPINDEX ((u16)0xFCB7) // NEW
-#define HFA384x_RID_BROADCASTKEYID ((u16)0xFCB8) // NEW
-#define HFA384x_RID_ENTSECFLAGEYID ((u16)0xFCB9) // NEW
-#define HFA384x_RID_CNFPASSIVESCANCTRL ((u16)0xFCBA) // NEW STA
-#define HFA384x_RID_CNFWPAHANDLING ((u16)0xFCBB) // 1.7.0
-#define HFA384x_RID_MDCCONTROL ((u16)0xFCBC) // 1.7.0/1.4.0
-#define HFA384x_RID_MDCCOUNTRY ((u16)0xFCBD) // 1.7.0/1.4.0
-#define HFA384x_RID_TXPOWERMAX ((u16)0xFCBE) // 1.7.0/1.4.0
-#define HFA384x_RID_CNFLFOENBLED ((u16)0xFCBF) // 1.6.3
-#define HFA384x_RID_CAPINFO ((u16)0xFCC0) // 1.7.0/1.3.7
-#define HFA384x_RID_LISTENintERVAL ((u16)0xFCC1) // 1.7.0/1.3.7
-#define HFA384x_RID_DIVERSITYENABLED ((u16)0xFCC2) // 1.7.0/1.3.7
-#define HFA384x_RID_LED_CONTROL ((u16)0xFCC4) // 1.7.6
-#define HFA384x_RID_HFO_DELAY ((u16)0xFCC5) // 1.7.6
-#define HFA384x_RID_DISSALOWEDBSSID ((u16)0xFCC6) // 1.8.0
-#define HFA384x_RID_SCANREQUEST ((u16)0xFCE1)
+#define HFA384x_RID_CNFPASSIVESCANCTRL ((u16)0xFCBA)
+#define HFA384x_RID_TXPOWERMAX ((u16)0xFCBE)
#define HFA384x_RID_JOINREQUEST ((u16)0xFCE2)
#define HFA384x_RID_AUTHENTICATESTA ((u16)0xFCE3)
-#define HFA384x_RID_CHANNELINFOREQUEST ((u16)0xFCE4)
-#define HFA384x_RID_HOSTSCAN ((u16)0xFCE5) // NEW STA
-#define HFA384x_RID_ASSOCIATESTA ((u16)0xFCE6)
+#define HFA384x_RID_HOSTSCAN ((u16)0xFCE5)
#define HFA384x_RID_CNFWEPDEFAULTKEY_LEN ((u16)6)
#define HFA384x_RID_CNFWEP128DEFAULTKEY_LEN ((u16)14)
-#define HFA384x_RID_CNFPRIOQUSAGE_LEN ((u16)4)
+
/*--------------------------------------------------------------------
PD Record codes
--------------------------------------------------------------------*/
@@ -697,22 +287,11 @@ PD Record codes
#define HFA384x_PDR_MFISUPRANGE ((u16)0x0006)
#define HFA384x_PDR_CFISUPRANGE ((u16)0x0007)
#define HFA384x_PDR_NICID ((u16)0x0008)
-//#define HFA384x_PDR_REFDAC_MEASUREMENTS ((u16)0x0010)
-//#define HFA384x_PDR_VGDAC_MEASUREMENTS ((u16)0x0020)
-//#define HFA384x_PDR_LEVEL_COMP_MEASUREMENTS ((u16)0x0030)
-//#define HFA384x_PDR_MODEM_TRIMDAC_MEASUREMENTS ((u16)0x0040)
-//#define HFA384x_PDR_COREGA_HACK ((u16)0x00ff)
#define HFA384x_PDR_MAC_ADDRESS ((u16)0x0101)
-//#define HFA384x_PDR_MKK_CALLNAME ((u16)0x0102)
#define HFA384x_PDR_REGDOMAIN ((u16)0x0103)
#define HFA384x_PDR_ALLOWED_CHANNEL ((u16)0x0104)
#define HFA384x_PDR_DEFAULT_CHANNEL ((u16)0x0105)
-//#define HFA384x_PDR_PRIVACY_OPTION ((u16)0x0106)
#define HFA384x_PDR_TEMPTYPE ((u16)0x0107)
-//#define HFA384x_PDR_REFDAC_SETUP ((u16)0x0110)
-//#define HFA384x_PDR_VGDAC_SETUP ((u16)0x0120)
-//#define HFA384x_PDR_LEVEL_COMP_SETUP ((u16)0x0130)
-//#define HFA384x_PDR_TRIMDAC_SETUP ((u16)0x0140)
#define HFA384x_PDR_IFR_SETTING ((u16)0x0200)
#define HFA384x_PDR_RFR_SETTING ((u16)0x0201)
#define HFA384x_PDR_HFA3861_BASELINE ((u16)0x0202)
@@ -729,7 +308,6 @@ PD Record codes
#define HFA384x_PDR_PCI_PMCONF ((u16)0x0404)
#define HFA384x_PDR_RFENRGY ((u16)0x0406)
#define HFA384x_PDR_USB_POWER_TYPE ((u16)0x0407)
-//#define HFA384x_PDR_UNKNOWN408 ((u16)0x0408)
#define HFA384x_PDR_USB_MAX_POWER ((u16)0x0409)
#define HFA384x_PDR_USB_MANUFACTURER ((u16)0x0410)
#define HFA384x_PDR_USB_PRODUCT ((u16)0x0411)
@@ -741,831 +319,122 @@ PD Record codes
#define HFA384x_PDR_HFA3861_MANF_TESTI ((u16)0x0901)
#define HFA384x_PDR_END_OF_PDA ((u16)0x0000)
-
-/*=============================================================*/
-/*------ Macros -----------------------------------------------*/
-
-/*--- Register ID macros ------------------------*/
-
-#define HFA384x_CMD HFA384x_CMD_OFF
-#define HFA384x_PARAM0 HFA384x_PARAM0_OFF
-#define HFA384x_PARAM1 HFA384x_PARAM1_OFF
-#define HFA384x_PARAM2 HFA384x_PARAM2_OFF
-#define HFA384x_STATUS HFA384x_STATUS_OFF
-#define HFA384x_RESP0 HFA384x_RESP0_OFF
-#define HFA384x_RESP1 HFA384x_RESP1_OFF
-#define HFA384x_RESP2 HFA384x_RESP2_OFF
-#define HFA384x_INFOFID HFA384x_INFOFID_OFF
-#define HFA384x_RXFID HFA384x_RXFID_OFF
-#define HFA384x_ALLOCFID HFA384x_ALLOCFID_OFF
-#define HFA384x_TXCOMPLFID HFA384x_TXCOMPLFID_OFF
-#define HFA384x_SELECT0 HFA384x_SELECT0_OFF
-#define HFA384x_OFFSET0 HFA384x_OFFSET0_OFF
-#define HFA384x_DATA0 HFA384x_DATA0_OFF
-#define HFA384x_SELECT1 HFA384x_SELECT1_OFF
-#define HFA384x_OFFSET1 HFA384x_OFFSET1_OFF
-#define HFA384x_DATA1 HFA384x_DATA1_OFF
-#define HFA384x_EVSTAT HFA384x_EVSTAT_OFF
-#define HFA384x_intEN HFA384x_INTEN_OFF
-#define HFA384x_EVACK HFA384x_EVACK_OFF
-#define HFA384x_CONTROL HFA384x_CONTROL_OFF
-#define HFA384x_SWSUPPORT0 HFA384x_SWSUPPORT0_OFF
-#define HFA384x_SWSUPPORT1 HFA384x_SWSUPPORT1_OFF
-#define HFA384x_SWSUPPORT2 HFA384x_SWSUPPORT2_OFF
-#define HFA384x_AUXPAGE HFA384x_AUXPAGE_OFF
-#define HFA384x_AUXOFFSET HFA384x_AUXOFFSET_OFF
-#define HFA384x_AUXDATA HFA384x_AUXDATA_OFF
-#define HFA384x_PCICOR HFA384x_PCICOR_OFF
-#define HFA384x_PCIHCR HFA384x_PCIHCR_OFF
-
-
/*--- Register Test/Get/Set Field macros ------------------------*/
-#define HFA384x_CMD_ISBUSY(value) ((u16)(((u16)value) & HFA384x_CMD_BUSY))
-#define HFA384x_CMD_AINFO_GET(value) ((u16)(((u16)(value) & HFA384x_CMD_AINFO) >> 8))
#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8))
-#define HFA384x_CMD_MACPORT_GET(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_MACPORT)))
#define HFA384x_CMD_MACPORT_SET(value) ((u16)HFA384x_CMD_AINFO_SET(value))
-#define HFA384x_CMD_ISRECL(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_RECL)))
-#define HFA384x_CMD_RECL_SET(value) ((u16)HFA384x_CMD_AINFO_SET(value))
-#define HFA384x_CMD_QOS_GET(value) ((u16)((((u16)(value))&((u16)0x3000)) >> 12))
-#define HFA384x_CMD_QOS_SET(value) ((u16)((((u16)(value)) << 12) & 0x3000))
-#define HFA384x_CMD_ISWRITE(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_WRITE)))
-#define HFA384x_CMD_WRITE_SET(value) ((u16)HFA384x_CMD_AINFO_SET((u16)value))
-#define HFA384x_CMD_PROGMODE_GET(value) ((u16)(HFA384x_CMD_AINFO_GET((u16)(value) & HFA384x_CMD_PROGMODE)))
#define HFA384x_CMD_PROGMODE_SET(value) ((u16)HFA384x_CMD_AINFO_SET((u16)value))
-#define HFA384x_CMD_CMDCODE_GET(value) ((u16)(((u16)(value)) & HFA384x_CMD_CMDCODE))
#define HFA384x_CMD_CMDCODE_SET(value) ((u16)(value))
-#define HFA384x_STATUS_RESULT_GET(value) ((u16)((((u16)(value)) & HFA384x_STATUS_RESULT) >> 8))
#define HFA384x_STATUS_RESULT_SET(value) (((u16)(value)) << 8)
-#define HFA384x_STATUS_CMDCODE_GET(value) (((u16)(value)) & HFA384x_STATUS_CMDCODE)
-#define HFA384x_STATUS_CMDCODE_SET(value) ((u16)(value))
-
-#define HFA384x_OFFSET_ISBUSY(value) ((u16)(((u16)(value)) & HFA384x_OFFSET_BUSY))
-#define HFA384x_OFFSET_ISERR(value) ((u16)(((u16)(value)) & HFA384x_OFFSET_ERR))
-#define HFA384x_OFFSET_DATAOFF_GET(value) ((u16)(((u16)(value)) & HFA384x_OFFSET_DATAOFF))
-#define HFA384x_OFFSET_DATAOFF_SET(value) ((u16)(value))
-
-#define HFA384x_EVSTAT_ISTICK(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_TICK))
-#define HFA384x_EVSTAT_ISWTERR(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_WTERR))
-#define HFA384x_EVSTAT_ISINFDROP(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_INFDROP))
-#define HFA384x_EVSTAT_ISINFO(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_INFO))
-#define HFA384x_EVSTAT_ISDTIM(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_DTIM))
-#define HFA384x_EVSTAT_ISCMD(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_CMD))
-#define HFA384x_EVSTAT_ISALLOC(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_ALLOC))
-#define HFA384x_EVSTAT_ISTXEXC(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_TXEXC))
-#define HFA384x_EVSTAT_ISTX(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_TX))
-#define HFA384x_EVSTAT_ISRX(value) ((u16)(((u16)(value)) & HFA384x_EVSTAT_RX))
-
-#define HFA384x_EVSTAT_ISBAP_OP(value) ((u16)(((u16)(value)) & HFA384x_int_BAP_OP))
-
-#define HFA384x_intEN_ISTICK(value) ((u16)(((u16)(value)) & HFA384x_INTEN_TICK))
-#define HFA384x_intEN_TICK_SET(value) ((u16)(((u16)(value)) << 15))
-#define HFA384x_intEN_ISWTERR(value) ((u16)(((u16)(value)) & HFA384x_INTEN_WTERR))
-#define HFA384x_intEN_WTERR_SET(value) ((u16)(((u16)(value)) << 14))
-#define HFA384x_intEN_ISINFDROP(value) ((u16)(((u16)(value)) & HFA384x_INTEN_INFDROP))
-#define HFA384x_intEN_INFDROP_SET(value) ((u16)(((u16)(value)) << 13))
-#define HFA384x_intEN_ISINFO(value) ((u16)(((u16)(value)) & HFA384x_INTEN_INFO))
-#define HFA384x_intEN_INFO_SET(value) ((u16)(((u16)(value)) << 7))
-#define HFA384x_intEN_ISDTIM(value) ((u16)(((u16)(value)) & HFA384x_INTEN_DTIM))
-#define HFA384x_intEN_DTIM_SET(value) ((u16)(((u16)(value)) << 5))
-#define HFA384x_intEN_ISCMD(value) ((u16)(((u16)(value)) & HFA384x_INTEN_CMD))
-#define HFA384x_intEN_CMD_SET(value) ((u16)(((u16)(value)) << 4))
-#define HFA384x_intEN_ISALLOC(value) ((u16)(((u16)(value)) & HFA384x_INTEN_ALLOC))
-#define HFA384x_intEN_ALLOC_SET(value) ((u16)(((u16)(value)) << 3))
-#define HFA384x_intEN_ISTXEXC(value) ((u16)(((u16)(value)) & HFA384x_INTEN_TXEXC))
-#define HFA384x_intEN_TXEXC_SET(value) ((u16)(((u16)(value)) << 2))
-#define HFA384x_intEN_ISTX(value) ((u16)(((u16)(value)) & HFA384x_INTEN_TX))
-#define HFA384x_intEN_TX_SET(value) ((u16)(((u16)(value)) << 1))
-#define HFA384x_intEN_ISRX(value) ((u16)(((u16)(value)) & HFA384x_INTEN_RX))
-#define HFA384x_intEN_RX_SET(value) ((u16)(((u16)(value)) << 0))
-
-#define HFA384x_EVACK_ISTICK(value) ((u16)(((u16)(value)) & HFA384x_EVACK_TICK))
-#define HFA384x_EVACK_TICK_SET(value) ((u16)(((u16)(value)) << 15))
-#define HFA384x_EVACK_ISWTERR(value) ((u16)(((u16)(value)) & HFA384x_EVACK_WTERR))
-#define HFA384x_EVACK_WTERR_SET(value) ((u16)(((u16)(value)) << 14))
-#define HFA384x_EVACK_ISINFDROP(value) ((u16)(((u16)(value)) & HFA384x_EVACK_INFDROP))
-#define HFA384x_EVACK_INFDROP_SET(value) ((u16)(((u16)(value)) << 13))
-#define HFA384x_EVACK_ISINFO(value) ((u16)(((u16)(value)) & HFA384x_EVACK_INFO))
-#define HFA384x_EVACK_INFO_SET(value) ((u16)(((u16)(value)) << 7))
-#define HFA384x_EVACK_ISDTIM(value) ((u16)(((u16)(value)) & HFA384x_EVACK_DTIM))
-#define HFA384x_EVACK_DTIM_SET(value) ((u16)(((u16)(value)) << 5))
-#define HFA384x_EVACK_ISCMD(value) ((u16)(((u16)(value)) & HFA384x_EVACK_CMD))
-#define HFA384x_EVACK_CMD_SET(value) ((u16)(((u16)(value)) << 4))
-#define HFA384x_EVACK_ISALLOC(value) ((u16)(((u16)(value)) & HFA384x_EVACK_ALLOC))
-#define HFA384x_EVACK_ALLOC_SET(value) ((u16)(((u16)(value)) << 3))
-#define HFA384x_EVACK_ISTXEXC(value) ((u16)(((u16)(value)) & HFA384x_EVACK_TXEXC))
-#define HFA384x_EVACK_TXEXC_SET(value) ((u16)(((u16)(value)) << 2))
-#define HFA384x_EVACK_ISTX(value) ((u16)(((u16)(value)) & HFA384x_EVACK_TX))
-#define HFA384x_EVACK_TX_SET(value) ((u16)(((u16)(value)) << 1))
-#define HFA384x_EVACK_ISRX(value) ((u16)(((u16)(value)) & HFA384x_EVACK_RX))
-#define HFA384x_EVACK_RX_SET(value) ((u16)(((u16)(value)) << 0))
-
-#define HFA384x_CONTROL_AUXEN_SET(value) ((u16)(((u16)(value)) << 14))
-#define HFA384x_CONTROL_AUXEN_GET(value) ((u16)(((u16)(value)) >> 14))
-
-/* Byte Order */
-#ifdef __KERNEL__
-#define hfa384x2host_16(n) (__le16_to_cpu((u16)(n)))
-#define hfa384x2host_32(n) (__le32_to_cpu((u32)(n)))
-#define host2hfa384x_16(n) (__cpu_to_le16((u16)(n)))
-#define host2hfa384x_32(n) (__cpu_to_le32((u32)(n)))
-#endif
/* Host Maintained State Info */
#define HFA384x_STATE_PREINIT 0
#define HFA384x_STATE_INIT 1
#define HFA384x_STATE_RUNNING 2
-/*=============================================================*/
-/*------ Types and their related constants --------------------*/
-
-#define HFA384x_HOSTAUTHASSOC_HOSTAUTH BIT0
-#define HFA384x_HOSTAUTHASSOC_HOSTASSOC BIT1
-
-#define HFA384x_WHAHANDLING_DISABLED 0
-#define HFA384x_WHAHANDLING_PASSTHROUGH BIT1
-
/*-------------------------------------------------------------*/
/* Commonly used basic types */
-typedef struct hfa384x_bytestr
-{
- u16 len;
- u8 data[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_bytestr_t;
+typedef struct hfa384x_bytestr {
+ u16 len;
+ u8 data[0];
+} __attribute__ ((packed)) hfa384x_bytestr_t;
-typedef struct hfa384x_bytestr32
-{
- u16 len;
- u8 data[32];
-} __WLAN_ATTRIB_PACK__ hfa384x_bytestr32_t;
+typedef struct hfa384x_bytestr32 {
+ u16 len;
+ u8 data[32];
+} __attribute__ ((packed)) hfa384x_bytestr32_t;
/*--------------------------------------------------------------------
Configuration Record Structures:
Network Parameters, Static Configuration Entities
--------------------------------------------------------------------*/
-/* Prototype structure: all configuration record structures start with
-these members */
-
-typedef struct hfa384x_record
-{
- u16 reclen;
- u16 rid;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec_t;
-
-typedef struct hfa384x_record16
-{
- u16 reclen;
- u16 rid;
- u16 val;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec16_t;
-
-typedef struct hfa384x_record32
-{
- u16 reclen;
- u16 rid;
- u32 val;
-} __WLAN_ATTRIB_PACK__ hfa384x_rec32;
/*-- Hardware/Firmware Component Information ----------*/
-typedef struct hfa384x_compident
-{
- u16 id;
- u16 variant;
- u16 major;
- u16 minor;
-} __WLAN_ATTRIB_PACK__ hfa384x_compident_t;
-
-typedef struct hfa384x_caplevel
-{
- u16 role;
- u16 id;
- u16 variant;
- u16 bottom;
- u16 top;
-} __WLAN_ATTRIB_PACK__ hfa384x_caplevel_t;
-
-/*-- Configuration Record: cnfPortType --*/
-typedef struct hfa384x_cnfPortType
-{
- u16 cnfPortType;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPortType_t;
-
-/*-- Configuration Record: cnfOwnMACAddress --*/
-typedef struct hfa384x_cnfOwnMACAddress
-{
- u8 cnfOwnMACAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnMACAddress_t;
-
-/*-- Configuration Record: cnfDesiredSSID --*/
-typedef struct hfa384x_cnfDesiredSSID
-{
- u8 cnfDesiredSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfDesiredSSID_t;
-
-/*-- Configuration Record: cnfOwnChannel --*/
-typedef struct hfa384x_cnfOwnChannel
-{
- u16 cnfOwnChannel;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnChannel_t;
-
-/*-- Configuration Record: cnfOwnSSID --*/
-typedef struct hfa384x_cnfOwnSSID
-{
- u8 cnfOwnSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnSSID_t;
-
-/*-- Configuration Record: cnfOwnATIMWindow --*/
-typedef struct hfa384x_cnfOwnATIMWindow
-{
- u16 cnfOwnATIMWindow;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnATIMWindow_t;
-
-/*-- Configuration Record: cnfSystemScale --*/
-typedef struct hfa384x_cnfSystemScale
-{
- u16 cnfSystemScale;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfSystemScale_t;
-
-/*-- Configuration Record: cnfMaxDataLength --*/
-typedef struct hfa384x_cnfMaxDataLength
-{
- u16 cnfMaxDataLength;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxDataLength_t;
-
-/*-- Configuration Record: cnfWDSAddress --*/
-typedef struct hfa384x_cnfWDSAddress
-{
- u8 cnfWDSAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddress_t;
-
-/*-- Configuration Record: cnfPMEnabled --*/
-typedef struct hfa384x_cnfPMEnabled
-{
- u16 cnfPMEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEnabled_t;
-
-/*-- Configuration Record: cnfPMEPS --*/
-typedef struct hfa384x_cnfPMEPS
-{
- u16 cnfPMEPS;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMEPS_t;
-
-/*-- Configuration Record: cnfMulticastReceive --*/
-typedef struct hfa384x_cnfMulticastReceive
-{
- u16 cnfMulticastReceive;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastReceive_t;
+typedef struct hfa384x_compident {
+ u16 id;
+ u16 variant;
+ u16 major;
+ u16 minor;
+} __attribute__ ((packed)) hfa384x_compident_t;
+
+typedef struct hfa384x_caplevel {
+ u16 role;
+ u16 id;
+ u16 variant;
+ u16 bottom;
+ u16 top;
+} __attribute__ ((packed)) hfa384x_caplevel_t;
/*-- Configuration Record: cnfAuthentication --*/
#define HFA384x_CNFAUTHENTICATION_OPENSYSTEM 0x0001
#define HFA384x_CNFAUTHENTICATION_SHAREDKEY 0x0002
#define HFA384x_CNFAUTHENTICATION_LEAP 0x0004
-/*-- Configuration Record: cnfMaxSleepDuration --*/
-typedef struct hfa384x_cnfMaxSleepDuration
-{
- u16 cnfMaxSleepDuration;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMaxSleepDuration_t;
-
-/*-- Configuration Record: cnfPMHoldoverDuration --*/
-typedef struct hfa384x_cnfPMHoldoverDuration
-{
- u16 cnfPMHoldoverDuration;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfPMHoldoverDuration_t;
-
-/*-- Configuration Record: cnfOwnName --*/
-typedef struct hfa384x_cnfOwnName
-{
- u8 cnfOwnName[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnName_t;
-
-/*-- Configuration Record: cnfOwnDTIMPeriod --*/
-typedef struct hfa384x_cnfOwnDTIMPeriod
-{
- u16 cnfOwnDTIMPeriod;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfOwnDTIMPeriod_t;
-
-/*-- Configuration Record: cnfWDSAddress --*/
-typedef struct hfa384x_cnfWDSAddressN
-{
- u8 cnfWDSAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfWDSAddressN_t;
-
-/*-- Configuration Record: cnfMulticastPMBuffering --*/
-typedef struct hfa384x_cnfMulticastPMBuffering
-{
- u16 cnfMulticastPMBuffering;
-} __WLAN_ATTRIB_PACK__ hfa384x_cnfMulticastPMBuffering_t;
-
/*--------------------------------------------------------------------
Configuration Record Structures:
Network Parameters, Dynamic Configuration Entities
--------------------------------------------------------------------*/
-/*-- Configuration Record: GroupAddresses --*/
-typedef struct hfa384x_GroupAddresses
-{
- u8 MACAddress[16][6];
-} __WLAN_ATTRIB_PACK__ hfa384x_GroupAddresses_t;
-
-/*-- Configuration Record: CreateIBSS --*/
-typedef struct hfa384x_CreateIBSS
-{
- u16 CreateIBSS;
-} __WLAN_ATTRIB_PACK__ hfa384x_CreateIBSS_t;
-
#define HFA384x_CREATEIBSS_JOINCREATEIBSS 0
-#define HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS 1
-#define HFA384x_CREATEIBSS_JOINIBSS 2
-#define HFA384x_CREATEIBSS_JOINESS_JOINIBSS 3
-
-/*-- Configuration Record: FragmentationThreshold --*/
-typedef struct hfa384x_FragmentationThreshold
-{
- u16 FragmentationThreshold;
-} __WLAN_ATTRIB_PACK__ hfa384x_FragmentationThreshold_t;
-
-/*-- Configuration Record: RTSThreshold --*/
-typedef struct hfa384x_RTSThreshold
-{
- u16 RTSThreshold;
-} __WLAN_ATTRIB_PACK__ hfa384x_RTSThreshold_t;
-
-/*-- Configuration Record: TxRateControl --*/
-typedef struct hfa384x_TxRateControl
-{
- u16 TxRateControl;
-} __WLAN_ATTRIB_PACK__ hfa384x_TxRateControl_t;
-
-/*-- Configuration Record: PromiscuousMode --*/
-typedef struct hfa384x_PromiscuousMode
-{
- u16 PromiscuousMode;
-} __WLAN_ATTRIB_PACK__ hfa384x_PromiscuousMode_t;
-
-/*-- Configuration Record: ScanRequest (data portion only) --*/
-typedef struct hfa384x_ScanRequest_data
-{
- u16 channelList;
- u16 txRate;
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanRequest_data_t;
/*-- Configuration Record: HostScanRequest (data portion only) --*/
-typedef struct hfa384x_HostScanRequest_data
-{
- u16 channelList;
- u16 txRate;
+typedef struct hfa384x_HostScanRequest_data {
+ u16 channelList;
+ u16 txRate;
hfa384x_bytestr32_t ssid;
-} __WLAN_ATTRIB_PACK__ hfa384x_HostScanRequest_data_t;
+} __attribute__ ((packed)) hfa384x_HostScanRequest_data_t;
/*-- Configuration Record: JoinRequest (data portion only) --*/
-typedef struct hfa384x_JoinRequest_data
-{
- u8 bssid[WLAN_BSSID_LEN];
- u16 channel;
-} __WLAN_ATTRIB_PACK__ hfa384x_JoinRequest_data_t;
+typedef struct hfa384x_JoinRequest_data {
+ u8 bssid[WLAN_BSSID_LEN];
+ u16 channel;
+} __attribute__ ((packed)) hfa384x_JoinRequest_data_t;
/*-- Configuration Record: authenticateStation (data portion only) --*/
-typedef struct hfa384x_authenticateStation_data
-{
- u8 address[WLAN_ADDR_LEN];
- u16 status;
- u16 algorithm;
-} __WLAN_ATTRIB_PACK__ hfa384x_authenticateStation_data_t;
-
-/*-- Configuration Record: associateStation (data portion only) --*/
-typedef struct hfa384x_associateStation_data
-{
- u8 address[WLAN_ADDR_LEN];
- u16 status;
- u16 type;
-} __WLAN_ATTRIB_PACK__ hfa384x_associateStation_data_t;
-
-/*-- Configuration Record: ChannelInfoRequest (data portion only) --*/
-typedef struct hfa384x_ChannelInfoRequest_data
-{
- u16 channelList;
- u16 channelDwellTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChannelInfoRequest_data_t;
-
-/*-- Configuration Record: WEPKeyMapping (data portion only) --*/
-typedef struct hfa384x_WEPKeyMapping
-{
- u8 address[WLAN_ADDR_LEN];
- u16 key_index;
- u8 key[16];
- u8 mic_transmit_key[4];
- u8 mic_receive_key[4];
-} __WLAN_ATTRIB_PACK__ hfa384x_WEPKeyMapping_t;
+typedef struct hfa384x_authenticateStation_data {
+ u8 address[ETH_ALEN];
+ u16 status;
+ u16 algorithm;
+} __attribute__ ((packed)) hfa384x_authenticateStation_data_t;
/*-- Configuration Record: WPAData (data portion only) --*/
-typedef struct hfa384x_WPAData
-{
- u16 datalen;
- u8 data[0]; // max 80
-} __WLAN_ATTRIB_PACK__ hfa384x_WPAData_t;
-
-/*--------------------------------------------------------------------
-Configuration Record Structures: Behavior Parameters
---------------------------------------------------------------------*/
-
-/*-- Configuration Record: TickTime --*/
-typedef struct hfa384x_TickTime
-{
- u16 TickTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_TickTime_t;
+typedef struct hfa384x_WPAData {
+ u16 datalen;
+ u8 data[0]; // max 80
+} __attribute__ ((packed)) hfa384x_WPAData_t;
/*--------------------------------------------------------------------
Information Record Structures: NIC Information
--------------------------------------------------------------------*/
-/*-- Information Record: MaxLoadTime --*/
-typedef struct hfa384x_MaxLoadTime
-{
- u16 MaxLoadTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxLoadTime_t;
-
/*-- Information Record: DownLoadBuffer --*/
/* NOTE: The page and offset are in AUX format */
-typedef struct hfa384x_downloadbuffer
-{
- u16 page;
- u16 offset;
- u16 len;
-} __WLAN_ATTRIB_PACK__ hfa384x_downloadbuffer_t;
-
-/*-- Information Record: PRIIdentity --*/
-typedef struct hfa384x_PRIIdentity
-{
- u16 PRICompID;
- u16 PRIVariant;
- u16 PRIMajorVersion;
- u16 PRIMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_PRIIdentity_t;
-
-/*-- Information Record: PRISupRange --*/
-typedef struct hfa384x_PRISupRange
-{
- u16 PRIRole;
- u16 PRIID;
- u16 PRIVariant;
- u16 PRIBottom;
- u16 PRITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_PRISupRange_t;
-
-/*-- Information Record: CFIActRanges --*/
-typedef struct hfa384x_CFIActRanges
-{
- u16 CFIRole;
- u16 CFIID;
- u16 CFIVariant;
- u16 CFIBottom;
- u16 CFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFIActRanges_t;
-
-/*-- Information Record: NICSerialNumber --*/
-typedef struct hfa384x_NICSerialNumber
-{
- u8 NICSerialNumber[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_NICSerialNumber_t;
-
-/*-- Information Record: NICIdentity --*/
-typedef struct hfa384x_NICIdentity
-{
- u16 NICCompID;
- u16 NICVariant;
- u16 NICMajorVersion;
- u16 NICMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_NICIdentity_t;
-
-/*-- Information Record: MFISupRange --*/
-typedef struct hfa384x_MFISupRange
-{
- u16 MFIRole;
- u16 MFIID;
- u16 MFIVariant;
- u16 MFIBottom;
- u16 MFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_MFISupRange_t;
-
-/*-- Information Record: CFISupRange --*/
-typedef struct hfa384x_CFISupRange
-{
- u16 CFIRole;
- u16 CFIID;
- u16 CFIVariant;
- u16 CFIBottom;
- u16 CFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFISupRange_t;
-
-/*-- Information Record: BUILDSEQ:BuildSeq --*/
-typedef struct hfa384x_BuildSeq {
- u16 primary;
- u16 secondary;
-} __WLAN_ATTRIB_PACK__ hfa384x_BuildSeq_t;
-
-/*-- Information Record: FWID --*/
-#define HFA384x_FWID_LEN 14
-typedef struct hfa384x_FWID {
- u8 primary[HFA384x_FWID_LEN];
- u8 secondary[HFA384x_FWID_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_FWID_t;
-
-/*-- Information Record: ChannelList --*/
-typedef struct hfa384x_ChannelList
-{
- u16 ChannelList;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChannelList_t;
-
-/*-- Information Record: RegulatoryDomains --*/
-typedef struct hfa384x_RegulatoryDomains
-{
- u8 RegulatoryDomains[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_RegulatoryDomains_t;
-
-/*-- Information Record: TempType --*/
-typedef struct hfa384x_TempType
-{
- u16 TempType;
-} __WLAN_ATTRIB_PACK__ hfa384x_TempType_t;
-
-/*-- Information Record: CIS --*/
-typedef struct hfa384x_CIS
-{
- u8 CIS[480];
-} __WLAN_ATTRIB_PACK__ hfa384x_CIS_t;
-
-/*-- Information Record: STAIdentity --*/
-typedef struct hfa384x_STAIdentity
-{
- u16 STACompID;
- u16 STAVariant;
- u16 STAMajorVersion;
- u16 STAMinorVersion;
-} __WLAN_ATTRIB_PACK__ hfa384x_STAIdentity_t;
-
-/*-- Information Record: STASupRange --*/
-typedef struct hfa384x_STASupRange
-{
- u16 STARole;
- u16 STAID;
- u16 STAVariant;
- u16 STABottom;
- u16 STATop;
-} __WLAN_ATTRIB_PACK__ hfa384x_STASupRange_t;
-
-/*-- Information Record: MFIActRanges --*/
-typedef struct hfa384x_MFIActRanges
-{
- u16 MFIRole;
- u16 MFIID;
- u16 MFIVariant;
- u16 MFIBottom;
- u16 MFITop;
-} __WLAN_ATTRIB_PACK__ hfa384x_MFIActRanges_t;
+typedef struct hfa384x_downloadbuffer {
+ u16 page;
+ u16 offset;
+ u16 len;
+} __attribute__ ((packed)) hfa384x_downloadbuffer_t;
/*--------------------------------------------------------------------
Information Record Structures: NIC Information
--------------------------------------------------------------------*/
-/*-- Information Record: PortStatus --*/
-typedef struct hfa384x_PortStatus
-{
- u16 PortStatus;
-} __WLAN_ATTRIB_PACK__ hfa384x_PortStatus_t;
-
-#define HFA384x_PSTATUS_DISABLED ((u16)1)
-#define HFA384x_PSTATUS_SEARCHING ((u16)2)
#define HFA384x_PSTATUS_CONN_IBSS ((u16)3)
-#define HFA384x_PSTATUS_CONN_ESS ((u16)4)
-#define HFA384x_PSTATUS_OUTOFRANGE ((u16)5)
-#define HFA384x_PSTATUS_CONN_WDS ((u16)6)
-
-/*-- Information Record: CurrentSSID --*/
-typedef struct hfa384x_CurrentSSID
-{
- u8 CurrentSSID[34];
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentSSID_t;
-
-/*-- Information Record: CurrentBSSID --*/
-typedef struct hfa384x_CurrentBSSID
-{
- u8 CurrentBSSID[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBSSID_t;
/*-- Information Record: commsquality --*/
-typedef struct hfa384x_commsquality
-{
- u16 CQ_currBSS;
- u16 ASL_currBSS;
- u16 ANL_currFC;
-} __WLAN_ATTRIB_PACK__ hfa384x_commsquality_t;
+typedef struct hfa384x_commsquality {
+ u16 CQ_currBSS;
+ u16 ASL_currBSS;
+ u16 ANL_currFC;
+} __attribute__ ((packed)) hfa384x_commsquality_t;
/*-- Information Record: dmbcommsquality --*/
-typedef struct hfa384x_dbmcommsquality
-{
- u16 CQdbm_currBSS;
- u16 ASLdbm_currBSS;
- u16 ANLdbm_currFC;
-} __WLAN_ATTRIB_PACK__ hfa384x_dbmcommsquality_t;
-
-/*-- Information Record: CurrentTxRate --*/
-typedef struct hfa384x_CurrentTxRate
-{
- u16 CurrentTxRate;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentTxRate_t;
-
-/*-- Information Record: CurrentBeaconInterval --*/
-typedef struct hfa384x_CurrentBeaconInterval
-{
- u16 CurrentBeaconInterval;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentBeaconInterval_t;
-
-/*-- Information Record: CurrentScaleThresholds --*/
-typedef struct hfa384x_CurrentScaleThresholds
-{
- u16 EnergyDetectThreshold;
- u16 CarrierDetectThreshold;
- u16 DeferDetectThreshold;
- u16 CellSearchThreshold; /* Stations only */
- u16 DeadSpotThreshold; /* Stations only */
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentScaleThresholds_t;
-
-/*-- Information Record: ProtocolRspTime --*/
-typedef struct hfa384x_ProtocolRspTime
-{
- u16 ProtocolRspTime;
-} __WLAN_ATTRIB_PACK__ hfa384x_ProtocolRspTime_t;
-
-/*-- Information Record: ShortRetryLimit --*/
-typedef struct hfa384x_ShortRetryLimit
-{
- u16 ShortRetryLimit;
-} __WLAN_ATTRIB_PACK__ hfa384x_ShortRetryLimit_t;
-
-/*-- Information Record: LongRetryLimit --*/
-typedef struct hfa384x_LongRetryLimit
-{
- u16 LongRetryLimit;
-} __WLAN_ATTRIB_PACK__ hfa384x_LongRetryLimit_t;
-
-/*-- Information Record: MaxTransmitLifetime --*/
-typedef struct hfa384x_MaxTransmitLifetime
-{
- u16 MaxTransmitLifetime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxTransmitLifetime_t;
-
-/*-- Information Record: MaxReceiveLifetime --*/
-typedef struct hfa384x_MaxReceiveLifetime
-{
- u16 MaxReceiveLifetime;
-} __WLAN_ATTRIB_PACK__ hfa384x_MaxReceiveLifetime_t;
-
-/*-- Information Record: CFPollable --*/
-typedef struct hfa384x_CFPollable
-{
- u16 CFPollable;
-} __WLAN_ATTRIB_PACK__ hfa384x_CFPollable_t;
-
-/*-- Information Record: AuthenticationAlgorithms --*/
-typedef struct hfa384x_AuthenticationAlgorithms
-{
- u16 AuthenticationType;
- u16 TypeEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_t;
-
-/*-- Information Record: AuthenticationAlgorithms
-(data only --*/
-typedef struct hfa384x_AuthenticationAlgorithms_data
-{
- u16 AuthenticationType;
- u16 TypeEnabled;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthenticationAlgorithms_data_t;
-
-/*-- Information Record: PrivacyOptionImplemented --*/
-typedef struct hfa384x_PrivacyOptionImplemented
-{
- u16 PrivacyOptionImplemented;
-} __WLAN_ATTRIB_PACK__ hfa384x_PrivacyOptionImplemented_t;
-
-/*-- Information Record: OwnMACAddress --*/
-typedef struct hfa384x_OwnMACAddress
-{
- u8 OwnMACAddress[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_OwnMACAddress_t;
-
-/*-- Information Record: PCFInfo --*/
-typedef struct hfa384x_PCFInfo
-{
- u16 MediumOccupancyLimit;
- u16 CFPPeriod;
- u16 CFPMaxDuration;
- u16 CFPFlags;
-} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_t;
-
-/*-- Information Record: PCFInfo (data portion only) --*/
-typedef struct hfa384x_PCFInfo_data
-{
- u16 MediumOccupancyLimit;
- u16 CFPPeriod;
- u16 CFPMaxDuration;
- u16 CFPFlags;
-} __WLAN_ATTRIB_PACK__ hfa384x_PCFInfo_data_t;
-
-/*--------------------------------------------------------------------
-Information Record Structures: Modem Information Records
---------------------------------------------------------------------*/
-
-/*-- Information Record: PHYType --*/
-typedef struct hfa384x_PHYType
-{
- u16 PHYType;
-} __WLAN_ATTRIB_PACK__ hfa384x_PHYType_t;
-
-/*-- Information Record: CurrentChannel --*/
-typedef struct hfa384x_CurrentChannel
-{
- u16 CurrentChannel;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentChannel_t;
-
-/*-- Information Record: CurrentPowerState --*/
-typedef struct hfa384x_CurrentPowerState
-{
- u16 CurrentPowerState;
-} __WLAN_ATTRIB_PACK__ hfa384x_CurrentPowerState_t;
-
-/*-- Information Record: CCAMode --*/
-typedef struct hfa384x_CCAMode
-{
- u16 CCAMode;
-} __WLAN_ATTRIB_PACK__ hfa384x_CCAMode_t;
-
-/*-- Information Record: SupportedDataRates --*/
-typedef struct hfa384x_SupportedDataRates
-{
- u8 SupportedDataRates[10];
-} __WLAN_ATTRIB_PACK__ hfa384x_SupportedDataRates_t;
-
-/*-- Information Record: LFOStatus --*/
-typedef struct hfa384x_LFOStatus
-{
- u16 TestResults;
- u16 LFOResult;
- u16 VRHFOResult;
-} __WLAN_ATTRIB_PACK__ hfa384x_LFOStatus_t;
-
-#define HFA384x_TESTRESULT_ALLPASSED BIT0
-#define HFA384x_TESTRESULT_LFO_FAIL BIT1
-#define HFA384x_TESTRESULT_VR_HF0_FAIL BIT2
-#define HFA384x_HOST_FIRM_COORDINATE BIT7
-#define HFA384x_TESTRESULT_COORDINATE BIT15
-
-/*-- Information Record: LEDControl --*/
-typedef struct hfa384x_LEDControl
-{
- u16 searching_on;
- u16 searching_off;
- u16 assoc_on;
- u16 assoc_off;
- u16 activity;
-} __WLAN_ATTRIB_PACK__ hfa384x_LEDControl_t;
-
-/*--------------------------------------------------------------------
- FRAME DESCRIPTORS AND FRAME STRUCTURES
-
-FRAME DESCRIPTORS: Offsets
-
-----------------------------------------------------------------------
-Control Info (offset 44-51)
---------------------------------------------------------------------*/
-#define HFA384x_FD_STATUS_OFF ((u16)0x44)
-#define HFA384x_FD_TIME_OFF ((u16)0x46)
-#define HFA384x_FD_SWSUPPORT_OFF ((u16)0x4A)
-#define HFA384x_FD_SILENCE_OFF ((u16)0x4A)
-#define HFA384x_FD_SIGNAL_OFF ((u16)0x4B)
-#define HFA384x_FD_RATE_OFF ((u16)0x4C)
-#define HFA384x_FD_RXFLOW_OFF ((u16)0x4D)
-#define HFA384x_FD_RESERVED_OFF ((u16)0x4E)
-#define HFA384x_FD_TXCONTROL_OFF ((u16)0x50)
-/*--------------------------------------------------------------------
-802.11 Header (offset 52-6B)
---------------------------------------------------------------------*/
-#define HFA384x_FD_FRAMECONTROL_OFF ((u16)0x52)
-#define HFA384x_FD_DURATIONID_OFF ((u16)0x54)
-#define HFA384x_FD_ADDRESS1_OFF ((u16)0x56)
-#define HFA384x_FD_ADDRESS2_OFF ((u16)0x5C)
-#define HFA384x_FD_ADDRESS3_OFF ((u16)0x62)
-#define HFA384x_FD_SEQCONTROL_OFF ((u16)0x68)
-#define HFA384x_FD_ADDRESS4_OFF ((u16)0x6A)
-#define HFA384x_FD_DATALEN_OFF ((u16)0x70)
-/*--------------------------------------------------------------------
-802.3 Header (offset 72-7F)
---------------------------------------------------------------------*/
-#define HFA384x_FD_DESTADDRESS_OFF ((u16)0x72)
-#define HFA384x_FD_SRCADDRESS_OFF ((u16)0x78)
-#define HFA384x_FD_DATALENGTH_OFF ((u16)0x7E)
+typedef struct hfa384x_dbmcommsquality {
+ u16 CQdbm_currBSS;
+ u16 ASLdbm_currBSS;
+ u16 ANLdbm_currFC;
+} __attribute__ ((packed)) hfa384x_dbmcommsquality_t;
/*--------------------------------------------------------------------
FRAME STRUCTURES: Communication Frames
@@ -1573,51 +442,46 @@ FRAME STRUCTURES: Communication Frames
Communication Frames: Transmit Frames
--------------------------------------------------------------------*/
/*-- Communication Frame: Transmit Frame Structure --*/
-typedef struct hfa384x_tx_frame
-{
- u16 status;
- u16 reserved1;
- u16 reserved2;
- u32 sw_support;
- u8 tx_retrycount;
- u8 tx_rate;
- u16 tx_control;
+typedef struct hfa384x_tx_frame {
+ u16 status;
+ u16 reserved1;
+ u16 reserved2;
+ u32 sw_support;
+ u8 tx_retrycount;
+ u8 tx_rate;
+ u16 tx_control;
/*-- 802.11 Header Information --*/
- u16 frame_control;
- u16 duration_id;
- u8 address1[6];
- u8 address2[6];
- u8 address3[6];
- u16 sequence_control;
- u8 address4[6];
- u16 data_len; /* little endian format */
+ u16 frame_control;
+ u16 duration_id;
+ u8 address1[6];
+ u8 address2[6];
+ u8 address3[6];
+ u16 sequence_control;
+ u8 address4[6];
+ u16 data_len; /* little endian format */
/*-- 802.3 Header Information --*/
- u8 dest_addr[6];
- u8 src_addr[6];
- u16 data_length; /* big endian format */
-} __WLAN_ATTRIB_PACK__ hfa384x_tx_frame_t;
+ u8 dest_addr[6];
+ u8 src_addr[6];
+ u16 data_length; /* big endian format */
+} __attribute__ ((packed)) hfa384x_tx_frame_t;
/*--------------------------------------------------------------------
Communication Frames: Field Masks for Transmit Frames
--------------------------------------------------------------------*/
/*-- Status Field --*/
-#define HFA384x_TXSTATUS_ACKERR ((u16)BIT5)
-#define HFA384x_TXSTATUS_FORMERR ((u16)BIT3)
-#define HFA384x_TXSTATUS_DISCON ((u16)BIT2)
-#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT1)
-#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT0)
+#define HFA384x_TXSTATUS_ACKERR ((u16)BIT(5))
+#define HFA384x_TXSTATUS_FORMERR ((u16)BIT(3))
+#define HFA384x_TXSTATUS_DISCON ((u16)BIT(2))
+#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT(1))
+#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT(0))
/*-- Transmit Control Field --*/
-#define HFA384x_TX_CFPOLL ((u16)BIT12)
-#define HFA384x_TX_PRST ((u16)BIT11)
-#define HFA384x_TX_MACPORT ((u16)(BIT10 | BIT9 | BIT8))
-#define HFA384x_TX_NOENCRYPT ((u16)BIT7)
-#define HFA384x_TX_RETRYSTRAT ((u16)(BIT6 | BIT5))
-#define HFA384x_TX_STRUCTYPE ((u16)(BIT4 | BIT3))
-#define HFA384x_TX_TXEX ((u16)BIT2)
-#define HFA384x_TX_TXOK ((u16)BIT1)
+#define HFA384x_TX_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_TX_STRUCTYPE ((u16)(BIT(4) | BIT(3)))
+#define HFA384x_TX_TXEX ((u16)BIT(2))
+#define HFA384x_TX_TXOK ((u16)BIT(1))
/*--------------------------------------------------------------------
Communication Frames: Test/Get/Set Field Values for Transmit Frames
--------------------------------------------------------------------*/
@@ -1628,83 +492,53 @@ Communication Frames: Test/Get/Set Field Values for Transmit Frames
HFA384x_TXSTATUS_DISCON|HFA384x_TXSTATUS_AGEDERR|\
HFA384x_TXSTATUS_RETRYERR))
-#define HFA384x_TXSTATUS_ISACKERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_ACKERR))
-#define HFA384x_TXSTATUS_ISFORMERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_FORMERR))
-#define HFA384x_TXSTATUS_ISDISCON(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_DISCON))
-#define HFA384x_TXSTATUS_ISAGEDERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_AGEDERR))
-#define HFA384x_TXSTATUS_ISRETRYERR(v) ((u16)(((u16)(v)) & HFA384x_TXSTATUS_RETRYERR))
-
-#define HFA384x_TX_GET(v,m,s) ((((u16)(v))&((u16)(m)))>>((u16)(s)))
-#define HFA384x_TX_SET(v,m,s) ((((u16)(v))<<((u16)(s)))&((u16)(m)))
+#define HFA384x_TX_SET(v, m, s) ((((u16)(v))<<((u16)(s)))&((u16)(m)))
-#define HFA384x_TX_CFPOLL_GET(v) HFA384x_TX_GET(v, HFA384x_TX_CFPOLL,12)
-#define HFA384x_TX_CFPOLL_SET(v) HFA384x_TX_SET(v, HFA384x_TX_CFPOLL,12)
-#define HFA384x_TX_PRST_GET(v) HFA384x_TX_GET(v, HFA384x_TX_PRST,11)
-#define HFA384x_TX_PRST_SET(v) HFA384x_TX_SET(v, HFA384x_TX_PRST,11)
-#define HFA384x_TX_MACPORT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_MACPORT, 8)
#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8)
-#define HFA384x_TX_NOENCRYPT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_NOENCRYPT, 7)
-#define HFA384x_TX_NOENCRYPT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_NOENCRYPT, 7)
-#define HFA384x_TX_RETRYSTRAT_GET(v) HFA384x_TX_GET(v, HFA384x_TX_RETRYSTRAT, 5)
-#define HFA384x_TX_RETRYSTRAT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_RETRYSTRAT, 5)
-#define HFA384x_TX_STRUCTYPE_GET(v) HFA384x_TX_GET(v, HFA384x_TX_STRUCTYPE, 3)
#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, HFA384x_TX_STRUCTYPE, 3)
-#define HFA384x_TX_TXEX_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXEX, 2)
#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2)
-#define HFA384x_TX_TXOK_GET(v) HFA384x_TX_GET(v, HFA384x_TX_TXOK, 1)
#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1)
/*--------------------------------------------------------------------
Communication Frames: Receive Frames
--------------------------------------------------------------------*/
/*-- Communication Frame: Receive Frame Structure --*/
-typedef struct hfa384x_rx_frame
-{
+typedef struct hfa384x_rx_frame {
/*-- MAC rx descriptor (hfa384x byte order) --*/
- u16 status;
- u32 time;
- u8 silence;
- u8 signal;
- u8 rate;
- u8 rx_flow;
- u16 reserved1;
- u16 reserved2;
+ u16 status;
+ u32 time;
+ u8 silence;
+ u8 signal;
+ u8 rate;
+ u8 rx_flow;
+ u16 reserved1;
+ u16 reserved2;
/*-- 802.11 Header Information (802.11 byte order) --*/
- u16 frame_control;
- u16 duration_id;
- u8 address1[6];
- u8 address2[6];
- u8 address3[6];
- u16 sequence_control;
- u8 address4[6];
- u16 data_len; /* hfa384x (little endian) format */
+ u16 frame_control;
+ u16 duration_id;
+ u8 address1[6];
+ u8 address2[6];
+ u8 address3[6];
+ u16 sequence_control;
+ u8 address4[6];
+ u16 data_len; /* hfa384x (little endian) format */
/*-- 802.3 Header Information --*/
- u8 dest_addr[6];
- u8 src_addr[6];
- u16 data_length; /* IEEE? (big endian) format */
-} __WLAN_ATTRIB_PACK__ hfa384x_rx_frame_t;
+ u8 dest_addr[6];
+ u8 src_addr[6];
+ u16 data_length; /* IEEE? (big endian) format */
+} __attribute__ ((packed)) hfa384x_rx_frame_t;
/*--------------------------------------------------------------------
Communication Frames: Field Masks for Receive Frames
--------------------------------------------------------------------*/
-/*-- Offsets --------*/
-#define HFA384x_RX_DATA_LEN_OFF ((u16)44)
-#define HFA384x_RX_80211HDR_OFF ((u16)14)
-#define HFA384x_RX_DATA_OFF ((u16)60)
/*-- Status Fields --*/
-#define HFA384x_RXSTATUS_MSGTYPE ((u16)(BIT15 | BIT14 | BIT13))
-#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT10 | BIT9 | BIT8))
-#define HFA384x_RXSTATUS_UNDECR ((u16)BIT1)
-#define HFA384x_RXSTATUS_FCSERR ((u16)BIT0)
+#define HFA384x_RXSTATUS_MACPORT ((u16)(BIT(10) | BIT(9) | BIT(8)))
+#define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0))
/*--------------------------------------------------------------------
Communication Frames: Test/Get/Set Field Values for Receive Frames
--------------------------------------------------------------------*/
-#define HFA384x_RXSTATUS_MSGTYPE_GET(value) ((u16)((((u16)(value)) & HFA384x_RXSTATUS_MSGTYPE) >> 13))
-#define HFA384x_RXSTATUS_MSGTYPE_SET(value) ((u16)(((u16)(value)) << 13))
#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) & HFA384x_RXSTATUS_MACPORT) >> 8))
-#define HFA384x_RXSTATUS_MACPORT_SET(value) ((u16)(((u16)(value)) << 8))
-#define HFA384x_RXSTATUS_ISUNDECR(value) ((u16)(((u16)(value)) & HFA384x_RXSTATUS_UNDECR))
#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) & HFA384x_RXSTATUS_FCSERR))
/*--------------------------------------------------------------------
FRAME STRUCTURES: Information Types and Information Frame Structures
@@ -1712,7 +546,6 @@ Communication Frames: Test/Get/Set Field Values for Receive Frames
Information Types
--------------------------------------------------------------------*/
#define HFA384x_IT_HANDOVERADDR ((u16)0xF000UL)
-#define HFA384x_IT_HANDOVERDEAUTHADDRESS ((u16)0xF001UL)//AP 1.3.7
#define HFA384x_IT_COMMTALLIES ((u16)0xF100UL)
#define HFA384x_IT_SCANRESULTS ((u16)0xF101UL)
#define HFA384x_IT_CHINFORESULTS ((u16)0xF102UL)
@@ -1730,128 +563,110 @@ Information Frames Structures
----------------------------------------------------------------------
Information Frames: Notification Frame Structures
--------------------------------------------------------------------*/
-/*-- Notification Frame,MAC Mgmt: Handover Address --*/
-typedef struct hfa384x_HandoverAddr
-{
- u16 framelen;
- u16 infotype;
- u8 handover_addr[WLAN_BSSID_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_HandoverAddr_t;
/*-- Inquiry Frame, Diagnose: Communication Tallies --*/
-typedef struct hfa384x_CommTallies16
-{
- u16 txunicastframes;
- u16 txmulticastframes;
- u16 txfragments;
- u16 txunicastoctets;
- u16 txmulticastoctets;
- u16 txdeferredtrans;
- u16 txsingleretryframes;
- u16 txmultipleretryframes;
- u16 txretrylimitexceeded;
- u16 txdiscards;
- u16 rxunicastframes;
- u16 rxmulticastframes;
- u16 rxfragments;
- u16 rxunicastoctets;
- u16 rxmulticastoctets;
- u16 rxfcserrors;
- u16 rxdiscardsnobuffer;
- u16 txdiscardswrongsa;
- u16 rxdiscardswepundecr;
- u16 rxmsginmsgfrag;
- u16 rxmsginbadmsgfrag;
-} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies16_t;
-
-typedef struct hfa384x_CommTallies32
-{
- u32 txunicastframes;
- u32 txmulticastframes;
- u32 txfragments;
- u32 txunicastoctets;
- u32 txmulticastoctets;
- u32 txdeferredtrans;
- u32 txsingleretryframes;
- u32 txmultipleretryframes;
- u32 txretrylimitexceeded;
- u32 txdiscards;
- u32 rxunicastframes;
- u32 rxmulticastframes;
- u32 rxfragments;
- u32 rxunicastoctets;
- u32 rxmulticastoctets;
- u32 rxfcserrors;
- u32 rxdiscardsnobuffer;
- u32 txdiscardswrongsa;
- u32 rxdiscardswepundecr;
- u32 rxmsginmsgfrag;
- u32 rxmsginbadmsgfrag;
-} __WLAN_ATTRIB_PACK__ hfa384x_CommTallies32_t;
+typedef struct hfa384x_CommTallies16 {
+ u16 txunicastframes;
+ u16 txmulticastframes;
+ u16 txfragments;
+ u16 txunicastoctets;
+ u16 txmulticastoctets;
+ u16 txdeferredtrans;
+ u16 txsingleretryframes;
+ u16 txmultipleretryframes;
+ u16 txretrylimitexceeded;
+ u16 txdiscards;
+ u16 rxunicastframes;
+ u16 rxmulticastframes;
+ u16 rxfragments;
+ u16 rxunicastoctets;
+ u16 rxmulticastoctets;
+ u16 rxfcserrors;
+ u16 rxdiscardsnobuffer;
+ u16 txdiscardswrongsa;
+ u16 rxdiscardswepundecr;
+ u16 rxmsginmsgfrag;
+ u16 rxmsginbadmsgfrag;
+} __attribute__ ((packed)) hfa384x_CommTallies16_t;
+
+typedef struct hfa384x_CommTallies32 {
+ u32 txunicastframes;
+ u32 txmulticastframes;
+ u32 txfragments;
+ u32 txunicastoctets;
+ u32 txmulticastoctets;
+ u32 txdeferredtrans;
+ u32 txsingleretryframes;
+ u32 txmultipleretryframes;
+ u32 txretrylimitexceeded;
+ u32 txdiscards;
+ u32 rxunicastframes;
+ u32 rxmulticastframes;
+ u32 rxfragments;
+ u32 rxunicastoctets;
+ u32 rxmulticastoctets;
+ u32 rxfcserrors;
+ u32 rxdiscardsnobuffer;
+ u32 txdiscardswrongsa;
+ u32 rxdiscardswepundecr;
+ u32 rxmsginmsgfrag;
+ u32 rxmsginbadmsgfrag;
+} __attribute__ ((packed)) hfa384x_CommTallies32_t;
/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/
-typedef struct hfa384x_ScanResultSub
-{
- u16 chid;
- u16 anl;
- u16 sl;
- u8 bssid[WLAN_BSSID_LEN];
- u16 bcnint;
- u16 capinfo;
- hfa384x_bytestr32_t ssid;
- u8 supprates[10]; /* 802.11 info element */
- u16 proberesp_rate;
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanResultSub_t;
-
-typedef struct hfa384x_ScanResult
-{
- u16 rsvd;
- u16 scanreason;
- hfa384x_ScanResultSub_t
- result[HFA384x_SCANRESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_ScanResult_t;
+typedef struct hfa384x_ScanResultSub {
+ u16 chid;
+ u16 anl;
+ u16 sl;
+ u8 bssid[WLAN_BSSID_LEN];
+ u16 bcnint;
+ u16 capinfo;
+ hfa384x_bytestr32_t ssid;
+ u8 supprates[10]; /* 802.11 info element */
+ u16 proberesp_rate;
+} __attribute__ ((packed)) hfa384x_ScanResultSub_t;
+
+typedef struct hfa384x_ScanResult {
+ u16 rsvd;
+ u16 scanreason;
+ hfa384x_ScanResultSub_t result[HFA384x_SCANRESULT_MAX];
+} __attribute__ ((packed)) hfa384x_ScanResult_t;
/*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/
-typedef struct hfa384x_ChInfoResultSub
-{
- u16 chid;
- u16 anl;
- u16 pnl;
- u16 active;
-} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResultSub_t;
+typedef struct hfa384x_ChInfoResultSub {
+ u16 chid;
+ u16 anl;
+ u16 pnl;
+ u16 active;
+} __attribute__ ((packed)) hfa384x_ChInfoResultSub_t;
-#define HFA384x_CHINFORESULT_BSSACTIVE BIT0
-#define HFA384x_CHINFORESULT_PCFACTIVE BIT1
+#define HFA384x_CHINFORESULT_BSSACTIVE BIT(0)
+#define HFA384x_CHINFORESULT_PCFACTIVE BIT(1)
-typedef struct hfa384x_ChInfoResult
-{
- u16 scanchannels;
- hfa384x_ChInfoResultSub_t
- result[HFA384x_CHINFORESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_ChInfoResult_t;
+typedef struct hfa384x_ChInfoResult {
+ u16 scanchannels;
+ hfa384x_ChInfoResultSub_t result[HFA384x_CHINFORESULT_MAX];
+} __attribute__ ((packed)) hfa384x_ChInfoResult_t;
/*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/
-typedef struct hfa384x_HScanResultSub
-{
- u16 chid;
- u16 anl;
- u16 sl;
- u8 bssid[WLAN_BSSID_LEN];
- u16 bcnint;
- u16 capinfo;
- hfa384x_bytestr32_t ssid;
- u8 supprates[10]; /* 802.11 info element */
- u16 proberesp_rate;
- u16 atim;
-} __WLAN_ATTRIB_PACK__ hfa384x_HScanResultSub_t;
-
-typedef struct hfa384x_HScanResult
-{
- u16 nresult;
- u16 rsvd;
- hfa384x_HScanResultSub_t
- result[HFA384x_HSCANRESULT_MAX];
-} __WLAN_ATTRIB_PACK__ hfa384x_HScanResult_t;
+typedef struct hfa384x_HScanResultSub {
+ u16 chid;
+ u16 anl;
+ u16 sl;
+ u8 bssid[WLAN_BSSID_LEN];
+ u16 bcnint;
+ u16 capinfo;
+ hfa384x_bytestr32_t ssid;
+ u8 supprates[10]; /* 802.11 info element */
+ u16 proberesp_rate;
+ u16 atim;
+} __attribute__ ((packed)) hfa384x_HScanResultSub_t;
+
+typedef struct hfa384x_HScanResult {
+ u16 nresult;
+ u16 rsvd;
+ hfa384x_HScanResultSub_t result[HFA384x_HSCANRESULT_MAX];
+} __attribute__ ((packed)) hfa384x_HScanResult_t;
/*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/
@@ -1863,100 +678,67 @@ typedef struct hfa384x_HScanResult
#define HFA384x_LINK_AP_INRANGE ((u16)5)
#define HFA384x_LINK_ASSOCFAIL ((u16)6)
-typedef struct hfa384x_LinkStatus
-{
- u16 linkstatus;
-} __WLAN_ATTRIB_PACK__ hfa384x_LinkStatus_t;
-
+typedef struct hfa384x_LinkStatus {
+ u16 linkstatus;
+} __attribute__ ((packed)) hfa384x_LinkStatus_t;
/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/
#define HFA384x_ASSOCSTATUS_STAASSOC ((u16)1)
#define HFA384x_ASSOCSTATUS_REASSOC ((u16)2)
-#define HFA384x_ASSOCSTATUS_DISASSOC ((u16)3)
-#define HFA384x_ASSOCSTATUS_ASSOCFAIL ((u16)4)
#define HFA384x_ASSOCSTATUS_AUTHFAIL ((u16)5)
-typedef struct hfa384x_AssocStatus
-{
- u16 assocstatus;
- u8 sta_addr[WLAN_ADDR_LEN];
+typedef struct hfa384x_AssocStatus {
+ u16 assocstatus;
+ u8 sta_addr[ETH_ALEN];
/* old_ap_addr is only valid if assocstatus == 2 */
- u8 old_ap_addr[WLAN_ADDR_LEN];
- u16 reason;
- u16 reserved;
-} __WLAN_ATTRIB_PACK__ hfa384x_AssocStatus_t;
+ u8 old_ap_addr[ETH_ALEN];
+ u16 reason;
+ u16 reserved;
+} __attribute__ ((packed)) hfa384x_AssocStatus_t;
/*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/
-typedef struct hfa384x_AuthRequest
-{
- u8 sta_addr[WLAN_ADDR_LEN];
- u16 algorithm;
-} __WLAN_ATTRIB_PACK__ hfa384x_AuthReq_t;
-
-/*-- Unsolicited Frame, MAC Mgmt: AssocRequest (AP Only) --*/
-
-typedef struct hfa384x_AssocRequest
-{
- u8 sta_addr[WLAN_ADDR_LEN];
- u16 type;
- u8 wpa_data[80];
-} __WLAN_ATTRIB_PACK__ hfa384x_AssocReq_t;
-
-
-#define HFA384x_ASSOCREQ_TYPE_ASSOC 0
-#define HFA384x_ASSOCREQ_TYPE_REASSOC 1
-
-/*-- Unsolicited Frame, MAC Mgmt: MIC Failure (AP Only) --*/
-
-typedef struct hfa384x_MicFailure
-{
- u8 sender[WLAN_ADDR_LEN];
- u8 dest[WLAN_ADDR_LEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_MicFailure_t;
+typedef struct hfa384x_AuthRequest {
+ u8 sta_addr[ETH_ALEN];
+ u16 algorithm;
+} __attribute__ ((packed)) hfa384x_AuthReq_t;
/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/
-typedef struct hfa384x_PSUserCount
-{
- u16 usercnt;
-} __WLAN_ATTRIB_PACK__ hfa384x_PSUserCount_t;
+typedef struct hfa384x_PSUserCount {
+ u16 usercnt;
+} __attribute__ ((packed)) hfa384x_PSUserCount_t;
-typedef struct hfa384x_KeyIDChanged
-{
- u8 sta_addr[WLAN_ADDR_LEN];
- u16 keyid;
-} __WLAN_ATTRIB_PACK__ hfa384x_KeyIDChanged_t;
+typedef struct hfa384x_KeyIDChanged {
+ u8 sta_addr[ETH_ALEN];
+ u16 keyid;
+} __attribute__ ((packed)) hfa384x_KeyIDChanged_t;
/*-- Collection of all Inf frames ---------------*/
typedef union hfa384x_infodata {
- hfa384x_CommTallies16_t commtallies16;
- hfa384x_CommTallies32_t commtallies32;
- hfa384x_ScanResult_t scanresult;
- hfa384x_ChInfoResult_t chinforesult;
- hfa384x_HScanResult_t hscanresult;
- hfa384x_LinkStatus_t linkstatus;
- hfa384x_AssocStatus_t assocstatus;
- hfa384x_AuthReq_t authreq;
- hfa384x_PSUserCount_t psusercnt;
- hfa384x_KeyIDChanged_t keyidchanged;
-} __WLAN_ATTRIB_PACK__ hfa384x_infodata_t;
-
-typedef struct hfa384x_InfFrame
-{
- u16 framelen;
- u16 infotype;
- hfa384x_infodata_t info;
-} __WLAN_ATTRIB_PACK__ hfa384x_InfFrame_t;
+ hfa384x_CommTallies16_t commtallies16;
+ hfa384x_CommTallies32_t commtallies32;
+ hfa384x_ScanResult_t scanresult;
+ hfa384x_ChInfoResult_t chinforesult;
+ hfa384x_HScanResult_t hscanresult;
+ hfa384x_LinkStatus_t linkstatus;
+ hfa384x_AssocStatus_t assocstatus;
+ hfa384x_AuthReq_t authreq;
+ hfa384x_PSUserCount_t psusercnt;
+ hfa384x_KeyIDChanged_t keyidchanged;
+} __attribute__ ((packed)) hfa384x_infodata_t;
+
+typedef struct hfa384x_InfFrame {
+ u16 framelen;
+ u16 infotype;
+ hfa384x_infodata_t info;
+} __attribute__ ((packed)) hfa384x_InfFrame_t;
/*--------------------------------------------------------------------
USB Packet structures and constants.
--------------------------------------------------------------------*/
-/* Should be sent to the ctrlout endpoint */
-#define HFA384x_USB_ENBULKIN 6
-
/* Should be sent to the bulkout endpoint */
#define HFA384x_USB_TXFRM 0
#define HFA384x_USB_CMDREQ 1
@@ -1966,7 +748,6 @@ USB Packet structures and constants.
#define HFA384x_USB_RMEMREQ 5
/* Received from the bulkin endpoint */
-#define HFA384x_USB_ISFRM(a) (!((a) & 0x8000))
#define HFA384x_USB_ISTXFRM(a) (((a) & 0x9000) == 0x1000)
#define HFA384x_USB_ISRXFRM(a) (!((a) & 0x9000))
#define HFA384x_USB_INFOFRM 0x8000
@@ -1982,380 +763,135 @@ USB Packet structures and constants.
/* Request (bulk OUT) packet contents */
typedef struct hfa384x_usb_txfrm {
- hfa384x_tx_frame_t desc;
- u8 data[WLAN_DATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_txfrm_t;
+ hfa384x_tx_frame_t desc;
+ u8 data[WLAN_DATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_txfrm_t;
typedef struct hfa384x_usb_cmdreq {
- u16 type;
- u16 cmd;
- u16 parm0;
- u16 parm1;
- u16 parm2;
- u8 pad[54];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdreq_t;
+ u16 type;
+ u16 cmd;
+ u16 parm0;
+ u16 parm1;
+ u16 parm2;
+ u8 pad[54];
+} __attribute__ ((packed)) hfa384x_usb_cmdreq_t;
typedef struct hfa384x_usb_wridreq {
- u16 type;
- u16 frmlen;
- u16 rid;
- u8 data[HFA384x_RIDDATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_wridreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 rid;
+ u8 data[HFA384x_RIDDATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_wridreq_t;
typedef struct hfa384x_usb_rridreq {
- u16 type;
- u16 frmlen;
- u16 rid;
- u8 pad[58];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 rid;
+ u8 pad[58];
+} __attribute__ ((packed)) hfa384x_usb_rridreq_t;
typedef struct hfa384x_usb_wmemreq {
- u16 type;
- u16 frmlen;
- u16 offset;
- u16 page;
- u8 data[HFA384x_USB_RWMEM_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_wmemreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 offset;
+ u16 page;
+ u8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_wmemreq_t;
typedef struct hfa384x_usb_rmemreq {
- u16 type;
- u16 frmlen;
- u16 offset;
- u16 page;
- u8 pad[56];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemreq_t;
+ u16 type;
+ u16 frmlen;
+ u16 offset;
+ u16 page;
+ u8 pad[56];
+} __attribute__ ((packed)) hfa384x_usb_rmemreq_t;
/*------------------------------------*/
/* Response (bulk IN) packet contents */
typedef struct hfa384x_usb_rxfrm {
- hfa384x_rx_frame_t desc;
- u8 data[WLAN_DATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rxfrm_t;
+ hfa384x_rx_frame_t desc;
+ u8 data[WLAN_DATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rxfrm_t;
typedef struct hfa384x_usb_infofrm {
- u16 type;
- hfa384x_InfFrame_t info;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_infofrm_t;
+ u16 type;
+ hfa384x_InfFrame_t info;
+} __attribute__ ((packed)) hfa384x_usb_infofrm_t;
typedef struct hfa384x_usb_statusresp {
- u16 type;
- u16 status;
- u16 resp0;
- u16 resp1;
- u16 resp2;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_cmdresp_t;
+ u16 type;
+ u16 status;
+ u16 resp0;
+ u16 resp1;
+ u16 resp2;
+} __attribute__ ((packed)) hfa384x_usb_cmdresp_t;
typedef hfa384x_usb_cmdresp_t hfa384x_usb_wridresp_t;
typedef struct hfa384x_usb_rridresp {
- u16 type;
- u16 frmlen;
- u16 rid;
- u8 data[HFA384x_RIDDATA_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rridresp_t;
+ u16 type;
+ u16 frmlen;
+ u16 rid;
+ u8 data[HFA384x_RIDDATA_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rridresp_t;
typedef hfa384x_usb_cmdresp_t hfa384x_usb_wmemresp_t;
typedef struct hfa384x_usb_rmemresp {
- u16 type;
- u16 frmlen;
- u8 data[HFA384x_USB_RWMEM_MAXLEN];
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_rmemresp_t;
+ u16 type;
+ u16 frmlen;
+ u8 data[HFA384x_USB_RWMEM_MAXLEN];
+} __attribute__ ((packed)) hfa384x_usb_rmemresp_t;
typedef struct hfa384x_usb_bufavail {
- u16 type;
- u16 frmlen;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_bufavail_t;
+ u16 type;
+ u16 frmlen;
+} __attribute__ ((packed)) hfa384x_usb_bufavail_t;
typedef struct hfa384x_usb_error {
- u16 type;
- u16 errortype;
-} __WLAN_ATTRIB_PACK__ hfa384x_usb_error_t;
+ u16 type;
+ u16 errortype;
+} __attribute__ ((packed)) hfa384x_usb_error_t;
/*----------------------------------------------------------*/
/* Unions for packaging all the known packet types together */
typedef union hfa384x_usbout {
- u16 type;
- hfa384x_usb_txfrm_t txfrm;
- hfa384x_usb_cmdreq_t cmdreq;
- hfa384x_usb_wridreq_t wridreq;
- hfa384x_usb_rridreq_t rridreq;
- hfa384x_usb_wmemreq_t wmemreq;
- hfa384x_usb_rmemreq_t rmemreq;
-} __WLAN_ATTRIB_PACK__ hfa384x_usbout_t;
+ u16 type;
+ hfa384x_usb_txfrm_t txfrm;
+ hfa384x_usb_cmdreq_t cmdreq;
+ hfa384x_usb_wridreq_t wridreq;
+ hfa384x_usb_rridreq_t rridreq;
+ hfa384x_usb_wmemreq_t wmemreq;
+ hfa384x_usb_rmemreq_t rmemreq;
+} __attribute__ ((packed)) hfa384x_usbout_t;
typedef union hfa384x_usbin {
- u16 type;
- hfa384x_usb_rxfrm_t rxfrm;
- hfa384x_usb_txfrm_t txfrm;
- hfa384x_usb_infofrm_t infofrm;
- hfa384x_usb_cmdresp_t cmdresp;
- hfa384x_usb_wridresp_t wridresp;
- hfa384x_usb_rridresp_t rridresp;
- hfa384x_usb_wmemresp_t wmemresp;
- hfa384x_usb_rmemresp_t rmemresp;
- hfa384x_usb_bufavail_t bufavail;
- hfa384x_usb_error_t usberror;
- u8 boguspad[3000];
-} __WLAN_ATTRIB_PACK__ hfa384x_usbin_t;
-
-/*--------------------------------------------------------------------
-PD record structures.
---------------------------------------------------------------------*/
-
-typedef struct hfa384x_pdr_pcb_partnum
-{
- u8 num[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_partnum_t;
-
-typedef struct hfa384x_pdr_pcb_tracenum
-{
- u8 num[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_pcb_tracenum_t;
-
-typedef struct hfa384x_pdr_nic_serial
-{
- u8 num[12];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_serial_t;
-
-typedef struct hfa384x_pdr_mkk_measurements
-{
- double carrier_freq;
- double occupied_band;
- double power_density;
- double tx_spur_f1;
- double tx_spur_f2;
- double tx_spur_f3;
- double tx_spur_f4;
- double tx_spur_l1;
- double tx_spur_l2;
- double tx_spur_l3;
- double tx_spur_l4;
- double rx_spur_f1;
- double rx_spur_f2;
- double rx_spur_l1;
- double rx_spur_l2;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_measurements_t;
-
-typedef struct hfa384x_pdr_nic_ramsize
-{
- u8 size[12]; /* units of KB */
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_ramsize_t;
-
-typedef struct hfa384x_pdr_mfisuprange
-{
- u16 id;
- u16 variant;
- u16 bottom;
- u16 top;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mfisuprange_t;
-
-typedef struct hfa384x_pdr_cfisuprange
-{
- u16 id;
- u16 variant;
- u16 bottom;
- u16 top;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_cfisuprange_t;
-
-typedef struct hfa384x_pdr_nicid
-{
- u16 id;
- u16 variant;
- u16 major;
- u16 minor;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nicid_t;
-
-
-typedef struct hfa384x_pdr_refdac_measurements
-{
- u16 value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_measurements_t;
-
-typedef struct hfa384x_pdr_vgdac_measurements
-{
- u16 value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_measurements_t;
-
-typedef struct hfa384x_pdr_level_comp_measurements
-{
- u16 value[0];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_compc_measurements_t;
-
-typedef struct hfa384x_pdr_mac_address
-{
- u8 addr[6];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mac_address_t;
-
-typedef struct hfa384x_pdr_mkk_callname
-{
- u8 callname[8];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_mkk_callname_t;
-
-typedef struct hfa384x_pdr_regdomain
-{
- u16 numdomains;
- u16 domain[5];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_regdomain_t;
-
-typedef struct hfa384x_pdr_allowed_channel
-{
- u16 ch_bitmap;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_allowed_channel_t;
-
-typedef struct hfa384x_pdr_default_channel
-{
- u16 channel;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_default_channel_t;
-
-typedef struct hfa384x_pdr_privacy_option
-{
- u16 available;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_privacy_option_t;
-
-typedef struct hfa384x_pdr_temptype
-{
- u16 type;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_temptype_t;
-
-typedef struct hfa384x_pdr_refdac_setup
-{
- u16 ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_refdac_setup_t;
-
-typedef struct hfa384x_pdr_vgdac_setup
-{
- u16 ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_vgdac_setup_t;
-
-typedef struct hfa384x_pdr_level_comp_setup
-{
- u16 ch_value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_level_comp_setup_t;
-
-typedef struct hfa384x_pdr_trimdac_setup
-{
- u16 trimidac;
- u16 trimqdac;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_trimdac_setup_t;
-
-typedef struct hfa384x_pdr_ifr_setting
-{
- u16 value[3];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_ifr_setting_t;
-
-typedef struct hfa384x_pdr_rfr_setting
-{
- u16 value[3];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_rfr_setting_t;
-
-typedef struct hfa384x_pdr_hfa3861_baseline
-{
- u16 value[50];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_baseline_t;
-
-typedef struct hfa384x_pdr_hfa3861_shadow
-{
- u32 value[32];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_shadow_t;
-
-typedef struct hfa384x_pdr_hfa3861_ifrf
-{
- u32 value[20];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_ifrf_t;
-
-typedef struct hfa384x_pdr_hfa3861_chcalsp
-{
- u16 value[14];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcalsp_t;
-
-typedef struct hfa384x_pdr_hfa3861_chcali
-{
- u16 value[17];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_chcali_t;
-
-typedef struct hfa384x_pdr_hfa3861_nic_config
-{
- u16 config_bitmap;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_nic_config_t;
-
-typedef struct hfa384x_pdr_hfo_delay
-{
- u8 hfo_delay;
-} __WLAN_ATTRIB_PACK__ hfa384x_hfo_delay_t;
-
-typedef struct hfa384x_pdr_hfa3861_manf_testsp
-{
- u16 value[30];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testsp_t;
-
-typedef struct hfa384x_pdr_hfa3861_manf_testi
-{
- u16 value[30];
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_hfa3861_manf_testi_t;
-
-typedef struct hfa384x_end_of_pda
-{
- u16 crc;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdr_end_of_pda_t;
-
-typedef struct hfa384x_pdrec
-{
- u16 len; /* in words */
- u16 code;
- union pdr {
- hfa384x_pdr_pcb_partnum_t pcb_partnum;
- hfa384x_pdr_pcb_tracenum_t pcb_tracenum;
- hfa384x_pdr_nic_serial_t nic_serial;
- hfa384x_pdr_mkk_measurements_t mkk_measurements;
- hfa384x_pdr_nic_ramsize_t nic_ramsize;
- hfa384x_pdr_mfisuprange_t mfisuprange;
- hfa384x_pdr_cfisuprange_t cfisuprange;
- hfa384x_pdr_nicid_t nicid;
- hfa384x_pdr_refdac_measurements_t refdac_measurements;
- hfa384x_pdr_vgdac_measurements_t vgdac_measurements;
- hfa384x_pdr_level_compc_measurements_t level_compc_measurements;
- hfa384x_pdr_mac_address_t mac_address;
- hfa384x_pdr_mkk_callname_t mkk_callname;
- hfa384x_pdr_regdomain_t regdomain;
- hfa384x_pdr_allowed_channel_t allowed_channel;
- hfa384x_pdr_default_channel_t default_channel;
- hfa384x_pdr_privacy_option_t privacy_option;
- hfa384x_pdr_temptype_t temptype;
- hfa384x_pdr_refdac_setup_t refdac_setup;
- hfa384x_pdr_vgdac_setup_t vgdac_setup;
- hfa384x_pdr_level_comp_setup_t level_comp_setup;
- hfa384x_pdr_trimdac_setup_t trimdac_setup;
- hfa384x_pdr_ifr_setting_t ifr_setting;
- hfa384x_pdr_rfr_setting_t rfr_setting;
- hfa384x_pdr_hfa3861_baseline_t hfa3861_baseline;
- hfa384x_pdr_hfa3861_shadow_t hfa3861_shadow;
- hfa384x_pdr_hfa3861_ifrf_t hfa3861_ifrf;
- hfa384x_pdr_hfa3861_chcalsp_t hfa3861_chcalsp;
- hfa384x_pdr_hfa3861_chcali_t hfa3861_chcali;
- hfa384x_pdr_nic_config_t nic_config;
- hfa384x_hfo_delay_t hfo_delay;
- hfa384x_pdr_hfa3861_manf_testsp_t hfa3861_manf_testsp;
- hfa384x_pdr_hfa3861_manf_testi_t hfa3861_manf_testi;
- hfa384x_pdr_end_of_pda_t end_of_pda;
-
- } data;
-} __WLAN_ATTRIB_PACK__ hfa384x_pdrec_t;
-
+ u16 type;
+ hfa384x_usb_rxfrm_t rxfrm;
+ hfa384x_usb_txfrm_t txfrm;
+ hfa384x_usb_infofrm_t infofrm;
+ hfa384x_usb_cmdresp_t cmdresp;
+ hfa384x_usb_wridresp_t wridresp;
+ hfa384x_usb_rridresp_t rridresp;
+ hfa384x_usb_wmemresp_t wmemresp;
+ hfa384x_usb_rmemresp_t rmemresp;
+ hfa384x_usb_bufavail_t bufavail;
+ hfa384x_usb_error_t usberror;
+ u8 boguspad[3000];
+} __attribute__ ((packed)) hfa384x_usbin_t;
#ifdef __KERNEL__
/*--------------------------------------------------------------------
--- MAC state structure, argument to all functions --
--- Also, a collection of support types --
--------------------------------------------------------------------*/
-typedef struct hfa384x_statusresult
-{
- u16 status;
- u16 resp0;
- u16 resp1;
- u16 resp2;
+typedef struct hfa384x_statusresult {
+ u16 status;
+ u16 resp0;
+ u16 resp1;
+ u16 resp2;
} hfa384x_cmdresult_t;
/* USB Control Exchange (CTLX):
@@ -2365,20 +901,16 @@ typedef struct hfa384x_statusresult
/* The following hfa384x_* structures are arguments to
* the usercb() for the different CTLX types.
*/
-typedef hfa384x_cmdresult_t hfa384x_wridresult_t;
-typedef hfa384x_cmdresult_t hfa384x_wmemresult_t;
-
-typedef struct hfa384x_rridresult
-{
- u16 rid;
- const void *riddata;
- unsigned int riddata_len;
+typedef struct hfa384x_rridresult {
+ u16 rid;
+ const void *riddata;
+ unsigned int riddata_len;
} hfa384x_rridresult_t;
enum ctlx_state {
- CTLX_START = 0, /* Start state, not queued */
+ CTLX_START = 0, /* Start state, not queued */
- CTLX_COMPLETE, /* CTLX successfully completed */
+ CTLX_COMPLETE, /* CTLX successfully completed */
CTLX_REQ_FAILED, /* OUT URB completed w/ error */
CTLX_PENDING, /* Queued, data valid */
@@ -2386,114 +918,98 @@ enum ctlx_state {
CTLX_REQ_COMPLETE, /* OUT URB complete */
CTLX_RESP_COMPLETE /* IN URB received */
};
-typedef enum ctlx_state CTLX_STATE;
+typedef enum ctlx_state CTLX_STATE;
struct hfa384x_usbctlx;
struct hfa384x;
-typedef void (*ctlx_cmdcb_t)( struct hfa384x*, const struct hfa384x_usbctlx* );
+typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *);
-typedef void (*ctlx_usercb_t)(
- struct hfa384x *hw,
- void *ctlxresult,
- void *usercb_data);
+typedef void (*ctlx_usercb_t) (struct hfa384x *hw,
+ void *ctlxresult, void *usercb_data);
-typedef struct hfa384x_usbctlx
-{
- struct list_head list;
+typedef struct hfa384x_usbctlx {
+ struct list_head list;
- size_t outbufsize;
- hfa384x_usbout_t outbuf; /* pkt buf for OUT */
- hfa384x_usbin_t inbuf; /* pkt buf for IN(a copy) */
+ size_t outbufsize;
+ hfa384x_usbout_t outbuf; /* pkt buf for OUT */
+ hfa384x_usbin_t inbuf; /* pkt buf for IN(a copy) */
- CTLX_STATE state; /* Tracks running state */
+ CTLX_STATE state; /* Tracks running state */
- struct completion done;
- volatile int reapable; /* Food for the reaper task */
+ struct completion done;
+ volatile int reapable; /* Food for the reaper task */
- ctlx_cmdcb_t cmdcb; /* Async command callback */
- ctlx_usercb_t usercb; /* Async user callback, */
- void *usercb_data; /* at CTLX completion */
+ ctlx_cmdcb_t cmdcb; /* Async command callback */
+ ctlx_usercb_t usercb; /* Async user callback, */
+ void *usercb_data; /* at CTLX completion */
- int variant; /* Identifies cmd variant */
+ int variant; /* Identifies cmd variant */
} hfa384x_usbctlx_t;
-typedef struct hfa384x_usbctlxq
-{
- spinlock_t lock;
- struct list_head pending;
- struct list_head active;
- struct list_head completing;
- struct list_head reapable;
+typedef struct hfa384x_usbctlxq {
+ spinlock_t lock;
+ struct list_head pending;
+ struct list_head active;
+ struct list_head completing;
+ struct list_head reapable;
} hfa384x_usbctlxq_t;
-typedef struct hfa484x_metacmd
-{
- u16 cmd;
+typedef struct hfa484x_metacmd {
+ u16 cmd;
- u16 parm0;
- u16 parm1;
- u16 parm2;
+ u16 parm0;
+ u16 parm1;
+ u16 parm2;
hfa384x_cmdresult_t result;
} hfa384x_metacmd_t;
-#define MAX_PRISM2_GRP_ADDR 16
#define MAX_GRP_ADDR 32
-#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */
-
-#define MM_SAT_PCF (BIT14)
-#define MM_GCSD_PCF (BIT15)
-#define MM_GCSD_PCF_EB (BIT14 | BIT15)
-
-#define WLAN_STATE_STOPPED 0 /* Network is not active. */
-#define WLAN_STATE_STARTED 1 /* Network has been started. */
+#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */
-#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */
-#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */
-#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */
-#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */
-#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */
-#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */
+#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */
+#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */
+#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */
+#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */
+#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */
+#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */
/* XXX These are going away ASAP */
-typedef struct prism2sta_authlist
-{
- unsigned int cnt;
- u8 addr[WLAN_AUTH_MAX][WLAN_ADDR_LEN];
- u8 assoc[WLAN_AUTH_MAX];
+typedef struct prism2sta_authlist {
+ unsigned int cnt;
+ u8 addr[WLAN_AUTH_MAX][ETH_ALEN];
+ u8 assoc[WLAN_AUTH_MAX];
} prism2sta_authlist_t;
-typedef struct prism2sta_accesslist
-{
- unsigned int modify;
- unsigned int cnt;
- u8 addr[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
- unsigned int cnt1;
- u8 addr1[WLAN_ACCESS_MAX][WLAN_ADDR_LEN];
+typedef struct prism2sta_accesslist {
+ unsigned int modify;
+ unsigned int cnt;
+ u8 addr[WLAN_ACCESS_MAX][ETH_ALEN];
+ unsigned int cnt1;
+ u8 addr1[WLAN_ACCESS_MAX][ETH_ALEN];
} prism2sta_accesslist_t;
-typedef struct hfa384x
-{
+typedef struct hfa384x {
/* USB support data */
- struct usb_device *usb;
- struct urb rx_urb;
- struct sk_buff *rx_urb_skb;
- struct urb tx_urb;
- struct urb ctlx_urb;
- hfa384x_usbout_t txbuff;
- hfa384x_usbctlxq_t ctlxq;
- struct timer_list reqtimer;
- struct timer_list resptimer;
+ struct usb_device *usb;
+ struct urb rx_urb;
+ struct sk_buff *rx_urb_skb;
+ struct urb tx_urb;
+ struct urb ctlx_urb;
+ hfa384x_usbout_t txbuff;
+ hfa384x_usbctlxq_t ctlxq;
+ struct timer_list reqtimer;
+ struct timer_list resptimer;
- struct timer_list throttle;
+ struct timer_list throttle;
- struct tasklet_struct reaper_bh;
- struct tasklet_struct completion_bh;
+ struct tasklet_struct reaper_bh;
+ struct tasklet_struct completion_bh;
- struct work_struct usb_work;
+ struct work_struct usb_work;
- unsigned long usb_flags;
+ unsigned long usb_flags;
#define THROTTLE_RX 0
#define THROTTLE_TX 1
#define WORK_RX_HALT 2
@@ -2501,292 +1017,168 @@ typedef struct hfa384x
#define WORK_RX_RESUME 4
#define WORK_TX_RESUME 5
- unsigned short req_timer_done:1;
- unsigned short resp_timer_done:1;
+ unsigned short req_timer_done:1;
+ unsigned short resp_timer_done:1;
- int endp_in;
- int endp_out;
+ int endp_in;
+ int endp_out;
- int sniff_fcs;
- int sniff_channel;
- int sniff_truncate;
- int sniffhdr;
+ int sniff_fcs;
+ int sniff_channel;
+ int sniff_truncate;
+ int sniffhdr;
- wait_queue_head_t cmdq; /* wait queue itself */
+ wait_queue_head_t cmdq; /* wait queue itself */
/* Controller state */
- u32 state;
- u32 isap;
- u8 port_enabled[HFA384x_NUMPORTS_MAX];
+ u32 state;
+ u32 isap;
+ u8 port_enabled[HFA384x_NUMPORTS_MAX];
/* Download support */
- unsigned int dlstate;
- hfa384x_downloadbuffer_t bufinfo;
- u16 dltimeout;
+ unsigned int dlstate;
+ hfa384x_downloadbuffer_t bufinfo;
+ u16 dltimeout;
- int scanflag; /* to signal scan comlete */
- int join_ap; /* are we joined to a specific ap */
- int join_retries; /* number of join retries till we fail */
- hfa384x_JoinRequest_data_t joinreq; /* join request saved data */
+ int scanflag; /* to signal scan comlete */
+ int join_ap; /* are we joined to a specific ap */
+ int join_retries; /* number of join retries till we fail */
+ hfa384x_JoinRequest_data_t joinreq; /* join request saved data */
- wlandevice_t *wlandev;
+ wlandevice_t *wlandev;
/* Timer to allow for the deferred processing of linkstatus messages */
- struct work_struct link_bh;
+ struct work_struct link_bh;
- struct work_struct commsqual_bh;
- hfa384x_commsquality_t qual;
- struct timer_list commsqual_timer;
+ struct work_struct commsqual_bh;
+ hfa384x_commsquality_t qual;
+ struct timer_list commsqual_timer;
u16 link_status;
u16 link_status_new;
- struct sk_buff_head authq;
+ struct sk_buff_head authq;
/* And here we have stuff that used to be in priv */
/* State variables */
- unsigned int presniff_port_type;
- u16 presniff_wepflags;
- u32 dot11_desired_bss_type;
+ unsigned int presniff_port_type;
+ u16 presniff_wepflags;
+ u32 dot11_desired_bss_type;
- int dbmadjust;
+ int dbmadjust;
/* Group Addresses - right now, there are up to a total
- of MAX_GRP_ADDR group addresses */
- u8 dot11_grp_addr[MAX_GRP_ADDR][WLAN_ADDR_LEN];
- unsigned int dot11_grpcnt;
+ of MAX_GRP_ADDR group addresses */
+ u8 dot11_grp_addr[MAX_GRP_ADDR][ETH_ALEN];
+ unsigned int dot11_grpcnt;
/* Component Identities */
- hfa384x_compident_t ident_nic;
- hfa384x_compident_t ident_pri_fw;
- hfa384x_compident_t ident_sta_fw;
- hfa384x_compident_t ident_ap_fw;
- u16 mm_mods;
+ hfa384x_compident_t ident_nic;
+ hfa384x_compident_t ident_pri_fw;
+ hfa384x_compident_t ident_sta_fw;
+ hfa384x_compident_t ident_ap_fw;
+ u16 mm_mods;
/* Supplier compatibility ranges */
- hfa384x_caplevel_t cap_sup_mfi;
- hfa384x_caplevel_t cap_sup_cfi;
- hfa384x_caplevel_t cap_sup_pri;
- hfa384x_caplevel_t cap_sup_sta;
- hfa384x_caplevel_t cap_sup_ap;
+ hfa384x_caplevel_t cap_sup_mfi;
+ hfa384x_caplevel_t cap_sup_cfi;
+ hfa384x_caplevel_t cap_sup_pri;
+ hfa384x_caplevel_t cap_sup_sta;
+ hfa384x_caplevel_t cap_sup_ap;
/* Actor compatibility ranges */
- hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */
- hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */
- hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */
- hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */
- hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */
+ hfa384x_caplevel_t cap_act_pri_cfi; /* pri f/w to controller interface */
+ hfa384x_caplevel_t cap_act_sta_cfi; /* sta f/w to controller interface */
+ hfa384x_caplevel_t cap_act_sta_mfi; /* sta f/w to modem interface */
+ hfa384x_caplevel_t cap_act_ap_cfi; /* ap f/w to controller interface */
+ hfa384x_caplevel_t cap_act_ap_mfi; /* ap f/w to modem interface */
- u32 psusercount; /* Power save user count. */
- hfa384x_CommTallies32_t tallies; /* Communication tallies. */
- u8 comment[WLAN_COMMENT_MAX+1]; /* User comment */
+ u32 psusercount; /* Power save user count. */
+ hfa384x_CommTallies32_t tallies; /* Communication tallies. */
+ u8 comment[WLAN_COMMENT_MAX + 1]; /* User comment */
/* Channel Info request results (AP only) */
struct {
- atomic_t done;
- u8 count;
- hfa384x_ChInfoResult_t results;
+ atomic_t done;
+ u8 count;
+ hfa384x_ChInfoResult_t results;
} channel_info;
- hfa384x_InfFrame_t *scanresults;
+ hfa384x_InfFrame_t *scanresults;
-
- prism2sta_authlist_t authlist; /* Authenticated station list. */
- unsigned int accessmode; /* Access mode. */
- prism2sta_accesslist_t allow; /* Allowed station list. */
- prism2sta_accesslist_t deny; /* Denied station list. */
+ prism2sta_authlist_t authlist; /* Authenticated station list. */
+ unsigned int accessmode; /* Access mode. */
+ prism2sta_accesslist_t allow; /* Allowed station list. */
+ prism2sta_accesslist_t deny; /* Denied station list. */
} hfa384x_t;
-/*=============================================================*/
-/*--- Function Declarations -----------------------------------*/
-/*=============================================================*/
-void
-hfa384x_create(
- hfa384x_t *hw,
- struct usb_device *usb);
-
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb);
void hfa384x_destroy(hfa384x_t *hw);
int
-hfa384x_corereset( hfa384x_t *hw, int holdtime, int settletime, int genesis);
-int
-hfa384x_drvr_chinforesults( hfa384x_t *hw);
-int
-hfa384x_drvr_commtallies( hfa384x_t *hw);
-int
-hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
-int
-hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
-int
-hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len);
-int
-hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-int
-hfa384x_drvr_handover( hfa384x_t *hw, u8 *addr);
-int
-hfa384x_drvr_hostscanresults( hfa384x_t *hw);
-int
-hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd);
-int
-hfa384x_drvr_mmi_read(hfa384x_t *hw, u32 address, u32 *result);
-int
-hfa384x_drvr_mmi_write(hfa384x_t *hw, u32 address, u32 data);
-int
-hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
-int
-hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
-int
-hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len);
-int
-hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
-int
-hfa384x_drvr_scanresults( hfa384x_t *hw);
-
-int
-hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
-
-static inline int
-hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
-{
- int result = 0;
+hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis);
+int hfa384x_drvr_commtallies(hfa384x_t *hw);
+int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_drvr_flashdl_enable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr);
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw);
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len);
+int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len);
+int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len);
+
+static inline int hfa384x_drvr_getconfig16(hfa384x_t *hw, u16 rid, void *val)
+{
+ int result = 0;
result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16));
- if ( result == 0 ) {
- *((u16*)val) = hfa384x2host_16(*((u16*)val));
- }
+ if (result == 0)
+ *((u16 *) val) = le16_to_cpu(*((u16 *) val));
return result;
}
-static inline int
-hfa384x_drvr_getconfig32(hfa384x_t *hw, u16 rid, void *val)
-{
- int result = 0;
-
- result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u32));
- if ( result == 0 ) {
- *((u32*)val) = hfa384x2host_32(*((u32*)val));
- }
-
- return result;
-}
-
-static inline int
-hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
-{
- u16 value = host2hfa384x_16(val);
- return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
-}
-
-static inline int
-hfa384x_drvr_setconfig32(hfa384x_t *hw, u16 rid, u32 val)
+static inline int hfa384x_drvr_setconfig16(hfa384x_t *hw, u16 rid, u16 val)
{
- u32 value = host2hfa384x_32(val);
+ u16 value = cpu_to_le16(val);
return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value));
}
int
-hfa384x_drvr_getconfig_async(hfa384x_t *hw,
- u16 rid,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
+ u16 rid, ctlx_usercb_t usercb, void *usercb_data);
int
hfa384x_drvr_setconfig_async(hfa384x_t *hw,
- u16 rid,
- void *buf,
- u16 len,
- ctlx_usercb_t usercb,
- void *usercb_data);
+ u16 rid,
+ void *buf,
+ u16 len, ctlx_usercb_t usercb, void *usercb_data);
static inline int
hfa384x_drvr_setconfig16_async(hfa384x_t *hw, u16 rid, u16 val)
{
- u16 value = host2hfa384x_16(val);
- return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
- NULL , NULL);
-}
-
-static inline int
-hfa384x_drvr_setconfig32_async(hfa384x_t *hw, u16 rid, u32 val)
-{
- u32 value = host2hfa384x_32(val);
+ u16 value = cpu_to_le16(val);
return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value),
- NULL , NULL);
+ NULL, NULL);
}
-
-int
-hfa384x_drvr_start(hfa384x_t *hw);
-int
-hfa384x_drvr_stop(hfa384x_t *hw);
-int
-hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
-void
-hfa384x_tx_timeout(wlandevice_t *wlandev);
-
-int
-hfa384x_cmd_initialize(hfa384x_t *hw);
-int
-hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
-int
-hfa384x_cmd_diagnose(hfa384x_t *hw);
-int
-hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
-int
-hfa384x_cmd_transmit(hfa384x_t *hw, u16 reclaim, u16 qos, u16 fid);
-int
-hfa384x_cmd_clearpersist(hfa384x_t *hw, u16 fid);
-int
-hfa384x_cmd_access(hfa384x_t *hw, u16 write, u16 rid, void *buf, u16 len);
-int
-hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
-int
-hfa384x_cmd_download(
- hfa384x_t *hw,
- u16 mode,
- u16 lowaddr,
- u16 highaddr,
- u16 codelen);
-int
-hfa384x_cmd_aux_enable(hfa384x_t *hw, int force);
-int
-hfa384x_cmd_aux_disable(hfa384x_t *hw);
+int hfa384x_drvr_start(hfa384x_t *hw);
+int hfa384x_drvr_stop(hfa384x_t *hw);
int
-hfa384x_copy_from_bap(
- hfa384x_t *hw,
- u16 bap,
- u16 id,
- u16 offset,
- void *buf,
- unsigned int len);
+hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+ p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
+void hfa384x_tx_timeout(wlandevice_t *wlandev);
+
+int hfa384x_cmd_initialize(hfa384x_t *hw);
+int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport);
+int hfa384x_cmd_allocate(hfa384x_t *hw, u16 len);
+int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable);
int
-hfa384x_copy_to_bap(
- hfa384x_t *hw,
- u16 bap,
- u16 id,
- u16 offset,
- void *buf,
- unsigned int len);
-void
-hfa384x_copy_from_aux(
- hfa384x_t *hw,
- u32 cardaddr,
- u32 auxctl,
- void *buf,
- unsigned int len);
-void
-hfa384x_copy_to_aux(
- hfa384x_t *hw,
- u32 cardaddr,
- u32 auxctl,
- void *buf,
- unsigned int len);
+hfa384x_cmd_download(hfa384x_t *hw,
+ u16 mode, u16 lowaddr, u16 highaddr, u16 codelen);
#endif /* __KERNEL__ */
-#endif /* _HFA384x_H */
+#endif /* _HFA384x_H */
diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c
index 8a75b50f863..888198c9a10 100644
--- a/drivers/staging/wlan-ng/hfa384x_usb.c
+++ b/drivers/staging/wlan-ng/hfa384x_usb.c
@@ -110,10 +110,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
#include <linux/version.h>
#include <linux/module.h>
@@ -130,8 +126,7 @@
#include <asm/bitops.h>
#include <linux/list.h>
#include <linux/usb.h>
-
-#include "wlan_compat.h"
+#include <linux/byteorder/generic.h>
#define SUBMIT_URB(u,f) usb_submit_urb(u,f)
@@ -150,69 +145,43 @@
#include "hfa384x.h"
#include "prism2mgmt.h"
-/*================================================================*/
-/* Local Constants */
-
-enum cmd_mode
-{
- DOWAIT = 0,
- DOASYNC
+enum cmd_mode {
+ DOWAIT = 0,
+ DOASYNC
};
typedef enum cmd_mode CMD_MODE;
#define THROTTLE_JIFFIES (HZ/8)
-
-/*================================================================*/
-/* Local Macros */
+#define URB_ASYNC_UNLINK 0
+#define USB_QUEUE_BULK 0
#define ROUNDUP64(a) (((a)+63)&~63)
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Static Definitions */
-extern int prism2_debug;
-
-/*================================================================*/
-/* Local Function Declarations */
-
#ifdef DEBUG_USB
-static void
-dbprint_urb(struct urb* urb);
+static void dbprint_urb(struct urb *urb);
#endif
static void
-hfa384x_int_rxmonitor(
- wlandevice_t *wlandev,
- hfa384x_usb_rxfrm_t *rxfrm);
+hfa384x_int_rxmonitor(wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm);
-static void
-hfa384x_usb_defer(struct work_struct *data);
+static void hfa384x_usb_defer(struct work_struct *data);
-static int
-submit_rx_urb(hfa384x_t *hw, gfp_t flags);
+static int submit_rx_urb(hfa384x_t *hw, gfp_t flags);
-static int
-submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
+static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t flags);
/*---------------------------------------------------*/
/* Callbacks */
-static void
-hfa384x_usbout_callback(struct urb *urb);
-static void
-hfa384x_ctlxout_callback(struct urb *urb);
-static void
-hfa384x_usbin_callback(struct urb *urb);
+static void hfa384x_usbout_callback(struct urb *urb);
+static void hfa384x_ctlxout_callback(struct urb *urb);
+static void hfa384x_usbin_callback(struct urb *urb);
static void
hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
-static void
-hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-static void
-hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
+static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin);
static void
hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout);
@@ -223,123 +192,94 @@ static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
/*---------------------------------------------------*/
/* Functions to support the prism2 usb command queue */
-static void
-hfa384x_usbctlxq_run(hfa384x_t *hw);
+static void hfa384x_usbctlxq_run(hfa384x_t *hw);
-static void
-hfa384x_usbctlx_reqtimerfn(unsigned long data);
+static void hfa384x_usbctlx_reqtimerfn(unsigned long data);
-static void
-hfa384x_usbctlx_resptimerfn(unsigned long data);
+static void hfa384x_usbctlx_resptimerfn(unsigned long data);
-static void
-hfa384x_usb_throttlefn(unsigned long data);
+static void hfa384x_usb_throttlefn(unsigned long data);
-static void
-hfa384x_usbctlx_completion_task(unsigned long data);
+static void hfa384x_usbctlx_completion_task(unsigned long data);
-static void
-hfa384x_usbctlx_reaper_task(unsigned long data);
+static void hfa384x_usbctlx_reaper_task(unsigned long data);
-static int
-hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
-static void
-unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
+static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
-struct usbctlx_completor
-{
- int (*complete)(struct usbctlx_completor*);
+struct usbctlx_completor {
+ int (*complete) (struct usbctlx_completor *);
};
typedef struct usbctlx_completor usbctlx_completor_t;
static int
hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
- hfa384x_usbctlx_t *ctlx,
- usbctlx_completor_t *completor);
+ hfa384x_usbctlx_t *ctlx,
+ usbctlx_completor_t *completor);
static int
unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx);
-static void
-hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
-static void
-hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
+static void hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx);
static int
usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
- hfa384x_cmdresult_t *result);
+ hfa384x_cmdresult_t *result);
static void
usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
- hfa384x_rridresult_t *result);
+ hfa384x_rridresult_t *result);
/*---------------------------------------------------*/
/* Low level req/resp CTLX formatters and submitters */
static int
-hfa384x_docmd(
- hfa384x_t *hw,
- CMD_MODE mode,
- hfa384x_metacmd_t *cmd,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_docmd(hfa384x_t *hw,
+ CMD_MODE mode,
+ hfa384x_metacmd_t *cmd,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dorrid(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dorrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dowrid(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dowrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dormem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dormem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
static int
-hfa384x_dowmem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data);
+hfa384x_dowmem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data);
-static int
-hfa384x_isgood_pdrcode(u16 pdrcode);
+static int hfa384x_isgood_pdrcode(u16 pdrcode);
-/*================================================================*/
-/* Function Definitions */
-static inline const char* ctlxstr(CTLX_STATE s)
+static inline const char *ctlxstr(CTLX_STATE s)
{
- static const char* ctlx_str[] = {
+ static const char *ctlx_str[] = {
"Initial state",
"Complete",
"Request failed",
@@ -352,36 +292,36 @@ static inline const char* ctlxstr(CTLX_STATE s)
return ctlx_str[s];
};
-
-static inline hfa384x_usbctlx_t*
-get_active_ctlx(hfa384x_t *hw)
+static inline hfa384x_usbctlx_t *get_active_ctlx(hfa384x_t *hw)
{
return list_entry(hw->ctlxq.active.next, hfa384x_usbctlx_t, list);
}
-
#ifdef DEBUG_USB
-void
-dbprint_urb(struct urb* urb)
+void dbprint_urb(struct urb *urb)
{
- WLAN_LOG_DEBUG(3,"urb->pipe=0x%08x\n", urb->pipe);
- WLAN_LOG_DEBUG(3,"urb->status=0x%08x\n", urb->status);
- WLAN_LOG_DEBUG(3,"urb->transfer_flags=0x%08x\n", urb->transfer_flags);
- WLAN_LOG_DEBUG(3,"urb->transfer_buffer=0x%08x\n", (unsigned int)urb->transfer_buffer);
- WLAN_LOG_DEBUG(3,"urb->transfer_buffer_length=0x%08x\n", urb->transfer_buffer_length);
- WLAN_LOG_DEBUG(3,"urb->actual_length=0x%08x\n", urb->actual_length);
- WLAN_LOG_DEBUG(3,"urb->bandwidth=0x%08x\n", urb->bandwidth);
- WLAN_LOG_DEBUG(3,"urb->setup_packet(ctl)=0x%08x\n", (unsigned int)urb->setup_packet);
- WLAN_LOG_DEBUG(3,"urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame);
- WLAN_LOG_DEBUG(3,"urb->interval(irq)=0x%08x\n", urb->interval);
- WLAN_LOG_DEBUG(3,"urb->error_count(iso)=0x%08x\n", urb->error_count);
- WLAN_LOG_DEBUG(3,"urb->timeout=0x%08x\n", urb->timeout);
- WLAN_LOG_DEBUG(3,"urb->context=0x%08x\n", (unsigned int)urb->context);
- WLAN_LOG_DEBUG(3,"urb->complete=0x%08x\n", (unsigned int)urb->complete);
+ pr_debug("urb->pipe=0x%08x\n", urb->pipe);
+ pr_debug("urb->status=0x%08x\n", urb->status);
+ pr_debug("urb->transfer_flags=0x%08x\n", urb->transfer_flags);
+ pr_debug("urb->transfer_buffer=0x%08x\n",
+ (unsigned int)urb->transfer_buffer);
+ pr_debug("urb->transfer_buffer_length=0x%08x\n",
+ urb->transfer_buffer_length);
+ pr_debug("urb->actual_length=0x%08x\n", urb->actual_length);
+ pr_debug("urb->bandwidth=0x%08x\n", urb->bandwidth);
+ pr_debug("urb->setup_packet(ctl)=0x%08x\n",
+ (unsigned int)urb->setup_packet);
+ pr_debug("urb->start_frame(iso/irq)=0x%08x\n",
+ urb->start_frame);
+ pr_debug("urb->interval(irq)=0x%08x\n", urb->interval);
+ pr_debug("urb->error_count(iso)=0x%08x\n", urb->error_count);
+ pr_debug("urb->timeout=0x%08x\n", urb->timeout);
+ pr_debug("urb->context=0x%08x\n", (unsigned int)urb->context);
+ pr_debug("urb->complete=0x%08x\n",
+ (unsigned int)urb->complete);
}
#endif
-
/*----------------------------------------------------------------
* submit_rx_urb
*
@@ -398,14 +338,11 @@ dbprint_urb(struct urb* urb)
* Call context:
* Any
----------------------------------------------------------------*/
-static int
-submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
+static int submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
{
struct sk_buff *skb;
int result;
- DBFENTER;
-
skb = dev_alloc_skb(sizeof(hfa384x_usbin_t));
if (skb == NULL) {
result = -ENOMEM;
@@ -414,21 +351,22 @@ submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
/* Post the IN urb */
usb_fill_bulk_urb(&hw->rx_urb, hw->usb,
- hw->endp_in,
- skb->data, sizeof(hfa384x_usbin_t),
- hfa384x_usbin_callback, hw->wlandev);
+ hw->endp_in,
+ skb->data, sizeof(hfa384x_usbin_t),
+ hfa384x_usbin_callback, hw->wlandev);
hw->rx_urb_skb = skb;
result = -ENOLINK;
- if ( !hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
+ if (!hw->wlandev->hwremoved && !test_bit(WORK_RX_HALT, &hw->usb_flags)) {
result = SUBMIT_URB(&hw->rx_urb, memflags);
/* Check whether we need to reset the RX pipe */
if (result == -EPIPE) {
- WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
- hw->wlandev->netdev->name);
- if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+ printk(KERN_WARNING
+ "%s rx pipe stalled: requesting reset\n",
+ hw->wlandev->netdev->name);
+ if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
schedule_work(&hw->usb_work);
}
}
@@ -439,9 +377,7 @@ submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
hw->rx_urb_skb = NULL;
}
- done:
-
- DBFEXIT;
+done:
return result;
}
@@ -463,24 +399,23 @@ submit_rx_urb(hfa384x_t *hw, gfp_t memflags)
* Call context:
* Any
----------------------------------------------------------------*/
-static int
-submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
+static int submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
{
struct net_device *netdev = hw->wlandev->netdev;
int result;
- DBFENTER;
-
result = -ENOLINK;
- if ( netif_running(netdev) ) {
+ if (netif_running(netdev)) {
- if ( !hw->wlandev->hwremoved && !test_bit(WORK_TX_HALT, &hw->usb_flags) ) {
+ if (!hw->wlandev->hwremoved
+ && !test_bit(WORK_TX_HALT, &hw->usb_flags)) {
result = SUBMIT_URB(tx_urb, memflags);
/* Test whether we need to reset the TX pipe */
if (result == -EPIPE) {
- WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
- netdev->name);
+ printk(KERN_WARNING
+ "%s tx pipe stalled: requesting reset\n",
+ netdev->name);
set_bit(WORK_TX_HALT, &hw->usb_flags);
schedule_work(&hw->usb_work);
} else if (result == 0) {
@@ -489,8 +424,6 @@ submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
}
}
- DBFEXIT;
-
return result;
}
@@ -510,27 +443,22 @@ submit_tx_urb(hfa384x_t *hw, struct urb *tx_urb, gfp_t memflags)
* Call context:
* process (by design)
----------------------------------------------------------------*/
-static void
-hfa384x_usb_defer(struct work_struct *data)
+static void hfa384x_usb_defer(struct work_struct *data)
{
hfa384x_t *hw = container_of(data, struct hfa384x, usb_work);
struct net_device *netdev = hw->wlandev->netdev;
- DBFENTER;
-
/* Don't bother trying to reset anything if the plug
* has been pulled ...
*/
- if ( hw->wlandev->hwremoved ) {
- DBFEXIT;
+ if (hw->wlandev->hwremoved)
return;
- }
/* Reception has stopped: try to reset the input pipe */
if (test_bit(WORK_RX_HALT, &hw->usb_flags)) {
int ret;
- usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */
+ usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */
ret = usb_clear_halt(hw->usb, hw->endp_in);
if (ret != 0) {
@@ -539,14 +467,14 @@ hfa384x_usb_defer(struct work_struct *data)
netdev->name, ret);
} else {
printk(KERN_INFO "%s rx pipe reset complete.\n",
- netdev->name);
+ netdev->name);
clear_bit(WORK_RX_HALT, &hw->usb_flags);
set_bit(WORK_RX_RESUME, &hw->usb_flags);
}
}
/* Resume receiving data back from the device. */
- if ( test_bit(WORK_RX_RESUME, &hw->usb_flags) ) {
+ if (test_bit(WORK_RX_RESUME, &hw->usb_flags)) {
int ret;
ret = submit_rx_urb(hw, GFP_KERNEL);
@@ -570,7 +498,7 @@ hfa384x_usb_defer(struct work_struct *data)
netdev->name, ret);
} else {
printk(KERN_INFO "%s tx pipe reset complete.\n",
- netdev->name);
+ netdev->name);
clear_bit(WORK_TX_HALT, &hw->usb_flags);
set_bit(WORK_TX_RESUME, &hw->usb_flags);
@@ -583,14 +511,10 @@ hfa384x_usb_defer(struct work_struct *data)
}
/* Resume transmitting. */
- if ( test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags) ) {
+ if (test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags))
netif_wake_queue(hw->wlandev->netdev);
- }
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_create
*
@@ -612,11 +536,8 @@ hfa384x_usb_defer(struct work_struct *data)
* Call context:
* process
----------------------------------------------------------------*/
-void
-hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
+void hfa384x_create(hfa384x_t *hw, struct usb_device *usb)
{
- DBFENTER;
-
memset(hw, 0, sizeof(hfa384x_t));
hw->usb = usb;
@@ -638,11 +559,9 @@ hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
skb_queue_head_init(&hw->authq);
tasklet_init(&hw->reaper_bh,
- hfa384x_usbctlx_reaper_task,
- (unsigned long)hw);
+ hfa384x_usbctlx_reaper_task, (unsigned long)hw);
tasklet_init(&hw->completion_bh,
- hfa384x_usbctlx_completion_task,
- (unsigned long)hw);
+ hfa384x_usbctlx_completion_task, (unsigned long)hw);
INIT_WORK(&hw->link_bh, prism2sta_processing_defer);
INIT_WORK(&hw->usb_work, hfa384x_usb_defer);
@@ -665,15 +584,12 @@ hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
hw->link_status = HFA384x_LINK_NOTCONNECTED;
hw->state = HFA384x_STATE_INIT;
- INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
+ INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer);
init_timer(&hw->commsqual_timer);
- hw->commsqual_timer.data = (unsigned long) hw;
+ hw->commsqual_timer.data = (unsigned long)hw;
hw->commsqual_timer.function = prism2sta_commsqual_timer;
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_destroy
*
@@ -696,16 +612,12 @@ hfa384x_create( hfa384x_t *hw, struct usb_device *usb)
* Call context:
* process
----------------------------------------------------------------*/
-void
-hfa384x_destroy( hfa384x_t *hw)
+void hfa384x_destroy(hfa384x_t *hw)
{
struct sk_buff *skb;
- DBFENTER;
-
- if ( hw->state == HFA384x_STATE_RUNNING ) {
+ if (hw->state == HFA384x_STATE_RUNNING)
hfa384x_drvr_stop(hw);
- }
hw->state = HFA384x_STATE_PREINIT;
if (hw->scanresults) {
@@ -714,23 +626,16 @@ hfa384x_destroy( hfa384x_t *hw)
}
/* Now to clean out the auth queue */
- while ( (skb = skb_dequeue(&hw->authq)) ) {
- dev_kfree_skb(skb);
- }
-
- DBFEXIT;
+ while ((skb = skb_dequeue(&hw->authq)))
+ dev_kfree_skb(skb);
}
-
-/*----------------------------------------------------------------
- */
-static hfa384x_usbctlx_t* usbctlx_alloc(void)
+static hfa384x_usbctlx_t *usbctlx_alloc(void)
{
hfa384x_usbctlx_t *ctlx;
ctlx = kmalloc(sizeof(*ctlx), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
- if (ctlx != NULL)
- {
+ if (ctlx != NULL) {
memset(ctlx, 0, sizeof(*ctlx));
init_completion(&ctlx->done);
}
@@ -738,70 +643,58 @@ static hfa384x_usbctlx_t* usbctlx_alloc(void)
return ctlx;
}
-
-/*----------------------------------------------------------------
- *
-----------------------------------------------------------------*/
static int
usbctlx_get_status(const hfa384x_usb_cmdresp_t *cmdresp,
- hfa384x_cmdresult_t *result)
+ hfa384x_cmdresult_t *result)
{
- DBFENTER;
-
- result->status = hfa384x2host_16(cmdresp->status);
- result->resp0 = hfa384x2host_16(cmdresp->resp0);
- result->resp1 = hfa384x2host_16(cmdresp->resp1);
- result->resp2 = hfa384x2host_16(cmdresp->resp2);
-
- WLAN_LOG_DEBUG(4, "cmdresult:status=0x%04x "
- "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
- result->status,
- result->resp0,
- result->resp1,
- result->resp2);
-
- DBFEXIT;
- return (result->status & HFA384x_STATUS_RESULT);
+ result->status = le16_to_cpu(cmdresp->status);
+ result->resp0 = le16_to_cpu(cmdresp->resp0);
+ result->resp1 = le16_to_cpu(cmdresp->resp1);
+ result->resp2 = le16_to_cpu(cmdresp->resp2);
+
+ pr_debug("cmdresult:status=0x%04x "
+ "resp0=0x%04x resp1=0x%04x resp2=0x%04x\n",
+ result->status, result->resp0, result->resp1, result->resp2);
+
+ return result->status & HFA384x_STATUS_RESULT;
}
static void
usbctlx_get_rridresult(const hfa384x_usb_rridresp_t *rridresp,
- hfa384x_rridresult_t *result)
+ hfa384x_rridresult_t *result)
{
- DBFENTER;
-
- result->rid = hfa384x2host_16(rridresp->rid);
+ result->rid = le16_to_cpu(rridresp->rid);
result->riddata = rridresp->data;
- result->riddata_len = ((hfa384x2host_16(rridresp->frmlen) - 1) * 2);
+ result->riddata_len = ((le16_to_cpu(rridresp->frmlen) - 1) * 2);
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* Completor object:
* This completor must be passed to hfa384x_usbctlx_complete_sync()
* when processing a CTLX that returns a hfa384x_cmdresult_t structure.
----------------------------------------------------------------*/
-struct usbctlx_cmd_completor
-{
- usbctlx_completor_t head;
+struct usbctlx_cmd_completor {
+ usbctlx_completor_t head;
- const hfa384x_usb_cmdresp_t *cmdresp;
- hfa384x_cmdresult_t *result;
+ const hfa384x_usb_cmdresp_t *cmdresp;
+ hfa384x_cmdresult_t *result;
};
typedef struct usbctlx_cmd_completor usbctlx_cmd_completor_t;
static int usbctlx_cmd_completor_fn(usbctlx_completor_t *head)
{
- usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t*)head;
+ usbctlx_cmd_completor_t *complete = (usbctlx_cmd_completor_t *) head;
return usbctlx_get_status(complete->cmdresp, complete->result);
}
-static inline usbctlx_completor_t*
-init_cmd_completor(usbctlx_cmd_completor_t *completor,
- const hfa384x_usb_cmdresp_t *cmdresp,
- hfa384x_cmdresult_t *result)
+static inline usbctlx_completor_t *init_cmd_completor(usbctlx_cmd_completor_t *
+ completor,
+ const
+ hfa384x_usb_cmdresp_t *
+ cmdresp,
+ hfa384x_cmdresult_t *
+ result)
{
completor->head.complete = usbctlx_cmd_completor_fn;
completor->cmdresp = cmdresp;
@@ -814,44 +707,41 @@ init_cmd_completor(usbctlx_cmd_completor_t *completor,
* This completor must be passed to hfa384x_usbctlx_complete_sync()
* when processing a CTLX that reads a RID.
----------------------------------------------------------------*/
-struct usbctlx_rrid_completor
-{
- usbctlx_completor_t head;
+struct usbctlx_rrid_completor {
+ usbctlx_completor_t head;
- const hfa384x_usb_rridresp_t *rridresp;
- void *riddata;
- unsigned int riddatalen;
+ const hfa384x_usb_rridresp_t *rridresp;
+ void *riddata;
+ unsigned int riddatalen;
};
typedef struct usbctlx_rrid_completor usbctlx_rrid_completor_t;
static int usbctlx_rrid_completor_fn(usbctlx_completor_t *head)
{
- usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t*)head;
+ usbctlx_rrid_completor_t *complete = (usbctlx_rrid_completor_t *) head;
hfa384x_rridresult_t rridresult;
usbctlx_get_rridresult(complete->rridresp, &rridresult);
/* Validate the length, note body len calculation in bytes */
- if ( rridresult.riddata_len != complete->riddatalen ) {
- WLAN_LOG_WARNING(
- "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
- rridresult.rid,
- complete->riddatalen,
- rridresult.riddata_len);
+ if (rridresult.riddata_len != complete->riddatalen) {
+ printk(KERN_WARNING
+ "RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n",
+ rridresult.rid,
+ complete->riddatalen, rridresult.riddata_len);
return -ENODATA;
}
- memcpy(complete->riddata,
- rridresult.riddata,
- complete->riddatalen);
+ memcpy(complete->riddata, rridresult.riddata, complete->riddatalen);
return 0;
}
-static inline usbctlx_completor_t*
-init_rrid_completor(usbctlx_rrid_completor_t *completor,
- const hfa384x_usb_rridresp_t *rridresp,
- void *riddata,
- unsigned int riddatalen)
+static inline usbctlx_completor_t *init_rrid_completor(usbctlx_rrid_completor_t
+ *completor,
+ const
+ hfa384x_usb_rridresp_t *
+ rridresp, void *riddata,
+ unsigned int riddatalen)
{
completor->head.complete = usbctlx_rrid_completor_fn;
completor->rridresp = rridresp;
@@ -878,30 +768,29 @@ typedef usbctlx_cmd_completor_t usbctlx_wmem_completor_t;
* Completor object:
* Interprets the results of a synchronous memory-read
----------------------------------------------------------------*/
-struct usbctlx_rmem_completor
-{
- usbctlx_completor_t head;
+struct usbctlx_rmem_completor {
+ usbctlx_completor_t head;
- const hfa384x_usb_rmemresp_t *rmemresp;
- void *data;
- unsigned int len;
+ const hfa384x_usb_rmemresp_t *rmemresp;
+ void *data;
+ unsigned int len;
};
typedef struct usbctlx_rmem_completor usbctlx_rmem_completor_t;
static int usbctlx_rmem_completor_fn(usbctlx_completor_t *head)
{
- usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t*)head;
+ usbctlx_rmem_completor_t *complete = (usbctlx_rmem_completor_t *) head;
- WLAN_LOG_DEBUG(4,"rmemresp:len=%d\n", complete->rmemresp->frmlen);
+ pr_debug("rmemresp:len=%d\n", complete->rmemresp->frmlen);
memcpy(complete->data, complete->rmemresp->data, complete->len);
return 0;
}
-static inline usbctlx_completor_t*
-init_rmem_completor(usbctlx_rmem_completor_t *completor,
- hfa384x_usb_rmemresp_t *rmemresp,
- void *data,
- unsigned int len)
+static inline usbctlx_completor_t *init_rmem_completor(usbctlx_rmem_completor_t
+ *completor,
+ hfa384x_usb_rmemresp_t
+ *rmemresp, void *data,
+ unsigned int len)
{
completor->head.complete = usbctlx_rmem_completor_fn;
completor->rmemresp = rmemresp;
@@ -931,28 +820,23 @@ init_rmem_completor(usbctlx_rmem_completor_t *completor,
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+static void hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
{
- DBFENTER;
-
- if ( ctlx->usercb != NULL ) {
+ if (ctlx->usercb != NULL) {
hfa384x_cmdresult_t cmdresult;
if (ctlx->state != CTLX_COMPLETE) {
memset(&cmdresult, 0, sizeof(cmdresult));
- cmdresult.status = HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
+ cmdresult.status =
+ HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR);
} else {
usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult);
}
ctlx->usercb(hw, &cmdresult, ctlx->usercb_data);
}
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_cb_rrid
*
@@ -973,132 +857,114 @@ hfa384x_cb_status(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
+static void hfa384x_cb_rrid(hfa384x_t *hw, const hfa384x_usbctlx_t *ctlx)
{
- DBFENTER;
-
- if ( ctlx->usercb != NULL ) {
+ if (ctlx->usercb != NULL) {
hfa384x_rridresult_t rridresult;
if (ctlx->state != CTLX_COMPLETE) {
memset(&rridresult, 0, sizeof(rridresult));
- rridresult.rid = hfa384x2host_16(ctlx->outbuf.rridreq.rid);
+ rridresult.rid =
+ le16_to_cpu(ctlx->outbuf.rridreq.rid);
} else {
- usbctlx_get_rridresult(&ctlx->inbuf.rridresp, &rridresult);
+ usbctlx_get_rridresult(&ctlx->inbuf.rridresp,
+ &rridresult);
}
ctlx->usercb(hw, &rridresult, ctlx->usercb_data);
}
-
- DBFEXIT;
}
-static inline int
-hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
+static inline int hfa384x_docmd_wait(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
{
return hfa384x_docmd(hw, DOWAIT, cmd, NULL, NULL, NULL);
}
static inline int
hfa384x_docmd_async(hfa384x_t *hw,
- hfa384x_metacmd_t *cmd,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+ hfa384x_metacmd_t *cmd,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- return hfa384x_docmd(hw, DOASYNC, cmd,
- cmdcb, usercb, usercb_data);
+ return hfa384x_docmd(hw, DOASYNC, cmd, cmdcb, usercb, usercb_data);
}
static inline int
-hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata, unsigned int riddatalen)
+hfa384x_dorrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+ unsigned int riddatalen)
{
return hfa384x_dorrid(hw, DOWAIT,
- rid, riddata, riddatalen,
- NULL, NULL, NULL);
+ rid, riddata, riddatalen, NULL, NULL, NULL);
}
static inline int
hfa384x_dorrid_async(hfa384x_t *hw,
- u16 rid, void *riddata, unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+ u16 rid, void *riddata, unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_dorrid(hw, DOASYNC,
- rid, riddata, riddatalen,
- cmdcb, usercb, usercb_data);
+ rid, riddata, riddatalen,
+ cmdcb, usercb, usercb_data);
}
static inline int
-hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata, unsigned int riddatalen)
+hfa384x_dowrid_wait(hfa384x_t *hw, u16 rid, void *riddata,
+ unsigned int riddatalen)
{
return hfa384x_dowrid(hw, DOWAIT,
- rid, riddata, riddatalen,
- NULL, NULL, NULL);
+ rid, riddata, riddatalen, NULL, NULL, NULL);
}
static inline int
hfa384x_dowrid_async(hfa384x_t *hw,
- u16 rid, void *riddata, unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+ u16 rid, void *riddata, unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_dowrid(hw, DOASYNC,
- rid, riddata, riddatalen,
- cmdcb, usercb, usercb_data);
+ rid, riddata, riddatalen,
+ cmdcb, usercb, usercb_data);
}
static inline int
hfa384x_dormem_wait(hfa384x_t *hw,
- u16 page, u16 offset, void *data, unsigned int len)
+ u16 page, u16 offset, void *data, unsigned int len)
{
return hfa384x_dormem(hw, DOWAIT,
- page, offset, data, len,
- NULL, NULL, NULL);
+ page, offset, data, len, NULL, NULL, NULL);
}
static inline int
hfa384x_dormem_async(hfa384x_t *hw,
- u16 page, u16 offset, void *data, unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+ u16 page, u16 offset, void *data, unsigned int len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_dormem(hw, DOASYNC,
- page, offset, data, len,
- cmdcb, usercb, usercb_data);
+ page, offset, data, len,
+ cmdcb, usercb, usercb_data);
}
static inline int
-hfa384x_dowmem_wait(
- hfa384x_t *hw,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len)
+hfa384x_dowmem_wait(hfa384x_t *hw,
+ u16 page, u16 offset, void *data, unsigned int len)
{
return hfa384x_dowmem(hw, DOWAIT,
- page, offset, data, len,
- NULL, NULL, NULL);
+ page, offset, data, len, NULL, NULL, NULL);
}
static inline int
-hfa384x_dowmem_async(
- hfa384x_t *hw,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dowmem_async(hfa384x_t *hw,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb,
+ ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_dowmem(hw, DOASYNC,
- page, offset, data, len,
- cmdcb, usercb, usercb_data);
+ page, offset, data, len,
+ cmdcb, usercb, usercb_data);
}
/*----------------------------------------------------------------
@@ -1120,16 +986,12 @@ hfa384x_dowmem_async(
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_cmd_initialize(hfa384x_t *hw)
+int hfa384x_cmd_initialize(hfa384x_t *hw)
{
- int result = 0;
- int i;
+ int result = 0;
+ int i;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
-
cmd.cmd = HFA384x_CMDCODE_INIT;
cmd.parm0 = 0;
cmd.parm1 = 0;
@@ -1137,27 +999,21 @@ hfa384x_cmd_initialize(hfa384x_t *hw)
result = hfa384x_docmd_wait(hw, &cmd);
-
- WLAN_LOG_DEBUG(3,"cmdresp.init: "
- "status=0x%04x, resp0=0x%04x, "
- "resp1=0x%04x, resp2=0x%04x\n",
- cmd.result.status,
- cmd.result.resp0,
- cmd.result.resp1,
- cmd.result.resp2);
- if ( result == 0 ) {
- for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+ pr_debug("cmdresp.init: "
+ "status=0x%04x, resp0=0x%04x, "
+ "resp1=0x%04x, resp2=0x%04x\n",
+ cmd.result.status,
+ cmd.result.resp0, cmd.result.resp1, cmd.result.resp2);
+ if (result == 0) {
+ for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
hw->port_enabled[i] = 0;
- }
}
- hw->link_status = HFA384x_LINK_NOTCONNECTED;
+ hw->link_status = HFA384x_LINK_NOTCONNECTED;
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_cmd_disable
*
@@ -1180,24 +1036,20 @@ hfa384x_cmd_initialize(hfa384x_t *hw)
----------------------------------------------------------------*/
int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) |
- HFA384x_CMD_MACPORT_SET(macport);
+ HFA384x_CMD_MACPORT_SET(macport);
cmd.parm0 = 0;
cmd.parm1 = 0;
cmd.parm2 = 0;
result = hfa384x_docmd_wait(hw, &cmd);
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_cmd_enable
*
@@ -1220,20 +1072,17 @@ int hfa384x_cmd_disable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) |
- HFA384x_CMD_MACPORT_SET(macport);
+ HFA384x_CMD_MACPORT_SET(macport);
cmd.parm0 = 0;
cmd.parm1 = 0;
cmd.parm2 = 0;
result = hfa384x_docmd_wait(hw, &cmd);
- DBFEXIT;
return result;
}
@@ -1268,24 +1117,20 @@ int hfa384x_cmd_enable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
{
- int result = 0;
+ int result = 0;
hfa384x_metacmd_t cmd;
- DBFENTER;
-
cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) |
- HFA384x_CMD_AINFO_SET(enable);
+ HFA384x_CMD_AINFO_SET(enable);
cmd.parm0 = 0;
cmd.parm1 = 0;
cmd.parm2 = 0;
result = hfa384x_docmd_wait(hw, &cmd);
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_cmd_download
*
@@ -1325,15 +1170,14 @@ int hfa384x_cmd_monitor(hfa384x_t *hw, u16 enable)
* process
----------------------------------------------------------------*/
int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
- u16 highaddr, u16 codelen)
+ u16 highaddr, u16 codelen)
{
- int result = 0;
+ int result = 0;
hfa384x_metacmd_t cmd;
- DBFENTER;
- WLAN_LOG_DEBUG(5,
- "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
- mode, lowaddr, highaddr, codelen);
+ printk(KERN_DEBUG
+ "mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n",
+ mode, lowaddr, highaddr, codelen);
cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) |
HFA384x_CMD_PROGMODE_SET(mode));
@@ -1344,79 +1188,9 @@ int hfa384x_cmd_download(hfa384x_t *hw, u16 mode, u16 lowaddr,
result = hfa384x_docmd_wait(hw, &cmd);
- DBFEXIT;
return result;
}
-
-/*----------------------------------------------------------------
-* hfa384x_copy_from_aux
-*
-* Copies a collection of bytes from the controller memory. The
-* Auxiliary port MUST be enabled prior to calling this function.
-* We _might_ be in a download state.
-*
-* Arguments:
-* hw device structure
-* cardaddr address in hfa384x data space to read
-* auxctl address space select
-* buf ptr to destination host buffer
-* len length of data to transfer (in bytes)
-*
-* Returns:
-* nothing
-*
-* Side effects:
-* buf contains the data copied
-*
-* Call context:
-* process
-* interrupt
-----------------------------------------------------------------*/
-void
-hfa384x_copy_from_aux(
- hfa384x_t *hw, u32 cardaddr, u32 auxctl, void *buf, unsigned int len)
-{
- DBFENTER;
- WLAN_LOG_ERROR("not used in USB.\n");
- DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* hfa384x_copy_to_aux
-*
-* Copies a collection of bytes to the controller memory. The
-* Auxiliary port MUST be enabled prior to calling this function.
-* We _might_ be in a download state.
-*
-* Arguments:
-* hw device structure
-* cardaddr address in hfa384x data space to read
-* auxctl address space select
-* buf ptr to destination host buffer
-* len length of data to transfer (in bytes)
-*
-* Returns:
-* nothing
-*
-* Side effects:
-* Controller memory now contains a copy of buf
-*
-* Call context:
-* process
-* interrupt
-----------------------------------------------------------------*/
-void
-hfa384x_copy_to_aux(
- hfa384x_t *hw, u32 cardaddr, u32 auxctl, void *buf, unsigned int len)
-{
- DBFENTER;
- WLAN_LOG_ERROR("not used in USB.\n");
- DBFEXIT;
-}
-
-
/*----------------------------------------------------------------
* hfa384x_corereset
*
@@ -1442,20 +1216,17 @@ hfa384x_copy_to_aux(
----------------------------------------------------------------*/
int hfa384x_corereset(hfa384x_t *hw, int holdtime, int settletime, int genesis)
{
- int result = 0;
-
- DBFENTER;
+ int result = 0;
- result=usb_reset_device(hw->usb);
- if(result<0) {
- WLAN_LOG_ERROR("usb_reset_device() failed, result=%d.\n",result);
+ result = usb_reset_device(hw->usb);
+ if (result < 0) {
+ printk(KERN_ERR "usb_reset_device() failed, result=%d.\n",
+ result);
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_usbctlx_complete_sync
*
@@ -1487,8 +1258,6 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
unsigned long flags;
int result;
- DBFENTER;
-
result = wait_for_completion_interruptible(&ctlx->done);
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -1497,14 +1266,11 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* We can only handle the CTLX if the USB disconnect
* function has not run yet ...
*/
- cleanup:
- if ( hw->wlandev->hwremoved )
- {
+cleanup:
+ if (hw->wlandev->hwremoved) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
result = -ENODEV;
- }
- else if ( result != 0 )
- {
+ } else if (result != 0) {
int runqueue = 0;
/*
@@ -1516,8 +1282,7 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* NOTE: We can only delete the timers and
* the URB if this CTLX is active.
*/
- if (ctlx == get_active_ctlx(hw))
- {
+ if (ctlx == get_active_ctlx(hw)) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
del_singleshot_timer_sync(&hw->reqtimer);
@@ -1534,7 +1299,7 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* This scenario is so unlikely that I'm
* happy with a grubby "goto" solution ...
*/
- if ( hw->wlandev->hwremoved )
+ if (hw->wlandev->hwremoved)
goto cleanup;
}
@@ -1555,9 +1320,9 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
if (ctlx->state == CTLX_COMPLETE) {
result = completor->complete(completor);
} else {
- WLAN_LOG_WARNING("CTLX[%d] error: state(%s)\n",
- hfa384x2host_16(ctlx->outbuf.type),
- ctlxstr(ctlx->state));
+ printk(KERN_WARNING "CTLX[%d] error: state(%s)\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
result = -EIO;
}
@@ -1566,7 +1331,6 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
kfree(ctlx);
}
- DBFEXIT;
return result;
}
@@ -1603,39 +1367,32 @@ static int hfa384x_usbctlx_complete_sync(hfa384x_t *hw,
* process
----------------------------------------------------------------*/
static int
-hfa384x_docmd(
- hfa384x_t *hw,
- CMD_MODE mode,
- hfa384x_metacmd_t *cmd,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_docmd(hfa384x_t *hw,
+ CMD_MODE mode,
+ hfa384x_metacmd_t *cmd,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ if (ctlx == NULL) {
result = -ENOMEM;
goto done;
}
/* Initialize the command */
- ctlx->outbuf.cmdreq.type = host2hfa384x_16(HFA384x_USB_CMDREQ);
- ctlx->outbuf.cmdreq.cmd = host2hfa384x_16(cmd->cmd);
- ctlx->outbuf.cmdreq.parm0 = host2hfa384x_16(cmd->parm0);
- ctlx->outbuf.cmdreq.parm1 = host2hfa384x_16(cmd->parm1);
- ctlx->outbuf.cmdreq.parm2 = host2hfa384x_16(cmd->parm2);
+ ctlx->outbuf.cmdreq.type = cpu_to_le16(HFA384x_USB_CMDREQ);
+ ctlx->outbuf.cmdreq.cmd = cpu_to_le16(cmd->cmd);
+ ctlx->outbuf.cmdreq.parm0 = cpu_to_le16(cmd->parm0);
+ ctlx->outbuf.cmdreq.parm1 = cpu_to_le16(cmd->parm1);
+ ctlx->outbuf.cmdreq.parm2 = cpu_to_le16(cmd->parm2);
ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq);
- WLAN_LOG_DEBUG(4, "cmdreq: cmd=0x%04x "
- "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
- cmd->cmd,
- cmd->parm0,
- cmd->parm1,
- cmd->parm2);
+ pr_debug("cmdreq: cmd=0x%04x "
+ "parm0=0x%04x parm1=0x%04x parm2=0x%04x\n",
+ cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2);
ctlx->reapable = mode;
ctlx->cmdcb = cmdcb;
@@ -1648,18 +1405,20 @@ hfa384x_docmd(
} else if (mode == DOWAIT) {
usbctlx_cmd_completor_t completor;
- result = hfa384x_usbctlx_complete_sync(
- hw, ctlx, init_cmd_completor(&completor,
- &ctlx->inbuf.cmdresp,
- &cmd->result) );
+ result =
+ hfa384x_usbctlx_complete_sync(hw, ctlx,
+ init_cmd_completor(&completor,
+ &ctlx->
+ inbuf.
+ cmdresp,
+ &cmd->
+ result));
}
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_dorrid
*
@@ -1697,31 +1456,27 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dorrid(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dorrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ if (ctlx == NULL) {
result = -ENOMEM;
goto done;
}
/* Initialize the command */
- ctlx->outbuf.rridreq.type = host2hfa384x_16(HFA384x_USB_RRIDREQ);
+ ctlx->outbuf.rridreq.type = cpu_to_le16(HFA384x_USB_RRIDREQ);
ctlx->outbuf.rridreq.frmlen =
- host2hfa384x_16(sizeof(ctlx->outbuf.rridreq.rid));
- ctlx->outbuf.rridreq.rid = host2hfa384x_16(rid);
+ cpu_to_le16(sizeof(ctlx->outbuf.rridreq.rid));
+ ctlx->outbuf.rridreq.rid = cpu_to_le16(rid);
ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq);
@@ -1737,19 +1492,18 @@ hfa384x_dorrid(
} else if (mode == DOWAIT) {
usbctlx_rrid_completor_t completor;
- result = hfa384x_usbctlx_complete_sync(
- hw, ctlx, init_rrid_completor(&completor,
- &ctlx->inbuf.rridresp,
- riddata,
- riddatalen) );
+ result =
+ hfa384x_usbctlx_complete_sync(hw, ctlx,
+ init_rrid_completor
+ (&completor,
+ &ctlx->inbuf.rridresp,
+ riddata, riddatalen));
}
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_dowrid
*
@@ -1783,38 +1537,34 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dowrid(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 rid,
- void *riddata,
- unsigned int riddatalen,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dowrid(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 rid,
+ void *riddata,
+ unsigned int riddatalen,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ if (ctlx == NULL) {
result = -ENOMEM;
goto done;
}
/* Initialize the command */
- ctlx->outbuf.wridreq.type = host2hfa384x_16(HFA384x_USB_WRIDREQ);
- ctlx->outbuf.wridreq.frmlen = host2hfa384x_16(
- (sizeof(ctlx->outbuf.wridreq.rid) +
- riddatalen + 1) / 2);
- ctlx->outbuf.wridreq.rid = host2hfa384x_16(rid);
+ ctlx->outbuf.wridreq.type = cpu_to_le16(HFA384x_USB_WRIDREQ);
+ ctlx->outbuf.wridreq.frmlen = cpu_to_le16((sizeof
+ (ctlx->outbuf.wridreq.
+ rid) + riddatalen +
+ 1) / 2);
+ ctlx->outbuf.wridreq.rid = cpu_to_le16(rid);
memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen);
ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) +
- sizeof(ctlx->outbuf.wridreq.frmlen) +
- sizeof(ctlx->outbuf.wridreq.rid) +
- riddatalen;
+ sizeof(ctlx->outbuf.wridreq.frmlen) +
+ sizeof(ctlx->outbuf.wridreq.rid) + riddatalen;
ctlx->reapable = mode;
ctlx->cmdcb = cmdcb;
@@ -1829,16 +1579,15 @@ hfa384x_dowrid(
usbctlx_wrid_completor_t completor;
hfa384x_cmdresult_t wridresult;
- result = hfa384x_usbctlx_complete_sync(
- hw,
- ctlx,
- init_wrid_completor(&completor,
- &ctlx->inbuf.wridresp,
- &wridresult) );
+ result = hfa384x_usbctlx_complete_sync(hw,
+ ctlx,
+ init_wrid_completor
+ (&completor,
+ &ctlx->inbuf.wridresp,
+ &wridresult));
}
done:
- DBFEXIT;
return result;
}
@@ -1876,47 +1625,41 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dormem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dormem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ if (ctlx == NULL) {
result = -ENOMEM;
goto done;
}
/* Initialize the command */
- ctlx->outbuf.rmemreq.type = host2hfa384x_16(HFA384x_USB_RMEMREQ);
- ctlx->outbuf.rmemreq.frmlen = host2hfa384x_16(
- sizeof(ctlx->outbuf.rmemreq.offset) +
- sizeof(ctlx->outbuf.rmemreq.page) +
- len);
- ctlx->outbuf.rmemreq.offset = host2hfa384x_16(offset);
- ctlx->outbuf.rmemreq.page = host2hfa384x_16(page);
+ ctlx->outbuf.rmemreq.type = cpu_to_le16(HFA384x_USB_RMEMREQ);
+ ctlx->outbuf.rmemreq.frmlen =
+ cpu_to_le16(sizeof(ctlx->outbuf.rmemreq.offset) +
+ sizeof(ctlx->outbuf.rmemreq.page) + len);
+ ctlx->outbuf.rmemreq.offset = cpu_to_le16(offset);
+ ctlx->outbuf.rmemreq.page = cpu_to_le16(page);
ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq);
- WLAN_LOG_DEBUG(4,
- "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
- ctlx->outbuf.rmemreq.type,
- ctlx->outbuf.rmemreq.frmlen,
- ctlx->outbuf.rmemreq.offset,
- ctlx->outbuf.rmemreq.page);
+ printk(KERN_DEBUG
+ "type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n",
+ ctlx->outbuf.rmemreq.type,
+ ctlx->outbuf.rmemreq.frmlen,
+ ctlx->outbuf.rmemreq.offset, ctlx->outbuf.rmemreq.page);
- WLAN_LOG_DEBUG(4,"pktsize=%zd\n",
- ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
+ pr_debug("pktsize=%zd\n",
+ ROUNDUP64(sizeof(ctlx->outbuf.rmemreq)));
ctlx->reapable = mode;
ctlx->cmdcb = cmdcb;
@@ -1926,23 +1669,21 @@ hfa384x_dormem(
result = hfa384x_usbctlx_submit(hw, ctlx);
if (result != 0) {
kfree(ctlx);
- } else if ( mode == DOWAIT ) {
- usbctlx_rmem_completor_t completor;
-
- result = hfa384x_usbctlx_complete_sync(
- hw, ctlx, init_rmem_completor(&completor,
- &ctlx->inbuf.rmemresp,
- data,
- len) );
+ } else if (mode == DOWAIT) {
+ usbctlx_rmem_completor_t completor;
+
+ result =
+ hfa384x_usbctlx_complete_sync(hw, ctlx,
+ init_rmem_completor
+ (&completor,
+ &ctlx->inbuf.rmemresp, data,
+ len));
}
done:
- DBFEXIT;
return result;
}
-
-
/*----------------------------------------------------------------
* hfa384x_dowmem
*
@@ -1977,45 +1718,39 @@ done:
* process (DOWAIT or DOASYNC)
----------------------------------------------------------------*/
static int
-hfa384x_dowmem(
- hfa384x_t *hw,
- CMD_MODE mode,
- u16 page,
- u16 offset,
- void *data,
- unsigned int len,
- ctlx_cmdcb_t cmdcb,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_dowmem(hfa384x_t *hw,
+ CMD_MODE mode,
+ u16 page,
+ u16 offset,
+ void *data,
+ unsigned int len,
+ ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data)
{
- int result;
- hfa384x_usbctlx_t *ctlx;
+ int result;
+ hfa384x_usbctlx_t *ctlx;
- DBFENTER;
- WLAN_LOG_DEBUG(5, "page=0x%04x offset=0x%04x len=%d\n",
- page,offset,len);
+ pr_debug("page=0x%04x offset=0x%04x len=%d\n",
+ page, offset, len);
ctlx = usbctlx_alloc();
- if ( ctlx == NULL ) {
+ if (ctlx == NULL) {
result = -ENOMEM;
goto done;
}
/* Initialize the command */
- ctlx->outbuf.wmemreq.type = host2hfa384x_16(HFA384x_USB_WMEMREQ);
- ctlx->outbuf.wmemreq.frmlen = host2hfa384x_16(
- sizeof(ctlx->outbuf.wmemreq.offset) +
- sizeof(ctlx->outbuf.wmemreq.page) +
- len);
- ctlx->outbuf.wmemreq.offset = host2hfa384x_16(offset);
- ctlx->outbuf.wmemreq.page = host2hfa384x_16(page);
+ ctlx->outbuf.wmemreq.type = cpu_to_le16(HFA384x_USB_WMEMREQ);
+ ctlx->outbuf.wmemreq.frmlen =
+ cpu_to_le16(sizeof(ctlx->outbuf.wmemreq.offset) +
+ sizeof(ctlx->outbuf.wmemreq.page) + len);
+ ctlx->outbuf.wmemreq.offset = cpu_to_le16(offset);
+ ctlx->outbuf.wmemreq.page = cpu_to_le16(page);
memcpy(ctlx->outbuf.wmemreq.data, data, len);
ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) +
- sizeof(ctlx->outbuf.wmemreq.frmlen) +
- sizeof(ctlx->outbuf.wmemreq.offset) +
- sizeof(ctlx->outbuf.wmemreq.page) +
- len;
+ sizeof(ctlx->outbuf.wmemreq.frmlen) +
+ sizeof(ctlx->outbuf.wmemreq.offset) +
+ sizeof(ctlx->outbuf.wmemreq.page) + len;
ctlx->reapable = mode;
ctlx->cmdcb = cmdcb;
@@ -2025,24 +1760,22 @@ hfa384x_dowmem(
result = hfa384x_usbctlx_submit(hw, ctlx);
if (result != 0) {
kfree(ctlx);
- } else if ( mode == DOWAIT ) {
- usbctlx_wmem_completor_t completor;
- hfa384x_cmdresult_t wmemresult;
-
- result = hfa384x_usbctlx_complete_sync(
- hw,
- ctlx,
- init_wmem_completor(&completor,
- &ctlx->inbuf.wmemresp,
- &wmemresult) );
+ } else if (mode == DOWAIT) {
+ usbctlx_wmem_completor_t completor;
+ hfa384x_cmdresult_t wmemresult;
+
+ result = hfa384x_usbctlx_complete_sync(hw,
+ ctlx,
+ init_wmem_completor
+ (&completor,
+ &ctlx->inbuf.wmemresp,
+ &wmemresult));
}
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_commtallies
*
@@ -2060,12 +1793,10 @@ done:
* Call context:
* process
----------------------------------------------------------------*/
-int hfa384x_drvr_commtallies( hfa384x_t *hw )
+int hfa384x_drvr_commtallies(hfa384x_t *hw)
{
hfa384x_metacmd_t cmd;
- DBFENTER;
-
cmd.cmd = HFA384x_CMDCODE_INQ;
cmd.parm0 = HFA384x_IT_COMMTALLIES;
cmd.parm1 = 0;
@@ -2073,11 +1804,9 @@ int hfa384x_drvr_commtallies( hfa384x_t *hw )
hfa384x_docmd_async(hw, &cmd, NULL, NULL, NULL);
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_disable
*
@@ -2102,24 +1831,20 @@ int hfa384x_drvr_commtallies( hfa384x_t *hw )
----------------------------------------------------------------*/
int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
- DBFENTER;
if ((!hw->isap && macport != 0) ||
(hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
- !(hw->port_enabled[macport]) ){
+ !(hw->port_enabled[macport])) {
result = -EINVAL;
} else {
result = hfa384x_cmd_disable(hw, macport);
- if ( result == 0 ) {
+ if (result == 0)
hw->port_enabled[macport] = 0;
- }
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_enable
*
@@ -2144,24 +1869,20 @@ int hfa384x_drvr_disable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
{
- int result = 0;
+ int result = 0;
- DBFENTER;
if ((!hw->isap && macport != 0) ||
(hw->isap && !(macport <= HFA384x_PORTID_MAX)) ||
- (hw->port_enabled[macport]) ){
+ (hw->port_enabled[macport])) {
result = -EINVAL;
} else {
result = hfa384x_cmd_enable(hw, macport);
- if ( result == 0 ) {
+ if (result == 0)
hw->port_enabled[macport] = 1;
- }
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_enable
*
@@ -2185,45 +1906,43 @@ int hfa384x_drvr_enable(hfa384x_t *hw, u16 macport)
----------------------------------------------------------------*/
int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
{
- int result = 0;
- int i;
+ int result = 0;
+ int i;
- DBFENTER;
/* Check that a port isn't active */
- for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
- if ( hw->port_enabled[i] ) {
- WLAN_LOG_DEBUG(1,"called when port enabled.\n");
+ for (i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if (hw->port_enabled[i]) {
+ pr_debug("called when port enabled.\n");
return -EINVAL;
}
}
/* Check that we're not already in a download state */
- if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_DISABLED)
return -EINVAL;
- }
/* Retrieve the buffer loc&size and timeout */
- if ( (result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
- &(hw->bufinfo), sizeof(hw->bufinfo))) ) {
+ if ((result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER,
+ &(hw->bufinfo),
+ sizeof(hw->bufinfo)))) {
return result;
}
- hw->bufinfo.page = hfa384x2host_16(hw->bufinfo.page);
- hw->bufinfo.offset = hfa384x2host_16(hw->bufinfo.offset);
- hw->bufinfo.len = hfa384x2host_16(hw->bufinfo.len);
- if ( (result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
- &(hw->dltimeout))) ) {
+ hw->bufinfo.page = le16_to_cpu(hw->bufinfo.page);
+ hw->bufinfo.offset = le16_to_cpu(hw->bufinfo.offset);
+ hw->bufinfo.len = le16_to_cpu(hw->bufinfo.len);
+ if ((result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME,
+ &(hw->dltimeout)))) {
return result;
}
- hw->dltimeout = hfa384x2host_16(hw->dltimeout);
+ hw->dltimeout = le16_to_cpu(hw->dltimeout);
- WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+ pr_debug("flashdl_enable\n");
hw->dlstate = HFA384x_DLSTATE_FLASHENABLED;
- DBFEXIT;
+
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_disable
*
@@ -2245,24 +1964,20 @@ int hfa384x_drvr_flashdl_enable(hfa384x_t *hw)
----------------------------------------------------------------*/
int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
{
- DBFENTER;
/* Check that we're already in the download state */
- if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
return -EINVAL;
- }
- WLAN_LOG_DEBUG(1,"flashdl_enable\n");
+ pr_debug("flashdl_enable\n");
/* There isn't much we can do at this point, so I don't */
/* bother w/ the return value */
- hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
hw->dlstate = HFA384x_DLSTATE_DISABLED;
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_flashdl_write
*
@@ -2292,48 +2007,42 @@ int hfa384x_drvr_flashdl_disable(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_flashdl_write(
- hfa384x_t *hw,
- u32 daddr,
- void *buf,
- u32 len)
+int hfa384x_drvr_flashdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
{
- int result = 0;
- u32 dlbufaddr;
- int nburns;
- u32 burnlen;
- u32 burndaddr;
- u16 burnlo;
- u16 burnhi;
- int nwrites;
- u8 *writebuf;
- u16 writepage;
- u16 writeoffset;
- u32 writelen;
- int i;
- int j;
-
- DBFENTER;
- WLAN_LOG_DEBUG(5,"daddr=0x%08x len=%d\n", daddr, len);
+ int result = 0;
+ u32 dlbufaddr;
+ int nburns;
+ u32 burnlen;
+ u32 burndaddr;
+ u16 burnlo;
+ u16 burnhi;
+ int nwrites;
+ u8 *writebuf;
+ u16 writepage;
+ u16 writeoffset;
+ u32 writelen;
+ int i;
+ int j;
+
+ pr_debug("daddr=0x%08x len=%d\n", daddr, len);
/* Check that we're in the flash download state */
- if ( hw->dlstate != HFA384x_DLSTATE_FLASHENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED)
return -EINVAL;
- }
- WLAN_LOG_INFO("Download %d bytes to flash @0x%06x\n", len, daddr);
+ printk(KERN_INFO "Download %d bytes to flash @0x%06x\n", len, daddr);
/* Convert to flat address for arithmetic */
/* NOTE: dlbuffer RID stores the address in AUX format */
- dlbufaddr = HFA384x_ADDR_AUX_MKFLAT(
- hw->bufinfo.page, hw->bufinfo.offset);
- WLAN_LOG_DEBUG(5,
- "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
- hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
+ dlbufaddr =
+ HFA384x_ADDR_AUX_MKFLAT(hw->bufinfo.page, hw->bufinfo.offset);
+ printk(KERN_DEBUG
+ "dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n",
+ hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr);
#if 0
-WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw->dltimeout);
+ printk(KERN_WARNING "dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr,
+ hw->bufinfo.len, hw->dltimeout);
#endif
/* Calculations to determine how many fills of the dlbuffer to do
* and how many USB wmemreq's to do for each fill. At this point
@@ -2351,74 +2060,60 @@ WLAN_LOG_WARNING("dlbuf@0x%06lx len=%d to=%d\n", dlbufaddr, hw->bufinfo.len, hw-
nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0;
/* For each burn */
- for ( i = 0; i < nburns; i++) {
+ for (i = 0; i < nburns; i++) {
/* Get the dest address and len */
burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ?
- hw->bufinfo.len :
- (len - (hw->bufinfo.len * i));
+ hw->bufinfo.len : (len - (hw->bufinfo.len * i));
burndaddr = daddr + (hw->bufinfo.len * i);
burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr);
burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr);
- WLAN_LOG_INFO("Writing %d bytes to flash @0x%06x\n",
- burnlen, burndaddr);
+ printk(KERN_INFO "Writing %d bytes to flash @0x%06x\n",
+ burnlen, burndaddr);
/* Set the download mode */
result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV,
- burnlo, burnhi, burnlen);
- if ( result ) {
- WLAN_LOG_ERROR("download(NV,lo=%x,hi=%x,len=%x) "
- "cmd failed, result=%d. Aborting d/l\n",
- burnlo, burnhi, burnlen, result);
+ burnlo, burnhi, burnlen);
+ if (result) {
+ printk(KERN_ERR "download(NV,lo=%x,hi=%x,len=%x) "
+ "cmd failed, result=%d. Aborting d/l\n",
+ burnlo, burnhi, burnlen, result);
goto exit_proc;
}
/* copy the data to the flash download buffer */
- for ( j=0; j < nwrites; j++) {
+ for (j = 0; j < nwrites; j++) {
writebuf = buf +
- (i*hw->bufinfo.len) +
- (j*HFA384x_USB_RWMEM_MAXLEN);
-
- writepage = HFA384x_ADDR_CMD_MKPAGE(
- dlbufaddr +
- (j*HFA384x_USB_RWMEM_MAXLEN));
- writeoffset = HFA384x_ADDR_CMD_MKOFF(
- dlbufaddr +
- (j*HFA384x_USB_RWMEM_MAXLEN));
-
- writelen = burnlen-(j*HFA384x_USB_RWMEM_MAXLEN);
- writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ?
- HFA384x_USB_RWMEM_MAXLEN :
- writelen;
-
- result = hfa384x_dowmem_wait( hw,
- writepage,
- writeoffset,
- writebuf,
- writelen );
-#if 0
-
-Comment out for debugging, assume the write was successful.
- if (result) {
- WLAN_LOG_ERROR(
- "Write to dl buffer failed, "
- "result=0x%04x. Aborting.\n",
- result);
- goto exit_proc;
- }
-#endif
-
+ (i * hw->bufinfo.len) +
+ (j * HFA384x_USB_RWMEM_MAXLEN);
+
+ writepage = HFA384x_ADDR_CMD_MKPAGE(dlbufaddr +
+ (j *
+ HFA384x_USB_RWMEM_MAXLEN));
+ writeoffset =
+ HFA384x_ADDR_CMD_MKOFF(dlbufaddr +
+ (j *
+ HFA384x_USB_RWMEM_MAXLEN));
+
+ writelen = burnlen - (j * HFA384x_USB_RWMEM_MAXLEN);
+ writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ?
+ HFA384x_USB_RWMEM_MAXLEN : writelen;
+
+ result = hfa384x_dowmem_wait(hw,
+ writepage,
+ writeoffset,
+ writebuf, writelen);
}
/* set the download 'write flash' mode */
result = hfa384x_cmd_download(hw,
- HFA384x_PROGMODE_NVWRITE,
- 0,0,0);
- if ( result ) {
- WLAN_LOG_ERROR(
- "download(NVWRITE,lo=%x,hi=%x,len=%x) "
- "cmd failed, result=%d. Aborting d/l\n",
- burnlo, burnhi, burnlen, result);
+ HFA384x_PROGMODE_NVWRITE,
+ 0, 0, 0);
+ if (result) {
+ printk(KERN_ERR
+ "download(NVWRITE,lo=%x,hi=%x,len=%x) "
+ "cmd failed, result=%d. Aborting d/l\n",
+ burnlo, burnhi, burnlen, result);
goto exit_proc;
}
@@ -2431,11 +2126,9 @@ exit_proc:
/* actually disable programming mode. Remember, that will cause the */
/* the firmware to effectively reset itself. */
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_getconfig
*
@@ -2463,12 +2156,10 @@ exit_proc:
----------------------------------------------------------------*/
int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
{
- int result;
- DBFENTER;
+ int result;
result = hfa384x_dorrid_wait(hw, rid, buf, len);
- DBFEXIT;
return result;
}
@@ -2500,14 +2191,11 @@ int hfa384x_drvr_getconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
* Any
----------------------------------------------------------------*/
int
-hfa384x_drvr_getconfig_async(
- hfa384x_t *hw,
- u16 rid,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_drvr_getconfig_async(hfa384x_t *hw,
+ u16 rid, ctlx_usercb_t usercb, void *usercb_data)
{
- return hfa384x_dorrid_async(hw, rid, NULL, 0,
- hfa384x_cb_rrid, usercb, usercb_data);
+ return hfa384x_dorrid_async(hw, rid, NULL, 0,
+ hfa384x_cb_rrid, usercb, usercb_data);
}
/*----------------------------------------------------------------
@@ -2534,71 +2222,16 @@ hfa384x_drvr_getconfig_async(
* process
----------------------------------------------------------------*/
int
-hfa384x_drvr_setconfig_async(
- hfa384x_t *hw,
- u16 rid,
- void *buf,
- u16 len,
- ctlx_usercb_t usercb,
- void *usercb_data)
+hfa384x_drvr_setconfig_async(hfa384x_t *hw,
+ u16 rid,
+ void *buf,
+ u16 len, ctlx_usercb_t usercb, void *usercb_data)
{
return hfa384x_dowrid_async(hw, rid, buf, len,
hfa384x_cb_status, usercb, usercb_data);
}
/*----------------------------------------------------------------
-* hfa384x_drvr_handover
-*
-* Sends a handover notification to the MAC.
-*
-* Arguments:
-* hw device structure
-* addr address of station that's left
-*
-* Returns:
-* zero success.
-* -ERESTARTSYS received signal while waiting for semaphore.
-* -EIO failed to write to bap, or failed in cmd.
-*
-* Side effects:
-*
-* Call context:
-* process
-----------------------------------------------------------------*/
-int hfa384x_drvr_handover( hfa384x_t *hw, u8 *addr)
-{
- DBFENTER;
- WLAN_LOG_ERROR("Not currently supported in USB!\n");
- DBFEXIT;
- return -EIO;
-}
-
-/*----------------------------------------------------------------
-* hfa384x_drvr_low_level
-*
-* Write test commands to the card. Some test commands don't make
-* sense without prior set-up. For example, continous TX isn't very
-* useful until you set the channel. That functionality should be
-*
-* Side effects:
-*
-* Call context:
-* process thread
-* -----------------------------------------------------------------*/
-int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
-{
- int result;
- DBFENTER;
-
- /* Do i need a host2hfa... conversion ? */
-
- result = hfa384x_docmd_wait(hw, cmd);
-
- DBFEXIT;
- return result;
-}
-
-/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_disable
*
* Ends the ram download state.
@@ -2616,27 +2249,22 @@ int hfa384x_drvr_low_level(hfa384x_t *hw, hfa384x_metacmd_t *cmd)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
+int hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
{
- DBFENTER;
/* Check that we're already in the download state */
- if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
return -EINVAL;
- }
- WLAN_LOG_DEBUG(3,"ramdl_disable()\n");
+ pr_debug("ramdl_disable()\n");
/* There isn't much we can do at this point, so I don't */
/* bother w/ the return value */
- hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0 , 0);
+ hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0);
hw->dlstate = HFA384x_DLSTATE_DISABLED;
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_enable
*
@@ -2661,55 +2289,49 @@ hfa384x_drvr_ramdl_disable(hfa384x_t *hw)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
+int hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
{
- int result = 0;
- u16 lowaddr;
- u16 hiaddr;
- int i;
- DBFENTER;
+ int result = 0;
+ u16 lowaddr;
+ u16 hiaddr;
+ int i;
+
/* Check that a port isn't active */
- for ( i = 0; i < HFA384x_PORTID_MAX; i++) {
- if ( hw->port_enabled[i] ) {
- WLAN_LOG_ERROR(
- "Can't download with a macport enabled.\n");
+ for (i = 0; i < HFA384x_PORTID_MAX; i++) {
+ if (hw->port_enabled[i]) {
+ printk(KERN_ERR
+ "Can't download with a macport enabled.\n");
return -EINVAL;
}
}
/* Check that we're not already in a download state */
- if ( hw->dlstate != HFA384x_DLSTATE_DISABLED ) {
- WLAN_LOG_ERROR(
- "Download state not disabled.\n");
+ if (hw->dlstate != HFA384x_DLSTATE_DISABLED) {
+ printk(KERN_ERR "Download state not disabled.\n");
return -EINVAL;
}
- WLAN_LOG_DEBUG(3,"ramdl_enable, exeaddr=0x%08x\n", exeaddr);
+ pr_debug("ramdl_enable, exeaddr=0x%08x\n", exeaddr);
/* Call the download(1,addr) function */
lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr);
- hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
+ hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr);
result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM,
- lowaddr, hiaddr, 0);
+ lowaddr, hiaddr, 0);
- if ( result == 0) {
+ if (result == 0) {
/* Set the download state */
hw->dlstate = HFA384x_DLSTATE_RAMENABLED;
} else {
- WLAN_LOG_DEBUG(1,
- "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
- lowaddr,
- hiaddr,
- result);
+ printk(KERN_DEBUG
+ "cmd_download(0x%04x, 0x%04x) failed, result=%d.\n",
+ lowaddr, hiaddr, result);
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_ramdl_write
*
@@ -2736,57 +2358,54 @@ hfa384x_drvr_ramdl_enable(hfa384x_t *hw, u32 exeaddr)
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len)
+int hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void *buf, u32 len)
{
- int result = 0;
- int nwrites;
- u8 *data = buf;
- int i;
- u32 curraddr;
- u16 currpage;
- u16 curroffset;
- u16 currlen;
- DBFENTER;
+ int result = 0;
+ int nwrites;
+ u8 *data = buf;
+ int i;
+ u32 curraddr;
+ u16 currpage;
+ u16 curroffset;
+ u16 currlen;
+
/* Check that we're in the ram download state */
- if ( hw->dlstate != HFA384x_DLSTATE_RAMENABLED ) {
+ if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED)
return -EINVAL;
- }
- WLAN_LOG_INFO("Writing %d bytes to ram @0x%06x\n", len, daddr);
+ printk(KERN_INFO "Writing %d bytes to ram @0x%06x\n", len, daddr);
/* How many dowmem calls? */
nwrites = len / HFA384x_USB_RWMEM_MAXLEN;
nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0;
/* Do blocking wmem's */
- for(i=0; i < nwrites; i++) {
+ for (i = 0; i < nwrites; i++) {
/* make address args */
curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN);
currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr);
curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr);
currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN);
- if ( currlen > HFA384x_USB_RWMEM_MAXLEN) {
+ if (currlen > HFA384x_USB_RWMEM_MAXLEN)
currlen = HFA384x_USB_RWMEM_MAXLEN;
- }
- /* Do blocking ctlx */
- result = hfa384x_dowmem_wait( hw,
- currpage,
- curroffset,
- data + (i*HFA384x_USB_RWMEM_MAXLEN),
- currlen );
+ /* Do blocking ctlx */
+ result = hfa384x_dowmem_wait(hw,
+ currpage,
+ curroffset,
+ data +
+ (i * HFA384x_USB_RWMEM_MAXLEN),
+ currlen);
- if (result) break;
+ if (result)
+ break;
/* TODO: We really should have a readback. */
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_readpda
*
@@ -2820,101 +2439,89 @@ hfa384x_drvr_ramdl_write(hfa384x_t *hw, u32 daddr, void* buf, u32 len)
----------------------------------------------------------------*/
int hfa384x_drvr_readpda(hfa384x_t *hw, void *buf, unsigned int len)
{
- int result = 0;
- u16 *pda = buf;
- int pdaok = 0;
- int morepdrs = 1;
- int currpdr = 0; /* word offset of the current pdr */
- size_t i;
- u16 pdrlen; /* pdr length in bytes, host order */
- u16 pdrcode; /* pdr code, host order */
- u16 currpage;
- u16 curroffset;
+ int result = 0;
+ u16 *pda = buf;
+ int pdaok = 0;
+ int morepdrs = 1;
+ int currpdr = 0; /* word offset of the current pdr */
+ size_t i;
+ u16 pdrlen; /* pdr length in bytes, host order */
+ u16 pdrcode; /* pdr code, host order */
+ u16 currpage;
+ u16 curroffset;
struct pdaloc {
- u32 cardaddr;
- u16 auxctl;
- } pdaloc[] =
- {
- { HFA3842_PDA_BASE, 0},
- { HFA3841_PDA_BASE, 0},
- { HFA3841_PDA_BOGUS_BASE, 0}
+ u32 cardaddr;
+ u16 auxctl;
+ } pdaloc[] = {
+ {
+ HFA3842_PDA_BASE, 0}, {
+ HFA3841_PDA_BASE, 0}, {
+ HFA3841_PDA_BOGUS_BASE, 0}
};
- DBFENTER;
-
/* Read the pda from each known address. */
- for ( i = 0; i < ARRAY_SIZE(pdaloc); i++) {
+ for (i = 0; i < ARRAY_SIZE(pdaloc); i++) {
/* Make address */
currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr);
curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr);
- result = hfa384x_dormem_wait(hw,
- currpage,
- curroffset,
- buf,
- len); /* units of bytes */
+ result = hfa384x_dormem_wait(hw, currpage, curroffset, buf, len); /* units of bytes */
if (result) {
- WLAN_LOG_WARNING(
- "Read from index %zd failed, continuing\n",
- i );
+ printk(KERN_WARNING
+ "Read from index %zd failed, continuing\n", i);
continue;
}
/* Test for garbage */
pdaok = 1; /* initially assume good */
morepdrs = 1;
- while ( pdaok && morepdrs ) {
- pdrlen = hfa384x2host_16(pda[currpdr]) * 2;
- pdrcode = hfa384x2host_16(pda[currpdr+1]);
+ while (pdaok && morepdrs) {
+ pdrlen = le16_to_cpu(pda[currpdr]) * 2;
+ pdrcode = le16_to_cpu(pda[currpdr + 1]);
/* Test the record length */
- if ( pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
- WLAN_LOG_ERROR("pdrlen invalid=%d\n",
- pdrlen);
+ if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) {
+ printk(KERN_ERR "pdrlen invalid=%d\n", pdrlen);
pdaok = 0;
break;
}
/* Test the code */
- if ( !hfa384x_isgood_pdrcode(pdrcode) ) {
- WLAN_LOG_ERROR("pdrcode invalid=%d\n",
- pdrcode);
+ if (!hfa384x_isgood_pdrcode(pdrcode)) {
+ printk(KERN_ERR "pdrcode invalid=%d\n",
+ pdrcode);
pdaok = 0;
break;
}
/* Test for completion */
- if ( pdrcode == HFA384x_PDR_END_OF_PDA) {
+ if (pdrcode == HFA384x_PDR_END_OF_PDA)
morepdrs = 0;
- }
/* Move to the next pdr (if necessary) */
- if ( morepdrs ) {
+ if (morepdrs) {
/* note the access to pda[], need words here */
- currpdr += hfa384x2host_16(pda[currpdr]) + 1;
+ currpdr += le16_to_cpu(pda[currpdr]) + 1;
}
}
- if ( pdaok ) {
- WLAN_LOG_INFO(
- "PDA Read from 0x%08x in %s space.\n",
- pdaloc[i].cardaddr,
- pdaloc[i].auxctl == 0 ? "EXTDS" :
- pdaloc[i].auxctl == 1 ? "NV" :
- pdaloc[i].auxctl == 2 ? "PHY" :
- pdaloc[i].auxctl == 3 ? "ICSRAM" :
- "<bogus auxctl>");
+ if (pdaok) {
+ printk(KERN_INFO
+ "PDA Read from 0x%08x in %s space.\n",
+ pdaloc[i].cardaddr,
+ pdaloc[i].auxctl == 0 ? "EXTDS" :
+ pdaloc[i].auxctl == 1 ? "NV" :
+ pdaloc[i].auxctl == 2 ? "PHY" :
+ pdaloc[i].auxctl == 3 ? "ICSRAM" :
+ "<bogus auxctl>");
break;
}
}
result = pdaok ? 0 : -ENODATA;
- if ( result ) {
- WLAN_LOG_DEBUG(3,"Failure: pda is not okay\n");
- }
+ if (result)
+ pr_debug("Failure: pda is not okay\n");
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_setconfig
*
@@ -2963,9 +2570,8 @@ int hfa384x_drvr_setconfig(hfa384x_t *hw, u16 rid, void *buf, u16 len)
int hfa384x_drvr_start(hfa384x_t *hw)
{
- int result, result1, result2;
- u16 status;
- DBFENTER;
+ int result, result1, result2;
+ u16 status;
might_sleep();
@@ -2974,27 +2580,23 @@ int hfa384x_drvr_start(hfa384x_t *hw)
* badly if a clear_halt is called when the endpoint is already
* ok
*/
- result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
+ result =
+ usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, &status);
if (result < 0) {
- WLAN_LOG_ERROR(
- "Cannot get bulk in endpoint status.\n");
+ printk(KERN_ERR "Cannot get bulk in endpoint status.\n");
goto done;
}
- if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in)) {
- WLAN_LOG_ERROR(
- "Failed to reset bulk in endpoint.\n");
- }
+ if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in))
+ printk(KERN_ERR "Failed to reset bulk in endpoint.\n");
- result = usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
+ result =
+ usb_get_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, &status);
if (result < 0) {
- WLAN_LOG_ERROR(
- "Cannot get bulk out endpoint status.\n");
+ printk(KERN_ERR "Cannot get bulk out endpoint status.\n");
goto done;
}
- if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out)) {
- WLAN_LOG_ERROR(
- "Failed to reset bulk out endpoint.\n");
- }
+ if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out))
+ printk(KERN_ERR "Failed to reset bulk out endpoint.\n");
/* Synchronous unlink, in case we're trying to restart the driver */
usb_kill_urb(&hw->rx_urb);
@@ -3002,9 +2604,8 @@ int hfa384x_drvr_start(hfa384x_t *hw)
/* Post the IN urb */
result = submit_rx_urb(hw, GFP_KERNEL);
if (result != 0) {
- WLAN_LOG_ERROR(
- "Fatal, failed to submit RX URB, result=%d\n",
- result);
+ printk(KERN_ERR
+ "Fatal, failed to submit RX URB, result=%d\n", result);
goto done;
}
@@ -3023,32 +2624,33 @@ int hfa384x_drvr_start(hfa384x_t *hw)
result = result2 = hfa384x_cmd_initialize(hw);
if (result1 != 0) {
if (result2 != 0) {
- WLAN_LOG_ERROR(
- "cmd_initialize() failed on two attempts, results %d and %d\n",
- result1, result2);
+ printk(KERN_ERR
+ "cmd_initialize() failed on two attempts, results %d and %d\n",
+ result1, result2);
usb_kill_urb(&hw->rx_urb);
goto done;
} else {
- WLAN_LOG_DEBUG(0, "First cmd_initialize() failed (result %d),\n",
- result1);
- WLAN_LOG_DEBUG(0, "but second attempt succeeded. All should be ok\n");
+ printk(KERN_DEBUG
+ "First cmd_initialize() failed (result %d),\n",
+ result1);
+ printk(KERN_DEBUG
+ "but second attempt succeeded. All should be ok\n");
}
} else if (result2 != 0) {
- WLAN_LOG_WARNING(
- "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
- result2);
- WLAN_LOG_WARNING("Most likely the card will be functional\n");
- goto done;
+ printk(KERN_WARNING
+ "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n",
+ result2);
+ printk(KERN_WARNING
+ "Most likely the card will be functional\n");
+ goto done;
}
hw->state = HFA384x_STATE_RUNNING;
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* hfa384x_drvr_stop
*
@@ -3068,19 +2670,17 @@ done:
* Call context:
* process
----------------------------------------------------------------*/
-int
-hfa384x_drvr_stop(hfa384x_t *hw)
+int hfa384x_drvr_stop(hfa384x_t *hw)
{
- int result = 0;
- int i;
- DBFENTER;
+ int result = 0;
+ int i;
might_sleep();
/* There's no need for spinlocks here. The USB "disconnect"
* function sets this "removed" flag and then calls us.
*/
- if ( !hw->wlandev->hwremoved ) {
+ if (!hw->wlandev->hwremoved) {
/* Call initialize to leave the MAC in its 'reset' state */
hfa384x_cmd_initialize(hw);
@@ -3094,11 +2694,9 @@ hfa384x_drvr_stop(hfa384x_t *hw)
del_timer_sync(&hw->commsqual_timer);
/* Clear all the port status */
- for ( i = 0; i < HFA384x_NUMPORTS_MAX; i++) {
+ for (i = 0; i < HFA384x_NUMPORTS_MAX; i++)
hw->port_enabled[i] = 0;
- }
- DBFEXIT;
return result;
}
@@ -3123,18 +2721,17 @@ hfa384x_drvr_stop(hfa384x_t *hw)
* Call context:
* interrupt
----------------------------------------------------------------*/
-int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
-
+int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb,
+ p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep)
{
- int usbpktlen = sizeof(hfa384x_tx_frame_t);
- int result;
- int ret;
- char *ptr;
-
- DBFENTER;
+ int usbpktlen = sizeof(hfa384x_tx_frame_t);
+ int result;
+ int ret;
+ char *ptr;
if (hw->tx_urb.status == -EINPROGRESS) {
- WLAN_LOG_WARNING("TX URB already in use\n");
+ printk(KERN_WARNING "TX URB already in use\n");
result = 3;
goto exit;
}
@@ -3144,7 +2741,7 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p8021
memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc));
/* Setup the usb type field */
- hw->txbuff.type = host2hfa384x_16(HFA384x_USB_TXFRM);
+ hw->txbuff.type = cpu_to_le16(HFA384x_USB_TXFRM);
/* Set up the sw_support field to identify this frame */
hw->txbuff.txfrm.desc.sw_support = 0x0123;
@@ -3152,33 +2749,33 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p8021
/* Tx complete and Tx exception disable per dleach. Might be causing
* buf depletion
*/
-//#define DOEXC SLP -- doboth breaks horribly under load, doexc less so.
+/* #define DOEXC SLP -- doboth breaks horribly under load, doexc less so. */
#if defined(DOBOTH)
hw->txbuff.txfrm.desc.tx_control =
- HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
- HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1);
#elif defined(DOEXC)
hw->txbuff.txfrm.desc.tx_control =
- HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
- HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0);
#else
hw->txbuff.txfrm.desc.tx_control =
- HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
- HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
+ HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) |
+ HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0);
#endif
hw->txbuff.txfrm.desc.tx_control =
- host2hfa384x_16(hw->txbuff.txfrm.desc.tx_control);
+ cpu_to_le16(hw->txbuff.txfrm.desc.tx_control);
/* copy the header over to the txdesc */
- memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr, sizeof(p80211_hdr_t));
+ memcpy(&(hw->txbuff.txfrm.desc.frame_control), p80211_hdr,
+ sizeof(p80211_hdr_t));
/* if we're using host WEP, increase size by IV+ICV */
if (p80211_wep->data) {
- hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len+8);
- // hw->txbuff.txfrm.desc.tx_control |= HFA384x_TX_NOENCRYPT_SET(1);
- usbpktlen+=8;
+ hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len + 8);
+ usbpktlen += 8;
} else {
- hw->txbuff.txfrm.desc.data_len = host2hfa384x_16(skb->len);
+ hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len);
}
usbpktlen += skb->len;
@@ -3187,59 +2784,51 @@ int hfa384x_drvr_txframe(hfa384x_t *hw, struct sk_buff *skb, p80211_hdr_t *p8021
ptr = hw->txbuff.txfrm.data;
if (p80211_wep->data) {
memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv));
- ptr+= sizeof(p80211_wep->iv);
+ ptr += sizeof(p80211_wep->iv);
memcpy(ptr, p80211_wep->data, skb->len);
} else {
memcpy(ptr, skb->data, skb->len);
}
/* copy over the packet data */
- ptr+= skb->len;
+ ptr += skb->len;
/* copy over the WEP ICV if we are using host WEP */
- if (p80211_wep->data) {
+ if (p80211_wep->data)
memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv));
- }
/* Send the USB packet */
- usb_fill_bulk_urb( &(hw->tx_urb), hw->usb,
- hw->endp_out,
- &(hw->txbuff), ROUNDUP64(usbpktlen),
- hfa384x_usbout_callback, hw->wlandev );
+ usb_fill_bulk_urb(&(hw->tx_urb), hw->usb,
+ hw->endp_out,
+ &(hw->txbuff), ROUNDUP64(usbpktlen),
+ hfa384x_usbout_callback, hw->wlandev);
hw->tx_urb.transfer_flags |= USB_QUEUE_BULK;
result = 1;
ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC);
- if ( ret != 0 ) {
- WLAN_LOG_ERROR(
- "submit_tx_urb() failed, error=%d\n", ret);
+ if (ret != 0) {
+ printk(KERN_ERR "submit_tx_urb() failed, error=%d\n", ret);
result = 3;
}
- exit:
- DBFEXIT;
+exit:
return result;
}
void hfa384x_tx_timeout(wlandevice_t *wlandev)
{
- hfa384x_t *hw = wlandev->priv;
+ hfa384x_t *hw = wlandev->priv;
unsigned long flags;
- DBFENTER;
-
spin_lock_irqsave(&hw->ctlxq.lock, flags);
- if ( !hw->wlandev->hwremoved &&
- /* Note the bitwise OR, not the logical OR. */
- ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) |
- !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) ) )
- {
+ if (!hw->wlandev->hwremoved &&
+ /* Note the bitwise OR, not the logical OR. */
+ (!test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) |
+ !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))) {
schedule_work(&hw->usb_work);
}
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
- DBFEXIT;
}
/*----------------------------------------------------------------
@@ -3257,12 +2846,10 @@ void hfa384x_tx_timeout(wlandevice_t *wlandev)
----------------------------------------------------------------*/
static void hfa384x_usbctlx_reaper_task(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
+ hfa384x_t *hw = (hfa384x_t *) data;
struct list_head *entry;
struct list_head *temp;
- unsigned long flags;
-
- DBFENTER;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3270,7 +2857,7 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
* has unplugged the adapter.
*/
list_for_each_safe(entry, temp, &hw->ctlxq.reapable) {
- hfa384x_usbctlx_t *ctlx;
+ hfa384x_usbctlx_t *ctlx;
ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
list_del(&ctlx->list);
@@ -3279,7 +2866,6 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
- DBFEXIT;
}
/*----------------------------------------------------------------
@@ -3298,15 +2884,13 @@ static void hfa384x_usbctlx_reaper_task(unsigned long data)
----------------------------------------------------------------*/
static void hfa384x_usbctlx_completion_task(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
+ hfa384x_t *hw = (hfa384x_t *) data;
struct list_head *entry;
struct list_head *temp;
unsigned long flags;
int reap = 0;
- DBFENTER;
-
spin_lock_irqsave(&hw->ctlxq.lock, flags);
/* This list is guaranteed to be empty if someone
@@ -3320,7 +2904,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
/* Call the completion function that this
* command was assigned, assuming it has one.
*/
- if ( ctlx->cmdcb != NULL ) {
+ if (ctlx->cmdcb != NULL) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
ctlx->cmdcb(hw, ctlx);
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3333,8 +2917,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
/* Did someone yank the adapter out
* while our list was (briefly) unlocked?
*/
- if ( hw->wlandev->hwremoved )
- {
+ if (hw->wlandev->hwremoved) {
reap = 0;
break;
}
@@ -3345,7 +2928,7 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
* threads waiting for them to die. Hence they must
* be delivered to The Reaper!
*/
- if ( ctlx->reapable ) {
+ if (ctlx->reapable) {
/* Move the CTLX off the "completing" list (hopefully)
* on to the "reapable" list where the reaper task
* can find it. And "reapable" means that this CTLX
@@ -3361,8 +2944,6 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
if (reap)
tasklet_schedule(&hw->reaper_bh);
-
- DBFEXIT;
}
/*----------------------------------------------------------------
@@ -3382,12 +2963,11 @@ static void hfa384x_usbctlx_completion_task(unsigned long data)
* Call context:
* Either process or interrupt, but presumably interrupt
----------------------------------------------------------------*/
-static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
+static int unlocked_usbctlx_cancel_async(hfa384x_t *hw,
+ hfa384x_usbctlx_t *ctlx)
{
int ret;
- DBFENTER;
-
/*
* Try to delete the URB containing our request packet.
* If we succeed, then its completion handler will be
@@ -3408,8 +2988,6 @@ static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
ret = 0;
}
- DBFEXIT;
-
return ret;
}
@@ -3437,8 +3015,6 @@ static int unlocked_usbctlx_cancel_async(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
----------------------------------------------------------------*/
static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
{
- DBFENTER;
-
/* Timers have been stopped, and ctlx should be in
* a terminal state. Retire it from the "active"
* queue.
@@ -3453,13 +3029,11 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
break;
default:
- WLAN_LOG_ERROR("CTLX[%d] not in a terminating state(%s)\n",
- hfa384x2host_16(ctlx->outbuf.type),
- ctlxstr(ctlx->state));
+ printk(KERN_ERR "CTLX[%d] not in a terminating state(%s)\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
break;
- } /* switch */
-
- DBFEXIT;
+ } /* switch */
}
/*----------------------------------------------------------------
@@ -3478,11 +3052,9 @@ static void unlocked_usbctlx_complete(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
* Call context:
* any
----------------------------------------------------------------*/
-static void
-hfa384x_usbctlxq_run(hfa384x_t *hw)
+static void hfa384x_usbctlxq_run(hfa384x_t *hw)
{
- unsigned long flags;
- DBFENTER;
+ unsigned long flags;
/* acquire lock */
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3494,28 +3066,26 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
* Don't touch any of these CTLXs if the hardware
* has been removed or the USB subsystem is stalled.
*/
- if ( !list_empty(&hw->ctlxq.active) ||
- test_bit(WORK_TX_HALT, &hw->usb_flags) ||
- hw->wlandev->hwremoved )
+ if (!list_empty(&hw->ctlxq.active) ||
+ test_bit(WORK_TX_HALT, &hw->usb_flags) || hw->wlandev->hwremoved)
goto unlock;
- while ( !list_empty(&hw->ctlxq.pending) ) {
- hfa384x_usbctlx_t *head;
- int result;
+ while (!list_empty(&hw->ctlxq.pending)) {
+ hfa384x_usbctlx_t *head;
+ int result;
/* This is the first pending command */
head = list_entry(hw->ctlxq.pending.next,
- hfa384x_usbctlx_t,
- list);
+ hfa384x_usbctlx_t, list);
/* We need to split this off to avoid a race condition */
list_move_tail(&head->list, &hw->ctlxq.active);
/* Fill the out packet */
- usb_fill_bulk_urb( &(hw->ctlx_urb), hw->usb,
- hw->endp_out,
- &(head->outbuf), ROUNDUP64(head->outbufsize),
- hfa384x_ctlxout_callback, hw);
+ usb_fill_bulk_urb(&(hw->ctlx_urb), hw->usb,
+ hw->endp_out,
+ &(head->outbuf), ROUNDUP64(head->outbufsize),
+ hfa384x_ctlxout_callback, hw);
hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK;
/* Now submit the URB and update the CTLX's state
@@ -3531,7 +3101,7 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
/* Start the IN wait timer */
hw->resp_timer_done = 0;
- hw->resptimer.expires = jiffies + 2*HZ;
+ hw->resptimer.expires = jiffies + 2 * HZ;
add_timer(&hw->resptimer);
break;
@@ -3542,8 +3112,9 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
* this CTLX back in the "pending" queue
* and schedule a reset ...
*/
- WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
- hw->wlandev->netdev->name);
+ printk(KERN_WARNING
+ "%s tx pipe stalled: requesting reset\n",
+ hw->wlandev->netdev->name);
list_move(&head->list, &hw->ctlxq.pending);
set_bit(WORK_TX_HALT, &hw->usb_flags);
schedule_work(&hw->usb_work);
@@ -3551,23 +3122,20 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
}
if (result == -ESHUTDOWN) {
- WLAN_LOG_WARNING("%s urb shutdown!\n",
- hw->wlandev->netdev->name);
+ printk(KERN_WARNING "%s urb shutdown!\n",
+ hw->wlandev->netdev->name);
break;
}
- WLAN_LOG_ERROR("Failed to submit CTLX[%d]: error=%d\n",
- hfa384x2host_16(head->outbuf.type), result);
+ printk(KERN_ERR "Failed to submit CTLX[%d]: error=%d\n",
+ le16_to_cpu(head->outbuf.type), result);
unlocked_usbctlx_complete(hw, head);
- } /* while */
+ } /* while */
- unlock:
+unlock:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_callback
*
@@ -3586,13 +3154,13 @@ hfa384x_usbctlxq_run(hfa384x_t *hw)
----------------------------------------------------------------*/
static void hfa384x_usbin_callback(struct urb *urb)
{
- wlandevice_t *wlandev = urb->context;
- hfa384x_t *hw;
- hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) urb->transfer_buffer;
- struct sk_buff *skb = NULL;
- int result;
- int urb_status;
- u16 type;
+ wlandevice_t *wlandev = urb->context;
+ hfa384x_t *hw;
+ hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) urb->transfer_buffer;
+ struct sk_buff *skb = NULL;
+ int result;
+ int urb_status;
+ u16 type;
enum USBIN_ACTION {
HANDLE,
@@ -3600,11 +3168,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
ABORT
} action;
- DBFENTER;
-
- if ( !wlandev ||
- !wlandev->netdev ||
- wlandev->hwremoved )
+ if (!wlandev || !wlandev->netdev || wlandev->hwremoved)
goto exit;
hw = wlandev->priv;
@@ -3612,9 +3176,8 @@ static void hfa384x_usbin_callback(struct urb *urb)
goto exit;
skb = hw->rx_urb_skb;
- if (!skb || (skb->data != urb->transfer_buffer)) {
- BUG();
- }
+ BUG_ON(!skb || (skb->data != urb->transfer_buffer));
+
hw->rx_urb_skb = NULL;
/* Check for error conditions within the URB */
@@ -3623,7 +3186,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
action = HANDLE;
/* Check for short packet */
- if ( urb->actual_length == 0 ) {
+ if (urb->actual_length == 0) {
++(wlandev->linux_stats.rx_errors);
++(wlandev->linux_stats.rx_length_errors);
action = RESUBMIT;
@@ -3631,9 +3194,9 @@ static void hfa384x_usbin_callback(struct urb *urb)
break;
case -EPIPE:
- WLAN_LOG_WARNING("%s rx pipe stalled: requesting reset\n",
- wlandev->netdev->name);
- if ( !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags) )
+ printk(KERN_WARNING "%s rx pipe stalled: requesting reset\n",
+ wlandev->netdev->name);
+ if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags))
schedule_work(&hw->usb_work);
++(wlandev->linux_stats.rx_errors);
action = ABORT;
@@ -3642,8 +3205,8 @@ static void hfa384x_usbin_callback(struct urb *urb)
case -EILSEQ:
case -ETIMEDOUT:
case -EPROTO:
- if ( !test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
- !timer_pending(&hw->throttle) ) {
+ if (!test_and_set_bit(THROTTLE_RX, &hw->usb_flags) &&
+ !timer_pending(&hw->throttle)) {
mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES);
}
++(wlandev->linux_stats.rx_errors);
@@ -3657,19 +3220,20 @@ static void hfa384x_usbin_callback(struct urb *urb)
case -ENODEV:
case -ESHUTDOWN:
- WLAN_LOG_DEBUG(3,"status=%d, device removed.\n", urb->status);
+ pr_debug("status=%d, device removed.\n", urb->status);
action = ABORT;
break;
case -ENOENT:
case -ECONNRESET:
- WLAN_LOG_DEBUG(3,"status=%d, urb explicitly unlinked.\n", urb->status);
+ pr_debug("status=%d, urb explicitly unlinked.\n",
+ urb->status);
action = ABORT;
break;
default:
- WLAN_LOG_DEBUG(3,"urb status=%d, transfer flags=0x%x\n",
- urb->status, urb->transfer_flags);
+ pr_debug("urb status=%d, transfer flags=0x%x\n",
+ urb->status, urb->transfer_flags);
++(wlandev->linux_stats.rx_errors);
action = RESUBMIT;
break;
@@ -3682,9 +3246,9 @@ static void hfa384x_usbin_callback(struct urb *urb)
result = submit_rx_urb(hw, GFP_ATOMIC);
if (result != 0) {
- WLAN_LOG_ERROR(
- "Fatal, failed to resubmit rx_urb. error=%d\n",
- result);
+ printk(KERN_ERR
+ "Fatal, failed to resubmit rx_urb. error=%d\n",
+ result);
}
}
@@ -3692,7 +3256,7 @@ static void hfa384x_usbin_callback(struct urb *urb)
/* Note: the check of the sw_support field, the type field doesn't
* have bit 12 set like the docs suggest.
*/
- type = hfa384x2host_16(usbin->type);
+ type = le16_to_cpu(usbin->type);
if (HFA384x_USB_ISRXFRM(type)) {
if (action == HANDLE) {
if (usbin->txfrm.desc.sw_support == 0x0123) {
@@ -3728,30 +3292,28 @@ static void hfa384x_usbin_callback(struct urb *urb)
break;
case HFA384x_USB_BUFAVAIL:
- WLAN_LOG_DEBUG(3,"Received BUFAVAIL packet, frmlen=%d\n",
- usbin->bufavail.frmlen);
+ pr_debug("Received BUFAVAIL packet, frmlen=%d\n",
+ usbin->bufavail.frmlen);
break;
case HFA384x_USB_ERROR:
- WLAN_LOG_DEBUG(3,"Received USB_ERROR packet, errortype=%d\n",
- usbin->usberror.errortype);
+ pr_debug("Received USB_ERROR packet, errortype=%d\n",
+ usbin->usberror.errortype);
break;
default:
- WLAN_LOG_DEBUG(3,"Unrecognized USBIN packet, type=%x, status=%d\n",
- usbin->type, urb_status);
+ printk(KERN_DEBUG
+ "Unrecognized USBIN packet, type=%x, status=%d\n",
+ usbin->type, urb_status);
break;
- } /* switch */
+ } /* switch */
exit:
if (skb)
dev_kfree_skb(skb);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_ctlx
*
@@ -3775,11 +3337,9 @@ exit:
static void hfa384x_usbin_ctlx(hfa384x_t *hw, hfa384x_usbin_t *usbin,
int urb_status)
{
- hfa384x_usbctlx_t *ctlx;
- int run_queue = 0;
- unsigned long flags;
-
- DBFENTER;
+ hfa384x_usbctlx_t *ctlx;
+ int run_queue = 0;
+ unsigned long flags;
retry:
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -3788,9 +3348,8 @@ retry:
* at any one time, and this is the CTLX that the
* timers are waiting for.
*/
- if ( list_empty(&hw->ctlxq.active) ) {
+ if (list_empty(&hw->ctlxq.active))
goto unlock;
- }
/* Remove the "response timeout". It's possible that
* we are already too late, and that the timeout is
@@ -3803,8 +3362,7 @@ retry:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
goto retry;
}
- }
- else {
+ } else {
hw->resp_timer_done = 1;
}
@@ -3819,15 +3377,16 @@ retry:
if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
run_queue = 1;
} else {
- const u16 intype = (usbin->type&~host2hfa384x_16(0x8000));
+ const u16 intype = (usbin->type & ~cpu_to_le16(0x8000));
/*
* Check that our message is what we're expecting ...
*/
if (ctlx->outbuf.type != intype) {
- WLAN_LOG_WARNING("Expected IN[%d], received IN[%d] - ignored.\n",
- hfa384x2host_16(ctlx->outbuf.type),
- hfa384x2host_16(intype));
+ printk(KERN_WARNING
+ "Expected IN[%d], received IN[%d] - ignored.\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ le16_to_cpu(intype));
goto unlock;
}
@@ -3841,7 +3400,8 @@ retry:
* our request has been acknowledged. Odd,
* but our OUT URB is still alive...
*/
- WLAN_LOG_DEBUG(0, "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n");
+ printk(KERN_DEBUG
+ "Causality violation: please reboot Universe, or email linux-wlan-devel@lists.linux-wlan.com\n");
ctlx->state = CTLX_RESP_COMPLETE;
break;
@@ -3860,14 +3420,15 @@ retry:
/*
* Throw this CTLX away ...
*/
- WLAN_LOG_ERROR("Matched IN URB, CTLX[%d] in invalid state(%s)."
- " Discarded.\n",
- hfa384x2host_16(ctlx->outbuf.type),
- ctlxstr(ctlx->state));
+ printk(KERN_ERR
+ "Matched IN URB, CTLX[%d] in invalid state(%s)."
+ " Discarded.\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state));
if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0)
run_queue = 1;
break;
- } /* switch */
+ } /* switch */
}
unlock:
@@ -3875,11 +3436,8 @@ unlock:
if (run_queue)
hfa384x_usbctlxq_run(hw);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_txcompl
*
@@ -3897,25 +3455,20 @@ unlock:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_txcompl(wlandevice_t *wlandev,
+ hfa384x_usbin_t *usbin)
{
- u16 status;
- DBFENTER;
+ u16 status;
- status = hfa384x2host_16(usbin->type); /* yeah I know it says type...*/
+ status = le16_to_cpu(usbin->type); /* yeah I know it says type... */
/* Was there an error? */
- if (HFA384x_TXSTATUS_ISERROR(status)) {
+ if (HFA384x_TXSTATUS_ISERROR(status))
prism2sta_ev_txexc(wlandev, status);
- } else {
+ else
prism2sta_ev_tx(wlandev, status);
- }
- // prism2sta_ev_alloc(wlandev);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbin_rx
*
@@ -3935,34 +3488,29 @@ static void hfa384x_usbin_txcompl(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
----------------------------------------------------------------*/
static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
{
- hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data;
- hfa384x_t *hw = wlandev->priv;
- int hdrlen;
- p80211_rxmeta_t *rxmeta;
- u16 data_len;
- u16 fc;
-
- DBFENTER;
+ hfa384x_usbin_t *usbin = (hfa384x_usbin_t *) skb->data;
+ hfa384x_t *hw = wlandev->priv;
+ int hdrlen;
+ p80211_rxmeta_t *rxmeta;
+ u16 data_len;
+ u16 fc;
/* Byte order convert once up front. */
- usbin->rxfrm.desc.status =
- hfa384x2host_16(usbin->rxfrm.desc.status);
- usbin->rxfrm.desc.time =
- hfa384x2host_32(usbin->rxfrm.desc.time);
+ usbin->rxfrm.desc.status = le16_to_cpu(usbin->rxfrm.desc.status);
+ usbin->rxfrm.desc.time = le32_to_cpu(usbin->rxfrm.desc.time);
/* Now handle frame based on port# */
- switch( HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) )
- {
+ switch (HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status)) {
case 0:
- fc = ieee2host16(usbin->rxfrm.desc.frame_control);
+ fc = le16_to_cpu(usbin->rxfrm.desc.frame_control);
/* If exclude and we receive an unencrypted, drop it */
- if ( (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
- !WLAN_GET_FC_ISWEP(fc)){
+ if ((wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) &&
+ !WLAN_GET_FC_ISWEP(fc)) {
goto done;
}
- data_len = hfa384x2host_16(usbin->rxfrm.desc.data_len);
+ data_len = le16_to_cpu(usbin->rxfrm.desc.data_len);
/* How much header data do we have? */
hdrlen = p80211_headerlen(fc);
@@ -3974,8 +3522,7 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
* with an "overlapping" copy
*/
memmove(skb_push(skb, hdrlen),
- &usbin->rxfrm.desc.frame_control,
- hdrlen);
+ &usbin->rxfrm.desc.frame_control, hdrlen);
skb->dev = wlandev->netdev;
skb->dev->last_rx = jiffies;
@@ -4001,24 +3548,24 @@ static void hfa384x_usbin_rx(wlandevice_t *wlandev, struct sk_buff *skb)
break;
case 7:
- if ( ! HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status) ) {
+ if (!HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status)) {
/* Copy to wlansnif skb */
- hfa384x_int_rxmonitor( wlandev, &usbin->rxfrm);
+ hfa384x_int_rxmonitor(wlandev, &usbin->rxfrm);
dev_kfree_skb(skb);
} else {
- WLAN_LOG_DEBUG(3,"Received monitor frame: FCSerr set\n");
+ printk(KERN_DEBUG
+ "Received monitor frame: FCSerr set\n");
}
break;
default:
- WLAN_LOG_WARNING("Received frame on unsupported port=%d\n",
- HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status) );
+ printk(KERN_WARNING "Received frame on unsupported port=%d\n",
+ HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status));
goto done;
break;
}
done:
- DBFEXIT;
return;
}
@@ -4043,97 +3590,93 @@ done:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *rxfrm)
+static void hfa384x_int_rxmonitor(wlandevice_t *wlandev,
+ hfa384x_usb_rxfrm_t *rxfrm)
{
- hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
- unsigned int hdrlen = 0;
- unsigned int datalen = 0;
- unsigned int skblen = 0;
- u8 *datap;
- u16 fc;
- struct sk_buff *skb;
- hfa384x_t *hw = wlandev->priv;
-
+ hfa384x_rx_frame_t *rxdesc = &(rxfrm->desc);
+ unsigned int hdrlen = 0;
+ unsigned int datalen = 0;
+ unsigned int skblen = 0;
+ u8 *datap;
+ u16 fc;
+ struct sk_buff *skb;
+ hfa384x_t *hw = wlandev->priv;
- DBFENTER;
/* Don't forget the status, time, and data_len fields are in host order */
/* Figure out how big the frame is */
- fc = ieee2host16(rxdesc->frame_control);
+ fc = le16_to_cpu(rxdesc->frame_control);
hdrlen = p80211_headerlen(fc);
- datalen = hfa384x2host_16(rxdesc->data_len);
+ datalen = le16_to_cpu(rxdesc->data_len);
/* Allocate an ind message+framesize skb */
- skblen = sizeof(p80211_caphdr_t) +
- hdrlen + datalen + WLAN_CRC_LEN;
+ skblen = sizeof(p80211_caphdr_t) + hdrlen + datalen + WLAN_CRC_LEN;
/* sanity check the length */
- if ( skblen >
- (sizeof(p80211_caphdr_t) +
- WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN) ) {
- WLAN_LOG_DEBUG(1, "overlen frm: len=%zd\n",
- skblen - sizeof(p80211_caphdr_t));
+ if (skblen >
+ (sizeof(p80211_caphdr_t) +
+ WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) {
+ pr_debug("overlen frm: len=%zd\n",
+ skblen - sizeof(p80211_caphdr_t));
}
- if ( (skb = dev_alloc_skb(skblen)) == NULL ) {
- WLAN_LOG_ERROR("alloc_skb failed trying to allocate %d bytes\n", skblen);
+ if ((skb = dev_alloc_skb(skblen)) == NULL) {
+ printk(KERN_ERR
+ "alloc_skb failed trying to allocate %d bytes\n",
+ skblen);
return;
}
/* only prepend the prism header if in the right mode */
if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) &&
(hw->sniffhdr != 0)) {
- p80211_caphdr_t *caphdr;
+ p80211_caphdr_t *caphdr;
/* The NEW header format! */
datap = skb_put(skb, sizeof(p80211_caphdr_t));
- caphdr = (p80211_caphdr_t*) datap;
-
- caphdr->version = htonl(P80211CAPTURE_VERSION);
- caphdr->length = htonl(sizeof(p80211_caphdr_t));
- caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000;
- caphdr->hosttime = __cpu_to_be64(jiffies);
- caphdr->phytype = htonl(4); /* dss_dot11_b */
- caphdr->channel = htonl(hw->sniff_channel);
- caphdr->datarate = htonl(rxdesc->rate);
- caphdr->antenna = htonl(0); /* unknown */
- caphdr->priority = htonl(0); /* unknown */
- caphdr->ssi_type = htonl(3); /* rssi_raw */
- caphdr->ssi_signal = htonl(rxdesc->signal);
- caphdr->ssi_noise = htonl(rxdesc->silence);
- caphdr->preamble = htonl(0); /* unknown */
- caphdr->encoding = htonl(1); /* cck */
+ caphdr = (p80211_caphdr_t *) datap;
+
+ caphdr->version = htonl(P80211CAPTURE_VERSION);
+ caphdr->length = htonl(sizeof(p80211_caphdr_t));
+ caphdr->mactime = __cpu_to_be64(rxdesc->time) * 1000;
+ caphdr->hosttime = __cpu_to_be64(jiffies);
+ caphdr->phytype = htonl(4); /* dss_dot11_b */
+ caphdr->channel = htonl(hw->sniff_channel);
+ caphdr->datarate = htonl(rxdesc->rate);
+ caphdr->antenna = htonl(0); /* unknown */
+ caphdr->priority = htonl(0); /* unknown */
+ caphdr->ssi_type = htonl(3); /* rssi_raw */
+ caphdr->ssi_signal = htonl(rxdesc->signal);
+ caphdr->ssi_noise = htonl(rxdesc->silence);
+ caphdr->preamble = htonl(0); /* unknown */
+ caphdr->encoding = htonl(1); /* cck */
}
/* Copy the 802.11 header to the skb (ctl frames may be less than a full header) */
datap = skb_put(skb, hdrlen);
- memcpy( datap, &(rxdesc->frame_control), hdrlen);
+ memcpy(datap, &(rxdesc->frame_control), hdrlen);
/* If any, copy the data from the card to the skb */
- if ( datalen > 0 )
- {
+ if (datalen > 0) {
datap = skb_put(skb, datalen);
memcpy(datap, rxfrm->data, datalen);
/* check for unencrypted stuff if WEP bit set. */
- if (*(datap - hdrlen + 1) & 0x40) // wep set
- if ((*(datap) == 0xaa) && (*(datap+1) == 0xaa))
- *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
+ if (*(datap - hdrlen + 1) & 0x40) /* wep set */
+ if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa))
+ *(datap - hdrlen + 1) &= 0xbf; // clear wep; it's the 802.2 header!
}
if (hw->sniff_fcs) {
/* Set the FCS */
datap = skb_put(skb, WLAN_CRC_LEN);
- memset( datap, 0xff, WLAN_CRC_LEN);
+ memset(datap, 0xff, WLAN_CRC_LEN);
}
/* pass it back up */
prism2sta_ev_rx(wlandev, skb);
- DBFEXIT;
return;
}
-
-
/*----------------------------------------------------------------
* hfa384x_usbin_info
*
@@ -4151,18 +3694,13 @@ static void hfa384x_int_rxmonitor( wlandevice_t *wlandev, hfa384x_usb_rxfrm_t *r
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
+static void hfa384x_usbin_info(wlandevice_t * wlandev, hfa384x_usbin_t * usbin)
{
- DBFENTER;
-
- usbin->infofrm.info.framelen = hfa384x2host_16(usbin->infofrm.info.framelen);
+ usbin->infofrm.info.framelen =
+ le16_to_cpu(usbin->infofrm.info.framelen);
prism2sta_ev_info(wlandev, &usbin->infofrm.info);
-
- DBFEXIT;
}
-
-
/*----------------------------------------------------------------
* hfa384x_usbout_callback
*
@@ -4181,48 +3719,49 @@ static void hfa384x_usbin_info(wlandevice_t *wlandev, hfa384x_usbin_t *usbin)
----------------------------------------------------------------*/
static void hfa384x_usbout_callback(struct urb *urb)
{
- wlandevice_t *wlandev = urb->context;
- hfa384x_usbout_t *usbout = urb->transfer_buffer;
- DBFENTER;
+ wlandevice_t *wlandev = urb->context;
+ hfa384x_usbout_t *usbout = urb->transfer_buffer;
#ifdef DEBUG_USB
dbprint_urb(urb);
#endif
- if ( wlandev &&
- wlandev->netdev ) {
+ if (wlandev && wlandev->netdev) {
- switch(urb->status) {
+ switch (urb->status) {
case 0:
hfa384x_usbout_tx(wlandev, usbout);
break;
case -EPIPE:
- {
- hfa384x_t *hw = wlandev->priv;
- WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
- wlandev->netdev->name);
- if ( !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) )
- schedule_work(&hw->usb_work);
- ++(wlandev->linux_stats.tx_errors);
- break;
- }
+ {
+ hfa384x_t *hw = wlandev->priv;
+ printk(KERN_WARNING
+ "%s tx pipe stalled: requesting reset\n",
+ wlandev->netdev->name);
+ if (!test_and_set_bit
+ (WORK_TX_HALT, &hw->usb_flags))
+ schedule_work(&hw->usb_work);
+ ++(wlandev->linux_stats.tx_errors);
+ break;
+ }
case -EPROTO:
case -ETIMEDOUT:
case -EILSEQ:
- {
- hfa384x_t *hw = wlandev->priv;
-
- if ( !test_and_set_bit(THROTTLE_TX, &hw->usb_flags)
- && !timer_pending(&hw->throttle) ) {
- mod_timer(&hw->throttle,
- jiffies + THROTTLE_JIFFIES);
+ {
+ hfa384x_t *hw = wlandev->priv;
+
+ if (!test_and_set_bit
+ (THROTTLE_TX, &hw->usb_flags)
+ && !timer_pending(&hw->throttle)) {
+ mod_timer(&hw->throttle,
+ jiffies + THROTTLE_JIFFIES);
+ }
+ ++(wlandev->linux_stats.tx_errors);
+ netif_stop_queue(wlandev->netdev);
+ break;
}
- ++(wlandev->linux_stats.tx_errors);
- netif_stop_queue(wlandev->netdev);
- break;
- }
case -ENOENT:
case -ESHUTDOWN:
@@ -4230,16 +3769,14 @@ static void hfa384x_usbout_callback(struct urb *urb)
break;
default:
- WLAN_LOG_INFO("unknown urb->status=%d\n", urb->status);
+ printk(KERN_INFO "unknown urb->status=%d\n",
+ urb->status);
++(wlandev->linux_stats.tx_errors);
break;
- } /* switch */
+ } /* switch */
}
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_ctlxout_callback
*
@@ -4258,22 +3795,19 @@ static void hfa384x_usbout_callback(struct urb *urb)
----------------------------------------------------------------*/
static void hfa384x_ctlxout_callback(struct urb *urb)
{
- hfa384x_t *hw = urb->context;
- int delete_resptimer = 0;
- int timer_ok = 1;
- int run_queue = 0;
- hfa384x_usbctlx_t *ctlx;
- unsigned long flags;
-
- DBFENTER;
+ hfa384x_t *hw = urb->context;
+ int delete_resptimer = 0;
+ int timer_ok = 1;
+ int run_queue = 0;
+ hfa384x_usbctlx_t *ctlx;
+ unsigned long flags;
- WLAN_LOG_DEBUG(3,"urb->status=%d\n", urb->status);
+ pr_debug("urb->status=%d\n", urb->status);
#ifdef DEBUG_USB
dbprint_urb(urb);
#endif
- if ( (urb->status == -ESHUTDOWN) ||
- (urb->status == -ENODEV) ||
- (hw == NULL) )
+ if ((urb->status == -ESHUTDOWN) ||
+ (urb->status == -ENODEV) || (hw == NULL))
goto done;
retry:
@@ -4285,7 +3819,7 @@ retry:
* rely on the disconnect function to clean everything
* up if someone unplugged the adapter.
*/
- if ( list_empty(&hw->ctlxq.active) ) {
+ if (list_empty(&hw->ctlxq.active)) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
goto done;
}
@@ -4304,16 +3838,15 @@ retry:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
goto retry;
}
- }
- else {
+ } else {
hw->req_timer_done = 1;
}
ctlx = get_active_ctlx(hw);
- if ( urb->status == 0 ) {
+ if (urb->status == 0) {
/* Request portion of a CTLX is successful */
- switch ( ctlx->state ) {
+ switch (ctlx->state) {
case CTLX_REQ_SUBMITTED:
/* This OUT-ACK received before IN */
ctlx->state = CTLX_REQ_COMPLETE;
@@ -4330,18 +3863,19 @@ retry:
default:
/* This is NOT a valid CTLX "success" state! */
- WLAN_LOG_ERROR(
- "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
- hfa384x2host_16(ctlx->outbuf.type),
- ctlxstr(ctlx->state), urb->status);
+ printk(KERN_ERR
+ "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n",
+ le16_to_cpu(ctlx->outbuf.type),
+ ctlxstr(ctlx->state), urb->status);
break;
- } /* switch */
+ } /* switch */
} else {
/* If the pipe has stalled then we need to reset it */
- if ( (urb->status == -EPIPE) &&
- !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags) ) {
- WLAN_LOG_WARNING("%s tx pipe stalled: requesting reset\n",
- hw->wlandev->netdev->name);
+ if ((urb->status == -EPIPE) &&
+ !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) {
+ printk(KERN_WARNING
+ "%s tx pipe stalled: requesting reset\n",
+ hw->wlandev->netdev->name);
schedule_work(&hw->usb_work);
}
@@ -4354,7 +3888,7 @@ retry:
run_queue = 1;
}
- delresp:
+delresp:
if (delete_resptimer) {
if ((timer_ok = del_timer(&hw->resptimer)) != 0) {
hw->resp_timer_done = 1;
@@ -4363,7 +3897,7 @@ retry:
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
- if ( !timer_ok && (hw->resp_timer_done == 0) ) {
+ if (!timer_ok && (hw->resp_timer_done == 0)) {
spin_lock_irqsave(&hw->ctlxq.lock, flags);
goto delresp;
}
@@ -4371,11 +3905,10 @@ retry:
if (run_queue)
hfa384x_usbctlxq_run(hw);
- done:
- DBFEXIT;
+done:
+ ;
}
-
/*----------------------------------------------------------------
* hfa384x_usbctlx_reqtimerfn
*
@@ -4394,12 +3927,10 @@ retry:
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_usbctlx_reqtimerfn(unsigned long data)
+static void hfa384x_usbctlx_reqtimerfn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
- unsigned long flags;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -4408,15 +3939,13 @@ hfa384x_usbctlx_reqtimerfn(unsigned long data)
/* Removing the hardware automatically empties
* the active list ...
*/
- if ( !list_empty(&hw->ctlxq.active) )
- {
+ if (!list_empty(&hw->ctlxq.active)) {
/*
* We must ensure that our URB is removed from
* the system, if it hasn't already expired.
*/
hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK;
- if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS)
- {
+ if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) {
hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
ctlx->state = CTLX_REQ_FAILED;
@@ -4436,11 +3965,8 @@ hfa384x_usbctlx_reqtimerfn(unsigned long data)
}
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbctlx_resptimerfn
*
@@ -4459,13 +3985,10 @@ hfa384x_usbctlx_reqtimerfn(unsigned long data)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_usbctlx_resptimerfn(unsigned long data)
+static void hfa384x_usbctlx_resptimerfn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
- unsigned long flags;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -4474,12 +3997,10 @@ hfa384x_usbctlx_resptimerfn(unsigned long data)
/* The active list will be empty if the
* adapter has been unplugged ...
*/
- if ( !list_empty(&hw->ctlxq.active) )
- {
+ if (!list_empty(&hw->ctlxq.active)) {
hfa384x_usbctlx_t *ctlx = get_active_ctlx(hw);
- if ( unlocked_usbctlx_cancel_async(hw, ctlx) == 0 )
- {
+ if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) {
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
hfa384x_usbctlxq_run(hw);
goto done;
@@ -4488,8 +4009,9 @@ hfa384x_usbctlx_resptimerfn(unsigned long data)
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
- done:
- DBFEXIT;
+done:
+ ;
+
}
/*----------------------------------------------------------------
@@ -4507,13 +4029,10 @@ hfa384x_usbctlx_resptimerfn(unsigned long data)
* Call context:
* Interrupt
----------------------------------------------------------------*/
-static void
-hfa384x_usb_throttlefn(unsigned long data)
+static void hfa384x_usb_throttlefn(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t*)data;
- unsigned long flags;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
+ unsigned long flags;
spin_lock_irqsave(&hw->ctlxq.lock, flags);
@@ -4521,25 +4040,20 @@ hfa384x_usb_throttlefn(unsigned long data)
* We need to check BOTH the RX and the TX throttle controls,
* so we use the bitwise OR instead of the logical OR.
*/
- WLAN_LOG_DEBUG(3, "flags=0x%lx\n", hw->usb_flags);
- if ( !hw->wlandev->hwremoved &&
- (
- (test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
- !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags))
- |
- (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
- !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
- ) )
- {
+ pr_debug("flags=0x%lx\n", hw->usb_flags);
+ if (!hw->wlandev->hwremoved &&
+ ((test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) &&
+ !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags))
+ |
+ (test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) &&
+ !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags))
+ )) {
schedule_work(&hw->usb_work);
}
spin_unlock_irqrestore(&hw->ctlxq.lock, flags);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* hfa384x_usbctlx_submit
*
@@ -4558,16 +4072,11 @@ hfa384x_usb_throttlefn(unsigned long data)
* Call context:
* process or interrupt
----------------------------------------------------------------*/
-static int
-hfa384x_usbctlx_submit(
- hfa384x_t *hw,
- hfa384x_usbctlx_t *ctlx)
+static int hfa384x_usbctlx_submit(hfa384x_t *hw, hfa384x_usbctlx_t *ctlx)
{
unsigned long flags;
int ret;
- DBFENTER;
-
spin_lock_irqsave(&hw->ctlxq.lock, flags);
if (hw->wlandev->hwremoved) {
@@ -4582,11 +4091,9 @@ hfa384x_usbctlx_submit(
ret = 0;
}
- DBFEXIT;
return ret;
}
-
/*----------------------------------------------------------------
* hfa384x_usbout_tx
*
@@ -4608,11 +4115,7 @@ hfa384x_usbctlx_submit(
----------------------------------------------------------------*/
static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
{
- DBFENTER;
-
prism2sta_ev_alloc(wlandev);
-
- DBFEXIT;
}
/*----------------------------------------------------------------
@@ -4631,10 +4134,9 @@ static void hfa384x_usbout_tx(wlandevice_t *wlandev, hfa384x_usbout_t *usbout)
*
* Call context:
----------------------------------------------------------------*/
-static int
-hfa384x_isgood_pdrcode(u16 pdrcode)
+static int hfa384x_isgood_pdrcode(u16 pdrcode)
{
- switch(pdrcode) {
+ switch (pdrcode) {
case HFA384x_PDR_END_OF_PDA:
case HFA384x_PDR_PCB_PARTNUM:
case HFA384x_PDR_PDAVER:
@@ -4668,23 +4170,20 @@ hfa384x_isgood_pdrcode(u16 pdrcode)
return 1;
break;
default:
- if ( pdrcode < 0x1000 ) {
+ if (pdrcode < 0x1000) {
/* code is OK, but we don't know exactly what it is */
- WLAN_LOG_DEBUG(3,
- "Encountered unknown PDR#=0x%04x, "
- "assuming it's ok.\n",
- pdrcode);
+ printk(KERN_DEBUG
+ "Encountered unknown PDR#=0x%04x, "
+ "assuming it's ok.\n", pdrcode);
return 1;
} else {
/* bad code */
- WLAN_LOG_DEBUG(3,
- "Encountered unknown PDR#=0x%04x, "
- "(>=0x1000), assuming it's bad.\n",
- pdrcode);
+ printk(KERN_DEBUG
+ "Encountered unknown PDR#=0x%04x, "
+ "(>=0x1000), assuming it's bad.\n", pdrcode);
return 0;
}
break;
}
- return 0; /* avoid compiler warnings */
+ return 0; /* avoid compiler warnings */
}
-
diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c
index dfc7b3a1e9c..2abce0c3444 100644
--- a/drivers/staging/wlan-ng/p80211conv.c
+++ b/drivers/staging/wlan-ng/p80211conv.c
@@ -48,10 +48,8 @@
* 802.11 frame conversions.
*
* --------------------------------------------------------------------
-*/
-/*================================================================*/
-/* System Includes */
-
+*
+*================================================================ */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -63,14 +61,10 @@
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
+#include <linux/byteorder/generic.h>
#include <asm/byteorder.h>
-#include "wlan_compat.h"
-
-/*================================================================*/
-/* Project Includes */
-
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
@@ -80,30 +74,8 @@
#include "p80211ioctl.h"
#include "p80211req.h"
-
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-
-/*================================================================*/
-/* Local Static Definitions */
-
-static u8 oui_rfc1042[] = {0x00, 0x00, 0x00};
-static u8 oui_8021h[] = {0x00, 0x00, 0xf8};
-
-/*================================================================*/
-/* Local Function Declarations */
-
-
-/*================================================================*/
-/* Function Definitions */
+static u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 };
+static u8 oui_8021h[] = { 0x00, 0x00, 0xf8 };
/*----------------------------------------------------------------
* p80211pb_ether_to_80211
@@ -130,35 +102,36 @@ static u8 oui_8021h[] = {0x00, 0x00, 0xf8};
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep)
+int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv,
+ struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep)
{
- u16 fc;
- u16 proto;
- wlan_ethhdr_t e_hdr;
- wlan_llc_t *e_llc;
- wlan_snap_t *e_snap;
+ u16 fc;
+ u16 proto;
+ wlan_ethhdr_t e_hdr;
+ wlan_llc_t *e_llc;
+ wlan_snap_t *e_snap;
int foo;
- DBFENTER;
memcpy(&e_hdr, skb->data, sizeof(e_hdr));
if (skb->len <= 0) {
- WLAN_LOG_DEBUG(1, "zero-length skb!\n");
+ pr_debug("zero-length skb!\n");
return 1;
}
- if ( ethconv == WLAN_ETHCONV_ENCAP ) { /* simplest case */
- WLAN_LOG_DEBUG(3, "ENCAP len: %d\n", skb->len);
+ if (ethconv == WLAN_ETHCONV_ENCAP) { /* simplest case */
+ pr_debug("ENCAP len: %d\n", skb->len);
/* here, we don't care what kind of ether frm. Just stick it */
/* in the 80211 payload */
/* which is to say, leave the skb alone. */
} else {
/* step 1: classify ether frame, DIX or 802.3? */
proto = ntohs(e_hdr.type);
- if ( proto <= 1500 ) {
- WLAN_LOG_DEBUG(3, "802.3 len: %d\n", skb->len);
- /* codes <= 1500 reserved for 802.3 lengths */
+ if (proto <= 1500) {
+ pr_debug("802.3 len: %d\n", skb->len);
+ /* codes <= 1500 reserved for 802.3 lengths */
/* it's 802.3, pass ether payload unchanged, */
/* trim off ethernet header */
@@ -167,23 +140,28 @@ int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* leave off any PAD octets. */
skb_trim(skb, proto);
} else {
- WLAN_LOG_DEBUG(3, "DIXII len: %d\n", skb->len);
+ pr_debug("DIXII len: %d\n", skb->len);
/* it's DIXII, time for some conversion */
/* trim off ethernet header */
skb_pull(skb, WLAN_ETHHDR_LEN);
/* tack on SNAP */
- e_snap = (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
+ e_snap =
+ (wlan_snap_t *) skb_push(skb, sizeof(wlan_snap_t));
e_snap->type = htons(proto);
- if ( ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto) ) {
- memcpy( e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN);
+ if (ethconv == WLAN_ETHCONV_8021h
+ && p80211_stt_findproto(proto)) {
+ memcpy(e_snap->oui, oui_8021h,
+ WLAN_IEEE_OUI_LEN);
} else {
- memcpy( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN);
+ memcpy(e_snap->oui, oui_rfc1042,
+ WLAN_IEEE_OUI_LEN);
}
/* tack on llc */
- e_llc = (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
+ e_llc =
+ (wlan_llc_t *) skb_push(skb, sizeof(wlan_llc_t));
e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */
e_llc->ssap = 0xAA;
e_llc->ctl = 0x03;
@@ -193,62 +171,61 @@ int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* Set up the 802.11 header */
/* It's a data frame */
- fc = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
- WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
+ fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) |
+ WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY));
- switch ( wlandev->macmode ) {
+ switch (wlandev->macmode) {
case WLAN_MACMODE_IBSS_STA:
- memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
- memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
- memcpy(p80211_hdr->a3.a3, wlandev->bssid, WLAN_ADDR_LEN);
+ memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a3, wlandev->bssid, ETH_ALEN);
break;
case WLAN_MACMODE_ESS_STA:
- fc |= host2ieee16(WLAN_SET_FC_TODS(1));
- memcpy(p80211_hdr->a3.a1, wlandev->bssid, WLAN_ADDR_LEN);
- memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
- memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, WLAN_ADDR_LEN);
+ fc |= cpu_to_le16(WLAN_SET_FC_TODS(1));
+ memcpy(p80211_hdr->a3.a1, wlandev->bssid, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, ETH_ALEN);
break;
case WLAN_MACMODE_ESS_AP:
- fc |= host2ieee16(WLAN_SET_FC_FROMDS(1));
- memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, WLAN_ADDR_LEN);
- memcpy(p80211_hdr->a3.a2, wlandev->bssid, WLAN_ADDR_LEN);
- memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, WLAN_ADDR_LEN);
+ fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1));
+ memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a2, wlandev->bssid, ETH_ALEN);
+ memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, ETH_ALEN);
break;
default:
- WLAN_LOG_ERROR("Error: Converting eth to wlan in unknown mode.\n");
+ printk(KERN_ERR
+ "Error: Converting eth to wlan in unknown mode.\n");
return 1;
break;
}
p80211_wep->data = NULL;
- if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
- // XXXX need to pick keynum other than default?
+ if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+ && (wlandev->hostwep & HOSTWEP_ENCRYPT)) {
+ /* XXXX need to pick keynum other than default? */
-#if 1
p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC);
-#else
- p80211_wep->data = skb->data;
-#endif
if ((foo = wep_encrypt(wlandev, skb->data, p80211_wep->data,
skb->len,
- (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK),
- p80211_wep->iv, p80211_wep->icv))) {
- WLAN_LOG_WARNING("Host en-WEP failed, dropping frame (%d).\n", foo);
+ (wlandev->
+ hostwep & HOSTWEP_DEFAULTKEY_MASK),
+ p80211_wep->iv, p80211_wep->icv))) {
+ printk(KERN_WARNING
+ "Host en-WEP failed, dropping frame (%d).\n",
+ foo);
return 2;
}
- fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+ fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
}
-
- // skb->nh.raw = skb->data;
+ /* skb->nh.raw = skb->data; */
p80211_hdr->a3.fc = fc;
p80211_hdr->a3.dur = 0;
p80211_hdr->a3.seq = 0;
- DBFEXIT;
return 0;
}
@@ -256,22 +233,24 @@ int skb_ether_to_p80211( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
p80211_rxmeta_t *rxmeta)
{
- int i;
+ int i;
- /* Gather wireless spy statistics: for each packet, compare the
- * source address with out list, and if match, get the stats... */
+ /* Gather wireless spy statistics: for each packet, compare the
+ * source address with out list, and if match, get the stats... */
- for (i = 0; i < wlandev->spy_number; i++) {
+ for (i = 0; i < wlandev->spy_number; i++) {
- if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
+ if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) {
memcpy(wlandev->spy_address[i], mac, ETH_ALEN);
- wlandev->spy_stat[i].level = rxmeta->signal;
- wlandev->spy_stat[i].noise = rxmeta->noise;
- wlandev->spy_stat[i].qual = (rxmeta->signal > rxmeta->noise) ? \
- (rxmeta->signal - rxmeta->noise) : 0;
- wlandev->spy_stat[i].updated = 0x7;
- }
- }
+ wlandev->spy_stat[i].level = rxmeta->signal;
+ wlandev->spy_stat[i].noise = rxmeta->noise;
+ wlandev->spy_stat[i].qual =
+ (rxmeta->signal >
+ rxmeta->noise) ? (rxmeta->signal -
+ rxmeta->noise) : 0;
+ wlandev->spy_stat[i].updated = 0x7;
+ }
+ }
}
/*----------------------------------------------------------------
@@ -293,43 +272,42 @@ static void orinoco_spy_gather(wlandevice_t *wlandev, char *mac,
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb)
+int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv,
+ struct sk_buff *skb)
{
- netdevice_t *netdev = wlandev->netdev;
- u16 fc;
- unsigned int payload_length;
- unsigned int payload_offset;
- u8 daddr[WLAN_ETHADDR_LEN];
- u8 saddr[WLAN_ETHADDR_LEN];
- p80211_hdr_t *w_hdr;
- wlan_ethhdr_t *e_hdr;
- wlan_llc_t *e_llc;
- wlan_snap_t *e_snap;
+ netdevice_t *netdev = wlandev->netdev;
+ u16 fc;
+ unsigned int payload_length;
+ unsigned int payload_offset;
+ u8 daddr[WLAN_ETHADDR_LEN];
+ u8 saddr[WLAN_ETHADDR_LEN];
+ p80211_hdr_t *w_hdr;
+ wlan_ethhdr_t *e_hdr;
+ wlan_llc_t *e_llc;
+ wlan_snap_t *e_snap;
int foo;
- DBFENTER;
-
payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN;
payload_offset = WLAN_HDR_A3_LEN;
w_hdr = (p80211_hdr_t *) skb->data;
- /* setup some vars for convenience */
- fc = ieee2host16(w_hdr->a3.fc);
- if ( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+ /* setup some vars for convenience */
+ fc = le16_to_cpu(w_hdr->a3.fc);
+ if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
- } else if( (WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1) ) {
+ } else if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1)) {
memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN);
memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
- } else if( (WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0) ) {
+ } else if ((WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0)) {
memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN);
memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN);
} else {
payload_offset = WLAN_HDR_A4_LEN;
if (payload_length < WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN) {
- WLAN_LOG_ERROR("A4 frame too short!\n");
+ printk(KERN_ERR "A4 frame too short!\n");
return 1;
}
payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN);
@@ -338,18 +316,22 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
}
/* perform de-wep if necessary.. */
- if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc) && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
+ if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && WLAN_GET_FC_ISWEP(fc)
+ && (wlandev->hostwep & HOSTWEP_DECRYPT)) {
if (payload_length <= 8) {
- WLAN_LOG_ERROR("WEP frame too short (%u).\n",
- skb->len);
+ printk(KERN_ERR "WEP frame too short (%u).\n",
+ skb->len);
return 1;
}
if ((foo = wep_decrypt(wlandev, skb->data + payload_offset + 4,
payload_length - 8, -1,
skb->data + payload_offset,
- skb->data + payload_offset + payload_length - 4))) {
+ skb->data + payload_offset +
+ payload_length - 4))) {
/* de-wep failed, drop skb. */
- WLAN_LOG_DEBUG(1, "Host de-WEP failed, dropping frame (%d).\n", foo);
+ printk(KERN_DEBUG
+ "Host de-WEP failed, dropping frame (%d).\n",
+ foo);
wlandev->rx.decrypt_err++;
return 2;
}
@@ -367,21 +349,22 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
e_hdr = (wlan_ethhdr_t *) (skb->data + payload_offset);
e_llc = (wlan_llc_t *) (skb->data + payload_offset);
- e_snap = (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
+ e_snap =
+ (wlan_snap_t *) (skb->data + payload_offset + sizeof(wlan_llc_t));
/* Test for the various encodings */
- if ( (payload_length >= sizeof(wlan_ethhdr_t)) &&
- ( e_llc->dsap != 0xaa || e_llc->ssap != 0xaa ) &&
- ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
+ if ((payload_length >= sizeof(wlan_ethhdr_t)) &&
+ (e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) &&
+ ((memcmp(daddr, e_hdr->daddr, WLAN_ETHADDR_LEN) == 0) ||
(memcmp(saddr, e_hdr->saddr, WLAN_ETHADDR_LEN) == 0))) {
- WLAN_LOG_DEBUG(3, "802.3 ENCAP len: %d\n", payload_length);
+ pr_debug("802.3 ENCAP len: %d\n", payload_length);
/* 802.3 Encapsulated */
/* Test for an overlength frame */
- if ( payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
+ if (payload_length > (netdev->mtu + WLAN_ETHHDR_LEN)) {
/* A bogus length ethfrm has been encap'd. */
/* Is someone trying an oflow attack? */
- WLAN_LOG_ERROR("ENCAP frame too large (%d > %d)\n",
- payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
+ printk(KERN_ERR "ENCAP frame too large (%d > %d)\n",
+ payload_length, netdev->mtu + WLAN_ETHHDR_LEN);
return 1;
}
@@ -390,25 +373,25 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* chop off the 802.11 CRC */
skb_trim(skb, skb->len - WLAN_CRC_LEN);
- } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
- (e_llc->dsap == 0xaa) &&
- (e_llc->ssap == 0xaa) &&
- (e_llc->ctl == 0x03) &&
- (((memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)==0) &&
- (ethconv == WLAN_ETHCONV_8021h) &&
- (p80211_stt_findproto(ieee2host16(e_snap->type)))) ||
- (memcmp( e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN)!=0)))
- {
- WLAN_LOG_DEBUG(3, "SNAP+RFC1042 len: %d\n", payload_length);
+ } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t))
+ && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
+ && (e_llc->ctl == 0x03)
+ &&
+ (((memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) == 0)
+ && (ethconv == WLAN_ETHCONV_8021h)
+ && (p80211_stt_findproto(le16_to_cpu(e_snap->type))))
+ || (memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) !=
+ 0))) {
+ pr_debug("SNAP+RFC1042 len: %d\n", payload_length);
/* it's a SNAP + RFC1042 frame && protocol is in STT */
/* build 802.3 + RFC1042 */
/* Test for an overlength frame */
- if ( payload_length > netdev->mtu ) {
+ if (payload_length > netdev->mtu) {
/* A bogus length ethfrm has been sent. */
/* Is someone trying an oflow attack? */
- WLAN_LOG_ERROR("SNAP frame too large (%d > %d)\n",
- payload_length, netdev->mtu);
+ printk(KERN_ERR "SNAP frame too large (%d > %d)\n",
+ payload_length, netdev->mtu);
return 1;
}
@@ -424,11 +407,10 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* chop off the 802.11 CRC */
skb_trim(skb, skb->len - WLAN_CRC_LEN);
- } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t)) &&
- (e_llc->dsap == 0xaa) &&
- (e_llc->ssap == 0xaa) &&
- (e_llc->ctl == 0x03) ) {
- WLAN_LOG_DEBUG(3, "802.1h/RFC1042 len: %d\n", payload_length);
+ } else if ((payload_length >= sizeof(wlan_llc_t) + sizeof(wlan_snap_t))
+ && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa)
+ && (e_llc->ctl == 0x03)) {
+ pr_debug("802.1h/RFC1042 len: %d\n", payload_length);
/* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */
/* build a DIXII + RFC894 */
@@ -437,10 +419,9 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
> netdev->mtu) {
/* A bogus length ethfrm has been sent. */
/* Is someone trying an oflow attack? */
- WLAN_LOG_ERROR("DIXII frame too large (%ld > %d)\n",
- (long int) (payload_length - sizeof(wlan_llc_t) -
- sizeof(wlan_snap_t)),
- netdev->mtu);
+ printk(KERN_ERR "DIXII frame too large (%ld > %d)\n",
+ (long int)(payload_length - sizeof(wlan_llc_t) -
+ sizeof(wlan_snap_t)), netdev->mtu);
return 1;
}
@@ -462,19 +443,18 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
/* chop off the 802.11 CRC */
skb_trim(skb, skb->len - WLAN_CRC_LEN);
} else {
- WLAN_LOG_DEBUG(3, "NON-ENCAP len: %d\n", payload_length);
+ pr_debug("NON-ENCAP len: %d\n", payload_length);
/* any NON-ENCAP */
/* it's a generic 80211+LLC or IPX 'Raw 802.3' */
/* build an 802.3 frame */
/* allocate space and setup hostbuf */
/* Test for an overlength frame */
- if ( payload_length > netdev->mtu ) {
+ if (payload_length > netdev->mtu) {
/* A bogus length ethfrm has been sent. */
/* Is someone trying an oflow attack? */
- WLAN_LOG_ERROR("OTHER frame too large (%d > %d)\n",
- payload_length,
- netdev->mtu);
+ printk(KERN_ERR "OTHER frame too large (%d > %d)\n",
+ payload_length, netdev->mtu);
return 1;
}
@@ -492,26 +472,26 @@ int skb_p80211_to_ether( wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb
}
- /*
- * Note that eth_type_trans() expects an skb w/ skb->data pointing
- * at the MAC header, it then sets the following skb members:
- * skb->mac_header,
- * skb->data, and
- * skb->pkt_type.
- * It then _returns_ the value that _we're_ supposed to stuff in
- * skb->protocol. This is nuts.
- */
+ /*
+ * Note that eth_type_trans() expects an skb w/ skb->data pointing
+ * at the MAC header, it then sets the following skb members:
+ * skb->mac_header,
+ * skb->data, and
+ * skb->pkt_type.
+ * It then _returns_ the value that _we're_ supposed to stuff in
+ * skb->protocol. This is nuts.
+ */
skb->protocol = eth_type_trans(skb, netdev);
- /* jkriegl: process signal and noise as set in hfa384x_int_rx() */
+ /* jkriegl: process signal and noise as set in hfa384x_int_rx() */
/* jkriegl: only process signal/noise if requested by iwspy */
- if (wlandev->spy_number)
- orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, P80211SKB_RXMETA(skb));
+ if (wlandev->spy_number)
+ orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source,
+ P80211SKB_RXMETA(skb));
/* Free the metadata */
p80211skb_rxmeta_detach(skb);
- DBFEXIT;
return 0;
}
@@ -536,11 +516,11 @@ int p80211_stt_findproto(u16 proto)
/* Always return found for now. This is the behavior used by the */
/* Zoom Win95 driver when 802.1h mode is selected */
/* TODO: If necessary, add an actual search we'll probably
- need this to match the CMAC's way of doing things.
- Need to do some testing to confirm.
- */
+ need this to match the CMAC's way of doing things.
+ Need to do some testing to confirm.
+ */
- if (proto == 0x80f3) /* APPLETALK */
+ if (proto == 0x80f3) /* APPLETALK */
return 1;
return 0;
@@ -561,26 +541,24 @@ int p80211_stt_findproto(u16 proto)
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-void
-p80211skb_rxmeta_detach(struct sk_buff *skb)
+void p80211skb_rxmeta_detach(struct sk_buff *skb)
{
- p80211_rxmeta_t *rxmeta;
- p80211_frmmeta_t *frmmeta;
+ p80211_rxmeta_t *rxmeta;
+ p80211_frmmeta_t *frmmeta;
- DBFENTER;
/* Sanity checks */
- if ( skb==NULL ) { /* bad skb */
- WLAN_LOG_DEBUG(1, "Called w/ null skb.\n");
+ if (skb == NULL) { /* bad skb */
+ pr_debug("Called w/ null skb.\n");
goto exit;
}
frmmeta = P80211SKB_FRMMETA(skb);
- if ( frmmeta == NULL ) { /* no magic */
- WLAN_LOG_DEBUG(1, "Called w/ bad frmmeta magic.\n");
+ if (frmmeta == NULL) { /* no magic */
+ pr_debug("Called w/ bad frmmeta magic.\n");
goto exit;
}
rxmeta = frmmeta->rx;
- if ( rxmeta == NULL ) { /* bad meta ptr */
- WLAN_LOG_DEBUG(1, "Called w/ bad rxmeta ptr.\n");
+ if (rxmeta == NULL) { /* bad meta ptr */
+ pr_debug("Called w/ bad rxmeta ptr.\n");
goto exit;
}
@@ -590,7 +568,6 @@ p80211skb_rxmeta_detach(struct sk_buff *skb)
/* Clear skb->cb */
memset(skb->cb, 0, sizeof(skb->cb));
exit:
- DBFEXIT;
return;
}
@@ -610,19 +587,16 @@ exit:
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-int
-p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
+int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
{
- int result = 0;
- p80211_rxmeta_t *rxmeta;
- p80211_frmmeta_t *frmmeta;
-
- DBFENTER;
+ int result = 0;
+ p80211_rxmeta_t *rxmeta;
+ p80211_frmmeta_t *frmmeta;
/* If these already have metadata, we error out! */
if (P80211SKB_RXMETA(skb) != NULL) {
- WLAN_LOG_ERROR("%s: RXmeta already attached!\n",
- wlandev->name);
+ printk(KERN_ERR "%s: RXmeta already attached!\n",
+ wlandev->name);
result = 0;
goto exit;
}
@@ -630,9 +604,9 @@ p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
/* Allocate the rxmeta */
rxmeta = kmalloc(sizeof(p80211_rxmeta_t), GFP_ATOMIC);
- if ( rxmeta == NULL ) {
- WLAN_LOG_ERROR("%s: Failed to allocate rxmeta.\n",
- wlandev->name);
+ if (rxmeta == NULL) {
+ printk(KERN_ERR "%s: Failed to allocate rxmeta.\n",
+ wlandev->name);
result = 1;
goto exit;
}
@@ -644,11 +618,10 @@ p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb)
/* Overlay a frmmeta_t onto skb->cb */
memset(skb->cb, 0, sizeof(p80211_frmmeta_t));
- frmmeta = (p80211_frmmeta_t*)(skb->cb);
+ frmmeta = (p80211_frmmeta_t *) (skb->cb);
frmmeta->magic = P80211_FRMMETA_MAGIC;
frmmeta->rx = rxmeta;
exit:
- DBFEXIT;
return result;
}
@@ -668,19 +641,15 @@ exit:
* Call context:
* May be called in interrupt or non-interrupt context
----------------------------------------------------------------*/
-void
-p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
+void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb)
{
- p80211_frmmeta_t *meta;
- DBFENTER;
+ p80211_frmmeta_t *meta;
+
meta = P80211SKB_FRMMETA(skb);
- if ( meta && meta->rx) {
+ if (meta && meta->rx)
p80211skb_rxmeta_detach(skb);
- } else {
- WLAN_LOG_ERROR("Freeing an skb (%p) w/ no frmmeta.\n", skb);
- }
-
+ else
+ printk(KERN_ERR "Freeing an skb (%p) w/ no frmmeta.\n", skb);
dev_kfree_skb(skb);
- DBFEXIT;
return;
}
diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h
index 538e9bd1490..6fe163be24f 100644
--- a/drivers/staging/wlan-ng/p80211conv.h
+++ b/drivers/staging/wlan-ng/p80211conv.h
@@ -53,134 +53,109 @@
#ifndef _LINUX_P80211CONV_H
#define _LINUX_P80211CONV_H
-/*================================================================*/
-/* Constants */
-
#define WLAN_ETHADDR_LEN 6
#define WLAN_IEEE_OUI_LEN 3
#define WLAN_ETHCONV_ENCAP 1
-#define WLAN_ETHCONV_RFC1042 2
#define WLAN_ETHCONV_8021h 3
-#define WLAN_MIN_ETHFRM_LEN 60
-#define WLAN_MAX_ETHFRM_LEN 1514
#define WLAN_ETHHDR_LEN 14
#define P80211CAPTURE_VERSION 0x80211001
-/*================================================================*/
-/* Macros */
-
#define P80211_FRMMETA_MAGIC 0x802110
#define P80211SKB_FRMMETA(s) \
- (((((p80211_frmmeta_t*)((s)->cb))->magic)==P80211_FRMMETA_MAGIC) ? \
- ((p80211_frmmeta_t*)((s)->cb)) : \
+ (((((p80211_frmmeta_t *)((s)->cb))->magic) == P80211_FRMMETA_MAGIC) ? \
+ ((p80211_frmmeta_t *)((s)->cb)) : \
(NULL))
#define P80211SKB_RXMETA(s) \
- (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t*)(NULL)))
+ (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((p80211_rxmeta_t *)(NULL)))
-typedef struct p80211_rxmeta
-{
- struct wlandevice *wlandev;
+typedef struct p80211_rxmeta {
+ struct wlandevice *wlandev;
- u64 mactime; /* Hi-rez MAC-supplied time value */
- u64 hosttime; /* Best-rez host supplied time value */
+ u64 mactime; /* Hi-rez MAC-supplied time value */
+ u64 hosttime; /* Best-rez host supplied time value */
- unsigned int rxrate; /* Receive data rate in 100kbps */
- unsigned int priority; /* 0-15, 0=contention, 6=CF */
- int signal; /* An SSI, see p80211netdev.h */
- int noise; /* An SSI, see p80211netdev.h */
- unsigned int channel; /* Receive channel (mostly for snifs) */
- unsigned int preamble; /* P80211ENUM_preambletype_* */
- unsigned int encoding; /* P80211ENUM_encoding_* */
+ unsigned int rxrate; /* Receive data rate in 100kbps */
+ unsigned int priority; /* 0-15, 0=contention, 6=CF */
+ int signal; /* An SSI, see p80211netdev.h */
+ int noise; /* An SSI, see p80211netdev.h */
+ unsigned int channel; /* Receive channel (mostly for snifs) */
+ unsigned int preamble; /* P80211ENUM_preambletype_* */
+ unsigned int encoding; /* P80211ENUM_encoding_* */
} p80211_rxmeta_t;
-typedef struct p80211_frmmeta
-{
- unsigned int magic;
- p80211_rxmeta_t *rx;
+typedef struct p80211_frmmeta {
+ unsigned int magic;
+ p80211_rxmeta_t *rx;
} p80211_frmmeta_t;
void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb);
int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb);
void p80211skb_rxmeta_detach(struct sk_buff *skb);
-/*================================================================*/
-/* Types */
-
/*
* Frame capture header. (See doc/capturefrm.txt)
*/
-typedef struct p80211_caphdr
-{
- u32 version;
- u32 length;
- u64 mactime;
- u64 hosttime;
- u32 phytype;
- u32 channel;
- u32 datarate;
- u32 antenna;
- u32 priority;
- u32 ssi_type;
- s32 ssi_signal;
- s32 ssi_noise;
- u32 preamble;
- u32 encoding;
+typedef struct p80211_caphdr {
+ u32 version;
+ u32 length;
+ u64 mactime;
+ u64 hosttime;
+ u32 phytype;
+ u32 channel;
+ u32 datarate;
+ u32 antenna;
+ u32 priority;
+ u32 ssi_type;
+ s32 ssi_signal;
+ s32 ssi_noise;
+ u32 preamble;
+ u32 encoding;
} p80211_caphdr_t;
/* buffer free method pointer type */
-typedef void (* freebuf_method_t)(void *buf, int size);
+typedef void (*freebuf_method_t) (void *buf, int size);
typedef struct p80211_metawep {
- void *data;
+ void *data;
u8 iv[4];
u8 icv[4];
} p80211_metawep_t;
/* local ether header type */
-typedef struct wlan_ethhdr
-{
- u8 daddr[WLAN_ETHADDR_LEN];
- u8 saddr[WLAN_ETHADDR_LEN];
- u16 type;
-} __WLAN_ATTRIB_PACK__ wlan_ethhdr_t;
+typedef struct wlan_ethhdr {
+ u8 daddr[WLAN_ETHADDR_LEN];
+ u8 saddr[WLAN_ETHADDR_LEN];
+ u16 type;
+} __attribute__ ((packed)) wlan_ethhdr_t;
/* local llc header type */
-typedef struct wlan_llc
-{
- u8 dsap;
- u8 ssap;
- u8 ctl;
-} __WLAN_ATTRIB_PACK__ wlan_llc_t;
+typedef struct wlan_llc {
+ u8 dsap;
+ u8 ssap;
+ u8 ctl;
+} __attribute__ ((packed)) wlan_llc_t;
/* local snap header type */
-typedef struct wlan_snap
-{
- u8 oui[WLAN_IEEE_OUI_LEN];
- u16 type;
-} __WLAN_ATTRIB_PACK__ wlan_snap_t;
+typedef struct wlan_snap {
+ u8 oui[WLAN_IEEE_OUI_LEN];
+ u16 type;
+} __attribute__ ((packed)) wlan_snap_t;
/* Circular include trick */
struct wlandevice;
-/*================================================================*/
-/* Externs */
-
-/*================================================================*/
-/*Function Declarations */
-
-int skb_p80211_to_ether( struct wlandevice *wlandev, u32 ethconv,
- struct sk_buff *skb);
-int skb_ether_to_p80211( struct wlandevice *wlandev, u32 ethconv,
- struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
- p80211_metawep_t *p80211_wep );
+int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv,
+ struct sk_buff *skb);
+int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv,
+ struct sk_buff *skb, p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep);
int p80211_stt_findproto(u16 proto);
-int p80211_stt_addproto(u16 proto);
#endif
diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h
index 72f12aff390..ded47751769 100644
--- a/drivers/staging/wlan-ng/p80211hdr.h
+++ b/drivers/staging/wlan-ng/p80211hdr.h
@@ -63,43 +63,23 @@
/*================================================================*/
/* System Includes */
+#include <linux/if_ether.h>
+
/*================================================================*/
/* Project Includes */
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
/*================================================================*/
/* Constants */
/*--- Sizes -----------------------------------------------*/
-#define WLAN_ADDR_LEN 6
#define WLAN_CRC_LEN 4
#define WLAN_BSSID_LEN 6
-#define WLAN_BSS_TS_LEN 8
#define WLAN_HDR_A3_LEN 24
#define WLAN_HDR_A4_LEN 30
#define WLAN_SSID_MAXLEN 32
#define WLAN_DATA_MAXLEN 2312
-#define WLAN_A3FR_MAXLEN (WLAN_HDR_A3_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
-#define WLAN_A4FR_MAXLEN (WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)
-#define WLAN_BEACON_FR_MAXLEN (WLAN_HDR_A3_LEN + 334)
-#define WLAN_ATIM_FR_MAXLEN (WLAN_HDR_A3_LEN + 0)
-#define WLAN_DISASSOC_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
-#define WLAN_ASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 48)
-#define WLAN_ASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
-#define WLAN_REASSOCREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 54)
-#define WLAN_REASSOCRESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 16)
-#define WLAN_PROBEREQ_FR_MAXLEN (WLAN_HDR_A3_LEN + 44)
-#define WLAN_PROBERESP_FR_MAXLEN (WLAN_HDR_A3_LEN + 78)
-#define WLAN_AUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 261)
-#define WLAN_DEAUTHEN_FR_MAXLEN (WLAN_HDR_A3_LEN + 2)
-#define WLAN_WEP_NKEYS 4
-#define WLAN_WEP_MAXKEYLEN 13
-#define WLAN_CHALLENGE_IE_LEN 130
-#define WLAN_CHALLENGE_LEN 128
#define WLAN_WEP_IV_LEN 4
#define WLAN_WEP_ICV_LEN 4
@@ -143,7 +123,6 @@
#define WLAN_FSTYPE_CFPOLL 0x06
#define WLAN_FSTYPE_CFACK_CFPOLL 0x07
-
/*================================================================*/
/* Macros */
@@ -166,97 +145,51 @@
/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */
/*------------------------------------------------------------*/
-#define WLAN_GET_FC_PVER(n) (((u16)(n)) & (BIT0 | BIT1))
-#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & (BIT2 | BIT3)) >> 2)
-#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & (BIT4|BIT5|BIT6|BIT7)) >> 4)
-#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT8)) >> 8)
-#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT9)) >> 9)
-#define WLAN_GET_FC_MOREFRAG(n) ((((u16)(n)) & (BIT10)) >> 10)
-#define WLAN_GET_FC_RETRY(n) ((((u16)(n)) & (BIT11)) >> 11)
-#define WLAN_GET_FC_PWRMGT(n) ((((u16)(n)) & (BIT12)) >> 12)
-#define WLAN_GET_FC_MOREDATA(n) ((((u16)(n)) & (BIT13)) >> 13)
-#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT14)) >> 14)
-#define WLAN_GET_FC_ORDER(n) ((((u16)(n)) & (BIT15)) >> 15)
+#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & (BIT(2) | BIT(3))) >> 2)
+#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & (BIT(4)|BIT(5)|BIT(6)|BIT(7))) >> 4)
+#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT(8))) >> 8)
+#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT(9))) >> 9)
+#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT(14))) >> 14)
-#define WLAN_SET_FC_PVER(n) ((u16)(n))
#define WLAN_SET_FC_FTYPE(n) (((u16)(n)) << 2)
#define WLAN_SET_FC_FSTYPE(n) (((u16)(n)) << 4)
#define WLAN_SET_FC_TODS(n) (((u16)(n)) << 8)
#define WLAN_SET_FC_FROMDS(n) (((u16)(n)) << 9)
-#define WLAN_SET_FC_MOREFRAG(n) (((u16)(n)) << 10)
-#define WLAN_SET_FC_RETRY(n) (((u16)(n)) << 11)
-#define WLAN_SET_FC_PWRMGT(n) (((u16)(n)) << 12)
-#define WLAN_SET_FC_MOREDATA(n) (((u16)(n)) << 13)
#define WLAN_SET_FC_ISWEP(n) (((u16)(n)) << 14)
-#define WLAN_SET_FC_ORDER(n) (((u16)(n)) << 15)
-
-/*--- Duration Macros ----------------------------------------*/
-/* Macros to get/set the bitfields of the Duration Field */
-/* - the duration value is only valid when bit15 is zero */
-/* - the firmware handles these values, so I'm not going */
-/* these macros right now. */
-/*------------------------------------------------------------*/
-/*--- Sequence Control Macros -------------------------------*/
-/* Macros to get/set the bitfields of the Sequence Control */
-/* Field. */
-/*------------------------------------------------------------*/
-#define WLAN_GET_SEQ_FRGNUM(n) (((u16)(n)) & (BIT0|BIT1|BIT2|BIT3))
-#define WLAN_GET_SEQ_SEQNUM(n) ((((u16)(n)) & (~(BIT0|BIT1|BIT2|BIT3))) >> 4)
-
-/*--- Data ptr macro -----------------------------------------*/
-/* Creates a u8* to the data portion of a frame */
-/* Assumes you're passing in a ptr to the beginning of the hdr*/
-/*------------------------------------------------------------*/
-#define WLAN_HDR_A3_DATAP(p) (((u8*)(p)) + WLAN_HDR_A3_LEN)
-#define WLAN_HDR_A4_DATAP(p) (((u8*)(p)) + WLAN_HDR_A4_LEN)
-
-#define DOT11_RATE5_ISBASIC_GET(r) (((u8)(r)) & BIT7)
+#define DOT11_RATE5_ISBASIC_GET(r) (((u8)(r)) & BIT(7))
/*================================================================*/
/* Types */
-/* BSS Timestamp */
-typedef u8 wlan_bss_ts_t[WLAN_BSS_TS_LEN];
-
/* Generic 802.11 Header types */
-typedef struct p80211_hdr_a3
-{
- u16 fc;
- u16 dur;
- u8 a1[WLAN_ADDR_LEN];
- u8 a2[WLAN_ADDR_LEN];
- u8 a3[WLAN_ADDR_LEN];
- u16 seq;
-} __WLAN_ATTRIB_PACK__ p80211_hdr_a3_t;
-
-typedef struct p80211_hdr_a4
-{
- u16 fc;
- u16 dur;
- u8 a1[WLAN_ADDR_LEN];
- u8 a2[WLAN_ADDR_LEN];
- u8 a3[WLAN_ADDR_LEN];
- u16 seq;
- u8 a4[WLAN_ADDR_LEN];
-} __WLAN_ATTRIB_PACK__ p80211_hdr_a4_t;
-
-typedef union p80211_hdr
-{
- p80211_hdr_a3_t a3;
- p80211_hdr_a4_t a4;
-} __WLAN_ATTRIB_PACK__ p80211_hdr_t;
-
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/* Frame and header lenght macros */
+typedef struct p80211_hdr_a3 {
+ u16 fc;
+ u16 dur;
+ u8 a1[ETH_ALEN];
+ u8 a2[ETH_ALEN];
+ u8 a3[ETH_ALEN];
+ u16 seq;
+} __attribute__ ((packed)) p80211_hdr_a3_t;
+
+typedef struct p80211_hdr_a4 {
+ u16 fc;
+ u16 dur;
+ u8 a1[ETH_ALEN];
+ u8 a2[ETH_ALEN];
+ u8 a3[ETH_ALEN];
+ u16 seq;
+ u8 a4[ETH_ALEN];
+} __attribute__ ((packed)) p80211_hdr_a4_t;
+
+typedef union p80211_hdr {
+ p80211_hdr_a3_t a3;
+ p80211_hdr_a4_t a4;
+} __attribute__ ((packed)) p80211_hdr_t;
+
+
+/* Frame and header length macros */
#define WLAN_CTL_FRAMELEN(fstype) (\
(fstype) == WLAN_FSTYPE_BLOCKACKREQ ? 24 : \
@@ -271,23 +204,22 @@ typedef union p80211_hdr
#define WLAN_FCS_LEN 4
/* ftcl in HOST order */
-inline static u16 p80211_headerlen(u16 fctl)
+static inline u16 p80211_headerlen(u16 fctl)
{
u16 hdrlen = 0;
- switch ( WLAN_GET_FC_FTYPE(fctl) ) {
+ switch (WLAN_GET_FC_FTYPE(fctl)) {
case WLAN_FTYPE_MGMT:
hdrlen = WLAN_HDR_A3_LEN;
break;
case WLAN_FTYPE_DATA:
hdrlen = WLAN_HDR_A3_LEN;
- if ( WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl) ) {
- hdrlen += WLAN_ADDR_LEN;
- }
+ if (WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl))
+ hdrlen += ETH_ALEN;
break;
case WLAN_FTYPE_CTL:
hdrlen = WLAN_CTL_FRAMELEN(WLAN_GET_FC_FSTYPE(fctl)) -
- WLAN_FCS_LEN;
+ WLAN_FCS_LEN;
break;
default:
hdrlen = WLAN_HDR_A3_LEN;
diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h
index ad67b698fa4..64ca7f95262 100644
--- a/drivers/staging/wlan-ng/p80211ioctl.h
+++ b/drivers/staging/wlan-ng/p80211ioctl.h
@@ -60,14 +60,9 @@
* --------------------------------------------------------------------
*/
-
#ifndef _P80211IOCTL_H
#define _P80211IOCTL_H
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */
#define P80211_IFTEST (SIOCDEVPRIVATE + 0)
@@ -79,45 +74,16 @@
#define P80211_IOCTL_MAGIC (0x4a2d464dUL)
/*----------------------------------------------------------------*/
-/* Netlink protocol numbers for the indication interface */
-
-#define P80211_NL_SOCK_IND NETLINK_USERSOCK
-
-/*----------------------------------------------------------------*/
-/* Netlink multicast bits for different types of messages */
-
-#define P80211_NL_MCAST_GRP_MLME BIT0 /* Local station messages */
-#define P80211_NL_MCAST_GRP_SNIFF BIT1 /* Sniffer messages */
-#define P80211_NL_MCAST_GRP_DIST BIT2 /* Distribution system messages */
-
-/*================================================================*/
-/* Macros */
-
-
-/*================================================================*/
-/* Types */
-
-/*----------------------------------------------------------------*/
/* A ptr to the following structure type is passed as the third */
/* argument to the ioctl system call when issuing a request to */
/* the p80211 module. */
-typedef struct p80211ioctl_req
-{
- char name[WLAN_DEVNAMELEN_MAX];
+typedef struct p80211ioctl_req {
+ char name[WLAN_DEVNAMELEN_MAX];
caddr_t data;
- u32 magic;
- u16 len;
- u32 result;
-} __WLAN_ATTRIB_PACK__ p80211ioctl_req_t;
-
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
+ u32 magic;
+ u16 len;
+ u32 result;
+} __attribute__ ((packed)) p80211ioctl_req_t;
#endif /* _P80211IOCTL_H */
diff --git a/drivers/staging/wlan-ng/p80211meta.h b/drivers/staging/wlan-ng/p80211meta.h
index 8b61e5fc292..2f3c9fc3358 100644
--- a/drivers/staging/wlan-ng/p80211meta.h
+++ b/drivers/staging/wlan-ng/p80211meta.h
@@ -58,50 +58,8 @@
#define _P80211META_H
/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
/* Project Includes */
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Macros */
-
-/*----------------------------------------------------------------*/
-/* The following macros are used to ensure consistent naming */
-/* conventions for all the different metadata lists. */
-
-#define MKREQMETANAME(name) p80211meta_ ## req ## _ ## name
-#define MKINDMETANAME(name) p80211meta_ ## ind ## _ ## name
-#define MKMIBMETANAME(name) p80211meta_ ## mib ## _ ## name
-#define MKGRPMETANAME(name) p80211meta_ ## grp ## _ ## name
-
-#define MKREQMETASIZE(name) p80211meta_ ## req ## _ ## name ## _ ## size
-#define MKINDMETASIZE(name) p80211meta_ ## ind ## _ ## name ## _ ## size
-#define MKMIBMETASIZE(name) p80211meta_ ## mib ## _ ## name ## _ ## size
-#define MKGRPMETASIZE(name) p80211meta_ ## grp ## _ ## name ## _ ## size
-
-#define GETMETASIZE(aptr) (**((u32**)(aptr)))
-
-/*----------------------------------------------------------------*/
-/* The following ifdef depends on the following defines: */
-/* P80211_NOINCLUDESTRINGS - if defined, all metadata name fields */
-/* are empty strings */
-
-#ifdef P80211_NOINCLUDESTRINGS
- #define MKITEMNAME(s) ("")
-#else
- #define MKITEMNAME(s) (s)
-#endif
/*================================================================*/
/* Types */
@@ -111,59 +69,29 @@
/* representation of category list metadata, group list metadata, */
/* and data item metadata for both Mib and Messages. */
-typedef struct p80211meta
-{
- char *name; /* data item name */
- u32 did; /* partial did */
- u32 flags; /* set of various flag bits */
- u32 min; /* min value of a BOUNDEDint */
- u32 max; /* max value of a BOUNDEDint */
-
- u32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */
- u32 minlen; /* minlen of a OCTETSTR or DISPLAYSTR */
- p80211enum_t *enumptr; /* ptr to the enum type for ENUMint */
- p80211_totext_t totextptr; /* ptr to totext conversion function */
- p80211_fromtext_t fromtextptr; /* ptr to totext conversion function */
- p80211_valid_t validfunptr; /* ptr to totext conversion function */
+typedef struct p80211meta {
+ char *name; /* data item name */
+ u32 did; /* partial did */
+ u32 flags; /* set of various flag bits */
+ u32 min; /* min value of a BOUNDEDint */
+ u32 max; /* max value of a BOUNDEDint */
+
+ u32 maxlen; /* maxlen of a OCTETSTR or DISPLAYSTR */
+ u32 minlen; /* minlen of a OCTETSTR or DISPLAYSTR */
+ p80211enum_t *enumptr; /* ptr to the enum type for ENUMint */
+ p80211_totext_t totextptr; /* ptr to totext conversion function */
+ p80211_fromtext_t fromtextptr; /* ptr to totext conversion function */
+ p80211_valid_t validfunptr; /* ptr to totext conversion function */
} p80211meta_t;
-typedef struct grplistitem
-{
- char *name;
- p80211meta_t *itemlist;
+typedef struct grplistitem {
+ char *name;
+ p80211meta_t *itemlist;
} grplistitem_t;
-typedef struct catlistitem
-{
- char *name;
- grplistitem_t *grplist;
+typedef struct catlistitem {
+ char *name;
+ grplistitem_t *grplist;
} catlistitem_t;
-/*================================================================*/
-/* Extern Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-u32 p80211_text2did(catlistitem_t *catlist, char *catname, char *grpname, char *itemname);
-u32 p80211_text2catdid(catlistitem_t *list, char *name );
-u32 p80211_text2grpdid(grplistitem_t *list, char *name );
-u32 p80211_text2itemdid(p80211meta_t *list, char *name );
-u32 p80211_isvalid_did( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_catdid( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_grpdid( catlistitem_t *catlist, u32 did );
-u32 p80211_isvalid_itemdid( catlistitem_t *catlist, u32 did );
-catlistitem_t *p80211_did2cat( catlistitem_t *catlist, u32 did );
-grplistitem_t *p80211_did2grp( catlistitem_t *catlist, u32 did );
-p80211meta_t *p80211_did2item( catlistitem_t *catlist, u32 did );
-u32 p80211item_maxdatalen( struct catlistitem *metalist, u32 did );
-u32 p80211_metaname2did(struct catlistitem *metalist, char *itemname);
-u32 p80211item_getoffset( struct catlistitem *metalist, u32 did );
-int p80211item_gettype(p80211meta_t *meta);
-
#endif /* _P80211META_H */
diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h
index ce4fdd547fc..a29d6ae3e77 100644
--- a/drivers/staging/wlan-ng/p80211metadef.h
+++ b/drivers/staging/wlan-ng/p80211metadef.h
@@ -47,20 +47,9 @@
#ifndef _P80211MKMETADEF_H
#define _P80211MKMETADEF_H
-
-#define DIDmsg_cat_dot11req \
- P80211DID_MKSECTION(1)
#define DIDmsg_dot11req_mibget \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(1))
-#define DIDmsg_dot11req_mibget_mibattribute \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_mibget_resultcode \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11req_mibset \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(2))
@@ -75,579 +64,48 @@
#define DIDmsg_dot11req_scan \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(4))
-#define DIDmsg_dot11req_scan_bsstype \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_scan_bssid \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_scan_ssid \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11req_scan_scantype \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_dot11req_scan_probedelay \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_dot11req_scan_channellist \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_dot11req_scan_minchanneltime \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_dot11req_scan_maxchanneltime \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(8) | 0x00000000)
-#define DIDmsg_dot11req_scan_resultcode \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(9) | 0x00000000)
-#define DIDmsg_dot11req_scan_numbss \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(10) | 0x00000000)
-#define DIDmsg_dot11req_scan_append \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(11) | 0x00000000)
#define DIDmsg_dot11req_scan_results \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(5))
-#define DIDmsg_dot11req_scan_results_bssindex \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_resultcode \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_signal \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_noise \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_bssid \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_ssid \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_bsstype \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_beaconperiod \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(8) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_dtimperiod \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(9) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_timestamp \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(10) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_localtime \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(11) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhdwelltime \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(12) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhhopset \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(13) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhhoppattern \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(14) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_fhhopindex \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(15) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_dschannel \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(16) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpcount \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(17) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpperiod \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(18) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpmaxduration \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(19) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpdurremaining \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(20) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_ibssatimwindow \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(21) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpollable \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(22) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_cfpollreq \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(23) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_privacy \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(24) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate1 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(25) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate2 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(26) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate3 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(27) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate4 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(28) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate5 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(29) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate6 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(30) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate7 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(31) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_basicrate8 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(32) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate1 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(33) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate2 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(34) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate3 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(35) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate4 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(36) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate5 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(37) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate6 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(38) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate7 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(39) | 0x00000000)
-#define DIDmsg_dot11req_scan_results_supprate8 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(40) | 0x00000000)
#define DIDmsg_dot11req_start \
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(13))
-#define DIDmsg_dot11req_start_ssid \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11req_start_bsstype \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11req_start_beaconperiod \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11req_start_dtimperiod \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpperiod \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpmaxduration \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_dot11req_start_fhdwelltime \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_dot11req_start_fhhopset \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(8) | 0x00000000)
-#define DIDmsg_dot11req_start_fhhoppattern \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(9) | 0x00000000)
-#define DIDmsg_dot11req_start_dschannel \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(10) | 0x00000000)
-#define DIDmsg_dot11req_start_ibssatimwindow \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(11) | 0x00000000)
-#define DIDmsg_dot11req_start_probedelay \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(12) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpollable \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(13) | 0x00000000)
-#define DIDmsg_dot11req_start_cfpollreq \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(14) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate1 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(15) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate2 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(16) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate3 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(17) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate4 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(18) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate5 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(19) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate6 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(20) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate7 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(21) | 0x00000000)
-#define DIDmsg_dot11req_start_basicrate8 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(22) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate1 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(23) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate2 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(24) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate3 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(25) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate4 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(26) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate5 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(27) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate6 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(28) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate7 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(29) | 0x00000000)
-#define DIDmsg_dot11req_start_operationalrate8 \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(30) | 0x00000000)
-#define DIDmsg_dot11req_start_resultcode \
- (P80211DID_MKSECTION(1) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(31) | 0x00000000)
-#define DIDmsg_cat_dot11ind \
- P80211DID_MKSECTION(2)
#define DIDmsg_dot11ind_authenticate \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1))
-#define DIDmsg_dot11ind_authenticate_peerstaaddress \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_authenticate_authenticationtype \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11ind_deauthenticate \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(2))
-#define DIDmsg_dot11ind_deauthenticate_peerstaaddress \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_deauthenticate_reasoncode \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_dot11ind_associate \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(3))
-#define DIDmsg_dot11ind_associate_peerstaaddress \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(3) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_associate_aid \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(3) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11ind_reassociate \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(4))
-#define DIDmsg_dot11ind_reassociate_peerstaaddress \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_reassociate_aid \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_dot11ind_reassociate_oldapaddress \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_dot11ind_disassociate \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(5))
-#define DIDmsg_dot11ind_disassociate_peerstaaddress \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_dot11ind_disassociate_reasoncode \
- (P80211DID_MKSECTION(2) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_cat_lnxreq \
- P80211DID_MKSECTION(3)
#define DIDmsg_lnxreq_ifstate \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(1))
-#define DIDmsg_lnxreq_ifstate_ifstate \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_ifstate_resultcode \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(1) | \
- P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_lnxreq_wlansniff \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(2))
-#define DIDmsg_lnxreq_wlansniff_enable \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_channel \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_prismheader \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_wlanheader \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_keepwepflags \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(5) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_stripfcs \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(6) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_packet_trunc \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(7) | 0x00000000)
-#define DIDmsg_lnxreq_wlansniff_resultcode \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(8) | 0x00000000)
#define DIDmsg_lnxreq_hostwep \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(3))
-#define DIDmsg_lnxreq_hostwep_resultcode \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(3) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_hostwep_decrypt \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(3) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_hostwep_encrypt \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(3) | \
- P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_lnxreq_commsquality \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(4))
-#define DIDmsg_lnxreq_commsquality_resultcode \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_dbm \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_link \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_level \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(4) | 0x00000000)
-#define DIDmsg_lnxreq_commsquality_noise \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(4) | \
- P80211DID_MKITEM(5) | 0x00000000)
#define DIDmsg_lnxreq_autojoin \
(P80211DID_MKSECTION(3) | \
P80211DID_MKGROUP(5))
-#define DIDmsg_lnxreq_autojoin_ssid \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_lnxreq_autojoin_authtype \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_lnxreq_autojoin_resultcode \
- (P80211DID_MKSECTION(3) | \
- P80211DID_MKGROUP(5) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_cat_p2req \
- P80211DID_MKSECTION(5)
#define DIDmsg_p2req_readpda \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(2))
-#define DIDmsg_p2req_readpda_pda \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_readpda_resultcode \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(2) | \
- P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_ramdl_state \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(11))
-#define DIDmsg_p2req_ramdl_state_enable \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(11) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_ramdl_state_exeaddr \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(11) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_ramdl_state_resultcode \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(11) | \
- P80211DID_MKITEM(3) | 0x00000000)
#define DIDmsg_p2req_ramdl_write \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(12))
-#define DIDmsg_p2req_ramdl_write_addr \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(12) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_len \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(12) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_data \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(12) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_p2req_ramdl_write_resultcode \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(12) | \
- P80211DID_MKITEM(4) | 0x00000000)
#define DIDmsg_p2req_flashdl_state \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(13))
-#define DIDmsg_p2req_flashdl_state_enable \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_flashdl_state_resultcode \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(13) | \
- P80211DID_MKITEM(2) | 0x00000000)
#define DIDmsg_p2req_flashdl_write \
(P80211DID_MKSECTION(5) | \
P80211DID_MKGROUP(14))
-#define DIDmsg_p2req_flashdl_write_addr \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(14) | \
- P80211DID_MKITEM(1) | 0x00000000)
-#define DIDmsg_p2req_flashdl_write_len \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(14) | \
- P80211DID_MKITEM(2) | 0x00000000)
-#define DIDmsg_p2req_flashdl_write_data \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(14) | \
- P80211DID_MKITEM(3) | 0x00000000)
-#define DIDmsg_p2req_flashdl_write_resultcode \
- (P80211DID_MKSECTION(5) | \
- P80211DID_MKGROUP(14) | \
- P80211DID_MKITEM(4) | 0x00000000)
#define DIDmib_cat_dot11smt \
P80211DID_MKSECTION(1)
#define DIDmib_dot11smt_dot11WEPDefaultKeysTable \
@@ -684,8 +142,6 @@
(P80211DID_MKSECTION(1) | \
P80211DID_MKGROUP(6) | \
P80211DID_MKITEM(4) | 0x18000000)
-#define DIDmib_cat_dot11mac \
- P80211DID_MKSECTION(2)
#define DIDmib_dot11mac_dot11OperationTable \
(P80211DID_MKSECTION(2) | \
P80211DID_MKGROUP(1))
diff --git a/drivers/staging/wlan-ng/p80211metamib.h b/drivers/staging/wlan-ng/p80211metamib.h
deleted file mode 100644
index 9cd72ede441..00000000000
--- a/drivers/staging/wlan-ng/p80211metamib.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* p80211metamib.h
-*
-* Macros, const, types, and funcs for p80211 mib metadata
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 (the "License"); you may not use this file
-* except in compliance with the License. You may obtain a copy of
-* the License at http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS
-* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-* implied. See the License for the specific language governing
-* rights and limitations under the License.
-*
-* Alternatively, the contents of this file may be used under the
-* terms of the GNU Public License version 2 (the "GPL"), in which
-* case the provisions of the GPL are applicable instead of the
-* above. If you wish to allow the use of your version of this file
-* only under the terms of the GPL and not to allow others to use
-* your version of this file under the MPL, indicate your decision
-* by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL. If you do not delete
-* the provisions above, a recipient may use your version of this
-* file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*
-* This file declares some of the constants and types used in various
-* parts of the linux-wlan system.
-*
-* Notes:
-* - Constant values are always in HOST byte order.
-*
-* All functions and statics declared here are implemented in p80211types.c
-* --------------------------------------------------------------------
-*/
-
-#ifndef _P80211METAMIB_H
-#define _P80211METAMIB_H
-
-/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
-/* Project Includes */
-
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Macros */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Types */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Extern Declarations */
-
-/*----------------------------------------------------------------*/
-/* The following is the external declaration for the mib */
-/* category metadata list */
-
-extern catlistitem_t mib_catlist[];
-extern u32 mib_catlist_size;
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-#endif /* _P80211METAMIB_H */
diff --git a/drivers/staging/wlan-ng/p80211metamsg.h b/drivers/staging/wlan-ng/p80211metamsg.h
deleted file mode 100644
index 6e659eae8af..00000000000
--- a/drivers/staging/wlan-ng/p80211metamsg.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/* p80211metamsg.h
-*
-* Macros, const, types, and funcs for p80211 msg metadata
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 (the "License"); you may not use this file
-* except in compliance with the License. You may obtain a copy of
-* the License at http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS
-* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-* implied. See the License for the specific language governing
-* rights and limitations under the License.
-*
-* Alternatively, the contents of this file may be used under the
-* terms of the GNU Public License version 2 (the "GPL"), in which
-* case the provisions of the GPL are applicable instead of the
-* above. If you wish to allow the use of your version of this file
-* only under the terms of the GPL and not to allow others to use
-* your version of this file under the MPL, indicate your decision
-* by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL. If you do not delete
-* the provisions above, a recipient may use your version of this
-* file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*
-* This file declares some of the constants and types used in various
-* parts of the linux-wlan system.
-*
-* Notes:
-* - Constant values are always in HOST byte order.
-*
-* All functions and statics declared here are implemented in p80211types.c
-* --------------------------------------------------------------------
-*/
-
-#ifndef _P80211METAMSG_H
-#define _P80211METAMSG_H
-
-/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
-/* Project Includes */
-
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Macros */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Types */
-
-/*----------------------------------------------------------------*/
-/* */
-
-/*================================================================*/
-/* Extern Declarations */
-
-/*----------------------------------------------------------------*/
-/* The following is the external declaration for the message */
-/* category metadata list */
-
-extern catlistitem_t msg_catlist[];
-extern u32 msg_catlist_size;
-
-
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* */
-
-#endif /* _P80211METAMSG_H */
diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h
index d2258b0e89c..db12713eeaa 100644
--- a/drivers/staging/wlan-ng/p80211metastruct.h
+++ b/drivers/staging/wlan-ng/p80211metastruct.h
@@ -47,239 +47,223 @@
#ifndef _P80211MKMETASTRUCT_H
#define _P80211MKMETASTRUCT_H
+typedef struct p80211msg_dot11req_mibget {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_unk392_t mibattribute;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_mibget_t;
-typedef struct p80211msg_dot11req_mibget
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_unk392_t mibattribute ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibget_t;
+typedef struct p80211msg_dot11req_mibset {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_unk392_t mibattribute;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_mibset_t;
-typedef struct p80211msg_dot11req_mibset
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_unk392_t mibattribute ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_mibset_t;
+typedef struct p80211msg_dot11req_scan {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t bsstype;
+ p80211item_pstr6_t bssid;
+ u8 pad_0C[1];
+ p80211item_pstr32_t ssid;
+ u8 pad_1D[3];
+ p80211item_uint32_t scantype;
+ p80211item_uint32_t probedelay;
+ p80211item_pstr14_t channellist;
+ u8 pad_2C[1];
+ p80211item_uint32_t minchanneltime;
+ p80211item_uint32_t maxchanneltime;
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t numbss;
+ p80211item_uint32_t append;
+} __attribute__ ((packed)) p80211msg_dot11req_scan_t;
-typedef struct p80211msg_dot11req_scan
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t bsstype ;
- p80211item_pstr6_t bssid ;
- u8 pad_0C[1] ;
- p80211item_pstr32_t ssid ;
- u8 pad_1D[3] ;
- p80211item_uint32_t scantype ;
- p80211item_uint32_t probedelay ;
- p80211item_pstr14_t channellist ;
- u8 pad_2C[1] ;
- p80211item_uint32_t minchanneltime ;
- p80211item_uint32_t maxchanneltime ;
- p80211item_uint32_t resultcode ;
- p80211item_uint32_t numbss ;
- p80211item_uint32_t append ;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_t;
+typedef struct p80211msg_dot11req_scan_results {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t bssindex;
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t signal;
+ p80211item_uint32_t noise;
+ p80211item_pstr6_t bssid;
+ u8 pad_3C[1];
+ p80211item_pstr32_t ssid;
+ u8 pad_4D[3];
+ p80211item_uint32_t bsstype;
+ p80211item_uint32_t beaconperiod;
+ p80211item_uint32_t dtimperiod;
+ p80211item_uint32_t timestamp;
+ p80211item_uint32_t localtime;
+ p80211item_uint32_t fhdwelltime;
+ p80211item_uint32_t fhhopset;
+ p80211item_uint32_t fhhoppattern;
+ p80211item_uint32_t fhhopindex;
+ p80211item_uint32_t dschannel;
+ p80211item_uint32_t cfpcount;
+ p80211item_uint32_t cfpperiod;
+ p80211item_uint32_t cfpmaxduration;
+ p80211item_uint32_t cfpdurremaining;
+ p80211item_uint32_t ibssatimwindow;
+ p80211item_uint32_t cfpollable;
+ p80211item_uint32_t cfpollreq;
+ p80211item_uint32_t privacy;
+ p80211item_uint32_t basicrate1;
+ p80211item_uint32_t basicrate2;
+ p80211item_uint32_t basicrate3;
+ p80211item_uint32_t basicrate4;
+ p80211item_uint32_t basicrate5;
+ p80211item_uint32_t basicrate6;
+ p80211item_uint32_t basicrate7;
+ p80211item_uint32_t basicrate8;
+ p80211item_uint32_t supprate1;
+ p80211item_uint32_t supprate2;
+ p80211item_uint32_t supprate3;
+ p80211item_uint32_t supprate4;
+ p80211item_uint32_t supprate5;
+ p80211item_uint32_t supprate6;
+ p80211item_uint32_t supprate7;
+ p80211item_uint32_t supprate8;
+} __attribute__ ((packed)) p80211msg_dot11req_scan_results_t;
-typedef struct p80211msg_dot11req_scan_results
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t bssindex ;
- p80211item_uint32_t resultcode ;
- p80211item_uint32_t signal ;
- p80211item_uint32_t noise ;
- p80211item_pstr6_t bssid ;
- u8 pad_3C[1] ;
- p80211item_pstr32_t ssid ;
- u8 pad_4D[3] ;
- p80211item_uint32_t bsstype ;
- p80211item_uint32_t beaconperiod ;
- p80211item_uint32_t dtimperiod ;
- p80211item_uint32_t timestamp ;
- p80211item_uint32_t localtime ;
- p80211item_uint32_t fhdwelltime ;
- p80211item_uint32_t fhhopset ;
- p80211item_uint32_t fhhoppattern ;
- p80211item_uint32_t fhhopindex ;
- p80211item_uint32_t dschannel ;
- p80211item_uint32_t cfpcount ;
- p80211item_uint32_t cfpperiod ;
- p80211item_uint32_t cfpmaxduration ;
- p80211item_uint32_t cfpdurremaining ;
- p80211item_uint32_t ibssatimwindow ;
- p80211item_uint32_t cfpollable ;
- p80211item_uint32_t cfpollreq ;
- p80211item_uint32_t privacy ;
- p80211item_uint32_t basicrate1 ;
- p80211item_uint32_t basicrate2 ;
- p80211item_uint32_t basicrate3 ;
- p80211item_uint32_t basicrate4 ;
- p80211item_uint32_t basicrate5 ;
- p80211item_uint32_t basicrate6 ;
- p80211item_uint32_t basicrate7 ;
- p80211item_uint32_t basicrate8 ;
- p80211item_uint32_t supprate1 ;
- p80211item_uint32_t supprate2 ;
- p80211item_uint32_t supprate3 ;
- p80211item_uint32_t supprate4 ;
- p80211item_uint32_t supprate5 ;
- p80211item_uint32_t supprate6 ;
- p80211item_uint32_t supprate7 ;
- p80211item_uint32_t supprate8 ;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_scan_results_t;
+typedef struct p80211msg_dot11req_start {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_pstr32_t ssid;
+ u8 pad_12D[3];
+ p80211item_uint32_t bsstype;
+ p80211item_uint32_t beaconperiod;
+ p80211item_uint32_t dtimperiod;
+ p80211item_uint32_t cfpperiod;
+ p80211item_uint32_t cfpmaxduration;
+ p80211item_uint32_t fhdwelltime;
+ p80211item_uint32_t fhhopset;
+ p80211item_uint32_t fhhoppattern;
+ p80211item_uint32_t dschannel;
+ p80211item_uint32_t ibssatimwindow;
+ p80211item_uint32_t probedelay;
+ p80211item_uint32_t cfpollable;
+ p80211item_uint32_t cfpollreq;
+ p80211item_uint32_t basicrate1;
+ p80211item_uint32_t basicrate2;
+ p80211item_uint32_t basicrate3;
+ p80211item_uint32_t basicrate4;
+ p80211item_uint32_t basicrate5;
+ p80211item_uint32_t basicrate6;
+ p80211item_uint32_t basicrate7;
+ p80211item_uint32_t basicrate8;
+ p80211item_uint32_t operationalrate1;
+ p80211item_uint32_t operationalrate2;
+ p80211item_uint32_t operationalrate3;
+ p80211item_uint32_t operationalrate4;
+ p80211item_uint32_t operationalrate5;
+ p80211item_uint32_t operationalrate6;
+ p80211item_uint32_t operationalrate7;
+ p80211item_uint32_t operationalrate8;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_dot11req_start_t;
-typedef struct p80211msg_dot11req_start
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_pstr32_t ssid ;
- u8 pad_12D[3] ;
- p80211item_uint32_t bsstype ;
- p80211item_uint32_t beaconperiod ;
- p80211item_uint32_t dtimperiod ;
- p80211item_uint32_t cfpperiod ;
- p80211item_uint32_t cfpmaxduration ;
- p80211item_uint32_t fhdwelltime ;
- p80211item_uint32_t fhhopset ;
- p80211item_uint32_t fhhoppattern ;
- p80211item_uint32_t dschannel ;
- p80211item_uint32_t ibssatimwindow ;
- p80211item_uint32_t probedelay ;
- p80211item_uint32_t cfpollable ;
- p80211item_uint32_t cfpollreq ;
- p80211item_uint32_t basicrate1 ;
- p80211item_uint32_t basicrate2 ;
- p80211item_uint32_t basicrate3 ;
- p80211item_uint32_t basicrate4 ;
- p80211item_uint32_t basicrate5 ;
- p80211item_uint32_t basicrate6 ;
- p80211item_uint32_t basicrate7 ;
- p80211item_uint32_t basicrate8 ;
- p80211item_uint32_t operationalrate1 ;
- p80211item_uint32_t operationalrate2 ;
- p80211item_uint32_t operationalrate3 ;
- p80211item_uint32_t operationalrate4 ;
- p80211item_uint32_t operationalrate5 ;
- p80211item_uint32_t operationalrate6 ;
- p80211item_uint32_t operationalrate7 ;
- p80211item_uint32_t operationalrate8 ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_dot11req_start_t;
+typedef struct p80211msg_lnxreq_ifstate {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t ifstate;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_ifstate_t;
-typedef struct p80211msg_lnxreq_ifstate
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t ifstate ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_ifstate_t;
+typedef struct p80211msg_lnxreq_wlansniff {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t enable;
+ p80211item_uint32_t channel;
+ p80211item_uint32_t prismheader;
+ p80211item_uint32_t wlanheader;
+ p80211item_uint32_t keepwepflags;
+ p80211item_uint32_t stripfcs;
+ p80211item_uint32_t packet_trunc;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_wlansniff_t;
-typedef struct p80211msg_lnxreq_wlansniff
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t enable ;
- p80211item_uint32_t channel ;
- p80211item_uint32_t prismheader ;
- p80211item_uint32_t wlanheader ;
- p80211item_uint32_t keepwepflags ;
- p80211item_uint32_t stripfcs ;
- p80211item_uint32_t packet_trunc ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_wlansniff_t;
+typedef struct p80211msg_lnxreq_hostwep {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t decrypt;
+ p80211item_uint32_t encrypt;
+} __attribute__ ((packed)) p80211msg_lnxreq_hostwep_t;
-typedef struct p80211msg_lnxreq_hostwep
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t resultcode ;
- p80211item_uint32_t decrypt ;
- p80211item_uint32_t encrypt ;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_hostwep_t;
+typedef struct p80211msg_lnxreq_commsquality {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t resultcode;
+ p80211item_uint32_t dbm;
+ p80211item_uint32_t link;
+ p80211item_uint32_t level;
+ p80211item_uint32_t noise;
+} __attribute__ ((packed)) p80211msg_lnxreq_commsquality_t;
-typedef struct p80211msg_lnxreq_commsquality
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t resultcode ;
- p80211item_uint32_t dbm ;
- p80211item_uint32_t link ;
- p80211item_uint32_t level ;
- p80211item_uint32_t noise ;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_commsquality_t;
+typedef struct p80211msg_lnxreq_autojoin {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_pstr32_t ssid;
+ u8 pad_19D[3];
+ p80211item_uint32_t authtype;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_lnxreq_autojoin_t;
-typedef struct p80211msg_lnxreq_autojoin
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_pstr32_t ssid ;
- u8 pad_19D[3] ;
- p80211item_uint32_t authtype ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_lnxreq_autojoin_t;
+typedef struct p80211msg_p2req_readpda {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_unk1024_t pda;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_readpda_t;
-typedef struct p80211msg_p2req_readpda
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_unk1024_t pda ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_readpda_t;
+typedef struct p80211msg_p2req_ramdl_state {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t enable;
+ p80211item_uint32_t exeaddr;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_ramdl_state_t;
-typedef struct p80211msg_p2req_ramdl_state
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t enable ;
- p80211item_uint32_t exeaddr ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_state_t;
+typedef struct p80211msg_p2req_ramdl_write {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t addr;
+ p80211item_uint32_t len;
+ p80211item_unk4096_t data;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_ramdl_write_t;
-typedef struct p80211msg_p2req_ramdl_write
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t addr ;
- p80211item_uint32_t len ;
- p80211item_unk4096_t data ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_ramdl_write_t;
+typedef struct p80211msg_p2req_flashdl_state {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t enable;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_flashdl_state_t;
-typedef struct p80211msg_p2req_flashdl_state
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t enable ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_state_t;
-
-typedef struct p80211msg_p2req_flashdl_write
-{
- u32 msgcode ;
- u32 msglen ;
- u8 devname[WLAN_DEVNAMELEN_MAX] ;
- p80211item_uint32_t addr ;
- p80211item_uint32_t len ;
- p80211item_unk4096_t data ;
- p80211item_uint32_t resultcode ;
-} __WLAN_ATTRIB_PACK__ p80211msg_p2req_flashdl_write_t;
+typedef struct p80211msg_p2req_flashdl_write {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+ p80211item_uint32_t addr;
+ p80211item_uint32_t len;
+ p80211item_unk4096_t data;
+ p80211item_uint32_t resultcode;
+} __attribute__ ((packed)) p80211msg_p2req_flashdl_write_t;
#endif
diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h
index 6cc16c3f8b1..6235fe7f235 100644
--- a/drivers/staging/wlan-ng/p80211mgmt.h
+++ b/drivers/staging/wlan-ng/p80211mgmt.h
@@ -101,14 +101,8 @@
#define _P80211MGMT_H
/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
/* Project Includes */
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
#ifndef _P80211HDR_H
#include "p80211hdr.h"
@@ -160,8 +154,6 @@
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20
#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21
-
-
/*-- Auth Algorithm Field ---------------------------*/
#define WLAN_AUTH_ALG_OPENSYSTEM 0
#define WLAN_AUTH_ALG_SHAREDKEY 1
@@ -211,20 +203,16 @@
#define WLAN_DEAUTHEN_OFF_REASON 0
-
-/*================================================================*/
-/* Macros */
-
/*-- Capability Field ---------------------------*/
-#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT0)
-#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT1) >> 1)
-#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT2) >> 2)
-#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT3) >> 3)
-#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT4) >> 4)
+#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT(0))
+#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT(1)) >> 1)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT(2)) >> 2)
+#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT(3)) >> 3)
+#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT(4)) >> 4)
/* p80211b additions */
-#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT5) >> 5)
-#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT6) >> 6)
-#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT7) >> 7)
+#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT(5)) >> 5)
+#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT(6)) >> 6)
+#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT(7)) >> 7)
#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n)
#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1)
@@ -236,143 +224,126 @@
#define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6)
#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7)
-
-/*================================================================*/
-/* Types */
-
/*-- Information Element Types --------------------*/
/* prototype structure, all IEs start with these members */
-typedef struct wlan_ie
-{
- u8 eid;
- u8 len;
-} __WLAN_ATTRIB_PACK__ wlan_ie_t;
+typedef struct wlan_ie {
+ u8 eid;
+ u8 len;
+} __attribute__ ((packed)) wlan_ie_t;
/*-- Service Set Identity (SSID) -----------------*/
-typedef struct wlan_ie_ssid
-{
- u8 eid;
- u8 len;
- u8 ssid[1]; /* may be zero, ptrs may overlap */
-} __WLAN_ATTRIB_PACK__ wlan_ie_ssid_t;
+typedef struct wlan_ie_ssid {
+ u8 eid;
+ u8 len;
+ u8 ssid[1]; /* may be zero, ptrs may overlap */
+} __attribute__ ((packed)) wlan_ie_ssid_t;
/*-- Supported Rates -----------------------------*/
-typedef struct wlan_ie_supp_rates
-{
- u8 eid;
- u8 len;
- u8 rates[1]; /* had better be at LEAST one! */
-} __WLAN_ATTRIB_PACK__ wlan_ie_supp_rates_t;
+typedef struct wlan_ie_supp_rates {
+ u8 eid;
+ u8 len;
+ u8 rates[1]; /* had better be at LEAST one! */
+} __attribute__ ((packed)) wlan_ie_supp_rates_t;
/*-- FH Parameter Set ----------------------------*/
-typedef struct wlan_ie_fh_parms
-{
- u8 eid;
- u8 len;
- u16 dwell;
- u8 hopset;
- u8 hoppattern;
- u8 hopindex;
-} __WLAN_ATTRIB_PACK__ wlan_ie_fh_parms_t;
+typedef struct wlan_ie_fh_parms {
+ u8 eid;
+ u8 len;
+ u16 dwell;
+ u8 hopset;
+ u8 hoppattern;
+ u8 hopindex;
+} __attribute__ ((packed)) wlan_ie_fh_parms_t;
/*-- DS Parameter Set ----------------------------*/
-typedef struct wlan_ie_ds_parms
-{
- u8 eid;
- u8 len;
- u8 curr_ch;
-} __WLAN_ATTRIB_PACK__ wlan_ie_ds_parms_t;
+typedef struct wlan_ie_ds_parms {
+ u8 eid;
+ u8 len;
+ u8 curr_ch;
+} __attribute__ ((packed)) wlan_ie_ds_parms_t;
/*-- CF Parameter Set ----------------------------*/
-typedef struct wlan_ie_cf_parms
-{
- u8 eid;
- u8 len;
- u8 cfp_cnt;
- u8 cfp_period;
- u16 cfp_maxdur;
- u16 cfp_durremaining;
-} __WLAN_ATTRIB_PACK__ wlan_ie_cf_parms_t;
+typedef struct wlan_ie_cf_parms {
+ u8 eid;
+ u8 len;
+ u8 cfp_cnt;
+ u8 cfp_period;
+ u16 cfp_maxdur;
+ u16 cfp_durremaining;
+} __attribute__ ((packed)) wlan_ie_cf_parms_t;
/*-- TIM ------------------------------------------*/
-typedef struct wlan_ie_tim
-{
- u8 eid;
- u8 len;
- u8 dtim_cnt;
- u8 dtim_period;
- u8 bitmap_ctl;
- u8 virt_bm[1];
-} __WLAN_ATTRIB_PACK__ wlan_ie_tim_t;
+typedef struct wlan_ie_tim {
+ u8 eid;
+ u8 len;
+ u8 dtim_cnt;
+ u8 dtim_period;
+ u8 bitmap_ctl;
+ u8 virt_bm[1];
+} __attribute__ ((packed)) wlan_ie_tim_t;
/*-- IBSS Parameter Set ---------------------------*/
-typedef struct wlan_ie_ibss_parms
-{
- u8 eid;
- u8 len;
- u16 atim_win;
-} __WLAN_ATTRIB_PACK__ wlan_ie_ibss_parms_t;
+typedef struct wlan_ie_ibss_parms {
+ u8 eid;
+ u8 len;
+ u16 atim_win;
+} __attribute__ ((packed)) wlan_ie_ibss_parms_t;
/*-- Challenge Text ------------------------------*/
-typedef struct wlan_ie_challenge
-{
- u8 eid;
- u8 len;
- u8 challenge[1];
-} __WLAN_ATTRIB_PACK__ wlan_ie_challenge_t;
+typedef struct wlan_ie_challenge {
+ u8 eid;
+ u8 len;
+ u8 challenge[1];
+} __attribute__ ((packed)) wlan_ie_challenge_t;
/*-------------------------------------------------*/
/* Frame Types */
/* prototype structure, all mgmt frame types will start with these members */
-typedef struct wlan_fr_mgmt
-{
- u16 type;
- u16 len; /* DOES NOT include CRC !!!!*/
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_mgmt {
+ u16 type;
+ u16 len; /* DOES NOT include CRC !!!! */
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
} wlan_fr_mgmt_t;
/*-- Beacon ---------------------------------------*/
-typedef struct wlan_fr_beacon
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_beacon {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u64 *ts;
- u16 *bcn_int;
- u16 *cap_info;
+ u64 *ts;
+ u16 *bcn_int;
+ u16 *cap_info;
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
- wlan_ie_fh_parms_t *fh_parms;
- wlan_ie_ds_parms_t *ds_parms;
- wlan_ie_cf_parms_t *cf_parms;
- wlan_ie_ibss_parms_t *ibss_parms;
- wlan_ie_tim_t *tim;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_fh_parms_t *fh_parms;
+ wlan_ie_ds_parms_t *ds_parms;
+ wlan_ie_cf_parms_t *cf_parms;
+ wlan_ie_ibss_parms_t *ibss_parms;
+ wlan_ie_tim_t *tim;
} wlan_fr_beacon_t;
-
/*-- IBSS ATIM ------------------------------------*/
-typedef struct wlan_fr_ibssatim
-{
- u16 type;
- u16 len;
- u8* buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_ibssatim {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
@@ -382,194 +353,176 @@ typedef struct wlan_fr_ibssatim
} wlan_fr_ibssatim_t;
/*-- Disassociation -------------------------------*/
-typedef struct wlan_fr_disassoc
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_disassoc {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *reason;
+ u16 *reason;
/*-- info elements ----------*/
} wlan_fr_disassoc_t;
/*-- Association Request --------------------------*/
-typedef struct wlan_fr_assocreq
-{
- u16 type;
- u16 len;
- u8* buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_assocreq {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *listen_int;
+ u16 *cap_info;
+ u16 *listen_int;
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_assocreq_t;
/*-- Association Response -------------------------*/
-typedef struct wlan_fr_assocresp
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_assocresp {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *status;
- u16 *aid;
+ u16 *cap_info;
+ u16 *status;
+ u16 *aid;
/*-- info elements ----------*/
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_assocresp_t;
/*-- Reassociation Request ------------------------*/
-typedef struct wlan_fr_reassocreq
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_reassocreq {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *listen_int;
- u8 *curr_ap;
+ u16 *cap_info;
+ u16 *listen_int;
+ u8 *curr_ap;
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_reassocreq_t;
/*-- Reassociation Response -----------------------*/
-typedef struct wlan_fr_reassocresp
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_reassocresp {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *cap_info;
- u16 *status;
- u16 *aid;
+ u16 *cap_info;
+ u16 *status;
+ u16 *aid;
/*-- info elements ----------*/
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_reassocresp_t;
/*-- Probe Request --------------------------------*/
-typedef struct wlan_fr_probereq
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_probereq {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
} wlan_fr_probereq_t;
/*-- Probe Response -------------------------------*/
-typedef struct wlan_fr_proberesp
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_proberesp {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u64 *ts;
- u16 *bcn_int;
- u16 *cap_info;
+ u64 *ts;
+ u16 *bcn_int;
+ u16 *cap_info;
/*-- info elements ----------*/
- wlan_ie_ssid_t *ssid;
- wlan_ie_supp_rates_t *supp_rates;
- wlan_ie_fh_parms_t *fh_parms;
- wlan_ie_ds_parms_t *ds_parms;
- wlan_ie_cf_parms_t *cf_parms;
- wlan_ie_ibss_parms_t *ibss_parms;
+ wlan_ie_ssid_t *ssid;
+ wlan_ie_supp_rates_t *supp_rates;
+ wlan_ie_fh_parms_t *fh_parms;
+ wlan_ie_ds_parms_t *ds_parms;
+ wlan_ie_cf_parms_t *cf_parms;
+ wlan_ie_ibss_parms_t *ibss_parms;
} wlan_fr_proberesp_t;
/*-- Authentication -------------------------------*/
-typedef struct wlan_fr_authen
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_authen {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *auth_alg;
- u16 *auth_seq;
- u16 *status;
+ u16 *auth_alg;
+ u16 *auth_seq;
+ u16 *status;
/*-- info elements ----------*/
- wlan_ie_challenge_t *challenge;
+ wlan_ie_challenge_t *challenge;
} wlan_fr_authen_t;
/*-- Deauthenication -----------------------------*/
-typedef struct wlan_fr_deauthen
-{
- u16 type;
- u16 len;
- u8 *buf;
- p80211_hdr_t *hdr;
+typedef struct wlan_fr_deauthen {
+ u16 type;
+ u16 len;
+ u8 *buf;
+ p80211_hdr_t *hdr;
/* used for target specific data, skb in Linux */
- void *priv;
+ void *priv;
/*-- fixed fields -----------*/
- u16 *reason;
+ u16 *reason;
/*-- info elements ----------*/
} wlan_fr_deauthen_t;
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
-void wlan_mgmt_encode_beacon( wlan_fr_beacon_t *f );
-void wlan_mgmt_decode_beacon( wlan_fr_beacon_t *f );
-void wlan_mgmt_encode_disassoc( wlan_fr_disassoc_t *f );
-void wlan_mgmt_decode_disassoc( wlan_fr_disassoc_t *f );
-void wlan_mgmt_encode_assocreq( wlan_fr_assocreq_t *f );
-void wlan_mgmt_decode_assocreq( wlan_fr_assocreq_t *f );
-void wlan_mgmt_encode_assocresp( wlan_fr_assocresp_t *f );
-void wlan_mgmt_decode_assocresp( wlan_fr_assocresp_t *f );
-void wlan_mgmt_encode_reassocreq( wlan_fr_reassocreq_t *f );
-void wlan_mgmt_decode_reassocreq( wlan_fr_reassocreq_t *f );
-void wlan_mgmt_encode_reassocresp( wlan_fr_reassocresp_t *f );
-void wlan_mgmt_decode_reassocresp( wlan_fr_reassocresp_t *f );
-void wlan_mgmt_encode_probereq( wlan_fr_probereq_t *f );
-void wlan_mgmt_decode_probereq( wlan_fr_probereq_t *f );
-void wlan_mgmt_encode_proberesp( wlan_fr_proberesp_t *f );
-void wlan_mgmt_decode_proberesp( wlan_fr_proberesp_t *f );
-void wlan_mgmt_encode_authen( wlan_fr_authen_t *f );
-void wlan_mgmt_decode_authen( wlan_fr_authen_t *f );
-void wlan_mgmt_encode_deauthen( wlan_fr_deauthen_t *f );
-void wlan_mgmt_decode_deauthen( wlan_fr_deauthen_t *f );
-
+void wlan_mgmt_encode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_decode_beacon(wlan_fr_beacon_t *f);
+void wlan_mgmt_encode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_decode_disassoc(wlan_fr_disassoc_t *f);
+void wlan_mgmt_encode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_decode_assocreq(wlan_fr_assocreq_t *f);
+void wlan_mgmt_encode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_decode_assocresp(wlan_fr_assocresp_t *f);
+void wlan_mgmt_encode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_decode_reassocreq(wlan_fr_reassocreq_t *f);
+void wlan_mgmt_encode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_decode_reassocresp(wlan_fr_reassocresp_t *f);
+void wlan_mgmt_encode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_decode_probereq(wlan_fr_probereq_t *f);
+void wlan_mgmt_encode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_decode_proberesp(wlan_fr_proberesp_t *f);
+void wlan_mgmt_encode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_decode_authen(wlan_fr_authen_t *f);
+void wlan_mgmt_encode_deauthen(wlan_fr_deauthen_t *f);
+void wlan_mgmt_decode_deauthen(wlan_fr_deauthen_t *f);
#endif /* _P80211MGMT_H */
diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h
index 3a575d8cc99..f15a5d921f3 100644
--- a/drivers/staging/wlan-ng/p80211msg.h
+++ b/drivers/staging/wlan-ng/p80211msg.h
@@ -49,54 +49,18 @@
#define _P80211MSG_H
/*================================================================*/
-/* System Includes */
-
-/*================================================================*/
/* Project Includes */
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-/*================================================================*/
-/* Constants */
-
-#define MSG_BUFF_LEN 4000
#define WLAN_DEVNAMELEN_MAX 16
-/*================================================================*/
-/* Macros */
-
-/*================================================================*/
-/* Types */
-
-/*--------------------------------------------------------------------*/
-/*----- Message Structure Types --------------------------------------*/
-
/*--------------------------------------------------------------------*/
/* Prototype msg type */
-typedef struct p80211msg
-{
- u32 msgcode;
- u32 msglen;
- u8 devname[WLAN_DEVNAMELEN_MAX];
-} __WLAN_ATTRIB_PACK__ p80211msg_t;
-
-typedef struct p80211msgd
-{
- u32 msgcode;
- u32 msglen;
- u8 devname[WLAN_DEVNAMELEN_MAX];
- u8 args[0];
-} __WLAN_ATTRIB_PACK__ p80211msgd_t;
-
-/*================================================================*/
-/* Extern Declarations */
-
-
-/*================================================================*/
-/* Function Declarations */
-
-#endif /* _P80211MSG_H */
+typedef struct p80211msg {
+ u32 msgcode;
+ u32 msglen;
+ u8 devname[WLAN_DEVNAMELEN_MAX];
+} __attribute__ ((packed)) p80211msg_t;
+#endif /* _P80211MSG_H */
diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c
index 59e5ad10dbd..b2a606a3693 100644
--- a/drivers/staging/wlan-ng/p80211netdev.c
+++ b/drivers/staging/wlan-ng/p80211netdev.c
@@ -49,13 +49,7 @@
* --------------------------------------------------------------------
*/
-
-/*================================================================*/
-/* System Includes */
-
-
#include <linux/version.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -70,9 +64,10 @@
#include <linux/wireless.h>
#include <linux/sockios.h>
#include <linux/etherdevice.h>
-
-#include <asm/bitops.h>
-#include <asm/uaccess.h>
+#include <linux/if_ether.h>
+#include <linux/byteorder/generic.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
#include <asm/byteorder.h>
#ifdef SIOCETHTOOL
@@ -85,7 +80,6 @@
/*================================================================*/
/* Project Includes */
-#include "wlan_compat.h"
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
@@ -97,33 +91,22 @@
#include "p80211metastruct.h"
#include "p80211metadef.h"
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Function Declarations */
-
/* Support functions */
static void p80211netdev_rx_bh(unsigned long arg);
/* netdevice method functions */
-static int p80211knetdev_init( netdevice_t *netdev);
-static struct net_device_stats* p80211knetdev_get_stats(netdevice_t *netdev);
-static int p80211knetdev_open( netdevice_t *netdev);
-static int p80211knetdev_stop( netdevice_t *netdev );
-static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev);
+static int p80211knetdev_init(netdevice_t *netdev);
+static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev);
+static int p80211knetdev_open(netdevice_t *netdev);
+static int p80211knetdev_stop(netdevice_t *netdev);
+static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
+ netdevice_t *netdev);
static void p80211knetdev_set_multicast_list(netdevice_t *dev);
-static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
+static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr,
+ int cmd);
static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr);
static void p80211knetdev_tx_timeout(netdevice_t *netdev);
-static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc);
+static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc);
int wlan_watchdog = 5000;
module_param(wlan_watchdog, int, 0644);
@@ -133,15 +116,6 @@ int wlan_wext_write = 1;
module_param(wlan_wext_write, int, 0644);
MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions");
-#ifdef WLAN_INCLUDE_DEBUG
-int wlan_debug=0;
-module_param(wlan_debug, int, 0644);
-MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
-#endif
-
-/*================================================================*/
-/* Function Definitions */
-
/*----------------------------------------------------------------
* p80211knetdev_init
*
@@ -154,18 +128,15 @@ MODULE_PARM_DESC(wlan_debug, "p80211 debug level");
* Returns:
* nothing
----------------------------------------------------------------*/
-static int p80211knetdev_init( netdevice_t *netdev)
+static int p80211knetdev_init(netdevice_t *netdev)
{
- DBFENTER;
/* Called in response to register_netdev */
/* This is usually the probe function, but the probe has */
/* already been done by the MSD and the create_kdev */
/* function. All we do here is return success */
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* p80211knetdev_get_stats
*
@@ -180,20 +151,16 @@ static int p80211knetdev_init( netdevice_t *netdev)
* Returns:
* the address of the statistics structure
----------------------------------------------------------------*/
-static struct net_device_stats*
-p80211knetdev_get_stats(netdevice_t *netdev)
+static struct net_device_stats *p80211knetdev_get_stats(netdevice_t *netdev)
{
- wlandevice_t *wlandev = netdev->ml_priv;
- DBFENTER;
+ wlandevice_t *wlandev = netdev->ml_priv;
/* TODO: review the MIB stats for items that correspond to
- linux stats */
+ linux stats */
- DBFEXIT;
return &(wlandev->linux_stats);
}
-
/*----------------------------------------------------------------
* p80211knetdev_open
*
@@ -208,22 +175,19 @@ p80211knetdev_get_stats(netdevice_t *netdev)
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
-static int p80211knetdev_open( netdevice_t *netdev )
+static int p80211knetdev_open(netdevice_t *netdev)
{
- int result = 0; /* success */
- wlandevice_t *wlandev = netdev->ml_priv;
-
- DBFENTER;
+ int result = 0; /* success */
+ wlandevice_t *wlandev = netdev->ml_priv;
/* Check to make sure the MSD is running */
- if ( wlandev->msdstate != WLAN_MSD_RUNNING ) {
+ if (wlandev->msdstate != WLAN_MSD_RUNNING)
return -ENODEV;
- }
/* Tell the MSD to open */
- if ( wlandev->open != NULL) {
+ if (wlandev->open != NULL) {
result = wlandev->open(wlandev);
- if ( result == 0 ) {
+ if (result == 0) {
netif_start_queue(wlandev->netdev);
wlandev->state = WLAN_DEVICE_OPEN;
}
@@ -231,11 +195,9 @@ static int p80211knetdev_open( netdevice_t *netdev )
result = -EAGAIN;
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* p80211knetdev_stop
*
@@ -248,21 +210,17 @@ static int p80211knetdev_open( netdevice_t *netdev )
* Returns:
* zero on success, non-zero otherwise
----------------------------------------------------------------*/
-static int p80211knetdev_stop( netdevice_t *netdev )
+static int p80211knetdev_stop(netdevice_t *netdev)
{
- int result = 0;
- wlandevice_t *wlandev = netdev->ml_priv;
-
- DBFENTER;
+ int result = 0;
+ wlandevice_t *wlandev = netdev->ml_priv;
- if ( wlandev->close != NULL ) {
+ if (wlandev->close != NULL)
result = wlandev->close(wlandev);
- }
netif_stop_queue(wlandev->netdev);
wlandev->state = WLAN_DEVICE_CLOSED;
- DBFEXIT;
return result;
}
@@ -279,17 +237,13 @@ static int p80211knetdev_stop( netdevice_t *netdev )
* Side effects:
*
----------------------------------------------------------------*/
-void
-p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb )
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
{
- DBFENTER;
-
/* Enqueue for post-irq processing */
skb_queue_tail(&wlandev->nsd_rxq, skb);
tasklet_schedule(&wlandev->rx_bh);
- DBFEXIT;
return;
}
@@ -310,19 +264,17 @@ static void p80211netdev_rx_bh(unsigned long arg)
{
wlandevice_t *wlandev = (wlandevice_t *) arg;
struct sk_buff *skb = NULL;
- netdevice_t *dev = wlandev->netdev;
+ netdevice_t *dev = wlandev->netdev;
p80211_hdr_a3_t *hdr;
u16 fc;
- DBFENTER;
-
/* Let's empty our our queue */
- while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+ while ((skb = skb_dequeue(&wlandev->nsd_rxq))) {
if (wlandev->state == WLAN_DEVICE_OPEN) {
if (dev->type != ARPHRD_ETHER) {
/* RAW frame; we shouldn't convert it */
- // XXX Append the Prism Header here instead.
+ /* XXX Append the Prism Header here instead. */
/* set up various data fields */
skb->dev = dev;
@@ -337,8 +289,8 @@ static void p80211netdev_rx_bh(unsigned long arg)
netif_rx_ni(skb);
continue;
} else {
- hdr = (p80211_hdr_a3_t *)skb->data;
- fc = ieee2host16(hdr->fc);
+ hdr = (p80211_hdr_a3_t *) skb->data;
+ fc = le16_to_cpu(hdr->fc);
if (p80211_rx_typedrop(wlandev, fc)) {
dev_kfree_skb(skb);
continue;
@@ -347,7 +299,9 @@ static void p80211netdev_rx_bh(unsigned long arg)
/* perform mcast filtering */
if (wlandev->netdev->flags & IFF_ALLMULTI) {
/* allow my local address through */
- if (memcmp(hdr->a1, wlandev->netdev->dev_addr, WLAN_ADDR_LEN) != 0) {
+ if (memcmp
+ (hdr->a1, wlandev->netdev->dev_addr,
+ ETH_ALEN) != 0) {
/* but reject anything else that isn't multicast */
if (!(hdr->a1[0] & 0x01)) {
dev_kfree_skb(skb);
@@ -356,23 +310,22 @@ static void p80211netdev_rx_bh(unsigned long arg)
}
}
- if ( skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0 ) {
+ if (skb_p80211_to_ether
+ (wlandev, wlandev->ethconv, skb) == 0) {
skb->dev->last_rx = jiffies;
wlandev->linux_stats.rx_packets++;
- wlandev->linux_stats.rx_bytes += skb->len;
+ wlandev->linux_stats.rx_bytes +=
+ skb->len;
netif_rx_ni(skb);
continue;
}
- WLAN_LOG_DEBUG(1, "p80211_to_ether failed.\n");
+ pr_debug("p80211_to_ether failed.\n");
}
}
dev_kfree_skb(skb);
}
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* p80211knetdev_hard_start_xmit
*
@@ -392,21 +345,19 @@ static void p80211netdev_rx_bh(unsigned long arg)
* Returns:
* zero on success, non-zero on failure.
----------------------------------------------------------------*/
-static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netdev)
+static int p80211knetdev_hard_start_xmit(struct sk_buff *skb,
+ netdevice_t *netdev)
{
- int result = 0;
- int txresult = -1;
- wlandevice_t *wlandev = netdev->ml_priv;
- p80211_hdr_t p80211_hdr;
+ int result = 0;
+ int txresult = -1;
+ wlandevice_t *wlandev = netdev->ml_priv;
+ p80211_hdr_t p80211_hdr;
p80211_metawep_t p80211_wep;
- DBFENTER;
-
- if (skb == NULL) {
+ if (skb == NULL)
return 0;
- }
- if (wlandev->state != WLAN_DEVICE_OPEN) {
+ if (wlandev->state != WLAN_DEVICE_OPEN) {
result = 1;
goto failed;
}
@@ -414,8 +365,8 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
memset(&p80211_hdr, 0, sizeof(p80211_hdr_t));
memset(&p80211_wep, 0, sizeof(p80211_metawep_t));
- if ( netif_queue_stopped(netdev) ) {
- WLAN_LOG_DEBUG(1, "called when queue stopped.\n");
+ if (netif_queue_stopped(netdev)) {
+ pr_debug("called when queue stopped.\n");
result = 1;
goto failed;
}
@@ -423,7 +374,7 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
netif_stop_queue(netdev);
/* Check to see that a valid mode is set */
- switch( wlandev->macmode ) {
+ switch (wlandev->macmode) {
case WLAN_MACMODE_IBSS_STA:
case WLAN_MACMODE_ESS_STA:
case WLAN_MACMODE_ESS_AP:
@@ -433,10 +384,10 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
* and return success .
* TODO: we need a saner way to handle this
*/
- if(skb->protocol != ETH_P_80211_RAW) {
+ if (skb->protocol != ETH_P_80211_RAW) {
netif_start_queue(wlandev->netdev);
- WLAN_LOG_NOTICE(
- "Tx attempt prior to association, frame dropped.\n");
+ printk(KERN_NOTICE
+ "Tx attempt prior to association, frame dropped.\n");
wlandev->linux_stats.tx_dropped++;
result = 0;
goto failed;
@@ -445,7 +396,7 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
}
/* Check for raw transmits */
- if(skb->protocol == ETH_P_80211_RAW) {
+ if (skb->protocol == ETH_P_80211_RAW) {
if (!capable(CAP_NET_ADMIN)) {
result = 1;
goto failed;
@@ -454,15 +405,17 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr_t));
skb_pull(skb, sizeof(p80211_hdr_t));
} else {
- if ( skb_ether_to_p80211(wlandev, wlandev->ethconv, skb, &p80211_hdr, &p80211_wep) != 0 ) {
+ if (skb_ether_to_p80211
+ (wlandev, wlandev->ethconv, skb, &p80211_hdr,
+ &p80211_wep) != 0) {
/* convert failed */
- WLAN_LOG_DEBUG(1, "ether_to_80211(%d) failed.\n",
- wlandev->ethconv);
+ pr_debug("ether_to_80211(%d) failed.\n",
+ wlandev->ethconv);
result = 1;
goto failed;
}
}
- if ( wlandev->txframe == NULL ) {
+ if (wlandev->txframe == NULL) {
result = 1;
goto failed;
}
@@ -475,28 +428,28 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep);
- if ( txresult == 0) {
+ if (txresult == 0) {
/* success and more buf */
/* avail, re: hw_txdata */
netif_wake_queue(wlandev->netdev);
result = 0;
- } else if ( txresult == 1 ) {
+ } else if (txresult == 1) {
/* success, no more avail */
- WLAN_LOG_DEBUG(3, "txframe success, no more bufs\n");
+ pr_debug("txframe success, no more bufs\n");
/* netdev->tbusy = 1; don't set here, irqhdlr */
/* may have already cleared it */
result = 0;
- } else if ( txresult == 2 ) {
+ } else if (txresult == 2) {
/* alloc failure, drop frame */
- WLAN_LOG_DEBUG(3, "txframe returned alloc_fail\n");
+ pr_debug("txframe returned alloc_fail\n");
result = 1;
} else {
/* buffer full or queue busy, drop frame. */
- WLAN_LOG_DEBUG(3, "txframe returned full or busy\n");
+ pr_debug("txframe returned full or busy\n");
result = 1;
}
- failed:
+failed:
/* Free up the WEP buffer if it's not the same as the skb */
if ((p80211_wep.data) && (p80211_wep.data != skb->data))
kfree(p80211_wep.data);
@@ -505,11 +458,9 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
if (!result)
dev_kfree_skb(skb);
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* p80211knetdev_set_multicast_list
*
@@ -524,16 +475,13 @@ static int p80211knetdev_hard_start_xmit( struct sk_buff *skb, netdevice_t *netd
----------------------------------------------------------------*/
static void p80211knetdev_set_multicast_list(netdevice_t *dev)
{
- wlandevice_t *wlandev = dev->ml_priv;
-
- DBFENTER;
+ wlandevice_t *wlandev = dev->ml_priv;
/* TODO: real multicast support as well */
if (wlandev->set_multicast_list)
wlandev->set_multicast_list(wlandev, dev);
- DBFEXIT;
}
#ifdef SIOCETHTOOL
@@ -558,9 +506,6 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
snprintf(info.version, sizeof(info.version), "%s",
WLAN_RELEASE);
- // info.fw_version
- // info.bus_info
-
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
@@ -576,7 +521,7 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
}
if (copy_to_user(useraddr, &edata, sizeof(edata)))
- return -EFAULT;
+ return -EFAULT;
return 0;
}
#endif
@@ -615,45 +560,47 @@ static int p80211netdev_ethtool(wlandevice_t *wlandev, void __user *useraddr)
----------------------------------------------------------------*/
static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
{
- int result = 0;
- p80211ioctl_req_t *req = (p80211ioctl_req_t*)ifr;
- wlandevice_t *wlandev = dev->ml_priv;
- u8 *msgbuf;
- DBFENTER;
+ int result = 0;
+ p80211ioctl_req_t *req = (p80211ioctl_req_t *) ifr;
+ wlandevice_t *wlandev = dev->ml_priv;
+ u8 *msgbuf;
+
+ pr_debug("rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
- WLAN_LOG_DEBUG(2, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len);
+ mutex_lock(&wlandev->ioctl_lock);
#ifdef SIOCETHTOOL
if (cmd == SIOCETHTOOL) {
- result = p80211netdev_ethtool(wlandev, (void __user *) ifr->ifr_data);
+ result =
+ p80211netdev_ethtool(wlandev, (void __user *)ifr->ifr_data);
goto bail;
}
#endif
/* Test the magic, assume ifr is good if it's there */
- if ( req->magic != P80211_IOCTL_MAGIC ) {
+ if (req->magic != P80211_IOCTL_MAGIC) {
result = -ENOSYS;
goto bail;
}
- if ( cmd == P80211_IFTEST ) {
+ if (cmd == P80211_IFTEST) {
result = 0;
goto bail;
- } else if ( cmd != P80211_IFREQ ) {
+ } else if (cmd != P80211_IFREQ) {
result = -ENOSYS;
goto bail;
}
/* Allocate a buf of size req->len */
- if ((msgbuf = kmalloc( req->len, GFP_KERNEL))) {
- if ( copy_from_user( msgbuf, (void __user *) req->data, req->len) ) {
+ if ((msgbuf = kmalloc(req->len, GFP_KERNEL))) {
+ if (copy_from_user(msgbuf, (void __user *)req->data, req->len))
result = -EFAULT;
- } else {
- result = p80211req_dorequest( wlandev, msgbuf);
- }
+ else
+ result = p80211req_dorequest(wlandev, msgbuf);
- if ( result == 0 ) {
- if ( copy_to_user( (void __user *) req->data, msgbuf, req->len)) {
+ if (result == 0) {
+ if (copy_to_user
+ ((void __user *)req->data, msgbuf, req->len)) {
result = -EFAULT;
}
}
@@ -662,9 +609,9 @@ static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd)
result = -ENOMEM;
}
bail:
- DBFEXIT;
+ mutex_unlock(&wlandev->ioctl_lock);
- return result; /* If allocate,copyfrom or copyto fails, return errno */
+ return result; /* If allocate,copyfrom or copyto fails, return errno */
}
/*----------------------------------------------------------------
@@ -694,22 +641,20 @@ bail:
----------------------------------------------------------------*/
static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
{
- struct sockaddr *new_addr = addr;
- p80211msg_dot11req_mibset_t dot11req;
- p80211item_unk392_t *mibattr;
- p80211item_pstr6_t *macaddr;
- p80211item_uint32_t *resultcode;
+ struct sockaddr *new_addr = addr;
+ p80211msg_dot11req_mibset_t dot11req;
+ p80211item_unk392_t *mibattr;
+ p80211item_pstr6_t *macaddr;
+ p80211item_uint32_t *resultcode;
int result = 0;
- DBFENTER;
/* If we're running, we don't allow MAC address changes */
- if (netif_running(dev)) {
+ if (netif_running(dev))
return -EBUSY;
- }
/* Set up some convenience pointers. */
mibattr = &dot11req.mibattribute;
- macaddr = (p80211item_pstr6_t*)&mibattr->data;
+ macaddr = (p80211item_pstr6_t *)&mibattr->data;
resultcode = &dot11req.resultcode;
/* Set up a dot11req_mibset */
@@ -717,8 +662,7 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
dot11req.msgcode = DIDmsg_dot11req_mibset;
dot11req.msglen = sizeof(p80211msg_dot11req_mibset_t);
memcpy(dot11req.devname,
- ((wlandevice_t *)dev->ml_priv)->name,
- WLAN_DEVNAMELEN_MAX - 1);
+ ((wlandevice_t *) dev->ml_priv)->name, WLAN_DEVNAMELEN_MAX - 1);
/* Set up the mibattribute argument */
mibattr->did = DIDmsg_dot11req_mibset_mibattribute;
@@ -728,8 +672,8 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
macaddr->did = DIDmib_dot11mac_dot11OperationTable_dot11MACAddress;
macaddr->status = P80211ENUM_msgitem_status_data_ok;
macaddr->len = sizeof(macaddr->data);
- macaddr->data.len = WLAN_ADDR_LEN;
- memcpy(&macaddr->data.data, new_addr->sa_data, WLAN_ADDR_LEN);
+ macaddr->data.len = ETH_ALEN;
+ memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN);
/* Set up the resultcode argument */
resultcode->did = DIDmsg_dot11req_mibset_resultcode;
@@ -743,36 +687,30 @@ static int p80211knetdev_set_mac_address(netdevice_t *dev, void *addr)
/* If the request wasn't successful, report an error and don't
* change the netdev address
*/
- if ( result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
- WLAN_LOG_ERROR(
- "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
+ if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) {
+ printk(KERN_ERR
+ "Low-level driver failed dot11req_mibset(dot11MACAddress).\n");
result = -EADDRNOTAVAIL;
} else {
/* everything's ok, change the addr in netdev */
memcpy(dev->dev_addr, new_addr->sa_data, dev->addr_len);
}
- DBFEXIT;
return result;
}
static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
{
- DBFENTER;
- // 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
- // and another 8 for wep.
- if ( (new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
- return -EINVAL;
-
- dev->mtu = new_mtu;
+ /* 2312 is max 802.11 payload, 20 is overhead, (ether + llc +snap)
+ and another 8 for wep. */
+ if ((new_mtu < 68) || (new_mtu > (2312 - 20 - 8)))
+ return -EINVAL;
- DBFEXIT;
+ dev->mtu = new_mtu;
- return 0;
+ return 0;
}
-
-
/*----------------------------------------------------------------
* wlan_setup
*
@@ -797,10 +735,8 @@ static int wlan_change_mtu(netdevice_t *dev, int new_mtu)
----------------------------------------------------------------*/
int wlan_setup(wlandevice_t *wlandev)
{
- int result = 0;
- netdevice_t *dev;
-
- DBFENTER;
+ int result = 0;
+ netdevice_t *dev;
/* Set up the wlandev */
wlandev->state = WLAN_DEVICE_CLOSED;
@@ -810,28 +746,26 @@ int wlan_setup(wlandevice_t *wlandev)
/* Set up the rx queue */
skb_queue_head_init(&wlandev->nsd_rxq);
tasklet_init(&wlandev->rx_bh,
- p80211netdev_rx_bh,
- (unsigned long)wlandev);
+ p80211netdev_rx_bh, (unsigned long)wlandev);
/* Allocate and initialize the struct device */
- dev = alloc_netdev(0,"wlan%d",ether_setup);
- if ( dev == NULL ) {
- WLAN_LOG_ERROR("Failed to alloc netdev.\n");
+ dev = alloc_netdev(0, "wlan%d", ether_setup);
+ if (dev == NULL) {
+ printk(KERN_ERR "Failed to alloc netdev.\n");
result = 1;
} else {
wlandev->netdev = dev;
dev->ml_priv = wlandev;
- dev->hard_start_xmit = p80211knetdev_hard_start_xmit;
- dev->get_stats = p80211knetdev_get_stats;
-#ifdef HAVE_PRIVATE_IOCTL
- dev->do_ioctl = p80211knetdev_do_ioctl;
-#endif
-#ifdef HAVE_MULTICAST
- dev->set_multicast_list = p80211knetdev_set_multicast_list;
-#endif
- dev->init = p80211knetdev_init;
- dev->open = p80211knetdev_open;
- dev->stop = p80211knetdev_stop;
+ dev->hard_start_xmit = p80211knetdev_hard_start_xmit;
+ dev->get_stats = p80211knetdev_get_stats;
+ dev->init = p80211knetdev_init;
+ dev->open = p80211knetdev_open;
+ dev->stop = p80211knetdev_stop;
+
+ mutex_init(&wlandev->ioctl_lock);
+ /* block ioctls until fully initialised. Don't forget to call
+ allow_ioctls at some point!*/
+ mutex_lock(&wlandev->ioctl_lock);
#if (WIRELESS_EXT < 21)
dev->get_wireless_stats = p80211wext_get_wireless_stats;
@@ -839,20 +773,9 @@ int wlan_setup(wlandevice_t *wlandev)
dev->wireless_handlers = &p80211wext_handler_def;
netif_stop_queue(dev);
-#ifdef HAVE_CHANGE_MTU
- dev->change_mtu = wlan_change_mtu;
-#endif
-#ifdef HAVE_SET_MAC_ADDR
- dev->set_mac_address = p80211knetdev_set_mac_address;
-#endif
-#ifdef HAVE_TX_TIMEOUT
- dev->tx_timeout = &p80211knetdev_tx_timeout;
- dev->watchdog_timeo = (wlan_watchdog * HZ) / 1000;
-#endif
netif_carrier_off(dev);
}
- DBFEXIT;
return result;
}
@@ -879,26 +802,21 @@ int wlan_setup(wlandevice_t *wlandev)
----------------------------------------------------------------*/
int wlan_unsetup(wlandevice_t *wlandev)
{
- int result = 0;
-
- DBFENTER;
+ int result = 0;
tasklet_kill(&wlandev->rx_bh);
- if (wlandev->netdev == NULL ) {
- WLAN_LOG_ERROR("called without wlandev->netdev set.\n");
+ if (wlandev->netdev == NULL) {
+ printk(KERN_ERR "called without wlandev->netdev set.\n");
result = 1;
} else {
free_netdev(wlandev->netdev);
wlandev->netdev = NULL;
}
- DBFEXIT;
return 0;
}
-
-
/*----------------------------------------------------------------
* register_wlandev
*
@@ -920,19 +838,15 @@ int wlan_unsetup(wlandevice_t *wlandev)
----------------------------------------------------------------*/
int register_wlandev(wlandevice_t *wlandev)
{
- int i = 0;
-
- DBFENTER;
+ int i = 0;
i = register_netdev(wlandev->netdev);
if (i)
return i;
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* unregister_wlandev
*
@@ -954,20 +868,15 @@ int unregister_wlandev(wlandevice_t *wlandev)
{
struct sk_buff *skb;
- DBFENTER;
-
unregister_netdev(wlandev->netdev);
/* Now to clean out the rx queue */
- while ( (skb = skb_dequeue(&wlandev->nsd_rxq)) ) {
+ while ((skb = skb_dequeue(&wlandev->nsd_rxq)))
dev_kfree_skb(skb);
- }
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* p80211netdev_hwremoved
*
@@ -1000,18 +909,13 @@ int unregister_wlandev(wlandevice_t *wlandev)
----------------------------------------------------------------*/
void p80211netdev_hwremoved(wlandevice_t *wlandev)
{
- DBFENTER;
wlandev->hwremoved = 1;
- if ( wlandev->state == WLAN_DEVICE_OPEN) {
+ if (wlandev->state == WLAN_DEVICE_OPEN)
netif_stop_queue(wlandev->netdev);
- }
netif_device_detach(wlandev->netdev);
-
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* p80211_rx_typedrop
*
@@ -1033,28 +937,27 @@ void p80211netdev_hwremoved(wlandevice_t *wlandev)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
+static int p80211_rx_typedrop(wlandevice_t *wlandev, u16 fc)
{
- u16 ftype;
- u16 fstype;
- int drop = 0;
+ u16 ftype;
+ u16 fstype;
+ int drop = 0;
/* Classify frame, increment counter */
ftype = WLAN_GET_FC_FTYPE(fc);
fstype = WLAN_GET_FC_FSTYPE(fc);
#if 0
- WLAN_LOG_DEBUG(4,
- "rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
+ pr_debug("rx_typedrop : ftype=%d fstype=%d.\n", ftype, fstype);
#endif
- switch ( ftype ) {
+ switch (ftype) {
case WLAN_FTYPE_MGMT:
if ((wlandev->netdev->flags & IFF_PROMISC) ||
- (wlandev->netdev->flags & IFF_ALLMULTI)) {
+ (wlandev->netdev->flags & IFF_ALLMULTI)) {
drop = 1;
break;
}
- WLAN_LOG_DEBUG(3, "rx'd mgmt:\n");
+ pr_debug("rx'd mgmt:\n");
wlandev->rx.mgmt++;
- switch( fstype ) {
+ switch (fstype) {
case WLAN_FSTYPE_ASSOCREQ:
/* printk("assocreq"); */
wlandev->rx.assocreq++;
@@ -1110,13 +1013,13 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
case WLAN_FTYPE_CTL:
if ((wlandev->netdev->flags & IFF_PROMISC) ||
- (wlandev->netdev->flags & IFF_ALLMULTI)) {
+ (wlandev->netdev->flags & IFF_ALLMULTI)) {
drop = 1;
break;
}
- WLAN_LOG_DEBUG(3, "rx'd ctl:\n");
+ pr_debug("rx'd ctl:\n");
wlandev->rx.ctl++;
- switch( fstype ) {
+ switch (fstype) {
case WLAN_FSTYPE_PSPOLL:
/* printk("pspoll"); */
wlandev->rx.pspoll++;
@@ -1152,7 +1055,7 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
case WLAN_FTYPE_DATA:
wlandev->rx.data++;
- switch( fstype ) {
+ switch (fstype) {
case WLAN_FSTYPE_DATAONLY:
wlandev->rx.dataonly++;
break;
@@ -1166,19 +1069,19 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
wlandev->rx.data__cfack_cfpoll++;
break;
case WLAN_FSTYPE_NULL:
- WLAN_LOG_DEBUG(3, "rx'd data:null\n");
+ pr_debug("rx'd data:null\n");
wlandev->rx.null++;
break;
case WLAN_FSTYPE_CFACK:
- WLAN_LOG_DEBUG(3, "rx'd data:cfack\n");
+ pr_debug("rx'd data:cfack\n");
wlandev->rx.cfack++;
break;
case WLAN_FSTYPE_CFPOLL:
- WLAN_LOG_DEBUG(3, "rx'd data:cfpoll\n");
+ pr_debug("rx'd data:cfpoll\n");
wlandev->rx.cfpoll++;
break;
case WLAN_FSTYPE_CFACK_CFPOLL:
- WLAN_LOG_DEBUG(3, "rx'd data:cfack_cfpoll\n");
+ pr_debug("rx'd data:cfack_cfpoll\n");
wlandev->rx.cfack_cfpoll++;
break;
default:
@@ -1192,18 +1095,20 @@ static int p80211_rx_typedrop( wlandevice_t *wlandev, u16 fc)
return drop;
}
-static void p80211knetdev_tx_timeout( netdevice_t *netdev)
+static void p80211knetdev_tx_timeout(netdevice_t *netdev)
{
- wlandevice_t *wlandev = netdev->ml_priv;
- DBFENTER;
+ wlandevice_t *wlandev = netdev->ml_priv;
if (wlandev->tx_timeout) {
wlandev->tx_timeout(wlandev);
} else {
- WLAN_LOG_WARNING("Implement tx_timeout for %s\n",
- wlandev->nsdname);
+ printk(KERN_WARNING "Implement tx_timeout for %s\n",
+ wlandev->nsdname);
netif_wake_queue(wlandev->netdev);
}
+}
- DBFEXIT;
+void p80211_allow_ioctls(wlandevice_t *wlandev)
+{
+ mutex_unlock(&wlandev->ioctl_lock);
}
diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h
index 940146fba9c..b96090d8788 100644
--- a/drivers/staging/wlan-ng/p80211netdev.h
+++ b/drivers/staging/wlan-ng/p80211netdev.h
@@ -55,10 +55,16 @@
#include <linux/interrupt.h>
#include <linux/wireless.h>
+#include <linux/netdevice.h>
/*================================================================*/
/* Constants */
+#undef netdevice_t
+typedef struct net_device netdevice_t;
+
+#define WLAN_RELEASE "0.3.0-staging"
+
#define WLAN_DEVICE_CLOSED 0
#define WLAN_DEVICE_OPEN 1
@@ -68,8 +74,6 @@
#define WLAN_MACMODE_ESS_AP 3
/* MSD States */
-#define WLAN_MSD_START -1
-#define WLAN_MSD_DRIVERLOADED 0
#define WLAN_MSD_HWPRESENT_PENDING 1
#define WLAN_MSD_HWFAIL 2
#define WLAN_MSD_HWPRESENT 3
@@ -79,79 +83,66 @@
#define WLAN_MSD_RUNNING 7
#ifndef ETH_P_ECONET
-#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */
+#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */
#endif
#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
#ifndef ARPHRD_IEEE80211
-#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */
+#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */
#endif
-#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */
+#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */
#define ARPHRD_IEEE80211_PRISM 802
#endif
/*--- NSD Capabilities Flags ------------------------------*/
-#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */
-#define P80211_NSDCAP_TIEDWEP 0x02 /* can't decouple en/de */
-#define P80211_NSDCAP_NOHOSTWEP 0x04 /* must use hardware wep */
-#define P80211_NSDCAP_PBCC 0x08 /* hardware supports PBCC */
-#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */
-#define P80211_NSDCAP_AGILITY 0x20 /* hardware supports */
-#define P80211_NSDCAP_AP_RETRANSMIT 0x40 /* nsd handles retransmits */
-#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */
-#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */
-#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */
-
-/*================================================================*/
-/* Macros */
-
-/*================================================================*/
-/* Types */
+#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */
+#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */
+#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */
+#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */
+#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */
/* Received frame statistics */
-typedef struct p80211_frmrx_t
-{
- u32 mgmt;
- u32 assocreq;
- u32 assocresp;
- u32 reassocreq;
- u32 reassocresp;
- u32 probereq;
- u32 proberesp;
- u32 beacon;
- u32 atim;
- u32 disassoc;
- u32 authen;
- u32 deauthen;
- u32 mgmt_unknown;
- u32 ctl;
- u32 pspoll;
- u32 rts;
- u32 cts;
- u32 ack;
- u32 cfend;
- u32 cfendcfack;
- u32 ctl_unknown;
- u32 data;
- u32 dataonly;
- u32 data_cfack;
- u32 data_cfpoll;
- u32 data__cfack_cfpoll;
- u32 null;
- u32 cfack;
- u32 cfpoll;
- u32 cfack_cfpoll;
- u32 data_unknown;
- u32 decrypt;
- u32 decrypt_err;
+typedef struct p80211_frmrx_t {
+ u32 mgmt;
+ u32 assocreq;
+ u32 assocresp;
+ u32 reassocreq;
+ u32 reassocresp;
+ u32 probereq;
+ u32 proberesp;
+ u32 beacon;
+ u32 atim;
+ u32 disassoc;
+ u32 authen;
+ u32 deauthen;
+ u32 mgmt_unknown;
+ u32 ctl;
+ u32 pspoll;
+ u32 rts;
+ u32 cts;
+ u32 ack;
+ u32 cfend;
+ u32 cfendcfack;
+ u32 ctl_unknown;
+ u32 data;
+ u32 dataonly;
+ u32 data_cfack;
+ u32 data_cfpoll;
+ u32 data__cfack_cfpoll;
+ u32 null;
+ u32 cfack;
+ u32 cfpoll;
+ u32 cfack_cfpoll;
+ u32 data_unknown;
+ u32 decrypt;
+ u32 decrypt_err;
} p80211_frmrx_t;
/* called by /proc/net/wireless */
-struct iw_statistics* p80211wext_get_wireless_stats(netdevice_t *dev);
+struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev);
/* wireless extensions' ioctls */
-int p80211wext_support_ioctl(netdevice_t *dev, struct ifreq *ifr, int cmd);
extern struct iw_handler_def p80211wext_handler_def;
int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
@@ -159,96 +150,99 @@ int p80211wext_event_associated(struct wlandevice *wlandev, int assoc);
#define NUM_WEPKEYS 4
#define MAX_KEYLEN 32
-#define HOSTWEP_DEFAULTKEY_MASK (BIT1|BIT0)
-#define HOSTWEP_DECRYPT BIT4
-#define HOSTWEP_ENCRYPT BIT5
-#define HOSTWEP_PRIVACYINVOKED BIT6
-#define HOSTWEP_EXCLUDEUNENCRYPTED BIT7
+#define HOSTWEP_DEFAULTKEY_MASK (BIT(1)|BIT(0))
+#define HOSTWEP_DECRYPT BIT(4)
+#define HOSTWEP_ENCRYPT BIT(5)
+#define HOSTWEP_PRIVACYINVOKED BIT(6)
+#define HOSTWEP_EXCLUDEUNENCRYPTED BIT(7)
extern int wlan_watchdog;
extern int wlan_wext_write;
/* WLAN device type */
-typedef struct wlandevice
-{
- struct wlandevice *next; /* link for list of devices */
- void *priv; /* private data for MSD */
+typedef struct wlandevice {
+ struct wlandevice *next; /* link for list of devices */
+ void *priv; /* private data for MSD */
/* Subsystem State */
- char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev()*/
- char *nsdname;
+ char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev() */
+ char *nsdname;
- u32 state; /* Device I/F state (open/closed) */
- u32 msdstate; /* state of underlying driver */
- u32 hwremoved; /* Has the hw been yanked out? */
+ u32 state; /* Device I/F state (open/closed) */
+ u32 msdstate; /* state of underlying driver */
+ u32 hwremoved; /* Has the hw been yanked out? */
/* Hardware config */
- unsigned int irq;
- unsigned int iobase;
- unsigned int membase;
- u32 nsdcaps; /* NSD Capabilities flags */
+ unsigned int irq;
+ unsigned int iobase;
+ unsigned int membase;
+ u32 nsdcaps; /* NSD Capabilities flags */
/* Config vars */
- unsigned int ethconv;
+ unsigned int ethconv;
/* device methods (init by MSD, used by p80211 */
- int (*open)(struct wlandevice *wlandev);
- int (*close)(struct wlandevice *wlandev);
- void (*reset)(struct wlandevice *wlandev );
- int (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
- int (*mlmerequest)(struct wlandevice *wlandev, p80211msg_t *msg);
- int (*set_multicast_list)(struct wlandevice *wlandev,
- netdevice_t *dev);
- void (*tx_timeout)(struct wlandevice *wlandev);
+ int (*open) (struct wlandevice *wlandev);
+ int (*close) (struct wlandevice *wlandev);
+ void (*reset) (struct wlandevice *wlandev);
+ int (*txframe) (struct wlandevice *wlandev, struct sk_buff *skb,
+ p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep);
+ int (*mlmerequest) (struct wlandevice *wlandev, p80211msg_t *msg);
+ int (*set_multicast_list) (struct wlandevice *wlandev,
+ netdevice_t *dev);
+ void (*tx_timeout) (struct wlandevice *wlandev);
/* 802.11 State */
- u8 bssid[WLAN_BSSID_LEN];
- p80211pstr32_t ssid;
- u32 macmode;
- int linkstatus;
+ u8 bssid[WLAN_BSSID_LEN];
+ p80211pstr32_t ssid;
+ u32 macmode;
+ int linkstatus;
/* WEP State */
u8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN];
u8 wep_keylens[NUM_WEPKEYS];
- int hostwep;
+ int hostwep;
/* Request/Confirm i/f state (used by p80211) */
- unsigned long request_pending; /* flag, access atomically */
+ unsigned long request_pending; /* flag, access atomically */
/* netlink socket */
/* queue for indications waiting for cmd completion */
/* Linux netdevice and support */
- netdevice_t *netdev; /* ptr to linux netdevice */
+ netdevice_t *netdev; /* ptr to linux netdevice */
struct net_device_stats linux_stats;
/* Rx bottom half */
- struct tasklet_struct rx_bh;
+ struct tasklet_struct rx_bh;
- struct sk_buff_head nsd_rxq;
+ struct sk_buff_head nsd_rxq;
/* 802.11 device statistics */
- struct p80211_frmrx_t rx;
+ struct p80211_frmrx_t rx;
- struct iw_statistics wstats;
+ struct iw_statistics wstats;
/* jkriegl: iwspy fields */
- u8 spy_number;
- char spy_address[IW_MAX_SPY][ETH_ALEN];
- struct iw_quality spy_stat[IW_MAX_SPY];
+ u8 spy_number;
+ char spy_address[IW_MAX_SPY][ETH_ALEN];
+ struct iw_quality spy_stat[IW_MAX_SPY];
+
+ struct mutex ioctl_lock;
} wlandevice_t;
/* WEP stuff */
-int wep_change_key(wlandevice_t *wlandev, int keynum, u8* key, int keylen);
-int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *iv, u8 *icv);
-int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8 *iv, u8 *icv);
-
-void p80211netdev_startup(void);
-void p80211netdev_shutdown(void);
-int wlan_setup(wlandevice_t *wlandev);
-int wlan_unsetup(wlandevice_t *wlandev);
-int register_wlandev(wlandevice_t *wlandev);
-int unregister_wlandev(wlandevice_t *wlandev);
-void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-void p80211netdev_hwremoved(wlandevice_t *wlandev);
-
+int wep_change_key(wlandevice_t *wlandev, int keynum, u8 *key, int keylen);
+int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override,
+ u8 *iv, u8 *icv);
+int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum,
+ u8 *iv, u8 *icv);
+
+int wlan_setup(wlandevice_t *wlandev);
+int wlan_unsetup(wlandevice_t *wlandev);
+int register_wlandev(wlandevice_t *wlandev);
+int unregister_wlandev(wlandevice_t *wlandev);
+void p80211netdev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void p80211netdev_hwremoved(wlandevice_t *wlandev);
+void p80211_allow_ioctls(wlandevice_t *wlandev);
#endif
diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c
index 6e20bff0e67..15ecba6e469 100644
--- a/drivers/staging/wlan-ng/p80211req.c
+++ b/drivers/staging/wlan-ng/p80211req.c
@@ -50,11 +50,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-
-
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -67,11 +62,6 @@
#include <net/sock.h>
#include <linux/netlink.h>
-#include "wlan_compat.h"
-
-/*================================================================*/
-/* Project Includes */
-
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211mgmt.h"
@@ -83,30 +73,10 @@
#include "p80211metastruct.h"
#include "p80211req.h"
-/*================================================================*/
-/* Local Constants */
-
-/* Maximum amount of time we'll wait for a request to complete */
-#define P80211REQ_MAXTIME 3*HZ /* 3 seconds */
-
-/*================================================================*/
-/* Local Macros */
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Static Definitions */
-
-/*================================================================*/
-/* Local Function Declarations */
-
-static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg);
-static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mibget_t *mib_msg, int isget);
-
-/*================================================================*/
-/* Function Definitions */
-
+static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg);
+static int p80211req_mibset_mibget(wlandevice_t *wlandev,
+ p80211msg_dot11req_mibget_t *mib_msg,
+ int isget);
/*----------------------------------------------------------------
* p80211req_dorequest
@@ -124,33 +94,30 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev, p80211msg_dot11req_mib
* Potentially blocks the caller, so it's a good idea to
* not call this function from an interrupt context.
----------------------------------------------------------------*/
-int p80211req_dorequest( wlandevice_t *wlandev, u8 *msgbuf)
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf)
{
- int result = 0;
- p80211msg_t *msg = (p80211msg_t*)msgbuf;
-
- DBFENTER;
+ int result = 0;
+ p80211msg_t *msg = (p80211msg_t *) msgbuf;
/* Check to make sure the MSD is running */
- if (
- !((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
- msg->msgcode == DIDmsg_lnxreq_ifstate) ||
- wlandev->msdstate == WLAN_MSD_RUNNING ||
- wlandev->msdstate == WLAN_MSD_FWLOAD) ) {
+ if (!((wlandev->msdstate == WLAN_MSD_HWPRESENT &&
+ msg->msgcode == DIDmsg_lnxreq_ifstate) ||
+ wlandev->msdstate == WLAN_MSD_RUNNING ||
+ wlandev->msdstate == WLAN_MSD_FWLOAD)) {
return -ENODEV;
}
/* Check Permissions */
- if (!capable(CAP_NET_ADMIN) &&
- (msg->msgcode != DIDmsg_dot11req_mibget)) {
- WLAN_LOG_ERROR("%s: only dot11req_mibget allowed for non-root.\n", wlandev->name);
+ if (!capable(CAP_NET_ADMIN) && (msg->msgcode != DIDmsg_dot11req_mibget)) {
+ printk(KERN_ERR
+ "%s: only dot11req_mibget allowed for non-root.\n",
+ wlandev->name);
return -EPERM;
}
/* Check for busy status */
- if ( test_and_set_bit(1, &(wlandev->request_pending))) {
+ if (test_and_set_bit(1, &(wlandev->request_pending)))
return -EBUSY;
- }
/* Allow p80211 to look at msg and handle if desired. */
/* So far, all p80211 msgs are immediate, no waitq/timer necessary */
@@ -158,12 +125,11 @@ int p80211req_dorequest( wlandevice_t *wlandev, u8 *msgbuf)
p80211req_handlemsg(wlandev, msg);
/* Pass it down to wlandev via wlandev->mlmerequest */
- if ( wlandev->mlmerequest != NULL )
+ if (wlandev->mlmerequest != NULL)
wlandev->mlmerequest(wlandev, msg);
- clear_bit( 1, &(wlandev->request_pending));
- DBFEXIT;
- return result; /* if result==0, msg->status still may contain an err */
+ clear_bit(1, &(wlandev->request_pending));
+ return result; /* if result==0, msg->status still may contain an err */
}
/*----------------------------------------------------------------
@@ -184,34 +150,32 @@ int p80211req_dorequest( wlandevice_t *wlandev, u8 *msgbuf)
* Call context:
* Process thread
----------------------------------------------------------------*/
-static void p80211req_handlemsg( wlandevice_t *wlandev, p80211msg_t *msg)
+static void p80211req_handlemsg(wlandevice_t *wlandev, p80211msg_t *msg)
{
- DBFENTER;
-
switch (msg->msgcode) {
- case DIDmsg_lnxreq_hostwep: {
- p80211msg_lnxreq_hostwep_t *req = (p80211msg_lnxreq_hostwep_t*) msg;
- wlandev->hostwep &= ~(HOSTWEP_DECRYPT|HOSTWEP_ENCRYPT);
- if (req->decrypt.data == P80211ENUM_truth_true)
- wlandev->hostwep |= HOSTWEP_DECRYPT;
- if (req->encrypt.data == P80211ENUM_truth_true)
- wlandev->hostwep |= HOSTWEP_ENCRYPT;
-
- break;
- }
+ case DIDmsg_lnxreq_hostwep:{
+ p80211msg_lnxreq_hostwep_t *req =
+ (p80211msg_lnxreq_hostwep_t *) msg;
+ wlandev->hostwep &=
+ ~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT);
+ if (req->decrypt.data == P80211ENUM_truth_true)
+ wlandev->hostwep |= HOSTWEP_DECRYPT;
+ if (req->encrypt.data == P80211ENUM_truth_true)
+ wlandev->hostwep |= HOSTWEP_ENCRYPT;
+
+ break;
+ }
case DIDmsg_dot11req_mibget:
- case DIDmsg_dot11req_mibset: {
- int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
- p80211msg_dot11req_mibget_t *mib_msg = (p80211msg_dot11req_mibget_t *) msg;
- p80211req_mibset_mibget (wlandev, mib_msg, isget);
- }
+ case DIDmsg_dot11req_mibset:{
+ int isget = (msg->msgcode == DIDmsg_dot11req_mibget);
+ p80211msg_dot11req_mibget_t *mib_msg =
+ (p80211msg_dot11req_mibget_t *) msg;
+ p80211req_mibset_mibget(wlandev, mib_msg, isget);
+ }
default:
- // XXX do nothing!
;
- } /* switch msg->msgcode */
-
- DBFEXIT;
+ } /* switch msg->msgcode */
return;
}
@@ -220,81 +184,82 @@ static int p80211req_mibset_mibget(wlandevice_t *wlandev,
p80211msg_dot11req_mibget_t *mib_msg,
int isget)
{
- p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
- p80211pstrd_t *pstr = (p80211pstrd_t*) mibitem->data;
+ p80211itemd_t *mibitem = (p80211itemd_t *) mib_msg->mibattribute.data;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) mibitem->data;
u8 *key = mibitem->data + sizeof(p80211pstrd_t);
- DBFENTER;
-
switch (mibitem->did) {
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0: {
- if (!isget)
- wep_change_key(wlandev, 0, key, pstr->len);
- break;
- }
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1: {
- if (!isget)
- wep_change_key(wlandev, 1, key, pstr->len);
- break;
- }
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2: {
- if (!isget)
- wep_change_key(wlandev, 2, key, pstr->len);
- break;
- }
- case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3: {
- if (!isget)
- wep_change_key(wlandev, 3, key, pstr->len);
- break;
- }
- case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID: {
- u32 *data = (u32 *) mibitem->data;
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0:{
+ if (!isget)
+ wep_change_key(wlandev, 0, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1:{
+ if (!isget)
+ wep_change_key(wlandev, 1, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2:{
+ if (!isget)
+ wep_change_key(wlandev, 2, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3:{
+ if (!isget)
+ wep_change_key(wlandev, 3, key, pstr->len);
+ break;
+ }
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID:{
+ u32 *data = (u32 *) mibitem->data;
- if (isget) {
- *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
+ if (isget) {
+ *data =
+ wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
} else {
wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK);
- wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK);
+ wlandev->hostwep |=
+ (*data & HOSTWEP_DEFAULTKEY_MASK);
}
- break;
- }
- case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked: {
- u32 *data = (u32 *) mibitem->data;
-
- if (isget) {
- if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
- *data = P80211ENUM_truth_true;
- else
- *data = P80211ENUM_truth_false;
- } else {
+ break;
+ }
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked:{
+ u32 *data = (u32 *) mibitem->data;
+
+ if (isget) {
+ if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
+ *data = P80211ENUM_truth_true;
+ else
+ *data = P80211ENUM_truth_false;
+ } else {
wlandev->hostwep &= ~(HOSTWEP_PRIVACYINVOKED);
if (*data == P80211ENUM_truth_true)
- wlandev->hostwep |= HOSTWEP_PRIVACYINVOKED;
+ wlandev->hostwep |=
+ HOSTWEP_PRIVACYINVOKED;
+ }
+ break;
}
- break;
- }
- case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted: {
- u32 *data = (u32 *) mibitem->data;
-
- if (isget) {
- if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
- *data = P80211ENUM_truth_true;
- else
- *data = P80211ENUM_truth_false;
- } else {
- wlandev->hostwep &= ~(HOSTWEP_EXCLUDEUNENCRYPTED);
- if (*data == P80211ENUM_truth_true)
- wlandev->hostwep |= HOSTWEP_EXCLUDEUNENCRYPTED;
+ case DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted:{
+ u32 *data = (u32 *) mibitem->data;
+
+ if (isget) {
+ if (wlandev->
+ hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
+ *data = P80211ENUM_truth_true;
+ else
+ *data = P80211ENUM_truth_false;
+ } else {
+ wlandev->hostwep &=
+ ~(HOSTWEP_EXCLUDEUNENCRYPTED);
+ if (*data == P80211ENUM_truth_true)
+ wlandev->hostwep |=
+ HOSTWEP_EXCLUDEUNENCRYPTED;
+ }
+ break;
}
- break;
- }
default:
- // XXXX do nothing!
;
}
- DBFEXIT;
return 0;
}
-
diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h
index 497a4d6eb59..a95a45a6814 100644
--- a/drivers/staging/wlan-ng/p80211req.h
+++ b/drivers/staging/wlan-ng/p80211req.h
@@ -48,21 +48,6 @@
#ifndef _LINUX_P80211REQ_H
#define _LINUX_P80211REQ_H
-/*================================================================*/
-/* Constants */
-
-/*================================================================*/
-/* Macros */
-
-/*================================================================*/
-/* Types */
-
-/*================================================================*/
-/* Externs */
-
-/*================================================================*/
-/* Function Declarations */
-
-int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
+int p80211req_dorequest(wlandevice_t *wlandev, u8 *msgbuf);
#endif
diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h
index 5be6737e3e5..a22437ceddc 100644
--- a/drivers/staging/wlan-ng/p80211types.h
+++ b/drivers/staging/wlan-ng/p80211types.h
@@ -58,37 +58,9 @@
#define _P80211TYPES_H
/*================================================================*/
-/* System Includes */
-/*================================================================*/
-
-/*================================================================*/
/* Project Includes */
/*================================================================*/
-#ifndef _WLAN_COMPAT_H
-#include "wlan_compat.h"
-#endif
-
-/*================================================================*/
-/* Constants */
-/*================================================================*/
-
-/*----------------------------------------------------------------*/
-/* p80211 data type codes used for MIB items and message */
-/* arguments. The various metadata structures provide additional */
-/* information about these types. */
-
-#define P80211_TYPE_OCTETSTR 1 /* pascal array of bytes */
-#define P80211_TYPE_DISPLAYSTR 2 /* pascal array of bytes containing ascii */
-#define P80211_TYPE_int 4 /* u32 min and max limited by 32 bits */
-#define P80211_TYPE_ENUMint 5 /* u32 holding a numeric
- code that can be mapped
- to a textual name */
-#define P80211_TYPE_UNKDATA 6 /* Data item containing an
- unknown data type */
-#define P80211_TYPE_intARRAY 7 /* Array of 32-bit integers. */
-#define P80211_TYPE_BITARRAY 8 /* Array of bits. */
-#define P80211_TYPE_MACARRAY 9 /* Array of MAC addresses. */
/*----------------------------------------------------------------*/
/* The following constants are indexes into the Mib Category List */
@@ -106,25 +78,6 @@
/* Message Category List */
#define P80211_MSG_CAT_DOT11REQ 1
#define P80211_MSG_CAT_DOT11IND 2
-/* #define P80211_MSG_CAT_DOT11CFM 3 (doesn't exist at this time) */
-
-#define P80211SEC_DOT11REQ P80211_MSG_CAT_DOT11REQ
-#define P80211SEC_DOT11IND P80211_MSG_CAT_DOT11IND
-/* #define P80211SEC_DOT11CFM P80211_MSG_CAT_DOT11CFM (doesn't exist at this time */
-
-
-
-/*----------------------------------------------------------------*/
-/* p80211 DID field codes that represent access type and */
-/* is_table status. */
-
-#define P80211DID_ACCESS_READ 0x10000000
-#define P80211DID_ACCESS_WRITE 0x08000000
-#define P80211DID_WRITEONLY 0x00000001
-#define P80211DID_READONLY 0x00000002
-#define P80211DID_READWRITE 0x00000003
-#define P80211DID_ISTABLE_FALSE 0
-#define P80211DID_ISTABLE_TRUE 1
/*----------------------------------------------------------------*/
/* p80211 enumeration constants. The value to text mappings for */
@@ -132,104 +85,30 @@
/* from the mappings. */
/* error codes for lookups */
-#define P80211ENUM_BAD 0xffffffffUL
-#define P80211ENUM_BADSTR "P80211ENUM_BAD"
#define P80211ENUM_truth_false 0
#define P80211ENUM_truth_true 1
#define P80211ENUM_ifstate_disable 0
#define P80211ENUM_ifstate_fwload 1
#define P80211ENUM_ifstate_enable 2
-#define P80211ENUM_powermgmt_active 1
-#define P80211ENUM_powermgmt_powersave 2
#define P80211ENUM_bsstype_infrastructure 1
#define P80211ENUM_bsstype_independent 2
#define P80211ENUM_bsstype_any 3
#define P80211ENUM_authalg_opensystem 1
#define P80211ENUM_authalg_sharedkey 2
-#define P80211ENUM_phytype_fhss 1
-#define P80211ENUM_phytype_dsss 2
-#define P80211ENUM_phytype_irbaseband 3
-#define P80211ENUM_temptype_commercial 1
-#define P80211ENUM_temptype_industrial 2
-#define P80211ENUM_regdomain_fcc 16
-#define P80211ENUM_regdomain_doc 32
-#define P80211ENUM_regdomain_etsi 48
-#define P80211ENUM_regdomain_spain 49
-#define P80211ENUM_regdomain_france 50
-#define P80211ENUM_regdomain_mkk 64
-#define P80211ENUM_ccamode_edonly 1
-#define P80211ENUM_ccamode_csonly 2
-#define P80211ENUM_ccamode_edandcs 4
-#define P80211ENUM_ccamode_cswithtimer 8
-#define P80211ENUM_ccamode_hrcsanded 16
-#define P80211ENUM_diversity_fixedlist 1
-#define P80211ENUM_diversity_notsupported 2
-#define P80211ENUM_diversity_dynamic 3
#define P80211ENUM_scantype_active 1
-#define P80211ENUM_scantype_passive 2
-#define P80211ENUM_scantype_both 3
#define P80211ENUM_resultcode_success 1
#define P80211ENUM_resultcode_invalid_parameters 2
#define P80211ENUM_resultcode_not_supported 3
-#define P80211ENUM_resultcode_timeout 4
-#define P80211ENUM_resultcode_too_many_req 5
#define P80211ENUM_resultcode_refused 6
-#define P80211ENUM_resultcode_bss_already 7
-#define P80211ENUM_resultcode_invalid_access 8
-#define P80211ENUM_resultcode_invalid_mibattribute 9
#define P80211ENUM_resultcode_cant_set_readonly_mib 10
#define P80211ENUM_resultcode_implementation_failure 11
#define P80211ENUM_resultcode_cant_get_writeonly_mib 12
-#define P80211ENUM_reason_unspec_reason 1
-#define P80211ENUM_reason_auth_not_valid 2
-#define P80211ENUM_reason_deauth_lv_ss 3
-#define P80211ENUM_reason_inactivity 4
-#define P80211ENUM_reason_ap_overload 5
-#define P80211ENUM_reason_class23_err 6
-#define P80211ENUM_reason_class3_err 7
-#define P80211ENUM_reason_disas_lv_ss 8
-#define P80211ENUM_reason_asoc_not_auth 9
#define P80211ENUM_status_successful 0
#define P80211ENUM_status_unspec_failure 1
-#define P80211ENUM_status_unsup_cap 10
-#define P80211ENUM_status_reasoc_no_asoc 11
-#define P80211ENUM_status_fail_other 12
-#define P80211ENUM_status_unspt_alg 13
-#define P80211ENUM_status_auth_seq_fail 14
-#define P80211ENUM_status_chlng_fail 15
-#define P80211ENUM_status_auth_timeout 16
#define P80211ENUM_status_ap_full 17
-#define P80211ENUM_status_unsup_rate 18
-#define P80211ENUM_status_unsup_shortpreamble 19
-#define P80211ENUM_status_unsup_pbcc 20
-#define P80211ENUM_status_unsup_agility 21
#define P80211ENUM_msgitem_status_data_ok 0
#define P80211ENUM_msgitem_status_no_value 1
-#define P80211ENUM_msgitem_status_invalid_itemname 2
-#define P80211ENUM_msgitem_status_invalid_itemdata 3
-#define P80211ENUM_msgitem_status_missing_itemdata 4
-#define P80211ENUM_msgitem_status_incomplete_itemdata 5
-#define P80211ENUM_msgitem_status_invalid_msg_did 6
-#define P80211ENUM_msgitem_status_invalid_mib_did 7
-#define P80211ENUM_msgitem_status_missing_conv_func 8
-#define P80211ENUM_msgitem_status_string_too_long 9
-#define P80211ENUM_msgitem_status_data_out_of_range 10
-#define P80211ENUM_msgitem_status_string_too_short 11
-#define P80211ENUM_msgitem_status_missing_valid_func 12
-#define P80211ENUM_msgitem_status_unknown 13
-#define P80211ENUM_msgitem_status_invalid_did 14
-#define P80211ENUM_msgitem_status_missing_print_func 15
-
-#define P80211ENUM_lnxroam_reason_unknown 0
-#define P80211ENUM_lnxroam_reason_beacon 1
-#define P80211ENUM_lnxroam_reason_signal 2
-#define P80211ENUM_lnxroam_reason_txretry 3
-#define P80211ENUM_lnxroam_reason_notjoined 4
-
-#define P80211ENUM_p2preamble_long 0
-#define P80211ENUM_p2preamble_short 2
-#define P80211ENUM_p2preamble_mixed 3
/*----------------------------------------------------------------*/
/* p80211 max length constants for the different pascal strings. */
@@ -243,46 +122,6 @@
/* is a DID-LEN-DATA triple */
/* with a max size of 4+4+384 */
-#define P80211_SET_int(item, value) do { \
- (item).data = (value); \
- (item).status = P80211ENUM_msgitem_status_data_ok; \
- } while(0)
-/*----------------------------------------------------------------*/
-/* string constants */
-
-#define NOT_SET "NOT_SET"
-#define NOT_SUPPORTED "NOT_SUPPORTED"
-#define UNKNOWN_DATA "UNKNOWN_DATA"
-
-
-/*--------------------------------------------------------------------*/
-/* Metadata flags */
-
-/* MSM: Do these belong in p80211meta.h? I'm not sure. */
-
-#define ISREQUIRED (0x80000000UL)
-#define ISREQUEST (0x40000000UL)
-#define ISCONFIRM (0x20000000UL)
-
-
-/*================================================================*/
-/* Macros */
-
-/*--------------------------------------------------------------------*/
-/* The following macros are used to manipulate the 'flags' field in */
-/* the metadata. These are only used when the metadata is for */
-/* command arguments to determine if the data item is required, and */
-/* whether the metadata item is for a request command, confirm */
-/* command or both. */
-/*--------------------------------------------------------------------*/
-/* MSM: Do these belong in p80211meta.h? I'm not sure */
-
-#define P80211ITEM_SETFLAGS(q, r, c) ( q | r | c )
-
-#define P80211ITEM_ISREQUIRED(flags) (((u32)(flags & ISREQUIRED)) >> 31 )
-#define P80211ITEM_ISREQUEST(flags) (((u32)(flags & ISREQUEST)) >> 30 )
-#define P80211ITEM_ISCONFIRM(flags) (((u32)(flags & ISCONFIRM)) >> 29 )
-
/*----------------------------------------------------------------*/
/* The following macro creates a name for an enum */
@@ -302,9 +141,6 @@
* . - Unused
*/
-#define P80211DID_INVALID 0xffffffffUL
-#define P80211DID_VALID 0x00000000UL
-
#define P80211DID_LSB_SECTION (0)
#define P80211DID_LSB_GROUP (6)
#define P80211DID_LSB_ITEM (12)
@@ -319,35 +155,32 @@
#define P80211DID_MASK_ISTABLE (0x00000001UL)
#define P80211DID_MASK_ACCESS (0x00000003UL)
-
-#define P80211DID_MK(a,m,l) ((((u32)(a)) & (m)) << (l))
+#define P80211DID_MK(a, m, l) ((((u32)(a)) & (m)) << (l))
#define P80211DID_MKSECTION(a) P80211DID_MK(a, \
P80211DID_MASK_SECTION, \
- P80211DID_LSB_SECTION )
+ P80211DID_LSB_SECTION)
#define P80211DID_MKGROUP(a) P80211DID_MK(a, \
P80211DID_MASK_GROUP, \
- P80211DID_LSB_GROUP )
+ P80211DID_LSB_GROUP)
#define P80211DID_MKITEM(a) P80211DID_MK(a, \
P80211DID_MASK_ITEM, \
- P80211DID_LSB_ITEM )
+ P80211DID_LSB_ITEM)
#define P80211DID_MKINDEX(a) P80211DID_MK(a, \
P80211DID_MASK_INDEX, \
- P80211DID_LSB_INDEX )
+ P80211DID_LSB_INDEX)
#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \
P80211DID_MASK_ISTABLE, \
- P80211DID_LSB_ISTABLE )
-
+ P80211DID_LSB_ISTABLE)
#define P80211DID_MKID(s,g,i,n,t,a) (P80211DID_MKSECTION(s) | \
P80211DID_MKGROUP(g) | \
P80211DID_MKITEM(i) | \
P80211DID_MKINDEX(n) | \
P80211DID_MKISTABLE(t) | \
- (a) )
+ (a))
-
-#define P80211DID_GET(a,m,l) ((((u32)(a)) >> (l)) & (m))
+#define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m))
#define P80211DID_SECTION(a) P80211DID_GET(a, \
P80211DID_MASK_SECTION, \
@@ -368,23 +201,18 @@
P80211DID_MASK_ACCESS, \
P80211DID_LSB_ACCESS)
-/*================================================================*/
-/* Types */
-
/*----------------------------------------------------------------*/
/* The following structure types are used for the represenation */
/* of ENUMint type metadata. */
-typedef struct p80211enumpair
-{
- u32 val;
- char *name;
+typedef struct p80211enumpair {
+ u32 val;
+ char *name;
} p80211enumpair_t;
-typedef struct p80211enum
-{
- int nitems;
- p80211enumpair_t *list;
+typedef struct p80211enum {
+ int nitems;
+ p80211enumpair_t *list;
} p80211enum_t;
/*----------------------------------------------------------------*/
@@ -392,140 +220,123 @@ typedef struct p80211enum
/* messages. */
/* Template pascal string */
-typedef struct p80211pstr
-{
- u8 len;
-} __WLAN_ATTRIB_PACK__ p80211pstr_t;
+typedef struct p80211pstr {
+ u8 len;
+} __attribute__ ((packed)) p80211pstr_t;
-typedef struct p80211pstrd
-{
- u8 len;
- u8 data[0];
-} __WLAN_ATTRIB_PACK__ p80211pstrd_t;
+typedef struct p80211pstrd {
+ u8 len;
+ u8 data[0];
+} __attribute__ ((packed)) p80211pstrd_t;
/* Maximum pascal string */
-typedef struct p80211pstr255
-{
- u8 len;
- u8 data[MAXLEN_PSTR255];
-} __WLAN_ATTRIB_PACK__ p80211pstr255_t;
+typedef struct p80211pstr255 {
+ u8 len;
+ u8 data[MAXLEN_PSTR255];
+} __attribute__ ((packed)) p80211pstr255_t;
/* pascal string for macaddress and bssid */
-typedef struct p80211pstr6
-{
- u8 len;
- u8 data[MAXLEN_PSTR6];
-} __WLAN_ATTRIB_PACK__ p80211pstr6_t;
+typedef struct p80211pstr6 {
+ u8 len;
+ u8 data[MAXLEN_PSTR6];
+} __attribute__ ((packed)) p80211pstr6_t;
/* pascal string for channel list */
-typedef struct p80211pstr14
-{
- u8 len;
- u8 data[MAXLEN_PSTR14];
-} __WLAN_ATTRIB_PACK__ p80211pstr14_t;
+typedef struct p80211pstr14 {
+ u8 len;
+ u8 data[MAXLEN_PSTR14];
+} __attribute__ ((packed)) p80211pstr14_t;
/* pascal string for ssid */
-typedef struct p80211pstr32
-{
- u8 len;
- u8 data[MAXLEN_PSTR32];
-} __WLAN_ATTRIB_PACK__ p80211pstr32_t;
+typedef struct p80211pstr32 {
+ u8 len;
+ u8 data[MAXLEN_PSTR32];
+} __attribute__ ((packed)) p80211pstr32_t;
/* MAC address array */
-typedef struct p80211macarray
-{
- u32 cnt;
- u8 data[1][MAXLEN_PSTR6];
-} __WLAN_ATTRIB_PACK__ p80211macarray_t;
+typedef struct p80211macarray {
+ u32 cnt;
+ u8 data[1][MAXLEN_PSTR6];
+} __attribute__ ((packed)) p80211macarray_t;
/* prototype template */
-typedef struct p80211item
-{
- u32 did;
- u16 status;
- u16 len;
-} __WLAN_ATTRIB_PACK__ p80211item_t;
+typedef struct p80211item {
+ u32 did;
+ u16 status;
+ u16 len;
+} __attribute__ ((packed)) p80211item_t;
/* prototype template w/ data item */
-typedef struct p80211itemd
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[0];
-} __WLAN_ATTRIB_PACK__ p80211itemd_t;
+typedef struct p80211itemd {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[0];
+} __attribute__ ((packed)) p80211itemd_t;
/* message data item for int, BOUNDEDINT, ENUMINT */
-typedef struct p80211item_uint32
-{
- u32 did;
- u16 status;
- u16 len;
- u32 data;
-} __WLAN_ATTRIB_PACK__ p80211item_uint32_t;
+typedef struct p80211item_uint32 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u32 data;
+} __attribute__ ((packed)) p80211item_uint32_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr6
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr6_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr6_t;
+typedef struct p80211item_pstr6 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr6_t data;
+} __attribute__ ((packed)) p80211item_pstr6_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr14
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr14_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr14_t;
+typedef struct p80211item_pstr14 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr14_t data;
+} __attribute__ ((packed)) p80211item_pstr14_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr32
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr32_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr32_t;
+typedef struct p80211item_pstr32 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr32_t data;
+} __attribute__ ((packed)) p80211item_pstr32_t;
/* message data item for OCTETSTR, DISPLAYSTR */
-typedef struct p80211item_pstr255
-{
- u32 did;
- u16 status;
- u16 len;
- p80211pstr255_t data;
-} __WLAN_ATTRIB_PACK__ p80211item_pstr255_t;
+typedef struct p80211item_pstr255 {
+ u32 did;
+ u16 status;
+ u16 len;
+ p80211pstr255_t data;
+} __attribute__ ((packed)) p80211item_pstr255_t;
/* message data item for UNK 392, namely mib items */
-typedef struct p80211item_unk392
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[MAXLEN_MIBATTRIBUTE];
-} __WLAN_ATTRIB_PACK__ p80211item_unk392_t;
+typedef struct p80211item_unk392 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[MAXLEN_MIBATTRIBUTE];
+} __attribute__ ((packed)) p80211item_unk392_t;
/* message data item for UNK 1025, namely p2 pdas */
-typedef struct p80211item_unk1024
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[1024];
-} __WLAN_ATTRIB_PACK__ p80211item_unk1024_t;
+typedef struct p80211item_unk1024 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[1024];
+} __attribute__ ((packed)) p80211item_unk1024_t;
/* message data item for UNK 4096, namely p2 download chunks */
-typedef struct p80211item_unk4096
-{
- u32 did;
- u16 status;
- u16 len;
- u8 data[4096];
-} __WLAN_ATTRIB_PACK__ p80211item_unk4096_t;
+typedef struct p80211item_unk4096 {
+ u32 did;
+ u16 status;
+ u16 len;
+ u8 data[4096];
+} __attribute__ ((packed)) p80211item_unk4096_t;
struct catlistitem;
@@ -534,13 +345,11 @@ struct catlistitem;
/* metadata items. Some components may choose to use more, */
/* less or different metadata items. */
-typedef void (*p80211_totext_t)( struct catlistitem *, u32 did, u8* itembuf, char *textbuf);
-typedef void (*p80211_fromtext_t)( struct catlistitem *, u32 did, u8* itembuf, char *textbuf);
-typedef u32 (*p80211_valid_t)( struct catlistitem *, u32 did, u8* itembuf);
-
-
-/*================================================================*/
-/* Extern Declarations */
+typedef void (*p80211_totext_t) (struct catlistitem *, u32 did, u8 *itembuf,
+ char *textbuf);
+typedef void (*p80211_fromtext_t) (struct catlistitem *, u32 did, u8 *itembuf,
+ char *textbuf);
+typedef u32(*p80211_valid_t) (struct catlistitem *, u32 did, u8 *itembuf);
/*----------------------------------------------------------------*/
/* Enumeration Lists */
@@ -568,108 +377,4 @@ extern p80211enum_t MKENUMNAME(lnxroam_reason);
extern p80211enum_t MKENUMNAME(p2preamble);
-/*================================================================*/
-/* Function Declarations */
-
-/*----------------------------------------------------------------*/
-/* The following declare some utility functions for use with the */
-/* p80211enum_t type. */
-
-u32 p80211enum_text2int(p80211enum_t *ep, char *text);
-u32 p80211enum_int2text(p80211enum_t *ep, u32 val, char *text);
-void p80211_error2text(int err_code, char *err_str);
-
-/*----------------------------------------------------------------*/
-/* The following declare some utility functions for use with the */
-/* p80211item_t and p80211meta_t types. */
-
-/*----------------------------------------------------------------*/
-/* The following declare functions that perform validation and */
-/* text to binary conversions based on the metadata for interface */
-/* and MIB data items. */
-/*----------------------------------------------------------------*/
-
-/*-- DISPLAYSTR ------------------------------------------------------*/
-/* pstr ==> cstr */
-void p80211_totext_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* cstr ==> pstr */
-void p80211_fromtext_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a displaystr binary value */
-u32 p80211_isvalid_displaystr( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- OCTETSTR --------------------------------------------------------*/
-/* pstr ==> "xx:xx:...." */
-void p80211_totext_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* "xx:xx:...." ==> pstr */
-void p80211_fromtext_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an octetstr binary value */
-u32 p80211_isvalid_octetstr( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- int -------------------------------------------------------------*/
-/* u32 ==> %d */
-void p80211_totext_int( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d ==> u32 */
-void p80211_fromtext_int( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an int's binary value (always successful) */
-u32 p80211_isvalid_int( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- ENUMint ---------------------------------------------------------*/
-/* u32 ==> <valuename> */
-void p80211_totext_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* <valuename> ==> u32 */
-void p80211_fromtext_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an enum's binary value */
-u32 p80211_isvalid_enumint( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- intARRAY --------------------------------------------------------*/
-/* u32[] => %d,%d,%d,... */
-void p80211_totext_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d,%d,%d,... ==> u32[] */
-void p80211_fromtext_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of an integer array's value */
-u32 p80211_isvalid_intarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- BITARRAY --------------------------------------------------------*/
-/* u32 ==> %d,%d,%d,... */
-void p80211_totext_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* %d,%d,%d,... ==> u32 */
-void p80211_fromtext_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a bit array's value */
-u32 p80211_isvalid_bitarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- MACARRAY --------------------------------------------------------*/
-void p80211_totext_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-void p80211_fromtext_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a MAC address array's value */
-u32 p80211_isvalid_macarray( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
-/*-- MIBATTRIUBTE ------------------------------------------------------*/
-/* <mibvalue> ==> <textual representation identified in MIB metadata> */
-void p80211_totext_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-void p80211_totext_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-
-/* <textual representation identified in MIB metadata> ==> <mibvalue> */
-void p80211_fromtext_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-void p80211_fromtext_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf, char *textbuf );
-
-/* function that checks validity of a mibitem's binary value */
-u32 p80211_isvalid_getmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf );
-u32 p80211_isvalid_setmibattribute( struct catlistitem *metalist, u32 did, u8 *itembuf );
-
#endif /* _P80211TYPES_H */
-
diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c
index 46a2a6b3bdc..405ce89e4e6 100644
--- a/drivers/staging/wlan-ng/p80211wep.c
+++ b/drivers/staging/wlan-ng/p80211wep.c
@@ -55,8 +55,7 @@
#include <linux/wireless.h>
#include <linux/slab.h>
#include <linux/random.h>
-
-#include "wlan_compat.h"
+#include <linux/kernel.h>
// #define WEP_DEBUG
@@ -72,18 +71,9 @@
/*================================================================*/
/* Local Constants */
-#define SSWAP(a,b) {u8 tmp = s[a]; s[a] = s[b]; s[b] = tmp;}
#define WEP_KEY(x) (((x) & 0xC0) >> 6)
/*================================================================*/
-/* Local Macros */
-
-
-/*================================================================*/
-/* Local Types */
-
-
-/*================================================================*/
/* Local Static Definitions */
static const u32 wep_crc32_table[256] = {
@@ -211,7 +201,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *i
j = 0;
for (i = 0; i < 256; i++) {
j = (j + s[i] + key[i % keylen]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
}
/* Apply the RC4 to the data, update the CRC32 */
@@ -220,7 +210,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *i
for (k = 0; k < len; k++) {
i = (i+1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
buf[k] ^= s[(s[i] + s[j]) & 0xff];
crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
}
@@ -235,7 +225,7 @@ int wep_decrypt(wlandevice_t *wlandev, u8 *buf, u32 len, int key_override, u8 *i
for (k = 0; k < 4; k++) {
i = (i + 1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k])
return -(4 | (k << 4)) ; /* ICV mismatch */
}
@@ -283,7 +273,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8
j = 0;
for (i = 0; i < 256; i++) {
j = (j + s[i] + key[i % keylen]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
}
/* Update CRC32 then apply RC4 to the data */
@@ -293,7 +283,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8
crc = wep_crc32_table[(crc ^ buf[k]) & 0xff] ^ (crc >> 8);
i = (i+1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff];
}
crc = ~crc;
@@ -307,7 +297,7 @@ int wep_encrypt(wlandevice_t *wlandev, u8 *buf, u8 *dst, u32 len, int keynum, u8
for (k = 0; k < 4; k++) {
i = (i + 1) & 0xff;
j = (j+s[i]) & 0xff;
- SSWAP(i,j);
+ swap(i,j);
icv[k] ^= s[(s[i] + s[j]) & 0xff];
}
diff --git a/drivers/staging/wlan-ng/p80211wext.c b/drivers/staging/wlan-ng/p80211wext.c
index 0d570f1f378..96078b0ea6a 100644
--- a/drivers/staging/wlan-ng/p80211wext.c
+++ b/drivers/staging/wlan-ng/p80211wext.c
@@ -51,12 +51,12 @@
#include <asm/bitops.h>
#include <asm/uaccess.h>
#include <asm/byteorder.h>
+#include <linux/if_ether.h>
+#include <linux/bitops.h>
/*================================================================*/
/* Project Includes */
-#include "wlan_compat.h"
-
#include "p80211types.h"
#include "p80211hdr.h"
#include "p80211conv.h"
@@ -77,16 +77,14 @@ static int p80211wext_giwessid(netdevice_t *dev,
static u8 p80211_mhz_to_channel(u16 mhz)
{
- if (mhz >= 5000) {
- return ((mhz - 5000) / 5);
- }
+ if (mhz >= 5000)
+ return (mhz - 5000) / 5;
if (mhz == 2482)
return 14;
- if (mhz >= 2407) {
- return ((mhz - 2407) / 5);
- }
+ if (mhz >= 2407)
+ return (mhz - 2407) / 5;
return 0;
}
@@ -100,19 +98,15 @@ static u16 p80211_channel_to_mhz(u8 ch, int dot11a)
return 0;
/* 5G */
-
- if (dot11a) {
- return (5000 + (5 * ch));
- }
+ if (dot11a)
+ return 5000 + (5 * ch);
/* 2.4G */
-
if (ch == 14)
return 2484;
- if ((ch < 14) && (ch > 0)) {
- return (2407 + (5 * ch));
- }
+ if ((ch < 14) && (ch > 0))
+ return 2407 + (5 * ch);
return 0;
}
@@ -122,54 +116,46 @@ static const long p80211wext_channel_freq[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484
};
-#define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
-
-/* steal a spare bit to store the shared/opensystems state. should default to open if not set */
-#define HOSTWEP_SHAREDKEY BIT3
+#define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
-/** function declarations =============== */
+/* steal a spare bit to store the shared/opensystems state.
+ should default to open if not set */
+#define HOSTWEP_SHAREDKEY BIT(3)
-static int qual_as_percent(int snr ) {
- if ( snr <= 0 )
- return 0;
- if ( snr <= 40 )
- return snr*5/2;
- return 100;
+static int qual_as_percent(int snr)
+{
+ if (snr <= 0)
+ return 0;
+ if (snr <= 40)
+ return snr * 5 / 2;
+ return 100;
}
-
-
-
static int p80211wext_dorequest(wlandevice_t *wlandev, u32 did, u32 data)
{
- p80211msg_dot11req_mibset_t msg;
- p80211item_uint32_t mibitem;
- int result;
-
- DBFENTER;
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ int result;
msg.msgcode = DIDmsg_dot11req_mibset;
mibitem.did = did;
mibitem.data = data;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
- DBFEXIT;
return result;
}
static int p80211wext_autojoin(wlandevice_t *wlandev)
{
- p80211msg_lnxreq_autojoin_t msg;
- struct iw_point data;
+ p80211msg_lnxreq_autojoin_t msg;
+ struct iw_point data;
char ssid[IW_ESSID_MAX_SIZE];
int result;
int err = 0;
- DBFENTER;
-
/* Get ESSID */
result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);
@@ -178,23 +164,22 @@ static int p80211wext_autojoin(wlandevice_t *wlandev)
goto exit;
}
- if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
- msg.authtype.data = P80211ENUM_authalg_sharedkey;
+ if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
+ msg.authtype.data = P80211ENUM_authalg_sharedkey;
else
- msg.authtype.data = P80211ENUM_authalg_opensystem;
+ msg.authtype.data = P80211ENUM_authalg_opensystem;
msg.msgcode = DIDmsg_lnxreq_autojoin;
/* Trim the last '\0' to fit the SSID format */
- if (data.length && ssid[data.length-1] == '\0') {
+ if (data.length && ssid[data.length - 1] == '\0')
data.length = data.length - 1;
- }
memcpy(msg.ssid.data.data, ssid, data.length);
msg.ssid.data.len = data.length;
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -203,22 +188,20 @@ static int p80211wext_autojoin(wlandevice_t *wlandev)
exit:
- DBFEXIT;
return err;
}
/* called by /proc/net/wireless */
-struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
+struct iw_statistics *p80211wext_get_wireless_stats(netdevice_t * dev)
{
- p80211msg_lnxreq_commsquality_t quality;
+ p80211msg_lnxreq_commsquality_t quality;
wlandevice_t *wlandev = dev->ml_priv;
- struct iw_statistics* wstats = &wlandev->wstats;
+ struct iw_statistics *wstats = &wlandev->wstats;
int retval;
- DBFENTER;
/* Check */
- if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )
+ if ((wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING))
return NULL;
/* XXX Only valid in station mode */
@@ -230,26 +213,24 @@ struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
/* send message to nsd */
- if ( wlandev->mlmerequest == NULL )
+ if (wlandev->mlmerequest == NULL)
return NULL;
- retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);
+ retval = wlandev->mlmerequest(wlandev, (p80211msg_t *)&quality);
- wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
- wstats->qual.level = quality.level.data; /* instant signal level */
- wstats->qual.noise = quality.noise.data; /* instant noise level */
+ wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
+ wstats->qual.level = quality.level.data; /* instant signal level */
+ wstats->qual.noise = quality.noise.data; /* instant noise level */
wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
wstats->discard.code = wlandev->rx.decrypt_err;
wstats->discard.nwid = 0;
wstats->discard.misc = 0;
- wstats->discard.fragment = 0; // incomplete fragments
- wstats->discard.retries = 0; // tx retries.
+ wstats->discard.fragment = 0; /* incomplete fragments */
+ wstats->discard.retries = 0; /* tx retries. */
wstats->miss.beacon = 0;
- DBFEXIT;
-
return wstats;
}
@@ -261,8 +242,6 @@ static int p80211wext_giwname(netdevice_t *dev,
int result;
int err = 0;
- DBFENTER;
-
result = p80211wext_giwrate(dev, NULL, &rate, NULL);
if (result) {
@@ -281,7 +260,6 @@ static int p80211wext_giwname(netdevice_t *dev,
break;
}
exit:
- DBFEXIT;
return err;
}
@@ -290,17 +268,15 @@ static int p80211wext_giwfreq(netdevice_t *dev,
struct iw_freq *freq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -318,8 +294,7 @@ static int p80211wext_giwfreq(netdevice_t *dev,
freq->e = 1;
freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000;
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -328,13 +303,11 @@ static int p80211wext_siwfreq(netdevice_t *dev,
struct iw_freq *freq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -344,21 +317,20 @@ static int p80211wext_siwfreq(netdevice_t *dev,
mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
mibitem.status = P80211ENUM_msgitem_status_data_ok;
- if ( (freq->e == 0) && (freq->m <= 1000) )
+ if ((freq->e == 0) && (freq->m <= 1000))
mibitem.data = freq->m;
else
mibitem.data = p80211_mhz_to_channel(freq->m);
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -368,8 +340,6 @@ static int p80211wext_giwmode(netdevice_t *dev,
{
wlandevice_t *wlandev = dev->ml_priv;
- DBFENTER;
-
switch (wlandev->macmode) {
case WLAN_MACMODE_IBSS_STA:
*mode = IW_MODE_ADHOC;
@@ -385,7 +355,6 @@ static int p80211wext_giwmode(netdevice_t *dev,
*mode = IW_MODE_AUTO;
}
- DBFEXIT;
return 0;
}
@@ -394,12 +363,10 @@ static int p80211wext_siwmode(netdevice_t *dev,
__u32 *mode, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
- int result;
- int err = 0;
-
- DBFENTER;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
@@ -428,7 +395,7 @@ static int p80211wext_siwmode(netdevice_t *dev,
break;
default:
/* Not set yet. */
- WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);
+ printk(KERN_INFO "Operation mode: %d not support\n", *mode);
return -EOPNOTSUPP;
}
@@ -437,33 +404,28 @@ static int p80211wext_siwmode(netdevice_t *dev,
mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result)
err = -EFAULT;
- exit:
- DBFEXIT;
-
+exit:
return err;
}
-
static int p80211wext_giwrange(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *extra)
{
- struct iw_range *range = (struct iw_range *) extra;
+ struct iw_range *range = (struct iw_range *)extra;
int i, val;
- DBFENTER;
-
- // for backward compatability set size & zero everything we don't understand
+ /* for backward compatability set size and zero everything we don't understand */
data->length = sizeof(*range);
- memset(range,0,sizeof(*range));
+ memset(range, 0, sizeof(*range));
range->txpower_capa = IW_TXPOW_DBM;
- // XXX what about min/max_pmp, min/max_pmt, etc.
+ /* XXX what about min/max_pmp, min/max_pmt, etc. */
range->we_version_compiled = WIRELESS_EXT;
range->we_version_source = 13;
@@ -473,18 +435,18 @@ static int p80211wext_giwrange(netdevice_t *dev,
range->min_retry = 0;
range->max_retry = 255;
- range->event_capa[0] = (IW_EVENT_CAPA_K_0 | //mode/freq/ssid
- IW_EVENT_CAPA_MASK(SIOCGIWAP) |
- IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
- range->event_capa[1] = IW_EVENT_CAPA_K_1; //encode
- range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
- IW_EVENT_CAPA_MASK(IWEVCUSTOM) );
+ range->event_capa[0] = (IW_EVENT_CAPA_K_0 | /* mode/freq/ssid */
+ IW_EVENT_CAPA_MASK(SIOCGIWAP) |
+ IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
+ range->event_capa[1] = IW_EVENT_CAPA_K_1; /* encode */
+ range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
+ IW_EVENT_CAPA_MASK(IWEVCUSTOM));
range->num_channels = NUM_CHANNELS;
/* XXX need to filter against the regulatory domain &| active set */
val = 0;
- for (i = 0; i < NUM_CHANNELS ; i++) {
+ for (i = 0; i < NUM_CHANNELS; i++) {
range->freq[val].i = i + 1;
range->freq[val].m = p80211wext_channel_freq[i] * 100000;
range->freq[val].e = 1;
@@ -498,7 +460,7 @@ static int p80211wext_giwrange(netdevice_t *dev,
range->max_qual.level = 0;
range->max_qual.noise = 0;
range->sensitivity = 3;
- // XXX these need to be nsd-specific!
+ /* XXX these need to be nsd-specific! */
range->min_rts = 0;
range->max_rts = 2347;
@@ -510,14 +472,13 @@ static int p80211wext_giwrange(netdevice_t *dev,
range->encoding_size[0] = 5;
range->encoding_size[1] = 13;
- // XXX what about num_bitrates/throughput?
+ /* XXX what about num_bitrates/throughput? */
range->num_bitrates = 0;
/* estimated max throughput */
- // XXX need to cap it if we're running at ~2Mbps..
+ /* XXX need to cap it if we're running at ~2Mbps.. */
range->throughput = 5500000;
- DBFEXIT;
return 0;
}
@@ -528,12 +489,9 @@ static int p80211wext_giwap(netdevice_t *dev,
wlandevice_t *wlandev = dev->ml_priv;
- DBFENTER;
-
memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
ap_addr->sa_family = ARPHRD_ETHER;
- DBFEXIT;
return 0;
}
@@ -545,8 +503,6 @@ static int p80211wext_giwencode(netdevice_t *dev,
int err = 0;
int i;
- DBFENTER;
-
i = (erq->flags & IW_ENCODE_INDEX) - 1;
erq->flags = 0;
@@ -576,8 +532,7 @@ static int p80211wext_giwencode(netdevice_t *dev,
erq->length = wlandev->wep_keylens[i];
memcpy(key, wlandev->wep_keys[i], erq->length);
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -586,32 +541,33 @@ static int p80211wext_siwencode(netdevice_t *dev,
struct iw_point *erq, char *key)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_dot11req_mibset_t msg;
- p80211item_pstr32_t pstr;
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_pstr32_t pstr;
int err = 0;
int result = 0;
int i;
- DBFENTER;
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
/* Check the Key index first. */
- if((i = (erq->flags & IW_ENCODE_INDEX))) {
+ if ((i = (erq->flags & IW_ENCODE_INDEX))) {
if ((i < 1) || (i > NUM_WEPKEYS)) {
err = -EINVAL;
goto exit;
- }
- else
+ } else
i--;
/* Set current key number only if no keys are given */
if (erq->flags & IW_ENCODE_NOKEY) {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+ i);
if (result) {
err = -EFAULT;
@@ -620,12 +576,12 @@ static int p80211wext_siwencode(netdevice_t *dev,
}
} else {
- // Use defaultkey if no Key Index
+ /* Use defaultkey if no Key Index */
i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
}
/* Check if there is no key information in the iwconfig request */
- if((erq->flags & IW_ENCODE_NOKEY) == 0 ) {
+ if ((erq->flags & IW_ENCODE_NOKEY) == 0) {
/*------------------------------------------------------------
* If there is WEP Key for setting, check the Key Information
@@ -642,32 +598,35 @@ static int p80211wext_siwencode(netdevice_t *dev,
memcpy(pstr.data.data, key, erq->length);
pstr.data.len = erq->length;
- switch(i)
- {
- case 0:
- pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
- break;
-
- case 1:
- pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
- break;
-
- case 2:
- pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
- break;
-
- case 3:
- pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
- break;
-
- default:
- err = -EINVAL;
- goto exit;
+ switch (i) {
+ case 0:
+ pstr.did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+ break;
+
+ case 1:
+ pstr.did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+ break;
+
+ case 2:
+ pstr.did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+ break;
+
+ case 3:
+ pstr.did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+ break;
+
+ default:
+ err = -EINVAL;
+ goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibset;
memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -679,9 +638,15 @@ static int p80211wext_siwencode(netdevice_t *dev,
/* Check the PrivacyInvoked flag */
if (erq->flags & IW_ENCODE_DISABLED) {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ P80211ENUM_truth_false);
} else {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ P80211ENUM_truth_true);
}
if (result) {
@@ -690,17 +655,22 @@ static int p80211wext_siwencode(netdevice_t *dev,
}
/* The security mode may be open or restricted, and its meaning
- depends on the card used. With most cards, in open mode no
- authentication is used and the card may also accept non-
- encrypted sessions, whereas in restricted mode only encrypted
- sessions are accepted and the card will use authentication if
- available.
- */
+ depends on the card used. With most cards, in open mode no
+ authentication is used and the card may also accept non-
+ encrypted sessions, whereas in restricted mode only encrypted
+ sessions are accepted and the card will use authentication if
+ available.
+ */
if (erq->flags & IW_ENCODE_RESTRICTED) {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
- }
- else if (erq->flags & IW_ENCODE_OPEN) {
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+ P80211ENUM_truth_true);
+ } else if (erq->flags & IW_ENCODE_OPEN) {
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+ P80211ENUM_truth_false);
}
if (result) {
@@ -708,9 +678,8 @@ static int p80211wext_siwencode(netdevice_t *dev,
goto exit;
}
- exit:
+exit:
- DBFEXIT;
return err;
}
@@ -720,8 +689,6 @@ static int p80211wext_giwessid(netdevice_t *dev,
{
wlandevice_t *wlandev = dev->ml_priv;
- DBFENTER;
-
if (wlandev->ssid.len) {
data->length = wlandev->ssid.len;
data->flags = 1;
@@ -731,12 +698,11 @@ static int p80211wext_giwessid(netdevice_t *dev,
data->length++;
#endif
} else {
- memset(essid, 0, sizeof(wlandev->ssid.data));
+ memset(essid, 0, sizeof(wlandev->ssid.data));
data->length = 0;
data->flags = 0;
}
- DBFEXIT;
return 0;
}
@@ -745,55 +711,49 @@ static int p80211wext_siwessid(netdevice_t *dev,
struct iw_point *data, char *essid)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_lnxreq_autojoin_t msg;
+ p80211msg_lnxreq_autojoin_t msg;
int result;
int err = 0;
int length = data->length;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
-
- if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
- msg.authtype.data = P80211ENUM_authalg_sharedkey;
+ if (wlandev->hostwep & HOSTWEP_SHAREDKEY)
+ msg.authtype.data = P80211ENUM_authalg_sharedkey;
else
- msg.authtype.data = P80211ENUM_authalg_opensystem;
+ msg.authtype.data = P80211ENUM_authalg_opensystem;
msg.msgcode = DIDmsg_lnxreq_autojoin;
#if (WIRELESS_EXT < 21)
- if (length) length--;
+ if (length)
+ length--;
#endif
/* Trim the last '\0' to fit the SSID format */
-
- if (length && essid[length-1] == '\0') {
- length--;
- }
+ if (length && essid[length - 1] == '\0')
+ length--;
memcpy(msg.ssid.data.data, essid, length);
msg.ssid.data.len = length;
- WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid);
- result = p80211req_dorequest(wlandev, (u8*)&msg);
- WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result);
+ pr_debug("autojoin_ssid for %s \n", essid);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
+ pr_debug("autojoin_ssid %d\n", result);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
-
static int p80211wext_siwcommit(netdevice_t *dev,
struct iw_request_info *info,
struct iw_point *data, char *essid)
@@ -801,8 +761,6 @@ static int p80211wext_siwcommit(netdevice_t *dev,
wlandevice_t *wlandev = dev->ml_priv;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -811,28 +769,24 @@ static int p80211wext_siwcommit(netdevice_t *dev,
/* Auto Join */
err = p80211wext_autojoin(wlandev);
- exit:
- DBFEXIT;
+exit:
return err;
}
-
static int p80211wext_giwrate(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -841,7 +795,7 @@ static int p80211wext_giwrate(netdevice_t *dev,
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
- rrq->fixed = 0; /* can it change? */
+ rrq->fixed = 0; /* can it change? */
rrq->disabled = 0;
rrq->value = 0;
@@ -866,8 +820,7 @@ static int p80211wext_giwrate(netdevice_t *dev,
default:
err = -EINVAL;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -876,17 +829,15 @@ static int p80211wext_giwrts(netdevice_t *dev,
struct iw_param *rts, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -899,24 +850,20 @@ static int p80211wext_giwrts(netdevice_t *dev,
rts->disabled = (rts->value == 2347);
rts->fixed = 1;
- exit:
- DBFEXIT;
+exit:
return err;
}
-
static int p80211wext_siwrts(netdevice_t *dev,
struct iw_request_info *info,
struct iw_param *rts, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -930,15 +877,14 @@ static int p80211wext_siwrts(netdevice_t *dev,
mibitem.data = rts->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -947,17 +893,16 @@ static int p80211wext_giwfrag(netdevice_t *dev,
struct iw_param *frag, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
msg.msgcode = DIDmsg_dot11req_mibget;
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -970,8 +915,7 @@ static int p80211wext_giwfrag(netdevice_t *dev,
frag->disabled = (frag->value == 2346);
frag->fixed = 1;
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -980,20 +924,19 @@ static int p80211wext_siwfrag(netdevice_t *dev,
struct iw_param *frag, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
}
msg.msgcode = DIDmsg_dot11req_mibset;
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
if (frag->disabled)
mibitem.data = 2346;
@@ -1001,15 +944,14 @@ static int p80211wext_siwfrag(netdevice_t *dev,
mibitem.data = frag->value;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
goto exit;
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -1026,19 +968,17 @@ static int p80211wext_giwretry(netdevice_t *dev,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
u16 shortretry, longretry, lifetime;
- DBFENTER;
-
msg.msgcode = DIDmsg_dot11req_mibget;
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1052,7 +992,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1063,10 +1003,11 @@ static int p80211wext_giwretry(netdevice_t *dev,
longretry = mibitem.data;
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1094,8 +1035,7 @@ static int p80211wext_giwretry(netdevice_t *dev,
}
}
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -1105,13 +1045,11 @@ static int p80211wext_siwretry(netdevice_t *dev,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
if (!wlan_wext_write) {
err = (-EOPNOTSUPP);
goto exit;
@@ -1125,11 +1063,12 @@ static int p80211wext_siwretry(netdevice_t *dev,
msg.msgcode = DIDmsg_dot11req_mibset;
if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
- mibitem.data = rrq->value /= 1024;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
+ mibitem.data = rrq->value /= 1024;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1137,11 +1076,13 @@ static int p80211wext_siwretry(netdevice_t *dev,
}
} else {
if (rrq->flags & IW_RETRY_LONG) {
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
mibitem.data = rrq->value;
- memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ memcpy(&msg.mibattribute.data, &mibitem,
+ sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1150,11 +1091,13 @@ static int p80211wext_siwretry(netdevice_t *dev,
}
if (rrq->flags & IW_RETRY_SHORT) {
- mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
+ mibitem.did =
+ DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
mibitem.data = rrq->value;
- memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ memcpy(&msg.mibattribute.data, &mibitem,
+ sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1163,46 +1106,43 @@ static int p80211wext_siwretry(netdevice_t *dev,
}
}
- exit:
- DBFEXIT;
+exit:
return err;
}
static int p80211wext_siwtxpow(netdevice_t *dev,
- struct iw_request_info *info,
- struct iw_param *rrq, char *extra)
+ struct iw_request_info *info,
+ struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
- int result;
- int err = 0;
-
- DBFENTER;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
+ int result;
+ int err = 0;
- if (!wlan_wext_write) {
- err = (-EOPNOTSUPP);
- goto exit;
- }
+ if (!wlan_wext_write) {
+ err = (-EOPNOTSUPP);
+ goto exit;
+ }
- msg.msgcode = DIDmsg_dot11req_mibset;
- mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ mibitem.did =
+ DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
if (rrq->fixed == 0)
- mibitem.data = 30;
+ mibitem.data = 30;
else
- mibitem.data = rrq->value;
- memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
-
- if (result) {
- err = -EFAULT;
- goto exit;
- }
-
- exit:
- DBFEXIT;
- return err;
+ mibitem.data = rrq->value;
+ memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
+
+ if (result) {
+ err = -EFAULT;
+ goto exit;
+ }
+
+exit:
+ return err;
}
static int p80211wext_giwtxpow(netdevice_t *dev,
@@ -1210,18 +1150,17 @@ static int p80211wext_giwtxpow(netdevice_t *dev,
struct iw_param *rrq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211item_uint32_t mibitem;
- p80211msg_dot11req_mibset_t msg;
+ p80211item_uint32_t mibitem;
+ p80211msg_dot11req_mibset_t msg;
int result;
int err = 0;
- DBFENTER;
-
msg.msgcode = DIDmsg_dot11req_mibget;
- mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
+ mibitem.did =
+ DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result) {
err = -EFAULT;
@@ -1230,15 +1169,14 @@ static int p80211wext_giwtxpow(netdevice_t *dev,
memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
- // XXX handle OFF by setting disabled = 1;
+ /* XXX handle OFF by setting disabled = 1; */
- rrq->flags = 0; // IW_TXPOW_DBM;
+ rrq->flags = 0; /* IW_TXPOW_DBM; */
rrq->disabled = 0;
rrq->fixed = 0;
rrq->value = mibitem.data;
- exit:
- DBFEXIT;
+exit:
return err;
}
@@ -1247,33 +1185,32 @@ static int p80211wext_siwspy(netdevice_t *dev,
struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- struct sockaddr address[IW_MAX_SPY];
- int number = srq->length;
- int i;
-
- DBFENTER;
+ struct sockaddr address[IW_MAX_SPY];
+ int number = srq->length;
+ int i;
/* Copy the data from the input buffer */
- memcpy(address, extra, sizeof(struct sockaddr)*number);
+ memcpy(address, extra, sizeof(struct sockaddr) * number);
- wlandev->spy_number = 0;
+ wlandev->spy_number = 0;
- if (number > 0) {
+ if (number > 0) {
- /* extract the addresses */
- for (i = 0; i < number; i++) {
+ /* extract the addresses */
+ for (i = 0; i < number; i++) {
- memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);
+ memcpy(wlandev->spy_address[i], address[i].sa_data,
+ ETH_ALEN);
}
- /* reset stats */
- memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
+ /* reset stats */
+ memset(wlandev->spy_stat, 0,
+ sizeof(struct iw_quality) * IW_MAX_SPY);
- /* set number of addresses */
- wlandev->spy_number = number;
- }
+ /* set number of addresses */
+ wlandev->spy_number = number;
+ }
- DBFEXIT;
return 0;
}
@@ -1284,74 +1221,72 @@ static int p80211wext_giwspy(netdevice_t *dev,
{
wlandevice_t *wlandev = dev->ml_priv;
- struct sockaddr address[IW_MAX_SPY];
- struct iw_quality spy_stat[IW_MAX_SPY];
- int number;
- int i;
-
- DBFENTER;
+ struct sockaddr address[IW_MAX_SPY];
+ struct iw_quality spy_stat[IW_MAX_SPY];
+ int number;
+ int i;
- number = wlandev->spy_number;
+ number = wlandev->spy_number;
- if (number > 0) {
+ if (number > 0) {
- /* populate address and spy struct's */
- for (i = 0; i < number; i++) {
- memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN);
- address[i].sa_family = AF_UNIX;
- memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality));
- }
+ /* populate address and spy struct's */
+ for (i = 0; i < number; i++) {
+ memcpy(address[i].sa_data, wlandev->spy_address[i],
+ ETH_ALEN);
+ address[i].sa_family = AF_UNIX;
+ memcpy(&spy_stat[i], &wlandev->spy_stat[i],
+ sizeof(struct iw_quality));
+ }
/* reset update flag */
- for (i=0; i < number; i++)
- wlandev->spy_stat[i].updated = 0;
- }
+ for (i = 0; i < number; i++)
+ wlandev->spy_stat[i].updated = 0;
+ }
- /* push stuff to user space */
- srq->length = number;
- memcpy(extra, address, sizeof(struct sockaddr)*number);
- memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number);
+ /* push stuff to user space */
+ srq->length = number;
+ memcpy(extra, address, sizeof(struct sockaddr) * number);
+ memcpy(extra + sizeof(struct sockaddr) * number, spy_stat,
+ sizeof(struct iw_quality) * number);
- DBFEXIT;
return 0;
}
-static int prism2_result2err (int prism2_result)
+static int prism2_result2err(int prism2_result)
{
int err = 0;
switch (prism2_result) {
- case P80211ENUM_resultcode_invalid_parameters:
- err = -EINVAL;
- break;
- case P80211ENUM_resultcode_implementation_failure:
- err = -EIO;
- break;
- case P80211ENUM_resultcode_not_supported:
- err = -EOPNOTSUPP;
- break;
- default:
- err = 0;
- break;
+ case P80211ENUM_resultcode_invalid_parameters:
+ err = -EINVAL;
+ break;
+ case P80211ENUM_resultcode_implementation_failure:
+ err = -EIO;
+ break;
+ case P80211ENUM_resultcode_not_supported:
+ err = -EOPNOTSUPP;
+ break;
+ default:
+ err = 0;
+ break;
}
return err;
}
static int p80211wext_siwscan(netdevice_t *dev,
- struct iw_request_info *info,
- struct iw_point *srq, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_dot11req_scan_t msg;
+ p80211msg_dot11req_scan_t msg;
int result;
int err = 0;
int i = 0;
- DBFENTER;
-
if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
- WLAN_LOG_ERROR("Can't scan in AP mode\n");
+ printk(KERN_ERR "Can't scan in AP mode\n");
err = (-EOPNOTSUPP);
goto exit;
}
@@ -1360,36 +1295,34 @@ static int p80211wext_siwscan(netdevice_t *dev,
msg.msgcode = DIDmsg_dot11req_scan;
msg.bsstype.data = P80211ENUM_bsstype_any;
- memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));
+ memset(&(msg.bssid.data), 0xFF, sizeof(p80211item_pstr6_t));
msg.bssid.data.len = 6;
msg.scantype.data = P80211ENUM_scantype_active;
msg.probedelay.data = 0;
for (i = 1; i <= 14; i++)
- msg.channellist.data.data[i-1] = i;
+ msg.channellist.data.data[i - 1] = i;
msg.channellist.data.len = 14;
msg.maxchanneltime.data = 250;
msg.minchanneltime.data = 200;
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if (result)
- err = prism2_result2err (msg.resultcode.data);
+ err = prism2_result2err(msg.resultcode.data);
- exit:
- DBFEXIT;
+exit:
return err;
}
-
/* Helper to translate scan into Wireless Extensions scan results.
* Inspired by the prism54 code, which was in turn inspired by the
* airo driver code.
*/
-static char *
-wext_translate_bss(struct iw_request_info *info, char *current_ev,
- char *end_buf, p80211msg_dot11req_scan_results_t *bss)
+static char *wext_translate_bss(struct iw_request_info *info, char *current_ev,
+ char *end_buf,
+ p80211msg_dot11req_scan_results_t *bss)
{
struct iw_event iwe; /* Temporary buffer */
@@ -1397,7 +1330,9 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev =
+ iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+ IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */
@@ -1406,33 +1341,39 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
char essid[IW_ESSID_MAX_SIZE + 1];
int size;
- size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len);
- memset(&essid, 0, sizeof (essid));
+ size =
+ min_t(unsigned short, IW_ESSID_MAX_SIZE,
+ bss->ssid.data.len);
+ memset(&essid, 0, sizeof(essid));
memcpy(&essid, bss->ssid.data.data, size);
- WLAN_LOG_DEBUG(1, " essid size = %d\n", size);
+ pr_debug(" essid size = %d\n", size);
iwe.u.data.length = size;
iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]);
- WLAN_LOG_DEBUG(1, " essid size OK.\n");
+ current_ev =
+ iwe_stream_add_point(info, current_ev, end_buf, &iwe,
+ &essid[0]);
+ pr_debug(" essid size OK.\n");
}
switch (bss->bsstype.data) {
- case P80211ENUM_bsstype_infrastructure:
- iwe.u.mode = IW_MODE_MASTER;
- break;
+ case P80211ENUM_bsstype_infrastructure:
+ iwe.u.mode = IW_MODE_MASTER;
+ break;
- case P80211ENUM_bsstype_independent:
- iwe.u.mode = IW_MODE_ADHOC;
- break;
+ case P80211ENUM_bsstype_independent:
+ iwe.u.mode = IW_MODE_ADHOC;
+ break;
- default:
- iwe.u.mode = 0;
- break;
+ default:
+ iwe.u.mode = 0;
+ break;
}
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev =
+ iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+ IW_EV_UINT_LEN);
/* Encryption capability */
if (bss->privacy.data == P80211ENUM_truth_true)
@@ -1441,13 +1382,16 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE;
- current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
+ current_ev =
+ iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->dschannel.data;
iwe.u.freq.e = 0;
iwe.cmd = SIOCGIWFREQ;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev =
+ iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+ IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.u.qual.level = bss->signal.data;
@@ -1455,26 +1399,25 @@ wext_translate_bss(struct iw_request_info *info, char *current_ev,
/* do a simple SNR for quality */
iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data);
iwe.cmd = IWEVQUAL;
- current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev =
+ iwe_stream_add_event(info, current_ev, end_buf, &iwe,
+ IW_EV_QUAL_LEN);
return current_ev;
}
-
static int p80211wext_giwscan(netdevice_t *dev,
- struct iw_request_info *info,
- struct iw_point *srq, char *extra)
+ struct iw_request_info *info,
+ struct iw_point *srq, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
- p80211msg_dot11req_scan_results_t msg;
+ p80211msg_dot11req_scan_results_t msg;
int result = 0;
int err = 0;
int i = 0;
int scan_good = 0;
char *current_ev = extra;
- DBFENTER;
-
/* Since wireless tools doesn't really have a way of passing how
* many scan results results there were back here, keep grabbing them
* until we fail.
@@ -1484,110 +1427,115 @@ static int p80211wext_giwscan(netdevice_t *dev,
msg.msgcode = DIDmsg_dot11req_scan_results;
msg.bssindex.data = i;
- result = p80211req_dorequest(wlandev, (u8*)&msg);
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
if ((result != 0) ||
(msg.resultcode.data != P80211ENUM_resultcode_success)) {
break;
}
- current_ev = wext_translate_bss(info, current_ev, extra + IW_SCAN_MAX_DATA, &msg);
+ current_ev =
+ wext_translate_bss(info, current_ev,
+ extra + IW_SCAN_MAX_DATA, &msg);
scan_good = 1;
i++;
} while (i < IW_MAX_AP);
srq->length = (current_ev - extra);
- srq->flags = 0; /* todo */
+ srq->flags = 0; /* todo */
if (result && !scan_good)
- err = prism2_result2err (msg.resultcode.data);
+ err = prism2_result2err(msg.resultcode.data);
- DBFEXIT;
return err;
}
-/*****************************************************/
-//extra wireless extensions stuff to support NetworkManager (I hope)
+/* extra wireless extensions stuff to support NetworkManager (I hope) */
/* SIOCSIWENCODEEXT */
static int p80211wext_set_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
- wlandevice_t *wlandev = dev->ml_priv;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- p80211msg_dot11req_mibset_t msg;
- p80211item_pstr32_t *pstr;
-
- int result = 0;
- struct iw_point *encoding = &wrqu->encoding;
- int idx = encoding->flags & IW_ENCODE_INDEX;
-
- WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
-
-
- if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) {
- // set default key ? I'm not sure if this the the correct thing to do here
-
- if ( idx ) {
- if (idx < 1 || idx > NUM_WEPKEYS) {
- return -EINVAL;
- } else
- idx--;
- }
- WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx);
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx);
- if ( result )
- return -EFAULT;
- }
-
-
- if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) {
- if (!(ext->alg & IW_ENCODE_ALG_WEP)) {
- WLAN_LOG_DEBUG(1,"asked to set a non wep key :(");
- return -EINVAL;
- }
- if (idx) {
- if (idx <1 || idx > NUM_WEPKEYS)
- return -EINVAL;
- else
- idx--;
- }
- WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx);
- wlandev->wep_keylens[idx] = ext->key_len;
- memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
-
- memset( &msg,0,sizeof(msg));
- pstr = (p80211item_pstr32_t*)&msg.mibattribute.data;
- memcpy(pstr->data.data, ext->key,ext->key_len);
- pstr->data.len = ext->key_len;
- switch (idx) {
- case 0:
- pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
- break;
- case 1:
- pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
- break;
- case 2:
- pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
- break;
- case 3:
- pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
- break;
- default:
- break;
- }
- msg.msgcode = DIDmsg_dot11req_mibset;
- result = p80211req_dorequest(wlandev,(u8*)&msg);
- WLAN_LOG_DEBUG(1,"result (%d)\n",result);
- }
- return result;
+ wlandevice_t *wlandev = dev->ml_priv;
+ struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+ p80211msg_dot11req_mibset_t msg;
+ p80211item_pstr32_t *pstr;
+
+ int result = 0;
+ struct iw_point *encoding = &wrqu->encoding;
+ int idx = encoding->flags & IW_ENCODE_INDEX;
+
+ pr_debug("set_encode_ext flags[%d] alg[%d] keylen[%d]\n",
+ ext->ext_flags, (int)ext->alg, (int)ext->key_len);
+
+ if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
+ /* set default key ? I'm not sure if this the the correct thing to do here */
+
+ if (idx) {
+ if (idx < 1 || idx > NUM_WEPKEYS)
+ return -EINVAL;
+ else
+ idx--;
+ }
+ pr_debug("setting default key (%d)\n", idx);
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+ idx);
+ if (result)
+ return -EFAULT;
+ }
+
+ if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
+ if (!(ext->alg & IW_ENCODE_ALG_WEP)) {
+ pr_debug("asked to set a non wep key :(");
+ return -EINVAL;
+ }
+ if (idx) {
+ if (idx < 1 || idx > NUM_WEPKEYS)
+ return -EINVAL;
+ else
+ idx--;
+ }
+ pr_debug("Set WEP key (%d)\n", idx);
+ wlandev->wep_keylens[idx] = ext->key_len;
+ memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
+
+ memset(&msg, 0, sizeof(msg));
+ pstr = (p80211item_pstr32_t *)&msg.mibattribute.data;
+ memcpy(pstr->data.data, ext->key, ext->key_len);
+ pstr->data.len = ext->key_len;
+ switch (idx) {
+ case 0:
+ pstr->did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
+ break;
+ case 1:
+ pstr->did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
+ break;
+ case 2:
+ pstr->did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
+ break;
+ case 3:
+ pstr->did =
+ DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
+ break;
+ default:
+ break;
+ }
+ msg.msgcode = DIDmsg_dot11req_mibset;
+ result = p80211req_dorequest(wlandev, (u8 *)&msg);
+ pr_debug("result (%d)\n", result);
+ }
+ return result;
}
/* SIOCGIWENCODEEXT */
static int p80211wext_get_encodeext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
wlandevice_t *wlandev = dev->ml_priv;
struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
@@ -1597,24 +1545,24 @@ static int p80211wext_get_encodeext(struct net_device *dev,
int max_len;
int idx;
- DBFENTER;
-
- WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
-
+ pr_debug("get_encode_ext flags[%d] alg[%d] keylen[%d]\n",
+ ext->ext_flags, (int)ext->alg, (int)ext->key_len);
max_len = encoding->length - sizeof(*ext);
- if ( max_len <= 0) {
- WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len);
+ if (max_len <= 0) {
+ pr_debug("get_encodeext max_len [%d] invalid\n",
+ max_len);
result = -EINVAL;
goto exit;
}
idx = encoding->flags & IW_ENCODE_INDEX;
- WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx);
+ pr_debug("get_encode_ext index [%d]\n", idx);
if (idx) {
- if (idx < 1 || idx > NUM_WEPKEYS ) {
- WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx);
+ if (idx < 1 || idx > NUM_WEPKEYS) {
+ printk(KERN_DEBUG
+ "get_encode_ext invalid key index [%d]\n", idx);
result = -EINVAL;
goto exit;
}
@@ -1625,203 +1573,207 @@ static int p80211wext_get_encodeext(struct net_device *dev,
}
encoding->flags = idx + 1;
- memset(ext,0,sizeof(*ext));
+ memset(ext, 0, sizeof(*ext));
ext->alg = IW_ENCODE_ALG_WEP;
ext->key_len = wlandev->wep_keylens[idx];
- memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len );
+ memcpy(ext->key, wlandev->wep_keys[idx], ext->key_len);
encoding->flags |= IW_ENCODE_ENABLED;
exit:
- DBFEXIT;
-
return result;
}
-
/* SIOCSIWAUTH */
-static int p80211_wext_set_iwauth (struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
+static int p80211_wext_set_iwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
{
- wlandevice_t *wlandev = dev->ml_priv;
- struct iw_param *param = &wrqu->param;
- int result =0;
-
- WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
-
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_DROP_UNENCRYPTED:
- WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value);
- if (param->value)
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
- else
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
- break;
-
- case IW_AUTH_PRIVACY_INVOKED:
- WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value);
- if ( param->value)
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
- else
- result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
-
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) {
- WLAN_LOG_DEBUG(1,"set open_system\n");
- wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
- } else if ( param->value & IW_AUTH_ALG_SHARED_KEY) {
- WLAN_LOG_DEBUG(1,"set shared key\n");
- wlandev->hostwep |= HOSTWEP_SHAREDKEY;
- } else {
- /* don't know what to do know :( */
- WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value);
- result = -EINVAL;
- }
- break;
-
- default:
- break;
- }
-
-
-
- return result;
-}
+ wlandevice_t *wlandev = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+ int result = 0;
-/* SIOCSIWAUTH */
-static int p80211_wext_get_iwauth (struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- wlandevice_t *wlandev = dev->ml_priv;
- struct iw_param *param = &wrqu->param;
- int result =0;
+ pr_debug("set_iwauth flags[%d]\n",
+ (int)param->flags & IW_AUTH_INDEX);
+
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_DROP_UNENCRYPTED:
+ pr_debug("drop_unencrypted %d\n", param->value);
+ if (param->value)
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+ P80211ENUM_truth_true);
+ else
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+ P80211ENUM_truth_false);
+ break;
+
+ case IW_AUTH_PRIVACY_INVOKED:
+ pr_debug("privacy invoked %d\n", param->value);
+ if (param->value)
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ P80211ENUM_truth_true);
+ else
+ result =
+ p80211wext_dorequest(wlandev,
+ DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ P80211ENUM_truth_false);
+
+ break;
+
+ case IW_AUTH_80211_AUTH_ALG:
+ if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+ pr_debug("set open_system\n");
+ wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
+ } else if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+ pr_debug("set shared key\n");
+ wlandev->hostwep |= HOSTWEP_SHAREDKEY;
+ } else {
+ /* don't know what to do know */
+ pr_debug("unknown AUTH_ALG (%d)\n",
+ param->value);
+ result = -EINVAL;
+ }
+ break;
- WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
+ default:
+ break;
+ }
- switch (param->flags & IW_AUTH_INDEX) {
- case IW_AUTH_DROP_UNENCRYPTED:
- param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0;
- break;
+ return result;
+}
- case IW_AUTH_PRIVACY_INVOKED:
- param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0;
- break;
+/* SIOCSIWAUTH */
+static int p80211_wext_get_iwauth(struct net_device *dev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ wlandevice_t *wlandev = dev->ml_priv;
+ struct iw_param *param = &wrqu->param;
+ int result = 0;
- case IW_AUTH_80211_AUTH_ALG:
- param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM;
- break;
+ pr_debug("get_iwauth flags[%d]\n",
+ (int)param->flags & IW_AUTH_INDEX);
+ switch (param->flags & IW_AUTH_INDEX) {
+ case IW_AUTH_DROP_UNENCRYPTED:
+ param->value =
+ wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED ? 1 : 0;
+ break;
- default:
- break;
- }
+ case IW_AUTH_PRIVACY_INVOKED:
+ param->value =
+ wlandev->hostwep & HOSTWEP_PRIVACYINVOKED ? 1 : 0;
+ break;
+ case IW_AUTH_80211_AUTH_ALG:
+ param->value =
+ wlandev->
+ hostwep & HOSTWEP_SHAREDKEY ? IW_AUTH_ALG_SHARED_KEY :
+ IW_AUTH_ALG_OPEN_SYSTEM;
+ break;
+ default:
+ break;
+ }
- return result;
+ return result;
}
-static iw_handler p80211wext_handlers[] = {
- (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */
- (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */
- (iw_handler) NULL, /* SIOCSIWNWID */
- (iw_handler) NULL, /* SIOCGIWNWID */
- (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */
- (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */
- (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */
- (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */
- (iw_handler) NULL, /* SIOCSIWSENS */
- (iw_handler) NULL, /* SIOCGIWSENS */
- (iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */
- (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */
- (iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */
- (iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */
- (iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */
- (iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */
- (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */
- (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCSIWAP */
- (iw_handler) p80211wext_giwap, /* SIOCGIWAP */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCGIWAPLIST */
- (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */
- (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */
- (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */
- (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */
- (iw_handler) NULL, /* SIOCSIWNICKN */
- (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCSIWRATE */
- (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */
- (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */
- (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */
- (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */
- (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */
- (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */
- (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */
- (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */
- (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */
- (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */
- (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */
- (iw_handler) NULL, /* SIOCSIWPOWER */
- (iw_handler) NULL, /* SIOCGIWPOWER */
+static iw_handler p80211wext_handlers[] = {
+ (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */
+ (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */
+ (iw_handler) NULL, /* SIOCSIWNWID */
+ (iw_handler) NULL, /* SIOCGIWNWID */
+ (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */
+ (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */
+ (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */
+ (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */
+ (iw_handler) NULL, /* SIOCSIWSENS */
+ (iw_handler) NULL, /* SIOCGIWSENS */
+ (iw_handler) NULL, /* not used *//* SIOCSIWRANGE */
+ (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */
+ (iw_handler) NULL, /* not used *//* SIOCSIWPRIV */
+ (iw_handler) NULL, /* kernel code *//* SIOCGIWPRIV */
+ (iw_handler) NULL, /* not used *//* SIOCSIWSTATS */
+ (iw_handler) NULL, /* kernel code *//* SIOCGIWSTATS */
+ (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */
+ (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWAP */
+ (iw_handler) p80211wext_giwap, /* SIOCGIWAP */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCGIWAPLIST */
+ (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */
+ (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */
+ (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */
+ (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */
+ (iw_handler) NULL, /* SIOCSIWNICKN */
+ (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWRATE */
+ (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */
+ (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */
+ (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */
+ (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */
+ (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */
+ (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */
+ (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */
+ (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */
+ (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */
+ (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */
+ (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */
+ (iw_handler) NULL, /* SIOCSIWPOWER */
+ (iw_handler) NULL, /* SIOCGIWPOWER */
/* WPA operations */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* -- hole -- */
- (iw_handler) NULL, /* SIOCSIWGENIE set generic IE */
- (iw_handler) NULL, /* SIOCGIWGENIE get generic IE */
- (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */
- (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */
-
- (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */
- (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */
- (iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* -- hole -- */
+ (iw_handler) NULL, /* SIOCSIWGENIE set generic IE */
+ (iw_handler) NULL, /* SIOCGIWGENIE get generic IE */
+ (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */
+ (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */
+
+ (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */
+ (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */
+ (iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */
};
struct iw_handler_def p80211wext_handler_def = {
.num_standard = ARRAY_SIZE(p80211wext_handlers),
.num_private = 0,
.num_private_args = 0,
- .standard = p80211wext_handlers,
+ .standard = p80211wext_handlers,
.private = NULL,
.private_args = NULL,
.get_wireless_stats = p80211wext_get_wireless_stats
};
-
int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
{
- union iwreq_data data;
-
- DBFENTER;
+ union iwreq_data data;
- /* Send the association state first */
- data.ap_addr.sa_family = ARPHRD_ETHER;
- if (assoc) {
- memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN);
- } else {
- memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN);
- }
+ /* Send the association state first */
+ data.ap_addr.sa_family = ARPHRD_ETHER;
+ if (assoc)
+ memcpy(data.ap_addr.sa_data, wlandev->bssid, ETH_ALEN);
+ else
+ memset(data.ap_addr.sa_data, 0, ETH_ALEN);
- if (wlan_wext_write)
- wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
+ if (wlan_wext_write)
+ wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
- if (!assoc) goto done;
+ if (!assoc)
+ goto done;
- // XXX send association data, like IEs, etc etc.
+ /* XXX send association data, like IEs, etc etc. */
- done:
- DBFEXIT;
- return 0;
+done:
+ return 0;
}
-
-
-
-
diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c
index f1727ba6ec6..e7a7939b428 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.c
+++ b/drivers/staging/wlan-ng/prism2mgmt.c
@@ -57,11 +57,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
-
#include <linux/if_arp.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -76,8 +71,7 @@
#include <asm/byteorder.h>
#include <linux/random.h>
#include <linux/usb.h>
-
-#include "wlan_compat.h"
+#include <linux/bitops.h>
/*================================================================*/
/* Project Includes */
@@ -94,10 +88,10 @@
#include "prism2mgmt.h"
/* Converts 802.11 format rate specifications to prism2 */
-#define p80211rate_to_p2bit(n) ((((n)&~BIT7) == 2) ? BIT0 : \
- (((n)&~BIT7) == 4) ? BIT1 : \
- (((n)&~BIT7) == 11) ? BIT2 : \
- (((n)&~BIT7) == 22) ? BIT3 : 0)
+#define p80211rate_to_p2bit(n) ((((n)&~BIT(7)) == 2) ? BIT(0) : \
+ (((n)&~BIT(7)) == 4) ? BIT(1) : \
+ (((n)&~BIT(7)) == 11) ? BIT(2) : \
+ (((n)&~BIT(7)) == 22) ? BIT(3) : 0)
/*----------------------------------------------------------------
* prism2mgmt_scan
@@ -125,183 +119,188 @@
----------------------------------------------------------------*/
int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- hfa384x_t *hw = wlandev->priv;
- p80211msg_dot11req_scan_t *msg = msgp;
- u16 roamingmode, word;
- int i, timeout;
- int istmpenable = 0;
-
- hfa384x_HostScanRequest_data_t scanreq;
-
- DBFENTER;
-
- /* gatekeeper check */
- if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
- hw->ident_sta_fw.minor,
- hw->ident_sta_fw.variant) <
- HFA384x_FIRMWARE_VERSION(1,3,2)) {
- WLAN_LOG_ERROR("HostScan not supported with current firmware (<1.3.2).\n");
- result = 1;
- msg->resultcode.data = P80211ENUM_resultcode_not_supported;
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_scan_t *msg = msgp;
+ u16 roamingmode, word;
+ int i, timeout;
+ int istmpenable = 0;
+
+ hfa384x_HostScanRequest_data_t scanreq;
+
+ /* gatekeeper check */
+ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) <
+ HFA384x_FIRMWARE_VERSION(1, 3, 2)) {
+ printk(KERN_ERR
+ "HostScan not supported with current firmware (<1.3.2).\n");
+ result = 1;
+ msg->resultcode.data = P80211ENUM_resultcode_not_supported;
goto exit;
}
- memset(&scanreq, 0, sizeof(scanreq));
-
- /* save current roaming mode */
- result = hfa384x_drvr_getconfig16(hw,
- HFA384x_RID_CNFROAMINGMODE, &roamingmode);
- if ( result ) {
- WLAN_LOG_ERROR("getconfig(ROAMMODE) failed. result=%d\n",
- result);
- msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
- goto exit;
- }
-
- /* drop into mode 3 for the scan */
- result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFROAMINGMODE,
- HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
- if ( result ) {
- WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n",
- result);
- msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
- goto exit;
- }
-
- /* active or passive? */
- if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
- hw->ident_sta_fw.minor,
- hw->ident_sta_fw.variant) >
- HFA384x_FIRMWARE_VERSION(1,5,0)) {
- if (msg->scantype.data != P80211ENUM_scantype_active) {
- word = host2hfa384x_16(msg->maxchanneltime.data);
- } else {
- word = 0;
- }
- result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, word);
- if ( result ) {
- WLAN_LOG_WARNING("Passive scan not supported with "
- "current firmware. (<1.5.1)\n");
- }
- }
+ memset(&scanreq, 0, sizeof(scanreq));
+
+ /* save current roaming mode */
+ result = hfa384x_drvr_getconfig16(hw,
+ HFA384x_RID_CNFROAMINGMODE,
+ &roamingmode);
+ if (result) {
+ printk(KERN_ERR "getconfig(ROAMMODE) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+
+ /* drop into mode 3 for the scan */
+ result = hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFROAMINGMODE,
+ HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+ if (result) {
+ printk(KERN_ERR "setconfig(ROAMINGMODE) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+
+ /* active or passive? */
+ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) >
+ HFA384x_FIRMWARE_VERSION(1, 5, 0)) {
+ if (msg->scantype.data != P80211ENUM_scantype_active)
+ word = cpu_to_le16(msg->maxchanneltime.data);
+ else
+ word = 0;
+
+ result =
+ hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL,
+ word);
+ if (result) {
+ printk(KERN_WARNING "Passive scan not supported with "
+ "current firmware. (<1.5.1)\n");
+ }
+ }
/* set up the txrate to be 2MBPS. Should be fastest basicrate... */
word = HFA384x_RATEBIT_2;
- scanreq.txRate = host2hfa384x_16(word);
-
- /* set up the channel list */
- word = 0;
- for (i = 0; i < msg->channellist.data.len; i++) {
- u8 channel = msg->channellist.data.data[i];
- if (channel > 14) continue;
- /* channel 1 is BIT0 ... channel 14 is BIT13 */
- word |= (1 << (channel-1));
- }
- scanreq.channelList = host2hfa384x_16(word);
-
- /* set up the ssid, if present. */
- scanreq.ssid.len = host2hfa384x_16(msg->ssid.data.len);
- memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
+ scanreq.txRate = cpu_to_le16(word);
+
+ /* set up the channel list */
+ word = 0;
+ for (i = 0; i < msg->channellist.data.len; i++) {
+ u8 channel = msg->channellist.data.data[i];
+ if (channel > 14)
+ continue;
+ /* channel 1 is BIT 0 ... channel 14 is BIT 13 */
+ word |= (1 << (channel - 1));
+ }
+ scanreq.channelList = cpu_to_le16(word);
+
+ /* set up the ssid, if present. */
+ scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len);
+ memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len);
/* Enable the MAC port if it's not already enabled */
result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word);
- if ( result ) {
- WLAN_LOG_ERROR("getconfig(PORTSTATUS) failed. "
- "result=%d\n", result);
+ if (result) {
+ printk(KERN_ERR "getconfig(PORTSTATUS) failed. "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
if (word == HFA384x_PORTSTATUS_DISABLED) {
u16 wordbuf[17];
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFROAMINGMODE,
- HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
- if ( result ) {
- WLAN_LOG_ERROR("setconfig(ROAMINGMODE) failed. result=%d\n", result);
+ HFA384x_RID_CNFROAMINGMODE,
+ HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM);
+ if (result) {
+ printk(KERN_ERR
+ "setconfig(ROAMINGMODE) failed. result=%d\n",
+ result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* Construct a bogus SSID and assign it to OwnSSID and
* DesiredSSID
*/
- wordbuf[0] = host2hfa384x_16(WLAN_SSID_MAXLEN);
+ wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN);
get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN);
- result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
- wordbuf, HFA384x_RID_CNFOWNSSID_LEN);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set OwnSSID.\n");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
+ wordbuf,
+ HFA384x_RID_CNFOWNSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "Failed to set OwnSSID.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
- result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
- wordbuf, HFA384x_RID_CNFDESIREDSSID_LEN);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set DesiredSSID.\n");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+ wordbuf,
+ HFA384x_RID_CNFDESIREDSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "Failed to set DesiredSSID.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* bsstype */
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFPORTTYPE,
- HFA384x_PORTTYPE_IBSS);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set CNFPORTTYPE.\n");
+ HFA384x_RID_CNFPORTTYPE,
+ HFA384x_PORTTYPE_IBSS);
+ if (result) {
+ printk(KERN_ERR "Failed to set CNFPORTTYPE.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
/* ibss options */
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CREATEIBSS,
- HFA384x_CREATEIBSS_JOINCREATEIBSS);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set CREATEIBSS.\n");
+ HFA384x_RID_CREATEIBSS,
+ HFA384x_CREATEIBSS_JOINCREATEIBSS);
+ if (result) {
+ printk(KERN_ERR "Failed to set CREATEIBSS.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
result = hfa384x_drvr_enable(hw, 0);
- if ( result ) {
- WLAN_LOG_ERROR("drvr_enable(0) failed. "
- "result=%d\n", result);
+ if (result) {
+ printk(KERN_ERR "drvr_enable(0) failed. "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
istmpenable = 1;
}
- /* Figure out our timeout first Kus, then HZ */
- timeout = msg->channellist.data.len * msg->maxchanneltime.data;
- timeout = (timeout * HZ)/1000;
-
- /* Issue the scan request */
- hw->scanflag = 0;
+ /* Figure out our timeout first Kus, then HZ */
+ timeout = msg->channellist.data.len * msg->maxchanneltime.data;
+ timeout = (timeout * HZ) / 1000;
- WLAN_HEX_DUMP(5,"hscanreq", &scanreq, sizeof(scanreq));
+ /* Issue the scan request */
+ hw->scanflag = 0;
- result = hfa384x_drvr_setconfig( hw,
- HFA384x_RID_HOSTSCAN, &scanreq,
- sizeof(hfa384x_HostScanRequest_data_t));
- if ( result ) {
- WLAN_LOG_ERROR("setconfig(SCANREQUEST) failed. result=%d\n",
- result);
- msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
- goto exit;
- }
+ result = hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_HOSTSCAN, &scanreq,
+ sizeof(hfa384x_HostScanRequest_data_t));
+ if (result) {
+ printk(KERN_ERR "setconfig(SCANREQUEST) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
- /* sleep until info frame arrives */
- wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
+ /* sleep until info frame arrives */
+ wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout);
msg->numbss.status = P80211ENUM_msgitem_status_data_ok;
if (hw->scanflag == -1)
@@ -309,16 +308,16 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
msg->numbss.data = hw->scanflag;
- hw->scanflag = 0;
+ hw->scanflag = 0;
/* Disable port if we temporarily enabled it. */
if (istmpenable) {
result = hfa384x_drvr_disable(hw, 0);
- if ( result ) {
- WLAN_LOG_ERROR("drvr_disable(0) failed. "
- "result=%d\n", result);
+ if (result) {
+ printk(KERN_ERR "drvr_disable(0) failed. "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
goto exit;
}
}
@@ -326,25 +325,23 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
/* restore original roaming mode */
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE,
roamingmode);
- if ( result ) {
- WLAN_LOG_ERROR("setconfig(ROAMMODE) failed. result=%d\n",
- result);
- msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
- goto exit;
- }
-
- result = 0;
- msg->resultcode.data = P80211ENUM_resultcode_success;
-
- exit:
+ if (result) {
+ printk(KERN_ERR "setconfig(ROAMMODE) failed. result=%d\n",
+ result);
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
+ goto exit;
+ }
+
+ result = 0;
+ msg->resultcode.data = P80211ENUM_resultcode_success;
+
+exit:
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2mgmt_scan_results
*
@@ -367,32 +364,32 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- p80211msg_dot11req_scan_results_t *req;
- hfa384x_t *hw = wlandev->priv;
+ int result = 0;
+ p80211msg_dot11req_scan_results_t *req;
+ hfa384x_t *hw = wlandev->priv;
hfa384x_HScanResultSub_t *item = NULL;
int count;
- DBFENTER;
-
- req = (p80211msg_dot11req_scan_results_t *) msgp;
+ req = (p80211msg_dot11req_scan_results_t *) msgp;
req->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- if (! hw->scanresults) {
- WLAN_LOG_ERROR("dot11req_scan_results can only be used after a successful dot11req_scan.\n");
+ if (!hw->scanresults) {
+ printk(KERN_ERR
+ "dot11req_scan_results can only be used after a successful dot11req_scan.\n");
result = 2;
req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
goto exit;
}
- count = (hw->scanresults->framelen - 3) / 32;
- if (count > 32) count = 32;
+ count = (hw->scanresults->framelen - 3) / 32;
+ if (count > 32)
+ count = 32;
if (req->bssindex.data >= count) {
- WLAN_LOG_DEBUG(0, "requested index (%d) out of range (%d)\n",
- req->bssindex.data, count);
+ pr_debug("requested index (%d) out of range (%d)\n",
+ req->bssindex.data, count);
result = 2;
req->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
goto exit;
@@ -402,8 +399,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* signal and noise */
req->signal.status = P80211ENUM_msgitem_status_data_ok;
req->noise.status = P80211ENUM_msgitem_status_data_ok;
- req->signal.data = hfa384x2host_16(item->sl);
- req->noise.data = hfa384x2host_16(item->anl);
+ req->signal.data = le16_to_cpu(item->sl);
+ req->noise.data = le16_to_cpu(item->anl);
/* BSSID */
req->bssid.status = P80211ENUM_msgitem_status_data_ok;
@@ -412,13 +409,13 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* SSID */
req->ssid.status = P80211ENUM_msgitem_status_data_ok;
- req->ssid.data.len = hfa384x2host_16(item->ssid.len);
+ req->ssid.data.len = le16_to_cpu(item->ssid.len);
memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len);
/* supported rates */
- for (count = 0; count < 10 ; count++)
- if (item->supprates[count] == 0)
- break;
+ for (count = 0; count < 10; count++)
+ if (item->supprates[count] == 0)
+ break;
#define REQBASICRATE(N) \
if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \
@@ -452,7 +449,7 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* beacon period */
req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok;
- req->beaconperiod.data = hfa384x2host_16(item->bcnint);
+ req->beaconperiod.data = le16_to_cpu(item->bcnint);
/* timestamps */
req->timestamp.status = P80211ENUM_msgitem_status_data_ok;
@@ -462,14 +459,14 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
/* atim window */
req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok;
- req->ibssatimwindow.data = hfa384x2host_16(item->atim);
+ req->ibssatimwindow.data = le16_to_cpu(item->atim);
/* Channel */
req->dschannel.status = P80211ENUM_msgitem_status_data_ok;
- req->dschannel.data = hfa384x2host_16(item->chid);
+ req->dschannel.data = le16_to_cpu(item->chid);
/* capinfo bits */
- count = hfa384x2host_16(item->capinfo);
+ count = le16_to_cpu(item->capinfo);
/* privacy flag */
req->privacy.status = P80211ENUM_msgitem_status_data_ok;
@@ -484,25 +481,14 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count);
/* bsstype */
- req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
+ req->bsstype.status = P80211ENUM_msgitem_status_data_ok;
req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ?
- P80211ENUM_bsstype_infrastructure :
- P80211ENUM_bsstype_independent;
-
- // item->proberesp_rate
-/*
- req->fhdwelltime
- req->fhhopset
- req->fhhoppattern
- req->fhhopindex
- req->cfpdurremaining
-*/
+ P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent;
result = 0;
req->resultcode.data = P80211ENUM_resultcode_success;
- exit:
- DBFEXIT;
+exit:
return result;
}
@@ -527,15 +513,14 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- hfa384x_t *hw = wlandev->priv;
- p80211msg_dot11req_start_t *msg = msgp;
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_dot11req_start_t *msg = msgp;
- p80211pstrd_t *pstr;
- u8 bytebuf[80];
- hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
- u16 word;
- DBFENTER;
+ p80211pstrd_t *pstr;
+ u8 bytebuf[80];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
+ u16 word;
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -547,7 +532,7 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
hw->ident_sta_fw.minor,
hw->ident_sta_fw.variant) <
- HFA384x_FIRMWARE_VERSION(0,8,3)) {
+ HFA384x_FIRMWARE_VERSION(0, 8, 3)) {
/* Ad-Hoc not quite supported on Prism2 */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_not_supported;
@@ -559,18 +544,19 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/*** STATION ***/
/* Set the REQUIRED config items */
/* SSID */
- pstr = (p80211pstrd_t*)&(msg->ssid.data);
+ pstr = (p80211pstrd_t *)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
- result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFOWNSSID,
- bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set CnfOwnSSID\n");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID,
+ bytebuf, HFA384x_RID_CNFOWNSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "Failed to set CnfOwnSSID\n");
goto failed;
}
- result = hfa384x_drvr_setconfig( hw, HFA384x_RID_CNFDESIREDSSID,
- bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set CnfDesiredSSID\n");
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+ bytebuf,
+ HFA384x_RID_CNFDESIREDSSID_LEN);
+ if (result) {
+ printk(KERN_ERR "Failed to set CnfDesiredSSID\n");
goto failed;
}
@@ -581,84 +567,84 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/* beacon period */
word = msg->beaconperiod.data;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNint, word);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set beacon period=%d.\n", word);
+ if (result) {
+ printk(KERN_ERR "Failed to set beacon period=%d.\n", word);
goto failed;
}
/* dschannel */
word = msg->dschannel.data;
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set channel=%d.\n", word);
+ if (result) {
+ printk(KERN_ERR "Failed to set channel=%d.\n", word);
goto failed;
}
/* Basic rates */
word = p80211rate_to_p2bit(msg->basicrate1.data);
- if ( msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ if (msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->basicrate2.data);
- }
- if ( msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->basicrate3.data);
- }
- if ( msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->basicrate4.data);
- }
- if ( msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->basicrate5.data);
- }
- if ( msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->basicrate6.data);
- }
- if ( msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->basicrate7.data);
- }
- if ( msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->basicrate8.data);
- }
+
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set basicrates=%d.\n", word);
+ if (result) {
+ printk(KERN_ERR "Failed to set basicrates=%d.\n", word);
goto failed;
}
/* Operational rates (supprates and txratecontrol) */
word = p80211rate_to_p2bit(msg->operationalrate1.data);
- if ( msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok ) {
+ if (msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->operationalrate2.data);
- }
- if ( msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->operationalrate3.data);
- }
- if ( msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->operationalrate4.data);
- }
- if ( msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->operationalrate5.data);
- }
- if ( msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->operationalrate6.data);
- }
- if ( msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->operationalrate7.data);
- }
- if ( msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok ) {
+
+ if (msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok)
word |= p80211rate_to_p2bit(msg->operationalrate8.data);
- }
+
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set supprates=%d.\n", word);
+ if (result) {
+ printk(KERN_ERR "Failed to set supprates=%d.\n", word);
goto failed;
}
result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word);
- if ( result ) {
- WLAN_LOG_ERROR("Failed to set txrates=%d.\n", word);
+ if (result) {
+ printk(KERN_ERR "Failed to set txrates=%d.\n", word);
goto failed;
}
/* Set the macmode so the frame setup code knows what to do */
- if ( msg->bsstype.data == P80211ENUM_bsstype_independent ) {
+ if (msg->bsstype.data == P80211ENUM_bsstype_independent) {
wlandev->macmode = WLAN_MACMODE_IBSS_STA;
/* lets extend the data length a bit */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304);
@@ -666,8 +652,8 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
/* Enable the Port */
result = hfa384x_drvr_enable(hw, 0);
- if ( result ) {
- WLAN_LOG_ERROR("Enable macport failed, result=%d.\n", result);
+ if (result) {
+ printk(KERN_ERR "Enable macport failed, result=%d.\n", result);
goto failed;
}
@@ -675,13 +661,12 @@ int prism2mgmt_start(wlandevice_t *wlandev, void *msgp)
goto done;
failed:
- WLAN_LOG_DEBUG(1, "Failed to set a config option, result=%d\n", result);
+ pr_debug("Failed to set a config option, result=%d\n", result);
msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
done:
result = 0;
- DBFEXIT;
return result;
}
@@ -705,40 +690,35 @@ done:
----------------------------------------------------------------*/
int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_readpda_t *msg = msgp;
- int result;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_readpda_t *msg = msgp;
+ int result;
/* We only support collecting the PDA when in the FWLOAD
* state.
*/
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "PDA may only be read "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "PDA may only be read " "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
} else {
/* Call drvr_readpda(), it handles the auxport enable
* and validating the returned PDA.
*/
- result = hfa384x_drvr_readpda(
- hw,
- msg->pda.data,
- HFA384x_PDA_LEN_MAX);
+ result = hfa384x_drvr_readpda(hw,
+ msg->pda.data,
+ HFA384x_PDA_LEN_MAX);
if (result) {
- WLAN_LOG_ERROR(
- "hfa384x_drvr_readpda() failed, "
- "result=%d\n",
- result);
+ printk(KERN_ERR
+ "hfa384x_drvr_readpda() failed, "
+ "result=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status =
- P80211ENUM_msgitem_status_data_ok;
- DBFEXIT;
+ P80211ENUM_msgitem_status_data_ok;
return 0;
}
msg->pda.status = P80211ENUM_msgitem_status_data_ok;
@@ -746,7 +726,6 @@ int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
}
- DBFEXIT;
return 0;
}
@@ -777,30 +756,29 @@ int prism2mgmt_readpda(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_ramdl_state_t *msg = msgp;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_ramdl_state_t *msg = msgp;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "ramdl_state(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "ramdl_state(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- DBFEXIT;
return 0;
}
/*
- ** Note: Interrupts are locked out if this is an AP and are NOT
- ** locked out if this is a station.
- */
+ ** Note: Interrupts are locked out if this is an AP and are NOT
+ ** locked out if this is a station.
+ */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- if ( msg->enable.data == P80211ENUM_truth_true ) {
- if ( hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data) ) {
- msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+ if (msg->enable.data == P80211ENUM_truth_true) {
+ if (hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data)) {
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
@@ -809,11 +787,9 @@ int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
msg->resultcode.data = P80211ENUM_resultcode_success;
}
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2mgmt_ramdl_write
*
@@ -836,45 +812,41 @@ int prism2mgmt_ramdl_state(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_ramdl_write_t *msg = msgp;
- u32 addr;
- u32 len;
- u8 *buf;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_ramdl_write_t *msg = msgp;
+ u32 addr;
+ u32 len;
+ u8 *buf;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "ramdl_write(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "ramdl_write(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- DBFEXIT;
return 0;
}
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* first validate the length */
- if ( msg->len.data > sizeof(msg->data.data) ) {
- msg->resultcode.status = P80211ENUM_resultcode_invalid_parameters;
+ if (msg->len.data > sizeof(msg->data.data)) {
+ msg->resultcode.status =
+ P80211ENUM_resultcode_invalid_parameters;
return 0;
}
/* call the hfa384x function to do the write */
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
- if ( hfa384x_drvr_ramdl_write(hw, addr, buf, len) ) {
+ if (hfa384x_drvr_ramdl_write(hw, addr, buf, len))
msg->resultcode.data = P80211ENUM_resultcode_refused;
- }
msg->resultcode.data = P80211ENUM_resultcode_success;
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2mgmt_flashdl_state
*
@@ -902,31 +874,30 @@ int prism2mgmt_ramdl_write(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_flashdl_state_t *msg = msgp;
- DBFENTER;
+ int result = 0;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_flashdl_state_t *msg = msgp;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "flashdl_state(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "flashdl_state(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- DBFEXIT;
return 0;
}
/*
- ** Note: Interrupts are locked out if this is an AP and are NOT
- ** locked out if this is a station.
- */
+ ** Note: Interrupts are locked out if this is an AP and are NOT
+ ** locked out if this is a station.
+ */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- if ( msg->enable.data == P80211ENUM_truth_true ) {
- if ( hfa384x_drvr_flashdl_enable(hw) ) {
- msg->resultcode.data = P80211ENUM_resultcode_implementation_failure;
+ if (msg->enable.data == P80211ENUM_truth_true) {
+ if (hfa384x_drvr_flashdl_enable(hw)) {
+ msg->resultcode.data =
+ P80211ENUM_resultcode_implementation_failure;
} else {
msg->resultcode.data = P80211ENUM_resultcode_success;
}
@@ -943,19 +914,17 @@ int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
wlandev->msdstate = WLAN_MSD_HWPRESENT;
result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload);
if (result != P80211ENUM_resultcode_success) {
- WLAN_LOG_ERROR("prism2sta_ifstate(fwload) failed,"
- "P80211ENUM_resultcode=%d\n", result);
+ printk(KERN_ERR "prism2sta_ifstate(fwload) failed,"
+ "P80211ENUM_resultcode=%d\n", result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
result = -1;
}
}
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2mgmt_flashdl_write
*
@@ -976,47 +945,43 @@ int prism2mgmt_flashdl_state(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- p80211msg_p2req_flashdl_write_t *msg = msgp;
- u32 addr;
- u32 len;
- u8 *buf;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ p80211msg_p2req_flashdl_write_t *msg = msgp;
+ u32 addr;
+ u32 len;
+ u8 *buf;
if (wlandev->msdstate != WLAN_MSD_FWLOAD) {
- WLAN_LOG_ERROR(
- "flashdl_write(): may only be called "
- "in the fwload state.\n");
+ printk(KERN_ERR
+ "flashdl_write(): may only be called "
+ "in the fwload state.\n");
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- DBFEXIT;
return 0;
}
/*
- ** Note: Interrupts are locked out if this is an AP and are NOT
- ** locked out if this is a station.
- */
+ ** Note: Interrupts are locked out if this is an AP and are NOT
+ ** locked out if this is a station.
+ */
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
/* first validate the length */
- if ( msg->len.data > sizeof(msg->data.data) ) {
+ if (msg->len.data > sizeof(msg->data.data)) {
msg->resultcode.status =
- P80211ENUM_resultcode_invalid_parameters;
+ P80211ENUM_resultcode_invalid_parameters;
return 0;
}
/* call the hfa384x function to do the write */
addr = msg->addr.data;
len = msg->len.data;
buf = msg->data.data;
- if ( hfa384x_drvr_flashdl_write(hw, addr, buf, len) ) {
+ if (hfa384x_drvr_flashdl_write(hw, addr, buf, len))
msg->resultcode.data = P80211ENUM_resultcode_refused;
- }
msg->resultcode.data = P80211ENUM_resultcode_success;
- DBFEXIT;
return 0;
}
@@ -1041,15 +1006,14 @@ int prism2mgmt_flashdl_write(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- int result = 0;
- u16 reg;
- u16 port_type;
- p80211msg_lnxreq_autojoin_t *msg = msgp;
- p80211pstrd_t *pstr;
- u8 bytebuf[256];
- hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t*)bytebuf;
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ int result = 0;
+ u16 reg;
+ u16 port_type;
+ p80211msg_lnxreq_autojoin_t *msg = msgp;
+ p80211pstrd_t *pstr;
+ u8 bytebuf[256];
+ hfa384x_bytestr_t *p2bytestr = (hfa384x_bytestr_t *) bytebuf;
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -1064,39 +1028,21 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f);
/* Set the auth type */
- if ( msg->authtype.data == P80211ENUM_authalg_sharedkey ) {
+ if (msg->authtype.data == P80211ENUM_authalg_sharedkey)
reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY;
- } else {
+ else
reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM;
- }
+
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg);
/* Set the ssid */
memset(bytebuf, 0, 256);
- pstr = (p80211pstrd_t*)&(msg->ssid.data);
+ pstr = (p80211pstrd_t *)&(msg->ssid.data);
prism2mgmt_pstr2bytestr(p2bytestr, pstr);
- result = hfa384x_drvr_setconfig(
- hw, HFA384x_RID_CNFDESIREDSSID,
- bytebuf, HFA384x_RID_CNFDESIREDSSID_LEN);
-#if 0
- /* we can use the new-fangled auto-unknown mode if the firmware
- is 1.3.3 or newer */
- if (HFA384x_FIRMARE_VERSION(hw->ident_sta_fw.major,
- hw->ident_sta_fw.minor,
- hw->ident_sta_fw.variant) >=
- HFA384x_FIRMWARE_VERSION(1,3,3)) {
- /* Set up the IBSS options */
- reg = HFA384x_CREATEIBSS_JOINESS_JOINCREATEIBSS;
- hfa384x_drvr_setconfig16(hw, HFA384x_RID_CREATEIBSS, reg);
-
- /* Set the PortType */
- port_type = HFA384x_PORTTYPE_IBSS;
- } else {
- port_type = HFA384x_PORTTYPE_BSS;
- }
-#else
+ result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID,
+ bytebuf,
+ HFA384x_RID_CNFDESIREDSSID_LEN);
port_type = HFA384x_PORTTYPE_BSS;
-#endif
/* Set the PortType */
hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type);
@@ -1107,11 +1053,9 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2mgmt_wlansniff
*
@@ -1133,38 +1077,36 @@ int prism2mgmt_autojoin(wlandevice_t *wlandev, void *msgp)
----------------------------------------------------------------*/
int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
{
- int result = 0;
- p80211msg_lnxreq_wlansniff_t *msg = msgp;
+ int result = 0;
+ p80211msg_lnxreq_wlansniff_t *msg = msgp;
- hfa384x_t *hw = wlandev->priv;
- u16 word;
-
- DBFENTER;
+ hfa384x_t *hw = wlandev->priv;
+ u16 word;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
- switch (msg->enable.data)
- {
+ switch (msg->enable.data) {
case P80211ENUM_truth_false:
/* Confirm that we're in monitor mode */
- if ( wlandev->netdev->type == ARPHRD_ETHER ) {
- msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters;
+ if (wlandev->netdev->type == ARPHRD_ETHER) {
+ msg->resultcode.data =
+ P80211ENUM_resultcode_invalid_parameters;
result = 0;
goto exit;
}
/* Disable monitor mode */
result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to disable monitor mode, result=%d\n",
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to disable monitor mode, result=%d\n",
+ result);
goto failed;
}
/* Disable port 0 */
result = hfa384x_drvr_disable(hw, 0);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to disable port 0 after sniffing, result=%d\n",
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to disable port 0 after sniffing, result=%d\n",
+ result);
goto failed;
}
/* Clear the driver state */
@@ -1172,32 +1114,34 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* Restore the wepflags */
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFWEPFLAGS,
- hw->presniff_wepflags);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to restore wepflags=0x%04x, result=%d\n",
- hw->presniff_wepflags,
- result);
+ HFA384x_RID_CNFWEPFLAGS,
+ hw->presniff_wepflags);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to restore wepflags=0x%04x, result=%d\n",
+ hw->presniff_wepflags, result);
goto failed;
}
/* Set the port to its prior type and enable (if necessary) */
- if (hw->presniff_port_type != 0 ) {
+ if (hw->presniff_port_type != 0) {
word = hw->presniff_port_type;
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFPORTTYPE, word);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to restore porttype, result=%d\n",
- result);
+ HFA384x_RID_CNFPORTTYPE,
+ word);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to restore porttype, result=%d\n",
+ result);
goto failed;
}
/* Enable the port */
result = hfa384x_drvr_enable(hw, 0);
- if ( result ) {
- WLAN_LOG_DEBUG(1, "failed to enable port to presniff setting, result=%d\n", result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to enable port to presniff setting, result=%d\n",
+ result);
goto failed;
}
} else {
@@ -1205,46 +1149,52 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
}
- WLAN_LOG_INFO("monitor mode disabled\n");
+ printk(KERN_INFO "monitor mode disabled\n");
msg->resultcode.data = P80211ENUM_resultcode_success;
result = 0;
goto exit;
break;
case P80211ENUM_truth_true:
/* Disable the port (if enabled), only check Port 0 */
- if ( hw->port_enabled[0]) {
+ if (hw->port_enabled[0]) {
if (wlandev->netdev->type == ARPHRD_ETHER) {
/* Save macport 0 state */
result = hfa384x_drvr_getconfig16(hw,
HFA384x_RID_CNFPORTTYPE,
- &(hw->presniff_port_type));
- if ( result ) {
- WLAN_LOG_DEBUG(1,"failed to read porttype, result=%d\n", result);
+ &(hw->
+ presniff_port_type));
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to read porttype, result=%d\n",
+ result);
goto failed;
}
/* Save the wepflags state */
result = hfa384x_drvr_getconfig16(hw,
HFA384x_RID_CNFWEPFLAGS,
- &(hw->presniff_wepflags));
- if ( result ) {
- WLAN_LOG_DEBUG(1,"failed to read wepflags, result=%d\n", result);
+ &(hw->
+ presniff_wepflags));
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to read wepflags, result=%d\n",
+ result);
goto failed;
}
hfa384x_drvr_stop(hw);
result = hfa384x_drvr_start(hw);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to restart the card for sniffing, result=%d\n",
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to restart the card for sniffing, result=%d\n",
+ result);
goto failed;
}
} else {
/* Disable the port */
result = hfa384x_drvr_disable(hw, 0);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to enable port for sniffing, result=%d\n",
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to enable port for sniffing, result=%d\n",
+ result);
goto failed;
}
}
@@ -1255,14 +1205,14 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* Set the channel we wish to sniff */
word = msg->channel.data;
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFOWNCHANNEL, word);
- hw->sniff_channel=word;
+ HFA384x_RID_CNFOWNCHANNEL,
+ word);
+ hw->sniff_channel = word;
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to set channel %d, result=%d\n",
- word,
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to set channel %d, result=%d\n",
+ word, result);
goto failed;
}
@@ -1271,39 +1221,46 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* Set the port type to pIbss */
word = HFA384x_PORTTYPE_PSUEDOIBSS;
result = hfa384x_drvr_setconfig16(hw,
- HFA384x_RID_CNFPORTTYPE, word);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to set porttype %d, result=%d\n",
- word,
- result);
+ HFA384x_RID_CNFPORTTYPE,
+ word);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to set porttype %d, result=%d\n",
+ word, result);
goto failed;
}
- if ((msg->keepwepflags.status == P80211ENUM_msgitem_status_data_ok) && (msg->keepwepflags.data != P80211ENUM_truth_true)) {
+ if ((msg->keepwepflags.status ==
+ P80211ENUM_msgitem_status_data_ok)
+ && (msg->keepwepflags.data !=
+ P80211ENUM_truth_true)) {
/* Set the wepflags for no decryption */
word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT |
- HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
- result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFWEPFLAGS, word);
+ HFA384x_WEPFLAGS_DISABLE_RXCRYPT;
+ result =
+ hfa384x_drvr_setconfig16(hw,
+ HFA384x_RID_CNFWEPFLAGS,
+ word);
}
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to set wepflags=0x%04x, result=%d\n",
- word,
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to set wepflags=0x%04x, result=%d\n",
+ word, result);
goto failed;
}
}
/* Do we want to strip the FCS in monitor mode? */
- if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok) && (msg->stripfcs.data == P80211ENUM_truth_true)) {
+ if ((msg->stripfcs.status == P80211ENUM_msgitem_status_data_ok)
+ && (msg->stripfcs.data == P80211ENUM_truth_true)) {
hw->sniff_fcs = 0;
} else {
hw->sniff_fcs = 1;
}
/* Do we want to truncate the packets? */
- if (msg->packet_trunc.status == P80211ENUM_msgitem_status_data_ok) {
+ if (msg->packet_trunc.status ==
+ P80211ENUM_msgitem_status_data_ok) {
hw->sniff_truncate = msg->packet_trunc.data;
} else {
hw->sniff_truncate = 0;
@@ -1311,31 +1268,35 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp)
/* Enable the port */
result = hfa384x_drvr_enable(hw, 0);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to enable port for sniffing, result=%d\n",
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to enable port for sniffing, result=%d\n",
+ result);
goto failed;
}
/* Enable monitor mode */
result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "failed to enable monitor mode, result=%d\n",
- result);
+ if (result) {
+ printk(KERN_DEBUG
+ "failed to enable monitor mode, result=%d\n",
+ result);
goto failed;
}
- if (wlandev->netdev->type == ARPHRD_ETHER) {
- WLAN_LOG_INFO("monitor mode enabled\n");
- }
+ if (wlandev->netdev->type == ARPHRD_ETHER)
+ printk(KERN_INFO "monitor mode enabled\n");
/* Set the driver state */
/* Do we want the prism2 header? */
- if ((msg->prismheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->prismheader.data == P80211ENUM_truth_true)) {
+ if ((msg->prismheader.status ==
+ P80211ENUM_msgitem_status_data_ok)
+ && (msg->prismheader.data == P80211ENUM_truth_true)) {
hw->sniffhdr = 0;
wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
- } else if ((msg->wlanheader.status == P80211ENUM_msgitem_status_data_ok) && (msg->wlanheader.data == P80211ENUM_truth_true)) {
+ } else
+ if ((msg->wlanheader.status ==
+ P80211ENUM_msgitem_status_data_ok)
+ && (msg->wlanheader.data == P80211ENUM_truth_true)) {
hw->sniffhdr = 1;
wlandev->netdev->type = ARPHRD_IEEE80211_PRISM;
} else {
@@ -1357,7 +1318,5 @@ failed:
msg->resultcode.data = P80211ENUM_resultcode_refused;
result = 0;
exit:
-
- DBFEXIT;
return result;
}
diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h
index caf808d5796..07eecebeb6c 100644
--- a/drivers/staging/wlan-ng/prism2mgmt.h
+++ b/drivers/staging/wlan-ng/prism2mgmt.h
@@ -60,43 +60,16 @@
#ifndef _PRISM2MGMT_H
#define _PRISM2MGMT_H
+extern int prism2_reset_holdtime;
+extern int prism2_reset_settletime;
-/*=============================================================*/
-/*------ Constants --------------------------------------------*/
+u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
-/*=============================================================*/
-/*------ Macros -----------------------------------------------*/
-
-/*=============================================================*/
-/*------ Types and their related constants --------------------*/
-
-/*=============================================================*/
-/*------ Static variable externs ------------------------------*/
-
-extern int prism2_debug;
-extern int prism2_reset_holdtime;
-extern int prism2_reset_settletime;
-/*=============================================================*/
-/*--- Function Declarations -----------------------------------*/
-/*=============================================================*/
-
-u32
-prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate);
-
-void
-prism2sta_ev_dtim(wlandevice_t *wlandev);
-void
-prism2sta_ev_infdrop(wlandevice_t *wlandev);
-void
-prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-void
-prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
-void
-prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
-void
-prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
-void
-prism2sta_ev_alloc(wlandevice_t *wlandev);
+void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
+void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status);
+void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb);
+void prism2sta_ev_alloc(wlandevice_t *wlandev);
int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp);
int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp);
@@ -122,34 +95,16 @@ void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len);
void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr);
-/* integer conversion functions */
-void prism2mgmt_prism2int2p80211int(u16 *prism2int, u32 *wlanint);
-void prism2mgmt_p80211int2prism2int(u16 *prism2int, u32 *wlanint);
-
-/* enumerated integer conversion functions */
-void prism2mgmt_prism2enum2p80211enum(u16 *prism2enum, u32 *wlanenum, u16 rid);
-void prism2mgmt_p80211enum2prism2enum(u16 *prism2enum, u32 *wlanenum, u16 rid);
-
-/* functions to convert a bit area to/from an Operational Rate Set */
-void prism2mgmt_get_oprateset(u16 *rate, p80211pstrd_t *pstr);
-void prism2mgmt_set_oprateset(u16 *rate, p80211pstrd_t *pstr);
-
/* functions to convert Group Addresses */
-void prism2mgmt_get_grpaddr(u32 did,
- p80211pstrd_t *pstr, hfa384x_t *priv );
+void prism2mgmt_get_grpaddr(u32 did, p80211pstrd_t *pstr, hfa384x_t *priv);
int prism2mgmt_set_grpaddr(u32 did,
- u8 *prism2buf, p80211pstrd_t *pstr, hfa384x_t *priv );
-int prism2mgmt_get_grpaddr_index( u32 did );
+ u8 *prism2buf, p80211pstrd_t *pstr,
+ hfa384x_t *priv);
+int prism2mgmt_get_grpaddr_index(u32 did);
void prism2sta_processing_defer(struct work_struct *data);
void prism2sta_commsqual_defer(struct work_struct *data);
void prism2sta_commsqual_timer(unsigned long data);
-/*=============================================================*/
-/*--- Inline Function Definitions (if supported) --------------*/
-/*=============================================================*/
-
-
-
#endif
diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c
index 539c4479d38..5a6ba86009d 100644
--- a/drivers/staging/wlan-ng/prism2mib.c
+++ b/drivers/staging/wlan-ng/prism2mib.c
@@ -50,12 +50,7 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
#include <linux/version.h>
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -63,13 +58,11 @@
#include <linux/slab.h>
#include <linux/wireless.h>
#include <linux/netdevice.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
#include <linux/usb.h>
-
-/*================================================================*/
-/* Project Includes */
+#include <linux/bitops.h>
#include "p80211types.h"
#include "p80211hdr.h"
@@ -82,196 +75,169 @@
#include "hfa384x.h"
#include "prism2mgmt.h"
-/*================================================================*/
-/* Local Constants */
-
-#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */
-
-/*================================================================*/
-/* Local Types */
-
-#define F_STA 0x1 /* MIB is supported on stations. */
-#define F_READ 0x2 /* MIB may be read. */
-#define F_WRITE 0x4 /* MIB may be written. */
-
-typedef struct mibrec
-{
- u32 did;
- u16 flag;
- u16 parm1;
- u16 parm2;
- u16 parm3;
- int (*func)(struct mibrec *mib,
- int isget,
- wlandevice_t *wlandev,
- hfa384x_t *hw,
- p80211msg_dot11req_mibset_t *msg,
- void *data);
+#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */
+
+#define F_STA 0x1 /* MIB is supported on stations. */
+#define F_READ 0x2 /* MIB may be read. */
+#define F_WRITE 0x4 /* MIB may be written. */
+
+typedef struct mibrec {
+ u32 did;
+ u16 flag;
+ u16 parm1;
+ u16 parm2;
+ u16 parm3;
+ int (*func) (struct mibrec *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data);
} mibrec_t;
-/*================================================================*/
-/* Local Function Declarations */
-
-static int prism2mib_bytearea2pstr(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-static int prism2mib_uint32(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-static int prism2mib_flag(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-static int prism2mib_wepdefaultkey(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-static int prism2mib_privacyinvoked(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-static int prism2mib_excludeunencrypted(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-static int prism2mib_fragmentationthreshold(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-static int prism2mib_priv(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data);
-
-/*================================================================*/
-/* Local Static Definitions */
+static int prism2mib_bytearea2pstr(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data);
+
+static int prism2mib_uint32(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data);
+
+static int prism2mib_flag(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data);
+
+static int prism2mib_wepdefaultkey(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data);
+
+static int prism2mib_privacyinvoked(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data);
+
+static int prism2mib_excludeunencrypted(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data);
+
+static int prism2mib_fragmentationthreshold(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data);
+
+static int prism2mib_priv(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data);
static mibrec_t mibtab[] = {
- /* dot11smt MIB's */
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
- F_STA | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
- prism2mib_wepdefaultkey },
- { DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
- prism2mib_privacyinvoked },
- { DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
- prism2mib_excludeunencrypted },
-
- /* dot11mac MIB's */
-
- { DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
- prism2mib_bytearea2pstr },
- { DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_RTSTHRESH, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
- F_STA | F_READ,
- HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
- F_STA | F_READ,
- HFA384x_RID_LONGRETRYLIMIT, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_FRAGTHRESH, 0, 0,
- prism2mib_fragmentationthreshold },
- { DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
- F_STA | F_READ,
- HFA384x_RID_MAXTXLIFETIME, 0, 0,
- prism2mib_uint32 },
-
- /* dot11phy MIB's */
-
- { DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
- F_STA | F_READ,
- HFA384x_RID_CURRENTCHANNEL, 0, 0,
- prism2mib_uint32 },
- { DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_TXPOWERMAX, 0, 0,
- prism2mib_uint32 },
-
- /* p2Static MIB's */
-
- { DIDmib_p2_p2Static_p2CnfPortType,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFPORTTYPE, 0, 0,
- prism2mib_uint32 },
-
- /* p2MAC MIB's */
-
- { DIDmib_p2_p2MAC_p2CurrentTxRate,
- F_STA | F_READ,
- HFA384x_RID_CURRENTTXRATE, 0, 0,
- prism2mib_uint32 },
-
- /* And finally, lnx mibs */
- { DIDmib_lnx_lnxConfigTable_lnxRSNAIE,
- F_STA | F_READ | F_WRITE,
- HFA384x_RID_CNFWPADATA, 0, 0,
- prism2mib_priv },
- { 0, 0, 0, 0, 0, NULL}};
-
-/*================================================================*/
-/* Function Definitions */
+ /* dot11smt MIB's */
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3,
+ F_STA | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0,
+ prism2mib_wepdefaultkey},
+ {DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0,
+ prism2mib_privacyinvoked},
+ {DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0,
+ prism2mib_excludeunencrypted},
+
+ /* dot11mac MIB's */
+
+ {DIDmib_dot11mac_dot11OperationTable_dot11MACAddress,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0,
+ prism2mib_bytearea2pstr},
+ {DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_RTSTHRESH, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit,
+ F_STA | F_READ,
+ HFA384x_RID_SHORTRETRYLIMIT, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit,
+ F_STA | F_READ,
+ HFA384x_RID_LONGRETRYLIMIT, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_FRAGTHRESH, 0, 0,
+ prism2mib_fragmentationthreshold},
+ {DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime,
+ F_STA | F_READ,
+ HFA384x_RID_MAXTXLIFETIME, 0, 0,
+ prism2mib_uint32},
+
+ /* dot11phy MIB's */
+
+ {DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTCHANNEL, 0, 0,
+ prism2mib_uint32},
+ {DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_TXPOWERMAX, 0, 0,
+ prism2mib_uint32},
+
+ /* p2Static MIB's */
+
+ {DIDmib_p2_p2Static_p2CnfPortType,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFPORTTYPE, 0, 0,
+ prism2mib_uint32},
+
+ /* p2MAC MIB's */
+
+ {DIDmib_p2_p2MAC_p2CurrentTxRate,
+ F_STA | F_READ,
+ HFA384x_RID_CURRENTTXRATE, 0, 0,
+ prism2mib_uint32},
+
+ /* And finally, lnx mibs */
+ {DIDmib_lnx_lnxConfigTable_lnxRSNAIE,
+ F_STA | F_READ | F_WRITE,
+ HFA384x_RID_CNFWPADATA, 0, 0,
+ prism2mib_priv},
+ {0, 0, 0, 0, 0, NULL}
+};
/*----------------------------------------------------------------
* prism2mgmt_mibset_mibget
@@ -295,32 +261,30 @@ static mibrec_t mibtab[] = {
int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
{
- hfa384x_t *hw = wlandev->priv;
- int result, isget;
- mibrec_t *mib;
-
- u16 which;
+ hfa384x_t *hw = wlandev->priv;
+ int result, isget;
+ mibrec_t *mib;
- p80211msg_dot11req_mibset_t *msg = msgp;
- p80211itemd_t *mibitem;
+ u16 which;
- DBFENTER;
+ p80211msg_dot11req_mibset_t *msg = msgp;
+ p80211itemd_t *mibitem;
msg->resultcode.status = P80211ENUM_msgitem_status_data_ok;
msg->resultcode.data = P80211ENUM_resultcode_success;
/*
- ** Determine if this is an Access Point or a station.
- */
+ ** Determine if this is an Access Point or a station.
+ */
which = F_STA;
/*
- ** Find the MIB in the MIB table. Note that a MIB may be in the
- ** table twice...once for an AP and once for a station. Make sure
- ** to get the correct one. Note that DID=0 marks the end of the
- ** MIB table.
- */
+ ** Find the MIB in the MIB table. Note that a MIB may be in the
+ ** table twice...once for an AP and once for a station. Make sure
+ ** to get the correct one. Note that DID=0 marks the end of the
+ ** MIB table.
+ */
mibitem = (p80211itemd_t *) msg->mibattribute.data;
@@ -334,58 +298,55 @@ int prism2mgmt_mibset_mibget(wlandevice_t *wlandev, void *msgp)
}
/*
- ** Determine if this is a "mibget" or a "mibset". If this is a
- ** "mibget", then make sure that the MIB may be read. Otherwise,
- ** this is a "mibset" so make make sure that the MIB may be written.
- */
+ ** Determine if this is a "mibget" or a "mibset". If this is a
+ ** "mibget", then make sure that the MIB may be read. Otherwise,
+ ** this is a "mibset" so make make sure that the MIB may be written.
+ */
isget = (msg->msgcode == DIDmsg_dot11req_mibget);
if (isget) {
if (!(mib->flag & F_READ)) {
msg->resultcode.data =
- P80211ENUM_resultcode_cant_get_writeonly_mib;
+ P80211ENUM_resultcode_cant_get_writeonly_mib;
goto done;
}
} else {
if (!(mib->flag & F_WRITE)) {
msg->resultcode.data =
- P80211ENUM_resultcode_cant_set_readonly_mib;
+ P80211ENUM_resultcode_cant_set_readonly_mib;
goto done;
}
}
/*
- ** Execute the MIB function. If things worked okay, then make
- ** sure that the MIB function also worked okay. If so, and this
- ** is a "mibget", then the status value must be set for both the
- ** "mibattribute" parameter and the mib item within the data
- ** portion of the "mibattribute".
- */
+ ** Execute the MIB function. If things worked okay, then make
+ ** sure that the MIB function also worked okay. If so, and this
+ ** is a "mibget", then the status value must be set for both the
+ ** "mibattribute" parameter and the mib item within the data
+ ** portion of the "mibattribute".
+ */
- result = mib->func(mib, isget, wlandev, hw, msg,
- (void *) mibitem->data);
+ result = mib->func(mib, isget, wlandev, hw, msg, (void *)mibitem->data);
if (msg->resultcode.data == P80211ENUM_resultcode_success) {
if (result != 0) {
- WLAN_LOG_DEBUG(1, "get/set failure, result=%d\n",
- result);
+ pr_debug("get/set failure, result=%d\n",
+ result);
msg->resultcode.data =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
} else {
if (isget) {
msg->mibattribute.status =
- P80211ENUM_msgitem_status_data_ok;
+ P80211ENUM_msgitem_status_data_ok;
mibitem->status =
- P80211ENUM_msgitem_status_data_ok;
+ P80211ENUM_msgitem_status_data_ok;
}
}
}
done:
- DBFEXIT;
-
- return(0);
+ return 0;
}
/*----------------------------------------------------------------
@@ -413,31 +374,29 @@ done:
*
----------------------------------------------------------------*/
-static int prism2mib_bytearea2pstr(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_bytearea2pstr(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
- p80211pstrd_t *pstr = (p80211pstrd_t*) data;
- u8 bytebuf[MIB_TMP_MAXLEN];
-
- DBFENTER;
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
if (isget) {
- result = hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
+ result =
+ hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2);
prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2);
} else {
memset(bytebuf, 0, mib->parm2);
prism2mgmt_pstr2bytearea(bytebuf, pstr);
- result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
+ result =
+ hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2);
}
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -465,37 +424,26 @@ void *data)
*
----------------------------------------------------------------*/
-static int prism2mib_uint32(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_uint32(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data)
{
- int result;
- u32 *uint32 = (u32*) data;
- u8 bytebuf[MIB_TMP_MAXLEN];
- u16 *wordbuf = (u16*) bytebuf;
-
- DBFENTER;
+ int result;
+ u32 *uint32 = (u32 *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
+ u16 *wordbuf = (u16 *) bytebuf;
if (isget) {
result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
*uint32 = *wordbuf;
- /* [MSM] Removed, getconfig16 returns the value in host order.
- * prism2mgmt_prism2int2p80211int(wordbuf, uint32);
- */
} else {
- /* [MSM] Removed, setconfig16 expects host order.
- * prism2mgmt_p80211int2prism2int(wordbuf, uint32);
- */
*wordbuf = *uint32;
result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
}
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -523,46 +471,36 @@ void *data)
*
----------------------------------------------------------------*/
-static int prism2mib_flag(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_flag(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data)
{
- int result;
- u32 *uint32 = (u32*) data;
- u8 bytebuf[MIB_TMP_MAXLEN];
- u16 *wordbuf = (u16*) bytebuf;
- u32 flags;
-
- DBFENTER;
+ int result;
+ u32 *uint32 = (u32 *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
+ u16 *wordbuf = (u16 *) bytebuf;
+ u32 flags;
result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf);
if (result == 0) {
- /* [MSM] Removed, getconfig16 returns the value in host order.
- * prism2mgmt_prism2int2p80211int(wordbuf, &flags);
- */
flags = *wordbuf;
if (isget) {
*uint32 = (flags & mib->parm2) ?
- P80211ENUM_truth_true : P80211ENUM_truth_false;
+ P80211ENUM_truth_true : P80211ENUM_truth_false;
} else {
if ((*uint32) == P80211ENUM_truth_true)
flags |= mib->parm2;
else
flags &= ~mib->parm2;
- /* [MSM] Removed, setconfig16 expects host order.
- * prism2mgmt_p80211int2prism2int(wordbuf, &flags);
- */
*wordbuf = flags;
- result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
+ result =
+ hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf);
}
}
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -590,33 +528,29 @@ void *data)
*
----------------------------------------------------------------*/
-static int prism2mib_wepdefaultkey(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_wepdefaultkey(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
- p80211pstrd_t *pstr = (p80211pstrd_t*) data;
- u8 bytebuf[MIB_TMP_MAXLEN];
- u16 len;
-
- DBFENTER;
+ int result;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
+ u8 bytebuf[MIB_TMP_MAXLEN];
+ u16 len;
if (isget) {
- result = 0; /* Should never happen. */
+ result = 0; /* Should never happen. */
} else {
len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN :
- HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
+ HFA384x_RID_CNFWEPDEFAULTKEY_LEN;
memset(bytebuf, 0, len);
prism2mgmt_pstr2bytearea(bytebuf, pstr);
result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len);
}
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -644,17 +578,14 @@ void *data)
*
----------------------------------------------------------------*/
-static int prism2mib_privacyinvoked(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_privacyinvoked(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
-
- DBFENTER;
+ int result;
if (wlandev->hostwep & HOSTWEP_DECRYPT) {
if (wlandev->hostwep & HOSTWEP_DECRYPT)
@@ -665,8 +596,7 @@ void *data)
result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -694,22 +624,18 @@ void *data)
*
----------------------------------------------------------------*/
-static int prism2mib_excludeunencrypted(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_excludeunencrypted(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
-
- DBFENTER;
+ int result;
result = prism2mib_flag(mib, isget, wlandev, hw, msg, data);
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -737,31 +663,28 @@ void *data)
*
----------------------------------------------------------------*/
-static int prism2mib_fragmentationthreshold(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_fragmentationthreshold(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg,
+ void *data)
{
- int result;
- u32 *uint32 = (u32*) data;
-
- DBFENTER;
+ int result;
+ u32 *uint32 = (u32 *) data;
if (!isget)
if ((*uint32) % 2) {
- WLAN_LOG_WARNING("Attempt to set odd number "
- "FragmentationThreshold\n");
- msg->resultcode.data = P80211ENUM_resultcode_not_supported;
- return(0);
+ printk(KERN_WARNING "Attempt to set odd number "
+ "FragmentationThreshold\n");
+ msg->resultcode.data =
+ P80211ENUM_resultcode_not_supported;
+ return 0;
}
result = prism2mib_uint32(mib, isget, wlandev, hw, msg, data);
- DBFEXIT;
- return(result);
+ return result;
}
/*----------------------------------------------------------------
@@ -789,43 +712,43 @@ void *data)
*
----------------------------------------------------------------*/
-static int prism2mib_priv(
-mibrec_t *mib,
-int isget,
-wlandevice_t *wlandev,
-hfa384x_t *hw,
-p80211msg_dot11req_mibset_t *msg,
-void *data)
+static int prism2mib_priv(mibrec_t *mib,
+ int isget,
+ wlandevice_t *wlandev,
+ hfa384x_t *hw,
+ p80211msg_dot11req_mibset_t *msg, void *data)
{
- p80211pstrd_t *pstr = (p80211pstrd_t*) data;
+ p80211pstrd_t *pstr = (p80211pstrd_t *) data;
- int result;
-
- DBFENTER;
+ int result;
switch (mib->did) {
- case DIDmib_lnx_lnxConfigTable_lnxRSNAIE: {
- hfa384x_WPAData_t wpa;
- if (isget) {
- hfa384x_drvr_getconfig( hw, HFA384x_RID_CNFWPADATA,
- (u8 *) &wpa, sizeof(wpa));
- pstr->len = hfa384x2host_16(wpa.datalen);
- memcpy(pstr->data, wpa.data, pstr->len);
- } else {
- wpa.datalen = host2hfa384x_16(pstr->len);
- memcpy(wpa.data, pstr->data, pstr->len);
-
- result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFWPADATA,
- (u8 *) &wpa, sizeof(wpa));
+ case DIDmib_lnx_lnxConfigTable_lnxRSNAIE:{
+ hfa384x_WPAData_t wpa;
+ if (isget) {
+ hfa384x_drvr_getconfig(hw,
+ HFA384x_RID_CNFWPADATA,
+ (u8 *)&wpa,
+ sizeof(wpa));
+ pstr->len = le16_to_cpu(wpa.datalen);
+ memcpy(pstr->data, wpa.data, pstr->len);
+ } else {
+ wpa.datalen = cpu_to_le16(pstr->len);
+ memcpy(wpa.data, pstr->data, pstr->len);
+
+ result =
+ hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_CNFWPADATA,
+ (u8 *)&wpa,
+ sizeof(wpa));
+ }
+ break;
}
- break;
- }
default:
- WLAN_LOG_ERROR("Unhandled DID 0x%08x\n", mib->did);
+ printk(KERN_ERR "Unhandled DID 0x%08x\n", mib->did);
}
- DBFEXIT;
- return(0);
+ return 0;
}
/*----------------------------------------------------------------
@@ -845,14 +768,10 @@ void *data)
void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
{
- DBFENTER;
-
- bytestr->len = host2hfa384x_16((u16)(pstr->len));
+ bytestr->len = cpu_to_le16((u16) (pstr->len));
memcpy(bytestr->data, pstr->data, pstr->len);
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* prism2mgmt_pstr2bytearea
*
@@ -870,13 +789,9 @@ void prism2mgmt_pstr2bytestr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr)
{
- DBFENTER;
-
memcpy(bytearea, pstr->data, pstr->len);
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* prism2mgmt_bytestr2pstr
*
@@ -894,14 +809,10 @@ void prism2mgmt_pstr2bytearea(u8 *bytearea, p80211pstrd_t *pstr)
void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
{
- DBFENTER;
-
- pstr->len = (u8)(hfa384x2host_16((u16)(bytestr->len)));
+ pstr->len = (u8) (le16_to_cpu((u16) (bytestr->len)));
memcpy(pstr->data, bytestr->data, pstr->len);
- DBFEXIT;
}
-
/*----------------------------------------------------------------
* prism2mgmt_bytearea2pstr
*
@@ -919,217 +830,11 @@ void prism2mgmt_bytestr2pstr(hfa384x_bytestr_t *bytestr, p80211pstrd_t *pstr)
void prism2mgmt_bytearea2pstr(u8 *bytearea, p80211pstrd_t *pstr, int len)
{
- DBFENTER;
-
- pstr->len = (u8)len;
+ pstr->len = (u8) len;
memcpy(pstr->data, bytearea, len);
- DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_prism2int2p80211int
-*
-* Convert an hfa384x integer into a wlan integer
-*
-* Arguments:
-* prism2enum pointer to hfa384x integer
-* wlanenum pointer to p80211 integer
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
-
-void prism2mgmt_prism2int2p80211int(u16 *prism2int, u32 *wlanint)
-{
- DBFENTER;
-
- *wlanint = (u32)hfa384x2host_16(*prism2int);
- DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_p80211int2prism2int
-*
-* Convert a wlan integer into an hfa384x integer
-*
-* Arguments:
-* prism2enum pointer to hfa384x integer
-* wlanenum pointer to p80211 integer
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
-
-void prism2mgmt_p80211int2prism2int(u16 *prism2int, u32 *wlanint)
-{
- DBFENTER;
-
- *prism2int = host2hfa384x_16((u16)(*wlanint));
- DBFEXIT;
-}
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_prism2enum2p80211enum
-*
-* Convert the hfa384x enumerated int into a p80211 enumerated int
-*
-* Arguments:
-* prism2enum pointer to hfa384x integer
-* wlanenum pointer to p80211 integer
-* rid hfa384x record id
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_prism2enum2p80211enum(u16 *prism2enum, u32 *wlanenum, u16 rid)
-{
- DBFENTER;
-
- /* At the moment, the need for this functionality hasn't
- presented itself. All the wlan enumerated values are
- a 1-to-1 match against the Prism2 enumerated values*/
- DBFEXIT;
- return;
}
-/*----------------------------------------------------------------
-* prism2mgmt_p80211enum2prism2enum
-*
-* Convert the p80211 enumerated int into an hfa384x enumerated int
-*
-* Arguments:
-* prism2enum pointer to hfa384x integer
-* wlanenum pointer to p80211 integer
-* rid hfa384x record id
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_p80211enum2prism2enum(u16 *prism2enum, u32 *wlanenum, u16 rid)
-{
- DBFENTER;
-
- /* At the moment, the need for this functionality hasn't
- presented itself. All the wlan enumerated values are
- a 1-to-1 match against the Prism2 enumerated values*/
- DBFEXIT;
- return;
-}
-
-/*----------------------------------------------------------------
-* prism2mgmt_get_oprateset
-*
-* Convert the hfa384x bit area into a wlan octet string.
-*
-* Arguments:
-* rate Prism2 bit area
-* pstr wlan octet string
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_get_oprateset(u16 *rate, p80211pstrd_t *pstr)
-{
- u8 len;
- u8 *datarate;
-
- DBFENTER;
-
- len = 0;
- datarate = pstr->data;
-
- /* 1 Mbps */
- if ( BIT0 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)2;
- datarate++;
- }
- /* 2 Mbps */
- if ( BIT1 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)4;
- datarate++;
- }
-
- /* 5.5 Mbps */
- if ( BIT2 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)11;
- datarate++;
- }
-
- /* 11 Mbps */
- if ( BIT3 & (*rate) ) {
- len += (u8)1;
- *datarate = (u8)22;
- datarate++;
- }
-
- pstr->len = len;
-
- DBFEXIT;
- return;
-}
-
-
-
-/*----------------------------------------------------------------
-* prism2mgmt_set_oprateset
-*
-* Convert the wlan octet string into an hfa384x bit area.
-*
-* Arguments:
-* rate Prism2 bit area
-* pstr wlan octet string
-*
-* Returns:
-* Nothing
-*
-----------------------------------------------------------------*/
-void prism2mgmt_set_oprateset(u16 *rate, p80211pstrd_t *pstr)
-{
- u8 *datarate;
- int i;
-
- DBFENTER;
-
- *rate = 0;
-
- datarate = pstr->data;
-
- for ( i=0; i < pstr->len; i++, datarate++ ) {
- switch (*datarate) {
- case 2: /* 1 Mbps */
- *rate |= BIT0;
- break;
- case 4: /* 2 Mbps */
- *rate |= BIT1;
- break;
- case 11: /* 5.5 Mbps */
- *rate |= BIT2;
- break;
- case 22: /* 11 Mbps */
- *rate |= BIT3;
- break;
- default:
- WLAN_LOG_DEBUG(1, "Unrecoginzed Rate of %d\n",
- *datarate);
- break;
- }
- }
-
- DBFEXIT;
- return;
-}
diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c
index b279c97cbc0..9d57f82f4a2 100644
--- a/drivers/staging/wlan-ng/prism2sta.c
+++ b/drivers/staging/wlan-ng/prism2sta.c
@@ -50,10 +50,6 @@
* --------------------------------------------------------------------
*/
-/*================================================================*/
-/* System Includes */
-#define WLAN_DBVAR prism2_debug
-
#include <linux/version.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -65,13 +61,15 @@
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <linux/workqueue.h>
+#include <linux/byteorder/generic.h>
+#include <linux/ctype.h>
#include <asm/io.h>
#include <linux/delay.h>
#include <asm/byteorder.h>
#include <linux/if_arp.h>
-
-#include "wlan_compat.h"
+#include <linux/if_ether.h>
+#include <linux/bitops.h>
/*================================================================*/
/* Project Includes */
@@ -88,111 +86,78 @@
#include "hfa384x.h"
#include "prism2mgmt.h"
-/*================================================================*/
-/* Local Constants */
-
-/*================================================================*/
-/* Local Macros */
-
-/*================================================================*/
-/* Local Types */
-
-/*================================================================*/
-/* Local Static Definitions */
+#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
+
+/* Create a string of printable chars from something that might not be */
+/* It's recommended that the str be 4*len + 1 bytes long */
+#define wlan_mkprintstr(buf, buflen, str, strlen) \
+{ \
+ int i = 0; \
+ int j = 0; \
+ memset(str, 0, (strlen)); \
+ for (i = 0; i < (buflen); i++) { \
+ if (isprint((buf)[i])) { \
+ (str)[j] = (buf)[i]; \
+ j++; \
+ } else { \
+ (str)[j] = '\\'; \
+ (str)[j+1] = 'x'; \
+ (str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
+ (str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
+ j += 4; \
+ } \
+ } \
+}
static char *dev_info = "prism2_usb";
-
static wlandevice_t *create_wlan(void);
-/*----------------------------------------------------------------*/
-/* --Module Parameters */
+int prism2_reset_holdtime = 30; /* Reset hold time in ms */
+int prism2_reset_settletime = 100; /* Reset settle time in ms */
-int prism2_reset_holdtime=30; /* Reset hold time in ms */
-int prism2_reset_settletime=100; /* Reset settle time in ms */
+static int prism2_doreset = 0; /* Do a reset at init? */
-static int prism2_doreset=0; /* Do a reset at init? */
-
-#ifdef WLAN_INCLUDE_DEBUG
-int prism2_debug=0;
-module_param( prism2_debug, int, 0644);
-MODULE_PARM_DESC(prism2_debug, "prism2 debugging");
-#endif
-
-module_param( prism2_doreset, int, 0644);
+module_param(prism2_doreset, int, 0644);
MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization");
-module_param( prism2_reset_holdtime, int, 0644);
-MODULE_PARM_DESC( prism2_reset_holdtime, "reset hold time in ms");
-module_param( prism2_reset_settletime, int, 0644);
-MODULE_PARM_DESC( prism2_reset_settletime, "reset settle time in ms");
+module_param(prism2_reset_holdtime, int, 0644);
+MODULE_PARM_DESC(prism2_reset_holdtime, "reset hold time in ms");
+module_param(prism2_reset_settletime, int, 0644);
+MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms");
MODULE_LICENSE("Dual MPL/GPL");
-/*================================================================*/
-/* Local Function Declarations */
-
-static int prism2sta_open(wlandevice_t *wlandev);
-static int prism2sta_close(wlandevice_t *wlandev);
-static void prism2sta_reset(wlandevice_t *wlandev );
-static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb, p80211_hdr_t *p80211_hdr, p80211_metawep_t *p80211_wep);
-static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
-static int prism2sta_getcardinfo(wlandevice_t *wlandev);
-static int prism2sta_globalsetup(wlandevice_t *wlandev);
-static int prism2sta_setmulticast(wlandevice_t *wlandev,
- netdevice_t *dev);
-
-static void prism2sta_inf_handover(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_tallies(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_hostscanresults(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_scanresults(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_chinforesults(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_linkstatus(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_assocstatus(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_authreq(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_authreq_defer(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-static void prism2sta_inf_psusercnt(
- wlandevice_t *wlandev, hfa384x_InfFrame_t *inf);
-
-/*================================================================*/
-/* Function Definitions */
-
-/*----------------------------------------------------------------
-* dmpmem
-*
-* Debug utility function to dump memory to the kernel debug log.
-*
-* Arguments:
-* buf ptr data we want dumped
-* len length of data
-*
-* Returns:
-* nothing
-* Side effects:
-*
-* Call context:
-* process thread
-* interrupt
-----------------------------------------------------------------*/
-inline void dmpmem(void *buf, int n)
-{
- int c;
- for ( c= 0; c < n; c++) {
- if ( (c % 16) == 0 ) printk(KERN_DEBUG"dmp[%d]: ", c);
- printk("%02x ", ((u8*)buf)[c]);
- if ( (c % 16) == 15 ) printk("\n");
- }
- if ( (c % 16) != 0 ) printk("\n");
-}
-
+static int prism2sta_open(wlandevice_t *wlandev);
+static int prism2sta_close(wlandevice_t *wlandev);
+static void prism2sta_reset(wlandevice_t *wlandev);
+static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
+ p80211_hdr_t *p80211_hdr,
+ p80211_metawep_t *p80211_wep);
+static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg);
+static int prism2sta_getcardinfo(wlandevice_t *wlandev);
+static int prism2sta_globalsetup(wlandevice_t *wlandev);
+static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev);
+
+static void prism2sta_inf_handover(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_tallies(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_authreq(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
+static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf);
/*----------------------------------------------------------------
* prism2sta_open
@@ -217,8 +182,6 @@ inline void dmpmem(void *buf, int n)
----------------------------------------------------------------*/
static int prism2sta_open(wlandevice_t *wlandev)
{
- DBFENTER;
-
/* We don't currently have to do anything else.
* The setup of the MAC should be subsequently completed via
* the mlme commands.
@@ -227,11 +190,9 @@ static int prism2sta_open(wlandevice_t *wlandev)
* frames because of dev->flags&IFF_UP is true.
*/
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2sta_close
*
@@ -255,19 +216,15 @@ static int prism2sta_open(wlandevice_t *wlandev)
----------------------------------------------------------------*/
static int prism2sta_close(wlandevice_t *wlandev)
{
- DBFENTER;
-
/* We don't currently have to do anything else.
* Higher layers know we're not ready from dev->start==0 and
* dev->tbusy==1. Our rx path knows to not pass up received
* frames because of dev->flags&IFF_UP is false.
*/
- DBFEXIT;
return 0;
}
-
/*----------------------------------------------------------------
* prism2sta_reset
*
@@ -285,14 +242,11 @@ static int prism2sta_close(wlandevice_t *wlandev)
* Call context:
* process thread
----------------------------------------------------------------*/
-static void prism2sta_reset(wlandevice_t *wlandev )
+static void prism2sta_reset(wlandevice_t *wlandev)
{
- DBFENTER;
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_txframe
*
@@ -318,22 +272,20 @@ static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
p80211_hdr_t *p80211_hdr,
p80211_metawep_t *p80211_wep)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- int result;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ int result;
/* If necessary, set the 802.11 WEP bit */
- if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == HOSTWEP_PRIVACYINVOKED) {
- p80211_hdr->a3.fc |= host2ieee16(WLAN_SET_FC_ISWEP(1));
+ if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) ==
+ HOSTWEP_PRIVACYINVOKED) {
+ p80211_hdr->a3.fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1));
}
result = hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep);
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_mlmerequest
*
@@ -360,109 +312,113 @@ static int prism2sta_txframe(wlandevice_t *wlandev, struct sk_buff *skb,
----------------------------------------------------------------*/
static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
int result = 0;
- DBFENTER;
- switch( msg->msgcode )
- {
- case DIDmsg_dot11req_mibget :
- WLAN_LOG_DEBUG(2,"Received mibget request\n");
+ switch (msg->msgcode) {
+ case DIDmsg_dot11req_mibget:
+ pr_debug("Received mibget request\n");
result = prism2mgmt_mibset_mibget(wlandev, msg);
break;
- case DIDmsg_dot11req_mibset :
- WLAN_LOG_DEBUG(2,"Received mibset request\n");
+ case DIDmsg_dot11req_mibset:
+ pr_debug("Received mibset request\n");
result = prism2mgmt_mibset_mibget(wlandev, msg);
break;
- case DIDmsg_dot11req_scan :
- WLAN_LOG_DEBUG(2,"Received scan request\n");
+ case DIDmsg_dot11req_scan:
+ pr_debug("Received scan request\n");
result = prism2mgmt_scan(wlandev, msg);
break;
- case DIDmsg_dot11req_scan_results :
- WLAN_LOG_DEBUG(2,"Received scan_results request\n");
+ case DIDmsg_dot11req_scan_results:
+ pr_debug("Received scan_results request\n");
result = prism2mgmt_scan_results(wlandev, msg);
break;
- case DIDmsg_dot11req_start :
- WLAN_LOG_DEBUG(2,"Received mlme start request\n");
+ case DIDmsg_dot11req_start:
+ pr_debug("Received mlme start request\n");
result = prism2mgmt_start(wlandev, msg);
break;
- /*
- * Prism2 specific messages
- */
- case DIDmsg_p2req_readpda :
- WLAN_LOG_DEBUG(2,"Received mlme readpda request\n");
+ /*
+ * Prism2 specific messages
+ */
+ case DIDmsg_p2req_readpda:
+ pr_debug("Received mlme readpda request\n");
result = prism2mgmt_readpda(wlandev, msg);
break;
- case DIDmsg_p2req_ramdl_state :
- WLAN_LOG_DEBUG(2,"Received mlme ramdl_state request\n");
+ case DIDmsg_p2req_ramdl_state:
+ pr_debug("Received mlme ramdl_state request\n");
result = prism2mgmt_ramdl_state(wlandev, msg);
break;
- case DIDmsg_p2req_ramdl_write :
- WLAN_LOG_DEBUG(2,"Received mlme ramdl_write request\n");
+ case DIDmsg_p2req_ramdl_write:
+ pr_debug("Received mlme ramdl_write request\n");
result = prism2mgmt_ramdl_write(wlandev, msg);
break;
- case DIDmsg_p2req_flashdl_state :
- WLAN_LOG_DEBUG(2,"Received mlme flashdl_state request\n");
+ case DIDmsg_p2req_flashdl_state:
+ pr_debug("Received mlme flashdl_state request\n");
result = prism2mgmt_flashdl_state(wlandev, msg);
break;
- case DIDmsg_p2req_flashdl_write :
- WLAN_LOG_DEBUG(2,"Received mlme flashdl_write request\n");
+ case DIDmsg_p2req_flashdl_write:
+ pr_debug("Received mlme flashdl_write request\n");
result = prism2mgmt_flashdl_write(wlandev, msg);
break;
- /*
- * Linux specific messages
- */
- case DIDmsg_lnxreq_hostwep :
- break; // ignore me.
- case DIDmsg_lnxreq_ifstate :
+ /*
+ * Linux specific messages
+ */
+ case DIDmsg_lnxreq_hostwep:
+ break; /* ignore me. */
+ case DIDmsg_lnxreq_ifstate:
{
- p80211msg_lnxreq_ifstate_t *ifstatemsg;
- WLAN_LOG_DEBUG(2,"Received mlme ifstate request\n");
- ifstatemsg = (p80211msg_lnxreq_ifstate_t*)msg;
- result = prism2sta_ifstate(wlandev, ifstatemsg->ifstate.data);
- ifstatemsg->resultcode.status =
- P80211ENUM_msgitem_status_data_ok;
- ifstatemsg->resultcode.data = result;
- result = 0;
+ p80211msg_lnxreq_ifstate_t *ifstatemsg;
+ pr_debug("Received mlme ifstate request\n");
+ ifstatemsg = (p80211msg_lnxreq_ifstate_t *) msg;
+ result =
+ prism2sta_ifstate(wlandev,
+ ifstatemsg->ifstate.data);
+ ifstatemsg->resultcode.status =
+ P80211ENUM_msgitem_status_data_ok;
+ ifstatemsg->resultcode.data = result;
+ result = 0;
}
- break;
- case DIDmsg_lnxreq_wlansniff :
- WLAN_LOG_DEBUG(2,"Received mlme wlansniff request\n");
- result = prism2mgmt_wlansniff(wlandev, msg);
- break;
- case DIDmsg_lnxreq_autojoin :
- WLAN_LOG_DEBUG(2,"Received mlme autojoin request\n");
+ break;
+ case DIDmsg_lnxreq_wlansniff:
+ pr_debug("Received mlme wlansniff request\n");
+ result = prism2mgmt_wlansniff(wlandev, msg);
+ break;
+ case DIDmsg_lnxreq_autojoin:
+ pr_debug("Received mlme autojoin request\n");
result = prism2mgmt_autojoin(wlandev, msg);
break;
- case DIDmsg_lnxreq_commsquality: {
- p80211msg_lnxreq_commsquality_t *qualmsg;
-
- WLAN_LOG_DEBUG(2,"Received commsquality request\n");
+ case DIDmsg_lnxreq_commsquality:{
+ p80211msg_lnxreq_commsquality_t *qualmsg;
- qualmsg = (p80211msg_lnxreq_commsquality_t*) msg;
+ pr_debug("Received commsquality request\n");
- qualmsg->link.status = P80211ENUM_msgitem_status_data_ok;
- qualmsg->level.status = P80211ENUM_msgitem_status_data_ok;
- qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok;
+ qualmsg = (p80211msg_lnxreq_commsquality_t *) msg;
+ qualmsg->link.status =
+ P80211ENUM_msgitem_status_data_ok;
+ qualmsg->level.status =
+ P80211ENUM_msgitem_status_data_ok;
+ qualmsg->noise.status =
+ P80211ENUM_msgitem_status_data_ok;
- qualmsg->link.data = hfa384x2host_16(hw->qual.CQ_currBSS);
- qualmsg->level.data = hfa384x2host_16(hw->qual.ASL_currBSS);
- qualmsg->noise.data = hfa384x2host_16(hw->qual.ANL_currFC);
+ qualmsg->link.data =
+ le16_to_cpu(hw->qual.CQ_currBSS);
+ qualmsg->level.data =
+ le16_to_cpu(hw->qual.ASL_currBSS);
+ qualmsg->noise.data =
+ le16_to_cpu(hw->qual.ANL_currFC);
- break;
- }
+ break;
+ }
default:
- WLAN_LOG_WARNING("Unknown mgmt request message 0x%08x", msg->msgcode);
+ printk(KERN_WARNING "Unknown mgmt request message 0x%08x",
+ msg->msgcode);
break;
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_ifstate
*
@@ -486,16 +442,14 @@ static int prism2sta_mlmerequest(wlandevice_t *wlandev, p80211msg_t *msg)
----------------------------------------------------------------*/
u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- u32 result;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ u32 result;
result = P80211ENUM_resultcode_implementation_failure;
- WLAN_LOG_DEBUG(2, "Current MSD state(%d), requesting(%d)\n",
- wlandev->msdstate, ifstate);
- switch (ifstate)
- {
+ pr_debug("Current MSD state(%d), requesting(%d)\n",
+ wlandev->msdstate, ifstate);
+ switch (ifstate) {
case P80211ENUM_ifstate_fwload:
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
@@ -504,12 +458,12 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
* Initialize the device+driver sufficiently
* for firmware loading.
*/
- if ((result=hfa384x_drvr_start(hw))) {
- WLAN_LOG_ERROR(
- "hfa384x_drvr_start() failed,"
- "result=%d\n", (int)result);
+ if ((result = hfa384x_drvr_start(hw))) {
+ printk(KERN_ERR
+ "hfa384x_drvr_start() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
@@ -521,9 +475,9 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_RUNNING:
- WLAN_LOG_WARNING(
- "Cannot enter fwload state from enable state,"
- "you must disable first.\n");
+ printk(KERN_WARNING
+ "Cannot enter fwload state from enable state,"
+ "you must disable first.\n");
result = P80211ENUM_resultcode_invalid_parameters;
break;
case WLAN_MSD_HWFAIL:
@@ -548,32 +502,32 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
* can't make any assumptions about the state
* of the hardware or a previous firmware load.
*/
- if ((result=hfa384x_drvr_start(hw))) {
- WLAN_LOG_ERROR(
- "hfa384x_drvr_start() failed,"
- "result=%d\n", (int)result);
+ if ((result = hfa384x_drvr_start(hw))) {
+ printk(KERN_ERR
+ "hfa384x_drvr_start() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
- if ((result=prism2sta_getcardinfo(wlandev))) {
- WLAN_LOG_ERROR(
- "prism2sta_getcardinfo() failed,"
- "result=%d\n", (int)result);
+ if ((result = prism2sta_getcardinfo(wlandev))) {
+ printk(KERN_ERR
+ "prism2sta_getcardinfo() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
hfa384x_drvr_stop(hw);
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
}
- if ((result=prism2sta_globalsetup(wlandev))) {
- WLAN_LOG_ERROR(
- "prism2sta_globalsetup() failed,"
- "result=%d\n", (int)result);
+ if ((result = prism2sta_globalsetup(wlandev))) {
+ printk(KERN_ERR
+ "prism2sta_globalsetup() failed,"
+ "result=%d\n", (int)result);
result =
- P80211ENUM_resultcode_implementation_failure;
+ P80211ENUM_resultcode_implementation_failure;
hfa384x_drvr_stop(hw);
wlandev->msdstate = WLAN_MSD_HWPRESENT;
break;
@@ -584,7 +538,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_RUNNING:
- /* Do nothing, we're already in this state.*/
+ /* Do nothing, we're already in this state. */
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_HWFAIL:
@@ -599,7 +553,7 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
case P80211ENUM_ifstate_disable:
switch (wlandev->msdstate) {
case WLAN_MSD_HWPRESENT:
- /* Do nothing, we're already in this state.*/
+ /* Do nothing, we're already in this state. */
result = P80211ENUM_resultcode_success;
break;
case WLAN_MSD_FWLOAD:
@@ -634,11 +588,9 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
break;
}
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_getcardinfo
*
@@ -660,269 +612,284 @@ u32 prism2sta_ifstate(wlandevice_t *wlandev, u32 ifstate)
----------------------------------------------------------------*/
static int prism2sta_getcardinfo(wlandevice_t *wlandev)
{
- int result = 0;
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- u16 temp;
- u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
- char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
-
- DBFENTER;
+ int result = 0;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ u16 temp;
+ u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN];
+ char pstr[(HFA384x_RID_NICSERIALNUMBER_LEN * 4) + 1];
/* Collect version and compatibility info */
/* Some are critical, some are not */
/* NIC identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY,
- &hw->ident_nic, sizeof(hfa384x_compident_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve NICIDENTITY\n");
+ &hw->ident_nic,
+ sizeof(hfa384x_compident_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve NICIDENTITY\n");
goto failed;
}
/* get all the nic id fields in host byte order */
- hw->ident_nic.id = hfa384x2host_16(hw->ident_nic.id);
- hw->ident_nic.variant = hfa384x2host_16(hw->ident_nic.variant);
- hw->ident_nic.major = hfa384x2host_16(hw->ident_nic.major);
- hw->ident_nic.minor = hfa384x2host_16(hw->ident_nic.minor);
+ hw->ident_nic.id = le16_to_cpu(hw->ident_nic.id);
+ hw->ident_nic.variant = le16_to_cpu(hw->ident_nic.variant);
+ hw->ident_nic.major = le16_to_cpu(hw->ident_nic.major);
+ hw->ident_nic.minor = le16_to_cpu(hw->ident_nic.minor);
- WLAN_LOG_INFO( "ident: nic h/w: id=0x%02x %d.%d.%d\n",
- hw->ident_nic.id, hw->ident_nic.major,
- hw->ident_nic.minor, hw->ident_nic.variant);
+ printk(KERN_INFO "ident: nic h/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_nic.id, hw->ident_nic.major,
+ hw->ident_nic.minor, hw->ident_nic.variant);
/* Primary f/w identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY,
- &hw->ident_pri_fw, sizeof(hfa384x_compident_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve PRIIDENTITY\n");
+ &hw->ident_pri_fw,
+ sizeof(hfa384x_compident_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve PRIIDENTITY\n");
goto failed;
}
/* get all the private fw id fields in host byte order */
- hw->ident_pri_fw.id = hfa384x2host_16(hw->ident_pri_fw.id);
- hw->ident_pri_fw.variant = hfa384x2host_16(hw->ident_pri_fw.variant);
- hw->ident_pri_fw.major = hfa384x2host_16(hw->ident_pri_fw.major);
- hw->ident_pri_fw.minor = hfa384x2host_16(hw->ident_pri_fw.minor);
+ hw->ident_pri_fw.id = le16_to_cpu(hw->ident_pri_fw.id);
+ hw->ident_pri_fw.variant = le16_to_cpu(hw->ident_pri_fw.variant);
+ hw->ident_pri_fw.major = le16_to_cpu(hw->ident_pri_fw.major);
+ hw->ident_pri_fw.minor = le16_to_cpu(hw->ident_pri_fw.minor);
- WLAN_LOG_INFO( "ident: pri f/w: id=0x%02x %d.%d.%d\n",
- hw->ident_pri_fw.id, hw->ident_pri_fw.major,
- hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
+ printk(KERN_INFO "ident: pri f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_pri_fw.id, hw->ident_pri_fw.major,
+ hw->ident_pri_fw.minor, hw->ident_pri_fw.variant);
/* Station (Secondary?) f/w identity */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY,
- &hw->ident_sta_fw, sizeof(hfa384x_compident_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve STAIDENTITY\n");
+ &hw->ident_sta_fw,
+ sizeof(hfa384x_compident_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve STAIDENTITY\n");
goto failed;
}
if (hw->ident_nic.id < 0x8000) {
- WLAN_LOG_ERROR("FATAL: Card is not an Intersil Prism2/2.5/3\n");
+ printk(KERN_ERR
+ "FATAL: Card is not an Intersil Prism2/2.5/3\n");
result = -1;
goto failed;
}
/* get all the station fw id fields in host byte order */
- hw->ident_sta_fw.id = hfa384x2host_16(hw->ident_sta_fw.id);
- hw->ident_sta_fw.variant = hfa384x2host_16(hw->ident_sta_fw.variant);
- hw->ident_sta_fw.major = hfa384x2host_16(hw->ident_sta_fw.major);
- hw->ident_sta_fw.minor = hfa384x2host_16(hw->ident_sta_fw.minor);
+ hw->ident_sta_fw.id = le16_to_cpu(hw->ident_sta_fw.id);
+ hw->ident_sta_fw.variant = le16_to_cpu(hw->ident_sta_fw.variant);
+ hw->ident_sta_fw.major = le16_to_cpu(hw->ident_sta_fw.major);
+ hw->ident_sta_fw.minor = le16_to_cpu(hw->ident_sta_fw.minor);
/* strip out the 'special' variant bits */
- hw->mm_mods = hw->ident_sta_fw.variant & (BIT14 | BIT15);
- hw->ident_sta_fw.variant &= ~((u16)(BIT14 | BIT15));
-
- if ( hw->ident_sta_fw.id == 0x1f ) {
- WLAN_LOG_INFO(
- "ident: sta f/w: id=0x%02x %d.%d.%d\n",
- hw->ident_sta_fw.id, hw->ident_sta_fw.major,
- hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+ hw->mm_mods = hw->ident_sta_fw.variant & (BIT(14) | BIT(15));
+ hw->ident_sta_fw.variant &= ~((u16) (BIT(14) | BIT(15)));
+
+ if (hw->ident_sta_fw.id == 0x1f) {
+ printk(KERN_INFO
+ "ident: sta f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
} else {
- WLAN_LOG_INFO(
- "ident: ap f/w: id=0x%02x %d.%d.%d\n",
- hw->ident_sta_fw.id, hw->ident_sta_fw.major,
- hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
- WLAN_LOG_ERROR("Unsupported Tertiary AP firmeare loaded!\n");
+ printk(KERN_INFO
+ "ident: ap f/w: id=0x%02x %d.%d.%d\n",
+ hw->ident_sta_fw.id, hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor, hw->ident_sta_fw.variant);
+ printk(KERN_ERR "Unsupported Tertiary AP firmeare loaded!\n");
goto failed;
}
/* Compatibility range, Modem supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE,
- &hw->cap_sup_mfi, sizeof(hfa384x_caplevel_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve MFISUPRANGE\n");
+ &hw->cap_sup_mfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve MFISUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, modem interface supplier
- fields in byte order */
- hw->cap_sup_mfi.role = hfa384x2host_16(hw->cap_sup_mfi.role);
- hw->cap_sup_mfi.id = hfa384x2host_16(hw->cap_sup_mfi.id);
- hw->cap_sup_mfi.variant = hfa384x2host_16(hw->cap_sup_mfi.variant);
- hw->cap_sup_mfi.bottom = hfa384x2host_16(hw->cap_sup_mfi.bottom);
- hw->cap_sup_mfi.top = hfa384x2host_16(hw->cap_sup_mfi.top);
-
- WLAN_LOG_INFO(
- "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
- hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
- hw->cap_sup_mfi.top);
+ fields in byte order */
+ hw->cap_sup_mfi.role = le16_to_cpu(hw->cap_sup_mfi.role);
+ hw->cap_sup_mfi.id = le16_to_cpu(hw->cap_sup_mfi.id);
+ hw->cap_sup_mfi.variant = le16_to_cpu(hw->cap_sup_mfi.variant);
+ hw->cap_sup_mfi.bottom = le16_to_cpu(hw->cap_sup_mfi.bottom);
+ hw->cap_sup_mfi.top = le16_to_cpu(hw->cap_sup_mfi.top);
+
+ printk(KERN_INFO
+ "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_mfi.role, hw->cap_sup_mfi.id,
+ hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom,
+ hw->cap_sup_mfi.top);
/* Compatibility range, Controller supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE,
- &hw->cap_sup_cfi, sizeof(hfa384x_caplevel_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve CFISUPRANGE\n");
+ &hw->cap_sup_cfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve CFISUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, controller interface supplier
- fields in byte order */
- hw->cap_sup_cfi.role = hfa384x2host_16(hw->cap_sup_cfi.role);
- hw->cap_sup_cfi.id = hfa384x2host_16(hw->cap_sup_cfi.id);
- hw->cap_sup_cfi.variant = hfa384x2host_16(hw->cap_sup_cfi.variant);
- hw->cap_sup_cfi.bottom = hfa384x2host_16(hw->cap_sup_cfi.bottom);
- hw->cap_sup_cfi.top = hfa384x2host_16(hw->cap_sup_cfi.top);
-
- WLAN_LOG_INFO(
- "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
- hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
- hw->cap_sup_cfi.top);
+ fields in byte order */
+ hw->cap_sup_cfi.role = le16_to_cpu(hw->cap_sup_cfi.role);
+ hw->cap_sup_cfi.id = le16_to_cpu(hw->cap_sup_cfi.id);
+ hw->cap_sup_cfi.variant = le16_to_cpu(hw->cap_sup_cfi.variant);
+ hw->cap_sup_cfi.bottom = le16_to_cpu(hw->cap_sup_cfi.bottom);
+ hw->cap_sup_cfi.top = le16_to_cpu(hw->cap_sup_cfi.top);
+
+ printk(KERN_INFO
+ "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_cfi.role, hw->cap_sup_cfi.id,
+ hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom,
+ hw->cap_sup_cfi.top);
/* Compatibility range, Primary f/w supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE,
- &hw->cap_sup_pri, sizeof(hfa384x_caplevel_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve PRISUPRANGE\n");
+ &hw->cap_sup_pri,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve PRISUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, primary firmware supplier
- fields in byte order */
- hw->cap_sup_pri.role = hfa384x2host_16(hw->cap_sup_pri.role);
- hw->cap_sup_pri.id = hfa384x2host_16(hw->cap_sup_pri.id);
- hw->cap_sup_pri.variant = hfa384x2host_16(hw->cap_sup_pri.variant);
- hw->cap_sup_pri.bottom = hfa384x2host_16(hw->cap_sup_pri.bottom);
- hw->cap_sup_pri.top = hfa384x2host_16(hw->cap_sup_pri.top);
-
- WLAN_LOG_INFO(
- "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_sup_pri.role, hw->cap_sup_pri.id,
- hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
- hw->cap_sup_pri.top);
+ fields in byte order */
+ hw->cap_sup_pri.role = le16_to_cpu(hw->cap_sup_pri.role);
+ hw->cap_sup_pri.id = le16_to_cpu(hw->cap_sup_pri.id);
+ hw->cap_sup_pri.variant = le16_to_cpu(hw->cap_sup_pri.variant);
+ hw->cap_sup_pri.bottom = le16_to_cpu(hw->cap_sup_pri.bottom);
+ hw->cap_sup_pri.top = le16_to_cpu(hw->cap_sup_pri.top);
+
+ printk(KERN_INFO
+ "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_pri.role, hw->cap_sup_pri.id,
+ hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom,
+ hw->cap_sup_pri.top);
/* Compatibility range, Station f/w supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE,
- &hw->cap_sup_sta, sizeof(hfa384x_caplevel_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve STASUPRANGE\n");
+ &hw->cap_sup_sta,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve STASUPRANGE\n");
goto failed;
}
/* get all the Compatibility range, station firmware supplier
- fields in byte order */
- hw->cap_sup_sta.role = hfa384x2host_16(hw->cap_sup_sta.role);
- hw->cap_sup_sta.id = hfa384x2host_16(hw->cap_sup_sta.id);
- hw->cap_sup_sta.variant = hfa384x2host_16(hw->cap_sup_sta.variant);
- hw->cap_sup_sta.bottom = hfa384x2host_16(hw->cap_sup_sta.bottom);
- hw->cap_sup_sta.top = hfa384x2host_16(hw->cap_sup_sta.top);
-
- if ( hw->cap_sup_sta.id == 0x04 ) {
- WLAN_LOG_INFO(
- "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_sup_sta.role, hw->cap_sup_sta.id,
- hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
- hw->cap_sup_sta.top);
+ fields in byte order */
+ hw->cap_sup_sta.role = le16_to_cpu(hw->cap_sup_sta.role);
+ hw->cap_sup_sta.id = le16_to_cpu(hw->cap_sup_sta.id);
+ hw->cap_sup_sta.variant = le16_to_cpu(hw->cap_sup_sta.variant);
+ hw->cap_sup_sta.bottom = le16_to_cpu(hw->cap_sup_sta.bottom);
+ hw->cap_sup_sta.top = le16_to_cpu(hw->cap_sup_sta.top);
+
+ if (hw->cap_sup_sta.id == 0x04) {
+ printk(KERN_INFO
+ "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+ hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+ hw->cap_sup_sta.top);
} else {
- WLAN_LOG_INFO(
- "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_sup_sta.role, hw->cap_sup_sta.id,
- hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
- hw->cap_sup_sta.top);
+ printk(KERN_INFO
+ "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_sup_sta.role, hw->cap_sup_sta.id,
+ hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom,
+ hw->cap_sup_sta.top);
}
/* Compatibility range, primary f/w actor, CFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES,
- &hw->cap_act_pri_cfi, sizeof(hfa384x_caplevel_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve PRI_CFIACTRANGES\n");
+ &hw->cap_act_pri_cfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve PRI_CFIACTRANGES\n");
goto failed;
}
/* get all the Compatibility range, primary f/w actor, CFI supplier
- fields in byte order */
- hw->cap_act_pri_cfi.role = hfa384x2host_16(hw->cap_act_pri_cfi.role);
- hw->cap_act_pri_cfi.id = hfa384x2host_16(hw->cap_act_pri_cfi.id);
- hw->cap_act_pri_cfi.variant = hfa384x2host_16(hw->cap_act_pri_cfi.variant);
- hw->cap_act_pri_cfi.bottom = hfa384x2host_16(hw->cap_act_pri_cfi.bottom);
- hw->cap_act_pri_cfi.top = hfa384x2host_16(hw->cap_act_pri_cfi.top);
-
- WLAN_LOG_INFO(
- "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
- hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
- hw->cap_act_pri_cfi.top);
+ fields in byte order */
+ hw->cap_act_pri_cfi.role = le16_to_cpu(hw->cap_act_pri_cfi.role);
+ hw->cap_act_pri_cfi.id = le16_to_cpu(hw->cap_act_pri_cfi.id);
+ hw->cap_act_pri_cfi.variant =
+ le16_to_cpu(hw->cap_act_pri_cfi.variant);
+ hw->cap_act_pri_cfi.bottom =
+ le16_to_cpu(hw->cap_act_pri_cfi.bottom);
+ hw->cap_act_pri_cfi.top = le16_to_cpu(hw->cap_act_pri_cfi.top);
+
+ printk(KERN_INFO
+ "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id,
+ hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom,
+ hw->cap_act_pri_cfi.top);
/* Compatibility range, sta f/w actor, CFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES,
- &hw->cap_act_sta_cfi, sizeof(hfa384x_caplevel_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve STA_CFIACTRANGES\n");
+ &hw->cap_act_sta_cfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve STA_CFIACTRANGES\n");
goto failed;
}
/* get all the Compatibility range, station f/w actor, CFI supplier
- fields in byte order */
- hw->cap_act_sta_cfi.role = hfa384x2host_16(hw->cap_act_sta_cfi.role);
- hw->cap_act_sta_cfi.id = hfa384x2host_16(hw->cap_act_sta_cfi.id);
- hw->cap_act_sta_cfi.variant = hfa384x2host_16(hw->cap_act_sta_cfi.variant);
- hw->cap_act_sta_cfi.bottom = hfa384x2host_16(hw->cap_act_sta_cfi.bottom);
- hw->cap_act_sta_cfi.top = hfa384x2host_16(hw->cap_act_sta_cfi.top);
-
- WLAN_LOG_INFO(
- "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
- hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
- hw->cap_act_sta_cfi.top);
+ fields in byte order */
+ hw->cap_act_sta_cfi.role = le16_to_cpu(hw->cap_act_sta_cfi.role);
+ hw->cap_act_sta_cfi.id = le16_to_cpu(hw->cap_act_sta_cfi.id);
+ hw->cap_act_sta_cfi.variant =
+ le16_to_cpu(hw->cap_act_sta_cfi.variant);
+ hw->cap_act_sta_cfi.bottom =
+ le16_to_cpu(hw->cap_act_sta_cfi.bottom);
+ hw->cap_act_sta_cfi.top = le16_to_cpu(hw->cap_act_sta_cfi.top);
+
+ printk(KERN_INFO
+ "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id,
+ hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom,
+ hw->cap_act_sta_cfi.top);
/* Compatibility range, sta f/w actor, MFI supplier */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES,
- &hw->cap_act_sta_mfi, sizeof(hfa384x_caplevel_t));
- if ( result ) {
- WLAN_LOG_ERROR("Failed to retrieve STA_MFIACTRANGES\n");
+ &hw->cap_act_sta_mfi,
+ sizeof(hfa384x_caplevel_t));
+ if (result) {
+ printk(KERN_ERR "Failed to retrieve STA_MFIACTRANGES\n");
goto failed;
}
/* get all the Compatibility range, station f/w actor, MFI supplier
- fields in byte order */
- hw->cap_act_sta_mfi.role = hfa384x2host_16(hw->cap_act_sta_mfi.role);
- hw->cap_act_sta_mfi.id = hfa384x2host_16(hw->cap_act_sta_mfi.id);
- hw->cap_act_sta_mfi.variant = hfa384x2host_16(hw->cap_act_sta_mfi.variant);
- hw->cap_act_sta_mfi.bottom = hfa384x2host_16(hw->cap_act_sta_mfi.bottom);
- hw->cap_act_sta_mfi.top = hfa384x2host_16(hw->cap_act_sta_mfi.top);
-
- WLAN_LOG_INFO(
- "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
- hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
- hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
- hw->cap_act_sta_mfi.top);
+ fields in byte order */
+ hw->cap_act_sta_mfi.role = le16_to_cpu(hw->cap_act_sta_mfi.role);
+ hw->cap_act_sta_mfi.id = le16_to_cpu(hw->cap_act_sta_mfi.id);
+ hw->cap_act_sta_mfi.variant =
+ le16_to_cpu(hw->cap_act_sta_mfi.variant);
+ hw->cap_act_sta_mfi.bottom =
+ le16_to_cpu(hw->cap_act_sta_mfi.bottom);
+ hw->cap_act_sta_mfi.top = le16_to_cpu(hw->cap_act_sta_mfi.top);
+
+ printk(KERN_INFO
+ "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n",
+ hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id,
+ hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom,
+ hw->cap_act_sta_mfi.top);
/* Serial Number */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER,
- snum, HFA384x_RID_NICSERIALNUMBER_LEN);
- if ( !result ) {
+ snum, HFA384x_RID_NICSERIALNUMBER_LEN);
+ if (!result) {
wlan_mkprintstr(snum, HFA384x_RID_NICSERIALNUMBER_LEN,
pstr, sizeof(pstr));
- WLAN_LOG_INFO("Prism2 card SN: %s\n", pstr);
+ printk(KERN_INFO "Prism2 card SN: %s\n", pstr);
} else {
- WLAN_LOG_ERROR("Failed to retrieve Prism2 Card SN\n");
+ printk(KERN_ERR "Failed to retrieve Prism2 Card SN\n");
goto failed;
}
/* Collect the MAC address */
result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR,
- wlandev->netdev->dev_addr, WLAN_ADDR_LEN);
- if ( result != 0 ) {
- WLAN_LOG_ERROR("Failed to retrieve mac address\n");
+ wlandev->netdev->dev_addr, ETH_ALEN);
+ if (result != 0) {
+ printk(KERN_ERR "Failed to retrieve mac address\n");
goto failed;
}
@@ -939,10 +906,10 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
hw->dbmadjust = temp;
/* Only enable scan by default on newer firmware */
- if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
- hw->ident_sta_fw.minor,
- hw->ident_sta_fw.variant) <
- HFA384x_FIRMWARE_VERSION(1,5,5)) {
+ if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major,
+ hw->ident_sta_fw.minor,
+ hw->ident_sta_fw.variant) <
+ HFA384x_FIRMWARE_VERSION(1, 5, 5)) {
wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN;
}
@@ -950,13 +917,11 @@ static int prism2sta_getcardinfo(wlandevice_t *wlandev)
goto done;
failed:
- WLAN_LOG_ERROR("Failed, result=%d\n", result);
+ printk(KERN_ERR "Failed, result=%d\n", result);
done:
- DBFEXIT;
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_globalsetup
*
@@ -977,43 +942,33 @@ done:
----------------------------------------------------------------*/
static int prism2sta_globalsetup(wlandevice_t *wlandev)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
/* Set the maximum frame size */
return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN,
- WLAN_DATA_MAXLEN);
+ WLAN_DATA_MAXLEN);
}
static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
{
int result = 0;
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
- u16 promisc;
-
- DBFENTER;
+ u16 promisc;
/* If we're not ready, what's the point? */
- if ( hw->state != HFA384x_STATE_RUNNING )
+ if (hw->state != HFA384x_STATE_RUNNING)
goto exit;
- if ( (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0 )
+ if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0)
promisc = P80211ENUM_truth_true;
else
promisc = P80211ENUM_truth_false;
- result = hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, promisc);
-
- /* XXX TODO: configure the multicast list */
- // CLEAR_HW_MULTICAST_LIST
- // struct dev_mc_list element = dev->mc_list;
- // while (element != null) {
- // HW_ADD_MULTICAST_ADDR(element->dmi_addr, dmi_addrlen)
- // element = element->next;
- // }
-
- exit:
- DBFEXIT;
+ result =
+ hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE,
+ promisc);
+exit:
return result;
}
@@ -1035,15 +990,13 @@ static int prism2sta_setmulticast(wlandevice_t *wlandev, netdevice_t *dev)
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_handover(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
{
- DBFENTER;
- WLAN_LOG_DEBUG(2,"received infoframe:HANDOVER (unhandled)\n");
- DBFEXIT;
+ pr_debug("received infoframe:HANDOVER (unhandled)\n");
return;
}
-
/*----------------------------------------------------------------
* prism2sta_inf_tallies
*
@@ -1061,37 +1014,34 @@ static void prism2sta_inf_handover(wlandevice_t *wlandev, hfa384x_InfFrame_t *in
* Call context:
* interrupt
----------------------------------------------------------------*/
-static void prism2sta_inf_tallies(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
+static void prism2sta_inf_tallies(wlandevice_t *wlandev,
+ hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- u16 *src16;
- u32 *dst;
- u32 *src32;
- int i;
- int cnt;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ u16 *src16;
+ u32 *dst;
+ u32 *src32;
+ int i;
+ int cnt;
/*
- ** Determine if these are 16-bit or 32-bit tallies, based on the
- ** record length of the info record.
- */
+ ** Determine if these are 16-bit or 32-bit tallies, based on the
+ ** record length of the info record.
+ */
cnt = sizeof(hfa384x_CommTallies32_t) / sizeof(u32);
if (inf->framelen > 22) {
- dst = (u32 *) &hw->tallies;
- src32 = (u32 *) &inf->info.commtallies32;
+ dst = (u32 *)&hw->tallies;
+ src32 = (u32 *)&inf->info.commtallies32;
for (i = 0; i < cnt; i++, dst++, src32++)
- *dst += hfa384x2host_32(*src32);
+ *dst += le32_to_cpu(*src32);
} else {
- dst = (u32 *) &hw->tallies;
- src16 = (u16 *) &inf->info.commtallies16;
+ dst = (u32 *)&hw->tallies;
+ src16 = (u16 *)&inf->info.commtallies16;
for (i = 0; i < cnt; i++, dst++, src16++)
- *dst += hfa384x2host_16(*src16);
+ *dst += le16_to_cpu(*src16);
}
- DBFEXIT;
-
return;
}
@@ -1116,44 +1066,40 @@ static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- int nbss;
- hfa384x_ScanResult_t *sr = &(inf->info.scanresult);
- int i;
- hfa384x_JoinRequest_data_t joinreq;
- int result;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ int nbss;
+ hfa384x_ScanResult_t *sr = &(inf->info.scanresult);
+ int i;
+ hfa384x_JoinRequest_data_t joinreq;
+ int result;
/* Get the number of results, first in bytes, then in results */
nbss = (inf->framelen * sizeof(u16)) -
- sizeof(inf->infotype) -
- sizeof(inf->info.scanresult.scanreason);
+ sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason);
nbss /= sizeof(hfa384x_ScanResultSub_t);
/* Print em */
- WLAN_LOG_DEBUG(1,"rx scanresults, reason=%d, nbss=%d:\n",
- inf->info.scanresult.scanreason, nbss);
- for ( i = 0; i < nbss; i++) {
- WLAN_LOG_DEBUG(1, "chid=%d anl=%d sl=%d bcnint=%d\n",
- sr->result[i].chid,
- sr->result[i].anl,
- sr->result[i].sl,
- sr->result[i].bcnint);
- WLAN_LOG_DEBUG(1, " capinfo=0x%04x proberesp_rate=%d\n",
- sr->result[i].capinfo,
- sr->result[i].proberesp_rate);
+ pr_debug("rx scanresults, reason=%d, nbss=%d:\n",
+ inf->info.scanresult.scanreason, nbss);
+ for (i = 0; i < nbss; i++) {
+ pr_debug("chid=%d anl=%d sl=%d bcnint=%d\n",
+ sr->result[i].chid,
+ sr->result[i].anl,
+ sr->result[i].sl, sr->result[i].bcnint);
+ pr_debug(" capinfo=0x%04x proberesp_rate=%d\n",
+ sr->result[i].capinfo, sr->result[i].proberesp_rate);
}
/* issue a join request */
joinreq.channel = sr->result[0].chid;
- memcpy( joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
- result = hfa384x_drvr_setconfig( hw,
- HFA384x_RID_JOINREQUEST,
- &joinreq, HFA384x_RID_JOINREQUEST_LEN);
+ memcpy(joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN);
+ result = hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq, HFA384x_RID_JOINREQUEST_LEN);
if (result) {
- WLAN_LOG_ERROR("setconfig(joinreq) failed, result=%d\n", result);
+ printk(KERN_ERR "setconfig(joinreq) failed, result=%d\n",
+ result);
}
- DBFEXIT;
return;
}
@@ -1177,18 +1123,16 @@ static void prism2sta_inf_scanresults(wlandevice_t *wlandev,
static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- int nbss;
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ int nbss;
nbss = (inf->framelen - 3) / 32;
- WLAN_LOG_DEBUG(1, "Received %d hostscan results\n", nbss);
+ pr_debug("Received %d hostscan results\n", nbss);
if (nbss > 32)
nbss = 32;
- if (hw->scanresults)
- kfree(hw->scanresults);
+ kfree(hw->scanresults);
hw->scanresults = kmalloc(sizeof(hfa384x_InfFrame_t), GFP_ATOMIC);
memcpy(hw->scanresults, inf, sizeof(hfa384x_InfFrame_t));
@@ -1196,11 +1140,9 @@ static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
if (nbss == 0)
nbss = -1;
- /* Notify/wake the sleeping caller. */
- hw->scanflag = nbss;
- wake_up_interruptible(&hw->cmdq);
-
- DBFEXIT;
+ /* Notify/wake the sleeping caller. */
+ hw->scanflag = nbss;
+ wake_up_interruptible(&hw->cmdq);
};
/*----------------------------------------------------------------
@@ -1223,55 +1165,60 @@ static void prism2sta_inf_hostscanresults(wlandevice_t *wlandev,
static void prism2sta_inf_chinforesults(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- unsigned int i, n;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ unsigned int i, n;
- DBFENTER;
hw->channel_info.results.scanchannels =
- hfa384x2host_16(inf->info.chinforesult.scanchannels);
-#if 0
- memcpy(&inf->info.chinforesult, &hw->channel_info.results, sizeof(hfa384x_ChInfoResult_t));
-#endif
-
- for (i=0, n=0; i<HFA384x_CHINFORESULT_MAX; i++) {
- if (hw->channel_info.results.scanchannels & (1<<i)) {
- int channel=hfa384x2host_16(inf->info.chinforesult.result[n].chid)-1;
- hfa384x_ChInfoResultSub_t *chinforesult=&hw->channel_info.results.result[channel];
- chinforesult->chid = channel;
- chinforesult->anl = hfa384x2host_16(inf->info.chinforesult.result[n].anl);
- chinforesult->pnl = hfa384x2host_16(inf->info.chinforesult.result[n].pnl);
- chinforesult->active = hfa384x2host_16(inf->info.chinforesult.result[n].active);
- WLAN_LOG_DEBUG(2, "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
- channel+1,
- chinforesult->active &
- HFA384x_CHINFORESULT_BSSACTIVE ? "signal" : "noise",
- chinforesult->anl, chinforesult->pnl,
- chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0
- );
+ le16_to_cpu(inf->info.chinforesult.scanchannels);
+
+ for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) {
+ if (hw->channel_info.results.scanchannels & (1 << i)) {
+ int channel =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ chid) - 1;
+ hfa384x_ChInfoResultSub_t *chinforesult =
+ &hw->channel_info.results.result[channel];
+ chinforesult->chid = channel;
+ chinforesult->anl =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ anl);
+ chinforesult->pnl =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ pnl);
+ chinforesult->active =
+ le16_to_cpu(inf->info.chinforesult.result[n].
+ active);
+ printk(KERN_DEBUG
+ "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n",
+ channel + 1,
+ chinforesult->
+ active & HFA384x_CHINFORESULT_BSSACTIVE ?
+ "signal" : "noise", chinforesult->anl,
+ chinforesult->pnl,
+ chinforesult->
+ active & HFA384x_CHINFORESULT_PCFACTIVE ? 1 : 0);
n++;
}
}
atomic_set(&hw->channel_info.done, 2);
hw->channel_info.count = n;
- DBFEXIT;
return;
}
void prism2sta_processing_defer(struct work_struct *data)
{
- hfa384x_t *hw = container_of(data, struct hfa384x, link_bh);
- wlandevice_t *wlandev = hw->wlandev;
+ hfa384x_t *hw = container_of(data, struct hfa384x, link_bh);
+ wlandevice_t *wlandev = hw->wlandev;
hfa384x_bytestr32_t ssid;
- int result;
+ int result;
- DBFENTER;
/* First let's process the auth frames */
{
- struct sk_buff *skb;
+ struct sk_buff *skb;
hfa384x_InfFrame_t *inf;
- while ( (skb = skb_dequeue(&hw->authq)) ) {
+ while ((skb = skb_dequeue(&hw->authq))) {
inf = (hfa384x_InfFrame_t *) skb->data;
prism2sta_inf_authreq_defer(wlandev, inf);
}
@@ -1284,7 +1231,7 @@ void prism2sta_processing_defer(struct work_struct *data)
hw->link_status = hw->link_status_new;
- switch(hw->link_status) {
+ switch (hw->link_status) {
case HFA384x_LINK_NOTCONNECTED:
/* I'm currently assuming that this is the initial link
* state. It should only be possible immediately
@@ -1294,7 +1241,7 @@ void prism2sta_processing_defer(struct work_struct *data)
*/
netif_carrier_off(wlandev->netdev);
- WLAN_LOG_INFO("linkstatus=NOTCONNECTED (unhandled)\n");
+ printk(KERN_INFO "linkstatus=NOTCONNECTED (unhandled)\n");
break;
case HFA384x_LINK_CONNECTED:
@@ -1311,53 +1258,56 @@ void prism2sta_processing_defer(struct work_struct *data)
netif_carrier_on(wlandev->netdev);
/* If we are joining a specific AP, set our state and reset retries */
- if(hw->join_ap == 1)
+ if (hw->join_ap == 1)
hw->join_ap = 2;
hw->join_retries = 60;
/* Don't call this in monitor mode */
- if ( wlandev->netdev->type == ARPHRD_ETHER ) {
- u16 portstatus;
+ if (wlandev->netdev->type == ARPHRD_ETHER) {
+ u16 portstatus;
- WLAN_LOG_INFO("linkstatus=CONNECTED\n");
+ printk(KERN_INFO "linkstatus=CONNECTED\n");
/* For non-usb devices, we can use the sync versions */
/* Collect the BSSID, and set state to allow tx */
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTBSSID,
- wlandev->bssid, WLAN_BSSID_LEN);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "getconfig(0x%02x) failed, result = %d\n",
- HFA384x_RID_CURRENTBSSID, result);
+ wlandev->bssid,
+ WLAN_BSSID_LEN);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTBSSID, result);
goto failed;
}
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTSSID,
&ssid, sizeof(ssid));
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "getconfig(0x%02x) failed, result = %d\n",
- HFA384x_RID_CURRENTSSID, result);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
goto failed;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
- (p80211pstrd_t *) &wlandev->ssid);
+ (p80211pstrd_t *)&wlandev->
+ ssid);
/* Collect the port status */
result = hfa384x_drvr_getconfig16(hw,
- HFA384x_RID_PORTSTATUS, &portstatus);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "getconfig(0x%02x) failed, result = %d\n",
- HFA384x_RID_PORTSTATUS, result);
+ HFA384x_RID_PORTSTATUS,
+ &portstatus);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_PORTSTATUS, result);
goto failed;
}
wlandev->macmode =
- (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
- WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
+ (portstatus == HFA384x_PSTATUS_CONN_IBSS) ?
+ WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA;
/* Get the ball rolling on the comms quality stuff */
prism2sta_commsqual_defer(&hw->commsqual_bh);
@@ -1374,18 +1324,20 @@ void prism2sta_processing_defer(struct work_struct *data)
* Indicate Deauthentication
* Block Transmits, Ignore receives of data frames
*/
- if(hw->join_ap == 2)
- {
- hfa384x_JoinRequest_data_t joinreq;
+ if (hw->join_ap == 2) {
+ hfa384x_JoinRequest_data_t joinreq;
joinreq = hw->joinreq;
/* Send the join request */
- hfa384x_drvr_setconfig( hw,
- HFA384x_RID_JOINREQUEST,
- &joinreq, HFA384x_RID_JOINREQUEST_LEN);
- WLAN_LOG_INFO("linkstatus=DISCONNECTED (re-submitting join)\n");
+ hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq,
+ HFA384x_RID_JOINREQUEST_LEN);
+ printk(KERN_INFO
+ "linkstatus=DISCONNECTED (re-submitting join)\n");
} else {
if (wlandev->netdev->type == ARPHRD_ETHER)
- WLAN_LOG_INFO("linkstatus=DISCONNECTED (unhandled)\n");
+ printk(KERN_INFO
+ "linkstatus=DISCONNECTED (unhandled)\n");
}
wlandev->macmode = WLAN_MACMODE_NONE;
@@ -1408,30 +1360,29 @@ void prism2sta_processing_defer(struct work_struct *data)
* Indicate Reassociation
* Enable Transmits, Receives and pass up data frames
*/
- WLAN_LOG_INFO("linkstatus=AP_CHANGE\n");
+ printk(KERN_INFO "linkstatus=AP_CHANGE\n");
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTBSSID,
wlandev->bssid, WLAN_BSSID_LEN);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "getconfig(0x%02x) failed, result = %d\n",
- HFA384x_RID_CURRENTBSSID, result);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTBSSID, result);
goto failed;
}
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTSSID,
&ssid, sizeof(ssid));
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "getconfig(0x%02x) failed, result = %d\n",
- HFA384x_RID_CURRENTSSID, result);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
goto failed;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
- (p80211pstrd_t *) &wlandev->ssid);
-
+ (p80211pstrd_t *)&wlandev->ssid);
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
@@ -1450,7 +1401,7 @@ void prism2sta_processing_defer(struct work_struct *data)
* Response:
* Block Transmits, Ignore receives of data frames
*/
- WLAN_LOG_INFO("linkstatus=AP_OUTOFRANGE (unhandled)\n");
+ printk(KERN_INFO "linkstatus=AP_OUTOFRANGE (unhandled)\n");
netif_carrier_off(wlandev->netdev);
@@ -1463,7 +1414,7 @@ void prism2sta_processing_defer(struct work_struct *data)
* Response:
* Enable Transmits, Receives and pass up data frames
*/
- WLAN_LOG_INFO("linkstatus=AP_INRANGE\n");
+ printk(KERN_INFO "linkstatus=AP_INRANGE\n");
hw->link_status = HFA384x_LINK_CONNECTED;
netif_carrier_on(wlandev->netdev);
@@ -1479,17 +1430,18 @@ void prism2sta_processing_defer(struct work_struct *data)
* Response:
* Disable Transmits, Ignore receives of data frames
*/
- if(hw->join_ap && --hw->join_retries > 0)
- {
- hfa384x_JoinRequest_data_t joinreq;
+ if (hw->join_ap && --hw->join_retries > 0) {
+ hfa384x_JoinRequest_data_t joinreq;
joinreq = hw->joinreq;
/* Send the join request */
- hfa384x_drvr_setconfig( hw,
- HFA384x_RID_JOINREQUEST,
- &joinreq, HFA384x_RID_JOINREQUEST_LEN);
- WLAN_LOG_INFO("linkstatus=ASSOCFAIL (re-submitting join)\n");
+ hfa384x_drvr_setconfig(hw,
+ HFA384x_RID_JOINREQUEST,
+ &joinreq,
+ HFA384x_RID_JOINREQUEST_LEN);
+ printk(KERN_INFO
+ "linkstatus=ASSOCFAIL (re-submitting join)\n");
} else {
- WLAN_LOG_INFO("linkstatus=ASSOCFAIL (unhandled)\n");
+ printk(KERN_INFO "linkstatus=ASSOCFAIL (unhandled)\n");
}
netif_carrier_off(wlandev->netdev);
@@ -1498,8 +1450,8 @@ void prism2sta_processing_defer(struct work_struct *data)
default:
/* This is bad, IO port problems? */
- WLAN_LOG_WARNING(
- "unknown linkstatus=0x%02x\n", hw->link_status);
+ printk(KERN_WARNING
+ "unknown linkstatus=0x%02x\n", hw->link_status);
goto failed;
break;
}
@@ -1509,8 +1461,8 @@ void prism2sta_processing_defer(struct work_struct *data)
p80211wext_event_associated(wlandev, wlandev->linkstatus);
#endif
- failed:
- DBFEXIT;
+failed:
+ return;
}
/*----------------------------------------------------------------
@@ -1533,15 +1485,12 @@ void prism2sta_processing_defer(struct work_struct *data)
static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
- DBFENTER;
-
- hw->link_status_new = hfa384x2host_16(inf->info.linkstatus.linkstatus);
+ hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus);
schedule_work(&hw->link_bh);
- DBFEXIT;
return;
}
@@ -1566,45 +1515,43 @@ static void prism2sta_inf_linkstatus(wlandevice_t *wlandev,
static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- hfa384x_AssocStatus_t rec;
- int i;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ hfa384x_AssocStatus_t rec;
+ int i;
memcpy(&rec, &inf->info.assocstatus, sizeof(rec));
- rec.assocstatus = hfa384x2host_16(rec.assocstatus);
- rec.reason = hfa384x2host_16(rec.reason);
+ rec.assocstatus = le16_to_cpu(rec.assocstatus);
+ rec.reason = le16_to_cpu(rec.reason);
/*
- ** Find the address in the list of authenticated stations. If it wasn't
- ** found, then this address has not been previously authenticated and
- ** something weird has happened if this is anything other than an
- ** "authentication failed" message. If the address was found, then
- ** set the "associated" flag for that station, based on whether the
- ** station is associating or losing its association. Something weird
- ** has also happened if we find the address in the list of authenticated
- ** stations but we are getting an "authentication failed" message.
- */
+ ** Find the address in the list of authenticated stations. If it wasn't
+ ** found, then this address has not been previously authenticated and
+ ** something weird has happened if this is anything other than an
+ ** "authentication failed" message. If the address was found, then
+ ** set the "associated" flag for that station, based on whether the
+ ** station is associating or losing its association. Something weird
+ ** has also happened if we find the address in the list of authenticated
+ ** stations but we are getting an "authentication failed" message.
+ */
for (i = 0; i < hw->authlist.cnt; i++)
- if (memcmp(rec.sta_addr, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+ if (memcmp(rec.sta_addr, hw->authlist.addr[i], ETH_ALEN) == 0)
break;
if (i >= hw->authlist.cnt) {
if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL)
- WLAN_LOG_WARNING("assocstatus info frame received for non-authenticated station.\n");
+ printk(KERN_WARNING
+ "assocstatus info frame received for non-authenticated station.\n");
} else {
hw->authlist.assoc[i] =
- (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
- rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
+ (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC ||
+ rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC);
if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL)
- WLAN_LOG_WARNING("authfail assocstatus info frame received for authenticated station.\n");
+ printk(KERN_WARNING
+ "authfail assocstatus info frame received for authenticated station.\n");
}
- DBFEXIT;
-
return;
}
@@ -1630,11 +1577,9 @@ static void prism2sta_inf_assocstatus(wlandevice_t *wlandev,
static void prism2sta_inf_authreq(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
struct sk_buff *skb;
- DBFENTER;
-
skb = dev_alloc_skb(sizeof(*inf));
if (skb) {
skb_put(skb, sizeof(*inf));
@@ -1642,132 +1587,129 @@ static void prism2sta_inf_authreq(wlandevice_t *wlandev,
skb_queue_tail(&hw->authq, skb);
schedule_work(&hw->link_bh);
}
-
- DBFEXIT;
}
static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
- hfa384x_authenticateStation_data_t rec;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
+ hfa384x_authenticateStation_data_t rec;
- int i, added, result, cnt;
- u8 *addr;
-
- DBFENTER;
+ int i, added, result, cnt;
+ u8 *addr;
/*
- ** Build the AuthenticateStation record. Initialize it for denying
- ** authentication.
- */
+ ** Build the AuthenticateStation record. Initialize it for denying
+ ** authentication.
+ */
- memcpy(rec.address, inf->info.authreq.sta_addr, WLAN_ADDR_LEN);
+ memcpy(rec.address, inf->info.authreq.sta_addr, ETH_ALEN);
rec.status = P80211ENUM_status_unspec_failure;
/*
- ** Authenticate based on the access mode.
- */
+ ** Authenticate based on the access mode.
+ */
switch (hw->accessmode) {
- case WLAN_ACCESS_NONE:
+ case WLAN_ACCESS_NONE:
- /*
- ** Deny all new authentications. However, if a station
- ** is ALREADY authenticated, then accept it.
- */
+ /*
+ ** Deny all new authentications. However, if a station
+ ** is ALREADY authenticated, then accept it.
+ */
- for (i = 0; i < hw->authlist.cnt; i++)
- if (memcmp(rec.address, hw->authlist.addr[i],
- WLAN_ADDR_LEN) == 0) {
- rec.status = P80211ENUM_status_successful;
- break;
- }
+ for (i = 0; i < hw->authlist.cnt; i++)
+ if (memcmp(rec.address, hw->authlist.addr[i],
+ ETH_ALEN) == 0) {
+ rec.status = P80211ENUM_status_successful;
+ break;
+ }
- break;
+ break;
- case WLAN_ACCESS_ALL:
+ case WLAN_ACCESS_ALL:
- /*
- ** Allow all authentications.
- */
+ /*
+ ** Allow all authentications.
+ */
- rec.status = P80211ENUM_status_successful;
- break;
+ rec.status = P80211ENUM_status_successful;
+ break;
- case WLAN_ACCESS_ALLOW:
+ case WLAN_ACCESS_ALLOW:
- /*
- ** Only allow the authentication if the MAC address
- ** is in the list of allowed addresses.
- **
- ** Since this is the interrupt handler, we may be here
- ** while the access list is in the middle of being
- ** updated. Choose the list which is currently okay.
- ** See "prism2mib_priv_accessallow()" for details.
- */
-
- if (hw->allow.modify == 0) {
- cnt = hw->allow.cnt;
- addr = hw->allow.addr[0];
- } else {
- cnt = hw->allow.cnt1;
- addr = hw->allow.addr1[0];
+ /*
+ ** Only allow the authentication if the MAC address
+ ** is in the list of allowed addresses.
+ **
+ ** Since this is the interrupt handler, we may be here
+ ** while the access list is in the middle of being
+ ** updated. Choose the list which is currently okay.
+ ** See "prism2mib_priv_accessallow()" for details.
+ */
+
+ if (hw->allow.modify == 0) {
+ cnt = hw->allow.cnt;
+ addr = hw->allow.addr[0];
+ } else {
+ cnt = hw->allow.cnt1;
+ addr = hw->allow.addr1[0];
+ }
+
+ for (i = 0; i < cnt; i++, addr += ETH_ALEN)
+ if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
+ rec.status = P80211ENUM_status_successful;
+ break;
}
- for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
- if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
- rec.status = P80211ENUM_status_successful;
- break;
- }
+ break;
- break;
+ case WLAN_ACCESS_DENY:
- case WLAN_ACCESS_DENY:
+ /*
+ ** Allow the authentication UNLESS the MAC address is
+ ** in the list of denied addresses.
+ **
+ ** Since this is the interrupt handler, we may be here
+ ** while the access list is in the middle of being
+ ** updated. Choose the list which is currently okay.
+ ** See "prism2mib_priv_accessdeny()" for details.
+ */
- /*
- ** Allow the authentication UNLESS the MAC address is
- ** in the list of denied addresses.
- **
- ** Since this is the interrupt handler, we may be here
- ** while the access list is in the middle of being
- ** updated. Choose the list which is currently okay.
- ** See "prism2mib_priv_accessdeny()" for details.
- */
-
- if (hw->deny.modify == 0) {
- cnt = hw->deny.cnt;
- addr = hw->deny.addr[0];
- } else {
- cnt = hw->deny.cnt1;
- addr = hw->deny.addr1[0];
- }
+ if (hw->deny.modify == 0) {
+ cnt = hw->deny.cnt;
+ addr = hw->deny.addr[0];
+ } else {
+ cnt = hw->deny.cnt1;
+ addr = hw->deny.addr1[0];
+ }
- rec.status = P80211ENUM_status_successful;
+ rec.status = P80211ENUM_status_successful;
- for (i = 0; i < cnt; i++, addr += WLAN_ADDR_LEN)
- if (memcmp(rec.address, addr, WLAN_ADDR_LEN) == 0) {
- rec.status = P80211ENUM_status_unspec_failure;
- break;
- }
+ for (i = 0; i < cnt; i++, addr += ETH_ALEN)
+ if (memcmp(rec.address, addr, ETH_ALEN) == 0) {
+ rec.status = P80211ENUM_status_unspec_failure;
+ break;
+ }
- break;
+ break;
}
/*
- ** If the authentication is okay, then add the MAC address to the list
- ** of authenticated stations. Don't add the address if it is already in
- ** the list. (802.11b does not seem to disallow a station from issuing
- ** an authentication request when the station is already authenticated.
- ** Does this sort of thing ever happen? We might as well do the check
- ** just in case.)
- */
+ ** If the authentication is okay, then add the MAC address to the list
+ ** of authenticated stations. Don't add the address if it is already in
+ ** the list. (802.11b does not seem to disallow a station from issuing
+ ** an authentication request when the station is already authenticated.
+ ** Does this sort of thing ever happen? We might as well do the check
+ ** just in case.)
+ */
added = 0;
if (rec.status == P80211ENUM_status_successful) {
for (i = 0; i < hw->authlist.cnt; i++)
- if (memcmp(rec.address, hw->authlist.addr[i], WLAN_ADDR_LEN) == 0)
+ if (memcmp(rec.address, hw->authlist.addr[i], ETH_ALEN)
+ == 0)
break;
if (i >= hw->authlist.cnt) {
@@ -1775,7 +1717,7 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
rec.status = P80211ENUM_status_ap_full;
} else {
memcpy(hw->authlist.addr[hw->authlist.cnt],
- rec.address, WLAN_ADDR_LEN);
+ rec.address, ETH_ALEN);
hw->authlist.cnt++;
added = 1;
}
@@ -1783,27 +1725,26 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
}
/*
- ** Send back the results of the authentication. If this doesn't work,
- ** then make sure to remove the address from the authenticated list if
- ** it was added.
- */
+ ** Send back the results of the authentication. If this doesn't work,
+ ** then make sure to remove the address from the authenticated list if
+ ** it was added.
+ */
- rec.status = host2hfa384x_16(rec.status);
+ rec.status = cpu_to_le16(rec.status);
rec.algorithm = inf->info.authreq.algorithm;
result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA,
- &rec, sizeof(rec));
+ &rec, sizeof(rec));
if (result) {
- if (added) hw->authlist.cnt--;
- WLAN_LOG_ERROR("setconfig(authenticatestation) failed, result=%d\n", result);
+ if (added)
+ hw->authlist.cnt--;
+ printk(KERN_ERR
+ "setconfig(authenticatestation) failed, result=%d\n",
+ result);
}
-
- DBFEXIT;
-
return;
}
-
/*----------------------------------------------------------------
* prism2sta_inf_psusercnt
*
@@ -1825,74 +1766,14 @@ static void prism2sta_inf_authreq_defer(wlandevice_t *wlandev,
static void prism2sta_inf_psusercnt(wlandevice_t *wlandev,
hfa384x_InfFrame_t *inf)
{
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) wlandev->priv;
- hw->psusercount = hfa384x2host_16(inf->info.psusercnt.usercnt);
-
- DBFEXIT;
+ hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt);
return;
}
/*----------------------------------------------------------------
-* prism2sta_ev_dtim
-*
-* Handles the DTIM early warning event.
-*
-* Arguments:
-* wlandev wlan device structure
-*
-* Returns:
-* nothing
-*
-* Side effects:
-*
-* Call context:
-* interrupt
-----------------------------------------------------------------*/
-void prism2sta_ev_dtim(wlandevice_t *wlandev)
-{
-#if 0
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
-#endif
- DBFENTER;
- WLAN_LOG_DEBUG(3, "DTIM event, currently unhandled.\n");
- DBFEXIT;
- return;
-}
-
-
-/*----------------------------------------------------------------
-* prism2sta_ev_infdrop
-*
-* Handles the InfDrop event.
-*
-* Arguments:
-* wlandev wlan device structure
-*
-* Returns:
-* nothing
-*
-* Side effects:
-*
-* Call context:
-* interrupt
-----------------------------------------------------------------*/
-void prism2sta_ev_infdrop(wlandevice_t *wlandev)
-{
-#if 0
- hfa384x_t *hw = (hfa384x_t *)wlandev->priv;
-#endif
- DBFENTER;
- WLAN_LOG_DEBUG(3, "Info frame dropped due to card mem low.\n");
- DBFEXIT;
- return;
-}
-
-
-/*----------------------------------------------------------------
* prism2sta_ev_info
*
* Handles the Info event.
@@ -1911,56 +1792,53 @@ void prism2sta_ev_infdrop(wlandevice_t *wlandev)
----------------------------------------------------------------*/
void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
{
- DBFENTER;
- inf->infotype = hfa384x2host_16(inf->infotype);
+ inf->infotype = le16_to_cpu(inf->infotype);
/* Dispatch */
- switch ( inf->infotype ) {
- case HFA384x_IT_HANDOVERADDR:
- prism2sta_inf_handover(wlandev, inf);
- break;
- case HFA384x_IT_COMMTALLIES:
- prism2sta_inf_tallies(wlandev, inf);
- break;
- case HFA384x_IT_HOSTSCANRESULTS:
- prism2sta_inf_hostscanresults(wlandev, inf);
- break;
- case HFA384x_IT_SCANRESULTS:
- prism2sta_inf_scanresults(wlandev, inf);
- break;
- case HFA384x_IT_CHINFORESULTS:
- prism2sta_inf_chinforesults(wlandev, inf);
- break;
- case HFA384x_IT_LINKSTATUS:
- prism2sta_inf_linkstatus(wlandev, inf);
- break;
- case HFA384x_IT_ASSOCSTATUS:
- prism2sta_inf_assocstatus(wlandev, inf);
- break;
- case HFA384x_IT_AUTHREQ:
- prism2sta_inf_authreq(wlandev, inf);
- break;
- case HFA384x_IT_PSUSERCNT:
- prism2sta_inf_psusercnt(wlandev, inf);
- break;
- case HFA384x_IT_KEYIDCHANGED:
- WLAN_LOG_WARNING("Unhandled IT_KEYIDCHANGED\n");
- break;
- case HFA384x_IT_ASSOCREQ:
- WLAN_LOG_WARNING("Unhandled IT_ASSOCREQ\n");
- break;
- case HFA384x_IT_MICFAILURE:
- WLAN_LOG_WARNING("Unhandled IT_MICFAILURE\n");
- break;
- default:
- WLAN_LOG_WARNING(
- "Unknown info type=0x%02x\n", inf->infotype);
- break;
+ switch (inf->infotype) {
+ case HFA384x_IT_HANDOVERADDR:
+ prism2sta_inf_handover(wlandev, inf);
+ break;
+ case HFA384x_IT_COMMTALLIES:
+ prism2sta_inf_tallies(wlandev, inf);
+ break;
+ case HFA384x_IT_HOSTSCANRESULTS:
+ prism2sta_inf_hostscanresults(wlandev, inf);
+ break;
+ case HFA384x_IT_SCANRESULTS:
+ prism2sta_inf_scanresults(wlandev, inf);
+ break;
+ case HFA384x_IT_CHINFORESULTS:
+ prism2sta_inf_chinforesults(wlandev, inf);
+ break;
+ case HFA384x_IT_LINKSTATUS:
+ prism2sta_inf_linkstatus(wlandev, inf);
+ break;
+ case HFA384x_IT_ASSOCSTATUS:
+ prism2sta_inf_assocstatus(wlandev, inf);
+ break;
+ case HFA384x_IT_AUTHREQ:
+ prism2sta_inf_authreq(wlandev, inf);
+ break;
+ case HFA384x_IT_PSUSERCNT:
+ prism2sta_inf_psusercnt(wlandev, inf);
+ break;
+ case HFA384x_IT_KEYIDCHANGED:
+ printk(KERN_WARNING "Unhandled IT_KEYIDCHANGED\n");
+ break;
+ case HFA384x_IT_ASSOCREQ:
+ printk(KERN_WARNING "Unhandled IT_ASSOCREQ\n");
+ break;
+ case HFA384x_IT_MICFAILURE:
+ printk(KERN_WARNING "Unhandled IT_MICFAILURE\n");
+ break;
+ default:
+ printk(KERN_WARNING
+ "Unknown info type=0x%02x\n", inf->infotype);
+ break;
}
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_ev_txexc
*
@@ -1982,15 +1860,11 @@ void prism2sta_ev_info(wlandevice_t *wlandev, hfa384x_InfFrame_t *inf)
----------------------------------------------------------------*/
void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
{
- DBFENTER;
-
- WLAN_LOG_DEBUG(3, "TxExc status=0x%x.\n", status);
+ pr_debug("TxExc status=0x%x.\n", status);
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_ev_tx
*
@@ -2009,15 +1883,12 @@ void prism2sta_ev_txexc(wlandevice_t *wlandev, u16 status)
----------------------------------------------------------------*/
void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
{
- DBFENTER;
- WLAN_LOG_DEBUG(4, "Tx Complete, status=0x%04x\n", status);
+ pr_debug("Tx Complete, status=0x%04x\n", status);
/* update linux network stats */
wlandev->linux_stats.tx_packets++;
- DBFEXIT;
return;
}
-
/*----------------------------------------------------------------
* prism2sta_ev_rx
*
@@ -2036,11 +1907,7 @@ void prism2sta_ev_tx(wlandevice_t *wlandev, u16 status)
----------------------------------------------------------------*/
void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
{
- DBFENTER;
-
p80211netdev_rx(wlandev, skb);
-
- DBFEXIT;
return;
}
@@ -2062,11 +1929,7 @@ void prism2sta_ev_rx(wlandevice_t *wlandev, struct sk_buff *skb)
----------------------------------------------------------------*/
void prism2sta_ev_alloc(wlandevice_t *wlandev)
{
- DBFENTER;
-
netif_wake_queue(wlandev->netdev);
-
- DBFEXIT;
return;
}
@@ -2091,17 +1954,17 @@ void prism2sta_ev_alloc(wlandevice_t *wlandev)
----------------------------------------------------------------*/
static wlandevice_t *create_wlan(void)
{
- wlandevice_t *wlandev = NULL;
- hfa384x_t *hw = NULL;
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
- /* Alloc our structures */
- wlandev = kmalloc(sizeof(wlandevice_t), GFP_KERNEL);
- hw = kmalloc(sizeof(hfa384x_t), GFP_KERNEL);
+ /* Alloc our structures */
+ wlandev = kmalloc(sizeof(wlandevice_t), GFP_KERNEL);
+ hw = kmalloc(sizeof(hfa384x_t), GFP_KERNEL);
if (!wlandev || !hw) {
- WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
- if (wlandev) kfree(wlandev);
- if (hw) kfree(hw);
+ printk(KERN_ERR "%s: Memory allocation failure.\n", dev_info);
+ kfree(wlandev);
+ kfree(hw);
return NULL;
}
@@ -2121,24 +1984,21 @@ static wlandevice_t *create_wlan(void)
wlandev->set_multicast_list = prism2sta_setmulticast;
wlandev->tx_timeout = hfa384x_tx_timeout;
- wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT |
- P80211_NSDCAP_AUTOJOIN;
+ wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN;
/* Initialize the device private data stucture. */
- hw->dot11_desired_bss_type = 1;
+ hw->dot11_desired_bss_type = 1;
return wlandev;
}
void prism2sta_commsqual_defer(struct work_struct *data)
{
- hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
- wlandevice_t *wlandev = hw->wlandev;
+ hfa384x_t *hw = container_of(data, struct hfa384x, commsqual_bh);
+ wlandevice_t *wlandev = hw->wlandev;
hfa384x_bytestr32_t ssid;
int result = 0;
- DBFENTER;
-
if (hw->wlandev->hwremoved)
goto done;
@@ -2155,58 +2015,49 @@ void prism2sta_commsqual_defer(struct work_struct *data)
HFA384x_RID_DBMCOMMSQUALITY_LEN);
if (result) {
- WLAN_LOG_ERROR("error fetching commsqual\n");
+ printk(KERN_ERR "error fetching commsqual\n");
goto done;
}
- // qual.CQ_currBSS; // link
- // ASL_currBSS; // level
- // qual.ANL_currFC; // noise
-
- WLAN_LOG_DEBUG(3, "commsqual %d %d %d\n",
- hfa384x2host_16(hw->qual.CQ_currBSS),
- hfa384x2host_16(hw->qual.ASL_currBSS),
- hfa384x2host_16(hw->qual.ANL_currFC));
+ pr_debug("commsqual %d %d %d\n",
+ le16_to_cpu(hw->qual.CQ_currBSS),
+ le16_to_cpu(hw->qual.ASL_currBSS),
+ le16_to_cpu(hw->qual.ANL_currFC));
}
/* Lastly, we need to make sure the BSSID didn't change on us */
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTBSSID,
wlandev->bssid, WLAN_BSSID_LEN);
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "getconfig(0x%02x) failed, result = %d\n",
- HFA384x_RID_CURRENTBSSID, result);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTBSSID, result);
goto done;
}
result = hfa384x_drvr_getconfig(hw,
HFA384x_RID_CURRENTSSID,
&ssid, sizeof(ssid));
- if ( result ) {
- WLAN_LOG_DEBUG(1,
- "getconfig(0x%02x) failed, result = %d\n",
- HFA384x_RID_CURRENTSSID, result);
+ if (result) {
+ printk(KERN_DEBUG
+ "getconfig(0x%02x) failed, result = %d\n",
+ HFA384x_RID_CURRENTSSID, result);
goto done;
}
prism2mgmt_bytestr2pstr((hfa384x_bytestr_t *)&ssid,
- (p80211pstrd_t *) &wlandev->ssid);
-
+ (p80211pstrd_t *)&wlandev->ssid);
/* Reschedule timer */
mod_timer(&hw->commsqual_timer, jiffies + HZ);
- done:
- DBFEXIT;
+done:
+ ;
}
void prism2sta_commsqual_timer(unsigned long data)
{
- hfa384x_t *hw = (hfa384x_t *) data;
-
- DBFENTER;
+ hfa384x_t *hw = (hfa384x_t *) data;
schedule_work(&hw->commsqual_bh);
-
- DBFEXIT;
}
diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c
index 8f7b1f281f0..d8a12982135 100644
--- a/drivers/staging/wlan-ng/prism2usb.c
+++ b/drivers/staging/wlan-ng/prism2usb.c
@@ -11,44 +11,70 @@ static struct usb_device_id usb_prism_tbl[] = {
{PRISM_USB_DEVICE(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS")},
{PRISM_USB_DEVICE(0x07aa, 0x0012, "Corega Wireless LAN USB Stick-11")},
{PRISM_USB_DEVICE(0x09aa, 0x3642, "Prism2.x 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x049f, 0x0033, "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
- {PRISM_USB_DEVICE(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
- {PRISM_USB_DEVICE(0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
- {PRISM_USB_DEVICE(0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
- {PRISM_USB_DEVICE(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
- {PRISM_USB_DEVICE(0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x1668, 0x0408, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x1668, 0x0421, "Actiontec Prism2.5 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x067c, 0x1022, "Siemens SpeedStream 1022 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x049f, 0x0033,
+ "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter")},
+ {PRISM_USB_DEVICE
+ (0x08de, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x8086, 0x1111, "Intel PRO/Wireless 2011B LAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x045e, 0x006e, "Microsoft MN510 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x0967, 0x0204, "Acer Warplink USB Adapter")},
- {PRISM_USB_DEVICE(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
- {PRISM_USB_DEVICE(0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
- {PRISM_USB_DEVICE(0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
- {PRISM_USB_DEVICE(0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
- {PRISM_USB_DEVICE(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
- {PRISM_USB_DEVICE(0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
- {PRISM_USB_DEVICE(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
- {PRISM_USB_DEVICE(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated")},
+ {PRISM_USB_DEVICE
+ (0x0cde, 0x0005, "Z-Com Xl735 Wireless 802.11b USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x413c, 0x8100, "Dell TrueMobile 1180 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0b3b, 0x1601, "ALLNET 0193 11Mbps WLAN USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0b3b, 0x1602, "ZyXEL ZyAIR B200 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0baf, 0x00eb, "USRobotics USR1120 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter")},
+ {PRISM_USB_DEVICE
+ (0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter")},
{PRISM_USB_DEVICE(0x0846, 0x4110, "NetGear MA111")},
- {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
-// {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")},
+ {PRISM_USB_DEVICE(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter")},
+/* {PRISM_USB_DEVICE(0x0ace, 0x1201, "ZyDAS ZD1201 Wireless USB Adapter")}, */
{PRISM_USB_DEVICE(0x2821, 0x3300, "ASUS-WL140 Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x2001, 0x3700, "DWL-122 Wireless USB Adapter")},
- {PRISM_USB_DEVICE(0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x2001, 0x3702, "DWL-120 Rev F Wireless USB Adapter")},
{PRISM_USB_DEVICE(0x50c2, 0x4013, "Averatec USB WLAN Adapter")},
{PRISM_USB_DEVICE(0x2c02, 0x14ea, "Planex GW-US11H WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x124a, 0x168b, "Airvast PRISM3 WLAN USB Adapter")},
{PRISM_USB_DEVICE(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter")},
{PRISM_USB_DEVICE(0x2821, 0x3300, "Hawking HighDB USB Adapter")},
- {PRISM_USB_DEVICE(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter")},
{PRISM_USB_DEVICE(0x1668, 0x6106, "ROPEX FreeLan 802.11b USB Adapter")},
- {PRISM_USB_DEVICE(0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x124a, 0x4017, "Pheenet WL-503IA 802.11b USB Adapter")},
{PRISM_USB_DEVICE(0x0bb2, 0x0302, "Ambit Microsystems Corp.")},
- {PRISM_USB_DEVICE(0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
- {PRISM_USB_DEVICE(0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
+ {PRISM_USB_DEVICE
+ (0x9016, 0x182d, "Sitecom WL-022 802.11b USB Adapter")},
+ {PRISM_USB_DEVICE
+ (0x0543, 0x0f01, "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)")},
{ /* terminator */ }
};
@@ -75,29 +101,26 @@ MODULE_DEVICE_TABLE(usb, usb_prism_tbl);
* I'm not sure, assume it's interrupt.
*
----------------------------------------------------------------*/
-static int prism2sta_probe_usb(
- struct usb_interface *interface,
- const struct usb_device_id *id)
+static int prism2sta_probe_usb(struct usb_interface *interface,
+ const struct usb_device_id *id)
{
struct usb_device *dev;
- wlandevice_t *wlandev = NULL;
- hfa384x_t *hw = NULL;
- int result = 0;
-
- DBFENTER;
+ wlandevice_t *wlandev = NULL;
+ hfa384x_t *hw = NULL;
+ int result = 0;
dev = interface_to_usbdev(interface);
if ((wlandev = create_wlan()) == NULL) {
- WLAN_LOG_ERROR("%s: Memory allocation failure.\n", dev_info);
+ printk(KERN_ERR "%s: Memory allocation failure.\n", dev_info);
result = -EIO;
goto failed;
}
hw = wlandev->priv;
- if ( wlan_setup(wlandev) != 0 ) {
- WLAN_LOG_ERROR("%s: wlan_setup() failed.\n", dev_info);
+ if (wlan_setup(wlandev) != 0) {
+ printk(KERN_ERR "%s: wlan_setup() failed.\n", dev_info);
result = -EIO;
goto failed;
}
@@ -114,15 +137,14 @@ static int prism2sta_probe_usb(
/* Do a chip-level reset on the MAC */
if (prism2_doreset) {
result = hfa384x_corereset(hw,
- prism2_reset_holdtime,
- prism2_reset_settletime, 0);
+ prism2_reset_holdtime,
+ prism2_reset_settletime, 0);
if (result != 0) {
unregister_wlandev(wlandev);
hfa384x_destroy(hw);
result = -EIO;
- WLAN_LOG_ERROR(
- "%s: hfa384x_corereset() failed.\n",
- dev_info);
+ printk(KERN_ERR
+ "%s: hfa384x_corereset() failed.\n", dev_info);
goto failed;
}
}
@@ -131,30 +153,28 @@ static int prism2sta_probe_usb(
wlandev->msdstate = WLAN_MSD_HWPRESENT;
- if ( register_wlandev(wlandev) != 0 ) {
- WLAN_LOG_ERROR("%s: register_wlandev() failed.\n", dev_info);
+ if (register_wlandev(wlandev) != 0) {
+ printk(KERN_ERR "%s: register_wlandev() failed.\n", dev_info);
result = -EIO;
goto failed;
- }
+ }
/* enable the card */
prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable);
goto done;
- failed:
- if (wlandev) kfree(wlandev);
- if (hw) kfree(hw);
+failed:
+ kfree(wlandev);
+ kfree(hw);
wlandev = NULL;
- done:
- DBFEXIT;
-
+done:
+ p80211_allow_ioctls(wlandev);
usb_set_intfdata(interface, wlandev);
return result;
}
-
/*----------------------------------------------------------------
* prism2sta_disconnect_usb
*
@@ -174,22 +194,19 @@ static int prism2sta_probe_usb(
* Call context:
* process
----------------------------------------------------------------*/
-static void
-prism2sta_disconnect_usb(struct usb_interface *interface)
+static void prism2sta_disconnect_usb(struct usb_interface *interface)
{
- wlandevice_t *wlandev;
-
- DBFENTER;
+ wlandevice_t *wlandev;
wlandev = (wlandevice_t *) usb_get_intfdata(interface);
- if ( wlandev != NULL ) {
+ if (wlandev != NULL) {
LIST_HEAD(cleanlist);
- struct list_head *entry;
- struct list_head *temp;
- unsigned long flags;
+ struct list_head *entry;
+ struct list_head *temp;
+ unsigned long flags;
- hfa384x_t *hw = wlandev->priv;
+ hfa384x_t *hw = wlandev->priv;
if (!hw)
goto exit;
@@ -231,7 +248,7 @@ prism2sta_disconnect_usb(struct usb_interface *interface)
* responses that we have shut down.
*/
list_for_each(entry, &cleanlist) {
- hfa384x_usbctlx_t *ctlx;
+ hfa384x_usbctlx_t *ctlx;
ctlx = list_entry(entry, hfa384x_usbctlx_t, list);
complete(&ctlx->done);
@@ -264,13 +281,10 @@ prism2sta_disconnect_usb(struct usb_interface *interface)
kfree(wlandev);
}
- exit:
-
+exit:
usb_set_intfdata(interface, NULL);
- DBFEXIT;
}
-
static struct usb_driver prism2_usb_driver = {
.name = "prism2_usb",
.probe = prism2sta_probe_usb,
@@ -281,21 +295,13 @@ static struct usb_driver prism2_usb_driver = {
static int __init prism2usb_init(void)
{
- DBFENTER;
-
/* This call will result in calls to prism2sta_probe_usb. */
return usb_register(&prism2_usb_driver);
-
- DBFEXIT;
};
static void __exit prism2usb_cleanup(void)
{
- DBFENTER;
-
usb_deregister(&prism2_usb_driver);
-
- DBFEXIT;
};
module_init(prism2usb_init);
diff --git a/drivers/staging/wlan-ng/wlan_compat.h b/drivers/staging/wlan-ng/wlan_compat.h
deleted file mode 100644
index 8b8a510685c..00000000000
--- a/drivers/staging/wlan-ng/wlan_compat.h
+++ /dev/null
@@ -1,193 +0,0 @@
-/* wlan_compat.h
-*
-* Types and macros to aid in portability
-*
-* Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
-* --------------------------------------------------------------------
-*
-* linux-wlan
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 (the "License"); you may not use this file
-* except in compliance with the License. You may obtain a copy of
-* the License at http://www.mozilla.org/MPL/
-*
-* Software distributed under the License is distributed on an "AS
-* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-* implied. See the License for the specific language governing
-* rights and limitations under the License.
-*
-* Alternatively, the contents of this file may be used under the
-* terms of the GNU Public License version 2 (the "GPL"), in which
-* case the provisions of the GPL are applicable instead of the
-* above. If you wish to allow the use of your version of this file
-* only under the terms of the GPL and not to allow others to use
-* your version of this file under the MPL, indicate your decision
-* by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL. If you do not delete
-* the provisions above, a recipient may use your version of this
-* file under either the MPL or the GPL.
-*
-* --------------------------------------------------------------------
-*
-* Inquiries regarding the linux-wlan Open Source project can be
-* made directly to:
-*
-* AbsoluteValue Systems Inc.
-* info@linux-wlan.com
-* http://www.linux-wlan.com
-*
-* --------------------------------------------------------------------
-*
-* Portions of the development of this software were funded by
-* Intersil Corporation as part of PRISM(R) chipset product development.
-*
-* --------------------------------------------------------------------
-*/
-
-#ifndef _WLAN_COMPAT_H
-#define _WLAN_COMPAT_H
-
-/*=============================================================*/
-/*------ Bit settings -----------------------------------------*/
-/*=============================================================*/
-
-#define BIT0 0x00000001
-#define BIT1 0x00000002
-#define BIT2 0x00000004
-#define BIT3 0x00000008
-#define BIT4 0x00000010
-#define BIT5 0x00000020
-#define BIT6 0x00000040
-#define BIT7 0x00000080
-#define BIT8 0x00000100
-#define BIT9 0x00000200
-#define BIT10 0x00000400
-#define BIT11 0x00000800
-#define BIT12 0x00001000
-#define BIT13 0x00002000
-#define BIT14 0x00004000
-#define BIT15 0x00008000
-#define BIT16 0x00010000
-#define BIT17 0x00020000
-#define BIT18 0x00040000
-#define BIT19 0x00080000
-#define BIT20 0x00100000
-#define BIT21 0x00200000
-#define BIT22 0x00400000
-#define BIT23 0x00800000
-#define BIT24 0x01000000
-#define BIT25 0x02000000
-#define BIT26 0x04000000
-#define BIT27 0x08000000
-#define BIT28 0x10000000
-#define BIT29 0x20000000
-#define BIT30 0x40000000
-#define BIT31 0x80000000
-
-/*=============================================================*/
-/*------ Compiler Portability Macros --------------------------*/
-/*=============================================================*/
-#define __WLAN_ATTRIB_PACK__ __attribute__ ((packed))
-
-/*=============================================================*/
-/*------ OS Portability Macros --------------------------------*/
-/*=============================================================*/
-
-#ifndef WLAN_DBVAR
-#define WLAN_DBVAR wlan_debug
-#endif
-
-#define WLAN_RELEASE "0.3.0-lkml"
-
-#include <linux/hardirq.h>
-
-#define WLAN_LOG_ERROR(x,args...) printk(KERN_ERR "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_WARNING(x,args...) printk(KERN_WARNING "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_NOTICE(x,args...) printk(KERN_NOTICE "%s: " x , __func__ , ##args);
-
-#define WLAN_LOG_INFO(args... ) printk(KERN_INFO args)
-
-#if defined(WLAN_INCLUDE_DEBUG)
- #define WLAN_HEX_DUMP( l, x, p, n) if( WLAN_DBVAR >= (l) ){ \
- int __i__; \
- printk(KERN_DEBUG x ":"); \
- for( __i__=0; __i__ < (n); __i__++) \
- printk( " %02x", ((u8*)(p))[__i__]); \
- printk("\n"); }
- #define DBFENTER { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"---->\n"); } }
- #define DBFEXIT { if ( WLAN_DBVAR >= 5 ){ WLAN_LOG_DEBUG(3,"<----\n"); } }
-
- #define WLAN_LOG_DEBUG(l,x,args...) if ( WLAN_DBVAR >= (l)) printk(KERN_DEBUG "%s(%lu): " x , __func__, (preempt_count() & PREEMPT_MASK), ##args );
-#else
- #define WLAN_HEX_DUMP( l, s, p, n)
- #define DBFENTER
- #define DBFEXIT
-
- #define WLAN_LOG_DEBUG(l, s, args...)
-#endif
-
-#undef netdevice_t
-typedef struct net_device netdevice_t;
-
-#define URB_ASYNC_UNLINK 0
-#define USB_QUEUE_BULK 0
-
-/*=============================================================*/
-/*------ Hardware Portability Macros --------------------------*/
-/*=============================================================*/
-
-#define ieee2host16(n) __le16_to_cpu(n)
-#define ieee2host32(n) __le32_to_cpu(n)
-#define host2ieee16(n) __cpu_to_le16(n)
-#define host2ieee32(n) __cpu_to_le32(n)
-
-/*=============================================================*/
-/*--- General Macros ------------------------------------------*/
-/*=============================================================*/
-
-#define wlan_max(a, b) (((a) > (b)) ? (a) : (b))
-#define wlan_min(a, b) (((a) < (b)) ? (a) : (b))
-
-#define wlan_isprint(c) (((c) > (0x19)) && ((c) < (0x7f)))
-
-#define wlan_hexchar(x) (((x) < 0x0a) ? ('0' + (x)) : ('a' + ((x) - 0x0a)))
-
-/* Create a string of printable chars from something that might not be */
-/* It's recommended that the str be 4*len + 1 bytes long */
-#define wlan_mkprintstr(buf, buflen, str, strlen) \
-{ \
- int i = 0; \
- int j = 0; \
- memset(str, 0, (strlen)); \
- for (i = 0; i < (buflen); i++) { \
- if ( wlan_isprint((buf)[i]) ) { \
- (str)[j] = (buf)[i]; \
- j++; \
- } else { \
- (str)[j] = '\\'; \
- (str)[j+1] = 'x'; \
- (str)[j+2] = wlan_hexchar(((buf)[i] & 0xf0) >> 4); \
- (str)[j+3] = wlan_hexchar(((buf)[i] & 0x0f)); \
- j += 4; \
- } \
- } \
-}
-
-/*=============================================================*/
-/*--- Variables -----------------------------------------------*/
-/*=============================================================*/
-
-#ifdef WLAN_INCLUDE_DEBUG
-extern int wlan_debug;
-#endif
-
-extern int wlan_ethconv; /* What's the default ethconv? */
-
-/*=============================================================*/
-/*--- Functions -----------------------------------------------*/
-/*=============================================================*/
-#endif /* _WLAN_COMPAT_H */
-
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 8171ca17b93..d0b093b66ad 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -30,6 +30,7 @@
#include <linux/idr.h>
#include <linux/thermal.h>
#include <linux/spinlock.h>
+#include <linux/reboot.h>
MODULE_AUTHOR("Zhang Rui");
MODULE_DESCRIPTION("Generic thermal management sysfs support");
@@ -104,22 +105,36 @@ static ssize_t
temp_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
+ long temperature;
+ int ret;
if (!tz->ops->get_temp)
return -EPERM;
- return tz->ops->get_temp(tz, buf);
+ ret = tz->ops->get_temp(tz, &temperature);
+
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%ld\n", temperature);
}
static ssize_t
mode_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
+ enum thermal_device_mode mode;
+ int result;
if (!tz->ops->get_mode)
return -EPERM;
- return tz->ops->get_mode(tz, buf);
+ result = tz->ops->get_mode(tz, &mode);
+ if (result)
+ return result;
+
+ return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
+ : "disabled");
}
static ssize_t
@@ -132,7 +147,13 @@ mode_store(struct device *dev, struct device_attribute *attr,
if (!tz->ops->set_mode)
return -EPERM;
- result = tz->ops->set_mode(tz, buf);
+ if (!strncmp(buf, "enabled", sizeof("enabled")))
+ result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
+ else if (!strncmp(buf, "disabled", sizeof("disabled")))
+ result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
+ else
+ result = -EINVAL;
+
if (result)
return result;
@@ -144,7 +165,8 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
- int trip;
+ enum thermal_trip_type type;
+ int trip, result;
if (!tz->ops->get_trip_type)
return -EPERM;
@@ -152,7 +174,22 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
return -EINVAL;
- return tz->ops->get_trip_type(tz, trip, buf);
+ result = tz->ops->get_trip_type(tz, trip, &type);
+ if (result)
+ return result;
+
+ switch (type) {
+ case THERMAL_TRIP_CRITICAL:
+ return sprintf(buf, "critical");
+ case THERMAL_TRIP_HOT:
+ return sprintf(buf, "hot");
+ case THERMAL_TRIP_PASSIVE:
+ return sprintf(buf, "passive");
+ case THERMAL_TRIP_ACTIVE:
+ return sprintf(buf, "active");
+ default:
+ return sprintf(buf, "unknown");
+ }
}
static ssize_t
@@ -160,7 +197,8 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct thermal_zone_device *tz = to_thermal_zone(dev);
- int trip;
+ int trip, ret;
+ long temperature;
if (!tz->ops->get_trip_temp)
return -EPERM;
@@ -168,12 +206,77 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
return -EINVAL;
- return tz->ops->get_trip_temp(tz, trip, buf);
+ ret = tz->ops->get_trip_temp(tz, trip, &temperature);
+
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%ld\n", temperature);
+}
+
+static ssize_t
+passive_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
+ struct thermal_cooling_device *cdev = NULL;
+ int state;
+
+ if (!sscanf(buf, "%d\n", &state))
+ return -EINVAL;
+
+ if (state && !tz->forced_passive) {
+ mutex_lock(&thermal_list_lock);
+ list_for_each_entry(cdev, &thermal_cdev_list, node) {
+ if (!strncmp("Processor", cdev->type,
+ sizeof("Processor")))
+ thermal_zone_bind_cooling_device(tz,
+ THERMAL_TRIPS_NONE,
+ cdev);
+ }
+ mutex_unlock(&thermal_list_lock);
+ } else if (!state && tz->forced_passive) {
+ mutex_lock(&thermal_list_lock);
+ list_for_each_entry(cdev, &thermal_cdev_list, node) {
+ if (!strncmp("Processor", cdev->type,
+ sizeof("Processor")))
+ thermal_zone_unbind_cooling_device(tz,
+ THERMAL_TRIPS_NONE,
+ cdev);
+ }
+ mutex_unlock(&thermal_list_lock);
+ }
+
+ tz->tc1 = 1;
+ tz->tc2 = 1;
+
+ if (!tz->passive_delay)
+ tz->passive_delay = 1000;
+
+ if (!tz->polling_delay)
+ tz->polling_delay = 10000;
+
+ tz->forced_passive = state;
+
+ thermal_zone_device_update(tz);
+
+ return count;
+}
+
+static ssize_t
+passive_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct thermal_zone_device *tz = to_thermal_zone(dev);
+
+ return sprintf(buf, "%d\n", tz->forced_passive);
}
static DEVICE_ATTR(type, 0444, type_show, NULL);
static DEVICE_ATTR(temp, 0444, temp_show, NULL);
static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
+static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \
+ passive_store);
static struct device_attribute trip_point_attrs[] = {
__ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
@@ -236,8 +339,13 @@ thermal_cooling_device_max_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct thermal_cooling_device *cdev = to_cooling_device(dev);
+ unsigned long state;
+ int ret;
- return cdev->ops->get_max_state(cdev, buf);
+ ret = cdev->ops->get_max_state(cdev, &state);
+ if (ret)
+ return ret;
+ return sprintf(buf, "%ld\n", state);
}
static ssize_t
@@ -245,8 +353,13 @@ thermal_cooling_device_cur_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct thermal_cooling_device *cdev = to_cooling_device(dev);
+ unsigned long state;
+ int ret;
- return cdev->ops->get_cur_state(cdev, buf);
+ ret = cdev->ops->get_cur_state(cdev, &state);
+ if (ret)
+ return ret;
+ return sprintf(buf, "%ld\n", state);
}
static ssize_t
@@ -255,10 +368,10 @@ thermal_cooling_device_cur_state_store(struct device *dev,
const char *buf, size_t count)
{
struct thermal_cooling_device *cdev = to_cooling_device(dev);
- int state;
+ unsigned long state;
int result;
- if (!sscanf(buf, "%d\n", &state))
+ if (!sscanf(buf, "%ld\n", &state))
return -EINVAL;
if (state < 0)
@@ -312,13 +425,20 @@ static DEVICE_ATTR(name, 0444, name_show, NULL);
static ssize_t
temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
{
+ long temperature;
+ int ret;
struct thermal_hwmon_attr *hwmon_attr
= container_of(attr, struct thermal_hwmon_attr, attr);
struct thermal_zone_device *tz
= container_of(hwmon_attr, struct thermal_zone_device,
temp_input);
- return tz->ops->get_temp(tz, buf);
+ ret = tz->ops->get_temp(tz, &temperature);
+
+ if (ret)
+ return ret;
+
+ return sprintf(buf, "%ld\n", temperature);
}
static ssize_t
@@ -330,8 +450,14 @@ temp_crit_show(struct device *dev, struct device_attribute *attr,
struct thermal_zone_device *tz
= container_of(hwmon_attr, struct thermal_zone_device,
temp_crit);
+ long temperature;
+ int ret;
+
+ ret = tz->ops->get_trip_temp(tz, 0, &temperature);
+ if (ret)
+ return ret;
- return tz->ops->get_trip_temp(tz, 0, buf);
+ return sprintf(buf, "%ld\n", temperature);
}
@@ -452,6 +578,97 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
}
#endif
+static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
+ int delay)
+{
+ cancel_delayed_work(&(tz->poll_queue));
+
+ if (!delay)
+ return;
+
+ if (delay > 1000)
+ schedule_delayed_work(&(tz->poll_queue),
+ round_jiffies(msecs_to_jiffies(delay)));
+ else
+ schedule_delayed_work(&(tz->poll_queue),
+ msecs_to_jiffies(delay));
+}
+
+static void thermal_zone_device_passive(struct thermal_zone_device *tz,
+ int temp, int trip_temp, int trip)
+{
+ int trend = 0;
+ struct thermal_cooling_device_instance *instance;
+ struct thermal_cooling_device *cdev;
+ long state, max_state;
+
+ /*
+ * Above Trip?
+ * -----------
+ * Calculate the thermal trend (using the passive cooling equation)
+ * and modify the performance limit for all passive cooling devices
+ * accordingly. Note that we assume symmetry.
+ */
+ if (temp >= trip_temp) {
+ tz->passive = true;
+
+ trend = (tz->tc1 * (temp - tz->last_temperature)) +
+ (tz->tc2 * (temp - trip_temp));
+
+ /* Heating up? */
+ if (trend > 0) {
+ list_for_each_entry(instance, &tz->cooling_devices,
+ node) {
+ if (instance->trip != trip)
+ continue;
+ cdev = instance->cdev;
+ cdev->ops->get_cur_state(cdev, &state);
+ cdev->ops->get_max_state(cdev, &max_state);
+ if (state++ < max_state)
+ cdev->ops->set_cur_state(cdev, state);
+ }
+ } else if (trend < 0) { /* Cooling off? */
+ list_for_each_entry(instance, &tz->cooling_devices,
+ node) {
+ if (instance->trip != trip)
+ continue;
+ cdev = instance->cdev;
+ cdev->ops->get_cur_state(cdev, &state);
+ cdev->ops->get_max_state(cdev, &max_state);
+ if (state > 0)
+ cdev->ops->set_cur_state(cdev, --state);
+ }
+ }
+ return;
+ }
+
+ /*
+ * Below Trip?
+ * -----------
+ * Implement passive cooling hysteresis to slowly increase performance
+ * and avoid thrashing around the passive trip point. Note that we
+ * assume symmetry.
+ */
+ list_for_each_entry(instance, &tz->cooling_devices, node) {
+ if (instance->trip != trip)
+ continue;
+ cdev = instance->cdev;
+ cdev->ops->get_cur_state(cdev, &state);
+ cdev->ops->get_max_state(cdev, &max_state);
+ if (state > 0)
+ cdev->ops->set_cur_state(cdev, --state);
+ if (state == 0)
+ tz->passive = false;
+ }
+}
+
+static void thermal_zone_device_check(struct work_struct *work)
+{
+ struct thermal_zone_device *tz = container_of(work, struct
+ thermal_zone_device,
+ poll_queue.work);
+ thermal_zone_device_update(tz);
+}
/**
* thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
@@ -722,25 +939,113 @@ void thermal_cooling_device_unregister(struct
EXPORT_SYMBOL(thermal_cooling_device_unregister);
/**
+ * thermal_zone_device_update - force an update of a thermal zone's state
+ * @ttz: the thermal zone to update
+ */
+
+void thermal_zone_device_update(struct thermal_zone_device *tz)
+{
+ int count, ret = 0;
+ long temp, trip_temp;
+ enum thermal_trip_type trip_type;
+ struct thermal_cooling_device_instance *instance;
+ struct thermal_cooling_device *cdev;
+
+ mutex_lock(&tz->lock);
+
+ tz->ops->get_temp(tz, &temp);
+
+ for (count = 0; count < tz->trips; count++) {
+ tz->ops->get_trip_type(tz, count, &trip_type);
+ tz->ops->get_trip_temp(tz, count, &trip_temp);
+
+ switch (trip_type) {
+ case THERMAL_TRIP_CRITICAL:
+ if (temp > trip_temp) {
+ if (tz->ops->notify)
+ ret = tz->ops->notify(tz, count,
+ trip_type);
+ if (!ret) {
+ printk(KERN_EMERG
+ "Critical temperature reached (%ld C), shutting down.\n",
+ temp/1000);
+ orderly_poweroff(true);
+ }
+ }
+ break;
+ case THERMAL_TRIP_HOT:
+ if (temp > trip_temp)
+ if (tz->ops->notify)
+ tz->ops->notify(tz, count, trip_type);
+ break;
+ case THERMAL_TRIP_ACTIVE:
+ list_for_each_entry(instance, &tz->cooling_devices,
+ node) {
+ if (instance->trip != count)
+ continue;
+
+ cdev = instance->cdev;
+
+ if (temp > trip_temp)
+ cdev->ops->set_cur_state(cdev, 1);
+ else
+ cdev->ops->set_cur_state(cdev, 0);
+ }
+ break;
+ case THERMAL_TRIP_PASSIVE:
+ if (temp > trip_temp || tz->passive)
+ thermal_zone_device_passive(tz, temp,
+ trip_temp, count);
+ break;
+ }
+ }
+
+ if (tz->forced_passive)
+ thermal_zone_device_passive(tz, temp, tz->forced_passive,
+ THERMAL_TRIPS_NONE);
+
+ tz->last_temperature = temp;
+ if (tz->passive)
+ thermal_zone_device_set_polling(tz, tz->passive_delay);
+ else if (tz->polling_delay)
+ thermal_zone_device_set_polling(tz, tz->polling_delay);
+ mutex_unlock(&tz->lock);
+}
+EXPORT_SYMBOL(thermal_zone_device_update);
+
+/**
* thermal_zone_device_register - register a new thermal zone device
* @type: the thermal zone device type
* @trips: the number of trip points the thermal zone support
* @devdata: private device data
* @ops: standard thermal zone device callbacks
+ * @tc1: thermal coefficient 1 for passive calculations
+ * @tc2: thermal coefficient 2 for passive calculations
+ * @passive_delay: number of milliseconds to wait between polls when
+ * performing passive cooling
+ * @polling_delay: number of milliseconds to wait between polls when checking
+ * whether trip points have been crossed (0 for interrupt
+ * driven systems)
*
* thermal_zone_device_unregister() must be called when the device is no
- * longer needed.
+ * longer needed. The passive cooling formula uses tc1 and tc2 as described in
+ * section 11.1.5.1 of the ACPI specification 3.0.
*/
struct thermal_zone_device *thermal_zone_device_register(char *type,
int trips,
void *devdata, struct
thermal_zone_device_ops
- *ops)
+ *ops, int tc1, int
+ tc2,
+ int passive_delay,
+ int polling_delay)
{
struct thermal_zone_device *tz;
struct thermal_cooling_device *pos;
+ enum thermal_trip_type trip_type;
int result;
int count;
+ int passive = 0;
if (strlen(type) >= THERMAL_NAME_LENGTH)
return ERR_PTR(-EINVAL);
@@ -769,6 +1074,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
tz->device.class = &thermal_class;
tz->devdata = devdata;
tz->trips = trips;
+ tz->tc1 = tc1;
+ tz->tc2 = tc2;
+ tz->passive_delay = passive_delay;
+ tz->polling_delay = polling_delay;
+
dev_set_name(&tz->device, "thermal_zone%d", tz->id);
result = device_register(&tz->device);
if (result) {
@@ -798,8 +1108,18 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
TRIP_POINT_ATTR_ADD(&tz->device, count, result);
if (result)
goto unregister;
+ tz->ops->get_trip_type(tz, count, &trip_type);
+ if (trip_type == THERMAL_TRIP_PASSIVE)
+ passive = 1;
}
+ if (!passive)
+ result = device_create_file(&tz->device,
+ &dev_attr_passive);
+
+ if (result)
+ goto unregister;
+
result = thermal_add_hwmon_sysfs(tz);
if (result)
goto unregister;
@@ -814,6 +1134,10 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
}
mutex_unlock(&thermal_list_lock);
+ INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
+
+ thermal_zone_device_update(tz);
+
if (!result)
return tz;
@@ -853,6 +1177,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
tz->ops->unbind(tz, cdev);
mutex_unlock(&thermal_list_lock);
+ thermal_zone_device_set_polling(tz, 0);
+
if (tz->type[0])
device_remove_file(&tz->device, &dev_attr_type);
device_remove_file(&tz->device, &dev_attr_temp);
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index b6483dd98ac..9cf9ff69e3e 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -626,7 +626,7 @@ static void uea_upload_pre_firmware(const struct firmware *fw_entry, void *conte
goto err_fw_corrupted;
/*
- * Start to upload formware : send reset
+ * Start to upload firmware : send reset
*/
value = 1;
ret = uea_send_modem_cmd(usb, F8051_USBCS, sizeof(value), &value);
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index b3d5a23ab56..869d47cb6db 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1358,6 +1358,9 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x079b, 0x000f), /* BT On-Air USB MODEM */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
+ { USB_DEVICE(0x0ace, 0x1602), /* ZyDAS 56K USB MODEM */
+ .driver_info = SINGLE_RX_URB,
+ },
{ USB_DEVICE(0x0ace, 0x1608), /* ZyDAS 56K USB MODEM */
.driver_info = SINGLE_RX_URB, /* firmware bug */
},
@@ -1493,4 +1496,4 @@ module_exit(acm_exit);
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
MODULE_LICENSE("GPL");
-
+MODULE_ALIAS_CHARDEV_MAJOR(ACM_TTY_MAJOR);
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 770b3eaa918..080bb1e4b84 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -392,7 +392,7 @@ config USB_GADGET_FSL_QE
controllers having QE or CPM2, given minor tweaks.
Set CONFIG_USB_GADGET to "m" to build this driver as a
- dynmically linked module called "fsl_qe_udc".
+ dynamically linked module called "fsl_qe_udc".
config USB_FSL_QE
tristate
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c
index c22fab16411..563d5727544 100644
--- a/drivers/usb/gadget/atmel_usba_udc.c
+++ b/drivers/usb/gadget/atmel_usba_udc.c
@@ -319,7 +319,7 @@ static inline void usba_cleanup_debugfs(struct usba_udc *udc)
static int vbus_is_present(struct usba_udc *udc)
{
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
return gpio_get_value(udc->vbus_pin);
/* No Vbus detection: Assume always present */
@@ -1821,7 +1821,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name);
udc->vbus_prev = 0;
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
enable_irq(gpio_to_irq(udc->vbus_pin));
/* If Vbus is present, enable the controller and wait for reset */
@@ -1852,7 +1852,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver)
if (driver != udc->driver || !driver->unbind)
return -EINVAL;
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
disable_irq(gpio_to_irq(udc->vbus_pin));
spin_lock_irqsave(&udc->lock, flags);
@@ -1910,7 +1910,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
udc->pdev = pdev;
udc->pclk = pclk;
udc->hclk = hclk;
- udc->vbus_pin = -1;
+ udc->vbus_pin = -ENODEV;
ret = -ENOMEM;
udc->regs = ioremap(regs->start, regs->end - regs->start + 1);
@@ -1996,7 +1996,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
goto err_device_add;
}
- if (pdata->vbus_pin >= 0) {
+ if (gpio_is_valid(pdata->vbus_pin)) {
if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) {
udc->vbus_pin = pdata->vbus_pin;
@@ -2005,7 +2005,7 @@ static int __init usba_udc_probe(struct platform_device *pdev)
"atmel_usba_udc", udc);
if (ret) {
gpio_free(udc->vbus_pin);
- udc->vbus_pin = -1;
+ udc->vbus_pin = -ENODEV;
dev_warn(&udc->pdev->dev,
"failed to request vbus irq; "
"assuming always on\n");
@@ -2051,7 +2051,7 @@ static int __exit usba_udc_remove(struct platform_device *pdev)
usba_ep_cleanup_debugfs(&usba_ep[i]);
usba_cleanup_debugfs(udc);
- if (udc->vbus_pin != -1)
+ if (gpio_is_valid(udc->vbus_pin))
gpio_free(udc->vbus_pin);
free_irq(udc->irq, udc);
diff --git a/drivers/usb/serial/ChangeLog.history b/drivers/usb/serial/ChangeLog.history
index c1b279939bb..f13fd488ebe 100644
--- a/drivers/usb/serial/ChangeLog.history
+++ b/drivers/usb/serial/ChangeLog.history
@@ -715,7 +715,7 @@ io_edgeport.c Change Log comments:
0.2 (01/30/2000) greg kroah-hartman
Milestone 1 release.
- Device is found by USB subsystem, enumerated, fimware is downloaded
+ Device is found by USB subsystem, enumerated, firmware is downloaded
and the descriptors are printed to the debug log, config is set, and
green light starts to blink. Open port works, and data can be sent
and received at the default settings of the UART. Loopback connector
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig
index a65f9196b0a..c480ea4c19f 100644
--- a/drivers/usb/serial/Kconfig
+++ b/drivers/usb/serial/Kconfig
@@ -518,8 +518,8 @@ config USB_SERIAL_SIERRAWIRELESS
help
Say M here if you want to use Sierra Wireless devices.
- Many deviecs have a feature known as TRU-Install, for those devices
- to work properly the USB Storage Sierra feature must be enabled.
+ Many devices have a feature known as TRU-Install. For those devices
+ to work properly, the USB Storage Sierra feature must be enabled.
To compile this driver as a module, choose M here: the
module will be called sierra.
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 1aed584be5e..751a533a434 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -79,6 +79,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) },
{ USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) },
+ { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_ID_S81) }, /* Benq/Siemens S81 */
{ USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) },
{ USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) },
{ USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 54974f446a8..1d7a22e3a9f 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -7,6 +7,10 @@
* (at your option) any later version.
*
*/
+
+#define BENQ_VENDOR_ID 0x04a5
+#define BENQ_PRODUCT_ID_S81 0x4027
+
#define PL2303_VENDOR_ID 0x067b
#define PL2303_PRODUCT_ID 0x2303
#define PL2303_PRODUCT_ID_RSAQ2 0x04bb
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index 8b3cbc87adc..69879e43794 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -139,14 +139,6 @@ static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port,
priv->port = port;
spin_unlock_irqrestore(&priv->lock, flags);
- /*
- * Force low_latency on so that our tty_push actually forces the data
- * through, otherwise it is scheduled, and with high data rates (like
- * with OHCI) data can get lost.
- */
- if (tty)
- tty->low_latency = 1;
-
/* Start reading from the device */
usb_fill_int_urb(priv->int_urb, priv->udev,
usb_rcvintpipe(priv->udev, priv->int_address),
@@ -205,62 +197,6 @@ static void symbol_unthrottle(struct tty_struct *tty)
__func__, result);
}
-static int symbol_ioctl(struct tty_struct *tty, struct file *file,
- unsigned int cmd, unsigned long arg)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct device *dev = &port->dev;
-
- /*
- * Right now we need to figure out what commands
- * most userspace tools want to see for this driver,
- * so just log the things.
- */
- switch (cmd) {
- case TIOCSERGETLSR:
- dev_info(dev, "%s: TIOCSERGETLSR\n", __func__);
- break;
-
- case TIOCGSERIAL:
- dev_info(dev, "%s: TIOCGSERIAL\n", __func__);
- break;
-
- case TIOCMIWAIT:
- dev_info(dev, "%s: TIOCMIWAIT\n", __func__);
- break;
-
- case TIOCGICOUNT:
- dev_info(dev, "%s: TIOCGICOUNT\n", __func__);
- break;
- default:
- dev_info(dev, "%s: unknown (%d)\n", __func__, cmd);
- }
- return -ENOIOCTLCMD;
-}
-
-static int symbol_tiocmget(struct tty_struct *tty, struct file *file)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct device *dev = &port->dev;
-
- /* TODO */
- /* probably just need to shadow whatever was sent to us here */
- dev_info(dev, "%s\n", __func__);
- return 0;
-}
-
-static int symbol_tiocmset(struct tty_struct *tty, struct file *file,
- unsigned int set, unsigned int clear)
-{
- struct usb_serial_port *port = tty->driver_data;
- struct device *dev = &port->dev;
-
- /* TODO */
- /* probably just need to shadow whatever was sent to us here */
- dev_info(dev, "%s\n", __func__);
- return 0;
-}
-
static int symbol_startup(struct usb_serial *serial)
{
struct symbol_private *priv;
@@ -367,9 +303,6 @@ static struct usb_serial_driver symbol_device = {
.shutdown = symbol_shutdown,
.throttle = symbol_throttle,
.unthrottle = symbol_unthrottle,
- .ioctl = symbol_ioctl,
- .tiocmget = symbol_tiocmget,
- .tiocmset = symbol_tiocmset,
};
static int __init symbol_init(void)
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 742a5bc44be..2a70563bbee 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -26,6 +26,7 @@
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
+#include <linux/seq_file.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/list.h>
@@ -421,57 +422,52 @@ static int serial_break(struct tty_struct *tty, int break_state)
return 0;
}
-static int serial_read_proc(char *page, char **start, off_t off, int count,
- int *eof, void *data)
+static int serial_proc_show(struct seq_file *m, void *v)
{
struct usb_serial *serial;
- int length = 0;
int i;
- off_t begin = 0;
char tmp[40];
dbg("%s", __func__);
- length += sprintf(page, "usbserinfo:1.0 driver:2.0\n");
- for (i = 0; i < SERIAL_TTY_MINORS && length < PAGE_SIZE; ++i) {
+ seq_puts(m, "usbserinfo:1.0 driver:2.0\n");
+ for (i = 0; i < SERIAL_TTY_MINORS; ++i) {
serial = usb_serial_get_by_index(i);
if (serial == NULL)
continue;
- length += sprintf(page+length, "%d:", i);
+ seq_printf(m, "%d:", i);
if (serial->type->driver.owner)
- length += sprintf(page+length, " module:%s",
+ seq_printf(m, " module:%s",
module_name(serial->type->driver.owner));
- length += sprintf(page+length, " name:\"%s\"",
+ seq_printf(m, " name:\"%s\"",
serial->type->description);
- length += sprintf(page+length, " vendor:%04x product:%04x",
+ seq_printf(m, " vendor:%04x product:%04x",
le16_to_cpu(serial->dev->descriptor.idVendor),
le16_to_cpu(serial->dev->descriptor.idProduct));
- length += sprintf(page+length, " num_ports:%d",
- serial->num_ports);
- length += sprintf(page+length, " port:%d",
- i - serial->minor + 1);
+ seq_printf(m, " num_ports:%d", serial->num_ports);
+ seq_printf(m, " port:%d", i - serial->minor + 1);
usb_make_path(serial->dev, tmp, sizeof(tmp));
- length += sprintf(page+length, " path:%s", tmp);
+ seq_printf(m, " path:%s", tmp);
- length += sprintf(page+length, "\n");
- if ((length + begin) > (off + count)) {
- usb_serial_put(serial);
- goto done;
- }
- if ((length + begin) < off) {
- begin += length;
- length = 0;
- }
+ seq_putc(m, '\n');
usb_serial_put(serial);
}
- *eof = 1;
-done:
- if (off >= (length + begin))
- return 0;
- *start = page + (off-begin);
- return (count < begin+length-off) ? count : begin+length-off;
+ return 0;
}
+static int serial_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, serial_proc_show, NULL);
+}
+
+static const struct file_operations serial_proc_fops = {
+ .owner = THIS_MODULE,
+ .open = serial_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static int serial_tiocmget(struct tty_struct *tty, struct file *file)
{
struct usb_serial_port *port = tty->driver_data;
@@ -1113,9 +1109,9 @@ static const struct tty_operations serial_ops = {
.unthrottle = serial_unthrottle,
.break_ctl = serial_break,
.chars_in_buffer = serial_chars_in_buffer,
- .read_proc = serial_read_proc,
.tiocmget = serial_tiocmget,
.tiocmset = serial_tiocmset,
+ .proc_fops = &serial_proc_fops,
};
struct tty_driver *usb_serial_tty_driver;
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 882c57b399f..fdba2f69d4c 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -46,6 +46,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/slab.h>
+#include <linux/ata.h>
#include <linux/hdreg.h>
#include <linux/scatterlist.h>
@@ -328,7 +329,7 @@ struct isd200_config {
struct isd200_info {
struct inquiry_data InquiryData;
- struct hd_driveid *id;
+ u16 *id;
struct isd200_config ConfigData;
unsigned char *RegsBuf;
unsigned char ATARegs[8];
@@ -419,19 +420,19 @@ static void isd200_build_sense(struct us_data *us, struct scsi_cmnd *srb)
buf->Flags = UNIT_ATTENTION;
buf->AdditionalSenseCode = 0;
buf->AdditionalSenseCodeQualifier = 0;
- } else if(error & MCR_ERR) {
+ } else if (error & ATA_MCR) {
buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
buf->AdditionalSenseLength = 0xb;
buf->Flags = UNIT_ATTENTION;
buf->AdditionalSenseCode = 0;
buf->AdditionalSenseCodeQualifier = 0;
- } else if(error & TRK0_ERR) {
+ } else if (error & ATA_TRK0NF) {
buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
buf->AdditionalSenseLength = 0xb;
buf->Flags = NOT_READY;
buf->AdditionalSenseCode = 0;
buf->AdditionalSenseCodeQualifier = 0;
- } else if(error & ECC_ERR) {
+ } else if (error & ATA_UNC) {
buf->ErrorCode = 0x70 | SENSE_ERRCODE_VALID;
buf->AdditionalSenseLength = 0xb;
buf->Flags = DATA_PROTECT;
@@ -547,16 +548,16 @@ static int isd200_action( struct us_data *us, int action,
ata.generic.ActionSelect = ACTION_SELECT_1|ACTION_SELECT_5;
ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND;
ata.write.DeviceHeadByte = info->DeviceHead;
- ata.write.CommandByte = WIN_SRST;
+ ata.write.CommandByte = ATA_CMD_DEV_RESET;
isd200_set_srb(info, DMA_NONE, NULL, 0);
break;
case ACTION_IDENTIFY:
US_DEBUGP(" isd200_action(IDENTIFY)\n");
ata.generic.RegisterSelect = REG_COMMAND;
- ata.write.CommandByte = WIN_IDENTIFY;
+ ata.write.CommandByte = ATA_CMD_ID_ATA;
isd200_set_srb(info, DMA_FROM_DEVICE, info->id,
- sizeof(struct hd_driveid));
+ ATA_ID_WORDS * 2);
break;
default:
@@ -944,22 +945,22 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave,
break;
if (!detect) {
- if (regs[ATA_REG_STATUS_OFFSET] & BUSY_STAT) {
+ if (regs[ATA_REG_STATUS_OFFSET] & ATA_BUSY) {
US_DEBUGP(" %s status is still BSY, try again...\n",mstr);
} else {
US_DEBUGP(" %s status !BSY, continue with next operation\n",mstr);
break;
}
}
- /* check for BUSY_STAT and */
- /* WRERR_STAT (workaround ATA Zip drive) and */
- /* ERR_STAT (workaround for Archos CD-ROM) */
+ /* check for ATA_BUSY and */
+ /* ATA_DF (workaround ATA Zip drive) and */
+ /* ATA_ERR (workaround for Archos CD-ROM) */
else if (regs[ATA_REG_STATUS_OFFSET] &
- (BUSY_STAT | WRERR_STAT | ERR_STAT )) {
+ (ATA_BUSY | ATA_DF | ATA_ERR)) {
US_DEBUGP(" Status indicates it is not ready, try again...\n");
}
/* check for DRDY, ATA devices set DRDY after SRST */
- else if (regs[ATA_REG_STATUS_OFFSET] & READY_STAT) {
+ else if (regs[ATA_REG_STATUS_OFFSET] & ATA_DRDY) {
US_DEBUGP(" Identified ATA device\n");
info->DeviceFlags |= DF_ATA_DEVICE;
info->DeviceHead = master_slave;
@@ -1053,103 +1054,50 @@ static int isd200_manual_enum(struct us_data *us)
return(retStatus);
}
-static void isd200_fix_driveid (struct hd_driveid *id)
+static void isd200_fix_driveid(u16 *id)
{
#ifndef __LITTLE_ENDIAN
# ifdef __BIG_ENDIAN
int i;
- u16 *stringcast;
-
- id->config = __le16_to_cpu(id->config);
- id->cyls = __le16_to_cpu(id->cyls);
- id->reserved2 = __le16_to_cpu(id->reserved2);
- id->heads = __le16_to_cpu(id->heads);
- id->track_bytes = __le16_to_cpu(id->track_bytes);
- id->sector_bytes = __le16_to_cpu(id->sector_bytes);
- id->sectors = __le16_to_cpu(id->sectors);
- id->vendor0 = __le16_to_cpu(id->vendor0);
- id->vendor1 = __le16_to_cpu(id->vendor1);
- id->vendor2 = __le16_to_cpu(id->vendor2);
- stringcast = (u16 *)&id->serial_no[0];
- for (i = 0; i < (20/2); i++)
- stringcast[i] = __le16_to_cpu(stringcast[i]);
- id->buf_type = __le16_to_cpu(id->buf_type);
- id->buf_size = __le16_to_cpu(id->buf_size);
- id->ecc_bytes = __le16_to_cpu(id->ecc_bytes);
- stringcast = (u16 *)&id->fw_rev[0];
- for (i = 0; i < (8/2); i++)
- stringcast[i] = __le16_to_cpu(stringcast[i]);
- stringcast = (u16 *)&id->model[0];
- for (i = 0; i < (40/2); i++)
- stringcast[i] = __le16_to_cpu(stringcast[i]);
- id->dword_io = __le16_to_cpu(id->dword_io);
- id->reserved50 = __le16_to_cpu(id->reserved50);
- id->field_valid = __le16_to_cpu(id->field_valid);
- id->cur_cyls = __le16_to_cpu(id->cur_cyls);
- id->cur_heads = __le16_to_cpu(id->cur_heads);
- id->cur_sectors = __le16_to_cpu(id->cur_sectors);
- id->cur_capacity0 = __le16_to_cpu(id->cur_capacity0);
- id->cur_capacity1 = __le16_to_cpu(id->cur_capacity1);
- id->lba_capacity = __le32_to_cpu(id->lba_capacity);
- id->dma_1word = __le16_to_cpu(id->dma_1word);
- id->dma_mword = __le16_to_cpu(id->dma_mword);
- id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
- id->eide_dma_min = __le16_to_cpu(id->eide_dma_min);
- id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
- id->eide_pio = __le16_to_cpu(id->eide_pio);
- id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
- for (i = 0; i < 2; ++i)
- id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
- for (i = 0; i < 4; ++i)
- id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
- id->queue_depth = __le16_to_cpu(id->queue_depth);
- for (i = 0; i < 4; ++i)
- id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
- id->major_rev_num = __le16_to_cpu(id->major_rev_num);
- id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
- id->command_set_1 = __le16_to_cpu(id->command_set_1);
- id->command_set_2 = __le16_to_cpu(id->command_set_2);
- id->cfsse = __le16_to_cpu(id->cfsse);
- id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1);
- id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2);
- id->csf_default = __le16_to_cpu(id->csf_default);
- id->dma_ultra = __le16_to_cpu(id->dma_ultra);
- id->trseuc = __le16_to_cpu(id->trseuc);
- id->trsEuc = __le16_to_cpu(id->trsEuc);
- id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues);
- id->mprc = __le16_to_cpu(id->mprc);
- id->hw_config = __le16_to_cpu(id->hw_config);
- id->acoustic = __le16_to_cpu(id->acoustic);
- id->msrqs = __le16_to_cpu(id->msrqs);
- id->sxfert = __le16_to_cpu(id->sxfert);
- id->sal = __le16_to_cpu(id->sal);
- id->spg = __le32_to_cpu(id->spg);
- id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
- for (i = 0; i < 22; i++)
- id->words104_125[i] = __le16_to_cpu(id->words104_125[i]);
- id->last_lun = __le16_to_cpu(id->last_lun);
- id->word127 = __le16_to_cpu(id->word127);
- id->dlf = __le16_to_cpu(id->dlf);
- id->csfo = __le16_to_cpu(id->csfo);
- for (i = 0; i < 26; i++)
- id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
- id->word156 = __le16_to_cpu(id->word156);
- for (i = 0; i < 3; i++)
- id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
- id->cfa_power = __le16_to_cpu(id->cfa_power);
- for (i = 0; i < 14; i++)
- id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
- for (i = 0; i < 31; i++)
- id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
- for (i = 0; i < 48; i++)
- id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
- id->integrity_word = __le16_to_cpu(id->integrity_word);
+
+ for (i = 0; i < ATA_ID_WORDS; i++)
+ id[i] = __le16_to_cpu(id[i]);
# else
# error "Please fix <asm/byteorder.h>"
# endif
#endif
}
+static void isd200_dump_driveid(u16 *id)
+{
+ US_DEBUGP(" Identify Data Structure:\n");
+ US_DEBUGP(" config = 0x%x\n", id[ATA_ID_CONFIG]);
+ US_DEBUGP(" cyls = 0x%x\n", id[ATA_ID_CYLS]);
+ US_DEBUGP(" heads = 0x%x\n", id[ATA_ID_HEADS]);
+ US_DEBUGP(" track_bytes = 0x%x\n", id[4]);
+ US_DEBUGP(" sector_bytes = 0x%x\n", id[5]);
+ US_DEBUGP(" sectors = 0x%x\n", id[ATA_ID_SECTORS]);
+ US_DEBUGP(" serial_no[0] = 0x%x\n", *(char *)&id[ATA_ID_SERNO]);
+ US_DEBUGP(" buf_type = 0x%x\n", id[20]);
+ US_DEBUGP(" buf_size = 0x%x\n", id[ATA_ID_BUF_SIZE]);
+ US_DEBUGP(" ecc_bytes = 0x%x\n", id[22]);
+ US_DEBUGP(" fw_rev[0] = 0x%x\n", *(char *)&id[ATA_ID_FW_REV]);
+ US_DEBUGP(" model[0] = 0x%x\n", *(char *)&id[ATA_ID_PROD]);
+ US_DEBUGP(" max_multsect = 0x%x\n", id[ATA_ID_MAX_MULTSECT] & 0xff);
+ US_DEBUGP(" dword_io = 0x%x\n", id[ATA_ID_DWORD_IO]);
+ US_DEBUGP(" capability = 0x%x\n", id[ATA_ID_CAPABILITY] >> 8);
+ US_DEBUGP(" tPIO = 0x%x\n", id[ATA_ID_OLD_PIO_MODES] >> 8);
+ US_DEBUGP(" tDMA = 0x%x\n", id[ATA_ID_OLD_DMA_MODES] >> 8);
+ US_DEBUGP(" field_valid = 0x%x\n", id[ATA_ID_FIELD_VALID]);
+ US_DEBUGP(" cur_cyls = 0x%x\n", id[ATA_ID_CUR_CYLS]);
+ US_DEBUGP(" cur_heads = 0x%x\n", id[ATA_ID_CUR_HEADS]);
+ US_DEBUGP(" cur_sectors = 0x%x\n", id[ATA_ID_CUR_SECTORS]);
+ US_DEBUGP(" cur_capacity = 0x%x\n", ata_id_u32(id, 57));
+ US_DEBUGP(" multsect = 0x%x\n", id[ATA_ID_MULTSECT] & 0xff);
+ US_DEBUGP(" lba_capacity = 0x%x\n", ata_id_u32(id, ATA_ID_LBA_CAPACITY));
+ US_DEBUGP(" command_set_1 = 0x%x\n", id[ATA_ID_COMMAND_SET_1]);
+ US_DEBUGP(" command_set_2 = 0x%x\n", id[ATA_ID_COMMAND_SET_2]);
+}
/**************************************************************************
* isd200_get_inquiry_data
@@ -1163,7 +1111,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
{
struct isd200_info *info = (struct isd200_info *)us->extra;
int retStatus = ISD200_GOOD;
- struct hd_driveid *id = info->id;
+ u16 *id = info->id;
US_DEBUGP("Entering isd200_get_inquiry_data\n");
@@ -1180,8 +1128,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
/* this must be an ATA device */
/* perform an ATA Command Identify */
transferStatus = isd200_action( us, ACTION_IDENTIFY,
- id,
- sizeof(struct hd_driveid) );
+ id, ATA_ID_WORDS * 2);
if (transferStatus != ISD200_TRANSPORT_GOOD) {
/* Error issuing ATA Command Identify */
US_DEBUGP(" Error issuing ATA Command Identify\n");
@@ -1191,35 +1138,9 @@ static int isd200_get_inquiry_data( struct us_data *us )
int i;
__be16 *src;
__u16 *dest;
- isd200_fix_driveid(id);
- US_DEBUGP(" Identify Data Structure:\n");
- US_DEBUGP(" config = 0x%x\n", id->config);
- US_DEBUGP(" cyls = 0x%x\n", id->cyls);
- US_DEBUGP(" heads = 0x%x\n", id->heads);
- US_DEBUGP(" track_bytes = 0x%x\n", id->track_bytes);
- US_DEBUGP(" sector_bytes = 0x%x\n", id->sector_bytes);
- US_DEBUGP(" sectors = 0x%x\n", id->sectors);
- US_DEBUGP(" serial_no[0] = 0x%x\n", id->serial_no[0]);
- US_DEBUGP(" buf_type = 0x%x\n", id->buf_type);
- US_DEBUGP(" buf_size = 0x%x\n", id->buf_size);
- US_DEBUGP(" ecc_bytes = 0x%x\n", id->ecc_bytes);
- US_DEBUGP(" fw_rev[0] = 0x%x\n", id->fw_rev[0]);
- US_DEBUGP(" model[0] = 0x%x\n", id->model[0]);
- US_DEBUGP(" max_multsect = 0x%x\n", id->max_multsect);
- US_DEBUGP(" dword_io = 0x%x\n", id->dword_io);
- US_DEBUGP(" capability = 0x%x\n", id->capability);
- US_DEBUGP(" tPIO = 0x%x\n", id->tPIO);
- US_DEBUGP(" tDMA = 0x%x\n", id->tDMA);
- US_DEBUGP(" field_valid = 0x%x\n", id->field_valid);
- US_DEBUGP(" cur_cyls = 0x%x\n", id->cur_cyls);
- US_DEBUGP(" cur_heads = 0x%x\n", id->cur_heads);
- US_DEBUGP(" cur_sectors = 0x%x\n", id->cur_sectors);
- US_DEBUGP(" cur_capacity = 0x%x\n", (id->cur_capacity1 << 16) + id->cur_capacity0 );
- US_DEBUGP(" multsect = 0x%x\n", id->multsect);
- US_DEBUGP(" lba_capacity = 0x%x\n", id->lba_capacity);
- US_DEBUGP(" command_set_1 = 0x%x\n", id->command_set_1);
- US_DEBUGP(" command_set_2 = 0x%x\n", id->command_set_2);
+ isd200_fix_driveid(id);
+ isd200_dump_driveid(id);
memset(&info->InquiryData, 0, sizeof(info->InquiryData));
@@ -1229,30 +1150,30 @@ static int isd200_get_inquiry_data( struct us_data *us )
/* The length must be at least 36 (5 + 31) */
info->InquiryData.AdditionalLength = 0x1F;
- if (id->command_set_1 & COMMANDSET_MEDIA_STATUS) {
+ if (id[ATA_ID_COMMAND_SET_1] & COMMANDSET_MEDIA_STATUS) {
/* set the removable bit */
info->InquiryData.DeviceTypeModifier = DEVICE_REMOVABLE;
info->DeviceFlags |= DF_REMOVABLE_MEDIA;
}
/* Fill in vendor identification fields */
- src = (__be16*)id->model;
+ src = (__be16 *)&id[ATA_ID_PROD];
dest = (__u16*)info->InquiryData.VendorId;
for (i=0;i<4;i++)
dest[i] = be16_to_cpu(src[i]);
- src = (__be16*)(id->model+8);
+ src = (__be16 *)&id[ATA_ID_PROD + 8/2];
dest = (__u16*)info->InquiryData.ProductId;
for (i=0;i<8;i++)
dest[i] = be16_to_cpu(src[i]);
- src = (__be16*)id->fw_rev;
+ src = (__be16 *)&id[ATA_ID_FW_REV];
dest = (__u16*)info->InquiryData.ProductRevisionLevel;
for (i=0;i<2;i++)
dest[i] = be16_to_cpu(src[i]);
/* determine if it supports Media Status Notification */
- if (id->command_set_2 & COMMANDSET_MEDIA_STATUS) {
+ if (id[ATA_ID_COMMAND_SET_2] & COMMANDSET_MEDIA_STATUS) {
US_DEBUGP(" Device supports Media Status Notification\n");
/* Indicate that it is enabled, even though it is not
@@ -1301,7 +1222,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
union ata_cdb * ataCdb)
{
struct isd200_info *info = (struct isd200_info *)us->extra;
- struct hd_driveid *id = info->id;
+ u16 *id = info->id;
int sendToTransport = 1;
unsigned char sectnum, head;
unsigned short cylinder;
@@ -1369,13 +1290,12 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
US_DEBUGP(" ATA OUT - SCSIOP_READ_CAPACITY\n");
- if (id->capability & CAPABILITY_LBA ) {
- capacity = id->lba_capacity - 1;
- } else {
- capacity = (id->heads *
- id->cyls *
- id->sectors) - 1;
- }
+ if (ata_id_has_lba(id))
+ capacity = ata_id_u32(id, ATA_ID_LBA_CAPACITY) - 1;
+ else
+ capacity = (id[ATA_ID_HEADS] * id[ATA_ID_CYLS] *
+ id[ATA_ID_SECTORS]) - 1;
+
readCapacityData.LogicalBlockAddress = cpu_to_be32(capacity);
readCapacityData.BytesPerBlock = cpu_to_be32(0x200);
@@ -1392,16 +1312,16 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
- if (id->capability & CAPABILITY_LBA) {
+ if (ata_id_has_lba(id)) {
sectnum = (unsigned char)(lba);
cylinder = (unsigned short)(lba>>8);
head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
} else {
- sectnum = (unsigned char)((lba % id->sectors) + 1);
- cylinder = (unsigned short)(lba / (id->sectors *
- id->heads));
- head = (unsigned char)((lba / id->sectors) %
- id->heads);
+ sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
+ cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
+ id[ATA_ID_HEADS]));
+ head = (u8)((lba / id[ATA_ID_SECTORS]) %
+ id[ATA_ID_HEADS]);
}
ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
@@ -1415,7 +1335,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
- ataCdb->write.CommandByte = WIN_READ;
+ ataCdb->write.CommandByte = ATA_CMD_PIO_READ;
break;
case WRITE_10:
@@ -1424,14 +1344,16 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
lba = be32_to_cpu(*(__be32 *)&srb->cmnd[2]);
blockCount = (unsigned long)srb->cmnd[7]<<8 | (unsigned long)srb->cmnd[8];
- if (id->capability & CAPABILITY_LBA) {
+ if (ata_id_has_lba(id)) {
sectnum = (unsigned char)(lba);
cylinder = (unsigned short)(lba>>8);
head = ATA_ADDRESS_DEVHEAD_LBA_MODE | (unsigned char)(lba>>24 & 0x0F);
} else {
- sectnum = (unsigned char)((lba % id->sectors) + 1);
- cylinder = (unsigned short)(lba / (id->sectors * id->heads));
- head = (unsigned char)((lba / id->sectors) % id->heads);
+ sectnum = (u8)((lba % id[ATA_ID_SECTORS]) + 1);
+ cylinder = (u16)(lba / (id[ATA_ID_SECTORS] *
+ id[ATA_ID_HEADS]));
+ head = (u8)((lba / id[ATA_ID_SECTORS]) %
+ id[ATA_ID_HEADS]);
}
ataCdb->generic.SignatureByte0 = info->ConfigData.ATAMajorCommand;
ataCdb->generic.SignatureByte1 = info->ConfigData.ATAMinorCommand;
@@ -1445,7 +1367,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
ataCdb->write.CylinderHighByte = (unsigned char)(cylinder>>8);
ataCdb->write.CylinderLowByte = (unsigned char)cylinder;
ataCdb->write.DeviceHeadByte = (head | ATA_ADDRESS_DEVHEAD_STD);
- ataCdb->write.CommandByte = WIN_WRITE;
+ ataCdb->write.CommandByte = ATA_CMD_PIO_WRITE;
break;
case ALLOW_MEDIUM_REMOVAL:
@@ -1459,7 +1381,7 @@ static int isd200_scsi_to_ata(struct scsi_cmnd *srb, struct us_data *us,
ataCdb->generic.TransferBlockSize = 1;
ataCdb->generic.RegisterSelect = REG_COMMAND;
ataCdb->write.CommandByte = (srb->cmnd[4] & 0x1) ?
- WIN_DOORLOCK : WIN_DOORUNLOCK;
+ ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
isd200_srb_set_bufflen(srb, 0);
} else {
US_DEBUGP(" Not removeable media, just report okay\n");
@@ -1539,8 +1461,7 @@ static int isd200_init_info(struct us_data *us)
if (!info)
retStatus = ISD200_ERROR;
else {
- info->id = (struct hd_driveid *)
- kzalloc(sizeof(struct hd_driveid), GFP_KERNEL);
+ info->id = kzalloc(ATA_ID_WORDS * 2, GFP_KERNEL);
info->RegsBuf = (unsigned char *)
kmalloc(sizeof(info->ATARegs), GFP_KERNEL);
info->srb.sense_buffer =
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c
index f0aac0cf315..386eaa22d21 100644
--- a/drivers/usb/wusbcore/devconnect.c
+++ b/drivers/usb/wusbcore/devconnect.c
@@ -471,7 +471,7 @@ static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
*/
static void wusbhc_keep_alive_run(struct work_struct *ws)
{
- struct delayed_work *dw = container_of(ws, struct delayed_work, work);
+ struct delayed_work *dw = to_delayed_work(ws);
struct wusbhc *wusbhc = container_of(dw, struct wusbhc, keep_alive_timer);
mutex_lock(&wusbhc->mutex);
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c
index 8118db7f1d8..b2f149fedcc 100644
--- a/drivers/usb/wusbcore/security.c
+++ b/drivers/usb/wusbcore/security.c
@@ -562,7 +562,7 @@ void wusbhc_gtk_rekey(struct wusbhc *wusbhc)
struct wusb_dev *wusb_dev;
wusb_dev = wusbhc->port[p].wusb_dev;
- if (!wusb_dev || !wusb_dev->usb_dev | !wusb_dev->usb_dev->authenticated)
+ if (!wusb_dev || !wusb_dev->usb_dev || !wusb_dev->usb_dev->authenticated)
continue;
usb_fill_control_urb(wusb_dev->set_gtk_urb, wusb_dev->usb_dev,
diff --git a/drivers/uwb/Kconfig b/drivers/uwb/Kconfig
index ca783127af3..bac8e7a6f17 100644
--- a/drivers/uwb/Kconfig
+++ b/drivers/uwb/Kconfig
@@ -48,10 +48,10 @@ config UWB_WHCI
help
This driver enables the radio controller for WHCI cards.
- WHCI is an specification developed by Intel
+ WHCI is a specification developed by Intel
(http://www.intel.com/technology/comms/wusb/whci.htm) much
in the spirit of USB's EHCI, but for UWB and Wireless USB
- radio/host controllers connected via memmory mapping (eg:
+ radio/host controllers connected via memory mapping (eg:
PCI). Most of these cards come also with a Wireless USB host
controller.
diff --git a/drivers/video/68328fb.c b/drivers/video/68328fb.c
index 7f907fb23b8..0b17824b0eb 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/68328fb.c
@@ -471,9 +471,11 @@ int __init mc68x328fb_init(void)
fb_info.pseudo_palette = &mc68x328fb_pseudo_palette;
fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
- fb_alloc_cmap(&fb_info.cmap, 256, 0);
+ if (fb_alloc_cmap(&fb_info.cmap, 256, 0))
+ return -ENOMEM;
if (register_framebuffer(&fb_info) < 0) {
+ fb_dealloc_cmap(&fb_info.cmap);
return -EINVAL;
}
@@ -494,6 +496,7 @@ module_init(mc68x328fb_init);
static void __exit mc68x328fb_cleanup(void)
{
unregister_framebuffer(&fb_info);
+ fb_dealloc_cmap(&fb_info.cmap);
}
module_exit(mc68x328fb_cleanup);
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 41c27a44bd8..ffe2f2796e2 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1597,32 +1597,8 @@ config FB_VT8623
Driver for CastleRock integrated graphics core in the
VIA VT8623 [Apollo CLE266] chipset.
-config FB_CYBLA
- tristate "Cyberblade/i1 support"
- depends on FB && PCI && X86_32 && !64BIT
- select FB_CFB_IMAGEBLIT
- ---help---
- This driver is supposed to support the Trident Cyberblade/i1
- graphics core integrated in the VIA VT8601A North Bridge,
- also known as VIA Apollo PLE133.
-
- Status:
- - Developed, tested and working on EPIA 5000 and EPIA 800.
- - Does work reliable on all systems with CRT/LCD connected to
- normal VGA ports.
- - Should work on systems that do use the internal LCD port, but
- this is absolutely not tested.
-
- Character imageblit, copyarea and rectangle fill are hw accelerated,
- ypan scrolling is used by default.
-
- Please do read <file:Documentation/fb/cyblafb/*>.
-
- To compile this driver as a module, choose M here: the
- module will be called cyblafb.
-
config FB_TRIDENT
- tristate "Trident support"
+ tristate "Trident/CyberXXX/CyberBlade support"
depends on FB && PCI
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
@@ -1633,21 +1609,14 @@ config FB_TRIDENT
and Blade XP.
There are also integrated versions of these chips called CyberXXXX,
CyberImage or CyberBlade. These chips are mostly found in laptops
- but also on some motherboards. For more information, read
- <file:Documentation/fb/tridentfb.txt>
+ but also on some motherboards including early VIA EPIA motherboards.
+ For more information, read <file:Documentation/fb/tridentfb.txt>
Say Y if you have such a graphics board.
To compile this driver as a module, choose M here: the
module will be called tridentfb.
-config FB_TRIDENT_ACCEL
- bool "Trident Acceleration functions (EXPERIMENTAL)"
- depends on FB_TRIDENT && EXPERIMENTAL
- ---help---
- This will compile the Trident frame buffer device with
- acceleration functions.
-
config FB_ARK
tristate "ARK 2000PV support"
depends on FB && PCI
@@ -1920,6 +1889,30 @@ config FB_TMIO_ACCELL
depends on FB_TMIO
default y
+config FB_S3C
+ tristate "Samsung S3C framebuffer support"
+ depends on FB && ARCH_S3C64XX
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in FB controller in the Samsung
+ SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
+ and the S3C64XX series such as the S3C6400 and S3C6410.
+
+ These chips all have the same basic framebuffer design with the
+ actual capabilities depending on the chip. For instance the S3C6400
+ and S3C6410 support 4 hardware windows whereas the S3C24XX series
+ currently only have two.
+
+ Currently the support is only for the S3C6400 and S3C6410 SoCs.
+
+config FB_S3C_DEBUG_REGWRITE
+ bool "Debug register writes"
+ depends on FB_S3C
+ ---help---
+ Show all register writes via printk(KERN_DEBUG)
+
config FB_S3C2410
tristate "S3C2410 LCD framebuffer support"
depends on FB && ARCH_S3C2410
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index bb265eca7d5..0dbd6c68d76 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
obj-$(CONFIG_FB_MAC) += macfb.o
obj-$(CONFIG_FB_HECUBA) += hecubafb.o
+obj-$(CONFIG_FB_N411) += n411.o
obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_XVR500) += sunxvr500.o
obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
@@ -110,6 +111,7 @@ obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
obj-$(CONFIG_FB_SH7760) += sh7760fb.o
obj-$(CONFIG_FB_IMX) += imxfb.o
+obj-$(CONFIG_FB_S3C) += s3c-fb.o
obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
diff --git a/drivers/video/amba-clcd.c b/drivers/video/amba-clcd.c
index 4e046fed138..61050ab1412 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/amba-clcd.c
@@ -408,7 +408,9 @@ static int clcdfb_register(struct clcd_fb *fb)
/*
* Allocate colourmap.
*/
- fb_alloc_cmap(&fb->fb.cmap, 256, 0);
+ ret = fb_alloc_cmap(&fb->fb.cmap, 256, 0);
+ if (ret)
+ goto unmap;
/*
* Ensure interrupts are disabled.
@@ -426,6 +428,8 @@ static int clcdfb_register(struct clcd_fb *fb)
printk(KERN_ERR "CLCD: cannot register framebuffer (%d)\n", ret);
+ fb_dealloc_cmap(&fb->fb.cmap);
+ unmap:
iounmap(fb->regs);
free_clk:
clk_put(fb->clk);
@@ -485,6 +489,8 @@ static int clcdfb_remove(struct amba_device *dev)
clcdfb_disable(fb);
unregister_framebuffer(&fb->fb);
+ if (fb->fb.cmap.len)
+ fb_dealloc_cmap(&fb->fb.cmap);
iounmap(fb->regs);
clk_put(fb->clk);
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 100f2366146..82bedd7f778 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2437,7 +2437,9 @@ default_chipset:
goto amifb_error;
}
- fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
+ err = fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
+ if (err)
+ goto amifb_error;
if (register_framebuffer(&fb_info) < 0) {
err = -EINVAL;
@@ -2456,7 +2458,8 @@ amifb_error:
static void amifb_deinit(void)
{
- fb_dealloc_cmap(&fb_info.cmap);
+ if (fb_info.cmap.len)
+ fb_dealloc_cmap(&fb_info.cmap);
chipfree();
if (videomemory)
iounmap((void*)videomemory);
diff --git a/drivers/video/arkfb.c b/drivers/video/arkfb.c
index 314d18694b6..d583bea608f 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/arkfb.c
@@ -470,7 +470,7 @@ static void ark_dac_read_regs(void *data, u8 *code, int count)
while (count != 0)
{
- vga_wseq(NULL, 0x1C, regval | (code[0] & 4) ? 0x80 : 0);
+ vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
code[1] = vga_r(NULL, dac_regs[code[0] & 3]);
count--;
code += 2;
@@ -485,7 +485,7 @@ static void ark_dac_write_regs(void *data, u8 *code, int count)
while (count != 0)
{
- vga_wseq(NULL, 0x1C, regval | (code[0] & 4) ? 0x80 : 0);
+ vga_wseq(NULL, 0x1C, regval | (code[0] & 4 ? 0x80 : 0));
vga_w(NULL, dac_regs[code[0] & 3], code[1]);
count--;
code += 2;
diff --git a/drivers/video/asiliantfb.c b/drivers/video/asiliantfb.c
index 1fd22f460b0..1a1f946d8fe 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/asiliantfb.c
@@ -505,19 +505,27 @@ static struct fb_var_screeninfo asiliantfb_var __devinitdata = {
.vsync_len = 2,
};
-static void __devinit init_asiliant(struct fb_info *p, unsigned long addr)
+static int __devinit init_asiliant(struct fb_info *p, unsigned long addr)
{
+ int err;
+
p->fix = asiliantfb_fix;
p->fix.smem_start = addr;
p->var = asiliantfb_var;
p->fbops = &asiliantfb_ops;
p->flags = FBINFO_DEFAULT;
- fb_alloc_cmap(&p->cmap, 256, 0);
+ err = fb_alloc_cmap(&p->cmap, 256, 0);
+ if (err) {
+ printk(KERN_ERR "C&T 69000 fb failed to alloc cmap memory\n");
+ return err;
+ }
- if (register_framebuffer(p) < 0) {
+ err = register_framebuffer(p);
+ if (err < 0) {
printk(KERN_ERR "C&T 69000 framebuffer failed to register\n");
- return;
+ fb_dealloc_cmap(&p->cmap);
+ return err;
}
printk(KERN_INFO "fb%d: Asiliant 69000 frame buffer (%dK RAM detected)\n",
@@ -532,6 +540,7 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
{
unsigned long addr, size;
struct fb_info *p;
+ int err;
if ((dp->resource[0].flags & IORESOURCE_MEM) == 0)
return -ENODEV;
@@ -560,7 +569,13 @@ asiliantfb_pci_init(struct pci_dev *dp, const struct pci_device_id *ent)
pci_write_config_dword(dp, 4, 0x02800083);
writeb(3, p->screen_base + 0x400784);
- init_asiliant(p, addr);
+ err = init_asiliant(p, addr);
+ if (err) {
+ iounmap(p->screen_base);
+ release_mem_region(addr, size);
+ framebuffer_release(p);
+ return err;
+ }
pci_set_drvdata(dp, p);
return 0;
@@ -571,6 +586,7 @@ static void __devexit asiliantfb_remove(struct pci_dev *dp)
struct fb_info *p = pci_get_drvdata(dp);
unregister_framebuffer(p);
+ fb_dealloc_cmap(&p->cmap);
iounmap(p->screen_base);
release_mem_region(pci_resource_start(dp, 0), pci_resource_len(dp, 0));
pci_set_drvdata(dp, NULL);
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/aty/mach64_accel.c
index a8f60c33863..0cc9724e61a 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/aty/mach64_accel.c
@@ -39,7 +39,8 @@ void aty_reset_engine(const struct atyfb_par *par)
{
/* reset engine */
aty_st_le32(GEN_TEST_CNTL,
- aty_ld_le32(GEN_TEST_CNTL, par) & ~GUI_ENGINE_ENABLE, par);
+ aty_ld_le32(GEN_TEST_CNTL, par) &
+ ~(GUI_ENGINE_ENABLE | HWCURSOR_ENABLE), par);
/* enable engine */
aty_st_le32(GEN_TEST_CNTL,
aty_ld_le32(GEN_TEST_CNTL, par) | GUI_ENGINE_ENABLE, par);
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index faf95da8fcb..04c710804bb 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -77,9 +77,13 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
if (par->asleep)
return -EPERM;
- /* Hide cursor */
wait_for_fifo(1, par);
- aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par) & ~HWCURSOR_ENABLE, par);
+ if (cursor->enable)
+ aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
+ | HWCURSOR_ENABLE, par);
+ else
+ aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
+ & ~HWCURSOR_ENABLE, par);
/* set position */
if (cursor->set & FB_CUR_SETPOS) {
@@ -109,7 +113,7 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
y<<=1;
h<<=1;
}
- wait_for_fifo(4, par);
+ wait_for_fifo(3, par);
aty_st_le32(CUR_OFFSET, (info->fix.smem_len >> 3) + (yoff << 1), par);
aty_st_le32(CUR_HORZ_VERT_OFF,
((u32) (64 - h + yoff) << 16) | xoff, par);
@@ -177,11 +181,6 @@ static int atyfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
}
}
- if (cursor->enable) {
- wait_for_fifo(1, par);
- aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, par)
- | HWCURSOR_ENABLE, par);
- }
return 0;
}
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c
index c6d7cc76516..97a1f095f32 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/aty/radeon_pm.c
@@ -89,6 +89,9 @@ static struct radeon_device_id radeon_workaround_list[] = {
BUGFIX("Acer Aspire 2010",
PCI_VENDOR_ID_AI, 0x0061,
radeon_pm_off, radeon_reinitialize_M10),
+ BUGFIX("Acer Travelmate 290D/292LMi",
+ PCI_VENDOR_ID_AI, 0x005a,
+ radeon_pm_off, radeon_reinitialize_M10),
{ .ident = NULL }
};
@@ -2582,7 +2585,7 @@ static void radeon_set_suspend(struct radeonfb_info *rinfo, int suspend)
* calling pci_set_power_state()
*/
radeonfb_whack_power_state(rinfo, PCI_D2);
- pci_set_power_state(rinfo->pdev, PCI_D2);
+ __pci_complete_power_transition(rinfo->pdev, PCI_D2);
} else {
printk(KERN_DEBUG "radeonfb (%s): switching to D0 state...\n",
pci_name(rinfo->pdev));
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index 72facb9eb7d..f9d19be0554 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -84,6 +84,15 @@ config LCD_TOSA
If you have an Sharp SL-6000 Zaurus say Y to enable a driver
for its LCD.
+config LCD_HP700
+ tristate "HP Jornada 700 series LCD Driver"
+ depends on LCD_CLASS_DEVICE
+ depends on SA1100_JORNADA720_SSP && !PREEMPT
+ default y
+ help
+ If you have an HP Jornada 700 series handheld (710/720/728)
+ say Y to enable LCD control driver.
+
#
# Backlight
#
@@ -157,6 +166,15 @@ config BACKLIGHT_HP680
If you have a HP Jornada 680, say y to enable the
backlight driver.
+config BACKLIGHT_HP700
+ tristate "HP Jornada 700 series Backlight Driver"
+ depends on BACKLIGHT_CLASS_DEVICE
+ depends on SA1100_JORNADA720_SSP && !PREEMPT
+ default y
+ help
+ If you have an HP Jornada 700 series,
+ say Y to include backlight control driver.
+
config BACKLIGHT_PROGEAR
tristate "Frontpath ProGear Backlight Driver"
depends on BACKLIGHT_CLASS_DEVICE && PCI && X86
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index 63d75949816..4eb178c1d68 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -2,6 +2,7 @@
obj-$(CONFIG_LCD_CLASS_DEVICE) += lcd.o
obj-$(CONFIG_LCD_CORGI) += corgi_lcd.o
+obj-$(CONFIG_LCD_HP700) += jornada720_lcd.o
obj-$(CONFIG_LCD_LTV350QV) += ltv350qv.o
obj-$(CONFIG_LCD_ILI9320) += ili9320.o
obj-$(CONFIG_LCD_PLATFORM) += platform_lcd.o
@@ -12,6 +13,7 @@ obj-$(CONFIG_LCD_TOSA) += tosa_lcd.o
obj-$(CONFIG_BACKLIGHT_CLASS_DEVICE) += backlight.o
obj-$(CONFIG_BACKLIGHT_ATMEL_PWM) += atmel-pwm-bl.o
obj-$(CONFIG_BACKLIGHT_GENERIC) += generic_bl.o
+obj-$(CONFIG_BACKLIGHT_HP700) += jornada720_bl.o
obj-$(CONFIG_BACKLIGHT_HP680) += hp680_bl.o
obj-$(CONFIG_BACKLIGHT_LOCOMO) += locomolcd.o
obj-$(CONFIG_BACKLIGHT_OMAP1) += omap1_bl.o
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c
index 157057c79ca..dd37cbcaf8c 100644
--- a/drivers/video/backlight/backlight.c
+++ b/drivers/video/backlight/backlight.c
@@ -35,6 +35,8 @@ static int fb_notifier_callback(struct notifier_block *self,
return 0;
bd = container_of(self, struct backlight_device, fb_notif);
+ if (!lock_fb_info(evdata->info))
+ return -ENODEV;
mutex_lock(&bd->ops_lock);
if (bd->ops)
if (!bd->ops->check_fb ||
@@ -47,6 +49,7 @@ static int fb_notifier_callback(struct notifier_block *self,
backlight_update_status(bd);
}
mutex_unlock(&bd->ops_lock);
+ unlock_fb_info(evdata->info);
return 0;
}
diff --git a/drivers/video/backlight/jornada720_bl.c b/drivers/video/backlight/jornada720_bl.c
new file mode 100644
index 00000000000..c3ebb6b41ce
--- /dev/null
+++ b/drivers/video/backlight/jornada720_bl.c
@@ -0,0 +1,161 @@
+/*
+ *
+ * Backlight driver for HP Jornada 700 series (710/720/728)
+ * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 or any later version as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/backlight.h>
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <mach/jornada720.h>
+#include <mach/hardware.h>
+
+#include <video/s1d13xxxfb.h>
+
+#define BL_MAX_BRIGHT 255
+#define BL_DEF_BRIGHT 25
+
+static int jornada_bl_get_brightness(struct backlight_device *bd)
+{
+ int ret;
+
+ /* check if backlight is on */
+ if (!(PPSR & PPC_LDD1))
+ return 0;
+
+ jornada_ssp_start();
+
+ /* cmd should return txdummy */
+ ret = jornada_ssp_byte(GETBRIGHTNESS);
+
+ if (jornada_ssp_byte(GETBRIGHTNESS) != TXDUMMY) {
+ printk(KERN_ERR "bl : get brightness timeout\n");
+ jornada_ssp_end();
+ return -ETIMEDOUT;
+ } else /* exchange txdummy for value */
+ ret = jornada_ssp_byte(TXDUMMY);
+
+ jornada_ssp_end();
+
+ return (BL_MAX_BRIGHT - ret);
+}
+
+static int jornada_bl_update_status(struct backlight_device *bd)
+{
+ int ret = 0;
+
+ jornada_ssp_start();
+
+ /* If backlight is off then really turn it off */
+ if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) {
+ ret = jornada_ssp_byte(BRIGHTNESSOFF);
+ if (ret != TXDUMMY) {
+ printk(KERN_INFO "bl : brightness off timeout\n");
+ /* turn off backlight */
+ PPSR &= ~PPC_LDD1;
+ PPDR |= PPC_LDD1;
+ ret = -ETIMEDOUT;
+ }
+ } else /* turn on backlight */
+ PPSR |= PPC_LDD1;
+
+ /* send command to our mcu */
+ if (jornada_ssp_byte(SETBRIGHTNESS) != TXDUMMY) {
+ printk(KERN_INFO "bl : failed to set brightness\n");
+ ret = -ETIMEDOUT;
+ goto out
+ }
+
+ /* at this point we expect that the mcu has accepted
+ our command and is waiting for our new value
+ please note that maximum brightness is 255,
+ but due to physical layout it is equal to 0, so we simply
+ invert the value (MAX VALUE - NEW VALUE). */
+ if (jornada_ssp_byte(BL_MAX_BRIGHT - bd->props.brightness) != TXDUMMY) {
+ printk(KERN_ERR "bl : set brightness failed\n");
+ ret = -ETIMEDOUT;
+ }
+
+ /* If infact we get an TXDUMMY as output we are happy and dont
+ make any further comments about it */
+out:
+ jornada_ssp_end();
+
+ return ret;
+}
+
+static struct backlight_ops jornada_bl_ops = {
+ .get_brightness = jornada_bl_get_brightness,
+ .update_status = jornada_bl_update_status,
+ .options = BL_CORE_SUSPENDRESUME,
+};
+
+static int jornada_bl_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct backlight_device *bd;
+
+ bd = backlight_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_bl_ops);
+
+ if (IS_ERR(bd)) {
+ ret = PTR_ERR(bd);
+ printk(KERN_ERR "bl : failed to register device, err=%x\n", ret);
+ return ret;
+ }
+
+ bd->props.power = FB_BLANK_UNBLANK;
+ bd->props.brightness = BL_DEF_BRIGHT;
+ /* note. make sure max brightness is set otherwise
+ you will get seemingly non-related errors when
+ trying to change brightness */
+ bd->props.max_brightness = BL_MAX_BRIGHT;
+ jornada_bl_update_status(bd);
+
+ platform_set_drvdata(pdev, bd);
+ printk(KERN_INFO "HP Jornada 700 series backlight driver\n");
+
+ return 0;
+}
+
+static int jornada_bl_remove(struct platform_device *pdev)
+{
+ struct backlight_device *bd = platform_get_drvdata(pdev);
+
+ backlight_device_unregister(bd);
+
+ return 0;
+}
+
+static struct platform_driver jornada_bl_driver = {
+ .probe = jornada_bl_probe,
+ .remove = jornada_bl_remove,
+ .driver = {
+ .name = "jornada_bl",
+ },
+};
+
+int __init jornada_bl_init(void)
+{
+ return platform_driver_register(&jornada_bl_driver);
+}
+
+void __exit jornada_bl_exit(void)
+{
+ platform_driver_unregister(&jornada_bl_driver);
+}
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 Backlight driver");
+MODULE_LICENSE("GPL");
+
+module_init(jornada_bl_init);
+module_exit(jornada_bl_exit);
diff --git a/drivers/video/backlight/jornada720_lcd.c b/drivers/video/backlight/jornada720_lcd.c
new file mode 100644
index 00000000000..cbbb167fd26
--- /dev/null
+++ b/drivers/video/backlight/jornada720_lcd.c
@@ -0,0 +1,153 @@
+/*
+ *
+ * LCD driver for HP Jornada 700 series (710/720/728)
+ * Copyright (C) 2006-2009 Kristoffer Ericson <kristoffer.ericson@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 or any later version as published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/lcd.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+
+#include <mach/jornada720.h>
+#include <mach/hardware.h>
+
+#include <video/s1d13xxxfb.h>
+
+#define LCD_MAX_CONTRAST 0xff
+#define LCD_DEF_CONTRAST 0x80
+
+static int jornada_lcd_get_power(struct lcd_device *dev)
+{
+ /* LDD2 in PPC = LCD POWER */
+ if (PPSR & PPC_LDD2)
+ return FB_BLANK_UNBLANK; /* PW ON */
+ else
+ return FB_BLANK_POWERDOWN; /* PW OFF */
+}
+
+static int jornada_lcd_get_contrast(struct lcd_device *dev)
+{
+ int ret;
+
+ if (jornada_lcd_get_power(dev) != FB_BLANK_UNBLANK)
+ return 0;
+
+ jornada_ssp_start();
+
+ if (jornada_ssp_byte(GETCONTRAST) != TXDUMMY) {
+ printk(KERN_ERR "lcd: get contrast failed\n");
+ jornada_ssp_end();
+ return -ETIMEDOUT;
+ } else {
+ ret = jornada_ssp_byte(TXDUMMY);
+ jornada_ssp_end();
+ return ret;
+ }
+}
+
+static int jornada_lcd_set_contrast(struct lcd_device *dev, int value)
+{
+ int ret;
+
+ jornada_ssp_start();
+
+ /* start by sending our set contrast cmd to mcu */
+ ret = jornada_ssp_byte(SETCONTRAST);
+
+ /* push the new value */
+ if (jornada_ssp_byte(value) != TXDUMMY) {
+ printk(KERN_ERR "lcd : set contrast failed\n");
+ jornada_ssp_end();
+ return -ETIMEDOUT;
+ }
+
+ /* if we get here we can assume everything went well */
+ jornada_ssp_end();
+
+ return 0;
+}
+
+static int jornada_lcd_set_power(struct lcd_device *dev, int power)
+{
+ if (power != FB_BLANK_UNBLANK) {
+ PPSR &= ~PPC_LDD2;
+ PPDR |= PPC_LDD2;
+ } else
+ PPSR |= PPC_LDD2;
+
+ return 0;
+}
+
+static struct lcd_ops jornada_lcd_props = {
+ .get_contrast = jornada_lcd_get_contrast,
+ .set_contrast = jornada_lcd_set_contrast,
+ .get_power = jornada_lcd_get_power,
+ .set_power = jornada_lcd_set_power,
+};
+
+static int jornada_lcd_probe(struct platform_device *pdev)
+{
+ struct lcd_device *lcd_device;
+ int ret;
+
+ lcd_device = lcd_device_register(S1D_DEVICENAME, &pdev->dev, NULL, &jornada_lcd_props);
+
+ if (IS_ERR(lcd_device)) {
+ ret = PTR_ERR(lcd_device);
+ printk(KERN_ERR "lcd : failed to register device\n");
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, lcd_device);
+
+ /* lets set our default values */
+ jornada_lcd_set_contrast(lcd_device, LCD_DEF_CONTRAST);
+ jornada_lcd_set_power(lcd_device, FB_BLANK_UNBLANK);
+ /* give it some time to startup */
+ msleep(100);
+
+ return 0;
+}
+
+static int jornada_lcd_remove(struct platform_device *pdev)
+{
+ struct lcd_device *lcd_device = platform_get_drvdata(pdev);
+
+ lcd_device_unregister(lcd_device);
+
+ return 0;
+}
+
+static struct platform_driver jornada_lcd_driver = {
+ .probe = jornada_lcd_probe,
+ .remove = jornada_lcd_remove,
+ .driver = {
+ .name = "jornada_lcd",
+ },
+};
+
+int __init jornada_lcd_init(void)
+{
+ return platform_driver_register(&jornada_lcd_driver);
+}
+
+void __exit jornada_lcd_exit(void)
+{
+ platform_driver_unregister(&jornada_lcd_driver);
+}
+
+MODULE_AUTHOR("Kristoffer Ericson <kristoffer.ericson@gmail.com>");
+MODULE_DESCRIPTION("HP Jornada 710/720/728 LCD driver");
+MODULE_LICENSE("GPL");
+
+module_init(jornada_lcd_init);
+module_exit(jornada_lcd_exit);
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c
index b6449470106..0bb13df0fa8 100644
--- a/drivers/video/backlight/lcd.c
+++ b/drivers/video/backlight/lcd.c
@@ -40,6 +40,8 @@ static int fb_notifier_callback(struct notifier_block *self,
if (!ld->ops)
return 0;
+ if (!lock_fb_info(evdata->info))
+ return -ENODEV;
mutex_lock(&ld->ops_lock);
if (!ld->ops->check_fb || ld->ops->check_fb(ld, evdata->info)) {
if (event == FB_EVENT_BLANK) {
@@ -51,6 +53,7 @@ static int fb_notifier_callback(struct notifier_block *self,
}
}
mutex_unlock(&ld->ops_lock);
+ unlock_fb_info(evdata->info);
return 0;
}
diff --git a/drivers/video/backlight/mbp_nvidia_bl.c b/drivers/video/backlight/mbp_nvidia_bl.c
index 65864c50045..3bb4c0a50c6 100644
--- a/drivers/video/backlight/mbp_nvidia_bl.c
+++ b/drivers/video/backlight/mbp_nvidia_bl.c
@@ -27,73 +27,192 @@
static struct backlight_device *mbp_backlight_device;
-static struct dmi_system_id __initdata mbp_device_table[] = {
+/* Structure to be passed to the DMI_MATCH function. */
+struct dmi_match_data {
+ /* I/O resource to allocate. */
+ unsigned long iostart;
+ unsigned long iolen;
+ /* Backlight operations structure. */
+ struct backlight_ops backlight_ops;
+};
+
+/* Module parameters. */
+static int debug;
+module_param_named(debug, debug, int, 0644);
+MODULE_PARM_DESC(debug, "Set to one to enable debugging messages.");
+
+/*
+ * Implementation for MacBooks with Intel chipset.
+ */
+static int intel_chipset_send_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+ intensity);
+
+ outb(0x04 | (intensity << 4), 0xb3);
+ outb(0xbf, 0xb2);
+ return 0;
+}
+
+static int intel_chipset_get_intensity(struct backlight_device *bd)
+{
+ int intensity;
+
+ outb(0x03, 0xb3);
+ outb(0xbf, 0xb2);
+ intensity = inb(0xb3) >> 4;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
+ intensity);
+
+ return intensity;
+}
+
+static const struct dmi_match_data intel_chipset_data = {
+ .iostart = 0xb2,
+ .iolen = 2,
+ .backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = intel_chipset_get_intensity,
+ .update_status = intel_chipset_send_intensity,
+ }
+};
+
+/*
+ * Implementation for MacBooks with Nvidia chipset.
+ */
+static int nvidia_chipset_send_intensity(struct backlight_device *bd)
+{
+ int intensity = bd->props.brightness;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: setting brightness to %d\n",
+ intensity);
+
+ outb(0x04 | (intensity << 4), 0x52f);
+ outb(0xbf, 0x52e);
+ return 0;
+}
+
+static int nvidia_chipset_get_intensity(struct backlight_device *bd)
+{
+ int intensity;
+
+ outb(0x03, 0x52f);
+ outb(0xbf, 0x52e);
+ intensity = inb(0x52f) >> 4;
+
+ if (debug)
+ printk(KERN_DEBUG "mbp_nvidia_bl: read brightness of %d\n",
+ intensity);
+
+ return intensity;
+}
+
+static const struct dmi_match_data nvidia_chipset_data = {
+ .iostart = 0x52e,
+ .iolen = 2,
+ .backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .get_brightness = nvidia_chipset_get_intensity,
+ .update_status = nvidia_chipset_send_intensity
+ }
+};
+
+/*
+ * DMI matching.
+ */
+static /* const */ struct dmi_match_data *driver_data;
+
+static int mbp_dmi_match(const struct dmi_system_id *id)
+{
+ driver_data = id->driver_data;
+
+ printk(KERN_INFO "mbp_nvidia_bl: %s detected\n", id->ident);
+ return 1;
+}
+
+static const struct dmi_system_id __initdata mbp_device_table[] = {
{
- .ident = "3,1",
- .matches = {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 3,1",
+ .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
},
+ .driver_data = (void *)&intel_chipset_data,
},
{
- .ident = "3,2",
- .matches = {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 3,2",
+ .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,2"),
},
+ .driver_data = (void *)&intel_chipset_data,
},
{
- .ident = "4,1",
- .matches = {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 4,1",
+ .matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro4,1"),
},
+ .driver_data = (void *)&intel_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBook 5,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5,1"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookAir 2,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookAir2,1"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
+ },
+ {
+ .callback = mbp_dmi_match,
+ .ident = "MacBookPro 5,1",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5,1"),
+ },
+ .driver_data = (void *)&nvidia_chipset_data,
},
{ }
};
-static int mbp_send_intensity(struct backlight_device *bd)
-{
- int intensity = bd->props.brightness;
-
- outb(0x04 | (intensity << 4), 0xb3);
- outb(0xbf, 0xb2);
-
- return 0;
-}
-
-static int mbp_get_intensity(struct backlight_device *bd)
-{
- outb(0x03, 0xb3);
- outb(0xbf, 0xb2);
- return inb(0xb3) >> 4;
-}
-
-static struct backlight_ops mbp_ops = {
- .options = BL_CORE_SUSPENDRESUME,
- .get_brightness = mbp_get_intensity,
- .update_status = mbp_send_intensity,
-};
-
static int __init mbp_init(void)
{
if (!dmi_check_system(mbp_device_table))
return -ENODEV;
- if (!request_region(0xb2, 2, "Macbook Pro backlight"))
+ if (!request_region(driver_data->iostart, driver_data->iolen,
+ "Macbook Pro backlight"))
return -ENXIO;
mbp_backlight_device = backlight_device_register("mbp_backlight",
- NULL, NULL,
- &mbp_ops);
+ NULL, NULL, &driver_data->backlight_ops);
if (IS_ERR(mbp_backlight_device)) {
- release_region(0xb2, 2);
+ release_region(driver_data->iostart, driver_data->iolen);
return PTR_ERR(mbp_backlight_device);
}
mbp_backlight_device->props.max_brightness = 15;
mbp_backlight_device->props.brightness =
- mbp_get_intensity(mbp_backlight_device);
+ driver_data->backlight_ops.get_brightness(mbp_backlight_device);
backlight_update_status(mbp_backlight_device);
return 0;
@@ -103,7 +222,7 @@ static void __exit mbp_exit(void)
{
backlight_device_unregister(mbp_backlight_device);
- release_region(0xb2, 2);
+ release_region(driver_data->iostart, driver_data->iolen);
}
module_init(mbp_init);
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index ea07258565f..e641584e212 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -3,7 +3,7 @@
*
* simple PWM based backlight control, board code has to setup
* 1) pin configuration so PWM waveforms can output
- * 2) platform_data casts to the PWM id (0/1/2/3 on PXA)
+ * 2) platform_data being correctly configured
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -97,7 +97,7 @@ static int pwm_backlight_probe(struct platform_device *pdev)
} else
dev_dbg(&pdev->dev, "got pwm for backlight\n");
- bl = backlight_device_register(pdev->name, &pdev->dev,
+ bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev,
pb, &pwm_backlight_ops);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index a2aa6ddffbe..d42e385f091 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -34,8 +34,6 @@
*
*/
-#define CIRRUSFB_VERSION "2.0-pre2"
-
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -72,20 +70,9 @@
*
*/
-/* enable debug output? */
-/* #define CIRRUSFB_DEBUG 1 */
-
/* disable runtime assertions? */
/* #define CIRRUSFB_NDEBUG */
-/* debug output */
-#ifdef CIRRUSFB_DEBUG
-#define DPRINTK(fmt, args...) \
- printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
-#else
-#define DPRINTK(fmt, args...)
-#endif
-
/* debugging assertions */
#ifndef CIRRUSFB_NDEBUG
#define assert(expr) \
@@ -108,14 +95,15 @@
/* board types */
enum cirrus_board {
BT_NONE = 0,
- BT_SD64,
- BT_PICCOLO,
- BT_PICASSO,
- BT_SPECTRUM,
+ BT_SD64, /* GD5434 */
+ BT_PICCOLO, /* GD5426 */
+ BT_PICASSO, /* GD5426 or GD5428 */
+ BT_SPECTRUM, /* GD5426 or GD5428 */
BT_PICASSO4, /* GD5446 */
BT_ALPINE, /* GD543x/4x */
BT_GD5480,
- BT_LAGUNA, /* GD546x */
+ BT_LAGUNA, /* GD5462/64 */
+ BT_LAGUNAB, /* GD5465 */
};
/*
@@ -150,15 +138,17 @@ static const struct cirrusfb_board_info_rec {
.maxclock = {
/* guess */
/* the SD64/P4 have a higher max. videoclock */
- 140000, 140000, 140000, 140000, 140000,
+ 135100, 135100, 85500, 85500, 0
},
.init_sr07 = true,
.init_sr1f = true,
.scrn_start_bit19 = true,
.sr07 = 0xF0,
.sr07_1bpp = 0xF0,
+ .sr07_1bpp_mux = 0xF6,
.sr07_8bpp = 0xF1,
- .sr1f = 0x20
+ .sr07_8bpp_mux = 0xF7,
+ .sr1f = 0x1E
},
[BT_PICCOLO] = {
.name = "CL Piccolo",
@@ -210,9 +200,11 @@ static const struct cirrusfb_board_info_rec {
.init_sr07 = true,
.init_sr1f = false,
.scrn_start_bit19 = true,
- .sr07 = 0x20,
- .sr07_1bpp = 0x20,
- .sr07_8bpp = 0x21,
+ .sr07 = 0xA0,
+ .sr07_1bpp = 0xA0,
+ .sr07_1bpp_mux = 0xA6,
+ .sr07_8bpp = 0xA1,
+ .sr07_8bpp_mux = 0xA7,
.sr1f = 0
},
[BT_ALPINE] = {
@@ -225,8 +217,8 @@ static const struct cirrusfb_board_info_rec {
.init_sr1f = true,
.scrn_start_bit19 = true,
.sr07 = 0xA0,
- .sr07_1bpp = 0xA1,
- .sr07_1bpp_mux = 0xA7,
+ .sr07_1bpp = 0xA0,
+ .sr07_1bpp_mux = 0xA6,
.sr07_8bpp = 0xA1,
.sr07_8bpp_mux = 0xA7,
.sr1f = 0x1C
@@ -247,8 +239,18 @@ static const struct cirrusfb_board_info_rec {
[BT_LAGUNA] = {
.name = "CL Laguna",
.maxclock = {
- /* guess */
- 135100, 135100, 135100, 135100, 135100,
+ /* taken from X11 code */
+ 170000, 170000, 170000, 170000, 135100,
+ },
+ .init_sr07 = false,
+ .init_sr1f = false,
+ .scrn_start_bit19 = true,
+ },
+ [BT_LAGUNAB] = {
+ .name = "CL Laguna AGP",
+ .maxclock = {
+ /* taken from X11 code */
+ 170000, 250000, 170000, 170000, 135100,
},
.init_sr07 = false,
.init_sr1f = false,
@@ -262,8 +264,8 @@ static const struct cirrusfb_board_info_rec {
static struct pci_device_id cirrusfb_pci_table[] = {
CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
- CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE),
- CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE),
+ CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_SD64),
+ CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_SD64),
CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
@@ -271,7 +273,7 @@ static struct pci_device_id cirrusfb_pci_table[] = {
CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
- CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/
+ CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNAB), /* CL Laguna 3DA*/
{ 0, }
};
MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
@@ -326,10 +328,6 @@ static const struct {
};
#endif /* CONFIG_ZORRO */
-struct cirrusfb_regs {
- int multiplexing;
-};
-
#ifdef CIRRUSFB_DEBUG
enum cirrusfb_dbg_reg_class {
CRT,
@@ -340,10 +338,12 @@ enum cirrusfb_dbg_reg_class {
/* info about board */
struct cirrusfb_info {
u8 __iomem *regbase;
+ u8 __iomem *laguna_mmio;
enum cirrus_board btype;
unsigned char SFR; /* Shadow of special function register */
- struct cirrusfb_regs currentmode;
+ int multiplexing;
+ int doubleVCLK;
int blank_mode;
u32 pseudo_palette[16];
@@ -357,43 +357,8 @@ static char *mode_option __devinitdata = "640x480@60";
/**** BEGIN PROTOTYPES ******************************************************/
/*--- Interface used by the world ------------------------------------------*/
-static int cirrusfb_init(void);
-#ifndef MODULE
-static int cirrusfb_setup(char *options);
-#endif
-
-static int cirrusfb_open(struct fb_info *info, int user);
-static int cirrusfb_release(struct fb_info *info, int user);
-static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info);
-static int cirrusfb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int cirrusfb_set_par(struct fb_info *info);
static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
-static int cirrusfb_blank(int blank_mode, struct fb_info *info);
-static void cirrusfb_fillrect(struct fb_info *info,
- const struct fb_fillrect *region);
-static void cirrusfb_copyarea(struct fb_info *info,
- const struct fb_copyarea *area);
-static void cirrusfb_imageblit(struct fb_info *info,
- const struct fb_image *image);
-
-/* function table of the above functions */
-static struct fb_ops cirrusfb_ops = {
- .owner = THIS_MODULE,
- .fb_open = cirrusfb_open,
- .fb_release = cirrusfb_release,
- .fb_setcolreg = cirrusfb_setcolreg,
- .fb_check_var = cirrusfb_check_var,
- .fb_set_par = cirrusfb_set_par,
- .fb_pan_display = cirrusfb_pan_display,
- .fb_blank = cirrusfb_blank,
- .fb_fillrect = cirrusfb_fillrect,
- .fb_copyarea = cirrusfb_copyarea,
- .fb_imageblit = cirrusfb_imageblit,
-};
/*--- Internal routines ----------------------------------------------------*/
static void init_vgachip(struct fb_info *info);
@@ -421,22 +386,27 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
u_short x, u_short y,
u_short width, u_short height,
- u_char color, u_short line_length);
+ u32 fg_color, u32 bg_color,
+ u_short line_length, u_char blitmode);
static void bestclock(long freq, int *nom, int *den, int *div);
#ifdef CIRRUSFB_DEBUG
-static void cirrusfb_dump(void);
-static void cirrusfb_dbg_reg_dump(caddr_t regbase);
-static void cirrusfb_dbg_print_regs(caddr_t regbase,
+static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase);
+static void cirrusfb_dbg_print_regs(struct fb_info *info,
+ caddr_t regbase,
enum cirrusfb_dbg_reg_class reg_class, ...);
-static void cirrusfb_dbg_print_byte(const char *name, unsigned char val);
#endif /* CIRRUSFB_DEBUG */
/*** END PROTOTYPES ********************************************************/
/*****************************************************************************/
/*** BEGIN Interface Used by the World ***************************************/
+static inline int is_laguna(const struct cirrusfb_info *cinfo)
+{
+ return cinfo->btype == BT_LAGUNA || cinfo->btype == BT_LAGUNAB;
+}
+
static int opencount;
/*--- Open /dev/fbx ---------------------------------------------------------*/
@@ -460,85 +430,94 @@ static int cirrusfb_release(struct fb_info *info, int user)
/**** BEGIN Hardware specific Routines **************************************/
/* Check if the MCLK is not a better clock source */
-static int cirrusfb_check_mclk(struct cirrusfb_info *cinfo, long freq)
+static int cirrusfb_check_mclk(struct fb_info *info, long freq)
{
+ struct cirrusfb_info *cinfo = info->par;
long mclk = vga_rseq(cinfo->regbase, CL_SEQR1F) & 0x3f;
/* Read MCLK value */
mclk = (14318 * mclk) >> 3;
- DPRINTK("Read MCLK of %ld kHz\n", mclk);
+ dev_dbg(info->device, "Read MCLK of %ld kHz\n", mclk);
/* Determine if we should use MCLK instead of VCLK, and if so, what we
* should divide it by to get VCLK
*/
if (abs(freq - mclk) < 250) {
- DPRINTK("Using VCLK = MCLK\n");
+ dev_dbg(info->device, "Using VCLK = MCLK\n");
return 1;
} else if (abs(freq - (mclk / 2)) < 250) {
- DPRINTK("Using VCLK = MCLK/2\n");
+ dev_dbg(info->device, "Using VCLK = MCLK/2\n");
return 2;
}
return 0;
}
-static int cirrusfb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info)
+static int cirrusfb_check_pixclock(const struct fb_var_screeninfo *var,
+ struct fb_info *info)
{
- int yres;
- /* memory size in pixels */
- unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
+ long freq;
+ long maxclock;
+ struct cirrusfb_info *cinfo = info->par;
+ unsigned maxclockidx = var->bits_per_pixel >> 3;
- switch (var->bits_per_pixel) {
- case 1:
- pixels /= 4;
- break; /* 8 pixel per byte, only 1/4th of mem usable */
- case 8:
- case 16:
- case 32:
- break; /* 1 pixel == 1 byte */
- default:
- printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
- "color depth not supported.\n",
- var->xres, var->yres, var->bits_per_pixel);
- DPRINTK("EXIT - EINVAL error\n");
- return -EINVAL;
- }
+ /* convert from ps to kHz */
+ freq = PICOS2KHZ(var->pixclock);
- if (var->xres_virtual < var->xres)
- var->xres_virtual = var->xres;
- /* use highest possible virtual resolution */
- if (var->yres_virtual == -1) {
- var->yres_virtual = pixels / var->xres_virtual;
+ dev_dbg(info->device, "desired pixclock: %ld kHz\n", freq);
- printk(KERN_INFO "cirrusfb: virtual resolution set to "
- "maximum of %dx%d\n", var->xres_virtual,
- var->yres_virtual);
- }
- if (var->yres_virtual < var->yres)
- var->yres_virtual = var->yres;
+ maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
+ cinfo->multiplexing = 0;
- if (var->xres_virtual * var->yres_virtual > pixels) {
- printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected... "
- "virtual resolution too high to fit into video memory!\n",
- var->xres_virtual, var->yres_virtual,
- var->bits_per_pixel);
- DPRINTK("EXIT - EINVAL error\n");
+ /* If the frequency is greater than we can support, we might be able
+ * to use multiplexing for the video mode */
+ if (freq > maxclock) {
+ dev_err(info->device,
+ "Frequency greater than maxclock (%ld kHz)\n",
+ maxclock);
return -EINVAL;
}
+ /*
+ * Additional constraint: 8bpp uses DAC clock doubling to allow maximum
+ * pixel clock
+ */
+ if (var->bits_per_pixel == 8) {
+ switch (cinfo->btype) {
+ case BT_ALPINE:
+ case BT_SD64:
+ case BT_PICASSO4:
+ if (freq > 85500)
+ cinfo->multiplexing = 1;
+ break;
+ case BT_GD5480:
+ if (freq > 135100)
+ cinfo->multiplexing = 1;
+ break;
+ default:
+ break;
+ }
+ }
- if (var->xoffset < 0)
- var->xoffset = 0;
- if (var->yoffset < 0)
- var->yoffset = 0;
+ /* If we have a 1MB 5434, we need to put ourselves in a mode where
+ * the VCLK is double the pixel clock. */
+ cinfo->doubleVCLK = 0;
+ if (cinfo->btype == BT_SD64 && info->fix.smem_len <= MB_ &&
+ var->bits_per_pixel == 16) {
+ cinfo->doubleVCLK = 1;
+ }
- /* truncate xoffset and yoffset to maximum if too high */
- if (var->xoffset > var->xres_virtual - var->xres)
- var->xoffset = var->xres_virtual - var->xres - 1;
- if (var->yoffset > var->yres_virtual - var->yres)
- var->yoffset = var->yres_virtual - var->yres - 1;
+ return 0;
+}
+
+static int cirrusfb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ int yres;
+ /* memory size in pixels */
+ unsigned pixels = info->screen_size * 8 / var->bits_per_pixel;
+ struct cirrusfb_info *cinfo = info->par;
switch (var->bits_per_pixel) {
case 1:
@@ -550,7 +529,7 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
case 8:
var->red.offset = 0;
- var->red.length = 6;
+ var->red.length = 8;
var->green = var->red;
var->blue = var->red;
break;
@@ -561,20 +540,20 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
var->green.offset = -3;
var->blue.offset = 8;
} else {
- var->red.offset = 10;
+ var->red.offset = 11;
var->green.offset = 5;
var->blue.offset = 0;
}
var->red.length = 5;
- var->green.length = 5;
+ var->green.length = 6;
var->blue.length = 5;
break;
- case 32:
+ case 24:
if (isPReP) {
- var->red.offset = 8;
- var->green.offset = 16;
- var->blue.offset = 24;
+ var->red.offset = 0;
+ var->green.offset = 8;
+ var->blue.offset = 16;
} else {
var->red.offset = 16;
var->green.offset = 8;
@@ -586,12 +565,45 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
break;
default:
- DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
+ dev_dbg(info->device,
+ "Unsupported bpp size: %d\n", var->bits_per_pixel);
assert(false);
/* should never occur */
break;
}
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ /* use highest possible virtual resolution */
+ if (var->yres_virtual == -1) {
+ var->yres_virtual = pixels / var->xres_virtual;
+
+ dev_info(info->device,
+ "virtual resolution set to maximum of %dx%d\n",
+ var->xres_virtual, var->yres_virtual);
+ }
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+
+ if (var->xres_virtual * var->yres_virtual > pixels) {
+ dev_err(info->device, "mode %dx%dx%d rejected... "
+ "virtual resolution too high to fit into video memory!\n",
+ var->xres_virtual, var->yres_virtual,
+ var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ if (var->xoffset < 0)
+ var->xoffset = 0;
+ if (var->yoffset < 0)
+ var->yoffset = 0;
+
+ /* truncate xoffset and yoffset to maximum if too high */
+ if (var->xoffset > var->xres_virtual - var->xres)
+ var->xoffset = var->xres_virtual - var->xres - 1;
+ if (var->yoffset > var->yres_virtual - var->yres)
+ var->yoffset = var->yres_virtual - var->yres - 1;
+
var->red.msb_right =
var->green.msb_right =
var->blue.msb_right =
@@ -606,99 +618,31 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
yres = (yres + 1) / 2;
if (yres >= 1280) {
- printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; "
+ dev_err(info->device, "ERROR: VerticalTotal >= 1280; "
"special treatment required! (TODO)\n");
- DPRINTK("EXIT - EINVAL error\n");
return -EINVAL;
}
- return 0;
-}
-
-static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
- struct cirrusfb_regs *regs,
- struct fb_info *info)
-{
- long freq;
- long maxclock;
- int maxclockidx = var->bits_per_pixel >> 3;
- struct cirrusfb_info *cinfo = info->par;
-
- switch (var->bits_per_pixel) {
- case 1:
- info->fix.line_length = var->xres_virtual / 8;
- info->fix.visual = FB_VISUAL_MONO10;
- break;
-
- case 8:
- info->fix.line_length = var->xres_virtual;
- info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
- break;
-
- case 16:
- case 32:
- info->fix.line_length = var->xres_virtual * maxclockidx;
- info->fix.visual = FB_VISUAL_TRUECOLOR;
- break;
-
- default:
- DPRINTK("Unsupported bpp size: %d\n", var->bits_per_pixel);
- assert(false);
- /* should never occur */
- break;
- }
-
- info->fix.type = FB_TYPE_PACKED_PIXELS;
-
- /* convert from ps to kHz */
- freq = PICOS2KHZ(var->pixclock);
-
- DPRINTK("desired pixclock: %ld kHz\n", freq);
-
- maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
- regs->multiplexing = 0;
+ if (cirrusfb_check_pixclock(var, info))
+ return -EINVAL;
- /* If the frequency is greater than we can support, we might be able
- * to use multiplexing for the video mode */
- if (freq > maxclock) {
- switch (cinfo->btype) {
- case BT_ALPINE:
- case BT_GD5480:
- regs->multiplexing = 1;
- break;
+ if (!is_laguna(cinfo))
+ var->accel_flags = FB_ACCELF_TEXT;
- default:
- printk(KERN_ERR "cirrusfb: Frequency greater "
- "than maxclock (%ld kHz)\n", maxclock);
- DPRINTK("EXIT - return -EINVAL\n");
- return -EINVAL;
- }
- }
-#if 0
- /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
- * the VCLK is double the pixel clock. */
- switch (var->bits_per_pixel) {
- case 16:
- case 32:
- if (var->xres <= 800)
- /* Xbh has this type of clock for 32-bit */
- freq /= 2;
- break;
- }
-#endif
return 0;
}
-static void cirrusfb_set_mclk_as_source(const struct cirrusfb_info *cinfo,
- int div)
+static void cirrusfb_set_mclk_as_source(const struct fb_info *info, int div)
{
+ struct cirrusfb_info *cinfo = info->par;
unsigned char old1f, old1e;
+
assert(cinfo != NULL);
old1f = vga_rseq(cinfo->regbase, CL_SEQR1F) & ~0x40;
if (div) {
- DPRINTK("Set %s as pixclock source.\n",
- (div == 2) ? "MCLK/2" : "MCLK");
+ dev_dbg(info->device, "Set %s as pixclock source.\n",
+ (div == 2) ? "MCLK/2" : "MCLK");
old1f |= 0x40;
old1e = vga_rseq(cinfo->regbase, CL_SEQR1E) & ~0x1;
if (div == 2)
@@ -718,101 +662,119 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
struct fb_var_screeninfo *var = &info->var;
- struct cirrusfb_regs regs;
u8 __iomem *regbase = cinfo->regbase;
unsigned char tmp;
- int offset = 0, err;
+ int pitch;
const struct cirrusfb_board_info_rec *bi;
int hdispend, hsyncstart, hsyncend, htotal;
int yres, vdispend, vsyncstart, vsyncend, vtotal;
long freq;
int nom, den, div;
+ unsigned int control = 0, format = 0, threshold = 0;
- DPRINTK("ENTER\n");
- DPRINTK("Requested mode: %dx%dx%d\n",
+ dev_dbg(info->device, "Requested mode: %dx%dx%d\n",
var->xres, var->yres, var->bits_per_pixel);
- DPRINTK("pixclock: %d\n", var->pixclock);
- init_vgachip(info);
+ switch (var->bits_per_pixel) {
+ case 1:
+ info->fix.line_length = var->xres_virtual / 8;
+ info->fix.visual = FB_VISUAL_MONO10;
+ break;
- err = cirrusfb_decode_var(var, &regs, info);
- if (err) {
- /* should never happen */
- DPRINTK("mode change aborted. invalid var.\n");
- return -EINVAL;
+ case 8:
+ info->fix.line_length = var->xres_virtual;
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ break;
+
+ case 16:
+ case 24:
+ info->fix.line_length = var->xres_virtual *
+ var->bits_per_pixel >> 3;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
}
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+
+ init_vgachip(info);
bi = &cirrusfb_board_info[cinfo->btype];
hsyncstart = var->xres + var->right_margin;
hsyncend = hsyncstart + var->hsync_len;
- htotal = (hsyncend + var->left_margin) / 8 - 5;
- hdispend = var->xres / 8 - 1;
- hsyncstart = hsyncstart / 8 + 1;
- hsyncend = hsyncend / 8 + 1;
+ htotal = (hsyncend + var->left_margin) / 8;
+ hdispend = var->xres / 8;
+ hsyncstart = hsyncstart / 8;
+ hsyncend = hsyncend / 8;
- yres = var->yres;
- vsyncstart = yres + var->lower_margin;
+ vdispend = var->yres;
+ vsyncstart = vdispend + var->lower_margin;
vsyncend = vsyncstart + var->vsync_len;
vtotal = vsyncend + var->upper_margin;
- vdispend = yres - 1;
if (var->vmode & FB_VMODE_DOUBLE) {
- yres *= 2;
+ vdispend *= 2;
vsyncstart *= 2;
vsyncend *= 2;
vtotal *= 2;
} else if (var->vmode & FB_VMODE_INTERLACED) {
- yres = (yres + 1) / 2;
+ vdispend = (vdispend + 1) / 2;
vsyncstart = (vsyncstart + 1) / 2;
vsyncend = (vsyncend + 1) / 2;
vtotal = (vtotal + 1) / 2;
}
-
- vtotal -= 2;
- vsyncstart -= 1;
- vsyncend -= 1;
-
+ yres = vdispend;
if (yres >= 1024) {
vtotal /= 2;
vsyncstart /= 2;
vsyncend /= 2;
vdispend /= 2;
}
- if (regs.multiplexing) {
+
+ vdispend -= 1;
+ vsyncstart -= 1;
+ vsyncend -= 1;
+ vtotal -= 2;
+
+ if (cinfo->multiplexing) {
htotal /= 2;
hsyncstart /= 2;
hsyncend /= 2;
hdispend /= 2;
}
+
+ htotal -= 5;
+ hdispend -= 1;
+ hsyncstart += 1;
+ hsyncend += 1;
+
/* unlock register VGA_CRTC_H_TOTAL..CRT7 */
vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
/* if debugging is enabled, all parameters get output before writing */
- DPRINTK("CRT0: %d\n", htotal);
+ dev_dbg(info->device, "CRT0: %d\n", htotal);
vga_wcrt(regbase, VGA_CRTC_H_TOTAL, htotal);
- DPRINTK("CRT1: %d\n", hdispend);
+ dev_dbg(info->device, "CRT1: %d\n", hdispend);
vga_wcrt(regbase, VGA_CRTC_H_DISP, hdispend);
- DPRINTK("CRT2: %d\n", var->xres / 8);
+ dev_dbg(info->device, "CRT2: %d\n", var->xres / 8);
vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, var->xres / 8);
/* + 128: Compatible read */
- DPRINTK("CRT3: 128+%d\n", (htotal + 5) % 32);
+ dev_dbg(info->device, "CRT3: 128+%d\n", (htotal + 5) % 32);
vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
128 + ((htotal + 5) % 32));
- DPRINTK("CRT4: %d\n", hsyncstart);
+ dev_dbg(info->device, "CRT4: %d\n", hsyncstart);
vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, hsyncstart);
tmp = hsyncend % 32;
if ((htotal + 5) & 32)
tmp += 128;
- DPRINTK("CRT5: %d\n", tmp);
+ dev_dbg(info->device, "CRT5: %d\n", tmp);
vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
- DPRINTK("CRT6: %d\n", vtotal & 0xff);
+ dev_dbg(info->device, "CRT6: %d\n", vtotal & 0xff);
vga_wcrt(regbase, VGA_CRTC_V_TOTAL, vtotal & 0xff);
tmp = 16; /* LineCompare bit #9 */
@@ -830,7 +792,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
tmp |= 64;
if (vsyncstart & 512)
tmp |= 128;
- DPRINTK("CRT7: %d\n", tmp);
+ dev_dbg(info->device, "CRT7: %d\n", tmp);
vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
tmp = 0x40; /* LineCompare bit #8 */
@@ -838,25 +800,25 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
tmp |= 0x20;
if (var->vmode & FB_VMODE_DOUBLE)
tmp |= 0x80;
- DPRINTK("CRT9: %d\n", tmp);
+ dev_dbg(info->device, "CRT9: %d\n", tmp);
vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
- DPRINTK("CRT10: %d\n", vsyncstart & 0xff);
+ dev_dbg(info->device, "CRT10: %d\n", vsyncstart & 0xff);
vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, vsyncstart & 0xff);
- DPRINTK("CRT11: 64+32+%d\n", vsyncend % 16);
+ dev_dbg(info->device, "CRT11: 64+32+%d\n", vsyncend % 16);
vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, vsyncend % 16 + 64 + 32);
- DPRINTK("CRT12: %d\n", vdispend & 0xff);
+ dev_dbg(info->device, "CRT12: %d\n", vdispend & 0xff);
vga_wcrt(regbase, VGA_CRTC_V_DISP_END, vdispend & 0xff);
- DPRINTK("CRT15: %d\n", (vdispend + 1) & 0xff);
+ dev_dbg(info->device, "CRT15: %d\n", (vdispend + 1) & 0xff);
vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, (vdispend + 1) & 0xff);
- DPRINTK("CRT16: %d\n", vtotal & 0xff);
+ dev_dbg(info->device, "CRT16: %d\n", vtotal & 0xff);
vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, vtotal & 0xff);
- DPRINTK("CRT18: 0xff\n");
+ dev_dbg(info->device, "CRT18: 0xff\n");
vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
tmp = 0;
@@ -871,41 +833,75 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
if (vtotal & 512)
tmp |= 128;
- DPRINTK("CRT1a: %d\n", tmp);
+ dev_dbg(info->device, "CRT1a: %d\n", tmp);
vga_wcrt(regbase, CL_CRT1A, tmp);
freq = PICOS2KHZ(var->pixclock);
+ if (var->bits_per_pixel == 24)
+ if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64)
+ freq *= 3;
+ if (cinfo->multiplexing)
+ freq /= 2;
+ if (cinfo->doubleVCLK)
+ freq *= 2;
+
bestclock(freq, &nom, &den, &div);
+ dev_dbg(info->device, "VCLK freq: %ld kHz nom: %d den: %d div: %d\n",
+ freq, nom, den, div);
+
/* set VCLK0 */
/* hardware RefClock: 14.31818 MHz */
/* formula: VClk = (OSC * N) / (D * (1+P)) */
/* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
- if (cinfo->btype == BT_ALPINE) {
+ if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4 ||
+ cinfo->btype == BT_SD64) {
/* if freq is close to mclk or mclk/2 select mclk
* as clock source
*/
- int divMCLK = cirrusfb_check_mclk(cinfo, freq);
- if (divMCLK) {
+ int divMCLK = cirrusfb_check_mclk(info, freq);
+ if (divMCLK)
nom = 0;
- cirrusfb_set_mclk_as_source(cinfo, divMCLK);
+ cirrusfb_set_mclk_as_source(info, divMCLK);
+ }
+ if (is_laguna(cinfo)) {
+ long pcifc = fb_readl(cinfo->laguna_mmio + 0x3fc);
+ unsigned char tile = fb_readb(cinfo->laguna_mmio + 0x407);
+ unsigned short tile_control;
+
+ if (cinfo->btype == BT_LAGUNAB) {
+ tile_control = fb_readw(cinfo->laguna_mmio + 0x2c4);
+ tile_control &= ~0x80;
+ fb_writew(tile_control, cinfo->laguna_mmio + 0x2c4);
}
+
+ fb_writel(pcifc | 0x10000000l, cinfo->laguna_mmio + 0x3fc);
+ fb_writeb(tile & 0x3f, cinfo->laguna_mmio + 0x407);
+ control = fb_readw(cinfo->laguna_mmio + 0x402);
+ threshold = fb_readw(cinfo->laguna_mmio + 0xea);
+ control &= ~0x6800;
+ format = 0;
+ threshold &= 0xffc0 & 0x3fbf;
}
if (nom) {
- vga_wseq(regbase, CL_SEQRB, nom);
tmp = den << 1;
if (div != 0)
tmp |= 1;
-
/* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
if ((cinfo->btype == BT_SD64) ||
(cinfo->btype == BT_ALPINE) ||
(cinfo->btype == BT_GD5480))
tmp |= 0x80;
- DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
- vga_wseq(regbase, CL_SEQR1B, tmp);
+ /* Laguna chipset has reversed clock registers */
+ if (is_laguna(cinfo)) {
+ vga_wseq(regbase, CL_SEQRE, tmp);
+ vga_wseq(regbase, CL_SEQR1E, nom);
+ } else {
+ vga_wseq(regbase, CL_SEQRE, nom);
+ vga_wseq(regbase, CL_SEQR1E, tmp);
+ }
}
if (yres >= 1024)
@@ -916,9 +912,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
* address wrap, no compat. */
vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
-/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
- * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
-
/* don't know if it would hurt to also program this if no interlaced */
/* mode is used, but I feel better this way.. :-) */
if (var->vmode & FB_VMODE_INTERLACED)
@@ -926,19 +919,15 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
else
vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
- vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
-
- /* adjust horizontal/vertical sync type (low/high) */
+ /* adjust horizontal/vertical sync type (low/high), use VCLK3 */
/* enable display memory & CRTC I/O address for color mode */
- tmp = 0x03;
+ tmp = 0x03 | 0xc;
if (var->sync & FB_SYNC_HOR_HIGH_ACT)
tmp |= 0x40;
if (var->sync & FB_SYNC_VERT_HIGH_ACT)
tmp |= 0x80;
WGen(cinfo, VGA_MIS_W, tmp);
- /* Screen A Preset Row-Scan register */
- vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
/* text cursor on and start line */
vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
/* text cursor end line */
@@ -952,7 +941,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
/* programming for different color depths */
if (var->bits_per_pixel == 1) {
- DPRINTK("cirrusfb: preparing for 1 bit deep display\n");
+ dev_dbg(info->device, "preparing for 1 bit deep display\n");
vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
/* SR07 */
@@ -964,68 +953,53 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_PICASSO4:
case BT_ALPINE:
case BT_GD5480:
- DPRINTK(" (for GD54xx)\n");
vga_wseq(regbase, CL_SEQR7,
- regs.multiplexing ?
+ cinfo->multiplexing ?
bi->sr07_1bpp_mux : bi->sr07_1bpp);
break;
case BT_LAGUNA:
- DPRINTK(" (for GD546x)\n");
+ case BT_LAGUNAB:
vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) & ~0x01);
break;
default:
- printk(KERN_WARNING "cirrusfb: unknown Board\n");
+ dev_warn(info->device, "unknown Board\n");
break;
}
/* Extended Sequencer Mode */
switch (cinfo->btype) {
- case BT_SD64:
- /* setting the SEQRF on SD64 is not necessary
- * (only during init)
- */
- DPRINTK("(for SD64)\n");
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x1a);
- break;
case BT_PICCOLO:
case BT_SPECTRUM:
- DPRINTK("(for Piccolo/Spectrum)\n");
- /* ### ueberall 0x22? */
- /* ##vorher 1c MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x22);
/* evtl d0 bei 1 bit? avoid FIFO underruns..? */
vga_wseq(regbase, CL_SEQRF, 0xb0);
break;
case BT_PICASSO:
- DPRINTK("(for Picasso)\n");
- /* ##vorher 22 MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x22);
/* ## vorher d0 avoid FIFO underruns..? */
vga_wseq(regbase, CL_SEQRF, 0xd0);
break;
+ case BT_SD64:
case BT_PICASSO4:
case BT_ALPINE:
case BT_GD5480:
case BT_LAGUNA:
- DPRINTK(" (for GD54xx)\n");
+ case BT_LAGUNAB:
/* do nothing */
break;
default:
- printk(KERN_WARNING "cirrusfb: unknown Board\n");
+ dev_warn(info->device, "unknown Board\n");
break;
}
/* pixel mask: pass-through for first plane */
WGen(cinfo, VGA_PEL_MSK, 0x01);
- if (regs.multiplexing)
+ if (cinfo->multiplexing)
/* hidden dac reg: 1280x1024 */
WHDR(cinfo, 0x4a);
else
@@ -1035,7 +1009,6 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
/* plane mask: only write to first plane */
vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
- offset = var->xres_virtual / 16;
}
/******************************************************
@@ -1045,7 +1018,7 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
*/
else if (var->bits_per_pixel == 8) {
- DPRINTK("cirrusfb: preparing for 8 bit deep display\n");
+ dev_dbg(info->device, "preparing for 8 bit deep display\n");
switch (cinfo->btype) {
case BT_SD64:
case BT_PICCOLO:
@@ -1054,34 +1027,27 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
case BT_PICASSO4:
case BT_ALPINE:
case BT_GD5480:
- DPRINTK(" (for GD54xx)\n");
vga_wseq(regbase, CL_SEQR7,
- regs.multiplexing ?
+ cinfo->multiplexing ?
bi->sr07_8bpp_mux : bi->sr07_8bpp);
break;
case BT_LAGUNA:
- DPRINTK(" (for GD546x)\n");
+ case BT_LAGUNAB:
vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) | 0x01);
+ threshold |= 0x10;
break;
default:
- printk(KERN_WARNING "cirrusfb: unknown Board\n");
+ dev_warn(info->device, "unknown Board\n");
break;
}
switch (cinfo->btype) {
- case BT_SD64:
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x1d);
- break;
-
case BT_PICCOLO:
case BT_PICASSO:
case BT_SPECTRUM:
- /* ### vorher 1c MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x22);
/* Fast Page-Mode writes */
vga_wseq(regbase, CL_SEQRF, 0xb0);
break;
@@ -1091,40 +1057,27 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
/* ### INCOMPLETE!! */
vga_wseq(regbase, CL_SEQRF, 0xb8);
#endif
-/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
- break;
-
case BT_ALPINE:
- DPRINTK(" (for GD543x)\n");
- /* We already set SRF and SR1F */
- break;
-
+ case BT_SD64:
case BT_GD5480:
case BT_LAGUNA:
- DPRINTK(" (for GD54xx)\n");
+ case BT_LAGUNAB:
/* do nothing */
break;
default:
- printk(KERN_WARNING "cirrusfb: unknown Board\n");
+ dev_warn(info->device, "unknown board\n");
break;
}
/* mode register: 256 color mode */
vga_wgfx(regbase, VGA_GFX_MODE, 64);
- /* pixel mask: pass-through all planes */
- WGen(cinfo, VGA_PEL_MSK, 0xff);
- if (regs.multiplexing)
+ if (cinfo->multiplexing)
/* hidden dac reg: 1280x1024 */
WHDR(cinfo, 0x4a);
else
/* hidden dac: nothing */
WHDR(cinfo, 0);
- /* memory mode: chain4, ext. memory */
- vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
- /* plane mask: enable writing to all 4 planes */
- vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
- offset = var->xres_virtual / 8;
}
/******************************************************
@@ -1134,147 +1087,110 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
*/
else if (var->bits_per_pixel == 16) {
- DPRINTK("cirrusfb: preparing for 16 bit deep display\n");
+ dev_dbg(info->device, "preparing for 16 bit deep display\n");
switch (cinfo->btype) {
- case BT_SD64:
- /* Extended Sequencer Mode: 256c col. mode */
- vga_wseq(regbase, CL_SEQR7, 0xf7);
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x1e);
- break;
-
case BT_PICCOLO:
case BT_SPECTRUM:
vga_wseq(regbase, CL_SEQR7, 0x87);
/* Fast Page-Mode writes */
vga_wseq(regbase, CL_SEQRF, 0xb0);
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
case BT_PICASSO:
vga_wseq(regbase, CL_SEQR7, 0x27);
/* Fast Page-Mode writes */
vga_wseq(regbase, CL_SEQRF, 0xb0);
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
+ case BT_SD64:
case BT_PICASSO4:
- vga_wseq(regbase, CL_SEQR7, 0x27);
-/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
- break;
-
case BT_ALPINE:
- DPRINTK(" (for GD543x)\n");
- vga_wseq(regbase, CL_SEQR7, 0xa7);
+ /* Extended Sequencer Mode: 256c col. mode */
+ vga_wseq(regbase, CL_SEQR7,
+ cinfo->doubleVCLK ? 0xa3 : 0xa7);
break;
case BT_GD5480:
- DPRINTK(" (for GD5480)\n");
vga_wseq(regbase, CL_SEQR7, 0x17);
/* We already set SRF and SR1F */
break;
case BT_LAGUNA:
- DPRINTK(" (for GD546x)\n");
+ case BT_LAGUNAB:
vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) & ~0x01);
+ control |= 0x2000;
+ format |= 0x1400;
+ threshold |= 0x10;
break;
default:
- printk(KERN_WARNING "CIRRUSFB: unknown Board\n");
+ dev_warn(info->device, "unknown Board\n");
break;
}
/* mode register: 256 color mode */
vga_wgfx(regbase, VGA_GFX_MODE, 64);
- /* pixel mask: pass-through all planes */
- WGen(cinfo, VGA_PEL_MSK, 0xff);
#ifdef CONFIG_PCI
- WHDR(cinfo, 0xc0); /* Copy Xbh */
+ WHDR(cinfo, cinfo->doubleVCLK ? 0xe1 : 0xc1);
#elif defined(CONFIG_ZORRO)
/* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
#endif
- /* memory mode: chain4, ext. memory */
- vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
- /* plane mask: enable writing to all 4 planes */
- vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
- offset = var->xres_virtual / 4;
}
/******************************************************
*
- * 32 bpp
+ * 24 bpp
*
*/
- else if (var->bits_per_pixel == 32) {
- DPRINTK("cirrusfb: preparing for 32 bit deep display\n");
+ else if (var->bits_per_pixel == 24) {
+ dev_dbg(info->device, "preparing for 24 bit deep display\n");
switch (cinfo->btype) {
- case BT_SD64:
- /* Extended Sequencer Mode: 256c col. mode */
- vga_wseq(regbase, CL_SEQR7, 0xf9);
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x1e);
- break;
-
case BT_PICCOLO:
case BT_SPECTRUM:
vga_wseq(regbase, CL_SEQR7, 0x85);
/* Fast Page-Mode writes */
vga_wseq(regbase, CL_SEQRF, 0xb0);
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
case BT_PICASSO:
vga_wseq(regbase, CL_SEQR7, 0x25);
/* Fast Page-Mode writes */
vga_wseq(regbase, CL_SEQRF, 0xb0);
- /* MCLK select */
- vga_wseq(regbase, CL_SEQR1F, 0x22);
break;
+ case BT_SD64:
case BT_PICASSO4:
- vga_wseq(regbase, CL_SEQR7, 0x25);
-/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
- break;
-
case BT_ALPINE:
- DPRINTK(" (for GD543x)\n");
- vga_wseq(regbase, CL_SEQR7, 0xa9);
+ /* Extended Sequencer Mode: 256c col. mode */
+ vga_wseq(regbase, CL_SEQR7, 0xa5);
break;
case BT_GD5480:
- DPRINTK(" (for GD5480)\n");
- vga_wseq(regbase, CL_SEQR7, 0x19);
+ vga_wseq(regbase, CL_SEQR7, 0x15);
/* We already set SRF and SR1F */
break;
case BT_LAGUNA:
- DPRINTK(" (for GD546x)\n");
+ case BT_LAGUNAB:
vga_wseq(regbase, CL_SEQR7,
vga_rseq(regbase, CL_SEQR7) & ~0x01);
+ control |= 0x4000;
+ format |= 0x2400;
+ threshold |= 0x20;
break;
default:
- printk(KERN_WARNING "cirrusfb: unknown Board\n");
+ dev_warn(info->device, "unknown Board\n");
break;
}
/* mode register: 256 color mode */
vga_wgfx(regbase, VGA_GFX_MODE, 64);
- /* pixel mask: pass-through all planes */
- WGen(cinfo, VGA_PEL_MSK, 0xff);
/* hidden dac reg: 8-8-8 mode (24 or 32) */
WHDR(cinfo, 0xc5);
- /* memory mode: chain4, ext. memory */
- vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
- /* plane mask: enable writing to all 4 planes */
- vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
- offset = var->xres_virtual / 4;
}
/******************************************************
@@ -1284,67 +1200,55 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
*/
else
- printk(KERN_ERR "cirrusfb: What's this?? "
- " requested color depth == %d.\n",
+ dev_err(info->device,
+ "What's this? requested color depth == %d.\n",
var->bits_per_pixel);
- vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff);
+ pitch = info->fix.line_length >> 3;
+ vga_wcrt(regbase, VGA_CRTC_OFFSET, pitch & 0xff);
tmp = 0x22;
- if (offset & 0x100)
+ if (pitch & 0x100)
tmp |= 0x10; /* offset overflow bit */
/* screen start addr #16-18, fastpagemode cycles */
vga_wcrt(regbase, CL_CRT1B, tmp);
- if (cinfo->btype == BT_SD64 ||
- cinfo->btype == BT_PICASSO4 ||
- cinfo->btype == BT_ALPINE ||
- cinfo->btype == BT_GD5480)
- /* screen start address bit 19 */
- vga_wcrt(regbase, CL_CRT1D, 0x00);
-
- /* text cursor location high */
- vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
- /* text cursor location low */
- vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
- /* underline row scanline = at very bottom */
- vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
-
- /* controller mode */
- vga_wattr(regbase, VGA_ATC_MODE, 1);
- /* overscan (border) color */
- vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
- /* color plane enable */
- vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
+ /* screen start address bit 19 */
+ if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
+ vga_wcrt(regbase, CL_CRT1D, (pitch >> 9) & 1);
+
+ if (is_laguna(cinfo)) {
+ tmp = 0;
+ if ((htotal + 5) & 256)
+ tmp |= 128;
+ if (hdispend & 256)
+ tmp |= 64;
+ if (hsyncstart & 256)
+ tmp |= 48;
+ if (vtotal & 1024)
+ tmp |= 8;
+ if (vdispend & 1024)
+ tmp |= 4;
+ if (vsyncstart & 1024)
+ tmp |= 3;
+
+ vga_wcrt(regbase, CL_CRT1E, tmp);
+ dev_dbg(info->device, "CRT1e: %d\n", tmp);
+ }
+
/* pixel panning */
vga_wattr(regbase, CL_AR33, 0);
- /* color select */
- vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
/* [ EGS: SetOffset(); ] */
/* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
AttrOn(cinfo);
- /* set/reset register */
- vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
- /* set/reset enable */
- vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
- /* color compare */
- vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
- /* data rotate */
- vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
- /* read map select */
- vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
- /* miscellaneous register */
- vga_wgfx(regbase, VGA_GFX_MISC, 1);
- /* color don't care */
- vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
- /* bit mask */
- vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
-
- /* graphics cursor attributes: nothing special */
- vga_wseq(regbase, CL_SEQR12, 0x0);
-
+ if (is_laguna(cinfo)) {
+ /* no tiles */
+ fb_writew(control | 0x1000, cinfo->laguna_mmio + 0x402);
+ fb_writew(format, cinfo->laguna_mmio + 0xc0);
+ fb_writew(threshold, cinfo->laguna_mmio + 0xea);
+ }
/* finally, turn on everything - turn off "FullBandwidth" bit */
/* also, set "DotClock%2" bit where requested */
tmp = 0x01;
@@ -1355,18 +1259,12 @@ static int cirrusfb_set_par_foo(struct fb_info *info)
*/
vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
- DPRINTK("CL_SEQR1: %d\n", tmp);
-
- cinfo->currentmode = regs;
-
- /* pan to requested offset */
- cirrusfb_pan_display(var, info);
+ dev_dbg(info->device, "CL_SEQR1: %d\n", tmp);
#ifdef CIRRUSFB_DEBUG
- cirrusfb_dump();
+ cirrusfb_dbg_reg_dump(info, NULL);
#endif
- DPRINTK("EXIT\n");
return 0;
}
@@ -1418,27 +1316,19 @@ static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info)
{
- int xoffset = 0;
- int yoffset = 0;
+ int xoffset;
unsigned long base;
- unsigned char tmp = 0, tmp2 = 0, xpix;
+ unsigned char tmp, xpix;
struct cirrusfb_info *cinfo = info->par;
- DPRINTK("ENTER\n");
- DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
-
/* no range checks for xoffset and yoffset, */
/* as fb_pan_display has already done this */
if (var->vmode & FB_VMODE_YWRAP)
return -EINVAL;
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
-
xoffset = var->xoffset * info->var.bits_per_pixel / 8;
- yoffset = var->yoffset;
- base = yoffset * info->fix.line_length + xoffset;
+ base = var->yoffset * info->fix.line_length + xoffset;
if (info->var.bits_per_pixel == 1) {
/* base is already correct */
@@ -1448,14 +1338,15 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
xpix = (unsigned char) ((xoffset % 4) * 2);
}
- cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
+ if (!is_laguna(cinfo))
+ cirrusfb_WaitBLT(cinfo->regbase);
/* lower 8 + 8 bits of screen start address */
- vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
- (unsigned char) (base & 0xff));
- vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
- (unsigned char) (base >> 8));
+ vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, base & 0xff);
+ vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, (base >> 8) & 0xff);
+ /* 0xf2 is %11110010, exclude tmp bits */
+ tmp = vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2;
/* construct bits 16, 17 and 18 of screen start address */
if (base & 0x10000)
tmp |= 0x01;
@@ -1464,13 +1355,17 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
if (base & 0x40000)
tmp |= 0x08;
- /* 0xf2 is %11110010, exclude tmp bits */
- tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
- vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
+ vga_wcrt(cinfo->regbase, CL_CRT1B, tmp);
/* construct bit 19 of screen start address */
- if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
- vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
+ if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) {
+ tmp = vga_rcrt(cinfo->regbase, CL_CRT1D);
+ if (is_laguna(cinfo))
+ tmp = (tmp & ~0x18) | ((base >> 16) & 0x18);
+ else
+ tmp = (tmp & ~0x80) | ((base >> 12) & 0x80);
+ vga_wcrt(cinfo->regbase, CL_CRT1D, tmp);
+ }
/* write pixel panning value to AR33; this does not quite work in 8bpp
*
@@ -1479,9 +1374,6 @@ static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
if (info->var.bits_per_pixel == 1)
vga_wattr(cinfo->regbase, CL_AR33, xpix);
- cirrusfb_WaitBLT(cinfo->regbase);
-
- DPRINTK("EXIT\n");
return 0;
}
@@ -1502,57 +1394,54 @@ static int cirrusfb_blank(int blank_mode, struct fb_info *info)
struct cirrusfb_info *cinfo = info->par;
int current_mode = cinfo->blank_mode;
- DPRINTK("ENTER, blank mode = %d\n", blank_mode);
+ dev_dbg(info->device, "ENTER, blank mode = %d\n", blank_mode);
if (info->state != FBINFO_STATE_RUNNING ||
current_mode == blank_mode) {
- DPRINTK("EXIT, returning 0\n");
+ dev_dbg(info->device, "EXIT, returning 0\n");
return 0;
}
/* Undo current */
if (current_mode == FB_BLANK_NORMAL ||
- current_mode == FB_BLANK_UNBLANK) {
- /* unblank the screen */
- val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
+ current_mode == FB_BLANK_UNBLANK)
/* clear "FullBandwidth" bit */
- vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);
- /* and undo VESA suspend trickery */
- vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
- }
-
- /* set new */
- if (blank_mode > FB_BLANK_NORMAL) {
- /* blank the screen */
- val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
+ val = 0;
+ else
/* set "FullBandwidth" bit */
- vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);
- }
+ val = 0x20;
+
+ val |= vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE) & 0xdf;
+ vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val);
switch (blank_mode) {
case FB_BLANK_UNBLANK:
case FB_BLANK_NORMAL:
+ val = 0x00;
break;
case FB_BLANK_VSYNC_SUSPEND:
- vga_wgfx(cinfo->regbase, CL_GRE, 0x04);
+ val = 0x04;
break;
case FB_BLANK_HSYNC_SUSPEND:
- vga_wgfx(cinfo->regbase, CL_GRE, 0x02);
+ val = 0x02;
break;
case FB_BLANK_POWERDOWN:
- vga_wgfx(cinfo->regbase, CL_GRE, 0x06);
+ val = 0x06;
break;
default:
- DPRINTK("EXIT, returning 1\n");
+ dev_dbg(info->device, "EXIT, returning 1\n");
return 1;
}
+ vga_wgfx(cinfo->regbase, CL_GRE, val);
+
cinfo->blank_mode = blank_mode;
- DPRINTK("EXIT, returning 0\n");
+ dev_dbg(info->device, "EXIT, returning 0\n");
/* Let fbcon do a soft blank for us */
return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
}
+
/**** END Hardware specific Routines **************************************/
/****************************************************************************/
/**** BEGIN Internal Routines ***********************************************/
@@ -1562,8 +1451,6 @@ static void init_vgachip(struct fb_info *info)
struct cirrusfb_info *cinfo = info->par;
const struct cirrusfb_board_info_rec *bi;
- DPRINTK("ENTER\n");
-
assert(cinfo != NULL);
bi = &cirrusfb_board_info[cinfo->btype];
@@ -1591,25 +1478,23 @@ static void init_vgachip(struct fb_info *info)
/* disable flickerfixer */
vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
mdelay(100);
- /* from Klaus' NetBSD driver: */
- vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
- /* put blitter into 542x compat */
- vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
/* mode */
vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
- break;
-
- case BT_GD5480:
+ case BT_GD5480: /* fall through */
/* from Klaus' NetBSD driver: */
vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
+ case BT_ALPINE: /* fall through */
+ /* put blitter into 542x compat */
+ vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
break;
- case BT_ALPINE:
+ case BT_LAGUNA:
+ case BT_LAGUNAB:
/* Nothing to do to reset the board. */
break;
default:
- printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n");
+ dev_err(info->device, "Warning: Unknown board type\n");
break;
}
@@ -1629,31 +1514,28 @@ static void init_vgachip(struct fb_info *info)
WGen(cinfo, CL_VSSM2, 0x01);
/* reset sequencer logic */
- vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
+ vga_wseq(cinfo->regbase, VGA_SEQ_RESET, 0x03);
/* FullBandwidth (video off) and 8/9 dot clock */
vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
- /* polarity (-/-), disable access to display memory,
- * VGA_CRTC_START_HI base address: color
- */
- WGen(cinfo, VGA_MIS_W, 0xc1);
/* "magic cookie" - doesn't make any sense to me.. */
/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
/* unlock all extension registers */
vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
- /* reset blitter */
- vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
-
switch (cinfo->btype) {
case BT_GD5480:
vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
break;
case BT_ALPINE:
+ case BT_LAGUNA:
+ case BT_LAGUNAB:
break;
case BT_SD64:
+#ifdef CONFIG_ZORRO
vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
+#endif
break;
default:
vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
@@ -1665,8 +1547,8 @@ static void init_vgachip(struct fb_info *info)
vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
/* character map select: doesn't even matter in gx mode */
vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
- /* memory mode: chain-4, no odd/even, ext. memory */
- vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
+ /* memory mode: chain4, ext. memory */
+ vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
/* controller-internal base address of video memory */
if (bi->init_sr07)
@@ -1692,20 +1574,12 @@ static void init_vgachip(struct fb_info *info)
vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
}
- /* MCLK select etc. */
- if (bi->init_sr1f)
- vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
-
/* Screen A preset row scan: none */
vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
/* Text cursor start: disable text cursor */
vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
/* Text cursor end: - */
vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
- /* Screen start address high: 0 */
- vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
- /* Screen start address low: 0 */
- vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
/* text cursor location high: 0 */
vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
/* text cursor location low: 0 */
@@ -1713,10 +1587,6 @@ static void init_vgachip(struct fb_info *info)
/* Underline Row scanline: - */
vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
- /* mode control: timing enable, byte mode, no compat modes */
- vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
- /* Line Compare: not needed */
- vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
/* ### add 0x40 for text modes with > 30 MHz pixclock */
/* ext. display controls: ext.adr. wrap */
vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
@@ -1739,7 +1609,9 @@ static void init_vgachip(struct fb_info *info)
vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
/* Bit Mask: no mask at all */
vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
- if (cinfo->btype == BT_ALPINE)
+
+ if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64 ||
+ is_laguna(cinfo))
/* (5434 can't have bit 3 set for bitblt) */
vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
else
@@ -1779,18 +1651,11 @@ static void init_vgachip(struct fb_info *info)
vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
/* Color Plane enable: Enable all 4 planes */
vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
-/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
/* Color Select: - */
vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
- if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
- /* polarity (-/-), enable display mem,
- * VGA_CRTC_START_HI i/o base = color
- */
- WGen(cinfo, VGA_MIS_W, 0xc3);
-
/* BLT Start/status: Blitter reset */
vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
/* - " - : "end-of-reset" */
@@ -1798,8 +1663,6 @@ static void init_vgachip(struct fb_info *info)
/* misc... */
WHDR(cinfo, 0); /* Hidden DAC register: - */
-
- DPRINTK("EXIT\n");
return;
}
@@ -1808,8 +1671,6 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
#ifdef CONFIG_ZORRO /* only works on Zorro boards */
static int IsOn = 0; /* XXX not ok for multiple boards */
- DPRINTK("ENTER\n");
-
if (cinfo->btype == BT_PICASSO4)
return; /* nothing to switch */
if (cinfo->btype == BT_ALPINE)
@@ -1819,8 +1680,6 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
if (cinfo->btype == BT_PICASSO) {
if ((on && !IsOn) || (!on && IsOn))
WSFR(cinfo, 0xff);
-
- DPRINTK("EXIT\n");
return;
}
if (on) {
@@ -1847,11 +1706,10 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
case BT_SPECTRUM:
WSFR(cinfo, 0x4f);
break;
- default: /* do nothing */ break;
+ default: /* do nothing */
+ break;
}
}
-
- DPRINTK("EXIT\n");
#endif /* CONFIG_ZORRO */
}
@@ -1859,6 +1717,17 @@ static void switch_monitor(struct cirrusfb_info *cinfo, int on)
/* Linux 2.6-style accelerated functions */
/******************************************/
+static int cirrusfb_sync(struct fb_info *info)
+{
+ struct cirrusfb_info *cinfo = info->par;
+
+ if (!is_laguna(cinfo)) {
+ while (vga_rgfx(cinfo->regbase, CL_GR31) & 0x03)
+ cpu_relax();
+ }
+ return 0;
+}
+
static void cirrusfb_fillrect(struct fb_info *info,
const struct fb_fillrect *region)
{
@@ -1894,8 +1763,8 @@ static void cirrusfb_fillrect(struct fb_info *info,
info->var.bits_per_pixel,
(region->dx * m) / 8, region->dy,
(region->width * m) / 8, region->height,
- color,
- info->fix.line_length);
+ color, color,
+ info->fix.line_length, 0x40);
}
static void cirrusfb_copyarea(struct fb_info *info,
@@ -1943,9 +1812,46 @@ static void cirrusfb_imageblit(struct fb_info *info,
const struct fb_image *image)
{
struct cirrusfb_info *cinfo = info->par;
+ unsigned char op = (info->var.bits_per_pixel == 24) ? 0xc : 0x4;
- cirrusfb_WaitBLT(cinfo->regbase);
- cfb_imageblit(info, image);
+ if (info->state != FBINFO_STATE_RUNNING)
+ return;
+ /* Alpine/SD64 does not work at 24bpp ??? */
+ if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1)
+ cfb_imageblit(info, image);
+ else if ((cinfo->btype == BT_ALPINE || cinfo->btype == BT_SD64) &&
+ op == 0xc)
+ cfb_imageblit(info, image);
+ else {
+ unsigned size = ((image->width + 7) >> 3) * image->height;
+ int m = info->var.bits_per_pixel;
+ u32 fg, bg;
+
+ if (info->var.bits_per_pixel == 8) {
+ fg = image->fg_color;
+ bg = image->bg_color;
+ } else {
+ fg = ((u32 *)(info->pseudo_palette))[image->fg_color];
+ bg = ((u32 *)(info->pseudo_palette))[image->bg_color];
+ }
+ if (info->var.bits_per_pixel == 24) {
+ /* clear background first */
+ cirrusfb_RectFill(cinfo->regbase,
+ info->var.bits_per_pixel,
+ (image->dx * m) / 8, image->dy,
+ (image->width * m) / 8,
+ image->height,
+ bg, bg,
+ info->fix.line_length, 0x40);
+ }
+ cirrusfb_RectFill(cinfo->regbase,
+ info->var.bits_per_pixel,
+ (image->dx * m) / 8, image->dy,
+ (image->width * m) / 8, image->height,
+ fg, bg,
+ info->fix.line_length, op);
+ memcpy(info->screen_base, image->data, size);
+ }
}
#ifdef CONFIG_PPC_PREP
@@ -1953,12 +1859,8 @@ static void cirrusfb_imageblit(struct fb_info *info,
#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
static void get_prep_addrs(unsigned long *display, unsigned long *registers)
{
- DPRINTK("ENTER\n");
-
*display = PREP_VIDEO_BASE;
*registers = (unsigned long) PREP_IO_BASE;
-
- DPRINTK("EXIT\n");
}
#endif /* CONFIG_PPC_PREP */
@@ -1970,40 +1872,43 @@ static int release_io_ports;
* based on the DRAM bandwidth bit and DRAM bank switching bit. This
* works with 1MB, 2MB and 4MB configurations (which the Motorola boards
* seem to have. */
-static unsigned int __devinit cirrusfb_get_memsize(u8 __iomem *regbase)
+static unsigned int __devinit cirrusfb_get_memsize(struct fb_info *info,
+ u8 __iomem *regbase)
{
unsigned long mem;
- unsigned char SRF;
+ struct cirrusfb_info *cinfo = info->par;
- DPRINTK("ENTER\n");
+ if (is_laguna(cinfo)) {
+ unsigned char SR14 = vga_rseq(regbase, CL_SEQR14);
- SRF = vga_rseq(regbase, CL_SEQRF);
- switch ((SRF & 0x18)) {
- case 0x08:
- mem = 512 * 1024;
- break;
- case 0x10:
- mem = 1024 * 1024;
- break;
- /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
- * on the 5430.
- */
- case 0x18:
- mem = 2048 * 1024;
- break;
- default:
- printk(KERN_WARNING "CLgenfb: Unknown memory size!\n");
- mem = 1024 * 1024;
+ mem = ((SR14 & 7) + 1) << 20;
+ } else {
+ unsigned char SRF = vga_rseq(regbase, CL_SEQRF);
+ switch ((SRF & 0x18)) {
+ case 0x08:
+ mem = 512 * 1024;
+ break;
+ case 0x10:
+ mem = 1024 * 1024;
+ break;
+ /* 64-bit DRAM data bus width; assume 2MB.
+ * Also indicates 2MB memory on the 5430.
+ */
+ case 0x18:
+ mem = 2048 * 1024;
+ break;
+ default:
+ dev_warn(info->device, "Unknown memory size!\n");
+ mem = 1024 * 1024;
+ }
+ /* If DRAM bank switching is enabled, there must be
+ * twice as much memory installed. (4MB on the 5434)
+ */
+ if (cinfo->btype != BT_ALPINE && (SRF & 0x80) != 0)
+ mem *= 2;
}
- if (SRF & 0x80)
- /* If DRAM bank switching is enabled, there must be twice as much
- * memory installed. (4MB on the 5434)
- */
- mem *= 2;
/* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
-
- DPRINTK("EXIT\n");
return mem;
}
@@ -2014,8 +1919,6 @@ static void get_pci_addrs(const struct pci_dev *pdev,
assert(display != NULL);
assert(registers != NULL);
- DPRINTK("ENTER\n");
-
*display = 0;
*registers = 0;
@@ -2030,14 +1933,15 @@ static void get_pci_addrs(const struct pci_dev *pdev,
}
assert(*display != 0);
-
- DPRINTK("EXIT\n");
}
static void cirrusfb_pci_unmap(struct fb_info *info)
{
struct pci_dev *pdev = to_pci_dev(info->device);
+ struct cirrusfb_info *cinfo = info->par;
+ if (cinfo->laguna_mmio == NULL)
+ iounmap(cinfo->laguna_mmio);
iounmap(info->screen_base);
#if 0 /* if system didn't claim this region, we would... */
release_mem_region(0xA0000, 65535);
@@ -2067,6 +1971,22 @@ static void cirrusfb_zorro_unmap(struct fb_info *info)
}
#endif /* CONFIG_ZORRO */
+/* function table of the above functions */
+static struct fb_ops cirrusfb_ops = {
+ .owner = THIS_MODULE,
+ .fb_open = cirrusfb_open,
+ .fb_release = cirrusfb_release,
+ .fb_setcolreg = cirrusfb_setcolreg,
+ .fb_check_var = cirrusfb_check_var,
+ .fb_set_par = cirrusfb_set_par,
+ .fb_pan_display = cirrusfb_pan_display,
+ .fb_blank = cirrusfb_blank,
+ .fb_fillrect = cirrusfb_fillrect,
+ .fb_copyarea = cirrusfb_copyarea,
+ .fb_sync = cirrusfb_sync,
+ .fb_imageblit = cirrusfb_imageblit,
+};
+
static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
@@ -2077,10 +1997,16 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
| FBINFO_HWACCEL_XPAN
| FBINFO_HWACCEL_YPAN
| FBINFO_HWACCEL_FILLRECT
+ | FBINFO_HWACCEL_IMAGEBLIT
| FBINFO_HWACCEL_COPYAREA;
- if (noaccel)
+ if (noaccel || is_laguna(cinfo)) {
info->flags |= FBINFO_HWACCEL_DISABLED;
+ info->fix.accel = FB_ACCEL_NONE;
+ } else
+ info->fix.accel = FB_ACCEL_CIRRUS_ALPINE;
+
info->fbops = &cirrusfb_ops;
+
if (cinfo->btype == BT_GD5480) {
if (var->bits_per_pixel == 16)
info->screen_base += 1 * MB_;
@@ -2104,7 +2030,6 @@ static int __devinit cirrusfb_set_fbinfo(struct fb_info *info)
/* FIXME: map region at 0xB8000 if available, fill in here */
info->fix.mmio_len = 0;
- info->fix.accel = FB_ACCEL_NONE;
fb_alloc_cmap(&info->cmap, 256, 0);
@@ -2115,70 +2040,56 @@ static int __devinit cirrusfb_register(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
int err;
- enum cirrus_board btype;
-
- DPRINTK("ENTER\n");
-
- printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "
- "graphic boards, v" CIRRUSFB_VERSION "\n");
-
- btype = cinfo->btype;
/* sanity checks */
- assert(btype != BT_NONE);
+ assert(cinfo->btype != BT_NONE);
/* set all the vital stuff */
cirrusfb_set_fbinfo(info);
- DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
+ dev_dbg(info->device, "(RAM start set to: 0x%p)\n", info->screen_base);
err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
if (!err) {
- DPRINTK("wrong initial video mode\n");
+ dev_dbg(info->device, "wrong initial video mode\n");
err = -EINVAL;
goto err_dealloc_cmap;
}
info->var.activate = FB_ACTIVATE_NOW;
- err = cirrusfb_decode_var(&info->var, &cinfo->currentmode, info);
+ err = cirrusfb_check_var(&info->var, info);
if (err < 0) {
/* should never happen */
- DPRINTK("choking on default var... umm, no good.\n");
+ dev_dbg(info->device,
+ "choking on default var... umm, no good.\n");
goto err_dealloc_cmap;
}
err = register_framebuffer(info);
if (err < 0) {
- printk(KERN_ERR "cirrusfb: could not register "
- "fb device; err = %d!\n", err);
+ dev_err(info->device,
+ "could not register fb device; err = %d!\n", err);
goto err_dealloc_cmap;
}
- DPRINTK("EXIT, returning 0\n");
return 0;
err_dealloc_cmap:
fb_dealloc_cmap(&info->cmap);
- cinfo->unmap(info);
- framebuffer_release(info);
return err;
}
static void __devexit cirrusfb_cleanup(struct fb_info *info)
{
struct cirrusfb_info *cinfo = info->par;
- DPRINTK("ENTER\n");
switch_monitor(cinfo, 0);
-
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
- printk("Framebuffer unregistered\n");
+ dev_dbg(info->device, "Framebuffer unregistered\n");
cinfo->unmap(info);
framebuffer_release(info);
-
- DPRINTK("EXIT\n");
}
#ifdef CONFIG_PCI
@@ -2187,7 +2098,6 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
{
struct cirrusfb_info *cinfo;
struct fb_info *info;
- enum cirrus_board btype;
unsigned long board_addr, board_size;
int ret;
@@ -2201,15 +2111,17 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
if (!info) {
printk(KERN_ERR "cirrusfb: could not allocate memory\n");
ret = -ENOMEM;
- goto err_disable;
+ goto err_out;
}
cinfo = info->par;
- cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
+ cinfo->btype = (enum cirrus_board) ent->driver_data;
- DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
- pdev->resource[0].start, btype);
- DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start);
+ dev_dbg(info->device,
+ " Found PCI device, base address 0 is 0x%Lx, btype set to %d\n",
+ (unsigned long long)pdev->resource[0].start, cinfo->btype);
+ dev_dbg(info->device, " base address 1 is 0x%Lx\n",
+ (unsigned long long)pdev->resource[1].start);
if (isPReP) {
pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
@@ -2219,30 +2131,30 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
/* PReP dies if we ioremap the IO registers, but it works w/out... */
cinfo->regbase = (char __iomem *) info->fix.mmio_start;
} else {
- DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n");
+ dev_dbg(info->device,
+ "Attempt to get PCI info for Cirrus Graphics Card\n");
get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
/* FIXME: this forces VGA. alternatives? */
cinfo->regbase = NULL;
+ cinfo->laguna_mmio = ioremap(info->fix.mmio_start, 0x1000);
}
- DPRINTK("Board address: 0x%lx, register address: 0x%lx\n",
+ dev_dbg(info->device, "Board address: 0x%lx, register address: 0x%lx\n",
board_addr, info->fix.mmio_start);
- board_size = (btype == BT_GD5480) ?
- 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase);
+ board_size = (cinfo->btype == BT_GD5480) ?
+ 32 * MB_ : cirrusfb_get_memsize(info, cinfo->regbase);
ret = pci_request_regions(pdev, "cirrusfb");
if (ret < 0) {
- printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
- "abort\n",
- board_addr);
+ dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
+ board_addr);
goto err_release_fb;
}
#if 0 /* if the system didn't claim this region, we would... */
if (!request_mem_region(0xA0000, 65535, "cirrusfb")) {
- printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n"
-,
- 0xA0000L);
+ dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
+ 0xA0000L);
ret = -EBUSY;
goto err_release_regions;
}
@@ -2260,16 +2172,17 @@ static int __devinit cirrusfb_pci_register(struct pci_dev *pdev,
info->screen_size = board_size;
cinfo->unmap = cirrusfb_pci_unmap;
- printk(KERN_INFO "RAM (%lu kB) at 0x%lx, Cirrus "
- "Logic chipset on PCI bus\n",
- info->screen_size >> 10, board_addr);
+ dev_info(info->device,
+ "Cirrus Logic chipset on PCI bus, RAM (%lu kB) at 0x%lx\n",
+ info->screen_size >> 10, board_addr);
pci_set_drvdata(pdev, info);
ret = cirrusfb_register(info);
- if (ret)
- iounmap(info->screen_base);
- return ret;
+ if (!ret)
+ return 0;
+ pci_set_drvdata(pdev, NULL);
+ iounmap(info->screen_base);
err_release_legacy:
if (release_io_ports)
release_region(0x3C0, 32);
@@ -2279,8 +2192,9 @@ err_release_regions:
#endif
pci_release_regions(pdev);
err_release_fb:
+ if (cinfo->laguna_mmio != NULL)
+ iounmap(cinfo->laguna_mmio);
framebuffer_release(info);
-err_disable:
err_out:
return ret;
}
@@ -2288,11 +2202,8 @@ err_out:
static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
{
struct fb_info *info = pci_get_drvdata(pdev);
- DPRINTK("ENTER\n");
cirrusfb_cleanup(info);
-
- DPRINTK("EXIT\n");
}
static struct pci_driver cirrusfb_pci_driver = {
@@ -2324,8 +2235,6 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
if (cirrusfb_zorro_table2[btype].id2)
z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
size = cirrusfb_zorro_table2[btype].size;
- printk(KERN_INFO "cirrusfb: %s board detected; ",
- cirrusfb_board_info[btype].name);
info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
if (!info) {
@@ -2334,6 +2243,9 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
goto err_out;
}
+ dev_info(info->device, "%s board detected\n",
+ cirrusfb_board_info[btype].name);
+
cinfo = info->par;
cinfo->btype = btype;
@@ -2345,19 +2257,16 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
info->screen_size = size;
if (!zorro_request_device(z, "cirrusfb")) {
- printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
- "abort\n",
- board_addr);
+ dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
+ board_addr);
ret = -EBUSY;
goto err_release_fb;
}
- printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
-
ret = -EIO;
if (btype == BT_PICASSO4) {
- printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000);
+ dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
/* To be precise, for the P4 this is not the */
/* begin of the board, but the begin of RAM. */
@@ -2367,7 +2276,7 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
if (!cinfo->regbase)
goto err_release_region;
- DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
+ dev_dbg(info->device, "Virtual address for board set to: $%p\n",
cinfo->regbase);
cinfo->regbase += 0x600000;
info->fix.mmio_start = board_addr + 0x600000;
@@ -2377,8 +2286,8 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
if (!info->screen_base)
goto err_unmap_regbase;
} else {
- printk(KERN_INFO " REG at $%lx\n",
- (unsigned long) z2->resource.start);
+ dev_info(info->device, " REG at $%lx\n",
+ (unsigned long) z2->resource.start);
info->fix.smem_start = board_addr;
if (board_addr > 0x01000000)
@@ -2392,27 +2301,32 @@ static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
info->fix.mmio_start = z2->resource.start;
- DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
+ dev_dbg(info->device, "Virtual address for board set to: $%p\n",
cinfo->regbase);
}
cinfo->unmap = cirrusfb_zorro_unmap;
- printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
+ dev_info(info->device,
+ "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
+ board_size / MB_, board_addr);
+
zorro_set_drvdata(z, info);
+ /* MCLK select etc. */
+ if (cirrusfb_board_info[btype].init_sr1f)
+ vga_wseq(cinfo->regbase, CL_SEQR1F,
+ cirrusfb_board_info[btype].sr1f);
+
ret = cirrusfb_register(info);
- if (ret) {
- if (btype == BT_PICASSO4) {
- iounmap(info->screen_base);
- iounmap(cinfo->regbase - 0x600000);
- } else if (board_addr > 0x01000000)
- iounmap(info->screen_base);
- }
- return ret;
+ if (!ret)
+ return 0;
+
+ if (btype == BT_PICASSO4 || board_addr > 0x01000000)
+ iounmap(info->screen_base);
err_unmap_regbase:
- /* Parental advisory: explicit hack */
- iounmap(cinfo->regbase - 0x600000);
+ if (btype == BT_PICASSO4)
+ iounmap(cinfo->regbase - 0x600000);
err_release_region:
release_region(board_addr, board_size);
err_release_fb:
@@ -2424,11 +2338,8 @@ err_out:
void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
{
struct fb_info *info = zorro_get_drvdata(z);
- DPRINTK("ENTER\n");
cirrusfb_cleanup(info);
-
- DPRINTK("EXIT\n");
}
static struct zorro_driver cirrusfb_zorro_driver = {
@@ -2439,33 +2350,11 @@ static struct zorro_driver cirrusfb_zorro_driver = {
};
#endif /* CONFIG_ZORRO */
-static int __init cirrusfb_init(void)
-{
- int error = 0;
-
#ifndef MODULE
- char *option = NULL;
-
- if (fb_get_options("cirrusfb", &option))
- return -ENODEV;
- cirrusfb_setup(option);
-#endif
-
-#ifdef CONFIG_ZORRO
- error |= zorro_register_driver(&cirrusfb_zorro_driver);
-#endif
-#ifdef CONFIG_PCI
- error |= pci_register_driver(&cirrusfb_pci_driver);
-#endif
- return error;
-}
-
-#ifndef MODULE
-static int __init cirrusfb_setup(char *options) {
+static int __init cirrusfb_setup(char *options)
+{
char *this_opt;
- DPRINTK("ENTER\n");
-
if (!options || !*options)
return 0;
@@ -2473,8 +2362,6 @@ static int __init cirrusfb_setup(char *options) {
if (!*this_opt)
continue;
- DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
-
if (!strcmp(this_opt, "noaccel"))
noaccel = 1;
else if (!strncmp(this_opt, "mode:", 5))
@@ -2494,6 +2381,27 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
MODULE_LICENSE("GPL");
+static int __init cirrusfb_init(void)
+{
+ int error = 0;
+
+#ifndef MODULE
+ char *option = NULL;
+
+ if (fb_get_options("cirrusfb", &option))
+ return -ENODEV;
+ cirrusfb_setup(option);
+#endif
+
+#ifdef CONFIG_ZORRO
+ error |= zorro_register_driver(&cirrusfb_zorro_driver);
+#endif
+#ifdef CONFIG_PCI
+ error |= pci_register_driver(&cirrusfb_pci_driver);
+#endif
+ return error;
+}
+
static void __exit cirrusfb_exit(void)
{
#ifdef CONFIG_PCI
@@ -2560,8 +2468,6 @@ static void AttrOn(const struct cirrusfb_info *cinfo)
{
assert(cinfo != NULL);
- DPRINTK("ENTER\n");
-
if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
/* if we're just in "write value" mode, write back the */
/* same value as before to not modify anything */
@@ -2574,8 +2480,6 @@ static void AttrOn(const struct cirrusfb_info *cinfo)
/* dummy write on Reg0 to be on "write index" mode next time */
vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
-
- DPRINTK("EXIT\n");
}
/*** WHDR() - write into the Hidden DAC register ***/
@@ -2588,6 +2492,8 @@ static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
{
unsigned char dummy;
+ if (is_laguna(cinfo))
+ return;
if (cinfo->btype == BT_PICASSO) {
/* Klaus' hint for correct access to HDR on some boards */
/* first write 0 to pixel mask (3c6) */
@@ -2655,7 +2561,8 @@ static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch
vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
- cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
+ cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480 ||
+ cinfo->btype == BT_SD64 || is_laguna(cinfo)) {
/* but DAC data register IS, at least for Picasso II */
if (cinfo->btype == BT_PICASSO)
data += 0xfff;
@@ -2702,9 +2609,8 @@ static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned ch
/* FIXME: use interrupts instead */
static void cirrusfb_WaitBLT(u8 __iomem *regbase)
{
- /* now busy-wait until we're done */
while (vga_rgfx(regbase, CL_GR31) & 0x08)
- /* do nothing */ ;
+ cpu_relax();
}
/*******************************************************************
@@ -2713,60 +2619,12 @@ static void cirrusfb_WaitBLT(u8 __iomem *regbase)
perform accelerated "scrolling"
********************************************************************/
-static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
- u_short curx, u_short cury,
- u_short destx, u_short desty,
- u_short width, u_short height,
- u_short line_length)
-{
- u_short nwidth, nheight;
- u_long nsrc, ndest;
- u_char bltmode;
-
- DPRINTK("ENTER\n");
-
- nwidth = width - 1;
- nheight = height - 1;
-
- bltmode = 0x00;
- /* if source adr < dest addr, do the Blt backwards */
- if (cury <= desty) {
- if (cury == desty) {
- /* if src and dest are on the same line, check x */
- if (curx < destx)
- bltmode |= 0x01;
- } else
- bltmode |= 0x01;
- }
- if (!bltmode) {
- /* standard case: forward blitting */
- nsrc = (cury * line_length) + curx;
- ndest = (desty * line_length) + destx;
- } else {
- /* this means start addresses are at the end,
- * counting backwards
- */
- nsrc = cury * line_length + curx +
- nheight * line_length + nwidth;
- ndest = desty * line_length + destx +
- nheight * line_length + nwidth;
- }
-
- /*
- run-down of registers to be programmed:
- destination pitch
- source pitch
- BLT width/height
- source start
- destination start
- BLT mode
- BLT ROP
- VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
- start/stop
- */
-
- cirrusfb_WaitBLT(regbase);
+static void cirrusfb_set_blitter(u8 __iomem *regbase,
+ u_short nwidth, u_short nheight,
+ u_long nsrc, u_long ndest,
+ u_short bltmode, u_short line_length)
+{
/* pitch: set to line_length */
/* dest pitch low */
vga_wgfx(regbase, CL_GR24, line_length & 0xff);
@@ -2813,91 +2671,91 @@ static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
/* and finally: GO! */
vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
-
- DPRINTK("EXIT\n");
}
/*******************************************************************
- cirrusfb_RectFill()
+ cirrusfb_BitBLT()
- perform accelerated rectangle fill
+ perform accelerated "scrolling"
********************************************************************/
-static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
- u_short x, u_short y, u_short width, u_short height,
- u_char color, u_short line_length)
+static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
+ u_short curx, u_short cury,
+ u_short destx, u_short desty,
+ u_short width, u_short height,
+ u_short line_length)
{
- u_short nwidth, nheight;
- u_long ndest;
- u_char op;
-
- DPRINTK("ENTER\n");
-
- nwidth = width - 1;
- nheight = height - 1;
+ u_short nwidth = width - 1;
+ u_short nheight = height - 1;
+ u_long nsrc, ndest;
+ u_char bltmode;
- ndest = (y * line_length) + x;
+ bltmode = 0x00;
+ /* if source adr < dest addr, do the Blt backwards */
+ if (cury <= desty) {
+ if (cury == desty) {
+ /* if src and dest are on the same line, check x */
+ if (curx < destx)
+ bltmode |= 0x01;
+ } else
+ bltmode |= 0x01;
+ }
+ /* standard case: forward blitting */
+ nsrc = (cury * line_length) + curx;
+ ndest = (desty * line_length) + destx;
+ if (bltmode) {
+ /* this means start addresses are at the end,
+ * counting backwards
+ */
+ nsrc += nheight * line_length + nwidth;
+ ndest += nheight * line_length + nwidth;
+ }
cirrusfb_WaitBLT(regbase);
- /* pitch: set to line_length */
- vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
- vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */
- vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
- vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */
+ cirrusfb_set_blitter(regbase, nwidth, nheight,
+ nsrc, ndest, bltmode, line_length);
+}
- /* BLT width: actual number of pixels - 1 */
- vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
- vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */
+/*******************************************************************
+ cirrusfb_RectFill()
- /* BLT height: actual number of lines -1 */
- vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */
- vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */
+ perform accelerated rectangle fill
+********************************************************************/
- /* BLT destination */
- /* BLT dest low */
- vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
- /* BLT dest mid */
- vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
- /* BLT dest hi */
- vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
+static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
+ u_short x, u_short y, u_short width, u_short height,
+ u32 fg_color, u32 bg_color, u_short line_length,
+ u_char blitmode)
+{
+ u_long ndest = (y * line_length) + x;
+ u_char op;
- /* BLT source: set to 0 (is a dummy here anyway) */
- vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */
- vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */
- vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */
+ cirrusfb_WaitBLT(regbase);
/* This is a ColorExpand Blt, using the */
/* same color for foreground and background */
- vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */
- vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */
-
- op = 0xc0;
- if (bits_per_pixel == 16) {
- vga_wgfx(regbase, CL_GR10, color); /* foreground color */
- vga_wgfx(regbase, CL_GR11, color); /* background color */
- op = 0x50;
- op = 0xd0;
- } else if (bits_per_pixel == 32) {
- vga_wgfx(regbase, CL_GR10, color); /* foreground color */
- vga_wgfx(regbase, CL_GR11, color); /* background color */
- vga_wgfx(regbase, CL_GR12, color); /* foreground color */
- vga_wgfx(regbase, CL_GR13, color); /* background color */
- vga_wgfx(regbase, CL_GR14, 0); /* foreground color */
- vga_wgfx(regbase, CL_GR15, 0); /* background color */
- op = 0x50;
- op = 0xf0;
- }
- /* BLT mode: color expand, Enable 8x8 copy (faster?) */
- vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
-
- /* BLT ROP: SrcCopy */
- vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
-
- /* and finally: GO! */
- vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
-
- DPRINTK("EXIT\n");
+ vga_wgfx(regbase, VGA_GFX_SR_VALUE, bg_color);
+ vga_wgfx(regbase, VGA_GFX_SR_ENABLE, fg_color);
+
+ op = 0x80;
+ if (bits_per_pixel >= 16) {
+ vga_wgfx(regbase, CL_GR10, bg_color >> 8);
+ vga_wgfx(regbase, CL_GR11, fg_color >> 8);
+ op = 0x90;
+ }
+ if (bits_per_pixel >= 24) {
+ vga_wgfx(regbase, CL_GR12, bg_color >> 16);
+ vga_wgfx(regbase, CL_GR13, fg_color >> 16);
+ op = 0xa0;
+ }
+ if (bits_per_pixel == 32) {
+ vga_wgfx(regbase, CL_GR14, bg_color >> 24);
+ vga_wgfx(regbase, CL_GR15, fg_color >> 24);
+ op = 0xb0;
+ }
+ cirrusfb_set_blitter(regbase, width - 1, height - 1,
+ 0, ndest, op | blitmode, line_length);
}
/**************************************************************************
@@ -2917,8 +2775,6 @@ static void bestclock(long freq, int *nom, int *den, int *div)
*den = 0;
*div = 0;
- DPRINTK("ENTER\n");
-
if (freq < 8000)
freq = 8000;
@@ -2960,12 +2816,6 @@ static void bestclock(long freq, int *nom, int *den, int *div)
}
}
}
-
- DPRINTK("Best possible values for given frequency:\n");
- DPRINTK(" freq: %ld kHz nom: %d den: %d div: %d\n",
- freq, *nom, *den, *div);
-
- DPRINTK("EXIT\n");
}
/* -------------------------------------------------------------------------
@@ -2978,32 +2828,6 @@ static void bestclock(long freq, int *nom, int *den, int *div)
#ifdef CIRRUSFB_DEBUG
/**
- * cirrusfb_dbg_print_byte
- * @name: name associated with byte value to be displayed
- * @val: byte value to be displayed
- *
- * DESCRIPTION:
- * Display an indented string, along with a hexidecimal byte value, and
- * its decoded bits. Bits 7 through 0 are listed in left-to-right
- * order.
- */
-
-static
-void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
-{
- DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
- name, val,
- val & 0x80 ? '1' : '0',
- val & 0x40 ? '1' : '0',
- val & 0x20 ? '1' : '0',
- val & 0x10 ? '1' : '0',
- val & 0x08 ? '1' : '0',
- val & 0x04 ? '1' : '0',
- val & 0x02 ? '1' : '0',
- val & 0x01 ? '1' : '0');
-}
-
-/**
* cirrusfb_dbg_print_regs
* @base: If using newmmio, the newmmio base address, otherwise %NULL
* @reg_class: type of registers to read: %CRT, or %SEQ
@@ -3014,9 +2838,9 @@ void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
* used at the given @base address to query the information.
*/
-static
-void cirrusfb_dbg_print_regs(caddr_t regbase,
- enum cirrusfb_dbg_reg_class reg_class, ...)
+static void cirrusfb_dbg_print_regs(struct fb_info *info,
+ caddr_t regbase,
+ enum cirrusfb_dbg_reg_class reg_class, ...)
{
va_list list;
unsigned char val = 0;
@@ -3042,7 +2866,7 @@ void cirrusfb_dbg_print_regs(caddr_t regbase,
break;
}
- cirrusfb_dbg_print_byte(name, val);
+ dev_dbg(info->device, "%8s = 0x%02X\n", name, val);
name = va_arg(list, char *);
}
@@ -3051,18 +2875,6 @@ void cirrusfb_dbg_print_regs(caddr_t regbase,
}
/**
- * cirrusfb_dump
- * @cirrusfbinfo:
- *
- * DESCRIPTION:
- */
-
-static void cirrusfb_dump(void)
-{
- cirrusfb_dbg_reg_dump(NULL);
-}
-
-/**
* cirrusfb_dbg_reg_dump
* @base: If using newmmio, the newmmio base address, otherwise %NULL
*
@@ -3072,12 +2884,11 @@ static void cirrusfb_dump(void)
* used at the given @base address to query the information.
*/
-static
-void cirrusfb_dbg_reg_dump(caddr_t regbase)
+static void cirrusfb_dbg_reg_dump(struct fb_info *info, caddr_t regbase)
{
- DPRINTK("CIRRUSFB VGA CRTC register dump:\n");
+ dev_dbg(info->device, "VGA CRTC register dump:\n");
- cirrusfb_dbg_print_regs(regbase, CRT,
+ cirrusfb_dbg_print_regs(info, regbase, CRT,
"CR00", 0x00,
"CR01", 0x01,
"CR02", 0x02,
@@ -3127,11 +2938,11 @@ void cirrusfb_dbg_reg_dump(caddr_t regbase)
"CR3F", 0x3F,
NULL);
- DPRINTK("\n");
+ dev_dbg(info->device, "\n");
- DPRINTK("CIRRUSFB VGA SEQ register dump:\n");
+ dev_dbg(info->device, "VGA SEQ register dump:\n");
- cirrusfb_dbg_print_regs(regbase, SEQ,
+ cirrusfb_dbg_print_regs(info, regbase, SEQ,
"SR00", 0x00,
"SR01", 0x01,
"SR02", 0x02,
@@ -3160,7 +2971,7 @@ void cirrusfb_dbg_reg_dump(caddr_t regbase)
"SR1F", 0x1F,
NULL);
- DPRINTK("\n");
+ dev_dbg(info->device, "\n");
}
#endif /* CIRRUSFB_DEBUG */
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 1657b9608b0..2cd500a304f 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -2954,8 +2954,11 @@ static int fbcon_fb_unbind(int idx)
static int fbcon_fb_unregistered(struct fb_info *info)
{
- int i, idx = info->node;
+ int i, idx;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ idx = info->node;
for (i = first_fb_vc; i <= last_fb_vc; i++) {
if (con2fb_map[i] == idx)
con2fb_map[i] = -1;
@@ -2979,13 +2982,14 @@ static int fbcon_fb_unregistered(struct fb_info *info)
}
}
- if (!num_registered_fb)
- unregister_con_driver(&fb_con);
-
-
if (primary_device == idx)
primary_device = -1;
+ unlock_fb_info(info);
+
+ if (!num_registered_fb)
+ unregister_con_driver(&fb_con);
+
return 0;
}
@@ -3021,9 +3025,13 @@ static inline void fbcon_select_primary(struct fb_info *info)
static int fbcon_fb_registered(struct fb_info *info)
{
- int ret = 0, i, idx = info->node;
+ int ret = 0, i, idx;
+ if (!lock_fb_info(info))
+ return -ENODEV;
+ idx = info->node;
fbcon_select_primary(info);
+ unlock_fb_info(info);
if (info_idx == -1) {
for (i = first_fb_vc; i <= last_fb_vc; i++) {
@@ -3124,7 +3132,7 @@ static void fbcon_get_requirement(struct fb_info *info,
}
}
-static int fbcon_event_notify(struct notifier_block *self,
+static int fbcon_event_notify(struct notifier_block *self,
unsigned long action, void *data)
{
struct fb_event *event = data;
@@ -3132,7 +3140,7 @@ static int fbcon_event_notify(struct notifier_block *self,
struct fb_videomode *mode;
struct fb_con2fbmap *con2fb;
struct fb_blit_caps *caps;
- int ret = 0;
+ int idx, ret = 0;
/*
* ignore all events except driver registration and deregistration
@@ -3144,23 +3152,54 @@ static int fbcon_event_notify(struct notifier_block *self,
switch(action) {
case FB_EVENT_SUSPEND:
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
fbcon_suspended(info);
+ unlock_fb_info(info);
break;
case FB_EVENT_RESUME:
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
fbcon_resumed(info);
+ unlock_fb_info(info);
break;
case FB_EVENT_MODE_CHANGE:
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
fbcon_modechanged(info);
+ unlock_fb_info(info);
break;
case FB_EVENT_MODE_CHANGE_ALL:
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
fbcon_set_all_vcs(info);
+ unlock_fb_info(info);
break;
case FB_EVENT_MODE_DELETE:
mode = event->data;
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
ret = fbcon_mode_deleted(info, mode);
+ unlock_fb_info(info);
break;
case FB_EVENT_FB_UNBIND:
- ret = fbcon_fb_unbind(info->node);
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
+ idx = info->node;
+ unlock_fb_info(info);
+ ret = fbcon_fb_unbind(idx);
break;
case FB_EVENT_FB_REGISTERED:
ret = fbcon_fb_registered(info);
@@ -3178,17 +3217,31 @@ static int fbcon_event_notify(struct notifier_block *self,
con2fb->framebuffer = con2fb_map[con2fb->console - 1];
break;
case FB_EVENT_BLANK:
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
fbcon_fb_blanked(info, *(int *)event->data);
+ unlock_fb_info(info);
break;
case FB_EVENT_NEW_MODELIST:
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
fbcon_new_modelist(info);
+ unlock_fb_info(info);
break;
case FB_EVENT_GET_REQ:
caps = event->data;
+ if (!lock_fb_info(info)) {
+ ret = -ENODEV;
+ goto done;
+ }
fbcon_get_requirement(info, caps);
+ unlock_fb_info(info);
break;
}
-
done:
return ret;
}
diff --git a/drivers/video/cyblafb.c b/drivers/video/cyblafb.c
deleted file mode 100644
index 9704b73135f..00000000000
--- a/drivers/video/cyblafb.c
+++ /dev/null
@@ -1,1683 +0,0 @@
-/*
- * Frame buffer driver for Trident Cyberblade/i1 graphics core
- *
- * Copyright 2005 Knut Petersen <Knut_Petersen@t-online.de>
- *
- * CREDITS:
- * tridentfb.c by Jani Monoses
- * see files above for further credits
- *
- */
-
-#define CYBLAFB_DEBUG 0
-#define CYBLAFB_KD_GRAPHICS_QUIRK 1
-
-#define CYBLAFB_PIXMAPSIZE 8192
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fb.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <asm/types.h>
-#include <video/cyblafb.h>
-
-#define VERSION "0.62"
-
-struct cyblafb_par {
- u32 pseudo_pal[16];
- struct fb_ops ops;
-};
-
-static struct fb_fix_screeninfo cyblafb_fix __devinitdata = {
- .id = "CyBla",
- .type = FB_TYPE_PACKED_PIXELS,
- .xpanstep = 1,
- .ypanstep = 1,
- .ywrapstep = 1,
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .accel = FB_ACCEL_NONE,
-};
-
-static char *mode __devinitdata = NULL;
-static int bpp __devinitdata = 8;
-static int ref __devinitdata = 75;
-static int fp __devinitdata;
-static int crt __devinitdata;
-static int memsize __devinitdata;
-
-static int basestride;
-static int vesafb;
-static int nativex;
-static int center;
-static int stretch;
-static int pciwb = 1;
-static int pcirb = 1;
-static int pciwr = 1;
-static int pcirr = 1;
-static int disabled;
-static int verbosity;
-static int displaytype;
-
-static void __iomem *io_virt; // iospace virtual memory address
-
-module_param(mode, charp, 0);
-module_param(bpp, int, 0);
-module_param(ref, int, 0);
-module_param(fp, int, 0);
-module_param(crt, int, 0);
-module_param(nativex, int, 0);
-module_param(center, int, 0);
-module_param(stretch, int, 0);
-module_param(pciwb, int, 0);
-module_param(pcirb, int, 0);
-module_param(pciwr, int, 0);
-module_param(pcirr, int, 0);
-module_param(memsize, int, 0);
-module_param(verbosity, int, 0);
-
-//=========================================
-//
-// Well, we have to fix the upper layers.
-// Until this has been done, we work around
-// the bugs.
-//
-//=========================================
-
-#if (CYBLAFB_KD_GRAPHICS_QUIRK && CYBLAFB_DEBUG)
- if (disabled) { \
- printk("********\n");\
- dump_stack();\
- return val;\
- }
-
-#elif CYBLAFB_KD_GRAPHICS_QUIRK
-#define KD_GRAPHICS_RETURN(val)\
- if (disabled) {\
- return val;\
- }
-#else
-#define KD_GRAPHICS_RETURN(val)
-#endif
-
-//=========================================
-//
-// Port access macros for memory mapped io
-//
-//=========================================
-
-#define out8(r, v) writeb(v, io_virt + r)
-#define out32(r, v) writel(v, io_virt + r)
-#define in8(r) readb(io_virt + r)
-#define in32(r) readl(io_virt + r)
-
-//======================================
-//
-// Hardware access inline functions
-//
-//======================================
-
-static inline u8 read3X4(u32 reg)
-{
- out8(0x3D4, reg);
- return in8(0x3D5);
-}
-
-static inline u8 read3C4(u32 reg)
-{
- out8(0x3C4, reg);
- return in8(0x3C5);
-}
-
-static inline u8 read3CE(u32 reg)
-{
- out8(0x3CE, reg);
- return in8(0x3CF);
-}
-
-static inline void write3X4(u32 reg, u8 val)
-{
- out8(0x3D4, reg);
- out8(0x3D5, val);
-}
-
-static inline void write3C4(u32 reg, u8 val)
-{
- out8(0x3C4, reg);
- out8(0x3C5, val);
-}
-
-static inline void write3CE(u32 reg, u8 val)
-{
- out8(0x3CE, reg);
- out8(0x3CF, val);
-}
-
-static inline void write3C0(u32 reg, u8 val)
-{
- in8(0x3DA); // read to reset index
- out8(0x3C0, reg);
- out8(0x3C0, val);
-}
-
-//=================================================
-//
-// Enable memory mapped io and unprotect registers
-//
-//=================================================
-
-static void enable_mmio(void)
-{
- u8 tmp;
-
- outb(0x0B, 0x3C4);
- inb(0x3C5); // Set NEW mode
- outb(SR0E, 0x3C4); // write enable a lot of extended ports
- outb(0x80, 0x3C5);
-
- outb(SR11, 0x3C4); // write enable those extended ports that
- outb(0x87, 0x3C5); // are not affected by SR0E_New
-
- outb(CR1E, 0x3d4); // clear write protect bit for port 0x3c2
- tmp = inb(0x3d5) & 0xBF;
- outb(CR1E, 0x3d4);
- outb(tmp, 0x3d5);
-
- outb(CR39, 0x3D4);
- outb(inb(0x3D5) | 0x01, 0x3D5); // Enable mmio
-}
-
-//=================================================
-//
-// Set pixel clock VCLK1
-// - multipliers set elswhere
-// - freq in units of 0.01 MHz
-//
-// Hardware bug: SR18 >= 250 is broken for the
-// cyberblade/i1
-//
-//=================================================
-
-static void set_vclk(struct cyblafb_par *par, int freq)
-{
- u32 m, n, k;
- int f, fi, d, di;
- u8 lo = 0, hi = 0;
-
- d = 2000;
- k = freq >= 10000 ? 0 : freq >= 5000 ? 1 : freq >= 2500 ? 2 : 3;
- for (m = 0; m < 64; m++)
- for (n = 0; n < 250; n++) {
- fi = (int)(((5864727 * (n + 8)) /
- ((m + 2) * (1 << k))) >> 12);
- if ((di = abs(fi - freq)) < d) {
- d = di;
- f = fi;
- lo = (u8) n;
- hi = (u8) ((k << 6) | m);
- }
- }
- write3C4(SR19, hi);
- write3C4(SR18, lo);
- if (verbosity > 0)
- output("pixclock = %d.%02d MHz, k/m/n %x %x %x\n",
- freq / 100, freq % 100, (hi & 0xc0) >> 6, hi & 0x3f, lo);
-}
-
-//================================================
-//
-// Cyberblade specific Graphics Engine (GE) setup
-//
-//================================================
-
-static void cyblafb_setup_GE(int pitch, int bpp)
-{
- KD_GRAPHICS_RETURN();
-
- switch (bpp) {
- case 8:
- basestride = ((pitch >> 3) << 20) | (0 << 29);
- break;
- case 15:
- basestride = ((pitch >> 3) << 20) | (5 << 29);
- break;
- case 16:
- basestride = ((pitch >> 3) << 20) | (1 << 29);
- break;
- case 24:
- case 32:
- basestride = ((pitch >> 3) << 20) | (2 << 29);
- break;
- }
-
- write3X4(CR36, 0x90); // reset GE
- write3X4(CR36, 0x80); // enable GE
- out32(GE24, 1 << 7); // reset all GE pointers by toggling
- out32(GE24, 0); // d7 of GE24
- write3X4(CR2D, 0x00); // GE Timinigs, no delays
- out32(GE6C, 0); // Pattern and Style, p 129, ok
-}
-
-//=====================================================================
-//
-// Cyberblade specific syncing
-//
-// A timeout might be caused by disabled mmio.
-// Cause:
-// - bit CR39 & 1 == 0 upon return, X trident driver bug
-// - kdm bug (KD_GRAPHICS not set on first switch)
-// - kernel design flaw (it believes in the correctness
-// of kdm/X
-// First we try to sync ignoring that problem, as most of the
-// time that will succeed immediately and the enable_mmio()
-// would only degrade performance.
-//
-//=====================================================================
-
-static int cyblafb_sync(struct fb_info *info)
-{
- u32 status, i = 100000;
-
- KD_GRAPHICS_RETURN(0);
-
- while (((status = in32(GE20)) & 0xFe800000) && i != 0)
- i--;
-
- if (i == 0) {
- enable_mmio();
- i = 1000000;
- while (((status = in32(GE20)) & 0xFA800000) && i != 0)
- i--;
- if (i == 0) {
- output("GE Timeout, status: %x\n", status);
- if (status & 0x80000000)
- output("Bresenham Engine : Busy\n");
- if (status & 0x40000000)
- output("Setup Engine : Busy\n");
- if (status & 0x20000000)
- output("SP / DPE : Busy\n");
- if (status & 0x10000000)
- output("Memory Interface : Busy\n");
- if (status & 0x08000000)
- output("Com Lst Proc : Busy\n");
- if (status & 0x04000000)
- output("Block Write : Busy\n");
- if (status & 0x02000000)
- output("Command Buffer : Full\n");
- if (status & 0x01000000)
- output("RESERVED : Busy\n");
- if (status & 0x00800000)
- output("PCI Write Buffer : Busy\n");
- cyblafb_setup_GE(info->var.xres,
- info->var.bits_per_pixel);
- }
- }
-
- return 0;
-}
-
-//==============================
-//
-// Cyberblade specific fillrect
-//
-//==============================
-
-static void cyblafb_fillrect(struct fb_info *info, const struct fb_fillrect *fr)
-{
- u32 bpp = info->var.bits_per_pixel, col, desty, height;
-
- KD_GRAPHICS_RETURN();
-
- switch (bpp) {
- default:
- case 8:
- col = fr->color;
- col |= col << 8;
- col |= col << 16;
- break;
- case 16:
- col = ((u32 *) (info->pseudo_palette))[fr->color];
- col |= col << 16;
- break;
- case 32:
- col = ((u32 *) (info->pseudo_palette))[fr->color];
- break;
- }
-
- desty = fr->dy;
- height = fr->height;
- while (height) {
- out32(GEB8, basestride | ((desty * info->var.xres_virtual *
- bpp) >> 6));
- out32(GE60, col);
- out32(GE48, fr->rop ? 0x66 : ROP_S);
- out32(GE44, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
- out32(GE08, point(fr->dx, 0));
- out32(GE0C, point(fr->dx + fr->width - 1,
- height > 4096 ? 4095 : height - 1));
- if (likely(height <= 4096))
- return;
- desty += 4096;
- height -= 4096;
- }
-}
-
-//================================================
-//
-// Cyberblade specific copyarea
-//
-// This function silently assumes that it never
-// will be called with width or height exceeding
-// 4096.
-//
-//================================================
-
-static void cyblafb_copyarea(struct fb_info *info, const struct fb_copyarea *ca)
-{
- u32 s1, s2, d1, d2, direction;
-
- KD_GRAPHICS_RETURN();
-
- s1 = point(ca->sx, 0);
- s2 = point(ca->sx + ca->width - 1, ca->height - 1);
- d1 = point(ca->dx, 0);
- d2 = point(ca->dx + ca->width - 1, ca->height - 1);
-
- if ((ca->sy > ca->dy) || ((ca->sy == ca->dy) && (ca->sx > ca->dx)))
- direction = 0;
- else
- direction = 2;
-
- out32(GEB8, basestride | ((ca->dy * info->var.xres_virtual *
- info->var.bits_per_pixel) >> 6));
- out32(GEC8, basestride | ((ca->sy * info->var.xres_virtual *
- info->var.bits_per_pixel) >> 6));
- out32(GE44, 0xa0000000 | 1 << 19 | 1 << 2 | direction);
- out32(GE00, direction ? s2 : s1);
- out32(GE04, direction ? s1 : s2);
- out32(GE08, direction ? d2 : d1);
- out32(GE0C, direction ? d1 : d2);
-}
-
-//=======================================================================
-//
-// Cyberblade specific imageblit
-//
-// Accelerated for the most usual case, blitting 1 - bit deep
-// character images. Everything else is passed to the generic imageblit
-// unless it is so insane that it is better to printk an alert.
-//
-// Hardware bug: _Never_ blit across pixel column 2048, that will lock
-// the system. We split those blit requests into three blitting
-// operations.
-//
-//=======================================================================
-
-static void cyblafb_imageblit(struct fb_info *info,
- const struct fb_image *image)
-{
- u32 fgcol, bgcol;
- u32 *pd = (u32 *) image->data;
- u32 bpp = info->var.bits_per_pixel;
-
- KD_GRAPHICS_RETURN();
-
- // Used only for drawing the penguine (image->depth > 1)
- if (image->depth != 1) {
- cfb_imageblit(info, image);
- return;
- }
- // That should never happen, but it would be fatal
- if (image->width == 0 || image->height == 0) {
- output("imageblit: width/height 0 detected\n");
- return;
- }
-
- if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
- info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
- fgcol = ((u32 *) (info->pseudo_palette))[image->fg_color];
- bgcol = ((u32 *) (info->pseudo_palette))[image->bg_color];
- } else {
- fgcol = image->fg_color;
- bgcol = image->bg_color;
- }
-
- switch (bpp) {
- case 8:
- fgcol |= fgcol << 8;
- bgcol |= bgcol << 8;
- case 16:
- fgcol |= fgcol << 16;
- bgcol |= bgcol << 16;
- default:
- break;
- }
-
- out32(GEB8, basestride | ((image->dy * info->var.xres_virtual *
- bpp) >> 6));
- out32(GE60, fgcol);
- out32(GE64, bgcol);
-
- if (!(image->dx < 2048 && (image->dx + image->width - 1) >= 2048)) {
- u32 dds = ((image->width + 31) >> 5) * image->height;
- out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
- out32(GE08, point(image->dx, 0));
- out32(GE0C, point(image->dx + image->width - 1,
- image->height - 1));
- while (dds--)
- out32(GE9C, *pd++);
- } else {
- int i, j;
- u32 ddstotal = (image->width + 31) >> 5;
- u32 ddsleft = (2048 - image->dx + 31) >> 5;
- u32 skipleft = ddstotal - ddsleft;
-
- out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
- out32(GE08, point(image->dx, 0));
- out32(GE0C, point(2048 - 1, image->height - 1));
- for (i = 0; i < image->height; i++) {
- for (j = 0; j < ddsleft; j++)
- out32(GE9C, *pd++);
- pd += skipleft;
- }
-
- if (image->dx % 32) {
- out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
- out32(GE08, point(2048, 0));
- if (image->width > ddsleft << 5)
- out32(GE0C, point(image->dx + (ddsleft << 5) -
- 1, image->height - 1));
- else
- out32(GE0C, point(image->dx + image->width - 1,
- image->height - 1));
- pd = ((u32 *) image->data) + ddstotal - skipleft - 1;
- for (i = 0; i < image->height; i++) {
- out32(GE9C, swab32(swab32(*pd) << ((32 -
- (image->dx & 31)) & 31)));
- pd += ddstotal;
- }
- }
-
- if (skipleft) {
- out32(GE44, 0xa0000000 | 1 << 20 | 1 << 19);
- out32(GE08, point(image->dx + (ddsleft << 5), 0));
- out32(GE0C, point(image->dx + image->width - 1,
- image->height - 1));
- pd = (u32 *) image->data;
- for (i = 0; i < image->height; i++) {
- pd += ddsleft;
- for (j = 0; j < skipleft; j++)
- out32(GE9C, *pd++);
- }
- }
- }
-}
-
-//==========================================================
-//
-// Check if video mode is acceptable. We change var->??? if
-// video mode is slightly off or return error otherwise.
-// info->??? must not be changed!
-//
-//==========================================================
-
-static int cyblafb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- int bpp = var->bits_per_pixel;
-
- //
- // we try to support 8, 16, 24 and 32 bpp modes,
- // default to 8
- //
- // there is a 24 bpp mode, but for now we change requests to 32 bpp
- // (This is what tridentfb does ... will be changed in the future)
- //
- //
- if (bpp % 8 != 0 || bpp < 8 || bpp > 32)
- bpp = 8;
- if (bpp == 24)
- bpp = var->bits_per_pixel = 32;
-
- //
- // interlaced modes are broken, fail if one is requested
- //
- if (var->vmode & FB_VMODE_INTERLACED)
- return -EINVAL;
-
- //
- // fail if requested resolution is higher than physical
- // flatpanel resolution
- //
- if ((displaytype == DISPLAY_FP) && nativex && var->xres > nativex)
- return -EINVAL;
-
- //
- // we do not allow vclk to exceed 230 MHz. If the requested
- // vclk is too high, we default to 200 MHz
- //
- if ((bpp == 32 ? 200000000 : 100000000) / var->pixclock > 23000)
- var->pixclock = (bpp == 32 ? 200000000 : 100000000) / 20000;
-
- //
- // enforce (h|v)sync_len limits
- //
- var->hsync_len &= ~7;
- if(var->hsync_len > 248)
- var->hsync_len = 248;
-
- var->vsync_len &= 15;
-
- //
- // Enforce horizontal and vertical hardware limits.
- // 1600x1200 is mentioned as a maximum, but higher resolutions could
- // work with slow refresh, small margins and short sync.
- //
- var->xres &= ~7;
-
- if (((var->xres + var->left_margin + var->right_margin +
- var->hsync_len) > (bpp == 32 ? 2040 : 4088)) ||
- ((var->yres + var->upper_margin + var->lower_margin +
- var->vsync_len) > 2047))
- return -EINVAL;
-
- if ((var->xres > 1600) || (var->yres > 1200))
- output("Mode %dx%d exceeds documented limits.\n",
- var->xres, var->yres);
- //
- // try to be smart about (x|y)res_virtual problems.
- //
- if (var->xres > var->xres_virtual)
- var->xres_virtual = var->xres;
- if (var->yres > var->yres_virtual)
- var->yres_virtual = var->yres;
-
- if (bpp == 8 || bpp == 16) {
- if (var->xres_virtual > 4088)
- var->xres_virtual = 4088;
- } else {
- if (var->xres_virtual > 2040)
- var->xres_virtual = 2040;
- }
- var->xres_virtual &= ~7;
- while (var->xres_virtual * var->yres_virtual * bpp / 8 >
- info->fix.smem_len) {
- if (var->yres_virtual > var->yres)
- var->yres_virtual--;
- else if (var->xres_virtual > var->xres)
- var->xres_virtual -= 8;
- else
- return -EINVAL;
- }
-
- switch (bpp) {
- case 8:
- var->red.offset = 0;
- var->green.offset = 0;
- var->blue.offset = 0;
- var->red.length = 6;
- var->green.length = 6;
- var->blue.length = 6;
- break;
- case 16:
- var->red.offset = 11;
- var->green.offset = 5;
- var->blue.offset = 0;
- var->red.length = 5;
- var->green.length = 6;
- var->blue.length = 5;
- break;
- case 32:
- var->red.offset = 16;
- var->green.offset = 8;
- var->blue.offset = 0;
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- break;
- default:
- return -EINVAL;
- }
-
- return 0;
-}
-
-//=====================================================================
-//
-// Pan the display
-//
-// The datasheets defines crt start address to be 20 bits wide and
-// to be programmed to CR0C, CR0D, CR1E and CR27. Actually there is
-// CR2B[5] as an undocumented extension bit. Epia BIOS 2.07 does use
-// it, so it is also safe to be used here. BTW: datasheet CR0E on page
-// 90 really is CR1E, the real CRE is documented on page 72.
-//
-// BUT:
-//
-// As of internal version 0.60 we do not use vga panning any longer.
-// Vga panning did not allow us the use of all available video memory
-// and thus prevented ywrap scrolling. We do use the "right view"
-// register now.
-//
-//
-//=====================================================================
-
-static int cyblafb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info)
-{
- KD_GRAPHICS_RETURN(0);
-
- info->var.xoffset = var->xoffset;
- info->var.yoffset = var->yoffset;
- out32(GE10, 0x80000000 | ((var->xoffset + (var->yoffset *
- var->xres_virtual)) * var->bits_per_pixel / 32));
- return 0;
-}
-
-//============================================
-//
-// This will really help in case of a bug ...
-// dump most gaphics core registers.
-//
-//============================================
-
-static void regdump(struct cyblafb_par *par)
-{
- int i;
-
- if (verbosity < 2)
- return;
-
- printk("\n");
- for (i = 0; i <= 0xff; i++) {
- outb(i, 0x3d4);
- printk("CR%02x=%02x ", i, inb(0x3d5));
- if (i % 16 == 15)
- printk("\n");
- }
-
- outb(0x30, 0x3ce);
- outb(inb(0x3cf) | 0x40, 0x3cf);
- for (i = 0; i <= 0x1f; i++) {
- if (i == 0 || (i > 2 && i < 8) || i == 0x10 || i == 0x11
- || i == 0x16) {
- outb(i, 0x3d4);
- printk("CR%02x=%02x ", i, inb(0x3d5));
- } else
- printk("------- ");
- if (i % 16 == 15)
- printk("\n");
- }
- outb(0x30, 0x3ce);
- outb(inb(0x3cf) & 0xbf, 0x3cf);
-
- printk("\n");
- for (i = 0; i <= 0x7f; i++) {
- outb(i, 0x3ce);
- printk("GR%02x=%02x ", i, inb(0x3cf));
- if (i % 16 == 15)
- printk("\n");
- }
-
- printk("\n");
- for (i = 0; i <= 0xff; i++) {
- outb(i, 0x3c4);
- printk("SR%02x=%02x ", i, inb(0x3c5));
- if (i % 16 == 15)
- printk("\n");
- }
-
- printk("\n");
- for (i = 0; i <= 0x1F; i++) {
- inb(0x3da); // next access is index!
- outb(i, 0x3c0);
- printk("AR%02x=%02x ", i, inb(0x3c1));
- if (i % 16 == 15)
- printk("\n");
- }
- printk("\n");
-
- inb(0x3DA); // reset internal flag to 3c0 index
- outb(0x20, 0x3C0); // enable attr
-
- return;
-}
-
-//=======================================================================
-//
-// Save State
-//
-// This function is called while a switch to KD_TEXT is in progress,
-// before any of the other functions are called.
-//
-//=======================================================================
-
-static void cyblafb_save_state(struct fb_info *info)
-{
- struct cyblafb_par *par = info->par;
- if (verbosity > 0)
- output("Switching to KD_TEXT\n");
- disabled = 0;
- regdump(par);
- enable_mmio();
- return;
-}
-
-//=======================================================================
-//
-// Restore State
-//
-// This function is called while a switch to KD_GRAPHICS is in progress,
-// We have to turn on vga style panning registers again because the
-// trident driver of X does not know about GE10.
-//
-//=======================================================================
-
-static void cyblafb_restore_state(struct fb_info *info)
-{
- if (verbosity > 0)
- output("Switching to KD_GRAPHICS\n");
- out32(GE10, 0);
- disabled = 1;
- return;
-}
-
-//======================================
-//
-// Set hardware to requested video mode
-//
-//======================================
-
-static int cyblafb_set_par(struct fb_info *info)
-{
- struct cyblafb_par *par = info->par;
- u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart,
- hblankend, preendfetch, vtotal, vdispend, vsyncstart,
- vsyncend, vblankstart, vblankend;
- struct fb_var_screeninfo *var = &info->var;
- int bpp = var->bits_per_pixel;
- int i;
-
- KD_GRAPHICS_RETURN(0);
-
- if (verbosity > 0)
- output("Switching to new mode: "
- "fbset -g %d %d %d %d %d -t %d %d %d %d %d %d %d\n",
- var->xres, var->yres, var->xres_virtual,
- var->yres_virtual, var->bits_per_pixel, var->pixclock,
- var->left_margin, var->right_margin, var->upper_margin,
- var->lower_margin, var->hsync_len, var->vsync_len);
-
- htotal = (var->xres + var->left_margin + var->right_margin +
- var->hsync_len) / 8 - 5;
- hdispend = var->xres / 8 - 1;
- hsyncstart = (var->xres + var->right_margin) / 8;
- hsyncend = var->hsync_len / 8;
- hblankstart = hdispend + 1;
- hblankend = htotal + 3; // should be htotal + 5, bios does it this way
- preendfetch = ((var->xres >> 3) + 1) * ((bpp + 1) >> 3);
-
- vtotal = var->yres + var->upper_margin + var->lower_margin +
- var->vsync_len - 2;
- vdispend = var->yres - 1;
- vsyncstart = var->yres + var->lower_margin;
- vblankstart = var->yres;
- vblankend = vtotal; // should be vtotal + 2, but bios does it this way
- vsyncend = var->vsync_len;
-
- enable_mmio(); // necessary! ... check X ...
-
- write3X4(CR11, read3X4(CR11) & 0x7F); // unlock cr00 .. cr07
-
- write3CE(GR30, 8);
-
- if ((displaytype == DISPLAY_FP) && var->xres < nativex) {
-
- // stretch or center ?
-
- out8(0x3C2, 0xEB);
-
- write3CE(GR30, read3CE(GR30) | 0x81); // shadow mode on
-
- if (center) {
- write3CE(GR52, (read3CE(GR52) & 0x7C) | 0x80);
- write3CE(GR53, (read3CE(GR53) & 0x7C) | 0x80);
- } else if (stretch) {
- write3CE(GR5D, 0);
- write3CE(GR52, (read3CE(GR52) & 0x7C) | 1);
- write3CE(GR53, (read3CE(GR53) & 0x7C) | 1);
- }
-
- } else {
- out8(0x3C2, 0x2B);
- write3CE(GR30, 8);
- }
-
- //
- // Setup CRxx regs
- //
-
- write3X4(CR00, htotal & 0xFF);
- write3X4(CR01, hdispend & 0xFF);
- write3X4(CR02, hblankstart & 0xFF);
- write3X4(CR03, hblankend & 0x1F);
- write3X4(CR04, hsyncstart & 0xFF);
- write3X4(CR05, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
- write3X4(CR06, vtotal & 0xFF);
- write3X4(CR07, (vtotal & 0x100) >> 8 |
- (vdispend & 0x100) >> 7 |
- (vsyncstart & 0x100) >> 6 |
- (vblankstart & 0x100) >> 5 |
- 0x10 |
- (vtotal & 0x200) >> 4 |
- (vdispend & 0x200) >> 3 | (vsyncstart & 0x200) >> 2);
- write3X4(CR08, 0);
- write3X4(CR09, (vblankstart & 0x200) >> 4 | 0x40 | // FIX !!!
- ((info->var.vmode & FB_VMODE_DOUBLE) ? 0x80 : 0));
- write3X4(CR0A, 0); // Init to some reasonable default
- write3X4(CR0B, 0); // Init to some reasonable default
- write3X4(CR0C, 0); // Offset 0
- write3X4(CR0D, 0); // Offset 0
- write3X4(CR0E, 0); // Init to some reasonable default
- write3X4(CR0F, 0); // Init to some reasonable default
- write3X4(CR10, vsyncstart & 0xFF);
- write3X4(CR11, (vsyncend & 0x0F));
- write3X4(CR12, vdispend & 0xFF);
- write3X4(CR13, ((info->var.xres_virtual * bpp) / (4 * 16)) & 0xFF);
- write3X4(CR14, 0x40); // double word mode
- write3X4(CR15, vblankstart & 0xFF);
- write3X4(CR16, vblankend & 0xFF);
- write3X4(CR17, 0xE3);
- write3X4(CR18, 0xFF);
- // CR19: needed for interlaced modes ... ignore it for now
- write3X4(CR1A, 0x07); // Arbitration Control Counter 1
- write3X4(CR1B, 0x07); // Arbitration Control Counter 2
- write3X4(CR1C, 0x07); // Arbitration Control Counter 3
- write3X4(CR1D, 0x00); // Don't know, doesn't hurt ; -)
- write3X4(CR1E, (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80);
- // CR1F: do not set, contains BIOS info about memsize
- write3X4(CR20, 0x20); // enabe wr buf, disable 16bit planar mode
- write3X4(CR21, 0x20); // enable linear memory access
- // CR22: RO cpu latch readback
- // CR23: ???
- // CR24: RO AR flag state
- // CR25: RAMDAC rw timing, pclk buffer tristate control ????
- // CR26: ???
- write3X4(CR27, (vdispend & 0x400) >> 6 |
- (vsyncstart & 0x400) >> 5 |
- (vblankstart & 0x400) >> 4 |
- (vtotal & 0x400) >> 3 |
- 0x8);
- // CR28: ???
- write3X4(CR29, (read3X4(CR29) & 0xCF) | ((((info->var.xres_virtual *
- bpp) / (4 * 16)) & 0x300) >> 4));
- write3X4(CR2A, read3X4(CR2A) | 0x40);
- write3X4(CR2B, (htotal & 0x100) >> 8 |
- (hdispend & 0x100) >> 7 |
- // (0x00 & 0x100) >> 6 | hinterlace para bit 8 ???
- (hsyncstart & 0x100) >> 5 |
- (hblankstart & 0x100) >> 4);
- // CR2C: ???
- // CR2D: initialized in cyblafb_setup_GE()
- write3X4(CR2F, 0x92); // conservative, better signal quality
- // CR30: reserved
- // CR31: reserved
- // CR32: reserved
- // CR33: reserved
- // CR34: disabled in CR36
- // CR35: disabled in CR36
- // CR36: initialized in cyblafb_setup_GE
- // CR37: i2c, ignore for now
- write3X4(CR38, (bpp == 8) ? 0x00 : //
- (bpp == 16) ? 0x05 : // highcolor
- (bpp == 24) ? 0x29 : // packed 24bit truecolor
- (bpp == 32) ? 0x09 : 0); // truecolor, 16 bit pixelbus
- write3X4(CR39, 0x01 | // MMIO enable
- (pcirb ? 0x02 : 0) | // pci read burst enable
- (pciwb ? 0x04 : 0)); // pci write burst enable
- write3X4(CR55, 0x1F | // pci clocks * 2 for STOP# during 1st data phase
- (pcirr ? 0x40 : 0) | // pci read retry enable
- (pciwr ? 0x80 : 0)); // pci write retry enable
- write3X4(CR56, preendfetch >> 8 < 2 ? (preendfetch >> 8 & 0x01) | 2
- : 0);
- write3X4(CR57, preendfetch >> 8 < 2 ? preendfetch & 0xff : 0);
- write3X4(CR58, 0x82); // Bios does this .... don't know more
- //
- // Setup SRxx regs
- //
- write3C4(SR00, 3);
- write3C4(SR01, 1); //set char clock 8 dots wide
- write3C4(SR02, 0x0F); //enable 4 maps needed in chain4 mode
- write3C4(SR03, 0); //no character map select
- write3C4(SR04, 0x0E); //memory mode: ext mem, even, chain4
-
- out8(0x3C4, 0x0b);
- in8(0x3C5); // Set NEW mode
- write3C4(SR0D, 0x00); // test ... check
-
- set_vclk(par, (bpp == 32 ? 200000000 : 100000000)
- / info->var.pixclock); //SR18, SR19
-
- //
- // Setup GRxx regs
- //
- write3CE(GR00, 0x00); // test ... check
- write3CE(GR01, 0x00); // test ... check
- write3CE(GR02, 0x00); // test ... check
- write3CE(GR03, 0x00); // test ... check
- write3CE(GR04, 0x00); // test ... check
- write3CE(GR05, 0x40); // no CGA compat, allow 256 col
- write3CE(GR06, 0x05); // graphics mode
- write3CE(GR07, 0x0F); // planes?
- write3CE(GR08, 0xFF); // test ... check
- write3CE(GR0F, (bpp == 32) ? 0x1A : 0x12); // vclk / 2 if 32bpp, chain4
- write3CE(GR20, 0xC0); // test ... check
- write3CE(GR2F, 0xA0); // PCLK = VCLK, no skew,
-
- //
- // Setup ARxx regs
- //
- for (i = 0; i < 0x10; i++) // set AR00 .. AR0f
- write3C0(i, i);
- write3C0(AR10, 0x41); // graphics mode and support 256 color modes
- write3C0(AR12, 0x0F); // planes
- write3C0(AR13, 0); // horizontal pel panning
- in8(0x3DA); // reset internal flag to 3c0 index
- out8(0x3C0, 0x20); // enable attr
-
- //
- // Setup hidden RAMDAC command register
- //
- in8(0x3C8); // these reads are
- in8(0x3C6); // necessary to
- in8(0x3C6); // unmask the RAMDAC
- in8(0x3C6); // command reg, otherwise
- in8(0x3C6); // we would write the pixelmask reg!
- out8(0x3C6, (bpp == 8) ? 0x00 : // 256 colors
- (bpp == 15) ? 0x10 : //
- (bpp == 16) ? 0x30 : // hicolor
- (bpp == 24) ? 0xD0 : // truecolor
- (bpp == 32) ? 0xD0 : 0); // truecolor
- in8(0x3C8);
-
- //
- // GR31 is not mentioned in the datasheet
- //
- if (displaytype == DISPLAY_FP)
- write3CE(GR31, (read3CE(GR31) & 0x8F) |
- ((info->var.yres > 1024) ? 0x50 :
- (info->var.yres > 768) ? 0x30 :
- (info->var.yres > 600) ? 0x20 :
- (info->var.yres > 480) ? 0x10 : 0));
-
- info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_TRUECOLOR;
- info->fix.line_length = info->var.xres_virtual * (bpp >> 3);
- info->cmap.len = (bpp == 8) ? 256 : 16;
-
- //
- // init acceleration engine
- //
- cyblafb_setup_GE(info->var.xres_virtual, info->var.bits_per_pixel);
-
- //
- // Set/clear flags to allow proper scroll mode selection.
- //
- if (var->xres == var->xres_virtual)
- info->flags &= ~FBINFO_HWACCEL_XPAN;
- else
- info->flags |= FBINFO_HWACCEL_XPAN;
-
- if (var->yres == var->yres_virtual)
- info->flags &= ~FBINFO_HWACCEL_YPAN;
- else
- info->flags |= FBINFO_HWACCEL_YPAN;
-
- if (info->fix.smem_len !=
- var->xres_virtual * var->yres_virtual * bpp / 8)
- info->flags &= ~FBINFO_HWACCEL_YWRAP;
- else
- info->flags |= FBINFO_HWACCEL_YWRAP;
-
- regdump(par);
-
- return 0;
-}
-
-//========================
-//
-// Set one color register
-//
-//========================
-
-static int cyblafb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- int bpp = info->var.bits_per_pixel;
-
- KD_GRAPHICS_RETURN(0);
-
- if (regno >= info->cmap.len)
- return 1;
-
- if (bpp == 8) {
- out8(0x3C6, 0xFF);
- out8(0x3C8, regno);
- out8(0x3C9, red >> 10);
- out8(0x3C9, green >> 10);
- out8(0x3C9, blue >> 10);
-
- } else if (regno < 16) {
- if (bpp == 16) // RGB 565
- ((u32 *) info->pseudo_palette)[regno] =
- (red & 0xF800) |
- ((green & 0xFC00) >> 5) |
- ((blue & 0xF800) >> 11);
- else if (bpp == 32) // ARGB 8888
- ((u32 *) info->pseudo_palette)[regno] =
- ((transp & 0xFF00) << 16) |
- ((red & 0xFF00) << 8) |
- ((green & 0xFF00)) | ((blue & 0xFF00) >> 8);
- }
-
- return 0;
-}
-
-//==========================================================
-//
-// Try blanking the screen. For flat panels it does nothing
-//
-//==========================================================
-
-static int cyblafb_blank(int blank_mode, struct fb_info *info)
-{
- unsigned char PMCont, DPMSCont;
-
- KD_GRAPHICS_RETURN(0);
-
- if (displaytype == DISPLAY_FP)
- return 0;
-
- out8(0x83C8, 0x04); // DPMS Control
- PMCont = in8(0x83C6) & 0xFC;
-
- DPMSCont = read3CE(GR23) & 0xFC;
-
- switch (blank_mode) {
- case FB_BLANK_UNBLANK: // Screen: On, HSync: On, VSync: On
- case FB_BLANK_NORMAL: // Screen: Off, HSync: On, VSync: On
- PMCont |= 0x03;
- DPMSCont |= 0x00;
- break;
- case FB_BLANK_HSYNC_SUSPEND: // Screen: Off, HSync: Off, VSync: On
- PMCont |= 0x02;
- DPMSCont |= 0x01;
- break;
- case FB_BLANK_VSYNC_SUSPEND: // Screen: Off, HSync: On, VSync: Off
- PMCont |= 0x02;
- DPMSCont |= 0x02;
- break;
- case FB_BLANK_POWERDOWN: // Screen: Off, HSync: Off, VSync: Off
- PMCont |= 0x00;
- DPMSCont |= 0x03;
- break;
- }
-
- write3CE(GR23, DPMSCont);
- out8(0x83C8, 4);
- out8(0x83C6, PMCont);
- //
- // let fbcon do a softblank for us
- //
- return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
-}
-
-static struct fb_ops cyblafb_ops __devinitdata = {
- .owner = THIS_MODULE,
- .fb_setcolreg = cyblafb_setcolreg,
- .fb_pan_display = cyblafb_pan_display,
- .fb_blank = cyblafb_blank,
- .fb_check_var = cyblafb_check_var,
- .fb_set_par = cyblafb_set_par,
- .fb_fillrect = cyblafb_fillrect,
- .fb_copyarea = cyblafb_copyarea,
- .fb_imageblit = cyblafb_imageblit,
- .fb_sync = cyblafb_sync,
- .fb_restore_state = cyblafb_restore_state,
- .fb_save_state = cyblafb_save_state,
-};
-
-//==========================================================================
-//
-// getstartupmode() decides about the inital video mode
-//
-// There is no reason to use modedb, a lot of video modes there would
-// need altered timings to display correctly. So I decided that it is much
-// better to provide a limited optimized set of modes plus the option of
-// using the mode in effect at startup time (might be selected using the
-// vga=??? parameter). After that the user might use fbset to select any
-// mode he likes, check_var will not try to alter geometry parameters as
-// it would be necessary otherwise.
-//
-//==========================================================================
-
-static int __devinit getstartupmode(struct fb_info *info)
-{
- u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend,
- vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend,
- cr00, cr01, cr02, cr03, cr04, cr05, cr2b,
- cr06, cr07, cr09, cr10, cr11, cr12, cr15, cr16, cr27,
- cr38, sr0d, sr18, sr19, gr0f, fi, pxclkdiv, vclkdiv, tmp, i;
-
- struct modus {
- int xres; int vxres; int yres; int vyres;
- int bpp; int pxclk;
- int left_margin; int right_margin;
- int upper_margin; int lower_margin;
- int hsync_len; int vsync_len;
- } modedb[5] = {
- {
- 0, 2048, 0, 4096, 0, 0, 0, 0, 0, 0, 0, 0}, {
- 640, 2048, 480, 4096, 0, 0, -40, 24, 17, 0, 216, 3}, {
- 800, 2048, 600, 4096, 0, 0, 96, 24, 14, 0, 136, 11}, {
- 1024, 2048, 768, 4096, 0, 0, 144, 24, 29, 0, 120, 3}, {
- 1280, 2048, 1024, 4096, 0, 0, 232, 16, 39, 0, 160, 3}
- };
-
- outb(0x00, 0x3d4); cr00 = inb(0x3d5);
- outb(0x01, 0x3d4); cr01 = inb(0x3d5);
- outb(0x02, 0x3d4); cr02 = inb(0x3d5);
- outb(0x03, 0x3d4); cr03 = inb(0x3d5);
- outb(0x04, 0x3d4); cr04 = inb(0x3d5);
- outb(0x05, 0x3d4); cr05 = inb(0x3d5);
- outb(0x06, 0x3d4); cr06 = inb(0x3d5);
- outb(0x07, 0x3d4); cr07 = inb(0x3d5);
- outb(0x09, 0x3d4); cr09 = inb(0x3d5);
- outb(0x10, 0x3d4); cr10 = inb(0x3d5);
- outb(0x11, 0x3d4); cr11 = inb(0x3d5);
- outb(0x12, 0x3d4); cr12 = inb(0x3d5);
- outb(0x15, 0x3d4); cr15 = inb(0x3d5);
- outb(0x16, 0x3d4); cr16 = inb(0x3d5);
- outb(0x27, 0x3d4); cr27 = inb(0x3d5);
- outb(0x2b, 0x3d4); cr2b = inb(0x3d5);
- outb(0x38, 0x3d4); cr38 = inb(0x3d5);
-
- outb(0x0b, 0x3c4);
- inb(0x3c5);
-
- outb(0x0d, 0x3c4); sr0d = inb(0x3c5);
- outb(0x18, 0x3c4); sr18 = inb(0x3c5);
- outb(0x19, 0x3c4); sr19 = inb(0x3c5);
- outb(0x0f, 0x3ce); gr0f = inb(0x3cf);
-
- htotal = cr00 | (cr2b & 0x01) << 8;
- hdispend = cr01 | (cr2b & 0x02) << 7;
- hblankstart = cr02 | (cr2b & 0x10) << 4;
- hblankend = (cr03 & 0x1f) | (cr05 & 0x80) >> 2;
- hsyncstart = cr04 | (cr2b & 0x08) << 5;
- hsyncend = cr05 & 0x1f;
-
- modedb[0].xres = hblankstart * 8;
- modedb[0].hsync_len = hsyncend * 8;
- modedb[0].right_margin = hsyncstart * 8 - modedb[0].xres;
- modedb[0].left_margin = (htotal + 5) * 8 - modedb[0].xres -
- modedb[0].right_margin - modedb[0].hsync_len;
-
- vtotal = cr06 | (cr07 & 0x01) << 8 | (cr07 & 0x20) << 4
- | (cr27 & 0x80) << 3;
- vdispend = cr12 | (cr07 & 0x02) << 7 | (cr07 & 0x40) << 3
- | (cr27 & 0x10) << 6;
- vsyncstart = cr10 | (cr07 & 0x04) << 6 | (cr07 & 0x80) << 2
- | (cr27 & 0x20) << 5;
- vsyncend = cr11 & 0x0f;
- vblankstart = cr15 | (cr07 & 0x08) << 5 | (cr09 & 0x20) << 4
- | (cr27 & 0x40) << 4;
- vblankend = cr16;
-
- modedb[0].yres = vdispend + 1;
- modedb[0].vsync_len = vsyncend;
- modedb[0].lower_margin = vsyncstart - modedb[0].yres;
- modedb[0].upper_margin = vtotal - modedb[0].yres -
- modedb[0].lower_margin - modedb[0].vsync_len + 2;
-
- tmp = cr38 & 0x3c;
- modedb[0].bpp = tmp == 0 ? 8 : tmp == 4 ? 16 : tmp == 28 ? 24 :
- tmp == 8 ? 32 : 8;
-
- fi = ((5864727 * (sr18 + 8)) /
- (((sr19 & 0x3f) + 2) * (1 << ((sr19 & 0xc0) >> 6)))) >> 12;
- pxclkdiv = ((gr0f & 0x08) >> 3 | (gr0f & 0x40) >> 5) + 1;
- tmp = sr0d & 0x06;
- vclkdiv = tmp == 0 ? 2 : tmp == 2 ? 4 : tmp == 4 ? 8 : 3; // * 2 !
- modedb[0].pxclk = ((100000000 * pxclkdiv * vclkdiv) >> 1) / fi;
-
- if (verbosity > 0)
- output("detected startup mode: "
- "fbset -g %d %d %d ??? %d -t %d %d %d %d %d %d %d\n",
- modedb[0].xres, modedb[0].yres, modedb[0].xres,
- modedb[0].bpp, modedb[0].pxclk, modedb[0].left_margin,
- modedb[0].right_margin, modedb[0].upper_margin,
- modedb[0].lower_margin, modedb[0].hsync_len,
- modedb[0].vsync_len);
-
- //
- // We use this goto target in case of a failed check_var. No, I really
- // do not want to do it in another way!
- //
-
- tryagain:
-
- i = (mode == NULL) ? 0 :
- !strncmp(mode, "640x480", 7) ? 1 :
- !strncmp(mode, "800x600", 7) ? 2 :
- !strncmp(mode, "1024x768", 8) ? 3 :
- !strncmp(mode, "1280x1024", 9) ? 4 : 0;
-
- ref = (ref < 50) ? 50 : (ref > 85) ? 85 : ref;
-
- if (i == 0) {
- info->var.pixclock = modedb[i].pxclk;
- info->var.bits_per_pixel = modedb[i].bpp;
- } else {
- info->var.pixclock = (100000000 /
- ((modedb[i].left_margin +
- modedb[i].xres +
- modedb[i].right_margin +
- modedb[i].hsync_len) *
- (modedb[i].upper_margin +
- modedb[i].yres +
- modedb[i].lower_margin +
- modedb[i].vsync_len) * ref / 10000));
- info->var.bits_per_pixel = bpp;
- }
-
- info->var.left_margin = modedb[i].left_margin;
- info->var.right_margin = modedb[i].right_margin;
- info->var.xres = modedb[i].xres;
- if (!(modedb[i].yres == 1280 && modedb[i].bpp == 32))
- info->var.xres_virtual = modedb[i].vxres;
- else
- info->var.xres_virtual = modedb[i].xres;
- info->var.xoffset = 0;
- info->var.hsync_len = modedb[i].hsync_len;
- info->var.upper_margin = modedb[i].upper_margin;
- info->var.yres = modedb[i].yres;
- info->var.yres_virtual = modedb[i].vyres;
- info->var.yoffset = 0;
- info->var.lower_margin = modedb[i].lower_margin;
- info->var.vsync_len = modedb[i].vsync_len;
- info->var.sync = 0;
- info->var.vmode = FB_VMODE_NONINTERLACED;
-
- if (cyblafb_check_var(&info->var, info)) {
- // 640x480 - 8@75 should really never fail. One case would
- // be fp == 1 and nativex < 640 ... give up then
- if (i == 1 && bpp == 8 && ref == 75) {
- output("Can't find a valid mode :-(\n");
- return -EINVAL;
- }
- // Our detected mode is unlikely to fail. If it does,
- // try 640x480 - 8@75 ...
- if (i == 0) {
- mode = "640x480";
- bpp = 8;
- ref = 75;
- output("Detected mode failed check_var! "
- "Trying 640x480 - 8@75\n");
- goto tryagain;
- }
- // A specified video mode failed for some reason.
- // Try the startup mode first
- output("Specified mode '%s' failed check! "
- "Falling back to startup mode.\n", mode);
- mode = NULL;
- goto tryagain;
- }
-
- return 0;
-}
-
-//========================================================
-//
-// Detect activated memory size. Undefined values require
-// memsize parameter.
-//
-//========================================================
-
-static unsigned int __devinit get_memsize(void)
-{
- unsigned char tmp;
- unsigned int k;
-
- if (memsize)
- k = memsize * Kb;
- else {
- tmp = read3X4(CR1F) & 0x0F;
- switch (tmp) {
- case 0x03:
- k = 1 * 1024 * 1024;
- break;
- case 0x07:
- k = 2 * 1024 * 1024;
- break;
- case 0x0F:
- k = 4 * 1024 * 1024;
- break;
- case 0x04:
- k = 8 * 1024 * 1024;
- break;
- default:
- k = 1 * 1024 * 1024;
- output("Unknown memory size code %x in CR1F."
- " We default to 1 Mb for now, please"
- " do provide a memsize parameter!\n", tmp);
- }
- }
-
- if (verbosity > 0)
- output("framebuffer size = %d Kb\n", k / Kb);
- return k;
-}
-
-//=========================================================
-//
-// Detect if a flat panel monitor connected to the special
-// interface is active. Override is possible by fp and crt
-// parameters.
-//
-//=========================================================
-
-static unsigned int __devinit get_displaytype(void)
-{
- if (fp)
- return DISPLAY_FP;
- if (crt)
- return DISPLAY_CRT;
- return (read3CE(GR33) & 0x10) ? DISPLAY_FP : DISPLAY_CRT;
-}
-
-//=====================================
-//
-// Get native resolution of flat panel
-//
-//=====================================
-
-static int __devinit get_nativex(void)
-{
- int x, y, tmp;
-
- if (nativex)
- return nativex;
-
- tmp = (read3CE(GR52) >> 4) & 3;
-
- switch (tmp) {
- case 0: x = 1280; y = 1024;
- break;
- case 2: x = 1024; y = 768;
- break;
- case 3: x = 800; y = 600;
- break;
- case 4: x = 1400; y = 1050;
- break;
- case 1:
- default:
- x = 640; y = 480;
- break;
- }
-
- if (verbosity > 0)
- output("%dx%d flat panel found\n", x, y);
- return x;
-}
-
-static int __devinit cybla_pci_probe(struct pci_dev *dev,
- const struct pci_device_id *id)
-{
- struct fb_info *info;
- struct cyblafb_par *par;
-
- info = framebuffer_alloc(sizeof(struct cyblafb_par), &dev->dev);
- if (!info)
- goto errout_alloc_info;
-
- info->pixmap.addr = kzalloc(CYBLAFB_PIXMAPSIZE, GFP_KERNEL);
- if (!info->pixmap.addr) {
- output("allocation of pixmap buffer failed!\n");
- goto errout_alloc_pixmap;
- }
- info->pixmap.size = CYBLAFB_PIXMAPSIZE - 4;
- info->pixmap.buf_align = 4;
- info->pixmap.access_align = 32;
- info->pixmap.flags = FB_PIXMAP_SYSTEM;
- info->pixmap.scan_align = 4;
-
- par = info->par;
- par->ops = cyblafb_ops;
-
- info->fix = cyblafb_fix;
- info->fbops = &par->ops;
- info->fix = cyblafb_fix;
-
- if (pci_enable_device(dev)) {
- output("could not enable device!\n");
- goto errout_enable;
- }
- // might already be requested by vga console or vesafb,
- // so we do care about success
- if (!request_region(0x3c0, 0x20, "cyblafb")) {
- output("region 0x3c0/0x20 already reserved\n");
- vesafb |= 1;
-
- }
- //
- // Graphics Engine Registers
- //
- if (!request_region(GEBase, 0x100, "cyblafb")) {
- output("region %#x/0x100 already reserved\n", GEBase);
- vesafb |= 2;
- }
-
- regdump(par);
-
- enable_mmio();
-
- // setup MMIO region
- info->fix.mmio_start = pci_resource_start(dev, 1);
- info->fix.mmio_len = 0x20000;
-
- if (!request_mem_region(info->fix.mmio_start,
- info->fix.mmio_len, "cyblafb")) {
- output("request_mem_region failed for mmio region!\n");
- goto errout_mmio_reqmem;
- }
-
- io_virt = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
-
- if (!io_virt) {
- output("ioremap failed for mmio region\n");
- goto errout_mmio_remap;
- }
- // setup framebuffer memory ... might already be requested
- // by vesafb. Not to fail in case of an unsuccessful request
- // is useful if both are loaded.
- info->fix.smem_start = pci_resource_start(dev, 0);
- info->fix.smem_len = get_memsize();
-
- if (!request_mem_region(info->fix.smem_start,
- info->fix.smem_len, "cyblafb")) {
- output("region %#lx/%#x already reserved\n",
- info->fix.smem_start, info->fix.smem_len);
- vesafb |= 4;
- }
-
- info->screen_base = ioremap_nocache(info->fix.smem_start,
- info->fix.smem_len);
-
- if (!info->screen_base) {
- output("ioremap failed for smem region\n");
- goto errout_smem_remap;
- }
-
- displaytype = get_displaytype();
-
- if (displaytype == DISPLAY_FP)
- nativex = get_nativex();
-
- info->flags = FBINFO_DEFAULT
- | FBINFO_HWACCEL_COPYAREA
- | FBINFO_HWACCEL_FILLRECT
- | FBINFO_HWACCEL_IMAGEBLIT
- | FBINFO_READS_FAST
-// | FBINFO_PARTIAL_PAN_OK
- | FBINFO_MISC_ALWAYS_SETPAR;
-
- info->pseudo_palette = par->pseudo_pal;
-
- if (getstartupmode(info))
- goto errout_findmode;
-
- fb_alloc_cmap(&info->cmap, 256, 0);
-
- if (register_framebuffer(info)) {
- output("Could not register CyBla framebuffer\n");
- goto errout_register;
- }
-
- pci_set_drvdata(dev, info);
-
- //
- // normal exit and error paths
- //
-
- return 0;
-
- errout_register:
- errout_findmode:
- iounmap(info->screen_base);
- errout_smem_remap:
- if (!(vesafb & 4))
- release_mem_region(info->fix.smem_start, info->fix.smem_len);
- iounmap(io_virt);
- errout_mmio_remap:
- release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
- errout_mmio_reqmem:
- if (!(vesafb & 1))
- release_region(0x3c0, 32);
- errout_enable:
- kfree(info->pixmap.addr);
- errout_alloc_pixmap:
- framebuffer_release(info);
- errout_alloc_info:
- output("CyblaFB version %s aborting init.\n", VERSION);
- return -ENODEV;
-}
-
-static void __devexit cybla_pci_remove(struct pci_dev *dev)
-{
- struct fb_info *info = pci_get_drvdata(dev);
-
- unregister_framebuffer(info);
- iounmap(io_virt);
- iounmap(info->screen_base);
- if (!(vesafb & 4))
- release_mem_region(info->fix.smem_start, info->fix.smem_len);
- release_mem_region(info->fix.mmio_start, info->fix.mmio_len);
- fb_dealloc_cmap(&info->cmap);
- if (!(vesafb & 2))
- release_region(GEBase, 0x100);
- if (!(vesafb & 1))
- release_region(0x3c0, 32);
- kfree(info->pixmap.addr);
- framebuffer_release(info);
- output("CyblaFB version %s normal exit.\n", VERSION);
-}
-
-//
-// List of boards that we are trying to support
-//
-static struct pci_device_id cybla_devices[] = {
- {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
- {0,}
-};
-
-MODULE_DEVICE_TABLE(pci, cybla_devices);
-
-static struct pci_driver cyblafb_pci_driver = {
- .name = "cyblafb",
- .id_table = cybla_devices,
- .probe = cybla_pci_probe,
- .remove = __devexit_p(cybla_pci_remove)
-};
-
-//=============================================================
-//
-// kernel command line example:
-//
-// video=cyblafb:1280x1024, bpp=16, ref=50 ...
-//
-// modprobe command line example:
-//
-// modprobe cyblafb mode=1280x1024 bpp=16 ref=50 ...
-//
-//=============================================================
-
-static int __devinit cyblafb_init(void)
-{
-#ifndef MODULE
- char *options = NULL;
- char *opt;
-
- if (fb_get_options("cyblafb", &options))
- return -ENODEV;
-
- if (options && *options)
- while ((opt = strsep(&options, ",")) != NULL) {
- if (!*opt)
- continue;
- else if (!strncmp(opt, "bpp=", 4))
- bpp = simple_strtoul(opt + 4, NULL, 0);
- else if (!strncmp(opt, "ref=", 4))
- ref = simple_strtoul(opt + 4, NULL, 0);
- else if (!strncmp(opt, "fp", 2))
- displaytype = DISPLAY_FP;
- else if (!strncmp(opt, "crt", 3))
- displaytype = DISPLAY_CRT;
- else if (!strncmp(opt, "nativex=", 8))
- nativex = simple_strtoul(opt + 8, NULL, 0);
- else if (!strncmp(opt, "center", 6))
- center = 1;
- else if (!strncmp(opt, "stretch", 7))
- stretch = 1;
- else if (!strncmp(opt, "pciwb=", 6))
- pciwb = simple_strtoul(opt + 6, NULL, 0);
- else if (!strncmp(opt, "pcirb=", 6))
- pcirb = simple_strtoul(opt + 6, NULL, 0);
- else if (!strncmp(opt, "pciwr=", 6))
- pciwr = simple_strtoul(opt + 6, NULL, 0);
- else if (!strncmp(opt, "pcirr=", 6))
- pcirr = simple_strtoul(opt + 6, NULL, 0);
- else if (!strncmp(opt, "memsize=", 8))
- memsize = simple_strtoul(opt + 8, NULL, 0);
- else if (!strncmp(opt, "verbosity=", 10))
- verbosity = simple_strtoul(opt + 10, NULL, 0);
- else
- mode = opt;
- }
-#endif
- output("CyblaFB version %s initializing\n", VERSION);
- return pci_register_driver(&cyblafb_pci_driver);
-}
-
-static void __exit cyblafb_exit(void)
-{
- pci_unregister_driver(&cyblafb_pci_driver);
-}
-
-module_init(cyblafb_init);
-module_exit(cyblafb_exit);
-
-MODULE_AUTHOR("Knut Petersen <knut_petersen@t-online.de>");
-MODULE_DESCRIPTION("Framebuffer driver for Cyberblade/i1 graphics core");
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index daf9b81878a..0c5b9a9fd56 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -129,6 +129,8 @@ static int set_system(const struct dmi_system_id *id)
screen_info.lfb_width = info->width;
if (screen_info.lfb_height == 0)
screen_info.lfb_height = info->height;
+ if (screen_info.orig_video_isVGA == 0)
+ screen_info.orig_video_isVGA = VIDEO_TYPE_EFI;
return 0;
}
@@ -374,9 +376,10 @@ static int __init efifb_init(void)
int ret;
char *option = NULL;
+ dmi_check_system(dmi_system_table);
+
if (screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
return -ENODEV;
- dmi_check_system(dmi_system_table);
if (fb_get_options("efifb", &option))
return -ENODEV;
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 082026546ae..0a7a6679ee6 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -85,8 +85,9 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
/* vm_ops->page_mkwrite handler */
static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
- struct page *page)
+ struct vm_fault *vmf)
{
+ struct page *page = vmf->page;
struct fb_info *info = vma->vm_private_data;
struct fb_deferred_io *fbdefio = info->fbdefio;
struct page *cur;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index cfd9dce1ce0..2ac32e6b595 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -46,6 +46,17 @@
struct fb_info *registered_fb[FB_MAX] __read_mostly;
int num_registered_fb __read_mostly;
+int lock_fb_info(struct fb_info *info)
+{
+ mutex_lock(&info->lock);
+ if (!info->fbops) {
+ mutex_unlock(&info->lock);
+ return 0;
+ }
+ return 1;
+}
+EXPORT_SYMBOL(lock_fb_info);
+
/*
* Helpers
*/
@@ -1086,13 +1097,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
return -EINVAL;
con2fb.framebuffer = -1;
event.data = &con2fb;
-
- if (!lock_fb_info(info))
- return -ENODEV;
event.info = info;
fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event);
- unlock_fb_info(info);
-
ret = copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0;
break;
case FBIOPUT_CON2FBMAP:
@@ -1109,12 +1115,8 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
break;
}
event.data = &con2fb;
- if (!lock_fb_info(info))
- return -ENODEV;
event.info = info;
- ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP,
- &event);
- unlock_fb_info(info);
+ ret = fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, &event);
break;
case FBIOBLANK:
if (!lock_fb_info(info))
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/nvidia/nv_setup.c
index d9627b57eb4..135ae18bfce 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/nvidia/nv_setup.c
@@ -362,6 +362,7 @@ int NVCommonSetup(struct fb_info *info)
case 0x0186:
case 0x0187:
case 0x018D:
+ case 0x01D7:
case 0x0228:
case 0x0286:
case 0x028C:
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index f132aab8c5d..c03f7f55c76 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -5,7 +5,6 @@
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
-#include <linux/mutex.h>
#include <video/vga.h>
#define NV_ARCH_04 0x04
@@ -99,7 +98,6 @@ struct nvidia_par {
RIVA_HW_STATE initial_state;
RIVA_HW_STATE *CurrentState;
struct vgastate vgastate;
- struct mutex open_lock;
u32 pseudo_palette[16];
struct pci_dev *pci_dev;
u32 Architecture;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index 9dbb5a5a267..efe10ff86d6 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -1004,15 +1004,12 @@ static int nvidiafb_open(struct fb_info *info, int user)
{
struct nvidia_par *par = info->par;
- mutex_lock(&par->open_lock);
-
if (!par->open_count) {
save_vga_x86(par);
nvidia_save_vga(par, &par->initial_state);
}
par->open_count++;
- mutex_unlock(&par->open_lock);
return 0;
}
@@ -1021,8 +1018,6 @@ static int nvidiafb_release(struct fb_info *info, int user)
struct nvidia_par *par = info->par;
int err = 0;
- mutex_lock(&par->open_lock);
-
if (!par->open_count) {
err = -EINVAL;
goto done;
@@ -1035,7 +1030,6 @@ static int nvidiafb_release(struct fb_info *info, int user)
par->open_count--;
done:
- mutex_unlock(&par->open_lock);
return err;
}
@@ -1300,7 +1294,6 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
par = info->par;
par->pci_dev = pd;
- mutex_init(&par->open_lock);
info->pixmap.addr = kzalloc(8 * 1024, GFP_KERNEL);
if (info->pixmap.addr == NULL)
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
index f24df0b54e1..8aa6e47202b 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/omap/hwa742.c
@@ -742,7 +742,7 @@ static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div)
if (calc_reg_timing(sysclk, div) == 0)
break;
}
- if (div > max_clk_div)
+ if (div >= max_clk_div)
goto err;
*extif_mem_div = div;
@@ -752,7 +752,7 @@ static int calc_extif_timings(unsigned long sysclk, int *extif_mem_div)
break;
}
- if (div > max_clk_div)
+ if (div >= max_clk_div)
goto err;
return 0;
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 1a49519dafa..060d72fe57c 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -338,7 +338,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
omapfb_rqueue_lock(fbdev);
switch (blank) {
- case VESA_NO_BLANKING:
+ case FB_BLANK_UNBLANK:
if (fbdev->state == OMAPFB_SUSPENDED) {
if (fbdev->ctrl->resume)
fbdev->ctrl->resume();
@@ -349,7 +349,7 @@ static int omapfb_blank(int blank, struct fb_info *fbi)
do_update = 1;
}
break;
- case VESA_POWERDOWN:
+ case FB_BLANK_POWERDOWN:
if (fbdev->state == OMAPFB_ACTIVE) {
fbdev->panel->disable(fbdev->panel);
if (fbdev->ctrl->suspend)
@@ -1818,7 +1818,7 @@ static int omapfb_suspend(struct platform_device *pdev, pm_message_t mesg)
{
struct omapfb_device *fbdev = platform_get_drvdata(pdev);
- omapfb_blank(VESA_POWERDOWN, fbdev->fb_info[0]);
+ omapfb_blank(FB_BLANK_POWERDOWN, fbdev->fb_info[0]);
return 0;
}
@@ -1828,7 +1828,7 @@ static int omapfb_resume(struct platform_device *pdev)
{
struct omapfb_device *fbdev = platform_get_drvdata(pdev);
- omapfb_blank(VESA_NO_BLANKING, fbdev->fb_info[0]);
+ omapfb_blank(FB_BLANK_UNBLANK, fbdev->fb_info[0]);
return 0;
}
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/s1d13xxxfb.c
index a7b01d2724b..0726aecf3b7 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/s1d13xxxfb.c
@@ -50,9 +50,22 @@
#define dbg(fmt, args...) do { } while (0)
#endif
-static const int __devinitconst s1d13xxxfb_revisions[] = {
- S1D13506_CHIP_REV, /* Rev.4 on HP Jornada 7xx S1D13506 */
- S1D13806_CHIP_REV, /* Rev.7 on .. */
+/*
+ * List of card production ids
+ */
+static const int s1d13xxxfb_prod_ids[] = {
+ S1D13505_PROD_ID,
+ S1D13506_PROD_ID,
+ S1D13806_PROD_ID,
+};
+
+/*
+ * List of card strings
+ */
+static const char *s1d13xxxfb_prod_names[] = {
+ "S1D13505",
+ "S1D13506",
+ "S1D13806",
};
/*
@@ -377,7 +390,6 @@ s1d13xxxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
return 0;
}
-
/* framebuffer information structures */
static struct fb_ops s1d13xxxfb_fbops = {
@@ -544,7 +556,7 @@ s1d13xxxfb_probe(struct platform_device *pdev)
struct s1d13xxxfb_pdata *pdata = NULL;
int ret = 0;
int i;
- u8 revision;
+ u8 revision, prod_id;
dbg("probe called: device is %p\n", pdev);
@@ -613,19 +625,31 @@ s1d13xxxfb_probe(struct platform_device *pdev)
goto bail;
}
- revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
-
+ /* production id is top 6 bits */
+ prod_id = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) >> 2;
+ /* revision id is lower 2 bits */
+ revision = s1d13xxxfb_readreg(default_par, S1DREG_REV_CODE) & 0x3;
ret = -ENODEV;
- for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_revisions); i++) {
- if (revision == s1d13xxxfb_revisions[i])
+ for (i = 0; i < ARRAY_SIZE(s1d13xxxfb_prod_ids); i++) {
+ if (prod_id == s1d13xxxfb_prod_ids[i]) {
+ /* looks like we got it in our list */
+ default_par->prod_id = prod_id;
+ default_par->revision = revision;
ret = 0;
+ break;
+ }
}
- if (!ret)
+ if (!ret) {
+ printk(KERN_INFO PFX "chip production id %i = %s\n",
+ prod_id, s1d13xxxfb_prod_names[i]);
printk(KERN_INFO PFX "chip revision %i\n", revision);
- else {
- printk(KERN_INFO PFX "unknown chip revision %i\n", revision);
+ } else {
+ printk(KERN_INFO PFX
+ "unknown chip production id %i, revision %i\n",
+ prod_id, revision);
+ printk(KERN_INFO PFX "please contant maintainer\n");
goto bail;
}
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
new file mode 100644
index 00000000000..5e9c6302433
--- /dev/null
+++ b/drivers/video/s3c-fb.c
@@ -0,0 +1,1036 @@
+/* linux/drivers/video/s3c-fb.c
+ *
+ * Copyright 2008 Openmoko Inc.
+ * Copyright 2008 Simtec Electronics
+ * Ben Dooks <ben@simtec.co.uk>
+ * http://armlinux.simtec.co.uk/
+ *
+ * Samsung SoC Framebuffer 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 <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/gfp.h>
+#include <linux/clk.h>
+#include <linux/fb.h>
+#include <linux/io.h>
+
+#include <mach/map.h>
+#include <mach/regs-fb.h>
+#include <plat/fb.h>
+
+/* This driver will export a number of framebuffer interfaces depending
+ * on the configuration passed in via the platform data. Each fb instance
+ * maps to a hardware window. Currently there is no support for runtime
+ * setting of the alpha-blending functions that each window has, so only
+ * window 0 is actually useful.
+ *
+ * Window 0 is treated specially, it is used for the basis of the LCD
+ * output timings and as the control for the output power-down state.
+*/
+
+/* note, some of the functions that get called are derived from including
+ * <mach/regs-fb.h> as they are specific to the architecture that the code
+ * is being built for.
+*/
+
+#ifdef CONFIG_FB_S3C_DEBUG_REGWRITE
+#undef writel
+#define writel(v, r) do { \
+ printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \
+ __raw_writel(v, r); } while(0)
+#endif /* FB_S3C_DEBUG_REGWRITE */
+
+struct s3c_fb;
+
+/**
+ * struct s3c_fb_win - per window private data for each framebuffer.
+ * @windata: The platform data supplied for the window configuration.
+ * @parent: The hardware that this window is part of.
+ * @fbinfo: Pointer pack to the framebuffer info for this window.
+ * @palette_buffer: Buffer/cache to hold palette entries.
+ * @pseudo_palette: For use in TRUECOLOUR modes for entries 0..15/
+ * @index: The window number of this window.
+ * @palette: The bitfields for changing r/g/b into a hardware palette entry.
+ */
+struct s3c_fb_win {
+ struct s3c_fb_pd_win *windata;
+ struct s3c_fb *parent;
+ struct fb_info *fbinfo;
+ struct s3c_fb_palette palette;
+
+ u32 *palette_buffer;
+ u32 pseudo_palette[16];
+ unsigned int index;
+};
+
+/**
+ * struct s3c_fb - overall hardware state of the hardware
+ * @dev: The device that we bound to, for printing, etc.
+ * @regs_res: The resource we claimed for the IO registers.
+ * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk.
+ * @regs: The mapped hardware registers.
+ * @enabled: A bitmask of enabled hardware windows.
+ * @pdata: The platform configuration data passed with the device.
+ * @windows: The hardware windows that have been claimed.
+ */
+struct s3c_fb {
+ struct device *dev;
+ struct resource *regs_res;
+ struct clk *bus_clk;
+ void __iomem *regs;
+
+ unsigned char enabled;
+
+ struct s3c_fb_platdata *pdata;
+ struct s3c_fb_win *windows[S3C_FB_MAX_WIN];
+};
+
+/**
+ * s3c_fb_win_has_palette() - determine if a mode has a palette
+ * @win: The window number being queried.
+ * @bpp: The number of bits per pixel to test.
+ *
+ * Work out if the given window supports palletised data at the specified bpp.
+ */
+static int s3c_fb_win_has_palette(unsigned int win, unsigned int bpp)
+{
+ return s3c_fb_win_pal_size(win) <= (1 << bpp);
+}
+
+/**
+ * s3c_fb_check_var() - framebuffer layer request to verify a given mode.
+ * @var: The screen information to verify.
+ * @info: The framebuffer device.
+ *
+ * Framebuffer layer call to verify the given information and allow us to
+ * update various information depending on the hardware capabilities.
+ */
+static int s3c_fb_check_var(struct fb_var_screeninfo *var,
+ struct fb_info *info)
+{
+ struct s3c_fb_win *win = info->par;
+ struct s3c_fb_pd_win *windata = win->windata;
+ struct s3c_fb *sfb = win->parent;
+
+ dev_dbg(sfb->dev, "checking parameters\n");
+
+ var->xres_virtual = max((unsigned int)windata->virtual_x, var->xres);
+ var->yres_virtual = max((unsigned int)windata->virtual_y, var->yres);
+
+ if (!s3c_fb_validate_win_bpp(win->index, var->bits_per_pixel)) {
+ dev_dbg(sfb->dev, "win %d: unsupported bpp %d\n",
+ win->index, var->bits_per_pixel);
+ return -EINVAL;
+ }
+
+ /* always ensure these are zero, for drop through cases below */
+ var->transp.offset = 0;
+ var->transp.length = 0;
+
+ switch (var->bits_per_pixel) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ if (!s3c_fb_win_has_palette(win->index, var->bits_per_pixel)) {
+ /* non palletised, A:1,R:2,G:3,B:2 mode */
+ var->red.offset = 4;
+ var->green.offset = 2;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 3;
+ var->blue.length = 2;
+ var->transp.offset = 7;
+ var->transp.length = 1;
+ } else {
+ var->red.offset = 0;
+ var->red.length = var->bits_per_pixel;
+ var->green = var->red;
+ var->blue = var->red;
+ }
+ break;
+
+ case 19:
+ /* 666 with one bit alpha/transparency */
+ var->transp.offset = 18;
+ var->transp.length = 1;
+ case 18:
+ var->bits_per_pixel = 32;
+
+ /* 666 format */
+ var->red.offset = 12;
+ var->green.offset = 6;
+ var->blue.offset = 0;
+ var->red.length = 6;
+ var->green.length = 6;
+ var->blue.length = 6;
+ break;
+
+ case 16:
+ /* 16 bpp, 565 format */
+ var->red.offset = 11;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = 5;
+ var->green.length = 6;
+ var->blue.length = 5;
+ break;
+
+ case 28:
+ case 25:
+ var->transp.length = var->bits_per_pixel - 24;
+ var->transp.offset = 24;
+ /* drop through */
+ case 24:
+ /* our 24bpp is unpacked, so 32bpp */
+ var->bits_per_pixel = 32;
+ case 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;
+ break;
+
+ default:
+ dev_err(sfb->dev, "invalid bpp\n");
+ }
+
+ dev_dbg(sfb->dev, "%s: verified parameters\n", __func__);
+ return 0;
+}
+
+/**
+ * s3c_fb_calc_pixclk() - calculate the divider to create the pixel clock.
+ * @sfb: The hardware state.
+ * @pixclock: The pixel clock wanted, in picoseconds.
+ *
+ * Given the specified pixel clock, work out the necessary divider to get
+ * close to the output frequency.
+ */
+static int s3c_fb_calc_pixclk(struct s3c_fb *sfb, unsigned int pixclk)
+{
+ unsigned long clk = clk_get_rate(sfb->bus_clk);
+ unsigned long long tmp;
+ unsigned int result;
+
+ tmp = (unsigned long long)clk;
+ tmp *= pixclk;
+
+ do_div(tmp, 1000000000UL);
+ result = (unsigned int)tmp / 1000;
+
+ dev_dbg(sfb->dev, "pixclk=%u, clk=%lu, div=%d (%lu)\n",
+ pixclk, clk, result, clk / result);
+
+ return result;
+}
+
+/**
+ * s3c_fb_align_word() - align pixel count to word boundary
+ * @bpp: The number of bits per pixel
+ * @pix: The value to be aligned.
+ *
+ * Align the given pixel count so that it will start on an 32bit word
+ * boundary.
+ */
+static int s3c_fb_align_word(unsigned int bpp, unsigned int pix)
+{
+ int pix_per_word;
+
+ if (bpp > 16)
+ return pix;
+
+ pix_per_word = (8 * 32) / bpp;
+ return ALIGN(pix, pix_per_word);
+}
+
+/**
+ * s3c_fb_set_par() - framebuffer request to set new framebuffer state.
+ * @info: The framebuffer to change.
+ *
+ * Framebuffer layer request to set a new mode for the specified framebuffer
+ */
+static int s3c_fb_set_par(struct fb_info *info)
+{
+ struct fb_var_screeninfo *var = &info->var;
+ struct s3c_fb_win *win = info->par;
+ struct s3c_fb *sfb = win->parent;
+ void __iomem *regs = sfb->regs;
+ int win_no = win->index;
+ u32 data;
+ u32 pagewidth;
+ int clkdiv;
+
+ dev_dbg(sfb->dev, "setting framebuffer parameters\n");
+
+ switch (var->bits_per_pixel) {
+ case 32:
+ case 24:
+ case 16:
+ case 12:
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+ case 8:
+ if (s3c_fb_win_has_palette(win_no, 8))
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ else
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ break;
+ case 1:
+ info->fix.visual = FB_VISUAL_MONO01;
+ break;
+ default:
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ break;
+ }
+
+ info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
+
+ /* disable the window whilst we update it */
+ writel(0, regs + WINCON(win_no));
+
+ /* use window 0 as the basis for the lcd output timings */
+
+ if (win_no == 0) {
+ clkdiv = s3c_fb_calc_pixclk(sfb, var->pixclock);
+
+ data = sfb->pdata->vidcon0;
+ data &= ~(VIDCON0_CLKVAL_F_MASK | VIDCON0_CLKDIR);
+
+ if (clkdiv > 1)
+ data |= VIDCON0_CLKVAL_F(clkdiv-1) | VIDCON0_CLKDIR;
+ else
+ data &= ~VIDCON0_CLKDIR; /* 1:1 clock */
+
+ /* write the timing data to the panel */
+
+ data |= VIDCON0_ENVID | VIDCON0_ENVID_F;
+ writel(data, regs + VIDCON0);
+
+ data = VIDTCON0_VBPD(var->upper_margin - 1) |
+ VIDTCON0_VFPD(var->lower_margin - 1) |
+ VIDTCON0_VSPW(var->vsync_len - 1);
+
+ writel(data, regs + VIDTCON0);
+
+ data = VIDTCON1_HBPD(var->left_margin - 1) |
+ VIDTCON1_HFPD(var->right_margin - 1) |
+ VIDTCON1_HSPW(var->hsync_len - 1);
+
+ writel(data, regs + VIDTCON1);
+
+ data = VIDTCON2_LINEVAL(var->yres - 1) |
+ VIDTCON2_HOZVAL(var->xres - 1);
+ writel(data, regs + VIDTCON2);
+ }
+
+ /* write the buffer address */
+
+ writel(info->fix.smem_start, regs + VIDW_BUF_START(win_no));
+
+ data = info->fix.smem_start + info->fix.line_length * var->yres;
+ writel(data, regs + VIDW_BUF_END(win_no));
+
+ pagewidth = (var->xres * var->bits_per_pixel) >> 3;
+ data = VIDW_BUF_SIZE_OFFSET(info->fix.line_length - pagewidth) |
+ VIDW_BUF_SIZE_PAGEWIDTH(pagewidth);
+ writel(data, regs + VIDW_BUF_SIZE(win_no));
+
+ /* write 'OSD' registers to control position of framebuffer */
+
+ data = VIDOSDxA_TOPLEFT_X(0) | VIDOSDxA_TOPLEFT_Y(0);
+ writel(data, regs + VIDOSD_A(win_no));
+
+ data = VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(var->bits_per_pixel,
+ var->xres - 1)) |
+ VIDOSDxB_BOTRIGHT_Y(var->yres - 1);
+
+ writel(data, regs + VIDOSD_B(win_no));
+
+ data = var->xres * var->yres;
+ if (s3c_fb_has_osd_d(win_no)) {
+ writel(data, regs + VIDOSD_D(win_no));
+ writel(0, regs + VIDOSD_C(win_no));
+ } else
+ writel(data, regs + VIDOSD_C(win_no));
+
+ data = WINCONx_ENWIN;
+
+ /* note, since we have to round up the bits-per-pixel, we end up
+ * relying on the bitfield information for r/g/b/a to work out
+ * exactly which mode of operation is intended. */
+
+ switch (var->bits_per_pixel) {
+ case 1:
+ data |= WINCON0_BPPMODE_1BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_4WORD;
+ break;
+ case 2:
+ data |= WINCON0_BPPMODE_2BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_8WORD;
+ break;
+ case 4:
+ data |= WINCON0_BPPMODE_4BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_8WORD;
+ break;
+ case 8:
+ if (var->transp.length != 0)
+ data |= WINCON1_BPPMODE_8BPP_1232;
+ else
+ data |= WINCON0_BPPMODE_8BPP_PALETTE;
+ data |= WINCONx_BURSTLEN_8WORD;
+ data |= WINCONx_BYTSWP;
+ break;
+ case 16:
+ if (var->transp.length != 0)
+ data |= WINCON1_BPPMODE_16BPP_A1555;
+ else
+ data |= WINCON0_BPPMODE_16BPP_565;
+ data |= WINCONx_HAWSWP;
+ data |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case 24:
+ case 32:
+ if (var->red.length == 6) {
+ if (var->transp.length != 0)
+ data |= WINCON1_BPPMODE_19BPP_A1666;
+ else
+ data |= WINCON1_BPPMODE_18BPP_666;
+ } else if (var->transp.length != 0)
+ data |= WINCON1_BPPMODE_25BPP_A1888;
+ else
+ data |= WINCON0_BPPMODE_24BPP_888;
+
+ data |= WINCONx_BURSTLEN_16WORD;
+ break;
+ }
+
+ writel(data, regs + WINCON(win_no));
+ writel(0x0, regs + WINxMAP(win_no));
+
+ return 0;
+}
+
+/**
+ * s3c_fb_update_palette() - set or schedule a palette update.
+ * @sfb: The hardware information.
+ * @win: The window being updated.
+ * @reg: The palette index being changed.
+ * @value: The computed palette value.
+ *
+ * Change the value of a palette register, either by directly writing to
+ * the palette (this requires the palette RAM to be disconnected from the
+ * hardware whilst this is in progress) or schedule the update for later.
+ *
+ * At the moment, since we have no VSYNC interrupt support, we simply set
+ * the palette entry directly.
+ */
+static void s3c_fb_update_palette(struct s3c_fb *sfb,
+ struct s3c_fb_win *win,
+ unsigned int reg,
+ u32 value)
+{
+ void __iomem *palreg;
+ u32 palcon;
+
+ palreg = sfb->regs + s3c_fb_pal_reg(win->index, reg);
+
+ dev_dbg(sfb->dev, "%s: win %d, reg %d (%p): %08x\n",
+ __func__, win->index, reg, palreg, value);
+
+ win->palette_buffer[reg] = value;
+
+ palcon = readl(sfb->regs + WPALCON);
+ writel(palcon | WPALCON_PAL_UPDATE, sfb->regs + WPALCON);
+
+ if (s3c_fb_pal_is16(win->index))
+ writew(value, palreg);
+ else
+ writel(value, palreg);
+
+ writel(palcon, sfb->regs + WPALCON);
+}
+
+static inline unsigned int chan_to_field(unsigned int chan,
+ struct fb_bitfield *bf)
+{
+ chan &= 0xffff;
+ chan >>= 16 - bf->length;
+ return chan << bf->offset;
+}
+
+/**
+ * s3c_fb_setcolreg() - framebuffer layer request to change palette.
+ * @regno: The palette index to change.
+ * @red: The red field for the palette data.
+ * @green: The green field for the palette data.
+ * @blue: The blue field for the palette data.
+ * @trans: The transparency (alpha) field for the palette data.
+ * @info: The framebuffer being changed.
+ */
+static int s3c_fb_setcolreg(unsigned regno,
+ unsigned red, unsigned green, unsigned blue,
+ unsigned transp, struct fb_info *info)
+{
+ struct s3c_fb_win *win = info->par;
+ struct s3c_fb *sfb = win->parent;
+ unsigned int val;
+
+ dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n",
+ __func__, win->index, regno, red, green, blue);
+
+ switch (info->fix.visual) {
+ case FB_VISUAL_TRUECOLOR:
+ /* true-colour, use pseudo-palette */
+
+ if (regno < 16) {
+ u32 *pal = info->pseudo_palette;
+
+ val = chan_to_field(red, &info->var.red);
+ val |= chan_to_field(green, &info->var.green);
+ val |= chan_to_field(blue, &info->var.blue);
+
+ pal[regno] = val;
+ }
+ break;
+
+ case FB_VISUAL_PSEUDOCOLOR:
+ if (regno < s3c_fb_win_pal_size(win->index)) {
+ val = chan_to_field(red, &win->palette.r);
+ val |= chan_to_field(green, &win->palette.g);
+ val |= chan_to_field(blue, &win->palette.b);
+
+ s3c_fb_update_palette(sfb, win, regno, val);
+ }
+
+ break;
+
+ default:
+ return 1; /* unknown type */
+ }
+
+ return 0;
+}
+
+/**
+ * s3c_fb_enable() - Set the state of the main LCD output
+ * @sfb: The main framebuffer state.
+ * @enable: The state to set.
+ */
+static void s3c_fb_enable(struct s3c_fb *sfb, int enable)
+{
+ u32 vidcon0 = readl(sfb->regs + VIDCON0);
+
+ if (enable)
+ vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F;
+ else {
+ /* see the note in the framebuffer datasheet about
+ * why you cannot take both of these bits down at the
+ * same time. */
+
+ if (!(vidcon0 & VIDCON0_ENVID))
+ return;
+
+ vidcon0 |= VIDCON0_ENVID;
+ vidcon0 &= ~VIDCON0_ENVID_F;
+ }
+
+ writel(vidcon0, sfb->regs + VIDCON0);
+}
+
+/**
+ * s3c_fb_blank() - blank or unblank the given window
+ * @blank_mode: The blank state from FB_BLANK_*
+ * @info: The framebuffer to blank.
+ *
+ * Framebuffer layer request to change the power state.
+ */
+static int s3c_fb_blank(int blank_mode, struct fb_info *info)
+{
+ struct s3c_fb_win *win = info->par;
+ struct s3c_fb *sfb = win->parent;
+ unsigned int index = win->index;
+ u32 wincon;
+
+ dev_dbg(sfb->dev, "blank mode %d\n", blank_mode);
+
+ wincon = readl(sfb->regs + WINCON(index));
+
+ switch (blank_mode) {
+ case FB_BLANK_POWERDOWN:
+ wincon &= ~WINCONx_ENWIN;
+ sfb->enabled &= ~(1 << index);
+ /* fall through to FB_BLANK_NORMAL */
+
+ case FB_BLANK_NORMAL:
+ /* disable the DMA and display 0x0 (black) */
+ writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0),
+ sfb->regs + WINxMAP(index));
+ break;
+
+ case FB_BLANK_UNBLANK:
+ writel(0x0, sfb->regs + WINxMAP(index));
+ wincon |= WINCONx_ENWIN;
+ sfb->enabled |= (1 << index);
+ break;
+
+ case FB_BLANK_VSYNC_SUSPEND:
+ case FB_BLANK_HSYNC_SUSPEND:
+ default:
+ return 1;
+ }
+
+ writel(wincon, sfb->regs + WINCON(index));
+
+ /* Check the enabled state to see if we need to be running the
+ * main LCD interface, as if there are no active windows then
+ * it is highly likely that we also do not need to output
+ * anything.
+ */
+
+ /* We could do something like the following code, but the current
+ * system of using framebuffer events means that we cannot make
+ * the distinction between just window 0 being inactive and all
+ * the windows being down.
+ *
+ * s3c_fb_enable(sfb, sfb->enabled ? 1 : 0);
+ */
+
+ /* we're stuck with this until we can do something about overriding
+ * the power control using the blanking event for a single fb.
+ */
+ if (index == 0)
+ s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0);
+
+ return 0;
+}
+
+static struct fb_ops s3c_fb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = s3c_fb_check_var,
+ .fb_set_par = s3c_fb_set_par,
+ .fb_blank = s3c_fb_blank,
+ .fb_setcolreg = s3c_fb_setcolreg,
+ .fb_fillrect = cfb_fillrect,
+ .fb_copyarea = cfb_copyarea,
+ .fb_imageblit = cfb_imageblit,
+};
+
+/**
+ * s3c_fb_alloc_memory() - allocate display memory for framebuffer window
+ * @sfb: The base resources for the hardware.
+ * @win: The window to initialise memory for.
+ *
+ * Allocate memory for the given framebuffer.
+ */
+static int __devinit s3c_fb_alloc_memory(struct s3c_fb *sfb,
+ struct s3c_fb_win *win)
+{
+ struct s3c_fb_pd_win *windata = win->windata;
+ unsigned int real_size, virt_size, size;
+ struct fb_info *fbi = win->fbinfo;
+ dma_addr_t map_dma;
+
+ dev_dbg(sfb->dev, "allocating memory for display\n");
+
+ real_size = windata->win_mode.xres * windata->win_mode.yres;
+ virt_size = windata->virtual_x * windata->virtual_y;
+
+ dev_dbg(sfb->dev, "real_size=%u (%u.%u), virt_size=%u (%u.%u)\n",
+ real_size, windata->win_mode.xres, windata->win_mode.yres,
+ virt_size, windata->virtual_x, windata->virtual_y);
+
+ size = (real_size > virt_size) ? real_size : virt_size;
+ size *= (windata->max_bpp > 16) ? 32 : windata->max_bpp;
+ size /= 8;
+
+ fbi->fix.smem_len = size;
+ size = PAGE_ALIGN(size);
+
+ dev_dbg(sfb->dev, "want %u bytes for window\n", size);
+
+ fbi->screen_base = dma_alloc_writecombine(sfb->dev, size,
+ &map_dma, GFP_KERNEL);
+ if (!fbi->screen_base)
+ return -ENOMEM;
+
+ dev_dbg(sfb->dev, "mapped %x to %p\n",
+ (unsigned int)map_dma, fbi->screen_base);
+
+ memset(fbi->screen_base, 0x0, size);
+ fbi->fix.smem_start = map_dma;
+
+ return 0;
+}
+
+/**
+ * s3c_fb_free_memory() - free the display memory for the given window
+ * @sfb: The base resources for the hardware.
+ * @win: The window to free the display memory for.
+ *
+ * Free the display memory allocated by s3c_fb_alloc_memory().
+ */
+static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
+{
+ struct fb_info *fbi = win->fbinfo;
+
+ dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),
+ fbi->screen_base, fbi->fix.smem_start);
+}
+
+/**
+ * s3c_fb_release_win() - release resources for a framebuffer window.
+ * @win: The window to cleanup the resources for.
+ *
+ * Release the resources that where claimed for the hardware window,
+ * such as the framebuffer instance and any memory claimed for it.
+ */
+static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
+{
+ fb_dealloc_cmap(&win->fbinfo->cmap);
+ unregister_framebuffer(win->fbinfo);
+ s3c_fb_free_memory(sfb, win);
+}
+
+/**
+ * s3c_fb_probe_win() - register an hardware window
+ * @sfb: The base resources for the hardware
+ * @res: Pointer to where to place the resultant window.
+ *
+ * Allocate and do the basic initialisation for one of the hardware's graphics
+ * windows.
+ */
+static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no,
+ struct s3c_fb_win **res)
+{
+ struct fb_var_screeninfo *var;
+ struct fb_videomode *initmode;
+ struct s3c_fb_pd_win *windata;
+ struct s3c_fb_win *win;
+ struct fb_info *fbinfo;
+ int palette_size;
+ int ret;
+
+ dev_dbg(sfb->dev, "probing window %d\n", win_no);
+
+ palette_size = s3c_fb_win_pal_size(win_no);
+
+ fbinfo = framebuffer_alloc(sizeof(struct s3c_fb_win) +
+ palette_size * sizeof(u32), sfb->dev);
+ if (!fbinfo) {
+ dev_err(sfb->dev, "failed to allocate framebuffer\n");
+ return -ENOENT;
+ }
+
+ windata = sfb->pdata->win[win_no];
+ initmode = &windata->win_mode;
+
+ WARN_ON(windata->max_bpp == 0);
+ WARN_ON(windata->win_mode.xres == 0);
+ WARN_ON(windata->win_mode.yres == 0);
+
+ win = fbinfo->par;
+ var = &fbinfo->var;
+ win->fbinfo = fbinfo;
+ win->parent = sfb;
+ win->windata = windata;
+ win->index = win_no;
+ win->palette_buffer = (u32 *)(win + 1);
+
+ ret = s3c_fb_alloc_memory(sfb, win);
+ if (ret) {
+ dev_err(sfb->dev, "failed to allocate display memory\n");
+ goto err_framebuffer;
+ }
+
+ /* setup the r/b/g positions for the window's palette */
+ s3c_fb_init_palette(win_no, &win->palette);
+
+ /* setup the initial video mode from the window */
+ fb_videomode_to_var(&fbinfo->var, initmode);
+
+ fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
+ fbinfo->fix.accel = FB_ACCEL_NONE;
+ fbinfo->var.activate = FB_ACTIVATE_NOW;
+ fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
+ fbinfo->var.bits_per_pixel = windata->default_bpp;
+ fbinfo->fbops = &s3c_fb_ops;
+ fbinfo->flags = FBINFO_FLAG_DEFAULT;
+ fbinfo->pseudo_palette = &win->pseudo_palette;
+
+ /* prepare to actually start the framebuffer */
+
+ ret = s3c_fb_check_var(&fbinfo->var, fbinfo);
+ if (ret < 0) {
+ dev_err(sfb->dev, "check_var failed on initial video params\n");
+ goto err_alloc_mem;
+ }
+
+ /* create initial colour map */
+
+ ret = fb_alloc_cmap(&fbinfo->cmap, s3c_fb_win_pal_size(win_no), 1);
+ if (ret == 0)
+ fb_set_cmap(&fbinfo->cmap, fbinfo);
+ else
+ dev_err(sfb->dev, "failed to allocate fb cmap\n");
+
+ s3c_fb_set_par(fbinfo);
+
+ dev_dbg(sfb->dev, "about to register framebuffer\n");
+
+ /* run the check_var and set_par on our configuration. */
+
+ ret = register_framebuffer(fbinfo);
+ if (ret < 0) {
+ dev_err(sfb->dev, "failed to register framebuffer\n");
+ goto err_alloc_mem;
+ }
+
+ *res = win;
+ dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id);
+
+ return 0;
+
+err_alloc_mem:
+ s3c_fb_free_memory(sfb, win);
+
+err_framebuffer:
+ unregister_framebuffer(fbinfo);
+ return ret;
+}
+
+/**
+ * s3c_fb_clear_win() - clear hardware window registers.
+ * @sfb: The base resources for the hardware.
+ * @win: The window to process.
+ *
+ * Reset the specific window registers to a known state.
+ */
+static void s3c_fb_clear_win(struct s3c_fb *sfb, int win)
+{
+ void __iomem *regs = sfb->regs;
+
+ writel(0, regs + WINCON(win));
+ writel(0xffffff, regs + WxKEYCONy(win, 0));
+ writel(0xffffff, regs + WxKEYCONy(win, 1));
+
+ writel(0, regs + VIDOSD_A(win));
+ writel(0, regs + VIDOSD_B(win));
+ writel(0, regs + VIDOSD_C(win));
+}
+
+static int __devinit s3c_fb_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct s3c_fb_platdata *pd;
+ struct s3c_fb *sfb;
+ struct resource *res;
+ int win;
+ int ret = 0;
+
+ pd = pdev->dev.platform_data;
+ if (!pd) {
+ dev_err(dev, "no platform data specified\n");
+ return -EINVAL;
+ }
+
+ sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL);
+ if (!sfb) {
+ dev_err(dev, "no memory for framebuffers\n");
+ return -ENOMEM;
+ }
+
+ sfb->dev = dev;
+ sfb->pdata = pd;
+
+ sfb->bus_clk = clk_get(dev, "lcd");
+ if (IS_ERR(sfb->bus_clk)) {
+ dev_err(dev, "failed to get bus clock\n");
+ goto err_sfb;
+ }
+
+ clk_enable(sfb->bus_clk);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "failed to find registers\n");
+ ret = -ENOENT;
+ goto err_clk;
+ }
+
+ sfb->regs_res = request_mem_region(res->start, resource_size(res),
+ dev_name(dev));
+ if (!sfb->regs_res) {
+ dev_err(dev, "failed to claim register region\n");
+ ret = -ENOENT;
+ goto err_clk;
+ }
+
+ sfb->regs = ioremap(res->start, resource_size(res));
+ if (!sfb->regs) {
+ dev_err(dev, "failed to map registers\n");
+ ret = -ENXIO;
+ goto err_req_region;
+ }
+
+ dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs);
+
+ /* setup gpio and output polarity controls */
+
+ pd->setup_gpio();
+
+ writel(pd->vidcon1, sfb->regs + VIDCON1);
+
+ /* zero all windows before we do anything */
+
+ for (win = 0; win < S3C_FB_MAX_WIN; win++)
+ s3c_fb_clear_win(sfb, win);
+
+ /* we have the register setup, start allocating framebuffers */
+
+ for (win = 0; win < S3C_FB_MAX_WIN; win++) {
+ if (!pd->win[win])
+ continue;
+
+ ret = s3c_fb_probe_win(sfb, win, &sfb->windows[win]);
+ if (ret < 0) {
+ dev_err(dev, "failed to create window %d\n", win);
+ for (; win >= 0; win--)
+ s3c_fb_release_win(sfb, sfb->windows[win]);
+ goto err_ioremap;
+ }
+ }
+
+ platform_set_drvdata(pdev, sfb);
+
+ return 0;
+
+err_ioremap:
+ iounmap(sfb->regs);
+
+err_req_region:
+ release_resource(sfb->regs_res);
+ kfree(sfb->regs_res);
+
+err_clk:
+ clk_disable(sfb->bus_clk);
+ clk_put(sfb->bus_clk);
+
+err_sfb:
+ kfree(sfb);
+ return ret;
+}
+
+/**
+ * s3c_fb_remove() - Cleanup on module finalisation
+ * @pdev: The platform device we are bound to.
+ *
+ * Shutdown and then release all the resources that the driver allocated
+ * on initialisation.
+ */
+static int __devexit s3c_fb_remove(struct platform_device *pdev)
+{
+ struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ int win;
+
+ for (win = 0; win <= S3C_FB_MAX_WIN; win++)
+ s3c_fb_release_win(sfb, sfb->windows[win]);
+
+ iounmap(sfb->regs);
+
+ clk_disable(sfb->bus_clk);
+ clk_put(sfb->bus_clk);
+
+ release_resource(sfb->regs_res);
+ kfree(sfb->regs_res);
+
+ kfree(sfb);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int s3c_fb_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ struct s3c_fb_win *win;
+ int win_no;
+
+ for (win_no = S3C_FB_MAX_WIN; win_no >= 0; win_no--) {
+ win = sfb->windows[win_no];
+ if (!win)
+ continue;
+
+ /* use the blank function to push into power-down */
+ s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
+ }
+
+ clk_disable(sfb->bus_clk);
+ return 0;
+}
+
+static int s3c_fb_resume(struct platform_device *pdev)
+{
+ struct s3c_fb *sfb = platform_get_drvdata(pdev);
+ struct s3c_fb_win *win;
+ int win_no;
+
+ clk_enable(sfb->bus_clk);
+
+ for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) {
+ win = sfb->windows[win_no];
+ if (!win)
+ continue;
+
+ dev_dbg(&pdev->dev, "resuming window %d\n", win_no);
+ s3c_fb_set_par(win->fbinfo);
+ }
+
+ return 0;
+}
+#else
+#define s3c_fb_suspend NULL
+#define s3c_fb_resume NULL
+#endif
+
+static struct platform_driver s3c_fb_driver = {
+ .probe = s3c_fb_probe,
+ .remove = s3c_fb_remove,
+ .suspend = s3c_fb_suspend,
+ .resume = s3c_fb_resume,
+ .driver = {
+ .name = "s3c-fb",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init s3c_fb_init(void)
+{
+ return platform_driver_register(&s3c_fb_driver);
+}
+
+static void __exit s3c_fb_cleanup(void)
+{
+ platform_driver_unregister(&s3c_fb_driver);
+}
+
+module_init(s3c_fb_init);
+module_exit(s3c_fb_cleanup);
+
+MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
+MODULE_DESCRIPTION("Samsung S3C SoC Framebuffer driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s3c-fb");
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index f5252c2552f..bba53714a7b 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -837,6 +837,8 @@ static int sgivwfb_remove(struct platform_device *dev)
iounmap(par->regs);
iounmap(info->screen_base);
release_mem_region(DBE_REG_PHYS, DBE_REG_SIZE);
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
}
return 0;
}
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index df5336561d1..a439159204a 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -795,8 +795,9 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
if (!retval || retval == 4)
return -EINVAL;
- /* This has to been done !!! */
- fb_alloc_cmap(&info->cmap, cmap_len, 0);
+ /* This has to be done! */
+ if (fb_alloc_cmap(&info->cmap, cmap_len, 0))
+ return -ENOMEM;
/*
* The following is done in the case of having hardware with a static
@@ -820,8 +821,10 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
*/
/* xxxfb_set_par(info); */
- if (register_framebuffer(info) < 0)
+ if (register_framebuffer(info) < 0) {
+ fb_dealloc_cmap(&info->cmap);
return -EINVAL;
+ }
printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
info->fix.id);
pci_set_drvdata(dev, info); /* or platform_set_drvdata(pdev, info) */
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index dcd98793d56..eb5d73a0670 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -1525,7 +1525,10 @@ static int sm501fb_init_fb(struct fb_info *fb,
}
/* initialise and set the palette */
- fb_alloc_cmap(&fb->cmap, NR_PALETTE, 0);
+ if (fb_alloc_cmap(&fb->cmap, NR_PALETTE, 0)) {
+ dev_err(info->dev, "failed to allocate cmap memory\n");
+ return -ENOMEM;
+ }
fb_set_cmap(&fb->cmap, fb);
ret = (fb->fbops->fb_check_var)(&fb->var, fb);
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 5b11a00f49b..609d0a521ca 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -1421,13 +1421,16 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
goto fail;
}
- fb_alloc_cmap(&info->cmap, 256, 0);
+ if (fb_alloc_cmap(&info->cmap, 256, 0)) {
+ printk(KERN_ERR "sstfb: can't alloc cmap memory.\n");
+ goto fail;
+ }
/* register fb */
info->device = &pdev->dev;
if (register_framebuffer(info) < 0) {
printk(KERN_ERR "sstfb: can't register framebuffer.\n");
- goto fail;
+ goto fail_register;
}
sstfb_clear_screen(info);
@@ -1441,8 +1444,9 @@ static int __devinit sstfb_probe(struct pci_dev *pdev,
return 0;
-fail:
+fail_register:
fb_dealloc_cmap(&info->cmap);
+fail:
iounmap(info->screen_base);
fail_fb_remap:
iounmap(par->mmio_vbase);
diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c
index 16648140241..eabaad765ae 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/stifb.c
@@ -1262,24 +1262,25 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
info->flags = FBINFO_DEFAULT;
info->pseudo_palette = &fb->pseudo_palette;
- /* This has to been done !!! */
- fb_alloc_cmap(&info->cmap, NR_PALETTE, 0);
+ /* This has to be done !!! */
+ if (fb_alloc_cmap(&info->cmap, NR_PALETTE, 0))
+ goto out_err1;
stifb_init_display(fb);
if (!request_mem_region(fix->smem_start, fix->smem_len, "stifb fb")) {
printk(KERN_ERR "stifb: cannot reserve fb region 0x%04lx-0x%04lx\n",
fix->smem_start, fix->smem_start+fix->smem_len);
- goto out_err1;
+ goto out_err2;
}
if (!request_mem_region(fix->mmio_start, fix->mmio_len, "stifb mmio")) {
printk(KERN_ERR "stifb: cannot reserve sti mmio region 0x%04lx-0x%04lx\n",
fix->mmio_start, fix->mmio_start+fix->mmio_len);
- goto out_err2;
+ goto out_err3;
}
if (register_framebuffer(&fb->info) < 0)
- goto out_err3;
+ goto out_err4;
sti->info = info; /* save for unregister_framebuffer() */
@@ -1297,13 +1298,14 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
return 0;
-out_err3:
+out_err4:
release_mem_region(fix->mmio_start, fix->mmio_len);
-out_err2:
+out_err3:
release_mem_region(fix->smem_start, fix->smem_len);
+out_err2:
+ fb_dealloc_cmap(&info->cmap);
out_err1:
iounmap(info->screen_base);
- fb_dealloc_cmap(&info->cmap);
out_err0:
kfree(fb);
return -ENXIO;
diff --git a/drivers/video/sunxvr500.c b/drivers/video/sunxvr500.c
index c2ba51b7ea1..18b950706ca 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/sunxvr500.c
@@ -349,11 +349,14 @@ static int __devinit e3d_pci_register(struct pci_dev *pdev,
if (err < 0) {
printk(KERN_ERR "e3d: Could not register framebuffer %s\n",
pci_name(pdev));
- goto err_unmap_fb;
+ goto err_free_cmap;
}
return 0;
+err_free_cmap:
+ fb_dealloc_cmap(&info->cmap);
+
err_unmap_fb:
iounmap(ep->fb_base);
@@ -389,6 +392,7 @@ static void __devexit e3d_pci_unregister(struct pci_dev *pdev)
pci_release_region(pdev, 0);
pci_release_region(pdev, 1);
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
pci_disable_device(pdev);
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 14bd3f3680b..ee64771fbe3 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -1393,6 +1393,7 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev)
release_mem_region(pci_resource_start(pdev, 0),
pci_resource_len(pdev, 0));
pci_set_drvdata(pdev, NULL);
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 680642c089c..a86046ff60a 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -1663,7 +1663,7 @@ tgafb_register(struct device *dev)
if (register_framebuffer(info) < 0) {
printk(KERN_ERR "tgafb: Could not register framebuffer\n");
ret = -EINVAL;
- goto err1;
+ goto err2;
}
if (tga_bus_pci) {
@@ -1682,6 +1682,8 @@ tgafb_register(struct device *dev)
return 0;
+ err2:
+ fb_dealloc_cmap(&info->cmap);
err1:
if (mem_base)
iounmap(mem_base);
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index 479b2e79ad6..03a9c35e9f5 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -2,7 +2,7 @@
* Frame buffer driver for Trident TGUI, Blade and Image series
*
* Copyright 2001, 2002 - Jani Monoses <jani@iv.ro>
- *
+ * Copyright 2009 Krzysztof Helt <krzysztof.h1@wp.pl>
*
* CREDITS:(in order of appearance)
* skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
@@ -490,7 +490,6 @@ static void tgui_copy_rect(struct tridentfb_par *par,
/*
* Accel functions called by the upper layers
*/
-#ifdef CONFIG_FB_TRIDENT_ACCEL
static void tridentfb_fillrect(struct fb_info *info,
const struct fb_fillrect *fr)
{
@@ -565,11 +564,6 @@ static int tridentfb_sync(struct fb_info *info)
par->wait_engine(par);
return 0;
}
-#else
-#define tridentfb_fillrect cfb_fillrect
-#define tridentfb_copyarea cfb_copyarea
-#define tridentfb_imageblit cfb_imageblit
-#endif /* CONFIG_FB_TRIDENT_ACCEL */
/*
* Hardware access functions
@@ -1333,9 +1327,7 @@ static struct fb_ops tridentfb_ops = {
.fb_fillrect = tridentfb_fillrect,
.fb_copyarea = tridentfb_copyarea,
.fb_imageblit = tridentfb_imageblit,
-#ifdef CONFIG_FB_TRIDENT_ACCEL
.fb_sync = tridentfb_sync,
-#endif
};
static int __devinit trident_pci_probe(struct pci_dev *dev,
@@ -1359,10 +1351,6 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
chip_id = id->device;
-#ifndef CONFIG_FB_TRIDENT_ACCEL
- noaccel = 1;
-#endif
-
/* If PCI id is 0x9660 then further detect chip type */
if (chip_id == TGUI9660) {
@@ -1490,6 +1478,9 @@ static int __devinit trident_pci_probe(struct pci_dev *dev,
} else
info->flags |= FBINFO_HWACCEL_DISABLED;
+ if (is_blade(chip_id) && chip_id != BLADE3D)
+ info->flags |= FBINFO_READS_FAST;
+
info->pixmap.addr = kmalloc(4096, GFP_KERNEL);
if (!info->pixmap.addr) {
err = -ENOMEM;
@@ -1563,6 +1554,7 @@ static void __devexit trident_pci_remove(struct pci_dev *dev)
release_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);
pci_set_drvdata(dev, NULL);
kfree(info->pixmap.addr);
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
@@ -1663,4 +1655,5 @@ module_exit(tridentfb_exit);
MODULE_AUTHOR("Jani Monoses <jani@iv.ro>");
MODULE_DESCRIPTION("Framebuffer driver for Trident cards");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("cyblafb");
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 74ae7589900..0b370aebdbf 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -189,7 +189,7 @@ static int uvesafb_exec(struct uvesafb_ktask *task)
uvfb_tasks[seq] = task;
mutex_unlock(&uvfb_lock);
- err = cn_netlink_send(m, 0, gfp_any());
+ err = cn_netlink_send(m, 0, GFP_KERNEL);
if (err == -ESRCH) {
/*
* Try to start the userspace helper if sending
@@ -850,14 +850,16 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
if (vbemode) {
for (i = 0; i < par->vbe_modes_cnt; i++) {
if (par->vbe_modes[i].mode_id == vbemode) {
+ modeid = i;
+ uvesafb_setup_var(&info->var, info,
+ &par->vbe_modes[modeid]);
fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
- &info->var, info);
+ &info->var, info);
/*
* With pixclock set to 0, the default BIOS
* timings will be used in set_par().
*/
info->var.pixclock = 0;
- modeid = i;
goto gotmode;
}
}
@@ -904,8 +906,11 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
fb_videomode_to_var(&info->var, mode);
} else {
modeid = par->vbe_modes[0].mode_id;
+ uvesafb_setup_var(&info->var, info,
+ &par->vbe_modes[modeid]);
fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
- &info->var, info);
+ &info->var, info);
+
goto gotmode;
}
}
@@ -917,9 +922,9 @@ static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
if (modeid == -1)
return -EINVAL;
-gotmode:
uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
+gotmode:
/*
* If we are not VBE3.0+ compliant, we're done -- the BIOS will
* ignore our timings anyway.
@@ -1552,7 +1557,7 @@ static void __devinit uvesafb_init_info(struct fb_info *info,
}
info->flags = FBINFO_FLAG_DEFAULT |
- (par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
+ (par->ypan ? FBINFO_HWACCEL_YPAN : 0);
if (!par->ypan)
info->fbops->fb_pan_display = NULL;
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index 7b0cef9ca8f..4bb9a0b1895 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -119,7 +119,7 @@ static void set_valkyrie_clock(unsigned char *params);
static int valkyrie_var_to_par(struct fb_var_screeninfo *var,
struct fb_par_valkyrie *par, const struct fb_info *fb_info);
-static void valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p);
+static int valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p);
static void valkyrie_par_to_fix(struct fb_par_valkyrie *par, struct fb_fix_screeninfo *fix);
static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valkyrie *p);
@@ -381,18 +381,22 @@ int __init valkyriefb_init(void)
valkyrie_choose_mode(p);
mac_vmode_to_var(default_vmode, default_cmode, &p->info.var);
- valkyrie_init_info(&p->info, p);
+ err = valkyrie_init_info(&p->info, p);
+ if (err < 0)
+ goto out_free;
valkyrie_init_fix(&p->info.fix, p);
if (valkyriefb_set_par(&p->info))
/* "can't happen" */
printk(KERN_ERR "valkyriefb: can't set default video mode\n");
if ((err = register_framebuffer(&p->info)) != 0)
- goto out_free;
+ goto out_cmap_free;
printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", p->info.node);
return 0;
+ out_cmap_free:
+ fb_dealloc_cmap(&p->info.cmap);
out_free:
if (p->frame_buffer)
iounmap(p->frame_buffer);
@@ -538,14 +542,15 @@ static void valkyrie_par_to_fix(struct fb_par_valkyrie *par,
/* ywrapstep, xpanstep, ypanstep */
}
-static void __init valkyrie_init_info(struct fb_info *info, struct fb_info_valkyrie *p)
+static int __init valkyrie_init_info(struct fb_info *info,
+ struct fb_info_valkyrie *p)
{
info->fbops = &valkyriefb_ops;
info->screen_base = p->frame_buffer + 0x1000;
info->flags = FBINFO_DEFAULT;
info->pseudo_palette = p->pseudo_palette;
- fb_alloc_cmap(&info->cmap, 256, 0);
info->par = &p->par;
+ return fb_alloc_cmap(&info->cmap, 256, 0);
}
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index e16322d157d..d6856f43d24 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -438,7 +438,7 @@ static int __init vesafb_probe(struct platform_device *dev)
info->var = vesafb_defined;
info->fix = vesafb_fix;
info->flags = FBINFO_FLAG_DEFAULT |
- (ypan) ? FBINFO_HWACCEL_YPAN : 0;
+ (ypan ? FBINFO_HWACCEL_YPAN : 0);
if (!ypan)
info->fbops->fb_pan_display = NULL;
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 93fe08d6c78..cc919ae4657 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -543,6 +543,7 @@ static int vfb_remove(struct platform_device *dev)
if (info) {
unregister_framebuffer(info);
rvfree(videomemory, videomemorysize);
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
return 0;
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index 632523ff1fb..45c54bfe99b 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -267,13 +267,17 @@ int viafb_wait_engine_idle(void)
int loop = 0;
while (!(readl(viaparinfo->io_virt + VIA_REG_STATUS) &
- VIA_VR_QUEUE_BUSY) && (loop++ < MAXLOOP))
+ VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
+ loop++;
cpu_relax();
+ }
while ((readl(viaparinfo->io_virt + VIA_REG_STATUS) &
(VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
- (loop++ < MAXLOOP))
+ (loop < MAXLOOP)) {
+ loop++;
cpu_relax();
+ }
return loop >= MAXLOOP;
}
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 37b433a08ce..e327b84820d 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -2059,25 +2059,21 @@ static void viafb_init_proc(struct proc_dir_entry **viafb_entry)
if (viafb_entry) {
entry = create_proc_entry("dvp0", 0, *viafb_entry);
if (entry) {
- entry->owner = THIS_MODULE;
entry->read_proc = viafb_dvp0_proc_read;
entry->write_proc = viafb_dvp0_proc_write;
}
entry = create_proc_entry("dvp1", 0, *viafb_entry);
if (entry) {
- entry->owner = THIS_MODULE;
entry->read_proc = viafb_dvp1_proc_read;
entry->write_proc = viafb_dvp1_proc_write;
}
entry = create_proc_entry("dfph", 0, *viafb_entry);
if (entry) {
- entry->owner = THIS_MODULE;
entry->read_proc = viafb_dfph_proc_read;
entry->write_proc = viafb_dfph_proc_write;
}
entry = create_proc_entry("dfpl", 0, *viafb_entry);
if (entry) {
- entry->owner = THIS_MODULE;
entry->read_proc = viafb_dfpl_proc_read;
entry->write_proc = viafb_dfpl_proc_write;
}
@@ -2086,7 +2082,6 @@ static void viafb_init_proc(struct proc_dir_entry **viafb_entry)
viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) {
entry = create_proc_entry("vt1636", 0, *viafb_entry);
if (entry) {
- entry->owner = THIS_MODULE;
entry->read_proc = viafb_vt1636_proc_read;
entry->write_proc = viafb_vt1636_proc_write;
}
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 5777196bf6c..5c52369ab9b 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -23,15 +23,21 @@
#ifdef DEBUG
/* For development, we want to crash whenever the ring is screwed. */
-#define BAD_RING(vq, fmt...) \
- do { dev_err(&vq->vq.vdev->dev, fmt); BUG(); } while(0)
-#define START_USE(vq) \
- do { if ((vq)->in_use) panic("in_use = %i\n", (vq)->in_use); (vq)->in_use = __LINE__; mb(); } while(0)
-#define END_USE(vq) \
- do { BUG_ON(!(vq)->in_use); (vq)->in_use = 0; mb(); } while(0)
+#define BAD_RING(_vq, fmt...) \
+ do { dev_err(&(_vq)->vq.vdev->dev, fmt); BUG(); } while(0)
+/* Caller is supposed to guarantee no reentry. */
+#define START_USE(_vq) \
+ do { \
+ if ((_vq)->in_use) \
+ panic("in_use = %i\n", (_vq)->in_use); \
+ (_vq)->in_use = __LINE__; \
+ mb(); \
+ } while(0)
+#define END_USE(_vq) \
+ do { BUG_ON(!(_vq)->in_use); (_vq)->in_use = 0; mb(); } while(0)
#else
-#define BAD_RING(vq, fmt...) \
- do { dev_err(&vq->vq.vdev->dev, fmt); (vq)->broken = true; } while(0)
+#define BAD_RING(_vq, fmt...) \
+ do { dev_err(&_vq->vq.vdev->dev, fmt); (_vq)->broken = true; } while(0)
#define START_USE(vq)
#define END_USE(vq)
#endif
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 29e144f81cb..37f08c85060 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -16,10 +16,10 @@
#include <linux/irq.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
-#include <linux/clk.h>
#include <linux/err.h>
#include <linux/delay.h>
-#include <linux/ds1wm.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/ds1wm.h>
#include <asm/io.h>
@@ -89,10 +89,9 @@ struct ds1wm_data {
void __iomem *map;
int bus_shift; /* # of shifts to calc register offsets */
struct platform_device *pdev;
- struct ds1wm_platform_data *pdata;
+ struct mfd_cell *cell;
int irq;
int active_high;
- struct clk *clk;
int slave_present;
void *reset_complete;
void *read_complete;
@@ -215,17 +214,17 @@ static int ds1wm_find_divisor(int gclk)
static void ds1wm_up(struct ds1wm_data *ds1wm_data)
{
- int gclk, divisor;
+ int divisor;
+ struct ds1wm_driver_data *plat = ds1wm_data->cell->driver_data;
- if (ds1wm_data->pdata->enable)
- ds1wm_data->pdata->enable(ds1wm_data->pdev);
+ if (ds1wm_data->cell->enable)
+ ds1wm_data->cell->enable(ds1wm_data->pdev);
- gclk = clk_get_rate(ds1wm_data->clk);
- clk_enable(ds1wm_data->clk);
- divisor = ds1wm_find_divisor(gclk);
+ divisor = ds1wm_find_divisor(plat->clock_rate);
if (divisor == 0) {
dev_err(&ds1wm_data->pdev->dev,
- "no suitable divisor for %dHz clock\n", gclk);
+ "no suitable divisor for %dHz clock\n",
+ plat->clock_rate);
return;
}
ds1wm_write_register(ds1wm_data, DS1WM_CLKDIV, divisor);
@@ -244,10 +243,8 @@ static void ds1wm_down(struct ds1wm_data *ds1wm_data)
ds1wm_write_register(ds1wm_data, DS1WM_INT_EN,
ds1wm_data->active_high ? DS1WM_INTEN_IAS : 0);
- if (ds1wm_data->pdata->disable)
- ds1wm_data->pdata->disable(ds1wm_data->pdev);
-
- clk_disable(ds1wm_data->clk);
+ if (ds1wm_data->cell->disable)
+ ds1wm_data->cell->disable(ds1wm_data->pdev);
}
/* --------------------------------------------------------------------- */
@@ -330,13 +327,18 @@ static struct w1_bus_master ds1wm_master = {
static int ds1wm_probe(struct platform_device *pdev)
{
struct ds1wm_data *ds1wm_data;
- struct ds1wm_platform_data *plat;
+ struct ds1wm_driver_data *plat;
struct resource *res;
+ struct mfd_cell *cell;
int ret;
if (!pdev)
return -ENODEV;
+ cell = pdev->dev.platform_data;
+ if (!cell)
+ return -ENODEV;
+
ds1wm_data = kzalloc(sizeof(*ds1wm_data), GFP_KERNEL);
if (!ds1wm_data)
return -ENOMEM;
@@ -348,15 +350,18 @@ static int ds1wm_probe(struct platform_device *pdev)
ret = -ENXIO;
goto err0;
}
- ds1wm_data->map = ioremap(res->start, res->end - res->start + 1);
+ ds1wm_data->map = ioremap(res->start, resource_size(res));
if (!ds1wm_data->map) {
ret = -ENOMEM;
goto err0;
}
- plat = pdev->dev.platform_data;
- ds1wm_data->bus_shift = plat->bus_shift;
+ plat = cell->driver_data;
+
+ /* calculate bus shift from mem resource */
+ ds1wm_data->bus_shift = resource_size(res) >> 3;
+
ds1wm_data->pdev = pdev;
- ds1wm_data->pdata = plat;
+ ds1wm_data->cell = cell;
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (!res) {
@@ -376,26 +381,18 @@ static int ds1wm_probe(struct platform_device *pdev)
if (ret)
goto err1;
- ds1wm_data->clk = clk_get(&pdev->dev, "ds1wm");
- if (IS_ERR(ds1wm_data->clk)) {
- ret = PTR_ERR(ds1wm_data->clk);
- goto err2;
- }
-
ds1wm_up(ds1wm_data);
ds1wm_master.data = (void *)ds1wm_data;
ret = w1_add_master_device(&ds1wm_master);
if (ret)
- goto err3;
+ goto err2;
return 0;
-err3:
- ds1wm_down(ds1wm_data);
- clk_put(ds1wm_data->clk);
err2:
+ ds1wm_down(ds1wm_data);
free_irq(ds1wm_data->irq, ds1wm_data);
err1:
iounmap(ds1wm_data->map);
@@ -434,7 +431,6 @@ static int ds1wm_remove(struct platform_device *pdev)
w1_remove_master_device(&ds1wm_master);
ds1wm_down(ds1wm_data);
- clk_put(ds1wm_data->clk);
free_irq(ds1wm_data->irq, ds1wm_data);
iounmap(ds1wm_data->map);
kfree(ds1wm_data);
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index 442bd8bbd4a..3ebe9726a9e 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -69,7 +69,7 @@ static u8 w1_touch_bit(struct w1_master *dev, int bit)
return w1_read_bit(dev);
else {
w1_write_bit(dev, 0);
- return(0);
+ return 0;
}
}
@@ -184,17 +184,17 @@ static u8 w1_read_bit(struct w1_master *dev)
*/
u8 w1_triplet(struct w1_master *dev, int bdir)
{
- if ( dev->bus_master->triplet )
- return(dev->bus_master->triplet(dev->bus_master->data, bdir));
+ if (dev->bus_master->triplet)
+ return dev->bus_master->triplet(dev->bus_master->data, bdir);
else {
u8 id_bit = w1_touch_bit(dev, 1);
u8 comp_bit = w1_touch_bit(dev, 1);
u8 retval;
- if ( id_bit && comp_bit )
- return(0x03); /* error */
+ if (id_bit && comp_bit)
+ return 0x03; /* error */
- if ( !id_bit && !comp_bit ) {
+ if (!id_bit && !comp_bit) {
/* Both bits are valid, take the direction given */
retval = bdir ? 0x04 : 0;
} else {
@@ -203,11 +203,11 @@ u8 w1_triplet(struct w1_master *dev, int bdir)
retval = id_bit ? 0x05 : 0x02;
}
- if ( dev->bus_master->touch_bit )
+ if (dev->bus_master->touch_bit)
w1_touch_bit(dev, bdir);
else
w1_write_bit(dev, bdir);
- return(retval);
+ return retval;
}
}
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 55f64af072a..63024145215 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -772,7 +772,7 @@ config TXX9_WDT
config GEF_WDT
tristate "GE Fanuc Watchdog Timer"
- depends on GEF_SBC610
+ depends on GEF_SBC610 || GEF_SBC310 || GEF_PPC9A
---help---
Watchdog timer found in a number of GE Fanuc single board computers.
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 6cf155d6b35..3137361ccbf 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -380,7 +380,7 @@ asm(".text \n\t"
* This function checks whether or not a SMBIOS/DMI record is
* the 64bit CRU info or not
*/
-static void __devinit dmi_find_cru(const struct dmi_header *dm)
+static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy)
{
struct smbios_cru64_info *smbios_cru64_ptr;
unsigned long cru_physical_address;
@@ -403,7 +403,7 @@ static int __devinit detect_cru_service(void)
{
cru_rom_addr = NULL;
- dmi_walk(dmi_find_cru);
+ dmi_walk(dmi_find_cru, NULL);
/* if cru_rom_addr has been set then we found a CRU service */
return ((cru_rom_addr != NULL) ? 0 : -ENODEV);
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index 526187c8a12..8ac9cddac57 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -37,7 +37,7 @@ config XEN_COMPAT_XENFS
The old xenstore userspace tools expect to find "xenbus"
under /proc/xen, but "xenbus" is now found at the root of the
xenfs filesystem. Selecting this causes the kernel to create
- the compatibilty mount point /proc/xen if it is running on
+ the compatibility mount point /proc/xen if it is running on
a xen platform.
If in doubt, say yes.
diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c
index 974f56d1ebe..5f54c01c156 100644
--- a/drivers/xen/cpu_hotplug.c
+++ b/drivers/xen/cpu_hotplug.c
@@ -10,7 +10,7 @@ static void enable_hotplug_cpu(int cpu)
if (!cpu_present(cpu))
arch_register_cpu(cpu);
- cpu_set(cpu, cpu_present_map);
+ set_cpu_present(cpu, true);
}
static void disable_hotplug_cpu(int cpu)
@@ -18,7 +18,7 @@ static void disable_hotplug_cpu(int cpu)
if (cpu_present(cpu))
arch_unregister_cpu(cpu);
- cpu_clear(cpu, cpu_present_map);
+ set_cpu_present(cpu, false);
}
static void vcpu_hotplug(unsigned int cpu)
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 3ccd348d112..0d61db1e7b4 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -39,12 +39,6 @@ static int xen_suspend(void *data)
BUG_ON(!irqs_disabled());
- err = device_power_down(PMSG_SUSPEND);
- if (err) {
- printk(KERN_ERR "xen_suspend: device_power_down failed: %d\n",
- err);
- return err;
- }
err = sysdev_suspend(PMSG_SUSPEND);
if (err) {
printk(KERN_ERR "xen_suspend: sysdev_suspend failed: %d\n",
@@ -69,7 +63,6 @@ static int xen_suspend(void *data)
xen_mm_unpin_all();
sysdev_resume();
- device_power_up(PMSG_RESUME);
if (!*cancelled) {
xen_irq_resume();
@@ -108,6 +101,12 @@ static void do_suspend(void)
/* XXX use normal device tree? */
xenbus_suspend();
+ err = device_power_down(PMSG_SUSPEND);
+ if (err) {
+ printk(KERN_ERR "device_power_down failed: %d\n", err);
+ goto resume_devices;
+ }
+
err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
if (err) {
printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
@@ -120,6 +119,9 @@ static void do_suspend(void)
} else
xenbus_suspend_cancel();
+ device_power_up(PMSG_RESUME);
+
+resume_devices:
device_resume(PMSG_RESUME);
/* Make sure timer events get retriggered on all CPUs */